diff --git a/AUTHORS b/AUTHORS
index f18761e..89caae6 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -14,6 +14,9 @@
 BlackBerry Limited
 Opera Software ASA
 Intel Corporation
+MIPS Technologies, Inc.
+Imagination Technologies, LLC
+Loongson Technology Corporation Limited
 
 Akinori MUSHA <knu@FreeBSD.org>
 Alexander Botero-Lowry <alexbl@FreeBSD.org>
@@ -24,6 +27,7 @@
 Baptiste Afsa <baptiste.afsa@arm.com>
 Bert Belder <bertbelder@gmail.com>
 Burcu Dogan <burcujdogan@gmail.com>
+Caitlin Potter <caitpotter88@gmail.com>
 Craig Schlenter <craig.schlenter@gmail.com>
 Chunyang Dai <chunyang.dai@intel.com>
 Daniel Andersson <kodandersson@gmail.com>
@@ -35,6 +39,7 @@
 Filipe David Manana <fdmanana@gmail.com>
 Haitao Feng <haitao.feng@intel.com>
 Ioseb Dzmanashvili <ioseb.dzmanashvili@gmail.com>
+Isiah Meadows <impinball@gmail.com>
 Jacob Bramley <jacob.bramley@arm.com>
 Jan de Mooij <jandemooij@gmail.com>
 Jay Freeman <saurik@saurik.com>
diff --git a/Android.d8.mk b/Android.d8.mk
index ffacf4b..ec122eb 100644
--- a/Android.d8.mk
+++ b/Android.d8.mk
@@ -30,7 +30,7 @@
 $(D8_GEN): $(LOCAL_JS_D8_FILES) $(JS2C_PY)
 	@echo "Generating d8-js.cc"
 	@mkdir -p $(dir $@)
-	python $(SCRIPT) $@ D8 off $(LOCAL_JS_D8_FILES)
+	python $(SCRIPT) $@ D8 $(LOCAL_JS_D8_FILES)
 LOCAL_GENERATED_SOURCES += $(D8_GEN)
 
 LOCAL_CPP_EXTENSION := .cc
diff --git a/Android.libv8.mk b/Android.libv8.mk
index 41815ce..a4f8351 100644
--- a/Android.libv8.mk
+++ b/Android.libv8.mk
@@ -47,7 +47,7 @@
 $(GEN1): $(LOCAL_JS_LIBRARY_FILES) $(JS2C_PY)
 	@echo "Generating libraries.cc"
 	@mkdir -p $(dir $@)
-	python $(SCRIPT) $@ CORE off $(LOCAL_JS_LIBRARY_FILES)
+	python $(SCRIPT) $@ CORE $(LOCAL_JS_LIBRARY_FILES)
 V8_GENERATED_LIBRARIES := $(generated_sources)/libraries.cc
 
 # Generate experimental-libraries.cc
@@ -56,7 +56,7 @@
 $(GEN2): $(LOCAL_JS_EXPERIMENTAL_LIBRARY_FILES) $(JS2C_PY)
 	@echo "Generating experimental-libraries.cc"
 	@mkdir -p $(dir $@)
-	python $(SCRIPT) $@ EXPERIMENTAL off $(LOCAL_JS_EXPERIMENTAL_LIBRARY_FILES)
+	python $(SCRIPT) $@ EXPERIMENTAL $(LOCAL_JS_EXPERIMENTAL_LIBRARY_FILES)
 V8_GENERATED_LIBRARIES += $(generated_sources)/experimental-libraries.cc
 
 LOCAL_GENERATED_SOURCES += $(V8_GENERATED_LIBRARIES)
diff --git a/Android.mksnapshot.mk b/Android.mksnapshot.mk
index f5377a8..28e0b0c 100644
--- a/Android.mksnapshot.mk
+++ b/Android.mksnapshot.mk
@@ -54,7 +54,7 @@
 $(GEN3): $(LOCAL_JS_LIBRARY_FILES) $(JS2C_PY)
 	@echo "Generating libraries.cc"
 	@mkdir -p $(dir $@)
-	python $(SCRIPT) $@ CORE off $(LOCAL_JS_LIBRARY_FILES)
+	python $(SCRIPT) $@ CORE $(LOCAL_JS_LIBRARY_FILES)
 LOCAL_GENERATED_SOURCES := $(generated_sources)/libraries.cc
 
 # Generate experimental-libraries.cc
@@ -63,7 +63,7 @@
 $(GEN4): $(LOCAL_JS_EXPERIMENTAL_LIBRARY_FILES) $(JS2C_PY)
 	@echo "Generating experimental-libraries.cc"
 	@mkdir -p $(dir $@)
-	python $(SCRIPT) $@ EXPERIMENTAL off $(LOCAL_JS_EXPERIMENTAL_LIBRARY_FILES)
+	python $(SCRIPT) $@ EXPERIMENTAL $(LOCAL_JS_EXPERIMENTAL_LIBRARY_FILES)
 LOCAL_GENERATED_SOURCES += $(generated_sources)/experimental-libraries.cc
 
 LOCAL_CFLAGS := \
diff --git a/Android.v8common.mk b/Android.v8common.mk
index bf8b072..a8d9bb5 100644
--- a/Android.v8common.mk
+++ b/Android.v8common.mk
@@ -9,6 +9,8 @@
 	src/arguments.cc \
 	src/assembler.cc \
 	src/assert-scope.cc \
+	src/ast-numbering.cc \
+	src/ast-this-access-visitor.cc \
 	src/ast-value-factory.cc \
 	src/ast.cc \
 	src/background-parsing-task.cc \
@@ -16,6 +18,7 @@
 	src/base/bits.cc \
 	src/base/cpu.cc \
 	src/base/division-by-constant.cc \
+	src/base/functional.cc \
 	src/base/logging.cc \
 	src/base/once.cc \
 	src/base/platform/condition-variable.cc \
@@ -24,24 +27,33 @@
 	src/base/platform/time.cc \
 	src/base/sys-info.cc \
 	src/base/utils/random-number-generator.cc \
+	src/basic-block-profiler.cc \
 	src/bignum-dtoa.cc \
 	src/bignum.cc \
+	src/bit-vector.cc \
 	src/bootstrapper.cc \
 	src/builtins.cc \
 	src/cached-powers.cc \
+	src/char-predicates.cc \
 	src/checks.cc \
 	src/code-factory.cc \
 	src/code-stubs-hydrogen.cc \
 	src/code-stubs.cc \
 	src/codegen.cc \
 	src/compilation-cache.cc \
+	src/compilation-statistics.cc \
 	src/compiler.cc \
 	src/compiler/access-builder.cc \
 	src/compiler/ast-graph-builder.cc \
+	src/compiler/ast-loop-assignment-analyzer.cc \
+	src/compiler/basic-block-instrumentor.cc \
 	src/compiler/change-lowering.cc \
 	src/compiler/code-generator.cc \
+	src/compiler/common-node-cache.cc \
 	src/compiler/common-operator.cc \
+	src/compiler/common-operator-reducer.cc \
 	src/compiler/control-builders.cc \
+	src/compiler/control-reducer.cc \
 	src/compiler/gap-resolver.cc \
 	src/compiler/graph-builder.cc \
 	src/compiler/graph-reducer.cc \
@@ -55,19 +67,31 @@
 	src/compiler/js-generic-lowering.cc \
 	src/compiler/js-graph.cc \
 	src/compiler/js-inlining.cc \
+	src/compiler/js-intrinsic-builder.cc \
+	src/compiler/js-operator.cc \
 	src/compiler/js-typed-lowering.cc \
+	src/compiler/jump-threading.cc \
 	src/compiler/linkage.cc \
+	src/compiler/load-elimination.cc \
+	src/compiler/loop-analysis.cc \
 	src/compiler/machine-operator-reducer.cc \
 	src/compiler/machine-operator.cc \
 	src/compiler/machine-type.cc \
+	src/compiler/move-optimizer.cc \
 	src/compiler/node-cache.cc \
 	src/compiler/node.cc \
+	src/compiler/opcodes.cc \
 	src/compiler/operator.cc \
+	src/compiler/operator-properties.cc \
 	src/compiler/pipeline.cc \
+	src/compiler/pipeline-statistics.cc \
 	src/compiler/raw-machine-assembler.cc \
 	src/compiler/register-allocator.cc \
+	src/compiler/register-allocator-verifier.cc \
+	src/compiler/register-configuration.cc \
 	src/compiler/schedule.cc \
 	src/compiler/scheduler.cc \
+	src/compiler/select-lowering.cc \
 	src/compiler/simplified-lowering.cc \
 	src/compiler/simplified-operator-reducer.cc \
 	src/compiler/simplified-operator.cc \
@@ -75,11 +99,11 @@
 	src/compiler/typer.cc \
 	src/compiler/value-numbering-reducer.cc \
 	src/compiler/verifier.cc \
+	src/compiler/zone-pool.cc \
 	src/contexts.cc \
 	src/conversions.cc \
 	src/counters.cc \
 	src/cpu-profiler.cc \
-	src/data-flow.cc \
 	src/date.cc \
 	src/dateparser.cc \
 	src/debug.cc \
@@ -115,7 +139,6 @@
 	src/heap/objects-visiting.cc \
 	src/heap/spaces.cc \
 	src/heap/store-buffer.cc \
-	src/heap/sweeper-thread.cc \
 	src/hydrogen-bce.cc \
 	src/hydrogen-bch.cc \
 	src/hydrogen-canonicalize.cc \
@@ -155,6 +178,7 @@
 	src/interpreter-irregexp.cc \
 	src/isolate.cc \
 	src/jsregexp.cc \
+	src/layout-descriptor.cc \
 	src/libplatform/default-platform.cc \
 	src/libplatform/task-queue.cc \
 	src/libplatform/worker-thread.cc \
@@ -179,8 +203,34 @@
 	src/regexp-macro-assembler.cc \
 	src/regexp-stack.cc \
 	src/rewriter.cc \
+	src/runtime/runtime-api.cc \
+	src/runtime/runtime-array.cc \
+	src/runtime/runtime.cc \
+	src/runtime/runtime-classes.cc \
+	src/runtime/runtime-collections.cc \
+	src/runtime/runtime-compiler.cc \
+	src/runtime/runtime-date.cc \
+	src/runtime/runtime-debug.cc \
+	src/runtime/runtime-function.cc \
+	src/runtime/runtime-generator.cc \
+	src/runtime/runtime-i18n.cc \
+	src/runtime/runtime-internal.cc \
+	src/runtime/runtime-json.cc \
+	src/runtime/runtime-literals.cc \
+	src/runtime/runtime-liveedit.cc \
+	src/runtime/runtime-maths.cc \
+	src/runtime/runtime-numbers.cc \
+	src/runtime/runtime-object.cc \
+	src/runtime/runtime-observe.cc \
+	src/runtime/runtime-proxy.cc \
+	src/runtime/runtime-regexp.cc \
+	src/runtime/runtime-scopes.cc \
+	src/runtime/runtime-strings.cc \
+	src/runtime/runtime-symbol.cc \
+	src/runtime/runtime-test.cc \
+	src/runtime/runtime-typedarray.cc \
+	src/runtime/runtime-uri.cc \
 	src/runtime-profiler.cc \
-	src/runtime.cc \
 	src/safepoint-table.cc \
 	src/sampler.cc \
 	src/scanner-character-streams.cc \
@@ -190,6 +240,7 @@
 	src/serialize.cc \
 	src/snapshot-common.cc \
 	src/snapshot-source-sink.cc \
+	src/string-builder.cc \
 	src/string-search.cc \
 	src/string-stream.cc \
 	src/strtod.cc \
@@ -200,6 +251,7 @@
 	src/types.cc \
 	src/typing.cc \
 	src/unicode.cc \
+	src/unicode-decoder.cc \
 	src/utils.cc \
 	src/v8.cc \
 	src/v8threads.cc \
@@ -208,7 +260,7 @@
 	src/zone.cc
 
 LOCAL_SRC_FILES += \
-	third_party/fdlibm/fdlibm.cc
+	src/third_party/fdlibm/fdlibm.cc
 
 v8_local_src_files_arm := \
 		src/arm/assembler-arm.cc \
@@ -271,6 +323,9 @@
 		src/ic/arm64/stub-cache-arm64.cc
 
 v8_local_src_files_mips := \
+		src/compiler/mips/code-generator-mips.cc \
+		src/compiler/mips/instruction-selector-mips.cc \
+		src/compiler/mips/linkage-mips.cc \
 		src/ic/mips/access-compiler-mips.cc\
 		src/ic/mips/handler-compiler-mips.cc \
 		src/ic/mips/ic-compiler-mips.cc \
@@ -296,6 +351,9 @@
 		src/mips/simulator-mips.cc
 
 v8_local_src_files_mips64 := \
+		src/compiler/mips64/code-generator-mips64.cc \
+		src/compiler/mips64/instruction-selector-mips64.cc \
+		src/compiler/mips64/linkage-mips64.cc \
 		src/ic/mips64/access-compiler-mips64.cc \
 		src/ic/mips64/handler-compiler-mips64.cc \
 		src/ic/mips64/ic-compiler-mips64.cc \
@@ -394,7 +452,7 @@
 	src/string.js \
 	src/array.js \
 	src/uri.js \
-	third_party/fdlibm/fdlibm.js \
+	src/third_party/fdlibm/fdlibm.js \
 	src/math.js \
 	src/apinatives.js \
 	src/date.js \
@@ -423,4 +481,10 @@
 	src/proxy.js \
 	src/harmony-string.js \
 	src/harmony-array.js \
-	src/harmony-classes.js
+	src/harmony-array-includes.js \
+	src/harmony-classes.js \
+	src/harmony-regexp.js \
+	src/harmony-templates.js \
+	src/harmony-tostring.js \
+	src/harmony-typedarray.js
+
diff --git a/BUILD.gn b/BUILD.gn
index 315c203..6534eea 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2,9 +2,12 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+# Because standalone V8 builds are not supported, assume this is part of a
+# Chromium build.
+import("//build/module_args/v8.gni")
+
 # TODO(jochen): These will need to be user-settable to support standalone V8
 # builds.
-v8_compress_startup_data = "off"
 v8_deprecation_warnings = false
 v8_enable_disassembler = false
 v8_enable_gdbjit = false
@@ -15,7 +18,6 @@
 v8_object_print = false
 v8_postmortem_support = false
 v8_use_snapshot = true
-v8_use_external_startup_data = false
 v8_enable_extra_checks = is_debug
 v8_target_arch = cpu_arch
 v8_random_seed = "314159265"
@@ -95,11 +97,6 @@
       "V8_I18N_SUPPORT",
     ]
   }
-  if (v8_compress_startup_data == "bz2") {
-    defines += [
-      "COMPRESS_STARTUP_DATA_BZ2",
-    ]
-  }
   if (v8_enable_extra_checks == true) {
     defines += [
       "ENABLE_EXTRA_CHECKS",
@@ -182,7 +179,7 @@
     "src/array.js",
     "src/string.js",
     "src/uri.js",
-    "third_party/fdlibm/fdlibm.js",
+    "src/third_party/fdlibm/fdlibm.js",
     "src/math.js",
     "src/apinatives.js",
     "src/date.js",
@@ -216,7 +213,6 @@
   args = [
     rebase_path("$target_gen_dir/libraries.cc", root_build_dir),
     "CORE",
-    v8_compress_startup_data
   ] + rebase_path(sources, root_build_dir)
 
   if (v8_use_external_startup_data) {
@@ -243,7 +239,12 @@
     "src/generator.js",
     "src/harmony-string.js",
     "src/harmony-array.js",
+    "src/harmony-array-includes.js",
+    "src/harmony-typedarray.js",
     "src/harmony-classes.js",
+    "src/harmony-tostring.js",
+    "src/harmony-templates.js",
+    "src/harmony-regexp.js"
   ]
 
   outputs = [
@@ -253,7 +254,6 @@
   args = [
     rebase_path("$target_gen_dir/experimental-libraries.cc", root_build_dir),
     "EXPERIMENTAL",
-    v8_compress_startup_data
   ] + rebase_path(sources, root_build_dir)
 
   if (v8_use_external_startup_data) {
@@ -280,7 +280,7 @@
     ]
 
     outputs = [
-      "$root_gen_dir/natives_blob.bin"
+      "$root_out_dir/natives_blob.bin"
     ]
 
     script = "tools/concatenate-files.py"
@@ -333,10 +333,10 @@
   }
 
   if (v8_use_external_startup_data) {
-    outputs += [ "$root_gen_dir/snapshot_blob.bin" ]
+    outputs += [ "$root_out_dir/snapshot_blob.bin" ]
     args += [
       "--startup_blob",
-      rebase_path("$root_gen_dir/snapshot_blob.bin", root_build_dir)
+      rebase_path("$root_out_dir/snapshot_blob.bin", root_build_dir)
     ]
   }
 }
@@ -359,7 +359,6 @@
     "$target_gen_dir/libraries.cc",
     "$target_gen_dir/experimental-libraries.cc",
     "src/snapshot-empty.cc",
-    "src/snapshot-common.cc",
   ]
 
   configs -= [ "//build/config/compiler:chromium_code" ]
@@ -381,7 +380,6 @@
     "$target_gen_dir/libraries.cc",
     "$target_gen_dir/experimental-libraries.cc",
     "$target_gen_dir/snapshot.cc",
-    "src/snapshot-common.cc",
   ]
 
   configs -= [ "//build/config/compiler:chromium_code" ]
@@ -432,6 +430,10 @@
     "src/assembler.h",
     "src/assert-scope.h",
     "src/assert-scope.cc",
+    "src/ast-numbering.cc",
+    "src/ast-numbering.h",
+    "src/ast-this-access-visitor.cc",
+    "src/ast-this-access-visitor.h",
     "src/ast-value-factory.cc",
     "src/ast-value-factory.h",
     "src/ast.cc",
@@ -440,10 +442,14 @@
     "src/background-parsing-task.h",
     "src/bailout-reason.cc",
     "src/bailout-reason.h",
+    "src/basic-block-profiler.cc",
+    "src/basic-block-profiler.h",
     "src/bignum-dtoa.cc",
     "src/bignum-dtoa.h",
     "src/bignum.cc",
     "src/bignum.h",
+    "src/bit-vector.cc",
+    "src/bit-vector.h",
     "src/bootstrapper.cc",
     "src/bootstrapper.h",
     "src/builtins.cc",
@@ -451,6 +457,7 @@
     "src/bytecodes-irregexp.h",
     "src/cached-powers.cc",
     "src/cached-powers.h",
+    "src/char-predicates.cc",
     "src/char-predicates-inl.h",
     "src/char-predicates.h",
     "src/checks.cc",
@@ -467,28 +474,37 @@
     "src/codegen.h",
     "src/compilation-cache.cc",
     "src/compilation-cache.h",
+    "src/compilation-statistics.cc",
+    "src/compilation-statistics.h",
     "src/compiler/access-builder.cc",
     "src/compiler/access-builder.h",
     "src/compiler/ast-graph-builder.cc",
     "src/compiler/ast-graph-builder.h",
+    "src/compiler/ast-loop-assignment-analyzer.cc",
+    "src/compiler/ast-loop-assignment-analyzer.h",
+    "src/compiler/basic-block-instrumentor.cc",
+    "src/compiler/basic-block-instrumentor.h",
     "src/compiler/change-lowering.cc",
     "src/compiler/change-lowering.h",
     "src/compiler/code-generator-impl.h",
     "src/compiler/code-generator.cc",
     "src/compiler/code-generator.h",
+    "src/compiler/common-node-cache.cc",
     "src/compiler/common-node-cache.h",
+    "src/compiler/common-operator-reducer.cc",
+    "src/compiler/common-operator-reducer.h",
     "src/compiler/common-operator.cc",
     "src/compiler/common-operator.h",
     "src/compiler/control-builders.cc",
     "src/compiler/control-builders.h",
+    "src/compiler/control-equivalence.h",
+    "src/compiler/control-reducer.cc",
+    "src/compiler/control-reducer.h",
+    "src/compiler/diamond.h",
     "src/compiler/frame.h",
     "src/compiler/gap-resolver.cc",
     "src/compiler/gap-resolver.h",
-    "src/compiler/generic-algorithm-inl.h",
     "src/compiler/generic-algorithm.h",
-    "src/compiler/generic-graph.h",
-    "src/compiler/generic-node-inl.h",
-    "src/compiler/generic-node.h",
     "src/compiler/graph-builder.cc",
     "src/compiler/graph-builder.h",
     "src/compiler/graph-inl.h",
@@ -516,18 +532,29 @@
     "src/compiler/js-graph.h",
     "src/compiler/js-inlining.cc",
     "src/compiler/js-inlining.h",
+    "src/compiler/js-intrinsic-builder.cc",
+    "src/compiler/js-intrinsic-builder.h",
+    "src/compiler/js-operator.cc",
     "src/compiler/js-operator.h",
     "src/compiler/js-typed-lowering.cc",
     "src/compiler/js-typed-lowering.h",
+    "src/compiler/jump-threading.cc",
+    "src/compiler/jump-threading.h",
     "src/compiler/linkage-impl.h",
     "src/compiler/linkage.cc",
     "src/compiler/linkage.h",
+    "src/compiler/load-elimination.cc",
+    "src/compiler/load-elimination.h",
+    "src/compiler/loop-analysis.cc",
+    "src/compiler/loop-analysis.h",
     "src/compiler/machine-operator-reducer.cc",
     "src/compiler/machine-operator-reducer.h",
     "src/compiler/machine-operator.cc",
     "src/compiler/machine-operator.h",
     "src/compiler/machine-type.cc",
     "src/compiler/machine-type.h",
+    "src/compiler/move-optimizer.cc",
+    "src/compiler/move-optimizer.h",
     "src/compiler/node-aux-data-inl.h",
     "src/compiler/node-aux-data.h",
     "src/compiler/node-cache.cc",
@@ -537,23 +564,31 @@
     "src/compiler/node-properties.h",
     "src/compiler/node.cc",
     "src/compiler/node.h",
+    "src/compiler/opcodes.cc",
     "src/compiler/opcodes.h",
-    "src/compiler/operator-properties-inl.h",
+    "src/compiler/operator-properties.cc",
     "src/compiler/operator-properties.h",
     "src/compiler/operator.cc",
     "src/compiler/operator.h",
-    "src/compiler/phi-reducer.h",
     "src/compiler/pipeline.cc",
     "src/compiler/pipeline.h",
+    "src/compiler/pipeline-statistics.cc",
+    "src/compiler/pipeline-statistics.h",
     "src/compiler/raw-machine-assembler.cc",
     "src/compiler/raw-machine-assembler.h",
     "src/compiler/register-allocator.cc",
     "src/compiler/register-allocator.h",
+    "src/compiler/register-allocator-verifier.cc",
+    "src/compiler/register-allocator-verifier.h",
+    "src/compiler/register-configuration.cc",
+    "src/compiler/register-configuration.h",
     "src/compiler/representation-change.h",
     "src/compiler/schedule.cc",
     "src/compiler/schedule.h",
     "src/compiler/scheduler.cc",
     "src/compiler/scheduler.h",
+    "src/compiler/select-lowering.cc",
+    "src/compiler/select-lowering.h",
     "src/compiler/simplified-lowering.cc",
     "src/compiler/simplified-lowering.h",
     "src/compiler/simplified-operator-reducer.cc",
@@ -568,6 +603,8 @@
     "src/compiler/value-numbering-reducer.h",
     "src/compiler/verifier.cc",
     "src/compiler/verifier.h",
+    "src/compiler/zone-pool.cc",
+    "src/compiler/zone-pool.h",
     "src/compiler.cc",
     "src/compiler.h",
     "src/contexts.cc",
@@ -580,8 +617,6 @@
     "src/cpu-profiler-inl.h",
     "src/cpu-profiler.cc",
     "src/cpu-profiler.h",
-    "src/data-flow.cc",
-    "src/data-flow.h",
     "src/date.cc",
     "src/date.h",
     "src/dateparser-inl.h",
@@ -620,7 +655,6 @@
     "src/factory.h",
     "src/fast-dtoa.cc",
     "src/fast-dtoa.h",
-    "src/feedback-slots.h",
     "src/field-index.h",
     "src/field-index-inl.h",
     "src/fixed-dtoa.cc",
@@ -670,8 +704,6 @@
     "src/heap/store-buffer-inl.h",
     "src/heap/store-buffer.cc",
     "src/heap/store-buffer.h",
-    "src/heap/sweeper-thread.h",
-    "src/heap/sweeper-thread.cc",
     "src/hydrogen-alias-analysis.h",
     "src/hydrogen-bce.cc",
     "src/hydrogen-bce.h",
@@ -756,6 +788,9 @@
     "src/jsregexp-inl.h",
     "src/jsregexp.cc",
     "src/jsregexp.h",
+    "src/layout-descriptor-inl.h",
+    "src/layout-descriptor.cc",
+    "src/layout-descriptor.h",
     "src/list-inl.h",
     "src/list.h",
     "src/lithium-allocator-inl.h",
@@ -820,8 +855,35 @@
     "src/rewriter.h",
     "src/runtime-profiler.cc",
     "src/runtime-profiler.h",
-    "src/runtime.cc",
-    "src/runtime.h",
+    "src/runtime/runtime-api.cc",
+    "src/runtime/runtime-array.cc",
+    "src/runtime/runtime-classes.cc",
+    "src/runtime/runtime-collections.cc",
+    "src/runtime/runtime-compiler.cc",
+    "src/runtime/runtime-date.cc",
+    "src/runtime/runtime-debug.cc",
+    "src/runtime/runtime-function.cc",
+    "src/runtime/runtime-generator.cc",
+    "src/runtime/runtime-i18n.cc",
+    "src/runtime/runtime-internal.cc",
+    "src/runtime/runtime-json.cc",
+    "src/runtime/runtime-literals.cc",
+    "src/runtime/runtime-liveedit.cc",
+    "src/runtime/runtime-maths.cc",
+    "src/runtime/runtime-numbers.cc",
+    "src/runtime/runtime-object.cc",
+    "src/runtime/runtime-observe.cc",
+    "src/runtime/runtime-proxy.cc",
+    "src/runtime/runtime-regexp.cc",
+    "src/runtime/runtime-scopes.cc",
+    "src/runtime/runtime-strings.cc",
+    "src/runtime/runtime-symbol.cc",
+    "src/runtime/runtime-test.cc",
+    "src/runtime/runtime-typedarray.cc",
+    "src/runtime/runtime-uri.cc",
+    "src/runtime/runtime-utils.h",
+    "src/runtime/runtime.cc",
+    "src/runtime/runtime.h",
     "src/safepoint-table.cc",
     "src/safepoint-table.h",
     "src/sampler.cc",
@@ -838,9 +900,12 @@
     "src/serialize.h",
     "src/small-pointer-list.h",
     "src/smart-pointers.h",
+    "src/snapshot-common.cc",
     "src/snapshot-source-sink.cc",
     "src/snapshot-source-sink.h",
     "src/snapshot.h",
+    "src/string-builder.cc",
+    "src/string-builder.h",
     "src/string-search.cc",
     "src/string-search.h",
     "src/string-stream.cc",
@@ -867,8 +932,9 @@
     "src/unicode-inl.h",
     "src/unicode.cc",
     "src/unicode.h",
+    "src/unicode-decoder.cc",
+    "src/unicode-decoder.h",
     "src/unique.h",
-    "src/uri.h",
     "src/utils-inl.h",
     "src/utils.cc",
     "src/utils.h",
@@ -886,8 +952,8 @@
     "src/zone-inl.h",
     "src/zone.cc",
     "src/zone.h",
-    "third_party/fdlibm/fdlibm.cc",
-    "third_party/fdlibm/fdlibm.h",
+    "src/third_party/fdlibm/fdlibm.cc",
+    "src/third_party/fdlibm/fdlibm.h",
   ]
 
   if (v8_target_arch == "x86") {
@@ -922,6 +988,8 @@
       "src/compiler/ia32/instruction-codes-ia32.h",
       "src/compiler/ia32/instruction-selector-ia32.cc",
       "src/compiler/ia32/linkage-ia32.cc",
+      "src/ic/ia32/access-compiler-ia32.cc",
+      "src/ic/ia32/handler-compiler-ia32.cc",
       "src/ic/ia32/ic-ia32.cc",
       "src/ic/ia32/ic-compiler-ia32.cc",
       "src/ic/ia32/stub-cache-ia32.cc",
@@ -1090,6 +1158,10 @@
       "src/mips/regexp-macro-assembler-mips.cc",
       "src/mips/regexp-macro-assembler-mips.h",
       "src/mips/simulator-mips.cc",
+      "src/compiler/mips/code-generator-mips.cc",
+      "src/compiler/mips/instruction-codes-mips.h",
+      "src/compiler/mips/instruction-selector-mips.cc",
+      "src/compiler/mips/linkage-mips.cc",
       "src/ic/mips/access-compiler-mips.cc",
       "src/ic/mips/handler-compiler-mips.cc",
       "src/ic/mips/ic-mips.cc",
@@ -1151,11 +1223,6 @@
     # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
     cflags = [ "/wd4267" ]
   }
-  if (is_linux) {
-    if (v8_compress_startup_data == "bz2") {
-      libs += [ "bz2" ]
-    }
-  }
 
   if (v8_enable_i18n_support) {
     deps += [ "//third_party/icu" ]
@@ -1199,6 +1266,9 @@
     "src/base/division-by-constant.cc",
     "src/base/division-by-constant.h",
     "src/base/flags.h",
+    "src/base/functional.cc",
+    "src/base/functional.h",
+    "src/base/iterator.h",
     "src/base/lazy-instance.h",
     "src/base/logging.cc",
     "src/base/logging.h",
@@ -1270,8 +1340,6 @@
     sources += [
       "src/base/platform/platform-win32.cc",
       "src/base/win32-headers.h",
-      "src/base/win32-math.cc",
-      "src/base/win32-math.h",
     ]
 
     defines += [ "_CRT_RAND_S" ]  # for rand_s()
@@ -1327,11 +1395,8 @@
       ":v8_base",
       ":v8_libplatform",
       ":v8_nosnapshot",
+      "//build/config/sanitizers:deps",
     ]
-
-    if (v8_compress_startup_data == "bz2") {
-      libs = [ "bz2" ]
-    }
   }
 }
 
@@ -1346,7 +1411,7 @@
     "src/v8dll-main.cc",
   ]
 
-  if (v8_use_external_startup_data) {
+  if (v8_use_snapshot && v8_use_external_startup_data) {
     deps = [
       ":v8_base",
       ":v8_external_snapshot",
@@ -1357,6 +1422,7 @@
       ":v8_snapshot",
     ]
   } else {
+    assert(!v8_use_external_startup_data)
     deps = [
       ":v8_base",
       ":v8_nosnapshot",
@@ -1378,7 +1444,7 @@
 } else {
 
 group("v8") {
-  if (v8_use_external_startup_data) {
+  if (v8_use_snapshot && v8_use_external_startup_data) {
     deps = [
       ":v8_base",
       ":v8_external_snapshot",
@@ -1389,6 +1455,7 @@
       ":v8_snapshot",
     ]
   } else {
+    assert(!v8_use_external_startup_data)
     deps = [
       ":v8_base",
       ":v8_nosnapshot",
diff --git a/ChangeLog b/ChangeLog
index d787965..d42a2f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,856 @@
+2015-01-07: Version 3.32.3
+
+        Performance and stability improvements on all platforms.
+
+
+2015-01-07: Version 3.32.2
+
+        Performance and stability improvements on all platforms.
+
+
+2015-01-07: Version 3.32.1
+
+        [turbofan] Don't crash when typing load from a Uint8ClampedArray
+        (Chromium issue 446156).
+
+        [turbofan] Truncation of Bit/Word8/16 to Word32 is a no-op (Chromium
+        issue 445859).
+
+        [x64] Rearrange code for OOB integer loads (Chromium issue 445858).
+
+        Fix %NeverOptimizeFunction() intrinsic (Chromium issue 445732).
+
+        [turbofan] Fix invalid bounds check with overflowing offset (Chromium
+        issue 445267).
+
+        [turbofan] Raise max virtual registers and call parameter limit (issue
+        3786).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-23: Version 3.31.74
+
+        [turbofan] Turn DCHECK for fixed slot index into a CHECK (Chromium issue
+        444681).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-23: Version 3.31.73
+
+        [turbofan] Fix missing ChangeUint32ToUint64 in lowering of LoadBuffer
+        (Chromium issue 444695).
+
+        Enable the embedder to specify what kind of context was disposed.
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-22: Version 3.31.72
+
+        [turbofan] Correctify lowering of Uint8ClampedArray buffer access
+        (Chromium issue 444508).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-20: Version 3.31.71
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-20: Version 3.31.70
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-20: Version 3.31.69
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-19: Version 3.31.68
+
+        [turbofan] Fix unsafe out-of-bounds check for checked loads/stores
+        (Chromium issue 443744).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-19: Version 3.31.67
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-19: Version 3.31.66
+
+        Ship ES6 template literals (issue 3230).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-18: Version 3.31.65
+
+        ES6 template literals should not use legacy octal strings (issue 3736).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-18: Version 3.31.64
+
+        Fixed -fsanitize=float-cast-overflow problems (issue 3773).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-18: Version 3.31.63
+
+        ES6 computed property names (issue 3754).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-17: Version 3.31.62
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-17: Version 3.31.61
+
+        ES6: Update unscopables to match spec (issue 3632).
+
+        ES6 computed property names (issue 3754).
+
+        More -fsanitize=vptr fixes (Chromium issue 441099).
+
+        [turbofan] Cache conversions inserted during typed lowering (issue
+        3763).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-16: Version 3.31.60
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-16: Version 3.31.59
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-16: Version 3.31.58
+
+        Ship ES6 classes (issue 3330).
+
+        ES6 computed property names (issue 3754).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-12: Version 3.31.57
+
+        Consistently use only one of virtual/OVERRIDE/FINAL (issue 3753).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-12: Version 3.31.56
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-12: Version 3.31.55
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-11: Version 3.31.54
+
+        Implement Array.from() (issue 3336).
+
+        move v8_use_external_startup_data to standalone.gypi (Chromium issue
+        421063).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-11: Version 3.31.53
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-11: Version 3.31.52
+
+        Ship ES6 block scoping (issue 2198).
+
+        Optimize Object.seal and Object.preventExtensions (issue 3662, Chromium
+        issue 115960).
+
+        Add Array.prototype.includes (issue 3575).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-10: Version 3.31.51
+
+        [x64] Fix optimization for certain checked load/stores (Chromium issue
+        439743).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-09: Version 3.31.50
+
+        Temporarily restore make dependencies.
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-09: Version 3.31.49
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-09: Version 3.31.48
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-09: Version 3.31.47
+
+        Temporarily restore make dependencies.
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-08: Version 3.31.46
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-08: Version 3.31.45
+
+        Update all DEPS to match chromium's DEPS at edb488e.
+
+        Turn on DCHECKs and other debugging code if dcheck_always_on is 1 (issue
+        3731).
+
+        Optimize GetPrototype.
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-05: Version 3.31.44
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-04: Version 3.31.43
+
+        ES6 template literals: Fix issue with template after rbrace (issue
+        3734).
+
+        Stage ES6 template literals (issue 3230).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-04: Version 3.31.42
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-04: Version 3.31.41
+
+        Simplify template literal raw string creation (issue 3710).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-03: Version 3.31.40
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-03: Version 3.31.39
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-03: Version 3.31.38
+
+        Stage ES6 classes and object literal extensions (issue 3330).
+
+        Fixed environment handling for LFlooringDivI on ARM (Chromium issue
+        437765).
+
+        Add GetIdentityHash to v8::Name object API (Chromium issue 437416).
+
+        Set V8_CC_GNU or V8_CC_MSVC for clang in gcc / cl mode (Chromium issue
+        82385).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-02: Version 3.31.37
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-02: Version 3.31.36
+
+        Set V8_CC_GNU or V8_CC_MSVC for clang in gcc / cl mode (Chromium issue
+        82385).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-02: Version 3.31.35
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-01: Version 3.31.34
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-01: Version 3.31.33
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-01: Version 3.31.32
+
+        Performance and stability improvements on all platforms.
+
+
+2014-12-01: Version 3.31.31
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-29: Version 3.31.30
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-28: Version 3.31.29
+
+        Stage @@toStringTag (--harmony-tostring).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-28: Version 3.31.28
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-28: Version 3.31.27
+
+        Ship harmony-strings.
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-28: Version 3.31.26
+
+        Abort optimization in corner case (Chromium issue 436893).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-26: Version 3.31.25
+
+        Stage ES6 block scoping (issue 2198).
+
+        Introduce legacy const slots in correct context (Chromium issue 410030).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-26: Version 3.31.24
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-25: Version 3.31.23
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-25: Version 3.31.22
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-24: Version 3.31.21
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-24: Version 3.31.20
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-22: Version 3.31.19
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-21: Version 3.31.18
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-21: Version 3.31.17
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-21: Version 3.31.16
+
+        Cache template literal callSiteObj (issue 3230).
+
+        Rename String.prototype.contains to 'includes'.
+
+        Reserve code range block for evacuation (Chromium issue 430118).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-20: Version 3.31.15
+
+        Rename String.prototype.contains to 'includes'.
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-19: Version 3.31.14
+
+        Remove Weak{Map,Set}.prototype.clear.
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-19: Version 3.31.13
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-19: Version 3.31.12
+
+        Classes: Expand test to cover strict runtime behavior (issue 3330).
+
+        v8::String::Concat must not throw (Chromium issue 420240).
+
+        Fix disabling all break points from within the debug event callback
+        (Chromium issue 432493).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-18: Version 3.31.11
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-17: Version 3.31.10
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-17: Version 3.31.9
+
+        Expose internal properties of map/set iterators via mirrors.
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-17: Version 3.31.8
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-15: Version 3.31.7
+
+        Classes: Add support for stepping through default constructors (issue
+        3674).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-14: Version 3.31.6
+
+        Fix desugaring of let bindings in for loops to handle continue properly
+        (issue 3683).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-14: Version 3.31.5
+
+        Classes: Implement correct name binding (issue 3330).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-14: Version 3.31.4
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-14: Version 3.31.3
+
+        Classes: Cleanup default constructor flag.
+
+        Soft fail for invalid cache data.
+
+        Implement .of() on typed arrays (issue 3578).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-13: Version 3.31.2
+
+        MIPS: Leaving a generator via an exception causes it to close (issue
+        3096).
+
+        MIPS: ES6: Add support for super in object literals (issue 3571).
+
+        Increase the target new space size to the max new space size (issue
+        3626).
+
+        Leaving a generator via an exception causes it to close (issue 3096).
+
+        Correctly compute line numbers in functions from the function
+        constructor (Chromium issue 109362).
+
+        Rename v8::Exception::GetMessage to CreateMessage.
+
+        Classes: Add support for arguments in default constructor (issue 3672).
+
+        ES6: Add support for super in object literals (issue 3571).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-12: Version 3.31.1
+
+        Fix has_constant_parameter_count() confusion in LReturn (Chromium issue
+        431602).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-05: Version 3.30.33
+
+        `1..isPrototypeOf.call(null)` should return false, not throw TypeError
+        (issue 3483).
+
+        Refactor ObjectGetOwnPropertyKeys to accept bitmask rather than boolean
+        (issue 3549).
+
+        Add debug mirror support for ES6 Map/Set iterators (Chromium issue
+        427868).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-04: Version 3.30.30
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-02: Version 3.30.27
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-02: Version 3.30.26
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-01: Version 3.30.25
+
+        Performance and stability improvements on all platforms.
+
+
+2014-11-01: Version 3.30.24
+
+        Ensure we don't try to inline raw access to indexed interceptor
+        receivers (Chromium issue 419220).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-31: Version 3.30.23
+
+        Introduce v8::Exception::GetMessage to find location of an error object
+        (Chromium issue 427954).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-30: Version 3.30.22
+
+        MIPS: Classes: Add super support in methods and accessors (issue 3330).
+
+        Classes: Add super support in methods and accessors (issue 3330).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-29: Version 3.30.21
+
+        MIPS: Classes: Add basic support for properties (issue 3330).
+
+        Classes: Add more tests for prototype edge cases (Chromium issue 3655).
+
+        Classes: Add test for method prototype (issue 3330).
+
+        Get stack trace for uncaught exceptions/promise rejections from the
+        simple stack when available.
+
+        Classes: Add basic support for properties (issue 3330).
+
+        Allow duplicate property names in classes (issue 3570).
+
+        Windows: use SystemTimeToTzSpecificLocalTime instead of localtime_s
+        (Chromium issue 417640).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-28: Version 3.30.20
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-27: Version 3.30.19
+
+        Check string literals with escapes in PreParserTraits::GetSymbol()
+        (issue 3606).
+
+        only define ARRAYSIZE_UNSAFE for NaCl builds (Chromium issue 405225).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-24: Version 3.30.18
+
+        Narrow cases where Sparse/Smart versions of Array methods are used
+        (issues 2615, 3612, 3621).
+
+        Shrink new space in idle notification (Chromium issue 424423).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-23: Version 3.30.17
+
+        ARM64: Fix stack manipulation (Chromium issue 425585).
+
+        Speed up creation of Objects whose prototype has dictionary elements
+        (Chromium issue 422754).
+
+        Enable libstdc++ debug mode in debug builds (issue 3638).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-22: Version 3.30.16
+
+        Remove v8stdint.h, it doesn't serve a purpose anymore.
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-21: Version 3.30.15
+
+        Avoid the Marsaglia effect in 3D (Chromium issue 423311).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-20: Version 3.30.14
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-17: Version 3.30.13
+
+        Don't expose Array.prototype.values as it breaks webcompat (Chromium
+        issue 409858).
+
+        Fix break location calculation (Chromium issue 419663).
+
+        Enable libstdc++ debug mode in debug builds (issue 3638).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-17: Version 3.30.12
+
+        Implement .forEach() on typed arrays (issue 3578).
+
+        Introduce v8::Exception::GetStackTrace API method.
+
+        Remove SmartMove, bringing Array methods further into spec compliance
+        (issue 2615).
+
+        Convert argument toObject() in Object.getOwnPropertyNames/Descriptors
+        (issue 3443).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-15: Version 3.30.11
+
+        Array.prototype.{every, filter, find, findIndex, forEach, map, some}:
+        Use fresh primitive wrapper for calls (issue 3536).
+
+        Correctly expand literal buffer for surrogate pairs (Chromium issue
+        423212).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-15: Version 3.30.10
+
+        Squeeze the layout of various AST node types (Chromium issue 417697).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-14: Version 3.30.9
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-13: Version 3.30.8
+
+        AST nodes have at most one bailout/typefeedback ID now, saving lots of
+        memory (Chromium issue 417697).
+
+        Allow identifier code points from supplementary multilingual planes
+        (issue 3617).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-10: Version 3.30.7
+
+        Fix computation of UTC time from local time at DST change points (issue
+        3116, Chromium issues 415424, 417640).
+
+        Convert `obj` ToObject in Object.keys() (issue 3587).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-09: Version 3.30.6
+
+        Update unicode to 7.0.0 (issue 2892).
+
+        Classes: Add support for toString (issue 3330).
+
+        Don't enable WPO on Win64 and require Server 2003 / x64 for win64
+        (Chromium issue 421363).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-08: Version 3.30.5
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-08: Version 3.30.4
+
+        This uses a runtime function to set up the the constructor and its
+        prototype (issue 3330).
+
+        Remove PersistentBase::ClearAndLeak.
+
+        Squeeze the layout of variable proxy nodes (Chromium issue 417697).
+
+        Add MonotonicallyIncreasingTime to V8 Platform (Chromium issue 417668).
+
+        Fix representation of HLoadRoot (Chromium issue 419036).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-03: Version 3.30.3
+
+        Removed the Isolate* field from literal nodes (Chromium issue 417697).
+
+        Squeeze the layout of expression nodes a bit (Chromium issue 417697).
+
+        Merged FeedbackSlotInterface into AstNode, removing the need for a 2nd
+        vtable (Chromium issue 417697).
+
+        Extend CPU profiler with mapping ticks to source lines.
+
+        Remove support for parallel sweeping.
+
+        Introduce v8::Object::GetIsolate().
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-02: Version 3.30.2
+
+        Fix Hydrogen's BuildStore() (Chromium issue 417508).
+
+        Move unit tests to test/unittests (issue 3489).
+
+        Changes to ALLOW_UNUSED to match upcoming changes to the Chromium trunk:
+        * Eliminate usage of ALLOW_UNUSED to define COMPILE_ASSERT and just use
+        static_assert() in all cases now that all platforms build with C++11. *
+        Convert remaining uses of ALLOW_UNUSED to ALLOW_UNUSED_TYPE to match how
+        Chromium will be splitting this functionality.  (In Chromium we'll have
+        both   ALLOW_UNUSED_TYPE and ALLOW_UNUSED_LOCAL, which have different
+        syntax to   enable us to use these with MSVC.) (Chromium issue 81439).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-10-01: Version 3.30.1
+
+        Introduce PromiseRejectCallback (issue 3093).
+
+        ES6: Implement object literal property shorthand (issue 3584).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-09-30: Version 3.29.93
+
+        Add a getter for the address and size of the code range to the pulic API
+        (issue 3598).
+
+        Convert `obj` ToObject in Object.keys() (issue 3587).
+
+        Performance and stability improvements on all platforms.
+
+
+2014-09-29: Version 3.29.92
+
+        Performance and stability improvements on all platforms.
+
+
+2014-09-26: Version 3.29.91
+
+        Performance and stability improvements on all platforms.
+
+
 2014-09-25: Version 3.29.88
 
         Performance and stability improvements on all platforms.
diff --git a/DEPS b/DEPS
index d4139c6..a81c7ec 100644
--- a/DEPS
+++ b/DEPS
@@ -3,44 +3,32 @@
 # all paths in here must match this assumption.
 
 vars = {
-  "chromium_git": "https://chromium.googlesource.com",
-
-  "chromium_trunk": "https://src.chromium.org/svn/trunk",
-
-  "buildtools_revision": "fb782d4369d5ae04f17a2fceef7de5a63e50f07b",
+  "git_url": "https://chromium.googlesource.com",
 }
 
 deps = {
-  # Remember to keep the revision in sync with the Makefile.
   "v8/build/gyp":
-    "http://gyp.googlecode.com/svn/trunk@1831",
-
+    Var("git_url") + "/external/gyp.git" + "@" + "fe00999dfaee449d3465a9316778434884da4fa7",  # from svn revision 2010
   "v8/third_party/icu":
-    Var("chromium_trunk") + "/deps/third_party/icu52@277999",
-
+    Var("git_url") + "/chromium/deps/icu.git" + "@" + "51c1a4ce5f362676aa1f1cfdb5b7e52edabfa5aa",
   "v8/buildtools":
-    "https://chromium.googlesource.com/chromium/buildtools.git@" +
-    Var("buildtools_revision"),
-
+    Var("git_url") + "/chromium/buildtools.git" + "@" + "23a4e2f545c7b6340d7e5a2b74801941b0a86535",
   "v8/testing/gtest":
-    "http://googletest.googlecode.com/svn/trunk@692",
-
+    Var("git_url") + "/external/googletest.git" + "@" + "8245545b6dc9c4703e6496d1efd19e975ad2b038",  # from svn revision 700
   "v8/testing/gmock":
-    "http://googlemock.googlecode.com/svn/trunk@485",
+    Var("git_url") + "/external/googlemock.git" + "@" + "29763965ab52f24565299976b936d1265cb6a271",  # from svn revision 501
+  "v8/tools/clang":
+    Var("git_url") + "/chromium/src/tools/clang.git" + "@" + "c945be21f6485fa177b43814f910b76cce921653",
 }
 
 deps_os = {
   "android": {
     "v8/third_party/android_tools":
-      Var("chromium_git") + "/android_tools.git" + "@" +
-          "31869996507de16812bb53a3d0aaa15cd6194c16",
+      Var("git_url") + "/android_tools.git" + "@" + "4f723e2a5fa5b7b8a198072ac19b92344be2b271",
   },
   "win": {
     "v8/third_party/cygwin":
-      Var("chromium_trunk") + "/deps/third_party/cygwin@66844",
-
-    "v8/third_party/python_26":
-      Var("chromium_trunk") + "/tools/third_party/python_26@89111",
+      Var("git_url") + "/chromium/deps/cygwin.git" + "@" + "c89e446b273697fadf3a10ff1007a97c0b7de6df",
   }
 }
 
@@ -93,6 +81,13 @@
     ],
   },
   {
+    # Pull clang if needed or requested via GYP_DEFINES.
+    # Note: On Win, this should run after win_toolchain, as it may use it.
+    'name': 'clang',
+    'pattern': '.',
+    'action': ['python', 'v8/tools/clang/scripts/update.py', '--if-needed'],
+  },
+  {
     # A change to a .gyp, .gypi, or to GYP itself should run the generator.
     "pattern": ".",
     "action": ["python", "v8/build/gyp_v8"],
diff --git a/Makefile b/Makefile
index 2fbe1ba..606b5d7 100644
--- a/Makefile
+++ b/Makefile
@@ -64,6 +64,10 @@
 ifeq ($(verifyheap), on)
   GYPFLAGS += -Dv8_enable_verify_heap=1
 endif
+# tracemaps=on
+ifeq ($(tracemaps), on)
+  GYPFLAGS += -Dv8_trace_maps=1
+endif
 # backtrace=off
 ifeq ($(backtrace), off)
   GYPFLAGS += -Dv8_enable_backtrace=0
@@ -78,6 +82,9 @@
 ifeq ($(snapshot), off)
   GYPFLAGS += -Dv8_use_snapshot='false'
 endif
+ifeq ($(snapshot), external)
+  GYPFLAGS += -Dv8_use_external_startup_data=1
+endif
 # extrachecks=on/off
 ifeq ($(extrachecks), on)
   GYPFLAGS += -Dv8_enable_extra_checks=1 -Dv8_enable_handle_zapping=1
@@ -140,10 +147,15 @@
 # asan=/path/to/clang++
 ifneq ($(strip $(asan)),)
   GYPFLAGS += -Dasan=1
+  export CC=$(dir $(asan))clang
   export CXX=$(asan)
   export CXX_host=$(asan)
   export LINK=$(asan)
-  export ASAN_SYMBOLIZER_PATH="$(dir $(asan))llvm-symbolizer"
+  export ASAN_SYMBOLIZER_PATH=$(dir $(asan))llvm-symbolizer
+  TESTFLAGS += --asan
+  ifeq ($(lsan), on)
+    GYPFLAGS += -Dlsan=1
+  endif
 endif
 
 # arm specific flags.
@@ -230,8 +242,8 @@
 
 # List of files that trigger Makefile regeneration:
 GYPFILES = build/all.gyp build/features.gypi build/standalone.gypi \
-           build/toolchain.gypi samples/samples.gyp src/compiler/compiler.gyp \
-           src/d8.gyp test/cctest/cctest.gyp tools/gyp/v8.gyp
+           build/toolchain.gypi samples/samples.gyp src/d8.gyp \
+           test/cctest/cctest.gyp test/unittests/unittests.gyp tools/gyp/v8.gyp
 
 # If vtunejit=on, the v8vtune.gyp will be appended.
 ifeq ($(vtunejit), on)
@@ -252,7 +264,7 @@
 ENVFILE = $(OUTDIR)/environment
 
 .PHONY: all check clean builddeps dependencies $(ENVFILE).new native \
-        qc quickcheck $(QUICKCHECKS) \
+        qc quickcheck $(QUICKCHECKS) turbocheck \
         $(addsuffix .quickcheck,$(MODES)) $(addsuffix .quickcheck,$(ARCHES)) \
         $(ARCHES) $(MODES) $(BUILDS) $(CHECKS) $(addsuffix .clean,$(ARCHES)) \
         $(addsuffix .check,$(MODES)) $(addsuffix .check,$(ARCHES)) \
@@ -381,6 +393,15 @@
 	    --arch-and-mode=$(FASTTESTMODES) $(TESTFLAGS) --quickcheck
 qc: quickcheck
 
+turbocheck: $(subst $(COMMA),$(SPACE),$(FASTCOMPILEMODES))
+	tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
+	    --arch-and-mode=$(SUPERFASTTESTMODES) $(TESTFLAGS) \
+	    --quickcheck --variants=turbofan --download-data mozilla webkit
+	tools/run-tests.py $(TESTJOBS) --outdir=$(OUTDIR) \
+	    --arch-and-mode=$(FASTTESTMODES) $(TESTFLAGS) \
+	    --quickcheck --variants=turbofan
+tc: turbocheck
+
 # Clean targets. You can clean each architecture individually, or everything.
 $(addsuffix .clean, $(ARCHES) $(ANDROID_ARCHES) $(NACL_ARCHES)):
 	rm -f $(OUTDIR)/Makefile.$(basename $@)*
@@ -472,7 +493,7 @@
 # "dependencies" includes also dependencies required for development.
 # Remember to keep these in sync with the DEPS file.
 builddeps:
-	svn checkout --force http://gyp.googlecode.com/svn/trunk build/gyp \
+	svn checkout --force https://gyp.googlecode.com/svn/trunk build/gyp \
 	    --revision 1831
 	if svn info third_party/icu 2>&1 | grep -q icu46 ; then \
 	  svn switch --force \
@@ -483,9 +504,9 @@
 	      https://src.chromium.org/chrome/trunk/deps/third_party/icu52 \
 	      third_party/icu --revision 277999 ; \
 	fi
-	svn checkout --force http://googletest.googlecode.com/svn/trunk \
+	svn checkout --force https://googletest.googlecode.com/svn/trunk \
 	    testing/gtest --revision 692
-	svn checkout --force http://googlemock.googlecode.com/svn/trunk \
+	svn checkout --force https://googlemock.googlecode.com/svn/trunk \
 	    testing/gmock --revision 485
 
 dependencies: builddeps
diff --git a/Makefile.android b/Makefile.android
index 8e200f1..2a36403 100644
--- a/Makefile.android
+++ b/Makefile.android
@@ -38,12 +38,10 @@
 ANDROID_NDK_HOST_ARCH ?= $(shell uname -m | sed -e 's/i[3456]86/x86/')
 ifeq ($(HOST_OS), linux)
   TOOLCHAIN_DIR = linux-$(ANDROID_NDK_HOST_ARCH)
+else ifeq ($(HOST_OS), mac)
+  TOOLCHAIN_DIR = darwin-$(ANDROID_NDK_HOST_ARCH)
 else
-  ifeq ($(HOST_OS), mac)
-    TOOLCHAIN_DIR = darwin-$(ANDROID_NDK_HOST_ARCH)
-  else
-    $(error Host platform "${HOST_OS}" is not supported)
-  endif
+  $(error Host platform "${HOST_OS}" is not supported)
 endif
 
 ifeq ($(ARCH), android_arm)
@@ -52,38 +50,29 @@
   TOOLCHAIN_ARCH = arm-linux-androideabi
   TOOLCHAIN_PREFIX = $(TOOLCHAIN_ARCH)
   TOOLCHAIN_VER = 4.8
+else ifeq ($(ARCH), android_arm64)
+  DEFINES  = target_arch=arm64 v8_target_arch=arm64 android_target_arch=arm64 android_target_platform=21
+  TOOLCHAIN_ARCH = aarch64-linux-android
+  TOOLCHAIN_PREFIX = $(TOOLCHAIN_ARCH)
+  TOOLCHAIN_VER = 4.9
+else ifeq ($(ARCH), android_mipsel)
+  DEFINES  = target_arch=mipsel v8_target_arch=mipsel android_target_platform=14
+  DEFINES += android_target_arch=mips mips_arch_variant=mips32r2
+  TOOLCHAIN_ARCH = mipsel-linux-android
+  TOOLCHAIN_PREFIX = $(TOOLCHAIN_ARCH)
+  TOOLCHAIN_VER = 4.8
+else ifeq ($(ARCH), android_ia32)
+  DEFINES = target_arch=ia32 v8_target_arch=ia32 android_target_arch=x86 android_target_platform=14
+  TOOLCHAIN_ARCH = x86
+  TOOLCHAIN_PREFIX = i686-linux-android
+  TOOLCHAIN_VER = 4.8
+else ifeq ($(ARCH), android_x87)
+  DEFINES = target_arch=x87 v8_target_arch=x87 android_target_arch=x86 android_target_platform=14
+  TOOLCHAIN_ARCH = x86
+  TOOLCHAIN_PREFIX = i686-linux-android
+  TOOLCHAIN_VER = 4.8
 else
-  ifeq ($(ARCH), android_arm64)
-    DEFINES  = target_arch=arm64 v8_target_arch=arm64 android_target_arch=arm64 android_target_platform=L
-    TOOLCHAIN_ARCH = aarch64-linux-android
-    TOOLCHAIN_PREFIX = $(TOOLCHAIN_ARCH)
-    TOOLCHAIN_VER = 4.9
-  else
-    ifeq ($(ARCH), android_mipsel)
-      DEFINES  = target_arch=mipsel v8_target_arch=mipsel android_target_platform=14
-      DEFINES += android_target_arch=mips mips_arch_variant=mips32r2
-      TOOLCHAIN_ARCH = mipsel-linux-android
-      TOOLCHAIN_PREFIX = $(TOOLCHAIN_ARCH)
-      TOOLCHAIN_VER = 4.8
-
-    else
-      ifeq ($(ARCH), android_ia32)
-        DEFINES = target_arch=ia32 v8_target_arch=ia32 android_target_arch=x86 android_target_platform=14
-        TOOLCHAIN_ARCH = x86
-        TOOLCHAIN_PREFIX = i686-linux-android
-        TOOLCHAIN_VER = 4.8
-      else
-        ifeq ($(ARCH), android_x87)
-          DEFINES = target_arch=x87 v8_target_arch=x87 android_target_arch=x86 android_target_platform=14
-          TOOLCHAIN_ARCH = x86
-          TOOLCHAIN_PREFIX = i686-linux-android
-          TOOLCHAIN_VER = 4.8
-	else
-          $(error Target architecture "${ARCH}" is not supported)
-        endif
-      endif
-    endif
-  endif
+  $(error Target architecture "${ARCH}" is not supported)
 endif
 
 TOOLCHAIN_PATH = \
diff --git a/Makefile.nacl b/Makefile.nacl
index 34bd960..3459c42 100644
--- a/Makefile.nacl
+++ b/Makefile.nacl
@@ -36,41 +36,29 @@
                    $(addsuffix .$(mode),$(NACL_ARCHES)))
 
 HOST_OS = $(shell uname -s | sed -e 's/Linux/linux/;s/Darwin/mac/')
-ifeq ($(HOST_OS), linux)
-  TOOLCHAIN_DIR = linux_x86_glibc
-else
-  ifeq ($(HOST_OS), mac)
-    TOOLCHAIN_DIR = mac_x86_glibc
-  else
-    $(error Host platform "${HOST_OS}" is not supported)
-  endif
-endif
-
 TOOLCHAIN_PATH = $(realpath ${NACL_SDK_ROOT}/toolchain)
-NACL_TOOLCHAIN ?= ${TOOLCHAIN_PATH}/${TOOLCHAIN_DIR}
-
-ifeq ($(ARCH), nacl_ia32)
-  GYPENV = nacl_target_arch=nacl_ia32 v8_target_arch=arm v8_host_arch=ia32
-  TOOLCHAIN_ARCH = x86-4.4
-  NACL_CC = "$(NACL_TOOLCHAIN)/bin/i686-nacl-gcc"
-  NACL_CXX = "$(NACL_TOOLCHAIN)/bin/i686-nacl-g++"
-  NACL_LINK = "$(NACL_TOOLCHAIN)/bin/i686-nacl-g++"
-else
-  ifeq ($(ARCH), nacl_x64)
-    GYPENV = nacl_target_arch=nacl_x64 v8_target_arch=arm v8_host_arch=ia32
-    TOOLCHAIN_ARCH = x86-4.4
-    NACL_CC = "$(NACL_TOOLCHAIN)/bin/x86_64-nacl-gcc"
-    NACL_CXX = "$(NACL_TOOLCHAIN)/bin/x86_64-nacl-g++"
-    NACL_LINK = "$(NACL_TOOLCHAIN)/bin/x86_64-nacl-g++"
-  else
-    $(error Target architecture "${ARCH}" is not supported)
-  endif
-endif
+NACL_TOOLCHAIN ?= ${TOOLCHAIN_PATH}/linux_pnacl
 
 ifeq ($(wildcard $(NACL_TOOLCHAIN)),)
   $(error Cannot find Native Client toolchain in "${NACL_TOOLCHAIN}")
 endif
 
+ifeq ($(ARCH), nacl_ia32)
+  GYPENV = nacl_target_arch=nacl_ia32 v8_target_arch=arm v8_host_arch=ia32
+  NACL_CC = "$(NACL_TOOLCHAIN)/bin/pnacl-clang"
+  NACL_CXX = "$(NACL_TOOLCHAIN)/bin/pnacl-clang++"
+  NACL_LINK = "$(NACL_TOOLCHAIN)/bin/pnacl-clang++ --pnacl-allow-native -arch x86-32"
+else
+  ifeq ($(ARCH), nacl_x64)
+    GYPENV = nacl_target_arch=nacl_x64 v8_target_arch=arm v8_host_arch=ia32
+    NACL_CC = "$(NACL_TOOLCHAIN)/bin/pnacl-clang"
+    NACL_CXX = "$(NACL_TOOLCHAIN)/bin/pnacl-clang++"
+    NACL_LINK = "$(NACL_TOOLCHAIN)/bin/pnacl-clang++ --pnacl-allow-native -arch x86-64"
+  else
+    $(error Target architecture "${ARCH}" is not supported)
+  endif
+endif
+
 # For mksnapshot host generation.
 GYPENV += host_os=${HOST_OS}
 
@@ -85,7 +73,11 @@
 # For some reason the $$(basename $$@) expansion didn't work here...
 $(NACL_BUILDS): $(NACL_MAKEFILES)
 	@$(MAKE) -C "$(OUTDIR)" -f Makefile.$@ \
+	            CC=${NACL_CC} \
 	            CXX=${NACL_CXX} \
+	            AR="$(NACL_TOOLCHAIN)/bin/pnacl-ar" \
+	            RANLIB="$(NACL_TOOLCHAIN)/bin/pnacl-ranlib" \
+	            LD="$(NACL_TOOLCHAIN)/bin/pnacl-ld" \
 	            LINK=${NACL_LINK} \
 	            BUILDTYPE=$(shell echo $(subst .,,$(suffix $@)) | \
 	                        python -c "print raw_input().capitalize()") \
@@ -97,6 +89,7 @@
 	GYP_DEFINES="${GYPENV}" \
 	CC=${NACL_CC} \
 	CXX=${NACL_CXX} \
+	LINK=${NACL_LINK} \
 	PYTHONPATH="$(shell pwd)/tools/generate_shim_headers:$(shell pwd)/build:$(PYTHONPATH)" \
 	build/gyp/gyp --generator-output="${OUTDIR}" build/all.gyp \
 	              -Ibuild/standalone.gypi --depth=. \
diff --git a/OWNERS b/OWNERS
index f67b3ec..22a05cb 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,3 +1,4 @@
+adamk@chromium.org
 bmeurer@chromium.org
 danno@chromium.org
 dcarney@chromium.org
@@ -16,7 +17,6 @@
 svenpanne@chromium.org
 titzer@chromium.org
 ulan@chromium.org
-vegorov@chromium.org
 verwaest@chromium.org
 vogelheim@chromium.org
 yangguo@chromium.org
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 3a9895d..6d19a4e 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -244,11 +244,11 @@
       'v8_linux_rel': set(['defaulttests']),
       'v8_linux_dbg': set(['defaulttests']),
       'v8_linux_nosnap_rel': set(['defaulttests']),
-      'v8_linux_nosnap_dbg': set(['defaulttests']),
       'v8_linux64_rel': set(['defaulttests']),
       'v8_linux_arm_dbg': set(['defaulttests']),
       'v8_linux_arm64_rel': set(['defaulttests']),
       'v8_linux_layout_dbg': set(['defaulttests']),
+      'v8_linux_chromium_gn_rel': set(['defaulttests']),
       'v8_mac_rel': set(['defaulttests']),
       'v8_win_rel': set(['defaulttests']),
       'v8_win64_compile_rel': set(['defaulttests']),
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..bc1685a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,33 @@
+V8 JavaScript Engine
+=============
+
+V8 is Google's open source JavaScript engine.
+
+V8 implements ECMAScript as specified in ECMA-262.
+
+V8 is written in C++ and is used in Google Chrome, the open source
+browser from Google.
+
+V8 can run standalone, or can be embedded into any C++ application.
+
+V8 Project page: https://code.google.com/p/v8/
+
+
+Getting the Code
+=============
+
+Checkout [depot tools](http://www.chromium.org/developers/how-tos/install-depot-tools), and run
+
+> `fetch v8`
+
+This will checkout V8 into the directory `v8` and fetch all of its dependencies.
+To stay up to date, run
+
+> `git pull origin`
+> `gclient sync`
+
+For fetching all branches, add the following into your remote
+configuration in `.git/config`:
+
+        fetch = +refs/branch-heads/*:refs/remotes/branch-heads/*
+        fetch = +refs/tags/*:refs/tags/*
diff --git a/V8_MERGE_REVISION b/V8_MERGE_REVISION
index fd6b1b2..aab9fb9 100644
--- a/V8_MERGE_REVISION
+++ b/V8_MERGE_REVISION
@@ -1,2 +1,2 @@
-v8 3.29.88.18
-https://chromium.googlesource.com/v8/v8/+/f0158730a3b758d746287cacc315ae262b83232d
+v8 4.1.0.21
+https://chromium.googlesource.com/v8/v8/+/4.1.0.21
diff --git a/build/all.gyp b/build/all.gyp
index 1e420fa..4aeb507 100644
--- a/build/all.gyp
+++ b/build/all.gyp
@@ -9,18 +9,14 @@
       'type': 'none',
       'dependencies': [
         '../samples/samples.gyp:*',
-        '../src/base/base.gyp:base-unittests',
-        '../src/compiler/compiler.gyp:compiler-unittests',
         '../src/d8.gyp:d8',
-        '../src/heap/heap.gyp:heap-unittests',
-        '../src/libplatform/libplatform.gyp:libplatform-unittests',
         '../test/cctest/cctest.gyp:*',
+        '../test/unittests/unittests.gyp:*',
       ],
       'conditions': [
         ['component!="shared_library"', {
           'dependencies': [
-            '../tools/lexer-shell.gyp:lexer-shell',
-            '../tools/lexer-shell.gyp:parser-shell',
+            '../tools/parser-shell.gyp:parser-shell',
           ],
         }],
       ]
diff --git a/build/android.gypi b/build/android.gypi
index f984ea3..5d3b25a 100644
--- a/build/android.gypi
+++ b/build/android.gypi
@@ -74,13 +74,13 @@
         ],
       },  # Release
     },  # configurations
-    'cflags': [ '-Wno-abi', '-Wall', '-W', '-Wno-unused-parameter',
-                '-Wnon-virtual-dtor', '-fno-rtti', '-fno-exceptions',
-                # Note: Using -std=c++0x will define __STRICT_ANSI__, which in
-                # turn will leave out some template stuff for 'long long'. What
-                # we want is -std=c++11, but this is not supported by GCC 4.6 or
-                # Xcode 4.2
-                '-std=gnu++0x' ],
+    'cflags': [ '-Wno-abi', '-Wall', '-W', '-Wno-unused-parameter'],
+    'cflags_cc': [ '-Wnon-virtual-dtor', '-fno-rtti', '-fno-exceptions',
+                   # Note: Using -std=c++0x will define __STRICT_ANSI__, which
+                   # in turn will leave out some template stuff for 'long
+                   # long'.  What we want is -std=c++11, but this is not
+                   # supported by GCC 4.6 or Xcode 4.2
+                   '-std=gnu++0x' ],
     'target_conditions': [
       ['_toolset=="target"', {
         'cflags!': [
@@ -93,11 +93,13 @@
           '-fno-short-enums',
           '-finline-limit=64',
           '-Wa,--noexecstack',
-          '-Wno-error=non-virtual-dtor',  # TODO(michaelbai): Fix warnings.
           # Note: This include is in cflags to ensure that it comes after
           # all of the includes.
           '-I<(android_include)',
         ],
+        'cflags_cc': [
+          '-Wno-error=non-virtual-dtor',  # TODO(michaelbai): Fix warnings.
+        ],
         'defines': [
           'ANDROID',
           #'__GNU_SOURCE=1',  # Necessary for clone()
@@ -213,8 +215,7 @@
               '-fno-stack-protector',
             ],
           }],
-          ['target_arch=="arm64" or target_arch=="x64"', {
-            # TODO(ulan): Enable PIE for other architectures (crbug.com/373219).
+          ['(target_arch=="arm" or target_arch=="arm64" or target_arch=="x64") and component!="shared_library"', {
             'cflags': [
               '-fPIE',
             ],
diff --git a/build/features.gypi b/build/features.gypi
index 8201ea9..465eba9 100644
--- a/build/features.gypi
+++ b/build/features.gypi
@@ -29,8 +29,6 @@
 
 {
   'variables': {
-    'v8_compress_startup_data%': 'off',
-
     'v8_enable_disassembler%': 0,
 
     'v8_enable_gdbjit%': 0,
@@ -39,6 +37,8 @@
 
     'v8_enable_verify_heap%': 0,
 
+    'v8_trace_maps%': 0,
+
     'v8_use_snapshot%': 'true',
 
     'v8_enable_verify_predictable%': 0,
@@ -59,9 +59,8 @@
     # Enable compiler warnings when using V8_DEPRECATED apis.
     'v8_deprecation_warnings%': 0,
 
-    # Use external files for startup data blobs:
-    # the JS builtins sources and the start snapshot.
-    'v8_use_external_startup_data%': 0,
+    # Set to 1 to enable DCHECKs in release builds.
+    'dcheck_always_on%': 0,
   },
   'target_defaults': {
     'conditions': [
@@ -77,6 +76,9 @@
       ['v8_enable_verify_heap==1', {
         'defines': ['VERIFY_HEAP',],
       }],
+      ['v8_trace_maps==1', {
+        'defines': ['TRACE_MAPS',],
+      }],
       ['v8_enable_verify_predictable==1', {
         'defines': ['VERIFY_PREDICTABLE',],
       }],
@@ -89,12 +91,12 @@
       ['v8_enable_i18n_support==1', {
         'defines': ['V8_I18N_SUPPORT',],
       }],
-      ['v8_compress_startup_data=="bz2"', {
-        'defines': ['COMPRESS_STARTUP_DATA_BZ2',],
-      }],
       ['v8_use_external_startup_data==1', {
         'defines': ['V8_USE_EXTERNAL_STARTUP_DATA',],
       }],
+      ['dcheck_always_on!=0', {
+        'defines': ['DEBUG',],
+      }],
     ],  # conditions
     'configurations': {
       'DebugBaseCommon': {
diff --git a/build/standalone.gypi b/build/standalone.gypi
index 32ad028..ee91e78 100644
--- a/build/standalone.gypi
+++ b/build/standalone.gypi
@@ -33,6 +33,8 @@
   'includes': ['toolchain.gypi'],
   'variables': {
     'component%': 'static_library',
+    'make_clang_dir%': '../third_party/llvm-build/Release+Asserts',
+    'clang_xcode%': 0,
     'asan%': 0,
     'tsan%': 0,
     'visibility%': 'hidden',
@@ -91,6 +93,12 @@
     #     near-release speeds.
     'v8_optimized_debug%': 0,
 
+    # Use external files for startup data blobs:
+    # the JS builtins sources and the start snapshot.
+    # Embedders that don't use standalone.gypi will need to add
+    # their own default value.
+    'v8_use_external_startup_data%': 0,
+
     # Relative path to icu.gyp from this file.
     'icu_gyp_path': '../third_party/icu/icu.gyp',
 
@@ -146,6 +154,14 @@
     'configurations': {
       'DebugBaseCommon': {
         'cflags': [ '-g', '-O0' ],
+        'conditions': [
+          ['(v8_target_arch=="ia32" or v8_target_arch=="x87") and \
+            OS=="linux"', {
+            'defines': [
+              '_GLIBCXX_DEBUG'
+            ],
+          }],
+        ],
       },
       'Optdebug': {
         'inherit_from': [ 'DebugBaseCommon', 'DebugBase2' ],
@@ -323,9 +339,15 @@
           },
           'VCLibrarianTool': {
             'AdditionalOptions': ['/ignore:4221'],
+            'conditions': [
+              ['v8_target_arch=="x64"', {
+                'TargetMachine': '17',  # x64
+              }, {
+                'TargetMachine': '1',  # ia32
+              }],
+            ],
           },
           'VCLinkerTool': {
-            'MinimumRequiredVersion': '5.01',  # XP.
             'AdditionalDependencies': [
               'ws2_32.lib',
             ],
@@ -350,6 +372,13 @@
                   'advapi32.lib',
                 ],
               }],
+              ['v8_target_arch=="x64"', {
+                'MinimumRequiredVersion': '5.02',  # Server 2003.
+                'TargetMachine': '17',  # x64
+              }, {
+                'MinimumRequiredVersion': '5.01',  # XP.
+                'TargetMachine': '1',  # ia32
+              }],
             ],
           },
         },
@@ -357,6 +386,7 @@
     }],  # OS=="win"
     ['OS=="mac"', {
       'xcode_settings': {
+        'SDKROOT': 'macosx',
         'SYMROOT': '<(DEPTH)/xcodebuild',
       },
       'target_defaults': {
@@ -411,5 +441,20 @@
         ],  # target_conditions
       },  # target_defaults
     }],  # OS=="mac"
+    ['clang==1 and ((OS!="mac" and OS!="ios") or clang_xcode==0) '
+        'and OS!="win"', {
+      'make_global_settings': [
+        ['CC', '<(make_clang_dir)/bin/clang'],
+        ['CXX', '<(make_clang_dir)/bin/clang++'],
+        ['CC.host', '$(CC)'],
+        ['CXX.host', '$(CXX)'],
+      ],
+    }],
+    ['clang==1 and OS=="win"', {
+      'make_global_settings': [
+        # On Windows, gyp's ninja generator only looks at CC.
+        ['CC', '<(make_clang_dir)/bin/clang-cl'],
+      ],
+    }],
   ],
 }
diff --git a/build/toolchain.gypi b/build/toolchain.gypi
index 38c9aee..ac10065 100644
--- a/build/toolchain.gypi
+++ b/build/toolchain.gypi
@@ -30,7 +30,6 @@
 {
   'variables': {
     'msvs_use_common_release': 0,
-    'gcc_version%': 'unknown',
     'clang%': 0,
     'v8_target_arch%': '<(target_arch)',
     # Native Client builds currently use the V8 ARM JIT and
@@ -888,7 +887,6 @@
           ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \
             OS=="qnx"', {
             'cflags!': [
-              '-O0',
               '-O3',
               '-O2',
               '-O1',
@@ -905,6 +903,9 @@
             },
           }],
         ],
+        'defines': [
+          'ENABLE_SLOW_DCHECKS',
+        ],
       },  # DebugBase0
       # Abstract configuration for v8_optimized_debug == 1.
       'DebugBase1': {
@@ -929,6 +930,9 @@
             'LinkIncremental': '2',
           },
         },
+        'defines': [
+          'ENABLE_SLOW_DCHECKS',
+        ],
         'conditions': [
           ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \
             OS=="qnx"', {
@@ -943,14 +947,6 @@
               '-ffunction-sections',
               '-O1', # TODO(2807) should be -O3.
             ],
-            'conditions': [
-              ['gcc_version==44 and clang==0', {
-                'cflags': [
-                  # Avoid crashes with gcc 4.4 in the v8 test suite.
-                  '-fno-tree-vrp',
-                ],
-              }],
-            ],
           }],
           ['OS=="mac"', {
             'xcode_settings': {
@@ -977,10 +973,6 @@
               }, {
                 'RuntimeLibrary': '1',  #/MTd
               }],
-              ['v8_target_arch=="x64"', {
-                # TODO(2207): remove this option once the bug is fixed.
-                'WholeProgramOptimization': 'true',
-              }],
             ],
           },
           'VCLinkerTool': {
@@ -1001,9 +993,6 @@
               '-fdata-sections',
               '-ffunction-sections',
             ],
-            'defines': [
-              'OPTIMIZED_DEBUG'
-            ],
             'conditions': [
               # TODO(crbug.com/272548): Avoid -O3 in NaCl
               ['nacl_target_arch=="none"', {
@@ -1013,12 +1002,6 @@
                 'cflags': ['-O2'],
                 'cflags!': ['-O3'],
               }],
-              ['gcc_version==44 and clang==0', {
-                'cflags': [
-                  # Avoid crashes with gcc 4.4 in the v8 test suite.
-                  '-fno-tree-vrp',
-                ],
-              }],
             ],
           }],
           ['OS=="mac"', {
@@ -1037,7 +1020,8 @@
           'V8_ENABLE_CHECKS',
           'OBJECT_PRINT',
           'VERIFY_HEAP',
-          'DEBUG'
+          'DEBUG',
+          'TRACE_MAPS'
         ],
         'conditions': [
           ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd" or \
@@ -1058,6 +1042,7 @@
                 # TODO(2304): pass DISABLE_DEBUG_ASSERT instead of hiding DEBUG.
                 'defines!': [
                   'DEBUG',
+                  'ENABLE_SLOW_DCHECKS',
                 ],
               }],
             ],
@@ -1090,12 +1075,6 @@
               '<(wno_array_bounds)',
             ],
             'conditions': [
-              [ 'gcc_version==44 and clang==0', {
-                'cflags': [
-                  # Avoid crashes with gcc 4.4 in the v8 test suite.
-                  '-fno-tree-vrp',
-                ],
-              }],
               # TODO(crbug.com/272548): Avoid -O3 in NaCl
               ['nacl_target_arch=="none"', {
                 'cflags': ['-O3'],
@@ -1116,14 +1095,6 @@
               '-ffunction-sections',
               '-O2',
             ],
-            'conditions': [
-              [ 'gcc_version==44 and clang==0', {
-                'cflags': [
-                  # Avoid crashes with gcc 4.4 in the v8 test suite.
-                  '-fno-tree-vrp',
-                ],
-              }],
-            ],
           }],
           ['OS=="mac"', {
             'xcode_settings': {
@@ -1150,10 +1121,6 @@
                   }, {
                     'RuntimeLibrary': '0',  #/MT
                   }],
-                  ['v8_target_arch=="x64"', {
-                    # TODO(2207): remove this option once the bug is fixed.
-                    'WholeProgramOptimization': 'true',
-                  }],
                 ],
               },
               'VCLinkerTool': {
diff --git a/buildtools b/buildtools
new file mode 160000
index 0000000..3b302fe
--- /dev/null
+++ b/buildtools
@@ -0,0 +1 @@
+Subproject commit 3b302fef93f7cc58d9b8168466905237484b2772
diff --git a/codereview.settings b/codereview.settings
index b7f853c..a7ee88e 100644
--- a/codereview.settings
+++ b/codereview.settings
@@ -1,8 +1,9 @@
 CODE_REVIEW_SERVER: https://codereview.chromium.org
 CC_LIST: v8-dev@googlegroups.com
-VIEW_VC: https://code.google.com/p/v8/source/detail?r=
+VIEW_VC: https://chromium.googlesource.com/v8/v8/+/
 STATUS: http://v8-status.appspot.com/status
 TRY_ON_UPLOAD: False
 TRYSERVER_SVN_URL: svn://svn.chromium.org/chrome-try-v8
 TRYSERVER_ROOT: v8
 PROJECT: v8
+PENDING_REF_PREFIX: refs/pending/
diff --git a/include/v8-platform.h b/include/v8-platform.h
index 1f1679f..67fb384 100644
--- a/include/v8-platform.h
+++ b/include/v8-platform.h
@@ -55,6 +55,15 @@
    * scheduling. The definition of "foreground" is opaque to V8.
    */
   virtual void CallOnForegroundThread(Isolate* isolate, Task* task) = 0;
+
+  /**
+   * Monotonically increasing time in seconds from an arbitrary fixed point in
+   * the past. This function is expected to return at least
+   * millisecond-precision values. For this reason,
+   * it is recommended that the fixed point be no further in the past than
+   * the epoch.
+   **/
+  virtual double MonotonicallyIncreasingTime() = 0;
 };
 
 }  // namespace v8
diff --git a/include/v8-profiler.h b/include/v8-profiler.h
index 7fc193d..d021520 100644
--- a/include/v8-profiler.h
+++ b/include/v8-profiler.h
@@ -22,6 +22,14 @@
  */
 class V8_EXPORT CpuProfileNode {
  public:
+  struct LineTick {
+    /** The 1-based number of the source line where the function originates. */
+    int line;
+
+    /** The count of samples associated with the source line. */
+    unsigned int hit_count;
+  };
+
   /** Returns function name (empty string for anonymous functions.) */
   Handle<String> GetFunctionName() const;
 
@@ -43,6 +51,18 @@
    */
   int GetColumnNumber() const;
 
+  /**
+   * Returns the number of the function's source lines that collect the samples.
+   */
+  unsigned int GetHitLineCount() const;
+
+  /** Returns the set of source lines that collect the samples.
+   *  The caller allocates buffer and responsible for releasing it.
+   *  True if all available entries are copied, otherwise false.
+   *  The function copies nothing if buffer is not large enough.
+   */
+  bool GetLineTicks(LineTick* entries, unsigned int length) const;
+
   /** Returns bailout reason for the function
     * if the optimization was disabled for it.
     */
diff --git a/include/v8.h b/include/v8.h
index ec1941e..b445525 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -15,7 +15,11 @@
 #ifndef V8_H_
 #define V8_H_
 
-#include "v8stdint.h"
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#include "v8config.h"
 
 // We reserve the V8_* prefix for macros defined in V8 public API and
 // assume there are no name conflicts with the embedder's code.
@@ -85,6 +89,7 @@
 class ObjectTemplate;
 class Platform;
 class Primitive;
+class Promise;
 class RawOperationDescriptor;
 class Script;
 class Signature;
@@ -135,6 +140,17 @@
 class PropertyCallbackArguments;
 class FunctionCallbackArguments;
 class GlobalHandles;
+
+class CallbackData {
+ public:
+  V8_INLINE v8::Isolate* GetIsolate() const { return isolate_; }
+
+ protected:
+  explicit CallbackData(v8::Isolate* isolate) : isolate_(isolate) {}
+
+ private:
+  v8::Isolate* isolate_;
+};
 }
 
 
@@ -413,22 +429,53 @@
 };
 
 
-template<class T, class P>
-class WeakCallbackData {
+template <typename T>
+class PhantomCallbackData : public internal::CallbackData {
+ public:
+  typedef void (*Callback)(const PhantomCallbackData<T>& data);
+
+  V8_INLINE T* GetParameter() const { return parameter_; }
+
+  PhantomCallbackData<T>(Isolate* isolate, T* parameter)
+      : internal::CallbackData(isolate), parameter_(parameter) {}
+
+ private:
+  T* parameter_;
+};
+
+
+template <class T, class P>
+class WeakCallbackData : public PhantomCallbackData<P> {
  public:
   typedef void (*Callback)(const WeakCallbackData<T, P>& data);
 
-  V8_INLINE Isolate* GetIsolate() const { return isolate_; }
   V8_INLINE Local<T> GetValue() const { return handle_; }
-  V8_INLINE P* GetParameter() const { return parameter_; }
 
  private:
   friend class internal::GlobalHandles;
-  WeakCallbackData(Isolate* isolate, Local<T> handle, P* parameter)
-    : isolate_(isolate), handle_(handle), parameter_(parameter) { }
-  Isolate* isolate_;
+  WeakCallbackData(Isolate* isolate, P* parameter, Local<T> handle)
+      : PhantomCallbackData<P>(isolate, parameter), handle_(handle) {}
   Local<T> handle_;
-  P* parameter_;
+};
+
+
+template <typename T, typename U>
+class InternalFieldsCallbackData : public internal::CallbackData {
+ public:
+  typedef void (*Callback)(const InternalFieldsCallbackData<T, U>& data);
+
+  InternalFieldsCallbackData(Isolate* isolate, T* internalField1,
+                             U* internalField2)
+      : internal::CallbackData(isolate),
+        internal_field1_(internalField1),
+        internal_field2_(internalField2) {}
+
+  V8_INLINE T* GetInternalField1() const { return internal_field1_; }
+  V8_INLINE U* GetInternalField2() const { return internal_field2_; }
+
+ private:
+  T* internal_field1_;
+  U* internal_field2_;
 };
 
 
@@ -466,22 +513,23 @@
   template <class S>
   V8_INLINE void Reset(Isolate* isolate, const PersistentBase<S>& other);
 
-  V8_INLINE bool IsEmpty() const { return val_ == 0; }
+  V8_INLINE bool IsEmpty() const { return val_ == NULL; }
+  V8_INLINE void Empty() { val_ = 0; }
 
   template <class S>
   V8_INLINE bool operator==(const PersistentBase<S>& that) const {
     internal::Object** a = reinterpret_cast<internal::Object**>(this->val_);
     internal::Object** b = reinterpret_cast<internal::Object**>(that.val_);
-    if (a == 0) return b == 0;
-    if (b == 0) return false;
+    if (a == NULL) return b == NULL;
+    if (b == NULL) return false;
     return *a == *b;
   }
 
   template <class S> V8_INLINE bool operator==(const Handle<S>& that) const {
     internal::Object** a = reinterpret_cast<internal::Object**>(this->val_);
     internal::Object** b = reinterpret_cast<internal::Object**>(that.val_);
-    if (a == 0) return b == 0;
-    if (b == 0) return false;
+    if (a == NULL) return b == NULL;
+    if (b == NULL) return false;
     return *a == *b;
   }
 
@@ -511,6 +559,21 @@
       P* parameter,
       typename WeakCallbackData<S, P>::Callback callback);
 
+  // Phantom persistents work like weak persistents, except that the pointer to
+  // the object being collected is not available in the finalization callback.
+  // This enables the garbage collector to collect the object and any objects
+  // it references transitively in one GC cycle. At the moment you can either
+  // specify a parameter for the callback or the location of two internal
+  // fields in the dying object.
+  template <typename P>
+  V8_INLINE void SetPhantom(P* parameter,
+                            typename PhantomCallbackData<P>::Callback callback);
+
+  template <typename P, typename Q>
+  V8_INLINE void SetPhantom(
+      void (*callback)(const InternalFieldsCallbackData<P, Q>&),
+      int internal_field_index1, int internal_field_index2);
+
   template<typename P>
   V8_INLINE P* ClearWeak();
 
@@ -696,9 +759,6 @@
     return Persistent<S>::Cast(*this);
   }
 
-  // This will be removed.
-  V8_INLINE T* ClearAndLeak();
-
  private:
   friend class Isolate;
   friend class Utils;
@@ -997,7 +1057,7 @@
   /**
    * Runs the script returning the resulting value. It will be run in the
    * context in which it was created (ScriptCompiler::CompileBound or
-   * UnboundScript::BindToGlobalContext()).
+   * UnboundScript::BindToCurrentContext()).
    */
   Local<Value> Run();
 
@@ -1031,7 +1091,11 @@
       BufferOwned
     };
 
-    CachedData() : data(NULL), length(0), buffer_policy(BufferNotOwned) {}
+    CachedData()
+        : data(NULL),
+          length(0),
+          rejected(false),
+          buffer_policy(BufferNotOwned) {}
 
     // If buffer_policy is BufferNotOwned, the caller keeps the ownership of
     // data and guarantees that it stays alive until the CachedData object is
@@ -1044,6 +1108,7 @@
     // which will be called when V8 no longer needs the data.
     const uint8_t* data;
     int length;
+    bool rejected;
     BufferPolicy buffer_policy;
 
    private:
@@ -1224,6 +1289,26 @@
   static Local<Script> Compile(Isolate* isolate, StreamedSource* source,
                                Handle<String> full_source_string,
                                const ScriptOrigin& origin);
+
+  /**
+   * Return a version tag for CachedData for the current V8 version & flags.
+   *
+   * This value is meant only for determining whether a previously generated
+   * CachedData instance is still valid; the tag has no other meaing.
+   *
+   * Background: The data carried by CachedData may depend on the exact
+   *   V8 version number or currently compiler flags. This means when
+   *   persisting CachedData, the embedder must take care to not pass in
+   *   data from another V8 version, or the same version with different
+   *   features enabled.
+   *
+   *   The easiest way to do so is to clear the embedder's cache on any
+   *   such change.
+   *
+   *   Alternatively, this tag can be stored alongside the cached data and
+   *   compared when it is being used.
+   */
+  static uint32_t CachedDataVersionTag();
 };
 
 
@@ -1415,6 +1500,27 @@
 };
 
 
+// A StateTag represents a possible state of the VM.
+enum StateTag { JS, GC, COMPILER, OTHER, EXTERNAL, IDLE };
+
+
+// A RegisterState represents the current state of registers used
+// by the sampling profiler API.
+struct RegisterState {
+  RegisterState() : pc(NULL), sp(NULL), fp(NULL) {}
+  void* pc;  // Instruction pointer.
+  void* sp;  // Stack pointer.
+  void* fp;  // Frame pointer.
+};
+
+
+// The output structure filled up by GetStackSample API function.
+struct SampleInfo {
+  size_t frames_count;
+  StateTag vm_state;
+};
+
+
 /**
  * A JSON Parser.
  */
@@ -1561,6 +1667,18 @@
   bool IsRegExp() const;
 
   /**
+   * Returns true if this value is a Generator function.
+   * This is an experimental feature.
+   */
+  bool IsGeneratorFunction() const;
+
+  /**
+   * Returns true if this value is a Generator object (iterator).
+   * This is an experimental feature.
+   */
+  bool IsGeneratorObject() const;
+
+  /**
    * Returns true if this value is a Promise.
    * This is an experimental feature.
    */
@@ -1579,6 +1697,18 @@
   bool IsSet() const;
 
   /**
+   * Returns true if this value is a Map Iterator.
+   * This is an experimental feature.
+   */
+  bool IsMapIterator() const;
+
+  /**
+   * Returns true if this value is a Set Iterator.
+   * This is an experimental feature.
+   */
+  bool IsSetIterator() const;
+
+  /**
    * Returns true if this value is a WeakMap.
    * This is an experimental feature.
    */
@@ -1668,14 +1798,24 @@
    */
   bool IsDataView() const;
 
-  Local<Boolean> ToBoolean() const;
-  Local<Number> ToNumber() const;
-  Local<String> ToString() const;
-  Local<String> ToDetailString() const;
-  Local<Object> ToObject() const;
-  Local<Integer> ToInteger() const;
-  Local<Uint32> ToUint32() const;
-  Local<Int32> ToInt32() const;
+  Local<Boolean> ToBoolean(Isolate* isolate) const;
+  Local<Number> ToNumber(Isolate* isolate) const;
+  Local<String> ToString(Isolate* isolate) const;
+  Local<String> ToDetailString(Isolate* isolate) const;
+  Local<Object> ToObject(Isolate* isolate) const;
+  Local<Integer> ToInteger(Isolate* isolate) const;
+  Local<Uint32> ToUint32(Isolate* isolate) const;
+  Local<Int32> ToInt32(Isolate* isolate) const;
+
+  // TODO(dcarney): deprecate all these.
+  inline Local<Boolean> ToBoolean() const;
+  inline Local<Number> ToNumber() const;
+  inline Local<String> ToString() const;
+  inline Local<String> ToDetailString() const;
+  inline Local<Object> ToObject() const;
+  inline Local<Integer> ToInteger() const;
+  inline Local<Uint32> ToUint32() const;
+  inline Local<Int32> ToInt32() const;
 
   /**
    * Attempts to convert a string to an array index.
@@ -1728,6 +1868,15 @@
  */
 class V8_EXPORT Name : public Primitive {
  public:
+  /**
+   * Returns the identity hash for this object. The current implementation
+   * uses an inline property on the object to store the identity hash.
+   *
+   * The return value will never be 0. Also, it is not guaranteed to be
+   * unique.
+   */
+  int GetIdentityHash();
+
   V8_INLINE static Name* Cast(v8::Value* obj);
  private:
   static void CheckCast(v8::Value* obj);
@@ -1742,7 +1891,6 @@
   enum Encoding {
     UNKNOWN_ENCODING = 0x1,
     TWO_BYTE_ENCODING = 0x0,
-    ASCII_ENCODING = 0x4,  // TODO(yangguo): deprecate this.
     ONE_BYTE_ENCODING = 0x4
   };
   /**
@@ -1798,7 +1946,6 @@
     NO_OPTIONS = 0,
     HINT_MANY_WRITES_EXPECTED = 1,
     NO_NULL_TERMINATION = 2,
-    PRESERVE_ASCII_NULL = 4,  // TODO(yangguo): deprecate this.
     PRESERVE_ONE_BYTE_NULL = 4,
     // Used by WriteUtf8 to replace orphan surrogate code units with the
     // unicode replacement character. Needs to be set to guarantee valid UTF-8
@@ -1837,9 +1984,6 @@
    */
   bool IsExternalOneByte() const;
 
-  // TODO(yangguo): deprecate this.
-  bool IsExternalAscii() const { return IsExternalOneByte(); }
-
   class V8_EXPORT ExternalStringResourceBase {  // NOLINT
    public:
     virtual ~ExternalStringResourceBase() {}
@@ -1918,8 +2062,6 @@
     ExternalOneByteStringResource() {}
   };
 
-  typedef ExternalOneByteStringResource ExternalAsciiStringResource;
-
   /**
    * If the string is an external string, return the ExternalStringResourceBase
    * regardless of the encoding, otherwise return NULL.  The encoding of the
@@ -1940,11 +2082,6 @@
    */
   const ExternalOneByteStringResource* GetExternalOneByteStringResource() const;
 
-  // TODO(yangguo): deprecate this.
-  const ExternalAsciiStringResource* GetExternalAsciiStringResource() const {
-    return GetExternalOneByteStringResource();
-  }
-
   V8_INLINE static String* Cast(v8::Value* obj);
 
   enum NewStringType {
@@ -2107,6 +2244,7 @@
   // Well-known symbols
   static Local<Symbol> GetIterator(Isolate* isolate);
   static Local<Symbol> GetUnscopables(Isolate* isolate);
+  static Local<Symbol> GetToStringTag(Isolate* isolate);
 
   V8_INLINE static Symbol* Cast(v8::Value* obj);
 
@@ -2400,6 +2538,8 @@
   /** Gets the number of internal fields for this Object. */
   int InternalFieldCount();
 
+  static const int kNoInternalFieldIndex = -1;
+
   /** Same as above, but works for Persistents */
   V8_INLINE static int InternalFieldCount(
       const PersistentBase<Object>& object) {
@@ -2484,15 +2624,6 @@
   bool DeleteHiddenValue(Handle<String> key);
 
   /**
-   * Returns true if this is an instance of an api function (one
-   * created from a function created from a function template) and has
-   * been modified since it was created.  Note that this method is
-   * conservative and may return true for objects that haven't actually
-   * been modified.
-   */
-  bool IsDirty();
-
-  /**
    * Clone this object with a fast but shallow copy.  Values will point
    * to the same values as the original object.
    */
@@ -2552,6 +2683,11 @@
    */
   Local<Value> CallAsConstructor(int argc, Handle<Value> argv[]);
 
+  /**
+   * Return the isolate to which the Object belongs to.
+   */
+  Isolate* GetIsolate();
+
   static Local<Object> New(Isolate* isolate);
 
   V8_INLINE static Object* Cast(Value* obj);
@@ -2818,6 +2954,12 @@
   Local<Promise> Catch(Handle<Function> handler);
   Local<Promise> Then(Handle<Function> handler);
 
+  /**
+   * Returns true if the promise has at least one derived promise, and
+   * therefore resolve/reject handlers (including default handler).
+   */
+  bool HasHandler();
+
   V8_INLINE static Promise* Cast(Value* obj);
 
  private:
@@ -2920,10 +3062,15 @@
   bool IsExternal() const;
 
   /**
+   * Returns true if this ArrayBuffer may be neutered.
+   */
+  bool IsNeuterable() const;
+
+  /**
    * Neuters this ArrayBuffer and all its views (typed arrays).
    * Neutering sets the byte length of the buffer and all typed arrays to zero,
    * preventing JavaScript from ever accessing underlying backing store.
-   * ArrayBuffer should have been externalized.
+   * ArrayBuffer should have been externalized and must be neuterable.
    */
   void Neuter();
 
@@ -3455,6 +3602,51 @@
     const PropertyCallbackInfo<Array>& info);
 
 
+// TODO(dcarney): Deprecate and remove previous typedefs, and replace
+// GenericNamedPropertyFooCallback with just NamedPropertyFooCallback.
+/**
+ * GenericNamedProperty[Getter|Setter] are used as interceptors on object.
+ * See ObjectTemplate::SetNamedPropertyHandler.
+ */
+typedef void (*GenericNamedPropertyGetterCallback)(
+    Local<Name> property, const PropertyCallbackInfo<Value>& info);
+
+
+/**
+ * Returns the value if the setter intercepts the request.
+ * Otherwise, returns an empty handle.
+ */
+typedef void (*GenericNamedPropertySetterCallback)(
+    Local<Name> property, Local<Value> value,
+    const PropertyCallbackInfo<Value>& info);
+
+
+/**
+ * Returns a non-empty handle if the interceptor intercepts the request.
+ * The result is an integer encoding property attributes (like v8::None,
+ * v8::DontEnum, etc.)
+ */
+typedef void (*GenericNamedPropertyQueryCallback)(
+    Local<Name> property, const PropertyCallbackInfo<Integer>& info);
+
+
+/**
+ * Returns a non-empty handle if the deleter intercepts the request.
+ * The return value is true if the property could be deleted and false
+ * otherwise.
+ */
+typedef void (*GenericNamedPropertyDeleterCallback)(
+    Local<Name> property, const PropertyCallbackInfo<Boolean>& info);
+
+
+/**
+ * Returns an array containing the names of the properties the named
+ * property getter intercepts.
+ */
+typedef void (*GenericNamedPropertyEnumeratorCallback)(
+    const PropertyCallbackInfo<Array>& info);
+
+
 /**
  * Returns the value of the property if the getter intercepts the
  * request.  Otherwise, returns an empty handle.
@@ -3707,6 +3899,65 @@
 };
 
 
+enum class PropertyHandlerFlags { kNone = 0, kAllCanRead = 1 };
+
+
+struct NamedPropertyHandlerConfiguration {
+  NamedPropertyHandlerConfiguration(
+      /** Note: getter is required **/
+      GenericNamedPropertyGetterCallback getter = 0,
+      GenericNamedPropertySetterCallback setter = 0,
+      GenericNamedPropertyQueryCallback query = 0,
+      GenericNamedPropertyDeleterCallback deleter = 0,
+      GenericNamedPropertyEnumeratorCallback enumerator = 0,
+      Handle<Value> data = Handle<Value>(),
+      PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
+      : getter(getter),
+        setter(setter),
+        query(query),
+        deleter(deleter),
+        enumerator(enumerator),
+        data(data),
+        flags(flags) {}
+
+  GenericNamedPropertyGetterCallback getter;
+  GenericNamedPropertySetterCallback setter;
+  GenericNamedPropertyQueryCallback query;
+  GenericNamedPropertyDeleterCallback deleter;
+  GenericNamedPropertyEnumeratorCallback enumerator;
+  Handle<Value> data;
+  PropertyHandlerFlags flags;
+};
+
+
+struct IndexedPropertyHandlerConfiguration {
+  IndexedPropertyHandlerConfiguration(
+      /** Note: getter is required **/
+      IndexedPropertyGetterCallback getter = 0,
+      IndexedPropertySetterCallback setter = 0,
+      IndexedPropertyQueryCallback query = 0,
+      IndexedPropertyDeleterCallback deleter = 0,
+      IndexedPropertyEnumeratorCallback enumerator = 0,
+      Handle<Value> data = Handle<Value>(),
+      PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
+      : getter(getter),
+        setter(setter),
+        query(query),
+        deleter(deleter),
+        enumerator(enumerator),
+        data(data),
+        flags(flags) {}
+
+  IndexedPropertyGetterCallback getter;
+  IndexedPropertySetterCallback setter;
+  IndexedPropertyQueryCallback query;
+  IndexedPropertyDeleterCallback deleter;
+  IndexedPropertyEnumeratorCallback enumerator;
+  Handle<Value> data;
+  PropertyHandlerFlags flags;
+};
+
+
 /**
  * An ObjectTemplate is used to create objects at runtime.
  *
@@ -3776,6 +4027,9 @@
    * from this object template, the provided callback is invoked instead of
    * accessing the property directly on the JavaScript object.
    *
+   * Note that new code should use the second version that can intercept
+   * symbol-named properties as well as string-named properties.
+   *
    * \param getter The callback to invoke when getting a property.
    * \param setter The callback to invoke when setting a property.
    * \param query The callback to invoke to check if a property is present,
@@ -3786,6 +4040,7 @@
    * \param data A piece of data that will be passed to the callbacks
    *   whenever they are invoked.
    */
+  // TODO(dcarney): deprecate
   void SetNamedPropertyHandler(
       NamedPropertyGetterCallback getter,
       NamedPropertySetterCallback setter = 0,
@@ -3793,6 +4048,7 @@
       NamedPropertyDeleterCallback deleter = 0,
       NamedPropertyEnumeratorCallback enumerator = 0,
       Handle<Value> data = Handle<Value>());
+  void SetHandler(const NamedPropertyHandlerConfiguration& configuration);
 
   /**
    * Sets an indexed property handler on the object template.
@@ -3810,14 +4066,18 @@
    * \param data A piece of data that will be passed to the callbacks
    *   whenever they are invoked.
    */
+  void SetHandler(const IndexedPropertyHandlerConfiguration& configuration);
+  // TODO(dcarney): deprecate
   void SetIndexedPropertyHandler(
       IndexedPropertyGetterCallback getter,
       IndexedPropertySetterCallback setter = 0,
       IndexedPropertyQueryCallback query = 0,
       IndexedPropertyDeleterCallback deleter = 0,
       IndexedPropertyEnumeratorCallback enumerator = 0,
-      Handle<Value> data = Handle<Value>());
-
+      Handle<Value> data = Handle<Value>()) {
+    SetHandler(IndexedPropertyHandlerConfiguration(getter, setter, query,
+                                                   deleter, enumerator, data));
+  }
   /**
    * Sets the callback to be used when calling instances created from
    * this template as a function.  If no callback is set, instances
@@ -4122,6 +4382,19 @@
   static Local<Value> SyntaxError(Handle<String> message);
   static Local<Value> TypeError(Handle<String> message);
   static Local<Value> Error(Handle<String> message);
+
+  /**
+   * Creates an error message for the given exception.
+   * Will try to reconstruct the original stack trace from the exception value,
+   * or capture the current stack trace if not available.
+   */
+  static Local<Message> CreateMessage(Handle<Value> exception);
+
+  /**
+   * Returns the original stack trace that was captured at the creation time
+   * of a given exception, or an empty handle if not available.
+   */
+  static Local<StackTrace> GetStackTrace(Handle<Value> exception);
 };
 
 
@@ -4137,18 +4410,19 @@
 typedef void (*AddHistogramSampleCallback)(void* histogram, int sample);
 
 // --- Memory Allocation Callback ---
-  enum ObjectSpace {
-    kObjectSpaceNewSpace = 1 << 0,
-    kObjectSpaceOldPointerSpace = 1 << 1,
-    kObjectSpaceOldDataSpace = 1 << 2,
-    kObjectSpaceCodeSpace = 1 << 3,
-    kObjectSpaceMapSpace = 1 << 4,
-    kObjectSpaceLoSpace = 1 << 5,
-
-    kObjectSpaceAll = kObjectSpaceNewSpace | kObjectSpaceOldPointerSpace |
-      kObjectSpaceOldDataSpace | kObjectSpaceCodeSpace | kObjectSpaceMapSpace |
-      kObjectSpaceLoSpace
-  };
+enum ObjectSpace {
+  kObjectSpaceNewSpace = 1 << 0,
+  kObjectSpaceOldPointerSpace = 1 << 1,
+  kObjectSpaceOldDataSpace = 1 << 2,
+  kObjectSpaceCodeSpace = 1 << 3,
+  kObjectSpaceMapSpace = 1 << 4,
+  kObjectSpaceCellSpace = 1 << 5,
+  kObjectSpacePropertyCellSpace = 1 << 6,
+  kObjectSpaceLoSpace = 1 << 7,
+  kObjectSpaceAll = kObjectSpaceNewSpace | kObjectSpaceOldPointerSpace |
+                    kObjectSpaceOldDataSpace | kObjectSpaceCodeSpace |
+                    kObjectSpaceMapSpace | kObjectSpaceLoSpace
+};
 
   enum AllocationAction {
     kAllocationActionAllocate = 1 << 0,
@@ -4163,6 +4437,37 @@
 // --- Leave Script Callback ---
 typedef void (*CallCompletedCallback)();
 
+// --- Promise Reject Callback ---
+enum PromiseRejectEvent {
+  kPromiseRejectWithNoHandler = 0,
+  kPromiseHandlerAddedAfterReject = 1
+};
+
+class PromiseRejectMessage {
+ public:
+  PromiseRejectMessage(Handle<Promise> promise, PromiseRejectEvent event,
+                       Handle<Value> value, Handle<StackTrace> stack_trace)
+      : promise_(promise),
+        event_(event),
+        value_(value),
+        stack_trace_(stack_trace) {}
+
+  V8_INLINE Handle<Promise> GetPromise() const { return promise_; }
+  V8_INLINE PromiseRejectEvent GetEvent() const { return event_; }
+  V8_INLINE Handle<Value> GetValue() const { return value_; }
+
+  // DEPRECATED. Use v8::Exception::CreateMessage(GetValue())->GetStackTrace()
+  V8_INLINE Handle<StackTrace> GetStackTrace() const { return stack_trace_; }
+
+ private:
+  Handle<Promise> promise_;
+  PromiseRejectEvent event_;
+  Handle<Value> value_;
+  Handle<StackTrace> stack_trace_;
+};
+
+typedef void (*PromiseRejectCallback)(PromiseRejectMessage message);
+
 // --- Microtask Callback ---
 typedef void (*MicrotaskCallback)(void* data);
 
@@ -4334,6 +4639,27 @@
 
 
 /**
+ * Interface for iterating through all external resources in the heap.
+ */
+class V8_EXPORT ExternalResourceVisitor {  // NOLINT
+ public:
+  virtual ~ExternalResourceVisitor() {}
+  virtual void VisitExternalString(Handle<String> string) {}
+};
+
+
+/**
+ * Interface for iterating through all the persistent handles in the heap.
+ */
+class V8_EXPORT PersistentHandleVisitor {  // NOLINT
+ public:
+  virtual ~PersistentHandleVisitor() {}
+  virtual void VisitPersistentHandle(Persistent<Value>* value,
+                                     uint16_t class_id) {}
+};
+
+
+/**
  * Isolate represents an isolated instance of the V8 engine.  V8 isolates have
  * completely separate states.  Objects from one isolate must not be used in
  * other isolates.  The embedder can create multiple isolates and use them in
@@ -4473,6 +4799,7 @@
    */
   enum UseCounterFeature {
     kUseAsm = 0,
+    kBreakIterator = 1,
     kUseCounterFeatureCount  // This enum value must be last.
   };
 
@@ -4494,6 +4821,8 @@
   /**
    * Returns the entered isolate for the current thread or NULL in
    * case there is no current isolate.
+   *
+   * This method must not be invoked before V8::Initialize() was invoked.
    */
   static Isolate* GetCurrent();
 
@@ -4548,6 +4877,21 @@
   void GetHeapStatistics(HeapStatistics* heap_statistics);
 
   /**
+   * Get a call stack sample from the isolate.
+   * \param state Execution state.
+   * \param frames Caller allocated buffer to store stack frames.
+   * \param frames_limit Maximum number of frames to capture. The buffer must
+   *                     be large enough to hold the number of frames.
+   * \param sample_info The sample info is filled up by the function
+   *                    provides number of actual captured stack frames and
+   *                    the current VM state.
+   * \note GetStackSample should only be called when the JS thread is paused or
+   *       interrupted. Otherwise the behavior is undefined.
+   */
+  void GetStackSample(const RegisterState& state, void** frames,
+                      size_t frames_limit, SampleInfo* sample_info);
+
+  /**
    * Adjusts the amount of registered external memory. Used to give V8 an
    * indication of the amount of externally allocated memory that is kept alive
    * by JavaScript objects. V8 uses this to decide when to perform global
@@ -4676,12 +5020,47 @@
    */
   void RemoveGCEpilogueCallback(GCEpilogueCallback callback);
 
+
+  /**
+   * Forcefully terminate the current thread of JavaScript execution
+   * in the given isolate.
+   *
+   * This method can be used by any thread even if that thread has not
+   * acquired the V8 lock with a Locker object.
+   */
+  void TerminateExecution();
+
+  /**
+   * Is V8 terminating JavaScript execution.
+   *
+   * Returns true if JavaScript execution is currently terminating
+   * because of a call to TerminateExecution.  In that case there are
+   * still JavaScript frames on the stack and the termination
+   * exception is still active.
+   */
+  bool IsExecutionTerminating();
+
+  /**
+   * Resume execution capability in the given isolate, whose execution
+   * was previously forcefully terminated using TerminateExecution().
+   *
+   * When execution is forcefully terminated using TerminateExecution(),
+   * the isolate can not resume execution until all JavaScript frames
+   * have propagated the uncatchable exception which is generated.  This
+   * method allows the program embedding the engine to handle the
+   * termination event and resume execution capability, even if
+   * JavaScript frames remain on the stack.
+   *
+   * This method can be used by any thread even if that thread has not
+   * acquired the V8 lock with a Locker object.
+   */
+  void CancelTerminateExecution();
+
   /**
    * Request V8 to interrupt long running JavaScript code and invoke
    * the given |callback| passing the given |data| to it. After |callback|
    * returns control will be returned to the JavaScript code.
-   * At any given moment V8 can remember only a single callback for the very
-   * last interrupt request.
+   * There may be a number of interrupt requests in flight.
    * Can be called from another thread without acquiring a |Locker|.
    * Registered |callback| must not reenter interrupted Isolate.
    */
@@ -4691,7 +5070,8 @@
    * Clear interrupt request created by |RequestInterrupt|.
    * Can be called from another thread without acquiring a |Locker|.
    */
-  void ClearInterrupt();
+  V8_DEPRECATED("There's no way to clear interrupts in flight.",
+                void ClearInterrupt());
 
   /**
    * Request garbage collection in this Isolate. It is only valid to call this
@@ -4723,6 +5103,13 @@
    */
   void RemoveCallCompletedCallback(CallCompletedCallback callback);
 
+
+  /**
+   * Set callback to notify about promise reject with no handler, or
+   * revocation of such a previous notification once the handler is added.
+   */
+  void SetPromiseRejectCallback(PromiseRejectCallback callback);
+
   /**
    * Experimental: Runs the Microtask Work Queue until empty
    * Any exceptions thrown by microtask callbacks are swallowed.
@@ -4773,17 +5160,23 @@
 
   /**
    * Optional notification that the embedder is idle.
-   * V8 uses the notification to reduce memory footprint.
+   * V8 uses the notification to perform garbage collection.
    * This call can be used repeatedly if the embedder remains idle.
    * Returns true if the embedder should stop calling IdleNotification
    * until real work has been done.  This indicates that V8 has done
    * as much cleanup as it will be able to do.
    *
-   * The idle_time_in_ms argument specifies the time V8 has to do reduce
-   * the memory footprint. There is no guarantee that the actual work will be
+   * The idle_time_in_ms argument specifies the time V8 has to perform
+   * garbage collection. There is no guarantee that the actual work will be
    * done within the time limit.
+   * The deadline_in_seconds argument specifies the deadline V8 has to finish
+   * garbage collection work. deadline_in_seconds is compared with
+   * MonotonicallyIncreasingTime() and should be based on the same timebase as
+   * that function. There is no guarantee that the actual work will be done
+   * within the time limit.
    */
   bool IdleNotification(int idle_time_in_ms);
+  bool IdleNotificationDeadline(double deadline_in_seconds);
 
   /**
    * Optional notification that the system is running low on memory.
@@ -4796,8 +5189,11 @@
    * these notifications to guide the GC heuristic. Returns the number
    * of context disposals - including this one - since the last time
    * V8 had a chance to clean up.
+   *
+   * The optional parameter |dependant_context| specifies whether the disposed
+   * context was depending on state from other contexts or not.
    */
-  int ContextDisposedNotification();
+  int ContextDisposedNotification(bool dependant_context = true);
 
   /**
    * Allows the host application to provide the address of a function that is
@@ -4835,6 +5231,99 @@
    */
   void SetStackLimit(uintptr_t stack_limit);
 
+  /**
+   * Returns a memory range that can potentially contain jitted code.
+   *
+   * On Win64, embedders are advised to install function table callbacks for
+   * these ranges, as default SEH won't be able to unwind through jitted code.
+   *
+   * The first page of the code range is reserved for the embedder and is
+   * committed, writable, and executable.
+   *
+   * Might be empty on other platforms.
+   *
+   * https://code.google.com/p/v8/issues/detail?id=3598
+   */
+  void GetCodeRange(void** start, size_t* length_in_bytes);
+
+  /** Set the callback to invoke in case of fatal errors. */
+  void SetFatalErrorHandler(FatalErrorCallback that);
+
+  /**
+   * Set the callback to invoke to check if code generation from
+   * strings should be allowed.
+   */
+  void SetAllowCodeGenerationFromStringsCallback(
+      AllowCodeGenerationFromStringsCallback callback);
+
+  /**
+  * Check if V8 is dead and therefore unusable.  This is the case after
+  * fatal errors such as out-of-memory situations.
+  */
+  bool IsDead();
+
+  /**
+   * Adds a message listener.
+   *
+   * The same message listener can be added more than once and in that
+   * case it will be called more than once for each message.
+   *
+   * If data is specified, it will be passed to the callback when it is called.
+   * Otherwise, the exception object will be passed to the callback instead.
+   */
+  bool AddMessageListener(MessageCallback that,
+                          Handle<Value> data = Handle<Value>());
+
+  /**
+   * Remove all message listeners from the specified callback function.
+   */
+  void RemoveMessageListeners(MessageCallback that);
+
+  /** Callback function for reporting failed access checks.*/
+  void SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback);
+
+  /**
+   * Tells V8 to capture current stack trace when uncaught exception occurs
+   * and report it to the message listeners. The option is off by default.
+   */
+  void SetCaptureStackTraceForUncaughtExceptions(
+      bool capture, int frame_limit = 10,
+      StackTrace::StackTraceOptions options = StackTrace::kOverview);
+
+  /**
+   * Enables the host application to provide a mechanism to be notified
+   * and perform custom logging when V8 Allocates Executable Memory.
+   */
+  void AddMemoryAllocationCallback(MemoryAllocationCallback callback,
+                                   ObjectSpace space, AllocationAction action);
+
+  /**
+   * Removes callback that was installed by AddMemoryAllocationCallback.
+   */
+  void RemoveMemoryAllocationCallback(MemoryAllocationCallback callback);
+
+  /**
+   * Iterates through all external resources referenced from current isolate
+   * heap.  GC is not invoked prior to iterating, therefore there is no
+   * guarantee that visited objects are still alive.
+   */
+  void VisitExternalResources(ExternalResourceVisitor* visitor);
+
+  /**
+   * Iterates through all the persistent handles in the current isolate's heap
+   * that have class_ids.
+   */
+  void VisitHandlesWithClassIds(PersistentHandleVisitor* visitor);
+
+  /**
+   * Iterates through all the persistent handles in the current isolate's heap
+   * that have class_ids and are candidates to be marked as partially dependent
+   * handles. This will visit handles to young objects created since the last
+   * garbage collection but is free to visit an arbitrary superset of these
+   * objects.
+   */
+  void VisitHandlesForPartialDependence(PersistentHandleVisitor* visitor);
+
  private:
   template<class K, class V, class Traits> friend class PersistentValueMap;
 
@@ -4853,43 +5342,12 @@
 
 class V8_EXPORT StartupData {
  public:
-  enum CompressionAlgorithm {
-    kUncompressed,
-    kBZip2
-  };
-
   const char* data;
-  int compressed_size;
   int raw_size;
 };
 
 
 /**
- * A helper class for driving V8 startup data decompression.  It is based on
- * "CompressedStartupData" API functions from the V8 class.  It isn't mandatory
- * for an embedder to use this class, instead, API functions can be used
- * directly.
- *
- * For an example of the class usage, see the "shell.cc" sample application.
- */
-class V8_EXPORT StartupDataDecompressor {  // NOLINT
- public:
-  StartupDataDecompressor();
-  virtual ~StartupDataDecompressor();
-  int Decompress();
-
- protected:
-  virtual int DecompressData(char* raw_data,
-                             int* raw_data_size,
-                             const char* compressed_data,
-                             int compressed_data_size) = 0;
-
- private:
-  char** raw_data;
-};
-
-
-/**
  * EntropySource is used as a callback function when v8 needs a source
  * of entropy.
  */
@@ -4914,39 +5372,20 @@
 
 
 /**
- * Interface for iterating through all external resources in the heap.
- */
-class V8_EXPORT ExternalResourceVisitor {  // NOLINT
- public:
-  virtual ~ExternalResourceVisitor() {}
-  virtual void VisitExternalString(Handle<String> string) {}
-};
-
-
-/**
- * Interface for iterating through all the persistent handles in the heap.
- */
-class V8_EXPORT PersistentHandleVisitor {  // NOLINT
- public:
-  virtual ~PersistentHandleVisitor() {}
-  virtual void VisitPersistentHandle(Persistent<Value>* value,
-                                     uint16_t class_id) {}
-};
-
-
-/**
  * Container class for static utility functions.
  */
 class V8_EXPORT V8 {
  public:
   /** Set the callback to invoke in case of fatal errors. */
-  static void SetFatalErrorHandler(FatalErrorCallback that);
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void SetFatalErrorHandler(FatalErrorCallback that);
 
   /**
    * Set the callback to invoke to check if code generation from
    * strings should be allowed.
    */
-  static void SetAllowCodeGenerationFromStringsCallback(
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void SetAllowCodeGenerationFromStringsCallback(
       AllowCodeGenerationFromStringsCallback that);
 
   /**
@@ -4958,34 +5397,11 @@
   static void SetArrayBufferAllocator(ArrayBuffer::Allocator* allocator);
 
   /**
-   * Check if V8 is dead and therefore unusable.  This is the case after
-   * fatal errors such as out-of-memory situations.
-   */
-  static bool IsDead();
-
-  /**
-   * The following 4 functions are to be used when V8 is built with
-   * the 'compress_startup_data' flag enabled. In this case, the
-   * embedder must decompress startup data prior to initializing V8.
-   *
-   * This is how interaction with V8 should look like:
-   *   int compressed_data_count = v8::V8::GetCompressedStartupDataCount();
-   *   v8::StartupData* compressed_data =
-   *     new v8::StartupData[compressed_data_count];
-   *   v8::V8::GetCompressedStartupData(compressed_data);
-   *   ... decompress data (compressed_data can be updated in-place) ...
-   *   v8::V8::SetDecompressedStartupData(compressed_data);
-   *   ... now V8 can be initialized
-   *   ... make sure the decompressed data stays valid until V8 shutdown
-   *
-   * A helper class StartupDataDecompressor is provided. It implements
-   * the protocol of the interaction described above, and can be used in
-   * most cases instead of calling these API functions directly.
-   */
-  static StartupData::CompressionAlgorithm GetCompressedStartupDataAlgorithm();
-  static int GetCompressedStartupDataCount();
-  static void GetCompressedStartupData(StartupData* compressed_data);
-  static void SetDecompressedStartupData(StartupData* decompressed_data);
+  * Check if V8 is dead and therefore unusable.  This is the case after
+  * fatal errors such as out-of-memory situations.
+  */
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static bool IsDead();
 
   /**
    * Hand startup data to V8, in case the embedder has chosen to build
@@ -5006,6 +5422,13 @@
   static void SetSnapshotDataBlob(StartupData* startup_blob);
 
   /**
+   * Create a new isolate and context for the purpose of capturing a snapshot
+   * Returns { NULL, 0 } on failure.
+   * The caller owns the data array in the return value.
+   */
+  static StartupData CreateSnapshotDataBlob();
+
+  /**
    * Adds a message listener.
    *
    * The same message listener can be added more than once and in that
@@ -5014,21 +5437,23 @@
    * If data is specified, it will be passed to the callback when it is called.
    * Otherwise, the exception object will be passed to the callback instead.
    */
-  static bool AddMessageListener(MessageCallback that,
-                                 Handle<Value> data = Handle<Value>());
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static bool AddMessageListener(
+      MessageCallback that, Handle<Value> data = Handle<Value>());
 
   /**
    * Remove all message listeners from the specified callback function.
    */
-  static void RemoveMessageListeners(MessageCallback that);
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void RemoveMessageListeners(MessageCallback that);
 
   /**
    * Tells V8 to capture current stack trace when uncaught exception occurs
    * and report it to the message listeners. The option is off by default.
    */
-  static void SetCaptureStackTraceForUncaughtExceptions(
-      bool capture,
-      int frame_limit = 10,
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void SetCaptureStackTraceForUncaughtExceptions(
+      bool capture, int frame_limit = 10,
       StackTrace::StackTraceOptions options = StackTrace::kOverview);
 
   /**
@@ -5047,7 +5472,9 @@
   static const char* GetVersion();
 
   /** Callback function for reporting failed access checks.*/
-  static void SetFailedAccessCheckCallbackFunction(FailedAccessCheckCallback);
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void SetFailedAccessCheckCallbackFunction(
+      FailedAccessCheckCallback);
 
   /**
    * Enables the host application to receive a notification before a
@@ -5059,6 +5486,7 @@
    * register the same callback function two times with different
    * GCType filters.
    */
+  // TODO(dcarney): deprecate this.
   static void AddGCPrologueCallback(
       GCPrologueCallback callback, GCType gc_type_filter = kGCTypeAll);
 
@@ -5066,7 +5494,8 @@
    * This function removes callback which was installed by
    * AddGCPrologueCallback function.
    */
-  static void RemoveGCPrologueCallback(GCPrologueCallback callback);
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void RemoveGCPrologueCallback(GCPrologueCallback callback);
 
   /**
    * Enables the host application to receive a notification after a
@@ -5078,6 +5507,7 @@
    * register the same callback function two times with different
    * GCType filters.
    */
+  // TODO(dcarney): deprecate this.
   static void AddGCEpilogueCallback(
       GCEpilogueCallback callback, GCType gc_type_filter = kGCTypeAll);
 
@@ -5085,20 +5515,24 @@
    * This function removes callback which was installed by
    * AddGCEpilogueCallback function.
    */
-  static void RemoveGCEpilogueCallback(GCEpilogueCallback callback);
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void RemoveGCEpilogueCallback(GCEpilogueCallback callback);
 
   /**
    * Enables the host application to provide a mechanism to be notified
    * and perform custom logging when V8 Allocates Executable Memory.
    */
-  static void AddMemoryAllocationCallback(MemoryAllocationCallback callback,
-                                          ObjectSpace space,
-                                          AllocationAction action);
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void AddMemoryAllocationCallback(
+      MemoryAllocationCallback callback, ObjectSpace space,
+      AllocationAction action);
 
   /**
    * Removes callback that was installed by AddMemoryAllocationCallback.
    */
-  static void RemoveMemoryAllocationCallback(MemoryAllocationCallback callback);
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void RemoveMemoryAllocationCallback(
+      MemoryAllocationCallback callback);
 
   /**
    * Initializes V8. This function needs to be called before the first Isolate
@@ -5128,7 +5562,8 @@
    *
    * \param isolate The isolate in which to terminate the current JS execution.
    */
-  static void TerminateExecution(Isolate* isolate);
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void TerminateExecution(Isolate* isolate);
 
   /**
    * Is V8 terminating JavaScript execution.
@@ -5140,7 +5575,8 @@
    *
    * \param isolate The isolate in which to check.
    */
-  static bool IsExecutionTerminating(Isolate* isolate = NULL);
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static bool IsExecutionTerminating(Isolate* isolate = NULL);
 
   /**
    * Resume execution capability in the given isolate, whose execution
@@ -5158,7 +5594,8 @@
    *
    * \param isolate The isolate in which to resume execution capability.
    */
-  static void CancelTerminateExecution(Isolate* isolate);
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void CancelTerminateExecution(Isolate* isolate);
 
   /**
    * Releases any resources used by v8 and stops any utility threads
@@ -5176,13 +5613,25 @@
    * heap.  GC is not invoked prior to iterating, therefore there is no
    * guarantee that visited objects are still alive.
    */
-  static void VisitExternalResources(ExternalResourceVisitor* visitor);
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void VisitExternalResources(
+      ExternalResourceVisitor* visitor);
 
   /**
    * Iterates through all the persistent handles in the current isolate's heap
    * that have class_ids.
    */
-  static void VisitHandlesWithClassIds(PersistentHandleVisitor* visitor);
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void VisitHandlesWithClassIds(
+      PersistentHandleVisitor* visitor);
+
+  /**
+   * Iterates through all the persistent handles in isolate's heap that have
+   * class_ids.
+   */
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void VisitHandlesWithClassIds(
+      Isolate* isolate, PersistentHandleVisitor* visitor);
 
   /**
    * Iterates through all the persistent handles in the current isolate's heap
@@ -5191,7 +5640,8 @@
    * garbage collection but is free to visit an arbitrary superset of these
    * objects.
    */
-  static void VisitHandlesForPartialDependence(
+  // TODO(dcarney): deprecate this.
+  V8_INLINE static void VisitHandlesForPartialDependence(
       Isolate* isolate, PersistentHandleVisitor* visitor);
 
   /**
@@ -5215,17 +5665,30 @@
    */
   static void ShutdownPlatform();
 
+  /**
+   * Returns the current v8::Platform in use.
+   */
+  static v8::Platform* GetCurrentPlatform();
+
  private:
   V8();
 
+  enum WeakHandleType { PhantomHandle, NonphantomHandle };
+
   static internal::Object** GlobalizeReference(internal::Isolate* isolate,
                                                internal::Object** handle);
   static internal::Object** CopyPersistent(internal::Object** handle);
   static void DisposeGlobal(internal::Object** global_handle);
   typedef WeakCallbackData<Value, void>::Callback WeakCallback;
-  static void MakeWeak(internal::Object** global_handle,
-                       void* data,
+  static void MakeWeak(internal::Object** global_handle, void* data,
                        WeakCallback weak_callback);
+  static void MakePhantom(internal::Object** global_handle, void* data,
+                          PhantomCallbackData<void>::Callback weak_callback);
+  static void MakePhantom(
+      internal::Object** global_handle,
+      InternalFieldsCallbackData<void, void>::Callback weak_callback,
+      int internal_field_index1,
+      int internal_field_index2 = Object::kNoInternalFieldIndex);
   static void* ClearWeak(internal::Object** global_handle);
   static void Eternalize(Isolate* isolate,
                          Value* handle,
@@ -5251,9 +5714,17 @@
    * all TryCatch blocks should be stack allocated because the memory
    * location itself is compared against JavaScript try/catch blocks.
    */
+  // TODO(dcarney): deprecate.
   TryCatch();
 
   /**
+   * Creates a new try/catch block and registers it with v8.  Note that
+   * all TryCatch blocks should be stack allocated because the memory
+   * location itself is compared against JavaScript try/catch blocks.
+   */
+  TryCatch(Isolate* isolate);
+
+  /**
    * Unregisters and deletes this try/catch block.
    */
   ~TryCatch();
@@ -5692,8 +6163,6 @@
   bool top_level_;
   internal::Isolate* isolate_;
 
-  static bool active_;
-
   // Disallow copying and assigning.
   Locker(const Locker&);
   void operator=(const Locker&);
@@ -5802,7 +6271,7 @@
   static const int kJSObjectHeaderSize = 3 * kApiPointerSize;
   static const int kFixedArrayHeaderSize = 2 * kApiPointerSize;
   static const int kContextHeaderSize = 2 * kApiPointerSize;
-  static const int kContextEmbedderDataIndex = 95;
+  static const int kContextEmbedderDataIndex = 76;
   static const int kFullStringRepresentationMask = 0x07;
   static const int kStringEncodingMask = 0x4;
   static const int kExternalTwoByteRepresentationTag = 0x02;
@@ -5820,7 +6289,7 @@
   static const int kNullValueRootIndex = 7;
   static const int kTrueValueRootIndex = 8;
   static const int kFalseValueRootIndex = 9;
-  static const int kEmptyStringRootIndex = 164;
+  static const int kEmptyStringRootIndex = 154;
 
   // The external allocation limit should be below 256 MB on all architectures
   // to avoid that resource-constrained embedders run low on memory.
@@ -5828,14 +6297,14 @@
 
   static const int kNodeClassIdOffset = 1 * kApiPointerSize;
   static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
-  static const int kNodeStateMask = 0xf;
+  static const int kNodeStateMask = 0x7;
   static const int kNodeStateIsWeakValue = 2;
   static const int kNodeStateIsPendingValue = 3;
   static const int kNodeStateIsNearDeathValue = 4;
-  static const int kNodeIsIndependentShift = 4;
-  static const int kNodeIsPartiallyDependentShift = 5;
+  static const int kNodeIsIndependentShift = 3;
+  static const int kNodeIsPartiallyDependentShift = 4;
 
-  static const int kJSObjectType = 0xbc;
+  static const int kJSObjectType = 0xbd;
   static const int kFirstNonstringType = 0x80;
   static const int kOddballType = 0x83;
   static const int kForeignType = 0x88;
@@ -6090,8 +6559,7 @@
     typename WeakCallbackData<S, P>::Callback callback) {
   TYPE_CHECK(S, T);
   typedef typename WeakCallbackData<Value, void>::Callback Callback;
-  V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_),
-               parameter,
+  V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_), parameter,
                reinterpret_cast<Callback>(callback));
 }
 
@@ -6106,7 +6574,29 @@
 
 
 template <class T>
-template<typename P>
+template <typename P>
+void PersistentBase<T>::SetPhantom(
+    P* parameter, typename PhantomCallbackData<P>::Callback callback) {
+  typedef typename PhantomCallbackData<void>::Callback Callback;
+  V8::MakePhantom(reinterpret_cast<internal::Object**>(this->val_), parameter,
+                  reinterpret_cast<Callback>(callback));
+}
+
+
+template <class T>
+template <typename U, typename V>
+void PersistentBase<T>::SetPhantom(
+    void (*callback)(const InternalFieldsCallbackData<U, V>&),
+    int internal_field_index1, int internal_field_index2) {
+  typedef typename InternalFieldsCallbackData<void, void>::Callback Callback;
+  V8::MakePhantom(reinterpret_cast<internal::Object**>(this->val_),
+                  reinterpret_cast<Callback>(callback), internal_field_index1,
+                  internal_field_index2);
+}
+
+
+template <class T>
+template <typename P>
 P* PersistentBase<T>::ClearWeak() {
   return reinterpret_cast<P*>(
     V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_)));
@@ -6133,15 +6623,6 @@
 }
 
 
-template <class T, class M>
-T* Persistent<T, M>::ClearAndLeak() {
-  T* old;
-  old = this->val_;
-  this->val_ = NULL;
-  return old;
-}
-
-
 template <class T>
 void PersistentBase<T>::SetWrapperClassId(uint16_t class_id) {
   typedef internal::Internals I;
@@ -6547,6 +7028,44 @@
 }
 
 
+Local<Boolean> Value::ToBoolean() const {
+  return ToBoolean(Isolate::GetCurrent());
+}
+
+
+Local<Number> Value::ToNumber() const {
+  return ToNumber(Isolate::GetCurrent());
+}
+
+
+Local<String> Value::ToString() const {
+  return ToString(Isolate::GetCurrent());
+}
+
+
+Local<String> Value::ToDetailString() const {
+  return ToDetailString(Isolate::GetCurrent());
+}
+
+
+Local<Object> Value::ToObject() const {
+  return ToObject(Isolate::GetCurrent());
+}
+
+
+Local<Integer> Value::ToInteger() const {
+  return ToInteger(Isolate::GetCurrent());
+}
+
+
+Local<Uint32> Value::ToUint32() const {
+  return ToUint32(Isolate::GetCurrent());
+}
+
+
+Local<Int32> Value::ToInt32() const { return ToInt32(Isolate::GetCurrent()); }
+
+
 Name* Name::Cast(v8::Value* value) {
 #ifdef V8_ENABLE_CHECKS
   CheckCast(value);
@@ -6937,6 +7456,119 @@
 }
 
 
+void V8::SetAllowCodeGenerationFromStringsCallback(
+    AllowCodeGenerationFromStringsCallback callback) {
+  Isolate* isolate = Isolate::GetCurrent();
+  isolate->SetAllowCodeGenerationFromStringsCallback(callback);
+}
+
+
+bool V8::IsDead() {
+  Isolate* isolate = Isolate::GetCurrent();
+  return isolate->IsDead();
+}
+
+
+bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
+  Isolate* isolate = Isolate::GetCurrent();
+  return isolate->AddMessageListener(that, data);
+}
+
+
+void V8::RemoveMessageListeners(MessageCallback that) {
+  Isolate* isolate = Isolate::GetCurrent();
+  isolate->RemoveMessageListeners(that);
+}
+
+
+void V8::SetFailedAccessCheckCallbackFunction(
+    FailedAccessCheckCallback callback) {
+  Isolate* isolate = Isolate::GetCurrent();
+  isolate->SetFailedAccessCheckCallbackFunction(callback);
+}
+
+
+void V8::SetCaptureStackTraceForUncaughtExceptions(
+    bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
+  Isolate* isolate = Isolate::GetCurrent();
+  isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
+                                                     options);
+}
+
+
+void V8::SetFatalErrorHandler(FatalErrorCallback callback) {
+  Isolate* isolate = Isolate::GetCurrent();
+  isolate->SetFatalErrorHandler(callback);
+}
+
+
+void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
+  Isolate* isolate = Isolate::GetCurrent();
+  isolate->RemoveGCPrologueCallback(
+      reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback));
+}
+
+
+void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
+  Isolate* isolate = Isolate::GetCurrent();
+  isolate->RemoveGCEpilogueCallback(
+      reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback));
+}
+
+
+void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
+                                     ObjectSpace space,
+                                     AllocationAction action) {
+  Isolate* isolate = Isolate::GetCurrent();
+  isolate->AddMemoryAllocationCallback(callback, space, action);
+}
+
+
+void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
+  Isolate* isolate = Isolate::GetCurrent();
+  isolate->RemoveMemoryAllocationCallback(callback);
+}
+
+
+void V8::TerminateExecution(Isolate* isolate) { isolate->TerminateExecution(); }
+
+
+bool V8::IsExecutionTerminating(Isolate* isolate) {
+  if (isolate == NULL) {
+    isolate = Isolate::GetCurrent();
+  }
+  return isolate->IsExecutionTerminating();
+}
+
+
+void V8::CancelTerminateExecution(Isolate* isolate) {
+  isolate->CancelTerminateExecution();
+}
+
+
+void V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
+  Isolate* isolate = Isolate::GetCurrent();
+  isolate->VisitExternalResources(visitor);
+}
+
+
+void V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
+  Isolate* isolate = Isolate::GetCurrent();
+  isolate->VisitHandlesWithClassIds(visitor);
+}
+
+
+void V8::VisitHandlesWithClassIds(Isolate* isolate,
+                                  PersistentHandleVisitor* visitor) {
+  isolate->VisitHandlesWithClassIds(visitor);
+}
+
+
+void V8::VisitHandlesForPartialDependence(Isolate* isolate,
+                                          PersistentHandleVisitor* visitor) {
+  isolate->VisitHandlesForPartialDependence(visitor);
+}
+
 /**
  * \example shell.cc
  * A simple shell that takes a list of expressions on the
diff --git a/include/v8config.h b/include/v8config.h
index 87de994..d1ca22c 100644
--- a/include/v8config.h
+++ b/include/v8config.h
@@ -120,7 +120,6 @@
 //  V8_LIBC_BIONIC  - Bionic libc
 //  V8_LIBC_BSD     - BSD libc derivate
 //  V8_LIBC_GLIBC   - GNU C library
-//  V8_LIBC_UCLIBC  - uClibc
 //
 // Note that testing for libc must be done using #if not #ifdef. For example,
 // to test for the GNU C library, use:
@@ -133,8 +132,6 @@
 #elif defined(__BIONIC__)
 # define V8_LIBC_BIONIC 1
 # define V8_LIBC_BSD 1
-#elif defined(__UCLIBC__)
-# define V8_LIBC_UCLIBC 1
 #elif defined(__GLIBC__) || defined(__GNU_LIBRARY__)
 # define V8_LIBC_GLIBC 1
 #else
@@ -145,13 +142,12 @@
 // -----------------------------------------------------------------------------
 // Compiler detection
 //
-//  V8_CC_CLANG   - Clang
-//  V8_CC_GNU     - GNU C++
+//  V8_CC_GNU     - GCC, or clang in gcc mode
 //  V8_CC_INTEL   - Intel C++
 //  V8_CC_MINGW   - Minimalist GNU for Windows
 //  V8_CC_MINGW32 - Minimalist GNU for Windows (mingw32)
 //  V8_CC_MINGW64 - Minimalist GNU for Windows (mingw-w64)
-//  V8_CC_MSVC    - Microsoft Visual C/C++
+//  V8_CC_MSVC    - Microsoft Visual C/C++, or clang in cl.exe mode
 //
 // C++11 feature detection
 //
@@ -178,6 +174,7 @@
 //  V8_HAS_BUILTIN_CLZ                  - __builtin_clz() supported
 //  V8_HAS_BUILTIN_CTZ                  - __builtin_ctz() supported
 //  V8_HAS_BUILTIN_EXPECT               - __builtin_expect() supported
+//  V8_HAS_BUILTIN_FRAME_ADDRESS        - __builtin_frame_address() supported
 //  V8_HAS_BUILTIN_POPCOUNT             - __builtin_popcount() supported
 //  V8_HAS_BUILTIN_SADD_OVERFLOW        - __builtin_sadd_overflow() supported
 //  V8_HAS_BUILTIN_SSUB_OVERFLOW        - __builtin_ssub_overflow() supported
@@ -186,7 +183,6 @@
 //  V8_HAS_DECLSPEC_NOINLINE            - __declspec(noinline) supported
 //  V8_HAS___FINAL                      - __final supported in non-C++11 mode
 //  V8_HAS___FORCEINLINE                - __forceinline supported
-//  V8_HAS_SEALED                       - MSVC style sealed marker supported
 //
 // Note that testing for compilers and/or features must be done using #if
 // not #ifdef. For example, to test for Intel C++ Compiler, use:
@@ -196,7 +192,11 @@
 
 #if defined(__clang__)
 
-# define V8_CC_CLANG 1
+#if defined(__GNUC__)  // Clang in gcc mode.
+# define V8_CC_GNU 1
+#elif defined(_MSC_VER)  // Clang in cl mode.
+# define V8_CC_MSVC 1
+#endif
 
 // Clang defines __alignof__ as alias for __alignof
 # define V8_HAS___ALIGNOF 1
@@ -214,6 +214,7 @@
 # define V8_HAS_BUILTIN_CLZ (__has_builtin(__builtin_clz))
 # define V8_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz))
 # define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect))
+# define V8_HAS_BUILTIN_FRAME_ADDRESS (__has_builtin(__builtin_frame_address))
 # define V8_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount))
 # define V8_HAS_BUILTIN_SADD_OVERFLOW (__has_builtin(__builtin_sadd_overflow))
 # define V8_HAS_BUILTIN_SSUB_OVERFLOW (__has_builtin(__builtin_ssub_overflow))
@@ -251,6 +252,7 @@
 # define V8_HAS_BUILTIN_CLZ (V8_GNUC_PREREQ(3, 4, 0))
 # define V8_HAS_BUILTIN_CTZ (V8_GNUC_PREREQ(3, 4, 0))
 # define V8_HAS_BUILTIN_EXPECT (V8_GNUC_PREREQ(2, 96, 0))
+# define V8_HAS_BUILTIN_FRAME_ADDRESS (V8_GNUC_PREREQ(2, 96, 0))
 # define V8_HAS_BUILTIN_POPCOUNT (V8_GNUC_PREREQ(3, 4, 0))
 
 // g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality
@@ -277,14 +279,11 @@
 
 # define V8_HAS___ALIGNOF 1
 
-// Override control was added with Visual Studio 2005, but
-// Visual Studio 2010 and earlier spell "final" as "sealed".
-# define V8_HAS_CXX11_FINAL (_MSC_VER >= 1700)
-# define V8_HAS_CXX11_OVERRIDE (_MSC_VER >= 1400)
-# define V8_HAS_SEALED (_MSC_VER >= 1400)
+# define V8_HAS_CXX11_FINAL 1
+# define V8_HAS_CXX11_OVERRIDE 1
 
 # define V8_HAS_DECLSPEC_ALIGN 1
-# define V8_HAS_DECLSPEC_DEPRECATED (_MSC_VER >= 1300)
+# define V8_HAS_DECLSPEC_DEPRECATED 1
 # define V8_HAS_DECLSPEC_NOINLINE 1
 
 # define V8_HAS___FORCEINLINE 1
diff --git a/include/v8stdint.h b/include/v8stdint.h
deleted file mode 100644
index 9a935dd..0000000
--- a/include/v8stdint.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Load definitions of standard types.
-
-#ifndef V8STDINT_H_
-#define V8STDINT_H_
-
-#include <stddef.h>
-#include <stdio.h>
-
-#include "v8config.h"
-
-#if V8_OS_WIN && !V8_CC_MINGW
-
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
-typedef short int16_t;  // NOLINT
-typedef unsigned short uint16_t;  // NOLINT
-typedef int int32_t;
-typedef unsigned int uint32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-// intptr_t and friends are defined in crtdefs.h through stdio.h.
-
-#else
-
-#include <stdint.h>  // NOLINT
-
-#endif
-
-#endif  // V8STDINT_H_
diff --git a/samples/process.cc b/samples/process.cc
index e5c9b7a..f447970 100644
--- a/samples/process.cc
+++ b/samples/process.cc
@@ -32,10 +32,6 @@
 #include <map>
 #include <string>
 
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-#error Using compressed startup data is not supported for this sample
-#endif
-
 using namespace std;
 using namespace v8;
 
@@ -116,10 +112,8 @@
                            const PropertyCallbackInfo<Value>& info);
 
   // Callbacks that access maps
-  static void MapGet(Local<String> name,
-                     const PropertyCallbackInfo<Value>& info);
-  static void MapSet(Local<String> name,
-                     Local<Value> value,
+  static void MapGet(Local<Name> name, const PropertyCallbackInfo<Value>& info);
+  static void MapSet(Local<Name> name, Local<Value> value,
                      const PropertyCallbackInfo<Value>& info);
 
   // Utility methods for wrapping C++ objects as JavaScript objects,
@@ -359,13 +353,15 @@
 }
 
 
-void JsHttpRequestProcessor::MapGet(Local<String> name,
+void JsHttpRequestProcessor::MapGet(Local<Name> name,
                                     const PropertyCallbackInfo<Value>& info) {
+  if (name->IsSymbol()) return;
+
   // Fetch the map wrapped by this object.
   map<string, string>* obj = UnwrapMap(info.Holder());
 
   // Convert the JavaScript string to a std::string.
-  string key = ObjectToString(name);
+  string key = ObjectToString(Local<String>::Cast(name));
 
   // Look up the value if it exists using the standard STL ideom.
   map<string, string>::iterator iter = obj->find(key);
@@ -381,14 +377,15 @@
 }
 
 
-void JsHttpRequestProcessor::MapSet(Local<String> name,
-                                    Local<Value> value_obj,
+void JsHttpRequestProcessor::MapSet(Local<Name> name, Local<Value> value_obj,
                                     const PropertyCallbackInfo<Value>& info) {
+  if (name->IsSymbol()) return;
+
   // Fetch the map wrapped by this object.
   map<string, string>* obj = UnwrapMap(info.Holder());
 
   // Convert the key and value to std::strings.
-  string key = ObjectToString(name);
+  string key = ObjectToString(Local<String>::Cast(name));
   string value = ObjectToString(value_obj);
 
   // Update the map.
@@ -405,7 +402,7 @@
 
   Local<ObjectTemplate> result = ObjectTemplate::New(isolate);
   result->SetInternalFieldCount(1);
-  result->SetNamedPropertyHandler(MapGet, MapSet);
+  result->SetHandler(NamedPropertyHandlerConfiguration(MapGet, MapSet));
 
   // Again, return the result through the current handle scope.
   return handle_scope.Escape(result);
diff --git a/samples/samples.gyp b/samples/samples.gyp
index 0c4c705..31e96f4 100644
--- a/samples/samples.gyp
+++ b/samples/samples.gyp
@@ -67,11 +67,5 @@
         'process.cc',
       ],
     },
-    {
-      'target_name': 'lineprocessor',
-      'sources': [
-        'lineprocessor.cc',
-      ],
-    }
   ],
 }
diff --git a/samples/shell.cc b/samples/shell.cc
index b66e8f7..1a08aff 100644
--- a/samples/shell.cc
+++ b/samples/shell.cc
@@ -35,10 +35,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-#error Using compressed startup data is not supported for this sample
-#endif
-
 /**
  * This sample program shows how to implement a simple javascript shell
  * based on V8.  This includes initializing V8 with command line options,
diff --git a/src/DEPS b/src/DEPS
index 260f5b2..4dbb3c7 100644
--- a/src/DEPS
+++ b/src/DEPS
@@ -3,8 +3,7 @@
   "-src/compiler",
   "+src/compiler/pipeline.h",
   "-src/libplatform",
-  "-include/libplatform",
-  "+testing",
+  "-include/libplatform"
 ]
 
 specific_include_rules = {
diff --git a/src/accessors.cc b/src/accessors.cc
index 011372c..662a9e1 100644
--- a/src/accessors.cc
+++ b/src/accessors.cc
@@ -56,17 +56,6 @@
 }
 
 
-template <class C>
-static C* FindInstanceOf(Isolate* isolate, Object* obj) {
-  for (PrototypeIterator iter(isolate, obj,
-                              PrototypeIterator::START_AT_RECEIVER);
-       !iter.IsAtEnd(); iter.Advance()) {
-    if (Is<C>(iter.GetCurrent())) return C::cast(iter.GetCurrent());
-  }
-  return NULL;
-}
-
-
 static V8_INLINE bool CheckForName(Handle<Name> name,
                                    Handle<String> property_name,
                                    int offset,
@@ -183,13 +172,16 @@
   LookupIterator it(object, Utils::OpenHandle(*name));
   CHECK_EQ(LookupIterator::ACCESSOR, it.state());
   DCHECK(it.HolderIsReceiverOrHiddenPrototype());
-  Object::SetDataProperty(&it, value);
+
+  if (Object::SetDataProperty(&it, value).is_null()) {
+    isolate->OptionalRescheduleException(false);
+  }
 }
 
 
 Handle<AccessorInfo> Accessors::ArgumentsIteratorInfo(
     Isolate* isolate, PropertyAttributes attributes) {
-  Handle<Name> name(isolate->native_context()->iterator_symbol(), isolate);
+  Handle<Name> name = isolate->factory()->iterator_symbol();
   return MakeAccessor(isolate, name, &ArgumentsIteratorGetter,
                       &ArgumentsIteratorSetter, attributes);
 }
@@ -258,7 +250,7 @@
 
   if (uint32_v->Number() == number_v->Number()) {
     maybe = JSArray::SetElementsLength(array_handle, uint32_v);
-    maybe.Check();
+    if (maybe.is_null()) isolate->OptionalRescheduleException(false);
     return;
   }
 
@@ -330,6 +322,98 @@
 }
 
 
+template <typename Char>
+inline int CountRequiredEscapes(Handle<String> source) {
+  DisallowHeapAllocation no_gc;
+  int escapes = 0;
+  Vector<const Char> src = source->GetCharVector<Char>();
+  for (int i = 0; i < src.length(); i++) {
+    if (src[i] == '/' && (i == 0 || src[i - 1] != '\\')) escapes++;
+  }
+  return escapes;
+}
+
+
+template <typename Char, typename StringType>
+inline Handle<StringType> WriteEscapedRegExpSource(Handle<String> source,
+                                                   Handle<StringType> result) {
+  DisallowHeapAllocation no_gc;
+  Vector<const Char> src = source->GetCharVector<Char>();
+  Vector<Char> dst(result->GetChars(), result->length());
+  int s = 0;
+  int d = 0;
+  while (s < src.length()) {
+    if (src[s] == '/' && (s == 0 || src[s - 1] != '\\')) dst[d++] = '\\';
+    dst[d++] = src[s++];
+  }
+  DCHECK_EQ(result->length(), d);
+  return result;
+}
+
+
+MaybeHandle<String> EscapeRegExpSource(Isolate* isolate,
+                                       Handle<String> source) {
+  String::Flatten(source);
+  if (source->length() == 0) return isolate->factory()->query_colon_string();
+  bool one_byte = source->IsOneByteRepresentationUnderneath();
+  int escapes = one_byte ? CountRequiredEscapes<uint8_t>(source)
+                         : CountRequiredEscapes<uc16>(source);
+  if (escapes == 0) return source;
+  int length = source->length() + escapes;
+  if (one_byte) {
+    Handle<SeqOneByteString> result;
+    ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
+                               isolate->factory()->NewRawOneByteString(length),
+                               String);
+    return WriteEscapedRegExpSource<uint8_t>(source, result);
+  } else {
+    Handle<SeqTwoByteString> result;
+    ASSIGN_RETURN_ON_EXCEPTION(isolate, result,
+                               isolate->factory()->NewRawTwoByteString(length),
+                               String);
+    return WriteEscapedRegExpSource<uc16>(source, result);
+  }
+}
+
+
+// Implements ECMA262 ES6 draft 21.2.5.9
+void Accessors::RegExpSourceGetter(
+    v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
+  HandleScope scope(isolate);
+
+  Handle<Object> holder =
+      Utils::OpenHandle(*v8::Local<v8::Value>(info.Holder()));
+  Handle<JSRegExp> regexp = Handle<JSRegExp>::cast(holder);
+  Handle<String> result;
+  if (regexp->TypeTag() == JSRegExp::NOT_COMPILED) {
+    result = isolate->factory()->empty_string();
+  } else {
+    Handle<String> pattern(regexp->Pattern(), isolate);
+    MaybeHandle<String> maybe = EscapeRegExpSource(isolate, pattern);
+    if (!maybe.ToHandle(&result)) {
+      isolate->OptionalRescheduleException(false);
+      return;
+    }
+  }
+  info.GetReturnValue().Set(Utils::ToLocal(result));
+}
+
+
+void Accessors::RegExpSourceSetter(v8::Local<v8::Name> name,
+                                   v8::Local<v8::Value> value,
+                                   const v8::PropertyCallbackInfo<void>& info) {
+  UNREACHABLE();
+}
+
+
+Handle<AccessorInfo> Accessors::RegExpSourceInfo(
+    Isolate* isolate, PropertyAttributes attributes) {
+  return MakeAccessor(isolate, isolate->factory()->source_string(),
+                      &RegExpSourceGetter, &RegExpSourceSetter, attributes);
+}
+
+
 //
 // Accessors::ScriptColumnOffset
 //
@@ -892,9 +976,8 @@
 }
 
 
-static Handle<Object> SetFunctionPrototype(Isolate* isolate,
-                                           Handle<JSFunction> function,
-                                           Handle<Object> value) {
+MUST_USE_RESULT static MaybeHandle<Object> SetFunctionPrototype(
+    Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) {
   Handle<Object> old_value;
   bool is_observed = function->map()->is_observed();
   if (is_observed) {
@@ -908,21 +991,17 @@
   DCHECK(function->prototype() == *value);
 
   if (is_observed && !old_value->SameValue(*value)) {
-    JSObject::EnqueueChangeRecord(
+    MaybeHandle<Object> result = JSObject::EnqueueChangeRecord(
         function, "update", isolate->factory()->prototype_string(), old_value);
+    if (result.is_null()) return MaybeHandle<Object>();
   }
 
   return function;
 }
 
 
-Handle<Object> Accessors::FunctionGetPrototype(Handle<JSFunction> function) {
-  return GetFunctionPrototype(function->GetIsolate(), function);
-}
-
-
-Handle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
-                                               Handle<Object> prototype) {
+MaybeHandle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
+                                                    Handle<Object> prototype) {
   DCHECK(function->should_have_prototype());
   Isolate* isolate = function->GetIsolate();
   return SetFunctionPrototype(isolate, function, prototype);
@@ -953,7 +1032,9 @@
   }
   Handle<JSFunction> object =
       Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
-  SetFunctionPrototype(isolate, object, value);
+  if (SetFunctionPrototype(isolate, object, value).is_null()) {
+    isolate->OptionalRescheduleException(false);
+  }
 }
 
 
diff --git a/src/accessors.h b/src/accessors.h
index 8fc1f84..0210d53 100644
--- a/src/accessors.h
+++ b/src/accessors.h
@@ -21,6 +21,7 @@
   V(FunctionName)                 \
   V(FunctionLength)               \
   V(FunctionPrototype)            \
+  V(RegExpSource)                 \
   V(ScriptColumnOffset)           \
   V(ScriptCompilationType)        \
   V(ScriptContextData)            \
@@ -66,9 +67,8 @@
   };
 
   // Accessor functions called directly from the runtime system.
-  static Handle<Object> FunctionSetPrototype(Handle<JSFunction> object,
-                                             Handle<Object> value);
-  static Handle<Object> FunctionGetPrototype(Handle<JSFunction> object);
+  MUST_USE_RESULT static MaybeHandle<Object> FunctionSetPrototype(
+      Handle<JSFunction> object, Handle<Object> value);
   static Handle<Object> FunctionGetArguments(Handle<JSFunction> object);
 
   // Accessor infos.
diff --git a/src/allocation.cc b/src/allocation.cc
index cae1c10..96fd71f 100644
--- a/src/allocation.cc
+++ b/src/allocation.cc
@@ -85,7 +85,7 @@
 
 void* AlignedAlloc(size_t size, size_t alignment) {
   DCHECK_LE(V8_ALIGNOF(void*), alignment);
-  DCHECK(base::bits::IsPowerOfTwo32(alignment));
+  DCHECK(base::bits::IsPowerOfTwo64(alignment));
   void* ptr;
 #if V8_OS_WIN
   ptr = _aligned_malloc(size, alignment);
diff --git a/src/api.cc b/src/api.cc
index e11d140..a459076 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -14,6 +14,7 @@
 #include "include/v8-testing.h"
 #include "src/assert-scope.h"
 #include "src/background-parsing-task.h"
+#include "src/base/functional.h"
 #include "src/base/platform/platform.h"
 #include "src/base/platform/time.h"
 #include "src/base/utils/random-number-generator.h"
@@ -38,8 +39,9 @@
 #include "src/property.h"
 #include "src/property-details.h"
 #include "src/prototype.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 #include "src/runtime-profiler.h"
+#include "src/sampler.h"
 #include "src/scanner-character-streams.h"
 #include "src/simulator.h"
 #include "src/snapshot.h"
@@ -51,9 +53,8 @@
 
 #define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
 
-#define ENTER_V8(isolate)                                          \
-  DCHECK((isolate)->IsInitialized());                              \
-  i::VMState<i::OTHER> __state__((isolate))
+#define ENTER_V8(isolate)             \
+  i::VMState<v8::OTHER> __state__((isolate))
 
 namespace v8 {
 
@@ -186,14 +187,7 @@
 }
 
 
-bool V8::IsDead() {
-  i::Isolate* isolate = i::Isolate::Current();
-  return isolate->IsDead();
-}
-
-
 static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
-  if (!isolate->IsInitialized()) return false;
   if (isolate->has_scheduled_exception()) {
     return isolate->scheduled_exception() ==
         isolate->heap()->termination_exception();
@@ -202,162 +196,60 @@
 }
 
 
-StartupDataDecompressor::StartupDataDecompressor()
-    : raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
-  for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
-    raw_data[i] = NULL;
-  }
-}
-
-
-StartupDataDecompressor::~StartupDataDecompressor() {
-  for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
-    i::DeleteArray(raw_data[i]);
-  }
-  i::DeleteArray(raw_data);
-}
-
-
-int StartupDataDecompressor::Decompress() {
-  int compressed_data_count = V8::GetCompressedStartupDataCount();
-  StartupData* compressed_data =
-      i::NewArray<StartupData>(compressed_data_count);
-  V8::GetCompressedStartupData(compressed_data);
-  for (int i = 0; i < compressed_data_count; ++i) {
-    char* decompressed = raw_data[i] =
-        i::NewArray<char>(compressed_data[i].raw_size);
-    if (compressed_data[i].compressed_size != 0) {
-      int result = DecompressData(decompressed,
-                                  &compressed_data[i].raw_size,
-                                  compressed_data[i].data,
-                                  compressed_data[i].compressed_size);
-      if (result != 0) return result;
-    } else {
-      DCHECK_EQ(0, compressed_data[i].raw_size);
-    }
-    compressed_data[i].data = decompressed;
-  }
-  V8::SetDecompressedStartupData(compressed_data);
-  i::DeleteArray(compressed_data);
-  return 0;
-}
-
-
-StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-  return StartupData::kBZip2;
-#else
-  return StartupData::kUncompressed;
-#endif
-}
-
-
-enum CompressedStartupDataItems {
-  kSnapshot = 0,
-  kSnapshotContext,
-  kLibraries,
-  kExperimentalLibraries,
-  kCompressedStartupDataCount
-};
-
-
-int V8::GetCompressedStartupDataCount() {
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-  return kCompressedStartupDataCount;
-#else
-  return 0;
-#endif
-}
-
-
-void V8::GetCompressedStartupData(StartupData* compressed_data) {
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-  compressed_data[kSnapshot].data =
-      reinterpret_cast<const char*>(i::Snapshot::data());
-  compressed_data[kSnapshot].compressed_size = i::Snapshot::size();
-  compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size();
-
-  compressed_data[kSnapshotContext].data =
-      reinterpret_cast<const char*>(i::Snapshot::context_data());
-  compressed_data[kSnapshotContext].compressed_size =
-      i::Snapshot::context_size();
-  compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size();
-
-  i::Vector<const i::byte> libraries_source = i::Natives::GetScriptsSource();
-  compressed_data[kLibraries].data =
-      reinterpret_cast<const char*>(libraries_source.start());
-  compressed_data[kLibraries].compressed_size = libraries_source.length();
-  compressed_data[kLibraries].raw_size = i::Natives::GetRawScriptsSize();
-
-  i::Vector<const i::byte> exp_libraries_source =
-      i::ExperimentalNatives::GetScriptsSource();
-  compressed_data[kExperimentalLibraries].data =
-      reinterpret_cast<const char*>(exp_libraries_source.start());
-  compressed_data[kExperimentalLibraries].compressed_size =
-      exp_libraries_source.length();
-  compressed_data[kExperimentalLibraries].raw_size =
-      i::ExperimentalNatives::GetRawScriptsSize();
-#endif
-}
-
-
-void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-  DCHECK_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
-  i::Snapshot::set_raw_data(
-      reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
-
-  DCHECK_EQ(i::Snapshot::context_raw_size(),
-            decompressed_data[kSnapshotContext].raw_size);
-  i::Snapshot::set_context_raw_data(
-      reinterpret_cast<const i::byte*>(
-          decompressed_data[kSnapshotContext].data));
-
-  DCHECK_EQ(i::Natives::GetRawScriptsSize(),
-            decompressed_data[kLibraries].raw_size);
-  i::Vector<const char> libraries_source(
-      decompressed_data[kLibraries].data,
-      decompressed_data[kLibraries].raw_size);
-  i::Natives::SetRawScriptsSource(libraries_source);
-
-  DCHECK_EQ(i::ExperimentalNatives::GetRawScriptsSize(),
-            decompressed_data[kExperimentalLibraries].raw_size);
-  i::Vector<const char> exp_libraries_source(
-      decompressed_data[kExperimentalLibraries].data,
-      decompressed_data[kExperimentalLibraries].raw_size);
-  i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source);
-#endif
-}
-
-
 void V8::SetNativesDataBlob(StartupData* natives_blob) {
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
-  i::SetNativesFromFile(natives_blob);
-#else
-  CHECK(false);
-#endif
+  i::V8::SetNativesBlob(natives_blob);
 }
 
 
 void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
-  i::SetSnapshotFromFile(snapshot_blob);
-#else
-  CHECK(false);
-#endif
+  i::V8::SetSnapshotBlob(snapshot_blob);
 }
 
 
-void V8::SetFatalErrorHandler(FatalErrorCallback that) {
-  i::Isolate* isolate = i::Isolate::Current();
-  isolate->set_exception_behavior(that);
-}
+StartupData V8::CreateSnapshotDataBlob() {
+  Isolate::CreateParams params;
+  params.enable_serializer = true;
+  Isolate* isolate = v8::Isolate::New(params);
+  StartupData result = {NULL, 0};
+  {
+    Isolate::Scope isolate_scope(isolate);
+    i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+    Persistent<Context> context;
+    {
+      HandleScope handle_scope(isolate);
+      context.Reset(isolate, Context::New(isolate));
+    }
+    if (!context.IsEmpty()) {
+      // Make sure all builtin scripts are cached.
+      {
+        HandleScope scope(isolate);
+        for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
+          internal_isolate->bootstrapper()->NativesSourceLookup(i);
+        }
+      }
+      // If we don't do this then we end up with a stray root pointing at the
+      // context even after we have disposed of the context.
+      internal_isolate->heap()->CollectAllAvailableGarbage("mksnapshot");
+      i::Object* raw_context = *v8::Utils::OpenPersistent(context);
+      context.Reset();
 
+      i::SnapshotByteSink snapshot_sink;
+      i::StartupSerializer ser(internal_isolate, &snapshot_sink);
+      ser.SerializeStrongReferences();
 
-void V8::SetAllowCodeGenerationFromStringsCallback(
-    AllowCodeGenerationFromStringsCallback callback) {
-  i::Isolate* isolate = i::Isolate::Current();
-  isolate->set_allow_code_gen_callback(callback);
+      i::SnapshotByteSink context_sink;
+      i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink);
+      context_ser.Serialize(&raw_context);
+      ser.SerializeWeakReferences();
+
+      i::SnapshotData sd(snapshot_sink, ser);
+      i::SnapshotData csd(context_sink, context_ser);
+
+      result = i::Snapshot::CreateSnapshotBlob(sd.RawData(), csd.RawData());
+    }
+  }
+  isolate->Dispose();
+  return result;
 }
 
 
@@ -494,26 +386,40 @@
 i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
   LOG_API(isolate, "Persistent::New");
   i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
   (*obj)->ObjectVerify();
-#endif  // DEBUG
+#endif  // VERIFY_HEAP
   return result.location();
 }
 
 
 i::Object** V8::CopyPersistent(i::Object** obj) {
   i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
-#ifdef DEBUG
+#ifdef VERIFY_HEAP
   (*obj)->ObjectVerify();
-#endif  // DEBUG
+#endif  // VERIFY_HEAP
   return result.location();
 }
 
 
-void V8::MakeWeak(i::Object** object,
-                  void* parameters,
+void V8::MakeWeak(i::Object** object, void* parameter,
                   WeakCallback weak_callback) {
-  i::GlobalHandles::MakeWeak(object, parameters, weak_callback);
+  i::GlobalHandles::MakeWeak(object, parameter, weak_callback);
+}
+
+
+void V8::MakePhantom(i::Object** object, void* parameter,
+                     PhantomCallbackData<void>::Callback weak_callback) {
+  i::GlobalHandles::MakePhantom(object, parameter, weak_callback);
+}
+
+
+void V8::MakePhantom(
+    i::Object** object,
+    InternalFieldsCallbackData<void, void>::Callback weak_callback,
+    int internal_field_index1, int internal_field_index2) {
+  i::GlobalHandles::MakePhantom(object, weak_callback, internal_field_index1,
+                                internal_field_index2);
 }
 
 
@@ -750,11 +656,11 @@
 // about this there is no HandleScope in this method.  When you add one to the
 // site calling this method you should check that you ensured the VM was not
 // dead first.
-void NeanderArray::add(i::Handle<i::Object> value) {
+void NeanderArray::add(i::Isolate* isolate, i::Handle<i::Object> value) {
   int length = this->length();
   int size = obj_.size();
   if (length == size - 1) {
-    i::Factory* factory = i::Isolate::Current()->factory();
+    i::Factory* factory = isolate->factory();
     i::Handle<i::FixedArray> new_elms = factory->NewFixedArray(2 * size);
     for (int i = 0; i < length; i++)
       new_elms->set(i + 1, get(i));
@@ -789,12 +695,12 @@
     Utils::OpenHandle(templ)->set_property_list(*list);
   }
   NeanderArray array(list);
-  array.add(isolate->factory()->NewNumberFromInt(length));
+  array.add(isolate, isolate->factory()->NewNumberFromInt(length));
   for (int i = 0; i < length; i++) {
     i::Handle<i::Object> value = data[i].IsEmpty() ?
         i::Handle<i::Object>(isolate->factory()->undefined_value()) :
         Utils::OpenHandle(*data[i]);
-    array.add(value);
+    array.add(isolate, value);
   }
 }
 
@@ -802,7 +708,7 @@
 void Template::Set(v8::Handle<Name> name,
                    v8::Handle<Data> value,
                    v8::PropertyAttribute attribute) {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   const int kSize = 3;
@@ -908,6 +814,9 @@
     v8::Handle<Signature> signature,
     int length) {
   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  // Changes to the environment cannot be captured in the snapshot. Expect no
+  // function templates when the isolate is created for serialization.
+  DCHECK(!i_isolate->serializer_enabled());
   LOG_API(i_isolate, "FunctionTemplate::New");
   ENTER_V8(i_isolate);
   return FunctionTemplateNew(
@@ -1084,11 +993,9 @@
 
 
 int TypeSwitch::match(v8::Handle<Value> value) {
-  i::Isolate* isolate = i::Isolate::Current();
-  LOG_API(isolate, "TypeSwitch::match");
-  USE(isolate);
-  i::Handle<i::Object> obj = Utils::OpenHandle(*value);
   i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
+  LOG_API(info->GetIsolate(), "TypeSwitch::match");
+  i::Handle<i::Object> obj = Utils::OpenHandle(*value);
   i::FixedArray* types = i::FixedArray::cast(info->types());
   for (int i = 0; i < types->length(); i++) {
     if (i::FunctionTemplateInfo::cast(types->get(i))->IsTemplateFor(*obj))
@@ -1249,6 +1156,9 @@
 Local<ObjectTemplate> ObjectTemplate::New(
     i::Isolate* isolate,
     v8::Handle<FunctionTemplate> constructor) {
+  // Changes to the environment cannot be captured in the snapshot. Expect no
+  // object templates when the isolate is created for serialization.
+  DCHECK(!isolate->serializer_enabled());
   LOG_API(isolate, "ObjectTemplate::New");
   ENTER_V8(isolate);
   i::Handle<i::Struct> struct_obj =
@@ -1292,7 +1202,7 @@
     info->set_property_accessors(*list);
   }
   NeanderArray array(list);
-  array.add(obj);
+  array.add(isolate, obj);
 }
 
 
@@ -1394,30 +1304,31 @@
 }
 
 
-void ObjectTemplate::SetNamedPropertyHandler(
-    NamedPropertyGetterCallback getter,
-    NamedPropertySetterCallback setter,
-    NamedPropertyQueryCallback query,
-    NamedPropertyDeleterCallback remover,
-    NamedPropertyEnumeratorCallback enumerator,
-    Handle<Value> data) {
-  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+template <typename Getter, typename Setter, typename Query, typename Deleter,
+          typename Enumerator>
+static void ObjectTemplateSetNamedPropertyHandler(
+    ObjectTemplate* templ, Getter getter, Setter setter, Query query,
+    Deleter remover, Enumerator enumerator, Handle<Value> data,
+    bool can_intercept_symbols, PropertyHandlerFlags flags) {
+  i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
-  EnsureConstructor(isolate, this);
-  i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
-      Utils::OpenHandle(this)->constructor());
+  EnsureConstructor(isolate, templ);
+  i::FunctionTemplateInfo* constructor =
+      i::FunctionTemplateInfo::cast(Utils::OpenHandle(templ)->constructor());
   i::Handle<i::FunctionTemplateInfo> cons(constructor);
-  i::Handle<i::Struct> struct_obj =
-      isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
-  i::Handle<i::InterceptorInfo> obj =
-      i::Handle<i::InterceptorInfo>::cast(struct_obj);
+  auto obj = i::Handle<i::InterceptorInfo>::cast(
+      isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
 
   if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
   if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
   if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
   if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
   if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
+  obj->set_flags(0);
+  obj->set_can_intercept_symbols(can_intercept_symbols);
+  obj->set_all_can_read(static_cast<int>(flags) &
+                        static_cast<int>(PropertyHandlerFlags::kAllCanRead));
 
   if (data.IsEmpty()) {
     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
@@ -1427,6 +1338,24 @@
 }
 
 
+void ObjectTemplate::SetNamedPropertyHandler(
+    NamedPropertyGetterCallback getter, NamedPropertySetterCallback setter,
+    NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover,
+    NamedPropertyEnumeratorCallback enumerator, Handle<Value> data) {
+  ObjectTemplateSetNamedPropertyHandler(this, getter, setter, query, remover,
+                                        enumerator, data, false,
+                                        PropertyHandlerFlags::kNone);
+}
+
+
+void ObjectTemplate::SetHandler(
+    const NamedPropertyHandlerConfiguration& config) {
+  ObjectTemplateSetNamedPropertyHandler(
+      this, config.getter, config.setter, config.query, config.deleter,
+      config.enumerator, config.data, true, config.flags);
+}
+
+
 void ObjectTemplate::MarkAsUndetectable() {
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ENTER_V8(isolate);
@@ -1470,13 +1399,8 @@
 }
 
 
-void ObjectTemplate::SetIndexedPropertyHandler(
-    IndexedPropertyGetterCallback getter,
-    IndexedPropertySetterCallback setter,
-    IndexedPropertyQueryCallback query,
-    IndexedPropertyDeleterCallback remover,
-    IndexedPropertyEnumeratorCallback enumerator,
-    Handle<Value> data) {
+void ObjectTemplate::SetHandler(
+    const IndexedPropertyHandlerConfiguration& config) {
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
@@ -1484,17 +1408,21 @@
   i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
       Utils::OpenHandle(this)->constructor());
   i::Handle<i::FunctionTemplateInfo> cons(constructor);
-  i::Handle<i::Struct> struct_obj =
-      isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
-  i::Handle<i::InterceptorInfo> obj =
-      i::Handle<i::InterceptorInfo>::cast(struct_obj);
+  auto obj = i::Handle<i::InterceptorInfo>::cast(
+      isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
 
-  if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
-  if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
-  if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
-  if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
-  if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
+  if (config.getter != 0) SET_FIELD_WRAPPED(obj, set_getter, config.getter);
+  if (config.setter != 0) SET_FIELD_WRAPPED(obj, set_setter, config.setter);
+  if (config.query != 0) SET_FIELD_WRAPPED(obj, set_query, config.query);
+  if (config.deleter != 0) SET_FIELD_WRAPPED(obj, set_deleter, config.deleter);
+  if (config.enumerator != 0) {
+    SET_FIELD_WRAPPED(obj, set_enumerator, config.enumerator);
+  }
+  obj->set_flags(0);
+  obj->set_all_can_read(static_cast<int>(config.flags) &
+                        static_cast<int>(PropertyHandlerFlags::kAllCanRead));
 
+  v8::Local<v8::Value> data = config.data;
   if (data.IsEmpty()) {
     data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
   }
@@ -1556,7 +1484,10 @@
 
 ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
                                        BufferPolicy buffer_policy_)
-    : data(data_), length(length_), buffer_policy(buffer_policy_) {}
+    : data(data_),
+      length(length_),
+      rejected(false),
+      buffer_policy(buffer_policy_) {}
 
 
 ScriptCompiler::CachedData::~CachedData() {
@@ -1587,7 +1518,7 @@
       function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate());
   i::Handle<i::JSFunction> function =
       obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo(
-          function_info, obj->GetIsolate()->global_context());
+          function_info, obj->GetIsolate()->native_context());
   return ToApiHandle<Script>(function);
 }
 
@@ -1717,6 +1648,12 @@
     options = kConsumeParserCache;
   }
 
+  // Don't try to produce any kind of cache when the debugger is loaded.
+  if (isolate->debug()->is_loaded() &&
+      (options == kProduceParserCache || options == kProduceCodeCache)) {
+    options = kNoCompileOptions;
+  }
+
   i::ScriptData* script_data = NULL;
   if (options == kConsumeParserCache || options == kConsumeCodeCache) {
     DCHECK(source->cached_data);
@@ -1752,7 +1689,7 @@
     EXCEPTION_PREAMBLE(isolate);
     i::Handle<i::SharedFunctionInfo> result = i::Compiler::CompileScript(
         str, name_obj, line_offset, column_offset, is_shared_cross_origin,
-        isolate->global_context(), NULL, &script_data, options,
+        isolate->native_context(), NULL, &script_data, options,
         i::NOT_NATIVES_CODE);
     has_pending_exception = result.is_null();
     if (has_pending_exception && script_data != NULL) {
@@ -1772,6 +1709,8 @@
       source->cached_data = new CachedData(
           script_data->data(), script_data->length(), CachedData::BufferOwned);
       script_data->ReleaseDataOwnership();
+    } else if (options == kConsumeParserCache || options == kConsumeCodeCache) {
+      source->cached_data->rejected = script_data->rejected();
     }
     delete script_data;
   }
@@ -1797,17 +1736,6 @@
 ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript(
     Isolate* v8_isolate, StreamedSource* source, CompileOptions options) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
-  if (!isolate->global_context().is_null() &&
-      !isolate->global_context()->IsNativeContext()) {
-    // The context chain is non-trivial, and constructing the corresponding
-    // non-trivial Scope chain outside the V8 heap is not implemented. Don't
-    // stream the script. This will only occur if Harmony scoping is enabled and
-    // a previous script has introduced "let" or "const" variables. TODO(marja):
-    // Implement externalizing ScopeInfos and constructing non-trivial Scope
-    // chains independent of the V8 heap so that we can stream also in this
-    // case.
-    return NULL;
-  }
   return new i::BackgroundParsingTask(source->impl(), options,
                                       i::FLAG_stack_size, isolate);
 }
@@ -1844,13 +1772,14 @@
                                          v8::True(v8_isolate));
     }
     source->info->set_script(script);
-    source->info->SetContext(isolate->global_context());
+    source->info->SetContext(isolate->native_context());
 
     EXCEPTION_PREAMBLE(isolate);
 
     // Do the parsing tasks which need to be done on the main thread. This will
     // also handle parse errors.
     source->parser->Internalize();
+    source->parser->HandleSourceURLComments();
 
     i::Handle<i::SharedFunctionInfo> result =
         i::Handle<i::SharedFunctionInfo>::null();
@@ -1877,6 +1806,13 @@
 }
 
 
+uint32_t ScriptCompiler::CachedDataVersionTag() {
+  return static_cast<uint32_t>(base::hash_combine(
+      internal::Version::Hash(), internal::FlagList::Hash(),
+      static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
+}
+
+
 Local<Script> Script::Compile(v8::Handle<String> source,
                               v8::ScriptOrigin* origin) {
   i::Handle<i::String> str = Utils::OpenHandle(*source);
@@ -1920,8 +1856,24 @@
 }
 
 
+v8::TryCatch::TryCatch(v8::Isolate* isolate)
+    : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
+      next_(isolate_->try_catch_handler()),
+      is_verbose_(false),
+      can_continue_(true),
+      capture_message_(true),
+      rethrow_(false),
+      has_terminated_(false) {
+  ResetInternal();
+  // Special handling for simulators which have a separate JS stack.
+  js_stack_comparable_address_ =
+      reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
+          v8::internal::GetCurrentStackPosition()));
+  isolate_->RegisterTryCatchHandler(this);
+}
+
+
 v8::TryCatch::~TryCatch() {
-  DCHECK(isolate_ == i::Isolate::Current());
   if (rethrow_) {
     v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
     v8::HandleScope scope(isolate);
@@ -1974,7 +1926,6 @@
 
 
 v8::Local<Value> v8::TryCatch::Exception() const {
-  DCHECK(isolate_ == i::Isolate::Current());
   if (HasCaught()) {
     // Check for out of memory exception.
     i::Object* exception = reinterpret_cast<i::Object*>(exception_);
@@ -1986,7 +1937,6 @@
 
 
 v8::Local<Value> v8::TryCatch::StackTrace() const {
-  DCHECK(isolate_ == i::Isolate::Current());
   if (HasCaught()) {
     i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
     if (!raw_obj->IsJSObject()) return v8::Local<Value>();
@@ -2010,7 +1960,6 @@
 
 
 v8::Local<v8::Message> v8::TryCatch::Message() const {
-  DCHECK(isolate_ == i::Isolate::Current());
   i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
   DCHECK(message->IsJSMessageObject() || message->IsTheHole());
   if (HasCaught() && !message->IsTheHole()) {
@@ -2022,7 +1971,6 @@
 
 
 void v8::TryCatch::Reset() {
-  DCHECK(isolate_ == i::Isolate::Current());
   if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
     // If an exception was caught but is still scheduled because no API call
     // promoted it, then it is canceled to prevent it from being propagated.
@@ -2110,11 +2058,8 @@
 
 
 MUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
-    const char* name,
-    i::Handle<i::Object> recv,
-    int argc,
+    i::Isolate* isolate, const char* name, i::Handle<i::Object> recv, int argc,
     i::Handle<i::Object> argv[]) {
-  i::Isolate* isolate = i::Isolate::Current();
   i::Handle<i::Object> object_fun =
       i::Object::GetProperty(
           isolate, isolate->js_builtins_object(), name).ToHandleChecked();
@@ -2124,13 +2069,10 @@
 
 
 MUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
-    const char* name,
-    i::Handle<i::Object> data) {
+    i::Isolate* isolate, const char* name, i::Handle<i::Object> data) {
   i::Handle<i::Object> argv[] = { data };
-  return CallV8HeapFunction(name,
-                            i::Isolate::Current()->js_builtins_object(),
-                            arraysize(argv),
-                            argv);
+  return CallV8HeapFunction(isolate, name, isolate->js_builtins_object(),
+                            arraysize(argv), argv);
 }
 
 
@@ -2142,8 +2084,9 @@
 
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> result;
-  has_pending_exception = !CallV8HeapFunction(
-      "GetLineNumber", Utils::OpenHandle(this)).ToHandle(&result);
+  has_pending_exception =
+      !CallV8HeapFunction(isolate, "GetLineNumber", Utils::OpenHandle(this))
+           .ToHandle(&result);
   EXCEPTION_BAILOUT_CHECK(isolate, 0);
   return static_cast<int>(result->Number());
 }
@@ -2177,8 +2120,9 @@
   i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> start_col_obj;
-  has_pending_exception = !CallV8HeapFunction(
-      "GetPositionInLine", data_obj).ToHandle(&start_col_obj);
+  has_pending_exception =
+      !CallV8HeapFunction(isolate, "GetPositionInLine", data_obj)
+           .ToHandle(&start_col_obj);
   EXCEPTION_BAILOUT_CHECK(isolate, 0);
   return static_cast<int>(start_col_obj->Number());
 }
@@ -2192,8 +2136,9 @@
   i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> start_col_obj;
-  has_pending_exception = !CallV8HeapFunction(
-      "GetPositionInLine", data_obj).ToHandle(&start_col_obj);
+  has_pending_exception =
+      !CallV8HeapFunction(isolate, "GetPositionInLine", data_obj)
+           .ToHandle(&start_col_obj);
   EXCEPTION_BAILOUT_CHECK(isolate, 0);
   i::Handle<i::JSMessageObject> message =
       i::Handle<i::JSMessageObject>::cast(data_obj);
@@ -2223,8 +2168,9 @@
   EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> result;
-  has_pending_exception = !CallV8HeapFunction(
-      "GetSourceLine", Utils::OpenHandle(this)).ToHandle(&result);
+  has_pending_exception =
+      !CallV8HeapFunction(isolate, "GetSourceLine", Utils::OpenHandle(this))
+           .ToHandle(&result);
   EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
   if (result->IsString()) {
     return scope.Escape(Utils::ToLocal(i::Handle<i::String>::cast(result)));
@@ -2568,13 +2514,36 @@
 }
 
 
-Local<String> Value::ToString() const {
+bool Value::IsGeneratorFunction() const {
+  i::Handle<i::Object> obj = Utils::OpenHandle(this);
+  if (!obj->IsJSFunction()) return false;
+  i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
+  return func->shared()->is_generator();
+}
+
+
+bool Value::IsGeneratorObject() const {
+  return Utils::OpenHandle(this)->IsJSGeneratorObject();
+}
+
+
+bool Value::IsMapIterator() const {
+  return Utils::OpenHandle(this)->IsJSMapIterator();
+}
+
+
+bool Value::IsSetIterator() const {
+  return Utils::OpenHandle(this)->IsJSSetIterator();
+}
+
+
+Local<String> Value::ToString(Isolate* v8_isolate) const {
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> str;
   if (obj->IsString()) {
     str = obj;
   } else {
-    i::Isolate* isolate = i::Isolate::Current();
+    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
     LOG_API(isolate, "ToString");
     ENTER_V8(isolate);
     EXCEPTION_PREAMBLE(isolate);
@@ -2586,13 +2555,13 @@
 }
 
 
-Local<String> Value::ToDetailString() const {
+Local<String> Value::ToDetailString(Isolate* v8_isolate) const {
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> str;
   if (obj->IsString()) {
     str = obj;
   } else {
-    i::Isolate* isolate = i::Isolate::Current();
+    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
     LOG_API(isolate, "ToDetailString");
     ENTER_V8(isolate);
     EXCEPTION_PREAMBLE(isolate);
@@ -2604,13 +2573,13 @@
 }
 
 
-Local<v8::Object> Value::ToObject() const {
+Local<v8::Object> Value::ToObject(Isolate* v8_isolate) const {
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> val;
   if (obj->IsJSObject()) {
     val = obj;
   } else {
-    i::Isolate* isolate = i::Isolate::Current();
+    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
     LOG_API(isolate, "ToObject");
     ENTER_V8(isolate);
     EXCEPTION_PREAMBLE(isolate);
@@ -2622,12 +2591,12 @@
 }
 
 
-Local<Boolean> Value::ToBoolean() const {
+Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   if (obj->IsBoolean()) {
     return ToApiHandle<Boolean>(obj);
   } else {
-    i::Isolate* isolate = i::Isolate::Current();
+    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
     LOG_API(isolate, "ToBoolean");
     ENTER_V8(isolate);
     i::Handle<i::Object> val =
@@ -2637,13 +2606,13 @@
 }
 
 
-Local<Number> Value::ToNumber() const {
+Local<Number> Value::ToNumber(Isolate* v8_isolate) const {
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> num;
   if (obj->IsNumber()) {
     num = obj;
   } else {
-    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
+    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
     LOG_API(isolate, "ToNumber");
     ENTER_V8(isolate);
     EXCEPTION_PREAMBLE(isolate);
@@ -2655,13 +2624,13 @@
 }
 
 
-Local<Integer> Value::ToInteger() const {
+Local<Integer> Value::ToInteger(Isolate* v8_isolate) const {
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> num;
   if (obj->IsSmi()) {
     num = obj;
   } else {
-    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
+    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
     LOG_API(isolate, "ToInteger");
     ENTER_V8(isolate);
     EXCEPTION_PREAMBLE(isolate);
@@ -2676,7 +2645,6 @@
 void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
   Utils::ApiCheck(isolate != NULL &&
-                  isolate->IsInitialized() &&
                   !isolate->IsDead(),
                   "v8::internal::Internals::CheckInitialized()",
                   "Isolate is not initialized or V8 has died");
@@ -2924,13 +2892,13 @@
 }
 
 
-Local<Int32> Value::ToInt32() const {
+Local<Int32> Value::ToInt32(Isolate* v8_isolate) const {
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> num;
   if (obj->IsSmi()) {
     num = obj;
   } else {
-    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
+    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
     LOG_API(isolate, "ToInt32");
     ENTER_V8(isolate);
     EXCEPTION_PREAMBLE(isolate);
@@ -2941,13 +2909,13 @@
 }
 
 
-Local<Uint32> Value::ToUint32() const {
+Local<Uint32> Value::ToUint32(Isolate* v8_isolate) const {
   i::Handle<i::Object> obj = Utils::OpenHandle(this);
   i::Handle<i::Object> num;
   if (obj->IsSmi()) {
     num = obj;
   } else {
-    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
+    i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
     LOG_API(isolate, "ToUInt32");
     ENTER_V8(isolate);
     EXCEPTION_PREAMBLE(isolate);
@@ -3010,8 +2978,13 @@
 
 
 bool Value::Equals(Handle<Value> that) const {
-  i::Isolate* isolate = i::Isolate::Current();
   i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
+  i::Handle<i::Object> other = Utils::OpenHandle(*that);
+  if (obj->IsSmi() && other->IsSmi()) {
+    return obj->Number() == other->Number();
+  }
+  i::Object* ho = obj->IsSmi() ? *other : *obj;
+  i::Isolate* isolate = i::HeapObject::cast(ho)->GetIsolate();
   if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
                        "v8::Value::Equals()",
                        "Reading from empty handle")) {
@@ -3019,7 +2992,6 @@
   }
   LOG_API(isolate, "Equals");
   ENTER_V8(isolate);
-  i::Handle<i::Object> other = Utils::OpenHandle(*that);
   // If both obj and other are JSObjects, we'd better compare by identity
   // immediately when going into JS builtin.  The reason is Invoke
   // would overwrite global object receiver with global proxy.
@@ -3029,23 +3001,27 @@
   i::Handle<i::Object> args[] = { other };
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> result;
-  has_pending_exception = !CallV8HeapFunction(
-      "EQUALS", obj, arraysize(args), args).ToHandle(&result);
+  has_pending_exception =
+      !CallV8HeapFunction(isolate, "EQUALS", obj, arraysize(args), args)
+           .ToHandle(&result);
   EXCEPTION_BAILOUT_CHECK(isolate, false);
   return *result == i::Smi::FromInt(i::EQUAL);
 }
 
 
 bool Value::StrictEquals(Handle<Value> that) const {
-  i::Isolate* isolate = i::Isolate::Current();
   i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
+  i::Handle<i::Object> other = Utils::OpenHandle(*that);
+  if (obj->IsSmi()) {
+    return other->IsNumber() && obj->Number() == other->Number();
+  }
+  i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
   if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
                        "v8::Value::StrictEquals()",
                        "Reading from empty handle")) {
     return false;
   }
   LOG_API(isolate, "StrictEquals");
-  i::Handle<i::Object> other = Utils::OpenHandle(*that);
   // Must check HeapNumber first, since NaN !== NaN.
   if (obj->IsHeapNumber()) {
     if (!other->IsNumber()) return false;
@@ -3162,6 +3138,44 @@
 }
 
 
+i::MaybeHandle<i::Object> DeleteObjectProperty(
+    i::Isolate* isolate, i::Handle<i::JSReceiver> receiver,
+    i::Handle<i::Object> key, i::JSReceiver::DeleteMode mode) {
+  // Check if the given key is an array index.
+  uint32_t index;
+  if (key->ToArrayIndex(&index)) {
+    // In Firefox/SpiderMonkey, Safari and Opera you can access the
+    // characters of a string using [] notation.  In the case of a
+    // String object we just need to redirect the deletion to the
+    // underlying string if the index is in range.  Since the
+    // underlying string does nothing with the deletion, we can ignore
+    // such deletions.
+    if (receiver->IsStringObjectWithCharacterAt(index)) {
+      return isolate->factory()->true_value();
+    }
+
+    return i::JSReceiver::DeleteElement(receiver, index, mode);
+  }
+
+  i::Handle<i::Name> name;
+  if (key->IsName()) {
+    name = i::Handle<i::Name>::cast(key);
+  } else {
+    // Call-back into JavaScript to convert the key to a string.
+    i::Handle<i::Object> converted;
+    if (!i::Execution::ToString(isolate, key).ToHandle(&converted)) {
+      return i::MaybeHandle<i::Object>();
+    }
+    name = i::Handle<i::String>::cast(converted);
+  }
+
+  if (name->IsString()) {
+    name = i::String::Flatten(i::Handle<i::String>::cast(name));
+  }
+  return i::JSReceiver::DeleteProperty(receiver, name, mode);
+}
+
+
 bool v8::Object::ForceDelete(v8::Handle<Value> key) {
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
@@ -3180,8 +3194,9 @@
 
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj;
-  has_pending_exception = !i::Runtime::DeleteObjectProperty(
-      isolate, self, key_obj, i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
+  has_pending_exception =
+      !DeleteObjectProperty(isolate, self, key_obj,
+                            i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
   EXCEPTION_BAILOUT_CHECK(isolate, false);
   return obj->IsTrue();
 }
@@ -3256,11 +3271,10 @@
   i::Handle<i::Object> args[] = { obj, key_name };
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> result;
-  has_pending_exception = !CallV8HeapFunction(
-      "ObjectGetOwnPropertyDescriptor",
-      isolate->factory()->undefined_value(),
-      arraysize(args),
-      args).ToHandle(&result);
+  has_pending_exception =
+      !CallV8HeapFunction(isolate, "ObjectGetOwnPropertyDescriptor",
+                          isolate->factory()->undefined_value(),
+                          arraysize(args), args).ToHandle(&result);
   EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
   return Utils::ToLocal(result);
 }
@@ -3359,6 +3373,37 @@
 }
 
 
+static bool GetPredefinedToString(i::Handle<i::String> tag,
+                                  Local<String>* result) {
+  i::Isolate* i_isolate = tag->GetIsolate();
+  Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
+  i::Factory* factory = i_isolate->factory();
+
+  if (i::String::Equals(tag, factory->Arguments_string())) {
+    *result = v8::String::NewFromUtf8(isolate, "[object ~Arguments]");
+  } else if (i::String::Equals(tag, factory->Array_string())) {
+    *result = v8::String::NewFromUtf8(isolate, "[object ~Array]");
+  } else if (i::String::Equals(tag, factory->Boolean_string())) {
+    *result = v8::String::NewFromUtf8(isolate, "[object ~Boolean]");
+  } else if (i::String::Equals(tag, factory->Date_string())) {
+    *result = v8::String::NewFromUtf8(isolate, "[object ~Date]");
+  } else if (i::String::Equals(tag, factory->Error_string())) {
+    *result = v8::String::NewFromUtf8(isolate, "[object ~Error]");
+  } else if (i::String::Equals(tag, factory->Function_string())) {
+    *result = v8::String::NewFromUtf8(isolate, "[object ~Function]");
+  } else if (i::String::Equals(tag, factory->Number_string())) {
+    *result = v8::String::NewFromUtf8(isolate, "[object ~Number]");
+  } else if (i::String::Equals(tag, factory->RegExp_string())) {
+    *result = v8::String::NewFromUtf8(isolate, "[object ~RegExp]");
+  } else if (i::String::Equals(tag, factory->String_string())) {
+    *result = v8::String::NewFromUtf8(isolate, "[object ~String]");
+  } else {
+    return false;
+  }
+  return true;
+}
+
+
 Local<String> v8::Object::ObjectProtoToString() {
   i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
   Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
@@ -3368,6 +3413,7 @@
   i::Handle<i::JSObject> self = Utils::OpenHandle(this);
 
   i::Handle<i::Object> name(self->class_name(), i_isolate);
+  i::Handle<i::Object> tag;
 
   // Native implementation of Object.prototype.toString (v8natives.js):
   //   var c = %_ClassOf(this);
@@ -3382,6 +3428,27 @@
                           i_isolate->factory()->Arguments_string())) {
       return v8::String::NewFromUtf8(isolate, "[object Object]");
     } else {
+      if (internal::FLAG_harmony_tostring) {
+        i::Handle<i::Symbol> toStringTag =
+            Utils::OpenHandle(*Symbol::GetToStringTag(isolate));
+        EXCEPTION_PREAMBLE(i_isolate);
+        has_pending_exception =
+            !i::Runtime::GetObjectProperty(i_isolate, self, toStringTag)
+                 .ToHandle(&tag);
+        EXCEPTION_BAILOUT_CHECK(i_isolate, Local<v8::String>());
+
+        if (!tag->IsUndefined()) {
+          if (!tag->IsString())
+            return v8::String::NewFromUtf8(isolate, "[object ???]");
+          i::Handle<i::String> tag_name = i::Handle<i::String>::cast(tag);
+          if (!i::String::Equals(class_name, tag_name)) {
+            Local<String> result;
+            if (GetPredefinedToString(tag_name, &result)) return result;
+
+            class_name = tag_name;
+          }
+        }
+      }
       const char* prefix = "[object ";
       Local<String> str = Utils::ToLocal(class_name);
       const char* postfix = "]";
@@ -3434,8 +3501,9 @@
   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj;
-  has_pending_exception = !i::Runtime::DeleteObjectProperty(
-      isolate, self, key_obj, i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
+  has_pending_exception =
+      !DeleteObjectProperty(isolate, self, key_obj,
+                            i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
   EXCEPTION_BAILOUT_CHECK(isolate, false);
   return obj->IsTrue();
 }
@@ -3453,11 +3521,22 @@
   i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
   i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
   EXCEPTION_PREAMBLE(isolate);
-  i::Handle<i::Object> obj;
-  has_pending_exception = !i::Runtime::HasObjectProperty(
-      isolate, self, key_obj).ToHandle(&obj);
+  Maybe<bool> maybe;
+  // Check if the given key is an array index.
+  uint32_t index;
+  if (key_obj->ToArrayIndex(&index)) {
+    maybe = i::JSReceiver::HasElement(self, index);
+  } else {
+    // Convert the key to a name - possibly by calling back into JavaScript.
+    i::Handle<i::Name> name;
+    if (i::Runtime::ToName(isolate, key_obj).ToHandle(&name)) {
+      maybe = i::JSReceiver::HasProperty(self, name);
+    }
+  }
+  if (!maybe.has_value) has_pending_exception = true;
   EXCEPTION_BAILOUT_CHECK(isolate, false);
-  return obj->IsTrue();
+  DCHECK(maybe.has_value);
+  return maybe.value;
 }
 
 
@@ -3520,7 +3599,9 @@
       i::JSObject::SetAccessor(Utils::OpenHandle(obj), info),
       false);
   if (result->IsUndefined()) return false;
-  if (fast) i::JSObject::MigrateSlowToFast(Utils::OpenHandle(obj), 0);
+  if (fast) {
+    i::JSObject::MigrateSlowToFast(Utils::OpenHandle(obj), 0, "APISetAccessor");
+  }
   return true;
 }
 
@@ -3706,17 +3787,13 @@
   // as optimized code does not always handle access checks.
   i::Deoptimizer::DeoptimizeGlobalObject(*obj);
 
-  i::Handle<i::Map> new_map = i::Map::Copy(i::Handle<i::Map>(obj->map()));
+  i::Handle<i::Map> new_map =
+      i::Map::Copy(i::Handle<i::Map>(obj->map()), "APITurnOnAccessCheck");
   new_map->set_is_access_check_needed(true);
   i::JSObject::MigrateToMap(obj, new_map);
 }
 
 
-bool v8::Object::IsDirty() {
-  return Utils::OpenHandle(this)->IsDirty();
-}
-
-
 Local<v8::Object> v8::Object::Clone() {
   i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
   ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
@@ -4223,6 +4300,16 @@
 }
 
 
+int Name::GetIdentityHash() {
+  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+  ON_BAILOUT(isolate, "v8::Name::GetIdentityHash()", return 0);
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
+  i::Handle<i::Name> self = Utils::OpenHandle(this);
+  return static_cast<int>(self->Hash());
+}
+
+
 int String::Length() const {
   i::Handle<i::String> str = Utils::OpenHandle(this);
   return str->length();
@@ -5041,6 +5128,9 @@
   i::V8::ShutdownPlatform();
 }
 
+v8::Platform* v8::V8::GetCurrentPlatform() {
+  return i::V8::GetCurrentPlatform();
+}
 
 bool v8::V8::Initialize() {
   i::V8::Initialize();
@@ -5081,50 +5171,6 @@
                                   heap_size_limit_(0) { }
 
 
-void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
-  i::Isolate* isolate = i::Isolate::Current();
-  isolate->heap()->VisitExternalResources(visitor);
-}
-
-
-class VisitorAdapter : public i::ObjectVisitor {
- public:
-  explicit VisitorAdapter(PersistentHandleVisitor* visitor)
-      : visitor_(visitor) {}
-  virtual void VisitPointers(i::Object** start, i::Object** end) {
-    UNREACHABLE();
-  }
-  virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
-    Value* value = ToApi<Value>(i::Handle<i::Object>(p));
-    visitor_->VisitPersistentHandle(
-        reinterpret_cast<Persistent<Value>*>(&value), class_id);
-  }
- private:
-  PersistentHandleVisitor* visitor_;
-};
-
-
-void v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
-  i::Isolate* isolate = i::Isolate::Current();
-  i::DisallowHeapAllocation no_allocation;
-
-  VisitorAdapter visitor_adapter(visitor);
-  isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
-}
-
-
-void v8::V8::VisitHandlesForPartialDependence(
-    Isolate* exported_isolate, PersistentHandleVisitor* visitor) {
-  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
-  DCHECK(isolate == i::Isolate::Current());
-  i::DisallowHeapAllocation no_allocation;
-
-  VisitorAdapter visitor_adapter(visitor);
-  isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
-      &visitor_adapter);
-}
-
-
 bool v8::V8::InitializeICU(const char* icu_data_file) {
   return i::InitializeICU(icu_data_file);
 }
@@ -5220,25 +5266,25 @@
 
 
 void v8::Context::SetSecurityToken(Handle<Value> token) {
-  i::Isolate* isolate = i::Isolate::Current();
-  ENTER_V8(isolate);
   i::Handle<i::Context> env = Utils::OpenHandle(this);
+  i::Isolate* isolate = env->GetIsolate();
+  ENTER_V8(isolate);
   i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
   env->set_security_token(*token_handle);
 }
 
 
 void v8::Context::UseDefaultSecurityToken() {
-  i::Isolate* isolate = i::Isolate::Current();
-  ENTER_V8(isolate);
   i::Handle<i::Context> env = Utils::OpenHandle(this);
+  i::Isolate* isolate = env->GetIsolate();
+  ENTER_V8(isolate);
   env->set_security_token(env->global_object());
 }
 
 
 Handle<Value> v8::Context::GetSecurityToken() {
-  i::Isolate* isolate = i::Isolate::Current();
   i::Handle<i::Context> env = Utils::OpenHandle(this);
+  i::Isolate* isolate = env->GetIsolate();
   i::Object* security_token = env->security_token();
   i::Handle<i::Object> token_handle(security_token, isolate);
   return Utils::ToLocal(token_handle);
@@ -5297,40 +5343,42 @@
 
 
 Local<v8::Object> ObjectTemplate::NewInstance() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Handle<i::ObjectTemplateInfo> info = Utils::OpenHandle(this);
+  i::Isolate* isolate = info->GetIsolate();
   ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
              return Local<v8::Object>());
   LOG_API(isolate, "ObjectTemplate::NewInstance");
   ENTER_V8(isolate);
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj;
-  has_pending_exception = !i::Execution::InstantiateObject(
-      Utils::OpenHandle(this)).ToHandle(&obj);
+  has_pending_exception = !i::Execution::InstantiateObject(info).ToHandle(&obj);
   EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
   return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
 }
 
 
 Local<v8::Function> FunctionTemplate::GetFunction() {
-  i::Isolate* isolate = i::Isolate::Current();
+  i::Handle<i::FunctionTemplateInfo> info = Utils::OpenHandle(this);
+  i::Isolate* isolate = info->GetIsolate();
   ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
              return Local<v8::Function>());
   LOG_API(isolate, "FunctionTemplate::GetFunction");
   ENTER_V8(isolate);
   EXCEPTION_PREAMBLE(isolate);
   i::Handle<i::Object> obj;
-  has_pending_exception = !i::Execution::InstantiateFunction(
-      Utils::OpenHandle(this)).ToHandle(&obj);
+  has_pending_exception =
+      !i::Execution::InstantiateFunction(info).ToHandle(&obj);
   EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
   return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
 }
 
 
 bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
-  ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
-             return false);
+  i::Handle<i::FunctionTemplateInfo> info = Utils::OpenHandle(this);
+  i::Isolate* isolate = info->GetIsolate();
+  ON_BAILOUT(isolate, "v8::FunctionTemplate::HasInstanceOf()", return false);
   i::Object* obj = *Utils::OpenHandle(*value);
-  return Utils::OpenHandle(this)->IsTemplateFor(obj);
+  return info->IsTemplateFor(obj);
 }
 
 
@@ -5476,28 +5524,26 @@
   LOG_API(isolate, "String::New(char)");
   ENTER_V8(isolate);
   i::Handle<i::String> right_string = Utils::OpenHandle(*right);
-  // We do not expect this to fail. Change this if it does.
+  // If we are steering towards a range error, do not wait for the error to be
+  // thrown, and return the null handle instead.
+  if (left_string->length() + right_string->length() > i::String::kMaxLength) {
+    return Local<String>();
+  }
   i::Handle<i::String> result = isolate->factory()->NewConsString(
       left_string, right_string).ToHandleChecked();
   return Utils::ToLocal(result);
 }
 
 
-static i::Handle<i::String> NewExternalStringHandle(
-    i::Isolate* isolate,
-    v8::String::ExternalStringResource* resource) {
-  // We do not expect this to fail. Change this if it does.
-  return isolate->factory()->NewExternalStringFromTwoByte(
-      resource).ToHandleChecked();
+static i::MaybeHandle<i::String> NewExternalStringHandle(
+    i::Isolate* isolate, v8::String::ExternalStringResource* resource) {
+  return isolate->factory()->NewExternalStringFromTwoByte(resource);
 }
 
 
-static i::Handle<i::String> NewExternalOneByteStringHandle(
+static i::MaybeHandle<i::String> NewExternalOneByteStringHandle(
     i::Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
-  // We do not expect this to fail. Change this if it does.
-  return isolate->factory()
-      ->NewExternalStringFromOneByte(resource)
-      .ToHandleChecked();
+  return isolate->factory()->NewExternalStringFromOneByte(resource);
 }
 
 
@@ -5508,9 +5554,13 @@
   LOG_API(i_isolate, "String::NewExternal");
   ENTER_V8(i_isolate);
   CHECK(resource && resource->data());
-  i::Handle<i::String> result = NewExternalStringHandle(i_isolate, resource);
-  i_isolate->heap()->external_string_table()->AddString(*result);
-  return Utils::ToLocal(result);
+  EXCEPTION_PREAMBLE(i_isolate);
+  i::Handle<i::String> string;
+  has_pending_exception =
+      !NewExternalStringHandle(i_isolate, resource).ToHandle(&string);
+  EXCEPTION_BAILOUT_CHECK(i_isolate, Local<String>());
+  i_isolate->heap()->external_string_table()->AddString(*string);
+  return Utils::ToLocal(string);
 }
 
 
@@ -5546,10 +5596,13 @@
   LOG_API(i_isolate, "String::NewExternal");
   ENTER_V8(i_isolate);
   CHECK(resource && resource->data());
-  i::Handle<i::String> result =
-      NewExternalOneByteStringHandle(i_isolate, resource);
-  i_isolate->heap()->external_string_table()->AddString(*result);
-  return Utils::ToLocal(result);
+  EXCEPTION_PREAMBLE(i_isolate);
+  i::Handle<i::String> string;
+  has_pending_exception =
+      !NewExternalOneByteStringHandle(i_isolate, resource).ToHandle(&string);
+  EXCEPTION_BAILOUT_CHECK(i_isolate, Local<String>());
+  i_isolate->heap()->external_string_table()->AddString(*string);
+  return Utils::ToLocal(string);
 }
 
 
@@ -5581,7 +5634,6 @@
 
 
 bool v8::String::CanMakeExternal() {
-  if (!internal::FLAG_clever_optimizations) return false;
   i::Handle<i::String> obj = Utils::OpenHandle(this);
   i::Isolate* isolate = obj->GetIsolate();
 
@@ -5593,6 +5645,12 @@
 }
 
 
+Isolate* v8::Object::GetIsolate() {
+  i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
+  return reinterpret_cast<Isolate*>(i_isolate);
+}
+
+
 Local<v8::Object> v8::Object::New(Isolate* isolate) {
   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
   LOG_API(i_isolate, "Object::New");
@@ -5715,7 +5773,6 @@
 
 void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
   i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  if (!i_isolate->IsInitialized()) return;
   ON_BAILOUT(i_isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
              return);
   LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
@@ -5970,11 +6027,26 @@
 }
 
 
+bool Promise::HasHandler() {
+  i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
+  i::Isolate* isolate = promise->GetIsolate();
+  LOG_API(isolate, "Promise::HasRejectHandler");
+  ENTER_V8(isolate);
+  i::Handle<i::Symbol> key = isolate->factory()->promise_has_handler_symbol();
+  return i::JSObject::GetDataProperty(promise, key)->IsTrue();
+}
+
+
 bool v8::ArrayBuffer::IsExternal() const {
   return Utils::OpenHandle(this)->is_external();
 }
 
 
+bool v8::ArrayBuffer::IsNeuterable() const {
+  return Utils::OpenHandle(this)->is_neuterable();
+}
+
+
 v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
   i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
   Utils::ApiCheck(!obj->is_external(),
@@ -5995,6 +6067,8 @@
   Utils::ApiCheck(obj->is_external(),
                   "v8::ArrayBuffer::Neuter",
                   "Only externalized ArrayBuffers can be neutered");
+  Utils::ApiCheck(obj->is_neuterable(), "v8::ArrayBuffer::Neuter",
+                  "Only neuterable ArrayBuffers can be neutered");
   LOG_API(obj->GetIsolate(), "v8::ArrayBuffer::Neuter()");
   ENTER_V8(isolate);
   i::Runtime::NeuterArrayBuffer(obj);
@@ -6063,78 +6137,22 @@
 }
 
 
-static inline void SetupArrayBufferView(
-    i::Isolate* isolate,
-    i::Handle<i::JSArrayBufferView> obj,
-    i::Handle<i::JSArrayBuffer> buffer,
-    size_t byte_offset,
-    size_t byte_length) {
-  DCHECK(byte_offset + byte_length <=
-         static_cast<size_t>(buffer->byte_length()->Number()));
-
-  obj->set_buffer(*buffer);
-
-  obj->set_weak_next(buffer->weak_first_view());
-  buffer->set_weak_first_view(*obj);
-
-  i::Handle<i::Object> byte_offset_object =
-      isolate->factory()->NewNumberFromSize(byte_offset);
-  obj->set_byte_offset(*byte_offset_object);
-
-  i::Handle<i::Object> byte_length_object =
-      isolate->factory()->NewNumberFromSize(byte_length);
-  obj->set_byte_length(*byte_length_object);
-}
-
-template<typename ElementType,
-         ExternalArrayType array_type,
-         i::ElementsKind elements_kind>
-i::Handle<i::JSTypedArray> NewTypedArray(
-    i::Isolate* isolate,
-    Handle<ArrayBuffer> array_buffer, size_t byte_offset, size_t length) {
-  i::Handle<i::JSTypedArray> obj =
-      isolate->factory()->NewJSTypedArray(array_type);
-  i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
-
-  DCHECK(byte_offset % sizeof(ElementType) == 0);
-
-  CHECK(length <= (std::numeric_limits<size_t>::max() / sizeof(ElementType)));
-  CHECK(length <= static_cast<size_t>(i::Smi::kMaxValue));
-  size_t byte_length = length * sizeof(ElementType);
-  SetupArrayBufferView(
-      isolate, obj, buffer, byte_offset, byte_length);
-
-  i::Handle<i::Object> length_object =
-      isolate->factory()->NewNumberFromSize(length);
-  obj->set_length(*length_object);
-
-  i::Handle<i::ExternalArray> elements =
-      isolate->factory()->NewExternalArray(
-          static_cast<int>(length), array_type,
-          static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
-  i::Handle<i::Map> map =
-      i::JSObject::GetElementsTransitionMap(obj, elements_kind);
-  i::JSObject::SetMapAndElements(obj, map, elements);
-  return obj;
-}
-
-
 #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size)                       \
   Local<Type##Array> Type##Array::New(Handle<ArrayBuffer> array_buffer,      \
-                                    size_t byte_offset, size_t length) {     \
+                                      size_t byte_offset, size_t length) {   \
     i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate();    \
     LOG_API(isolate,                                                         \
-        "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)");     \
+            "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
     ENTER_V8(isolate);                                                       \
     if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue),   \
-            "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)",  \
-            "length exceeds max allowed value")) {                           \
-      return Local<Type##Array>();                                          \
+                         "v8::" #Type                                        \
+                         "Array::New(Handle<ArrayBuffer>, size_t, size_t)",  \
+                         "length exceeds max allowed value")) {              \
+      return Local<Type##Array>();                                           \
     }                                                                        \
-    i::Handle<i::JSTypedArray> obj =                                         \
-        NewTypedArray<ctype, v8::kExternal##Type##Array,                     \
-                      i::EXTERNAL_##TYPE##_ELEMENTS>(                        \
-            isolate, array_buffer, byte_offset, length);                     \
+    i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);   \
+    i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray(    \
+        v8::kExternal##Type##Array, buffer, byte_offset, length);            \
     return Utils::ToLocal##Type##Array(obj);                                 \
   }
 
@@ -6148,9 +6166,8 @@
   i::Isolate* isolate = buffer->GetIsolate();
   LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
   ENTER_V8(isolate);
-  i::Handle<i::JSDataView> obj = isolate->factory()->NewJSDataView();
-  SetupArrayBufferView(
-      isolate, obj, buffer, byte_offset, byte_length);
+  i::Handle<i::JSDataView> obj =
+      isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
   return Utils::ToLocal(obj);
 }
 
@@ -6200,22 +6217,21 @@
 }
 
 
-static Local<Symbol> GetWellKnownSymbol(Isolate* isolate, const char* name) {
-  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  i::Handle<i::String> i_name =
-      Utils::OpenHandle(*String::NewFromUtf8(isolate, name));
-  i::Handle<i::String> part = i_isolate->factory()->for_intern_string();
-  return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
-}
-
-
 Local<Symbol> v8::Symbol::GetIterator(Isolate* isolate) {
-  return GetWellKnownSymbol(isolate, "Symbol.iterator");
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  return Utils::ToLocal(i_isolate->factory()->iterator_symbol());
 }
 
 
 Local<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) {
-  return GetWellKnownSymbol(isolate, "Symbol.unscopables");
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  return Utils::ToLocal(i_isolate->factory()->unscopables_symbol());
+}
+
+
+Local<Symbol> v8::Symbol::GetToStringTag(Isolate* isolate) {
+  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+  return Utils::ToLocal(i_isolate->factory()->to_string_tag_symbol());
 }
 
 
@@ -6253,7 +6269,6 @@
 
 Local<Number> v8::Number::New(Isolate* isolate, double value) {
   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  DCHECK(internal_isolate->IsInitialized());
   if (std::isnan(value)) {
     // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
     value = base::OS::nan_value();
@@ -6266,7 +6281,6 @@
 
 Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  DCHECK(internal_isolate->IsInitialized());
   if (i::Smi::IsValid(value)) {
     return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
                                                       internal_isolate));
@@ -6279,7 +6293,6 @@
 
 Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
   i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  DCHECK(internal_isolate->IsInitialized());
   bool fits_into_int32_t = (value & (1 << 31)) == 0;
   if (fits_into_int32_t) {
     return Integer::New(isolate, static_cast<int32_t>(value));
@@ -6290,57 +6303,6 @@
 }
 
 
-bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
-  i::Isolate* isolate = i::Isolate::Current();
-  ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
-  ENTER_V8(isolate);
-  i::HandleScope scope(isolate);
-  NeanderArray listeners(isolate->factory()->message_listeners());
-  NeanderObject obj(isolate, 2);
-  obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
-  obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
-          : *Utils::OpenHandle(*data));
-  listeners.add(obj.value());
-  return true;
-}
-
-
-void V8::RemoveMessageListeners(MessageCallback that) {
-  i::Isolate* isolate = i::Isolate::Current();
-  ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
-  ENTER_V8(isolate);
-  i::HandleScope scope(isolate);
-  NeanderArray listeners(isolate->factory()->message_listeners());
-  for (int i = 0; i < listeners.length(); i++) {
-    if (listeners.get(i)->IsUndefined()) continue;  // skip deleted ones
-
-    NeanderObject listener(i::JSObject::cast(listeners.get(i)));
-    i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
-    if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
-      listeners.set(i, isolate->heap()->undefined_value());
-    }
-  }
-}
-
-
-void V8::SetCaptureStackTraceForUncaughtExceptions(
-    bool capture,
-    int frame_limit,
-    StackTrace::StackTraceOptions options) {
-  i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
-      capture,
-      frame_limit,
-      options);
-}
-
-
-void V8::SetFailedAccessCheckCallbackFunction(
-    FailedAccessCheckCallback callback) {
-  i::Isolate* isolate = i::Isolate::Current();
-  isolate->SetFailedAccessCheckCallback(callback);
-}
-
-
 void Isolate::CollectAllGarbage(const char* gc_reason) {
   reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
       i::Heap::kNoGCFlags, gc_reason);
@@ -6470,13 +6432,6 @@
 }
 
 
-void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
-  i::Isolate* isolate = i::Isolate::Current();
-  isolate->heap()->RemoveGCPrologueCallback(
-      reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback));
-}
-
-
 void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
   i::Isolate* isolate = i::Isolate::Current();
   isolate->heap()->AddGCEpilogueCallback(
@@ -6486,62 +6441,49 @@
 }
 
 
-void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
-  i::Isolate* isolate = i::Isolate::Current();
-  isolate->heap()->RemoveGCEpilogueCallback(
-      reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback));
-}
-
-
-void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
-                                     ObjectSpace space,
-                                     AllocationAction action) {
-  i::Isolate* isolate = i::Isolate::Current();
+void Isolate::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
+                                          ObjectSpace space,
+                                          AllocationAction action) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
   isolate->memory_allocator()->AddMemoryAllocationCallback(
       callback, space, action);
 }
 
 
-void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
-  i::Isolate* isolate = i::Isolate::Current();
+void Isolate::RemoveMemoryAllocationCallback(
+    MemoryAllocationCallback callback) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
   isolate->memory_allocator()->RemoveMemoryAllocationCallback(
       callback);
 }
 
 
-void V8::TerminateExecution(Isolate* isolate) {
-  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  i_isolate->stack_guard()->RequestTerminateExecution();
+void Isolate::TerminateExecution() {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  isolate->stack_guard()->RequestTerminateExecution();
 }
 
 
-bool V8::IsExecutionTerminating(Isolate* isolate) {
-  i::Isolate* i_isolate = isolate != NULL ?
-      reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
-  return IsExecutionTerminatingCheck(i_isolate);
+bool Isolate::IsExecutionTerminating() {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  return IsExecutionTerminatingCheck(isolate);
 }
 
 
-void V8::CancelTerminateExecution(Isolate* isolate) {
-  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
-  i_isolate->stack_guard()->ClearTerminateExecution();
-  i_isolate->CancelTerminateExecution();
+void Isolate::CancelTerminateExecution() {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  isolate->stack_guard()->ClearTerminateExecution();
+  isolate->CancelTerminateExecution();
 }
 
 
 void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
-  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
-  i_isolate->set_api_interrupt_callback(callback);
-  i_isolate->set_api_interrupt_callback_data(data);
-  i_isolate->stack_guard()->RequestApiInterrupt();
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  isolate->RequestInterrupt(callback, data);
 }
 
 
 void Isolate::ClearInterrupt() {
-  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
-  i_isolate->stack_guard()->ClearApiInterrupt();
-  i_isolate->set_api_interrupt_callback(NULL);
-  i_isolate->set_api_interrupt_callback_data(NULL);
 }
 
 
@@ -6567,7 +6509,7 @@
 
 
 Isolate* Isolate::New(const Isolate::CreateParams& params) {
-  i::Isolate* isolate = new i::Isolate();
+  i::Isolate* isolate = new i::Isolate(params.enable_serializer);
   Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
   if (params.entry_hook) {
     isolate->set_function_entry_hook(params.entry_hook);
@@ -6578,9 +6520,6 @@
                                            params.code_event_handler);
   }
   SetResourceConstraints(isolate, params.constraints);
-  if (params.enable_serializer) {
-    isolate->enable_serializer();
-  }
   // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
   Isolate::Scope isolate_scope(v8_isolate);
   if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
@@ -6670,14 +6609,6 @@
 
 void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
-  if (!isolate->IsInitialized()) {
-    heap_statistics->total_heap_size_ = 0;
-    heap_statistics->total_heap_size_executable_ = 0;
-    heap_statistics->total_physical_size_ = 0;
-    heap_statistics->used_heap_size_ = 0;
-    heap_statistics->heap_size_limit_ = 0;
-    return;
-  }
   i::Heap* heap = isolate->heap();
   heap_statistics->total_heap_size_ = heap->CommittedMemory();
   heap_statistics->total_heap_size_executable_ =
@@ -6688,9 +6619,17 @@
 }
 
 
+void Isolate::GetStackSample(const RegisterState& state, void** frames,
+                             size_t frames_limit, SampleInfo* sample_info) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  i::TickSample::GetStackSample(isolate, state, i::TickSample::kSkipCEntryFrame,
+                                frames, frames_limit, sample_info);
+}
+
+
 void Isolate::SetEventLogger(LogEventCallback that) {
   // Do not overwrite the event logger if we want to log explicitly.
-  if (i::FLAG_log_timer_events) return;
+  if (i::FLAG_log_internal_timer_events) return;
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
   isolate->set_event_logger(that);
 }
@@ -6709,6 +6648,13 @@
 }
 
 
+void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
+  if (callback == NULL) return;
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  isolate->SetPromiseRejectCallback(callback);
+}
+
+
 void Isolate::RunMicrotasks() {
   reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
 }
@@ -6771,7 +6717,7 @@
 }
 
 
-bool v8::Isolate::IdleNotification(int idle_time_in_ms) {
+bool Isolate::IdleNotification(int idle_time_in_ms) {
   // Returning true tells the caller that it need not
   // continue to call IdleNotification.
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
@@ -6780,7 +6726,16 @@
 }
 
 
-void v8::Isolate::LowMemoryNotification() {
+bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
+  // Returning true tells the caller that it need not
+  // continue to call IdleNotification.
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  if (!i::FLAG_use_idle_notification) return true;
+  return isolate->heap()->IdleNotification(deadline_in_seconds);
+}
+
+
+void Isolate::LowMemoryNotification() {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
   {
     i::HistogramTimerScope idle_notification_scope(
@@ -6790,14 +6745,14 @@
 }
 
 
-int v8::Isolate::ContextDisposedNotification() {
+int Isolate::ContextDisposedNotification(bool dependant_context) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
-  return isolate->heap()->NotifyContextDisposed();
+  return isolate->heap()->NotifyContextDisposed(dependant_context);
 }
 
 
-void v8::Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
-                                         JitCodeEventHandler event_handler) {
+void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
+                                     JitCodeEventHandler event_handler) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
   // Ensure that logging is initialized for our isolate.
   isolate->InitializeLoggingAndCounters();
@@ -6805,13 +6760,134 @@
 }
 
 
-void v8::Isolate::SetStackLimit(uintptr_t stack_limit) {
+void Isolate::SetStackLimit(uintptr_t stack_limit) {
   i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
   CHECK(stack_limit);
   isolate->stack_guard()->SetStackLimit(stack_limit);
 }
 
 
+void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  if (isolate->code_range()->valid()) {
+    *start = isolate->code_range()->start();
+    *length_in_bytes = isolate->code_range()->size();
+  } else {
+    *start = NULL;
+    *length_in_bytes = 0;
+  }
+}
+
+
+void Isolate::SetFatalErrorHandler(FatalErrorCallback that) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  isolate->set_exception_behavior(that);
+}
+
+
+void Isolate::SetAllowCodeGenerationFromStringsCallback(
+    AllowCodeGenerationFromStringsCallback callback) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  isolate->set_allow_code_gen_callback(callback);
+}
+
+
+bool Isolate::IsDead() {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  return isolate->IsDead();
+}
+
+
+bool Isolate::AddMessageListener(MessageCallback that, Handle<Value> data) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
+  NeanderArray listeners(isolate->factory()->message_listeners());
+  NeanderObject obj(isolate, 2);
+  obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
+  obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
+                            : *Utils::OpenHandle(*data));
+  listeners.add(isolate, obj.value());
+  return true;
+}
+
+
+void Isolate::RemoveMessageListeners(MessageCallback that) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
+  NeanderArray listeners(isolate->factory()->message_listeners());
+  for (int i = 0; i < listeners.length(); i++) {
+    if (listeners.get(i)->IsUndefined()) continue;  // skip deleted ones
+
+    NeanderObject listener(i::JSObject::cast(listeners.get(i)));
+    i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
+    if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
+      listeners.set(i, isolate->heap()->undefined_value());
+    }
+  }
+}
+
+
+void Isolate::SetFailedAccessCheckCallbackFunction(
+    FailedAccessCheckCallback callback) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  isolate->SetFailedAccessCheckCallback(callback);
+}
+
+
+void Isolate::SetCaptureStackTraceForUncaughtExceptions(
+    bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
+                                                     options);
+}
+
+
+void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  isolate->heap()->VisitExternalResources(visitor);
+}
+
+
+class VisitorAdapter : public i::ObjectVisitor {
+ public:
+  explicit VisitorAdapter(PersistentHandleVisitor* visitor)
+      : visitor_(visitor) {}
+  virtual void VisitPointers(i::Object** start, i::Object** end) {
+    UNREACHABLE();
+  }
+  virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
+    Value* value = ToApi<Value>(i::Handle<i::Object>(p));
+    visitor_->VisitPersistentHandle(
+        reinterpret_cast<Persistent<Value>*>(&value), class_id);
+  }
+
+ private:
+  PersistentHandleVisitor* visitor_;
+};
+
+
+void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  i::DisallowHeapAllocation no_allocation;
+  VisitorAdapter visitor_adapter(visitor);
+  isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
+}
+
+
+void Isolate::VisitHandlesForPartialDependence(
+    PersistentHandleVisitor* visitor) {
+  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+  i::DisallowHeapAllocation no_allocation;
+  VisitorAdapter visitor_adapter(visitor);
+  isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
+      &visitor_adapter);
+}
+
+
 String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
     : str_(NULL), length_(0) {
   i::Isolate* isolate = i::Isolate::Current();
@@ -6819,7 +6895,7 @@
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   TryCatch try_catch;
-  Handle<String> str = obj->ToString();
+  Handle<String> str = obj->ToString(reinterpret_cast<v8::Isolate*>(isolate));
   if (str.IsEmpty()) return;
   i::Handle<i::String> i_str = Utils::OpenHandle(*str);
   length_ = v8::Utf8Length(*i_str, isolate);
@@ -6840,7 +6916,7 @@
   ENTER_V8(isolate);
   i::HandleScope scope(isolate);
   TryCatch try_catch;
-  Handle<String> str = obj->ToString();
+  Handle<String> str = obj->ToString(reinterpret_cast<v8::Isolate*>(isolate));
   if (str.IsEmpty()) return;
   length_ = str->Length();
   str_ = i::NewArray<uint16_t>(length_ + 1);
@@ -6886,6 +6962,27 @@
 #undef DEFINE_ERROR
 
 
+Local<Message> Exception::CreateMessage(Handle<Value> exception) {
+  i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
+  if (!obj->IsHeapObject()) return Local<Message>();
+  i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
+  ENTER_V8(isolate);
+  i::HandleScope scope(isolate);
+  return Utils::MessageToLocal(
+      scope.CloseAndEscape(isolate->CreateMessage(obj, NULL)));
+}
+
+
+Local<StackTrace> Exception::GetStackTrace(Handle<Value> exception) {
+  i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
+  if (!obj->IsJSObject()) return Local<StackTrace>();
+  i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
+  i::Isolate* isolate = js_obj->GetIsolate();
+  ENTER_V8(isolate);
+  return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
+}
+
+
 // --- D e b u g   S u p p o r t ---
 
 bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
@@ -6946,7 +7043,6 @@
 Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
                          v8::Handle<v8::Value> data) {
   i::Isolate* isolate = i::Isolate::Current();
-  if (!isolate->IsInitialized()) return Local<Value>();
   ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
   ENTER_V8(isolate);
   i::MaybeHandle<i::Object> maybe_result;
@@ -6967,7 +7063,6 @@
 
 Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
   i::Isolate* isolate = i::Isolate::Current();
-  if (!isolate->IsInitialized()) return Local<Value>();
   ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
   ENTER_V8(isolate);
   v8::EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
@@ -7056,6 +7151,19 @@
 }
 
 
+unsigned int CpuProfileNode::GetHitLineCount() const {
+  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
+  return node->GetHitLineCount();
+}
+
+
+bool CpuProfileNode::GetLineTicks(LineTick* entries,
+                                  unsigned int length) const {
+  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
+  return node->GetLineTicks(entries, length);
+}
+
+
 const char* CpuProfileNode::GetBailoutReason() const {
   const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
   return node->entry()->bailout_reason();
@@ -7173,13 +7281,13 @@
 
 void CpuProfiler::SetIdle(bool is_idle) {
   i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
-  i::StateTag state = isolate->current_vm_state();
-  DCHECK(state == i::EXTERNAL || state == i::IDLE);
+  v8::StateTag state = isolate->current_vm_state();
+  DCHECK(state == v8::EXTERNAL || state == v8::IDLE);
   if (isolate->js_entry_sp() != NULL) return;
   if (is_idle) {
-    isolate->set_current_vm_state(i::IDLE);
-  } else if (state == i::IDLE) {
-    isolate->set_current_vm_state(i::EXTERNAL);
+    isolate->set_current_vm_state(v8::IDLE);
+  } else if (state == v8::IDLE) {
+    isolate->set_current_vm_state(v8::EXTERNAL);
   }
 }
 
diff --git a/src/api.h b/src/api.h
index 9aed5dd..1d2a8c8 100644
--- a/src/api.h
+++ b/src/api.h
@@ -54,7 +54,8 @@
     return obj_.value();
   }
 
-  void add(v8::internal::Handle<v8::internal::Object> value);
+  void add(internal::Isolate* isolate,
+           v8::internal::Handle<v8::internal::Object> value);
 
   int length();
 
@@ -232,6 +233,8 @@
 
   static inline Local<Message> MessageToLocal(
       v8::internal::Handle<v8::internal::Object> obj);
+  static inline Local<Promise> PromiseToLocal(
+      v8::internal::Handle<v8::internal::JSObject> obj);
   static inline Local<StackTrace> StackTraceToLocal(
       v8::internal::Handle<v8::internal::JSArray> obj);
   static inline Local<StackFrame> StackFrameToLocal(
@@ -355,6 +358,7 @@
 MAKE_TO_LOCAL(AccessorSignatureToLocal, FunctionTemplateInfo, AccessorSignature)
 MAKE_TO_LOCAL(ToLocal, TypeSwitchInfo, TypeSwitch)
 MAKE_TO_LOCAL(MessageToLocal, Object, Message)
+MAKE_TO_LOCAL(PromiseToLocal, JSObject, Promise)
 MAKE_TO_LOCAL(StackTraceToLocal, JSArray, StackTrace)
 MAKE_TO_LOCAL(StackFrameToLocal, JSObject, StackFrame)
 MAKE_TO_LOCAL(NumberToLocal, Object, Number)
diff --git a/src/arguments.h b/src/arguments.h
index 9fb2da3..e6c6db5 100644
--- a/src/arguments.h
+++ b/src/arguments.h
@@ -67,39 +67,24 @@
 // For each type of callback, we have a list of arguments
 // They are used to generate the Call() functions below
 // These aren't included in the list as they have duplicate signatures
-// F(NamedPropertyEnumeratorCallback, ...)
+// F(GenericNamedPropertyEnumeratorCallback, ...)
+// F(GenericNamedPropertyGetterCallback, ...)
 
 #define FOR_EACH_CALLBACK_TABLE_MAPPING_0(F) \
-  F(IndexedPropertyEnumeratorCallback, v8::Array) \
+  F(IndexedPropertyEnumeratorCallback, v8::Array)
 
-#define FOR_EACH_CALLBACK_TABLE_MAPPING_1(F) \
-  F(NamedPropertyGetterCallback, v8::Value, v8::Local<v8::String>) \
-  F(AccessorNameGetterCallback, v8::Value, v8::Local<v8::Name>) \
-  F(NamedPropertyQueryCallback, \
-    v8::Integer, \
-    v8::Local<v8::String>) \
-  F(NamedPropertyDeleterCallback, \
-    v8::Boolean, \
-    v8::Local<v8::String>) \
-  F(IndexedPropertyGetterCallback, \
-    v8::Value, \
-    uint32_t) \
-  F(IndexedPropertyQueryCallback, \
-    v8::Integer, \
-    uint32_t) \
-  F(IndexedPropertyDeleterCallback, \
-    v8::Boolean, \
-    uint32_t) \
+#define FOR_EACH_CALLBACK_TABLE_MAPPING_1(F)                               \
+  F(AccessorNameGetterCallback, v8::Value, v8::Local<v8::Name>)            \
+  F(GenericNamedPropertyQueryCallback, v8::Integer, v8::Local<v8::Name>)   \
+  F(GenericNamedPropertyDeleterCallback, v8::Boolean, v8::Local<v8::Name>) \
+  F(IndexedPropertyGetterCallback, v8::Value, uint32_t)                    \
+  F(IndexedPropertyQueryCallback, v8::Integer, uint32_t)                   \
+  F(IndexedPropertyDeleterCallback, v8::Boolean, uint32_t)
 
-#define FOR_EACH_CALLBACK_TABLE_MAPPING_2(F) \
-  F(NamedPropertySetterCallback, \
-    v8::Value, \
-    v8::Local<v8::String>, \
-    v8::Local<v8::Value>) \
-  F(IndexedPropertySetterCallback, \
-    v8::Value, \
-    uint32_t, \
-    v8::Local<v8::Value>) \
+#define FOR_EACH_CALLBACK_TABLE_MAPPING_2(F)                            \
+  F(GenericNamedPropertySetterCallback, v8::Value, v8::Local<v8::Name>, \
+    v8::Local<v8::Value>)                                               \
+  F(IndexedPropertySetterCallback, v8::Value, uint32_t, v8::Local<v8::Value>)
 
 #define FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(F) \
   F(AccessorNameSetterCallback, \
diff --git a/src/arm/assembler-arm-inl.h b/src/arm/assembler-arm-inl.h
index 8b5c4b8..876cd3d 100644
--- a/src/arm/assembler-arm-inl.h
+++ b/src/arm/assembler-arm-inl.h
@@ -70,6 +70,12 @@
 }
 
 
+// static
+int DwVfpRegister::NumAllocatableAliasedRegisters() {
+  return LowDwVfpRegister::kMaxNumLowRegisters - kNumReservedRegisters;
+}
+
+
 int DwVfpRegister::ToAllocationIndex(DwVfpRegister reg) {
   DCHECK(!reg.is(kDoubleRegZero));
   DCHECK(!reg.is(kScratchDoubleReg));
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index 96f28f9..105d711 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -109,6 +109,9 @@
 
   if (cpu.architecture() >= 7) {
     if (FLAG_enable_armv7) supported_ |= 1u << ARMv7;
+    if (FLAG_enable_armv8 && cpu.architecture() >= 8) {
+      supported_ |= 1u << ARMv8;
+    }
     if (FLAG_enable_unaligned_accesses) supported_ |= 1u << UNALIGNED_ACCESSES;
     // Use movw/movt for QUALCOMM ARMv7 cores.
     if (FLAG_enable_movw_movt && cpu.implementer() == base::CPU::QUALCOMM) {
@@ -124,6 +127,11 @@
   }
 
   if (FLAG_enable_32dregs && cpu.has_vfp3_d32()) supported_ |= 1u << VFP32DREGS;
+
+  if (cpu.implementer() == base::CPU::NVIDIA &&
+      cpu.variant() == base::CPU::NVIDIA_DENVER) {
+    supported_ |= 1u << COHERENT_CACHE;
+  }
 #endif
 
   DCHECK(!IsSupported(VFP3) || IsSupported(ARMv7));
@@ -185,14 +193,15 @@
 void CpuFeatures::PrintFeatures() {
   printf(
     "ARMv7=%d VFP3=%d VFP32DREGS=%d NEON=%d SUDIV=%d UNALIGNED_ACCESSES=%d "
-    "MOVW_MOVT_IMMEDIATE_LOADS=%d",
+    "MOVW_MOVT_IMMEDIATE_LOADS=%d COHERENT_CACHE=%d",
     CpuFeatures::IsSupported(ARMv7),
     CpuFeatures::IsSupported(VFP3),
     CpuFeatures::IsSupported(VFP32DREGS),
     CpuFeatures::IsSupported(NEON),
     CpuFeatures::IsSupported(SUDIV),
     CpuFeatures::IsSupported(UNALIGNED_ACCESSES),
-    CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS));
+    CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS),
+    CpuFeatures::IsSupported(COHERENT_CACHE));
 #ifdef __arm__
   bool eabi_hardfloat = base::OS::ArmUsingHardFloat();
 #elif USE_EABI_HARDFLOAT
@@ -472,7 +481,6 @@
   first_const_pool_32_use_ = -1;
   first_const_pool_64_use_ = -1;
   last_bound_pos_ = 0;
-  constant_pool_available_ = !FLAG_enable_ool_constant_pool;
   ClearRecordedAstId();
 }
 
@@ -1056,7 +1064,8 @@
 
 static bool use_mov_immediate_load(const Operand& x,
                                    const Assembler* assembler) {
-  if (assembler != NULL && !assembler->is_constant_pool_available()) {
+  if (FLAG_enable_ool_constant_pool && assembler != NULL &&
+      !assembler->is_ool_constant_pool_available()) {
     return true;
   } else if (CpuFeatures::IsSupported(MOVW_MOVT_IMMEDIATE_LOADS) &&
              (assembler == NULL || !assembler->predictable_code_size())) {
@@ -1137,7 +1146,7 @@
       mov(rd, target, LeaveCC, cond);
     }
   } else {
-    DCHECK(is_constant_pool_available());
+    DCHECK(!FLAG_enable_ool_constant_pool || is_ool_constant_pool_available());
     ConstantPoolArray::LayoutSection section = ConstantPoolAddEntry(rinfo);
     if (section == ConstantPoolArray::EXTENDED_SECTION) {
       DCHECK(FLAG_enable_ool_constant_pool);
@@ -1335,7 +1344,7 @@
 void Assembler::b(int branch_offset, Condition cond) {
   DCHECK((branch_offset & 3) == 0);
   int imm24 = branch_offset >> 2;
-  DCHECK(is_int24(imm24));
+  CHECK(is_int24(imm24));
   emit(cond | B27 | B25 | (imm24 & kImm24Mask));
 
   if (cond == al) {
@@ -1349,7 +1358,7 @@
   positions_recorder()->WriteRecordedPositions();
   DCHECK((branch_offset & 3) == 0);
   int imm24 = branch_offset >> 2;
-  DCHECK(is_int24(imm24));
+  CHECK(is_int24(imm24));
   emit(cond | B27 | B25 | B24 | (imm24 & kImm24Mask));
 }
 
@@ -1359,7 +1368,7 @@
   DCHECK((branch_offset & 1) == 0);
   int h = ((branch_offset & 2) >> 1)*B24;
   int imm24 = branch_offset >> 2;
-  DCHECK(is_int24(imm24));
+  CHECK(is_int24(imm24));
   emit(kSpecialCondition | B27 | B25 | h | (imm24 & kImm24Mask));
 }
 
@@ -1501,7 +1510,7 @@
     //
     // When the label gets bound: target_at extracts the link and target_at_put
     // patches the instructions.
-    DCHECK(is_uint24(link));
+    CHECK(is_uint24(link));
     BlockConstPoolScope block_const_pool(this);
     emit(link);
     nop(dst.code());
@@ -1571,11 +1580,27 @@
 }
 
 
-void Assembler::mul(Register dst, Register src1, Register src2,
-                    SBit s, Condition cond) {
+void Assembler::mul(Register dst, Register src1, Register src2, SBit s,
+                    Condition cond) {
   DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
   // dst goes in bits 16-19 for this instruction!
-  emit(cond | s | dst.code()*B16 | src2.code()*B8 | B7 | B4 | src1.code());
+  emit(cond | s | dst.code() * B16 | src2.code() * B8 | B7 | B4 | src1.code());
+}
+
+
+void Assembler::smmla(Register dst, Register src1, Register src2, Register srcA,
+                      Condition cond) {
+  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc) && !srcA.is(pc));
+  emit(cond | B26 | B25 | B24 | B22 | B20 | dst.code() * B16 |
+       srcA.code() * B12 | src2.code() * B8 | B4 | src1.code());
+}
+
+
+void Assembler::smmul(Register dst, Register src1, Register src2,
+                      Condition cond) {
+  DCHECK(!dst.is(pc) && !src1.is(pc) && !src2.is(pc));
+  emit(cond | B26 | B25 | B24 | B22 | B20 | dst.code() * B16 | 0xf * B12 |
+       src2.code() * B8 | B4 | src1.code());
 }
 
 
@@ -1779,71 +1804,119 @@
 }
 
 
-void Assembler::uxtb(Register dst,
-                     const Operand& src,
-                     Condition cond) {
+void Assembler::sxtb(Register dst, Register src, int rotate, Condition cond) {
+  // Instruction details available in ARM DDI 0406C.b, A8.8.233.
+  // cond(31-28) | 01101010(27-20) | 1111(19-16) |
+  // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
+  DCHECK(!dst.is(pc));
+  DCHECK(!src.is(pc));
+  DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
+  emit(cond | 0x6A * B20 | 0xF * B16 | dst.code() * B12 |
+       ((rotate >> 1) & 0xC) * B8 | 7 * B4 | src.code());
+}
+
+
+void Assembler::sxtab(Register dst, Register src1, Register src2, int rotate,
+                      Condition cond) {
+  // Instruction details available in ARM DDI 0406C.b, A8.8.233.
+  // cond(31-28) | 01101010(27-20) | Rn(19-16) |
+  // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
+  DCHECK(!dst.is(pc));
+  DCHECK(!src1.is(pc));
+  DCHECK(!src2.is(pc));
+  DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
+  emit(cond | 0x6A * B20 | src1.code() * B16 | dst.code() * B12 |
+       ((rotate >> 1) & 0xC) * B8 | 7 * B4 | src2.code());
+}
+
+
+void Assembler::sxth(Register dst, Register src, int rotate, Condition cond) {
+  // Instruction details available in ARM DDI 0406C.b, A8.8.235.
+  // cond(31-28) | 01101011(27-20) | 1111(19-16) |
+  // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
+  DCHECK(!dst.is(pc));
+  DCHECK(!src.is(pc));
+  DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
+  emit(cond | 0x6B * B20 | 0xF * B16 | dst.code() * B12 |
+       ((rotate >> 1) & 0xC) * B8 | 7 * B4 | src.code());
+}
+
+
+void Assembler::sxtah(Register dst, Register src1, Register src2, int rotate,
+                      Condition cond) {
+  // Instruction details available in ARM DDI 0406C.b, A8.8.235.
+  // cond(31-28) | 01101011(27-20) | Rn(19-16) |
+  // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
+  DCHECK(!dst.is(pc));
+  DCHECK(!src1.is(pc));
+  DCHECK(!src2.is(pc));
+  DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
+  emit(cond | 0x6B * B20 | src1.code() * B16 | dst.code() * B12 |
+       ((rotate >> 1) & 0xC) * B8 | 7 * B4 | src2.code());
+}
+
+
+void Assembler::uxtb(Register dst, Register src, int rotate, Condition cond) {
   // Instruction details available in ARM DDI 0406C.b, A8.8.274.
   // cond(31-28) | 01101110(27-20) | 1111(19-16) |
   // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
   DCHECK(!dst.is(pc));
-  DCHECK(!src.rm().is(pc));
-  DCHECK(!src.rm().is(no_reg));
-  DCHECK(src.rs().is(no_reg));
-  DCHECK((src.shift_imm_ == 0) ||
-         (src.shift_imm_ == 8) ||
-         (src.shift_imm_ == 16) ||
-         (src.shift_imm_ == 24));
-  // Operand maps ROR #0 to LSL #0.
-  DCHECK((src.shift_op() == ROR) ||
-         ((src.shift_op() == LSL) && (src.shift_imm_ == 0)));
-  emit(cond | 0x6E*B20 | 0xF*B16 | dst.code()*B12 |
-       ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
+  DCHECK(!src.is(pc));
+  DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
+  emit(cond | 0x6E * B20 | 0xF * B16 | dst.code() * B12 |
+       ((rotate >> 1) & 0xC) * B8 | 7 * B4 | src.code());
 }
 
 
-void Assembler::uxtab(Register dst,
-                      Register src1,
-                      const Operand& src2,
+void Assembler::uxtab(Register dst, Register src1, Register src2, int rotate,
                       Condition cond) {
   // Instruction details available in ARM DDI 0406C.b, A8.8.271.
   // cond(31-28) | 01101110(27-20) | Rn(19-16) |
   // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
   DCHECK(!dst.is(pc));
   DCHECK(!src1.is(pc));
-  DCHECK(!src2.rm().is(pc));
-  DCHECK(!src2.rm().is(no_reg));
-  DCHECK(src2.rs().is(no_reg));
-  DCHECK((src2.shift_imm_ == 0) ||
-         (src2.shift_imm_ == 8) ||
-         (src2.shift_imm_ == 16) ||
-         (src2.shift_imm_ == 24));
-  // Operand maps ROR #0 to LSL #0.
-  DCHECK((src2.shift_op() == ROR) ||
-         ((src2.shift_op() == LSL) && (src2.shift_imm_ == 0)));
-  emit(cond | 0x6E*B20 | src1.code()*B16 | dst.code()*B12 |
-       ((src2.shift_imm_ >> 1) &0xC)*B8 | 7*B4 | src2.rm().code());
+  DCHECK(!src2.is(pc));
+  DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
+  emit(cond | 0x6E * B20 | src1.code() * B16 | dst.code() * B12 |
+       ((rotate >> 1) & 0xC) * B8 | 7 * B4 | src2.code());
 }
 
 
-void Assembler::uxtb16(Register dst,
-                       const Operand& src,
-                       Condition cond) {
+void Assembler::uxtb16(Register dst, Register src, int rotate, Condition cond) {
   // Instruction details available in ARM DDI 0406C.b, A8.8.275.
   // cond(31-28) | 01101100(27-20) | 1111(19-16) |
   // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
   DCHECK(!dst.is(pc));
-  DCHECK(!src.rm().is(pc));
-  DCHECK(!src.rm().is(no_reg));
-  DCHECK(src.rs().is(no_reg));
-  DCHECK((src.shift_imm_ == 0) ||
-         (src.shift_imm_ == 8) ||
-         (src.shift_imm_ == 16) ||
-         (src.shift_imm_ == 24));
-  // Operand maps ROR #0 to LSL #0.
-  DCHECK((src.shift_op() == ROR) ||
-         ((src.shift_op() == LSL) && (src.shift_imm_ == 0)));
-  emit(cond | 0x6C*B20 | 0xF*B16 | dst.code()*B12 |
-       ((src.shift_imm_ >> 1)&0xC)*B8 | 7*B4 | src.rm().code());
+  DCHECK(!src.is(pc));
+  DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
+  emit(cond | 0x6C * B20 | 0xF * B16 | dst.code() * B12 |
+       ((rotate >> 1) & 0xC) * B8 | 7 * B4 | src.code());
+}
+
+
+void Assembler::uxth(Register dst, Register src, int rotate, Condition cond) {
+  // Instruction details available in ARM DDI 0406C.b, A8.8.276.
+  // cond(31-28) | 01101111(27-20) | 1111(19-16) |
+  // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
+  DCHECK(!dst.is(pc));
+  DCHECK(!src.is(pc));
+  DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
+  emit(cond | 0x6F * B20 | 0xF * B16 | dst.code() * B12 |
+       ((rotate >> 1) & 0xC) * B8 | 7 * B4 | src.code());
+}
+
+
+void Assembler::uxtah(Register dst, Register src1, Register src2, int rotate,
+                      Condition cond) {
+  // Instruction details available in ARM DDI 0406C.b, A8.8.273.
+  // cond(31-28) | 01101111(27-20) | Rn(19-16) |
+  // Rd(15-12) | rotate(11-10) | 00(9-8)| 0111(7-4) | Rm(3-0)
+  DCHECK(!dst.is(pc));
+  DCHECK(!src1.is(pc));
+  DCHECK(!src2.is(pc));
+  DCHECK(rotate == 0 || rotate == 8 || rotate == 16 || rotate == 24);
+  emit(cond | 0x6F * B20 | src1.code() * B16 | dst.code() * B12 |
+       ((rotate >> 1) & 0xC) * B8 | 7 * B4 | src2.code());
 }
 
 
@@ -2418,6 +2491,12 @@
 }
 
 
+void Assembler::vmov(const SwVfpRegister dst, float imm) {
+  mov(ip, Operand(bit_cast<int32_t>(imm)));
+  vmov(dst, ip);
+}
+
+
 static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
   uint64_t i;
   memcpy(&i, &d, 8);
@@ -2492,7 +2571,7 @@
     int vd, d;
     dst.split_code(&vd, &d);
     emit(al | 0x1D*B23 | d*B22 | 0x3*B20 | vd*B12 | 0x5*B9 | B8 | enc);
-  } else if (FLAG_enable_vldr_imm && is_constant_pool_available()) {
+  } else if (FLAG_enable_vldr_imm && is_ool_constant_pool_available()) {
     // TODO(jfb) Temporarily turned off until we have constant blinding or
     //           some equivalent mitigation: an attacker can otherwise control
     //           generated data which also happens to be executable, a Very Bad
@@ -2526,27 +2605,20 @@
     uint32_t lo, hi;
     DoubleAsTwoUInt32(imm, &lo, &hi);
 
-    if (scratch.is(no_reg)) {
-      if (dst.code() < 16) {
-        const LowDwVfpRegister loc = LowDwVfpRegister::from_code(dst.code());
-        // Move the low part of the double into the lower of the corresponsing S
-        // registers of D register dst.
-        mov(ip, Operand(lo));
-        vmov(loc.low(), ip);
-
-        // Move the high part of the double into the higher of the
-        // corresponsing S registers of D register dst.
-        mov(ip, Operand(hi));
-        vmov(loc.high(), ip);
+    if (lo == hi) {
+      // Move the low and high parts of the double to a D register in one
+      // instruction.
+      mov(ip, Operand(lo));
+      vmov(dst, ip, ip);
+    } else if (scratch.is(no_reg)) {
+      mov(ip, Operand(lo));
+      vmov(dst, VmovIndexLo, ip);
+      if ((lo & 0xffff) == (hi & 0xffff)) {
+        movt(ip, hi >> 16);
       } else {
-        // D16-D31 does not have S registers, so move the low and high parts
-        // directly to the D register using vmov.32.
-        // Note: This may be slower, so we only do this when we have to.
-        mov(ip, Operand(lo));
-        vmov(dst, VmovIndexLo, ip);
         mov(ip, Operand(hi));
-        vmov(dst, VmovIndexHi, ip);
       }
+      vmov(dst, VmovIndexHi, ip);
     } else {
       // Move the low and high parts of the double to a D register in one
       // instruction.
@@ -3075,6 +3147,76 @@
 }
 
 
+void Assembler::vrinta(const DwVfpRegister dst, const DwVfpRegister src) {
+  // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) |
+  // 10(19-18) | RM=00(17-16) |  Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) |
+  // M(5) | 0(4) | Vm(3-0)
+  DCHECK(CpuFeatures::IsSupported(ARMv8));
+  int vd, d;
+  dst.split_code(&vd, &d);
+  int vm, m;
+  src.split_code(&vm, &m);
+  emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | vd * B12 |
+       0x5 * B9 | B8 | B6 | m * B5 | vm);
+}
+
+
+void Assembler::vrintn(const DwVfpRegister dst, const DwVfpRegister src) {
+  // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) |
+  // 10(19-18) | RM=01(17-16) |  Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) |
+  // M(5) | 0(4) | Vm(3-0)
+  DCHECK(CpuFeatures::IsSupported(ARMv8));
+  int vd, d;
+  dst.split_code(&vd, &d);
+  int vm, m;
+  src.split_code(&vm, &m);
+  emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x1 * B16 |
+       vd * B12 | 0x5 * B9 | B8 | B6 | m * B5 | vm);
+}
+
+
+void Assembler::vrintp(const DwVfpRegister dst, const DwVfpRegister src) {
+  // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) |
+  // 10(19-18) | RM=10(17-16) |  Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) |
+  // M(5) | 0(4) | Vm(3-0)
+  DCHECK(CpuFeatures::IsSupported(ARMv8));
+  int vd, d;
+  dst.split_code(&vd, &d);
+  int vm, m;
+  src.split_code(&vm, &m);
+  emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x2 * B16 |
+       vd * B12 | 0x5 * B9 | B8 | B6 | m * B5 | vm);
+}
+
+
+void Assembler::vrintm(const DwVfpRegister dst, const DwVfpRegister src) {
+  // cond=kSpecialCondition(31-28) | 11101(27-23)| D(22) | 11(21-20) |
+  // 10(19-18) | RM=11(17-16) |  Vd(15-12) | 101(11-9) | sz=1(8) | 01(7-6) |
+  // M(5) | 0(4) | Vm(3-0)
+  DCHECK(CpuFeatures::IsSupported(ARMv8));
+  int vd, d;
+  dst.split_code(&vd, &d);
+  int vm, m;
+  src.split_code(&vm, &m);
+  emit(kSpecialCondition | 0x1D * B23 | d * B22 | 0x3 * B20 | B19 | 0x3 * B16 |
+       vd * B12 | 0x5 * B9 | B8 | B6 | m * B5 | vm);
+}
+
+
+void Assembler::vrintz(const DwVfpRegister dst, const DwVfpRegister src,
+                       const Condition cond) {
+  // cond(31-28) | 11101(27-23)| D(22) | 11(21-20) | 011(19-17) | 0(16) |
+  // Vd(15-12) | 101(11-9) | sz=1(8) | op=1(7) | 1(6) | M(5) | 0(4) | Vm(3-0)
+  DCHECK(CpuFeatures::IsSupported(ARMv8));
+  int vd, d;
+  dst.split_code(&vd, &d);
+  int vm, m;
+  src.split_code(&vm, &m);
+  emit(cond | 0x1D * B23 | d * B22 | 0x3 * B20 | 0x3 * B17 | vd * B12 |
+       0x5 * B9 | B8 | B7 | B6 | m * B5 | vm);
+}
+
+
 // Support for NEON.
 
 void Assembler::vld1(NeonSize size,
diff --git a/src/arm/assembler-arm.h b/src/arm/assembler-arm.h
index 108d5cb..4a719e6 100644
--- a/src/arm/assembler-arm.h
+++ b/src/arm/assembler-arm.h
@@ -218,6 +218,11 @@
   inline static int NumReservedRegisters();
   inline static int NumAllocatableRegisters();
 
+  // TODO(turbofan): This is a temporary work-around required because our
+  // register allocator does not yet support the aliasing of single/double
+  // registers on ARM.
+  inline static int NumAllocatableAliasedRegisters();
+
   inline static int ToAllocationIndex(DwVfpRegister reg);
   static const char* AllocationIndexToString(int index);
   inline static DwVfpRegister FromAllocationIndex(int index);
@@ -970,6 +975,11 @@
   void mul(Register dst, Register src1, Register src2,
            SBit s = LeaveCC, Condition cond = al);
 
+  void smmla(Register dst, Register src1, Register src2, Register srcA,
+             Condition cond = al);
+
+  void smmul(Register dst, Register src1, Register src2, Condition cond = al);
+
   void smlal(Register dstL, Register dstH, Register src1, Register src2,
              SBit s = LeaveCC, Condition cond = al);
 
@@ -1024,12 +1034,20 @@
   void pkhtb(Register dst, Register src1, const Operand& src2,
              Condition cond = al);
 
-  void uxtb(Register dst, const Operand& src, Condition cond = al);
-
-  void uxtab(Register dst, Register src1, const Operand& src2,
+  void sxtb(Register dst, Register src, int rotate = 0, Condition cond = al);
+  void sxtab(Register dst, Register src1, Register src2, int rotate = 0,
+             Condition cond = al);
+  void sxth(Register dst, Register src, int rotate = 0, Condition cond = al);
+  void sxtah(Register dst, Register src1, Register src2, int rotate = 0,
              Condition cond = al);
 
-  void uxtb16(Register dst, const Operand& src, Condition cond = al);
+  void uxtb(Register dst, Register src, int rotate = 0, Condition cond = al);
+  void uxtab(Register dst, Register src1, Register src2, int rotate = 0,
+             Condition cond = al);
+  void uxtb16(Register dst, Register src, int rotate = 0, Condition cond = al);
+  void uxth(Register dst, Register src, int rotate = 0, Condition cond = al);
+  void uxtah(Register dst, Register src1, Register src2, int rotate = 0,
+             Condition cond = al);
 
   // Status register access instructions
 
@@ -1162,6 +1180,7 @@
             SwVfpRegister last,
             Condition cond = al);
 
+  void vmov(const SwVfpRegister dst, float imm);
   void vmov(const DwVfpRegister dst,
             double imm,
             const Register scratch = no_reg);
@@ -1269,6 +1288,14 @@
              const DwVfpRegister src,
              const Condition cond = al);
 
+  // ARMv8 rounding instructions.
+  void vrinta(const DwVfpRegister dst, const DwVfpRegister src);
+  void vrintn(const DwVfpRegister dst, const DwVfpRegister src);
+  void vrintm(const DwVfpRegister dst, const DwVfpRegister src);
+  void vrintp(const DwVfpRegister dst, const DwVfpRegister src);
+  void vrintz(const DwVfpRegister dst, const DwVfpRegister src,
+              const Condition cond = al);
+
   // Support for NEON.
   // All these APIs support D0 to D31 and Q0 to Q15.
 
@@ -1483,8 +1510,6 @@
   // Generate the constant pool for the generated code.
   void PopulateConstantPool(ConstantPoolArray* constant_pool);
 
-  bool is_constant_pool_available() const { return constant_pool_available_; }
-
   bool use_extended_constant_pool() const {
     return constant_pool_builder_.current_section() ==
            ConstantPoolArray::EXTENDED_SECTION;
@@ -1544,10 +1569,6 @@
            (pc_offset() < no_const_pool_before_);
   }
 
-  void set_constant_pool_available(bool available) {
-    constant_pool_available_ = available;
-  }
-
  private:
   int next_buffer_check_;  // pc offset of next buffer check
 
@@ -1610,10 +1631,6 @@
   // The bound position, before this we cannot do instruction elimination.
   int last_bound_pos_;
 
-  // Indicates whether the constant pool can be accessed, which is only possible
-  // if the pp register points to the current code object's constant pool.
-  bool constant_pool_available_;
-
   // Code emission
   inline void CheckBuffer();
   void GrowBuffer();
@@ -1649,9 +1666,6 @@
   friend class RelocInfo;
   friend class CodePatcher;
   friend class BlockConstPoolScope;
-  friend class FrameAndConstantPoolScope;
-  friend class ConstantPoolUnavailableScope;
-
   PositionsRecorder positions_recorder_;
   friend class PositionsRecorder;
   friend class EnsureSpace;
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index 9d1a72a..8ce57d5 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -10,7 +10,7 @@
 #include "src/debug.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -372,13 +372,13 @@
         MemOperand bit_field3 = FieldMemOperand(r2, Map::kBitField3Offset);
         // Check if slack tracking is enabled.
         __ ldr(r4, bit_field3);
-        __ DecodeField<Map::ConstructionCount>(r3, r4);
-        __ cmp(r3, Operand(JSFunction::kNoSlackTracking));
-        __ b(eq, &allocate);
+        __ DecodeField<Map::Counter>(r3, r4);
+        __ cmp(r3, Operand(Map::kSlackTrackingCounterEnd));
+        __ b(lt, &allocate);
         // Decrease generous allocation count.
-        __ sub(r4, r4, Operand(1 << Map::ConstructionCount::kShift));
+        __ sub(r4, r4, Operand(1 << Map::Counter::kShift));
         __ str(r4, bit_field3);
-        __ cmp(r3, Operand(JSFunction::kFinishSlackTracking));
+        __ cmp(r3, Operand(Map::kSlackTrackingCounterEnd));
         __ b(ne, &allocate);
 
         __ push(r1);
@@ -431,9 +431,9 @@
 
         // Check if slack tracking is enabled.
         __ ldr(ip, FieldMemOperand(r2, Map::kBitField3Offset));
-        __ DecodeField<Map::ConstructionCount>(ip);
-        __ cmp(ip, Operand(JSFunction::kNoSlackTracking));
-        __ b(eq, &no_inobject_slack_tracking);
+        __ DecodeField<Map::Counter>(ip);
+        __ cmp(ip, Operand(Map::kSlackTrackingCounterEnd));
+        __ b(lt, &no_inobject_slack_tracking);
 
         // Allocate object with a slack.
         __ ldr(r0, FieldMemOperand(r2, Map::kInstanceSizesOffset));
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 25270d1..ef286bb 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -15,7 +15,7 @@
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -234,61 +234,6 @@
 }
 
 
-void WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(
-    Isolate* isolate) {
-  WriteInt32ToHeapNumberStub stub1(isolate, r1, r0, r2);
-  WriteInt32ToHeapNumberStub stub2(isolate, r2, r0, r3);
-  stub1.GetCode();
-  stub2.GetCode();
-}
-
-
-// See comment for class.
-void WriteInt32ToHeapNumberStub::Generate(MacroAssembler* masm) {
-  Label max_negative_int;
-  // the_int_ has the answer which is a signed int32 but not a Smi.
-  // We test for the special value that has a different exponent.  This test
-  // has the neat side effect of setting the flags according to the sign.
-  STATIC_ASSERT(HeapNumber::kSignMask == 0x80000000u);
-  __ cmp(the_int(), Operand(0x80000000u));
-  __ b(eq, &max_negative_int);
-  // Set up the correct exponent in scratch_.  All non-Smi int32s have the same.
-  // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased).
-  uint32_t non_smi_exponent =
-      (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift;
-  __ mov(scratch(), Operand(non_smi_exponent));
-  // Set the sign bit in scratch_ if the value was negative.
-  __ orr(scratch(), scratch(), Operand(HeapNumber::kSignMask), LeaveCC, cs);
-  // Subtract from 0 if the value was negative.
-  __ rsb(the_int(), the_int(), Operand::Zero(), LeaveCC, cs);
-  // We should be masking the implict first digit of the mantissa away here,
-  // but it just ends up combining harmlessly with the last digit of the
-  // exponent that happens to be 1.  The sign bit is 0 so we shift 10 to get
-  // the most significant 1 to hit the last bit of the 12 bit sign and exponent.
-  DCHECK(((1 << HeapNumber::kExponentShift) & non_smi_exponent) != 0);
-  const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2;
-  __ orr(scratch(), scratch(), Operand(the_int(), LSR, shift_distance));
-  __ str(scratch(),
-         FieldMemOperand(the_heap_number(), HeapNumber::kExponentOffset));
-  __ mov(scratch(), Operand(the_int(), LSL, 32 - shift_distance));
-  __ str(scratch(),
-         FieldMemOperand(the_heap_number(), HeapNumber::kMantissaOffset));
-  __ Ret();
-
-  __ bind(&max_negative_int);
-  // The max negative int32 is stored as a positive number in the mantissa of
-  // a double because it uses a sign bit instead of using two's complement.
-  // The actual mantissa bits stored are all 0 because the implicit most
-  // significant 1 bit is not stored.
-  non_smi_exponent += 1 << HeapNumber::kExponentShift;
-  __ mov(ip, Operand(HeapNumber::kSignMask | non_smi_exponent));
-  __ str(ip, FieldMemOperand(the_heap_number(), HeapNumber::kExponentOffset));
-  __ mov(ip, Operand::Zero());
-  __ str(ip, FieldMemOperand(the_heap_number(), HeapNumber::kMantissaOffset));
-  __ Ret();
-}
-
-
 // Handle the case where the lhs and rhs are the same object.
 // Equality is almost reflexive (everything but NaN), so this is a test
 // for "identity and not NaN".
@@ -967,7 +912,6 @@
 
 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
   CEntryStub::GenerateAheadOfTime(isolate);
-  WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate);
   StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
   StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
   ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
@@ -1441,7 +1385,7 @@
   __ b(ne, &slow);
 
   // Null is not instance of anything.
-  __ cmp(scratch, Operand(isolate()->factory()->null_value()));
+  __ cmp(object, Operand(isolate()->factory()->null_value()));
   __ b(ne, &object_not_null);
   if (ReturnTrueFalseObject()) {
     __ Move(r0, factory->false_value());
@@ -1494,15 +1438,54 @@
 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
   Label miss;
   Register receiver = LoadDescriptor::ReceiverRegister();
+  // Ensure that the vector and slot registers won't be clobbered before
+  // calling the miss handler.
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(r4, r5, VectorLoadICDescriptor::VectorRegister(),
+                     VectorLoadICDescriptor::SlotRegister()));
 
-  NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r3,
-                                                          r4, &miss);
+  NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r4,
+                                                          r5, &miss);
   __ bind(&miss);
   PropertyAccessCompiler::TailCallBuiltin(
       masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
 }
 
 
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+  // Return address is in lr.
+  Label miss;
+
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register index = LoadDescriptor::NameRegister();
+  Register scratch = r5;
+  Register result = r0;
+  DCHECK(!scratch.is(receiver) && !scratch.is(index));
+  DCHECK(!FLAG_vector_ics ||
+         (!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
+          result.is(VectorLoadICDescriptor::SlotRegister())));
+
+  // StringCharAtGenerator doesn't use the result register until it's passed
+  // the different miss possibilities. If it did, we would have a conflict
+  // when FLAG_vector_ics is true.
+  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+                                          &miss,  // When not a string.
+                                          &miss,  // When not a number.
+                                          &miss,  // When index out of range.
+                                          STRING_INDEX_IS_ARRAY_INDEX,
+                                          RECEIVER_IS_STRING);
+  char_at_generator.GenerateFast(masm);
+  __ Ret();
+
+  StubRuntimeCallHelper call_helper;
+  char_at_generator.GenerateSlow(masm, call_helper);
+
+  __ bind(&miss);
+  PropertyAccessCompiler::TailCallBuiltin(
+      masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
+
+
 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
   // The displacement is the offset of the last parameter (if any)
   // relative to the frame pointer.
@@ -2376,13 +2359,13 @@
 
   // A monomorphic miss (i.e, here the cache is not uninitialized) goes
   // megamorphic.
-  __ CompareRoot(r4, Heap::kUninitializedSymbolRootIndex);
+  __ CompareRoot(r4, Heap::kuninitialized_symbolRootIndex);
   __ b(eq, &initialize);
   // MegamorphicSentinel is an immortal immovable object (undefined) so no
   // write-barrier is needed.
   __ bind(&megamorphic);
   __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
-  __ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex);
+  __ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex);
   __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
   __ jmp(&done);
 
@@ -2658,6 +2641,10 @@
 void CallICStub::Generate(MacroAssembler* masm) {
   // r1 - function
   // r3 - slot id (Smi)
+  const int with_types_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
+  const int generic_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
   Label extra_checks_or_miss, slow_start;
   Label slow, non_function, wrap, cont;
   Label have_js_function;
@@ -2696,26 +2683,70 @@
   }
 
   __ bind(&extra_checks_or_miss);
-  Label miss;
+  Label uninitialized, miss;
 
-  __ CompareRoot(r4, Heap::kMegamorphicSymbolRootIndex);
+  __ CompareRoot(r4, Heap::kmegamorphic_symbolRootIndex);
   __ b(eq, &slow_start);
-  __ CompareRoot(r4, Heap::kUninitializedSymbolRootIndex);
-  __ b(eq, &miss);
 
-  if (!FLAG_trace_ic) {
-    // We are going megamorphic. If the feedback is a JSFunction, it is fine
-    // to handle it here. More complex cases are dealt with in the runtime.
-    __ AssertNotSmi(r4);
-    __ CompareObjectType(r4, r5, r5, JS_FUNCTION_TYPE);
-    __ b(ne, &miss);
-    __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
-    __ LoadRoot(ip, Heap::kMegamorphicSymbolRootIndex);
-    __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
-    __ jmp(&slow_start);
+  // The following cases attempt to handle MISS cases without going to the
+  // runtime.
+  if (FLAG_trace_ic) {
+    __ jmp(&miss);
   }
 
-  // We are here because tracing is on or we are going monomorphic.
+  __ CompareRoot(r4, Heap::kuninitialized_symbolRootIndex);
+  __ b(eq, &uninitialized);
+
+  // We are going megamorphic. If the feedback is a JSFunction, it is fine
+  // to handle it here. More complex cases are dealt with in the runtime.
+  __ AssertNotSmi(r4);
+  __ CompareObjectType(r4, r5, r5, JS_FUNCTION_TYPE);
+  __ b(ne, &miss);
+  __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
+  __ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex);
+  __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
+  // We have to update statistics for runtime profiling.
+  __ ldr(r4, FieldMemOperand(r2, with_types_offset));
+  __ sub(r4, r4, Operand(Smi::FromInt(1)));
+  __ str(r4, FieldMemOperand(r2, with_types_offset));
+  __ ldr(r4, FieldMemOperand(r2, generic_offset));
+  __ add(r4, r4, Operand(Smi::FromInt(1)));
+  __ str(r4, FieldMemOperand(r2, generic_offset));
+  __ jmp(&slow_start);
+
+  __ bind(&uninitialized);
+
+  // We are going monomorphic, provided we actually have a JSFunction.
+  __ JumpIfSmi(r1, &miss);
+
+  // Goto miss case if we do not have a function.
+  __ CompareObjectType(r1, r4, r4, JS_FUNCTION_TYPE);
+  __ b(ne, &miss);
+
+  // Make sure the function is not the Array() function, which requires special
+  // behavior on MISS.
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r4);
+  __ cmp(r1, r4);
+  __ b(eq, &miss);
+
+  // Update stats.
+  __ ldr(r4, FieldMemOperand(r2, with_types_offset));
+  __ add(r4, r4, Operand(Smi::FromInt(1)));
+  __ str(r4, FieldMemOperand(r2, with_types_offset));
+
+  // Store the function.
+  __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
+  __ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ str(r1, MemOperand(r4, 0));
+
+  // Update the write barrier.
+  __ mov(r5, r1);
+  __ RecordWrite(r2, r4, r5, kLRHasNotBeenSaved, kDontSaveFPRegs,
+                 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+  __ jmp(&have_js_function);
+
+  // We are here because tracing is on or we encountered a MISS case we can't
+  // handle here.
   __ bind(&miss);
   GenerateMiss(masm);
 
@@ -2759,14 +2790,16 @@
 // StringCharCodeAtGenerator
 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
   // If the receiver is a smi trigger the non-string case.
-  __ JumpIfSmi(object_, receiver_not_string_);
+  if (check_mode_ == RECEIVER_IS_UNKNOWN) {
+    __ JumpIfSmi(object_, receiver_not_string_);
 
-  // Fetch the instance type of the receiver into result register.
-  __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
-  __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
-  // If the receiver is not a string trigger the non-string case.
-  __ tst(result_, Operand(kIsNotStringMask));
-  __ b(ne, receiver_not_string_);
+    // Fetch the instance type of the receiver into result register.
+    __ ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
+    __ ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
+    // If the receiver is not a string trigger the non-string case.
+    __ tst(result_, Operand(kIsNotStringMask));
+    __ b(ne, receiver_not_string_);
+  }
 
   // If the index is non-smi trigger the non-smi case.
   __ JumpIfNotSmi(index_, &index_not_smi_);
@@ -3137,8 +3170,8 @@
   // r2: length
   // r3: from index (untagged)
   __ SmiTag(r3, r3);
-  StringCharAtGenerator generator(
-      r0, r3, r2, r0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
+  StringCharAtGenerator generator(r0, r3, r2, r0, &runtime, &runtime, &runtime,
+                                  STRING_INDEX_IS_NUMBER, RECEIVER_IS_STRING);
   generator.GenerateFast(masm);
   __ Drop(3);
   __ Ret();
@@ -3146,6 +3179,49 @@
 }
 
 
+void ToNumberStub::Generate(MacroAssembler* masm) {
+  // The ToNumber stub takes one argument in r0.
+  Label not_smi;
+  __ JumpIfNotSmi(r0, &not_smi);
+  __ Ret();
+  __ bind(&not_smi);
+
+  Label not_heap_number;
+  __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
+  __ ldrb(r1, FieldMemOperand(r1, Map::kInstanceTypeOffset));
+  // r0: object
+  // r1: instance type.
+  __ cmp(r1, Operand(HEAP_NUMBER_TYPE));
+  __ b(ne, &not_heap_number);
+  __ Ret();
+  __ bind(&not_heap_number);
+
+  Label not_string, slow_string;
+  __ cmp(r1, Operand(FIRST_NONSTRING_TYPE));
+  __ b(hs, &not_string);
+  // Check if string has a cached array index.
+  __ ldr(r2, FieldMemOperand(r0, String::kHashFieldOffset));
+  __ tst(r2, Operand(String::kContainsCachedArrayIndexMask));
+  __ b(ne, &slow_string);
+  __ IndexFromHash(r2, r0);
+  __ Ret();
+  __ bind(&slow_string);
+  __ push(r0);  // Push argument.
+  __ TailCallRuntime(Runtime::kStringToNumber, 1, 1);
+  __ bind(&not_string);
+
+  Label not_oddball;
+  __ cmp(r1, Operand(ODDBALL_TYPE));
+  __ b(ne, &not_oddball);
+  __ ldr(r0, FieldMemOperand(r0, Oddball::kToNumberOffset));
+  __ Ret();
+  __ bind(&not_oddball);
+
+  __ push(r0);  // Push argument.
+  __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
+}
+
+
 void StringHelper::GenerateFlatOneByteStringEquals(
     MacroAssembler* masm, Register left, Register right, Register scratch1,
     Register scratch2, Register scratch3) {
diff --git a/src/arm/code-stubs-arm.h b/src/arm/code-stubs-arm.h
index 727bb1b..e1fab29 100644
--- a/src/arm/code-stubs-arm.h
+++ b/src/arm/code-stubs-arm.h
@@ -46,44 +46,6 @@
 };
 
 
-// This stub can convert a signed int32 to a heap number (double).  It does
-// not work for int32s that are in Smi range!  No GC occurs during this stub
-// so you don't have to set up the frame.
-class WriteInt32ToHeapNumberStub : public PlatformCodeStub {
- public:
-  WriteInt32ToHeapNumberStub(Isolate* isolate, Register the_int,
-                             Register the_heap_number, Register scratch)
-      : PlatformCodeStub(isolate) {
-    minor_key_ = IntRegisterBits::encode(the_int.code()) |
-                 HeapNumberRegisterBits::encode(the_heap_number.code()) |
-                 ScratchRegisterBits::encode(scratch.code());
-  }
-
-  static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
-
- private:
-  Register the_int() const {
-    return Register::from_code(IntRegisterBits::decode(minor_key_));
-  }
-
-  Register the_heap_number() const {
-    return Register::from_code(HeapNumberRegisterBits::decode(minor_key_));
-  }
-
-  Register scratch() const {
-    return Register::from_code(ScratchRegisterBits::decode(minor_key_));
-  }
-
-  // Minor key encoding in 16 bits.
-  class IntRegisterBits: public BitField<int, 0, 4> {};
-  class HeapNumberRegisterBits: public BitField<int, 4, 4> {};
-  class ScratchRegisterBits: public BitField<int, 8, 4> {};
-
-  DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
-  DEFINE_PLATFORM_CODE_STUB(WriteInt32ToHeapNumber, PlatformCodeStub);
-};
-
-
 class RecordWriteStub: public PlatformCodeStub {
  public:
   RecordWriteStub(Isolate* isolate,
@@ -112,7 +74,7 @@
     INCREMENTAL_COMPACTION
   };
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
   static void PatchBranchIntoNop(MacroAssembler* masm, int pos) {
     masm->instr_at_put(pos, (masm->instr_at(pos) & ~B27) | (B24 | B20));
@@ -235,9 +197,9 @@
     kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
   };
 
-  virtual inline Major MajorKey() const FINAL OVERRIDE { return RecordWrite; }
+  inline Major MajorKey() const FINAL { return RecordWrite; }
 
-  virtual void Generate(MacroAssembler* masm) OVERRIDE;
+  void Generate(MacroAssembler* masm) OVERRIDE;
   void GenerateIncremental(MacroAssembler* masm, Mode mode);
   void CheckNeedsToInformIncrementalMarker(
       MacroAssembler* masm,
@@ -245,7 +207,7 @@
       Mode mode);
   void InformIncrementalMarker(MacroAssembler* masm);
 
-  void Activate(Code* code) {
+  void Activate(Code* code) OVERRIDE {
     code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
   }
 
@@ -293,7 +255,7 @@
   void GenerateCall(MacroAssembler* masm, Register target);
 
  private:
-  bool NeedsImmovableCode() { return true; }
+  bool NeedsImmovableCode() OVERRIDE { return true; }
 
   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
   DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub);
@@ -325,7 +287,7 @@
                                      Register r0,
                                      Register r1);
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
  private:
   static const int kInlinedProbes = 4;
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index d050399..fd1b0ef 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -288,8 +288,8 @@
 
     __ bind(&loop);
     __ ldr(temp1, MemOperand(src, 4, PostIndex));
-    __ uxtb16(temp3, Operand(temp1, ROR, 0));
-    __ uxtb16(temp4, Operand(temp1, ROR, 8));
+    __ uxtb16(temp3, temp1);
+    __ uxtb16(temp4, temp1, 8);
     __ pkhbt(temp1, temp3, Operand(temp4, LSL, 16));
     __ str(temp1, MemOperand(dest));
     __ pkhtb(temp1, temp4, Operand(temp3, ASR, 16));
@@ -301,9 +301,9 @@
     __ mov(chars, Operand(chars, LSL, 31), SetCC);  // bit0 => ne, bit1 => cs
     __ b(&not_two, cc);
     __ ldrh(temp1, MemOperand(src, 2, PostIndex));
-    __ uxtb(temp3, Operand(temp1, ROR, 8));
+    __ uxtb(temp3, temp1, 8);
     __ mov(temp3, Operand(temp3, LSL, 16));
-    __ uxtab(temp3, temp3, Operand(temp1, ROR, 0));
+    __ uxtab(temp3, temp3, temp1);
     __ str(temp3, MemOperand(dest, 4, PostIndex));
     __ bind(&not_two);
     __ ldrb(temp1, MemOperand(src), ne);
@@ -604,8 +604,22 @@
   __ add(src_elements, elements,
          Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4));
   __ add(dst_elements, array, Operand(FixedArray::kHeaderSize));
-  __ add(array, array, Operand(kHeapObjectTag));
   __ add(dst_end, dst_elements, Operand(length, LSL, 1));
+
+  // Allocating heap numbers in the loop below can fail and cause a jump to
+  // gc_required. We can't leave a partly initialized FixedArray behind,
+  // so pessimistically fill it with holes now.
+  Label initialization_loop, initialization_loop_entry;
+  __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
+  __ b(&initialization_loop_entry);
+  __ bind(&initialization_loop);
+  __ str(scratch, MemOperand(dst_elements, kPointerSize, PostIndex));
+  __ bind(&initialization_loop_entry);
+  __ cmp(dst_elements, dst_end);
+  __ b(lt, &initialization_loop);
+
+  __ add(dst_elements, array, Operand(FixedArray::kHeaderSize));
+  __ add(array, array, Operand(kHeapObjectTag));
   __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
   // Using offsetted addresses in src_elements to fully take advantage of
   // post-indexing.
diff --git a/src/arm/constants-arm.h b/src/arm/constants-arm.h
index 375ef89..0037ce1 100644
--- a/src/arm/constants-arm.h
+++ b/src/arm/constants-arm.h
@@ -161,26 +161,26 @@
 
 // Instruction encoding bits and masks.
 enum {
-  H   = 1 << 5,   // Halfword (or byte).
-  S6  = 1 << 6,   // Signed (or unsigned).
-  L   = 1 << 20,  // Load (or store).
-  S   = 1 << 20,  // Set condition code (or leave unchanged).
-  W   = 1 << 21,  // Writeback base register (or leave unchanged).
-  A   = 1 << 21,  // Accumulate in multiply instruction (or not).
-  B   = 1 << 22,  // Unsigned byte (or word).
-  N   = 1 << 22,  // Long (or short).
-  U   = 1 << 23,  // Positive (or negative) offset/index.
-  P   = 1 << 24,  // Offset/pre-indexed addressing (or post-indexed addressing).
-  I   = 1 << 25,  // Immediate shifter operand (or not).
-
-  B4  = 1 << 4,
-  B5  = 1 << 5,
-  B6  = 1 << 6,
-  B7  = 1 << 7,
-  B8  = 1 << 8,
-  B9  = 1 << 9,
+  H = 1 << 5,   // Halfword (or byte).
+  S6 = 1 << 6,  // Signed (or unsigned).
+  L = 1 << 20,  // Load (or store).
+  S = 1 << 20,  // Set condition code (or leave unchanged).
+  W = 1 << 21,  // Writeback base register (or leave unchanged).
+  A = 1 << 21,  // Accumulate in multiply instruction (or not).
+  B = 1 << 22,  // Unsigned byte (or word).
+  N = 1 << 22,  // Long (or short).
+  U = 1 << 23,  // Positive (or negative) offset/index.
+  P = 1 << 24,  // Offset/pre-indexed addressing (or post-indexed addressing).
+  I = 1 << 25,  // Immediate shifter operand (or not).
+  B4 = 1 << 4,
+  B5 = 1 << 5,
+  B6 = 1 << 6,
+  B7 = 1 << 7,
+  B8 = 1 << 8,
+  B9 = 1 << 9,
   B12 = 1 << 12,
   B16 = 1 << 16,
+  B17 = 1 << 17,
   B18 = 1 << 18,
   B19 = 1 << 19,
   B20 = 1 << 20,
@@ -194,16 +194,16 @@
   B28 = 1 << 28,
 
   // Instruction bit masks.
-  kCondMask   = 15 << 28,
-  kALUMask    = 0x6f << 21,
-  kRdMask     = 15 << 12,  // In str instruction.
+  kCondMask = 15 << 28,
+  kALUMask = 0x6f << 21,
+  kRdMask = 15 << 12,  // In str instruction.
   kCoprocessorMask = 15 << 8,
   kOpCodeMask = 15 << 21,  // In data-processing instructions.
-  kImm24Mask  = (1 << 24) - 1,
-  kImm16Mask  = (1 << 16) - 1,
-  kImm8Mask  = (1 << 8) - 1,
-  kOff12Mask  = (1 << 12) - 1,
-  kOff8Mask  = (1 << 8) - 1
+  kImm24Mask = (1 << 24) - 1,
+  kImm16Mask = (1 << 16) - 1,
+  kImm8Mask = (1 << 8) - 1,
+  kOff12Mask = (1 << 12) - 1,
+  kOff8Mask = (1 << 8) - 1
 };
 
 
@@ -332,9 +332,9 @@
 // standard SoftwareInterrupCode. Bit 23 is reserved for the stop feature.
 enum SoftwareInterruptCodes {
   // transition to C code
-  kCallRtRedirected= 0x10,
+  kCallRtRedirected = 0x10,
   // break point
-  kBreakpoint= 0x20,
+  kBreakpoint = 0x20,
   // stop
   kStopCode = 1 << 23
 };
diff --git a/src/arm/cpu-arm.cc b/src/arm/cpu-arm.cc
index 9c7104e..4a34070 100644
--- a/src/arm/cpu-arm.cc
+++ b/src/arm/cpu-arm.cc
@@ -27,6 +27,8 @@
 void CpuFeatures::FlushICache(void* start, size_t size) {
   if (size == 0) return;
 
+  if (CpuFeatures::IsSupported(COHERENT_CACHE)) return;
+
 #if defined(USE_SIMULATOR)
   // Not generating ARM instructions for C-code. This means that we are
   // building an ARM emulator based target.  We should notify the simulator
diff --git a/src/arm/debug-arm.cc b/src/arm/debug-arm.cc
index 6d7d6b8..c910057 100644
--- a/src/arm/debug-arm.cc
+++ b/src/arm/debug-arm.cc
@@ -178,7 +178,11 @@
   // Calling convention for IC load (from ic-arm.cc).
   Register receiver = LoadDescriptor::ReceiverRegister();
   Register name = LoadDescriptor::NameRegister();
-  Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0);
+  RegList regs = receiver.bit() | name.bit();
+  if (FLAG_vector_ics) {
+    regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit();
+  }
+  Generate_DebugBreakCallHelper(masm, regs, 0);
 }
 
 
diff --git a/src/arm/deoptimizer-arm.cc b/src/arm/deoptimizer-arm.cc
index 0455a3b..b3a6173 100644
--- a/src/arm/deoptimizer-arm.cc
+++ b/src/arm/deoptimizer-arm.cc
@@ -21,6 +21,12 @@
 }
 
 
+void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
+  // Empty because there is no need for relocation information for the code
+  // patching in Deoptimizer::PatchCodeForDeoptimization below.
+}
+
+
 void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
   Address code_start_address = code->instruction_start();
   // Invalidate the relocation information, as it will become invalid by the
diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc
index 85977b1..4e631b0 100644
--- a/src/arm/disasm-arm.cc
+++ b/src/arm/disasm-arm.cc
@@ -148,7 +148,7 @@
 
 // These condition names are defined in a way to match the native disassembler
 // formatting. See for example the command "objdump -d <binary file>".
-static const char* cond_names[kNumberOfConditions] = {
+static const char* const cond_names[kNumberOfConditions] = {
   "eq", "ne", "cs" , "cc" , "mi" , "pl" , "vs" , "vc" ,
   "hi", "ls", "ge", "lt", "gt", "le", "", "invalid",
 };
@@ -1027,7 +1027,75 @@
               UNREACHABLE();
               break;
             case 1:
-              UNREACHABLE();
+              if (instr->Bits(9, 6) == 1) {
+                if (instr->Bit(20) == 0) {
+                  if (instr->Bits(19, 16) == 0xF) {
+                    switch (instr->Bits(11, 10)) {
+                      case 0:
+                        Format(instr, "sxtb'cond 'rd, 'rm");
+                        break;
+                      case 1:
+                        Format(instr, "sxtb'cond 'rd, 'rm, ror #8");
+                        break;
+                      case 2:
+                        Format(instr, "sxtb'cond 'rd, 'rm, ror #16");
+                        break;
+                      case 3:
+                        Format(instr, "sxtb'cond 'rd, 'rm, ror #24");
+                        break;
+                    }
+                  } else {
+                    switch (instr->Bits(11, 10)) {
+                      case 0:
+                        Format(instr, "sxtab'cond 'rd, 'rn, 'rm");
+                        break;
+                      case 1:
+                        Format(instr, "sxtab'cond 'rd, 'rn, 'rm, ror #8");
+                        break;
+                      case 2:
+                        Format(instr, "sxtab'cond 'rd, 'rn, 'rm, ror #16");
+                        break;
+                      case 3:
+                        Format(instr, "sxtab'cond 'rd, 'rn, 'rm, ror #24");
+                        break;
+                    }
+                  }
+                } else {
+                  if (instr->Bits(19, 16) == 0xF) {
+                    switch (instr->Bits(11, 10)) {
+                      case 0:
+                        Format(instr, "sxth'cond 'rd, 'rm");
+                        break;
+                      case 1:
+                        Format(instr, "sxth'cond 'rd, 'rm, ror #8");
+                        break;
+                      case 2:
+                        Format(instr, "sxth'cond 'rd, 'rm, ror #16");
+                        break;
+                      case 3:
+                        Format(instr, "sxth'cond 'rd, 'rm, ror #24");
+                        break;
+                    }
+                  } else {
+                    switch (instr->Bits(11, 10)) {
+                      case 0:
+                        Format(instr, "sxtah'cond 'rd, 'rn, 'rm");
+                        break;
+                      case 1:
+                        Format(instr, "sxtah'cond 'rd, 'rn, 'rm, ror #8");
+                        break;
+                      case 2:
+                        Format(instr, "sxtah'cond 'rd, 'rn, 'rm, ror #16");
+                        break;
+                      case 3:
+                        Format(instr, "sxtah'cond 'rd, 'rn, 'rm, ror #24");
+                        break;
+                    }
+                  }
+                }
+              } else {
+                UNREACHABLE();
+              }
               break;
             case 2:
               if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
@@ -1054,36 +1122,70 @@
               }
               break;
             case 3:
-              if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
-                if (instr->Bits(19, 16) == 0xF) {
-                  switch (instr->Bits(11, 10)) {
-                    case 0:
-                      Format(instr, "uxtb'cond 'rd, 'rm");
-                      break;
-                    case 1:
-                      Format(instr, "uxtb'cond 'rd, 'rm, ror #8");
-                      break;
-                    case 2:
-                      Format(instr, "uxtb'cond 'rd, 'rm, ror #16");
-                      break;
-                    case 3:
-                      Format(instr, "uxtb'cond 'rd, 'rm, ror #24");
-                      break;
+              if ((instr->Bits(9, 6) == 1)) {
+                if ((instr->Bit(20) == 0)) {
+                  if (instr->Bits(19, 16) == 0xF) {
+                    switch (instr->Bits(11, 10)) {
+                      case 0:
+                        Format(instr, "uxtb'cond 'rd, 'rm");
+                        break;
+                      case 1:
+                        Format(instr, "uxtb'cond 'rd, 'rm, ror #8");
+                        break;
+                      case 2:
+                        Format(instr, "uxtb'cond 'rd, 'rm, ror #16");
+                        break;
+                      case 3:
+                        Format(instr, "uxtb'cond 'rd, 'rm, ror #24");
+                        break;
+                    }
+                  } else {
+                    switch (instr->Bits(11, 10)) {
+                      case 0:
+                        Format(instr, "uxtab'cond 'rd, 'rn, 'rm");
+                        break;
+                      case 1:
+                        Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #8");
+                        break;
+                      case 2:
+                        Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #16");
+                        break;
+                      case 3:
+                        Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #24");
+                        break;
+                    }
                   }
                 } else {
-                  switch (instr->Bits(11, 10)) {
-                    case 0:
-                      Format(instr, "uxtab'cond 'rd, 'rn, 'rm");
-                      break;
-                    case 1:
-                      Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #8");
-                      break;
-                    case 2:
-                      Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #16");
-                      break;
-                    case 3:
-                      Format(instr, "uxtab'cond 'rd, 'rn, 'rm, ror #24");
-                      break;
+                  if (instr->Bits(19, 16) == 0xF) {
+                    switch (instr->Bits(11, 10)) {
+                      case 0:
+                        Format(instr, "uxth'cond 'rd, 'rm");
+                        break;
+                      case 1:
+                        Format(instr, "uxth'cond 'rd, 'rm, ror #8");
+                        break;
+                      case 2:
+                        Format(instr, "uxth'cond 'rd, 'rm, ror #16");
+                        break;
+                      case 3:
+                        Format(instr, "uxth'cond 'rd, 'rm, ror #24");
+                        break;
+                    }
+                  } else {
+                    switch (instr->Bits(11, 10)) {
+                      case 0:
+                        Format(instr, "uxtah'cond 'rd, 'rn, 'rm");
+                        break;
+                      case 1:
+                        Format(instr, "uxtah'cond 'rd, 'rn, 'rm, ror #8");
+                        break;
+                      case 2:
+                        Format(instr, "uxtah'cond 'rd, 'rn, 'rm, ror #16");
+                        break;
+                      case 3:
+                        Format(instr, "uxtah'cond 'rd, 'rn, 'rm, ror #24");
+                        break;
+                    }
                   }
                 }
               } else {
@@ -1096,6 +1198,17 @@
       break;
     }
     case db_x: {
+      if (instr->Bits(22, 20) == 0x5) {
+        if (instr->Bits(7, 4) == 0x1) {
+          if (instr->Bits(15, 12) == 0xF) {
+            Format(instr, "smmul'cond 'rn, 'rm, 'rs");
+          } else {
+            // SMMLA (in V8 notation matching ARM ISA format)
+            Format(instr, "smmla'cond 'rn, 'rm, 'rs, 'rd");
+          }
+          break;
+        }
+      }
       if (FLAG_enable_sudiv) {
         if (instr->Bits(5, 4) == 0x1) {
           if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) {
@@ -1266,6 +1379,14 @@
         } else {
           Unknown(instr);  // Not used by V8.
         }
+      } else if (((instr->Opc2Value() == 0x6)) && instr->Opc3Value() == 0x3) {
+        bool dp_operation = (instr->SzValue() == 1);
+        // vrintz - round towards zero (truncate)
+        if (dp_operation) {
+          Format(instr, "vrintz'cond.f64.f64 'Dd, 'Dm");
+        } else {
+          Unknown(instr);  // Not used by V8.
+        }
       } else {
         Unknown(instr);  // Not used by V8.
       }
@@ -1616,6 +1737,50 @@
         Unknown(instr);
       }
       break;
+    case 0x1D:
+      if (instr->Opc1Value() == 0x7 && instr->Bits(19, 18) == 0x2 &&
+          instr->Bits(11, 9) == 0x5 && instr->Bits(7, 6) == 0x1 &&
+          instr->Bit(4) == 0x0) {
+        // VRINTA, VRINTN, VRINTP, VRINTM (floating-point)
+        bool dp_operation = (instr->SzValue() == 1);
+        int rounding_mode = instr->Bits(17, 16);
+        switch (rounding_mode) {
+          case 0x0:
+            if (dp_operation) {
+              Format(instr, "vrinta.f64.f64 'Dd, 'Dm");
+            } else {
+              Unknown(instr);
+            }
+            break;
+          case 0x1:
+            if (dp_operation) {
+              Format(instr, "vrintn.f64.f64 'Dd, 'Dm");
+            } else {
+              Unknown(instr);
+            }
+            break;
+          case 0x2:
+            if (dp_operation) {
+              Format(instr, "vrintp.f64.f64 'Dd, 'Dm");
+            } else {
+              Unknown(instr);
+            }
+            break;
+          case 0x3:
+            if (dp_operation) {
+              Format(instr, "vrintm.f64.f64 'Dd, 'Dm");
+            } else {
+              Unknown(instr);
+            }
+            break;
+          default:
+            UNREACHABLE();  // Case analysis is exhaustive.
+            break;
+        }
+      } else {
+        Unknown(instr);
+      }
+      break;
     default:
       Unknown(instr);
       break;
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index eb60c3f..3dc5420 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -195,10 +195,10 @@
     // Argument to NewContext is the function, which is still in r1.
     Comment cmnt(masm_, "[ Allocate context");
     bool need_write_barrier = true;
-    if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
+    if (FLAG_harmony_scoping && info->scope()->is_script_scope()) {
       __ push(r1);
       __ Push(info->scope()->GetScopeInfo());
-      __ CallRuntime(Runtime::kNewGlobalContext, 2);
+      __ CallRuntime(Runtime::kNewScriptContext, 2);
     } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
       FastNewContextStub stub(isolate(), heap_slots);
       __ CallStub(&stub);
@@ -937,7 +937,7 @@
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
-  __ LoadContext(r1, scope_->ContextChainLength(scope_->GlobalScope()));
+  __ LoadContext(r1, scope_->ContextChainLength(scope_->ScriptScope()));
   __ ldr(r1, ContextOperand(r1, variable->interface()->Index()));
   __ ldr(r1, ContextOperand(r1, Context::EXTENSION_INDEX));
 
@@ -1102,7 +1102,7 @@
 
 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   Comment cmnt(masm_, "[ ForInStatement");
-  int slot = stmt->ForInFeedbackSlot();
+  FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
   SetStatementPosition(stmt);
 
   Label loop, exit;
@@ -1111,6 +1111,7 @@
 
   // Get the object to enumerate over. If the object is null or undefined, skip
   // over the loop.  See ECMA-262 version 5, section 12.6.4.
+  SetExpressionPosition(stmt->enumerable());
   VisitForAccumulatorValue(stmt->enumerable());
   __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
   __ cmp(r0, ip);
@@ -1131,6 +1132,7 @@
   __ push(r0);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ push(r0);
 
   // Check for proxies.
@@ -1155,6 +1157,7 @@
   __ bind(&call_runtime);
   __ push(r0);  // Duplicate the enumerable object on the stack.
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
 
   // If we got a map from the runtime call, we can do a fast
   // modification check. Otherwise, we got a fixed array, and we have
@@ -1194,7 +1197,8 @@
 
   __ Move(r1, FeedbackVector());
   __ mov(r2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
-  __ str(r2, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(slot)));
+  int vector_index = FeedbackVector()->GetIndex(slot);
+  __ str(r2, FieldMemOperand(r1, FixedArray::OffsetOfElementAt(vector_index)));
 
   __ mov(r1, Operand(Smi::FromInt(1)));  // Smi indicates slow check
   __ ldr(r2, MemOperand(sp, 0 * kPointerSize));  // Get enumerated object
@@ -1211,6 +1215,8 @@
   // Generate code for doing the condition check.
   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
   __ bind(&loop);
+  SetExpressionPosition(stmt->each());
+
   // Load the current count to r0, load the length to r1.
   __ Ldrd(r0, r1, MemOperand(sp, 0 * kPointerSize));
   __ cmp(r0, r1);  // Compare to the array length.
@@ -1280,48 +1286,6 @@
 }
 
 
-void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
-  Comment cmnt(masm_, "[ ForOfStatement");
-  SetStatementPosition(stmt);
-
-  Iteration loop_statement(this, stmt);
-  increment_loop_depth();
-
-  // var iterator = iterable[Symbol.iterator]();
-  VisitForEffect(stmt->assign_iterator());
-
-  // Loop entry.
-  __ bind(loop_statement.continue_label());
-
-  // result = iterator.next()
-  VisitForEffect(stmt->next_result());
-
-  // if (result.done) break;
-  Label result_not_done;
-  VisitForControl(stmt->result_done(),
-                  loop_statement.break_label(),
-                  &result_not_done,
-                  &result_not_done);
-  __ bind(&result_not_done);
-
-  // each = result.value
-  VisitForEffect(stmt->assign_each());
-
-  // Generate code for the body of the loop.
-  Visit(stmt->body());
-
-  // Check stack before looping.
-  PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
-  EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
-  __ jmp(loop_statement.continue_label());
-
-  // Exit and decrement the loop depth.
-  PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
-  __ bind(loop_statement.break_label());
-  decrement_loop_depth();
-}
-
-
 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
                                        bool pretenure) {
   // Use the fast case closure allocation code that allocates in new
@@ -1364,7 +1328,13 @@
   Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
   __ Move(LoadDescriptor::NameRegister(), home_object_symbol);
 
-  CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  if (FLAG_vector_ics) {
+    __ mov(VectorLoadICDescriptor::SlotRegister(),
+           Operand(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
+    CallLoadIC(NOT_CONTEXTUAL);
+  } else {
+    CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  }
 
   __ cmp(r0, Operand(isolate()->factory()->undefined_value()));
   Label done;
@@ -1374,6 +1344,19 @@
 }
 
 
+void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
+                                                  int offset) {
+  if (NeedsHomeObject(initializer)) {
+    __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
+    __ mov(StoreDescriptor::NameRegister(),
+           Operand(isolate()->factory()->home_object_symbol()));
+    __ ldr(StoreDescriptor::ValueRegister(),
+           MemOperand(sp, offset * kPointerSize));
+    CallStoreIC();
+  }
+}
+
+
 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
                                                       TypeofState typeof_state,
                                                       Label* slow) {
@@ -1426,7 +1409,7 @@
   __ mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
   if (FLAG_vector_ics) {
     __ mov(VectorLoadICDescriptor::SlotRegister(),
-           Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
+           Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
   }
 
   ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
@@ -1515,7 +1498,7 @@
       __ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
       if (FLAG_vector_ics) {
         __ mov(VectorLoadICDescriptor::SlotRegister(),
-               Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
+               Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
       }
       CallLoadIC(CONTEXTUAL);
       context()->Plug(r0);
@@ -1691,6 +1674,7 @@
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in r0.
@@ -1719,6 +1703,8 @@
         DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
         // Fall through.
       case ObjectLiteral::Property::COMPUTED:
+        // It is safe to use [[Put]] here because the boilerplate already
+        // contains computed properties with an uninitialized value.
         if (key->value()->IsInternalizedString()) {
           if (property->emit_store()) {
             VisitForAccumulatorValue(value);
@@ -1727,6 +1713,14 @@
             __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
             CallStoreIC(key->LiteralFeedbackId());
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
+
+            if (NeedsHomeObject(value)) {
+              __ Move(StoreDescriptor::ReceiverRegister(), r0);
+              __ mov(StoreDescriptor::NameRegister(),
+                     Operand(isolate()->factory()->home_object_symbol()));
+              __ ldr(StoreDescriptor::ValueRegister(), MemOperand(sp));
+              CallStoreIC();
+            }
           } else {
             VisitForEffect(value);
           }
@@ -1738,6 +1732,7 @@
         VisitForStackValue(key);
         VisitForStackValue(value);
         if (property->emit_store()) {
+          EmitSetHomeObjectIfNeeded(value, 2);
           __ mov(r0, Operand(Smi::FromInt(SLOPPY)));  // PropertyAttributes
           __ push(r0);
           __ CallRuntime(Runtime::kSetProperty, 4);
@@ -1751,7 +1746,7 @@
         __ push(r0);
         VisitForStackValue(value);
         if (property->emit_store()) {
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           __ Drop(2);
         }
@@ -1775,7 +1770,9 @@
     __ push(r0);
     VisitForStackValue(it->first);
     EmitAccessor(it->second->getter);
+    EmitSetHomeObjectIfNeeded(it->second->getter, 2);
     EmitAccessor(it->second->setter);
+    EmitSetHomeObjectIfNeeded(it->second->setter, 3);
     __ mov(r0, Operand(Smi::FromInt(NONE)));
     __ push(r0);
     __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
@@ -1883,16 +1880,8 @@
 
   Comment cmnt(masm_, "[ Assignment");
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
-  if (property != NULL) {
-    assign_type = (property->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(property);
 
   // Evaluate LHS expression.
   switch (assign_type) {
@@ -1908,6 +1897,32 @@
         VisitForStackValue(property->obj());
       }
       break;
+    case NAMED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        const Register scratch = r1;
+        __ ldr(scratch, MemOperand(sp, kPointerSize));
+        __ Push(scratch);
+        __ Push(result_register());
+      }
+      break;
+    case KEYED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(property->key());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        const Register scratch = r1;
+        __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch);
+        __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch);
+        __ Push(result_register());
+      }
+      break;
     case KEYED_PROPERTY:
       if (expr->is_compound()) {
         VisitForStackValue(property->obj());
@@ -1935,6 +1950,14 @@
           EmitNamedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
           break;
+        case NAMED_SUPER_PROPERTY:
+          EmitNamedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
+        case KEYED_SUPER_PROPERTY:
+          EmitKeyedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
         case KEYED_PROPERTY:
           EmitKeyedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
@@ -1981,6 +2004,14 @@
     case NAMED_PROPERTY:
       EmitNamedPropertyAssignment(expr);
       break;
+    case NAMED_SUPER_PROPERTY:
+      EmitNamedSuperPropertyStore(property);
+      context()->Plug(r0);
+      break;
+    case KEYED_SUPER_PROPERTY:
+      EmitKeyedSuperPropertyStore(property);
+      context()->Plug(r0);
+      break;
     case KEYED_PROPERTY:
       EmitKeyedPropertyAssignment(expr);
       break;
@@ -2110,7 +2141,7 @@
       __ ldr(load_name, MemOperand(sp, 2 * kPointerSize));
       if (FLAG_vector_ics) {
         __ mov(VectorLoadICDescriptor::SlotRegister(),
-               Operand(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
+               Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
       }
       Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
       CallIC(ic, TypeFeedbackId::None());
@@ -2130,7 +2161,7 @@
       __ LoadRoot(load_name, Heap::kdone_stringRootIndex);  // "done"
       if (FLAG_vector_ics) {
         __ mov(VectorLoadICDescriptor::SlotRegister(),
-               Operand(Smi::FromInt(expr->DoneFeedbackSlot())));
+               Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
       }
       CallLoadIC(NOT_CONTEXTUAL);                           // r0=result.done
       Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
@@ -2143,7 +2174,7 @@
       __ LoadRoot(load_name, Heap::kvalue_stringRootIndex);  // "value"
       if (FLAG_vector_ics) {
         __ mov(VectorLoadICDescriptor::SlotRegister(),
-               Operand(Smi::FromInt(expr->ValueFeedbackSlot())));
+               Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
       }
       CallLoadIC(NOT_CONTEXTUAL);                            // r0=result.value
       context()->DropAndPlug(2, r0);                         // drop iter and g
@@ -2164,15 +2195,6 @@
   VisitForAccumulatorValue(value);
   __ pop(r1);
 
-  // Check generator state.
-  Label wrong_state, closed_state, done;
-  __ ldr(r3, FieldMemOperand(r1, JSGeneratorObject::kContinuationOffset));
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
-  __ cmp(r3, Operand(Smi::FromInt(0)));
-  __ b(eq, &closed_state);
-  __ b(lt, &wrong_state);
-
   // Load suspended function and context.
   __ ldr(cp, FieldMemOperand(r1, JSGeneratorObject::kContextOffset));
   __ ldr(r4, FieldMemOperand(r1, JSGeneratorObject::kFunctionOffset));
@@ -2195,7 +2217,7 @@
 
   // Enter a new JavaScript frame, and initialize its slots as they were when
   // the generator was suspended.
-  Label resume_frame;
+  Label resume_frame, done;
   __ bind(&push_frame);
   __ bl(&resume_frame);
   __ jmp(&done);
@@ -2255,26 +2277,6 @@
   // Not reached: the runtime call returns elsewhere.
   __ stop("not-reached");
 
-  // Reach here when generator is closed.
-  __ bind(&closed_state);
-  if (resume_mode == JSGeneratorObject::NEXT) {
-    // Return completed iterator result when generator is closed.
-    __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
-    __ push(r2);
-    // Pop value from top-of-stack slot; box result into result register.
-    EmitCreateIteratorResult(true);
-  } else {
-    // Throw the provided value.
-    __ push(r0);
-    __ CallRuntime(Runtime::kThrow, 1);
-  }
-  __ jmp(&done);
-
-  // Throw error if we attempt to operate on a running generator.
-  __ bind(&wrong_state);
-  __ push(r1);
-  __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
-
   __ bind(&done);
   context()->Plug(result_register());
 }
@@ -2284,23 +2286,26 @@
   Label gc_required;
   Label allocated;
 
-  Handle<Map> map(isolate()->native_context()->iterator_result_map());
+  const int instance_size = 5 * kPointerSize;
+  DCHECK_EQ(isolate()->native_context()->iterator_result_map()->instance_size(),
+            instance_size);
 
-  __ Allocate(map->instance_size(), r0, r2, r3, &gc_required, TAG_OBJECT);
+  __ Allocate(instance_size, r0, r2, r3, &gc_required, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&gc_required);
-  __ Push(Smi::FromInt(map->instance_size()));
+  __ Push(Smi::FromInt(instance_size));
   __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
   __ ldr(context_register(),
          MemOperand(fp, StandardFrameConstants::kContextOffset));
 
   __ bind(&allocated);
-  __ mov(r1, Operand(map));
+  __ ldr(r1, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+  __ ldr(r1, FieldMemOperand(r1, GlobalObject::kNativeContextOffset));
+  __ ldr(r1, ContextOperand(r1, Context::ITERATOR_RESULT_MAP_INDEX));
   __ pop(r2);
   __ mov(r3, Operand(isolate()->factory()->ToBoolean(done)));
   __ mov(r4, Operand(isolate()->factory()->empty_fixed_array()));
-  DCHECK_EQ(map->instance_size(), 5 * kPointerSize);
   __ str(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
   __ str(r4, FieldMemOperand(r0, JSObject::kPropertiesOffset));
   __ str(r4, FieldMemOperand(r0, JSObject::kElementsOffset));
@@ -2319,11 +2324,12 @@
 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
+  DCHECK(!prop->IsSuperAccess());
 
   __ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
   if (FLAG_vector_ics) {
     __ mov(VectorLoadICDescriptor::SlotRegister(),
-           Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
+           Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
     CallLoadIC(NOT_CONTEXTUAL);
   } else {
     CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
@@ -2332,15 +2338,12 @@
 
 
 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object.
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
   DCHECK(!key->value()->IsSmi());
   DCHECK(prop->IsSuperAccess());
 
-  SuperReference* super_ref = prop->obj()->AsSuperReference();
-  EmitLoadHomeObject(super_ref);
-  __ Push(r0);
-  VisitForStackValue(super_ref->this_var());
   __ Push(key->value());
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 }
@@ -2351,7 +2354,7 @@
   Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
   if (FLAG_vector_ics) {
     __ mov(VectorLoadICDescriptor::SlotRegister(),
-           Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
+           Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
     CallIC(ic);
   } else {
     CallIC(ic, prop->PropertyFeedbackId());
@@ -2359,6 +2362,14 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object, key.
+  SetSourcePosition(prop->position());
+
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+}
+
+
 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
                                               Token::Value op,
                                               OverwriteMode mode,
@@ -2453,6 +2464,63 @@
 }
 
 
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
+  // Constructor is in r0.
+  DCHECK(lit != NULL);
+  __ push(r0);
+
+  // No access check is needed here since the constructor is created by the
+  // class literal.
+  Register scratch = r1;
+  __ ldr(scratch,
+         FieldMemOperand(r0, JSFunction::kPrototypeOrInitialMapOffset));
+  __ push(scratch);
+
+  for (int i = 0; i < lit->properties()->length(); i++) {
+    ObjectLiteral::Property* property = lit->properties()->at(i);
+    Literal* key = property->key()->AsLiteral();
+    Expression* value = property->value();
+    DCHECK(key != NULL);
+
+    if (property->is_static()) {
+      __ ldr(scratch, MemOperand(sp, kPointerSize));  // constructor
+    } else {
+      __ ldr(scratch, MemOperand(sp, 0));  // prototype
+    }
+    __ push(scratch);
+    VisitForStackValue(key);
+    VisitForStackValue(value);
+    EmitSetHomeObjectIfNeeded(value, 2);
+
+    switch (property->kind()) {
+      case ObjectLiteral::Property::CONSTANT:
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+      case ObjectLiteral::Property::COMPUTED:
+      case ObjectLiteral::Property::PROTOTYPE:
+        __ CallRuntime(Runtime::kDefineClassMethod, 3);
+        break;
+
+      case ObjectLiteral::Property::GETTER:
+        __ CallRuntime(Runtime::kDefineClassGetter, 3);
+        break;
+
+      case ObjectLiteral::Property::SETTER:
+        __ CallRuntime(Runtime::kDefineClassSetter, 3);
+        break;
+
+      default:
+        UNREACHABLE();
+    }
+  }
+
+  // prototype
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+
+  // constructor
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+}
+
+
 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
                                      Token::Value op,
                                      OverwriteMode mode) {
@@ -2468,16 +2536,8 @@
 void FullCodeGenerator::EmitAssignment(Expression* expr) {
   DCHECK(expr->IsValidReferenceExpression());
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->AsProperty();
-  if (prop != NULL) {
-    assign_type = (prop->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   switch (assign_type) {
     case VARIABLE: {
@@ -2496,6 +2556,42 @@
       CallStoreIC();
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      __ Push(r0);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      // stack: value, this; r0: home_object
+      Register scratch = r2;
+      Register scratch2 = r3;
+      __ mov(scratch, result_register());              // home_object
+      __ ldr(r0, MemOperand(sp, kPointerSize));        // value
+      __ ldr(scratch2, MemOperand(sp, 0));             // this
+      __ str(scratch2, MemOperand(sp, kPointerSize));  // this
+      __ str(scratch, MemOperand(sp, 0));              // home_object
+      // stack: this, home_object; r0: value
+      EmitNamedSuperPropertyStore(prop);
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      __ Push(r0);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(prop->key());
+      Register scratch = r2;
+      Register scratch2 = r3;
+      __ ldr(scratch2, MemOperand(sp, 2 * kPointerSize));  // value
+      // stack: value, this, home_object; r0: key, r3: value
+      __ ldr(scratch, MemOperand(sp, kPointerSize));  // this
+      __ str(scratch, MemOperand(sp, 2 * kPointerSize));
+      __ ldr(scratch, MemOperand(sp, 0));  // home_object
+      __ str(scratch, MemOperand(sp, kPointerSize));
+      __ str(r0, MemOperand(sp, 0));
+      __ Move(r0, scratch2);
+      // stack: this, home_object, key; r0: value.
+      EmitKeyedSuperPropertyStore(prop);
+      break;
+    }
     case KEYED_PROPERTY: {
       __ push(r0);  // Preserve value.
       VisitForStackValue(prop->obj());
@@ -2589,8 +2685,9 @@
       }
       EmitStoreToStackLocalOrContextSlot(var, location);
     }
+  } else if (IsSignallingAssignmentToConst(var, op, strict_mode())) {
+    __ CallRuntime(Runtime::kThrowConstAssignError, 0);
   }
-  // Non-initializing assignments to consts are ignored.
 }
 
 
@@ -2612,6 +2709,35 @@
 }
 
 
+void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // r0 : value
+  // stack : receiver ('this'), home_object
+  DCHECK(prop != NULL);
+  Literal* key = prop->key()->AsLiteral();
+  DCHECK(key != NULL);
+
+  __ Push(key->value());
+  __ Push(r0);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
+                                          : Runtime::kStoreToSuper_Sloppy),
+                 4);
+}
+
+
+void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // r0 : value
+  // stack : receiver ('this'), home_object, key
+  DCHECK(prop != NULL);
+
+  __ Push(r0);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict
+                                          : Runtime::kStoreKeyedToSuper_Sloppy),
+                 4);
+}
+
+
 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
   // Assignment to a property, using a keyed store IC.
 
@@ -2638,16 +2764,27 @@
       __ Move(LoadDescriptor::ReceiverRegister(), r0);
       EmitNamedPropertyLoad(expr);
     } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ Push(result_register());
       EmitNamedSuperPropertyLoad(expr);
     }
     PrepareForBailoutForId(expr->LoadId(), TOS_REG);
     context()->Plug(r0);
   } else {
-    VisitForStackValue(expr->obj());
-    VisitForAccumulatorValue(expr->key());
-    __ Move(LoadDescriptor::NameRegister(), r0);
-    __ pop(LoadDescriptor::ReceiverRegister());
-    EmitKeyedPropertyLoad(expr);
+    if (!expr->IsSuperAccess()) {
+      VisitForStackValue(expr->obj());
+      VisitForAccumulatorValue(expr->key());
+      __ Move(LoadDescriptor::NameRegister(), r0);
+      __ pop(LoadDescriptor::ReceiverRegister());
+      EmitKeyedPropertyLoad(expr);
+    } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForStackValue(expr->key());
+      EmitKeyedSuperPropertyLoad(expr);
+    }
     context()->Plug(r0);
   }
 }
@@ -2712,16 +2849,16 @@
   __ Push(r0);
   VisitForAccumulatorValue(super_ref->this_var());
   __ Push(r0);
-  __ ldr(scratch, MemOperand(sp, kPointerSize));
-  __ Push(scratch);
   __ Push(r0);
+  __ ldr(scratch, MemOperand(sp, kPointerSize * 2));
+  __ Push(scratch);
   __ Push(key->value());
 
   // Stack here:
   //  - home_object
   //  - this (receiver)
-  //  - home_object <-- LoadFromSuper will pop here and below.
-  //  - this (receiver)
+  //  - this (receiver) <-- LoadFromSuper will pop here and below.
+  //  - home_object
   //  - key
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 
@@ -2759,6 +2896,43 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
+  Expression* callee = expr->expression();
+  DCHECK(callee->IsProperty());
+  Property* prop = callee->AsProperty();
+  DCHECK(prop->IsSuperAccess());
+
+  SetSourcePosition(prop->position());
+  // Load the function from the receiver.
+  const Register scratch = r1;
+  SuperReference* super_ref = prop->obj()->AsSuperReference();
+  EmitLoadHomeObject(super_ref);
+  __ Push(r0);
+  VisitForAccumulatorValue(super_ref->this_var());
+  __ Push(r0);
+  __ Push(r0);
+  __ ldr(scratch, MemOperand(sp, kPointerSize * 2));
+  __ Push(scratch);
+  VisitForStackValue(prop->key());
+
+  // Stack here:
+  //  - home_object
+  //  - this (receiver)
+  //  - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
+  //  - home_object
+  //  - key
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+
+  // Replace home_object with target function.
+  __ str(r0, MemOperand(sp, kPointerSize));
+
+  // Stack here:
+  // - target function
+  // - this (receiver)
+  EmitCall(expr, CallICState::METHOD);
+}
+
+
 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Load the arguments.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2773,7 +2947,7 @@
   SetSourcePosition(expr->position());
   Handle<Code> ic = CallIC::initialize_stub(
       isolate(), arg_count, call_type);
-  __ mov(r3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
+  __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackSlot())));
   __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize));
   // Don't assign a type feedback id to the IC, since type feedback is provided
   // by the vector above.
@@ -2814,6 +2988,14 @@
 }
 
 
+void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
+  DCHECK(super_ref != NULL);
+  __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ Push(r0);
+  __ CallRuntime(Runtime::kGetPrototype, 1);
+}
+
+
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -2853,6 +3035,8 @@
       // r1 (receiver). Touch up the stack with the right values.
       __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize));
       __ str(r1, MemOperand(sp, arg_count * kPointerSize));
+
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
 
     // Record source position for debugger.
@@ -2886,6 +3070,7 @@
     __ Push(context_register(), r2);
     __ CallRuntime(Runtime::kLoadLookupSlot, 2);
     __ Push(r0, r1);  // Function, receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
 
     // If fast case code has been generated, emit code to push the
     // function and receiver and have the slow path jump around this
@@ -2909,9 +3094,12 @@
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
     bool is_named_call = property->key()->IsPropertyName();
-    // super.x() is handled in EmitCallWithLoadIC.
-    if (property->IsSuperAccess() && is_named_call) {
-      EmitSuperCallWithLoadIC(expr);
+    if (property->IsSuperAccess()) {
+      if (is_named_call) {
+        EmitSuperCallWithLoadIC(expr);
+      } else {
+        EmitKeyedSuperCallWithLoadIC(expr);
+      }
     } else {
       {
         PreservePositionScope scope(masm()->positions_recorder());
@@ -2923,6 +3111,12 @@
         EmitKeyedCallWithLoadIC(expr, property->key());
       }
     }
+  } else if (call_type == Call::SUPER_CALL) {
+    SuperReference* super_ref = callee->AsSuperReference();
+    EmitLoadSuperConstructor(super_ref);
+    __ Push(result_register());
+    VisitForStackValue(super_ref->this_var());
+    EmitCall(expr, CallICState::METHOD);
   } else {
     DCHECK(call_type == Call::OTHER_CALL);
     // Call to an arbitrary expression not handled specially above.
@@ -2951,7 +3145,12 @@
   // Push constructor on the stack.  If it's not a function it's used as
   // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
   // ignored.
-  VisitForStackValue(expr->expression());
+  if (expr->expression()->IsSuperReference()) {
+    EmitLoadSuperConstructor(expr->expression()->AsSuperReference());
+    __ Push(result_register());
+  } else {
+    VisitForStackValue(expr->expression());
+  }
 
   // Push the arguments ("left-to-right") on the stack.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2971,12 +3170,12 @@
   // Record call targets in unoptimized code.
   if (FLAG_pretenuring_call_new) {
     EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
-    DCHECK(expr->AllocationSiteFeedbackSlot() ==
-           expr->CallNewFeedbackSlot() + 1);
+    DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
+           expr->CallNewFeedbackSlot().ToInt() + 1);
   }
 
   __ Move(r2, FeedbackVector());
-  __ mov(r3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
+  __ mov(r3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
 
   CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
   __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
@@ -3287,6 +3486,32 @@
 }
 
 
+void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(r0, if_false);
+  Register map = r1;
+  Register type_reg = r2;
+  __ ldr(map, FieldMemOperand(r0, HeapObject::kMapOffset));
+  __ ldrb(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  __ sub(type_reg, type_reg, Operand(FIRST_JS_PROXY_TYPE));
+  __ cmp(type_reg, Operand(LAST_JS_PROXY_TYPE - FIRST_JS_PROXY_TYPE));
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(ls, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
 
 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
   DCHECK(expr->arguments()->length() == 0);
@@ -4177,7 +4402,7 @@
     __ mov(LoadDescriptor::NameRegister(), Operand(expr->name()));
     if (FLAG_vector_ics) {
       __ mov(VectorLoadICDescriptor::SlotRegister(),
-             Operand(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
+             Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
       CallLoadIC(NOT_CONTEXTUAL);
     } else {
       CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
@@ -4333,17 +4558,8 @@
   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());
 
-  // Expression can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
-  // In case of a property we use the uninitialized expression context
-  // of the key to detect a named property.
-  if (prop != NULL) {
-    assign_type =
-        (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   // Evaluate expression and get value.
   if (assign_type == VARIABLE) {
@@ -4356,18 +4572,55 @@
       __ mov(ip, Operand(Smi::FromInt(0)));
       __ push(ip);
     }
-    if (assign_type == NAMED_PROPERTY) {
-      // Put the object both on the stack and in the register.
-      VisitForStackValue(prop->obj());
-      __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
-      EmitNamedPropertyLoad(prop);
-    } else {
-      VisitForStackValue(prop->obj());
-      VisitForStackValue(prop->key());
-      __ ldr(LoadDescriptor::ReceiverRegister(),
-             MemOperand(sp, 1 * kPointerSize));
-      __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
-      EmitKeyedPropertyLoad(prop);
+    switch (assign_type) {
+      case NAMED_PROPERTY: {
+        // Put the object both on the stack and in the register.
+        VisitForStackValue(prop->obj());
+        __ ldr(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
+        EmitNamedPropertyLoad(prop);
+        break;
+      }
+
+      case NAMED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        const Register scratch = r1;
+        __ ldr(scratch, MemOperand(sp, kPointerSize));
+        __ Push(scratch);
+        __ Push(result_register());
+        EmitNamedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        VisitForAccumulatorValue(prop->key());
+        __ Push(result_register());
+        const Register scratch = r1;
+        __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch);
+        __ ldr(scratch, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch);
+        __ Push(result_register());
+        EmitKeyedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_PROPERTY: {
+        VisitForStackValue(prop->obj());
+        VisitForStackValue(prop->key());
+        __ ldr(LoadDescriptor::ReceiverRegister(),
+               MemOperand(sp, 1 * kPointerSize));
+        __ ldr(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
+        EmitKeyedPropertyLoad(prop);
+        break;
+      }
+
+      case VARIABLE:
+        UNREACHABLE();
     }
   }
 
@@ -4401,9 +4654,15 @@
           case NAMED_PROPERTY:
             __ str(r0, MemOperand(sp, kPointerSize));
             break;
+          case NAMED_SUPER_PROPERTY:
+            __ str(r0, MemOperand(sp, 2 * kPointerSize));
+            break;
           case KEYED_PROPERTY:
             __ str(r0, MemOperand(sp, 2 * kPointerSize));
             break;
+          case KEYED_SUPER_PROPERTY:
+            __ str(r0, MemOperand(sp, 3 * kPointerSize));
+            break;
         }
       }
     }
@@ -4431,9 +4690,15 @@
         case NAMED_PROPERTY:
           __ str(r0, MemOperand(sp, kPointerSize));
           break;
+        case NAMED_SUPER_PROPERTY:
+          __ str(r0, MemOperand(sp, 2 * kPointerSize));
+          break;
         case KEYED_PROPERTY:
           __ str(r0, MemOperand(sp, 2 * kPointerSize));
           break;
+        case KEYED_SUPER_PROPERTY:
+          __ str(r0, MemOperand(sp, 3 * kPointerSize));
+          break;
       }
     }
   }
@@ -4489,6 +4754,28 @@
       }
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      EmitNamedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(r0);
+      }
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      EmitKeyedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(r0);
+      }
+      break;
+    }
     case KEYED_PROPERTY: {
       __ Pop(StoreDescriptor::ReceiverRegister(),
              StoreDescriptor::NameRegister());
@@ -4519,7 +4806,7 @@
     __ mov(LoadDescriptor::NameRegister(), Operand(proxy->name()));
     if (FLAG_vector_ics) {
       __ mov(VectorLoadICDescriptor::SlotRegister(),
-             Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
+             Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
     }
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
@@ -4756,7 +5043,7 @@
 
 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
   Scope* declaration_scope = scope()->DeclarationScope();
-  if (declaration_scope->is_global_scope() ||
+  if (declaration_scope->is_script_scope() ||
       declaration_scope->is_module_scope()) {
     // Contexts nested in the native context have a canonical empty function
     // as their closure, not the anonymous closure containing the global
diff --git a/src/arm/interface-descriptors-arm.cc b/src/arm/interface-descriptors-arm.cc
index 9bbc1f5..6e77ee4 100644
--- a/src/arm/interface-descriptors-arm.cc
+++ b/src/arm/interface-descriptors-arm.cc
@@ -29,6 +29,9 @@
 const Register StoreDescriptor::ValueRegister() { return r0; }
 
 
+const Register StoreTransitionDescriptor::MapRegister() { return r3; }
+
+
 const Register ElementTransitionAndStoreDescriptor::MapRegister() { return r3; }
 
 
@@ -149,6 +152,15 @@
 }
 
 
+void AllocateHeapNumberDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  // register state
+  // cp -- context
+  Register registers[] = {cp};
+  data->Initialize(arraysize(registers), registers, nullptr);
+}
+
+
 void ArrayConstructorConstantArgCountDescriptor::Initialize(
     CallInterfaceDescriptorData* data) {
   // register state
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 13a46a2..e5de950 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <sstream>
+
 #include "src/v8.h"
 
 #include "src/arm/lithium-codegen-arm.h"
@@ -316,9 +318,9 @@
 
 void LStoreNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
-  OStringStream os;
+  std::ostringstream os;
   os << hydrogen()->access() << " <- ";
-  stream->Add(os.c_str());
+  stream->Add(os.str().c_str());
   value()->PrintTo(stream);
 }
 
@@ -697,11 +699,7 @@
     // Shift operations can only deoptimize if we do a logical shift
     // by 0 and the result cannot be truncated to int32.
     if (op == Token::SHR && constant_value == 0) {
-      if (FLAG_opt_safe_uint32_operations) {
-        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-      } else {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
-      }
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
     }
 
     LInstruction* result =
@@ -1100,9 +1098,17 @@
       UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
   LOperand* name_register =
       UseFixed(instr->name(), LoadDescriptor::NameRegister());
+  LOperand* slot = NULL;
+  LOperand* vector = NULL;
+  if (FLAG_vector_ics) {
+    slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
+    vector =
+        UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
+  }
+
   // Not marked as call. It can't deoptimize, and it never returns.
   return new (zone()) LTailCallThroughMegamorphicCache(
-      context, receiver_register, name_register);
+      context, receiver_register, name_register, slot, vector);
 }
 
 
@@ -1399,8 +1405,16 @@
   LOperand* divisor = UseRegister(instr->right());
   LOperand* temp =
       CpuFeatures::IsSupported(SUDIV) ? NULL : TempDoubleRegister();
-  LFlooringDivI* div = new(zone()) LFlooringDivI(dividend, divisor, temp);
-  return AssignEnvironment(DefineAsRegister(div));
+  LInstruction* result =
+      DefineAsRegister(new (zone()) LFlooringDivI(dividend, divisor, temp));
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+      (instr->CheckFlag(HValue::kCanOverflow) &&
+       (!CpuFeatures::IsSupported(SUDIV) ||
+        !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)))) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -2113,7 +2127,7 @@
   LOperand* global_object =
       UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
   LLoadGlobalGeneric* result =
@@ -2172,7 +2186,7 @@
   LOperand* object =
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
@@ -2239,7 +2253,7 @@
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index f9feaf6..1920935 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -166,17 +166,13 @@
   V(WrapReceiver)
 
 
-#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)                        \
-  virtual Opcode opcode() const FINAL OVERRIDE {                      \
-    return LInstruction::k##type;                                           \
-  }                                                                         \
-  virtual void CompileToNative(LCodeGen* generator) FINAL OVERRIDE;   \
-  virtual const char* Mnemonic() const FINAL OVERRIDE {               \
-    return mnemonic;                                                        \
-  }                                                                         \
-  static L##type* cast(LInstruction* instr) {                               \
-    DCHECK(instr->Is##type());                                              \
-    return reinterpret_cast<L##type*>(instr);                               \
+#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)            \
+  Opcode opcode() const FINAL { return LInstruction::k##type; } \
+  void CompileToNative(LCodeGen* generator) FINAL;              \
+  const char* Mnemonic() const FINAL { return mnemonic; }       \
+  static L##type* cast(LInstruction* instr) {                   \
+    DCHECK(instr->Is##type());                                  \
+    return reinterpret_cast<L##type*>(instr);                   \
   }
 
 
@@ -291,11 +287,9 @@
  public:
   // Allow 0 or 1 output operands.
   STATIC_ASSERT(R == 0 || R == 1);
-  virtual bool HasResult() const FINAL OVERRIDE {
-    return R != 0 && result() != NULL;
-  }
+  bool HasResult() const FINAL { return R != 0 && result() != NULL; }
   void set_result(LOperand* operand) { results_[0] = operand; }
-  LOperand* result() const { return results_[0]; }
+  LOperand* result() const OVERRIDE { return results_[0]; }
 
  protected:
   EmbeddedContainer<LOperand*, R> results_;
@@ -313,11 +307,11 @@
 
  private:
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return I; }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return I; }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return T; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return temps_[i]; }
+  int TempCount() FINAL { return T; }
+  LOperand* TempAt(int i) FINAL { return temps_[i]; }
 };
 
 
@@ -332,8 +326,8 @@
   }
 
   // Can't use the DECLARE-macro here because of sub-classes.
-  virtual bool IsGap() const OVERRIDE { return true; }
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsGap() const OVERRIDE { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   static LGap* cast(LInstruction* instr) {
     DCHECK(instr->IsGap());
     return reinterpret_cast<LGap*>(instr);
@@ -373,7 +367,7 @@
  public:
   explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
     return !IsRedundant();
   }
 
@@ -385,10 +379,10 @@
  public:
   explicit LGoto(HBasicBlock* block) : block_(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
-  virtual bool IsControl() const OVERRIDE { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsControl() const OVERRIDE { return true; }
 
   int block_id() const { return block_->block_id(); }
 
@@ -431,7 +425,7 @@
 
 class LDeoptimize FINAL : public LTemplateInstruction<0, 0, 0> {
  public:
-  virtual bool IsControl() const OVERRIDE { return true; }
+  bool IsControl() const OVERRIDE { return true; }
   DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
   DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
 };
@@ -442,12 +436,10 @@
   explicit LLabel(HBasicBlock* block)
       : LGap(block), replacement_(NULL) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Label, "label")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int block_id() const { return block()->block_id(); }
   bool is_loop_header() const { return block()->IsLoopHeader(); }
@@ -465,7 +457,7 @@
 
 class LParameter FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const { return false; }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
 };
 
@@ -484,30 +476,33 @@
 
 
 class LTailCallThroughMegamorphicCache FINAL
-    : public LTemplateInstruction<0, 3, 0> {
+    : public LTemplateInstruction<0, 5, 0> {
  public:
-  explicit LTailCallThroughMegamorphicCache(LOperand* context,
-                                            LOperand* receiver,
-                                            LOperand* name) {
+  LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
+                                   LOperand* name, LOperand* slot,
+                                   LOperand* vector) {
     inputs_[0] = context;
     inputs_[1] = receiver;
     inputs_[2] = name;
+    inputs_[3] = slot;
+    inputs_[4] = vector;
   }
 
   LOperand* context() { return inputs_[0]; }
   LOperand* receiver() { return inputs_[1]; }
   LOperand* name() { return inputs_[2]; }
+  LOperand* slot() { return inputs_[3]; }
+  LOperand* vector() { return inputs_[4]; }
 
   DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
                                "tail-call-through-megamorphic-cache")
   DECLARE_HYDROGEN_ACCESSOR(TailCallThroughMegamorphicCache)
 };
 
+
 class LUnknownOSRValue FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
 };
 
@@ -517,7 +512,7 @@
  public:
   LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
 
-  virtual bool IsControl() const FINAL OVERRIDE { return true; }
+  bool IsControl() const FINAL { return true; }
 
   int SuccessorCount() { return hydrogen()->SuccessorCount(); }
   HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
@@ -606,7 +601,7 @@
   LOperand* length() { return inputs_[1]; }
   LOperand* index() { return inputs_[2]; }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -869,7 +864,7 @@
     return hydrogen()->representation().IsDouble();
   }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1053,7 +1048,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1070,7 +1065,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1085,7 +1080,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1103,7 +1098,7 @@
                                "is-undetectable-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1125,7 +1120,7 @@
 
   Token::Value op() const { return hydrogen()->token(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1141,7 +1136,7 @@
                                "has-instance-type-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1171,7 +1166,7 @@
                                "has-cached-array-index-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1189,7 +1184,7 @@
                                "class-of-test-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1401,7 +1396,7 @@
   DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
   DECLARE_HYDROGEN_ACCESSOR(Branch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1546,11 +1541,9 @@
   LOperand* left() { return inputs_[0]; }
   LOperand* right() { return inputs_[1]; }
 
-  virtual Opcode opcode() const OVERRIDE {
-    return LInstruction::kArithmeticD;
-  }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticD; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
  private:
   Token::Value op_;
@@ -1574,11 +1567,9 @@
   LOperand* right() { return inputs_[2]; }
   Token::Value op() const { return op_; }
 
-  virtual Opcode opcode() const OVERRIDE {
-    return LInstruction::kArithmeticT;
-  }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticT; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
  private:
   Token::Value op_;
@@ -1687,7 +1678,7 @@
   DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
   DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   uint32_t base_offset() const { return hydrogen()->base_offset(); }
 };
 
@@ -1768,7 +1759,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1787,7 +1778,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1826,7 +1817,7 @@
   LOperand* function() { return inputs_[0]; }
   LOperand* code_object() { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
   DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
@@ -1843,7 +1834,7 @@
   LOperand* base_object() const { return inputs_[0]; }
   LOperand* offset() const { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
 };
@@ -1887,7 +1878,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
   DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1907,11 +1898,12 @@
 
   const CallInterfaceDescriptor descriptor() { return descriptor_; }
 
- private:
-  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
   DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+ private:
+  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 
@@ -1919,11 +1911,11 @@
   ZoneList<LOperand*> inputs_;
 
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return inputs_.length(); }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return inputs_.length(); }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return 0; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return NULL; }
+  int TempCount() FINAL { return 0; }
+  LOperand* TempAt(int i) FINAL { return NULL; }
 };
 
 
@@ -1940,7 +1932,7 @@
   DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
   DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1976,7 +1968,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
   DECLARE_HYDROGEN_ACCESSOR(CallNew)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1995,7 +1987,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
   DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -2012,7 +2004,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
   DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
 
-  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
+  bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
     return save_doubles() == kDontSaveFPRegs;
   }
 
@@ -2206,7 +2198,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Representation representation() const {
     return hydrogen()->field_representation();
@@ -2229,7 +2221,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Handle<Object> name() const { return hydrogen()->name(); }
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
@@ -2261,7 +2253,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   bool NeedsCanonicalization() {
     if (hydrogen()->value()->IsAdd() || hydrogen()->value()->IsSub() ||
         hydrogen()->value()->IsMul() || hydrogen()->value()->IsDiv()) {
@@ -2293,7 +2285,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
@@ -2317,7 +2309,7 @@
                                "transition-elements-kind")
   DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
   Handle<Map> transitioned_map() {
@@ -2611,7 +2603,7 @@
 
   Handle<String> type_literal() { return hydrogen()->type_literal(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -2632,9 +2624,7 @@
  public:
   LOsrEntry() {}
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
 };
 
@@ -2839,7 +2829,7 @@
 
   // An input operand in register, stack slot or a constant operand.
   // Will not be moved to a register even if one is freely available.
-  virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
+  MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
 
   // Temporary operand that must be in a register.
   MUST_USE_RESULT LUnallocated* TempRegister();
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index a06ed73..9d9591b 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -27,9 +27,9 @@
         deopt_mode_(mode) { }
   virtual ~SafepointGenerator() {}
 
-  virtual void BeforeCall(int call_size) const OVERRIDE {}
+  void BeforeCall(int call_size) const OVERRIDE {}
 
-  virtual void AfterCall() const OVERRIDE {
+  void AfterCall() const OVERRIDE {
     codegen_->RecordSafepoint(pointers_, deopt_mode_);
   }
 
@@ -1158,7 +1158,7 @@
     __ and_(dividend, dividend, Operand(mask));
     __ rsb(dividend, dividend, Operand::Zero(), SetCC);
     if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      DeoptimizeIf(eq, instr);
+      DeoptimizeIf(eq, instr, "minus zero");
     }
     __ b(&done);
   }
@@ -1176,7 +1176,7 @@
   DCHECK(!dividend.is(result));
 
   if (divisor == 0) {
-    DeoptimizeIf(al, instr);
+    DeoptimizeIf(al, instr, "division by zero");
     return;
   }
 
@@ -1191,7 +1191,7 @@
     Label remainder_not_zero;
     __ b(ne, &remainder_not_zero);
     __ cmp(dividend, Operand::Zero());
-    DeoptimizeIf(lt, instr);
+    DeoptimizeIf(lt, instr, "minus zero");
     __ bind(&remainder_not_zero);
   }
 }
@@ -1211,7 +1211,7 @@
     // case because we can't return a NaN.
     if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
       __ cmp(right_reg, Operand::Zero());
-      DeoptimizeIf(eq, instr);
+      DeoptimizeIf(eq, instr, "division by zero");
     }
 
     // Check for kMinInt % -1, sdiv will return kMinInt, which is not what we
@@ -1222,7 +1222,7 @@
       __ b(ne, &no_overflow_possible);
       __ cmp(right_reg, Operand(-1));
       if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
-        DeoptimizeIf(eq, instr);
+        DeoptimizeIf(eq, instr, "minus zero");
       } else {
         __ b(ne, &no_overflow_possible);
         __ mov(result_reg, Operand::Zero());
@@ -1243,7 +1243,7 @@
       __ cmp(result_reg, Operand::Zero());
       __ b(ne, &done);
       __ cmp(left_reg, Operand::Zero());
-      DeoptimizeIf(lt, instr);
+      DeoptimizeIf(lt, instr, "minus zero");
     }
     __ bind(&done);
 
@@ -1268,7 +1268,7 @@
     // NaN.
     if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
       __ cmp(right_reg, Operand::Zero());
-      DeoptimizeIf(eq, instr);
+      DeoptimizeIf(eq, instr, "division by zero");
     }
 
     __ Move(result_reg, left_reg);
@@ -1298,7 +1298,7 @@
     if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
       __ b(ne, &done);
       __ cmp(left_reg, Operand::Zero());
-      DeoptimizeIf(mi, instr);
+      DeoptimizeIf(mi, instr, "minus zero");
     }
     __ bind(&done);
   }
@@ -1316,19 +1316,19 @@
   HDiv* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ cmp(dividend, Operand::Zero());
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "minus zero");
   }
   // Check for (kMinInt / -1).
   if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
     __ cmp(dividend, Operand(kMinInt));
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "overflow");
   }
   // Deoptimize if remainder will not be 0.
   if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
       divisor != 1 && divisor != -1) {
     int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
     __ tst(dividend, Operand(mask));
-    DeoptimizeIf(ne, instr);
+    DeoptimizeIf(ne, instr, "lost precision");
   }
 
   if (divisor == -1) {  // Nice shortcut, not needed for correctness.
@@ -1356,7 +1356,7 @@
   DCHECK(!dividend.is(result));
 
   if (divisor == 0) {
-    DeoptimizeIf(al, instr);
+    DeoptimizeIf(al, instr, "division by zero");
     return;
   }
 
@@ -1364,7 +1364,7 @@
   HDiv* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ cmp(dividend, Operand::Zero());
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "minus zero");
   }
 
   __ TruncatingDiv(result, dividend, Abs(divisor));
@@ -1374,7 +1374,7 @@
     __ mov(ip, Operand(divisor));
     __ smull(scratch0(), ip, result, ip);
     __ sub(scratch0(), scratch0(), dividend, SetCC);
-    DeoptimizeIf(ne, instr);
+    DeoptimizeIf(ne, instr, "lost precision");
   }
 }
 
@@ -1389,7 +1389,7 @@
   // Check for x / 0.
   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
     __ cmp(divisor, Operand::Zero());
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "division by zero");
   }
 
   // Check for (0 / -x) that will produce negative zero.
@@ -1401,7 +1401,7 @@
     }
     __ b(pl, &positive);
     __ cmp(dividend, Operand::Zero());
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "minus zero");
     __ bind(&positive);
   }
 
@@ -1413,7 +1413,7 @@
     // support because, on ARM, sdiv kMinInt, -1 -> kMinInt.
     __ cmp(dividend, Operand(kMinInt));
     __ cmp(divisor, Operand(-1), eq);
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "overflow");
   }
 
   if (CpuFeatures::IsSupported(SUDIV)) {
@@ -1436,7 +1436,7 @@
     Register remainder = scratch0();
     __ Mls(remainder, result, divisor, dividend);
     __ cmp(remainder, Operand::Zero());
-    DeoptimizeIf(ne, instr);
+    DeoptimizeIf(ne, instr, "lost precision");
   }
 }
 
@@ -1487,13 +1487,13 @@
   // If the divisor is negative, we have to negate and handle edge cases.
   __ rsb(result, dividend, Operand::Zero(), SetCC);
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "minus zero");
   }
 
   // Dividing by -1 is basically negation, unless we overflow.
   if (divisor == -1) {
     if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
-      DeoptimizeIf(vs, instr);
+      DeoptimizeIf(vs, instr, "overflow");
     }
     return;
   }
@@ -1516,7 +1516,7 @@
   DCHECK(!dividend.is(result));
 
   if (divisor == 0) {
-    DeoptimizeIf(al, instr);
+    DeoptimizeIf(al, instr, "division by zero");
     return;
   }
 
@@ -1524,7 +1524,7 @@
   HMathFloorOfDiv* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
     __ cmp(dividend, Operand::Zero());
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "minus zero");
   }
 
   // Easy case: We need no dynamic check for the dividend and the flooring
@@ -1565,7 +1565,7 @@
   // Check for x / 0.
   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
     __ cmp(right, Operand::Zero());
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "division by zero");
   }
 
   // Check for (0 / -x) that will produce negative zero.
@@ -1577,7 +1577,7 @@
     }
     __ b(pl, &positive);
     __ cmp(left, Operand::Zero());
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "minus zero");
     __ bind(&positive);
   }
 
@@ -1589,7 +1589,7 @@
     // support because, on ARM, sdiv kMinInt, -1 -> kMinInt.
     __ cmp(left, Operand(kMinInt));
     __ cmp(right, Operand(-1), eq);
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "overflow");
   }
 
   if (CpuFeatures::IsSupported(SUDIV)) {
@@ -1635,14 +1635,14 @@
       // The case of a null constant will be handled separately.
       // If constant is negative and left is null, the result should be -0.
       __ cmp(left, Operand::Zero());
-      DeoptimizeIf(eq, instr);
+      DeoptimizeIf(eq, instr, "minus zero");
     }
 
     switch (constant) {
       case -1:
         if (overflow) {
           __ rsb(result, left, Operand::Zero(), SetCC);
-          DeoptimizeIf(vs, instr);
+          DeoptimizeIf(vs, instr, "overflow");
         } else {
           __ rsb(result, left, Operand::Zero());
         }
@@ -1652,7 +1652,7 @@
           // If left is strictly negative and the constant is null, the
           // result is -0. Deoptimize if required, otherwise return 0.
           __ cmp(left, Operand::Zero());
-          DeoptimizeIf(mi, instr);
+          DeoptimizeIf(mi, instr, "minus zero");
         }
         __ mov(result, Operand::Zero());
         break;
@@ -1702,7 +1702,7 @@
         __ smull(result, scratch, left, right);
       }
       __ cmp(scratch, Operand(result, ASR, 31));
-      DeoptimizeIf(ne, instr);
+      DeoptimizeIf(ne, instr, "overflow");
     } else {
       if (instr->hydrogen()->representation().IsSmi()) {
         __ SmiUntag(result, left);
@@ -1718,7 +1718,7 @@
       __ b(pl, &done);
       // Bail out if the result is minus zero.
       __ cmp(result, Operand::Zero());
-      DeoptimizeIf(eq, instr);
+      DeoptimizeIf(eq, instr, "minus zero");
       __ bind(&done);
     }
   }
@@ -1781,7 +1781,7 @@
       case Token::SHR:
         if (instr->can_deopt()) {
           __ mov(result, Operand(left, LSR, scratch), SetCC);
-          DeoptimizeIf(mi, instr);
+          DeoptimizeIf(mi, instr, "negative value");
         } else {
           __ mov(result, Operand(left, LSR, scratch));
         }
@@ -1818,7 +1818,7 @@
         } else {
           if (instr->can_deopt()) {
             __ tst(left, Operand(0x80000000));
-            DeoptimizeIf(ne, instr);
+            DeoptimizeIf(ne, instr, "negative value");
           }
           __ Move(result, left);
         }
@@ -1833,7 +1833,7 @@
             } else {
               __ SmiTag(result, left, SetCC);
             }
-            DeoptimizeIf(vs, instr);
+            DeoptimizeIf(vs, instr, "overflow");
           } else {
             __ mov(result, Operand(left, LSL, shift_count));
           }
@@ -1865,7 +1865,7 @@
   }
 
   if (can_overflow) {
-    DeoptimizeIf(vs, instr);
+    DeoptimizeIf(vs, instr, "overflow");
   }
 }
 
@@ -1886,7 +1886,7 @@
   }
 
   if (can_overflow) {
-    DeoptimizeIf(vs, instr);
+    DeoptimizeIf(vs, instr, "overflow");
   }
 }
 
@@ -1940,9 +1940,9 @@
   DCHECK(!scratch.is(object));
 
   __ SmiTst(object);
-  DeoptimizeIf(eq, instr);
+  DeoptimizeIf(eq, instr, "Smi");
   __ CompareObjectType(object, scratch, scratch, JS_DATE_TYPE);
-  DeoptimizeIf(ne, instr);
+  DeoptimizeIf(ne, instr, "not a date object");
 
   if (index->value() == 0) {
     __ ldr(result, FieldMemOperand(object, JSDate::kValueOffset));
@@ -2059,7 +2059,7 @@
   }
 
   if (can_overflow) {
-    DeoptimizeIf(vs, instr);
+    DeoptimizeIf(vs, instr, "overflow");
   }
 }
 
@@ -2285,7 +2285,7 @@
       } else if (expected.NeedsMap()) {
         // If we need a map later and have a Smi -> deopt.
         __ SmiTst(reg);
-        DeoptimizeIf(eq, instr);
+        DeoptimizeIf(eq, instr, "Smi");
       }
 
       const Register map = scratch0();
@@ -2341,7 +2341,7 @@
       if (!expected.IsGeneric()) {
         // We've seen something for the first time -> deopt.
         // This can only happen if we are not generic already.
-        DeoptimizeIf(al, instr);
+        DeoptimizeIf(al, instr, "unexpected object");
       }
     }
   }
@@ -2785,11 +2785,11 @@
     DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
                                   LInstanceOfKnownGlobal* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_,
                                                  &load_bool_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
     Label* map_check() { return &map_check_; }
     Label* load_bool() { return &load_bool_; }
 
@@ -2964,6 +2964,7 @@
         __ add(sp, sp, Operand(sp_delta));
       }
     } else {
+      DCHECK(info()->IsStub());  // Functions would need to drop one more value.
       Register reg = ToRegister(instr->parameter_count());
       // The argument count parameter is a smi
       __ SmiUntag(reg);
@@ -2986,7 +2987,7 @@
   if (instr->hydrogen()->RequiresHoleCheck()) {
     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
     __ cmp(result, ip);
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "hole");
   }
 }
 
@@ -2994,13 +2995,18 @@
 template <class T>
 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
   DCHECK(FLAG_vector_ics);
-  Register vector = ToRegister(instr->temp_vector());
-  DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister()));
-  __ Move(vector, instr->hydrogen()->feedback_vector());
+  Register vector_register = ToRegister(instr->temp_vector());
+  Register slot_register = VectorLoadICDescriptor::SlotRegister();
+  DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
+  DCHECK(slot_register.is(r0));
+
+  AllowDeferredHandleDereference vector_structure_check;
+  Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
+  __ Move(vector_register, vector);
   // No need to allocate this register.
-  DCHECK(VectorLoadICDescriptor::SlotRegister().is(r0));
-  __ mov(VectorLoadICDescriptor::SlotRegister(),
-         Operand(Smi::FromInt(instr->hydrogen()->slot())));
+  FeedbackVectorICSlot slot = instr->hydrogen()->slot();
+  int index = vector->GetIndex(slot);
+  __ mov(slot_register, Operand(Smi::FromInt(index)));
 }
 
 
@@ -3015,7 +3021,7 @@
     EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
+  Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3036,7 +3042,7 @@
     Register payload = ToRegister(instr->temp());
     __ ldr(payload, FieldMemOperand(cell, Cell::kValueOffset));
     __ CompareRoot(payload, Heap::kTheHoleValueRootIndex);
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "hole");
   }
 
   // Store the value.
@@ -3053,7 +3059,7 @@
     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
     __ cmp(result, ip);
     if (instr->hydrogen()->DeoptimizesOnHole()) {
-      DeoptimizeIf(eq, instr);
+      DeoptimizeIf(eq, instr, "hole");
     } else {
       __ mov(result, Operand(factory()->undefined_value()), LeaveCC, eq);
     }
@@ -3074,7 +3080,7 @@
     __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
     __ cmp(scratch, ip);
     if (instr->hydrogen()->DeoptimizesOnHole()) {
-      DeoptimizeIf(eq, instr);
+      DeoptimizeIf(eq, instr, "hole");
     } else {
       __ b(ne, &skip_assignment);
     }
@@ -3137,7 +3143,8 @@
   if (FLAG_vector_ics) {
     EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
+  Handle<Code> ic =
+      CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
 }
 
@@ -3154,7 +3161,7 @@
   // Check that the function has a prototype or an initial map.
   __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
   __ cmp(result, ip);
-  DeoptimizeIf(eq, instr);
+  DeoptimizeIf(eq, instr, "hole");
 
   // If the function does not have an initial map, we're done.
   Label done;
@@ -3280,7 +3287,7 @@
         __ ldr(result, mem_operand);
         if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
           __ cmp(result, Operand(0x80000000));
-          DeoptimizeIf(cs, instr);
+          DeoptimizeIf(cs, instr, "negative value");
         }
         break;
       case FLOAT32_ELEMENTS:
@@ -3333,7 +3340,7 @@
   if (instr->hydrogen()->RequiresHoleCheck()) {
     __ ldr(scratch, MemOperand(scratch, sizeof(kHoleNanLower32)));
     __ cmp(scratch, Operand(kHoleNanUpper32));
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "hole");
   }
 }
 
@@ -3367,11 +3374,11 @@
   if (instr->hydrogen()->RequiresHoleCheck()) {
     if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
       __ SmiTst(result);
-      DeoptimizeIf(ne, instr);
+      DeoptimizeIf(ne, instr, "not a Smi");
     } else {
       __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
       __ cmp(result, scratch);
-      DeoptimizeIf(eq, instr);
+      DeoptimizeIf(eq, instr, "hole");
     }
   }
 }
@@ -3428,7 +3435,7 @@
     EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
-  Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
+  Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
 }
 
@@ -3513,9 +3520,9 @@
 
   // Deoptimize if the receiver is not a JS object.
   __ SmiTst(receiver);
-  DeoptimizeIf(eq, instr);
+  DeoptimizeIf(eq, instr, "Smi");
   __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE);
-  DeoptimizeIf(lt, instr);
+  DeoptimizeIf(lt, instr, "not a JavaScript object");
 
   __ b(&result_in_receiver);
   __ bind(&global_object);
@@ -3550,7 +3557,7 @@
   // adaptor frame below it.
   const uint32_t kArgumentsLimit = 1 * KB;
   __ cmp(length, Operand(kArgumentsLimit));
-  DeoptimizeIf(hi, instr);
+  DeoptimizeIf(hi, instr, "too many arguments");
 
   // Push the receiver and use the register to keep the original
   // number of arguments.
@@ -3680,7 +3687,7 @@
   __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
   __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
   __ cmp(scratch, Operand(ip));
-  DeoptimizeIf(ne, instr);
+  DeoptimizeIf(ne, instr, "not a heap number");
 
   Label done;
   Register exponent = scratch0();
@@ -3748,7 +3755,7 @@
   // if input is positive.
   __ rsb(result, input, Operand::Zero(), SetCC, mi);
   // Deoptimize on overflow.
-  DeoptimizeIf(vs, instr);
+  DeoptimizeIf(vs, instr, "overflow");
 }
 
 
@@ -3758,10 +3765,11 @@
    public:
     DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LMathAbs* instr_;
   };
@@ -3794,7 +3802,7 @@
   Label done, exact;
 
   __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact);
-  DeoptimizeIf(al, instr);
+  DeoptimizeIf(al, instr, "lost precision or NaN");
 
   __ bind(&exact);
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
@@ -3802,7 +3810,7 @@
     __ cmp(result, Operand::Zero());
     __ b(ne, &done);
     __ cmp(input_high, Operand::Zero());
-    DeoptimizeIf(mi, instr);
+    DeoptimizeIf(mi, instr, "minus zero");
   }
   __ bind(&done);
 }
@@ -3827,7 +3835,8 @@
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     __ VmovHigh(input_high, input);
     __ cmp(input_high, Operand::Zero());
-    DeoptimizeIf(mi, instr);  // [-0.5, -0].
+    // [-0.5, -0].
+    DeoptimizeIf(mi, instr, "minus zero");
   }
   __ VFPCompareAndSetFlags(input, dot_five);
   __ mov(result, Operand(1), LeaveCC, eq);  // +0.5.
@@ -3841,7 +3850,7 @@
   // Reuse dot_five (double_scratch0) as we no longer need this value.
   __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(),
                    &done, &done);
-  DeoptimizeIf(al, instr);
+  DeoptimizeIf(al, instr, "lost precision or NaN");
   __ bind(&done);
 }
 
@@ -3905,7 +3914,7 @@
     __ ldr(r6, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset));
     __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
     __ cmp(r6, Operand(ip));
-    DeoptimizeIf(ne, instr);
+    DeoptimizeIf(ne, instr, "not a heap number");
     __ bind(&no_deopt);
     MathPowStub stub(isolate(), MathPowStub::TAGGED);
     __ CallStub(&stub);
@@ -3979,54 +3988,91 @@
   DCHECK(name.is(LoadDescriptor::NameRegister()));
   DCHECK(receiver.is(r1));
   DCHECK(name.is(r2));
+  Register scratch = r4;
+  Register extra = r5;
+  Register extra2 = r6;
+  Register extra3 = r9;
 
-  Register scratch = r3;
-  Register extra = r4;
-  Register extra2 = r5;
-  Register extra3 = r6;
+#ifdef DEBUG
+  Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg;
+  Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg;
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(slot, vector, scratch, extra, extra2, extra3));
+#endif
 
   // Important for the tail-call.
   bool must_teardown_frame = NeedsEagerFrame();
 
-  // The probe will tail call to a handler if found.
-  isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
-                                         must_teardown_frame, receiver, name,
-                                         scratch, extra, extra2, extra3);
+  if (!instr->hydrogen()->is_just_miss()) {
+    DCHECK(!instr->hydrogen()->is_keyed_load());
+
+    // The probe will tail call to a handler if found.
+    isolate()->stub_cache()->GenerateProbe(
+        masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
+        receiver, name, scratch, extra, extra2, extra3);
+  }
 
   // Tail call to miss if we ended up here.
   if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL);
-  LoadIC::GenerateMiss(masm());
+  if (instr->hydrogen()->is_keyed_load()) {
+    KeyedLoadIC::GenerateMiss(masm());
+  } else {
+    LoadIC::GenerateMiss(masm());
+  }
 }
 
 
 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
   DCHECK(ToRegister(instr->result()).is(r0));
 
-  LPointerMap* pointers = instr->pointer_map();
-  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+  if (instr->hydrogen()->IsTailCall()) {
+    if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL);
 
-  if (instr->target()->IsConstantOperand()) {
-    LConstantOperand* target = LConstantOperand::cast(instr->target());
-    Handle<Code> code = Handle<Code>::cast(ToHandle(target));
-    generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
-    PlatformInterfaceDescriptor* call_descriptor =
-        instr->descriptor().platform_specific_descriptor();
-    __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None(), al,
-            call_descriptor->storage_mode());
-  } else {
-    DCHECK(instr->target()->IsRegister());
-    Register target = ToRegister(instr->target());
-    generator.BeforeCall(__ CallSize(target));
-    // Make sure we don't emit any additional entries in the constant pool
-    // before the call to ensure that the CallCodeSize() calculated the correct
-    // number of instructions for the constant pool load.
-    {
-      ConstantPoolUnavailableScope constant_pool_unavailable(masm_);
-      __ add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      __ Jump(code, RelocInfo::CODE_TARGET);
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      // Make sure we don't emit any additional entries in the constant pool
+      // before the call to ensure that the CallCodeSize() calculated the
+      // correct
+      // number of instructions for the constant pool load.
+      {
+        ConstantPoolUnavailableScope constant_pool_unavailable(masm_);
+        __ add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
+      }
+      __ Jump(target);
     }
-    __ Call(target);
+  } else {
+    LPointerMap* pointers = instr->pointer_map();
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
+      PlatformInterfaceDescriptor* call_descriptor =
+          instr->descriptor().platform_specific_descriptor();
+      __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None(), al,
+              call_descriptor->storage_mode());
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      generator.BeforeCall(__ CallSize(target));
+      // Make sure we don't emit any additional entries in the constant pool
+      // before the call to ensure that the CallCodeSize() calculated the
+      // correct
+      // number of instructions for the constant pool load.
+      {
+        ConstantPoolUnavailableScope constant_pool_unavailable(masm_);
+        __ add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
+      }
+      __ Call(target);
+    }
+    generator.AfterCall();
   }
-  generator.AfterCall();
 }
 
 
@@ -4257,7 +4303,7 @@
     __ stop("eliminated bounds check failed");
     __ bind(&done);
   } else {
-    DeoptimizeIf(cc, instr);
+    DeoptimizeIf(cc, instr, "out of bounds");
   }
 }
 
@@ -4505,7 +4551,7 @@
   Register temp = ToRegister(instr->temp());
   Label no_memento_found;
   __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
-  DeoptimizeIf(eq, instr);
+  DeoptimizeIf(eq, instr, "memento found");
   __ bind(&no_memento_found);
 }
 
@@ -4526,10 +4572,9 @@
    public:
     DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredStringCharCodeAt(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredStringCharCodeAt(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStringCharCodeAt* instr_;
   };
@@ -4582,10 +4627,11 @@
    public:
     DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredStringCharFromCode(instr_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStringCharFromCode* instr_;
   };
@@ -4659,14 +4705,15 @@
    public:
     DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredNumberTagIU(instr_,
                                        instr_->value(),
                                        instr_->temp1(),
                                        instr_->temp2(),
                                        SIGNED_INT32);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagI* instr_;
   };
@@ -4686,14 +4733,15 @@
    public:
     DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredNumberTagIU(instr_,
                                        instr_->value(),
                                        instr_->temp1(),
                                        instr_->temp2(),
                                        UNSIGNED_INT32);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagU* instr_;
   };
@@ -4780,10 +4828,9 @@
    public:
     DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredNumberTagD(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredNumberTagD(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagD* instr_;
   };
@@ -4839,12 +4886,12 @@
   if (hchange->CheckFlag(HValue::kCanOverflow) &&
       hchange->value()->CheckFlag(HValue::kUint32)) {
     __ tst(input, Operand(0xc0000000));
-    DeoptimizeIf(ne, instr);
+    DeoptimizeIf(ne, instr, "overflow");
   }
   if (hchange->CheckFlag(HValue::kCanOverflow) &&
       !hchange->value()->CheckFlag(HValue::kUint32)) {
     __ SmiTag(output, input, SetCC);
-    DeoptimizeIf(vs, instr);
+    DeoptimizeIf(vs, instr, "overflow");
   } else {
     __ SmiTag(output, input);
   }
@@ -4858,7 +4905,7 @@
     STATIC_ASSERT(kHeapObjectTag == 1);
     // If the input is a HeapObject, SmiUntag will set the carry flag.
     __ SmiUntag(result, input, SetCC);
-    DeoptimizeIf(cs, instr);
+    DeoptimizeIf(cs, instr, "not a Smi");
   } else {
     __ SmiUntag(result, input);
   }
@@ -4886,7 +4933,7 @@
     if (can_convert_undefined_to_nan) {
       __ b(ne, &convert);
     } else {
-      DeoptimizeIf(ne, instr);
+      DeoptimizeIf(ne, instr, "not a heap number");
     }
     // load heap number
     __ vldr(result_reg, input_reg, HeapNumber::kValueOffset - kHeapObjectTag);
@@ -4896,7 +4943,7 @@
       __ b(ne, &done);
       __ VmovHigh(scratch, result_reg);
       __ cmp(scratch, Operand(HeapNumber::kSignMask));
-      DeoptimizeIf(eq, instr);
+      DeoptimizeIf(eq, instr, "minus zero");
     }
     __ jmp(&done);
     if (can_convert_undefined_to_nan) {
@@ -4904,7 +4951,7 @@
       // Convert undefined (and hole) to NaN.
       __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
       __ cmp(input_reg, Operand(ip));
-      DeoptimizeIf(ne, instr);
+      DeoptimizeIf(ne, instr, "not a heap number/undefined");
       __ LoadRoot(scratch, Heap::kNanValueRootIndex);
       __ vldr(result_reg, scratch, HeapNumber::kValueOffset - kHeapObjectTag);
       __ jmp(&done);
@@ -4972,7 +5019,7 @@
     __ bind(&check_false);
     __ LoadRoot(ip, Heap::kFalseValueRootIndex);
     __ cmp(scratch2, Operand(ip));
-    DeoptimizeIf(ne, instr, "cannot truncate");
+    DeoptimizeIf(ne, instr, "not a heap number/undefined/true/false");
     __ mov(input_reg, Operand::Zero());
   } else {
     DeoptimizeIf(ne, instr, "not a heap number");
@@ -4999,10 +5046,9 @@
    public:
     DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredTaggedToI(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredTaggedToI(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LTaggedToI* instr_;
   };
@@ -5057,14 +5103,14 @@
   } else {
     __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch);
     // Deoptimize if the input wasn't a int32 (inside a double).
-    DeoptimizeIf(ne, instr);
+    DeoptimizeIf(ne, instr, "lost precision or NaN");
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
       Label done;
       __ cmp(result_reg, Operand::Zero());
       __ b(ne, &done);
       __ VmovHigh(scratch1, double_input);
       __ tst(scratch1, Operand(HeapNumber::kSignMask));
-      DeoptimizeIf(ne, instr);
+      DeoptimizeIf(ne, instr, "minus zero");
       __ bind(&done);
     }
   }
@@ -5082,26 +5128,26 @@
   } else {
     __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch);
     // Deoptimize if the input wasn't a int32 (inside a double).
-    DeoptimizeIf(ne, instr);
+    DeoptimizeIf(ne, instr, "lost precision or NaN");
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
       Label done;
       __ cmp(result_reg, Operand::Zero());
       __ b(ne, &done);
       __ VmovHigh(scratch1, double_input);
       __ tst(scratch1, Operand(HeapNumber::kSignMask));
-      DeoptimizeIf(ne, instr);
+      DeoptimizeIf(ne, instr, "minus zero");
       __ bind(&done);
     }
   }
   __ SmiTag(result_reg, SetCC);
-  DeoptimizeIf(vs, instr);
+  DeoptimizeIf(vs, instr, "overflow");
 }
 
 
 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
   LOperand* input = instr->value();
   __ SmiTst(ToRegister(input));
-  DeoptimizeIf(ne, instr);
+  DeoptimizeIf(ne, instr, "not a Smi");
 }
 
 
@@ -5109,7 +5155,7 @@
   if (!instr->hydrogen()->value()->type().IsHeapObject()) {
     LOperand* input = instr->value();
     __ SmiTst(ToRegister(input));
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "Smi");
   }
 }
 
@@ -5130,13 +5176,13 @@
 
     // If there is only one type in the interval check for equality.
     if (first == last) {
-      DeoptimizeIf(ne, instr);
+      DeoptimizeIf(ne, instr, "wrong instance type");
     } else {
-      DeoptimizeIf(lo, instr);
+      DeoptimizeIf(lo, instr, "wrong instance type");
       // Omit check for the last type.
       if (last != LAST_TYPE) {
         __ cmp(scratch, Operand(last));
-        DeoptimizeIf(hi, instr);
+        DeoptimizeIf(hi, instr, "wrong instance type");
       }
     }
   } else {
@@ -5147,11 +5193,11 @@
     if (base::bits::IsPowerOfTwo32(mask)) {
       DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag));
       __ tst(scratch, Operand(mask));
-      DeoptimizeIf(tag == 0 ? ne : eq, instr);
+      DeoptimizeIf(tag == 0 ? ne : eq, instr, "wrong instance type");
     } else {
       __ and_(scratch, scratch, Operand(mask));
       __ cmp(scratch, Operand(tag));
-      DeoptimizeIf(ne, instr);
+      DeoptimizeIf(ne, instr, "wrong instance type");
     }
   }
 }
@@ -5170,7 +5216,7 @@
   } else {
     __ cmp(reg, Operand(object));
   }
-  DeoptimizeIf(ne, instr);
+  DeoptimizeIf(ne, instr, "value mismatch");
 }
 
 
@@ -5185,7 +5231,7 @@
     __ StoreToSafepointRegisterSlot(r0, scratch0());
   }
   __ tst(scratch0(), Operand(kSmiTagMask));
-  DeoptimizeIf(eq, instr);
+  DeoptimizeIf(eq, instr, "instance migration failed");
 }
 
 
@@ -5196,11 +5242,12 @@
         : LDeferredCode(codegen), instr_(instr), object_(object) {
       SetExit(check_maps());
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredInstanceMigration(instr_, object_);
     }
     Label* check_maps() { return &check_maps_; }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LCheckMaps* instr_;
     Label check_maps_;
@@ -5242,7 +5289,7 @@
   if (instr->hydrogen()->HasMigrationTarget()) {
     __ b(ne, deferred->entry());
   } else {
-    DeoptimizeIf(ne, instr);
+    DeoptimizeIf(ne, instr, "wrong map");
   }
 
   __ bind(&success);
@@ -5281,7 +5328,7 @@
   // Check for undefined. Undefined is converted to zero for clamping
   // conversions.
   __ cmp(input_reg, Operand(factory()->undefined_value()));
-  DeoptimizeIf(ne, instr);
+  DeoptimizeIf(ne, instr, "not a heap number/undefined");
   __ mov(result_reg, Operand::Zero());
   __ jmp(&done);
 
@@ -5324,10 +5371,9 @@
    public:
     DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredAllocate(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredAllocate(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LAllocate* instr_;
   };
@@ -5689,10 +5735,9 @@
    public:
     DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredStackCheck(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredStackCheck(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStackCheck* instr_;
   };
@@ -5751,19 +5796,19 @@
 void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
   __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
   __ cmp(r0, ip);
-  DeoptimizeIf(eq, instr);
+  DeoptimizeIf(eq, instr, "undefined");
 
   Register null_value = r5;
   __ LoadRoot(null_value, Heap::kNullValueRootIndex);
   __ cmp(r0, null_value);
-  DeoptimizeIf(eq, instr);
+  DeoptimizeIf(eq, instr, "null");
 
   __ SmiTst(r0);
-  DeoptimizeIf(eq, instr);
+  DeoptimizeIf(eq, instr, "Smi");
 
   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
   __ CompareObjectType(r0, r1, r1, LAST_JS_PROXY_TYPE);
-  DeoptimizeIf(le, instr);
+  DeoptimizeIf(le, instr, "wrong instance type");
 
   Label use_cache, call_runtime;
   __ CheckEnumCache(null_value, &call_runtime);
@@ -5779,7 +5824,7 @@
   __ ldr(r1, FieldMemOperand(r0, HeapObject::kMapOffset));
   __ LoadRoot(ip, Heap::kMetaMapRootIndex);
   __ cmp(r1, ip);
-  DeoptimizeIf(ne, instr);
+  DeoptimizeIf(ne, instr, "wrong map");
   __ bind(&use_cache);
 }
 
@@ -5801,7 +5846,7 @@
   __ ldr(result,
          FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
   __ cmp(result, Operand::Zero());
-  DeoptimizeIf(eq, instr);
+  DeoptimizeIf(eq, instr, "no cache");
 
   __ bind(&done);
 }
@@ -5812,7 +5857,7 @@
   Register map = ToRegister(instr->map());
   __ ldr(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset));
   __ cmp(map, scratch0());
-  DeoptimizeIf(ne, instr);
+  DeoptimizeIf(ne, instr, "wrong map");
 }
 
 
@@ -5845,10 +5890,11 @@
           object_(object),
           index_(index) {
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredLoadMutableDouble(instr_, result_, object_, index_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LLoadFieldByIndex* instr_;
     Register result_;
diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h
index cb137d1..65cc213 100644
--- a/src/arm/lithium-codegen-arm.h
+++ b/src/arm/lithium-codegen-arm.h
@@ -237,7 +237,7 @@
   void DeoptimizeIf(Condition condition, LInstruction* instr,
                     const char* detail, Deoptimizer::BailoutType bailout_type);
   void DeoptimizeIf(Condition condition, LInstruction* instr,
-                    const char* detail = NULL);
+                    const char* detail);
 
   void AddToTranslation(LEnvironment* environment,
                         Translation* translation,
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index c845a3d..0aa886b 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -15,7 +15,7 @@
 #include "src/cpu-profiler.h"
 #include "src/debug.h"
 #include "src/isolate-inl.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -967,7 +967,7 @@
   add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
   if (FLAG_enable_ool_constant_pool) {
     LoadConstantPoolPointerRegister();
-    set_constant_pool_available(true);
+    set_ool_constant_pool_available(true);
   }
 }
 
@@ -992,16 +992,16 @@
   }
   if (FLAG_enable_ool_constant_pool) {
     LoadConstantPoolPointerRegister();
-    set_constant_pool_available(true);
+    set_ool_constant_pool_available(true);
   }
 }
 
 
 void MacroAssembler::EnterFrame(StackFrame::Type type,
-                                bool load_constant_pool) {
+                                bool load_constant_pool_pointer_reg) {
   // r0-r3: preserved
   PushFixedFrame();
-  if (FLAG_enable_ool_constant_pool && load_constant_pool) {
+  if (FLAG_enable_ool_constant_pool && load_constant_pool_pointer_reg) {
     LoadConstantPoolPointerRegister();
   }
   mov(ip, Operand(Smi::FromInt(type)));
@@ -1699,11 +1699,12 @@
   }
 
   bind(&done);
-  // Check that the value is a normal property.
+  // Check that the value is a field property.
   // t2: elements + (index * kPointerSize)
   const int kDetailsOffset =
       SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
   ldr(t1, FieldMemOperand(t2, kDetailsOffset));
+  DCHECK_EQ(FIELD, 0);
   tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask)));
   b(ne, miss);
 
@@ -2251,23 +2252,37 @@
 }
 
 
-void MacroAssembler::DispatchMap(Register obj,
-                                 Register scratch,
-                                 Handle<Map> map,
-                                 Handle<Code> success,
-                                 SmiCheckType smi_check_type) {
+void MacroAssembler::DispatchWeakMap(Register obj, Register scratch1,
+                                     Register scratch2, Handle<WeakCell> cell,
+                                     Handle<Code> success,
+                                     SmiCheckType smi_check_type) {
   Label fail;
   if (smi_check_type == DO_SMI_CHECK) {
     JumpIfSmi(obj, &fail);
   }
-  ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
-  mov(ip, Operand(map));
-  cmp(scratch, ip);
+  ldr(scratch1, FieldMemOperand(obj, HeapObject::kMapOffset));
+  CmpWeakValue(scratch1, cell, scratch2);
   Jump(success, RelocInfo::CODE_TARGET, eq);
   bind(&fail);
 }
 
 
+void MacroAssembler::CmpWeakValue(Register value, Handle<WeakCell> cell,
+                                  Register scratch) {
+  mov(scratch, Operand(cell));
+  ldr(scratch, FieldMemOperand(scratch, WeakCell::kValueOffset));
+  cmp(value, scratch);
+}
+
+
+void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell,
+                                   Label* miss) {
+  mov(value, Operand(cell));
+  ldr(value, FieldMemOperand(value, WeakCell::kValueOffset));
+  JumpIfSmi(value, miss);
+}
+
+
 void MacroAssembler::TryGetFunctionPrototype(Register function,
                                              Register result,
                                              Register scratch,
@@ -3653,18 +3668,6 @@
 }
 
 
-void MacroAssembler::CheckMapDeprecated(Handle<Map> map,
-                                        Register scratch,
-                                        Label* if_deprecated) {
-  if (map->CanBeDeprecated()) {
-    mov(scratch, Operand(map));
-    ldr(scratch, FieldMemOperand(scratch, Map::kBitField3Offset));
-    tst(scratch, Operand(Map::Deprecated::kMask));
-    b(ne, if_deprecated);
-  }
-}
-
-
 void MacroAssembler::JumpIfBlack(Register object,
                                  Register scratch0,
                                  Register scratch1,
@@ -4071,21 +4074,22 @@
   DCHECK(!dividend.is(ip));
   DCHECK(!result.is(ip));
   base::MagicNumbersForDivision<uint32_t> mag =
-      base::SignedDivisionByConstant(static_cast<uint32_t>(divisor));
+      base::SignedDivisionByConstant(bit_cast<uint32_t>(divisor));
   mov(ip, Operand(mag.multiplier));
-  smull(ip, result, dividend, ip);
-  bool neg = (mag.multiplier & (static_cast<uint32_t>(1) << 31)) != 0;
+  bool neg = (mag.multiplier & (1U << 31)) != 0;
   if (divisor > 0 && neg) {
-    add(result, result, Operand(dividend));
-  }
-  if (divisor < 0 && !neg && mag.multiplier > 0) {
-    sub(result, result, Operand(dividend));
+    smmla(result, dividend, ip, dividend);
+  } else {
+    smmul(result, dividend, ip);
+    if (divisor < 0 && !neg && mag.multiplier > 0) {
+      sub(result, result, Operand(dividend));
+    }
   }
   if (mag.shift > 0) mov(result, Operand(result, ASR, mag.shift));
   add(result, result, Operand(dividend, LSR, 31));
 }
 
-
-} }  // namespace v8::internal
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_TARGET_ARCH_ARM
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index d2a1786..d83b64b 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -200,10 +200,6 @@
                      Condition cc,
                      Label* condition_met);
 
-  void CheckMapDeprecated(Handle<Map> map,
-                          Register scratch,
-                          Label* if_deprecated);
-
   // Check if object is in new space.  Jumps if the object is not in new space.
   // The register scratch can be object itself, but scratch will be clobbered.
   void JumpIfNotInNewSpace(Register object,
@@ -918,15 +914,19 @@
                 SmiCheckType smi_check_type);
 
 
-  // Check if the map of an object is equal to a specified map and branch to a
-  // specified target if equal. Skip the smi check if not required (object is
-  // known to be a heap object)
-  void DispatchMap(Register obj,
-                   Register scratch,
-                   Handle<Map> map,
-                   Handle<Code> success,
-                   SmiCheckType smi_check_type);
+  // Check if the map of an object is equal to a specified weak map and branch
+  // to a specified target if equal. Skip the smi check if not required
+  // (object is known to be a heap object)
+  void DispatchWeakMap(Register obj, Register scratch1, Register scratch2,
+                       Handle<WeakCell> cell, Handle<Code> success,
+                       SmiCheckType smi_check_type);
 
+  // Compare the given value and the value of weak cell.
+  void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch);
+
+  // Load the value of the weak cell in the value register. Branch to the given
+  // miss label if the weak cell was cleared.
+  void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss);
 
   // Compare the object in a register to a value from the root list.
   // Uses the ip register as scratch.
@@ -1401,7 +1401,8 @@
   }
 
   // Activation support.
-  void EnterFrame(StackFrame::Type type, bool load_constant_pool = false);
+  void EnterFrame(StackFrame::Type type,
+                  bool load_constant_pool_pointer_reg = false);
   // Returns the pc offset at which the frame ends.
   int LeaveFrame(StackFrame::Type type);
 
@@ -1530,71 +1531,6 @@
 };
 
 
-class FrameAndConstantPoolScope {
- public:
-  FrameAndConstantPoolScope(MacroAssembler* masm, StackFrame::Type type)
-      : masm_(masm),
-        type_(type),
-        old_has_frame_(masm->has_frame()),
-        old_constant_pool_available_(masm->is_constant_pool_available())  {
-    // We only want to enable constant pool access for non-manual frame scopes
-    // to ensure the constant pool pointer is valid throughout the scope.
-    DCHECK(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
-    masm->set_has_frame(true);
-    masm->set_constant_pool_available(true);
-    masm->EnterFrame(type, !old_constant_pool_available_);
-  }
-
-  ~FrameAndConstantPoolScope() {
-    masm_->LeaveFrame(type_);
-    masm_->set_has_frame(old_has_frame_);
-    masm_->set_constant_pool_available(old_constant_pool_available_);
-  }
-
-  // Normally we generate the leave-frame code when this object goes
-  // out of scope.  Sometimes we may need to generate the code somewhere else
-  // in addition.  Calling this will achieve that, but the object stays in
-  // scope, the MacroAssembler is still marked as being in a frame scope, and
-  // the code will be generated again when it goes out of scope.
-  void GenerateLeaveFrame() {
-    DCHECK(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
-    masm_->LeaveFrame(type_);
-  }
-
- private:
-  MacroAssembler* masm_;
-  StackFrame::Type type_;
-  bool old_has_frame_;
-  bool old_constant_pool_available_;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(FrameAndConstantPoolScope);
-};
-
-
-// Class for scoping the the unavailability of constant pool access.
-class ConstantPoolUnavailableScope {
- public:
-  explicit ConstantPoolUnavailableScope(MacroAssembler* masm)
-     : masm_(masm),
-       old_constant_pool_available_(masm->is_constant_pool_available()) {
-    if (FLAG_enable_ool_constant_pool) {
-      masm_->set_constant_pool_available(false);
-    }
-  }
-  ~ConstantPoolUnavailableScope() {
-    if (FLAG_enable_ool_constant_pool) {
-     masm_->set_constant_pool_available(old_constant_pool_available_);
-    }
-  }
-
- private:
-  MacroAssembler* masm_;
-  int old_constant_pool_available_;
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolUnavailableScope);
-};
-
-
 // -----------------------------------------------------------------------------
 // Static helper functions.
 
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index 0444025..e34c311 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -2629,7 +2629,89 @@
               UNIMPLEMENTED();
               break;
             case 1:
-              UNIMPLEMENTED();
+              if (instr->Bits(9, 6) == 1) {
+                if (instr->Bit(20) == 0) {
+                  if (instr->Bits(19, 16) == 0xF) {
+                    // Sxtb.
+                    int32_t rm_val = get_register(instr->RmValue());
+                    int32_t rotate = instr->Bits(11, 10);
+                    switch (rotate) {
+                      case 0:
+                        break;
+                      case 1:
+                        rm_val = (rm_val >> 8) | (rm_val << 24);
+                        break;
+                      case 2:
+                        rm_val = (rm_val >> 16) | (rm_val << 16);
+                        break;
+                      case 3:
+                        rm_val = (rm_val >> 24) | (rm_val << 8);
+                        break;
+                    }
+                    set_register(rd, static_cast<int8_t>(rm_val));
+                  } else {
+                    // Sxtab.
+                    int32_t rn_val = get_register(rn);
+                    int32_t rm_val = get_register(instr->RmValue());
+                    int32_t rotate = instr->Bits(11, 10);
+                    switch (rotate) {
+                      case 0:
+                        break;
+                      case 1:
+                        rm_val = (rm_val >> 8) | (rm_val << 24);
+                        break;
+                      case 2:
+                        rm_val = (rm_val >> 16) | (rm_val << 16);
+                        break;
+                      case 3:
+                        rm_val = (rm_val >> 24) | (rm_val << 8);
+                        break;
+                    }
+                    set_register(rd, rn_val + static_cast<int8_t>(rm_val));
+                  }
+                } else {
+                  if (instr->Bits(19, 16) == 0xF) {
+                    // Sxth.
+                    int32_t rm_val = get_register(instr->RmValue());
+                    int32_t rotate = instr->Bits(11, 10);
+                    switch (rotate) {
+                      case 0:
+                        break;
+                      case 1:
+                        rm_val = (rm_val >> 8) | (rm_val << 24);
+                        break;
+                      case 2:
+                        rm_val = (rm_val >> 16) | (rm_val << 16);
+                        break;
+                      case 3:
+                        rm_val = (rm_val >> 24) | (rm_val << 8);
+                        break;
+                    }
+                    set_register(rd, static_cast<int16_t>(rm_val));
+                  } else {
+                    // Sxtah.
+                    int32_t rn_val = get_register(rn);
+                    int32_t rm_val = get_register(instr->RmValue());
+                    int32_t rotate = instr->Bits(11, 10);
+                    switch (rotate) {
+                      case 0:
+                        break;
+                      case 1:
+                        rm_val = (rm_val >> 8) | (rm_val << 24);
+                        break;
+                      case 2:
+                        rm_val = (rm_val >> 16) | (rm_val << 16);
+                        break;
+                      case 3:
+                        rm_val = (rm_val >> 24) | (rm_val << 8);
+                        break;
+                    }
+                    set_register(rd, rn_val + static_cast<int16_t>(rm_val));
+                  }
+                }
+              } else {
+                UNREACHABLE();
+              }
               break;
             case 2:
               if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
@@ -2650,8 +2732,7 @@
                       rm_val = (rm_val >> 24) | (rm_val << 8);
                       break;
                   }
-                  set_register(rd,
-                               (rm_val & 0xFF) | (rm_val & 0xFF0000));
+                  set_register(rd, (rm_val & 0xFF) | (rm_val & 0xFF0000));
                 } else {
                   UNIMPLEMENTED();
                 }
@@ -2660,44 +2741,85 @@
               }
               break;
             case 3:
-              if ((instr->Bit(20) == 0) && (instr->Bits(9, 6) == 1)) {
-                if (instr->Bits(19, 16) == 0xF) {
-                  // Uxtb.
-                  uint32_t rm_val = get_register(instr->RmValue());
-                  int32_t rotate = instr->Bits(11, 10);
-                  switch (rotate) {
-                    case 0:
-                      break;
-                    case 1:
-                      rm_val = (rm_val >> 8) | (rm_val << 24);
-                      break;
-                    case 2:
-                      rm_val = (rm_val >> 16) | (rm_val << 16);
-                      break;
-                    case 3:
-                      rm_val = (rm_val >> 24) | (rm_val << 8);
-                      break;
+              if ((instr->Bits(9, 6) == 1)) {
+                if (instr->Bit(20) == 0) {
+                  if (instr->Bits(19, 16) == 0xF) {
+                    // Uxtb.
+                    uint32_t rm_val = get_register(instr->RmValue());
+                    int32_t rotate = instr->Bits(11, 10);
+                    switch (rotate) {
+                      case 0:
+                        break;
+                      case 1:
+                        rm_val = (rm_val >> 8) | (rm_val << 24);
+                        break;
+                      case 2:
+                        rm_val = (rm_val >> 16) | (rm_val << 16);
+                        break;
+                      case 3:
+                        rm_val = (rm_val >> 24) | (rm_val << 8);
+                        break;
+                    }
+                    set_register(rd, (rm_val & 0xFF));
+                  } else {
+                    // Uxtab.
+                    uint32_t rn_val = get_register(rn);
+                    uint32_t rm_val = get_register(instr->RmValue());
+                    int32_t rotate = instr->Bits(11, 10);
+                    switch (rotate) {
+                      case 0:
+                        break;
+                      case 1:
+                        rm_val = (rm_val >> 8) | (rm_val << 24);
+                        break;
+                      case 2:
+                        rm_val = (rm_val >> 16) | (rm_val << 16);
+                        break;
+                      case 3:
+                        rm_val = (rm_val >> 24) | (rm_val << 8);
+                        break;
+                    }
+                    set_register(rd, rn_val + (rm_val & 0xFF));
                   }
-                  set_register(rd, (rm_val & 0xFF));
                 } else {
-                  // Uxtab.
-                  uint32_t rn_val = get_register(rn);
-                  uint32_t rm_val = get_register(instr->RmValue());
-                  int32_t rotate = instr->Bits(11, 10);
-                  switch (rotate) {
-                    case 0:
-                      break;
-                    case 1:
-                      rm_val = (rm_val >> 8) | (rm_val << 24);
-                      break;
-                    case 2:
-                      rm_val = (rm_val >> 16) | (rm_val << 16);
-                      break;
-                    case 3:
-                      rm_val = (rm_val >> 24) | (rm_val << 8);
-                      break;
+                  if (instr->Bits(19, 16) == 0xF) {
+                    // Uxth.
+                    uint32_t rm_val = get_register(instr->RmValue());
+                    int32_t rotate = instr->Bits(11, 10);
+                    switch (rotate) {
+                      case 0:
+                        break;
+                      case 1:
+                        rm_val = (rm_val >> 8) | (rm_val << 24);
+                        break;
+                      case 2:
+                        rm_val = (rm_val >> 16) | (rm_val << 16);
+                        break;
+                      case 3:
+                        rm_val = (rm_val >> 24) | (rm_val << 8);
+                        break;
+                    }
+                    set_register(rd, (rm_val & 0xFFFF));
+                  } else {
+                    // Uxtah.
+                    uint32_t rn_val = get_register(rn);
+                    uint32_t rm_val = get_register(instr->RmValue());
+                    int32_t rotate = instr->Bits(11, 10);
+                    switch (rotate) {
+                      case 0:
+                        break;
+                      case 1:
+                        rm_val = (rm_val >> 8) | (rm_val << 24);
+                        break;
+                      case 2:
+                        rm_val = (rm_val >> 16) | (rm_val << 16);
+                        break;
+                      case 3:
+                        rm_val = (rm_val >> 24) | (rm_val << 8);
+                        break;
+                    }
+                    set_register(rd, rn_val + (rm_val & 0xFFFF));
                   }
-                  set_register(rd, rn_val + (rm_val & 0xFF));
                 }
               } else {
                 UNIMPLEMENTED();
@@ -2710,6 +2832,27 @@
       break;
     }
     case db_x: {
+      if (instr->Bits(22, 20) == 0x5) {
+        if (instr->Bits(7, 4) == 0x1) {
+          int rm = instr->RmValue();
+          int32_t rm_val = get_register(rm);
+          int rs = instr->RsValue();
+          int32_t rs_val = get_register(rs);
+          if (instr->Bits(15, 12) == 0xF) {
+            // SMMUL (in V8 notation matching ARM ISA format)
+            // Format(instr, "smmul'cond 'rn, 'rm, 'rs");
+            rn_val = base::bits::SignedMulHigh32(rm_val, rs_val);
+          } else {
+            // SMMLA (in V8 notation matching ARM ISA format)
+            // Format(instr, "smmla'cond 'rn, 'rm, 'rs, 'rd");
+            int rd = instr->RdValue();
+            int32_t rd_val = get_register(rd);
+            rn_val = base::bits::SignedMulHighAndAdd32(rm_val, rs_val, rd_val);
+          }
+          set_register(rn, rn_val);
+          return;
+        }
+      }
       if (FLAG_enable_sudiv) {
         if (instr->Bits(5, 4) == 0x1) {
           if ((instr->Bit(22) == 0x0) && (instr->Bit(20) == 0x1)) {
@@ -2720,15 +2863,12 @@
             int rs = instr->RsValue();
             int32_t rs_val = get_register(rs);
             int32_t ret_val = 0;
-            DCHECK(rs_val != 0);
             // udiv
             if (instr->Bit(21) == 0x1) {
-              ret_val = static_cast<int32_t>(static_cast<uint32_t>(rm_val) /
-                                             static_cast<uint32_t>(rs_val));
-            } else if ((rm_val == kMinInt) && (rs_val == -1)) {
-              ret_val = kMinInt;
+              ret_val = bit_cast<int32_t>(base::bits::UnsignedDiv32(
+                  bit_cast<uint32_t>(rm_val), bit_cast<uint32_t>(rs_val)));
             } else {
-              ret_val = rm_val / rs_val;
+              ret_val = base::bits::SignedDiv32(rm_val, rs_val);
             }
             set_register(rn, ret_val);
             return;
@@ -2939,6 +3079,12 @@
         } else {
           UNREACHABLE();  // Not used by v8.
         }
+      } else if (((instr->Opc2Value() == 0x6)) && (instr->Opc3Value() == 0x3)) {
+        // vrintz - truncate
+        double dm_value = get_double_from_d_register(vm);
+        double dd_value = trunc(dm_value);
+        dd_value = canonicalizeNaN(dd_value);
+        set_d_register_from_double(vd, dd_value);
       } else {
         UNREACHABLE();  // Not used by V8.
       }
@@ -3589,6 +3735,50 @@
         UNIMPLEMENTED();
       }
       break;
+    case 0x1D:
+      if (instr->Opc1Value() == 0x7 && instr->Opc3Value() == 0x1 &&
+          instr->Bits(11, 9) == 0x5 && instr->Bits(19, 18) == 0x2 &&
+          instr->Bit(8) == 0x1) {
+        int vm = instr->VFPMRegValue(kDoublePrecision);
+        int vd = instr->VFPDRegValue(kDoublePrecision);
+        double dm_value = get_double_from_d_register(vm);
+        double dd_value = 0.0;
+        int rounding_mode = instr->Bits(17, 16);
+        switch (rounding_mode) {
+          case 0x0:  // vrinta - round with ties to away from zero
+            dd_value = round(dm_value);
+            break;
+          case 0x1: {  // vrintn - round with ties to even
+            dd_value = std::floor(dm_value);
+            double error = dm_value - dd_value;
+            // Take care of correctly handling the range [-0.5, -0.0], which
+            // must yield -0.0.
+            if ((-0.5 <= dm_value) && (dm_value < 0.0)) {
+              dd_value = -0.0;
+              // If the error is greater than 0.5, or is equal to 0.5 and the
+              // integer result is odd, round up.
+            } else if ((error > 0.5) ||
+                       ((error == 0.5) && (fmod(dd_value, 2) != 0))) {
+              dd_value++;
+            }
+            break;
+          }
+          case 0x2:  // vrintp - ceil
+            dd_value = std::ceil(dm_value);
+            break;
+          case 0x3:  // vrintm - floor
+            dd_value = std::floor(dm_value);
+            break;
+          default:
+            UNREACHABLE();  // Case analysis is exhaustive.
+            break;
+        }
+        dd_value = canonicalizeNaN(dd_value);
+        set_d_register_from_double(vd, dd_value);
+      } else {
+        UNIMPLEMENTED();
+      }
+      break;
     default:
       UNIMPLEMENTED();
       break;
diff --git a/src/arm64/assembler-arm64-inl.h b/src/arm64/assembler-arm64-inl.h
index 5e1bed1..4547efe 100644
--- a/src/arm64/assembler-arm64-inl.h
+++ b/src/arm64/assembler-arm64-inl.h
@@ -503,7 +503,7 @@
     DCHECK(addrmode == Offset);
 
     regoffset_ = offset.reg();
-    shift_= offset.shift();
+    shift_ = offset.shift();
     shift_amount_ = offset.shift_amount();
 
     extend_ = NO_EXTEND;
@@ -520,7 +520,7 @@
     extend_ = offset.extend();
     shift_amount_ = offset.shift_amount();
 
-    shift_= NO_SHIFT;
+    shift_ = NO_SHIFT;
     offset_ = 0;
 
     // These assertions match those in the extended-register constructor.
diff --git a/src/arm64/assembler-arm64.cc b/src/arm64/assembler-arm64.cc
index c1213e9..770d425 100644
--- a/src/arm64/assembler-arm64.cc
+++ b/src/arm64/assembler-arm64.cc
@@ -44,22 +44,27 @@
 // CpuFeatures implementation.
 
 void CpuFeatures::ProbeImpl(bool cross_compile) {
-  if (cross_compile) {
-    // Always align csp in cross compiled code - this is safe and ensures that
-    // csp will always be aligned if it is enabled by probing at runtime.
-    if (FLAG_enable_always_align_csp) supported_ |= 1u << ALWAYS_ALIGN_CSP;
-  } else {
-    base::CPU cpu;
-    if (FLAG_enable_always_align_csp &&
-        (cpu.implementer() == base::CPU::NVIDIA || FLAG_debug_code)) {
-      supported_ |= 1u << ALWAYS_ALIGN_CSP;
-    }
+  // AArch64 has no configuration options, no further probing is required.
+  supported_ = 0;
+
+  // Only use statically determined features for cross compile (snapshot).
+  if (cross_compile) return;
+
+  // Probe for runtime features
+  base::CPU cpu;
+  if (cpu.implementer() == base::CPU::NVIDIA &&
+      cpu.variant() == base::CPU::NVIDIA_DENVER) {
+    supported_ |= 1u << COHERENT_CACHE;
   }
 }
 
 
 void CpuFeatures::PrintTarget() { }
-void CpuFeatures::PrintFeatures() { }
+
+
+void CpuFeatures::PrintFeatures() {
+  printf("COHERENT_CACHE=%d\n", CpuFeatures::IsSupported(COHERENT_CACHE));
+}
 
 
 // -----------------------------------------------------------------------------
@@ -612,9 +617,12 @@
 void Assembler::CheckLabelLinkChain(Label const * label) {
 #ifdef DEBUG
   if (label->is_linked()) {
+    static const int kMaxLinksToCheck = 64;  // Avoid O(n2) behaviour.
+    int links_checked = 0;
     int linkoffset = label->pos();
     bool end_of_chain = false;
     while (!end_of_chain) {
+      if (++links_checked > kMaxLinksToCheck) break;
       Instruction * link = InstructionAt(linkoffset);
       int linkpcoffset = link->ImmPCOffset();
       int prevlinkoffset = linkoffset + linkpcoffset;
@@ -1936,6 +1944,12 @@
 }
 
 
+void Assembler::frintp(const FPRegister& fd, const FPRegister& fn) {
+  DCHECK(fd.SizeInBits() == fn.SizeInBits());
+  FPDataProcessing1Source(fd, fn, FRINTP);
+}
+
+
 void Assembler::frintz(const FPRegister& fd,
                        const FPRegister& fn) {
   DCHECK(fd.SizeInBits() == fn.SizeInBits());
diff --git a/src/arm64/assembler-arm64.h b/src/arm64/assembler-arm64.h
index 82b4500..53496f3 100644
--- a/src/arm64/assembler-arm64.h
+++ b/src/arm64/assembler-arm64.h
@@ -276,6 +276,11 @@
       (kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1);
   static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; }
 
+  // TODO(turbofan): Proper float32 support.
+  static int NumAllocatableAliasedRegisters() {
+    return NumAllocatableRegisters();
+  }
+
   // Return true if the register is one that crankshaft can allocate.
   bool IsAllocatable() const {
     return (Bit() & kAllocatableFPRegisters) != 0;
@@ -1658,6 +1663,9 @@
   // FP round to integer (nearest with ties to even).
   void frintn(const FPRegister& fd, const FPRegister& fn);
 
+  // FP round to integer (towards plus infinity).
+  void frintp(const FPRegister& fd, const FPRegister& fn);
+
   // FP round to integer (towards zero.)
   void frintz(const FPRegister& fd, const FPRegister& fn);
 
diff --git a/src/arm64/builtins-arm64.cc b/src/arm64/builtins-arm64.cc
index 0013e24..9f140c2 100644
--- a/src/arm64/builtins-arm64.cc
+++ b/src/arm64/builtins-arm64.cc
@@ -10,7 +10,7 @@
 #include "src/debug.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -156,7 +156,7 @@
   __ Cbz(argc, &no_arguments);
   // First args = sp[(argc - 1) * 8].
   __ Sub(argc, argc, 1);
-  __ Claim(argc, kXRegSize);
+  __ Drop(argc, kXRegSize);
   // jssp now point to args[0], load and drop args[0] + receiver.
   Register arg = argc;
   __ Ldr(arg, MemOperand(jssp, 2 * kPointerSize, PostIndex));
@@ -367,13 +367,13 @@
             FieldMemOperand(init_map, Map::kBitField3Offset);
         // Check if slack tracking is enabled.
         __ Ldr(x4, bit_field3);
-        __ DecodeField<Map::ConstructionCount>(constructon_count, x4);
-        __ Cmp(constructon_count, Operand(JSFunction::kNoSlackTracking));
-        __ B(eq, &allocate);
+        __ DecodeField<Map::Counter>(constructon_count, x4);
+        __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd));
+        __ B(lt, &allocate);
         // Decrease generous allocation count.
-        __ Subs(x4, x4, Operand(1 << Map::ConstructionCount::kShift));
+        __ Subs(x4, x4, Operand(1 << Map::Counter::kShift));
         __ Str(x4, bit_field3);
-        __ Cmp(constructon_count, Operand(JSFunction::kFinishSlackTracking));
+        __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd));
         __ B(ne, &allocate);
 
         // Push the constructor and map to the stack, and the constructor again
@@ -381,7 +381,7 @@
         __ Push(constructor, init_map, constructor);
         __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
         __ Pop(init_map, constructor);
-        __ Mov(constructon_count, Operand(JSFunction::kNoSlackTracking));
+        __ Mov(constructon_count, Operand(Map::kSlackTrackingCounterEnd - 1));
         __ Bind(&allocate);
       }
 
@@ -434,8 +434,8 @@
         Label no_inobject_slack_tracking;
 
         // Check if slack tracking is enabled.
-        __ Cmp(constructon_count, Operand(JSFunction::kNoSlackTracking));
-        __ B(eq, &no_inobject_slack_tracking);
+        __ Cmp(constructon_count, Operand(Map::kSlackTrackingCounterEnd));
+        __ B(lt, &no_inobject_slack_tracking);
         constructon_count = NoReg;
 
         // Fill the pre-allocated fields with undef.
diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc
index 4978e5e..e773b53 100644
--- a/src/arm64/code-stubs-arm64.cc
+++ b/src/arm64/code-stubs-arm64.cc
@@ -14,7 +14,7 @@
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -1412,6 +1412,11 @@
 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
   Label miss;
   Register receiver = LoadDescriptor::ReceiverRegister();
+  // Ensure that the vector and slot registers won't be clobbered before
+  // calling the miss handler.
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(x10, x11, VectorLoadICDescriptor::VectorRegister(),
+                     VectorLoadICDescriptor::SlotRegister()));
 
   NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, x10,
                                                           x11, &miss);
@@ -1422,6 +1427,40 @@
 }
 
 
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+  // Return address is in lr.
+  Label miss;
+
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register index = LoadDescriptor::NameRegister();
+  Register result = x0;
+  Register scratch = x10;
+  DCHECK(!scratch.is(receiver) && !scratch.is(index));
+  DCHECK(!FLAG_vector_ics ||
+         (!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
+          result.is(VectorLoadICDescriptor::SlotRegister())));
+
+  // StringCharAtGenerator doesn't use the result register until it's passed
+  // the different miss possibilities. If it did, we would have a conflict
+  // when FLAG_vector_ics is true.
+  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+                                          &miss,  // When not a string.
+                                          &miss,  // When not a number.
+                                          &miss,  // When index out of range.
+                                          STRING_INDEX_IS_ARRAY_INDEX,
+                                          RECEIVER_IS_STRING);
+  char_at_generator.GenerateFast(masm);
+  __ Ret();
+
+  StubRuntimeCallHelper call_helper;
+  char_at_generator.GenerateSlow(masm, call_helper);
+
+  __ Bind(&miss);
+  PropertyAccessCompiler::TailCallBuiltin(
+      masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
+
+
 void InstanceofStub::Generate(MacroAssembler* masm) {
   // Stack on entry:
   // jssp[0]: function.
@@ -1569,7 +1608,7 @@
   __ Mov(result, res_false);
 
   // Null is not instance of anything.
-  __ Cmp(object_type, Operand(isolate()->factory()->null_value()));
+  __ Cmp(object, Operand(isolate()->factory()->null_value()));
   __ B(ne, &object_not_null);
   __ Ret();
 
@@ -2683,13 +2722,13 @@
 
   // A monomorphic miss (i.e, here the cache is not uninitialized) goes
   // megamorphic.
-  __ JumpIfRoot(scratch1, Heap::kUninitializedSymbolRootIndex, &initialize);
+  __ JumpIfRoot(scratch1, Heap::kuninitialized_symbolRootIndex, &initialize);
   // MegamorphicSentinel is an immortal immovable object (undefined) so no
   // write-barrier is needed.
   __ Bind(&megamorphic);
   __ Add(scratch1, feedback_vector,
          Operand::UntagSmiAndScale(index, kPointerSizeLog2));
-  __ LoadRoot(scratch2, Heap::kMegamorphicSymbolRootIndex);
+  __ LoadRoot(scratch2, Heap::kmegamorphic_symbolRootIndex);
   __ Str(scratch2, FieldMemOperand(scratch1, FixedArray::kHeaderSize));
   __ B(&done);
 
@@ -2988,6 +3027,10 @@
 
   // x1 - function
   // x3 - slot id (Smi)
+  const int with_types_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
+  const int generic_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
   Label extra_checks_or_miss, slow_start;
   Label slow, non_function, wrap, cont;
   Label have_js_function;
@@ -3036,24 +3079,72 @@
   }
 
   __ bind(&extra_checks_or_miss);
-  Label miss;
+  Label uninitialized, miss;
 
-  __ JumpIfRoot(x4, Heap::kMegamorphicSymbolRootIndex, &slow_start);
-  __ JumpIfRoot(x4, Heap::kUninitializedSymbolRootIndex, &miss);
+  __ JumpIfRoot(x4, Heap::kmegamorphic_symbolRootIndex, &slow_start);
 
-  if (!FLAG_trace_ic) {
-    // We are going megamorphic. If the feedback is a JSFunction, it is fine
-    // to handle it here. More complex cases are dealt with in the runtime.
-    __ AssertNotSmi(x4);
-    __ JumpIfNotObjectType(x4, x5, x5, JS_FUNCTION_TYPE, &miss);
-    __ Add(x4, feedback_vector,
-           Operand::UntagSmiAndScale(index, kPointerSizeLog2));
-    __ LoadRoot(x5, Heap::kMegamorphicSymbolRootIndex);
-    __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize));
-    __ B(&slow_start);
+  // The following cases attempt to handle MISS cases without going to the
+  // runtime.
+  if (FLAG_trace_ic) {
+    __ jmp(&miss);
   }
 
-  // We are here because tracing is on or we are going monomorphic.
+  __ JumpIfRoot(x4, Heap::kuninitialized_symbolRootIndex, &miss);
+
+  // We are going megamorphic. If the feedback is a JSFunction, it is fine
+  // to handle it here. More complex cases are dealt with in the runtime.
+  __ AssertNotSmi(x4);
+  __ JumpIfNotObjectType(x4, x5, x5, JS_FUNCTION_TYPE, &miss);
+  __ Add(x4, feedback_vector,
+         Operand::UntagSmiAndScale(index, kPointerSizeLog2));
+  __ LoadRoot(x5, Heap::kmegamorphic_symbolRootIndex);
+  __ Str(x5, FieldMemOperand(x4, FixedArray::kHeaderSize));
+  // We have to update statistics for runtime profiling.
+  __ Ldr(x4, FieldMemOperand(feedback_vector, with_types_offset));
+  __ Subs(x4, x4, Operand(Smi::FromInt(1)));
+  __ Str(x4, FieldMemOperand(feedback_vector, with_types_offset));
+  __ Ldr(x4, FieldMemOperand(feedback_vector, generic_offset));
+  __ Adds(x4, x4, Operand(Smi::FromInt(1)));
+  __ Str(x4, FieldMemOperand(feedback_vector, generic_offset));
+  __ B(&slow_start);
+
+  __ bind(&uninitialized);
+
+  // We are going monomorphic, provided we actually have a JSFunction.
+  __ JumpIfSmi(function, &miss);
+
+  // Goto miss case if we do not have a function.
+  __ JumpIfNotObjectType(function, x5, x5, JS_FUNCTION_TYPE, &miss);
+
+  // Make sure the function is not the Array() function, which requires special
+  // behavior on MISS.
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, x5);
+  __ Cmp(function, x5);
+  __ B(eq, &miss);
+
+  // Update stats.
+  __ Ldr(x4, FieldMemOperand(feedback_vector, with_types_offset));
+  __ Adds(x4, x4, Operand(Smi::FromInt(1)));
+  __ Str(x4, FieldMemOperand(feedback_vector, with_types_offset));
+
+  // Store the function.
+  __ Add(x4, feedback_vector,
+         Operand::UntagSmiAndScale(index, kPointerSizeLog2));
+  __ Str(function, FieldMemOperand(x4, FixedArray::kHeaderSize));
+
+  __ Add(x4, feedback_vector,
+         Operand::UntagSmiAndScale(index, kPointerSizeLog2));
+  __ Add(x4, x4, FixedArray::kHeaderSize - kHeapObjectTag);
+  __ Str(function, MemOperand(x4, 0));
+
+  // Update the write barrier.
+  __ Mov(x5, function);
+  __ RecordWrite(feedback_vector, x4, x5, kLRHasNotBeenSaved, kDontSaveFPRegs,
+                 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+  __ B(&have_js_function);
+
+  // We are here because tracing is on or we encountered a MISS case we can't
+  // handle here.
   __ bind(&miss);
   GenerateMiss(masm);
 
@@ -3097,14 +3188,16 @@
 
 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
   // If the receiver is a smi trigger the non-string case.
-  __ JumpIfSmi(object_, receiver_not_string_);
+  if (check_mode_ == RECEIVER_IS_UNKNOWN) {
+    __ JumpIfSmi(object_, receiver_not_string_);
 
-  // Fetch the instance type of the receiver into result register.
-  __ Ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
-  __ Ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
+    // Fetch the instance type of the receiver into result register.
+    __ Ldr(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
+    __ Ldrb(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
 
-  // If the receiver is not a string trigger the non-string case.
-  __ TestAndBranchIfAnySet(result_, kIsNotStringMask, receiver_not_string_);
+    // If the receiver is not a string trigger the non-string case.
+    __ TestAndBranchIfAnySet(result_, kIsNotStringMask, receiver_not_string_);
+  }
 
   // If the index is non-smi trigger the non-smi case.
   __ JumpIfNotSmi(index_, &index_not_smi_);
@@ -3782,9 +3875,9 @@
   // x12: input_type
   // x15: from (untagged)
   __ SmiTag(from);
-  StringCharAtGenerator generator(
-      input_string, from, result_length, x0,
-      &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
+  StringCharAtGenerator generator(input_string, from, result_length, x0,
+                                  &runtime, &runtime, &runtime,
+                                  STRING_INDEX_IS_NUMBER, RECEIVER_IS_STRING);
   generator.GenerateFast(masm);
   __ Drop(3);
   __ Ret();
@@ -3792,6 +3885,49 @@
 }
 
 
+void ToNumberStub::Generate(MacroAssembler* masm) {
+  // The ToNumber stub takes one argument in x0.
+  Label not_smi;
+  __ JumpIfNotSmi(x0, &not_smi);
+  __ Ret();
+  __ Bind(&not_smi);
+
+  Label not_heap_number;
+  __ Ldr(x1, FieldMemOperand(x0, HeapObject::kMapOffset));
+  __ Ldrb(x1, FieldMemOperand(x1, Map::kInstanceTypeOffset));
+  // x0: object
+  // x1: instance type
+  __ Cmp(x1, HEAP_NUMBER_TYPE);
+  __ B(ne, &not_heap_number);
+  __ Ret();
+  __ Bind(&not_heap_number);
+
+  Label not_string, slow_string;
+  __ Cmp(x1, FIRST_NONSTRING_TYPE);
+  __ B(hs, &not_string);
+  // Check if string has a cached array index.
+  __ Ldr(x2, FieldMemOperand(x0, String::kHashFieldOffset));
+  __ Tst(x2, Operand(String::kContainsCachedArrayIndexMask));
+  __ B(ne, &slow_string);
+  __ IndexFromHash(x2, x0);
+  __ Ret();
+  __ Bind(&slow_string);
+  __ Push(x0);  // Push argument.
+  __ TailCallRuntime(Runtime::kStringToNumber, 1, 1);
+  __ Bind(&not_string);
+
+  Label not_oddball;
+  __ Cmp(x1, ODDBALL_TYPE);
+  __ B(ne, &not_oddball);
+  __ Ldr(x0, FieldMemOperand(x0, Oddball::kToNumberOffset));
+  __ Ret();
+  __ Bind(&not_oddball);
+
+  __ Push(x0);  // Push argument.
+  __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
+}
+
+
 void StringHelper::GenerateFlatOneByteStringEquals(
     MacroAssembler* masm, Register left, Register right, Register scratch1,
     Register scratch2, Register scratch3) {
@@ -4236,18 +4372,10 @@
 }
 
 
-static unsigned int GetProfileEntryHookCallSize(MacroAssembler* masm) {
-  // The entry hook is a "BumpSystemStackPointer" instruction (sub),
-  // followed by a "Push lr" instruction, followed by a call.
-  unsigned int size =
-      Assembler::kCallSizeWithRelocation + (2 * kInstructionSize);
-  if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) {
-    // If ALWAYS_ALIGN_CSP then there will be an extra bic instruction in
-    // "BumpSystemStackPointer".
-    size += kInstructionSize;
-  }
-  return size;
-}
+// The entry hook is a "BumpSystemStackPointer" instruction (sub), followed by
+// a "Push lr" instruction, followed by a call.
+static const unsigned int kProfileEntryHookCallSize =
+    Assembler::kCallSizeWithRelocation + (2 * kInstructionSize);
 
 
 void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
@@ -4260,7 +4388,7 @@
     __ Push(lr);
     __ CallStub(&stub);
     DCHECK(masm->SizeOfCodeGeneratedSince(&entry_hook_call_start) ==
-           GetProfileEntryHookCallSize(masm));
+           kProfileEntryHookCallSize);
 
     __ Pop(lr);
   }
@@ -4278,7 +4406,7 @@
   const int kNumSavedRegs = kCallerSaved.Count();
 
   // Compute the function's address as the first argument.
-  __ Sub(x0, lr, GetProfileEntryHookCallSize(masm));
+  __ Sub(x0, lr, kProfileEntryHookCallSize);
 
 #if V8_HOST_ARCH_ARM64
   uintptr_t entry_hook =
diff --git a/src/arm64/code-stubs-arm64.h b/src/arm64/code-stubs-arm64.h
index 03dab5b..c9ee2c9 100644
--- a/src/arm64/code-stubs-arm64.h
+++ b/src/arm64/code-stubs-arm64.h
@@ -97,7 +97,7 @@
     INCREMENTAL_COMPACTION
   };
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
   static Mode GetMode(Code* stub) {
     // Find the mode depending on the first two instructions.
@@ -275,9 +275,9 @@
     kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
   };
 
-  virtual inline Major MajorKey() const FINAL OVERRIDE { return RecordWrite; }
+  inline Major MajorKey() const FINAL { return RecordWrite; }
 
-  virtual void Generate(MacroAssembler* masm) OVERRIDE;
+  void Generate(MacroAssembler* masm) OVERRIDE;
   void GenerateIncremental(MacroAssembler* masm, Mode mode);
   void CheckNeedsToInformIncrementalMarker(
       MacroAssembler* masm,
@@ -285,7 +285,7 @@
       Mode mode);
   void InformIncrementalMarker(MacroAssembler* masm);
 
-  void Activate(Code* code) {
+  void Activate(Code* code) OVERRIDE {
     code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
   }
 
@@ -328,7 +328,7 @@
   void GenerateCall(MacroAssembler* masm, Register target);
 
  private:
-  bool NeedsImmovableCode() { return true; }
+  bool NeedsImmovableCode() OVERRIDE { return true; }
 
   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
   DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub);
@@ -360,7 +360,7 @@
                                      Register scratch1,
                                      Register scratch2);
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
  private:
   static const int kInlinedProbes = 4;
diff --git a/src/arm64/codegen-arm64.cc b/src/arm64/codegen-arm64.cc
index 91eaba7..cda6e5b 100644
--- a/src/arm64/codegen-arm64.cc
+++ b/src/arm64/codegen-arm64.cc
@@ -290,15 +290,28 @@
   Register src_elements = x10;
   Register dst_elements = x11;
   Register dst_end = x12;
+  Register the_hole = x14;
+  __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex);
   __ Add(src_elements, elements,
          FixedDoubleArray::kHeaderSize - kHeapObjectTag);
   __ Add(dst_elements, array, FixedArray::kHeaderSize);
-  __ Add(array, array, kHeapObjectTag);
   __ Add(dst_end, dst_elements, Operand(length, LSL, kPointerSizeLog2));
 
-  Register the_hole = x14;
+  // Allocating heap numbers in the loop below can fail and cause a jump to
+  // gc_required. We can't leave a partly initialized FixedArray behind,
+  // so pessimistically fill it with holes now.
+  Label initialization_loop, initialization_loop_entry;
+  __ B(&initialization_loop_entry);
+  __ bind(&initialization_loop);
+  __ Str(the_hole, MemOperand(dst_elements, kPointerSize, PostIndex));
+  __ bind(&initialization_loop_entry);
+  __ Cmp(dst_elements, dst_end);
+  __ B(lt, &initialization_loop);
+
+  __ Add(dst_elements, array, FixedArray::kHeaderSize);
+  __ Add(array, array, kHeapObjectTag);
+
   Register heap_num_map = x15;
-  __ LoadRoot(the_hole, Heap::kTheHoleValueRootIndex);
   __ LoadRoot(heap_num_map, Heap::kHeapNumberMapRootIndex);
 
   Label entry;
diff --git a/src/arm64/cpu-arm64.cc b/src/arm64/cpu-arm64.cc
index 39beb6d..11ba7c9 100644
--- a/src/arm64/cpu-arm64.cc
+++ b/src/arm64/cpu-arm64.cc
@@ -43,6 +43,8 @@
 void CpuFeatures::FlushICache(void* address, size_t length) {
   if (length == 0) return;
 
+  if (CpuFeatures::IsSupported(COHERENT_CACHE)) return;
+
 #ifdef USE_SIMULATOR
   // TODO(all): consider doing some cache simulation to ensure every address
   // run has been synced.
diff --git a/src/arm64/debug-arm64.cc b/src/arm64/debug-arm64.cc
index f57d5b5..dae5a28 100644
--- a/src/arm64/debug-arm64.cc
+++ b/src/arm64/debug-arm64.cc
@@ -238,7 +238,11 @@
   // Calling convention for IC load (from ic-arm.cc).
   Register receiver = LoadDescriptor::ReceiverRegister();
   Register name = LoadDescriptor::NameRegister();
-  Generate_DebugBreakCallHelper(masm, receiver.Bit() | name.Bit(), 0, x10);
+  RegList regs = receiver.Bit() | name.Bit();
+  if (FLAG_vector_ics) {
+    regs |= VectorLoadICTrampolineDescriptor::SlotRegister().Bit();
+  }
+  Generate_DebugBreakCallHelper(masm, regs, 0, x10);
 }
 
 
diff --git a/src/arm64/delayed-masm-arm64.cc b/src/arm64/delayed-masm-arm64.cc
index c3bda91..b51e77e 100644
--- a/src/arm64/delayed-masm-arm64.cc
+++ b/src/arm64/delayed-masm-arm64.cc
@@ -16,8 +16,8 @@
 
 
 void DelayedMasm::StackSlotMove(LOperand* src, LOperand* dst) {
-  DCHECK(src->IsStackSlot());
-  DCHECK(dst->IsStackSlot());
+  DCHECK((src->IsStackSlot() && dst->IsStackSlot()) ||
+         (src->IsDoubleStackSlot() && dst->IsDoubleStackSlot()));
   MemOperand src_operand = cgen_->ToMemOperand(src);
   MemOperand dst_operand = cgen_->ToMemOperand(dst);
   if (pending_ == kStackSlotMove) {
diff --git a/src/arm64/deoptimizer-arm64.cc b/src/arm64/deoptimizer-arm64.cc
index d67dc8f..b83bbbe 100644
--- a/src/arm64/deoptimizer-arm64.cc
+++ b/src/arm64/deoptimizer-arm64.cc
@@ -21,6 +21,11 @@
 }
 
 
+void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
+  // Empty because there is no need for relocation information for the code
+  // patching in Deoptimizer::PatchCodeForDeoptimization below.
+}
+
 
 void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
   // Invalidate the relocation information, as it will become invalid by the
diff --git a/src/arm64/disasm-arm64.cc b/src/arm64/disasm-arm64.cc
index ac7cb37..36bad37 100644
--- a/src/arm64/disasm-arm64.cc
+++ b/src/arm64/disasm-arm64.cc
@@ -1695,7 +1695,7 @@
   DCHECK(format[0] == 'M');
   USE(format);
 
-  static const char* options[4][4] = {
+  static const char* const options[4][4] = {
     { "sy (0b0000)", "oshld", "oshst", "osh" },
     { "sy (0b0100)", "nshld", "nshst", "nsh" },
     { "sy (0b1000)", "ishld", "ishst", "ish" },
diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc
index 25a9efd..0d3d34b 100644
--- a/src/arm64/full-codegen-arm64.cc
+++ b/src/arm64/full-codegen-arm64.cc
@@ -196,10 +196,10 @@
     // Argument to NewContext is the function, which is still in x1.
     Comment cmnt(masm_, "[ Allocate context");
     bool need_write_barrier = true;
-    if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
+    if (FLAG_harmony_scoping && info->scope()->is_script_scope()) {
       __ Mov(x10, Operand(info->scope()->GetScopeInfo()));
       __ Push(x1, x10);
-      __ CallRuntime(Runtime::kNewGlobalContext, 2);
+      __ CallRuntime(Runtime::kNewScriptContext, 2);
     } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
       FastNewContextStub stub(isolate(), heap_slots);
       __ CallStub(&stub);
@@ -299,24 +299,26 @@
       }
       VisitDeclarations(scope()->declarations());
     }
-  }
 
-  { Comment cmnt(masm_, "[ Stack check");
-    PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
-    Label ok;
-    DCHECK(jssp.Is(__ StackPointer()));
-    __ CompareRoot(jssp, Heap::kStackLimitRootIndex);
-    __ B(hs, &ok);
-    PredictableCodeSizeScope predictable(masm_,
-                                         Assembler::kCallSizeWithRelocation);
-    __ Call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
-    __ Bind(&ok);
-  }
+    {
+      Comment cmnt(masm_, "[ Stack check");
+      PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
+      Label ok;
+      DCHECK(jssp.Is(__ StackPointer()));
+      __ CompareRoot(jssp, Heap::kStackLimitRootIndex);
+      __ B(hs, &ok);
+      PredictableCodeSizeScope predictable(masm_,
+                                           Assembler::kCallSizeWithRelocation);
+      __ Call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
+      __ Bind(&ok);
+    }
 
-  { Comment cmnt(masm_, "[ Body");
-    DCHECK(loop_depth() == 0);
-    VisitStatements(function()->body());
-    DCHECK(loop_depth() == 0);
+    {
+      Comment cmnt(masm_, "[ Body");
+      DCHECK(loop_depth() == 0);
+      VisitStatements(function()->body());
+      DCHECK(loop_depth() == 0);
+    }
   }
 
   // Always emit a 'return undefined' in case control fell off the end of
@@ -932,7 +934,7 @@
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
-  __ LoadContext(x1, scope_->ContextChainLength(scope_->GlobalScope()));
+  __ LoadContext(x1, scope_->ContextChainLength(scope_->ScriptScope()));
   __ Ldr(x1, ContextMemOperand(x1, variable->interface()->Index()));
   __ Ldr(x1, ContextMemOperand(x1, Context::EXTENSION_INDEX));
 
@@ -1097,7 +1099,7 @@
 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   ASM_LOCATION("FullCodeGenerator::VisitForInStatement");
   Comment cmnt(masm_, "[ ForInStatement");
-  int slot = stmt->ForInFeedbackSlot();
+  FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
   // TODO(all): This visitor probably needs better comments and a revisit.
   SetStatementPosition(stmt);
 
@@ -1107,6 +1109,7 @@
 
   // Get the object to enumerate over. If the object is null or undefined, skip
   // over the loop.  See ECMA-262 version 5, section 12.6.4.
+  SetExpressionPosition(stmt->enumerable());
   VisitForAccumulatorValue(stmt->enumerable());
   __ JumpIfRoot(x0, Heap::kUndefinedValueRootIndex, &exit);
   Register null_value = x15;
@@ -1124,6 +1127,7 @@
   __ Push(x0);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ Bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ Push(x0);
 
   // Check for proxies.
@@ -1147,6 +1151,7 @@
   __ Bind(&call_runtime);
   __ Push(x0);  // Duplicate the enumerable object on the stack.
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
 
   // If we got a map from the runtime call, we can do a fast
   // modification check. Otherwise, we got a fixed array, and we have
@@ -1181,7 +1186,8 @@
 
   __ LoadObject(x1, FeedbackVector());
   __ Mov(x10, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
-  __ Str(x10, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(slot)));
+  int vector_index = FeedbackVector()->GetIndex(slot);
+  __ Str(x10, FieldMemOperand(x1, FixedArray::OffsetOfElementAt(vector_index)));
 
   __ Mov(x1, Smi::FromInt(1));  // Smi indicates slow check.
   __ Peek(x10, 0);  // Get enumerated object.
@@ -1197,6 +1203,8 @@
   // Generate code for doing the condition check.
   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
   __ Bind(&loop);
+  SetExpressionPosition(stmt->each());
+
   // Load the current count to x0, load the length to x1.
   __ PeekPair(x0, x1, 0);
   __ Cmp(x0, x1);  // Compare to the array length.
@@ -1266,48 +1274,6 @@
 }
 
 
-void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
-  Comment cmnt(masm_, "[ ForOfStatement");
-  SetStatementPosition(stmt);
-
-  Iteration loop_statement(this, stmt);
-  increment_loop_depth();
-
-  // var iterator = iterable[Symbol.iterator]();
-  VisitForEffect(stmt->assign_iterator());
-
-  // Loop entry.
-  __ Bind(loop_statement.continue_label());
-
-  // result = iterator.next()
-  VisitForEffect(stmt->next_result());
-
-  // if (result.done) break;
-  Label result_not_done;
-  VisitForControl(stmt->result_done(),
-                  loop_statement.break_label(),
-                  &result_not_done,
-                  &result_not_done);
-  __ Bind(&result_not_done);
-
-  // each = result.value
-  VisitForEffect(stmt->assign_each());
-
-  // Generate code for the body of the loop.
-  Visit(stmt->body());
-
-  // Check stack before looping.
-  PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
-  EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
-  __ B(loop_statement.continue_label());
-
-  // Exit and decrement the loop depth.
-  PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
-  __ Bind(loop_statement.break_label());
-  decrement_loop_depth();
-}
-
-
 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
                                        bool pretenure) {
   // Use the fast case closure allocation code that allocates in new space for
@@ -1350,7 +1316,13 @@
   Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
   __ Mov(LoadDescriptor::NameRegister(), Operand(home_object_symbol));
 
-  CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  if (FLAG_vector_ics) {
+    __ Mov(VectorLoadICDescriptor::SlotRegister(),
+           SmiFromSlot(expr->HomeObjectFeedbackSlot()));
+    CallLoadIC(NOT_CONTEXTUAL);
+  } else {
+    CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  }
 
   __ Mov(x10, Operand(isolate()->factory()->undefined_value()));
   __ cmp(x0, x10);
@@ -1361,6 +1333,18 @@
 }
 
 
+void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
+                                                  int offset) {
+  if (NeedsHomeObject(initializer)) {
+    __ Peek(StoreDescriptor::ReceiverRegister(), 0);
+    __ Mov(StoreDescriptor::NameRegister(),
+           Operand(isolate()->factory()->home_object_symbol()));
+    __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize);
+    CallStoreIC();
+  }
+}
+
+
 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
                                                       TypeofState typeof_state,
                                                       Label* slow) {
@@ -1408,7 +1392,7 @@
   __ Mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
   if (FLAG_vector_ics) {
     __ Mov(VectorLoadICDescriptor::SlotRegister(),
-           Smi::FromInt(proxy->VariableFeedbackSlot()));
+           SmiFromSlot(proxy->VariableFeedbackSlot()));
   }
 
   ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL
@@ -1493,7 +1477,7 @@
       __ Mov(LoadDescriptor::NameRegister(), Operand(var->name()));
       if (FLAG_vector_ics) {
         __ Mov(VectorLoadICDescriptor::SlotRegister(),
-               Smi::FromInt(proxy->VariableFeedbackSlot()));
+               SmiFromSlot(proxy->VariableFeedbackSlot()));
       }
       CallLoadIC(CONTEXTUAL);
       context()->Plug(x0);
@@ -1671,6 +1655,7 @@
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in x0.
@@ -1699,6 +1684,8 @@
         DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
         // Fall through.
       case ObjectLiteral::Property::COMPUTED:
+        // It is safe to use [[Put]] here because the boilerplate already
+        // contains computed properties with an uninitialized value.
         if (key->value()->IsInternalizedString()) {
           if (property->emit_store()) {
             VisitForAccumulatorValue(value);
@@ -1707,6 +1694,14 @@
             __ Peek(StoreDescriptor::ReceiverRegister(), 0);
             CallStoreIC(key->LiteralFeedbackId());
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
+
+            if (NeedsHomeObject(value)) {
+              __ Mov(StoreDescriptor::ReceiverRegister(), x0);
+              __ Mov(StoreDescriptor::NameRegister(),
+                     Operand(isolate()->factory()->home_object_symbol()));
+              __ Peek(StoreDescriptor::ValueRegister(), 0);
+              CallStoreIC();
+            }
           } else {
             VisitForEffect(value);
           }
@@ -1718,6 +1713,7 @@
           __ Push(x0);
           VisitForStackValue(key);
           VisitForStackValue(value);
+          EmitSetHomeObjectIfNeeded(value, 2);
           __ Mov(x0, Smi::FromInt(SLOPPY));  // Strict mode
           __ Push(x0);
           __ CallRuntime(Runtime::kSetProperty, 4);
@@ -1732,7 +1728,7 @@
           __ Peek(x0, 0);
           __ Push(x0);
           VisitForStackValue(value);
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           VisitForEffect(value);
         }
@@ -1755,7 +1751,9 @@
       __ Push(x10);
       VisitForStackValue(it->first);
       EmitAccessor(it->second->getter);
+      EmitSetHomeObjectIfNeeded(it->second->getter, 2);
       EmitAccessor(it->second->setter);
+      EmitSetHomeObjectIfNeeded(it->second->setter, 3);
       __ Mov(x10, Smi::FromInt(NONE));
       __ Push(x10);
       __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
@@ -1862,16 +1860,8 @@
 
   Comment cmnt(masm_, "[ Assignment");
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
-  if (property != NULL) {
-    assign_type = (property->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(property);
 
   // Evaluate LHS expression.
   switch (assign_type) {
@@ -1887,6 +1877,30 @@
         VisitForStackValue(property->obj());
       }
       break;
+    case NAMED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        const Register scratch = x10;
+        __ Peek(scratch, kPointerSize);
+        __ Push(scratch, result_register());
+      }
+      break;
+    case KEYED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(property->key());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        const Register scratch1 = x10;
+        const Register scratch2 = x11;
+        __ Peek(scratch1, 2 * kPointerSize);
+        __ Peek(scratch2, kPointerSize);
+        __ Push(scratch1, scratch2, result_register());
+      }
+      break;
     case KEYED_PROPERTY:
       if (expr->is_compound()) {
         VisitForStackValue(property->obj());
@@ -1913,6 +1927,14 @@
           EmitNamedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
           break;
+        case NAMED_SUPER_PROPERTY:
+          EmitNamedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
+        case KEYED_SUPER_PROPERTY:
+          EmitKeyedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
         case KEYED_PROPERTY:
           EmitKeyedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
@@ -1959,6 +1981,14 @@
     case NAMED_PROPERTY:
       EmitNamedPropertyAssignment(expr);
       break;
+    case NAMED_SUPER_PROPERTY:
+      EmitNamedSuperPropertyStore(property);
+      context()->Plug(x0);
+      break;
+    case KEYED_SUPER_PROPERTY:
+      EmitKeyedSuperPropertyStore(property);
+      context()->Plug(x0);
+      break;
     case KEYED_PROPERTY:
       EmitKeyedPropertyAssignment(expr);
       break;
@@ -1974,7 +2004,7 @@
   __ Mov(LoadDescriptor::NameRegister(), Operand(key->value()));
   if (FLAG_vector_ics) {
     __ Mov(VectorLoadICDescriptor::SlotRegister(),
-           Smi::FromInt(prop->PropertyFeedbackSlot()));
+           SmiFromSlot(prop->PropertyFeedbackSlot()));
     CallLoadIC(NOT_CONTEXTUAL);
   } else {
     CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
@@ -1983,15 +2013,12 @@
 
 
 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object.
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
   DCHECK(!key->value()->IsSmi());
   DCHECK(prop->IsSuperAccess());
 
-  SuperReference* super_ref = prop->obj()->AsSuperReference();
-  EmitLoadHomeObject(super_ref);
-  __ Push(x0);
-  VisitForStackValue(super_ref->this_var());
   __ Push(key->value());
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 }
@@ -1999,11 +2026,11 @@
 
 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
-  // Call keyed load IC. It has arguments key and receiver in r0 and r1.
+  // Call keyed load IC. It has arguments key and receiver in x0 and x1.
   Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
   if (FLAG_vector_ics) {
     __ Mov(VectorLoadICDescriptor::SlotRegister(),
-           Smi::FromInt(prop->PropertyFeedbackSlot()));
+           SmiFromSlot(prop->PropertyFeedbackSlot()));
     CallIC(ic);
   } else {
     CallIC(ic, prop->PropertyFeedbackId());
@@ -2011,6 +2038,14 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object, key.
+  SetSourcePosition(prop->position());
+
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+}
+
+
 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
                                               Token::Value op,
                                               OverwriteMode mode,
@@ -2126,19 +2161,68 @@
 }
 
 
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
+  // Constructor is in x0.
+  DCHECK(lit != NULL);
+  __ push(x0);
+
+  // No access check is needed here since the constructor is created by the
+  // class literal.
+  Register scratch = x1;
+  __ Ldr(scratch,
+         FieldMemOperand(x0, JSFunction::kPrototypeOrInitialMapOffset));
+  __ Push(scratch);
+
+  for (int i = 0; i < lit->properties()->length(); i++) {
+    ObjectLiteral::Property* property = lit->properties()->at(i);
+    Literal* key = property->key()->AsLiteral();
+    Expression* value = property->value();
+    DCHECK(key != NULL);
+
+    if (property->is_static()) {
+      __ Peek(scratch, kPointerSize);  // constructor
+    } else {
+      __ Peek(scratch, 0);  // prototype
+    }
+    __ Push(scratch);
+    VisitForStackValue(key);
+    VisitForStackValue(value);
+    EmitSetHomeObjectIfNeeded(value, 2);
+
+    switch (property->kind()) {
+      case ObjectLiteral::Property::CONSTANT:
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+      case ObjectLiteral::Property::COMPUTED:
+      case ObjectLiteral::Property::PROTOTYPE:
+        __ CallRuntime(Runtime::kDefineClassMethod, 3);
+        break;
+
+      case ObjectLiteral::Property::GETTER:
+        __ CallRuntime(Runtime::kDefineClassGetter, 3);
+        break;
+
+      case ObjectLiteral::Property::SETTER:
+        __ CallRuntime(Runtime::kDefineClassSetter, 3);
+        break;
+
+      default:
+        UNREACHABLE();
+    }
+  }
+
+  // prototype
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+
+  // constructor
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+}
+
+
 void FullCodeGenerator::EmitAssignment(Expression* expr) {
   DCHECK(expr->IsValidReferenceExpression());
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->AsProperty();
-  if (prop != NULL) {
-    assign_type = (prop->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   switch (assign_type) {
     case VARIABLE: {
@@ -2159,6 +2243,42 @@
       CallStoreIC();
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      __ Push(x0);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      // stack: value, this; x0: home_object
+      Register scratch = x10;
+      Register scratch2 = x11;
+      __ mov(scratch, result_register());  // home_object
+      __ Peek(x0, kPointerSize);           // value
+      __ Peek(scratch2, 0);                // this
+      __ Poke(scratch2, kPointerSize);     // this
+      __ Poke(scratch, 0);                 // home_object
+      // stack: this, home_object; x0: value
+      EmitNamedSuperPropertyStore(prop);
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      __ Push(x0);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(prop->key());
+      Register scratch = x10;
+      Register scratch2 = x11;
+      __ Peek(scratch2, 2 * kPointerSize);  // value
+      // stack: value, this, home_object; x0: key, x11: value
+      __ Peek(scratch, kPointerSize);  // this
+      __ Poke(scratch, 2 * kPointerSize);
+      __ Peek(scratch, 0);  // home_object
+      __ Poke(scratch, kPointerSize);
+      __ Poke(x0, 0);
+      __ Move(x0, scratch2);
+      // stack: this, home_object, key; x0: value.
+      EmitKeyedSuperPropertyStore(prop);
+      break;
+    }
     case KEYED_PROPERTY: {
       __ Push(x0);  // Preserve value.
       VisitForStackValue(prop->obj());
@@ -2253,8 +2373,9 @@
       }
       EmitStoreToStackLocalOrContextSlot(var, location);
     }
+  } else if (IsSignallingAssignmentToConst(var, op, strict_mode())) {
+    __ CallRuntime(Runtime::kThrowConstAssignError, 0);
   }
-  // Non-initializing assignments to consts are ignored.
 }
 
 
@@ -2277,6 +2398,35 @@
 }
 
 
+void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // x0 : value
+  // stack : receiver ('this'), home_object
+  DCHECK(prop != NULL);
+  Literal* key = prop->key()->AsLiteral();
+  DCHECK(key != NULL);
+
+  __ Push(key->value());
+  __ Push(x0);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
+                                          : Runtime::kStoreToSuper_Sloppy),
+                 4);
+}
+
+
+void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // x0 : value
+  // stack : receiver ('this'), home_object, key
+  DCHECK(prop != NULL);
+
+  __ Push(x0);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict
+                                          : Runtime::kStoreKeyedToSuper_Sloppy),
+                 4);
+}
+
+
 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
   ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment");
   // Assignment to a property, using a keyed store IC.
@@ -2305,16 +2455,27 @@
       __ Move(LoadDescriptor::ReceiverRegister(), x0);
       EmitNamedPropertyLoad(expr);
     } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ Push(result_register());
       EmitNamedSuperPropertyLoad(expr);
     }
     PrepareForBailoutForId(expr->LoadId(), TOS_REG);
     context()->Plug(x0);
   } else {
-    VisitForStackValue(expr->obj());
-    VisitForAccumulatorValue(expr->key());
-    __ Move(LoadDescriptor::NameRegister(), x0);
-    __ Pop(LoadDescriptor::ReceiverRegister());
-    EmitKeyedPropertyLoad(expr);
+    if (!expr->IsSuperAccess()) {
+      VisitForStackValue(expr->obj());
+      VisitForAccumulatorValue(expr->key());
+      __ Move(LoadDescriptor::NameRegister(), x0);
+      __ Pop(LoadDescriptor::ReceiverRegister());
+      EmitKeyedPropertyLoad(expr);
+    } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForStackValue(expr->key());
+      EmitKeyedSuperPropertyLoad(expr);
+    }
     context()->Plug(x0);
   }
 }
@@ -2379,14 +2540,14 @@
   VisitForAccumulatorValue(super_ref->this_var());
   __ Push(x0);
   __ Peek(scratch, kPointerSize);
-  __ Push(scratch, x0);
+  __ Push(x0, scratch);
   __ Push(key->value());
 
   // Stack here:
   //  - home_object
   //  - this (receiver)
-  //  - home_object <-- LoadFromSuper will pop here and below.
-  //  - this (receiver)
+  //  - this (receiver) <-- LoadFromSuper will pop here and below.
+  //  - home_object
   //  - key
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 
@@ -2423,6 +2584,43 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
+  Expression* callee = expr->expression();
+  DCHECK(callee->IsProperty());
+  Property* prop = callee->AsProperty();
+  DCHECK(prop->IsSuperAccess());
+
+  SetSourcePosition(prop->position());
+
+  // Load the function from the receiver.
+  const Register scratch = x10;
+  SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference();
+  EmitLoadHomeObject(super_ref);
+  __ Push(x0);
+  VisitForAccumulatorValue(super_ref->this_var());
+  __ Push(x0);
+  __ Peek(scratch, kPointerSize);
+  __ Push(x0, scratch);
+  VisitForStackValue(prop->key());
+
+  // Stack here:
+  //  - home_object
+  //  - this (receiver)
+  //  - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
+  //  - home_object
+  //  - key
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+
+  // Replace home_object with target function.
+  __ Poke(x0, kPointerSize);
+
+  // Stack here:
+  // - target function
+  // - this (receiver)
+  EmitCall(expr, CallICState::METHOD);
+}
+
+
 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Load the arguments.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2437,7 +2635,7 @@
 
   Handle<Code> ic = CallIC::initialize_stub(
       isolate(), arg_count, call_type);
-  __ Mov(x3, Smi::FromInt(expr->CallFeedbackSlot()));
+  __ Mov(x3, SmiFromSlot(expr->CallFeedbackSlot()));
   __ Peek(x1, (arg_count + 1) * kXRegSize);
   // Don't assign a type feedback id to the IC, since type feedback is provided
   // by the vector above.
@@ -2478,6 +2676,14 @@
 }
 
 
+void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
+  DCHECK(super_ref != NULL);
+  __ ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ Push(x0);
+  __ CallRuntime(Runtime::kGetPrototype, 1);
+}
+
+
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -2517,6 +2723,8 @@
       // The runtime call returns a pair of values in x0 (function) and
       // x1 (receiver). Touch up the stack with the right values.
       __ PokePair(x1, x0, arg_count * kPointerSize);
+
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
 
     // Record source position for debugger.
@@ -2552,6 +2760,7 @@
     __ Push(context_register(), x10);
     __ CallRuntime(Runtime::kLoadLookupSlot, 2);
     __ Push(x0, x1);  // Receiver, function.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
 
     // If fast case code has been generated, emit code to push the
     // function and receiver and have the slow path jump around this
@@ -2574,9 +2783,12 @@
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
     bool is_named_call = property->key()->IsPropertyName();
-    // super.x() is handled in EmitCallWithLoadIC.
-    if (property->IsSuperAccess() && is_named_call) {
-      EmitSuperCallWithLoadIC(expr);
+    if (property->IsSuperAccess()) {
+      if (is_named_call) {
+        EmitSuperCallWithLoadIC(expr);
+      } else {
+        EmitKeyedSuperCallWithLoadIC(expr);
+      }
     } else {
       {
         PreservePositionScope scope(masm()->positions_recorder());
@@ -2588,6 +2800,12 @@
         EmitKeyedCallWithLoadIC(expr, property->key());
       }
     }
+  } else if (call_type == Call::SUPER_CALL) {
+    SuperReference* super_ref = callee->AsSuperReference();
+    EmitLoadSuperConstructor(super_ref);
+    __ Push(result_register());
+    VisitForStackValue(super_ref->this_var());
+    EmitCall(expr, CallICState::METHOD);
   } else {
     DCHECK(call_type == Call::OTHER_CALL);
     // Call to an arbitrary expression not handled specially above.
@@ -2616,7 +2834,12 @@
   // Push constructor on the stack.  If it's not a function it's used as
   // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
   // ignored.
-  VisitForStackValue(expr->expression());
+  if (expr->expression()->IsSuperReference()) {
+    EmitLoadSuperConstructor(expr->expression()->AsSuperReference());
+    __ Push(result_register());
+  } else {
+    VisitForStackValue(expr->expression());
+  }
 
   // Push the arguments ("left-to-right") on the stack.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2636,12 +2859,12 @@
   // Record call targets in unoptimized code.
   if (FLAG_pretenuring_call_new) {
     EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
-    DCHECK(expr->AllocationSiteFeedbackSlot() ==
-           expr->CallNewFeedbackSlot() + 1);
+    DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
+           expr->CallNewFeedbackSlot().ToInt() + 1);
   }
 
   __ LoadObject(x2, FeedbackVector());
-  __ Mov(x3, Smi::FromInt(expr->CallNewFeedbackSlot()));
+  __ Mov(x3, SmiFromSlot(expr->CallNewFeedbackSlot()));
 
   CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
   __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
@@ -2964,6 +3187,32 @@
 }
 
 
+void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(x0, if_false);
+  Register map = x10;
+  Register type_reg = x11;
+  __ Ldr(map, FieldMemOperand(x0, HeapObject::kMapOffset));
+  __ Ldrb(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  __ Sub(type_reg, type_reg, Operand(FIRST_JS_PROXY_TYPE));
+  __ Cmp(type_reg, Operand(LAST_JS_PROXY_TYPE - FIRST_JS_PROXY_TYPE));
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(ls, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
 
 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
   DCHECK(expr->arguments()->length() == 0);
@@ -3843,7 +4092,7 @@
     __ Mov(LoadDescriptor::NameRegister(), Operand(name));
     if (FLAG_vector_ics) {
       __ Mov(VectorLoadICDescriptor::SlotRegister(),
-             Smi::FromInt(expr->CallRuntimeFeedbackSlot()));
+             SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
       CallLoadIC(NOT_CONTEXTUAL);
     } else {
       CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
@@ -3997,17 +4246,8 @@
   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());
 
-  // Expression can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
-  // In case of a property we use the uninitialized expression context
-  // of the key to detect a named property.
-  if (prop != NULL) {
-    assign_type =
-        (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   // Evaluate expression and get value.
   if (assign_type == VARIABLE) {
@@ -4019,18 +4259,52 @@
     if (expr->is_postfix() && !context()->IsEffect()) {
       __ Push(xzr);
     }
-    if (assign_type == NAMED_PROPERTY) {
-      // Put the object both on the stack and in the register.
-      VisitForStackValue(prop->obj());
-      __ Peek(LoadDescriptor::ReceiverRegister(), 0);
-      EmitNamedPropertyLoad(prop);
-    } else {
-      // KEYED_PROPERTY
-      VisitForStackValue(prop->obj());
-      VisitForStackValue(prop->key());
-      __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize);
-      __ Peek(LoadDescriptor::NameRegister(), 0);
-      EmitKeyedPropertyLoad(prop);
+    switch (assign_type) {
+      case NAMED_PROPERTY: {
+        // Put the object both on the stack and in the register.
+        VisitForStackValue(prop->obj());
+        __ Peek(LoadDescriptor::ReceiverRegister(), 0);
+        EmitNamedPropertyLoad(prop);
+        break;
+      }
+
+      case NAMED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        const Register scratch = x10;
+        __ Peek(scratch, kPointerSize);
+        __ Push(scratch, result_register());
+        EmitNamedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        VisitForAccumulatorValue(prop->key());
+        __ Push(result_register());
+        const Register scratch1 = x10;
+        const Register scratch2 = x11;
+        __ Peek(scratch1, 2 * kPointerSize);
+        __ Peek(scratch2, kPointerSize);
+        __ Push(scratch1, scratch2, result_register());
+        EmitKeyedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_PROPERTY: {
+        VisitForStackValue(prop->obj());
+        VisitForStackValue(prop->key());
+        __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize);
+        __ Peek(LoadDescriptor::NameRegister(), 0);
+        EmitKeyedPropertyLoad(prop);
+        break;
+      }
+
+      case VARIABLE:
+        UNREACHABLE();
     }
   }
 
@@ -4064,9 +4338,15 @@
           case NAMED_PROPERTY:
             __ Poke(x0, kPointerSize);
             break;
+          case NAMED_SUPER_PROPERTY:
+            __ Poke(x0, kPointerSize * 2);
+            break;
           case KEYED_PROPERTY:
             __ Poke(x0, kPointerSize * 2);
             break;
+          case KEYED_SUPER_PROPERTY:
+            __ Poke(x0, kPointerSize * 3);
+            break;
         }
       }
     }
@@ -4094,9 +4374,15 @@
         case NAMED_PROPERTY:
           __ Poke(x0, kXRegSize);
           break;
+        case NAMED_SUPER_PROPERTY:
+          __ Poke(x0, 2 * kXRegSize);
+          break;
         case KEYED_PROPERTY:
           __ Poke(x0, 2 * kXRegSize);
           break;
+        case KEYED_SUPER_PROPERTY:
+          __ Poke(x0, 3 * kXRegSize);
+          break;
       }
     }
   }
@@ -4154,6 +4440,28 @@
       }
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      EmitNamedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(x0);
+      }
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      EmitKeyedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(x0);
+      }
+      break;
+    }
     case KEYED_PROPERTY: {
       __ Pop(StoreDescriptor::NameRegister());
       __ Pop(StoreDescriptor::ReceiverRegister());
@@ -4184,7 +4492,7 @@
     __ Mov(LoadDescriptor::NameRegister(), Operand(proxy->name()));
     if (FLAG_vector_ics) {
       __ Mov(VectorLoadICDescriptor::SlotRegister(),
-             Smi::FromInt(proxy->VariableFeedbackSlot()));
+             SmiFromSlot(proxy->VariableFeedbackSlot()));
     }
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
@@ -4540,7 +4848,7 @@
       __ Peek(load_name, 2 * kPointerSize);
       if (FLAG_vector_ics) {
         __ Mov(VectorLoadICDescriptor::SlotRegister(),
-               Smi::FromInt(expr->KeyedLoadFeedbackSlot()));
+               SmiFromSlot(expr->KeyedLoadFeedbackSlot()));
       }
       Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
       CallIC(ic, TypeFeedbackId::None());
@@ -4560,7 +4868,7 @@
       __ LoadRoot(load_name, Heap::kdone_stringRootIndex);  // "done"
       if (FLAG_vector_ics) {
         __ Mov(VectorLoadICDescriptor::SlotRegister(),
-               Smi::FromInt(expr->DoneFeedbackSlot()));
+               SmiFromSlot(expr->DoneFeedbackSlot()));
       }
       CallLoadIC(NOT_CONTEXTUAL);                           // x0=result.done
       // The ToBooleanStub argument (result.done) is in x0.
@@ -4573,7 +4881,7 @@
       __ LoadRoot(load_name, Heap::kvalue_stringRootIndex);  // "value"
       if (FLAG_vector_ics) {
         __ Mov(VectorLoadICDescriptor::SlotRegister(),
-               Smi::FromInt(expr->ValueFeedbackSlot()));
+               SmiFromSlot(expr->ValueFeedbackSlot()));
       }
       CallLoadIC(NOT_CONTEXTUAL);                            // x0=result.value
       context()->DropAndPlug(2, x0);                         // drop iter and g
@@ -4587,7 +4895,6 @@
     Expression *value,
     JSGeneratorObject::ResumeMode resume_mode) {
   ASM_LOCATION("FullCodeGenerator::EmitGeneratorResume");
-  Register value_reg = x0;
   Register generator_object = x1;
   Register the_hole = x2;
   Register operand_stack_size = w3;
@@ -4595,21 +4902,12 @@
 
   // The value stays in x0, and is ultimately read by the resumed generator, as
   // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
-  // is read to throw the value when the resumed generator is already closed. r1
+  // is read to throw the value when the resumed generator is already closed. x1
   // will hold the generator object until the activation has been resumed.
   VisitForStackValue(generator);
   VisitForAccumulatorValue(value);
   __ Pop(generator_object);
 
-  // Check generator state.
-  Label wrong_state, closed_state, done;
-  __ Ldr(x10, FieldMemOperand(generator_object,
-                              JSGeneratorObject::kContinuationOffset));
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
-  __ CompareAndBranch(x10, Smi::FromInt(0), eq, &closed_state);
-  __ CompareAndBranch(x10, Smi::FromInt(0), lt, &wrong_state);
-
   // Load suspended function and context.
   __ Ldr(cp, FieldMemOperand(generator_object,
                              JSGeneratorObject::kContextOffset));
@@ -4635,7 +4933,7 @@
 
   // Enter a new JavaScript frame, and initialize its slots as they were when
   // the generator was suspended.
-  Label resume_frame;
+  Label resume_frame, done;
   __ Bl(&resume_frame);
   __ B(&done);
 
@@ -4680,26 +4978,6 @@
   // Not reached: the runtime call returns elsewhere.
   __ Unreachable();
 
-  // Reach here when generator is closed.
-  __ Bind(&closed_state);
-  if (resume_mode == JSGeneratorObject::NEXT) {
-    // Return completed iterator result when generator is closed.
-    __ LoadRoot(x10, Heap::kUndefinedValueRootIndex);
-    __ Push(x10);
-    // Pop value from top-of-stack slot; box result into result register.
-    EmitCreateIteratorResult(true);
-  } else {
-    // Throw the provided value.
-    __ Push(value_reg);
-    __ CallRuntime(Runtime::kThrow, 1);
-  }
-  __ B(&done);
-
-  // Throw error if we attempt to operate on a running generator.
-  __ Bind(&wrong_state);
-  __ Push(generator_object);
-  __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
-
   __ Bind(&done);
   context()->Plug(result_register());
 }
@@ -4709,16 +4987,18 @@
   Label gc_required;
   Label allocated;
 
-  Handle<Map> map(isolate()->native_context()->iterator_result_map());
+  const int instance_size = 5 * kPointerSize;
+  DCHECK_EQ(isolate()->native_context()->iterator_result_map()->instance_size(),
+            instance_size);
 
   // Allocate and populate an object with this form: { value: VAL, done: DONE }
 
   Register result = x0;
-  __ Allocate(map->instance_size(), result, x10, x11, &gc_required, TAG_OBJECT);
+  __ Allocate(instance_size, result, x10, x11, &gc_required, TAG_OBJECT);
   __ B(&allocated);
 
   __ Bind(&gc_required);
-  __ Push(Smi::FromInt(map->instance_size()));
+  __ Push(Smi::FromInt(instance_size));
   __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
   __ Ldr(context_register(),
          MemOperand(fp, StandardFrameConstants::kContextOffset));
@@ -4729,11 +5009,13 @@
   Register boolean_done = x3;
   Register empty_fixed_array = x4;
   Register untagged_result = x5;
-  __ Mov(map_reg, Operand(map));
+  __ Ldr(map_reg, GlobalObjectMemOperand());
+  __ Ldr(map_reg, FieldMemOperand(map_reg, GlobalObject::kNativeContextOffset));
+  __ Ldr(map_reg,
+         ContextMemOperand(map_reg, Context::ITERATOR_RESULT_MAP_INDEX));
   __ Pop(result_value);
   __ Mov(boolean_done, Operand(isolate()->factory()->ToBoolean(done)));
   __ Mov(empty_fixed_array, Operand(isolate()->factory()->empty_fixed_array()));
-  DCHECK_EQ(map->instance_size(), 5 * kPointerSize);
   STATIC_ASSERT(JSObject::kPropertiesOffset + kPointerSize ==
                 JSObject::kElementsOffset);
   STATIC_ASSERT(JSGeneratorObject::kResultValuePropertyOffset + kPointerSize ==
@@ -4785,7 +5067,7 @@
 
 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
   Scope* declaration_scope = scope()->DeclarationScope();
-  if (declaration_scope->is_global_scope() ||
+  if (declaration_scope->is_script_scope() ||
       declaration_scope->is_module_scope()) {
     // Contexts nested in the native context have a canonical empty function
     // as their closure, not the anonymous closure containing the global
diff --git a/src/arm64/interface-descriptors-arm64.cc b/src/arm64/interface-descriptors-arm64.cc
index 690c8c2..57eebcc 100644
--- a/src/arm64/interface-descriptors-arm64.cc
+++ b/src/arm64/interface-descriptors-arm64.cc
@@ -29,6 +29,9 @@
 const Register StoreDescriptor::ValueRegister() { return x0; }
 
 
+const Register StoreTransitionDescriptor::MapRegister() { return x3; }
+
+
 const Register ElementTransitionAndStoreDescriptor::MapRegister() { return x3; }
 
 
@@ -182,6 +185,14 @@
 }
 
 
+void AllocateHeapNumberDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  // cp: context
+  Register registers[] = {cp};
+  data->Initialize(arraysize(registers), registers, nullptr);
+}
+
+
 void ArrayConstructorConstantArgCountDescriptor::Initialize(
     CallInterfaceDescriptorData* data) {
   // cp: context
diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc
index 502b046..2d5f7f2 100644
--- a/src/arm64/lithium-arm64.cc
+++ b/src/arm64/lithium-arm64.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <sstream>
+
 #include "src/v8.h"
 
 #include "src/arm64/lithium-codegen-arm64.h"
@@ -282,9 +284,9 @@
 
 void LStoreNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
-  OStringStream os;
+  std::ostringstream os;
   os << hydrogen()->access();
-  stream->Add(os.c_str());
+  stream->Add(os.str().c_str());
   stream->Add(" <- ");
   value()->PrintTo(stream);
 }
@@ -1562,9 +1564,17 @@
       UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
   LOperand* name_register =
       UseFixed(instr->name(), LoadDescriptor::NameRegister());
+  LOperand* slot = NULL;
+  LOperand* vector = NULL;
+  if (FLAG_vector_ics) {
+    slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
+    vector =
+        UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
+  }
+
   // Not marked as call. It can't deoptimize, and it never returns.
   return new (zone()) LTailCallThroughMegamorphicCache(
-      context, receiver_register, name_register);
+      context, receiver_register, name_register, slot, vector);
 }
 
 
@@ -1673,7 +1683,7 @@
   LOperand* global_object =
       UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
@@ -1736,7 +1746,7 @@
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
@@ -1758,7 +1768,7 @@
   LOperand* object =
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
@@ -2234,11 +2244,7 @@
                            (JSShiftAmountFromHConstant(instr->right()) == 0);
   bool can_deopt = false;
   if ((op == Token::SHR) && right_can_be_zero) {
-    if (FLAG_opt_safe_uint32_operations) {
-      can_deopt = !instr->CheckFlag(HInstruction::kUint32);
-    } else {
-      can_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
-    }
+    can_deopt = !instr->CheckFlag(HInstruction::kUint32);
   }
 
   LInstruction* result;
@@ -2402,7 +2408,7 @@
   LOperand* temp1 = NULL;
 
   if (instr->access().IsExternalMemory() ||
-      instr->field_representation().IsDouble()) {
+      (!FLAG_unbox_double_fields && instr->field_representation().IsDouble())) {
     value = UseRegister(instr->value());
   } else if (instr->NeedsWriteBarrier()) {
     value = UseRegisterAndClobber(instr->value());
diff --git a/src/arm64/lithium-arm64.h b/src/arm64/lithium-arm64.h
index 6ead3fe..424ecba 100644
--- a/src/arm64/lithium-arm64.h
+++ b/src/arm64/lithium-arm64.h
@@ -178,17 +178,13 @@
   V(WrapReceiver)
 
 
-#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)                        \
-  virtual Opcode opcode() const FINAL OVERRIDE {                      \
-    return LInstruction::k##type;                                           \
-  }                                                                         \
-  virtual void CompileToNative(LCodeGen* generator) FINAL OVERRIDE;   \
-  virtual const char* Mnemonic() const FINAL OVERRIDE {               \
-    return mnemonic;                                                        \
-  }                                                                         \
-  static L##type* cast(LInstruction* instr) {                               \
-    DCHECK(instr->Is##type());                                              \
-    return reinterpret_cast<L##type*>(instr);                               \
+#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)            \
+  Opcode opcode() const FINAL { return LInstruction::k##type; } \
+  void CompileToNative(LCodeGen* generator) FINAL;              \
+  const char* Mnemonic() const FINAL { return mnemonic; }       \
+  static L##type* cast(LInstruction* instr) {                   \
+    DCHECK(instr->Is##type());                                  \
+    return reinterpret_cast<L##type*>(instr);                   \
   }
 
 
@@ -295,11 +291,9 @@
  public:
   // Allow 0 or 1 output operands.
   STATIC_ASSERT(R == 0 || R == 1);
-  virtual bool HasResult() const FINAL OVERRIDE {
-    return (R != 0) && (result() != NULL);
-  }
+  bool HasResult() const FINAL { return (R != 0) && (result() != NULL); }
   void set_result(LOperand* operand) { results_[0] = operand; }
-  LOperand* result() const { return results_[0]; }
+  LOperand* result() const OVERRIDE { return results_[0]; }
 
  protected:
   EmbeddedContainer<LOperand*, R> results_;
@@ -317,28 +311,32 @@
 
  private:
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return I; }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return I; }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return T; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return temps_[i]; }
+  int TempCount() FINAL { return T; }
+  LOperand* TempAt(int i) FINAL { return temps_[i]; }
 };
 
 
 class LTailCallThroughMegamorphicCache FINAL
-    : public LTemplateInstruction<0, 3, 0> {
+    : public LTemplateInstruction<0, 5, 0> {
  public:
-  explicit LTailCallThroughMegamorphicCache(LOperand* context,
-                                            LOperand* receiver,
-                                            LOperand* name) {
+  LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
+                                   LOperand* name, LOperand* slot,
+                                   LOperand* vector) {
     inputs_[0] = context;
     inputs_[1] = receiver;
     inputs_[2] = name;
+    inputs_[3] = slot;
+    inputs_[4] = vector;
   }
 
   LOperand* context() { return inputs_[0]; }
   LOperand* receiver() { return inputs_[1]; }
   LOperand* name() { return inputs_[2]; }
+  LOperand* slot() { return inputs_[3]; }
+  LOperand* vector() { return inputs_[4]; }
 
   DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
                                "tail-call-through-megamorphic-cache")
@@ -348,9 +346,7 @@
 
 class LUnknownOSRValue FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
 };
 
@@ -360,7 +356,7 @@
  public:
   LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
 
-  virtual bool IsControl() const FINAL OVERRIDE { return true; }
+  bool IsControl() const FINAL { return true; }
 
   int SuccessorCount() { return hydrogen()->SuccessorCount(); }
   HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
@@ -410,8 +406,8 @@
   }
 
   // Can't use the DECLARE-macro here because of sub-classes.
-  virtual bool IsGap() const OVERRIDE { return true; }
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsGap() const OVERRIDE { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   static LGap* cast(LInstruction* instr) {
     DCHECK(instr->IsGap());
     return reinterpret_cast<LGap*>(instr);
@@ -451,7 +447,7 @@
  public:
   explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
     return !IsRedundant();
   }
 
@@ -492,10 +488,10 @@
  public:
   explicit LGoto(HBasicBlock* block) : block_(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
-  virtual bool IsControl() const OVERRIDE { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsControl() const OVERRIDE { return true; }
 
   int block_id() const { return block_->block_id(); }
 
@@ -525,12 +521,10 @@
   explicit LLabel(HBasicBlock* block)
       : LGap(block), replacement_(NULL) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Label, "label")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int block_id() const { return block()->block_id(); }
   bool is_loop_header() const { return block()->IsLoopHeader(); }
@@ -550,9 +544,7 @@
  public:
   LOsrEntry() {}
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
 };
 
@@ -573,7 +565,7 @@
   LOperand* length() { return inputs_[1]; }
   LOperand* index() { return inputs_[2]; }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -721,11 +713,9 @@
   LOperand* left() { return inputs_[0]; }
   LOperand* right() { return inputs_[1]; }
 
-  virtual Opcode opcode() const OVERRIDE {
-    return LInstruction::kArithmeticD;
-  }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticD; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
  private:
   Token::Value op_;
@@ -749,11 +739,9 @@
   LOperand* right() { return inputs_[2]; }
   Token::Value op() const { return op_; }
 
-  virtual Opcode opcode() const OVERRIDE {
-    return LInstruction::kArithmeticT;
-  }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticT; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
  private:
   Token::Value op_;
@@ -838,7 +826,7 @@
   DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
   DECLARE_HYDROGEN_ACCESSOR(Branch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -853,7 +841,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
   DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -889,7 +877,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
   DECLARE_HYDROGEN_ACCESSOR(CallNew)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -908,7 +896,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
   DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -925,7 +913,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
   DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
 
-  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
+  bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
     return save_doubles() == kDontSaveFPRegs;
   }
 
@@ -1097,7 +1085,7 @@
                                "class-of-test-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1215,7 +1203,7 @@
     return hydrogen()->representation().IsDouble();
   }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1313,7 +1301,7 @@
 
 class LDeoptimize FINAL : public LTemplateInstruction<0, 0, 0> {
  public:
-  virtual bool IsControl() const OVERRIDE { return true; }
+  bool IsControl() const OVERRIDE { return true; }
   DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
   DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
 };
@@ -1447,7 +1435,7 @@
                                "has-cached-array-index-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1465,7 +1453,7 @@
                                "has-instance-type-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1479,7 +1467,7 @@
   LOperand* base_object() const { return inputs_[0]; }
   LOperand* offset() const { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
 };
@@ -1555,11 +1543,12 @@
 
   CallInterfaceDescriptor descriptor() { return descriptor_; }
 
- private:
-  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
   DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+ private:
+  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 
@@ -1567,11 +1556,11 @@
   ZoneList<LOperand*> inputs_;
 
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return inputs_.length(); }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return inputs_.length(); }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return 0; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return NULL; }
+  int TempCount() FINAL { return 0; }
+  LOperand* TempAt(int i) FINAL { return NULL; }
 };
 
 
@@ -1588,7 +1577,7 @@
   DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
   DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1624,7 +1613,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1641,7 +1630,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1656,7 +1645,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1674,7 +1663,7 @@
                                "is-undetectable-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1691,7 +1680,7 @@
 
   int slot_index() const { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -2272,7 +2261,7 @@
 
 class LParameter FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const { return false; }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
 };
 
@@ -2331,11 +2320,11 @@
 
  private:
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return inputs_.length(); }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return inputs_.length(); }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return 0; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return NULL; }
+  int TempCount() FINAL { return 0; }
+  LOperand* TempAt(int i) FINAL { return NULL; }
 };
 
 
@@ -2585,7 +2574,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
@@ -2609,7 +2598,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Representation representation() const {
     return hydrogen()->field_representation();
@@ -2632,7 +2621,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Handle<Object> name() const { return hydrogen()->name(); }
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
@@ -2707,7 +2696,7 @@
 
   Token::Value op() const { return hydrogen()->token(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -2786,7 +2775,7 @@
   LOperand* code_object() { return inputs_[1]; }
   LOperand* temp() { return temps_[0]; }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
   DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
@@ -2810,7 +2799,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -2916,7 +2905,7 @@
                                "transition-elements-kind")
   DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
   Handle<Map> transitioned_map() {
@@ -2991,7 +2980,7 @@
 
   Handle<String> type_literal() const { return hydrogen()->type_literal(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc
index 2998642..df9e7b5 100644
--- a/src/arm64/lithium-codegen-arm64.cc
+++ b/src/arm64/lithium-codegen-arm64.cc
@@ -557,11 +557,6 @@
       safepoint.DefinePointerRegister(ToRegister(pointer), zone());
     }
   }
-
-  if (kind & Safepoint::kWithRegisters) {
-    // Register cp always contains a pointer to the context.
-    safepoint.DefinePointerRegister(cp, zone());
-  }
 }
 
 void LCodeGen::RecordSafepoint(LPointerMap* pointers,
@@ -1063,9 +1058,8 @@
 }
 
 
-void LCodeGen::Deoptimize(LInstruction* instr,
-                          Deoptimizer::BailoutType* override_bailout_type,
-                          const char* detail) {
+void LCodeGen::Deoptimize(LInstruction* instr, const char* detail,
+                          Deoptimizer::BailoutType* override_bailout_type) {
   DeoptimizeBranch(instr, detail, always, NoReg, -1, override_bailout_type);
 }
 
@@ -1516,7 +1510,7 @@
 
   if (can_overflow) {
     __ Adds(result, left, right);
-    DeoptimizeIf(vs, instr);
+    DeoptimizeIf(vs, instr, "overflow");
   } else {
     __ Add(result, left, right);
   }
@@ -1530,7 +1524,7 @@
   Operand right = ToOperand(instr->right());
   if (can_overflow) {
     __ Adds(result, left, right);
-    DeoptimizeIf(vs, instr);
+    DeoptimizeIf(vs, instr, "overflow");
   } else {
     __ Add(result, left, right);
   }
@@ -1656,7 +1650,7 @@
   // adaptor frame below it.
   const uint32_t kArgumentsLimit = 1 * KB;
   __ Cmp(length, kArgumentsLimit);
-  DeoptimizeIf(hi, instr);
+  DeoptimizeIf(hi, instr, "too many arguments");
 
   // Push the receiver and use the register to keep the original
   // number of arguments.
@@ -1838,7 +1832,7 @@
   if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
     __ Assert(NegateCondition(cond), kEliminatedBoundsCheckFailed);
   } else {
-    DeoptimizeIf(cond, instr);
+    DeoptimizeIf(cond, instr, "out of bounds");
   }
 }
 
@@ -1917,7 +1911,7 @@
         __ JumpIfSmi(value, true_label);
       } else if (expected.NeedsMap()) {
         // If we need a map later and have a smi, deopt.
-        DeoptimizeIfSmi(value, instr);
+        DeoptimizeIfSmi(value, instr, "Smi");
       }
 
       Register map = NoReg;
@@ -1978,7 +1972,7 @@
       if (!expected.IsGeneric()) {
         // We've seen something for the first time -> deopt.
         // This can only happen if we are not generic already.
-        Deoptimize(instr);
+        Deoptimize(instr, "unexpected object");
       }
     }
   }
@@ -2048,23 +2042,33 @@
   DCHECK(name.is(LoadDescriptor::NameRegister()));
   DCHECK(receiver.is(x1));
   DCHECK(name.is(x2));
-
-  Register scratch = x3;
-  Register extra = x4;
-  Register extra2 = x5;
-  Register extra3 = x6;
+  Register scratch = x4;
+  Register extra = x5;
+  Register extra2 = x6;
+  Register extra3 = x7;
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(ToRegister(instr->slot()), ToRegister(instr->vector()),
+                     scratch, extra, extra2, extra3));
 
   // Important for the tail-call.
   bool must_teardown_frame = NeedsEagerFrame();
 
-  // The probe will tail call to a handler if found.
-  isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
-                                         must_teardown_frame, receiver, name,
-                                         scratch, extra, extra2, extra3);
+  if (!instr->hydrogen()->is_just_miss()) {
+    DCHECK(!instr->hydrogen()->is_keyed_load());
+
+    // The probe will tail call to a handler if found.
+    isolate()->stub_cache()->GenerateProbe(
+        masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
+        receiver, name, scratch, extra, extra2, extra3);
+  }
 
   // Tail call to miss if we ended up here.
   if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL);
-  LoadIC::GenerateMiss(masm());
+  if (instr->hydrogen()->is_keyed_load()) {
+    KeyedLoadIC::GenerateMiss(masm());
+  } else {
+    LoadIC::GenerateMiss(masm());
+  }
 }
 
 
@@ -2072,25 +2076,44 @@
   DCHECK(instr->IsMarkedAsCall());
   DCHECK(ToRegister(instr->result()).Is(x0));
 
-  LPointerMap* pointers = instr->pointer_map();
-  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+  if (instr->hydrogen()->IsTailCall()) {
+    if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL);
 
-  if (instr->target()->IsConstantOperand()) {
-    LConstantOperand* target = LConstantOperand::cast(instr->target());
-    Handle<Code> code = Handle<Code>::cast(ToHandle(target));
-    generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
-    // TODO(all): on ARM we use a call descriptor to specify a storage mode
-    // but on ARM64 we only have one storage mode so it isn't necessary. Check
-    // this understanding is correct.
-    __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None());
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      // TODO(all): on ARM we use a call descriptor to specify a storage mode
+      // but on ARM64 we only have one storage mode so it isn't necessary. Check
+      // this understanding is correct.
+      __ Jump(code, RelocInfo::CODE_TARGET);
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
+      __ Br(target);
+    }
   } else {
-    DCHECK(instr->target()->IsRegister());
-    Register target = ToRegister(instr->target());
-    generator.BeforeCall(__ CallSize(target));
-    __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
-    __ Call(target);
+    LPointerMap* pointers = instr->pointer_map();
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
+      // TODO(all): on ARM we use a call descriptor to specify a storage mode
+      // but on ARM64 we only have one storage mode so it isn't necessary. Check
+      // this understanding is correct.
+      __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None());
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      generator.BeforeCall(__ CallSize(target));
+      __ Add(target, target, Code::kHeaderSize - kHeapObjectTag);
+      __ Call(target);
+    }
+    generator.AfterCall();
   }
-  generator.AfterCall();
+
   after_push_argument_ = false;
 }
 
@@ -2163,7 +2186,7 @@
         instr->pointer_map(), 1, Safepoint::kNoLazyDeopt);
     __ StoreToSafepointRegisterSlot(x0, temp);
   }
-  DeoptimizeIfSmi(temp, instr);
+  DeoptimizeIfSmi(temp, instr, "instance migration failed");
 }
 
 
@@ -2218,7 +2241,7 @@
   if (instr->hydrogen()->HasMigrationTarget()) {
     __ B(ne, deferred->entry());
   } else {
-    DeoptimizeIf(ne, instr);
+    DeoptimizeIf(ne, instr, "wrong map");
   }
 
   __ Bind(&success);
@@ -2227,7 +2250,7 @@
 
 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
   if (!instr->hydrogen()->value()->type().IsHeapObject()) {
-    DeoptimizeIfSmi(ToRegister(instr->value()), instr);
+    DeoptimizeIfSmi(ToRegister(instr->value()), instr, "Smi");
   }
 }
 
@@ -2235,7 +2258,7 @@
 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
   Register value = ToRegister(instr->value());
   DCHECK(!instr->result() || ToRegister(instr->result()).Is(value));
-  DeoptimizeIfNotSmi(value, instr);
+  DeoptimizeIfNotSmi(value, instr, "not a Smi");
 }
 
 
@@ -2253,15 +2276,15 @@
     __ Cmp(scratch, first);
     if (first == last) {
       // If there is only one type in the interval check for equality.
-      DeoptimizeIf(ne, instr);
+      DeoptimizeIf(ne, instr, "wrong instance type");
     } else if (last == LAST_TYPE) {
       // We don't need to compare with the higher bound of the interval.
-      DeoptimizeIf(lo, instr);
+      DeoptimizeIf(lo, instr, "wrong instance type");
     } else {
       // If we are below the lower bound, set the C flag and clear the Z flag
       // to force a deopt.
       __ Ccmp(scratch, last, CFlag, hs);
-      DeoptimizeIf(hi, instr);
+      DeoptimizeIf(hi, instr, "wrong instance type");
     }
   } else {
     uint8_t mask;
@@ -2271,9 +2294,11 @@
     if (base::bits::IsPowerOfTwo32(mask)) {
       DCHECK((tag == 0) || (tag == mask));
       if (tag == 0) {
-        DeoptimizeIfBitSet(scratch, MaskToBit(mask), instr);
+        DeoptimizeIfBitSet(scratch, MaskToBit(mask), instr,
+                           "wrong instance type");
       } else {
-        DeoptimizeIfBitClear(scratch, MaskToBit(mask), instr);
+        DeoptimizeIfBitClear(scratch, MaskToBit(mask), instr,
+                             "wrong instance type");
       }
     } else {
       if (tag == 0) {
@@ -2282,7 +2307,7 @@
         __ And(scratch, scratch, mask);
         __ Cmp(scratch, tag);
       }
-      DeoptimizeIf(ne, instr);
+      DeoptimizeIf(ne, instr, "wrong instance type");
     }
   }
 }
@@ -2321,7 +2346,8 @@
   __ JumpIfHeapNumber(input, &is_heap_number);
 
   // Check for undefined. Undefined is coverted to zero for clamping conversion.
-  DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr);
+  DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr,
+                      "not a heap number/undefined");
   __ Mov(result, 0);
   __ B(&done);
 
@@ -2626,7 +2652,7 @@
   } else {
     __ Cmp(reg, Operand(object));
   }
-  DeoptimizeIf(ne, instr);
+  DeoptimizeIf(ne, instr, "value mismatch");
 }
 
 
@@ -2650,9 +2676,9 @@
   DCHECK(object.is(result) && object.Is(x0));
   DCHECK(instr->IsMarkedAsCall());
 
-  DeoptimizeIfSmi(object, instr);
+  DeoptimizeIfSmi(object, instr, "Smi");
   __ CompareObjectType(object, temp1, temp1, JS_DATE_TYPE);
-  DeoptimizeIf(ne, instr);
+  DeoptimizeIf(ne, instr, "not a date object");
 
   if (index->value() == 0) {
     __ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset));
@@ -2688,7 +2714,7 @@
     type = Deoptimizer::LAZY;
   }
 
-  Deoptimize(instr, &type, instr->hydrogen()->reason());
+  Deoptimize(instr, instr->hydrogen()->reason(), &type);
 }
 
 
@@ -2702,21 +2728,21 @@
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
-    DeoptimizeIfZero(dividend, instr);
+    DeoptimizeIfZero(dividend, instr, "division by zero");
   }
   // Check for (kMinInt / -1).
   if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
     // Test dividend for kMinInt by subtracting one (cmp) and checking for
     // overflow.
     __ Cmp(dividend, 1);
-    DeoptimizeIf(vs, instr);
+    DeoptimizeIf(vs, instr, "overflow");
   }
   // Deoptimize if remainder will not be 0.
   if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
       divisor != 1 && divisor != -1) {
     int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
     __ Tst(dividend, mask);
-    DeoptimizeIf(ne, instr);
+    DeoptimizeIf(ne, instr, "lost precision");
   }
 
   if (divisor == -1) {  // Nice shortcut, not needed for correctness.
@@ -2744,14 +2770,14 @@
   DCHECK(!AreAliased(dividend, result));
 
   if (divisor == 0) {
-    Deoptimize(instr);
+    Deoptimize(instr, "division by zero");
     return;
   }
 
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
-    DeoptimizeIfZero(dividend, instr);
+    DeoptimizeIfZero(dividend, instr, "minus zero");
   }
 
   __ TruncatingDiv(result, dividend, Abs(divisor));
@@ -2763,7 +2789,7 @@
     __ Sxtw(dividend.X(), dividend);
     __ Mov(temp, divisor);
     __ Smsubl(temp.X(), result, temp, dividend.X());
-    DeoptimizeIfNotZero(temp, instr);
+    DeoptimizeIfNotZero(temp, instr, "lost precision");
   }
 }
 
@@ -2786,7 +2812,7 @@
 
   // Check for x / 0.
   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
-    DeoptimizeIfZero(divisor, instr);
+    DeoptimizeIfZero(divisor, instr, "division by zero");
   }
 
   // Check for (0 / -x) as that will produce negative zero.
@@ -2798,7 +2824,7 @@
     // If the divisor >= 0 (pl, the opposite of mi) set the flags to
     // condition ne, so we don't deopt, ie. positive divisor doesn't deopt.
     __ Ccmp(dividend, 0, NoFlag, mi);
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "minus zero");
   }
 
   // Check for (kMinInt / -1).
@@ -2810,13 +2836,13 @@
     // -1. If overflow is clear, set the flags for condition ne, as the
     // dividend isn't -1, and thus we shouldn't deopt.
     __ Ccmp(divisor, -1, NoFlag, vs);
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "overflow");
   }
 
   // Compute remainder and deopt if it's not zero.
   Register remainder = ToRegister32(instr->temp());
   __ Msub(remainder, result, divisor, dividend);
-  DeoptimizeIfNotZero(remainder, instr);
+  DeoptimizeIfNotZero(remainder, instr, "lost precision");
 }
 
 
@@ -2825,11 +2851,11 @@
   Register result = ToRegister32(instr->result());
 
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    DeoptimizeIfMinusZero(input, instr);
+    DeoptimizeIfMinusZero(input, instr, "minus zero");
   }
 
   __ TryRepresentDoubleAsInt32(result, input, double_scratch());
-  DeoptimizeIf(ne, instr);
+  DeoptimizeIf(ne, instr, "lost precision or NaN");
 
   if (instr->tag_result()) {
     __ SmiTag(result.X());
@@ -2890,7 +2916,7 @@
   __ LoadInstanceDescriptors(map, result);
   __ Ldr(result, FieldMemOperand(result, DescriptorArray::kEnumCacheOffset));
   __ Ldr(result, FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
-  DeoptimizeIfZero(result, instr);
+  DeoptimizeIfZero(result, instr, "no cache");
 
   __ Bind(&done);
 }
@@ -2903,17 +2929,17 @@
   DCHECK(instr->IsMarkedAsCall());
   DCHECK(object.Is(x0));
 
-  DeoptimizeIfRoot(object, Heap::kUndefinedValueRootIndex, instr);
+  DeoptimizeIfRoot(object, Heap::kUndefinedValueRootIndex, instr, "undefined");
 
   __ LoadRoot(null_value, Heap::kNullValueRootIndex);
   __ Cmp(object, null_value);
-  DeoptimizeIf(eq, instr);
+  DeoptimizeIf(eq, instr, "null");
 
-  DeoptimizeIfSmi(object, instr);
+  DeoptimizeIfSmi(object, instr, "Smi");
 
   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
   __ CompareObjectType(object, x1, x1, LAST_JS_PROXY_TYPE);
-  DeoptimizeIf(le, instr);
+  DeoptimizeIf(le, instr, "not a JavaScript object");
 
   Label use_cache, call_runtime;
   __ CheckEnumCache(object, null_value, x1, x2, x3, x4, &call_runtime);
@@ -2927,7 +2953,7 @@
   CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
 
   __ Ldr(x1, FieldMemOperand(object, HeapObject::kMapOffset));
-  DeoptimizeIfNotRoot(x1, Heap::kMetaMapRootIndex, instr);
+  DeoptimizeIfNotRoot(x1, Heap::kMetaMapRootIndex, instr, "wrong map");
 
   __ Bind(&use_cache);
 }
@@ -3320,7 +3346,7 @@
   __ Ldr(result, ContextMemOperand(context, instr->slot_index()));
   if (instr->hydrogen()->RequiresHoleCheck()) {
     if (instr->hydrogen()->DeoptimizesOnHole()) {
-      DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr);
+      DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr, "hole");
     } else {
       Label not_the_hole;
       __ JumpIfNotRoot(result, Heap::kTheHoleValueRootIndex, &not_the_hole);
@@ -3341,7 +3367,7 @@
                                  JSFunction::kPrototypeOrInitialMapOffset));
 
   // Check that the function has a prototype or an initial map.
-  DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr);
+  DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr, "hole");
 
   // If the function does not have an initial map, we're done.
   Label done;
@@ -3361,7 +3387,7 @@
   __ Mov(result, Operand(Handle<Object>(instr->hydrogen()->cell().handle())));
   __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset));
   if (instr->hydrogen()->RequiresHoleCheck()) {
-    DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr);
+    DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr, "hole");
   }
 }
 
@@ -3369,13 +3395,18 @@
 template <class T>
 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
   DCHECK(FLAG_vector_ics);
-  Register vector = ToRegister(instr->temp_vector());
-  DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister()));
-  __ Mov(vector, instr->hydrogen()->feedback_vector());
+  Register vector_register = ToRegister(instr->temp_vector());
+  Register slot_register = VectorLoadICDescriptor::SlotRegister();
+  DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
+  DCHECK(slot_register.is(x0));
+
+  AllowDeferredHandleDereference vector_structure_check;
+  Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
+  __ Mov(vector_register, vector);
   // No need to allocate this register.
-  DCHECK(VectorLoadICDescriptor::SlotRegister().is(x0));
-  __ Mov(VectorLoadICDescriptor::SlotRegister(),
-         Smi::FromInt(instr->hydrogen()->slot()));
+  FeedbackVectorICSlot slot = instr->hydrogen()->slot();
+  int index = vector->GetIndex(slot);
+  __ Mov(slot_register, Smi::FromInt(index));
 }
 
 
@@ -3389,7 +3420,7 @@
     EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
+  Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3492,7 +3523,7 @@
         if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
           // Deopt if value > 0x80000000.
           __ Tst(result, 0xFFFFFFFF80000000);
-          DeoptimizeIf(ne, instr);
+          DeoptimizeIf(ne, instr, "negative value");
         }
         break;
       case FLOAT32_ELEMENTS:
@@ -3589,7 +3620,7 @@
     STATIC_ASSERT(kHoleNanInt64 == 0x7fffffffffffffff);
     __ Ldr(scratch, mem_op);
     __ Cmn(scratch, 1);
-    DeoptimizeIf(vs, instr);
+    DeoptimizeIf(vs, instr, "hole");
   }
 }
 
@@ -3627,9 +3658,9 @@
 
   if (instr->hydrogen()->RequiresHoleCheck()) {
     if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
-      DeoptimizeIfNotSmi(result, instr);
+      DeoptimizeIfNotSmi(result, instr, "not a Smi");
     } else {
-      DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr);
+      DeoptimizeIfRoot(result, Heap::kTheHoleValueRootIndex, instr, "hole");
     }
   }
 }
@@ -3643,7 +3674,7 @@
     EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
-  Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
+  Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 
   DCHECK(ToRegister(instr->result()).Is(x0));
@@ -3662,6 +3693,7 @@
   }
 
   if (instr->hydrogen()->representation().IsDouble()) {
+    DCHECK(access.IsInobject());
     FPRegister result = ToDoubleRegister(instr->result());
     __ Ldr(result, FieldMemOperand(object, offset));
     return;
@@ -3699,7 +3731,8 @@
     EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
 
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
+  Handle<Code> ic =
+      CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 
   DCHECK(ToRegister(instr->result()).is(x0));
@@ -3731,7 +3764,7 @@
     Register result = r.IsSmi() ? ToRegister(instr->result())
                                 : ToRegister32(instr->result());
     __ Abs(result, input);
-    DeoptimizeIf(vs, instr);
+    DeoptimizeIf(vs, instr, "overflow");
   }
 }
 
@@ -3883,7 +3916,7 @@
   Register result = ToRegister(instr->result());
 
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    DeoptimizeIfMinusZero(input, instr);
+    DeoptimizeIfMinusZero(input, instr, "minus zero");
   }
 
   __ Fcvtms(result, input);
@@ -3893,7 +3926,7 @@
   __ Cmp(result, Operand(result, SXTW));
   //  - The input was not NaN.
   __ Fccmp(input, input, NoFlag, eq);
-  DeoptimizeIf(ne, instr);
+  DeoptimizeIf(ne, instr, "lost precision or NaN");
 }
 
 
@@ -3919,13 +3952,13 @@
   // If the divisor is negative, we have to negate and handle edge cases.
   __ Negs(result, dividend);
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "minus zero");
   }
 
   // Dividing by -1 is basically negation, unless we overflow.
   if (divisor == -1) {
     if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
-      DeoptimizeIf(vs, instr);
+      DeoptimizeIf(vs, instr, "overflow");
     }
     return;
   }
@@ -3948,14 +3981,14 @@
   DCHECK(!AreAliased(dividend, result));
 
   if (divisor == 0) {
-    Deoptimize(instr);
+    Deoptimize(instr, "division by zero");
     return;
   }
 
   // Check for (0 / -x) that will produce negative zero.
   HMathFloorOfDiv* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
-    DeoptimizeIfZero(dividend, instr);
+    DeoptimizeIfZero(dividend, instr, "minus zero");
   }
 
   // Easy case: We need no dynamic check for the dividend and the flooring
@@ -3998,14 +4031,14 @@
   __ Sdiv(result, dividend, divisor);
 
   // Check for x / 0.
-  DeoptimizeIfZero(divisor, instr);
+  DeoptimizeIfZero(divisor, instr, "division by zero");
 
   // Check for (kMinInt / -1).
   if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
     // The V flag will be set iff dividend == kMinInt.
     __ Cmp(dividend, 1);
     __ Ccmp(divisor, -1, NoFlag, vs);
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "overflow");
   }
 
   // Check for (0 / -x) that will produce negative zero.
@@ -4015,7 +4048,7 @@
     // "divisor" can't be null because the code would have already been
     // deoptimized. The Z flag is set only if (divisor < 0) and (dividend == 0).
     // In this case we need to deoptimize to produce a -0.
-    DeoptimizeIf(eq, instr);
+    DeoptimizeIf(eq, instr, "minus zero");
   }
 
   Label done;
@@ -4174,18 +4207,18 @@
 
   // Deoptimize if the result > 1, as it must be larger than 32 bits.
   __ Cmp(result, 1);
-  DeoptimizeIf(hi, instr);
+  DeoptimizeIf(hi, instr, "overflow");
 
   // Deoptimize for negative inputs, which at this point are only numbers in
   // the range [-0.5, -0.0]
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     __ Fmov(result, input);
-    DeoptimizeIfNegative(result, instr);
+    DeoptimizeIfNegative(result, instr, "minus zero");
   }
 
   // Deoptimize if the input was NaN.
   __ Fcmp(input, dot_five);
-  DeoptimizeIf(vs, instr);
+  DeoptimizeIf(vs, instr, "NaN");
 
   // Now, the only unhandled inputs are in the range [0.0, 1.5[ (or [-0.5, 1.5[
   // if we didn't generate a -0.0 bailout). If input >= 0.5 then return 1,
@@ -4263,7 +4296,7 @@
     __ And(dividend, dividend, mask);
     __ Negs(dividend, dividend);
     if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      DeoptimizeIf(eq, instr);
+      DeoptimizeIf(eq, instr, "minus zero");
     }
     __ B(&done);
   }
@@ -4282,7 +4315,7 @@
   DCHECK(!AreAliased(dividend, result, temp));
 
   if (divisor == 0) {
-    Deoptimize(instr);
+    Deoptimize(instr, "division by zero");
     return;
   }
 
@@ -4296,7 +4329,7 @@
   if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label remainder_not_zero;
     __ Cbnz(result, &remainder_not_zero);
-    DeoptimizeIfNegative(dividend, instr);
+    DeoptimizeIfNegative(dividend, instr, "minus zero");
     __ bind(&remainder_not_zero);
   }
 }
@@ -4311,12 +4344,12 @@
   // modulo = dividend - quotient * divisor
   __ Sdiv(result, dividend, divisor);
   if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
-    DeoptimizeIfZero(divisor, instr);
+    DeoptimizeIfZero(divisor, instr, "division by zero");
   }
   __ Msub(result, result, divisor, dividend);
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     __ Cbnz(result, &done);
-    DeoptimizeIfNegative(dividend, instr);
+    DeoptimizeIfNegative(dividend, instr, "minus zero");
   }
   __ Bind(&done);
 }
@@ -4339,10 +4372,10 @@
   if (bailout_on_minus_zero) {
     if (right < 0) {
       // The result is -0 if right is negative and left is zero.
-      DeoptimizeIfZero(left, instr);
+      DeoptimizeIfZero(left, instr, "minus zero");
     } else if (right == 0) {
       // The result is -0 if the right is zero and the left is negative.
-      DeoptimizeIfNegative(left, instr);
+      DeoptimizeIfNegative(left, instr, "minus zero");
     }
   }
 
@@ -4352,7 +4385,7 @@
       if (can_overflow) {
         // Only 0x80000000 can overflow here.
         __ Negs(result, left);
-        DeoptimizeIf(vs, instr);
+        DeoptimizeIf(vs, instr, "overflow");
       } else {
         __ Neg(result, left);
       }
@@ -4368,7 +4401,7 @@
     case 2:
       if (can_overflow) {
         __ Adds(result, left, left);
-        DeoptimizeIf(vs, instr);
+        DeoptimizeIf(vs, instr, "overflow");
       } else {
         __ Add(result, left, left);
       }
@@ -4387,7 +4420,7 @@
           DCHECK(!AreAliased(scratch, left));
           __ Cls(scratch, left);
           __ Cmp(scratch, right_log2);
-          DeoptimizeIf(lt, instr);
+          DeoptimizeIf(lt, instr, "overflow");
         }
 
         if (right >= 0) {
@@ -4397,7 +4430,7 @@
           // result = -left << log2(-right)
           if (can_overflow) {
             __ Negs(result, Operand(left, LSL, right_log2));
-            DeoptimizeIf(vs, instr);
+            DeoptimizeIf(vs, instr, "overflow");
           } else {
             __ Neg(result, Operand(left, LSL, right_log2));
           }
@@ -4455,13 +4488,13 @@
     //  - If so (eq), set N (mi) if left + right is negative.
     //  - Otherwise, clear N.
     __ Ccmn(left, right, NoFlag, eq);
-    DeoptimizeIf(mi, instr);
+    DeoptimizeIf(mi, instr, "minus zero");
   }
 
   if (can_overflow) {
     __ Smull(result.X(), left, right);
     __ Cmp(result.X(), Operand(result, SXTW));
-    DeoptimizeIf(ne, instr);
+    DeoptimizeIf(ne, instr, "overflow");
   } else {
     __ Mul(result, left, right);
   }
@@ -4485,7 +4518,7 @@
     //  - If so (eq), set N (mi) if left + right is negative.
     //  - Otherwise, clear N.
     __ Ccmn(left, right, NoFlag, eq);
-    DeoptimizeIf(mi, instr);
+    DeoptimizeIf(mi, instr, "minus zero");
   }
 
   STATIC_ASSERT((kSmiShift == 32) && (kSmiTag == 0));
@@ -4493,7 +4526,7 @@
     __ Smulh(result, left, right);
     __ Cmp(result, Operand(result.W(), SXTW));
     __ SmiTag(result);
-    DeoptimizeIf(ne, instr);
+    DeoptimizeIf(ne, instr, "overflow");
   } else {
     if (AreAliased(result, left, right)) {
       // All three registers are the same: half untag the input and then
@@ -4669,13 +4702,14 @@
     // Load heap number.
     __ Ldr(result, FieldMemOperand(input, HeapNumber::kValueOffset));
     if (instr->hydrogen()->deoptimize_on_minus_zero()) {
-      DeoptimizeIfMinusZero(result, instr);
+      DeoptimizeIfMinusZero(result, instr, "minus zero");
     }
     __ B(&done);
 
     if (can_convert_undefined_to_nan) {
       __ Bind(&convert_undefined);
-      DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr);
+      DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr,
+                          "not a heap number/undefined");
 
       __ LoadRoot(scratch, Heap::kNanValueRootIndex);
       __ Ldr(result, FieldMemOperand(scratch, HeapNumber::kValueOffset));
@@ -4766,6 +4800,7 @@
     int parameter_count = ToInteger32(instr->constant_parameter_count());
     __ Drop(parameter_count + 1);
   } else {
+    DCHECK(info()->IsStub());  // Functions would need to drop one more value.
     Register parameter_count = ToRegister(instr->parameter_count());
     __ DropBySMI(parameter_count);
   }
@@ -4868,7 +4903,7 @@
   Register output = ToRegister(instr->result());
   if (hchange->CheckFlag(HValue::kCanOverflow) &&
       hchange->value()->CheckFlag(HValue::kUint32)) {
-    DeoptimizeIfNegative(input.W(), instr);
+    DeoptimizeIfNegative(input.W(), instr, "overflow");
   }
   __ SmiTag(output, input);
 }
@@ -4880,7 +4915,7 @@
   Label done, untag;
 
   if (instr->needs_check()) {
-    DeoptimizeIfNotSmi(input, instr);
+    DeoptimizeIfNotSmi(input, instr, "not a Smi");
   }
 
   __ Bind(&untag);
@@ -4905,7 +4940,7 @@
         if (instr->can_deopt()) {
           // If `left >>> right` >= 0x80000000, the result is not representable
           // in a signed 32-bit smi.
-          DeoptimizeIfNegative(result, instr);
+          DeoptimizeIfNegative(result, instr, "negative value");
         }
         break;
       default: UNREACHABLE();
@@ -4915,7 +4950,7 @@
     int shift_count = JSShiftAmountFromLConstant(right_op);
     if (shift_count == 0) {
       if ((instr->op() == Token::SHR) && instr->can_deopt()) {
-        DeoptimizeIfNegative(left, instr);
+        DeoptimizeIfNegative(left, instr, "negative value");
       }
       __ Mov(result, left, kDiscardForSameWReg);
     } else {
@@ -4968,7 +5003,7 @@
         if (instr->can_deopt()) {
           // If `left >>> right` >= 0x80000000, the result is not representable
           // in a signed 32-bit smi.
-          DeoptimizeIfNegative(result, instr);
+          DeoptimizeIfNegative(result, instr, "negative value");
         }
         break;
       default: UNREACHABLE();
@@ -4978,7 +5013,7 @@
     int shift_count = JSShiftAmountFromLConstant(right_op);
     if (shift_count == 0) {
       if ((instr->op() == Token::SHR) && instr->can_deopt()) {
-        DeoptimizeIfNegative(left, instr);
+        DeoptimizeIfNegative(left, instr, "negative value");
       }
       __ Mov(result, left);
     } else {
@@ -5017,7 +5052,6 @@
   Register scratch2 = x6;
   DCHECK(instr->IsMarkedAsCall());
 
-  ASM_UNIMPLEMENTED_BREAK("DoDeclareGlobals");
   // TODO(all): if Mov could handle object in new space then it could be used
   // here.
   __ LoadHeapObject(scratch1, instr->hydrogen()->pairs());
@@ -5107,7 +5141,7 @@
   if (instr->hydrogen()->RequiresHoleCheck()) {
     __ Ldr(scratch, target);
     if (instr->hydrogen()->DeoptimizesOnHole()) {
-      DeoptimizeIfRoot(scratch, Heap::kTheHoleValueRootIndex, instr);
+      DeoptimizeIfRoot(scratch, Heap::kTheHoleValueRootIndex, instr, "hole");
     } else {
       __ JumpIfNotRoot(scratch, Heap::kTheHoleValueRootIndex, &skip_assignment);
     }
@@ -5145,7 +5179,7 @@
   if (instr->hydrogen()->RequiresHoleCheck()) {
     Register payload = ToRegister(instr->temp2());
     __ Ldr(payload, FieldMemOperand(cell, Cell::kValueOffset));
-    DeoptimizeIfRoot(payload, Heap::kTheHoleValueRootIndex, instr);
+    DeoptimizeIfRoot(payload, Heap::kTheHoleValueRootIndex, instr, "hole");
   }
 
   // Store the value.
@@ -5349,7 +5383,7 @@
 
   __ AssertNotSmi(object);
 
-  if (representation.IsDouble()) {
+  if (!FLAG_unbox_double_fields && representation.IsDouble()) {
     DCHECK(access.IsInobject());
     DCHECK(!instr->hydrogen()->has_transition());
     DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
@@ -5358,8 +5392,6 @@
     return;
   }
 
-  Register value = ToRegister(instr->value());
-
   DCHECK(!representation.IsSmi() ||
          !instr->value()->IsConstantOperand() ||
          IsInteger32Constant(LConstantOperand::cast(instr->value())));
@@ -5391,8 +5423,12 @@
     destination = temp0;
   }
 
-  if (representation.IsSmi() &&
-     instr->hydrogen()->value()->representation().IsInteger32()) {
+  if (FLAG_unbox_double_fields && representation.IsDouble()) {
+    DCHECK(access.IsInobject());
+    FPRegister value = ToDoubleRegister(instr->value());
+    __ Str(value, FieldMemOperand(object, offset));
+  } else if (representation.IsSmi() &&
+             instr->hydrogen()->value()->representation().IsInteger32()) {
     DCHECK(instr->hydrogen()->store_mode() == STORE_TO_INITIALIZED_ENTRY);
 #ifdef DEBUG
     Register temp0 = ToRegister(instr->temp0());
@@ -5407,12 +5443,15 @@
 #endif
     STATIC_ASSERT(static_cast<unsigned>(kSmiValueSize) == kWRegSizeInBits);
     STATIC_ASSERT(kSmiTag == 0);
+    Register value = ToRegister(instr->value());
     __ Store(value, UntagSmiFieldMemOperand(destination, offset),
              Representation::Integer32());
   } else {
+    Register value = ToRegister(instr->value());
     __ Store(value, FieldMemOperand(destination, offset), representation);
   }
   if (instr->hydrogen()->NeedsWriteBarrier()) {
+    Register value = ToRegister(instr->value());
     __ RecordWriteField(destination,
                         offset,
                         value,                        // Clobbered.
@@ -5562,7 +5601,7 @@
 
   if (can_overflow) {
     __ Subs(result, left, right);
-    DeoptimizeIf(vs, instr);
+    DeoptimizeIf(vs, instr, "overflow");
   } else {
     __ Sub(result, left, right);
   }
@@ -5576,7 +5615,7 @@
   Operand right = ToOperand(instr->right());
   if (can_overflow) {
     __ Subs(result, left, right);
-    DeoptimizeIf(vs, instr);
+    DeoptimizeIf(vs, instr, "overflow");
   } else {
     __ Sub(result, left, right);
   }
@@ -5616,7 +5655,8 @@
 
     // Output contains zero, undefined is converted to zero for truncating
     // conversions.
-    DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr);
+    DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex, instr,
+                        "not a heap number/undefined/true/false");
   } else {
     Register output = ToRegister32(instr->result());
     DoubleRegister dbl_scratch2 = ToDoubleRegister(temp2);
@@ -5774,7 +5814,7 @@
 
   Label no_memento_found;
   __ TestJSArrayForAllocationMemento(object, temp1, temp2, &no_memento_found);
-  DeoptimizeIf(eq, instr);
+  DeoptimizeIf(eq, instr, "memento found");
   __ Bind(&no_memento_found);
 }
 
@@ -5899,7 +5939,7 @@
   Register temp = ToRegister(instr->temp());
   __ Ldr(temp, FieldMemOperand(object, HeapObject::kMapOffset));
   __ Cmp(map, temp);
-  DeoptimizeIf(ne, instr);
+  DeoptimizeIf(ne, instr, "wrong map");
 }
 
 
@@ -5933,10 +5973,10 @@
   __ JumpIfRoot(receiver, Heap::kUndefinedValueRootIndex, &global_object);
 
   // Deoptimize if the receiver is not a JS object.
-  DeoptimizeIfSmi(receiver, instr);
+  DeoptimizeIfSmi(receiver, instr, "Smi");
   __ CompareObjectType(receiver, result, result, FIRST_SPEC_OBJECT_TYPE);
   __ B(ge, &copy_receiver);
-  Deoptimize(instr);
+  Deoptimize(instr, "not a JavaScript object");
 
   __ Bind(&global_object);
   __ Ldr(result, FieldMemOperand(function, JSFunction::kContextOffset));
@@ -5979,10 +6019,11 @@
           object_(object),
           index_(index) {
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredLoadMutableDouble(instr_, result_, object_, index_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LLoadFieldByIndex* instr_;
     Register result_;
diff --git a/src/arm64/lithium-codegen-arm64.h b/src/arm64/lithium-codegen-arm64.h
index a141dfa..a73bb8c 100644
--- a/src/arm64/lithium-codegen-arm64.h
+++ b/src/arm64/lithium-codegen-arm64.h
@@ -217,32 +217,27 @@
                         BranchType branch_type, Register reg = NoReg,
                         int bit = -1,
                         Deoptimizer::BailoutType* override_bailout_type = NULL);
-  void Deoptimize(LInstruction* instr,
-                  Deoptimizer::BailoutType* override_bailout_type = NULL,
-                  const char* detail = NULL);
-  void DeoptimizeIf(Condition cond, LInstruction* instr,
-                    const char* detail = NULL);
-  void DeoptimizeIfZero(Register rt, LInstruction* instr,
-                        const char* detail = NULL);
+  void Deoptimize(LInstruction* instr, const char* detail,
+                  Deoptimizer::BailoutType* override_bailout_type = NULL);
+  void DeoptimizeIf(Condition cond, LInstruction* instr, const char* detail);
+  void DeoptimizeIfZero(Register rt, LInstruction* instr, const char* detail);
   void DeoptimizeIfNotZero(Register rt, LInstruction* instr,
-                           const char* detail = NULL);
+                           const char* detail);
   void DeoptimizeIfNegative(Register rt, LInstruction* instr,
-                            const char* detail = NULL);
-  void DeoptimizeIfSmi(Register rt, LInstruction* instr,
-                       const char* detail = NULL);
-  void DeoptimizeIfNotSmi(Register rt, LInstruction* instr,
-                          const char* detail = NULL);
+                            const char* detail);
+  void DeoptimizeIfSmi(Register rt, LInstruction* instr, const char* detail);
+  void DeoptimizeIfNotSmi(Register rt, LInstruction* instr, const char* detail);
   void DeoptimizeIfRoot(Register rt, Heap::RootListIndex index,
-                        LInstruction* instr, const char* detail = NULL);
+                        LInstruction* instr, const char* detail);
   void DeoptimizeIfNotRoot(Register rt, Heap::RootListIndex index,
-                           LInstruction* instr, const char* detail = NULL);
+                           LInstruction* instr, const char* detail);
   void DeoptimizeIfNotHeapNumber(Register object, LInstruction* instr);
   void DeoptimizeIfMinusZero(DoubleRegister input, LInstruction* instr,
-                             const char* detail = NULL);
+                             const char* detail);
   void DeoptimizeIfBitSet(Register rt, int bit, LInstruction* instr,
-                          const char* detail = NULL);
+                          const char* detail);
   void DeoptimizeIfBitClear(Register rt, int bit, LInstruction* instr,
-                            const char* detail = NULL);
+                            const char* detail);
 
   MemOperand PrepareKeyedExternalArrayOperand(Register key,
                                               Register base,
diff --git a/src/arm64/macro-assembler-arm64-inl.h b/src/arm64/macro-assembler-arm64-inl.h
index 23767e4..b691e21 100644
--- a/src/arm64/macro-assembler-arm64-inl.h
+++ b/src/arm64/macro-assembler-arm64-inl.h
@@ -825,6 +825,12 @@
 }
 
 
+void MacroAssembler::Frintp(const FPRegister& fd, const FPRegister& fn) {
+  DCHECK(allow_macro_instructions_);
+  frintp(fd, fn);
+}
+
+
 void MacroAssembler::Frintz(const FPRegister& fd, const FPRegister& fn) {
   DCHECK(allow_macro_instructions_);
   frintz(fd, fn);
@@ -1120,6 +1126,14 @@
 }
 
 
+void MacroAssembler::Umull(const Register& rd, const Register& rn,
+                           const Register& rm) {
+  DCHECK(allow_macro_instructions_);
+  DCHECK(!rd.IsZero());
+  umaddl(rd, rn, rm, xzr);
+}
+
+
 void MacroAssembler::Stnp(const CPURegister& rt,
                           const CPURegister& rt2,
                           const MemOperand& dst) {
@@ -1230,14 +1244,7 @@
 void MacroAssembler::BumpSystemStackPointer(const Operand& space) {
   DCHECK(!csp.Is(sp_));
   if (!TmpList()->IsEmpty()) {
-    if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) {
-      UseScratchRegisterScope temps(this);
-      Register temp = temps.AcquireX();
-      Sub(temp, StackPointer(), space);
-      Bic(csp, temp, 0xf);
-    } else {
-      Sub(csp, StackPointer(), space);
-    }
+    Sub(csp, StackPointer(), space);
   } else {
     // TODO(jbramley): Several callers rely on this not using scratch
     // registers, so we use the assembler directly here. However, this means
@@ -1274,11 +1281,7 @@
   DCHECK(emit_debug_code());
   DCHECK(!csp.Is(sp_));
   { InstructionAccurateScope scope(this);
-    if (CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) {
-      bic(csp, StackPointer(), 0xf);
-    } else {
-      mov(csp, StackPointer());
-    }
+    mov(csp, StackPointer());
   }
   AssertStackConsistency();
 }
diff --git a/src/arm64/macro-assembler-arm64.cc b/src/arm64/macro-assembler-arm64.cc
index f670403..0253e7c 100644
--- a/src/arm64/macro-assembler-arm64.cc
+++ b/src/arm64/macro-assembler-arm64.cc
@@ -13,7 +13,7 @@
 #include "src/cpu-profiler.h"
 #include "src/debug.h"
 #include "src/isolate-inl.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -1308,7 +1308,7 @@
   // Avoid emitting code when !use_real_abort() since non-real aborts cause too
   // much code to be generated.
   if (emit_debug_code() && use_real_aborts()) {
-    if (csp.Is(StackPointer()) || CpuFeatures::IsSupported(ALWAYS_ALIGN_CSP)) {
+    if (csp.Is(StackPointer())) {
       // Always check the alignment of csp if ALWAYS_ALIGN_CSP is true.  We
       // can't check the alignment of csp without using a scratch register (or
       // clobbering the flags), but the processor (or simulator) will abort if
@@ -3064,6 +3064,13 @@
 }
 
 
+void MacroAssembler::EnterFrame(StackFrame::Type type,
+                                bool load_constant_pool_pointer_reg) {
+  // Out-of-line constant pool not implemented on arm64.
+  UNREACHABLE();
+}
+
+
 void MacroAssembler::EnterFrame(StackFrame::Type type) {
   DCHECK(jssp.Is(StackPointer()));
   UseScratchRegisterScope temps(this);
@@ -3781,23 +3788,38 @@
 }
 
 
-void MacroAssembler::DispatchMap(Register obj,
-                                 Register scratch,
-                                 Handle<Map> map,
-                                 Handle<Code> success,
-                                 SmiCheckType smi_check_type) {
+void MacroAssembler::DispatchWeakMap(Register obj, Register scratch1,
+                                     Register scratch2, Handle<WeakCell> cell,
+                                     Handle<Code> success,
+                                     SmiCheckType smi_check_type) {
   Label fail;
   if (smi_check_type == DO_SMI_CHECK) {
     JumpIfSmi(obj, &fail);
   }
-  Ldr(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
-  Cmp(scratch, Operand(map));
+  Ldr(scratch1, FieldMemOperand(obj, HeapObject::kMapOffset));
+  CmpWeakValue(scratch1, cell, scratch2);
   B(ne, &fail);
   Jump(success, RelocInfo::CODE_TARGET);
   Bind(&fail);
 }
 
 
+void MacroAssembler::CmpWeakValue(Register value, Handle<WeakCell> cell,
+                                  Register scratch) {
+  Mov(scratch, Operand(cell));
+  Ldr(scratch, FieldMemOperand(scratch, WeakCell::kValueOffset));
+  Cmp(value, scratch);
+}
+
+
+void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell,
+                                   Label* miss) {
+  Mov(value, Operand(cell));
+  Ldr(value, FieldMemOperand(value, WeakCell::kValueOffset));
+  JumpIfSmi(value, miss);
+}
+
+
 void MacroAssembler::TestMapBitfield(Register object, uint64_t mask) {
   UseScratchRegisterScope temps(this);
   Register temp = temps.AcquireX();
@@ -4080,7 +4102,7 @@
 
   // Check the context is a native context.
   if (emit_debug_code()) {
-    // Read the first word and compare to the global_context_map.
+    // Read the first word and compare to the native_context_map.
     Ldr(scratch2, FieldMemOperand(scratch1, HeapObject::kMapOffset));
     CompareRoot(scratch2, Heap::kNativeContextMapRootIndex);
     Check(eq, kExpectedNativeContext);
@@ -4206,10 +4228,11 @@
   }
 
   Bind(&done);
-  // Check that the value is a normal property.
+  // Check that the value is a field property.
   const int kDetailsOffset =
       SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
   Ldrsw(scratch1, UntagSmiFieldMemOperand(scratch2, kDetailsOffset));
+  DCHECK_EQ(FIELD, 0);
   TestAndBranchIfAnySet(scratch1, PropertyDetails::TypeField::kMask, miss);
 
   // Get the value at the masked, scaled index and return.
@@ -4626,17 +4649,6 @@
 }
 
 
-void MacroAssembler::CheckMapDeprecated(Handle<Map> map,
-                                        Register scratch,
-                                        Label* if_deprecated) {
-  if (map->CanBeDeprecated()) {
-    Mov(scratch, Operand(map));
-    Ldrsw(scratch, FieldMemOperand(scratch, Map::kBitField3Offset));
-    TestAndBranchIfAnySet(scratch, Map::Deprecated::kMask, if_deprecated);
-  }
-}
-
-
 void MacroAssembler::JumpIfBlack(Register object,
                                  Register scratch0,
                                  Register scratch1,
diff --git a/src/arm64/macro-assembler-arm64.h b/src/arm64/macro-assembler-arm64.h
index 7a106a1..ee43589 100644
--- a/src/arm64/macro-assembler-arm64.h
+++ b/src/arm64/macro-assembler-arm64.h
@@ -422,6 +422,7 @@
   inline void Frinta(const FPRegister& fd, const FPRegister& fn);
   inline void Frintm(const FPRegister& fd, const FPRegister& fn);
   inline void Frintn(const FPRegister& fd, const FPRegister& fn);
+  inline void Frintp(const FPRegister& fd, const FPRegister& fn);
   inline void Frintz(const FPRegister& fd, const FPRegister& fn);
   inline void Fsqrt(const FPRegister& fd, const FPRegister& fn);
   inline void Fsub(const FPRegister& fd,
@@ -489,6 +490,7 @@
   inline void Smulh(const Register& rd,
                     const Register& rn,
                     const Register& rm);
+  inline void Umull(const Register& rd, const Register& rn, const Register& rm);
   inline void Stnp(const CPURegister& rt,
                    const CPURegister& rt2,
                    const MemOperand& dst);
@@ -759,9 +761,9 @@
   // it can be evidence of a potential bug because the ABI forbids accesses
   // below csp.
   //
-  // If StackPointer() is the system stack pointer (csp) or ALWAYS_ALIGN_CSP is
-  // enabled, then csp will be dereferenced to  cause the processor
-  // (or simulator) to abort if it is not properly aligned.
+  // If StackPointer() is the system stack pointer (csp), then csp will be
+  // dereferenced to cause the processor (or simulator) to abort if it is not
+  // properly aligned.
   //
   // If emit_debug_code() is false, this emits no code.
   void AssertStackConsistency();
@@ -829,9 +831,7 @@
   inline void BumpSystemStackPointer(const Operand& space);
 
   // Re-synchronizes the system stack pointer (csp) with the current stack
-  // pointer (according to StackPointer()).  This function will ensure the
-  // new value of the system stack pointer is remains aligned to 16 bytes, and
-  // is lower than or equal to the value of the current stack pointer.
+  // pointer (according to StackPointer()).
   //
   // This method asserts that StackPointer() is not csp, since the call does
   // not make sense in that context.
@@ -1478,14 +1478,19 @@
                 Label* fail,
                 SmiCheckType smi_check_type);
 
-  // Check if the map of an object is equal to a specified map and branch to a
-  // specified target if equal. Skip the smi check if not required (object is
-  // known to be a heap object)
-  void DispatchMap(Register obj,
-                   Register scratch,
-                   Handle<Map> map,
-                   Handle<Code> success,
-                   SmiCheckType smi_check_type);
+  // Check if the map of an object is equal to a specified weak map and branch
+  // to a specified target if equal. Skip the smi check if not required
+  // (object is known to be a heap object)
+  void DispatchWeakMap(Register obj, Register scratch1, Register scratch2,
+                       Handle<WeakCell> cell, Handle<Code> success,
+                       SmiCheckType smi_check_type);
+
+  // Compare the given value and the value of weak cell.
+  void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch);
+
+  // Load the value of the weak cell in the value register. Branch to the given
+  // miss label if the weak cell was cleared.
+  void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss);
 
   // Test the bitfield of the heap object map with mask and set the condition
   // flags. The object register is preserved.
@@ -1627,6 +1632,7 @@
 
   // Activation support.
   void EnterFrame(StackFrame::Type type);
+  void EnterFrame(StackFrame::Type type, bool load_constant_pool_pointer_reg);
   void LeaveFrame(StackFrame::Type type);
 
   // Returns map with validated enum cache in object register.
@@ -1774,10 +1780,6 @@
                           int mask,
                           Label* if_all_clear);
 
-  void CheckMapDeprecated(Handle<Map> map,
-                          Register scratch,
-                          Label* if_deprecated);
-
   // Check if object is in new space and jump accordingly.
   // Register 'object' is preserved.
   void JumpIfNotInNewSpace(Register object,
diff --git a/src/arm64/simulator-arm64.cc b/src/arm64/simulator-arm64.cc
index 129252b..bc524af 100644
--- a/src/arm64/simulator-arm64.cc
+++ b/src/arm64/simulator-arm64.cc
@@ -413,7 +413,7 @@
 
   // Reset debug helpers.
   breakpoints_.empty();
-  break_on_next_= false;
+  break_on_next_ = false;
 }
 
 
@@ -2463,6 +2463,12 @@
         set_sreg(fd, FPRoundInt(sreg(fn), FPNegativeInfinity)); break;
     case FRINTM_d:
         set_dreg(fd, FPRoundInt(dreg(fn), FPNegativeInfinity)); break;
+    case FRINTP_s:
+      set_sreg(fd, FPRoundInt(sreg(fn), FPPositiveInfinity));
+      break;
+    case FRINTP_d:
+      set_dreg(fd, FPRoundInt(dreg(fn), FPPositiveInfinity));
+      break;
     case FRINTN_s: set_sreg(fd, FPRoundInt(sreg(fn), FPTieEven)); break;
     case FRINTN_d: set_dreg(fd, FPRoundInt(dreg(fn), FPTieEven)); break;
     case FRINTZ_s: set_sreg(fd, FPRoundInt(sreg(fn), FPZero)); break;
@@ -2767,6 +2773,10 @@
       // We always use floor(value).
       break;
     }
+    case FPPositiveInfinity: {
+      int_result = ceil(value);
+      break;
+    }
     default: UNIMPLEMENTED();
   }
   return int_result;
diff --git a/src/array-iterator.js b/src/array-iterator.js
index 5ced9da..17d55f0 100644
--- a/src/array-iterator.js
+++ b/src/array-iterator.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
+"use strict";
 
 
 // This file relies on the fact that the following declaration has been made
@@ -112,6 +112,8 @@
   %FunctionSetName(ArrayIteratorIterator, '[Symbol.iterator]');
   %AddNamedProperty(ArrayIterator.prototype, symbolIterator,
                     ArrayIteratorIterator, DONT_ENUM);
+  %AddNamedProperty(ArrayIterator.prototype, symbolToStringTag,
+                    "Array Iterator", READ_ONLY | DONT_ENUM);
 }
 SetUpArrayIterator();
 
diff --git a/src/array.js b/src/array.js
index 81f1f65..c702d8c 100644
--- a/src/array.js
+++ b/src/array.js
@@ -90,7 +90,8 @@
   // Only use the sparse variant on arrays that are likely to be sparse and the
   // number of elements touched in the operation is relatively small compared to
   // the overall size of the array.
-  if (!is_array || length < 1000 || %IsObserved(array)) {
+  if (!is_array || length < 1000 || %IsObserved(array) ||
+      %HasComplexElements(array)) {
     return false;
   }
   if (!%_IsSmi(length)) {
@@ -203,7 +204,7 @@
 
 // This function implements the optimized splice implementation that can use
 // special array operations to handle sparse arrays in a sensible fashion.
-function SmartSlice(array, start_i, del_count, len, deleted_elements) {
+function SparseSlice(array, start_i, del_count, len, deleted_elements) {
   // Move deleted elements to a new array (the return value from splice).
   var indices = %GetArrayKeys(array, start_i + del_count);
   if (IS_NUMBER(indices)) {
@@ -211,7 +212,7 @@
     for (var i = start_i; i < limit; ++i) {
       var current = array[i];
       if (!IS_UNDEFINED(current) || i in array) {
-        deleted_elements[i - start_i] = current;
+        %AddElement(deleted_elements, i - start_i, current, NONE);
       }
     }
   } else {
@@ -222,7 +223,7 @@
         if (key >= start_i) {
           var current = array[key];
           if (!IS_UNDEFINED(current) || key in array) {
-            deleted_elements[key - start_i] = current;
+            %AddElement(deleted_elements, key - start_i, current, NONE);
           }
         }
       }
@@ -233,9 +234,14 @@
 
 // This function implements the optimized splice implementation that can use
 // special array operations to handle sparse arrays in a sensible fashion.
-function SmartMove(array, start_i, del_count, len, num_additional_args) {
+function SparseMove(array, start_i, del_count, len, num_additional_args) {
+  // Bail out if no moving is necessary.
+  if (num_additional_args === del_count) return;
   // Move data to new array.
-  var new_array = new InternalArray(len - del_count + num_additional_args);
+  var new_array = new InternalArray(
+      // Clamp array length to 2^32-1 to avoid early RangeError.
+      MathMin(len - del_count + num_additional_args, 0xffffffff));
+  var big_indices;
   var indices = %GetArrayKeys(array, len);
   if (IS_NUMBER(indices)) {
     var limit = indices;
@@ -264,7 +270,12 @@
         } else if (key >= start_i + del_count) {
           var current = array[key];
           if (!IS_UNDEFINED(current) || key in array) {
-            new_array[key - del_count + num_additional_args] = current;
+            var new_key = key - del_count + num_additional_args;
+            new_array[new_key] = current;
+            if (new_key > 0xffffffff) {
+              big_indices = big_indices || new InternalArray();
+              big_indices.push(new_key);
+            }
           }
         }
       }
@@ -272,6 +283,14 @@
   }
   // Move contents of new_array into this array
   %MoveArrayContents(new_array, array);
+  // Add any moved values that aren't elements anymore.
+  if (!IS_UNDEFINED(big_indices)) {
+    var length = big_indices.length;
+    for (var i = 0; i < length; ++i) {
+      var key = big_indices[i];
+      array[key] = new_array[key];
+    }
+  }
 }
 
 
@@ -279,20 +298,21 @@
 // because the receiver is not an array (so we have no choice) or because we
 // know we are not deleting or moving a lot of elements.
 function SimpleSlice(array, start_i, del_count, len, deleted_elements) {
+  var is_array = IS_ARRAY(array);
   for (var i = 0; i < del_count; i++) {
     var index = start_i + i;
-    // The spec could also be interpreted such that %HasOwnProperty
-    // would be the appropriate test.  We follow KJS in consulting the
-    // prototype.
-    var current = array[index];
-    if (!IS_UNDEFINED(current) || index in array) {
-      deleted_elements[i] = current;
+    if (HAS_INDEX(array, index, is_array)) {
+      var current = array[index];
+      // The spec requires [[DefineOwnProperty]] here, %AddElement is close
+      // enough (in that it ignores the prototype).
+      %AddElement(deleted_elements, i, current, NONE);
     }
   }
 }
 
 
 function SimpleMove(array, start_i, del_count, len, num_additional_args) {
+  var is_array = IS_ARRAY(array);
   if (num_additional_args !== del_count) {
     // Move the existing elements after the elements to be deleted
     // to the right position in the resulting array.
@@ -300,12 +320,8 @@
       for (var i = len - del_count; i > start_i; i--) {
         var from_index = i + del_count - 1;
         var to_index = i + num_additional_args - 1;
-        // The spec could also be interpreted such that
-        // %HasOwnProperty would be the appropriate test.  We follow
-        // KJS in consulting the prototype.
-        var current = array[from_index];
-        if (!IS_UNDEFINED(current) || from_index in array) {
-          array[to_index] = current;
+        if (HAS_INDEX(array, from_index, is_array)) {
+          array[to_index] = array[from_index];
         } else {
           delete array[to_index];
         }
@@ -314,12 +330,8 @@
       for (var i = start_i; i < len - del_count; i++) {
         var from_index = i + del_count;
         var to_index = i + num_additional_args;
-        // The spec could also be interpreted such that
-        // %HasOwnProperty would be the appropriate test.  We follow
-        // KJS in consulting the prototype.
-        var current = array[from_index];
-        if (!IS_UNDEFINED(current) || from_index in array) {
-          array[to_index] = current;
+        if (HAS_INDEX(array, from_index, is_array)) {
+          array[to_index] = array[from_index];
         } else {
           delete array[to_index];
         }
@@ -349,7 +361,7 @@
     func = array.join;
   }
   if (!IS_SPEC_FUNCTION(func)) {
-    return %_CallFunction(array, ObjectToString);
+    return %_CallFunction(array, NoSideEffectsObjectToString);
   }
   return %_CallFunction(array, func);
 }
@@ -378,6 +390,14 @@
   var result = %_FastOneByteArrayJoin(array, separator);
   if (!IS_UNDEFINED(result)) return result;
 
+  // Fast case for one-element arrays.
+  if (length === 1) {
+    var e = array[0];
+    if (IS_STRING(e)) return e;
+    if (IS_NULL_OR_UNDEFINED(e)) return '';
+    return NonStringToString(e);
+  }
+
   return Join(array, length, separator, ConvertToString);
 }
 
@@ -596,8 +616,8 @@
 
   var first = array[0];
 
-  if (IS_ARRAY(array)) {
-    SmartMove(array, 0, 1, len, 0);
+  if (UseSparseVariant(array, len, IS_ARRAY(array), len)) {
+    SparseMove(array, 0, 1, len, 0);
   } else {
     SimpleMove(array, 0, 1, len, 0);
   }
@@ -636,10 +656,10 @@
   var array = TO_OBJECT_INLINE(this);
   var len = TO_UINT32(array.length);
   var num_arguments = %_ArgumentsLength();
-  var is_sealed = ObjectIsSealed(array);
 
-  if (IS_ARRAY(array) && !is_sealed && len > 0) {
-    SmartMove(array, 0, 0, len, num_arguments);
+  if (len > 0 && UseSparseVariant(array, len, IS_ARRAY(array), len) &&
+     !ObjectIsSealed(array)) {
+    SparseMove(array, 0, 0, len, num_arguments);
   } else {
     SimpleMove(array, 0, 0, len, num_arguments);
   }
@@ -685,7 +705,7 @@
   if (UseSparseVariant(array, len, IS_ARRAY(array), end_i - start_i)) {
     %NormalizeElements(array);
     %NormalizeElements(result);
-    SmartSlice(array, start_i, end_i - start_i, len, result);
+    SparseSlice(array, start_i, end_i - start_i, len, result);
   } else {
     SimpleSlice(array, start_i, end_i - start_i, len, result);
   }
@@ -801,8 +821,8 @@
   if (UseSparseVariant(array, len, IS_ARRAY(array), changed_elements)) {
     %NormalizeElements(array);
     %NormalizeElements(deleted_elements);
-    SmartSlice(array, start_i, del_count, len, deleted_elements);
-    SmartMove(array, start_i, del_count, len, num_elements_to_add);
+    SparseSlice(array, start_i, del_count, len, deleted_elements);
+    SparseMove(array, start_i, del_count, len, num_elements_to_add);
   } else {
     SimpleSlice(array, start_i, del_count, len, deleted_elements);
     SimpleMove(array, start_i, del_count, len, num_elements_to_add);
@@ -964,7 +984,7 @@
   // of a prototype property.
   var CopyFromPrototype = function CopyFromPrototype(obj, length) {
     var max = 0;
-    for (var proto = %GetPrototype(obj); proto; proto = %GetPrototype(proto)) {
+    for (var proto = %_GetPrototype(obj); proto; proto = %_GetPrototype(proto)) {
       var indices = %GetArrayKeys(proto, length);
       if (IS_NUMBER(indices)) {
         // It's an interval.
@@ -993,7 +1013,7 @@
   // where a prototype of obj has an element. I.e., shadow all prototype
   // elements in that range.
   var ShadowPrototypeElements = function(obj, from, to) {
-    for (var proto = %GetPrototype(obj); proto; proto = %GetPrototype(proto)) {
+    for (var proto = %_GetPrototype(obj); proto; proto = %_GetPrototype(proto)) {
       var indices = %GetArrayKeys(proto, to);
       if (IS_NUMBER(indices)) {
         // It's an interval.
@@ -1061,7 +1081,7 @@
     }
     for (i = length - num_holes; i < length; i++) {
       // For compatability with Webkit, do not expose elements in the prototype.
-      if (i in %GetPrototype(obj)) {
+      if (i in %_GetPrototype(obj)) {
         obj[i] = UNDEFINED;
       } else {
         delete obj[i];
@@ -1125,22 +1145,25 @@
   if (!IS_SPEC_FUNCTION(f)) {
     throw MakeTypeError('called_non_callable', [ f ]);
   }
+  var needs_wrapper = false;
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
-  } else if (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(f)) {
-    receiver = ToObject(receiver);
+  } else {
+    needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
   }
 
   var result = new $Array();
   var accumulator = new InternalArray();
   var accumulator_length = 0;
+  var is_array = IS_ARRAY(array);
   var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
   for (var i = 0; i < length; i++) {
-    if (i in array) {
+    if (HAS_INDEX(array, i, is_array)) {
       var element = array[i];
       // Prepare break slots for debugger step in.
       if (stepping) %DebugPrepareStepInIfStepping(f);
-      if (%_CallFunction(receiver, element, i, array, f)) {
+      var new_receiver = needs_wrapper ? ToObject(receiver) : receiver;
+      if (%_CallFunction(new_receiver, element, i, array, f)) {
         accumulator[accumulator_length++] = element;
       }
     }
@@ -1161,19 +1184,22 @@
   if (!IS_SPEC_FUNCTION(f)) {
     throw MakeTypeError('called_non_callable', [ f ]);
   }
+  var needs_wrapper = false;
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
-  } else if (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(f)) {
-    receiver = ToObject(receiver);
+  } else {
+    needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
   }
 
+  var is_array = IS_ARRAY(array);
   var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
   for (var i = 0; i < length; i++) {
-    if (i in array) {
+    if (HAS_INDEX(array, i, is_array)) {
       var element = array[i];
       // Prepare break slots for debugger step in.
       if (stepping) %DebugPrepareStepInIfStepping(f);
-      %_CallFunction(receiver, element, i, array, f);
+      var new_receiver = needs_wrapper ? ToObject(receiver) : receiver;
+      %_CallFunction(new_receiver, element, i, array, f);
     }
   }
 }
@@ -1192,19 +1218,22 @@
   if (!IS_SPEC_FUNCTION(f)) {
     throw MakeTypeError('called_non_callable', [ f ]);
   }
+  var needs_wrapper = false;
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
-  } else if (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(f)) {
-    receiver = ToObject(receiver);
+  } else {
+    needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
   }
 
+  var is_array = IS_ARRAY(array);
   var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
   for (var i = 0; i < length; i++) {
-    if (i in array) {
+    if (HAS_INDEX(array, i, is_array)) {
       var element = array[i];
       // Prepare break slots for debugger step in.
       if (stepping) %DebugPrepareStepInIfStepping(f);
-      if (%_CallFunction(receiver, element, i, array, f)) return true;
+      var new_receiver = needs_wrapper ? ToObject(receiver) : receiver;
+      if (%_CallFunction(new_receiver, element, i, array, f)) return true;
     }
   }
   return false;
@@ -1222,19 +1251,22 @@
   if (!IS_SPEC_FUNCTION(f)) {
     throw MakeTypeError('called_non_callable', [ f ]);
   }
+  var needs_wrapper = false;
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
-  } else if (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(f)) {
-    receiver = ToObject(receiver);
+  } else {
+    needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
   }
 
+  var is_array = IS_ARRAY(array);
   var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
   for (var i = 0; i < length; i++) {
-    if (i in array) {
+    if (HAS_INDEX(array, i, is_array)) {
       var element = array[i];
       // Prepare break slots for debugger step in.
       if (stepping) %DebugPrepareStepInIfStepping(f);
-      if (!%_CallFunction(receiver, element, i, array, f)) return false;
+      var new_receiver = needs_wrapper ? ToObject(receiver) : receiver;
+      if (!%_CallFunction(new_receiver, element, i, array, f)) return false;
     }
   }
   return true;
@@ -1251,21 +1283,24 @@
   if (!IS_SPEC_FUNCTION(f)) {
     throw MakeTypeError('called_non_callable', [ f ]);
   }
+  var needs_wrapper = false;
   if (IS_NULL_OR_UNDEFINED(receiver)) {
     receiver = %GetDefaultReceiver(f) || receiver;
-  } else if (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(f)) {
-    receiver = ToObject(receiver);
+  } else {
+    needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
   }
 
   var result = new $Array();
   var accumulator = new InternalArray(length);
+  var is_array = IS_ARRAY(array);
   var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
   for (var i = 0; i < length; i++) {
-    if (i in array) {
+    if (HAS_INDEX(array, i, is_array)) {
       var element = array[i];
       // Prepare break slots for debugger step in.
       if (stepping) %DebugPrepareStepInIfStepping(f);
-      accumulator[i] = %_CallFunction(receiver, element, i, array, f);
+      var new_receiver = needs_wrapper ? ToObject(receiver) : receiver;
+      accumulator[i] = %_CallFunction(new_receiver, element, i, array, f);
     }
   }
   %MoveArrayContents(accumulator, result);
@@ -1395,12 +1430,12 @@
     throw MakeTypeError('called_non_callable', [callback]);
   }
 
+  var is_array = IS_ARRAY(array);
   var i = 0;
   find_initial: if (%_ArgumentsLength() < 2) {
     for (; i < length; i++) {
-      current = array[i];
-      if (!IS_UNDEFINED(current) || i in array) {
-        i++;
+      if (HAS_INDEX(array, i, is_array)) {
+        current = array[i++];
         break find_initial;
       }
     }
@@ -1410,7 +1445,7 @@
   var receiver = %GetDefaultReceiver(callback);
   var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(callback);
   for (; i < length; i++) {
-    if (i in array) {
+    if (HAS_INDEX(array, i, is_array)) {
       var element = array[i];
       // Prepare break slots for debugger step in.
       if (stepping) %DebugPrepareStepInIfStepping(callback);
@@ -1432,12 +1467,12 @@
     throw MakeTypeError('called_non_callable', [callback]);
   }
 
+  var is_array = IS_ARRAY(array);
   var i = length - 1;
   find_initial: if (%_ArgumentsLength() < 2) {
     for (; i >= 0; i--) {
-      current = array[i];
-      if (!IS_UNDEFINED(current) || i in array) {
-        i--;
+      if (HAS_INDEX(array, i, is_array)) {
+        current = array[i--];
         break find_initial;
       }
     }
@@ -1447,7 +1482,7 @@
   var receiver = %GetDefaultReceiver(callback);
   var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(callback);
   for (; i >= 0; i--) {
-    if (i in array) {
+    if (HAS_INDEX(array, i, is_array)) {
       var element = array[i];
       // Prepare break slots for debugger step in.
       if (stepping) %DebugPrepareStepInIfStepping(callback);
diff --git a/src/arraybuffer.js b/src/arraybuffer.js
index e1c887f..cf00693 100644
--- a/src/arraybuffer.js
+++ b/src/arraybuffer.js
@@ -77,6 +77,9 @@
   %AddNamedProperty(
       $ArrayBuffer.prototype, "constructor", $ArrayBuffer, DONT_ENUM);
 
+  %AddNamedProperty($ArrayBuffer.prototype,
+      symbolToStringTag, "ArrayBuffer", DONT_ENUM | READ_ONLY);
+
   InstallGetter($ArrayBuffer.prototype, "byteLength", ArrayBufferGetByteLen);
 
   InstallFunctions($ArrayBuffer, DONT_ENUM, $Array(
diff --git a/src/assembler.cc b/src/assembler.cc
index a705300..c73b470 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -37,6 +37,7 @@
 #include <cmath>
 #include "src/api.h"
 #include "src/base/cpu.h"
+#include "src/base/functional.h"
 #include "src/base/lazy-instance.h"
 #include "src/base/platform/platform.h"
 #include "src/builtins.h"
@@ -52,7 +53,7 @@
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
 #include "src/regexp-stack.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 #include "src/serialize.h"
 #include "src/token.h"
 
@@ -130,7 +131,8 @@
       emit_debug_code_(FLAG_debug_code),
       predictable_code_size_(false),
       // We may use the assembler without an isolate.
-      serializer_enabled_(isolate && isolate->serializer_enabled()) {
+      serializer_enabled_(isolate && isolate->serializer_enabled()),
+      ool_constant_pool_available_(false) {
   if (FLAG_mask_constants_with_cookie && isolate != NULL)  {
     jit_cookie_ = isolate->random_number_generator()->NextInt();
   }
@@ -794,8 +796,8 @@
 }
 
 
-void RelocInfo::Print(Isolate* isolate, OStream& os) {  // NOLINT
-  os << pc_ << "  " << RelocModeName(rmode_);
+void RelocInfo::Print(Isolate* isolate, std::ostream& os) {  // NOLINT
+  os << static_cast<const void*>(pc_) << "  " << RelocModeName(rmode_);
   if (IsComment(rmode_)) {
     os << "  (" << reinterpret_cast<char*>(data_) << ")";
   } else if (rmode_ == EMBEDDED_OBJECT) {
@@ -803,11 +805,11 @@
   } else if (rmode_ == EXTERNAL_REFERENCE) {
     ExternalReferenceEncoder ref_encoder(isolate);
     os << " (" << ref_encoder.NameOfAddress(target_reference()) << ")  ("
-       << target_reference() << ")";
+       << static_cast<const void*>(target_reference()) << ")";
   } else if (IsCodeTarget(rmode_)) {
     Code* code = Code::GetCodeFromTargetAddress(target_address());
-    os << " (" << Code::Kind2String(code->kind()) << ")  (" << target_address()
-       << ")";
+    os << " (" << Code::Kind2String(code->kind()) << ")  ("
+       << static_cast<const void*>(target_address()) << ")";
     if (rmode_ == CODE_TARGET_WITH_ID) {
       os << " (id=" << static_cast<int>(data_) << ")";
     }
@@ -1521,6 +1523,29 @@
 }
 
 
+bool operator==(ExternalReference lhs, ExternalReference rhs) {
+  return lhs.address() == rhs.address();
+}
+
+
+bool operator!=(ExternalReference lhs, ExternalReference rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(ExternalReference reference) {
+  return base::hash<Address>()(reference.address());
+}
+
+
+std::ostream& operator<<(std::ostream& os, ExternalReference reference) {
+  os << static_cast<const void*>(reference.address());
+  const Runtime::Function* fn = Runtime::FunctionForEntry(reference.address());
+  if (fn) os << "<" << fn->name << ".entry>";
+  return os;
+}
+
+
 void PositionsRecorder::RecordPosition(int pos) {
   DCHECK(pos != RelocInfo::kNoPosition);
   DCHECK(pos >= 0);
diff --git a/src/assembler.h b/src/assembler.h
index 3d2f7d9..e95b7ed 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -41,7 +41,7 @@
 #include "src/builtins.h"
 #include "src/gdb-jit.h"
 #include "src/isolate.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 #include "src/token.h"
 
 namespace v8 {
@@ -79,6 +79,16 @@
     return (enabled_cpu_features_ & (static_cast<uint64_t>(1) << f)) != 0;
   }
 
+  bool is_ool_constant_pool_available() const {
+    if (FLAG_enable_ool_constant_pool) {
+      return ool_constant_pool_available_;
+    } else {
+      // Out-of-line constant pool not supported on this architecture.
+      UNREACHABLE();
+      return false;
+    }
+  }
+
   // Overwrite a host NaN with a quiet target NaN.  Used by mksnapshot for
   // cross-snapshotting.
   static void QuietNaN(HeapObject* nan) { }
@@ -98,6 +108,15 @@
   int buffer_size_;
   bool own_buffer_;
 
+  void set_ool_constant_pool_available(bool available) {
+    if (FLAG_enable_ool_constant_pool) {
+      ool_constant_pool_available_ = available;
+    } else {
+      // Out-of-line constant pool not supported on this architecture.
+      UNREACHABLE();
+    }
+  }
+
   // The program counter, which points into the buffer above and moves forward.
   byte* pc_;
 
@@ -108,6 +127,14 @@
   bool emit_debug_code_;
   bool predictable_code_size_;
   bool serializer_enabled_;
+
+  // Indicates whether the constant pool can be accessed, which is only possible
+  // if the pp register points to the current code object's constant pool.
+  bool ool_constant_pool_available_;
+
+  // Constant pool.
+  friend class FrameAndConstantPoolScope;
+  friend class ConstantPoolUnavailableScope;
 };
 
 
@@ -216,7 +243,7 @@
 // unknown pc location. Assembler::bind() is used to bind a label to the
 // current pc. A label can be bound only once.
 
-class Label BASE_EMBEDDED {
+class Label {
  public:
   enum Distance {
     kNear, kFar
@@ -578,7 +605,7 @@
 #ifdef ENABLE_DISASSEMBLER
   // Printing
   static const char* RelocModeName(Mode rmode);
-  void Print(Isolate* isolate, OStream& os);  // NOLINT
+  void Print(Isolate* isolate, std::ostream& os);  // NOLINT
 #endif  // ENABLE_DISASSEMBLER
 #ifdef VERIFY_HEAP
   void Verify(Isolate* isolate);
@@ -959,14 +986,6 @@
 
   static ExternalReference stress_deopt_count(Isolate* isolate);
 
-  bool operator==(const ExternalReference& other) const {
-    return address_ == other.address_;
-  }
-
-  bool operator!=(const ExternalReference& other) const {
-    return !(*this == other);
-  }
-
  private:
   explicit ExternalReference(void* address)
       : address_(address) {}
@@ -987,6 +1006,13 @@
   void* address_;
 };
 
+bool operator==(ExternalReference, ExternalReference);
+bool operator!=(ExternalReference, ExternalReference);
+
+size_t hash_value(ExternalReference);
+
+std::ostream& operator<<(std::ostream&, ExternalReference);
+
 
 // -----------------------------------------------------------------------------
 // Position recording support
diff --git a/src/assert-scope.cc b/src/assert-scope.cc
index c4aa987..4c10fdd 100644
--- a/src/assert-scope.cc
+++ b/src/assert-scope.cc
@@ -2,20 +2,154 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-
 #include "src/assert-scope.h"
-#include "src/v8.h"
+
+#include "src/base/lazy-instance.h"
+#include "src/base/platform/platform.h"
+#include "src/isolate-inl.h"
+#include "src/utils.h"
 
 namespace v8 {
 namespace internal {
 
-uint32_t PerIsolateAssertBase::GetData(Isolate* isolate) {
-  return isolate->per_isolate_assert_data();
+namespace {
+
+struct PerThreadAssertKeyConstructTrait FINAL {
+  static void Construct(base::Thread::LocalStorageKey* key) {
+    *key = base::Thread::CreateThreadLocalKey();
+  }
+};
+
+
+typedef base::LazyStaticInstance<base::Thread::LocalStorageKey,
+                                 PerThreadAssertKeyConstructTrait>::type
+    PerThreadAssertKey;
+
+
+PerThreadAssertKey kPerThreadAssertKey;
+
+}  // namespace
+
+
+class PerThreadAssertData FINAL {
+ public:
+  PerThreadAssertData() : nesting_level_(0) {
+    for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) {
+      assert_states_[i] = true;
+    }
+  }
+
+  ~PerThreadAssertData() {
+    for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; ++i) {
+      DCHECK(assert_states_[i]);
+    }
+  }
+
+  bool Get(PerThreadAssertType type) const { return assert_states_[type]; }
+  void Set(PerThreadAssertType type, bool x) { assert_states_[type] = x; }
+
+  void IncrementLevel() { ++nesting_level_; }
+  bool DecrementLevel() { return --nesting_level_ == 0; }
+
+  static PerThreadAssertData* GetCurrent() {
+    return reinterpret_cast<PerThreadAssertData*>(
+        base::Thread::GetThreadLocal(kPerThreadAssertKey.Get()));
+  }
+  static void SetCurrent(PerThreadAssertData* data) {
+    base::Thread::SetThreadLocal(kPerThreadAssertKey.Get(), data);
+  }
+
+ private:
+  bool assert_states_[LAST_PER_THREAD_ASSERT_TYPE];
+  int nesting_level_;
+
+  DISALLOW_COPY_AND_ASSIGN(PerThreadAssertData);
+};
+
+
+template <PerThreadAssertType kType, bool kAllow>
+PerThreadAssertScope<kType, kAllow>::PerThreadAssertScope()
+    : data_(PerThreadAssertData::GetCurrent()) {
+  if (data_ == NULL) {
+    data_ = new PerThreadAssertData();
+    PerThreadAssertData::SetCurrent(data_);
+  }
+  data_->IncrementLevel();
+  old_state_ = data_->Get(kType);
+  data_->Set(kType, kAllow);
 }
 
 
-void PerIsolateAssertBase::SetData(Isolate* isolate, uint32_t data) {
-  isolate->set_per_isolate_assert_data(data);
+template <PerThreadAssertType kType, bool kAllow>
+PerThreadAssertScope<kType, kAllow>::~PerThreadAssertScope() {
+  DCHECK_NOT_NULL(data_);
+  data_->Set(kType, old_state_);
+  if (data_->DecrementLevel()) {
+    PerThreadAssertData::SetCurrent(NULL);
+    delete data_;
+  }
 }
 
-} }  // namespace v8::internal
+
+// static
+template <PerThreadAssertType kType, bool kAllow>
+bool PerThreadAssertScope<kType, kAllow>::IsAllowed() {
+  PerThreadAssertData* data = PerThreadAssertData::GetCurrent();
+  return data == NULL || data->Get(kType);
+}
+
+
+template <PerIsolateAssertType kType, bool kAllow>
+class PerIsolateAssertScope<kType, kAllow>::DataBit
+    : public BitField<bool, kType, 1> {};
+
+
+template <PerIsolateAssertType kType, bool kAllow>
+PerIsolateAssertScope<kType, kAllow>::PerIsolateAssertScope(Isolate* isolate)
+    : isolate_(isolate), old_data_(isolate->per_isolate_assert_data()) {
+  DCHECK_NOT_NULL(isolate);
+  STATIC_ASSERT(kType < 32);
+  isolate_->set_per_isolate_assert_data(DataBit::update(old_data_, kAllow));
+}
+
+
+template <PerIsolateAssertType kType, bool kAllow>
+PerIsolateAssertScope<kType, kAllow>::~PerIsolateAssertScope() {
+  isolate_->set_per_isolate_assert_data(old_data_);
+}
+
+
+// static
+template <PerIsolateAssertType kType, bool kAllow>
+bool PerIsolateAssertScope<kType, kAllow>::IsAllowed(Isolate* isolate) {
+  return DataBit::decode(isolate->per_isolate_assert_data());
+}
+
+
+// -----------------------------------------------------------------------------
+// Instantiations.
+
+template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, false>;
+template class PerThreadAssertScope<HEAP_ALLOCATION_ASSERT, true>;
+template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, false>;
+template class PerThreadAssertScope<HANDLE_ALLOCATION_ASSERT, true>;
+template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, false>;
+template class PerThreadAssertScope<HANDLE_DEREFERENCE_ASSERT, true>;
+template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, false>;
+template class PerThreadAssertScope<DEFERRED_HANDLE_DEREFERENCE_ASSERT, true>;
+template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, false>;
+template class PerThreadAssertScope<CODE_DEPENDENCY_CHANGE_ASSERT, true>;
+
+template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, false>;
+template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_ASSERT, true>;
+template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, false>;
+template class PerIsolateAssertScope<JAVASCRIPT_EXECUTION_THROWS, true>;
+template class PerIsolateAssertScope<ALLOCATION_FAILURE_ASSERT, false>;
+template class PerIsolateAssertScope<ALLOCATION_FAILURE_ASSERT, true>;
+template class PerIsolateAssertScope<DEOPTIMIZATION_ASSERT, false>;
+template class PerIsolateAssertScope<DEOPTIMIZATION_ASSERT, true>;
+template class PerIsolateAssertScope<COMPILATION_ASSERT, false>;
+template class PerIsolateAssertScope<COMPILATION_ASSERT, true>;
+
+}  // namespace internal
+}  // namespace v8
diff --git a/src/assert-scope.h b/src/assert-scope.h
index 7cfec56..0f1e056 100644
--- a/src/assert-scope.h
+++ b/src/assert-scope.h
@@ -5,14 +5,16 @@
 #ifndef V8_ASSERT_SCOPE_H_
 #define V8_ASSERT_SCOPE_H_
 
-#include "src/allocation.h"
-#include "src/base/platform/platform.h"
-#include "src/utils.h"
+#include <stdint.h>
+#include "src/base/macros.h"
 
 namespace v8 {
 namespace internal {
 
+// Forward declarations.
 class Isolate;
+class PerThreadAssertData;
+
 
 enum PerThreadAssertType {
   HEAP_ALLOCATION_ASSERT,
@@ -33,120 +35,35 @@
 };
 
 
-class PerThreadAssertData {
+template <PerThreadAssertType kType, bool kAllow>
+class PerThreadAssertScope {
  public:
-  PerThreadAssertData() : nesting_level_(0) {
-    for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) {
-      assert_states_[i] = true;
-    }
-  }
+  PerThreadAssertScope();
+  ~PerThreadAssertScope();
 
-  void set(PerThreadAssertType type, bool allow) {
-    assert_states_[type] = allow;
-  }
-
-  bool get(PerThreadAssertType type) const {
-    return assert_states_[type];
-  }
-
-  void increment_level() { ++nesting_level_; }
-  bool decrement_level() { return --nesting_level_ == 0; }
+  static bool IsAllowed();
 
  private:
-  bool assert_states_[LAST_PER_THREAD_ASSERT_TYPE];
-  int nesting_level_;
-
-  DISALLOW_COPY_AND_ASSIGN(PerThreadAssertData);
-};
-
-
-class PerThreadAssertScopeBase {
- protected:
-  PerThreadAssertScopeBase() {
-    data_ = GetAssertData();
-    if (data_ == NULL) {
-      data_ = new PerThreadAssertData();
-      SetThreadLocalData(data_);
-    }
-    data_->increment_level();
-  }
-
-  ~PerThreadAssertScopeBase() {
-    if (!data_->decrement_level()) return;
-    for (int i = 0; i < LAST_PER_THREAD_ASSERT_TYPE; i++) {
-      DCHECK(data_->get(static_cast<PerThreadAssertType>(i)));
-    }
-    delete data_;
-    SetThreadLocalData(NULL);
-  }
-
-  static PerThreadAssertData* GetAssertData() {
-    return reinterpret_cast<PerThreadAssertData*>(
-        base::Thread::GetThreadLocal(thread_local_key));
-  }
-
-  static base::Thread::LocalStorageKey thread_local_key;
   PerThreadAssertData* data_;
-  friend class Isolate;
-
- private:
-  static void SetThreadLocalData(PerThreadAssertData* data) {
-    base::Thread::SetThreadLocal(thread_local_key, data);
-  }
-};
-
-
-template <PerThreadAssertType type, bool allow>
-class PerThreadAssertScope : public PerThreadAssertScopeBase {
- public:
-  PerThreadAssertScope() {
-    old_state_ = data_->get(type);
-    data_->set(type, allow);
-  }
-
-  ~PerThreadAssertScope() { data_->set(type, old_state_); }
-
-  static bool IsAllowed() {
-    PerThreadAssertData* data = GetAssertData();
-    return data == NULL || data->get(type);
-  }
-
- private:
   bool old_state_;
 
   DISALLOW_COPY_AND_ASSIGN(PerThreadAssertScope);
 };
 
 
-class PerIsolateAssertBase {
- protected:
-  static uint32_t GetData(Isolate* isolate);
-  static void SetData(Isolate* isolate, uint32_t data);
-};
-
-
 template <PerIsolateAssertType type, bool allow>
-class PerIsolateAssertScope : public PerIsolateAssertBase {
+class PerIsolateAssertScope {
  public:
-  explicit PerIsolateAssertScope(Isolate* isolate) : isolate_(isolate) {
-    STATIC_ASSERT(type < 32);
-    old_data_ = GetData(isolate_);
-    SetData(isolate_, DataBit::update(old_data_, allow));
-  }
+  explicit PerIsolateAssertScope(Isolate* isolate);
+  ~PerIsolateAssertScope();
 
-  ~PerIsolateAssertScope() {
-    SetData(isolate_, old_data_);
-  }
-
-  static bool IsAllowed(Isolate* isolate) {
-    return DataBit::decode(GetData(isolate));
-  }
+  static bool IsAllowed(Isolate* isolate);
 
  private:
-  typedef BitField<bool, type, 1> DataBit;
+  class DataBit;
 
-  uint32_t old_data_;
   Isolate* isolate_;
+  uint32_t old_data_;
 
   DISALLOW_COPY_AND_ASSIGN(PerIsolateAssertScope);
 };
diff --git a/src/ast-numbering.cc b/src/ast-numbering.cc
new file mode 100644
index 0000000..c2dd70e
--- /dev/null
+++ b/src/ast-numbering.cc
@@ -0,0 +1,578 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/ast.h"
+#include "src/ast-numbering.h"
+#include "src/compiler.h"
+#include "src/scopes.h"
+
+namespace v8 {
+namespace internal {
+
+
+class AstNumberingVisitor FINAL : public AstVisitor {
+ public:
+  explicit AstNumberingVisitor(Zone* zone)
+      : AstVisitor(),
+        next_id_(BailoutId::FirstUsable().ToInt()),
+        dont_crankshaft_reason_(kNoReason),
+        dont_turbofan_reason_(kNoReason) {
+    InitializeAstVisitor(zone);
+  }
+
+  bool Renumber(FunctionLiteral* node);
+
+ private:
+// AST node visitor interface.
+#define DEFINE_VISIT(type) virtual void Visit##type(type* node) OVERRIDE;
+  AST_NODE_LIST(DEFINE_VISIT)
+#undef DEFINE_VISIT
+
+  bool Finish(FunctionLiteral* node);
+
+  void VisitStatements(ZoneList<Statement*>* statements) OVERRIDE;
+  void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE;
+  void VisitArguments(ZoneList<Expression*>* arguments);
+  void VisitObjectLiteralProperty(ObjectLiteralProperty* property);
+
+  int ReserveIdRange(int n) {
+    int tmp = next_id_;
+    next_id_ += n;
+    return tmp;
+  }
+
+  void IncrementNodeCount() { properties_.add_node_count(1); }
+  void DisableCrankshaft(BailoutReason reason) {
+    dont_crankshaft_reason_ = reason;
+    properties_.flags()->Add(kDontSelfOptimize);
+  }
+  // TODO(turbofan): Remove the dont_turbofan_reason once no nodes are
+  // DontTurbofanNode.  That set of nodes must be kept in sync with
+  // Pipeline::GenerateCode.
+  void DisableTurbofan(BailoutReason reason) {
+    dont_crankshaft_reason_ = reason;
+    dont_turbofan_reason_ = reason;
+    DisableSelfOptimization();
+  }
+  void DisableSelfOptimization() {
+    properties_.flags()->Add(kDontSelfOptimize);
+  }
+  void DisableCaching(BailoutReason reason) {
+    dont_crankshaft_reason_ = reason;
+    DisableSelfOptimization();
+    properties_.flags()->Add(kDontCache);
+  }
+
+  template <typename Node>
+  void ReserveFeedbackSlots(Node* node) {
+    FeedbackVectorRequirements reqs =
+        node->ComputeFeedbackRequirements(isolate());
+    if (reqs.slots() > 0) {
+      node->SetFirstFeedbackSlot(FeedbackVectorSlot(properties_.slots()));
+      properties_.increase_slots(reqs.slots());
+    }
+    if (reqs.ic_slots() > 0) {
+      int ic_slots = properties_.ic_slots();
+      node->SetFirstFeedbackICSlot(FeedbackVectorICSlot(ic_slots));
+      properties_.increase_ic_slots(reqs.ic_slots());
+      if (FLAG_vector_ics) {
+        for (int i = 0; i < reqs.ic_slots(); i++) {
+          properties_.SetKind(ic_slots + i, node->FeedbackICSlotKind(i));
+        }
+      }
+    }
+  }
+
+  BailoutReason dont_optimize_reason() const {
+    return (dont_turbofan_reason_ != kNoReason) ? dont_turbofan_reason_
+                                                : dont_crankshaft_reason_;
+  }
+
+  int next_id_;
+  AstProperties properties_;
+  BailoutReason dont_crankshaft_reason_;
+  BailoutReason dont_turbofan_reason_;
+
+  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
+  DISALLOW_COPY_AND_ASSIGN(AstNumberingVisitor);
+};
+
+
+void AstNumberingVisitor::VisitVariableDeclaration(VariableDeclaration* node) {
+  IncrementNodeCount();
+  VisitVariableProxy(node->proxy());
+}
+
+
+void AstNumberingVisitor::VisitExportDeclaration(ExportDeclaration* node) {
+  IncrementNodeCount();
+  DisableCrankshaft(kExportDeclaration);
+  VisitVariableProxy(node->proxy());
+}
+
+
+void AstNumberingVisitor::VisitModuleUrl(ModuleUrl* node) {
+  IncrementNodeCount();
+  DisableCrankshaft(kModuleUrl);
+}
+
+
+void AstNumberingVisitor::VisitEmptyStatement(EmptyStatement* node) {
+  IncrementNodeCount();
+}
+
+
+void AstNumberingVisitor::VisitContinueStatement(ContinueStatement* node) {
+  IncrementNodeCount();
+}
+
+
+void AstNumberingVisitor::VisitBreakStatement(BreakStatement* node) {
+  IncrementNodeCount();
+}
+
+
+void AstNumberingVisitor::VisitDebuggerStatement(DebuggerStatement* node) {
+  IncrementNodeCount();
+  DisableCrankshaft(kDebuggerStatement);
+  node->set_base_id(ReserveIdRange(DebuggerStatement::num_ids()));
+}
+
+
+void AstNumberingVisitor::VisitNativeFunctionLiteral(
+    NativeFunctionLiteral* node) {
+  IncrementNodeCount();
+  DisableCrankshaft(kNativeFunctionLiteral);
+  node->set_base_id(ReserveIdRange(NativeFunctionLiteral::num_ids()));
+}
+
+
+void AstNumberingVisitor::VisitLiteral(Literal* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(Literal::num_ids()));
+}
+
+
+void AstNumberingVisitor::VisitRegExpLiteral(RegExpLiteral* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(RegExpLiteral::num_ids()));
+}
+
+
+void AstNumberingVisitor::VisitVariableProxy(VariableProxy* node) {
+  IncrementNodeCount();
+  if (node->var()->IsLookupSlot()) {
+    DisableCrankshaft(kReferenceToAVariableWhichRequiresDynamicLookup);
+  }
+  ReserveFeedbackSlots(node);
+  node->set_base_id(ReserveIdRange(VariableProxy::num_ids()));
+}
+
+
+void AstNumberingVisitor::VisitThisFunction(ThisFunction* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(ThisFunction::num_ids()));
+}
+
+
+void AstNumberingVisitor::VisitSuperReference(SuperReference* node) {
+  IncrementNodeCount();
+  DisableTurbofan(kSuperReference);
+  ReserveFeedbackSlots(node);
+  node->set_base_id(ReserveIdRange(SuperReference::num_ids()));
+  Visit(node->this_var());
+}
+
+
+void AstNumberingVisitor::VisitModuleDeclaration(ModuleDeclaration* node) {
+  IncrementNodeCount();
+  DisableCrankshaft(kModuleDeclaration);
+  VisitVariableProxy(node->proxy());
+  Visit(node->module());
+}
+
+
+void AstNumberingVisitor::VisitImportDeclaration(ImportDeclaration* node) {
+  IncrementNodeCount();
+  DisableCrankshaft(kImportDeclaration);
+  VisitVariableProxy(node->proxy());
+  Visit(node->module());
+}
+
+
+void AstNumberingVisitor::VisitModuleVariable(ModuleVariable* node) {
+  IncrementNodeCount();
+  DisableCrankshaft(kModuleVariable);
+  Visit(node->proxy());
+}
+
+
+void AstNumberingVisitor::VisitModulePath(ModulePath* node) {
+  IncrementNodeCount();
+  DisableCrankshaft(kModulePath);
+  Visit(node->module());
+}
+
+
+void AstNumberingVisitor::VisitModuleStatement(ModuleStatement* node) {
+  IncrementNodeCount();
+  DisableCrankshaft(kModuleStatement);
+  Visit(node->body());
+}
+
+
+void AstNumberingVisitor::VisitExpressionStatement(ExpressionStatement* node) {
+  IncrementNodeCount();
+  Visit(node->expression());
+}
+
+
+void AstNumberingVisitor::VisitReturnStatement(ReturnStatement* node) {
+  IncrementNodeCount();
+  Visit(node->expression());
+}
+
+
+void AstNumberingVisitor::VisitYield(Yield* node) {
+  IncrementNodeCount();
+  DisableCrankshaft(kYield);
+  ReserveFeedbackSlots(node);
+  node->set_base_id(ReserveIdRange(Yield::num_ids()));
+  Visit(node->generator_object());
+  Visit(node->expression());
+}
+
+
+void AstNumberingVisitor::VisitThrow(Throw* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(Throw::num_ids()));
+  Visit(node->exception());
+}
+
+
+void AstNumberingVisitor::VisitUnaryOperation(UnaryOperation* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(UnaryOperation::num_ids()));
+  Visit(node->expression());
+}
+
+
+void AstNumberingVisitor::VisitCountOperation(CountOperation* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(CountOperation::num_ids()));
+  Visit(node->expression());
+}
+
+
+void AstNumberingVisitor::VisitBlock(Block* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(Block::num_ids()));
+  if (node->scope() != NULL) VisitDeclarations(node->scope()->declarations());
+  VisitStatements(node->statements());
+}
+
+
+void AstNumberingVisitor::VisitFunctionDeclaration(FunctionDeclaration* node) {
+  IncrementNodeCount();
+  VisitVariableProxy(node->proxy());
+  VisitFunctionLiteral(node->fun());
+}
+
+
+void AstNumberingVisitor::VisitModuleLiteral(ModuleLiteral* node) {
+  IncrementNodeCount();
+  DisableCaching(kModuleLiteral);
+  VisitBlock(node->body());
+}
+
+
+void AstNumberingVisitor::VisitCallRuntime(CallRuntime* node) {
+  IncrementNodeCount();
+  ReserveFeedbackSlots(node);
+  if (node->is_jsruntime()) {
+    // Don't try to optimize JS runtime calls because we bailout on them.
+    DisableCrankshaft(kCallToAJavaScriptRuntimeFunction);
+  }
+  node->set_base_id(ReserveIdRange(CallRuntime::num_ids()));
+  VisitArguments(node->arguments());
+}
+
+
+void AstNumberingVisitor::VisitWithStatement(WithStatement* node) {
+  IncrementNodeCount();
+  DisableCrankshaft(kWithStatement);
+  Visit(node->expression());
+  Visit(node->statement());
+}
+
+
+void AstNumberingVisitor::VisitDoWhileStatement(DoWhileStatement* node) {
+  IncrementNodeCount();
+  DisableSelfOptimization();
+  node->set_base_id(ReserveIdRange(DoWhileStatement::num_ids()));
+  Visit(node->body());
+  Visit(node->cond());
+}
+
+
+void AstNumberingVisitor::VisitWhileStatement(WhileStatement* node) {
+  IncrementNodeCount();
+  DisableSelfOptimization();
+  node->set_base_id(ReserveIdRange(WhileStatement::num_ids()));
+  Visit(node->cond());
+  Visit(node->body());
+}
+
+
+void AstNumberingVisitor::VisitTryCatchStatement(TryCatchStatement* node) {
+  IncrementNodeCount();
+  DisableTurbofan(kTryCatchStatement);
+  Visit(node->try_block());
+  Visit(node->catch_block());
+}
+
+
+void AstNumberingVisitor::VisitTryFinallyStatement(TryFinallyStatement* node) {
+  IncrementNodeCount();
+  DisableTurbofan(kTryFinallyStatement);
+  Visit(node->try_block());
+  Visit(node->finally_block());
+}
+
+
+void AstNumberingVisitor::VisitProperty(Property* node) {
+  IncrementNodeCount();
+  ReserveFeedbackSlots(node);
+  node->set_base_id(ReserveIdRange(Property::num_ids()));
+  Visit(node->key());
+  Visit(node->obj());
+}
+
+
+void AstNumberingVisitor::VisitAssignment(Assignment* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(Assignment::num_ids()));
+  if (node->is_compound()) VisitBinaryOperation(node->binary_operation());
+  Visit(node->target());
+  Visit(node->value());
+}
+
+
+void AstNumberingVisitor::VisitBinaryOperation(BinaryOperation* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(BinaryOperation::num_ids()));
+  Visit(node->left());
+  Visit(node->right());
+}
+
+
+void AstNumberingVisitor::VisitCompareOperation(CompareOperation* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(CompareOperation::num_ids()));
+  Visit(node->left());
+  Visit(node->right());
+}
+
+
+void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) {
+  IncrementNodeCount();
+  DisableSelfOptimization();
+  ReserveFeedbackSlots(node);
+  node->set_base_id(ReserveIdRange(ForInStatement::num_ids()));
+  Visit(node->each());
+  Visit(node->enumerable());
+  Visit(node->body());
+}
+
+
+void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) {
+  IncrementNodeCount();
+  DisableTurbofan(kForOfStatement);
+  node->set_base_id(ReserveIdRange(ForOfStatement::num_ids()));
+  Visit(node->assign_iterator());
+  Visit(node->next_result());
+  Visit(node->result_done());
+  Visit(node->assign_each());
+  Visit(node->body());
+}
+
+
+void AstNumberingVisitor::VisitConditional(Conditional* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(Conditional::num_ids()));
+  Visit(node->condition());
+  Visit(node->then_expression());
+  Visit(node->else_expression());
+}
+
+
+void AstNumberingVisitor::VisitIfStatement(IfStatement* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(IfStatement::num_ids()));
+  Visit(node->condition());
+  Visit(node->then_statement());
+  if (node->HasElseStatement()) {
+    Visit(node->else_statement());
+  }
+}
+
+
+void AstNumberingVisitor::VisitSwitchStatement(SwitchStatement* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(SwitchStatement::num_ids()));
+  Visit(node->tag());
+  ZoneList<CaseClause*>* cases = node->cases();
+  for (int i = 0; i < cases->length(); i++) {
+    VisitCaseClause(cases->at(i));
+  }
+}
+
+
+void AstNumberingVisitor::VisitCaseClause(CaseClause* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(CaseClause::num_ids()));
+  if (!node->is_default()) Visit(node->label());
+  VisitStatements(node->statements());
+}
+
+
+void AstNumberingVisitor::VisitForStatement(ForStatement* node) {
+  IncrementNodeCount();
+  DisableSelfOptimization();
+  node->set_base_id(ReserveIdRange(ForStatement::num_ids()));
+  if (node->init() != NULL) Visit(node->init());
+  if (node->cond() != NULL) Visit(node->cond());
+  if (node->next() != NULL) Visit(node->next());
+  Visit(node->body());
+}
+
+
+void AstNumberingVisitor::VisitClassLiteral(ClassLiteral* node) {
+  IncrementNodeCount();
+  DisableTurbofan(kClassLiteral);
+  node->set_base_id(ReserveIdRange(ClassLiteral::num_ids()));
+  if (node->extends()) Visit(node->extends());
+  if (node->constructor()) Visit(node->constructor());
+  if (node->class_variable_proxy()) {
+    VisitVariableProxy(node->class_variable_proxy());
+  }
+  for (int i = 0; i < node->properties()->length(); i++) {
+    VisitObjectLiteralProperty(node->properties()->at(i));
+  }
+}
+
+
+void AstNumberingVisitor::VisitObjectLiteral(ObjectLiteral* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(ObjectLiteral::num_ids()));
+  for (int i = 0; i < node->properties()->length(); i++) {
+    VisitObjectLiteralProperty(node->properties()->at(i));
+  }
+}
+
+
+void AstNumberingVisitor::VisitObjectLiteralProperty(
+    ObjectLiteralProperty* node) {
+  Visit(node->key());
+  Visit(node->value());
+}
+
+
+void AstNumberingVisitor::VisitArrayLiteral(ArrayLiteral* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(node->num_ids()));
+  for (int i = 0; i < node->values()->length(); i++) {
+    Visit(node->values()->at(i));
+  }
+}
+
+
+void AstNumberingVisitor::VisitCall(Call* node) {
+  IncrementNodeCount();
+  ReserveFeedbackSlots(node);
+  node->set_base_id(ReserveIdRange(Call::num_ids()));
+  Visit(node->expression());
+  VisitArguments(node->arguments());
+}
+
+
+void AstNumberingVisitor::VisitCallNew(CallNew* node) {
+  IncrementNodeCount();
+  ReserveFeedbackSlots(node);
+  node->set_base_id(ReserveIdRange(CallNew::num_ids()));
+  Visit(node->expression());
+  VisitArguments(node->arguments());
+}
+
+
+void AstNumberingVisitor::VisitStatements(ZoneList<Statement*>* statements) {
+  if (statements == NULL) return;
+  for (int i = 0; i < statements->length(); i++) {
+    Visit(statements->at(i));
+  }
+}
+
+
+void AstNumberingVisitor::VisitDeclarations(
+    ZoneList<Declaration*>* declarations) {
+  for (int i = 0; i < declarations->length(); i++) {
+    Visit(declarations->at(i));
+  }
+}
+
+
+void AstNumberingVisitor::VisitArguments(ZoneList<Expression*>* arguments) {
+  for (int i = 0; i < arguments->length(); i++) {
+    Visit(arguments->at(i));
+  }
+}
+
+
+void AstNumberingVisitor::VisitFunctionLiteral(FunctionLiteral* node) {
+  IncrementNodeCount();
+  node->set_base_id(ReserveIdRange(FunctionLiteral::num_ids()));
+  // We don't recurse into the declarations or body of the function literal:
+  // you have to separately Renumber() each FunctionLiteral that you compile.
+}
+
+
+bool AstNumberingVisitor::Finish(FunctionLiteral* node) {
+  node->set_ast_properties(&properties_);
+  node->set_dont_optimize_reason(dont_optimize_reason());
+  return !HasStackOverflow();
+}
+
+
+bool AstNumberingVisitor::Renumber(FunctionLiteral* node) {
+  Scope* scope = node->scope();
+
+  if (scope->HasIllegalRedeclaration()) {
+    scope->VisitIllegalRedeclaration(this);
+    DisableCrankshaft(kFunctionWithIllegalRedeclaration);
+    return Finish(node);
+  }
+  if (scope->calls_eval()) DisableCrankshaft(kFunctionCallsEval);
+  if (scope->arguments() != NULL && !scope->arguments()->IsStackAllocated()) {
+    DisableCrankshaft(kContextAllocatedArguments);
+  }
+
+  VisitDeclarations(scope->declarations());
+  if (scope->is_function_scope() && scope->function() != NULL) {
+    // Visit the name of the named function expression.
+    Visit(scope->function());
+  }
+  VisitStatements(node->body());
+
+  return Finish(node);
+}
+
+
+bool AstNumbering::Renumber(FunctionLiteral* function, Zone* zone) {
+  AstNumberingVisitor visitor(zone);
+  return visitor.Renumber(function);
+}
+}
+}  // namespace v8::internal
diff --git a/src/ast-numbering.h b/src/ast-numbering.h
new file mode 100644
index 0000000..ab97c22
--- /dev/null
+++ b/src/ast-numbering.h
@@ -0,0 +1,19 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_AST_NUMBERING_H_
+#define V8_AST_NUMBERING_H_
+
+namespace v8 {
+namespace internal {
+
+namespace AstNumbering {
+// Assign type feedback IDs and bailout IDs to an AST node tree.
+//
+bool Renumber(FunctionLiteral* function, Zone* zone);
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_AST_NUMBERING_H_
diff --git a/src/ast-this-access-visitor.cc b/src/ast-this-access-visitor.cc
new file mode 100644
index 0000000..cf4a3de
--- /dev/null
+++ b/src/ast-this-access-visitor.cc
@@ -0,0 +1,239 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/ast-this-access-visitor.h"
+#include "src/parser.h"
+
+namespace v8 {
+namespace internal {
+
+typedef class AstThisAccessVisitor ATAV;  // for code shortitude.
+
+ATAV::AstThisAccessVisitor(Zone* zone) : uses_this_(false) {
+  InitializeAstVisitor(zone);
+}
+
+
+void ATAV::VisitVariableProxy(VariableProxy* proxy) {
+  if (proxy->is_this()) {
+    uses_this_ = true;
+  }
+}
+
+
+void ATAV::VisitSuperReference(SuperReference* leaf) {
+  // disallow super.method() and super(...).
+  uses_this_ = true;
+}
+
+
+void ATAV::VisitCallNew(CallNew* e) {
+  // new super(..) does not use 'this'.
+  if (!e->expression()->IsSuperReference()) {
+    Visit(e->expression());
+  }
+  VisitExpressions(e->arguments());
+}
+
+
+// ---------------------------------------------------------------------------
+// -- Leaf nodes -------------------------------------------------------------
+// ---------------------------------------------------------------------------
+
+void ATAV::VisitVariableDeclaration(VariableDeclaration* leaf) {}
+void ATAV::VisitFunctionDeclaration(FunctionDeclaration* leaf) {}
+void ATAV::VisitModuleDeclaration(ModuleDeclaration* leaf) {}
+void ATAV::VisitImportDeclaration(ImportDeclaration* leaf) {}
+void ATAV::VisitExportDeclaration(ExportDeclaration* leaf) {}
+void ATAV::VisitModuleVariable(ModuleVariable* leaf) {}
+void ATAV::VisitModulePath(ModulePath* leaf) {}
+void ATAV::VisitModuleUrl(ModuleUrl* leaf) {}
+void ATAV::VisitEmptyStatement(EmptyStatement* leaf) {}
+void ATAV::VisitContinueStatement(ContinueStatement* leaf) {}
+void ATAV::VisitBreakStatement(BreakStatement* leaf) {}
+void ATAV::VisitDebuggerStatement(DebuggerStatement* leaf) {}
+void ATAV::VisitFunctionLiteral(FunctionLiteral* leaf) {}
+void ATAV::VisitNativeFunctionLiteral(NativeFunctionLiteral* leaf) {}
+void ATAV::VisitLiteral(Literal* leaf) {}
+void ATAV::VisitRegExpLiteral(RegExpLiteral* leaf) {}
+void ATAV::VisitThisFunction(ThisFunction* leaf) {}
+
+// ---------------------------------------------------------------------------
+// -- Pass-through nodes------------------------------------------------------
+// ---------------------------------------------------------------------------
+void ATAV::VisitModuleLiteral(ModuleLiteral* e) { Visit(e->body()); }
+
+
+void ATAV::VisitBlock(Block* stmt) { VisitStatements(stmt->statements()); }
+
+
+void ATAV::VisitExpressionStatement(ExpressionStatement* stmt) {
+  Visit(stmt->expression());
+}
+
+
+void ATAV::VisitIfStatement(IfStatement* stmt) {
+  Visit(stmt->condition());
+  Visit(stmt->then_statement());
+  Visit(stmt->else_statement());
+}
+
+
+void ATAV::VisitReturnStatement(ReturnStatement* stmt) {
+  Visit(stmt->expression());
+}
+
+
+void ATAV::VisitWithStatement(WithStatement* stmt) {
+  Visit(stmt->expression());
+  Visit(stmt->statement());
+}
+
+
+void ATAV::VisitSwitchStatement(SwitchStatement* stmt) {
+  Visit(stmt->tag());
+  ZoneList<CaseClause*>* clauses = stmt->cases();
+  for (int i = 0; i < clauses->length(); i++) {
+    Visit(clauses->at(i));
+  }
+}
+
+
+void ATAV::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
+  Visit(stmt->try_block());
+  Visit(stmt->finally_block());
+}
+
+
+void ATAV::VisitClassLiteral(ClassLiteral* e) {
+  VisitIfNotNull(e->extends());
+  Visit(e->constructor());
+  ZoneList<ObjectLiteralProperty*>* properties = e->properties();
+  for (int i = 0; i < properties->length(); i++) {
+    Visit(properties->at(i)->value());
+  }
+}
+
+
+void ATAV::VisitConditional(Conditional* e) {
+  Visit(e->condition());
+  Visit(e->then_expression());
+  Visit(e->else_expression());
+}
+
+
+void ATAV::VisitObjectLiteral(ObjectLiteral* e) {
+  ZoneList<ObjectLiteralProperty*>* properties = e->properties();
+  for (int i = 0; i < properties->length(); i++) {
+    Visit(properties->at(i)->value());
+  }
+}
+
+
+void ATAV::VisitArrayLiteral(ArrayLiteral* e) { VisitExpressions(e->values()); }
+
+
+void ATAV::VisitYield(Yield* stmt) {
+  Visit(stmt->generator_object());
+  Visit(stmt->expression());
+}
+
+
+void ATAV::VisitThrow(Throw* stmt) { Visit(stmt->exception()); }
+
+
+void ATAV::VisitProperty(Property* e) {
+  Visit(e->obj());
+  Visit(e->key());
+}
+
+
+void ATAV::VisitCall(Call* e) {
+  Visit(e->expression());
+  VisitExpressions(e->arguments());
+}
+
+
+void ATAV::VisitCallRuntime(CallRuntime* e) {
+  VisitExpressions(e->arguments());
+}
+
+
+void ATAV::VisitUnaryOperation(UnaryOperation* e) { Visit(e->expression()); }
+
+
+void ATAV::VisitBinaryOperation(BinaryOperation* e) {
+  Visit(e->left());
+  Visit(e->right());
+}
+
+
+void ATAV::VisitCompareOperation(CompareOperation* e) {
+  Visit(e->left());
+  Visit(e->right());
+}
+
+
+void ATAV::VisitCaseClause(CaseClause* cc) {
+  if (!cc->is_default()) Visit(cc->label());
+  VisitStatements(cc->statements());
+}
+
+
+void ATAV::VisitModuleStatement(ModuleStatement* stmt) { Visit(stmt->body()); }
+
+
+void ATAV::VisitTryCatchStatement(TryCatchStatement* stmt) {
+  Visit(stmt->try_block());
+  Visit(stmt->catch_block());
+}
+
+
+void ATAV::VisitDoWhileStatement(DoWhileStatement* loop) {
+  Visit(loop->body());
+  Visit(loop->cond());
+}
+
+
+void ATAV::VisitWhileStatement(WhileStatement* loop) {
+  Visit(loop->cond());
+  Visit(loop->body());
+}
+
+
+void ATAV::VisitForStatement(ForStatement* loop) {
+  VisitIfNotNull(loop->init());
+  VisitIfNotNull(loop->cond());
+  Visit(loop->body());
+  VisitIfNotNull(loop->next());
+}
+
+
+void ATAV::VisitForInStatement(ForInStatement* loop) {
+  Visit(loop->each());
+  Visit(loop->subject());
+  Visit(loop->body());
+}
+
+
+void ATAV::VisitForOfStatement(ForOfStatement* loop) {
+  Visit(loop->each());
+  Visit(loop->subject());
+  Visit(loop->body());
+}
+
+
+void ATAV::VisitAssignment(Assignment* stmt) {
+  Expression* l = stmt->target();
+  Visit(l);
+  Visit(stmt->value());
+}
+
+
+void ATAV::VisitCountOperation(CountOperation* e) {
+  Expression* l = e->expression();
+  Visit(l);
+}
+}
+}  // namespace v8::internal
diff --git a/src/ast-this-access-visitor.h b/src/ast-this-access-visitor.h
new file mode 100644
index 0000000..6030981
--- /dev/null
+++ b/src/ast-this-access-visitor.h
@@ -0,0 +1,34 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_AST_THIS_ACCESS_VISITOR_H_
+#define V8_AST_THIS_ACCESS_VISITOR_H_
+#include "src/ast.h"
+
+namespace v8 {
+namespace internal {
+
+class AstThisAccessVisitor : public AstVisitor {
+ public:
+  explicit AstThisAccessVisitor(Zone* zone);
+
+  bool UsesThis() { return uses_this_; }
+
+#define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE;
+  AST_NODE_LIST(DECLARE_VISIT)
+#undef DECLARE_VISIT
+
+ private:
+  bool uses_this_;
+
+  void VisitIfNotNull(AstNode* node) {
+    if (node != NULL) Visit(node);
+  }
+
+  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
+  DISALLOW_COPY_AND_ASSIGN(AstThisAccessVisitor);
+};
+}
+}  // namespace v8::internal
+#endif  // V8_AST_THIS_ACCESS_VISITOR_H_
diff --git a/src/ast-value-factory.cc b/src/ast-value-factory.cc
index ea8474f..ff20100 100644
--- a/src/ast-value-factory.cc
+++ b/src/ast-value-factory.cc
@@ -56,22 +56,20 @@
   explicit AstRawStringInternalizationKey(const AstRawString* string)
       : string_(string) {}
 
-  virtual bool IsMatch(Object* other) OVERRIDE {
+  bool IsMatch(Object* other) OVERRIDE {
     if (string_->is_one_byte_)
       return String::cast(other)->IsOneByteEqualTo(string_->literal_bytes_);
     return String::cast(other)->IsTwoByteEqualTo(
         Vector<const uint16_t>::cast(string_->literal_bytes_));
   }
 
-  virtual uint32_t Hash() OVERRIDE {
-    return string_->hash() >> Name::kHashShift;
-  }
+  uint32_t Hash() OVERRIDE { return string_->hash() >> Name::kHashShift; }
 
-  virtual uint32_t HashForObject(Object* key) OVERRIDE {
+  uint32_t HashForObject(Object* key) OVERRIDE {
     return String::cast(key)->Hash();
   }
 
-  virtual Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
+  Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
     if (string_->is_one_byte_)
       return isolate->factory()->NewOneByteInternalizedString(
           string_->literal_bytes_, string_->hash());
@@ -117,14 +115,15 @@
 
 
 bool AstRawString::Compare(void* a, void* b) {
-  AstRawString* string1 = reinterpret_cast<AstRawString*>(a);
-  AstRawString* string2 = reinterpret_cast<AstRawString*>(b);
-  if (string1->is_one_byte_ != string2->is_one_byte_) return false;
-  if (string1->hash_ != string2->hash_) return false;
-  int length = string1->literal_bytes_.length();
-  if (string2->literal_bytes_.length() != length) return false;
-  return memcmp(string1->literal_bytes_.start(),
-                string2->literal_bytes_.start(), length) == 0;
+  return *static_cast<AstRawString*>(a) == *static_cast<AstRawString*>(b);
+}
+
+bool AstRawString::operator==(const AstRawString& rhs) const {
+  if (is_one_byte_ != rhs.is_one_byte_) return false;
+  if (hash_ != rhs.hash_) return false;
+  int len = literal_bytes_.length();
+  if (rhs.literal_bytes_.length() != len) return false;
+  return memcmp(literal_bytes_.start(), rhs.literal_bytes_.start(), len) == 0;
 }
 
 
@@ -158,9 +157,6 @@
       return DoubleToBoolean(number_);
     case SMI:
       return smi_ != 0;
-    case STRING_ARRAY:
-      UNREACHABLE();
-      break;
     case BOOLEAN:
       return bool_;
     case NULL_TYPE:
@@ -184,9 +180,8 @@
       DCHECK(!string_->string().is_null());
       break;
     case SYMBOL:
-      value_ = Object::GetProperty(
-                   isolate, handle(isolate->native_context()->builtins()),
-                   symbol_name_).ToHandleChecked();
+      DCHECK_EQ(0, strcmp(symbol_name_, "iterator_symbol"));
+      value_ = isolate->factory()->iterator_symbol();
       break;
     case NUMBER:
       value_ = isolate->factory()->NewNumber(number_, TENURED);
@@ -201,22 +196,6 @@
         value_ = isolate->factory()->false_value();
       }
       break;
-    case STRING_ARRAY: {
-      DCHECK(strings_ != NULL);
-      Factory* factory = isolate->factory();
-      int len = strings_->length();
-      Handle<FixedArray> elements = factory->NewFixedArray(len, TENURED);
-      for (int i = 0; i < len; i++) {
-        const AstRawString* string = (*strings_)[i];
-        Handle<Object> element = string->string();
-        // Strings are already internalized.
-        DCHECK(!element.is_null());
-        elements->set(i, *element);
-      }
-      value_ =
-          factory->NewJSArrayWithElements(elements, FAST_ELEMENTS, TENURED);
-      break;
-    }
     case NULL_TYPE:
       value_ = isolate->factory()->null_value();
       break;
@@ -230,7 +209,7 @@
 }
 
 
-const AstRawString* AstValueFactory::GetOneByteString(
+AstRawString* AstValueFactory::GetOneByteStringInternal(
     Vector<const uint8_t> literal) {
   uint32_t hash = StringHasher::HashSequentialString<uint8_t>(
       literal.start(), literal.length(), hash_seed_);
@@ -238,7 +217,7 @@
 }
 
 
-const AstRawString* AstValueFactory::GetTwoByteString(
+AstRawString* AstValueFactory::GetTwoByteStringInternal(
     Vector<const uint16_t> literal) {
   uint32_t hash = StringHasher::HashSequentialString<uint16_t>(
       literal.start(), literal.length(), hash_seed_);
@@ -247,13 +226,24 @@
 
 
 const AstRawString* AstValueFactory::GetString(Handle<String> literal) {
-  DisallowHeapAllocation no_gc;
-  String::FlatContent content = literal->GetFlatContent();
-  if (content.IsOneByte()) {
-    return GetOneByteString(content.ToOneByteVector());
+  // For the FlatContent to stay valid, we shouldn't do any heap
+  // allocation. Make sure we won't try to internalize the string in GetString.
+  AstRawString* result = NULL;
+  Isolate* saved_isolate = isolate_;
+  isolate_ = NULL;
+  {
+    DisallowHeapAllocation no_gc;
+    String::FlatContent content = literal->GetFlatContent();
+    if (content.IsOneByte()) {
+      result = GetOneByteStringInternal(content.ToOneByteVector());
+    } else {
+      DCHECK(content.IsTwoByte());
+      result = GetTwoByteStringInternal(content.ToUC16Vector());
+    }
   }
-  DCHECK(content.IsTwoByte());
-  return GetTwoByteString(content.ToUC16Vector());
+  isolate_ = saved_isolate;
+  if (isolate_) result->Internalize(isolate_);
+  return result;
 }
 
 
@@ -329,59 +319,45 @@
 }
 
 
+#define GENERATE_VALUE_GETTER(value, initializer) \
+  if (!value) {                                   \
+    value = new (zone_) AstValue(initializer);    \
+    if (isolate_) {                               \
+      value->Internalize(isolate_);               \
+    }                                             \
+    values_.Add(value);                           \
+  }                                               \
+  return value;
+
+
 const AstValue* AstValueFactory::NewBoolean(bool b) {
-  AstValue* value = new (zone_) AstValue(b);
-  if (isolate_) {
-    value->Internalize(isolate_);
+  if (b) {
+    GENERATE_VALUE_GETTER(true_value_, true);
+  } else {
+    GENERATE_VALUE_GETTER(false_value_, false);
   }
-  values_.Add(value);
-  return value;
-}
-
-
-const AstValue* AstValueFactory::NewStringList(
-    ZoneList<const AstRawString*>* strings) {
-  AstValue* value = new (zone_) AstValue(strings);
-  if (isolate_) {
-    value->Internalize(isolate_);
-  }
-  values_.Add(value);
-  return value;
 }
 
 
 const AstValue* AstValueFactory::NewNull() {
-  AstValue* value = new (zone_) AstValue(AstValue::NULL_TYPE);
-  if (isolate_) {
-    value->Internalize(isolate_);
-  }
-  values_.Add(value);
-  return value;
+  GENERATE_VALUE_GETTER(null_value_, AstValue::NULL_TYPE);
 }
 
 
 const AstValue* AstValueFactory::NewUndefined() {
-  AstValue* value = new (zone_) AstValue(AstValue::UNDEFINED);
-  if (isolate_) {
-    value->Internalize(isolate_);
-  }
-  values_.Add(value);
-  return value;
+  GENERATE_VALUE_GETTER(undefined_value_, AstValue::UNDEFINED);
 }
 
 
 const AstValue* AstValueFactory::NewTheHole() {
-  AstValue* value = new (zone_) AstValue(AstValue::THE_HOLE);
-  if (isolate_) {
-    value->Internalize(isolate_);
-  }
-  values_.Add(value);
-  return value;
+  GENERATE_VALUE_GETTER(the_hole_value_, AstValue::THE_HOLE);
 }
 
 
-const AstRawString* AstValueFactory::GetString(
-    uint32_t hash, bool is_one_byte, Vector<const byte> literal_bytes) {
+#undef GENERATE_VALUE_GETTER
+
+AstRawString* AstValueFactory::GetString(uint32_t hash, bool is_one_byte,
+                                         Vector<const byte> literal_bytes) {
   // literal_bytes here points to whatever the user passed, and this is OK
   // because we use vector_compare (which checks the contents) to compare
   // against the AstRawStrings which are in the string_table_. We should not
diff --git a/src/ast-value-factory.h b/src/ast-value-factory.h
index 2f84163..a189f17 100644
--- a/src/ast-value-factory.h
+++ b/src/ast-value-factory.h
@@ -64,13 +64,13 @@
 
 class AstRawString : public AstString {
  public:
-  virtual int length() const OVERRIDE {
+  int length() const OVERRIDE {
     if (is_one_byte_)
       return literal_bytes_.length();
     return literal_bytes_.length() / 2;
   }
 
-  virtual void Internalize(Isolate* isolate) OVERRIDE;
+  void Internalize(Isolate* isolate) OVERRIDE;
 
   bool AsArrayIndex(uint32_t* index) const;
 
@@ -88,12 +88,16 @@
     return *c;
   }
 
+  V8_INLINE bool IsArguments(AstValueFactory* ast_value_factory) const;
+
   // For storing AstRawStrings in a hash map.
   uint32_t hash() const {
     return hash_;
   }
   static bool Compare(void* a, void* b);
 
+  bool operator==(const AstRawString& rhs) const;
+
  private:
   friend class AstValueFactory;
   friend class AstRawStringInternalizationKey;
@@ -120,11 +124,9 @@
       : left_(left),
         right_(right) {}
 
-  virtual int length() const OVERRIDE {
-    return left_->length() + right_->length();
-  }
+  int length() const OVERRIDE { return left_->length() + right_->length(); }
 
-  virtual void Internalize(Isolate* isolate) OVERRIDE;
+  void Internalize(Isolate* isolate) OVERRIDE;
 
  private:
   friend class AstValueFactory;
@@ -190,7 +192,6 @@
     NUMBER,
     SMI,
     BOOLEAN,
-    STRING_ARRAY,
     NULL_TYPE,
     UNDEFINED,
     THE_HOLE
@@ -209,10 +210,6 @@
 
   explicit AstValue(bool b) : type_(BOOLEAN) { bool_ = b; }
 
-  explicit AstValue(ZoneList<const AstRawString*>* s) : type_(STRING_ARRAY) {
-    strings_ = s;
-  }
-
   explicit AstValue(Type t) : type_(t) {
     DCHECK(t == NULL_TYPE || t == UNDEFINED || t == THE_HOLE);
   }
@@ -234,36 +231,44 @@
 };
 
 
-// For generating string constants.
-#define STRING_CONSTANTS(F)                           \
-  F(anonymous_function, "(anonymous function)")       \
-  F(arguments, "arguments")                           \
-  F(constructor, "constructor")                       \
-  F(done, "done")                                     \
-  F(dot, ".")                                         \
-  F(dot_for, ".for")                                  \
-  F(dot_generator, ".generator")                      \
-  F(dot_generator_object, ".generator_object")        \
-  F(dot_iterator, ".iterator")                        \
-  F(dot_module, ".module")                            \
-  F(dot_result, ".result")                            \
-  F(empty, "")                                        \
-  F(eval, "eval")                                     \
-  F(initialize_const_global, "initializeConstGlobal") \
-  F(initialize_var_global, "initializeVarGlobal")     \
-  F(make_reference_error, "MakeReferenceError")       \
-  F(make_syntax_error, "MakeSyntaxError")             \
-  F(make_type_error, "MakeTypeError")                 \
-  F(module, "module")                                 \
-  F(native, "native")                                 \
-  F(next, "next")                                     \
-  F(proto, "__proto__")                               \
-  F(prototype, "prototype")                           \
-  F(this, "this")                                     \
-  F(use_asm, "use asm")                               \
-  F(use_strict, "use strict")                         \
+// For generating constants.
+#define STRING_CONSTANTS(F)                             \
+  F(anonymous_function, "(anonymous function)")         \
+  F(arguments, "arguments")                             \
+  F(constructor, "constructor")                         \
+  F(done, "done")                                       \
+  F(dot, ".")                                           \
+  F(dot_for, ".for")                                    \
+  F(dot_generator, ".generator")                        \
+  F(dot_generator_object, ".generator_object")          \
+  F(dot_iterator, ".iterator")                          \
+  F(dot_module, ".module")                              \
+  F(dot_result, ".result")                              \
+  F(empty, "")                                          \
+  F(eval, "eval")                                       \
+  F(get_template_callsite, "GetTemplateCallSite")       \
+  F(initialize_const_global, "initializeConstGlobal")   \
+  F(initialize_var_global, "initializeVarGlobal")       \
+  F(let, "let")                                         \
+  F(make_reference_error, "MakeReferenceErrorEmbedded") \
+  F(make_syntax_error, "MakeSyntaxErrorEmbedded")       \
+  F(make_type_error, "MakeTypeErrorEmbedded")           \
+  F(module, "module")                                   \
+  F(native, "native")                                   \
+  F(next, "next")                                       \
+  F(proto, "__proto__")                                 \
+  F(prototype, "prototype")                             \
+  F(this, "this")                                       \
+  F(use_asm, "use asm")                                 \
+  F(use_strict, "use strict")                           \
   F(value, "value")
 
+#define OTHER_CONSTANTS(F) \
+  F(true_value)            \
+  F(false_value)           \
+  F(null_value)            \
+  F(undefined_value)       \
+  F(the_hole_value)
 
 class AstValueFactory {
  public:
@@ -272,18 +277,26 @@
         zone_(zone),
         isolate_(NULL),
         hash_seed_(hash_seed) {
-#define F(name, str) \
-    name##_string_ = NULL;
+#define F(name, str) name##_string_ = NULL;
     STRING_CONSTANTS(F)
 #undef F
+#define F(name) name##_ = NULL;
+    OTHER_CONSTANTS(F)
+#undef F
   }
 
-  const AstRawString* GetOneByteString(Vector<const uint8_t> literal);
+  Zone* zone() const { return zone_; }
+
+  const AstRawString* GetOneByteString(Vector<const uint8_t> literal) {
+    return GetOneByteStringInternal(literal);
+  }
   const AstRawString* GetOneByteString(const char* string) {
     return GetOneByteString(Vector<const uint8_t>(
         reinterpret_cast<const uint8_t*>(string), StrLength(string)));
   }
-  const AstRawString* GetTwoByteString(Vector<const uint16_t> literal);
+  const AstRawString* GetTwoByteString(Vector<const uint16_t> literal) {
+    return GetTwoByteStringInternal(literal);
+  }
   const AstRawString* GetString(Handle<String> literal);
   const AstConsString* NewConsString(const AstString* left,
                                      const AstString* right);
@@ -293,15 +306,15 @@
     return isolate_ != NULL;
   }
 
-#define F(name, str) \
-  const AstRawString* name##_string() { \
-    if (name##_string_ == NULL) { \
-      const char* data = str; \
-      name##_string_ = GetOneByteString( \
+#define F(name, str)                                                    \
+  const AstRawString* name##_string() {                                 \
+    if (name##_string_ == NULL) {                                       \
+      const char* data = str;                                           \
+      name##_string_ = GetOneByteString(                                \
           Vector<const uint8_t>(reinterpret_cast<const uint8_t*>(data), \
-                                static_cast<int>(strlen(data)))); \
-    } \
-    return name##_string_; \
+                                static_cast<int>(strlen(data))));       \
+    }                                                                   \
+    return name##_string_;                                              \
   }
   STRING_CONSTANTS(F)
 #undef F
@@ -318,8 +331,10 @@
   const AstValue* NewTheHole();
 
  private:
-  const AstRawString* GetString(uint32_t hash, bool is_one_byte,
-                                Vector<const byte> literal_bytes);
+  AstRawString* GetOneByteStringInternal(Vector<const uint8_t> literal);
+  AstRawString* GetTwoByteStringInternal(Vector<const uint16_t> literal);
+  AstRawString* GetString(uint32_t hash, bool is_one_byte,
+                          Vector<const byte> literal_bytes);
 
   // All strings are copied here, one after another (no NULLs inbetween).
   HashMap string_table_;
@@ -332,14 +347,22 @@
 
   uint32_t hash_seed_;
 
-#define F(name, str) \
-  const AstRawString* name##_string_;
+#define F(name, str) const AstRawString* name##_string_;
   STRING_CONSTANTS(F)
 #undef F
+
+#define F(name) AstValue* name##_;
+  OTHER_CONSTANTS(F)
+#undef F
 };
 
+
+bool AstRawString::IsArguments(AstValueFactory* ast_value_factory) const {
+  return ast_value_factory->arguments_string() == this;
+}
 } }  // namespace v8::internal
 
 #undef STRING_CONSTANTS
+#undef OTHER_CONSTANTS
 
 #endif  // V8_AST_VALUE_FACTORY_H_
diff --git a/src/ast.cc b/src/ast.cc
index 6816992..6329371 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -59,59 +59,56 @@
 }
 
 
-VariableProxy::VariableProxy(Zone* zone, Variable* var, int position,
-                             IdGen* id_gen)
-    : Expression(zone, position, id_gen),
-      name_(var->raw_name()),
-      var_(NULL),  // Will be set by the call to BindTo.
-      is_this_(var->is_this()),
-      is_assigned_(false),
-      interface_(var->interface()),
-      variable_feedback_slot_(kInvalidFeedbackSlot) {
+VariableProxy::VariableProxy(Zone* zone, Variable* var, int position)
+    : Expression(zone, position),
+      bit_field_(IsThisField::encode(var->is_this()) |
+                 IsAssignedField::encode(false) |
+                 IsResolvedField::encode(false)),
+      variable_feedback_slot_(FeedbackVectorICSlot::Invalid()),
+      raw_name_(var->raw_name()),
+      interface_(var->interface()) {
   BindTo(var);
 }
 
 
 VariableProxy::VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
-                             Interface* interface, int position, IdGen* id_gen)
-    : Expression(zone, position, id_gen),
-      name_(name),
-      var_(NULL),
-      is_this_(is_this),
-      is_assigned_(false),
-      interface_(interface),
-      variable_feedback_slot_(kInvalidFeedbackSlot) {}
+                             Interface* interface, int position)
+    : Expression(zone, position),
+      bit_field_(IsThisField::encode(is_this) | IsAssignedField::encode(false) |
+                 IsResolvedField::encode(false)),
+      variable_feedback_slot_(FeedbackVectorICSlot::Invalid()),
+      raw_name_(name),
+      interface_(interface) {}
 
 
 void VariableProxy::BindTo(Variable* var) {
-  DCHECK(var_ == NULL);  // must be bound only once
-  DCHECK(var != NULL);  // must bind
   DCHECK(!FLAG_harmony_modules || interface_->IsUnified(var->interface()));
-  DCHECK((is_this() && var->is_this()) || name_ == var->raw_name());
+  DCHECK((is_this() && var->is_this()) || raw_name() == var->raw_name());
   // Ideally CONST-ness should match. However, this is very hard to achieve
   // because we don't know the exact semantics of conflicting (const and
   // non-const) multiple variable declarations, const vars introduced via
   // eval() etc.  Const-ness and variable declarations are a complete mess
   // in JS. Sigh...
-  var_ = var;
+  set_var(var);
+  set_is_resolved();
   var->set_is_used();
 }
 
 
 Assignment::Assignment(Zone* zone, Token::Value op, Expression* target,
-                       Expression* value, int pos, IdGen* id_gen)
-    : Expression(zone, pos, id_gen),
-      op_(op),
+                       Expression* value, int pos)
+    : Expression(zone, pos),
+      bit_field_(IsUninitializedField::encode(false) |
+                 KeyTypeField::encode(ELEMENT) |
+                 StoreModeField::encode(STANDARD_STORE) |
+                 TokenField::encode(op)),
       target_(target),
       value_(value),
-      binary_operation_(NULL),
-      assignment_id_(id_gen->GetNextId()),
-      is_uninitialized_(false),
-      store_mode_(STANDARD_STORE) {}
+      binary_operation_(NULL) {}
 
 
 Token::Value Assignment::binary_op() const {
-  switch (op_) {
+  switch (op()) {
     case Token::ASSIGN_BIT_OR: return Token::BIT_OR;
     case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR;
     case Token::ASSIGN_BIT_AND: return Token::BIT_AND;
@@ -154,6 +151,21 @@
 }
 
 
+bool FunctionLiteral::uses_super_property() const {
+  DCHECK_NOT_NULL(scope());
+  return scope()->uses_super_property() || scope()->inner_uses_super_property();
+}
+
+
+bool FunctionLiteral::uses_super_constructor_call() const {
+  DCHECK_NOT_NULL(scope());
+  return scope()->uses_super_constructor_call() ||
+         scope()->inner_uses_super_constructor_call();
+}
+
+
+// Helper to find an existing shared function info in the baseline code for the
+// given function literal. Used to canonicalize SharedFunctionInfo objects.
 void FunctionLiteral::InitializeSharedInfo(
     Handle<Code> unoptimized_code) {
   for (RelocIterator it(*unoptimized_code); !it.done(); it.next()) {
@@ -436,7 +448,7 @@
 
 
 bool BinaryOperation::ResultOverwriteAllowed() const {
-  switch (op_) {
+  switch (op()) {
     case Token::COMMA:
     case Token::OR:
     case Token::AND:
@@ -560,7 +572,7 @@
 // once we use the common type field in the AST consistently.
 
 void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
-  to_boolean_types_ = oracle->ToBooleanTypes(test_id());
+  set_to_boolean_types(oracle->ToBooleanTypes(test_id()));
 }
 
 
@@ -570,6 +582,12 @@
 }
 
 
+FeedbackVectorRequirements Call::ComputeFeedbackRequirements(Isolate* isolate) {
+  int ic_slots = IsUsingCallFeedbackSlot(isolate) ? 1 : 0;
+  return FeedbackVectorRequirements(0, ic_slots);
+}
+
+
 Call::CallType Call::GetCallType(Isolate* isolate) const {
   VariableProxy* proxy = expression()->AsVariableProxy();
   if (proxy != NULL) {
@@ -582,6 +600,8 @@
     }
   }
 
+  if (expression()->AsSuperReference() != NULL) return SUPER_CALL;
+
   Property* property = expression()->AsProperty();
   return property != NULL ? PROPERTY_CALL : OTHER_CALL;
 }
@@ -607,17 +627,14 @@
 
 
 void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
-  int allocation_site_feedback_slot = FLAG_pretenuring_call_new
-      ? AllocationSiteFeedbackSlot()
-      : CallNewFeedbackSlot();
+  FeedbackVectorSlot allocation_site_feedback_slot =
+      FLAG_pretenuring_call_new ? AllocationSiteFeedbackSlot()
+                                : CallNewFeedbackSlot();
   allocation_site_ =
       oracle->GetCallNewAllocationSite(allocation_site_feedback_slot);
   is_monomorphic_ = oracle->CallNewIsMonomorphic(CallNewFeedbackSlot());
   if (is_monomorphic_) {
     target_ = oracle->GetCallNewTarget(CallNewFeedbackSlot());
-    if (!allocation_site_.is_null()) {
-      elements_kind_ = allocation_site_->GetElementsKind();
-    }
   }
 }
 
@@ -797,14 +814,14 @@
 // output formats are alike.
 class RegExpUnparser FINAL : public RegExpVisitor {
  public:
-  RegExpUnparser(OStream& os, Zone* zone) : os_(os), zone_(zone) {}
+  RegExpUnparser(std::ostream& os, Zone* zone) : os_(os), zone_(zone) {}
   void VisitCharacterRange(CharacterRange that);
 #define MAKE_CASE(Name) virtual void* Visit##Name(RegExp##Name*,          \
                                                   void* data) OVERRIDE;
   FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
 #undef MAKE_CASE
  private:
-  OStream& os_;
+  std::ostream& os_;
   Zone* zone_;
 };
 
@@ -947,7 +964,7 @@
 }
 
 
-OStream& RegExpTree::Print(OStream& os, Zone* zone) {  // NOLINT
+std::ostream& RegExpTree::Print(std::ostream& os, Zone* zone) {  // NOLINT
   RegExpUnparser unparser(os, zone);
   Accept(&unparser, NULL);
   return os;
@@ -992,157 +1009,26 @@
 
 
 CaseClause::CaseClause(Zone* zone, Expression* label,
-                       ZoneList<Statement*>* statements, int pos, IdGen* id_gen)
-    : Expression(zone, pos, id_gen),
+                       ZoneList<Statement*>* statements, int pos)
+    : Expression(zone, pos),
       label_(label),
       statements_(statements),
-      compare_type_(Type::None(zone)),
-      compare_id_(id_gen->GetNextId()),
-      entry_id_(id_gen->GetNextId()) {}
+      compare_type_(Type::None(zone)) {}
 
 
-#define REGULAR_NODE(NodeType)                                   \
-  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
-    increase_node_count();                                       \
-  }
-#define REGULAR_NODE_WITH_FEEDBACK_SLOTS(NodeType)               \
-  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
-    increase_node_count();                                       \
-    add_slot_node(node);                                         \
-  }
-#define DONT_OPTIMIZE_NODE(NodeType)                             \
-  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
-    increase_node_count();                                       \
-    set_dont_crankshaft_reason(k##NodeType);                     \
-    add_flag(kDontSelfOptimize);                                 \
-  }
-#define DONT_OPTIMIZE_NODE_WITH_FEEDBACK_SLOTS(NodeType)         \
-  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
-    increase_node_count();                                       \
-    add_slot_node(node);                                         \
-    set_dont_crankshaft_reason(k##NodeType);                     \
-    add_flag(kDontSelfOptimize);                                 \
-  }
-#define DONT_TURBOFAN_NODE(NodeType)                             \
-  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
-    increase_node_count();                                       \
-    set_dont_crankshaft_reason(k##NodeType);                     \
-    set_dont_turbofan_reason(k##NodeType);                       \
-    add_flag(kDontSelfOptimize);                                 \
-  }
-#define DONT_SELFOPTIMIZE_NODE(NodeType)                         \
-  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
-    increase_node_count();                                       \
-    add_flag(kDontSelfOptimize);                                 \
-  }
-#define DONT_SELFOPTIMIZE_NODE_WITH_FEEDBACK_SLOTS(NodeType)     \
-  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
-    increase_node_count();                                       \
-    add_slot_node(node);                                         \
-    add_flag(kDontSelfOptimize);                                 \
-  }
-#define DONT_CACHE_NODE(NodeType)                                \
-  void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \
-    increase_node_count();                                       \
-    set_dont_crankshaft_reason(k##NodeType);                     \
-    add_flag(kDontSelfOptimize);                                 \
-    add_flag(kDontCache);                                        \
-  }
-
-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(CaseClause)
-REGULAR_NODE(Conditional)
-REGULAR_NODE(Literal)
-REGULAR_NODE(ArrayLiteral)
-REGULAR_NODE(ObjectLiteral)
-REGULAR_NODE(RegExpLiteral)
-REGULAR_NODE(FunctionLiteral)
-REGULAR_NODE(Assignment)
-REGULAR_NODE(Throw)
-REGULAR_NODE(UnaryOperation)
-REGULAR_NODE(CountOperation)
-REGULAR_NODE(BinaryOperation)
-REGULAR_NODE(CompareOperation)
-REGULAR_NODE(ThisFunction)
-
-REGULAR_NODE_WITH_FEEDBACK_SLOTS(Call)
-REGULAR_NODE_WITH_FEEDBACK_SLOTS(CallNew)
-REGULAR_NODE_WITH_FEEDBACK_SLOTS(Property)
-// In theory, for VariableProxy we'd have to add:
-// if (node->var()->IsLookupSlot())
-//   set_dont_optimize_reason(kReferenceToAVariableWhichRequiresDynamicLookup);
-// 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_WITH_FEEDBACK_SLOTS(VariableProxy)
-
-// We currently do not optimize any modules.
-DONT_OPTIMIZE_NODE(ModuleDeclaration)
-DONT_OPTIMIZE_NODE(ImportDeclaration)
-DONT_OPTIMIZE_NODE(ExportDeclaration)
-DONT_OPTIMIZE_NODE(ModuleVariable)
-DONT_OPTIMIZE_NODE(ModulePath)
-DONT_OPTIMIZE_NODE(ModuleUrl)
-DONT_OPTIMIZE_NODE(ModuleStatement)
-DONT_OPTIMIZE_NODE(WithStatement)
-DONT_OPTIMIZE_NODE(DebuggerStatement)
-DONT_OPTIMIZE_NODE(ClassLiteral)
-DONT_OPTIMIZE_NODE(NativeFunctionLiteral)
-DONT_OPTIMIZE_NODE(SuperReference)
-
-DONT_OPTIMIZE_NODE_WITH_FEEDBACK_SLOTS(Yield)
-
-// TODO(turbofan): Remove the dont_turbofan_reason once this list is empty.
-DONT_TURBOFAN_NODE(ForOfStatement)
-DONT_TURBOFAN_NODE(TryCatchStatement)
-DONT_TURBOFAN_NODE(TryFinallyStatement)
-
-DONT_SELFOPTIMIZE_NODE(DoWhileStatement)
-DONT_SELFOPTIMIZE_NODE(WhileStatement)
-DONT_SELFOPTIMIZE_NODE(ForStatement)
-
-DONT_SELFOPTIMIZE_NODE_WITH_FEEDBACK_SLOTS(ForInStatement)
-
-DONT_CACHE_NODE(ModuleLiteral)
-
-
-void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) {
-  increase_node_count();
-  add_slot_node(node);
-  if (node->is_jsruntime()) {
-    // Don't try to optimize JS runtime calls because we bailout on them.
-    set_dont_crankshaft_reason(kCallToAJavaScriptRuntimeFunction);
-  }
+uint32_t Literal::Hash() {
+  return raw_value()->IsString()
+             ? raw_value()->AsString()->hash()
+             : ComputeLongHash(double_to_uint64(raw_value()->AsNumber()));
 }
 
-#undef REGULAR_NODE
-#undef DONT_OPTIMIZE_NODE
-#undef DONT_SELFOPTIMIZE_NODE
-#undef DONT_CACHE_NODE
 
-
-Handle<String> Literal::ToString() {
-  if (value_->IsString()) return value_->AsString()->string();
-  DCHECK(value_->IsNumber());
-  char arr[100];
-  Vector<char> buffer(arr, arraysize(arr));
-  const char* str;
-  if (value()->IsSmi()) {
-    // Optimization only, the heap number case would subsume this.
-    SNPrintF(buffer, "%d", Smi::cast(*value())->value());
-    str = arr;
-  } else {
-    str = DoubleToCString(value()->Number(), buffer);
-  }
-  return isolate_->factory()->NewStringFromAsciiChecked(str);
+// static
+bool Literal::Match(void* literal1, void* literal2) {
+  const AstValue* x = static_cast<Literal*>(literal1)->raw_value();
+  const AstValue* y = static_cast<Literal*>(literal2)->raw_value();
+  return (x->IsString() && y->IsString() && *x->AsString() == *y->AsString()) ||
+         (x->IsNumber() && y->IsNumber() && x->AsNumber() == y->AsNumber());
 }
 
 
diff --git a/src/ast.h b/src/ast.h
index 03f43ad..43bde6a 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -11,12 +11,11 @@
 #include "src/ast-value-factory.h"
 #include "src/bailout-reason.h"
 #include "src/factory.h"
-#include "src/feedback-slots.h"
 #include "src/interface.h"
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/list-inl.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 #include "src/small-pointer-list.h"
 #include "src/smart-pointers.h"
 #include "src/token.h"
@@ -106,8 +105,7 @@
   EXPRESSION_NODE_LIST(V)
 
 // Forward declarations
-class AstConstructionVisitor;
-template<class> class AstNodeFactory;
+class AstNodeFactory;
 class AstVisitor;
 class Declaration;
 class Module;
@@ -115,7 +113,6 @@
 class Expression;
 class IterationStatement;
 class MaterializedLiteral;
-class OStream;
 class Statement;
 class TargetCollector;
 class TypeFeedbackOracle;
@@ -144,12 +141,10 @@
 typedef ZoneList<Handle<Object> > ZoneObjectList;
 
 
-#define DECLARE_NODE_TYPE(type)                                 \
-  virtual void Accept(AstVisitor* v) OVERRIDE;                  \
-  virtual AstNode::NodeType node_type() const FINAL OVERRIDE {  \
-    return AstNode::k##type;                                    \
-  }                                                             \
-  template<class> friend class AstNodeFactory;
+#define DECLARE_NODE_TYPE(type)                                          \
+  void Accept(AstVisitor* v) OVERRIDE;                                   \
+  AstNode::NodeType node_type() const FINAL { return AstNode::k##type; } \
+  friend class AstNodeFactory;
 
 
 enum AstPropertiesFlag {
@@ -159,46 +154,47 @@
 };
 
 
+class FeedbackVectorRequirements {
+ public:
+  FeedbackVectorRequirements(int slots, int ic_slots)
+      : slots_(slots), ic_slots_(ic_slots) {}
+
+  int slots() const { return slots_; }
+  int ic_slots() const { return ic_slots_; }
+
+ private:
+  int slots_;
+  int ic_slots_;
+};
+
+
 class AstProperties FINAL BASE_EMBEDDED {
  public:
   class Flags : public EnumSet<AstPropertiesFlag, int> {};
 
-AstProperties() : node_count_(0), feedback_slots_(0) {}
+  AstProperties() : node_count_(0) {}
 
   Flags* flags() { return &flags_; }
   int node_count() { return node_count_; }
   void add_node_count(int count) { node_count_ += count; }
 
-  int feedback_slots() const { return feedback_slots_; }
-  void increase_feedback_slots(int count) {
-    feedback_slots_ += count;
-  }
+  int slots() const { return spec_.slots(); }
+  void increase_slots(int count) { spec_.increase_slots(count); }
+
+  int ic_slots() const { return spec_.ic_slots(); }
+  void increase_ic_slots(int count) { spec_.increase_ic_slots(count); }
+  void SetKind(int ic_slot, Code::Kind kind) { spec_.SetKind(ic_slot, kind); }
+  const FeedbackVectorSpec& get_spec() const { return spec_; }
 
  private:
   Flags flags_;
   int node_count_;
-  int feedback_slots_;
+  FeedbackVectorSpec spec_;
 };
 
 
 class AstNode: public ZoneObject {
  public:
-  // For generating IDs for AstNodes.
-  class IdGen {
-   public:
-    explicit IdGen(int id = 0) : id_(id) {}
-
-    int GetNextId() { return ReserveIdRange(1); }
-    int ReserveIdRange(int n) {
-      int tmp = id_;
-      id_ += n;
-      return tmp;
-    }
-
-   private:
-    int id_;
-  };
-
 #define DECLARE_TYPE_ENUM(type) k##type,
   enum NodeType {
     AST_NODE_LIST(DECLARE_TYPE_ENUM)
@@ -234,12 +230,23 @@
   virtual IterationStatement* AsIterationStatement() { return NULL; }
   virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
 
- protected:
-  // Some nodes re-use bailout IDs for type feedback.
-  static TypeFeedbackId reuse(BailoutId id) {
-    return TypeFeedbackId(id.ToInt());
+  // The interface for feedback slots, with default no-op implementations for
+  // node types which don't actually have this. Note that this is conceptually
+  // not really nice, but multiple inheritance would introduce yet another
+  // vtable entry per node, something we don't want for space reasons.
+  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
+      Isolate* isolate) {
+    return FeedbackVectorRequirements(0, 0);
   }
-
+  virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) { UNREACHABLE(); }
+  virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) {
+    UNREACHABLE();
+  }
+  // Each ICSlot stores a kind of IC which the participating node should know.
+  virtual Code::Kind FeedbackICSlotKind(int index) {
+    UNREACHABLE();
+    return Code::NUMBER_OF_KINDS;
+  }
 
  private:
   // Hidden to prevent accidental usage. It would have to load the
@@ -354,9 +361,17 @@
   void set_bounds(Bounds bounds) { bounds_ = bounds; }
 
   // Whether the expression is parenthesized
-  unsigned parenthesization_level() const { return parenthesization_level_; }
-  bool is_parenthesized() const { return parenthesization_level_ > 0; }
-  void increase_parenthesization_level() { ++parenthesization_level_; }
+  bool is_parenthesized() const {
+    return IsParenthesizedField::decode(bit_field_);
+  }
+  bool is_multi_parenthesized() const {
+    return IsMultiParenthesizedField::decode(bit_field_);
+  }
+  void increase_parenthesization_level() {
+    bit_field_ =
+        IsMultiParenthesizedField::update(bit_field_, is_parenthesized());
+    bit_field_ = IsParenthesizedField::update(bit_field_, true);
+  }
 
   // Type feedback information for assignments and properties.
   virtual bool IsMonomorphic() {
@@ -367,34 +382,53 @@
     UNREACHABLE();
     return NULL;
   }
-  virtual KeyedAccessStoreMode GetStoreMode() {
+  virtual KeyedAccessStoreMode GetStoreMode() const {
     UNREACHABLE();
     return STANDARD_STORE;
   }
+  virtual IcCheckType GetKeyType() const {
+    UNREACHABLE();
+    return ELEMENT;
+  }
 
   // TODO(rossberg): this should move to its own AST node eventually.
   virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
-  byte to_boolean_types() const { return to_boolean_types_; }
+  byte to_boolean_types() const {
+    return ToBooleanTypesField::decode(bit_field_);
+  }
 
-  BailoutId id() const { return id_; }
-  TypeFeedbackId test_id() const { return test_id_; }
+  void set_base_id(int id) { base_id_ = id; }
+  static int num_ids() { return parent_num_ids() + 2; }
+  BailoutId id() const { return BailoutId(local_id(0)); }
+  TypeFeedbackId test_id() const { return TypeFeedbackId(local_id(1)); }
 
  protected:
-  Expression(Zone* zone, int pos, IdGen* id_gen)
+  Expression(Zone* zone, int pos)
       : AstNode(pos),
+        base_id_(BailoutId::None().ToInt()),
         bounds_(Bounds::Unbounded(zone)),
-        parenthesization_level_(0),
-        id_(id_gen->GetNextId()),
-        test_id_(id_gen->GetNextId()) {}
-  void set_to_boolean_types(byte types) { to_boolean_types_ = types; }
+        bit_field_(0) {}
+  static int parent_num_ids() { return 0; }
+  void set_to_boolean_types(byte types) {
+    bit_field_ = ToBooleanTypesField::update(bit_field_, types);
+  }
+
+  int base_id() const {
+    DCHECK(!BailoutId(base_id_).IsNone());
+    return base_id_;
+  }
 
  private:
-  Bounds bounds_;
-  byte to_boolean_types_;
-  unsigned parenthesization_level_;
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
 
-  const BailoutId id_;
-  const TypeFeedbackId test_id_;
+  int base_id_;
+  Bounds bounds_;
+  class ToBooleanTypesField : public BitField16<byte, 0, 8> {};
+  class IsParenthesizedField : public BitField16<bool, 8, 1> {};
+  class IsMultiParenthesizedField : public BitField16<bool, 9, 1> {};
+  uint16_t bit_field_;
+  // Ends with 16-bit field; deriving classes in turn begin with
+  // 16-bit fields for optimum packing efficiency.
 };
 
 
@@ -410,9 +444,7 @@
   ZoneList<const AstRawString*>* labels() const { return labels_; }
 
   // Type testing & conversion.
-  virtual BreakableStatement* AsBreakableStatement() FINAL OVERRIDE {
-    return this;
-  }
+  BreakableStatement* AsBreakableStatement() FINAL { return this; }
 
   // Code generation
   Label* break_target() { return &break_target_; }
@@ -422,27 +454,34 @@
     return breakable_type_ == TARGET_FOR_ANONYMOUS;
   }
 
-  BailoutId EntryId() const { return entry_id_; }
-  BailoutId ExitId() const { return exit_id_; }
+  void set_base_id(int id) { base_id_ = id; }
+  static int num_ids() { return parent_num_ids() + 2; }
+  BailoutId EntryId() const { return BailoutId(local_id(0)); }
+  BailoutId ExitId() const { return BailoutId(local_id(1)); }
 
  protected:
   BreakableStatement(Zone* zone, ZoneList<const AstRawString*>* labels,
-                     BreakableType breakable_type, int position, IdGen* id_gen)
+                     BreakableType breakable_type, int position)
       : Statement(zone, position),
         labels_(labels),
         breakable_type_(breakable_type),
-        entry_id_(id_gen->GetNextId()),
-        exit_id_(id_gen->GetNextId()) {
+        base_id_(BailoutId::None().ToInt()) {
     DCHECK(labels == NULL || labels->length() > 0);
   }
+  static int parent_num_ids() { return 0; }
 
+  int base_id() const {
+    DCHECK(!BailoutId(base_id_).IsNone());
+    return base_id_;
+  }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   ZoneList<const AstRawString*>* labels_;
   BreakableType breakable_type_;
   Label break_target_;
-  const BailoutId entry_id_;
-  const BailoutId exit_id_;
+  int base_id_;
 };
 
 
@@ -457,9 +496,10 @@
   ZoneList<Statement*>* statements() { return &statements_; }
   bool is_initializer_block() const { return is_initializer_block_; }
 
-  BailoutId DeclsId() const { return decls_id_; }
+  static int num_ids() { return parent_num_ids() + 1; }
+  BailoutId DeclsId() const { return BailoutId(local_id(0)); }
 
-  virtual bool IsJump() const OVERRIDE {
+  bool IsJump() const OVERRIDE {
     return !statements_.is_empty() && statements_.last()->IsJump()
         && labels() == NULL;  // Good enough as an approximation...
   }
@@ -469,17 +509,18 @@
 
  protected:
   Block(Zone* zone, ZoneList<const AstRawString*>* labels, int capacity,
-        bool is_initializer_block, int pos, IdGen* id_gen)
-      : BreakableStatement(zone, labels, TARGET_FOR_NAMED_ONLY, pos, id_gen),
+        bool is_initializer_block, int pos)
+      : BreakableStatement(zone, labels, TARGET_FOR_NAMED_ONLY, pos),
         statements_(capacity, zone),
         is_initializer_block_(is_initializer_block),
-        decls_id_(id_gen->GetNextId()),
         scope_(NULL) {}
+  static int parent_num_ids() { return BreakableStatement::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   ZoneList<Statement*> statements_;
   bool is_initializer_block_;
-  const BailoutId decls_id_;
   Scope* scope_;
 };
 
@@ -493,21 +534,15 @@
   virtual bool IsInlineable() const;
 
  protected:
-  Declaration(Zone* zone,
-              VariableProxy* proxy,
-              VariableMode mode,
-              Scope* scope,
+  Declaration(Zone* zone, VariableProxy* proxy, VariableMode mode, Scope* scope,
               int pos)
-      : AstNode(pos),
-        proxy_(proxy),
-        mode_(mode),
-        scope_(scope) {
+      : AstNode(pos), mode_(mode), proxy_(proxy), scope_(scope) {
     DCHECK(IsDeclaredVariableMode(mode));
   }
 
  private:
-  VariableProxy* proxy_;
   VariableMode mode_;
+  VariableProxy* proxy_;
 
   // Nested scope from which the declaration originated.
   Scope* scope_;
@@ -518,7 +553,7 @@
  public:
   DECLARE_NODE_TYPE(VariableDeclaration)
 
-  virtual InitializationFlag initialization() const OVERRIDE {
+  InitializationFlag initialization() const OVERRIDE {
     return mode() == VAR ? kCreatedInitialized : kNeedsInitialization;
   }
 
@@ -538,10 +573,10 @@
   DECLARE_NODE_TYPE(FunctionDeclaration)
 
   FunctionLiteral* fun() const { return fun_; }
-  virtual InitializationFlag initialization() const OVERRIDE {
+  InitializationFlag initialization() const OVERRIDE {
     return kCreatedInitialized;
   }
-  virtual bool IsInlineable() const OVERRIDE;
+  bool IsInlineable() const OVERRIDE;
 
  protected:
   FunctionDeclaration(Zone* zone,
@@ -567,7 +602,7 @@
   DECLARE_NODE_TYPE(ModuleDeclaration)
 
   Module* module() const { return module_; }
-  virtual InitializationFlag initialization() const OVERRIDE {
+  InitializationFlag initialization() const OVERRIDE {
     return kCreatedInitialized;
   }
 
@@ -591,7 +626,7 @@
   DECLARE_NODE_TYPE(ImportDeclaration)
 
   Module* module() const { return module_; }
-  virtual InitializationFlag initialization() const OVERRIDE {
+  InitializationFlag initialization() const OVERRIDE {
     return kCreatedInitialized;
   }
 
@@ -614,7 +649,7 @@
  public:
   DECLARE_NODE_TYPE(ExportDeclaration)
 
-  virtual InitializationFlag initialization() const OVERRIDE {
+  InitializationFlag initialization() const OVERRIDE {
     return kCreatedInitialized;
   }
 
@@ -725,13 +760,12 @@
 class IterationStatement : public BreakableStatement {
  public:
   // Type testing & conversion.
-  virtual IterationStatement* AsIterationStatement() FINAL OVERRIDE {
-    return this;
-  }
+  IterationStatement* AsIterationStatement() FINAL { return this; }
 
   Statement* body() const { return body_; }
 
-  BailoutId OsrEntryId() const { return osr_entry_id_; }
+  static int num_ids() { return parent_num_ids() + 1; }
+  BailoutId OsrEntryId() const { return BailoutId(local_id(0)); }
   virtual BailoutId ContinueId() const = 0;
   virtual BailoutId StackCheckId() const = 0;
 
@@ -739,21 +773,17 @@
   Label* continue_target()  { return &continue_target_; }
 
  protected:
-  IterationStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
-                     IdGen* id_gen)
-      : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos, id_gen),
-        body_(NULL),
-        osr_entry_id_(id_gen->GetNextId()) {}
-
-  void Initialize(Statement* body) {
-    body_ = body;
-  }
+  IterationStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
+      : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos),
+        body_(NULL) {}
+  static int parent_num_ids() { return BreakableStatement::num_ids(); }
+  void Initialize(Statement* body) { body_ = body; }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   Statement* body_;
   Label continue_target_;
-
-  const BailoutId osr_entry_id_;
 };
 
 
@@ -768,23 +798,20 @@
 
   Expression* cond() const { return cond_; }
 
-  virtual BailoutId ContinueId() const OVERRIDE { return continue_id_; }
-  virtual BailoutId StackCheckId() const OVERRIDE { return back_edge_id_; }
-  BailoutId BackEdgeId() const { return back_edge_id_; }
+  static int num_ids() { return parent_num_ids() + 2; }
+  BailoutId ContinueId() const OVERRIDE { return BailoutId(local_id(0)); }
+  BailoutId StackCheckId() const OVERRIDE { return BackEdgeId(); }
+  BailoutId BackEdgeId() const { return BailoutId(local_id(1)); }
 
  protected:
-  DoWhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
-                   IdGen* id_gen)
-      : IterationStatement(zone, labels, pos, id_gen),
-        cond_(NULL),
-        continue_id_(id_gen->GetNextId()),
-        back_edge_id_(id_gen->GetNextId()) {}
+  DoWhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
+      : IterationStatement(zone, labels, pos), cond_(NULL) {}
+  static int parent_num_ids() { return IterationStatement::num_ids(); }
 
  private:
-  Expression* cond_;
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
 
-  const BailoutId continue_id_;
-  const BailoutId back_edge_id_;
+  Expression* cond_;
 };
 
 
@@ -798,32 +825,21 @@
   }
 
   Expression* cond() const { return cond_; }
-  bool may_have_function_literal() const {
-    return may_have_function_literal_;
-  }
-  void set_may_have_function_literal(bool value) {
-    may_have_function_literal_ = value;
-  }
 
-  virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
-  virtual BailoutId StackCheckId() const OVERRIDE { return body_id_; }
-  BailoutId BodyId() const { return body_id_; }
+  static int num_ids() { return parent_num_ids() + 1; }
+  BailoutId ContinueId() const OVERRIDE { return EntryId(); }
+  BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
+  BailoutId BodyId() const { return BailoutId(local_id(0)); }
 
  protected:
-  WhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
-                 IdGen* id_gen)
-      : IterationStatement(zone, labels, pos, id_gen),
-        cond_(NULL),
-        may_have_function_literal_(true),
-        body_id_(id_gen->GetNextId()) {}
+  WhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
+      : IterationStatement(zone, labels, pos), cond_(NULL) {}
+  static int parent_num_ids() { return IterationStatement::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   Expression* cond_;
-
-  // True if there is a function literal subexpression in the condition.
-  bool may_have_function_literal_;
-
-  const BailoutId body_id_;
 };
 
 
@@ -845,44 +861,25 @@
   Expression* cond() const { return cond_; }
   Statement* next() const { return next_; }
 
-  bool may_have_function_literal() const {
-    return may_have_function_literal_;
-  }
-  void set_may_have_function_literal(bool value) {
-    may_have_function_literal_ = value;
-  }
-
-  virtual BailoutId ContinueId() const OVERRIDE { return continue_id_; }
-  virtual BailoutId StackCheckId() const OVERRIDE { return body_id_; }
-  BailoutId BodyId() const { return body_id_; }
-
-  bool is_fast_smi_loop() { return loop_variable_ != NULL; }
-  Variable* loop_variable() { return loop_variable_; }
-  void set_loop_variable(Variable* var) { loop_variable_ = var; }
+  static int num_ids() { return parent_num_ids() + 2; }
+  BailoutId ContinueId() const OVERRIDE { return BailoutId(local_id(0)); }
+  BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
+  BailoutId BodyId() const { return BailoutId(local_id(1)); }
 
  protected:
-  ForStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
-               IdGen* id_gen)
-      : IterationStatement(zone, labels, pos, id_gen),
+  ForStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
+      : IterationStatement(zone, labels, pos),
         init_(NULL),
         cond_(NULL),
-        next_(NULL),
-        may_have_function_literal_(true),
-        loop_variable_(NULL),
-        continue_id_(id_gen->GetNextId()),
-        body_id_(id_gen->GetNextId()) {}
+        next_(NULL) {}
+  static int parent_num_ids() { return IterationStatement::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   Statement* init_;
   Expression* cond_;
   Statement* next_;
-
-  // True if there is a function literal subexpression in the condition.
-  bool may_have_function_literal_;
-  Variable* loop_variable_;
-
-  const BailoutId continue_id_;
-  const BailoutId body_id_;
 };
 
 
@@ -903,11 +900,8 @@
   Expression* subject() const { return subject_; }
 
  protected:
-  ForEachStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
-                   IdGen* id_gen)
-      : IterationStatement(zone, labels, pos, id_gen),
-        each_(NULL),
-        subject_(NULL) {}
+  ForEachStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
+      : IterationStatement(zone, labels, pos), each_(NULL), subject_(NULL) {}
 
  private:
   Expression* each_;
@@ -915,8 +909,7 @@
 };
 
 
-class ForInStatement FINAL : public ForEachStatement,
-    public FeedbackSlotInterface {
+class ForInStatement FINAL : public ForEachStatement {
  public:
   DECLARE_NODE_TYPE(ForInStatement)
 
@@ -925,11 +918,16 @@
   }
 
   // Type feedback information.
-  virtual int ComputeFeedbackSlotCount() { return 1; }
-  virtual void SetFirstFeedbackSlot(int slot) { for_in_feedback_slot_ = slot; }
+  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
+      Isolate* isolate) OVERRIDE {
+    return FeedbackVectorRequirements(1, 0);
+  }
+  void SetFirstFeedbackSlot(FeedbackVectorSlot slot) OVERRIDE {
+    for_in_feedback_slot_ = slot;
+  }
 
-  int ForInFeedbackSlot() {
-    DCHECK(for_in_feedback_slot_ != kInvalidFeedbackSlot);
+  FeedbackVectorSlot ForInFeedbackSlot() {
+    DCHECK(!for_in_feedback_slot_.IsInvalid());
     return for_in_feedback_slot_;
   }
 
@@ -937,24 +935,26 @@
   ForInType for_in_type() const { return for_in_type_; }
   void set_for_in_type(ForInType type) { for_in_type_ = type; }
 
-  BailoutId BodyId() const { return body_id_; }
-  BailoutId PrepareId() const { return prepare_id_; }
-  virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
-  virtual BailoutId StackCheckId() const OVERRIDE { return body_id_; }
+  static int num_ids() { return parent_num_ids() + 4; }
+  BailoutId BodyId() const { return BailoutId(local_id(0)); }
+  BailoutId PrepareId() const { return BailoutId(local_id(1)); }
+  BailoutId EnumId() const { return BailoutId(local_id(2)); }
+  BailoutId ToObjectId() const { return BailoutId(local_id(3)); }
+  BailoutId ContinueId() const OVERRIDE { return EntryId(); }
+  BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
 
  protected:
-  ForInStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
-                 IdGen* id_gen)
-      : ForEachStatement(zone, labels, pos, id_gen),
+  ForInStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
+      : ForEachStatement(zone, labels, pos),
         for_in_type_(SLOW_FOR_IN),
-        for_in_feedback_slot_(kInvalidFeedbackSlot),
-        body_id_(id_gen->GetNextId()),
-        prepare_id_(id_gen->GetNextId()) {}
+        for_in_feedback_slot_(FeedbackVectorSlot::Invalid()) {}
+  static int parent_num_ids() { return ForEachStatement::num_ids(); }
+
+ private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
 
   ForInType for_in_type_;
-  int for_in_feedback_slot_;
-  const BailoutId body_id_;
-  const BailoutId prepare_id_;
+  FeedbackVectorSlot for_in_feedback_slot_;
 };
 
 
@@ -1000,26 +1000,28 @@
     return assign_each_;
   }
 
-  virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
-  virtual BailoutId StackCheckId() const OVERRIDE { return BackEdgeId(); }
+  BailoutId ContinueId() const OVERRIDE { return EntryId(); }
+  BailoutId StackCheckId() const OVERRIDE { return BackEdgeId(); }
 
-  BailoutId BackEdgeId() const { return back_edge_id_; }
+  static int num_ids() { return parent_num_ids() + 1; }
+  BailoutId BackEdgeId() const { return BailoutId(local_id(0)); }
 
  protected:
-  ForOfStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
-                 IdGen* id_gen)
-      : ForEachStatement(zone, labels, pos, id_gen),
+  ForOfStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
+      : ForEachStatement(zone, labels, pos),
         assign_iterator_(NULL),
         next_result_(NULL),
         result_done_(NULL),
-        assign_each_(NULL),
-        back_edge_id_(id_gen->GetNextId()) {}
+        assign_each_(NULL) {}
+  static int parent_num_ids() { return ForEachStatement::num_ids(); }
+
+ private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
 
   Expression* assign_iterator_;
   Expression* next_result_;
   Expression* result_done_;
   Expression* assign_each_;
-  const BailoutId back_edge_id_;
 };
 
 
@@ -1029,7 +1031,7 @@
 
   void set_expression(Expression* e) { expression_ = e; }
   Expression* expression() const { return expression_; }
-  virtual bool IsJump() const OVERRIDE { return expression_->IsThrow(); }
+  bool IsJump() const OVERRIDE { return expression_->IsThrow(); }
 
  protected:
   ExpressionStatement(Zone* zone, Expression* expression, int pos)
@@ -1042,7 +1044,7 @@
 
 class JumpStatement : public Statement {
  public:
-  virtual bool IsJump() const FINAL OVERRIDE { return true; }
+  bool IsJump() const FINAL { return true; }
 
  protected:
   explicit JumpStatement(Zone* zone, int pos) : Statement(zone, pos) {}
@@ -1130,24 +1132,25 @@
   Label* body_target() { return &body_target_; }
   ZoneList<Statement*>* statements() const { return statements_; }
 
-  BailoutId EntryId() const { return entry_id_; }
+  static int num_ids() { return parent_num_ids() + 2; }
+  BailoutId EntryId() const { return BailoutId(local_id(0)); }
+  TypeFeedbackId CompareId() { return TypeFeedbackId(local_id(1)); }
 
-  // Type feedback information.
-  TypeFeedbackId CompareId() { return compare_id_; }
   Type* compare_type() { return compare_type_; }
   void set_compare_type(Type* type) { compare_type_ = type; }
 
+ protected:
+  static int parent_num_ids() { return Expression::num_ids(); }
+
  private:
   CaseClause(Zone* zone, Expression* label, ZoneList<Statement*>* statements,
-             int pos, IdGen* id_gen);
+             int pos);
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
 
   Expression* label_;
   Label body_target_;
   ZoneList<Statement*>* statements_;
   Type* compare_type_;
-
-  const TypeFeedbackId compare_id_;
-  const BailoutId entry_id_;
 };
 
 
@@ -1164,9 +1167,8 @@
   ZoneList<CaseClause*>* cases() const { return cases_; }
 
  protected:
-  SwitchStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
-                  IdGen* id_gen)
-      : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos, id_gen),
+  SwitchStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
+      : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos),
         tag_(NULL),
         cases_(NULL) {}
 
@@ -1192,33 +1194,39 @@
   Statement* then_statement() const { return then_statement_; }
   Statement* else_statement() const { return else_statement_; }
 
-  virtual bool IsJump() const OVERRIDE {
+  bool IsJump() const OVERRIDE {
     return HasThenStatement() && then_statement()->IsJump()
         && HasElseStatement() && else_statement()->IsJump();
   }
 
-  BailoutId IfId() const { return if_id_; }
-  BailoutId ThenId() const { return then_id_; }
-  BailoutId ElseId() const { return else_id_; }
+  void set_base_id(int id) { base_id_ = id; }
+  static int num_ids() { return parent_num_ids() + 3; }
+  BailoutId IfId() const { return BailoutId(local_id(0)); }
+  BailoutId ThenId() const { return BailoutId(local_id(1)); }
+  BailoutId ElseId() const { return BailoutId(local_id(2)); }
 
  protected:
   IfStatement(Zone* zone, Expression* condition, Statement* then_statement,
-              Statement* else_statement, int pos, IdGen* id_gen)
+              Statement* else_statement, int pos)
       : Statement(zone, pos),
         condition_(condition),
         then_statement_(then_statement),
         else_statement_(else_statement),
-        if_id_(id_gen->GetNextId()),
-        then_id_(id_gen->GetNextId()),
-        else_id_(id_gen->GetNextId()) {}
+        base_id_(BailoutId::None().ToInt()) {}
+  static int parent_num_ids() { return 0; }
+
+  int base_id() const {
+    DCHECK(!BailoutId(base_id_).IsNone());
+    return base_id_;
+  }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   Expression* condition_;
   Statement* then_statement_;
   Statement* else_statement_;
-  const BailoutId if_id_;
-  const BailoutId then_id_;
-  const BailoutId else_id_;
+  int base_id_;
 };
 
 
@@ -1235,9 +1243,9 @@
   void AddTarget(Label* target, Zone* zone);
 
   // Virtual behaviour. TargetCollectors are never part of the AST.
-  virtual void Accept(AstVisitor* v) OVERRIDE { UNREACHABLE(); }
-  virtual NodeType node_type() const OVERRIDE { return kInvalid; }
-  virtual TargetCollector* AsTargetCollector() OVERRIDE { return this; }
+  void Accept(AstVisitor* v) OVERRIDE { UNREACHABLE(); }
+  NodeType node_type() const OVERRIDE { return kInvalid; }
+  TargetCollector* AsTargetCollector() OVERRIDE { return this; }
 
   ZoneList<Label*>* targets() { return &targets_; }
 
@@ -1322,14 +1330,24 @@
  public:
   DECLARE_NODE_TYPE(DebuggerStatement)
 
-  BailoutId DebugBreakId() const { return debugger_id_; }
+  void set_base_id(int id) { base_id_ = id; }
+  static int num_ids() { return parent_num_ids() + 1; }
+  BailoutId DebugBreakId() const { return BailoutId(local_id(0)); }
 
  protected:
-  explicit DebuggerStatement(Zone* zone, int pos, IdGen* id_gen)
-      : Statement(zone, pos), debugger_id_(id_gen->GetNextId()) {}
+  explicit DebuggerStatement(Zone* zone, int pos)
+      : Statement(zone, pos), base_id_(BailoutId::None().ToInt()) {}
+  static int parent_num_ids() { return 0; }
+
+  int base_id() const {
+    DCHECK(!BailoutId(base_id_).IsNone());
+    return base_id_;
+  }
 
  private:
-  const BailoutId debugger_id_;
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
+  int base_id_;
 };
 
 
@@ -1346,9 +1364,7 @@
  public:
   DECLARE_NODE_TYPE(Literal)
 
-  virtual bool IsPropertyName() const OVERRIDE {
-    return value_->IsPropertyName();
-  }
+  bool IsPropertyName() const OVERRIDE { return value_->IsPropertyName(); }
 
   Handle<String> AsPropertyName() {
     DCHECK(IsPropertyName());
@@ -1360,40 +1376,31 @@
     return value_->AsString();
   }
 
-  virtual bool ToBooleanIsTrue() const OVERRIDE {
-    return value()->BooleanValue();
-  }
-  virtual bool ToBooleanIsFalse() const OVERRIDE {
-    return !value()->BooleanValue();
-  }
+  bool ToBooleanIsTrue() const OVERRIDE { return value()->BooleanValue(); }
+  bool ToBooleanIsFalse() const OVERRIDE { return !value()->BooleanValue(); }
 
   Handle<Object> value() const { return value_->value(); }
   const AstValue* raw_value() const { return value_; }
 
   // Support for using Literal as a HashMap key. NOTE: Currently, this works
   // only for string and number literals!
-  uint32_t Hash() { return ToString()->Hash(); }
+  uint32_t Hash();
+  static bool Match(void* literal1, void* literal2);
 
-  static bool Match(void* literal1, void* literal2) {
-    Handle<String> s1 = static_cast<Literal*>(literal1)->ToString();
-    Handle<String> s2 = static_cast<Literal*>(literal2)->ToString();
-    return String::Equals(s1, s2);
+  static int num_ids() { return parent_num_ids() + 1; }
+  TypeFeedbackId LiteralFeedbackId() const {
+    return TypeFeedbackId(local_id(0));
   }
 
-  TypeFeedbackId LiteralFeedbackId() const { return reuse(id()); }
-
  protected:
-  Literal(Zone* zone, const AstValue* value, int position, IdGen* id_gen)
-      : Expression(zone, position, id_gen),
-        value_(value),
-        isolate_(zone->isolate()) {}
+  Literal(Zone* zone, const AstValue* value, int position)
+      : Expression(zone, position), value_(value) {}
+  static int parent_num_ids() { return Expression::num_ids(); }
 
  private:
-  Handle<String> ToString();
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
 
   const AstValue* value_;
-  // TODO(dcarney): remove.  this is only needed for Match and Hash.
-  Isolate* isolate_;
 };
 
 
@@ -1411,8 +1418,8 @@
   }
 
  protected:
-  MaterializedLiteral(Zone* zone, int literal_index, int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen),
+  MaterializedLiteral(Zone* zone, int literal_index, int pos)
+      : Expression(zone, pos),
         literal_index_(literal_index),
         is_simple_(false),
         depth_(0) {}
@@ -1477,8 +1484,10 @@
   void set_emit_store(bool emit_store);
   bool emit_store();
 
+  bool is_static() const { return is_static_; }
+
  protected:
-  template<class> friend class AstNodeFactory;
+  friend class AstNodeFactory;
 
   ObjectLiteralProperty(Zone* zone, bool is_getter, FunctionLiteral* value,
                         bool is_static);
@@ -1535,23 +1544,28 @@
   };
 
   struct Accessors: public ZoneObject {
-    Accessors() : getter(NULL), setter(NULL) { }
+    Accessors() : getter(NULL), setter(NULL) {}
     Expression* getter;
     Expression* setter;
   };
 
+  BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
+
+  static int num_ids() { return parent_num_ids() + 1; }
+
  protected:
   ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index,
-                int boilerplate_properties, bool has_function, int pos,
-                IdGen* id_gen)
-      : MaterializedLiteral(zone, literal_index, pos, id_gen),
+                int boilerplate_properties, bool has_function, int pos)
+      : MaterializedLiteral(zone, literal_index, pos),
         properties_(properties),
         boilerplate_properties_(boilerplate_properties),
         fast_elements_(false),
         may_store_doubles_(false),
         has_function_(has_function) {}
+  static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
   Handle<FixedArray> constant_properties_;
   ZoneList<Property*>* properties_;
   int boilerplate_properties_;
@@ -1571,9 +1585,8 @@
 
  protected:
   RegExpLiteral(Zone* zone, const AstRawString* pattern,
-                const AstRawString* flags, int literal_index, int pos,
-                IdGen* id_gen)
-      : MaterializedLiteral(zone, literal_index, pos, id_gen),
+                const AstRawString* flags, int literal_index, int pos)
+      : MaterializedLiteral(zone, literal_index, pos),
         pattern_(pattern),
         flags_(flags) {
     set_depth(1);
@@ -1594,10 +1607,12 @@
   Handle<FixedArray> constant_elements() const { return constant_elements_; }
   ZoneList<Expression*>* values() const { return values_; }
 
+  // Unlike other AST nodes, this number of bailout IDs allocated for an
+  // ArrayLiteral can vary, so num_ids() is not a static method.
+  int num_ids() const { return parent_num_ids() + values()->length(); }
+
   // Return an AST id for an element that is used in simulate instructions.
-  BailoutId GetIdForElement(int i) {
-    return BailoutId(first_element_id_.ToInt() + i);
-  }
+  BailoutId GetIdForElement(int i) { return BailoutId(local_id(i)); }
 
   // Populate the constant elements fixed array.
   void BuildConstantElements(Isolate* isolate);
@@ -1617,132 +1632,191 @@
 
  protected:
   ArrayLiteral(Zone* zone, ZoneList<Expression*>* values, int literal_index,
-               int pos, IdGen* id_gen)
-      : MaterializedLiteral(zone, literal_index, pos, id_gen),
-        values_(values),
-        first_element_id_(id_gen->ReserveIdRange(values->length())) {}
+               int pos)
+      : MaterializedLiteral(zone, literal_index, pos), values_(values) {}
+  static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   Handle<FixedArray> constant_elements_;
   ZoneList<Expression*>* values_;
-  const BailoutId first_element_id_;
 };
 
 
-class VariableProxy FINAL : public Expression, public FeedbackSlotInterface {
+class VariableProxy FINAL : public Expression {
  public:
   DECLARE_NODE_TYPE(VariableProxy)
 
-  virtual bool IsValidReferenceExpression() const OVERRIDE {
-    return var_ == NULL ? true : var_->IsValidReference();
+  bool IsValidReferenceExpression() const OVERRIDE {
+    return !is_resolved() || var()->IsValidReference();
   }
 
-  bool IsArguments() const { return var_ != NULL && var_->is_arguments(); }
+  bool IsArguments() const { return is_resolved() && var()->is_arguments(); }
 
-  Handle<String> name() const { return name_->string(); }
-  const AstRawString* raw_name() const { return name_; }
-  Variable* var() const { return var_; }
-  bool is_this() const { return is_this_; }
+  Handle<String> name() const { return raw_name()->string(); }
+  const AstRawString* raw_name() const {
+    return is_resolved() ? var_->raw_name() : raw_name_;
+  }
+
+  Variable* var() const {
+    DCHECK(is_resolved());
+    return var_;
+  }
+  void set_var(Variable* v) {
+    DCHECK(!is_resolved());
+    DCHECK_NOT_NULL(v);
+    var_ = v;
+  }
+
+  bool is_this() const { return IsThisField::decode(bit_field_); }
+
+  bool is_assigned() const { return IsAssignedField::decode(bit_field_); }
+  void set_is_assigned() {
+    bit_field_ = IsAssignedField::update(bit_field_, true);
+  }
+
+  bool is_resolved() const { return IsResolvedField::decode(bit_field_); }
+  void set_is_resolved() {
+    bit_field_ = IsResolvedField::update(bit_field_, true);
+  }
+
   Interface* interface() const { return interface_; }
 
-  bool is_assigned() const { return is_assigned_; }
-  void set_is_assigned() { is_assigned_ = true; }
-
   // Bind this proxy to the variable var. Interfaces must match.
   void BindTo(Variable* var);
 
-  virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; }
-  virtual void SetFirstFeedbackSlot(int slot) {
-    variable_feedback_slot_ = slot;
+  bool UsesVariableFeedbackSlot() const {
+    return FLAG_vector_ics && (var()->IsUnallocated() || var()->IsLookupSlot());
   }
 
-  int VariableFeedbackSlot() { return variable_feedback_slot_; }
+  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
+      Isolate* isolate) OVERRIDE {
+    return FeedbackVectorRequirements(0, UsesVariableFeedbackSlot() ? 1 : 0);
+  }
+
+  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
+    variable_feedback_slot_ = slot;
+  }
+  Code::Kind FeedbackICSlotKind(int index) OVERRIDE { return Code::LOAD_IC; }
+  FeedbackVectorICSlot VariableFeedbackSlot() {
+    DCHECK(!UsesVariableFeedbackSlot() || !variable_feedback_slot_.IsInvalid());
+    return variable_feedback_slot_;
+  }
 
  protected:
-  VariableProxy(Zone* zone, Variable* var, int position, IdGen* id_gen);
+  VariableProxy(Zone* zone, Variable* var, int position);
 
   VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
-                Interface* interface, int position, IdGen* id_gen);
+                Interface* interface, int position);
 
-  const AstRawString* name_;
-  Variable* var_;  // resolved variable, or NULL
-  bool is_this_;
-  bool is_assigned_;
+  class IsThisField : public BitField8<bool, 0, 1> {};
+  class IsAssignedField : public BitField8<bool, 1, 1> {};
+  class IsResolvedField : public BitField8<bool, 2, 1> {};
+
+  // Start with 16-bit (or smaller) field, which should get packed together
+  // with Expression's trailing 16-bit field.
+  uint8_t bit_field_;
+  FeedbackVectorICSlot variable_feedback_slot_;
+  union {
+    const AstRawString* raw_name_;  // if !is_resolved_
+    Variable* var_;                 // if is_resolved_
+  };
   Interface* interface_;
-  int variable_feedback_slot_;
 };
 
 
-class Property FINAL : public Expression, public FeedbackSlotInterface {
+class Property FINAL : public Expression {
  public:
   DECLARE_NODE_TYPE(Property)
 
-  virtual bool IsValidReferenceExpression() const OVERRIDE { return true; }
+  bool IsValidReferenceExpression() const OVERRIDE { return true; }
 
   Expression* obj() const { return obj_; }
   Expression* key() const { return key_; }
 
-  BailoutId LoadId() const { return load_id_; }
+  static int num_ids() { return parent_num_ids() + 2; }
+  BailoutId LoadId() const { return BailoutId(local_id(0)); }
+  TypeFeedbackId PropertyFeedbackId() { return TypeFeedbackId(local_id(1)); }
 
-  bool IsStringAccess() const { return is_string_access_; }
+  bool IsStringAccess() const {
+    return IsStringAccessField::decode(bit_field_);
+  }
 
   // Type feedback information.
-  virtual bool IsMonomorphic() OVERRIDE {
-    return receiver_types_.length() == 1;
+  bool IsMonomorphic() OVERRIDE { return receiver_types_.length() == 1; }
+  SmallMapList* GetReceiverTypes() OVERRIDE { return &receiver_types_; }
+  KeyedAccessStoreMode GetStoreMode() const OVERRIDE { return STANDARD_STORE; }
+  IcCheckType GetKeyType() const OVERRIDE {
+    return KeyTypeField::decode(bit_field_);
   }
-  virtual SmallMapList* GetReceiverTypes() OVERRIDE {
-    return &receiver_types_;
+  bool IsUninitialized() const {
+    return !is_for_call() && HasNoTypeInformation();
   }
-  virtual KeyedAccessStoreMode GetStoreMode() OVERRIDE {
-    return STANDARD_STORE;
+  bool HasNoTypeInformation() const {
+    return IsUninitializedField::decode(bit_field_);
   }
-  bool IsUninitialized() { return !is_for_call_ && is_uninitialized_; }
-  bool HasNoTypeInformation() {
-    return is_uninitialized_;
+  void set_is_uninitialized(bool b) {
+    bit_field_ = IsUninitializedField::update(bit_field_, b);
   }
-  void set_is_uninitialized(bool b) { is_uninitialized_ = b; }
-  void set_is_string_access(bool b) { is_string_access_ = b; }
-  void mark_for_call() { is_for_call_ = true; }
-  bool IsForCall() { return is_for_call_; }
+  void set_is_string_access(bool b) {
+    bit_field_ = IsStringAccessField::update(bit_field_, b);
+  }
+  void set_key_type(IcCheckType key_type) {
+    bit_field_ = KeyTypeField::update(bit_field_, key_type);
+  }
+  void mark_for_call() {
+    bit_field_ = IsForCallField::update(bit_field_, true);
+  }
+  bool is_for_call() const { return IsForCallField::decode(bit_field_); }
 
   bool IsSuperAccess() {
     return obj()->IsSuperReference();
   }
 
-  TypeFeedbackId PropertyFeedbackId() { return reuse(id()); }
-
-  virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; }
-  virtual void SetFirstFeedbackSlot(int slot) {
+  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
+      Isolate* isolate) OVERRIDE {
+    return FeedbackVectorRequirements(0, FLAG_vector_ics ? 1 : 0);
+  }
+  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
     property_feedback_slot_ = slot;
   }
+  Code::Kind FeedbackICSlotKind(int index) OVERRIDE {
+    return key()->IsPropertyName() ? Code::LOAD_IC : Code::KEYED_LOAD_IC;
+  }
 
-  int PropertyFeedbackSlot() const { return property_feedback_slot_; }
+  FeedbackVectorICSlot PropertyFeedbackSlot() const {
+    DCHECK(!FLAG_vector_ics || !property_feedback_slot_.IsInvalid());
+    return property_feedback_slot_;
+  }
 
  protected:
-  Property(Zone* zone, Expression* obj, Expression* key, int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen),
+  Property(Zone* zone, Expression* obj, Expression* key, int pos)
+      : Expression(zone, pos),
+        bit_field_(IsForCallField::encode(false) |
+                   IsUninitializedField::encode(false) |
+                   IsStringAccessField::encode(false)),
+        property_feedback_slot_(FeedbackVectorICSlot::Invalid()),
         obj_(obj),
-        key_(key),
-        load_id_(id_gen->GetNextId()),
-        property_feedback_slot_(kInvalidFeedbackSlot),
-        is_for_call_(false),
-        is_uninitialized_(false),
-        is_string_access_(false) {}
+        key_(key) {}
+  static int parent_num_ids() { return Expression::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
+  class IsForCallField : public BitField8<bool, 0, 1> {};
+  class IsUninitializedField : public BitField8<bool, 1, 1> {};
+  class IsStringAccessField : public BitField8<bool, 2, 1> {};
+  class KeyTypeField : public BitField8<IcCheckType, 3, 1> {};
+  uint8_t bit_field_;
+  FeedbackVectorICSlot property_feedback_slot_;
   Expression* obj_;
   Expression* key_;
-  const BailoutId load_id_;
-  int property_feedback_slot_;
-
   SmallMapList receiver_types_;
-  bool is_for_call_ : 1;
-  bool is_uninitialized_ : 1;
-  bool is_string_access_ : 1;
 };
 
 
-class Call FINAL : public Expression, public FeedbackSlotInterface {
+class Call FINAL : public Expression {
  public:
   DECLARE_NODE_TYPE(Call)
 
@@ -1750,24 +1824,27 @@
   ZoneList<Expression*>* arguments() const { return arguments_; }
 
   // Type feedback information.
-  virtual int ComputeFeedbackSlotCount() { return 1; }
-  virtual void SetFirstFeedbackSlot(int slot) {
+  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
+      Isolate* isolate) OVERRIDE;
+  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
     call_feedback_slot_ = slot;
   }
+  Code::Kind FeedbackICSlotKind(int index) OVERRIDE { return Code::CALL_IC; }
 
-  bool HasCallFeedbackSlot() const {
-    return call_feedback_slot_ != kInvalidFeedbackSlot;
+  bool HasCallFeedbackSlot() const { return !call_feedback_slot_.IsInvalid(); }
+  FeedbackVectorICSlot CallFeedbackSlot() const {
+    DCHECK(!call_feedback_slot_.IsInvalid());
+    return call_feedback_slot_;
   }
-  int CallFeedbackSlot() const { return call_feedback_slot_; }
 
-  virtual SmallMapList* GetReceiverTypes() OVERRIDE {
+  SmallMapList* GetReceiverTypes() OVERRIDE {
     if (expression()->IsProperty()) {
       return expression()->AsProperty()->GetReceiverTypes();
     }
     return NULL;
   }
 
-  virtual bool IsMonomorphic() OVERRIDE {
+  bool IsMonomorphic() OVERRIDE {
     if (expression()->IsProperty()) {
       return expression()->AsProperty()->IsMonomorphic();
     }
@@ -1795,13 +1872,23 @@
   }
   bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupIterator* it);
 
-  BailoutId ReturnId() const { return return_id_; }
+  static int num_ids() { return parent_num_ids() + 2; }
+  BailoutId ReturnId() const { return BailoutId(local_id(0)); }
+  BailoutId EvalOrLookupId() const { return BailoutId(local_id(1)); }
+
+  bool is_uninitialized() const {
+    return IsUninitializedField::decode(bit_field_);
+  }
+  void set_is_uninitialized(bool b) {
+    bit_field_ = IsUninitializedField::update(bit_field_, b);
+  }
 
   enum CallType {
     POSSIBLY_EVAL_CALL,
     GLOBAL_CALL,
     LOOKUP_SLOT_CALL,
     PROPERTY_CALL,
+    SUPER_CALL,
     OTHER_CALL
   };
 
@@ -1816,31 +1903,33 @@
 
  protected:
   Call(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
-       int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen),
+       int pos)
+      : Expression(zone, pos),
+        call_feedback_slot_(FeedbackVectorICSlot::Invalid()),
         expression_(expression),
         arguments_(arguments),
-        call_feedback_slot_(kInvalidFeedbackSlot),
-        return_id_(id_gen->GetNextId()) {
+        bit_field_(IsUninitializedField::encode(false)) {
     if (expression->IsProperty()) {
       expression->AsProperty()->mark_for_call();
     }
   }
+  static int parent_num_ids() { return Expression::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
+  FeedbackVectorICSlot call_feedback_slot_;
   Expression* expression_;
   ZoneList<Expression*>* arguments_;
-
   Handle<JSFunction> target_;
   Handle<Cell> cell_;
   Handle<AllocationSite> allocation_site_;
-  int call_feedback_slot_;
-
-  const BailoutId return_id_;
+  class IsUninitializedField : public BitField8<bool, 0, 1> {};
+  uint8_t bit_field_;
 };
 
 
-class CallNew FINAL : public Expression, public FeedbackSlotInterface {
+class CallNew FINAL : public Expression {
  public:
   DECLARE_NODE_TYPE(CallNew)
 
@@ -1848,57 +1937,54 @@
   ZoneList<Expression*>* arguments() const { return arguments_; }
 
   // Type feedback information.
-  virtual int ComputeFeedbackSlotCount() {
-    return FLAG_pretenuring_call_new ? 2 : 1;
+  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
+      Isolate* isolate) OVERRIDE {
+    return FeedbackVectorRequirements(FLAG_pretenuring_call_new ? 2 : 1, 0);
   }
-  virtual void SetFirstFeedbackSlot(int slot) {
+  void SetFirstFeedbackSlot(FeedbackVectorSlot slot) OVERRIDE {
     callnew_feedback_slot_ = slot;
   }
 
-  int CallNewFeedbackSlot() {
-    DCHECK(callnew_feedback_slot_ != kInvalidFeedbackSlot);
+  FeedbackVectorSlot CallNewFeedbackSlot() {
+    DCHECK(!callnew_feedback_slot_.IsInvalid());
     return callnew_feedback_slot_;
   }
-  int AllocationSiteFeedbackSlot() {
-    DCHECK(callnew_feedback_slot_ != kInvalidFeedbackSlot);
+  FeedbackVectorSlot AllocationSiteFeedbackSlot() {
     DCHECK(FLAG_pretenuring_call_new);
-    return callnew_feedback_slot_ + 1;
+    return CallNewFeedbackSlot().next();
   }
 
   void RecordTypeFeedback(TypeFeedbackOracle* oracle);
-  virtual bool IsMonomorphic() OVERRIDE { return is_monomorphic_; }
+  bool IsMonomorphic() OVERRIDE { return is_monomorphic_; }
   Handle<JSFunction> target() const { return target_; }
-  ElementsKind elements_kind() const { return elements_kind_; }
   Handle<AllocationSite> allocation_site() const {
     return allocation_site_;
   }
 
+  static int num_ids() { return parent_num_ids() + 1; }
   static int feedback_slots() { return 1; }
-
-  BailoutId ReturnId() const { return return_id_; }
+  BailoutId ReturnId() const { return BailoutId(local_id(0)); }
 
  protected:
   CallNew(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
-          int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen),
+          int pos)
+      : Expression(zone, pos),
         expression_(expression),
         arguments_(arguments),
         is_monomorphic_(false),
-        elements_kind_(GetInitialFastElementsKind()),
-        callnew_feedback_slot_(kInvalidFeedbackSlot),
-        return_id_(id_gen->GetNextId()) {}
+        callnew_feedback_slot_(FeedbackVectorSlot::Invalid()) {}
+
+  static int parent_num_ids() { return Expression::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   Expression* expression_;
   ZoneList<Expression*>* arguments_;
-
   bool is_monomorphic_;
   Handle<JSFunction> target_;
-  ElementsKind elements_kind_;
   Handle<AllocationSite> allocation_site_;
-  int callnew_feedback_slot_;
-
-  const BailoutId return_id_;
+  FeedbackVectorSlot callnew_feedback_slot_;
 };
 
 
@@ -1906,7 +1992,7 @@
 // language construct. Instead it is used to call a C or JS function
 // with a set of arguments. This is used from the builtins that are
 // implemented in JavaScript (see "v8natives.js").
-class CallRuntime FINAL : public Expression, public FeedbackSlotInterface {
+class CallRuntime FINAL : public Expression {
  public:
   DECLARE_NODE_TYPE(CallRuntime)
 
@@ -1917,35 +2003,47 @@
   bool is_jsruntime() const { return function_ == NULL; }
 
   // Type feedback information.
-  virtual int ComputeFeedbackSlotCount() {
-    return (FLAG_vector_ics && is_jsruntime()) ? 1 : 0;
+  bool HasCallRuntimeFeedbackSlot() const {
+    return FLAG_vector_ics && is_jsruntime();
   }
-  virtual void SetFirstFeedbackSlot(int slot) {
+  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
+      Isolate* isolate) OVERRIDE {
+    return FeedbackVectorRequirements(0, HasCallRuntimeFeedbackSlot() ? 1 : 0);
+  }
+  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
     callruntime_feedback_slot_ = slot;
   }
+  Code::Kind FeedbackICSlotKind(int index) OVERRIDE { return Code::LOAD_IC; }
 
-  int CallRuntimeFeedbackSlot() {
-    DCHECK(!is_jsruntime() ||
-           callruntime_feedback_slot_ != kInvalidFeedbackSlot);
+  FeedbackVectorICSlot CallRuntimeFeedbackSlot() {
+    DCHECK(!HasCallRuntimeFeedbackSlot() ||
+           !callruntime_feedback_slot_.IsInvalid());
     return callruntime_feedback_slot_;
   }
 
-  TypeFeedbackId CallRuntimeFeedbackId() const { return reuse(id()); }
+  static int num_ids() { return parent_num_ids() + 1; }
+  TypeFeedbackId CallRuntimeFeedbackId() const {
+    return TypeFeedbackId(local_id(0));
+  }
 
  protected:
   CallRuntime(Zone* zone, const AstRawString* name,
               const Runtime::Function* function,
-              ZoneList<Expression*>* arguments, int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen),
+              ZoneList<Expression*>* arguments, int pos)
+      : Expression(zone, pos),
         raw_name_(name),
         function_(function),
-        arguments_(arguments) {}
+        arguments_(arguments),
+        callruntime_feedback_slot_(FeedbackVectorICSlot::Invalid()) {}
+  static int parent_num_ids() { return Expression::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   const AstRawString* raw_name_;
   const Runtime::Function* function_;
   ZoneList<Expression*>* arguments_;
-  int callruntime_feedback_slot_;
+  FeedbackVectorICSlot callruntime_feedback_slot_;
 };
 
 
@@ -1956,31 +2054,27 @@
   Token::Value op() const { return op_; }
   Expression* expression() const { return expression_; }
 
-  BailoutId MaterializeTrueId() { return materialize_true_id_; }
-  BailoutId MaterializeFalseId() { return materialize_false_id_; }
+  // For unary not (Token::NOT), the AST ids where true and false will
+  // actually be materialized, respectively.
+  static int num_ids() { return parent_num_ids() + 2; }
+  BailoutId MaterializeTrueId() const { return BailoutId(local_id(0)); }
+  BailoutId MaterializeFalseId() const { return BailoutId(local_id(1)); }
 
   virtual void RecordToBooleanTypeFeedback(
       TypeFeedbackOracle* oracle) OVERRIDE;
 
  protected:
-  UnaryOperation(Zone* zone, Token::Value op, Expression* expression, int pos,
-                 IdGen* id_gen)
-      : Expression(zone, pos, id_gen),
-        op_(op),
-        expression_(expression),
-        materialize_true_id_(id_gen->GetNextId()),
-        materialize_false_id_(id_gen->GetNextId()) {
+  UnaryOperation(Zone* zone, Token::Value op, Expression* expression, int pos)
+      : Expression(zone, pos), op_(op), expression_(expression) {
     DCHECK(Token::IsUnaryOp(op));
   }
+  static int parent_num_ids() { return Expression::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   Token::Value op_;
   Expression* expression_;
-
-  // For unary not (Token::NOT), the AST ids where true and false will
-  // actually be materialized, respectively.
-  const BailoutId materialize_true_id_;
-  const BailoutId materialize_false_id_;
 };
 
 
@@ -1988,9 +2082,9 @@
  public:
   DECLARE_NODE_TYPE(BinaryOperation)
 
-  virtual bool ResultOverwriteAllowed() const OVERRIDE;
+  bool ResultOverwriteAllowed() const OVERRIDE;
 
-  Token::Value op() const { return op_; }
+  Token::Value op() const { return static_cast<Token::Value>(op_); }
   Expression* left() const { return left_; }
   Expression* right() const { return right_; }
   Handle<AllocationSite> allocation_site() const { return allocation_site_; }
@@ -1998,39 +2092,50 @@
     allocation_site_ = allocation_site;
   }
 
-  BailoutId RightId() const { return right_id_; }
+  // The short-circuit logical operations need an AST ID for their
+  // right-hand subexpression.
+  static int num_ids() { return parent_num_ids() + 2; }
+  BailoutId RightId() const { return BailoutId(local_id(0)); }
 
-  TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); }
-  Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
-  void set_fixed_right_arg(Maybe<int> arg) { fixed_right_arg_ = arg; }
+  TypeFeedbackId BinaryOperationFeedbackId() const {
+    return TypeFeedbackId(local_id(1));
+  }
+  Maybe<int> fixed_right_arg() const {
+    return has_fixed_right_arg_ ? Maybe<int>(fixed_right_arg_value_)
+                                : Maybe<int>();
+  }
+  void set_fixed_right_arg(Maybe<int> arg) {
+    has_fixed_right_arg_ = arg.has_value;
+    if (arg.has_value) fixed_right_arg_value_ = arg.value;
+  }
 
   virtual void RecordToBooleanTypeFeedback(
       TypeFeedbackOracle* oracle) OVERRIDE;
 
  protected:
   BinaryOperation(Zone* zone, Token::Value op, Expression* left,
-                  Expression* right, int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen),
-        op_(op),
+                  Expression* right, int pos)
+      : Expression(zone, pos),
+        op_(static_cast<byte>(op)),
+        has_fixed_right_arg_(false),
+        fixed_right_arg_value_(0),
         left_(left),
-        right_(right),
-        right_id_(id_gen->GetNextId()) {
+        right_(right) {
     DCHECK(Token::IsBinaryOp(op));
   }
+  static int parent_num_ids() { return Expression::num_ids(); }
 
  private:
-  Token::Value op_;
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
+  const byte op_;  // actually Token::Value
+  // TODO(rossberg): the fixed arg should probably be represented as a Constant
+  // type for the RHS. Currenty it's actually a Maybe<int>
+  bool has_fixed_right_arg_;
+  int fixed_right_arg_value_;
   Expression* left_;
   Expression* right_;
   Handle<AllocationSite> allocation_site_;
-
-  // TODO(rossberg): the fixed arg should probably be represented as a Constant
-  // type for the RHS.
-  Maybe<int> fixed_right_arg_;
-
-  // The short-circuit logical operations need an AST ID for their
-  // right-hand subexpression.
-  const BailoutId right_id_;
 };
 
 
@@ -2038,55 +2143,67 @@
  public:
   DECLARE_NODE_TYPE(CountOperation)
 
-  bool is_prefix() const { return is_prefix_; }
-  bool is_postfix() const { return !is_prefix_; }
+  bool is_prefix() const { return IsPrefixField::decode(bit_field_); }
+  bool is_postfix() const { return !is_prefix(); }
 
-  Token::Value op() const { return op_; }
+  Token::Value op() const { return TokenField::decode(bit_field_); }
   Token::Value binary_op() {
     return (op() == Token::INC) ? Token::ADD : Token::SUB;
   }
 
   Expression* expression() const { return expression_; }
 
-  virtual bool IsMonomorphic() OVERRIDE {
-    return receiver_types_.length() == 1;
+  bool IsMonomorphic() OVERRIDE { return receiver_types_.length() == 1; }
+  SmallMapList* GetReceiverTypes() OVERRIDE { return &receiver_types_; }
+  IcCheckType GetKeyType() const OVERRIDE {
+    return KeyTypeField::decode(bit_field_);
   }
-  virtual SmallMapList* GetReceiverTypes() OVERRIDE {
-    return &receiver_types_;
-  }
-  virtual KeyedAccessStoreMode GetStoreMode() OVERRIDE {
-    return store_mode_;
+  KeyedAccessStoreMode GetStoreMode() const OVERRIDE {
+    return StoreModeField::decode(bit_field_);
   }
   Type* type() const { return type_; }
-  void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }
+  void set_key_type(IcCheckType type) {
+    bit_field_ = KeyTypeField::update(bit_field_, type);
+  }
+  void set_store_mode(KeyedAccessStoreMode mode) {
+    bit_field_ = StoreModeField::update(bit_field_, mode);
+  }
   void set_type(Type* type) { type_ = type; }
 
-  BailoutId AssignmentId() const { return assignment_id_; }
-
-  TypeFeedbackId CountBinOpFeedbackId() const { return count_id_; }
-  TypeFeedbackId CountStoreFeedbackId() const { return reuse(id()); }
+  static int num_ids() { return parent_num_ids() + 3; }
+  BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
+  TypeFeedbackId CountBinOpFeedbackId() const {
+    return TypeFeedbackId(local_id(1));
+  }
+  TypeFeedbackId CountStoreFeedbackId() const {
+    return TypeFeedbackId(local_id(2));
+  }
 
  protected:
   CountOperation(Zone* zone, Token::Value op, bool is_prefix, Expression* expr,
-                 int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen),
-        op_(op),
-        is_prefix_(is_prefix),
-        store_mode_(STANDARD_STORE),
-        expression_(expr),
-        assignment_id_(id_gen->GetNextId()),
-        count_id_(id_gen->GetNextId()) {}
+                 int pos)
+      : Expression(zone, pos),
+        bit_field_(IsPrefixField::encode(is_prefix) |
+                   KeyTypeField::encode(ELEMENT) |
+                   StoreModeField::encode(STANDARD_STORE) |
+                   TokenField::encode(op)),
+        type_(NULL),
+        expression_(expr) {}
+  static int parent_num_ids() { return Expression::num_ids(); }
 
  private:
-  Token::Value op_;
-  bool is_prefix_ : 1;
-  KeyedAccessStoreMode store_mode_ : 5;  // Windows treats as signed,
-                                         // must have extra bit.
-  Type* type_;
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
 
+  class IsPrefixField : public BitField16<bool, 0, 1> {};
+  class KeyTypeField : public BitField16<IcCheckType, 1, 1> {};
+  class StoreModeField : public BitField16<KeyedAccessStoreMode, 2, 4> {};
+  class TokenField : public BitField16<Token::Value, 6, 8> {};
+
+  // Starts with 16-bit field, which should get packed together with
+  // Expression's trailing 16-bit field.
+  uint16_t bit_field_;
+  Type* type_;
   Expression* expression_;
-  const BailoutId assignment_id_;
-  const TypeFeedbackId count_id_;
   SmallMapList receiver_types_;
 };
 
@@ -2100,7 +2217,10 @@
   Expression* right() const { return right_; }
 
   // Type feedback information.
-  TypeFeedbackId CompareOperationFeedbackId() const { return reuse(id()); }
+  static int num_ids() { return parent_num_ids() + 1; }
+  TypeFeedbackId CompareOperationFeedbackId() const {
+    return TypeFeedbackId(local_id(0));
+  }
   Type* combined_type() const { return combined_type_; }
   void set_combined_type(Type* type) { combined_type_ = type; }
 
@@ -2111,16 +2231,19 @@
 
  protected:
   CompareOperation(Zone* zone, Token::Value op, Expression* left,
-                   Expression* right, int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen),
+                   Expression* right, int pos)
+      : Expression(zone, pos),
         op_(op),
         left_(left),
         right_(right),
         combined_type_(Type::None(zone)) {
     DCHECK(Token::IsCompareOp(op));
   }
+  static int parent_num_ids() { return Expression::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   Token::Value op_;
   Expression* left_;
   Expression* right_;
@@ -2137,25 +2260,25 @@
   Expression* then_expression() const { return then_expression_; }
   Expression* else_expression() const { return else_expression_; }
 
-  BailoutId ThenId() const { return then_id_; }
-  BailoutId ElseId() const { return else_id_; }
+  static int num_ids() { return parent_num_ids() + 2; }
+  BailoutId ThenId() const { return BailoutId(local_id(0)); }
+  BailoutId ElseId() const { return BailoutId(local_id(1)); }
 
  protected:
   Conditional(Zone* zone, Expression* condition, Expression* then_expression,
-              Expression* else_expression, int position, IdGen* id_gen)
-      : Expression(zone, position, id_gen),
+              Expression* else_expression, int position)
+      : Expression(zone, position),
         condition_(condition),
         then_expression_(then_expression),
-        else_expression_(else_expression),
-        then_id_(id_gen->GetNextId()),
-        else_id_(id_gen->GetNextId()) {}
+        else_expression_(else_expression) {}
+  static int parent_num_ids() { return Expression::num_ids(); }
 
  private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   Expression* condition_;
   Expression* then_expression_;
   Expression* else_expression_;
-  const BailoutId then_id_;
-  const BailoutId else_id_;
 };
 
 
@@ -2167,7 +2290,7 @@
 
   Token::Value binary_op() const;
 
-  Token::Value op() const { return op_; }
+  Token::Value op() const { return TokenField::decode(bit_field_); }
   Expression* target() const { return target_; }
   Expression* value() const { return value_; }
   BinaryOperation* binary_operation() const { return binary_operation_; }
@@ -2175,54 +2298,59 @@
   // This check relies on the definition order of token in token.h.
   bool is_compound() const { return op() > Token::ASSIGN; }
 
-  BailoutId AssignmentId() const { return assignment_id_; }
+  static int num_ids() { return parent_num_ids() + 2; }
+  BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
 
   // Type feedback information.
-  TypeFeedbackId AssignmentFeedbackId() { return reuse(id()); }
-  virtual bool IsMonomorphic() OVERRIDE {
-    return receiver_types_.length() == 1;
+  TypeFeedbackId AssignmentFeedbackId() { return TypeFeedbackId(local_id(1)); }
+  bool IsMonomorphic() OVERRIDE { return receiver_types_.length() == 1; }
+  bool IsUninitialized() const {
+    return IsUninitializedField::decode(bit_field_);
   }
-  bool IsUninitialized() { return is_uninitialized_; }
   bool HasNoTypeInformation() {
-    return is_uninitialized_;
+    return IsUninitializedField::decode(bit_field_);
   }
-  virtual SmallMapList* GetReceiverTypes() OVERRIDE {
-    return &receiver_types_;
+  SmallMapList* GetReceiverTypes() OVERRIDE { return &receiver_types_; }
+  IcCheckType GetKeyType() const OVERRIDE {
+    return KeyTypeField::decode(bit_field_);
   }
-  virtual KeyedAccessStoreMode GetStoreMode() OVERRIDE {
-    return store_mode_;
+  KeyedAccessStoreMode GetStoreMode() const OVERRIDE {
+    return StoreModeField::decode(bit_field_);
   }
-  void set_is_uninitialized(bool b) { is_uninitialized_ = b; }
-  void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }
+  void set_is_uninitialized(bool b) {
+    bit_field_ = IsUninitializedField::update(bit_field_, b);
+  }
+  void set_key_type(IcCheckType key_type) {
+    bit_field_ = KeyTypeField::update(bit_field_, key_type);
+  }
+  void set_store_mode(KeyedAccessStoreMode mode) {
+    bit_field_ = StoreModeField::update(bit_field_, mode);
+  }
 
  protected:
   Assignment(Zone* zone, Token::Value op, Expression* target, Expression* value,
-             int pos, IdGen* id_gen);
-
-  template<class Visitor>
-  void Init(Zone* zone, AstNodeFactory<Visitor>* factory) {
-    DCHECK(Token::IsAssignmentOp(op_));
-    if (is_compound()) {
-      binary_operation_ = factory->NewBinaryOperation(
-          binary_op(), target_, value_, position() + 1);
-    }
-  }
+             int pos);
+  static int parent_num_ids() { return Expression::num_ids(); }
 
  private:
-  Token::Value op_;
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
+  class IsUninitializedField : public BitField16<bool, 0, 1> {};
+  class KeyTypeField : public BitField16<IcCheckType, 1, 1> {};
+  class StoreModeField : public BitField16<KeyedAccessStoreMode, 2, 4> {};
+  class TokenField : public BitField16<Token::Value, 6, 8> {};
+
+  // Starts with 16-bit field, which should get packed together with
+  // Expression's trailing 16-bit field.
+  uint16_t bit_field_;
   Expression* target_;
   Expression* value_;
   BinaryOperation* binary_operation_;
-  const BailoutId assignment_id_;
-
-  bool is_uninitialized_ : 1;
-  KeyedAccessStoreMode store_mode_ : 5;  // Windows treats as signed,
-                                         // must have extra bit.
   SmallMapList receiver_types_;
 };
 
 
-class Yield FINAL : public Expression, public FeedbackSlotInterface {
+class Yield FINAL : public Expression {
  public:
   DECLARE_NODE_TYPE(Yield)
 
@@ -2250,44 +2378,47 @@
   }
 
   // Type feedback information.
-  virtual int ComputeFeedbackSlotCount() {
-    return (FLAG_vector_ics && yield_kind() == kDelegating) ? 3 : 0;
+  bool HasFeedbackSlots() const {
+    return FLAG_vector_ics && (yield_kind() == kDelegating);
   }
-  virtual void SetFirstFeedbackSlot(int slot) {
+  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
+      Isolate* isolate) OVERRIDE {
+    return FeedbackVectorRequirements(0, HasFeedbackSlots() ? 3 : 0);
+  }
+  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
     yield_first_feedback_slot_ = slot;
   }
+  Code::Kind FeedbackICSlotKind(int index) OVERRIDE {
+    return index == 0 ? Code::KEYED_LOAD_IC : Code::LOAD_IC;
+  }
 
-  int KeyedLoadFeedbackSlot() {
-    DCHECK(yield_first_feedback_slot_ != kInvalidFeedbackSlot);
+  FeedbackVectorICSlot KeyedLoadFeedbackSlot() {
+    DCHECK(!HasFeedbackSlots() || !yield_first_feedback_slot_.IsInvalid());
     return yield_first_feedback_slot_;
   }
 
-  int DoneFeedbackSlot() {
-    DCHECK(yield_first_feedback_slot_ != kInvalidFeedbackSlot);
-    return yield_first_feedback_slot_ + 1;
+  FeedbackVectorICSlot DoneFeedbackSlot() {
+    return KeyedLoadFeedbackSlot().next();
   }
 
-  int ValueFeedbackSlot() {
-    DCHECK(yield_first_feedback_slot_ != kInvalidFeedbackSlot);
-    return yield_first_feedback_slot_ + 2;
-  }
+  FeedbackVectorICSlot ValueFeedbackSlot() { return DoneFeedbackSlot().next(); }
 
  protected:
   Yield(Zone* zone, Expression* generator_object, Expression* expression,
-        Kind yield_kind, int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen),
+        Kind yield_kind, int pos)
+      : Expression(zone, pos),
         generator_object_(generator_object),
         expression_(expression),
         yield_kind_(yield_kind),
         index_(-1),
-        yield_first_feedback_slot_(kInvalidFeedbackSlot) {}
+        yield_first_feedback_slot_(FeedbackVectorICSlot::Invalid()) {}
 
  private:
   Expression* generator_object_;
   Expression* expression_;
   Kind yield_kind_;
   int index_;
-  int yield_first_feedback_slot_;
+  FeedbackVectorICSlot yield_first_feedback_slot_;
 };
 
 
@@ -2298,8 +2429,8 @@
   Expression* exception() const { return exception_; }
 
  protected:
-  Throw(Zone* zone, Expression* exception, int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen), exception_(exception) {}
+  Throw(Zone* zone, Expression* exception, int pos)
+      : Expression(zone, pos), exception_(exception) {}
 
  private:
   Expression* exception_;
@@ -2349,6 +2480,13 @@
   bool is_expression() const { return IsExpression::decode(bitfield_); }
   bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
   StrictMode strict_mode() const;
+  bool uses_super_property() const;
+  bool uses_super_constructor_call() const;
+
+  static bool NeedsHomeObject(Expression* literal) {
+    return literal != NULL && literal->IsFunctionLiteral() &&
+           literal->AsFunctionLiteral()->uses_super_property();
+  }
 
   int materialized_literal_count() { return materialized_literal_count_; }
   int expected_property_count() { return expected_property_count_; }
@@ -2428,14 +2566,17 @@
   bool is_concise_method() {
     return IsConciseMethod(FunctionKindBits::decode(bitfield_));
   }
+  bool is_default_constructor() {
+    return IsDefaultConstructor(FunctionKindBits::decode(bitfield_));
+  }
 
   int ast_node_count() { return ast_properties_.node_count(); }
   AstProperties::Flags* flags() { return ast_properties_.flags(); }
   void set_ast_properties(AstProperties* ast_properties) {
     ast_properties_ = *ast_properties;
   }
-  int slot_count() {
-    return ast_properties_.feedback_slots();
+  const FeedbackVectorSpec& feedback_vector_spec() const {
+    return ast_properties_.get_spec();
   }
   bool dont_optimize() { return dont_optimize_reason_ != kNoReason; }
   BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }
@@ -2452,8 +2593,8 @@
                   ParameterFlag has_duplicate_parameters,
                   IsFunctionFlag is_function,
                   IsParenthesizedFlag is_parenthesized, FunctionKind kind,
-                  int position, IdGen* id_gen)
-      : Expression(zone, position, id_gen),
+                  int position)
+      : Expression(zone, position),
         raw_name_(name),
         scope_(scope),
         body_(body),
@@ -2498,7 +2639,7 @@
   class HasDuplicateParameters : public BitField<ParameterFlag, 3, 1> {};
   class IsFunction : public BitField<IsFunctionFlag, 4, 1> {};
   class IsParenthesized : public BitField<IsParenthesizedFlag, 5, 1> {};
-  class FunctionKindBits : public BitField<FunctionKind, 6, 3> {};
+  class FunctionKindBits : public BitField<FunctionKind, 6, 4> {};
 };
 
 
@@ -2510,25 +2651,36 @@
 
   Handle<String> name() const { return raw_name_->string(); }
   const AstRawString* raw_name() const { return raw_name_; }
+  Scope* scope() const { return scope_; }
+  VariableProxy* class_variable_proxy() const { return class_variable_proxy_; }
   Expression* extends() const { return extends_; }
   Expression* constructor() const { return constructor_; }
   ZoneList<Property*>* properties() const { return properties_; }
+  int start_position() const { return position(); }
+  int end_position() const { return end_position_; }
 
  protected:
-  ClassLiteral(Zone* zone, const AstRawString* name, Expression* extends,
+  ClassLiteral(Zone* zone, const AstRawString* name, Scope* scope,
+               VariableProxy* class_variable_proxy, Expression* extends,
                Expression* constructor, ZoneList<Property*>* properties,
-               int position, IdGen* id_gen)
-      : Expression(zone, position, id_gen),
+               int start_position, int end_position)
+      : Expression(zone, start_position),
         raw_name_(name),
+        scope_(scope),
+        class_variable_proxy_(class_variable_proxy),
         extends_(extends),
         constructor_(constructor),
-        properties_(properties) {}
+        properties_(properties),
+        end_position_(end_position) {}
 
  private:
   const AstRawString* raw_name_;
+  Scope* scope_;
+  VariableProxy* class_variable_proxy_;
   Expression* extends_;
   Expression* constructor_;
   ZoneList<Property*>* properties_;
+  int end_position_;
 };
 
 
@@ -2541,8 +2693,8 @@
 
  protected:
   NativeFunctionLiteral(Zone* zone, const AstRawString* name,
-                        v8::Extension* extension, int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen), name_(name), extension_(extension) {}
+                        v8::Extension* extension, int pos)
+      : Expression(zone, pos), name_(name), extension_(extension) {}
 
  private:
   const AstRawString* name_;
@@ -2555,8 +2707,7 @@
   DECLARE_NODE_TYPE(ThisFunction)
 
  protected:
-  ThisFunction(Zone* zone, int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen) {}
+  ThisFunction(Zone* zone, int pos) : Expression(zone, pos) {}
 };
 
 
@@ -2566,15 +2717,38 @@
 
   VariableProxy* this_var() const { return this_var_; }
 
-  TypeFeedbackId HomeObjectFeedbackId() { return reuse(id()); }
+  static int num_ids() { return parent_num_ids() + 1; }
+  TypeFeedbackId HomeObjectFeedbackId() { return TypeFeedbackId(local_id(0)); }
 
- protected:
-  SuperReference(Zone* zone, VariableProxy* this_var, int pos, IdGen* id_gen)
-      : Expression(zone, pos, id_gen), this_var_(this_var) {
-    DCHECK(this_var->is_this());
+  // Type feedback information.
+  virtual FeedbackVectorRequirements ComputeFeedbackRequirements(
+      Isolate* isolate) OVERRIDE {
+    return FeedbackVectorRequirements(0, FLAG_vector_ics ? 1 : 0);
+  }
+  void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
+    homeobject_feedback_slot_ = slot;
+  }
+  Code::Kind FeedbackICSlotKind(int index) OVERRIDE { return Code::LOAD_IC; }
+
+  FeedbackVectorICSlot HomeObjectFeedbackSlot() {
+    DCHECK(!FLAG_vector_ics || !homeobject_feedback_slot_.IsInvalid());
+    return homeobject_feedback_slot_;
   }
 
+ protected:
+  SuperReference(Zone* zone, VariableProxy* this_var, int pos)
+      : Expression(zone, pos),
+        this_var_(this_var),
+        homeobject_feedback_slot_(FeedbackVectorICSlot::Invalid()) {
+    DCHECK(this_var->is_this());
+  }
+  static int parent_num_ids() { return Expression::num_ids(); }
+
+ private:
+  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
+
   VariableProxy* this_var_;
+  FeedbackVectorICSlot homeobject_feedback_slot_;
 };
 
 
@@ -2611,7 +2785,7 @@
   // expression.
   virtual Interval CaptureRegisters() { return Interval::Empty(); }
   virtual void AppendToText(RegExpText* text, Zone* zone);
-  OStream& Print(OStream& os, Zone* zone);  // NOLINT
+  std::ostream& Print(std::ostream& os, Zone* zone);  // NOLINT
 #define MAKE_ASTYPE(Name)                                                  \
   virtual RegExp##Name* As##Name();                                        \
   virtual bool Is##Name();
@@ -2623,16 +2797,16 @@
 class RegExpDisjunction FINAL : public RegExpTree {
  public:
   explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
-  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success) OVERRIDE;
-  virtual RegExpDisjunction* AsDisjunction() OVERRIDE;
-  virtual Interval CaptureRegisters() OVERRIDE;
-  virtual bool IsDisjunction() OVERRIDE;
-  virtual bool IsAnchoredAtStart() OVERRIDE;
-  virtual bool IsAnchoredAtEnd() OVERRIDE;
-  virtual int min_match() OVERRIDE { return min_match_; }
-  virtual int max_match() OVERRIDE { return max_match_; }
+  RegExpDisjunction* AsDisjunction() OVERRIDE;
+  Interval CaptureRegisters() OVERRIDE;
+  bool IsDisjunction() OVERRIDE;
+  bool IsAnchoredAtStart() OVERRIDE;
+  bool IsAnchoredAtEnd() OVERRIDE;
+  int min_match() OVERRIDE { return min_match_; }
+  int max_match() OVERRIDE { return max_match_; }
   ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
  private:
   ZoneList<RegExpTree*>* alternatives_;
@@ -2644,16 +2818,16 @@
 class RegExpAlternative FINAL : public RegExpTree {
  public:
   explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
-  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success) OVERRIDE;
-  virtual RegExpAlternative* AsAlternative() OVERRIDE;
-  virtual Interval CaptureRegisters() OVERRIDE;
-  virtual bool IsAlternative() OVERRIDE;
-  virtual bool IsAnchoredAtStart() OVERRIDE;
-  virtual bool IsAnchoredAtEnd() OVERRIDE;
-  virtual int min_match() OVERRIDE { return min_match_; }
-  virtual int max_match() OVERRIDE { return max_match_; }
+  RegExpAlternative* AsAlternative() OVERRIDE;
+  Interval CaptureRegisters() OVERRIDE;
+  bool IsAlternative() OVERRIDE;
+  bool IsAnchoredAtStart() OVERRIDE;
+  bool IsAnchoredAtEnd() OVERRIDE;
+  int min_match() OVERRIDE { return min_match_; }
+  int max_match() OVERRIDE { return max_match_; }
   ZoneList<RegExpTree*>* nodes() { return nodes_; }
  private:
   ZoneList<RegExpTree*>* nodes_;
@@ -2673,15 +2847,15 @@
     NON_BOUNDARY
   };
   explicit RegExpAssertion(AssertionType type) : assertion_type_(type) { }
-  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success) OVERRIDE;
-  virtual RegExpAssertion* AsAssertion() OVERRIDE;
-  virtual bool IsAssertion() OVERRIDE;
-  virtual bool IsAnchoredAtStart() OVERRIDE;
-  virtual bool IsAnchoredAtEnd() OVERRIDE;
-  virtual int min_match() OVERRIDE { return 0; }
-  virtual int max_match() OVERRIDE { return 0; }
+  RegExpAssertion* AsAssertion() OVERRIDE;
+  bool IsAssertion() OVERRIDE;
+  bool IsAnchoredAtStart() OVERRIDE;
+  bool IsAnchoredAtEnd() OVERRIDE;
+  int min_match() OVERRIDE { return 0; }
+  int max_match() OVERRIDE { return 0; }
   AssertionType assertion_type() { return assertion_type_; }
  private:
   AssertionType assertion_type_;
@@ -2719,15 +2893,15 @@
   explicit RegExpCharacterClass(uc16 type)
       : set_(type),
         is_negated_(false) { }
-  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success) OVERRIDE;
-  virtual RegExpCharacterClass* AsCharacterClass() OVERRIDE;
-  virtual bool IsCharacterClass() OVERRIDE;
-  virtual bool IsTextElement() OVERRIDE { return true; }
-  virtual int min_match() OVERRIDE { return 1; }
-  virtual int max_match() OVERRIDE { return 1; }
-  virtual void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
+  RegExpCharacterClass* AsCharacterClass() OVERRIDE;
+  bool IsCharacterClass() OVERRIDE;
+  bool IsTextElement() OVERRIDE { return true; }
+  int min_match() OVERRIDE { return 1; }
+  int max_match() OVERRIDE { return 1; }
+  void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
   CharacterSet character_set() { return set_; }
   // TODO(lrn): Remove need for complex version if is_standard that
   // recognizes a mangled standard set and just do { return set_.is_special(); }
@@ -2756,15 +2930,15 @@
 class RegExpAtom FINAL : public RegExpTree {
  public:
   explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
-  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success) OVERRIDE;
-  virtual RegExpAtom* AsAtom() OVERRIDE;
-  virtual bool IsAtom() OVERRIDE;
-  virtual bool IsTextElement() OVERRIDE { return true; }
-  virtual int min_match() OVERRIDE { return data_.length(); }
-  virtual int max_match() OVERRIDE { return data_.length(); }
-  virtual void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
+  RegExpAtom* AsAtom() OVERRIDE;
+  bool IsAtom() OVERRIDE;
+  bool IsTextElement() OVERRIDE { return true; }
+  int min_match() OVERRIDE { return data_.length(); }
+  int max_match() OVERRIDE { return data_.length(); }
+  void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
   Vector<const uc16> data() { return data_; }
   int length() { return data_.length(); }
  private:
@@ -2775,15 +2949,15 @@
 class RegExpText FINAL : public RegExpTree {
  public:
   explicit RegExpText(Zone* zone) : elements_(2, zone), length_(0) {}
-  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success) OVERRIDE;
-  virtual RegExpText* AsText() OVERRIDE;
-  virtual bool IsText() OVERRIDE;
-  virtual bool IsTextElement() OVERRIDE { return true; }
-  virtual int min_match() OVERRIDE { return length_; }
-  virtual int max_match() OVERRIDE { return length_; }
-  virtual void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
+  RegExpText* AsText() OVERRIDE;
+  bool IsText() OVERRIDE;
+  bool IsTextElement() OVERRIDE { return true; }
+  int min_match() OVERRIDE { return length_; }
+  int max_match() OVERRIDE { return length_; }
+  void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
   void AddElement(TextElement elm, Zone* zone)  {
     elements_.Add(elm, zone);
     length_ += elm.length();
@@ -2810,7 +2984,7 @@
       max_match_ = max * body->max_match();
     }
   }
-  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success) OVERRIDE;
   static RegExpNode* ToNode(int min,
@@ -2820,11 +2994,11 @@
                             RegExpCompiler* compiler,
                             RegExpNode* on_success,
                             bool not_at_start = false);
-  virtual RegExpQuantifier* AsQuantifier() OVERRIDE;
-  virtual Interval CaptureRegisters() OVERRIDE;
-  virtual bool IsQuantifier() OVERRIDE;
-  virtual int min_match() OVERRIDE { return min_match_; }
-  virtual int max_match() OVERRIDE { return max_match_; }
+  RegExpQuantifier* AsQuantifier() OVERRIDE;
+  Interval CaptureRegisters() OVERRIDE;
+  bool IsQuantifier() OVERRIDE;
+  int min_match() OVERRIDE { return min_match_; }
+  int max_match() OVERRIDE { return max_match_; }
   int min() { return min_; }
   int max() { return max_; }
   bool is_possessive() { return quantifier_type_ == POSSESSIVE; }
@@ -2846,20 +3020,20 @@
  public:
   explicit RegExpCapture(RegExpTree* body, int index)
       : body_(body), index_(index) { }
-  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success) OVERRIDE;
   static RegExpNode* ToNode(RegExpTree* body,
                             int index,
                             RegExpCompiler* compiler,
                             RegExpNode* on_success);
-  virtual RegExpCapture* AsCapture() OVERRIDE;
-  virtual bool IsAnchoredAtStart() OVERRIDE;
-  virtual bool IsAnchoredAtEnd() OVERRIDE;
-  virtual Interval CaptureRegisters() OVERRIDE;
-  virtual bool IsCapture() OVERRIDE;
-  virtual int min_match() OVERRIDE { return body_->min_match(); }
-  virtual int max_match() OVERRIDE { return body_->max_match(); }
+  RegExpCapture* AsCapture() OVERRIDE;
+  bool IsAnchoredAtStart() OVERRIDE;
+  bool IsAnchoredAtEnd() OVERRIDE;
+  Interval CaptureRegisters() OVERRIDE;
+  bool IsCapture() OVERRIDE;
+  int min_match() OVERRIDE { return body_->min_match(); }
+  int max_match() OVERRIDE { return body_->max_match(); }
   RegExpTree* body() { return body_; }
   int index() { return index_; }
   static int StartRegister(int index) { return index * 2; }
@@ -2882,15 +3056,15 @@
         capture_count_(capture_count),
         capture_from_(capture_from) { }
 
-  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success) OVERRIDE;
-  virtual RegExpLookahead* AsLookahead() OVERRIDE;
-  virtual Interval CaptureRegisters() OVERRIDE;
-  virtual bool IsLookahead() OVERRIDE;
-  virtual bool IsAnchoredAtStart() OVERRIDE;
-  virtual int min_match() OVERRIDE { return 0; }
-  virtual int max_match() OVERRIDE { return 0; }
+  RegExpLookahead* AsLookahead() OVERRIDE;
+  Interval CaptureRegisters() OVERRIDE;
+  bool IsLookahead() OVERRIDE;
+  bool IsAnchoredAtStart() OVERRIDE;
+  int min_match() OVERRIDE { return 0; }
+  int max_match() OVERRIDE { return 0; }
   RegExpTree* body() { return body_; }
   bool is_positive() { return is_positive_; }
   int capture_count() { return capture_count_; }
@@ -2908,13 +3082,13 @@
  public:
   explicit RegExpBackReference(RegExpCapture* capture)
       : capture_(capture) { }
-  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success) OVERRIDE;
-  virtual RegExpBackReference* AsBackReference() OVERRIDE;
-  virtual bool IsBackReference() OVERRIDE;
-  virtual int min_match() OVERRIDE { return 0; }
-  virtual int max_match() OVERRIDE { return capture_->max_match(); }
+  RegExpBackReference* AsBackReference() OVERRIDE;
+  bool IsBackReference() OVERRIDE;
+  int min_match() OVERRIDE { return 0; }
+  int max_match() OVERRIDE { return capture_->max_match(); }
   int index() { return capture_->index(); }
   RegExpCapture* capture() { return capture_; }
  private:
@@ -2925,17 +3099,13 @@
 class RegExpEmpty FINAL : public RegExpTree {
  public:
   RegExpEmpty() { }
-  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
+  void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
   virtual RegExpNode* ToNode(RegExpCompiler* compiler,
                              RegExpNode* on_success) OVERRIDE;
-  virtual RegExpEmpty* AsEmpty() OVERRIDE;
-  virtual bool IsEmpty() OVERRIDE;
-  virtual int min_match() OVERRIDE { return 0; }
-  virtual int max_match() OVERRIDE { return 0; }
-  static RegExpEmpty* GetInstance() {
-    static RegExpEmpty* instance = ::new RegExpEmpty();
-    return instance;
-  }
+  RegExpEmpty* AsEmpty() OVERRIDE;
+  bool IsEmpty() OVERRIDE;
+  int min_match() OVERRIDE { return 0; }
+  int max_match() OVERRIDE { return 0; }
 };
 
 
@@ -2973,118 +3143,49 @@
 };
 
 
-#define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS()                       \
-public:                                                             \
-  virtual void Visit(AstNode* node) FINAL OVERRIDE {          \
-    if (!CheckStackOverflow()) node->Accept(this);                  \
-  }                                                                 \
-                                                                    \
-  void SetStackOverflow() { stack_overflow_ = true; }               \
-  void ClearStackOverflow() { stack_overflow_ = false; }            \
-  bool HasStackOverflow() const { return stack_overflow_; }         \
-                                                                    \
-  bool CheckStackOverflow() {                                       \
-    if (stack_overflow_) return true;                               \
-    StackLimitCheck check(zone_->isolate());                        \
-    if (!check.HasOverflowed()) return false;                       \
-    return (stack_overflow_ = true);                                \
-  }                                                                 \
-                                                                    \
-private:                                                            \
-  void InitializeAstVisitor(Zone* zone) {                           \
-    zone_ = zone;                                                   \
-    stack_overflow_ = false;                                        \
-  }                                                                 \
-  Zone* zone() { return zone_; }                                    \
-  Isolate* isolate() { return zone_->isolate(); }                   \
-                                                                    \
-  Zone* zone_;                                                      \
+#define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS()               \
+ public:                                                    \
+  void Visit(AstNode* node) FINAL {                         \
+    if (!CheckStackOverflow()) node->Accept(this);          \
+  }                                                         \
+                                                            \
+  void SetStackOverflow() { stack_overflow_ = true; }       \
+  void ClearStackOverflow() { stack_overflow_ = false; }    \
+  bool HasStackOverflow() const { return stack_overflow_; } \
+                                                            \
+  bool CheckStackOverflow() {                               \
+    if (stack_overflow_) return true;                       \
+    StackLimitCheck check(zone_->isolate());                \
+    if (!check.HasOverflowed()) return false;               \
+    return (stack_overflow_ = true);                        \
+  }                                                         \
+                                                            \
+ private:                                                   \
+  void InitializeAstVisitor(Zone* zone) {                   \
+    zone_ = zone;                                           \
+    stack_overflow_ = false;                                \
+  }                                                         \
+  Zone* zone() { return zone_; }                            \
+  Isolate* isolate() { return zone_->isolate(); }           \
+                                                            \
+  Zone* zone_;                                              \
   bool stack_overflow_
 
 
 // ----------------------------------------------------------------------------
-// Construction time visitor.
-
-class AstConstructionVisitor BASE_EMBEDDED {
- public:
-  AstConstructionVisitor()
-      : dont_crankshaft_reason_(kNoReason), dont_turbofan_reason_(kNoReason) {}
-
-  AstProperties* ast_properties() { return &properties_; }
-  BailoutReason dont_optimize_reason() {
-    if (dont_turbofan_reason_ != kNoReason) {
-      return dont_turbofan_reason_;
-    } else {
-      return dont_crankshaft_reason_;
-    }
-  }
-
- private:
-  template<class> friend class AstNodeFactory;
-
-  // Node visitors.
-#define DEF_VISIT(type) \
-  void Visit##type(type* node);
-  AST_NODE_LIST(DEF_VISIT)
-#undef DEF_VISIT
-
-  void increase_node_count() { properties_.add_node_count(1); }
-  void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); }
-  void set_dont_crankshaft_reason(BailoutReason reason) {
-    dont_crankshaft_reason_ = reason;
-  }
-  void set_dont_turbofan_reason(BailoutReason reason) {
-    dont_turbofan_reason_ = reason;
-  }
-
-  void add_slot_node(FeedbackSlotInterface* slot_node) {
-    int count = slot_node->ComputeFeedbackSlotCount();
-    if (count > 0) {
-      slot_node->SetFirstFeedbackSlot(properties_.feedback_slots());
-      properties_.increase_feedback_slots(count);
-    }
-  }
-
-  AstProperties properties_;
-  BailoutReason dont_crankshaft_reason_;
-  BailoutReason dont_turbofan_reason_;
-};
-
-
-class AstNullVisitor BASE_EMBEDDED {
- public:
-  // Node visitors.
-#define DEF_VISIT(type) \
-  void Visit##type(type* node) {}
-  AST_NODE_LIST(DEF_VISIT)
-#undef DEF_VISIT
-};
-
-
-
-// ----------------------------------------------------------------------------
 // AstNode factory
 
-template<class Visitor>
 class AstNodeFactory FINAL BASE_EMBEDDED {
  public:
-  AstNodeFactory(Zone* zone, AstValueFactory* ast_value_factory,
-                 AstNode::IdGen* id_gen)
-      : zone_(zone), ast_value_factory_(ast_value_factory), id_gen_(id_gen) {}
-
-  Visitor* visitor() { return &visitor_; }
-
-#define VISIT_AND_RETURN(NodeType, node) \
-  visitor_.Visit##NodeType((node)); \
-  return node;
+  explicit AstNodeFactory(AstValueFactory* ast_value_factory)
+      : zone_(ast_value_factory->zone()),
+        ast_value_factory_(ast_value_factory) {}
 
   VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
                                               VariableMode mode,
                                               Scope* scope,
                                               int pos) {
-    VariableDeclaration* decl =
-        new(zone_) VariableDeclaration(zone_, proxy, mode, scope, pos);
-    VISIT_AND_RETURN(VariableDeclaration, decl)
+    return new (zone_) VariableDeclaration(zone_, proxy, mode, scope, pos);
   }
 
   FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
@@ -3092,71 +3193,56 @@
                                               FunctionLiteral* fun,
                                               Scope* scope,
                                               int pos) {
-    FunctionDeclaration* decl =
-        new(zone_) FunctionDeclaration(zone_, proxy, mode, fun, scope, pos);
-    VISIT_AND_RETURN(FunctionDeclaration, decl)
+    return new (zone_) FunctionDeclaration(zone_, proxy, mode, fun, scope, pos);
   }
 
   ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy,
                                           Module* module,
                                           Scope* scope,
                                           int pos) {
-    ModuleDeclaration* decl =
-        new(zone_) ModuleDeclaration(zone_, proxy, module, scope, pos);
-    VISIT_AND_RETURN(ModuleDeclaration, decl)
+    return new (zone_) ModuleDeclaration(zone_, proxy, module, scope, pos);
   }
 
   ImportDeclaration* NewImportDeclaration(VariableProxy* proxy,
                                           Module* module,
                                           Scope* scope,
                                           int pos) {
-    ImportDeclaration* decl =
-        new(zone_) ImportDeclaration(zone_, proxy, module, scope, pos);
-    VISIT_AND_RETURN(ImportDeclaration, decl)
+    return new (zone_) ImportDeclaration(zone_, proxy, module, scope, pos);
   }
 
   ExportDeclaration* NewExportDeclaration(VariableProxy* proxy,
                                           Scope* scope,
                                           int pos) {
-    ExportDeclaration* decl =
-        new(zone_) ExportDeclaration(zone_, proxy, scope, pos);
-    VISIT_AND_RETURN(ExportDeclaration, decl)
+    return new (zone_) ExportDeclaration(zone_, proxy, scope, pos);
   }
 
   ModuleLiteral* NewModuleLiteral(Block* body, Interface* interface, int pos) {
-    ModuleLiteral* module =
-        new(zone_) ModuleLiteral(zone_, body, interface, pos);
-    VISIT_AND_RETURN(ModuleLiteral, module)
+    return new (zone_) ModuleLiteral(zone_, body, interface, pos);
   }
 
   ModuleVariable* NewModuleVariable(VariableProxy* proxy, int pos) {
-    ModuleVariable* module = new(zone_) ModuleVariable(zone_, proxy, pos);
-    VISIT_AND_RETURN(ModuleVariable, module)
+    return new (zone_) ModuleVariable(zone_, proxy, pos);
   }
 
   ModulePath* NewModulePath(Module* origin, const AstRawString* name, int pos) {
-    ModulePath* module = new (zone_) ModulePath(zone_, origin, name, pos);
-    VISIT_AND_RETURN(ModulePath, module)
+    return new (zone_) ModulePath(zone_, origin, name, pos);
   }
 
   ModuleUrl* NewModuleUrl(Handle<String> url, int pos) {
-    ModuleUrl* module = new(zone_) ModuleUrl(zone_, url, pos);
-    VISIT_AND_RETURN(ModuleUrl, module)
+    return new (zone_) ModuleUrl(zone_, url, pos);
   }
 
   Block* NewBlock(ZoneList<const AstRawString*>* labels,
                   int capacity,
                   bool is_initializer_block,
                   int pos) {
-    Block* block = new (zone_)
-        Block(zone_, labels, capacity, is_initializer_block, pos, id_gen_);
-    VISIT_AND_RETURN(Block, block)
+    return new (zone_)
+        Block(zone_, labels, capacity, is_initializer_block, pos);
   }
 
 #define STATEMENT_WITH_LABELS(NodeType)                                     \
   NodeType* New##NodeType(ZoneList<const AstRawString*>* labels, int pos) { \
-    NodeType* stmt = new (zone_) NodeType(zone_, labels, pos, id_gen_);     \
-    VISIT_AND_RETURN(NodeType, stmt);                                       \
+    return new (zone_) NodeType(zone_, labels, pos);                        \
   }
   STATEMENT_WITH_LABELS(DoWhileStatement)
   STATEMENT_WITH_LABELS(WhileStatement)
@@ -3169,14 +3255,10 @@
                                         int pos) {
     switch (visit_mode) {
       case ForEachStatement::ENUMERATE: {
-        ForInStatement* stmt =
-            new (zone_) ForInStatement(zone_, labels, pos, id_gen_);
-        VISIT_AND_RETURN(ForInStatement, stmt);
+        return new (zone_) ForInStatement(zone_, labels, pos);
       }
       case ForEachStatement::ITERATE: {
-        ForOfStatement* stmt =
-            new (zone_) ForOfStatement(zone_, labels, pos, id_gen_);
-        VISIT_AND_RETURN(ForOfStatement, stmt);
+        return new (zone_) ForOfStatement(zone_, labels, pos);
       }
     }
     UNREACHABLE();
@@ -3185,47 +3267,38 @@
 
   ModuleStatement* NewModuleStatement(
       VariableProxy* proxy, Block* body, int pos) {
-    ModuleStatement* stmt = new(zone_) ModuleStatement(zone_, proxy, body, pos);
-    VISIT_AND_RETURN(ModuleStatement, stmt)
+    return new (zone_) ModuleStatement(zone_, proxy, body, pos);
   }
 
   ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
-    ExpressionStatement* stmt =
-        new(zone_) ExpressionStatement(zone_, expression, pos);
-    VISIT_AND_RETURN(ExpressionStatement, stmt)
+    return new (zone_) ExpressionStatement(zone_, expression, pos);
   }
 
   ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) {
-    ContinueStatement* stmt = new(zone_) ContinueStatement(zone_, target, pos);
-    VISIT_AND_RETURN(ContinueStatement, stmt)
+    return new (zone_) ContinueStatement(zone_, target, pos);
   }
 
   BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) {
-    BreakStatement* stmt = new(zone_) BreakStatement(zone_, target, pos);
-    VISIT_AND_RETURN(BreakStatement, stmt)
+    return new (zone_) BreakStatement(zone_, target, pos);
   }
 
   ReturnStatement* NewReturnStatement(Expression* expression, int pos) {
-    ReturnStatement* stmt = new(zone_) ReturnStatement(zone_, expression, pos);
-    VISIT_AND_RETURN(ReturnStatement, stmt)
+    return new (zone_) ReturnStatement(zone_, expression, pos);
   }
 
   WithStatement* NewWithStatement(Scope* scope,
                                   Expression* expression,
                                   Statement* statement,
                                   int pos) {
-    WithStatement* stmt = new(zone_) WithStatement(
-        zone_, scope, expression, statement, pos);
-    VISIT_AND_RETURN(WithStatement, stmt)
+    return new (zone_) WithStatement(zone_, scope, expression, statement, pos);
   }
 
   IfStatement* NewIfStatement(Expression* condition,
                               Statement* then_statement,
                               Statement* else_statement,
                               int pos) {
-    IfStatement* stmt = new (zone_) IfStatement(
-        zone_, condition, then_statement, else_statement, pos, id_gen_);
-    VISIT_AND_RETURN(IfStatement, stmt)
+    return new (zone_)
+        IfStatement(zone_, condition, then_statement, else_statement, pos);
   }
 
   TryCatchStatement* NewTryCatchStatement(int index,
@@ -3234,24 +3307,20 @@
                                           Variable* variable,
                                           Block* catch_block,
                                           int pos) {
-    TryCatchStatement* stmt = new(zone_) TryCatchStatement(
-        zone_, index, try_block, scope, variable, catch_block, pos);
-    VISIT_AND_RETURN(TryCatchStatement, stmt)
+    return new (zone_) TryCatchStatement(zone_, index, try_block, scope,
+                                         variable, catch_block, pos);
   }
 
   TryFinallyStatement* NewTryFinallyStatement(int index,
                                               Block* try_block,
                                               Block* finally_block,
                                               int pos) {
-    TryFinallyStatement* stmt = new(zone_) TryFinallyStatement(
-        zone_, index, try_block, finally_block, pos);
-    VISIT_AND_RETURN(TryFinallyStatement, stmt)
+    return new (zone_)
+        TryFinallyStatement(zone_, index, try_block, finally_block, pos);
   }
 
   DebuggerStatement* NewDebuggerStatement(int pos) {
-    DebuggerStatement* stmt =
-        new (zone_) DebuggerStatement(zone_, pos, id_gen_);
-    VISIT_AND_RETURN(DebuggerStatement, stmt)
+    return new (zone_) DebuggerStatement(zone_, pos);
   }
 
   EmptyStatement* NewEmptyStatement(int pos) {
@@ -3260,65 +3329,42 @@
 
   CaseClause* NewCaseClause(
       Expression* label, ZoneList<Statement*>* statements, int pos) {
-    CaseClause* clause =
-        new (zone_) CaseClause(zone_, label, statements, pos, id_gen_);
-    VISIT_AND_RETURN(CaseClause, clause)
+    return new (zone_) CaseClause(zone_, label, statements, pos);
   }
 
   Literal* NewStringLiteral(const AstRawString* string, int pos) {
-    Literal* lit = new (zone_)
-        Literal(zone_, ast_value_factory_->NewString(string), pos, id_gen_);
-    VISIT_AND_RETURN(Literal, lit)
+    return new (zone_)
+        Literal(zone_, ast_value_factory_->NewString(string), pos);
   }
 
   // A JavaScript symbol (ECMA-262 edition 6).
   Literal* NewSymbolLiteral(const char* name, int pos) {
-    Literal* lit = new (zone_)
-        Literal(zone_, ast_value_factory_->NewSymbol(name), pos, id_gen_);
-    VISIT_AND_RETURN(Literal, lit)
+    return new (zone_) Literal(zone_, ast_value_factory_->NewSymbol(name), pos);
   }
 
   Literal* NewNumberLiteral(double number, int pos) {
-    Literal* lit = new (zone_)
-        Literal(zone_, ast_value_factory_->NewNumber(number), pos, id_gen_);
-    VISIT_AND_RETURN(Literal, lit)
+    return new (zone_)
+        Literal(zone_, ast_value_factory_->NewNumber(number), pos);
   }
 
   Literal* NewSmiLiteral(int number, int pos) {
-    Literal* lit = new (zone_)
-        Literal(zone_, ast_value_factory_->NewSmi(number), pos, id_gen_);
-    VISIT_AND_RETURN(Literal, lit)
+    return new (zone_) Literal(zone_, ast_value_factory_->NewSmi(number), pos);
   }
 
   Literal* NewBooleanLiteral(bool b, int pos) {
-    Literal* lit = new (zone_)
-        Literal(zone_, ast_value_factory_->NewBoolean(b), pos, id_gen_);
-    VISIT_AND_RETURN(Literal, lit)
-  }
-
-  Literal* NewStringListLiteral(ZoneList<const AstRawString*>* strings,
-                                int pos) {
-    Literal* lit = new (zone_) Literal(
-        zone_, ast_value_factory_->NewStringList(strings), pos, id_gen_);
-    VISIT_AND_RETURN(Literal, lit)
+    return new (zone_) Literal(zone_, ast_value_factory_->NewBoolean(b), pos);
   }
 
   Literal* NewNullLiteral(int pos) {
-    Literal* lit =
-        new (zone_) Literal(zone_, ast_value_factory_->NewNull(), pos, id_gen_);
-    VISIT_AND_RETURN(Literal, lit)
+    return new (zone_) Literal(zone_, ast_value_factory_->NewNull(), pos);
   }
 
   Literal* NewUndefinedLiteral(int pos) {
-    Literal* lit = new (zone_)
-        Literal(zone_, ast_value_factory_->NewUndefined(), pos, id_gen_);
-    VISIT_AND_RETURN(Literal, lit)
+    return new (zone_) Literal(zone_, ast_value_factory_->NewUndefined(), pos);
   }
 
   Literal* NewTheHoleLiteral(int pos) {
-    Literal* lit = new (zone_)
-        Literal(zone_, ast_value_factory_->NewTheHole(), pos, id_gen_);
-    VISIT_AND_RETURN(Literal, lit)
+    return new (zone_) Literal(zone_, ast_value_factory_->NewTheHole(), pos);
   }
 
   ObjectLiteral* NewObjectLiteral(
@@ -3327,10 +3373,8 @@
       int boilerplate_properties,
       bool has_function,
       int pos) {
-    ObjectLiteral* lit = new (zone_)
-        ObjectLiteral(zone_, properties, literal_index, boilerplate_properties,
-                      has_function, pos, id_gen_);
-    VISIT_AND_RETURN(ObjectLiteral, lit)
+    return new (zone_) ObjectLiteral(zone_, properties, literal_index,
+                                     boilerplate_properties, has_function, pos);
   }
 
   ObjectLiteral::Property* NewObjectLiteralProperty(Literal* key,
@@ -3346,122 +3390,104 @@
     ObjectLiteral::Property* prop =
         new (zone_) ObjectLiteral::Property(zone_, is_getter, value, is_static);
     prop->set_key(NewStringLiteral(value->raw_name(), pos));
-    return prop;  // Not an AST node, will not be visited.
+    return prop;
   }
 
   RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern,
                                   const AstRawString* flags,
                                   int literal_index,
                                   int pos) {
-    RegExpLiteral* lit = new (zone_)
-        RegExpLiteral(zone_, pattern, flags, literal_index, pos, id_gen_);
-    VISIT_AND_RETURN(RegExpLiteral, lit);
+    return new (zone_) RegExpLiteral(zone_, pattern, flags, literal_index, pos);
   }
 
   ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
                                 int literal_index,
                                 int pos) {
-    ArrayLiteral* lit =
-        new (zone_) ArrayLiteral(zone_, values, literal_index, pos, id_gen_);
-    VISIT_AND_RETURN(ArrayLiteral, lit)
+    return new (zone_) ArrayLiteral(zone_, values, literal_index, pos);
   }
 
   VariableProxy* NewVariableProxy(Variable* var,
                                   int pos = RelocInfo::kNoPosition) {
-    VariableProxy* proxy = new (zone_) VariableProxy(zone_, var, pos, id_gen_);
-    VISIT_AND_RETURN(VariableProxy, proxy)
+    return new (zone_) VariableProxy(zone_, var, pos);
   }
 
   VariableProxy* NewVariableProxy(const AstRawString* name,
                                   bool is_this,
                                   Interface* interface = Interface::NewValue(),
                                   int position = RelocInfo::kNoPosition) {
-    VariableProxy* proxy = new (zone_)
-        VariableProxy(zone_, name, is_this, interface, position, id_gen_);
-    VISIT_AND_RETURN(VariableProxy, proxy)
+    return new (zone_) VariableProxy(zone_, name, is_this, interface, position);
   }
 
   Property* NewProperty(Expression* obj, Expression* key, int pos) {
-    Property* prop = new (zone_) Property(zone_, obj, key, pos, id_gen_);
-    VISIT_AND_RETURN(Property, prop)
+    return new (zone_) Property(zone_, obj, key, pos);
   }
 
   Call* NewCall(Expression* expression,
                 ZoneList<Expression*>* arguments,
                 int pos) {
-    Call* call = new (zone_) Call(zone_, expression, arguments, pos, id_gen_);
-    VISIT_AND_RETURN(Call, call)
+    return new (zone_) Call(zone_, expression, arguments, pos);
   }
 
   CallNew* NewCallNew(Expression* expression,
                       ZoneList<Expression*>* arguments,
                       int pos) {
-    CallNew* call =
-        new (zone_) CallNew(zone_, expression, arguments, pos, id_gen_);
-    VISIT_AND_RETURN(CallNew, call)
+    return new (zone_) CallNew(zone_, expression, arguments, pos);
   }
 
   CallRuntime* NewCallRuntime(const AstRawString* name,
                               const Runtime::Function* function,
                               ZoneList<Expression*>* arguments,
                               int pos) {
-    CallRuntime* call =
-        new (zone_) CallRuntime(zone_, name, function, arguments, pos, id_gen_);
-    VISIT_AND_RETURN(CallRuntime, call)
+    return new (zone_) CallRuntime(zone_, name, function, arguments, pos);
   }
 
   UnaryOperation* NewUnaryOperation(Token::Value op,
                                     Expression* expression,
                                     int pos) {
-    UnaryOperation* node =
-        new (zone_) UnaryOperation(zone_, op, expression, pos, id_gen_);
-    VISIT_AND_RETURN(UnaryOperation, node)
+    return new (zone_) UnaryOperation(zone_, op, expression, pos);
   }
 
   BinaryOperation* NewBinaryOperation(Token::Value op,
                                       Expression* left,
                                       Expression* right,
                                       int pos) {
-    BinaryOperation* node =
-        new (zone_) BinaryOperation(zone_, op, left, right, pos, id_gen_);
-    VISIT_AND_RETURN(BinaryOperation, node)
+    return new (zone_) BinaryOperation(zone_, op, left, right, pos);
   }
 
   CountOperation* NewCountOperation(Token::Value op,
                                     bool is_prefix,
                                     Expression* expr,
                                     int pos) {
-    CountOperation* node =
-        new (zone_) CountOperation(zone_, op, is_prefix, expr, pos, id_gen_);
-    VISIT_AND_RETURN(CountOperation, node)
+    return new (zone_) CountOperation(zone_, op, is_prefix, expr, pos);
   }
 
   CompareOperation* NewCompareOperation(Token::Value op,
                                         Expression* left,
                                         Expression* right,
                                         int pos) {
-    CompareOperation* node =
-        new (zone_) CompareOperation(zone_, op, left, right, pos, id_gen_);
-    VISIT_AND_RETURN(CompareOperation, node)
+    return new (zone_) CompareOperation(zone_, op, left, right, pos);
   }
 
   Conditional* NewConditional(Expression* condition,
                               Expression* then_expression,
                               Expression* else_expression,
                               int position) {
-    Conditional* cond = new (zone_) Conditional(
-        zone_, condition, then_expression, else_expression, position, id_gen_);
-    VISIT_AND_RETURN(Conditional, cond)
+    return new (zone_) Conditional(zone_, condition, then_expression,
+                                   else_expression, position);
   }
 
   Assignment* NewAssignment(Token::Value op,
                             Expression* target,
                             Expression* value,
                             int pos) {
-    Assignment* assign =
-        new (zone_) Assignment(zone_, op, target, value, pos, id_gen_);
-    assign->Init(zone_, this);
-    VISIT_AND_RETURN(Assignment, assign)
+    DCHECK(Token::IsAssignmentOp(op));
+    Assignment* assign = new (zone_) Assignment(zone_, op, target, value, pos);
+    if (assign->is_compound()) {
+      DCHECK(Token::IsAssignmentOp(op));
+      assign->binary_operation_ =
+          NewBinaryOperation(assign->binary_op(), target, value, pos + 1);
+    }
+    return assign;
   }
 
   Yield* NewYield(Expression *generator_object,
@@ -3469,14 +3495,12 @@
                   Yield::Kind yield_kind,
                   int pos) {
     if (!expression) expression = NewUndefinedLiteral(pos);
-    Yield* yield = new (zone_)
-        Yield(zone_, generator_object, expression, yield_kind, pos, id_gen_);
-    VISIT_AND_RETURN(Yield, yield)
+    return new (zone_)
+        Yield(zone_, generator_object, expression, yield_kind, pos);
   }
 
   Throw* NewThrow(Expression* exception, int pos) {
-    Throw* t = new (zone_) Throw(zone_, exception, pos, id_gen_);
-    VISIT_AND_RETURN(Throw, t)
+    return new (zone_) Throw(zone_, exception, pos);
   }
 
   FunctionLiteral* NewFunctionLiteral(
@@ -3488,53 +3512,40 @@
       FunctionLiteral::IsFunctionFlag is_function,
       FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind,
       int position) {
-    FunctionLiteral* lit = new (zone_) FunctionLiteral(
+    return new (zone_) FunctionLiteral(
         zone_, name, ast_value_factory, scope, body, materialized_literal_count,
         expected_property_count, handler_count, parameter_count, function_type,
-        has_duplicate_parameters, is_function, is_parenthesized, kind, position,
-        id_gen_);
-    // Top-level literal doesn't count for the AST's properties.
-    if (is_function == FunctionLiteral::kIsFunction) {
-      visitor_.VisitFunctionLiteral(lit);
-    }
-    return lit;
+        has_duplicate_parameters, is_function, is_parenthesized, kind,
+        position);
   }
 
-  ClassLiteral* NewClassLiteral(const AstRawString* name, Expression* extends,
+  ClassLiteral* NewClassLiteral(const AstRawString* name, Scope* scope,
+                                VariableProxy* proxy, Expression* extends,
                                 Expression* constructor,
                                 ZoneList<ObjectLiteral::Property*>* properties,
-                                int position) {
-    ClassLiteral* lit = new (zone_) ClassLiteral(
-        zone_, name, extends, constructor, properties, position, id_gen_);
-    VISIT_AND_RETURN(ClassLiteral, lit)
+                                int start_position, int end_position) {
+    return new (zone_)
+        ClassLiteral(zone_, name, scope, proxy, extends, constructor,
+                     properties, start_position, end_position);
   }
 
   NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
                                                   v8::Extension* extension,
                                                   int pos) {
-    NativeFunctionLiteral* lit =
-        new (zone_) NativeFunctionLiteral(zone_, name, extension, pos, id_gen_);
-    VISIT_AND_RETURN(NativeFunctionLiteral, lit)
+    return new (zone_) NativeFunctionLiteral(zone_, name, extension, pos);
   }
 
   ThisFunction* NewThisFunction(int pos) {
-    ThisFunction* fun = new (zone_) ThisFunction(zone_, pos, id_gen_);
-    VISIT_AND_RETURN(ThisFunction, fun)
+    return new (zone_) ThisFunction(zone_, pos);
   }
 
   SuperReference* NewSuperReference(VariableProxy* this_var, int pos) {
-    SuperReference* super =
-        new (zone_) SuperReference(zone_, this_var, pos, id_gen_);
-    VISIT_AND_RETURN(SuperReference, super);
+    return new (zone_) SuperReference(zone_, this_var, pos);
   }
 
-#undef VISIT_AND_RETURN
-
  private:
   Zone* zone_;
-  Visitor visitor_;
   AstValueFactory* ast_value_factory_;
-  AstNode::IdGen* id_gen_;
 };
 
 
diff --git "a/src/base/\043functional.h\043" "b/src/base/\043functional.h\043"
new file mode 100644
index 0000000..ff0d807
--- /dev/null
+++ "b/src/base/\043functional.h\043"
@@ -0,0 +1,227 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_BASE_FUNCTIONAL_H_
+#define V8_BASE_FUNCTIONAL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <cstddef>
+#include <cstring>
+#include <functional>
+#include <utility>
+
+#include "src/base/macros.h"
+
+namespace v8 {
+namespace base {
+
+// base::hash is an implementation of the hash function object specified by
+// C++11. It was designed to be compatible with std::hash (in C++11) and
+// boost:hash (which in turn is based on the hash function object specified by
+// the Draft Technical Report on C++ Library Extensions (TR1)).
+//
+// base::hash is implemented by calling the hash_value function. The namespace
+// isn't specified so that it can detect overloads via argument dependant
+// lookup. So if there is a free function hash_value in the same namespace as a
+// custom type, it will get called.
+//
+// If users are asked to implement a hash function for their own types with no
+// guidance, they generally write bad hash functions. Instead, we provide  a
+// simple function base::hash_combine to pass hash-relevant member variables
+// into, in order to define a decent hash function. base::hash_combine is
+// declared as:
+//
+//   template<typename T, typename... Ts>
+//   size_t hash_combine(const T& v, const Ts& ...vs);
+//
+// Consider the following example:
+//
+//   namespace v8 {
+//   namespace bar {
+//     struct Point { int x; int y; };
+//     size_t hash_value(Point const& p) {
+//       return base::hash_combine(p.x, p.y);
+//     }
+//   }
+//
+//   namespace foo {
+//     void DoSomeWork(bar::Point const& p) {
+//       base::hash<bar::Point> h;
+//       ...
+//       size_t hash_code = h(p);  // calls bar::hash_value(Point const&)
+//       ...
+//     }
+//   }
+//   }
+//
+// Based on the "Hashing User-Defined Types in C++1y" proposal from Jeffrey
+// Yasskin and Chandler Carruth, see
+// http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2012/n3333.html.
+
+template <typename>
+struct hash;
+
+
+V8_INLINE size_t hash_combine() { return 0u; }
+V8_INLINE size_t hash_combine(size_t seed) { return seed; }
+size_t hash_combine(size_t seed, size_t value);
+template <typename T, typename... Ts>
+V8_INLINE size_t hash_combine(T const& v, Ts const&... vs) {
+  return hash_combine(hash_combine(vs...), hash<T>()(v));
+}
+
+
+template <typename Iterator>
+V8_INLINE size_t hash_range(Iterator first, Iterator last) {
+  size_t seed = 0;
+  for (; first != last; ++first) {
+    seed = hash_combine(seed, *first);
+  }
+  return seed;
+}
+
+
+#define V8_BASE_HASH_VALUE_TRIVIAL(type) \
+  V8_INLINE size_t hash_value(type v) { return static_cast<size_t>(v); }
+V8_BASE_HASH_VALUE_TRIVIAL(bool)
+V8_BASE_HASH_VALUE_TRIVIAL(unsigned char)
+V8_BASE_HASH_VALUE_TRIVIAL(unsigned short)  // NOLINT(runtime/int)
+#undef V8_BASE_HASH_VALUE_TRIVIAL
+
+size_t hash_value(unsigned int);
+size_t hash_value(unsigned long);       // NOLINT(runtime/int)
+size_t hash_value(unsigned long long);  // NOLINT(runtime/int)
+
+#define V8_BASE_HASH_VALUE_SIGNED(type)            \
+  V8_INLINE size_t hash_value(signed type v) {     \
+    return hash_value(bit_cast<unsigned type>(v)); \
+  }
+V8_BASE_HASH_VALUE_SIGNED(char)
+V8_BASE_HASH_VALUE_SIGNED(short)      // NOLINT(runtime/int)
+V8_BASE_HASH_VALUE_SIGNED(int)        // NOLINT(runtime/int)
+V8_BASE_HASH_VALUE_SIGNED(long)       // NOLINT(runtime/int)
+V8_BASE_HASH_VALUE_SIGNED(long long)  // NOLINT(runtime/int)
+#undef V8_BASE_HASH_VALUE_SIGNED
+
+V8_INLINE size_t hash_value(float v) {
+  // 0 and -0 both hash to zero.
+  return v != 0.0f ? hash_value(bit_cast<uint32_t>(v)) : 0;
+}
+
+V8_INLINE size_t hash_value(double v) {
+  // 0 and -0 both hash to zero.
+  return v != 0.0 ? hash_value(bit_cast<uint64_t>(v)) : 0;
+}
+
+template <typename T, size_t N>
+V8_INLINE size_t hash_value(const T (&v)[N]) {
+  return hash_range(v, v + N);
+}
+
+template <typename T, size_t N>
+V8_INLINE size_t hash_value(T (&v)[N]) {
+  return hash_range(v, v + N);
+}
+
+template <typename T>
+V8_INLINE size_t hash_value(T* const& v) {
+  return hash_value(bit_cast<uintptr_t>(v));
+}
+
+template <typename T1, typename T2>
+V8_INLINE size_t hash_value(std::pair<T1, T2> const& v) {
+  return hash_combine(v.first, v.second);
+}
+
+
+template <typename T>
+struct hash : public std::unary_function<T, size_t> {
+  V8_INLINE size_t operator()(T const& v) const { return hash_value(v); }
+};
+
+#define V8_BASE_HASH_SPECIALIZE(type)                            \
+  template <>                                                    \
+  struct hash<type> : public std::unary_function<type, size_t> { \
+    V8_INLINE size_t operator()(type const v) const {            \
+      return ::v8::base::hash_value(v);                          \
+    }                                                            \
+  };
+V8_BASE_HASH_SPECIALIZE(bool)
+V8_BASE_HASH_SPECIALIZE(signed char)
+V8_BASE_HASH_SPECIALIZE(unsigned char)
+V8_BASE_HASH_SPECIALIZE(short)           // NOLINT(runtime/int)
+V8_BASE_HASH_SPECIALIZE(unsigned short)  // NOLINT(runtime/int)
+V8_BASE_HASH_SPECIALIZE(int)
+V8_BASE_HASH_SPECIALIZE(unsigned int)
+V8_BASE_HASH_SPECIALIZE(long)                // NOLINT(runtime/int)
+V8_BASE_HASH_SPECIALIZE(unsigned long)       // NOLINT(runtime/int)
+V8_BASE_HASH_SPECIALIZE(long long)           // NOLINT(runtime/int)
+V8_BASE_HASH_SPECIALIZE(unsigned long long)  // NOLINT(runtime/int)
+V8_BASE_HASH_SPECIALIZE(float)
+V8_BASE_HASH_SPECIALIZE(double)
+#undef V8_BASE_HASH_SPECIALIZE
+
+template <typename T>
+struct hash<T*> : public std::unary_function<T*, size_t> {
+  V8_INLINE size_t operator()(T* const v) const {
+    return ::v8::base::hash_value(v);
+  }
+};
+
+
+// base::bit_equal_to is a function object class for bitwise equality
+// comparison, similar to std::equal_to, except that the comparison is performed
+// on the bit representation of the operands.
+//
+// base::bit_hash is a function object class for bitwise hashing, similar to
+// base::hash. It can be used together with base::bit_equal_to to implement a
+// hash data structure based on the bitwise representation of types.
+
+template <typename T>
+struct bit_equal_to : public std::binary_function<T, T, bool> {};
+
+template <typename T>
+struct bit_hash : public std::unary_function<T, size_t> {};
+
+#define V8_BASE_BIT_SPECIALIZE_TRIVIAL(type)                 \
+  template <>                                                \
+  struct bit_equal_to<type> : public std::equal_to<type> {}; \
+  template <>                                                \
+  struct bit_hash<type> : public hash<type> {};
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(signed char)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned char)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(short)           // NOLINT(runtime/int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned short)  // NOLINT(runtime/int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(long)                // NOLINT(runtime/int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned long)       // NOLINT(runtime/int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(long long)           // NOLINT(runtime/int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned long long)  // NOLINT(runtime/int)
+#undef V8_BASE_BIT_SPECIALIZE_TRIVIAL
+
+#define V8_BASE_BIT_SPECIALIZE_BIT_CAST(type, btype)                          \
+  template <>                                                                 \
+  struct bit_equal_to<type> : public std::binary_function<type, type, bool> { \
+    V8_INLINE bool operator()(type lhs, type rhs) const {                     \
+      return bit_cast<btype>(lhs) == bit_cast<btype>(rhs);                    \
+    }                                                                         \
+  };                                                                          \
+  template <>                                                                 \
+  struct bit_hash<type> : public std::unary_function<type, size_t> {          \
+    V8_INLINE size_t operator()(type v) const {                               \
+      hash<btype> h;                                                          \
+      return h(bit_cast<btype>(v));                                           \
+    }                                                                         \
+  };
+V8_BASE_BIT_SPECIALIZE_BIT_CAST(float, uint32_t)
+V8_BASE_BIT_SPECIALIZE_BIT_CAST(double, uint64_t)
+#undef V8_BASE_BIT_SPECIALIZE_BIT_CAST
+
+}  // namespace base
+}  // namespace v8
+
+#endif  // V8_BASE_FUNCTIONAL_H_
diff --git a/src/base/atomicops.h b/src/base/atomicops.h
index eba172f..675e43f 100644
--- a/src/base/atomicops.h
+++ b/src/base/atomicops.h
@@ -25,7 +25,7 @@
 #ifndef V8_BASE_ATOMICOPS_H_
 #define V8_BASE_ATOMICOPS_H_
 
-#include "include/v8stdint.h"
+#include <stdint.h>
 #include "src/base/build_config.h"
 
 #if defined(_WIN32) && defined(V8_HOST_ARCH_64_BIT)
@@ -42,15 +42,17 @@
 
 typedef char Atomic8;
 typedef int32_t Atomic32;
-#ifdef V8_HOST_ARCH_64_BIT
+#if defined(__native_client__)
+typedef int64_t Atomic64;
+#elif defined(V8_HOST_ARCH_64_BIT)
 // We need to be able to go between Atomic64 and AtomicWord implicitly.  This
 // means Atomic64 and AtomicWord should be the same type on 64-bit.
 #if defined(__ILP32__)
 typedef int64_t Atomic64;
 #else
 typedef intptr_t Atomic64;
-#endif
-#endif
+#endif  // defined(V8_HOST_ARCH_64_BIT)
+#endif  // defined(__native_client__)
 
 // Use AtomicWord for a machine-sized pointer.  It will use the Atomic32 or
 // Atomic64 routines below, depending on your architecture.
@@ -140,6 +142,8 @@
 #include "src/base/atomicops_internals_x86_msvc.h"
 #elif defined(__APPLE__)
 #include "src/base/atomicops_internals_mac.h"
+#elif defined(__native_client__)
+#include "src/base/atomicops_internals_portable.h"
 #elif defined(__GNUC__) && V8_HOST_ARCH_ARM64
 #include "src/base/atomicops_internals_arm64_gcc.h"
 #elif defined(__GNUC__) && V8_HOST_ARCH_ARM
diff --git a/src/base/atomicops_internals_mac.h b/src/base/atomicops_internals_mac.h
index a046872..84f9dbc 100644
--- a/src/base/atomicops_internals_mac.h
+++ b/src/base/atomicops_internals_mac.h
@@ -12,6 +12,20 @@
 namespace v8 {
 namespace base {
 
+#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
+
+inline void MemoryBarrier() { OSMemoryBarrier(); }
+
+inline void AcquireMemoryBarrier() {
+// On x86 processors, loads already have acquire semantics, so
+// there is no need to put a full barrier here.
+#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
+  ATOMICOPS_COMPILER_BARRIER();
+#else
+  MemoryBarrier();
+#endif
+}
+
 inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
                                          Atomic32 old_value,
                                          Atomic32 new_value) {
@@ -46,10 +60,6 @@
   return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr));
 }
 
-inline void MemoryBarrier() {
-  OSMemoryBarrier();
-}
-
 inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
                                        Atomic32 old_value,
                                        Atomic32 new_value) {
@@ -98,7 +108,7 @@
 
 inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
   Atomic32 value = *ptr;
-  MemoryBarrier();
+  AcquireMemoryBarrier();
   return value;
 }
 
@@ -188,7 +198,7 @@
 
 inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
   Atomic64 value = *ptr;
-  MemoryBarrier();
+  AcquireMemoryBarrier();
   return value;
 }
 
@@ -199,6 +209,7 @@
 
 #endif  // defined(__LP64__)
 
+#undef ATOMICOPS_COMPILER_BARRIER
 } }  // namespace v8::base
 
 #endif  // V8_BASE_ATOMICOPS_INTERNALS_MAC_H_
diff --git a/src/base/atomicops_internals_portable.h b/src/base/atomicops_internals_portable.h
new file mode 100644
index 0000000..a3a6e74
--- /dev/null
+++ b/src/base/atomicops_internals_portable.h
@@ -0,0 +1,138 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is an internal atomic implementation, use atomicops.h instead.
+
+#ifndef V8_BASE_ATOMICOPS_INTERNALS_PORTABLE_H_
+#define V8_BASE_ATOMICOPS_INTERNALS_PORTABLE_H_
+
+namespace v8 {
+namespace base {
+
+inline void MemoryBarrier() { __sync_synchronize(); }
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+                                         Atomic32 old_value,
+                                         Atomic32 new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+                                         Atomic32 new_value) {
+  return __sync_lock_test_and_set(ptr, new_value);
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+                                          Atomic32 increment) {
+  return __sync_add_and_fetch(ptr, increment);
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+                                        Atomic32 increment) {
+  return __sync_add_and_fetch(ptr, increment);
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value, Atomic32 new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+                                       Atomic32 old_value, Atomic32 new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic8* ptr, Atomic8 value) {
+  __sync_lock_test_and_set(ptr, value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+  __sync_lock_test_and_set(ptr, value);
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+  __sync_lock_test_and_set(ptr, value);
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+  __sync_lock_test_and_set(ptr, value);
+}
+
+inline Atomic8 NoBarrier_Load(volatile const Atomic8* ptr) {
+  return __sync_add_and_fetch(ptr, 0);
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+  return __sync_add_and_fetch(ptr, 0);
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+  return __sync_add_and_fetch(ptr, 0);
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+  return __sync_add_and_fetch(ptr, 0);
+}
+
+// 64-bit versions of the operations.
+// See the 32-bit versions for comments.
+
+inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
+                                         Atomic64 old_value,
+                                         Atomic64 new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+                                         Atomic64 new_value) {
+  return __sync_lock_test_and_set(ptr, new_value);
+}
+
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+                                          Atomic64 increment) {
+  return __sync_add_and_fetch(ptr, increment);
+}
+
+inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
+                                        Atomic64 increment) {
+  return __sync_add_and_fetch(ptr, increment);
+}
+
+inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value, Atomic64 new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
+
+inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
+                                       Atomic64 old_value, Atomic64 new_value) {
+  return __sync_val_compare_and_swap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+  __sync_lock_test_and_set(ptr, value);
+}
+
+inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
+  __sync_lock_test_and_set(ptr, value);
+}
+
+inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
+  __sync_lock_test_and_set(ptr, value);
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+  return __sync_add_and_fetch(ptr, 0);
+}
+
+inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
+  return __sync_add_and_fetch(ptr, 0);
+}
+
+inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
+  return __sync_add_and_fetch(ptr, 0);
+}
+}
+}  // namespace v8::base
+
+#endif  // V8_BASE_ATOMICOPS_INTERNALS_PORTABLE_H_
diff --git a/src/base/base.gyp b/src/base/base.gyp
deleted file mode 100644
index e391e2e..0000000
--- a/src/base/base.gyp
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2014 the V8 project authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
-  'variables': {
-    'v8_code': 1,
-  },
-  'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
-  'targets': [
-    {
-      'target_name': 'base-unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../../testing/gtest.gyp:gtest',
-        '../../testing/gtest.gyp:gtest_main',
-        '../../tools/gyp/v8.gyp:v8_libbase',
-      ],
-      'include_dirs': [
-        '../..',
-      ],
-      'sources': [  ### gcmole(all) ###
-        'bits-unittest.cc',
-        'cpu-unittest.cc',
-        'division-by-constant-unittest.cc',
-        'flags-unittest.cc',
-        'platform/condition-variable-unittest.cc',
-        'platform/mutex-unittest.cc',
-        'platform/platform-unittest.cc',
-        'platform/semaphore-unittest.cc',
-        'platform/time-unittest.cc',
-        'sys-info-unittest.cc',
-        'utils/random-number-generator-unittest.cc',
-      ],
-      'conditions': [
-        ['os_posix == 1', {
-          # TODO(svenpanne): This is a temporary work-around to fix the warnings
-          # that show up because we use -std=gnu++0x instead of -std=c++11.
-          'cflags!': [
-            '-pedantic',
-          ],
-        }],
-      ],
-    },
-  ],
-}
diff --git a/src/base/bits-unittest.cc b/src/base/bits-unittest.cc
deleted file mode 100644
index 06c1183..0000000
--- a/src/base/bits-unittest.cc
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <limits>
-
-#include "src/base/bits.h"
-#include "src/base/macros.h"
-#include "testing/gtest-support.h"
-
-#ifdef DEBUG
-#define DISABLE_IN_RELEASE(Name) Name
-#else
-#define DISABLE_IN_RELEASE(Name) DISABLED_##Name
-#endif
-
-namespace v8 {
-namespace base {
-namespace bits {
-
-TEST(Bits, CountPopulation32) {
-  EXPECT_EQ(0u, CountPopulation32(0));
-  EXPECT_EQ(1u, CountPopulation32(1));
-  EXPECT_EQ(8u, CountPopulation32(0x11111111));
-  EXPECT_EQ(16u, CountPopulation32(0xf0f0f0f0));
-  EXPECT_EQ(24u, CountPopulation32(0xfff0f0ff));
-  EXPECT_EQ(32u, CountPopulation32(0xffffffff));
-}
-
-
-TEST(Bits, CountLeadingZeros32) {
-  EXPECT_EQ(32u, CountLeadingZeros32(0));
-  EXPECT_EQ(31u, CountLeadingZeros32(1));
-  TRACED_FORRANGE(uint32_t, shift, 0, 31) {
-    EXPECT_EQ(31u - shift, CountLeadingZeros32(1u << shift));
-  }
-  EXPECT_EQ(4u, CountLeadingZeros32(0x0f0f0f0f));
-}
-
-
-TEST(Bits, CountTrailingZeros32) {
-  EXPECT_EQ(32u, CountTrailingZeros32(0));
-  EXPECT_EQ(31u, CountTrailingZeros32(0x80000000));
-  TRACED_FORRANGE(uint32_t, shift, 0, 31) {
-    EXPECT_EQ(shift, CountTrailingZeros32(1u << shift));
-  }
-  EXPECT_EQ(4u, CountTrailingZeros32(0xf0f0f0f0));
-}
-
-
-TEST(Bits, IsPowerOfTwo32) {
-  EXPECT_FALSE(IsPowerOfTwo32(0U));
-  TRACED_FORRANGE(uint32_t, shift, 0, 31) {
-    EXPECT_TRUE(IsPowerOfTwo32(1U << shift));
-    EXPECT_FALSE(IsPowerOfTwo32((1U << shift) + 5U));
-    EXPECT_FALSE(IsPowerOfTwo32(~(1U << shift)));
-  }
-  TRACED_FORRANGE(uint32_t, shift, 2, 31) {
-    EXPECT_FALSE(IsPowerOfTwo32((1U << shift) - 1U));
-  }
-  EXPECT_FALSE(IsPowerOfTwo32(0xffffffff));
-}
-
-
-TEST(Bits, IsPowerOfTwo64) {
-  EXPECT_FALSE(IsPowerOfTwo64(0U));
-  TRACED_FORRANGE(uint32_t, shift, 0, 63) {
-    EXPECT_TRUE(IsPowerOfTwo64(V8_UINT64_C(1) << shift));
-    EXPECT_FALSE(IsPowerOfTwo64((V8_UINT64_C(1) << shift) + 5U));
-    EXPECT_FALSE(IsPowerOfTwo64(~(V8_UINT64_C(1) << shift)));
-  }
-  TRACED_FORRANGE(uint32_t, shift, 2, 63) {
-    EXPECT_FALSE(IsPowerOfTwo64((V8_UINT64_C(1) << shift) - 1U));
-  }
-  EXPECT_FALSE(IsPowerOfTwo64(V8_UINT64_C(0xffffffffffffffff)));
-}
-
-
-TEST(Bits, RoundUpToPowerOfTwo32) {
-  TRACED_FORRANGE(uint32_t, shift, 0, 31) {
-    EXPECT_EQ(1u << shift, RoundUpToPowerOfTwo32(1u << shift));
-  }
-  EXPECT_EQ(0u, RoundUpToPowerOfTwo32(0));
-  EXPECT_EQ(4u, RoundUpToPowerOfTwo32(3));
-  EXPECT_EQ(0x80000000u, RoundUpToPowerOfTwo32(0x7fffffffu));
-}
-
-
-TEST(BitsDeathTest, DISABLE_IN_RELEASE(RoundUpToPowerOfTwo32)) {
-  ASSERT_DEATH_IF_SUPPORTED({ RoundUpToPowerOfTwo32(0x80000001u); },
-                            "0x80000000");
-}
-
-
-TEST(Bits, RoundDownToPowerOfTwo32) {
-  TRACED_FORRANGE(uint32_t, shift, 0, 31) {
-    EXPECT_EQ(1u << shift, RoundDownToPowerOfTwo32(1u << shift));
-  }
-  EXPECT_EQ(0u, RoundDownToPowerOfTwo32(0));
-  EXPECT_EQ(4u, RoundDownToPowerOfTwo32(5));
-  EXPECT_EQ(0x80000000u, RoundDownToPowerOfTwo32(0x80000001u));
-}
-
-
-TEST(Bits, RotateRight32) {
-  TRACED_FORRANGE(uint32_t, shift, 0, 31) {
-    EXPECT_EQ(0u, RotateRight32(0u, shift));
-  }
-  EXPECT_EQ(1u, RotateRight32(1, 0));
-  EXPECT_EQ(1u, RotateRight32(2, 1));
-  EXPECT_EQ(0x80000000u, RotateRight32(1, 1));
-}
-
-
-TEST(Bits, RotateRight64) {
-  TRACED_FORRANGE(uint64_t, shift, 0, 63) {
-    EXPECT_EQ(0u, RotateRight64(0u, shift));
-  }
-  EXPECT_EQ(1u, RotateRight64(1, 0));
-  EXPECT_EQ(1u, RotateRight64(2, 1));
-  EXPECT_EQ(V8_UINT64_C(0x8000000000000000), RotateRight64(1, 1));
-}
-
-
-TEST(Bits, SignedAddOverflow32) {
-  int32_t val = 0;
-  EXPECT_FALSE(SignedAddOverflow32(0, 0, &val));
-  EXPECT_EQ(0, val);
-  EXPECT_TRUE(
-      SignedAddOverflow32(std::numeric_limits<int32_t>::max(), 1, &val));
-  EXPECT_EQ(std::numeric_limits<int32_t>::min(), val);
-  EXPECT_TRUE(
-      SignedAddOverflow32(std::numeric_limits<int32_t>::min(), -1, &val));
-  EXPECT_EQ(std::numeric_limits<int32_t>::max(), val);
-  EXPECT_TRUE(SignedAddOverflow32(std::numeric_limits<int32_t>::max(),
-                                  std::numeric_limits<int32_t>::max(), &val));
-  EXPECT_EQ(-2, val);
-  TRACED_FORRANGE(int32_t, i, 1, 50) {
-    TRACED_FORRANGE(int32_t, j, 1, i) {
-      EXPECT_FALSE(SignedAddOverflow32(i, j, &val));
-      EXPECT_EQ(i + j, val);
-    }
-  }
-}
-
-
-TEST(Bits, SignedSubOverflow32) {
-  int32_t val = 0;
-  EXPECT_FALSE(SignedSubOverflow32(0, 0, &val));
-  EXPECT_EQ(0, val);
-  EXPECT_TRUE(
-      SignedSubOverflow32(std::numeric_limits<int32_t>::min(), 1, &val));
-  EXPECT_EQ(std::numeric_limits<int32_t>::max(), val);
-  EXPECT_TRUE(
-      SignedSubOverflow32(std::numeric_limits<int32_t>::max(), -1, &val));
-  EXPECT_EQ(std::numeric_limits<int32_t>::min(), val);
-  TRACED_FORRANGE(int32_t, i, 1, 50) {
-    TRACED_FORRANGE(int32_t, j, 1, i) {
-      EXPECT_FALSE(SignedSubOverflow32(i, j, &val));
-      EXPECT_EQ(i - j, val);
-    }
-  }
-}
-
-}  // namespace bits
-}  // namespace base
-}  // namespace v8
diff --git a/src/base/bits.cc b/src/base/bits.cc
index 6daee53..74d747f 100644
--- a/src/base/bits.cc
+++ b/src/base/bits.cc
@@ -3,6 +3,9 @@
 // found in the LICENSE file.
 
 #include "src/base/bits.h"
+
+#include <limits>
+
 #include "src/base/logging.h"
 
 namespace v8 {
@@ -20,6 +23,31 @@
   return value + 1;
 }
 
+
+int32_t SignedMulHigh32(int32_t lhs, int32_t rhs) {
+  int64_t const value = static_cast<int64_t>(lhs) * static_cast<int64_t>(rhs);
+  return bit_cast<int32_t, uint32_t>(bit_cast<uint64_t>(value) >> 32u);
+}
+
+
+int32_t SignedMulHighAndAdd32(int32_t lhs, int32_t rhs, int32_t acc) {
+  return bit_cast<int32_t>(bit_cast<uint32_t>(acc) +
+                           bit_cast<uint32_t>(SignedMulHigh32(lhs, rhs)));
+}
+
+
+int32_t SignedDiv32(int32_t lhs, int32_t rhs) {
+  if (rhs == 0) return 0;
+  if (rhs == -1) return -lhs;
+  return lhs / rhs;
+}
+
+
+int32_t SignedMod32(int32_t lhs, int32_t rhs) {
+  if (rhs == 0 || rhs == -1) return 0;
+  return lhs % rhs;
+}
+
 }  // namespace bits
 }  // namespace base
 }  // namespace v8
diff --git a/src/base/bits.h b/src/base/bits.h
index e6a733a..0f4d4c7 100644
--- a/src/base/bits.h
+++ b/src/base/bits.h
@@ -5,7 +5,7 @@
 #ifndef V8_BASE_BITS_H_
 #define V8_BASE_BITS_H_
 
-#include "include/v8stdint.h"
+#include <stdint.h>
 #include "src/base/macros.h"
 #if V8_CC_MSVC
 #include <intrin.h>
@@ -19,7 +19,7 @@
 namespace bits {
 
 // CountPopulation32(value) returns the number of bits set in |value|.
-inline uint32_t CountPopulation32(uint32_t value) {
+inline unsigned CountPopulation32(uint32_t value) {
 #if V8_HAS_BUILTIN_POPCOUNT
   return __builtin_popcount(value);
 #else
@@ -28,20 +28,31 @@
   value = ((value >> 4) & 0x0f0f0f0f) + (value & 0x0f0f0f0f);
   value = ((value >> 8) & 0x00ff00ff) + (value & 0x00ff00ff);
   value = ((value >> 16) & 0x0000ffff) + (value & 0x0000ffff);
-  return value;
+  return static_cast<unsigned>(value);
+#endif
+}
+
+
+// CountPopulation64(value) returns the number of bits set in |value|.
+inline unsigned CountPopulation64(uint64_t value) {
+#if V8_HAS_BUILTIN_POPCOUNT
+  return __builtin_popcountll(value);
+#else
+  return CountPopulation32(static_cast<uint32_t>(value)) +
+         CountPopulation32(static_cast<uint32_t>(value >> 32));
 #endif
 }
 
 
 // CountLeadingZeros32(value) returns the number of zero bits following the most
 // significant 1 bit in |value| if |value| is non-zero, otherwise it returns 32.
-inline uint32_t CountLeadingZeros32(uint32_t value) {
+inline unsigned CountLeadingZeros32(uint32_t value) {
 #if V8_HAS_BUILTIN_CLZ
   return value ? __builtin_clz(value) : 32;
 #elif V8_CC_MSVC
   unsigned long result;  // NOLINT(runtime/int)
   if (!_BitScanReverse(&result, value)) return 32;
-  return static_cast<uint32_t>(31 - result);
+  return static_cast<unsigned>(31 - result);
 #else
   value = value | (value >> 1);
   value = value | (value >> 2);
@@ -53,16 +64,33 @@
 }
 
 
+// CountLeadingZeros64(value) returns the number of zero bits following the most
+// significant 1 bit in |value| if |value| is non-zero, otherwise it returns 64.
+inline unsigned CountLeadingZeros64(uint64_t value) {
+#if V8_HAS_BUILTIN_CLZ
+  return value ? __builtin_clzll(value) : 64;
+#else
+  value = value | (value >> 1);
+  value = value | (value >> 2);
+  value = value | (value >> 4);
+  value = value | (value >> 8);
+  value = value | (value >> 16);
+  value = value | (value >> 32);
+  return CountPopulation64(~value);
+#endif
+}
+
+
 // CountTrailingZeros32(value) returns the number of zero bits preceding the
 // least significant 1 bit in |value| if |value| is non-zero, otherwise it
 // returns 32.
-inline uint32_t CountTrailingZeros32(uint32_t value) {
+inline unsigned CountTrailingZeros32(uint32_t value) {
 #if V8_HAS_BUILTIN_CTZ
   return value ? __builtin_ctz(value) : 32;
 #elif V8_CC_MSVC
   unsigned long result;  // NOLINT(runtime/int)
   if (!_BitScanForward(&result, value)) return 32;
-  return static_cast<uint32_t>(result);
+  return static_cast<unsigned>(result);
 #else
   if (value == 0) return 32;
   unsigned count = 0;
@@ -73,6 +101,22 @@
 }
 
 
+// CountTrailingZeros64(value) returns the number of zero bits preceding the
+// least significant 1 bit in |value| if |value| is non-zero, otherwise it
+// returns 64.
+inline unsigned CountTrailingZeros64(uint64_t value) {
+#if V8_HAS_BUILTIN_CTZ
+  return value ? __builtin_ctzll(value) : 64;
+#else
+  if (value == 0) return 64;
+  unsigned count = 0;
+  for (value ^= value - 1; value >>= 1; ++count)
+    ;
+  return count;
+#endif
+}
+
+
 // Returns true iff |value| is a power of 2.
 inline bool IsPowerOfTwo32(uint32_t value) {
   return value && !(value & (value - 1));
@@ -143,6 +187,44 @@
 #endif
 }
 
+
+// SignedMulHigh32(lhs, rhs) multiplies two signed 32-bit values |lhs| and
+// |rhs|, extracts the most significant 32 bits of the result, and returns
+// those.
+int32_t SignedMulHigh32(int32_t lhs, int32_t rhs);
+
+
+// SignedMulHighAndAdd32(lhs, rhs, acc) multiplies two signed 32-bit values
+// |lhs| and |rhs|, extracts the most significant 32 bits of the result, and
+// adds the accumulate value |acc|.
+int32_t SignedMulHighAndAdd32(int32_t lhs, int32_t rhs, int32_t acc);
+
+
+// SignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient
+// truncated to int32. If |rhs| is zero, then zero is returned. If |lhs|
+// is minint and |rhs| is -1, it returns minint.
+int32_t SignedDiv32(int32_t lhs, int32_t rhs);
+
+
+// SignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder
+// truncated to int32. If either |rhs| is zero or |lhs| is minint and |rhs|
+// is -1, it returns zero.
+int32_t SignedMod32(int32_t lhs, int32_t rhs);
+
+
+// UnsignedDiv32(lhs, rhs) divides |lhs| by |rhs| and returns the quotient
+// truncated to uint32. If |rhs| is zero, then zero is returned.
+inline uint32_t UnsignedDiv32(uint32_t lhs, uint32_t rhs) {
+  return rhs ? lhs / rhs : 0u;
+}
+
+
+// UnsignedMod32(lhs, rhs) divides |lhs| by |rhs| and returns the remainder
+// truncated to uint32. If |rhs| is zero, then zero is returned.
+inline uint32_t UnsignedMod32(uint32_t lhs, uint32_t rhs) {
+  return rhs ? lhs % rhs : 0u;
+}
+
 }  // namespace bits
 }  // namespace base
 }  // namespace v8
diff --git a/src/base/build_config.h b/src/base/build_config.h
index 2bf57c9..f528776 100644
--- a/src/base/build_config.h
+++ b/src/base/build_config.h
@@ -29,6 +29,10 @@
 #define V8_HOST_ARCH_64_BIT 1
 #endif
 #endif  // __native_client__
+#elif defined(__pnacl__)
+// PNaCl is also ILP-32.
+#define V8_HOST_ARCH_IA32 1
+#define V8_HOST_ARCH_32_BIT 1
 #elif defined(_M_IX86) || defined(__i386__)
 #define V8_HOST_ARCH_IA32 1
 #define V8_HOST_ARCH_32_BIT 1
diff --git a/src/base/compiler-specific.h b/src/base/compiler-specific.h
index 475a32c..9755fc1 100644
--- a/src/base/compiler-specific.h
+++ b/src/base/compiler-specific.h
@@ -7,15 +7,13 @@
 
 #include "include/v8config.h"
 
-// Annotate a variable indicating it's ok if the variable is not used.
-// (Typically used to silence a compiler warning when the assignment
-// is important for some other reason.)
+// Annotate a typedef or function indicating it's ok if it's not used.
 // Use like:
-//   int x ALLOW_UNUSED = ...;
+//   typedef Foo Bar ALLOW_UNUSED_TYPE;
 #if V8_HAS_ATTRIBUTE_UNUSED
-#define ALLOW_UNUSED __attribute__((unused))
+#define ALLOW_UNUSED_TYPE __attribute__((unused))
 #else
-#define ALLOW_UNUSED
+#define ALLOW_UNUSED_TYPE
 #endif
 
 
@@ -39,8 +37,6 @@
 #define FINAL final
 #elif V8_HAS___FINAL
 #define FINAL __final
-#elif V8_HAS_SEALED
-#define FINAL sealed
 #else
 #define FINAL /* NOT SUPPORTED */
 #endif
diff --git a/src/base/cpu.cc b/src/base/cpu.cc
index cd40d4f..daf3302 100644
--- a/src/base/cpu.cc
+++ b/src/base/cpu.cc
@@ -7,12 +7,18 @@
 #if V8_LIBC_MSVCRT
 #include <intrin.h>  // __cpuid()
 #endif
-#if V8_OS_POSIX
-#include <unistd.h>  // sysconf()
+#if V8_OS_LINUX
+#include <linux/auxvec.h>  // AT_HWCAP
+#endif
+#if V8_GLIBC_PREREQ(2, 16)
+#include <sys/auxv.h>  // getauxval()
 #endif
 #if V8_OS_QNX
 #include <sys/syspage.h>  // cpuinfo
 #endif
+#if V8_OS_POSIX
+#include <unistd.h>  // sysconf()
+#endif
 
 #include <ctype.h>
 #include <limits.h>
@@ -29,7 +35,9 @@
 namespace v8 {
 namespace base {
 
-#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
+#if defined(__pnacl__)
+// Portable host shouldn't do feature detection.
+#elif V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
 
 // Define __cpuid() for non-MSVC libraries.
 #if !V8_LIBC_MSVCRT
@@ -90,11 +98,12 @@
 #define HWCAP_IDIV  (HWCAP_IDIVA | HWCAP_IDIVT)
 #define HWCAP_LPAE  (1 << 20)
 
-#define AT_HWCAP 16
-
-// Read the ELF HWCAP flags by parsing /proc/self/auxv.
 static uint32_t ReadELFHWCaps() {
   uint32_t result = 0;
+#if V8_GLIBC_PREREQ(2, 16)
+  result = static_cast<uint32_t>(getauxval(AT_HWCAP));
+#else
+  // Read the ELF HWCAP flags by parsing /proc/self/auxv.
   FILE* fp = fopen("/proc/self/auxv", "r");
   if (fp != NULL) {
     struct { uint32_t tag; uint32_t value; } entry;
@@ -110,6 +119,7 @@
     }
     fclose(fp);
   }
+#endif
   return result;
 }
 
@@ -281,34 +291,42 @@
 
 #endif  // V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
 
-CPU::CPU() : stepping_(0),
-             model_(0),
-             ext_model_(0),
-             family_(0),
-             ext_family_(0),
-             type_(0),
-             implementer_(0),
-             architecture_(0),
-             part_(0),
-             has_fpu_(false),
-             has_cmov_(false),
-             has_sahf_(false),
-             has_mmx_(false),
-             has_sse_(false),
-             has_sse2_(false),
-             has_sse3_(false),
-             has_ssse3_(false),
-             has_sse41_(false),
-             has_sse42_(false),
-             has_idiva_(false),
-             has_neon_(false),
-             has_thumb2_(false),
-             has_vfp_(false),
-             has_vfp3_(false),
-             has_vfp3_d32_(false),
-             is_fp64_mode_(false) {
+CPU::CPU()
+    : stepping_(0),
+      model_(0),
+      ext_model_(0),
+      family_(0),
+      ext_family_(0),
+      type_(0),
+      implementer_(0),
+      architecture_(0),
+      variant_(-1),
+      part_(0),
+      has_fpu_(false),
+      has_cmov_(false),
+      has_sahf_(false),
+      has_mmx_(false),
+      has_sse_(false),
+      has_sse2_(false),
+      has_sse3_(false),
+      has_ssse3_(false),
+      has_sse41_(false),
+      has_sse42_(false),
+      has_avx_(false),
+      has_fma3_(false),
+      has_idiva_(false),
+      has_neon_(false),
+      has_thumb2_(false),
+      has_vfp_(false),
+      has_vfp3_(false),
+      has_vfp3_d32_(false),
+      is_fp64_mode_(false) {
   memcpy(vendor_, "Unknown", 8);
-#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
+#if V8_OS_NACL
+// Portable host shouldn't do feature detection.
+// TODO(jfb): Remove the hardcoded ARM simulator flags in the build, and
+// hardcode them here instead.
+#elif V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
   int cpu_info[4];
 
   // __cpuid with an InfoType argument of 0 returns the number of
@@ -342,6 +360,8 @@
     has_ssse3_ = (cpu_info[2] & 0x00000200) != 0;
     has_sse41_ = (cpu_info[2] & 0x00080000) != 0;
     has_sse42_ = (cpu_info[2] & 0x00100000) != 0;
+    has_avx_ = (cpu_info[2] & 0x10000000) != 0;
+    if (has_avx_) has_fma3_ = (cpu_info[2] & 0x00001000) != 0;
   }
 
 #if V8_HOST_ARCH_IA32
@@ -369,7 +389,7 @@
   // Extract implementor from the "CPU implementer" field.
   char* implementer = cpu_info.ExtractField("CPU implementer");
   if (implementer != NULL) {
-    char* end ;
+    char* end;
     implementer_ = strtol(implementer, &end, 0);
     if (end == implementer) {
       implementer_ = 0;
@@ -377,10 +397,20 @@
     delete[] implementer;
   }
 
+  char* variant = cpu_info.ExtractField("CPU variant");
+  if (variant != NULL) {
+    char* end;
+    variant_ = strtol(variant, &end, 0);
+    if (end == variant) {
+      variant_ = -1;
+    }
+    delete[] variant;
+  }
+
   // Extract part number from the "CPU part" field.
   char* part = cpu_info.ExtractField("CPU part");
   if (part != NULL) {
-    char* end ;
+    char* end;
     part_ = strtol(part, &end, 0);
     if (end == part) {
       part_ = 0;
@@ -408,7 +438,7 @@
     //
     // See http://code.google.com/p/android/issues/detail?id=10812
     //
-    // We try to correct this by looking at the 'elf_format'
+    // We try to correct this by looking at the 'elf_platform'
     // field reported by the 'Processor' field, which is of the
     // form of "(v7l)" for an ARMv7-based CPU, and "(v6l)" for
     // an ARMv6-one. For example, the Raspberry Pi is one popular
@@ -420,6 +450,15 @@
       }
       delete[] processor;
     }
+
+    // elf_platform moved to the model name field in Linux v3.8.
+    if (architecture_ == 7) {
+      char* processor = cpu_info.ExtractField("model name");
+      if (HasListItem(processor, "(v6l)")) {
+        architecture_ = 6;
+      }
+      delete[] processor;
+    }
   }
 
   // Try to extract the list of CPU features from ELF hwcaps.
@@ -521,7 +560,7 @@
   // Extract implementor from the "CPU implementer" field.
   char* implementer = cpu_info.ExtractField("CPU implementer");
   if (implementer != NULL) {
-    char* end ;
+    char* end;
     implementer_ = strtol(implementer, &end, 0);
     if (end == implementer) {
       implementer_ = 0;
@@ -529,10 +568,20 @@
     delete[] implementer;
   }
 
+  char* variant = cpu_info.ExtractField("CPU variant");
+  if (variant != NULL) {
+    char* end;
+    variant_ = strtol(variant, &end, 0);
+    if (end == variant) {
+      variant_ = -1;
+    }
+    delete[] variant;
+  }
+
   // Extract part number from the "CPU part" field.
   char* part = cpu_info.ExtractField("CPU part");
   if (part != NULL) {
-    char* end ;
+    char* end;
     part_ = strtol(part, &end, 0);
     if (end == part) {
       part_ = 0;
diff --git a/src/base/cpu.h b/src/base/cpu.h
index dc0eaf4..8c41f9d 100644
--- a/src/base/cpu.h
+++ b/src/base/cpu.h
@@ -47,6 +47,8 @@
   static const int NVIDIA = 0x4e;
   static const int QUALCOMM = 0x51;
   int architecture() const { return architecture_; }
+  int variant() const { return variant_; }
+  static const int NVIDIA_DENVER = 0x0;
   int part() const { return part_; }
   static const int ARM_CORTEX_A5 = 0xc05;
   static const int ARM_CORTEX_A7 = 0xc07;
@@ -68,6 +70,8 @@
   bool has_ssse3() const { return has_ssse3_; }
   bool has_sse41() const { return has_sse41_; }
   bool has_sse42() const { return has_sse42_; }
+  bool has_avx() const { return has_avx_; }
+  bool has_fma3() const { return has_fma3_; }
 
   // arm features
   bool has_idiva() const { return has_idiva_; }
@@ -90,6 +94,7 @@
   int type_;
   int implementer_;
   int architecture_;
+  int variant_;
   int part_;
   bool has_fpu_;
   bool has_cmov_;
@@ -101,6 +106,8 @@
   bool has_ssse3_;
   bool has_sse41_;
   bool has_sse42_;
+  bool has_avx_;
+  bool has_fma3_;
   bool has_idiva_;
   bool has_neon_;
   bool has_thumb2_;
diff --git a/src/base/division-by-constant-unittest.cc b/src/base/division-by-constant-unittest.cc
deleted file mode 100644
index 47c2483..0000000
--- a/src/base/division-by-constant-unittest.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Check all examples from table 10-1 of "Hacker's Delight".
-
-#include "src/base/division-by-constant.h"
-
-#include <ostream>  // NOLINT
-
-#include "testing/gtest-support.h"
-
-namespace v8 {
-namespace base {
-
-template <class T>
-std::ostream& operator<<(std::ostream& os,
-                         const MagicNumbersForDivision<T>& mag) {
-  return os << "{ multiplier: " << mag.multiplier << ", shift: " << mag.shift
-            << ", add: " << mag.add << " }";
-}
-
-
-// Some abbreviations...
-
-typedef MagicNumbersForDivision<uint32_t> M32;
-typedef MagicNumbersForDivision<uint64_t> M64;
-
-
-static M32 s32(int32_t d) {
-  return SignedDivisionByConstant<uint32_t>(static_cast<uint32_t>(d));
-}
-
-
-static M64 s64(int64_t d) {
-  return SignedDivisionByConstant<uint64_t>(static_cast<uint64_t>(d));
-}
-
-
-static M32 u32(uint32_t d) { return UnsignedDivisionByConstant<uint32_t>(d); }
-static M64 u64(uint64_t d) { return UnsignedDivisionByConstant<uint64_t>(d); }
-
-
-TEST(DivisionByConstant, Signed32) {
-  EXPECT_EQ(M32(0x99999999U, 1, false), s32(-5));
-  EXPECT_EQ(M32(0x55555555U, 1, false), s32(-3));
-  int32_t d = -1;
-  for (unsigned k = 1; k <= 32 - 1; ++k) {
-    d *= 2;
-    EXPECT_EQ(M32(0x7FFFFFFFU, k - 1, false), s32(d));
-  }
-  for (unsigned k = 1; k <= 32 - 2; ++k) {
-    EXPECT_EQ(M32(0x80000001U, k - 1, false), s32(1 << k));
-  }
-  EXPECT_EQ(M32(0x55555556U, 0, false), s32(3));
-  EXPECT_EQ(M32(0x66666667U, 1, false), s32(5));
-  EXPECT_EQ(M32(0x2AAAAAABU, 0, false), s32(6));
-  EXPECT_EQ(M32(0x92492493U, 2, false), s32(7));
-  EXPECT_EQ(M32(0x38E38E39U, 1, false), s32(9));
-  EXPECT_EQ(M32(0x66666667U, 2, false), s32(10));
-  EXPECT_EQ(M32(0x2E8BA2E9U, 1, false), s32(11));
-  EXPECT_EQ(M32(0x2AAAAAABU, 1, false), s32(12));
-  EXPECT_EQ(M32(0x51EB851FU, 3, false), s32(25));
-  EXPECT_EQ(M32(0x10624DD3U, 3, false), s32(125));
-  EXPECT_EQ(M32(0x68DB8BADU, 8, false), s32(625));
-}
-
-
-TEST(DivisionByConstant, Unsigned32) {
-  EXPECT_EQ(M32(0x00000000U, 0, true), u32(1));
-  for (unsigned k = 1; k <= 30; ++k) {
-    EXPECT_EQ(M32(1U << (32 - k), 0, false), u32(1U << k));
-  }
-  EXPECT_EQ(M32(0xAAAAAAABU, 1, false), u32(3));
-  EXPECT_EQ(M32(0xCCCCCCCDU, 2, false), u32(5));
-  EXPECT_EQ(M32(0xAAAAAAABU, 2, false), u32(6));
-  EXPECT_EQ(M32(0x24924925U, 3, true), u32(7));
-  EXPECT_EQ(M32(0x38E38E39U, 1, false), u32(9));
-  EXPECT_EQ(M32(0xCCCCCCCDU, 3, false), u32(10));
-  EXPECT_EQ(M32(0xBA2E8BA3U, 3, false), u32(11));
-  EXPECT_EQ(M32(0xAAAAAAABU, 3, false), u32(12));
-  EXPECT_EQ(M32(0x51EB851FU, 3, false), u32(25));
-  EXPECT_EQ(M32(0x10624DD3U, 3, false), u32(125));
-  EXPECT_EQ(M32(0xD1B71759U, 9, false), u32(625));
-}
-
-
-TEST(DivisionByConstant, Signed64) {
-  EXPECT_EQ(M64(0x9999999999999999ULL, 1, false), s64(-5));
-  EXPECT_EQ(M64(0x5555555555555555ULL, 1, false), s64(-3));
-  int64_t d = -1;
-  for (unsigned k = 1; k <= 64 - 1; ++k) {
-    d *= 2;
-    EXPECT_EQ(M64(0x7FFFFFFFFFFFFFFFULL, k - 1, false), s64(d));
-  }
-  for (unsigned k = 1; k <= 64 - 2; ++k) {
-    EXPECT_EQ(M64(0x8000000000000001ULL, k - 1, false), s64(1LL << k));
-  }
-  EXPECT_EQ(M64(0x5555555555555556ULL, 0, false), s64(3));
-  EXPECT_EQ(M64(0x6666666666666667ULL, 1, false), s64(5));
-  EXPECT_EQ(M64(0x2AAAAAAAAAAAAAABULL, 0, false), s64(6));
-  EXPECT_EQ(M64(0x4924924924924925ULL, 1, false), s64(7));
-  EXPECT_EQ(M64(0x1C71C71C71C71C72ULL, 0, false), s64(9));
-  EXPECT_EQ(M64(0x6666666666666667ULL, 2, false), s64(10));
-  EXPECT_EQ(M64(0x2E8BA2E8BA2E8BA3ULL, 1, false), s64(11));
-  EXPECT_EQ(M64(0x2AAAAAAAAAAAAAABULL, 1, false), s64(12));
-  EXPECT_EQ(M64(0xA3D70A3D70A3D70BULL, 4, false), s64(25));
-  EXPECT_EQ(M64(0x20C49BA5E353F7CFULL, 4, false), s64(125));
-  EXPECT_EQ(M64(0x346DC5D63886594BULL, 7, false), s64(625));
-}
-
-
-TEST(DivisionByConstant, Unsigned64) {
-  EXPECT_EQ(M64(0x0000000000000000ULL, 0, true), u64(1));
-  for (unsigned k = 1; k <= 64 - 2; ++k) {
-    EXPECT_EQ(M64(1ULL << (64 - k), 0, false), u64(1ULL << k));
-  }
-  EXPECT_EQ(M64(0xAAAAAAAAAAAAAAABULL, 1, false), u64(3));
-  EXPECT_EQ(M64(0xCCCCCCCCCCCCCCCDULL, 2, false), u64(5));
-  EXPECT_EQ(M64(0xAAAAAAAAAAAAAAABULL, 2, false), u64(6));
-  EXPECT_EQ(M64(0x2492492492492493ULL, 3, true), u64(7));
-  EXPECT_EQ(M64(0xE38E38E38E38E38FULL, 3, false), u64(9));
-  EXPECT_EQ(M64(0xCCCCCCCCCCCCCCCDULL, 3, false), u64(10));
-  EXPECT_EQ(M64(0x2E8BA2E8BA2E8BA3ULL, 1, false), u64(11));
-  EXPECT_EQ(M64(0xAAAAAAAAAAAAAAABULL, 3, false), u64(12));
-  EXPECT_EQ(M64(0x47AE147AE147AE15ULL, 5, true), u64(25));
-  EXPECT_EQ(M64(0x0624DD2F1A9FBE77ULL, 7, true), u64(125));
-  EXPECT_EQ(M64(0x346DC5D63886594BULL, 7, false), u64(625));
-}
-
-}  // namespace base
-}  // namespace v8
diff --git a/src/base/division-by-constant.cc b/src/base/division-by-constant.cc
index 235d39f..5167b7a 100644
--- a/src/base/division-by-constant.cc
+++ b/src/base/division-by-constant.cc
@@ -52,7 +52,7 @@
     delta = ad - r2;
   } while (q1 < delta || (q1 == delta && r1 == 0));
   T mul = q2 + 1;
-  return {neg ? (0 - mul) : mul, p - bits, false};
+  return MagicNumbersForDivision<T>(neg ? (0 - mul) : mul, p - bits, false);
 }
 
 
@@ -93,7 +93,7 @@
     }
     delta = d - 1 - r2;
   } while (p < bits * 2 && (q1 < delta || (q1 == delta && r1 == 0)));
-  return {q2 + 1, p - bits, a};
+  return MagicNumbersForDivision<T>(q2 + 1, p - bits, a);
 }
 
 
diff --git a/src/base/flags-unittest.cc b/src/base/flags-unittest.cc
deleted file mode 100644
index a1d6f37..0000000
--- a/src/base/flags-unittest.cc
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "include/v8stdint.h"
-#include "src/base/flags.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace v8 {
-namespace base {
-
-namespace {
-
-enum Flag1 {
-  kFlag1None = 0,
-  kFlag1First = 1u << 1,
-  kFlag1Second = 1u << 2,
-  kFlag1All = kFlag1None | kFlag1First | kFlag1Second
-};
-typedef Flags<Flag1> Flags1;
-
-
-DEFINE_OPERATORS_FOR_FLAGS(Flags1)
-
-
-Flags1 bar(Flags1 flags1) { return flags1; }
-
-}  // namespace
-
-
-TEST(FlagsTest, BasicOperations) {
-  Flags1 a;
-  EXPECT_EQ(kFlag1None, static_cast<int>(a));
-  a |= kFlag1First;
-  EXPECT_EQ(kFlag1First, static_cast<int>(a));
-  a = a | kFlag1Second;
-  EXPECT_EQ(kFlag1All, static_cast<int>(a));
-  a &= kFlag1Second;
-  EXPECT_EQ(kFlag1Second, static_cast<int>(a));
-  a = kFlag1None & a;
-  EXPECT_EQ(kFlag1None, static_cast<int>(a));
-  a ^= (kFlag1All | kFlag1None);
-  EXPECT_EQ(kFlag1All, static_cast<int>(a));
-  Flags1 b = ~a;
-  EXPECT_EQ(kFlag1All, static_cast<int>(a));
-  EXPECT_EQ(~static_cast<int>(a), static_cast<int>(b));
-  Flags1 c = a;
-  EXPECT_EQ(a, c);
-  EXPECT_NE(a, b);
-  EXPECT_EQ(a, bar(a));
-  EXPECT_EQ(a, bar(kFlag1All));
-}
-
-
-namespace {
-namespace foo {
-
-enum Option {
-  kNoOptions = 0,
-  kOption1 = 1,
-  kOption2 = 2,
-  kAllOptions = kNoOptions | kOption1 | kOption2
-};
-typedef Flags<Option> Options;
-
-}  // namespace foo
-
-
-DEFINE_OPERATORS_FOR_FLAGS(foo::Options)
-
-}  // namespace
-
-
-TEST(FlagsTest, NamespaceScope) {
-  foo::Options options;
-  options ^= foo::kNoOptions;
-  options |= foo::kOption1 | foo::kOption2;
-  EXPECT_EQ(foo::kAllOptions, static_cast<int>(options));
-}
-
-
-namespace {
-
-struct Foo {
-  enum Enum { kEnum1 = 1, kEnum2 = 2 };
-  typedef Flags<Enum, uint32_t> Enums;
-};
-
-
-DEFINE_OPERATORS_FOR_FLAGS(Foo::Enums)
-
-}  // namespace
-
-
-TEST(FlagsTest, ClassScope) {
-  Foo::Enums enums;
-  enums |= Foo::kEnum1;
-  enums |= Foo::kEnum2;
-  EXPECT_TRUE(enums & Foo::kEnum1);
-  EXPECT_TRUE(enums & Foo::kEnum2);
-}
-
-}  // namespace base
-}  // namespace v8
diff --git a/src/base/flags.h b/src/base/flags.h
index f3420ee..060dba8 100644
--- a/src/base/flags.h
+++ b/src/base/flags.h
@@ -26,8 +26,9 @@
   typedef S mask_type;
 
   Flags() : mask_(0) {}
-  Flags(flag_type flag) : mask_(flag) {}  // NOLINT(runtime/explicit)
-  explicit Flags(mask_type mask) : mask_(mask) {}
+  Flags(flag_type flag)  // NOLINT(runtime/explicit)
+      : mask_(static_cast<S>(flag)) {}
+  explicit Flags(mask_type mask) : mask_(static_cast<S>(mask)) {}
 
   Flags& operator&=(const Flags& flags) {
     mask_ &= flags.mask_;
@@ -64,42 +65,44 @@
 };
 
 
-#define DEFINE_OPERATORS_FOR_FLAGS(Type)                                       \
-  inline Type operator&(Type::flag_type lhs,                                   \
-                        Type::flag_type rhs)ALLOW_UNUSED WARN_UNUSED_RESULT;   \
-  inline Type operator&(Type::flag_type lhs, Type::flag_type rhs) {            \
-    return Type(lhs) & rhs;                                                    \
-  }                                                                            \
-  inline Type operator&(Type::flag_type lhs,                                   \
-                        const Type& rhs)ALLOW_UNUSED WARN_UNUSED_RESULT;       \
-  inline Type operator&(Type::flag_type lhs, const Type& rhs) {                \
-    return rhs & lhs;                                                          \
-  }                                                                            \
-  inline void operator&(Type::flag_type lhs, Type::mask_type rhs)ALLOW_UNUSED; \
-  inline void operator&(Type::flag_type lhs, Type::mask_type rhs) {}           \
-  inline Type operator|(Type::flag_type lhs, Type::flag_type rhs)              \
-      ALLOW_UNUSED WARN_UNUSED_RESULT;                                         \
-  inline Type operator|(Type::flag_type lhs, Type::flag_type rhs) {            \
-    return Type(lhs) | rhs;                                                    \
-  }                                                                            \
-  inline Type operator|(Type::flag_type lhs, const Type& rhs)                  \
-      ALLOW_UNUSED WARN_UNUSED_RESULT;                                         \
-  inline Type operator|(Type::flag_type lhs, const Type& rhs) {                \
-    return rhs | lhs;                                                          \
-  }                                                                            \
-  inline void operator|(Type::flag_type lhs, Type::mask_type rhs)              \
-      ALLOW_UNUSED;                                                            \
-  inline void operator|(Type::flag_type lhs, Type::mask_type rhs) {}           \
-  inline Type operator^(Type::flag_type lhs, Type::flag_type rhs)              \
-      ALLOW_UNUSED WARN_UNUSED_RESULT;                                         \
-  inline Type operator^(Type::flag_type lhs, Type::flag_type rhs) {            \
-    return Type(lhs) ^ rhs;                                                    \
-  } inline Type operator^(Type::flag_type lhs, const Type& rhs)                \
-      ALLOW_UNUSED WARN_UNUSED_RESULT;                                         \
-  inline Type operator^(Type::flag_type lhs, const Type& rhs) {                \
-    return rhs ^ lhs;                                                          \
-  } inline void operator^(Type::flag_type lhs, Type::mask_type rhs)            \
-      ALLOW_UNUSED;                                                            \
+#define DEFINE_OPERATORS_FOR_FLAGS(Type)                                      \
+  inline Type operator&(                                                      \
+      Type::flag_type lhs,                                                    \
+      Type::flag_type rhs)ALLOW_UNUSED_TYPE WARN_UNUSED_RESULT;               \
+  inline Type operator&(Type::flag_type lhs, Type::flag_type rhs) {           \
+    return Type(lhs) & rhs;                                                   \
+  }                                                                           \
+  inline Type operator&(Type::flag_type lhs,                                  \
+                        const Type& rhs)ALLOW_UNUSED_TYPE WARN_UNUSED_RESULT; \
+  inline Type operator&(Type::flag_type lhs, const Type& rhs) {               \
+    return rhs & lhs;                                                         \
+  }                                                                           \
+  inline void operator&(Type::flag_type lhs,                                  \
+                        Type::mask_type rhs)ALLOW_UNUSED_TYPE;                \
+  inline void operator&(Type::flag_type lhs, Type::mask_type rhs) {}          \
+  inline Type operator|(Type::flag_type lhs, Type::flag_type rhs)             \
+      ALLOW_UNUSED_TYPE WARN_UNUSED_RESULT;                                   \
+  inline Type operator|(Type::flag_type lhs, Type::flag_type rhs) {           \
+    return Type(lhs) | rhs;                                                   \
+  }                                                                           \
+  inline Type operator|(Type::flag_type lhs, const Type& rhs)                 \
+      ALLOW_UNUSED_TYPE WARN_UNUSED_RESULT;                                   \
+  inline Type operator|(Type::flag_type lhs, const Type& rhs) {               \
+    return rhs | lhs;                                                         \
+  }                                                                           \
+  inline void operator|(Type::flag_type lhs, Type::mask_type rhs)             \
+      ALLOW_UNUSED_TYPE;                                                      \
+  inline void operator|(Type::flag_type lhs, Type::mask_type rhs) {}          \
+  inline Type operator^(Type::flag_type lhs, Type::flag_type rhs)             \
+      ALLOW_UNUSED_TYPE WARN_UNUSED_RESULT;                                   \
+  inline Type operator^(Type::flag_type lhs, Type::flag_type rhs) {           \
+    return Type(lhs) ^ rhs;                                                   \
+  } inline Type operator^(Type::flag_type lhs, const Type& rhs)               \
+      ALLOW_UNUSED_TYPE WARN_UNUSED_RESULT;                                   \
+  inline Type operator^(Type::flag_type lhs, const Type& rhs) {               \
+    return rhs ^ lhs;                                                         \
+  } inline void operator^(Type::flag_type lhs, Type::mask_type rhs)           \
+      ALLOW_UNUSED_TYPE;                                                      \
   inline void operator^(Type::flag_type lhs, Type::mask_type rhs) {}
 
 }  // namespace base
diff --git a/src/base/functional.cc b/src/base/functional.cc
new file mode 100644
index 0000000..d212912
--- /dev/null
+++ b/src/base/functional.cc
@@ -0,0 +1,111 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// This also contains public domain code from MurmurHash. From the
+// MurmurHash header:
+//
+// MurmurHash3 was written by Austin Appleby, and is placed in the public
+// domain. The author hereby disclaims copyright to this source code.
+
+#include "src/base/functional.h"
+
+#include <limits>
+
+#include "src/base/bits.h"
+
+namespace v8 {
+namespace base {
+
+namespace {
+
+// Thomas Wang, Integer Hash Functions.
+// https://gist.github.com/badboy/6267743
+template <typename T>
+V8_INLINE size_t hash_value_unsigned(T v) {
+  switch (sizeof(T)) {
+    case 4: {
+      // "32 bit Mix Functions"
+      v = ~v + (v << 15);  // v = (v << 15) - v - 1;
+      v = v ^ (v >> 12);
+      v = v + (v << 2);
+      v = v ^ (v >> 4);
+      v = v * 2057;  // v = (v + (v << 3)) + (v << 11);
+      v = v ^ (v >> 16);
+      return static_cast<size_t>(v);
+    }
+    case 8: {
+      switch (sizeof(size_t)) {
+        case 4: {
+          // "64 bit to 32 bit Hash Functions"
+          v = ~v + (v << 18);  // v = (v << 18) - v - 1;
+          v = v ^ (v >> 31);
+          v = v * 21;  // v = (v + (v << 2)) + (v << 4);
+          v = v ^ (v >> 11);
+          v = v + (v << 6);
+          v = v ^ (v >> 22);
+          return static_cast<size_t>(v);
+        }
+        case 8: {
+          // "64 bit Mix Functions"
+          v = ~v + (v << 21);  // v = (v << 21) - v - 1;
+          v = v ^ (v >> 24);
+          v = (v + (v << 3)) + (v << 8);  // v * 265
+          v = v ^ (v >> 14);
+          v = (v + (v << 2)) + (v << 4);  // v * 21
+          v = v ^ (v >> 28);
+          v = v + (v << 31);
+          return static_cast<size_t>(v);
+        }
+      }
+    }
+  }
+  UNREACHABLE();
+  return static_cast<size_t>(v);
+}
+
+}  // namespace
+
+
+// This code was taken from MurmurHash.
+size_t hash_combine(size_t seed, size_t value) {
+#if V8_HOST_ARCH_32_BIT
+  const uint32_t c1 = 0xcc9e2d51;
+  const uint32_t c2 = 0x1b873593;
+
+  value *= c1;
+  value = bits::RotateRight32(value, 15);
+  value *= c2;
+
+  seed ^= value;
+  seed = bits::RotateRight32(seed, 13);
+  seed = seed * 5 + 0xe6546b64;
+#else
+  const uint64_t m = V8_UINT64_C(0xc6a4a7935bd1e995);
+  const uint32_t r = 47;
+
+  value *= m;
+  value ^= value >> r;
+  value *= m;
+
+  seed ^= value;
+  seed *= m;
+#endif  // V8_HOST_ARCH_32_BIT
+  return seed;
+}
+
+
+size_t hash_value(unsigned int v) { return hash_value_unsigned(v); }
+
+
+size_t hash_value(unsigned long v) {  // NOLINT(runtime/int)
+  return hash_value_unsigned(v);
+}
+
+
+size_t hash_value(unsigned long long v) {  // NOLINT(runtime/int)
+  return hash_value_unsigned(v);
+}
+
+}  // namespace base
+}  // namespace v8
diff --git a/src/base/functional.h b/src/base/functional.h
new file mode 100644
index 0000000..ff0d807
--- /dev/null
+++ b/src/base/functional.h
@@ -0,0 +1,227 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_BASE_FUNCTIONAL_H_
+#define V8_BASE_FUNCTIONAL_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <cstddef>
+#include <cstring>
+#include <functional>
+#include <utility>
+
+#include "src/base/macros.h"
+
+namespace v8 {
+namespace base {
+
+// base::hash is an implementation of the hash function object specified by
+// C++11. It was designed to be compatible with std::hash (in C++11) and
+// boost:hash (which in turn is based on the hash function object specified by
+// the Draft Technical Report on C++ Library Extensions (TR1)).
+//
+// base::hash is implemented by calling the hash_value function. The namespace
+// isn't specified so that it can detect overloads via argument dependant
+// lookup. So if there is a free function hash_value in the same namespace as a
+// custom type, it will get called.
+//
+// If users are asked to implement a hash function for their own types with no
+// guidance, they generally write bad hash functions. Instead, we provide  a
+// simple function base::hash_combine to pass hash-relevant member variables
+// into, in order to define a decent hash function. base::hash_combine is
+// declared as:
+//
+//   template<typename T, typename... Ts>
+//   size_t hash_combine(const T& v, const Ts& ...vs);
+//
+// Consider the following example:
+//
+//   namespace v8 {
+//   namespace bar {
+//     struct Point { int x; int y; };
+//     size_t hash_value(Point const& p) {
+//       return base::hash_combine(p.x, p.y);
+//     }
+//   }
+//
+//   namespace foo {
+//     void DoSomeWork(bar::Point const& p) {
+//       base::hash<bar::Point> h;
+//       ...
+//       size_t hash_code = h(p);  // calls bar::hash_value(Point const&)
+//       ...
+//     }
+//   }
+//   }
+//
+// Based on the "Hashing User-Defined Types in C++1y" proposal from Jeffrey
+// Yasskin and Chandler Carruth, see
+// http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2012/n3333.html.
+
+template <typename>
+struct hash;
+
+
+V8_INLINE size_t hash_combine() { return 0u; }
+V8_INLINE size_t hash_combine(size_t seed) { return seed; }
+size_t hash_combine(size_t seed, size_t value);
+template <typename T, typename... Ts>
+V8_INLINE size_t hash_combine(T const& v, Ts const&... vs) {
+  return hash_combine(hash_combine(vs...), hash<T>()(v));
+}
+
+
+template <typename Iterator>
+V8_INLINE size_t hash_range(Iterator first, Iterator last) {
+  size_t seed = 0;
+  for (; first != last; ++first) {
+    seed = hash_combine(seed, *first);
+  }
+  return seed;
+}
+
+
+#define V8_BASE_HASH_VALUE_TRIVIAL(type) \
+  V8_INLINE size_t hash_value(type v) { return static_cast<size_t>(v); }
+V8_BASE_HASH_VALUE_TRIVIAL(bool)
+V8_BASE_HASH_VALUE_TRIVIAL(unsigned char)
+V8_BASE_HASH_VALUE_TRIVIAL(unsigned short)  // NOLINT(runtime/int)
+#undef V8_BASE_HASH_VALUE_TRIVIAL
+
+size_t hash_value(unsigned int);
+size_t hash_value(unsigned long);       // NOLINT(runtime/int)
+size_t hash_value(unsigned long long);  // NOLINT(runtime/int)
+
+#define V8_BASE_HASH_VALUE_SIGNED(type)            \
+  V8_INLINE size_t hash_value(signed type v) {     \
+    return hash_value(bit_cast<unsigned type>(v)); \
+  }
+V8_BASE_HASH_VALUE_SIGNED(char)
+V8_BASE_HASH_VALUE_SIGNED(short)      // NOLINT(runtime/int)
+V8_BASE_HASH_VALUE_SIGNED(int)        // NOLINT(runtime/int)
+V8_BASE_HASH_VALUE_SIGNED(long)       // NOLINT(runtime/int)
+V8_BASE_HASH_VALUE_SIGNED(long long)  // NOLINT(runtime/int)
+#undef V8_BASE_HASH_VALUE_SIGNED
+
+V8_INLINE size_t hash_value(float v) {
+  // 0 and -0 both hash to zero.
+  return v != 0.0f ? hash_value(bit_cast<uint32_t>(v)) : 0;
+}
+
+V8_INLINE size_t hash_value(double v) {
+  // 0 and -0 both hash to zero.
+  return v != 0.0 ? hash_value(bit_cast<uint64_t>(v)) : 0;
+}
+
+template <typename T, size_t N>
+V8_INLINE size_t hash_value(const T (&v)[N]) {
+  return hash_range(v, v + N);
+}
+
+template <typename T, size_t N>
+V8_INLINE size_t hash_value(T (&v)[N]) {
+  return hash_range(v, v + N);
+}
+
+template <typename T>
+V8_INLINE size_t hash_value(T* const& v) {
+  return hash_value(bit_cast<uintptr_t>(v));
+}
+
+template <typename T1, typename T2>
+V8_INLINE size_t hash_value(std::pair<T1, T2> const& v) {
+  return hash_combine(v.first, v.second);
+}
+
+
+template <typename T>
+struct hash : public std::unary_function<T, size_t> {
+  V8_INLINE size_t operator()(T const& v) const { return hash_value(v); }
+};
+
+#define V8_BASE_HASH_SPECIALIZE(type)                            \
+  template <>                                                    \
+  struct hash<type> : public std::unary_function<type, size_t> { \
+    V8_INLINE size_t operator()(type const v) const {            \
+      return ::v8::base::hash_value(v);                          \
+    }                                                            \
+  };
+V8_BASE_HASH_SPECIALIZE(bool)
+V8_BASE_HASH_SPECIALIZE(signed char)
+V8_BASE_HASH_SPECIALIZE(unsigned char)
+V8_BASE_HASH_SPECIALIZE(short)           // NOLINT(runtime/int)
+V8_BASE_HASH_SPECIALIZE(unsigned short)  // NOLINT(runtime/int)
+V8_BASE_HASH_SPECIALIZE(int)
+V8_BASE_HASH_SPECIALIZE(unsigned int)
+V8_BASE_HASH_SPECIALIZE(long)                // NOLINT(runtime/int)
+V8_BASE_HASH_SPECIALIZE(unsigned long)       // NOLINT(runtime/int)
+V8_BASE_HASH_SPECIALIZE(long long)           // NOLINT(runtime/int)
+V8_BASE_HASH_SPECIALIZE(unsigned long long)  // NOLINT(runtime/int)
+V8_BASE_HASH_SPECIALIZE(float)
+V8_BASE_HASH_SPECIALIZE(double)
+#undef V8_BASE_HASH_SPECIALIZE
+
+template <typename T>
+struct hash<T*> : public std::unary_function<T*, size_t> {
+  V8_INLINE size_t operator()(T* const v) const {
+    return ::v8::base::hash_value(v);
+  }
+};
+
+
+// base::bit_equal_to is a function object class for bitwise equality
+// comparison, similar to std::equal_to, except that the comparison is performed
+// on the bit representation of the operands.
+//
+// base::bit_hash is a function object class for bitwise hashing, similar to
+// base::hash. It can be used together with base::bit_equal_to to implement a
+// hash data structure based on the bitwise representation of types.
+
+template <typename T>
+struct bit_equal_to : public std::binary_function<T, T, bool> {};
+
+template <typename T>
+struct bit_hash : public std::unary_function<T, size_t> {};
+
+#define V8_BASE_BIT_SPECIALIZE_TRIVIAL(type)                 \
+  template <>                                                \
+  struct bit_equal_to<type> : public std::equal_to<type> {}; \
+  template <>                                                \
+  struct bit_hash<type> : public hash<type> {};
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(signed char)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned char)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(short)           // NOLINT(runtime/int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned short)  // NOLINT(runtime/int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(long)                // NOLINT(runtime/int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned long)       // NOLINT(runtime/int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(long long)           // NOLINT(runtime/int)
+V8_BASE_BIT_SPECIALIZE_TRIVIAL(unsigned long long)  // NOLINT(runtime/int)
+#undef V8_BASE_BIT_SPECIALIZE_TRIVIAL
+
+#define V8_BASE_BIT_SPECIALIZE_BIT_CAST(type, btype)                          \
+  template <>                                                                 \
+  struct bit_equal_to<type> : public std::binary_function<type, type, bool> { \
+    V8_INLINE bool operator()(type lhs, type rhs) const {                     \
+      return bit_cast<btype>(lhs) == bit_cast<btype>(rhs);                    \
+    }                                                                         \
+  };                                                                          \
+  template <>                                                                 \
+  struct bit_hash<type> : public std::unary_function<type, size_t> {          \
+    V8_INLINE size_t operator()(type v) const {                               \
+      hash<btype> h;                                                          \
+      return h(bit_cast<btype>(v));                                           \
+    }                                                                         \
+  };
+V8_BASE_BIT_SPECIALIZE_BIT_CAST(float, uint32_t)
+V8_BASE_BIT_SPECIALIZE_BIT_CAST(double, uint64_t)
+#undef V8_BASE_BIT_SPECIALIZE_BIT_CAST
+
+}  // namespace base
+}  // namespace v8
+
+#endif  // V8_BASE_FUNCTIONAL_H_
diff --git a/src/base/iterator.h b/src/base/iterator.h
new file mode 100644
index 0000000..e380dc3
--- /dev/null
+++ b/src/base/iterator.h
@@ -0,0 +1,56 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_BASE_ITERATOR_H_
+#define V8_BASE_ITERATOR_H_
+
+#include <iterator>
+
+#include "src/base/macros.h"
+
+namespace v8 {
+namespace base {
+
+// The intention of the base::iterator_range class is to encapsulate two
+// iterators so that the range defined by the iterators can be used like
+// a regular STL container (actually only a subset of the full container
+// functionality is available usually).
+template <typename ForwardIterator>
+class iterator_range {
+ public:
+  typedef ForwardIterator iterator;
+  typedef ForwardIterator const_iterator;
+  typedef typename std::iterator_traits<iterator>::pointer pointer;
+  typedef typename std::iterator_traits<iterator>::reference reference;
+  typedef typename std::iterator_traits<iterator>::value_type value_type;
+  typedef
+      typename std::iterator_traits<iterator>::difference_type difference_type;
+
+  iterator_range() : begin_(), end_() {}
+  template <typename ForwardIterator2>
+  iterator_range(ForwardIterator2 const& begin, ForwardIterator2 const& end)
+      : begin_(begin), end_(end) {}
+
+  iterator begin() { return begin_; }
+  iterator end() { return end_; }
+  const_iterator begin() const { return begin_; }
+  const_iterator end() const { return end_; }
+  const_iterator cbegin() const { return begin_; }
+  const_iterator cend() const { return end_; }
+
+  bool empty() const { return cbegin() == cend(); }
+
+  // Random Access iterators only.
+  reference operator[](difference_type n) { return begin()[n]; }
+  difference_type size() const { return cend() - cbegin(); }
+
+ private:
+  const_iterator const begin_;
+  const_iterator const end_;
+};
+
+}  // namespace base
+}  // namespace v8
+
+#endif  // V8_BASE_ITERATOR_H_
diff --git a/src/base/logging.h b/src/base/logging.h
index 8e24bb0..83c1bb6 100644
--- a/src/base/logging.h
+++ b/src/base/logging.h
@@ -5,9 +5,9 @@
 #ifndef V8_BASE_LOGGING_H_
 #define V8_BASE_LOGGING_H_
 
+#include <stdint.h>
 #include <string.h>
 
-#include "include/v8stdint.h"
 #include "src/base/build_config.h"
 
 extern "C" void V8_Fatal(const char* file, int line, const char* format, ...);
diff --git a/src/base/macros.h b/src/base/macros.h
index cef088c..371d7da 100644
--- a/src/base/macros.h
+++ b/src/base/macros.h
@@ -5,9 +5,11 @@
 #ifndef V8_BASE_MACROS_H_
 #define V8_BASE_MACROS_H_
 
+#include <stddef.h>
+#include <stdint.h>
+
 #include <cstring>
 
-#include "include/v8stdint.h"
 #include "src/base/build_config.h"
 #include "src/base/compiler-specific.h"
 #include "src/base/logging.h"
@@ -18,11 +20,13 @@
 // corresponds to 'offsetof' (in stddef.h), except that it doesn't
 // use 0 or NULL, which causes a problem with the compiler warnings
 // we have enabled (which is also why 'offsetof' doesn't seem to work).
-// Here we simply use the non-zero value 4, which seems to work.
-#define OFFSET_OF(type, field)                                          \
-  (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(4)->field)) - 4)
+// Here we simply use the aligned, non-zero value 16.
+#define OFFSET_OF(type, field) \
+  (reinterpret_cast<intptr_t>(&(reinterpret_cast<type*>(16)->field)) - 16)
 
 
+#if V8_OS_NACL
+
 // ARRAYSIZE_UNSAFE performs essentially the same calculation as arraysize,
 // but can be used on anonymous types or types defined inside
 // functions.  It's less safe than arraysize as it accepts some
@@ -63,9 +67,6 @@
   ((sizeof(a) / sizeof(*(a))) / \
    static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))  // NOLINT
 
-
-#if V8_OS_NACL
-
 // TODO(bmeurer): For some reason, the NaCl toolchain cannot handle the correct
 // definition of arraysize() below, so we have to use the unsafe version for
 // now.
@@ -130,7 +131,7 @@
 
 #define COMPILE_ASSERT(expr, msg)                \
   typedef CompileAssert<static_cast<bool>(expr)> \
-      msg[static_cast<bool>(expr) ? 1 : -1] ALLOW_UNUSED
+      msg[static_cast<bool>(expr) ? 1 : -1] ALLOW_UNUSED_TYPE
 
 // Implementation details of COMPILE_ASSERT:
 //
@@ -150,23 +151,11 @@
 //     COMPILE_ASSERT(foo, msg); // not supposed to compile as foo is
 //                               // not a compile-time constant.
 //
-// - By using the type CompileAssert<(bool(expr))>, we ensures that
+// - By using the type CompileAssert<static_cast<bool>(expr)>, we ensure that
 //   expr is a compile-time constant.  (Template arguments must be
 //   determined at compile-time.)
 //
-// - The outer parentheses in CompileAssert<(bool(expr))> are necessary
-//   to work around a bug in gcc 3.4.4 and 4.0.1.  If we had written
-//
-//     CompileAssert<bool(expr)>
-//
-//   instead, these compilers will refuse to compile
-//
-//     COMPILE_ASSERT(5 > 0, some_message);
-//
-//   (They seem to think the ">" in "5 > 0" marks the end of the
-//   template argument list.)
-//
-// - The array size is (bool(expr) ? 1 : -1), instead of simply
+// - The array size is (static_cast<bool>(expr) ? 1 : -1), instead of simply
 //
 //     ((expr) ? 1 : -1).
 //
@@ -308,10 +297,10 @@
 // actually causes each use to introduce a new defined type with a
 // name depending on the source line.
 template <int> class StaticAssertionHelper { };
-#define STATIC_ASSERT(test)                                                    \
-  typedef                                                                     \
-    StaticAssertionHelper<sizeof(StaticAssertion<static_cast<bool>((test))>)> \
-    SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__) ALLOW_UNUSED
+#define STATIC_ASSERT(test)                               \
+  typedef StaticAssertionHelper<                          \
+      sizeof(StaticAssertion<static_cast<bool>((test))>)> \
+      SEMI_STATIC_JOIN(__StaticAssertTypedef__, __LINE__) ALLOW_UNUSED_TYPE
 
 #endif
 
@@ -408,4 +397,22 @@
   return RoundDown<T>(static_cast<T>(x + m - 1), m);
 }
 
+
+namespace v8 {
+namespace base {
+
+// TODO(yangguo): This is a poor man's replacement for std::is_fundamental,
+// which requires C++11. Switch to std::is_fundamental once possible.
+template <typename T>
+inline bool is_fundamental() {
+  return false;
+}
+
+template <>
+inline bool is_fundamental<uint8_t>() {
+  return true;
+}
+}
+}  // namespace v8::base
+
 #endif   // V8_BASE_MACROS_H_
diff --git a/src/base/once.h b/src/base/once.h
index a8e8437..6bf741d 100644
--- a/src/base/once.h
+++ b/src/base/once.h
@@ -52,6 +52,8 @@
 #ifndef V8_BASE_ONCE_H_
 #define V8_BASE_ONCE_H_
 
+#include <stddef.h>
+
 #include "src/base/atomicops.h"
 
 namespace v8 {
diff --git a/src/base/platform/platform-freebsd.cc b/src/base/platform/platform-freebsd.cc
index 507b946..58316f8 100644
--- a/src/base/platform/platform-freebsd.cc
+++ b/src/base/platform/platform-freebsd.cc
@@ -141,7 +141,7 @@
     if (bytes_read < 8) break;
     unsigned end = StringToLong(addr_buffer);
     char buffer[MAP_LENGTH];
-    int bytes_read = -1;
+    bytes_read = -1;
     do {
       bytes_read++;
       if (bytes_read >= MAP_LENGTH - 1)
diff --git a/src/base/platform/platform-linux.cc b/src/base/platform/platform-linux.cc
index eff5ced..36857e6 100644
--- a/src/base/platform/platform-linux.cc
+++ b/src/base/platform/platform-linux.cc
@@ -8,10 +8,10 @@
 #include <pthread.h>
 #include <semaphore.h>
 #include <signal.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <sys/resource.h>
 #include <sys/time.h>
-#include <sys/types.h>
 
 // Ubuntu Dapper requires memory pages to be marked as
 // executable. Otherwise, OS raises an exception when executing code
@@ -109,7 +109,7 @@
   if (std::isnan(time)) return "";
   time_t tv = static_cast<time_t>(std::floor(time/msPerSecond));
   struct tm* t = localtime(&tv);
-  if (NULL == t) return "";
+  if (!t || !t->tm_zone) return "";
   return t->tm_zone;
 #endif
 }
diff --git a/src/base/platform/platform-posix.cc b/src/base/platform/platform-posix.cc
index 99feb65..64aed2b 100644
--- a/src/base/platform/platform-posix.cc
+++ b/src/base/platform/platform-posix.cc
@@ -13,6 +13,7 @@
 #include <pthread_np.h>  // for pthread_set_name_np
 #endif
 #include <sched.h>  // for sched_yield
+#include <stdio.h>
 #include <time.h>
 #include <unistd.h>
 
@@ -253,20 +254,14 @@
 
 
 int OS::GetCurrentThreadId() {
-#if defined(ANDROID)
-#if defined(__APPLE__)
-  uint64_t owner;
-  pthread_threadid_np(NULL, &owner);  // Requires Mac OS 10.6
-  return owner;
-#else
+#if V8_OS_MACOSX || (V8_OS_ANDROID && defined(__APPLE__))
+  return static_cast<int>(pthread_mach_thread_np(pthread_self()));
+#elif V8_OS_LINUX
   return static_cast<int>(syscall(__NR_gettid));
-#endif
-#elif defined(SYS_gettid)
-  return static_cast<int>(syscall(SYS_gettid));
+#elif V8_OS_ANDROID
+  return static_cast<int>(gettid());
 #else
-  // PNaCL doesn't have a way to get an integral thread ID, but it doesn't
-  // really matter, because we only need it in PerfJitLogger::LogRecordedBuffer.
-  return 0;
+  return static_cast<int>(reinterpret_cast<intptr_t>(pthread_self()));
 #endif
 }
 
diff --git a/src/base/platform/platform-solaris.cc b/src/base/platform/platform-solaris.cc
index b9ef465..b9a2ec8 100644
--- a/src/base/platform/platform-solaris.cc
+++ b/src/base/platform/platform-solaris.cc
@@ -31,26 +31,6 @@
 #include "src/base/platform/platform.h"
 
 
-// It seems there is a bug in some Solaris distributions (experienced in
-// SunOS 5.10 Generic_141445-09) which make it difficult or impossible to
-// access signbit() despite the availability of other C99 math functions.
-#ifndef signbit
-namespace std {
-// Test sign - usually defined in math.h
-int signbit(double x) {
-  // We need to take care of the special case of both positive and negative
-  // versions of zero.
-  if (x == 0) {
-    return fpclass(x) & FP_NZERO;
-  } else {
-    // This won't detect negative NaN but that should be okay since we don't
-    // assume that behavior.
-    return x < 0;
-  }
-}
-}  // namespace std
-#endif  // signbit
-
 namespace v8 {
 namespace base {
 
diff --git a/src/base/platform/platform-unittest.cc b/src/base/platform/platform-unittest.cc
deleted file mode 100644
index 06fbee0..0000000
--- a/src/base/platform/platform-unittest.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/base/platform/platform.h"
-
-#if V8_OS_POSIX
-#include <unistd.h>  // NOLINT
-#endif
-
-#if V8_OS_WIN
-#include "src/base/win32-headers.h"
-#endif
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace v8 {
-namespace base {
-
-TEST(OS, GetCurrentProcessId) {
-#if V8_OS_POSIX
-  EXPECT_EQ(static_cast<int>(getpid()), OS::GetCurrentProcessId());
-#endif
-
-#if V8_OS_WIN
-  EXPECT_EQ(static_cast<int>(::GetCurrentProcessId()),
-            OS::GetCurrentProcessId());
-#endif
-}
-
-
-namespace {
-
-class SelfJoinThread FINAL : public Thread {
- public:
-  SelfJoinThread() : Thread(Options("SelfJoinThread")) {}
-  virtual void Run() OVERRIDE { Join(); }
-};
-
-}  // namespace
-
-
-TEST(Thread, SelfJoin) {
-  SelfJoinThread thread;
-  thread.Start();
-  thread.Join();
-}
-
-
-namespace {
-
-class ThreadLocalStorageTest : public Thread, public ::testing::Test {
- public:
-  ThreadLocalStorageTest() : Thread(Options("ThreadLocalStorageTest")) {
-    for (size_t i = 0; i < arraysize(keys_); ++i) {
-      keys_[i] = Thread::CreateThreadLocalKey();
-    }
-  }
-  ~ThreadLocalStorageTest() {
-    for (size_t i = 0; i < arraysize(keys_); ++i) {
-      Thread::DeleteThreadLocalKey(keys_[i]);
-    }
-  }
-
-  virtual void Run() FINAL OVERRIDE {
-    for (size_t i = 0; i < arraysize(keys_); i++) {
-      CHECK(!Thread::HasThreadLocal(keys_[i]));
-    }
-    for (size_t i = 0; i < arraysize(keys_); i++) {
-      Thread::SetThreadLocal(keys_[i], GetValue(i));
-    }
-    for (size_t i = 0; i < arraysize(keys_); i++) {
-      CHECK(Thread::HasThreadLocal(keys_[i]));
-    }
-    for (size_t i = 0; i < arraysize(keys_); i++) {
-      CHECK_EQ(GetValue(i), Thread::GetThreadLocal(keys_[i]));
-      CHECK_EQ(GetValue(i), Thread::GetExistingThreadLocal(keys_[i]));
-    }
-    for (size_t i = 0; i < arraysize(keys_); i++) {
-      Thread::SetThreadLocal(keys_[i], GetValue(arraysize(keys_) - i - 1));
-    }
-    for (size_t i = 0; i < arraysize(keys_); i++) {
-      CHECK(Thread::HasThreadLocal(keys_[i]));
-    }
-    for (size_t i = 0; i < arraysize(keys_); i++) {
-      CHECK_EQ(GetValue(arraysize(keys_) - i - 1),
-               Thread::GetThreadLocal(keys_[i]));
-      CHECK_EQ(GetValue(arraysize(keys_) - i - 1),
-               Thread::GetExistingThreadLocal(keys_[i]));
-    }
-  }
-
- private:
-  static void* GetValue(size_t x) {
-    return reinterpret_cast<void*>(static_cast<uintptr_t>(x + 1));
-  }
-
-  Thread::LocalStorageKey keys_[256];
-};
-
-}  // namespace
-
-
-TEST_F(ThreadLocalStorageTest, DoTest) {
-  Run();
-  Start();
-  Join();
-}
-
-}  // namespace base
-}  // namespace v8
diff --git a/src/base/platform/platform-win32.cc b/src/base/platform/platform-win32.cc
index 10f89de..d68e861 100644
--- a/src/base/platform/platform-win32.cc
+++ b/src/base/platform/platform-win32.cc
@@ -15,9 +15,7 @@
 #endif  // MINGW_HAS_SECURE_API
 #endif  // __MINGW32__
 
-#ifdef _MSC_VER
 #include <limits>
-#endif
 
 #include "src/base/win32-headers.h"
 
@@ -28,16 +26,6 @@
 #include "src/base/platform/time.h"
 #include "src/base/utils/random-number-generator.h"
 
-#ifdef _MSC_VER
-
-// Case-insensitive bounded string comparisons. Use stricmp() on Win32. Usually
-// defined in strings.h.
-int strncasecmp(const char* s1, const char* s2, int n) {
-  return _strnicmp(s1, s2, n);
-}
-
-#endif  // _MSC_VER
-
 
 // Extra functions for MinGW. Most of these are the _s functions which are in
 // the Microsoft Visual Studio C++ CRT.
@@ -367,8 +355,8 @@
   cache->InitializeIfNeeded();
 
   Win32Time rounded_to_second(*this);
-  rounded_to_second.t() = rounded_to_second.t() / 1000 / kTimeScaler *
-      1000 * kTimeScaler;
+  rounded_to_second.t() =
+      rounded_to_second.t() / 1000 / kTimeScaler * 1000 * kTimeScaler;
   // Convert to local time using POSIX localtime function.
   // Windows XP Service Pack 3 made SystemTimeToTzSpecificLocalTime()
   // very slow.  Other browsers use localtime().
@@ -832,7 +820,7 @@
 
 
 void OS::DebugBreak() {
-#ifdef _MSC_VER
+#if V8_CC_MSVC
   // To avoid Visual Studio runtime support the following code can be used
   // instead
   // __asm { int 3 }
@@ -1175,11 +1163,7 @@
 
 
 double OS::nan_value() {
-#ifdef _MSC_VER
   return std::numeric_limits<double>::quiet_NaN();
-#else  // _MSC_VER
-  return NAN;
-#endif  // _MSC_VER
 }
 
 
diff --git a/src/base/platform/platform.h b/src/base/platform/platform.h
index 9e20c08..0bf1027 100644
--- a/src/base/platform/platform.h
+++ b/src/base/platform/platform.h
@@ -21,7 +21,7 @@
 #ifndef V8_BASE_PLATFORM_PLATFORM_H_
 #define V8_BASE_PLATFORM_PLATFORM_H_
 
-#include <stdarg.h>
+#include <cstdarg>
 #include <string>
 #include <vector>
 
@@ -29,48 +29,10 @@
 #include "src/base/platform/mutex.h"
 #include "src/base/platform/semaphore.h"
 
-#ifdef __sun
-# ifndef signbit
-namespace std {
-int signbit(double x);
-}
-# endif
-#endif
-
 #if V8_OS_QNX
 #include "src/base/qnx-math.h"
 #endif
 
-// Microsoft Visual C++ specific stuff.
-#if V8_LIBC_MSVCRT
-
-#include "src/base/win32-headers.h"
-#include "src/base/win32-math.h"
-
-int strncasecmp(const char* s1, const char* s2, int n);
-
-// Visual C++ 2013 and higher implement this function.
-#if (_MSC_VER < 1800)
-inline int lrint(double flt) {
-  int intgr;
-#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
-  __asm {
-    fld flt
-    fistp intgr
-  };
-#else
-  intgr = static_cast<int>(flt + 0.5);
-  if ((intgr & 1) != 0 && intgr - flt == 0.5) {
-    // If the number is halfway between two integers, round to the even one.
-    intgr--;
-  }
-#endif
-  return intgr;
-}
-#endif  // _MSC_VER < 1800
-
-#endif  // V8_LIBC_MSVCRT
-
 namespace v8 {
 namespace base {
 
@@ -79,7 +41,7 @@
 
 #ifndef V8_NO_FAST_TLS
 
-#if defined(_MSC_VER) && (V8_HOST_ARCH_IA32)
+#if V8_CC_MSVC && V8_HOST_ARCH_IA32
 
 #define V8_FAST_TLS_SUPPORTED 1
 
diff --git a/src/base/platform/time.cc b/src/base/platform/time.cc
index d47ccaf..40dd188 100644
--- a/src/base/platform/time.cc
+++ b/src/base/platform/time.cc
@@ -401,7 +401,7 @@
   }
   virtual ~HighResolutionTickClock() {}
 
-  virtual int64_t Now() OVERRIDE {
+  int64_t Now() OVERRIDE {
     LARGE_INTEGER now;
     BOOL result = QueryPerformanceCounter(&now);
     DCHECK(result);
@@ -419,9 +419,7 @@
     return ticks + 1;
   }
 
-  virtual bool IsHighResolution() OVERRIDE {
-    return true;
-  }
+  bool IsHighResolution() OVERRIDE { return true; }
 
  private:
   int64_t ticks_per_second_;
@@ -435,7 +433,7 @@
   RolloverProtectedTickClock() : last_seen_now_(0), rollover_ms_(1) {}
   virtual ~RolloverProtectedTickClock() {}
 
-  virtual int64_t Now() OVERRIDE {
+  int64_t Now() OVERRIDE {
     LockGuard<Mutex> lock_guard(&mutex_);
     // We use timeGetTime() to implement TimeTicks::Now(), which rolls over
     // every ~49.7 days. We try to track rollover ourselves, which works if
@@ -454,9 +452,7 @@
     return (now + rollover_ms_) * Time::kMicrosecondsPerMillisecond;
   }
 
-  virtual bool IsHighResolution() OVERRIDE {
-    return false;
-  }
+  bool IsHighResolution() OVERRIDE { return false; }
 
  private:
   Mutex mutex_;
diff --git a/src/base/sys-info.cc b/src/base/sys-info.cc
index 06c4f24..c665771 100644
--- a/src/base/sys-info.cc
+++ b/src/base/sys-info.cc
@@ -34,14 +34,12 @@
   int ncpu = 0;
   size_t len = sizeof(ncpu);
   if (sysctl(mib, arraysize(mib), &ncpu, &len, NULL, 0) != 0) {
-    UNREACHABLE();
     return 1;
   }
   return ncpu;
 #elif V8_OS_POSIX
   long result = sysconf(_SC_NPROCESSORS_ONLN);  // NOLINT(runtime/int)
   if (result == -1) {
-    UNREACHABLE();
     return 1;
   }
   return static_cast<int>(result);
@@ -60,7 +58,6 @@
   int64_t memsize = 0;
   size_t len = sizeof(memsize);
   if (sysctl(mib, arraysize(mib), &memsize, &len, NULL, 0) != 0) {
-    UNREACHABLE();
     return 0;
   }
   return memsize;
@@ -70,7 +67,6 @@
   sysctlbyname("vm.stats.vm.v_page_count", &pages, &size, NULL, 0);
   sysctlbyname("vm.stats.vm.v_page_size", &page_size, &size, NULL, 0);
   if (pages == -1 || page_size == -1) {
-    UNREACHABLE();
     return 0;
   }
   return static_cast<int64_t>(pages) * page_size;
@@ -78,7 +74,6 @@
   MEMORYSTATUSEX memory_info;
   memory_info.dwLength = sizeof(memory_info);
   if (!GlobalMemoryStatusEx(&memory_info)) {
-    UNREACHABLE();
     return 0;
   }
   int64_t result = static_cast<int64_t>(memory_info.ullTotalPhys);
@@ -87,7 +82,6 @@
 #elif V8_OS_QNX
   struct stat stat_buf;
   if (stat("/proc", &stat_buf) != 0) {
-    UNREACHABLE();
     return 0;
   }
   return static_cast<int64_t>(stat_buf.st_size);
@@ -98,7 +92,6 @@
   long pages = sysconf(_SC_PHYS_PAGES);    // NOLINT(runtime/int)
   long page_size = sysconf(_SC_PAGESIZE);  // NOLINT(runtime/int)
   if (pages == -1 || page_size == -1) {
-    UNREACHABLE();
     return 0;
   }
   return static_cast<int64_t>(pages) * page_size;
@@ -114,7 +107,6 @@
   struct rlimit rlim;
   int result = getrlimit(RLIMIT_DATA, &rlim);
   if (result != 0) {
-    UNREACHABLE();
     return 0;
   }
   return (rlim.rlim_cur == RLIM_INFINITY) ? 0 : rlim.rlim_cur;
diff --git a/src/base/sys-info.h b/src/base/sys-info.h
index d1658fc..377deb0 100644
--- a/src/base/sys-info.h
+++ b/src/base/sys-info.h
@@ -5,7 +5,7 @@
 #ifndef V8_BASE_SYS_INFO_H_
 #define V8_BASE_SYS_INFO_H_
 
-#include "include/v8stdint.h"
+#include <stdint.h>
 #include "src/base/compiler-specific.h"
 
 namespace v8 {
diff --git a/src/base/utils/random-number-generator.cc b/src/base/utils/random-number-generator.cc
index 9454936..29a48ff 100644
--- a/src/base/utils/random-number-generator.cc
+++ b/src/base/utils/random-number-generator.cc
@@ -79,7 +79,7 @@
 
 
 int RandomNumberGenerator::NextInt(int max) {
-  DCHECK_LE(0, max);
+  DCHECK_LT(0, max);
 
   // Fast path if max is a power of 2.
   if (IS_POWER_OF_TWO(max)) {
@@ -102,6 +102,13 @@
 }
 
 
+int64_t RandomNumberGenerator::NextInt64() {
+  uint64_t lo = bit_cast<unsigned>(Next(32));
+  uint64_t hi = bit_cast<unsigned>(Next(32));
+  return lo | (hi << 32);
+}
+
+
 void RandomNumberGenerator::NextBytes(void* buffer, size_t buflen) {
   for (size_t n = 0; n < buflen; ++n) {
     static_cast<uint8_t*>(buffer)[n] = static_cast<uint8_t>(Next(8));
diff --git a/src/base/utils/random-number-generator.h b/src/base/utils/random-number-generator.h
index 479423d..d1294f2 100644
--- a/src/base/utils/random-number-generator.h
+++ b/src/base/utils/random-number-generator.h
@@ -68,6 +68,13 @@
   // (exclusive), is pseudorandomly generated and returned.
   double NextDouble() WARN_UNUSED_RESULT;
 
+  // Returns the next pseudorandom, uniformly distributed int64 value from this
+  // random number generator's sequence. The general contract of |NextInt64()|
+  // is that one 64-bit int value is pseudorandomly generated and returned.
+  // All 2^64 possible integer values are produced with (approximately) equal
+  // probability.
+  int64_t NextInt64() WARN_UNUSED_RESULT;
+
   // Fills the elements of a specified array of bytes with random numbers.
   void NextBytes(void* buffer, size_t buflen);
 
diff --git a/src/base/win32-math.cc b/src/base/win32-math.cc
deleted file mode 100644
index d6fc78b..0000000
--- a/src/base/win32-math.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Extra POSIX/ANSI routines for Win32 when using Visual Studio C++. Please
-// refer to The Open Group Base Specification for specification of the correct
-// semantics for these functions.
-// (http://www.opengroup.org/onlinepubs/000095399/)
-#if defined(_MSC_VER) && (_MSC_VER < 1800)
-
-#include "src/base/win32-headers.h"
-#include <float.h>         // Required for DBL_MAX and on Win32 for finite()
-#include <limits.h>        // Required for INT_MAX etc.
-#include <cmath>
-#include "src/base/win32-math.h"
-
-#include "src/base/logging.h"
-
-
-namespace std {
-
-// Test for a NaN (not a number) value - usually defined in math.h
-int isnan(double x) {
-  return _isnan(x);
-}
-
-
-// Test for infinity - usually defined in math.h
-int isinf(double x) {
-  return (_fpclass(x) & (_FPCLASS_PINF | _FPCLASS_NINF)) != 0;
-}
-
-
-// Test for finite value - usually defined in math.h
-int isfinite(double x) {
-  return _finite(x);
-}
-
-
-// Test if x is less than y and both nominal - usually defined in math.h
-int isless(double x, double y) {
-  return isnan(x) || isnan(y) ? 0 : x < y;
-}
-
-
-// Test if x is greater than y and both nominal - usually defined in math.h
-int isgreater(double x, double y) {
-  return isnan(x) || isnan(y) ? 0 : x > y;
-}
-
-
-// Classify floating point number - usually defined in math.h
-int fpclassify(double x) {
-  // Use the MS-specific _fpclass() for classification.
-  int flags = _fpclass(x);
-
-  // Determine class. We cannot use a switch statement because
-  // the _FPCLASS_ constants are defined as flags.
-  if (flags & (_FPCLASS_PN | _FPCLASS_NN)) return FP_NORMAL;
-  if (flags & (_FPCLASS_PZ | _FPCLASS_NZ)) return FP_ZERO;
-  if (flags & (_FPCLASS_PD | _FPCLASS_ND)) return FP_SUBNORMAL;
-  if (flags & (_FPCLASS_PINF | _FPCLASS_NINF)) return FP_INFINITE;
-
-  // All cases should be covered by the code above.
-  DCHECK(flags & (_FPCLASS_SNAN | _FPCLASS_QNAN));
-  return FP_NAN;
-}
-
-
-// Test sign - usually defined in math.h
-int signbit(double x) {
-  // We need to take care of the special case of both positive
-  // and negative versions of zero.
-  if (x == 0)
-    return _fpclass(x) & _FPCLASS_NZ;
-  else
-    return x < 0;
-}
-
-}  // namespace std
-
-#endif  // _MSC_VER
diff --git a/src/base/win32-math.h b/src/base/win32-math.h
deleted file mode 100644
index e1c0350..0000000
--- a/src/base/win32-math.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Extra POSIX/ANSI routines for Win32 when using Visual Studio C++. Please
-// refer to The Open Group Base Specification for specification of the correct
-// semantics for these functions.
-// (http://www.opengroup.org/onlinepubs/000095399/)
-
-#ifndef V8_BASE_WIN32_MATH_H_
-#define V8_BASE_WIN32_MATH_H_
-
-#ifndef _MSC_VER
-#error Wrong environment, expected MSVC.
-#endif  // _MSC_VER
-
-// MSVC 2013+ provides implementations of all standard math functions.
-#if (_MSC_VER < 1800)
-enum {
-  FP_NAN,
-  FP_INFINITE,
-  FP_ZERO,
-  FP_SUBNORMAL,
-  FP_NORMAL
-};
-
-
-namespace std {
-
-int isfinite(double x);
-int isinf(double x);
-int isnan(double x);
-int isless(double x, double y);
-int isgreater(double x, double y);
-int fpclassify(double x);
-int signbit(double x);
-
-}  // namespace std
-
-#endif  // _MSC_VER < 1800
-
-#endif  // V8_BASE_WIN32_MATH_H_
diff --git a/src/basic-block-profiler.cc b/src/basic-block-profiler.cc
new file mode 100644
index 0000000..deb1a53
--- /dev/null
+++ b/src/basic-block-profiler.cc
@@ -0,0 +1,114 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/basic-block-profiler.h"
+
+#include <sstream>
+
+namespace v8 {
+namespace internal {
+
+BasicBlockProfiler::Data::Data(size_t n_blocks)
+    : n_blocks_(n_blocks), block_ids_(n_blocks_), counts_(n_blocks_, 0) {}
+
+
+BasicBlockProfiler::Data::~Data() {}
+
+
+static void InsertIntoString(std::ostringstream* os, std::string* string) {
+  string->insert(0, os->str());
+}
+
+
+void BasicBlockProfiler::Data::SetCode(std::ostringstream* os) {
+  InsertIntoString(os, &code_);
+}
+
+
+void BasicBlockProfiler::Data::SetFunctionName(std::ostringstream* os) {
+  InsertIntoString(os, &function_name_);
+}
+
+
+void BasicBlockProfiler::Data::SetSchedule(std::ostringstream* os) {
+  InsertIntoString(os, &schedule_);
+}
+
+
+void BasicBlockProfiler::Data::SetBlockId(size_t offset, size_t block_id) {
+  DCHECK(offset < n_blocks_);
+  block_ids_[offset] = block_id;
+}
+
+
+uint32_t* BasicBlockProfiler::Data::GetCounterAddress(size_t offset) {
+  DCHECK(offset < n_blocks_);
+  return &counts_[offset];
+}
+
+
+void BasicBlockProfiler::Data::ResetCounts() {
+  for (size_t i = 0; i < n_blocks_; ++i) {
+    counts_[i] = 0;
+  }
+}
+
+
+BasicBlockProfiler::BasicBlockProfiler() {}
+
+
+BasicBlockProfiler::Data* BasicBlockProfiler::NewData(size_t n_blocks) {
+  Data* data = new Data(n_blocks);
+  data_list_.push_back(data);
+  return data;
+}
+
+
+BasicBlockProfiler::~BasicBlockProfiler() {
+  for (DataList::iterator i = data_list_.begin(); i != data_list_.end(); ++i) {
+    delete (*i);
+  }
+}
+
+
+void BasicBlockProfiler::ResetCounts() {
+  for (DataList::iterator i = data_list_.begin(); i != data_list_.end(); ++i) {
+    (*i)->ResetCounts();
+  }
+}
+
+
+std::ostream& operator<<(std::ostream& os, const BasicBlockProfiler& p) {
+  os << "---- Start Profiling Data ----" << std::endl;
+  typedef BasicBlockProfiler::DataList::const_iterator iterator;
+  for (iterator i = p.data_list_.begin(); i != p.data_list_.end(); ++i) {
+    os << **i;
+  }
+  os << "---- End Profiling Data ----" << std::endl;
+  return os;
+}
+
+
+std::ostream& operator<<(std::ostream& os, const BasicBlockProfiler::Data& d) {
+  const char* name = "unknown function";
+  if (!d.function_name_.empty()) {
+    name = d.function_name_.c_str();
+  }
+  if (!d.schedule_.empty()) {
+    os << "schedule for " << name << std::endl;
+    os << d.schedule_.c_str() << std::endl;
+  }
+  os << "block counts for " << name << ":" << std::endl;
+  for (size_t i = 0; i < d.n_blocks_; ++i) {
+    os << "block " << d.block_ids_[i] << " : " << d.counts_[i] << std::endl;
+  }
+  os << std::endl;
+  if (!d.code_.empty()) {
+    os << d.code_.c_str() << std::endl;
+  }
+  return os;
+}
+
+}  // namespace internal
+}  // namespace v8
diff --git a/src/basic-block-profiler.h b/src/basic-block-profiler.h
new file mode 100644
index 0000000..99fa3b1
--- /dev/null
+++ b/src/basic-block-profiler.h
@@ -0,0 +1,77 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_BASIC_BLOCK_PROFILER_H_
+#define V8_BASIC_BLOCK_PROFILER_H_
+
+#include <iosfwd>
+#include <list>
+#include <string>
+
+#include "src/v8.h"
+
+namespace v8 {
+namespace internal {
+
+class Schedule;
+class Graph;
+
+class BasicBlockProfiler {
+ public:
+  class Data {
+   public:
+    size_t n_blocks() const { return n_blocks_; }
+    const uint32_t* counts() const { return &counts_[0]; }
+
+    void SetCode(std::ostringstream* os);
+    void SetFunctionName(std::ostringstream* os);
+    void SetSchedule(std::ostringstream* os);
+    void SetBlockId(size_t offset, size_t block_id);
+    uint32_t* GetCounterAddress(size_t offset);
+
+   private:
+    friend class BasicBlockProfiler;
+    friend std::ostream& operator<<(std::ostream& os,
+                                    const BasicBlockProfiler::Data& s);
+
+    explicit Data(size_t n_blocks);
+    ~Data();
+
+    void ResetCounts();
+
+    const size_t n_blocks_;
+    std::vector<size_t> block_ids_;
+    std::vector<uint32_t> counts_;
+    std::string function_name_;
+    std::string schedule_;
+    std::string code_;
+    DISALLOW_COPY_AND_ASSIGN(Data);
+  };
+
+  typedef std::list<Data*> DataList;
+
+  BasicBlockProfiler();
+  ~BasicBlockProfiler();
+
+  Data* NewData(size_t n_blocks);
+  void ResetCounts();
+
+  const DataList* data_list() { return &data_list_; }
+
+ private:
+  friend std::ostream& operator<<(std::ostream& os,
+                                  const BasicBlockProfiler& s);
+
+  DataList data_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(BasicBlockProfiler);
+};
+
+std::ostream& operator<<(std::ostream& os, const BasicBlockProfiler& s);
+std::ostream& operator<<(std::ostream& os, const BasicBlockProfiler::Data& s);
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_BASIC_BLOCK_PROFILER_H_
diff --git a/src/bignum-dtoa.cc b/src/bignum-dtoa.cc
index 53bf418..f9a0c95 100644
--- a/src/bignum-dtoa.cc
+++ b/src/bignum-dtoa.cc
@@ -4,7 +4,6 @@
 
 #include <cmath>
 
-#include "include/v8stdint.h"
 #include "src/base/logging.h"
 #include "src/utils.h"
 
diff --git a/src/bit-vector.cc b/src/bit-vector.cc
new file mode 100644
index 0000000..198b242
--- /dev/null
+++ b/src/bit-vector.cc
@@ -0,0 +1,58 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/bit-vector.h"
+
+#include "src/base/bits.h"
+#include "src/scopes.h"
+
+namespace v8 {
+namespace internal {
+
+#ifdef DEBUG
+void BitVector::Print() {
+  bool first = true;
+  PrintF("{");
+  for (int i = 0; i < length(); i++) {
+    if (Contains(i)) {
+      if (!first) PrintF(",");
+      first = false;
+      PrintF("%d", i);
+    }
+  }
+  PrintF("}");
+}
+#endif
+
+
+void BitVector::Iterator::Advance() {
+  current_++;
+  uintptr_t val = current_value_;
+  while (val == 0) {
+    current_index_++;
+    if (Done()) return;
+    val = target_->data_[current_index_];
+    current_ = current_index_ << kDataBitShift;
+  }
+  val = SkipZeroBytes(val);
+  val = SkipZeroBits(val);
+  current_value_ = val >> 1;
+}
+
+
+int BitVector::Count() const {
+  int count = 0;
+  for (int i = 0; i < data_length_; i++) {
+    uintptr_t data = data_[i];
+    if (sizeof(data) == 8) {
+      count += base::bits::CountPopulation64(data);
+    } else {
+      count += base::bits::CountPopulation32(static_cast<uint32_t>(data));
+    }
+  }
+  return count;
+}
+
+}  // namespace internal
+}  // namespace v8
diff --git a/src/bit-vector.h b/src/bit-vector.h
new file mode 100644
index 0000000..9fc747d
--- /dev/null
+++ b/src/bit-vector.h
@@ -0,0 +1,253 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_DATAFLOW_H_
+#define V8_DATAFLOW_H_
+
+#include "src/v8.h"
+
+#include "src/allocation.h"
+#include "src/ast.h"
+#include "src/compiler.h"
+#include "src/zone-inl.h"
+
+namespace v8 {
+namespace internal {
+
+class BitVector : public ZoneObject {
+ public:
+  // Iterator for the elements of this BitVector.
+  class Iterator BASE_EMBEDDED {
+   public:
+    explicit Iterator(BitVector* target)
+        : target_(target),
+          current_index_(0),
+          current_value_(target->data_[0]),
+          current_(-1) {
+      DCHECK(target->data_length_ > 0);
+      Advance();
+    }
+    ~Iterator() {}
+
+    bool Done() const { return current_index_ >= target_->data_length_; }
+    void Advance();
+
+    int Current() const {
+      DCHECK(!Done());
+      return current_;
+    }
+
+   private:
+    uintptr_t SkipZeroBytes(uintptr_t val) {
+      while ((val & 0xFF) == 0) {
+        val >>= 8;
+        current_ += 8;
+      }
+      return val;
+    }
+    uintptr_t SkipZeroBits(uintptr_t val) {
+      while ((val & 0x1) == 0) {
+        val >>= 1;
+        current_++;
+      }
+      return val;
+    }
+
+    BitVector* target_;
+    int current_index_;
+    uintptr_t current_value_;
+    int current_;
+
+    friend class BitVector;
+  };
+
+  static const int kDataBits = kPointerSize * 8;
+  static const int kDataBitShift = kPointerSize == 8 ? 6 : 5;
+  static const uintptr_t kOne = 1;  // This saves some static_casts.
+
+  BitVector(int length, Zone* zone)
+      : length_(length),
+        data_length_(SizeFor(length)),
+        data_(zone->NewArray<uintptr_t>(data_length_)) {
+    DCHECK(length > 0);
+    Clear();
+  }
+
+  BitVector(const BitVector& other, Zone* zone)
+      : length_(other.length()),
+        data_length_(SizeFor(length_)),
+        data_(zone->NewArray<uintptr_t>(data_length_)) {
+    CopyFrom(other);
+  }
+
+  static int SizeFor(int length) { return 1 + ((length - 1) / kDataBits); }
+
+  void CopyFrom(const BitVector& other) {
+    DCHECK(other.length() <= length());
+    for (int i = 0; i < other.data_length_; i++) {
+      data_[i] = other.data_[i];
+    }
+    for (int i = other.data_length_; i < data_length_; i++) {
+      data_[i] = 0;
+    }
+  }
+
+  bool Contains(int i) const {
+    DCHECK(i >= 0 && i < length());
+    uintptr_t block = data_[i / kDataBits];
+    return (block & (kOne << (i % kDataBits))) != 0;
+  }
+
+  void Add(int i) {
+    DCHECK(i >= 0 && i < length());
+    data_[i / kDataBits] |= (kOne << (i % kDataBits));
+  }
+
+  void Remove(int i) {
+    DCHECK(i >= 0 && i < length());
+    data_[i / kDataBits] &= ~(kOne << (i % kDataBits));
+  }
+
+  void Union(const BitVector& other) {
+    DCHECK(other.length() == length());
+    for (int i = 0; i < data_length_; i++) {
+      data_[i] |= other.data_[i];
+    }
+  }
+
+  bool UnionIsChanged(const BitVector& other) {
+    DCHECK(other.length() == length());
+    bool changed = false;
+    for (int i = 0; i < data_length_; i++) {
+      uintptr_t old_data = data_[i];
+      data_[i] |= other.data_[i];
+      if (data_[i] != old_data) changed = true;
+    }
+    return changed;
+  }
+
+  void Intersect(const BitVector& other) {
+    DCHECK(other.length() == length());
+    for (int i = 0; i < data_length_; i++) {
+      data_[i] &= other.data_[i];
+    }
+  }
+
+  bool IntersectIsChanged(const BitVector& other) {
+    DCHECK(other.length() == length());
+    bool changed = false;
+    for (int i = 0; i < data_length_; i++) {
+      uintptr_t old_data = data_[i];
+      data_[i] &= other.data_[i];
+      if (data_[i] != old_data) changed = true;
+    }
+    return changed;
+  }
+
+  void Subtract(const BitVector& other) {
+    DCHECK(other.length() == length());
+    for (int i = 0; i < data_length_; i++) {
+      data_[i] &= ~other.data_[i];
+    }
+  }
+
+  void Clear() {
+    for (int i = 0; i < data_length_; i++) {
+      data_[i] = 0;
+    }
+  }
+
+  bool IsEmpty() const {
+    for (int i = 0; i < data_length_; i++) {
+      if (data_[i] != 0) return false;
+    }
+    return true;
+  }
+
+  bool Equals(const BitVector& other) {
+    for (int i = 0; i < data_length_; i++) {
+      if (data_[i] != other.data_[i]) return false;
+    }
+    return true;
+  }
+
+  int Count() const;
+
+  int length() const { return length_; }
+
+#ifdef DEBUG
+  void Print();
+#endif
+
+ private:
+  const int length_;
+  const int data_length_;
+  uintptr_t* const data_;
+
+  DISALLOW_COPY_AND_ASSIGN(BitVector);
+};
+
+
+class GrowableBitVector BASE_EMBEDDED {
+ public:
+  class Iterator BASE_EMBEDDED {
+   public:
+    Iterator(const GrowableBitVector* target, Zone* zone)
+        : it_(target->bits_ == NULL ? new (zone) BitVector(1, zone)
+                                    : target->bits_) {}
+    bool Done() const { return it_.Done(); }
+    void Advance() { it_.Advance(); }
+    int Current() const { return it_.Current(); }
+
+   private:
+    BitVector::Iterator it_;
+  };
+
+  GrowableBitVector() : bits_(NULL) {}
+  GrowableBitVector(int length, Zone* zone)
+      : bits_(new (zone) BitVector(length, zone)) {}
+
+  bool Contains(int value) const {
+    if (!InBitsRange(value)) return false;
+    return bits_->Contains(value);
+  }
+
+  void Add(int value, Zone* zone) {
+    EnsureCapacity(value, zone);
+    bits_->Add(value);
+  }
+
+  void Union(const GrowableBitVector& other, Zone* zone) {
+    for (Iterator it(&other, zone); !it.Done(); it.Advance()) {
+      Add(it.Current(), zone);
+    }
+  }
+
+  void Clear() {
+    if (bits_ != NULL) bits_->Clear();
+  }
+
+ private:
+  static const int kInitialLength = 1024;
+
+  bool InBitsRange(int value) const {
+    return bits_ != NULL && bits_->length() > value;
+  }
+
+  void EnsureCapacity(int value, Zone* zone) {
+    if (InBitsRange(value)) return;
+    int new_length = bits_ == NULL ? kInitialLength : bits_->length();
+    while (new_length <= value) new_length *= 2;
+    BitVector* new_bits = new (zone) BitVector(new_length, zone);
+    if (bits_ != NULL) new_bits->CopyFrom(*bits_);
+    bits_ = new_bits;
+  }
+
+  BitVector* bits_;
+};
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_DATAFLOW_H_
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 250562a..7105eb2 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -48,7 +48,7 @@
   Heap* heap = isolate_->heap();
   if (heap->natives_source_cache()->get(index)->IsUndefined()) {
     // We can use external strings for the natives.
-    Vector<const char> source = Natives::GetRawScriptSource(index);
+    Vector<const char> source = Natives::GetScriptSource(index);
     NativesExternalStringResource* resource =
         new NativesExternalStringResource(this,
                                           source.start(),
@@ -57,6 +57,8 @@
     Handle<String> source_code = isolate_->factory()
                                      ->NewExternalStringFromOneByte(resource)
                                      .ToHandleChecked();
+    // Mark this external string with a special map.
+    source_code->set_map(isolate_->heap()->native_source_string_map());
     heap->natives_source_cache()->set(index, *source_code);
   }
   Handle<Object> cached_source(heap->natives_source_cache()->get(index),
@@ -126,7 +128,7 @@
 void Bootstrapper::TearDown() {
   if (delete_these_non_arrays_on_tear_down_ != NULL) {
     int len = delete_these_non_arrays_on_tear_down_->length();
-    DCHECK(len < 28);  // Don't use this mechanism for unbounded allocations.
+    DCHECK(len < 1000);  // Don't use this mechanism for unbounded allocations.
     for (int i = 0; i < len; i++) {
       delete delete_these_non_arrays_on_tear_down_->at(i);
       delete_these_non_arrays_on_tear_down_->at(i) = NULL;
@@ -208,6 +210,16 @@
   // Used for creating a context from scratch.
   void InstallNativeFunctions();
   void InstallExperimentalNativeFunctions();
+
+#define DECLARE_FEATURE_INITIALIZATION(id, descr) \
+  void InstallNativeFunctions_##id();             \
+  void InitializeGlobal_##id();
+
+  HARMONY_INPROGRESS(DECLARE_FEATURE_INITIALIZATION)
+  HARMONY_STAGED(DECLARE_FEATURE_INITIALIZATION)
+  HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
+#undef DECLARE_FEATURE_INITIALIZATION
+
   Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins,
                                           const char* name,
                                           ElementsKind elements_kind);
@@ -349,8 +361,8 @@
 static void SetObjectPrototype(Handle<JSObject> object, Handle<Object> proto) {
   // object.__proto__ = proto;
   Handle<Map> old_map = Handle<Map>(object->map());
-  Handle<Map> new_map = Map::Copy(old_map);
-  new_map->set_prototype(*proto);
+  Handle<Map> new_map = Map::Copy(old_map, "SetObjectPrototype");
+  new_map->SetPrototype(proto, FAST_PROTOTYPE);
   JSObject::MigrateToMap(object, new_map);
 }
 
@@ -481,6 +493,8 @@
 
   Handle<String> object_name = factory->Object_string();
 
+  Handle<JSObject> object_function_prototype;
+
   {  // --- O b j e c t ---
     Handle<JSFunction> object_fun = factory->NewFunction(object_name);
     int unused = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
@@ -495,19 +509,20 @@
     native_context()->set_object_function(*object_fun);
 
     // Allocate a new prototype for the object function.
-    Handle<JSObject> prototype = factory->NewJSObject(
-        isolate->object_function(),
-        TENURED);
-    Handle<Map> map = Map::Copy(handle(prototype->map()));
+    object_function_prototype =
+        factory->NewJSObject(isolate->object_function(), TENURED);
+    Handle<Map> map = Map::Copy(handle(object_function_prototype->map()),
+                                "EmptyObjectPrototype");
     map->set_is_prototype_map(true);
-    prototype->set_map(*map);
+    object_function_prototype->set_map(*map);
 
-    native_context()->set_initial_object_prototype(*prototype);
+    native_context()->set_initial_object_prototype(*object_function_prototype);
     // For bootstrapping set the array prototype to be the same as the object
     // prototype, otherwise the missing initial_array_prototype will cause
     // assertions during startup.
-    native_context()->set_initial_array_prototype(*prototype);
-    Accessors::FunctionSetPrototype(object_fun, prototype);
+    native_context()->set_initial_array_prototype(*object_function_prototype);
+    Accessors::FunctionSetPrototype(object_fun, object_function_prototype)
+        .Assert();
   }
 
   // Allocate the empty function as the prototype for function ECMAScript
@@ -522,8 +537,7 @@
   Handle<Map> empty_function_map =
       CreateFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
   DCHECK(!empty_function_map->is_dictionary_map());
-  empty_function_map->set_prototype(
-      native_context()->object_function()->prototype());
+  empty_function_map->SetPrototype(object_function_prototype);
   empty_function_map->set_is_prototype_map(true);
   empty_function->set_map(*empty_function_map);
 
@@ -537,10 +551,10 @@
   empty_function->shared()->DontAdaptArguments();
 
   // Set prototypes for the function maps.
-  native_context()->sloppy_function_map()->set_prototype(*empty_function);
-  native_context()->sloppy_function_without_prototype_map()->
-      set_prototype(*empty_function);
-  sloppy_function_map_writable_prototype_->set_prototype(*empty_function);
+  native_context()->sloppy_function_map()->SetPrototype(empty_function);
+  native_context()->sloppy_function_without_prototype_map()->SetPrototype(
+      empty_function);
+  sloppy_function_map_writable_prototype_->SetPrototype(empty_function);
   return empty_function;
 }
 
@@ -642,7 +656,7 @@
   Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
   SetStrictFunctionInstanceDescriptor(map, function_mode);
   map->set_function_with_prototype(IsFunctionModeWithPrototype(function_mode));
-  map->set_prototype(*empty_function);
+  map->SetPrototype(empty_function);
   return map;
 }
 
@@ -851,7 +865,6 @@
                                 Handle<JSGlobalProxy> global_proxy) {
   // Set the native context for the global object.
   global_object->set_native_context(*native_context());
-  global_object->set_global_context(*native_context());
   global_object->set_global_proxy(*global_proxy);
   global_proxy->set_native_context(*native_context());
   native_context()->set_global_proxy(*global_proxy);
@@ -896,6 +909,10 @@
   Factory* factory = isolate->factory();
   Heap* heap = isolate->heap();
 
+  Handle<ScriptContextTable> script_context_table =
+      factory->NewScriptContextTable();
+  native_context()->set_script_context_table(*script_context_table);
+
   Handle<String> object_name = factory->Object_string();
   JSObject::AddProperty(
       global_object, object_name, isolate->object_function(), DONT_ENUM);
@@ -934,7 +951,7 @@
       CallbacksDescriptor d(
           Handle<Name>(Name::cast(array_length->name())),
           array_length, attribs);
-      array_function->initial_map()->AppendDescriptor(&d);
+      initial_map->AppendDescriptor(&d);
     }
 
     // array_function is used internally. JS code creating array object should
@@ -1028,11 +1045,10 @@
 
     {
       // ECMA-262, section 15.10.7.1.
-      FieldDescriptor field(factory->source_string(),
-                            JSRegExp::kSourceFieldIndex,
-                            final,
-                            Representation::Tagged());
-      initial_map->AppendDescriptor(&field);
+      Handle<AccessorInfo> regexp_source(
+          Accessors::RegExpSourceInfo(isolate, final));
+      CallbacksDescriptor d(factory->source_string(), regexp_source, final);
+      initial_map->AppendDescriptor(&d);
     }
     {
       // ECMA-262, section 15.10.7.2.
@@ -1069,19 +1085,17 @@
       initial_map->AppendDescriptor(&field);
     }
 
-    initial_map->set_inobject_properties(5);
-    initial_map->set_pre_allocated_property_fields(5);
+    static const int num_fields = JSRegExp::kInObjectFieldCount;
+    initial_map->set_inobject_properties(num_fields);
+    initial_map->set_pre_allocated_property_fields(num_fields);
     initial_map->set_unused_property_fields(0);
-    initial_map->set_instance_size(
-        initial_map->instance_size() + 5 * kPointerSize);
-    initial_map->set_visitor_id(StaticVisitorBase::GetVisitorId(*initial_map));
+    initial_map->set_instance_size(initial_map->instance_size() +
+                                   num_fields * kPointerSize);
 
     // RegExp prototype object is itself a RegExp.
-    Handle<Map> proto_map = Map::Copy(initial_map);
-    proto_map->set_prototype(native_context()->initial_object_prototype());
+    Handle<Map> proto_map = Map::Copy(initial_map, "RegExpPrototype");
+    DCHECK(proto_map->prototype() == *isolate->initial_object_prototype());
     Handle<JSObject> proto = factory->NewJSObjectFromMap(proto_map);
-    proto->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex,
-                                 heap->query_colon_string());
     proto->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex,
                                  heap->false_value());
     proto->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex,
@@ -1092,7 +1106,7 @@
                                  Smi::FromInt(0),
                                  SKIP_WRITE_BARRIER);  // It's a Smi.
     proto_map->set_is_prototype_map(true);
-    initial_map->set_prototype(*proto);
+    initial_map->SetPrototype(proto);
     factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto),
                                    JSRegExp::IRREGEXP, factory->empty_string(),
                                    JSRegExp::Flags(0), 0);
@@ -1232,7 +1246,8 @@
   }
 
   {  // --- aliased arguments map
-    Handle<Map> map = Map::Copy(isolate->sloppy_arguments_map());
+    Handle<Map> map =
+        Map::Copy(isolate->sloppy_arguments_map(), "AliasedArguments");
     map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
     DCHECK_EQ(2, map->pre_allocated_property_fields());
     native_context()->set_aliased_arguments_map(*map);
@@ -1276,7 +1291,9 @@
     // @@iterator method is added later.
 
     map->set_function_with_prototype(true);
-    map->set_prototype(native_context()->object_function()->prototype());
+    DCHECK_EQ(native_context()->object_function()->prototype(),
+              *isolate->initial_object_prototype());
+    map->SetPrototype(isolate->initial_object_prototype());
     map->set_pre_allocated_property_fields(1);
     map->set_inobject_properties(1);
 
@@ -1358,16 +1375,12 @@
 
 
 void Genesis::InitializeExperimentalGlobal() {
-  // TODO(erikcorry): Move this into Genesis::InitializeGlobal once we no
-  // longer need to live behind a flag.
-  Handle<JSObject> builtins(native_context()->builtins());
+#define FEATURE_INITIALIZE_GLOBAL(id, descr) InitializeGlobal_##id();
 
-  Handle<HeapObject> flag(
-      FLAG_harmony_regexps ? heap()->true_value() : heap()->false_value());
-  PropertyAttributes attributes =
-      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
-  Runtime::DefineObjectProperty(builtins, factory()->harmony_regexps_string(),
-                                flag, attributes).Assert();
+  HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
+  HARMONY_STAGED(FEATURE_INITIALIZE_GLOBAL)
+  HARMONY_SHIPPING(FEATURE_INITIALIZE_GLOBAL)
+#undef FEATURE_INITIALIZE_GLOBAL
 }
 
 
@@ -1384,8 +1397,8 @@
   Factory* factory = isolate->factory();
   Handle<String> source_code;
   ASSIGN_RETURN_ON_EXCEPTION_VALUE(
-      isolate, source_code, factory->NewStringFromAscii(
-                                ExperimentalNatives::GetRawScriptSource(index)),
+      isolate, source_code,
+      factory->NewStringFromAscii(ExperimentalNatives::GetScriptSource(index)),
       false);
   return CompileNative(isolate, name, source_code);
 }
@@ -1503,12 +1516,6 @@
           .ToHandleChecked();                                               \
   native_context()->set_##var(Type::cast(*var##_native));
 
-#define INSTALL_NATIVE_MATH(name)                                    \
-  {                                                                  \
-    Handle<Object> fun =                                             \
-        ResolveBuiltinIdHolder(native_context(), "Math." #name);     \
-    native_context()->set_math_##name##_fun(JSFunction::cast(*fun)); \
-  }
 
 void Genesis::InstallNativeFunctions() {
   HandleScope scope(isolate());
@@ -1521,6 +1528,7 @@
   INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
   INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
   INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
+  INSTALL_NATIVE(JSFunction, "ToLength", to_length_fun);
 
   INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun);
   INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun);
@@ -1551,30 +1559,7 @@
                  native_object_get_notifier);
   INSTALL_NATIVE(JSFunction, "NativeObjectNotifierPerformChange",
                  native_object_notifier_perform_change);
-
-  INSTALL_NATIVE(Symbol, "symbolIterator", iterator_symbol);
-  INSTALL_NATIVE(Symbol, "symbolUnscopables", unscopables_symbol);
   INSTALL_NATIVE(JSFunction, "ArrayValues", array_values_iterator);
-
-  INSTALL_NATIVE_MATH(abs)
-  INSTALL_NATIVE_MATH(acos)
-  INSTALL_NATIVE_MATH(asin)
-  INSTALL_NATIVE_MATH(atan)
-  INSTALL_NATIVE_MATH(atan2)
-  INSTALL_NATIVE_MATH(ceil)
-  INSTALL_NATIVE_MATH(cos)
-  INSTALL_NATIVE_MATH(exp)
-  INSTALL_NATIVE_MATH(floor)
-  INSTALL_NATIVE_MATH(imul)
-  INSTALL_NATIVE_MATH(log)
-  INSTALL_NATIVE_MATH(max)
-  INSTALL_NATIVE_MATH(min)
-  INSTALL_NATIVE_MATH(pow)
-  INSTALL_NATIVE_MATH(random)
-  INSTALL_NATIVE_MATH(round)
-  INSTALL_NATIVE_MATH(sin)
-  INSTALL_NATIVE_MATH(sqrt)
-  INSTALL_NATIVE_MATH(tan)
 }
 
 
@@ -1585,10 +1570,74 @@
     INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
     INSTALL_NATIVE(JSFunction, "ProxyEnumerate", proxy_enumerate);
   }
+
+#define INSTALL_NATIVE_FUNCTIONS_FOR(id, descr) InstallNativeFunctions_##id();
+  HARMONY_INPROGRESS(INSTALL_NATIVE_FUNCTIONS_FOR)
+  HARMONY_STAGED(INSTALL_NATIVE_FUNCTIONS_FOR)
+  HARMONY_SHIPPING(INSTALL_NATIVE_FUNCTIONS_FOR)
+#undef INSTALL_NATIVE_FUNCTIONS_FOR
+}
+
+
+#define EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(id) \
+  void Genesis::InstallNativeFunctions_##id() {}
+
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_scoping)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_modules)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_strings)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_arrays)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_array_includes)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_classes)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_object_literals)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_regexps)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_arrow_functions)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_numeric_literals)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_tostring)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_templates)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_sloppy)
+EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_unicode)
+
+
+void Genesis::InstallNativeFunctions_harmony_proxies() {
+  if (FLAG_harmony_proxies) {
+    INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
+    INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
+    INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
+    INSTALL_NATIVE(JSFunction, "ProxyEnumerate", proxy_enumerate);
+  }
 }
 
 #undef INSTALL_NATIVE
 
+#define EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(id) \
+  void Genesis::InitializeGlobal_##id() {}
+
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_scoping)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_modules)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_strings)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_arrays)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_array_includes)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_classes)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object_literals)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_arrow_functions)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_numeric_literals)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_tostring)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_proxies)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_templates)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_sloppy)
+EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_unicode)
+
+void Genesis::InitializeGlobal_harmony_regexps() {
+  Handle<JSObject> builtins(native_context()->builtins());
+
+  Handle<HeapObject> flag(FLAG_harmony_regexps ? heap()->true_value()
+                                               : heap()->false_value());
+  PropertyAttributes attributes =
+      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
+  Runtime::DefineObjectProperty(builtins, factory()->harmony_regexps_string(),
+                                flag, attributes).Assert();
+}
+
 
 Handle<JSFunction> Genesis::InstallInternalArray(
     Handle<JSBuiltinsObject> builtins,
@@ -1612,7 +1661,7 @@
   array_function->shared()->DontAdaptArguments();
 
   Handle<Map> original_map(array_function->initial_map());
-  Handle<Map> initial_map = Map::Copy(original_map);
+  Handle<Map> initial_map = Map::Copy(original_map, "InternalArray");
   initial_map->set_elements_kind(elements_kind);
   JSFunction::SetInitialMap(array_function, initial_map, prototype);
 
@@ -1627,7 +1676,7 @@
   {  // Add length.
     CallbacksDescriptor d(
         Handle<Name>(Name::cast(array_length->name())), array_length, attribs);
-    array_function->initial_map()->AppendDescriptor(&d);
+    initial_map->AppendDescriptor(&d);
   }
 
   return array_function;
@@ -1657,7 +1706,6 @@
       Handle<JSBuiltinsObject>::cast(factory()->NewGlobalObject(builtins_fun));
   builtins->set_builtins(*builtins);
   builtins->set_native_context(*native_context());
-  builtins->set_global_context(*native_context());
   builtins->set_global_proxy(native_context()->global_proxy());
 
 
@@ -1697,7 +1745,7 @@
         isolate()->initial_object_prototype(), Builtins::kIllegal);
     Handle<JSObject> prototype =
         factory()->NewJSObject(isolate()->object_function(), TENURED);
-    Accessors::FunctionSetPrototype(script_fun, prototype);
+    Accessors::FunctionSetPrototype(script_fun, prototype).Assert();
     native_context()->set_script_function(*script_fun);
 
     Handle<Map> script_map = Handle<Map>(script_fun->initial_map());
@@ -1839,7 +1887,7 @@
         isolate()->initial_object_prototype(), Builtins::kIllegal);
     Handle<JSObject> prototype =
         factory()->NewJSObject(isolate()->object_function(), TENURED);
-    Accessors::FunctionSetPrototype(opaque_reference_fun, prototype);
+    Accessors::FunctionSetPrototype(opaque_reference_fun, prototype).Assert();
     native_context()->set_opaque_reference_function(*opaque_reference_fun);
   }
 
@@ -1890,8 +1938,8 @@
     // Create maps for generator functions and their prototypes.  Store those
     // maps in the native context.
     Handle<Map> generator_function_map =
-        Map::Copy(sloppy_function_map_writable_prototype_);
-    generator_function_map->set_prototype(*generator_function_prototype);
+        Map::Copy(sloppy_function_map_writable_prototype_, "GeneratorFunction");
+    generator_function_map->SetPrototype(generator_function_prototype);
     native_context()->set_sloppy_generator_function_map(
         *generator_function_map);
 
@@ -1921,15 +1969,16 @@
                      rw_attribs, poison_pair);
 
     Handle<Map> strict_function_map(native_context()->strict_function_map());
-    Handle<Map> strict_generator_function_map = Map::Copy(strict_function_map);
+    Handle<Map> strict_generator_function_map =
+        Map::Copy(strict_function_map, "StrictGeneratorFunction");
     // "arguments" and "caller" already poisoned.
-    strict_generator_function_map->set_prototype(*generator_function_prototype);
+    strict_generator_function_map->SetPrototype(generator_function_prototype);
     native_context()->set_strict_generator_function_map(
         *strict_generator_function_map);
 
     Handle<JSFunction> object_function(native_context()->object_function());
     Handle<Map> generator_object_prototype_map = Map::Create(isolate(), 0);
-    generator_object_prototype_map->set_prototype(*generator_object_prototype);
+    generator_object_prototype_map->SetPrototype(generator_object_prototype);
     native_context()->set_generator_object_prototype_map(
         *generator_object_prototype_map);
   }
@@ -1939,6 +1988,17 @@
     return true;
   }
 
+  // Install public symbols.
+  {
+    static const PropertyAttributes attributes =
+        static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
+#define INSTALL_PUBLIC_SYMBOL(name, varname, description)                 \
+  Handle<String> varname = factory()->NewStringFromStaticChars(#varname); \
+  JSObject::AddProperty(builtins, varname, factory()->name(), attributes);
+    PUBLIC_SYMBOL_LIST(INSTALL_PUBLIC_SYMBOL)
+#undef INSTALL_PUBLIC_SYMBOL
+  }
+
   // Install natives.
   for (int i = Natives::GetDebuggerCount();
        i < Natives::GetBuiltinsCount();
@@ -1979,8 +2039,10 @@
     if (FLAG_vector_ics) {
       // Apply embeds an IC, so we need a type vector of size 1 in the shared
       // function info.
+      FeedbackVectorSpec spec(0, 1);
+      spec.SetKind(0, Code::CALL_IC);
       Handle<TypeFeedbackVector> feedback_vector =
-          factory()->NewTypeFeedbackVector(1);
+          factory()->NewTypeFeedbackVector(spec);
       apply->shared()->set_feedback_vector(*feedback_vector);
     }
 
@@ -2017,7 +2079,7 @@
 
     // Set prototype on map.
     initial_map->set_non_instance_prototype(false);
-    initial_map->set_prototype(*array_prototype);
+    initial_map->SetPrototype(array_prototype);
 
     // Update map with length accessor from Array and add "index" and "input".
     Map::EnsureDescriptorSlack(initial_map, 3);
@@ -2065,22 +2127,22 @@
     Handle<AccessorInfo> arguments_iterator =
         Accessors::ArgumentsIteratorInfo(isolate(), attribs);
     {
-      CallbacksDescriptor d(Handle<Name>(native_context()->iterator_symbol()),
-                            arguments_iterator, attribs);
+      CallbacksDescriptor d(factory()->iterator_symbol(), arguments_iterator,
+                            attribs);
       Handle<Map> map(native_context()->sloppy_arguments_map());
       Map::EnsureDescriptorSlack(map, 1);
       map->AppendDescriptor(&d);
     }
     {
-      CallbacksDescriptor d(Handle<Name>(native_context()->iterator_symbol()),
-                            arguments_iterator, attribs);
+      CallbacksDescriptor d(factory()->iterator_symbol(), arguments_iterator,
+                            attribs);
       Handle<Map> map(native_context()->aliased_arguments_map());
       Map::EnsureDescriptorSlack(map, 1);
       map->AppendDescriptor(&d);
     }
     {
-      CallbacksDescriptor d(Handle<Name>(native_context()->iterator_symbol()),
-                            arguments_iterator, attribs);
+      CallbacksDescriptor d(factory()->iterator_symbol(), arguments_iterator,
+                            attribs);
       Handle<Map> map(native_context()->strict_arguments_map());
       Map::EnsureDescriptorSlack(map, 1);
       map->AppendDescriptor(&d);
@@ -2095,22 +2157,46 @@
 }
 
 
-#define INSTALL_EXPERIMENTAL_NATIVE(i, flag, file)                \
-  if (FLAG_harmony_##flag &&                                      \
-      strcmp(ExperimentalNatives::GetScriptName(i).start(),       \
-          "native " file) == 0) {                                 \
-    if (!CompileExperimentalBuiltin(isolate(), i)) return false;  \
-  }
-
-
 bool Genesis::InstallExperimentalNatives() {
+  static const char* harmony_arrays_natives[] = {
+      "native harmony-array.js", "native harmony-typedarray.js", NULL};
+  static const char* harmony_array_includes_natives[] = {
+      "native harmony-array-includes.js", NULL};
+  static const char* harmony_proxies_natives[] = {"native proxy.js", NULL};
+  static const char* harmony_strings_natives[] = {"native harmony-string.js",
+                                                  NULL};
+  static const char* harmony_classes_natives[] = {"native harmony-classes.js",
+                                                  NULL};
+  static const char* harmony_modules_natives[] = {NULL};
+  static const char* harmony_scoping_natives[] = {NULL};
+  static const char* harmony_object_literals_natives[] = {NULL};
+  static const char* harmony_regexps_natives[] = {
+      "native harmony-regexp.js", NULL};
+  static const char* harmony_arrow_functions_natives[] = {NULL};
+  static const char* harmony_numeric_literals_natives[] = {NULL};
+  static const char* harmony_tostring_natives[] = {"native harmony-tostring.js",
+                                                   NULL};
+  static const char* harmony_templates_natives[] = {
+      "native harmony-templates.js", NULL};
+  static const char* harmony_sloppy_natives[] = {NULL};
+  static const char* harmony_unicode_natives[] = {NULL};
+
   for (int i = ExperimentalNatives::GetDebuggerCount();
-       i < ExperimentalNatives::GetBuiltinsCount();
-       i++) {
-    INSTALL_EXPERIMENTAL_NATIVE(i, proxies, "proxy.js")
-    INSTALL_EXPERIMENTAL_NATIVE(i, strings, "harmony-string.js")
-    INSTALL_EXPERIMENTAL_NATIVE(i, arrays, "harmony-array.js")
-    INSTALL_EXPERIMENTAL_NATIVE(i, classes, "harmony-classes.js")
+       i < ExperimentalNatives::GetBuiltinsCount(); i++) {
+#define INSTALL_EXPERIMENTAL_NATIVES(id, desc)                                \
+  if (FLAG_##id) {                                                            \
+    for (size_t j = 0; id##_natives[j] != NULL; j++) {                        \
+      Vector<const char> script_name = ExperimentalNatives::GetScriptName(i); \
+      if (strncmp(script_name.start(), id##_natives[j],                       \
+                  script_name.length()) == 0) {                               \
+        if (!CompileExperimentalBuiltin(isolate(), i)) return false;          \
+      }                                                                       \
+    }                                                                         \
+  }
+    HARMONY_INPROGRESS(INSTALL_EXPERIMENTAL_NATIVES);
+    HARMONY_STAGED(INSTALL_EXPERIMENTAL_NATIVES);
+    HARMONY_SHIPPING(INSTALL_EXPERIMENTAL_NATIVES);
+#undef INSTALL_EXPERIMENTAL_NATIVES
   }
 
   InstallExperimentalNativeFunctions();
@@ -2495,6 +2581,8 @@
           JSObject::AddProperty(to, key, constant, details.attributes());
           break;
         }
+        case ACCESSOR_FIELD:
+          UNREACHABLE();
         case CALLBACKS: {
           Handle<Name> key(descs->GetKey(i));
           LookupIterator it(to, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
@@ -2505,15 +2593,10 @@
           DCHECK(!to->HasFastProperties());
           // Add to dictionary.
           Handle<Object> callbacks(descs->GetCallbacksObject(i), isolate());
-          PropertyDetails d = PropertyDetails(
-              details.attributes(), CALLBACKS, i + 1);
+          PropertyDetails d(details.attributes(), CALLBACKS, i + 1);
           JSObject::SetNormalizedProperty(to, key, callbacks, d);
           break;
         }
-        // Do not occur since the from object has fast properties.
-        case NORMAL:
-          UNREACHABLE();
-          break;
       }
     }
   } else {
@@ -2538,6 +2621,7 @@
                                  isolate());
         }
         PropertyDetails details = properties->DetailsAt(i);
+        DCHECK_EQ(DATA, details.kind());
         JSObject::AddProperty(to, key, value, details.attributes());
       }
     }
@@ -2588,20 +2672,24 @@
 class NoTrackDoubleFieldsForSerializerScope {
  public:
   explicit NoTrackDoubleFieldsForSerializerScope(Isolate* isolate)
-      : flag_(FLAG_track_double_fields) {
+      : flag_(FLAG_track_double_fields), enabled_(false) {
     if (isolate->serializer_enabled()) {
       // Disable tracking double fields because heap numbers treated as
       // immutable by the serializer.
       FLAG_track_double_fields = false;
+      enabled_ = true;
     }
   }
 
   ~NoTrackDoubleFieldsForSerializerScope() {
-    FLAG_track_double_fields = flag_;
+    if (enabled_) {
+      FLAG_track_double_fields = flag_;
+    }
   }
 
  private:
   bool flag_;
+  bool enabled_;
 };
 
 
@@ -2635,6 +2723,15 @@
     AddToWeakNativeContextList(*native_context());
     isolate->set_context(*native_context());
     isolate->counters()->contexts_created_by_snapshot()->Increment();
+#if TRACE_MAPS
+    if (FLAG_trace_maps) {
+      Handle<JSFunction> object_fun = isolate->object_function();
+      PrintF("[TraceMap: InitialMap map= %p SFI= %d_Object ]\n",
+             reinterpret_cast<void*>(object_fun->initial_map()),
+             object_fun->shared()->unique_id());
+      Map::TraceAllTransitions(object_fun->initial_map());
+    }
+#endif
     Handle<GlobalObject> global_object;
     Handle<JSGlobalProxy> global_proxy = CreateNewGlobals(
         global_proxy_template, maybe_global_proxy, &global_object);
diff --git a/src/bootstrapper.h b/src/bootstrapper.h
index 0cc8486..9d4f270 100644
--- a/src/bootstrapper.h
+++ b/src/bootstrapper.h
@@ -158,8 +158,8 @@
   NativesExternalStringResource(Bootstrapper* bootstrapper,
                                 const char* source,
                                 size_t length);
-  virtual const char* data() const OVERRIDE { return data_; }
-  virtual size_t length() const OVERRIDE { return length_; }
+  const char* data() const OVERRIDE { return data_; }
+  size_t length() const OVERRIDE { return length_; }
 
  private:
   const char* data_;
diff --git a/src/builtins.cc b/src/builtins.cc
index d0c19e5..b8d0b42 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -182,23 +182,24 @@
 }
 
 
-static bool ArrayPrototypeHasNoElements(Heap* heap,
-                                        Context* native_context,
-                                        JSObject* array_proto) {
+static bool ArrayPrototypeHasNoElements(Heap* heap, PrototypeIterator* iter) {
   DisallowHeapAllocation no_gc;
-  // This method depends on non writability of Object and Array prototype
-  // fields.
-  if (array_proto->elements() != heap->empty_fixed_array()) return false;
-  // Object.prototype
-  PrototypeIterator iter(heap->isolate(), array_proto);
-  if (iter.IsAtEnd()) {
-    return false;
+  for (; !iter->IsAtEnd(); iter->Advance()) {
+    if (iter->GetCurrent()->IsJSProxy()) return false;
+    if (JSObject::cast(iter->GetCurrent())->elements() !=
+        heap->empty_fixed_array()) {
+      return false;
+    }
   }
-  array_proto = JSObject::cast(iter.GetCurrent());
-  if (array_proto != native_context->initial_object_prototype()) return false;
-  if (array_proto->elements() != heap->empty_fixed_array()) return false;
-  iter.Advance();
-  return iter.IsAtEnd();
+  return true;
+}
+
+
+static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
+                                                     JSArray* receiver) {
+  DisallowHeapAllocation no_gc;
+  PrototypeIterator iter(heap->isolate(), receiver);
+  return ArrayPrototypeHasNoElements(heap, &iter);
 }
 
 
@@ -213,13 +214,13 @@
   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
   // If there may be elements accessors in the prototype chain, the fast path
   // cannot be used if there arguments to add to the array.
-  if (args != NULL && array->map()->DictionaryElementsInPrototypeChainOnly()) {
+  Heap* heap = isolate->heap();
+  if (args != NULL && !IsJSArrayFastElementMovingAllowed(heap, *array)) {
     return MaybeHandle<FixedArrayBase>();
   }
   if (array->map()->is_observed()) return MaybeHandle<FixedArrayBase>();
   if (!array->map()->is_extensible()) return MaybeHandle<FixedArrayBase>();
   Handle<FixedArrayBase> elms(array->elements(), isolate);
-  Heap* heap = isolate->heap();
   Map* map = elms->map();
   if (map == heap->fixed_array_map()) {
     if (args == NULL || array->HasFastObjectElements()) return elms;
@@ -264,19 +265,6 @@
 }
 
 
-static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
-                                                     JSArray* receiver) {
-  if (!FLAG_clever_optimizations) return false;
-  DisallowHeapAllocation no_gc;
-  Context* native_context = heap->isolate()->context()->native_context();
-  JSObject* array_proto =
-      JSObject::cast(native_context->array_function()->prototype());
-  PrototypeIterator iter(heap->isolate(), receiver);
-  return iter.GetCurrent() == array_proto &&
-         ArrayPrototypeHasNoElements(heap, native_context, array_proto);
-}
-
-
 MUST_USE_RESULT static Object* CallJsBuiltin(
     Isolate* isolate,
     const char* name,
@@ -431,6 +419,10 @@
   int len = Smi::cast(array->length())->value();
   if (len == 0) return isolate->heap()->undefined_value();
 
+  if (JSArray::HasReadOnlyLength(array)) {
+    return CallJsBuiltin(isolate, "ArrayPop", args);
+  }
+
   ElementsAccessor* accessor = array->GetElementsAccessor();
   int new_length = len - 1;
   Handle<Object> element =
@@ -453,8 +445,7 @@
       EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
   Handle<FixedArrayBase> elms_obj;
   if (!maybe_elms_obj.ToHandle(&elms_obj) ||
-      !IsJSArrayFastElementMovingAllowed(heap,
-                                         *Handle<JSArray>::cast(receiver))) {
+      !IsJSArrayFastElementMovingAllowed(heap, JSArray::cast(*receiver))) {
     return CallJsBuiltin(isolate, "ArrayShift", args);
   }
   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
@@ -463,6 +454,10 @@
   int len = Smi::cast(array->length())->value();
   if (len == 0) return heap->undefined_value();
 
+  if (JSArray::HasReadOnlyLength(array)) {
+    return CallJsBuiltin(isolate, "ArrayShift", args);
+  }
+
   // Get first element
   ElementsAccessor* accessor = array->GetElementsAccessor();
   Handle<Object> first =
@@ -499,11 +494,9 @@
   Heap* heap = isolate->heap();
   Handle<Object> receiver = args.receiver();
   MaybeHandle<FixedArrayBase> maybe_elms_obj =
-      EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
+      EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
   Handle<FixedArrayBase> elms_obj;
-  if (!maybe_elms_obj.ToHandle(&elms_obj) ||
-      !IsJSArrayFastElementMovingAllowed(heap,
-                                         *Handle<JSArray>::cast(receiver))) {
+  if (!maybe_elms_obj.ToHandle(&elms_obj)) {
     return CallJsBuiltin(isolate, "ArrayUnshift", args);
   }
   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
@@ -524,9 +517,6 @@
 
   Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
 
-  JSObject::EnsureCanContainElements(array, &args, 1, to_add,
-                                     DONT_ALLOW_DOUBLE_ELEMENTS);
-
   if (new_length > elms->length()) {
     // New backing storage is needed.
     int capacity = new_length + (new_length >> 1) + 16;
@@ -708,9 +698,7 @@
   MaybeHandle<FixedArrayBase> maybe_elms_obj =
       EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3);
   Handle<FixedArrayBase> elms_obj;
-  if (!maybe_elms_obj.ToHandle(&elms_obj) ||
-      !IsJSArrayFastElementMovingAllowed(heap,
-                                         *Handle<JSArray>::cast(receiver))) {
+  if (!maybe_elms_obj.ToHandle(&elms_obj)) {
     return CallJsBuiltin(isolate, "ArraySplice", args);
   }
   Handle<JSArray> array = Handle<JSArray>::cast(receiver);
@@ -775,6 +763,11 @@
     return CallJsBuiltin(isolate, "ArraySplice", args);
   }
 
+  if (new_length != len && JSArray::HasReadOnlyLength(array)) {
+    AllowHeapAllocation allow_allocation;
+    return CallJsBuiltin(isolate, "ArraySplice", args);
+  }
+
   if (new_length == 0) {
     Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(
         elms_obj, elements_kind, actual_delete_count);
@@ -928,9 +921,10 @@
     DisallowHeapAllocation no_gc;
     Heap* heap = isolate->heap();
     Context* native_context = isolate->context()->native_context();
-    JSObject* array_proto =
-        JSObject::cast(native_context->array_function()->prototype());
-    if (!ArrayPrototypeHasNoElements(heap, native_context, array_proto)) {
+    Object* array_proto = native_context->array_function()->prototype();
+    PrototypeIterator iter(isolate, array_proto,
+                           PrototypeIterator::START_AT_RECEIVER);
+    if (!ArrayPrototypeHasNoElements(heap, &iter)) {
       AllowHeapAllocation allow_allocation;
       return CallJsBuiltin(isolate, "ArrayConcatJS", args);
     }
@@ -987,12 +981,12 @@
   Handle<FixedArrayBase> storage(result_array->elements(), isolate);
   ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
   for (int i = 0; i < n_arguments; i++) {
-    // TODO(ishell): It is crucial to keep |array| as a raw pointer to avoid
-    // performance degradation. Revisit this later.
+    // It is crucial to keep |array| in a raw pointer form to avoid performance
+    // degradation.
     JSArray* array = JSArray::cast(args[i]);
     int len = Smi::cast(array->length())->value();
-    ElementsKind from_kind = array->GetElementsKind();
     if (len > 0) {
+      ElementsKind from_kind = array->GetElementsKind();
       accessor->CopyElements(array, 0, from_kind, storage, j, len);
       j += len;
     }
@@ -1279,11 +1273,6 @@
 }
 
 
-static void Generate_KeyedLoadIC_String(MacroAssembler* masm) {
-  KeyedLoadIC::GenerateString(masm);
-}
-
-
 static void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) {
   KeyedLoadIC::GeneratePreMonomorphic(masm);
 }
@@ -1314,6 +1303,16 @@
 }
 
 
+static void Generate_KeyedStoreIC_Megamorphic(MacroAssembler* masm) {
+  KeyedStoreIC::GenerateMegamorphic(masm, SLOPPY);
+}
+
+
+static void Generate_KeyedStoreIC_Megamorphic_Strict(MacroAssembler* masm) {
+  KeyedStoreIC::GenerateMegamorphic(masm, STRICT);
+}
+
+
 static void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) {
   KeyedStoreIC::GenerateGeneric(masm, SLOPPY);
 }
@@ -1562,14 +1561,14 @@
       // Move the code into the object heap.
       CodeDesc desc;
       masm.GetCode(&desc);
-      Code::Flags flags =  functions[i].flags;
+      Code::Flags flags = functions[i].flags;
       Handle<Code> code =
           isolate->factory()->NewCode(desc, flags, masm.CodeObject());
       // Log the event and add the code to the builtins array.
       PROFILE(isolate,
               CodeCreateEvent(Logger::BUILTIN_TAG, *code, functions[i].s_name));
       builtins_[i] = *code;
-      if (code->kind() == Code::BUILTIN) code->set_builtin_index(i);
+      code->set_builtin_index(i);
 #ifdef ENABLE_DISASSEMBLER
       if (FLAG_print_builtin_code) {
         CodeTracer::Scope trace_scope(isolate->GetCodeTracer());
diff --git a/src/builtins.h b/src/builtins.h
index c1ed91d..13a4b80 100644
--- a/src/builtins.h
+++ b/src/builtins.h
@@ -88,19 +88,21 @@
   V(KeyedLoadIC_PreMonomorphic, KEYED_LOAD_IC, PREMONOMORPHIC,                 \
     kNoExtraICState)                                                           \
   V(KeyedLoadIC_Generic, KEYED_LOAD_IC, GENERIC, kNoExtraICState)              \
-  V(KeyedLoadIC_String, KEYED_LOAD_IC, MEGAMORPHIC, kNoExtraICState)           \
                                                                                \
   V(StoreIC_Setter_ForDeopt, STORE_IC, MONOMORPHIC, StoreIC::kStrictModeState) \
                                                                                \
   V(KeyedStoreIC_Initialize, KEYED_STORE_IC, UNINITIALIZED, kNoExtraICState)   \
   V(KeyedStoreIC_PreMonomorphic, KEYED_STORE_IC, PREMONOMORPHIC,               \
     kNoExtraICState)                                                           \
+  V(KeyedStoreIC_Megamorphic, KEYED_STORE_IC, MEGAMORPHIC, kNoExtraICState)    \
   V(KeyedStoreIC_Generic, KEYED_STORE_IC, GENERIC, kNoExtraICState)            \
                                                                                \
   V(KeyedStoreIC_Initialize_Strict, KEYED_STORE_IC, UNINITIALIZED,             \
     StoreIC::kStrictModeState)                                                 \
   V(KeyedStoreIC_PreMonomorphic_Strict, KEYED_STORE_IC, PREMONOMORPHIC,        \
     StoreIC::kStrictModeState)                                                 \
+  V(KeyedStoreIC_Megamorphic_Strict, KEYED_STORE_IC, MEGAMORPHIC,              \
+    StoreIC::kStrictModeState)                                                 \
   V(KeyedStoreIC_Generic_Strict, KEYED_STORE_IC, GENERIC,                      \
     StoreIC::kStrictModeState)                                                 \
   V(KeyedStoreIC_SloppyArguments, KEYED_STORE_IC, MONOMORPHIC,                 \
diff --git a/src/cached-powers.cc b/src/cached-powers.cc
index dd9e3b4..ccf8882 100644
--- a/src/cached-powers.cc
+++ b/src/cached-powers.cc
@@ -4,9 +4,9 @@
 
 #include <limits.h>
 #include <stdarg.h>
+#include <stdint.h>
 #include <cmath>
 
-#include "include/v8stdint.h"
 #include "src/base/logging.h"
 #include "src/cached-powers.h"
 #include "src/globals.h"
diff --git a/src/char-predicates.cc b/src/char-predicates.cc
new file mode 100644
index 0000000..ab551d8
--- /dev/null
+++ b/src/char-predicates.cc
@@ -0,0 +1,42 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/char-predicates.h"
+
+#ifdef V8_I18N_SUPPORT
+#include "unicode/uchar.h"
+#include "unicode/urename.h"
+#endif  // V8_I18N_SUPPORT
+
+namespace v8 {
+namespace internal {
+
+bool SupplementaryPlanes::IsIDStart(uc32 c) {
+  DCHECK(c > 0xFFFF);
+#ifdef V8_I18N_SUPPORT
+  // This only works for code points in the SMPs, since ICU does not exclude
+  // code points with properties 'Pattern_Syntax' or 'Pattern_White_Space'.
+  // Code points in the SMP do not have those properties.
+  return u_isIDStart(c);
+#else
+  // This is incorrect, but if we don't have ICU, use this as fallback.
+  return false;
+#endif  // V8_I18N_SUPPORT
+}
+
+
+bool SupplementaryPlanes::IsIDPart(uc32 c) {
+  DCHECK(c > 0xFFFF);
+#ifdef V8_I18N_SUPPORT
+  // This only works for code points in the SMPs, since ICU does not exclude
+  // code points with properties 'Pattern_Syntax' or 'Pattern_White_Space'.
+  // Code points in the SMP do not have those properties.
+  return u_isIDPart(c);
+#else
+  // This is incorrect, but if we don't have ICU, use this as fallback.
+  return false;
+#endif  // V8_I18N_SUPPORT
+}
+}
+}  // namespace v8::internal
diff --git a/src/char-predicates.h b/src/char-predicates.h
index b7c5d42..5ecb07d 100644
--- a/src/char-predicates.h
+++ b/src/char-predicates.h
@@ -22,42 +22,54 @@
 inline bool IsRegExpWord(uc32 c);
 inline bool IsRegExpNewline(uc32 c);
 
+
+struct SupplementaryPlanes {
+  static bool IsIDStart(uc32 c);
+  static bool IsIDPart(uc32 c);
+};
+
+
+// ES6 draft section 11.6
+// This includes '_', '$' and '\', and ID_Start according to
+// http://www.unicode.org/reports/tr31/, which consists of categories
+// 'Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl', but excluding properties
+// 'Pattern_Syntax' or 'Pattern_White_Space'.
+// For code points in the SMPs, we can resort to ICU (if available).
 struct IdentifierStart {
   static inline bool Is(uc32 c) {
-    switch (c) {
-      case '$': case '_': case '\\': return true;
-      default: return unibrow::Letter::Is(c);
-    }
+    if (c > 0xFFFF) return SupplementaryPlanes::IsIDStart(c);
+    return unibrow::ID_Start::Is(c);
   }
 };
 
 
+// ES6 draft section 11.6
+// This includes \u200c and \u200d, and ID_Continue according to
+// http://www.unicode.org/reports/tr31/, which consists of ID_Start,
+// the categories 'Mn', 'Mc', 'Nd', 'Pc', but excluding properties
+// 'Pattern_Syntax' or 'Pattern_White_Space'.
+// For code points in the SMPs, we can resort to ICU (if available).
 struct IdentifierPart {
   static inline bool Is(uc32 c) {
-    return IdentifierStart::Is(c)
-        || unibrow::Number::Is(c)
-        || c == 0x200C  // U+200C is Zero-Width Non-Joiner.
-        || c == 0x200D  // U+200D is Zero-Width Joiner.
-        || unibrow::CombiningMark::Is(c)
-        || unibrow::ConnectorPunctuation::Is(c);
+    if (c > 0xFFFF) return SupplementaryPlanes::IsIDPart(c);
+    return unibrow::ID_Start::Is(c) || unibrow::ID_Continue::Is(c);
   }
 };
 
 
-// WhiteSpace according to ECMA-262 5.1, 7.2.
+// ES6 draft section 11.2
+// This includes all code points of Unicode category 'Zs'.
+// \u180e stops being one as of Unicode 6.3.0, but ES6 adheres to Unicode 5.1,
+// so it is also included.
+// Further included are \u0009, \u000b, \u0020, \u00a0, \u000c, and \ufeff.
+// There are no category 'Zs' code points in the SMPs.
 struct WhiteSpace {
-  static inline bool Is(uc32 c) {
-    return c == 0x0009 ||  // <TAB>
-           c == 0x000B ||  // <VT>
-           c == 0x000C ||  // <FF>
-           c == 0xFEFF ||  // <BOM>
-           // \u0020 and \u00A0 are included in unibrow::WhiteSpace.
-           unibrow::WhiteSpace::Is(c);
-  }
+  static inline bool Is(uc32 c) { return unibrow::WhiteSpace::Is(c); }
 };
 
 
-// WhiteSpace and LineTerminator according to ECMA-262 5.1, 7.2 and 7.3.
+// WhiteSpace and LineTerminator according to ES6 draft section 11.2 and 11.3
+// This consists of \000a, \000d, \u2028, and \u2029.
 struct WhiteSpaceOrLineTerminator {
   static inline bool Is(uc32 c) {
     return WhiteSpace::Is(c) || unibrow::LineTerminator::Is(c);
diff --git a/src/checks.h b/src/checks.h
index 6303855..6ba64c1 100644
--- a/src/checks.h
+++ b/src/checks.h
@@ -7,12 +7,6 @@
 
 #include "src/base/logging.h"
 
-#ifdef DEBUG
-#ifndef OPTIMIZED_DEBUG
-#define ENABLE_SLOW_DCHECKS    1
-#endif
-#endif
-
 namespace v8 {
 
 class Value;
diff --git a/src/code-factory.cc b/src/code-factory.cc
index c969c8f..e68d539 100644
--- a/src/code-factory.cc
+++ b/src/code-factory.cc
@@ -20,13 +20,35 @@
 
 
 // static
+Callable CodeFactory::LoadICInOptimizedCode(Isolate* isolate,
+                                            ContextualMode mode) {
+  if (FLAG_vector_ics) {
+    return Callable(LoadIC::initialize_stub_in_optimized_code(
+                        isolate, LoadICState(mode).GetExtraICState()),
+                    VectorLoadICDescriptor(isolate));
+  }
+  return CodeFactory::LoadIC(isolate, mode);
+}
+
+
+// static
 Callable CodeFactory::KeyedLoadIC(Isolate* isolate) {
-  return Callable(isolate->builtins()->KeyedLoadIC_Initialize(),
+  return Callable(KeyedLoadIC::initialize_stub(isolate),
                   LoadDescriptor(isolate));
 }
 
 
 // static
+Callable CodeFactory::KeyedLoadICInOptimizedCode(Isolate* isolate) {
+  if (FLAG_vector_ics) {
+    return Callable(KeyedLoadIC::initialize_stub_in_optimized_code(isolate),
+                    VectorLoadICDescriptor(isolate));
+  }
+  return CodeFactory::KeyedLoadIC(isolate);
+}
+
+
+// static
 Callable CodeFactory::StoreIC(Isolate* isolate, StrictMode mode) {
   return Callable(StoreIC::initialize_stub(isolate, mode),
                   StoreDescriptor(isolate));
@@ -82,6 +104,13 @@
 
 
 // static
+Callable CodeFactory::AllocateHeapNumber(Isolate* isolate) {
+  AllocateHeapNumberStub stub(isolate);
+  return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
+}
+
+
+// static
 Callable CodeFactory::CallFunction(Isolate* isolate, int argc,
                                    CallFunctionFlags flags) {
   CallFunctionStub stub(isolate, argc, flags);
diff --git a/src/code-factory.h b/src/code-factory.h
index 3add384..f26bf2a 100644
--- a/src/code-factory.h
+++ b/src/code-factory.h
@@ -33,7 +33,9 @@
  public:
   // Initial states for ICs.
   static Callable LoadIC(Isolate* isolate, ContextualMode mode);
+  static Callable LoadICInOptimizedCode(Isolate* isolate, ContextualMode mode);
   static Callable KeyedLoadIC(Isolate* isolate);
+  static Callable KeyedLoadICInOptimizedCode(Isolate* isolate);
   static Callable StoreIC(Isolate* isolate, StrictMode mode);
   static Callable KeyedStoreIC(Isolate* isolate, StrictMode mode);
 
@@ -53,9 +55,13 @@
   static Callable StringAdd(Isolate* isolate, StringAddFlags flags,
                             PretenureFlag pretenure_flag);
 
+  static Callable AllocateHeapNumber(Isolate* isolate);
+
   static Callable CallFunction(Isolate* isolate, int argc,
                                CallFunctionFlags flags);
 };
-}
-}
+
+}  // namespace internal
+}  // namespace v8
+
 #endif  // V8_CODE_FACTORY_H_
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index dafef52..800a09d 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -8,6 +8,7 @@
 #include "src/code-stubs.h"
 #include "src/field-index.h"
 #include "src/hydrogen.h"
+#include "src/ic/ic.h"
 #include "src/lithium.h"
 
 namespace v8 {
@@ -34,11 +35,11 @@
 
 class CodeStubGraphBuilderBase : public HGraphBuilder {
  public:
-  CodeStubGraphBuilderBase(Isolate* isolate, HydrogenCodeStub* stub)
-      : HGraphBuilder(&info_),
+  explicit CodeStubGraphBuilderBase(CompilationInfoWithZone* info)
+      : HGraphBuilder(info),
         arguments_length_(NULL),
-        info_(stub, isolate),
-        descriptor_(stub),
+        info_(info),
+        descriptor_(info->code_stub()),
         context_(NULL) {
     int parameter_count = descriptor_.GetEnvironmentParameterCount();
     parameters_.Reset(new HParameter*[parameter_count]);
@@ -56,15 +57,16 @@
     DCHECK(arguments_length_ != NULL);
     return arguments_length_;
   }
-  CompilationInfo* info() { return &info_; }
-  HydrogenCodeStub* stub() { return info_.code_stub(); }
+  CompilationInfo* info() { return info_; }
+  HydrogenCodeStub* stub() { return info_->code_stub(); }
   HContext* context() { return context_; }
-  Isolate* isolate() { return info_.isolate(); }
+  Isolate* isolate() { return info_->isolate(); }
 
   HLoadNamedField* BuildLoadNamedField(HValue* object,
                                        FieldIndex index);
   void BuildStoreNamedField(HValue* object, HValue* value, FieldIndex index,
-                            Representation representation);
+                            Representation representation,
+                            bool transition_to_field);
 
   enum ArgumentClass {
     NONE,
@@ -98,6 +100,21 @@
                                         HValue* shared_info,
                                         HValue* native_context);
 
+  // Tail calls handler found at array[map_index + 1].
+  void TailCallHandler(HValue* receiver, HValue* name, HValue* array,
+                       HValue* map_index, HValue* slot, HValue* vector);
+
+  // Tail calls handler_code.
+  void TailCallHandler(HValue* receiver, HValue* name, HValue* slot,
+                       HValue* vector, HValue* handler_code);
+
+  void TailCallMiss(HValue* receiver, HValue* name, HValue* slot,
+                    HValue* vector, bool keyed_load);
+
+  // Handle MONOMORPHIC and POLYMORPHIC LoadIC and KeyedLoadIC cases.
+  void HandleArrayCases(HValue* array, HValue* receiver, HValue* name,
+                        HValue* slot, HValue* vector, bool keyed_load);
+
  private:
   HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
   HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
@@ -105,7 +122,7 @@
 
   SmartArrayPointer<HParameter*> parameters_;
   HValue* arguments_length_;
-  CompilationInfoWithZone info_;
+  CompilationInfoWithZone* info_;
   CodeStubDescriptor descriptor_;
   HContext* context_;
 };
@@ -119,7 +136,7 @@
     const char* name = CodeStub::MajorName(stub()->MajorKey(), false);
     PrintF("-----------------------------------------------------------\n");
     PrintF("Compiling stub %s using hydrogen\n", name);
-    isolate()->GetHTracer()->TraceCompilation(&info_);
+    isolate()->GetHTracer()->TraceCompilation(info());
   }
 
   int param_count = descriptor_.GetEnvironmentParameterCount();
@@ -188,8 +205,8 @@
 template <class Stub>
 class CodeStubGraphBuilder: public CodeStubGraphBuilderBase {
  public:
-  CodeStubGraphBuilder(Isolate* isolate, Stub* stub)
-      : CodeStubGraphBuilderBase(isolate, stub) {}
+  explicit CodeStubGraphBuilder(CompilationInfoWithZone* info)
+      : CodeStubGraphBuilderBase(info) {}
 
  protected:
   virtual HValue* BuildCodeStub() {
@@ -232,6 +249,8 @@
 
     // Generate the code for the stub.
     masm.set_generating_stub(true);
+    // TODO(yangguo): remove this once we can serialize IC stubs.
+    masm.enable_serializer();
     NoCurrentFrameScope scope(&masm);
     GenerateLightweightMiss(&masm, miss);
   }
@@ -268,52 +287,20 @@
   if (FLAG_profile_hydrogen_code_stub_compilation) {
     timer.Start();
   }
-  CodeStubGraphBuilder<Stub> builder(isolate, stub);
+  CompilationInfoWithZone info(stub, isolate);
+  CodeStubGraphBuilder<Stub> builder(&info);
   LChunk* chunk = OptimizeGraph(builder.CreateGraph());
-  // TODO(yangguo) remove this once the code serializer handles code stubs.
-  if (FLAG_serialize_toplevel) chunk->info()->PrepareForSerializing();
   Handle<Code> code = chunk->Codegen();
   if (FLAG_profile_hydrogen_code_stub_compilation) {
     OFStream os(stdout);
     os << "[Lazy compilation of " << stub << " took "
-       << timer.Elapsed().InMillisecondsF() << " ms]" << endl;
+       << timer.Elapsed().InMillisecondsF() << " ms]" << std::endl;
   }
   return code;
 }
 
 
 template <>
-HValue* CodeStubGraphBuilder<ToNumberStub>::BuildCodeStub() {
-  HValue* value = GetParameter(0);
-
-  // Check if the parameter is already a SMI or heap number.
-  IfBuilder if_number(this);
-  if_number.If<HIsSmiAndBranch>(value);
-  if_number.OrIf<HCompareMap>(value, isolate()->factory()->heap_number_map());
-  if_number.Then();
-
-  // Return the number.
-  Push(value);
-
-  if_number.Else();
-
-  // Convert the parameter to number using the builtin.
-  HValue* function = AddLoadJSBuiltin(Builtins::TO_NUMBER);
-  Add<HPushArguments>(value);
-  Push(Add<HInvokeFunction>(function, 1));
-
-  if_number.End();
-
-  return Pop();
-}
-
-
-Handle<Code> ToNumberStub::GenerateCode() {
-  return DoGenerateCode(this);
-}
-
-
-template <>
 HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() {
   info()->MarkAsSavesCallerDoubles();
   HValue* number = GetParameter(NumberToStringStub::kNumber);
@@ -336,10 +323,8 @@
   // so that it doesn't build and eager frame.
   info()->MarkMustNotHaveEagerFrame();
 
-  HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0),
-                                                  GetParameter(1),
-                                                  static_cast<HValue*>(NULL),
-                                                  FAST_ELEMENTS);
+  HInstruction* allocation_site =
+      Add<HLoadKeyed>(GetParameter(0), GetParameter(1), nullptr, FAST_ELEMENTS);
   IfBuilder checker(this);
   checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
                                                     undefined);
@@ -347,8 +332,8 @@
 
   HObjectAccess access = HObjectAccess::ForAllocationSiteOffset(
       AllocationSite::kTransitionInfoOffset);
-  HInstruction* boilerplate = Add<HLoadNamedField>(
-      allocation_site, static_cast<HValue*>(NULL), access);
+  HInstruction* boilerplate =
+      Add<HLoadNamedField>(allocation_site, nullptr, access);
   HValue* elements = AddLoadElements(boilerplate);
   HValue* capacity = AddLoadFixedArrayLength(elements);
   IfBuilder zero_capacity(this);
@@ -400,10 +385,8 @@
 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
   HValue* undefined = graph()->GetConstantUndefined();
 
-  HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0),
-                                                  GetParameter(1),
-                                                  static_cast<HValue*>(NULL),
-                                                  FAST_ELEMENTS);
+  HInstruction* allocation_site =
+      Add<HLoadKeyed>(GetParameter(0), GetParameter(1), nullptr, FAST_ELEMENTS);
 
   IfBuilder checker(this);
   checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
@@ -412,21 +395,24 @@
 
   HObjectAccess access = HObjectAccess::ForAllocationSiteOffset(
       AllocationSite::kTransitionInfoOffset);
-  HInstruction* boilerplate = Add<HLoadNamedField>(
-      allocation_site, static_cast<HValue*>(NULL), access);
+  HInstruction* boilerplate =
+      Add<HLoadNamedField>(allocation_site, nullptr, access);
 
-  int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize;
+  int length = casted_stub()->length();
+  if (length == 0) {
+    // Empty objects have some slack added to them.
+    length = JSObject::kInitialGlobalObjectUnusedPropertiesCount;
+  }
+  int size = JSObject::kHeaderSize + length * kPointerSize;
   int object_size = size;
   if (FLAG_allocation_site_pretenuring) {
     size += AllocationMemento::kSize;
   }
 
-  HValue* boilerplate_map = Add<HLoadNamedField>(
-      boilerplate, static_cast<HValue*>(NULL),
-      HObjectAccess::ForMap());
+  HValue* boilerplate_map =
+      Add<HLoadNamedField>(boilerplate, nullptr, HObjectAccess::ForMap());
   HValue* boilerplate_size = Add<HLoadNamedField>(
-      boilerplate_map, static_cast<HValue*>(NULL),
-      HObjectAccess::ForMapInstanceSize());
+      boilerplate_map, nullptr, HObjectAccess::ForMapInstanceSize());
   HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2);
   checker.If<HCompareNumericAndBranch>(boilerplate_size,
                                        size_in_words, Token::EQ);
@@ -439,9 +425,8 @@
 
   for (int i = 0; i < object_size; i += kPointerSize) {
     HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(i);
-    Add<HStoreNamedField>(
-        object, access, Add<HLoadNamedField>(
-            boilerplate, static_cast<HValue*>(NULL), access));
+    Add<HStoreNamedField>(object, access,
+                          Add<HLoadNamedField>(boilerplate, nullptr, access));
   }
 
   DCHECK(FLAG_allocation_site_pretenuring || (size == object_size));
@@ -510,9 +495,8 @@
   // Link the object to the allocation site list
   HValue* site_list = Add<HConstant>(
       ExternalReference::allocation_sites_list_address(isolate()));
-  HValue* site = Add<HLoadNamedField>(
-      site_list, static_cast<HValue*>(NULL),
-      HObjectAccess::ForAllocationSiteList());
+  HValue* site = Add<HLoadNamedField>(site_list, nullptr,
+                                      HObjectAccess::ForAllocationSiteList());
   // TODO(mvstanton): This is a store to a weak pointer, which we may want to
   // mark as such in order to skip the write barrier, once we have a unified
   // system for weakness. For now we decided to keep it like this because having
@@ -539,6 +523,40 @@
 
 
 template <>
+HValue* CodeStubGraphBuilder<LoadScriptContextFieldStub>::BuildCodeStub() {
+  int context_index = casted_stub()->context_index();
+  int slot_index = casted_stub()->slot_index();
+
+  HValue* script_context = BuildGetScriptContext(context_index);
+  return Add<HLoadNamedField>(script_context, nullptr,
+                              HObjectAccess::ForContextSlot(slot_index));
+}
+
+
+Handle<Code> LoadScriptContextFieldStub::GenerateCode() {
+  return DoGenerateCode(this);
+}
+
+
+template <>
+HValue* CodeStubGraphBuilder<StoreScriptContextFieldStub>::BuildCodeStub() {
+  int context_index = casted_stub()->context_index();
+  int slot_index = casted_stub()->slot_index();
+
+  HValue* script_context = BuildGetScriptContext(context_index);
+  Add<HStoreNamedField>(script_context,
+                        HObjectAccess::ForContextSlot(slot_index),
+                        GetParameter(2), STORE_TO_INITIALIZED_ENTRY);
+  return GetParameter(2);
+}
+
+
+Handle<Code> StoreScriptContextFieldStub::GenerateCode() {
+  return DoGenerateCode(this);
+}
+
+
+template <>
 HValue* CodeStubGraphBuilder<LoadFastElementStub>::BuildCodeStub() {
   HInstruction* load = BuildUncheckedMonomorphicElementAccess(
       GetParameter(LoadDescriptor::kReceiverIndex),
@@ -563,15 +581,15 @@
   HObjectAccess access = index.is_inobject()
       ? HObjectAccess::ForObservableJSObjectOffset(offset, representation)
       : HObjectAccess::ForBackingStoreOffset(offset, representation);
-  if (index.is_double()) {
+  if (index.is_double() &&
+      (!FLAG_unbox_double_fields || !index.is_inobject())) {
     // Load the heap number.
     object = Add<HLoadNamedField>(
-        object, static_cast<HValue*>(NULL),
-        access.WithRepresentation(Representation::Tagged()));
+        object, nullptr, access.WithRepresentation(Representation::Tagged()));
     // Load the double value from it.
     access = HObjectAccess::ForHeapNumberValue();
   }
-  return Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), access);
+  return Add<HLoadNamedField>(object, nullptr, access);
 }
 
 
@@ -591,12 +609,10 @@
   HValue* map = AddLoadMap(GetParameter(0), NULL);
   HObjectAccess descriptors_access = HObjectAccess::ForObservableJSObjectOffset(
       Map::kDescriptorsOffset, Representation::Tagged());
-  HValue* descriptors =
-      Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), descriptors_access);
+  HValue* descriptors = Add<HLoadNamedField>(map, nullptr, descriptors_access);
   HObjectAccess value_access = HObjectAccess::ForObservableJSObjectOffset(
       DescriptorArray::GetValueOffset(casted_stub()->constant_index()));
-  return Add<HLoadNamedField>(descriptors, static_cast<HValue*>(NULL),
-                              value_access);
+  return Add<HLoadNamedField>(descriptors, nullptr, value_access);
 }
 
 
@@ -605,20 +621,19 @@
 
 HValue* CodeStubGraphBuilderBase::UnmappedCase(HValue* elements, HValue* key) {
   HValue* result;
-  HInstruction* backing_store = Add<HLoadKeyed>(
-      elements, graph()->GetConstant1(), static_cast<HValue*>(NULL),
-      FAST_ELEMENTS, ALLOW_RETURN_HOLE);
+  HInstruction* backing_store =
+      Add<HLoadKeyed>(elements, graph()->GetConstant1(), nullptr, FAST_ELEMENTS,
+                      ALLOW_RETURN_HOLE);
   Add<HCheckMaps>(backing_store, isolate()->factory()->fixed_array_map());
-  HValue* backing_store_length =
-      Add<HLoadNamedField>(backing_store, static_cast<HValue*>(NULL),
-                           HObjectAccess::ForFixedArrayLength());
+  HValue* backing_store_length = Add<HLoadNamedField>(
+      backing_store, nullptr, HObjectAccess::ForFixedArrayLength());
   IfBuilder in_unmapped_range(this);
   in_unmapped_range.If<HCompareNumericAndBranch>(key, backing_store_length,
                                                  Token::LT);
   in_unmapped_range.Then();
   {
-    result = Add<HLoadKeyed>(backing_store, key, static_cast<HValue*>(NULL),
-                             FAST_HOLEY_ELEMENTS, NEVER_RETURN_HOLE);
+    result = Add<HLoadKeyed>(backing_store, key, nullptr, FAST_HOLEY_ELEMENTS,
+                             NEVER_RETURN_HOLE);
   }
   in_unmapped_range.ElseDeopt("Outside of range");
   in_unmapped_range.End();
@@ -665,19 +680,17 @@
   positive_smi.End();
 
   HValue* constant_two = Add<HConstant>(2);
-  HValue* elements = AddLoadElements(receiver, static_cast<HValue*>(NULL));
-  HValue* elements_length =
-      Add<HLoadNamedField>(elements, static_cast<HValue*>(NULL),
-                           HObjectAccess::ForFixedArrayLength());
+  HValue* elements = AddLoadElements(receiver, nullptr);
+  HValue* elements_length = Add<HLoadNamedField>(
+      elements, nullptr, HObjectAccess::ForFixedArrayLength());
   HValue* adjusted_length = AddUncasted<HSub>(elements_length, constant_two);
   IfBuilder in_range(this);
   in_range.If<HCompareNumericAndBranch>(key, adjusted_length, Token::LT);
   in_range.Then();
   {
     HValue* index = AddUncasted<HAdd>(key, constant_two);
-    HInstruction* mapped_index =
-        Add<HLoadKeyed>(elements, index, static_cast<HValue*>(NULL),
-                        FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE);
+    HInstruction* mapped_index = Add<HLoadKeyed>(
+        elements, index, nullptr, FAST_HOLEY_ELEMENTS, ALLOW_RETURN_HOLE);
 
     IfBuilder is_valid(this);
     is_valid.IfNot<HCompareObjectEqAndBranch>(mapped_index,
@@ -687,13 +700,11 @@
       // TODO(mvstanton): I'd like to assert from this point, that if the
       // mapped_index is not the hole that it is indeed, a smi. An unnecessary
       // smi check is being emitted.
-      HValue* the_context =
-          Add<HLoadKeyed>(elements, graph()->GetConstant0(),
-                          static_cast<HValue*>(NULL), FAST_ELEMENTS);
+      HValue* the_context = Add<HLoadKeyed>(elements, graph()->GetConstant0(),
+                                            nullptr, FAST_ELEMENTS);
       DCHECK(Context::kHeaderSize == FixedArray::kHeaderSize);
-      HValue* result =
-          Add<HLoadKeyed>(the_context, mapped_index, static_cast<HValue*>(NULL),
-                          FAST_ELEMENTS, ALLOW_RETURN_HOLE);
+      HValue* result = Add<HLoadKeyed>(the_context, mapped_index, nullptr,
+                                       FAST_ELEMENTS, ALLOW_RETURN_HOLE);
       environment()->Push(result);
     }
     is_valid.Else();
@@ -721,7 +732,7 @@
 
 void CodeStubGraphBuilderBase::BuildStoreNamedField(
     HValue* object, HValue* value, FieldIndex index,
-    Representation representation) {
+    Representation representation, bool transition_to_field) {
   DCHECK(!index.is_double() || representation.IsDouble());
   int offset = index.offset();
   HObjectAccess access =
@@ -730,12 +741,32 @@
           : HObjectAccess::ForBackingStoreOffset(offset, representation);
 
   if (representation.IsDouble()) {
-    // Load the heap number.
-    object = Add<HLoadNamedField>(
-        object, static_cast<HValue*>(NULL),
-        access.WithRepresentation(Representation::Tagged()));
-    // Store the double value into it.
-    access = HObjectAccess::ForHeapNumberValue();
+    if (!FLAG_unbox_double_fields || !index.is_inobject()) {
+      HObjectAccess heap_number_access =
+          access.WithRepresentation(Representation::Tagged());
+      if (transition_to_field) {
+        // The store requires a mutable HeapNumber to be allocated.
+        NoObservableSideEffectsScope no_side_effects(this);
+        HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize);
+
+        // TODO(hpayer): Allocation site pretenuring support.
+        HInstruction* heap_number =
+            Add<HAllocate>(heap_number_size, HType::HeapObject(), NOT_TENURED,
+                           MUTABLE_HEAP_NUMBER_TYPE);
+        AddStoreMapConstant(heap_number,
+                            isolate()->factory()->mutable_heap_number_map());
+        Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(),
+                              value);
+        // Store the new mutable heap number into the object.
+        access = heap_number_access;
+        value = heap_number;
+      } else {
+        // Load the heap number.
+        object = Add<HLoadNamedField>(object, nullptr, heap_number_access);
+        // Store the double value into it.
+        access = HObjectAccess::ForHeapNumberValue();
+      }
+    }
   } else if (representation.IsHeapObject()) {
     BuildCheckHeapObject(value);
   }
@@ -747,7 +778,7 @@
 template <>
 HValue* CodeStubGraphBuilder<StoreFieldStub>::BuildCodeStub() {
   BuildStoreNamedField(GetParameter(0), GetParameter(2), casted_stub()->index(),
-                       casted_stub()->representation());
+                       casted_stub()->representation(), false);
   return GetParameter(2);
 }
 
@@ -756,6 +787,58 @@
 
 
 template <>
+HValue* CodeStubGraphBuilder<StoreTransitionStub>::BuildCodeStub() {
+  HValue* object = GetParameter(StoreTransitionDescriptor::kReceiverIndex);
+
+  switch (casted_stub()->store_mode()) {
+    case StoreTransitionStub::ExtendStorageAndStoreMapAndValue: {
+      HValue* properties = Add<HLoadNamedField>(
+          object, nullptr, HObjectAccess::ForPropertiesPointer());
+      HValue* length = AddLoadFixedArrayLength(properties);
+      HValue* delta =
+          Add<HConstant>(static_cast<int32_t>(JSObject::kFieldsAdded));
+      HValue* new_capacity = AddUncasted<HAdd>(length, delta);
+
+      // Grow properties array.
+      ElementsKind kind = FAST_ELEMENTS;
+      Add<HBoundsCheck>(new_capacity,
+                        Add<HConstant>((Page::kMaxRegularHeapObjectSize -
+                                        FixedArray::kHeaderSize) >>
+                                       ElementsKindToShiftSize(kind)));
+
+      // Reuse this code for properties backing store allocation.
+      HValue* new_properties =
+          BuildAllocateAndInitializeArray(kind, new_capacity);
+
+      BuildCopyProperties(properties, new_properties, length, new_capacity);
+
+      Add<HStoreNamedField>(object, HObjectAccess::ForPropertiesPointer(),
+                            new_properties);
+    }
+    // Fall through.
+    case StoreTransitionStub::StoreMapAndValue:
+      // Store the new value into the "extended" object.
+      BuildStoreNamedField(
+          object, GetParameter(StoreTransitionDescriptor::kValueIndex),
+          casted_stub()->index(), casted_stub()->representation(), true);
+    // Fall through.
+
+    case StoreTransitionStub::StoreMapOnly:
+      // And finally update the map.
+      Add<HStoreNamedField>(object, HObjectAccess::ForMap(),
+                            GetParameter(StoreTransitionDescriptor::kMapIndex));
+      break;
+  }
+  return GetParameter(StoreTransitionDescriptor::kValueIndex);
+}
+
+
+Handle<Code> StoreTransitionStub::GenerateCode() {
+  return DoGenerateCode(this);
+}
+
+
+template <>
 HValue* CodeStubGraphBuilder<StringLengthStub>::BuildCodeStub() {
   HValue* string = BuildLoadNamedField(GetParameter(0),
       FieldIndex::ForInObjectOffset(JSValue::kValueOffset));
@@ -805,6 +888,22 @@
   return DoGenerateCode(this);
 }
 
+
+template <>
+HValue* CodeStubGraphBuilder<AllocateHeapNumberStub>::BuildCodeStub() {
+  HValue* result =
+      Add<HAllocate>(Add<HConstant>(HeapNumber::kSize), HType::HeapNumber(),
+                     NOT_TENURED, HEAP_NUMBER_TYPE);
+  AddStoreMapConstant(result, isolate()->factory()->heap_number_map());
+  return result;
+}
+
+
+Handle<Code> AllocateHeapNumberStub::GenerateCode() {
+  return DoGenerateCode(this);
+}
+
+
 HValue* CodeStubGraphBuilderBase::BuildArrayConstructor(
     ElementsKind kind,
     AllocationSiteOverrideMode override_mode,
@@ -1003,7 +1102,7 @@
   HIfContinuation continuation;
   Handle<Map> sentinel_map(isolate->heap()->meta_map());
   Type* type = stub->GetType(zone(), sentinel_map);
-  BuildCompareNil(GetParameter(0), type, &continuation);
+  BuildCompareNil(GetParameter(0), type, &continuation, kEmbedMapsViaWeakCells);
   IfBuilder if_nil(this, &continuation);
   if_nil.Then();
   if (continuation.IsFalseReachable()) {
@@ -1228,8 +1327,7 @@
 
   HValue* cell = Add<HConstant>(placeholder_cell);
   HObjectAccess access(HObjectAccess::ForCellPayload(isolate()));
-  HValue* cell_contents = Add<HLoadNamedField>(
-      cell, static_cast<HValue*>(NULL), access);
+  HValue* cell_contents = Add<HLoadNamedField>(cell, nullptr, access);
 
   if (stub->is_constant()) {
     IfBuilder builder(this);
@@ -1327,7 +1425,7 @@
 
   // Now link a function into a list of optimized functions.
   HValue* optimized_functions_list = Add<HLoadNamedField>(
-      native_context, static_cast<HValue*>(NULL),
+      native_context, nullptr,
       HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
   Add<HStoreNamedField>(js_function,
                         HObjectAccess::ForNextFunctionLinkPointer(),
@@ -1347,8 +1445,8 @@
   Add<HStoreNamedField>(js_function,
                         HObjectAccess::ForNextFunctionLinkPointer(),
                         graph()->GetConstantUndefined());
-  HValue* code_object = Add<HLoadNamedField>(
-      shared_info, static_cast<HValue*>(NULL), HObjectAccess::ForCodeOffset());
+  HValue* code_object = Add<HLoadNamedField>(shared_info, nullptr,
+                                             HObjectAccess::ForCodeOffset());
   Add<HStoreCodeEntry>(js_function, code_object);
 }
 
@@ -1365,8 +1463,8 @@
     HValue* field_offset_value = Add<HConstant>(field_offset);
     field_slot = AddUncasted<HAdd>(iterator, field_offset_value);
   }
-  HInstruction* field_entry = Add<HLoadKeyed>(optimized_map, field_slot,
-      static_cast<HValue*>(NULL), FAST_ELEMENTS);
+  HInstruction* field_entry =
+      Add<HLoadKeyed>(optimized_map, field_slot, nullptr, FAST_ELEMENTS);
   return field_entry;
 }
 
@@ -1378,8 +1476,7 @@
   Counters* counters = isolate()->counters();
   IfBuilder is_optimized(this);
   HInstruction* optimized_map = Add<HLoadNamedField>(
-      shared_info, static_cast<HValue*>(NULL),
-      HObjectAccess::ForOptimizedCodeMap());
+      shared_info, nullptr, HObjectAccess::ForOptimizedCodeMap());
   HValue* null_constant = Add<HConstant>(0);
   is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant);
   is_optimized.Then();
@@ -1412,8 +1509,7 @@
                                LoopBuilder::kPostDecrement,
                                shared_function_entry_length);
       HValue* array_length = Add<HLoadNamedField>(
-          optimized_map, static_cast<HValue*>(NULL),
-          HObjectAccess::ForFixedArrayLength());
+          optimized_map, nullptr, HObjectAccess::ForFixedArrayLength());
       HValue* start_pos = AddUncasted<HSub>(array_length,
                                             shared_function_entry_length);
       HValue* slot_iterator = loop_builder.BeginBody(start_pos,
@@ -1457,8 +1553,8 @@
 
   // Create a new closure from the given function info in new space
   HValue* size = Add<HConstant>(JSFunction::kSize);
-  HInstruction* js_function = Add<HAllocate>(size, HType::JSObject(),
-                                             NOT_TENURED, JS_FUNCTION_TYPE);
+  HInstruction* js_function =
+      Add<HAllocate>(size, HType::JSObject(), NOT_TENURED, JS_FUNCTION_TYPE);
 
   int map_index = Context::FunctionMapIndex(casted_stub()->strict_mode(),
                                             casted_stub()->kind());
@@ -1467,8 +1563,7 @@
   // as the map of the allocated object.
   HInstruction* native_context = BuildGetNativeContext();
   HInstruction* map_slot_value = Add<HLoadNamedField>(
-      native_context, static_cast<HValue*>(NULL),
-      HObjectAccess::ForContextSlot(map_index));
+      native_context, nullptr, HObjectAccess::ForContextSlot(map_index));
   Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value);
 
   // Initialize the rest of the function.
@@ -1480,9 +1575,8 @@
                         empty_fixed_array);
   Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
                         graph()->GetConstantHole());
-  Add<HStoreNamedField>(js_function,
-                        HObjectAccess::ForSharedFunctionInfoPointer(),
-                        shared_info);
+  Add<HStoreNamedField>(
+      js_function, HObjectAccess::ForSharedFunctionInfoPointer(), shared_info);
   Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
                         context());
 
@@ -1536,7 +1630,7 @@
 
   // Copy the global object from the previous context.
   HValue* global_object = Add<HLoadNamedField>(
-      context(), static_cast<HValue*>(NULL),
+      context(), nullptr,
       HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
   Add<HStoreNamedField>(function_context,
                         HObjectAccess::ForContextSlot(
@@ -1601,8 +1695,8 @@
 class CodeStubGraphBuilder<KeyedLoadGenericStub>
     : public CodeStubGraphBuilderBase {
  public:
-  CodeStubGraphBuilder(Isolate* isolate, KeyedLoadGenericStub* stub)
-      : CodeStubGraphBuilderBase(isolate, stub) {}
+  explicit CodeStubGraphBuilder(CompilationInfoWithZone* info)
+      : CodeStubGraphBuilderBase(info) {}
 
  protected:
   virtual HValue* BuildCodeStub();
@@ -1701,16 +1795,14 @@
       (1 << Map::kHasIndexedInterceptor);
     BuildJSObjectCheck(receiver, bit_field_mask);
 
-    HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
-                                       HObjectAccess::ForMap());
+    HValue* map =
+        Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap());
 
     HValue* instance_type =
-      Add<HLoadNamedField>(map, static_cast<HValue*>(NULL),
-                           HObjectAccess::ForMapInstanceType());
+        Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType());
 
-    HValue* bit_field2 = Add<HLoadNamedField>(map,
-                                              static_cast<HValue*>(NULL),
-                                              HObjectAccess::ForMapBitField2());
+    HValue* bit_field2 =
+        Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField2());
 
     IfBuilder kind_if(this);
     BuildFastElementLoad(&kind_if, receiver, key, instance_type, bit_field2,
@@ -1800,12 +1892,10 @@
       BuildNonGlobalObjectCheck(receiver);
 
       HValue* properties = Add<HLoadNamedField>(
-          receiver, static_cast<HValue*>(NULL),
-          HObjectAccess::ForPropertiesPointer());
+          receiver, nullptr, HObjectAccess::ForPropertiesPointer());
 
       HValue* hash =
-          Add<HLoadNamedField>(key, static_cast<HValue*>(NULL),
-          HObjectAccess::ForNameHashField());
+          Add<HLoadNamedField>(key, nullptr, HObjectAccess::ForNameHashField());
 
       hash = AddUncasted<HShr>(hash, Add<HConstant>(Name::kHashShift));
 
@@ -1824,8 +1914,8 @@
           ExternalReference::keyed_lookup_cache_keys(isolate());
       HValue* cache_keys = Add<HConstant>(cache_keys_ref);
 
-      HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
-                                         HObjectAccess::ForMap());
+      HValue* map =
+          Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap());
       HValue* base_index = AddUncasted<HMul>(hash, Add<HConstant>(2));
       base_index->ClearFlag(HValue::kCanOverflow);
 
@@ -1847,13 +1937,13 @@
               Add<HConstant>(probe_base + KeyedLookupCache::kKeyIndex));
           key_index->ClearFlag(HValue::kCanOverflow);
           HValue* map_to_check =
-              Add<HLoadKeyed>(cache_keys, map_index, static_cast<HValue*>(NULL),
-                              FAST_ELEMENTS, NEVER_RETURN_HOLE, 0);
+              Add<HLoadKeyed>(cache_keys, map_index, nullptr, FAST_ELEMENTS,
+                              NEVER_RETURN_HOLE, 0);
           lookup_if->If<HCompareObjectEqAndBranch>(map_to_check, map);
           lookup_if->And();
           HValue* key_to_check =
-              Add<HLoadKeyed>(cache_keys, key_index, static_cast<HValue*>(NULL),
-                              FAST_ELEMENTS, NEVER_RETURN_HOLE, 0);
+              Add<HLoadKeyed>(cache_keys, key_index, nullptr, FAST_ELEMENTS,
+                              NEVER_RETURN_HOLE, 0);
           lookup_if->If<HCompareObjectEqAndBranch>(key_to_check, key);
           lookup_if->Then();
           {
@@ -1863,9 +1953,9 @@
                 Add<HConstant>(cache_field_offsets_ref);
             HValue* index = AddUncasted<HAdd>(hash, Add<HConstant>(probe));
             index->ClearFlag(HValue::kCanOverflow);
-            HValue* property_index = Add<HLoadKeyed>(
-                cache_field_offsets, index, static_cast<HValue*>(NULL),
-                EXTERNAL_INT32_ELEMENTS, NEVER_RETURN_HOLE, 0);
+            HValue* property_index =
+                Add<HLoadKeyed>(cache_field_offsets, index, nullptr,
+                                EXTERNAL_INT32_ELEMENTS, NEVER_RETURN_HOLE, 0);
             Push(property_index);
           }
           lookup_if->Else();
@@ -1904,11 +1994,129 @@
 }
 
 
+void CodeStubGraphBuilderBase::TailCallHandler(HValue* receiver, HValue* name,
+                                               HValue* array, HValue* map_index,
+                                               HValue* slot, HValue* vector) {
+  // The handler is at array[map_index + 1]. Compute this with a custom offset
+  // to HLoadKeyed.
+  int offset =
+      GetDefaultHeaderSizeForElementsKind(FAST_ELEMENTS) + kPointerSize;
+  HValue* handler_code = Add<HLoadKeyed>(
+      array, map_index, nullptr, FAST_ELEMENTS, NEVER_RETURN_HOLE, offset);
+  TailCallHandler(receiver, name, slot, vector, handler_code);
+}
+
+
+void CodeStubGraphBuilderBase::TailCallHandler(HValue* receiver, HValue* name,
+                                               HValue* slot, HValue* vector,
+                                               HValue* handler_code) {
+  VectorLoadICDescriptor descriptor(isolate());
+  HValue* op_vals[] = {context(), receiver, name, slot, vector};
+  Add<HCallWithDescriptor>(handler_code, 0, descriptor,
+                           Vector<HValue*>(op_vals, 5), TAIL_CALL);
+  // We never return here, it is a tail call.
+}
+
+
+void CodeStubGraphBuilderBase::TailCallMiss(HValue* receiver, HValue* name,
+                                            HValue* slot, HValue* vector,
+                                            bool keyed_load) {
+  DCHECK(FLAG_vector_ics);
+  Add<HTailCallThroughMegamorphicCache>(
+      receiver, name, slot, vector,
+      HTailCallThroughMegamorphicCache::ComputeFlags(keyed_load, true));
+  // We never return here, it is a tail call.
+}
+
+
+void CodeStubGraphBuilderBase::HandleArrayCases(HValue* array, HValue* receiver,
+                                                HValue* name, HValue* slot,
+                                                HValue* vector,
+                                                bool keyed_load) {
+  IfBuilder if_receiver_heap_object(this);
+  if_receiver_heap_object.IfNot<HIsSmiAndBranch>(receiver);
+  if_receiver_heap_object.Then();
+  {
+    HConstant* constant_two = Add<HConstant>(2);
+    HConstant* constant_three = Add<HConstant>(3);
+
+    HValue* receiver_map = AddLoadMap(receiver, nullptr);
+    HValue* start =
+        keyed_load ? graph()->GetConstant1() : graph()->GetConstant0();
+    HValue* weak_cell = Add<HLoadKeyed>(array, start, nullptr, FAST_ELEMENTS,
+                                        ALLOW_RETURN_HOLE);
+    // Load the weak cell value. It may be Smi(0), or a map. Compare nonetheless
+    // against the receiver_map.
+    HValue* array_map = Add<HLoadNamedField>(weak_cell, nullptr,
+                                             HObjectAccess::ForWeakCellValue());
+
+    IfBuilder if_correct_map(this);
+    if_correct_map.If<HCompareObjectEqAndBranch>(receiver_map, array_map);
+    if_correct_map.Then();
+    { TailCallHandler(receiver, name, array, start, slot, vector); }
+    if_correct_map.Else();
+    {
+      // If our array has more elements, the ic is polymorphic. Look for the
+      // receiver map in the rest of the array.
+      HValue* length = AddLoadFixedArrayLength(array, nullptr);
+      LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement,
+                          constant_two);
+      start = keyed_load ? constant_three : constant_two;
+      HValue* key = builder.BeginBody(start, length, Token::LT);
+      {
+        HValue* weak_cell = Add<HLoadKeyed>(array, key, nullptr, FAST_ELEMENTS,
+                                            ALLOW_RETURN_HOLE);
+        HValue* array_map = Add<HLoadNamedField>(
+            weak_cell, nullptr, HObjectAccess::ForWeakCellValue());
+        IfBuilder if_correct_poly_map(this);
+        if_correct_poly_map.If<HCompareObjectEqAndBranch>(receiver_map,
+                                                          array_map);
+        if_correct_poly_map.Then();
+        { TailCallHandler(receiver, name, array, key, slot, vector); }
+      }
+      builder.EndBody();
+    }
+    if_correct_map.End();
+  }
+}
+
+
 template <>
 HValue* CodeStubGraphBuilder<VectorLoadStub>::BuildCodeStub() {
   HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
-  Add<HDeoptimize>("Always deopt", Deoptimizer::EAGER);
-  return receiver;
+  HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex);
+  HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex);
+  HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex);
+
+  // If the feedback is an array, then the IC is in the monomorphic or
+  // polymorphic state.
+  HValue* feedback =
+      Add<HLoadKeyed>(vector, slot, nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE);
+  IfBuilder array_checker(this);
+  array_checker.If<HCompareMap>(feedback,
+                                isolate()->factory()->fixed_array_map());
+  array_checker.Then();
+  { HandleArrayCases(feedback, receiver, name, slot, vector, false); }
+  array_checker.Else();
+  {
+    // Is the IC megamorphic?
+    IfBuilder mega_checker(this);
+    HConstant* megamorphic_symbol =
+        Add<HConstant>(isolate()->factory()->megamorphic_symbol());
+    mega_checker.If<HCompareObjectEqAndBranch>(feedback, megamorphic_symbol);
+    mega_checker.Then();
+    {
+      // Probe the stub cache.
+      Add<HTailCallThroughMegamorphicCache>(
+          receiver, name, slot, vector,
+          HTailCallThroughMegamorphicCache::ComputeFlags(false, false));
+    }
+    mega_checker.End();
+  }
+  array_checker.End();
+
+  TailCallMiss(receiver, name, slot, vector, false);
+  return graph()->GetConstant0();
 }
 
 
@@ -1918,8 +2126,65 @@
 template <>
 HValue* CodeStubGraphBuilder<VectorKeyedLoadStub>::BuildCodeStub() {
   HValue* receiver = GetParameter(VectorLoadICDescriptor::kReceiverIndex);
-  Add<HDeoptimize>("Always deopt", Deoptimizer::EAGER);
-  return receiver;
+  HValue* name = GetParameter(VectorLoadICDescriptor::kNameIndex);
+  HValue* slot = GetParameter(VectorLoadICDescriptor::kSlotIndex);
+  HValue* vector = GetParameter(VectorLoadICDescriptor::kVectorIndex);
+  HConstant* zero = graph()->GetConstant0();
+
+  // If the feedback is an array, then the IC is in the monomorphic or
+  // polymorphic state.
+  HValue* feedback =
+      Add<HLoadKeyed>(vector, slot, nullptr, FAST_ELEMENTS, ALLOW_RETURN_HOLE);
+  IfBuilder array_checker(this);
+  array_checker.If<HCompareMap>(feedback,
+                                isolate()->factory()->fixed_array_map());
+  array_checker.Then();
+  {
+    // If feedback[0] is 0, then the IC has element handlers and name should be
+    // a smi. If feedback[0] is a string, verify that it matches name.
+    HValue* recorded_name = Add<HLoadKeyed>(feedback, zero, nullptr,
+                                            FAST_ELEMENTS, ALLOW_RETURN_HOLE);
+
+    IfBuilder recorded_name_is_zero(this);
+    recorded_name_is_zero.If<HCompareObjectEqAndBranch>(recorded_name, zero);
+    recorded_name_is_zero.Then();
+    { Add<HCheckSmi>(name); }
+    recorded_name_is_zero.Else();
+    {
+      IfBuilder strings_match(this);
+      strings_match.IfNot<HCompareObjectEqAndBranch>(name, recorded_name);
+      strings_match.Then();
+      TailCallMiss(receiver, name, slot, vector, true);
+      strings_match.End();
+    }
+    recorded_name_is_zero.End();
+
+    HandleArrayCases(feedback, receiver, name, slot, vector, true);
+  }
+  array_checker.Else();
+  {
+    // Check if the IC is in generic state.
+    IfBuilder generic_checker(this);
+    HConstant* generic_symbol =
+        Add<HConstant>(isolate()->factory()->generic_symbol());
+    generic_checker.If<HCompareObjectEqAndBranch>(feedback, generic_symbol);
+    generic_checker.Then();
+    {
+      // Tail-call to the generic KeyedLoadIC, treating it like a handler.
+      Handle<Code> stub = KeyedLoadIC::generic_stub(isolate());
+      HValue* constant_stub = Add<HConstant>(stub);
+      LoadDescriptor descriptor(isolate());
+      HValue* op_vals[] = {context(), receiver, name};
+      Add<HCallWithDescriptor>(constant_stub, 0, descriptor,
+                               Vector<HValue*>(op_vals, 3), TAIL_CALL);
+      // We never return here, it is a tail call.
+    }
+    generic_checker.End();
+  }
+  array_checker.End();
+
+  TailCallMiss(receiver, name, slot, vector, true);
+  return zero;
 }
 
 
@@ -1935,14 +2200,15 @@
 
 template <>
 HValue* CodeStubGraphBuilder<MegamorphicLoadStub>::BuildCodeStub() {
-  // The return address is on the stack.
   HValue* receiver = GetParameter(LoadDescriptor::kReceiverIndex);
   HValue* name = GetParameter(LoadDescriptor::kNameIndex);
 
+  // We shouldn't generate this when FLAG_vector_ics is true because the
+  // megamorphic case is handled as part of the default stub.
+  DCHECK(!FLAG_vector_ics);
+
   // Probe the stub cache.
-  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
-      Code::ComputeHandlerFlags(Code::LOAD_IC));
-  Add<HTailCallThroughMegamorphicCache>(receiver, name, flags);
+  Add<HTailCallThroughMegamorphicCache>(receiver, name);
 
   // We never continue.
   return graph()->GetConstant0();
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 5c9e1a2..895569d 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -2,10 +2,11 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
+#include "src/code-stubs.h"
+
+#include <sstream>
 
 #include "src/bootstrapper.h"
-#include "src/code-stubs.h"
 #include "src/cpu-profiler.h"
 #include "src/factory.h"
 #include "src/gdb-jit.h"
@@ -74,10 +75,10 @@
 
 
 void CodeStub::RecordCodeGeneration(Handle<Code> code) {
-  IC::RegisterWeakMapDependency(code);
-  OStringStream os;
+  std::ostringstream os;
   os << *this;
-  PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, os.c_str()));
+  PROFILE(isolate(),
+          CodeCreateEvent(Logger::STUB_TAG, *code, os.str().c_str()));
   Counters* counters = isolate()->counters();
   counters->total_stubs_code_size()->Increment(code->instruction_size());
 }
@@ -103,15 +104,14 @@
   // Generate the new code.
   MacroAssembler masm(isolate(), NULL, 256);
 
-  // TODO(yangguo) remove this once the code serializer handles code stubs.
-  if (FLAG_serialize_toplevel) masm.enable_serializer();
-
   {
     // Update the static counter each time a new code stub is generated.
     isolate()->counters()->code_stubs()->Increment();
 
     // Generate the code for the stub.
     masm.set_generating_stub(true);
+    // TODO(yangguo): remove this once we can serialize IC stubs.
+    masm.enable_serializer();
     NoCurrentFrameScope scope(&masm);
     Generate(&masm);
   }
@@ -153,9 +153,9 @@
     if (FLAG_print_code_stubs) {
       CodeTracer::Scope trace_scope(isolate()->GetCodeTracer());
       OFStream os(trace_scope.file());
-      OStringStream name;
+      std::ostringstream name;
       name << *this;
-      new_object->Disassemble(name.c_str(), os);
+      new_object->Disassemble(name.str().c_str(), os);
       os << "\n";
     }
 #endif
@@ -198,12 +198,12 @@
 }
 
 
-void CodeStub::PrintBaseName(OStream& os) const {  // NOLINT
+void CodeStub::PrintBaseName(std::ostream& os) const {  // NOLINT
   os << MajorName(MajorKey(), false);
 }
 
 
-void CodeStub::PrintName(OStream& os) const {  // NOLINT
+void CodeStub::PrintName(std::ostream& os) const {  // NOLINT
   PrintBaseName(os);
   PrintState(os);
 }
@@ -222,9 +222,8 @@
     CODE_STUB_LIST(DEF_CASE)
 #undef DEF_CASE
     case NUMBER_OF_IDS:
-      UNREACHABLE();
     case NoCache:
-      *value_out = NULL;
+      UNREACHABLE();
       break;
   }
 }
@@ -279,7 +278,7 @@
 }
 
 
-void BinaryOpICStub::PrintState(OStream& os) const {  // NOLINT
+void BinaryOpICStub::PrintState(std::ostream& os) const {  // NOLINT
   os << state();
 }
 
@@ -300,7 +299,7 @@
 
 
 void BinaryOpICWithAllocationSiteStub::PrintState(
-    OStream& os) const {  // NOLINT
+    std::ostream& os) const {  // NOLINT
   os << state();
 }
 
@@ -315,7 +314,7 @@
 }
 
 
-void StringAddStub::PrintBaseName(OStream& os) const {  // NOLINT
+void StringAddStub::PrintBaseName(std::ostream& os) const {  // NOLINT
   os << "StringAddStub";
   if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) {
     os << "_CheckBoth";
@@ -463,17 +462,17 @@
   OFStream os(stdout);
   os << "[";
   PrintBaseName(os);
-  os << ": " << from << "=>" << to << "]" << endl;
+  os << ": " << from << "=>" << to << "]" << std::endl;
 }
 
 
-void CompareNilICStub::PrintBaseName(OStream& os) const {  // NOLINT
+void CompareNilICStub::PrintBaseName(std::ostream& os) const {  // NOLINT
   CodeStub::PrintBaseName(os);
   os << ((nil_value() == kNullValue) ? "(NullValue)" : "(UndefinedValue)");
 }
 
 
-void CompareNilICStub::PrintState(OStream& os) const {  // NOLINT
+void CompareNilICStub::PrintState(std::ostream& os) const {  // NOLINT
   os << state();
 }
 
@@ -481,7 +480,7 @@
 // TODO(svenpanne) Make this a real infix_ostream_iterator.
 class SimpleListPrinter {
  public:
-  explicit SimpleListPrinter(OStream& os) : os_(os), first_(true) {}
+  explicit SimpleListPrinter(std::ostream& os) : os_(os), first_(true) {}
 
   void Add(const char* s) {
     if (first_) {
@@ -493,12 +492,12 @@
   }
 
  private:
-  OStream& os_;
+  std::ostream& os_;
   bool first_;
 };
 
 
-OStream& operator<<(OStream& os, const CompareNilICStub::State& s) {
+std::ostream& operator<<(std::ostream& os, const CompareNilICStub::State& s) {
   os << "(";
   SimpleListPrinter p(os);
   if (s.IsEmpty()) p.Add("None");
@@ -539,17 +538,17 @@
 }
 
 
-void CallIC_ArrayStub::PrintState(OStream& os) const {  // NOLINT
+void CallIC_ArrayStub::PrintState(std::ostream& os) const {  // NOLINT
   os << state() << " (Array)";
 }
 
 
-void CallICStub::PrintState(OStream& os) const {  // NOLINT
+void CallICStub::PrintState(std::ostream& os) const {  // NOLINT
   os << state();
 }
 
 
-void InstanceofStub::PrintName(OStream& os) const {  // NOLINT
+void InstanceofStub::PrintName(std::ostream& os) const {  // NOLINT
   os << "InstanceofStub";
   if (HasArgsInRegisters()) os << "_REGS";
   if (HasCallSiteInlineCheck()) os << "_INLINE";
@@ -594,6 +593,9 @@
 
 CallInterfaceDescriptor HandlerStub::GetCallInterfaceDescriptor() {
   if (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC) {
+    if (FLAG_vector_ics) {
+      return VectorLoadICDescriptor(isolate());
+    }
     return LoadDescriptor(isolate());
   } else {
     DCHECK_EQ(Code::STORE_IC, kind());
@@ -614,6 +616,11 @@
 }
 
 
+CallInterfaceDescriptor StoreTransitionStub::GetCallInterfaceDescriptor() {
+  return StoreTransitionDescriptor(isolate());
+}
+
+
 static void InitializeVectorLoadStub(Isolate* isolate,
                                      CodeStubDescriptor* descriptor,
                                      Address deoptimization_handler) {
@@ -624,14 +631,13 @@
 
 void VectorLoadStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
   InitializeVectorLoadStub(isolate(), descriptor,
-                           FUNCTION_ADDR(VectorLoadIC_MissFromStubFailure));
+                           FUNCTION_ADDR(LoadIC_MissFromStubFailure));
 }
 
 
 void VectorKeyedLoadStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
-  InitializeVectorLoadStub(
-      isolate(), descriptor,
-      FUNCTION_ADDR(VectorKeyedLoadIC_MissFromStubFailure));
+  InitializeVectorLoadStub(isolate(), descriptor,
+                           FUNCTION_ADDR(KeyedLoadIC_MissFromStubFailure));
 }
 
 
@@ -647,9 +653,6 @@
 void FastNewContextStub::InitializeDescriptor(CodeStubDescriptor* d) {}
 
 
-void ToNumberStub::InitializeDescriptor(CodeStubDescriptor* d) {}
-
-
 void NumberToStringStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
   NumberToStringDescriptor call_descriptor(isolate());
   descriptor->Initialize(
@@ -690,6 +693,13 @@
 }
 
 
+void AllocateHeapNumberStub::InitializeDescriptor(
+    CodeStubDescriptor* descriptor) {
+  descriptor->Initialize(
+      Runtime::FunctionForId(Runtime::kAllocateHeapNumber)->entry);
+}
+
+
 void CompareNilICStub::InitializeDescriptor(CodeStubDescriptor* descriptor) {
   descriptor->Initialize(FUNCTION_ADDR(CompareNilIC_Miss));
   descriptor->SetMissHandler(
@@ -772,7 +782,7 @@
 }
 
 
-void ArgumentsAccessStub::PrintName(OStream& os) const {  // NOLINT
+void ArgumentsAccessStub::PrintName(std::ostream& os) const {  // NOLINT
   os << "ArgumentsAccessStub_";
   switch (type()) {
     case READ_ELEMENT:
@@ -792,18 +802,18 @@
 }
 
 
-void CallFunctionStub::PrintName(OStream& os) const {  // NOLINT
+void CallFunctionStub::PrintName(std::ostream& os) const {  // NOLINT
   os << "CallFunctionStub_Args" << argc();
 }
 
 
-void CallConstructStub::PrintName(OStream& os) const {  // NOLINT
+void CallConstructStub::PrintName(std::ostream& os) const {  // NOLINT
   os << "CallConstructStub";
   if (RecordCallTarget()) os << "_Recording";
 }
 
 
-void ArrayConstructorStub::PrintName(OStream& os) const {  // NOLINT
+void ArrayConstructorStub::PrintName(std::ostream& os) const {  // NOLINT
   os << "ArrayConstructorStub";
   switch (argument_count()) {
     case ANY:
@@ -823,8 +833,9 @@
 }
 
 
-OStream& ArrayConstructorStubBase::BasePrintName(OStream& os,  // NOLINT
-                                                 const char* name) const {
+std::ostream& ArrayConstructorStubBase::BasePrintName(
+    std::ostream& os,  // NOLINT
+    const char* name) const {
   os << name << "_" << ElementsKindToString(elements_kind());
   if (override_mode() == DISABLE_ALLOCATION_SITES) {
     os << "_DISABLE_ALLOCATION_SITES";
@@ -843,12 +854,12 @@
 }
 
 
-void ToBooleanStub::PrintState(OStream& os) const {  // NOLINT
+void ToBooleanStub::PrintState(std::ostream& os) const {  // NOLINT
   os << types();
 }
 
 
-OStream& operator<<(OStream& os, const ToBooleanStub::Types& s) {
+std::ostream& operator<<(std::ostream& os, const ToBooleanStub::Types& s) {
   os << "(";
   SimpleListPrinter p(os);
   if (s.IsEmpty()) p.Add("None");
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 3b31399..8448e55 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -39,6 +39,7 @@
   V(KeyedLoadICTrampoline)                  \
   V(LoadICTrampoline)                       \
   V(LoadIndexedInterceptor)                 \
+  V(LoadIndexedString)                      \
   V(MathPow)                                \
   V(ProfileEntryHook)                       \
   V(RecordWrite)                            \
@@ -49,7 +50,9 @@
   V(StringCompare)                          \
   V(StubFailureTrampoline)                  \
   V(SubString)                              \
+  V(ToNumber)                               \
   /* HydrogenCodeStubs */                   \
+  V(AllocateHeapNumber)                     \
   V(ArrayNArgumentsConstructor)             \
   V(ArrayNoArgumentConstructor)             \
   V(ArraySingleArgumentConstructor)         \
@@ -66,6 +69,7 @@
   V(InternalArrayNoArgumentConstructor)     \
   V(InternalArraySingleArgumentConstructor) \
   V(KeyedLoadGeneric)                       \
+  V(LoadScriptContextField)                 \
   V(LoadDictionaryElement)                  \
   V(LoadFastElement)                        \
   V(MegamorphicLoad)                        \
@@ -73,9 +77,9 @@
   V(NumberToString)                         \
   V(RegExpConstructResult)                  \
   V(StoreFastElement)                       \
+  V(StoreScriptContextField)                \
   V(StringAdd)                              \
   V(ToBoolean)                              \
-  V(ToNumber)                               \
   V(TransitionElementsKind)                 \
   V(VectorKeyedLoad)                        \
   V(VectorLoad)                             \
@@ -85,13 +89,12 @@
   V(KeyedLoadSloppyArguments)               \
   V(StoreField)                             \
   V(StoreGlobal)                            \
+  V(StoreTransition)                        \
   V(StringLength)
 
 // List of code stubs only used on ARM 32 bits platforms.
 #if V8_TARGET_ARCH_ARM
-#define CODE_STUB_LIST_ARM(V) \
-  V(DirectCEntry)             \
-  V(WriteInt32ToHeapNumber)
+#define CODE_STUB_LIST_ARM(V) V(DirectCEntry)
 
 #else
 #define CODE_STUB_LIST_ARM(V)
@@ -110,17 +113,15 @@
 
 // List of code stubs only used on MIPS platforms.
 #if V8_TARGET_ARCH_MIPS
-#define CODE_STUB_LIST_MIPS(V)  \
-  V(DirectCEntry)               \
-  V(RestoreRegistersState)      \
-  V(StoreRegistersState)        \
-  V(WriteInt32ToHeapNumber)
+#define CODE_STUB_LIST_MIPS(V) \
+  V(DirectCEntry)              \
+  V(RestoreRegistersState)     \
+  V(StoreRegistersState)
 #elif V8_TARGET_ARCH_MIPS64
-#define CODE_STUB_LIST_MIPS(V)  \
-  V(DirectCEntry)               \
-  V(RestoreRegistersState)      \
-  V(StoreRegistersState)        \
-  V(WriteInt32ToHeapNumber)
+#define CODE_STUB_LIST_MIPS(V) \
+  V(DirectCEntry)              \
+  V(RestoreRegistersState)     \
+  V(StoreRegistersState)
 #else
 #define CODE_STUB_LIST_MIPS(V)
 #endif
@@ -136,10 +137,12 @@
 class CodeStub BASE_EMBEDDED {
  public:
   enum Major {
+    // TODO(mvstanton): eliminate the NoCache key by getting rid
+    //                  of the non-monomorphic-cache.
+    NoCache = 0,  // marker for stubs that do custom caching]
 #define DEF_ENUM(name) name,
     CODE_STUB_LIST(DEF_ENUM)
 #undef DEF_ENUM
-    NoCache,  // marker for stubs that do custom caching
     NUMBER_OF_IDS
   };
 
@@ -201,7 +204,7 @@
     return Code::NORMAL;
   }
 
-  friend OStream& operator<<(OStream& os, const CodeStub& s) {
+  friend std::ostream& operator<<(std::ostream& os, const CodeStub& s) {
     s.PrintName(os);
     return os;
   }
@@ -219,9 +222,9 @@
   // a fixed (non-moveable) code object.
   virtual bool NeedsImmovableCode() { return false; }
 
-  virtual void PrintName(OStream& os) const;        // NOLINT
-  virtual void PrintBaseName(OStream& os) const;    // NOLINT
-  virtual void PrintState(OStream& os) const { ; }  // NOLINT
+  virtual void PrintName(std::ostream& os) const;        // NOLINT
+  virtual void PrintBaseName(std::ostream& os) const;    // NOLINT
+  virtual void PrintState(std::ostream& os) const { ; }  // NOLINT
 
   // Computes the key based on major and minor.
   uint32_t GetKey() {
@@ -286,54 +289,52 @@
   DISALLOW_COPY_AND_ASSIGN(NAME)
 
 
-#define DEFINE_CODE_STUB(NAME, SUPER)              \
- protected:                                        \
-  virtual inline Major MajorKey() const OVERRIDE { \
-    return NAME;                                   \
-  };                                               \
+#define DEFINE_CODE_STUB(NAME, SUPER)                      \
+ protected:                                                \
+  inline Major MajorKey() const OVERRIDE { return NAME; }; \
   DEFINE_CODE_STUB_BASE(NAME##Stub, SUPER)
 
 
-#define DEFINE_PLATFORM_CODE_STUB(NAME, SUPER)          \
- private:                                               \
-  virtual void Generate(MacroAssembler* masm) OVERRIDE; \
+#define DEFINE_PLATFORM_CODE_STUB(NAME, SUPER)  \
+ private:                                       \
+  void Generate(MacroAssembler* masm) OVERRIDE; \
   DEFINE_CODE_STUB(NAME, SUPER)
 
 
-#define DEFINE_HYDROGEN_CODE_STUB(NAME, SUPER)                                \
- public:                                                                      \
-  virtual void InitializeDescriptor(CodeStubDescriptor* descriptor) OVERRIDE; \
-  virtual Handle<Code> GenerateCode() OVERRIDE;                               \
+#define DEFINE_HYDROGEN_CODE_STUB(NAME, SUPER)                        \
+ public:                                                              \
+  void InitializeDescriptor(CodeStubDescriptor* descriptor) OVERRIDE; \
+  Handle<Code> GenerateCode() OVERRIDE;                               \
   DEFINE_CODE_STUB(NAME, SUPER)
 
-#define DEFINE_HANDLER_CODE_STUB(NAME, SUPER)   \
- public:                                        \
-  virtual Handle<Code> GenerateCode() OVERRIDE; \
+#define DEFINE_HANDLER_CODE_STUB(NAME, SUPER) \
+ public:                                      \
+  Handle<Code> GenerateCode() OVERRIDE;       \
   DEFINE_CODE_STUB(NAME, SUPER)
 
-#define DEFINE_CALL_INTERFACE_DESCRIPTOR(NAME)                            \
- public:                                                                  \
-  virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { \
-    return NAME##Descriptor(isolate());                                   \
+#define DEFINE_CALL_INTERFACE_DESCRIPTOR(NAME)                    \
+ public:                                                          \
+  CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { \
+    return NAME##Descriptor(isolate());                           \
   }
 
 // There are some code stubs we just can't describe right now with a
 // CallInterfaceDescriptor. Isolate behavior for those cases with this macro.
 // An attempt to retrieve a descriptor will fail.
-#define DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR()                           \
- public:                                                                  \
-  virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { \
-    UNREACHABLE();                                                        \
-    return CallInterfaceDescriptor();                                     \
+#define DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR()                   \
+ public:                                                          \
+  CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { \
+    UNREACHABLE();                                                \
+    return CallInterfaceDescriptor();                             \
   }
 
 
 class PlatformCodeStub : public CodeStub {
  public:
   // Retrieve the code for the stub. Generate the code if needed.
-  virtual Handle<Code> GenerateCode() OVERRIDE;
+  Handle<Code> GenerateCode() OVERRIDE;
 
-  virtual Code::Kind GetCodeKind() const { return Code::STUB; }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::STUB; }
 
  protected:
   explicit PlatformCodeStub(Isolate* isolate) : CodeStub(isolate) {}
@@ -433,7 +434,7 @@
     INITIALIZED
   };
 
-  virtual Code::Kind GetCodeKind() const { return Code::STUB; }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::STUB; }
 
   template<class SubClass>
   static Handle<Code> GetUninitialized(Isolate* isolate) {
@@ -442,7 +443,7 @@
   }
 
   // Retrieve the code for the stub. Generate the code if needed.
-  virtual Handle<Code> GenerateCode() = 0;
+  Handle<Code> GenerateCode() OVERRIDE = 0;
 
   bool IsUninitialized() const { return IsMissBits::decode(minor_key_); }
 
@@ -540,15 +541,6 @@
 };
 
 
-class ToNumberStub: public HydrogenCodeStub {
- public:
-  explicit ToNumberStub(Isolate* isolate) : HydrogenCodeStub(isolate) { }
-
-  DEFINE_CALL_INTERFACE_DESCRIPTOR(ToNumber);
-  DEFINE_HYDROGEN_CODE_STUB(ToNumber, HydrogenCodeStub);
-};
-
-
 class NumberToStringStub FINAL : public HydrogenCodeStub {
  public:
   explicit NumberToStringStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
@@ -581,10 +573,11 @@
   bool is_arrow() const { return IsArrowFunction(kind()); }
   bool is_generator() const { return IsGeneratorFunction(kind()); }
   bool is_concise_method() const { return IsConciseMethod(kind()); }
+  bool is_default_constructor() const { return IsDefaultConstructor(kind()); }
 
  private:
   class StrictModeBits : public BitField<StrictMode, 0, 1> {};
-  class FunctionKindBits : public BitField<FunctionKind, 1, 3> {};
+  class FunctionKindBits : public BitField<FunctionKind, 1, 4> {};
 
   DEFINE_CALL_INTERFACE_DESCRIPTOR(FastNewClosure);
   DEFINE_HYDROGEN_CODE_STUB(FastNewClosure, HydrogenCodeStub);
@@ -683,7 +676,7 @@
   static Register left() { return InstanceofDescriptor::left(); }
   static Register right() { return InstanceofDescriptor::right(); }
 
-  virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
+  CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
     if (HasArgsInRegisters()) {
       return InstanceofDescriptor(isolate());
     }
@@ -703,7 +696,7 @@
     return (flags() & kReturnTrueFalseObject) != 0;
   }
 
-  virtual void PrintName(OStream& os) const OVERRIDE;  // NOLINT
+  void PrintName(std::ostream& os) const OVERRIDE;  // NOLINT
 
   class FlagBits : public BitField<Flags, 0, 3> {};
 
@@ -734,7 +727,7 @@
   void GenerateDispatchToArrayStub(MacroAssembler* masm,
                                    AllocationSiteOverrideMode mode);
 
-  virtual void PrintName(OStream& os) const OVERRIDE;  // NOLINT
+  void PrintName(std::ostream& os) const OVERRIDE;  // NOLINT
 
   class ArgumentCountBits : public BitField<ArgumentCountKey, 0, 2> {};
 
@@ -764,7 +757,7 @@
     minor_key_ = ExponentTypeBits::encode(exponent_type);
   }
 
-  virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
+  CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
     if (exponent_type() == TAGGED) {
       return MathPowTaggedDescriptor(isolate());
     } else if (exponent_type() == INTEGER) {
@@ -797,11 +790,11 @@
     return state.arg_count();
   }
 
-  virtual Code::Kind GetCodeKind() const OVERRIDE { return Code::CALL_IC; }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::CALL_IC; }
 
-  virtual InlineCacheState GetICState() const OVERRIDE { return DEFAULT; }
+  InlineCacheState GetICState() const OVERRIDE { return DEFAULT; }
 
-  virtual ExtraICState GetExtraICState() const FINAL OVERRIDE {
+  ExtraICState GetExtraICState() const FINAL {
     return static_cast<ExtraICState>(minor_key_);
   }
 
@@ -820,7 +813,7 @@
   void GenerateMiss(MacroAssembler* masm);
 
  private:
-  virtual void PrintState(OStream& os) const OVERRIDE;  // NOLINT
+  void PrintState(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedback);
   DEFINE_PLATFORM_CODE_STUB(CallIC, PlatformCodeStub);
@@ -832,12 +825,10 @@
   CallIC_ArrayStub(Isolate* isolate, const CallICState& state_in)
       : CallICStub(isolate, state_in) {}
 
-  virtual InlineCacheState GetICState() const FINAL OVERRIDE {
-    return MONOMORPHIC;
-  }
+  InlineCacheState GetICState() const FINAL { return MONOMORPHIC; }
 
  private:
-  virtual void PrintState(OStream& os) const OVERRIDE;  // NOLINT
+  void PrintState(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DEFINE_PLATFORM_CODE_STUB(CallIC_Array, CallICStub);
 };
@@ -849,12 +840,18 @@
   explicit FunctionPrototypeStub(Isolate* isolate)
       : PlatformCodeStub(isolate) {}
 
-  virtual Code::Kind GetCodeKind() const { return Code::HANDLER; }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::HANDLER; }
 
   // TODO(mvstanton): only the receiver register is accessed. When this is
   // translated to a hydrogen code stub, a new CallInterfaceDescriptor
   // should be created that just uses that register for more efficient code.
-  DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
+  CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
+    if (FLAG_vector_ics) {
+      return VectorLoadICDescriptor(isolate());
+    }
+    return LoadDescriptor(isolate());
+  }
+
   DEFINE_PLATFORM_CODE_STUB(FunctionPrototype, PlatformCodeStub);
 };
 
@@ -865,23 +862,36 @@
   explicit LoadIndexedInterceptorStub(Isolate* isolate)
       : PlatformCodeStub(isolate) {}
 
-  virtual Code::Kind GetCodeKind() const { return Code::HANDLER; }
-  virtual Code::StubType GetStubType() { return Code::FAST; }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::HANDLER; }
+  Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
 
   DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
   DEFINE_PLATFORM_CODE_STUB(LoadIndexedInterceptor, PlatformCodeStub);
 };
 
 
+class LoadIndexedStringStub : public PlatformCodeStub {
+ public:
+  explicit LoadIndexedStringStub(Isolate* isolate)
+      : PlatformCodeStub(isolate) {}
+
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::HANDLER; }
+  Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
+
+  DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
+  DEFINE_PLATFORM_CODE_STUB(LoadIndexedString, PlatformCodeStub);
+};
+
+
 class HandlerStub : public HydrogenCodeStub {
  public:
-  virtual Code::Kind GetCodeKind() const { return Code::HANDLER; }
-  virtual ExtraICState GetExtraICState() const { return kind(); }
-  virtual InlineCacheState GetICState() const { return MONOMORPHIC; }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::HANDLER; }
+  ExtraICState GetExtraICState() const OVERRIDE { return kind(); }
+  InlineCacheState GetICState() const OVERRIDE { return MONOMORPHIC; }
 
-  virtual void InitializeDescriptor(CodeStubDescriptor* descriptor) OVERRIDE;
+  void InitializeDescriptor(CodeStubDescriptor* descriptor) OVERRIDE;
 
-  virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE;
+  CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE;
 
  protected:
   explicit HandlerStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
@@ -905,8 +915,8 @@
   }
 
  protected:
-  virtual Code::Kind kind() const { return Code::LOAD_IC; }
-  virtual Code::StubType GetStubType() { return Code::FAST; }
+  Code::Kind kind() const OVERRIDE { return Code::LOAD_IC; }
+  Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
 
  private:
   class LoadFieldByIndexBits : public BitField<int, 0, 13> {};
@@ -921,8 +931,8 @@
       : HandlerStub(isolate) {}
 
  protected:
-  virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }
-  virtual Code::StubType GetStubType() { return Code::FAST; }
+  Code::Kind kind() const OVERRIDE { return Code::KEYED_LOAD_IC; }
+  Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
 
  private:
   DEFINE_HANDLER_CODE_STUB(KeyedLoadSloppyArguments, HandlerStub);
@@ -941,8 +951,8 @@
   }
 
  protected:
-  virtual Code::Kind kind() const { return Code::LOAD_IC; }
-  virtual Code::StubType GetStubType() { return Code::FAST; }
+  Code::Kind kind() const OVERRIDE { return Code::LOAD_IC; }
+  Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
 
  private:
   class ConstantIndexBits : public BitField<int, 0, kSubMinorKeyBits> {};
@@ -956,8 +966,8 @@
   explicit StringLengthStub(Isolate* isolate) : HandlerStub(isolate) {}
 
  protected:
-  virtual Code::Kind kind() const { return Code::LOAD_IC; }
-  virtual Code::StubType GetStubType() { return Code::FAST; }
+  Code::Kind kind() const OVERRIDE { return Code::LOAD_IC; }
+  Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
 
   DEFINE_HANDLER_CODE_STUB(StringLength, HandlerStub);
 };
@@ -985,8 +995,8 @@
   }
 
  protected:
-  virtual Code::Kind kind() const { return Code::STORE_IC; }
-  virtual Code::StubType GetStubType() { return Code::FAST; }
+  Code::Kind kind() const OVERRIDE { return Code::STORE_IC; }
+  Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
 
  private:
   class StoreFieldByIndexBits : public BitField<int, 0, 13> {};
@@ -996,6 +1006,60 @@
 };
 
 
+class StoreTransitionStub : public HandlerStub {
+ public:
+  enum StoreMode {
+    StoreMapOnly,
+    StoreMapAndValue,
+    ExtendStorageAndStoreMapAndValue
+  };
+
+  explicit StoreTransitionStub(Isolate* isolate) : HandlerStub(isolate) {
+    set_sub_minor_key(StoreModeBits::encode(StoreMapOnly));
+  }
+
+  StoreTransitionStub(Isolate* isolate, FieldIndex index,
+                      Representation representation, StoreMode store_mode)
+      : HandlerStub(isolate) {
+    DCHECK(store_mode != StoreMapOnly);
+    int property_index_key = index.GetFieldAccessStubKey();
+    uint8_t repr = PropertyDetails::EncodeRepresentation(representation);
+    set_sub_minor_key(StoreFieldByIndexBits::encode(property_index_key) |
+                      RepresentationBits::encode(repr) |
+                      StoreModeBits::encode(store_mode));
+  }
+
+  FieldIndex index() const {
+    DCHECK(store_mode() != StoreMapOnly);
+    int property_index_key = StoreFieldByIndexBits::decode(sub_minor_key());
+    return FieldIndex::FromFieldAccessStubKey(property_index_key);
+  }
+
+  Representation representation() {
+    DCHECK(store_mode() != StoreMapOnly);
+    uint8_t repr = RepresentationBits::decode(sub_minor_key());
+    return PropertyDetails::DecodeRepresentation(repr);
+  }
+
+  StoreMode store_mode() const {
+    return StoreModeBits::decode(sub_minor_key());
+  }
+
+  CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE;
+
+ protected:
+  Code::Kind kind() const OVERRIDE { return Code::STORE_IC; }
+  Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
+
+ private:
+  class StoreFieldByIndexBits : public BitField<int, 0, 13> {};
+  class RepresentationBits : public BitField<uint8_t, 13, 4> {};
+  class StoreModeBits : public BitField<StoreMode, 17, 2> {};
+
+  DEFINE_HANDLER_CODE_STUB(StoreTransition, HandlerStub);
+};
+
+
 class StoreGlobalStub : public HandlerStub {
  public:
   StoreGlobalStub(Isolate* isolate, bool is_constant, bool check_global)
@@ -1023,7 +1087,7 @@
     }
   }
 
-  virtual Code::Kind kind() const { return Code::STORE_IC; }
+  Code::Kind kind() const OVERRIDE { return Code::STORE_IC; }
 
   bool is_constant() const { return IsConstantBits::decode(sub_minor_key()); }
 
@@ -1105,15 +1169,11 @@
 
   static void GenerateAheadOfTime(Isolate* isolate);
 
-  virtual Code::Kind GetCodeKind() const OVERRIDE {
-    return Code::BINARY_OP_IC;
-  }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::BINARY_OP_IC; }
 
-  virtual InlineCacheState GetICState() const FINAL OVERRIDE {
-    return state().GetICState();
-  }
+  InlineCacheState GetICState() const FINAL { return state().GetICState(); }
 
-  virtual ExtraICState GetExtraICState() const FINAL OVERRIDE {
+  ExtraICState GetExtraICState() const FINAL {
     return static_cast<ExtraICState>(sub_minor_key());
   }
 
@@ -1121,7 +1181,7 @@
     return BinaryOpICState(isolate(), GetExtraICState());
   }
 
-  virtual void PrintState(OStream& os) const FINAL OVERRIDE;  // NOLINT
+  void PrintState(std::ostream& os) const FINAL;  // NOLINT
 
   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
   static const int kLeft = 0;
@@ -1154,19 +1214,15 @@
     return CodeStub::GetCodeCopy(pattern);
   }
 
-  virtual Code::Kind GetCodeKind() const OVERRIDE {
-    return Code::BINARY_OP_IC;
-  }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::BINARY_OP_IC; }
 
-  virtual InlineCacheState GetICState() const OVERRIDE {
-    return state().GetICState();
-  }
+  InlineCacheState GetICState() const OVERRIDE { return state().GetICState(); }
 
-  virtual ExtraICState GetExtraICState() const OVERRIDE {
+  ExtraICState GetExtraICState() const OVERRIDE {
     return static_cast<ExtraICState>(minor_key_);
   }
 
-  virtual void PrintState(OStream& os) const OVERRIDE;  // NOLINT
+  void PrintState(std::ostream& os) const OVERRIDE;  // NOLINT
 
  private:
   BinaryOpICState state() const {
@@ -1191,9 +1247,7 @@
   BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
       : BinaryOpICStub(isolate, state) {}
 
-  virtual Code::Kind GetCodeKind() const FINAL OVERRIDE {
-    return Code::STUB;
-  }
+  Code::Kind GetCodeKind() const FINAL { return Code::STUB; }
 
   // Parameters accessed via CodeStubGraphBuilder::GetParameter()
   static const int kAllocationSite = 0;
@@ -1242,7 +1296,7 @@
   class StringAddFlagsBits: public BitField<StringAddFlags, 0, 2> {};
   class PretenureFlagBits: public BitField<PretenureFlag, 2, 1> {};
 
-  virtual void PrintBaseName(OStream& os) const OVERRIDE;  // NOLINT
+  void PrintBaseName(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DEFINE_CALL_INTERFACE_DESCRIPTOR(StringAdd);
   DEFINE_HYDROGEN_CODE_STUB(StringAdd, HydrogenCodeStub);
@@ -1261,7 +1315,7 @@
 
   void set_known_map(Handle<Map> map) { known_map_ = map; }
 
-  virtual InlineCacheState GetICState() const;
+  InlineCacheState GetICState() const OVERRIDE;
 
   Token::Value op() const {
     return static_cast<Token::Value>(Token::EQ + OpBits::decode(minor_key_));
@@ -1276,7 +1330,7 @@
   CompareICState::State state() const { return StateBits::decode(minor_key_); }
 
  private:
-  virtual Code::Kind GetCodeKind() const { return Code::COMPARE_IC; }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::COMPARE_IC; }
 
   void GenerateSmis(MacroAssembler* masm);
   void GenerateNumbers(MacroAssembler* masm);
@@ -1291,9 +1345,9 @@
   bool strict() const { return op() == Token::EQ_STRICT; }
   Condition GetCondition() const;
 
-  virtual void AddToSpecialCache(Handle<Code> new_object);
-  virtual bool FindCodeInSpecialCache(Code** code_out);
-  virtual bool UseSpecialCache() {
+  void AddToSpecialCache(Handle<Code> new_object) OVERRIDE;
+  bool FindCodeInSpecialCache(Code** code_out) OVERRIDE;
+  bool UseSpecialCache() OVERRIDE {
     return state() == CompareICState::KNOWN_OBJECT;
   }
 
@@ -1329,7 +1383,7 @@
     return CompareNilICStub(isolate, nil, UNINITIALIZED).GetCode();
   }
 
-  virtual InlineCacheState GetICState() const {
+  InlineCacheState GetICState() const OVERRIDE {
     State state = this->state();
     if (state.Contains(GENERIC)) {
       return MEGAMORPHIC;
@@ -1340,9 +1394,9 @@
     }
   }
 
-  virtual Code::Kind GetCodeKind() const { return Code::COMPARE_NIL_IC; }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::COMPARE_NIL_IC; }
 
-  virtual ExtraICState GetExtraICState() const { return sub_minor_key(); }
+  ExtraICState GetExtraICState() const OVERRIDE { return sub_minor_key(); }
 
   void UpdateStatus(Handle<Object> object);
 
@@ -1354,8 +1408,8 @@
     set_sub_minor_key(TypesBits::update(sub_minor_key(), 0));
   }
 
-  virtual void PrintState(OStream& os) const OVERRIDE;     // NOLINT
-  virtual void PrintBaseName(OStream& os) const OVERRIDE;  // NOLINT
+  void PrintState(std::ostream& os) const OVERRIDE;     // NOLINT
+  void PrintBaseName(std::ostream& os) const OVERRIDE;  // NOLINT
 
  private:
   CompareNilICStub(Isolate* isolate, NilValue nil,
@@ -1382,7 +1436,7 @@
     State() : EnumSet<CompareNilType, byte>(0) { }
     explicit State(byte bits) : EnumSet<CompareNilType, byte>(bits) { }
   };
-  friend OStream& operator<<(OStream& os, const State& s);
+  friend std::ostream& operator<<(std::ostream& os, const State& s);
 
   State state() const { return State(TypesBits::decode(sub_minor_key())); }
 
@@ -1396,7 +1450,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const CompareNilICStub::State& s);
+std::ostream& operator<<(std::ostream& os, const CompareNilICStub::State& s);
 
 
 class CEntryStub : public PlatformCodeStub {
@@ -1423,7 +1477,7 @@
   int result_size() const { return ResultSizeBits::decode(minor_key_); }
 #endif  // _WIN64
 
-  bool NeedsImmovableCode();
+  bool NeedsImmovableCode() OVERRIDE;
 
   class SaveDoublesBits : public BitField<bool, 0, 1> {};
   class ResultSizeBits : public BitField<int, 1, 3> {};
@@ -1442,9 +1496,9 @@
   }
 
  private:
-  virtual void FinishCode(Handle<Code> code);
+  void FinishCode(Handle<Code> code) OVERRIDE;
 
-  virtual void PrintName(OStream& os) const OVERRIDE {  // NOLINT
+  void PrintName(std::ostream& os) const OVERRIDE {  // NOLINT
     os << (type() == StackFrame::ENTRY ? "JSEntryStub"
                                        : "JSConstructEntryStub");
   }
@@ -1475,7 +1529,7 @@
     minor_key_ = TypeBits::encode(type);
   }
 
-  virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
+  CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
     if (type() == READ_ELEMENT) {
       return ArgumentsAccessReadDescriptor(isolate());
     }
@@ -1490,7 +1544,7 @@
   void GenerateNewSloppyFast(MacroAssembler* masm);
   void GenerateNewSloppySlow(MacroAssembler* masm);
 
-  virtual void PrintName(OStream& os) const OVERRIDE;  // NOLINT
+  void PrintName(std::ostream& os) const OVERRIDE;  // NOLINT
 
   class TypeBits : public BitField<Type, 0, 2> {};
 
@@ -1544,7 +1598,7 @@
 
   bool NeedsChecks() const { return flags() != WRAP_AND_CALL; }
 
-  virtual void PrintName(OStream& os) const OVERRIDE;  // NOLINT
+  void PrintName(std::ostream& os) const OVERRIDE;  // NOLINT
 
   // Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
   class FlagBits : public BitField<CallFunctionFlags, 0, 2> {};
@@ -1563,7 +1617,7 @@
     minor_key_ = FlagBits::encode(flags);
   }
 
-  virtual void FinishCode(Handle<Code> code) {
+  void FinishCode(Handle<Code> code) OVERRIDE {
     code->set_has_function_cache(RecordCallTarget());
   }
 
@@ -1574,7 +1628,7 @@
     return (flags() & RECORD_CONSTRUCTOR_TARGET) != 0;
   }
 
-  virtual void PrintName(OStream& os) const OVERRIDE;  // NOLINT
+  void PrintName(std::ostream& os) const OVERRIDE;  // NOLINT
 
   class FlagBits : public BitField<CallConstructorFlags, 0, 1> {};
 
@@ -1594,6 +1648,15 @@
 };
 
 
+enum ReceiverCheckMode {
+  // We don't know anything about the receiver.
+  RECEIVER_IS_UNKNOWN,
+
+  // We know the receiver is a string.
+  RECEIVER_IS_STRING
+};
+
+
 // Generates code implementing String.prototype.charCodeAt.
 //
 // Only supports the case when the receiver is a string and the index
@@ -1606,20 +1669,19 @@
 // preserved, |scratch| and |result| are clobbered.
 class StringCharCodeAtGenerator {
  public:
-  StringCharCodeAtGenerator(Register object,
-                            Register index,
-                            Register result,
-                            Label* receiver_not_string,
-                            Label* index_not_number,
+  StringCharCodeAtGenerator(Register object, Register index, Register result,
+                            Label* receiver_not_string, Label* index_not_number,
                             Label* index_out_of_range,
-                            StringIndexFlags index_flags)
+                            StringIndexFlags index_flags,
+                            ReceiverCheckMode check_mode = RECEIVER_IS_UNKNOWN)
       : object_(object),
         index_(index),
         result_(result),
         receiver_not_string_(receiver_not_string),
         index_not_number_(index_not_number),
         index_out_of_range_(index_out_of_range),
-        index_flags_(index_flags) {
+        index_flags_(index_flags),
+        check_mode_(check_mode) {
     DCHECK(!result_.is(object_));
     DCHECK(!result_.is(index_));
   }
@@ -1651,6 +1713,7 @@
   Label* index_out_of_range_;
 
   StringIndexFlags index_flags_;
+  ReceiverCheckMode check_mode_;
 
   Label call_runtime_;
   Label index_not_smi_;
@@ -1710,21 +1773,14 @@
 // preserved, |scratch1|, |scratch2|, and |result| are clobbered.
 class StringCharAtGenerator {
  public:
-  StringCharAtGenerator(Register object,
-                        Register index,
-                        Register scratch,
-                        Register result,
-                        Label* receiver_not_string,
-                        Label* index_not_number,
-                        Label* index_out_of_range,
-                        StringIndexFlags index_flags)
-      : char_code_at_generator_(object,
-                                index,
-                                scratch,
-                                receiver_not_string,
-                                index_not_number,
-                                index_out_of_range,
-                                index_flags),
+  StringCharAtGenerator(Register object, Register index, Register scratch,
+                        Register result, Label* receiver_not_string,
+                        Label* index_not_number, Label* index_out_of_range,
+                        StringIndexFlags index_flags,
+                        ReceiverCheckMode check_mode = RECEIVER_IS_UNKNOWN)
+      : char_code_at_generator_(object, index, scratch, receiver_not_string,
+                                index_not_number, index_out_of_range,
+                                index_flags, check_mode),
         char_from_code_generator_(scratch, result) {}
 
   // Generates the fast case code. On the fallthrough path |result|
@@ -1762,7 +1818,13 @@
   explicit LoadDictionaryElementStub(Isolate* isolate)
       : HydrogenCodeStub(isolate) {}
 
-  DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
+  CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
+    if (FLAG_vector_ics) {
+      return VectorLoadICDescriptor(isolate());
+    }
+    return LoadDescriptor(isolate());
+  }
+
   DEFINE_HYDROGEN_CODE_STUB(LoadDictionaryElement, HydrogenCodeStub);
 };
 
@@ -1771,10 +1833,14 @@
  public:
   explicit KeyedLoadGenericStub(Isolate* isolate) : HydrogenCodeStub(isolate) {}
 
-  virtual Code::Kind GetCodeKind() const { return Code::KEYED_LOAD_IC; }
-  virtual InlineCacheState GetICState() const { return GENERIC; }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::KEYED_LOAD_IC; }
+  InlineCacheState GetICState() const OVERRIDE { return GENERIC; }
 
+  // Since KeyedLoadGeneric stub doesn't miss (simply calls runtime), it
+  // doesn't need to use the VectorLoadICDescriptor for the case when
+  // flag --vector-ics is true.
   DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
+
   DEFINE_HYDROGEN_CODE_STUB(KeyedLoadGeneric, HydrogenCodeStub);
 };
 
@@ -1786,13 +1852,11 @@
     minor_key_ = state.GetExtraICState();
   }
 
-  virtual Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; }
 
-  virtual InlineCacheState GetICState() const FINAL OVERRIDE {
-    return GENERIC;
-  }
+  InlineCacheState GetICState() const FINAL { return DEFAULT; }
 
-  virtual ExtraICState GetExtraICState() const FINAL OVERRIDE {
+  ExtraICState GetExtraICState() const FINAL {
     return static_cast<ExtraICState>(minor_key_);
   }
 
@@ -1811,9 +1875,7 @@
   explicit KeyedLoadICTrampolineStub(Isolate* isolate)
       : LoadICTrampolineStub(isolate, LoadICState(0)) {}
 
-  virtual Code::Kind GetCodeKind() const OVERRIDE {
-    return Code::KEYED_LOAD_IC;
-  }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::KEYED_LOAD_IC; }
 
   DEFINE_PLATFORM_CODE_STUB(KeyedLoadICTrampoline, LoadICTrampolineStub);
 };
@@ -1826,17 +1888,21 @@
     set_sub_minor_key(state.GetExtraICState());
   }
 
-  virtual Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; }
 
-  virtual InlineCacheState GetICState() const FINAL OVERRIDE {
-    return MEGAMORPHIC;
-  }
+  InlineCacheState GetICState() const FINAL { return MEGAMORPHIC; }
 
-  virtual ExtraICState GetExtraICState() const FINAL OVERRIDE {
+  ExtraICState GetExtraICState() const FINAL {
     return static_cast<ExtraICState>(sub_minor_key());
   }
 
-  DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
+  CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
+    if (FLAG_vector_ics) {
+      return VectorLoadICDescriptor(isolate());
+    }
+    return LoadDescriptor(isolate());
+  }
+
   DEFINE_HYDROGEN_CODE_STUB(MegamorphicLoad, HydrogenCodeStub);
 };
 
@@ -1848,13 +1914,11 @@
     set_sub_minor_key(state.GetExtraICState());
   }
 
-  virtual Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::LOAD_IC; }
 
-  virtual InlineCacheState GetICState() const FINAL OVERRIDE {
-    return GENERIC;
-  }
+  InlineCacheState GetICState() const FINAL { return DEFAULT; }
 
-  virtual ExtraICState GetExtraICState() const FINAL OVERRIDE {
+  ExtraICState GetExtraICState() const FINAL {
     return static_cast<ExtraICState>(sub_minor_key());
   }
 
@@ -1871,9 +1935,7 @@
   explicit VectorKeyedLoadStub(Isolate* isolate)
       : VectorLoadStub(isolate, LoadICState(0)) {}
 
-  virtual Code::Kind GetCodeKind() const OVERRIDE {
-    return Code::KEYED_LOAD_IC;
-  }
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::KEYED_LOAD_IC; }
 
   DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorLoadIC);
   DEFINE_HYDROGEN_CODE_STUB(VectorKeyedLoad, VectorLoadStub);
@@ -1893,7 +1955,7 @@
                  SSE3Bits::encode(CpuFeatures::IsSupported(SSE3) ? 1 : 0);
   }
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
  private:
   Register source() const {
@@ -1927,6 +1989,66 @@
 };
 
 
+class ScriptContextFieldStub : public HandlerStub {
+ public:
+  ScriptContextFieldStub(Isolate* isolate,
+                         const ScriptContextTable::LookupResult* lookup_result)
+      : HandlerStub(isolate) {
+    DCHECK(Accepted(lookup_result));
+    set_sub_minor_key(ContextIndexBits::encode(lookup_result->context_index) |
+                      SlotIndexBits::encode(lookup_result->slot_index));
+  }
+
+  int context_index() const {
+    return ContextIndexBits::decode(sub_minor_key());
+  }
+
+  int slot_index() const { return SlotIndexBits::decode(sub_minor_key()); }
+
+  static bool Accepted(const ScriptContextTable::LookupResult* lookup_result) {
+    return ContextIndexBits::is_valid(lookup_result->context_index) &&
+           SlotIndexBits::is_valid(lookup_result->slot_index);
+  }
+
+ private:
+  static const int kContextIndexBits = 13;
+  static const int kSlotIndexBits = 13;
+  class ContextIndexBits : public BitField<int, 0, kContextIndexBits> {};
+  class SlotIndexBits
+      : public BitField<int, kContextIndexBits, kSlotIndexBits> {};
+
+  Code::StubType GetStubType() OVERRIDE { return Code::FAST; }
+
+  DEFINE_CODE_STUB_BASE(ScriptContextFieldStub, HandlerStub);
+};
+
+
+class LoadScriptContextFieldStub : public ScriptContextFieldStub {
+ public:
+  LoadScriptContextFieldStub(
+      Isolate* isolate, const ScriptContextTable::LookupResult* lookup_result)
+      : ScriptContextFieldStub(isolate, lookup_result) {}
+
+ private:
+  Code::Kind kind() const OVERRIDE { return Code::LOAD_IC; }
+
+  DEFINE_HANDLER_CODE_STUB(LoadScriptContextField, ScriptContextFieldStub);
+};
+
+
+class StoreScriptContextFieldStub : public ScriptContextFieldStub {
+ public:
+  StoreScriptContextFieldStub(
+      Isolate* isolate, const ScriptContextTable::LookupResult* lookup_result)
+      : ScriptContextFieldStub(isolate, lookup_result) {}
+
+ private:
+  Code::Kind kind() const OVERRIDE { return Code::STORE_IC; }
+
+  DEFINE_HANDLER_CODE_STUB(StoreScriptContextField, ScriptContextFieldStub);
+};
+
+
 class LoadFastElementStub : public HydrogenCodeStub {
  public:
   LoadFastElementStub(Isolate* isolate, bool is_js_array,
@@ -1946,7 +2068,13 @@
   class ElementsKindBits: public BitField<ElementsKind, 0, 8> {};
   class IsJSArrayBits: public BitField<bool, 8, 1> {};
 
-  DEFINE_CALL_INTERFACE_DESCRIPTOR(Load);
+  CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE {
+    if (FLAG_vector_ics) {
+      return VectorLoadICDescriptor(isolate());
+    }
+    return LoadDescriptor(isolate());
+  }
+
   DEFINE_HYDROGEN_CODE_STUB(LoadFastElement, HydrogenCodeStub);
 };
 
@@ -2010,6 +2138,17 @@
 };
 
 
+class AllocateHeapNumberStub FINAL : public HydrogenCodeStub {
+ public:
+  explicit AllocateHeapNumberStub(Isolate* isolate)
+      : HydrogenCodeStub(isolate) {}
+
+ private:
+  DEFINE_CALL_INTERFACE_DESCRIPTOR(AllocateHeapNumber);
+  DEFINE_HYDROGEN_CODE_STUB(AllocateHeapNumber, HydrogenCodeStub);
+};
+
+
 class ArrayConstructorStubBase : public HydrogenCodeStub {
  public:
   ArrayConstructorStubBase(Isolate* isolate,
@@ -2040,7 +2179,8 @@
   static const int kAllocationSite = 1;
 
  protected:
-  OStream& BasePrintName(OStream& os, const char* name) const;  // NOLINT
+  std::ostream& BasePrintName(std::ostream& os,
+                              const char* name) const;  // NOLINT
 
  private:
   // Ensure data fits within available bits.
@@ -2064,7 +2204,7 @@
   }
 
  private:
-  virtual void PrintName(OStream& os) const OVERRIDE {  // NOLINT
+  void PrintName(std::ostream& os) const OVERRIDE {  // NOLINT
     BasePrintName(os, "ArrayNoArgumentConstructorStub");
   }
 
@@ -2084,7 +2224,7 @@
   }
 
  private:
-  virtual void PrintName(OStream& os) const {  // NOLINT
+  void PrintName(std::ostream& os) const OVERRIDE {  // NOLINT
     BasePrintName(os, "ArraySingleArgumentConstructorStub");
   }
 
@@ -2104,7 +2244,7 @@
   }
 
  private:
-  virtual void PrintName(OStream& os) const {  // NOLINT
+  void PrintName(std::ostream& os) const OVERRIDE {  // NOLINT
     BasePrintName(os, "ArrayNArgumentsConstructorStub");
   }
 
@@ -2248,18 +2388,18 @@
   Types types() const { return Types(TypesBits::decode(sub_minor_key())); }
   ResultMode mode() const { return ResultModeBits::decode(sub_minor_key()); }
 
-  virtual Code::Kind GetCodeKind() const { return Code::TO_BOOLEAN_IC; }
-  virtual void PrintState(OStream& os) const OVERRIDE;  // NOLINT
+  Code::Kind GetCodeKind() const OVERRIDE { return Code::TO_BOOLEAN_IC; }
+  void PrintState(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
   static Handle<Code> GetUninitialized(Isolate* isolate) {
     return ToBooleanStub(isolate, UNINITIALIZED).GetCode();
   }
 
-  virtual ExtraICState GetExtraICState() const { return types().ToIntegral(); }
+  ExtraICState GetExtraICState() const OVERRIDE { return types().ToIntegral(); }
 
-  virtual InlineCacheState GetICState() const {
+  InlineCacheState GetICState() const OVERRIDE {
     if (types().IsEmpty()) {
       return ::v8::internal::UNINITIALIZED;
     } else {
@@ -2281,7 +2421,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const ToBooleanStub::Types& t);
+std::ostream& operator<<(std::ostream& os, const ToBooleanStub::Types& t);
 
 
 class ElementsTransitionAndStoreStub : public HydrogenCodeStub {
@@ -2371,7 +2511,7 @@
   explicit ProfileEntryHookStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
 
   // The profile entry hook function is not allowed to cause a GC.
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
   // Generates a call to the entry hook if it's enabled.
   static void MaybeCallEntryHook(MacroAssembler* masm);
@@ -2396,7 +2536,7 @@
   }
 
   static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
  private:
   bool save_doubles() const { return SaveDoublesBits::decode(minor_key_); }
@@ -2417,6 +2557,15 @@
 };
 
 
+class ToNumberStub FINAL : public PlatformCodeStub {
+ public:
+  explicit ToNumberStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
+
+  DEFINE_CALL_INTERFACE_DESCRIPTOR(ToNumber);
+  DEFINE_PLATFORM_CODE_STUB(ToNumber, PlatformCodeStub);
+};
+
+
 class StringCompareStub : public PlatformCodeStub {
  public:
   explicit StringCompareStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
diff --git a/src/codegen.cc b/src/codegen.cc
index 1362232..627e836 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -11,7 +11,7 @@
 #include "src/debug.h"
 #include "src/prettyprinter.h"
 #include "src/rewriter.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -180,9 +180,7 @@
       Handle<Script> script = info->script();
       if (!script->IsUndefined() && !script->source()->IsUndefined()) {
         os << "--- Raw source ---\n";
-        ConsStringIteratorOp op;
         StringCharacterStream stream(String::cast(script->source()),
-                                     &op,
                                      function->start_position());
         // fun->end_position() points to the last character in the stream. We
         // need to compensate by adding one to calculate the length.
diff --git a/src/codegen.h b/src/codegen.h
index e01a398..ba99a40 100644
--- a/src/codegen.h
+++ b/src/codegen.h
@@ -6,7 +6,7 @@
 #define V8_CODEGEN_H_
 
 #include "src/code-stubs.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 // Include the declaration of the architecture defined class CodeGenerator.
 // The contract  to the shared code is that the the CodeGenerator is a subclass
diff --git a/src/collection-iterator.js b/src/collection-iterator.js
index 2bccc8d..c1a9a27 100644
--- a/src/collection-iterator.js
+++ b/src/collection-iterator.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
+"use strict";
 
 
 // This file relies on the fact that the following declaration has been made
@@ -77,6 +77,8 @@
   %FunctionSetName(SetIteratorSymbolIterator, '[Symbol.iterator]');
   %AddNamedProperty(SetIterator.prototype, symbolIterator,
       SetIteratorSymbolIterator, DONT_ENUM);
+  %AddNamedProperty(SetIterator.prototype, symbolToStringTag,
+      "Set Iterator", READ_ONLY | DONT_ENUM);
 }
 
 SetUpSetIterator();
@@ -174,6 +176,8 @@
   %FunctionSetName(MapIteratorSymbolIterator, '[Symbol.iterator]');
   %AddNamedProperty(MapIterator.prototype, symbolIterator,
       MapIteratorSymbolIterator, DONT_ENUM);
+  %AddNamedProperty(MapIterator.prototype, symbolToStringTag,
+      "Map Iterator", READ_ONLY | DONT_ENUM);
 }
 
 SetUpMapIterator();
diff --git a/src/collection.js b/src/collection.js
index 0027bd7..94bda70 100644
--- a/src/collection.js
+++ b/src/collection.js
@@ -30,7 +30,7 @@
     }
   }
 
-  %SetInitialize(this);
+  %_SetInitialize(this);
 
   if (IS_UNDEFINED(iter)) return;
 
@@ -56,7 +56,7 @@
   if (key === 0) {
     key = 0;
   }
-  return %SetAdd(this, key);
+  return %_SetAdd(this, key);
 }
 
 
@@ -65,7 +65,7 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['Set.prototype.has', this]);
   }
-  return %SetHas(this, key);
+  return %_SetHas(this, key);
 }
 
 
@@ -74,7 +74,7 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['Set.prototype.delete', this]);
   }
-  return %SetDelete(this, key);
+  return %_SetDelete(this, key);
 }
 
 
@@ -83,7 +83,7 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['Set.prototype.size', this]);
   }
-  return %SetGetSize(this);
+  return %_SetGetSize(this);
 }
 
 
@@ -92,7 +92,7 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['Set.prototype.clear', this]);
   }
-  %SetClear(this);
+  %_SetClear(this);
 }
 
 
@@ -105,6 +105,12 @@
   if (!IS_SPEC_FUNCTION(f)) {
     throw MakeTypeError('called_non_callable', [f]);
   }
+  var needs_wrapper = false;
+  if (IS_NULL_OR_UNDEFINED(receiver)) {
+    receiver = %GetDefaultReceiver(f) || receiver;
+  } else {
+    needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
+  }
 
   var iterator = new SetIterator(this, ITERATOR_KIND_VALUES);
   var key;
@@ -113,7 +119,8 @@
   while (%SetIteratorNext(iterator, value_array)) {
     if (stepping) %DebugPrepareStepInIfStepping(f);
     key = value_array[0];
-    %_CallFunction(receiver, key, key, this, f);
+    var new_receiver = needs_wrapper ? ToObject(receiver) : receiver;
+    %_CallFunction(new_receiver, key, key, this, f);
   }
 }
 
@@ -126,6 +133,8 @@
   %SetCode($Set, SetConstructor);
   %FunctionSetPrototype($Set, new $Object());
   %AddNamedProperty($Set.prototype, "constructor", $Set, DONT_ENUM);
+  %AddNamedProperty(
+      $Set.prototype, symbolToStringTag, "Set", DONT_ENUM | READ_ONLY);
 
   %FunctionSetLength(SetForEach, 1);
 
@@ -161,7 +170,7 @@
     }
   }
 
-  %MapInitialize(this);
+  %_MapInitialize(this);
 
   if (IS_UNDEFINED(iter)) return;
 
@@ -184,7 +193,7 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['Map.prototype.get', this]);
   }
-  return %MapGet(this, key);
+  return %_MapGet(this, key);
 }
 
 
@@ -200,7 +209,7 @@
   if (key === 0) {
     key = 0;
   }
-  return %MapSet(this, key, value);
+  return %_MapSet(this, key, value);
 }
 
 
@@ -209,7 +218,7 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['Map.prototype.has', this]);
   }
-  return %MapHas(this, key);
+  return %_MapHas(this, key);
 }
 
 
@@ -218,7 +227,7 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['Map.prototype.delete', this]);
   }
-  return %MapDelete(this, key);
+  return %_MapDelete(this, key);
 }
 
 
@@ -227,7 +236,7 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['Map.prototype.size', this]);
   }
-  return %MapGetSize(this);
+  return %_MapGetSize(this);
 }
 
 
@@ -236,7 +245,7 @@
     throw MakeTypeError('incompatible_method_receiver',
                         ['Map.prototype.clear', this]);
   }
-  %MapClear(this);
+  %_MapClear(this);
 }
 
 
@@ -249,13 +258,20 @@
   if (!IS_SPEC_FUNCTION(f)) {
     throw MakeTypeError('called_non_callable', [f]);
   }
+  var needs_wrapper = false;
+  if (IS_NULL_OR_UNDEFINED(receiver)) {
+    receiver = %GetDefaultReceiver(f) || receiver;
+  } else {
+    needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
+  }
 
   var iterator = new MapIterator(this, ITERATOR_KIND_ENTRIES);
   var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
   var value_array = [UNDEFINED, UNDEFINED];
   while (%MapIteratorNext(iterator, value_array)) {
     if (stepping) %DebugPrepareStepInIfStepping(f);
-    %_CallFunction(receiver, value_array[1], value_array[0], this, f);
+    var new_receiver = needs_wrapper ? ToObject(receiver) : receiver;
+    %_CallFunction(new_receiver, value_array[1], value_array[0], this, f);
   }
 }
 
@@ -268,6 +284,8 @@
   %SetCode($Map, MapConstructor);
   %FunctionSetPrototype($Map, new $Object());
   %AddNamedProperty($Map.prototype, "constructor", $Map, DONT_ENUM);
+  %AddNamedProperty(
+      $Map.prototype, symbolToStringTag, "Map", DONT_ENUM | READ_ONLY);
 
   %FunctionSetLength(MapForEach, 1);
 
diff --git a/src/compilation-cache.cc b/src/compilation-cache.cc
index aab2fe5..6c9f95a 100644
--- a/src/compilation-cache.cc
+++ b/src/compilation-cache.cc
@@ -13,11 +13,6 @@
 
 
 // The number of generations for each sub cache.
-// The number of ScriptGenerations is carefully chosen based on histograms.
-// See issue 458: http://code.google.com/p/v8/issues/detail?id=458
-static const int kScriptGenerations = 5;
-static const int kEvalGlobalGenerations = 2;
-static const int kEvalContextualGenerations = 2;
 static const int kRegExpGenerations = 2;
 
 // Initial size of each compilation cache table allocated.
@@ -26,9 +21,9 @@
 
 CompilationCache::CompilationCache(Isolate* isolate)
     : isolate_(isolate),
-      script_(isolate, kScriptGenerations),
-      eval_global_(isolate, kEvalGlobalGenerations),
-      eval_contextual_(isolate, kEvalContextualGenerations),
+      script_(isolate, 1),
+      eval_global_(isolate, 1),
+      eval_contextual_(isolate, 1),
       reg_exp_(isolate, kRegExpGenerations),
       enabled_(true) {
   CompilationSubCache* subcaches[kSubCacheCount] =
@@ -58,6 +53,14 @@
 
 
 void CompilationSubCache::Age() {
+  // Don't directly age single-generation caches.
+  if (generations_ == 1) {
+    if (tables_[0] != isolate()->heap()->undefined_value()) {
+      CompilationCacheTable::cast(tables_[0])->Age();
+    }
+    return;
+  }
+
   // Age the generations implicitly killing off the oldest.
   for (int i = generations_ - 1; i > 0; i--) {
     tables_[i] = tables_[i - 1];
@@ -102,9 +105,7 @@
 
 CompilationCacheScript::CompilationCacheScript(Isolate* isolate,
                                                int generations)
-    : CompilationSubCache(isolate, generations),
-      script_histogram_(NULL),
-      script_histogram_initialized_(false) { }
+    : CompilationSubCache(isolate, generations) {}
 
 
 // We only re-use a cached function for some script source code if the
@@ -173,20 +174,6 @@
     }
   }
 
-  if (!script_histogram_initialized_) {
-    script_histogram_ = isolate()->stats_table()->CreateHistogram(
-        "V8.ScriptCache",
-        0,
-        kScriptGenerations,
-        kScriptGenerations + 1);
-    script_histogram_initialized_ = true;
-  }
-
-  if (script_histogram_ != NULL) {
-    // The level NUMBER_OF_SCRIPT_GENERATIONS is equivalent to a cache miss.
-    isolate()->stats_table()->AddHistogramSample(script_histogram_, generation);
-  }
-
   // Once outside the manacles of the handle scope, we need to recheck
   // to see if we actually found a cached script. If so, we return a
   // handle created in the caller's handle scope.
diff --git a/src/compilation-cache.h b/src/compilation-cache.h
index 6799b1c..a7c84b7 100644
--- a/src/compilation-cache.h
+++ b/src/compilation-cache.h
@@ -89,9 +89,6 @@
                  int column_offset,
                  bool is_shared_cross_origin);
 
-  void* script_histogram_;
-  bool script_histogram_initialized_;
-
   DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript);
 };
 
diff --git a/src/compilation-statistics.cc b/src/compilation-statistics.cc
new file mode 100644
index 0000000..2686ff7
--- /dev/null
+++ b/src/compilation-statistics.cc
@@ -0,0 +1,144 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <ostream>  // NOLINT(readability/streams)
+#include <vector>
+
+#include "src/base/platform/platform.h"
+#include "src/compilation-statistics.h"
+
+namespace v8 {
+namespace internal {
+
+void CompilationStatistics::RecordPhaseStats(const char* phase_kind_name,
+                                             const char* phase_name,
+                                             const BasicStats& stats) {
+  std::string phase_name_str(phase_name);
+  auto it = phase_map_.find(phase_name_str);
+  if (it == phase_map_.end()) {
+    PhaseStats phase_stats(phase_map_.size(), phase_kind_name);
+    it = phase_map_.insert(std::make_pair(phase_name_str, phase_stats)).first;
+  }
+  it->second.Accumulate(stats);
+}
+
+
+void CompilationStatistics::RecordPhaseKindStats(const char* phase_kind_name,
+                                                 const BasicStats& stats) {
+  std::string phase_kind_name_str(phase_kind_name);
+  auto it = phase_kind_map_.find(phase_kind_name_str);
+  if (it == phase_kind_map_.end()) {
+    PhaseKindStats phase_kind_stats(phase_kind_map_.size());
+    it = phase_kind_map_.insert(std::make_pair(phase_kind_name_str,
+                                               phase_kind_stats)).first;
+  }
+  it->second.Accumulate(stats);
+}
+
+
+void CompilationStatistics::RecordTotalStats(size_t source_size,
+                                             const BasicStats& stats) {
+  source_size += source_size;
+  total_stats_.Accumulate(stats);
+}
+
+
+void CompilationStatistics::BasicStats::Accumulate(const BasicStats& stats) {
+  delta_ += stats.delta_;
+  total_allocated_bytes_ += stats.total_allocated_bytes_;
+  if (stats.absolute_max_allocated_bytes_ > absolute_max_allocated_bytes_) {
+    absolute_max_allocated_bytes_ = stats.absolute_max_allocated_bytes_;
+    max_allocated_bytes_ = stats.max_allocated_bytes_;
+    function_name_ = stats.function_name_;
+  }
+}
+
+
+static void WriteLine(std::ostream& os, const char* name,
+                      const CompilationStatistics::BasicStats& stats,
+                      const CompilationStatistics::BasicStats& total_stats) {
+  const size_t kBufferSize = 128;
+  char buffer[kBufferSize];
+
+  double ms = stats.delta_.InMillisecondsF();
+  double percent = stats.delta_.PercentOf(total_stats.delta_);
+  double size_percent =
+      static_cast<double>(stats.total_allocated_bytes_ * 100) /
+      static_cast<double>(total_stats.total_allocated_bytes_);
+  base::OS::SNPrintF(buffer, kBufferSize,
+                     "%28s %10.3f ms / %5.1f %%"
+                     "%10u total / %5.1f %% "
+                     "%10u max %10u abs_max",
+                     name, ms, percent, stats.total_allocated_bytes_,
+                     size_percent, stats.max_allocated_bytes_,
+                     stats.absolute_max_allocated_bytes_);
+
+  os << buffer;
+  if (stats.function_name_.size() > 0) {
+    os << " : " << stats.function_name_.c_str();
+  }
+  os << std::endl;
+}
+
+
+static void WriteFullLine(std::ostream& os) {
+  os << "--------------------------------------------------------"
+        "--------------------------------------------------------\n";
+}
+
+
+static void WriteHeader(std::ostream& os) {
+  WriteFullLine(os);
+  os << "                             Turbofan timing results:\n";
+  WriteFullLine(os);
+}
+
+
+static void WritePhaseKindBreak(std::ostream& os) {
+  os << "                             ---------------------------"
+        "--------------------------------------------------------\n";
+}
+
+
+std::ostream& operator<<(std::ostream& os, const CompilationStatistics& s) {
+  // phase_kind_map_ and phase_map_ don't get mutated, so store a bunch of
+  // pointers into them.
+
+  typedef std::vector<CompilationStatistics::PhaseKindMap::const_iterator>
+      SortedPhaseKinds;
+  SortedPhaseKinds sorted_phase_kinds(s.phase_kind_map_.size());
+  for (auto it = s.phase_kind_map_.begin(); it != s.phase_kind_map_.end();
+       ++it) {
+    sorted_phase_kinds[it->second.insert_order_] = it;
+  }
+
+  typedef std::vector<CompilationStatistics::PhaseMap::const_iterator>
+      SortedPhases;
+  SortedPhases sorted_phases(s.phase_map_.size());
+  for (auto it = s.phase_map_.begin(); it != s.phase_map_.end(); ++it) {
+    sorted_phases[it->second.insert_order_] = it;
+  }
+
+  WriteHeader(os);
+  for (auto phase_kind_it : sorted_phase_kinds) {
+    const auto& phase_kind_name = phase_kind_it->first;
+    for (auto phase_it : sorted_phases) {
+      const auto& phase_stats = phase_it->second;
+      if (phase_stats.phase_kind_name_ != phase_kind_name) continue;
+      const auto& phase_name = phase_it->first;
+      WriteLine(os, phase_name.c_str(), phase_stats, s.total_stats_);
+    }
+    WritePhaseKindBreak(os);
+    const auto& phase_kind_stats = phase_kind_it->second;
+    WriteLine(os, phase_kind_name.c_str(), phase_kind_stats, s.total_stats_);
+    os << std::endl;
+  }
+  WriteFullLine(os);
+  WriteLine(os, "totals", s.total_stats_, s.total_stats_);
+
+  return os;
+}
+
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compilation-statistics.h b/src/compilation-statistics.h
new file mode 100644
index 0000000..45ffb9b
--- /dev/null
+++ b/src/compilation-statistics.h
@@ -0,0 +1,86 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILATION_STATISTICS_H_
+#define V8_COMPILATION_STATISTICS_H_
+
+#include <map>
+#include <string>
+
+#include "src/allocation.h"
+#include "src/base/platform/time.h"
+
+namespace v8 {
+namespace internal {
+
+class CompilationInfo;
+
+class CompilationStatistics FINAL : public Malloced {
+ public:
+  CompilationStatistics() {}
+
+  class BasicStats {
+   public:
+    BasicStats()
+        : total_allocated_bytes_(0),
+          max_allocated_bytes_(0),
+          absolute_max_allocated_bytes_(0) {}
+
+    void Accumulate(const BasicStats& stats);
+
+    base::TimeDelta delta_;
+    size_t total_allocated_bytes_;
+    size_t max_allocated_bytes_;
+    size_t absolute_max_allocated_bytes_;
+    std::string function_name_;
+  };
+
+  void RecordPhaseStats(const char* phase_kind_name, const char* phase_name,
+                        const BasicStats& stats);
+
+  void RecordPhaseKindStats(const char* phase_kind_name,
+                            const BasicStats& stats);
+
+  void RecordTotalStats(size_t source_size, const BasicStats& stats);
+
+ private:
+  class TotalStats : public BasicStats {
+   public:
+    TotalStats() : source_size_(0) {}
+    uint64_t source_size_;
+  };
+
+  class OrderedStats : public BasicStats {
+   public:
+    explicit OrderedStats(size_t insert_order) : insert_order_(insert_order) {}
+    size_t insert_order_;
+  };
+
+  class PhaseStats : public OrderedStats {
+   public:
+    PhaseStats(size_t insert_order, const char* phase_kind_name)
+        : OrderedStats(insert_order), phase_kind_name_(phase_kind_name) {}
+    std::string phase_kind_name_;
+  };
+
+  friend std::ostream& operator<<(std::ostream& os,
+                                  const CompilationStatistics& s);
+
+  typedef OrderedStats PhaseKindStats;
+  typedef std::map<std::string, PhaseKindStats> PhaseKindMap;
+  typedef std::map<std::string, PhaseStats> PhaseMap;
+
+  TotalStats total_stats_;
+  PhaseKindMap phase_kind_map_;
+  PhaseMap phase_map_;
+
+  DISALLOW_COPY_AND_ASSIGN(CompilationStatistics);
+};
+
+std::ostream& operator<<(std::ostream& os, const CompilationStatistics& s);
+
+}  // namespace internal
+}  // namespace v8
+
+#endif
diff --git a/src/compiler.cc b/src/compiler.cc
index ea604c9..3b52aa2 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -6,6 +6,8 @@
 
 #include "src/compiler.h"
 
+#include "src/ast-numbering.h"
+#include "src/ast-this-access-visitor.h"
 #include "src/bootstrapper.h"
 #include "src/codegen.h"
 #include "src/compilation-cache.h"
@@ -19,6 +21,7 @@
 #include "src/isolate-inl.h"
 #include "src/lithium.h"
 #include "src/liveedit.h"
+#include "src/messages.h"
 #include "src/parser.h"
 #include "src/rewriter.h"
 #include "src/runtime-profiler.h"
@@ -33,7 +36,7 @@
 
 
 ScriptData::ScriptData(const byte* data, int length)
-    : owns_data_(false), data_(data), length_(length) {
+    : owns_data_(false), rejected_(false), data_(data), length_(length) {
   if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) {
     byte* copy = NewArray<byte>(length);
     DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment));
@@ -143,7 +146,7 @@
   isolate_ = isolate;
   function_ = NULL;
   scope_ = NULL;
-  global_scope_ = NULL;
+  script_scope_ = NULL;
   extension_ = NULL;
   cached_data_ = NULL;
   compile_options_ = ScriptCompiler::kNoCompileOptions;
@@ -165,6 +168,14 @@
   if (!script_.is_null() && script_->type()->value() == Script::TYPE_NATIVE) {
     MarkAsNative();
   }
+  // Compiling for the snapshot typically results in different code than
+  // compiling later on. This means that code recompiled with deoptimization
+  // support won't be "equivalent" (as defined by SharedFunctionInfo::
+  // EnableDeoptimizationSupport), so it will replace the old code and all
+  // its type feedback. To avoid this, always compile functions in the snapshot
+  // with deoptimization support.
+  if (isolate_->serializer_enabled()) EnableDeoptimizationSupport();
+
   if (isolate_->debug()->is_active()) MarkAsDebug();
   if (FLAG_context_specialization) MarkAsContextSpecializing();
   if (FLAG_turbo_inlining) MarkAsInliningEnabled();
@@ -282,13 +293,14 @@
 void CompilationInfo::PrepareForCompilation(Scope* scope) {
   DCHECK(scope_ == NULL);
   scope_ = scope;
+}
 
-  int length = function()->slot_count();
+
+void CompilationInfo::EnsureFeedbackVector() {
   if (feedback_vector_.is_null()) {
-    // Allocate the feedback vector too.
-    feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector(length);
+    feedback_vector_ = isolate()->factory()->NewTypeFeedbackVector(
+        function()->feedback_vector_spec());
   }
-  DCHECK(feedback_vector_->length() == length);
 }
 
 
@@ -298,29 +310,29 @@
       : HOptimizedGraphBuilder(info) {
   }
 
-#define DEF_VISIT(type)                                 \
-  virtual void Visit##type(type* node) OVERRIDE {    \
-    if (node->position() != RelocInfo::kNoPosition) {   \
-      SetSourcePosition(node->position());              \
-    }                                                   \
-    HOptimizedGraphBuilder::Visit##type(node);          \
+#define DEF_VISIT(type)                               \
+  void Visit##type(type* node) OVERRIDE {             \
+    if (node->position() != RelocInfo::kNoPosition) { \
+      SetSourcePosition(node->position());            \
+    }                                                 \
+    HOptimizedGraphBuilder::Visit##type(node);        \
   }
   EXPRESSION_NODE_LIST(DEF_VISIT)
 #undef DEF_VISIT
 
-#define DEF_VISIT(type)                                          \
-  virtual void Visit##type(type* node) OVERRIDE {             \
-    if (node->position() != RelocInfo::kNoPosition) {            \
-      SetSourcePosition(node->position());                       \
-    }                                                            \
-    HOptimizedGraphBuilder::Visit##type(node);                   \
+#define DEF_VISIT(type)                               \
+  void Visit##type(type* node) OVERRIDE {             \
+    if (node->position() != RelocInfo::kNoPosition) { \
+      SetSourcePosition(node->position());            \
+    }                                                 \
+    HOptimizedGraphBuilder::Visit##type(node);        \
   }
   STATEMENT_NODE_LIST(DEF_VISIT)
 #undef DEF_VISIT
 
-#define DEF_VISIT(type)                                            \
-  virtual void Visit##type(type* node) OVERRIDE {               \
-    HOptimizedGraphBuilder::Visit##type(node);                     \
+#define DEF_VISIT(type)                        \
+  void Visit##type(type* node) OVERRIDE {      \
+    HOptimizedGraphBuilder::Visit##type(node); \
   }
   MODULE_NODE_LIST(DEF_VISIT)
   DECLARATION_NODE_LIST(DEF_VISIT)
@@ -329,13 +341,14 @@
 
 
 OptimizedCompileJob::Status OptimizedCompileJob::CreateGraph() {
-  DCHECK(isolate()->use_crankshaft());
   DCHECK(info()->IsOptimizing());
   DCHECK(!info()->IsCompilingForDebugging());
 
-  // We should never arrive here if optimization has been disabled on the
-  // shared function info.
-  DCHECK(!info()->shared_info()->optimization_disabled());
+  // Optimization could have been disabled by the parser.
+  if (info()->shared_info()->optimization_disabled()) {
+    return AbortOptimization(
+        info()->shared_info()->disable_optimization_reason());
+  }
 
   // Do not use crankshaft if we need to be able to set break points.
   if (isolate()->DebuggerHasBreakPoints()) {
@@ -402,20 +415,26 @@
   // Check the whitelist for TurboFan.
   if ((FLAG_turbo_asm && info()->shared_info()->asm_function()) ||
       info()->closure()->PassesFilter(FLAG_turbo_filter)) {
+    if (FLAG_trace_opt) {
+      OFStream os(stdout);
+      os << "[compiling method " << Brief(*info()->closure())
+         << " using TurboFan]" << std::endl;
+    }
+    Timer t(this, &time_taken_to_create_graph_);
     compiler::Pipeline pipeline(info());
     pipeline.GenerateCode();
     if (!info()->code().is_null()) {
-      if (FLAG_turbo_deoptimization) {
-        info()->context()->native_context()->AddOptimizedCode(*info()->code());
-      }
       return SetLastStatus(SUCCEEDED);
     }
   }
 
+  if (FLAG_trace_opt) {
+    OFStream os(stdout);
+    os << "[compiling method " << Brief(*info()->closure())
+       << " using Crankshaft]" << std::endl;
+  }
+
   if (FLAG_trace_hydrogen) {
-    Handle<String> name = info()->function()->debug_name();
-    PrintF("-----------------------------------------------------------\n");
-    PrintF("Compiling method %s using hydrogen\n", name->ToCString().get());
     isolate()->GetHTracer()->TraceCompilation(info());
   }
 
@@ -476,6 +495,9 @@
   DCHECK(last_status() == SUCCEEDED);
   // TODO(turbofan): Currently everything is done in the first phase.
   if (!info()->code().is_null()) {
+    if (FLAG_turbo_deoptimization) {
+      info()->context()->native_context()->AddOptimizedCode(*info()->code());
+    }
     RecordOptimizationStats();
     return last_status();
   }
@@ -557,18 +579,24 @@
   // the estimate conservatively.
   if (shared->GetIsolate()->serializer_enabled()) {
     estimate += 2;
-  } else if (FLAG_clever_optimizations) {
+  } else {
     // Inobject slack tracking will reclaim redundant inobject space later,
     // so we can afford to adjust the estimate generously.
     estimate += 8;
-  } else {
-    estimate += 3;
   }
 
   shared->set_expected_nof_properties(estimate);
 }
 
 
+static void MaybeDisableOptimization(Handle<SharedFunctionInfo> shared_info,
+                                     BailoutReason bailout_reason) {
+  if (bailout_reason != kNoReason) {
+    shared_info->DisableOptimization(bailout_reason);
+  }
+}
+
+
 // Sets the function info on a function.
 // The start_position points to the first '(' character after the function name
 // in the full script source. When counting characters in the script source the
@@ -595,9 +623,12 @@
   function_info->set_has_duplicate_parameters(lit->has_duplicate_parameters());
   function_info->set_ast_node_count(lit->ast_node_count());
   function_info->set_is_function(lit->is_function());
-  function_info->set_bailout_reason(lit->dont_optimize_reason());
+  MaybeDisableOptimization(function_info, lit->dont_optimize_reason());
   function_info->set_dont_cache(lit->flags()->Contains(kDontCache));
   function_info->set_kind(lit->kind());
+  function_info->set_uses_super_property(lit->uses_super_property());
+  function_info->set_uses_super_constructor_call(
+      lit->uses_super_constructor_call());
   function_info->set_asm_function(lit->scope()->asm_function());
 }
 
@@ -638,12 +669,7 @@
 
 static bool CompileUnoptimizedCode(CompilationInfo* info) {
   DCHECK(AllowCompilation::IsAllowed(info->isolate()));
-  DCHECK(info->function() != NULL);
-  if (!Rewriter::Rewrite(info)) return false;
-  if (!Scope::Analyze(info)) return false;
-  DCHECK(info->scope() != NULL);
-
-  if (!FullCodeGenerator::MakeCode(info)) {
+  if (!Compiler::Analyze(info) || !FullCodeGenerator::MakeCode(info)) {
     Isolate* isolate = info->isolate();
     if (!isolate->has_pending_exception()) isolate->StackOverflow();
     return false;
@@ -663,8 +689,7 @@
   FunctionLiteral* lit = info->function();
   shared->set_strict_mode(lit->strict_mode());
   SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
-  shared->set_bailout_reason(lit->dont_optimize_reason());
-  shared->set_ast_node_count(lit->ast_node_count());
+  MaybeDisableOptimization(shared, lit->dont_optimize_reason());
 
   // Compile unoptimized code.
   if (!CompileUnoptimizedCode(info)) return MaybeHandle<Code>();
@@ -734,17 +759,107 @@
 }
 
 
-static bool CompileOptimizedPrologue(CompilationInfo* info) {
-  if (!Parser::Parse(info)) return false;
-  if (!Rewriter::Rewrite(info)) return false;
-  if (!Scope::Analyze(info)) return false;
-  DCHECK(info->scope() != NULL);
+static bool Renumber(CompilationInfo* info) {
+  if (!AstNumbering::Renumber(info->function(), info->zone())) return false;
+  if (!info->shared_info().is_null()) {
+    FunctionLiteral* lit = info->function();
+    info->shared_info()->set_ast_node_count(lit->ast_node_count());
+    MaybeDisableOptimization(info->shared_info(), lit->dont_optimize_reason());
+    info->shared_info()->set_dont_cache(lit->flags()->Contains(kDontCache));
+  }
   return true;
 }
 
 
+static void ThrowSuperConstructorCheckError(CompilationInfo* info,
+                                            Statement* stmt) {
+  MaybeHandle<Object> obj = info->isolate()->factory()->NewTypeError(
+      "super_constructor_call", HandleVector<Object>(nullptr, 0));
+  Handle<Object> exception;
+  if (!obj.ToHandle(&exception)) return;
+
+  MessageLocation location(info->script(), stmt->position(), stmt->position());
+  USE(info->isolate()->Throw(*exception, &location));
+}
+
+
+static bool CheckSuperConstructorCall(CompilationInfo* info) {
+  FunctionLiteral* function = info->function();
+  if (!function->uses_super_constructor_call()) return true;
+
+  if (function->is_default_constructor()) return true;
+
+  ZoneList<Statement*>* body = function->body();
+  CHECK(body->length() > 0);
+
+  int super_call_index = 0;
+  // Allow 'use strict' and similiar and empty statements.
+  while (true) {
+    CHECK(super_call_index < body->length());  // We know there is a super call.
+    Statement* stmt = body->at(super_call_index);
+    if (stmt->IsExpressionStatement() &&
+        stmt->AsExpressionStatement()->expression()->IsLiteral()) {
+      super_call_index++;
+      continue;
+    }
+    if (stmt->IsEmptyStatement()) {
+      super_call_index++;
+      continue;
+    }
+    break;
+  }
+
+  Statement* stmt = body->at(super_call_index);
+  ExpressionStatement* exprStm = stmt->AsExpressionStatement();
+  if (exprStm == nullptr) {
+    ThrowSuperConstructorCheckError(info, stmt);
+    return false;
+  }
+  Call* callExpr = exprStm->expression()->AsCall();
+  if (callExpr == nullptr) {
+    ThrowSuperConstructorCheckError(info, stmt);
+    return false;
+  }
+
+  if (!callExpr->expression()->IsSuperReference()) {
+    ThrowSuperConstructorCheckError(info, stmt);
+    return false;
+  }
+
+  ZoneList<Expression*>* arguments = callExpr->arguments();
+
+  AstThisAccessVisitor this_access_visitor(info->zone());
+  this_access_visitor.VisitExpressions(arguments);
+
+  if (this_access_visitor.HasStackOverflow()) return false;
+  if (this_access_visitor.UsesThis()) {
+    ThrowSuperConstructorCheckError(info, stmt);
+    return false;
+  }
+
+  return true;
+}
+
+
+bool Compiler::Analyze(CompilationInfo* info) {
+  DCHECK(info->function() != NULL);
+  if (!Rewriter::Rewrite(info)) return false;
+  if (!Scope::Analyze(info)) return false;
+  if (!Renumber(info)) return false;
+  DCHECK(info->scope() != NULL);
+  if (!CheckSuperConstructorCall(info)) return false;
+  return true;
+}
+
+
+bool Compiler::ParseAndAnalyze(CompilationInfo* info) {
+  if (!Parser::Parse(info)) return false;
+  return Compiler::Analyze(info);
+}
+
+
 static bool GetOptimizedCodeNow(CompilationInfo* info) {
-  if (!CompileOptimizedPrologue(info)) return false;
+  if (!Compiler::ParseAndAnalyze(info)) return false;
 
   TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate());
 
@@ -765,11 +880,6 @@
   InsertCodeIntoOptimizedCodeMap(info);
   RecordFunctionCompilation(Logger::LAZY_COMPILE_TAG, info,
                             info->shared_info());
-  if (FLAG_trace_opt) {
-    PrintF("[completed optimizing ");
-    info->closure()->ShortPrint();
-    PrintF("]\n");
-  }
   return true;
 }
 
@@ -786,7 +896,7 @@
   }
 
   CompilationHandleScope handle_scope(info);
-  if (!CompileOptimizedPrologue(info)) return false;
+  if (!Compiler::ParseAndAnalyze(info)) return false;
   info->SaveHandles();  // Copy handles to the compilation handle scope.
 
   TimerEventScope<TimerEventRecompileSynchronous> timer(info->isolate());
@@ -826,23 +936,25 @@
 
 
 MaybeHandle<Code> Compiler::GetLazyCode(Handle<JSFunction> function) {
-  DCHECK(!function->GetIsolate()->has_pending_exception());
+  Isolate* isolate = function->GetIsolate();
+  DCHECK(!isolate->has_pending_exception());
   DCHECK(!function->is_compiled());
-
-  if (FLAG_turbo_asm && function->shared()->asm_function()) {
+  // If the debugger is active, do not compile with turbofan unless we can
+  // deopt from turbofan code.
+  if (FLAG_turbo_asm && function->shared()->asm_function() &&
+      (FLAG_turbo_deoptimization || !isolate->debug()->is_active())) {
     CompilationInfoWithZone info(function);
 
-    VMState<COMPILER> state(info.isolate());
-    PostponeInterruptsScope postpone(info.isolate());
+    VMState<COMPILER> state(isolate);
+    PostponeInterruptsScope postpone(isolate);
 
-    info.SetOptimizing(BailoutId::None(),
-                       Handle<Code>(function->shared()->code()));
-
+    info.SetOptimizing(BailoutId::None(), handle(function->shared()->code()));
     info.MarkAsContextSpecializing();
-    info.MarkAsTypingEnabled();
-    info.MarkAsInliningDisabled();
 
-    if (GetOptimizedCodeNow(&info)) return info.code();
+    if (GetOptimizedCodeNow(&info)) {
+      DCHECK(function->shared()->is_compiled());
+      return info.code();
+    }
   }
 
   if (function->shared()->is_compiled()) {
@@ -851,13 +963,12 @@
 
   CompilationInfoWithZone info(function);
   Handle<Code> result;
-  ASSIGN_RETURN_ON_EXCEPTION(info.isolate(), result,
-                             GetUnoptimizedCodeCommon(&info), Code);
+  ASSIGN_RETURN_ON_EXCEPTION(isolate, result, GetUnoptimizedCodeCommon(&info),
+                             Code);
 
-  if (FLAG_always_opt &&
-      info.isolate()->use_crankshaft() &&
+  if (FLAG_always_opt && isolate->use_crankshaft() &&
       !info.shared_info()->optimization_disabled() &&
-      !info.isolate()->DebuggerHasBreakPoints()) {
+      !isolate->DebuggerHasBreakPoints()) {
     Handle<Code> opt_code;
     if (Compiler::GetOptimizedCode(
             function, result,
@@ -900,17 +1011,26 @@
 // TODO(turbofan): In the future, unoptimized code with deopt support could
 // be generated lazily once deopt is triggered.
 bool Compiler::EnsureDeoptimizationSupport(CompilationInfo* info) {
+  DCHECK(info->function() != NULL);
+  DCHECK(info->scope() != NULL);
   if (!info->shared_info()->has_deoptimization_support()) {
-    CompilationInfoWithZone unoptimized(info->shared_info());
+    Handle<SharedFunctionInfo> shared = info->shared_info();
+    CompilationInfoWithZone unoptimized(shared);
     // Note that we use the same AST that we will use for generating the
     // optimized code.
     unoptimized.SetFunction(info->function());
     unoptimized.PrepareForCompilation(info->scope());
     unoptimized.SetContext(info->context());
     unoptimized.EnableDeoptimizationSupport();
+    // If the current code has reloc info for serialization, also include
+    // reloc info for serialization for the new code, so that deopt support
+    // can be added without losing IC state.
+    if (shared->code()->kind() == Code::FUNCTION &&
+        shared->code()->has_reloc_info_for_serialization()) {
+      unoptimized.PrepareForSerializing();
+    }
     if (!FullCodeGenerator::MakeCode(&unoptimized)) return false;
 
-    Handle<SharedFunctionInfo> shared = info->shared_info();
     shared->EnableDeoptimizationSupport(*unoptimized.code());
     shared->set_feedback_vector(*unoptimized.feedback_vector());
 
@@ -1002,6 +1122,8 @@
 
   DCHECK(info->is_eval() || info->is_global());
 
+  info->MarkAsToplevel();
+
   Handle<SharedFunctionInfo> result;
 
   { VMState<COMPILER> state(info->isolate());
@@ -1139,19 +1261,20 @@
     int column_offset, bool is_shared_cross_origin, Handle<Context> context,
     v8::Extension* extension, ScriptData** cached_data,
     ScriptCompiler::CompileOptions compile_options, NativesFlag natives) {
+  Isolate* isolate = source->GetIsolate();
   if (compile_options == ScriptCompiler::kNoCompileOptions) {
     cached_data = NULL;
   } else if (compile_options == ScriptCompiler::kProduceParserCache ||
              compile_options == ScriptCompiler::kProduceCodeCache) {
     DCHECK(cached_data && !*cached_data);
     DCHECK(extension == NULL);
+    DCHECK(!isolate->debug()->is_loaded());
   } else {
     DCHECK(compile_options == ScriptCompiler::kConsumeParserCache ||
            compile_options == ScriptCompiler::kConsumeCodeCache);
     DCHECK(cached_data && *cached_data);
     DCHECK(extension == NULL);
   }
-  Isolate* isolate = source->GetIsolate();
   int source_length = source->length();
   isolate->counters()->total_load_size()->Increment(source_length);
   isolate->counters()->total_compile_size()->Increment(source_length);
@@ -1166,7 +1289,12 @@
         compile_options == ScriptCompiler::kConsumeCodeCache &&
         !isolate->debug()->is_loaded()) {
       HistogramTimerScope timer(isolate->counters()->compile_deserialize());
-      return CodeSerializer::Deserialize(isolate, *cached_data, source);
+      Handle<SharedFunctionInfo> result;
+      if (CodeSerializer::Deserialize(isolate, *cached_data, source)
+              .ToHandle(&result)) {
+        return result;
+      }
+      // Deserializer failed. Fall through to compile.
     } else {
       maybe_result = compilation_cache->LookupScript(
           source, script_name, line_offset, column_offset,
@@ -1216,8 +1344,8 @@
             isolate->counters()->compile_serialize());
         *cached_data = CodeSerializer::Serialize(isolate, result, source);
         if (FLAG_profile_deserialization) {
-          PrintF("[Compiling and serializing %d bytes took %0.3f ms]\n",
-                 (*cached_data)->length(), timer.Elapsed().InMillisecondsF());
+          PrintF("[Compiling and serializing took %0.3f ms]\n",
+                 timer.Elapsed().InMillisecondsF());
         }
       }
     }
@@ -1269,13 +1397,30 @@
   bool allow_lazy = literal->AllowsLazyCompilation() &&
       !DebuggerWantsEagerCompilation(&info, allow_lazy_without_ctx);
 
+  if (outer_info->is_toplevel() && outer_info->will_serialize()) {
+    // Make sure that if the toplevel code (possibly to be serialized),
+    // the inner function must be allowed to be compiled lazily.
+    // This is necessary to serialize toplevel code without inner functions.
+    DCHECK(allow_lazy);
+  }
+
   // Generate code
   Handle<ScopeInfo> scope_info;
   if (FLAG_lazy && allow_lazy && !literal->is_parenthesized()) {
     Handle<Code> code = isolate->builtins()->CompileLazy();
     info.SetCode(code);
+    // There's no need in theory for a lazy-compiled function to have a type
+    // feedback vector, but some parts of the system expect all
+    // SharedFunctionInfo instances to have one.  The size of the vector depends
+    // on how many feedback-needing nodes are in the tree, and when lazily
+    // parsing we might not know that, if this function was never parsed before.
+    // In that case the vector will be replaced the next time MakeCode is
+    // called.
+    info.EnsureFeedbackVector();
     scope_info = Handle<ScopeInfo>(ScopeInfo::Empty(isolate));
-  } else if (FullCodeGenerator::MakeCode(&info)) {
+  } else if (Renumber(&info) && FullCodeGenerator::MakeCode(&info)) {
+    // MakeCode will ensure that the feedback vector is present and
+    // appropriately sized.
     DCHECK(!info.code().is_null());
     scope_info = ScopeInfo::Create(info.scope(), info.zone());
   } else {
@@ -1314,6 +1459,7 @@
   Isolate* isolate = info->isolate();
   DCHECK(AllowCompilation::IsAllowed(isolate));
   VMState<COMPILER> state(isolate);
+  DCHECK(isolate->use_crankshaft());
   DCHECK(!isolate->has_pending_exception());
   PostponeInterruptsScope postpone(isolate);
 
@@ -1399,8 +1545,10 @@
 
 bool Compiler::DebuggerWantsEagerCompilation(CompilationInfo* info,
                                              bool allow_lazy_without_ctx) {
-  return LiveEditFunctionTracker::IsActive(info->isolate()) ||
-         (info->isolate()->DebuggerHasBreakPoints() && !allow_lazy_without_ctx);
+  if (LiveEditFunctionTracker::IsActive(info->isolate())) return true;
+  Debug* debug = info->isolate()->debug();
+  bool debugging = debug->is_active() || debug->has_break_points();
+  return debugging && !allow_lazy_without_ctx;
 }
 
 
diff --git a/src/compiler.h b/src/compiler.h
index f950ef7..3db32ce 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -39,6 +39,9 @@
 
   const byte* data() const { return data_; }
   int length() const { return length_; }
+  bool rejected() const { return rejected_; }
+
+  void Reject() { rejected_ = true; }
 
   void AcquireDataOwnership() {
     DCHECK(!owns_data_);
@@ -51,7 +54,8 @@
   }
 
  private:
-  bool owns_data_;
+  bool owns_data_ : 1;
+  bool rejected_ : 1;
   const byte* data_;
   int length_;
 
@@ -84,7 +88,8 @@
     kContextSpecializing = 1 << 16,
     kInliningEnabled = 1 << 17,
     kTypingEnabled = 1 << 18,
-    kDisableFutureOptimization = 1 << 19
+    kDisableFutureOptimization = 1 << 19,
+    kToplevel = 1 << 20
   };
 
   CompilationInfo(Handle<JSFunction> closure, Zone* zone);
@@ -104,7 +109,7 @@
   }
   FunctionLiteral* function() const { return function_; }
   Scope* scope() const { return scope_; }
-  Scope* global_scope() const { return global_scope_; }
+  Scope* script_scope() const { return script_scope_; }
   Handle<Code> code() const { return code_; }
   Handle<JSFunction> closure() const { return closure_; }
   Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
@@ -199,14 +204,16 @@
 
   void MarkAsInliningEnabled() { SetFlag(kInliningEnabled); }
 
-  void MarkAsInliningDisabled() { SetFlag(kInliningEnabled, false); }
-
   bool is_inlining_enabled() const { return GetFlag(kInliningEnabled); }
 
   void MarkAsTypingEnabled() { SetFlag(kTypingEnabled); }
 
   bool is_typing_enabled() const { return GetFlag(kTypingEnabled); }
 
+  void MarkAsToplevel() { SetFlag(kToplevel); }
+
+  bool is_toplevel() const { return GetFlag(kToplevel); }
+
   bool IsCodePreAgingActive() const {
     return FLAG_optimize_for_size && FLAG_age_code && !will_serialize() &&
            !is_debug();
@@ -226,10 +233,11 @@
     function_ = literal;
   }
   void PrepareForCompilation(Scope* scope);
-  void SetGlobalScope(Scope* global_scope) {
-    DCHECK(global_scope_ == NULL);
-    global_scope_ = global_scope;
+  void SetScriptScope(Scope* script_scope) {
+    DCHECK(script_scope_ == NULL);
+    script_scope_ = script_scope;
   }
+  void EnsureFeedbackVector();
   Handle<TypeFeedbackVector> feedback_vector() const {
     return feedback_vector_;
   }
@@ -386,8 +394,6 @@
     ast_value_factory_owned_ = owned;
   }
 
-  AstNode::IdGen* ast_node_id_gen() { return &ast_node_id_gen_; }
-
  protected:
   CompilationInfo(Handle<Script> script,
                   Zone* zone);
@@ -438,8 +444,8 @@
   // The scope of the function literal as a convenience.  Set to indicate
   // that scopes have been analyzed.
   Scope* scope_;
-  // The global scope provided as a convenience.
-  Scope* global_scope_;
+  // The script scope provided as a convenience.
+  Scope* script_scope_;
   // For compiled stubs, the stub object
   HydrogenCodeStub* code_stub_;
   // The compiled code.
@@ -457,7 +463,7 @@
   ScriptData** cached_data_;
   ScriptCompiler::CompileOptions compile_options_;
 
-  // The context of the caller for eval code, and the global context for a
+  // The context of the caller for eval code, and the script context for a
   // global script. Will be a null handle otherwise.
   Handle<Context> context_;
 
@@ -507,7 +513,6 @@
 
   AstValueFactory* ast_value_factory_;
   bool ast_value_factory_owned_;
-  AstNode::IdGen ast_node_id_gen_;
 
   // This flag is used by the main thread to track whether this compilation
   // should be abandoned due to dependency change.
@@ -673,11 +678,16 @@
   MUST_USE_RESULT static MaybeHandle<Code> GetDebugCode(
       Handle<JSFunction> function);
 
+  // Parser::Parse, then Compiler::Analyze.
+  static bool ParseAndAnalyze(CompilationInfo* info);
+  // Rewrite, analyze scopes, and renumber.
+  static bool Analyze(CompilationInfo* info);
+  // Adds deoptimization support, requires ParseAndAnalyze.
+  static bool EnsureDeoptimizationSupport(CompilationInfo* info);
+
   static bool EnsureCompiled(Handle<JSFunction> function,
                              ClearExceptionFlag flag);
 
-  static bool EnsureDeoptimizationSupport(CompilationInfo* info);
-
   static void CompileForLiveEdit(Handle<Script> script);
 
   // Compile a String source within a context for eval.
diff --git a/src/compiler/access-builder.cc b/src/compiler/access-builder.cc
index ac9cfa8..8c8e530 100644
--- a/src/compiler/access-builder.cc
+++ b/src/compiler/access-builder.cc
@@ -11,43 +11,73 @@
 
 // static
 FieldAccess AccessBuilder::ForMap() {
-  return {kTaggedBase, HeapObject::kMapOffset, Handle<Name>(), Type::Any(),
+  return {kTaggedBase, HeapObject::kMapOffset, MaybeHandle<Name>(), Type::Any(),
           kMachAnyTagged};
 }
 
 
 // static
 FieldAccess AccessBuilder::ForJSObjectProperties() {
-  return {kTaggedBase, JSObject::kPropertiesOffset, Handle<Name>(), Type::Any(),
-          kMachAnyTagged};
+  return {kTaggedBase, JSObject::kPropertiesOffset, MaybeHandle<Name>(),
+          Type::Any(), kMachAnyTagged};
 }
 
 
 // static
 FieldAccess AccessBuilder::ForJSObjectElements() {
-  return {kTaggedBase, JSObject::kElementsOffset, Handle<Name>(),
+  return {kTaggedBase, JSObject::kElementsOffset, MaybeHandle<Name>(),
           Type::Internal(), kMachAnyTagged};
 }
 
 
 // static
 FieldAccess AccessBuilder::ForJSFunctionContext() {
-  return {kTaggedBase, JSFunction::kContextOffset, Handle<Name>(),
+  return {kTaggedBase, JSFunction::kContextOffset, MaybeHandle<Name>(),
           Type::Internal(), kMachAnyTagged};
 }
 
 
 // static
 FieldAccess AccessBuilder::ForJSArrayBufferBackingStore() {
-  return {kTaggedBase, JSArrayBuffer::kBackingStoreOffset, Handle<Name>(),
-          Type::UntaggedPtr(), kMachPtr};
+  return {kTaggedBase, JSArrayBuffer::kBackingStoreOffset, MaybeHandle<Name>(),
+          Type::UntaggedPointer(), kMachPtr};
 }
 
 
 // static
 FieldAccess AccessBuilder::ForExternalArrayPointer() {
-  return {kTaggedBase, ExternalArray::kExternalPointerOffset, Handle<Name>(),
-          Type::UntaggedPtr(), kMachPtr};
+  return {kTaggedBase, ExternalArray::kExternalPointerOffset,
+          MaybeHandle<Name>(), Type::UntaggedPointer(), kMachPtr};
+}
+
+
+// static
+FieldAccess AccessBuilder::ForMapInstanceType() {
+  return {kTaggedBase, Map::kInstanceTypeOffset, Handle<Name>(),
+          Type::UntaggedUnsigned8(), kMachUint8};
+}
+
+
+// static
+FieldAccess AccessBuilder::ForStringLength() {
+  return {kTaggedBase, String::kLengthOffset, Handle<Name>(),
+          Type::SignedSmall(), kMachAnyTagged};
+}
+
+
+// static
+FieldAccess AccessBuilder::ForValue() {
+  return {kTaggedBase, JSValue::kValueOffset, Handle<Name>(), Type::Any(),
+          kMachAnyTagged};
+}
+
+
+// static
+FieldAccess AccessBuilder::ForContextSlot(size_t index) {
+  int offset = Context::kHeaderSize + static_cast<int>(index) * kPointerSize;
+  DCHECK_EQ(offset,
+            Context::SlotOffset(static_cast<int>(index)) + kHeapObjectTag);
+  return {kTaggedBase, offset, Handle<Name>(), Type::Any(), kMachAnyTagged};
 }
 
 
@@ -58,13 +88,6 @@
 
 
 // static
-ElementAccess AccessBuilder::ForBackingStoreElement(MachineType rep) {
-  return {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
-          rep};
-}
-
-
-// static
 ElementAccess AccessBuilder::ForTypedArrayElement(ExternalArrayType type,
                                                   bool is_external) {
   BaseTaggedness taggedness = is_external ? kUntaggedBase : kTaggedBase;
@@ -84,9 +107,9 @@
     case kExternalUint32Array:
       return {taggedness, header_size, Type::Unsigned32(), kMachUint32};
     case kExternalFloat32Array:
-      return {taggedness, header_size, Type::Number(), kRepFloat32};
+      return {taggedness, header_size, Type::Number(), kMachFloat32};
     case kExternalFloat64Array:
-      return {taggedness, header_size, Type::Number(), kRepFloat64};
+      return {taggedness, header_size, Type::Number(), kMachFloat64};
   }
   UNREACHABLE();
   return {kUntaggedBase, 0, Type::None(), kMachNone};
diff --git a/src/compiler/access-builder.h b/src/compiler/access-builder.h
index 7d0bda1..d6385e4 100644
--- a/src/compiler/access-builder.h
+++ b/src/compiler/access-builder.h
@@ -34,12 +34,21 @@
   // Provides access to ExternalArray::external_pointer() field.
   static FieldAccess ForExternalArrayPointer();
 
+  // Provides access to Map::instance_type() field.
+  static FieldAccess ForMapInstanceType();
+
+  // Provides access to String::length() field.
+  static FieldAccess ForStringLength();
+
+  // Provides access to JSValue::value() field.
+  static FieldAccess ForValue();
+
+  // Provides access Context slots.
+  static FieldAccess ForContextSlot(size_t index);
+
   // Provides access to FixedArray elements.
   static ElementAccess ForFixedArrayElement();
 
-  // TODO(mstarzinger): Raw access only for testing, drop me.
-  static ElementAccess ForBackingStoreElement(MachineType rep);
-
   // Provides access to Fixed{type}TypedArray and External{type}Array elements.
   static ElementAccess ForTypedArrayElement(ExternalArrayType type,
                                             bool is_external);
diff --git a/src/compiler/arm/code-generator-arm.cc b/src/compiler/arm/code-generator-arm.cc
index 1ec174d..cfa4de9 100644
--- a/src/compiler/arm/code-generator-arm.cc
+++ b/src/compiler/arm/code-generator-arm.cc
@@ -22,11 +22,35 @@
 
 
 // Adds Arm-specific methods to convert InstructionOperands.
-class ArmOperandConverter : public InstructionOperandConverter {
+class ArmOperandConverter FINAL : public InstructionOperandConverter {
  public:
   ArmOperandConverter(CodeGenerator* gen, Instruction* instr)
       : InstructionOperandConverter(gen, instr) {}
 
+  SwVfpRegister OutputFloat32Register(int index = 0) {
+    return ToFloat32Register(instr_->OutputAt(index));
+  }
+
+  SwVfpRegister InputFloat32Register(int index) {
+    return ToFloat32Register(instr_->InputAt(index));
+  }
+
+  SwVfpRegister ToFloat32Register(InstructionOperand* op) {
+    return ToFloat64Register(op).low();
+  }
+
+  LowDwVfpRegister OutputFloat64Register(int index = 0) {
+    return ToFloat64Register(instr_->OutputAt(index));
+  }
+
+  LowDwVfpRegister InputFloat64Register(int index) {
+    return ToFloat64Register(instr_->InputAt(index));
+  }
+
+  LowDwVfpRegister ToFloat64Register(InstructionOperand* op) {
+    return LowDwVfpRegister::from_code(ToDoubleRegister(op).code());
+  }
+
   SBit OutputSBit() const {
     switch (instr_->flags_mode()) {
       case kFlags_branch:
@@ -44,12 +68,16 @@
     switch (constant.type()) {
       case Constant::kInt32:
         return Operand(constant.ToInt32());
+      case Constant::kFloat32:
+        return Operand(
+            isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
       case Constant::kFloat64:
         return Operand(
             isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
       case Constant::kInt64:
       case Constant::kExternalReference:
       case Constant::kHeapObject:
+      case Constant::kRpoNumber:
         break;
     }
     UNREACHABLE();
@@ -114,9 +142,8 @@
     return MemOperand(r0);
   }
 
-  MemOperand InputOffset() {
-    int index = 0;
-    return InputOffset(&index);
+  MemOperand InputOffset(int first_index = 0) {
+    return InputOffset(&first_index);
   }
 
   MemOperand ToMemOperand(InstructionOperand* op) const {
@@ -131,6 +158,112 @@
 };
 
 
+namespace {
+
+class OutOfLineLoadFloat32 FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadFloat32(CodeGenerator* gen, SwVfpRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL {
+    __ vmov(result_, std::numeric_limits<float>::quiet_NaN());
+  }
+
+ private:
+  SwVfpRegister const result_;
+};
+
+
+class OutOfLineLoadFloat64 FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadFloat64(CodeGenerator* gen, DwVfpRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL {
+    __ vmov(result_, std::numeric_limits<double>::quiet_NaN(), kScratchReg);
+  }
+
+ private:
+  DwVfpRegister const result_;
+};
+
+
+class OutOfLineLoadInteger FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadInteger(CodeGenerator* gen, Register result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL { __ mov(result_, Operand::Zero()); }
+
+ private:
+  Register const result_;
+};
+
+}  // namespace
+
+
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(width)                           \
+  do {                                                               \
+    auto result = i.OutputFloat##width##Register();                  \
+    auto offset = i.InputRegister(0);                                \
+    if (instr->InputAt(1)->IsRegister()) {                           \
+      __ cmp(offset, i.InputRegister(1));                            \
+    } else {                                                         \
+      __ cmp(offset, i.InputImmediate(1));                           \
+    }                                                                \
+    auto ool = new (zone()) OutOfLineLoadFloat##width(this, result); \
+    __ b(hs, ool->entry());                                          \
+    __ vldr(result, i.InputOffset(2));                               \
+    __ bind(ool->exit());                                            \
+    DCHECK_EQ(LeaveCC, i.OutputSBit());                              \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr)                \
+  do {                                                          \
+    auto result = i.OutputRegister();                           \
+    auto offset = i.InputRegister(0);                           \
+    if (instr->InputAt(1)->IsRegister()) {                      \
+      __ cmp(offset, i.InputRegister(1));                       \
+    } else {                                                    \
+      __ cmp(offset, i.InputImmediate(1));                      \
+    }                                                           \
+    auto ool = new (zone()) OutOfLineLoadInteger(this, result); \
+    __ b(hs, ool->entry());                                     \
+    __ asm_instr(result, i.InputOffset(2));                     \
+    __ bind(ool->exit());                                       \
+    DCHECK_EQ(LeaveCC, i.OutputSBit());                         \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_STORE_FLOAT(width)        \
+  do {                                             \
+    auto offset = i.InputRegister(0);              \
+    if (instr->InputAt(1)->IsRegister()) {         \
+      __ cmp(offset, i.InputRegister(1));          \
+    } else {                                       \
+      __ cmp(offset, i.InputImmediate(1));         \
+    }                                              \
+    auto value = i.InputFloat##width##Register(2); \
+    __ vstr(value, i.InputOffset(3), lo);          \
+    DCHECK_EQ(LeaveCC, i.OutputSBit());            \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
+  do {                                            \
+    auto offset = i.InputRegister(0);             \
+    if (instr->InputAt(1)->IsRegister()) {        \
+      __ cmp(offset, i.InputRegister(1));         \
+    } else {                                      \
+      __ cmp(offset, i.InputImmediate(1));        \
+    }                                             \
+    auto value = i.InputRegister(2);              \
+    __ asm_instr(value, i.InputOffset(3), lo);    \
+    DCHECK_EQ(LeaveCC, i.OutputSBit());           \
+  } while (0)
+
+
 // Assembles an instruction after register allocation, producing machine code.
 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
   ArmOperandConverter i(this, instr);
@@ -166,7 +299,7 @@
       break;
     }
     case kArchJmp:
-      __ b(code_->GetLabel(i.InputBlock(0)));
+      AssembleArchJump(i.InputRpo(0));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     case kArchNop:
@@ -177,8 +310,12 @@
       AssembleReturn();
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
+    case kArchStackPointer:
+      __ mov(i.OutputRegister(), sp);
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
     case kArchTruncateDoubleToI:
-      __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
+      __ TruncateDoubleToI(i.OutputRegister(), i.InputFloat64Register(0));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     case kArmAdd:
@@ -208,6 +345,19 @@
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
+    case kArmSmmul:
+      __ smmul(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmSmmla:
+      __ smmla(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+               i.InputRegister(2));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmUmull:
+      __ umull(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0),
+               i.InputRegister(1), i.OutputSBit());
+      break;
     case kArmSdiv: {
       CpuFeatureScope scope(masm(), SUDIV);
       __ sdiv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
@@ -255,6 +405,42 @@
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
+    case kArmSxtb:
+      __ sxtb(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmSxth:
+      __ sxth(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmSxtab:
+      __ sxtab(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+               i.InputInt32(2));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmSxtah:
+      __ sxtah(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+               i.InputInt32(2));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmUxtb:
+      __ uxtb(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmUxth:
+      __ uxth(i.OutputRegister(), i.InputRegister(0), i.InputInt32(1));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmUxtab:
+      __ uxtab(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+               i.InputInt32(2));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    case kArmUxtah:
+      __ uxtah(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+               i.InputInt32(2));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
     case kArmCmp:
       __ cmp(i.InputRegister(0), i.InputOperand2(1));
       DCHECK_EQ(SetCC, i.OutputSBit());
@@ -272,38 +458,38 @@
       DCHECK_EQ(SetCC, i.OutputSBit());
       break;
     case kArmVcmpF64:
-      __ VFPCompareAndSetFlags(i.InputDoubleRegister(0),
-                               i.InputDoubleRegister(1));
+      __ VFPCompareAndSetFlags(i.InputFloat64Register(0),
+                               i.InputFloat64Register(1));
       DCHECK_EQ(SetCC, i.OutputSBit());
       break;
     case kArmVaddF64:
-      __ vadd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
-              i.InputDoubleRegister(1));
+      __ vadd(i.OutputFloat64Register(), i.InputFloat64Register(0),
+              i.InputFloat64Register(1));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     case kArmVsubF64:
-      __ vsub(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
-              i.InputDoubleRegister(1));
+      __ vsub(i.OutputFloat64Register(), i.InputFloat64Register(0),
+              i.InputFloat64Register(1));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     case kArmVmulF64:
-      __ vmul(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
-              i.InputDoubleRegister(1));
+      __ vmul(i.OutputFloat64Register(), i.InputFloat64Register(0),
+              i.InputFloat64Register(1));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     case kArmVmlaF64:
-      __ vmla(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
-              i.InputDoubleRegister(2));
+      __ vmla(i.OutputFloat64Register(), i.InputFloat64Register(1),
+              i.InputFloat64Register(2));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     case kArmVmlsF64:
-      __ vmls(i.OutputDoubleRegister(), i.InputDoubleRegister(1),
-              i.InputDoubleRegister(2));
+      __ vmls(i.OutputFloat64Register(), i.InputFloat64Register(1),
+              i.InputFloat64Register(2));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     case kArmVdivF64:
-      __ vdiv(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
-              i.InputDoubleRegister(1));
+      __ vdiv(i.OutputFloat64Register(), i.InputFloat64Register(0),
+              i.InputFloat64Register(1));
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     case kArmVmodF64: {
@@ -311,45 +497,67 @@
       // and generate a CallAddress instruction instead.
       FrameScope scope(masm(), StackFrame::MANUAL);
       __ PrepareCallCFunction(0, 2, kScratchReg);
-      __ MovToFloatParameters(i.InputDoubleRegister(0),
-                              i.InputDoubleRegister(1));
+      __ MovToFloatParameters(i.InputFloat64Register(0),
+                              i.InputFloat64Register(1));
       __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()),
                        0, 2);
       // Move the result in the double result register.
-      __ MovFromFloatResult(i.OutputDoubleRegister());
+      __ MovFromFloatResult(i.OutputFloat64Register());
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
-    case kArmVnegF64:
-      __ vneg(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
-      break;
     case kArmVsqrtF64:
-      __ vsqrt(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      __ vsqrt(i.OutputFloat64Register(), i.InputFloat64Register(0));
       break;
+    case kArmVfloorF64:
+      __ vrintm(i.OutputFloat64Register(), i.InputFloat64Register(0));
+      break;
+    case kArmVceilF64:
+      __ vrintp(i.OutputFloat64Register(), i.InputFloat64Register(0));
+      break;
+    case kArmVroundTruncateF64:
+      __ vrintz(i.OutputFloat64Register(), i.InputFloat64Register(0));
+      break;
+    case kArmVroundTiesAwayF64:
+      __ vrinta(i.OutputFloat64Register(), i.InputFloat64Register(0));
+      break;
+    case kArmVnegF64:
+      __ vneg(i.OutputFloat64Register(), i.InputFloat64Register(0));
+      break;
+    case kArmVcvtF32F64: {
+      __ vcvt_f32_f64(i.OutputFloat32Register(), i.InputFloat64Register(0));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
+    case kArmVcvtF64F32: {
+      __ vcvt_f64_f32(i.OutputFloat64Register(), i.InputFloat32Register(0));
+      DCHECK_EQ(LeaveCC, i.OutputSBit());
+      break;
+    }
     case kArmVcvtF64S32: {
       SwVfpRegister scratch = kScratchDoubleReg.low();
       __ vmov(scratch, i.InputRegister(0));
-      __ vcvt_f64_s32(i.OutputDoubleRegister(), scratch);
+      __ vcvt_f64_s32(i.OutputFloat64Register(), scratch);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
     case kArmVcvtF64U32: {
       SwVfpRegister scratch = kScratchDoubleReg.low();
       __ vmov(scratch, i.InputRegister(0));
-      __ vcvt_f64_u32(i.OutputDoubleRegister(), scratch);
+      __ vcvt_f64_u32(i.OutputFloat64Register(), scratch);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
     case kArmVcvtS32F64: {
       SwVfpRegister scratch = kScratchDoubleReg.low();
-      __ vcvt_s32_f64(scratch, i.InputDoubleRegister(0));
+      __ vcvt_s32_f64(scratch, i.InputFloat64Register(0));
       __ vmov(i.OutputRegister(), scratch);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
     case kArmVcvtU32F64: {
       SwVfpRegister scratch = kScratchDoubleReg.low();
-      __ vcvt_u32_f64(scratch, i.InputDoubleRegister(0));
+      __ vcvt_u32_f64(scratch, i.InputFloat64Register(0));
       __ vmov(i.OutputRegister(), scratch);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
@@ -392,30 +600,26 @@
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
-    case kArmVldr32: {
-      SwVfpRegister scratch = kScratchDoubleReg.low();
-      __ vldr(scratch, i.InputOffset());
-      __ vcvt_f64_f32(i.OutputDoubleRegister(), scratch);
+    case kArmVldrF32: {
+      __ vldr(i.OutputFloat32Register(), i.InputOffset());
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
-    case kArmVstr32: {
+    case kArmVstrF32: {
       int index = 0;
-      SwVfpRegister scratch = kScratchDoubleReg.low();
       MemOperand operand = i.InputOffset(&index);
-      __ vcvt_f32_f64(scratch, i.InputDoubleRegister(index));
-      __ vstr(scratch, operand);
+      __ vstr(i.InputFloat32Register(index), operand);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
-    case kArmVldr64:
-      __ vldr(i.OutputDoubleRegister(), i.InputOffset());
+    case kArmVldrF64:
+      __ vldr(i.OutputFloat64Register(), i.InputOffset());
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
-    case kArmVstr64: {
+    case kArmVstrF64: {
       int index = 0;
       MemOperand operand = i.InputOffset(&index);
-      __ vstr(i.InputDoubleRegister(index), operand);
+      __ vstr(i.InputFloat64Register(index), operand);
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
@@ -436,33 +640,62 @@
       DCHECK_EQ(LeaveCC, i.OutputSBit());
       break;
     }
+    case kCheckedLoadInt8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(ldrsb);
+      break;
+    case kCheckedLoadUint8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(ldrb);
+      break;
+    case kCheckedLoadInt16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(ldrsh);
+      break;
+    case kCheckedLoadUint16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(ldrh);
+      break;
+    case kCheckedLoadWord32:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(ldr);
+      break;
+    case kCheckedLoadFloat32:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(32);
+      break;
+    case kCheckedLoadFloat64:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(64);
+      break;
+    case kCheckedStoreWord8:
+      ASSEMBLE_CHECKED_STORE_INTEGER(strb);
+      break;
+    case kCheckedStoreWord16:
+      ASSEMBLE_CHECKED_STORE_INTEGER(strh);
+      break;
+    case kCheckedStoreWord32:
+      ASSEMBLE_CHECKED_STORE_INTEGER(str);
+      break;
+    case kCheckedStoreFloat32:
+      ASSEMBLE_CHECKED_STORE_FLOAT(32);
+      break;
+    case kCheckedStoreFloat64:
+      ASSEMBLE_CHECKED_STORE_FLOAT(64);
+      break;
   }
 }
 
 
 // Assembles branches after an instruction.
-void CodeGenerator::AssembleArchBranch(Instruction* instr,
-                                       FlagsCondition condition) {
+void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
   ArmOperandConverter i(this, instr);
-  Label done;
-
-  // Emit a branch. The true and false targets are always the last two inputs
-  // to the instruction.
-  BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2);
-  BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1);
-  bool fallthru = IsNextInAssemblyOrder(fblock);
-  Label* tlabel = code()->GetLabel(tblock);
-  Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
-  switch (condition) {
+  Label* tlabel = branch->true_label;
+  Label* flabel = branch->false_label;
+  switch (branch->condition) {
     case kUnorderedEqual:
-      __ b(vs, flabel);
-    // Fall through.
+      // The "eq" condition will not catch the unordered case.
+      // The jump/fall through to false label will be used if the comparison
+      // was unordered.
     case kEqual:
       __ b(eq, tlabel);
       break;
     case kUnorderedNotEqual:
-      __ b(vs, tlabel);
-    // Fall through.
+      // Unordered or not equal can be tested with "ne" condtion.
+      // See ARMv7 manual A8.3 - Conditional execution.
     case kNotEqual:
       __ b(ne, tlabel);
       break;
@@ -479,26 +712,28 @@
       __ b(gt, tlabel);
       break;
     case kUnorderedLessThan:
-      __ b(vs, flabel);
-    // Fall through.
+      // The "lo" condition will not catch the unordered case.
+      // The jump/fall through to false label will be used if the comparison
+      // was unordered.
     case kUnsignedLessThan:
       __ b(lo, tlabel);
       break;
     case kUnorderedGreaterThanOrEqual:
-      __ b(vs, tlabel);
-    // Fall through.
+      // Unordered, greater than or equal can be tested with "hs" condtion.
+      // See ARMv7 manual A8.3 - Conditional execution.
     case kUnsignedGreaterThanOrEqual:
       __ b(hs, tlabel);
       break;
     case kUnorderedLessThanOrEqual:
-      __ b(vs, flabel);
-    // Fall through.
+      // The "ls" condition will not catch the unordered case.
+      // The jump/fall through to false label will be used if the comparison
+      // was unordered.
     case kUnsignedLessThanOrEqual:
       __ b(ls, tlabel);
       break;
     case kUnorderedGreaterThan:
-      __ b(vs, tlabel);
-    // Fall through.
+      // Unordered or greater than can be tested with "hi" condtion.
+      // See ARMv7 manual A8.3 - Conditional execution.
     case kUnsignedGreaterThan:
       __ b(hi, tlabel);
       break;
@@ -509,8 +744,12 @@
       __ b(vc, tlabel);
       break;
   }
-  if (!fallthru) __ b(flabel);  // no fallthru to flabel.
-  __ bind(&done);
+  if (!branch->fallthru) __ b(flabel);  // no fallthru to flabel.
+}
+
+
+void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+  if (!IsNextInAssemblyOrder(target)) __ b(GetLabel(target));
 }
 
 
@@ -634,28 +873,10 @@
       __ stm(db_w, sp, saves);
     }
   } else if (descriptor->IsJSFunctionCall()) {
-    CompilationInfo* info = linkage()->info();
+    CompilationInfo* info = this->info();
     __ Prologue(info->IsCodePreAgingActive());
     frame()->SetRegisterSaveAreaSize(
         StandardFrameConstants::kFixedFrameSizeFromFp);
-
-    // Sloppy mode functions and builtins need to replace the receiver with the
-    // global proxy when called as functions (without an explicit receiver
-    // object).
-    // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
-    if (info->strict_mode() == SLOPPY && !info->is_native()) {
-      Label ok;
-      // +2 for return address and saved frame pointer.
-      int receiver_slot = info->scope()->num_parameters() + 2;
-      __ ldr(r2, MemOperand(fp, receiver_slot * kPointerSize));
-      __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
-      __ b(ne, &ok);
-      __ ldr(r2, GlobalObjectOperand());
-      __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalProxyOffset));
-      __ str(r2, MemOperand(fp, receiver_slot * kPointerSize));
-      __ bind(&ok);
-    }
-
   } else {
     __ StubPrologue();
     frame()->SetRegisterSaveAreaSize(
@@ -720,10 +941,10 @@
       __ str(temp, g.ToMemOperand(destination));
     }
   } else if (source->IsConstant()) {
+    Constant src = g.ToConstant(source);
     if (destination->IsRegister() || destination->IsStackSlot()) {
       Register dst =
           destination->IsRegister() ? g.ToRegister(destination) : kScratchReg;
-      Constant src = g.ToConstant(source);
       switch (src.type()) {
         case Constant::kInt32:
           __ mov(dst, Operand(src.ToInt32()));
@@ -731,6 +952,10 @@
         case Constant::kInt64:
           UNREACHABLE();
           break;
+        case Constant::kFloat32:
+          __ Move(dst,
+                  isolate()->factory()->NewNumber(src.ToFloat32(), TENURED));
+          break;
         case Constant::kFloat64:
           __ Move(dst,
                   isolate()->factory()->NewNumber(src.ToFloat64(), TENURED));
@@ -741,16 +966,29 @@
         case Constant::kHeapObject:
           __ Move(dst, src.ToHeapObject());
           break;
+        case Constant::kRpoNumber:
+          UNREACHABLE();  // TODO(dcarney): loading RPO constants on arm.
+          break;
       }
       if (destination->IsStackSlot()) __ str(dst, g.ToMemOperand(destination));
-    } else if (destination->IsDoubleRegister()) {
-      DwVfpRegister result = g.ToDoubleRegister(destination);
-      __ vmov(result, g.ToDouble(source));
+    } else if (src.type() == Constant::kFloat32) {
+      if (destination->IsDoubleStackSlot()) {
+        MemOperand dst = g.ToMemOperand(destination);
+        __ mov(ip, Operand(bit_cast<int32_t>(src.ToFloat32())));
+        __ str(ip, dst);
+      } else {
+        SwVfpRegister dst = g.ToFloat32Register(destination);
+        __ vmov(dst, src.ToFloat32());
+      }
     } else {
-      DCHECK(destination->IsDoubleStackSlot());
-      DwVfpRegister temp = kScratchDoubleReg;
-      __ vmov(temp, g.ToDouble(source));
-      __ vstr(temp, g.ToMemOperand(destination));
+      DCHECK_EQ(Constant::kFloat64, src.type());
+      DwVfpRegister dst = destination->IsDoubleRegister()
+                              ? g.ToFloat64Register(destination)
+                              : kScratchDoubleReg;
+      __ vmov(dst, src.ToFloat64(), kScratchReg);
+      if (destination->IsDoubleStackSlot()) {
+        __ vstr(dst, g.ToMemOperand(destination));
+      }
     }
   } else if (source->IsDoubleRegister()) {
     DwVfpRegister src = g.ToDoubleRegister(source);
@@ -851,7 +1089,7 @@
 
 void CodeGenerator::EnsureSpaceForLazyDeopt() {
   int space_needed = Deoptimizer::patch_size();
-  if (!linkage()->info()->IsStub()) {
+  if (!info()->IsStub()) {
     // Ensure that we have enough space after the previous lazy-bailout
     // instruction for patching the code here.
     int current_pc = masm()->pc_offset();
diff --git a/src/compiler/arm/instruction-codes-arm.h b/src/compiler/arm/instruction-codes-arm.h
index 7849ca9..ecd0b2d 100644
--- a/src/compiler/arm/instruction-codes-arm.h
+++ b/src/compiler/arm/instruction-codes-arm.h
@@ -26,12 +26,23 @@
   V(ArmMul)                        \
   V(ArmMla)                        \
   V(ArmMls)                        \
+  V(ArmSmmul)                      \
+  V(ArmSmmla)                      \
+  V(ArmUmull)                      \
   V(ArmSdiv)                       \
   V(ArmUdiv)                       \
   V(ArmMov)                        \
   V(ArmMvn)                        \
   V(ArmBfc)                        \
   V(ArmUbfx)                       \
+  V(ArmSxtb)                       \
+  V(ArmSxth)                       \
+  V(ArmSxtab)                      \
+  V(ArmSxtah)                      \
+  V(ArmUxtb)                       \
+  V(ArmUxth)                       \
+  V(ArmUxtab)                      \
+  V(ArmUxtah)                      \
   V(ArmVcmpF64)                    \
   V(ArmVaddF64)                    \
   V(ArmVsubF64)                    \
@@ -42,14 +53,20 @@
   V(ArmVmodF64)                    \
   V(ArmVnegF64)                    \
   V(ArmVsqrtF64)                   \
+  V(ArmVfloorF64)                  \
+  V(ArmVceilF64)                   \
+  V(ArmVroundTruncateF64)          \
+  V(ArmVroundTiesAwayF64)          \
+  V(ArmVcvtF32F64)                 \
+  V(ArmVcvtF64F32)                 \
   V(ArmVcvtF64S32)                 \
   V(ArmVcvtF64U32)                 \
   V(ArmVcvtS32F64)                 \
   V(ArmVcvtU32F64)                 \
-  V(ArmVldr32)                     \
-  V(ArmVstr32)                     \
-  V(ArmVldr64)                     \
-  V(ArmVstr64)                     \
+  V(ArmVldrF32)                    \
+  V(ArmVstrF32)                    \
+  V(ArmVldrF64)                    \
+  V(ArmVstrF64)                    \
   V(ArmLdrb)                       \
   V(ArmLdrsb)                      \
   V(ArmStrb)                       \
diff --git a/src/compiler/arm/instruction-selector-arm-unittest.cc b/src/compiler/arm/instruction-selector-arm-unittest.cc
deleted file mode 100644
index 208d2e9..0000000
--- a/src/compiler/arm/instruction-selector-arm-unittest.cc
+++ /dev/null
@@ -1,1900 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/instruction-selector-unittest.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-namespace {
-
-typedef RawMachineAssembler::Label MLabel;
-typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);
-
-
-// Data processing instructions.
-struct DPI {
-  Constructor constructor;
-  const char* constructor_name;
-  ArchOpcode arch_opcode;
-  ArchOpcode reverse_arch_opcode;
-  ArchOpcode test_arch_opcode;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const DPI& dpi) {
-  return os << dpi.constructor_name;
-}
-
-
-static const DPI kDPIs[] = {
-    {&RawMachineAssembler::Word32And, "Word32And", kArmAnd, kArmAnd, kArmTst},
-    {&RawMachineAssembler::Word32Or, "Word32Or", kArmOrr, kArmOrr, kArmOrr},
-    {&RawMachineAssembler::Word32Xor, "Word32Xor", kArmEor, kArmEor, kArmTeq},
-    {&RawMachineAssembler::Int32Add, "Int32Add", kArmAdd, kArmAdd, kArmCmn},
-    {&RawMachineAssembler::Int32Sub, "Int32Sub", kArmSub, kArmRsb, kArmCmp}};
-
-
-// Data processing instructions with overflow.
-struct ODPI {
-  Constructor constructor;
-  const char* constructor_name;
-  ArchOpcode arch_opcode;
-  ArchOpcode reverse_arch_opcode;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const ODPI& odpi) {
-  return os << odpi.constructor_name;
-}
-
-
-static const ODPI kODPIs[] = {{&RawMachineAssembler::Int32AddWithOverflow,
-                               "Int32AddWithOverflow", kArmAdd, kArmAdd},
-                              {&RawMachineAssembler::Int32SubWithOverflow,
-                               "Int32SubWithOverflow", kArmSub, kArmRsb}};
-
-
-// Shifts.
-struct Shift {
-  Constructor constructor;
-  const char* constructor_name;
-  int32_t i_low;          // lowest possible immediate
-  int32_t i_high;         // highest possible immediate
-  AddressingMode i_mode;  // Operand2_R_<shift>_I
-  AddressingMode r_mode;  // Operand2_R_<shift>_R
-};
-
-
-std::ostream& operator<<(std::ostream& os, const Shift& shift) {
-  return os << shift.constructor_name;
-}
-
-
-static const Shift kShifts[] = {
-    {&RawMachineAssembler::Word32Sar, "Word32Sar", 1, 32,
-     kMode_Operand2_R_ASR_I, kMode_Operand2_R_ASR_R},
-    {&RawMachineAssembler::Word32Shl, "Word32Shl", 0, 31,
-     kMode_Operand2_R_LSL_I, kMode_Operand2_R_LSL_R},
-    {&RawMachineAssembler::Word32Shr, "Word32Shr", 1, 32,
-     kMode_Operand2_R_LSR_I, kMode_Operand2_R_LSR_R},
-    {&RawMachineAssembler::Word32Ror, "Word32Ror", 1, 31,
-     kMode_Operand2_R_ROR_I, kMode_Operand2_R_ROR_R}};
-
-
-// Immediates (random subset).
-static const int32_t kImmediates[] = {
-    -2147483617, -2147483606, -2113929216, -2080374784, -1996488704,
-    -1879048192, -1459617792, -1358954496, -1342177265, -1275068414,
-    -1073741818, -1073741777, -855638016,  -805306368,  -402653184,
-    -268435444,  -16777216,   0,           35,          61,
-    105,         116,         171,         245,         255,
-    692,         1216,        1248,        1520,        1600,
-    1888,        3744,        4080,        5888,        8384,
-    9344,        9472,        9792,        13312,       15040,
-    15360,       20736,       22272,       23296,       32000,
-    33536,       37120,       45824,       47872,       56320,
-    59392,       65280,       72704,       101376,      147456,
-    161792,      164864,      167936,      173056,      195584,
-    209920,      212992,      356352,      655360,      704512,
-    716800,      851968,      901120,      1044480,     1523712,
-    2572288,     3211264,     3588096,     3833856,     3866624,
-    4325376,     5177344,     6488064,     7012352,     7471104,
-    14090240,    16711680,    19398656,    22282240,    28573696,
-    30408704,    30670848,    43253760,    54525952,    55312384,
-    56623104,    68157440,    115343360,   131072000,   187695104,
-    188743680,   195035136,   197132288,   203423744,   218103808,
-    267386880,   268435470,   285212672,   402653185,   415236096,
-    595591168,   603979776,   603979778,   629145600,   1073741835,
-    1073741855,  1073741861,  1073741884,  1157627904,  1476395008,
-    1476395010,  1610612741,  2030043136,  2080374785,  2097152000};
-
-}  // namespace
-
-
-// -----------------------------------------------------------------------------
-// Data processing instructions.
-
-
-typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorDPITest;
-
-
-TEST_P(InstructionSelectorDPITest, Parameters) {
-  const DPI dpi = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorDPITest, Immediate) {
-  const DPI dpi = GetParam();
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-TEST_P(InstructionSelectorDPITest, ShiftByParameter) {
-  const DPI dpi = GetParam();
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    m.Return((m.*dpi.constructor)(
-        m.Parameter(0),
-        (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-    EXPECT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    m.Return((m.*dpi.constructor)(
-        (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
-        m.Parameter(2)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-    EXPECT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-TEST_P(InstructionSelectorDPITest, ShiftByImmediate) {
-  const DPI dpi = GetParam();
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-      m.Return((m.*dpi.constructor)(
-          m.Parameter(0),
-          (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
-      Stream s = m.Build();
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-      EXPECT_EQ(1U, s[0]->OutputCount());
-    }
-  }
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-      m.Return((m.*dpi.constructor)(
-          (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
-          m.Parameter(1)));
-      Stream s = m.Build();
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
-      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-      EXPECT_EQ(1U, s[0]->OutputCount());
-    }
-  }
-}
-
-
-TEST_P(InstructionSelectorDPITest, BranchWithParameters) {
-  const DPI dpi = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  MLabel a, b;
-  m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)), &a, &b);
-  m.Bind(&a);
-  m.Return(m.Int32Constant(1));
-  m.Bind(&b);
-  m.Return(m.Int32Constant(0));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-  EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-}
-
-
-TEST_P(InstructionSelectorDPITest, BranchWithImmediate) {
-  const DPI dpi = GetParam();
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)), &a,
-             &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-  }
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)), &a,
-             &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorDPITest, BranchWithShiftByParameter) {
-  const DPI dpi = GetParam();
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch((m.*dpi.constructor)(
-                 m.Parameter(0),
-                 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))),
-             &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-  }
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch((m.*dpi.constructor)(
-                 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
-                 m.Parameter(2)),
-             &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorDPITest, BranchWithShiftByImmediate) {
-  const DPI dpi = GetParam();
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-      MLabel a, b;
-      m.Branch((m.*dpi.constructor)(m.Parameter(0),
-                                    (m.*shift.constructor)(
-                                        m.Parameter(1), m.Int32Constant(imm))),
-               &a, &b);
-      m.Bind(&a);
-      m.Return(m.Int32Constant(1));
-      m.Bind(&b);
-      m.Return(m.Int32Constant(0));
-      Stream s = m.Build();
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-      ASSERT_EQ(5U, s[0]->InputCount());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-      EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-      EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-    }
-  }
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-      MLabel a, b;
-      m.Branch((m.*dpi.constructor)(
-                   (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
-                   m.Parameter(1)),
-               &a, &b);
-      m.Bind(&a);
-      m.Return(m.Int32Constant(1));
-      m.Bind(&b);
-      m.Return(m.Int32Constant(0));
-      Stream s = m.Build();
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-      ASSERT_EQ(5U, s[0]->InputCount());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-      EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-      EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-    }
-  }
-}
-
-
-TEST_P(InstructionSelectorDPITest, BranchIfZeroWithParameters) {
-  const DPI dpi = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  MLabel a, b;
-  m.Branch(m.Word32Equal((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
-                         m.Int32Constant(0)),
-           &a, &b);
-  m.Bind(&a);
-  m.Return(m.Int32Constant(1));
-  m.Bind(&b);
-  m.Return(m.Int32Constant(0));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-  EXPECT_EQ(kEqual, s[0]->flags_condition());
-}
-
-
-TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithParameters) {
-  const DPI dpi = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  MLabel a, b;
-  m.Branch(
-      m.Word32NotEqual((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
-                       m.Int32Constant(0)),
-      &a, &b);
-  m.Bind(&a);
-  m.Return(m.Int32Constant(1));
-  m.Bind(&b);
-  m.Return(m.Int32Constant(0));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-  EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-}
-
-
-TEST_P(InstructionSelectorDPITest, BranchIfZeroWithImmediate) {
-  const DPI dpi = GetParam();
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch(m.Word32Equal(
-                 (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
-                 m.Int32Constant(0)),
-             &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch(m.Word32Equal(
-                 (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
-                 m.Int32Constant(0)),
-             &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithImmediate) {
-  const DPI dpi = GetParam();
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch(m.Word32NotEqual(
-                 (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
-                 m.Int32Constant(0)),
-             &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-  }
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch(m.Word32NotEqual(
-                 (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
-                 m.Int32Constant(0)),
-             &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-  }
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorDPITest,
-                        ::testing::ValuesIn(kDPIs));
-
-
-// -----------------------------------------------------------------------------
-// Data processing instructions with overflow.
-
-
-typedef InstructionSelectorTestWithParam<ODPI> InstructionSelectorODPITest;
-
-
-TEST_P(InstructionSelectorODPITest, OvfWithParameters) {
-  const ODPI odpi = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(
-      m.Projection(1, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_LE(1U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-  EXPECT_EQ(kOverflow, s[0]->flags_condition());
-}
-
-
-TEST_P(InstructionSelectorODPITest, OvfWithImmediate) {
-  const ODPI odpi = GetParam();
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Projection(
-        1, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_LE(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Projection(
-        1, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_LE(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorODPITest, OvfWithShiftByParameter) {
-  const ODPI odpi = GetParam();
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(m.Projection(
-        1, (m.*odpi.constructor)(
-               m.Parameter(0),
-               (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-    EXPECT_EQ(3U, s[0]->InputCount());
-    EXPECT_LE(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(m.Projection(
-        1, (m.*odpi.constructor)(
-               (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
-               m.Parameter(0))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-    EXPECT_EQ(3U, s[0]->InputCount());
-    EXPECT_LE(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorODPITest, OvfWithShiftByImmediate) {
-  const ODPI odpi = GetParam();
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-      m.Return(m.Projection(
-          1, (m.*odpi.constructor)(m.Parameter(0),
-                                   (m.*shift.constructor)(
-                                       m.Parameter(1), m.Int32Constant(imm)))));
-      Stream s = m.Build();
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-      EXPECT_LE(1U, s[0]->OutputCount());
-      EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-      EXPECT_EQ(kOverflow, s[0]->flags_condition());
-    }
-  }
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-      m.Return(m.Projection(
-          1, (m.*odpi.constructor)(
-                 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
-                 m.Parameter(0))));
-      Stream s = m.Build();
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
-      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-      EXPECT_LE(1U, s[0]->OutputCount());
-      EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-      EXPECT_EQ(kOverflow, s[0]->flags_condition());
-    }
-  }
-}
-
-
-TEST_P(InstructionSelectorODPITest, ValWithParameters) {
-  const ODPI odpi = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(
-      m.Projection(0, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_LE(1U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
-}
-
-
-TEST_P(InstructionSelectorODPITest, ValWithImmediate) {
-  const ODPI odpi = GetParam();
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Projection(
-        0, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_LE(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
-  }
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Projection(
-        0, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_LE(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
-  }
-}
-
-
-TEST_P(InstructionSelectorODPITest, ValWithShiftByParameter) {
-  const ODPI odpi = GetParam();
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(m.Projection(
-        0, (m.*odpi.constructor)(
-               m.Parameter(0),
-               (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-    EXPECT_EQ(3U, s[0]->InputCount());
-    EXPECT_LE(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
-  }
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(m.Projection(
-        0, (m.*odpi.constructor)(
-               (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
-               m.Parameter(0))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-    EXPECT_EQ(3U, s[0]->InputCount());
-    EXPECT_LE(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
-  }
-}
-
-
-TEST_P(InstructionSelectorODPITest, ValWithShiftByImmediate) {
-  const ODPI odpi = GetParam();
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-      m.Return(m.Projection(
-          0, (m.*odpi.constructor)(m.Parameter(0),
-                                   (m.*shift.constructor)(
-                                       m.Parameter(1), m.Int32Constant(imm)))));
-      Stream s = m.Build();
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-      EXPECT_LE(1U, s[0]->OutputCount());
-      EXPECT_EQ(kFlags_none, s[0]->flags_mode());
-    }
-  }
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-      m.Return(m.Projection(
-          0, (m.*odpi.constructor)(
-                 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
-                 m.Parameter(0))));
-      Stream s = m.Build();
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
-      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-      EXPECT_LE(1U, s[0]->OutputCount());
-      EXPECT_EQ(kFlags_none, s[0]->flags_mode());
-    }
-  }
-}
-
-
-TEST_P(InstructionSelectorODPITest, BothWithParameters) {
-  const ODPI odpi = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
-  m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
-  Stream s = m.Build();
-  ASSERT_LE(1U, s.size());
-  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(2U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-  EXPECT_EQ(kOverflow, s[0]->flags_condition());
-}
-
-
-TEST_P(InstructionSelectorODPITest, BothWithImmediate) {
-  const ODPI odpi = GetParam();
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
-    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
-    Stream s = m.Build();
-    ASSERT_LE(1U, s.size());
-    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(2U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
-    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
-    Stream s = m.Build();
-    ASSERT_LE(1U, s.size());
-    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(2U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorODPITest, BothWithShiftByParameter) {
-  const ODPI odpi = GetParam();
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    Node* n = (m.*odpi.constructor)(
-        m.Parameter(0), (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)));
-    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
-    Stream s = m.Build();
-    ASSERT_LE(1U, s.size());
-    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-    EXPECT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(2U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    Node* n = (m.*odpi.constructor)(
-        (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)), m.Parameter(2));
-    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
-    Stream s = m.Build();
-    ASSERT_LE(1U, s.size());
-    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-    EXPECT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(2U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorODPITest, BothWithShiftByImmediate) {
-  const ODPI odpi = GetParam();
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-      Node* n = (m.*odpi.constructor)(
-          m.Parameter(0),
-          (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)));
-      m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
-      Stream s = m.Build();
-      ASSERT_LE(1U, s.size());
-      EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-      EXPECT_EQ(2U, s[0]->OutputCount());
-      EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-      EXPECT_EQ(kOverflow, s[0]->flags_condition());
-    }
-  }
-  TRACED_FOREACH(Shift, shift, kShifts) {
-    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-      Node* n = (m.*odpi.constructor)(
-          (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
-          m.Parameter(1));
-      m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
-      Stream s = m.Build();
-      ASSERT_LE(1U, s.size());
-      EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
-      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-      EXPECT_EQ(2U, s[0]->OutputCount());
-      EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-      EXPECT_EQ(kOverflow, s[0]->flags_condition());
-    }
-  }
-}
-
-
-TEST_P(InstructionSelectorODPITest, BranchWithParameters) {
-  const ODPI odpi = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  MLabel a, b;
-  Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
-  m.Branch(m.Projection(1, n), &a, &b);
-  m.Bind(&a);
-  m.Return(m.Int32Constant(0));
-  m.Bind(&b);
-  m.Return(m.Projection(0, n));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-  EXPECT_EQ(4U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-  EXPECT_EQ(kOverflow, s[0]->flags_condition());
-}
-
-
-TEST_P(InstructionSelectorODPITest, BranchWithImmediate) {
-  const ODPI odpi = GetParam();
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
-    m.Branch(m.Projection(1, n), &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(0));
-    m.Bind(&b);
-    m.Return(m.Projection(0, n));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    ASSERT_EQ(4U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
-    m.Branch(m.Projection(1, n), &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(0));
-    m.Bind(&b);
-    m.Return(m.Projection(0, n));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    ASSERT_EQ(4U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorODPITest, BranchIfZeroWithParameters) {
-  const ODPI odpi = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  MLabel a, b;
-  Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
-  m.Branch(m.Word32Equal(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
-  m.Bind(&a);
-  m.Return(m.Projection(0, n));
-  m.Bind(&b);
-  m.Return(m.Int32Constant(0));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-  EXPECT_EQ(4U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-  EXPECT_EQ(kNotOverflow, s[0]->flags_condition());
-}
-
-
-TEST_P(InstructionSelectorODPITest, BranchIfNotZeroWithParameters) {
-  const ODPI odpi = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  MLabel a, b;
-  Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
-  m.Branch(m.Word32NotEqual(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
-  m.Bind(&a);
-  m.Return(m.Projection(0, n));
-  m.Bind(&b);
-  m.Return(m.Int32Constant(0));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-  EXPECT_EQ(4U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-  EXPECT_EQ(kOverflow, s[0]->flags_condition());
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorODPITest,
-                        ::testing::ValuesIn(kODPIs));
-
-
-// -----------------------------------------------------------------------------
-// Shifts.
-
-
-typedef InstructionSelectorTestWithParam<Shift> InstructionSelectorShiftTest;
-
-
-TEST_P(InstructionSelectorShiftTest, Parameters) {
-  const Shift shift = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return((m.*shift.constructor)(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArmMov, s[0]->arch_opcode());
-  EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorShiftTest, Immediate) {
-  const Shift shift = GetParam();
-  TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return((m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmMov, s[0]->arch_opcode());
-    EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameter) {
-  const Shift shift = GetParam();
-  {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(
-        m.Word32Equal(m.Parameter(0),
-                      (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
-    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-    EXPECT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-  {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(
-        m.Word32Equal((m.*shift.constructor)(m.Parameter(1), m.Parameter(2)),
-                      m.Parameter(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
-    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-    EXPECT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameterAndImmediate) {
-  const Shift shift = GetParam();
-  TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(m.Word32Equal(
-        (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
-        m.Parameter(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
-    EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-  TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(m.Word32Equal(
-        m.Parameter(0),
-        (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
-    EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorShiftTest, Word32EqualToZeroWithParameters) {
-  const Shift shift = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(
-      m.Word32Equal(m.Int32Constant(0),
-                    (m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArmMov, s[0]->arch_opcode());
-  EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(2U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-  EXPECT_EQ(kEqual, s[0]->flags_condition());
-}
-
-
-TEST_P(InstructionSelectorShiftTest, Word32EqualToZeroWithImmediate) {
-  const Shift shift = GetParam();
-  TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(m.Word32Equal(
-        m.Int32Constant(0),
-        (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmMov, s[0]->arch_opcode());
-    EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(2U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorShiftTest, Word32NotWithParameters) {
-  const Shift shift = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Word32Not((m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
-  EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorShiftTest, Word32NotWithImmediate) {
-  const Shift shift = GetParam();
-  TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Word32Not(
-        (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
-    EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithParameters) {
-  const Shift shift = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Word32And(m.Parameter(0), m.Word32Not((m.*shift.constructor)(
-                                           m.Parameter(1), m.Parameter(2)))));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArmBic, s[0]->arch_opcode());
-  EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
-  EXPECT_EQ(3U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithImmediate) {
-  const Shift shift = GetParam();
-  TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(m.Word32And(m.Parameter(0),
-                         m.Word32Not((m.*shift.constructor)(
-                             m.Parameter(1), m.Int32Constant(imm)))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmBic, s[0]->arch_opcode());
-    EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
-                        ::testing::ValuesIn(kShifts));
-
-
-// -----------------------------------------------------------------------------
-// Memory access instructions.
-
-
-namespace {
-
-struct MemoryAccess {
-  MachineType type;
-  ArchOpcode ldr_opcode;
-  ArchOpcode str_opcode;
-  bool (InstructionSelectorTest::Stream::*val_predicate)(
-      const InstructionOperand*) const;
-  const int32_t immediates[40];
-};
-
-
-std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
-  OStringStream ost;
-  ost << memacc.type;
-  return os << ost.c_str();
-}
-
-
-static const MemoryAccess kMemoryAccesses[] = {
-    {kMachInt8,
-     kArmLdrsb,
-     kArmStrb,
-     &InstructionSelectorTest::Stream::IsInteger,
-     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
-      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
-      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
-    {kMachUint8,
-     kArmLdrb,
-     kArmStrb,
-     &InstructionSelectorTest::Stream::IsInteger,
-     {-4095, -3914, -3536, -3234, -3185, -3169, -1073, -990, -859, -720, -434,
-      -127, -124, -122, -105, -91, -86, -64, -55, -53, -30, -10, -3, 0, 20, 28,
-      39, 58, 64, 73, 75, 100, 108, 121, 686, 963, 1363, 2759, 3449, 4095}},
-    {kMachInt16,
-     kArmLdrsh,
-     kArmStrh,
-     &InstructionSelectorTest::Stream::IsInteger,
-     {-255, -251, -232, -220, -144, -138, -130, -126, -116, -115, -102, -101,
-      -98, -69, -59, -56, -39, -35, -23, -19, -7, 0, 22, 26, 37, 68, 83, 87, 98,
-      102, 108, 111, 117, 171, 195, 203, 204, 245, 246, 255}},
-    {kMachUint16,
-     kArmLdrh,
-     kArmStrh,
-     &InstructionSelectorTest::Stream::IsInteger,
-     {-255, -230, -201, -172, -125, -119, -118, -105, -98, -79, -54, -42, -41,
-      -32, -12, -11, -5, -4, 0, 5, 9, 25, 28, 51, 58, 60, 89, 104, 108, 109,
-      114, 116, 120, 138, 150, 161, 166, 172, 228, 255}},
-    {kMachInt32,
-     kArmLdr,
-     kArmStr,
-     &InstructionSelectorTest::Stream::IsInteger,
-     {-4095, -1898, -1685, -1562, -1408, -1313, -344, -128, -116, -100, -92,
-      -80, -72, -71, -56, -25, -21, -11, -9, 0, 3, 5, 27, 28, 42, 52, 63, 88,
-      93, 97, 125, 846, 1037, 2102, 2403, 2597, 2632, 2997, 3935, 4095}},
-    {kMachFloat32,
-     kArmVldr32,
-     kArmVstr32,
-     &InstructionSelectorTest::Stream::IsDouble,
-     {-1020, -928, -896, -772, -728, -680, -660, -488, -372, -112, -100, -92,
-      -84, -80, -72, -64, -60, -56, -52, -48, -36, -32, -20, -8, -4, 0, 8, 20,
-      24, 40, 64, 112, 204, 388, 516, 852, 856, 976, 988, 1020}},
-    {kMachFloat64,
-     kArmVldr64,
-     kArmVstr64,
-     &InstructionSelectorTest::Stream::IsDouble,
-     {-1020, -948, -796, -696, -612, -364, -320, -308, -128, -112, -108, -104,
-      -96, -84, -80, -56, -48, -40, -20, 0, 24, 28, 36, 48, 64, 84, 96, 100,
-      108, 116, 120, 140, 156, 408, 432, 444, 772, 832, 940, 1020}}};
-
-}  // namespace
-
-
-typedef InstructionSelectorTestWithParam<MemoryAccess>
-    InstructionSelectorMemoryAccessTest;
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
-  const MemoryAccess memacc = GetParam();
-  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
-  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
-}
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
-  const MemoryAccess memacc = GetParam();
-  TRACED_FOREACH(int32_t, index, memacc.immediates) {
-    StreamBuilder m(this, memacc.type, kMachPtr);
-    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
-    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
-    ASSERT_EQ(1U, s[0]->OutputCount());
-    EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
-  }
-}
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
-  const MemoryAccess memacc = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
-  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
-  m.Return(m.Int32Constant(0));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
-  EXPECT_EQ(3U, s[0]->InputCount());
-  EXPECT_EQ(0U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
-  const MemoryAccess memacc = GetParam();
-  TRACED_FOREACH(int32_t, index, memacc.immediates) {
-    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
-    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
-            m.Parameter(1));
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
-    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(0U, s[0]->OutputCount());
-  }
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
-                        InstructionSelectorMemoryAccessTest,
-                        ::testing::ValuesIn(kMemoryAccesses));
-
-
-// -----------------------------------------------------------------------------
-// Miscellaneous.
-
-
-TEST_F(InstructionSelectorTest, Int32AddWithInt32Mul) {
-  {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(
-        m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmMla, s[0]->arch_opcode());
-    EXPECT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-  {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(
-        m.Int32Add(m.Int32Mul(m.Parameter(1), m.Parameter(2)), m.Parameter(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmMla, s[0]->arch_opcode());
-    EXPECT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, Int32DivWithParameters) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(4U, s.size());
-  EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
-  ASSERT_EQ(1U, s[1]->OutputCount());
-  EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
-  ASSERT_EQ(2U, s[2]->InputCount());
-  ASSERT_EQ(1U, s[2]->OutputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
-  EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
-  ASSERT_EQ(1U, s[3]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
-}
-
-
-TEST_F(InstructionSelectorTest, Int32DivWithParametersForSUDIV) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build(SUDIV);
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
-}
-
-
-TEST_F(InstructionSelectorTest, Int32ModWithParameters) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(6U, s.size());
-  EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
-  ASSERT_EQ(1U, s[1]->OutputCount());
-  EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
-  ASSERT_EQ(2U, s[2]->InputCount());
-  ASSERT_EQ(1U, s[2]->OutputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
-  EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
-  ASSERT_EQ(1U, s[3]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
-  EXPECT_EQ(kArmMul, s[4]->arch_opcode());
-  ASSERT_EQ(1U, s[4]->OutputCount());
-  ASSERT_EQ(2U, s[4]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
-  EXPECT_EQ(kArmSub, s[5]->arch_opcode());
-  ASSERT_EQ(1U, s[5]->OutputCount());
-  ASSERT_EQ(2U, s[5]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
-}
-
-
-TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIV) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build(SUDIV);
-  ASSERT_EQ(3U, s.size());
-  EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  ASSERT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(kArmMul, s[1]->arch_opcode());
-  ASSERT_EQ(1U, s[1]->OutputCount());
-  ASSERT_EQ(2U, s[1]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
-  EXPECT_EQ(kArmSub, s[2]->arch_opcode());
-  ASSERT_EQ(1U, s[2]->OutputCount());
-  ASSERT_EQ(2U, s[2]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
-}
-
-
-TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIVAndMLS) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build(MLS, SUDIV);
-  ASSERT_EQ(2U, s.size());
-  EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  ASSERT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(kArmMls, s[1]->arch_opcode());
-  ASSERT_EQ(1U, s[1]->OutputCount());
-  ASSERT_EQ(3U, s[1]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
-  EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
-}
-
-
-TEST_F(InstructionSelectorTest, Int32MulWithParameters) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32Mul(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArmMul, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_F(InstructionSelectorTest, Int32MulWithImmediate) {
-  // x * (2^k + 1) -> x + (x >> k)
-  TRACED_FORRANGE(int32_t, k, 1, 30) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
-    EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-  // x * (2^k - 1) -> -x + (x >> k)
-  TRACED_FORRANGE(int32_t, k, 3, 30) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) - 1)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
-    EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-  // (2^k + 1) * x -> x + (x >> k)
-  TRACED_FORRANGE(int32_t, k, 1, 30) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
-    EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-  // x * (2^k - 1) -> -x + (x >> k)
-  TRACED_FORRANGE(int32_t, k, 3, 30) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Int32Mul(m.Int32Constant((1 << k) - 1), m.Parameter(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
-    EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, Int32SubWithInt32Mul) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(
-      m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
-  Stream s = m.Build();
-  ASSERT_EQ(2U, s.size());
-  EXPECT_EQ(kArmMul, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kArmSub, s[1]->arch_opcode());
-  ASSERT_EQ(2U, s[1]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(1)));
-}
-
-
-TEST_F(InstructionSelectorTest, Int32SubWithInt32MulForMLS) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(
-      m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
-  Stream s = m.Build(MLS);
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArmMls, s[0]->arch_opcode());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(3U, s[0]->InputCount());
-}
-
-
-TEST_F(InstructionSelectorTest, Int32UDivWithParameters) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32UDiv(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(4U, s.size());
-  EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
-  ASSERT_EQ(1U, s[1]->OutputCount());
-  EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
-  ASSERT_EQ(2U, s[2]->InputCount());
-  ASSERT_EQ(1U, s[2]->OutputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
-  EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
-  ASSERT_EQ(1U, s[3]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
-}
-
-
-TEST_F(InstructionSelectorTest, Int32UDivWithParametersForSUDIV) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32UDiv(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build(SUDIV);
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
-}
-
-
-TEST_F(InstructionSelectorTest, Int32UModWithParameters) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(6U, s.size());
-  EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
-  ASSERT_EQ(1U, s[1]->OutputCount());
-  EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
-  ASSERT_EQ(2U, s[2]->InputCount());
-  ASSERT_EQ(1U, s[2]->OutputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
-  EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
-  ASSERT_EQ(1U, s[3]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
-  EXPECT_EQ(kArmMul, s[4]->arch_opcode());
-  ASSERT_EQ(1U, s[4]->OutputCount());
-  ASSERT_EQ(2U, s[4]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
-  EXPECT_EQ(kArmSub, s[5]->arch_opcode());
-  ASSERT_EQ(1U, s[5]->OutputCount());
-  ASSERT_EQ(2U, s[5]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
-}
-
-
-TEST_F(InstructionSelectorTest, Int32UModWithParametersForSUDIV) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build(SUDIV);
-  ASSERT_EQ(3U, s.size());
-  EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  ASSERT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(kArmMul, s[1]->arch_opcode());
-  ASSERT_EQ(1U, s[1]->OutputCount());
-  ASSERT_EQ(2U, s[1]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
-  EXPECT_EQ(kArmSub, s[2]->arch_opcode());
-  ASSERT_EQ(1U, s[2]->OutputCount());
-  ASSERT_EQ(2U, s[2]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
-}
-
-
-TEST_F(InstructionSelectorTest, Int32UModWithParametersForSUDIVAndMLS) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32UMod(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build(MLS, SUDIV);
-  ASSERT_EQ(2U, s.size());
-  EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  ASSERT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(kArmMls, s[1]->arch_opcode());
-  ASSERT_EQ(1U, s[1]->OutputCount());
-  ASSERT_EQ(3U, s[1]->InputCount());
-  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
-  EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
-  EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
-}
-
-
-TEST_F(InstructionSelectorTest, Word32AndWithUbfxImmediateForARMv7) {
-  TRACED_FORRANGE(int32_t, width, 1, 32) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Word32And(m.Parameter(0),
-                         m.Int32Constant(0xffffffffu >> (32 - width))));
-    Stream s = m.Build(ARMv7);
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
-  }
-  TRACED_FORRANGE(int32_t, width, 1, 32) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
-                         m.Parameter(0)));
-    Stream s = m.Build(ARMv7);
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, Word32AndWithBfcImmediateForARMv7) {
-  TRACED_FORRANGE(int32_t, lsb, 0, 31) {
-    TRACED_FORRANGE(int32_t, width, 1, (32 - lsb) - 1) {
-      StreamBuilder m(this, kMachInt32, kMachInt32);
-      m.Return(m.Word32And(
-          m.Parameter(0),
-          m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb))));
-      Stream s = m.Build(ARMv7);
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
-      ASSERT_EQ(1U, s[0]->OutputCount());
-      EXPECT_TRUE(
-          UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
-      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
-    }
-  }
-  TRACED_FORRANGE(int32_t, lsb, 0, 31) {
-    TRACED_FORRANGE(int32_t, width, 1, (32 - lsb) - 1) {
-      StreamBuilder m(this, kMachInt32, kMachInt32);
-      m.Return(
-          m.Word32And(m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb)),
-                      m.Parameter(0)));
-      Stream s = m.Build(ARMv7);
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
-      ASSERT_EQ(1U, s[0]->OutputCount());
-      EXPECT_TRUE(
-          UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
-      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
-    }
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediateForARMv7) {
-  TRACED_FORRANGE(int32_t, lsb, 0, 31) {
-    TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
-      uint32_t max = 1 << lsb;
-      if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
-      uint32_t jnk = rng()->NextInt(max);
-      uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
-      StreamBuilder m(this, kMachInt32, kMachInt32);
-      m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
-                           m.Int32Constant(lsb)));
-      Stream s = m.Build(ARMv7);
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
-      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
-    }
-  }
-  TRACED_FORRANGE(int32_t, lsb, 0, 31) {
-    TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
-      uint32_t max = 1 << lsb;
-      if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
-      uint32_t jnk = rng()->NextInt(max);
-      uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
-      StreamBuilder m(this, kMachInt32, kMachInt32);
-      m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
-                           m.Int32Constant(lsb)));
-      Stream s = m.Build(ARMv7);
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
-      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
-    }
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, Word32AndWithWord32Not) {
-  {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(m.Word32And(m.Parameter(0), m.Word32Not(m.Parameter(1))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmBic, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-    EXPECT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-  {
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(m.Word32And(m.Word32Not(m.Parameter(0)), m.Parameter(1)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmBic, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-    EXPECT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, Word32EqualWithParameters) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Word32Equal(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-  EXPECT_EQ(kEqual, s[0]->flags_condition());
-}
-
-
-TEST_F(InstructionSelectorTest, Word32EqualWithImmediate) {
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    if (imm == 0) continue;
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(imm)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    if (imm == 0) continue;
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Word32Equal(m.Int32Constant(imm), m.Parameter(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
-  {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmTst, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-  {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArmTst, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, Word32NotWithParameter) {
-  StreamBuilder m(this, kMachInt32, kMachInt32);
-  m.Return(m.Word32Not(m.Parameter(0)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
-  EXPECT_EQ(1U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrWithImmediateForARMv7) {
-  TRACED_FORRANGE(int32_t, lsb, 0, 31) {
-    TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
-      StreamBuilder m(this, kMachInt32, kMachInt32);
-      m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)),
-                           m.Int32Constant(0xffffffffu >> (32 - width))));
-      Stream s = m.Build(ARMv7);
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
-      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
-    }
-  }
-  TRACED_FORRANGE(int32_t, lsb, 0, 31) {
-    TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
-      StreamBuilder m(this, kMachInt32, kMachInt32);
-      m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
-                           m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb))));
-      Stream s = m.Build(ARMv7);
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
-      ASSERT_EQ(3U, s[0]->InputCount());
-      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
-      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
-    }
-  }
-}
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc
index ae93b27..ef9e89e 100644
--- a/src/compiler/arm/instruction-selector-arm.cc
+++ b/src/compiler/arm/instruction-selector-arm.cc
@@ -11,16 +11,17 @@
 namespace compiler {
 
 // Adds Arm-specific methods for generating InstructionOperands.
-class ArmOperandGenerator FINAL : public OperandGenerator {
+class ArmOperandGenerator : public OperandGenerator {
  public:
   explicit ArmOperandGenerator(InstructionSelector* selector)
       : OperandGenerator(selector) {}
 
-  InstructionOperand* UseOperand(Node* node, InstructionCode opcode) {
-    if (CanBeImmediate(node, opcode)) {
-      return UseImmediate(node);
-    }
-    return UseRegister(node);
+  bool CanBeImmediate(int32_t value) const {
+    return Assembler::ImmediateFitsAddrMode1Instruction(value);
+  }
+
+  bool CanBeImmediate(uint32_t value) const {
+    return CanBeImmediate(bit_cast<int32_t>(value));
   }
 
   bool CanBeImmediate(Node* node, InstructionCode opcode) {
@@ -32,27 +33,25 @@
       case kArmMov:
       case kArmMvn:
       case kArmBic:
-        return ImmediateFitsAddrMode1Instruction(value) ||
-               ImmediateFitsAddrMode1Instruction(~value);
+        return CanBeImmediate(value) || CanBeImmediate(~value);
 
       case kArmAdd:
       case kArmSub:
       case kArmCmp:
       case kArmCmn:
-        return ImmediateFitsAddrMode1Instruction(value) ||
-               ImmediateFitsAddrMode1Instruction(-value);
+        return CanBeImmediate(value) || CanBeImmediate(-value);
 
       case kArmTst:
       case kArmTeq:
       case kArmOrr:
       case kArmEor:
       case kArmRsb:
-        return ImmediateFitsAddrMode1Instruction(value);
+        return CanBeImmediate(value);
 
-      case kArmVldr32:
-      case kArmVstr32:
-      case kArmVldr64:
-      case kArmVstr64:
+      case kArmVldrF32:
+      case kArmVstrF32:
+      case kArmVldrF64:
+      case kArmVstrF64:
         return value >= -1020 && value <= 1020 && (value % 4) == 0;
 
       case kArmLdrb:
@@ -68,49 +67,26 @@
       case kArmStrh:
         return value >= -255 && value <= 255;
 
-      case kArchCallCodeObject:
-      case kArchCallJSFunction:
-      case kArchJmp:
-      case kArchNop:
-      case kArchRet:
-      case kArchTruncateDoubleToI:
-      case kArmMul:
-      case kArmMla:
-      case kArmMls:
-      case kArmSdiv:
-      case kArmUdiv:
-      case kArmBfc:
-      case kArmUbfx:
-      case kArmVcmpF64:
-      case kArmVaddF64:
-      case kArmVsubF64:
-      case kArmVmulF64:
-      case kArmVmlaF64:
-      case kArmVmlsF64:
-      case kArmVdivF64:
-      case kArmVmodF64:
-      case kArmVnegF64:
-      case kArmVsqrtF64:
-      case kArmVcvtF64S32:
-      case kArmVcvtF64U32:
-      case kArmVcvtS32F64:
-      case kArmVcvtU32F64:
-      case kArmPush:
-        return false;
+      default:
+        break;
     }
-    UNREACHABLE();
     return false;
   }
-
- private:
-  bool ImmediateFitsAddrMode1Instruction(int32_t imm) const {
-    return Assembler::ImmediateFitsAddrMode1Instruction(imm);
-  }
 };
 
 
-static void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
-                            Node* node) {
+namespace {
+
+void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
+                    Node* node) {
+  ArmOperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)));
+}
+
+
+void VisitRRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
+                     Node* node) {
   ArmOperandGenerator g(selector);
   selector->Emit(opcode, g.DefineAsRegister(node),
                  g.UseRegister(node->InputAt(0)),
@@ -118,86 +94,69 @@
 }
 
 
-static bool TryMatchROR(InstructionSelector* selector,
-                        InstructionCode* opcode_return, Node* node,
-                        InstructionOperand** value_return,
-                        InstructionOperand** shift_return) {
+template <IrOpcode::Value kOpcode, int kImmMin, int kImmMax,
+          AddressingMode kImmMode, AddressingMode kRegMode>
+bool TryMatchShift(InstructionSelector* selector,
+                   InstructionCode* opcode_return, Node* node,
+                   InstructionOperand** value_return,
+                   InstructionOperand** shift_return) {
   ArmOperandGenerator g(selector);
-  if (node->opcode() != IrOpcode::kWord32Ror) return false;
-  Int32BinopMatcher m(node);
-  *value_return = g.UseRegister(m.left().node());
-  if (m.right().IsInRange(1, 31)) {
-    *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_I);
-    *shift_return = g.UseImmediate(m.right().node());
-  } else {
-    *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ROR_R);
-    *shift_return = g.UseRegister(m.right().node());
+  if (node->opcode() == kOpcode) {
+    Int32BinopMatcher m(node);
+    *value_return = g.UseRegister(m.left().node());
+    if (m.right().IsInRange(kImmMin, kImmMax)) {
+      *opcode_return |= AddressingModeField::encode(kImmMode);
+      *shift_return = g.UseImmediate(m.right().node());
+    } else {
+      *opcode_return |= AddressingModeField::encode(kRegMode);
+      *shift_return = g.UseRegister(m.right().node());
+    }
+    return true;
   }
-  return true;
+  return false;
 }
 
 
-static inline bool TryMatchASR(InstructionSelector* selector,
-                               InstructionCode* opcode_return, Node* node,
-                               InstructionOperand** value_return,
-                               InstructionOperand** shift_return) {
-  ArmOperandGenerator g(selector);
-  if (node->opcode() != IrOpcode::kWord32Sar) return false;
-  Int32BinopMatcher m(node);
-  *value_return = g.UseRegister(m.left().node());
-  if (m.right().IsInRange(1, 32)) {
-    *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ASR_I);
-    *shift_return = g.UseImmediate(m.right().node());
-  } else {
-    *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_ASR_R);
-    *shift_return = g.UseRegister(m.right().node());
-  }
-  return true;
+bool TryMatchROR(InstructionSelector* selector, InstructionCode* opcode_return,
+                 Node* node, InstructionOperand** value_return,
+                 InstructionOperand** shift_return) {
+  return TryMatchShift<IrOpcode::kWord32Ror, 1, 31, kMode_Operand2_R_ROR_I,
+                       kMode_Operand2_R_ROR_R>(selector, opcode_return, node,
+                                               value_return, shift_return);
 }
 
 
-static inline bool TryMatchLSL(InstructionSelector* selector,
-                               InstructionCode* opcode_return, Node* node,
-                               InstructionOperand** value_return,
-                               InstructionOperand** shift_return) {
-  ArmOperandGenerator g(selector);
-  if (node->opcode() != IrOpcode::kWord32Shl) return false;
-  Int32BinopMatcher m(node);
-  *value_return = g.UseRegister(m.left().node());
-  if (m.right().IsInRange(0, 31)) {
-    *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSL_I);
-    *shift_return = g.UseImmediate(m.right().node());
-  } else {
-    *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSL_R);
-    *shift_return = g.UseRegister(m.right().node());
-  }
-  return true;
+bool TryMatchASR(InstructionSelector* selector, InstructionCode* opcode_return,
+                 Node* node, InstructionOperand** value_return,
+                 InstructionOperand** shift_return) {
+  return TryMatchShift<IrOpcode::kWord32Sar, 1, 32, kMode_Operand2_R_ASR_I,
+                       kMode_Operand2_R_ASR_R>(selector, opcode_return, node,
+                                               value_return, shift_return);
 }
 
 
-static inline bool TryMatchLSR(InstructionSelector* selector,
-                               InstructionCode* opcode_return, Node* node,
-                               InstructionOperand** value_return,
-                               InstructionOperand** shift_return) {
-  ArmOperandGenerator g(selector);
-  if (node->opcode() != IrOpcode::kWord32Shr) return false;
-  Int32BinopMatcher m(node);
-  *value_return = g.UseRegister(m.left().node());
-  if (m.right().IsInRange(1, 32)) {
-    *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_I);
-    *shift_return = g.UseImmediate(m.right().node());
-  } else {
-    *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_R);
-    *shift_return = g.UseRegister(m.right().node());
-  }
-  return true;
+bool TryMatchLSL(InstructionSelector* selector, InstructionCode* opcode_return,
+                 Node* node, InstructionOperand** value_return,
+                 InstructionOperand** shift_return) {
+  return TryMatchShift<IrOpcode::kWord32Shl, 0, 31, kMode_Operand2_R_LSL_I,
+                       kMode_Operand2_R_LSL_R>(selector, opcode_return, node,
+                                               value_return, shift_return);
 }
 
 
-static inline bool TryMatchShift(InstructionSelector* selector,
-                                 InstructionCode* opcode_return, Node* node,
-                                 InstructionOperand** value_return,
-                                 InstructionOperand** shift_return) {
+bool TryMatchLSR(InstructionSelector* selector, InstructionCode* opcode_return,
+                 Node* node, InstructionOperand** value_return,
+                 InstructionOperand** shift_return) {
+  return TryMatchShift<IrOpcode::kWord32Shr, 1, 32, kMode_Operand2_R_LSR_I,
+                       kMode_Operand2_R_LSR_R>(selector, opcode_return, node,
+                                               value_return, shift_return);
+}
+
+
+bool TryMatchShift(InstructionSelector* selector,
+                   InstructionCode* opcode_return, Node* node,
+                   InstructionOperand** value_return,
+                   InstructionOperand** shift_return) {
   return (
       TryMatchASR(selector, opcode_return, node, value_return, shift_return) ||
       TryMatchLSL(selector, opcode_return, node, value_return, shift_return) ||
@@ -206,11 +165,10 @@
 }
 
 
-static inline bool TryMatchImmediateOrShift(InstructionSelector* selector,
-                                            InstructionCode* opcode_return,
-                                            Node* node,
-                                            size_t* input_count_return,
-                                            InstructionOperand** inputs) {
+bool TryMatchImmediateOrShift(InstructionSelector* selector,
+                              InstructionCode* opcode_return, Node* node,
+                              size_t* input_count_return,
+                              InstructionOperand** inputs) {
   ArmOperandGenerator g(selector);
   if (g.CanBeImmediate(node, *opcode_return)) {
     *opcode_return |= AddressingModeField::encode(kMode_Operand2_I);
@@ -226,9 +184,9 @@
 }
 
 
-static void VisitBinop(InstructionSelector* selector, Node* node,
-                       InstructionCode opcode, InstructionCode reverse_opcode,
-                       FlagsContinuation* cont) {
+void VisitBinop(InstructionSelector* selector, Node* node,
+                InstructionCode opcode, InstructionCode reverse_opcode,
+                FlagsContinuation* cont) {
   ArmOperandGenerator g(selector);
   Int32BinopMatcher m(node);
   InstructionOperand* inputs[5];
@@ -236,8 +194,20 @@
   InstructionOperand* outputs[2];
   size_t output_count = 0;
 
-  if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(),
-                               &input_count, &inputs[1])) {
+  if (m.left().node() == m.right().node()) {
+    // If both inputs refer to the same operand, enforce allocating a register
+    // for both of them to ensure that we don't end up generating code like
+    // this:
+    //
+    //   mov r0, r1, asr #16
+    //   adds r0, r0, r1, asr #16
+    //   bvs label
+    InstructionOperand* const input = g.UseRegister(m.left().node());
+    opcode |= AddressingModeField::encode(kMode_Operand2_R);
+    inputs[input_count++] = input;
+    inputs[input_count++] = input;
+  } else if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(),
+                                      &input_count, &inputs[1])) {
     inputs[0] = g.UseRegister(m.left().node());
     input_count++;
   } else if (TryMatchImmediateOrShift(selector, &reverse_opcode,
@@ -274,13 +244,16 @@
 }
 
 
-static void VisitBinop(InstructionSelector* selector, Node* node,
-                       InstructionCode opcode, InstructionCode reverse_opcode) {
+void VisitBinop(InstructionSelector* selector, Node* node,
+                InstructionCode opcode, InstructionCode reverse_opcode) {
   FlagsContinuation cont;
   VisitBinop(selector, node, opcode, reverse_opcode, &cont);
 }
 
 
+}  // namespace
+
+
 void InstructionSelector::VisitLoad(Node* node) {
   MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
   MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
@@ -291,10 +264,10 @@
   ArchOpcode opcode;
   switch (rep) {
     case kRepFloat32:
-      opcode = kArmVldr32;
+      opcode = kArmVldrF32;
       break;
     case kRepFloat64:
-      opcode = kArmVldr64;
+      opcode = kArmVldrF64;
       break;
     case kRepBit:  // Fall through.
     case kRepWord8:
@@ -346,10 +319,10 @@
   ArchOpcode opcode;
   switch (rep) {
     case kRepFloat32:
-      opcode = kArmVstr32;
+      opcode = kArmVstrF32;
       break;
     case kRepFloat64:
-      opcode = kArmVstr64;
+      opcode = kArmVstrF64;
       break;
     case kRepBit:  // Fall through.
     case kRepWord8:
@@ -377,8 +350,86 @@
 }
 
 
-static inline void EmitBic(InstructionSelector* selector, Node* node,
-                           Node* left, Node* right) {
+void InstructionSelector::VisitCheckedLoad(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  ArmOperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepWord8:
+      opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
+      break;
+    case kRepWord16:
+      opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
+      break;
+    case kRepWord32:
+      opcode = kCheckedLoadWord32;
+      break;
+    case kRepFloat32:
+      opcode = kCheckedLoadFloat32;
+      break;
+    case kRepFloat64:
+      opcode = kCheckedLoadFloat64;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  InstructionOperand* offset_operand = g.UseRegister(offset);
+  InstructionOperand* length_operand = g.CanBeImmediate(length, kArmCmp)
+                                           ? g.UseImmediate(length)
+                                           : g.UseRegister(length);
+  Emit(opcode | AddressingModeField::encode(kMode_Offset_RR),
+       g.DefineAsRegister(node), offset_operand, length_operand,
+       g.UseRegister(buffer), offset_operand);
+}
+
+
+void InstructionSelector::VisitCheckedStore(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  ArmOperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  Node* const value = node->InputAt(3);
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepWord8:
+      opcode = kCheckedStoreWord8;
+      break;
+    case kRepWord16:
+      opcode = kCheckedStoreWord16;
+      break;
+    case kRepWord32:
+      opcode = kCheckedStoreWord32;
+      break;
+    case kRepFloat32:
+      opcode = kCheckedStoreFloat32;
+      break;
+    case kRepFloat64:
+      opcode = kCheckedStoreFloat64;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  InstructionOperand* offset_operand = g.UseRegister(offset);
+  InstructionOperand* length_operand = g.CanBeImmediate(length, kArmCmp)
+                                           ? g.UseImmediate(length)
+                                           : g.UseRegister(length);
+  Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), nullptr,
+       offset_operand, length_operand, g.UseRegister(value),
+       g.UseRegister(buffer), offset_operand);
+}
+
+
+namespace {
+
+void EmitBic(InstructionSelector* selector, Node* node, Node* left,
+             Node* right) {
   ArmOperandGenerator g(selector);
   InstructionCode opcode = kArmBic;
   InstructionOperand* value_operand;
@@ -394,6 +445,18 @@
 }
 
 
+void EmitUbfx(InstructionSelector* selector, Node* node, Node* left,
+              uint32_t lsb, uint32_t width) {
+  DCHECK_LE(1, width);
+  DCHECK_LE(width, 32 - lsb);
+  ArmOperandGenerator g(selector);
+  selector->Emit(kArmUbfx, g.DefineAsRegister(node), g.UseRegister(left),
+                 g.TempImmediate(lsb), g.TempImmediate(width));
+}
+
+}  // namespace
+
+
 void InstructionSelector::VisitWord32And(Node* node) {
   ArmOperandGenerator g(this);
   Int32BinopMatcher m(node);
@@ -411,33 +474,50 @@
       return;
     }
   }
-  if (IsSupported(ARMv7) && m.right().HasValue()) {
-    uint32_t value = m.right().Value();
+  if (m.right().HasValue()) {
+    uint32_t const value = m.right().Value();
     uint32_t width = base::bits::CountPopulation32(value);
     uint32_t msb = base::bits::CountLeadingZeros32(value);
-    if (width != 0 && msb + width == 32) {
+    // Try to interpret this AND as UBFX.
+    if (IsSupported(ARMv7) && width != 0 && msb + width == 32) {
       DCHECK_EQ(0, base::bits::CountTrailingZeros32(value));
       if (m.left().IsWord32Shr()) {
         Int32BinopMatcher mleft(m.left().node());
         if (mleft.right().IsInRange(0, 31)) {
-          Emit(kArmUbfx, g.DefineAsRegister(node),
-               g.UseRegister(mleft.left().node()),
-               g.UseImmediate(mleft.right().node()), g.TempImmediate(width));
-          return;
+          // UBFX cannot extract bits past the register size, however since
+          // shifting the original value would have introduced some zeros we can
+          // still use UBFX with a smaller mask and the remaining bits will be
+          // zeros.
+          uint32_t const lsb = mleft.right().Value();
+          return EmitUbfx(this, node, mleft.left().node(), lsb,
+                          std::min(width, 32 - lsb));
         }
       }
-      Emit(kArmUbfx, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
-           g.TempImmediate(0), g.TempImmediate(width));
+      return EmitUbfx(this, node, m.left().node(), 0, width);
+    }
+    // Try to interpret this AND as BIC.
+    if (g.CanBeImmediate(~value)) {
+      Emit(kArmBic | AddressingModeField::encode(kMode_Operand2_I),
+           g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+           g.TempImmediate(~value));
+      return;
+    }
+    // Try to interpret this AND as UXTH.
+    if (value == 0xffff) {
+      Emit(kArmUxth, g.DefineAsRegister(m.node()),
+           g.UseRegister(m.left().node()), g.TempImmediate(0));
       return;
     }
     // Try to interpret this AND as BFC.
-    width = 32 - width;
-    msb = base::bits::CountLeadingZeros32(~value);
-    uint32_t lsb = base::bits::CountTrailingZeros32(~value);
-    if (msb + width + lsb == 32) {
-      Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
-           g.TempImmediate(lsb), g.TempImmediate(width));
-      return;
+    if (IsSupported(ARMv7)) {
+      width = 32 - width;
+      msb = base::bits::CountLeadingZeros32(~value);
+      uint32_t lsb = base::bits::CountTrailingZeros32(~value);
+      if (msb + width + lsb == 32) {
+        Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
+             g.TempImmediate(lsb), g.TempImmediate(width));
+        return;
+      }
     }
   }
   VisitBinop(this, node, kArmAnd, kArmAnd);
@@ -530,10 +610,7 @@
       uint32_t msb = base::bits::CountLeadingZeros32(value);
       if (msb + width + lsb == 32) {
         DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(value));
-        Emit(kArmUbfx, g.DefineAsRegister(node),
-             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
-             g.TempImmediate(width));
-        return;
+        return EmitUbfx(this, node, mleft.left().node(), lsb, width);
       }
     }
   }
@@ -542,6 +619,20 @@
 
 
 void InstructionSelector::VisitWord32Sar(Node* node) {
+  ArmOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (CanCover(m.node(), m.left().node()) && m.left().IsWord32Shl()) {
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.right().Is(16) && m.right().Is(16)) {
+      Emit(kArmSxth, g.DefineAsRegister(node),
+           g.UseRegister(mleft.left().node()), g.TempImmediate(0));
+      return;
+    } else if (mleft.right().Is(24) && m.right().Is(24)) {
+      Emit(kArmSxtb, g.DefineAsRegister(node),
+           g.UseRegister(mleft.left().node()), g.TempImmediate(0));
+      return;
+    }
+  }
   VisitShift(this, node, TryMatchASR);
 }
 
@@ -554,17 +645,113 @@
 void InstructionSelector::VisitInt32Add(Node* node) {
   ArmOperandGenerator g(this);
   Int32BinopMatcher m(node);
-  if (m.left().IsInt32Mul() && CanCover(node, m.left().node())) {
-    Int32BinopMatcher mleft(m.left().node());
-    Emit(kArmMla, g.DefineAsRegister(node), g.UseRegister(mleft.left().node()),
-         g.UseRegister(mleft.right().node()), g.UseRegister(m.right().node()));
-    return;
+  if (CanCover(node, m.left().node())) {
+    switch (m.left().opcode()) {
+      case IrOpcode::kInt32Mul: {
+        Int32BinopMatcher mleft(m.left().node());
+        Emit(kArmMla, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()),
+             g.UseRegister(mleft.right().node()),
+             g.UseRegister(m.right().node()));
+        return;
+      }
+      case IrOpcode::kInt32MulHigh: {
+        Int32BinopMatcher mleft(m.left().node());
+        Emit(kArmSmmla, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()),
+             g.UseRegister(mleft.right().node()),
+             g.UseRegister(m.right().node()));
+        return;
+      }
+      case IrOpcode::kWord32And: {
+        Int32BinopMatcher mleft(m.left().node());
+        if (mleft.right().Is(0xff)) {
+          Emit(kArmUxtab, g.DefineAsRegister(node),
+               g.UseRegister(m.right().node()),
+               g.UseRegister(mleft.left().node()), g.TempImmediate(0));
+          return;
+        } else if (mleft.right().Is(0xffff)) {
+          Emit(kArmUxtah, g.DefineAsRegister(node),
+               g.UseRegister(m.right().node()),
+               g.UseRegister(mleft.left().node()), g.TempImmediate(0));
+          return;
+        }
+      }
+      case IrOpcode::kWord32Sar: {
+        Int32BinopMatcher mleft(m.left().node());
+        if (CanCover(mleft.node(), mleft.left().node()) &&
+            mleft.left().IsWord32Shl()) {
+          Int32BinopMatcher mleftleft(mleft.left().node());
+          if (mleft.right().Is(24) && mleftleft.right().Is(24)) {
+            Emit(kArmSxtab, g.DefineAsRegister(node),
+                 g.UseRegister(m.right().node()),
+                 g.UseRegister(mleftleft.left().node()), g.TempImmediate(0));
+            return;
+          } else if (mleft.right().Is(16) && mleftleft.right().Is(16)) {
+            Emit(kArmSxtah, g.DefineAsRegister(node),
+                 g.UseRegister(m.right().node()),
+                 g.UseRegister(mleftleft.left().node()), g.TempImmediate(0));
+            return;
+          }
+        }
+      }
+      default:
+        break;
+    }
   }
-  if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) {
-    Int32BinopMatcher mright(m.right().node());
-    Emit(kArmMla, g.DefineAsRegister(node), g.UseRegister(mright.left().node()),
-         g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
-    return;
+  if (CanCover(node, m.right().node())) {
+    switch (m.right().opcode()) {
+      case IrOpcode::kInt32Mul: {
+        Int32BinopMatcher mright(m.right().node());
+        Emit(kArmMla, g.DefineAsRegister(node),
+             g.UseRegister(mright.left().node()),
+             g.UseRegister(mright.right().node()),
+             g.UseRegister(m.left().node()));
+        return;
+      }
+      case IrOpcode::kInt32MulHigh: {
+        Int32BinopMatcher mright(m.right().node());
+        Emit(kArmSmmla, g.DefineAsRegister(node),
+             g.UseRegister(mright.left().node()),
+             g.UseRegister(mright.right().node()),
+             g.UseRegister(m.left().node()));
+        return;
+      }
+      case IrOpcode::kWord32And: {
+        Int32BinopMatcher mright(m.right().node());
+        if (mright.right().Is(0xff)) {
+          Emit(kArmUxtab, g.DefineAsRegister(node),
+               g.UseRegister(m.left().node()),
+               g.UseRegister(mright.left().node()), g.TempImmediate(0));
+          return;
+        } else if (mright.right().Is(0xffff)) {
+          Emit(kArmUxtah, g.DefineAsRegister(node),
+               g.UseRegister(m.left().node()),
+               g.UseRegister(mright.left().node()), g.TempImmediate(0));
+          return;
+        }
+      }
+      case IrOpcode::kWord32Sar: {
+        Int32BinopMatcher mright(m.right().node());
+        if (CanCover(mright.node(), mright.left().node()) &&
+            mright.left().IsWord32Shl()) {
+          Int32BinopMatcher mrightleft(mright.left().node());
+          if (mright.right().Is(24) && mrightleft.right().Is(24)) {
+            Emit(kArmSxtab, g.DefineAsRegister(node),
+                 g.UseRegister(m.left().node()),
+                 g.UseRegister(mrightleft.left().node()), g.TempImmediate(0));
+            return;
+          } else if (mright.right().Is(16) && mrightleft.right().Is(16)) {
+            Emit(kArmSxtah, g.DefineAsRegister(node),
+                 g.UseRegister(m.left().node()),
+                 g.UseRegister(mrightleft.left().node()), g.TempImmediate(0));
+            return;
+          }
+        }
+      }
+      default:
+        break;
+    }
   }
   VisitBinop(this, node, kArmAdd, kArmAdd);
 }
@@ -609,6 +796,22 @@
 }
 
 
+void InstructionSelector::VisitInt32MulHigh(Node* node) {
+  ArmOperandGenerator g(this);
+  Emit(kArmSmmul, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
+       g.UseRegister(node->InputAt(1)));
+}
+
+
+void InstructionSelector::VisitUint32MulHigh(Node* node) {
+  ArmOperandGenerator g(this);
+  InstructionOperand* outputs[] = {g.TempRegister(), g.DefineAsRegister(node)};
+  InstructionOperand* inputs[] = {g.UseRegister(node->InputAt(0)),
+                                  g.UseRegister(node->InputAt(1))};
+  Emit(kArmUmull, arraysize(outputs), outputs, arraysize(inputs), inputs);
+}
+
+
 static void EmitDiv(InstructionSelector* selector, ArchOpcode div_opcode,
                     ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode,
                     InstructionOperand* result_operand,
@@ -646,7 +849,7 @@
 }
 
 
-void InstructionSelector::VisitInt32UDiv(Node* node) {
+void InstructionSelector::VisitUint32Div(Node* node) {
   VisitDiv(this, node, kArmUdiv, kArmVcvtF64U32, kArmVcvtU32F64);
 }
 
@@ -678,11 +881,18 @@
 }
 
 
-void InstructionSelector::VisitInt32UMod(Node* node) {
+void InstructionSelector::VisitUint32Mod(Node* node) {
   VisitMod(this, node, kArmUdiv, kArmVcvtF64U32, kArmVcvtU32F64);
 }
 
 
+void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
+  ArmOperandGenerator g(this);
+  Emit(kArmVcvtF64F32, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
   ArmOperandGenerator g(this);
   Emit(kArmVcvtF64S32, g.DefineAsRegister(node),
@@ -711,18 +921,25 @@
 }
 
 
+void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
+  ArmOperandGenerator g(this);
+  Emit(kArmVcvtF32F64, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
 void InstructionSelector::VisitFloat64Add(Node* node) {
   ArmOperandGenerator g(this);
-  Int32BinopMatcher m(node);
+  Float64BinopMatcher m(node);
   if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) {
-    Int32BinopMatcher mleft(m.left().node());
+    Float64BinopMatcher mleft(m.left().node());
     Emit(kArmVmlaF64, g.DefineSameAsFirst(node),
          g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()),
          g.UseRegister(mleft.right().node()));
     return;
   }
   if (m.right().IsFloat64Mul() && CanCover(node, m.right().node())) {
-    Int32BinopMatcher mright(m.right().node());
+    Float64BinopMatcher mright(m.right().node());
     Emit(kArmVmlaF64, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
          g.UseRegister(mright.left().node()),
          g.UseRegister(mright.right().node()));
@@ -734,9 +951,14 @@
 
 void InstructionSelector::VisitFloat64Sub(Node* node) {
   ArmOperandGenerator g(this);
-  Int32BinopMatcher m(node);
+  Float64BinopMatcher m(node);
+  if (m.left().IsMinusZero()) {
+    Emit(kArmVnegF64, g.DefineAsRegister(node),
+         g.UseRegister(m.right().node()));
+    return;
+  }
   if (m.right().IsFloat64Mul() && CanCover(node, m.right().node())) {
-    Int32BinopMatcher mright(m.right().node());
+    Float64BinopMatcher mright(m.right().node());
     Emit(kArmVmlsF64, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
          g.UseRegister(mright.left().node()),
          g.UseRegister(mright.right().node()));
@@ -747,13 +969,7 @@
 
 
 void InstructionSelector::VisitFloat64Mul(Node* node) {
-  ArmOperandGenerator g(this);
-  Float64BinopMatcher m(node);
-  if (m.right().Is(-1.0)) {
-    Emit(kArmVnegF64, g.DefineAsRegister(node), g.UseRegister(m.left().node()));
-  } else {
-    VisitRRRFloat64(this, kArmVmulF64, node);
-  }
+  VisitRRRFloat64(this, kArmVmulF64, node);
 }
 
 
@@ -775,15 +991,38 @@
 }
 
 
-void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
-                                    BasicBlock* deoptimization) {
+void InstructionSelector::VisitFloat64Floor(Node* node) {
+  DCHECK(CpuFeatures::IsSupported(ARMv8));
+  VisitRRFloat64(this, kArmVfloorF64, node);
+}
+
+
+void InstructionSelector::VisitFloat64Ceil(Node* node) {
+  DCHECK(CpuFeatures::IsSupported(ARMv8));
+  VisitRRFloat64(this, kArmVceilF64, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
+  DCHECK(CpuFeatures::IsSupported(ARMv8));
+  VisitRRFloat64(this, kArmVroundTruncateF64, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
+  DCHECK(CpuFeatures::IsSupported(ARMv8));
+  VisitRRFloat64(this, kArmVroundTiesAwayF64, node);
+}
+
+
+void InstructionSelector::VisitCall(Node* node) {
   ArmOperandGenerator g(this);
-  CallDescriptor* descriptor = OpParameter<CallDescriptor*>(call);
+  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
 
   FrameStateDescriptor* frame_state_descriptor = NULL;
   if (descriptor->NeedsFrameState()) {
     frame_state_descriptor =
-        GetFrameStateDescriptor(call->InputAt(descriptor->InputCount()));
+        GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
   }
 
   CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
@@ -792,7 +1031,7 @@
   // TODO(turbofan): on ARM64 it's probably better to use the code object in a
   // register if there are multiple uses of it. Improve constant pool and the
   // heuristics in the register allocator for where to emit constants.
-  InitializeCallBuffer(call, &buffer, true, false);
+  InitializeCallBuffer(node, &buffer, true, false);
 
   // TODO(dcarney): might be possible to use claim/poke instead
   // Push any stack arguments.
@@ -818,34 +1057,39 @@
   opcode |= MiscField::encode(descriptor->flags());
 
   // Emit the call instruction.
+  InstructionOperand** first_output =
+      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
   Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
+      Emit(opcode, buffer.outputs.size(), first_output,
            buffer.instruction_args.size(), &buffer.instruction_args.front());
-
   call_instr->MarkAsCall();
-  if (deoptimization != NULL) {
-    DCHECK(continuation != NULL);
-    call_instr->MarkAsControl();
+}
+
+
+namespace {
+
+// Shared routine for multiple float compare operations.
+void VisitFloat64Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  ArmOperandGenerator g(selector);
+  Float64BinopMatcher m(node);
+  if (cont->IsBranch()) {
+    selector->Emit(cont->Encode(kArmVcmpF64), nullptr,
+                   g.UseRegister(m.left().node()),
+                   g.UseRegister(m.right().node()), g.Label(cont->true_block()),
+                   g.Label(cont->false_block()))->MarkAsControl();
+  } else {
+    DCHECK(cont->IsSet());
+    selector->Emit(
+        cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()),
+        g.UseRegister(m.left().node()), g.UseRegister(m.right().node()));
   }
 }
 
 
-void InstructionSelector::VisitInt32AddWithOverflow(Node* node,
-                                                    FlagsContinuation* cont) {
-  VisitBinop(this, node, kArmAdd, kArmAdd, cont);
-}
-
-
-void InstructionSelector::VisitInt32SubWithOverflow(Node* node,
-                                                    FlagsContinuation* cont) {
-  VisitBinop(this, node, kArmSub, kArmRsb, cont);
-}
-
-
-// Shared routine for multiple compare operations.
-static void VisitWordCompare(InstructionSelector* selector, Node* node,
-                             InstructionCode opcode, FlagsContinuation* cont,
-                             bool commutative) {
+// Shared routine for multiple word compare operations.
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      InstructionCode opcode, FlagsContinuation* cont) {
   ArmOperandGenerator g(selector);
   Int32BinopMatcher m(node);
   InstructionOperand* inputs[5];
@@ -859,7 +1103,7 @@
     input_count++;
   } else if (TryMatchImmediateOrShift(selector, &opcode, m.left().node(),
                                       &input_count, &inputs[1])) {
-    if (!commutative) cont->Commute();
+    if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
     inputs[0] = g.UseRegister(m.right().node());
     input_count++;
   } else {
@@ -886,63 +1130,211 @@
 }
 
 
-void InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) {
-  switch (node->opcode()) {
-    case IrOpcode::kInt32Add:
-      return VisitWordCompare(this, node, kArmCmn, cont, true);
-    case IrOpcode::kInt32Sub:
-      return VisitWordCompare(this, node, kArmCmp, cont, false);
-    case IrOpcode::kWord32And:
-      return VisitWordCompare(this, node, kArmTst, cont, true);
-    case IrOpcode::kWord32Or:
-      return VisitBinop(this, node, kArmOrr, kArmOrr, cont);
-    case IrOpcode::kWord32Xor:
-      return VisitWordCompare(this, node, kArmTeq, cont, true);
-    case IrOpcode::kWord32Sar:
-      return VisitShift(this, node, TryMatchASR, cont);
-    case IrOpcode::kWord32Shl:
-      return VisitShift(this, node, TryMatchLSL, cont);
-    case IrOpcode::kWord32Shr:
-      return VisitShift(this, node, TryMatchLSR, cont);
-    case IrOpcode::kWord32Ror:
-      return VisitShift(this, node, TryMatchROR, cont);
-    default:
-      break;
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      FlagsContinuation* cont) {
+  VisitWordCompare(selector, node, kArmCmp, cont);
+}
+
+
+// Shared routine for word comparisons against zero.
+void VisitWordCompareZero(InstructionSelector* selector, Node* user,
+                          Node* value, FlagsContinuation* cont) {
+  while (selector->CanCover(user, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kWord32Equal: {
+        // Combine with comparisons against 0 by simply inverting the
+        // continuation.
+        Int32BinopMatcher m(value);
+        if (m.right().Is(0)) {
+          user = value;
+          value = m.left().node();
+          cont->Negate();
+          continue;
+        }
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitWordCompare(selector, value, cont);
+      }
+      case IrOpcode::kInt32LessThan:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThan);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kInt32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kUint32LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kUint32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kFloat64Equal:
+        cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kFloat64LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnorderedLessThan);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kFloat64LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kProjection:
+        // Check if this is the overflow output projection of an
+        // <Operation>WithOverflow node.
+        if (OpParameter<size_t>(value) == 1u) {
+          // We cannot combine the <Operation>WithOverflow with this branch
+          // unless the 0th projection (the use of the actual value of the
+          // <Operation> is either NULL, which means there's no use of the
+          // actual value, or was already defined, which means it is scheduled
+          // *AFTER* this branch).
+          Node* const node = value->InputAt(0);
+          Node* const result = node->FindProjection(0);
+          if (!result || selector->IsDefined(result)) {
+            switch (node->opcode()) {
+              case IrOpcode::kInt32AddWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(selector, node, kArmAdd, kArmAdd, cont);
+              case IrOpcode::kInt32SubWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(selector, node, kArmSub, kArmRsb, cont);
+              default:
+                break;
+            }
+          }
+        }
+        break;
+      case IrOpcode::kInt32Add:
+        return VisitWordCompare(selector, value, kArmCmn, cont);
+      case IrOpcode::kInt32Sub:
+        return VisitWordCompare(selector, value, kArmCmp, cont);
+      case IrOpcode::kWord32And:
+        return VisitWordCompare(selector, value, kArmTst, cont);
+      case IrOpcode::kWord32Or:
+        return VisitBinop(selector, value, kArmOrr, kArmOrr, cont);
+      case IrOpcode::kWord32Xor:
+        return VisitWordCompare(selector, value, kArmTeq, cont);
+      case IrOpcode::kWord32Sar:
+        return VisitShift(selector, value, TryMatchASR, cont);
+      case IrOpcode::kWord32Shl:
+        return VisitShift(selector, value, TryMatchLSL, cont);
+      case IrOpcode::kWord32Shr:
+        return VisitShift(selector, value, TryMatchLSR, cont);
+      case IrOpcode::kWord32Ror:
+        return VisitShift(selector, value, TryMatchROR, cont);
+      default:
+        break;
+    }
+    break;
   }
 
-  ArmOperandGenerator g(this);
-  InstructionCode opcode =
+  // Continuation could not be combined with a compare, emit compare against 0.
+  ArmOperandGenerator g(selector);
+  InstructionCode const opcode =
       cont->Encode(kArmTst) | AddressingModeField::encode(kMode_Operand2_R);
+  InstructionOperand* const value_operand = g.UseRegister(value);
   if (cont->IsBranch()) {
-    Emit(opcode, NULL, g.UseRegister(node), g.UseRegister(node),
-         g.Label(cont->true_block()),
-         g.Label(cont->false_block()))->MarkAsControl();
+    selector->Emit(opcode, nullptr, value_operand, value_operand,
+                   g.Label(cont->true_block()),
+                   g.Label(cont->false_block()))->MarkAsControl();
   } else {
-    Emit(opcode, g.DefineAsRegister(cont->result()), g.UseRegister(node),
-         g.UseRegister(node));
+    selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand,
+                   value_operand);
   }
 }
 
+}  // namespace
 
-void InstructionSelector::VisitWord32Compare(Node* node,
-                                             FlagsContinuation* cont) {
-  VisitWordCompare(this, node, kArmCmp, cont, false);
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+                                      BasicBlock* fbranch) {
+  FlagsContinuation cont(kNotEqual, tbranch, fbranch);
+  VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
 }
 
 
-void InstructionSelector::VisitFloat64Compare(Node* node,
-                                              FlagsContinuation* cont) {
-  ArmOperandGenerator g(this);
-  Float64BinopMatcher m(node);
-  if (cont->IsBranch()) {
-    Emit(cont->Encode(kArmVcmpF64), NULL, g.UseRegister(m.left().node()),
-         g.UseRegister(m.right().node()), g.Label(cont->true_block()),
-         g.Label(cont->false_block()))->MarkAsControl();
-  } else {
-    DCHECK(cont->IsSet());
-    Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()),
-         g.UseRegister(m.left().node()), g.UseRegister(m.right().node()));
+void InstructionSelector::VisitWord32Equal(Node* const node) {
+  FlagsContinuation cont(kEqual, node);
+  Int32BinopMatcher m(node);
+  if (m.right().Is(0)) {
+    return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
   }
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kArmAdd, kArmAdd, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kArmAdd, kArmAdd, &cont);
+}
+
+
+void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kArmSub, kArmRsb, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kArmSub, kArmRsb, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64Equal(Node* node) {
+  FlagsContinuation cont(kUnorderedEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThan(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThan, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  MachineOperatorBuilder::Flags flags =
+      MachineOperatorBuilder::kInt32DivIsSafe |
+      MachineOperatorBuilder::kUint32DivIsSafe;
+
+  if (CpuFeatures::IsSupported(ARMv8)) {
+    flags |= MachineOperatorBuilder::kFloat64Floor |
+             MachineOperatorBuilder::kFloat64Ceil |
+             MachineOperatorBuilder::kFloat64RoundTruncate |
+             MachineOperatorBuilder::kFloat64RoundTiesAway;
+  }
+  return flags;
 }
 
 }  // namespace compiler
diff --git a/src/compiler/arm/linkage-arm.cc b/src/compiler/arm/linkage-arm.cc
index 6673a47..3fca76f 100644
--- a/src/compiler/arm/linkage-arm.cc
+++ b/src/compiler/arm/linkage-arm.cc
@@ -35,8 +35,9 @@
 
 typedef LinkageHelper<ArmLinkageHelperTraits> LH;
 
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) {
-  return LH::GetJSCallDescriptor(zone, parameter_count);
+CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
+                                             CallDescriptor::Flags flags) {
+  return LH::GetJSCallDescriptor(zone, parameter_count, flags);
 }
 
 
@@ -49,10 +50,10 @@
 
 
 CallDescriptor* Linkage::GetStubCallDescriptor(
-    CallInterfaceDescriptor descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Zone* zone) {
+    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
+    CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone) {
   return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count,
-                                   flags);
+                                   flags, properties);
 }
 
 
diff --git a/src/compiler/arm64/code-generator-arm64.cc b/src/compiler/arm64/code-generator-arm64.cc
index 31c53d3..e025236 100644
--- a/src/compiler/arm64/code-generator-arm64.cc
+++ b/src/compiler/arm64/code-generator-arm64.cc
@@ -24,6 +24,18 @@
   Arm64OperandConverter(CodeGenerator* gen, Instruction* instr)
       : InstructionOperandConverter(gen, instr) {}
 
+  DoubleRegister InputFloat32Register(int index) {
+    return InputDoubleRegister(index).S();
+  }
+
+  DoubleRegister InputFloat64Register(int index) {
+    return InputDoubleRegister(index);
+  }
+
+  DoubleRegister OutputFloat32Register() { return OutputDoubleRegister().S(); }
+
+  DoubleRegister OutputFloat64Register() { return OutputDoubleRegister(); }
+
   Register InputRegister32(int index) {
     return ToRegister(instr_->InputAt(index)).W();
   }
@@ -46,26 +58,68 @@
 
   Register OutputRegister32() { return ToRegister(instr_->Output()).W(); }
 
+  Operand InputOperand2_32(int index) {
+    switch (AddressingModeField::decode(instr_->opcode())) {
+      case kMode_None:
+        return InputOperand32(index);
+      case kMode_Operand2_R_LSL_I:
+        return Operand(InputRegister32(index), LSL, InputInt5(index + 1));
+      case kMode_Operand2_R_LSR_I:
+        return Operand(InputRegister32(index), LSR, InputInt5(index + 1));
+      case kMode_Operand2_R_ASR_I:
+        return Operand(InputRegister32(index), ASR, InputInt5(index + 1));
+      case kMode_Operand2_R_ROR_I:
+        return Operand(InputRegister32(index), ROR, InputInt5(index + 1));
+      case kMode_MRI:
+      case kMode_MRR:
+        break;
+    }
+    UNREACHABLE();
+    return Operand(-1);
+  }
+
+  Operand InputOperand2_64(int index) {
+    switch (AddressingModeField::decode(instr_->opcode())) {
+      case kMode_None:
+        return InputOperand64(index);
+      case kMode_Operand2_R_LSL_I:
+        return Operand(InputRegister64(index), LSL, InputInt6(index + 1));
+      case kMode_Operand2_R_LSR_I:
+        return Operand(InputRegister64(index), LSR, InputInt6(index + 1));
+      case kMode_Operand2_R_ASR_I:
+        return Operand(InputRegister64(index), ASR, InputInt6(index + 1));
+      case kMode_Operand2_R_ROR_I:
+        return Operand(InputRegister64(index), ROR, InputInt6(index + 1));
+      case kMode_MRI:
+      case kMode_MRR:
+        break;
+    }
+    UNREACHABLE();
+    return Operand(-1);
+  }
+
   MemOperand MemoryOperand(int* first_index) {
     const int index = *first_index;
     switch (AddressingModeField::decode(instr_->opcode())) {
       case kMode_None:
+      case kMode_Operand2_R_LSL_I:
+      case kMode_Operand2_R_LSR_I:
+      case kMode_Operand2_R_ASR_I:
+      case kMode_Operand2_R_ROR_I:
         break;
       case kMode_MRI:
         *first_index += 2;
         return MemOperand(InputRegister(index + 0), InputInt32(index + 1));
       case kMode_MRR:
         *first_index += 2;
-        return MemOperand(InputRegister(index + 0), InputRegister(index + 1),
-                          SXTW);
+        return MemOperand(InputRegister(index + 0), InputRegister(index + 1));
     }
     UNREACHABLE();
     return MemOperand(no_reg);
   }
 
-  MemOperand MemoryOperand() {
-    int index = 0;
-    return MemoryOperand(&index);
+  MemOperand MemoryOperand(int first_index = 0) {
+    return MemoryOperand(&first_index);
   }
 
   Operand ToOperand(InstructionOperand* op) {
@@ -89,6 +143,9 @@
         return Operand(constant.ToInt32());
       case Constant::kInt64:
         return Operand(constant.ToInt64());
+      case Constant::kFloat32:
+        return Operand(
+            isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
       case Constant::kFloat64:
         return Operand(
             isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
@@ -96,6 +153,9 @@
         return Operand(constant.ToExternalReference());
       case Constant::kHeapObject:
         return Operand(constant.ToHeapObject());
+      case Constant::kRpoNumber:
+        UNREACHABLE();  // TODO(dcarney): RPO immediates on arm64.
+        break;
     }
     UNREACHABLE();
     return Operand(-1);
@@ -114,6 +174,106 @@
 };
 
 
+namespace {
+
+class OutOfLineLoadNaN32 FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadNaN32(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL {
+    __ Fmov(result_, std::numeric_limits<float>::quiet_NaN());
+  }
+
+ private:
+  DoubleRegister const result_;
+};
+
+
+class OutOfLineLoadNaN64 FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadNaN64(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL {
+    __ Fmov(result_, std::numeric_limits<double>::quiet_NaN());
+  }
+
+ private:
+  DoubleRegister const result_;
+};
+
+
+class OutOfLineLoadZero FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadZero(CodeGenerator* gen, Register result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL { __ Mov(result_, 0); }
+
+ private:
+  Register const result_;
+};
+
+}  // namespace
+
+
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(width)                         \
+  do {                                                             \
+    auto result = i.OutputFloat##width##Register();                \
+    auto buffer = i.InputRegister(0);                              \
+    auto offset = i.InputRegister32(1);                            \
+    auto length = i.InputOperand32(2);                             \
+    __ Cmp(offset, length);                                        \
+    auto ool = new (zone()) OutOfLineLoadNaN##width(this, result); \
+    __ B(hs, ool->entry());                                        \
+    __ Ldr(result, MemOperand(buffer, offset, UXTW));              \
+    __ Bind(ool->exit());                                          \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr)             \
+  do {                                                       \
+    auto result = i.OutputRegister32();                      \
+    auto buffer = i.InputRegister(0);                        \
+    auto offset = i.InputRegister32(1);                      \
+    auto length = i.InputOperand32(2);                       \
+    __ Cmp(offset, length);                                  \
+    auto ool = new (zone()) OutOfLineLoadZero(this, result); \
+    __ B(hs, ool->entry());                                  \
+    __ asm_instr(result, MemOperand(buffer, offset, UXTW));  \
+    __ Bind(ool->exit());                                    \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_STORE_FLOAT(width)          \
+  do {                                               \
+    auto buffer = i.InputRegister(0);                \
+    auto offset = i.InputRegister32(1);              \
+    auto length = i.InputOperand32(2);               \
+    auto value = i.InputFloat##width##Register(3);   \
+    __ Cmp(offset, length);                          \
+    Label done;                                      \
+    __ B(hs, &done);                                 \
+    __ Str(value, MemOperand(buffer, offset, UXTW)); \
+    __ Bind(&done);                                  \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr)          \
+  do {                                                     \
+    auto buffer = i.InputRegister(0);                      \
+    auto offset = i.InputRegister32(1);                    \
+    auto length = i.InputOperand32(2);                     \
+    auto value = i.InputRegister32(3);                     \
+    __ Cmp(offset, length);                                \
+    Label done;                                            \
+    __ B(hs, &done);                                       \
+    __ asm_instr(value, MemOperand(buffer, offset, UXTW)); \
+    __ Bind(&done);                                        \
+  } while (0)
+
+
 #define ASSEMBLE_SHIFT(asm_instr, width)                                       \
   do {                                                                         \
     if (instr->InputAt(1)->IsRegister()) {                                     \
@@ -123,7 +283,7 @@
       int64_t imm = i.InputOperand##width(1).immediate().value();              \
       __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), imm); \
     }                                                                          \
-  } while (0);
+  } while (0)
 
 
 // Assembles an instruction after register allocation, producing machine code.
@@ -161,7 +321,7 @@
       break;
     }
     case kArchJmp:
-      __ B(code_->GetLabel(i.InputBlock(0)));
+      AssembleArchJump(i.InputRpo(0));
       break;
     case kArchNop:
       // don't emit code for nops.
@@ -169,25 +329,47 @@
     case kArchRet:
       AssembleReturn();
       break;
+    case kArchStackPointer:
+      __ mov(i.OutputRegister(), masm()->StackPointer());
+      break;
     case kArchTruncateDoubleToI:
       __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
       break;
+    case kArm64Float64Ceil:
+      __ Frintp(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
+    case kArm64Float64Floor:
+      __ Frintm(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
+    case kArm64Float64RoundTruncate:
+      __ Frintz(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
+    case kArm64Float64RoundTiesAway:
+      __ Frinta(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
     case kArm64Add:
-      __ Add(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      __ Add(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
       break;
     case kArm64Add32:
       if (FlagsModeField::decode(opcode) != kFlags_none) {
         __ Adds(i.OutputRegister32(), i.InputRegister32(0),
-                i.InputOperand32(1));
+                i.InputOperand2_32(1));
       } else {
-        __ Add(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand32(1));
+        __ Add(i.OutputRegister32(), i.InputRegister32(0),
+               i.InputOperand2_32(1));
       }
       break;
     case kArm64And:
-      __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
       break;
     case kArm64And32:
-      __ And(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand32(1));
+      __ And(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand2_32(1));
+      break;
+    case kArm64Bic:
+      __ Bic(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
+      break;
+    case kArm64Bic32:
+      __ Bic(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand2_32(1));
       break;
     case kArm64Mul:
       __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
@@ -195,6 +377,34 @@
     case kArm64Mul32:
       __ Mul(i.OutputRegister32(), i.InputRegister32(0), i.InputRegister32(1));
       break;
+    case kArm64Smull:
+      __ Smull(i.OutputRegister(), i.InputRegister32(0), i.InputRegister32(1));
+      break;
+    case kArm64Umull:
+      __ Umull(i.OutputRegister(), i.InputRegister32(0), i.InputRegister32(1));
+      break;
+    case kArm64Madd:
+      __ Madd(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+              i.InputRegister(2));
+      break;
+    case kArm64Madd32:
+      __ Madd(i.OutputRegister32(), i.InputRegister32(0), i.InputRegister32(1),
+              i.InputRegister32(2));
+      break;
+    case kArm64Msub:
+      __ Msub(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1),
+              i.InputRegister(2));
+      break;
+    case kArm64Msub32:
+      __ Msub(i.OutputRegister32(), i.InputRegister32(0), i.InputRegister32(1),
+              i.InputRegister32(2));
+      break;
+    case kArm64Mneg:
+      __ Mneg(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      break;
+    case kArm64Mneg32:
+      __ Mneg(i.OutputRegister32(), i.InputRegister32(0), i.InputRegister32(1));
+      break;
     case kArm64Idiv:
       __ Sdiv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
       break;
@@ -251,44 +461,57 @@
       __ Neg(i.OutputRegister32(), i.InputOperand32(0));
       break;
     case kArm64Or:
-      __ Orr(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      __ Orr(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
       break;
     case kArm64Or32:
-      __ Orr(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand32(1));
+      __ Orr(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand2_32(1));
       break;
-    case kArm64Xor:
-      __ Eor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+    case kArm64Orn:
+      __ Orn(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
       break;
-    case kArm64Xor32:
-      __ Eor(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand32(1));
+    case kArm64Orn32:
+      __ Orn(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand2_32(1));
+      break;
+    case kArm64Eor:
+      __ Eor(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
+      break;
+    case kArm64Eor32:
+      __ Eor(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand2_32(1));
+      break;
+    case kArm64Eon:
+      __ Eon(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
+      break;
+    case kArm64Eon32:
+      __ Eon(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand2_32(1));
       break;
     case kArm64Sub:
-      __ Sub(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      __ Sub(i.OutputRegister(), i.InputRegister(0), i.InputOperand2_64(1));
       break;
     case kArm64Sub32:
       if (FlagsModeField::decode(opcode) != kFlags_none) {
         __ Subs(i.OutputRegister32(), i.InputRegister32(0),
-                i.InputOperand32(1));
+                i.InputOperand2_32(1));
       } else {
-        __ Sub(i.OutputRegister32(), i.InputRegister32(0), i.InputOperand32(1));
+        __ Sub(i.OutputRegister32(), i.InputRegister32(0),
+               i.InputOperand2_32(1));
       }
       break;
-    case kArm64Shl:
+    case kArm64Lsl:
       ASSEMBLE_SHIFT(Lsl, 64);
       break;
-    case kArm64Shl32:
+    case kArm64Lsl32:
       ASSEMBLE_SHIFT(Lsl, 32);
       break;
-    case kArm64Shr:
+    case kArm64Lsr:
       ASSEMBLE_SHIFT(Lsr, 64);
       break;
-    case kArm64Shr32:
+    case kArm64Lsr32:
       ASSEMBLE_SHIFT(Lsr, 32);
       break;
-    case kArm64Sar:
+    case kArm64Asr:
       ASSEMBLE_SHIFT(Asr, 64);
       break;
-    case kArm64Sar32:
+    case kArm64Asr32:
       ASSEMBLE_SHIFT(Asr, 32);
       break;
     case kArm64Ror:
@@ -300,9 +523,30 @@
     case kArm64Mov32:
       __ Mov(i.OutputRegister32(), i.InputRegister32(0));
       break;
+    case kArm64Sxtb32:
+      __ Sxtb(i.OutputRegister32(), i.InputRegister32(0));
+      break;
+    case kArm64Sxth32:
+      __ Sxth(i.OutputRegister32(), i.InputRegister32(0));
+      break;
     case kArm64Sxtw:
       __ Sxtw(i.OutputRegister(), i.InputRegister32(0));
       break;
+    case kArm64Ubfx:
+      __ Ubfx(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
+              i.InputInt8(2));
+      break;
+    case kArm64Ubfx32:
+      __ Ubfx(i.OutputRegister32(), i.InputRegister32(0), i.InputInt8(1),
+              i.InputInt8(2));
+      break;
+    case kArm64TestAndBranch32:
+    case kArm64TestAndBranch:
+      // Pseudo instructions turned into tbz/tbnz in AssembleArchBranch.
+      break;
+    case kArm64CompareAndBranch32:
+      // Pseudo instruction turned into cbz/cbnz in AssembleArchBranch.
+      break;
     case kArm64Claim: {
       int words = MiscField::decode(instr->opcode());
       __ Claim(words);
@@ -376,6 +620,12 @@
     case kArm64Float64Sqrt:
       __ Fsqrt(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
       break;
+    case kArm64Float32ToFloat64:
+      __ Fcvt(i.OutputDoubleRegister(), i.InputDoubleRegister(0).S());
+      break;
+    case kArm64Float64ToFloat32:
+      __ Fcvt(i.OutputDoubleRegister().S(), i.InputDoubleRegister(0));
+      break;
     case kArm64Float64ToInt32:
       __ Fcvtzs(i.OutputRegister32(), i.InputDoubleRegister(0));
       break;
@@ -418,20 +668,12 @@
     case kArm64Str:
       __ Str(i.InputRegister(2), i.MemoryOperand());
       break;
-    case kArm64LdrS: {
-      UseScratchRegisterScope scope(masm());
-      FPRegister scratch = scope.AcquireS();
-      __ Ldr(scratch, i.MemoryOperand());
-      __ Fcvt(i.OutputDoubleRegister(), scratch);
+    case kArm64LdrS:
+      __ Ldr(i.OutputDoubleRegister().S(), i.MemoryOperand());
       break;
-    }
-    case kArm64StrS: {
-      UseScratchRegisterScope scope(masm());
-      FPRegister scratch = scope.AcquireS();
-      __ Fcvt(scratch, i.InputDoubleRegister(2));
-      __ Str(scratch, i.MemoryOperand());
+    case kArm64StrS:
+      __ Str(i.InputDoubleRegister(2).S(), i.MemoryOperand());
       break;
-    }
     case kArm64LdrD:
       __ Ldr(i.OutputDoubleRegister(), i.MemoryOperand());
       break;
@@ -444,9 +686,8 @@
       Register value = i.InputRegister(2);
       __ Add(index, object, Operand(index, SXTW));
       __ Str(value, MemOperand(index));
-      SaveFPRegsMode mode = code_->frame()->DidAllocateDoubleRegisters()
-                                ? kSaveFPRegs
-                                : kDontSaveFPRegs;
+      SaveFPRegsMode mode =
+          frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
       // TODO(dcarney): we shouldn't test write barriers from c calls.
       LinkRegisterStatus lr_status = kLRHasNotBeenSaved;
       UseScratchRegisterScope scope(masm());
@@ -462,81 +703,154 @@
       }
       break;
     }
+    case kCheckedLoadInt8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrsb);
+      break;
+    case kCheckedLoadUint8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrb);
+      break;
+    case kCheckedLoadInt16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrsh);
+      break;
+    case kCheckedLoadUint16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrh);
+      break;
+    case kCheckedLoadWord32:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(Ldr);
+      break;
+    case kCheckedLoadFloat32:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(32);
+      break;
+    case kCheckedLoadFloat64:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(64);
+      break;
+    case kCheckedStoreWord8:
+      ASSEMBLE_CHECKED_STORE_INTEGER(Strb);
+      break;
+    case kCheckedStoreWord16:
+      ASSEMBLE_CHECKED_STORE_INTEGER(Strh);
+      break;
+    case kCheckedStoreWord32:
+      ASSEMBLE_CHECKED_STORE_INTEGER(Str);
+      break;
+    case kCheckedStoreFloat32:
+      ASSEMBLE_CHECKED_STORE_FLOAT(32);
+      break;
+    case kCheckedStoreFloat64:
+      ASSEMBLE_CHECKED_STORE_FLOAT(64);
+      break;
   }
 }
 
 
 // Assemble branches after this instruction.
-void CodeGenerator::AssembleArchBranch(Instruction* instr,
-                                       FlagsCondition condition) {
+void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
   Arm64OperandConverter i(this, instr);
-  Label done;
+  Label* tlabel = branch->true_label;
+  Label* flabel = branch->false_label;
+  FlagsCondition condition = branch->condition;
+  ArchOpcode opcode = instr->arch_opcode();
 
-  // Emit a branch. The true and false targets are always the last two inputs
-  // to the instruction.
-  BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2);
-  BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1);
-  bool fallthru = IsNextInAssemblyOrder(fblock);
-  Label* tlabel = code()->GetLabel(tblock);
-  Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
-  switch (condition) {
-    case kUnorderedEqual:
-      __ B(vs, flabel);
-    // Fall through.
-    case kEqual:
-      __ B(eq, tlabel);
-      break;
-    case kUnorderedNotEqual:
-      __ B(vs, tlabel);
-    // Fall through.
-    case kNotEqual:
-      __ B(ne, tlabel);
-      break;
-    case kSignedLessThan:
-      __ B(lt, tlabel);
-      break;
-    case kSignedGreaterThanOrEqual:
-      __ B(ge, tlabel);
-      break;
-    case kSignedLessThanOrEqual:
-      __ B(le, tlabel);
-      break;
-    case kSignedGreaterThan:
-      __ B(gt, tlabel);
-      break;
-    case kUnorderedLessThan:
-      __ B(vs, flabel);
-    // Fall through.
-    case kUnsignedLessThan:
-      __ B(lo, tlabel);
-      break;
-    case kUnorderedGreaterThanOrEqual:
-      __ B(vs, tlabel);
-    // Fall through.
-    case kUnsignedGreaterThanOrEqual:
-      __ B(hs, tlabel);
-      break;
-    case kUnorderedLessThanOrEqual:
-      __ B(vs, flabel);
-    // Fall through.
-    case kUnsignedLessThanOrEqual:
-      __ B(ls, tlabel);
-      break;
-    case kUnorderedGreaterThan:
-      __ B(vs, tlabel);
-    // Fall through.
-    case kUnsignedGreaterThan:
-      __ B(hi, tlabel);
-      break;
-    case kOverflow:
-      __ B(vs, tlabel);
-      break;
-    case kNotOverflow:
-      __ B(vc, tlabel);
-      break;
+  if (opcode == kArm64CompareAndBranch32) {
+    switch (condition) {
+      case kEqual:
+        __ Cbz(i.InputRegister32(0), tlabel);
+        break;
+      case kNotEqual:
+        __ Cbnz(i.InputRegister32(0), tlabel);
+        break;
+      default:
+        UNREACHABLE();
+    }
+  } else if (opcode == kArm64TestAndBranch32) {
+    switch (condition) {
+      case kEqual:
+        __ Tbz(i.InputRegister32(0), i.InputInt5(1), tlabel);
+        break;
+      case kNotEqual:
+        __ Tbnz(i.InputRegister32(0), i.InputInt5(1), tlabel);
+        break;
+      default:
+        UNREACHABLE();
+    }
+  } else if (opcode == kArm64TestAndBranch) {
+    switch (condition) {
+      case kEqual:
+        __ Tbz(i.InputRegister64(0), i.InputInt6(1), tlabel);
+        break;
+      case kNotEqual:
+        __ Tbnz(i.InputRegister64(0), i.InputInt6(1), tlabel);
+        break;
+      default:
+        UNREACHABLE();
+    }
+  } else {
+    switch (condition) {
+      case kUnorderedEqual:
+        // The "eq" condition will not catch the unordered case.
+        // The jump/fall through to false label will be used if the comparison
+        // was unordered.
+      case kEqual:
+        __ B(eq, tlabel);
+        break;
+      case kUnorderedNotEqual:
+        // Unordered or not equal can be tested with "ne" condtion.
+        // See ARMv8 manual C1.2.3 - Condition Code.
+      case kNotEqual:
+        __ B(ne, tlabel);
+        break;
+      case kSignedLessThan:
+        __ B(lt, tlabel);
+        break;
+      case kSignedGreaterThanOrEqual:
+        __ B(ge, tlabel);
+        break;
+      case kSignedLessThanOrEqual:
+        __ B(le, tlabel);
+        break;
+      case kSignedGreaterThan:
+        __ B(gt, tlabel);
+        break;
+      case kUnorderedLessThan:
+        // The "lo" condition will not catch the unordered case.
+        // The jump/fall through to false label will be used if the comparison
+        // was unordered.
+      case kUnsignedLessThan:
+        __ B(lo, tlabel);
+        break;
+      case kUnorderedGreaterThanOrEqual:
+        // Unordered, greater than or equal can be tested with "hs" condtion.
+        // See ARMv8 manual C1.2.3 - Condition Code.
+      case kUnsignedGreaterThanOrEqual:
+        __ B(hs, tlabel);
+        break;
+      case kUnorderedLessThanOrEqual:
+        // The "ls" condition will not catch the unordered case.
+        // The jump/fall through to false label will be used if the comparison
+        // was unordered.
+      case kUnsignedLessThanOrEqual:
+        __ B(ls, tlabel);
+        break;
+      case kUnorderedGreaterThan:
+        // Unordered or greater than can be tested with "hi" condtion.
+        // See ARMv8 manual C1.2.3 - Condition Code.
+      case kUnsignedGreaterThan:
+        __ B(hi, tlabel);
+        break;
+      case kOverflow:
+        __ B(vs, tlabel);
+        break;
+      case kNotOverflow:
+        __ B(vc, tlabel);
+        break;
+    }
   }
-  if (!fallthru) __ B(flabel);  // no fallthru to flabel.
-  __ Bind(&done);
+  if (!branch->fallthru) __ B(flabel);  // no fallthru to flabel.
+}
+
+
+void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+  if (!IsNextInAssemblyOrder(target)) __ B(GetLabel(target));
 }
 
 
@@ -620,7 +934,7 @@
       cc = vc;
       break;
   }
-  __ bind(&check);
+  __ Bind(&check);
   __ Cset(reg, cc);
   __ Bind(&done);
 }
@@ -650,28 +964,11 @@
     __ PushCalleeSavedRegisters();
     frame()->SetRegisterSaveAreaSize(20 * kPointerSize);
   } else if (descriptor->IsJSFunctionCall()) {
-    CompilationInfo* info = linkage()->info();
+    CompilationInfo* info = this->info();
     __ SetStackPointer(jssp);
     __ Prologue(info->IsCodePreAgingActive());
     frame()->SetRegisterSaveAreaSize(
         StandardFrameConstants::kFixedFrameSizeFromFp);
-
-    // Sloppy mode functions and builtins need to replace the receiver with the
-    // global proxy when called as functions (without an explicit receiver
-    // object).
-    // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
-    if (info->strict_mode() == SLOPPY && !info->is_native()) {
-      Label ok;
-      // +2 for return address and saved frame pointer.
-      int receiver_slot = info->scope()->num_parameters() + 2;
-      __ Ldr(x10, MemOperand(fp, receiver_slot * kXRegSize));
-      __ JumpIfNotRoot(x10, Heap::kUndefinedValueRootIndex, &ok);
-      __ Ldr(x10, GlobalObjectMemOperand());
-      __ Ldr(x10, FieldMemOperand(x10, GlobalObject::kGlobalProxyOffset));
-      __ Str(x10, MemOperand(fp, receiver_slot * kXRegSize));
-      __ Bind(&ok);
-    }
-
   } else {
     __ SetStackPointer(jssp);
     __ StubPrologue();
@@ -742,12 +1039,11 @@
       __ Str(temp, g.ToMemOperand(destination, masm()));
     }
   } else if (source->IsConstant()) {
-    ConstantOperand* constant_source = ConstantOperand::cast(source);
+    Constant src = g.ToConstant(ConstantOperand::cast(source));
     if (destination->IsRegister() || destination->IsStackSlot()) {
       UseScratchRegisterScope scope(masm());
       Register dst = destination->IsRegister() ? g.ToRegister(destination)
                                                : scope.AcquireX();
-      Constant src = g.ToConstant(source);
       if (src.type() == Constant::kHeapObject) {
         __ LoadObject(dst, src.ToHeapObject());
       } else {
@@ -756,15 +1052,29 @@
       if (destination->IsStackSlot()) {
         __ Str(dst, g.ToMemOperand(destination, masm()));
       }
-    } else if (destination->IsDoubleRegister()) {
-      FPRegister result = g.ToDoubleRegister(destination);
-      __ Fmov(result, g.ToDouble(constant_source));
+    } else if (src.type() == Constant::kFloat32) {
+      if (destination->IsDoubleRegister()) {
+        FPRegister dst = g.ToDoubleRegister(destination).S();
+        __ Fmov(dst, src.ToFloat32());
+      } else {
+        DCHECK(destination->IsDoubleStackSlot());
+        UseScratchRegisterScope scope(masm());
+        FPRegister temp = scope.AcquireS();
+        __ Fmov(temp, src.ToFloat32());
+        __ Str(temp, g.ToMemOperand(destination, masm()));
+      }
     } else {
-      DCHECK(destination->IsDoubleStackSlot());
-      UseScratchRegisterScope scope(masm());
-      FPRegister temp = scope.AcquireD();
-      __ Fmov(temp, g.ToDouble(constant_source));
-      __ Str(temp, g.ToMemOperand(destination, masm()));
+      DCHECK_EQ(Constant::kFloat64, src.type());
+      if (destination->IsDoubleRegister()) {
+        FPRegister dst = g.ToDoubleRegister(destination);
+        __ Fmov(dst, src.ToFloat64());
+      } else {
+        DCHECK(destination->IsDoubleStackSlot());
+        UseScratchRegisterScope scope(masm());
+        FPRegister temp = scope.AcquireD();
+        __ Fmov(temp, src.ToFloat64());
+        __ Str(temp, g.ToMemOperand(destination, masm()));
+      }
     }
   } else if (source->IsDoubleRegister()) {
     FPRegister src = g.ToDoubleRegister(source);
@@ -816,8 +1126,8 @@
     }
   } else if (source->IsStackSlot() || source->IsDoubleStackSlot()) {
     UseScratchRegisterScope scope(masm());
-    CPURegister temp_0 = scope.AcquireX();
-    CPURegister temp_1 = scope.AcquireX();
+    DoubleRegister temp_0 = scope.AcquireD();
+    DoubleRegister temp_1 = scope.AcquireD();
     MemOperand src = g.ToMemOperand(source, masm());
     MemOperand dst = g.ToMemOperand(destination, masm());
     __ Ldr(temp_0, src);
@@ -852,7 +1162,7 @@
 
 void CodeGenerator::EnsureSpaceForLazyDeopt() {
   int space_needed = Deoptimizer::patch_size();
-  if (!linkage()->info()->IsStub()) {
+  if (!info()->IsStub()) {
     // Ensure that we have enough space after the previous lazy-bailout
     // instruction for patching the code here.
     intptr_t current_pc = masm()->pc_offset();
diff --git a/src/compiler/arm64/instruction-codes-arm64.h b/src/compiler/arm64/instruction-codes-arm64.h
index 0a9a2ed..863451f 100644
--- a/src/compiler/arm64/instruction-codes-arm64.h
+++ b/src/compiler/arm64/instruction-codes-arm64.h
@@ -16,6 +16,8 @@
   V(Arm64Add32)                    \
   V(Arm64And)                      \
   V(Arm64And32)                    \
+  V(Arm64Bic)                      \
+  V(Arm64Bic32)                    \
   V(Arm64Cmp)                      \
   V(Arm64Cmp32)                    \
   V(Arm64Cmn)                      \
@@ -24,12 +26,24 @@
   V(Arm64Tst32)                    \
   V(Arm64Or)                       \
   V(Arm64Or32)                     \
-  V(Arm64Xor)                      \
-  V(Arm64Xor32)                    \
+  V(Arm64Orn)                      \
+  V(Arm64Orn32)                    \
+  V(Arm64Eor)                      \
+  V(Arm64Eor32)                    \
+  V(Arm64Eon)                      \
+  V(Arm64Eon32)                    \
   V(Arm64Sub)                      \
   V(Arm64Sub32)                    \
   V(Arm64Mul)                      \
   V(Arm64Mul32)                    \
+  V(Arm64Smull)                    \
+  V(Arm64Umull)                    \
+  V(Arm64Madd)                     \
+  V(Arm64Madd32)                   \
+  V(Arm64Msub)                     \
+  V(Arm64Msub32)                   \
+  V(Arm64Mneg)                     \
+  V(Arm64Mneg32)                   \
   V(Arm64Idiv)                     \
   V(Arm64Idiv32)                   \
   V(Arm64Udiv)                     \
@@ -42,16 +56,23 @@
   V(Arm64Not32)                    \
   V(Arm64Neg)                      \
   V(Arm64Neg32)                    \
-  V(Arm64Shl)                      \
-  V(Arm64Shl32)                    \
-  V(Arm64Shr)                      \
-  V(Arm64Shr32)                    \
-  V(Arm64Sar)                      \
-  V(Arm64Sar32)                    \
+  V(Arm64Lsl)                      \
+  V(Arm64Lsl32)                    \
+  V(Arm64Lsr)                      \
+  V(Arm64Lsr32)                    \
+  V(Arm64Asr)                      \
+  V(Arm64Asr32)                    \
   V(Arm64Ror)                      \
   V(Arm64Ror32)                    \
   V(Arm64Mov32)                    \
+  V(Arm64Sxtb32)                   \
+  V(Arm64Sxth32)                   \
   V(Arm64Sxtw)                     \
+  V(Arm64Ubfx)                     \
+  V(Arm64Ubfx32)                   \
+  V(Arm64TestAndBranch32)          \
+  V(Arm64TestAndBranch)            \
+  V(Arm64CompareAndBranch32)       \
   V(Arm64Claim)                    \
   V(Arm64Poke)                     \
   V(Arm64PokePairZero)             \
@@ -63,6 +84,12 @@
   V(Arm64Float64Div)               \
   V(Arm64Float64Mod)               \
   V(Arm64Float64Sqrt)              \
+  V(Arm64Float64Floor)             \
+  V(Arm64Float64Ceil)              \
+  V(Arm64Float64RoundTruncate)     \
+  V(Arm64Float64RoundTiesAway)     \
+  V(Arm64Float32ToFloat64)         \
+  V(Arm64Float64ToFloat32)         \
   V(Arm64Float64ToInt32)           \
   V(Arm64Float64ToUint32)          \
   V(Arm64Int32ToFloat64)           \
@@ -97,9 +124,13 @@
 // I = immediate (handle, external, int32)
 // MRI = [register + immediate]
 // MRR = [register + register]
-#define TARGET_ADDRESSING_MODE_LIST(V) \
-  V(MRI) /* [%r0 + K] */               \
-  V(MRR) /* [%r0 + %r1] */
+#define TARGET_ADDRESSING_MODE_LIST(V)  \
+  V(MRI)              /* [%r0 + K] */   \
+  V(MRR)              /* [%r0 + %r1] */ \
+  V(Operand2_R_LSL_I) /* %r0 LSL K */   \
+  V(Operand2_R_LSR_I) /* %r0 LSR K */   \
+  V(Operand2_R_ASR_I) /* %r0 ASR K */   \
+  V(Operand2_R_ROR_I) /* %r0 ROR K */
 
 }  // namespace internal
 }  // namespace compiler
diff --git a/src/compiler/arm64/instruction-selector-arm64-unittest.cc b/src/compiler/arm64/instruction-selector-arm64-unittest.cc
deleted file mode 100644
index b5562c2..0000000
--- a/src/compiler/arm64/instruction-selector-arm64-unittest.cc
+++ /dev/null
@@ -1,1121 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <list>
-
-#include "src/compiler/instruction-selector-unittest.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-namespace {
-
-typedef RawMachineAssembler::Label MLabel;
-
-template <typename T>
-struct MachInst {
-  T constructor;
-  const char* constructor_name;
-  ArchOpcode arch_opcode;
-  MachineType machine_type;
-};
-
-typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1;
-typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2;
-
-
-template <typename T>
-std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) {
-  return os << mi.constructor_name;
-}
-
-
-// Helper to build Int32Constant or Int64Constant depending on the given
-// machine type.
-Node* BuildConstant(InstructionSelectorTest::StreamBuilder& m, MachineType type,
-                    int64_t value) {
-  switch (type) {
-    case kMachInt32:
-      return m.Int32Constant(value);
-      break;
-
-    case kMachInt64:
-      return m.Int64Constant(value);
-      break;
-
-    default:
-      UNIMPLEMENTED();
-  }
-  return NULL;
-}
-
-
-// ARM64 logical instructions.
-static const MachInst2 kLogicalInstructions[] = {
-    {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32},
-    {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64},
-    {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32},
-    {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, kMachInt64},
-    {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Xor32, kMachInt32},
-    {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Xor, kMachInt64}};
-
-
-// ARM64 logical immediates: contiguous set bits, rotated about a power of two
-// sized block. The block is then duplicated across the word. Below is a random
-// subset of the 32-bit immediates.
-static const uint32_t kLogicalImmediates[] = {
-    0x00000002, 0x00000003, 0x00000070, 0x00000080, 0x00000100, 0x000001c0,
-    0x00000300, 0x000007e0, 0x00003ffc, 0x00007fc0, 0x0003c000, 0x0003f000,
-    0x0003ffc0, 0x0003fff8, 0x0007ff00, 0x0007ffe0, 0x000e0000, 0x001e0000,
-    0x001ffffc, 0x003f0000, 0x003f8000, 0x00780000, 0x007fc000, 0x00ff0000,
-    0x01800000, 0x01800180, 0x01f801f8, 0x03fe0000, 0x03ffffc0, 0x03fffffc,
-    0x06000000, 0x07fc0000, 0x07ffc000, 0x07ffffc0, 0x07ffffe0, 0x0ffe0ffe,
-    0x0ffff800, 0x0ffffff0, 0x0fffffff, 0x18001800, 0x1f001f00, 0x1f801f80,
-    0x30303030, 0x3ff03ff0, 0x3ff83ff8, 0x3fff0000, 0x3fff8000, 0x3fffffc0,
-    0x70007000, 0x7f7f7f7f, 0x7fc00000, 0x7fffffc0, 0x8000001f, 0x800001ff,
-    0x81818181, 0x9fff9fff, 0xc00007ff, 0xc0ffffff, 0xdddddddd, 0xe00001ff,
-    0xe00003ff, 0xe007ffff, 0xefffefff, 0xf000003f, 0xf001f001, 0xf3fff3ff,
-    0xf800001f, 0xf80fffff, 0xf87ff87f, 0xfbfbfbfb, 0xfc00001f, 0xfc0000ff,
-    0xfc0001ff, 0xfc03fc03, 0xfe0001ff, 0xff000001, 0xff03ff03, 0xff800000,
-    0xff800fff, 0xff801fff, 0xff87ffff, 0xffc0003f, 0xffc007ff, 0xffcfffcf,
-    0xffe00003, 0xffe1ffff, 0xfff0001f, 0xfff07fff, 0xfff80007, 0xfff87fff,
-    0xfffc00ff, 0xfffe07ff, 0xffff00ff, 0xffffc001, 0xfffff007, 0xfffff3ff,
-    0xfffff807, 0xfffff9ff, 0xfffffc0f, 0xfffffeff};
-
-
-// ARM64 arithmetic instructions.
-static const MachInst2 kAddSubInstructions[] = {
-    {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32},
-    {&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64},
-    {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32},
-    {&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, kMachInt64}};
-
-
-// ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12.
-// Below is a combination of a random subset and some edge values.
-static const int32_t kAddSubImmediates[] = {
-    0,        1,        69,       493,      599,      701,      719,
-    768,      818,      842,      945,      1246,     1286,     1429,
-    1669,     2171,     2179,     2182,     2254,     2334,     2338,
-    2343,     2396,     2449,     2610,     2732,     2855,     2876,
-    2944,     3377,     3458,     3475,     3476,     3540,     3574,
-    3601,     3813,     3871,     3917,     4095,     4096,     16384,
-    364544,   462848,   970752,   1523712,  1863680,  2363392,  3219456,
-    3280896,  4247552,  4526080,  4575232,  4960256,  5505024,  5894144,
-    6004736,  6193152,  6385664,  6795264,  7114752,  7233536,  7348224,
-    7499776,  7573504,  7729152,  8634368,  8937472,  9465856,  10354688,
-    10682368, 11059200, 11460608, 13168640, 13176832, 14336000, 15028224,
-    15597568, 15892480, 16773120};
-
-
-// ARM64 flag setting data processing instructions.
-static const MachInst2 kDPFlagSetInstructions[] = {
-    {&RawMachineAssembler::Word32And, "Word32And", kArm64Tst32, kMachInt32},
-    {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Cmn32, kMachInt32},
-    {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Cmp32, kMachInt32}};
-
-
-// ARM64 arithmetic with overflow instructions.
-static const MachInst2 kOvfAddSubInstructions[] = {
-    {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow",
-     kArm64Add32, kMachInt32},
-    {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow",
-     kArm64Sub32, kMachInt32}};
-
-
-// ARM64 shift instructions.
-static const MachInst2 kShiftInstructions[] = {
-    {&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Shl32, kMachInt32},
-    {&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Shl, kMachInt64},
-    {&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Shr32, kMachInt32},
-    {&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Shr, kMachInt64},
-    {&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Sar32, kMachInt32},
-    {&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Sar, kMachInt64},
-    {&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32},
-    {&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64}};
-
-
-// ARM64 Mul/Div instructions.
-static const MachInst2 kMulDivInstructions[] = {
-    {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32},
-    {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64},
-    {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32},
-    {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, kMachInt64},
-    {&RawMachineAssembler::Int32UDiv, "Int32UDiv", kArm64Udiv32, kMachInt32},
-    {&RawMachineAssembler::Int64UDiv, "Int64UDiv", kArm64Udiv, kMachInt64}};
-
-
-// ARM64 FP arithmetic instructions.
-static const MachInst2 kFPArithInstructions[] = {
-    {&RawMachineAssembler::Float64Add, "Float64Add", kArm64Float64Add,
-     kMachFloat64},
-    {&RawMachineAssembler::Float64Sub, "Float64Sub", kArm64Float64Sub,
-     kMachFloat64},
-    {&RawMachineAssembler::Float64Mul, "Float64Mul", kArm64Float64Mul,
-     kMachFloat64},
-    {&RawMachineAssembler::Float64Div, "Float64Div", kArm64Float64Div,
-     kMachFloat64}};
-
-
-struct FPCmp {
-  MachInst2 mi;
-  FlagsCondition cond;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const FPCmp& cmp) {
-  return os << cmp.mi;
-}
-
-
-// ARM64 FP comparison instructions.
-static const FPCmp kFPCmpInstructions[] = {
-    {{&RawMachineAssembler::Float64Equal, "Float64Equal", kArm64Float64Cmp,
-      kMachFloat64},
-     kUnorderedEqual},
-    {{&RawMachineAssembler::Float64LessThan, "Float64LessThan",
-      kArm64Float64Cmp, kMachFloat64},
-     kUnorderedLessThan},
-    {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
-      kArm64Float64Cmp, kMachFloat64},
-     kUnorderedLessThanOrEqual}};
-
-
-struct Conversion {
-  // The machine_type field in MachInst1 represents the destination type.
-  MachInst1 mi;
-  MachineType src_machine_type;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const Conversion& conv) {
-  return os << conv.mi;
-}
-
-
-// ARM64 type conversion instructions.
-static const Conversion kConversionInstructions[] = {
-    {{&RawMachineAssembler::ChangeInt32ToInt64, "ChangeInt32ToInt64",
-      kArm64Sxtw, kMachInt64},
-     kMachInt32},
-    {{&RawMachineAssembler::ChangeUint32ToUint64, "ChangeUint32ToUint64",
-      kArm64Mov32, kMachUint64},
-     kMachUint32},
-    {{&RawMachineAssembler::TruncateInt64ToInt32, "TruncateInt64ToInt32",
-      kArm64Mov32, kMachInt32},
-     kMachInt64},
-    {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64",
-      kArm64Int32ToFloat64, kMachFloat64},
-     kMachInt32},
-    {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64",
-      kArm64Uint32ToFloat64, kMachFloat64},
-     kMachUint32},
-    {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32",
-      kArm64Float64ToInt32, kMachInt32},
-     kMachFloat64},
-    {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32",
-      kArm64Float64ToUint32, kMachUint32},
-     kMachFloat64}};
-
-}  // namespace
-
-
-// -----------------------------------------------------------------------------
-// Logical instructions.
-
-
-typedef InstructionSelectorTestWithParam<MachInst2>
-    InstructionSelectorLogicalTest;
-
-
-TEST_P(InstructionSelectorLogicalTest, Parameter) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  StreamBuilder m(this, type, type, type);
-  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorLogicalTest, Immediate) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  // TODO(all): Add support for testing 64-bit immediates.
-  if (type == kMachInt32) {
-    // Immediate on the right.
-    TRACED_FOREACH(int32_t, imm, kLogicalImmediates) {
-      StreamBuilder m(this, type, type);
-      m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
-      Stream s = m.Build();
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-      ASSERT_EQ(2U, s[0]->InputCount());
-      EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-      EXPECT_EQ(1U, s[0]->OutputCount());
-    }
-
-    // Immediate on the left; all logical ops should commute.
-    TRACED_FOREACH(int32_t, imm, kLogicalImmediates) {
-      StreamBuilder m(this, type, type);
-      m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)));
-      Stream s = m.Build();
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-      ASSERT_EQ(2U, s[0]->InputCount());
-      EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-      EXPECT_EQ(1U, s[0]->OutputCount());
-    }
-  }
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest,
-                        ::testing::ValuesIn(kLogicalInstructions));
-
-
-// -----------------------------------------------------------------------------
-// Add and Sub instructions.
-
-typedef InstructionSelectorTestWithParam<MachInst2>
-    InstructionSelectorAddSubTest;
-
-
-TEST_P(InstructionSelectorAddSubTest, Parameter) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  StreamBuilder m(this, type, type, type);
-  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorAddSubTest, ImmediateOnRight) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, type, type);
-    m.Return((m.*dpi.constructor)(m.Parameter(0), BuildConstant(m, type, imm)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
-    EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-TEST_P(InstructionSelectorAddSubTest, ImmediateOnLeft) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, type, type);
-    m.Return((m.*dpi.constructor)(BuildConstant(m, type, imm), m.Parameter(0)));
-    Stream s = m.Build();
-
-    // Add can support an immediate on the left by commuting, but Sub can't
-    // commute. We test zero-on-left Sub later.
-    if (strstr(dpi.constructor_name, "Add") != NULL) {
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-      ASSERT_EQ(2U, s[0]->InputCount());
-      EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
-      EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
-      EXPECT_EQ(1U, s[0]->OutputCount());
-    }
-  }
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest,
-                        ::testing::ValuesIn(kAddSubInstructions));
-
-
-TEST_F(InstructionSelectorTest, SubZeroOnLeft) {
-  // Subtraction with zero on the left maps to Neg.
-  {
-    // 32-bit subtract.
-    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-    m.Return(m.Int32Sub(m.Int32Constant(0), m.Parameter(0)));
-    Stream s = m.Build();
-
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Neg32, s[0]->arch_opcode());
-    EXPECT_EQ(1U, s[0]->InputCount());
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-  {
-    // 64-bit subtract.
-    StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
-    m.Return(m.Int64Sub(m.Int64Constant(0), m.Parameter(0)));
-    Stream s = m.Build();
-
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Neg, s[0]->arch_opcode());
-    EXPECT_EQ(1U, s[0]->InputCount());
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// Data processing controlled branches.
-
-
-typedef InstructionSelectorTestWithParam<MachInst2>
-    InstructionSelectorDPFlagSetTest;
-
-
-TEST_P(InstructionSelectorDPFlagSetTest, BranchWithParameters) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  StreamBuilder m(this, type, type, type);
-  MLabel a, b;
-  m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)), &a, &b);
-  m.Bind(&a);
-  m.Return(m.Int32Constant(1));
-  m.Bind(&b);
-  m.Return(m.Int32Constant(0));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-  EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
-                        InstructionSelectorDPFlagSetTest,
-                        ::testing::ValuesIn(kDPFlagSetInstructions));
-
-
-TEST_F(InstructionSelectorTest, AndBranchWithImmediateOnRight) {
-  TRACED_FOREACH(int32_t, imm, kLogicalImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(imm)), &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnRight) {
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch(m.Int32Add(m.Parameter(0), m.Int32Constant(imm)), &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, SubBranchWithImmediateOnRight) {
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm)), &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, AndBranchWithImmediateOnLeft) {
-  TRACED_FOREACH(int32_t, imm, kLogicalImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch(m.Word32And(m.Int32Constant(imm), m.Parameter(0)), &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
-    ASSERT_LE(1U, s[0]->InputCount());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnLeft) {
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    m.Branch(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)), &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(1));
-    m.Bind(&b);
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
-    ASSERT_LE(1U, s[0]->InputCount());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// Add and subtract instructions with overflow.
-
-
-typedef InstructionSelectorTestWithParam<MachInst2>
-    InstructionSelectorOvfAddSubTest;
-
-
-TEST_P(InstructionSelectorOvfAddSubTest, OvfParameter) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  StreamBuilder m(this, type, type, type);
-  m.Return(
-      m.Projection(1, (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_LE(1U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-  EXPECT_EQ(kOverflow, s[0]->flags_condition());
-}
-
-
-TEST_P(InstructionSelectorOvfAddSubTest, OvfImmediateOnRight) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, type, type);
-    m.Return(m.Projection(
-        1, (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_LE(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorOvfAddSubTest, ValParameter) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  StreamBuilder m(this, type, type, type);
-  m.Return(
-      m.Projection(0, (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_LE(1U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
-}
-
-
-TEST_P(InstructionSelectorOvfAddSubTest, ValImmediateOnRight) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, type, type);
-    m.Return(m.Projection(
-        0, (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_LE(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
-  }
-}
-
-
-TEST_P(InstructionSelectorOvfAddSubTest, BothParameter) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  StreamBuilder m(this, type, type, type);
-  Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1));
-  m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
-  Stream s = m.Build();
-  ASSERT_LE(1U, s.size());
-  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(2U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-  EXPECT_EQ(kOverflow, s[0]->flags_condition());
-}
-
-
-TEST_P(InstructionSelectorOvfAddSubTest, BothImmediateOnRight) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, type, type);
-    Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
-    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
-    Stream s = m.Build();
-    ASSERT_LE(1U, s.size());
-    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(2U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-}
-
-
-TEST_P(InstructionSelectorOvfAddSubTest, BranchWithParameters) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  StreamBuilder m(this, type, type, type);
-  MLabel a, b;
-  Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1));
-  m.Branch(m.Projection(1, n), &a, &b);
-  m.Bind(&a);
-  m.Return(m.Int32Constant(0));
-  m.Bind(&b);
-  m.Return(m.Projection(0, n));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(4U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-  EXPECT_EQ(kOverflow, s[0]->flags_condition());
-}
-
-
-TEST_P(InstructionSelectorOvfAddSubTest, BranchWithImmediateOnRight) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, type, type);
-    MLabel a, b;
-    Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
-    m.Branch(m.Projection(1, n), &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(0));
-    m.Bind(&b);
-    m.Return(m.Projection(0, n));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-    ASSERT_EQ(4U, s[0]->InputCount());
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
-                        InstructionSelectorOvfAddSubTest,
-                        ::testing::ValuesIn(kOvfAddSubInstructions));
-
-
-TEST_F(InstructionSelectorTest, OvfFlagAddImmediateOnLeft) {
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Projection(
-        1, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0))));
-    Stream s = m.Build();
-
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
-    EXPECT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_LE(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, OvfValAddImmediateOnLeft) {
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Projection(
-        0, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0))));
-    Stream s = m.Build();
-
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_LE(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, OvfBothAddImmediateOnLeft) {
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0));
-    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
-    Stream s = m.Build();
-
-    ASSERT_LE(1U, s.size());
-    EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(2U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, OvfBranchWithImmediateOnLeft) {
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    MLabel a, b;
-    Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0));
-    m.Branch(m.Projection(1, n), &a, &b);
-    m.Bind(&a);
-    m.Return(m.Int32Constant(0));
-    m.Bind(&b);
-    m.Return(m.Projection(0, n));
-    Stream s = m.Build();
-
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
-    ASSERT_EQ(4U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
-    EXPECT_EQ(kOverflow, s[0]->flags_condition());
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// Shift instructions.
-
-
-typedef InstructionSelectorTestWithParam<MachInst2>
-    InstructionSelectorShiftTest;
-
-
-TEST_P(InstructionSelectorShiftTest, Parameter) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  StreamBuilder m(this, type, type, type);
-  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorShiftTest, Immediate) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) {
-    StreamBuilder m(this, type, type);
-    m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(2U, s[0]->InputCount());
-    EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
-                        ::testing::ValuesIn(kShiftInstructions));
-
-
-// -----------------------------------------------------------------------------
-// Mul and Div instructions.
-
-
-typedef InstructionSelectorTestWithParam<MachInst2>
-    InstructionSelectorMulDivTest;
-
-
-TEST_P(InstructionSelectorMulDivTest, Parameter) {
-  const MachInst2 dpi = GetParam();
-  const MachineType type = dpi.machine_type;
-  StreamBuilder m(this, type, type, type);
-  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMulDivTest,
-                        ::testing::ValuesIn(kMulDivInstructions));
-
-
-// -----------------------------------------------------------------------------
-// Floating point instructions.
-
-typedef InstructionSelectorTestWithParam<MachInst2>
-    InstructionSelectorFPArithTest;
-
-
-TEST_P(InstructionSelectorFPArithTest, Parameter) {
-  const MachInst2 fpa = GetParam();
-  StreamBuilder m(this, fpa.machine_type, fpa.machine_type, fpa.machine_type);
-  m.Return((m.*fpa.constructor)(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(fpa.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest,
-                        ::testing::ValuesIn(kFPArithInstructions));
-
-
-typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest;
-
-
-TEST_P(InstructionSelectorFPCmpTest, Parameter) {
-  const FPCmp cmp = GetParam();
-  StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type);
-  m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-  EXPECT_EQ(cmp.cond, s[0]->flags_condition());
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPCmpTest,
-                        ::testing::ValuesIn(kFPCmpInstructions));
-
-
-// -----------------------------------------------------------------------------
-// Conversions.
-
-typedef InstructionSelectorTestWithParam<Conversion>
-    InstructionSelectorConversionTest;
-
-
-TEST_P(InstructionSelectorConversionTest, Parameter) {
-  const Conversion conv = GetParam();
-  StreamBuilder m(this, conv.mi.machine_type, conv.src_machine_type);
-  m.Return((m.*conv.mi.constructor)(m.Parameter(0)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(conv.mi.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(1U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
-                        InstructionSelectorConversionTest,
-                        ::testing::ValuesIn(kConversionInstructions));
-
-
-// -----------------------------------------------------------------------------
-// Memory access instructions.
-
-
-namespace {
-
-struct MemoryAccess {
-  MachineType type;
-  ArchOpcode ldr_opcode;
-  ArchOpcode str_opcode;
-  const int32_t immediates[20];
-};
-
-
-std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
-  OStringStream ost;
-  ost << memacc.type;
-  return os << ost.c_str();
-}
-
-}  // namespace
-
-
-static const MemoryAccess kMemoryAccesses[] = {
-    {kMachInt8, kArm64Ldrsb, kArm64Strb,
-     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001,
-      2121, 2442, 4093, 4094, 4095}},
-    {kMachUint8, kArm64Ldrb, kArm64Strb,
-     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001,
-      2121, 2442, 4093, 4094, 4095}},
-    {kMachInt16, kArm64Ldrsh, kArm64Strh,
-     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098,
-      4100, 4242, 6786, 8188, 8190}},
-    {kMachUint16, kArm64Ldrh, kArm64Strh,
-     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098,
-      4100, 4242, 6786, 8188, 8190}},
-    {kMachInt32, kArm64LdrW, kArm64StrW,
-     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192,
-      8196, 3276, 3280, 16376, 16380}},
-    {kMachUint32, kArm64LdrW, kArm64StrW,
-     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192,
-      8196, 3276, 3280, 16376, 16380}},
-    {kMachInt64, kArm64Ldr, kArm64Str,
-     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192,
-      8200, 16384, 16392, 32752, 32760}},
-    {kMachUint64, kArm64Ldr, kArm64Str,
-     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192,
-      8200, 16384, 16392, 32752, 32760}},
-    {kMachFloat32, kArm64LdrS, kArm64StrS,
-     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192,
-      8196, 3276, 3280, 16376, 16380}},
-    {kMachFloat64, kArm64LdrD, kArm64StrD,
-     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192,
-      8200, 16384, 16392, 32752, 32760}}};
-
-
-typedef InstructionSelectorTestWithParam<MemoryAccess>
-    InstructionSelectorMemoryAccessTest;
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
-  const MemoryAccess memacc = GetParam();
-  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
-  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_MRR, s[0]->addressing_mode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
-  const MemoryAccess memacc = GetParam();
-  TRACED_FOREACH(int32_t, index, memacc.immediates) {
-    StreamBuilder m(this, memacc.type, kMachPtr);
-    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
-    EXPECT_EQ(2U, s[0]->InputCount());
-    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
-    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
-    ASSERT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
-  const MemoryAccess memacc = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
-  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
-  m.Return(m.Int32Constant(0));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(kMode_MRR, s[0]->addressing_mode());
-  EXPECT_EQ(3U, s[0]->InputCount());
-  EXPECT_EQ(0U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
-  const MemoryAccess memacc = GetParam();
-  TRACED_FOREACH(int32_t, index, memacc.immediates) {
-    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
-    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
-            m.Parameter(1));
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
-    EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
-    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(0U, s[0]->OutputCount());
-  }
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
-                        InstructionSelectorMemoryAccessTest,
-                        ::testing::ValuesIn(kMemoryAccesses));
-
-
-// -----------------------------------------------------------------------------
-// Comparison instructions.
-
-static const MachInst2 kComparisonInstructions[] = {
-    {&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, kMachInt32},
-    {&RawMachineAssembler::Word64Equal, "Word64Equal", kArm64Cmp, kMachInt64},
-};
-
-
-typedef InstructionSelectorTestWithParam<MachInst2>
-    InstructionSelectorComparisonTest;
-
-
-TEST_P(InstructionSelectorComparisonTest, WithParameters) {
-  const MachInst2 cmp = GetParam();
-  const MachineType type = cmp.machine_type;
-  StreamBuilder m(this, type, type, type);
-  m.Return((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-  EXPECT_EQ(kEqual, s[0]->flags_condition());
-}
-
-
-TEST_P(InstructionSelectorComparisonTest, WithImmediate) {
-  const MachInst2 cmp = GetParam();
-  const MachineType type = cmp.machine_type;
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    // Compare with 0 are turned into tst instruction.
-    if (imm == 0) continue;
-    StreamBuilder m(this, type, type);
-    m.Return((m.*cmp.constructor)(m.Parameter(0), BuildConstant(m, type, imm)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
-    EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
-    // Compare with 0 are turned into tst instruction.
-    if (imm == 0) continue;
-    StreamBuilder m(this, type, type);
-    m.Return((m.*cmp.constructor)(m.Parameter(0), BuildConstant(m, type, imm)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
-    EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-}
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
-                        InstructionSelectorComparisonTest,
-                        ::testing::ValuesIn(kComparisonInstructions));
-
-
-TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
-  {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-  {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, Word64EqualWithZero) {
-  {
-    StreamBuilder m(this, kMachInt64, kMachInt64);
-    m.Return(m.Word64Equal(m.Parameter(0), m.Int64Constant(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-  {
-    StreamBuilder m(this, kMachInt64, kMachInt64);
-    m.Return(m.Word64Equal(m.Int64Constant(0), m.Parameter(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
-    EXPECT_EQ(kEqual, s[0]->flags_condition());
-  }
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc
index 472ce6f..72661af 100644
--- a/src/compiler/arm64/instruction-selector-arm64.cc
+++ b/src/compiler/arm64/instruction-selector-arm64.cc
@@ -44,6 +44,10 @@
       value = OpParameter<int64_t>(node);
     else
       return false;
+    return CanBeImmediate(value, mode);
+  }
+
+  bool CanBeImmediate(int64_t value, ImmediateMode mode) {
     unsigned ignored;
     switch (mode) {
       case kLogical32Imm:
@@ -55,7 +59,6 @@
         return Assembler::IsImmLogical(static_cast<uint64_t>(value), 64,
                                        &ignored, &ignored, &ignored);
       case kArithmeticImm:
-        // TODO(dcarney): -values can be handled by instruction swapping
         return Assembler::IsImmAddSub(value);
       case kShift32Imm:
         return 0 <= value && value < 32;
@@ -83,6 +86,14 @@
 };
 
 
+static void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
+                           Node* node) {
+  Arm64OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)));
+}
+
+
 static void VisitRRR(InstructionSelector* selector, ArchOpcode opcode,
                      Node* node) {
   Arm64OperandGenerator g(selector);
@@ -110,6 +121,51 @@
 }
 
 
+template <typename Matcher>
+static bool TryMatchShift(InstructionSelector* selector, Node* node,
+                          InstructionCode* opcode, IrOpcode::Value shift_opcode,
+                          ImmediateMode imm_mode,
+                          AddressingMode addressing_mode) {
+  if (node->opcode() != shift_opcode) return false;
+  Arm64OperandGenerator g(selector);
+  Matcher m(node);
+  if (g.CanBeImmediate(m.right().node(), imm_mode)) {
+    *opcode |= AddressingModeField::encode(addressing_mode);
+    return true;
+  }
+  return false;
+}
+
+
+static bool TryMatchAnyShift(InstructionSelector* selector, Node* node,
+                             InstructionCode* opcode, bool try_ror) {
+  return TryMatchShift<Int32BinopMatcher>(selector, node, opcode,
+                                          IrOpcode::kWord32Shl, kShift32Imm,
+                                          kMode_Operand2_R_LSL_I) ||
+         TryMatchShift<Int32BinopMatcher>(selector, node, opcode,
+                                          IrOpcode::kWord32Shr, kShift32Imm,
+                                          kMode_Operand2_R_LSR_I) ||
+         TryMatchShift<Int32BinopMatcher>(selector, node, opcode,
+                                          IrOpcode::kWord32Sar, kShift32Imm,
+                                          kMode_Operand2_R_ASR_I) ||
+         (try_ror && TryMatchShift<Int32BinopMatcher>(
+                         selector, node, opcode, IrOpcode::kWord32Ror,
+                         kShift32Imm, kMode_Operand2_R_ROR_I)) ||
+         TryMatchShift<Int64BinopMatcher>(selector, node, opcode,
+                                          IrOpcode::kWord64Shl, kShift64Imm,
+                                          kMode_Operand2_R_LSL_I) ||
+         TryMatchShift<Int64BinopMatcher>(selector, node, opcode,
+                                          IrOpcode::kWord64Shr, kShift64Imm,
+                                          kMode_Operand2_R_LSR_I) ||
+         TryMatchShift<Int64BinopMatcher>(selector, node, opcode,
+                                          IrOpcode::kWord64Sar, kShift64Imm,
+                                          kMode_Operand2_R_ASR_I) ||
+         (try_ror && TryMatchShift<Int64BinopMatcher>(
+                         selector, node, opcode, IrOpcode::kWord64Ror,
+                         kShift64Imm, kMode_Operand2_R_ROR_I));
+}
+
+
 // Shared routine for multiple binary operations.
 template <typename Matcher>
 static void VisitBinop(InstructionSelector* selector, Node* node,
@@ -121,9 +177,32 @@
   size_t input_count = 0;
   InstructionOperand* outputs[2];
   size_t output_count = 0;
+  bool try_ror_operand = true;
 
-  inputs[input_count++] = g.UseRegister(m.left().node());
-  inputs[input_count++] = g.UseOperand(m.right().node(), operand_mode);
+  if (m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() || m.IsInt64Sub()) {
+    try_ror_operand = false;
+  }
+
+  if (g.CanBeImmediate(m.right().node(), operand_mode)) {
+    inputs[input_count++] = g.UseRegister(m.left().node());
+    inputs[input_count++] = g.UseImmediate(m.right().node());
+  } else if (TryMatchAnyShift(selector, m.right().node(), &opcode,
+                              try_ror_operand)) {
+    Matcher m_shift(m.right().node());
+    inputs[input_count++] = g.UseRegister(m.left().node());
+    inputs[input_count++] = g.UseRegister(m_shift.left().node());
+    inputs[input_count++] = g.UseImmediate(m_shift.right().node());
+  } else if (m.HasProperty(Operator::kCommutative) &&
+             TryMatchAnyShift(selector, m.left().node(), &opcode,
+                              try_ror_operand)) {
+    Matcher m_shift(m.left().node());
+    inputs[input_count++] = g.UseRegister(m.right().node());
+    inputs[input_count++] = g.UseRegister(m_shift.left().node());
+    inputs[input_count++] = g.UseImmediate(m_shift.right().node());
+  } else {
+    inputs[input_count++] = g.UseRegister(m.left().node());
+    inputs[input_count++] = g.UseRegister(m.right().node());
+  }
 
   if (cont->IsBranch()) {
     inputs[input_count++] = g.Label(cont->true_block());
@@ -155,6 +234,22 @@
 }
 
 
+template <typename Matcher>
+static void VisitAddSub(InstructionSelector* selector, Node* node,
+                        ArchOpcode opcode, ArchOpcode negate_opcode) {
+  Arm64OperandGenerator g(selector);
+  Matcher m(node);
+  if (m.right().HasValue() && (m.right().Value() < 0) &&
+      g.CanBeImmediate(-m.right().Value(), kArithmeticImm)) {
+    selector->Emit(negate_opcode, g.DefineAsRegister(node),
+                   g.UseRegister(m.left().node()),
+                   g.TempImmediate(-m.right().Value()));
+  } else {
+    VisitBinop<Matcher>(selector, node, opcode, kArithmeticImm);
+  }
+}
+
+
 void InstructionSelector::VisitLoad(Node* node) {
   MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
   MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
@@ -267,75 +362,339 @@
 }
 
 
+void InstructionSelector::VisitCheckedLoad(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  Arm64OperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepWord8:
+      opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
+      break;
+    case kRepWord16:
+      opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
+      break;
+    case kRepWord32:
+      opcode = kCheckedLoadWord32;
+      break;
+    case kRepFloat32:
+      opcode = kCheckedLoadFloat32;
+      break;
+    case kRepFloat64:
+      opcode = kCheckedLoadFloat64;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer),
+       g.UseRegister(offset), g.UseOperand(length, kArithmeticImm));
+}
+
+
+void InstructionSelector::VisitCheckedStore(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  Arm64OperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  Node* const value = node->InputAt(3);
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepWord8:
+      opcode = kCheckedStoreWord8;
+      break;
+    case kRepWord16:
+      opcode = kCheckedStoreWord16;
+      break;
+    case kRepWord32:
+      opcode = kCheckedStoreWord32;
+      break;
+    case kRepFloat32:
+      opcode = kCheckedStoreFloat32;
+      break;
+    case kRepFloat64:
+      opcode = kCheckedStoreFloat64;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  Emit(opcode, nullptr, g.UseRegister(buffer), g.UseRegister(offset),
+       g.UseOperand(length, kArithmeticImm), g.UseRegister(value));
+}
+
+
+template <typename Matcher>
+static void VisitLogical(InstructionSelector* selector, Node* node, Matcher* m,
+                         ArchOpcode opcode, bool left_can_cover,
+                         bool right_can_cover, ImmediateMode imm_mode) {
+  Arm64OperandGenerator g(selector);
+
+  // Map instruction to equivalent operation with inverted right input.
+  ArchOpcode inv_opcode = opcode;
+  switch (opcode) {
+    case kArm64And32:
+      inv_opcode = kArm64Bic32;
+      break;
+    case kArm64And:
+      inv_opcode = kArm64Bic;
+      break;
+    case kArm64Or32:
+      inv_opcode = kArm64Orn32;
+      break;
+    case kArm64Or:
+      inv_opcode = kArm64Orn;
+      break;
+    case kArm64Eor32:
+      inv_opcode = kArm64Eon32;
+      break;
+    case kArm64Eor:
+      inv_opcode = kArm64Eon;
+      break;
+    default:
+      UNREACHABLE();
+  }
+
+  // Select Logical(y, ~x) for Logical(Xor(x, -1), y).
+  if ((m->left().IsWord32Xor() || m->left().IsWord64Xor()) && left_can_cover) {
+    Matcher mleft(m->left().node());
+    if (mleft.right().Is(-1)) {
+      // TODO(all): support shifted operand on right.
+      selector->Emit(inv_opcode, g.DefineAsRegister(node),
+                     g.UseRegister(m->right().node()),
+                     g.UseRegister(mleft.left().node()));
+      return;
+    }
+  }
+
+  // Select Logical(x, ~y) for Logical(x, Xor(y, -1)).
+  if ((m->right().IsWord32Xor() || m->right().IsWord64Xor()) &&
+      right_can_cover) {
+    Matcher mright(m->right().node());
+    if (mright.right().Is(-1)) {
+      // TODO(all): support shifted operand on right.
+      selector->Emit(inv_opcode, g.DefineAsRegister(node),
+                     g.UseRegister(m->left().node()),
+                     g.UseRegister(mright.left().node()));
+      return;
+    }
+  }
+
+  if (m->IsWord32Xor() && m->right().Is(-1)) {
+    selector->Emit(kArm64Not32, g.DefineAsRegister(node),
+                   g.UseRegister(m->left().node()));
+  } else if (m->IsWord64Xor() && m->right().Is(-1)) {
+    selector->Emit(kArm64Not, g.DefineAsRegister(node),
+                   g.UseRegister(m->left().node()));
+  } else {
+    VisitBinop<Matcher>(selector, node, opcode, imm_mode);
+  }
+}
+
+
 void InstructionSelector::VisitWord32And(Node* node) {
-  VisitBinop<Int32BinopMatcher>(this, node, kArm64And32, kLogical32Imm);
+  Arm64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) &&
+      m.right().HasValue()) {
+    uint32_t mask = m.right().Value();
+    uint32_t mask_width = base::bits::CountPopulation32(mask);
+    uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
+    if ((mask_width != 0) && (mask_msb + mask_width == 32)) {
+      // The mask must be contiguous, and occupy the least-significant bits.
+      DCHECK_EQ(0, base::bits::CountTrailingZeros32(mask));
+
+      // Select Ubfx for And(Shr(x, imm), mask) where the mask is in the least
+      // significant bits.
+      Int32BinopMatcher mleft(m.left().node());
+      if (mleft.right().IsInRange(0, 31)) {
+        // Ubfx cannot extract bits past the register size, however since
+        // shifting the original value would have introduced some zeros we can
+        // still use ubfx with a smaller mask and the remaining bits will be
+        // zeros.
+        uint32_t lsb = mleft.right().Value();
+        if (lsb + mask_width > 32) mask_width = 32 - lsb;
+
+        Emit(kArm64Ubfx32, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()),
+             g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width));
+        return;
+      }
+      // Other cases fall through to the normal And operation.
+    }
+  }
+  VisitLogical<Int32BinopMatcher>(
+      this, node, &m, kArm64And32, CanCover(node, m.left().node()),
+      CanCover(node, m.right().node()), kLogical32Imm);
 }
 
 
 void InstructionSelector::VisitWord64And(Node* node) {
-  VisitBinop<Int64BinopMatcher>(this, node, kArm64And, kLogical64Imm);
+  Arm64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  if (m.left().IsWord64Shr() && CanCover(node, m.left().node()) &&
+      m.right().HasValue()) {
+    uint64_t mask = m.right().Value();
+    uint64_t mask_width = base::bits::CountPopulation64(mask);
+    uint64_t mask_msb = base::bits::CountLeadingZeros64(mask);
+    if ((mask_width != 0) && (mask_msb + mask_width == 64)) {
+      // The mask must be contiguous, and occupy the least-significant bits.
+      DCHECK_EQ(0, base::bits::CountTrailingZeros64(mask));
+
+      // Select Ubfx for And(Shr(x, imm), mask) where the mask is in the least
+      // significant bits.
+      Int64BinopMatcher mleft(m.left().node());
+      if (mleft.right().IsInRange(0, 63)) {
+        // Ubfx cannot extract bits past the register size, however since
+        // shifting the original value would have introduced some zeros we can
+        // still use ubfx with a smaller mask and the remaining bits will be
+        // zeros.
+        uint64_t lsb = mleft.right().Value();
+        if (lsb + mask_width > 64) mask_width = 64 - lsb;
+
+        Emit(kArm64Ubfx, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()),
+             g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width));
+        return;
+      }
+      // Other cases fall through to the normal And operation.
+    }
+  }
+  VisitLogical<Int64BinopMatcher>(
+      this, node, &m, kArm64And, CanCover(node, m.left().node()),
+      CanCover(node, m.right().node()), kLogical64Imm);
 }
 
 
 void InstructionSelector::VisitWord32Or(Node* node) {
-  VisitBinop<Int32BinopMatcher>(this, node, kArm64Or32, kLogical32Imm);
+  Int32BinopMatcher m(node);
+  VisitLogical<Int32BinopMatcher>(
+      this, node, &m, kArm64Or32, CanCover(node, m.left().node()),
+      CanCover(node, m.right().node()), kLogical32Imm);
 }
 
 
 void InstructionSelector::VisitWord64Or(Node* node) {
-  VisitBinop<Int64BinopMatcher>(this, node, kArm64Or, kLogical64Imm);
+  Int64BinopMatcher m(node);
+  VisitLogical<Int64BinopMatcher>(
+      this, node, &m, kArm64Or, CanCover(node, m.left().node()),
+      CanCover(node, m.right().node()), kLogical64Imm);
 }
 
 
 void InstructionSelector::VisitWord32Xor(Node* node) {
-  Arm64OperandGenerator g(this);
   Int32BinopMatcher m(node);
-  if (m.right().Is(-1)) {
-    Emit(kArm64Not32, g.DefineAsRegister(node), g.UseRegister(m.left().node()));
-  } else {
-    VisitBinop<Int32BinopMatcher>(this, node, kArm64Xor32, kLogical32Imm);
-  }
+  VisitLogical<Int32BinopMatcher>(
+      this, node, &m, kArm64Eor32, CanCover(node, m.left().node()),
+      CanCover(node, m.right().node()), kLogical32Imm);
 }
 
 
 void InstructionSelector::VisitWord64Xor(Node* node) {
-  Arm64OperandGenerator g(this);
   Int64BinopMatcher m(node);
-  if (m.right().Is(-1)) {
-    Emit(kArm64Not, g.DefineAsRegister(node), g.UseRegister(m.left().node()));
-  } else {
-    VisitBinop<Int64BinopMatcher>(this, node, kArm64Xor, kLogical32Imm);
-  }
+  VisitLogical<Int64BinopMatcher>(
+      this, node, &m, kArm64Eor, CanCover(node, m.left().node()),
+      CanCover(node, m.right().node()), kLogical64Imm);
 }
 
 
 void InstructionSelector::VisitWord32Shl(Node* node) {
-  VisitRRO(this, kArm64Shl32, node, kShift32Imm);
+  VisitRRO(this, kArm64Lsl32, node, kShift32Imm);
 }
 
 
 void InstructionSelector::VisitWord64Shl(Node* node) {
-  VisitRRO(this, kArm64Shl, node, kShift64Imm);
+  Arm64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  if ((m.left().IsChangeInt32ToInt64() || m.left().IsChangeUint32ToUint64()) &&
+      m.right().IsInRange(32, 63)) {
+    // There's no need to sign/zero-extend to 64-bit if we shift out the upper
+    // 32 bits anyway.
+    Emit(kArm64Lsl, g.DefineAsRegister(node),
+         g.UseRegister(m.left().node()->InputAt(0)),
+         g.UseImmediate(m.right().node()));
+    return;
+  }
+  VisitRRO(this, kArm64Lsl, node, kShift64Imm);
 }
 
 
 void InstructionSelector::VisitWord32Shr(Node* node) {
-  VisitRRO(this, kArm64Shr32, node, kShift32Imm);
+  Arm64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.left().IsWord32And() && m.right().IsInRange(0, 31)) {
+    int32_t lsb = m.right().Value();
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.right().HasValue()) {
+      uint32_t mask = (mleft.right().Value() >> lsb) << lsb;
+      uint32_t mask_width = base::bits::CountPopulation32(mask);
+      uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
+      // Select Ubfx for Shr(And(x, mask), imm) where the result of the mask is
+      // shifted into the least-significant bits.
+      if ((mask_msb + mask_width + lsb) == 32) {
+        DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(mask));
+        Emit(kArm64Ubfx32, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
+             g.TempImmediate(mask_width));
+        return;
+      }
+    }
+  }
+  VisitRRO(this, kArm64Lsr32, node, kShift32Imm);
 }
 
 
 void InstructionSelector::VisitWord64Shr(Node* node) {
-  VisitRRO(this, kArm64Shr, node, kShift64Imm);
+  Arm64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  if (m.left().IsWord64And() && m.right().IsInRange(0, 63)) {
+    int64_t lsb = m.right().Value();
+    Int64BinopMatcher mleft(m.left().node());
+    if (mleft.right().HasValue()) {
+      // Select Ubfx for Shr(And(x, mask), imm) where the result of the mask is
+      // shifted into the least-significant bits.
+      uint64_t mask = (mleft.right().Value() >> lsb) << lsb;
+      uint64_t mask_width = base::bits::CountPopulation64(mask);
+      uint64_t mask_msb = base::bits::CountLeadingZeros64(mask);
+      if ((mask_msb + mask_width + lsb) == 64) {
+        DCHECK_EQ(lsb, base::bits::CountTrailingZeros64(mask));
+        Emit(kArm64Ubfx, g.DefineAsRegister(node),
+             g.UseRegister(mleft.left().node()), g.TempImmediate(lsb),
+             g.TempImmediate(mask_width));
+        return;
+      }
+    }
+  }
+  VisitRRO(this, kArm64Lsr, node, kShift64Imm);
 }
 
 
 void InstructionSelector::VisitWord32Sar(Node* node) {
-  VisitRRO(this, kArm64Sar32, node, kShift32Imm);
+  Arm64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  // Select Sxth/Sxtb for (x << K) >> K where K is 16 or 24.
+  if (CanCover(node, m.left().node()) && m.left().IsWord32Shl()) {
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.right().Is(16) && m.right().Is(16)) {
+      Emit(kArm64Sxth32, g.DefineAsRegister(node),
+           g.UseRegister(mleft.left().node()));
+      return;
+    } else if (mleft.right().Is(24) && m.right().Is(24)) {
+      Emit(kArm64Sxtb32, g.DefineAsRegister(node),
+           g.UseRegister(mleft.left().node()));
+      return;
+    }
+  }
+  VisitRRO(this, kArm64Asr32, node, kShift32Imm);
 }
 
 
 void InstructionSelector::VisitWord64Sar(Node* node) {
-  VisitRRO(this, kArm64Sar, node, kShift64Imm);
+  VisitRRO(this, kArm64Asr, node, kShift64Imm);
 }
 
 
@@ -350,23 +709,69 @@
 
 
 void InstructionSelector::VisitInt32Add(Node* node) {
-  VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, kArithmeticImm);
+  Arm64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  // Select Madd(x, y, z) for Add(Mul(x, y), z).
+  if (m.left().IsInt32Mul() && CanCover(node, m.left().node())) {
+    Int32BinopMatcher mleft(m.left().node());
+    Emit(kArm64Madd32, g.DefineAsRegister(node),
+         g.UseRegister(mleft.left().node()),
+         g.UseRegister(mleft.right().node()), g.UseRegister(m.right().node()));
+    return;
+  }
+  // Select Madd(x, y, z) for Add(x, Mul(x, y)).
+  if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) {
+    Int32BinopMatcher mright(m.right().node());
+    Emit(kArm64Madd32, g.DefineAsRegister(node),
+         g.UseRegister(mright.left().node()),
+         g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
+    return;
+  }
+  VisitAddSub<Int32BinopMatcher>(this, node, kArm64Add32, kArm64Sub32);
 }
 
 
 void InstructionSelector::VisitInt64Add(Node* node) {
-  VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm);
+  Arm64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  // Select Madd(x, y, z) for Add(Mul(x, y), z).
+  if (m.left().IsInt64Mul() && CanCover(node, m.left().node())) {
+    Int64BinopMatcher mleft(m.left().node());
+    Emit(kArm64Madd, g.DefineAsRegister(node),
+         g.UseRegister(mleft.left().node()),
+         g.UseRegister(mleft.right().node()), g.UseRegister(m.right().node()));
+    return;
+  }
+  // Select Madd(x, y, z) for Add(x, Mul(x, y)).
+  if (m.right().IsInt64Mul() && CanCover(node, m.right().node())) {
+    Int64BinopMatcher mright(m.right().node());
+    Emit(kArm64Madd, g.DefineAsRegister(node),
+         g.UseRegister(mright.left().node()),
+         g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
+    return;
+  }
+  VisitAddSub<Int64BinopMatcher>(this, node, kArm64Add, kArm64Sub);
 }
 
 
 void InstructionSelector::VisitInt32Sub(Node* node) {
   Arm64OperandGenerator g(this);
   Int32BinopMatcher m(node);
+
+  // Select Msub(a, x, y) for Sub(a, Mul(x, y)).
+  if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) {
+    Int32BinopMatcher mright(m.right().node());
+    Emit(kArm64Msub32, g.DefineAsRegister(node),
+         g.UseRegister(mright.left().node()),
+         g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
+    return;
+  }
+
   if (m.left().Is(0)) {
     Emit(kArm64Neg32, g.DefineAsRegister(node),
          g.UseRegister(m.right().node()));
   } else {
-    VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm);
+    VisitAddSub<Int32BinopMatcher>(this, node, kArm64Sub32, kArm64Add32);
   }
 }
 
@@ -374,24 +779,107 @@
 void InstructionSelector::VisitInt64Sub(Node* node) {
   Arm64OperandGenerator g(this);
   Int64BinopMatcher m(node);
+
+  // Select Msub(a, x, y) for Sub(a, Mul(x, y)).
+  if (m.right().IsInt64Mul() && CanCover(node, m.right().node())) {
+    Int64BinopMatcher mright(m.right().node());
+    Emit(kArm64Msub, g.DefineAsRegister(node),
+         g.UseRegister(mright.left().node()),
+         g.UseRegister(mright.right().node()), g.UseRegister(m.left().node()));
+    return;
+  }
+
   if (m.left().Is(0)) {
     Emit(kArm64Neg, g.DefineAsRegister(node), g.UseRegister(m.right().node()));
   } else {
-    VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub, kArithmeticImm);
+    VisitAddSub<Int64BinopMatcher>(this, node, kArm64Sub, kArm64Add);
   }
 }
 
 
 void InstructionSelector::VisitInt32Mul(Node* node) {
+  Arm64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+
+  if (m.left().IsInt32Sub() && CanCover(node, m.left().node())) {
+    Int32BinopMatcher mleft(m.left().node());
+
+    // Select Mneg(x, y) for Mul(Sub(0, x), y).
+    if (mleft.left().Is(0)) {
+      Emit(kArm64Mneg32, g.DefineAsRegister(node),
+           g.UseRegister(mleft.right().node()),
+           g.UseRegister(m.right().node()));
+      return;
+    }
+  }
+
+  if (m.right().IsInt32Sub() && CanCover(node, m.right().node())) {
+    Int32BinopMatcher mright(m.right().node());
+
+    // Select Mneg(x, y) for Mul(x, Sub(0, y)).
+    if (mright.left().Is(0)) {
+      Emit(kArm64Mneg32, g.DefineAsRegister(node),
+           g.UseRegister(m.left().node()),
+           g.UseRegister(mright.right().node()));
+      return;
+    }
+  }
+
   VisitRRR(this, kArm64Mul32, node);
 }
 
 
 void InstructionSelector::VisitInt64Mul(Node* node) {
+  Arm64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+
+  if (m.left().IsInt64Sub() && CanCover(node, m.left().node())) {
+    Int64BinopMatcher mleft(m.left().node());
+
+    // Select Mneg(x, y) for Mul(Sub(0, x), y).
+    if (mleft.left().Is(0)) {
+      Emit(kArm64Mneg, g.DefineAsRegister(node),
+           g.UseRegister(mleft.right().node()),
+           g.UseRegister(m.right().node()));
+      return;
+    }
+  }
+
+  if (m.right().IsInt64Sub() && CanCover(node, m.right().node())) {
+    Int64BinopMatcher mright(m.right().node());
+
+    // Select Mneg(x, y) for Mul(x, Sub(0, y)).
+    if (mright.left().Is(0)) {
+      Emit(kArm64Mneg, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+           g.UseRegister(mright.right().node()));
+      return;
+    }
+  }
+
   VisitRRR(this, kArm64Mul, node);
 }
 
 
+void InstructionSelector::VisitInt32MulHigh(Node* node) {
+  // TODO(arm64): Can we do better here?
+  Arm64OperandGenerator g(this);
+  InstructionOperand* const smull_operand = g.TempRegister();
+  Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)),
+       g.UseRegister(node->InputAt(1)));
+  Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32));
+}
+
+
+void InstructionSelector::VisitUint32MulHigh(Node* node) {
+  // TODO(arm64): Can we do better here?
+  Arm64OperandGenerator g(this);
+  InstructionOperand* const smull_operand = g.TempRegister();
+  Emit(kArm64Umull, smull_operand, g.UseRegister(node->InputAt(0)),
+       g.UseRegister(node->InputAt(1)));
+  Emit(kArm64Lsr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32));
+}
+
+
 void InstructionSelector::VisitInt32Div(Node* node) {
   VisitRRR(this, kArm64Idiv32, node);
 }
@@ -402,12 +890,12 @@
 }
 
 
-void InstructionSelector::VisitInt32UDiv(Node* node) {
+void InstructionSelector::VisitUint32Div(Node* node) {
   VisitRRR(this, kArm64Udiv32, node);
 }
 
 
-void InstructionSelector::VisitInt64UDiv(Node* node) {
+void InstructionSelector::VisitUint64Div(Node* node) {
   VisitRRR(this, kArm64Udiv, node);
 }
 
@@ -422,16 +910,23 @@
 }
 
 
-void InstructionSelector::VisitInt32UMod(Node* node) {
+void InstructionSelector::VisitUint32Mod(Node* node) {
   VisitRRR(this, kArm64Umod32, node);
 }
 
 
-void InstructionSelector::VisitInt64UMod(Node* node) {
+void InstructionSelector::VisitUint64Mod(Node* node) {
   VisitRRR(this, kArm64Umod, node);
 }
 
 
+void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
+  Arm64OperandGenerator g(this);
+  Emit(kArm64Float32ToFloat64, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
   Arm64OperandGenerator g(this);
   Emit(kArm64Int32ToFloat64, g.DefineAsRegister(node),
@@ -468,12 +963,65 @@
 
 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
   Arm64OperandGenerator g(this);
-  Emit(kArm64Mov32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+  Node* value = node->InputAt(0);
+  switch (value->opcode()) {
+    case IrOpcode::kWord32And:
+    case IrOpcode::kWord32Or:
+    case IrOpcode::kWord32Xor:
+    case IrOpcode::kWord32Shl:
+    case IrOpcode::kWord32Shr:
+    case IrOpcode::kWord32Sar:
+    case IrOpcode::kWord32Ror:
+    case IrOpcode::kWord32Equal:
+    case IrOpcode::kInt32Add:
+    case IrOpcode::kInt32AddWithOverflow:
+    case IrOpcode::kInt32Sub:
+    case IrOpcode::kInt32SubWithOverflow:
+    case IrOpcode::kInt32Mul:
+    case IrOpcode::kInt32MulHigh:
+    case IrOpcode::kInt32Div:
+    case IrOpcode::kInt32Mod:
+    case IrOpcode::kInt32LessThan:
+    case IrOpcode::kInt32LessThanOrEqual:
+    case IrOpcode::kUint32Div:
+    case IrOpcode::kUint32LessThan:
+    case IrOpcode::kUint32LessThanOrEqual:
+    case IrOpcode::kUint32Mod:
+    case IrOpcode::kUint32MulHigh: {
+      // 32-bit operations will write their result in a W register (implicitly
+      // clearing the top 32-bit of the corresponding X register) so the
+      // zero-extension is a no-op.
+      Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
+      return;
+    }
+    default:
+      break;
+  }
+  Emit(kArm64Mov32, g.DefineAsRegister(node), g.UseRegister(value));
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
+  Arm64OperandGenerator g(this);
+  Emit(kArm64Float64ToFloat32, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
 }
 
 
 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
   Arm64OperandGenerator g(this);
+  Node* value = node->InputAt(0);
+  if (CanCover(node, value)) {
+    Int64BinopMatcher m(value);
+    if ((m.IsWord64Sar() && m.right().HasValue() &&
+         (m.right().Value() == 32)) ||
+        (m.IsWord64Shr() && m.right().IsInRange(32, 63))) {
+      Emit(kArm64Lsr, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+           g.UseImmediate(m.right().node()));
+      return;
+    }
+  }
+
   Emit(kArm64Mov32, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
 }
 
@@ -507,125 +1055,38 @@
 
 
 void InstructionSelector::VisitFloat64Sqrt(Node* node) {
+  VisitRRFloat64(this, kArm64Float64Sqrt, node);
+}
+
+
+void InstructionSelector::VisitFloat64Floor(Node* node) {
+  VisitRRFloat64(this, kArm64Float64Floor, node);
+}
+
+
+void InstructionSelector::VisitFloat64Ceil(Node* node) {
+  VisitRRFloat64(this, kArm64Float64Ceil, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
+  VisitRRFloat64(this, kArm64Float64RoundTruncate, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
+  VisitRRFloat64(this, kArm64Float64RoundTiesAway, node);
+}
+
+
+void InstructionSelector::VisitCall(Node* node) {
   Arm64OperandGenerator g(this);
-  Emit(kArm64Float64Sqrt, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
-}
-
-
-void InstructionSelector::VisitInt32AddWithOverflow(Node* node,
-                                                    FlagsContinuation* cont) {
-  VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, kArithmeticImm, cont);
-}
-
-
-void InstructionSelector::VisitInt32SubWithOverflow(Node* node,
-                                                    FlagsContinuation* cont) {
-  VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm, cont);
-}
-
-
-// Shared routine for multiple compare operations.
-static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
-                         InstructionOperand* left, InstructionOperand* right,
-                         FlagsContinuation* cont) {
-  Arm64OperandGenerator g(selector);
-  opcode = cont->Encode(opcode);
-  if (cont->IsBranch()) {
-    selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()),
-                   g.Label(cont->false_block()))->MarkAsControl();
-  } else {
-    DCHECK(cont->IsSet());
-    selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
-  }
-}
-
-
-// Shared routine for multiple word compare operations.
-static void VisitWordCompare(InstructionSelector* selector, Node* node,
-                             InstructionCode opcode, FlagsContinuation* cont,
-                             bool commutative) {
-  Arm64OperandGenerator g(selector);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
-
-  // Match immediates on left or right side of comparison.
-  if (g.CanBeImmediate(right, kArithmeticImm)) {
-    VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
-                 cont);
-  } else if (g.CanBeImmediate(left, kArithmeticImm)) {
-    if (!commutative) cont->Commute();
-    VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
-                 cont);
-  } else {
-    VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right),
-                 cont);
-  }
-}
-
-
-void InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) {
-  switch (node->opcode()) {
-    case IrOpcode::kInt32Add:
-      return VisitWordCompare(this, node, kArm64Cmn32, cont, true);
-    case IrOpcode::kInt32Sub:
-      return VisitWordCompare(this, node, kArm64Cmp32, cont, false);
-    case IrOpcode::kWord32And:
-      return VisitWordCompare(this, node, kArm64Tst32, cont, true);
-    default:
-      break;
-  }
-
-  Arm64OperandGenerator g(this);
-  VisitCompare(this, kArm64Tst32, g.UseRegister(node), g.UseRegister(node),
-               cont);
-}
-
-
-void InstructionSelector::VisitWord64Test(Node* node, FlagsContinuation* cont) {
-  switch (node->opcode()) {
-    case IrOpcode::kWord64And:
-      return VisitWordCompare(this, node, kArm64Tst, cont, true);
-    default:
-      break;
-  }
-
-  Arm64OperandGenerator g(this);
-  VisitCompare(this, kArm64Tst, g.UseRegister(node), g.UseRegister(node), cont);
-}
-
-
-void InstructionSelector::VisitWord32Compare(Node* node,
-                                             FlagsContinuation* cont) {
-  VisitWordCompare(this, node, kArm64Cmp32, cont, false);
-}
-
-
-void InstructionSelector::VisitWord64Compare(Node* node,
-                                             FlagsContinuation* cont) {
-  VisitWordCompare(this, node, kArm64Cmp, cont, false);
-}
-
-
-void InstructionSelector::VisitFloat64Compare(Node* node,
-                                              FlagsContinuation* cont) {
-  Arm64OperandGenerator g(this);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
-  VisitCompare(this, kArm64Float64Cmp, g.UseRegister(left),
-               g.UseRegister(right), cont);
-}
-
-
-void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
-                                    BasicBlock* deoptimization) {
-  Arm64OperandGenerator g(this);
-  CallDescriptor* descriptor = OpParameter<CallDescriptor*>(call);
+  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
 
   FrameStateDescriptor* frame_state_descriptor = NULL;
   if (descriptor->NeedsFrameState()) {
     frame_state_descriptor =
-        GetFrameStateDescriptor(call->InputAt(descriptor->InputCount()));
+        GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
   }
 
   CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
@@ -634,7 +1095,7 @@
   // TODO(turbofan): on ARM64 it's probably better to use the code object in a
   // register if there are multiple uses of it. Improve constant pool and the
   // heuristics in the register allocator for where to emit constants.
-  InitializeCallBuffer(call, &buffer, true, false);
+  InitializeCallBuffer(node, &buffer, true, false);
 
   // Push the arguments to the stack.
   bool pushed_count_uneven = buffer.pushed_nodes.size() & 1;
@@ -681,17 +1142,389 @@
   opcode |= MiscField::encode(descriptor->flags());
 
   // Emit the call instruction.
+  InstructionOperand** first_output =
+      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
   Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
+      Emit(opcode, buffer.outputs.size(), first_output,
            buffer.instruction_args.size(), &buffer.instruction_args.front());
-
   call_instr->MarkAsCall();
-  if (deoptimization != NULL) {
-    DCHECK(continuation != NULL);
-    call_instr->MarkAsControl();
+}
+
+
+// Shared routine for multiple compare operations.
+static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                         InstructionOperand* left, InstructionOperand* right,
+                         FlagsContinuation* cont) {
+  Arm64OperandGenerator g(selector);
+  opcode = cont->Encode(opcode);
+  if (cont->IsBranch()) {
+    selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()),
+                   g.Label(cont->false_block()))->MarkAsControl();
+  } else {
+    DCHECK(cont->IsSet());
+    selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
   }
 }
 
+
+// Shared routine for multiple word compare operations.
+static void VisitWordCompare(InstructionSelector* selector, Node* node,
+                             InstructionCode opcode, FlagsContinuation* cont,
+                             bool commutative, ImmediateMode immediate_mode) {
+  Arm64OperandGenerator g(selector);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+
+  // Match immediates on left or right side of comparison.
+  if (g.CanBeImmediate(right, immediate_mode)) {
+    VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
+                 cont);
+  } else if (g.CanBeImmediate(left, immediate_mode)) {
+    if (!commutative) cont->Commute();
+    VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
+                 cont);
+  } else {
+    VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right),
+                 cont);
+  }
+}
+
+
+static void VisitWord32Compare(InstructionSelector* selector, Node* node,
+                               FlagsContinuation* cont) {
+  VisitWordCompare(selector, node, kArm64Cmp32, cont, false, kArithmeticImm);
+}
+
+
+static void VisitWordTest(InstructionSelector* selector, Node* node,
+                          InstructionCode opcode, FlagsContinuation* cont) {
+  Arm64OperandGenerator g(selector);
+  VisitCompare(selector, opcode, g.UseRegister(node), g.UseRegister(node),
+               cont);
+}
+
+
+static void VisitWord32Test(InstructionSelector* selector, Node* node,
+                            FlagsContinuation* cont) {
+  VisitWordTest(selector, node, kArm64Tst32, cont);
+}
+
+
+static void VisitWord64Test(InstructionSelector* selector, Node* node,
+                            FlagsContinuation* cont) {
+  VisitWordTest(selector, node, kArm64Tst, cont);
+}
+
+
+// Shared routine for multiple float compare operations.
+static void VisitFloat64Compare(InstructionSelector* selector, Node* node,
+                                FlagsContinuation* cont) {
+  Arm64OperandGenerator g(selector);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(left),
+               g.UseRegister(right), cont);
+}
+
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+                                      BasicBlock* fbranch) {
+  OperandGenerator g(this);
+  Node* user = branch;
+  Node* value = branch->InputAt(0);
+
+  FlagsContinuation cont(kNotEqual, tbranch, fbranch);
+
+  // Try to combine with comparisons against 0 by simply inverting the branch.
+  while (CanCover(user, value)) {
+    if (value->opcode() == IrOpcode::kWord32Equal) {
+      Int32BinopMatcher m(value);
+      if (m.right().Is(0)) {
+        user = value;
+        value = m.left().node();
+        cont.Negate();
+      } else {
+        break;
+      }
+    } else if (value->opcode() == IrOpcode::kWord64Equal) {
+      Int64BinopMatcher m(value);
+      if (m.right().Is(0)) {
+        user = value;
+        value = m.left().node();
+        cont.Negate();
+      } else {
+        break;
+      }
+    } else {
+      break;
+    }
+  }
+
+  // Try to combine the branch with a comparison.
+  if (CanCover(user, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kWord32Equal:
+        cont.OverwriteAndNegateIfEqual(kEqual);
+        return VisitWord32Compare(this, value, &cont);
+      case IrOpcode::kInt32LessThan:
+        cont.OverwriteAndNegateIfEqual(kSignedLessThan);
+        return VisitWord32Compare(this, value, &cont);
+      case IrOpcode::kInt32LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+        return VisitWord32Compare(this, value, &cont);
+      case IrOpcode::kUint32LessThan:
+        cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitWord32Compare(this, value, &cont);
+      case IrOpcode::kUint32LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWord32Compare(this, value, &cont);
+      case IrOpcode::kWord64Equal:
+        cont.OverwriteAndNegateIfEqual(kEqual);
+        return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+                                kArithmeticImm);
+      case IrOpcode::kInt64LessThan:
+        cont.OverwriteAndNegateIfEqual(kSignedLessThan);
+        return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+                                kArithmeticImm);
+      case IrOpcode::kInt64LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+        return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+                                kArithmeticImm);
+      case IrOpcode::kUint64LessThan:
+        cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitWordCompare(this, value, kArm64Cmp, &cont, false,
+                                kArithmeticImm);
+      case IrOpcode::kFloat64Equal:
+        cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
+        return VisitFloat64Compare(this, value, &cont);
+      case IrOpcode::kFloat64LessThan:
+        cont.OverwriteAndNegateIfEqual(kUnorderedLessThan);
+        return VisitFloat64Compare(this, value, &cont);
+      case IrOpcode::kFloat64LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+        return VisitFloat64Compare(this, value, &cont);
+      case IrOpcode::kProjection:
+        // Check if this is the overflow output projection of an
+        // <Operation>WithOverflow node.
+        if (OpParameter<size_t>(value) == 1u) {
+          // We cannot combine the <Operation>WithOverflow with this branch
+          // unless the 0th projection (the use of the actual value of the
+          // <Operation> is either NULL, which means there's no use of the
+          // actual value, or was already defined, which means it is scheduled
+          // *AFTER* this branch).
+          Node* node = value->InputAt(0);
+          Node* result = node->FindProjection(0);
+          if (result == NULL || IsDefined(result)) {
+            switch (node->opcode()) {
+              case IrOpcode::kInt32AddWithOverflow:
+                cont.OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32,
+                                                     kArithmeticImm, &cont);
+              case IrOpcode::kInt32SubWithOverflow:
+                cont.OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32,
+                                                     kArithmeticImm, &cont);
+              default:
+                break;
+            }
+          }
+        }
+        break;
+      case IrOpcode::kInt32Add:
+        return VisitWordCompare(this, value, kArm64Cmn32, &cont, true,
+                                kArithmeticImm);
+      case IrOpcode::kInt32Sub:
+        return VisitWordCompare(this, value, kArm64Cmp32, &cont, false,
+                                kArithmeticImm);
+      case IrOpcode::kWord32And: {
+        Int32BinopMatcher m(value);
+        if (m.right().HasValue() &&
+            (base::bits::CountPopulation32(m.right().Value()) == 1)) {
+          // If the mask has only one bit set, we can use tbz/tbnz.
+          DCHECK((cont.condition() == kEqual) ||
+                 (cont.condition() == kNotEqual));
+          Emit(cont.Encode(kArm64TestAndBranch32), NULL,
+               g.UseRegister(m.left().node()),
+               g.TempImmediate(
+                   base::bits::CountTrailingZeros32(m.right().Value())),
+               g.Label(cont.true_block()),
+               g.Label(cont.false_block()))->MarkAsControl();
+          return;
+        }
+        return VisitWordCompare(this, value, kArm64Tst32, &cont, true,
+                                kLogical32Imm);
+      }
+      case IrOpcode::kWord64And: {
+        Int64BinopMatcher m(value);
+        if (m.right().HasValue() &&
+            (base::bits::CountPopulation64(m.right().Value()) == 1)) {
+          // If the mask has only one bit set, we can use tbz/tbnz.
+          DCHECK((cont.condition() == kEqual) ||
+                 (cont.condition() == kNotEqual));
+          Emit(cont.Encode(kArm64TestAndBranch), NULL,
+               g.UseRegister(m.left().node()),
+               g.TempImmediate(
+                   base::bits::CountTrailingZeros64(m.right().Value())),
+               g.Label(cont.true_block()),
+               g.Label(cont.false_block()))->MarkAsControl();
+          return;
+        }
+        return VisitWordCompare(this, value, kArm64Tst, &cont, true,
+                                kLogical64Imm);
+      }
+      default:
+        break;
+    }
+  }
+
+  // Branch could not be combined with a compare, compare against 0 and branch.
+  Emit(cont.Encode(kArm64CompareAndBranch32), NULL, g.UseRegister(value),
+       g.Label(cont.true_block()),
+       g.Label(cont.false_block()))->MarkAsControl();
+}
+
+
+void InstructionSelector::VisitWord32Equal(Node* const node) {
+  Node* const user = node;
+  FlagsContinuation cont(kEqual, node);
+  Int32BinopMatcher m(user);
+  if (m.right().Is(0)) {
+    Node* const value = m.left().node();
+    if (CanCover(user, value)) {
+      switch (value->opcode()) {
+        case IrOpcode::kInt32Add:
+          return VisitWordCompare(this, value, kArm64Cmn32, &cont, true,
+                                  kArithmeticImm);
+        case IrOpcode::kInt32Sub:
+          return VisitWordCompare(this, value, kArm64Cmp32, &cont, false,
+                                  kArithmeticImm);
+        case IrOpcode::kWord32And:
+          return VisitWordCompare(this, value, kArm64Tst32, &cont, true,
+                                  kLogical32Imm);
+        default:
+          break;
+      }
+      return VisitWord32Test(this, value, &cont);
+    }
+  }
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitWord64Equal(Node* const node) {
+  Node* const user = node;
+  FlagsContinuation cont(kEqual, node);
+  Int64BinopMatcher m(user);
+  if (m.right().Is(0)) {
+    Node* const value = m.left().node();
+    if (CanCover(user, value)) {
+      switch (value->opcode()) {
+        case IrOpcode::kWord64And:
+          return VisitWordCompare(this, value, kArm64Tst, &cont, true,
+                                  kLogical64Imm);
+        default:
+          break;
+      }
+      return VisitWord64Test(this, value, &cont);
+    }
+  }
+  VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
+}
+
+
+void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32,
+                                         kArithmeticImm, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, kArithmeticImm, &cont);
+}
+
+
+void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32,
+                                         kArithmeticImm, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm, &cont);
+}
+
+
+void InstructionSelector::VisitInt64LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
+}
+
+
+void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
+}
+
+
+void InstructionSelector::VisitUint64LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
+}
+
+
+void InstructionSelector::VisitFloat64Equal(Node* node) {
+  FlagsContinuation cont(kUnorderedEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThan(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThan, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  return MachineOperatorBuilder::kFloat64Floor |
+         MachineOperatorBuilder::kFloat64Ceil |
+         MachineOperatorBuilder::kFloat64RoundTruncate |
+         MachineOperatorBuilder::kFloat64RoundTiesAway |
+         MachineOperatorBuilder::kWord32ShiftIsSafe |
+         MachineOperatorBuilder::kInt32DivIsSafe |
+         MachineOperatorBuilder::kUint32DivIsSafe;
+}
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/arm64/linkage-arm64.cc b/src/compiler/arm64/linkage-arm64.cc
index 2be2cb1..291b552 100644
--- a/src/compiler/arm64/linkage-arm64.cc
+++ b/src/compiler/arm64/linkage-arm64.cc
@@ -35,8 +35,9 @@
 
 typedef LinkageHelper<Arm64LinkageHelperTraits> LH;
 
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) {
-  return LH::GetJSCallDescriptor(zone, parameter_count);
+CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
+                                             CallDescriptor::Flags flags) {
+  return LH::GetJSCallDescriptor(zone, parameter_count, flags);
 }
 
 
@@ -49,10 +50,10 @@
 
 
 CallDescriptor* Linkage::GetStubCallDescriptor(
-    CallInterfaceDescriptor descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Zone* zone) {
+    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
+    CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone) {
   return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count,
-                                   flags);
+                                   flags, properties);
 }
 
 
diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc
index 74fb0ae..cde5e71 100644
--- a/src/compiler/ast-graph-builder.cc
+++ b/src/compiler/ast-graph-builder.cc
@@ -5,10 +5,12 @@
 #include "src/compiler/ast-graph-builder.h"
 
 #include "src/compiler.h"
+#include "src/compiler/ast-loop-assignment-analyzer.h"
 #include "src/compiler/control-builders.h"
 #include "src/compiler/machine-operator.h"
-#include "src/compiler/node-properties.h"
+#include "src/compiler/node-matchers.h"
 #include "src/compiler/node-properties-inl.h"
+#include "src/compiler/node-properties.h"
 #include "src/full-codegen.h"
 #include "src/parser.h"
 #include "src/scopes.h"
@@ -17,14 +19,16 @@
 namespace internal {
 namespace compiler {
 
-AstGraphBuilder::AstGraphBuilder(CompilationInfo* info, JSGraph* jsgraph)
-    : StructuredGraphBuilder(jsgraph->graph(), jsgraph->common()),
+AstGraphBuilder::AstGraphBuilder(Zone* local_zone, CompilationInfo* info,
+                                 JSGraph* jsgraph, LoopAssignmentAnalysis* loop)
+    : StructuredGraphBuilder(local_zone, jsgraph->graph(), jsgraph->common()),
       info_(info),
       jsgraph_(jsgraph),
-      globals_(0, info->zone()),
+      globals_(0, local_zone),
       breakable_(NULL),
-      execution_context_(NULL) {
-  InitializeAstVisitor(info->zone());
+      execution_context_(NULL),
+      loop_assignment_analysis_(loop) {
+  InitializeAstVisitor(local_zone);
 }
 
 
@@ -62,20 +66,29 @@
   Environment env(this, scope, graph()->start());
   set_environment(&env);
 
+  // Initialize the incoming context.
+  Node* outer_context = GetFunctionContext();
+  set_current_context(outer_context);
+
+  // Build receiver check for sloppy mode if necessary.
+  // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
+  Node* original_receiver = env.Lookup(scope->receiver());
+  Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver);
+  env.Bind(scope->receiver(), patched_receiver);
+
   // Build node to initialize local function context.
   Node* closure = GetFunctionClosure();
-  Node* outer = GetFunctionContext();
-  Node* inner = BuildLocalFunctionContext(outer, closure);
+  Node* inner_context = BuildLocalFunctionContext(outer_context, closure);
 
   // Push top-level function scope for the function body.
-  ContextScope top_context(this, scope, inner);
+  ContextScope top_context(this, scope, inner_context);
 
   // Build the arguments object if it is used.
   BuildArgumentsObject(scope->arguments());
 
   // Emit tracing call if requested to do so.
   if (FLAG_trace) {
-    NewNode(javascript()->Runtime(Runtime::kTraceEnter, 0));
+    NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0));
   }
 
   // Visit implicit declaration of the function name.
@@ -86,8 +99,8 @@
   // Visit declarations within the function scope.
   VisitDeclarations(scope->declarations());
 
-  // TODO(mstarzinger): This should do an inlined stack check.
-  Node* node = NewNode(javascript()->Runtime(Runtime::kStackGuard, 0));
+  // Build a stack-check before the body.
+  Node* node = BuildStackCheck();
   PrepareFrameState(node, BailoutId::FunctionEntry());
 
   // Visit statements in the function body.
@@ -98,7 +111,7 @@
   if (FLAG_trace) {
     // TODO(mstarzinger): Only traces implicit return.
     Node* return_value = jsgraph()->UndefinedConstant();
-    NewNode(javascript()->Runtime(Runtime::kTraceExit, 1), return_value);
+    NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value);
   }
 
   // Return 'undefined' in case we can fall off the end.
@@ -129,26 +142,6 @@
 }
 
 
-// Helper to find an existing shared function info in the baseline code for the
-// given function literal. Used to canonicalize SharedFunctionInfo objects.
-static Handle<SharedFunctionInfo> SearchSharedFunctionInfo(
-    Code* unoptimized_code, FunctionLiteral* expr) {
-  int start_position = expr->start_position();
-  for (RelocIterator it(unoptimized_code); !it.done(); it.next()) {
-    RelocInfo* rinfo = it.rinfo();
-    if (rinfo->rmode() != RelocInfo::EMBEDDED_OBJECT) continue;
-    Object* obj = rinfo->target_object();
-    if (obj->IsSharedFunctionInfo()) {
-      SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
-      if (shared->start_position() == start_position) {
-        return Handle<SharedFunctionInfo>(shared);
-      }
-    }
-  }
-  return Handle<SharedFunctionInfo>();
-}
-
-
 StructuredGraphBuilder::Environment* AstGraphBuilder::CopyEnvironment(
     StructuredGraphBuilder::Environment* env) {
   return new (zone()) Environment(*reinterpret_cast<Environment*>(env));
@@ -329,24 +322,40 @@
 
 void AstGraphBuilder::VisitForValue(Expression* expr) {
   AstValueContext for_value(this);
-  if (!HasStackOverflow()) {
+  if (!CheckStackOverflow()) {
     expr->Accept(this);
+  } else {
+    ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
   }
 }
 
 
 void AstGraphBuilder::VisitForEffect(Expression* expr) {
   AstEffectContext for_effect(this);
-  if (!HasStackOverflow()) {
+  if (!CheckStackOverflow()) {
     expr->Accept(this);
+  } else {
+    ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
   }
 }
 
 
 void AstGraphBuilder::VisitForTest(Expression* expr) {
   AstTestContext for_condition(this);
-  if (!HasStackOverflow()) {
+  if (!CheckStackOverflow()) {
     expr->Accept(this);
+  } else {
+    ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
+  }
+}
+
+
+void AstGraphBuilder::Visit(Expression* expr) {
+  // Reuses enclosing AstContext.
+  if (!CheckStackOverflow()) {
+    expr->Accept(this);
+  } else {
+    ast_context()->ProduceValue(jsgraph()->UndefinedConstant());
   }
 }
 
@@ -360,8 +369,8 @@
       Handle<Oddball> value = variable->binding_needs_init()
                                   ? isolate()->factory()->the_hole_value()
                                   : isolate()->factory()->undefined_value();
-      globals()->Add(variable->name(), zone());
-      globals()->Add(value, zone());
+      globals()->push_back(variable->name());
+      globals()->push_back(value);
       break;
     }
     case Variable::PARAMETER:
@@ -392,8 +401,8 @@
           Compiler::BuildFunctionInfo(decl->fun(), info()->script(), info());
       // Check for stack-overflow exception.
       if (function.is_null()) return SetStackOverflow();
-      globals()->Add(variable->name(), zone());
-      globals()->Add(function, zone());
+      globals()->push_back(variable->name());
+      globals()->push_back(function);
       break;
     }
     case Variable::PARAMETER:
@@ -580,7 +589,7 @@
 
 void AstGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
   LoopBuilder while_loop(this);
-  while_loop.BeginLoop();
+  while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt));
   VisitIterationBody(stmt, &while_loop, 0);
   while_loop.EndBody();
   VisitForTest(stmt->cond());
@@ -592,7 +601,7 @@
 
 void AstGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
   LoopBuilder while_loop(this);
-  while_loop.BeginLoop();
+  while_loop.BeginLoop(GetVariablesAssignedInLoop(stmt));
   VisitForTest(stmt->cond());
   Node* condition = environment()->Pop();
   while_loop.BreakUnless(condition);
@@ -605,11 +614,13 @@
 void AstGraphBuilder::VisitForStatement(ForStatement* stmt) {
   LoopBuilder for_loop(this);
   VisitIfNotNull(stmt->init());
-  for_loop.BeginLoop();
+  for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt));
   if (stmt->cond() != NULL) {
     VisitForTest(stmt->cond());
     Node* condition = environment()->Pop();
     for_loop.BreakUnless(condition);
+  } else {
+    for_loop.BreakUnless(jsgraph()->TrueConstant());
   }
   VisitIterationBody(stmt, &for_loop, 0);
   for_loop.EndBody();
@@ -639,24 +650,27 @@
     // Convert object to jsobject.
     // PrepareForBailoutForId(stmt->PrepareId(), TOS_REG);
     obj = NewNode(javascript()->ToObject(), obj);
+    PrepareFrameState(obj, stmt->ToObjectId(), OutputFrameStateCombine::Push());
     environment()->Push(obj);
     // TODO(dcarney): should do a fast enum cache check here to skip runtime.
     environment()->Push(obj);
     Node* cache_type = ProcessArguments(
-        javascript()->Runtime(Runtime::kGetPropertyNamesFast, 1), 1);
+        javascript()->CallRuntime(Runtime::kGetPropertyNamesFast, 1), 1);
+    PrepareFrameState(cache_type, stmt->EnumId(),
+                      OutputFrameStateCombine::Push());
     // TODO(dcarney): these next runtime calls should be removed in favour of
     //                a few simplified instructions.
     environment()->Push(obj);
     environment()->Push(cache_type);
     Node* cache_pair =
-        ProcessArguments(javascript()->Runtime(Runtime::kForInInit, 2), 2);
+        ProcessArguments(javascript()->CallRuntime(Runtime::kForInInit, 2), 2);
     // cache_type may have been replaced.
     Node* cache_array = NewNode(common()->Projection(0), cache_pair);
     cache_type = NewNode(common()->Projection(1), cache_pair);
     environment()->Push(cache_type);
     environment()->Push(cache_array);
     Node* cache_length = ProcessArguments(
-        javascript()->Runtime(Runtime::kForInCacheArrayLength, 2), 2);
+        javascript()->CallRuntime(Runtime::kForInCacheArrayLength, 2), 2);
     {
       // TODO(dcarney): this check is actually supposed to be for the
       //                empty enum case only.
@@ -676,7 +690,7 @@
         environment()->Push(jsgraph()->ZeroConstant());
         // PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
         LoopBuilder for_loop(this);
-        for_loop.BeginLoop();
+        for_loop.BeginLoop(GetVariablesAssignedInLoop(stmt));
         // Check loop termination condition.
         Node* index = environment()->Peek(0);
         Node* exit_cond =
@@ -692,8 +706,8 @@
         environment()->Push(cache_array);
         environment()->Push(cache_type);
         environment()->Push(index);
-        Node* pair =
-            ProcessArguments(javascript()->Runtime(Runtime::kForInNext, 4), 4);
+        Node* pair = ProcessArguments(
+            javascript()->CallRuntime(Runtime::kForInNext, 4), 4);
         Node* value = NewNode(common()->Projection(0), pair);
         Node* should_filter = NewNode(common()->Projection(1), pair);
         environment()->Push(value);
@@ -719,7 +733,7 @@
           // result is either the string key or Smi(0) indicating the property
           // is gone.
           Node* res = ProcessArguments(
-              javascript()->Call(3, NO_CALL_FUNCTION_FLAGS), 3);
+              javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS), 3);
           // TODO(jarin): provide real bailout id.
           PrepareFrameState(res, BailoutId::None());
           Node* property_missing = NewNode(javascript()->StrictEqual(), res,
@@ -785,7 +799,7 @@
 
 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
   // TODO(turbofan): Do we really need a separate reloc-info for this?
-  Node* node = NewNode(javascript()->Runtime(Runtime::kDebugBreak, 0));
+  Node* node = NewNode(javascript()->CallRuntime(Runtime::kDebugBreak, 0));
   PrepareFrameState(node, stmt->DebugBreakId());
 }
 
@@ -795,8 +809,8 @@
 
   // Build a new shared function info if we cannot find one in the baseline
   // code. We also have a stack overflow if the recursive compilation did.
-  Handle<SharedFunctionInfo> shared_info =
-      SearchSharedFunctionInfo(info()->shared_info()->code(), expr);
+  expr->InitializeSharedInfo(handle(info()->shared_info()->code()));
+  Handle<SharedFunctionInfo> shared_info = expr->shared_info();
   if (shared_info.is_null()) {
     shared_info = Compiler::BuildFunctionInfo(expr, info()->script(), info());
     CHECK(!shared_info.is_null());  // TODO(mstarzinger): Set stack overflow?
@@ -804,16 +818,14 @@
 
   // Create node to instantiate a new closure.
   Node* info = jsgraph()->Constant(shared_info);
-  Node* pretenure = expr->pretenure() ? jsgraph()->TrueConstant()
-                                      : jsgraph()->FalseConstant();
-  const Operator* op = javascript()->Runtime(Runtime::kNewClosure, 3);
+  Node* pretenure = jsgraph()->BooleanConstant(expr->pretenure());
+  const Operator* op = javascript()->CallRuntime(Runtime::kNewClosure, 3);
   Node* value = NewNode(op, context, info, pretenure);
   ast_context()->ProduceValue(value);
 }
 
 
 void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
-  // TODO(arv): Implement.
   UNREACHABLE();
 }
 
@@ -838,7 +850,8 @@
 
 
 void AstGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
-  Node* value = BuildVariableLoad(expr->var(), expr->id());
+  VectorSlotPair pair = CreateVectorSlotPair(expr->VariableFeedbackSlot());
+  Node* value = BuildVariableLoad(expr->var(), expr->id(), pair);
   ast_context()->ProduceValue(value);
 }
 
@@ -859,8 +872,9 @@
   Node* pattern = jsgraph()->Constant(expr->pattern());
   Node* flags = jsgraph()->Constant(expr->flags());
   const Operator* op =
-      javascript()->Runtime(Runtime::kMaterializeRegExpLiteral, 4);
+      javascript()->CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
   Node* literal = NewNode(op, literals_array, literal_index, pattern, flags);
+  PrepareFrameState(literal, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(literal);
 }
 
@@ -875,8 +889,11 @@
   Node* literal_index = jsgraph()->Constant(expr->literal_index());
   Node* constants = jsgraph()->Constant(expr->constant_properties());
   Node* flags = jsgraph()->Constant(expr->ComputeFlags());
-  const Operator* op = javascript()->Runtime(Runtime::kCreateObjectLiteral, 4);
+  const Operator* op =
+      javascript()->CallRuntime(Runtime::kCreateObjectLiteral, 4);
   Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
+  PrepareFrameState(literal, expr->CreateLiteralId(),
+                    OutputFrameStateCombine::Push());
 
   // The object is expected on the operand stack during computation of the
   // property values and is the value of the entire expression.
@@ -924,7 +941,8 @@
         Node* receiver = environment()->Pop();
         if (property->emit_store()) {
           Node* strict = jsgraph()->Constant(SLOPPY);
-          const Operator* op = javascript()->Runtime(Runtime::kSetProperty, 4);
+          const Operator* op =
+              javascript()->CallRuntime(Runtime::kSetProperty, 4);
           NewNode(op, receiver, key, value, strict);
         }
         break;
@@ -935,8 +953,12 @@
         Node* value = environment()->Pop();
         Node* receiver = environment()->Pop();
         if (property->emit_store()) {
-          const Operator* op = javascript()->Runtime(Runtime::kSetPrototype, 2);
-          NewNode(op, receiver, value);
+          const Operator* op =
+              javascript()->CallRuntime(Runtime::kInternalSetPrototype, 2);
+          Node* set_prototype = NewNode(op, receiver, value);
+          // SetPrototype should not lazy deopt on an object
+          // literal.
+          PrepareFrameState(set_prototype, BailoutId::None());
         }
         break;
       }
@@ -961,14 +983,16 @@
     Node* name = environment()->Pop();
     Node* attr = jsgraph()->Constant(NONE);
     const Operator* op =
-        javascript()->Runtime(Runtime::kDefineAccessorPropertyUnchecked, 5);
+        javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
     Node* call = NewNode(op, literal, name, getter, setter, attr);
-    PrepareFrameState(call, it->first->id());
+    // This should not lazy deopt on a new literal.
+    PrepareFrameState(call, BailoutId::None());
   }
 
   // Transform literals that contain functions to fast properties.
   if (expr->has_function()) {
-    const Operator* op = javascript()->Runtime(Runtime::kToFastProperties, 1);
+    const Operator* op =
+        javascript()->CallRuntime(Runtime::kToFastProperties, 1);
     NewNode(op, literal);
   }
 
@@ -986,7 +1010,8 @@
   Node* literal_index = jsgraph()->Constant(expr->literal_index());
   Node* constants = jsgraph()->Constant(expr->constant_elements());
   Node* flags = jsgraph()->Constant(expr->ComputeFlags());
-  const Operator* op = javascript()->Runtime(Runtime::kCreateArrayLiteral, 4);
+  const Operator* op =
+      javascript()->CallRuntime(Runtime::kCreateArrayLiteral, 4);
   Node* literal = NewNode(op, literals_array, literal_index, constants, flags);
 
   // The array and the literal index are both expected on the operand stack
@@ -1086,23 +1111,31 @@
     Node* old_value = NULL;
     switch (assign_type) {
       case VARIABLE: {
-        Variable* variable = expr->target()->AsVariableProxy()->var();
-        old_value = BuildVariableLoad(variable, expr->target()->id());
+        VariableProxy* proxy = expr->target()->AsVariableProxy();
+        VectorSlotPair pair =
+            CreateVectorSlotPair(proxy->VariableFeedbackSlot());
+        old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair);
         break;
       }
       case NAMED_PROPERTY: {
         Node* object = environment()->Top();
         Unique<Name> name =
             MakeUnique(property->key()->AsLiteral()->AsPropertyName());
-        old_value = NewNode(javascript()->LoadNamed(name), object);
-        PrepareFrameState(old_value, property->LoadId(), kPushOutput);
+        VectorSlotPair pair =
+            CreateVectorSlotPair(property->PropertyFeedbackSlot());
+        old_value = NewNode(javascript()->LoadNamed(name, pair), object);
+        PrepareFrameState(old_value, property->LoadId(),
+                          OutputFrameStateCombine::Push());
         break;
       }
       case KEYED_PROPERTY: {
         Node* key = environment()->Top();
         Node* object = environment()->Peek(1);
-        old_value = NewNode(javascript()->LoadProperty(), object, key);
-        PrepareFrameState(old_value, property->LoadId(), kPushOutput);
+        VectorSlotPair pair =
+            CreateVectorSlotPair(property->PropertyFeedbackSlot());
+        old_value = NewNode(javascript()->LoadProperty(pair), object, key);
+        PrepareFrameState(old_value, property->LoadId(),
+                          OutputFrameStateCombine::Push());
         break;
       }
     }
@@ -1111,7 +1144,8 @@
     Node* right = environment()->Pop();
     Node* left = environment()->Pop();
     Node* value = BuildBinaryOp(left, right, expr->binary_op());
-    PrepareFrameState(value, expr->binary_operation()->id(), kPushOutput);
+    PrepareFrameState(value, expr->binary_operation()->id(),
+                      OutputFrameStateCombine::Push());
     environment()->Push(value);
   } else {
     VisitForValue(expr->value());
@@ -1122,8 +1156,8 @@
   switch (assign_type) {
     case VARIABLE: {
       Variable* variable = expr->target()->AsVariableProxy()->var();
-      BuildVariableAssignment(variable, value, expr->op(),
-                              expr->AssignmentId());
+      BuildVariableAssignment(variable, value, expr->op(), expr->AssignmentId(),
+                              ast_context()->GetStateCombine());
       break;
     }
     case NAMED_PROPERTY: {
@@ -1132,7 +1166,8 @@
           MakeUnique(property->key()->AsLiteral()->AsPropertyName());
       Node* store =
           NewNode(javascript()->StoreNamed(strict_mode(), name), object, value);
-      PrepareFrameState(store, expr->AssignmentId());
+      PrepareFrameState(store, expr->AssignmentId(),
+                        ast_context()->GetStateCombine());
       break;
     }
     case KEYED_PROPERTY: {
@@ -1140,7 +1175,8 @@
       Node* object = environment()->Pop();
       Node* store = NewNode(javascript()->StoreProperty(strict_mode()), object,
                             key, value);
-      PrepareFrameState(store, expr->AssignmentId());
+      PrepareFrameState(store, expr->AssignmentId(),
+                        ast_context()->GetStateCombine());
       break;
     }
   }
@@ -1162,25 +1198,27 @@
 void AstGraphBuilder::VisitThrow(Throw* expr) {
   VisitForValue(expr->exception());
   Node* exception = environment()->Pop();
-  const Operator* op = javascript()->Runtime(Runtime::kThrow, 1);
+  const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1);
   Node* value = NewNode(op, exception);
+  PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(value);
 }
 
 
 void AstGraphBuilder::VisitProperty(Property* expr) {
   Node* value;
+  VectorSlotPair pair = CreateVectorSlotPair(expr->PropertyFeedbackSlot());
   if (expr->key()->IsPropertyName()) {
     VisitForValue(expr->obj());
     Node* object = environment()->Pop();
     Unique<Name> name = MakeUnique(expr->key()->AsLiteral()->AsPropertyName());
-    value = NewNode(javascript()->LoadNamed(name), object);
+    value = NewNode(javascript()->LoadNamed(name, pair), object);
   } else {
     VisitForValue(expr->obj());
     VisitForValue(expr->key());
     Node* key = environment()->Pop();
     Node* object = environment()->Pop();
-    value = NewNode(javascript()->LoadProperty(), object, key);
+    value = NewNode(javascript()->LoadProperty(pair), object, key);
   }
   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(value);
@@ -1199,8 +1237,10 @@
   bool possibly_eval = false;
   switch (call_type) {
     case Call::GLOBAL_CALL: {
-      Variable* variable = callee->AsVariableProxy()->var();
-      callee_value = BuildVariableLoad(variable, expr->expression()->id());
+      VariableProxy* proxy = callee->AsVariableProxy();
+      VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
+      callee_value =
+          BuildVariableLoad(proxy->var(), expr->expression()->id(), pair);
       receiver_value = jsgraph()->UndefinedConstant();
       break;
     }
@@ -1208,26 +1248,33 @@
       Variable* variable = callee->AsVariableProxy()->var();
       DCHECK(variable->location() == Variable::LOOKUP);
       Node* name = jsgraph()->Constant(variable->name());
-      const Operator* op = javascript()->Runtime(Runtime::kLoadLookupSlot, 2);
+      const Operator* op =
+          javascript()->CallRuntime(Runtime::kLoadLookupSlot, 2);
       Node* pair = NewNode(op, current_context(), name);
       callee_value = NewNode(common()->Projection(0), pair);
       receiver_value = NewNode(common()->Projection(1), pair);
+
+      PrepareFrameState(pair, expr->EvalOrLookupId(),
+                        OutputFrameStateCombine::Push(2));
       break;
     }
     case Call::PROPERTY_CALL: {
       Property* property = callee->AsProperty();
       VisitForValue(property->obj());
       Node* object = environment()->Top();
+      VectorSlotPair pair =
+          CreateVectorSlotPair(property->PropertyFeedbackSlot());
       if (property->key()->IsPropertyName()) {
         Unique<Name> name =
             MakeUnique(property->key()->AsLiteral()->AsPropertyName());
-        callee_value = NewNode(javascript()->LoadNamed(name), object);
+        callee_value = NewNode(javascript()->LoadNamed(name, pair), object);
       } else {
         VisitForValue(property->key());
         Node* key = environment()->Pop();
-        callee_value = NewNode(javascript()->LoadProperty(), object, key);
+        callee_value = NewNode(javascript()->LoadProperty(pair), object, key);
       }
-      PrepareFrameState(callee_value, property->LoadId(), kPushOutput);
+      PrepareFrameState(callee_value, property->LoadId(),
+                        OutputFrameStateCombine::Push());
       receiver_value = environment()->Pop();
       // Note that a PROPERTY_CALL requires the receiver to be wrapped into an
       // object for sloppy callees. This could also be modeled explicitly here,
@@ -1235,6 +1282,11 @@
       flags = CALL_AS_METHOD;
       break;
     }
+    case Call::SUPER_CALL: {
+      // todo(dslomov): implement super calls in turbofan.
+      UNIMPLEMENTED();
+      break;
+    }
     case Call::POSSIBLY_EVAL_CALL:
       possibly_eval = true;
     // Fall through.
@@ -1270,9 +1322,11 @@
     Node* strict = jsgraph()->Constant(strict_mode());
     Node* position = jsgraph()->Constant(info()->scope()->start_position());
     const Operator* op =
-        javascript()->Runtime(Runtime::kResolvePossiblyDirectEval, 6);
+        javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
     Node* pair =
         NewNode(op, callee, source, function, receiver, strict, position);
+    PrepareFrameState(pair, expr->EvalOrLookupId(),
+                      OutputFrameStateCombine::PokeAt(arg_count + 1));
     Node* new_callee = NewNode(common()->Projection(0), pair);
     Node* new_receiver = NewNode(common()->Projection(1), pair);
 
@@ -1282,7 +1336,7 @@
   }
 
   // Create node to perform the function call.
-  const Operator* call = javascript()->Call(args->length() + 2, flags);
+  const Operator* call = javascript()->CallFunction(args->length() + 2, flags);
   Node* value = ProcessArguments(call, args->length() + 2);
   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(value);
@@ -1297,7 +1351,7 @@
   VisitForValues(args);
 
   // Create node to perform the construct call.
-  const Operator* call = javascript()->CallNew(args->length() + 1);
+  const Operator* call = javascript()->CallConstruct(args->length() + 1);
   Node* value = ProcessArguments(call, args->length() + 1);
   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(value);
@@ -1312,10 +1366,13 @@
   CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS;
   Node* receiver_value = BuildLoadBuiltinsObject();
   Unique<String> unique = MakeUnique(name);
-  Node* callee_value = NewNode(javascript()->LoadNamed(unique), receiver_value);
+  VectorSlotPair pair = CreateVectorSlotPair(expr->CallRuntimeFeedbackSlot());
+  Node* callee_value =
+      NewNode(javascript()->LoadNamed(unique, pair), receiver_value);
   // TODO(jarin): Find/create a bailout id to deoptimize to (crankshaft
   // refuses to optimize functions with jsruntime calls).
-  PrepareFrameState(callee_value, BailoutId::None(), kPushOutput);
+  PrepareFrameState(callee_value, BailoutId::None(),
+                    OutputFrameStateCombine::Push());
   environment()->Push(callee_value);
   environment()->Push(receiver_value);
 
@@ -1324,7 +1381,7 @@
   VisitForValues(args);
 
   // Create node to perform the JS runtime call.
-  const Operator* call = javascript()->Call(args->length() + 2, flags);
+  const Operator* call = javascript()->CallFunction(args->length() + 2, flags);
   Node* value = ProcessArguments(call, args->length() + 2);
   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(value);
@@ -1347,7 +1404,7 @@
 
   // Create node to perform the runtime call.
   Runtime::FunctionId functionId = function->function_id;
-  const Operator* call = javascript()->Runtime(functionId, args->length());
+  const Operator* call = javascript()->CallRuntime(functionId, args->length());
   Node* value = ProcessArguments(call, args->length());
   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   ast_context()->ProduceValue(value);
@@ -1386,8 +1443,10 @@
   int stack_depth = -1;
   switch (assign_type) {
     case VARIABLE: {
-      Variable* variable = expr->expression()->AsVariableProxy()->var();
-      old_value = BuildVariableLoad(variable, expr->expression()->id());
+      VariableProxy* proxy = expr->expression()->AsVariableProxy();
+      VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
+      old_value =
+          BuildVariableLoad(proxy->var(), expr->expression()->id(), pair);
       stack_depth = 0;
       break;
     }
@@ -1396,8 +1455,11 @@
       Node* object = environment()->Top();
       Unique<Name> name =
           MakeUnique(property->key()->AsLiteral()->AsPropertyName());
-      old_value = NewNode(javascript()->LoadNamed(name), object);
-      PrepareFrameState(old_value, property->LoadId(), kPushOutput);
+      VectorSlotPair pair =
+          CreateVectorSlotPair(property->PropertyFeedbackSlot());
+      old_value = NewNode(javascript()->LoadNamed(name, pair), object);
+      PrepareFrameState(old_value, property->LoadId(),
+                        OutputFrameStateCombine::Push());
       stack_depth = 1;
       break;
     }
@@ -1406,8 +1468,11 @@
       VisitForValue(property->key());
       Node* key = environment()->Top();
       Node* object = environment()->Peek(1);
-      old_value = NewNode(javascript()->LoadProperty(), object, key);
-      PrepareFrameState(old_value, property->LoadId(), kPushOutput);
+      VectorSlotPair pair =
+          CreateVectorSlotPair(property->PropertyFeedbackSlot());
+      old_value = NewNode(javascript()->LoadProperty(pair), object, key);
+      PrepareFrameState(old_value, property->LoadId(),
+                        OutputFrameStateCombine::Push());
       stack_depth = 2;
       break;
     }
@@ -1548,20 +1613,21 @@
 
 
 void AstGraphBuilder::VisitDeclarations(ZoneList<Declaration*>* declarations) {
-  DCHECK(globals()->is_empty());
+  DCHECK(globals()->empty());
   AstVisitor::VisitDeclarations(declarations);
-  if (globals()->is_empty()) return;
-  Handle<FixedArray> data =
-      isolate()->factory()->NewFixedArray(globals()->length(), TENURED);
-  for (int i = 0; i < globals()->length(); ++i) data->set(i, *globals()->at(i));
+  if (globals()->empty()) return;
+  int array_index = 0;
+  Handle<FixedArray> data = isolate()->factory()->NewFixedArray(
+      static_cast<int>(globals()->size()), TENURED);
+  for (Handle<Object> obj : *globals()) data->set(array_index++, *obj);
   int encoded_flags = DeclareGlobalsEvalFlag::encode(info()->is_eval()) |
                       DeclareGlobalsNativeFlag::encode(info()->is_native()) |
                       DeclareGlobalsStrictMode::encode(strict_mode());
   Node* flags = jsgraph()->Constant(encoded_flags);
   Node* pairs = jsgraph()->Constant(data);
-  const Operator* op = javascript()->Runtime(Runtime::kDeclareGlobals, 3);
+  const Operator* op = javascript()->CallRuntime(Runtime::kDeclareGlobals, 3);
   NewNode(op, current_context(), pairs, flags);
-  globals()->Rewind(0);
+  globals()->clear();
 }
 
 
@@ -1585,7 +1651,8 @@
     // deleting "this" is allowed in all language modes.
     Variable* variable = expr->expression()->AsVariableProxy()->var();
     DCHECK(strict_mode() == SLOPPY || variable->is_this());
-    value = BuildVariableDelete(variable);
+    value = BuildVariableDelete(variable, expr->id(),
+                                ast_context()->GetStateCombine());
   } else if (expr->expression()->IsProperty()) {
     Property* property = expr->expression()->AsProperty();
     VisitForValue(property->obj());
@@ -1593,6 +1660,7 @@
     Node* key = environment()->Pop();
     Node* object = environment()->Pop();
     value = NewNode(javascript()->DeleteProperty(strict_mode()), object, key);
+    PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine());
   } else {
     VisitForEffect(expr->expression());
     value = jsgraph()->TrueConstant();
@@ -1613,9 +1681,10 @@
   if (expr->expression()->IsVariableProxy()) {
     // Typeof does not throw a reference error on global variables, hence we
     // perform a non-contextual load in case the operand is a variable proxy.
-    Variable* variable = expr->expression()->AsVariableProxy()->var();
-    operand =
-        BuildVariableLoad(variable, expr->expression()->id(), NOT_CONTEXTUAL);
+    VariableProxy* proxy = expr->expression()->AsVariableProxy();
+    VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
+    operand = BuildVariableLoad(proxy->var(), expr->expression()->id(), pair,
+                                NOT_CONTEXTUAL);
   } else {
     VisitForValue(expr->expression());
     operand = environment()->Pop();
@@ -1666,6 +1735,17 @@
 }
 
 
+StrictMode AstGraphBuilder::strict_mode() const {
+  return info()->strict_mode();
+}
+
+
+VectorSlotPair AstGraphBuilder::CreateVectorSlotPair(
+    FeedbackVectorICSlot slot) const {
+  return VectorSlotPair(handle(info()->shared_info()->feedback_vector()), slot);
+}
+
+
 Node* AstGraphBuilder::ProcessArguments(const Operator* op, int arity) {
   DCHECK(environment()->stack_height() >= arity);
   Node** all = info()->zone()->NewArray<Node*>(arity);
@@ -1677,10 +1757,36 @@
 }
 
 
+Node* AstGraphBuilder::BuildPatchReceiverToGlobalProxy(Node* receiver) {
+  // Sloppy mode functions and builtins need to replace the receiver with the
+  // global proxy when called as functions (without an explicit receiver
+  // object). Otherwise there is nothing left to do here.
+  if (info()->strict_mode() != SLOPPY || info()->is_native()) return receiver;
+
+  // There is no need to perform patching if the receiver is never used. Note
+  // that scope predicates are purely syntactical, a call to eval might still
+  // inspect the receiver value.
+  if (!info()->scope()->uses_this() && !info()->scope()->inner_uses_this() &&
+      !info()->scope()->calls_sloppy_eval()) {
+    return receiver;
+  }
+
+  IfBuilder receiver_check(this);
+  Node* undefined = jsgraph()->UndefinedConstant();
+  Node* check = NewNode(javascript()->StrictEqual(), receiver, undefined);
+  receiver_check.If(check);
+  receiver_check.Then();
+  environment()->Push(BuildLoadGlobalProxy());
+  receiver_check.Else();
+  environment()->Push(receiver);
+  receiver_check.End();
+  return environment()->Pop();
+}
+
+
 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) {
   int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
   if (heap_slots <= 0) return context;
-  set_current_context(context);
 
   // Allocate a new local context.
   const Operator* op = javascript()->CreateFunctionContext();
@@ -1710,7 +1816,7 @@
 
   // Allocate and initialize a new arguments object.
   Node* callee = GetFunctionClosure();
-  const Operator* op = javascript()->Runtime(Runtime::kNewArguments, 1);
+  const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1);
   Node* object = NewNode(op, callee);
 
   // Assign the object to the arguments variable.
@@ -1738,13 +1844,14 @@
 
 
 Node* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable,
-                                           Node* not_hole) {
+                                           Node* not_hole,
+                                           BailoutId bailout_id) {
   IfBuilder hole_check(this);
   Node* the_hole = jsgraph()->TheHoleConstant();
   Node* check = NewNode(javascript()->StrictEqual(), value, the_hole);
   hole_check.If(check);
   hole_check.Then();
-  environment()->Push(BuildThrowReferenceError(variable));
+  environment()->Push(BuildThrowReferenceError(variable, bailout_id));
   hole_check.Else();
   environment()->Push(not_hole);
   hole_check.End();
@@ -1754,6 +1861,7 @@
 
 Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
                                          BailoutId bailout_id,
+                                         const VectorSlotPair& feedback,
                                          ContextualMode contextual_mode) {
   Node* the_hole = jsgraph()->TheHoleConstant();
   VariableMode mode = variable->mode();
@@ -1762,9 +1870,10 @@
       // Global var, const, or let variable.
       Node* global = BuildLoadGlobalObject();
       Unique<Name> name = MakeUnique(variable->name());
-      const Operator* op = javascript()->LoadNamed(name, contextual_mode);
+      const Operator* op =
+          javascript()->LoadNamed(name, feedback, contextual_mode);
       Node* node = NewNode(op, global);
-      PrepareFrameState(node, bailout_id, kPushOutput);
+      PrepareFrameState(node, bailout_id, OutputFrameStateCombine::Push());
       return node;
     }
     case Variable::PARAMETER:
@@ -1782,9 +1891,9 @@
       } else if (mode == LET || mode == CONST) {
         // Perform check for uninitialized let/const variables.
         if (value->op() == the_hole->op()) {
-          value = BuildThrowReferenceError(variable);
+          value = BuildThrowReferenceError(variable, bailout_id);
         } else if (value->opcode() == IrOpcode::kPhi) {
-          value = BuildHoleCheckThrow(value, variable, value);
+          value = BuildHoleCheckThrow(value, variable, value, bailout_id);
         }
       }
       return value;
@@ -1805,7 +1914,7 @@
         value = BuildHoleCheckSilent(value, undefined, value);
       } else if (mode == LET || mode == CONST) {
         // Perform check for uninitialized let/const variables.
-        value = BuildHoleCheckThrow(value, variable, value);
+        value = BuildHoleCheckThrow(value, variable, value, bailout_id);
       }
       return value;
     }
@@ -1816,8 +1925,9 @@
           (contextual_mode == CONTEXTUAL)
               ? Runtime::kLoadLookupSlot
               : Runtime::kLoadLookupSlotNoReferenceError;
-      const Operator* op = javascript()->Runtime(function_id, 2);
+      const Operator* op = javascript()->CallRuntime(function_id, 2);
       Node* pair = NewNode(op, current_context(), name);
+      PrepareFrameState(pair, bailout_id, OutputFrameStateCombine::Push(1));
       return NewNode(common()->Projection(0), pair);
     }
   }
@@ -1826,26 +1936,32 @@
 }
 
 
-Node* AstGraphBuilder::BuildVariableDelete(Variable* variable) {
+Node* AstGraphBuilder::BuildVariableDelete(
+    Variable* variable, BailoutId bailout_id,
+    OutputFrameStateCombine state_combine) {
   switch (variable->location()) {
     case Variable::UNALLOCATED: {
       // Global var, const, or let variable.
       Node* global = BuildLoadGlobalObject();
       Node* name = jsgraph()->Constant(variable->name());
       const Operator* op = javascript()->DeleteProperty(strict_mode());
-      return NewNode(op, global, name);
+      Node* result = NewNode(op, global, name);
+      PrepareFrameState(result, bailout_id, state_combine);
+      return result;
     }
     case Variable::PARAMETER:
     case Variable::LOCAL:
     case Variable::CONTEXT:
       // Local var, const, or let variable or context variable.
-      return variable->is_this() ? jsgraph()->TrueConstant()
-                                 : jsgraph()->FalseConstant();
+      return jsgraph()->BooleanConstant(variable->is_this());
     case Variable::LOOKUP: {
       // Dynamic lookup of context variable (anywhere in the chain).
       Node* name = jsgraph()->Constant(variable->name());
-      const Operator* op = javascript()->Runtime(Runtime::kDeleteLookupSlot, 2);
-      return NewNode(op, current_context(), name);
+      const Operator* op =
+          javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2);
+      Node* result = NewNode(op, current_context(), name);
+      PrepareFrameState(result, bailout_id, state_combine);
+      return result;
     }
   }
   UNREACHABLE();
@@ -1853,9 +1969,9 @@
 }
 
 
-Node* AstGraphBuilder::BuildVariableAssignment(Variable* variable, Node* value,
-                                               Token::Value op,
-                                               BailoutId bailout_id) {
+Node* AstGraphBuilder::BuildVariableAssignment(
+    Variable* variable, Node* value, Token::Value op, BailoutId bailout_id,
+    OutputFrameStateCombine combine) {
   Node* the_hole = jsgraph()->TheHoleConstant();
   VariableMode mode = variable->mode();
   switch (variable->location()) {
@@ -1865,7 +1981,7 @@
       Unique<Name> name = MakeUnique(variable->name());
       const Operator* op = javascript()->StoreNamed(strict_mode(), name);
       Node* store = NewNode(op, global, value);
-      PrepareFrameState(store, bailout_id);
+      PrepareFrameState(store, bailout_id, combine);
       return store;
     }
     case Variable::PARAMETER:
@@ -1878,7 +1994,12 @@
           value = BuildHoleCheckSilent(current, value, current);
         }
       } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) {
-        // Non-initializing assignments to legacy const is ignored.
+        // Non-initializing assignments to legacy const is
+        // - exception in strict mode.
+        // - ignored in sloppy mode.
+        if (strict_mode() == STRICT) {
+          return BuildThrowConstAssignError(bailout_id);
+        }
         return value;
       } else if (mode == LET && op != Token::INIT_LET) {
         // Perform an initialization check for let declared variables.
@@ -1887,13 +2008,13 @@
         // temporal dead zone of a let declared variable.
         Node* current = environment()->Lookup(variable);
         if (current->op() == the_hole->op()) {
-          value = BuildThrowReferenceError(variable);
+          value = BuildThrowReferenceError(variable, bailout_id);
         } else if (value->opcode() == IrOpcode::kPhi) {
-          value = BuildHoleCheckThrow(current, variable, value);
+          value = BuildHoleCheckThrow(current, variable, value, bailout_id);
         }
       } else if (mode == CONST && op != Token::INIT_CONST) {
-        // All assignments to const variables are early errors.
-        UNREACHABLE();
+        // Non-initializing assignments to const is exception in all modes.
+        return BuildThrowConstAssignError(bailout_id);
       }
       environment()->Bind(variable, value);
       return value;
@@ -1907,17 +2028,22 @@
         Node* current = NewNode(op, current_context());
         value = BuildHoleCheckSilent(current, value, current);
       } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) {
-        // Non-initializing assignments to legacy const is ignored.
+        // Non-initializing assignments to legacy const is
+        // - exception in strict mode.
+        // - ignored in sloppy mode.
+        if (strict_mode() == STRICT) {
+          return BuildThrowConstAssignError(bailout_id);
+        }
         return value;
       } else if (mode == LET && op != Token::INIT_LET) {
         // Perform an initialization check for let declared variables.
         const Operator* op =
             javascript()->LoadContext(depth, variable->index(), false);
         Node* current = NewNode(op, current_context());
-        value = BuildHoleCheckThrow(current, variable, value);
+        value = BuildHoleCheckThrow(current, variable, value, bailout_id);
       } else if (mode == CONST && op != Token::INIT_CONST) {
-        // All assignments to const variables are early errors.
-        UNREACHABLE();
+        // Non-initializing assignments to const is exception in all modes.
+        return BuildThrowConstAssignError(bailout_id);
       }
       const Operator* op = javascript()->StoreContext(depth, variable->index());
       return NewNode(op, current_context(), value);
@@ -1928,8 +2054,11 @@
       Node* strict = jsgraph()->Constant(strict_mode());
       // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for
       // initializations of const declarations.
-      const Operator* op = javascript()->Runtime(Runtime::kStoreLookupSlot, 4);
-      return NewNode(op, value, current_context(), name, strict);
+      const Operator* op =
+          javascript()->CallRuntime(Runtime::kStoreLookupSlot, 4);
+      Node* store = NewNode(op, value, current_context(), name, strict);
+      PrepareFrameState(store, bailout_id, combine);
+      return store;
     }
   }
   UNREACHABLE();
@@ -1938,7 +2067,6 @@
 
 
 Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
-  // TODO(sigurds) Use simplified load here once it is ready.
   Node* field_load = NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
                              jsgraph()->Int32Constant(offset - kHeapObjectTag));
   return field_load;
@@ -1961,17 +2089,61 @@
 }
 
 
-Node* AstGraphBuilder::BuildToBoolean(Node* value) {
-  // TODO(mstarzinger): Possible optimization is to NOP for boolean values.
-  return NewNode(javascript()->ToBoolean(), value);
+Node* AstGraphBuilder::BuildLoadGlobalProxy() {
+  Node* global = BuildLoadGlobalObject();
+  Node* proxy =
+      BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset);
+  return proxy;
 }
 
 
-Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable) {
+Node* AstGraphBuilder::BuildToBoolean(Node* input) {
+  // TODO(titzer): this should be in a JSOperatorReducer.
+  switch (input->opcode()) {
+    case IrOpcode::kInt32Constant:
+      return jsgraph_->BooleanConstant(!Int32Matcher(input).Is(0));
+    case IrOpcode::kFloat64Constant:
+      return jsgraph_->BooleanConstant(!Float64Matcher(input).Is(0));
+    case IrOpcode::kNumberConstant:
+      return jsgraph_->BooleanConstant(!NumberMatcher(input).Is(0));
+    case IrOpcode::kHeapConstant: {
+      Handle<Object> object = HeapObjectMatcher<Object>(input).Value().handle();
+      if (object->IsTrue()) return jsgraph_->TrueConstant();
+      if (object->IsFalse()) return jsgraph_->FalseConstant();
+      // TODO(turbofan): other constants.
+      break;
+    }
+    default:
+      break;
+  }
+  if (NodeProperties::IsTyped(input)) {
+    Type* upper = NodeProperties::GetBounds(input).upper;
+    if (upper->Is(Type::Boolean())) return input;
+  }
+
+  return NewNode(javascript()->ToBoolean(), input);
+}
+
+
+Node* AstGraphBuilder::BuildThrowReferenceError(Variable* variable,
+                                                BailoutId bailout_id) {
   // TODO(mstarzinger): Should be unified with the VisitThrow implementation.
   Node* variable_name = jsgraph()->Constant(variable->name());
-  const Operator* op = javascript()->Runtime(Runtime::kThrowReferenceError, 1);
-  return NewNode(op, variable_name);
+  const Operator* op =
+      javascript()->CallRuntime(Runtime::kThrowReferenceError, 1);
+  Node* call = NewNode(op, variable_name);
+  PrepareFrameState(call, bailout_id);
+  return call;
+}
+
+
+Node* AstGraphBuilder::BuildThrowConstAssignError(BailoutId bailout_id) {
+  // TODO(mstarzinger): Should be unified with the VisitThrow implementation.
+  const Operator* op =
+      javascript()->CallRuntime(Runtime::kThrowConstAssignError, 0);
+  Node* call = NewNode(op);
+  PrepareFrameState(call, bailout_id);
+  return call;
 }
 
 
@@ -2019,6 +2191,24 @@
 }
 
 
+Node* AstGraphBuilder::BuildStackCheck() {
+  IfBuilder stack_check(this);
+  Node* limit =
+      NewNode(jsgraph()->machine()->Load(kMachPtr),
+              jsgraph()->ExternalConstant(
+                  ExternalReference::address_of_stack_limit(isolate())),
+              jsgraph()->ZeroConstant());
+  Node* stack = NewNode(jsgraph()->machine()->LoadStackPointer());
+  Node* tag = NewNode(jsgraph()->machine()->UintLessThan(), limit, stack);
+  stack_check.If(tag, BranchHint::kTrue);
+  stack_check.Then();
+  stack_check.Else();
+  Node* guard = NewNode(javascript()->CallRuntime(Runtime::kStackGuard, 0));
+  stack_check.End();
+  return guard;
+}
+
+
 void AstGraphBuilder::PrepareFrameState(Node* node, BailoutId ast_id,
                                         OutputFrameStateCombine combine) {
   if (OperatorProperties::HasFrameStateInput(node->op())) {
@@ -2029,6 +2219,13 @@
   }
 }
 
+
+BitVector* AstGraphBuilder::GetVariablesAssignedInLoop(
+    IterationStatement* stmt) {
+  if (loop_assignment_analysis_ == NULL) return NULL;
+  return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt);
 }
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/ast-graph-builder.h b/src/compiler/ast-graph-builder.h
index 6a7e3db..0337c81 100644
--- a/src/compiler/ast-graph-builder.h
+++ b/src/compiler/ast-graph-builder.h
@@ -16,8 +16,9 @@
 namespace compiler {
 
 class ControlBuilder;
-class LoopBuilder;
 class Graph;
+class LoopAssignmentAnalysis;
+class LoopBuilder;
 
 // The AstGraphBuilder produces a high-level IR graph, based on an
 // underlying AST. The produced graph can either be compiled into a
@@ -25,7 +26,8 @@
 // of function inlining.
 class AstGraphBuilder : public StructuredGraphBuilder, public AstVisitor {
  public:
-  AstGraphBuilder(CompilationInfo* info, JSGraph* jsgraph);
+  AstGraphBuilder(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph,
+                  LoopAssignmentAnalysis* loop_assignment = NULL);
 
   // Creates a graph by visiting the entire AST.
   bool CreateGraph();
@@ -55,11 +57,7 @@
   // Support for control flow builders. The concrete type of the environment
   // depends on the graph builder, but environments themselves are not virtual.
   typedef StructuredGraphBuilder::Environment BaseEnvironment;
-  virtual BaseEnvironment* CopyEnvironment(BaseEnvironment* env);
-
-  // TODO(mstarzinger): The pipeline only needs to be a friend to access the
-  // function context. Remove as soon as the context is a parameter.
-  friend class Pipeline;
+  BaseEnvironment* CopyEnvironment(BaseEnvironment* env) OVERRIDE;
 
   // Getters for values in the activation record.
   Node* GetFunctionClosure();
@@ -71,6 +69,9 @@
   // other dependencies tracked by the environment might be mutated though.
   //
 
+  // Builder to create a receiver check for sloppy mode.
+  Node* BuildPatchReceiverToGlobalProxy(Node* receiver);
+
   // Builder to create a local function context.
   Node* BuildLocalFunctionContext(Node* context, Node* closure);
 
@@ -79,14 +80,19 @@
 
   // Builders for variable load and assignment.
   Node* BuildVariableAssignment(Variable* var, Node* value, Token::Value op,
-                                BailoutId bailout_id);
-  Node* BuildVariableDelete(Variable* var);
+                                BailoutId bailout_id,
+                                OutputFrameStateCombine state_combine =
+                                    OutputFrameStateCombine::Ignore());
+  Node* BuildVariableDelete(Variable* var, BailoutId bailout_id,
+                            OutputFrameStateCombine state_combine);
   Node* BuildVariableLoad(Variable* var, BailoutId bailout_id,
+                          const VectorSlotPair& feedback,
                           ContextualMode mode = CONTEXTUAL);
 
   // Builders for accessing the function context.
   Node* BuildLoadBuiltinsObject();
   Node* BuildLoadGlobalObject();
+  Node* BuildLoadGlobalProxy();
   Node* BuildLoadClosure();
   Node* BuildLoadObjectField(Node* object, int offset);
 
@@ -94,22 +100,27 @@
   Node* BuildToBoolean(Node* value);
 
   // Builders for error reporting at runtime.
-  Node* BuildThrowReferenceError(Variable* var);
+  Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id);
+  Node* BuildThrowConstAssignError(BailoutId bailout_id);
 
   // Builders for dynamic hole-checks at runtime.
   Node* BuildHoleCheckSilent(Node* value, Node* for_hole, Node* not_hole);
-  Node* BuildHoleCheckThrow(Node* value, Variable* var, Node* not_hole);
+  Node* BuildHoleCheckThrow(Node* value, Variable* var, Node* not_hole,
+                            BailoutId bailout_id);
 
   // Builders for binary operations.
   Node* BuildBinaryOp(Node* left, Node* right, Token::Value op);
 
-#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
+  // Builder for stack-check guards.
+  Node* BuildStackCheck();
+
+#define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE;
   // Visiting functions for AST nodes make this an AstVisitor.
   AST_NODE_LIST(DECLARE_VISIT)
 #undef DECLARE_VISIT
 
   // Visiting function for declarations list is overridden.
-  virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
+  void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE;
 
  private:
   CompilationInfo* info_;
@@ -117,7 +128,7 @@
   JSGraph* jsgraph_;
 
   // List of global declarations for functions and variables.
-  ZoneList<Handle<Object> > globals_;
+  ZoneVector<Handle<Object>> globals_;
 
   // Stack of breakable statements entered by the visitor.
   BreakableScope* breakable_;
@@ -129,15 +140,21 @@
   SetOncePointer<Node> function_closure_;
   SetOncePointer<Node> function_context_;
 
-  CompilationInfo* info() { return info_; }
-  StrictMode strict_mode() { return info()->strict_mode(); }
+  // Result of loop assignment analysis performed before graph creation.
+  LoopAssignmentAnalysis* loop_assignment_analysis_;
+
+  CompilationInfo* info() const { return info_; }
+  inline StrictMode strict_mode() const;
   JSGraph* jsgraph() { return jsgraph_; }
   JSOperatorBuilder* javascript() { return jsgraph_->javascript(); }
-  ZoneList<Handle<Object> >* globals() { return &globals_; }
+  ZoneVector<Handle<Object>>* globals() { return &globals_; }
 
   // Current scope during visitation.
   inline Scope* current_scope() const;
 
+  // Named and keyed loads require a VectorSlotPair for successful lowering.
+  VectorSlotPair CreateVectorSlotPair(FeedbackVectorICSlot slot) const;
+
   // Process arguments to a call by popping {arity} elements off the operand
   // stack and build a call node using the given call operator.
   Node* ProcessArguments(const Operator* op, int arity);
@@ -146,6 +163,7 @@
   void VisitIfNotNull(Statement* stmt);
 
   // Visit expressions.
+  void Visit(Expression* expr);
   void VisitForTest(Expression* expr);
   void VisitForEffect(Expression* expr);
   void VisitForValue(Expression* expr);
@@ -173,10 +191,11 @@
   void VisitForInAssignment(Expression* expr, Node* value);
 
   // Builds deoptimization for a given node.
-  void PrepareFrameState(Node* node, BailoutId ast_id,
-                         OutputFrameStateCombine combine = kIgnoreOutput);
+  void PrepareFrameState(
+      Node* node, BailoutId ast_id,
+      OutputFrameStateCombine combine = OutputFrameStateCombine::Ignore());
 
-  OutputFrameStateCombine StateCombineFromAstContext();
+  BitVector* GetVariablesAssignedInLoop(IterationStatement* stmt);
 
   DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
   DISALLOW_COPY_AND_ASSIGN(AstGraphBuilder);
@@ -288,7 +307,8 @@
   // Determines how to combine the frame state with the value
   // that is about to be plugged into this AstContext.
   OutputFrameStateCombine GetStateCombine() {
-    return IsEffect() ? kIgnoreOutput : kPushOutput;
+    return IsEffect() ? OutputFrameStateCombine::Ignore()
+                      : OutputFrameStateCombine::Push();
   }
 
   // Plug a node into this expression context.  Call this function in tail
@@ -327,9 +347,9 @@
  public:
   explicit AstEffectContext(AstGraphBuilder* owner)
       : AstContext(owner, Expression::kEffect) {}
-  virtual ~AstEffectContext();
-  virtual void ProduceValue(Node* value) OVERRIDE;
-  virtual Node* ConsumeValue() OVERRIDE;
+  ~AstEffectContext() FINAL;
+  void ProduceValue(Node* value) FINAL;
+  Node* ConsumeValue() FINAL;
 };
 
 
@@ -338,9 +358,9 @@
  public:
   explicit AstValueContext(AstGraphBuilder* owner)
       : AstContext(owner, Expression::kValue) {}
-  virtual ~AstValueContext();
-  virtual void ProduceValue(Node* value) OVERRIDE;
-  virtual Node* ConsumeValue() OVERRIDE;
+  ~AstValueContext() FINAL;
+  void ProduceValue(Node* value) FINAL;
+  Node* ConsumeValue() FINAL;
 };
 
 
@@ -349,9 +369,9 @@
  public:
   explicit AstTestContext(AstGraphBuilder* owner)
       : AstContext(owner, Expression::kTest) {}
-  virtual ~AstTestContext();
-  virtual void ProduceValue(Node* value) OVERRIDE;
-  virtual Node* ConsumeValue() OVERRIDE;
+  ~AstTestContext() FINAL;
+  void ProduceValue(Node* value) FINAL;
+  Node* ConsumeValue() FINAL;
 };
 
 
@@ -423,8 +443,9 @@
 Scope* AstGraphBuilder::current_scope() const {
   return execution_context_->scope();
 }
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_AST_GRAPH_BUILDER_H_
diff --git a/src/compiler/ast-loop-assignment-analyzer.cc b/src/compiler/ast-loop-assignment-analyzer.cc
new file mode 100644
index 0000000..7adac56
--- /dev/null
+++ b/src/compiler/ast-loop-assignment-analyzer.cc
@@ -0,0 +1,305 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/ast-loop-assignment-analyzer.h"
+#include "src/parser.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+typedef class AstLoopAssignmentAnalyzer ALAA;  // for code shortitude.
+
+ALAA::AstLoopAssignmentAnalyzer(Zone* zone, CompilationInfo* info)
+    : info_(info), loop_stack_(zone) {
+  InitializeAstVisitor(zone);
+}
+
+
+LoopAssignmentAnalysis* ALAA::Analyze() {
+  LoopAssignmentAnalysis* a = new (zone()) LoopAssignmentAnalysis(zone());
+  result_ = a;
+  VisitStatements(info()->function()->body());
+  result_ = NULL;
+  return a;
+}
+
+
+void ALAA::Enter(IterationStatement* loop) {
+  int num_variables = 1 + info()->scope()->num_parameters() +
+                      info()->scope()->num_stack_slots();
+  BitVector* bits = new (zone()) BitVector(num_variables, zone());
+  loop_stack_.push_back(bits);
+}
+
+
+void ALAA::Exit(IterationStatement* loop) {
+  DCHECK(loop_stack_.size() > 0);
+  BitVector* bits = loop_stack_.back();
+  loop_stack_.pop_back();
+  if (!loop_stack_.empty()) {
+    loop_stack_.back()->Union(*bits);
+  }
+  result_->list_.push_back(
+      std::pair<IterationStatement*, BitVector*>(loop, bits));
+}
+
+
+// ---------------------------------------------------------------------------
+// -- Leaf nodes -------------------------------------------------------------
+// ---------------------------------------------------------------------------
+
+void ALAA::VisitVariableDeclaration(VariableDeclaration* leaf) {}
+void ALAA::VisitFunctionDeclaration(FunctionDeclaration* leaf) {}
+void ALAA::VisitModuleDeclaration(ModuleDeclaration* leaf) {}
+void ALAA::VisitImportDeclaration(ImportDeclaration* leaf) {}
+void ALAA::VisitExportDeclaration(ExportDeclaration* leaf) {}
+void ALAA::VisitModuleVariable(ModuleVariable* leaf) {}
+void ALAA::VisitModulePath(ModulePath* leaf) {}
+void ALAA::VisitModuleUrl(ModuleUrl* leaf) {}
+void ALAA::VisitEmptyStatement(EmptyStatement* leaf) {}
+void ALAA::VisitContinueStatement(ContinueStatement* leaf) {}
+void ALAA::VisitBreakStatement(BreakStatement* leaf) {}
+void ALAA::VisitDebuggerStatement(DebuggerStatement* leaf) {}
+void ALAA::VisitFunctionLiteral(FunctionLiteral* leaf) {}
+void ALAA::VisitNativeFunctionLiteral(NativeFunctionLiteral* leaf) {}
+void ALAA::VisitVariableProxy(VariableProxy* leaf) {}
+void ALAA::VisitLiteral(Literal* leaf) {}
+void ALAA::VisitRegExpLiteral(RegExpLiteral* leaf) {}
+void ALAA::VisitThisFunction(ThisFunction* leaf) {}
+void ALAA::VisitSuperReference(SuperReference* leaf) {}
+
+
+// ---------------------------------------------------------------------------
+// -- Pass-through nodes------------------------------------------------------
+// ---------------------------------------------------------------------------
+void ALAA::VisitModuleLiteral(ModuleLiteral* e) { Visit(e->body()); }
+
+
+void ALAA::VisitBlock(Block* stmt) { VisitStatements(stmt->statements()); }
+
+
+void ALAA::VisitExpressionStatement(ExpressionStatement* stmt) {
+  Visit(stmt->expression());
+}
+
+
+void ALAA::VisitIfStatement(IfStatement* stmt) {
+  Visit(stmt->condition());
+  Visit(stmt->then_statement());
+  Visit(stmt->else_statement());
+}
+
+
+void ALAA::VisitReturnStatement(ReturnStatement* stmt) {
+  Visit(stmt->expression());
+}
+
+
+void ALAA::VisitWithStatement(WithStatement* stmt) {
+  Visit(stmt->expression());
+  Visit(stmt->statement());
+}
+
+
+void ALAA::VisitSwitchStatement(SwitchStatement* stmt) {
+  Visit(stmt->tag());
+  ZoneList<CaseClause*>* clauses = stmt->cases();
+  for (int i = 0; i < clauses->length(); i++) {
+    Visit(clauses->at(i));
+  }
+}
+
+
+void ALAA::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
+  Visit(stmt->try_block());
+  Visit(stmt->finally_block());
+}
+
+
+void ALAA::VisitClassLiteral(ClassLiteral* e) {
+  VisitIfNotNull(e->extends());
+  VisitIfNotNull(e->constructor());
+  ZoneList<ObjectLiteralProperty*>* properties = e->properties();
+  for (int i = 0; i < properties->length(); i++) {
+    Visit(properties->at(i)->value());
+  }
+}
+
+
+void ALAA::VisitConditional(Conditional* e) {
+  Visit(e->condition());
+  Visit(e->then_expression());
+  Visit(e->else_expression());
+}
+
+
+void ALAA::VisitObjectLiteral(ObjectLiteral* e) {
+  ZoneList<ObjectLiteralProperty*>* properties = e->properties();
+  for (int i = 0; i < properties->length(); i++) {
+    Visit(properties->at(i)->value());
+  }
+}
+
+
+void ALAA::VisitArrayLiteral(ArrayLiteral* e) { VisitExpressions(e->values()); }
+
+
+void ALAA::VisitYield(Yield* stmt) {
+  Visit(stmt->generator_object());
+  Visit(stmt->expression());
+}
+
+
+void ALAA::VisitThrow(Throw* stmt) { Visit(stmt->exception()); }
+
+
+void ALAA::VisitProperty(Property* e) {
+  Visit(e->obj());
+  Visit(e->key());
+}
+
+
+void ALAA::VisitCall(Call* e) {
+  Visit(e->expression());
+  VisitExpressions(e->arguments());
+}
+
+
+void ALAA::VisitCallNew(CallNew* e) {
+  Visit(e->expression());
+  VisitExpressions(e->arguments());
+}
+
+
+void ALAA::VisitCallRuntime(CallRuntime* e) {
+  VisitExpressions(e->arguments());
+}
+
+
+void ALAA::VisitUnaryOperation(UnaryOperation* e) { Visit(e->expression()); }
+
+
+void ALAA::VisitBinaryOperation(BinaryOperation* e) {
+  Visit(e->left());
+  Visit(e->right());
+}
+
+
+void ALAA::VisitCompareOperation(CompareOperation* e) {
+  Visit(e->left());
+  Visit(e->right());
+}
+
+
+void ALAA::VisitCaseClause(CaseClause* cc) {
+  if (!cc->is_default()) Visit(cc->label());
+  VisitStatements(cc->statements());
+}
+
+
+// ---------------------------------------------------------------------------
+// -- Interesting nodes-------------------------------------------------------
+// ---------------------------------------------------------------------------
+void ALAA::VisitModuleStatement(ModuleStatement* stmt) {
+  Visit(stmt->body());
+  // TODO(turbofan): can a module appear in a loop?
+  AnalyzeAssignment(stmt->proxy()->var());
+}
+
+
+void ALAA::VisitTryCatchStatement(TryCatchStatement* stmt) {
+  Visit(stmt->try_block());
+  Visit(stmt->catch_block());
+  // TODO(turbofan): are catch variables well-scoped?
+  AnalyzeAssignment(stmt->variable());
+}
+
+
+void ALAA::VisitDoWhileStatement(DoWhileStatement* loop) {
+  Enter(loop);
+  Visit(loop->body());
+  Visit(loop->cond());
+  Exit(loop);
+}
+
+
+void ALAA::VisitWhileStatement(WhileStatement* loop) {
+  Enter(loop);
+  Visit(loop->cond());
+  Visit(loop->body());
+  Exit(loop);
+}
+
+
+void ALAA::VisitForStatement(ForStatement* loop) {
+  VisitIfNotNull(loop->init());
+  Enter(loop);
+  VisitIfNotNull(loop->cond());
+  Visit(loop->body());
+  VisitIfNotNull(loop->next());
+  Exit(loop);
+}
+
+
+void ALAA::VisitForInStatement(ForInStatement* loop) {
+  Enter(loop);
+  Visit(loop->each());
+  Visit(loop->subject());
+  Visit(loop->body());
+  Exit(loop);
+}
+
+
+void ALAA::VisitForOfStatement(ForOfStatement* loop) {
+  Enter(loop);
+  Visit(loop->each());
+  Visit(loop->subject());
+  Visit(loop->body());
+  Exit(loop);
+}
+
+
+void ALAA::VisitAssignment(Assignment* stmt) {
+  Expression* l = stmt->target();
+  Visit(l);
+  Visit(stmt->value());
+  if (l->IsVariableProxy()) AnalyzeAssignment(l->AsVariableProxy()->var());
+}
+
+
+void ALAA::VisitCountOperation(CountOperation* e) {
+  Expression* l = e->expression();
+  Visit(l);
+  if (l->IsVariableProxy()) AnalyzeAssignment(l->AsVariableProxy()->var());
+}
+
+
+void ALAA::AnalyzeAssignment(Variable* var) {
+  if (!loop_stack_.empty() && var->IsStackAllocated()) {
+    loop_stack_.back()->Add(GetVariableIndex(info()->scope(), var));
+  }
+}
+
+
+int ALAA::GetVariableIndex(Scope* scope, Variable* var) {
+  CHECK(var->IsStackAllocated());
+  if (var->is_this()) return 0;
+  if (var->IsParameter()) return 1 + var->index();
+  return 1 + scope->num_parameters() + var->index();
+}
+
+
+int LoopAssignmentAnalysis::GetAssignmentCountForTesting(Scope* scope,
+                                                         Variable* var) {
+  int count = 0;
+  int var_index = AstLoopAssignmentAnalyzer::GetVariableIndex(scope, var);
+  for (size_t i = 0; i < list_.size(); i++) {
+    if (list_[i].second->Contains(var_index)) count++;
+  }
+  return count;
+}
+}
+}
+}  // namespace v8::internal::compiler
diff --git a/src/compiler/ast-loop-assignment-analyzer.h b/src/compiler/ast-loop-assignment-analyzer.h
new file mode 100644
index 0000000..00a7f2d
--- /dev/null
+++ b/src/compiler/ast-loop-assignment-analyzer.h
@@ -0,0 +1,78 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_AST_LOOP_ASSIGNMENT_ANALYZER_H_
+#define V8_COMPILER_AST_LOOP_ASSIGNMENT_ANALYZER_H_
+
+#include "src/ast.h"
+#include "src/bit-vector.h"
+#include "src/v8.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+
+class Variable;
+class Scope;
+
+namespace compiler {
+
+// The result of analyzing loop assignments.
+class LoopAssignmentAnalysis : public ZoneObject {
+ public:
+  BitVector* GetVariablesAssignedInLoop(IterationStatement* loop) {
+    for (size_t i = 0; i < list_.size(); i++) {
+      // TODO(turbofan): hashmap or binary search for loop assignments.
+      if (list_[i].first == loop) return list_[i].second;
+    }
+    UNREACHABLE();  // should never ask for loops that aren't here!
+    return NULL;
+  }
+
+  int GetAssignmentCountForTesting(Scope* scope, Variable* var);
+
+ private:
+  friend class AstLoopAssignmentAnalyzer;
+  explicit LoopAssignmentAnalysis(Zone* zone) : list_(zone) {}
+  ZoneVector<std::pair<IterationStatement*, BitVector*>> list_;
+};
+
+
+// The class that performs loop assignment analysis by walking the AST.
+class AstLoopAssignmentAnalyzer : public AstVisitor {
+ public:
+  AstLoopAssignmentAnalyzer(Zone* zone, CompilationInfo* info);
+
+  LoopAssignmentAnalysis* Analyze();
+
+#define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE;
+  AST_NODE_LIST(DECLARE_VISIT)
+#undef DECLARE_VISIT
+
+  static int GetVariableIndex(Scope* scope, Variable* var);
+
+ private:
+  CompilationInfo* info_;
+  ZoneDeque<BitVector*> loop_stack_;
+  LoopAssignmentAnalysis* result_;
+
+  CompilationInfo* info() { return info_; }
+
+  void Enter(IterationStatement* loop);
+  void Exit(IterationStatement* loop);
+
+  void VisitIfNotNull(AstNode* node) {
+    if (node != NULL) Visit(node);
+  }
+
+  void AnalyzeAssignment(Variable* var);
+
+  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();
+  DISALLOW_COPY_AND_ASSIGN(AstLoopAssignmentAnalyzer);
+};
+}
+}
+}  // namespace v8::internal::compiler
+
+#endif  // V8_COMPILER_AST_LOOP_ASSIGNMENT_ANALYZER_H_
diff --git a/src/compiler/basic-block-instrumentor.cc b/src/compiler/basic-block-instrumentor.cc
new file mode 100644
index 0000000..d7d3ade
--- /dev/null
+++ b/src/compiler/basic-block-instrumentor.cc
@@ -0,0 +1,106 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/basic-block-instrumentor.h"
+
+#include <sstream>
+
+#include "src/compiler.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/operator-properties.h"
+#include "src/compiler/schedule.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Find the first place to insert new nodes in a block that's already been
+// scheduled that won't upset the register allocator.
+static NodeVector::iterator FindInsertionPoint(BasicBlock* block) {
+  NodeVector::iterator i = block->begin();
+  for (; i != block->end(); ++i) {
+    const Operator* op = (*i)->op();
+    if (OperatorProperties::IsBasicBlockBegin(op)) continue;
+    switch (op->opcode()) {
+      case IrOpcode::kParameter:
+      case IrOpcode::kPhi:
+      case IrOpcode::kEffectPhi:
+        continue;
+    }
+    break;
+  }
+  return i;
+}
+
+
+// TODO(dcarney): need to mark code as non-serializable.
+static const Operator* PointerConstant(CommonOperatorBuilder* common,
+                                       void* ptr) {
+  return kPointerSize == 8
+             ? common->Int64Constant(reinterpret_cast<intptr_t>(ptr))
+             : common->Int32Constant(
+                   static_cast<int32_t>(reinterpret_cast<intptr_t>(ptr)));
+}
+
+
+BasicBlockProfiler::Data* BasicBlockInstrumentor::Instrument(
+    CompilationInfo* info, Graph* graph, Schedule* schedule) {
+  // Skip the exit block in profiles, since the register allocator can't handle
+  // it and entry into it means falling off the end of the function anyway.
+  size_t n_blocks = static_cast<size_t>(schedule->RpoBlockCount()) - 1;
+  BasicBlockProfiler::Data* data =
+      info->isolate()->GetOrCreateBasicBlockProfiler()->NewData(n_blocks);
+  // Set the function name.
+  if (!info->shared_info().is_null() &&
+      info->shared_info()->name()->IsString()) {
+    std::ostringstream os;
+    String::cast(info->shared_info()->name())->PrintUC16(os);
+    data->SetFunctionName(&os);
+  }
+  // Capture the schedule string before instrumentation.
+  {
+    std::ostringstream os;
+    os << *schedule;
+    data->SetSchedule(&os);
+  }
+  // Add the increment instructions to the start of every block.
+  CommonOperatorBuilder common(graph->zone());
+  Node* zero = graph->NewNode(common.Int32Constant(0));
+  Node* one = graph->NewNode(common.Int32Constant(1));
+  MachineOperatorBuilder machine(graph->zone());
+  BasicBlockVector* blocks = schedule->rpo_order();
+  size_t block_number = 0;
+  for (BasicBlockVector::iterator it = blocks->begin(); block_number < n_blocks;
+       ++it, ++block_number) {
+    BasicBlock* block = (*it);
+    data->SetBlockId(block_number, block->id().ToSize());
+    // TODO(dcarney): wire effect and control deps for load and store.
+    // Construct increment operation.
+    Node* base = graph->NewNode(
+        PointerConstant(&common, data->GetCounterAddress(block_number)));
+    Node* load = graph->NewNode(machine.Load(kMachUint32), base, zero);
+    Node* inc = graph->NewNode(machine.Int32Add(), load, one);
+    Node* store = graph->NewNode(
+        machine.Store(StoreRepresentation(kMachUint32, kNoWriteBarrier)), base,
+        zero, inc);
+    // Insert the new nodes.
+    static const int kArraySize = 6;
+    Node* to_insert[kArraySize] = {zero, one, base, load, inc, store};
+    int insertion_start = block_number == 0 ? 0 : 2;
+    NodeVector::iterator insertion_point = FindInsertionPoint(block);
+    block->InsertNodes(insertion_point, &to_insert[insertion_start],
+                       &to_insert[kArraySize]);
+    // Tell the scheduler about the new nodes.
+    for (int i = insertion_start; i < kArraySize; ++i) {
+      schedule->SetBlockForNode(block, to_insert[i]);
+    }
+  }
+  return data;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/basic-block-instrumentor.h b/src/compiler/basic-block-instrumentor.h
new file mode 100644
index 0000000..7edac0d
--- /dev/null
+++ b/src/compiler/basic-block-instrumentor.h
@@ -0,0 +1,32 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_BASIC_BLOCK_INSTRUMENTOR_H_
+#define V8_COMPILER_BASIC_BLOCK_INSTRUMENTOR_H_
+
+#include "src/v8.h"
+
+#include "src/basic-block-profiler.h"
+
+namespace v8 {
+namespace internal {
+
+class CompilationInfo;
+
+namespace compiler {
+
+class Graph;
+class Schedule;
+
+class BasicBlockInstrumentor : public AllStatic {
+ public:
+  static BasicBlockProfiler::Data* Instrument(CompilationInfo* info,
+                                              Graph* graph, Schedule* schedule);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif
diff --git a/src/compiler/change-lowering-unittest.cc b/src/compiler/change-lowering-unittest.cc
deleted file mode 100644
index 994027a..0000000
--- a/src/compiler/change-lowering-unittest.cc
+++ /dev/null
@@ -1,476 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/change-lowering.h"
-#include "src/compiler/compiler-test-utils.h"
-#include "src/compiler/graph-unittest.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/compiler/simplified-operator.h"
-#include "src/compiler/typer.h"
-#include "testing/gmock-support.h"
-
-using testing::_;
-using testing::AllOf;
-using testing::Capture;
-using testing::CaptureEq;
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-// TODO(bmeurer): Find a new home for these functions.
-inline std::ostream& operator<<(std::ostream& os, const MachineType& type) {
-  OStringStream ost;
-  ost << type;
-  return os << ost.c_str();
-}
-
-
-class ChangeLoweringTest : public GraphTest {
- public:
-  ChangeLoweringTest() : simplified_(zone()) {}
-  virtual ~ChangeLoweringTest() {}
-
-  virtual MachineType WordRepresentation() const = 0;
-
- protected:
-  int HeapNumberValueOffset() const {
-    STATIC_ASSERT(HeapNumber::kValueOffset % kApiPointerSize == 0);
-    return (HeapNumber::kValueOffset / kApiPointerSize) * PointerSize() -
-           kHeapObjectTag;
-  }
-  bool Is32() const { return WordRepresentation() == kRepWord32; }
-  int PointerSize() const {
-    switch (WordRepresentation()) {
-      case kRepWord32:
-        return 4;
-      case kRepWord64:
-        return 8;
-      default:
-        break;
-    }
-    UNREACHABLE();
-    return 0;
-  }
-  int SmiMaxValue() const { return -(SmiMinValue() + 1); }
-  int SmiMinValue() const {
-    return static_cast<int>(0xffffffffu << (SmiValueSize() - 1));
-  }
-  int SmiShiftAmount() const { return kSmiTagSize + SmiShiftSize(); }
-  int SmiShiftSize() const {
-    return Is32() ? SmiTagging<4>::SmiShiftSize()
-                  : SmiTagging<8>::SmiShiftSize();
-  }
-  int SmiValueSize() const {
-    return Is32() ? SmiTagging<4>::SmiValueSize()
-                  : SmiTagging<8>::SmiValueSize();
-  }
-
-  Node* Parameter(int32_t index = 0) {
-    return graph()->NewNode(common()->Parameter(index), graph()->start());
-  }
-
-  Reduction Reduce(Node* node) {
-    Typer typer(zone());
-    MachineOperatorBuilder machine(WordRepresentation());
-    JSOperatorBuilder javascript(zone());
-    JSGraph jsgraph(graph(), common(), &javascript, &typer, &machine);
-    CompilationInfo info(isolate(), zone());
-    Linkage linkage(&info);
-    ChangeLowering reducer(&jsgraph, &linkage);
-    return reducer.Reduce(node);
-  }
-
-  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
-
-  Matcher<Node*> IsAllocateHeapNumber(const Matcher<Node*>& effect_matcher,
-                                      const Matcher<Node*>& control_matcher) {
-    return IsCall(
-        _, IsHeapConstant(Unique<HeapObject>::CreateImmovable(
-               CEntryStub(isolate(), 1).GetCode())),
-        IsExternalConstant(ExternalReference(
-            Runtime::FunctionForId(Runtime::kAllocateHeapNumber), isolate())),
-        IsInt32Constant(0), IsNumberConstant(0.0), effect_matcher,
-        control_matcher);
-  }
-  Matcher<Node*> IsWordEqual(const Matcher<Node*>& lhs_matcher,
-                             const Matcher<Node*>& rhs_matcher) {
-    return Is32() ? IsWord32Equal(lhs_matcher, rhs_matcher)
-                  : IsWord64Equal(lhs_matcher, rhs_matcher);
-  }
-
- private:
-  SimplifiedOperatorBuilder simplified_;
-};
-
-
-// -----------------------------------------------------------------------------
-// Common.
-
-
-class ChangeLoweringCommonTest
-    : public ChangeLoweringTest,
-      public ::testing::WithParamInterface<MachineType> {
- public:
-  virtual ~ChangeLoweringCommonTest() {}
-
-  virtual MachineType WordRepresentation() const FINAL OVERRIDE {
-    return GetParam();
-  }
-};
-
-
-TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBitToBool) {
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeBitToBool(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  Node* phi = reduction.replacement();
-  Capture<Node*> branch;
-  EXPECT_THAT(phi,
-              IsPhi(static_cast<MachineType>(kTypeBool | kRepTagged),
-                    IsTrueConstant(), IsFalseConstant(),
-                    IsMerge(IsIfTrue(AllOf(CaptureEq(&branch),
-                                           IsBranch(val, graph()->start()))),
-                            IsIfFalse(CaptureEq(&branch)))));
-}
-
-
-TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBoolToBit) {
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeBoolToBit(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  EXPECT_THAT(reduction.replacement(), IsWordEqual(val, IsTrueConstant()));
-}
-
-
-TARGET_TEST_P(ChangeLoweringCommonTest, ChangeFloat64ToTagged) {
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeFloat64ToTagged(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  Node* finish = reduction.replacement();
-  Capture<Node*> heap_number;
-  EXPECT_THAT(
-      finish,
-      IsFinish(
-          AllOf(CaptureEq(&heap_number),
-                IsAllocateHeapNumber(IsValueEffect(val), graph()->start())),
-          IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number),
-                  IsInt32Constant(HeapNumberValueOffset()), val,
-                  CaptureEq(&heap_number), graph()->start())));
-}
-
-
-TARGET_TEST_P(ChangeLoweringCommonTest, StringAdd) {
-  Node* node =
-      graph()->NewNode(simplified()->StringAdd(), Parameter(0), Parameter(1));
-  Reduction reduction = Reduce(node);
-  EXPECT_FALSE(reduction.Changed());
-}
-
-
-INSTANTIATE_TEST_CASE_P(ChangeLoweringTest, ChangeLoweringCommonTest,
-                        ::testing::Values(kRepWord32, kRepWord64));
-
-
-// -----------------------------------------------------------------------------
-// 32-bit
-
-
-class ChangeLowering32Test : public ChangeLoweringTest {
- public:
-  virtual ~ChangeLowering32Test() {}
-  virtual MachineType WordRepresentation() const FINAL OVERRIDE {
-    return kRepWord32;
-  }
-};
-
-
-TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) {
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  Node* phi = reduction.replacement();
-  Capture<Node*> add, branch, heap_number, if_true;
-  EXPECT_THAT(
-      phi,
-      IsPhi(kMachAnyTagged,
-            IsFinish(
-                AllOf(CaptureEq(&heap_number),
-                      IsAllocateHeapNumber(_, CaptureEq(&if_true))),
-                IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number),
-                        IsInt32Constant(HeapNumberValueOffset()),
-                        IsChangeInt32ToFloat64(val), CaptureEq(&heap_number),
-                        CaptureEq(&if_true))),
-            IsProjection(
-                0, AllOf(CaptureEq(&add), IsInt32AddWithOverflow(val, val))),
-            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
-                    IsIfFalse(AllOf(CaptureEq(&branch),
-                                    IsBranch(IsProjection(1, CaptureEq(&add)),
-                                             graph()->start()))))));
-}
-
-
-TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToFloat64) {
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagSize == 1);
-
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  Node* phi = reduction.replacement();
-  Capture<Node*> branch, if_true;
-  EXPECT_THAT(
-      phi,
-      IsPhi(
-          kMachFloat64,
-          IsLoad(kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
-                 IsControlEffect(CaptureEq(&if_true))),
-          IsChangeInt32ToFloat64(
-              IsWord32Sar(val, IsInt32Constant(SmiShiftAmount()))),
-          IsMerge(
-              AllOf(CaptureEq(&if_true),
-                    IsIfTrue(AllOf(
-                        CaptureEq(&branch),
-                        IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
-                                 graph()->start())))),
-              IsIfFalse(CaptureEq(&branch)))));
-}
-
-
-TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToInt32) {
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagSize == 1);
-
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeTaggedToInt32(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  Node* phi = reduction.replacement();
-  Capture<Node*> branch, if_true;
-  EXPECT_THAT(
-      phi,
-      IsPhi(kMachInt32,
-            IsChangeFloat64ToInt32(IsLoad(
-                kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
-                IsControlEffect(CaptureEq(&if_true)))),
-            IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
-            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
-                    IsIfFalse(AllOf(
-                        CaptureEq(&branch),
-                        IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
-                                 graph()->start()))))));
-}
-
-
-TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToUint32) {
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagSize == 1);
-
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  Node* phi = reduction.replacement();
-  Capture<Node*> branch, if_true;
-  EXPECT_THAT(
-      phi,
-      IsPhi(kMachUint32,
-            IsChangeFloat64ToUint32(IsLoad(
-                kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
-                IsControlEffect(CaptureEq(&if_true)))),
-            IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
-            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
-                    IsIfFalse(AllOf(
-                        CaptureEq(&branch),
-                        IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
-                                 graph()->start()))))));
-}
-
-
-TARGET_TEST_F(ChangeLowering32Test, ChangeUint32ToTagged) {
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagSize == 1);
-
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  Node* phi = reduction.replacement();
-  Capture<Node*> branch, heap_number, if_false;
-  EXPECT_THAT(
-      phi,
-      IsPhi(
-          kMachAnyTagged, IsWord32Shl(val, IsInt32Constant(SmiShiftAmount())),
-          IsFinish(
-              AllOf(CaptureEq(&heap_number),
-                    IsAllocateHeapNumber(_, CaptureEq(&if_false))),
-              IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number),
-                      IsInt32Constant(HeapNumberValueOffset()),
-                      IsChangeUint32ToFloat64(val), CaptureEq(&heap_number),
-                      CaptureEq(&if_false))),
-          IsMerge(
-              IsIfTrue(AllOf(CaptureEq(&branch),
-                             IsBranch(IsUint32LessThanOrEqual(
-                                          val, IsInt32Constant(SmiMaxValue())),
-                                      graph()->start()))),
-              AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
-}
-
-
-// -----------------------------------------------------------------------------
-// 64-bit
-
-
-class ChangeLowering64Test : public ChangeLoweringTest {
- public:
-  virtual ~ChangeLowering64Test() {}
-  virtual MachineType WordRepresentation() const FINAL OVERRIDE {
-    return kRepWord64;
-  }
-};
-
-
-TARGET_TEST_F(ChangeLowering64Test, ChangeInt32ToTagged) {
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  EXPECT_THAT(reduction.replacement(),
-              IsWord64Shl(IsChangeInt32ToInt64(val),
-                          IsInt32Constant(SmiShiftAmount())));
-}
-
-
-TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToFloat64) {
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagSize == 1);
-
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  Node* phi = reduction.replacement();
-  Capture<Node*> branch, if_true;
-  EXPECT_THAT(
-      phi,
-      IsPhi(
-          kMachFloat64,
-          IsLoad(kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
-                 IsControlEffect(CaptureEq(&if_true))),
-          IsChangeInt32ToFloat64(IsTruncateInt64ToInt32(
-              IsWord64Sar(val, IsInt32Constant(SmiShiftAmount())))),
-          IsMerge(
-              AllOf(CaptureEq(&if_true),
-                    IsIfTrue(AllOf(
-                        CaptureEq(&branch),
-                        IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
-                                 graph()->start())))),
-              IsIfFalse(CaptureEq(&branch)))));
-}
-
-
-TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToInt32) {
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagSize == 1);
-
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeTaggedToInt32(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  Node* phi = reduction.replacement();
-  Capture<Node*> branch, if_true;
-  EXPECT_THAT(
-      phi,
-      IsPhi(kMachInt32,
-            IsChangeFloat64ToInt32(IsLoad(
-                kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
-                IsControlEffect(CaptureEq(&if_true)))),
-            IsTruncateInt64ToInt32(
-                IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))),
-            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
-                    IsIfFalse(AllOf(
-                        CaptureEq(&branch),
-                        IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
-                                 graph()->start()))))));
-}
-
-
-TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToUint32) {
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagSize == 1);
-
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  Node* phi = reduction.replacement();
-  Capture<Node*> branch, if_true;
-  EXPECT_THAT(
-      phi,
-      IsPhi(kMachUint32,
-            IsChangeFloat64ToUint32(IsLoad(
-                kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()),
-                IsControlEffect(CaptureEq(&if_true)))),
-            IsTruncateInt64ToInt32(
-                IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))),
-            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
-                    IsIfFalse(AllOf(
-                        CaptureEq(&branch),
-                        IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
-                                 graph()->start()))))));
-}
-
-
-TARGET_TEST_F(ChangeLowering64Test, ChangeUint32ToTagged) {
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagSize == 1);
-
-  Node* val = Parameter(0);
-  Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), val);
-  Reduction reduction = Reduce(node);
-  ASSERT_TRUE(reduction.Changed());
-
-  Node* phi = reduction.replacement();
-  Capture<Node*> branch, heap_number, if_false;
-  EXPECT_THAT(
-      phi,
-      IsPhi(
-          kMachAnyTagged, IsWord64Shl(IsChangeUint32ToUint64(val),
-                                      IsInt32Constant(SmiShiftAmount())),
-          IsFinish(
-              AllOf(CaptureEq(&heap_number),
-                    IsAllocateHeapNumber(_, CaptureEq(&if_false))),
-              IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number),
-                      IsInt32Constant(HeapNumberValueOffset()),
-                      IsChangeUint32ToFloat64(val), CaptureEq(&heap_number),
-                      CaptureEq(&if_false))),
-          IsMerge(
-              IsIfTrue(AllOf(CaptureEq(&branch),
-                             IsBranch(IsUint32LessThanOrEqual(
-                                          val, IsInt32Constant(SmiMaxValue())),
-                                      graph()->start()))),
-              AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/change-lowering.cc b/src/compiler/change-lowering.cc
index b13db4c..7ddc751 100644
--- a/src/compiler/change-lowering.cc
+++ b/src/compiler/change-lowering.cc
@@ -3,9 +3,13 @@
 // found in the LICENSE file.
 
 #include "src/compiler/change-lowering.h"
-#include "src/compiler/machine-operator.h"
 
+#include "src/code-factory.h"
+#include "src/compiler/diamond.h"
 #include "src/compiler/js-graph.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/node-properties-inl.h"
 
 namespace v8 {
 namespace internal {
@@ -45,7 +49,7 @@
   STATIC_ASSERT(HeapNumber::kValueOffset % kPointerSize == 0);
   const int heap_number_value_offset =
       ((HeapNumber::kValueOffset / kPointerSize) * (machine()->Is64() ? 8 : 4));
-  return jsgraph()->Int32Constant(heap_number_value_offset - kHeapObjectTag);
+  return jsgraph()->IntPtrConstant(heap_number_value_offset - kHeapObjectTag);
 }
 
 
@@ -60,24 +64,21 @@
 Node* ChangeLowering::SmiShiftBitsConstant() {
   const int smi_shift_size = machine()->Is32() ? SmiTagging<4>::SmiShiftSize()
                                                : SmiTagging<8>::SmiShiftSize();
-  return jsgraph()->Int32Constant(smi_shift_size + kSmiTagSize);
+  return jsgraph()->IntPtrConstant(smi_shift_size + kSmiTagSize);
 }
 
 
 Node* ChangeLowering::AllocateHeapNumberWithValue(Node* value, Node* control) {
-  // The AllocateHeapNumber() runtime function does not use the context, so we
-  // can safely pass in Smi zero here.
-  Node* context = jsgraph()->ZeroConstant();
+  // The AllocateHeapNumberStub does not use the context, so we can safely pass
+  // in Smi zero here.
+  Callable callable = CodeFactory::AllocateHeapNumber(isolate());
+  CallDescriptor* descriptor = linkage()->GetStubCallDescriptor(
+      callable.descriptor(), 0, CallDescriptor::kNoFlags);
+  Node* target = jsgraph()->HeapConstant(callable.code());
+  Node* context = jsgraph()->NoContextConstant();
   Node* effect = graph()->NewNode(common()->ValueEffect(1), value);
-  const Runtime::Function* function =
-      Runtime::FunctionForId(Runtime::kAllocateHeapNumber);
-  DCHECK_EQ(0, function->nargs);
-  CallDescriptor* desc = linkage()->GetRuntimeCallDescriptor(
-      function->function_id, 0, Operator::kNoProperties);
-  Node* heap_number = graph()->NewNode(
-      common()->Call(desc), jsgraph()->CEntryStubConstant(),
-      jsgraph()->ExternalConstant(ExternalReference(function, isolate())),
-      jsgraph()->Int32Constant(function->nargs), context, effect, control);
+  Node* heap_number = graph()->NewNode(common()->Call(descriptor), target,
+                                       context, effect, control);
   Node* store = graph()->NewNode(
       machine()->Store(StoreRepresentation(kMachFloat64, kNoWriteBarrier)),
       heap_number, HeapNumberValueIndexConstant(), value, heap_number, control);
@@ -85,6 +86,16 @@
 }
 
 
+Node* ChangeLowering::ChangeInt32ToFloat64(Node* value) {
+  return graph()->NewNode(machine()->ChangeInt32ToFloat64(), value);
+}
+
+
+Node* ChangeLowering::ChangeSmiToFloat64(Node* value) {
+  return ChangeInt32ToFloat64(ChangeSmiToInt32(value));
+}
+
+
 Node* ChangeLowering::ChangeSmiToInt32(Node* value) {
   value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant());
   if (machine()->Is64()) {
@@ -94,28 +105,44 @@
 }
 
 
+Node* ChangeLowering::ChangeUint32ToFloat64(Node* value) {
+  return graph()->NewNode(machine()->ChangeUint32ToFloat64(), value);
+}
+
+
+Node* ChangeLowering::ChangeUint32ToSmi(Node* value) {
+  if (machine()->Is64()) {
+    value = graph()->NewNode(machine()->ChangeUint32ToUint64(), value);
+  }
+  return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant());
+}
+
+
 Node* ChangeLowering::LoadHeapNumberValue(Node* value, Node* control) {
   return graph()->NewNode(machine()->Load(kMachFloat64), value,
-                          HeapNumberValueIndexConstant(),
-                          graph()->NewNode(common()->ControlEffect(), control));
+                          HeapNumberValueIndexConstant(), graph()->start(),
+                          control);
+}
+
+
+Node* ChangeLowering::TestNotSmi(Node* value) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagMask == 1);
+  return graph()->NewNode(machine()->WordAnd(), value,
+                          jsgraph()->IntPtrConstant(kSmiTagMask));
+}
+
+
+Node* ChangeLowering::Uint32LessThanOrEqual(Node* lhs, Node* rhs) {
+  return graph()->NewNode(machine()->Uint32LessThanOrEqual(), lhs, rhs);
 }
 
 
 Reduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) {
-  Node* branch = graph()->NewNode(common()->Branch(), val, control);
-
-  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
-  Node* true_value = jsgraph()->TrueConstant();
-
-  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
-  Node* false_value = jsgraph()->FalseConstant();
-
-  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
-  Node* phi = graph()->NewNode(
-      common()->Phi(static_cast<MachineType>(kTypeBool | kRepTagged), 2),
-      true_value, false_value, merge);
-
-  return Replace(phi);
+  MachineType const type = static_cast<MachineType>(kTypeBool | kRepTagged);
+  return Replace(graph()->NewNode(common()->Select(type), val,
+                                  jsgraph()->TrueConstant(),
+                                  jsgraph()->FalseConstant()));
 }
 
 
@@ -130,109 +157,109 @@
 }
 
 
-Reduction ChangeLowering::ChangeInt32ToTagged(Node* val, Node* control) {
+Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) {
   if (machine()->Is64()) {
+    return Replace(graph()->NewNode(
+        machine()->Word64Shl(),
+        graph()->NewNode(machine()->ChangeInt32ToInt64(), value),
+        SmiShiftBitsConstant()));
+  } else if (NodeProperties::GetBounds(value).upper->Is(Type::SignedSmall())) {
     return Replace(
-        graph()->NewNode(machine()->Word64Shl(),
-                         graph()->NewNode(machine()->ChangeInt32ToInt64(), val),
-                         SmiShiftBitsConstant()));
+        graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant()));
   }
 
-  Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), val, val);
+  Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value);
   Node* ovf = graph()->NewNode(common()->Projection(1), add);
 
-  Node* branch = graph()->NewNode(common()->Branch(), ovf, control);
-
-  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
-  Node* heap_number = AllocateHeapNumberWithValue(
-      graph()->NewNode(machine()->ChangeInt32ToFloat64(), val), if_true);
-
-  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
-  Node* smi = graph()->NewNode(common()->Projection(0), add);
-
-  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
-  Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), heap_number,
-                               smi, merge);
-
-  return Replace(phi);
+  Diamond d(graph(), common(), ovf, BranchHint::kFalse);
+  d.Chain(control);
+  return Replace(
+      d.Phi(kMachAnyTagged,
+            AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), d.if_true),
+            graph()->NewNode(common()->Projection(0), add)));
 }
 
 
-Reduction ChangeLowering::ChangeTaggedToUI32(Node* val, Node* control,
+Reduction ChangeLowering::ChangeTaggedToUI32(Node* value, Node* control,
                                              Signedness signedness) {
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagMask == 1);
-
-  Node* tag = graph()->NewNode(machine()->WordAnd(), val,
-                               jsgraph()->Int32Constant(kSmiTagMask));
-  Node* branch = graph()->NewNode(common()->Branch(), tag, control);
-
-  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  const MachineType type = (signedness == kSigned) ? kMachInt32 : kMachUint32;
   const Operator* op = (signedness == kSigned)
                            ? machine()->ChangeFloat64ToInt32()
                            : machine()->ChangeFloat64ToUint32();
-  Node* change = graph()->NewNode(op, LoadHeapNumberValue(val, if_true));
-
-  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
-  Node* number = ChangeSmiToInt32(val);
-
-  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
-  Node* phi = graph()->NewNode(
-      common()->Phi((signedness == kSigned) ? kMachInt32 : kMachUint32, 2),
-      change, number, merge);
-
-  return Replace(phi);
+  Diamond d(graph(), common(), TestNotSmi(value), BranchHint::kFalse);
+  d.Chain(control);
+  return Replace(
+      d.Phi(type, graph()->NewNode(op, LoadHeapNumberValue(value, d.if_true)),
+            ChangeSmiToInt32(value)));
 }
 
 
-Reduction ChangeLowering::ChangeTaggedToFloat64(Node* val, Node* control) {
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagMask == 1);
+namespace {
 
-  Node* tag = graph()->NewNode(machine()->WordAnd(), val,
-                               jsgraph()->Int32Constant(kSmiTagMask));
-  Node* branch = graph()->NewNode(common()->Branch(), tag, control);
+bool CanCover(Node* value, IrOpcode::Value opcode) {
+  if (value->opcode() != opcode) return false;
+  bool first = true;
+  for (Edge const edge : value->use_edges()) {
+    if (NodeProperties::IsEffectEdge(edge)) continue;
+    DCHECK(NodeProperties::IsValueEdge(edge));
+    if (!first) return false;
+    first = false;
+  }
+  return true;
+}
 
-  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
-  Node* load = LoadHeapNumberValue(val, if_true);
+}  // namespace
 
-  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
-  Node* number = graph()->NewNode(machine()->ChangeInt32ToFloat64(),
-                                  ChangeSmiToInt32(val));
 
-  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
-  Node* phi =
-      graph()->NewNode(common()->Phi(kMachFloat64, 2), load, number, merge);
+Reduction ChangeLowering::ChangeTaggedToFloat64(Node* value, Node* control) {
+  if (CanCover(value, IrOpcode::kJSToNumber)) {
+    // ChangeTaggedToFloat64(JSToNumber(x)) =>
+    //   if IsSmi(x) then ChangeSmiToFloat64(x)
+    //   else let y = JSToNumber(x) in
+    //     if IsSmi(y) then ChangeSmiToFloat64(y)
+    //     else LoadHeapNumberValue(y)
+    Node* const object = NodeProperties::GetValueInput(value, 0);
+    Node* const context = NodeProperties::GetContextInput(value);
+    Node* const effect = NodeProperties::GetEffectInput(value);
+    Node* const control = NodeProperties::GetControlInput(value);
 
-  return Replace(phi);
+    Diamond d1(graph(), common(), TestNotSmi(object), BranchHint::kFalse);
+    d1.Chain(control);
+
+    Node* number =
+        graph()->NewNode(value->op(), object, context, effect, d1.if_true);
+    Diamond d2(graph(), common(), TestNotSmi(number));
+    d2.Nest(d1, true);
+    Node* phi2 = d2.Phi(kMachFloat64, LoadHeapNumberValue(number, d2.if_true),
+                        ChangeSmiToFloat64(number));
+
+    Node* phi1 = d1.Phi(kMachFloat64, phi2, ChangeSmiToFloat64(object));
+    Node* ephi1 = d1.EffectPhi(number, effect);
+
+    for (Edge edge : value->use_edges()) {
+      if (NodeProperties::IsEffectEdge(edge)) {
+        edge.UpdateTo(ephi1);
+      }
+    }
+    return Replace(phi1);
+  }
+
+  Diamond d(graph(), common(), TestNotSmi(value), BranchHint::kFalse);
+  d.Chain(control);
+  Node* load = LoadHeapNumberValue(value, d.if_true);
+  Node* number = ChangeSmiToFloat64(value);
+  return Replace(d.Phi(kMachFloat64, load, number));
 }
 
 
-Reduction ChangeLowering::ChangeUint32ToTagged(Node* val, Node* control) {
-  STATIC_ASSERT(kSmiTag == 0);
-  STATIC_ASSERT(kSmiTagMask == 1);
-
-  Node* cmp = graph()->NewNode(machine()->Uint32LessThanOrEqual(), val,
-                               SmiMaxValueConstant());
-  Node* branch = graph()->NewNode(common()->Branch(), cmp, control);
-
-  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
-  Node* smi = graph()->NewNode(
-      machine()->WordShl(),
-      machine()->Is64()
-          ? graph()->NewNode(machine()->ChangeUint32ToUint64(), val)
-          : val,
-      SmiShiftBitsConstant());
-
-  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
-  Node* heap_number = AllocateHeapNumberWithValue(
-      graph()->NewNode(machine()->ChangeUint32ToFloat64(), val), if_false);
-
-  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
-  Node* phi = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), smi,
-                               heap_number, merge);
-
-  return Replace(phi);
+Reduction ChangeLowering::ChangeUint32ToTagged(Node* value, Node* control) {
+  Diamond d(graph(), common(),
+            Uint32LessThanOrEqual(value, SmiMaxValueConstant()),
+            BranchHint::kTrue);
+  d.Chain(control);
+  return Replace(d.Phi(
+      kMachAnyTagged, ChangeUint32ToSmi(value),
+      AllocateHeapNumberWithValue(ChangeUint32ToFloat64(value), d.if_false)));
 }
 
 
diff --git a/src/compiler/change-lowering.h b/src/compiler/change-lowering.h
index 5d7ab41..773fd08 100644
--- a/src/compiler/change-lowering.h
+++ b/src/compiler/change-lowering.h
@@ -21,9 +21,9 @@
  public:
   ChangeLowering(JSGraph* jsgraph, Linkage* linkage)
       : jsgraph_(jsgraph), linkage_(linkage) {}
-  virtual ~ChangeLowering();
+  ~ChangeLowering() FINAL;
 
-  virtual Reduction Reduce(Node* node) OVERRIDE;
+  Reduction Reduce(Node* node) FINAL;
 
  private:
   Node* HeapNumberValueIndexConstant();
@@ -31,16 +31,23 @@
   Node* SmiShiftBitsConstant();
 
   Node* AllocateHeapNumberWithValue(Node* value, Node* control);
+  Node* ChangeInt32ToFloat64(Node* value);
+  Node* ChangeSmiToFloat64(Node* value);
   Node* ChangeSmiToInt32(Node* value);
+  Node* ChangeUint32ToFloat64(Node* value);
+  Node* ChangeUint32ToSmi(Node* value);
   Node* LoadHeapNumberValue(Node* value, Node* control);
+  Node* TestNotSmi(Node* value);
+  Node* Uint32LessThanOrEqual(Node* lhs, Node* rhs);
 
-  Reduction ChangeBitToBool(Node* val, Node* control);
-  Reduction ChangeBoolToBit(Node* val);
-  Reduction ChangeFloat64ToTagged(Node* val, Node* control);
-  Reduction ChangeInt32ToTagged(Node* val, Node* control);
-  Reduction ChangeTaggedToFloat64(Node* val, Node* control);
-  Reduction ChangeTaggedToUI32(Node* val, Node* control, Signedness signedness);
-  Reduction ChangeUint32ToTagged(Node* val, Node* control);
+  Reduction ChangeBitToBool(Node* value, Node* control);
+  Reduction ChangeBoolToBit(Node* value);
+  Reduction ChangeFloat64ToTagged(Node* value, Node* control);
+  Reduction ChangeInt32ToTagged(Node* value, Node* control);
+  Reduction ChangeTaggedToFloat64(Node* value, Node* control);
+  Reduction ChangeTaggedToUI32(Node* value, Node* control,
+                               Signedness signedness);
+  Reduction ChangeUint32ToTagged(Node* value, Node* control);
 
   Graph* graph() const;
   Isolate* isolate() const;
diff --git a/src/compiler/code-generator-impl.h b/src/compiler/code-generator-impl.h
index a3f7e4c..7942344 100644
--- a/src/compiler/code-generator-impl.h
+++ b/src/compiler/code-generator-impl.h
@@ -5,15 +5,12 @@
 #ifndef V8_COMPILER_CODE_GENERATOR_IMPL_H_
 #define V8_COMPILER_CODE_GENERATOR_IMPL_H_
 
+#include "src/code-stubs.h"
 #include "src/compiler/code-generator.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/generic-graph.h"
 #include "src/compiler/instruction.h"
 #include "src/compiler/linkage.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/node.h"
 #include "src/compiler/opcodes.h"
-#include "src/compiler/operator.h"
+#include "src/macro-assembler.h"
 
 namespace v8 {
 namespace internal {
@@ -28,6 +25,8 @@
   InstructionOperandConverter(CodeGenerator* gen, Instruction* instr)
       : gen_(gen), instr_(instr) {}
 
+  // -- Instruction operand accesses with conversions --------------------------
+
   Register InputRegister(int index) {
     return ToRegister(instr_->InputAt(index));
   }
@@ -60,27 +59,31 @@
     return ToHeapObject(instr_->InputAt(index));
   }
 
-  Label* InputLabel(int index) {
-    return gen_->code()->GetLabel(InputBlock(index));
-  }
+  Label* InputLabel(int index) { return ToLabel(instr_->InputAt(index)); }
 
-  BasicBlock* InputBlock(int index) {
-    NodeId block_id = static_cast<NodeId>(InputInt32(index));
-    // operand should be a block id.
-    DCHECK(block_id >= 0);
-    DCHECK(block_id < gen_->schedule()->BasicBlockCount());
-    return gen_->schedule()->GetBlockById(block_id);
+  BasicBlock::RpoNumber InputRpo(int index) {
+    return ToRpoNumber(instr_->InputAt(index));
   }
 
   Register OutputRegister(int index = 0) {
     return ToRegister(instr_->OutputAt(index));
   }
 
+  Register TempRegister(int index) { return ToRegister(instr_->TempAt(index)); }
+
   DoubleRegister OutputDoubleRegister() {
     return ToDoubleRegister(instr_->Output());
   }
 
-  Register TempRegister(int index) { return ToRegister(instr_->TempAt(index)); }
+  // -- Conversions for operands -----------------------------------------------
+
+  Label* ToLabel(InstructionOperand* op) {
+    return gen_->GetLabel(ToRpoNumber(op));
+  }
+
+  BasicBlock::RpoNumber ToRpoNumber(InstructionOperand* op) {
+    return ToConstant(op).ToRpoNumber();
+  }
 
   Register ToRegister(InstructionOperand* op) {
     DCHECK(op->IsRegister());
@@ -92,19 +95,17 @@
     return DoubleRegister::FromAllocationIndex(op->index());
   }
 
-  Constant ToConstant(InstructionOperand* operand) {
-    if (operand->IsImmediate()) {
-      return gen_->code()->GetImmediate(operand->index());
+  Constant ToConstant(InstructionOperand* op) {
+    if (op->IsImmediate()) {
+      return gen_->code()->GetImmediate(op->index());
     }
-    return gen_->code()->GetConstant(operand->index());
+    return gen_->code()->GetConstant(op->index());
   }
 
-  double ToDouble(InstructionOperand* operand) {
-    return ToConstant(operand).ToFloat64();
-  }
+  double ToDouble(InstructionOperand* op) { return ToConstant(op).ToFloat64(); }
 
-  Handle<HeapObject> ToHeapObject(InstructionOperand* operand) {
-    return ToConstant(operand).ToHeapObject();
+  Handle<HeapObject> ToHeapObject(InstructionOperand* op) {
+    return ToConstant(op).ToHeapObject();
   }
 
   Frame* frame() const { return gen_->frame(); }
@@ -117,6 +118,27 @@
 };
 
 
+// Generator for out-of-line code that is emitted after the main code is done.
+class OutOfLineCode : public ZoneObject {
+ public:
+  explicit OutOfLineCode(CodeGenerator* gen);
+  virtual ~OutOfLineCode();
+
+  virtual void Generate() = 0;
+
+  Label* entry() { return &entry_; }
+  Label* exit() { return &exit_; }
+  MacroAssembler* masm() const { return masm_; }
+  OutOfLineCode* next() const { return next_; }
+
+ private:
+  Label entry_;
+  Label exit_;
+  MacroAssembler* const masm_;
+  OutOfLineCode* const next_;
+};
+
+
 // TODO(dcarney): generify this on bleeding_edge and replace this call
 // when merged.
 static inline void FinishCode(MacroAssembler* masm) {
diff --git a/src/compiler/code-generator.cc b/src/compiler/code-generator.cc
index f22c479..cfe4f06 100644
--- a/src/compiler/code-generator.cc
+++ b/src/compiler/code-generator.cc
@@ -12,9 +12,14 @@
 namespace internal {
 namespace compiler {
 
-CodeGenerator::CodeGenerator(InstructionSequence* code)
-    : code_(code),
-      current_block_(NULL),
+CodeGenerator::CodeGenerator(Frame* frame, Linkage* linkage,
+                             InstructionSequence* code, CompilationInfo* info)
+    : frame_(frame),
+      linkage_(linkage),
+      code_(code),
+      info_(info),
+      labels_(zone()->NewArray<Label>(code->InstructionBlockCount())),
+      current_block_(BasicBlock::RpoNumber::Invalid()),
       current_source_position_(SourcePosition::Invalid()),
       masm_(code->zone()->isolate(), NULL, 0),
       resolver_(this),
@@ -22,11 +27,16 @@
       deoptimization_states_(code->zone()),
       deoptimization_literals_(code->zone()),
       translations_(code->zone()),
-      last_lazy_deopt_pc_(0) {}
+      last_lazy_deopt_pc_(0),
+      ools_(nullptr) {
+  for (int i = 0; i < code->InstructionBlockCount(); ++i) {
+    new (&labels_[i]) Label;
+  }
+}
 
 
 Handle<Code> CodeGenerator::GenerateCode() {
-  CompilationInfo* info = linkage()->info();
+  CompilationInfo* info = this->info();
 
   // Emit a code line info recording start event.
   PositionsRecorder* recorder = masm()->positions_recorder();
@@ -41,15 +51,42 @@
   info->set_prologue_offset(masm()->pc_offset());
   AssemblePrologue();
 
-  // Assemble all instructions.
-  for (InstructionSequence::const_iterator i = code()->begin();
-       i != code()->end(); ++i) {
-    AssembleInstruction(*i);
+  // Assemble all non-deferred blocks, followed by deferred ones.
+  for (int deferred = 0; deferred < 2; ++deferred) {
+    for (auto const block : code()->instruction_blocks()) {
+      if (block->IsDeferred() == (deferred == 0)) {
+        continue;
+      }
+      // Align loop headers on 16-byte boundaries.
+      if (block->IsLoopHeader()) masm()->Align(16);
+      // Bind a label for a block.
+      current_block_ = block->rpo_number();
+      if (FLAG_code_comments) {
+        // TODO(titzer): these code comments are a giant memory leak.
+        Vector<char> buffer = Vector<char>::New(32);
+        SNPrintF(buffer, "-- B%d start --", block->id().ToInt());
+        masm()->RecordComment(buffer.start());
+      }
+      masm()->bind(GetLabel(current_block_));
+      for (int i = block->code_start(); i < block->code_end(); ++i) {
+        AssembleInstruction(code()->InstructionAt(i));
+      }
+    }
+  }
+
+  // Assemble all out-of-line code.
+  if (ools_) {
+    masm()->RecordComment("-- Out of line code --");
+    for (OutOfLineCode* ool = ools_; ool; ool = ool->next()) {
+      masm()->bind(ool->entry());
+      ool->Generate();
+      masm()->jmp(ool->exit());
+    }
   }
 
   FinishCode(masm());
 
-  // Ensure there is space for lazy deopt.
+  // Ensure there is space for lazy deoptimization in the code.
   if (!info->IsStub()) {
     int target_offset = masm()->pc_offset() + Deoptimizer::patch_size();
     while (masm()->pc_offset() < target_offset) {
@@ -72,6 +109,11 @@
 
   PopulateDeoptimizationData(result);
 
+  // Ensure there is space for lazy deoptimization in the relocation info.
+  if (!info->IsStub()) {
+    Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(result);
+  }
+
   // Emit a code line info recording stop event.
   void* line_info = recorder->DetachJITHandlerData();
   LOG_CODE_EVENT(isolate(), CodeEndLinePosInfoRecordEvent(*result, line_info));
@@ -80,6 +122,12 @@
 }
 
 
+bool CodeGenerator::IsNextInAssemblyOrder(BasicBlock::RpoNumber block) const {
+  return code()->InstructionBlockAt(current_block_)->ao_number().IsNext(
+      code()->InstructionBlockAt(block)->ao_number());
+}
+
+
 void CodeGenerator::RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind,
                                     int arguments,
                                     Safepoint::DeoptMode deopt_mode) {
@@ -100,18 +148,6 @@
 
 
 void CodeGenerator::AssembleInstruction(Instruction* instr) {
-  if (instr->IsBlockStart()) {
-    // Bind a label for a block start and handle parallel moves.
-    BlockStartInstruction* block_start = BlockStartInstruction::cast(instr);
-    current_block_ = block_start->block();
-    if (FLAG_code_comments) {
-      // TODO(titzer): these code comments are a giant memory leak.
-      Vector<char> buffer = Vector<char>::New(32);
-      SNPrintF(buffer, "-- B%d start --", block_start->block()->id());
-      masm()->RecordComment(buffer.start());
-    }
-    masm()->bind(block_start->label());
-  }
   if (instr->IsGapMoves()) {
     // Handle parallel moves associated with the gap instruction.
     AssembleGap(GapInstruction::cast(instr));
@@ -121,18 +157,39 @@
     // Assemble architecture-specific code for the instruction.
     AssembleArchInstruction(instr);
 
-    // Assemble branches or boolean materializations after this instruction.
     FlagsMode mode = FlagsModeField::decode(instr->opcode());
     FlagsCondition condition = FlagsConditionField::decode(instr->opcode());
-    switch (mode) {
-      case kFlags_none:
+    if (mode == kFlags_branch) {
+      // Assemble a branch after this instruction.
+      InstructionOperandConverter i(this, instr);
+      BasicBlock::RpoNumber true_rpo =
+          i.InputRpo(static_cast<int>(instr->InputCount()) - 2);
+      BasicBlock::RpoNumber false_rpo =
+          i.InputRpo(static_cast<int>(instr->InputCount()) - 1);
+
+      if (true_rpo == false_rpo) {
+        // redundant branch.
+        if (!IsNextInAssemblyOrder(true_rpo)) {
+          AssembleArchJump(true_rpo);
+        }
         return;
-      case kFlags_set:
-        return AssembleArchBoolean(instr, condition);
-      case kFlags_branch:
-        return AssembleArchBranch(instr, condition);
+      }
+      if (IsNextInAssemblyOrder(true_rpo)) {
+        // true block is next, can fall through if condition negated.
+        std::swap(true_rpo, false_rpo);
+        condition = NegateFlagsCondition(condition);
+      }
+      BranchInfo branch;
+      branch.condition = condition;
+      branch.true_label = GetLabel(true_rpo);
+      branch.false_label = GetLabel(false_rpo);
+      branch.fallthru = IsNextInAssemblyOrder(false_rpo);
+      // Assemble architecture-specific branch.
+      AssembleArchBranch(instr, &branch);
+    } else if (mode == kFlags_set) {
+      // Assemble a boolean materialization after this instruction.
+      AssembleArchBoolean(instr, condition);
     }
-    UNREACHABLE();
   }
 }
 
@@ -147,7 +204,7 @@
     masm()->positions_recorder()->WriteRecordedPositions();
     if (FLAG_code_comments) {
       Vector<char> buffer = Vector<char>::New(256);
-      CompilationInfo* info = linkage()->info();
+      CompilationInfo* info = this->info();
       int ln = Script::GetLineNumber(info->script(), code_pos);
       int cn = Script::GetColumnNumber(info->script(), code_pos);
       if (info->script()->name()->IsString()) {
@@ -177,7 +234,7 @@
 
 
 void CodeGenerator::PopulateDeoptimizationData(Handle<Code> code_object) {
-  CompilationInfo* info = linkage()->info();
+  CompilationInfo* info = this->info();
   int deopt_count = static_cast<int>(deoptimization_states_.size());
   if (deopt_count == 0) return;
   Handle<DeoptimizationInputData> data =
@@ -260,17 +317,17 @@
     // because it is only used to get locals and arguments (by the debugger and
     // f.arguments), and those are the same in the pre-call and post-call
     // states.
-    if (descriptor->state_combine() != kIgnoreOutput) {
-      deopt_state_id =
-          BuildTranslation(instr, -1, frame_state_offset, kIgnoreOutput);
+    if (!descriptor->state_combine().IsOutputIgnored()) {
+      deopt_state_id = BuildTranslation(instr, -1, frame_state_offset,
+                                        OutputFrameStateCombine::Ignore());
     }
 #if DEBUG
     // Make sure all the values live in stack slots or they are immediates.
     // (The values should not live in register because registers are clobbered
     // by calls.)
-    for (size_t i = 0; i < descriptor->size(); i++) {
+    for (size_t i = 0; i < descriptor->GetSize(); i++) {
       InstructionOperand* op = instr->InputAt(frame_state_offset + 1 + i);
-      CHECK(op->IsStackSlot() || op->IsImmediate());
+      CHECK(op->IsStackSlot() || op->IsDoubleStackSlot() || op->IsImmediate());
     }
 #endif
     safepoints()->RecordLazyDeoptimizationIndex(deopt_state_id);
@@ -296,6 +353,44 @@
   return code()->GetFrameStateDescriptor(state_id);
 }
 
+struct OperandAndType {
+  OperandAndType(InstructionOperand* operand, MachineType type)
+      : operand_(operand), type_(type) {}
+
+  InstructionOperand* operand_;
+  MachineType type_;
+};
+
+static OperandAndType TypedOperandForFrameState(
+    FrameStateDescriptor* descriptor, Instruction* instr,
+    size_t frame_state_offset, size_t index, OutputFrameStateCombine combine) {
+  DCHECK(index < descriptor->GetSize(combine));
+  switch (combine.kind()) {
+    case OutputFrameStateCombine::kPushOutput: {
+      DCHECK(combine.GetPushCount() <= instr->OutputCount());
+      size_t size_without_output =
+          descriptor->GetSize(OutputFrameStateCombine::Ignore());
+      // If the index is past the existing stack items, return the output.
+      if (index >= size_without_output) {
+        return OperandAndType(instr->OutputAt(index - size_without_output),
+                              kMachAnyTagged);
+      }
+      break;
+    }
+    case OutputFrameStateCombine::kPokeAt:
+      size_t index_from_top =
+          descriptor->GetSize(combine) - 1 - combine.GetOffsetToPokeAt();
+      if (index >= index_from_top &&
+          index < index_from_top + instr->OutputCount()) {
+        return OperandAndType(instr->OutputAt(index - index_from_top),
+                              kMachAnyTagged);
+      }
+      break;
+  }
+  return OperandAndType(instr->InputAt(frame_state_offset + index),
+                        descriptor->GetType(index));
+}
+
 
 void CodeGenerator::BuildTranslationForFrameStateDescriptor(
     FrameStateDescriptor* descriptor, Instruction* instr,
@@ -305,7 +400,7 @@
   if (descriptor->outer_state() != NULL) {
     BuildTranslationForFrameStateDescriptor(descriptor->outer_state(), instr,
                                             translation, frame_state_offset,
-                                            kIgnoreOutput);
+                                            OutputFrameStateCombine::Ignore());
   }
 
   int id = Translation::kSelfLiteralId;
@@ -318,7 +413,8 @@
     case JS_FRAME:
       translation->BeginJSFrame(
           descriptor->bailout_id(), id,
-          static_cast<unsigned int>(descriptor->GetHeight(state_combine)));
+          static_cast<unsigned int>(descriptor->GetSize(state_combine) -
+                                    descriptor->parameters_count()));
       break;
     case ARGUMENTS_ADAPTOR:
       translation->BeginArgumentsAdaptorFrame(
@@ -327,19 +423,10 @@
   }
 
   frame_state_offset += descriptor->outer_state()->GetTotalSize();
-  for (size_t i = 0; i < descriptor->size(); i++) {
-    AddTranslationForOperand(
-        translation, instr,
-        instr->InputAt(static_cast<int>(frame_state_offset + i)));
-  }
-
-  switch (state_combine) {
-    case kPushOutput:
-      DCHECK(instr->OutputCount() == 1);
-      AddTranslationForOperand(translation, instr, instr->OutputAt(0));
-      break;
-    case kIgnoreOutput:
-      break;
+  for (size_t i = 0; i < descriptor->GetSize(state_combine); i++) {
+    OperandAndType op = TypedOperandForFrameState(
+        descriptor, instr, frame_state_offset, i, state_combine);
+    AddTranslationForOperand(translation, instr, op.operand_, op.type_);
   }
 }
 
@@ -368,15 +455,38 @@
 
 void CodeGenerator::AddTranslationForOperand(Translation* translation,
                                              Instruction* instr,
-                                             InstructionOperand* op) {
+                                             InstructionOperand* op,
+                                             MachineType type) {
   if (op->IsStackSlot()) {
-    translation->StoreStackSlot(op->index());
+    if (type == kMachBool || type == kMachInt32 || type == kMachInt8 ||
+        type == kMachInt16) {
+      translation->StoreInt32StackSlot(op->index());
+    } else if (type == kMachUint32 || type == kMachUint16 ||
+               type == kMachUint8) {
+      translation->StoreUint32StackSlot(op->index());
+    } else if ((type & kRepMask) == kRepTagged) {
+      translation->StoreStackSlot(op->index());
+    } else {
+      CHECK(false);
+    }
   } else if (op->IsDoubleStackSlot()) {
+    DCHECK((type & (kRepFloat32 | kRepFloat64)) != 0);
     translation->StoreDoubleStackSlot(op->index());
   } else if (op->IsRegister()) {
     InstructionOperandConverter converter(this, instr);
-    translation->StoreRegister(converter.ToRegister(op));
+    if (type == kMachBool || type == kMachInt32 || type == kMachInt8 ||
+        type == kMachInt16) {
+      translation->StoreInt32Register(converter.ToRegister(op));
+    } else if (type == kMachUint32 || type == kMachUint16 ||
+               type == kMachUint8) {
+      translation->StoreUint32Register(converter.ToRegister(op));
+    } else if ((type & kRepMask) == kRepTagged) {
+      translation->StoreRegister(converter.ToRegister(op));
+    } else {
+      CHECK(false);
+    }
   } else if (op->IsDoubleRegister()) {
+    DCHECK((type & (kRepFloat32 | kRepFloat64)) != 0);
     InstructionOperandConverter converter(this, instr);
     translation->StoreDoubleRegister(converter.ToDoubleRegister(op));
   } else if (op->IsImmediate()) {
@@ -385,22 +495,25 @@
     Handle<Object> constant_object;
     switch (constant.type()) {
       case Constant::kInt32:
+        DCHECK(type == kMachInt32 || type == kMachUint32);
         constant_object =
             isolate()->factory()->NewNumberFromInt(constant.ToInt32());
         break;
       case Constant::kFloat64:
+        DCHECK(type == kMachFloat64 || type == kMachAnyTagged);
         constant_object = isolate()->factory()->NewNumber(constant.ToFloat64());
         break;
       case Constant::kHeapObject:
+        DCHECK((type & kRepMask) == kRepTagged);
         constant_object = constant.ToHeapObject();
         break;
       default:
-        UNREACHABLE();
+        CHECK(false);
     }
     int literal_id = DefineDeoptimizationLiteral(constant_object);
     translation->StoreLiteral(literal_id);
   } else {
-    UNREACHABLE();
+    CHECK(false);
   }
 }
 
@@ -417,7 +530,7 @@
 
 
 void CodeGenerator::AssembleArchBranch(Instruction* instr,
-                                       FlagsCondition condition) {
+                                       BranchInfo* branch) {
   UNIMPLEMENTED();
 }
 
@@ -428,6 +541,11 @@
 }
 
 
+void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+  UNIMPLEMENTED();
+}
+
+
 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
   UNIMPLEMENTED();
 }
@@ -455,6 +573,15 @@
 
 #endif  // !V8_TURBOFAN_BACKEND
 
+
+OutOfLineCode::OutOfLineCode(CodeGenerator* gen)
+    : masm_(gen->masm()), next_(gen->ools_) {
+  gen->ools_ = this;
+}
+
+
+OutOfLineCode::~OutOfLineCode() {}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/code-generator.h b/src/compiler/code-generator.h
index ddc2f9a..747bad2 100644
--- a/src/compiler/code-generator.h
+++ b/src/compiler/code-generator.h
@@ -5,8 +5,6 @@
 #ifndef V8_COMPILER_CODE_GENERATOR_H_
 #define V8_COMPILER_CODE_GENERATOR_H_
 
-#include <deque>
-
 #include "src/compiler/gap-resolver.h"
 #include "src/compiler/instruction.h"
 #include "src/deoptimizer.h"
@@ -17,33 +15,44 @@
 namespace internal {
 namespace compiler {
 
+// Forward declarations.
+class Linkage;
+class OutOfLineCode;
+
+struct BranchInfo {
+  FlagsCondition condition;
+  Label* true_label;
+  Label* false_label;
+  bool fallthru;
+};
+
+
 // Generates native code for a sequence of instructions.
 class CodeGenerator FINAL : public GapResolver::Assembler {
  public:
-  explicit CodeGenerator(InstructionSequence* code);
+  explicit CodeGenerator(Frame* frame, Linkage* linkage,
+                         InstructionSequence* code, CompilationInfo* info);
 
   // Generate native code.
   Handle<Code> GenerateCode();
 
   InstructionSequence* code() const { return code_; }
-  Frame* frame() const { return code()->frame(); }
-  Graph* graph() const { return code()->graph(); }
+  Frame* frame() const { return frame_; }
   Isolate* isolate() const { return zone()->isolate(); }
-  Linkage* linkage() const { return code()->linkage(); }
-  Schedule* schedule() const { return code()->schedule(); }
+  Linkage* linkage() const { return linkage_; }
+
+  Label* GetLabel(BasicBlock::RpoNumber rpo) { return &labels_[rpo.ToSize()]; }
 
  private:
   MacroAssembler* masm() { return &masm_; }
   GapResolver* resolver() { return &resolver_; }
   SafepointTableBuilder* safepoints() { return &safepoints_; }
   Zone* zone() const { return code()->zone(); }
+  CompilationInfo* info() const { return info_; }
 
   // Checks if {block} will appear directly after {current_block_} when
   // assembling code, in which case, a fall-through can be used.
-  bool IsNextInAssemblyOrder(const BasicBlock* block) const {
-    return block->rpo_number_ == (current_block_->rpo_number_ + 1) &&
-           block->deferred_ == current_block_->deferred_;
-  }
+  bool IsNextInAssemblyOrder(BasicBlock::RpoNumber block) const;
 
   // Record a safepoint with the given pointer map.
   void RecordSafepoint(PointerMap* pointers, Safepoint::Kind kind,
@@ -59,7 +68,8 @@
   // ===========================================================================
 
   void AssembleArchInstruction(Instruction* instr);
-  void AssembleArchBranch(Instruction* instr, FlagsCondition condition);
+  void AssembleArchJump(BasicBlock::RpoNumber target);
+  void AssembleArchBranch(Instruction* instr, BranchInfo* branch);
   void AssembleArchBoolean(Instruction* instr, FlagsCondition condition);
 
   void AssembleDeoptimizerCall(int deoptimization_id);
@@ -76,10 +86,10 @@
   // ===========================================================================
 
   // Interface used by the gap resolver to emit moves and swaps.
-  virtual void AssembleMove(InstructionOperand* source,
-                            InstructionOperand* destination) OVERRIDE;
-  virtual void AssembleSwap(InstructionOperand* source,
-                            InstructionOperand* destination) OVERRIDE;
+  void AssembleMove(InstructionOperand* source,
+                    InstructionOperand* destination) FINAL;
+  void AssembleSwap(InstructionOperand* source,
+                    InstructionOperand* destination) FINAL;
 
   // ===========================================================================
   // Deoptimization table construction
@@ -96,7 +106,7 @@
       Translation* translation, size_t frame_state_offset,
       OutputFrameStateCombine state_combine);
   void AddTranslationForOperand(Translation* translation, Instruction* instr,
-                                InstructionOperand* op);
+                                InstructionOperand* op, MachineType type);
   void AddNopForSmiCodeInlining();
   void EnsureSpaceForLazyDeopt();
   void MarkLazyDeoptSite();
@@ -119,8 +129,14 @@
     int pc_offset_;
   };
 
-  InstructionSequence* code_;
-  BasicBlock* current_block_;
+  friend class OutOfLineCode;
+
+  Frame* const frame_;
+  Linkage* const linkage_;
+  InstructionSequence* const code_;
+  CompilationInfo* const info_;
+  Label* const labels_;
+  BasicBlock::RpoNumber current_block_;
   SourcePosition current_source_position_;
   MacroAssembler masm_;
   GapResolver resolver_;
@@ -129,6 +145,7 @@
   ZoneDeque<Handle<Object> > deoptimization_literals_;
   TranslationBuffer translations_;
   int last_lazy_deopt_pc_;
+  OutOfLineCode* ools_;
 };
 
 }  // namespace compiler
diff --git a/src/compiler/common-node-cache.cc b/src/compiler/common-node-cache.cc
new file mode 100644
index 0000000..ee1fa0f
--- /dev/null
+++ b/src/compiler/common-node-cache.cc
@@ -0,0 +1,29 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/common-node-cache.h"
+
+#include "src/assembler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+Node** CommonNodeCache::FindExternalConstant(ExternalReference value) {
+  return external_constants_.Find(zone(), bit_cast<intptr_t>(value.address()));
+}
+
+
+void CommonNodeCache::GetCachedNodes(ZoneVector<Node*>* nodes) {
+  int32_constants_.GetCachedNodes(nodes);
+  int64_constants_.GetCachedNodes(nodes);
+  float32_constants_.GetCachedNodes(nodes);
+  float64_constants_.GetCachedNodes(nodes);
+  external_constants_.GetCachedNodes(nodes);
+  number_constants_.GetCachedNodes(nodes);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/common-node-cache.h b/src/compiler/common-node-cache.h
index 1ed2b04..7ec70ae 100644
--- a/src/compiler/common-node-cache.h
+++ b/src/compiler/common-node-cache.h
@@ -5,47 +5,67 @@
 #ifndef V8_COMPILER_COMMON_NODE_CACHE_H_
 #define V8_COMPILER_COMMON_NODE_CACHE_H_
 
-#include "src/assembler.h"
 #include "src/compiler/node-cache.h"
 
 namespace v8 {
 namespace internal {
+
+// Forward declarations.
+class ExternalReference;
+
+
 namespace compiler {
 
 // Bundles various caches for common nodes.
-class CommonNodeCache FINAL : public ZoneObject {
+class CommonNodeCache FINAL {
  public:
   explicit CommonNodeCache(Zone* zone) : zone_(zone) {}
+  ~CommonNodeCache() {}
 
   Node** FindInt32Constant(int32_t value) {
-    return int32_constants_.Find(zone_, value);
+    return int32_constants_.Find(zone(), value);
+  }
+
+  Node** FindInt64Constant(int64_t value) {
+    return int64_constants_.Find(zone(), value);
+  }
+
+  Node** FindFloat32Constant(float value) {
+    // We canonicalize float constants at the bit representation level.
+    return float32_constants_.Find(zone(), bit_cast<int32_t>(value));
   }
 
   Node** FindFloat64Constant(double value) {
     // We canonicalize double constants at the bit representation level.
-    return float64_constants_.Find(zone_, bit_cast<int64_t>(value));
+    return float64_constants_.Find(zone(), bit_cast<int64_t>(value));
   }
 
-  Node** FindExternalConstant(ExternalReference reference) {
-    return external_constants_.Find(zone_, reference.address());
-  }
+  Node** FindExternalConstant(ExternalReference value);
 
   Node** FindNumberConstant(double value) {
     // We canonicalize double constants at the bit representation level.
-    return number_constants_.Find(zone_, bit_cast<int64_t>(value));
+    return number_constants_.Find(zone(), bit_cast<int64_t>(value));
   }
 
+  // Return all nodes from the cache.
+  void GetCachedNodes(ZoneVector<Node*>* nodes);
+
   Zone* zone() const { return zone_; }
 
  private:
   Int32NodeCache int32_constants_;
+  Int64NodeCache int64_constants_;
+  Int32NodeCache float32_constants_;
   Int64NodeCache float64_constants_;
-  PtrNodeCache external_constants_;
+  IntPtrNodeCache external_constants_;
   Int64NodeCache number_constants_;
   Zone* zone_;
+
+  DISALLOW_COPY_AND_ASSIGN(CommonNodeCache);
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_COMMON_NODE_CACHE_H_
diff --git a/src/compiler/common-operator-reducer.cc b/src/compiler/common-operator-reducer.cc
new file mode 100644
index 0000000..cf597ea
--- /dev/null
+++ b/src/compiler/common-operator-reducer.cc
@@ -0,0 +1,41 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/common-operator-reducer.h"
+
+#include "src/compiler/common-operator.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+Reduction CommonOperatorReducer::Reduce(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kEffectPhi:
+    case IrOpcode::kPhi: {
+      int const input_count = node->InputCount();
+      if (input_count > 1) {
+        Node* const replacement = node->InputAt(0);
+        for (int i = 1; i < input_count - 1; ++i) {
+          if (node->InputAt(i) != replacement) return NoChange();
+        }
+        return Replace(replacement);
+      }
+      break;
+    }
+    case IrOpcode::kSelect: {
+      if (node->InputAt(1) == node->InputAt(2)) {
+        return Replace(node->InputAt(1));
+      }
+      break;
+    }
+    default:
+      break;
+  }
+  return NoChange();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/common-operator-reducer.h b/src/compiler/common-operator-reducer.h
new file mode 100644
index 0000000..10543db
--- /dev/null
+++ b/src/compiler/common-operator-reducer.h
@@ -0,0 +1,27 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_COMMON_OPERATOR_REDUCER_H_
+#define V8_COMPILER_COMMON_OPERATOR_REDUCER_H_
+
+#include "src/compiler/graph-reducer.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Performs strength reduction on nodes that have common operators.
+class CommonOperatorReducer FINAL : public Reducer {
+ public:
+  CommonOperatorReducer() {}
+  ~CommonOperatorReducer() FINAL {}
+
+  Reduction Reduce(Node* node) FINAL;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_COMMON_OPERATOR_REDUCER_H_
diff --git a/src/compiler/common-operator-unittest.cc b/src/compiler/common-operator-unittest.cc
deleted file mode 100644
index 5001770..0000000
--- a/src/compiler/common-operator-unittest.cc
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/common-operator.h"
-
-#include <limits>
-
-#include "src/compiler/operator-properties-inl.h"
-#include "src/test/test-utils.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-
-// -----------------------------------------------------------------------------
-// Shared operators.
-
-
-namespace {
-
-struct SharedOperator {
-  const Operator* (CommonOperatorBuilder::*constructor)();
-  IrOpcode::Value opcode;
-  Operator::Properties properties;
-  int value_input_count;
-  int effect_input_count;
-  int control_input_count;
-  int effect_output_count;
-  int control_output_count;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const SharedOperator& fop) {
-  return os << IrOpcode::Mnemonic(fop.opcode);
-}
-
-
-const SharedOperator kSharedOperators[] = {
-#define SHARED(Name, properties, value_input_count, effect_input_count,        \
-               control_input_count, effect_output_count, control_output_count) \
-  {                                                                            \
-    &CommonOperatorBuilder::Name, IrOpcode::k##Name, properties,               \
-        value_input_count, effect_input_count, control_input_count,            \
-        effect_output_count, control_output_count                              \
-  }
-    SHARED(Dead, Operator::kFoldable, 0, 0, 0, 0, 1),
-    SHARED(End, Operator::kFoldable, 0, 0, 1, 0, 0),
-    SHARED(Branch, Operator::kFoldable, 1, 0, 1, 0, 2),
-    SHARED(IfTrue, Operator::kFoldable, 0, 0, 1, 0, 1),
-    SHARED(IfFalse, Operator::kFoldable, 0, 0, 1, 0, 1),
-    SHARED(Throw, Operator::kFoldable, 1, 0, 1, 0, 1),
-    SHARED(Return, Operator::kNoProperties, 1, 1, 1, 1, 1),
-    SHARED(ControlEffect, Operator::kPure, 0, 0, 1, 1, 0)
-#undef SHARED
-};
-
-
-class CommonSharedOperatorTest
-    : public TestWithZone,
-      public ::testing::WithParamInterface<SharedOperator> {};
-
-}  // namespace
-
-
-TEST_P(CommonSharedOperatorTest, InstancesAreGloballyShared) {
-  const SharedOperator& sop = GetParam();
-  CommonOperatorBuilder common1(zone());
-  CommonOperatorBuilder common2(zone());
-  EXPECT_EQ((common1.*sop.constructor)(), (common2.*sop.constructor)());
-}
-
-
-TEST_P(CommonSharedOperatorTest, NumberOfInputsAndOutputs) {
-  CommonOperatorBuilder common(zone());
-  const SharedOperator& sop = GetParam();
-  const Operator* op = (common.*sop.constructor)();
-
-  EXPECT_EQ(sop.value_input_count, OperatorProperties::GetValueInputCount(op));
-  EXPECT_EQ(sop.effect_input_count,
-            OperatorProperties::GetEffectInputCount(op));
-  EXPECT_EQ(sop.control_input_count,
-            OperatorProperties::GetControlInputCount(op));
-  EXPECT_EQ(
-      sop.value_input_count + sop.effect_input_count + sop.control_input_count,
-      OperatorProperties::GetTotalInputCount(op));
-
-  EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
-  EXPECT_EQ(sop.effect_output_count,
-            OperatorProperties::GetEffectOutputCount(op));
-  EXPECT_EQ(sop.control_output_count,
-            OperatorProperties::GetControlOutputCount(op));
-}
-
-
-TEST_P(CommonSharedOperatorTest, OpcodeIsCorrect) {
-  CommonOperatorBuilder common(zone());
-  const SharedOperator& sop = GetParam();
-  const Operator* op = (common.*sop.constructor)();
-  EXPECT_EQ(sop.opcode, op->opcode());
-}
-
-
-TEST_P(CommonSharedOperatorTest, Properties) {
-  CommonOperatorBuilder common(zone());
-  const SharedOperator& sop = GetParam();
-  const Operator* op = (common.*sop.constructor)();
-  EXPECT_EQ(sop.properties, op->properties());
-}
-
-
-INSTANTIATE_TEST_CASE_P(CommonOperatorTest, CommonSharedOperatorTest,
-                        ::testing::ValuesIn(kSharedOperators));
-
-
-// -----------------------------------------------------------------------------
-// Other operators.
-
-
-namespace {
-
-class CommonOperatorTest : public TestWithZone {
- public:
-  CommonOperatorTest() : common_(zone()) {}
-  virtual ~CommonOperatorTest() {}
-
-  CommonOperatorBuilder* common() { return &common_; }
-
- private:
-  CommonOperatorBuilder common_;
-};
-
-
-const int kArguments[] = {1, 5, 6, 42, 100, 10000, kMaxInt};
-
-const float kFloat32Values[] = {
-    std::numeric_limits<float>::min(), -1.0f, -0.0f, 0.0f, 1.0f,
-    std::numeric_limits<float>::max()};
-
-}  // namespace
-
-
-TEST_F(CommonOperatorTest, Float32Constant) {
-  TRACED_FOREACH(float, value, kFloat32Values) {
-    const Operator* op = common()->Float32Constant(value);
-    EXPECT_FLOAT_EQ(value, OpParameter<float>(op));
-    EXPECT_EQ(0, OperatorProperties::GetValueInputCount(op));
-    EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
-    EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
-    EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
-    EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
-  }
-}
-
-
-TEST_F(CommonOperatorTest, ValueEffect) {
-  TRACED_FOREACH(int, arguments, kArguments) {
-    const Operator* op = common()->ValueEffect(arguments);
-    EXPECT_EQ(arguments, OperatorProperties::GetValueInputCount(op));
-    EXPECT_EQ(arguments, OperatorProperties::GetTotalInputCount(op));
-    EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
-    EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
-    EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
-  }
-}
-
-
-TEST_F(CommonOperatorTest, Finish) {
-  TRACED_FOREACH(int, arguments, kArguments) {
-    const Operator* op = common()->Finish(arguments);
-    EXPECT_EQ(1, OperatorProperties::GetValueInputCount(op));
-    EXPECT_EQ(arguments, OperatorProperties::GetEffectInputCount(op));
-    EXPECT_EQ(arguments + 1, OperatorProperties::GetTotalInputCount(op));
-    EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
-    EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
-    EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
-  }
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/common-operator.cc b/src/compiler/common-operator.cc
index 19792bd..a6cca45 100644
--- a/src/compiler/common-operator.cc
+++ b/src/compiler/common-operator.cc
@@ -7,6 +7,8 @@
 #include "src/assembler.h"
 #include "src/base/lazy-instance.h"
 #include "src/compiler/linkage.h"
+#include "src/compiler/opcodes.h"
+#include "src/compiler/operator.h"
 #include "src/unique.h"
 #include "src/zone.h"
 
@@ -14,209 +16,430 @@
 namespace internal {
 namespace compiler {
 
-namespace {
-
-// TODO(turbofan): Use size_t instead of int here.
-class ControlOperator : public Operator1<int> {
- public:
-  ControlOperator(IrOpcode::Value opcode, Properties properties, int inputs,
-                  int outputs, int controls, const char* mnemonic)
-      : Operator1<int>(opcode, properties, inputs, outputs, mnemonic,
-                       controls) {}
-
-  virtual OStream& PrintParameter(OStream& os) const FINAL { return os; }
-};
-
-}  // namespace
-
-
-// Specialization for static parameters of type {ExternalReference}.
-template <>
-struct StaticParameterTraits<ExternalReference> {
-  static OStream& PrintTo(OStream& os, ExternalReference reference) {
-    os << reference.address();
-    // TODO(bmeurer): Move to operator<<(os, ExternalReference)
-    const Runtime::Function* function =
-        Runtime::FunctionForEntry(reference.address());
-    if (function) {
-      os << " <" << function->name << ".entry>";
-    }
-    return os;
+std::ostream& operator<<(std::ostream& os, BranchHint hint) {
+  switch (hint) {
+    case BranchHint::kNone:
+      return os << "None";
+    case BranchHint::kTrue:
+      return os << "True";
+    case BranchHint::kFalse:
+      return os << "False";
   }
-  static int HashCode(ExternalReference reference) {
-    return bit_cast<int>(static_cast<uint32_t>(
-        reinterpret_cast<uintptr_t>(reference.address())));
+  UNREACHABLE();
+  return os;
+}
+
+
+BranchHint BranchHintOf(const Operator* const op) {
+  DCHECK_EQ(IrOpcode::kBranch, op->opcode());
+  return OpParameter<BranchHint>(op);
+}
+
+
+bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) {
+  return lhs.type() == rhs.type() && lhs.hint() == rhs.hint();
+}
+
+
+bool operator!=(SelectParameters const& lhs, SelectParameters const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(SelectParameters const& p) {
+  return base::hash_combine(p.type(), p.hint());
+}
+
+
+std::ostream& operator<<(std::ostream& os, SelectParameters const& p) {
+  return os << p.type() << "|" << p.hint();
+}
+
+
+SelectParameters const& SelectParametersOf(const Operator* const op) {
+  DCHECK_EQ(IrOpcode::kSelect, op->opcode());
+  return OpParameter<SelectParameters>(op);
+}
+
+
+size_t hash_value(OutputFrameStateCombine const& sc) {
+  return base::hash_combine(sc.kind_, sc.parameter_);
+}
+
+
+std::ostream& operator<<(std::ostream& os, OutputFrameStateCombine const& sc) {
+  switch (sc.kind_) {
+    case OutputFrameStateCombine::kPushOutput:
+      if (sc.parameter_ == 0) return os << "Ignore";
+      return os << "Push(" << sc.parameter_ << ")";
+    case OutputFrameStateCombine::kPokeAt:
+      return os << "PokeAt(" << sc.parameter_ << ")";
   }
-  static bool Equals(ExternalReference lhs, ExternalReference rhs) {
-    return lhs == rhs;
-  }
-};
+  UNREACHABLE();
+  return os;
+}
 
 
-#define SHARED_OP_LIST(V)               \
-  V(Dead, Operator::kFoldable, 0, 0)    \
-  V(End, Operator::kFoldable, 0, 1)     \
-  V(Branch, Operator::kFoldable, 1, 1)  \
-  V(IfTrue, Operator::kFoldable, 0, 1)  \
-  V(IfFalse, Operator::kFoldable, 0, 1) \
-  V(Throw, Operator::kFoldable, 1, 1)   \
-  V(Return, Operator::kNoProperties, 1, 1)
+bool operator==(FrameStateCallInfo const& lhs, FrameStateCallInfo const& rhs) {
+  return lhs.type() == rhs.type() && lhs.bailout_id() == rhs.bailout_id() &&
+         lhs.state_combine() == rhs.state_combine();
+}
 
 
-struct CommonOperatorBuilderImpl FINAL {
-#define SHARED(Name, properties, value_input_count, control_input_count)       \
-  struct Name##Operator FINAL : public ControlOperator {                       \
-    Name##Operator()                                                           \
-        : ControlOperator(IrOpcode::k##Name, properties, value_input_count, 0, \
-                          control_input_count, #Name) {}                       \
-  };                                                                           \
+bool operator!=(FrameStateCallInfo const& lhs, FrameStateCallInfo const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(FrameStateCallInfo const& info) {
+  return base::hash_combine(info.type(), info.bailout_id(),
+                            info.state_combine());
+}
+
+
+std::ostream& operator<<(std::ostream& os, FrameStateCallInfo const& info) {
+  return os << info.type() << ", " << info.bailout_id() << ", "
+            << info.state_combine();
+}
+
+
+#define CACHED_OP_LIST(V)                     \
+  V(Dead, Operator::kFoldable, 0, 0, 0, 1)    \
+  V(End, Operator::kFoldable, 0, 0, 1, 0)     \
+  V(IfTrue, Operator::kFoldable, 0, 0, 1, 1)  \
+  V(IfFalse, Operator::kFoldable, 0, 0, 1, 1) \
+  V(Throw, Operator::kFoldable, 1, 1, 1, 1)   \
+  V(Return, Operator::kNoProperties, 1, 1, 1, 1)
+
+
+#define CACHED_LOOP_LIST(V) \
+  V(1)                      \
+  V(2)
+
+
+#define CACHED_MERGE_LIST(V) \
+  V(1)                       \
+  V(2)                       \
+  V(3)                       \
+  V(4)                       \
+  V(5)                       \
+  V(6)                       \
+  V(7)                       \
+  V(8)
+
+
+#define CACHED_PARAMETER_LIST(V) \
+  V(0)                           \
+  V(1)                           \
+  V(2)                           \
+  V(3)                           \
+  V(4)                           \
+  V(5)                           \
+  V(6)
+
+
+struct CommonOperatorGlobalCache FINAL {
+#define CACHED(Name, properties, value_input_count, effect_input_count,     \
+               control_input_count, control_output_count)                   \
+  struct Name##Operator FINAL : public Operator {                           \
+    Name##Operator()                                                        \
+        : Operator(IrOpcode::k##Name, properties, #Name, value_input_count, \
+                   effect_input_count, control_input_count, 0, 0,           \
+                   control_output_count) {}                                 \
+  };                                                                        \
   Name##Operator k##Name##Operator;
-  SHARED_OP_LIST(SHARED)
-#undef SHARED
+  CACHED_OP_LIST(CACHED)
+#undef CACHED
 
-  struct ControlEffectOperator FINAL : public SimpleOperator {
-    ControlEffectOperator()
-        : SimpleOperator(IrOpcode::kControlEffect, Operator::kPure, 0, 0,
-                         "ControlEffect") {}
+  template <BranchHint kBranchHint>
+  struct BranchOperator FINAL : public Operator1<BranchHint> {
+    BranchOperator()
+        : Operator1<BranchHint>(                       // --
+              IrOpcode::kBranch, Operator::kFoldable,  // opcode
+              "Branch",                                // name
+              1, 0, 1, 0, 0, 2,                        // counts
+              kBranchHint) {}                          // parameter
   };
-  ControlEffectOperator kControlEffectOperator;
+  BranchOperator<BranchHint::kNone> kBranchNoneOperator;
+  BranchOperator<BranchHint::kTrue> kBranchTrueOperator;
+  BranchOperator<BranchHint::kFalse> kBranchFalseOperator;
+
+  template <size_t kInputCount>
+  struct LoopOperator FINAL : public Operator {
+    LoopOperator()
+        : Operator(                                  // --
+              IrOpcode::kLoop, Operator::kFoldable,  // opcode
+              "Loop",                                // name
+              0, 0, kInputCount, 0, 0, 1) {}         // counts
+  };
+#define CACHED_LOOP(input_count) \
+  LoopOperator<input_count> kLoop##input_count##Operator;
+  CACHED_LOOP_LIST(CACHED_LOOP)
+#undef CACHED_LOOP
+
+  template <size_t kInputCount>
+  struct MergeOperator FINAL : public Operator {
+    MergeOperator()
+        : Operator(                                   // --
+              IrOpcode::kMerge, Operator::kFoldable,  // opcode
+              "Merge",                                // name
+              0, 0, kInputCount, 0, 0, 1) {}          // counts
+  };
+#define CACHED_MERGE(input_count) \
+  MergeOperator<input_count> kMerge##input_count##Operator;
+  CACHED_MERGE_LIST(CACHED_MERGE)
+#undef CACHED_MERGE
+
+  template <int kIndex>
+  struct ParameterOperator FINAL : public Operator1<int> {
+    ParameterOperator()
+        : Operator1<int>(                             // --
+              IrOpcode::kParameter, Operator::kPure,  // opcode
+              "Parameter",                            // name
+              1, 0, 0, 1, 0, 0,                       // counts,
+              kIndex) {}                              // parameter
+  };
+#define CACHED_PARAMETER(index) \
+  ParameterOperator<index> kParameter##index##Operator;
+  CACHED_PARAMETER_LIST(CACHED_PARAMETER)
+#undef CACHED_PARAMETER
 };
 
 
-static base::LazyInstance<CommonOperatorBuilderImpl>::type kImpl =
+static base::LazyInstance<CommonOperatorGlobalCache>::type kCache =
     LAZY_INSTANCE_INITIALIZER;
 
 
 CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone)
-    : impl_(kImpl.Get()), zone_(zone) {}
+    : cache_(kCache.Get()), zone_(zone) {}
 
 
-#define SHARED(Name, properties, value_input_count, control_input_count) \
-  const Operator* CommonOperatorBuilder::Name() {                        \
-    return &impl_.k##Name##Operator;                                     \
+#define CACHED(Name, properties, value_input_count, effect_input_count, \
+               control_input_count, control_output_count)               \
+  const Operator* CommonOperatorBuilder::Name() {                       \
+    return &cache_.k##Name##Operator;                                   \
   }
-SHARED_OP_LIST(SHARED)
-#undef SHARED
+CACHED_OP_LIST(CACHED)
+#undef CACHED
+
+
+const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
+  switch (hint) {
+    case BranchHint::kNone:
+      return &cache_.kBranchNoneOperator;
+    case BranchHint::kTrue:
+      return &cache_.kBranchTrueOperator;
+    case BranchHint::kFalse:
+      return &cache_.kBranchFalseOperator;
+  }
+  UNREACHABLE();
+  return nullptr;
+}
 
 
 const Operator* CommonOperatorBuilder::Start(int num_formal_parameters) {
   // Outputs are formal parameters, plus context, receiver, and JSFunction.
   const int value_output_count = num_formal_parameters + 3;
-  return new (zone()) ControlOperator(IrOpcode::kStart, Operator::kFoldable, 0,
-                                      value_output_count, 0, "Start");
+  return new (zone()) Operator(               // --
+      IrOpcode::kStart, Operator::kFoldable,  // opcode
+      "Start",                                // name
+      0, 0, 0, value_output_count, 1, 1);     // counts
 }
 
 
-const Operator* CommonOperatorBuilder::Merge(int controls) {
-  return new (zone()) ControlOperator(IrOpcode::kMerge, Operator::kFoldable, 0,
-                                      0, controls, "Merge");
+const Operator* CommonOperatorBuilder::Loop(int control_input_count) {
+  switch (control_input_count) {
+#define CACHED_LOOP(input_count) \
+  case input_count:              \
+    return &cache_.kLoop##input_count##Operator;
+    CACHED_LOOP_LIST(CACHED_LOOP)
+#undef CACHED_LOOP
+    default:
+      break;
+  }
+  // Uncached.
+  return new (zone()) Operator(              // --
+      IrOpcode::kLoop, Operator::kFoldable,  // opcode
+      "Loop",                                // name
+      0, 0, control_input_count, 0, 0, 1);   // counts
 }
 
 
-const Operator* CommonOperatorBuilder::Loop(int controls) {
-  return new (zone()) ControlOperator(IrOpcode::kLoop, Operator::kFoldable, 0,
-                                      0, controls, "Loop");
+const Operator* CommonOperatorBuilder::Merge(int control_input_count) {
+  switch (control_input_count) {
+#define CACHED_MERGE(input_count) \
+  case input_count:               \
+    return &cache_.kMerge##input_count##Operator;
+    CACHED_MERGE_LIST(CACHED_MERGE)
+#undef CACHED_MERGE
+    default:
+      break;
+  }
+  // Uncached.
+  return new (zone()) Operator(               // --
+      IrOpcode::kMerge, Operator::kFoldable,  // opcode
+      "Merge",                                // name
+      0, 0, control_input_count, 0, 0, 1);    // counts
+}
+
+
+const Operator* CommonOperatorBuilder::Terminate(int effects) {
+  return new (zone()) Operator(               // --
+      IrOpcode::kTerminate, Operator::kPure,  // opcode
+      "Terminate",                            // name
+      0, effects, 1, 0, 0, 1);                // counts
 }
 
 
 const Operator* CommonOperatorBuilder::Parameter(int index) {
-  return new (zone()) Operator1<int>(IrOpcode::kParameter, Operator::kPure, 1,
-                                     1, "Parameter", index);
+  switch (index) {
+#define CACHED_PARAMETER(index) \
+  case index:                   \
+    return &cache_.kParameter##index##Operator;
+    CACHED_PARAMETER_LIST(CACHED_PARAMETER)
+#undef CACHED_PARAMETER
+    default:
+      break;
+  }
+  // Uncached.
+  return new (zone()) Operator1<int>(         // --
+      IrOpcode::kParameter, Operator::kPure,  // opcode
+      "Parameter",                            // name
+      1, 0, 0, 1, 0, 0,                       // counts
+      index);                                 // parameter
 }
 
 
 const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) {
-  return new (zone()) Operator1<int32_t>(
-      IrOpcode::kInt32Constant, Operator::kPure, 0, 1, "Int32Constant", value);
+  return new (zone()) Operator1<int32_t>(         // --
+      IrOpcode::kInt32Constant, Operator::kPure,  // opcode
+      "Int32Constant",                            // name
+      0, 0, 0, 1, 0, 0,                           // counts
+      value);                                     // parameter
 }
 
 
 const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) {
-  return new (zone()) Operator1<int64_t>(
-      IrOpcode::kInt64Constant, Operator::kPure, 0, 1, "Int64Constant", value);
+  return new (zone()) Operator1<int64_t>(         // --
+      IrOpcode::kInt64Constant, Operator::kPure,  // opcode
+      "Int64Constant",                            // name
+      0, 0, 0, 1, 0, 0,                           // counts
+      value);                                     // parameter
 }
 
 
 const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
   return new (zone())
-      Operator1<float>(IrOpcode::kFloat32Constant, Operator::kPure, 0, 1,
-                       "Float32Constant", value);
+      Operator1<float, base::bit_equal_to<float>, base::bit_hash<float>>(  // --
+          IrOpcode::kFloat32Constant, Operator::kPure,  // opcode
+          "Float32Constant",                            // name
+          0, 0, 0, 1, 0, 0,                             // counts
+          value);                                       // parameter
 }
 
 
 const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
-  return new (zone())
-      Operator1<double>(IrOpcode::kFloat64Constant, Operator::kPure, 0, 1,
-                        "Float64Constant", value);
+  return new (zone()) Operator1<double, base::bit_equal_to<double>,
+                                base::bit_hash<double>>(  // --
+      IrOpcode::kFloat64Constant, Operator::kPure,        // opcode
+      "Float64Constant",                                  // name
+      0, 0, 0, 1, 0, 0,                                   // counts
+      value);                                             // parameter
 }
 
 
 const Operator* CommonOperatorBuilder::ExternalConstant(
     const ExternalReference& value) {
-  return new (zone())
-      Operator1<ExternalReference>(IrOpcode::kExternalConstant, Operator::kPure,
-                                   0, 1, "ExternalConstant", value);
+  return new (zone()) Operator1<ExternalReference>(  // --
+      IrOpcode::kExternalConstant, Operator::kPure,  // opcode
+      "ExternalConstant",                            // name
+      0, 0, 0, 1, 0, 0,                              // counts
+      value);                                        // parameter
 }
 
 
 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
-  return new (zone())
-      Operator1<double>(IrOpcode::kNumberConstant, Operator::kPure, 0, 1,
-                        "NumberConstant", value);
+  return new (zone()) Operator1<double, base::bit_equal_to<double>,
+                                base::bit_hash<double>>(  // --
+      IrOpcode::kNumberConstant, Operator::kPure,         // opcode
+      "NumberConstant",                                   // name
+      0, 0, 0, 1, 0, 0,                                   // counts
+      value);                                             // parameter
 }
 
 
 const Operator* CommonOperatorBuilder::HeapConstant(
-    const Unique<Object>& value) {
-  return new (zone()) Operator1<Unique<Object> >(
-      IrOpcode::kHeapConstant, Operator::kPure, 0, 1, "HeapConstant", value);
+    const Unique<HeapObject>& value) {
+  return new (zone()) Operator1<Unique<HeapObject>>(  // --
+      IrOpcode::kHeapConstant, Operator::kPure,       // opcode
+      "HeapConstant",                                 // name
+      0, 0, 0, 1, 0, 0,                               // counts
+      value);                                         // parameter
+}
+
+
+const Operator* CommonOperatorBuilder::Select(MachineType type,
+                                              BranchHint hint) {
+  return new (zone()) Operator1<SelectParameters>(  // --
+      IrOpcode::kSelect, Operator::kPure,           // opcode
+      "Select",                                     // name
+      3, 0, 0, 1, 0, 0,                             // counts
+      SelectParameters(type, hint));                // parameter
 }
 
 
 const Operator* CommonOperatorBuilder::Phi(MachineType type, int arguments) {
-  DCHECK(arguments > 0);  // Disallow empty phis.
-  return new (zone()) Operator1<MachineType>(IrOpcode::kPhi, Operator::kPure,
-                                             arguments, 1, "Phi", type);
+  DCHECK(arguments > 0);                       // Disallow empty phis.
+  return new (zone()) Operator1<MachineType>(  // --
+      IrOpcode::kPhi, Operator::kPure,         // opcode
+      "Phi",                                   // name
+      arguments, 0, 1, 1, 0, 0,                // counts
+      type);                                   // parameter
 }
 
 
 const Operator* CommonOperatorBuilder::EffectPhi(int arguments) {
-  DCHECK(arguments > 0);  // Disallow empty phis.
-  return new (zone()) Operator1<int>(IrOpcode::kEffectPhi, Operator::kPure, 0,
-                                     0, "EffectPhi", arguments);
-}
-
-
-const Operator* CommonOperatorBuilder::ControlEffect() {
-  return &impl_.kControlEffectOperator;
+  DCHECK(arguments > 0);                      // Disallow empty phis.
+  return new (zone()) Operator(               // --
+      IrOpcode::kEffectPhi, Operator::kPure,  // opcode
+      "EffectPhi",                            // name
+      0, arguments, 1, 0, 1, 0);              // counts
 }
 
 
 const Operator* CommonOperatorBuilder::ValueEffect(int arguments) {
-  DCHECK(arguments > 0);  // Disallow empty value effects.
-  return new (zone()) SimpleOperator(IrOpcode::kValueEffect, Operator::kPure,
-                                     arguments, 0, "ValueEffect");
+  DCHECK(arguments > 0);                        // Disallow empty value effects.
+  return new (zone()) Operator(                 // --
+      IrOpcode::kValueEffect, Operator::kPure,  // opcode
+      "ValueEffect",                            // name
+      arguments, 0, 0, 0, 1, 0);                // counts
 }
 
 
 const Operator* CommonOperatorBuilder::Finish(int arguments) {
-  DCHECK(arguments > 0);  // Disallow empty finishes.
-  return new (zone()) Operator1<int>(IrOpcode::kFinish, Operator::kPure, 1, 1,
-                                     "Finish", arguments);
+  DCHECK(arguments > 0);                   // Disallow empty finishes.
+  return new (zone()) Operator(            // --
+      IrOpcode::kFinish, Operator::kPure,  // opcode
+      "Finish",                            // name
+      1, arguments, 0, 1, 0, 0);           // counts
 }
 
 
 const Operator* CommonOperatorBuilder::StateValues(int arguments) {
-  return new (zone()) Operator1<int>(IrOpcode::kStateValues, Operator::kPure,
-                                     arguments, 1, "StateValues", arguments);
+  return new (zone()) Operator(                 // --
+      IrOpcode::kStateValues, Operator::kPure,  // opcode
+      "StateValues",                            // name
+      arguments, 0, 0, 1, 0, 0);                // counts
 }
 
 
 const Operator* CommonOperatorBuilder::FrameState(
     FrameStateType type, BailoutId bailout_id,
     OutputFrameStateCombine state_combine, MaybeHandle<JSFunction> jsfunction) {
-  return new (zone()) Operator1<FrameStateCallInfo>(
-      IrOpcode::kFrameState, Operator::kPure, 4, 1, "FrameState",
+  return new (zone()) Operator1<FrameStateCallInfo>(  // --
+      IrOpcode::kFrameState, Operator::kPure,         // opcode
+      "FrameState",                                   // name
+      4, 0, 0, 1, 0, 0,                               // counts
       FrameStateCallInfo(type, bailout_id, state_combine, jsfunction));
 }
 
@@ -224,18 +447,17 @@
 const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
   class CallOperator FINAL : public Operator1<const CallDescriptor*> {
    public:
-    // TODO(titzer): Operator still uses int, whereas CallDescriptor uses
-    // size_t.
     CallOperator(const CallDescriptor* descriptor, const char* mnemonic)
         : Operator1<const CallDescriptor*>(
-              IrOpcode::kCall, descriptor->properties(),
-              static_cast<int>(descriptor->InputCount() +
-                               descriptor->FrameStateCount()),
-              static_cast<int>(descriptor->ReturnCount()), mnemonic,
-              descriptor) {}
+              IrOpcode::kCall, descriptor->properties(), mnemonic,
+              descriptor->InputCount() + descriptor->FrameStateCount(),
+              Operator::ZeroIfPure(descriptor->properties()),
+              Operator::ZeroIfPure(descriptor->properties()),
+              descriptor->ReturnCount(),
+              Operator::ZeroIfPure(descriptor->properties()), 0, descriptor) {}
 
-    virtual OStream& PrintParameter(OStream& os) const OVERRIDE {
-      return os << "[" << *parameter() << "]";
+    void PrintParameter(std::ostream& os) const OVERRIDE {
+      os << "[" << *parameter() << "]";
     }
   };
   return new (zone()) CallOperator(descriptor, "Call");
@@ -243,8 +465,11 @@
 
 
 const Operator* CommonOperatorBuilder::Projection(size_t index) {
-  return new (zone()) Operator1<size_t>(IrOpcode::kProjection, Operator::kPure,
-                                        1, 1, "Projection", index);
+  return new (zone()) Operator1<size_t>(       // --
+      IrOpcode::kProjection, Operator::kPure,  // opcode
+      "Projection",                            // name
+      1, 0, 0, 1, 0, 0,                        // counts
+      index);                                  // parameter
 }
 
 }  // namespace compiler
diff --git a/src/compiler/common-operator.h b/src/compiler/common-operator.h
index a3659ad..af6066b 100644
--- a/src/compiler/common-operator.h
+++ b/src/compiler/common-operator.h
@@ -13,22 +13,105 @@
 
 // Forward declarations.
 class ExternalReference;
-class OStream;
 
 
 namespace compiler {
 
 // Forward declarations.
 class CallDescriptor;
-struct CommonOperatorBuilderImpl;
+struct CommonOperatorGlobalCache;
 class Operator;
 
 
+// Prediction hint for branches.
+enum class BranchHint : uint8_t { kNone, kTrue, kFalse };
+
+inline size_t hash_value(BranchHint hint) { return static_cast<size_t>(hint); }
+
+std::ostream& operator<<(std::ostream&, BranchHint);
+
+BranchHint BranchHintOf(const Operator* const);
+
+
+class SelectParameters FINAL {
+ public:
+  explicit SelectParameters(MachineType type,
+                            BranchHint hint = BranchHint::kNone)
+      : type_(type), hint_(hint) {}
+
+  MachineType type() const { return type_; }
+  BranchHint hint() const { return hint_; }
+
+ private:
+  const MachineType type_;
+  const BranchHint hint_;
+};
+
+bool operator==(SelectParameters const&, SelectParameters const&);
+bool operator!=(SelectParameters const&, SelectParameters const&);
+
+size_t hash_value(SelectParameters const& p);
+
+std::ostream& operator<<(std::ostream&, SelectParameters const& p);
+
+SelectParameters const& SelectParametersOf(const Operator* const);
+
+
 // Flag that describes how to combine the current environment with
 // the output of a node to obtain a framestate for lazy bailout.
-enum OutputFrameStateCombine {
-  kPushOutput,   // Push the output on the expression stack.
-  kIgnoreOutput  // Use the frame state as-is.
+class OutputFrameStateCombine {
+ public:
+  enum Kind {
+    kPushOutput,  // Push the output on the expression stack.
+    kPokeAt       // Poke at the given environment location,
+                  // counting from the top of the stack.
+  };
+
+  static OutputFrameStateCombine Ignore() {
+    return OutputFrameStateCombine(kPushOutput, 0);
+  }
+  static OutputFrameStateCombine Push(size_t count = 1) {
+    return OutputFrameStateCombine(kPushOutput, count);
+  }
+  static OutputFrameStateCombine PokeAt(size_t index) {
+    return OutputFrameStateCombine(kPokeAt, index);
+  }
+
+  Kind kind() const { return kind_; }
+  size_t GetPushCount() const {
+    DCHECK_EQ(kPushOutput, kind());
+    return parameter_;
+  }
+  size_t GetOffsetToPokeAt() const {
+    DCHECK_EQ(kPokeAt, kind());
+    return parameter_;
+  }
+
+  bool IsOutputIgnored() const {
+    return kind_ == kPushOutput && parameter_ == 0;
+  }
+
+  size_t ConsumedOutputCount() const {
+    return kind_ == kPushOutput ? GetPushCount() : 1;
+  }
+
+  bool operator==(OutputFrameStateCombine const& other) const {
+    return kind_ == other.kind_ && parameter_ == other.parameter_;
+  }
+  bool operator!=(OutputFrameStateCombine const& other) const {
+    return !(*this == other);
+  }
+
+  friend size_t hash_value(OutputFrameStateCombine const&);
+  friend std::ostream& operator<<(std::ostream&,
+                                  OutputFrameStateCombine const&);
+
+ private:
+  OutputFrameStateCombine(Kind kind, size_t parameter)
+      : kind_(kind), parameter_(parameter) {}
+
+  Kind const kind_;
+  size_t const parameter_;
 };
 
 
@@ -62,24 +145,32 @@
   MaybeHandle<JSFunction> jsfunction_;
 };
 
+bool operator==(FrameStateCallInfo const&, FrameStateCallInfo const&);
+bool operator!=(FrameStateCallInfo const&, FrameStateCallInfo const&);
+
+size_t hash_value(FrameStateCallInfo const&);
+
+std::ostream& operator<<(std::ostream&, FrameStateCallInfo const&);
+
 
 // Interface for building common operators that can be used at any level of IR,
 // including JavaScript, mid-level, and low-level.
-class CommonOperatorBuilder FINAL {
+class CommonOperatorBuilder FINAL : public ZoneObject {
  public:
   explicit CommonOperatorBuilder(Zone* zone);
 
   const Operator* Dead();
   const Operator* End();
-  const Operator* Branch();
+  const Operator* Branch(BranchHint = BranchHint::kNone);
   const Operator* IfTrue();
   const Operator* IfFalse();
   const Operator* Throw();
+  const Operator* Terminate(int effects);
   const Operator* Return();
 
   const Operator* Start(int num_formal_parameters);
-  const Operator* Merge(int controls);
-  const Operator* Loop(int controls);
+  const Operator* Loop(int control_input_count);
+  const Operator* Merge(int control_input_count);
   const Operator* Parameter(int index);
 
   const Operator* Int32Constant(int32_t);
@@ -88,11 +179,11 @@
   const Operator* Float64Constant(volatile double);
   const Operator* ExternalConstant(const ExternalReference&);
   const Operator* NumberConstant(volatile double);
-  const Operator* HeapConstant(const Unique<Object>&);
+  const Operator* HeapConstant(const Unique<HeapObject>&);
 
+  const Operator* Select(MachineType, BranchHint = BranchHint::kNone);
   const Operator* Phi(MachineType type, int arguments);
   const Operator* EffectPhi(int arguments);
-  const Operator* ControlEffect();
   const Operator* ValueEffect(int arguments);
   const Operator* Finish(int arguments);
   const Operator* StateValues(int arguments);
@@ -106,8 +197,10 @@
  private:
   Zone* zone() const { return zone_; }
 
-  const CommonOperatorBuilderImpl& impl_;
+  const CommonOperatorGlobalCache& cache_;
   Zone* const zone_;
+
+  DISALLOW_COPY_AND_ASSIGN(CommonOperatorBuilder);
 };
 
 }  // namespace compiler
diff --git a/src/compiler/compiler-test-utils.h b/src/compiler/compiler-test-utils.h
deleted file mode 100644
index 437abd6..0000000
--- a/src/compiler/compiler-test-utils.h
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_COMPILER_TEST_UTILS_H_
-#define V8_COMPILER_COMPILER_TEST_UTILS_H_
-
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-// The TARGET_TEST(Case, Name) macro works just like
-// TEST(Case, Name), except that the test is disabled
-// if the platform is not a supported TurboFan target.
-#if V8_TURBOFAN_TARGET
-#define TARGET_TEST(Case, Name) TEST(Case, Name)
-#else
-#define TARGET_TEST(Case, Name) TEST(Case, DISABLED_##Name)
-#endif
-
-
-// The TARGET_TEST_F(Case, Name) macro works just like
-// TEST_F(Case, Name), except that the test is disabled
-// if the platform is not a supported TurboFan target.
-#if V8_TURBOFAN_TARGET
-#define TARGET_TEST_F(Case, Name) TEST_F(Case, Name)
-#else
-#define TARGET_TEST_F(Case, Name) TEST_F(Case, DISABLED_##Name)
-#endif
-
-
-// The TARGET_TEST_P(Case, Name) macro works just like
-// TEST_P(Case, Name), except that the test is disabled
-// if the platform is not a supported TurboFan target.
-#if V8_TURBOFAN_TARGET
-#define TARGET_TEST_P(Case, Name) TEST_P(Case, Name)
-#else
-#define TARGET_TEST_P(Case, Name) TEST_P(Case, DISABLED_##Name)
-#endif
-
-
-// The TARGET_TYPED_TEST(Case, Name) macro works just like
-// TYPED_TEST(Case, Name), except that the test is disabled
-// if the platform is not a supported TurboFan target.
-#if V8_TURBOFAN_TARGET
-#define TARGET_TYPED_TEST(Case, Name) TYPED_TEST(Case, Name)
-#else
-#define TARGET_TYPED_TEST(Case, Name) TYPED_TEST(Case, DISABLED_##Name)
-#endif
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_COMPILER_COMPILER_TEST_UTILS_H_
diff --git a/src/compiler/compiler.gyp b/src/compiler/compiler.gyp
deleted file mode 100644
index ec5ec28..0000000
--- a/src/compiler/compiler.gyp
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright 2014 the V8 project authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
-  'variables': {
-    'v8_code': 1,
-  },
-  'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
-  'targets': [
-    {
-      'target_name': 'compiler-unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../test/test.gyp:run-all-unittests',
-      ],
-      'include_dirs': [
-        '../..',
-      ],
-      'sources': [  ### gcmole(all) ###
-        'change-lowering-unittest.cc',
-        'common-operator-unittest.cc',
-        'compiler-test-utils.h',
-        'graph-reducer-unittest.cc',
-        'graph-unittest.cc',
-        'graph-unittest.h',
-        'instruction-selector-unittest.cc',
-        'instruction-selector-unittest.h',
-        'js-builtin-reducer-unittest.cc',
-        'machine-operator-reducer-unittest.cc',
-        'machine-operator-unittest.cc',
-        'simplified-operator-reducer-unittest.cc',
-        'simplified-operator-unittest.cc',
-        'value-numbering-reducer-unittest.cc',
-      ],
-      'conditions': [
-        ['v8_target_arch=="arm"', {
-          'sources': [  ### gcmole(arch:arm) ###
-            'arm/instruction-selector-arm-unittest.cc',
-          ],
-        }],
-        ['v8_target_arch=="arm64"', {
-          'sources': [  ### gcmole(arch:arm64) ###
-            'arm64/instruction-selector-arm64-unittest.cc',
-          ],
-        }],
-        ['v8_target_arch=="ia32"', {
-          'sources': [  ### gcmole(arch:ia32) ###
-            'ia32/instruction-selector-ia32-unittest.cc',
-          ],
-        }],
-        ['v8_target_arch=="x64"', {
-          'sources': [  ### gcmole(arch:x64) ###
-            'x64/instruction-selector-x64-unittest.cc',
-          ],
-        }],
-      ],
-    },
-  ],
-}
diff --git a/src/compiler/control-builders.cc b/src/compiler/control-builders.cc
index 3b7d05b..8725244 100644
--- a/src/compiler/control-builders.cc
+++ b/src/compiler/control-builders.cc
@@ -9,8 +9,8 @@
 namespace compiler {
 
 
-void IfBuilder::If(Node* condition) {
-  builder_->NewBranch(condition);
+void IfBuilder::If(Node* condition, BranchHint hint) {
+  builder_->NewBranch(condition, hint);
   else_environment_ = environment()->CopyForConditional();
 }
 
@@ -32,9 +32,9 @@
 }
 
 
-void LoopBuilder::BeginLoop() {
+void LoopBuilder::BeginLoop(BitVector* assigned) {
   builder_->NewLoop();
-  loop_environment_ = environment()->CopyForLoop();
+  loop_environment_ = environment()->CopyForLoop(assigned);
   continue_environment_ = environment()->CopyAsUnreachable();
   break_environment_ = environment()->CopyAsUnreachable();
 }
@@ -78,7 +78,6 @@
   body_environment_ = environment()->CopyAsUnreachable();
   label_environment_ = environment()->CopyAsUnreachable();
   break_environment_ = environment()->CopyAsUnreachable();
-  body_environments_.AddBlock(NULL, case_count(), zone());
 }
 
 
diff --git a/src/compiler/control-builders.h b/src/compiler/control-builders.h
index 695282b..11adfdb 100644
--- a/src/compiler/control-builders.h
+++ b/src/compiler/control-builders.h
@@ -14,7 +14,6 @@
 namespace internal {
 namespace compiler {
 
-
 // Base class for all control builders. Also provides a common interface for
 // control builders to handle 'break' and 'continue' statements when they are
 // used to model breakable statements.
@@ -32,7 +31,7 @@
   typedef StructuredGraphBuilder Builder;
   typedef StructuredGraphBuilder::Environment Environment;
 
-  Zone* zone() const { return builder_->zone(); }
+  Zone* zone() const { return builder_->local_zone(); }
   Environment* environment() { return builder_->environment(); }
   void set_environment(Environment* env) { builder_->set_environment(env); }
 
@@ -41,7 +40,7 @@
 
 
 // Tracks control flow for a conditional statement.
-class IfBuilder : public ControlBuilder {
+class IfBuilder FINAL : public ControlBuilder {
  public:
   explicit IfBuilder(StructuredGraphBuilder* builder)
       : ControlBuilder(builder),
@@ -49,7 +48,7 @@
         else_environment_(NULL) {}
 
   // Primitive control commands.
-  void If(Node* condition);
+  void If(Node* condition, BranchHint hint = BranchHint::kNone);
   void Then();
   void Else();
   void End();
@@ -61,7 +60,7 @@
 
 
 // Tracks control flow for an iteration statement.
-class LoopBuilder : public ControlBuilder {
+class LoopBuilder FINAL : public ControlBuilder {
  public:
   explicit LoopBuilder(StructuredGraphBuilder* builder)
       : ControlBuilder(builder),
@@ -70,13 +69,13 @@
         break_environment_(NULL) {}
 
   // Primitive control commands.
-  void BeginLoop();
+  void BeginLoop(BitVector* assigned);
   void EndBody();
   void EndLoop();
 
   // Primitive support for break and continue.
-  virtual void Continue();
-  virtual void Break();
+  void Continue() FINAL;
+  void Break() FINAL;
 
   // Compound control command for conditional break.
   void BreakUnless(Node* condition);
@@ -89,7 +88,7 @@
 
 
 // Tracks control flow for a switch statement.
-class SwitchBuilder : public ControlBuilder {
+class SwitchBuilder FINAL : public ControlBuilder {
  public:
   explicit SwitchBuilder(StructuredGraphBuilder* builder, int case_count)
       : ControlBuilder(builder),
@@ -108,21 +107,21 @@
   void EndSwitch();
 
   // Primitive support for break.
-  virtual void Break();
+  void Break() FINAL;
 
   // The number of cases within a switch is statically known.
-  int case_count() const { return body_environments_.capacity(); }
+  size_t case_count() const { return body_environments_.size(); }
 
  private:
   Environment* body_environment_;   // Environment after last case body.
   Environment* label_environment_;  // Environment for next label condition.
   Environment* break_environment_;  // Environment after the switch exits.
-  ZoneList<Environment*> body_environments_;
+  ZoneVector<Environment*> body_environments_;
 };
 
 
 // Tracks control flow for a block statement.
-class BlockBuilder : public ControlBuilder {
+class BlockBuilder FINAL : public ControlBuilder {
  public:
   explicit BlockBuilder(StructuredGraphBuilder* builder)
       : ControlBuilder(builder), break_environment_(NULL) {}
@@ -132,13 +131,14 @@
   void EndBlock();
 
   // Primitive support for break.
-  virtual void Break();
+  void Break() FINAL;
 
  private:
   Environment* break_environment_;  // Environment after the block exits.
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_CONTROL_BUILDERS_H_
diff --git a/src/compiler/control-equivalence.h b/src/compiler/control-equivalence.h
new file mode 100644
index 0000000..cca087f
--- /dev/null
+++ b/src/compiler/control-equivalence.h
@@ -0,0 +1,361 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_CONTROL_EQUIVALENCE_H_
+#define V8_COMPILER_CONTROL_EQUIVALENCE_H_
+
+#include "src/v8.h"
+
+#include "src/compiler/graph.h"
+#include "src/compiler/node.h"
+#include "src/compiler/node-properties.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Determines control dependence equivalence classes for control nodes. Any two
+// nodes having the same set of control dependences land in one class. These
+// classes can in turn be used to:
+//  - Build a program structure tree (PST) for controls in the graph.
+//  - Determine single-entry single-exit (SESE) regions within the graph.
+//
+// Note that this implementation actually uses cycle equivalence to establish
+// class numbers. Any two nodes are cycle equivalent if they occur in the same
+// set of cycles. It can be shown that control dependence equivalence reduces
+// to undirected cycle equivalence for strongly connected control flow graphs.
+//
+// The algorithm is based on the paper, "The program structure tree: computing
+// control regions in linear time" by Johnson, Pearson & Pingali (PLDI94) which
+// also contains proofs for the aforementioned equivalence. References to line
+// numbers in the algorithm from figure 4 have been added [line:x].
+class ControlEquivalence : public ZoneObject {
+ public:
+  ControlEquivalence(Zone* zone, Graph* graph)
+      : zone_(zone),
+        graph_(graph),
+        dfs_number_(0),
+        class_number_(1),
+        node_data_(graph->NodeCount(), EmptyData(), zone) {}
+
+  // Run the main algorithm starting from the {exit} control node. This causes
+  // the following iterations over control edges of the graph:
+  //  1) A breadth-first backwards traversal to determine the set of nodes that
+  //     participate in the next step. Takes O(E) time and O(N) space.
+  //  2) An undirected depth-first backwards traversal that determines class
+  //     numbers for all participating nodes. Takes O(E) time and O(N) space.
+  void Run(Node* exit) {
+    if (GetClass(exit) != kInvalidClass) return;
+    DetermineParticipation(exit);
+    RunUndirectedDFS(exit);
+  }
+
+  // Retrieves a previously computed class number.
+  size_t ClassOf(Node* node) {
+    DCHECK(GetClass(node) != kInvalidClass);
+    return GetClass(node);
+  }
+
+ private:
+  static const size_t kInvalidClass = static_cast<size_t>(-1);
+  typedef enum { kInputDirection, kUseDirection } DFSDirection;
+
+  struct Bracket {
+    DFSDirection direction;  // Direction in which this bracket was added.
+    size_t recent_class;     // Cached class when bracket was topmost.
+    size_t recent_size;      // Cached set-size when bracket was topmost.
+    Node* from;              // Node that this bracket originates from.
+    Node* to;                // Node that this bracket points to.
+  };
+
+  // The set of brackets for each node during the DFS walk.
+  typedef ZoneLinkedList<Bracket> BracketList;
+
+  struct DFSStackEntry {
+    DFSDirection direction;            // Direction currently used in DFS walk.
+    Node::InputEdges::iterator input;  // Iterator used for "input" direction.
+    Node::UseEdges::iterator use;      // Iterator used for "use" direction.
+    Node* parent_node;                 // Parent node of entry during DFS walk.
+    Node* node;                        // Node that this stack entry belongs to.
+  };
+
+  // The stack is used during the undirected DFS walk.
+  typedef ZoneStack<DFSStackEntry> DFSStack;
+
+  struct NodeData {
+    size_t class_number;  // Equivalence class number assigned to node.
+    size_t dfs_number;    // Pre-order DFS number assigned to node.
+    bool visited;         // Indicates node has already been visited.
+    bool on_stack;        // Indicates node is on DFS stack during walk.
+    bool participates;    // Indicates node participates in DFS walk.
+    BracketList blist;    // List of brackets per node.
+  };
+
+  // The per-node data computed during the DFS walk.
+  typedef ZoneVector<NodeData> Data;
+
+  // Called at pre-visit during DFS walk.
+  void VisitPre(Node* node) {
+    Trace("CEQ: Pre-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
+
+    // Dispense a new pre-order number.
+    SetNumber(node, NewDFSNumber());
+    Trace("  Assigned DFS number is %d\n", GetNumber(node));
+  }
+
+  // Called at mid-visit during DFS walk.
+  void VisitMid(Node* node, DFSDirection direction) {
+    Trace("CEQ: Mid-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
+    BracketList& blist = GetBracketList(node);
+
+    // Remove brackets pointing to this node [line:19].
+    BracketListDelete(blist, node, direction);
+
+    // Potentially introduce artificial dependency from start to end.
+    if (blist.empty()) {
+      DCHECK_EQ(kInputDirection, direction);
+      VisitBackedge(node, graph_->end(), kInputDirection);
+    }
+
+    // Potentially start a new equivalence class [line:37].
+    BracketListTrace(blist);
+    Bracket* recent = &blist.back();
+    if (recent->recent_size != blist.size()) {
+      recent->recent_size = blist.size();
+      recent->recent_class = NewClassNumber();
+    }
+
+    // Assign equivalence class to node.
+    SetClass(node, recent->recent_class);
+    Trace("  Assigned class number is %d\n", GetClass(node));
+  }
+
+  // Called at post-visit during DFS walk.
+  void VisitPost(Node* node, Node* parent_node, DFSDirection direction) {
+    Trace("CEQ: Post-visit of #%d:%s\n", node->id(), node->op()->mnemonic());
+    BracketList& blist = GetBracketList(node);
+
+    // Remove brackets pointing to this node [line:19].
+    BracketListDelete(blist, node, direction);
+
+    // Propagate bracket list up the DFS tree [line:13].
+    if (parent_node != NULL) {
+      BracketList& parent_blist = GetBracketList(parent_node);
+      parent_blist.splice(parent_blist.end(), blist);
+    }
+  }
+
+  // Called when hitting a back edge in the DFS walk.
+  void VisitBackedge(Node* from, Node* to, DFSDirection direction) {
+    Trace("CEQ: Backedge from #%d:%s to #%d:%s\n", from->id(),
+          from->op()->mnemonic(), to->id(), to->op()->mnemonic());
+
+    // Push backedge onto the bracket list [line:25].
+    Bracket bracket = {direction, kInvalidClass, 0, from, to};
+    GetBracketList(from).push_back(bracket);
+  }
+
+  // Performs and undirected DFS walk of the graph. Conceptually all nodes are
+  // expanded, splitting "input" and "use" out into separate nodes. During the
+  // traversal, edges towards the representative nodes are preferred.
+  //
+  //   \ /        - Pre-visit: When N1 is visited in direction D the preferred
+  //    x   N1      edge towards N is taken next, calling VisitPre(N).
+  //    |         - Mid-visit: After all edges out of N2 in direction D have
+  //    |   N       been visited, we switch the direction and start considering
+  //    |           edges out of N1 now, and we call VisitMid(N).
+  //    x   N2    - Post-visit: After all edges out of N1 in direction opposite
+  //   / \          to D have been visited, we pop N and call VisitPost(N).
+  //
+  // This will yield a true spanning tree (without cross or forward edges) and
+  // also discover proper back edges in both directions.
+  void RunUndirectedDFS(Node* exit) {
+    ZoneStack<DFSStackEntry> stack(zone_);
+    DFSPush(stack, exit, NULL, kInputDirection);
+    VisitPre(exit);
+
+    while (!stack.empty()) {  // Undirected depth-first backwards traversal.
+      DFSStackEntry& entry = stack.top();
+      Node* node = entry.node;
+
+      if (entry.direction == kInputDirection) {
+        if (entry.input != node->input_edges().end()) {
+          Edge edge = *entry.input;
+          Node* input = edge.to();
+          ++(entry.input);
+          if (NodeProperties::IsControlEdge(edge) &&
+              NodeProperties::IsControl(input)) {
+            // Visit next control input.
+            if (!GetData(input)->participates) continue;
+            if (GetData(input)->visited) continue;
+            if (GetData(input)->on_stack) {
+              // Found backedge if input is on stack.
+              if (input != entry.parent_node) {
+                VisitBackedge(node, input, kInputDirection);
+              }
+            } else {
+              // Push input onto stack.
+              DFSPush(stack, input, node, kInputDirection);
+              VisitPre(input);
+            }
+          }
+          continue;
+        }
+        if (entry.use != node->use_edges().end()) {
+          // Switch direction to uses.
+          entry.direction = kUseDirection;
+          VisitMid(node, kInputDirection);
+          continue;
+        }
+      }
+
+      if (entry.direction == kUseDirection) {
+        if (entry.use != node->use_edges().end()) {
+          Edge edge = *entry.use;
+          Node* use = edge.from();
+          ++(entry.use);
+          if (NodeProperties::IsControlEdge(edge) &&
+              NodeProperties::IsControl(use)) {
+            // Visit next control use.
+            if (!GetData(use)->participates) continue;
+            if (GetData(use)->visited) continue;
+            if (GetData(use)->on_stack) {
+              // Found backedge if use is on stack.
+              if (use != entry.parent_node) {
+                VisitBackedge(node, use, kUseDirection);
+              }
+            } else {
+              // Push use onto stack.
+              DFSPush(stack, use, node, kUseDirection);
+              VisitPre(use);
+            }
+          }
+          continue;
+        }
+        if (entry.input != node->input_edges().end()) {
+          // Switch direction to inputs.
+          entry.direction = kInputDirection;
+          VisitMid(node, kUseDirection);
+          continue;
+        }
+      }
+
+      // Pop node from stack when done with all inputs and uses.
+      DCHECK(entry.input == node->input_edges().end());
+      DCHECK(entry.use == node->use_edges().end());
+      DFSPop(stack, node);
+      VisitPost(node, entry.parent_node, entry.direction);
+    }
+  }
+
+  void DetermineParticipationEnqueue(ZoneQueue<Node*>& queue, Node* node) {
+    if (!GetData(node)->participates) {
+      GetData(node)->participates = true;
+      queue.push(node);
+    }
+  }
+
+  void DetermineParticipation(Node* exit) {
+    ZoneQueue<Node*> queue(zone_);
+    DetermineParticipationEnqueue(queue, exit);
+    while (!queue.empty()) {  // Breadth-first backwards traversal.
+      Node* node = queue.front();
+      queue.pop();
+      int max = NodeProperties::PastControlIndex(node);
+      for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) {
+        DetermineParticipationEnqueue(queue, node->InputAt(i));
+      }
+    }
+  }
+
+ private:
+  NodeData* GetData(Node* node) { return &node_data_[node->id()]; }
+  int NewClassNumber() { return class_number_++; }
+  int NewDFSNumber() { return dfs_number_++; }
+
+  // Template used to initialize per-node data.
+  NodeData EmptyData() {
+    return {kInvalidClass, 0, false, false, false, BracketList(zone_)};
+  }
+
+  // Accessors for the DFS number stored within the per-node data.
+  size_t GetNumber(Node* node) { return GetData(node)->dfs_number; }
+  void SetNumber(Node* node, size_t number) {
+    GetData(node)->dfs_number = number;
+  }
+
+  // Accessors for the equivalence class stored within the per-node data.
+  size_t GetClass(Node* node) { return GetData(node)->class_number; }
+  void SetClass(Node* node, size_t number) {
+    GetData(node)->class_number = number;
+  }
+
+  // Accessors for the bracket list stored within the per-node data.
+  BracketList& GetBracketList(Node* node) { return GetData(node)->blist; }
+  void SetBracketList(Node* node, BracketList& list) {
+    GetData(node)->blist = list;
+  }
+
+  // Mutates the DFS stack by pushing an entry.
+  void DFSPush(DFSStack& stack, Node* node, Node* from, DFSDirection dir) {
+    DCHECK(GetData(node)->participates);
+    DCHECK(!GetData(node)->visited);
+    GetData(node)->on_stack = true;
+    Node::InputEdges::iterator input = node->input_edges().begin();
+    Node::UseEdges::iterator use = node->use_edges().begin();
+    stack.push({dir, input, use, from, node});
+  }
+
+  // Mutates the DFS stack by popping an entry.
+  void DFSPop(DFSStack& stack, Node* node) {
+    DCHECK_EQ(stack.top().node, node);
+    GetData(node)->on_stack = false;
+    GetData(node)->visited = true;
+    stack.pop();
+  }
+
+  // TODO(mstarzinger): Optimize this to avoid linear search.
+  void BracketListDelete(BracketList& blist, Node* to, DFSDirection direction) {
+    for (BracketList::iterator i = blist.begin(); i != blist.end(); /*nop*/) {
+      if (i->to == to && i->direction != direction) {
+        Trace("  BList erased: {%d->%d}\n", i->from->id(), i->to->id());
+        i = blist.erase(i);
+      } else {
+        ++i;
+      }
+    }
+  }
+
+  void BracketListTrace(BracketList& blist) {
+    if (FLAG_trace_turbo_scheduler) {
+      Trace("  BList: ");
+      for (Bracket bracket : blist) {
+        Trace("{%d->%d} ", bracket.from->id(), bracket.to->id());
+      }
+      Trace("\n");
+    }
+  }
+
+  void Trace(const char* msg, ...) {
+    if (FLAG_trace_turbo_scheduler) {
+      va_list arguments;
+      va_start(arguments, msg);
+      base::OS::VPrint(msg, arguments);
+      va_end(arguments);
+    }
+  }
+
+  Zone* zone_;
+  Graph* graph_;
+  int dfs_number_;    // Generates new DFS pre-order numbers on demand.
+  int class_number_;  // Generates new equivalence class numbers on demand.
+  Data node_data_;    // Per-node data stored as a side-table.
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_CONTROL_EQUIVALENCE_H_
diff --git a/src/compiler/control-reducer.cc b/src/compiler/control-reducer.cc
new file mode 100644
index 0000000..eef8a49
--- /dev/null
+++ b/src/compiler/control-reducer.cc
@@ -0,0 +1,592 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/control-reducer.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+enum VisitState { kUnvisited = 0, kOnStack = 1, kRevisit = 2, kVisited = 3 };
+enum Decision { kFalse, kUnknown, kTrue };
+
+class ReachabilityMarker : public NodeMarker<uint8_t> {
+ public:
+  explicit ReachabilityMarker(Graph* graph) : NodeMarker<uint8_t>(graph, 8) {}
+  bool SetReachableFromEnd(Node* node) {
+    uint8_t before = Get(node);
+    Set(node, before | kFromEnd);
+    return before & kFromEnd;
+  }
+  bool IsReachableFromEnd(Node* node) { return Get(node) & kFromEnd; }
+  bool SetReachableFromStart(Node* node) {
+    uint8_t before = Get(node);
+    Set(node, before | kFromStart);
+    return before & kFromStart;
+  }
+  bool IsReachableFromStart(Node* node) { return Get(node) & kFromStart; }
+  void Push(Node* node) { Set(node, Get(node) | kFwStack); }
+  void Pop(Node* node) { Set(node, Get(node) & ~kFwStack); }
+  bool IsOnStack(Node* node) { return Get(node) & kFwStack; }
+
+ private:
+  enum Bit { kFromEnd = 1, kFromStart = 2, kFwStack = 4 };
+};
+
+
+#define TRACE(x) \
+  if (FLAG_trace_turbo_reduction) PrintF x
+
+class ControlReducerImpl {
+ public:
+  ControlReducerImpl(Zone* zone, JSGraph* jsgraph,
+                     CommonOperatorBuilder* common)
+      : zone_(zone),
+        jsgraph_(jsgraph),
+        common_(common),
+        state_(jsgraph->graph()->NodeCount(), kUnvisited, zone_),
+        stack_(zone_),
+        revisit_(zone_),
+        dead_(NULL) {}
+
+  Zone* zone_;
+  JSGraph* jsgraph_;
+  CommonOperatorBuilder* common_;
+  ZoneVector<VisitState> state_;
+  ZoneDeque<Node*> stack_;
+  ZoneDeque<Node*> revisit_;
+  Node* dead_;
+
+  void Reduce() {
+    Push(graph()->end());
+    do {
+      // Process the node on the top of the stack, potentially pushing more
+      // or popping the node off the stack.
+      ReduceTop();
+      // If the stack becomes empty, revisit any nodes in the revisit queue.
+      // If no nodes in the revisit queue, try removing dead loops.
+      // If no dead loops, then finish.
+    } while (!stack_.empty() || TryRevisit() || RepairAndRemoveLoops());
+  }
+
+  bool TryRevisit() {
+    while (!revisit_.empty()) {
+      Node* n = revisit_.back();
+      revisit_.pop_back();
+      if (state_[n->id()] == kRevisit) {  // state can change while in queue.
+        Push(n);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  // Repair the graph after the possible creation of non-terminating or dead
+  // loops. Removing dead loops can produce more opportunities for reduction.
+  bool RepairAndRemoveLoops() {
+    // TODO(turbofan): we can skip this if the graph has no loops, but
+    // we have to be careful about proper loop detection during reduction.
+
+    // Gather all nodes backwards-reachable from end (through inputs).
+    ReachabilityMarker marked(graph());
+    NodeVector nodes(zone_);
+    AddNodesReachableFromEnd(marked, nodes);
+
+    // Walk forward through control nodes, looking for back edges to nodes
+    // that are not connected to end. Those are non-terminating loops (NTLs).
+    Node* start = graph()->start();
+    marked.Push(start);
+    marked.SetReachableFromStart(start);
+
+    // We use a stack of (Node, UseIter) pairs to avoid O(n^2) traversal.
+    typedef std::pair<Node*, UseIter> FwIter;
+    ZoneVector<FwIter> fw_stack(zone_);
+    fw_stack.push_back(FwIter(start, start->uses().begin()));
+
+    while (!fw_stack.empty()) {
+      Node* node = fw_stack.back().first;
+      TRACE(("ControlFw: #%d:%s\n", node->id(), node->op()->mnemonic()));
+      bool pop = true;
+      while (fw_stack.back().second != node->uses().end()) {
+        Node* succ = *(fw_stack.back().second);
+        if (marked.IsOnStack(succ) && !marked.IsReachableFromEnd(succ)) {
+          // {succ} is on stack and not reachable from end.
+          Node* added = ConnectNTL(succ);
+          nodes.push_back(added);
+          marked.SetReachableFromEnd(added);
+          AddBackwardsReachableNodes(marked, nodes, nodes.size() - 1);
+
+          // Reset the use iterators for the entire stack.
+          for (size_t i = 0; i < fw_stack.size(); i++) {
+            FwIter& iter = fw_stack[i];
+            fw_stack[i] = FwIter(iter.first, iter.first->uses().begin());
+          }
+          pop = false;  // restart traversing successors of this node.
+          break;
+        }
+        if (IrOpcode::IsControlOpcode(succ->opcode()) &&
+            !marked.IsReachableFromStart(succ)) {
+          // {succ} is a control node and not yet reached from start.
+          marked.Push(succ);
+          marked.SetReachableFromStart(succ);
+          fw_stack.push_back(FwIter(succ, succ->uses().begin()));
+          pop = false;  // "recurse" into successor control node.
+          break;
+        }
+        ++fw_stack.back().second;
+      }
+      if (pop) {
+        marked.Pop(node);
+        fw_stack.pop_back();
+      }
+    }
+
+    // Trim references from dead nodes to live nodes first.
+    jsgraph_->GetCachedNodes(&nodes);
+    TrimNodes(marked, nodes);
+
+    // Any control nodes not reachable from start are dead, even loops.
+    for (size_t i = 0; i < nodes.size(); i++) {
+      Node* node = nodes[i];
+      if (IrOpcode::IsControlOpcode(node->opcode()) &&
+          !marked.IsReachableFromStart(node)) {
+        ReplaceNode(node, dead());  // uses will be added to revisit queue.
+      }
+    }
+    return TryRevisit();  // try to push a node onto the stack.
+  }
+
+  // Connect {loop}, the header of a non-terminating loop, to the end node.
+  Node* ConnectNTL(Node* loop) {
+    TRACE(("ConnectNTL: #%d:%s\n", loop->id(), loop->op()->mnemonic()));
+
+    if (loop->opcode() != IrOpcode::kTerminate) {
+      // Insert a {Terminate} node if the loop has effects.
+      ZoneDeque<Node*> effects(zone_);
+      for (Node* const use : loop->uses()) {
+        if (use->opcode() == IrOpcode::kEffectPhi) effects.push_back(use);
+      }
+      int count = static_cast<int>(effects.size());
+      if (count > 0) {
+        Node** inputs = zone_->NewArray<Node*>(1 + count);
+        for (int i = 0; i < count; i++) inputs[i] = effects[i];
+        inputs[count] = loop;
+        loop = graph()->NewNode(common_->Terminate(count), 1 + count, inputs);
+        TRACE(("AddTerminate: #%d:%s[%d]\n", loop->id(), loop->op()->mnemonic(),
+               count));
+      }
+    }
+
+    Node* to_add = loop;
+    Node* end = graph()->end();
+    CHECK_EQ(IrOpcode::kEnd, end->opcode());
+    Node* merge = end->InputAt(0);
+    if (merge == NULL || merge->opcode() == IrOpcode::kDead) {
+      // The end node died; just connect end to {loop}.
+      end->ReplaceInput(0, loop);
+    } else if (merge->opcode() != IrOpcode::kMerge) {
+      // Introduce a final merge node for {end->InputAt(0)} and {loop}.
+      merge = graph()->NewNode(common_->Merge(2), merge, loop);
+      end->ReplaceInput(0, merge);
+      to_add = merge;
+      // Mark the node as visited so that we can revisit later.
+      EnsureStateSize(merge->id());
+      state_[merge->id()] = kVisited;
+    } else {
+      // Append a new input to the final merge at the end.
+      merge->AppendInput(graph()->zone(), loop);
+      merge->set_op(common_->Merge(merge->InputCount()));
+    }
+    return to_add;
+  }
+
+  void AddNodesReachableFromEnd(ReachabilityMarker& marked, NodeVector& nodes) {
+    Node* end = graph()->end();
+    marked.SetReachableFromEnd(end);
+    if (!end->IsDead()) {
+      nodes.push_back(end);
+      AddBackwardsReachableNodes(marked, nodes, nodes.size() - 1);
+    }
+  }
+
+  void AddBackwardsReachableNodes(ReachabilityMarker& marked, NodeVector& nodes,
+                                  size_t cursor) {
+    while (cursor < nodes.size()) {
+      Node* node = nodes[cursor++];
+      for (Node* const input : node->inputs()) {
+        if (!marked.SetReachableFromEnd(input)) {
+          nodes.push_back(input);
+        }
+      }
+    }
+  }
+
+  void Trim() {
+    // Gather all nodes backwards-reachable from end through inputs.
+    ReachabilityMarker marked(graph());
+    NodeVector nodes(zone_);
+    AddNodesReachableFromEnd(marked, nodes);
+
+    // Process cached nodes in the JSGraph too.
+    jsgraph_->GetCachedNodes(&nodes);
+    TrimNodes(marked, nodes);
+  }
+
+  void TrimNodes(ReachabilityMarker& marked, NodeVector& nodes) {
+    // Remove dead->live edges.
+    for (size_t j = 0; j < nodes.size(); j++) {
+      Node* node = nodes[j];
+      for (Edge edge : node->use_edges()) {
+        Node* use = edge.from();
+        if (!marked.IsReachableFromEnd(use)) {
+          TRACE(("DeadLink: #%d:%s(%d) -> #%d:%s\n", use->id(),
+                 use->op()->mnemonic(), edge.index(), node->id(),
+                 node->op()->mnemonic()));
+          edge.UpdateTo(NULL);
+        }
+      }
+    }
+#if DEBUG
+    // Verify that no inputs to live nodes are NULL.
+    for (size_t j = 0; j < nodes.size(); j++) {
+      Node* node = nodes[j];
+      for (Node* const input : node->inputs()) {
+        CHECK_NE(NULL, input);
+      }
+      for (Node* const use : node->uses()) {
+        CHECK(marked.IsReachableFromEnd(use));
+      }
+    }
+#endif
+  }
+
+  // Reduce the node on the top of the stack.
+  // If an input {i} is not yet visited or needs to be revisited, push {i} onto
+  // the stack and return. Otherwise, all inputs are visited, so apply
+  // reductions for {node} and pop it off the stack.
+  void ReduceTop() {
+    size_t height = stack_.size();
+    Node* node = stack_.back();
+
+    if (node->IsDead()) return Pop();  // Node was killed while on stack.
+
+    TRACE(("ControlReduce: #%d:%s\n", node->id(), node->op()->mnemonic()));
+
+    // Recurse on an input if necessary.
+    for (Node* const input : node->inputs()) {
+      if (Recurse(input)) return;
+    }
+
+    // All inputs should be visited or on stack. Apply reductions to node.
+    Node* replacement = ReduceNode(node);
+    if (replacement != node) ReplaceNode(node, replacement);
+
+    // After reducing the node, pop it off the stack.
+    CHECK_EQ(static_cast<int>(height), static_cast<int>(stack_.size()));
+    Pop();
+
+    // If there was a replacement, reduce it after popping {node}.
+    if (replacement != node) Recurse(replacement);
+  }
+
+  void EnsureStateSize(size_t id) {
+    if (id >= state_.size()) {
+      state_.resize((3 * id) / 2, kUnvisited);
+    }
+  }
+
+  // Push a node onto the stack if its state is {kUnvisited} or {kRevisit}.
+  bool Recurse(Node* node) {
+    size_t id = static_cast<size_t>(node->id());
+    EnsureStateSize(id);
+    if (state_[id] != kRevisit && state_[id] != kUnvisited) return false;
+    Push(node);
+    return true;
+  }
+
+  void Push(Node* node) {
+    state_[node->id()] = kOnStack;
+    stack_.push_back(node);
+  }
+
+  void Pop() {
+    int pos = static_cast<int>(stack_.size()) - 1;
+    DCHECK_GE(pos, 0);
+    DCHECK_EQ(kOnStack, state_[stack_[pos]->id()]);
+    state_[stack_[pos]->id()] = kVisited;
+    stack_.pop_back();
+  }
+
+  // Queue a node to be revisited if it has been visited once already.
+  void Revisit(Node* node) {
+    size_t id = static_cast<size_t>(node->id());
+    if (id < state_.size() && state_[id] == kVisited) {
+      TRACE(("  Revisit #%d:%s\n", node->id(), node->op()->mnemonic()));
+      state_[id] = kRevisit;
+      revisit_.push_back(node);
+    }
+  }
+
+  Node* dead() {
+    if (dead_ == NULL) dead_ = graph()->NewNode(common_->Dead());
+    return dead_;
+  }
+
+  //===========================================================================
+  // Reducer implementation: perform reductions on a node.
+  //===========================================================================
+  Node* ReduceNode(Node* node) {
+    if (node->op()->ControlInputCount() == 1) {
+      // If a node has only one control input and it is dead, replace with dead.
+      Node* control = NodeProperties::GetControlInput(node);
+      if (control->opcode() == IrOpcode::kDead) {
+        TRACE(("ControlDead: #%d:%s\n", node->id(), node->op()->mnemonic()));
+        return control;
+      }
+    }
+
+    // Reduce branches, phis, and merges.
+    switch (node->opcode()) {
+      case IrOpcode::kBranch:
+        return ReduceBranch(node);
+      case IrOpcode::kLoop:
+      case IrOpcode::kMerge:
+        return ReduceMerge(node);
+      case IrOpcode::kSelect:
+        return ReduceSelect(node);
+      case IrOpcode::kPhi:
+      case IrOpcode::kEffectPhi:
+        return ReducePhi(node);
+      default:
+        return node;
+    }
+  }
+
+  // Try to statically fold a condition.
+  Decision DecideCondition(Node* cond) {
+    switch (cond->opcode()) {
+      case IrOpcode::kInt32Constant:
+        return Int32Matcher(cond).Is(0) ? kFalse : kTrue;
+      case IrOpcode::kInt64Constant:
+        return Int64Matcher(cond).Is(0) ? kFalse : kTrue;
+      case IrOpcode::kNumberConstant:
+        return NumberMatcher(cond).Is(0) ? kFalse : kTrue;
+      case IrOpcode::kHeapConstant: {
+        Handle<Object> object =
+            HeapObjectMatcher<Object>(cond).Value().handle();
+        if (object->IsTrue()) return kTrue;
+        if (object->IsFalse()) return kFalse;
+        // TODO(turbofan): decide more conditions for heap constants.
+        break;
+      }
+      default:
+        break;
+    }
+    return kUnknown;
+  }
+
+  // Reduce redundant selects.
+  Node* ReduceSelect(Node* const node) {
+    Node* const tvalue = node->InputAt(1);
+    Node* const fvalue = node->InputAt(2);
+    if (tvalue == fvalue) return tvalue;
+    Decision result = DecideCondition(node->InputAt(0));
+    if (result == kTrue) return tvalue;
+    if (result == kFalse) return fvalue;
+    return node;
+  }
+
+  // Reduce redundant phis.
+  Node* ReducePhi(Node* node) {
+    int n = node->InputCount();
+    if (n <= 1) return dead();            // No non-control inputs.
+    if (n == 2) return node->InputAt(0);  // Only one non-control input.
+
+    // Never remove an effect phi from a (potentially non-terminating) loop.
+    // Otherwise, we might end up eliminating effect nodes, such as calls,
+    // before the loop.
+    if (node->opcode() == IrOpcode::kEffectPhi &&
+        NodeProperties::GetControlInput(node)->opcode() == IrOpcode::kLoop) {
+      return node;
+    }
+
+    Node* replacement = NULL;
+    Node::Inputs inputs = node->inputs();
+    for (InputIter it = inputs.begin(); n > 1; --n, ++it) {
+      Node* input = *it;
+      if (input->opcode() == IrOpcode::kDead) continue;  // ignore dead inputs.
+      if (input != node && input != replacement) {       // non-redundant input.
+        if (replacement != NULL) return node;
+        replacement = input;
+      }
+    }
+    return replacement == NULL ? dead() : replacement;
+  }
+
+  // Reduce merges by trimming away dead inputs from the merge and phis.
+  Node* ReduceMerge(Node* node) {
+    // Count the number of live inputs.
+    int live = 0;
+    int index = 0;
+    int live_index = 0;
+    for (Node* const input : node->inputs()) {
+      if (input->opcode() != IrOpcode::kDead) {
+        live++;
+        live_index = index;
+      }
+      index++;
+    }
+
+    if (live > 1 && live == node->InputCount()) return node;  // nothing to do.
+
+    TRACE(("ReduceMerge: #%d:%s (%d live)\n", node->id(),
+           node->op()->mnemonic(), live));
+
+    if (live == 0) return dead();  // no remaining inputs.
+
+    // Gather phis and effect phis to be edited.
+    ZoneVector<Node*> phis(zone_);
+    for (Node* const use : node->uses()) {
+      if (use->opcode() == IrOpcode::kPhi ||
+          use->opcode() == IrOpcode::kEffectPhi) {
+        phis.push_back(use);
+      }
+    }
+
+    if (live == 1) {
+      // All phis are redundant. Replace them with their live input.
+      for (Node* const phi : phis) ReplaceNode(phi, phi->InputAt(live_index));
+      // The merge itself is redundant.
+      return node->InputAt(live_index);
+    }
+
+    // Edit phis in place, removing dead inputs and revisiting them.
+    for (Node* const phi : phis) {
+      TRACE(("  PhiInMerge: #%d:%s (%d live)\n", phi->id(),
+             phi->op()->mnemonic(), live));
+      RemoveDeadInputs(node, phi);
+      Revisit(phi);
+    }
+    // Edit the merge in place, removing dead inputs.
+    RemoveDeadInputs(node, node);
+    return node;
+  }
+
+  // Reduce branches if they have constant inputs.
+  Node* ReduceBranch(Node* node) {
+    Decision result = DecideCondition(node->InputAt(0));
+    if (result == kUnknown) return node;
+
+    TRACE(("BranchReduce: #%d:%s = %s\n", node->id(), node->op()->mnemonic(),
+           (result == kTrue) ? "true" : "false"));
+
+    // Replace IfTrue and IfFalse projections from this branch.
+    Node* control = NodeProperties::GetControlInput(node);
+    for (Edge edge : node->use_edges()) {
+      Node* use = edge.from();
+      if (use->opcode() == IrOpcode::kIfTrue) {
+        TRACE(("  IfTrue: #%d:%s\n", use->id(), use->op()->mnemonic()));
+        edge.UpdateTo(NULL);
+        ReplaceNode(use, (result == kTrue) ? control : dead());
+      } else if (use->opcode() == IrOpcode::kIfFalse) {
+        TRACE(("  IfFalse: #%d:%s\n", use->id(), use->op()->mnemonic()));
+        edge.UpdateTo(NULL);
+        ReplaceNode(use, (result == kTrue) ? dead() : control);
+      }
+    }
+    return control;
+  }
+
+  // Remove inputs to {node} corresponding to the dead inputs to {merge}
+  // and compact the remaining inputs, updating the operator.
+  void RemoveDeadInputs(Node* merge, Node* node) {
+    int pos = 0;
+    for (int i = 0; i < node->InputCount(); i++) {
+      // skip dead inputs.
+      if (i < merge->InputCount() &&
+          merge->InputAt(i)->opcode() == IrOpcode::kDead)
+        continue;
+      // compact live inputs.
+      if (pos != i) node->ReplaceInput(pos, node->InputAt(i));
+      pos++;
+    }
+    node->TrimInputCount(pos);
+    if (node->opcode() == IrOpcode::kPhi) {
+      node->set_op(common_->Phi(OpParameter<MachineType>(node->op()), pos - 1));
+    } else if (node->opcode() == IrOpcode::kEffectPhi) {
+      node->set_op(common_->EffectPhi(pos - 1));
+    } else if (node->opcode() == IrOpcode::kMerge) {
+      node->set_op(common_->Merge(pos));
+    } else if (node->opcode() == IrOpcode::kLoop) {
+      node->set_op(common_->Loop(pos));
+    } else {
+      UNREACHABLE();
+    }
+  }
+
+  // Replace uses of {node} with {replacement} and revisit the uses.
+  void ReplaceNode(Node* node, Node* replacement) {
+    if (node == replacement) return;
+    TRACE(("  Replace: #%d:%s with #%d:%s\n", node->id(),
+           node->op()->mnemonic(), replacement->id(),
+           replacement->op()->mnemonic()));
+    for (Node* const use : node->uses()) {
+      // Don't revisit this node if it refers to itself.
+      if (use != node) Revisit(use);
+    }
+    node->ReplaceUses(replacement);
+    node->Kill();
+  }
+
+  Graph* graph() { return jsgraph_->graph(); }
+};
+
+
+void ControlReducer::ReduceGraph(Zone* zone, JSGraph* jsgraph,
+                                 CommonOperatorBuilder* common) {
+  ControlReducerImpl impl(zone, jsgraph, common);
+  impl.Reduce();
+}
+
+
+void ControlReducer::TrimGraph(Zone* zone, JSGraph* jsgraph) {
+  ControlReducerImpl impl(zone, jsgraph, NULL);
+  impl.Trim();
+}
+
+
+Node* ControlReducer::ReducePhiForTesting(JSGraph* jsgraph,
+                                          CommonOperatorBuilder* common,
+                                          Node* node) {
+  Zone zone(jsgraph->graph()->zone()->isolate());
+  ControlReducerImpl impl(&zone, jsgraph, common);
+  return impl.ReducePhi(node);
+}
+
+
+Node* ControlReducer::ReduceMergeForTesting(JSGraph* jsgraph,
+                                            CommonOperatorBuilder* common,
+                                            Node* node) {
+  Zone zone(jsgraph->graph()->zone()->isolate());
+  ControlReducerImpl impl(&zone, jsgraph, common);
+  return impl.ReduceMerge(node);
+}
+
+
+Node* ControlReducer::ReduceBranchForTesting(JSGraph* jsgraph,
+                                             CommonOperatorBuilder* common,
+                                             Node* node) {
+  Zone zone(jsgraph->graph()->zone()->isolate());
+  ControlReducerImpl impl(&zone, jsgraph, common);
+  return impl.ReduceBranch(node);
+}
+}
+}
+}  // namespace v8::internal::compiler
diff --git a/src/compiler/control-reducer.h b/src/compiler/control-reducer.h
new file mode 100644
index 0000000..e25bb88
--- /dev/null
+++ b/src/compiler/control-reducer.h
@@ -0,0 +1,39 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_CONTROL_REDUCER_H_
+#define V8_COMPILER_CONTROL_REDUCER_H_
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class JSGraph;
+class CommonOperatorBuilder;
+class Node;
+
+class ControlReducer {
+ public:
+  // Perform branch folding and dead code elimination on the graph.
+  static void ReduceGraph(Zone* zone, JSGraph* graph,
+                          CommonOperatorBuilder* builder);
+
+  // Trim nodes in the graph that are not reachable from end.
+  static void TrimGraph(Zone* zone, JSGraph* graph);
+
+  // Testing interface.
+  static Node* ReducePhiForTesting(JSGraph* graph,
+                                   CommonOperatorBuilder* builder, Node* node);
+  static Node* ReduceBranchForTesting(JSGraph* graph,
+                                      CommonOperatorBuilder* builder,
+                                      Node* node);
+  static Node* ReduceMergeForTesting(JSGraph* graph,
+                                     CommonOperatorBuilder* builder,
+                                     Node* node);
+};
+}
+}
+}  // namespace v8::internal::compiler
+
+#endif  // V8_COMPILER_CONTROL_REDUCER_H_
diff --git a/src/compiler/diamond.h b/src/compiler/diamond.h
new file mode 100644
index 0000000..6133cc5
--- /dev/null
+++ b/src/compiler/diamond.h
@@ -0,0 +1,85 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_DIAMOND_H_
+#define V8_COMPILER_DIAMOND_H_
+
+#include "src/v8.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph-inl.h"
+#include "src/compiler/node.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// A helper to make it easier to build diamond-shaped control patterns.
+struct Diamond {
+  Graph* graph;
+  CommonOperatorBuilder* common;
+  Node* branch;
+  Node* if_true;
+  Node* if_false;
+  Node* merge;
+
+  Diamond(Graph* g, CommonOperatorBuilder* b, Node* cond,
+          BranchHint hint = BranchHint::kNone) {
+    graph = g;
+    common = b;
+    branch = graph->NewNode(common->Branch(hint), cond, graph->start());
+    if_true = graph->NewNode(common->IfTrue(), branch);
+    if_false = graph->NewNode(common->IfFalse(), branch);
+    merge = graph->NewNode(common->Merge(2), if_true, if_false);
+  }
+
+  // Place {this} after {that} in control flow order.
+  void Chain(Diamond& that) { branch->ReplaceInput(1, that.merge); }
+
+  // Place {this} after {that} in control flow order.
+  void Chain(Node* that) { branch->ReplaceInput(1, that); }
+
+  // Nest {this} into either the if_true or if_false branch of {that}.
+  void Nest(Diamond& that, bool if_true) {
+    if (if_true) {
+      branch->ReplaceInput(1, that.if_true);
+      that.merge->ReplaceInput(0, merge);
+    } else {
+      branch->ReplaceInput(1, that.if_false);
+      that.merge->ReplaceInput(1, merge);
+    }
+  }
+
+  Node* Phi(MachineType machine_type, Node* tv, Node* fv) {
+    return graph->NewNode(common->Phi(machine_type, 2), tv, fv, merge);
+  }
+
+  Node* EffectPhi(Node* tv, Node* fv) {
+    return graph->NewNode(common->EffectPhi(2), tv, fv, merge);
+  }
+
+  void OverwriteWithPhi(Node* node, MachineType machine_type, Node* tv,
+                        Node* fv) {
+    DCHECK(node->InputCount() >= 3);
+    node->set_op(common->Phi(machine_type, 2));
+    node->ReplaceInput(0, tv);
+    node->ReplaceInput(1, fv);
+    node->ReplaceInput(2, merge);
+    node->TrimInputCount(3);
+  }
+
+  void OverwriteWithEffectPhi(Node* node, Node* te, Node* fe) {
+    DCHECK(node->InputCount() >= 3);
+    node->set_op(common->EffectPhi(2));
+    node->ReplaceInput(0, te);
+    node->ReplaceInput(1, fe);
+    node->ReplaceInput(2, merge);
+    node->TrimInputCount(3);
+  }
+};
+}
+}
+}  // namespace v8::internal::compiler
+
+#endif  // V8_COMPILER_DIAMOND_H_
diff --git a/src/compiler/frame.h b/src/compiler/frame.h
index afcbc37..f99d7bd 100644
--- a/src/compiler/frame.h
+++ b/src/compiler/frame.h
@@ -7,7 +7,7 @@
 
 #include "src/v8.h"
 
-#include "src/data-flow.h"
+#include "src/bit-vector.h"
 
 namespace v8 {
 namespace internal {
@@ -17,7 +17,7 @@
 // registers for a compiled function. Frames are usually populated by the
 // register allocator and are used by Linkage to generate code for the prologue
 // and epilogue to compiled code.
-class Frame {
+class Frame : public ZoneObject {
  public:
   Frame()
       : register_save_area_size_(0),
@@ -69,6 +69,8 @@
   int double_spill_slot_count_;
   BitVector* allocated_registers_;
   BitVector* allocated_double_registers_;
+
+  DISALLOW_COPY_AND_ASSIGN(Frame);
 };
 
 
diff --git a/src/compiler/gap-resolver.h b/src/compiler/gap-resolver.h
index 98aaab2..4f4f4e4 100644
--- a/src/compiler/gap-resolver.h
+++ b/src/compiler/gap-resolver.h
@@ -39,8 +39,9 @@
   // Assembler used to emit moves and save registers.
   Assembler* const assembler_;
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_GAP_RESOLVER_H_
diff --git a/src/compiler/generic-algorithm-inl.h b/src/compiler/generic-algorithm-inl.h
deleted file mode 100644
index a25131f..0000000
--- a/src/compiler/generic-algorithm-inl.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_GENERIC_ALGORITHM_INL_H_
-#define V8_COMPILER_GENERIC_ALGORITHM_INL_H_
-
-#include <vector>
-
-#include "src/compiler/generic-algorithm.h"
-#include "src/compiler/generic-graph.h"
-#include "src/compiler/generic-node.h"
-#include "src/compiler/generic-node-inl.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-template <class N>
-class NodeInputIterationTraits {
- public:
-  typedef N Node;
-  typedef typename N::Inputs::iterator Iterator;
-
-  static Iterator begin(Node* node) { return node->inputs().begin(); }
-  static Iterator end(Node* node) { return node->inputs().end(); }
-  static int max_id(GenericGraphBase* graph) { return graph->NodeCount(); }
-  static Node* to(Iterator iterator) { return *iterator; }
-  static Node* from(Iterator iterator) { return iterator.edge().from(); }
-};
-
-template <class N>
-class NodeUseIterationTraits {
- public:
-  typedef N Node;
-  typedef typename N::Uses::iterator Iterator;
-
-  static Iterator begin(Node* node) { return node->uses().begin(); }
-  static Iterator end(Node* node) { return node->uses().end(); }
-  static int max_id(GenericGraphBase* graph) { return graph->NodeCount(); }
-  static Node* to(Iterator iterator) { return *iterator; }
-  static Node* from(Iterator iterator) { return iterator.edge().to(); }
-};
-}
-}
-}  // namespace v8::internal::compiler
-
-#endif  // V8_COMPILER_GENERIC_ALGORITHM_INL_H_
diff --git a/src/compiler/generic-algorithm.h b/src/compiler/generic-algorithm.h
index cd4984f..391757e 100644
--- a/src/compiler/generic-algorithm.h
+++ b/src/compiler/generic-algorithm.h
@@ -6,69 +6,60 @@
 #define V8_COMPILER_GENERIC_ALGORITHM_H_
 
 #include <stack>
+#include <vector>
 
-#include "src/compiler/generic-graph.h"
-#include "src/compiler/generic-node.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/node.h"
 #include "src/zone-containers.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+class Graph;
+class Node;
+
 // GenericGraphVisit allows visitation of graphs of nodes and edges in pre- and
 // post-order. Visitation uses an explicitly allocated stack rather than the
-// execution stack to avoid stack overflow. Although GenericGraphVisit is
-// primarily intended to traverse networks of nodes through their
-// dependencies and uses, it also can be used to visit any graph-like network
-// by specifying custom traits.
+// execution stack to avoid stack overflow.
 class GenericGraphVisit {
  public:
-  enum Control {
-    CONTINUE = 0x0,  // Continue depth-first normally
-    SKIP = 0x1,      // Skip this node and its successors
-    REENTER = 0x2,   // Allow reentering this node
-    DEFER = SKIP | REENTER
-  };
-
   // struct Visitor {
-  //   Control Pre(Traits::Node* current);
-  //   Control Post(Traits::Node* current);
-  //   void PreEdge(Traits::Node* from, int index, Traits::Node* to);
-  //   void PostEdge(Traits::Node* from, int index, Traits::Node* to);
+  //   void Pre(Node* current);
+  //   void Post(Node* current);
+  //   void PreEdge(Node* from, int index, Node* to);
+  //   void PostEdge(Node* from, int index, Node* to);
   // }
-  template <class Visitor, class Traits, class RootIterator>
-  static void Visit(GenericGraphBase* graph, Zone* zone,
-                    RootIterator root_begin, RootIterator root_end,
-                    Visitor* visitor) {
-    typedef typename Traits::Node Node;
-    typedef typename Traits::Iterator Iterator;
+  template <class Visitor>
+  static void Visit(Graph* graph, Zone* zone, Node** root_begin,
+                    Node** root_end, Visitor* visitor) {
+    typedef typename Node::InputEdges::iterator Iterator;
     typedef std::pair<Iterator, Iterator> NodeState;
     typedef std::stack<NodeState, ZoneDeque<NodeState> > NodeStateStack;
     NodeStateStack stack((ZoneDeque<NodeState>(zone)));
-    BoolVector visited(Traits::max_id(graph), false, zone);
+    BoolVector visited(graph->NodeCount(), false, zone);
     Node* current = *root_begin;
     while (true) {
       DCHECK(current != NULL);
       const int id = current->id();
       DCHECK(id >= 0);
-      DCHECK(id < Traits::max_id(graph));  // Must be a valid id.
+      DCHECK(id < graph->NodeCount());  // Must be a valid id.
       bool visit = !GetVisited(&visited, id);
       if (visit) {
-        Control control = visitor->Pre(current);
-        visit = !IsSkip(control);
-        if (!IsReenter(control)) SetVisited(&visited, id, true);
+        visitor->Pre(current);
+        SetVisited(&visited, id);
       }
-      Iterator begin(visit ? Traits::begin(current) : Traits::end(current));
-      Iterator end(Traits::end(current));
+      Iterator begin(visit ? current->input_edges().begin()
+                           : current->input_edges().end());
+      Iterator end(current->input_edges().end());
       stack.push(NodeState(begin, end));
       Node* post_order_node = current;
       while (true) {
         NodeState top = stack.top();
         if (top.first == top.second) {
           if (visit) {
-            Control control = visitor->Post(post_order_node);
-            DCHECK(!IsSkip(control));
-            SetVisited(&visited, post_order_node->id(), !IsReenter(control));
+            visitor->Post(post_order_node);
+            SetVisited(&visited, post_order_node->id());
           }
           stack.pop();
           if (stack.empty()) {
@@ -76,48 +67,42 @@
             current = *root_begin;
             break;
           }
-          post_order_node = Traits::from(stack.top().first);
+          post_order_node = (*stack.top().first).from();
           visit = true;
         } else {
-          visitor->PreEdge(Traits::from(top.first), top.first.edge().index(),
-                           Traits::to(top.first));
-          current = Traits::to(top.first);
+          visitor->PreEdge((*top.first).from(), (*top.first).index(),
+                           (*top.first).to());
+          current = (*top.first).to();
           if (!GetVisited(&visited, current->id())) break;
         }
         top = stack.top();
-        visitor->PostEdge(Traits::from(top.first), top.first.edge().index(),
-                          Traits::to(top.first));
+        visitor->PostEdge((*top.first).from(), (*top.first).index(),
+                          (*top.first).to());
         ++stack.top().first;
       }
     }
   }
 
-  template <class Visitor, class Traits>
-  static void Visit(GenericGraphBase* graph, Zone* zone,
-                    typename Traits::Node* current, Visitor* visitor) {
-    typename Traits::Node* array[] = {current};
-    Visit<Visitor, Traits>(graph, zone, &array[0], &array[1], visitor);
+  template <class Visitor>
+  static void Visit(Graph* graph, Zone* zone, Node* current, Visitor* visitor) {
+    Node* array[] = {current};
+    Visit<Visitor>(graph, zone, &array[0], &array[1], visitor);
   }
 
-  template <class B, class S>
   struct NullNodeVisitor {
-    Control Pre(GenericNode<B, S>* node) { return CONTINUE; }
-    Control Post(GenericNode<B, S>* node) { return CONTINUE; }
-    void PreEdge(GenericNode<B, S>* from, int index, GenericNode<B, S>* to) {}
-    void PostEdge(GenericNode<B, S>* from, int index, GenericNode<B, S>* to) {}
+    void Pre(Node* node) {}
+    void Post(Node* node) {}
+    void PreEdge(Node* from, int index, Node* to) {}
+    void PostEdge(Node* from, int index, Node* to) {}
   };
 
  private:
-  static bool IsSkip(Control c) { return c & SKIP; }
-  static bool IsReenter(Control c) { return c & REENTER; }
-
-  // TODO(turbofan): resizing could be optionally templatized away.
-  static void SetVisited(BoolVector* visited, int id, bool value) {
+  static void SetVisited(BoolVector* visited, int id) {
     if (id >= static_cast<int>(visited->size())) {
       // Resize and set all values to unvisited.
       visited->resize((3 * id) / 2, false);
     }
-    visited->at(id) = value;
+    visited->at(id) = true;
   }
 
   static bool GetVisited(BoolVector* visited, int id) {
@@ -125,8 +110,11 @@
     return visited->at(id);
   }
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+typedef GenericGraphVisit::NullNodeVisitor NullNodeVisitor;
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_GENERIC_ALGORITHM_H_
diff --git a/src/compiler/generic-graph.h b/src/compiler/generic-graph.h
deleted file mode 100644
index a555456..0000000
--- a/src/compiler/generic-graph.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_GENERIC_GRAPH_H_
-#define V8_COMPILER_GENERIC_GRAPH_H_
-
-#include "src/compiler/generic-node.h"
-
-namespace v8 {
-namespace internal {
-
-class Zone;
-
-namespace compiler {
-
-class GenericGraphBase : public ZoneObject {
- public:
-  explicit GenericGraphBase(Zone* zone) : zone_(zone), next_node_id_(0) {}
-
-  Zone* zone() const { return zone_; }
-
-  NodeId NextNodeID() { return next_node_id_++; }
-  NodeId NodeCount() const { return next_node_id_; }
-
- private:
-  Zone* zone_;
-  NodeId next_node_id_;
-};
-
-template <class V>
-class GenericGraph : public GenericGraphBase {
- public:
-  explicit GenericGraph(Zone* zone)
-      : GenericGraphBase(zone), start_(NULL), end_(NULL) {}
-
-  V* start() { return start_; }
-  V* end() { return end_; }
-
-  void SetStart(V* start) { start_ = start; }
-  void SetEnd(V* end) { end_ = end; }
-
- private:
-  V* start_;
-  V* end_;
-
-  DISALLOW_COPY_AND_ASSIGN(GenericGraph);
-};
-}
-}
-}  // namespace v8::internal::compiler
-
-#endif  // V8_COMPILER_GENERIC_GRAPH_H_
diff --git a/src/compiler/generic-node-inl.h b/src/compiler/generic-node-inl.h
deleted file mode 100644
index c2dc24e..0000000
--- a/src/compiler/generic-node-inl.h
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_GENERIC_NODE_INL_H_
-#define V8_COMPILER_GENERIC_NODE_INL_H_
-
-#include "src/v8.h"
-
-#include "src/compiler/generic-graph.h"
-#include "src/compiler/generic-node.h"
-#include "src/zone.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-template <class B, class S>
-GenericNode<B, S>::GenericNode(GenericGraphBase* graph, int input_count)
-    : BaseClass(graph->zone()),
-      input_count_(input_count),
-      has_appendable_inputs_(false),
-      use_count_(0),
-      first_use_(NULL),
-      last_use_(NULL) {
-  inputs_.static_ = reinterpret_cast<Input*>(this + 1), AssignUniqueID(graph);
-}
-
-template <class B, class S>
-inline void GenericNode<B, S>::AssignUniqueID(GenericGraphBase* graph) {
-  id_ = graph->NextNodeID();
-}
-
-template <class B, class S>
-inline typename GenericNode<B, S>::Inputs::iterator
-GenericNode<B, S>::Inputs::begin() {
-  return typename GenericNode<B, S>::Inputs::iterator(this->node_, 0);
-}
-
-template <class B, class S>
-inline typename GenericNode<B, S>::Inputs::iterator
-GenericNode<B, S>::Inputs::end() {
-  return typename GenericNode<B, S>::Inputs::iterator(
-      this->node_, this->node_->InputCount());
-}
-
-template <class B, class S>
-inline typename GenericNode<B, S>::Uses::iterator
-GenericNode<B, S>::Uses::begin() {
-  return typename GenericNode<B, S>::Uses::iterator(this->node_);
-}
-
-template <class B, class S>
-inline typename GenericNode<B, S>::Uses::iterator
-GenericNode<B, S>::Uses::end() {
-  return typename GenericNode<B, S>::Uses::iterator();
-}
-
-template <class B, class S>
-void GenericNode<B, S>::ReplaceUses(GenericNode* replace_to) {
-  for (Use* use = first_use_; use != NULL; use = use->next) {
-    use->from->GetInputRecordPtr(use->input_index)->to = replace_to;
-  }
-  if (replace_to->last_use_ == NULL) {
-    DCHECK_EQ(NULL, replace_to->first_use_);
-    replace_to->first_use_ = first_use_;
-    replace_to->last_use_ = last_use_;
-  } else if (first_use_ != NULL) {
-    DCHECK_NE(NULL, replace_to->first_use_);
-    replace_to->last_use_->next = first_use_;
-    first_use_->prev = replace_to->last_use_;
-    replace_to->last_use_ = last_use_;
-  }
-  replace_to->use_count_ += use_count_;
-  use_count_ = 0;
-  first_use_ = NULL;
-  last_use_ = NULL;
-}
-
-template <class B, class S>
-template <class UnaryPredicate>
-void GenericNode<B, S>::ReplaceUsesIf(UnaryPredicate pred,
-                                      GenericNode* replace_to) {
-  for (Use* use = first_use_; use != NULL;) {
-    Use* next = use->next;
-    if (pred(static_cast<S*>(use->from))) {
-      RemoveUse(use);
-      replace_to->AppendUse(use);
-      use->from->GetInputRecordPtr(use->input_index)->to = replace_to;
-    }
-    use = next;
-  }
-}
-
-template <class B, class S>
-void GenericNode<B, S>::RemoveAllInputs() {
-  for (typename Inputs::iterator iter(inputs().begin()); iter != inputs().end();
-       ++iter) {
-    iter.GetInput()->Update(NULL);
-  }
-}
-
-template <class B, class S>
-void GenericNode<B, S>::TrimInputCount(int new_input_count) {
-  if (new_input_count == input_count_) return;  // Nothing to do.
-
-  DCHECK(new_input_count < input_count_);
-
-  // Update inline inputs.
-  for (int i = new_input_count; i < input_count_; i++) {
-    typename GenericNode<B, S>::Input* input = GetInputRecordPtr(i);
-    input->Update(NULL);
-  }
-  input_count_ = new_input_count;
-}
-
-template <class B, class S>
-void GenericNode<B, S>::ReplaceInput(int index, GenericNode<B, S>* new_to) {
-  Input* input = GetInputRecordPtr(index);
-  input->Update(new_to);
-}
-
-template <class B, class S>
-void GenericNode<B, S>::Input::Update(GenericNode<B, S>* new_to) {
-  GenericNode* old_to = this->to;
-  if (new_to == old_to) return;  // Nothing to do.
-  // Snip out the use from where it used to be
-  if (old_to != NULL) {
-    old_to->RemoveUse(use);
-  }
-  to = new_to;
-  // And put it into the new node's use list.
-  if (new_to != NULL) {
-    new_to->AppendUse(use);
-  } else {
-    use->next = NULL;
-    use->prev = NULL;
-  }
-}
-
-template <class B, class S>
-void GenericNode<B, S>::EnsureAppendableInputs(Zone* zone) {
-  if (!has_appendable_inputs_) {
-    void* deque_buffer = zone->New(sizeof(InputDeque));
-    InputDeque* deque = new (deque_buffer) InputDeque(zone);
-    for (int i = 0; i < input_count_; ++i) {
-      deque->push_back(inputs_.static_[i]);
-    }
-    inputs_.appendable_ = deque;
-    has_appendable_inputs_ = true;
-  }
-}
-
-template <class B, class S>
-void GenericNode<B, S>::AppendInput(Zone* zone, GenericNode<B, S>* to_append) {
-  EnsureAppendableInputs(zone);
-  Use* new_use = new (zone) Use;
-  Input new_input;
-  new_input.to = to_append;
-  new_input.use = new_use;
-  inputs_.appendable_->push_back(new_input);
-  new_use->input_index = input_count_;
-  new_use->from = this;
-  to_append->AppendUse(new_use);
-  input_count_++;
-}
-
-template <class B, class S>
-void GenericNode<B, S>::InsertInput(Zone* zone, int index,
-                                    GenericNode<B, S>* to_insert) {
-  DCHECK(index >= 0 && index < InputCount());
-  // TODO(turbofan): Optimize this implementation!
-  AppendInput(zone, InputAt(InputCount() - 1));
-  for (int i = InputCount() - 1; i > index; --i) {
-    ReplaceInput(i, InputAt(i - 1));
-  }
-  ReplaceInput(index, to_insert);
-}
-
-template <class B, class S>
-void GenericNode<B, S>::RemoveInput(int index) {
-  DCHECK(index >= 0 && index < InputCount());
-  // TODO(turbofan): Optimize this implementation!
-  for (; index < InputCount() - 1; ++index) {
-    ReplaceInput(index, InputAt(index + 1));
-  }
-  TrimInputCount(InputCount() - 1);
-}
-
-template <class B, class S>
-void GenericNode<B, S>::AppendUse(Use* use) {
-  use->next = NULL;
-  use->prev = last_use_;
-  if (last_use_ == NULL) {
-    first_use_ = use;
-  } else {
-    last_use_->next = use;
-  }
-  last_use_ = use;
-  ++use_count_;
-}
-
-template <class B, class S>
-void GenericNode<B, S>::RemoveUse(Use* use) {
-  if (last_use_ == use) {
-    last_use_ = use->prev;
-  }
-  if (use->prev != NULL) {
-    use->prev->next = use->next;
-  } else {
-    first_use_ = use->next;
-  }
-  if (use->next != NULL) {
-    use->next->prev = use->prev;
-  }
-  --use_count_;
-}
-
-template <class B, class S>
-inline bool GenericNode<B, S>::OwnedBy(GenericNode* owner) const {
-  return first_use_ != NULL && first_use_->from == owner &&
-         first_use_->next == NULL;
-}
-
-template <class B, class S>
-S* GenericNode<B, S>::New(GenericGraphBase* graph, int input_count,
-                          S** inputs) {
-  size_t node_size = sizeof(GenericNode);
-  size_t inputs_size = input_count * sizeof(Input);
-  size_t uses_size = input_count * sizeof(Use);
-  int size = static_cast<int>(node_size + inputs_size + uses_size);
-  Zone* zone = graph->zone();
-  void* buffer = zone->New(size);
-  S* result = new (buffer) S(graph, input_count);
-  Input* input =
-      reinterpret_cast<Input*>(reinterpret_cast<char*>(buffer) + node_size);
-  Use* use =
-      reinterpret_cast<Use*>(reinterpret_cast<char*>(input) + inputs_size);
-
-  for (int current = 0; current < input_count; ++current) {
-    GenericNode* to = *inputs++;
-    input->to = to;
-    input->use = use;
-    use->input_index = current;
-    use->from = result;
-    to->AppendUse(use);
-    ++use;
-    ++input;
-  }
-  return result;
-}
-}
-}
-}  // namespace v8::internal::compiler
-
-#endif  // V8_COMPILER_GENERIC_NODE_INL_H_
diff --git a/src/compiler/generic-node.h b/src/compiler/generic-node.h
deleted file mode 100644
index 3dc324d..0000000
--- a/src/compiler/generic-node.h
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_GENERIC_NODE_H_
-#define V8_COMPILER_GENERIC_NODE_H_
-
-#include "src/v8.h"
-
-#include "src/zone-containers.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class GenericGraphBase;
-
-typedef int NodeId;
-
-// A GenericNode<> is the basic primitive of graphs. GenericNode's are
-// chained together by input/use chains but by default otherwise contain only an
-// identifying number which specific applications of graphs and nodes can use
-// to index auxiliary out-of-line data, especially transient data.
-// Specializations of the templatized GenericNode<> class must provide a base
-// class B that contains all of the members to be made available in each
-// specialized Node instance. GenericNode uses a mixin template pattern to
-// ensure that common accessors and methods expect the derived class S type
-// rather than the GenericNode<B, S> type.
-template <class B, class S>
-class GenericNode : public B {
- public:
-  typedef B BaseClass;
-  typedef S DerivedClass;
-
-  inline NodeId id() const { return id_; }
-
-  int InputCount() const { return input_count_; }
-  S* InputAt(int index) const {
-    return static_cast<S*>(GetInputRecordPtr(index)->to);
-  }
-  inline void ReplaceInput(int index, GenericNode* new_input);
-  inline void AppendInput(Zone* zone, GenericNode* new_input);
-  inline void InsertInput(Zone* zone, int index, GenericNode* new_input);
-  inline void RemoveInput(int index);
-
-  int UseCount() { return use_count_; }
-  S* UseAt(int index) {
-    DCHECK(index < use_count_);
-    Use* current = first_use_;
-    while (index-- != 0) {
-      current = current->next;
-    }
-    return static_cast<S*>(current->from);
-  }
-  inline void ReplaceUses(GenericNode* replace_to);
-  template <class UnaryPredicate>
-  inline void ReplaceUsesIf(UnaryPredicate pred, GenericNode* replace_to);
-  inline void RemoveAllInputs();
-
-  inline void TrimInputCount(int input_count);
-
-  class Inputs {
-   public:
-    class iterator;
-    iterator begin();
-    iterator end();
-
-    explicit Inputs(GenericNode* node) : node_(node) {}
-
-   private:
-    GenericNode* node_;
-  };
-
-  Inputs inputs() { return Inputs(this); }
-
-  class Uses {
-   public:
-    class iterator;
-    iterator begin();
-    iterator end();
-    bool empty() { return begin() == end(); }
-
-    explicit Uses(GenericNode* node) : node_(node) {}
-
-   private:
-    GenericNode* node_;
-  };
-
-  Uses uses() { return Uses(this); }
-
-  class Edge;
-
-  bool OwnedBy(GenericNode* owner) const;
-
-  static S* New(GenericGraphBase* graph, int input_count, S** inputs);
-
- protected:
-  friend class GenericGraphBase;
-
-  class Use : public ZoneObject {
-   public:
-    GenericNode* from;
-    Use* next;
-    Use* prev;
-    int input_index;
-  };
-
-  class Input {
-   public:
-    GenericNode* to;
-    Use* use;
-
-    void Update(GenericNode* new_to);
-  };
-
-  void EnsureAppendableInputs(Zone* zone);
-
-  Input* GetInputRecordPtr(int index) const {
-    if (has_appendable_inputs_) {
-      return &((*inputs_.appendable_)[index]);
-    } else {
-      return inputs_.static_ + index;
-    }
-  }
-
-  inline void AppendUse(Use* use);
-  inline void RemoveUse(Use* use);
-
-  void* operator new(size_t, void* location) { return location; }
-
-  GenericNode(GenericGraphBase* graph, int input_count);
-
- private:
-  void AssignUniqueID(GenericGraphBase* graph);
-
-  typedef ZoneDeque<Input> InputDeque;
-
-  NodeId id_;
-  int input_count_ : 31;
-  bool has_appendable_inputs_ : 1;
-  union {
-    // When a node is initially allocated, it uses a static buffer to hold its
-    // inputs under the assumption that the number of outputs will not increase.
-    // When the first input is appended, the static buffer is converted into a
-    // deque to allow for space-efficient growing.
-    Input* static_;
-    InputDeque* appendable_;
-  } inputs_;
-  int use_count_;
-  Use* first_use_;
-  Use* last_use_;
-
-  DISALLOW_COPY_AND_ASSIGN(GenericNode);
-};
-
-// An encapsulation for information associated with a single use of node as a
-// input from another node, allowing access to both the defining node and
-// the ndoe having the input.
-template <class B, class S>
-class GenericNode<B, S>::Edge {
- public:
-  S* from() const { return static_cast<S*>(input_->use->from); }
-  S* to() const { return static_cast<S*>(input_->to); }
-  int index() const {
-    int index = input_->use->input_index;
-    DCHECK(index < input_->use->from->input_count_);
-    return index;
-  }
-
- private:
-  friend class GenericNode<B, S>::Uses::iterator;
-  friend class GenericNode<B, S>::Inputs::iterator;
-
-  explicit Edge(typename GenericNode<B, S>::Input* input) : input_(input) {}
-
-  typename GenericNode<B, S>::Input* input_;
-};
-
-// A forward iterator to visit the nodes which are depended upon by a node
-// in the order of input.
-template <class B, class S>
-class GenericNode<B, S>::Inputs::iterator {
- public:
-  iterator(const typename GenericNode<B, S>::Inputs::iterator& other)  // NOLINT
-      : node_(other.node_),
-        index_(other.index_) {}
-
-  S* operator*() { return static_cast<S*>(GetInput()->to); }
-  typename GenericNode<B, S>::Edge edge() {
-    return typename GenericNode::Edge(GetInput());
-  }
-  bool operator==(const iterator& other) const {
-    return other.index_ == index_ && other.node_ == node_;
-  }
-  bool operator!=(const iterator& other) const { return !(other == *this); }
-  iterator& operator++() {
-    DCHECK(node_ != NULL);
-    DCHECK(index_ < node_->input_count_);
-    ++index_;
-    return *this;
-  }
-  iterator& UpdateToAndIncrement(GenericNode<B, S>* new_to) {
-    typename GenericNode<B, S>::Input* input = GetInput();
-    input->Update(new_to);
-    index_++;
-    return *this;
-  }
-  int index() { return index_; }
-
- private:
-  friend class GenericNode;
-
-  explicit iterator(GenericNode* node, int index)
-      : node_(node), index_(index) {}
-
-  Input* GetInput() const { return node_->GetInputRecordPtr(index_); }
-
-  GenericNode* node_;
-  int index_;
-};
-
-// A forward iterator to visit the uses of a node. The uses are returned in
-// the order in which they were added as inputs.
-template <class B, class S>
-class GenericNode<B, S>::Uses::iterator {
- public:
-  iterator(const typename GenericNode<B, S>::Uses::iterator& other)  // NOLINT
-      : current_(other.current_),
-        index_(other.index_) {}
-
-  S* operator*() { return static_cast<S*>(current_->from); }
-  typename GenericNode<B, S>::Edge edge() {
-    return typename GenericNode::Edge(CurrentInput());
-  }
-
-  bool operator==(const iterator& other) { return other.current_ == current_; }
-  bool operator!=(const iterator& other) { return other.current_ != current_; }
-  iterator& operator++() {
-    DCHECK(current_ != NULL);
-    index_++;
-    current_ = current_->next;
-    return *this;
-  }
-  iterator& UpdateToAndIncrement(GenericNode<B, S>* new_to) {
-    DCHECK(current_ != NULL);
-    index_++;
-    typename GenericNode<B, S>::Input* input = CurrentInput();
-    current_ = current_->next;
-    input->Update(new_to);
-    return *this;
-  }
-  int index() const { return index_; }
-
- private:
-  friend class GenericNode<B, S>::Uses;
-
-  iterator() : current_(NULL), index_(0) {}
-  explicit iterator(GenericNode<B, S>* node)
-      : current_(node->first_use_), index_(0) {}
-
-  Input* CurrentInput() const {
-    return current_->from->GetInputRecordPtr(current_->input_index);
-  }
-
-  typename GenericNode<B, S>::Use* current_;
-  int index_;
-};
-}
-}
-}  // namespace v8::internal::compiler
-
-#endif  // V8_COMPILER_GENERIC_NODE_H_
diff --git a/src/compiler/graph-builder.cc b/src/compiler/graph-builder.cc
index 8992881..6321aaa 100644
--- a/src/compiler/graph-builder.cc
+++ b/src/compiler/graph-builder.cc
@@ -4,53 +4,65 @@
 
 #include "src/compiler/graph-builder.h"
 
+#include "src/bit-vector.h"
 #include "src/compiler.h"
-#include "src/compiler/generic-graph.h"
-#include "src/compiler/generic-node.h"
-#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/graph-visualizer.h"
+#include "src/compiler/node.h"
 #include "src/compiler/node-properties.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/compiler/operator-properties.h"
-#include "src/compiler/operator-properties-inl.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
 
-StructuredGraphBuilder::StructuredGraphBuilder(Graph* graph,
+StructuredGraphBuilder::StructuredGraphBuilder(Zone* local_zone, Graph* graph,
                                                CommonOperatorBuilder* common)
     : GraphBuilder(graph),
       common_(common),
       environment_(NULL),
+      local_zone_(local_zone),
+      input_buffer_size_(0),
+      input_buffer_(NULL),
       current_context_(NULL),
-      exit_control_(NULL) {}
+      exit_control_(NULL) {
+  EnsureInputBufferSize(kInputBufferSizeIncrement);
+}
+
+
+Node** StructuredGraphBuilder::EnsureInputBufferSize(int size) {
+  if (size > input_buffer_size_) {
+    size += kInputBufferSizeIncrement;
+    input_buffer_ = local_zone()->NewArray<Node*>(size);
+  }
+  return input_buffer_;
+}
 
 
 Node* StructuredGraphBuilder::MakeNode(const Operator* op,
                                        int value_input_count,
-                                       Node** value_inputs) {
-  DCHECK(op->InputCount() == value_input_count);
+                                       Node** value_inputs, bool incomplete) {
+  DCHECK(op->ValueInputCount() == value_input_count);
 
   bool has_context = OperatorProperties::HasContextInput(op);
   bool has_framestate = OperatorProperties::HasFrameStateInput(op);
-  bool has_control = OperatorProperties::GetControlInputCount(op) == 1;
-  bool has_effect = OperatorProperties::GetEffectInputCount(op) == 1;
+  bool has_control = op->ControlInputCount() == 1;
+  bool has_effect = op->EffectInputCount() == 1;
 
-  DCHECK(OperatorProperties::GetControlInputCount(op) < 2);
-  DCHECK(OperatorProperties::GetEffectInputCount(op) < 2);
+  DCHECK(op->ControlInputCount() < 2);
+  DCHECK(op->EffectInputCount() < 2);
 
   Node* result = NULL;
   if (!has_context && !has_framestate && !has_control && !has_effect) {
-    result = graph()->NewNode(op, value_input_count, value_inputs);
+    result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
   } else {
     int input_count_with_deps = value_input_count;
     if (has_context) ++input_count_with_deps;
     if (has_framestate) ++input_count_with_deps;
     if (has_control) ++input_count_with_deps;
     if (has_effect) ++input_count_with_deps;
-    Node** buffer = zone()->NewArray<Node*>(input_count_with_deps);
+    Node** buffer = EnsureInputBufferSize(input_count_with_deps);
     memcpy(buffer, value_inputs, kPointerSize * value_input_count);
     Node** current_input = buffer + value_input_count;
     if (has_context) {
@@ -68,11 +80,11 @@
     if (has_control) {
       *current_input++ = environment_->GetControlDependency();
     }
-    result = graph()->NewNode(op, input_count_with_deps, buffer);
+    result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
     if (has_effect) {
       environment_->UpdateEffectDependency(result);
     }
-    if (OperatorProperties::HasControlOutput(result->op()) &&
+    if (result->op()->ControlOutputCount() > 0 &&
         !environment()->IsMarkedAsUnreachable()) {
       environment_->UpdateControlDependency(result);
     }
@@ -95,7 +107,7 @@
 
 StructuredGraphBuilder::Environment* StructuredGraphBuilder::CopyEnvironment(
     Environment* env) {
-  return new (zone()) Environment(*env);
+  return new (local_zone()) Environment(*env);
 }
 
 
@@ -111,7 +123,11 @@
     : builder_(copy.builder()),
       control_dependency_(copy.control_dependency_),
       effect_dependency_(copy.effect_dependency_),
-      values_(copy.values_) {}
+      values_(copy.zone()) {
+  const size_t kStackEstimate = 7;  // optimum from experimentation!
+  values_.reserve(copy.values_.size() + kStackEstimate);
+  values_.insert(values_.begin(), copy.values_.begin(), copy.values_.end());
+}
 
 
 void StructuredGraphBuilder::Environment::Merge(Environment* other) {
@@ -124,7 +140,9 @@
   // placing a singleton merge as the new control dependency.
   if (this->IsMarkedAsUnreachable()) {
     Node* other_control = other->control_dependency_;
-    control_dependency_ = graph()->NewNode(common()->Merge(1), other_control);
+    Node* inputs[] = {other_control};
+    control_dependency_ =
+        graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true);
     effect_dependency_ = other->effect_dependency_;
     values_ = other->values_;
     return;
@@ -150,11 +168,22 @@
 }
 
 
-void StructuredGraphBuilder::Environment::PrepareForLoop() {
+void StructuredGraphBuilder::Environment::PrepareForLoop(BitVector* assigned) {
   Node* control = GetControlDependency();
-  for (int i = 0; i < static_cast<int>(values()->size()); ++i) {
-    Node* phi = builder_->NewPhi(1, values()->at(i), control);
-    values()->at(i) = phi;
+  int size = static_cast<int>(values()->size());
+  if (assigned == NULL) {
+    // Assume that everything is updated in the loop.
+    for (int i = 0; i < size; ++i) {
+      Node* phi = builder_->NewPhi(1, values()->at(i), control);
+      values()->at(i) = phi;
+    }
+  } else {
+    // Only build phis for those locals assigned in this loop.
+    for (int i = 0; i < size; ++i) {
+      if (i < assigned->length() && !assigned->Contains(i)) continue;
+      Node* phi = builder_->NewPhi(1, values()->at(i), control);
+      values()->at(i) = phi;
+    }
   }
   Node* effect = builder_->NewEffectPhi(1, GetEffectDependency(), control);
   UpdateEffectDependency(effect);
@@ -163,10 +192,10 @@
 
 Node* StructuredGraphBuilder::NewPhi(int count, Node* input, Node* control) {
   const Operator* phi_op = common()->Phi(kMachAnyTagged, count);
-  Node** buffer = zone()->NewArray<Node*>(count + 1);
+  Node** buffer = EnsureInputBufferSize(count + 1);
   MemsetPointer(buffer, input, count);
   buffer[count] = control;
-  return graph()->NewNode(phi_op, count + 1, buffer);
+  return graph()->NewNode(phi_op, count + 1, buffer, true);
 }
 
 
@@ -174,29 +203,30 @@
 Node* StructuredGraphBuilder::NewEffectPhi(int count, Node* input,
                                            Node* control) {
   const Operator* phi_op = common()->EffectPhi(count);
-  Node** buffer = zone()->NewArray<Node*>(count + 1);
+  Node** buffer = EnsureInputBufferSize(count + 1);
   MemsetPointer(buffer, input, count);
   buffer[count] = control;
-  return graph()->NewNode(phi_op, count + 1, buffer);
+  return graph()->NewNode(phi_op, count + 1, buffer, true);
 }
 
 
 Node* StructuredGraphBuilder::MergeControl(Node* control, Node* other) {
-  int inputs = OperatorProperties::GetControlInputCount(control->op()) + 1;
+  int inputs = control->op()->ControlInputCount() + 1;
   if (control->opcode() == IrOpcode::kLoop) {
     // Control node for loop exists, add input.
     const Operator* op = common()->Loop(inputs);
-    control->AppendInput(zone(), other);
+    control->AppendInput(graph_zone(), other);
     control->set_op(op);
   } else if (control->opcode() == IrOpcode::kMerge) {
     // Control node for merge exists, add input.
     const Operator* op = common()->Merge(inputs);
-    control->AppendInput(zone(), other);
+    control->AppendInput(graph_zone(), other);
     control->set_op(op);
   } else {
     // Control node is a singleton, introduce a merge.
     const Operator* op = common()->Merge(inputs);
-    control = graph()->NewNode(op, control, other);
+    Node* inputs[] = {control, other};
+    control = graph()->NewNode(op, arraysize(inputs), inputs, true);
   }
   return control;
 }
@@ -204,12 +234,12 @@
 
 Node* StructuredGraphBuilder::MergeEffect(Node* value, Node* other,
                                           Node* control) {
-  int inputs = OperatorProperties::GetControlInputCount(control->op());
+  int inputs = control->op()->ControlInputCount();
   if (value->opcode() == IrOpcode::kEffectPhi &&
       NodeProperties::GetControlInput(value) == control) {
     // Phi already exists, add input.
     value->set_op(common()->EffectPhi(inputs));
-    value->InsertInput(zone(), inputs - 1, other);
+    value->InsertInput(graph_zone(), inputs - 1, other);
   } else if (value != other) {
     // Phi does not exist yet, introduce one.
     value = NewEffectPhi(inputs, value, control);
@@ -221,12 +251,12 @@
 
 Node* StructuredGraphBuilder::MergeValue(Node* value, Node* other,
                                          Node* control) {
-  int inputs = OperatorProperties::GetControlInputCount(control->op());
+  int inputs = control->op()->ControlInputCount();
   if (value->opcode() == IrOpcode::kPhi &&
       NodeProperties::GetControlInput(value) == control) {
     // Phi already exists, add input.
     value->set_op(common()->Phi(kMachAnyTagged, inputs));
-    value->InsertInput(zone(), inputs - 1, other);
+    value->InsertInput(graph_zone(), inputs - 1, other);
   } else if (value != other) {
     // Phi does not exist yet, introduce one.
     value = NewPhi(inputs, value, control);
diff --git a/src/compiler/graph-builder.h b/src/compiler/graph-builder.h
index c966c29..d88b125 100644
--- a/src/compiler/graph-builder.h
+++ b/src/compiler/graph-builder.h
@@ -14,6 +14,9 @@
 
 namespace v8 {
 namespace internal {
+
+class BitVector;
+
 namespace compiler {
 
 class Node;
@@ -24,42 +27,44 @@
   explicit GraphBuilder(Graph* graph) : graph_(graph) {}
   virtual ~GraphBuilder() {}
 
-  Node* NewNode(const Operator* op) {
-    return MakeNode(op, 0, static_cast<Node**>(NULL));
+  Node* NewNode(const Operator* op, bool incomplete = false) {
+    return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete);
   }
 
-  Node* NewNode(const Operator* op, Node* n1) { return MakeNode(op, 1, &n1); }
+  Node* NewNode(const Operator* op, Node* n1) {
+    return MakeNode(op, 1, &n1, false);
+  }
 
   Node* NewNode(const Operator* op, Node* n1, Node* n2) {
     Node* buffer[] = {n1, n2};
-    return MakeNode(op, arraysize(buffer), buffer);
+    return MakeNode(op, arraysize(buffer), buffer, false);
   }
 
   Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) {
     Node* buffer[] = {n1, n2, n3};
-    return MakeNode(op, arraysize(buffer), buffer);
+    return MakeNode(op, arraysize(buffer), buffer, false);
   }
 
   Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) {
     Node* buffer[] = {n1, n2, n3, n4};
-    return MakeNode(op, arraysize(buffer), buffer);
+    return MakeNode(op, arraysize(buffer), buffer, false);
   }
 
   Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
                 Node* n5) {
     Node* buffer[] = {n1, n2, n3, n4, n5};
-    return MakeNode(op, arraysize(buffer), buffer);
+    return MakeNode(op, arraysize(buffer), buffer, false);
   }
 
   Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
                 Node* n5, Node* n6) {
     Node* nodes[] = {n1, n2, n3, n4, n5, n6};
-    return MakeNode(op, arraysize(nodes), nodes);
+    return MakeNode(op, arraysize(nodes), nodes, false);
   }
 
-  Node* NewNode(const Operator* op, int value_input_count,
-                Node** value_inputs) {
-    return MakeNode(op, value_input_count, value_inputs);
+  Node* NewNode(const Operator* op, int value_input_count, Node** value_inputs,
+                bool incomplete = false) {
+    return MakeNode(op, value_input_count, value_inputs, incomplete);
   }
 
   Graph* graph() const { return graph_; }
@@ -67,7 +72,7 @@
  protected:
   // Base implementation used by all factory methods.
   virtual Node* MakeNode(const Operator* op, int value_input_count,
-                         Node** value_inputs) = 0;
+                         Node** value_inputs, bool incomplete) = 0;
 
  private:
   Graph* graph_;
@@ -79,8 +84,9 @@
 // StubGraphBuilder).
 class StructuredGraphBuilder : public GraphBuilder {
  public:
-  StructuredGraphBuilder(Graph* graph, CommonOperatorBuilder* common);
-  virtual ~StructuredGraphBuilder() {}
+  StructuredGraphBuilder(Zone* zone, Graph* graph,
+                         CommonOperatorBuilder* common);
+  ~StructuredGraphBuilder() OVERRIDE {}
 
   // Creates a new Phi node having {count} input values.
   Node* NewPhi(int count, Node* input, Node* control);
@@ -94,10 +100,10 @@
   // Helpers to create new control nodes.
   Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
   Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
-  Node* NewMerge() { return NewNode(common()->Merge(1)); }
-  Node* NewLoop() { return NewNode(common()->Loop(1)); }
-  Node* NewBranch(Node* condition) {
-    return NewNode(common()->Branch(), condition);
+  Node* NewMerge() { return NewNode(common()->Merge(1), true); }
+  Node* NewLoop() { return NewNode(common()->Loop(1), true); }
+  Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
+    return NewNode(common()->Branch(hint), condition);
   }
 
  protected:
@@ -108,8 +114,8 @@
   // The following method creates a new node having the specified operator and
   // ensures effect and control dependencies are wired up. The dependencies
   // tracked by the environment might be mutated.
-  virtual Node* MakeNode(const Operator* op, int value_input_count,
-                         Node** value_inputs) FINAL;
+  Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
+                 bool incomplete) FINAL;
 
   Environment* environment() const { return environment_; }
   void set_environment(Environment* env) { environment_ = env; }
@@ -122,9 +128,9 @@
 
   Node* dead_control();
 
-  // TODO(mstarzinger): Use phase-local zone instead!
-  Zone* zone() const { return graph()->zone(); }
-  Isolate* isolate() const { return zone()->isolate(); }
+  Zone* graph_zone() const { return graph()->zone(); }
+  Zone* local_zone() const { return local_zone_; }
+  Isolate* isolate() const { return graph_zone()->isolate(); }
   CommonOperatorBuilder* common() const { return common_; }
 
   // Helper to wrap a Handle<T> into a Unique<T>.
@@ -144,6 +150,13 @@
   CommonOperatorBuilder* common_;
   Environment* environment_;
 
+  // Zone local to the builder for data not leaking into the graph.
+  Zone* local_zone_;
+
+  // Temporary storage for building node input lists.
+  int input_buffer_size_;
+  Node** input_buffer_;
+
   // Node representing the control dependency for dead code.
   SetOncePointer<Node> dead_control_;
 
@@ -153,6 +166,12 @@
   // Merge of all control nodes that exit the function body.
   Node* exit_control_;
 
+  // Growth increment for the temporary buffer used to construct input lists to
+  // new nodes.
+  static const int kInputBufferSizeIncrement = 64;
+
+  Node** EnsureInputBufferSize(int size);
+
   DISALLOW_COPY_AND_ASSIGN(StructuredGraphBuilder);
 };
 
@@ -199,23 +218,22 @@
   }
 
   // Copies this environment at a loop header control-flow point.
-  Environment* CopyForLoop() {
-    PrepareForLoop();
+  Environment* CopyForLoop(BitVector* assigned) {
+    PrepareForLoop(assigned);
     return builder()->CopyEnvironment(this);
   }
 
   Node* GetContext() { return builder_->current_context(); }
 
  protected:
-  // TODO(mstarzinger): Use phase-local zone instead!
-  Zone* zone() const { return graph()->zone(); }
+  Zone* zone() const { return builder_->local_zone(); }
   Graph* graph() const { return builder_->graph(); }
   StructuredGraphBuilder* builder() const { return builder_; }
   CommonOperatorBuilder* common() { return builder_->common(); }
   NodeVector* values() { return &values_; }
 
   // Prepare environment to be used as loop header.
-  void PrepareForLoop();
+  void PrepareForLoop(BitVector* assigned);
 
  private:
   StructuredGraphBuilder* builder_;
diff --git a/src/compiler/graph-inl.h b/src/compiler/graph-inl.h
index 571ffb3..c135ae5 100644
--- a/src/compiler/graph-inl.h
+++ b/src/compiler/graph-inl.h
@@ -5,7 +5,7 @@
 #ifndef V8_COMPILER_GRAPH_INL_H_
 #define V8_COMPILER_GRAPH_INL_H_
 
-#include "src/compiler/generic-algorithm-inl.h"
+#include "src/compiler/generic-algorithm.h"
 #include "src/compiler/graph.h"
 
 namespace v8 {
@@ -13,25 +13,13 @@
 namespace compiler {
 
 template <class Visitor>
-void Graph::VisitNodeUsesFrom(Node* node, Visitor* visitor) {
-  GenericGraphVisit::Visit<Visitor, NodeUseIterationTraits<Node> >(
-      this, zone(), node, visitor);
-}
-
-
-template <class Visitor>
-void Graph::VisitNodeUsesFromStart(Visitor* visitor) {
-  VisitNodeUsesFrom(start(), visitor);
-}
-
-
-template <class Visitor>
 void Graph::VisitNodeInputsFromEnd(Visitor* visitor) {
-  GenericGraphVisit::Visit<Visitor, NodeInputIterationTraits<Node> >(
-      this, zone(), end(), visitor);
+  Zone tmp_zone(zone()->isolate());
+  GenericGraphVisit::Visit<Visitor>(this, &tmp_zone, end(), visitor);
 }
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_GRAPH_INL_H_
diff --git a/src/compiler/graph-reducer-unittest.cc b/src/compiler/graph-reducer-unittest.cc
deleted file mode 100644
index 6567203..0000000
--- a/src/compiler/graph-reducer-unittest.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/graph.h"
-#include "src/compiler/graph-reducer.h"
-#include "src/compiler/operator.h"
-#include "src/test/test-utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-using testing::_;
-using testing::DefaultValue;
-using testing::Return;
-using testing::Sequence;
-using testing::StrictMock;
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-namespace {
-
-SimpleOperator OP0(0, Operator::kNoWrite, 0, 1, "op0");
-SimpleOperator OP1(1, Operator::kNoProperties, 1, 1, "op1");
-
-
-struct MockReducer : public Reducer {
-  MOCK_METHOD1(Reduce, Reduction(Node*));
-};
-
-}  // namespace
-
-
-class GraphReducerTest : public TestWithZone {
- public:
-  GraphReducerTest() : graph_(zone()) {}
-
-  static void SetUpTestCase() {
-    TestWithZone::SetUpTestCase();
-    DefaultValue<Reduction>::Set(Reducer::NoChange());
-  }
-
-  static void TearDownTestCase() {
-    DefaultValue<Reduction>::Clear();
-    TestWithZone::TearDownTestCase();
-  }
-
- protected:
-  void ReduceNode(Node* node, Reducer* r) {
-    GraphReducer reducer(graph());
-    reducer.AddReducer(r);
-    reducer.ReduceNode(node);
-  }
-
-  void ReduceNode(Node* node, Reducer* r1, Reducer* r2) {
-    GraphReducer reducer(graph());
-    reducer.AddReducer(r1);
-    reducer.AddReducer(r2);
-    reducer.ReduceNode(node);
-  }
-
-  void ReduceNode(Node* node, Reducer* r1, Reducer* r2, Reducer* r3) {
-    GraphReducer reducer(graph());
-    reducer.AddReducer(r1);
-    reducer.AddReducer(r2);
-    reducer.AddReducer(r3);
-    reducer.ReduceNode(node);
-  }
-
-  Graph* graph() { return &graph_; }
-
- private:
-  Graph graph_;
-};
-
-
-TEST_F(GraphReducerTest, NodeIsDeadAfterReplace) {
-  StrictMock<MockReducer> r;
-  Node* node0 = graph()->NewNode(&OP0);
-  Node* node1 = graph()->NewNode(&OP1, node0);
-  Node* node2 = graph()->NewNode(&OP1, node0);
-  EXPECT_CALL(r, Reduce(node1)).WillOnce(Return(Reducer::Replace(node2)));
-  ReduceNode(node1, &r);
-  EXPECT_FALSE(node0->IsDead());
-  EXPECT_TRUE(node1->IsDead());
-  EXPECT_FALSE(node2->IsDead());
-}
-
-
-TEST_F(GraphReducerTest, ReduceOnceForEveryReducer) {
-  StrictMock<MockReducer> r1, r2;
-  Node* node0 = graph()->NewNode(&OP0);
-  EXPECT_CALL(r1, Reduce(node0));
-  EXPECT_CALL(r2, Reduce(node0));
-  ReduceNode(node0, &r1, &r2);
-}
-
-
-TEST_F(GraphReducerTest, ReduceAgainAfterChanged) {
-  Sequence s1, s2;
-  StrictMock<MockReducer> r1, r2, r3;
-  Node* node0 = graph()->NewNode(&OP0);
-  EXPECT_CALL(r1, Reduce(node0));
-  EXPECT_CALL(r2, Reduce(node0));
-  EXPECT_CALL(r3, Reduce(node0)).InSequence(s1, s2).WillOnce(
-      Return(Reducer::Changed(node0)));
-  EXPECT_CALL(r1, Reduce(node0)).InSequence(s1);
-  EXPECT_CALL(r2, Reduce(node0)).InSequence(s2);
-  ReduceNode(node0, &r1, &r2, &r3);
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/graph-reducer.cc b/src/compiler/graph-reducer.cc
index 36a54e0..9a6b121 100644
--- a/src/compiler/graph-reducer.cc
+++ b/src/compiler/graph-reducer.cc
@@ -12,86 +12,190 @@
 namespace internal {
 namespace compiler {
 
-GraphReducer::GraphReducer(Graph* graph)
-    : graph_(graph), reducers_(graph->zone()) {}
+enum class GraphReducer::State : uint8_t {
+  kUnvisited,
+  kRevisit,
+  kOnStack,
+  kVisited
+};
 
 
-static bool NodeIdIsLessThan(const Node* node, NodeId id) {
-  return node->id() < id;
+GraphReducer::GraphReducer(Graph* graph, Zone* zone)
+    : graph_(graph),
+      state_(graph, 4),
+      reducers_(zone),
+      revisit_(zone),
+      stack_(zone) {}
+
+
+void GraphReducer::AddReducer(Reducer* reducer) {
+  reducers_.push_back(reducer);
 }
 
 
 void GraphReducer::ReduceNode(Node* node) {
-  ZoneVector<Reducer*>::iterator skip = reducers_.end();
-  static const unsigned kMaxAttempts = 16;
-  bool reduce = true;
-  for (unsigned attempts = 0; attempts <= kMaxAttempts; ++attempts) {
-    if (!reduce) return;
-    reduce = false;  // Assume we don't need to rerun any reducers.
-    int before = graph_->NodeCount();
-    for (ZoneVector<Reducer*>::iterator i = reducers_.begin();
-         i != reducers_.end(); ++i) {
-      if (i == skip) continue;  // Skip this reducer.
-      Reduction reduction = (*i)->Reduce(node);
-      Node* replacement = reduction.replacement();
-      if (replacement == NULL) {
-        // No change from this reducer.
-      } else if (replacement == node) {
-        // {replacement == node} represents an in-place reduction.
-        // Rerun all the reducers except the current one for this node,
-        // as now there may be more opportunities for reduction.
-        reduce = true;
-        skip = i;
-        break;
-      } else {
-        if (node == graph_->start()) graph_->SetStart(replacement);
-        if (node == graph_->end()) graph_->SetEnd(replacement);
-        // If {node} was replaced by an old node, unlink {node} and assume that
-        // {replacement} was already reduced and finish.
-        if (replacement->id() < before) {
-          node->ReplaceUses(replacement);
-          node->Kill();
-          return;
-        }
-        // Otherwise, {node} was replaced by a new node. Replace all old uses of
-        // {node} with {replacement}. New nodes created by this reduction can
-        // use {node}.
-        node->ReplaceUsesIf(
-            std::bind2nd(std::ptr_fun(&NodeIdIsLessThan), before), replacement);
-        // Unlink {node} if it's no longer used.
-        if (node->uses().empty()) {
-          node->Kill();
-        }
-        // Rerun all the reductions on the {replacement}.
-        skip = reducers_.end();
-        node = replacement;
-        reduce = true;
-        break;
+  DCHECK(stack_.empty());
+  DCHECK(revisit_.empty());
+  Push(node);
+  for (;;) {
+    if (!stack_.empty()) {
+      // Process the node on the top of the stack, potentially pushing more or
+      // popping the node off the stack.
+      ReduceTop();
+    } else if (!revisit_.empty()) {
+      // If the stack becomes empty, revisit any nodes in the revisit queue.
+      Node* const node = revisit_.top();
+      revisit_.pop();
+      if (state_.Get(node) == State::kRevisit) {
+        // state can change while in queue.
+        Push(node);
       }
+    } else {
+      break;
+    }
+  }
+  DCHECK(revisit_.empty());
+  DCHECK(stack_.empty());
+}
+
+
+void GraphReducer::ReduceGraph() { ReduceNode(graph()->end()); }
+
+
+Reduction GraphReducer::Reduce(Node* const node) {
+  auto skip = reducers_.end();
+  for (auto i = reducers_.begin(); i != reducers_.end();) {
+    if (i != skip) {
+      Reduction reduction = (*i)->Reduce(node);
+      if (!reduction.Changed()) {
+        // No change from this reducer.
+      } else if (reduction.replacement() == node) {
+        // {replacement} == {node} represents an in-place reduction. Rerun
+        // all the other reducers for this node, as now there may be more
+        // opportunities for reduction.
+        skip = i;
+        i = reducers_.begin();
+        continue;
+      } else {
+        // {node} was replaced by another node.
+        return reduction;
+      }
+    }
+    ++i;
+  }
+  if (skip == reducers_.end()) {
+    // No change from any reducer.
+    return Reducer::NoChange();
+  }
+  // At least one reducer did some in-place reduction.
+  return Reducer::Changed(node);
+}
+
+
+void GraphReducer::ReduceTop() {
+  NodeState& entry = stack_.top();
+  Node* node = entry.node;
+  DCHECK(state_.Get(node) == State::kOnStack);
+
+  if (node->IsDead()) return Pop();  // Node was killed while on stack.
+
+  // Recurse on an input if necessary.
+  int start = entry.input_index < node->InputCount() ? entry.input_index : 0;
+  for (int i = start; i < node->InputCount(); i++) {
+    Node* input = node->InputAt(i);
+    entry.input_index = i + 1;
+    if (input != node && Recurse(input)) return;
+  }
+  for (int i = 0; i < start; i++) {
+    Node* input = node->InputAt(i);
+    entry.input_index = i + 1;
+    if (input != node && Recurse(input)) return;
+  }
+
+  // Remember the node count before reduction.
+  const int node_count = graph()->NodeCount();
+
+  // All inputs should be visited or on stack. Apply reductions to node.
+  Reduction reduction = Reduce(node);
+
+  // If there was no reduction, pop {node} and continue.
+  if (!reduction.Changed()) return Pop();
+
+  // Check if the reduction is an in-place update of the {node}.
+  Node* const replacement = reduction.replacement();
+  if (replacement == node) {
+    // In-place update of {node}, may need to recurse on an input.
+    for (int i = 0; i < node->InputCount(); ++i) {
+      Node* input = node->InputAt(i);
+      entry.input_index = i + 1;
+      if (input != node && Recurse(input)) return;
+    }
+  }
+
+  // After reducing the node, pop it off the stack.
+  Pop();
+
+  // Revisit all uses of the node.
+  for (Node* const use : node->uses()) {
+    // Don't revisit this node if it refers to itself.
+    if (use != node) Revisit(use);
+  }
+
+  // Check if we have a new replacement.
+  if (replacement != node) {
+    if (node == graph()->start()) graph()->SetStart(replacement);
+    if (node == graph()->end()) graph()->SetEnd(replacement);
+    // If {node} was replaced by an old node, unlink {node} and assume that
+    // {replacement} was already reduced and finish.
+    if (replacement->id() < node_count) {
+      node->ReplaceUses(replacement);
+      node->Kill();
+    } else {
+      // Otherwise {node} was replaced by a new node. Replace all old uses of
+      // {node} with {replacement}. New nodes created by this reduction can
+      // use {node}.
+      node->ReplaceUsesIf(
+          [node_count](Node* const node) { return node->id() < node_count; },
+          replacement);
+      // Unlink {node} if it's no longer used.
+      if (node->uses().empty()) {
+        node->Kill();
+      }
+
+      // If there was a replacement, reduce it after popping {node}.
+      Recurse(replacement);
     }
   }
 }
 
 
-// A helper class to reuse the node traversal algorithm.
-struct GraphReducerVisitor FINAL : public NullNodeVisitor {
-  explicit GraphReducerVisitor(GraphReducer* reducer) : reducer_(reducer) {}
-  GenericGraphVisit::Control Post(Node* node) {
-    reducer_->ReduceNode(node);
-    return GenericGraphVisit::CONTINUE;
-  }
-  GraphReducer* reducer_;
-};
-
-
-void GraphReducer::ReduceGraph() {
-  GraphReducerVisitor visitor(this);
-  // Perform a post-order reduction of all nodes starting from the end.
-  graph()->VisitNodeInputsFromEnd(&visitor);
+void GraphReducer::Pop() {
+  Node* node = stack_.top().node;
+  state_.Set(node, State::kVisited);
+  stack_.pop();
 }
 
 
-// TODO(titzer): partial graph reductions.
+void GraphReducer::Push(Node* const node) {
+  DCHECK(state_.Get(node) != State::kOnStack);
+  state_.Set(node, State::kOnStack);
+  stack_.push({node, 0});
+}
+
+
+bool GraphReducer::Recurse(Node* node) {
+  if (state_.Get(node) > State::kRevisit) return false;
+  Push(node);
+  return true;
+}
+
+
+void GraphReducer::Revisit(Node* node) {
+  if (state_.Get(node) == State::kVisited) {
+    state_.Set(node, State::kRevisit);
+    revisit_.push(node);
+  }
+}
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/graph-reducer.h b/src/compiler/graph-reducer.h
index e0e4f7a..09a650c 100644
--- a/src/compiler/graph-reducer.h
+++ b/src/compiler/graph-reducer.h
@@ -5,17 +5,13 @@
 #ifndef V8_COMPILER_GRAPH_REDUCER_H_
 #define V8_COMPILER_GRAPH_REDUCER_H_
 
+#include "src/compiler/graph.h"
 #include "src/zone-containers.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-// Forward declarations.
-class Graph;
-class Node;
-
-
 // Represents the result of trying to reduce a node in the graph.
 class Reduction FINAL {
  public:
@@ -55,20 +51,42 @@
 // Performs an iterative reduction of a node graph.
 class GraphReducer FINAL {
  public:
-  explicit GraphReducer(Graph* graph);
+  GraphReducer(Graph* graph, Zone* zone);
 
   Graph* graph() const { return graph_; }
 
-  void AddReducer(Reducer* reducer) { reducers_.push_back(reducer); }
+  void AddReducer(Reducer* reducer);
 
   // Reduce a single node.
-  void ReduceNode(Node* node);
+  void ReduceNode(Node* const);
   // Reduce the whole graph.
   void ReduceGraph();
 
  private:
+  enum class State : uint8_t;
+  struct NodeState {
+    Node* node;
+    int input_index;
+  };
+
+  // Reduce a single node.
+  Reduction Reduce(Node* const);
+  // Reduce the node on top of the stack.
+  void ReduceTop();
+
+  // Node stack operations.
+  void Pop();
+  void Push(Node* node);
+
+  // Revisit queue operations.
+  bool Recurse(Node* node);
+  void Revisit(Node* node);
+
   Graph* graph_;
+  NodeMarker<State> state_;
   ZoneVector<Reducer*> reducers_;
+  ZoneStack<Node*> revisit_;
+  ZoneStack<NodeState> stack_;
 
   DISALLOW_COPY_AND_ASSIGN(GraphReducer);
 };
diff --git a/src/compiler/graph-replay.cc b/src/compiler/graph-replay.cc
index 494d431..3a0b783 100644
--- a/src/compiler/graph-replay.cc
+++ b/src/compiler/graph-replay.cc
@@ -9,7 +9,7 @@
 #include "src/compiler/graph-inl.h"
 #include "src/compiler/node.h"
 #include "src/compiler/operator.h"
-#include "src/compiler/operator-properties-inl.h"
+#include "src/compiler/operator-properties.h"
 
 namespace v8 {
 namespace internal {
@@ -24,14 +24,13 @@
 }
 
 
-GenericGraphVisit::Control GraphReplayPrinter::Pre(Node* node) {
+void GraphReplayPrinter::Pre(Node* node) {
   PrintReplayOpCreator(node->op());
   PrintF("  Node* n%d = graph.NewNode(op", node->id());
   for (int i = 0; i < node->InputCount(); ++i) {
     PrintF(", nil");
   }
   PrintF("); USE(n%d);\n", node->id());
-  return GenericGraphVisit::CONTINUE;
 }
 
 
@@ -60,14 +59,14 @@
       PrintF("unique_constant");
       break;
     case IrOpcode::kPhi:
-      PrintF("%d", op->InputCount());
+      PrintF("%d", op->ValueInputCount());
       break;
     case IrOpcode::kEffectPhi:
-      PrintF("%d", OperatorProperties::GetEffectInputCount(op));
+      PrintF("%d", op->EffectInputCount());
       break;
     case IrOpcode::kLoop:
     case IrOpcode::kMerge:
-      PrintF("%d", OperatorProperties::GetControlInputCount(op));
+      PrintF("%d", op->ControlInputCount());
       break;
     default:
       break;
diff --git a/src/compiler/graph-replay.h b/src/compiler/graph-replay.h
index 53d5247..f41311e 100644
--- a/src/compiler/graph-replay.h
+++ b/src/compiler/graph-replay.h
@@ -5,6 +5,7 @@
 #ifndef V8_COMPILER_GRAPH_REPLAY_H_
 #define V8_COMPILER_GRAPH_REPLAY_H_
 
+#include "src/compiler/generic-algorithm.h"
 #include "src/compiler/node.h"
 
 namespace v8 {
@@ -25,7 +26,7 @@
   static void PrintReplay(Graph* graph) {}
 #endif
 
-  GenericGraphVisit::Control Pre(Node* node);
+  void Pre(Node* node);
   void PostEdge(Node* from, int index, Node* to);
 
  private:
diff --git a/src/compiler/graph-unittest.cc b/src/compiler/graph-unittest.cc
deleted file mode 100644
index 75e70cb..0000000
--- a/src/compiler/graph-unittest.cc
+++ /dev/null
@@ -1,779 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/graph-unittest.h"
-
-#include <ostream>  // NOLINT(readability/streams)
-
-#include "src/compiler/node-properties-inl.h"
-
-using testing::_;
-using testing::MakeMatcher;
-using testing::MatcherInterface;
-using testing::MatchResultListener;
-using testing::StringMatchResultListener;
-
-namespace v8 {
-namespace internal {
-
-// TODO(bmeurer): Find a new home for these functions.
-template <typename T>
-inline std::ostream& operator<<(std::ostream& os, const Unique<T>& value) {
-  return os << *value.handle();
-}
-inline std::ostream& operator<<(std::ostream& os,
-                                const ExternalReference& value) {
-  OStringStream ost;
-  compiler::StaticParameterTraits<ExternalReference>::PrintTo(ost, value);
-  return os << ost.c_str();
-}
-
-namespace compiler {
-
-GraphTest::GraphTest(int num_parameters) : common_(zone()), graph_(zone()) {
-  graph()->SetStart(graph()->NewNode(common()->Start(num_parameters)));
-}
-
-
-GraphTest::~GraphTest() {}
-
-
-Node* GraphTest::Parameter(int32_t index) {
-  return graph()->NewNode(common()->Parameter(index), graph()->start());
-}
-
-
-Node* GraphTest::Float32Constant(volatile float value) {
-  return graph()->NewNode(common()->Float32Constant(value));
-}
-
-
-Node* GraphTest::Float64Constant(volatile double value) {
-  return graph()->NewNode(common()->Float64Constant(value));
-}
-
-
-Node* GraphTest::Int32Constant(int32_t value) {
-  return graph()->NewNode(common()->Int32Constant(value));
-}
-
-
-Node* GraphTest::Int64Constant(int64_t value) {
-  return graph()->NewNode(common()->Int64Constant(value));
-}
-
-
-Node* GraphTest::NumberConstant(volatile double value) {
-  return graph()->NewNode(common()->NumberConstant(value));
-}
-
-
-Node* GraphTest::HeapConstant(const Unique<HeapObject>& value) {
-  return graph()->NewNode(common()->HeapConstant(value));
-}
-
-
-Node* GraphTest::FalseConstant() {
-  return HeapConstant(
-      Unique<HeapObject>::CreateImmovable(factory()->false_value()));
-}
-
-
-Node* GraphTest::TrueConstant() {
-  return HeapConstant(
-      Unique<HeapObject>::CreateImmovable(factory()->true_value()));
-}
-
-
-Matcher<Node*> GraphTest::IsFalseConstant() {
-  return IsHeapConstant(
-      Unique<HeapObject>::CreateImmovable(factory()->false_value()));
-}
-
-
-Matcher<Node*> GraphTest::IsTrueConstant() {
-  return IsHeapConstant(
-      Unique<HeapObject>::CreateImmovable(factory()->true_value()));
-}
-
-namespace {
-
-template <typename T>
-bool PrintMatchAndExplain(const T& value, const char* value_name,
-                          const Matcher<T>& value_matcher,
-                          MatchResultListener* listener) {
-  StringMatchResultListener value_listener;
-  if (!value_matcher.MatchAndExplain(value, &value_listener)) {
-    *listener << "whose " << value_name << " " << value << " doesn't match";
-    if (value_listener.str() != "") {
-      *listener << ", " << value_listener.str();
-    }
-    return false;
-  }
-  return true;
-}
-
-
-class NodeMatcher : public MatcherInterface<Node*> {
- public:
-  explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    if (node == NULL) {
-      *listener << "which is NULL";
-      return false;
-    }
-    if (node->opcode() != opcode_) {
-      *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode())
-                << " but should have been " << IrOpcode::Mnemonic(opcode_);
-      return false;
-    }
-    return true;
-  }
-
- private:
-  const IrOpcode::Value opcode_;
-};
-
-
-class IsBranchMatcher FINAL : public NodeMatcher {
- public:
-  IsBranchMatcher(const Matcher<Node*>& value_matcher,
-                  const Matcher<Node*>& control_matcher)
-      : NodeMatcher(IrOpcode::kBranch),
-        value_matcher_(value_matcher),
-        control_matcher_(control_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose value (";
-    value_matcher_.DescribeTo(os);
-    *os << ") and control (";
-    control_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
-                                 "value", value_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
-                                 "control", control_matcher_, listener));
-  }
-
- private:
-  const Matcher<Node*> value_matcher_;
-  const Matcher<Node*> control_matcher_;
-};
-
-
-class IsMergeMatcher FINAL : public NodeMatcher {
- public:
-  IsMergeMatcher(const Matcher<Node*>& control0_matcher,
-                 const Matcher<Node*>& control1_matcher)
-      : NodeMatcher(IrOpcode::kMerge),
-        control0_matcher_(control0_matcher),
-        control1_matcher_(control1_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose control0 (";
-    control0_matcher_.DescribeTo(os);
-    *os << ") and control1 (";
-    control1_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0),
-                                 "control0", control0_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1),
-                                 "control1", control1_matcher_, listener));
-  }
-
- private:
-  const Matcher<Node*> control0_matcher_;
-  const Matcher<Node*> control1_matcher_;
-};
-
-
-class IsControl1Matcher FINAL : public NodeMatcher {
- public:
-  IsControl1Matcher(IrOpcode::Value opcode,
-                    const Matcher<Node*>& control_matcher)
-      : NodeMatcher(opcode), control_matcher_(control_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose control (";
-    control_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
-                                 "control", control_matcher_, listener));
-  }
-
- private:
-  const Matcher<Node*> control_matcher_;
-};
-
-
-class IsFinishMatcher FINAL : public NodeMatcher {
- public:
-  IsFinishMatcher(const Matcher<Node*>& value_matcher,
-                  const Matcher<Node*>& effect_matcher)
-      : NodeMatcher(IrOpcode::kFinish),
-        value_matcher_(value_matcher),
-        effect_matcher_(effect_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose value (";
-    value_matcher_.DescribeTo(os);
-    *os << ") and effect (";
-    effect_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
-                                 "value", value_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
-                                 effect_matcher_, listener));
-  }
-
- private:
-  const Matcher<Node*> value_matcher_;
-  const Matcher<Node*> effect_matcher_;
-};
-
-
-template <typename T>
-class IsConstantMatcher FINAL : public NodeMatcher {
- public:
-  IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher)
-      : NodeMatcher(opcode), value_matcher_(value_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose value (";
-    value_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(OpParameter<T>(node), "value", value_matcher_,
-                                 listener));
-  }
-
- private:
-  const Matcher<T> value_matcher_;
-};
-
-
-class IsPhiMatcher FINAL : public NodeMatcher {
- public:
-  IsPhiMatcher(const Matcher<MachineType>& type_matcher,
-               const Matcher<Node*>& value0_matcher,
-               const Matcher<Node*>& value1_matcher,
-               const Matcher<Node*>& control_matcher)
-      : NodeMatcher(IrOpcode::kPhi),
-        type_matcher_(type_matcher),
-        value0_matcher_(value0_matcher),
-        value1_matcher_(value1_matcher),
-        control_matcher_(control_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose type (";
-    type_matcher_.DescribeTo(os);
-    *os << "), value0 (";
-    value0_matcher_.DescribeTo(os);
-    *os << "), value1 (";
-    value1_matcher_.DescribeTo(os);
-    *os << ") and control (";
-    control_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
-                                 type_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
-                                 "value0", value0_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
-                                 "value1", value1_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
-                                 "control", control_matcher_, listener));
-  }
-
- private:
-  const Matcher<MachineType> type_matcher_;
-  const Matcher<Node*> value0_matcher_;
-  const Matcher<Node*> value1_matcher_;
-  const Matcher<Node*> control_matcher_;
-};
-
-
-class IsProjectionMatcher FINAL : public NodeMatcher {
- public:
-  IsProjectionMatcher(const Matcher<size_t>& index_matcher,
-                      const Matcher<Node*>& base_matcher)
-      : NodeMatcher(IrOpcode::kProjection),
-        index_matcher_(index_matcher),
-        base_matcher_(base_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose index (";
-    index_matcher_.DescribeTo(os);
-    *os << ") and base (";
-    base_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(OpParameter<size_t>(node), "index",
-                                 index_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
-                                 base_matcher_, listener));
-  }
-
- private:
-  const Matcher<size_t> index_matcher_;
-  const Matcher<Node*> base_matcher_;
-};
-
-
-class IsCallMatcher FINAL : public NodeMatcher {
- public:
-  IsCallMatcher(const Matcher<CallDescriptor*>& descriptor_matcher,
-                const Matcher<Node*>& value0_matcher,
-                const Matcher<Node*>& value1_matcher,
-                const Matcher<Node*>& value2_matcher,
-                const Matcher<Node*>& value3_matcher,
-                const Matcher<Node*>& effect_matcher,
-                const Matcher<Node*>& control_matcher)
-      : NodeMatcher(IrOpcode::kCall),
-        descriptor_matcher_(descriptor_matcher),
-        value0_matcher_(value0_matcher),
-        value1_matcher_(value1_matcher),
-        value2_matcher_(value2_matcher),
-        value3_matcher_(value3_matcher),
-        effect_matcher_(effect_matcher),
-        control_matcher_(control_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose value0 (";
-    value0_matcher_.DescribeTo(os);
-    *os << ") and value1 (";
-    value1_matcher_.DescribeTo(os);
-    *os << ") and value2 (";
-    value2_matcher_.DescribeTo(os);
-    *os << ") and value3 (";
-    value3_matcher_.DescribeTo(os);
-    *os << ") and effect (";
-    effect_matcher_.DescribeTo(os);
-    *os << ") and control (";
-    control_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(OpParameter<CallDescriptor*>(node),
-                                 "descriptor", descriptor_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
-                                 "value0", value0_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
-                                 "value1", value1_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
-                                 "value2", value2_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3),
-                                 "value3", value3_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
-                                 effect_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
-                                 "control", control_matcher_, listener));
-  }
-
- private:
-  const Matcher<CallDescriptor*> descriptor_matcher_;
-  const Matcher<Node*> value0_matcher_;
-  const Matcher<Node*> value1_matcher_;
-  const Matcher<Node*> value2_matcher_;
-  const Matcher<Node*> value3_matcher_;
-  const Matcher<Node*> effect_matcher_;
-  const Matcher<Node*> control_matcher_;
-};
-
-
-class IsLoadMatcher FINAL : public NodeMatcher {
- public:
-  IsLoadMatcher(const Matcher<LoadRepresentation>& rep_matcher,
-                const Matcher<Node*>& base_matcher,
-                const Matcher<Node*>& index_matcher,
-                const Matcher<Node*>& effect_matcher)
-      : NodeMatcher(IrOpcode::kLoad),
-        rep_matcher_(rep_matcher),
-        base_matcher_(base_matcher),
-        index_matcher_(index_matcher),
-        effect_matcher_(effect_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose rep (";
-    rep_matcher_.DescribeTo(os);
-    *os << "), base (";
-    base_matcher_.DescribeTo(os);
-    *os << "), index (";
-    index_matcher_.DescribeTo(os);
-    *os << ") and effect (";
-    effect_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(OpParameter<LoadRepresentation>(node), "rep",
-                                 rep_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
-                                 base_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
-                                 "index", index_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
-                                 effect_matcher_, listener));
-  }
-
- private:
-  const Matcher<LoadRepresentation> rep_matcher_;
-  const Matcher<Node*> base_matcher_;
-  const Matcher<Node*> index_matcher_;
-  const Matcher<Node*> effect_matcher_;
-};
-
-
-class IsStoreMatcher FINAL : public NodeMatcher {
- public:
-  IsStoreMatcher(const Matcher<MachineType>& type_matcher,
-                 const Matcher<WriteBarrierKind> write_barrier_matcher,
-                 const Matcher<Node*>& base_matcher,
-                 const Matcher<Node*>& index_matcher,
-                 const Matcher<Node*>& value_matcher,
-                 const Matcher<Node*>& effect_matcher,
-                 const Matcher<Node*>& control_matcher)
-      : NodeMatcher(IrOpcode::kStore),
-        type_matcher_(type_matcher),
-        write_barrier_matcher_(write_barrier_matcher),
-        base_matcher_(base_matcher),
-        index_matcher_(index_matcher),
-        value_matcher_(value_matcher),
-        effect_matcher_(effect_matcher),
-        control_matcher_(control_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose type (";
-    type_matcher_.DescribeTo(os);
-    *os << "), write barrier (";
-    write_barrier_matcher_.DescribeTo(os);
-    *os << "), base (";
-    base_matcher_.DescribeTo(os);
-    *os << "), index (";
-    index_matcher_.DescribeTo(os);
-    *os << "), value (";
-    value_matcher_.DescribeTo(os);
-    *os << "), effect (";
-    effect_matcher_.DescribeTo(os);
-    *os << ") and control (";
-    control_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(
-                OpParameter<StoreRepresentation>(node).machine_type(), "type",
-                type_matcher_, listener) &&
-            PrintMatchAndExplain(
-                OpParameter<StoreRepresentation>(node).write_barrier_kind(),
-                "write barrier", write_barrier_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
-                                 base_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
-                                 "index", index_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
-                                 "value", value_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
-                                 effect_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
-                                 "control", control_matcher_, listener));
-  }
-
- private:
-  const Matcher<MachineType> type_matcher_;
-  const Matcher<WriteBarrierKind> write_barrier_matcher_;
-  const Matcher<Node*> base_matcher_;
-  const Matcher<Node*> index_matcher_;
-  const Matcher<Node*> value_matcher_;
-  const Matcher<Node*> effect_matcher_;
-  const Matcher<Node*> control_matcher_;
-};
-
-
-class IsBinopMatcher FINAL : public NodeMatcher {
- public:
-  IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher,
-                 const Matcher<Node*>& rhs_matcher)
-      : NodeMatcher(opcode),
-        lhs_matcher_(lhs_matcher),
-        rhs_matcher_(rhs_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose lhs (";
-    lhs_matcher_.DescribeTo(os);
-    *os << ") and rhs (";
-    rhs_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
-                                 lhs_matcher_, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
-                                 rhs_matcher_, listener));
-  }
-
- private:
-  const Matcher<Node*> lhs_matcher_;
-  const Matcher<Node*> rhs_matcher_;
-};
-
-
-class IsUnopMatcher FINAL : public NodeMatcher {
- public:
-  IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher)
-      : NodeMatcher(opcode), input_matcher_(input_matcher) {}
-
-  virtual void DescribeTo(std::ostream* os) const OVERRIDE {
-    NodeMatcher::DescribeTo(os);
-    *os << " whose input (";
-    input_matcher_.DescribeTo(os);
-    *os << ")";
-  }
-
-  virtual bool MatchAndExplain(Node* node, MatchResultListener* listener) const
-      OVERRIDE {
-    return (NodeMatcher::MatchAndExplain(node, listener) &&
-            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
-                                 "input", input_matcher_, listener));
-  }
-
- private:
-  const Matcher<Node*> input_matcher_;
-};
-}
-
-
-Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
-                        const Matcher<Node*>& control_matcher) {
-  return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher));
-}
-
-
-Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
-                       const Matcher<Node*>& control1_matcher) {
-  return MakeMatcher(new IsMergeMatcher(control0_matcher, control1_matcher));
-}
-
-
-Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) {
-  return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher));
-}
-
-
-Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) {
-  return MakeMatcher(
-      new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher));
-}
-
-
-Matcher<Node*> IsControlEffect(const Matcher<Node*>& control_matcher) {
-  return MakeMatcher(
-      new IsControl1Matcher(IrOpcode::kControlEffect, control_matcher));
-}
-
-
-Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) {
-  return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect, value_matcher));
-}
-
-
-Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
-                        const Matcher<Node*>& effect_matcher) {
-  return MakeMatcher(new IsFinishMatcher(value_matcher, effect_matcher));
-}
-
-
-Matcher<Node*> IsExternalConstant(
-    const Matcher<ExternalReference>& value_matcher) {
-  return MakeMatcher(new IsConstantMatcher<ExternalReference>(
-      IrOpcode::kExternalConstant, value_matcher));
-}
-
-
-Matcher<Node*> IsHeapConstant(
-    const Matcher<Unique<HeapObject> >& value_matcher) {
-  return MakeMatcher(new IsConstantMatcher<Unique<HeapObject> >(
-      IrOpcode::kHeapConstant, value_matcher));
-}
-
-
-Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) {
-  return MakeMatcher(
-      new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher));
-}
-
-
-Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher) {
-  return MakeMatcher(
-      new IsConstantMatcher<int64_t>(IrOpcode::kInt64Constant, value_matcher));
-}
-
-
-Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher) {
-  return MakeMatcher(
-      new IsConstantMatcher<float>(IrOpcode::kFloat32Constant, value_matcher));
-}
-
-
-Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher) {
-  return MakeMatcher(
-      new IsConstantMatcher<double>(IrOpcode::kFloat64Constant, value_matcher));
-}
-
-
-Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) {
-  return MakeMatcher(
-      new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher));
-}
-
-
-Matcher<Node*> IsPhi(const Matcher<MachineType>& type_matcher,
-                     const Matcher<Node*>& value0_matcher,
-                     const Matcher<Node*>& value1_matcher,
-                     const Matcher<Node*>& merge_matcher) {
-  return MakeMatcher(new IsPhiMatcher(type_matcher, value0_matcher,
-                                      value1_matcher, merge_matcher));
-}
-
-
-Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher,
-                            const Matcher<Node*>& base_matcher) {
-  return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher));
-}
-
-
-Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
-                      const Matcher<Node*>& value0_matcher,
-                      const Matcher<Node*>& value1_matcher,
-                      const Matcher<Node*>& value2_matcher,
-                      const Matcher<Node*>& value3_matcher,
-                      const Matcher<Node*>& effect_matcher,
-                      const Matcher<Node*>& control_matcher) {
-  return MakeMatcher(new IsCallMatcher(
-      descriptor_matcher, value0_matcher, value1_matcher, value2_matcher,
-      value3_matcher, effect_matcher, control_matcher));
-}
-
-
-Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
-                      const Matcher<Node*>& base_matcher,
-                      const Matcher<Node*>& index_matcher,
-                      const Matcher<Node*>& effect_matcher) {
-  return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher,
-                                       effect_matcher));
-}
-
-
-Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
-                       const Matcher<WriteBarrierKind>& write_barrier_matcher,
-                       const Matcher<Node*>& base_matcher,
-                       const Matcher<Node*>& index_matcher,
-                       const Matcher<Node*>& value_matcher,
-                       const Matcher<Node*>& effect_matcher,
-                       const Matcher<Node*>& control_matcher) {
-  return MakeMatcher(new IsStoreMatcher(
-      type_matcher, write_barrier_matcher, base_matcher, index_matcher,
-      value_matcher, effect_matcher, control_matcher));
-}
-
-
-#define IS_BINOP_MATCHER(Name)                                            \
-  Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher,              \
-                          const Matcher<Node*>& rhs_matcher) {            \
-    return MakeMatcher(                                                   \
-        new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \
-  }
-IS_BINOP_MATCHER(NumberLessThan)
-IS_BINOP_MATCHER(Word32And)
-IS_BINOP_MATCHER(Word32Sar)
-IS_BINOP_MATCHER(Word32Shl)
-IS_BINOP_MATCHER(Word32Ror)
-IS_BINOP_MATCHER(Word32Equal)
-IS_BINOP_MATCHER(Word64And)
-IS_BINOP_MATCHER(Word64Sar)
-IS_BINOP_MATCHER(Word64Shl)
-IS_BINOP_MATCHER(Word64Equal)
-IS_BINOP_MATCHER(Int32AddWithOverflow)
-IS_BINOP_MATCHER(Int32Mul)
-IS_BINOP_MATCHER(Uint32LessThanOrEqual)
-#undef IS_BINOP_MATCHER
-
-
-#define IS_UNOP_MATCHER(Name)                                                \
-  Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) {             \
-    return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
-  }
-IS_UNOP_MATCHER(ChangeFloat64ToInt32)
-IS_UNOP_MATCHER(ChangeFloat64ToUint32)
-IS_UNOP_MATCHER(ChangeInt32ToFloat64)
-IS_UNOP_MATCHER(ChangeInt32ToInt64)
-IS_UNOP_MATCHER(ChangeUint32ToFloat64)
-IS_UNOP_MATCHER(ChangeUint32ToUint64)
-IS_UNOP_MATCHER(TruncateFloat64ToInt32)
-IS_UNOP_MATCHER(TruncateInt64ToInt32)
-IS_UNOP_MATCHER(Float64Sqrt)
-#undef IS_UNOP_MATCHER
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/graph-unittest.h b/src/compiler/graph-unittest.h
deleted file mode 100644
index 1dc9c3d..0000000
--- a/src/compiler/graph-unittest.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_GRAPH_UNITTEST_H_
-#define V8_COMPILER_GRAPH_UNITTEST_H_
-
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph.h"
-#include "src/compiler/machine-operator.h"
-#include "src/test/test-utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace v8 {
-namespace internal {
-
-// Forward declarations.
-class HeapObject;
-template <class T>
-class Unique;
-
-namespace compiler {
-
-using ::testing::Matcher;
-
-
-class GraphTest : public TestWithContext, public TestWithZone {
- public:
-  explicit GraphTest(int parameters = 1);
-  virtual ~GraphTest();
-
- protected:
-  Node* Parameter(int32_t index);
-  Node* Float32Constant(volatile float value);
-  Node* Float64Constant(volatile double value);
-  Node* Int32Constant(int32_t value);
-  Node* Int64Constant(int64_t value);
-  Node* NumberConstant(volatile double value);
-  Node* HeapConstant(const Unique<HeapObject>& value);
-  Node* FalseConstant();
-  Node* TrueConstant();
-
-  Matcher<Node*> IsFalseConstant();
-  Matcher<Node*> IsTrueConstant();
-
-  CommonOperatorBuilder* common() { return &common_; }
-  Graph* graph() { return &graph_; }
-
- private:
-  CommonOperatorBuilder common_;
-  Graph graph_;
-};
-
-
-Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
-                        const Matcher<Node*>& control_matcher);
-Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
-                       const Matcher<Node*>& control1_matcher);
-Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher);
-Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher);
-Matcher<Node*> IsControlEffect(const Matcher<Node*>& control_matcher);
-Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher);
-Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
-                        const Matcher<Node*>& effect_matcher);
-Matcher<Node*> IsExternalConstant(
-    const Matcher<ExternalReference>& value_matcher);
-Matcher<Node*> IsHeapConstant(
-    const Matcher<Unique<HeapObject> >& value_matcher);
-Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher);
-Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher);
-Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher);
-Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher);
-Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher);
-Matcher<Node*> IsPhi(const Matcher<MachineType>& type_matcher,
-                     const Matcher<Node*>& value0_matcher,
-                     const Matcher<Node*>& value1_matcher,
-                     const Matcher<Node*>& merge_matcher);
-Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher,
-                            const Matcher<Node*>& base_matcher);
-Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
-                      const Matcher<Node*>& value0_matcher,
-                      const Matcher<Node*>& value1_matcher,
-                      const Matcher<Node*>& value2_matcher,
-                      const Matcher<Node*>& value3_matcher,
-                      const Matcher<Node*>& effect_matcher,
-                      const Matcher<Node*>& control_matcher);
-
-Matcher<Node*> IsNumberLessThan(const Matcher<Node*>& lhs_matcher,
-                                const Matcher<Node*>& rhs_matcher);
-
-Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
-                      const Matcher<Node*>& base_matcher,
-                      const Matcher<Node*>& index_matcher,
-                      const Matcher<Node*>& effect_matcher);
-Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
-                       const Matcher<WriteBarrierKind>& write_barrier_matcher,
-                       const Matcher<Node*>& base_matcher,
-                       const Matcher<Node*>& index_matcher,
-                       const Matcher<Node*>& value_matcher,
-                       const Matcher<Node*>& effect_matcher,
-                       const Matcher<Node*>& control_matcher);
-Matcher<Node*> IsWord32And(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord32Sar(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord32Shl(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord32Ror(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord32Equal(const Matcher<Node*>& lhs_matcher,
-                             const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord64And(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord64Shl(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord64Sar(const Matcher<Node*>& lhs_matcher,
-                           const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsWord64Equal(const Matcher<Node*>& lhs_matcher,
-                             const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsInt32AddWithOverflow(const Matcher<Node*>& lhs_matcher,
-                                      const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsInt32Mul(const Matcher<Node*>& lhs_matcher,
-                          const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsUint32LessThanOrEqual(const Matcher<Node*>& lhs_matcher,
-                                       const Matcher<Node*>& rhs_matcher);
-Matcher<Node*> IsChangeFloat64ToInt32(const Matcher<Node*>& input_matcher);
-Matcher<Node*> IsChangeFloat64ToUint32(const Matcher<Node*>& input_matcher);
-Matcher<Node*> IsChangeInt32ToFloat64(const Matcher<Node*>& input_matcher);
-Matcher<Node*> IsChangeInt32ToInt64(const Matcher<Node*>& input_matcher);
-Matcher<Node*> IsChangeUint32ToFloat64(const Matcher<Node*>& input_matcher);
-Matcher<Node*> IsChangeUint32ToUint64(const Matcher<Node*>& input_matcher);
-Matcher<Node*> IsTruncateFloat64ToInt32(const Matcher<Node*>& input_matcher);
-Matcher<Node*> IsTruncateInt64ToInt32(const Matcher<Node*>& input_matcher);
-Matcher<Node*> IsFloat64Sqrt(const Matcher<Node*>& input_matcher);
-
-}  //  namespace compiler
-}  //  namespace internal
-}  //  namespace v8
-
-#endif  // V8_COMPILER_GRAPH_UNITTEST_H_
diff --git a/src/compiler/graph-visualizer.cc b/src/compiler/graph-visualizer.cc
index 10d6698..e018c7a 100644
--- a/src/compiler/graph-visualizer.cc
+++ b/src/compiler/graph-visualizer.cc
@@ -4,9 +4,10 @@
 
 #include "src/compiler/graph-visualizer.h"
 
-#include "src/compiler/generic-algorithm.h"
-#include "src/compiler/generic-node.h"
-#include "src/compiler/generic-node-inl.h"
+#include <sstream>
+#include <string>
+
+#include "src/code-stubs.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/graph-inl.h"
 #include "src/compiler/node.h"
@@ -14,33 +15,223 @@
 #include "src/compiler/node-properties-inl.h"
 #include "src/compiler/opcodes.h"
 #include "src/compiler/operator.h"
+#include "src/compiler/register-allocator.h"
+#include "src/compiler/schedule.h"
+#include "src/compiler/scheduler.h"
 #include "src/ostreams.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+static int SafeId(Node* node) { return node == NULL ? -1 : node->id(); }
+static const char* SafeMnemonic(Node* node) {
+  return node == NULL ? "null" : node->op()->mnemonic();
+}
+
 #define DEAD_COLOR "#999999"
 
-class GraphVisualizer : public NullNodeVisitor {
+class AllNodes {
  public:
-  GraphVisualizer(OStream& os, Zone* zone, const Graph* graph);  // NOLINT
+  enum State { kDead, kGray, kLive };
+
+  AllNodes(Zone* local_zone, const Graph* graph)
+      : state(graph->NodeCount(), kDead, local_zone),
+        live(local_zone),
+        gray(local_zone) {
+    Node* end = graph->end();
+    state[end->id()] = kLive;
+    live.push_back(end);
+    // Find all live nodes reachable from end.
+    for (size_t i = 0; i < live.size(); i++) {
+      for (Node* const input : live[i]->inputs()) {
+        if (input == NULL) {
+          // TODO(titzer): print a warning.
+          continue;
+        }
+        if (input->id() >= graph->NodeCount()) {
+          // TODO(titzer): print a warning.
+          continue;
+        }
+        if (state[input->id()] != kLive) {
+          live.push_back(input);
+          state[input->id()] = kLive;
+        }
+      }
+    }
+
+    // Find all nodes that are not reachable from end that use live nodes.
+    for (size_t i = 0; i < live.size(); i++) {
+      for (Node* const use : live[i]->uses()) {
+        if (state[use->id()] == kDead) {
+          gray.push_back(use);
+          state[use->id()] = kGray;
+        }
+      }
+    }
+  }
+
+  bool IsLive(Node* node) {
+    return node != NULL && node->id() < static_cast<int>(state.size()) &&
+           state[node->id()] == kLive;
+  }
+
+  ZoneVector<State> state;
+  NodeVector live;
+  NodeVector gray;
+};
+
+
+class Escaped {
+ public:
+  explicit Escaped(const std::ostringstream& os,
+                   const char* escaped_chars = "<>|{}")
+      : str_(os.str()), escaped_chars_(escaped_chars) {}
+
+  friend std::ostream& operator<<(std::ostream& os, const Escaped& e) {
+    for (std::string::const_iterator i = e.str_.begin(); i != e.str_.end();
+         ++i) {
+      if (e.needs_escape(*i)) os << "\\";
+      os << *i;
+    }
+    return os;
+  }
+
+ private:
+  bool needs_escape(char ch) const {
+    for (size_t i = 0; i < strlen(escaped_chars_); ++i) {
+      if (ch == escaped_chars_[i]) return true;
+    }
+    return false;
+  }
+
+  const std::string str_;
+  const char* const escaped_chars_;
+};
+
+class JSONGraphNodeWriter {
+ public:
+  JSONGraphNodeWriter(std::ostream& os, Zone* zone, const Graph* graph)
+      : os_(os), all_(zone, graph), first_node_(true) {}
+
+  void Print() {
+    for (Node* const node : all_.live) PrintNode(node);
+  }
+
+  void PrintNode(Node* node) {
+    if (first_node_) {
+      first_node_ = false;
+    } else {
+      os_ << ",";
+    }
+    std::ostringstream label;
+    label << *node->op();
+    os_ << "{\"id\":" << SafeId(node) << ",\"label\":\"" << Escaped(label, "\"")
+        << "\"";
+    IrOpcode::Value opcode = node->opcode();
+    if (opcode == IrOpcode::kPhi || opcode == IrOpcode::kEffectPhi) {
+      os_ << ",\"rankInputs\":[0," << NodeProperties::FirstControlIndex(node)
+          << "]";
+      os_ << ",\"rankWithInput\":[" << NodeProperties::FirstControlIndex(node)
+          << "]";
+    } else if (opcode == IrOpcode::kIfTrue || opcode == IrOpcode::kIfFalse ||
+               opcode == IrOpcode::kLoop) {
+      os_ << ",\"rankInputs\":[" << NodeProperties::FirstControlIndex(node)
+          << "]";
+    }
+    if (opcode == IrOpcode::kBranch) {
+      os_ << ",\"rankInputs\":[0]";
+    }
+    os_ << ",\"opcode\":\"" << IrOpcode::Mnemonic(node->opcode()) << "\"";
+    os_ << ",\"control\":" << (NodeProperties::IsControl(node) ? "true"
+                                                               : "false");
+    os_ << "}";
+  }
+
+ private:
+  std::ostream& os_;
+  AllNodes all_;
+  bool first_node_;
+
+  DISALLOW_COPY_AND_ASSIGN(JSONGraphNodeWriter);
+};
+
+
+class JSONGraphEdgeWriter {
+ public:
+  JSONGraphEdgeWriter(std::ostream& os, Zone* zone, const Graph* graph)
+      : os_(os), all_(zone, graph), first_edge_(true) {}
+
+  void Print() {
+    for (Node* const node : all_.live) PrintEdges(node);
+  }
+
+  void PrintEdges(Node* node) {
+    for (int i = 0; i < node->InputCount(); i++) {
+      Node* input = node->InputAt(i);
+      if (input == NULL) continue;
+      PrintEdge(node, i, input);
+    }
+  }
+
+  void PrintEdge(Node* from, int index, Node* to) {
+    if (first_edge_) {
+      first_edge_ = false;
+    } else {
+      os_ << ",";
+    }
+    const char* edge_type = NULL;
+    if (index < NodeProperties::FirstValueIndex(from)) {
+      edge_type = "unknown";
+    } else if (index < NodeProperties::FirstContextIndex(from)) {
+      edge_type = "value";
+    } else if (index < NodeProperties::FirstFrameStateIndex(from)) {
+      edge_type = "context";
+    } else if (index < NodeProperties::FirstEffectIndex(from)) {
+      edge_type = "frame-state";
+    } else if (index < NodeProperties::FirstControlIndex(from)) {
+      edge_type = "effect";
+    } else {
+      edge_type = "control";
+    }
+    os_ << "{\"source\":" << SafeId(to) << ",\"target\":" << SafeId(from)
+        << ",\"index\":" << index << ",\"type\":\"" << edge_type << "\"}";
+  }
+
+ private:
+  std::ostream& os_;
+  AllNodes all_;
+  bool first_edge_;
+
+  DISALLOW_COPY_AND_ASSIGN(JSONGraphEdgeWriter);
+};
+
+
+std::ostream& operator<<(std::ostream& os, const AsJSON& ad) {
+  Zone tmp_zone(ad.graph.zone()->isolate());
+  os << "{\"nodes\":[";
+  JSONGraphNodeWriter(os, &tmp_zone, &ad.graph).Print();
+  os << "],\"edges\":[";
+  JSONGraphEdgeWriter(os, &tmp_zone, &ad.graph).Print();
+  os << "]}";
+  return os;
+}
+
+
+class GraphVisualizer {
+ public:
+  GraphVisualizer(std::ostream& os, Zone* zone, const Graph* graph)
+      : all_(zone, graph), os_(os) {}
 
   void Print();
 
-  GenericGraphVisit::Control Pre(Node* node);
-  GenericGraphVisit::Control PreEdge(Node* from, int index, Node* to);
+  void PrintNode(Node* node, bool gray);
 
  private:
-  void AnnotateNode(Node* node);
-  void PrintEdge(Node::Edge edge);
+  void PrintEdge(Edge edge);
 
-  Zone* zone_;
-  NodeSet all_nodes_;
-  NodeSet white_nodes_;
-  bool use_to_def_;
-  OStream& os_;
-  const Graph* const graph_;
+  AllNodes all_;
+  std::ostream& os_;
 
   DISALLOW_COPY_AND_ASSIGN(GraphVisualizer);
 };
@@ -49,92 +240,24 @@
 static Node* GetControlCluster(Node* node) {
   if (OperatorProperties::IsBasicBlockBegin(node->op())) {
     return node;
-  } else if (OperatorProperties::GetControlInputCount(node->op()) == 1) {
+  } else if (node->op()->ControlInputCount() == 1) {
     Node* control = NodeProperties::GetControlInput(node, 0);
-    return OperatorProperties::IsBasicBlockBegin(control->op()) ? control
-                                                                : NULL;
+    return control != NULL &&
+                   OperatorProperties::IsBasicBlockBegin(control->op())
+               ? control
+               : NULL;
   } else {
     return NULL;
   }
 }
 
 
-GenericGraphVisit::Control GraphVisualizer::Pre(Node* node) {
-  if (all_nodes_.count(node) == 0) {
-    Node* control_cluster = GetControlCluster(node);
-    if (control_cluster != NULL) {
-      os_ << "  subgraph cluster_BasicBlock" << control_cluster->id() << " {\n";
-    }
-    os_ << "  ID" << node->id() << " [\n";
-    AnnotateNode(node);
-    os_ << "  ]\n";
-    if (control_cluster != NULL) os_ << "  }\n";
-    all_nodes_.insert(node);
-    if (use_to_def_) white_nodes_.insert(node);
+void GraphVisualizer::PrintNode(Node* node, bool gray) {
+  Node* control_cluster = GetControlCluster(node);
+  if (control_cluster != NULL) {
+    os_ << "  subgraph cluster_BasicBlock" << control_cluster->id() << " {\n";
   }
-  return GenericGraphVisit::CONTINUE;
-}
-
-
-GenericGraphVisit::Control GraphVisualizer::PreEdge(Node* from, int index,
-                                                    Node* to) {
-  if (use_to_def_) return GenericGraphVisit::CONTINUE;
-  // When going from def to use, only consider white -> other edges, which are
-  // the dead nodes that use live nodes. We're probably not interested in
-  // dead nodes that only use other dead nodes.
-  if (white_nodes_.count(from) > 0) return GenericGraphVisit::CONTINUE;
-  return GenericGraphVisit::SKIP;
-}
-
-
-class Escaped {
- public:
-  explicit Escaped(const OStringStream& os) : str_(os.c_str()) {}
-
-  friend OStream& operator<<(OStream& os, const Escaped& e) {
-    for (const char* s = e.str_; *s != '\0'; ++s) {
-      if (needs_escape(*s)) os << "\\";
-      os << *s;
-    }
-    return os;
-  }
-
- private:
-  static bool needs_escape(char ch) {
-    switch (ch) {
-      case '>':
-      case '<':
-      case '|':
-      case '}':
-      case '{':
-        return true;
-      default:
-        return false;
-    }
-  }
-
-  const char* const str_;
-};
-
-
-static bool IsLikelyBackEdge(Node* from, int index, Node* to) {
-  if (from->opcode() == IrOpcode::kPhi ||
-      from->opcode() == IrOpcode::kEffectPhi) {
-    Node* control = NodeProperties::GetControlInput(from, 0);
-    return control->opcode() != IrOpcode::kMerge && control != to && index != 0;
-  } else if (from->opcode() == IrOpcode::kLoop) {
-    return index != 0;
-  } else {
-    return false;
-  }
-}
-
-
-void GraphVisualizer::AnnotateNode(Node* node) {
-  if (!use_to_def_) {
-    os_ << "    style=\"filled\"\n"
-        << "    fillcolor=\"" DEAD_COLOR "\"\n";
-  }
+  os_ << "  ID" << SafeId(node) << " [\n";
 
   os_ << "    shape=\"record\"\n";
   switch (node->opcode()) {
@@ -153,68 +276,89 @@
       break;
   }
 
-  OStringStream label;
-  label << *node->op();
-  os_ << "    label=\"{{#" << node->id() << ":" << Escaped(label);
+  if (gray) {
+    os_ << "    style=\"filled\"\n"
+        << "    fillcolor=\"" DEAD_COLOR "\"\n";
+  }
 
-  InputIter i = node->inputs().begin();
-  for (int j = OperatorProperties::GetValueInputCount(node->op()); j > 0;
-       ++i, j--) {
-    os_ << "|<I" << i.index() << ">#" << (*i)->id();
+  std::ostringstream label;
+  label << *node->op();
+  os_ << "    label=\"{{#" << SafeId(node) << ":" << Escaped(label);
+
+  auto i = node->input_edges().begin();
+  for (int j = node->op()->ValueInputCount(); j > 0; ++i, j--) {
+    os_ << "|<I" << (*i).index() << ">#" << SafeId((*i).to());
   }
   for (int j = OperatorProperties::GetContextInputCount(node->op()); j > 0;
        ++i, j--) {
-    os_ << "|<I" << i.index() << ">X #" << (*i)->id();
+    os_ << "|<I" << (*i).index() << ">X #" << SafeId((*i).to());
   }
   for (int j = OperatorProperties::GetFrameStateInputCount(node->op()); j > 0;
        ++i, j--) {
-    os_ << "|<I" << i.index() << ">F #" << (*i)->id();
+    os_ << "|<I" << (*i).index() << ">F #" << SafeId((*i).to());
   }
-  for (int j = OperatorProperties::GetEffectInputCount(node->op()); j > 0;
-       ++i, j--) {
-    os_ << "|<I" << i.index() << ">E #" << (*i)->id();
+  for (int j = node->op()->EffectInputCount(); j > 0; ++i, j--) {
+    os_ << "|<I" << (*i).index() << ">E #" << SafeId((*i).to());
   }
 
-  if (!use_to_def_ || OperatorProperties::IsBasicBlockBegin(node->op()) ||
+  if (OperatorProperties::IsBasicBlockBegin(node->op()) ||
       GetControlCluster(node) == NULL) {
-    for (int j = OperatorProperties::GetControlInputCount(node->op()); j > 0;
-         ++i, j--) {
-      os_ << "|<I" << i.index() << ">C #" << (*i)->id();
+    for (int j = node->op()->ControlInputCount(); j > 0; ++i, j--) {
+      os_ << "|<I" << (*i).index() << ">C #" << SafeId((*i).to());
     }
   }
   os_ << "}";
 
-  if (FLAG_trace_turbo_types && !NodeProperties::IsControl(node)) {
+  if (FLAG_trace_turbo_types && NodeProperties::IsTyped(node)) {
     Bounds bounds = NodeProperties::GetBounds(node);
-    OStringStream upper;
+    std::ostringstream upper;
     bounds.upper->PrintTo(upper);
-    OStringStream lower;
+    std::ostringstream lower;
     bounds.lower->PrintTo(lower);
     os_ << "|" << Escaped(upper) << "|" << Escaped(lower);
   }
   os_ << "}\"\n";
+
+  os_ << "  ]\n";
+  if (control_cluster != NULL) os_ << "  }\n";
 }
 
 
-void GraphVisualizer::PrintEdge(Node::Edge edge) {
+static bool IsLikelyBackEdge(Node* from, int index, Node* to) {
+  if (from->opcode() == IrOpcode::kPhi ||
+      from->opcode() == IrOpcode::kEffectPhi) {
+    Node* control = NodeProperties::GetControlInput(from, 0);
+    return control != NULL && control->opcode() != IrOpcode::kMerge &&
+           control != to && index != 0;
+  } else if (from->opcode() == IrOpcode::kLoop) {
+    return index != 0;
+  } else {
+    return false;
+  }
+}
+
+
+void GraphVisualizer::PrintEdge(Edge edge) {
   Node* from = edge.from();
   int index = edge.index();
   Node* to = edge.to();
+
+  if (!all_.IsLive(to)) return;  // skip inputs that point to dead or NULL.
+
   bool unconstrained = IsLikelyBackEdge(from, index, to);
-  os_ << "  ID" << from->id();
-  if (all_nodes_.count(to) == 0) {
-    os_ << ":I" << index << ":n -> DEAD_INPUT";
-  } else if (OperatorProperties::IsBasicBlockBegin(from->op()) ||
-             GetControlCluster(from) == NULL ||
-             (OperatorProperties::GetControlInputCount(from->op()) > 0 &&
-              NodeProperties::GetControlInput(from) != to)) {
-    os_ << ":I" << index << ":n -> ID" << to->id() << ":s"
+  os_ << "  ID" << SafeId(from);
+
+  if (OperatorProperties::IsBasicBlockBegin(from->op()) ||
+      GetControlCluster(from) == NULL ||
+      (from->op()->ControlInputCount() > 0 &&
+       NodeProperties::GetControlInput(from) != to)) {
+    os_ << ":I" << index << ":n -> ID" << SafeId(to) << ":s"
         << "[" << (unconstrained ? "constraint=false, " : "")
         << (NodeProperties::IsControlEdge(edge) ? "style=bold, " : "")
         << (NodeProperties::IsEffectEdge(edge) ? "style=dotted, " : "")
         << (NodeProperties::IsContextEdge(edge) ? "style=dashed, " : "") << "]";
   } else {
-    os_ << " -> ID" << to->id() << ":s [color=transparent, "
+    os_ << " -> ID" << SafeId(to) << ":s [color=transparent, "
         << (unconstrained ? "constraint=false, " : "")
         << (NodeProperties::IsControlEdge(edge) ? "style=dashed, " : "") << "]";
   }
@@ -233,50 +377,456 @@
       << "  \n";
 
   // Make sure all nodes have been output before writing out the edges.
-  use_to_def_ = true;
-  // TODO(svenpanne) Remove the need for the const_casts.
-  const_cast<Graph*>(graph_)->VisitNodeInputsFromEnd(this);
-  white_nodes_.insert(const_cast<Graph*>(graph_)->start());
-
-  // Visit all uses of white nodes.
-  use_to_def_ = false;
-  GenericGraphVisit::Visit<GraphVisualizer, NodeUseIterationTraits<Node> >(
-      const_cast<Graph*>(graph_), zone_, white_nodes_.begin(),
-      white_nodes_.end(), this);
-
-  os_ << "  DEAD_INPUT [\n"
-      << "    style=\"filled\" \n"
-      << "    fillcolor=\"" DEAD_COLOR "\"\n"
-      << "  ]\n"
-      << "\n";
+  for (Node* const node : all_.live) PrintNode(node, false);
+  for (Node* const node : all_.gray) PrintNode(node, true);
 
   // With all the nodes written, add the edges.
-  for (NodeSetIter i = all_nodes_.begin(); i != all_nodes_.end(); ++i) {
-    Node::Inputs inputs = (*i)->inputs();
-    for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
-         ++iter) {
-      PrintEdge(iter.edge());
+  for (Node* const node : all_.live) {
+    for (Edge edge : node->use_edges()) {
+      PrintEdge(edge);
     }
   }
   os_ << "}\n";
 }
 
 
-GraphVisualizer::GraphVisualizer(OStream& os, Zone* zone,
-                                 const Graph* graph)  // NOLINT
-    : zone_(zone),
-      all_nodes_(NodeSet::key_compare(), NodeSet::allocator_type(zone)),
-      white_nodes_(NodeSet::key_compare(), NodeSet::allocator_type(zone)),
-      use_to_def_(true),
-      os_(os),
-      graph_(graph) {}
-
-
-OStream& operator<<(OStream& os, const AsDOT& ad) {
+std::ostream& operator<<(std::ostream& os, const AsDOT& ad) {
   Zone tmp_zone(ad.graph.zone()->isolate());
   GraphVisualizer(os, &tmp_zone, &ad.graph).Print();
   return os;
 }
+
+
+class GraphC1Visualizer {
+ public:
+  GraphC1Visualizer(std::ostream& os, Zone* zone);  // NOLINT
+
+  void PrintCompilation(const CompilationInfo* info);
+  void PrintSchedule(const char* phase, const Schedule* schedule,
+                     const SourcePositionTable* positions,
+                     const InstructionSequence* instructions);
+  void PrintAllocator(const char* phase, const RegisterAllocator* allocator);
+  Zone* zone() const { return zone_; }
+
+ private:
+  void PrintIndent();
+  void PrintStringProperty(const char* name, const char* value);
+  void PrintLongProperty(const char* name, int64_t value);
+  void PrintIntProperty(const char* name, int value);
+  void PrintBlockProperty(const char* name, BasicBlock::Id block_id);
+  void PrintNodeId(Node* n);
+  void PrintNode(Node* n);
+  void PrintInputs(Node* n);
+  void PrintInputs(InputIter* i, int count, const char* prefix);
+  void PrintType(Node* node);
+
+  void PrintLiveRange(LiveRange* range, const char* type);
+  class Tag FINAL BASE_EMBEDDED {
+   public:
+    Tag(GraphC1Visualizer* visualizer, const char* name) {
+      name_ = name;
+      visualizer_ = visualizer;
+      visualizer->PrintIndent();
+      visualizer_->os_ << "begin_" << name << "\n";
+      visualizer->indent_++;
+    }
+
+    ~Tag() {
+      visualizer_->indent_--;
+      visualizer_->PrintIndent();
+      visualizer_->os_ << "end_" << name_ << "\n";
+      DCHECK(visualizer_->indent_ >= 0);
+    }
+
+   private:
+    GraphC1Visualizer* visualizer_;
+    const char* name_;
+  };
+
+  std::ostream& os_;
+  int indent_;
+  Zone* zone_;
+
+  DISALLOW_COPY_AND_ASSIGN(GraphC1Visualizer);
+};
+
+
+void GraphC1Visualizer::PrintIndent() {
+  for (int i = 0; i < indent_; i++) {
+    os_ << "  ";
+  }
+}
+
+
+GraphC1Visualizer::GraphC1Visualizer(std::ostream& os, Zone* zone)
+    : os_(os), indent_(0), zone_(zone) {}
+
+
+void GraphC1Visualizer::PrintStringProperty(const char* name,
+                                            const char* value) {
+  PrintIndent();
+  os_ << name << " \"" << value << "\"\n";
+}
+
+
+void GraphC1Visualizer::PrintLongProperty(const char* name, int64_t value) {
+  PrintIndent();
+  os_ << name << " " << static_cast<int>(value / 1000) << "\n";
+}
+
+
+void GraphC1Visualizer::PrintBlockProperty(const char* name,
+                                           BasicBlock::Id block_id) {
+  PrintIndent();
+  os_ << name << " \"B" << block_id << "\"\n";
+}
+
+
+void GraphC1Visualizer::PrintIntProperty(const char* name, int value) {
+  PrintIndent();
+  os_ << name << " " << value << "\n";
+}
+
+
+void GraphC1Visualizer::PrintCompilation(const CompilationInfo* info) {
+  Tag tag(this, "compilation");
+  if (info->IsOptimizing()) {
+    Handle<String> name = info->function()->debug_name();
+    PrintStringProperty("name", name->ToCString().get());
+    PrintIndent();
+    os_ << "method \"" << name->ToCString().get() << ":"
+        << info->optimization_id() << "\"\n";
+  } else {
+    CodeStub::Major major_key = info->code_stub()->MajorKey();
+    PrintStringProperty("name", CodeStub::MajorName(major_key, false));
+    PrintStringProperty("method", "stub");
+  }
+  PrintLongProperty("date",
+                    static_cast<int64_t>(base::OS::TimeCurrentMillis()));
+}
+
+
+void GraphC1Visualizer::PrintNodeId(Node* n) { os_ << "n" << SafeId(n); }
+
+
+void GraphC1Visualizer::PrintNode(Node* n) {
+  PrintNodeId(n);
+  os_ << " " << *n->op() << " ";
+  PrintInputs(n);
+}
+
+
+void GraphC1Visualizer::PrintInputs(InputIter* i, int count,
+                                    const char* prefix) {
+  if (count > 0) {
+    os_ << prefix;
+  }
+  while (count > 0) {
+    os_ << " ";
+    PrintNodeId(**i);
+    ++(*i);
+    count--;
+  }
+}
+
+
+void GraphC1Visualizer::PrintInputs(Node* node) {
+  auto i = node->inputs().begin();
+  PrintInputs(&i, node->op()->ValueInputCount(), " ");
+  PrintInputs(&i, OperatorProperties::GetContextInputCount(node->op()),
+              " Ctx:");
+  PrintInputs(&i, OperatorProperties::GetFrameStateInputCount(node->op()),
+              " FS:");
+  PrintInputs(&i, node->op()->EffectInputCount(), " Eff:");
+  PrintInputs(&i, node->op()->ControlInputCount(), " Ctrl:");
+}
+
+
+void GraphC1Visualizer::PrintType(Node* node) {
+  if (NodeProperties::IsTyped(node)) {
+    Bounds bounds = NodeProperties::GetBounds(node);
+    os_ << " type:";
+    bounds.upper->PrintTo(os_);
+    os_ << "..";
+    bounds.lower->PrintTo(os_);
+  }
+}
+
+
+void GraphC1Visualizer::PrintSchedule(const char* phase,
+                                      const Schedule* schedule,
+                                      const SourcePositionTable* positions,
+                                      const InstructionSequence* instructions) {
+  Tag tag(this, "cfg");
+  PrintStringProperty("name", phase);
+  const BasicBlockVector* rpo = schedule->rpo_order();
+  for (size_t i = 0; i < rpo->size(); i++) {
+    BasicBlock* current = (*rpo)[i];
+    Tag block_tag(this, "block");
+    PrintBlockProperty("name", current->id());
+    PrintIntProperty("from_bci", -1);
+    PrintIntProperty("to_bci", -1);
+
+    PrintIndent();
+    os_ << "predecessors";
+    for (BasicBlock::Predecessors::iterator j = current->predecessors_begin();
+         j != current->predecessors_end(); ++j) {
+      os_ << " \"B" << (*j)->id() << "\"";
+    }
+    os_ << "\n";
+
+    PrintIndent();
+    os_ << "successors";
+    for (BasicBlock::Successors::iterator j = current->successors_begin();
+         j != current->successors_end(); ++j) {
+      os_ << " \"B" << (*j)->id() << "\"";
+    }
+    os_ << "\n";
+
+    PrintIndent();
+    os_ << "xhandlers\n";
+
+    PrintIndent();
+    os_ << "flags\n";
+
+    if (current->dominator() != NULL) {
+      PrintBlockProperty("dominator", current->dominator()->id());
+    }
+
+    PrintIntProperty("loop_depth", current->loop_depth());
+
+    const InstructionBlock* instruction_block =
+        instructions->InstructionBlockAt(current->GetRpoNumber());
+    if (instruction_block->code_start() >= 0) {
+      int first_index = instruction_block->first_instruction_index();
+      int last_index = instruction_block->last_instruction_index();
+      PrintIntProperty("first_lir_id", LifetimePosition::FromInstructionIndex(
+                                           first_index).Value());
+      PrintIntProperty("last_lir_id", LifetimePosition::FromInstructionIndex(
+                                          last_index).Value());
+    }
+
+    {
+      Tag states_tag(this, "states");
+      Tag locals_tag(this, "locals");
+      int total = 0;
+      for (BasicBlock::const_iterator i = current->begin(); i != current->end();
+           ++i) {
+        if ((*i)->opcode() == IrOpcode::kPhi) total++;
+      }
+      PrintIntProperty("size", total);
+      PrintStringProperty("method", "None");
+      int index = 0;
+      for (BasicBlock::const_iterator i = current->begin(); i != current->end();
+           ++i) {
+        if ((*i)->opcode() != IrOpcode::kPhi) continue;
+        PrintIndent();
+        os_ << index << " ";
+        PrintNodeId(*i);
+        os_ << " [";
+        PrintInputs(*i);
+        os_ << "]\n";
+        index++;
+      }
+    }
+
+    {
+      Tag HIR_tag(this, "HIR");
+      for (BasicBlock::const_iterator i = current->begin(); i != current->end();
+           ++i) {
+        Node* node = *i;
+        if (node->opcode() == IrOpcode::kPhi) continue;
+        int uses = node->UseCount();
+        PrintIndent();
+        os_ << "0 " << uses << " ";
+        PrintNode(node);
+        if (FLAG_trace_turbo_types) {
+          os_ << " ";
+          PrintType(node);
+        }
+        if (positions != NULL) {
+          SourcePosition position = positions->GetSourcePosition(node);
+          if (!position.IsUnknown()) {
+            DCHECK(!position.IsInvalid());
+            os_ << " pos:" << position.raw();
+          }
+        }
+        os_ << " <|@\n";
+      }
+
+      BasicBlock::Control control = current->control();
+      if (control != BasicBlock::kNone) {
+        PrintIndent();
+        os_ << "0 0 ";
+        if (current->control_input() != NULL) {
+          PrintNode(current->control_input());
+        } else {
+          os_ << -1 - current->id().ToInt() << " Goto";
+        }
+        os_ << " ->";
+        for (BasicBlock::Successors::iterator j = current->successors_begin();
+             j != current->successors_end(); ++j) {
+          os_ << " B" << (*j)->id();
+        }
+        if (FLAG_trace_turbo_types && current->control_input() != NULL) {
+          os_ << " ";
+          PrintType(current->control_input());
+        }
+        os_ << " <|@\n";
+      }
+    }
+
+    if (instructions != NULL) {
+      Tag LIR_tag(this, "LIR");
+      for (int j = instruction_block->first_instruction_index();
+           j <= instruction_block->last_instruction_index(); j++) {
+        PrintIndent();
+        PrintableInstruction printable = {RegisterConfiguration::ArchDefault(),
+                                          instructions->InstructionAt(j)};
+        os_ << j << " " << printable << " <|@\n";
+      }
+    }
+  }
+}
+
+
+void GraphC1Visualizer::PrintAllocator(const char* phase,
+                                       const RegisterAllocator* allocator) {
+  Tag tag(this, "intervals");
+  PrintStringProperty("name", phase);
+
+  for (auto range : allocator->fixed_double_live_ranges()) {
+    PrintLiveRange(range, "fixed");
+  }
+
+  for (auto range : allocator->fixed_live_ranges()) {
+    PrintLiveRange(range, "fixed");
+  }
+
+  for (auto range : allocator->live_ranges()) {
+    PrintLiveRange(range, "object");
+  }
+}
+
+
+void GraphC1Visualizer::PrintLiveRange(LiveRange* range, const char* type) {
+  if (range != NULL && !range->IsEmpty()) {
+    PrintIndent();
+    os_ << range->id() << " " << type;
+    if (range->HasRegisterAssigned()) {
+      InstructionOperand* op = range->CreateAssignedOperand(zone());
+      int assigned_reg = op->index();
+      if (op->IsDoubleRegister()) {
+        os_ << " \"" << DoubleRegister::AllocationIndexToString(assigned_reg)
+            << "\"";
+      } else {
+        DCHECK(op->IsRegister());
+        os_ << " \"" << Register::AllocationIndexToString(assigned_reg) << "\"";
+      }
+    } else if (range->IsSpilled()) {
+      int index = -1;
+      if (range->TopLevel()->HasSpillRange()) {
+        index = kMaxInt;  // This hasn't been set yet.
+      } else {
+        index = range->TopLevel()->GetSpillOperand()->index();
+      }
+      if (range->TopLevel()->Kind() == DOUBLE_REGISTERS) {
+        os_ << " \"double_stack:" << index << "\"";
+      } else if (range->TopLevel()->Kind() == GENERAL_REGISTERS) {
+        os_ << " \"stack:" << index << "\"";
+      } else {
+        os_ << " \"const(nostack):" << index << "\"";
+      }
+    }
+    int parent_index = -1;
+    if (range->IsChild()) {
+      parent_index = range->parent()->id();
+    } else {
+      parent_index = range->id();
+    }
+    InstructionOperand* op = range->FirstHint();
+    int hint_index = -1;
+    if (op != NULL && op->IsUnallocated()) {
+      hint_index = UnallocatedOperand::cast(op)->virtual_register();
+    }
+    os_ << " " << parent_index << " " << hint_index;
+    UseInterval* cur_interval = range->first_interval();
+    while (cur_interval != NULL && range->Covers(cur_interval->start())) {
+      os_ << " [" << cur_interval->start().Value() << ", "
+          << cur_interval->end().Value() << "[";
+      cur_interval = cur_interval->next();
+    }
+
+    UsePosition* current_pos = range->first_pos();
+    while (current_pos != NULL) {
+      if (current_pos->RegisterIsBeneficial() || FLAG_trace_all_uses) {
+        os_ << " " << current_pos->pos().Value() << " M";
+      }
+      current_pos = current_pos->next();
+    }
+
+    os_ << " \"\"\n";
+  }
+}
+
+
+std::ostream& operator<<(std::ostream& os, const AsC1VCompilation& ac) {
+  Zone tmp_zone(ac.info_->isolate());
+  GraphC1Visualizer(os, &tmp_zone).PrintCompilation(ac.info_);
+  return os;
+}
+
+
+std::ostream& operator<<(std::ostream& os, const AsC1V& ac) {
+  Zone tmp_zone(ac.schedule_->zone()->isolate());
+  GraphC1Visualizer(os, &tmp_zone)
+      .PrintSchedule(ac.phase_, ac.schedule_, ac.positions_, ac.instructions_);
+  return os;
+}
+
+
+std::ostream& operator<<(std::ostream& os, const AsC1VAllocator& ac) {
+  Zone tmp_zone(ac.allocator_->code()->zone()->isolate());
+  GraphC1Visualizer(os, &tmp_zone).PrintAllocator(ac.phase_, ac.allocator_);
+  return os;
+}
+
+const int kUnvisited = 0;
+const int kOnStack = 1;
+const int kVisited = 2;
+
+std::ostream& operator<<(std::ostream& os, const AsRPO& ar) {
+  Zone local_zone(ar.graph.zone()->isolate());
+  ZoneVector<byte> state(ar.graph.NodeCount(), kUnvisited, &local_zone);
+  ZoneStack<Node*> stack(&local_zone);
+
+  stack.push(ar.graph.end());
+  state[ar.graph.end()->id()] = kOnStack;
+  while (!stack.empty()) {
+    Node* n = stack.top();
+    bool pop = true;
+    for (Node* const i : n->inputs()) {
+      if (state[i->id()] == kUnvisited) {
+        state[i->id()] = kOnStack;
+        stack.push(i);
+        pop = false;
+        break;
+      }
+    }
+    if (pop) {
+      state[n->id()] = kVisited;
+      stack.pop();
+      os << "#" << SafeId(n) << ":" << SafeMnemonic(n) << "(";
+      int j = 0;
+      for (Node* const i : n->inputs()) {
+        if (j++ > 0) os << ", ";
+        os << "#" << SafeId(i) << ":" << SafeMnemonic(i);
+      }
+      os << ")" << std::endl;
+    }
+  }
+  return os;
+}
 }
 }
 }  // namespace v8::internal::compiler
diff --git a/src/compiler/graph-visualizer.h b/src/compiler/graph-visualizer.h
index 12532ba..3dd66ea 100644
--- a/src/compiler/graph-visualizer.h
+++ b/src/compiler/graph-visualizer.h
@@ -5,25 +5,80 @@
 #ifndef V8_COMPILER_GRAPH_VISUALIZER_H_
 #define V8_COMPILER_GRAPH_VISUALIZER_H_
 
-#include "src/v8.h"
+#include <iosfwd>
 
 namespace v8 {
 namespace internal {
 
-class OStream;
+class CompilationInfo;
 
 namespace compiler {
 
 class Graph;
+class InstructionSequence;
+class RegisterAllocator;
+class Schedule;
+class SourcePositionTable;
+
 
 struct AsDOT {
   explicit AsDOT(const Graph& g) : graph(g) {}
   const Graph& graph;
 };
 
-OStream& operator<<(OStream& os, const AsDOT& ad);
-}
-}
-}  // namespace v8::internal::compiler
+std::ostream& operator<<(std::ostream& os, const AsDOT& ad);
+
+
+struct AsJSON {
+  explicit AsJSON(const Graph& g) : graph(g) {}
+  const Graph& graph;
+};
+
+std::ostream& operator<<(std::ostream& os, const AsJSON& ad);
+
+struct AsRPO {
+  explicit AsRPO(const Graph& g) : graph(g) {}
+  const Graph& graph;
+};
+
+std::ostream& operator<<(std::ostream& os, const AsRPO& ad);
+
+
+struct AsC1VCompilation {
+  explicit AsC1VCompilation(const CompilationInfo* info) : info_(info) {}
+  const CompilationInfo* info_;
+};
+
+
+struct AsC1V {
+  AsC1V(const char* phase, const Schedule* schedule,
+        const SourcePositionTable* positions = NULL,
+        const InstructionSequence* instructions = NULL)
+      : schedule_(schedule),
+        instructions_(instructions),
+        positions_(positions),
+        phase_(phase) {}
+  const Schedule* schedule_;
+  const InstructionSequence* instructions_;
+  const SourcePositionTable* positions_;
+  const char* phase_;
+};
+
+struct AsC1VAllocator {
+  explicit AsC1VAllocator(const char* phase,
+                          const RegisterAllocator* allocator = NULL)
+      : phase_(phase), allocator_(allocator) {}
+  const char* phase_;
+  const RegisterAllocator* allocator_;
+};
+
+std::ostream& operator<<(std::ostream& os, const AsDOT& ad);
+std::ostream& operator<<(std::ostream& os, const AsC1VCompilation& ac);
+std::ostream& operator<<(std::ostream& os, const AsC1V& ac);
+std::ostream& operator<<(std::ostream& os, const AsC1VAllocator& ac);
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_GRAPH_VISUALIZER_H_
diff --git a/src/compiler/graph.cc b/src/compiler/graph.cc
index 7b5f228..995046b 100644
--- a/src/compiler/graph.cc
+++ b/src/compiler/graph.cc
@@ -5,29 +5,42 @@
 #include "src/compiler/graph.h"
 
 #include "src/compiler/common-operator.h"
-#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/graph-inl.h"
 #include "src/compiler/node.h"
 #include "src/compiler/node-aux-data-inl.h"
 #include "src/compiler/node-properties.h"
 #include "src/compiler/node-properties-inl.h"
+#include "src/compiler/opcodes.h"
 #include "src/compiler/operator-properties.h"
-#include "src/compiler/operator-properties-inl.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-Graph::Graph(Zone* zone) : GenericGraph<Node>(zone), decorators_(zone) {}
+Graph::Graph(Zone* zone)
+    : zone_(zone),
+      start_(NULL),
+      end_(NULL),
+      mark_max_(0),
+      next_node_id_(0),
+      decorators_(zone) {}
 
 
-Node* Graph::NewNode(const Operator* op, int input_count, Node** inputs) {
-  DCHECK_LE(op->InputCount(), input_count);
-  Node* result = Node::New(this, input_count, inputs);
-  result->Initialize(op);
+void Graph::Decorate(Node* node) {
   for (ZoneVector<GraphDecorator*>::iterator i = decorators_.begin();
        i != decorators_.end(); ++i) {
-    (*i)->Decorate(result);
+    (*i)->Decorate(node);
+  }
+}
+
+
+Node* Graph::NewNode(const Operator* op, int input_count, Node** inputs,
+                     bool incomplete) {
+  DCHECK_LE(op->ValueInputCount(), input_count);
+  Node* result = Node::New(this, input_count, inputs, incomplete);
+  result->Initialize(op);
+  if (!incomplete) {
+    Decorate(result);
   }
   return result;
 }
diff --git a/src/compiler/graph.h b/src/compiler/graph.h
index 07eb02f..d619da2 100644
--- a/src/compiler/graph.h
+++ b/src/compiler/graph.h
@@ -8,7 +8,6 @@
 #include <map>
 #include <set>
 
-#include "src/compiler/generic-algorithm.h"
 #include "src/compiler/node.h"
 #include "src/compiler/node-aux-data.h"
 #include "src/compiler/source-position.h"
@@ -17,19 +16,21 @@
 namespace internal {
 namespace compiler {
 
+// Forward declarations.
 class GraphDecorator;
 
 
-class Graph : public GenericGraph<Node> {
+class Graph : public ZoneObject {
  public:
   explicit Graph(Zone* zone);
 
   // Base implementation used by all factory methods.
-  Node* NewNode(const Operator* op, int input_count, Node** inputs);
+  Node* NewNode(const Operator* op, int input_count, Node** inputs,
+                bool incomplete = false);
 
   // Factories for nodes with static input counts.
   Node* NewNode(const Operator* op) {
-    return NewNode(op, 0, static_cast<Node**>(NULL));
+    return NewNode(op, 0, static_cast<Node**>(nullptr));
   }
   Node* NewNode(const Operator* op, Node* n1) { return NewNode(op, 1, &n1); }
   Node* NewNode(const Operator* op, Node* n1, Node* n2) {
@@ -54,15 +55,26 @@
     Node* nodes[] = {n1, n2, n3, n4, n5, n6};
     return NewNode(op, arraysize(nodes), nodes);
   }
+  Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4,
+                Node* n5, Node* n6, Node* n7) {
+    Node* nodes[] = {n1, n2, n3, n4, n5, n6, n7};
+    return NewNode(op, arraysize(nodes), nodes);
+  }
 
   template <class Visitor>
-  void VisitNodeUsesFrom(Node* node, Visitor* visitor);
+  inline void VisitNodeInputsFromEnd(Visitor* visitor);
 
-  template <class Visitor>
-  void VisitNodeUsesFromStart(Visitor* visitor);
+  Zone* zone() const { return zone_; }
+  Node* start() const { return start_; }
+  Node* end() const { return end_; }
 
-  template <class Visitor>
-  void VisitNodeInputsFromEnd(Visitor* visitor);
+  void SetStart(Node* start) { start_ = start; }
+  void SetEnd(Node* end) { end_ = end; }
+
+  NodeId NextNodeID() { return next_node_id_++; }
+  NodeId NodeCount() const { return next_node_id_; }
+
+  void Decorate(Node* node);
 
   void AddDecorator(GraphDecorator* decorator) {
     decorators_.push_back(decorator);
@@ -76,10 +88,56 @@
   }
 
  private:
+  template <typename State>
+  friend class NodeMarker;
+
+  Zone* zone_;
+  Node* start_;
+  Node* end_;
+  Mark mark_max_;
+  NodeId next_node_id_;
   ZoneVector<GraphDecorator*> decorators_;
+
+  DISALLOW_COPY_AND_ASSIGN(Graph);
 };
 
 
+// A NodeMarker uses monotonically increasing marks to assign local "states"
+// to nodes. Only one NodeMarker per graph is valid at a given time.
+template <typename State>
+class NodeMarker BASE_EMBEDDED {
+ public:
+  NodeMarker(Graph* graph, uint32_t num_states)
+      : mark_min_(graph->mark_max_), mark_max_(graph->mark_max_ += num_states) {
+    DCHECK(num_states > 0);         // user error!
+    DCHECK(mark_max_ > mark_min_);  // check for wraparound.
+  }
+
+  State Get(Node* node) {
+    Mark mark = node->mark();
+    if (mark < mark_min_) {
+      mark = mark_min_;
+      node->set_mark(mark_min_);
+    }
+    DCHECK_LT(mark, mark_max_);
+    return static_cast<State>(mark - mark_min_);
+  }
+
+  void Set(Node* node, State state) {
+    Mark local = static_cast<Mark>(state);
+    DCHECK(local < (mark_max_ - mark_min_));
+    DCHECK_LT(node->mark(), mark_max_);
+    node->set_mark(local + mark_min_);
+  }
+
+ private:
+  Mark mark_min_;
+  Mark mark_max_;
+};
+
+
+// A graph decorator can be used to add behavior to the creation of nodes
+// in a graph.
 class GraphDecorator : public ZoneObject {
  public:
   virtual ~GraphDecorator() {}
diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc
index deab7cd..55f7426 100644
--- a/src/compiler/ia32/code-generator-ia32.cc
+++ b/src/compiler/ia32/code-generator-ia32.cc
@@ -33,8 +33,6 @@
 
   Operand OutputOperand() { return ToOperand(instr_->Output()); }
 
-  Operand TempOperand(int index) { return ToOperand(instr_->TempAt(index)); }
-
   Operand ToOperand(InstructionOperand* op, int extra = 0) {
     if (op->IsRegister()) {
       DCHECK(extra == 0);
@@ -59,6 +57,9 @@
     switch (constant.type()) {
       case Constant::kInt32:
         return Immediate(constant.ToInt32());
+      case Constant::kFloat32:
+        return Immediate(
+            isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
       case Constant::kFloat64:
         return Immediate(
             isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
@@ -68,44 +69,216 @@
         return Immediate(constant.ToHeapObject());
       case Constant::kInt64:
         break;
+      case Constant::kRpoNumber:
+        return Immediate::CodeRelativeOffset(ToLabel(operand));
     }
     UNREACHABLE();
     return Immediate(-1);
   }
 
-  Operand MemoryOperand(int* first_input) {
-    const int offset = *first_input;
-    switch (AddressingModeField::decode(instr_->opcode())) {
-      case kMode_MR1I:
-        *first_input += 2;
-        return Operand(InputRegister(offset + 0), InputRegister(offset + 1),
-                       times_1,
-                       0);  // TODO(dcarney): K != 0
-      case kMode_MRI:
-        *first_input += 2;
-        return Operand::ForRegisterPlusImmediate(InputRegister(offset + 0),
-                                                 InputImmediate(offset + 1));
-      case kMode_MI:
-        *first_input += 1;
-        return Operand(InputImmediate(offset + 0));
-      default:
-        UNREACHABLE();
-        return Operand(no_reg);
-    }
+  static int NextOffset(int* offset) {
+    int i = *offset;
+    (*offset)++;
+    return i;
   }
 
-  Operand MemoryOperand() {
-    int first_input = 0;
+  static ScaleFactor ScaleFor(AddressingMode one, AddressingMode mode) {
+    STATIC_ASSERT(0 == static_cast<int>(times_1));
+    STATIC_ASSERT(1 == static_cast<int>(times_2));
+    STATIC_ASSERT(2 == static_cast<int>(times_4));
+    STATIC_ASSERT(3 == static_cast<int>(times_8));
+    int scale = static_cast<int>(mode - one);
+    DCHECK(scale >= 0 && scale < 4);
+    return static_cast<ScaleFactor>(scale);
+  }
+
+  Operand MemoryOperand(int* offset) {
+    AddressingMode mode = AddressingModeField::decode(instr_->opcode());
+    switch (mode) {
+      case kMode_MR: {
+        Register base = InputRegister(NextOffset(offset));
+        int32_t disp = 0;
+        return Operand(base, disp);
+      }
+      case kMode_MRI: {
+        Register base = InputRegister(NextOffset(offset));
+        int32_t disp = InputInt32(NextOffset(offset));
+        return Operand(base, disp);
+      }
+      case kMode_MR1:
+      case kMode_MR2:
+      case kMode_MR4:
+      case kMode_MR8: {
+        Register base = InputRegister(NextOffset(offset));
+        Register index = InputRegister(NextOffset(offset));
+        ScaleFactor scale = ScaleFor(kMode_MR1, mode);
+        int32_t disp = 0;
+        return Operand(base, index, scale, disp);
+      }
+      case kMode_MR1I:
+      case kMode_MR2I:
+      case kMode_MR4I:
+      case kMode_MR8I: {
+        Register base = InputRegister(NextOffset(offset));
+        Register index = InputRegister(NextOffset(offset));
+        ScaleFactor scale = ScaleFor(kMode_MR1I, mode);
+        int32_t disp = InputInt32(NextOffset(offset));
+        return Operand(base, index, scale, disp);
+      }
+      case kMode_M1:
+      case kMode_M2:
+      case kMode_M4:
+      case kMode_M8: {
+        Register index = InputRegister(NextOffset(offset));
+        ScaleFactor scale = ScaleFor(kMode_M1, mode);
+        int32_t disp = 0;
+        return Operand(index, scale, disp);
+      }
+      case kMode_M1I:
+      case kMode_M2I:
+      case kMode_M4I:
+      case kMode_M8I: {
+        Register index = InputRegister(NextOffset(offset));
+        ScaleFactor scale = ScaleFor(kMode_M1I, mode);
+        int32_t disp = InputInt32(NextOffset(offset));
+        return Operand(index, scale, disp);
+      }
+      case kMode_MI: {
+        int32_t disp = InputInt32(NextOffset(offset));
+        return Operand(Immediate(disp));
+      }
+      case kMode_None:
+        UNREACHABLE();
+        return Operand(no_reg, 0);
+    }
+    UNREACHABLE();
+    return Operand(no_reg, 0);
+  }
+
+  Operand MemoryOperand(int first_input = 0) {
     return MemoryOperand(&first_input);
   }
 };
 
 
-static bool HasImmediateInput(Instruction* instr, int index) {
+namespace {
+
+bool HasImmediateInput(Instruction* instr, int index) {
   return instr->InputAt(index)->IsImmediate();
 }
 
 
+class OutOfLineLoadInteger FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadInteger(CodeGenerator* gen, Register result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL { __ xor_(result_, result_); }
+
+ private:
+  Register const result_;
+};
+
+
+class OutOfLineLoadFloat FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL { __ pcmpeqd(result_, result_); }
+
+ private:
+  XMMRegister const result_;
+};
+
+
+class OutOfLineTruncateDoubleToI FINAL : public OutOfLineCode {
+ public:
+  OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result,
+                             XMMRegister input)
+      : OutOfLineCode(gen), result_(result), input_(input) {}
+
+  void Generate() FINAL {
+    __ sub(esp, Immediate(kDoubleSize));
+    __ movsd(MemOperand(esp, 0), input_);
+    __ SlowTruncateToI(result_, esp, 0);
+    __ add(esp, Immediate(kDoubleSize));
+  }
+
+ private:
+  Register const result_;
+  XMMRegister const input_;
+};
+
+}  // namespace
+
+
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr)                          \
+  do {                                                                  \
+    auto result = i.OutputDoubleRegister();                             \
+    auto offset = i.InputRegister(0);                                   \
+    if (instr->InputAt(1)->IsRegister()) {                              \
+      __ cmp(offset, i.InputRegister(1));                               \
+    } else {                                                            \
+      __ cmp(offset, i.InputImmediate(1));                              \
+    }                                                                   \
+    OutOfLineCode* ool = new (zone()) OutOfLineLoadFloat(this, result); \
+    __ j(above_equal, ool->entry());                                    \
+    __ asm_instr(result, i.MemoryOperand(2));                           \
+    __ bind(ool->exit());                                               \
+  } while (false)
+
+
+#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr)                          \
+  do {                                                                    \
+    auto result = i.OutputRegister();                                     \
+    auto offset = i.InputRegister(0);                                     \
+    if (instr->InputAt(1)->IsRegister()) {                                \
+      __ cmp(offset, i.InputRegister(1));                                 \
+    } else {                                                              \
+      __ cmp(offset, i.InputImmediate(1));                                \
+    }                                                                     \
+    OutOfLineCode* ool = new (zone()) OutOfLineLoadInteger(this, result); \
+    __ j(above_equal, ool->entry());                                      \
+    __ asm_instr(result, i.MemoryOperand(2));                             \
+    __ bind(ool->exit());                                                 \
+  } while (false)
+
+
+#define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr)                 \
+  do {                                                          \
+    auto offset = i.InputRegister(0);                           \
+    if (instr->InputAt(1)->IsRegister()) {                      \
+      __ cmp(offset, i.InputRegister(1));                       \
+    } else {                                                    \
+      __ cmp(offset, i.InputImmediate(1));                      \
+    }                                                           \
+    Label done;                                                 \
+    __ j(above_equal, &done, Label::kNear);                     \
+    __ asm_instr(i.MemoryOperand(3), i.InputDoubleRegister(2)); \
+    __ bind(&done);                                             \
+  } while (false)
+
+
+#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr)            \
+  do {                                                       \
+    auto offset = i.InputRegister(0);                        \
+    if (instr->InputAt(1)->IsRegister()) {                   \
+      __ cmp(offset, i.InputRegister(1));                    \
+    } else {                                                 \
+      __ cmp(offset, i.InputImmediate(1));                   \
+    }                                                        \
+    Label done;                                              \
+    __ j(above_equal, &done, Label::kNear);                  \
+    if (instr->InputAt(2)->IsRegister()) {                   \
+      __ asm_instr(i.MemoryOperand(3), i.InputRegister(2));  \
+    } else {                                                 \
+      __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \
+    }                                                        \
+    __ bind(&done);                                          \
+  } while (false)
+
+
 // Assembles an instruction after register allocation, producing machine code.
 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
   IA32OperandConverter i(this, instr);
@@ -136,7 +309,7 @@
       break;
     }
     case kArchJmp:
-      __ jmp(code()->GetLabel(i.InputBlock(0)));
+      AssembleArchJump(i.InputRpo(0));
       break;
     case kArchNop:
       // don't emit code for nops.
@@ -144,9 +317,19 @@
     case kArchRet:
       AssembleReturn();
       break;
-    case kArchTruncateDoubleToI:
-      __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
+    case kArchStackPointer:
+      __ mov(i.OutputRegister(), esp);
       break;
+    case kArchTruncateDoubleToI: {
+      auto result = i.OutputRegister();
+      auto input = i.InputDoubleRegister(0);
+      auto ool = new (zone()) OutOfLineTruncateDoubleToI(this, result, input);
+      __ cvttsd2si(result, Operand(input));
+      __ cmp(result, 1);
+      __ j(overflow, ool->entry());
+      __ bind(ool->exit());
+      break;
+    }
     case kIA32Add:
       if (HasImmediateInput(instr, 1)) {
         __ add(i.InputOperand(0), i.InputImmediate(1));
@@ -182,12 +365,18 @@
         __ imul(i.OutputRegister(), i.InputOperand(1));
       }
       break;
+    case kIA32ImulHigh:
+      __ imul(i.InputRegister(1));
+      break;
+    case kIA32UmulHigh:
+      __ mul(i.InputRegister(1));
+      break;
     case kIA32Idiv:
       __ cdq();
       __ idiv(i.InputOperand(1));
       break;
     case kIA32Udiv:
-      __ xor_(edx, edx);
+      __ Move(edx, Immediate(0));
       __ div(i.InputOperand(1));
       break;
     case kIA32Not:
@@ -219,46 +408,46 @@
       break;
     case kIA32Shl:
       if (HasImmediateInput(instr, 1)) {
-        __ shl(i.OutputRegister(), i.InputInt5(1));
+        __ shl(i.OutputOperand(), i.InputInt5(1));
       } else {
-        __ shl_cl(i.OutputRegister());
+        __ shl_cl(i.OutputOperand());
       }
       break;
     case kIA32Shr:
       if (HasImmediateInput(instr, 1)) {
-        __ shr(i.OutputRegister(), i.InputInt5(1));
+        __ shr(i.OutputOperand(), i.InputInt5(1));
       } else {
-        __ shr_cl(i.OutputRegister());
+        __ shr_cl(i.OutputOperand());
       }
       break;
     case kIA32Sar:
       if (HasImmediateInput(instr, 1)) {
-        __ sar(i.OutputRegister(), i.InputInt5(1));
+        __ sar(i.OutputOperand(), i.InputInt5(1));
       } else {
-        __ sar_cl(i.OutputRegister());
+        __ sar_cl(i.OutputOperand());
       }
       break;
     case kIA32Ror:
       if (HasImmediateInput(instr, 1)) {
-        __ ror(i.OutputRegister(), i.InputInt5(1));
+        __ ror(i.OutputOperand(), i.InputInt5(1));
       } else {
-        __ ror_cl(i.OutputRegister());
+        __ ror_cl(i.OutputOperand());
       }
       break;
     case kSSEFloat64Cmp:
       __ ucomisd(i.InputDoubleRegister(0), i.InputOperand(1));
       break;
     case kSSEFloat64Add:
-      __ addsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      __ addsd(i.InputDoubleRegister(0), i.InputOperand(1));
       break;
     case kSSEFloat64Sub:
-      __ subsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      __ subsd(i.InputDoubleRegister(0), i.InputOperand(1));
       break;
     case kSSEFloat64Mul:
-      __ mulsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      __ mulsd(i.InputDoubleRegister(0), i.InputOperand(1));
       break;
     case kSSEFloat64Div:
-      __ divsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      __ divsd(i.InputDoubleRegister(0), i.InputOperand(1));
       break;
     case kSSEFloat64Mod: {
       // TODO(dcarney): alignment is wrong.
@@ -288,6 +477,30 @@
     case kSSEFloat64Sqrt:
       __ sqrtsd(i.OutputDoubleRegister(), i.InputOperand(0));
       break;
+    case kSSEFloat64Floor: {
+      CpuFeatureScope sse_scope(masm(), SSE4_1);
+      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                 v8::internal::Assembler::kRoundDown);
+      break;
+    }
+    case kSSEFloat64Ceil: {
+      CpuFeatureScope sse_scope(masm(), SSE4_1);
+      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                 v8::internal::Assembler::kRoundUp);
+      break;
+    }
+    case kSSEFloat64RoundTruncate: {
+      CpuFeatureScope sse_scope(masm(), SSE4_1);
+      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                 v8::internal::Assembler::kRoundToZero);
+      break;
+    }
+    case kSSECvtss2sd:
+      __ cvtss2sd(i.OutputDoubleRegister(), i.InputOperand(0));
+      break;
+    case kSSECvtsd2ss:
+      __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0));
+      break;
     case kSSEFloat64ToInt32:
       __ cvttsd2si(i.OutputRegister(), i.InputOperand(0));
       break;
@@ -303,9 +516,32 @@
       __ cvtsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
       break;
     case kSSEUint32ToFloat64:
-      // TODO(turbofan): IA32 SSE LoadUint32() should take an operand.
-      __ LoadUint32(i.OutputDoubleRegister(), i.InputRegister(0));
+      __ LoadUint32(i.OutputDoubleRegister(), i.InputOperand(0));
       break;
+    case kAVXFloat64Add: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vaddsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                i.InputOperand(1));
+      break;
+    }
+    case kAVXFloat64Sub: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vsubsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                i.InputOperand(1));
+      break;
+    }
+    case kAVXFloat64Mul: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vmulsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                i.InputOperand(1));
+      break;
+    }
+    case kAVXFloat64Div: {
+      CpuFeatureScope avx_scope(masm(), AVX);
+      __ vdivsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                i.InputOperand(1));
+      break;
+    }
     case kIA32Movsxbl:
       __ movsx_b(i.OutputRegister(), i.MemoryOperand());
       break;
@@ -363,14 +599,47 @@
     case kIA32Movss:
       if (instr->HasOutput()) {
         __ movss(i.OutputDoubleRegister(), i.MemoryOperand());
-        __ cvtss2sd(i.OutputDoubleRegister(), i.OutputDoubleRegister());
       } else {
         int index = 0;
         Operand operand = i.MemoryOperand(&index);
-        __ cvtsd2ss(xmm0, i.InputDoubleRegister(index));
-        __ movss(operand, xmm0);
+        __ movss(operand, i.InputDoubleRegister(index));
       }
       break;
+    case kIA32Lea: {
+      AddressingMode mode = AddressingModeField::decode(instr->opcode());
+      // Shorten "leal" to "addl", "subl" or "shll" if the register allocation
+      // and addressing mode just happens to work out. The "addl"/"subl" forms
+      // in these cases are faster based on measurements.
+      if (mode == kMode_MI) {
+        __ Move(i.OutputRegister(), Immediate(i.InputInt32(0)));
+      } else if (i.InputRegister(0).is(i.OutputRegister())) {
+        if (mode == kMode_MRI) {
+          int32_t constant_summand = i.InputInt32(1);
+          if (constant_summand > 0) {
+            __ add(i.OutputRegister(), Immediate(constant_summand));
+          } else if (constant_summand < 0) {
+            __ sub(i.OutputRegister(), Immediate(-constant_summand));
+          }
+        } else if (mode == kMode_MR1) {
+          if (i.InputRegister(1).is(i.OutputRegister())) {
+            __ shl(i.OutputRegister(), 1);
+          } else {
+            __ lea(i.OutputRegister(), i.MemoryOperand());
+          }
+        } else if (mode == kMode_M2) {
+          __ shl(i.OutputRegister(), 1);
+        } else if (mode == kMode_M4) {
+          __ shl(i.OutputRegister(), 2);
+        } else if (mode == kMode_M8) {
+          __ shl(i.OutputRegister(), 3);
+        } else {
+          __ lea(i.OutputRegister(), i.MemoryOperand());
+        }
+      } else {
+        __ lea(i.OutputRegister(), i.MemoryOperand());
+      }
+      break;
+    }
     case kIA32Push:
       if (HasImmediateInput(instr, 0)) {
         __ push(i.InputImmediate(0));
@@ -384,31 +653,59 @@
       Register value = i.InputRegister(2);
       __ mov(Operand(object, index, times_1, 0), value);
       __ lea(index, Operand(object, index, times_1, 0));
-      SaveFPRegsMode mode = code_->frame()->DidAllocateDoubleRegisters()
-                                ? kSaveFPRegs
-                                : kDontSaveFPRegs;
+      SaveFPRegsMode mode =
+          frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
       __ RecordWrite(object, index, value, mode);
       break;
     }
+    case kCheckedLoadInt8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_b);
+      break;
+    case kCheckedLoadUint8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_b);
+      break;
+    case kCheckedLoadInt16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_w);
+      break;
+    case kCheckedLoadUint16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_w);
+      break;
+    case kCheckedLoadWord32:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(mov);
+      break;
+    case kCheckedLoadFloat32:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(movss);
+      break;
+    case kCheckedLoadFloat64:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(movsd);
+      break;
+    case kCheckedStoreWord8:
+      ASSEMBLE_CHECKED_STORE_INTEGER(mov_b);
+      break;
+    case kCheckedStoreWord16:
+      ASSEMBLE_CHECKED_STORE_INTEGER(mov_w);
+      break;
+    case kCheckedStoreWord32:
+      ASSEMBLE_CHECKED_STORE_INTEGER(mov);
+      break;
+    case kCheckedStoreFloat32:
+      ASSEMBLE_CHECKED_STORE_FLOAT(movss);
+      break;
+    case kCheckedStoreFloat64:
+      ASSEMBLE_CHECKED_STORE_FLOAT(movsd);
+      break;
   }
 }
 
 
-// Assembles branches after an instruction.
-void CodeGenerator::AssembleArchBranch(Instruction* instr,
-                                       FlagsCondition condition) {
+// Assembles a branch after an instruction.
+void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
   IA32OperandConverter i(this, instr);
-  Label done;
-
-  // Emit a branch. The true and false targets are always the last two inputs
-  // to the instruction.
-  BasicBlock* tblock = i.InputBlock(instr->InputCount() - 2);
-  BasicBlock* fblock = i.InputBlock(instr->InputCount() - 1);
-  bool fallthru = IsNextInAssemblyOrder(fblock);
-  Label* tlabel = code()->GetLabel(tblock);
-  Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
-  Label::Distance flabel_distance = fallthru ? Label::kNear : Label::kFar;
-  switch (condition) {
+  Label::Distance flabel_distance =
+      branch->fallthru ? Label::kNear : Label::kFar;
+  Label* tlabel = branch->true_label;
+  Label* flabel = branch->false_label;
+  switch (branch->condition) {
     case kUnorderedEqual:
       __ j(parity_even, flabel, flabel_distance);
     // Fall through.
@@ -464,8 +761,13 @@
       __ j(no_overflow, tlabel);
       break;
   }
-  if (!fallthru) __ jmp(flabel, flabel_distance);  // no fallthru to flabel.
-  __ bind(&done);
+  // Add a jump if not falling through to the next block.
+  if (!branch->fallthru) __ jmp(flabel);
+}
+
+
+void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+  if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
 }
 
 
@@ -484,7 +786,7 @@
   switch (condition) {
     case kUnorderedEqual:
       __ j(parity_odd, &check, Label::kNear);
-      __ mov(reg, Immediate(0));
+      __ Move(reg, Immediate(0));
       __ jmp(&done, Label::kNear);
     // Fall through.
     case kEqual:
@@ -512,7 +814,7 @@
       break;
     case kUnorderedLessThan:
       __ j(parity_odd, &check, Label::kNear);
-      __ mov(reg, Immediate(0));
+      __ Move(reg, Immediate(0));
       __ jmp(&done, Label::kNear);
     // Fall through.
     case kUnsignedLessThan:
@@ -528,7 +830,7 @@
       break;
     case kUnorderedLessThanOrEqual:
       __ j(parity_odd, &check, Label::kNear);
-      __ mov(reg, Immediate(0));
+      __ Move(reg, Immediate(0));
       __ jmp(&done, Label::kNear);
     // Fall through.
     case kUnsignedLessThanOrEqual:
@@ -558,7 +860,7 @@
     // Emit a branch to set a register to either 1 or 0.
     Label set;
     __ j(cc, &set, Label::kNear);
-    __ mov(reg, Immediate(0));
+    __ Move(reg, Immediate(0));
     __ jmp(&done, Label::kNear);
     __ bind(&set);
     __ mov(reg, Immediate(1));
@@ -704,7 +1006,7 @@
 
 void CodeGenerator::AssemblePrologue() {
   CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
-  Frame* frame = code_->frame();
+  Frame* frame = this->frame();
   int stack_slots = frame->GetSpillSlotCount();
   if (descriptor->kind() == CallDescriptor::kCallAddress) {
     // Assemble a prologue similar the to cdecl calling convention.
@@ -721,28 +1023,10 @@
       frame->SetRegisterSaveAreaSize(register_save_area_size);
     }
   } else if (descriptor->IsJSFunctionCall()) {
-    CompilationInfo* info = linkage()->info();
+    CompilationInfo* info = this->info();
     __ Prologue(info->IsCodePreAgingActive());
     frame->SetRegisterSaveAreaSize(
         StandardFrameConstants::kFixedFrameSizeFromFp);
-
-    // Sloppy mode functions and builtins need to replace the receiver with the
-    // global proxy when called as functions (without an explicit receiver
-    // object).
-    // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
-    if (info->strict_mode() == SLOPPY && !info->is_native()) {
-      Label ok;
-      // +2 for return address and saved frame pointer.
-      int receiver_slot = info->scope()->num_parameters() + 2;
-      __ mov(ecx, Operand(ebp, receiver_slot * kPointerSize));
-      __ cmp(ecx, isolate()->factory()->undefined_value());
-      __ j(not_equal, &ok, Label::kNear);
-      __ mov(ecx, GlobalObjectOperand());
-      __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalProxyOffset));
-      __ mov(Operand(ebp, receiver_slot * kPointerSize), ecx);
-      __ bind(&ok);
-    }
-
   } else {
     __ StubPrologue();
     frame->SetRegisterSaveAreaSize(
@@ -831,24 +1115,35 @@
       }
     } else if (destination->IsRegister()) {
       Register dst = g.ToRegister(destination);
-      __ mov(dst, g.ToImmediate(source));
+      __ Move(dst, g.ToImmediate(source));
     } else if (destination->IsStackSlot()) {
       Operand dst = g.ToOperand(destination);
-      __ mov(dst, g.ToImmediate(source));
-    } else {
-      double v = g.ToDouble(source);
-      uint64_t int_val = bit_cast<uint64_t, double>(v);
-      int32_t lower = static_cast<int32_t>(int_val);
-      int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt);
+      __ Move(dst, g.ToImmediate(source));
+    } else if (src_constant.type() == Constant::kFloat32) {
+      // TODO(turbofan): Can we do better here?
+      uint32_t src = bit_cast<uint32_t>(src_constant.ToFloat32());
       if (destination->IsDoubleRegister()) {
         XMMRegister dst = g.ToDoubleRegister(destination);
-        __ Move(dst, v);
+        __ Move(dst, src);
+      } else {
+        DCHECK(destination->IsDoubleStackSlot());
+        Operand dst = g.ToOperand(destination);
+        __ Move(dst, Immediate(src));
+      }
+    } else {
+      DCHECK_EQ(Constant::kFloat64, src_constant.type());
+      uint64_t src = bit_cast<uint64_t>(src_constant.ToFloat64());
+      uint32_t lower = static_cast<uint32_t>(src);
+      uint32_t upper = static_cast<uint32_t>(src >> 32);
+      if (destination->IsDoubleRegister()) {
+        XMMRegister dst = g.ToDoubleRegister(destination);
+        __ Move(dst, src);
       } else {
         DCHECK(destination->IsDoubleStackSlot());
         Operand dst0 = g.ToOperand(destination);
         Operand dst1 = g.HighOperand(destination);
-        __ mov(dst0, Immediate(lower));
-        __ mov(dst1, Immediate(upper));
+        __ Move(dst0, Immediate(lower));
+        __ Move(dst1, Immediate(upper));
       }
     }
   } else if (source->IsDoubleRegister()) {
@@ -908,7 +1203,7 @@
     __ movaps(xmm0, src);
     __ movaps(src, dst);
     __ movaps(dst, xmm0);
-  } else if (source->IsDoubleRegister() && source->IsDoubleStackSlot()) {
+  } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) {
     // XMM register-memory swap.  We rely on having xmm0
     // available as a fixed scratch register.
     XMMRegister reg = g.ToDoubleRegister(source);
@@ -940,7 +1235,7 @@
 
 void CodeGenerator::EnsureSpaceForLazyDeopt() {
   int space_needed = Deoptimizer::patch_size();
-  if (!linkage()->info()->IsStub()) {
+  if (!info()->IsStub()) {
     // Ensure that we have enough space after the previous lazy-bailout
     // instruction for patching the code here.
     int current_pc = masm()->pc_offset();
diff --git a/src/compiler/ia32/instruction-codes-ia32.h b/src/compiler/ia32/instruction-codes-ia32.h
index 0f46088..ec9fd18 100644
--- a/src/compiler/ia32/instruction-codes-ia32.h
+++ b/src/compiler/ia32/instruction-codes-ia32.h
@@ -20,6 +20,8 @@
   V(IA32Xor)                       \
   V(IA32Sub)                       \
   V(IA32Imul)                      \
+  V(IA32ImulHigh)                  \
+  V(IA32UmulHigh)                  \
   V(IA32Idiv)                      \
   V(IA32Udiv)                      \
   V(IA32Not)                       \
@@ -35,10 +37,19 @@
   V(SSEFloat64Div)                 \
   V(SSEFloat64Mod)                 \
   V(SSEFloat64Sqrt)                \
+  V(SSEFloat64Floor)               \
+  V(SSEFloat64Ceil)                \
+  V(SSEFloat64RoundTruncate)       \
+  V(SSECvtss2sd)                   \
+  V(SSECvtsd2ss)                   \
   V(SSEFloat64ToInt32)             \
   V(SSEFloat64ToUint32)            \
   V(SSEInt32ToFloat64)             \
   V(SSEUint32ToFloat64)            \
+  V(AVXFloat64Add)                 \
+  V(AVXFloat64Sub)                 \
+  V(AVXFloat64Mul)                 \
+  V(AVXFloat64Div)                 \
   V(IA32Movsxbl)                   \
   V(IA32Movzxbl)                   \
   V(IA32Movb)                      \
@@ -48,6 +59,7 @@
   V(IA32Movl)                      \
   V(IA32Movss)                     \
   V(IA32Movsd)                     \
+  V(IA32Lea)                       \
   V(IA32Push)                      \
   V(IA32StoreWriteBarrier)
 
@@ -59,23 +71,31 @@
 //
 // We use the following local notation for addressing modes:
 //
-// R = register
-// O = register or stack slot
-// D = double register
-// I = immediate (handle, external, int32)
-// MR = [register]
-// MI = [immediate]
-// MRN = [register + register * N in {1, 2, 4, 8}]
-// MRI = [register + immediate]
-// MRNI = [register + register * N in {1, 2, 4, 8} + immediate]
+// M = memory operand
+// R = base register
+// N = index register * N for N in {1, 2, 4, 8}
+// I = immediate displacement (int32_t)
+
 #define TARGET_ADDRESSING_MODE_LIST(V) \
-  V(MI)   /* [K] */                    \
-  V(MR)   /* [%r0] */                  \
-  V(MRI)  /* [%r0 + K] */              \
-  V(MR1I) /* [%r0 + %r1 * 1 + K] */    \
-  V(MR2I) /* [%r0 + %r1 * 2 + K] */    \
-  V(MR4I) /* [%r0 + %r1 * 4 + K] */    \
-  V(MR8I) /* [%r0 + %r1 * 8 + K] */
+  V(MR)   /* [%r1            ] */      \
+  V(MRI)  /* [%r1         + K] */      \
+  V(MR1)  /* [%r1 + %r2*1    ] */      \
+  V(MR2)  /* [%r1 + %r2*2    ] */      \
+  V(MR4)  /* [%r1 + %r2*4    ] */      \
+  V(MR8)  /* [%r1 + %r2*8    ] */      \
+  V(MR1I) /* [%r1 + %r2*1 + K] */      \
+  V(MR2I) /* [%r1 + %r2*2 + K] */      \
+  V(MR4I) /* [%r1 + %r2*3 + K] */      \
+  V(MR8I) /* [%r1 + %r2*4 + K] */      \
+  V(M1)   /* [      %r2*1    ] */      \
+  V(M2)   /* [      %r2*2    ] */      \
+  V(M4)   /* [      %r2*4    ] */      \
+  V(M8)   /* [      %r2*8    ] */      \
+  V(M1I)  /* [      %r2*1 + K] */      \
+  V(M2I)  /* [      %r2*2 + K] */      \
+  V(M4I)  /* [      %r2*4 + K] */      \
+  V(M8I)  /* [      %r2*8 + K] */      \
+  V(MI)   /* [              K] */
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/ia32/instruction-selector-ia32-unittest.cc b/src/compiler/ia32/instruction-selector-ia32-unittest.cc
deleted file mode 100644
index 60708c1..0000000
--- a/src/compiler/ia32/instruction-selector-ia32-unittest.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/instruction-selector-unittest.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-namespace {
-
-// Immediates (random subset).
-static const int32_t kImmediates[] = {
-    kMinInt, -42, -1, 0,  1,  2,    3,      4,          5,
-    6,       7,   8,  16, 42, 0xff, 0xffff, 0x0f0f0f0f, kMaxInt};
-
-}  // namespace
-
-
-TEST_F(InstructionSelectorTest, Int32AddWithParameter) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32Add(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kIA32Add, s[0]->arch_opcode());
-}
-
-
-TEST_F(InstructionSelectorTest, Int32AddWithImmediate) {
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    {
-      StreamBuilder m(this, kMachInt32, kMachInt32);
-      m.Return(m.Int32Add(m.Parameter(0), m.Int32Constant(imm)));
-      Stream s = m.Build();
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(kIA32Add, s[0]->arch_opcode());
-      ASSERT_EQ(2U, s[0]->InputCount());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    }
-    {
-      StreamBuilder m(this, kMachInt32, kMachInt32);
-      m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)));
-      Stream s = m.Build();
-      ASSERT_EQ(1U, s.size());
-      EXPECT_EQ(kIA32Add, s[0]->arch_opcode());
-      ASSERT_EQ(2U, s[0]->InputCount());
-      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-    }
-  }
-}
-
-
-TEST_F(InstructionSelectorTest, Int32SubWithParameter) {
-  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
-  m.Return(m.Int32Sub(m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kIA32Sub, s[0]->arch_opcode());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_F(InstructionSelectorTest, Int32SubWithImmediate) {
-  TRACED_FOREACH(int32_t, imm, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32);
-    m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(kIA32Sub, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// Loads and stores
-
-namespace {
-
-struct MemoryAccess {
-  MachineType type;
-  ArchOpcode load_opcode;
-  ArchOpcode store_opcode;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
-  OStringStream ost;
-  ost << memacc.type;
-  return os << ost.c_str();
-}
-
-
-static const MemoryAccess kMemoryAccesses[] = {
-    {kMachInt8, kIA32Movsxbl, kIA32Movb},
-    {kMachUint8, kIA32Movzxbl, kIA32Movb},
-    {kMachInt16, kIA32Movsxwl, kIA32Movw},
-    {kMachUint16, kIA32Movzxwl, kIA32Movw},
-    {kMachInt32, kIA32Movl, kIA32Movl},
-    {kMachUint32, kIA32Movl, kIA32Movl},
-    {kMachFloat32, kIA32Movss, kIA32Movss},
-    {kMachFloat64, kIA32Movsd, kIA32Movsd}};
-
-}  // namespace
-
-
-typedef InstructionSelectorTestWithParam<MemoryAccess>
-    InstructionSelectorMemoryAccessTest;
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
-  const MemoryAccess memacc = GetParam();
-  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
-  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateBase) {
-  const MemoryAccess memacc = GetParam();
-  TRACED_FOREACH(int32_t, base, kImmediates) {
-    StreamBuilder m(this, memacc.type, kMachPtr);
-    m.Return(m.Load(memacc.type, m.Int32Constant(base), m.Parameter(0)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
-    EXPECT_EQ(base, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
-  const MemoryAccess memacc = GetParam();
-  TRACED_FOREACH(int32_t, index, kImmediates) {
-    StreamBuilder m(this, memacc.type, kMachPtr);
-    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
-    ASSERT_EQ(2U, s[0]->InputCount());
-    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
-    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(1U, s[0]->OutputCount());
-  }
-}
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
-  const MemoryAccess memacc = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
-  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
-  m.Return(m.Int32Constant(0));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(3U, s[0]->InputCount());
-  EXPECT_EQ(0U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateBase) {
-  const MemoryAccess memacc = GetParam();
-  TRACED_FOREACH(int32_t, base, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachInt32, memacc.type);
-    m.Store(memacc.type, m.Int32Constant(base), m.Parameter(0), m.Parameter(1));
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
-    EXPECT_EQ(base, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(0U, s[0]->OutputCount());
-  }
-}
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
-  const MemoryAccess memacc = GetParam();
-  TRACED_FOREACH(int32_t, index, kImmediates) {
-    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
-    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
-            m.Parameter(1));
-    m.Return(m.Int32Constant(0));
-    Stream s = m.Build();
-    ASSERT_EQ(1U, s.size());
-    EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
-    ASSERT_EQ(3U, s[0]->InputCount());
-    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
-    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
-    EXPECT_EQ(0U, s[0]->OutputCount());
-  }
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
-                        InstructionSelectorMemoryAccessTest,
-                        ::testing::ValuesIn(kMemoryAccesses));
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc
index 24ebc38..16063ab 100644
--- a/src/compiler/ia32/instruction-selector-ia32.cc
+++ b/src/compiler/ia32/instruction-selector-ia32.cc
@@ -37,15 +37,98 @@
         return false;
     }
   }
+
+  AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base,
+                                             Node* displacement_node,
+                                             InstructionOperand* inputs[],
+                                             size_t* input_count) {
+    AddressingMode mode = kMode_MRI;
+    int32_t displacement = (displacement_node == NULL)
+                               ? 0
+                               : OpParameter<int32_t>(displacement_node);
+    if (base != NULL) {
+      if (base->opcode() == IrOpcode::kInt32Constant) {
+        displacement += OpParameter<int32_t>(base);
+        base = NULL;
+      }
+    }
+    if (base != NULL) {
+      inputs[(*input_count)++] = UseRegister(base);
+      if (index != NULL) {
+        DCHECK(scale >= 0 && scale <= 3);
+        inputs[(*input_count)++] = UseRegister(index);
+        if (displacement != 0) {
+          inputs[(*input_count)++] = TempImmediate(displacement);
+          static const AddressingMode kMRnI_modes[] = {kMode_MR1I, kMode_MR2I,
+                                                       kMode_MR4I, kMode_MR8I};
+          mode = kMRnI_modes[scale];
+        } else {
+          static const AddressingMode kMRn_modes[] = {kMode_MR1, kMode_MR2,
+                                                      kMode_MR4, kMode_MR8};
+          mode = kMRn_modes[scale];
+        }
+      } else {
+        if (displacement == 0) {
+          mode = kMode_MR;
+        } else {
+          inputs[(*input_count)++] = TempImmediate(displacement);
+          mode = kMode_MRI;
+        }
+      }
+    } else {
+      DCHECK(scale >= 0 && scale <= 3);
+      if (index != NULL) {
+        inputs[(*input_count)++] = UseRegister(index);
+        if (displacement != 0) {
+          inputs[(*input_count)++] = TempImmediate(displacement);
+          static const AddressingMode kMnI_modes[] = {kMode_MRI, kMode_M2I,
+                                                      kMode_M4I, kMode_M8I};
+          mode = kMnI_modes[scale];
+        } else {
+          static const AddressingMode kMn_modes[] = {kMode_MR, kMode_M2,
+                                                     kMode_M4, kMode_M8};
+          mode = kMn_modes[scale];
+        }
+      } else {
+        inputs[(*input_count)++] = TempImmediate(displacement);
+        return kMode_MI;
+      }
+    }
+    return mode;
+  }
+
+  AddressingMode GetEffectiveAddressMemoryOperand(Node* node,
+                                                  InstructionOperand* inputs[],
+                                                  size_t* input_count) {
+    BaseWithIndexAndDisplacement32Matcher m(node, true);
+    DCHECK(m.matches());
+    if ((m.displacement() == NULL || CanBeImmediate(m.displacement()))) {
+      return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(),
+                                         m.displacement(), inputs, input_count);
+    } else {
+      inputs[(*input_count)++] = UseRegister(node->InputAt(0));
+      inputs[(*input_count)++] = UseRegister(node->InputAt(1));
+      return kMode_MR1;
+    }
+  }
+
+  bool CanBeBetterLeftOperand(Node* node) const {
+    return !selector()->IsLive(node);
+  }
 };
 
 
+static void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
+                           Node* node) {
+  IA32OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)));
+}
+
+
 void InstructionSelector::VisitLoad(Node* node) {
   MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
   MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
-  IA32OperandGenerator g(this);
-  Node* base = node->InputAt(0);
-  Node* index = node->InputAt(1);
 
   ArchOpcode opcode;
   // TODO(titzer): signed/unsigned small loads
@@ -71,23 +154,16 @@
       UNREACHABLE();
       return;
   }
-  if (g.CanBeImmediate(base)) {
-    if (Int32Matcher(index).Is(0)) {  // load [#base + #0]
-      Emit(opcode | AddressingModeField::encode(kMode_MI),
-           g.DefineAsRegister(node), g.UseImmediate(base));
-    } else {  // load [#base + %index]
-      Emit(opcode | AddressingModeField::encode(kMode_MRI),
-           g.DefineAsRegister(node), g.UseRegister(index),
-           g.UseImmediate(base));
-    }
-  } else if (g.CanBeImmediate(index)) {  // load [%base + #index]
-    Emit(opcode | AddressingModeField::encode(kMode_MRI),
-         g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
-  } else {  // load [%base + %index + K]
-    Emit(opcode | AddressingModeField::encode(kMode_MR1I),
-         g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index));
-  }
-  // TODO(turbofan): addressing modes [r+r*{2,4,8}+K]
+
+  IA32OperandGenerator g(this);
+  InstructionOperand* outputs[1];
+  outputs[0] = g.DefineAsRegister(node);
+  InstructionOperand* inputs[3];
+  size_t input_count = 0;
+  AddressingMode mode =
+      g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
+  InstructionCode code = opcode | AddressingModeField::encode(mode);
+  Emit(code, 1, outputs, input_count, inputs);
 }
 
 
@@ -111,14 +187,7 @@
     return;
   }
   DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
-  InstructionOperand* val;
-  if (g.CanBeImmediate(value)) {
-    val = g.UseImmediate(value);
-  } else if (rep == kRepWord8 || rep == kRepBit) {
-    val = g.UseByteRegister(value);
-  } else {
-    val = g.UseRegister(value);
-  }
+
   ArchOpcode opcode;
   switch (rep) {
     case kRepFloat32:
@@ -142,22 +211,114 @@
       UNREACHABLE();
       return;
   }
-  if (g.CanBeImmediate(base)) {
-    if (Int32Matcher(index).Is(0)) {  // store [#base], %|#value
-      Emit(opcode | AddressingModeField::encode(kMode_MI), NULL,
-           g.UseImmediate(base), val);
-    } else {  // store [#base + %index], %|#value
-      Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
-           g.UseRegister(index), g.UseImmediate(base), val);
-    }
-  } else if (g.CanBeImmediate(index)) {  // store [%base + #index], %|#value
-    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
-         g.UseRegister(base), g.UseImmediate(index), val);
-  } else {  // store [%base + %index], %|#value
-    Emit(opcode | AddressingModeField::encode(kMode_MR1I), NULL,
-         g.UseRegister(base), g.UseRegister(index), val);
+
+  InstructionOperand* val;
+  if (g.CanBeImmediate(value)) {
+    val = g.UseImmediate(value);
+  } else if (rep == kRepWord8 || rep == kRepBit) {
+    val = g.UseByteRegister(value);
+  } else {
+    val = g.UseRegister(value);
   }
-  // TODO(turbofan): addressing modes [r+r*{2,4,8}+K]
+
+  InstructionOperand* inputs[4];
+  size_t input_count = 0;
+  AddressingMode mode =
+      g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
+  InstructionCode code = opcode | AddressingModeField::encode(mode);
+  inputs[input_count++] = val;
+  Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs);
+}
+
+
+void InstructionSelector::VisitCheckedLoad(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  IA32OperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepWord8:
+      opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
+      break;
+    case kRepWord16:
+      opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
+      break;
+    case kRepWord32:
+      opcode = kCheckedLoadWord32;
+      break;
+    case kRepFloat32:
+      opcode = kCheckedLoadFloat32;
+      break;
+    case kRepFloat64:
+      opcode = kCheckedLoadFloat64;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  InstructionOperand* offset_operand = g.UseRegister(offset);
+  InstructionOperand* length_operand =
+      g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
+  if (g.CanBeImmediate(buffer)) {
+    Emit(opcode | AddressingModeField::encode(kMode_MRI),
+         g.DefineAsRegister(node), offset_operand, length_operand,
+         offset_operand, g.UseImmediate(buffer));
+  } else {
+    Emit(opcode | AddressingModeField::encode(kMode_MR1),
+         g.DefineAsRegister(node), offset_operand, length_operand,
+         g.UseRegister(buffer), offset_operand);
+  }
+}
+
+
+void InstructionSelector::VisitCheckedStore(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  IA32OperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  Node* const value = node->InputAt(3);
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepWord8:
+      opcode = kCheckedStoreWord8;
+      break;
+    case kRepWord16:
+      opcode = kCheckedStoreWord16;
+      break;
+    case kRepWord32:
+      opcode = kCheckedStoreWord32;
+      break;
+    case kRepFloat32:
+      opcode = kCheckedStoreFloat32;
+      break;
+    case kRepFloat64:
+      opcode = kCheckedStoreFloat64;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  InstructionOperand* value_operand =
+      g.CanBeImmediate(value)
+          ? g.UseImmediate(value)
+          : ((rep == kRepWord8 || rep == kRepBit) ? g.UseByteRegister(value)
+                                                  : g.UseRegister(value));
+  InstructionOperand* offset_operand = g.UseRegister(offset);
+  InstructionOperand* length_operand =
+      g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
+  if (g.CanBeImmediate(buffer)) {
+    Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr,
+         offset_operand, length_operand, value_operand, offset_operand,
+         g.UseImmediate(buffer));
+  } else {
+    Emit(opcode | AddressingModeField::encode(kMode_MR1), nullptr,
+         offset_operand, length_operand, value_operand, g.UseRegister(buffer),
+         offset_operand);
+  }
 }
 
 
@@ -166,20 +327,35 @@
                        InstructionCode opcode, FlagsContinuation* cont) {
   IA32OperandGenerator g(selector);
   Int32BinopMatcher m(node);
+  Node* left = m.left().node();
+  Node* right = m.right().node();
   InstructionOperand* inputs[4];
   size_t input_count = 0;
   InstructionOperand* outputs[2];
   size_t output_count = 0;
 
   // TODO(turbofan): match complex addressing modes.
-  // TODO(turbofan): if commutative, pick the non-live-in operand as the left as
-  // this might be the last use and therefore its register can be reused.
-  if (g.CanBeImmediate(m.right().node())) {
-    inputs[input_count++] = g.Use(m.left().node());
-    inputs[input_count++] = g.UseImmediate(m.right().node());
+  if (left == right) {
+    // If both inputs refer to the same operand, enforce allocating a register
+    // for both of them to ensure that we don't end up generating code like
+    // this:
+    //
+    //   mov eax, [ebp-0x10]
+    //   add eax, [ebp-0x10]
+    //   jo label
+    InstructionOperand* const input = g.UseRegister(left);
+    inputs[input_count++] = input;
+    inputs[input_count++] = input;
+  } else if (g.CanBeImmediate(right)) {
+    inputs[input_count++] = g.UseRegister(left);
+    inputs[input_count++] = g.UseImmediate(right);
   } else {
-    inputs[input_count++] = g.UseRegister(m.left().node());
-    inputs[input_count++] = g.Use(m.right().node());
+    if (node->op()->HasProperty(Operator::kCommutative) &&
+        g.CanBeBetterLeftOperand(right)) {
+      std::swap(left, right);
+    }
+    inputs[input_count++] = g.UseRegister(left);
+    inputs[input_count++] = g.Use(right);
   }
 
   if (cont->IsBranch()) {
@@ -226,7 +402,7 @@
   IA32OperandGenerator g(this);
   Int32BinopMatcher m(node);
   if (m.right().Is(-1)) {
-    Emit(kIA32Not, g.DefineSameAsFirst(node), g.Use(m.left().node()));
+    Emit(kIA32Not, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()));
   } else {
     VisitBinop(this, node, kIA32Xor);
   }
@@ -240,25 +416,73 @@
   Node* left = node->InputAt(0);
   Node* right = node->InputAt(1);
 
-  // TODO(turbofan): assembler only supports some addressing modes for shifts.
   if (g.CanBeImmediate(right)) {
     selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
                    g.UseImmediate(right));
   } else {
-    Int32BinopMatcher m(node);
-    if (m.right().IsWord32And()) {
-      Int32BinopMatcher mright(right);
-      if (mright.right().Is(0x1F)) {
-        right = mright.left().node();
-      }
-    }
     selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
                    g.UseFixed(right, ecx));
   }
 }
 
 
+namespace {
+
+void VisitMulHigh(InstructionSelector* selector, Node* node,
+                  ArchOpcode opcode) {
+  IA32OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsFixed(node, edx),
+                 g.UseFixed(node->InputAt(0), eax),
+                 g.UseUniqueRegister(node->InputAt(1)));
+}
+
+
+void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
+  IA32OperandGenerator g(selector);
+  InstructionOperand* temps[] = {g.TempRegister(edx)};
+  selector->Emit(opcode, g.DefineAsFixed(node, eax),
+                 g.UseFixed(node->InputAt(0), eax),
+                 g.UseUnique(node->InputAt(1)), arraysize(temps), temps);
+}
+
+
+void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
+  IA32OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsFixed(node, edx),
+                 g.UseFixed(node->InputAt(0), eax),
+                 g.UseUnique(node->InputAt(1)));
+}
+
+void EmitLea(InstructionSelector* selector, Node* result, Node* index,
+             int scale, Node* base, Node* displacement) {
+  IA32OperandGenerator g(selector);
+  InstructionOperand* inputs[4];
+  size_t input_count = 0;
+  AddressingMode mode = g.GenerateMemoryOperandInputs(
+      index, scale, base, displacement, inputs, &input_count);
+
+  DCHECK_NE(0, static_cast<int>(input_count));
+  DCHECK_GE(arraysize(inputs), input_count);
+
+  InstructionOperand* outputs[1];
+  outputs[0] = g.DefineAsRegister(result);
+
+  InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea;
+
+  selector->Emit(opcode, 1, outputs, input_count, inputs);
+}
+
+}  // namespace
+
+
 void InstructionSelector::VisitWord32Shl(Node* node) {
+  Int32ScaleMatcher m(node, true);
+  if (m.matches()) {
+    Node* index = node->InputAt(0);
+    Node* base = m.power_of_two_plus_one() ? index : NULL;
+    EmitLea(this, node, index, m.scale(), base, NULL);
+    return;
+  }
   VisitShift(this, node, kIA32Shl);
 }
 
@@ -279,6 +503,29 @@
 
 
 void InstructionSelector::VisitInt32Add(Node* node) {
+  IA32OperandGenerator g(this);
+
+  // Try to match the Add to a lea pattern
+  BaseWithIndexAndDisplacement32Matcher m(node);
+  if (m.matches() &&
+      (m.displacement() == NULL || g.CanBeImmediate(m.displacement()))) {
+    InstructionOperand* inputs[4];
+    size_t input_count = 0;
+    AddressingMode mode = g.GenerateMemoryOperandInputs(
+        m.index(), m.scale(), m.base(), m.displacement(), inputs, &input_count);
+
+    DCHECK_NE(0, static_cast<int>(input_count));
+    DCHECK_GE(arraysize(inputs), input_count);
+
+    InstructionOperand* outputs[1];
+    outputs[0] = g.DefineAsRegister(node);
+
+    InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea;
+    Emit(opcode, 1, outputs, input_count, inputs);
+    return;
+  }
+
+  // No lea pattern match, use add
   VisitBinop(this, node, kIA32Add);
 }
 
@@ -295,31 +542,36 @@
 
 
 void InstructionSelector::VisitInt32Mul(Node* node) {
+  Int32ScaleMatcher m(node, true);
+  if (m.matches()) {
+    Node* index = node->InputAt(0);
+    Node* base = m.power_of_two_plus_one() ? index : NULL;
+    EmitLea(this, node, index, m.scale(), base, NULL);
+    return;
+  }
   IA32OperandGenerator g(this);
   Node* left = node->InputAt(0);
   Node* right = node->InputAt(1);
   if (g.CanBeImmediate(right)) {
     Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(left),
          g.UseImmediate(right));
-  } else if (g.CanBeImmediate(left)) {
-    Emit(kIA32Imul, g.DefineAsRegister(node), g.Use(right),
-         g.UseImmediate(left));
   } else {
-    // TODO(turbofan): select better left operand.
+    if (g.CanBeBetterLeftOperand(right)) {
+      std::swap(left, right);
+    }
     Emit(kIA32Imul, g.DefineSameAsFirst(node), g.UseRegister(left),
          g.Use(right));
   }
 }
 
 
-static inline void VisitDiv(InstructionSelector* selector, Node* node,
-                            ArchOpcode opcode) {
-  IA32OperandGenerator g(selector);
-  InstructionOperand* temps[] = {g.TempRegister(edx)};
-  size_t temp_count = arraysize(temps);
-  selector->Emit(opcode, g.DefineAsFixed(node, eax),
-                 g.UseFixed(node->InputAt(0), eax),
-                 g.UseUnique(node->InputAt(1)), temp_count, temps);
+void InstructionSelector::VisitInt32MulHigh(Node* node) {
+  VisitMulHigh(this, node, kIA32ImulHigh);
+}
+
+
+void InstructionSelector::VisitUint32MulHigh(Node* node) {
+  VisitMulHigh(this, node, kIA32UmulHigh);
 }
 
 
@@ -328,32 +580,27 @@
 }
 
 
-void InstructionSelector::VisitInt32UDiv(Node* node) {
+void InstructionSelector::VisitUint32Div(Node* node) {
   VisitDiv(this, node, kIA32Udiv);
 }
 
 
-static inline void VisitMod(InstructionSelector* selector, Node* node,
-                            ArchOpcode opcode) {
-  IA32OperandGenerator g(selector);
-  InstructionOperand* temps[] = {g.TempRegister(eax), g.TempRegister(edx)};
-  size_t temp_count = arraysize(temps);
-  selector->Emit(opcode, g.DefineAsFixed(node, edx),
-                 g.UseFixed(node->InputAt(0), eax),
-                 g.UseUnique(node->InputAt(1)), temp_count, temps);
-}
-
-
 void InstructionSelector::VisitInt32Mod(Node* node) {
   VisitMod(this, node, kIA32Idiv);
 }
 
 
-void InstructionSelector::VisitInt32UMod(Node* node) {
+void InstructionSelector::VisitUint32Mod(Node* node) {
   VisitMod(this, node, kIA32Udiv);
 }
 
 
+void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
+  IA32OperandGenerator g(this);
+  Emit(kSSECvtss2sd, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
   IA32OperandGenerator g(this);
   Emit(kSSEInt32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
@@ -362,9 +609,7 @@
 
 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
   IA32OperandGenerator g(this);
-  // TODO(turbofan): IA32 SSE LoadUint32() should take an operand.
-  Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
 }
 
 
@@ -380,31 +625,57 @@
 }
 
 
+void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
+  IA32OperandGenerator g(this);
+  Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
 void InstructionSelector::VisitFloat64Add(Node* node) {
   IA32OperandGenerator g(this);
-  Emit(kSSEFloat64Add, g.DefineSameAsFirst(node),
-       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+  if (IsSupported(AVX)) {
+    Emit(kAVXFloat64Add, g.DefineAsRegister(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  } else {
+    Emit(kSSEFloat64Add, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  }
 }
 
 
 void InstructionSelector::VisitFloat64Sub(Node* node) {
   IA32OperandGenerator g(this);
-  Emit(kSSEFloat64Sub, g.DefineSameAsFirst(node),
-       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+  if (IsSupported(AVX)) {
+    Emit(kAVXFloat64Sub, g.DefineAsRegister(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  } else {
+    Emit(kSSEFloat64Sub, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  }
 }
 
 
 void InstructionSelector::VisitFloat64Mul(Node* node) {
   IA32OperandGenerator g(this);
-  Emit(kSSEFloat64Mul, g.DefineSameAsFirst(node),
-       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+  if (IsSupported(AVX)) {
+    Emit(kAVXFloat64Mul, g.DefineAsRegister(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  } else {
+    Emit(kSSEFloat64Mul, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  }
 }
 
 
 void InstructionSelector::VisitFloat64Div(Node* node) {
   IA32OperandGenerator g(this);
-  Emit(kSSEFloat64Div, g.DefineSameAsFirst(node),
-       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+  if (IsSupported(AVX)) {
+    Emit(kAVXFloat64Div, g.DefineAsRegister(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  } else {
+    Emit(kSSEFloat64Div, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  }
 }
 
 
@@ -423,104 +694,44 @@
 }
 
 
-void InstructionSelector::VisitInt32AddWithOverflow(Node* node,
-                                                    FlagsContinuation* cont) {
-  VisitBinop(this, node, kIA32Add, cont);
+void InstructionSelector::VisitFloat64Floor(Node* node) {
+  DCHECK(CpuFeatures::IsSupported(SSE4_1));
+  VisitRRFloat64(this, kSSEFloat64Floor, node);
 }
 
 
-void InstructionSelector::VisitInt32SubWithOverflow(Node* node,
-                                                    FlagsContinuation* cont) {
-  VisitBinop(this, node, kIA32Sub, cont);
+void InstructionSelector::VisitFloat64Ceil(Node* node) {
+  DCHECK(CpuFeatures::IsSupported(SSE4_1));
+  VisitRRFloat64(this, kSSEFloat64Ceil, node);
 }
 
 
-// Shared routine for multiple compare operations.
-static inline void VisitCompare(InstructionSelector* selector,
-                                InstructionCode opcode,
-                                InstructionOperand* left,
-                                InstructionOperand* right,
-                                FlagsContinuation* cont) {
-  IA32OperandGenerator g(selector);
-  if (cont->IsBranch()) {
-    selector->Emit(cont->Encode(opcode), NULL, left, right,
-                   g.Label(cont->true_block()),
-                   g.Label(cont->false_block()))->MarkAsControl();
-  } else {
-    DCHECK(cont->IsSet());
-    // TODO(titzer): Needs byte register.
-    selector->Emit(cont->Encode(opcode), g.DefineAsRegister(cont->result()),
-                   left, right);
-  }
+void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
+  DCHECK(CpuFeatures::IsSupported(SSE4_1));
+  VisitRRFloat64(this, kSSEFloat64RoundTruncate, node);
 }
 
 
-// Shared routine for multiple word compare operations.
-static inline void VisitWordCompare(InstructionSelector* selector, Node* node,
-                                    InstructionCode opcode,
-                                    FlagsContinuation* cont, bool commutative) {
-  IA32OperandGenerator g(selector);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
-
-  // Match immediates on left or right side of comparison.
-  if (g.CanBeImmediate(right)) {
-    VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont);
-  } else if (g.CanBeImmediate(left)) {
-    if (!commutative) cont->Commute();
-    VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont);
-  } else {
-    VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont);
-  }
+void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
+  UNREACHABLE();
 }
 
 
-void InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) {
-  switch (node->opcode()) {
-    case IrOpcode::kInt32Sub:
-      return VisitWordCompare(this, node, kIA32Cmp, cont, false);
-    case IrOpcode::kWord32And:
-      return VisitWordCompare(this, node, kIA32Test, cont, true);
-    default:
-      break;
-  }
-
+void InstructionSelector::VisitCall(Node* node) {
   IA32OperandGenerator g(this);
-  VisitCompare(this, kIA32Test, g.Use(node), g.TempImmediate(-1), cont);
-}
-
-
-void InstructionSelector::VisitWord32Compare(Node* node,
-                                             FlagsContinuation* cont) {
-  VisitWordCompare(this, node, kIA32Cmp, cont, false);
-}
-
-
-void InstructionSelector::VisitFloat64Compare(Node* node,
-                                              FlagsContinuation* cont) {
-  IA32OperandGenerator g(this);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
-  VisitCompare(this, kSSEFloat64Cmp, g.UseRegister(left), g.Use(right), cont);
-}
-
-
-void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
-                                    BasicBlock* deoptimization) {
-  IA32OperandGenerator g(this);
-  CallDescriptor* descriptor = OpParameter<CallDescriptor*>(call);
+  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
 
   FrameStateDescriptor* frame_state_descriptor = NULL;
 
   if (descriptor->NeedsFrameState()) {
     frame_state_descriptor =
-        GetFrameStateDescriptor(call->InputAt(descriptor->InputCount()));
+        GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
   }
 
   CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
 
   // Compute InstructionOperands for inputs and outputs.
-  InitializeCallBuffer(call, &buffer, true, true);
+  InitializeCallBuffer(node, &buffer, true, true);
 
   // Push any stack arguments.
   for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
@@ -547,17 +758,254 @@
   opcode |= MiscField::encode(descriptor->flags());
 
   // Emit the call instruction.
+  InstructionOperand** first_output =
+      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
   Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
+      Emit(opcode, buffer.outputs.size(), first_output,
            buffer.instruction_args.size(), &buffer.instruction_args.front());
-
   call_instr->MarkAsCall();
-  if (deoptimization != NULL) {
-    DCHECK(continuation != NULL);
-    call_instr->MarkAsControl();
+}
+
+
+namespace {
+
+// Shared routine for multiple compare operations.
+void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                  InstructionOperand* left, InstructionOperand* right,
+                  FlagsContinuation* cont) {
+  IA32OperandGenerator g(selector);
+  if (cont->IsBranch()) {
+    selector->Emit(cont->Encode(opcode), NULL, left, right,
+                   g.Label(cont->true_block()),
+                   g.Label(cont->false_block()))->MarkAsControl();
+  } else {
+    DCHECK(cont->IsSet());
+    // TODO(titzer): Needs byte register.
+    selector->Emit(cont->Encode(opcode), g.DefineAsRegister(cont->result()),
+                   left, right);
   }
 }
 
+
+// Shared routine for multiple compare operations.
+void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                  Node* left, Node* right, FlagsContinuation* cont,
+                  bool commutative) {
+  IA32OperandGenerator g(selector);
+  if (commutative && g.CanBeBetterLeftOperand(right)) {
+    std::swap(left, right);
+  }
+  VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont);
+}
+
+
+// Shared routine for multiple float compare operations.
+void VisitFloat64Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  VisitCompare(selector, kSSEFloat64Cmp, node->InputAt(0), node->InputAt(1),
+               cont, node->op()->HasProperty(Operator::kCommutative));
+}
+
+
+// Shared routine for multiple word compare operations.
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      InstructionCode opcode, FlagsContinuation* cont) {
+  IA32OperandGenerator g(selector);
+  Node* const left = node->InputAt(0);
+  Node* const right = node->InputAt(1);
+
+  // Match immediates on left or right side of comparison.
+  if (g.CanBeImmediate(right)) {
+    VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont);
+  } else if (g.CanBeImmediate(left)) {
+    if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
+    VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont);
+  } else {
+    VisitCompare(selector, opcode, left, right, cont,
+                 node->op()->HasProperty(Operator::kCommutative));
+  }
+}
+
+
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      FlagsContinuation* cont) {
+  VisitWordCompare(selector, node, kIA32Cmp, cont);
+}
+
+
+// Shared routine for word comparison with zero.
+void VisitWordCompareZero(InstructionSelector* selector, Node* user,
+                          Node* value, FlagsContinuation* cont) {
+  // Try to combine the branch with a comparison.
+  while (selector->CanCover(user, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kWord32Equal: {
+        // Try to combine with comparisons against 0 by simply inverting the
+        // continuation.
+        Int32BinopMatcher m(value);
+        if (m.right().Is(0)) {
+          user = value;
+          value = m.left().node();
+          cont->Negate();
+          continue;
+        }
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitWordCompare(selector, value, cont);
+      }
+      case IrOpcode::kInt32LessThan:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThan);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kInt32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kUint32LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kUint32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kFloat64Equal:
+        cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kFloat64LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnorderedLessThan);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kFloat64LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kProjection:
+        // Check if this is the overflow output projection of an
+        // <Operation>WithOverflow node.
+        if (OpParameter<size_t>(value) == 1u) {
+          // We cannot combine the <Operation>WithOverflow with this branch
+          // unless the 0th projection (the use of the actual value of the
+          // <Operation> is either NULL, which means there's no use of the
+          // actual value, or was already defined, which means it is scheduled
+          // *AFTER* this branch).
+          Node* node = value->InputAt(0);
+          Node* result = node->FindProjection(0);
+          if (result == NULL || selector->IsDefined(result)) {
+            switch (node->opcode()) {
+              case IrOpcode::kInt32AddWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(selector, node, kIA32Add, cont);
+              case IrOpcode::kInt32SubWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(selector, node, kIA32Sub, cont);
+              default:
+                break;
+            }
+          }
+        }
+        break;
+      case IrOpcode::kInt32Sub:
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kWord32And:
+        return VisitWordCompare(selector, value, kIA32Test, cont);
+      default:
+        break;
+    }
+    break;
+  }
+
+  // Continuation could not be combined with a compare, emit compare against 0.
+  IA32OperandGenerator g(selector);
+  VisitCompare(selector, kIA32Cmp, g.Use(value), g.TempImmediate(0), cont);
+}
+
+}  // namespace
+
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+                                      BasicBlock* fbranch) {
+  FlagsContinuation cont(kNotEqual, tbranch, fbranch);
+  VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
+}
+
+
+void InstructionSelector::VisitWord32Equal(Node* const node) {
+  FlagsContinuation cont(kEqual, node);
+  Int32BinopMatcher m(node);
+  if (m.right().Is(0)) {
+    return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
+  }
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kIA32Add, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kIA32Add, &cont);
+}
+
+
+void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kIA32Sub, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kIA32Sub, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64Equal(Node* node) {
+  FlagsContinuation cont(kUnorderedEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThan(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThan, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  if (CpuFeatures::IsSupported(SSE4_1)) {
+    return MachineOperatorBuilder::kFloat64Floor |
+           MachineOperatorBuilder::kFloat64Ceil |
+           MachineOperatorBuilder::kFloat64RoundTruncate |
+           MachineOperatorBuilder::kWord32ShiftIsSafe;
+  }
+  return MachineOperatorBuilder::Flag::kNoFlags;
+}
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/ia32/linkage-ia32.cc b/src/compiler/ia32/linkage-ia32.cc
index f2c5fab..12cc34f 100644
--- a/src/compiler/ia32/linkage-ia32.cc
+++ b/src/compiler/ia32/linkage-ia32.cc
@@ -30,8 +30,9 @@
 
 typedef LinkageHelper<IA32LinkageHelperTraits> LH;
 
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) {
-  return LH::GetJSCallDescriptor(zone, parameter_count);
+CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
+                                             CallDescriptor::Flags flags) {
+  return LH::GetJSCallDescriptor(zone, parameter_count, flags);
 }
 
 
@@ -44,10 +45,10 @@
 
 
 CallDescriptor* Linkage::GetStubCallDescriptor(
-    CallInterfaceDescriptor descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Zone* zone) {
+    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
+    CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone) {
   return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count,
-                                   flags);
+                                   flags, properties);
 }
 
 
diff --git a/src/compiler/instruction-codes.h b/src/compiler/instruction-codes.h
index 2d921bd..ea17854 100644
--- a/src/compiler/instruction-codes.h
+++ b/src/compiler/instruction-codes.h
@@ -5,12 +5,18 @@
 #ifndef V8_COMPILER_INSTRUCTION_CODES_H_
 #define V8_COMPILER_INSTRUCTION_CODES_H_
 
+#include <iosfwd>
+
 #if V8_TARGET_ARCH_ARM
 #include "src/compiler/arm/instruction-codes-arm.h"
 #elif V8_TARGET_ARCH_ARM64
 #include "src/compiler/arm64/instruction-codes-arm64.h"
 #elif V8_TARGET_ARCH_IA32
 #include "src/compiler/ia32/instruction-codes-ia32.h"
+#elif V8_TARGET_ARCH_MIPS
+#include "src/compiler/mips/instruction-codes-mips.h"
+#elif V8_TARGET_ARCH_MIPS64
+#include "src/compiler/mips64/instruction-codes-mips64.h"
 #elif V8_TARGET_ARCH_X64
 #include "src/compiler/x64/instruction-codes-x64.h"
 #else
@@ -21,9 +27,6 @@
 
 namespace v8 {
 namespace internal {
-
-class OStream;
-
 namespace compiler {
 
 // Target-specific opcodes that specify which assembly sequence to emit.
@@ -34,7 +37,20 @@
   V(ArchJmp)                \
   V(ArchNop)                \
   V(ArchRet)                \
+  V(ArchStackPointer)       \
   V(ArchTruncateDoubleToI)  \
+  V(CheckedLoadInt8)        \
+  V(CheckedLoadUint8)       \
+  V(CheckedLoadInt16)       \
+  V(CheckedLoadUint16)      \
+  V(CheckedLoadWord32)      \
+  V(CheckedLoadFloat32)     \
+  V(CheckedLoadFloat64)     \
+  V(CheckedStoreWord8)      \
+  V(CheckedStoreWord16)     \
+  V(CheckedStoreWord32)     \
+  V(CheckedStoreFloat32)    \
+  V(CheckedStoreFloat64)    \
   TARGET_ARCH_OPCODE_LIST(V)
 
 enum ArchOpcode {
@@ -46,7 +62,7 @@
 #undef COUNT_ARCH_OPCODE
 };
 
-OStream& operator<<(OStream& os, const ArchOpcode& ao);
+std::ostream& operator<<(std::ostream& os, const ArchOpcode& ao);
 
 // Addressing modes represent the "shape" of inputs to an instruction.
 // Many instructions support multiple addressing modes. Addressing modes
@@ -65,12 +81,12 @@
 #undef COUNT_ADDRESSING_MODE
 };
 
-OStream& operator<<(OStream& os, const AddressingMode& am);
+std::ostream& operator<<(std::ostream& os, const AddressingMode& am);
 
 // The mode of the flags continuation (see below).
 enum FlagsMode { kFlags_none = 0, kFlags_branch = 1, kFlags_set = 2 };
 
-OStream& operator<<(OStream& os, const FlagsMode& fm);
+std::ostream& operator<<(std::ostream& os, const FlagsMode& fm);
 
 // The condition of flags continuation (see below).
 enum FlagsCondition {
@@ -94,7 +110,11 @@
   kNotOverflow
 };
 
-OStream& operator<<(OStream& os, const FlagsCondition& fc);
+inline FlagsCondition NegateFlagsCondition(FlagsCondition condition) {
+  return static_cast<FlagsCondition>(condition ^ 1);
+}
+
+std::ostream& operator<<(std::ostream& os, const FlagsCondition& fc);
 
 // The InstructionCode is an opaque, target-specific integer that encodes
 // what code to emit for an instruction in the code generator. It is not
@@ -107,10 +127,10 @@
 // continuation into a single InstructionCode which is stored as part of
 // the instruction.
 typedef BitField<ArchOpcode, 0, 7> ArchOpcodeField;
-typedef BitField<AddressingMode, 7, 4> AddressingModeField;
-typedef BitField<FlagsMode, 11, 2> FlagsModeField;
-typedef BitField<FlagsCondition, 13, 5> FlagsConditionField;
-typedef BitField<int, 13, 19> MiscField;
+typedef BitField<AddressingMode, 7, 5> AddressingModeField;
+typedef BitField<FlagsMode, 12, 2> FlagsModeField;
+typedef BitField<FlagsCondition, 14, 5> FlagsConditionField;
+typedef BitField<int, 14, 18> MiscField;
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/instruction-selector-impl.h b/src/compiler/instruction-selector-impl.h
index d00109e..bdcd952 100644
--- a/src/compiler/instruction-selector-impl.h
+++ b/src/compiler/instruction-selector-impl.h
@@ -8,6 +8,7 @@
 #include "src/compiler/instruction.h"
 #include "src/compiler/instruction-selector.h"
 #include "src/compiler/linkage.h"
+#include "src/macro-assembler.h"
 
 namespace v8 {
 namespace internal {
@@ -44,8 +45,9 @@
 
   InstructionOperand* DefineAsConstant(Node* node) {
     selector()->MarkAsDefined(node);
-    sequence()->AddConstant(node->id(), ToConstant(node));
-    return ConstantOperand::Create(node->id(), zone());
+    int virtual_register = selector_->GetVirtualRegister(node);
+    sequence()->AddConstant(virtual_register, ToConstant(node));
+    return ConstantOperand::Create(virtual_register, zone());
   }
 
   InstructionOperand* DefineAsLocation(Node* node, LinkageLocation location,
@@ -54,9 +56,9 @@
   }
 
   InstructionOperand* Use(Node* node) {
-    return Use(node,
-               new (zone()) UnallocatedOperand(
-                   UnallocatedOperand::ANY, UnallocatedOperand::USED_AT_START));
+    return Use(
+        node, new (zone()) UnallocatedOperand(
+                  UnallocatedOperand::NONE, UnallocatedOperand::USED_AT_START));
   }
 
   InstructionOperand* UseRegister(Node* node) {
@@ -68,7 +70,7 @@
   // Use register or operand for the node. If a register is chosen, it won't
   // alias any temporary or output registers.
   InstructionOperand* UseUnique(Node* node) {
-    return Use(node, new (zone()) UnallocatedOperand(UnallocatedOperand::ANY));
+    return Use(node, new (zone()) UnallocatedOperand(UnallocatedOperand::NONE));
   }
 
   // Use a unique register for the node that does not alias any temporary or
@@ -127,13 +129,18 @@
     return ImmediateOperand::Create(index, zone());
   }
 
+  InstructionOperand* TempLocation(LinkageLocation location, MachineType type) {
+    UnallocatedOperand* op = ToUnallocatedOperand(location, type);
+    op->set_virtual_register(sequence()->NextVirtualRegister());
+    return op;
+  }
+
   InstructionOperand* Label(BasicBlock* block) {
-    // TODO(bmeurer): We misuse ImmediateOperand here.
-    return TempImmediate(block->id());
+    int index = sequence()->AddImmediate(Constant(block->GetRpoNumber()));
+    return ImmediateOperand::Create(index, zone());
   }
 
  protected:
-  Graph* graph() const { return selector()->graph(); }
   InstructionSelector* selector() const { return selector_; }
   InstructionSequence* sequence() const { return selector()->sequence(); }
   Isolate* isolate() const { return zone()->isolate(); }
@@ -146,8 +153,10 @@
         return Constant(OpParameter<int32_t>(node));
       case IrOpcode::kInt64Constant:
         return Constant(OpParameter<int64_t>(node));
-      case IrOpcode::kNumberConstant:
+      case IrOpcode::kFloat32Constant:
+        return Constant(OpParameter<float>(node));
       case IrOpcode::kFloat64Constant:
+      case IrOpcode::kNumberConstant:
         return Constant(OpParameter<double>(node));
       case IrOpcode::kExternalConstant:
         return Constant(OpParameter<ExternalReference>(node));
@@ -163,7 +172,7 @@
   UnallocatedOperand* Define(Node* node, UnallocatedOperand* operand) {
     DCHECK_NOT_NULL(node);
     DCHECK_NOT_NULL(operand);
-    operand->set_virtual_register(node->id());
+    operand->set_virtual_register(selector_->GetVirtualRegister(node));
     selector()->MarkAsDefined(node);
     return operand;
   }
@@ -171,7 +180,7 @@
   UnallocatedOperand* Use(Node* node, UnallocatedOperand* operand) {
     DCHECK_NOT_NULL(node);
     DCHECK_NOT_NULL(operand);
-    operand->set_virtual_register(node->id());
+    operand->set_virtual_register(selector_->GetVirtualRegister(node));
     selector()->MarkAsUsed(node);
     return operand;
   }
@@ -247,7 +256,7 @@
 
   void Negate() {
     DCHECK(!IsNone());
-    condition_ = static_cast<FlagsCondition>(condition_ ^ 1);
+    condition_ = NegateFlagsCondition(condition_);
   }
 
   void Commute() {
@@ -307,8 +316,6 @@
     if (negate) Negate();
   }
 
-  void SwapBlocks() { std::swap(true_block_, false_block_); }
-
   // Encodes this flags continuation into the given opcode.
   InstructionCode Encode(InstructionCode opcode) {
     opcode |= FlagsModeField::encode(mode_);
@@ -331,10 +338,10 @@
 // TODO(bmeurer): Get rid of the CallBuffer business and make
 // InstructionSelector::VisitCall platform independent instead.
 struct CallBuffer {
-  CallBuffer(Zone* zone, CallDescriptor* descriptor,
+  CallBuffer(Zone* zone, const CallDescriptor* descriptor,
              FrameStateDescriptor* frame_state);
 
-  CallDescriptor* descriptor;
+  const CallDescriptor* descriptor;
   FrameStateDescriptor* frame_state_descriptor;
   NodeVector output_nodes;
   InstructionOperandVector outputs;
diff --git a/src/compiler/instruction-selector-unittest.cc b/src/compiler/instruction-selector-unittest.cc
deleted file mode 100644
index aa70735..0000000
--- a/src/compiler/instruction-selector-unittest.cc
+++ /dev/null
@@ -1,496 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/instruction-selector-unittest.h"
-
-#include "src/compiler/compiler-test-utils.h"
-#include "src/flags.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-namespace {
-
-typedef RawMachineAssembler::Label MLabel;
-
-}  // namespace
-
-
-InstructionSelectorTest::InstructionSelectorTest() : rng_(FLAG_random_seed) {}
-
-
-InstructionSelectorTest::~InstructionSelectorTest() {}
-
-
-InstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build(
-    InstructionSelector::Features features,
-    InstructionSelectorTest::StreamBuilderMode mode) {
-  Schedule* schedule = Export();
-  if (FLAG_trace_turbo) {
-    OFStream out(stdout);
-    out << "=== Schedule before instruction selection ===" << endl << *schedule;
-  }
-  EXPECT_NE(0, graph()->NodeCount());
-  CompilationInfo info(test_->isolate(), test_->zone());
-  Linkage linkage(&info, call_descriptor());
-  InstructionSequence sequence(&linkage, graph(), schedule);
-  SourcePositionTable source_position_table(graph());
-  InstructionSelector selector(&sequence, &source_position_table, features);
-  selector.SelectInstructions();
-  if (FLAG_trace_turbo) {
-    OFStream out(stdout);
-    out << "=== Code sequence after instruction selection ===" << endl
-        << sequence;
-  }
-  Stream s;
-  std::set<int> virtual_registers;
-  for (InstructionSequence::const_iterator i = sequence.begin();
-       i != sequence.end(); ++i) {
-    Instruction* instr = *i;
-    if (instr->opcode() < 0) continue;
-    if (mode == kTargetInstructions) {
-      switch (instr->arch_opcode()) {
-#define CASE(Name) \
-  case k##Name:    \
-    break;
-        TARGET_ARCH_OPCODE_LIST(CASE)
-#undef CASE
-        default:
-          continue;
-      }
-    }
-    if (mode == kAllExceptNopInstructions && instr->arch_opcode() == kArchNop) {
-      continue;
-    }
-    for (size_t i = 0; i < instr->OutputCount(); ++i) {
-      InstructionOperand* output = instr->OutputAt(i);
-      EXPECT_NE(InstructionOperand::IMMEDIATE, output->kind());
-      if (output->IsConstant()) {
-        s.constants_.insert(std::make_pair(
-            output->index(), sequence.GetConstant(output->index())));
-        virtual_registers.insert(output->index());
-      } else if (output->IsUnallocated()) {
-        virtual_registers.insert(
-            UnallocatedOperand::cast(output)->virtual_register());
-      }
-    }
-    for (size_t i = 0; i < instr->InputCount(); ++i) {
-      InstructionOperand* input = instr->InputAt(i);
-      EXPECT_NE(InstructionOperand::CONSTANT, input->kind());
-      if (input->IsImmediate()) {
-        s.immediates_.insert(std::make_pair(
-            input->index(), sequence.GetImmediate(input->index())));
-      } else if (input->IsUnallocated()) {
-        virtual_registers.insert(
-            UnallocatedOperand::cast(input)->virtual_register());
-      }
-    }
-    s.instructions_.push_back(instr);
-  }
-  for (std::set<int>::const_iterator i = virtual_registers.begin();
-       i != virtual_registers.end(); ++i) {
-    int virtual_register = *i;
-    if (sequence.IsDouble(virtual_register)) {
-      EXPECT_FALSE(sequence.IsReference(virtual_register));
-      s.doubles_.insert(virtual_register);
-    }
-    if (sequence.IsReference(virtual_register)) {
-      EXPECT_FALSE(sequence.IsDouble(virtual_register));
-      s.references_.insert(virtual_register);
-    }
-  }
-  for (int i = 0; i < sequence.GetFrameStateDescriptorCount(); i++) {
-    s.deoptimization_entries_.push_back(sequence.GetFrameStateDescriptor(
-        InstructionSequence::StateId::FromInt(i)));
-  }
-  return s;
-}
-
-
-// -----------------------------------------------------------------------------
-// Return.
-
-
-TARGET_TEST_F(InstructionSelectorTest, ReturnParameter) {
-  StreamBuilder m(this, kMachInt32, kMachInt32);
-  m.Return(m.Parameter(0));
-  Stream s = m.Build(kAllInstructions);
-  ASSERT_EQ(2U, s.size());
-  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(kArchRet, s[1]->arch_opcode());
-  EXPECT_EQ(1U, s[1]->InputCount());
-}
-
-
-TARGET_TEST_F(InstructionSelectorTest, ReturnZero) {
-  StreamBuilder m(this, kMachInt32);
-  m.Return(m.Int32Constant(0));
-  Stream s = m.Build(kAllInstructions);
-  ASSERT_EQ(2U, s.size());
-  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  EXPECT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind());
-  EXPECT_EQ(0, s.ToInt32(s[0]->OutputAt(0)));
-  EXPECT_EQ(kArchRet, s[1]->arch_opcode());
-  EXPECT_EQ(1U, s[1]->InputCount());
-}
-
-
-// -----------------------------------------------------------------------------
-// Conversions.
-
-
-TARGET_TEST_F(InstructionSelectorTest, TruncateFloat64ToInt32WithParameter) {
-  StreamBuilder m(this, kMachInt32, kMachFloat64);
-  m.Return(m.TruncateFloat64ToInt32(m.Parameter(0)));
-  Stream s = m.Build(kAllInstructions);
-  ASSERT_EQ(3U, s.size());
-  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
-  EXPECT_EQ(kArchTruncateDoubleToI, s[1]->arch_opcode());
-  EXPECT_EQ(1U, s[1]->InputCount());
-  EXPECT_EQ(1U, s[1]->OutputCount());
-  EXPECT_EQ(kArchRet, s[2]->arch_opcode());
-}
-
-
-// -----------------------------------------------------------------------------
-// Parameters.
-
-
-TARGET_TEST_F(InstructionSelectorTest, DoubleParameter) {
-  StreamBuilder m(this, kMachFloat64, kMachFloat64);
-  Node* param = m.Parameter(0);
-  m.Return(param);
-  Stream s = m.Build(kAllInstructions);
-  EXPECT_TRUE(s.IsDouble(param->id()));
-}
-
-
-TARGET_TEST_F(InstructionSelectorTest, ReferenceParameter) {
-  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged);
-  Node* param = m.Parameter(0);
-  m.Return(param);
-  Stream s = m.Build(kAllInstructions);
-  EXPECT_TRUE(s.IsReference(param->id()));
-}
-
-
-// -----------------------------------------------------------------------------
-// Finish.
-
-
-TARGET_TEST_F(InstructionSelectorTest, Finish) {
-  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged);
-  Node* param = m.Parameter(0);
-  Node* finish = m.NewNode(m.common()->Finish(1), param, m.graph()->start());
-  m.Return(finish);
-  Stream s = m.Build(kAllInstructions);
-  ASSERT_EQ(3U, s.size());
-  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
-  ASSERT_EQ(1U, s[0]->OutputCount());
-  ASSERT_TRUE(s[0]->Output()->IsUnallocated());
-  EXPECT_EQ(param->id(), s.ToVreg(s[0]->Output()));
-  EXPECT_EQ(kArchNop, s[1]->arch_opcode());
-  ASSERT_EQ(1U, s[1]->InputCount());
-  ASSERT_TRUE(s[1]->InputAt(0)->IsUnallocated());
-  EXPECT_EQ(param->id(), s.ToVreg(s[1]->InputAt(0)));
-  ASSERT_EQ(1U, s[1]->OutputCount());
-  ASSERT_TRUE(s[1]->Output()->IsUnallocated());
-  EXPECT_TRUE(UnallocatedOperand::cast(s[1]->Output())->HasSameAsInputPolicy());
-  EXPECT_EQ(finish->id(), s.ToVreg(s[1]->Output()));
-  EXPECT_TRUE(s.IsReference(finish->id()));
-}
-
-
-// -----------------------------------------------------------------------------
-// Phi.
-
-
-typedef InstructionSelectorTestWithParam<MachineType>
-    InstructionSelectorPhiTest;
-
-
-TARGET_TEST_P(InstructionSelectorPhiTest, Doubleness) {
-  const MachineType type = GetParam();
-  StreamBuilder m(this, type, type, type);
-  Node* param0 = m.Parameter(0);
-  Node* param1 = m.Parameter(1);
-  MLabel a, b, c;
-  m.Branch(m.Int32Constant(0), &a, &b);
-  m.Bind(&a);
-  m.Goto(&c);
-  m.Bind(&b);
-  m.Goto(&c);
-  m.Bind(&c);
-  Node* phi = m.Phi(type, param0, param1);
-  m.Return(phi);
-  Stream s = m.Build(kAllInstructions);
-  EXPECT_EQ(s.IsDouble(phi->id()), s.IsDouble(param0->id()));
-  EXPECT_EQ(s.IsDouble(phi->id()), s.IsDouble(param1->id()));
-}
-
-
-TARGET_TEST_P(InstructionSelectorPhiTest, Referenceness) {
-  const MachineType type = GetParam();
-  StreamBuilder m(this, type, type, type);
-  Node* param0 = m.Parameter(0);
-  Node* param1 = m.Parameter(1);
-  MLabel a, b, c;
-  m.Branch(m.Int32Constant(1), &a, &b);
-  m.Bind(&a);
-  m.Goto(&c);
-  m.Bind(&b);
-  m.Goto(&c);
-  m.Bind(&c);
-  Node* phi = m.Phi(type, param0, param1);
-  m.Return(phi);
-  Stream s = m.Build(kAllInstructions);
-  EXPECT_EQ(s.IsReference(phi->id()), s.IsReference(param0->id()));
-  EXPECT_EQ(s.IsReference(phi->id()), s.IsReference(param1->id()));
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorPhiTest,
-                        ::testing::Values(kMachFloat64, kMachInt8, kMachUint8,
-                                          kMachInt16, kMachUint16, kMachInt32,
-                                          kMachUint32, kMachInt64, kMachUint64,
-                                          kMachPtr, kMachAnyTagged));
-
-
-// -----------------------------------------------------------------------------
-// ValueEffect.
-
-
-TARGET_TEST_F(InstructionSelectorTest, ValueEffect) {
-  StreamBuilder m1(this, kMachInt32, kMachPtr);
-  Node* p1 = m1.Parameter(0);
-  m1.Return(m1.Load(kMachInt32, p1, m1.Int32Constant(0)));
-  Stream s1 = m1.Build(kAllInstructions);
-  StreamBuilder m2(this, kMachInt32, kMachPtr);
-  Node* p2 = m2.Parameter(0);
-  m2.Return(m2.NewNode(m2.machine()->Load(kMachInt32), p2, m2.Int32Constant(0),
-                       m2.NewNode(m2.common()->ValueEffect(1), p2)));
-  Stream s2 = m2.Build(kAllInstructions);
-  EXPECT_LE(3U, s1.size());
-  ASSERT_EQ(s1.size(), s2.size());
-  TRACED_FORRANGE(size_t, i, 0, s1.size() - 1) {
-    const Instruction* i1 = s1[i];
-    const Instruction* i2 = s2[i];
-    EXPECT_EQ(i1->arch_opcode(), i2->arch_opcode());
-    EXPECT_EQ(i1->InputCount(), i2->InputCount());
-    EXPECT_EQ(i1->OutputCount(), i2->OutputCount());
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// Calls with deoptimization.
-TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) {
-  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
-                  kMachAnyTagged);
-
-  BailoutId bailout_id(42);
-
-  Node* function_node = m.Parameter(0);
-  Node* receiver = m.Parameter(1);
-  Node* context = m.Parameter(2);
-
-  Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(1));
-  Node* locals = m.NewNode(m.common()->StateValues(0));
-  Node* stack = m.NewNode(m.common()->StateValues(0));
-  Node* context_dummy = m.Int32Constant(0);
-
-  Node* state_node = m.NewNode(
-      m.common()->FrameState(JS_FRAME, bailout_id, kPushOutput), parameters,
-      locals, stack, context_dummy, m.UndefinedConstant());
-  Node* call = m.CallJS0(function_node, receiver, context, state_node);
-  m.Return(call);
-
-  Stream s = m.Build(kAllExceptNopInstructions);
-
-  // Skip until kArchCallJSFunction.
-  size_t index = 0;
-  for (; index < s.size() && s[index]->arch_opcode() != kArchCallJSFunction;
-       index++) {
-  }
-  // Now we should have two instructions: call and return.
-  ASSERT_EQ(index + 2, s.size());
-
-  EXPECT_EQ(kArchCallJSFunction, s[index++]->arch_opcode());
-  EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
-
-  // TODO(jarin) Check deoptimization table.
-}
-
-
-TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
-  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
-                  kMachAnyTagged);
-
-  BailoutId bailout_id_before(42);
-
-  // Some arguments for the call node.
-  Node* function_node = m.Parameter(0);
-  Node* receiver = m.Parameter(1);
-  Node* context = m.Int32Constant(1);  // Context is ignored.
-
-  // Build frame state for the state before the call.
-  Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(43));
-  Node* locals = m.NewNode(m.common()->StateValues(1), m.Int32Constant(44));
-  Node* stack = m.NewNode(m.common()->StateValues(1), m.Int32Constant(45));
-
-  Node* context_sentinel = m.Int32Constant(0);
-  Node* frame_state_before = m.NewNode(
-      m.common()->FrameState(JS_FRAME, bailout_id_before, kPushOutput),
-      parameters, locals, stack, context_sentinel, m.UndefinedConstant());
-
-  // Build the call.
-  Node* call = m.CallFunctionStub0(function_node, receiver, context,
-                                   frame_state_before, CALL_AS_METHOD);
-
-  m.Return(call);
-
-  Stream s = m.Build(kAllExceptNopInstructions);
-
-  // Skip until kArchCallJSFunction.
-  size_t index = 0;
-  for (; index < s.size() && s[index]->arch_opcode() != kArchCallCodeObject;
-       index++) {
-  }
-  // Now we should have two instructions: call, return.
-  ASSERT_EQ(index + 2, s.size());
-
-  // Check the call instruction
-  const Instruction* call_instr = s[index++];
-  EXPECT_EQ(kArchCallCodeObject, call_instr->arch_opcode());
-  size_t num_operands =
-      1 +  // Code object.
-      1 +
-      4 +  // Frame state deopt id + one input for each value in frame state.
-      1 +  // Function.
-      1;   // Context.
-  ASSERT_EQ(num_operands, call_instr->InputCount());
-
-  // Code object.
-  EXPECT_TRUE(call_instr->InputAt(0)->IsImmediate());
-
-  // Deoptimization id.
-  int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1));
-  FrameStateDescriptor* desc_before =
-      s.GetFrameStateDescriptor(deopt_id_before);
-  EXPECT_EQ(bailout_id_before, desc_before->bailout_id());
-  EXPECT_EQ(kPushOutput, desc_before->state_combine());
-  EXPECT_EQ(1u, desc_before->parameters_count());
-  EXPECT_EQ(1u, desc_before->locals_count());
-  EXPECT_EQ(1u, desc_before->stack_count());
-  EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(2)));
-  EXPECT_EQ(0, s.ToInt32(call_instr->InputAt(3)));
-  EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(4)));
-  EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(5)));
-
-  // Function.
-  EXPECT_EQ(function_node->id(), s.ToVreg(call_instr->InputAt(6)));
-  // Context.
-  EXPECT_EQ(context->id(), s.ToVreg(call_instr->InputAt(7)));
-
-  EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
-
-  EXPECT_EQ(index, s.size());
-}
-
-
-TARGET_TEST_F(InstructionSelectorTest,
-              CallFunctionStubDeoptRecursiveFrameState) {
-  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
-                  kMachAnyTagged);
-
-  BailoutId bailout_id_before(42);
-  BailoutId bailout_id_parent(62);
-
-  // Some arguments for the call node.
-  Node* function_node = m.Parameter(0);
-  Node* receiver = m.Parameter(1);
-  Node* context = m.Int32Constant(66);
-
-  // Build frame state for the state before the call.
-  Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(63));
-  Node* locals = m.NewNode(m.common()->StateValues(1), m.Int32Constant(64));
-  Node* stack = m.NewNode(m.common()->StateValues(1), m.Int32Constant(65));
-  Node* frame_state_parent = m.NewNode(
-      m.common()->FrameState(JS_FRAME, bailout_id_parent, kIgnoreOutput),
-      parameters, locals, stack, context, m.UndefinedConstant());
-
-  Node* context2 = m.Int32Constant(46);
-  Node* parameters2 =
-      m.NewNode(m.common()->StateValues(1), m.Int32Constant(43));
-  Node* locals2 = m.NewNode(m.common()->StateValues(1), m.Int32Constant(44));
-  Node* stack2 = m.NewNode(m.common()->StateValues(1), m.Int32Constant(45));
-  Node* frame_state_before = m.NewNode(
-      m.common()->FrameState(JS_FRAME, bailout_id_before, kPushOutput),
-      parameters2, locals2, stack2, context2, frame_state_parent);
-
-  // Build the call.
-  Node* call = m.CallFunctionStub0(function_node, receiver, context2,
-                                   frame_state_before, CALL_AS_METHOD);
-
-  m.Return(call);
-
-  Stream s = m.Build(kAllExceptNopInstructions);
-
-  // Skip until kArchCallJSFunction.
-  size_t index = 0;
-  for (; index < s.size() && s[index]->arch_opcode() != kArchCallCodeObject;
-       index++) {
-  }
-  // Now we should have three instructions: call, return.
-  EXPECT_EQ(index + 2, s.size());
-
-  // Check the call instruction
-  const Instruction* call_instr = s[index++];
-  EXPECT_EQ(kArchCallCodeObject, call_instr->arch_opcode());
-  size_t num_operands =
-      1 +  // Code object.
-      1 +  // Frame state deopt id
-      4 +  // One input for each value in frame state + context.
-      4 +  // One input for each value in the parent frame state + context.
-      1 +  // Function.
-      1;   // Context.
-  EXPECT_EQ(num_operands, call_instr->InputCount());
-  // Code object.
-  EXPECT_TRUE(call_instr->InputAt(0)->IsImmediate());
-
-  // Deoptimization id.
-  int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1));
-  FrameStateDescriptor* desc_before =
-      s.GetFrameStateDescriptor(deopt_id_before);
-  EXPECT_EQ(bailout_id_before, desc_before->bailout_id());
-  EXPECT_EQ(1u, desc_before->parameters_count());
-  EXPECT_EQ(1u, desc_before->locals_count());
-  EXPECT_EQ(1u, desc_before->stack_count());
-  EXPECT_EQ(63, s.ToInt32(call_instr->InputAt(2)));
-  // Context:
-  EXPECT_EQ(66, s.ToInt32(call_instr->InputAt(3)));
-  EXPECT_EQ(64, s.ToInt32(call_instr->InputAt(4)));
-  EXPECT_EQ(65, s.ToInt32(call_instr->InputAt(5)));
-  // Values from parent environment should follow.
-  EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(6)));
-  EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(7)));
-  EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(8)));
-  EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(9)));
-
-  // Function.
-  EXPECT_EQ(function_node->id(), s.ToVreg(call_instr->InputAt(10)));
-  // Context.
-  EXPECT_EQ(context2->id(), s.ToVreg(call_instr->InputAt(11)));
-  // Continuation.
-
-  EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
-  EXPECT_EQ(index, s.size());
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/instruction-selector-unittest.h b/src/compiler/instruction-selector-unittest.h
deleted file mode 100644
index 4e12dab..0000000
--- a/src/compiler/instruction-selector-unittest.h
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_
-#define V8_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_
-
-#include <deque>
-#include <set>
-
-#include "src/base/utils/random-number-generator.h"
-#include "src/compiler/instruction-selector.h"
-#include "src/compiler/raw-machine-assembler.h"
-#include "src/test/test-utils.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class InstructionSelectorTest : public TestWithContext, public TestWithZone {
- public:
-  InstructionSelectorTest();
-  virtual ~InstructionSelectorTest();
-
-  base::RandomNumberGenerator* rng() { return &rng_; }
-
-  class Stream;
-
-  enum StreamBuilderMode {
-    kAllInstructions,
-    kTargetInstructions,
-    kAllExceptNopInstructions
-  };
-
-  class StreamBuilder FINAL : public RawMachineAssembler {
-   public:
-    StreamBuilder(InstructionSelectorTest* test, MachineType return_type)
-        : RawMachineAssembler(new (test->zone()) Graph(test->zone()),
-                              MakeMachineSignature(test->zone(), return_type)),
-          test_(test) {}
-    StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
-                  MachineType parameter0_type)
-        : RawMachineAssembler(
-              new (test->zone()) Graph(test->zone()),
-              MakeMachineSignature(test->zone(), return_type, parameter0_type)),
-          test_(test) {}
-    StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
-                  MachineType parameter0_type, MachineType parameter1_type)
-        : RawMachineAssembler(
-              new (test->zone()) Graph(test->zone()),
-              MakeMachineSignature(test->zone(), return_type, parameter0_type,
-                                   parameter1_type)),
-          test_(test) {}
-    StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
-                  MachineType parameter0_type, MachineType parameter1_type,
-                  MachineType parameter2_type)
-        : RawMachineAssembler(
-              new (test->zone()) Graph(test->zone()),
-              MakeMachineSignature(test->zone(), return_type, parameter0_type,
-                                   parameter1_type, parameter2_type)),
-          test_(test) {}
-
-    Stream Build(CpuFeature feature) {
-      return Build(InstructionSelector::Features(feature));
-    }
-    Stream Build(CpuFeature feature1, CpuFeature feature2) {
-      return Build(InstructionSelector::Features(feature1, feature2));
-    }
-    Stream Build(StreamBuilderMode mode = kTargetInstructions) {
-      return Build(InstructionSelector::Features(), mode);
-    }
-    Stream Build(InstructionSelector::Features features,
-                 StreamBuilderMode mode = kTargetInstructions);
-
-   private:
-    MachineSignature* MakeMachineSignature(Zone* zone,
-                                           MachineType return_type) {
-      MachineSignature::Builder builder(zone, 1, 0);
-      builder.AddReturn(return_type);
-      return builder.Build();
-    }
-
-    MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type,
-                                           MachineType parameter0_type) {
-      MachineSignature::Builder builder(zone, 1, 1);
-      builder.AddReturn(return_type);
-      builder.AddParam(parameter0_type);
-      return builder.Build();
-    }
-
-    MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type,
-                                           MachineType parameter0_type,
-                                           MachineType parameter1_type) {
-      MachineSignature::Builder builder(zone, 1, 2);
-      builder.AddReturn(return_type);
-      builder.AddParam(parameter0_type);
-      builder.AddParam(parameter1_type);
-      return builder.Build();
-    }
-
-    MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type,
-                                           MachineType parameter0_type,
-                                           MachineType parameter1_type,
-                                           MachineType parameter2_type) {
-      MachineSignature::Builder builder(zone, 1, 3);
-      builder.AddReturn(return_type);
-      builder.AddParam(parameter0_type);
-      builder.AddParam(parameter1_type);
-      builder.AddParam(parameter2_type);
-      return builder.Build();
-    }
-
-   private:
-    InstructionSelectorTest* test_;
-  };
-
-  class Stream FINAL {
-   public:
-    size_t size() const { return instructions_.size(); }
-    const Instruction* operator[](size_t index) const {
-      EXPECT_LT(index, size());
-      return instructions_[index];
-    }
-
-    bool IsDouble(const InstructionOperand* operand) const {
-      return IsDouble(ToVreg(operand));
-    }
-    bool IsDouble(int virtual_register) const {
-      return doubles_.find(virtual_register) != doubles_.end();
-    }
-
-    bool IsInteger(const InstructionOperand* operand) const {
-      return IsInteger(ToVreg(operand));
-    }
-    bool IsInteger(int virtual_register) const {
-      return !IsDouble(virtual_register) && !IsReference(virtual_register);
-    }
-
-    bool IsReference(const InstructionOperand* operand) const {
-      return IsReference(ToVreg(operand));
-    }
-    bool IsReference(int virtual_register) const {
-      return references_.find(virtual_register) != references_.end();
-    }
-
-    int32_t ToInt32(const InstructionOperand* operand) const {
-      return ToConstant(operand).ToInt32();
-    }
-
-    int64_t ToInt64(const InstructionOperand* operand) const {
-      return ToConstant(operand).ToInt64();
-    }
-
-    int ToVreg(const InstructionOperand* operand) const {
-      if (operand->IsConstant()) return operand->index();
-      EXPECT_EQ(InstructionOperand::UNALLOCATED, operand->kind());
-      return UnallocatedOperand::cast(operand)->virtual_register();
-    }
-
-    FrameStateDescriptor* GetFrameStateDescriptor(int deoptimization_id) {
-      EXPECT_LT(deoptimization_id, GetFrameStateDescriptorCount());
-      return deoptimization_entries_[deoptimization_id];
-    }
-
-    int GetFrameStateDescriptorCount() {
-      return static_cast<int>(deoptimization_entries_.size());
-    }
-
-   private:
-    Constant ToConstant(const InstructionOperand* operand) const {
-      ConstantMap::const_iterator i;
-      if (operand->IsConstant()) {
-        i = constants_.find(operand->index());
-        EXPECT_FALSE(constants_.end() == i);
-      } else {
-        EXPECT_EQ(InstructionOperand::IMMEDIATE, operand->kind());
-        i = immediates_.find(operand->index());
-        EXPECT_FALSE(immediates_.end() == i);
-      }
-      EXPECT_EQ(operand->index(), i->first);
-      return i->second;
-    }
-
-    friend class StreamBuilder;
-
-    typedef std::map<int, Constant> ConstantMap;
-
-    ConstantMap constants_;
-    ConstantMap immediates_;
-    std::deque<Instruction*> instructions_;
-    std::set<int> doubles_;
-    std::set<int> references_;
-    std::deque<FrameStateDescriptor*> deoptimization_entries_;
-  };
-
-  base::RandomNumberGenerator rng_;
-};
-
-
-template <typename T>
-class InstructionSelectorTestWithParam
-    : public InstructionSelectorTest,
-      public ::testing::WithParamInterface<T> {};
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_
diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc
index 3c32b64..ffb8f9f 100644
--- a/src/compiler/instruction-selector.cc
+++ b/src/compiler/instruction-selector.cc
@@ -4,6 +4,7 @@
 
 #include "src/compiler/instruction-selector.h"
 
+#include "src/compiler/graph.h"
 #include "src/compiler/instruction-selector-impl.h"
 #include "src/compiler/node-matchers.h"
 #include "src/compiler/node-properties-inl.h"
@@ -13,17 +14,23 @@
 namespace internal {
 namespace compiler {
 
-InstructionSelector::InstructionSelector(InstructionSequence* sequence,
+InstructionSelector::InstructionSelector(Zone* local_zone, Graph* graph,
+                                         Linkage* linkage,
+                                         InstructionSequence* sequence,
+                                         Schedule* schedule,
                                          SourcePositionTable* source_positions,
                                          Features features)
-    : zone_(sequence->isolate()),
+    : zone_(local_zone),
+      linkage_(linkage),
       sequence_(sequence),
       source_positions_(source_positions),
       features_(features),
+      schedule_(schedule),
+      node_map_(graph->NodeCount(), kNodeUnmapped, zone()),
       current_block_(NULL),
       instructions_(zone()),
-      defined_(graph()->NodeCount(), false, zone()),
-      used_(graph()->NodeCount(), false, zone()) {}
+      defined_(graph->NodeCount(), false, zone()),
+      used_(graph->NodeCount(), false, zone()) {}
 
 
 void InstructionSelector::SelectInstructions() {
@@ -32,17 +39,16 @@
   for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) {
     BasicBlock* block = *i;
     if (!block->IsLoopHeader()) continue;
-    DCHECK_NE(0, block->PredecessorCount());
-    DCHECK_NE(1, block->PredecessorCount());
+    DCHECK_NE(0, static_cast<int>(block->PredecessorCount()));
+    DCHECK_NE(1, static_cast<int>(block->PredecessorCount()));
     for (BasicBlock::const_iterator j = block->begin(); j != block->end();
          ++j) {
       Node* phi = *j;
       if (phi->opcode() != IrOpcode::kPhi) continue;
 
       // Mark all inputs as used.
-      Node::Inputs inputs = phi->inputs();
-      for (InputIter k = inputs.begin(); k != inputs.end(); ++k) {
-        MarkAsUsed(*k);
+      for (Node* const k : phi->inputs()) {
+        MarkAsUsed(k);
       }
     }
   }
@@ -55,13 +61,15 @@
   // Schedule the selected instructions.
   for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end(); ++i) {
     BasicBlock* block = *i;
-    size_t end = block->code_end_;
-    size_t start = block->code_start_;
-    sequence()->StartBlock(block);
+    InstructionBlock* instruction_block =
+        sequence()->InstructionBlockAt(block->GetRpoNumber());
+    size_t end = instruction_block->code_end();
+    size_t start = instruction_block->code_start();
+    sequence()->StartBlock(block->GetRpoNumber());
     while (start-- > end) {
-      sequence()->AddInstruction(instructions_[start], block);
+      sequence()->AddInstruction(instructions_[start]);
     }
-    sequence()->EndBlock(block);
+    sequence()->EndBlock(block->GetRpoNumber());
   }
 }
 
@@ -124,6 +132,31 @@
 
 
 Instruction* InstructionSelector::Emit(
+    InstructionCode opcode, InstructionOperand* output, InstructionOperand* a,
+    InstructionOperand* b, InstructionOperand* c, InstructionOperand* d,
+    InstructionOperand* e, size_t temp_count, InstructionOperand** temps) {
+  size_t output_count = output == NULL ? 0 : 1;
+  InstructionOperand* inputs[] = {a, b, c, d, e};
+  size_t input_count = arraysize(inputs);
+  return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
+              temps);
+}
+
+
+Instruction* InstructionSelector::Emit(
+    InstructionCode opcode, InstructionOperand* output, InstructionOperand* a,
+    InstructionOperand* b, InstructionOperand* c, InstructionOperand* d,
+    InstructionOperand* e, InstructionOperand* f, size_t temp_count,
+    InstructionOperand** temps) {
+  size_t output_count = output == NULL ? 0 : 1;
+  InstructionOperand* inputs[] = {a, b, c, d, e, f};
+  size_t input_count = arraysize(inputs);
+  return Emit(opcode, output_count, &output, input_count, inputs, temp_count,
+              temps);
+}
+
+
+Instruction* InstructionSelector::Emit(
     InstructionCode opcode, size_t output_count, InstructionOperand** outputs,
     size_t input_count, InstructionOperand** inputs, size_t temp_count,
     InstructionOperand** temps) {
@@ -140,18 +173,25 @@
 }
 
 
-bool InstructionSelector::IsNextInAssemblyOrder(const BasicBlock* block) const {
-  return block->rpo_number_ == (current_block_->rpo_number_ + 1) &&
-         block->deferred_ == current_block_->deferred_;
-}
-
-
 bool InstructionSelector::CanCover(Node* user, Node* node) const {
   return node->OwnedBy(user) &&
          schedule()->block(node) == schedule()->block(user);
 }
 
 
+int InstructionSelector::GetVirtualRegister(const Node* node) {
+  if (node_map_[node->id()] == kNodeUnmapped) {
+    node_map_[node->id()] = sequence()->NextVirtualRegister();
+  }
+  return node_map_[node->id()];
+}
+
+
+int InstructionSelector::GetMappedVirtualRegister(const Node* node) const {
+  return node_map_[node->id()];
+}
+
+
 bool InstructionSelector::IsDefined(Node* node) const {
   DCHECK_NOT_NULL(node);
   NodeId id = node->id();
@@ -190,27 +230,48 @@
 
 bool InstructionSelector::IsDouble(const Node* node) const {
   DCHECK_NOT_NULL(node);
-  return sequence()->IsDouble(node->id());
+  int virtual_register = GetMappedVirtualRegister(node);
+  if (virtual_register == kNodeUnmapped) return false;
+  return sequence()->IsDouble(virtual_register);
 }
 
 
 void InstructionSelector::MarkAsDouble(Node* node) {
   DCHECK_NOT_NULL(node);
   DCHECK(!IsReference(node));
-  sequence()->MarkAsDouble(node->id());
+  sequence()->MarkAsDouble(GetVirtualRegister(node));
 }
 
 
 bool InstructionSelector::IsReference(const Node* node) const {
   DCHECK_NOT_NULL(node);
-  return sequence()->IsReference(node->id());
+  int virtual_register = GetMappedVirtualRegister(node);
+  if (virtual_register == kNodeUnmapped) return false;
+  return sequence()->IsReference(virtual_register);
 }
 
 
 void InstructionSelector::MarkAsReference(Node* node) {
   DCHECK_NOT_NULL(node);
   DCHECK(!IsDouble(node));
-  sequence()->MarkAsReference(node->id());
+  sequence()->MarkAsReference(GetVirtualRegister(node));
+}
+
+
+void InstructionSelector::MarkAsRepresentation(MachineType rep,
+                                               InstructionOperand* op) {
+  UnallocatedOperand* unalloc = UnallocatedOperand::cast(op);
+  switch (RepresentationOf(rep)) {
+    case kRepFloat32:
+    case kRepFloat64:
+      sequence()->MarkAsDouble(unalloc->virtual_register());
+      break;
+    case kRepTagged:
+      sequence()->MarkAsReference(unalloc->virtual_register());
+      break;
+    default:
+      break;
+  }
 }
 
 
@@ -232,7 +293,7 @@
 
 // TODO(bmeurer): Get rid of the CallBuffer business and make
 // InstructionSelector::VisitCall platform independent instead.
-CallBuffer::CallBuffer(Zone* zone, CallDescriptor* d,
+CallBuffer::CallBuffer(Zone* zone, const CallDescriptor* d,
                        FrameStateDescriptor* frame_desc)
     : descriptor(d),
       frame_state_descriptor(frame_desc),
@@ -253,9 +314,11 @@
                                                bool call_code_immediate,
                                                bool call_address_immediate) {
   OperandGenerator g(this);
-  DCHECK_EQ(call->op()->OutputCount(), buffer->descriptor->ReturnCount());
-  DCHECK_EQ(OperatorProperties::GetValueInputCount(call->op()),
-            buffer->input_count() + buffer->frame_state_count());
+  DCHECK_EQ(call->op()->ValueOutputCount(),
+            static_cast<int>(buffer->descriptor->ReturnCount()));
+  DCHECK_EQ(
+      call->op()->ValueInputCount(),
+      static_cast<int>(buffer->input_count() + buffer->frame_state_count()));
 
   if (buffer->descriptor->ReturnCount() > 0) {
     // Collect the projections that represent multiple outputs from this call.
@@ -267,15 +330,27 @@
     }
 
     // Filter out the outputs that aren't live because no projection uses them.
+    size_t outputs_needed_by_framestate =
+        buffer->frame_state_descriptor == NULL
+            ? 0
+            : buffer->frame_state_descriptor->state_combine()
+                  .ConsumedOutputCount();
     for (size_t i = 0; i < buffer->output_nodes.size(); i++) {
-      if (buffer->output_nodes[i] != NULL) {
-        Node* output = buffer->output_nodes[i];
+      bool output_is_live =
+          buffer->output_nodes[i] != NULL || i < outputs_needed_by_framestate;
+      if (output_is_live) {
         MachineType type =
             buffer->descriptor->GetReturnType(static_cast<int>(i));
         LinkageLocation location =
             buffer->descriptor->GetReturnLocation(static_cast<int>(i));
-        MarkAsRepresentation(type, output);
-        buffer->outputs.push_back(g.DefineAsLocation(output, location, type));
+
+        Node* output = buffer->output_nodes[i];
+        InstructionOperand* op =
+            output == NULL ? g.TempLocation(location, type)
+                           : g.DefineAsLocation(output, location, type);
+        MarkAsRepresentation(type, op);
+
+        buffer->outputs.push_back(op);
       }
     }
   }
@@ -303,7 +378,7 @@
                         buffer->descriptor->GetInputType(0)));
       break;
   }
-  DCHECK_EQ(1, buffer->instruction_args.size());
+  DCHECK_EQ(1, static_cast<int>(buffer->instruction_args.size()));
 
   // If the call needs a frame state, we insert the state information as
   // follows (n is the number of value inputs to the frame state):
@@ -328,11 +403,10 @@
   // arguments require an explicit push instruction before the call and do
   // not appear as arguments to the call. Everything else ends up
   // as an InstructionOperand argument to the call.
-  InputIter iter(call->inputs().begin());
+  auto iter(call->inputs().begin());
   int pushed_count = 0;
   for (size_t index = 0; index < input_count; ++iter, ++index) {
     DCHECK(iter != call->inputs().end());
-    DCHECK(index == static_cast<size_t>(iter.index()));
     DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState);
     if (index == 0) continue;  // The first argument (callee) is already done.
     InstructionOperand* op =
@@ -382,9 +456,10 @@
   }
 
   // We're done with the block.
-  // TODO(bmeurer): We should not mutate the schedule.
-  block->code_end_ = current_block_end;
-  block->code_start_ = static_cast<int>(instructions_.size());
+  InstructionBlock* instruction_block =
+      sequence()->InstructionBlockAt(block->GetRpoNumber());
+  instruction_block->set_code_start(static_cast<int>(instructions_.size()));
+  instruction_block->set_code_end(current_block_end);
 
   current_block_ = NULL;
 }
@@ -402,11 +477,11 @@
 
 
 void InstructionSelector::VisitControl(BasicBlock* block) {
-  Node* input = block->control_input_;
-  switch (block->control_) {
-    case BasicBlockData::kGoto:
+  Node* input = block->control_input();
+  switch (block->control()) {
+    case BasicBlock::kGoto:
       return VisitGoto(block->SuccessorAt(0));
-    case BasicBlockData::kBranch: {
+    case BasicBlock::kBranch: {
       DCHECK_EQ(IrOpcode::kBranch, input->opcode());
       BasicBlock* tbranch = block->SuccessorAt(0);
       BasicBlock* fbranch = block->SuccessorAt(1);
@@ -417,16 +492,16 @@
       if (tbranch == fbranch) return VisitGoto(tbranch);
       return VisitBranch(input, tbranch, fbranch);
     }
-    case BasicBlockData::kReturn: {
+    case BasicBlock::kReturn: {
       // If the result itself is a return, return its input.
       Node* value = (input != NULL && input->opcode() == IrOpcode::kReturn)
                         ? input->InputAt(0)
                         : input;
       return VisitReturn(value);
     }
-    case BasicBlockData::kThrow:
+    case BasicBlock::kThrow:
       return VisitThrow(input);
-    case BasicBlockData::kNone: {
+    case BasicBlock::kNone: {
       // TODO(titzer): exit block doesn't have control.
       DCHECK(input == NULL);
       break;
@@ -438,6 +513,135 @@
 }
 
 
+MachineType InstructionSelector::GetMachineType(Node* node) {
+  DCHECK_NOT_NULL(schedule()->block(node));  // should only use scheduled nodes.
+  switch (node->opcode()) {
+    case IrOpcode::kStart:
+    case IrOpcode::kLoop:
+    case IrOpcode::kEnd:
+    case IrOpcode::kBranch:
+    case IrOpcode::kIfTrue:
+    case IrOpcode::kIfFalse:
+    case IrOpcode::kEffectPhi:
+    case IrOpcode::kMerge:
+    case IrOpcode::kTerminate:
+      // No code needed for these graph artifacts.
+      return kMachNone;
+    case IrOpcode::kFinish:
+      return kMachAnyTagged;
+    case IrOpcode::kParameter:
+      return linkage()->GetParameterType(OpParameter<int>(node));
+    case IrOpcode::kPhi:
+      return OpParameter<MachineType>(node);
+    case IrOpcode::kProjection:
+      // TODO(jarin) Really project from outputs.
+      return kMachAnyTagged;
+    case IrOpcode::kInt32Constant:
+      return kMachInt32;
+    case IrOpcode::kInt64Constant:
+      return kMachInt64;
+    case IrOpcode::kExternalConstant:
+      return kMachPtr;
+    case IrOpcode::kFloat64Constant:
+      return kMachFloat64;
+    case IrOpcode::kHeapConstant:
+    case IrOpcode::kNumberConstant:
+      return kMachAnyTagged;
+    case IrOpcode::kCall:
+      return kMachAnyTagged;
+    case IrOpcode::kFrameState:
+    case IrOpcode::kStateValues:
+      return kMachNone;
+    case IrOpcode::kLoad:
+      return OpParameter<LoadRepresentation>(node);
+    case IrOpcode::kStore:
+      return kMachNone;
+    case IrOpcode::kCheckedLoad:
+      return OpParameter<MachineType>(node);
+    case IrOpcode::kCheckedStore:
+      return kMachNone;
+    case IrOpcode::kWord32And:
+    case IrOpcode::kWord32Or:
+    case IrOpcode::kWord32Xor:
+    case IrOpcode::kWord32Shl:
+    case IrOpcode::kWord32Shr:
+    case IrOpcode::kWord32Sar:
+    case IrOpcode::kWord32Ror:
+      return kMachInt32;
+    case IrOpcode::kWord32Equal:
+      return kMachBool;
+    case IrOpcode::kWord64And:
+    case IrOpcode::kWord64Or:
+    case IrOpcode::kWord64Xor:
+    case IrOpcode::kWord64Shl:
+    case IrOpcode::kWord64Shr:
+    case IrOpcode::kWord64Sar:
+    case IrOpcode::kWord64Ror:
+      return kMachInt64;
+    case IrOpcode::kWord64Equal:
+      return kMachBool;
+    case IrOpcode::kInt32Add:
+    case IrOpcode::kInt32AddWithOverflow:
+    case IrOpcode::kInt32Sub:
+    case IrOpcode::kInt32SubWithOverflow:
+    case IrOpcode::kInt32Mul:
+    case IrOpcode::kInt32Div:
+    case IrOpcode::kInt32Mod:
+      return kMachInt32;
+    case IrOpcode::kInt32LessThan:
+    case IrOpcode::kInt32LessThanOrEqual:
+    case IrOpcode::kUint32LessThan:
+    case IrOpcode::kUint32LessThanOrEqual:
+      return kMachBool;
+    case IrOpcode::kInt64Add:
+    case IrOpcode::kInt64Sub:
+    case IrOpcode::kInt64Mul:
+    case IrOpcode::kInt64Div:
+    case IrOpcode::kInt64Mod:
+      return kMachInt64;
+    case IrOpcode::kInt64LessThan:
+    case IrOpcode::kInt64LessThanOrEqual:
+      return kMachBool;
+    case IrOpcode::kChangeFloat32ToFloat64:
+    case IrOpcode::kChangeInt32ToFloat64:
+    case IrOpcode::kChangeUint32ToFloat64:
+      return kMachFloat64;
+    case IrOpcode::kChangeFloat64ToInt32:
+      return kMachInt32;
+    case IrOpcode::kChangeFloat64ToUint32:
+      return kMachUint32;
+    case IrOpcode::kChangeInt32ToInt64:
+      return kMachInt64;
+    case IrOpcode::kChangeUint32ToUint64:
+      return kMachUint64;
+    case IrOpcode::kTruncateFloat64ToFloat32:
+      return kMachFloat32;
+    case IrOpcode::kTruncateFloat64ToInt32:
+    case IrOpcode::kTruncateInt64ToInt32:
+      return kMachInt32;
+    case IrOpcode::kFloat64Add:
+    case IrOpcode::kFloat64Sub:
+    case IrOpcode::kFloat64Mul:
+    case IrOpcode::kFloat64Div:
+    case IrOpcode::kFloat64Mod:
+    case IrOpcode::kFloat64Sqrt:
+    case IrOpcode::kFloat64Floor:
+    case IrOpcode::kFloat64Ceil:
+    case IrOpcode::kFloat64RoundTruncate:
+    case IrOpcode::kFloat64RoundTiesAway:
+      return kMachFloat64;
+    case IrOpcode::kFloat64Equal:
+    case IrOpcode::kFloat64LessThan:
+    case IrOpcode::kFloat64LessThanOrEqual:
+      return kMachBool;
+    default:
+      V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d",
+               node->opcode(), node->op()->mnemonic(), node->id());
+  }
+  return kMachNone;
+}
+
+
 void InstructionSelector::VisitNode(Node* node) {
   DCHECK_NOT_NULL(schedule()->block(node));  // should only use scheduled nodes.
   SourcePosition source_position = source_positions_->GetSourcePosition(node);
@@ -476,6 +680,8 @@
     case IrOpcode::kInt64Constant:
     case IrOpcode::kExternalConstant:
       return VisitConstant(node);
+    case IrOpcode::kFloat32Constant:
+      return MarkAsDouble(node), VisitConstant(node);
     case IrOpcode::kFloat64Constant:
       return MarkAsDouble(node), VisitConstant(node);
     case IrOpcode::kHeapConstant:
@@ -483,7 +689,7 @@
       // TODO(turbofan): only mark non-smis as references.
       return MarkAsReference(node), VisitConstant(node);
     case IrOpcode::kCall:
-      return VisitCall(node, NULL, NULL);
+      return VisitCall(node);
     case IrOpcode::kFrameState:
     case IrOpcode::kStateValues:
       return;
@@ -536,22 +742,26 @@
       return VisitInt32SubWithOverflow(node);
     case IrOpcode::kInt32Mul:
       return VisitInt32Mul(node);
+    case IrOpcode::kInt32MulHigh:
+      return VisitInt32MulHigh(node);
     case IrOpcode::kInt32Div:
       return VisitInt32Div(node);
-    case IrOpcode::kInt32UDiv:
-      return VisitInt32UDiv(node);
     case IrOpcode::kInt32Mod:
       return VisitInt32Mod(node);
-    case IrOpcode::kInt32UMod:
-      return VisitInt32UMod(node);
     case IrOpcode::kInt32LessThan:
       return VisitInt32LessThan(node);
     case IrOpcode::kInt32LessThanOrEqual:
       return VisitInt32LessThanOrEqual(node);
+    case IrOpcode::kUint32Div:
+      return VisitUint32Div(node);
     case IrOpcode::kUint32LessThan:
       return VisitUint32LessThan(node);
     case IrOpcode::kUint32LessThanOrEqual:
       return VisitUint32LessThanOrEqual(node);
+    case IrOpcode::kUint32Mod:
+      return VisitUint32Mod(node);
+    case IrOpcode::kUint32MulHigh:
+      return VisitUint32MulHigh(node);
     case IrOpcode::kInt64Add:
       return VisitInt64Add(node);
     case IrOpcode::kInt64Sub:
@@ -560,16 +770,20 @@
       return VisitInt64Mul(node);
     case IrOpcode::kInt64Div:
       return VisitInt64Div(node);
-    case IrOpcode::kInt64UDiv:
-      return VisitInt64UDiv(node);
     case IrOpcode::kInt64Mod:
       return VisitInt64Mod(node);
-    case IrOpcode::kInt64UMod:
-      return VisitInt64UMod(node);
     case IrOpcode::kInt64LessThan:
       return VisitInt64LessThan(node);
     case IrOpcode::kInt64LessThanOrEqual:
       return VisitInt64LessThanOrEqual(node);
+    case IrOpcode::kUint64Div:
+      return VisitUint64Div(node);
+    case IrOpcode::kUint64LessThan:
+      return VisitUint64LessThan(node);
+    case IrOpcode::kUint64Mod:
+      return VisitUint64Mod(node);
+    case IrOpcode::kChangeFloat32ToFloat64:
+      return MarkAsDouble(node), VisitChangeFloat32ToFloat64(node);
     case IrOpcode::kChangeInt32ToFloat64:
       return MarkAsDouble(node), VisitChangeInt32ToFloat64(node);
     case IrOpcode::kChangeUint32ToFloat64:
@@ -582,6 +796,8 @@
       return VisitChangeInt32ToInt64(node);
     case IrOpcode::kChangeUint32ToUint64:
       return VisitChangeUint32ToUint64(node);
+    case IrOpcode::kTruncateFloat64ToFloat32:
+      return MarkAsDouble(node), VisitTruncateFloat64ToFloat32(node);
     case IrOpcode::kTruncateFloat64ToInt32:
       return VisitTruncateFloat64ToInt32(node);
     case IrOpcode::kTruncateInt64ToInt32:
@@ -604,91 +820,33 @@
       return VisitFloat64LessThan(node);
     case IrOpcode::kFloat64LessThanOrEqual:
       return VisitFloat64LessThanOrEqual(node);
+    case IrOpcode::kFloat64Floor:
+      return MarkAsDouble(node), VisitFloat64Floor(node);
+    case IrOpcode::kFloat64Ceil:
+      return MarkAsDouble(node), VisitFloat64Ceil(node);
+    case IrOpcode::kFloat64RoundTruncate:
+      return MarkAsDouble(node), VisitFloat64RoundTruncate(node);
+    case IrOpcode::kFloat64RoundTiesAway:
+      return MarkAsDouble(node), VisitFloat64RoundTiesAway(node);
+    case IrOpcode::kLoadStackPointer:
+      return VisitLoadStackPointer(node);
+    case IrOpcode::kCheckedLoad: {
+      MachineType rep = OpParameter<MachineType>(node);
+      MarkAsRepresentation(rep, node);
+      return VisitCheckedLoad(node);
+    }
+    case IrOpcode::kCheckedStore:
+      return VisitCheckedStore(node);
     default:
       V8_Fatal(__FILE__, __LINE__, "Unexpected operator #%d:%s @ node #%d",
                node->opcode(), node->op()->mnemonic(), node->id());
+      break;
   }
 }
 
 
 #if V8_TURBOFAN_BACKEND
 
-void InstructionSelector::VisitWord32Equal(Node* node) {
-  FlagsContinuation cont(kEqual, node);
-  Int32BinopMatcher m(node);
-  if (m.right().Is(0)) {
-    return VisitWord32Test(m.left().node(), &cont);
-  }
-  VisitWord32Compare(node, &cont);
-}
-
-
-void InstructionSelector::VisitInt32LessThan(Node* node) {
-  FlagsContinuation cont(kSignedLessThan, node);
-  VisitWord32Compare(node, &cont);
-}
-
-
-void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
-  FlagsContinuation cont(kSignedLessThanOrEqual, node);
-  VisitWord32Compare(node, &cont);
-}
-
-
-void InstructionSelector::VisitUint32LessThan(Node* node) {
-  FlagsContinuation cont(kUnsignedLessThan, node);
-  VisitWord32Compare(node, &cont);
-}
-
-
-void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
-  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
-  VisitWord32Compare(node, &cont);
-}
-
-
-void InstructionSelector::VisitWord64Equal(Node* node) {
-  FlagsContinuation cont(kEqual, node);
-  Int64BinopMatcher m(node);
-  if (m.right().Is(0)) {
-    return VisitWord64Test(m.left().node(), &cont);
-  }
-  VisitWord64Compare(node, &cont);
-}
-
-
-void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
-    FlagsContinuation cont(kOverflow, ovf);
-    return VisitInt32AddWithOverflow(node, &cont);
-  }
-  FlagsContinuation cont;
-  VisitInt32AddWithOverflow(node, &cont);
-}
-
-
-void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
-  if (Node* ovf = node->FindProjection(1)) {
-    FlagsContinuation cont(kOverflow, ovf);
-    return VisitInt32SubWithOverflow(node, &cont);
-  }
-  FlagsContinuation cont;
-  VisitInt32SubWithOverflow(node, &cont);
-}
-
-
-void InstructionSelector::VisitInt64LessThan(Node* node) {
-  FlagsContinuation cont(kSignedLessThan, node);
-  VisitWord64Compare(node, &cont);
-}
-
-
-void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
-  FlagsContinuation cont(kSignedLessThanOrEqual, node);
-  VisitWord64Compare(node, &cont);
-}
-
-
 void InstructionSelector::VisitTruncateFloat64ToInt32(Node* node) {
   OperandGenerator g(this);
   Emit(kArchTruncateDoubleToI, g.DefineAsRegister(node),
@@ -696,27 +854,15 @@
 }
 
 
-void InstructionSelector::VisitFloat64Equal(Node* node) {
-  FlagsContinuation cont(kUnorderedEqual, node);
-  VisitFloat64Compare(node, &cont);
-}
-
-
-void InstructionSelector::VisitFloat64LessThan(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThan, node);
-  VisitFloat64Compare(node, &cont);
-}
-
-
-void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
-  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
-  VisitFloat64Compare(node, &cont);
+void InstructionSelector::VisitLoadStackPointer(Node* node) {
+  OperandGenerator g(this);
+  Emit(kArchStackPointer, g.DefineAsRegister(node));
 }
 
 #endif  // V8_TURBOFAN_BACKEND
 
 // 32 bit targets do not implement the following instructions.
-#if V8_TARGET_ARCH_32_BIT && V8_TURBOFAN_BACKEND
+#if V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_X64 && V8_TURBOFAN_BACKEND
 
 void InstructionSelector::VisitWord64And(Node* node) { UNIMPLEMENTED(); }
 
@@ -739,6 +885,9 @@
 void InstructionSelector::VisitWord64Ror(Node* node) { UNIMPLEMENTED(); }
 
 
+void InstructionSelector::VisitWord64Equal(Node* node) { UNIMPLEMENTED(); }
+
+
 void InstructionSelector::VisitInt64Add(Node* node) { UNIMPLEMENTED(); }
 
 
@@ -751,13 +900,24 @@
 void InstructionSelector::VisitInt64Div(Node* node) { UNIMPLEMENTED(); }
 
 
-void InstructionSelector::VisitInt64UDiv(Node* node) { UNIMPLEMENTED(); }
+void InstructionSelector::VisitInt64LessThan(Node* node) { UNIMPLEMENTED(); }
+
+
+void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
+  UNIMPLEMENTED();
+}
+
+
+void InstructionSelector::VisitUint64Div(Node* node) { UNIMPLEMENTED(); }
 
 
 void InstructionSelector::VisitInt64Mod(Node* node) { UNIMPLEMENTED(); }
 
 
-void InstructionSelector::VisitInt64UMod(Node* node) { UNIMPLEMENTED(); }
+void InstructionSelector::VisitUint64LessThan(Node* node) { UNIMPLEMENTED(); }
+
+
+void InstructionSelector::VisitUint64Mod(Node* node) { UNIMPLEMENTED(); }
 
 
 void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
@@ -774,24 +934,7 @@
   UNIMPLEMENTED();
 }
 
-#endif  // V8_TARGET_ARCH_32_BIT && V8_TURBOFAN_BACKEND
-
-
-// 32-bit targets and unsupported architectures need dummy implementations of
-// selected 64-bit ops.
-#if V8_TARGET_ARCH_32_BIT || !V8_TURBOFAN_BACKEND
-
-void InstructionSelector::VisitWord64Test(Node* node, FlagsContinuation* cont) {
-  UNIMPLEMENTED();
-}
-
-
-void InstructionSelector::VisitWord64Compare(Node* node,
-                                             FlagsContinuation* cont) {
-  UNIMPLEMENTED();
-}
-
-#endif  // V8_TARGET_ARCH_32_BIT || !V8_TURBOFAN_BACKEND
+#endif  // V8_TARGET_ARCH_32_BIT && !V8_TARGET_ARCH_X64 && V8_TURBOFAN_BACKEND
 
 
 void InstructionSelector::VisitFinish(Node* node) {
@@ -811,9 +954,15 @@
 
 
 void InstructionSelector::VisitPhi(Node* node) {
-  // TODO(bmeurer): Emit a PhiInstruction here.
-  for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) {
-    MarkAsUsed(*i);
+  const int input_count = node->op()->ValueInputCount();
+  PhiInstruction* phi = new (instruction_zone())
+      PhiInstruction(instruction_zone(), GetVirtualRegister(node),
+                     static_cast<size_t>(input_count));
+  sequence()->InstructionBlockAt(current_block_->GetRpoNumber())->AddPhi(phi);
+  for (int i = 0; i < input_count; ++i) {
+    Node* const input = node->InputAt(i);
+    MarkAsUsed(input);
+    phi->Extend(instruction_zone(), GetVirtualRegister(input));
   }
 }
 
@@ -846,124 +995,9 @@
 
 
 void InstructionSelector::VisitGoto(BasicBlock* target) {
-  if (IsNextInAssemblyOrder(target)) {
-    // fall through to the next block.
-    Emit(kArchNop, NULL)->MarkAsControl();
-  } else {
-    // jump to the next block.
-    OperandGenerator g(this);
-    Emit(kArchJmp, NULL, g.Label(target))->MarkAsControl();
-  }
-}
-
-
-void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
-                                      BasicBlock* fbranch) {
+  // jump to the next block.
   OperandGenerator g(this);
-  Node* user = branch;
-  Node* value = branch->InputAt(0);
-
-  FlagsContinuation cont(kNotEqual, tbranch, fbranch);
-
-  // If we can fall through to the true block, invert the branch.
-  if (IsNextInAssemblyOrder(tbranch)) {
-    cont.Negate();
-    cont.SwapBlocks();
-  }
-
-  // Try to combine with comparisons against 0 by simply inverting the branch.
-  while (CanCover(user, value)) {
-    if (value->opcode() == IrOpcode::kWord32Equal) {
-      Int32BinopMatcher m(value);
-      if (m.right().Is(0)) {
-        user = value;
-        value = m.left().node();
-        cont.Negate();
-      } else {
-        break;
-      }
-    } else if (value->opcode() == IrOpcode::kWord64Equal) {
-      Int64BinopMatcher m(value);
-      if (m.right().Is(0)) {
-        user = value;
-        value = m.left().node();
-        cont.Negate();
-      } else {
-        break;
-      }
-    } else {
-      break;
-    }
-  }
-
-  // Try to combine the branch with a comparison.
-  if (CanCover(user, value)) {
-    switch (value->opcode()) {
-      case IrOpcode::kWord32Equal:
-        cont.OverwriteAndNegateIfEqual(kEqual);
-        return VisitWord32Compare(value, &cont);
-      case IrOpcode::kInt32LessThan:
-        cont.OverwriteAndNegateIfEqual(kSignedLessThan);
-        return VisitWord32Compare(value, &cont);
-      case IrOpcode::kInt32LessThanOrEqual:
-        cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
-        return VisitWord32Compare(value, &cont);
-      case IrOpcode::kUint32LessThan:
-        cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
-        return VisitWord32Compare(value, &cont);
-      case IrOpcode::kUint32LessThanOrEqual:
-        cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
-        return VisitWord32Compare(value, &cont);
-      case IrOpcode::kWord64Equal:
-        cont.OverwriteAndNegateIfEqual(kEqual);
-        return VisitWord64Compare(value, &cont);
-      case IrOpcode::kInt64LessThan:
-        cont.OverwriteAndNegateIfEqual(kSignedLessThan);
-        return VisitWord64Compare(value, &cont);
-      case IrOpcode::kInt64LessThanOrEqual:
-        cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
-        return VisitWord64Compare(value, &cont);
-      case IrOpcode::kFloat64Equal:
-        cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
-        return VisitFloat64Compare(value, &cont);
-      case IrOpcode::kFloat64LessThan:
-        cont.OverwriteAndNegateIfEqual(kUnorderedLessThan);
-        return VisitFloat64Compare(value, &cont);
-      case IrOpcode::kFloat64LessThanOrEqual:
-        cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
-        return VisitFloat64Compare(value, &cont);
-      case IrOpcode::kProjection:
-        // Check if this is the overflow output projection of an
-        // <Operation>WithOverflow node.
-        if (OpParameter<size_t>(value) == 1u) {
-          // We cannot combine the <Operation>WithOverflow with this branch
-          // unless the 0th projection (the use of the actual value of the
-          // <Operation> is either NULL, which means there's no use of the
-          // actual value, or was already defined, which means it is scheduled
-          // *AFTER* this branch).
-          Node* node = value->InputAt(0);
-          Node* result = node->FindProjection(0);
-          if (result == NULL || IsDefined(result)) {
-            switch (node->opcode()) {
-              case IrOpcode::kInt32AddWithOverflow:
-                cont.OverwriteAndNegateIfEqual(kOverflow);
-                return VisitInt32AddWithOverflow(node, &cont);
-              case IrOpcode::kInt32SubWithOverflow:
-                cont.OverwriteAndNegateIfEqual(kOverflow);
-                return VisitInt32SubWithOverflow(node, &cont);
-              default:
-                break;
-            }
-          }
-        }
-        break;
-      default:
-        break;
-    }
-  }
-
-  // Branch could not be combined with a compare, emit compare against 0.
-  VisitWord32Test(value, &cont);
+  Emit(kArchJmp, NULL, g.Label(target))->MarkAsControl();
 }
 
 
@@ -983,14 +1017,29 @@
 }
 
 
+void InstructionSelector::FillTypeVectorFromStateValues(
+    ZoneVector<MachineType>* types, Node* state_values) {
+  DCHECK(state_values->opcode() == IrOpcode::kStateValues);
+  int count = state_values->InputCount();
+  types->reserve(static_cast<size_t>(count));
+  for (int i = 0; i < count; i++) {
+    types->push_back(GetMachineType(state_values->InputAt(i)));
+  }
+}
+
+
 FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor(
     Node* state) {
   DCHECK(state->opcode() == IrOpcode::kFrameState);
   DCHECK_EQ(5, state->InputCount());
+  DCHECK_EQ(IrOpcode::kStateValues, state->InputAt(0)->opcode());
+  DCHECK_EQ(IrOpcode::kStateValues, state->InputAt(1)->opcode());
+  DCHECK_EQ(IrOpcode::kStateValues, state->InputAt(2)->opcode());
   FrameStateCallInfo state_info = OpParameter<FrameStateCallInfo>(state);
-  int parameters = OpParameter<int>(state->InputAt(0));
-  int locals = OpParameter<int>(state->InputAt(1));
-  int stack = OpParameter<int>(state->InputAt(2));
+
+  int parameters = state->InputAt(0)->InputCount();
+  int locals = state->InputAt(1)->InputCount();
+  int stack = state->InputAt(2)->InputCount();
 
   FrameStateDescriptor* outer_state = NULL;
   Node* outer_node = state->InputAt(4);
@@ -998,8 +1047,8 @@
     outer_state = GetFrameStateDescriptor(outer_node);
   }
 
-  return new (instruction_zone())
-      FrameStateDescriptor(state_info, parameters, locals, stack, outer_state);
+  return new (instruction_zone()) FrameStateDescriptor(
+      instruction_zone(), state_info, parameters, locals, stack, outer_state);
 }
 
 
@@ -1034,23 +1083,36 @@
   DCHECK_EQ(IrOpcode::kStateValues, locals->op()->opcode());
   DCHECK_EQ(IrOpcode::kStateValues, stack->op()->opcode());
 
-  DCHECK_EQ(descriptor->parameters_count(), parameters->InputCount());
-  DCHECK_EQ(descriptor->locals_count(), locals->InputCount());
-  DCHECK_EQ(descriptor->stack_count(), stack->InputCount());
+  DCHECK_EQ(static_cast<int>(descriptor->parameters_count()),
+            parameters->InputCount());
+  DCHECK_EQ(static_cast<int>(descriptor->locals_count()), locals->InputCount());
+  DCHECK_EQ(static_cast<int>(descriptor->stack_count()), stack->InputCount());
+
+  ZoneVector<MachineType> types(instruction_zone());
+  types.reserve(descriptor->GetSize());
 
   OperandGenerator g(this);
+  size_t value_index = 0;
   for (int i = 0; i < static_cast<int>(descriptor->parameters_count()); i++) {
-    inputs->push_back(UseOrImmediate(&g, parameters->InputAt(i)));
+    Node* input_node = parameters->InputAt(i);
+    inputs->push_back(UseOrImmediate(&g, input_node));
+    descriptor->SetType(value_index++, GetMachineType(input_node));
   }
   if (descriptor->HasContext()) {
     inputs->push_back(UseOrImmediate(&g, context));
+    descriptor->SetType(value_index++, kMachAnyTagged);
   }
   for (int i = 0; i < static_cast<int>(descriptor->locals_count()); i++) {
-    inputs->push_back(UseOrImmediate(&g, locals->InputAt(i)));
+    Node* input_node = locals->InputAt(i);
+    inputs->push_back(UseOrImmediate(&g, input_node));
+    descriptor->SetType(value_index++, GetMachineType(input_node));
   }
   for (int i = 0; i < static_cast<int>(descriptor->stack_count()); i++) {
-    inputs->push_back(UseOrImmediate(&g, stack->InputAt(i)));
+    Node* input_node = stack->InputAt(i);
+    inputs->push_back(UseOrImmediate(&g, input_node));
+    descriptor->SetType(value_index++, GetMachineType(input_node));
   }
+  DCHECK(value_index == descriptor->GetSize());
 }
 
 
@@ -1062,38 +1124,21 @@
 #undef DECLARE_UNIMPLEMENTED_SELECTOR
 
 
-void InstructionSelector::VisitInt32AddWithOverflow(Node* node,
-                                                    FlagsContinuation* cont) {
+void InstructionSelector::VisitCall(Node* node) { UNIMPLEMENTED(); }
+
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+                                      BasicBlock* fbranch) {
   UNIMPLEMENTED();
 }
 
 
-void InstructionSelector::VisitInt32SubWithOverflow(Node* node,
-                                                    FlagsContinuation* cont) {
-  UNIMPLEMENTED();
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  return MachineOperatorBuilder::Flag::kNoFlags;
 }
 
-
-void InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) {
-  UNIMPLEMENTED();
-}
-
-
-void InstructionSelector::VisitWord32Compare(Node* node,
-                                             FlagsContinuation* cont) {
-  UNIMPLEMENTED();
-}
-
-
-void InstructionSelector::VisitFloat64Compare(Node* node,
-                                              FlagsContinuation* cont) {
-  UNIMPLEMENTED();
-}
-
-
-void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
-                                    BasicBlock* deoptimization) {}
-
 #endif  // !V8_TURBOFAN_BACKEND
 
 }  // namespace compiler
diff --git a/src/compiler/instruction-selector.h b/src/compiler/instruction-selector.h
index a86e156..5e3c52f 100644
--- a/src/compiler/instruction-selector.h
+++ b/src/compiler/instruction-selector.h
@@ -19,13 +19,20 @@
 // Forward declarations.
 struct CallBuffer;  // TODO(bmeurer): Remove this.
 class FlagsContinuation;
+class Linkage;
+
+typedef IntVector NodeToVregMap;
 
 class InstructionSelector FINAL {
  public:
+  static const int kNodeUnmapped = -1;
+
   // Forward declarations.
   class Features;
 
-  InstructionSelector(InstructionSequence* sequence,
+  // TODO(dcarney): pass in vreg mapping instead of graph.
+  InstructionSelector(Zone* local_zone, Graph* graph, Linkage* linkage,
+                      InstructionSequence* sequence, Schedule* schedule,
                       SourcePositionTable* source_positions,
                       Features features = SupportedFeatures());
 
@@ -52,6 +59,16 @@
                     InstructionOperand* a, InstructionOperand* b,
                     InstructionOperand* c, InstructionOperand* d,
                     size_t temp_count = 0, InstructionOperand* *temps = NULL);
+  Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
+                    InstructionOperand* a, InstructionOperand* b,
+                    InstructionOperand* c, InstructionOperand* d,
+                    InstructionOperand* e, size_t temp_count = 0,
+                    InstructionOperand* *temps = NULL);
+  Instruction* Emit(InstructionCode opcode, InstructionOperand* output,
+                    InstructionOperand* a, InstructionOperand* b,
+                    InstructionOperand* c, InstructionOperand* d,
+                    InstructionOperand* e, InstructionOperand* f,
+                    size_t temp_count = 0, InstructionOperand* *temps = NULL);
   Instruction* Emit(InstructionCode opcode, size_t output_count,
                     InstructionOperand** outputs, size_t input_count,
                     InstructionOperand** inputs, size_t temp_count = 0,
@@ -84,17 +101,13 @@
     return Features(CpuFeatures::SupportedFeatures());
   }
 
- private:
-  friend class OperandGenerator;
+  // TODO(sigurds) This should take a CpuFeatures argument.
+  static MachineOperatorBuilder::Flags SupportedMachineOperatorFlags();
 
   // ===========================================================================
   // ============ Architecture-independent graph covering methods. =============
   // ===========================================================================
 
-  // Checks if {block} will appear directly after {current_block_} when
-  // assembling code, in which case, a fall-through can be used.
-  bool IsNextInAssemblyOrder(const BasicBlock* block) const;
-
   // Used in pattern matching during code generation.
   // Check if {node} can be covered while generating code for the current
   // instruction. A node can be covered if the {user} of the node has the only
@@ -105,13 +118,24 @@
   // generated for it.
   bool IsDefined(Node* node) const;
 
-  // Inform the instruction selection that {node} was just defined.
-  void MarkAsDefined(Node* node);
-
   // Checks if {node} has any uses, and therefore code has to be generated for
   // it.
   bool IsUsed(Node* node) const;
 
+  // Checks if {node} is currently live.
+  bool IsLive(Node* node) const { return !IsDefined(node) && IsUsed(node); }
+
+  int GetVirtualRegister(const Node* node);
+  // Gets the current mapping if it exists, kNodeUnmapped otherwise.
+  int GetMappedVirtualRegister(const Node* node) const;
+  const NodeToVregMap& GetNodeMapForTesting() const { return node_map_; }
+
+ private:
+  friend class OperandGenerator;
+
+  // Inform the instruction selection that {node} was just defined.
+  void MarkAsDefined(Node* node);
+
   // Inform the instruction selection that {node} has at least one use and we
   // will need to generate code for it.
   void MarkAsUsed(Node* node);
@@ -132,6 +156,10 @@
   // by {node}.
   void MarkAsRepresentation(MachineType rep, Node* node);
 
+  // Inform the register allocation of the representation of the unallocated
+  // operand {op}.
+  void MarkAsRepresentation(MachineType rep, InstructionOperand* op);
+
   // Initialize the call buffer with the InstructionOperands, nodes, etc,
   // corresponding
   // to the inputs and outputs of the call.
@@ -142,8 +170,11 @@
                             bool call_address_immediate);
 
   FrameStateDescriptor* GetFrameStateDescriptor(Node* node);
+  void FillTypeVectorFromStateValues(ZoneVector<MachineType>* parameters,
+                                     Node* state_values);
   void AddFrameStateInputs(Node* state, InstructionOperandVector* inputs,
                            FrameStateDescriptor* descriptor);
+  MachineType GetMachineType(Node* node);
 
   // ===========================================================================
   // ============= Architecture-specific graph covering methods. ===============
@@ -163,22 +194,12 @@
   MACHINE_OP_LIST(DECLARE_GENERATOR)
 #undef DECLARE_GENERATOR
 
-  void VisitInt32AddWithOverflow(Node* node, FlagsContinuation* cont);
-  void VisitInt32SubWithOverflow(Node* node, FlagsContinuation* cont);
-
-  void VisitWord32Test(Node* node, FlagsContinuation* cont);
-  void VisitWord64Test(Node* node, FlagsContinuation* cont);
-  void VisitWord32Compare(Node* node, FlagsContinuation* cont);
-  void VisitWord64Compare(Node* node, FlagsContinuation* cont);
-  void VisitFloat64Compare(Node* node, FlagsContinuation* cont);
-
   void VisitFinish(Node* node);
   void VisitParameter(Node* node);
   void VisitPhi(Node* node);
   void VisitProjection(Node* node);
   void VisitConstant(Node* node);
-  void VisitCall(Node* call, BasicBlock* continuation,
-                 BasicBlock* deoptimization);
+  void VisitCall(Node* call);
   void VisitGoto(BasicBlock* target);
   void VisitBranch(Node* input, BasicBlock* tbranch, BasicBlock* fbranch);
   void VisitReturn(Node* value);
@@ -187,19 +208,21 @@
 
   // ===========================================================================
 
-  Graph* graph() const { return sequence()->graph(); }
-  Linkage* linkage() const { return sequence()->linkage(); }
-  Schedule* schedule() const { return sequence()->schedule(); }
+  Schedule* schedule() const { return schedule_; }
+  Linkage* linkage() const { return linkage_; }
   InstructionSequence* sequence() const { return sequence_; }
   Zone* instruction_zone() const { return sequence()->zone(); }
-  Zone* zone() { return &zone_; }
+  Zone* zone() const { return zone_; }
 
   // ===========================================================================
 
-  Zone zone_;
-  InstructionSequence* sequence_;
-  SourcePositionTable* source_positions_;
+  Zone* const zone_;
+  Linkage* const linkage_;
+  InstructionSequence* const sequence_;
+  SourcePositionTable* const source_positions_;
   Features features_;
+  Schedule* const schedule_;
+  NodeToVregMap node_map_;
   BasicBlock* current_block_;
   ZoneDeque<Instruction*> instructions_;
   BoolVector defined_;
diff --git a/src/compiler/instruction.cc b/src/compiler/instruction.cc
index 9ab81b6..f83cdeb 100644
--- a/src/compiler/instruction.cc
+++ b/src/compiler/instruction.cc
@@ -2,18 +2,19 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/compiler/instruction.h"
-
 #include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/instruction.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-OStream& operator<<(OStream& os, const InstructionOperand& op) {
+std::ostream& operator<<(std::ostream& os,
+                         const PrintableInstructionOperand& printable) {
+  const InstructionOperand& op = *printable.op_;
+  const RegisterConfiguration* conf = printable.register_configuration_;
   switch (op.kind()) {
-    case InstructionOperand::INVALID:
-      return os << "(0)";
     case InstructionOperand::UNALLOCATED: {
       const UnallocatedOperand* unalloc = UnallocatedOperand::cast(&op);
       os << "v" << unalloc->virtual_register();
@@ -24,10 +25,10 @@
         case UnallocatedOperand::NONE:
           return os;
         case UnallocatedOperand::FIXED_REGISTER:
-          return os << "(=" << Register::AllocationIndexToString(
+          return os << "(=" << conf->general_register_name(
                                    unalloc->fixed_register_index()) << ")";
         case UnallocatedOperand::FIXED_DOUBLE_REGISTER:
-          return os << "(=" << DoubleRegister::AllocationIndexToString(
+          return os << "(=" << conf->double_register_name(
                                    unalloc->fixed_register_index()) << ")";
         case UnallocatedOperand::MUST_HAVE_REGISTER:
           return os << "(R)";
@@ -46,11 +47,9 @@
     case InstructionOperand::DOUBLE_STACK_SLOT:
       return os << "[double_stack:" << op.index() << "]";
     case InstructionOperand::REGISTER:
-      return os << "[" << Register::AllocationIndexToString(op.index())
-                << "|R]";
+      return os << "[" << conf->general_register_name(op.index()) << "|R]";
     case InstructionOperand::DOUBLE_REGISTER:
-      return os << "[" << DoubleRegister::AllocationIndexToString(op.index())
-                << "|R]";
+      return os << "[" << conf->double_register_name(op.index()) << "|R]";
   }
   UNREACHABLE();
   return os;
@@ -95,9 +94,17 @@
 }
 
 
-OStream& operator<<(OStream& os, const MoveOperands& mo) {
-  os << *mo.destination();
-  if (!mo.source()->Equals(mo.destination())) os << " = " << *mo.source();
+std::ostream& operator<<(std::ostream& os,
+                         const PrintableMoveOperands& printable) {
+  const MoveOperands& mo = *printable.move_operands_;
+  PrintableInstructionOperand printable_op = {printable.register_configuration_,
+                                              mo.destination()};
+
+  os << printable_op;
+  if (!mo.source()->Equals(mo.destination())) {
+    printable_op.op_ = mo.source();
+    os << " = " << printable_op;
+  }
   return os << ";";
 }
 
@@ -110,14 +117,27 @@
 }
 
 
-OStream& operator<<(OStream& os, const ParallelMove& pm) {
+bool GapInstruction::IsRedundant() const {
+  for (int i = GapInstruction::FIRST_INNER_POSITION;
+       i <= GapInstruction::LAST_INNER_POSITION; i++) {
+    if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant())
+      return false;
+  }
+  return true;
+}
+
+
+std::ostream& operator<<(std::ostream& os,
+                         const PrintableParallelMove& printable) {
+  const ParallelMove& pm = *printable.parallel_move_;
   bool first = true;
   for (ZoneList<MoveOperands>::iterator move = pm.move_operands()->begin();
        move != pm.move_operands()->end(); ++move) {
     if (move->IsEliminated()) continue;
     if (!first) os << " ";
     first = false;
-    os << *move;
+    PrintableMoveOperands pmo = {printable.register_configuration_, move};
+    os << pmo;
   }
   return os;
 }
@@ -152,7 +172,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const PointerMap& pm) {
+std::ostream& operator<<(std::ostream& os, const PointerMap& pm) {
   os << "{";
   for (ZoneList<InstructionOperand*>::iterator op =
            pm.pointer_operands_.begin();
@@ -164,7 +184,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const ArchOpcode& ao) {
+std::ostream& operator<<(std::ostream& os, const ArchOpcode& ao) {
   switch (ao) {
 #define CASE(Name) \
   case k##Name:    \
@@ -177,7 +197,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const AddressingMode& am) {
+std::ostream& operator<<(std::ostream& os, const AddressingMode& am) {
   switch (am) {
     case kMode_None:
       return os;
@@ -192,7 +212,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const FlagsMode& fm) {
+std::ostream& operator<<(std::ostream& os, const FlagsMode& fm) {
   switch (fm) {
     case kFlags_none:
       return os;
@@ -206,7 +226,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const FlagsCondition& fc) {
+std::ostream& operator<<(std::ostream& os, const FlagsCondition& fc) {
   switch (fc) {
     case kEqual:
       return os << "equal";
@@ -250,11 +270,16 @@
 }
 
 
-OStream& operator<<(OStream& os, const Instruction& instr) {
+std::ostream& operator<<(std::ostream& os,
+                         const PrintableInstruction& printable) {
+  const Instruction& instr = *printable.instr_;
+  PrintableInstructionOperand printable_op = {printable.register_configuration_,
+                                              NULL};
   if (instr.OutputCount() > 1) os << "(";
   for (size_t i = 0; i < instr.OutputCount(); i++) {
     if (i > 0) os << ", ";
-    os << *instr.OutputAt(i);
+    printable_op.op_ = instr.OutputAt(i);
+    os << printable_op;
   }
 
   if (instr.OutputCount() > 1) os << ") = ";
@@ -266,7 +291,11 @@
     for (int i = GapInstruction::FIRST_INNER_POSITION;
          i <= GapInstruction::LAST_INNER_POSITION; i++) {
       os << "(";
-      if (gap->parallel_moves_[i] != NULL) os << *gap->parallel_moves_[i];
+      if (gap->parallel_moves_[i] != NULL) {
+        PrintableParallelMove ppm = {printable.register_configuration_,
+                                     gap->parallel_moves_[i]};
+        os << ppm;
+      }
       os << ") ";
     }
   } else if (instr.IsSourcePosition()) {
@@ -287,57 +316,175 @@
   }
   if (instr.InputCount() > 0) {
     for (size_t i = 0; i < instr.InputCount(); i++) {
-      os << " " << *instr.InputAt(i);
+      printable_op.op_ = instr.InputAt(i);
+      os << " " << printable_op;
     }
   }
-  return os << "\n";
+  return os;
 }
 
 
-OStream& operator<<(OStream& os, const Constant& constant) {
+std::ostream& operator<<(std::ostream& os, const Constant& constant) {
   switch (constant.type()) {
     case Constant::kInt32:
       return os << constant.ToInt32();
     case Constant::kInt64:
       return os << constant.ToInt64() << "l";
+    case Constant::kFloat32:
+      return os << constant.ToFloat32() << "f";
     case Constant::kFloat64:
       return os << constant.ToFloat64();
     case Constant::kExternalReference:
-      return os << constant.ToExternalReference().address();
+      return os << static_cast<const void*>(
+                       constant.ToExternalReference().address());
     case Constant::kHeapObject:
       return os << Brief(*constant.ToHeapObject());
+    case Constant::kRpoNumber:
+      return os << "RPO" << constant.ToRpoNumber().ToInt();
   }
   UNREACHABLE();
   return os;
 }
 
 
-Label* InstructionSequence::GetLabel(BasicBlock* block) {
-  return GetBlockStart(block)->label();
+InstructionBlock::InstructionBlock(Zone* zone, BasicBlock::Id id,
+                                   BasicBlock::RpoNumber rpo_number,
+                                   BasicBlock::RpoNumber loop_header,
+                                   BasicBlock::RpoNumber loop_end,
+                                   bool deferred)
+    : successors_(zone),
+      predecessors_(zone),
+      phis_(zone),
+      id_(id),
+      ao_number_(rpo_number),
+      rpo_number_(rpo_number),
+      loop_header_(loop_header),
+      loop_end_(loop_end),
+      code_start_(-1),
+      code_end_(-1),
+      deferred_(deferred) {}
+
+
+size_t InstructionBlock::PredecessorIndexOf(
+    BasicBlock::RpoNumber rpo_number) const {
+  size_t j = 0;
+  for (InstructionBlock::Predecessors::const_iterator i = predecessors_.begin();
+       i != predecessors_.end(); ++i, ++j) {
+    if (*i == rpo_number) break;
+  }
+  return j;
 }
 
 
-BlockStartInstruction* InstructionSequence::GetBlockStart(BasicBlock* block) {
-  return BlockStartInstruction::cast(InstructionAt(block->code_start_));
+static BasicBlock::RpoNumber GetRpo(BasicBlock* block) {
+  if (block == NULL) return BasicBlock::RpoNumber::Invalid();
+  return block->GetRpoNumber();
 }
 
 
-void InstructionSequence::StartBlock(BasicBlock* block) {
-  block->code_start_ = static_cast<int>(instructions_.size());
-  BlockStartInstruction* block_start =
-      BlockStartInstruction::New(zone(), block);
-  AddInstruction(block_start, block);
+static BasicBlock::RpoNumber GetLoopEndRpo(const BasicBlock* block) {
+  if (!block->IsLoopHeader()) return BasicBlock::RpoNumber::Invalid();
+  return block->loop_end()->GetRpoNumber();
 }
 
 
-void InstructionSequence::EndBlock(BasicBlock* block) {
+static InstructionBlock* InstructionBlockFor(Zone* zone,
+                                             const BasicBlock* block) {
+  InstructionBlock* instr_block = new (zone) InstructionBlock(
+      zone, block->id(), block->GetRpoNumber(), GetRpo(block->loop_header()),
+      GetLoopEndRpo(block), block->deferred());
+  // Map successors and precessors
+  instr_block->successors().reserve(block->SuccessorCount());
+  for (auto it = block->successors_begin(); it != block->successors_end();
+       ++it) {
+    instr_block->successors().push_back((*it)->GetRpoNumber());
+  }
+  instr_block->predecessors().reserve(block->PredecessorCount());
+  for (auto it = block->predecessors_begin(); it != block->predecessors_end();
+       ++it) {
+    instr_block->predecessors().push_back((*it)->GetRpoNumber());
+  }
+  return instr_block;
+}
+
+
+InstructionBlocks* InstructionSequence::InstructionBlocksFor(
+    Zone* zone, const Schedule* schedule) {
+  InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1);
+  new (blocks) InstructionBlocks(
+      static_cast<int>(schedule->rpo_order()->size()), NULL, zone);
+  size_t rpo_number = 0;
+  for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin();
+       it != schedule->rpo_order()->end(); ++it, ++rpo_number) {
+    DCHECK_EQ(NULL, (*blocks)[rpo_number]);
+    DCHECK((*it)->GetRpoNumber().ToSize() == rpo_number);
+    (*blocks)[rpo_number] = InstructionBlockFor(zone, *it);
+  }
+  ComputeAssemblyOrder(blocks);
+  return blocks;
+}
+
+
+void InstructionSequence::ComputeAssemblyOrder(InstructionBlocks* blocks) {
+  int ao = 0;
+  for (auto const block : *blocks) {
+    if (!block->IsDeferred()) {
+      block->set_ao_number(BasicBlock::RpoNumber::FromInt(ao++));
+    }
+  }
+  for (auto const block : *blocks) {
+    if (block->IsDeferred()) {
+      block->set_ao_number(BasicBlock::RpoNumber::FromInt(ao++));
+    }
+  }
+}
+
+
+InstructionSequence::InstructionSequence(Zone* instruction_zone,
+                                         InstructionBlocks* instruction_blocks)
+    : zone_(instruction_zone),
+      instruction_blocks_(instruction_blocks),
+      block_starts_(zone()),
+      constants_(ConstantMap::key_compare(),
+                 ConstantMap::allocator_type(zone())),
+      immediates_(zone()),
+      instructions_(zone()),
+      next_virtual_register_(0),
+      pointer_maps_(zone()),
+      doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())),
+      references_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())),
+      deoptimization_entries_(zone()) {
+  block_starts_.reserve(instruction_blocks_->size());
+}
+
+
+BlockStartInstruction* InstructionSequence::GetBlockStart(
+    BasicBlock::RpoNumber rpo) const {
+  const InstructionBlock* block = InstructionBlockAt(rpo);
+  return BlockStartInstruction::cast(InstructionAt(block->code_start()));
+}
+
+
+void InstructionSequence::StartBlock(BasicBlock::RpoNumber rpo) {
+  DCHECK(block_starts_.size() == rpo.ToSize());
+  InstructionBlock* block = InstructionBlockAt(rpo);
+  int code_start = static_cast<int>(instructions_.size());
+  block->set_code_start(code_start);
+  block_starts_.push_back(code_start);
+  BlockStartInstruction* block_start = BlockStartInstruction::New(zone());
+  AddInstruction(block_start);
+}
+
+
+void InstructionSequence::EndBlock(BasicBlock::RpoNumber rpo) {
   int end = static_cast<int>(instructions_.size());
-  DCHECK(block->code_start_ >= 0 && block->code_start_ < end);
-  block->code_end_ = end;
+  InstructionBlock* block = InstructionBlockAt(rpo);
+  DCHECK(block->code_start() >= 0 && block->code_start() < end);
+  block->set_code_end(end);
 }
 
 
-int InstructionSequence::AddInstruction(Instruction* instr, BasicBlock* block) {
+int InstructionSequence::AddInstruction(Instruction* instr) {
   // TODO(titzer): the order of these gaps is a holdover from Lithium.
   GapInstruction* gap = GapInstruction::New(zone());
   if (instr->IsControl()) instructions_.push_back(gap);
@@ -355,15 +502,17 @@
 }
 
 
-BasicBlock* InstructionSequence::GetBasicBlock(int instruction_index) {
-  // TODO(turbofan): Optimize this.
-  for (;;) {
-    DCHECK_LE(0, instruction_index);
-    Instruction* instruction = InstructionAt(instruction_index--);
-    if (instruction->IsBlockStart()) {
-      return BlockStartInstruction::cast(instruction)->block();
-    }
-  }
+const InstructionBlock* InstructionSequence::GetInstructionBlock(
+    int instruction_index) const {
+  DCHECK(instruction_blocks_->size() == block_starts_.size());
+  auto begin = block_starts_.begin();
+  auto end = std::lower_bound(begin, block_starts_.end(), instruction_index,
+                              std::less_equal<int>());
+  size_t index = std::distance(begin, end) - 1;
+  auto block = instruction_blocks_->at(index);
+  DCHECK(block->code_start() <= instruction_index &&
+         instruction_index < block->code_end());
+  return block;
 }
 
 
@@ -412,7 +561,81 @@
 }
 
 
-OStream& operator<<(OStream& os, const InstructionSequence& code) {
+FrameStateDescriptor::FrameStateDescriptor(
+    Zone* zone, const FrameStateCallInfo& state_info, size_t parameters_count,
+    size_t locals_count, size_t stack_count, FrameStateDescriptor* outer_state)
+    : type_(state_info.type()),
+      bailout_id_(state_info.bailout_id()),
+      frame_state_combine_(state_info.state_combine()),
+      parameters_count_(parameters_count),
+      locals_count_(locals_count),
+      stack_count_(stack_count),
+      types_(zone),
+      outer_state_(outer_state),
+      jsfunction_(state_info.jsfunction()) {
+  types_.resize(GetSize(), kMachNone);
+}
+
+size_t FrameStateDescriptor::GetSize(OutputFrameStateCombine combine) const {
+  size_t size = parameters_count() + locals_count() + stack_count() +
+                (HasContext() ? 1 : 0);
+  switch (combine.kind()) {
+    case OutputFrameStateCombine::kPushOutput:
+      size += combine.GetPushCount();
+      break;
+    case OutputFrameStateCombine::kPokeAt:
+      break;
+  }
+  return size;
+}
+
+
+size_t FrameStateDescriptor::GetTotalSize() const {
+  size_t total_size = 0;
+  for (const FrameStateDescriptor* iter = this; iter != NULL;
+       iter = iter->outer_state_) {
+    total_size += iter->GetSize();
+  }
+  return total_size;
+}
+
+
+size_t FrameStateDescriptor::GetFrameCount() const {
+  size_t count = 0;
+  for (const FrameStateDescriptor* iter = this; iter != NULL;
+       iter = iter->outer_state_) {
+    ++count;
+  }
+  return count;
+}
+
+
+size_t FrameStateDescriptor::GetJSFrameCount() const {
+  size_t count = 0;
+  for (const FrameStateDescriptor* iter = this; iter != NULL;
+       iter = iter->outer_state_) {
+    if (iter->type_ == JS_FRAME) {
+      ++count;
+    }
+  }
+  return count;
+}
+
+
+MachineType FrameStateDescriptor::GetType(size_t index) const {
+  return types_[index];
+}
+
+
+void FrameStateDescriptor::SetType(size_t index, MachineType type) {
+  DCHECK(index < GetSize());
+  types_[index] = type;
+}
+
+
+std::ostream& operator<<(std::ostream& os,
+                         const PrintableInstructionSequence& printable) {
+  const InstructionSequence& code = *printable.sequence_;
   for (size_t i = 0; i < code.immediates_.size(); ++i) {
     Constant constant = code.immediates_[i];
     os << "IMM#" << i << ": " << constant << "\n";
@@ -422,57 +645,53 @@
        it != code.constants_.end(); ++i, ++it) {
     os << "CST#" << i << ": v" << it->first << " = " << it->second << "\n";
   }
-  for (int i = 0; i < code.BasicBlockCount(); i++) {
-    BasicBlock* block = code.BlockAt(i);
+  for (int i = 0; i < code.InstructionBlockCount(); i++) {
+    BasicBlock::RpoNumber rpo = BasicBlock::RpoNumber::FromInt(i);
+    const InstructionBlock* block = code.InstructionBlockAt(rpo);
+    CHECK(block->rpo_number() == rpo);
 
-    int bid = block->id();
-    os << "RPO#" << block->rpo_number_ << ": B" << bid;
-    CHECK(block->rpo_number_ == i);
+    os << "RPO#" << block->rpo_number();
+    os << ": AO#" << block->ao_number();
+    os << ": B" << block->id();
+    if (block->IsDeferred()) os << " (deferred)";
     if (block->IsLoopHeader()) {
-      os << " loop blocks: [" << block->rpo_number_ << ", " << block->loop_end_
-         << ")";
+      os << " loop blocks: [" << block->rpo_number() << ", "
+         << block->loop_end() << ")";
     }
-    os << "  instructions: [" << block->code_start_ << ", " << block->code_end_
-       << ")\n  predecessors:";
+    os << "  instructions: [" << block->code_start() << ", "
+       << block->code_end() << ")\n  predecessors:";
 
-    BasicBlock::Predecessors predecessors = block->predecessors();
-    for (BasicBlock::Predecessors::iterator iter = predecessors.begin();
-         iter != predecessors.end(); ++iter) {
-      os << " B" << (*iter)->id();
+    for (auto pred : block->predecessors()) {
+      const InstructionBlock* pred_block = code.InstructionBlockAt(pred);
+      os << " B" << pred_block->id();
     }
     os << "\n";
 
-    for (BasicBlock::const_iterator j = block->begin(); j != block->end();
-         ++j) {
-      Node* phi = *j;
-      if (phi->opcode() != IrOpcode::kPhi) continue;
-      os << "     phi: v" << phi->id() << " =";
-      Node::Inputs inputs = phi->inputs();
-      for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
-           ++iter) {
-        os << " v" << (*iter)->id();
+    for (auto phi : block->phis()) {
+      PrintableInstructionOperand printable_op = {
+          printable.register_configuration_, phi->output()};
+      os << "     phi: " << printable_op << " =";
+      for (auto input : phi->inputs()) {
+        printable_op.op_ = input;
+        os << " " << printable_op;
       }
       os << "\n";
     }
 
     ScopedVector<char> buf(32);
+    PrintableInstruction printable_instr;
+    printable_instr.register_configuration_ = printable.register_configuration_;
     for (int j = block->first_instruction_index();
          j <= block->last_instruction_index(); j++) {
       // TODO(svenpanne) Add some basic formatting to our streams.
       SNPrintF(buf, "%5d", j);
-      os << "   " << buf.start() << ": " << *code.InstructionAt(j);
+      printable_instr.instr_ = code.InstructionAt(j);
+      os << "   " << buf.start() << ": " << printable_instr << "\n";
     }
 
-    os << "  " << block->control_;
-
-    if (block->control_input_ != NULL) {
-      os << " v" << block->control_input_->id();
-    }
-
-    BasicBlock::Successors successors = block->successors();
-    for (BasicBlock::Successors::iterator iter = successors.begin();
-         iter != successors.end(); ++iter) {
-      os << " B" << (*iter)->id();
+    for (auto succ : block->successors()) {
+      const InstructionBlock* succ_block = code.InstructionBlockAt(succ);
+      os << " B" << succ_block->id();
     }
     os << "\n";
   }
diff --git a/src/compiler/instruction.h b/src/compiler/instruction.h
index 6d00784..daa83f2 100644
--- a/src/compiler/instruction.h
+++ b/src/compiler/instruction.h
@@ -6,48 +6,39 @@
 #define V8_COMPILER_INSTRUCTION_H_
 
 #include <deque>
+#include <iosfwd>
 #include <map>
 #include <set>
 
 #include "src/compiler/common-operator.h"
 #include "src/compiler/frame.h"
-#include "src/compiler/graph.h"
 #include "src/compiler/instruction-codes.h"
 #include "src/compiler/opcodes.h"
+#include "src/compiler/register-configuration.h"
 #include "src/compiler/schedule.h"
-// TODO(titzer): don't include the macro-assembler?
-#include "src/macro-assembler.h"
+#include "src/compiler/source-position.h"
 #include "src/zone-allocator.h"
 
 namespace v8 {
 namespace internal {
-
-// Forward declarations.
-class OStream;
-
 namespace compiler {
 
-// Forward declarations.
-class Linkage;
-
 // A couple of reserved opcodes are used for internal use.
 const InstructionCode kGapInstruction = -1;
 const InstructionCode kBlockStartInstruction = -2;
 const InstructionCode kSourcePositionInstruction = -3;
 
-
-#define INSTRUCTION_OPERAND_LIST(V)              \
-  V(Constant, CONSTANT, 128)                     \
-  V(Immediate, IMMEDIATE, 128)                   \
-  V(StackSlot, STACK_SLOT, 128)                  \
-  V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128)     \
-  V(Register, REGISTER, Register::kNumRegisters) \
-  V(DoubleRegister, DOUBLE_REGISTER, DoubleRegister::kMaxNumRegisters)
+#define INSTRUCTION_OPERAND_LIST(V)                                  \
+  V(Constant, CONSTANT, 0)                                           \
+  V(Immediate, IMMEDIATE, 0)                                         \
+  V(StackSlot, STACK_SLOT, 128)                                      \
+  V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128)                         \
+  V(Register, REGISTER, RegisterConfiguration::kMaxGeneralRegisters) \
+  V(DoubleRegister, DOUBLE_REGISTER, RegisterConfiguration::kMaxDoubleRegisters)
 
 class InstructionOperand : public ZoneObject {
  public:
   enum Kind {
-    INVALID,
     UNALLOCATED,
     CONSTANT,
     IMMEDIATE,
@@ -57,7 +48,6 @@
     DOUBLE_REGISTER
   };
 
-  InstructionOperand() : value_(KindField::encode(INVALID)) {}
   InstructionOperand(Kind kind, int index) { ConvertTo(kind, index); }
 
   Kind kind() const { return KindField::decode(value_); }
@@ -66,16 +56,15 @@
   bool Is##name() const { return kind() == type; }
   INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE)
   INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0)
-  INSTRUCTION_OPERAND_PREDICATE(Ignored, INVALID, 0)
 #undef INSTRUCTION_OPERAND_PREDICATE
-  bool Equals(InstructionOperand* other) const {
+  bool Equals(const InstructionOperand* other) const {
     return value_ == other->value_;
   }
 
   void ConvertTo(Kind kind, int index) {
     if (kind == REGISTER || kind == DOUBLE_REGISTER) DCHECK(index >= 0);
     value_ = KindField::encode(kind);
-    value_ |= index << KindField::kSize;
+    value_ |= bit_cast<unsigned>(index << KindField::kSize);
     DCHECK(this->index() == index);
   }
 
@@ -84,14 +73,20 @@
   static void TearDownCaches();
 
  protected:
-  typedef BitField<Kind, 0, 3> KindField;
+  typedef BitField64<Kind, 0, 3> KindField;
 
-  unsigned value_;
+  uint64_t value_;
 };
 
 typedef ZoneVector<InstructionOperand*> InstructionOperandVector;
 
-OStream& operator<<(OStream& os, const InstructionOperand& op);
+struct PrintableInstructionOperand {
+  const RegisterConfiguration* register_configuration_;
+  const InstructionOperand* op_;
+};
+
+std::ostream& operator<<(std::ostream& os,
+                         const PrintableInstructionOperand& op);
 
 class UnallocatedOperand : public InstructionOperand {
  public:
@@ -122,6 +117,7 @@
 
   explicit UnallocatedOperand(ExtendedPolicy policy)
       : InstructionOperand(UNALLOCATED, 0) {
+    value_ |= VirtualRegisterField::encode(kInvalidVirtualRegister);
     value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
     value_ |= ExtendedPolicyField::encode(policy);
     value_ |= LifetimeField::encode(USED_AT_END);
@@ -130,14 +126,16 @@
   UnallocatedOperand(BasicPolicy policy, int index)
       : InstructionOperand(UNALLOCATED, 0) {
     DCHECK(policy == FIXED_SLOT);
+    value_ |= VirtualRegisterField::encode(kInvalidVirtualRegister);
     value_ |= BasicPolicyField::encode(policy);
-    value_ |= index << FixedSlotIndexField::kShift;
+    value_ |= static_cast<int64_t>(index) << FixedSlotIndexField::kShift;
     DCHECK(this->fixed_slot_index() == index);
   }
 
   UnallocatedOperand(ExtendedPolicy policy, int index)
       : InstructionOperand(UNALLOCATED, 0) {
     DCHECK(policy == FIXED_REGISTER || policy == FIXED_DOUBLE_REGISTER);
+    value_ |= VirtualRegisterField::encode(kInvalidVirtualRegister);
     value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
     value_ |= ExtendedPolicyField::encode(policy);
     value_ |= LifetimeField::encode(USED_AT_END);
@@ -146,6 +144,7 @@
 
   UnallocatedOperand(ExtendedPolicy policy, Lifetime lifetime)
       : InstructionOperand(UNALLOCATED, 0) {
+    value_ |= VirtualRegisterField::encode(kInvalidVirtualRegister);
     value_ |= BasicPolicyField::encode(EXTENDED_POLICY);
     value_ |= ExtendedPolicyField::encode(policy);
     value_ |= LifetimeField::encode(lifetime);
@@ -183,24 +182,25 @@
   //     +------------------------------------------+    P ... Policy
   //
   // The slot index is a signed value which requires us to decode it manually
-  // instead of using the BitField utility class.
+  // instead of using the BitField64 utility class.
 
   // The superclass has a KindField.
   STATIC_ASSERT(KindField::kSize == 3);
 
   // BitFields for all unallocated operands.
-  class BasicPolicyField : public BitField<BasicPolicy, 3, 1> {};
-  class VirtualRegisterField : public BitField<unsigned, 4, 18> {};
+  class BasicPolicyField : public BitField64<BasicPolicy, 3, 1> {};
+  class VirtualRegisterField : public BitField64<unsigned, 4, 30> {};
 
   // BitFields specific to BasicPolicy::FIXED_SLOT.
-  class FixedSlotIndexField : public BitField<int, 22, 10> {};
+  class FixedSlotIndexField : public BitField64<int, 34, 30> {};
 
   // BitFields specific to BasicPolicy::EXTENDED_POLICY.
-  class ExtendedPolicyField : public BitField<ExtendedPolicy, 22, 3> {};
-  class LifetimeField : public BitField<Lifetime, 25, 1> {};
-  class FixedRegisterField : public BitField<int, 26, 6> {};
+  class ExtendedPolicyField : public BitField64<ExtendedPolicy, 34, 3> {};
+  class LifetimeField : public BitField64<Lifetime, 37, 1> {};
+  class FixedRegisterField : public BitField64<int, 38, 6> {};
 
-  static const int kMaxVirtualRegisters = VirtualRegisterField::kMax + 1;
+  static const int kInvalidVirtualRegister = VirtualRegisterField::kMax;
+  static const int kMaxVirtualRegisters = VirtualRegisterField::kMax;
   static const int kFixedSlotIndexWidth = FixedSlotIndexField::kSize;
   static const int kMaxFixedSlotIndex = (1 << (kFixedSlotIndexWidth - 1)) - 1;
   static const int kMinFixedSlotIndex = -(1 << (kFixedSlotIndexWidth - 1));
@@ -244,7 +244,8 @@
   // [fixed_slot_index]: Only for FIXED_SLOT.
   int fixed_slot_index() const {
     DCHECK(HasFixedSlotPolicy());
-    return static_cast<int>(value_) >> FixedSlotIndexField::kShift;
+    return static_cast<int>(bit_cast<int64_t>(value_) >>
+                            FixedSlotIndexField::kShift);
   }
 
   // [fixed_register_index]: Only for FIXED_REGISTER or FIXED_DOUBLE_REGISTER.
@@ -260,7 +261,7 @@
   }
 
   // [lifetime]: Only for non-FIXED_SLOT.
-  bool IsUsedAtStart() {
+  bool IsUsedAtStart() const {
     DCHECK(basic_policy() == EXTENDED_POLICY);
     return LifetimeField::decode(value_) == USED_AT_START;
   }
@@ -288,16 +289,12 @@
   }
 
   // A move is redundant if it's been eliminated, if its source and
-  // destination are the same, or if its destination is unneeded or constant.
+  // destination are the same, or if its destination is  constant.
   bool IsRedundant() const {
-    return IsEliminated() || source_->Equals(destination_) || IsIgnored() ||
+    return IsEliminated() || source_->Equals(destination_) ||
            (destination_ != NULL && destination_->IsConstant());
   }
 
-  bool IsIgnored() const {
-    return destination_ != NULL && destination_->IsIgnored();
-  }
-
   // We clear both operands to indicate move that's been eliminated.
   void Eliminate() { source_ = destination_ = NULL; }
   bool IsEliminated() const {
@@ -310,7 +307,15 @@
   InstructionOperand* destination_;
 };
 
-OStream& operator<<(OStream& os, const MoveOperands& mo);
+
+struct PrintableMoveOperands {
+  const RegisterConfiguration* register_configuration_;
+  const MoveOperands* move_operands_;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo);
+
 
 template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands>
 class SubKindOperand FINAL : public InstructionOperand {
@@ -326,13 +331,18 @@
     return reinterpret_cast<SubKindOperand*>(op);
   }
 
+  static const SubKindOperand* cast(const InstructionOperand* op) {
+    DCHECK(op->kind() == kOperandKind);
+    return reinterpret_cast<const SubKindOperand*>(op);
+  }
+
   static void SetUpCache();
   static void TearDownCache();
 
  private:
   static SubKindOperand* cache;
 
-  SubKindOperand() : InstructionOperand() {}
+  SubKindOperand() : InstructionOperand(kOperandKind, 0) {}  // For the caches.
   explicit SubKindOperand(int index)
       : InstructionOperand(kOperandKind, index) {}
 };
@@ -363,7 +373,15 @@
   ZoneList<MoveOperands> move_operands_;
 };
 
-OStream& operator<<(OStream& os, const ParallelMove& pm);
+
+struct PrintableParallelMove {
+  const RegisterConfiguration* register_configuration_;
+  const ParallelMove* parallel_move_;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const PrintableParallelMove& pm);
+
 
 class PointerMap FINAL : public ZoneObject {
  public:
@@ -391,14 +409,14 @@
   void RecordUntagged(InstructionOperand* op, Zone* zone);
 
  private:
-  friend OStream& operator<<(OStream& os, const PointerMap& pm);
+  friend std::ostream& operator<<(std::ostream& os, const PointerMap& pm);
 
   ZoneList<InstructionOperand*> pointer_operands_;
   ZoneList<InstructionOperand*> untagged_operands_;
   int instruction_position_;
 };
 
-OStream& operator<<(OStream& os, const PointerMap& pm);
+std::ostream& operator<<(std::ostream& os, const PointerMap& pm);
 
 // TODO(titzer): s/PointerMap/ReferenceMap/
 class Instruction : public ZoneObject {
@@ -417,6 +435,10 @@
     DCHECK(i < InputCount());
     return operands_[OutputCount() + i];
   }
+  void SetInputAt(size_t i, InstructionOperand* operand) {
+    DCHECK(i < InputCount());
+    operands_[OutputCount() + i] = operand;
+  }
 
   size_t TempCount() const { return TempCountField::decode(bit_field_); }
   InstructionOperand* TempAt(size_t i) const {
@@ -496,6 +518,17 @@
 
   void operator delete(void* pointer, void* location) { UNREACHABLE(); }
 
+  void OverwriteWithNop() {
+    opcode_ = ArchOpcodeField::encode(kArchNop);
+    bit_field_ = 0;
+    pointer_map_ = NULL;
+  }
+
+  bool IsNop() const {
+    return arch_opcode() == kArchNop && InputCount() == 0 &&
+           OutputCount() == 0 && TempCount() == 0;
+  }
+
  protected:
   explicit Instruction(InstructionCode opcode)
       : opcode_(opcode),
@@ -538,7 +571,13 @@
   InstructionOperand* operands_[1];
 };
 
-OStream& operator<<(OStream& os, const Instruction& instr);
+
+struct PrintableInstruction {
+  const RegisterConfiguration* register_configuration_;
+  const Instruction* instr_;
+};
+std::ostream& operator<<(std::ostream& os, const PrintableInstruction& instr);
+
 
 // Represents moves inserted before an instruction due to register allocation.
 // TODO(titzer): squash GapInstruction back into Instruction, since essentially
@@ -565,6 +604,14 @@
     return parallel_moves_[pos];
   }
 
+  const ParallelMove* GetParallelMove(InnerPosition pos) const {
+    return parallel_moves_[pos];
+  }
+
+  bool IsRedundant() const;
+
+  ParallelMove** parallel_moves() { return parallel_moves_; }
+
   static GapInstruction* New(Zone* zone) {
     void* buffer = zone->New(sizeof(GapInstruction));
     return new (buffer) GapInstruction(kGapInstruction);
@@ -589,22 +636,19 @@
   }
 
  private:
-  friend OStream& operator<<(OStream& os, const Instruction& instr);
+  friend std::ostream& operator<<(std::ostream& os,
+                                  const PrintableInstruction& instr);
   ParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
 };
 
 
 // This special kind of gap move instruction represents the beginning of a
 // block of code.
-// TODO(titzer): move code_start and code_end from BasicBlock to here.
 class BlockStartInstruction FINAL : public GapInstruction {
  public:
-  BasicBlock* block() const { return block_; }
-  Label* label() { return &label_; }
-
-  static BlockStartInstruction* New(Zone* zone, BasicBlock* block) {
+  static BlockStartInstruction* New(Zone* zone) {
     void* buffer = zone->New(sizeof(BlockStartInstruction));
-    return new (buffer) BlockStartInstruction(block);
+    return new (buffer) BlockStartInstruction();
   }
 
   static BlockStartInstruction* cast(Instruction* instr) {
@@ -612,12 +656,13 @@
     return static_cast<BlockStartInstruction*>(instr);
   }
 
- private:
-  explicit BlockStartInstruction(BasicBlock* block)
-      : GapInstruction(kBlockStartInstruction), block_(block) {}
+  static const BlockStartInstruction* cast(const Instruction* instr) {
+    DCHECK(instr->IsBlockStart());
+    return static_cast<const BlockStartInstruction*>(instr);
+  }
 
-  BasicBlock* block_;
-  Label label_;
+ private:
+  BlockStartInstruction() : GapInstruction(kBlockStartInstruction) {}
 };
 
 
@@ -654,21 +699,34 @@
 
 class Constant FINAL {
  public:
-  enum Type { kInt32, kInt64, kFloat64, kExternalReference, kHeapObject };
+  enum Type {
+    kInt32,
+    kInt64,
+    kFloat32,
+    kFloat64,
+    kExternalReference,
+    kHeapObject,
+    kRpoNumber
+  };
 
   explicit Constant(int32_t v) : type_(kInt32), value_(v) {}
   explicit Constant(int64_t v) : type_(kInt64), value_(v) {}
+  explicit Constant(float v) : type_(kFloat32), value_(bit_cast<int32_t>(v)) {}
   explicit Constant(double v) : type_(kFloat64), value_(bit_cast<int64_t>(v)) {}
   explicit Constant(ExternalReference ref)
       : type_(kExternalReference), value_(bit_cast<intptr_t>(ref)) {}
   explicit Constant(Handle<HeapObject> obj)
       : type_(kHeapObject), value_(bit_cast<intptr_t>(obj)) {}
+  explicit Constant(BasicBlock::RpoNumber rpo)
+      : type_(kRpoNumber), value_(rpo.ToInt()) {}
 
   Type type() const { return type_; }
 
   int32_t ToInt32() const {
-    DCHECK_EQ(kInt32, type());
-    return static_cast<int32_t>(value_);
+    DCHECK(type() == kInt32 || type() == kInt64);
+    const int32_t value = static_cast<int32_t>(value_);
+    DCHECK_EQ(value_, static_cast<int64_t>(value));
+    return value;
   }
 
   int64_t ToInt64() const {
@@ -677,6 +735,11 @@
     return value_;
   }
 
+  float ToFloat32() const {
+    DCHECK_EQ(kFloat32, type());
+    return bit_cast<float>(static_cast<int32_t>(value_));
+  }
+
   double ToFloat64() const {
     if (type() == kInt32) return ToInt32();
     DCHECK_EQ(kFloat64, type());
@@ -688,6 +751,11 @@
     return bit_cast<ExternalReference>(static_cast<intptr_t>(value_));
   }
 
+  BasicBlock::RpoNumber ToRpoNumber() const {
+    DCHECK_EQ(kRpoNumber, type());
+    return BasicBlock::RpoNumber::FromInt(static_cast<int>(value_));
+  }
+
   Handle<HeapObject> ToHeapObject() const {
     DCHECK_EQ(kHeapObject, type());
     return bit_cast<Handle<HeapObject> >(static_cast<intptr_t>(value_));
@@ -701,18 +769,10 @@
 
 class FrameStateDescriptor : public ZoneObject {
  public:
-  FrameStateDescriptor(const FrameStateCallInfo& state_info,
+  FrameStateDescriptor(Zone* zone, const FrameStateCallInfo& state_info,
                        size_t parameters_count, size_t locals_count,
                        size_t stack_count,
-                       FrameStateDescriptor* outer_state = NULL)
-      : type_(state_info.type()),
-        bailout_id_(state_info.bailout_id()),
-        frame_state_combine_(state_info.state_combine()),
-        parameters_count_(parameters_count),
-        locals_count_(locals_count),
-        stack_count_(stack_count),
-        outer_state_(outer_state),
-        jsfunction_(state_info.jsfunction()) {}
+                       FrameStateDescriptor* outer_state = NULL);
 
   FrameStateType type() const { return type_; }
   BailoutId bailout_id() const { return bailout_id_; }
@@ -722,55 +782,17 @@
   size_t stack_count() const { return stack_count_; }
   FrameStateDescriptor* outer_state() const { return outer_state_; }
   MaybeHandle<JSFunction> jsfunction() const { return jsfunction_; }
-
-  size_t size() const {
-    return parameters_count_ + locals_count_ + stack_count_ +
-           (HasContext() ? 1 : 0);
-  }
-
-  size_t GetTotalSize() const {
-    size_t total_size = 0;
-    for (const FrameStateDescriptor* iter = this; iter != NULL;
-         iter = iter->outer_state_) {
-      total_size += iter->size();
-    }
-    return total_size;
-  }
-
-  size_t GetHeight(OutputFrameStateCombine override) const {
-    size_t height = size() - parameters_count();
-    switch (override) {
-      case kPushOutput:
-        ++height;
-        break;
-      case kIgnoreOutput:
-        break;
-    }
-    return height;
-  }
-
-  size_t GetFrameCount() const {
-    size_t count = 0;
-    for (const FrameStateDescriptor* iter = this; iter != NULL;
-         iter = iter->outer_state_) {
-      ++count;
-    }
-    return count;
-  }
-
-  size_t GetJSFrameCount() const {
-    size_t count = 0;
-    for (const FrameStateDescriptor* iter = this; iter != NULL;
-         iter = iter->outer_state_) {
-      if (iter->type_ == JS_FRAME) {
-        ++count;
-      }
-    }
-    return count;
-  }
-
   bool HasContext() const { return type_ == JS_FRAME; }
 
+  size_t GetSize(OutputFrameStateCombine combine =
+                     OutputFrameStateCombine::Ignore()) const;
+  size_t GetTotalSize() const;
+  size_t GetFrameCount() const;
+  size_t GetJSFrameCount() const;
+
+  MachineType GetType(size_t index) const;
+  void SetType(size_t index, MachineType type);
+
  private:
   FrameStateType type_;
   BailoutId bailout_id_;
@@ -778,11 +800,128 @@
   size_t parameters_count_;
   size_t locals_count_;
   size_t stack_count_;
+  ZoneVector<MachineType> types_;
   FrameStateDescriptor* outer_state_;
   MaybeHandle<JSFunction> jsfunction_;
 };
 
-OStream& operator<<(OStream& os, const Constant& constant);
+std::ostream& operator<<(std::ostream& os, const Constant& constant);
+
+
+class PhiInstruction FINAL : public ZoneObject {
+ public:
+  typedef ZoneVector<InstructionOperand*> Inputs;
+
+  PhiInstruction(Zone* zone, int virtual_register, size_t reserved_input_count)
+      : virtual_register_(virtual_register),
+        operands_(zone),
+        output_(nullptr),
+        inputs_(zone) {
+    UnallocatedOperand* output =
+        new (zone) UnallocatedOperand(UnallocatedOperand::NONE);
+    output->set_virtual_register(virtual_register);
+    output_ = output;
+    inputs_.reserve(reserved_input_count);
+    operands_.reserve(reserved_input_count);
+  }
+
+  int virtual_register() const { return virtual_register_; }
+  const IntVector& operands() const { return operands_; }
+
+  void Extend(Zone* zone, int virtual_register) {
+    UnallocatedOperand* input =
+        new (zone) UnallocatedOperand(UnallocatedOperand::ANY);
+    input->set_virtual_register(virtual_register);
+    operands_.push_back(virtual_register);
+    inputs_.push_back(input);
+  }
+
+  InstructionOperand* output() const { return output_; }
+  const Inputs& inputs() const { return inputs_; }
+  Inputs& inputs() { return inputs_; }
+
+ private:
+  // TODO(dcarney): some of these fields are only for verification, move them to
+  // verifier.
+  const int virtual_register_;
+  IntVector operands_;
+  InstructionOperand* output_;
+  Inputs inputs_;
+};
+
+
+// Analogue of BasicBlock for Instructions instead of Nodes.
+class InstructionBlock FINAL : public ZoneObject {
+ public:
+  InstructionBlock(Zone* zone, BasicBlock::Id id,
+                   BasicBlock::RpoNumber rpo_number,
+                   BasicBlock::RpoNumber loop_header,
+                   BasicBlock::RpoNumber loop_end, bool deferred);
+
+  // Instruction indexes (used by the register allocator).
+  int first_instruction_index() const {
+    DCHECK(code_start_ >= 0);
+    DCHECK(code_end_ > 0);
+    DCHECK(code_end_ >= code_start_);
+    return code_start_;
+  }
+  int last_instruction_index() const {
+    DCHECK(code_start_ >= 0);
+    DCHECK(code_end_ > 0);
+    DCHECK(code_end_ >= code_start_);
+    return code_end_ - 1;
+  }
+
+  int32_t code_start() const { return code_start_; }
+  void set_code_start(int32_t start) { code_start_ = start; }
+
+  int32_t code_end() const { return code_end_; }
+  void set_code_end(int32_t end) { code_end_ = end; }
+
+  bool IsDeferred() const { return deferred_; }
+
+  BasicBlock::Id id() const { return id_; }
+  BasicBlock::RpoNumber ao_number() const { return ao_number_; }
+  BasicBlock::RpoNumber rpo_number() const { return rpo_number_; }
+  BasicBlock::RpoNumber loop_header() const { return loop_header_; }
+  BasicBlock::RpoNumber loop_end() const {
+    DCHECK(IsLoopHeader());
+    return loop_end_;
+  }
+  inline bool IsLoopHeader() const { return loop_end_.IsValid(); }
+
+  typedef ZoneVector<BasicBlock::RpoNumber> Predecessors;
+  Predecessors& predecessors() { return predecessors_; }
+  const Predecessors& predecessors() const { return predecessors_; }
+  size_t PredecessorCount() const { return predecessors_.size(); }
+  size_t PredecessorIndexOf(BasicBlock::RpoNumber rpo_number) const;
+
+  typedef ZoneVector<BasicBlock::RpoNumber> Successors;
+  Successors& successors() { return successors_; }
+  const Successors& successors() const { return successors_; }
+  size_t SuccessorCount() const { return successors_.size(); }
+
+  typedef ZoneVector<PhiInstruction*> PhiInstructions;
+  const PhiInstructions& phis() const { return phis_; }
+  void AddPhi(PhiInstruction* phi) { phis_.push_back(phi); }
+
+  void set_ao_number(BasicBlock::RpoNumber ao_number) {
+    ao_number_ = ao_number;
+  }
+
+ private:
+  Successors successors_;
+  Predecessors predecessors_;
+  PhiInstructions phis_;
+  const BasicBlock::Id id_;
+  BasicBlock::RpoNumber ao_number_;  // Assembly order number.
+  const BasicBlock::RpoNumber rpo_number_;
+  const BasicBlock::RpoNumber loop_header_;
+  const BasicBlock::RpoNumber loop_end_;
+  int32_t code_start_;   // start index of arch-specific code.
+  int32_t code_end_;     // end index of arch-specific code.
+  const bool deferred_;  // Block contains deferred code.
+};
 
 typedef ZoneDeque<Constant> ConstantDeque;
 typedef std::map<int, Constant, std::less<int>,
@@ -791,49 +930,49 @@
 typedef ZoneDeque<Instruction*> InstructionDeque;
 typedef ZoneDeque<PointerMap*> PointerMapDeque;
 typedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector;
+typedef ZoneVector<InstructionBlock*> InstructionBlocks;
+
+struct PrintableInstructionSequence;
+
 
 // Represents architecture-specific generated code before, during, and after
 // register allocation.
 // TODO(titzer): s/IsDouble/IsFloat64/
-class InstructionSequence FINAL {
+class InstructionSequence FINAL : public ZoneObject {
  public:
-  InstructionSequence(Linkage* linkage, Graph* graph, Schedule* schedule)
-      : graph_(graph),
-        linkage_(linkage),
-        schedule_(schedule),
-        constants_(ConstantMap::key_compare(),
-                   ConstantMap::allocator_type(zone())),
-        immediates_(zone()),
-        instructions_(zone()),
-        next_virtual_register_(graph->NodeCount()),
-        pointer_maps_(zone()),
-        doubles_(std::less<int>(), VirtualRegisterSet::allocator_type(zone())),
-        references_(std::less<int>(),
-                    VirtualRegisterSet::allocator_type(zone())),
-        deoptimization_entries_(zone()) {}
+  static InstructionBlocks* InstructionBlocksFor(Zone* zone,
+                                                 const Schedule* schedule);
+  // Puts the deferred blocks last.
+  static void ComputeAssemblyOrder(InstructionBlocks* blocks);
+
+  InstructionSequence(Zone* zone, InstructionBlocks* instruction_blocks);
 
   int NextVirtualRegister() { return next_virtual_register_++; }
   int VirtualRegisterCount() const { return next_virtual_register_; }
 
-  int ValueCount() const { return graph_->NodeCount(); }
-
-  int BasicBlockCount() const {
-    return static_cast<int>(schedule_->rpo_order()->size());
+  const InstructionBlocks& instruction_blocks() const {
+    return *instruction_blocks_;
   }
 
-  BasicBlock* BlockAt(int rpo_number) const {
-    return (*schedule_->rpo_order())[rpo_number];
+  int InstructionBlockCount() const {
+    return static_cast<int>(instruction_blocks_->size());
   }
 
-  BasicBlock* GetContainingLoop(BasicBlock* block) {
-    return block->loop_header_;
+  InstructionBlock* InstructionBlockAt(BasicBlock::RpoNumber rpo_number) {
+    return instruction_blocks_->at(rpo_number.ToSize());
   }
 
-  int GetLoopEnd(BasicBlock* block) const { return block->loop_end_; }
+  int LastLoopInstructionIndex(const InstructionBlock* block) {
+    return instruction_blocks_->at(block->loop_end().ToSize() - 1)
+        ->last_instruction_index();
+  }
 
-  BasicBlock* GetBasicBlock(int instruction_index);
+  const InstructionBlock* InstructionBlockAt(
+      BasicBlock::RpoNumber rpo_number) const {
+    return instruction_blocks_->at(rpo_number.ToSize());
+  }
 
-  int GetVirtualRegister(Node* node) const { return node->id(); }
+  const InstructionBlock* GetInstructionBlock(int instruction_index) const;
 
   bool IsReference(int virtual_register) const;
   bool IsDouble(int virtual_register) const;
@@ -843,12 +982,12 @@
 
   void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to);
 
-  Label* GetLabel(BasicBlock* block);
-  BlockStartInstruction* GetBlockStart(BasicBlock* block);
+  BlockStartInstruction* GetBlockStart(BasicBlock::RpoNumber rpo) const;
 
   typedef InstructionDeque::const_iterator const_iterator;
   const_iterator begin() const { return instructions_.begin(); }
   const_iterator end() const { return instructions_.end(); }
+  const InstructionDeque& instructions() const { return instructions_; }
 
   GapInstruction* GapAt(int index) const {
     return GapInstruction::cast(InstructionAt(index));
@@ -860,22 +999,22 @@
     return instructions_[index];
   }
 
-  Frame* frame() { return &frame_; }
-  Graph* graph() const { return graph_; }
   Isolate* isolate() const { return zone()->isolate(); }
-  Linkage* linkage() const { return linkage_; }
-  Schedule* schedule() const { return schedule_; }
   const PointerMapDeque* pointer_maps() const { return &pointer_maps_; }
-  Zone* zone() const { return graph_->zone(); }
+  Zone* zone() const { return zone_; }
 
-  // Used by the code generator while adding instructions.
-  int AddInstruction(Instruction* instr, BasicBlock* block);
-  void StartBlock(BasicBlock* block);
-  void EndBlock(BasicBlock* block);
+  // Used by the instruction selector while adding instructions.
+  int AddInstruction(Instruction* instr);
+  void StartBlock(BasicBlock::RpoNumber rpo);
+  void EndBlock(BasicBlock::RpoNumber rpo);
 
-  void AddConstant(int virtual_register, Constant constant) {
+  int AddConstant(int virtual_register, Constant constant) {
+    // TODO(titzer): allow RPO numbers as constants?
+    DCHECK(constant.type() != Constant::kRpoNumber);
+    DCHECK(virtual_register >= 0 && virtual_register < next_virtual_register_);
     DCHECK(constants_.find(virtual_register) == constants_.end());
     constants_.insert(std::make_pair(virtual_register, constant));
+    return virtual_register;
   }
   Constant GetConstant(int virtual_register) const {
     ConstantMap::const_iterator it = constants_.find(virtual_register);
@@ -884,8 +1023,8 @@
     return it->second;
   }
 
-  typedef ConstantDeque Immediates;
-  const Immediates& immediates() const { return immediates_; }
+  typedef ZoneVector<Constant> Immediates;
+  Immediates& immediates() { return immediates_; }
 
   int AddImmediate(Constant constant) {
     int index = static_cast<int>(immediates_.size());
@@ -912,26 +1051,43 @@
   FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id);
   int GetFrameStateDescriptorCount();
 
+  BasicBlock::RpoNumber InputRpo(Instruction* instr, size_t index) {
+    InstructionOperand* operand = instr->InputAt(index);
+    Constant constant = operand->IsImmediate() ? GetImmediate(operand->index())
+                                               : GetConstant(operand->index());
+    return constant.ToRpoNumber();
+  }
+
  private:
-  friend OStream& operator<<(OStream& os, const InstructionSequence& code);
+  friend std::ostream& operator<<(std::ostream& os,
+                                  const PrintableInstructionSequence& code);
 
   typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet;
 
-  Graph* graph_;
-  Linkage* linkage_;
-  Schedule* schedule_;
+  Zone* const zone_;
+  InstructionBlocks* const instruction_blocks_;
+  IntVector block_starts_;
   ConstantMap constants_;
-  ConstantDeque immediates_;
+  Immediates immediates_;
   InstructionDeque instructions_;
   int next_virtual_register_;
   PointerMapDeque pointer_maps_;
   VirtualRegisterSet doubles_;
   VirtualRegisterSet references_;
-  Frame frame_;
   DeoptimizationVector deoptimization_entries_;
+
+  DISALLOW_COPY_AND_ASSIGN(InstructionSequence);
 };
 
-OStream& operator<<(OStream& os, const InstructionSequence& code);
+
+struct PrintableInstructionSequence {
+  const RegisterConfiguration* register_configuration_;
+  const InstructionSequence* sequence_;
+};
+
+
+std::ostream& operator<<(std::ostream& os,
+                         const PrintableInstructionSequence& code);
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/js-builtin-reducer-unittest.cc b/src/compiler/js-builtin-reducer-unittest.cc
deleted file mode 100644
index 51561d0..0000000
--- a/src/compiler/js-builtin-reducer-unittest.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/graph-unittest.h"
-#include "src/compiler/js-builtin-reducer.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/compiler/typer.h"
-#include "testing/gmock-support.h"
-
-using testing::Capture;
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class JSBuiltinReducerTest : public GraphTest {
- public:
-  JSBuiltinReducerTest() : javascript_(zone()) {}
-
- protected:
-  Reduction Reduce(Node* node) {
-    Typer typer(zone());
-    MachineOperatorBuilder machine;
-    JSGraph jsgraph(graph(), common(), javascript(), &typer, &machine);
-    JSBuiltinReducer reducer(&jsgraph);
-    return reducer.Reduce(node);
-  }
-
-  Node* Parameter(Type* t, int32_t index = 0) {
-    Node* n = graph()->NewNode(common()->Parameter(index), graph()->start());
-    NodeProperties::SetBounds(n, Bounds(Type::None(), t));
-    return n;
-  }
-
-  Node* UndefinedConstant() {
-    return HeapConstant(
-        Unique<HeapObject>::CreateImmovable(factory()->undefined_value()));
-  }
-
-  JSOperatorBuilder* javascript() { return &javascript_; }
-
- private:
-  JSOperatorBuilder javascript_;
-};
-
-
-namespace {
-
-// TODO(mstarzinger): Find a common place and unify with test-js-typed-lowering.
-Type* const kNumberTypes[] = {
-    Type::UnsignedSmall(),   Type::OtherSignedSmall(), Type::OtherUnsigned31(),
-    Type::OtherUnsigned32(), Type::OtherSigned32(),    Type::SignedSmall(),
-    Type::Signed32(),        Type::Unsigned32(),       Type::Integral32(),
-    Type::MinusZero(),       Type::NaN(),              Type::OtherNumber(),
-    Type::OrderedNumber(),   Type::Number()};
-
-}  // namespace
-
-
-// -----------------------------------------------------------------------------
-// Math.sqrt
-
-
-TEST_F(JSBuiltinReducerTest, MathSqrt) {
-  Handle<JSFunction> f(isolate()->context()->math_sqrt_fun());
-
-  TRACED_FOREACH(Type*, t0, kNumberTypes) {
-    Node* p0 = Parameter(t0, 0);
-    Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
-    Node* call = graph()->NewNode(javascript()->Call(3, NO_CALL_FUNCTION_FLAGS),
-                                  fun, UndefinedConstant(), p0);
-    Reduction r = Reduce(call);
-
-    ASSERT_TRUE(r.Changed());
-    EXPECT_THAT(r.replacement(), IsFloat64Sqrt(p0));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// Math.max
-
-
-TEST_F(JSBuiltinReducerTest, MathMax0) {
-  Handle<JSFunction> f(isolate()->context()->math_max_fun());
-
-  Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
-  Node* call = graph()->NewNode(javascript()->Call(2, NO_CALL_FUNCTION_FLAGS),
-                                fun, UndefinedConstant());
-  Reduction r = Reduce(call);
-
-  ASSERT_TRUE(r.Changed());
-  EXPECT_THAT(r.replacement(), IsNumberConstant(-V8_INFINITY));
-}
-
-
-TEST_F(JSBuiltinReducerTest, MathMax1) {
-  Handle<JSFunction> f(isolate()->context()->math_max_fun());
-
-  TRACED_FOREACH(Type*, t0, kNumberTypes) {
-    Node* p0 = Parameter(t0, 0);
-    Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
-    Node* call = graph()->NewNode(javascript()->Call(3, NO_CALL_FUNCTION_FLAGS),
-                                  fun, UndefinedConstant(), p0);
-    Reduction r = Reduce(call);
-
-    ASSERT_TRUE(r.Changed());
-    EXPECT_THAT(r.replacement(), p0);
-  }
-}
-
-
-TEST_F(JSBuiltinReducerTest, MathMax2) {
-  Handle<JSFunction> f(isolate()->context()->math_max_fun());
-
-  TRACED_FOREACH(Type*, t0, kNumberTypes) {
-    TRACED_FOREACH(Type*, t1, kNumberTypes) {
-      Node* p0 = Parameter(t0, 0);
-      Node* p1 = Parameter(t1, 1);
-      Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
-      Node* call =
-          graph()->NewNode(javascript()->Call(4, NO_CALL_FUNCTION_FLAGS), fun,
-                           UndefinedConstant(), p0, p1);
-      Reduction r = Reduce(call);
-
-      if (t0->Is(Type::Integral32()) && t1->Is(Type::Integral32())) {
-        Capture<Node*> branch;
-        ASSERT_TRUE(r.Changed());
-        EXPECT_THAT(
-            r.replacement(),
-            IsPhi(kMachNone, p1, p0,
-                  IsMerge(IsIfTrue(CaptureEq(&branch)),
-                          IsIfFalse(AllOf(CaptureEq(&branch),
-                                          IsBranch(IsNumberLessThan(p0, p1),
-                                                   graph()->start()))))));
-      } else {
-        ASSERT_FALSE(r.Changed());
-        EXPECT_EQ(IrOpcode::kJSCallFunction, call->opcode());
-      }
-    }
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// Math.imul
-
-
-TEST_F(JSBuiltinReducerTest, MathImul) {
-  Handle<JSFunction> f(isolate()->context()->math_imul_fun());
-
-  TRACED_FOREACH(Type*, t0, kNumberTypes) {
-    TRACED_FOREACH(Type*, t1, kNumberTypes) {
-      Node* p0 = Parameter(t0, 0);
-      Node* p1 = Parameter(t1, 1);
-      Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
-      Node* call =
-          graph()->NewNode(javascript()->Call(4, NO_CALL_FUNCTION_FLAGS), fun,
-                           UndefinedConstant(), p0, p1);
-      Reduction r = Reduce(call);
-
-      if (t0->Is(Type::Integral32()) && t1->Is(Type::Integral32())) {
-        ASSERT_TRUE(r.Changed());
-        EXPECT_THAT(r.replacement(), IsInt32Mul(p0, p1));
-      } else {
-        ASSERT_FALSE(r.Changed());
-        EXPECT_EQ(IrOpcode::kJSCallFunction, call->opcode());
-      }
-    }
-  }
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/js-builtin-reducer.cc b/src/compiler/js-builtin-reducer.cc
index c57ac33..263b0fe 100644
--- a/src/compiler/js-builtin-reducer.cc
+++ b/src/compiler/js-builtin-reducer.cc
@@ -2,8 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/compiler/diamond.h"
 #include "src/compiler/graph-inl.h"
 #include "src/compiler/js-builtin-reducer.h"
+#include "src/compiler/js-graph.h"
 #include "src/compiler/node-matchers.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/types.h"
@@ -80,7 +82,7 @@
   int GetJSCallArity() {
     DCHECK_EQ(IrOpcode::kJSCallFunction, node_->opcode());
     // Skip first (i.e. callee) and second (i.e. receiver) operand.
-    return OperatorProperties::GetValueInputCount(node_->op()) - 2;
+    return node_->op()->ValueInputCount() - 2;
   }
 
   Node* GetJSCallInput(int index) {
@@ -95,6 +97,30 @@
 };
 
 
+JSBuiltinReducer::JSBuiltinReducer(JSGraph* jsgraph)
+    : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {}
+
+
+// ECMA-262, section 15.8.2.1.
+Reduction JSBuiltinReducer::ReduceMathAbs(Node* node) {
+  JSCallReduction r(node);
+  if (r.InputsMatchOne(Type::Unsigned32())) {
+    // Math.abs(a:uint32) -> a
+    return Replace(r.left());
+  }
+  if (r.InputsMatchOne(Type::Number())) {
+    // Math.abs(a:number) -> (a > 0 ? a : 0 - a)
+    Node* const value = r.left();
+    Node* const zero = jsgraph()->ZeroConstant();
+    return Replace(graph()->NewNode(
+        common()->Select(kMachNone),
+        graph()->NewNode(simplified()->NumberLessThan(), zero, value), value,
+        graph()->NewNode(simplified()->NumberSubtract(), zero, value)));
+  }
+  return NoChange();
+}
+
+
 // ECMA-262, section 15.8.2.17.
 Reduction JSBuiltinReducer::ReduceMathSqrt(Node* node) {
   JSCallReduction r(node);
@@ -122,16 +148,11 @@
     // Math.max(a:int32, b:int32, ...)
     Node* value = r.GetJSCallInput(0);
     for (int i = 1; i < r.GetJSCallArity(); i++) {
-      Node* p = r.GetJSCallInput(i);
-      Node* control = graph()->start();
-      Node* tag = graph()->NewNode(simplified()->NumberLessThan(), value, p);
-
-      Node* branch = graph()->NewNode(common()->Branch(), tag, control);
-      Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
-      Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
-      Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
-
-      value = graph()->NewNode(common()->Phi(kMachNone, 2), p, value, merge);
+      Node* const input = r.GetJSCallInput(i);
+      value = graph()->NewNode(
+          common()->Select(kMachNone),
+          graph()->NewNode(simplified()->NumberLessThan(), input, value), input,
+          value);
     }
     return Replace(value);
   }
@@ -151,24 +172,84 @@
 }
 
 
+// ES6 draft 08-24-14, section 20.2.2.17.
+Reduction JSBuiltinReducer::ReduceMathFround(Node* node) {
+  JSCallReduction r(node);
+  if (r.InputsMatchOne(Type::Number())) {
+    // Math.fround(a:number) -> TruncateFloat64ToFloat32(a)
+    Node* value =
+        graph()->NewNode(machine()->TruncateFloat64ToFloat32(), r.left());
+    return Replace(value);
+  }
+  return NoChange();
+}
+
+
+// ES6 draft 10-14-14, section 20.2.2.16.
+Reduction JSBuiltinReducer::ReduceMathFloor(Node* node) {
+  if (!machine()->HasFloat64Floor()) return NoChange();
+  JSCallReduction r(node);
+  if (r.InputsMatchOne(Type::Number())) {
+    // Math.floor(a:number) -> Float64Floor(a)
+    Node* value = graph()->NewNode(machine()->Float64Floor(), r.left());
+    return Replace(value);
+  }
+  return NoChange();
+}
+
+
+// ES6 draft 10-14-14, section 20.2.2.10.
+Reduction JSBuiltinReducer::ReduceMathCeil(Node* node) {
+  if (!machine()->HasFloat64Ceil()) return NoChange();
+  JSCallReduction r(node);
+  if (r.InputsMatchOne(Type::Number())) {
+    // Math.ceil(a:number) -> Float64Ceil(a)
+    Node* value = graph()->NewNode(machine()->Float64Ceil(), r.left());
+    return Replace(value);
+  }
+  return NoChange();
+}
+
+
 Reduction JSBuiltinReducer::Reduce(Node* node) {
   JSCallReduction r(node);
 
   // Dispatch according to the BuiltinFunctionId if present.
   if (!r.HasBuiltinFunctionId()) return NoChange();
   switch (r.GetBuiltinFunctionId()) {
+    case kMathAbs:
+      return ReplaceWithPureReduction(node, ReduceMathAbs(node));
     case kMathSqrt:
       return ReplaceWithPureReduction(node, ReduceMathSqrt(node));
     case kMathMax:
       return ReplaceWithPureReduction(node, ReduceMathMax(node));
     case kMathImul:
       return ReplaceWithPureReduction(node, ReduceMathImul(node));
+    case kMathFround:
+      return ReplaceWithPureReduction(node, ReduceMathFround(node));
+    case kMathFloor:
+      return ReplaceWithPureReduction(node, ReduceMathFloor(node));
+    case kMathCeil:
+      return ReplaceWithPureReduction(node, ReduceMathCeil(node));
     default:
       break;
   }
   return NoChange();
 }
 
+
+Graph* JSBuiltinReducer::graph() const { return jsgraph()->graph(); }
+
+
+CommonOperatorBuilder* JSBuiltinReducer::common() const {
+  return jsgraph()->common();
+}
+
+
+MachineOperatorBuilder* JSBuiltinReducer::machine() const {
+  return jsgraph()->machine();
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/js-builtin-reducer.h b/src/compiler/js-builtin-reducer.h
index 13927f6..ac6f266 100644
--- a/src/compiler/js-builtin-reducer.h
+++ b/src/compiler/js-builtin-reducer.h
@@ -6,33 +6,39 @@
 #define V8_COMPILER_JS_BUILTIN_REDUCER_H_
 
 #include "src/compiler/graph-reducer.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/node.h"
 #include "src/compiler/simplified-operator.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+// Forward declarations.
+class CommonOperatorBuilder;
+class JSGraph;
+class MachineOperatorBuilder;
+
+
 class JSBuiltinReducer FINAL : public Reducer {
  public:
-  explicit JSBuiltinReducer(JSGraph* jsgraph)
-      : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {}
-  virtual ~JSBuiltinReducer() {}
+  explicit JSBuiltinReducer(JSGraph* jsgraph);
+  ~JSBuiltinReducer() FINAL {}
 
-  virtual Reduction Reduce(Node* node) OVERRIDE;
+  Reduction Reduce(Node* node) FINAL;
 
  private:
-  JSGraph* jsgraph() const { return jsgraph_; }
-  Graph* graph() const { return jsgraph_->graph(); }
-  CommonOperatorBuilder* common() const { return jsgraph_->common(); }
-  MachineOperatorBuilder* machine() const { return jsgraph_->machine(); }
-  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
-
+  Reduction ReduceMathAbs(Node* node);
   Reduction ReduceMathSqrt(Node* node);
   Reduction ReduceMathMax(Node* node);
   Reduction ReduceMathImul(Node* node);
+  Reduction ReduceMathFround(Node* node);
+  Reduction ReduceMathFloor(Node* node);
+  Reduction ReduceMathCeil(Node* node);
+
+  JSGraph* jsgraph() const { return jsgraph_; }
+  Graph* graph() const;
+  CommonOperatorBuilder* common() const;
+  MachineOperatorBuilder* machine() const;
+  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
 
   JSGraph* jsgraph_;
   SimplifiedOperatorBuilder simplified_;
diff --git a/src/compiler/js-context-specialization.cc b/src/compiler/js-context-specialization.cc
index cd8932b..a700b47 100644
--- a/src/compiler/js-context-specialization.cc
+++ b/src/compiler/js-context-specialization.cc
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/compiler/common-operator.h"
-#include "src/compiler/generic-node-inl.h"
-#include "src/compiler/graph-inl.h"
 #include "src/compiler/js-context-specialization.h"
+
+#include "src/compiler.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph-inl.h"
 #include "src/compiler/js-operator.h"
-#include "src/compiler/node-aux-data-inl.h"
 #include "src/compiler/node-matchers.h"
 #include "src/compiler/node-properties-inl.h"
 
@@ -15,46 +15,19 @@
 namespace internal {
 namespace compiler {
 
-class ContextSpecializationVisitor : public NullNodeVisitor {
- public:
-  explicit ContextSpecializationVisitor(JSContextSpecializer* spec)
-      : spec_(spec) {}
-
-  GenericGraphVisit::Control Post(Node* node) {
-    switch (node->opcode()) {
-      case IrOpcode::kJSLoadContext: {
-        Reduction r = spec_->ReduceJSLoadContext(node);
-        if (r.Changed() && r.replacement() != node) {
-          NodeProperties::ReplaceWithValue(node, r.replacement());
-          node->RemoveAllInputs();
-        }
-        break;
-      }
-      case IrOpcode::kJSStoreContext: {
-        Reduction r = spec_->ReduceJSStoreContext(node);
-        if (r.Changed() && r.replacement() != node) {
-          NodeProperties::ReplaceWithValue(node, r.replacement());
-          node->RemoveAllInputs();
-        }
-        break;
-      }
-      default:
-        break;
-    }
-    return GenericGraphVisit::CONTINUE;
+Reduction JSContextSpecializer::Reduce(Node* node) {
+  if (node == context_) {
+    Node* constant = jsgraph_->Constant(info_->context());
+    NodeProperties::ReplaceWithValue(node, constant);
+    return Replace(constant);
   }
-
- private:
-  JSContextSpecializer* spec_;
-};
-
-
-void JSContextSpecializer::SpecializeToContext() {
-  NodeProperties::ReplaceWithValue(context_,
-                                   jsgraph_->Constant(info_->context()));
-
-  ContextSpecializationVisitor visitor(this);
-  jsgraph_->graph()->VisitNodeInputsFromEnd(&visitor);
+  if (node->opcode() == IrOpcode::kJSLoadContext) {
+    return ReduceJSLoadContext(node);
+  }
+  if (node->opcode() == IrOpcode::kJSStoreContext) {
+    return ReduceJSStoreContext(node);
+  }
+  return NoChange();
 }
 
 
@@ -64,14 +37,14 @@
   HeapObjectMatcher<Context> m(NodeProperties::GetValueInput(node, 0));
   // If the context is not constant, no reduction can occur.
   if (!m.HasValue()) {
-    return Reducer::NoChange();
+    return NoChange();
   }
 
-  ContextAccess access = OpParameter<ContextAccess>(node);
+  const ContextAccess& access = ContextAccessOf(node->op());
 
   // Find the right parent context.
   Context* context = *m.Value().handle();
-  for (int i = access.depth(); i > 0; --i) {
+  for (size_t i = access.depth(); i > 0; --i) {
     context = context->previous();
   }
 
@@ -79,30 +52,32 @@
   if (!access.immutable()) {
     // The access does not have to look up a parent, nothing to fold.
     if (access.depth() == 0) {
-      return Reducer::NoChange();
+      return NoChange();
     }
     const Operator* op = jsgraph_->javascript()->LoadContext(
         0, access.index(), access.immutable());
     node->set_op(op);
     Handle<Object> context_handle = Handle<Object>(context, info_->isolate());
     node->ReplaceInput(0, jsgraph_->Constant(context_handle));
-    return Reducer::Changed(node);
+    return Changed(node);
   }
-  Handle<Object> value =
-      Handle<Object>(context->get(access.index()), info_->isolate());
+  Handle<Object> value = Handle<Object>(
+      context->get(static_cast<int>(access.index())), info_->isolate());
 
   // Even though the context slot is immutable, the context might have escaped
   // before the function to which it belongs has initialized the slot.
   // We must be conservative and check if the value in the slot is currently the
   // hole or undefined. If it is neither of these, then it must be initialized.
   if (value->IsUndefined() || value->IsTheHole()) {
-    return Reducer::NoChange();
+    return NoChange();
   }
 
   // Success. The context load can be replaced with the constant.
   // TODO(titzer): record the specialization for sharing code across multiple
   // contexts that have the same value in the corresponding context slot.
-  return Reducer::Replace(jsgraph_->Constant(value));
+  Node* constant = jsgraph_->Constant(value);
+  NodeProperties::ReplaceWithValue(node, constant);
+  return Replace(constant);
 }
 
 
@@ -112,19 +87,19 @@
   HeapObjectMatcher<Context> m(NodeProperties::GetValueInput(node, 0));
   // If the context is not constant, no reduction can occur.
   if (!m.HasValue()) {
-    return Reducer::NoChange();
+    return NoChange();
   }
 
-  ContextAccess access = OpParameter<ContextAccess>(node);
+  const ContextAccess& access = ContextAccessOf(node->op());
 
   // The access does not have to look up a parent, nothing to fold.
   if (access.depth() == 0) {
-    return Reducer::NoChange();
+    return NoChange();
   }
 
   // Find the right parent context.
   Context* context = *m.Value().handle();
-  for (int i = access.depth(); i > 0; --i) {
+  for (size_t i = access.depth(); i > 0; --i) {
     context = context->previous();
   }
 
@@ -133,7 +108,7 @@
   Handle<Object> new_context_handle = Handle<Object>(context, info_->isolate());
   node->ReplaceInput(0, jsgraph_->Constant(new_context_handle));
 
-  return Reducer::Changed(node);
+  return Changed(node);
 }
 
 }  // namespace compiler
diff --git a/src/compiler/js-context-specialization.h b/src/compiler/js-context-specialization.h
index b8b50ed..298d3a3 100644
--- a/src/compiler/js-context-specialization.h
+++ b/src/compiler/js-context-specialization.h
@@ -16,12 +16,14 @@
 
 // Specializes a given JSGraph to a given context, potentially constant folding
 // some {LoadContext} nodes or strength reducing some {StoreContext} nodes.
-class JSContextSpecializer {
+class JSContextSpecializer : public Reducer {
  public:
   JSContextSpecializer(CompilationInfo* info, JSGraph* jsgraph, Node* context)
       : info_(info), jsgraph_(jsgraph), context_(context) {}
 
-  void SpecializeToContext();
+  Reduction Reduce(Node* node) OVERRIDE;
+
+  // Visible for unit testing.
   Reduction ReduceJSLoadContext(Node* node);
   Reduction ReduceJSStoreContext(Node* node);
 
diff --git a/src/compiler/js-generic-lowering.cc b/src/compiler/js-generic-lowering.cc
index 300604e..4886442 100644
--- a/src/compiler/js-generic-lowering.cc
+++ b/src/compiler/js-generic-lowering.cc
@@ -9,6 +9,7 @@
 #include "src/compiler/js-generic-lowering.h"
 #include "src/compiler/machine-operator.h"
 #include "src/compiler/node-aux-data-inl.h"
+#include "src/compiler/node-matchers.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/unique.h"
 
@@ -19,7 +20,7 @@
 JSGenericLowering::JSGenericLowering(CompilationInfo* info, JSGraph* jsgraph)
     : info_(info),
       jsgraph_(jsgraph),
-      linkage_(new (jsgraph->zone()) Linkage(info)) {}
+      linkage_(new (jsgraph->zone()) Linkage(jsgraph->zone(), info)) {}
 
 
 void JSGenericLowering::PatchOperator(Node* node, const Operator* op) {
@@ -32,40 +33,25 @@
 }
 
 
-Node* JSGenericLowering::SmiConstant(int32_t immediate) {
-  return jsgraph()->SmiConstant(immediate);
-}
-
-
-Node* JSGenericLowering::Int32Constant(int immediate) {
-  return jsgraph()->Int32Constant(immediate);
-}
-
-
-Node* JSGenericLowering::CodeConstant(Handle<Code> code) {
-  return jsgraph()->HeapConstant(code);
-}
-
-
-Node* JSGenericLowering::FunctionConstant(Handle<JSFunction> function) {
-  return jsgraph()->HeapConstant(function);
-}
-
-
-Node* JSGenericLowering::ExternalConstant(ExternalReference ref) {
-  return jsgraph()->ExternalConstant(ref);
-}
-
-
 Reduction JSGenericLowering::Reduce(Node* node) {
   switch (node->opcode()) {
-#define DECLARE_CASE(x) \
-  case IrOpcode::k##x:  \
-    Lower##x(node);     \
-    break;
-    DECLARE_CASE(Branch)
+#define DECLARE_CASE(x)  \
+    case IrOpcode::k##x: \
+      Lower##x(node);    \
+      break;
     JS_OP_LIST(DECLARE_CASE)
 #undef DECLARE_CASE
+    case IrOpcode::kBranch:
+      // TODO(mstarzinger): If typing is enabled then simplified lowering will
+      // have inserted the correct ChangeBoolToBit, otherwise we need to perform
+      // poor-man's representation inference here and insert manual change.
+      if (!info()->is_typing_enabled()) {
+        Node* test = graph()->NewNode(machine()->WordEqual(), node->InputAt(0),
+                                      jsgraph()->TrueConstant());
+        node->ReplaceInput(0, test);
+        break;
+      }
+      // Fall-through.
     default:
       // Nothing to see.
       return NoChange();
@@ -93,18 +79,18 @@
 #undef REPLACE_BINARY_OP_IC_CALL
 
 
-#define REPLACE_COMPARE_IC_CALL(op, token, pure)  \
+#define REPLACE_COMPARE_IC_CALL(op, token)        \
   void JSGenericLowering::Lower##op(Node* node) { \
-    ReplaceWithCompareIC(node, token, pure);      \
+    ReplaceWithCompareIC(node, token);            \
   }
-REPLACE_COMPARE_IC_CALL(JSEqual, Token::EQ, false)
-REPLACE_COMPARE_IC_CALL(JSNotEqual, Token::NE, false)
-REPLACE_COMPARE_IC_CALL(JSStrictEqual, Token::EQ_STRICT, true)
-REPLACE_COMPARE_IC_CALL(JSStrictNotEqual, Token::NE_STRICT, true)
-REPLACE_COMPARE_IC_CALL(JSLessThan, Token::LT, false)
-REPLACE_COMPARE_IC_CALL(JSGreaterThan, Token::GT, false)
-REPLACE_COMPARE_IC_CALL(JSLessThanOrEqual, Token::LTE, false)
-REPLACE_COMPARE_IC_CALL(JSGreaterThanOrEqual, Token::GTE, false)
+REPLACE_COMPARE_IC_CALL(JSEqual, Token::EQ)
+REPLACE_COMPARE_IC_CALL(JSNotEqual, Token::NE)
+REPLACE_COMPARE_IC_CALL(JSStrictEqual, Token::EQ_STRICT)
+REPLACE_COMPARE_IC_CALL(JSStrictNotEqual, Token::NE_STRICT)
+REPLACE_COMPARE_IC_CALL(JSLessThan, Token::LT)
+REPLACE_COMPARE_IC_CALL(JSGreaterThan, Token::GT)
+REPLACE_COMPARE_IC_CALL(JSLessThanOrEqual, Token::LTE)
+REPLACE_COMPARE_IC_CALL(JSGreaterThanOrEqual, Token::GTE)
 #undef REPLACE_COMPARE_IC_CALL
 
 
@@ -119,7 +105,7 @@
 REPLACE_RUNTIME_CALL(JSCreateWithContext, Runtime::kPushWithContext)
 REPLACE_RUNTIME_CALL(JSCreateBlockContext, Runtime::kPushBlockContext)
 REPLACE_RUNTIME_CALL(JSCreateModuleContext, Runtime::kPushModuleContext)
-REPLACE_RUNTIME_CALL(JSCreateGlobalContext, Runtime::kAbort)
+REPLACE_RUNTIME_CALL(JSCreateScriptContext, Runtime::kAbort)
 #undef REPLACE_RUNTIME
 
 
@@ -140,8 +126,7 @@
 }
 
 
-void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token,
-                                             bool pure) {
+void JSGenericLowering::ReplaceWithCompareIC(Node* node, Token::Value token) {
   Callable callable = CodeFactory::CompareIC(isolate(), token);
   bool has_frame_state = OperatorProperties::HasFrameStateInput(node->op());
   CallDescriptor* desc_compare = linkage()->GetStubCallDescriptor(
@@ -149,11 +134,11 @@
       CallDescriptor::kPatchableCallSiteWithNop | FlagsForNode(node));
   NodeVector inputs(zone());
   inputs.reserve(node->InputCount() + 1);
-  inputs.push_back(CodeConstant(callable.code()));
+  inputs.push_back(jsgraph()->HeapConstant(callable.code()));
   inputs.push_back(NodeProperties::GetValueInput(node, 0));
   inputs.push_back(NodeProperties::GetValueInput(node, 1));
   inputs.push_back(NodeProperties::GetContextInput(node));
-  if (pure) {
+  if (node->op()->HasProperty(Operator::kPure)) {
     // A pure (strict) comparison doesn't have an effect, control or frame
     // state.  But for the graph, we need to add control and effect inputs.
     DCHECK(!has_frame_state);
@@ -172,7 +157,7 @@
                        static_cast<int>(inputs.size()), &inputs.front());
 
   node->ReplaceInput(0, compare);
-  node->ReplaceInput(1, SmiConstant(token));
+  node->ReplaceInput(1, jsgraph()->SmiConstant(token));
 
   if (has_frame_state) {
     // Remove the frame state from inputs.
@@ -185,9 +170,10 @@
 
 void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
                                             CallDescriptor::Flags flags) {
+  Operator::Properties properties = node->op()->properties();
   CallDescriptor* desc = linkage()->GetStubCallDescriptor(
-      callable.descriptor(), 0, flags | FlagsForNode(node));
-  Node* stub_code = CodeConstant(callable.code());
+      callable.descriptor(), 0, flags | FlagsForNode(node), properties);
+  Node* stub_code = jsgraph()->HeapConstant(callable.code());
   PatchInsertInput(node, 0, stub_code);
   PatchOperator(node, common()->Call(desc));
 }
@@ -196,16 +182,17 @@
 void JSGenericLowering::ReplaceWithBuiltinCall(Node* node,
                                                Builtins::JavaScript id,
                                                int nargs) {
+  Operator::Properties properties = node->op()->properties();
   Callable callable =
       CodeFactory::CallFunction(isolate(), nargs - 1, NO_CALL_FUNCTION_FLAGS);
-  CallDescriptor* desc =
-      linkage()->GetStubCallDescriptor(callable.descriptor(), nargs);
+  CallDescriptor* desc = linkage()->GetStubCallDescriptor(
+      callable.descriptor(), nargs, FlagsForNode(node), properties);
   // TODO(mstarzinger): Accessing the builtins object this way prevents sharing
   // of code across native contexts. Fix this by loading from given context.
   Handle<JSFunction> function(
       JSFunction::cast(info()->context()->builtins()->javascript_builtin(id)));
-  Node* stub_code = CodeConstant(callable.code());
-  Node* function_node = FunctionConstant(function);
+  Node* stub_code = jsgraph()->HeapConstant(callable.code());
+  Node* function_node = jsgraph()->HeapConstant(function);
   PatchInsertInput(node, 0, stub_code);
   PatchInsertInput(node, 1, function_node);
   PatchOperator(node, common()->Call(desc));
@@ -220,30 +207,15 @@
   int nargs = (nargs_override < 0) ? fun->nargs : nargs_override;
   CallDescriptor* desc =
       linkage()->GetRuntimeCallDescriptor(f, nargs, properties);
-  Node* ref = ExternalConstant(ExternalReference(f, isolate()));
-  Node* arity = Int32Constant(nargs);
-  if (!centrystub_constant_.is_set()) {
-    centrystub_constant_.set(CodeConstant(CEntryStub(isolate(), 1).GetCode()));
-  }
-  PatchInsertInput(node, 0, centrystub_constant_.get());
+  Node* ref = jsgraph()->ExternalConstant(ExternalReference(f, isolate()));
+  Node* arity = jsgraph()->Int32Constant(nargs);
+  PatchInsertInput(node, 0, jsgraph()->CEntryStubConstant(fun->result_size));
   PatchInsertInput(node, nargs + 1, ref);
   PatchInsertInput(node, nargs + 2, arity);
   PatchOperator(node, common()->Call(desc));
 }
 
 
-void JSGenericLowering::LowerBranch(Node* node) {
-  if (!info()->is_typing_enabled()) {
-    // TODO(mstarzinger): If typing is enabled then simplified lowering will
-    // have inserted the correct ChangeBoolToBit, otherwise we need to perform
-    // poor-man's representation inference here and insert manual change.
-    Node* test = graph()->NewNode(machine()->WordEqual(), node->InputAt(0),
-                                  jsgraph()->TrueConstant());
-    node->ReplaceInput(0, test);
-  }
-}
-
-
 void JSGenericLowering::LowerJSUnaryNot(Node* node) {
   Callable callable = CodeFactory::ToBoolean(
       isolate(), ToBooleanStub::RESULT_AS_INVERSE_ODDBALL);
@@ -260,7 +232,7 @@
 
 void JSGenericLowering::LowerJSToNumber(Node* node) {
   Callable callable = CodeFactory::ToNumber(isolate());
-  ReplaceWithStubCall(node, callable, CallDescriptor::kNoFlags);
+  ReplaceWithStubCall(node, callable, FlagsForNode(node));
 }
 
 
@@ -275,15 +247,25 @@
 
 
 void JSGenericLowering::LowerJSLoadProperty(Node* node) {
-  Callable callable = CodeFactory::KeyedLoadIC(isolate());
+  const LoadPropertyParameters& p = LoadPropertyParametersOf(node->op());
+  Callable callable = CodeFactory::KeyedLoadICInOptimizedCode(isolate());
+  if (FLAG_vector_ics) {
+    PatchInsertInput(node, 2, jsgraph()->SmiConstant(p.feedback().index()));
+    PatchInsertInput(node, 3, jsgraph()->HeapConstant(p.feedback().vector()));
+  }
   ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
 }
 
 
 void JSGenericLowering::LowerJSLoadNamed(Node* node) {
-  LoadNamedParameters p = OpParameter<LoadNamedParameters>(node);
-  Callable callable = CodeFactory::LoadIC(isolate(), p.contextual_mode);
-  PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name));
+  const LoadNamedParameters& p = LoadNamedParametersOf(node->op());
+  Callable callable =
+      CodeFactory::LoadICInOptimizedCode(isolate(), p.contextual_mode());
+  PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name()));
+  if (FLAG_vector_ics) {
+    PatchInsertInput(node, 2, jsgraph()->SmiConstant(p.feedback().index()));
+    PatchInsertInput(node, 3, jsgraph()->HeapConstant(p.feedback().vector()));
+  }
   ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
 }
 
@@ -296,16 +278,16 @@
 
 
 void JSGenericLowering::LowerJSStoreNamed(Node* node) {
-  StoreNamedParameters params = OpParameter<StoreNamedParameters>(node);
-  Callable callable = CodeFactory::StoreIC(isolate(), params.strict_mode);
-  PatchInsertInput(node, 1, jsgraph()->HeapConstant(params.name));
+  const StoreNamedParameters& p = StoreNamedParametersOf(node->op());
+  Callable callable = CodeFactory::StoreIC(isolate(), p.strict_mode());
+  PatchInsertInput(node, 1, jsgraph()->HeapConstant(p.name()));
   ReplaceWithStubCall(node, callable, CallDescriptor::kPatchableCallSite);
 }
 
 
 void JSGenericLowering::LowerJSDeleteProperty(Node* node) {
   StrictMode strict_mode = OpParameter<StrictMode>(node);
-  PatchInsertInput(node, 2, SmiConstant(strict_mode));
+  PatchInsertInput(node, 2, jsgraph()->SmiConstant(strict_mode));
   ReplaceWithBuiltinCall(node, Builtins::DELETE, 3);
 }
 
@@ -321,44 +303,46 @@
       InstanceofStub::kArgsInRegisters);
   InstanceofStub stub(isolate(), flags);
   CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor();
-  CallDescriptor* desc = linkage()->GetStubCallDescriptor(d, 0);
-  Node* stub_code = CodeConstant(stub.GetCode());
+  CallDescriptor* desc =
+      linkage()->GetStubCallDescriptor(d, 0, FlagsForNode(node));
+  Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
   PatchInsertInput(node, 0, stub_code);
   PatchOperator(node, common()->Call(desc));
 }
 
 
 void JSGenericLowering::LowerJSLoadContext(Node* node) {
-  ContextAccess access = OpParameter<ContextAccess>(node);
-  // TODO(mstarzinger): Use simplified operators instead of machine operators
-  // here so that load/store optimization can be applied afterwards.
-  for (int i = 0; i < access.depth(); ++i) {
+  const ContextAccess& access = ContextAccessOf(node->op());
+  for (size_t i = 0; i < access.depth(); ++i) {
     node->ReplaceInput(
-        0, graph()->NewNode(
-               machine()->Load(kMachAnyTagged),
-               NodeProperties::GetValueInput(node, 0),
-               Int32Constant(Context::SlotOffset(Context::PREVIOUS_INDEX)),
-               NodeProperties::GetEffectInput(node)));
+        0, graph()->NewNode(machine()->Load(kMachAnyTagged),
+                            NodeProperties::GetValueInput(node, 0),
+                            jsgraph()->Int32Constant(
+                                Context::SlotOffset(Context::PREVIOUS_INDEX)),
+                            NodeProperties::GetEffectInput(node),
+                            graph()->start()));
   }
-  node->ReplaceInput(1, Int32Constant(Context::SlotOffset(access.index())));
+  node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset(
+                            static_cast<int>(access.index()))));
+  node->AppendInput(zone(), graph()->start());
   PatchOperator(node, machine()->Load(kMachAnyTagged));
 }
 
 
 void JSGenericLowering::LowerJSStoreContext(Node* node) {
-  ContextAccess access = OpParameter<ContextAccess>(node);
-  // TODO(mstarzinger): Use simplified operators instead of machine operators
-  // here so that load/store optimization can be applied afterwards.
-  for (int i = 0; i < access.depth(); ++i) {
+  const ContextAccess& access = ContextAccessOf(node->op());
+  for (size_t i = 0; i < access.depth(); ++i) {
     node->ReplaceInput(
-        0, graph()->NewNode(
-               machine()->Load(kMachAnyTagged),
-               NodeProperties::GetValueInput(node, 0),
-               Int32Constant(Context::SlotOffset(Context::PREVIOUS_INDEX)),
-               NodeProperties::GetEffectInput(node)));
+        0, graph()->NewNode(machine()->Load(kMachAnyTagged),
+                            NodeProperties::GetValueInput(node, 0),
+                            jsgraph()->Int32Constant(
+                                Context::SlotOffset(Context::PREVIOUS_INDEX)),
+                            NodeProperties::GetEffectInput(node),
+                            graph()->start()));
   }
   node->ReplaceInput(2, NodeProperties::GetValueInput(node, 1));
-  node->ReplaceInput(1, Int32Constant(Context::SlotOffset(access.index())));
+  node->ReplaceInput(1, jsgraph()->Int32Constant(Context::SlotOffset(
+                            static_cast<int>(access.index()))));
   PatchOperator(node, machine()->Store(StoreRepresentation(kMachAnyTagged,
                                                            kFullWriteBarrier)));
 }
@@ -370,32 +354,73 @@
   CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor();
   CallDescriptor* desc =
       linkage()->GetStubCallDescriptor(d, arity, FlagsForNode(node));
-  Node* stub_code = CodeConstant(stub.GetCode());
+  Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
   Node* construct = NodeProperties::GetValueInput(node, 0);
   PatchInsertInput(node, 0, stub_code);
-  PatchInsertInput(node, 1, Int32Constant(arity - 1));
+  PatchInsertInput(node, 1, jsgraph()->Int32Constant(arity - 1));
   PatchInsertInput(node, 2, construct);
   PatchInsertInput(node, 3, jsgraph()->UndefinedConstant());
   PatchOperator(node, common()->Call(desc));
 }
 
 
+bool JSGenericLowering::TryLowerDirectJSCall(Node* node) {
+  // Lower to a direct call to a constant JSFunction if legal.
+  const CallFunctionParameters& p = CallFunctionParametersOf(node->op());
+  int arg_count = static_cast<int>(p.arity() - 2);
+
+  // Check the function is a constant and is really a JSFunction.
+  HeapObjectMatcher<Object> function_const(node->InputAt(0));
+  if (!function_const.HasValue()) return false;  // not a constant.
+  Handle<Object> func = function_const.Value().handle();
+  if (!func->IsJSFunction()) return false;  // not a function.
+  Handle<JSFunction> function = Handle<JSFunction>::cast(func);
+  if (arg_count != function->shared()->formal_parameter_count()) return false;
+
+  // Check the receiver doesn't need to be wrapped.
+  Node* receiver = node->InputAt(1);
+  if (!NodeProperties::IsTyped(receiver)) return false;
+  Type* ok_receiver = Type::Union(Type::Undefined(), Type::Receiver(), zone());
+  if (!NodeProperties::GetBounds(receiver).upper->Is(ok_receiver)) return false;
+
+  int index = NodeProperties::FirstContextIndex(node);
+
+  // TODO(titzer): total hack to share function context constants.
+  // Remove this when the JSGraph canonicalizes heap constants.
+  Node* context = node->InputAt(index);
+  HeapObjectMatcher<Context> context_const(context);
+  if (!context_const.HasValue() ||
+      *(context_const.Value().handle()) != function->context()) {
+    context = jsgraph()->HeapConstant(Handle<Context>(function->context()));
+  }
+  node->ReplaceInput(index, context);
+  CallDescriptor* desc = linkage()->GetJSCallDescriptor(
+      1 + arg_count, jsgraph()->zone(), FlagsForNode(node));
+  PatchOperator(node, common()->Call(desc));
+  return true;
+}
+
+
 void JSGenericLowering::LowerJSCallFunction(Node* node) {
-  CallParameters p = OpParameter<CallParameters>(node);
-  CallFunctionStub stub(isolate(), p.arity - 2, p.flags);
+  // Fast case: call function directly.
+  if (TryLowerDirectJSCall(node)) return;
+
+  // General case: CallFunctionStub.
+  const CallFunctionParameters& p = CallFunctionParametersOf(node->op());
+  int arg_count = static_cast<int>(p.arity() - 2);
+  CallFunctionStub stub(isolate(), arg_count, p.flags());
   CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor();
-  CallDescriptor* desc =
-      linkage()->GetStubCallDescriptor(d, p.arity - 1, FlagsForNode(node));
-  Node* stub_code = CodeConstant(stub.GetCode());
+  CallDescriptor* desc = linkage()->GetStubCallDescriptor(
+      d, static_cast<int>(p.arity() - 1), FlagsForNode(node));
+  Node* stub_code = jsgraph()->HeapConstant(stub.GetCode());
   PatchInsertInput(node, 0, stub_code);
   PatchOperator(node, common()->Call(desc));
 }
 
 
 void JSGenericLowering::LowerJSCallRuntime(Node* node) {
-  Runtime::FunctionId function = OpParameter<Runtime::FunctionId>(node);
-  int arity = OperatorProperties::GetValueInputCount(node->op());
-  ReplaceWithRuntimeCall(node, function, arity);
+  const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op());
+  ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity()));
 }
 
 }  // namespace compiler
diff --git a/src/compiler/js-generic-lowering.h b/src/compiler/js-generic-lowering.h
index 400f806..f626338 100644
--- a/src/compiler/js-generic-lowering.h
+++ b/src/compiler/js-generic-lowering.h
@@ -5,13 +5,12 @@
 #ifndef V8_COMPILER_JS_GENERIC_LOWERING_H_
 #define V8_COMPILER_JS_GENERIC_LOWERING_H_
 
-#include "src/v8.h"
-
 #include "src/allocation.h"
 #include "src/code-factory.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/graph-reducer.h"
 #include "src/compiler/js-graph.h"
+#include "src/compiler/linkage.h"
 #include "src/compiler/opcodes.h"
 
 namespace v8 {
@@ -23,37 +22,34 @@
 class MachineOperatorBuilder;
 class Linkage;
 
+
 // Lowers JS-level operators to runtime and IC calls in the "generic" case.
-class JSGenericLowering : public Reducer {
+class JSGenericLowering FINAL : public Reducer {
  public:
   JSGenericLowering(CompilationInfo* info, JSGraph* graph);
-  virtual ~JSGenericLowering() {}
+  ~JSGenericLowering() FINAL {}
 
-  virtual Reduction Reduce(Node* node);
+  Reduction Reduce(Node* node) FINAL;
 
  protected:
 #define DECLARE_LOWER(x) void Lower##x(Node* node);
   // Dispatched depending on opcode.
-  ALL_OP_LIST(DECLARE_LOWER)
+  JS_OP_LIST(DECLARE_LOWER)
 #undef DECLARE_LOWER
 
-  // Helpers to create new constant nodes.
-  Node* SmiConstant(int immediate);
-  Node* Int32Constant(int immediate);
-  Node* CodeConstant(Handle<Code> code);
-  Node* FunctionConstant(Handle<JSFunction> function);
-  Node* ExternalConstant(ExternalReference ref);
-
   // Helpers to patch existing nodes in the graph.
   void PatchOperator(Node* node, const Operator* new_op);
   void PatchInsertInput(Node* node, int index, Node* input);
 
   // Helpers to replace existing nodes with a generic call.
-  void ReplaceWithCompareIC(Node* node, Token::Value token, bool pure);
+  void ReplaceWithCompareIC(Node* node, Token::Value token);
   void ReplaceWithStubCall(Node* node, Callable c, CallDescriptor::Flags flags);
   void ReplaceWithBuiltinCall(Node* node, Builtins::JavaScript id, int args);
   void ReplaceWithRuntimeCall(Node* node, Runtime::FunctionId f, int args = -1);
 
+  // Helper for optimization of JSCallFunction.
+  bool TryLowerDirectJSCall(Node* node);
+
   Zone* zone() const { return graph()->zone(); }
   Isolate* isolate() const { return zone()->isolate(); }
   JSGraph* jsgraph() const { return jsgraph_; }
@@ -67,7 +63,6 @@
   CompilationInfo* info_;
   JSGraph* jsgraph_;
   Linkage* linkage_;
-  SetOncePointer<Node> centrystub_constant_;
 };
 
 }  // namespace compiler
diff --git a/src/compiler/js-graph.cc b/src/compiler/js-graph.cc
index 1309531..7759ba1 100644
--- a/src/compiler/js-graph.cc
+++ b/src/compiler/js-graph.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/code-stubs.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/compiler/typer.h"
@@ -10,25 +11,22 @@
 namespace internal {
 namespace compiler {
 
-Node* JSGraph::ImmovableHeapConstant(Handle<Object> object) {
-  Unique<Object> unique = Unique<Object>::CreateImmovable(object);
-  return NewNode(common()->HeapConstant(unique));
+Node* JSGraph::ImmovableHeapConstant(Handle<HeapObject> object) {
+  Unique<HeapObject> unique = Unique<HeapObject>::CreateImmovable(object);
+  return graph()->NewNode(common()->HeapConstant(unique));
 }
 
 
-Node* JSGraph::NewNode(const Operator* op) {
-  Node* node = graph()->NewNode(op);
-  typer_->Init(node);
-  return node;
-}
-
-
-Node* JSGraph::CEntryStubConstant() {
-  if (!c_entry_stub_constant_.is_set()) {
-    c_entry_stub_constant_.set(
-        ImmovableHeapConstant(CEntryStub(isolate(), 1).GetCode()));
+Node* JSGraph::CEntryStubConstant(int result_size) {
+  if (result_size == 1) {
+    if (!c_entry_stub_constant_.is_set()) {
+      c_entry_stub_constant_.set(
+          ImmovableHeapConstant(CEntryStub(isolate(), 1).GetCode()));
+    }
+    return c_entry_stub_constant_.get();
   }
-  return c_entry_stub_constant_.get();
+
+  return ImmovableHeapConstant(CEntryStub(isolate(), result_size).GetCode());
 }
 
 
@@ -93,13 +91,13 @@
 }
 
 
-Node* JSGraph::HeapConstant(Unique<Object> value) {
+Node* JSGraph::HeapConstant(Unique<HeapObject> value) {
   // TODO(turbofan): canonicalize heap constants using Unique<T>
-  return NewNode(common()->HeapConstant(value));
+  return graph()->NewNode(common()->HeapConstant(value));
 }
 
 
-Node* JSGraph::HeapConstant(Handle<Object> value) {
+Node* JSGraph::HeapConstant(Handle<HeapObject> value) {
   // TODO(titzer): We could also match against the addresses of immortable
   // immovables here, even without access to the heap, thus always
   // canonicalizing references to them.
@@ -107,7 +105,8 @@
   // TODO(turbofan): This is a work-around to make Unique::HashCode() work for
   // value numbering. We need some sane way to compute a unique hash code for
   // arbitrary handles here.
-  Unique<Object> unique(reinterpret_cast<Address>(*value.location()), value);
+  Unique<HeapObject> unique(reinterpret_cast<Address>(*value.location()),
+                            value);
   return HeapConstant(unique);
 }
 
@@ -128,7 +127,7 @@
   } else if (value->IsTheHole()) {
     return TheHoleConstant();
   } else {
-    return HeapConstant(value);
+    return HeapConstant(Handle<HeapObject>::cast(value));
   }
 }
 
@@ -150,7 +149,16 @@
 Node* JSGraph::Int32Constant(int32_t value) {
   Node** loc = cache_.FindInt32Constant(value);
   if (*loc == NULL) {
-    *loc = NewNode(common()->Int32Constant(value));
+    *loc = graph()->NewNode(common()->Int32Constant(value));
+  }
+  return *loc;
+}
+
+
+Node* JSGraph::Int64Constant(int64_t value) {
+  Node** loc = cache_.FindInt64Constant(value);
+  if (*loc == NULL) {
+    *loc = graph()->NewNode(common()->Int64Constant(value));
   }
   return *loc;
 }
@@ -159,7 +167,16 @@
 Node* JSGraph::NumberConstant(double value) {
   Node** loc = cache_.FindNumberConstant(value);
   if (*loc == NULL) {
-    *loc = NewNode(common()->NumberConstant(value));
+    *loc = graph()->NewNode(common()->NumberConstant(value));
+  }
+  return *loc;
+}
+
+
+Node* JSGraph::Float32Constant(float value) {
+  Node** loc = cache_.FindFloat32Constant(value);
+  if (*loc == NULL) {
+    *loc = graph()->NewNode(common()->Float32Constant(value));
   }
   return *loc;
 }
@@ -168,7 +185,7 @@
 Node* JSGraph::Float64Constant(double value) {
   Node** loc = cache_.FindFloat64Constant(value);
   if (*loc == NULL) {
-    *loc = NewNode(common()->Float64Constant(value));
+    *loc = graph()->NewNode(common()->Float64Constant(value));
   }
   return *loc;
 }
@@ -177,10 +194,23 @@
 Node* JSGraph::ExternalConstant(ExternalReference reference) {
   Node** loc = cache_.FindExternalConstant(reference);
   if (*loc == NULL) {
-    *loc = NewNode(common()->ExternalConstant(reference));
+    *loc = graph()->NewNode(common()->ExternalConstant(reference));
   }
   return *loc;
 }
+
+
+void JSGraph::GetCachedNodes(NodeVector* nodes) {
+  cache_.GetCachedNodes(nodes);
+  SetOncePointer<Node>* ptrs[] = {
+      &c_entry_stub_constant_, &undefined_constant_, &the_hole_constant_,
+      &true_constant_,         &false_constant_,     &null_constant_,
+      &zero_constant_,         &one_constant_,       &nan_constant_};
+  for (size_t i = 0; i < arraysize(ptrs); i++) {
+    if (ptrs[i]->is_set()) nodes->push_back(ptrs[i]->get());
+  }
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/js-graph.h b/src/compiler/js-graph.h
index 2b2dfd1..040a745 100644
--- a/src/compiler/js-graph.h
+++ b/src/compiler/js-graph.h
@@ -24,17 +24,15 @@
 class JSGraph : public ZoneObject {
  public:
   JSGraph(Graph* graph, CommonOperatorBuilder* common,
-          JSOperatorBuilder* javascript, Typer* typer,
-          MachineOperatorBuilder* machine)
+          JSOperatorBuilder* javascript, MachineOperatorBuilder* machine)
       : graph_(graph),
         common_(common),
         javascript_(javascript),
-        typer_(typer),
         machine_(machine),
         cache_(zone()) {}
 
   // Canonicalized global constants.
-  Node* CEntryStubConstant();
+  Node* CEntryStubConstant(int result_size);
   Node* UndefinedConstant();
   Node* TheHoleConstant();
   Node* TrueConstant();
@@ -46,11 +44,11 @@
 
   // Creates a HeapConstant node, possibly canonicalized, without inspecting the
   // object.
-  Node* HeapConstant(Unique<Object> value);
+  Node* HeapConstant(Unique<HeapObject> value);
 
   // Creates a HeapConstant node, possibly canonicalized, and may access the
   // heap to inspect the object.
-  Node* HeapConstant(Handle<Object> value);
+  Node* HeapConstant(Handle<HeapObject> value);
 
   // Creates a Constant node of the appropriate type for the given object.
   // Accesses the heap to inspect the object and determine whether one of the
@@ -69,6 +67,33 @@
     return Int32Constant(bit_cast<int32_t>(value));
   }
 
+  // Creates a HeapConstant node for either true or false.
+  Node* BooleanConstant(bool is_true) {
+    return is_true ? TrueConstant() : FalseConstant();
+  }
+
+  // Creates a Int64Constant node, usually canonicalized.
+  Node* Int64Constant(int64_t value);
+  Node* Uint64Constant(uint64_t value) {
+    return Int64Constant(bit_cast<int64_t>(value));
+  }
+
+  // Creates a Int32Constant/Int64Constant node, depending on the word size of
+  // the target machine.
+  // TODO(turbofan): Code using Int32Constant/Int64Constant to store pointer
+  // constants is probably not serializable.
+  Node* IntPtrConstant(intptr_t value) {
+    return machine()->Is32() ? Int32Constant(static_cast<int32_t>(value))
+                             : Int64Constant(static_cast<int64_t>(value));
+  }
+  template <typename T>
+  Node* PointerConstant(T* value) {
+    return IntPtrConstant(bit_cast<intptr_t>(value));
+  }
+
+  // Creates a Float32Constant node, usually canonicalized.
+  Node* Float32Constant(float value);
+
   // Creates a Float64Constant node, usually canonicalized.
   Node* Float64Constant(double value);
 
@@ -80,20 +105,27 @@
     return Constant(immediate);
   }
 
+  // Creates a dummy Constant node, used to satisfy calling conventions of
+  // stubs and runtime functions that do not require a context.
+  Node* NoContextConstant() { return ZeroConstant(); }
+
   JSOperatorBuilder* javascript() { return javascript_; }
   CommonOperatorBuilder* common() { return common_; }
   MachineOperatorBuilder* machine() { return machine_; }
   Graph* graph() { return graph_; }
   Zone* zone() { return graph()->zone(); }
   Isolate* isolate() { return zone()->isolate(); }
+  Factory* factory() { return isolate()->factory(); }
+
+  void GetCachedNodes(NodeVector* nodes);
 
  private:
   Graph* graph_;
   CommonOperatorBuilder* common_;
   JSOperatorBuilder* javascript_;
-  Typer* typer_;
   MachineOperatorBuilder* machine_;
 
+  // TODO(titzer): make this into a simple array.
   SetOncePointer<Node> c_entry_stub_constant_;
   SetOncePointer<Node> undefined_constant_;
   SetOncePointer<Node> the_hole_constant_;
@@ -106,11 +138,10 @@
 
   CommonNodeCache cache_;
 
-  Node* ImmovableHeapConstant(Handle<Object> value);
+  Node* ImmovableHeapConstant(Handle<HeapObject> value);
   Node* NumberConstant(double value);
-  Node* NewNode(const Operator* op);
 
-  Factory* factory() { return isolate()->factory(); }
+  DISALLOW_COPY_AND_ASSIGN(JSGraph);
 };
 
 }  // namespace compiler
diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc
index af02145..d143382 100644
--- a/src/compiler/js-inlining.cc
+++ b/src/compiler/js-inlining.cc
@@ -2,13 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/ast.h"
+#include "src/ast-numbering.h"
 #include "src/compiler/access-builder.h"
 #include "src/compiler/ast-graph-builder.h"
 #include "src/compiler/common-operator.h"
-#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/graph-inl.h"
 #include "src/compiler/graph-visualizer.h"
 #include "src/compiler/js-inlining.h"
+#include "src/compiler/js-intrinsic-builder.h"
 #include "src/compiler/js-operator.h"
 #include "src/compiler/node-aux-data-inl.h"
 #include "src/compiler/node-matchers.h"
@@ -29,15 +31,19 @@
  public:
   explicit InlinerVisitor(JSInliner* inliner) : inliner_(inliner) {}
 
-  GenericGraphVisit::Control Post(Node* node) {
+  void Post(Node* node) {
     switch (node->opcode()) {
       case IrOpcode::kJSCallFunction:
-        inliner_->TryInlineCall(node);
+        inliner_->TryInlineJSCall(node);
+        break;
+      case IrOpcode::kJSCallRuntime:
+        if (FLAG_turbo_inlining_intrinsics) {
+          inliner_->TryInlineRuntimeCall(node);
+        }
         break;
       default:
         break;
     }
-    return GenericGraphVisit::CONTINUE;
   }
 
  private:
@@ -51,16 +57,6 @@
 }
 
 
-// TODO(sigurds) Find a home for this function and reuse it everywhere (esp. in
-// test cases, where similar code is currently duplicated).
-static void Parse(Handle<JSFunction> function, CompilationInfoWithZone* info) {
-  CHECK(Parser::Parse(info));
-  CHECK(Rewriter::Rewrite(info));
-  CHECK(Scope::Analyze(info));
-  CHECK(Compiler::EnsureDeoptimizationSupport(info));
-}
-
-
 // A facade on a JSFunction's graph to facilitate inlining. It assumes the
 // that the function graph has only one return statement, and provides
 // {UnifyReturn} to convert a function graph to that end.
@@ -90,7 +86,7 @@
   }
 
   // Counts JSFunction, Receiver, arguments, context but not effect, control.
-  size_t total_parameters() { return start_->op()->OutputCount(); }
+  size_t total_parameters() { return start_->op()->ValueOutputCount(); }
 
   // Counts only formal parameters.
   size_t formal_parameters() {
@@ -121,8 +117,7 @@
   }
   DCHECK_EQ(IrOpcode::kMerge, final_merge->opcode());
 
-  int predecessors =
-      OperatorProperties::GetControlInputCount(final_merge->op());
+  int predecessors = final_merge->op()->ControlInputCount();
 
   const Operator* op_phi = jsgraph->common()->Phi(kMachAnyTagged, predecessors);
   const Operator* op_ephi = jsgraph->common()->EffectPhi(predecessors);
@@ -131,19 +126,17 @@
   NodeVector effects(jsgraph->zone());
   // Iterate over all control flow predecessors,
   // which must be return statements.
-  InputIter iter = final_merge->inputs().begin();
-  while (iter != final_merge->inputs().end()) {
-    Node* input = *iter;
+  for (Edge edge : final_merge->input_edges()) {
+    Node* input = edge.to();
     switch (input->opcode()) {
       case IrOpcode::kReturn:
         values.push_back(NodeProperties::GetValueInput(input, 0));
         effects.push_back(NodeProperties::GetEffectInput(input));
-        iter.UpdateToAndIncrement(NodeProperties::GetControlInput(input));
+        edge.UpdateTo(NodeProperties::GetControlInput(input));
         input->RemoveAllInputs();
         break;
       default:
         UNREACHABLE();
-        ++iter;
         break;
     }
   }
@@ -167,14 +160,13 @@
         source_graph_(source_graph),
         target_graph_(target_graph),
         temp_zone_(temp_zone),
-        sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, 0, 0,
-                     "sentinel") {}
+        sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, "sentinel", 0, 0,
+                     0, 0, 0, 0) {}
 
-  GenericGraphVisit::Control Post(Node* original) {
+  void Post(Node* original) {
     NodeVector inputs(temp_zone_);
-    for (InputIter it = original->inputs().begin();
-         it != original->inputs().end(); ++it) {
-      inputs.push_back(GetCopy(*it));
+    for (Node* const node : original->inputs()) {
+      inputs.push_back(GetCopy(node));
     }
 
     // Reuse the operator in the copy. This assumes that op lives in a zone
@@ -183,7 +175,6 @@
         target_graph_->NewNode(original->op(), static_cast<int>(inputs.size()),
                                (inputs.empty() ? NULL : &inputs.front()));
     copies_[original->id()] = copy;
-    return GenericGraphVisit::CONTINUE;
   }
 
   Node* GetCopy(Node* original) {
@@ -214,11 +205,10 @@
   }
 
   Node* GetSentinel(Node* original) {
-    Node* sentinel = sentinels_[original->id()];
-    if (sentinel == NULL) {
-      sentinel = target_graph_->NewNode(&sentinel_op_);
+    if (sentinels_[original->id()] == NULL) {
+      sentinels_[original->id()] = target_graph_->NewNode(&sentinel_op_);
     }
-    return sentinel;
+    return sentinels_[original->id()];
   }
 
   NodeVector copies_;
@@ -226,7 +216,7 @@
   Graph* source_graph_;
   Graph* target_graph_;
   Zone* temp_zone_;
-  SimpleOperator sentinel_op_;
+  Operator sentinel_op_;
 };
 
 
@@ -241,43 +231,41 @@
   Node* context = jsgraph->graph()->NewNode(
       simplified.LoadField(AccessBuilder::ForJSFunctionContext()),
       NodeProperties::GetValueInput(call, 0),
-      NodeProperties::GetEffectInput(call));
+      NodeProperties::GetEffectInput(call), control);
 
   // Context is last argument.
   int inlinee_context_index = static_cast<int>(total_parameters()) - 1;
   // {inliner_inputs} counts JSFunction, Receiver, arguments, but not
   // context, effect, control.
-  int inliner_inputs = OperatorProperties::GetValueInputCount(call->op());
+  int inliner_inputs = call->op()->ValueInputCount();
   // Iterate over all uses of the start node.
-  UseIter iter = start_->uses().begin();
-  while (iter != start_->uses().end()) {
-    Node* use = *iter;
+  for (Edge edge : start_->use_edges()) {
+    Node* use = edge.from();
     switch (use->opcode()) {
       case IrOpcode::kParameter: {
         int index = 1 + OpParameter<int>(use->op());
         if (index < inliner_inputs && index < inlinee_context_index) {
           // There is an input from the call, and the index is a value
           // projection but not the context, so rewire the input.
-          NodeProperties::ReplaceWithValue(*iter, call->InputAt(index));
+          NodeProperties::ReplaceWithValue(use, call->InputAt(index));
         } else if (index == inlinee_context_index) {
           // This is the context projection, rewire it to the context from the
           // JSFunction object.
-          NodeProperties::ReplaceWithValue(*iter, context);
+          NodeProperties::ReplaceWithValue(use, context);
         } else if (index < inlinee_context_index) {
           // Call has fewer arguments than required, fill with undefined.
-          NodeProperties::ReplaceWithValue(*iter, jsgraph->UndefinedConstant());
+          NodeProperties::ReplaceWithValue(use, jsgraph->UndefinedConstant());
         } else {
           // We got too many arguments, discard for now.
           // TODO(sigurds): Fix to treat arguments array correctly.
         }
-        ++iter;
         break;
       }
       default:
-        if (NodeProperties::IsEffectEdge(iter.edge())) {
-          iter.UpdateToAndIncrement(context);
-        } else if (NodeProperties::IsControlEdge(iter.edge())) {
-          iter.UpdateToAndIncrement(control);
+        if (NodeProperties::IsEffectEdge(edge)) {
+          edge.UpdateTo(context);
+        } else if (NodeProperties::IsControlEdge(edge)) {
+          edge.UpdateTo(control);
         } else {
           UNREACHABLE();
         }
@@ -285,22 +273,9 @@
     }
   }
 
-  // Iterate over all uses of the call node.
-  iter = call->uses().begin();
-  while (iter != call->uses().end()) {
-    if (NodeProperties::IsEffectEdge(iter.edge())) {
-      iter.UpdateToAndIncrement(effect_output());
-    } else if (NodeProperties::IsControlEdge(iter.edge())) {
-      UNREACHABLE();
-    } else {
-      DCHECK(NodeProperties::IsValueEdge(iter.edge()));
-      iter.UpdateToAndIncrement(value_output());
-    }
-  }
+  NodeProperties::ReplaceWithValue(call, value_output(), effect_output());
   call->RemoveAllInputs();
   DCHECK_EQ(0, call->UseCount());
-  // TODO(sigurds) Remove this once we copy.
-  unique_return()->RemoveAllInputs();
 }
 
 
@@ -323,7 +298,7 @@
 
   size_t formal_arguments() {
     // {value_inputs} includes jsfunction and receiver.
-    size_t value_inputs = OperatorProperties::GetValueInputCount(call_->op());
+    size_t value_inputs = call_->op()->ValueInputCount();
     DCHECK_GE(call_->InputCount(), 2);
     return value_inputs - 2;
   }
@@ -348,9 +323,9 @@
 Node* JSInliner::CreateArgumentsAdaptorFrameState(JSCallFunctionAccessor* call,
                                                   Handle<JSFunction> jsfunction,
                                                   Zone* temp_zone) {
-  const Operator* op =
-      jsgraph_->common()->FrameState(FrameStateType::ARGUMENTS_ADAPTOR,
-                                     BailoutId(-1), kIgnoreOutput, jsfunction);
+  const Operator* op = jsgraph_->common()->FrameState(
+      FrameStateType::ARGUMENTS_ADAPTOR, BailoutId(-1),
+      OutputFrameStateCombine::Ignore(), jsfunction);
   const Operator* op0 = jsgraph_->common()->StateValues(0);
   Node* node0 = jsgraph_->graph()->NewNode(op0);
   NodeVector params(temp_zone);
@@ -368,7 +343,7 @@
 }
 
 
-void JSInliner::TryInlineCall(Node* call_node) {
+void JSInliner::TryInlineJSCall(Node* call_node) {
   JSCallFunctionAccessor call(call_node);
 
   HeapObjectMatcher<JSFunction> match(call.jsfunction());
@@ -389,9 +364,11 @@
   }
 
   CompilationInfoWithZone info(function);
-  Parse(function, &info);
+  // TODO(wingo): ParseAndAnalyze can fail due to stack overflow.
+  CHECK(Compiler::ParseAndAnalyze(&info));
+  CHECK(Compiler::EnsureDeoptimizationSupport(&info));
 
-  if (info.scope()->arguments() != NULL) {
+  if (info.scope()->arguments() != NULL && info.strict_mode() != STRICT) {
     // For now do not inline functions that use their arguments array.
     SmartArrayPointer<char> name = function->shared()->DebugName()->ToCString();
     if (FLAG_trace_turbo_inlining) {
@@ -410,11 +387,10 @@
   }
 
   Graph graph(info.zone());
-  Typer typer(info.zone());
-  JSGraph jsgraph(&graph, jsgraph_->common(), jsgraph_->javascript(), &typer,
+  JSGraph jsgraph(&graph, jsgraph_->common(), jsgraph_->javascript(),
                   jsgraph_->machine());
 
-  AstGraphBuilder graph_builder(&info, &jsgraph);
+  AstGraphBuilder graph_builder(local_zone_, &info, &jsgraph);
   graph_builder.CreateGraph();
   Inlinee::UnifyReturn(&jsgraph);
 
@@ -423,24 +399,91 @@
 
   Inlinee inlinee(visitor.GetCopy(graph.start()), visitor.GetCopy(graph.end()));
 
-  Node* outer_frame_state = call.frame_state();
-  // Insert argument adaptor frame if required.
-  if (call.formal_arguments() != inlinee.formal_parameters()) {
-    outer_frame_state =
-        CreateArgumentsAdaptorFrameState(&call, function, info.zone());
-  }
+  if (FLAG_turbo_deoptimization) {
+    Node* outer_frame_state = call.frame_state();
+    // Insert argument adaptor frame if required.
+    if (call.formal_arguments() != inlinee.formal_parameters()) {
+      outer_frame_state =
+          CreateArgumentsAdaptorFrameState(&call, function, info.zone());
+    }
 
-  for (NodeVectorConstIter it = visitor.copies().begin();
-       it != visitor.copies().end(); ++it) {
-    Node* node = *it;
-    if (node != NULL && node->opcode() == IrOpcode::kFrameState) {
-      AddClosureToFrameState(node, function);
-      NodeProperties::ReplaceFrameStateInput(node, outer_frame_state);
+    for (NodeVectorConstIter it = visitor.copies().begin();
+         it != visitor.copies().end(); ++it) {
+      Node* node = *it;
+      if (node != NULL && node->opcode() == IrOpcode::kFrameState) {
+        AddClosureToFrameState(node, function);
+        NodeProperties::ReplaceFrameStateInput(node, outer_frame_state);
+      }
     }
   }
 
   inlinee.InlineAtCall(jsgraph_, call_node);
 }
+
+
+class JSCallRuntimeAccessor {
+ public:
+  explicit JSCallRuntimeAccessor(Node* call) : call_(call) {
+    DCHECK_EQ(IrOpcode::kJSCallRuntime, call->opcode());
+  }
+
+  Node* formal_argument(size_t index) {
+    DCHECK(index < formal_arguments());
+    return call_->InputAt(static_cast<int>(index));
+  }
+
+  size_t formal_arguments() {
+    size_t value_inputs = call_->op()->ValueInputCount();
+    return value_inputs;
+  }
+
+  Node* frame_state() const {
+    return NodeProperties::GetFrameStateInput(call_);
+  }
+  Node* context() const { return NodeProperties::GetContextInput(call_); }
+  Node* control() const { return NodeProperties::GetControlInput(call_); }
+  Node* effect() const { return NodeProperties::GetEffectInput(call_); }
+
+  const Runtime::Function* function() const {
+    return Runtime::FunctionForId(CallRuntimeParametersOf(call_->op()).id());
+  }
+
+  NodeVector inputs(Zone* zone) const {
+    NodeVector inputs(zone);
+    for (Node* const node : call_->inputs()) {
+      inputs.push_back(node);
+    }
+    return inputs;
+  }
+
+ private:
+  Node* call_;
+};
+
+
+void JSInliner::TryInlineRuntimeCall(Node* call_node) {
+  JSCallRuntimeAccessor call(call_node);
+  const Runtime::Function* f = call.function();
+
+  if (f->intrinsic_type != Runtime::IntrinsicType::INLINE) {
+    return;
+  }
+
+  JSIntrinsicBuilder intrinsic_builder(jsgraph_);
+
+  ResultAndEffect r = intrinsic_builder.BuildGraphFor(
+      f->function_id, call.inputs(jsgraph_->zone()));
+
+  if (r.first != NULL) {
+    if (FLAG_trace_turbo_inlining) {
+      PrintF("Inlining %s into %s\n", f->name,
+             info_->shared_info()->DebugName()->ToCString().get());
+    }
+    NodeProperties::ReplaceWithValue(call_node, r.first, r.second);
+    call_node->RemoveAllInputs();
+    DCHECK_EQ(0, call_node->UseCount());
+  }
+}
 }
 }
 }  // namespace v8::internal::compiler
diff --git a/src/compiler/js-inlining.h b/src/compiler/js-inlining.h
index f135170..eef29d6 100644
--- a/src/compiler/js-inlining.h
+++ b/src/compiler/js-inlining.h
@@ -16,14 +16,16 @@
 
 class JSInliner {
  public:
-  JSInliner(CompilationInfo* info, JSGraph* jsgraph)
-      : info_(info), jsgraph_(jsgraph) {}
+  JSInliner(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph)
+      : local_zone_(local_zone), info_(info), jsgraph_(jsgraph) {}
 
   void Inline();
-  void TryInlineCall(Node* node);
+  void TryInlineJSCall(Node* node);
+  void TryInlineRuntimeCall(Node* node);
 
  private:
   friend class InlinerVisitor;
+  Zone* local_zone_;
   CompilationInfo* info_;
   JSGraph* jsgraph_;
 
diff --git a/src/compiler/js-intrinsic-builder.cc b/src/compiler/js-intrinsic-builder.cc
new file mode 100644
index 0000000..80b6968
--- /dev/null
+++ b/src/compiler/js-intrinsic-builder.cc
@@ -0,0 +1,140 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/access-builder.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/diamond.h"
+#include "src/compiler/js-intrinsic-builder.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/simplified-operator.h"
+
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+ResultAndEffect JSIntrinsicBuilder::BuildGraphFor(Runtime::FunctionId id,
+                                                  const NodeVector& arguments) {
+  switch (id) {
+    case Runtime::kInlineIsSmi:
+      return BuildGraphFor_IsSmi(arguments);
+    case Runtime::kInlineIsNonNegativeSmi:
+      return BuildGraphFor_IsNonNegativeSmi(arguments);
+    case Runtime::kInlineIsArray:
+      return BuildMapCheck(arguments[0], arguments[2], JS_ARRAY_TYPE);
+    case Runtime::kInlineIsRegExp:
+      return BuildMapCheck(arguments[0], arguments[2], JS_REGEXP_TYPE);
+    case Runtime::kInlineIsFunction:
+      return BuildMapCheck(arguments[0], arguments[2], JS_FUNCTION_TYPE);
+    case Runtime::kInlineValueOf:
+      return BuildGraphFor_ValueOf(arguments);
+    default:
+      break;
+  }
+  return ResultAndEffect();
+}
+
+ResultAndEffect JSIntrinsicBuilder::BuildGraphFor_IsSmi(
+    const NodeVector& arguments) {
+  Node* object = arguments[0];
+  SimplifiedOperatorBuilder simplified(jsgraph_->zone());
+  Node* condition = graph()->NewNode(simplified.ObjectIsSmi(), object);
+
+  return ResultAndEffect(condition, arguments[2]);
+}
+
+
+ResultAndEffect JSIntrinsicBuilder::BuildGraphFor_IsNonNegativeSmi(
+    const NodeVector& arguments) {
+  Node* object = arguments[0];
+  SimplifiedOperatorBuilder simplified(jsgraph_->zone());
+  Node* condition =
+      graph()->NewNode(simplified.ObjectIsNonNegativeSmi(), object);
+
+  return ResultAndEffect(condition, arguments[2]);
+}
+
+
+/*
+ * if (_isSmi(object)) {
+ *   return false
+ * } else {
+ *   return %_GetMapInstanceType(object) == map_type
+ * }
+ */
+ResultAndEffect JSIntrinsicBuilder::BuildMapCheck(Node* object, Node* effect,
+                                                  InstanceType map_type) {
+  SimplifiedOperatorBuilder simplified(jsgraph_->zone());
+
+  Node* is_smi = graph()->NewNode(simplified.ObjectIsSmi(), object);
+  Diamond d(graph(), common(), is_smi);
+
+  Node* map = graph()->NewNode(simplified.LoadField(AccessBuilder::ForMap()),
+                               object, effect, d.if_false);
+
+  Node* instance_type = graph()->NewNode(
+      simplified.LoadField(AccessBuilder::ForMapInstanceType()), map, map,
+      d.if_false);
+
+  Node* has_map_type =
+      graph()->NewNode(jsgraph_->machine()->Word32Equal(), instance_type,
+                       jsgraph_->Int32Constant(map_type));
+
+  Node* phi = d.Phi(static_cast<MachineType>(kTypeBool | kRepTagged),
+                    jsgraph_->FalseConstant(), has_map_type);
+
+  Node* ephi = d.EffectPhi(effect, instance_type);
+
+  return ResultAndEffect(phi, ephi);
+}
+
+
+/*
+ * if (%_isSmi(object)) {
+ *   return object;
+ * } else if (%_GetMapInstanceType(object) == JS_VALUE_TYPE) {
+ *   return %_LoadValueField(object);
+ * } else {
+ *   return object;
+ * }
+ */
+ResultAndEffect JSIntrinsicBuilder::BuildGraphFor_ValueOf(
+    const NodeVector& arguments) {
+  Node* object = arguments[0];
+  Node* effect = arguments[2];
+  SimplifiedOperatorBuilder simplified(jsgraph_->zone());
+
+  Node* is_smi = graph()->NewNode(simplified.ObjectIsSmi(), object);
+
+  Diamond if_is_smi(graph(), common(), is_smi);
+
+  Node* map = graph()->NewNode(simplified.LoadField(AccessBuilder::ForMap()),
+                               object, effect, if_is_smi.if_false);
+
+  Node* instance_type = graph()->NewNode(
+      simplified.LoadField(AccessBuilder::ForMapInstanceType()), map, map,
+      if_is_smi.if_false);
+
+  Node* is_value =
+      graph()->NewNode(jsgraph_->machine()->Word32Equal(), instance_type,
+                       jsgraph_->Constant(JS_VALUE_TYPE));
+
+  Diamond if_is_value(graph(), common(), is_value);
+  if_is_value.Nest(if_is_smi, false);
+
+  Node* value =
+      graph()->NewNode(simplified.LoadField(AccessBuilder::ForValue()), object,
+                       instance_type, if_is_value.if_true);
+
+  Node* phi_is_value = if_is_value.Phi(kTypeAny, value, object);
+
+  Node* phi = if_is_smi.Phi(kTypeAny, object, phi_is_value);
+
+  Node* ephi = if_is_smi.EffectPhi(effect, instance_type);
+
+  return ResultAndEffect(phi, ephi);
+}
+}
+}
+}  // namespace v8::internal::compiler
diff --git a/src/compiler/js-intrinsic-builder.h b/src/compiler/js-intrinsic-builder.h
new file mode 100644
index 0000000..9336be6
--- /dev/null
+++ b/src/compiler/js-intrinsic-builder.h
@@ -0,0 +1,40 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_JS_INTRINSIC_BUILDER_H_
+#define V8_COMPILER_JS_INTRINSIC_BUILDER_H_
+
+#include "src/compiler/js-graph.h"
+#include "src/v8.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+typedef std::pair<Node*, Node*> ResultAndEffect;
+
+class JSIntrinsicBuilder {
+ public:
+  explicit JSIntrinsicBuilder(JSGraph* jsgraph) : jsgraph_(jsgraph) {}
+
+  ResultAndEffect BuildGraphFor(Runtime::FunctionId id,
+                                const NodeVector& arguments);
+
+ private:
+  ResultAndEffect BuildMapCheck(Node* object, Node* effect,
+                                InstanceType map_type);
+  ResultAndEffect BuildGraphFor_IsSmi(const NodeVector& arguments);
+  ResultAndEffect BuildGraphFor_IsNonNegativeSmi(const NodeVector& arguments);
+  ResultAndEffect BuildGraphFor_ValueOf(const NodeVector& arguments);
+
+
+  Graph* graph() const { return jsgraph_->graph(); }
+  CommonOperatorBuilder* common() const { return jsgraph_->common(); }
+  JSGraph* jsgraph_;
+};
+}
+}
+}  // namespace v8::internal::compiler
+
+#endif  // V8_COMPILER_JS_INTRINSIC_BUILDER_H_
diff --git a/src/compiler/js-operator.cc b/src/compiler/js-operator.cc
new file mode 100644
index 0000000..aa76a3b
--- /dev/null
+++ b/src/compiler/js-operator.cc
@@ -0,0 +1,411 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/js-operator.h"
+
+#include <limits>
+
+#include "src/base/lazy-instance.h"
+#include "src/compiler/opcodes.h"
+#include "src/compiler/operator.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+bool operator==(CallFunctionParameters const& lhs,
+                CallFunctionParameters const& rhs) {
+  return lhs.arity() == rhs.arity() && lhs.flags() == rhs.flags();
+}
+
+
+bool operator!=(CallFunctionParameters const& lhs,
+                CallFunctionParameters const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(CallFunctionParameters const& p) {
+  return base::hash_combine(p.arity(), p.flags());
+}
+
+
+std::ostream& operator<<(std::ostream& os, CallFunctionParameters const& p) {
+  return os << p.arity() << ", " << p.flags();
+}
+
+
+const CallFunctionParameters& CallFunctionParametersOf(const Operator* op) {
+  DCHECK_EQ(IrOpcode::kJSCallFunction, op->opcode());
+  return OpParameter<CallFunctionParameters>(op);
+}
+
+
+bool operator==(CallRuntimeParameters const& lhs,
+                CallRuntimeParameters const& rhs) {
+  return lhs.id() == rhs.id() && lhs.arity() == rhs.arity();
+}
+
+
+bool operator!=(CallRuntimeParameters const& lhs,
+                CallRuntimeParameters const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(CallRuntimeParameters const& p) {
+  return base::hash_combine(p.id(), p.arity());
+}
+
+
+std::ostream& operator<<(std::ostream& os, CallRuntimeParameters const& p) {
+  return os << p.id() << ", " << p.arity();
+}
+
+
+const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op) {
+  DCHECK_EQ(IrOpcode::kJSCallRuntime, op->opcode());
+  return OpParameter<CallRuntimeParameters>(op);
+}
+
+
+ContextAccess::ContextAccess(size_t depth, size_t index, bool immutable)
+    : immutable_(immutable),
+      depth_(static_cast<uint16_t>(depth)),
+      index_(static_cast<uint32_t>(index)) {
+  DCHECK(depth <= std::numeric_limits<uint16_t>::max());
+  DCHECK(index <= std::numeric_limits<uint32_t>::max());
+}
+
+
+bool operator==(ContextAccess const& lhs, ContextAccess const& rhs) {
+  return lhs.depth() == rhs.depth() && lhs.index() == rhs.index() &&
+         lhs.immutable() == rhs.immutable();
+}
+
+
+bool operator!=(ContextAccess const& lhs, ContextAccess const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(ContextAccess const& access) {
+  return base::hash_combine(access.depth(), access.index(), access.immutable());
+}
+
+
+std::ostream& operator<<(std::ostream& os, ContextAccess const& access) {
+  return os << access.depth() << ", " << access.index() << ", "
+            << access.immutable();
+}
+
+
+ContextAccess const& ContextAccessOf(Operator const* op) {
+  DCHECK(op->opcode() == IrOpcode::kJSLoadContext ||
+         op->opcode() == IrOpcode::kJSStoreContext);
+  return OpParameter<ContextAccess>(op);
+}
+
+
+bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
+  return lhs.slot().ToInt() == rhs.slot().ToInt() &&
+         lhs.vector().is_identical_to(rhs.vector());
+}
+
+
+size_t hash_value(VectorSlotPair const& p) {
+  // TODO(mvstanton): include the vector in the hash.
+  base::hash<int> h;
+  return h(p.slot().ToInt());
+}
+
+
+bool operator==(LoadNamedParameters const& lhs,
+                LoadNamedParameters const& rhs) {
+  return lhs.name() == rhs.name() &&
+         lhs.contextual_mode() == rhs.contextual_mode() &&
+         lhs.feedback() == rhs.feedback();
+}
+
+
+bool operator!=(LoadNamedParameters const& lhs,
+                LoadNamedParameters const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(LoadNamedParameters const& p) {
+  return base::hash_combine(p.name(), p.contextual_mode(), p.feedback());
+}
+
+
+std::ostream& operator<<(std::ostream& os, LoadNamedParameters const& p) {
+  return os << Brief(*p.name().handle()) << ", " << p.contextual_mode();
+}
+
+
+std::ostream& operator<<(std::ostream& os, LoadPropertyParameters const& p) {
+  // Nothing special to print.
+  return os;
+}
+
+
+bool operator==(LoadPropertyParameters const& lhs,
+                LoadPropertyParameters const& rhs) {
+  return lhs.feedback() == rhs.feedback();
+}
+
+
+bool operator!=(LoadPropertyParameters const& lhs,
+                LoadPropertyParameters const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+const LoadPropertyParameters& LoadPropertyParametersOf(const Operator* op) {
+  DCHECK_EQ(IrOpcode::kJSLoadProperty, op->opcode());
+  return OpParameter<LoadPropertyParameters>(op);
+}
+
+
+size_t hash_value(LoadPropertyParameters const& p) {
+  return hash_value(p.feedback());
+}
+
+
+const LoadNamedParameters& LoadNamedParametersOf(const Operator* op) {
+  DCHECK_EQ(IrOpcode::kJSLoadNamed, op->opcode());
+  return OpParameter<LoadNamedParameters>(op);
+}
+
+
+bool operator==(StoreNamedParameters const& lhs,
+                StoreNamedParameters const& rhs) {
+  return lhs.strict_mode() == rhs.strict_mode() && lhs.name() == rhs.name();
+}
+
+
+bool operator!=(StoreNamedParameters const& lhs,
+                StoreNamedParameters const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(StoreNamedParameters const& p) {
+  return base::hash_combine(p.strict_mode(), p.name());
+}
+
+
+std::ostream& operator<<(std::ostream& os, StoreNamedParameters const& p) {
+  return os << p.strict_mode() << ", " << Brief(*p.name().handle());
+}
+
+
+const StoreNamedParameters& StoreNamedParametersOf(const Operator* op) {
+  DCHECK_EQ(IrOpcode::kJSStoreNamed, op->opcode());
+  return OpParameter<StoreNamedParameters>(op);
+}
+
+
+#define CACHED_OP_LIST(V)                                 \
+  V(Equal, Operator::kNoProperties, 2, 1)                 \
+  V(NotEqual, Operator::kNoProperties, 2, 1)              \
+  V(StrictEqual, Operator::kPure, 2, 1)                   \
+  V(StrictNotEqual, Operator::kPure, 2, 1)                \
+  V(LessThan, Operator::kNoProperties, 2, 1)              \
+  V(GreaterThan, Operator::kNoProperties, 2, 1)           \
+  V(LessThanOrEqual, Operator::kNoProperties, 2, 1)       \
+  V(GreaterThanOrEqual, Operator::kNoProperties, 2, 1)    \
+  V(BitwiseOr, Operator::kNoProperties, 2, 1)             \
+  V(BitwiseXor, Operator::kNoProperties, 2, 1)            \
+  V(BitwiseAnd, Operator::kNoProperties, 2, 1)            \
+  V(ShiftLeft, Operator::kNoProperties, 2, 1)             \
+  V(ShiftRight, Operator::kNoProperties, 2, 1)            \
+  V(ShiftRightLogical, Operator::kNoProperties, 2, 1)     \
+  V(Add, Operator::kNoProperties, 2, 1)                   \
+  V(Subtract, Operator::kNoProperties, 2, 1)              \
+  V(Multiply, Operator::kNoProperties, 2, 1)              \
+  V(Divide, Operator::kNoProperties, 2, 1)                \
+  V(Modulus, Operator::kNoProperties, 2, 1)               \
+  V(UnaryNot, Operator::kPure, 1, 1)                      \
+  V(ToBoolean, Operator::kPure, 1, 1)                     \
+  V(ToNumber, Operator::kNoProperties, 1, 1)              \
+  V(ToString, Operator::kNoProperties, 1, 1)              \
+  V(ToName, Operator::kNoProperties, 1, 1)                \
+  V(ToObject, Operator::kNoProperties, 1, 1)              \
+  V(Yield, Operator::kNoProperties, 1, 1)                 \
+  V(Create, Operator::kEliminatable, 0, 1)                \
+  V(HasProperty, Operator::kNoProperties, 2, 1)           \
+  V(TypeOf, Operator::kPure, 1, 1)                        \
+  V(InstanceOf, Operator::kNoProperties, 2, 1)            \
+  V(Debugger, Operator::kNoProperties, 0, 0)              \
+  V(CreateFunctionContext, Operator::kNoProperties, 1, 1) \
+  V(CreateWithContext, Operator::kNoProperties, 2, 1)     \
+  V(CreateBlockContext, Operator::kNoProperties, 2, 1)    \
+  V(CreateModuleContext, Operator::kNoProperties, 2, 1)   \
+  V(CreateScriptContext, Operator::kNoProperties, 2, 1)
+
+
+struct JSOperatorGlobalCache FINAL {
+#define CACHED(Name, properties, value_input_count, value_output_count)  \
+  struct Name##Operator FINAL : public Operator {                        \
+    Name##Operator()                                                     \
+        : Operator(IrOpcode::kJS##Name, properties, "JS" #Name,          \
+                   value_input_count, Operator::ZeroIfPure(properties),  \
+                   Operator::ZeroIfPure(properties), value_output_count, \
+                   Operator::ZeroIfPure(properties), 0) {}               \
+  };                                                                     \
+  Name##Operator k##Name##Operator;
+  CACHED_OP_LIST(CACHED)
+#undef CACHED
+
+  template <StrictMode kStrictMode>
+  struct StorePropertyOperator FINAL : public Operator1<StrictMode> {
+    StorePropertyOperator()
+        : Operator1<StrictMode>(IrOpcode::kJSStoreProperty,
+                                Operator::kNoProperties, "JSStoreProperty", 3,
+                                1, 1, 0, 1, 0, kStrictMode) {}
+  };
+  StorePropertyOperator<SLOPPY> kStorePropertySloppyOperator;
+  StorePropertyOperator<STRICT> kStorePropertyStrictOperator;
+};
+
+
+static base::LazyInstance<JSOperatorGlobalCache>::type kCache =
+    LAZY_INSTANCE_INITIALIZER;
+
+
+JSOperatorBuilder::JSOperatorBuilder(Zone* zone)
+    : cache_(kCache.Get()), zone_(zone) {}
+
+
+#define CACHED(Name, properties, value_input_count, value_output_count) \
+  const Operator* JSOperatorBuilder::Name() {                           \
+    return &cache_.k##Name##Operator;                                   \
+  }
+CACHED_OP_LIST(CACHED)
+#undef CACHED
+
+
+const Operator* JSOperatorBuilder::CallFunction(size_t arity,
+                                                CallFunctionFlags flags) {
+  CallFunctionParameters parameters(arity, flags);
+  return new (zone()) Operator1<CallFunctionParameters>(   // --
+      IrOpcode::kJSCallFunction, Operator::kNoProperties,  // opcode
+      "JSCallFunction",                                    // name
+      parameters.arity(), 1, 1, 1, 1, 0,                   // inputs/outputs
+      parameters);                                         // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CallRuntime(Runtime::FunctionId id,
+                                               size_t arity) {
+  CallRuntimeParameters parameters(id, arity);
+  const Runtime::Function* f = Runtime::FunctionForId(parameters.id());
+  DCHECK(f->nargs == -1 || f->nargs == static_cast<int>(parameters.arity()));
+  return new (zone()) Operator1<CallRuntimeParameters>(   // --
+      IrOpcode::kJSCallRuntime, Operator::kNoProperties,  // opcode
+      "JSCallRuntime",                                    // name
+      parameters.arity(), 1, 1, f->result_size, 1, 0,     // inputs/outputs
+      parameters);                                        // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CallConstruct(int arguments) {
+  return new (zone()) Operator1<int>(                       // --
+      IrOpcode::kJSCallConstruct, Operator::kNoProperties,  // opcode
+      "JSCallConstruct",                                    // name
+      arguments, 1, 1, 1, 1, 0,                             // counts
+      arguments);                                           // parameter
+}
+
+
+const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name,
+                                             const VectorSlotPair& feedback,
+                                             ContextualMode contextual_mode) {
+  LoadNamedParameters parameters(name, feedback, contextual_mode);
+  return new (zone()) Operator1<LoadNamedParameters>(   // --
+      IrOpcode::kJSLoadNamed, Operator::kNoProperties,  // opcode
+      "JSLoadNamed",                                    // name
+      1, 1, 1, 1, 1, 0,                                 // counts
+      parameters);                                      // parameter
+}
+
+
+const Operator* JSOperatorBuilder::LoadProperty(
+    const VectorSlotPair& feedback) {
+  LoadPropertyParameters parameters(feedback);
+  return new (zone()) Operator1<LoadPropertyParameters>(   // --
+      IrOpcode::kJSLoadProperty, Operator::kNoProperties,  // opcode
+      "JSLoadProperty",                                    // name
+      2, 1, 1, 1, 1, 0,                                    // counts
+      parameters);                                         // parameter
+}
+
+
+const Operator* JSOperatorBuilder::StoreProperty(StrictMode strict_mode) {
+  switch (strict_mode) {
+    case SLOPPY:
+      return &cache_.kStorePropertySloppyOperator;
+    case STRICT:
+      return &cache_.kStorePropertyStrictOperator;
+  }
+  UNREACHABLE();
+  return nullptr;
+}
+
+
+const Operator* JSOperatorBuilder::StoreNamed(StrictMode strict_mode,
+                                              const Unique<Name>& name) {
+  StoreNamedParameters parameters(strict_mode, name);
+  return new (zone()) Operator1<StoreNamedParameters>(   // --
+      IrOpcode::kJSStoreNamed, Operator::kNoProperties,  // opcode
+      "JSStoreNamed",                                    // name
+      2, 1, 1, 0, 1, 0,                                  // counts
+      parameters);                                       // parameter
+}
+
+
+const Operator* JSOperatorBuilder::DeleteProperty(StrictMode strict_mode) {
+  return new (zone()) Operator1<StrictMode>(                 // --
+      IrOpcode::kJSDeleteProperty, Operator::kNoProperties,  // opcode
+      "JSDeleteProperty",                                    // name
+      2, 1, 1, 1, 1, 0,                                      // counts
+      strict_mode);                                          // parameter
+}
+
+
+const Operator* JSOperatorBuilder::LoadContext(size_t depth, size_t index,
+                                               bool immutable) {
+  ContextAccess access(depth, index, immutable);
+  return new (zone()) Operator1<ContextAccess>(      // --
+      IrOpcode::kJSLoadContext, Operator::kNoWrite,  // opcode
+      "JSLoadContext",                               // name
+      1, 1, 0, 1, 1, 0,                              // counts
+      access);                                       // parameter
+}
+
+
+const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
+  ContextAccess access(depth, index, false);
+  return new (zone()) Operator1<ContextAccess>(      // --
+      IrOpcode::kJSStoreContext, Operator::kNoRead,  // opcode
+      "JSStoreContext",                              // name
+      2, 1, 1, 0, 1, 0,                              // counts
+      access);                                       // parameter
+}
+
+
+const Operator* JSOperatorBuilder::CreateCatchContext(
+    const Unique<String>& name) {
+  return new (zone()) Operator1<Unique<String>>(                 // --
+      IrOpcode::kJSCreateCatchContext, Operator::kNoProperties,  // opcode
+      "JSCreateCatchContext",                                    // name
+      1, 1, 1, 1, 1, 0,                                          // counts
+      name);                                                     // parameter
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/js-operator.h b/src/compiler/js-operator.h
index b95467f..e716a8e 100644
--- a/src/compiler/js-operator.h
+++ b/src/compiler/js-operator.h
@@ -5,28 +5,77 @@
 #ifndef V8_COMPILER_JS_OPERATOR_H_
 #define V8_COMPILER_JS_OPERATOR_H_
 
-#include "src/compiler/linkage.h"
-#include "src/compiler/opcodes.h"
-#include "src/compiler/operator.h"
+#include "src/runtime/runtime.h"
 #include "src/unique.h"
-#include "src/zone.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+// Forward declarations.
+class Operator;
+struct JSOperatorGlobalCache;
+
+
+// Defines the arity and the call flags for a JavaScript function call. This is
+// used as a parameter by JSCallFunction operators.
+class CallFunctionParameters FINAL {
+ public:
+  CallFunctionParameters(size_t arity, CallFunctionFlags flags)
+      : arity_(arity), flags_(flags) {}
+
+  size_t arity() const { return arity_; }
+  CallFunctionFlags flags() const { return flags_; }
+
+ private:
+  const size_t arity_;
+  const CallFunctionFlags flags_;
+};
+
+bool operator==(CallFunctionParameters const&, CallFunctionParameters const&);
+bool operator!=(CallFunctionParameters const&, CallFunctionParameters const&);
+
+size_t hash_value(CallFunctionParameters const&);
+
+std::ostream& operator<<(std::ostream&, CallFunctionParameters const&);
+
+const CallFunctionParameters& CallFunctionParametersOf(const Operator* op);
+
+
+// Defines the arity and the ID for a runtime function call. This is used as a
+// parameter by JSCallRuntime operators.
+class CallRuntimeParameters FINAL {
+ public:
+  CallRuntimeParameters(Runtime::FunctionId id, size_t arity)
+      : id_(id), arity_(arity) {}
+
+  Runtime::FunctionId id() const { return id_; }
+  size_t arity() const { return arity_; }
+
+ private:
+  const Runtime::FunctionId id_;
+  const size_t arity_;
+};
+
+bool operator==(CallRuntimeParameters const&, CallRuntimeParameters const&);
+bool operator!=(CallRuntimeParameters const&, CallRuntimeParameters const&);
+
+size_t hash_value(CallRuntimeParameters const&);
+
+std::ostream& operator<<(std::ostream&, CallRuntimeParameters const&);
+
+const CallRuntimeParameters& CallRuntimeParametersOf(const Operator* op);
+
+
 // Defines the location of a context slot relative to a specific scope. This is
 // used as a parameter by JSLoadContext and JSStoreContext operators and allows
 // accessing a context-allocated variable without keeping track of the scope.
-class ContextAccess {
+class ContextAccess FINAL {
  public:
-  ContextAccess(int depth, int index, bool immutable)
-      : immutable_(immutable), depth_(depth), index_(index) {
-    DCHECK(0 <= depth && depth <= kMaxUInt16);
-    DCHECK(0 <= index && static_cast<uint32_t>(index) <= kMaxUInt32);
-  }
-  int depth() const { return depth_; }
-  int index() const { return index_; }
+  ContextAccess(size_t depth, size_t index, bool immutable);
+
+  size_t depth() const { return depth_; }
+  size_t index() const { return index_; }
   bool immutable() const { return immutable_; }
 
  private:
@@ -37,193 +86,188 @@
   const uint32_t index_;
 };
 
-// Defines the property being loaded from an object by a named load. This is
-// used as a parameter by JSLoadNamed operators.
-struct LoadNamedParameters {
-  Unique<Name> name;
-  ContextualMode contextual_mode;
+bool operator==(ContextAccess const&, ContextAccess const&);
+bool operator!=(ContextAccess const&, ContextAccess const&);
+
+size_t hash_value(ContextAccess const&);
+
+std::ostream& operator<<(std::ostream&, ContextAccess const&);
+
+ContextAccess const& ContextAccessOf(Operator const*);
+
+
+class VectorSlotPair {
+ public:
+  VectorSlotPair(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
+      : vector_(vector), slot_(slot) {}
+
+  Handle<TypeFeedbackVector> vector() const { return vector_; }
+  FeedbackVectorICSlot slot() const { return slot_; }
+
+  int index() const { return vector_->GetIndex(slot_); }
+
+ private:
+  const Handle<TypeFeedbackVector> vector_;
+  const FeedbackVectorICSlot slot_;
 };
 
-// Defines the arity and the call flags for a JavaScript function call. This is
-// used as a parameter by JSCall operators.
-struct CallParameters {
-  int arity;
-  CallFunctionFlags flags;
+
+bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs);
+
+
+// Defines the property being loaded from an object by a named load. This is
+// used as a parameter by JSLoadNamed operators.
+class LoadNamedParameters FINAL {
+ public:
+  LoadNamedParameters(const Unique<Name>& name, const VectorSlotPair& feedback,
+                      ContextualMode contextual_mode)
+      : name_(name), contextual_mode_(contextual_mode), feedback_(feedback) {}
+
+  const Unique<Name>& name() const { return name_; }
+  ContextualMode contextual_mode() const { return contextual_mode_; }
+
+  const VectorSlotPair& feedback() const { return feedback_; }
+
+ private:
+  const Unique<Name> name_;
+  const ContextualMode contextual_mode_;
+  const VectorSlotPair feedback_;
 };
 
+bool operator==(LoadNamedParameters const&, LoadNamedParameters const&);
+bool operator!=(LoadNamedParameters const&, LoadNamedParameters const&);
+
+size_t hash_value(LoadNamedParameters const&);
+
+std::ostream& operator<<(std::ostream&, LoadNamedParameters const&);
+
+const LoadNamedParameters& LoadNamedParametersOf(const Operator* op);
+
+
+// Defines the property being loaded from an object. This is
+// used as a parameter by JSLoadProperty operators.
+class LoadPropertyParameters FINAL {
+ public:
+  explicit LoadPropertyParameters(const VectorSlotPair& feedback)
+      : feedback_(feedback) {}
+
+  const VectorSlotPair& feedback() const { return feedback_; }
+
+ private:
+  const VectorSlotPair feedback_;
+};
+
+bool operator==(LoadPropertyParameters const&, LoadPropertyParameters const&);
+bool operator!=(LoadPropertyParameters const&, LoadPropertyParameters const&);
+
+size_t hash_value(LoadPropertyParameters const&);
+
+std::ostream& operator<<(std::ostream&, LoadPropertyParameters const&);
+
+const LoadPropertyParameters& LoadPropertyParametersOf(const Operator* op);
+
+
 // Defines the property being stored to an object by a named store. This is
 // used as a parameter by JSStoreNamed operators.
-struct StoreNamedParameters {
-  StrictMode strict_mode;
-  Unique<Name> name;
+class StoreNamedParameters FINAL {
+ public:
+  StoreNamedParameters(StrictMode strict_mode, const Unique<Name>& name)
+      : strict_mode_(strict_mode), name_(name) {}
+
+  StrictMode strict_mode() const { return strict_mode_; }
+  const Unique<Name>& name() const { return name_; }
+
+ private:
+  const StrictMode strict_mode_;
+  const Unique<Name> name_;
 };
 
+bool operator==(StoreNamedParameters const&, StoreNamedParameters const&);
+bool operator!=(StoreNamedParameters const&, StoreNamedParameters const&);
+
+size_t hash_value(StoreNamedParameters const&);
+
+std::ostream& operator<<(std::ostream&, StoreNamedParameters const&);
+
+const StoreNamedParameters& StoreNamedParametersOf(const Operator* op);
+
+
 // Interface for building JavaScript-level operators, e.g. directly from the
 // AST. Most operators have no parameters, thus can be globally shared for all
 // graphs.
-class JSOperatorBuilder {
+class JSOperatorBuilder FINAL : public ZoneObject {
  public:
-  explicit JSOperatorBuilder(Zone* zone) : zone_(zone) {}
+  explicit JSOperatorBuilder(Zone* zone);
 
-#define SIMPLE(name, properties, inputs, outputs) \
-  return new (zone_)                              \
-      SimpleOperator(IrOpcode::k##name, properties, inputs, outputs, #name);
+  const Operator* Equal();
+  const Operator* NotEqual();
+  const Operator* StrictEqual();
+  const Operator* StrictNotEqual();
+  const Operator* LessThan();
+  const Operator* GreaterThan();
+  const Operator* LessThanOrEqual();
+  const Operator* GreaterThanOrEqual();
+  const Operator* BitwiseOr();
+  const Operator* BitwiseXor();
+  const Operator* BitwiseAnd();
+  const Operator* ShiftLeft();
+  const Operator* ShiftRight();
+  const Operator* ShiftRightLogical();
+  const Operator* Add();
+  const Operator* Subtract();
+  const Operator* Multiply();
+  const Operator* Divide();
+  const Operator* Modulus();
 
-#define NOPROPS(name, inputs, outputs) \
-  SIMPLE(name, Operator::kNoProperties, inputs, outputs)
+  const Operator* UnaryNot();
+  const Operator* ToBoolean();
+  const Operator* ToNumber();
+  const Operator* ToString();
+  const Operator* ToName();
+  const Operator* ToObject();
+  const Operator* Yield();
 
-#define OP1(name, ptype, pname, properties, inputs, outputs)                 \
-  return new (zone_) Operator1<ptype>(IrOpcode::k##name, properties, inputs, \
-                                      outputs, #name, pname)
+  const Operator* Create();
 
-#define BINOP(name) NOPROPS(name, 2, 1)
-#define UNOP(name) NOPROPS(name, 1, 1)
+  const Operator* CallFunction(size_t arity, CallFunctionFlags flags);
+  const Operator* CallRuntime(Runtime::FunctionId id, size_t arity);
 
-#define PURE_BINOP(name) SIMPLE(name, Operator::kPure, 2, 1)
+  const Operator* CallConstruct(int arguments);
 
-  const Operator* Equal() { BINOP(JSEqual); }
-  const Operator* NotEqual() { BINOP(JSNotEqual); }
-  const Operator* StrictEqual() { PURE_BINOP(JSStrictEqual); }
-  const Operator* StrictNotEqual() { PURE_BINOP(JSStrictNotEqual); }
-  const Operator* LessThan() { BINOP(JSLessThan); }
-  const Operator* GreaterThan() { BINOP(JSGreaterThan); }
-  const Operator* LessThanOrEqual() { BINOP(JSLessThanOrEqual); }
-  const Operator* GreaterThanOrEqual() { BINOP(JSGreaterThanOrEqual); }
-  const Operator* BitwiseOr() { BINOP(JSBitwiseOr); }
-  const Operator* BitwiseXor() { BINOP(JSBitwiseXor); }
-  const Operator* BitwiseAnd() { BINOP(JSBitwiseAnd); }
-  const Operator* ShiftLeft() { BINOP(JSShiftLeft); }
-  const Operator* ShiftRight() { BINOP(JSShiftRight); }
-  const Operator* ShiftRightLogical() { BINOP(JSShiftRightLogical); }
-  const Operator* Add() { BINOP(JSAdd); }
-  const Operator* Subtract() { BINOP(JSSubtract); }
-  const Operator* Multiply() { BINOP(JSMultiply); }
-  const Operator* Divide() { BINOP(JSDivide); }
-  const Operator* Modulus() { BINOP(JSModulus); }
+  const Operator* LoadProperty(const VectorSlotPair& feedback);
+  const Operator* LoadNamed(const Unique<Name>& name,
+                            const VectorSlotPair& feedback,
+                            ContextualMode contextual_mode = NOT_CONTEXTUAL);
 
-  const Operator* UnaryNot() { UNOP(JSUnaryNot); }
-  const Operator* ToBoolean() { UNOP(JSToBoolean); }
-  const Operator* ToNumber() { UNOP(JSToNumber); }
-  const Operator* ToString() { UNOP(JSToString); }
-  const Operator* ToName() { UNOP(JSToName); }
-  const Operator* ToObject() { UNOP(JSToObject); }
-  const Operator* Yield() { UNOP(JSYield); }
+  const Operator* StoreProperty(StrictMode strict_mode);
+  const Operator* StoreNamed(StrictMode strict_mode, const Unique<Name>& name);
 
-  const Operator* Create() { SIMPLE(JSCreate, Operator::kEliminatable, 0, 1); }
+  const Operator* DeleteProperty(StrictMode strict_mode);
 
-  const Operator* Call(int arguments, CallFunctionFlags flags) {
-    CallParameters parameters = {arguments, flags};
-    OP1(JSCallFunction, CallParameters, parameters, Operator::kNoProperties,
-        arguments, 1);
-  }
+  const Operator* HasProperty();
 
-  const Operator* CallNew(int arguments) {
-    return new (zone_)
-        Operator1<int>(IrOpcode::kJSCallConstruct, Operator::kNoProperties,
-                       arguments, 1, "JSCallConstruct", arguments);
-  }
+  const Operator* LoadContext(size_t depth, size_t index, bool immutable);
+  const Operator* StoreContext(size_t depth, size_t index);
 
-  const Operator* LoadProperty() { BINOP(JSLoadProperty); }
-  const Operator* LoadNamed(Unique<Name> name,
-                            ContextualMode contextual_mode = NOT_CONTEXTUAL) {
-    LoadNamedParameters parameters = {name, contextual_mode};
-    OP1(JSLoadNamed, LoadNamedParameters, parameters, Operator::kNoProperties,
-        1, 1);
-  }
-
-  const Operator* StoreProperty(StrictMode strict_mode) {
-    OP1(JSStoreProperty, StrictMode, strict_mode, Operator::kNoProperties, 3,
-        0);
-  }
-
-  const Operator* StoreNamed(StrictMode strict_mode, Unique<Name> name) {
-    StoreNamedParameters parameters = {strict_mode, name};
-    OP1(JSStoreNamed, StoreNamedParameters, parameters, Operator::kNoProperties,
-        2, 0);
-  }
-
-  const Operator* DeleteProperty(StrictMode strict_mode) {
-    OP1(JSDeleteProperty, StrictMode, strict_mode, Operator::kNoProperties, 2,
-        1);
-  }
-
-  const Operator* HasProperty() { NOPROPS(JSHasProperty, 2, 1); }
-
-  const Operator* LoadContext(uint16_t depth, uint32_t index, bool immutable) {
-    ContextAccess access(depth, index, immutable);
-    OP1(JSLoadContext, ContextAccess, access,
-        Operator::kEliminatable | Operator::kNoWrite, 1, 1);
-  }
-  const Operator* StoreContext(uint16_t depth, uint32_t index) {
-    ContextAccess access(depth, index, false);
-    OP1(JSStoreContext, ContextAccess, access, Operator::kNoProperties, 2, 0);
-  }
-
-  const Operator* TypeOf() { SIMPLE(JSTypeOf, Operator::kPure, 1, 1); }
-  const Operator* InstanceOf() { NOPROPS(JSInstanceOf, 2, 1); }
-  const Operator* Debugger() { NOPROPS(JSDebugger, 0, 0); }
+  const Operator* TypeOf();
+  const Operator* InstanceOf();
+  const Operator* Debugger();
 
   // TODO(titzer): nail down the static parts of each of these context flavors.
-  const Operator* CreateFunctionContext() {
-    NOPROPS(JSCreateFunctionContext, 1, 1);
-  }
-  const Operator* CreateCatchContext(Unique<String> name) {
-    OP1(JSCreateCatchContext, Unique<String>, name, Operator::kNoProperties, 1,
-        1);
-  }
-  const Operator* CreateWithContext() { NOPROPS(JSCreateWithContext, 2, 1); }
-  const Operator* CreateBlockContext() { NOPROPS(JSCreateBlockContext, 2, 1); }
-  const Operator* CreateModuleContext() {
-    NOPROPS(JSCreateModuleContext, 2, 1);
-  }
-  const Operator* CreateGlobalContext() {
-    NOPROPS(JSCreateGlobalContext, 2, 1);
-  }
-
-  const Operator* Runtime(Runtime::FunctionId function, int arguments) {
-    const Runtime::Function* f = Runtime::FunctionForId(function);
-    DCHECK(f->nargs == -1 || f->nargs == arguments);
-    OP1(JSCallRuntime, Runtime::FunctionId, function, Operator::kNoProperties,
-        arguments, f->result_size);
-  }
-
-#undef SIMPLE
-#undef NOPROPS
-#undef OP1
-#undef BINOP
-#undef UNOP
+  const Operator* CreateFunctionContext();
+  const Operator* CreateCatchContext(const Unique<String>& name);
+  const Operator* CreateWithContext();
+  const Operator* CreateBlockContext();
+  const Operator* CreateModuleContext();
+  const Operator* CreateScriptContext();
 
  private:
-  Zone* zone_;
-};
+  Zone* zone() const { return zone_; }
 
-// Specialization for static parameters of type {ContextAccess}.
-template <>
-struct StaticParameterTraits<ContextAccess> {
-  static OStream& PrintTo(OStream& os, ContextAccess val) {  // NOLINT
-    return os << val.depth() << "," << val.index()
-              << (val.immutable() ? ",imm" : "");
-  }
-  static int HashCode(ContextAccess val) {
-    return (val.depth() << 16) | (val.index() & 0xffff);
-  }
-  static bool Equals(ContextAccess a, ContextAccess b) {
-    return a.immutable() == b.immutable() && a.depth() == b.depth() &&
-           a.index() == b.index();
-  }
-};
+  const JSOperatorGlobalCache& cache_;
+  Zone* const zone_;
 
-// Specialization for static parameters of type {Runtime::FunctionId}.
-template <>
-struct StaticParameterTraits<Runtime::FunctionId> {
-  static OStream& PrintTo(OStream& os, Runtime::FunctionId val) {  // NOLINT
-    const Runtime::Function* f = Runtime::FunctionForId(val);
-    return os << (f->name ? f->name : "?Runtime?");
-  }
-  static int HashCode(Runtime::FunctionId val) { return static_cast<int>(val); }
-  static bool Equals(Runtime::FunctionId a, Runtime::FunctionId b) {
-    return a == b;
-  }
+  DISALLOW_COPY_AND_ASSIGN(JSOperatorBuilder);
 };
 
 }  // namespace compiler
diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc
index be12534..7618375 100644
--- a/src/compiler/js-typed-lowering.cc
+++ b/src/compiler/js-typed-lowering.cc
@@ -4,9 +4,10 @@
 
 #include "src/compiler/access-builder.h"
 #include "src/compiler/graph-inl.h"
-#include "src/compiler/js-builtin-reducer.h"
+#include "src/compiler/js-graph.h"
 #include "src/compiler/js-typed-lowering.h"
 #include "src/compiler/node-aux-data-inl.h"
+#include "src/compiler/node-matchers.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/types.h"
 
@@ -17,7 +18,6 @@
 // TODO(turbofan): js-typed-lowering improvements possible
 // - immediately put in type bounds for all new nodes
 // - relax effects from generic but not-side-effecting operations
-// - relax effects for ToNumber(mixed)
 
 
 // Relax the effects of {node} by immediately replacing effect uses of {node}
@@ -29,7 +29,32 @@
 }
 
 
-JSTypedLowering::~JSTypedLowering() {}
+JSTypedLowering::JSTypedLowering(JSGraph* jsgraph, Zone* zone)
+    : jsgraph_(jsgraph), simplified_(graph()->zone()), conversions_(zone) {
+  Handle<Object> zero = factory()->NewNumber(0.0);
+  Handle<Object> one = factory()->NewNumber(1.0);
+  zero_range_ = Type::Range(zero, zero, graph()->zone());
+  one_range_ = Type::Range(one, one, graph()->zone());
+  Handle<Object> thirtyone = factory()->NewNumber(31.0);
+  zero_thirtyone_range_ = Type::Range(zero, thirtyone, graph()->zone());
+  // TODO(jarin): Can we have a correctification of the stupid type system?
+  // These stupid work-arounds are just stupid!
+  shifted_int32_ranges_[0] = Type::Signed32();
+  if (SmiValuesAre31Bits()) {
+    shifted_int32_ranges_[1] = Type::SignedSmall();
+    for (size_t k = 2; k < arraysize(shifted_int32_ranges_); ++k) {
+      Handle<Object> min = factory()->NewNumber(kMinInt / (1 << k));
+      Handle<Object> max = factory()->NewNumber(kMaxInt / (1 << k));
+      shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
+    }
+  } else {
+    for (size_t k = 1; k < arraysize(shifted_int32_ranges_); ++k) {
+      Handle<Object> min = factory()->NewNumber(kMinInt / (1 << k));
+      Handle<Object> max = factory()->NewNumber(kMaxInt / (1 << k));
+      shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone());
+    }
+  }
+}
 
 
 Reduction JSTypedLowering::ReplaceEagerly(Node* old, Node* node) {
@@ -42,7 +67,7 @@
 // JSOperator. This class manages the rewriting of context, control, and effect
 // dependencies during lowering of a binop and contains numerous helper
 // functions for matching the types of inputs to an operation.
-class JSBinopReduction {
+class JSBinopReduction FINAL {
  public:
   JSBinopReduction(JSTypedLowering* lowering, Node* node)
       : lowering_(lowering),
@@ -55,9 +80,10 @@
     node_->ReplaceInput(1, ConvertToNumber(right()));
   }
 
-  void ConvertInputsToInt32(bool left_signed, bool right_signed) {
-    node_->ReplaceInput(0, ConvertToI32(left_signed, left()));
-    node_->ReplaceInput(1, ConvertToI32(right_signed, right()));
+  void ConvertInputsToUI32(Signedness left_signedness,
+                           Signedness right_signedness) {
+    node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness));
+    node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness));
   }
 
   void ConvertInputsToString() {
@@ -66,11 +92,15 @@
   }
 
   // Convert inputs for bitwise shift operation (ES5 spec 11.7).
-  void ConvertInputsForShift(bool left_signed) {
-    node_->ReplaceInput(0, ConvertToI32(left_signed, left()));
-    Node* rnum = ConvertToI32(false, right());
-    node_->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rnum,
-                                            jsgraph()->Int32Constant(0x1F)));
+  void ConvertInputsForShift(Signedness left_signedness) {
+    node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness));
+    Node* rnum = ConvertToUI32(right(), kUnsigned);
+    Type* rnum_type = NodeProperties::GetBounds(rnum).upper;
+    if (!rnum_type->Is(lowering_->zero_thirtyone_range_)) {
+      rnum = graph()->NewNode(machine()->Word32And(), rnum,
+                              jsgraph()->Int32Constant(0x1F));
+    }
+    node_->ReplaceInput(1, rnum);
   }
 
   void SwapInputs() {
@@ -83,14 +113,15 @@
 
   // Remove all effect and control inputs and outputs to this node and change
   // to the pure operator {op}, possibly inserting a boolean inversion.
-  Reduction ChangeToPureOperator(const Operator* op, bool invert = false) {
-    DCHECK_EQ(0, OperatorProperties::GetEffectInputCount(op));
+  Reduction ChangeToPureOperator(const Operator* op, bool invert = false,
+                                 Type* type = Type::Any()) {
+    DCHECK_EQ(0, op->EffectInputCount());
     DCHECK_EQ(false, OperatorProperties::HasContextInput(op));
-    DCHECK_EQ(0, OperatorProperties::GetControlInputCount(op));
-    DCHECK_EQ(2, OperatorProperties::GetValueInputCount(op));
+    DCHECK_EQ(0, op->ControlInputCount());
+    DCHECK_EQ(2, op->ValueInputCount());
 
     // Remove the effects from the node, if any, and update its effect usages.
-    if (OperatorProperties::GetEffectInputCount(node_->op()) > 0) {
+    if (node_->op()->EffectInputCount() > 0) {
       RelaxEffects(node_);
     }
     // Remove the inputs corresponding to context, effect, and control.
@@ -98,17 +129,26 @@
     // Finally, update the operator to the new one.
     node_->set_op(op);
 
+    // TODO(jarin): Replace the explicit typing hack with a call to some method
+    // that encapsulates changing the operator and re-typing.
+    Bounds const bounds = NodeProperties::GetBounds(node_);
+    NodeProperties::SetBounds(node_, Bounds::NarrowUpper(bounds, type, zone()));
+
     if (invert) {
       // Insert an boolean not to invert the value.
       Node* value = graph()->NewNode(simplified()->BooleanNot(), node_);
       node_->ReplaceUses(value);
       // Note: ReplaceUses() smashes all uses, so smash it back here.
       value->ReplaceInput(0, node_);
-      return lowering_->ReplaceWith(value);
+      return lowering_->Replace(value);
     }
     return lowering_->Changed(node_);
   }
 
+  Reduction ChangeToPureOperator(const Operator* op, Type* type) {
+    return ChangeToPureOperator(op, false, type);
+  }
+
   bool OneInputIs(Type* t) { return left_type_->Is(t) || right_type_->Is(t); }
 
   bool BothInputsAre(Type* t) {
@@ -132,10 +172,11 @@
   Type* right_type() { return right_type_; }
 
   SimplifiedOperatorBuilder* simplified() { return lowering_->simplified(); }
-  Graph* graph() { return lowering_->graph(); }
+  Graph* graph() const { return lowering_->graph(); }
   JSGraph* jsgraph() { return lowering_->jsgraph(); }
   JSOperatorBuilder* javascript() { return lowering_->javascript(); }
   MachineOperatorBuilder* machine() { return lowering_->machine(); }
+  Zone* zone() const { return graph()->zone(); }
 
  private:
   JSTypedLowering* lowering_;  // The containing lowering instance.
@@ -154,65 +195,30 @@
   }
 
   Node* ConvertToNumber(Node* node) {
-    // Avoid introducing too many eager ToNumber() operations.
-    Reduction reduced = lowering_->ReduceJSToNumberInput(node);
-    if (reduced.Changed()) return reduced.replacement();
+    if (NodeProperties::GetBounds(node).upper->Is(Type::PlainPrimitive())) {
+      return lowering_->ConvertToNumber(node);
+    }
     Node* n = graph()->NewNode(javascript()->ToNumber(), node, context(),
                                effect(), control());
     update_effect(n);
     return n;
   }
 
-  // Try to narrowing a double or number operation to an Int32 operation.
-  bool TryNarrowingToI32(Type* type, Node* node) {
-    switch (node->opcode()) {
-      case IrOpcode::kFloat64Add:
-      case IrOpcode::kNumberAdd: {
-        JSBinopReduction r(lowering_, node);
-        if (r.BothInputsAre(Type::Integral32())) {
-          node->set_op(lowering_->machine()->Int32Add());
-          // TODO(titzer): narrow bounds instead of overwriting.
-          NodeProperties::SetBounds(node, Bounds(type));
-          return true;
-        }
-      }
-      case IrOpcode::kFloat64Sub:
-      case IrOpcode::kNumberSubtract: {
-        JSBinopReduction r(lowering_, node);
-        if (r.BothInputsAre(Type::Integral32())) {
-          node->set_op(lowering_->machine()->Int32Sub());
-          // TODO(titzer): narrow bounds instead of overwriting.
-          NodeProperties::SetBounds(node, Bounds(type));
-          return true;
-        }
-      }
-      default:
-        return false;
-    }
-  }
-
-  Node* ConvertToI32(bool is_signed, Node* node) {
-    Type* type = is_signed ? Type::Signed32() : Type::Unsigned32();
-    if (node->OwnedBy(node_)) {
-      // If this node {node_} has the only edge to {node}, then try narrowing
-      // its operation to an Int32 add or subtract.
-      if (TryNarrowingToI32(type, node)) return node;
-    } else {
-      // Otherwise, {node} has multiple uses. Leave it as is and let the
-      // further lowering passes deal with it, which use a full backwards
-      // fixpoint.
-    }
-
+  Node* ConvertToUI32(Node* node, Signedness signedness) {
     // Avoid introducing too many eager NumberToXXnt32() operations.
     node = ConvertToNumber(node);
-    Type* input_type = NodeProperties::GetBounds(node).upper;
-
-    if (input_type->Is(type)) return node;  // already in the value range.
-
-    const Operator* op = is_signed ? simplified()->NumberToInt32()
-                                   : simplified()->NumberToUint32();
-    Node* n = graph()->NewNode(op, node);
-    return n;
+    Type* type = NodeProperties::GetBounds(node).upper;
+    if (signedness == kSigned) {
+      if (!type->Is(Type::Signed32())) {
+        node = graph()->NewNode(simplified()->NumberToInt32(), node);
+      }
+    } else {
+      DCHECK_EQ(kUnsigned, signedness);
+      if (!type->Is(Type::Unsigned32())) {
+        node = graph()->NewNode(simplified()->NumberToUint32(), node);
+      }
+    }
+    return node;
   }
 
   void update_effect(Node* effect) {
@@ -225,15 +231,24 @@
   JSBinopReduction r(this, node);
   if (r.BothInputsAre(Type::Number())) {
     // JSAdd(x:number, y:number) => NumberAdd(x, y)
-    return r.ChangeToPureOperator(simplified()->NumberAdd());
+    return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
   }
-  Type* maybe_string = Type::Union(Type::String(), Type::Receiver(), zone());
-  if (r.NeitherInputCanBe(maybe_string)) {
+  if (r.BothInputsAre(Type::Primitive()) &&
+      r.NeitherInputCanBe(Type::StringOrReceiver())) {
     // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y))
     r.ConvertInputsToNumber();
-    return r.ChangeToPureOperator(simplified()->NumberAdd());
+    return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number());
   }
 #if 0
+  // TODO(turbofan): General ToNumber disabled for now because:
+  //   a) The inserted ToNumber operation screws up observability of valueOf.
+  //   b) Deoptimization at ToNumber doesn't have corresponding bailout id.
+  Type* maybe_string = Type::Union(Type::String(), Type::Receiver(), zone());
+  if (r.NeitherInputCanBe(maybe_string)) {
+    ...
+  }
+#endif
+#if 0
   // TODO(turbofan): Lowering of StringAdd is disabled for now because:
   //   a) The inserted ToString operation screws up valueOf vs. toString order.
   //   b) Deoptimization at ToString doesn't have corresponding bailout id.
@@ -250,9 +265,48 @@
 }
 
 
+Reduction JSTypedLowering::ReduceJSBitwiseOr(Node* node) {
+  JSBinopReduction r(this, node);
+  if (r.BothInputsAre(Type::Primitive()) || r.OneInputIs(zero_range_)) {
+    // TODO(jarin): Propagate frame state input from non-primitive input node to
+    // JSToNumber node.
+    // TODO(titzer): some Smi bitwise operations don't really require going
+    // all the way to int32, which can save tagging/untagging for some
+    // operations
+    // on some platforms.
+    // TODO(turbofan): make this heuristic configurable for code size.
+    r.ConvertInputsToUI32(kSigned, kSigned);
+    return r.ChangeToPureOperator(machine()->Word32Or(), Type::Integral32());
+  }
+  return NoChange();
+}
+
+
+Reduction JSTypedLowering::ReduceJSMultiply(Node* node) {
+  JSBinopReduction r(this, node);
+  if (r.BothInputsAre(Type::Primitive()) || r.OneInputIs(one_range_)) {
+    // TODO(jarin): Propagate frame state input from non-primitive input node to
+    // JSToNumber node.
+    r.ConvertInputsToNumber();
+    return r.ChangeToPureOperator(simplified()->NumberMultiply(),
+                                  Type::Number());
+  }
+  // TODO(turbofan): relax/remove the effects of this operator in other cases.
+  return NoChange();
+}
+
+
 Reduction JSTypedLowering::ReduceNumberBinop(Node* node,
                                              const Operator* numberOp) {
   JSBinopReduction r(this, node);
+  if (r.BothInputsAre(Type::Primitive())) {
+    r.ConvertInputsToNumber();
+    return r.ChangeToPureOperator(numberOp, Type::Number());
+  }
+#if 0
+  // TODO(turbofan): General ToNumber disabled for now because:
+  //   a) The inserted ToNumber operation screws up observability of valueOf.
+  //   b) Deoptimization at ToNumber doesn't have corresponding bailout id.
   if (r.OneInputIs(Type::Primitive())) {
     // If at least one input is a primitive, then insert appropriate conversions
     // to number and reduce this operator to the given numeric one.
@@ -260,29 +314,36 @@
     r.ConvertInputsToNumber();
     return r.ChangeToPureOperator(numberOp);
   }
+#endif
   // TODO(turbofan): relax/remove the effects of this operator in other cases.
   return NoChange();
 }
 
 
-Reduction JSTypedLowering::ReduceI32Binop(Node* node, bool left_signed,
-                                          bool right_signed,
-                                          const Operator* intOp) {
+Reduction JSTypedLowering::ReduceInt32Binop(Node* node, const Operator* intOp) {
   JSBinopReduction r(this, node);
-  // TODO(titzer): some Smi bitwise operations don't really require going
-  // all the way to int32, which can save tagging/untagging for some operations
-  // on some platforms.
-  // TODO(turbofan): make this heuristic configurable for code size.
-  r.ConvertInputsToInt32(left_signed, right_signed);
-  return r.ChangeToPureOperator(intOp);
+  if (r.BothInputsAre(Type::Primitive())) {
+    // TODO(titzer): some Smi bitwise operations don't really require going
+    // all the way to int32, which can save tagging/untagging for some
+    // operations
+    // on some platforms.
+    // TODO(turbofan): make this heuristic configurable for code size.
+    r.ConvertInputsToUI32(kSigned, kSigned);
+    return r.ChangeToPureOperator(intOp, Type::Integral32());
+  }
+  return NoChange();
 }
 
 
-Reduction JSTypedLowering::ReduceI32Shift(Node* node, bool left_signed,
-                                          const Operator* shift_op) {
+Reduction JSTypedLowering::ReduceUI32Shift(Node* node,
+                                           Signedness left_signedness,
+                                           const Operator* shift_op) {
   JSBinopReduction r(this, node);
-  r.ConvertInputsForShift(left_signed);
-  return r.ChangeToPureOperator(shift_op);
+  if (r.BothInputsAre(Type::Primitive())) {
+    r.ConvertInputsForShift(left_signedness);
+    return r.ChangeToPureOperator(shift_op, Type::Integral32());
+  }
+  return NoChange();
 }
 
 
@@ -311,9 +372,18 @@
     }
     return r.ChangeToPureOperator(stringOp);
   }
+#if 0
+  // TODO(turbofan): General ToNumber disabled for now because:
+  //   a) The inserted ToNumber operation screws up observability of valueOf.
+  //   b) Deoptimization at ToNumber doesn't have corresponding bailout id.
   Type* maybe_string = Type::Union(Type::String(), Type::Receiver(), zone());
   if (r.OneInputCannotBe(maybe_string)) {
     // If one input cannot be a string, then emit a number comparison.
+    ...
+  }
+#endif
+  if (r.BothInputsAre(Type::Primitive()) &&
+      r.OneInputCannotBe(Type::StringOrReceiver())) {
     const Operator* less_than;
     const Operator* less_than_or_equal;
     if (r.BothInputsAre(Type::Unsigned32())) {
@@ -379,16 +449,14 @@
   if (r.left() == r.right()) {
     // x === x is always true if x != NaN
     if (!r.left_type()->Maybe(Type::NaN())) {
-      return ReplaceEagerly(node, invert ? jsgraph()->FalseConstant()
-                                         : jsgraph()->TrueConstant());
+      return ReplaceEagerly(node, jsgraph()->BooleanConstant(!invert));
     }
   }
-  if (!r.left_type()->Maybe(r.right_type())) {
-    // Type intersection is empty; === is always false unless both
-    // inputs could be strings (one internalized and one not).
-    if (r.OneInputCannotBe(Type::String())) {
-      return ReplaceEagerly(node, invert ? jsgraph()->TrueConstant()
-                                         : jsgraph()->FalseConstant());
+  if (r.OneInputCannotBe(Type::NumberOrString())) {
+    // For values with canonical representation (i.e. not string nor number) an
+    // empty type intersection means the values cannot be strictly equal.
+    if (!r.left_type()->Maybe(r.right_type())) {
+      return ReplaceEagerly(node, jsgraph()->BooleanConstant(invert));
     }
   }
   if (r.OneInputIs(Type::Undefined())) {
@@ -422,16 +490,47 @@
 }
 
 
+Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) {
+  Node* input = node->InputAt(0);
+  Type* input_type = NodeProperties::GetBounds(input).upper;
+  if (input_type->Is(Type::Boolean())) {
+    // JSUnaryNot(x:boolean,context) => BooleanNot(x)
+    node->set_op(simplified()->BooleanNot());
+    node->TrimInputCount(1);
+    return Changed(node);
+  }
+  // JSUnaryNot(x,context) => BooleanNot(AnyToBoolean(x))
+  node->set_op(simplified()->BooleanNot());
+  node->ReplaceInput(0, graph()->NewNode(simplified()->AnyToBoolean(), input));
+  node->TrimInputCount(1);
+  return Changed(node);
+}
+
+
+Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) {
+  Node* input = node->InputAt(0);
+  Type* input_type = NodeProperties::GetBounds(input).upper;
+  if (input_type->Is(Type::Boolean())) {
+    // JSToBoolean(x:boolean,context) => x
+    return Replace(input);
+  }
+  // JSToBoolean(x,context) => AnyToBoolean(x)
+  node->set_op(simplified()->AnyToBoolean());
+  node->TrimInputCount(1);
+  return Changed(node);
+}
+
+
 Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) {
   if (input->opcode() == IrOpcode::kJSToNumber) {
     // Recursively try to reduce the input first.
-    Reduction result = ReduceJSToNumberInput(input->InputAt(0));
-    if (result.Changed()) {
-      RelaxEffects(input);
-      return result;
-    }
+    Reduction result = ReduceJSToNumber(input);
+    if (result.Changed()) return result;
     return Changed(input);  // JSToNumber(JSToNumber(x)) => JSToNumber(x)
   }
+  // Check if we have a cached conversion.
+  Node* conversion = FindConversion<IrOpcode::kJSToNumber>(input);
+  if (conversion) return Replace(conversion);
   Type* input_type = NodeProperties::GetBounds(input).upper;
   if (input_type->Is(Type::Number())) {
     // JSToNumber(x:number) => x
@@ -439,30 +538,113 @@
   }
   if (input_type->Is(Type::Undefined())) {
     // JSToNumber(undefined) => #NaN
-    return ReplaceWith(jsgraph()->NaNConstant());
+    return Replace(jsgraph()->NaNConstant());
   }
   if (input_type->Is(Type::Null())) {
     // JSToNumber(null) => #0
-    return ReplaceWith(jsgraph()->ZeroConstant());
+    return Replace(jsgraph()->ZeroConstant());
   }
   if (input_type->Is(Type::Boolean())) {
     // JSToNumber(x:boolean) => BooleanToNumber(x)
-    return ReplaceWith(
-        graph()->NewNode(simplified()->BooleanToNumber(), input));
+    return Replace(graph()->NewNode(simplified()->BooleanToNumber(), input));
   }
   // TODO(turbofan): js-typed-lowering of ToNumber(x:string)
   return NoChange();
 }
 
 
+Reduction JSTypedLowering::ReduceJSToNumber(Node* node) {
+  // Try to reduce the input first.
+  Node* const input = node->InputAt(0);
+  Reduction reduction = ReduceJSToNumberInput(input);
+  if (reduction.Changed()) {
+    NodeProperties::ReplaceWithValue(node, reduction.replacement());
+    return reduction;
+  }
+  Type* const input_type = NodeProperties::GetBounds(input).upper;
+  if (input_type->Is(Type::PlainPrimitive())) {
+    if (input->opcode() == IrOpcode::kPhi) {
+      // JSToNumber(phi(x1,...,xn,control):plain-primitive,context)
+      //   => phi(JSToNumber(x1,no-context),
+      //          ...,
+      //          JSToNumber(xn,no-context),control)
+      int const input_count = input->InputCount() - 1;
+      Node* const control = input->InputAt(input_count);
+      DCHECK_LE(0, input_count);
+      DCHECK(NodeProperties::IsControl(control));
+      DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Number()));
+      DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Number()));
+      RelaxEffects(node);
+      node->set_op(common()->Phi(kMachAnyTagged, input_count));
+      for (int i = 0; i < input_count; ++i) {
+        // We must be very careful not to introduce cycles when pushing
+        // operations into phis. It is safe for {value}, since it appears
+        // as input to the phi that we are replacing, but it's not safe
+        // to simply reuse the context of the {node}. However, ToNumber()
+        // does not require a context anyways, so it's safe to discard it
+        // here and pass the dummy context.
+        Node* const value = ConvertToNumber(input->InputAt(i));
+        if (i < node->InputCount()) {
+          node->ReplaceInput(i, value);
+        } else {
+          node->AppendInput(graph()->zone(), value);
+        }
+      }
+      if (input_count < node->InputCount()) {
+        node->ReplaceInput(input_count, control);
+      } else {
+        node->AppendInput(graph()->zone(), control);
+      }
+      node->TrimInputCount(input_count + 1);
+      return Changed(node);
+    }
+    if (input->opcode() == IrOpcode::kSelect) {
+      // JSToNumber(select(c,x1,x2):plain-primitive,context)
+      //   => select(c,JSToNumber(x1,no-context),JSToNumber(x2,no-context))
+      int const input_count = input->InputCount();
+      BranchHint const input_hint = SelectParametersOf(input->op()).hint();
+      DCHECK_EQ(3, input_count);
+      DCHECK(NodeProperties::GetBounds(node).upper->Is(Type::Number()));
+      DCHECK(!NodeProperties::GetBounds(input).upper->Is(Type::Number()));
+      RelaxEffects(node);
+      node->set_op(common()->Select(kMachAnyTagged, input_hint));
+      node->ReplaceInput(0, input->InputAt(0));
+      for (int i = 1; i < input_count; ++i) {
+        // We must be very careful not to introduce cycles when pushing
+        // operations into selects. It is safe for {value}, since it appears
+        // as input to the select that we are replacing, but it's not safe
+        // to simply reuse the context of the {node}. However, ToNumber()
+        // does not require a context anyways, so it's safe to discard it
+        // here and pass the dummy context.
+        Node* const value = ConvertToNumber(input->InputAt(i));
+        node->ReplaceInput(i, value);
+      }
+      node->TrimInputCount(input_count);
+      return Changed(node);
+    }
+    // Remember this conversion.
+    InsertConversion(node);
+    if (node->InputAt(1) != jsgraph()->NoContextConstant() ||
+        node->InputAt(2) != graph()->start() ||
+        node->InputAt(3) != graph()->start()) {
+      // JSToNumber(x:plain-primitive,context,effect,control)
+      //   => JSToNumber(x,no-context,start,start)
+      RelaxEffects(node);
+      node->ReplaceInput(1, jsgraph()->NoContextConstant());
+      node->ReplaceInput(2, graph()->start());
+      node->ReplaceInput(3, graph()->start());
+      return Changed(node);
+    }
+  }
+  return NoChange();
+}
+
+
 Reduction JSTypedLowering::ReduceJSToStringInput(Node* input) {
   if (input->opcode() == IrOpcode::kJSToString) {
     // Recursively try to reduce the input first.
-    Reduction result = ReduceJSToStringInput(input->InputAt(0));
-    if (result.Changed()) {
-      RelaxEffects(input);
-      return result;
-    }
+    Reduction result = ReduceJSToString(input);
+    if (result.Changed()) return result;
     return Changed(input);  // JSToString(JSToString(x)) => JSToString(x)
   }
   Type* input_type = NodeProperties::GetBounds(input).upper;
@@ -470,12 +652,10 @@
     return Changed(input);  // JSToString(x:string) => x
   }
   if (input_type->Is(Type::Undefined())) {
-    return ReplaceWith(jsgraph()->HeapConstant(
-        graph()->zone()->isolate()->factory()->undefined_string()));
+    return Replace(jsgraph()->HeapConstant(factory()->undefined_string()));
   }
   if (input_type->Is(Type::Null())) {
-    return ReplaceWith(jsgraph()->HeapConstant(
-        graph()->zone()->isolate()->factory()->null_string()));
+    return Replace(jsgraph()->HeapConstant(factory()->null_string()));
   }
   // TODO(turbofan): js-typed-lowering of ToString(x:boolean)
   // TODO(turbofan): js-typed-lowering of ToString(x:number)
@@ -483,44 +663,14 @@
 }
 
 
-Reduction JSTypedLowering::ReduceJSToBooleanInput(Node* input) {
-  if (input->opcode() == IrOpcode::kJSToBoolean) {
-    // Recursively try to reduce the input first.
-    Reduction result = ReduceJSToBooleanInput(input->InputAt(0));
-    if (result.Changed()) {
-      RelaxEffects(input);
-      return result;
-    }
-    return Changed(input);  // JSToBoolean(JSToBoolean(x)) => JSToBoolean(x)
+Reduction JSTypedLowering::ReduceJSToString(Node* node) {
+  // Try to reduce the input first.
+  Node* const input = node->InputAt(0);
+  Reduction reduction = ReduceJSToStringInput(input);
+  if (reduction.Changed()) {
+    NodeProperties::ReplaceWithValue(node, reduction.replacement());
+    return reduction;
   }
-  Type* input_type = NodeProperties::GetBounds(input).upper;
-  if (input_type->Is(Type::Boolean())) {
-    return Changed(input);  // JSToBoolean(x:boolean) => x
-  }
-  if (input_type->Is(Type::Undefined())) {
-    // JSToBoolean(undefined) => #false
-    return ReplaceWith(jsgraph()->FalseConstant());
-  }
-  if (input_type->Is(Type::Null())) {
-    // JSToBoolean(null) => #false
-    return ReplaceWith(jsgraph()->FalseConstant());
-  }
-  if (input_type->Is(Type::DetectableReceiver())) {
-    // JSToBoolean(x:detectable) => #true
-    return ReplaceWith(jsgraph()->TrueConstant());
-  }
-  if (input_type->Is(Type::Undetectable())) {
-    // JSToBoolean(x:undetectable) => #false
-    return ReplaceWith(jsgraph()->FalseConstant());
-  }
-  if (input_type->Is(Type::OrderedNumber())) {
-    // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0))
-    Node* cmp = graph()->NewNode(simplified()->NumberEqual(), input,
-                                 jsgraph()->ZeroConstant());
-    Node* inv = graph()->NewNode(simplified()->BooleanNot(), cmp);
-    return ReplaceWith(inv);
-  }
-  // TODO(turbofan): js-typed-lowering of ToBoolean(string)
   return NoChange();
 }
 
@@ -529,37 +679,40 @@
   Node* key = NodeProperties::GetValueInput(node, 1);
   Node* base = NodeProperties::GetValueInput(node, 0);
   Type* key_type = NodeProperties::GetBounds(key).upper;
-  Type* base_type = NodeProperties::GetBounds(base).upper;
   // TODO(mstarzinger): This lowering is not correct if:
-  //   a) The typed array turns external (i.e. MaterializeArrayBuffer)
-  //   b) The typed array or it's buffer is neutered.
-  //   c) The index is out of bounds.
-  if (base_type->IsConstant() && key_type->Is(Type::Integral32()) &&
-      base_type->AsConstant()->Value()->IsJSTypedArray()) {
-    // JSLoadProperty(typed-array, int32)
-    JSTypedArray* array = JSTypedArray::cast(*base_type->AsConstant()->Value());
-    ElementsKind elements_kind = array->map()->elements_kind();
-    ExternalArrayType type = array->type();
-    uint32_t length;
-    CHECK(array->length()->ToUint32(&length));
-    ElementAccess element_access;
-    Node* elements = graph()->NewNode(
-        simplified()->LoadField(AccessBuilder::ForJSObjectElements()), base,
-        NodeProperties::GetEffectInput(node));
-    if (IsExternalArrayElementsKind(elements_kind)) {
-      elements = graph()->NewNode(
-          simplified()->LoadField(AccessBuilder::ForExternalArrayPointer()),
-          elements, NodeProperties::GetEffectInput(node));
-      element_access = AccessBuilder::ForTypedArrayElement(type, true);
-    } else {
-      DCHECK(IsFixedTypedArrayElementsKind(elements_kind));
-      element_access = AccessBuilder::ForTypedArrayElement(type, false);
+  //   a) The typed array or it's buffer is neutered.
+  HeapObjectMatcher<Object> mbase(base);
+  if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) {
+    Handle<JSTypedArray> const array =
+        Handle<JSTypedArray>::cast(mbase.Value().handle());
+    array->GetBuffer()->set_is_neuterable(false);
+    BufferAccess const access(array->type());
+    size_t const k = ElementSizeLog2Of(access.machine_type());
+    double const byte_length = array->byte_length()->Number();
+    CHECK_LT(k, arraysize(shifted_int32_ranges_));
+    if (IsExternalArrayElementsKind(array->map()->elements_kind()) &&
+        key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
+      // JSLoadProperty(typed-array, int32)
+      Handle<ExternalArray> elements =
+          Handle<ExternalArray>::cast(handle(array->elements()));
+      Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
+      Node* length = jsgraph()->Constant(byte_length);
+      Node* effect = NodeProperties::GetEffectInput(node);
+      Node* control = NodeProperties::GetControlInput(node);
+      // Check if we can avoid the bounds check.
+      if (key_type->Min() >= 0 && key_type->Max() < array->length()->Number()) {
+        Node* load = graph()->NewNode(
+            simplified()->LoadElement(
+                AccessBuilder::ForTypedArrayElement(array->type(), true)),
+            buffer, key, effect, control);
+        return ReplaceEagerly(node, load);
+      }
+      // Compute byte offset.
+      Node* offset = Word32Shl(key, static_cast<int>(k));
+      Node* load = graph()->NewNode(simplified()->LoadBuffer(access), buffer,
+                                    offset, length, effect, control);
+      return ReplaceEagerly(node, load);
     }
-    Node* value =
-        graph()->NewNode(simplified()->LoadElement(element_access), elements,
-                         key, jsgraph()->Uint32Constant(length),
-                         NodeProperties::GetEffectInput(node));
-    return ReplaceEagerly(node, value);
   }
   return NoChange();
 }
@@ -570,65 +723,151 @@
   Node* base = NodeProperties::GetValueInput(node, 0);
   Node* value = NodeProperties::GetValueInput(node, 2);
   Type* key_type = NodeProperties::GetBounds(key).upper;
-  Type* base_type = NodeProperties::GetBounds(base).upper;
+  Type* value_type = NodeProperties::GetBounds(value).upper;
   // TODO(mstarzinger): This lowering is not correct if:
-  //   a) The typed array turns external (i.e. MaterializeArrayBuffer)
-  //   b) The typed array or it's buffer is neutered.
-  if (key_type->Is(Type::Integral32()) && base_type->IsConstant() &&
-      base_type->AsConstant()->Value()->IsJSTypedArray()) {
-    // JSStoreProperty(typed-array, int32, value)
-    JSTypedArray* array = JSTypedArray::cast(*base_type->AsConstant()->Value());
-    ElementsKind elements_kind = array->map()->elements_kind();
-    ExternalArrayType type = array->type();
-    uint32_t length;
-    CHECK(array->length()->ToUint32(&length));
-    ElementAccess element_access;
-    Node* elements = graph()->NewNode(
-        simplified()->LoadField(AccessBuilder::ForJSObjectElements()), base,
-        NodeProperties::GetEffectInput(node));
-    if (IsExternalArrayElementsKind(elements_kind)) {
-      elements = graph()->NewNode(
-          simplified()->LoadField(AccessBuilder::ForExternalArrayPointer()),
-          elements, NodeProperties::GetEffectInput(node));
-      element_access = AccessBuilder::ForTypedArrayElement(type, true);
-    } else {
-      DCHECK(IsFixedTypedArrayElementsKind(elements_kind));
-      element_access = AccessBuilder::ForTypedArrayElement(type, false);
+  //   a) The typed array or its buffer is neutered.
+  HeapObjectMatcher<Object> mbase(base);
+  if (mbase.HasValue() && mbase.Value().handle()->IsJSTypedArray()) {
+    Handle<JSTypedArray> const array =
+        Handle<JSTypedArray>::cast(mbase.Value().handle());
+    array->GetBuffer()->set_is_neuterable(false);
+    BufferAccess const access(array->type());
+    size_t const k = ElementSizeLog2Of(access.machine_type());
+    double const byte_length = array->byte_length()->Number();
+    CHECK_LT(k, arraysize(shifted_int32_ranges_));
+    if (IsExternalArrayElementsKind(array->map()->elements_kind()) &&
+        access.external_array_type() != kExternalUint8ClampedArray &&
+        key_type->Is(shifted_int32_ranges_[k]) && byte_length <= kMaxInt) {
+      // JSLoadProperty(typed-array, int32)
+      Handle<ExternalArray> elements =
+          Handle<ExternalArray>::cast(handle(array->elements()));
+      Node* buffer = jsgraph()->PointerConstant(elements->external_pointer());
+      Node* length = jsgraph()->Constant(byte_length);
+      Node* context = NodeProperties::GetContextInput(node);
+      Node* effect = NodeProperties::GetEffectInput(node);
+      Node* control = NodeProperties::GetControlInput(node);
+      // Convert to a number first.
+      if (!value_type->Is(Type::Number())) {
+        Reduction number_reduction = ReduceJSToNumberInput(value);
+        if (number_reduction.Changed()) {
+          value = number_reduction.replacement();
+        } else {
+          value = effect = graph()->NewNode(javascript()->ToNumber(), value,
+                                            context, effect, control);
+        }
+      }
+      // For integer-typed arrays, convert to the integer type.
+      if (TypeOf(access.machine_type()) == kTypeInt32 &&
+          !value_type->Is(Type::Signed32())) {
+        value = graph()->NewNode(simplified()->NumberToInt32(), value);
+      } else if (TypeOf(access.machine_type()) == kTypeUint32 &&
+                 !value_type->Is(Type::Unsigned32())) {
+        value = graph()->NewNode(simplified()->NumberToUint32(), value);
+      }
+      // Check if we can avoid the bounds check.
+      if (key_type->Min() >= 0 && key_type->Max() < array->length()->Number()) {
+        node->set_op(simplified()->StoreElement(
+            AccessBuilder::ForTypedArrayElement(array->type(), true)));
+        node->ReplaceInput(0, buffer);
+        DCHECK_EQ(key, node->InputAt(1));
+        node->ReplaceInput(2, value);
+        node->ReplaceInput(3, effect);
+        node->ReplaceInput(4, control);
+        node->TrimInputCount(5);
+        return Changed(node);
+      }
+      // Compute byte offset.
+      Node* offset = Word32Shl(key, static_cast<int>(k));
+      // Turn into a StoreBuffer operation.
+      node->set_op(simplified()->StoreBuffer(access));
+      node->ReplaceInput(0, buffer);
+      node->ReplaceInput(1, offset);
+      node->ReplaceInput(2, length);
+      node->ReplaceInput(3, value);
+      node->ReplaceInput(4, effect);
+      DCHECK_EQ(control, node->InputAt(5));
+      DCHECK_EQ(6, node->InputCount());
+      return Changed(node);
     }
-
-    Node* check = graph()->NewNode(machine()->Uint32LessThan(), key,
-                                   jsgraph()->Uint32Constant(length));
-    Node* branch = graph()->NewNode(common()->Branch(), check,
-                                    NodeProperties::GetControlInput(node));
-
-    Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
-    Node* store =
-        graph()->NewNode(simplified()->StoreElement(element_access), elements,
-                         key, jsgraph()->Uint32Constant(length), value,
-                         NodeProperties::GetEffectInput(node), if_true);
-
-    Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
-
-    Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
-    Node* phi = graph()->NewNode(common()->EffectPhi(2), store,
-                                 NodeProperties::GetEffectInput(node), merge);
-
-    return ReplaceWith(phi);
   }
   return NoChange();
 }
 
 
-static Reduction ReplaceWithReduction(Node* node, Reduction reduction) {
-  if (reduction.Changed()) {
-    NodeProperties::ReplaceWithValue(node, reduction.replacement());
-    return reduction;
+Reduction JSTypedLowering::ReduceJSLoadContext(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode());
+  ContextAccess const& access = ContextAccessOf(node->op());
+  Node* const effect = NodeProperties::GetEffectInput(node);
+  Node* const control = graph()->start();
+  for (size_t i = 0; i < access.depth(); ++i) {
+    node->ReplaceInput(
+        0, graph()->NewNode(
+               simplified()->LoadField(
+                   AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
+               NodeProperties::GetValueInput(node, 0), effect, control));
   }
-  return Reducer::NoChange();
+  node->set_op(
+      simplified()->LoadField(AccessBuilder::ForContextSlot(access.index())));
+  node->ReplaceInput(1, effect);
+  node->ReplaceInput(2, control);
+  DCHECK_EQ(3, node->InputCount());
+  return Changed(node);
+}
+
+
+Reduction JSTypedLowering::ReduceJSStoreContext(Node* node) {
+  DCHECK_EQ(IrOpcode::kJSStoreContext, node->opcode());
+  ContextAccess const& access = ContextAccessOf(node->op());
+  Node* const effect = NodeProperties::GetEffectInput(node);
+  Node* const control = graph()->start();
+  for (size_t i = 0; i < access.depth(); ++i) {
+    node->ReplaceInput(
+        0, graph()->NewNode(
+               simplified()->LoadField(
+                   AccessBuilder::ForContextSlot(Context::PREVIOUS_INDEX)),
+               NodeProperties::GetValueInput(node, 0), effect, control));
+  }
+  node->set_op(
+      simplified()->StoreField(AccessBuilder::ForContextSlot(access.index())));
+  node->RemoveInput(2);
+  DCHECK_EQ(4, node->InputCount());
+  return Changed(node);
 }
 
 
 Reduction JSTypedLowering::Reduce(Node* node) {
+  // Check if the output type is a singleton.  In that case we already know the
+  // result value and can simply replace the node if it's eliminable.
+  if (NodeProperties::IsTyped(node) &&
+      !IrOpcode::IsLeafOpcode(node->opcode()) &&
+      node->op()->HasProperty(Operator::kEliminatable)) {
+    Type* upper = NodeProperties::GetBounds(node).upper;
+    if (upper->IsConstant()) {
+      Node* replacement = jsgraph()->Constant(upper->AsConstant()->Value());
+      NodeProperties::ReplaceWithValue(node, replacement);
+      return Changed(replacement);
+    } else if (upper->Is(Type::MinusZero())) {
+      Node* replacement = jsgraph()->Constant(factory()->minus_zero_value());
+      NodeProperties::ReplaceWithValue(node, replacement);
+      return Changed(replacement);
+    } else if (upper->Is(Type::NaN())) {
+      Node* replacement = jsgraph()->NaNConstant();
+      NodeProperties::ReplaceWithValue(node, replacement);
+      return Changed(replacement);
+    } else if (upper->Is(Type::Null())) {
+      Node* replacement = jsgraph()->NullConstant();
+      NodeProperties::ReplaceWithValue(node, replacement);
+      return Changed(replacement);
+    } else if (upper->Is(Type::PlainNumber()) && upper->Min() == upper->Max()) {
+      Node* replacement = jsgraph()->Constant(upper->Min());
+      NodeProperties::ReplaceWithValue(node, replacement);
+      return Changed(replacement);
+    } else if (upper->Is(Type::Undefined())) {
+      Node* replacement = jsgraph()->UndefinedConstant();
+      NodeProperties::ReplaceWithValue(node, replacement);
+      return Changed(replacement);
+    }
+  }
   switch (node->opcode()) {
     case IrOpcode::kJSEqual:
       return ReduceJSEqual(node, false);
@@ -644,67 +883,113 @@
     case IrOpcode::kJSGreaterThanOrEqual:
       return ReduceJSComparison(node);
     case IrOpcode::kJSBitwiseOr:
-      return ReduceI32Binop(node, true, true, machine()->Word32Or());
+      return ReduceJSBitwiseOr(node);
     case IrOpcode::kJSBitwiseXor:
-      return ReduceI32Binop(node, true, true, machine()->Word32Xor());
+      return ReduceInt32Binop(node, machine()->Word32Xor());
     case IrOpcode::kJSBitwiseAnd:
-      return ReduceI32Binop(node, true, true, machine()->Word32And());
+      return ReduceInt32Binop(node, machine()->Word32And());
     case IrOpcode::kJSShiftLeft:
-      return ReduceI32Shift(node, true, machine()->Word32Shl());
+      return ReduceUI32Shift(node, kSigned, machine()->Word32Shl());
     case IrOpcode::kJSShiftRight:
-      return ReduceI32Shift(node, true, machine()->Word32Sar());
+      return ReduceUI32Shift(node, kSigned, machine()->Word32Sar());
     case IrOpcode::kJSShiftRightLogical:
-      return ReduceI32Shift(node, false, machine()->Word32Shr());
+      return ReduceUI32Shift(node, kUnsigned, machine()->Word32Shr());
     case IrOpcode::kJSAdd:
       return ReduceJSAdd(node);
     case IrOpcode::kJSSubtract:
       return ReduceNumberBinop(node, simplified()->NumberSubtract());
     case IrOpcode::kJSMultiply:
-      return ReduceNumberBinop(node, simplified()->NumberMultiply());
+      return ReduceJSMultiply(node);
     case IrOpcode::kJSDivide:
       return ReduceNumberBinop(node, simplified()->NumberDivide());
     case IrOpcode::kJSModulus:
       return ReduceNumberBinop(node, simplified()->NumberModulus());
-    case IrOpcode::kJSUnaryNot: {
-      Reduction result = ReduceJSToBooleanInput(node->InputAt(0));
-      Node* value;
-      if (result.Changed()) {
-        // JSUnaryNot(x:boolean) => BooleanNot(x)
-        value =
-            graph()->NewNode(simplified()->BooleanNot(), result.replacement());
-        NodeProperties::ReplaceWithValue(node, value);
-        return Changed(value);
-      } else {
-        // JSUnaryNot(x) => BooleanNot(JSToBoolean(x))
-        value = graph()->NewNode(simplified()->BooleanNot(), node);
-        node->set_op(javascript()->ToBoolean());
-        NodeProperties::ReplaceWithValue(node, value, node);
-        // Note: ReplaceUses() smashes all uses, so smash it back here.
-        value->ReplaceInput(0, node);
-        return Changed(node);
-      }
-    }
+    case IrOpcode::kJSUnaryNot:
+      return ReduceJSUnaryNot(node);
     case IrOpcode::kJSToBoolean:
-      return ReplaceWithReduction(node,
-                                  ReduceJSToBooleanInput(node->InputAt(0)));
+      return ReduceJSToBoolean(node);
     case IrOpcode::kJSToNumber:
-      return ReplaceWithReduction(node,
-                                  ReduceJSToNumberInput(node->InputAt(0)));
+      return ReduceJSToNumber(node);
     case IrOpcode::kJSToString:
-      return ReplaceWithReduction(node,
-                                  ReduceJSToStringInput(node->InputAt(0)));
+      return ReduceJSToString(node);
     case IrOpcode::kJSLoadProperty:
       return ReduceJSLoadProperty(node);
     case IrOpcode::kJSStoreProperty:
       return ReduceJSStoreProperty(node);
-    case IrOpcode::kJSCallFunction:
-      return JSBuiltinReducer(jsgraph()).Reduce(node);
+    case IrOpcode::kJSLoadContext:
+      return ReduceJSLoadContext(node);
+    case IrOpcode::kJSStoreContext:
+      return ReduceJSStoreContext(node);
     default:
       break;
   }
   return NoChange();
 }
 
+
+Node* JSTypedLowering::ConvertToNumber(Node* input) {
+  DCHECK(NodeProperties::GetBounds(input).upper->Is(Type::PlainPrimitive()));
+  // Avoid inserting too many eager ToNumber() operations.
+  Reduction const reduction = ReduceJSToNumberInput(input);
+  if (reduction.Changed()) return reduction.replacement();
+  Node* const conversion = graph()->NewNode(javascript()->ToNumber(), input,
+                                            jsgraph()->NoContextConstant(),
+                                            graph()->start(), graph()->start());
+  InsertConversion(conversion);
+  return conversion;
+}
+
+
+template <IrOpcode::Value kOpcode>
+Node* JSTypedLowering::FindConversion(Node* input) {
+  size_t const input_id = input->id();
+  if (input_id < conversions_.size()) {
+    Node* const conversion = conversions_[input_id];
+    if (conversion && conversion->opcode() == kOpcode) {
+      return conversion;
+    }
+  }
+  return nullptr;
+}
+
+
+void JSTypedLowering::InsertConversion(Node* conversion) {
+  DCHECK(conversion->opcode() == IrOpcode::kJSToNumber);
+  size_t const input_id = conversion->InputAt(0)->id();
+  if (input_id >= conversions_.size()) {
+    conversions_.resize(2 * input_id + 1);
+  }
+  conversions_[input_id] = conversion;
+}
+
+
+Node* JSTypedLowering::Word32Shl(Node* const lhs, int32_t const rhs) {
+  if (rhs == 0) return lhs;
+  return graph()->NewNode(machine()->Word32Shl(), lhs,
+                          jsgraph()->Int32Constant(rhs));
+}
+
+
+Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); }
+
+
+Graph* JSTypedLowering::graph() const { return jsgraph()->graph(); }
+
+
+JSOperatorBuilder* JSTypedLowering::javascript() const {
+  return jsgraph()->javascript();
+}
+
+
+CommonOperatorBuilder* JSTypedLowering::common() const {
+  return jsgraph()->common();
+}
+
+
+MachineOperatorBuilder* JSTypedLowering::machine() const {
+  return jsgraph()->machine();
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/js-typed-lowering.h b/src/compiler/js-typed-lowering.h
index deaf1fa..838085e 100644
--- a/src/compiler/js-typed-lowering.h
+++ b/src/compiler/js-typed-lowering.h
@@ -6,55 +6,74 @@
 #define V8_COMPILER_JS_TYPED_LOWERING_H_
 
 #include "src/compiler/graph-reducer.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/node.h"
 #include "src/compiler/simplified-operator.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+// Forward declarations.
+class CommonOperatorBuilder;
+class JSGraph;
+class JSOperatorBuilder;
+class MachineOperatorBuilder;
+
+
 // Lowers JS-level operators to simplified operators based on types.
 class JSTypedLowering FINAL : public Reducer {
  public:
-  explicit JSTypedLowering(JSGraph* jsgraph)
-      : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {}
-  virtual ~JSTypedLowering();
+  JSTypedLowering(JSGraph* jsgraph, Zone* zone);
+  ~JSTypedLowering() FINAL {}
 
-  virtual Reduction Reduce(Node* node) OVERRIDE;
-
-  JSGraph* jsgraph() { return jsgraph_; }
-  Graph* graph() { return jsgraph_->graph(); }
-  Zone* zone() { return jsgraph_->zone(); }
+  Reduction Reduce(Node* node) FINAL;
 
  private:
   friend class JSBinopReduction;
 
   Reduction ReplaceEagerly(Node* old, Node* node);
-  Reduction ReplaceWith(Node* node) { return Reducer::Replace(node); }
   Reduction ReduceJSAdd(Node* node);
+  Reduction ReduceJSBitwiseOr(Node* node);
+  Reduction ReduceJSMultiply(Node* node);
   Reduction ReduceJSComparison(Node* node);
   Reduction ReduceJSLoadProperty(Node* node);
   Reduction ReduceJSStoreProperty(Node* node);
+  Reduction ReduceJSLoadContext(Node* node);
+  Reduction ReduceJSStoreContext(Node* node);
   Reduction ReduceJSEqual(Node* node, bool invert);
   Reduction ReduceJSStrictEqual(Node* node, bool invert);
+  Reduction ReduceJSUnaryNot(Node* node);
+  Reduction ReduceJSToBoolean(Node* node);
   Reduction ReduceJSToNumberInput(Node* input);
+  Reduction ReduceJSToNumber(Node* node);
   Reduction ReduceJSToStringInput(Node* input);
-  Reduction ReduceJSToBooleanInput(Node* input);
+  Reduction ReduceJSToString(Node* node);
   Reduction ReduceNumberBinop(Node* node, const Operator* numberOp);
-  Reduction ReduceI32Binop(Node* node, bool left_signed, bool right_signed,
-                           const Operator* intOp);
-  Reduction ReduceI32Shift(Node* node, bool left_signed,
-                           const Operator* shift_op);
+  Reduction ReduceInt32Binop(Node* node, const Operator* intOp);
+  Reduction ReduceUI32Shift(Node* node, Signedness left_signedness,
+                            const Operator* shift_op);
 
-  JSOperatorBuilder* javascript() { return jsgraph_->javascript(); }
-  CommonOperatorBuilder* common() { return jsgraph_->common(); }
+  Node* ConvertToNumber(Node* input);
+  template <IrOpcode::Value>
+  Node* FindConversion(Node* input);
+  void InsertConversion(Node* conversion);
+
+  Node* Word32Shl(Node* const lhs, int32_t const rhs);
+
+  Factory* factory() const;
+  Graph* graph() const;
+  JSGraph* jsgraph() const { return jsgraph_; }
+  JSOperatorBuilder* javascript() const;
+  CommonOperatorBuilder* common() const;
   SimplifiedOperatorBuilder* simplified() { return &simplified_; }
-  MachineOperatorBuilder* machine() { return jsgraph_->machine(); }
+  MachineOperatorBuilder* machine() const;
 
   JSGraph* jsgraph_;
   SimplifiedOperatorBuilder simplified_;
+  ZoneVector<Node*> conversions_;  // Cache inserted JSToXXX() conversions.
+  Type* zero_range_;
+  Type* one_range_;
+  Type* zero_thirtyone_range_;
+  Type* shifted_int32_ranges_[4];
 };
 
 }  // namespace compiler
diff --git a/src/compiler/jump-threading.cc b/src/compiler/jump-threading.cc
new file mode 100644
index 0000000..f0bb731
--- /dev/null
+++ b/src/compiler/jump-threading.cc
@@ -0,0 +1,198 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/jump-threading.h"
+#include "src/compiler/code-generator-impl.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+typedef BasicBlock::RpoNumber RpoNumber;
+
+#define TRACE(x) \
+  if (FLAG_trace_turbo_jt) PrintF x
+
+struct JumpThreadingState {
+  bool forwarded;
+  ZoneVector<RpoNumber>& result;
+  ZoneStack<RpoNumber>& stack;
+
+  void Clear(size_t count) { result.assign(count, unvisited()); }
+  void PushIfUnvisited(RpoNumber num) {
+    if (result[num.ToInt()] == unvisited()) {
+      stack.push(num);
+      result[num.ToInt()] = onstack();
+    }
+  }
+  void Forward(RpoNumber to) {
+    RpoNumber from = stack.top();
+    RpoNumber to_to = result[to.ToInt()];
+    bool pop = true;
+    if (to == from) {
+      TRACE(("  xx %d\n", from.ToInt()));
+      result[from.ToInt()] = from;
+    } else if (to_to == unvisited()) {
+      TRACE(("  fw %d -> %d (recurse)\n", from.ToInt(), to.ToInt()));
+      stack.push(to);
+      result[to.ToInt()] = onstack();
+      pop = false;  // recurse.
+    } else if (to_to == onstack()) {
+      TRACE(("  fw %d -> %d (cycle)\n", from.ToInt(), to.ToInt()));
+      result[from.ToInt()] = to;  // break the cycle.
+      forwarded = true;
+    } else {
+      TRACE(("  fw %d -> %d (forward)\n", from.ToInt(), to.ToInt()));
+      result[from.ToInt()] = to_to;  // forward the block.
+      forwarded = true;
+    }
+    if (pop) stack.pop();
+  }
+  RpoNumber unvisited() { return RpoNumber::FromInt(-1); }
+  RpoNumber onstack() { return RpoNumber::FromInt(-2); }
+};
+
+
+bool JumpThreading::ComputeForwarding(Zone* local_zone,
+                                      ZoneVector<RpoNumber>& result,
+                                      InstructionSequence* code) {
+  ZoneStack<RpoNumber> stack(local_zone);
+  JumpThreadingState state = {false, result, stack};
+  state.Clear(code->InstructionBlockCount());
+
+  // Iterate over the blocks forward, pushing the blocks onto the stack.
+  for (auto const block : code->instruction_blocks()) {
+    RpoNumber current = block->rpo_number();
+    state.PushIfUnvisited(current);
+
+    // Process the stack, which implements DFS through empty blocks.
+    while (!state.stack.empty()) {
+      InstructionBlock* block = code->InstructionBlockAt(state.stack.top());
+      // Process the instructions in a block up to a non-empty instruction.
+      TRACE(("jt [%d] B%d RPO%d\n", static_cast<int>(stack.size()),
+             block->id().ToInt(), block->rpo_number().ToInt()));
+      bool fallthru = true;
+      RpoNumber fw = block->rpo_number();
+      for (int i = block->code_start(); i < block->code_end(); ++i) {
+        Instruction* instr = code->InstructionAt(i);
+        if (instr->IsGapMoves() && GapInstruction::cast(instr)->IsRedundant()) {
+          // skip redundant gap moves.
+          TRACE(("  nop gap\n"));
+          continue;
+        } else if (instr->IsSourcePosition()) {
+          // skip source positions.
+          TRACE(("  src pos\n"));
+          continue;
+        } else if (FlagsModeField::decode(instr->opcode()) != kFlags_none) {
+          // can't skip instructions with flags continuations.
+          TRACE(("  flags\n"));
+          fallthru = false;
+        } else if (instr->IsNop()) {
+          // skip nops.
+          TRACE(("  nop\n"));
+          continue;
+        } else if (instr->arch_opcode() == kArchJmp) {
+          // try to forward the jump instruction.
+          TRACE(("  jmp\n"));
+          fw = code->InputRpo(instr, 0);
+          fallthru = false;
+        } else {
+          // can't skip other instructions.
+          TRACE(("  other\n"));
+          fallthru = false;
+        }
+        break;
+      }
+      if (fallthru) {
+        int next = 1 + block->rpo_number().ToInt();
+        if (next < code->InstructionBlockCount()) fw = RpoNumber::FromInt(next);
+      }
+      state.Forward(fw);
+    }
+  }
+
+#ifdef DEBUG
+  for (RpoNumber num : result) {
+    CHECK(num.IsValid());
+  }
+#endif
+
+  if (FLAG_trace_turbo_jt) {
+    for (int i = 0; i < static_cast<int>(result.size()); i++) {
+      TRACE(("RPO%d B%d ", i,
+             code->InstructionBlockAt(RpoNumber::FromInt(i))->id().ToInt()));
+      int to = result[i].ToInt();
+      if (i != to) {
+        TRACE(("-> B%d\n",
+               code->InstructionBlockAt(RpoNumber::FromInt(to))->id().ToInt()));
+      } else {
+        TRACE(("\n"));
+      }
+    }
+  }
+
+  return state.forwarded;
+}
+
+
+void JumpThreading::ApplyForwarding(ZoneVector<RpoNumber>& result,
+                                    InstructionSequence* code) {
+  if (!FLAG_turbo_jt) return;
+
+  Zone local_zone(code->zone()->isolate());
+  ZoneVector<bool> skip(static_cast<int>(result.size()), false, &local_zone);
+
+  // Skip empty blocks when the previous block doesn't fall through.
+  bool prev_fallthru = true;
+  for (auto const block : code->instruction_blocks()) {
+    int block_num = block->rpo_number().ToInt();
+    skip[block_num] = !prev_fallthru && result[block_num].ToInt() != block_num;
+
+    bool fallthru = true;
+    for (int i = block->code_start(); i < block->code_end(); ++i) {
+      Instruction* instr = code->InstructionAt(i);
+      if (FlagsModeField::decode(instr->opcode()) == kFlags_branch) {
+        fallthru = false;  // branches don't fall through to the next block.
+      } else if (instr->arch_opcode() == kArchJmp) {
+        if (skip[block_num]) {
+          // Overwrite a redundant jump with a nop.
+          TRACE(("jt-fw nop @%d\n", i));
+          instr->OverwriteWithNop();
+        }
+        fallthru = false;  // jumps don't fall through to the next block.
+      }
+    }
+    prev_fallthru = fallthru;
+  }
+
+  // Patch RPO immediates.
+  InstructionSequence::Immediates& immediates = code->immediates();
+  for (size_t i = 0; i < immediates.size(); i++) {
+    Constant constant = immediates[i];
+    if (constant.type() == Constant::kRpoNumber) {
+      RpoNumber rpo = constant.ToRpoNumber();
+      RpoNumber fw = result[rpo.ToInt()];
+      if (!(fw == rpo)) immediates[i] = Constant(fw);
+    }
+  }
+
+  // Recompute assembly order numbers.
+  int ao = 0;
+  for (auto const block : code->instruction_blocks()) {
+    if (!block->IsDeferred()) {
+      block->set_ao_number(RpoNumber::FromInt(ao));
+      if (!skip[block->rpo_number().ToInt()]) ao++;
+    }
+  }
+  for (auto const block : code->instruction_blocks()) {
+    if (block->IsDeferred()) {
+      block->set_ao_number(RpoNumber::FromInt(ao));
+      if (!skip[block->rpo_number().ToInt()]) ao++;
+    }
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/jump-threading.h b/src/compiler/jump-threading.h
new file mode 100644
index 0000000..b801fec
--- /dev/null
+++ b/src/compiler/jump-threading.h
@@ -0,0 +1,34 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_JUMP_THREADING_H_
+#define V8_COMPILER_JUMP_THREADING_H_
+
+#include "src/compiler/instruction.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Forwards jumps to empty basic blocks that end with a second jump to the
+// destination of the second jump, transitively.
+class JumpThreading {
+ public:
+  // Compute the forwarding map of basic blocks to their ultimate destination.
+  // Returns {true} if there is at least one block that is forwarded.
+  static bool ComputeForwarding(Zone* local_zone,
+                                ZoneVector<BasicBlock::RpoNumber>& result,
+                                InstructionSequence* code);
+
+  // Rewrite the instructions to forward jumps and branches.
+  // May also negate some branches.
+  static void ApplyForwarding(ZoneVector<BasicBlock::RpoNumber>& forwarding,
+                              InstructionSequence* code);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_JUMP_THREADING_H
diff --git a/src/compiler/linkage-impl.h b/src/compiler/linkage-impl.h
index c32c706..c13bd74 100644
--- a/src/compiler/linkage-impl.h
+++ b/src/compiler/linkage-impl.h
@@ -5,6 +5,8 @@
 #ifndef V8_COMPILER_LINKAGE_IMPL_H_
 #define V8_COMPILER_LINKAGE_IMPL_H_
 
+#include "src/code-stubs.h"
+
 namespace v8 {
 namespace internal {
 namespace compiler {
@@ -26,8 +28,8 @@
   }
 
   // TODO(turbofan): cache call descriptors for JSFunction calls.
-  static CallDescriptor* GetJSCallDescriptor(Zone* zone,
-                                             int js_parameter_count) {
+  static CallDescriptor* GetJSCallDescriptor(Zone* zone, int js_parameter_count,
+                                             CallDescriptor::Flags flags) {
     const size_t return_count = 1;
     const size_t context_count = 1;
     const size_t parameter_count = js_parameter_count + context_count;
@@ -54,16 +56,17 @@
     // The target for JS function calls is the JSFunction object.
     MachineType target_type = kMachAnyTagged;
     LinkageLocation target_loc = regloc(LinkageTraits::JSCallFunctionReg());
-    return new (zone) CallDescriptor(CallDescriptor::kCallJSFunction,  // kind
-                                     target_type,         // target MachineType
-                                     target_loc,          // target location
-                                     types.Build(),       // machine_sig
-                                     locations.Build(),   // location_sig
-                                     js_parameter_count,  // js_parameter_count
-                                     Operator::kNoProperties,  // properties
-                                     kNoCalleeSaved,           // callee-saved
-                                     CallDescriptor::kNeedsFrameState,  // flags
-                                     "js-call");
+    return new (zone) CallDescriptor(     // --
+        CallDescriptor::kCallJSFunction,  // kind
+        target_type,                      // target MachineType
+        target_loc,                       // target location
+        types.Build(),                    // machine_sig
+        locations.Build(),                // location_sig
+        js_parameter_count,               // js_parameter_count
+        Operator::kNoProperties,          // properties
+        kNoCalleeSaved,                   // callee-saved
+        flags,                            // flags
+        "js-call");
   }
 
 
@@ -114,23 +117,25 @@
     // The target for runtime calls is a code object.
     MachineType target_type = kMachAnyTagged;
     LinkageLocation target_loc = LinkageLocation::AnyRegister();
-    return new (zone) CallDescriptor(CallDescriptor::kCallCodeObject,  // kind
-                                     target_type,         // target MachineType
-                                     target_loc,          // target location
-                                     types.Build(),       // machine_sig
-                                     locations.Build(),   // location_sig
-                                     js_parameter_count,  // js_parameter_count
-                                     properties,          // properties
-                                     kNoCalleeSaved,      // callee-saved
-                                     flags,               // flags
-                                     function->name);     // debug name
+    return new (zone) CallDescriptor(     // --
+        CallDescriptor::kCallCodeObject,  // kind
+        target_type,                      // target MachineType
+        target_loc,                       // target location
+        types.Build(),                    // machine_sig
+        locations.Build(),                // location_sig
+        js_parameter_count,               // js_parameter_count
+        properties,                       // properties
+        kNoCalleeSaved,                   // callee-saved
+        flags,                            // flags
+        function->name);                  // debug name
   }
 
 
   // TODO(turbofan): cache call descriptors for code stub calls.
   static CallDescriptor* GetStubCallDescriptor(
-      Zone* zone, CallInterfaceDescriptor descriptor, int stack_parameter_count,
-      CallDescriptor::Flags flags) {
+      Zone* zone, const CallInterfaceDescriptor& descriptor,
+      int stack_parameter_count, CallDescriptor::Flags flags,
+      Operator::Properties properties) {
     const int register_parameter_count =
         descriptor.GetEnvironmentParameterCount();
     const int js_parameter_count =
@@ -167,16 +172,17 @@
     // The target for stub calls is a code object.
     MachineType target_type = kMachAnyTagged;
     LinkageLocation target_loc = LinkageLocation::AnyRegister();
-    return new (zone) CallDescriptor(CallDescriptor::kCallCodeObject,  // kind
-                                     target_type,         // target MachineType
-                                     target_loc,          // target location
-                                     types.Build(),       // machine_sig
-                                     locations.Build(),   // location_sig
-                                     js_parameter_count,  // js_parameter_count
-                                     Operator::kNoProperties,  // properties
-                                     kNoCalleeSaved,  // callee-saved registers
-                                     flags,           // flags
-                                     descriptor.DebugName(zone->isolate()));
+    return new (zone) CallDescriptor(     // --
+        CallDescriptor::kCallCodeObject,  // kind
+        target_type,                      // target MachineType
+        target_loc,                       // target location
+        types.Build(),                    // machine_sig
+        locations.Build(),                // location_sig
+        js_parameter_count,               // js_parameter_count
+        properties,                       // properties
+        kNoCalleeSaved,                   // callee-saved registers
+        flags,                            // flags
+        descriptor.DebugName(zone->isolate()));
   }
 
   static CallDescriptor* GetSimplifiedCDescriptor(Zone* zone,
@@ -199,15 +205,16 @@
     // The target for C calls is always an address (i.e. machine pointer).
     MachineType target_type = kMachPtr;
     LinkageLocation target_loc = LinkageLocation::AnyRegister();
-    return new (zone) CallDescriptor(CallDescriptor::kCallAddress,  // kind
-                                     target_type,        // target MachineType
-                                     target_loc,         // target location
-                                     msig,               // machine_sig
-                                     locations.Build(),  // location_sig
-                                     0,                  // js_parameter_count
-                                     Operator::kNoProperties,  // properties
-                                     LinkageTraits::CCalleeSaveRegisters(),
-                                     CallDescriptor::kNoFlags, "c-call");
+    return new (zone) CallDescriptor(  // --
+        CallDescriptor::kCallAddress,  // kind
+        target_type,                   // target MachineType
+        target_loc,                    // target location
+        msig,                          // machine_sig
+        locations.Build(),             // location_sig
+        0,                             // js_parameter_count
+        Operator::kNoProperties,       // properties
+        LinkageTraits::CCalleeSaveRegisters(), CallDescriptor::kNoFlags,
+        "c-call");
   }
 
   static LinkageLocation regloc(Register reg) {
diff --git a/src/compiler/linkage.cc b/src/compiler/linkage.cc
index 465a667..fc6b19e 100644
--- a/src/compiler/linkage.cc
+++ b/src/compiler/linkage.cc
@@ -2,10 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/compiler/linkage.h"
-
 #include "src/code-stubs.h"
 #include "src/compiler.h"
+#include "src/compiler/linkage.h"
 #include "src/compiler/node.h"
 #include "src/compiler/pipeline.h"
 #include "src/scopes.h"
@@ -15,7 +14,7 @@
 namespace compiler {
 
 
-OStream& operator<<(OStream& os, const CallDescriptor::Kind& k) {
+std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k) {
   switch (k) {
     case CallDescriptor::kCallCodeObject:
       os << "Code";
@@ -31,7 +30,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const CallDescriptor& d) {
+std::ostream& operator<<(std::ostream& os, const CallDescriptor& d) {
   // TODO(svenpanne) Output properties etc. and be less cryptic.
   return os << d.kind() << ":" << d.debug_name() << ":r" << d.ReturnCount()
             << "j" << d.JSParameterCount() << "i" << d.InputCount() << "f"
@@ -39,28 +38,33 @@
 }
 
 
-Linkage::Linkage(CompilationInfo* info) : info_(info) {
+CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) {
   if (info->function() != NULL) {
     // If we already have the function literal, use the number of parameters
     // plus the receiver.
-    incoming_ = GetJSCallDescriptor(1 + info->function()->parameter_count());
-  } else if (!info->closure().is_null()) {
+    return GetJSCallDescriptor(1 + info->function()->parameter_count(), zone,
+                               CallDescriptor::kNoFlags);
+  }
+  if (!info->closure().is_null()) {
     // If we are compiling a JS function, use a JS call descriptor,
     // plus the receiver.
     SharedFunctionInfo* shared = info->closure()->shared();
-    incoming_ = GetJSCallDescriptor(1 + shared->formal_parameter_count());
-  } else if (info->code_stub() != NULL) {
+    return GetJSCallDescriptor(1 + shared->formal_parameter_count(), zone,
+                               CallDescriptor::kNoFlags);
+  }
+  if (info->code_stub() != NULL) {
     // Use the code stub interface descriptor.
     CallInterfaceDescriptor descriptor =
         info->code_stub()->GetCallInterfaceDescriptor();
-    incoming_ = GetStubCallDescriptor(descriptor);
-  } else {
-    incoming_ = NULL;  // TODO(titzer): ?
+    return GetStubCallDescriptor(descriptor, 0, CallDescriptor::kNoFlags,
+                                 Operator::kNoProperties, zone);
   }
+  return NULL;  // TODO(titzer): ?
 }
 
 
-FrameOffset Linkage::GetFrameOffset(int spill_slot, Frame* frame, int extra) {
+FrameOffset Linkage::GetFrameOffset(int spill_slot, Frame* frame,
+                                    int extra) const {
   if (frame->GetSpillSlotCount() > 0 || incoming_->IsJSFunctionCall() ||
       incoming_->kind() == CallDescriptor::kCallAddress) {
     int offset;
@@ -87,24 +91,24 @@
 }
 
 
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count) {
-  return GetJSCallDescriptor(parameter_count, this->info_->zone());
+CallDescriptor* Linkage::GetJSCallDescriptor(
+    int parameter_count, CallDescriptor::Flags flags) const {
+  return GetJSCallDescriptor(parameter_count, zone_, flags);
 }
 
 
 CallDescriptor* Linkage::GetRuntimeCallDescriptor(
     Runtime::FunctionId function, int parameter_count,
-    Operator::Properties properties) {
-  return GetRuntimeCallDescriptor(function, parameter_count, properties,
-                                  this->info_->zone());
+    Operator::Properties properties) const {
+  return GetRuntimeCallDescriptor(function, parameter_count, properties, zone_);
 }
 
 
 CallDescriptor* Linkage::GetStubCallDescriptor(
-    CallInterfaceDescriptor descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags) {
+    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
+    CallDescriptor::Flags flags, Operator::Properties properties) const {
   return GetStubCallDescriptor(descriptor, stack_parameter_count, flags,
-                               this->info_->zone());
+                               properties, zone_);
 }
 
 
@@ -116,16 +120,98 @@
   // TODO(jarin) At the moment, we only add frame state for
   // few chosen runtime functions.
   switch (function) {
-    case Runtime::kDebugBreak:
-    case Runtime::kDebugGetLoadedScripts:
-    case Runtime::kDeoptimizeFunction:
-    case Runtime::kInlineCallFunction:
-    case Runtime::kPrepareStep:
-    case Runtime::kSetScriptBreakPoint:
-    case Runtime::kStackGuard:
+    case Runtime::kApply:
+    case Runtime::kArrayBufferNeuter:
+    case Runtime::kArrayConcat:
+    case Runtime::kBasicJSONStringify:
     case Runtime::kCheckExecutionState:
-    case Runtime::kDebugEvaluate:
     case Runtime::kCollectStackTrace:
+    case Runtime::kCompileLazy:
+    case Runtime::kCompileOptimized:
+    case Runtime::kCompileString:
+    case Runtime::kCreateObjectLiteral:
+    case Runtime::kDebugBreak:
+    case Runtime::kDataViewSetInt8:
+    case Runtime::kDataViewSetUint8:
+    case Runtime::kDataViewSetInt16:
+    case Runtime::kDataViewSetUint16:
+    case Runtime::kDataViewSetInt32:
+    case Runtime::kDataViewSetUint32:
+    case Runtime::kDataViewSetFloat32:
+    case Runtime::kDataViewSetFloat64:
+    case Runtime::kDataViewGetInt8:
+    case Runtime::kDataViewGetUint8:
+    case Runtime::kDataViewGetInt16:
+    case Runtime::kDataViewGetUint16:
+    case Runtime::kDataViewGetInt32:
+    case Runtime::kDataViewGetUint32:
+    case Runtime::kDataViewGetFloat32:
+    case Runtime::kDataViewGetFloat64:
+    case Runtime::kDebugEvaluate:
+    case Runtime::kDebugEvaluateGlobal:
+    case Runtime::kDebugGetLoadedScripts:
+    case Runtime::kDebugGetPropertyDetails:
+    case Runtime::kDebugPromiseEvent:
+    case Runtime::kDefineAccessorPropertyUnchecked:
+    case Runtime::kDefineDataPropertyUnchecked:
+    case Runtime::kDeleteProperty:
+    case Runtime::kDeoptimizeFunction:
+    case Runtime::kFunctionBindArguments:
+    case Runtime::kGetDefaultReceiver:
+    case Runtime::kGetFrameCount:
+    case Runtime::kGetOwnProperty:
+    case Runtime::kGetOwnPropertyNames:
+    case Runtime::kGetPropertyNamesFast:
+    case Runtime::kGetPrototype:
+    case Runtime::kInlineArguments:
+    case Runtime::kInlineCallFunction:
+    case Runtime::kInlineDateField:
+    case Runtime::kInlineRegExpExec:
+    case Runtime::kInternalSetPrototype:
+    case Runtime::kInterrupt:
+    case Runtime::kIsPropertyEnumerable:
+    case Runtime::kIsSloppyModeFunction:
+    case Runtime::kLiveEditGatherCompileInfo:
+    case Runtime::kLoadLookupSlot:
+    case Runtime::kLoadLookupSlotNoReferenceError:
+    case Runtime::kMaterializeRegExpLiteral:
+    case Runtime::kNewObject:
+    case Runtime::kNewObjectFromBound:
+    case Runtime::kNewObjectWithAllocationSite:
+    case Runtime::kObjectFreeze:
+    case Runtime::kOwnKeys:
+    case Runtime::kParseJson:
+    case Runtime::kPrepareStep:
+    case Runtime::kPreventExtensions:
+    case Runtime::kPromiseRejectEvent:
+    case Runtime::kPromiseRevokeReject:
+    case Runtime::kRegExpInitializeAndCompile:
+    case Runtime::kRegExpExecMultiple:
+    case Runtime::kResolvePossiblyDirectEval:
+    case Runtime::kRunMicrotasks:
+    case Runtime::kSetPrototype:
+    case Runtime::kSetScriptBreakPoint:
+    case Runtime::kSparseJoinWithSeparator:
+    case Runtime::kStackGuard:
+    case Runtime::kStoreKeyedToSuper_Sloppy:
+    case Runtime::kStoreKeyedToSuper_Strict:
+    case Runtime::kStoreToSuper_Sloppy:
+    case Runtime::kStoreToSuper_Strict:
+    case Runtime::kStoreLookupSlot:
+    case Runtime::kStringBuilderConcat:
+    case Runtime::kStringBuilderJoin:
+    case Runtime::kStringMatch:
+    case Runtime::kStringReplaceGlobalRegExpWithString:
+    case Runtime::kThrowNonMethodError:
+    case Runtime::kThrowNotDateError:
+    case Runtime::kThrowReferenceError:
+    case Runtime::kThrowUnsupportedSuperError:
+    case Runtime::kThrow:
+    case Runtime::kTypedArraySetFastCases:
+    case Runtime::kTypedArrayInitializeFromArrayLike:
+#ifdef V8_I18N_SUPPORT
+    case Runtime::kGetImplFromInitializedIntlObject:
+#endif
       return true;
     default:
       return false;
@@ -137,7 +223,8 @@
 // Provide unimplemented methods on unsupported architectures, to at least link.
 //==============================================================================
 #if !V8_TURBOFAN_BACKEND
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) {
+CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
+                                             CallDescriptor::Flags flags) {
   UNIMPLEMENTED();
   return NULL;
 }
@@ -152,8 +239,9 @@
 
 
 CallDescriptor* Linkage::GetStubCallDescriptor(
-    CallInterfaceDescriptor descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Zone* zone) {
+    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
+    CallDescriptor::Flags flags, Operator::Properties properties,
+    Zone* zone) {
   UNIMPLEMENTED();
   return NULL;
 }
diff --git a/src/compiler/linkage.h b/src/compiler/linkage.h
index c5cef5e..0ad0761 100644
--- a/src/compiler/linkage.h
+++ b/src/compiler/linkage.h
@@ -6,15 +6,16 @@
 #define V8_COMPILER_LINKAGE_H_
 
 #include "src/base/flags.h"
-#include "src/code-stubs.h"
 #include "src/compiler/frame.h"
 #include "src/compiler/machine-type.h"
-#include "src/compiler/node.h"
 #include "src/compiler/operator.h"
 #include "src/zone.h"
 
 namespace v8 {
 namespace internal {
+
+class CallInterfaceDescriptor;
+
 namespace compiler {
 
 // Describes the location for a parameter or a return value to a call.
@@ -129,22 +130,24 @@
  private:
   friend class Linkage;
 
-  Kind kind_;
-  MachineType target_type_;
-  LinkageLocation target_loc_;
-  MachineSignature* machine_sig_;
-  LocationSignature* location_sig_;
-  size_t js_param_count_;
-  Operator::Properties properties_;
-  RegList callee_saved_registers_;
-  Flags flags_;
-  const char* debug_name_;
+  const Kind kind_;
+  const MachineType target_type_;
+  const LinkageLocation target_loc_;
+  const MachineSignature* const machine_sig_;
+  const LocationSignature* const location_sig_;
+  const size_t js_param_count_;
+  const Operator::Properties properties_;
+  const RegList callee_saved_registers_;
+  const Flags flags_;
+  const char* const debug_name_;
+
+  DISALLOW_COPY_AND_ASSIGN(CallDescriptor);
 };
 
 DEFINE_OPERATORS_FOR_FLAGS(CallDescriptor::Flags)
 
-OStream& operator<<(OStream& os, const CallDescriptor& d);
-OStream& operator<<(OStream& os, const CallDescriptor::Kind& k);
+std::ostream& operator<<(std::ostream& os, const CallDescriptor& d);
+std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k);
 
 // Defines the linkage for a compilation, including the calling conventions
 // for incoming parameters and return value(s) as well as the outgoing calling
@@ -161,28 +164,34 @@
 // Call[Runtime]    CEntryStub, arg 1, arg 2, arg 3, [...], fun, #arg, context
 class Linkage : public ZoneObject {
  public:
-  explicit Linkage(CompilationInfo* info);
-  explicit Linkage(CompilationInfo* info, CallDescriptor* incoming)
-      : info_(info), incoming_(incoming) {}
+  Linkage(Zone* zone, CompilationInfo* info)
+      : zone_(zone), incoming_(ComputeIncoming(zone, info)) {}
+  Linkage(Zone* zone, CallDescriptor* incoming)
+      : zone_(zone), incoming_(incoming) {}
+
+  static CallDescriptor* ComputeIncoming(Zone* zone, CompilationInfo* info);
 
   // The call descriptor for this compilation unit describes the locations
   // of incoming parameters and the outgoing return value(s).
-  CallDescriptor* GetIncomingDescriptor() { return incoming_; }
-  CallDescriptor* GetJSCallDescriptor(int parameter_count);
-  static CallDescriptor* GetJSCallDescriptor(int parameter_count, Zone* zone);
-  CallDescriptor* GetRuntimeCallDescriptor(Runtime::FunctionId function,
-                                           int parameter_count,
-                                           Operator::Properties properties);
+  CallDescriptor* GetIncomingDescriptor() const { return incoming_; }
+  CallDescriptor* GetJSCallDescriptor(int parameter_count,
+                                      CallDescriptor::Flags flags) const;
+  static CallDescriptor* GetJSCallDescriptor(int parameter_count, Zone* zone,
+                                             CallDescriptor::Flags flags);
+  CallDescriptor* GetRuntimeCallDescriptor(
+      Runtime::FunctionId function, int parameter_count,
+      Operator::Properties properties) const;
   static CallDescriptor* GetRuntimeCallDescriptor(
       Runtime::FunctionId function, int parameter_count,
       Operator::Properties properties, Zone* zone);
 
   CallDescriptor* GetStubCallDescriptor(
-      CallInterfaceDescriptor descriptor, int stack_parameter_count = 0,
-      CallDescriptor::Flags flags = CallDescriptor::kNoFlags);
+      const CallInterfaceDescriptor& descriptor, int stack_parameter_count = 0,
+      CallDescriptor::Flags flags = CallDescriptor::kNoFlags,
+      Operator::Properties properties = Operator::kNoProperties) const;
   static CallDescriptor* GetStubCallDescriptor(
-      CallInterfaceDescriptor descriptor, int stack_parameter_count,
-      CallDescriptor::Flags flags, Zone* zone);
+      const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
+      CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone);
 
   // Creates a call descriptor for simplified C calls that is appropriate
   // for the host platform. This simplified calling convention only supports
@@ -192,37 +201,37 @@
                                                   MachineSignature* sig);
 
   // Get the location of an (incoming) parameter to this function.
-  LinkageLocation GetParameterLocation(int index) {
+  LinkageLocation GetParameterLocation(int index) const {
     return incoming_->GetInputLocation(index + 1);  // + 1 to skip target.
   }
 
   // Get the machine type of an (incoming) parameter to this function.
-  MachineType GetParameterType(int index) {
+  MachineType GetParameterType(int index) const {
     return incoming_->GetInputType(index + 1);  // + 1 to skip target.
   }
 
   // Get the location where this function should place its return value.
-  LinkageLocation GetReturnLocation() {
+  LinkageLocation GetReturnLocation() const {
     return incoming_->GetReturnLocation(0);
   }
 
   // Get the machine type of this function's return value.
-  MachineType GetReturnType() { return incoming_->GetReturnType(0); }
+  MachineType GetReturnType() const { return incoming_->GetReturnType(0); }
 
   // Get the frame offset for a given spill slot. The location depends on the
   // calling convention and the specific frame layout, and may thus be
   // architecture-specific. Negative spill slots indicate arguments on the
   // caller's frame. The {extra} parameter indicates an additional offset from
   // the frame offset, e.g. to index into part of a double slot.
-  FrameOffset GetFrameOffset(int spill_slot, Frame* frame, int extra = 0);
-
-  CompilationInfo* info() const { return info_; }
+  FrameOffset GetFrameOffset(int spill_slot, Frame* frame, int extra = 0) const;
 
   static bool NeedsFrameState(Runtime::FunctionId function);
 
  private:
-  CompilationInfo* info_;
-  CallDescriptor* incoming_;
+  Zone* const zone_;
+  CallDescriptor* const incoming_;
+
+  DISALLOW_COPY_AND_ASSIGN(Linkage);
 };
 
 }  // namespace compiler
diff --git a/src/compiler/load-elimination.cc b/src/compiler/load-elimination.cc
new file mode 100644
index 0000000..fe0714e
--- /dev/null
+++ b/src/compiler/load-elimination.cc
@@ -0,0 +1,76 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/load-elimination.h"
+
+#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/simplified-operator.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+LoadElimination::~LoadElimination() {}
+
+
+Reduction LoadElimination::Reduce(Node* node) {
+  switch (node->opcode()) {
+    case IrOpcode::kLoadField:
+      return ReduceLoadField(node);
+    default:
+      break;
+  }
+  return NoChange();
+}
+
+
+Reduction LoadElimination::ReduceLoadField(Node* node) {
+  DCHECK_EQ(IrOpcode::kLoadField, node->opcode());
+  FieldAccess const access = FieldAccessOf(node->op());
+  Node* const object = NodeProperties::GetValueInput(node, 0);
+  for (Node* effect = NodeProperties::GetEffectInput(node);;
+       effect = NodeProperties::GetEffectInput(effect)) {
+    switch (effect->opcode()) {
+      case IrOpcode::kLoadField: {
+        if (object == NodeProperties::GetValueInput(effect, 0) &&
+            access == FieldAccessOf(effect->op())) {
+          Node* const value = effect;
+          NodeProperties::ReplaceWithValue(node, value);
+          return Replace(value);
+        }
+        break;
+      }
+      case IrOpcode::kStoreField: {
+        if (access == FieldAccessOf(effect->op())) {
+          if (object == NodeProperties::GetValueInput(effect, 0)) {
+            Node* const value = NodeProperties::GetValueInput(effect, 1);
+            NodeProperties::ReplaceWithValue(node, value);
+            return Replace(value);
+          }
+          // TODO(turbofan): Alias analysis to the rescue?
+          return NoChange();
+        }
+        break;
+      }
+      case IrOpcode::kStoreBuffer:
+      case IrOpcode::kStoreElement: {
+        // These can never interfere with field loads.
+        break;
+      }
+      default: {
+        if (!effect->op()->HasProperty(Operator::kNoWrite) ||
+            effect->op()->EffectInputCount() != 1) {
+          return NoChange();
+        }
+        break;
+      }
+    }
+  }
+  UNREACHABLE();
+  return NoChange();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/load-elimination.h b/src/compiler/load-elimination.h
new file mode 100644
index 0000000..6917ce3
--- /dev/null
+++ b/src/compiler/load-elimination.h
@@ -0,0 +1,29 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_LOAD_ELIMINATION_H_
+#define V8_COMPILER_LOAD_ELIMINATION_H_
+
+#include "src/compiler/graph-reducer.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class LoadElimination FINAL : public Reducer {
+ public:
+  LoadElimination() {}
+  ~LoadElimination() FINAL;
+
+  Reduction Reduce(Node* node) FINAL;
+
+ private:
+  Reduction ReduceLoadField(Node* node);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_LOAD_ELIMINATION_H_
diff --git a/src/compiler/loop-analysis.cc b/src/compiler/loop-analysis.cc
new file mode 100644
index 0000000..e1b703e
--- /dev/null
+++ b/src/compiler/loop-analysis.cc
@@ -0,0 +1,411 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/graph.h"
+#include "src/compiler/loop-analysis.h"
+#include "src/compiler/node.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/zone.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+typedef uint32_t LoopMarks;
+
+
+// TODO(titzer): don't assume entry edges have a particular index.
+// TODO(titzer): use a BitMatrix to generalize this algorithm.
+static const size_t kMaxLoops = 31;
+static const int kAssumedLoopEntryIndex = 0;  // assume loops are entered here.
+static const LoopMarks kVisited = 1;          // loop #0 is reserved.
+
+
+// Temporary information for each node during marking.
+struct NodeInfo {
+  Node* node;
+  NodeInfo* next;       // link in chaining loop members
+  LoopMarks forward;    // accumulated marks in the forward direction
+  LoopMarks backward;   // accumulated marks in the backward direction
+  LoopMarks loop_mark;  // loop mark for header nodes; encodes loop_num
+
+  bool MarkBackward(LoopMarks bw) {
+    LoopMarks prev = backward;
+    LoopMarks next = backward | bw;
+    backward = next;
+    return prev != next;
+  }
+
+  bool MarkForward(LoopMarks fw) {
+    LoopMarks prev = forward;
+    LoopMarks next = forward | fw;
+    forward = next;
+    return prev != next;
+  }
+
+  bool IsInLoop(size_t loop_num) {
+    DCHECK(loop_num > 0 && loop_num <= 31);
+    return forward & backward & (1 << loop_num);
+  }
+
+  bool IsLoopHeader() { return loop_mark != 0; }
+  bool IsInAnyLoop() { return (forward & backward) > kVisited; }
+
+  bool IsInHeaderForLoop(size_t loop_num) {
+    DCHECK(loop_num > 0);
+    return loop_mark == (kVisited | (1 << loop_num));
+  }
+};
+
+
+// Temporary loop info needed during traversal and building the loop tree.
+struct LoopInfo {
+  Node* header;
+  NodeInfo* header_list;
+  NodeInfo* body_list;
+  LoopTree::Loop* loop;
+};
+
+
+static const NodeInfo kEmptyNodeInfo = {nullptr, nullptr, 0, 0, 0};
+
+
+// Encapsulation of the loop finding algorithm.
+// -----------------------------------------------------------------------------
+// Conceptually, the contents of a loop are those nodes that are "between" the
+// loop header and the backedges of the loop. Graphs in the soup of nodes can
+// form improper cycles, so standard loop finding algorithms that work on CFGs
+// aren't sufficient. However, in valid TurboFan graphs, all cycles involve
+// either a {Loop} node or a phi. The {Loop} node itself and its accompanying
+// phis are treated together as a set referred to here as the loop header.
+// This loop finding algorithm works by traversing the graph in two directions,
+// first from nodes to their inputs, starting at {end}, then in the reverse
+// direction, from nodes to their uses, starting at loop headers.
+// 1 bit per loop per node per direction are required during the marking phase.
+// To handle nested loops correctly, the algorithm must filter some reachability
+// marks on edges into/out-of the loop header nodes.
+class LoopFinderImpl {
+ public:
+  LoopFinderImpl(Graph* graph, LoopTree* loop_tree, Zone* zone)
+      : end_(graph->end()),
+        queue_(zone),
+        queued_(graph, 2),
+        info_(graph->NodeCount(), kEmptyNodeInfo, zone),
+        loops_(zone),
+        loop_tree_(loop_tree),
+        loops_found_(0) {}
+
+  void Run() {
+    PropagateBackward();
+    PropagateForward();
+    FinishLoopTree();
+  }
+
+  void Print() {
+    // Print out the results.
+    for (NodeInfo& ni : info_) {
+      if (ni.node == nullptr) continue;
+      for (size_t i = 1; i <= loops_.size(); i++) {
+        if (ni.IsInLoop(i)) {
+          PrintF("X");
+        } else if (ni.forward & (1 << i)) {
+          PrintF("/");
+        } else if (ni.backward & (1 << i)) {
+          PrintF("\\");
+        } else {
+          PrintF(" ");
+        }
+      }
+      PrintF(" #%d:%s\n", ni.node->id(), ni.node->op()->mnemonic());
+    }
+
+    int i = 0;
+    for (LoopInfo& li : loops_) {
+      PrintF("Loop %d headed at #%d\n", i, li.header->id());
+      i++;
+    }
+
+    for (LoopTree::Loop* loop : loop_tree_->outer_loops_) {
+      PrintLoop(loop);
+    }
+  }
+
+ private:
+  Node* end_;
+  NodeDeque queue_;
+  NodeMarker<bool> queued_;
+  ZoneVector<NodeInfo> info_;
+  ZoneVector<LoopInfo> loops_;
+  LoopTree* loop_tree_;
+  size_t loops_found_;
+
+  // Propagate marks backward from loop headers.
+  void PropagateBackward() {
+    PropagateBackward(end_, kVisited);
+
+    while (!queue_.empty()) {
+      Node* node = queue_.front();
+      queue_.pop_front();
+      queued_.Set(node, false);
+
+      // Setup loop headers first.
+      if (node->opcode() == IrOpcode::kLoop) {
+        // found the loop node first.
+        CreateLoopInfo(node);
+      } else if (node->opcode() == IrOpcode::kPhi ||
+                 node->opcode() == IrOpcode::kEffectPhi) {
+        // found a phi first.
+        Node* merge = node->InputAt(node->InputCount() - 1);
+        if (merge->opcode() == IrOpcode::kLoop) CreateLoopInfo(merge);
+      }
+
+      // Propagate reachability marks backwards from this node.
+      NodeInfo& ni = info(node);
+      if (ni.IsLoopHeader()) {
+        // Handle edges from loop header nodes specially.
+        for (int i = 0; i < node->InputCount(); i++) {
+          if (i == kAssumedLoopEntryIndex) {
+            // Don't propagate the loop mark backwards on the entry edge.
+            PropagateBackward(node->InputAt(0),
+                              kVisited | (ni.backward & ~ni.loop_mark));
+          } else {
+            // Only propagate the loop mark on backedges.
+            PropagateBackward(node->InputAt(i), ni.loop_mark);
+          }
+        }
+      } else {
+        // Propagate all loop marks backwards for a normal node.
+        for (Node* const input : node->inputs()) {
+          PropagateBackward(input, ni.backward);
+        }
+      }
+    }
+  }
+
+  // Make a new loop header for the given node.
+  void CreateLoopInfo(Node* node) {
+    NodeInfo& ni = info(node);
+    if (ni.IsLoopHeader()) return;  // loop already set up.
+
+    loops_found_++;
+    size_t loop_num = loops_.size() + 1;
+    CHECK(loops_found_ <= kMaxLoops);  // TODO(titzer): don't crash.
+    // Create a new loop.
+    loops_.push_back({node, nullptr, nullptr, nullptr});
+    loop_tree_->NewLoop();
+    LoopMarks loop_mark = kVisited | (1 << loop_num);
+    ni.node = node;
+    ni.loop_mark = loop_mark;
+
+    // Setup loop mark for phis attached to loop header.
+    for (Node* use : node->uses()) {
+      if (use->opcode() == IrOpcode::kPhi ||
+          use->opcode() == IrOpcode::kEffectPhi) {
+        info(use).loop_mark = loop_mark;
+      }
+    }
+  }
+
+  // Propagate marks forward from loops.
+  void PropagateForward() {
+    for (LoopInfo& li : loops_) {
+      queued_.Set(li.header, true);
+      queue_.push_back(li.header);
+      NodeInfo& ni = info(li.header);
+      ni.forward = ni.loop_mark;
+    }
+    // Propagate forward on paths that were backward reachable from backedges.
+    while (!queue_.empty()) {
+      Node* node = queue_.front();
+      queue_.pop_front();
+      queued_.Set(node, false);
+      NodeInfo& ni = info(node);
+      for (Edge edge : node->use_edges()) {
+        Node* use = edge.from();
+        NodeInfo& ui = info(use);
+        if (IsBackedge(use, ui, edge)) continue;  // skip backedges.
+        LoopMarks both = ni.forward & ui.backward;
+        if (ui.MarkForward(both) && !queued_.Get(use)) {
+          queued_.Set(use, true);
+          queue_.push_back(use);
+        }
+      }
+    }
+  }
+
+  bool IsBackedge(Node* use, NodeInfo& ui, Edge& edge) {
+    // TODO(titzer): checking for backedges here is ugly.
+    if (!ui.IsLoopHeader()) return false;
+    if (edge.index() == kAssumedLoopEntryIndex) return false;
+    if (use->opcode() == IrOpcode::kPhi ||
+        use->opcode() == IrOpcode::kEffectPhi) {
+      return !NodeProperties::IsControlEdge(edge);
+    }
+    return true;
+  }
+
+  NodeInfo& info(Node* node) {
+    NodeInfo& i = info_[node->id()];
+    if (i.node == nullptr) i.node = node;
+    return i;
+  }
+
+  void PropagateBackward(Node* node, LoopMarks marks) {
+    if (info(node).MarkBackward(marks) && !queued_.Get(node)) {
+      queue_.push_back(node);
+      queued_.Set(node, true);
+    }
+  }
+
+  void FinishLoopTree() {
+    // Degenerate cases.
+    if (loops_.size() == 0) return;
+    if (loops_.size() == 1) return FinishSingleLoop();
+
+    for (size_t i = 1; i <= loops_.size(); i++) ConnectLoopTree(i);
+
+    size_t count = 0;
+    // Place the node into the innermost nested loop of which it is a member.
+    for (NodeInfo& ni : info_) {
+      if (ni.node == nullptr || !ni.IsInAnyLoop()) continue;
+
+      LoopInfo* innermost = nullptr;
+      size_t index = 0;
+      for (size_t i = 1; i <= loops_.size(); i++) {
+        if (ni.IsInLoop(i)) {
+          LoopInfo* loop = &loops_[i - 1];
+          if (innermost == nullptr ||
+              loop->loop->depth_ > innermost->loop->depth_) {
+            innermost = loop;
+            index = i;
+          }
+        }
+      }
+      if (ni.IsInHeaderForLoop(index)) {
+        ni.next = innermost->header_list;
+        innermost->header_list = &ni;
+      } else {
+        ni.next = innermost->body_list;
+        innermost->body_list = &ni;
+      }
+      count++;
+    }
+
+    // Serialize the node lists for loops into the loop tree.
+    loop_tree_->loop_nodes_.reserve(count);
+    for (LoopTree::Loop* loop : loop_tree_->outer_loops_) {
+      SerializeLoop(loop);
+    }
+  }
+
+  // Handle the simpler case of a single loop (no checks for nesting necessary).
+  void FinishSingleLoop() {
+    DCHECK(loops_.size() == 1);
+    DCHECK(loop_tree_->all_loops_.size() == 1);
+
+    // Place nodes into the loop header and body.
+    LoopInfo* li = &loops_[0];
+    li->loop = &loop_tree_->all_loops_[0];
+    loop_tree_->SetParent(nullptr, li->loop);
+    size_t count = 0;
+    for (NodeInfo& ni : info_) {
+      if (ni.node == nullptr || !ni.IsInAnyLoop()) continue;
+      DCHECK(ni.IsInLoop(1));
+      if (ni.IsInHeaderForLoop(1)) {
+        ni.next = li->header_list;
+        li->header_list = &ni;
+      } else {
+        ni.next = li->body_list;
+        li->body_list = &ni;
+      }
+      count++;
+    }
+
+    // Serialize the node lists for the loop into the loop tree.
+    loop_tree_->loop_nodes_.reserve(count);
+    SerializeLoop(li->loop);
+  }
+
+  // Recursively serialize the list of header nodes and body nodes
+  // so that nested loops occupy nested intervals.
+  void SerializeLoop(LoopTree::Loop* loop) {
+    size_t loop_num = loop_tree_->LoopNum(loop);
+    LoopInfo& li = loops_[loop_num - 1];
+
+    // Serialize the header.
+    loop->header_start_ = static_cast<int>(loop_tree_->loop_nodes_.size());
+    for (NodeInfo* ni = li.header_list; ni != nullptr; ni = ni->next) {
+      loop_tree_->loop_nodes_.push_back(ni->node);
+      // TODO(titzer): lift loop count restriction.
+      loop_tree_->node_to_loop_num_[ni->node->id()] =
+          static_cast<uint8_t>(loop_num);
+    }
+
+    // Serialize the body.
+    loop->body_start_ = static_cast<int>(loop_tree_->loop_nodes_.size());
+    for (NodeInfo* ni = li.body_list; ni != nullptr; ni = ni->next) {
+      loop_tree_->loop_nodes_.push_back(ni->node);
+      // TODO(titzer): lift loop count restriction.
+      loop_tree_->node_to_loop_num_[ni->node->id()] =
+          static_cast<uint8_t>(loop_num);
+    }
+
+    // Serialize nested loops.
+    for (LoopTree::Loop* child : loop->children_) SerializeLoop(child);
+
+    loop->body_end_ = static_cast<int>(loop_tree_->loop_nodes_.size());
+  }
+
+  // Connect the LoopTree loops to their parents recursively.
+  LoopTree::Loop* ConnectLoopTree(size_t loop_num) {
+    LoopInfo& li = loops_[loop_num - 1];
+    if (li.loop != nullptr) return li.loop;
+
+    NodeInfo& ni = info(li.header);
+    LoopTree::Loop* parent = nullptr;
+    for (size_t i = 1; i <= loops_.size(); i++) {
+      if (i == loop_num) continue;
+      if (ni.IsInLoop(i)) {
+        // recursively create potential parent loops first.
+        LoopTree::Loop* upper = ConnectLoopTree(i);
+        if (parent == nullptr || upper->depth_ > parent->depth_) {
+          parent = upper;
+        }
+      }
+    }
+    li.loop = &loop_tree_->all_loops_[loop_num - 1];
+    loop_tree_->SetParent(parent, li.loop);
+    return li.loop;
+  }
+
+  void PrintLoop(LoopTree::Loop* loop) {
+    for (int i = 0; i < loop->depth_; i++) PrintF("  ");
+    PrintF("Loop depth = %d ", loop->depth_);
+    int i = loop->header_start_;
+    while (i < loop->body_start_) {
+      PrintF(" H#%d", loop_tree_->loop_nodes_[i++]->id());
+    }
+    while (i < loop->body_end_) {
+      PrintF(" B#%d", loop_tree_->loop_nodes_[i++]->id());
+    }
+    PrintF("\n");
+    for (LoopTree::Loop* child : loop->children_) PrintLoop(child);
+  }
+};
+
+
+LoopTree* LoopFinder::BuildLoopTree(Graph* graph, Zone* zone) {
+  LoopTree* loop_tree =
+      new (graph->zone()) LoopTree(graph->NodeCount(), graph->zone());
+  LoopFinderImpl finder(graph, loop_tree, zone);
+  finder.Run();
+  if (FLAG_trace_turbo_graph) {
+    finder.Print();
+  }
+  return loop_tree;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/loop-analysis.h b/src/compiler/loop-analysis.h
new file mode 100644
index 0000000..8c8d19a
--- /dev/null
+++ b/src/compiler/loop-analysis.h
@@ -0,0 +1,135 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_LOOP_ANALYSIS_H_
+#define V8_COMPILER_LOOP_ANALYSIS_H_
+
+#include "src/base/iterator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/node.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class LoopFinderImpl;
+
+typedef base::iterator_range<Node**> NodeRange;
+
+// Represents a tree of loops in a graph.
+class LoopTree : public ZoneObject {
+ public:
+  LoopTree(size_t num_nodes, Zone* zone)
+      : zone_(zone),
+        outer_loops_(zone),
+        all_loops_(zone),
+        node_to_loop_num_(static_cast<int>(num_nodes), 0, zone),
+        loop_nodes_(zone) {}
+
+  // Represents a loop in the tree of loops, including the header nodes,
+  // the body, and any nested loops.
+  class Loop {
+   public:
+    Loop* parent() const { return parent_; }
+    const ZoneVector<Loop*>& children() const { return children_; }
+    size_t HeaderSize() const { return body_start_ - header_start_; }
+    size_t BodySize() const { return body_end_ - body_start_; }
+    size_t TotalSize() const { return body_end_ - header_start_; }
+
+   private:
+    friend class LoopTree;
+    friend class LoopFinderImpl;
+
+    explicit Loop(Zone* zone)
+        : parent_(nullptr),
+          depth_(0),
+          children_(zone),
+          header_start_(-1),
+          body_start_(-1),
+          body_end_(-1) {}
+    Loop* parent_;
+    int depth_;
+    ZoneVector<Loop*> children_;
+    int header_start_;
+    int body_start_;
+    int body_end_;
+  };
+
+  // Return the innermost nested loop, if any, that contains {node}.
+  Loop* ContainingLoop(Node* node) {
+    if (node->id() >= static_cast<int>(node_to_loop_num_.size()))
+      return nullptr;
+    uint8_t num = node_to_loop_num_[node->id()];
+    return num > 0 ? &all_loops_[num - 1] : nullptr;
+  }
+
+  // Check if the {loop} contains the {node}, either directly or by containing
+  // a nested loop that contains {node}.
+  bool Contains(Loop* loop, Node* node) {
+    for (Loop* c = ContainingLoop(node); c != nullptr; c = c->parent_) {
+      if (c == loop) return true;
+    }
+    return false;
+  }
+
+  // Return the list of outer loops.
+  const ZoneVector<Loop*>& outer_loops() const { return outer_loops_; }
+
+  // Return the unique loop number for a given loop. Loop numbers start at {1}.
+  int LoopNum(Loop* loop) const {
+    return 1 + static_cast<int>(loop - &all_loops_[0]);
+  }
+
+  // Return a range which can iterate over the header nodes of {loop}.
+  NodeRange HeaderNodes(Loop* loop) {
+    return NodeRange(&loop_nodes_[0] + loop->header_start_,
+                     &loop_nodes_[0] + loop->body_start_);
+  }
+
+  // Return a range which can iterate over the body nodes of {loop}.
+  NodeRange BodyNodes(Loop* loop) {
+    return NodeRange(&loop_nodes_[0] + loop->body_start_,
+                     &loop_nodes_[0] + loop->body_end_);
+  }
+
+ private:
+  friend class LoopFinderImpl;
+
+  Loop* NewLoop() {
+    all_loops_.push_back(Loop(zone_));
+    Loop* result = &all_loops_.back();
+    return result;
+  }
+
+  void SetParent(Loop* parent, Loop* child) {
+    if (parent != nullptr) {
+      parent->children_.push_back(child);
+      child->parent_ = parent;
+      child->depth_ = parent->depth_ + 1;
+    } else {
+      outer_loops_.push_back(child);
+    }
+  }
+
+  Zone* zone_;
+  ZoneVector<Loop*> outer_loops_;
+  ZoneVector<Loop> all_loops_;
+  // TODO(titzer): lift loop count restriction.
+  ZoneVector<uint8_t> node_to_loop_num_;
+  ZoneVector<Node*> loop_nodes_;
+};
+
+
+class LoopFinder {
+ public:
+  // Build a loop tree for the entire graph.
+  static LoopTree* BuildLoopTree(Graph* graph, Zone* temp_zone);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_LOOP_ANALYSIS_H_
diff --git a/src/compiler/machine-operator-reducer-unittest.cc b/src/compiler/machine-operator-reducer-unittest.cc
deleted file mode 100644
index f3073ab..0000000
--- a/src/compiler/machine-operator-reducer-unittest.cc
+++ /dev/null
@@ -1,616 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/base/bits.h"
-#include "src/compiler/graph-unittest.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/machine-operator-reducer.h"
-#include "src/compiler/typer.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class MachineOperatorReducerTest : public GraphTest {
- public:
-  explicit MachineOperatorReducerTest(int num_parameters = 2)
-      : GraphTest(num_parameters) {}
-
- protected:
-  Reduction Reduce(Node* node) {
-    Typer typer(zone());
-    JSOperatorBuilder javascript(zone());
-    JSGraph jsgraph(graph(), common(), &javascript, &typer, &machine_);
-    MachineOperatorReducer reducer(&jsgraph);
-    return reducer.Reduce(node);
-  }
-
-  MachineOperatorBuilder* machine() { return &machine_; }
-
- private:
-  MachineOperatorBuilder machine_;
-};
-
-
-template <typename T>
-class MachineOperatorReducerTestWithParam
-    : public MachineOperatorReducerTest,
-      public ::testing::WithParamInterface<T> {
- public:
-  explicit MachineOperatorReducerTestWithParam(int num_parameters = 2)
-      : MachineOperatorReducerTest(num_parameters) {}
-  virtual ~MachineOperatorReducerTestWithParam() {}
-};
-
-
-namespace {
-
-static const float kFloat32Values[] = {
-    -std::numeric_limits<float>::infinity(), -2.70497e+38f, -1.4698e+37f,
-    -1.22813e+35f,                           -1.20555e+35f, -1.34584e+34f,
-    -1.0079e+32f,                            -6.49364e+26f, -3.06077e+25f,
-    -1.46821e+25f,                           -1.17658e+23f, -1.9617e+22f,
-    -2.7357e+20f,                            -1.48708e+13f, -1.89633e+12f,
-    -4.66622e+11f,                           -2.22581e+11f, -1.45381e+10f,
-    -1.3956e+09f,                            -1.32951e+09f, -1.30721e+09f,
-    -1.19756e+09f,                           -9.26822e+08f, -6.35647e+08f,
-    -4.00037e+08f,                           -1.81227e+08f, -5.09256e+07f,
-    -964300.0f,                              -192446.0f,    -28455.0f,
-    -27194.0f,                               -26401.0f,     -20575.0f,
-    -17069.0f,                               -9167.0f,      -960.178f,
-    -113.0f,                                 -62.0f,        -15.0f,
-    -7.0f,                                   -0.0256635f,   -4.60374e-07f,
-    -3.63759e-10f,                           -4.30175e-14f, -5.27385e-15f,
-    -1.48084e-15f,                           -1.05755e-19f, -3.2995e-21f,
-    -1.67354e-23f,                           -1.11885e-23f, -1.78506e-30f,
-    -5.07594e-31f,                           -3.65799e-31f, -1.43718e-34f,
-    -1.27126e-38f,                           -0.0f,         0.0f,
-    1.17549e-38f,                            1.56657e-37f,  4.08512e-29f,
-    3.31357e-28f,                            6.25073e-22f,  4.1723e-13f,
-    1.44343e-09f,                            5.27004e-08f,  9.48298e-08f,
-    5.57888e-07f,                            4.89988e-05f,  0.244326f,
-    12.4895f,                                19.0f,         47.0f,
-    106.0f,                                  538.324f,      564.536f,
-    819.124f,                                7048.0f,       12611.0f,
-    19878.0f,                                20309.0f,      797056.0f,
-    1.77219e+09f,                            1.51116e+11f,  4.18193e+13f,
-    3.59167e+16f,                            3.38211e+19f,  2.67488e+20f,
-    1.78831e+21f,                            9.20914e+21f,  8.35654e+23f,
-    1.4495e+24f,                             5.94015e+25f,  4.43608e+30f,
-    2.44502e+33f,                            2.61152e+33f,  1.38178e+37f,
-    1.71306e+37f,                            3.31899e+38f,  3.40282e+38f,
-    std::numeric_limits<float>::infinity()};
-
-
-static const double kFloat64Values[] = {
-    -V8_INFINITY,  -4.23878e+275, -5.82632e+265, -6.60355e+220, -6.26172e+212,
-    -2.56222e+211, -4.82408e+201, -1.84106e+157, -1.63662e+127, -1.55772e+100,
-    -1.67813e+72,  -2.3382e+55,   -3.179e+30,    -1.441e+09,    -1.0647e+09,
-    -7.99361e+08,  -5.77375e+08,  -2.20984e+08,  -32757,        -13171,
-    -9970,         -3984,         -107,          -105,          -92,
-    -77,           -61,           -0.000208163,  -1.86685e-06,  -1.17296e-10,
-    -9.26358e-11,  -5.08004e-60,  -1.74753e-65,  -1.06561e-71,  -5.67879e-79,
-    -5.78459e-130, -2.90989e-171, -7.15489e-243, -3.76242e-252, -1.05639e-263,
-    -4.40497e-267, -2.19666e-273, -4.9998e-276,  -5.59821e-278, -2.03855e-282,
-    -5.99335e-283, -7.17554e-284, -3.11744e-309, -0.0,          0.0,
-    2.22507e-308,  1.30127e-270,  7.62898e-260,  4.00313e-249,  3.16829e-233,
-    1.85244e-228,  2.03544e-129,  1.35126e-110,  1.01182e-106,  5.26333e-94,
-    1.35292e-90,   2.85394e-83,   1.78323e-77,   5.4967e-57,    1.03207e-25,
-    4.57401e-25,   1.58738e-05,   2,             125,           2310,
-    9636,          14802,         17168,         28945,         29305,
-    4.81336e+07,   1.41207e+08,   4.65962e+08,   1.40499e+09,   2.12648e+09,
-    8.80006e+30,   1.4446e+45,    1.12164e+54,   2.48188e+89,   6.71121e+102,
-    3.074e+112,    4.9699e+152,   5.58383e+166,  4.30654e+172,  7.08824e+185,
-    9.6586e+214,   2.028e+223,    6.63277e+243,  1.56192e+261,  1.23202e+269,
-    5.72883e+289,  8.5798e+290,   1.40256e+294,  1.79769e+308,  V8_INFINITY};
-
-
-static const int32_t kInt32Values[] = {
-    -2147483647 - 1, -1914954528, -1698749618, -1578693386, -1577976073,
-    -1573998034,     -1529085059, -1499540537, -1299205097, -1090814845,
-    -938186388,      -806828902,  -750927650,  -520676892,  -513661538,
-    -453036354,      -433622833,  -282638793,  -28375,      -27788,
-    -22770,          -18806,      -14173,      -11956,      -11200,
-    -10212,          -8160,       -3751,       -2758,       -1522,
-    -121,            -120,        -118,        -117,        -106,
-    -84,             -80,         -74,         -59,         -52,
-    -48,             -39,         -35,         -17,         -11,
-    -10,             -9,          -7,          -5,          0,
-    9,               12,          17,          23,          29,
-    31,              33,          35,          40,          47,
-    55,              56,          62,          64,          67,
-    68,              69,          74,          79,          84,
-    89,              90,          97,          104,         118,
-    124,             126,         127,         7278,        17787,
-    24136,           24202,       25570,       26680,       30242,
-    32399,           420886487,   642166225,   821912648,   822577803,
-    851385718,       1212241078,  1411419304,  1589626102,  1596437184,
-    1876245816,      1954730266,  2008792749,  2045320228,  2147483647};
-
-
-static const int64_t kInt64Values[] = {
-    V8_INT64_C(-9223372036854775807) - 1, V8_INT64_C(-8974392461363618006),
-    V8_INT64_C(-8874367046689588135),     V8_INT64_C(-8269197512118230839),
-    V8_INT64_C(-8146091527100606733),     V8_INT64_C(-7550917981466150848),
-    V8_INT64_C(-7216590251577894337),     V8_INT64_C(-6464086891160048440),
-    V8_INT64_C(-6365616494908257190),     V8_INT64_C(-6305630541365849726),
-    V8_INT64_C(-5982222642272245453),     V8_INT64_C(-5510103099058504169),
-    V8_INT64_C(-5496838675802432701),     V8_INT64_C(-4047626578868642657),
-    V8_INT64_C(-4033755046900164544),     V8_INT64_C(-3554299241457877041),
-    V8_INT64_C(-2482258764588614470),     V8_INT64_C(-1688515425526875335),
-    V8_INT64_C(-924784137176548532),      V8_INT64_C(-725316567157391307),
-    V8_INT64_C(-439022654781092241),      V8_INT64_C(-105545757668917080),
-    V8_INT64_C(-2088319373),              V8_INT64_C(-2073699916),
-    V8_INT64_C(-1844949911),              V8_INT64_C(-1831090548),
-    V8_INT64_C(-1756711933),              V8_INT64_C(-1559409497),
-    V8_INT64_C(-1281179700),              V8_INT64_C(-1211513985),
-    V8_INT64_C(-1182371520),              V8_INT64_C(-785934753),
-    V8_INT64_C(-767480697),               V8_INT64_C(-705745662),
-    V8_INT64_C(-514362436),               V8_INT64_C(-459916580),
-    V8_INT64_C(-312328082),               V8_INT64_C(-302949707),
-    V8_INT64_C(-285499304),               V8_INT64_C(-125701262),
-    V8_INT64_C(-95139843),                V8_INT64_C(-32768),
-    V8_INT64_C(-27542),                   V8_INT64_C(-23600),
-    V8_INT64_C(-18582),                   V8_INT64_C(-17770),
-    V8_INT64_C(-9086),                    V8_INT64_C(-9010),
-    V8_INT64_C(-8244),                    V8_INT64_C(-2890),
-    V8_INT64_C(-103),                     V8_INT64_C(-34),
-    V8_INT64_C(-27),                      V8_INT64_C(-25),
-    V8_INT64_C(-9),                       V8_INT64_C(-7),
-    V8_INT64_C(0),                        V8_INT64_C(2),
-    V8_INT64_C(38),                       V8_INT64_C(58),
-    V8_INT64_C(65),                       V8_INT64_C(93),
-    V8_INT64_C(111),                      V8_INT64_C(1003),
-    V8_INT64_C(1267),                     V8_INT64_C(12797),
-    V8_INT64_C(23122),                    V8_INT64_C(28200),
-    V8_INT64_C(30888),                    V8_INT64_C(42648848),
-    V8_INT64_C(116836693),                V8_INT64_C(263003643),
-    V8_INT64_C(571039860),                V8_INT64_C(1079398689),
-    V8_INT64_C(1145196402),               V8_INT64_C(1184846321),
-    V8_INT64_C(1758281648),               V8_INT64_C(1859991374),
-    V8_INT64_C(1960251588),               V8_INT64_C(2042443199),
-    V8_INT64_C(296220586027987448),       V8_INT64_C(1015494173071134726),
-    V8_INT64_C(1151237951914455318),      V8_INT64_C(1331941174616854174),
-    V8_INT64_C(2022020418667972654),      V8_INT64_C(2450251424374977035),
-    V8_INT64_C(3668393562685561486),      V8_INT64_C(4858229301215502171),
-    V8_INT64_C(4919426235170669383),      V8_INT64_C(5034286595330341762),
-    V8_INT64_C(5055797915536941182),      V8_INT64_C(6072389716149252074),
-    V8_INT64_C(6185309910199801210),      V8_INT64_C(6297328311011094138),
-    V8_INT64_C(6932372858072165827),      V8_INT64_C(8483640924987737210),
-    V8_INT64_C(8663764179455849203),      V8_INT64_C(8877197042645298254),
-    V8_INT64_C(8901543506779157333),      V8_INT64_C(9223372036854775807)};
-
-
-static const uint32_t kUint32Values[] = {
-    0x00000000, 0x00000001, 0xffffffff, 0x1b09788b, 0x04c5fce8, 0xcc0de5bf,
-    0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344,
-    0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c,
-    0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00,
-    0x761c4761, 0x80000000, 0x88888888, 0xa0000000, 0xdddddddd, 0xe0000000,
-    0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff,
-    0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, 0x0000ffff, 0x00007fff,
-    0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff};
-
-}  // namespace
-
-
-// -----------------------------------------------------------------------------
-// Unary operators
-
-
-namespace {
-
-struct UnaryOperator {
-  const Operator* (MachineOperatorBuilder::*constructor)();
-  const char* constructor_name;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) {
-  return os << unop.constructor_name;
-}
-
-
-static const UnaryOperator kUnaryOperators[] = {
-    {&MachineOperatorBuilder::ChangeInt32ToFloat64, "ChangeInt32ToFloat64"},
-    {&MachineOperatorBuilder::ChangeUint32ToFloat64, "ChangeUint32ToFloat64"},
-    {&MachineOperatorBuilder::ChangeFloat64ToInt32, "ChangeFloat64ToInt32"},
-    {&MachineOperatorBuilder::ChangeFloat64ToUint32, "ChangeFloat64ToUint32"},
-    {&MachineOperatorBuilder::ChangeInt32ToInt64, "ChangeInt32ToInt64"},
-    {&MachineOperatorBuilder::ChangeUint32ToUint64, "ChangeUint32ToUint64"},
-    {&MachineOperatorBuilder::TruncateFloat64ToInt32, "TruncateFloat64ToInt32"},
-    {&MachineOperatorBuilder::TruncateInt64ToInt32, "TruncateInt64ToInt32"}};
-
-}  // namespace
-
-
-typedef MachineOperatorReducerTestWithParam<UnaryOperator>
-    MachineUnaryOperatorReducerTest;
-
-
-TEST_P(MachineUnaryOperatorReducerTest, Parameter) {
-  const UnaryOperator unop = GetParam();
-  Reduction reduction =
-      Reduce(graph()->NewNode((machine()->*unop.constructor)(), Parameter(0)));
-  EXPECT_FALSE(reduction.Changed());
-}
-
-
-INSTANTIATE_TEST_CASE_P(MachineOperatorReducerTest,
-                        MachineUnaryOperatorReducerTest,
-                        ::testing::ValuesIn(kUnaryOperators));
-
-
-// -----------------------------------------------------------------------------
-// ChangeFloat64ToFloat32
-
-
-TEST_F(MachineOperatorReducerTest, ChangeFloat64ToFloat32WithConstant) {
-  TRACED_FOREACH(float, x, kFloat32Values) {
-    Reduction reduction = Reduce(graph()->NewNode(
-        machine()->ChangeFloat32ToFloat64(), Float32Constant(x)));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsFloat64Constant(x));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeFloat64ToInt32
-
-
-TEST_F(MachineOperatorReducerTest,
-       ChangeFloat64ToInt32WithChangeInt32ToFloat64) {
-  Node* value = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      machine()->ChangeFloat64ToInt32(),
-      graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_EQ(value, reduction.replacement());
-}
-
-
-TEST_F(MachineOperatorReducerTest, ChangeFloat64ToInt32WithConstant) {
-  TRACED_FOREACH(int32_t, x, kInt32Values) {
-    Reduction reduction = Reduce(graph()->NewNode(
-        machine()->ChangeFloat64ToInt32(), Float64Constant(FastI2D(x))));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsInt32Constant(x));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeFloat64ToUint32
-
-
-TEST_F(MachineOperatorReducerTest,
-       ChangeFloat64ToUint32WithChangeUint32ToFloat64) {
-  Node* value = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      machine()->ChangeFloat64ToUint32(),
-      graph()->NewNode(machine()->ChangeUint32ToFloat64(), value)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_EQ(value, reduction.replacement());
-}
-
-
-TEST_F(MachineOperatorReducerTest, ChangeFloat64ToUint32WithConstant) {
-  TRACED_FOREACH(uint32_t, x, kUint32Values) {
-    Reduction reduction = Reduce(graph()->NewNode(
-        machine()->ChangeFloat64ToUint32(), Float64Constant(FastUI2D(x))));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsInt32Constant(bit_cast<int32_t>(x)));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeInt32ToFloat64
-
-
-TEST_F(MachineOperatorReducerTest, ChangeInt32ToFloat64WithConstant) {
-  TRACED_FOREACH(int32_t, x, kInt32Values) {
-    Reduction reduction = Reduce(
-        graph()->NewNode(machine()->ChangeInt32ToFloat64(), Int32Constant(x)));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsFloat64Constant(FastI2D(x)));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeInt32ToInt64
-
-
-TEST_F(MachineOperatorReducerTest, ChangeInt32ToInt64WithConstant) {
-  TRACED_FOREACH(int32_t, x, kInt32Values) {
-    Reduction reduction = Reduce(
-        graph()->NewNode(machine()->ChangeInt32ToInt64(), Int32Constant(x)));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsInt64Constant(x));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeUint32ToFloat64
-
-
-TEST_F(MachineOperatorReducerTest, ChangeUint32ToFloat64WithConstant) {
-  TRACED_FOREACH(uint32_t, x, kUint32Values) {
-    Reduction reduction =
-        Reduce(graph()->NewNode(machine()->ChangeUint32ToFloat64(),
-                                Int32Constant(bit_cast<int32_t>(x))));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsFloat64Constant(FastUI2D(x)));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeUint32ToUint64
-
-
-TEST_F(MachineOperatorReducerTest, ChangeUint32ToUint64WithConstant) {
-  TRACED_FOREACH(uint32_t, x, kUint32Values) {
-    Reduction reduction =
-        Reduce(graph()->NewNode(machine()->ChangeUint32ToUint64(),
-                                Int32Constant(bit_cast<int32_t>(x))));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(),
-                IsInt64Constant(bit_cast<int64_t>(static_cast<uint64_t>(x))));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// TruncateFloat64ToFloat32
-
-
-TEST_F(MachineOperatorReducerTest,
-       TruncateFloat64ToFloat32WithChangeFloat32ToFloat64) {
-  Node* value = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      machine()->TruncateFloat64ToFloat32(),
-      graph()->NewNode(machine()->ChangeFloat32ToFloat64(), value)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_EQ(value, reduction.replacement());
-}
-
-
-TEST_F(MachineOperatorReducerTest, TruncateFloat64ToFloat32WithConstant) {
-  TRACED_FOREACH(double, x, kFloat64Values) {
-    Reduction reduction = Reduce(graph()->NewNode(
-        machine()->TruncateFloat64ToFloat32(), Float64Constant(x)));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsFloat32Constant(DoubleToFloat32(x)));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// TruncateFloat64ToInt32
-
-
-TEST_F(MachineOperatorReducerTest,
-       TruncateFloat64ToInt32WithChangeInt32ToFloat64) {
-  Node* value = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      machine()->TruncateFloat64ToInt32(),
-      graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_EQ(value, reduction.replacement());
-}
-
-
-TEST_F(MachineOperatorReducerTest, TruncateFloat64ToInt32WithConstant) {
-  TRACED_FOREACH(double, x, kFloat64Values) {
-    Reduction reduction = Reduce(graph()->NewNode(
-        machine()->TruncateFloat64ToInt32(), Float64Constant(x)));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(x)));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// TruncateInt64ToInt32
-
-
-TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithChangeInt32ToInt64) {
-  Node* value = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      machine()->TruncateInt64ToInt32(),
-      graph()->NewNode(machine()->ChangeInt32ToInt64(), value)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_EQ(value, reduction.replacement());
-}
-
-
-TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithConstant) {
-  TRACED_FOREACH(int64_t, x, kInt64Values) {
-    Reduction reduction = Reduce(
-        graph()->NewNode(machine()->TruncateInt64ToInt32(), Int64Constant(x)));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(),
-                IsInt32Constant(bit_cast<int32_t>(
-                    static_cast<uint32_t>(bit_cast<uint64_t>(x)))));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// Word32Ror
-
-
-TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithParameters) {
-  Node* value = Parameter(0);
-  Node* shift = Parameter(1);
-  Node* shl = graph()->NewNode(machine()->Word32Shl(), value, shift);
-  Node* shr = graph()->NewNode(
-      machine()->Word32Shr(), value,
-      graph()->NewNode(machine()->Int32Sub(), Int32Constant(32), shift));
-
-  // (x << y) | (x >> (32 - y)) => x ror y
-  Node* node1 = graph()->NewNode(machine()->Word32Or(), shl, shr);
-  Reduction reduction1 = Reduce(node1);
-  EXPECT_TRUE(reduction1.Changed());
-  EXPECT_EQ(reduction1.replacement(), node1);
-  EXPECT_THAT(reduction1.replacement(), IsWord32Ror(value, shift));
-
-  // (x >> (32 - y)) | (x << y) => x ror y
-  Node* node2 = graph()->NewNode(machine()->Word32Or(), shr, shl);
-  Reduction reduction2 = Reduce(node2);
-  EXPECT_TRUE(reduction2.Changed());
-  EXPECT_EQ(reduction2.replacement(), node2);
-  EXPECT_THAT(reduction2.replacement(), IsWord32Ror(value, shift));
-}
-
-
-TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithConstant) {
-  Node* value = Parameter(0);
-  TRACED_FORRANGE(int32_t, k, 0, 31) {
-    Node* shl =
-        graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(k));
-    Node* shr =
-        graph()->NewNode(machine()->Word32Shr(), value, Int32Constant(32 - k));
-
-    // (x << K) | (x >> ((32 - K) - y)) => x ror K
-    Node* node1 = graph()->NewNode(machine()->Word32Or(), shl, shr);
-    Reduction reduction1 = Reduce(node1);
-    EXPECT_TRUE(reduction1.Changed());
-    EXPECT_EQ(reduction1.replacement(), node1);
-    EXPECT_THAT(reduction1.replacement(),
-                IsWord32Ror(value, IsInt32Constant(k)));
-
-    // (x >> (32 - K)) | (x << K) => x ror K
-    Node* node2 = graph()->NewNode(machine()->Word32Or(), shr, shl);
-    Reduction reduction2 = Reduce(node2);
-    EXPECT_TRUE(reduction2.Changed());
-    EXPECT_EQ(reduction2.replacement(), node2);
-    EXPECT_THAT(reduction2.replacement(),
-                IsWord32Ror(value, IsInt32Constant(k)));
-  }
-}
-
-
-TEST_F(MachineOperatorReducerTest, Word32RorWithZeroShift) {
-  Node* value = Parameter(0);
-  Node* node =
-      graph()->NewNode(machine()->Word32Ror(), value, Int32Constant(0));
-  Reduction reduction = Reduce(node);
-  EXPECT_TRUE(reduction.Changed());
-  EXPECT_EQ(reduction.replacement(), value);
-}
-
-
-TEST_F(MachineOperatorReducerTest, Word32RorWithConstants) {
-  TRACED_FOREACH(int32_t, x, kUint32Values) {
-    TRACED_FORRANGE(int32_t, y, 0, 31) {
-      Node* node = graph()->NewNode(machine()->Word32Ror(), Int32Constant(x),
-                                    Int32Constant(y));
-      Reduction reduction = Reduce(node);
-      EXPECT_TRUE(reduction.Changed());
-      EXPECT_THAT(reduction.replacement(),
-                  IsInt32Constant(base::bits::RotateRight32(x, y)));
-    }
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// Int32AddWithOverflow
-
-
-TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithZero) {
-  Node* p0 = Parameter(0);
-  {
-    Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
-                                 Int32Constant(0), p0);
-
-    Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
-    ASSERT_TRUE(r.Changed());
-    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
-
-    r = Reduce(graph()->NewNode(common()->Projection(0), add));
-    ASSERT_TRUE(r.Changed());
-    EXPECT_EQ(p0, r.replacement());
-  }
-  {
-    Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), p0,
-                                 Int32Constant(0));
-
-    Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
-    ASSERT_TRUE(r.Changed());
-    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
-
-    r = Reduce(graph()->NewNode(common()->Projection(0), add));
-    ASSERT_TRUE(r.Changed());
-    EXPECT_EQ(p0, r.replacement());
-  }
-}
-
-
-TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithConstant) {
-  TRACED_FOREACH(int32_t, x, kInt32Values) {
-    TRACED_FOREACH(int32_t, y, kInt32Values) {
-      int32_t z;
-      Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
-                                   Int32Constant(x), Int32Constant(y));
-
-      Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
-      ASSERT_TRUE(r.Changed());
-      EXPECT_THAT(r.replacement(),
-                  IsInt32Constant(base::bits::SignedAddOverflow32(x, y, &z)));
-
-      r = Reduce(graph()->NewNode(common()->Projection(0), add));
-      ASSERT_TRUE(r.Changed());
-      EXPECT_THAT(r.replacement(), IsInt32Constant(z));
-    }
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// Int32SubWithOverflow
-
-
-TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithZero) {
-  Node* p0 = Parameter(0);
-  Node* add =
-      graph()->NewNode(machine()->Int32SubWithOverflow(), p0, Int32Constant(0));
-
-  Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
-  ASSERT_TRUE(r.Changed());
-  EXPECT_THAT(r.replacement(), IsInt32Constant(0));
-
-  r = Reduce(graph()->NewNode(common()->Projection(0), add));
-  ASSERT_TRUE(r.Changed());
-  EXPECT_EQ(p0, r.replacement());
-}
-
-
-TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithConstant) {
-  TRACED_FOREACH(int32_t, x, kInt32Values) {
-    TRACED_FOREACH(int32_t, y, kInt32Values) {
-      int32_t z;
-      Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(),
-                                   Int32Constant(x), Int32Constant(y));
-
-      Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
-      ASSERT_TRUE(r.Changed());
-      EXPECT_THAT(r.replacement(),
-                  IsInt32Constant(base::bits::SignedSubOverflow32(x, y, &z)));
-
-      r = Reduce(graph()->NewNode(common()->Projection(0), add));
-      ASSERT_TRUE(r.Changed());
-      EXPECT_THAT(r.replacement(), IsInt32Constant(z));
-    }
-  }
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/machine-operator-reducer.cc b/src/compiler/machine-operator-reducer.cc
index 9328547..c3e45a1 100644
--- a/src/compiler/machine-operator-reducer.cc
+++ b/src/compiler/machine-operator-reducer.cc
@@ -5,7 +5,9 @@
 #include "src/compiler/machine-operator-reducer.h"
 
 #include "src/base/bits.h"
-#include "src/compiler/generic-node-inl.h"
+#include "src/base/division-by-constant.h"
+#include "src/codegen.h"
+#include "src/compiler/diamond.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/node-matchers.h"
@@ -41,81 +43,90 @@
 }
 
 
+Node* MachineOperatorReducer::Word32And(Node* lhs, Node* rhs) {
+  Node* const node = graph()->NewNode(machine()->Word32And(), lhs, rhs);
+  Reduction const reduction = ReduceWord32And(node);
+  return reduction.Changed() ? reduction.replacement() : node;
+}
+
+
+Node* MachineOperatorReducer::Word32Sar(Node* lhs, uint32_t rhs) {
+  if (rhs == 0) return lhs;
+  return graph()->NewNode(machine()->Word32Sar(), lhs, Uint32Constant(rhs));
+}
+
+
+Node* MachineOperatorReducer::Word32Shr(Node* lhs, uint32_t rhs) {
+  if (rhs == 0) return lhs;
+  return graph()->NewNode(machine()->Word32Shr(), lhs, Uint32Constant(rhs));
+}
+
+
+Node* MachineOperatorReducer::Word32Equal(Node* lhs, Node* rhs) {
+  return graph()->NewNode(machine()->Word32Equal(), lhs, rhs);
+}
+
+
+Node* MachineOperatorReducer::Int32Add(Node* lhs, Node* rhs) {
+  Node* const node = graph()->NewNode(machine()->Int32Add(), lhs, rhs);
+  Reduction const reduction = ReduceInt32Add(node);
+  return reduction.Changed() ? reduction.replacement() : node;
+}
+
+
+Node* MachineOperatorReducer::Int32Sub(Node* lhs, Node* rhs) {
+  return graph()->NewNode(machine()->Int32Sub(), lhs, rhs);
+}
+
+
+Node* MachineOperatorReducer::Int32Mul(Node* lhs, Node* rhs) {
+  return graph()->NewNode(machine()->Int32Mul(), lhs, rhs);
+}
+
+
+Node* MachineOperatorReducer::Int32Div(Node* dividend, int32_t divisor) {
+  DCHECK_NE(0, divisor);
+  DCHECK_NE(std::numeric_limits<int32_t>::min(), divisor);
+  base::MagicNumbersForDivision<uint32_t> const mag =
+      base::SignedDivisionByConstant(bit_cast<uint32_t>(divisor));
+  Node* quotient = graph()->NewNode(machine()->Int32MulHigh(), dividend,
+                                    Uint32Constant(mag.multiplier));
+  if (divisor > 0 && bit_cast<int32_t>(mag.multiplier) < 0) {
+    quotient = Int32Add(quotient, dividend);
+  } else if (divisor < 0 && bit_cast<int32_t>(mag.multiplier) > 0) {
+    quotient = Int32Sub(quotient, dividend);
+  }
+  return Int32Add(Word32Sar(quotient, mag.shift), Word32Shr(dividend, 31));
+}
+
+
+Node* MachineOperatorReducer::Uint32Div(Node* dividend, uint32_t divisor) {
+  DCHECK_LT(0, divisor);
+  base::MagicNumbersForDivision<uint32_t> const mag =
+      base::UnsignedDivisionByConstant(bit_cast<uint32_t>(divisor));
+  Node* quotient = graph()->NewNode(machine()->Uint32MulHigh(), dividend,
+                                    Uint32Constant(mag.multiplier));
+  if (mag.add) {
+    DCHECK_LE(1, mag.shift);
+    quotient = Word32Shr(
+        Int32Add(Word32Shr(Int32Sub(dividend, quotient), 1), quotient),
+        mag.shift - 1);
+  } else {
+    quotient = Word32Shr(quotient, mag.shift);
+  }
+  return quotient;
+}
+
+
 // Perform constant folding and strength reduction on machine operators.
 Reduction MachineOperatorReducer::Reduce(Node* node) {
   switch (node->opcode()) {
     case IrOpcode::kProjection:
       return ReduceProjection(OpParameter<size_t>(node), node->InputAt(0));
-    case IrOpcode::kWord32And: {
-      Int32BinopMatcher m(node);
-      if (m.right().Is(0)) return Replace(m.right().node());  // x & 0  => 0
-      if (m.right().Is(-1)) return Replace(m.left().node());  // x & -1 => x
-      if (m.IsFoldable()) {                                   // K & K  => K
-        return ReplaceInt32(m.left().Value() & m.right().Value());
-      }
-      if (m.LeftEqualsRight()) return Replace(m.left().node());  // x & x => x
-      break;
-    }
-    case IrOpcode::kWord32Or: {
-      Int32BinopMatcher m(node);
-      if (m.right().Is(0)) return Replace(m.left().node());    // x | 0  => x
-      if (m.right().Is(-1)) return Replace(m.right().node());  // x | -1 => -1
-      if (m.IsFoldable()) {                                    // K | K  => K
-        return ReplaceInt32(m.left().Value() | m.right().Value());
-      }
-      if (m.LeftEqualsRight()) return Replace(m.left().node());  // x | x => x
-      if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) {
-        Int32BinopMatcher mleft(m.left().node());
-        Int32BinopMatcher mright(m.right().node());
-        if (mleft.left().node() == mright.left().node()) {
-          // (x << y) | (x >> (32 - y)) => x ror y
-          if (mright.right().IsInt32Sub()) {
-            Int32BinopMatcher mrightright(mright.right().node());
-            if (mrightright.left().Is(32) &&
-                mrightright.right().node() == mleft.right().node()) {
-              node->set_op(machine()->Word32Ror());
-              node->ReplaceInput(0, mleft.left().node());
-              node->ReplaceInput(1, mleft.right().node());
-              return Changed(node);
-            }
-          }
-          // (x << K) | (x >> (32 - K)) => x ror K
-          if (mleft.right().IsInRange(0, 31) &&
-              mright.right().Is(32 - mleft.right().Value())) {
-            node->set_op(machine()->Word32Ror());
-            node->ReplaceInput(0, mleft.left().node());
-            node->ReplaceInput(1, mleft.right().node());
-            return Changed(node);
-          }
-        }
-      }
-      if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) {
-        // (x >> (32 - y)) | (x << y)  => x ror y
-        Int32BinopMatcher mleft(m.left().node());
-        Int32BinopMatcher mright(m.right().node());
-        if (mleft.left().node() == mright.left().node()) {
-          if (mleft.right().IsInt32Sub()) {
-            Int32BinopMatcher mleftright(mleft.right().node());
-            if (mleftright.left().Is(32) &&
-                mleftright.right().node() == mright.right().node()) {
-              node->set_op(machine()->Word32Ror());
-              node->ReplaceInput(0, mright.left().node());
-              node->ReplaceInput(1, mright.right().node());
-              return Changed(node);
-            }
-          }
-          // (x >> (32 - K)) | (x << K) => x ror K
-          if (mright.right().IsInRange(0, 31) &&
-              mleft.right().Is(32 - mright.right().Value())) {
-            node->set_op(machine()->Word32Ror());
-            node->ReplaceInput(0, mright.left().node());
-            node->ReplaceInput(1, mright.right().node());
-            return Changed(node);
-          }
-        }
-      }
-      break;
-    }
+    case IrOpcode::kWord32And:
+      return ReduceWord32And(node);
+    case IrOpcode::kWord32Or:
+      return ReduceWord32Or(node);
     case IrOpcode::kWord32Xor: {
       Int32BinopMatcher m(node);
       if (m.right().Is(0)) return Replace(m.left().node());  // x ^ 0 => x
@@ -123,23 +134,23 @@
         return ReplaceInt32(m.left().Value() ^ m.right().Value());
       }
       if (m.LeftEqualsRight()) return ReplaceInt32(0);  // x ^ x => 0
-      break;
-    }
-    case IrOpcode::kWord32Shl: {
-      Int32BinopMatcher m(node);
-      if (m.right().Is(0)) return Replace(m.left().node());  // x << 0 => x
-      if (m.IsFoldable()) {                                  // K << K => K
-        return ReplaceInt32(m.left().Value() << m.right().Value());
+      if (m.left().IsWord32Xor() && m.right().Is(-1)) {
+        Int32BinopMatcher mleft(m.left().node());
+        if (mleft.right().Is(-1)) {  // (x ^ -1) ^ -1 => x
+          return Replace(mleft.left().node());
+        }
       }
       break;
     }
+    case IrOpcode::kWord32Shl:
+      return ReduceWord32Shl(node);
     case IrOpcode::kWord32Shr: {
       Uint32BinopMatcher m(node);
       if (m.right().Is(0)) return Replace(m.left().node());  // x >>> 0 => x
       if (m.IsFoldable()) {                                  // K >>> K => K
         return ReplaceInt32(m.left().Value() >> m.right().Value());
       }
-      break;
+      return ReduceWord32Shifts(node);
     }
     case IrOpcode::kWord32Sar: {
       Int32BinopMatcher m(node);
@@ -147,7 +158,22 @@
       if (m.IsFoldable()) {                                  // K >> K => K
         return ReplaceInt32(m.left().Value() >> m.right().Value());
       }
-      break;
+      if (m.left().IsWord32Shl()) {
+        Int32BinopMatcher mleft(m.left().node());
+        if (mleft.left().IsLoad()) {
+          LoadRepresentation const rep =
+              OpParameter<LoadRepresentation>(mleft.left().node());
+          if (m.right().Is(24) && mleft.right().Is(24) && rep == kMachInt8) {
+            // Load[kMachInt8] << 24 >> 24 => Load[kMachInt8]
+            return Replace(mleft.left().node());
+          }
+          if (m.right().Is(16) && mleft.right().Is(16) && rep == kMachInt16) {
+            // Load[kMachInt16] << 16 >> 16 => Load[kMachInt8]
+            return Replace(mleft.left().node());
+          }
+        }
+      }
+      return ReduceWord32Shifts(node);
     }
     case IrOpcode::kWord32Ror: {
       Int32BinopMatcher m(node);
@@ -173,15 +199,23 @@
       if (m.LeftEqualsRight()) return ReplaceBool(true);  // x == x => true
       break;
     }
-    case IrOpcode::kInt32Add: {
-      Int32BinopMatcher m(node);
-      if (m.right().Is(0)) return Replace(m.left().node());  // x + 0 => x
-      if (m.IsFoldable()) {                                  // K + K => K
-        return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) +
-                            static_cast<uint32_t>(m.right().Value()));
+    case IrOpcode::kWord64Equal: {
+      Int64BinopMatcher m(node);
+      if (m.IsFoldable()) {  // K == K => K
+        return ReplaceBool(m.left().Value() == m.right().Value());
       }
+      if (m.left().IsInt64Sub() && m.right().Is(0)) {  // x - y == 0 => x == y
+        Int64BinopMatcher msub(m.left().node());
+        node->ReplaceInput(0, msub.left().node());
+        node->ReplaceInput(1, msub.right().node());
+        return Changed(node);
+      }
+      // TODO(turbofan): fold HeapConstant, ExternalReference, pointer compares
+      if (m.LeftEqualsRight()) return ReplaceBool(true);  // x == x => true
       break;
     }
+    case IrOpcode::kInt32Add:
+      return ReduceInt32Add(node);
     case IrOpcode::kInt32Sub: {
       Int32BinopMatcher m(node);
       if (m.right().Is(0)) return Replace(m.left().node());  // x - 0 => x
@@ -208,74 +242,19 @@
       if (m.right().IsPowerOf2()) {  // x * 2^n => x << n
         node->set_op(machine()->Word32Shl());
         node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value())));
-        return Changed(node);
+        Reduction reduction = ReduceWord32Shl(node);
+        return reduction.Changed() ? reduction : Changed(node);
       }
       break;
     }
-    case IrOpcode::kInt32Div: {
-      Int32BinopMatcher m(node);
-      if (m.right().Is(1)) return Replace(m.left().node());  // x / 1 => x
-      // TODO(turbofan): if (m.left().Is(0))
-      // TODO(turbofan): if (m.right().IsPowerOf2())
-      // TODO(turbofan): if (m.right().Is(0))
-      // TODO(turbofan): if (m.LeftEqualsRight())
-      if (m.IsFoldable() && !m.right().Is(0)) {  // K / K => K
-        if (m.right().Is(-1)) return ReplaceInt32(-m.left().Value());
-        return ReplaceInt32(m.left().Value() / m.right().Value());
-      }
-      if (m.right().Is(-1)) {  // x / -1 => 0 - x
-        node->set_op(machine()->Int32Sub());
-        node->ReplaceInput(0, Int32Constant(0));
-        node->ReplaceInput(1, m.left().node());
-        return Changed(node);
-      }
-      break;
-    }
-    case IrOpcode::kInt32UDiv: {
-      Uint32BinopMatcher m(node);
-      if (m.right().Is(1)) return Replace(m.left().node());  // x / 1 => x
-      // TODO(turbofan): if (m.left().Is(0))
-      // TODO(turbofan): if (m.right().Is(0))
-      // TODO(turbofan): if (m.LeftEqualsRight())
-      if (m.IsFoldable() && !m.right().Is(0)) {  // K / K => K
-        return ReplaceInt32(m.left().Value() / m.right().Value());
-      }
-      if (m.right().IsPowerOf2()) {  // x / 2^n => x >> n
-        node->set_op(machine()->Word32Shr());
-        node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value())));
-        return Changed(node);
-      }
-      break;
-    }
-    case IrOpcode::kInt32Mod: {
-      Int32BinopMatcher m(node);
-      if (m.right().Is(1)) return ReplaceInt32(0);   // x % 1  => 0
-      if (m.right().Is(-1)) return ReplaceInt32(0);  // x % -1 => 0
-      // TODO(turbofan): if (m.left().Is(0))
-      // TODO(turbofan): if (m.right().IsPowerOf2())
-      // TODO(turbofan): if (m.right().Is(0))
-      // TODO(turbofan): if (m.LeftEqualsRight())
-      if (m.IsFoldable() && !m.right().Is(0)) {  // K % K => K
-        return ReplaceInt32(m.left().Value() % m.right().Value());
-      }
-      break;
-    }
-    case IrOpcode::kInt32UMod: {
-      Uint32BinopMatcher m(node);
-      if (m.right().Is(1)) return ReplaceInt32(0);  // x % 1 => 0
-      // TODO(turbofan): if (m.left().Is(0))
-      // TODO(turbofan): if (m.right().Is(0))
-      // TODO(turbofan): if (m.LeftEqualsRight())
-      if (m.IsFoldable() && !m.right().Is(0)) {  // K % K => K
-        return ReplaceInt32(m.left().Value() % m.right().Value());
-      }
-      if (m.right().IsPowerOf2()) {  // x % 2^n => x & 2^n-1
-        node->set_op(machine()->Word32And());
-        node->ReplaceInput(1, Int32Constant(m.right().Value() - 1));
-        return Changed(node);
-      }
-      break;
-    }
+    case IrOpcode::kInt32Div:
+      return ReduceInt32Div(node);
+    case IrOpcode::kUint32Div:
+      return ReduceUint32Div(node);
+    case IrOpcode::kInt32Mod:
+      return ReduceInt32Mod(node);
+    case IrOpcode::kUint32Mod:
+      return ReduceUint32Mod(node);
     case IrOpcode::kInt32LessThan: {
       Int32BinopMatcher m(node);
       if (m.IsFoldable()) {  // K < K => K
@@ -324,6 +303,21 @@
         return ReplaceBool(m.left().Value() < m.right().Value());
       }
       if (m.LeftEqualsRight()) return ReplaceBool(false);  // x < x => false
+      if (m.left().IsWord32Sar() && m.right().HasValue()) {
+        Int32BinopMatcher mleft(m.left().node());
+        if (mleft.right().HasValue()) {
+          // (x >> K) < C => x < (C << K)
+          // when C < (M >> K)
+          const uint32_t c = m.right().Value();
+          const uint32_t k = mleft.right().Value() & 0x1f;
+          if (c < static_cast<uint32_t>(kMaxInt >> k)) {
+            node->ReplaceInput(0, mleft.left().node());
+            node->ReplaceInput(1, Uint32Constant(c << k));
+            return Changed(node);
+          }
+          // TODO(turbofan): else the comparison is always true.
+        }
+      }
       break;
     }
     case IrOpcode::kUint32LessThanOrEqual: {
@@ -338,6 +332,9 @@
     }
     case IrOpcode::kFloat64Add: {
       Float64BinopMatcher m(node);
+      if (m.right().IsNaN()) {  // x + NaN => NaN
+        return Replace(m.right().node());
+      }
       if (m.IsFoldable()) {  // K + K => K
         return ReplaceFloat64(m.left().Value() + m.right().Value());
       }
@@ -345,6 +342,15 @@
     }
     case IrOpcode::kFloat64Sub: {
       Float64BinopMatcher m(node);
+      if (m.right().Is(0) && (Double(m.right().Value()).Sign() > 0)) {
+        return Replace(m.left().node());  // x - 0 => x
+      }
+      if (m.right().IsNaN()) {  // x - NaN => NaN
+        return Replace(m.right().node());
+      }
+      if (m.left().IsNaN()) {  // NaN - x => NaN
+        return Replace(m.left().node());
+      }
       if (m.IsFoldable()) {  // K - K => K
         return ReplaceFloat64(m.left().Value() - m.right().Value());
       }
@@ -352,6 +358,12 @@
     }
     case IrOpcode::kFloat64Mul: {
       Float64BinopMatcher m(node);
+      if (m.right().Is(-1)) {  // x * -1.0 => -0.0 - x
+        node->set_op(machine()->Float64Sub());
+        node->ReplaceInput(0, Float64Constant(-0.0));
+        node->ReplaceInput(1, m.left().node());
+        return Changed(node);
+      }
       if (m.right().Is(1)) return Replace(m.left().node());  // x * 1.0 => x
       if (m.right().IsNaN()) {                               // x * NaN => NaN
         return Replace(m.right().node());
@@ -377,6 +389,9 @@
     }
     case IrOpcode::kFloat64Mod: {
       Float64BinopMatcher m(node);
+      if (m.right().Is(0)) {  // x % 0 => NaN
+        return ReplaceFloat64(base::OS::nan_value());
+      }
       if (m.right().IsNaN()) {  // x % NaN => NaN
         return Replace(m.right().node());
       }
@@ -425,12 +440,8 @@
       if (m.HasValue()) return ReplaceInt64(static_cast<uint64_t>(m.Value()));
       break;
     }
-    case IrOpcode::kTruncateFloat64ToInt32: {
-      Float64Matcher m(node->InputAt(0));
-      if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
-      if (m.IsChangeInt32ToFloat64()) return Replace(m.node()->InputAt(0));
-      break;
-    }
+    case IrOpcode::kTruncateFloat64ToInt32:
+      return ReduceTruncateFloat64ToInt32(node);
     case IrOpcode::kTruncateInt64ToInt32: {
       Int64Matcher m(node->InputAt(0));
       if (m.HasValue()) return ReplaceInt32(static_cast<int32_t>(m.Value()));
@@ -443,6 +454,227 @@
       if (m.IsChangeFloat32ToFloat64()) return Replace(m.node()->InputAt(0));
       break;
     }
+    case IrOpcode::kStore:
+      return ReduceStore(node);
+    default:
+      break;
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceInt32Add(Node* node) {
+  DCHECK_EQ(IrOpcode::kInt32Add, node->opcode());
+  Int32BinopMatcher m(node);
+  if (m.right().Is(0)) return Replace(m.left().node());  // x + 0 => x
+  if (m.IsFoldable()) {                                  // K + K => K
+    return ReplaceUint32(bit_cast<uint32_t>(m.left().Value()) +
+                         bit_cast<uint32_t>(m.right().Value()));
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) {
+  Int32BinopMatcher m(node);
+  if (m.left().Is(0)) return Replace(m.left().node());    // 0 / x => 0
+  if (m.right().Is(0)) return Replace(m.right().node());  // x / 0 => 0
+  if (m.right().Is(1)) return Replace(m.left().node());   // x / 1 => x
+  if (m.IsFoldable()) {                                   // K / K => K
+    return ReplaceInt32(
+        base::bits::SignedDiv32(m.left().Value(), m.right().Value()));
+  }
+  if (m.LeftEqualsRight()) {  // x / x => x != 0
+    Node* const zero = Int32Constant(0);
+    return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
+  }
+  if (m.right().Is(-1)) {  // x / -1 => 0 - x
+    node->set_op(machine()->Int32Sub());
+    node->ReplaceInput(0, Int32Constant(0));
+    node->ReplaceInput(1, m.left().node());
+    node->TrimInputCount(2);
+    return Changed(node);
+  }
+  if (m.right().HasValue()) {
+    int32_t const divisor = m.right().Value();
+    Node* const dividend = m.left().node();
+    Node* quotient = dividend;
+    if (base::bits::IsPowerOfTwo32(Abs(divisor))) {
+      uint32_t const shift = WhichPowerOf2Abs(divisor);
+      DCHECK_NE(0, shift);
+      if (shift > 1) {
+        quotient = Word32Sar(quotient, 31);
+      }
+      quotient = Int32Add(Word32Shr(quotient, 32u - shift), dividend);
+      quotient = Word32Sar(quotient, shift);
+    } else {
+      quotient = Int32Div(quotient, Abs(divisor));
+    }
+    if (divisor < 0) {
+      node->set_op(machine()->Int32Sub());
+      node->ReplaceInput(0, Int32Constant(0));
+      node->ReplaceInput(1, quotient);
+      node->TrimInputCount(2);
+      return Changed(node);
+    }
+    return Replace(quotient);
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceUint32Div(Node* node) {
+  Uint32BinopMatcher m(node);
+  if (m.left().Is(0)) return Replace(m.left().node());    // 0 / x => 0
+  if (m.right().Is(0)) return Replace(m.right().node());  // x / 0 => 0
+  if (m.right().Is(1)) return Replace(m.left().node());   // x / 1 => x
+  if (m.IsFoldable()) {                                   // K / K => K
+    return ReplaceUint32(
+        base::bits::UnsignedDiv32(m.left().Value(), m.right().Value()));
+  }
+  if (m.LeftEqualsRight()) {  // x / x => x != 0
+    Node* const zero = Int32Constant(0);
+    return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
+  }
+  if (m.right().HasValue()) {
+    Node* const dividend = m.left().node();
+    uint32_t const divisor = m.right().Value();
+    if (base::bits::IsPowerOfTwo32(divisor)) {  // x / 2^n => x >> n
+      node->set_op(machine()->Word32Shr());
+      node->ReplaceInput(1, Uint32Constant(WhichPowerOf2(m.right().Value())));
+      node->TrimInputCount(2);
+      return Changed(node);
+    } else {
+      return Replace(Uint32Div(dividend, divisor));
+    }
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceInt32Mod(Node* node) {
+  Int32BinopMatcher m(node);
+  if (m.left().Is(0)) return Replace(m.left().node());    // 0 % x  => 0
+  if (m.right().Is(0)) return Replace(m.right().node());  // x % 0  => 0
+  if (m.right().Is(1)) return ReplaceInt32(0);            // x % 1  => 0
+  if (m.right().Is(-1)) return ReplaceInt32(0);           // x % -1 => 0
+  if (m.LeftEqualsRight()) return ReplaceInt32(0);        // x % x  => 0
+  if (m.IsFoldable()) {                                   // K % K => K
+    return ReplaceInt32(
+        base::bits::SignedMod32(m.left().Value(), m.right().Value()));
+  }
+  if (m.right().HasValue()) {
+    Node* const dividend = m.left().node();
+    int32_t const divisor = Abs(m.right().Value());
+    if (base::bits::IsPowerOfTwo32(divisor)) {
+      uint32_t const mask = divisor - 1;
+      Node* const zero = Int32Constant(0);
+      node->set_op(common()->Select(kMachInt32, BranchHint::kFalse));
+      node->ReplaceInput(
+          0, graph()->NewNode(machine()->Int32LessThan(), dividend, zero));
+      node->ReplaceInput(
+          1, Int32Sub(zero, Word32And(Int32Sub(zero, dividend), mask)));
+      node->ReplaceInput(2, Word32And(dividend, mask));
+    } else {
+      Node* quotient = Int32Div(dividend, divisor);
+      node->set_op(machine()->Int32Sub());
+      DCHECK_EQ(dividend, node->InputAt(0));
+      node->ReplaceInput(1, Int32Mul(quotient, Int32Constant(divisor)));
+      node->TrimInputCount(2);
+    }
+    return Changed(node);
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceUint32Mod(Node* node) {
+  Uint32BinopMatcher m(node);
+  if (m.left().Is(0)) return Replace(m.left().node());    // 0 % x => 0
+  if (m.right().Is(0)) return Replace(m.right().node());  // x % 0 => 0
+  if (m.right().Is(1)) return ReplaceUint32(0);           // x % 1 => 0
+  if (m.LeftEqualsRight()) return ReplaceInt32(0);        // x % x  => 0
+  if (m.IsFoldable()) {                                   // K % K => K
+    return ReplaceUint32(
+        base::bits::UnsignedMod32(m.left().Value(), m.right().Value()));
+  }
+  if (m.right().HasValue()) {
+    Node* const dividend = m.left().node();
+    uint32_t const divisor = m.right().Value();
+    if (base::bits::IsPowerOfTwo32(divisor)) {  // x % 2^n => x & 2^n-1
+      node->set_op(machine()->Word32And());
+      node->ReplaceInput(1, Uint32Constant(m.right().Value() - 1));
+    } else {
+      Node* quotient = Uint32Div(dividend, divisor);
+      node->set_op(machine()->Int32Sub());
+      DCHECK_EQ(dividend, node->InputAt(0));
+      node->ReplaceInput(1, Int32Mul(quotient, Uint32Constant(divisor)));
+    }
+    node->TrimInputCount(2);
+    return Changed(node);
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceTruncateFloat64ToInt32(Node* node) {
+  Float64Matcher m(node->InputAt(0));
+  if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
+  if (m.IsChangeInt32ToFloat64()) return Replace(m.node()->InputAt(0));
+  if (m.IsPhi()) {
+    Node* const phi = m.node();
+    DCHECK_EQ(kRepFloat64, RepresentationOf(OpParameter<MachineType>(phi)));
+    if (phi->OwnedBy(node)) {
+      // TruncateFloat64ToInt32(Phi[Float64](x1,...,xn))
+      //   => Phi[Int32](TruncateFloat64ToInt32(x1),
+      //                 ...,
+      //                 TruncateFloat64ToInt32(xn))
+      const int value_input_count = phi->InputCount() - 1;
+      for (int i = 0; i < value_input_count; ++i) {
+        Node* input = graph()->NewNode(machine()->TruncateFloat64ToInt32(),
+                                       phi->InputAt(i));
+        // TODO(bmeurer): Reschedule input for reduction once we have Revisit()
+        // instead of recursing into ReduceTruncateFloat64ToInt32() here.
+        Reduction reduction = ReduceTruncateFloat64ToInt32(input);
+        if (reduction.Changed()) input = reduction.replacement();
+        phi->ReplaceInput(i, input);
+      }
+      phi->set_op(common()->Phi(kMachInt32, value_input_count));
+      return Replace(phi);
+    }
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceStore(Node* node) {
+  MachineType const rep =
+      RepresentationOf(StoreRepresentationOf(node->op()).machine_type());
+  Node* const value = node->InputAt(2);
+  switch (value->opcode()) {
+    case IrOpcode::kWord32And: {
+      Uint32BinopMatcher m(value);
+      if (m.right().HasValue() &&
+          ((rep == kRepWord8 && (m.right().Value() & 0xff) == 0xff) ||
+           (rep == kRepWord16 && (m.right().Value() & 0xffff) == 0xffff))) {
+        node->ReplaceInput(2, m.left().node());
+        return Changed(node);
+      }
+      break;
+    }
+    case IrOpcode::kWord32Sar: {
+      Int32BinopMatcher m(value);
+      if (m.left().IsWord32Shl() &&
+          ((rep == kRepWord8 && m.right().IsInRange(1, 24)) ||
+           (rep == kRepWord16 && m.right().IsInRange(1, 16)))) {
+        Int32BinopMatcher mleft(m.left().node());
+        if (mleft.right().Is(m.right().Value())) {
+          node->ReplaceInput(2, mleft.left().node());
+          return Changed(node);
+        }
+      }
+      break;
+    }
     default:
       break;
   }
@@ -487,6 +719,192 @@
 }
 
 
+Reduction MachineOperatorReducer::ReduceWord32Shifts(Node* node) {
+  DCHECK((node->opcode() == IrOpcode::kWord32Shl) ||
+         (node->opcode() == IrOpcode::kWord32Shr) ||
+         (node->opcode() == IrOpcode::kWord32Sar));
+  if (machine()->Word32ShiftIsSafe()) {
+    // Remove the explicit 'and' with 0x1f if the shift provided by the machine
+    // instruction matches that required by JavaScript.
+    Int32BinopMatcher m(node);
+    if (m.right().IsWord32And()) {
+      Int32BinopMatcher mright(m.right().node());
+      if (mright.right().Is(0x1f)) {
+        node->ReplaceInput(1, mright.left().node());
+        return Changed(node);
+      }
+    }
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceWord32Shl(Node* node) {
+  DCHECK_EQ(IrOpcode::kWord32Shl, node->opcode());
+  Int32BinopMatcher m(node);
+  if (m.right().Is(0)) return Replace(m.left().node());  // x << 0 => x
+  if (m.IsFoldable()) {                                  // K << K => K
+    return ReplaceInt32(m.left().Value() << m.right().Value());
+  }
+  if (m.right().IsInRange(1, 31)) {
+    // (x >>> K) << K => x & ~(2^K - 1)
+    // (x >> K) << K => x & ~(2^K - 1)
+    if (m.left().IsWord32Sar() || m.left().IsWord32Shr()) {
+      Int32BinopMatcher mleft(m.left().node());
+      if (mleft.right().Is(m.right().Value())) {
+        node->set_op(machine()->Word32And());
+        node->ReplaceInput(0, mleft.left().node());
+        node->ReplaceInput(1,
+                           Uint32Constant(~((1U << m.right().Value()) - 1U)));
+        Reduction reduction = ReduceWord32And(node);
+        return reduction.Changed() ? reduction : Changed(node);
+      }
+    }
+  }
+  return ReduceWord32Shifts(node);
+}
+
+
+Reduction MachineOperatorReducer::ReduceWord32And(Node* node) {
+  DCHECK_EQ(IrOpcode::kWord32And, node->opcode());
+  Int32BinopMatcher m(node);
+  if (m.right().Is(0)) return Replace(m.right().node());  // x & 0  => 0
+  if (m.right().Is(-1)) return Replace(m.left().node());  // x & -1 => x
+  if (m.IsFoldable()) {                                   // K & K  => K
+    return ReplaceInt32(m.left().Value() & m.right().Value());
+  }
+  if (m.LeftEqualsRight()) return Replace(m.left().node());  // x & x => x
+  if (m.left().IsWord32And() && m.right().HasValue()) {
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.right().HasValue()) {  // (x & K) & K => x & K
+      node->ReplaceInput(0, mleft.left().node());
+      node->ReplaceInput(
+          1, Int32Constant(m.right().Value() & mleft.right().Value()));
+      Reduction const reduction = ReduceWord32And(node);
+      return reduction.Changed() ? reduction : Changed(node);
+    }
+  }
+  if (m.left().IsInt32Add() && m.right().IsNegativePowerOf2()) {
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.right().HasValue() &&
+        (mleft.right().Value() & m.right().Value()) == mleft.right().Value()) {
+      // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
+      node->set_op(machine()->Int32Add());
+      node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
+      node->ReplaceInput(1, mleft.right().node());
+      Reduction const reduction = ReduceInt32Add(node);
+      return reduction.Changed() ? reduction : Changed(node);
+    }
+    if (mleft.left().IsInt32Mul()) {
+      Int32BinopMatcher mleftleft(mleft.left().node());
+      if (mleftleft.right().IsMultipleOf(-m.right().Value())) {
+        // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
+        node->set_op(machine()->Int32Add());
+        node->ReplaceInput(0,
+                           Word32And(mleft.right().node(), m.right().node()));
+        node->ReplaceInput(1, mleftleft.node());
+        Reduction const reduction = ReduceInt32Add(node);
+        return reduction.Changed() ? reduction : Changed(node);
+      }
+    }
+    if (mleft.right().IsInt32Mul()) {
+      Int32BinopMatcher mleftright(mleft.right().node());
+      if (mleftright.right().IsMultipleOf(-m.right().Value())) {
+        // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
+        node->set_op(machine()->Int32Add());
+        node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
+        node->ReplaceInput(1, mleftright.node());
+        Reduction const reduction = ReduceInt32Add(node);
+        return reduction.Changed() ? reduction : Changed(node);
+      }
+    }
+    if (mleft.left().IsWord32Shl()) {
+      Int32BinopMatcher mleftleft(mleft.left().node());
+      if (mleftleft.right().Is(
+              base::bits::CountTrailingZeros32(m.right().Value()))) {
+        // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
+        node->set_op(machine()->Int32Add());
+        node->ReplaceInput(0,
+                           Word32And(mleft.right().node(), m.right().node()));
+        node->ReplaceInput(1, mleftleft.node());
+        Reduction const reduction = ReduceInt32Add(node);
+        return reduction.Changed() ? reduction : Changed(node);
+      }
+    }
+    if (mleft.right().IsWord32Shl()) {
+      Int32BinopMatcher mleftright(mleft.right().node());
+      if (mleftright.right().Is(
+              base::bits::CountTrailingZeros32(m.right().Value()))) {
+        // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
+        node->set_op(machine()->Int32Add());
+        node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
+        node->ReplaceInput(1, mleftright.node());
+        Reduction const reduction = ReduceInt32Add(node);
+        return reduction.Changed() ? reduction : Changed(node);
+      }
+    }
+  }
+  return NoChange();
+}
+
+
+Reduction MachineOperatorReducer::ReduceWord32Or(Node* node) {
+  DCHECK_EQ(IrOpcode::kWord32Or, node->opcode());
+  Int32BinopMatcher m(node);
+  if (m.right().Is(0)) return Replace(m.left().node());    // x | 0  => x
+  if (m.right().Is(-1)) return Replace(m.right().node());  // x | -1 => -1
+  if (m.IsFoldable()) {                                    // K | K  => K
+    return ReplaceInt32(m.left().Value() | m.right().Value());
+  }
+  if (m.LeftEqualsRight()) return Replace(m.left().node());  // x | x => x
+
+  Node* shl = NULL;
+  Node* shr = NULL;
+  // Recognize rotation, we are matching either:
+  //  * x << y | x >>> (32 - y) => x ror (32 - y), i.e  x rol y
+  //  * x << (32 - y) | x >>> y => x ror y
+  // as well as their commuted form.
+  if (m.left().IsWord32Shl() && m.right().IsWord32Shr()) {
+    shl = m.left().node();
+    shr = m.right().node();
+  } else if (m.left().IsWord32Shr() && m.right().IsWord32Shl()) {
+    shl = m.right().node();
+    shr = m.left().node();
+  } else {
+    return NoChange();
+  }
+
+  Int32BinopMatcher mshl(shl);
+  Int32BinopMatcher mshr(shr);
+  if (mshl.left().node() != mshr.left().node()) return NoChange();
+
+  if (mshl.right().HasValue() && mshr.right().HasValue()) {
+    // Case where y is a constant.
+    if (mshl.right().Value() + mshr.right().Value() != 32) return NoChange();
+  } else {
+    Node* sub = NULL;
+    Node* y = NULL;
+    if (mshl.right().IsInt32Sub()) {
+      sub = mshl.right().node();
+      y = mshr.right().node();
+    } else if (mshr.right().IsInt32Sub()) {
+      sub = mshr.right().node();
+      y = mshl.right().node();
+    } else {
+      return NoChange();
+    }
+
+    Int32BinopMatcher msub(sub);
+    if (!msub.left().Is(32) || msub.right().node() != y) return NoChange();
+  }
+
+  node->set_op(machine()->Word32Ror());
+  node->ReplaceInput(0, mshl.left().node());
+  node->ReplaceInput(1, mshr.right().node());
+  return Changed(node);
+}
+
+
 CommonOperatorBuilder* MachineOperatorReducer::common() const {
   return jsgraph()->common();
 }
diff --git a/src/compiler/machine-operator-reducer.h b/src/compiler/machine-operator-reducer.h
index c79ceae..8200abb 100644
--- a/src/compiler/machine-operator-reducer.h
+++ b/src/compiler/machine-operator-reducer.h
@@ -24,13 +24,28 @@
   explicit MachineOperatorReducer(JSGraph* jsgraph);
   ~MachineOperatorReducer();
 
-  virtual Reduction Reduce(Node* node) OVERRIDE;
+  Reduction Reduce(Node* node) OVERRIDE;
 
  private:
   Node* Float32Constant(volatile float value);
   Node* Float64Constant(volatile double value);
   Node* Int32Constant(int32_t value);
   Node* Int64Constant(int64_t value);
+  Node* Uint32Constant(uint32_t value) {
+    return Int32Constant(bit_cast<uint32_t>(value));
+  }
+  Node* Word32And(Node* lhs, Node* rhs);
+  Node* Word32And(Node* lhs, uint32_t rhs) {
+    return Word32And(lhs, Uint32Constant(rhs));
+  }
+  Node* Word32Sar(Node* lhs, uint32_t rhs);
+  Node* Word32Shr(Node* lhs, uint32_t rhs);
+  Node* Word32Equal(Node* lhs, Node* rhs);
+  Node* Int32Add(Node* lhs, Node* rhs);
+  Node* Int32Sub(Node* lhs, Node* rhs);
+  Node* Int32Mul(Node* lhs, Node* rhs);
+  Node* Int32Div(Node* dividend, int32_t divisor);
+  Node* Uint32Div(Node* dividend, uint32_t divisor);
 
   Reduction ReplaceBool(bool value) { return ReplaceInt32(value ? 1 : 0); }
   Reduction ReplaceFloat32(volatile float value) {
@@ -42,11 +57,25 @@
   Reduction ReplaceInt32(int32_t value) {
     return Replace(Int32Constant(value));
   }
+  Reduction ReplaceUint32(uint32_t value) {
+    return Replace(Uint32Constant(value));
+  }
   Reduction ReplaceInt64(int64_t value) {
     return Replace(Int64Constant(value));
   }
 
+  Reduction ReduceInt32Add(Node* node);
+  Reduction ReduceInt32Div(Node* node);
+  Reduction ReduceUint32Div(Node* node);
+  Reduction ReduceInt32Mod(Node* node);
+  Reduction ReduceUint32Mod(Node* node);
+  Reduction ReduceTruncateFloat64ToInt32(Node* node);
+  Reduction ReduceStore(Node* node);
   Reduction ReduceProjection(size_t index, Node* node);
+  Reduction ReduceWord32Shifts(Node* node);
+  Reduction ReduceWord32Shl(Node* node);
+  Reduction ReduceWord32And(Node* node);
+  Reduction ReduceWord32Or(Node* node);
 
   Graph* graph() const;
   JSGraph* jsgraph() const { return jsgraph_; }
diff --git a/src/compiler/machine-operator-unittest.cc b/src/compiler/machine-operator-unittest.cc
deleted file mode 100644
index cb93ce7..0000000
--- a/src/compiler/machine-operator-unittest.cc
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/operator-properties-inl.h"
-#include "testing/gtest-support.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-#if GTEST_HAS_COMBINE
-
-// TODO(bmeurer): Find a new home for these.
-inline std::ostream& operator<<(std::ostream& os, const MachineType& type) {
-  OStringStream ost;
-  ost << type;
-  return os << ost.c_str();
-}
-inline std::ostream& operator<<(std::ostream& os,
-                         const WriteBarrierKind& write_barrier_kind) {
-  OStringStream ost;
-  ost << write_barrier_kind;
-  return os << ost.c_str();
-}
-
-
-template <typename T>
-class MachineOperatorTestWithParam
-    : public ::testing::TestWithParam< ::testing::tuple<MachineType, T> > {
- protected:
-  MachineType type() const { return ::testing::get<0>(B::GetParam()); }
-  const T& GetParam() const { return ::testing::get<1>(B::GetParam()); }
-
- private:
-  typedef ::testing::TestWithParam< ::testing::tuple<MachineType, T> > B;
-};
-
-
-namespace {
-
-const MachineType kMachineReps[] = {kRepWord32, kRepWord64};
-
-
-const MachineType kMachineTypes[] = {
-    kMachFloat32, kMachFloat64,   kMachInt8,   kMachUint8,  kMachInt16,
-    kMachUint16,  kMachInt32,     kMachUint32, kMachInt64,  kMachUint64,
-    kMachPtr,     kMachAnyTagged, kRepBit,     kRepWord8,   kRepWord16,
-    kRepWord32,   kRepWord64,     kRepFloat32, kRepFloat64, kRepTagged};
-
-}  // namespace
-
-
-// -----------------------------------------------------------------------------
-// Load operator.
-
-
-typedef MachineOperatorTestWithParam<LoadRepresentation>
-    MachineLoadOperatorTest;
-
-
-TEST_P(MachineLoadOperatorTest, InstancesAreGloballyShared) {
-  MachineOperatorBuilder machine1(type());
-  MachineOperatorBuilder machine2(type());
-  EXPECT_EQ(machine1.Load(GetParam()), machine2.Load(GetParam()));
-}
-
-
-TEST_P(MachineLoadOperatorTest, NumberOfInputsAndOutputs) {
-  MachineOperatorBuilder machine(type());
-  const Operator* op = machine.Load(GetParam());
-
-  EXPECT_EQ(2, OperatorProperties::GetValueInputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
-  EXPECT_EQ(3, OperatorProperties::GetTotalInputCount(op));
-
-  EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
-}
-
-
-TEST_P(MachineLoadOperatorTest, OpcodeIsCorrect) {
-  MachineOperatorBuilder machine(type());
-  EXPECT_EQ(IrOpcode::kLoad, machine.Load(GetParam())->opcode());
-}
-
-
-TEST_P(MachineLoadOperatorTest, ParameterIsCorrect) {
-  MachineOperatorBuilder machine(type());
-  EXPECT_EQ(GetParam(),
-            OpParameter<LoadRepresentation>(machine.Load(GetParam())));
-}
-
-
-INSTANTIATE_TEST_CASE_P(MachineOperatorTest, MachineLoadOperatorTest,
-                        ::testing::Combine(::testing::ValuesIn(kMachineReps),
-                                           ::testing::ValuesIn(kMachineTypes)));
-
-
-// -----------------------------------------------------------------------------
-// Store operator.
-
-
-class MachineStoreOperatorTest
-    : public MachineOperatorTestWithParam<
-          ::testing::tuple<MachineType, WriteBarrierKind> > {
- protected:
-  StoreRepresentation GetParam() const {
-    return StoreRepresentation(
-        ::testing::get<0>(MachineOperatorTestWithParam<
-            ::testing::tuple<MachineType, WriteBarrierKind> >::GetParam()),
-        ::testing::get<1>(MachineOperatorTestWithParam<
-            ::testing::tuple<MachineType, WriteBarrierKind> >::GetParam()));
-  }
-};
-
-
-TEST_P(MachineStoreOperatorTest, InstancesAreGloballyShared) {
-  MachineOperatorBuilder machine1(type());
-  MachineOperatorBuilder machine2(type());
-  EXPECT_EQ(machine1.Store(GetParam()), machine2.Store(GetParam()));
-}
-
-
-TEST_P(MachineStoreOperatorTest, NumberOfInputsAndOutputs) {
-  MachineOperatorBuilder machine(type());
-  const Operator* op = machine.Store(GetParam());
-
-  EXPECT_EQ(3, OperatorProperties::GetValueInputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetControlInputCount(op));
-  EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
-
-  EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
-}
-
-
-TEST_P(MachineStoreOperatorTest, OpcodeIsCorrect) {
-  MachineOperatorBuilder machine(type());
-  EXPECT_EQ(IrOpcode::kStore, machine.Store(GetParam())->opcode());
-}
-
-
-TEST_P(MachineStoreOperatorTest, ParameterIsCorrect) {
-  MachineOperatorBuilder machine(type());
-  EXPECT_EQ(GetParam(),
-            OpParameter<StoreRepresentation>(machine.Store(GetParam())));
-}
-
-
-INSTANTIATE_TEST_CASE_P(
-    MachineOperatorTest, MachineStoreOperatorTest,
-    ::testing::Combine(
-        ::testing::ValuesIn(kMachineReps),
-        ::testing::Combine(::testing::ValuesIn(kMachineTypes),
-                           ::testing::Values(kNoWriteBarrier,
-                                             kFullWriteBarrier))));
-
-
-// -----------------------------------------------------------------------------
-// Pure operators.
-
-
-namespace {
-
-struct PureOperator {
-  const Operator* (MachineOperatorBuilder::*constructor)();
-  IrOpcode::Value opcode;
-  int value_input_count;
-  int value_output_count;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
-  return os << IrOpcode::Mnemonic(pop.opcode);
-}
-
-
-const PureOperator kPureOperators[] = {
-#define PURE(Name, input_count, output_count)                      \
-  {                                                                \
-    &MachineOperatorBuilder::Name, IrOpcode::k##Name, input_count, \
-        output_count                                               \
-  }
-    PURE(Word32And, 2, 1),                PURE(Word32Or, 2, 1),
-    PURE(Word32Xor, 2, 1),                PURE(Word32Shl, 2, 1),
-    PURE(Word32Shr, 2, 1),                PURE(Word32Sar, 2, 1),
-    PURE(Word32Ror, 2, 1),                PURE(Word32Equal, 2, 1),
-    PURE(Word64And, 2, 1),                PURE(Word64Or, 2, 1),
-    PURE(Word64Xor, 2, 1),                PURE(Word64Shl, 2, 1),
-    PURE(Word64Shr, 2, 1),                PURE(Word64Sar, 2, 1),
-    PURE(Word64Ror, 2, 1),                PURE(Word64Equal, 2, 1),
-    PURE(Int32Add, 2, 1),                 PURE(Int32AddWithOverflow, 2, 2),
-    PURE(Int32Sub, 2, 1),                 PURE(Int32SubWithOverflow, 2, 2),
-    PURE(Int32Mul, 2, 1),                 PURE(Int32Div, 2, 1),
-    PURE(Int32UDiv, 2, 1),                PURE(Int32Mod, 2, 1),
-    PURE(Int32UMod, 2, 1),                PURE(Int32LessThan, 2, 1),
-    PURE(Int32LessThanOrEqual, 2, 1),     PURE(Uint32LessThan, 2, 1),
-    PURE(Uint32LessThanOrEqual, 2, 1),    PURE(Int64Add, 2, 1),
-    PURE(Int64Sub, 2, 1),                 PURE(Int64Mul, 2, 1),
-    PURE(Int64Div, 2, 1),                 PURE(Int64UDiv, 2, 1),
-    PURE(Int64Mod, 2, 1),                 PURE(Int64UMod, 2, 1),
-    PURE(Int64LessThan, 2, 1),            PURE(Int64LessThanOrEqual, 2, 1),
-    PURE(ChangeFloat32ToFloat64, 1, 1),   PURE(ChangeFloat64ToInt32, 1, 1),
-    PURE(ChangeFloat64ToUint32, 1, 1),    PURE(ChangeInt32ToInt64, 1, 1),
-    PURE(ChangeUint32ToFloat64, 1, 1),    PURE(ChangeUint32ToUint64, 1, 1),
-    PURE(TruncateFloat64ToFloat32, 1, 1), PURE(TruncateFloat64ToInt32, 1, 1),
-    PURE(TruncateInt64ToInt32, 1, 1),     PURE(Float64Add, 2, 1),
-    PURE(Float64Sub, 2, 1),               PURE(Float64Mul, 2, 1),
-    PURE(Float64Div, 2, 1),               PURE(Float64Mod, 2, 1),
-    PURE(Float64Sqrt, 1, 1),              PURE(Float64Equal, 2, 1),
-    PURE(Float64LessThan, 2, 1),          PURE(Float64LessThanOrEqual, 2, 1)
-#undef PURE
-};
-
-
-typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest;
-
-}  // namespace
-
-
-TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) {
-  const PureOperator& pop = GetParam();
-  MachineOperatorBuilder machine1(type());
-  MachineOperatorBuilder machine2(type());
-  EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)());
-}
-
-
-TEST_P(MachinePureOperatorTest, NumberOfInputsAndOutputs) {
-  MachineOperatorBuilder machine(type());
-  const PureOperator& pop = GetParam();
-  const Operator* op = (machine.*pop.constructor)();
-
-  EXPECT_EQ(pop.value_input_count, OperatorProperties::GetValueInputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetEffectInputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
-  EXPECT_EQ(pop.value_input_count, OperatorProperties::GetTotalInputCount(op));
-
-  EXPECT_EQ(pop.value_output_count,
-            OperatorProperties::GetValueOutputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
-}
-
-
-TEST_P(MachinePureOperatorTest, MarkedAsPure) {
-  MachineOperatorBuilder machine(type());
-  const PureOperator& pop = GetParam();
-  const Operator* op = (machine.*pop.constructor)();
-  EXPECT_TRUE(op->HasProperty(Operator::kPure));
-}
-
-
-TEST_P(MachinePureOperatorTest, OpcodeIsCorrect) {
-  MachineOperatorBuilder machine(type());
-  const PureOperator& pop = GetParam();
-  const Operator* op = (machine.*pop.constructor)();
-  EXPECT_EQ(pop.opcode, op->opcode());
-}
-
-
-INSTANTIATE_TEST_CASE_P(
-    MachineOperatorTest, MachinePureOperatorTest,
-    ::testing::Combine(::testing::ValuesIn(kMachineReps),
-                       ::testing::ValuesIn(kPureOperators)));
-
-#endif  // GTEST_HAS_COMBINE
-
-
-// -----------------------------------------------------------------------------
-// Pseudo operators.
-
-
-TEST(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs32Bit) {
-  MachineOperatorBuilder machine(kRepWord32);
-  EXPECT_EQ(machine.Word32And(), machine.WordAnd());
-  EXPECT_EQ(machine.Word32Or(), machine.WordOr());
-  EXPECT_EQ(machine.Word32Xor(), machine.WordXor());
-  EXPECT_EQ(machine.Word32Shl(), machine.WordShl());
-  EXPECT_EQ(machine.Word32Shr(), machine.WordShr());
-  EXPECT_EQ(machine.Word32Sar(), machine.WordSar());
-  EXPECT_EQ(machine.Word32Ror(), machine.WordRor());
-  EXPECT_EQ(machine.Word32Equal(), machine.WordEqual());
-  EXPECT_EQ(machine.Int32Add(), machine.IntAdd());
-  EXPECT_EQ(machine.Int32Sub(), machine.IntSub());
-  EXPECT_EQ(machine.Int32Mul(), machine.IntMul());
-  EXPECT_EQ(machine.Int32Div(), machine.IntDiv());
-  EXPECT_EQ(machine.Int32UDiv(), machine.IntUDiv());
-  EXPECT_EQ(machine.Int32Mod(), machine.IntMod());
-  EXPECT_EQ(machine.Int32UMod(), machine.IntUMod());
-  EXPECT_EQ(machine.Int32LessThan(), machine.IntLessThan());
-  EXPECT_EQ(machine.Int32LessThanOrEqual(), machine.IntLessThanOrEqual());
-}
-
-
-TEST(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs64Bit) {
-  MachineOperatorBuilder machine(kRepWord64);
-  EXPECT_EQ(machine.Word64And(), machine.WordAnd());
-  EXPECT_EQ(machine.Word64Or(), machine.WordOr());
-  EXPECT_EQ(machine.Word64Xor(), machine.WordXor());
-  EXPECT_EQ(machine.Word64Shl(), machine.WordShl());
-  EXPECT_EQ(machine.Word64Shr(), machine.WordShr());
-  EXPECT_EQ(machine.Word64Sar(), machine.WordSar());
-  EXPECT_EQ(machine.Word64Ror(), machine.WordRor());
-  EXPECT_EQ(machine.Word64Equal(), machine.WordEqual());
-  EXPECT_EQ(machine.Int64Add(), machine.IntAdd());
-  EXPECT_EQ(machine.Int64Sub(), machine.IntSub());
-  EXPECT_EQ(machine.Int64Mul(), machine.IntMul());
-  EXPECT_EQ(machine.Int64Div(), machine.IntDiv());
-  EXPECT_EQ(machine.Int64UDiv(), machine.IntUDiv());
-  EXPECT_EQ(machine.Int64Mod(), machine.IntMod());
-  EXPECT_EQ(machine.Int64UMod(), machine.IntUMod());
-  EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan());
-  EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual());
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/machine-operator.cc b/src/compiler/machine-operator.cc
index 2f30bd2..eb034e9 100644
--- a/src/compiler/machine-operator.cc
+++ b/src/compiler/machine-operator.cc
@@ -7,13 +7,15 @@
 #include "src/base/lazy-instance.h"
 #include "src/compiler/opcodes.h"
 #include "src/compiler/operator.h"
+#include "src/v8.h"
+#include "src/zone-inl.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-OStream& operator<<(OStream& os, const WriteBarrierKind& write_barrier_kind) {
-  switch (write_barrier_kind) {
+std::ostream& operator<<(std::ostream& os, WriteBarrierKind kind) {
+  switch (kind) {
     case kNoWriteBarrier:
       return os << "NoWriteBarrier";
     case kFullWriteBarrier:
@@ -24,98 +26,113 @@
 }
 
 
-OStream& operator<<(OStream& os, const StoreRepresentation& rep) {
+bool operator==(StoreRepresentation lhs, StoreRepresentation rhs) {
+  return lhs.machine_type() == rhs.machine_type() &&
+         lhs.write_barrier_kind() == rhs.write_barrier_kind();
+}
+
+
+bool operator!=(StoreRepresentation lhs, StoreRepresentation rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(StoreRepresentation rep) {
+  return base::hash_combine(rep.machine_type(), rep.write_barrier_kind());
+}
+
+
+std::ostream& operator<<(std::ostream& os, StoreRepresentation rep) {
   return os << "(" << rep.machine_type() << " : " << rep.write_barrier_kind()
             << ")";
 }
 
 
-template <>
-struct StaticParameterTraits<StoreRepresentation> {
-  static OStream& PrintTo(OStream& os, const StoreRepresentation& rep) {
-    return os << rep;
-  }
-  static int HashCode(const StoreRepresentation& rep) {
-    return rep.machine_type() + rep.write_barrier_kind();
-  }
-  static bool Equals(const StoreRepresentation& rep1,
-                     const StoreRepresentation& rep2) {
-    return rep1 == rep2;
-  }
-};
+StoreRepresentation const& StoreRepresentationOf(Operator const* op) {
+  DCHECK_EQ(IrOpcode::kStore, op->opcode());
+  return OpParameter<StoreRepresentation>(op);
+}
 
 
-template <>
-struct StaticParameterTraits<LoadRepresentation> {
-  static OStream& PrintTo(OStream& os, LoadRepresentation type) {  // NOLINT
-    return os << type;
-  }
-  static int HashCode(LoadRepresentation type) { return type; }
-  static bool Equals(LoadRepresentation lhs, LoadRepresentation rhs) {
-    return lhs == rhs;
-  }
-};
+CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const* op) {
+  DCHECK_EQ(IrOpcode::kCheckedLoad, op->opcode());
+  return OpParameter<CheckedLoadRepresentation>(op);
+}
+
+
+CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const* op) {
+  DCHECK_EQ(IrOpcode::kCheckedStore, op->opcode());
+  return OpParameter<CheckedStoreRepresentation>(op);
+}
 
 
 #define PURE_OP_LIST(V)                                                       \
-  V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 1)         \
-  V(Word32Or, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
-  V(Word32Xor, Operator::kAssociative | Operator::kCommutative, 2, 1)         \
-  V(Word32Shl, Operator::kNoProperties, 2, 1)                                 \
-  V(Word32Shr, Operator::kNoProperties, 2, 1)                                 \
-  V(Word32Sar, Operator::kNoProperties, 2, 1)                                 \
-  V(Word32Ror, Operator::kNoProperties, 2, 1)                                 \
-  V(Word32Equal, Operator::kCommutative, 2, 1)                                \
-  V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 1)         \
-  V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
-  V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 1)         \
-  V(Word64Shl, Operator::kNoProperties, 2, 1)                                 \
-  V(Word64Shr, Operator::kNoProperties, 2, 1)                                 \
-  V(Word64Sar, Operator::kNoProperties, 2, 1)                                 \
-  V(Word64Ror, Operator::kNoProperties, 2, 1)                                 \
-  V(Word64Equal, Operator::kCommutative, 2, 1)                                \
-  V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
+  V(Word32And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
+  V(Word32Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
+  V(Word32Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
+  V(Word32Shl, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Word32Shr, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Word32Sar, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Word32Ror, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Word32Equal, Operator::kCommutative, 2, 0, 1)                             \
+  V(Word64And, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
+  V(Word64Or, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
+  V(Word64Xor, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)      \
+  V(Word64Shl, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Word64Shr, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Word64Sar, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Word64Ror, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Word64Equal, Operator::kCommutative, 2, 0, 1)                             \
+  V(Int32Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
   V(Int32AddWithOverflow, Operator::kAssociative | Operator::kCommutative, 2, \
-    2)                                                                        \
-  V(Int32Sub, Operator::kNoProperties, 2, 1)                                  \
-  V(Int32SubWithOverflow, Operator::kNoProperties, 2, 2)                      \
-  V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
-  V(Int32Div, Operator::kNoProperties, 2, 1)                                  \
-  V(Int32UDiv, Operator::kNoProperties, 2, 1)                                 \
-  V(Int32Mod, Operator::kNoProperties, 2, 1)                                  \
-  V(Int32UMod, Operator::kNoProperties, 2, 1)                                 \
-  V(Int32LessThan, Operator::kNoProperties, 2, 1)                             \
-  V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 1)                      \
-  V(Uint32LessThan, Operator::kNoProperties, 2, 1)                            \
-  V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 1)                     \
-  V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
-  V(Int64Sub, Operator::kNoProperties, 2, 1)                                  \
-  V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 1)          \
-  V(Int64Div, Operator::kNoProperties, 2, 1)                                  \
-  V(Int64UDiv, Operator::kNoProperties, 2, 1)                                 \
-  V(Int64Mod, Operator::kNoProperties, 2, 1)                                  \
-  V(Int64UMod, Operator::kNoProperties, 2, 1)                                 \
-  V(Int64LessThan, Operator::kNoProperties, 2, 1)                             \
-  V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 1)                      \
-  V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 1)                    \
-  V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 1)                      \
-  V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 1)                     \
-  V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 1)                      \
-  V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 1)                        \
-  V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 1)                     \
-  V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 1)                      \
-  V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 1)                  \
-  V(TruncateFloat64ToInt32, Operator::kNoProperties, 1, 1)                    \
-  V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 1)                      \
-  V(Float64Add, Operator::kCommutative, 2, 1)                                 \
-  V(Float64Sub, Operator::kNoProperties, 2, 1)                                \
-  V(Float64Mul, Operator::kCommutative, 2, 1)                                 \
-  V(Float64Div, Operator::kNoProperties, 2, 1)                                \
-  V(Float64Mod, Operator::kNoProperties, 2, 1)                                \
-  V(Float64Sqrt, Operator::kNoProperties, 1, 1)                               \
-  V(Float64Equal, Operator::kCommutative, 2, 1)                               \
-  V(Float64LessThan, Operator::kNoProperties, 2, 1)                           \
-  V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 1)
+    0, 2)                                                                     \
+  V(Int32Sub, Operator::kNoProperties, 2, 0, 1)                               \
+  V(Int32SubWithOverflow, Operator::kNoProperties, 2, 0, 2)                   \
+  V(Int32Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
+  V(Int32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)   \
+  V(Int32Div, Operator::kNoProperties, 2, 1, 1)                               \
+  V(Int32Mod, Operator::kNoProperties, 2, 1, 1)                               \
+  V(Int32LessThan, Operator::kNoProperties, 2, 0, 1)                          \
+  V(Int32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                   \
+  V(Uint32Div, Operator::kNoProperties, 2, 1, 1)                              \
+  V(Uint32LessThan, Operator::kNoProperties, 2, 0, 1)                         \
+  V(Uint32LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                  \
+  V(Uint32Mod, Operator::kNoProperties, 2, 1, 1)                              \
+  V(Uint32MulHigh, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)  \
+  V(Int64Add, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
+  V(Int64Sub, Operator::kNoProperties, 2, 0, 1)                               \
+  V(Int64Mul, Operator::kAssociative | Operator::kCommutative, 2, 0, 1)       \
+  V(Int64Div, Operator::kNoProperties, 2, 0, 1)                               \
+  V(Int64Mod, Operator::kNoProperties, 2, 0, 1)                               \
+  V(Int64LessThan, Operator::kNoProperties, 2, 0, 1)                          \
+  V(Int64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                   \
+  V(Uint64Div, Operator::kNoProperties, 2, 0, 1)                              \
+  V(Uint64LessThan, Operator::kNoProperties, 2, 0, 1)                         \
+  V(Uint64Mod, Operator::kNoProperties, 2, 0, 1)                              \
+  V(ChangeFloat32ToFloat64, Operator::kNoProperties, 1, 0, 1)                 \
+  V(ChangeFloat64ToInt32, Operator::kNoProperties, 1, 0, 1)                   \
+  V(ChangeFloat64ToUint32, Operator::kNoProperties, 1, 0, 1)                  \
+  V(ChangeInt32ToFloat64, Operator::kNoProperties, 1, 0, 1)                   \
+  V(ChangeInt32ToInt64, Operator::kNoProperties, 1, 0, 1)                     \
+  V(ChangeUint32ToFloat64, Operator::kNoProperties, 1, 0, 1)                  \
+  V(ChangeUint32ToUint64, Operator::kNoProperties, 1, 0, 1)                   \
+  V(TruncateFloat64ToFloat32, Operator::kNoProperties, 1, 0, 1)               \
+  V(TruncateFloat64ToInt32, Operator::kNoProperties, 1, 0, 1)                 \
+  V(TruncateInt64ToInt32, Operator::kNoProperties, 1, 0, 1)                   \
+  V(Float64Add, Operator::kCommutative, 2, 0, 1)                              \
+  V(Float64Sub, Operator::kNoProperties, 2, 0, 1)                             \
+  V(Float64Mul, Operator::kCommutative, 2, 0, 1)                              \
+  V(Float64Div, Operator::kNoProperties, 2, 0, 1)                             \
+  V(Float64Mod, Operator::kNoProperties, 2, 0, 1)                             \
+  V(Float64Sqrt, Operator::kNoProperties, 1, 0, 1)                            \
+  V(Float64Ceil, Operator::kNoProperties, 1, 0, 1)                            \
+  V(Float64Floor, Operator::kNoProperties, 1, 0, 1)                           \
+  V(Float64RoundTruncate, Operator::kNoProperties, 1, 0, 1)                   \
+  V(Float64RoundTiesAway, Operator::kNoProperties, 1, 0, 1)                   \
+  V(Float64Equal, Operator::kCommutative, 2, 0, 1)                            \
+  V(Float64LessThan, Operator::kNoProperties, 2, 0, 1)                        \
+  V(Float64LessThanOrEqual, Operator::kNoProperties, 2, 0, 1)                 \
+  V(LoadStackPointer, Operator::kNoProperties, 0, 0, 1)
 
 
 #define MACHINE_TYPE_LIST(V) \
@@ -140,64 +157,85 @@
   V(RepTagged)
 
 
-struct MachineOperatorBuilderImpl {
-#define PURE(Name, properties, input_count, output_count)                 \
-  struct Name##Operator FINAL : public SimpleOperator {                   \
-    Name##Operator()                                                      \
-        : SimpleOperator(IrOpcode::k##Name, Operator::kPure | properties, \
-                         input_count, output_count, #Name) {}             \
-  };                                                                      \
+struct MachineOperatorGlobalCache {
+#define PURE(Name, properties, value_input_count, control_input_count,         \
+             output_count)                                                     \
+  struct Name##Operator FINAL : public Operator {                              \
+    Name##Operator()                                                           \
+        : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name,     \
+                   value_input_count, 0, control_input_count, output_count, 0, \
+                   0) {}                                                       \
+  };                                                                           \
   Name##Operator k##Name;
   PURE_OP_LIST(PURE)
 #undef PURE
 
-#define LOAD(Type)                                                            \
-  struct Load##Type##Operator FINAL : public Operator1<LoadRepresentation> {  \
-    Load##Type##Operator()                                                    \
-        : Operator1<LoadRepresentation>(                                      \
-              IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, 2, 1, \
-              "Load", k##Type) {}                                             \
-  };                                                                          \
-  Load##Type##Operator k##Load##Type;
+#define LOAD(Type)                                                             \
+  struct Load##Type##Operator FINAL : public Operator1<LoadRepresentation> {   \
+    Load##Type##Operator()                                                     \
+        : Operator1<LoadRepresentation>(                                       \
+              IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite,        \
+              "Load", 2, 1, 1, 1, 1, 0, k##Type) {}                            \
+  };                                                                           \
+  struct CheckedLoad##Type##Operator FINAL                                     \
+      : public Operator1<CheckedLoadRepresentation> {                          \
+    CheckedLoad##Type##Operator()                                              \
+        : Operator1<CheckedLoadRepresentation>(                                \
+              IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite, \
+              "CheckedLoad", 3, 1, 1, 1, 1, 0, k##Type) {}                     \
+  };                                                                           \
+  Load##Type##Operator kLoad##Type;                                            \
+  CheckedLoad##Type##Operator kCheckedLoad##Type;
   MACHINE_TYPE_LIST(LOAD)
 #undef LOAD
 
-#define STORE(Type)                                                           \
-  struct Store##Type##Operator : public Operator1<StoreRepresentation> {      \
-    explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind)       \
-        : Operator1<StoreRepresentation>(                                     \
-              IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, 3, 0, \
-              "Store", StoreRepresentation(k##Type, write_barrier_kind)) {}   \
-  };                                                                          \
-  struct Store##Type##NoWriteBarrier##Operator FINAL                          \
-      : public Store##Type##Operator {                                        \
-    Store##Type##NoWriteBarrier##Operator()                                   \
-        : Store##Type##Operator(kNoWriteBarrier) {}                           \
-  };                                                                          \
-  struct Store##Type##FullWriteBarrier##Operator FINAL                        \
-      : public Store##Type##Operator {                                        \
-    Store##Type##FullWriteBarrier##Operator()                                 \
-        : Store##Type##Operator(kFullWriteBarrier) {}                         \
-  };                                                                          \
-  Store##Type##NoWriteBarrier##Operator k##Store##Type##NoWriteBarrier;       \
-  Store##Type##FullWriteBarrier##Operator k##Store##Type##FullWriteBarrier;
+#define STORE(Type)                                                            \
+  struct Store##Type##Operator : public Operator1<StoreRepresentation> {       \
+    explicit Store##Type##Operator(WriteBarrierKind write_barrier_kind)        \
+        : Operator1<StoreRepresentation>(                                      \
+              IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow,        \
+              "Store", 3, 1, 1, 0, 1, 0,                                       \
+              StoreRepresentation(k##Type, write_barrier_kind)) {}             \
+  };                                                                           \
+  struct Store##Type##NoWriteBarrier##Operator FINAL                           \
+      : public Store##Type##Operator {                                         \
+    Store##Type##NoWriteBarrier##Operator()                                    \
+        : Store##Type##Operator(kNoWriteBarrier) {}                            \
+  };                                                                           \
+  struct Store##Type##FullWriteBarrier##Operator FINAL                         \
+      : public Store##Type##Operator {                                         \
+    Store##Type##FullWriteBarrier##Operator()                                  \
+        : Store##Type##Operator(kFullWriteBarrier) {}                          \
+  };                                                                           \
+  struct CheckedStore##Type##Operator FINAL                                    \
+      : public Operator1<CheckedStoreRepresentation> {                         \
+    CheckedStore##Type##Operator()                                             \
+        : Operator1<CheckedStoreRepresentation>(                               \
+              IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow, \
+              "CheckedStore", 4, 1, 1, 0, 1, 0, k##Type) {}                    \
+  };                                                                           \
+  Store##Type##NoWriteBarrier##Operator kStore##Type##NoWriteBarrier;          \
+  Store##Type##FullWriteBarrier##Operator kStore##Type##FullWriteBarrier;      \
+  CheckedStore##Type##Operator kCheckedStore##Type;
   MACHINE_TYPE_LIST(STORE)
 #undef STORE
 };
 
 
-static base::LazyInstance<MachineOperatorBuilderImpl>::type kImpl =
+static base::LazyInstance<MachineOperatorGlobalCache>::type kCache =
     LAZY_INSTANCE_INITIALIZER;
 
 
-MachineOperatorBuilder::MachineOperatorBuilder(MachineType word)
-    : impl_(kImpl.Get()), word_(word) {
+MachineOperatorBuilder::MachineOperatorBuilder(Zone* zone, MachineType word,
+                                               Flags flags)
+    : zone_(zone), cache_(kCache.Get()), word_(word), flags_(flags) {
   DCHECK(word == kRepWord32 || word == kRepWord64);
 }
 
 
-#define PURE(Name, properties, input_count, output_count) \
-  const Operator* MachineOperatorBuilder::Name() { return &impl_.k##Name; }
+#define PURE(Name, properties, value_input_count, control_input_count, \
+             output_count)                                             \
+  const Operator* MachineOperatorBuilder::Name() { return &cache_.k##Name; }
 PURE_OP_LIST(PURE)
 #undef PURE
 
@@ -206,28 +244,29 @@
   switch (rep) {
 #define LOAD(Type) \
   case k##Type:    \
-    return &impl_.k##Load##Type;
+    return &cache_.kLoad##Type;
     MACHINE_TYPE_LIST(LOAD)
 #undef LOAD
-
     default:
       break;
   }
-  UNREACHABLE();
-  return NULL;
+  // Uncached.
+  return new (zone_) Operator1<LoadRepresentation>(  // --
+      IrOpcode::kLoad, Operator::kNoThrow | Operator::kNoWrite, "Load", 2, 1, 1,
+      1, 1, 0, rep);
 }
 
 
 const Operator* MachineOperatorBuilder::Store(StoreRepresentation rep) {
   switch (rep.machine_type()) {
-#define STORE(Type)                                     \
-  case k##Type:                                         \
-    switch (rep.write_barrier_kind()) {                 \
-      case kNoWriteBarrier:                             \
-        return &impl_.k##Store##Type##NoWriteBarrier;   \
-      case kFullWriteBarrier:                           \
-        return &impl_.k##Store##Type##FullWriteBarrier; \
-    }                                                   \
+#define STORE(Type)                                      \
+  case k##Type:                                          \
+    switch (rep.write_barrier_kind()) {                  \
+      case kNoWriteBarrier:                              \
+        return &cache_.k##Store##Type##NoWriteBarrier;   \
+      case kFullWriteBarrier:                            \
+        return &cache_.k##Store##Type##FullWriteBarrier; \
+    }                                                    \
     break;
     MACHINE_TYPE_LIST(STORE)
 #undef STORE
@@ -235,8 +274,46 @@
     default:
       break;
   }
-  UNREACHABLE();
-  return NULL;
+  // Uncached.
+  return new (zone_) Operator1<StoreRepresentation>(  // --
+      IrOpcode::kStore, Operator::kNoRead | Operator::kNoThrow, "Store", 3, 1,
+      1, 0, 1, 0, rep);
+}
+
+
+const Operator* MachineOperatorBuilder::CheckedLoad(
+    CheckedLoadRepresentation rep) {
+  switch (rep) {
+#define LOAD(Type) \
+  case k##Type:    \
+    return &cache_.kCheckedLoad##Type;
+    MACHINE_TYPE_LIST(LOAD)
+#undef LOAD
+    default:
+      break;
+  }
+  // Uncached.
+  return new (zone_) Operator1<CheckedLoadRepresentation>(
+      IrOpcode::kCheckedLoad, Operator::kNoThrow | Operator::kNoWrite,
+      "CheckedLoad", 3, 1, 1, 1, 1, 0, rep);
+}
+
+
+const Operator* MachineOperatorBuilder::CheckedStore(
+    CheckedStoreRepresentation rep) {
+  switch (rep) {
+#define STORE(Type) \
+  case k##Type:     \
+    return &cache_.kCheckedStore##Type;
+    MACHINE_TYPE_LIST(STORE)
+#undef STORE
+    default:
+      break;
+  }
+  // Uncached.
+  return new (zone_) Operator1<CheckedStoreRepresentation>(
+      IrOpcode::kCheckedStore, Operator::kNoRead | Operator::kNoThrow,
+      "CheckedStore", 4, 1, 1, 0, 1, 0, rep);
 }
 
 }  // namespace compiler
diff --git a/src/compiler/machine-operator.h b/src/compiler/machine-operator.h
index 92c8ac4..42f3130 100644
--- a/src/compiler/machine-operator.h
+++ b/src/compiler/machine-operator.h
@@ -5,6 +5,7 @@
 #ifndef V8_COMPILER_MACHINE_OPERATOR_H_
 #define V8_COMPILER_MACHINE_OPERATOR_H_
 
+#include "src/base/flags.h"
 #include "src/compiler/machine-type.h"
 
 namespace v8 {
@@ -12,21 +13,22 @@
 namespace compiler {
 
 // Forward declarations.
-struct MachineOperatorBuilderImpl;
+struct MachineOperatorGlobalCache;
 class Operator;
 
 
 // Supported write barrier modes.
 enum WriteBarrierKind { kNoWriteBarrier, kFullWriteBarrier };
 
-OStream& operator<<(OStream& os, const WriteBarrierKind& write_barrier_kind);
+std::ostream& operator<<(std::ostream& os, WriteBarrierKind);
 
 
+// A Load needs a MachineType.
 typedef MachineType LoadRepresentation;
 
 
-// A Store needs a MachineType and a WriteBarrierKind
-// in order to emit the correct write barrier.
+// A Store needs a MachineType and a WriteBarrierKind in order to emit the
+// correct write barrier.
 class StoreRepresentation FINAL {
  public:
   StoreRepresentation(MachineType machine_type,
@@ -41,26 +43,49 @@
   WriteBarrierKind write_barrier_kind_;
 };
 
-inline bool operator==(const StoreRepresentation& rep1,
-                       const StoreRepresentation& rep2) {
-  return rep1.machine_type() == rep2.machine_type() &&
-         rep1.write_barrier_kind() == rep2.write_barrier_kind();
-}
+bool operator==(StoreRepresentation, StoreRepresentation);
+bool operator!=(StoreRepresentation, StoreRepresentation);
 
-inline bool operator!=(const StoreRepresentation& rep1,
-                       const StoreRepresentation& rep2) {
-  return !(rep1 == rep2);
-}
+size_t hash_value(StoreRepresentation);
 
-OStream& operator<<(OStream& os, const StoreRepresentation& rep);
+std::ostream& operator<<(std::ostream&, StoreRepresentation);
+
+StoreRepresentation const& StoreRepresentationOf(Operator const*);
+
+
+// A CheckedLoad needs a MachineType.
+typedef MachineType CheckedLoadRepresentation;
+
+CheckedLoadRepresentation CheckedLoadRepresentationOf(Operator const*);
+
+
+// A CheckedStore needs a MachineType.
+typedef MachineType CheckedStoreRepresentation;
+
+CheckedStoreRepresentation CheckedStoreRepresentationOf(Operator const*);
 
 
 // Interface for building machine-level operators. These operators are
 // machine-level but machine-independent and thus define a language suitable
 // for generating code to run on architectures such as ia32, x64, arm, etc.
-class MachineOperatorBuilder FINAL {
+class MachineOperatorBuilder FINAL : public ZoneObject {
  public:
-  explicit MachineOperatorBuilder(MachineType word = kMachPtr);
+  // Flags that specify which operations are available. This is useful
+  // for operations that are unsupported by some back-ends.
+  enum Flag {
+    kNoFlags = 0u,
+    kFloat64Floor = 1u << 0,
+    kFloat64Ceil = 1u << 1,
+    kFloat64RoundTruncate = 1u << 2,
+    kFloat64RoundTiesAway = 1u << 3,
+    kInt32DivIsSafe = 1u << 4,
+    kUint32DivIsSafe = 1u << 5,
+    kWord32ShiftIsSafe = 1u << 6
+  };
+  typedef base::Flags<Flag, unsigned> Flags;
+
+  explicit MachineOperatorBuilder(Zone* zone, MachineType word = kMachPtr,
+                                  Flags supportedOperators = kNoFlags);
 
   const Operator* Word32And();
   const Operator* Word32Or();
@@ -70,6 +95,7 @@
   const Operator* Word32Sar();
   const Operator* Word32Ror();
   const Operator* Word32Equal();
+  bool Word32ShiftIsSafe() const { return flags_ & kWord32ShiftIsSafe; }
 
   const Operator* Word64And();
   const Operator* Word64Or();
@@ -85,24 +111,29 @@
   const Operator* Int32Sub();
   const Operator* Int32SubWithOverflow();
   const Operator* Int32Mul();
+  const Operator* Int32MulHigh();
   const Operator* Int32Div();
-  const Operator* Int32UDiv();
   const Operator* Int32Mod();
-  const Operator* Int32UMod();
   const Operator* Int32LessThan();
   const Operator* Int32LessThanOrEqual();
+  const Operator* Uint32Div();
   const Operator* Uint32LessThan();
   const Operator* Uint32LessThanOrEqual();
+  const Operator* Uint32Mod();
+  const Operator* Uint32MulHigh();
+  bool Int32DivIsSafe() const { return flags_ & kInt32DivIsSafe; }
+  bool Uint32DivIsSafe() const { return flags_ & kUint32DivIsSafe; }
 
   const Operator* Int64Add();
   const Operator* Int64Sub();
   const Operator* Int64Mul();
   const Operator* Int64Div();
-  const Operator* Int64UDiv();
   const Operator* Int64Mod();
-  const Operator* Int64UMod();
   const Operator* Int64LessThan();
   const Operator* Int64LessThanOrEqual();
+  const Operator* Uint64Div();
+  const Operator* Uint64LessThan();
+  const Operator* Uint64Mod();
 
   // These operators change the representation of numbers while preserving the
   // value of the number. Narrowing operators assume the input is representable
@@ -136,12 +167,30 @@
   const Operator* Float64LessThan();
   const Operator* Float64LessThanOrEqual();
 
+  // Floating point rounding.
+  const Operator* Float64Floor();
+  const Operator* Float64Ceil();
+  const Operator* Float64RoundTruncate();
+  const Operator* Float64RoundTiesAway();
+  bool HasFloat64Floor() { return flags_ & kFloat64Floor; }
+  bool HasFloat64Ceil() { return flags_ & kFloat64Ceil; }
+  bool HasFloat64RoundTruncate() { return flags_ & kFloat64RoundTruncate; }
+  bool HasFloat64RoundTiesAway() { return flags_ & kFloat64RoundTiesAway; }
+
   // load [base + index]
   const Operator* Load(LoadRepresentation rep);
 
   // store [base + index], value
   const Operator* Store(StoreRepresentation rep);
 
+  // Access to the machine stack.
+  const Operator* LoadStackPointer();
+
+  // checked-load heap, index, length
+  const Operator* CheckedLoad(CheckedLoadRepresentation);
+  // checked-store heap, index, length, value
+  const Operator* CheckedStore(CheckedStoreRepresentation);
+
   // Target machine word-size assumed by this builder.
   bool Is32() const { return word() == kRepWord32; }
   bool Is64() const { return word() == kRepWord64; }
@@ -162,11 +211,12 @@
   V(Int, Sub)             \
   V(Int, Mul)             \
   V(Int, Div)             \
-  V(Int, UDiv)            \
   V(Int, Mod)             \
-  V(Int, UMod)            \
   V(Int, LessThan)        \
-  V(Int, LessThanOrEqual)
+  V(Int, LessThanOrEqual) \
+  V(Uint, Div)            \
+  V(Uint, LessThan)       \
+  V(Uint, Mod)
 #define PSEUDO_OP(Prefix, Suffix)                                \
   const Operator* Prefix##Suffix() {                             \
     return Is32() ? Prefix##32##Suffix() : Prefix##64##Suffix(); \
@@ -176,10 +226,17 @@
 #undef PSEUDO_OP_LIST
 
  private:
-  const MachineOperatorBuilderImpl& impl_;
+  Zone* zone_;
+  const MachineOperatorGlobalCache& cache_;
   const MachineType word_;
+  const Flags flags_;
+
+  DISALLOW_COPY_AND_ASSIGN(MachineOperatorBuilder);
 };
 
+
+DEFINE_OPERATORS_FOR_FLAGS(MachineOperatorBuilder::Flags)
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/machine-type.cc b/src/compiler/machine-type.cc
index 94aa124..7475a03 100644
--- a/src/compiler/machine-type.cc
+++ b/src/compiler/machine-type.cc
@@ -17,7 +17,7 @@
   }
 
 
-OStream& operator<<(OStream& os, const MachineType& type) {
+std::ostream& operator<<(std::ostream& os, const MachineType& type) {
   bool before = false;
   PRINT(kRepBit);
   PRINT(kRepWord8);
diff --git a/src/compiler/machine-type.h b/src/compiler/machine-type.h
index 88b482c..4c51a9f 100644
--- a/src/compiler/machine-type.h
+++ b/src/compiler/machine-type.h
@@ -5,15 +5,14 @@
 #ifndef V8_COMPILER_MACHINE_TYPE_H_
 #define V8_COMPILER_MACHINE_TYPE_H_
 
+#include <iosfwd>
+
 #include "src/base/bits.h"
 #include "src/globals.h"
 #include "src/zone.h"
 
 namespace v8 {
 namespace internal {
-
-class OStream;
-
 namespace compiler {
 
 // Machine-level types and representations.
@@ -40,6 +39,7 @@
 
   // Machine types.
   kMachNone = 0,
+  kMachBool = kRepBit | kTypeBool,
   kMachFloat32 = kRepFloat32 | kTypeNumber,
   kMachFloat64 = kRepFloat64 | kTypeNumber,
   kMachInt8 = kRepWord8 | kTypeInt32,
@@ -50,11 +50,13 @@
   kMachUint32 = kRepWord32 | kTypeUint32,
   kMachInt64 = kRepWord64 | kTypeInt64,
   kMachUint64 = kRepWord64 | kTypeUint64,
+  kMachIntPtr = (kPointerSize == 4) ? kMachInt32 : kMachInt64,
+  kMachUintPtr = (kPointerSize == 4) ? kMachUint32 : kMachUint64,
   kMachPtr = (kPointerSize == 4) ? kRepWord32 : kRepWord64,
   kMachAnyTagged = kRepTagged | kTypeAny
 };
 
-OStream& operator<<(OStream& os, const MachineType& type);
+std::ostream& operator<<(std::ostream& os, const MachineType& type);
 
 typedef uint16_t MachineTypeUnion;
 
@@ -79,26 +81,34 @@
   return static_cast<MachineType>(result);
 }
 
-// Gets the element size in bytes of the machine type.
-inline int ElementSizeOf(MachineType machine_type) {
+// Gets the log2 of the element size in bytes of the machine type.
+inline int ElementSizeLog2Of(MachineType machine_type) {
   switch (RepresentationOf(machine_type)) {
     case kRepBit:
     case kRepWord8:
-      return 1;
+      return 0;
     case kRepWord16:
-      return 2;
+      return 1;
     case kRepWord32:
     case kRepFloat32:
-      return 4;
+      return 2;
     case kRepWord64:
     case kRepFloat64:
-      return 8;
+      return 3;
     case kRepTagged:
-      return kPointerSize;
+      return kPointerSizeLog2;
     default:
-      UNREACHABLE();
-      return kPointerSize;
+      break;
   }
+  UNREACHABLE();
+  return -1;
+}
+
+// Gets the element size in bytes of the machine type.
+inline int ElementSizeOf(MachineType machine_type) {
+  const int shift = ElementSizeLog2Of(machine_type);
+  DCHECK_NE(-1, shift);
+  return 1 << shift;
 }
 
 // Describes the inputs and outputs of a function or call.
diff --git a/src/compiler/mips/OWNERS b/src/compiler/mips/OWNERS
new file mode 100644
index 0000000..5508ba6
--- /dev/null
+++ b/src/compiler/mips/OWNERS
@@ -0,0 +1,5 @@
+paul.lind@imgtec.com
+gergely.kis@imgtec.com
+akos.palfi@imgtec.com
+balazs.kilvady@imgtec.com
+dusan.milosavljevic@imgtec.com
diff --git a/src/compiler/mips/code-generator-mips.cc b/src/compiler/mips/code-generator-mips.cc
new file mode 100644
index 0000000..dd92837
--- /dev/null
+++ b/src/compiler/mips/code-generator-mips.cc
@@ -0,0 +1,1185 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/code-generator.h"
+#include "src/compiler/code-generator-impl.h"
+#include "src/compiler/gap-resolver.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/mips/macro-assembler-mips.h"
+#include "src/scopes.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+#define __ masm()->
+
+
+// TODO(plind): Possibly avoid using these lithium names.
+#define kScratchReg kLithiumScratchReg
+#define kCompareReg kLithiumScratchReg2
+#define kScratchReg2 kLithiumScratchReg2
+#define kScratchDoubleReg kLithiumScratchDouble
+
+
+// TODO(plind): consider renaming these macros.
+#define TRACE_MSG(msg)                                                      \
+  PrintF("code_gen: \'%s\' in function %s at line %d\n", msg, __FUNCTION__, \
+         __LINE__)
+
+#define TRACE_UNIMPL()                                                       \
+  PrintF("UNIMPLEMENTED code_generator_mips: %s at line %d\n", __FUNCTION__, \
+         __LINE__)
+
+
+// Adds Mips-specific methods to convert InstructionOperands.
+class MipsOperandConverter FINAL : public InstructionOperandConverter {
+ public:
+  MipsOperandConverter(CodeGenerator* gen, Instruction* instr)
+      : InstructionOperandConverter(gen, instr) {}
+
+  FloatRegister OutputSingleRegister(int index = 0) {
+    return ToSingleRegister(instr_->OutputAt(index));
+  }
+
+  FloatRegister InputSingleRegister(int index) {
+    return ToSingleRegister(instr_->InputAt(index));
+  }
+
+  FloatRegister ToSingleRegister(InstructionOperand* op) {
+    // Single (Float) and Double register namespace is same on MIPS,
+    // both are typedefs of FPURegister.
+    return ToDoubleRegister(op);
+  }
+
+  Operand InputImmediate(int index) {
+    Constant constant = ToConstant(instr_->InputAt(index));
+    switch (constant.type()) {
+      case Constant::kInt32:
+        return Operand(constant.ToInt32());
+      case Constant::kFloat32:
+        return Operand(
+            isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
+      case Constant::kFloat64:
+        return Operand(
+            isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
+      case Constant::kInt64:
+      case Constant::kExternalReference:
+      case Constant::kHeapObject:
+        // TODO(plind): Maybe we should handle ExtRef & HeapObj here?
+        //    maybe not done on arm due to const pool ??
+        break;
+      case Constant::kRpoNumber:
+        UNREACHABLE();  // TODO(titzer): RPO immediates on mips?
+        break;
+    }
+    UNREACHABLE();
+    return Operand(zero_reg);
+  }
+
+  Operand InputOperand(int index) {
+    InstructionOperand* op = instr_->InputAt(index);
+    if (op->IsRegister()) {
+      return Operand(ToRegister(op));
+    }
+    return InputImmediate(index);
+  }
+
+  MemOperand MemoryOperand(int* first_index) {
+    const int index = *first_index;
+    switch (AddressingModeField::decode(instr_->opcode())) {
+      case kMode_None:
+        break;
+      case kMode_MRI:
+        *first_index += 2;
+        return MemOperand(InputRegister(index + 0), InputInt32(index + 1));
+      case kMode_MRR:
+        // TODO(plind): r6 address mode, to be implemented ...
+        UNREACHABLE();
+    }
+    UNREACHABLE();
+    return MemOperand(no_reg);
+  }
+
+  MemOperand MemoryOperand(int index = 0) { return MemoryOperand(&index); }
+
+  MemOperand ToMemOperand(InstructionOperand* op) const {
+    DCHECK(op != NULL);
+    DCHECK(!op->IsRegister());
+    DCHECK(!op->IsDoubleRegister());
+    DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
+    // The linkage computes where all spill slots are located.
+    FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0);
+    return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
+  }
+};
+
+
+static inline bool HasRegisterInput(Instruction* instr, int index) {
+  return instr->InputAt(index)->IsRegister();
+}
+
+
+namespace {
+
+class OutOfLineLoadSingle FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadSingle(CodeGenerator* gen, FloatRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL {
+    __ Move(result_, std::numeric_limits<float>::quiet_NaN());
+  }
+
+ private:
+  FloatRegister const result_;
+};
+
+
+class OutOfLineLoadDouble FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadDouble(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL {
+    __ Move(result_, std::numeric_limits<double>::quiet_NaN());
+  }
+
+ private:
+  DoubleRegister const result_;
+};
+
+
+class OutOfLineLoadInteger FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadInteger(CodeGenerator* gen, Register result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL { __ mov(result_, zero_reg); }
+
+ private:
+  Register const result_;
+};
+
+
+class OutOfLineRound : public OutOfLineCode {
+ public:
+  OutOfLineRound(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL {
+    // Handle rounding to zero case where sign has to be preserved.
+    // High bits of double input already in kScratchReg.
+    __ srl(at, kScratchReg, 31);
+    __ sll(at, at, 31);
+    __ Mthc1(at, result_);
+  }
+
+ private:
+  DoubleRegister const result_;
+};
+
+
+class OutOfLineTruncate FINAL : public OutOfLineRound {
+ public:
+  OutOfLineTruncate(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineRound(gen, result) {}
+};
+
+
+class OutOfLineFloor FINAL : public OutOfLineRound {
+ public:
+  OutOfLineFloor(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineRound(gen, result) {}
+};
+
+
+class OutOfLineCeil FINAL : public OutOfLineRound {
+ public:
+  OutOfLineCeil(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineRound(gen, result) {}
+};
+
+}  // namespace
+
+
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr)                         \
+  do {                                                                        \
+    auto result = i.Output##width##Register();                                \
+    auto ool = new (zone()) OutOfLineLoad##width(this, result);               \
+    if (instr->InputAt(0)->IsRegister()) {                                    \
+      auto offset = i.InputRegister(0);                                       \
+      __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
+      __ addu(at, i.InputRegister(2), offset);                                \
+      __ asm_instr(result, MemOperand(at, 0));                                \
+    } else {                                                                  \
+      auto offset = i.InputOperand(0).immediate();                            \
+      __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset));       \
+      __ asm_instr(result, MemOperand(i.InputRegister(2), offset));           \
+    }                                                                         \
+    __ bind(ool->exit());                                                     \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr)                              \
+  do {                                                                        \
+    auto result = i.OutputRegister();                                         \
+    auto ool = new (zone()) OutOfLineLoadInteger(this, result);               \
+    if (instr->InputAt(0)->IsRegister()) {                                    \
+      auto offset = i.InputRegister(0);                                       \
+      __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
+      __ addu(at, i.InputRegister(2), offset);                                \
+      __ asm_instr(result, MemOperand(at, 0));                                \
+    } else {                                                                  \
+      auto offset = i.InputOperand(0).immediate();                            \
+      __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset));       \
+      __ asm_instr(result, MemOperand(i.InputRegister(2), offset));           \
+    }                                                                         \
+    __ bind(ool->exit());                                                     \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr)                 \
+  do {                                                                 \
+    Label done;                                                        \
+    if (instr->InputAt(0)->IsRegister()) {                             \
+      auto offset = i.InputRegister(0);                                \
+      auto value = i.Input##width##Register(2);                        \
+      __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
+      __ addu(at, i.InputRegister(3), offset);                         \
+      __ asm_instr(value, MemOperand(at, 0));                          \
+    } else {                                                           \
+      auto offset = i.InputOperand(0).immediate();                     \
+      auto value = i.Input##width##Register(2);                        \
+      __ Branch(&done, ls, i.InputRegister(1), Operand(offset));       \
+      __ asm_instr(value, MemOperand(i.InputRegister(3), offset));     \
+    }                                                                  \
+    __ bind(&done);                                                    \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr)                      \
+  do {                                                                 \
+    Label done;                                                        \
+    if (instr->InputAt(0)->IsRegister()) {                             \
+      auto offset = i.InputRegister(0);                                \
+      auto value = i.InputRegister(2);                                 \
+      __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
+      __ addu(at, i.InputRegister(3), offset);                         \
+      __ asm_instr(value, MemOperand(at, 0));                          \
+    } else {                                                           \
+      auto offset = i.InputOperand(0).immediate();                     \
+      auto value = i.InputRegister(2);                                 \
+      __ Branch(&done, ls, i.InputRegister(1), Operand(offset));       \
+      __ asm_instr(value, MemOperand(i.InputRegister(3), offset));     \
+    }                                                                  \
+    __ bind(&done);                                                    \
+  } while (0)
+
+
+#define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(asm_instr, operation)                  \
+  do {                                                                         \
+    auto ool =                                                                 \
+        new (zone()) OutOfLine##operation(this, i.OutputDoubleRegister());     \
+    Label done;                                                                \
+    __ Mfhc1(kScratchReg, i.InputDoubleRegister(0));                           \
+    __ Ext(at, kScratchReg, HeapNumber::kExponentShift,                        \
+           HeapNumber::kExponentBits);                                         \
+    __ Branch(USE_DELAY_SLOT, &done, hs, at,                                   \
+              Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits)); \
+    __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));              \
+    __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));          \
+    __ Move(at, kScratchReg2, i.OutputDoubleRegister());                       \
+    __ or_(at, at, kScratchReg2);                                              \
+    __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg));        \
+    __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister());            \
+    __ bind(ool->exit());                                                      \
+    __ bind(&done);                                                            \
+  } while (0)
+
+
+// Assembles an instruction after register allocation, producing machine code.
+void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
+  MipsOperandConverter i(this, instr);
+  InstructionCode opcode = instr->opcode();
+
+  switch (ArchOpcodeField::decode(opcode)) {
+    case kArchCallCodeObject: {
+      EnsureSpaceForLazyDeopt();
+      if (instr->InputAt(0)->IsImmediate()) {
+        __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
+                RelocInfo::CODE_TARGET);
+      } else {
+        __ addiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
+        __ Call(at);
+      }
+      AddSafepointAndDeopt(instr);
+      break;
+    }
+    case kArchCallJSFunction: {
+      EnsureSpaceForLazyDeopt();
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        __ lw(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
+        __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
+      }
+
+      __ lw(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
+      __ Call(at);
+      AddSafepointAndDeopt(instr);
+      break;
+    }
+    case kArchJmp:
+      AssembleArchJump(i.InputRpo(0));
+      break;
+    case kArchNop:
+      // don't emit code for nops.
+      break;
+    case kArchRet:
+      AssembleReturn();
+      break;
+    case kArchStackPointer:
+      __ mov(i.OutputRegister(), sp);
+      break;
+    case kArchTruncateDoubleToI:
+      __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
+    case kMipsAdd:
+      __ Addu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsAddOvf:
+      __ AdduAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0),
+                                 i.InputOperand(1), kCompareReg, kScratchReg);
+      break;
+    case kMipsSub:
+      __ Subu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsSubOvf:
+      __ SubuAndCheckForOverflow(i.OutputRegister(), i.InputRegister(0),
+                                 i.InputOperand(1), kCompareReg, kScratchReg);
+      break;
+    case kMipsMul:
+      __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsMulHigh:
+      __ Mulh(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsMulHighU:
+      __ Mulhu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsDiv:
+      __ Div(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsDivU:
+      __ Divu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsMod:
+      __ Mod(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsModU:
+      __ Modu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsAnd:
+      __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsOr:
+      __ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsXor:
+      __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsShl:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ sllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        int32_t imm = i.InputOperand(1).immediate();
+        __ sll(i.OutputRegister(), i.InputRegister(0), imm);
+      }
+      break;
+    case kMipsShr:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ srlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        int32_t imm = i.InputOperand(1).immediate();
+        __ srl(i.OutputRegister(), i.InputRegister(0), imm);
+      }
+      break;
+    case kMipsSar:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ srav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        int32_t imm = i.InputOperand(1).immediate();
+        __ sra(i.OutputRegister(), i.InputRegister(0), imm);
+      }
+      break;
+    case kMipsRor:
+      __ Ror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMipsTst:
+      // Pseudo-instruction used for tst/branch. No opcode emitted here.
+      break;
+    case kMipsCmp:
+      // Pseudo-instruction used for cmp/branch. No opcode emitted here.
+      break;
+    case kMipsMov:
+      // TODO(plind): Should we combine mov/li like this, or use separate instr?
+      //    - Also see x64 ASSEMBLE_BINOP & RegisterOrOperandType
+      if (HasRegisterInput(instr, 0)) {
+        __ mov(i.OutputRegister(), i.InputRegister(0));
+      } else {
+        __ li(i.OutputRegister(), i.InputOperand(0));
+      }
+      break;
+
+    case kMipsCmpD:
+      // Psuedo-instruction used for FP cmp/branch. No opcode emitted here.
+      break;
+    case kMipsAddD:
+      // TODO(plind): add special case: combine mult & add.
+      __ add_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMipsSubD:
+      __ sub_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMipsMulD:
+      // TODO(plind): add special case: right op is -1.0, see arm port.
+      __ mul_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMipsDivD:
+      __ div_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMipsModD: {
+      // TODO(bmeurer): We should really get rid of this special instruction,
+      // and generate a CallAddress instruction instead.
+      FrameScope scope(masm(), StackFrame::MANUAL);
+      __ PrepareCallCFunction(0, 2, kScratchReg);
+      __ MovToFloatParameters(i.InputDoubleRegister(0),
+                              i.InputDoubleRegister(1));
+      __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()),
+                       0, 2);
+      // Move the result in the double result register.
+      __ MovFromFloatResult(i.OutputDoubleRegister());
+      break;
+    }
+    case kMipsFloat64Floor: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d, Floor);
+      break;
+    }
+    case kMipsFloat64Ceil: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil);
+      break;
+    }
+    case kMipsFloat64RoundTruncate: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d, Truncate);
+      break;
+    }
+    case kMipsSqrtD: {
+      __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
+    }
+    case kMipsCvtSD: {
+      __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0));
+      break;
+    }
+    case kMipsCvtDS: {
+      __ cvt_d_s(i.OutputDoubleRegister(), i.InputSingleRegister(0));
+      break;
+    }
+    case kMipsCvtDW: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ mtc1(i.InputRegister(0), scratch);
+      __ cvt_d_w(i.OutputDoubleRegister(), scratch);
+      break;
+    }
+    case kMipsCvtDUw: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ Cvt_d_uw(i.OutputDoubleRegister(), i.InputRegister(0), scratch);
+      break;
+    }
+    case kMipsTruncWD: {
+      FPURegister scratch = kScratchDoubleReg;
+      // Other arches use round to zero here, so we follow.
+      __ trunc_w_d(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMipsTruncUwD: {
+      FPURegister scratch = kScratchDoubleReg;
+      // TODO(plind): Fix wrong param order of Trunc_uw_d() macro-asm function.
+      __ Trunc_uw_d(i.InputDoubleRegister(0), i.OutputRegister(), scratch);
+      break;
+    }
+    // ... more basic instructions ...
+
+    case kMipsLbu:
+      __ lbu(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kMipsLb:
+      __ lb(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kMipsSb:
+      __ sb(i.InputRegister(2), i.MemoryOperand());
+      break;
+    case kMipsLhu:
+      __ lhu(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kMipsLh:
+      __ lh(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kMipsSh:
+      __ sh(i.InputRegister(2), i.MemoryOperand());
+      break;
+    case kMipsLw:
+      __ lw(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kMipsSw:
+      __ sw(i.InputRegister(2), i.MemoryOperand());
+      break;
+    case kMipsLwc1: {
+      __ lwc1(i.OutputSingleRegister(), i.MemoryOperand());
+      break;
+    }
+    case kMipsSwc1: {
+      int index = 0;
+      MemOperand operand = i.MemoryOperand(&index);
+      __ swc1(i.InputSingleRegister(index), operand);
+      break;
+    }
+    case kMipsLdc1:
+      __ ldc1(i.OutputDoubleRegister(), i.MemoryOperand());
+      break;
+    case kMipsSdc1:
+      __ sdc1(i.InputDoubleRegister(2), i.MemoryOperand());
+      break;
+    case kMipsPush:
+      __ Push(i.InputRegister(0));
+      break;
+    case kMipsStackClaim: {
+      int words = MiscField::decode(instr->opcode());
+      __ Subu(sp, sp, Operand(words << kPointerSizeLog2));
+      break;
+    }
+    case kMipsStoreToStackSlot: {
+      int slot = MiscField::decode(instr->opcode());
+      __ sw(i.InputRegister(0), MemOperand(sp, slot << kPointerSizeLog2));
+      break;
+    }
+    case kMipsStoreWriteBarrier: {
+      Register object = i.InputRegister(0);
+      Register index = i.InputRegister(1);
+      Register value = i.InputRegister(2);
+      __ addu(index, object, index);
+      __ sw(value, MemOperand(index));
+      SaveFPRegsMode mode =
+          frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
+      RAStatus ra_status = kRAHasNotBeenSaved;
+      __ RecordWrite(object, index, value, ra_status, mode);
+      break;
+    }
+    case kCheckedLoadInt8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lb);
+      break;
+    case kCheckedLoadUint8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lbu);
+      break;
+    case kCheckedLoadInt16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lh);
+      break;
+    case kCheckedLoadUint16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lhu);
+      break;
+    case kCheckedLoadWord32:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lw);
+      break;
+    case kCheckedLoadFloat32:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(Single, lwc1);
+      break;
+    case kCheckedLoadFloat64:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(Double, ldc1);
+      break;
+    case kCheckedStoreWord8:
+      ASSEMBLE_CHECKED_STORE_INTEGER(sb);
+      break;
+    case kCheckedStoreWord16:
+      ASSEMBLE_CHECKED_STORE_INTEGER(sh);
+      break;
+    case kCheckedStoreWord32:
+      ASSEMBLE_CHECKED_STORE_INTEGER(sw);
+      break;
+    case kCheckedStoreFloat32:
+      ASSEMBLE_CHECKED_STORE_FLOAT(Single, swc1);
+      break;
+    case kCheckedStoreFloat64:
+      ASSEMBLE_CHECKED_STORE_FLOAT(Double, sdc1);
+      break;
+  }
+}
+
+
+#define UNSUPPORTED_COND(opcode, condition)                                  \
+  OFStream out(stdout);                                                      \
+  out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \
+  UNIMPLEMENTED();
+
+// Assembles branches after an instruction.
+void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
+  MipsOperandConverter i(this, instr);
+  Label* tlabel = branch->true_label;
+  Label* flabel = branch->false_label;
+  Condition cc = kNoCondition;
+
+  // MIPS does not have condition code flags, so compare and branch are
+  // implemented differently than on the other arch's. The compare operations
+  // emit mips pseudo-instructions, which are handled here by branch
+  // instructions that do the actual comparison. Essential that the input
+  // registers to compare pseudo-op are not modified before this branch op, as
+  // they are tested here.
+  // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
+  //    not separated by other instructions.
+
+  if (instr->arch_opcode() == kMipsTst) {
+    switch (branch->condition) {
+      case kNotEqual:
+        cc = ne;
+        break;
+      case kEqual:
+        cc = eq;
+        break;
+      default:
+        UNSUPPORTED_COND(kMipsTst, branch->condition);
+        break;
+    }
+    __ And(at, i.InputRegister(0), i.InputOperand(1));
+    __ Branch(tlabel, cc, at, Operand(zero_reg));
+
+  } else if (instr->arch_opcode() == kMipsAddOvf ||
+             instr->arch_opcode() == kMipsSubOvf) {
+    // kMipsAddOvf, SubOvf emit negative result to 'kCompareReg' on overflow.
+    switch (branch->condition) {
+      case kOverflow:
+        cc = lt;
+        break;
+      case kNotOverflow:
+        cc = ge;
+        break;
+      default:
+        UNSUPPORTED_COND(kMipsAddOvf, branch->condition);
+        break;
+    }
+    __ Branch(tlabel, cc, kCompareReg, Operand(zero_reg));
+
+  } else if (instr->arch_opcode() == kMipsCmp) {
+    switch (branch->condition) {
+      case kEqual:
+        cc = eq;
+        break;
+      case kNotEqual:
+        cc = ne;
+        break;
+      case kSignedLessThan:
+        cc = lt;
+        break;
+      case kSignedGreaterThanOrEqual:
+        cc = ge;
+        break;
+      case kSignedLessThanOrEqual:
+        cc = le;
+        break;
+      case kSignedGreaterThan:
+        cc = gt;
+        break;
+      case kUnsignedLessThan:
+        cc = lo;
+        break;
+      case kUnsignedGreaterThanOrEqual:
+        cc = hs;
+        break;
+      case kUnsignedLessThanOrEqual:
+        cc = ls;
+        break;
+      case kUnsignedGreaterThan:
+        cc = hi;
+        break;
+      default:
+        UNSUPPORTED_COND(kMipsCmp, branch->condition);
+        break;
+    }
+    __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
+
+    if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
+
+  } else if (instr->arch_opcode() == kMipsCmpD) {
+    // TODO(dusmil) optimize unordered checks to use fewer instructions
+    // even if we have to unfold BranchF macro.
+    Label* nan = flabel;
+    switch (branch->condition) {
+      case kUnorderedEqual:
+        cc = eq;
+        break;
+      case kUnorderedNotEqual:
+        cc = ne;
+        nan = tlabel;
+        break;
+      case kUnorderedLessThan:
+        cc = lt;
+        break;
+      case kUnorderedGreaterThanOrEqual:
+        cc = ge;
+        nan = tlabel;
+        break;
+      case kUnorderedLessThanOrEqual:
+        cc = le;
+        break;
+      case kUnorderedGreaterThan:
+        cc = gt;
+        nan = tlabel;
+        break;
+      default:
+        UNSUPPORTED_COND(kMipsCmpD, branch->condition);
+        break;
+    }
+    __ BranchF(tlabel, nan, cc, i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+
+    if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
+
+  } else {
+    PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n",
+           instr->arch_opcode());
+    UNIMPLEMENTED();
+  }
+}
+
+
+void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+  if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
+}
+
+
+// Assembles boolean materializations after an instruction.
+void CodeGenerator::AssembleArchBoolean(Instruction* instr,
+                                        FlagsCondition condition) {
+  MipsOperandConverter i(this, instr);
+  Label done;
+
+  // Materialize a full 32-bit 1 or 0 value. The result register is always the
+  // last output of the instruction.
+  Label false_value;
+  DCHECK_NE(0, instr->OutputCount());
+  Register result = i.OutputRegister(instr->OutputCount() - 1);
+  Condition cc = kNoCondition;
+
+  // MIPS does not have condition code flags, so compare and branch are
+  // implemented differently than on the other arch's. The compare operations
+  // emit mips psuedo-instructions, which are checked and handled here.
+
+  // For materializations, we use delay slot to set the result true, and
+  // in the false case, where we fall thru the branch, we reset the result
+  // false.
+
+  // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
+  //    not separated by other instructions.
+  if (instr->arch_opcode() == kMipsTst) {
+    switch (condition) {
+      case kNotEqual:
+        cc = ne;
+        break;
+      case kEqual:
+        cc = eq;
+        break;
+      default:
+        UNSUPPORTED_COND(kMipsTst, condition);
+        break;
+    }
+    __ And(at, i.InputRegister(0), i.InputOperand(1));
+    __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg));
+    __ li(result, Operand(1));  // In delay slot.
+
+  } else if (instr->arch_opcode() == kMipsAddOvf ||
+             instr->arch_opcode() == kMipsSubOvf) {
+    // kMipsAddOvf, SubOvf emits negative result to 'kCompareReg' on overflow.
+    switch (condition) {
+      case kOverflow:
+        cc = lt;
+        break;
+      case kNotOverflow:
+        cc = ge;
+        break;
+      default:
+        UNSUPPORTED_COND(kMipsAddOvf, condition);
+        break;
+    }
+    __ Branch(USE_DELAY_SLOT, &done, cc, kCompareReg, Operand(zero_reg));
+    __ li(result, Operand(1));  // In delay slot.
+
+
+  } else if (instr->arch_opcode() == kMipsCmp) {
+    Register left = i.InputRegister(0);
+    Operand right = i.InputOperand(1);
+    switch (condition) {
+      case kEqual:
+        cc = eq;
+        break;
+      case kNotEqual:
+        cc = ne;
+        break;
+      case kSignedLessThan:
+        cc = lt;
+        break;
+      case kSignedGreaterThanOrEqual:
+        cc = ge;
+        break;
+      case kSignedLessThanOrEqual:
+        cc = le;
+        break;
+      case kSignedGreaterThan:
+        cc = gt;
+        break;
+      case kUnsignedLessThan:
+        cc = lo;
+        break;
+      case kUnsignedGreaterThanOrEqual:
+        cc = hs;
+        break;
+      case kUnsignedLessThanOrEqual:
+        cc = ls;
+        break;
+      case kUnsignedGreaterThan:
+        cc = hi;
+        break;
+      default:
+        UNSUPPORTED_COND(kMipsCmp, condition);
+        break;
+    }
+    __ Branch(USE_DELAY_SLOT, &done, cc, left, right);
+    __ li(result, Operand(1));  // In delay slot.
+
+  } else if (instr->arch_opcode() == kMipsCmpD) {
+    FPURegister left = i.InputDoubleRegister(0);
+    FPURegister right = i.InputDoubleRegister(1);
+    // TODO(plind): Provide NaN-testing macro-asm function without need for
+    // BranchF.
+    FPURegister dummy1 = f0;
+    FPURegister dummy2 = f2;
+    switch (condition) {
+      case kUnorderedEqual:
+        // TODO(plind):  improve the NaN testing throughout this function.
+        __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
+        cc = eq;
+        break;
+      case kUnorderedNotEqual:
+        __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
+        __ li(result, Operand(1));  // In delay slot - returns 1 on NaN.
+        cc = ne;
+        break;
+      case kUnorderedLessThan:
+        __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
+        cc = lt;
+        break;
+      case kUnorderedGreaterThanOrEqual:
+        __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
+        __ li(result, Operand(1));  // In delay slot - returns 1 on NaN.
+        cc = ge;
+        break;
+      case kUnorderedLessThanOrEqual:
+        __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
+        cc = le;
+        break;
+      case kUnorderedGreaterThan:
+        __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
+        __ li(result, Operand(1));  // In delay slot - returns 1 on NaN.
+        cc = gt;
+        break;
+      default:
+        UNSUPPORTED_COND(kMipsCmp, condition);
+        break;
+    }
+    __ BranchF(USE_DELAY_SLOT, &done, NULL, cc, left, right);
+    __ li(result, Operand(1));  // In delay slot - branch taken returns 1.
+                                // Fall-thru (branch not taken) returns 0.
+
+  } else {
+    PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n",
+           instr->arch_opcode());
+    TRACE_UNIMPL();
+    UNIMPLEMENTED();
+  }
+  // Fallthru case is the false materialization.
+  __ bind(&false_value);
+  __ li(result, Operand(0));
+  __ bind(&done);
+}
+
+
+void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
+  Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
+      isolate(), deoptimization_id, Deoptimizer::LAZY);
+  __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
+}
+
+
+void CodeGenerator::AssemblePrologue() {
+  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
+  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+    __ Push(ra, fp);
+    __ mov(fp, sp);
+    const RegList saves = descriptor->CalleeSavedRegisters();
+    if (saves != 0) {  // Save callee-saved registers.
+      // TODO(plind): make callee save size const, possibly DCHECK it.
+      int register_save_area_size = 0;
+      for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
+        if (!((1 << i) & saves)) continue;
+        register_save_area_size += kPointerSize;
+      }
+      frame()->SetRegisterSaveAreaSize(register_save_area_size);
+      __ MultiPush(saves);
+    }
+  } else if (descriptor->IsJSFunctionCall()) {
+    CompilationInfo* info = this->info();
+    __ Prologue(info->IsCodePreAgingActive());
+    frame()->SetRegisterSaveAreaSize(
+        StandardFrameConstants::kFixedFrameSizeFromFp);
+  } else {
+    __ StubPrologue();
+    frame()->SetRegisterSaveAreaSize(
+        StandardFrameConstants::kFixedFrameSizeFromFp);
+  }
+  int stack_slots = frame()->GetSpillSlotCount();
+  if (stack_slots > 0) {
+    __ Subu(sp, sp, Operand(stack_slots * kPointerSize));
+  }
+}
+
+
+void CodeGenerator::AssembleReturn() {
+  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
+  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+    if (frame()->GetRegisterSaveAreaSize() > 0) {
+      // Remove this frame's spill slots first.
+      int stack_slots = frame()->GetSpillSlotCount();
+      if (stack_slots > 0) {
+        __ Addu(sp, sp, Operand(stack_slots * kPointerSize));
+      }
+      // Restore registers.
+      const RegList saves = descriptor->CalleeSavedRegisters();
+      if (saves != 0) {
+        __ MultiPop(saves);
+      }
+    }
+    __ mov(sp, fp);
+    __ Pop(ra, fp);
+    __ Ret();
+  } else {
+    __ mov(sp, fp);
+    __ Pop(ra, fp);
+    int pop_count = descriptor->IsJSFunctionCall()
+                        ? static_cast<int>(descriptor->JSParameterCount())
+                        : 0;
+    __ DropAndRet(pop_count);
+  }
+}
+
+
+void CodeGenerator::AssembleMove(InstructionOperand* source,
+                                 InstructionOperand* destination) {
+  MipsOperandConverter g(this, NULL);
+  // Dispatch on the source and destination operand kinds.  Not all
+  // combinations are possible.
+  if (source->IsRegister()) {
+    DCHECK(destination->IsRegister() || destination->IsStackSlot());
+    Register src = g.ToRegister(source);
+    if (destination->IsRegister()) {
+      __ mov(g.ToRegister(destination), src);
+    } else {
+      __ sw(src, g.ToMemOperand(destination));
+    }
+  } else if (source->IsStackSlot()) {
+    DCHECK(destination->IsRegister() || destination->IsStackSlot());
+    MemOperand src = g.ToMemOperand(source);
+    if (destination->IsRegister()) {
+      __ lw(g.ToRegister(destination), src);
+    } else {
+      Register temp = kScratchReg;
+      __ lw(temp, src);
+      __ sw(temp, g.ToMemOperand(destination));
+    }
+  } else if (source->IsConstant()) {
+    Constant src = g.ToConstant(source);
+    if (destination->IsRegister() || destination->IsStackSlot()) {
+      Register dst =
+          destination->IsRegister() ? g.ToRegister(destination) : kScratchReg;
+      switch (src.type()) {
+        case Constant::kInt32:
+          __ li(dst, Operand(src.ToInt32()));
+          break;
+        case Constant::kFloat32:
+          __ li(dst, isolate()->factory()->NewNumber(src.ToFloat32(), TENURED));
+          break;
+        case Constant::kInt64:
+          UNREACHABLE();
+          break;
+        case Constant::kFloat64:
+          __ li(dst, isolate()->factory()->NewNumber(src.ToFloat64(), TENURED));
+          break;
+        case Constant::kExternalReference:
+          __ li(dst, Operand(src.ToExternalReference()));
+          break;
+        case Constant::kHeapObject:
+          __ li(dst, src.ToHeapObject());
+          break;
+        case Constant::kRpoNumber:
+          UNREACHABLE();  // TODO(titzer): loading RPO numbers on mips.
+          break;
+      }
+      if (destination->IsStackSlot()) __ sw(dst, g.ToMemOperand(destination));
+    } else if (src.type() == Constant::kFloat32) {
+      if (destination->IsDoubleStackSlot()) {
+        MemOperand dst = g.ToMemOperand(destination);
+        __ li(at, Operand(bit_cast<int32_t>(src.ToFloat32())));
+        __ sw(at, dst);
+      } else {
+        FloatRegister dst = g.ToSingleRegister(destination);
+        __ Move(dst, src.ToFloat32());
+      }
+    } else {
+      DCHECK_EQ(Constant::kFloat64, src.type());
+      DoubleRegister dst = destination->IsDoubleRegister()
+                               ? g.ToDoubleRegister(destination)
+                               : kScratchDoubleReg;
+      __ Move(dst, src.ToFloat64());
+      if (destination->IsDoubleStackSlot()) {
+        __ sdc1(dst, g.ToMemOperand(destination));
+      }
+    }
+  } else if (source->IsDoubleRegister()) {
+    FPURegister src = g.ToDoubleRegister(source);
+    if (destination->IsDoubleRegister()) {
+      FPURegister dst = g.ToDoubleRegister(destination);
+      __ Move(dst, src);
+    } else {
+      DCHECK(destination->IsDoubleStackSlot());
+      __ sdc1(src, g.ToMemOperand(destination));
+    }
+  } else if (source->IsDoubleStackSlot()) {
+    DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot());
+    MemOperand src = g.ToMemOperand(source);
+    if (destination->IsDoubleRegister()) {
+      __ ldc1(g.ToDoubleRegister(destination), src);
+    } else {
+      FPURegister temp = kScratchDoubleReg;
+      __ ldc1(temp, src);
+      __ sdc1(temp, g.ToMemOperand(destination));
+    }
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
+void CodeGenerator::AssembleSwap(InstructionOperand* source,
+                                 InstructionOperand* destination) {
+  MipsOperandConverter g(this, NULL);
+  // Dispatch on the source and destination operand kinds.  Not all
+  // combinations are possible.
+  if (source->IsRegister()) {
+    // Register-register.
+    Register temp = kScratchReg;
+    Register src = g.ToRegister(source);
+    if (destination->IsRegister()) {
+      Register dst = g.ToRegister(destination);
+      __ Move(temp, src);
+      __ Move(src, dst);
+      __ Move(dst, temp);
+    } else {
+      DCHECK(destination->IsStackSlot());
+      MemOperand dst = g.ToMemOperand(destination);
+      __ mov(temp, src);
+      __ lw(src, dst);
+      __ sw(temp, dst);
+    }
+  } else if (source->IsStackSlot()) {
+    DCHECK(destination->IsStackSlot());
+    Register temp_0 = kScratchReg;
+    Register temp_1 = kCompareReg;
+    MemOperand src = g.ToMemOperand(source);
+    MemOperand dst = g.ToMemOperand(destination);
+    __ lw(temp_0, src);
+    __ lw(temp_1, dst);
+    __ sw(temp_0, dst);
+    __ sw(temp_1, src);
+  } else if (source->IsDoubleRegister()) {
+    FPURegister temp = kScratchDoubleReg;
+    FPURegister src = g.ToDoubleRegister(source);
+    if (destination->IsDoubleRegister()) {
+      FPURegister dst = g.ToDoubleRegister(destination);
+      __ Move(temp, src);
+      __ Move(src, dst);
+      __ Move(dst, temp);
+    } else {
+      DCHECK(destination->IsDoubleStackSlot());
+      MemOperand dst = g.ToMemOperand(destination);
+      __ Move(temp, src);
+      __ ldc1(src, dst);
+      __ sdc1(temp, dst);
+    }
+  } else if (source->IsDoubleStackSlot()) {
+    DCHECK(destination->IsDoubleStackSlot());
+    Register temp_0 = kScratchReg;
+    FPURegister temp_1 = kScratchDoubleReg;
+    MemOperand src0 = g.ToMemOperand(source);
+    MemOperand src1(src0.rm(), src0.offset() + kPointerSize);
+    MemOperand dst0 = g.ToMemOperand(destination);
+    MemOperand dst1(dst0.rm(), dst0.offset() + kPointerSize);
+    __ ldc1(temp_1, dst0);  // Save destination in temp_1.
+    __ lw(temp_0, src0);    // Then use temp_0 to copy source to destination.
+    __ sw(temp_0, dst0);
+    __ lw(temp_0, src1);
+    __ sw(temp_0, dst1);
+    __ sdc1(temp_1, src0);
+  } else {
+    // No other combinations are possible.
+    UNREACHABLE();
+  }
+}
+
+
+void CodeGenerator::AddNopForSmiCodeInlining() {
+  // Unused on 32-bit ARM. Still exists on 64-bit arm.
+  // TODO(plind): Unclear when this is called now. Understand, fix if needed.
+  __ nop();  // Maybe PROPERTY_ACCESS_INLINED?
+}
+
+
+void CodeGenerator::EnsureSpaceForLazyDeopt() {
+  int space_needed = Deoptimizer::patch_size();
+  if (!info()->IsStub()) {
+    // Ensure that we have enough space after the previous lazy-bailout
+    // instruction for patching the code here.
+    int current_pc = masm()->pc_offset();
+    if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+      // Block tramoline pool emission for duration of padding.
+      v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
+          masm());
+      int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+      DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
+      while (padding_size > 0) {
+        __ nop();
+        padding_size -= v8::internal::Assembler::kInstrSize;
+      }
+    }
+  }
+  MarkLazyDeoptSite();
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/mips/instruction-codes-mips.h b/src/compiler/mips/instruction-codes-mips.h
new file mode 100644
index 0000000..3aa508f
--- /dev/null
+++ b/src/compiler/mips/instruction-codes-mips.h
@@ -0,0 +1,93 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_MIPS_INSTRUCTION_CODES_MIPS_H_
+#define V8_COMPILER_MIPS_INSTRUCTION_CODES_MIPS_H_
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// MIPS-specific opcodes that specify which assembly sequence to emit.
+// Most opcodes specify a single instruction.
+#define TARGET_ARCH_OPCODE_LIST(V) \
+  V(MipsAdd)                       \
+  V(MipsAddOvf)                    \
+  V(MipsSub)                       \
+  V(MipsSubOvf)                    \
+  V(MipsMul)                       \
+  V(MipsMulHigh)                   \
+  V(MipsMulHighU)                  \
+  V(MipsDiv)                       \
+  V(MipsDivU)                      \
+  V(MipsMod)                       \
+  V(MipsModU)                      \
+  V(MipsAnd)                       \
+  V(MipsOr)                        \
+  V(MipsXor)                       \
+  V(MipsShl)                       \
+  V(MipsShr)                       \
+  V(MipsSar)                       \
+  V(MipsRor)                       \
+  V(MipsMov)                       \
+  V(MipsTst)                       \
+  V(MipsCmp)                       \
+  V(MipsCmpD)                      \
+  V(MipsAddD)                      \
+  V(MipsSubD)                      \
+  V(MipsMulD)                      \
+  V(MipsDivD)                      \
+  V(MipsModD)                      \
+  V(MipsSqrtD)                     \
+  V(MipsFloat64Floor)              \
+  V(MipsFloat64Ceil)               \
+  V(MipsFloat64RoundTruncate)      \
+  V(MipsCvtSD)                     \
+  V(MipsCvtDS)                     \
+  V(MipsTruncWD)                   \
+  V(MipsTruncUwD)                  \
+  V(MipsCvtDW)                     \
+  V(MipsCvtDUw)                    \
+  V(MipsLb)                        \
+  V(MipsLbu)                       \
+  V(MipsSb)                        \
+  V(MipsLh)                        \
+  V(MipsLhu)                       \
+  V(MipsSh)                        \
+  V(MipsLw)                        \
+  V(MipsSw)                        \
+  V(MipsLwc1)                      \
+  V(MipsSwc1)                      \
+  V(MipsLdc1)                      \
+  V(MipsSdc1)                      \
+  V(MipsPush)                      \
+  V(MipsStoreToStackSlot)          \
+  V(MipsStackClaim)                \
+  V(MipsStoreWriteBarrier)
+
+
+// Addressing modes represent the "shape" of inputs to an instruction.
+// Many instructions support multiple addressing modes. Addressing modes
+// are encoded into the InstructionCode of the instruction and tell the
+// code generator after register allocation which assembler method to call.
+//
+// We use the following local notation for addressing modes:
+//
+// R = register
+// O = register or stack slot
+// D = double register
+// I = immediate (handle, external, int32)
+// MRI = [register + immediate]
+// MRR = [register + register]
+// TODO(plind): Add the new r6 address modes.
+#define TARGET_ADDRESSING_MODE_LIST(V) \
+  V(MRI) /* [%r0 + K] */               \
+  V(MRR) /* [%r0 + %r1] */
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_MIPS_INSTRUCTION_CODES_MIPS_H_
diff --git a/src/compiler/mips/instruction-selector-mips.cc b/src/compiler/mips/instruction-selector-mips.cc
new file mode 100644
index 0000000..5e8e3b1
--- /dev/null
+++ b/src/compiler/mips/instruction-selector-mips.cc
@@ -0,0 +1,831 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/base/bits.h"
+#include "src/compiler/instruction-selector-impl.h"
+#include "src/compiler/node-matchers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+#define TRACE_UNIMPL() \
+  PrintF("UNIMPLEMENTED instr_sel: %s at line %d\n", __FUNCTION__, __LINE__)
+
+#define TRACE() PrintF("instr_sel: %s at line %d\n", __FUNCTION__, __LINE__)
+
+
+// Adds Mips-specific methods for generating InstructionOperands.
+class MipsOperandGenerator FINAL : public OperandGenerator {
+ public:
+  explicit MipsOperandGenerator(InstructionSelector* selector)
+      : OperandGenerator(selector) {}
+
+  InstructionOperand* UseOperand(Node* node, InstructionCode opcode) {
+    if (CanBeImmediate(node, opcode)) {
+      return UseImmediate(node);
+    }
+    return UseRegister(node);
+  }
+
+  bool CanBeImmediate(Node* node, InstructionCode opcode) {
+    Int32Matcher m(node);
+    if (!m.HasValue()) return false;
+    int32_t value = m.Value();
+    switch (ArchOpcodeField::decode(opcode)) {
+      case kMipsShl:
+      case kMipsSar:
+      case kMipsShr:
+        return is_uint5(value);
+      case kMipsXor:
+        return is_uint16(value);
+      case kMipsLdc1:
+      case kMipsSdc1:
+      case kCheckedLoadFloat32:
+      case kCheckedLoadFloat64:
+      case kCheckedStoreFloat32:
+      case kCheckedStoreFloat64:
+        return is_int16(value + kIntSize);
+      default:
+        return is_int16(value);
+    }
+  }
+
+ private:
+  bool ImmediateFitsAddrMode1Instruction(int32_t imm) const {
+    TRACE_UNIMPL();
+    return false;
+  }
+};
+
+
+static void VisitRRR(InstructionSelector* selector, ArchOpcode opcode,
+                     Node* node) {
+  MipsOperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)),
+                 g.UseRegister(node->InputAt(1)));
+}
+
+
+static void VisitRR(InstructionSelector* selector, ArchOpcode opcode,
+                    Node* node) {
+  MipsOperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)));
+}
+
+
+static void VisitRRO(InstructionSelector* selector, ArchOpcode opcode,
+                     Node* node) {
+  MipsOperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)),
+                 g.UseOperand(node->InputAt(1), opcode));
+}
+
+
+static void VisitBinop(InstructionSelector* selector, Node* node,
+                       InstructionCode opcode, FlagsContinuation* cont) {
+  MipsOperandGenerator g(selector);
+  Int32BinopMatcher m(node);
+  InstructionOperand* inputs[4];
+  size_t input_count = 0;
+  InstructionOperand* outputs[2];
+  size_t output_count = 0;
+
+  inputs[input_count++] = g.UseRegister(m.left().node());
+  inputs[input_count++] = g.UseOperand(m.right().node(), opcode);
+
+  if (cont->IsBranch()) {
+    inputs[input_count++] = g.Label(cont->true_block());
+    inputs[input_count++] = g.Label(cont->false_block());
+  }
+
+  outputs[output_count++] = g.DefineAsRegister(node);
+  if (cont->IsSet()) {
+    outputs[output_count++] = g.DefineAsRegister(cont->result());
+  }
+
+  DCHECK_NE(0, input_count);
+  DCHECK_NE(0, output_count);
+  DCHECK_GE(arraysize(inputs), input_count);
+  DCHECK_GE(arraysize(outputs), output_count);
+
+  Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
+                                      outputs, input_count, inputs);
+  if (cont->IsBranch()) instr->MarkAsControl();
+}
+
+
+static void VisitBinop(InstructionSelector* selector, Node* node,
+                       InstructionCode opcode) {
+  FlagsContinuation cont;
+  VisitBinop(selector, node, opcode, &cont);
+}
+
+
+void InstructionSelector::VisitLoad(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
+  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
+  MipsOperandGenerator g(this);
+  Node* base = node->InputAt(0);
+  Node* index = node->InputAt(1);
+
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepFloat32:
+      opcode = kMipsLwc1;
+      break;
+    case kRepFloat64:
+      opcode = kMipsLdc1;
+      break;
+    case kRepBit:  // Fall through.
+    case kRepWord8:
+      opcode = typ == kTypeUint32 ? kMipsLbu : kMipsLb;
+      break;
+    case kRepWord16:
+      opcode = typ == kTypeUint32 ? kMipsLhu : kMipsLh;
+      break;
+    case kRepTagged:  // Fall through.
+    case kRepWord32:
+      opcode = kMipsLw;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+
+  if (g.CanBeImmediate(index, opcode)) {
+    Emit(opcode | AddressingModeField::encode(kMode_MRI),
+         g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
+  } else {
+    InstructionOperand* addr_reg = g.TempRegister();
+    Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
+         g.UseRegister(index), g.UseRegister(base));
+    // Emit desired load opcode, using temp addr_reg.
+    Emit(opcode | AddressingModeField::encode(kMode_MRI),
+         g.DefineAsRegister(node), addr_reg, g.TempImmediate(0));
+  }
+}
+
+
+void InstructionSelector::VisitStore(Node* node) {
+  MipsOperandGenerator g(this);
+  Node* base = node->InputAt(0);
+  Node* index = node->InputAt(1);
+  Node* value = node->InputAt(2);
+
+  StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
+  MachineType rep = RepresentationOf(store_rep.machine_type());
+  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
+    DCHECK(rep == kRepTagged);
+    // TODO(dcarney): refactor RecordWrite function to take temp registers
+    //                and pass them here instead of using fixed regs
+    // TODO(dcarney): handle immediate indices.
+    InstructionOperand* temps[] = {g.TempRegister(t1), g.TempRegister(t2)};
+    Emit(kMipsStoreWriteBarrier, NULL, g.UseFixed(base, t0),
+         g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps);
+    return;
+  }
+  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
+
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepFloat32:
+      opcode = kMipsSwc1;
+      break;
+    case kRepFloat64:
+      opcode = kMipsSdc1;
+      break;
+    case kRepBit:  // Fall through.
+    case kRepWord8:
+      opcode = kMipsSb;
+      break;
+    case kRepWord16:
+      opcode = kMipsSh;
+      break;
+    case kRepTagged:  // Fall through.
+    case kRepWord32:
+      opcode = kMipsSw;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+
+  if (g.CanBeImmediate(index, opcode)) {
+    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
+         g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
+  } else {
+    InstructionOperand* addr_reg = g.TempRegister();
+    Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg,
+         g.UseRegister(index), g.UseRegister(base));
+    // Emit desired store opcode, using temp addr_reg.
+    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, addr_reg,
+         g.TempImmediate(0), g.UseRegister(value));
+  }
+}
+
+
+void InstructionSelector::VisitWord32And(Node* node) {
+  VisitBinop(this, node, kMipsAnd);
+}
+
+
+void InstructionSelector::VisitWord32Or(Node* node) {
+  VisitBinop(this, node, kMipsOr);
+}
+
+
+void InstructionSelector::VisitWord32Xor(Node* node) {
+  VisitBinop(this, node, kMipsXor);
+}
+
+
+void InstructionSelector::VisitWord32Shl(Node* node) {
+  VisitRRO(this, kMipsShl, node);
+}
+
+
+void InstructionSelector::VisitWord32Shr(Node* node) {
+  VisitRRO(this, kMipsShr, node);
+}
+
+
+void InstructionSelector::VisitWord32Sar(Node* node) {
+  VisitRRO(this, kMipsSar, node);
+}
+
+
+void InstructionSelector::VisitWord32Ror(Node* node) {
+  VisitRRO(this, kMipsRor, node);
+}
+
+
+void InstructionSelector::VisitInt32Add(Node* node) {
+  MipsOperandGenerator g(this);
+
+  // TODO(plind): Consider multiply & add optimization from arm port.
+  VisitBinop(this, node, kMipsAdd);
+}
+
+
+void InstructionSelector::VisitInt32Sub(Node* node) {
+  VisitBinop(this, node, kMipsSub);
+}
+
+
+void InstructionSelector::VisitInt32Mul(Node* node) {
+  MipsOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.right().HasValue() && m.right().Value() > 0) {
+    int32_t value = m.right().Value();
+    if (base::bits::IsPowerOfTwo32(value)) {
+      Emit(kMipsShl | AddressingModeField::encode(kMode_None),
+           g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+           g.TempImmediate(WhichPowerOf2(value)));
+      return;
+    }
+    if (base::bits::IsPowerOfTwo32(value - 1)) {
+      InstructionOperand* temp = g.TempRegister();
+      Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp,
+           g.UseRegister(m.left().node()),
+           g.TempImmediate(WhichPowerOf2(value - 1)));
+      Emit(kMipsAdd | AddressingModeField::encode(kMode_None),
+           g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp);
+      return;
+    }
+    if (base::bits::IsPowerOfTwo32(value + 1)) {
+      InstructionOperand* temp = g.TempRegister();
+      Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp,
+           g.UseRegister(m.left().node()),
+           g.TempImmediate(WhichPowerOf2(value + 1)));
+      Emit(kMipsSub | AddressingModeField::encode(kMode_None),
+           g.DefineAsRegister(node), temp, g.UseRegister(m.left().node()));
+      return;
+    }
+  }
+  Emit(kMipsMul, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitInt32MulHigh(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsMulHigh, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
+       g.UseRegister(node->InputAt(1)));
+}
+
+
+void InstructionSelector::VisitUint32MulHigh(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsMulHighU, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
+       g.UseRegister(node->InputAt(1)));
+}
+
+
+void InstructionSelector::VisitInt32Div(Node* node) {
+  MipsOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  Emit(kMipsDiv, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitUint32Div(Node* node) {
+  MipsOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  Emit(kMipsDivU, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitInt32Mod(Node* node) {
+  MipsOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  Emit(kMipsMod, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitUint32Mod(Node* node) {
+  MipsOperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  Emit(kMipsModU, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsCvtDS, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsCvtDW, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsCvtDUw, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsTruncWD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsTruncUwD, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsCvtSD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64Add(Node* node) {
+  VisitRRR(this, kMipsAddD, node);
+}
+
+
+void InstructionSelector::VisitFloat64Sub(Node* node) {
+  VisitRRR(this, kMipsSubD, node);
+}
+
+
+void InstructionSelector::VisitFloat64Mul(Node* node) {
+  VisitRRR(this, kMipsMulD, node);
+}
+
+
+void InstructionSelector::VisitFloat64Div(Node* node) {
+  VisitRRR(this, kMipsDivD, node);
+}
+
+
+void InstructionSelector::VisitFloat64Mod(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsModD, g.DefineAsFixed(node, f0), g.UseFixed(node->InputAt(0), f12),
+       g.UseFixed(node->InputAt(1), f14))->MarkAsCall();
+}
+
+
+void InstructionSelector::VisitFloat64Sqrt(Node* node) {
+  MipsOperandGenerator g(this);
+  Emit(kMipsSqrtD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64Floor(Node* node) {
+  VisitRR(this, kMipsFloat64Floor, node);
+}
+
+
+void InstructionSelector::VisitFloat64Ceil(Node* node) {
+  VisitRR(this, kMipsFloat64Ceil, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
+  VisitRR(this, kMipsFloat64RoundTruncate, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
+  UNREACHABLE();
+}
+
+
+void InstructionSelector::VisitCall(Node* node) {
+  MipsOperandGenerator g(this);
+  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
+
+  FrameStateDescriptor* frame_state_descriptor = NULL;
+  if (descriptor->NeedsFrameState()) {
+    frame_state_descriptor =
+        GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
+  }
+
+  CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
+
+  // Compute InstructionOperands for inputs and outputs.
+  InitializeCallBuffer(node, &buffer, true, false);
+  // Possibly align stack here for functions.
+  int push_count = buffer.pushed_nodes.size();
+  if (push_count > 0) {
+    Emit(kMipsStackClaim | MiscField::encode(push_count), NULL);
+  }
+  int slot = buffer.pushed_nodes.size() - 1;
+  for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
+       input != buffer.pushed_nodes.rend(); input++) {
+    Emit(kMipsStoreToStackSlot | MiscField::encode(slot), NULL,
+         g.UseRegister(*input));
+    slot--;
+  }
+
+  // Select the appropriate opcode based on the call type.
+  InstructionCode opcode;
+  switch (descriptor->kind()) {
+    case CallDescriptor::kCallCodeObject: {
+      opcode = kArchCallCodeObject;
+      break;
+    }
+    case CallDescriptor::kCallJSFunction:
+      opcode = kArchCallJSFunction;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  opcode |= MiscField::encode(descriptor->flags());
+
+  // Emit the call instruction.
+  InstructionOperand** first_output =
+      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
+  Instruction* call_instr =
+      Emit(opcode, buffer.outputs.size(), first_output,
+           buffer.instruction_args.size(), &buffer.instruction_args.front());
+  call_instr->MarkAsCall();
+}
+
+
+void InstructionSelector::VisitCheckedLoad(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  MipsOperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepWord8:
+      opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
+      break;
+    case kRepWord16:
+      opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
+      break;
+    case kRepWord32:
+      opcode = kCheckedLoadWord32;
+      break;
+    case kRepFloat32:
+      opcode = kCheckedLoadFloat32;
+      break;
+    case kRepFloat64:
+      opcode = kCheckedLoadFloat64;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
+                                           ? g.UseImmediate(offset)
+                                           : g.UseRegister(offset);
+
+  InstructionOperand* length_operand =
+      (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
+      ? g.UseImmediate(length)
+      : g.UseRegister(length)
+      : g.UseRegister(length);
+
+  Emit(opcode | AddressingModeField::encode(kMode_MRI),
+       g.DefineAsRegister(node), offset_operand, length_operand,
+       g.UseRegister(buffer));
+}
+
+
+void InstructionSelector::VisitCheckedStore(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MipsOperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  Node* const value = node->InputAt(3);
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepWord8:
+      opcode = kCheckedStoreWord8;
+      break;
+    case kRepWord16:
+      opcode = kCheckedStoreWord16;
+      break;
+    case kRepWord32:
+      opcode = kCheckedStoreWord32;
+      break;
+    case kRepFloat32:
+      opcode = kCheckedStoreFloat32;
+      break;
+    case kRepFloat64:
+      opcode = kCheckedStoreFloat64;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
+                                           ? g.UseImmediate(offset)
+                                           : g.UseRegister(offset);
+
+  InstructionOperand* length_operand =
+      (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
+      ? g.UseImmediate(length)
+      : g.UseRegister(length)
+      : g.UseRegister(length);
+
+  Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand,
+       length_operand, g.UseRegister(value), g.UseRegister(buffer));
+}
+
+
+namespace {
+
+// Shared routine for multiple compare operations.
+static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                         InstructionOperand* left, InstructionOperand* right,
+                         FlagsContinuation* cont) {
+  MipsOperandGenerator g(selector);
+  opcode = cont->Encode(opcode);
+  if (cont->IsBranch()) {
+    selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()),
+                   g.Label(cont->false_block()))->MarkAsControl();
+  } else {
+    DCHECK(cont->IsSet());
+    // TODO(plind): Revisit and test this path.
+    selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
+  }
+}
+
+
+// Shared routine for multiple float compare operations.
+void VisitFloat64Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  MipsOperandGenerator g(selector);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  VisitCompare(selector, kMipsCmpD, g.UseRegister(left), g.UseRegister(right),
+               cont);
+}
+
+
+// Shared routine for multiple word compare operations.
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      InstructionCode opcode, FlagsContinuation* cont,
+                      bool commutative) {
+  MipsOperandGenerator g(selector);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+
+  // Match immediates on left or right side of comparison.
+  if (g.CanBeImmediate(right, opcode)) {
+    VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
+                 cont);
+  } else if (g.CanBeImmediate(left, opcode)) {
+    if (!commutative) cont->Commute();
+    VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
+                 cont);
+  } else {
+    VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right),
+                 cont);
+  }
+}
+
+
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      FlagsContinuation* cont) {
+  VisitWordCompare(selector, node, kMipsCmp, cont, false);
+}
+
+}  // namespace
+
+
+// Shared routine for word comparisons against zero.
+void VisitWordCompareZero(InstructionSelector* selector, Node* user,
+                          Node* value, FlagsContinuation* cont) {
+  while (selector->CanCover(user, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kWord32Equal: {
+        // Combine with comparisons against 0 by simply inverting the
+        // continuation.
+        Int32BinopMatcher m(value);
+        if (m.right().Is(0)) {
+          user = value;
+          value = m.left().node();
+          cont->Negate();
+          continue;
+        }
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitWordCompare(selector, value, cont);
+      }
+      case IrOpcode::kInt32LessThan:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThan);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kInt32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kUint32LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kUint32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWordCompare(selector, value, cont);
+      case IrOpcode::kFloat64Equal:
+        cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kFloat64LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnorderedLessThan);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kFloat64LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kProjection:
+        // Check if this is the overflow output projection of an
+        // <Operation>WithOverflow node.
+        if (OpParameter<size_t>(value) == 1u) {
+          // We cannot combine the <Operation>WithOverflow with this branch
+          // unless the 0th projection (the use of the actual value of the
+          // <Operation> is either NULL, which means there's no use of the
+          // actual value, or was already defined, which means it is scheduled
+          // *AFTER* this branch).
+          Node* const node = value->InputAt(0);
+          Node* const result = node->FindProjection(0);
+          if (!result || selector->IsDefined(result)) {
+            switch (node->opcode()) {
+              case IrOpcode::kInt32AddWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(selector, node, kMipsAddOvf, cont);
+              case IrOpcode::kInt32SubWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(selector, node, kMipsSubOvf, cont);
+              default:
+                break;
+            }
+          }
+        }
+        break;
+      case IrOpcode::kWord32And:
+        return VisitWordCompare(selector, value, kMipsTst, cont, true);
+      default:
+        break;
+    }
+    break;
+  }
+
+  // Continuation could not be combined with a compare, emit compare against 0.
+  MipsOperandGenerator g(selector);
+  InstructionCode const opcode = cont->Encode(kMipsCmp);
+  InstructionOperand* const value_operand = g.UseRegister(value);
+  if (cont->IsBranch()) {
+    selector->Emit(opcode, nullptr, value_operand, g.TempImmediate(0),
+                   g.Label(cont->true_block()),
+                   g.Label(cont->false_block()))->MarkAsControl();
+  } else {
+    selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand,
+                   g.TempImmediate(0));
+  }
+}
+
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+                                      BasicBlock* fbranch) {
+  FlagsContinuation cont(kNotEqual, tbranch, fbranch);
+  VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
+}
+
+
+void InstructionSelector::VisitWord32Equal(Node* const node) {
+  FlagsContinuation cont(kEqual, node);
+  Int32BinopMatcher m(node);
+  if (m.right().Is(0)) {
+    return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
+  }
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kMipsAddOvf, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kMipsAddOvf, &cont);
+}
+
+
+void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kMipsSubOvf, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kMipsSubOvf, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64Equal(Node* node) {
+  FlagsContinuation cont(kUnorderedEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThan(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThan, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+    return MachineOperatorBuilder::kFloat64Floor |
+           MachineOperatorBuilder::kFloat64Ceil |
+           MachineOperatorBuilder::kFloat64RoundTruncate;
+  }
+  return MachineOperatorBuilder::kNoFlags;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/mips/linkage-mips.cc b/src/compiler/mips/linkage-mips.cc
new file mode 100644
index 0000000..2b314a2
--- /dev/null
+++ b/src/compiler/mips/linkage-mips.cc
@@ -0,0 +1,67 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/assembler.h"
+#include "src/code-stubs.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/linkage-impl.h"
+#include "src/zone.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+struct MipsLinkageHelperTraits {
+  static Register ReturnValueReg() { return v0; }
+  static Register ReturnValue2Reg() { return v1; }
+  static Register JSCallFunctionReg() { return a1; }
+  static Register ContextReg() { return cp; }
+  static Register RuntimeCallFunctionReg() { return a1; }
+  static Register RuntimeCallArgCountReg() { return a0; }
+  static RegList CCalleeSaveRegisters() {
+    return s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() |
+           s6.bit() | s7.bit();
+  }
+  static Register CRegisterParameter(int i) {
+    static Register register_parameters[] = {a0, a1, a2, a3};
+    return register_parameters[i];
+  }
+  static int CRegisterParametersLength() { return 4; }
+};
+
+
+typedef LinkageHelper<MipsLinkageHelperTraits> LH;
+
+CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
+                                             CallDescriptor::Flags flags) {
+  return LH::GetJSCallDescriptor(zone, parameter_count, flags);
+}
+
+
+CallDescriptor* Linkage::GetRuntimeCallDescriptor(
+    Runtime::FunctionId function, int parameter_count,
+    Operator::Properties properties, Zone* zone) {
+  return LH::GetRuntimeCallDescriptor(zone, function, parameter_count,
+                                      properties);
+}
+
+
+CallDescriptor* Linkage::GetStubCallDescriptor(
+    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
+    CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone) {
+  return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count,
+                                   flags, properties);
+}
+
+
+CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
+                                                  MachineSignature* sig) {
+  return LH::GetSimplifiedCDescriptor(zone, sig);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/mips64/OWNERS b/src/compiler/mips64/OWNERS
new file mode 100644
index 0000000..5508ba6
--- /dev/null
+++ b/src/compiler/mips64/OWNERS
@@ -0,0 +1,5 @@
+paul.lind@imgtec.com
+gergely.kis@imgtec.com
+akos.palfi@imgtec.com
+balazs.kilvady@imgtec.com
+dusan.milosavljevic@imgtec.com
diff --git a/src/compiler/mips64/code-generator-mips64.cc b/src/compiler/mips64/code-generator-mips64.cc
new file mode 100644
index 0000000..dee7705
--- /dev/null
+++ b/src/compiler/mips64/code-generator-mips64.cc
@@ -0,0 +1,1444 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/code-generator.h"
+#include "src/compiler/code-generator-impl.h"
+#include "src/compiler/gap-resolver.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/mips/macro-assembler-mips.h"
+#include "src/scopes.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+#define __ masm()->
+
+
+// TODO(plind): Possibly avoid using these lithium names.
+#define kScratchReg kLithiumScratchReg
+#define kScratchReg2 kLithiumScratchReg2
+#define kScratchDoubleReg kLithiumScratchDouble
+
+
+// TODO(plind): consider renaming these macros.
+#define TRACE_MSG(msg)                                                      \
+  PrintF("code_gen: \'%s\' in function %s at line %d\n", msg, __FUNCTION__, \
+         __LINE__)
+
+#define TRACE_UNIMPL()                                                       \
+  PrintF("UNIMPLEMENTED code_generator_mips: %s at line %d\n", __FUNCTION__, \
+         __LINE__)
+
+
+// Adds Mips-specific methods to convert InstructionOperands.
+class MipsOperandConverter FINAL : public InstructionOperandConverter {
+ public:
+  MipsOperandConverter(CodeGenerator* gen, Instruction* instr)
+      : InstructionOperandConverter(gen, instr) {}
+
+  FloatRegister OutputSingleRegister(int index = 0) {
+    return ToSingleRegister(instr_->OutputAt(index));
+  }
+
+  FloatRegister InputSingleRegister(int index) {
+    return ToSingleRegister(instr_->InputAt(index));
+  }
+
+  FloatRegister ToSingleRegister(InstructionOperand* op) {
+    // Single (Float) and Double register namespace is same on MIPS,
+    // both are typedefs of FPURegister.
+    return ToDoubleRegister(op);
+  }
+
+  Operand InputImmediate(int index) {
+    Constant constant = ToConstant(instr_->InputAt(index));
+    switch (constant.type()) {
+      case Constant::kInt32:
+        return Operand(constant.ToInt32());
+      case Constant::kInt64:
+        return Operand(constant.ToInt64());
+      case Constant::kFloat32:
+        return Operand(
+            isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED));
+      case Constant::kFloat64:
+        return Operand(
+            isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED));
+      case Constant::kExternalReference:
+      case Constant::kHeapObject:
+        // TODO(plind): Maybe we should handle ExtRef & HeapObj here?
+        //    maybe not done on arm due to const pool ??
+        break;
+      case Constant::kRpoNumber:
+        UNREACHABLE();  // TODO(titzer): RPO immediates on mips?
+        break;
+    }
+    UNREACHABLE();
+    return Operand(zero_reg);
+  }
+
+  Operand InputOperand(int index) {
+    InstructionOperand* op = instr_->InputAt(index);
+    if (op->IsRegister()) {
+      return Operand(ToRegister(op));
+    }
+    return InputImmediate(index);
+  }
+
+  MemOperand MemoryOperand(int* first_index) {
+    const int index = *first_index;
+    switch (AddressingModeField::decode(instr_->opcode())) {
+      case kMode_None:
+        break;
+      case kMode_MRI:
+        *first_index += 2;
+        return MemOperand(InputRegister(index + 0), InputInt32(index + 1));
+      case kMode_MRR:
+        // TODO(plind): r6 address mode, to be implemented ...
+        UNREACHABLE();
+    }
+    UNREACHABLE();
+    return MemOperand(no_reg);
+  }
+
+  MemOperand MemoryOperand(int index = 0) { return MemoryOperand(&index); }
+
+  MemOperand ToMemOperand(InstructionOperand* op) const {
+    DCHECK(op != NULL);
+    DCHECK(!op->IsRegister());
+    DCHECK(!op->IsDoubleRegister());
+    DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
+    // The linkage computes where all spill slots are located.
+    FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0);
+    return MemOperand(offset.from_stack_pointer() ? sp : fp, offset.offset());
+  }
+};
+
+
+static inline bool HasRegisterInput(Instruction* instr, int index) {
+  return instr->InputAt(index)->IsRegister();
+}
+
+
+namespace {
+
+class OutOfLineLoadSingle FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadSingle(CodeGenerator* gen, FloatRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL {
+    __ Move(result_, std::numeric_limits<float>::quiet_NaN());
+  }
+
+ private:
+  FloatRegister const result_;
+};
+
+
+class OutOfLineLoadDouble FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadDouble(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL {
+    __ Move(result_, std::numeric_limits<double>::quiet_NaN());
+  }
+
+ private:
+  DoubleRegister const result_;
+};
+
+
+class OutOfLineLoadInteger FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadInteger(CodeGenerator* gen, Register result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL { __ mov(result_, zero_reg); }
+
+ private:
+  Register const result_;
+};
+
+
+class OutOfLineRound : public OutOfLineCode {
+ public:
+  OutOfLineRound(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL {
+    // Handle rounding to zero case where sign has to be preserved.
+    // High bits of double input already in kScratchReg.
+    __ dsrl(at, kScratchReg, 31);
+    __ dsll(at, at, 31);
+    __ mthc1(at, result_);
+  }
+
+ private:
+  DoubleRegister const result_;
+};
+
+
+class OutOfLineTruncate FINAL : public OutOfLineRound {
+ public:
+  OutOfLineTruncate(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineRound(gen, result) {}
+};
+
+
+class OutOfLineFloor FINAL : public OutOfLineRound {
+ public:
+  OutOfLineFloor(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineRound(gen, result) {}
+};
+
+
+class OutOfLineCeil FINAL : public OutOfLineRound {
+ public:
+  OutOfLineCeil(CodeGenerator* gen, DoubleRegister result)
+      : OutOfLineRound(gen, result) {}
+};
+
+
+}  // namespace
+
+
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr)                         \
+  do {                                                                        \
+    auto result = i.Output##width##Register();                                \
+    auto ool = new (zone()) OutOfLineLoad##width(this, result);               \
+    if (instr->InputAt(0)->IsRegister()) {                                    \
+      auto offset = i.InputRegister(0);                                       \
+      __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
+      __ Daddu(at, i.InputRegister(2), offset);                               \
+      __ asm_instr(result, MemOperand(at, 0));                                \
+    } else {                                                                  \
+      auto offset = i.InputOperand(0).immediate();                            \
+      __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset));       \
+      __ asm_instr(result, MemOperand(i.InputRegister(2), offset));           \
+    }                                                                         \
+    __ bind(ool->exit());                                                     \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr)                              \
+  do {                                                                        \
+    auto result = i.OutputRegister();                                         \
+    auto ool = new (zone()) OutOfLineLoadInteger(this, result);               \
+    if (instr->InputAt(0)->IsRegister()) {                                    \
+      auto offset = i.InputRegister(0);                                       \
+      __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
+      __ Daddu(at, i.InputRegister(2), offset);                               \
+      __ asm_instr(result, MemOperand(at, 0));                                \
+    } else {                                                                  \
+      auto offset = i.InputOperand(0).immediate();                            \
+      __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset));       \
+      __ asm_instr(result, MemOperand(i.InputRegister(2), offset));           \
+    }                                                                         \
+    __ bind(ool->exit());                                                     \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr)                 \
+  do {                                                                 \
+    Label done;                                                        \
+    if (instr->InputAt(0)->IsRegister()) {                             \
+      auto offset = i.InputRegister(0);                                \
+      auto value = i.Input##width##Register(2);                        \
+      __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
+      __ Daddu(at, i.InputRegister(3), offset);                        \
+      __ asm_instr(value, MemOperand(at, 0));                          \
+    } else {                                                           \
+      auto offset = i.InputOperand(0).immediate();                     \
+      auto value = i.Input##width##Register(2);                        \
+      __ Branch(&done, ls, i.InputRegister(1), Operand(offset));       \
+      __ asm_instr(value, MemOperand(i.InputRegister(3), offset));     \
+    }                                                                  \
+    __ bind(&done);                                                    \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr)                      \
+  do {                                                                 \
+    Label done;                                                        \
+    if (instr->InputAt(0)->IsRegister()) {                             \
+      auto offset = i.InputRegister(0);                                \
+      auto value = i.InputRegister(2);                                 \
+      __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
+      __ Daddu(at, i.InputRegister(3), offset);                        \
+      __ asm_instr(value, MemOperand(at, 0));                          \
+    } else {                                                           \
+      auto offset = i.InputOperand(0).immediate();                     \
+      auto value = i.InputRegister(2);                                 \
+      __ Branch(&done, ls, i.InputRegister(1), Operand(offset));       \
+      __ asm_instr(value, MemOperand(i.InputRegister(3), offset));     \
+    }                                                                  \
+    __ bind(&done);                                                    \
+  } while (0)
+
+
+#define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(asm_instr, operation)                  \
+  do {                                                                         \
+    auto ool =                                                                 \
+        new (zone()) OutOfLine##operation(this, i.OutputDoubleRegister());     \
+    Label done;                                                                \
+    __ mfhc1(kScratchReg, i.InputDoubleRegister(0));                           \
+    __ Ext(at, kScratchReg, HeapNumber::kExponentShift,                        \
+           HeapNumber::kExponentBits);                                         \
+    __ Branch(USE_DELAY_SLOT, &done, hs, at,                                   \
+              Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits)); \
+    __ mov_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));              \
+    __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0));          \
+    __ dmfc1(at, i.OutputDoubleRegister());                                    \
+    __ Branch(USE_DELAY_SLOT, ool->entry(), eq, at, Operand(zero_reg));        \
+    __ cvt_d_l(i.OutputDoubleRegister(), i.OutputDoubleRegister());            \
+    __ bind(ool->exit());                                                      \
+    __ bind(&done);                                                            \
+  } while (0)
+
+
+// Assembles an instruction after register allocation, producing machine code.
+void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
+  MipsOperandConverter i(this, instr);
+  InstructionCode opcode = instr->opcode();
+
+  switch (ArchOpcodeField::decode(opcode)) {
+    case kArchCallCodeObject: {
+      EnsureSpaceForLazyDeopt();
+      if (instr->InputAt(0)->IsImmediate()) {
+        __ Call(Handle<Code>::cast(i.InputHeapObject(0)),
+                RelocInfo::CODE_TARGET);
+      } else {
+        __ daddiu(at, i.InputRegister(0), Code::kHeaderSize - kHeapObjectTag);
+        __ Call(at);
+      }
+      AddSafepointAndDeopt(instr);
+      break;
+    }
+    case kArchCallJSFunction: {
+      EnsureSpaceForLazyDeopt();
+      Register func = i.InputRegister(0);
+      if (FLAG_debug_code) {
+        // Check the function's context matches the context argument.
+        __ ld(kScratchReg, FieldMemOperand(func, JSFunction::kContextOffset));
+        __ Assert(eq, kWrongFunctionContext, cp, Operand(kScratchReg));
+      }
+
+      __ ld(at, FieldMemOperand(func, JSFunction::kCodeEntryOffset));
+      __ Call(at);
+      AddSafepointAndDeopt(instr);
+      break;
+    }
+    case kArchJmp:
+      AssembleArchJump(i.InputRpo(0));
+      break;
+    case kArchNop:
+      // don't emit code for nops.
+      break;
+    case kArchRet:
+      AssembleReturn();
+      break;
+    case kArchStackPointer:
+      __ mov(i.OutputRegister(), sp);
+      break;
+    case kArchTruncateDoubleToI:
+      __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
+      break;
+    case kMips64Add:
+      __ Addu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Dadd:
+      __ Daddu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Sub:
+      __ Subu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Dsub:
+      __ Dsubu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Mul:
+      __ Mul(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64MulHigh:
+      __ Mulh(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64MulHighU:
+      __ Mulhu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Div:
+      __ Div(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64DivU:
+      __ Divu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Mod:
+      __ Mod(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64ModU:
+      __ Modu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Dmul:
+      __ Dmul(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Ddiv:
+      __ Ddiv(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64DdivU:
+      __ Ddivu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Dmod:
+      __ Dmod(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64DmodU:
+      __ Dmodu(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+      __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64And:
+      __ And(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Or:
+      __ Or(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Xor:
+      __ Xor(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Shl:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ sllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        int32_t imm = i.InputOperand(1).immediate();
+        __ sll(i.OutputRegister(), i.InputRegister(0), imm);
+      }
+      break;
+    case kMips64Shr:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ srlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        int32_t imm = i.InputOperand(1).immediate();
+        __ srl(i.OutputRegister(), i.InputRegister(0), imm);
+      }
+      break;
+    case kMips64Sar:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ srav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        int32_t imm = i.InputOperand(1).immediate();
+        __ sra(i.OutputRegister(), i.InputRegister(0), imm);
+      }
+      break;
+    case kMips64Ext:
+      __ Ext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
+             i.InputInt8(2));
+      break;
+    case kMips64Dext:
+      __ Dext(i.OutputRegister(), i.InputRegister(0), i.InputInt8(1),
+              i.InputInt8(2));
+      break;
+    case kMips64Dshl:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ dsllv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        int32_t imm = i.InputOperand(1).immediate();
+        if (imm < 32) {
+          __ dsll(i.OutputRegister(), i.InputRegister(0), imm);
+        } else {
+          __ dsll32(i.OutputRegister(), i.InputRegister(0), imm - 32);
+        }
+      }
+      break;
+    case kMips64Dshr:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ dsrlv(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        int32_t imm = i.InputOperand(1).immediate();
+        if (imm < 32) {
+          __ dsrl(i.OutputRegister(), i.InputRegister(0), imm);
+        } else {
+          __ dsrl32(i.OutputRegister(), i.InputRegister(0), imm - 32);
+        }
+      }
+      break;
+    case kMips64Dsar:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ dsrav(i.OutputRegister(), i.InputRegister(0), i.InputRegister(1));
+      } else {
+        int32_t imm = i.InputOperand(1).immediate();
+        if (imm < 32) {
+          __ dsra(i.OutputRegister(), i.InputRegister(0), imm);
+        } else {
+          __ dsra32(i.OutputRegister(), i.InputRegister(0), imm - 32);
+        }
+      }
+      break;
+    case kMips64Ror:
+      __ Ror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Dror:
+      __ Dror(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+      break;
+    case kMips64Tst:
+    case kMips64Tst32:
+      // Pseudo-instruction used for cmp/branch. No opcode emitted here.
+      break;
+    case kMips64Cmp:
+    case kMips64Cmp32:
+      // Pseudo-instruction used for cmp/branch. No opcode emitted here.
+      break;
+    case kMips64Mov:
+      // TODO(plind): Should we combine mov/li like this, or use separate instr?
+      //    - Also see x64 ASSEMBLE_BINOP & RegisterOrOperandType
+      if (HasRegisterInput(instr, 0)) {
+        __ mov(i.OutputRegister(), i.InputRegister(0));
+      } else {
+        __ li(i.OutputRegister(), i.InputOperand(0));
+      }
+      break;
+
+    case kMips64CmpD:
+      // Psuedo-instruction used for FP cmp/branch. No opcode emitted here.
+      break;
+    case kMips64AddD:
+      // TODO(plind): add special case: combine mult & add.
+      __ add_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMips64SubD:
+      __ sub_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMips64MulD:
+      // TODO(plind): add special case: right op is -1.0, see arm port.
+      __ mul_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMips64DivD:
+      __ div_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+      break;
+    case kMips64ModD: {
+      // TODO(bmeurer): We should really get rid of this special instruction,
+      // and generate a CallAddress instruction instead.
+      FrameScope scope(masm(), StackFrame::MANUAL);
+      __ PrepareCallCFunction(0, 2, kScratchReg);
+      __ MovToFloatParameters(i.InputDoubleRegister(0),
+                              i.InputDoubleRegister(1));
+      __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()),
+                       0, 2);
+      // Move the result in the double result register.
+      __ MovFromFloatResult(i.OutputDoubleRegister());
+      break;
+    }
+    case kMips64Float64Floor: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(floor_l_d, Floor);
+      break;
+    }
+    case kMips64Float64Ceil: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(ceil_l_d, Ceil);
+      break;
+    }
+    case kMips64Float64RoundTruncate: {
+      ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(trunc_l_d, Truncate);
+      break;
+    }
+    case kMips64SqrtD: {
+      __ sqrt_d(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      break;
+    }
+    case kMips64CvtSD: {
+      __ cvt_s_d(i.OutputSingleRegister(), i.InputDoubleRegister(0));
+      break;
+    }
+    case kMips64CvtDS: {
+      __ cvt_d_s(i.OutputDoubleRegister(), i.InputSingleRegister(0));
+      break;
+    }
+    case kMips64CvtDW: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ mtc1(i.InputRegister(0), scratch);
+      __ cvt_d_w(i.OutputDoubleRegister(), scratch);
+      break;
+    }
+    case kMips64CvtDUw: {
+      FPURegister scratch = kScratchDoubleReg;
+      __ Cvt_d_uw(i.OutputDoubleRegister(), i.InputRegister(0), scratch);
+      break;
+    }
+    case kMips64TruncWD: {
+      FPURegister scratch = kScratchDoubleReg;
+      // Other arches use round to zero here, so we follow.
+      __ trunc_w_d(scratch, i.InputDoubleRegister(0));
+      __ mfc1(i.OutputRegister(), scratch);
+      break;
+    }
+    case kMips64TruncUwD: {
+      FPURegister scratch = kScratchDoubleReg;
+      // TODO(plind): Fix wrong param order of Trunc_uw_d() macro-asm function.
+      __ Trunc_uw_d(i.InputDoubleRegister(0), i.OutputRegister(), scratch);
+      break;
+    }
+    // ... more basic instructions ...
+
+    case kMips64Lbu:
+      __ lbu(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kMips64Lb:
+      __ lb(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kMips64Sb:
+      __ sb(i.InputRegister(2), i.MemoryOperand());
+      break;
+    case kMips64Lhu:
+      __ lhu(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kMips64Lh:
+      __ lh(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kMips64Sh:
+      __ sh(i.InputRegister(2), i.MemoryOperand());
+      break;
+    case kMips64Lw:
+      __ lw(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kMips64Ld:
+      __ ld(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kMips64Sw:
+      __ sw(i.InputRegister(2), i.MemoryOperand());
+      break;
+    case kMips64Sd:
+      __ sd(i.InputRegister(2), i.MemoryOperand());
+      break;
+    case kMips64Lwc1: {
+      __ lwc1(i.OutputSingleRegister(), i.MemoryOperand());
+      break;
+    }
+    case kMips64Swc1: {
+      int index = 0;
+      MemOperand operand = i.MemoryOperand(&index);
+      __ swc1(i.InputSingleRegister(index), operand);
+      break;
+    }
+    case kMips64Ldc1:
+      __ ldc1(i.OutputDoubleRegister(), i.MemoryOperand());
+      break;
+    case kMips64Sdc1:
+      __ sdc1(i.InputDoubleRegister(2), i.MemoryOperand());
+      break;
+    case kMips64Push:
+      __ Push(i.InputRegister(0));
+      break;
+    case kMips64StackClaim: {
+      int words = MiscField::decode(instr->opcode());
+      __ Dsubu(sp, sp, Operand(words << kPointerSizeLog2));
+      break;
+    }
+    case kMips64StoreToStackSlot: {
+      int slot = MiscField::decode(instr->opcode());
+      __ sd(i.InputRegister(0), MemOperand(sp, slot << kPointerSizeLog2));
+      break;
+    }
+    case kMips64StoreWriteBarrier: {
+      Register object = i.InputRegister(0);
+      Register index = i.InputRegister(1);
+      Register value = i.InputRegister(2);
+      __ daddu(index, object, index);
+      __ sd(value, MemOperand(index));
+      SaveFPRegsMode mode =
+          frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
+      RAStatus ra_status = kRAHasNotBeenSaved;
+      __ RecordWrite(object, index, value, ra_status, mode);
+      break;
+    }
+    case kCheckedLoadInt8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lb);
+      break;
+    case kCheckedLoadUint8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lbu);
+      break;
+    case kCheckedLoadInt16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lh);
+      break;
+    case kCheckedLoadUint16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lhu);
+      break;
+    case kCheckedLoadWord32:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(lw);
+      break;
+    case kCheckedLoadFloat32:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(Single, lwc1);
+      break;
+    case kCheckedLoadFloat64:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(Double, ldc1);
+      break;
+    case kCheckedStoreWord8:
+      ASSEMBLE_CHECKED_STORE_INTEGER(sb);
+      break;
+    case kCheckedStoreWord16:
+      ASSEMBLE_CHECKED_STORE_INTEGER(sh);
+      break;
+    case kCheckedStoreWord32:
+      ASSEMBLE_CHECKED_STORE_INTEGER(sw);
+      break;
+    case kCheckedStoreFloat32:
+      ASSEMBLE_CHECKED_STORE_FLOAT(Single, swc1);
+      break;
+    case kCheckedStoreFloat64:
+      ASSEMBLE_CHECKED_STORE_FLOAT(Double, sdc1);
+      break;
+  }
+}
+
+
+#define UNSUPPORTED_COND(opcode, condition)                                  \
+  OFStream out(stdout);                                                      \
+  out << "Unsupported " << #opcode << " condition: \"" << condition << "\""; \
+  UNIMPLEMENTED();
+
+// Assembles branches after an instruction.
+void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
+  MipsOperandConverter i(this, instr);
+  Label* tlabel = branch->true_label;
+  Label* flabel = branch->false_label;
+  Condition cc = kNoCondition;
+
+  // MIPS does not have condition code flags, so compare and branch are
+  // implemented differently than on the other arch's. The compare operations
+  // emit mips psuedo-instructions, which are handled here by branch
+  // instructions that do the actual comparison. Essential that the input
+  // registers to compare psuedo-op are not modified before this branch op, as
+  // they are tested here.
+  // TODO(plind): Add CHECK() to ensure that test/cmp and this branch were
+  //    not separated by other instructions.
+
+  if (instr->arch_opcode() == kMips64Tst) {
+    switch (branch->condition) {
+      case kNotEqual:
+        cc = ne;
+        break;
+      case kEqual:
+        cc = eq;
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64Tst, branch->condition);
+        break;
+    }
+    __ And(at, i.InputRegister(0), i.InputOperand(1));
+    __ Branch(tlabel, cc, at, Operand(zero_reg));
+  } else if (instr->arch_opcode() == kMips64Tst32) {
+    switch (branch->condition) {
+      case kNotEqual:
+        cc = ne;
+        break;
+      case kEqual:
+        cc = eq;
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64Tst32, branch->condition);
+        break;
+    }
+    // Zero-extend registers on MIPS64 only 64-bit operand
+    // branch and compare op. is available.
+    // This is a disadvantage to perform 32-bit operation on MIPS64.
+    // Try to force globally in front-end Word64 representation to be preferred
+    // for MIPS64 even for Word32.
+    __ And(at, i.InputRegister(0), i.InputOperand(1));
+    __ Dext(at, at, 0, 32);
+    __ Branch(tlabel, cc, at, Operand(zero_reg));
+  } else if (instr->arch_opcode() == kMips64Dadd ||
+             instr->arch_opcode() == kMips64Dsub) {
+    switch (branch->condition) {
+      case kOverflow:
+        cc = ne;
+        break;
+      case kNotOverflow:
+        cc = eq;
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64Dadd, branch->condition);
+        break;
+    }
+
+    __ dsra32(kScratchReg, i.OutputRegister(), 0);
+    __ sra(at, i.OutputRegister(), 31);
+    __ Branch(tlabel, cc, at, Operand(kScratchReg));
+  } else if (instr->arch_opcode() == kMips64Cmp) {
+    switch (branch->condition) {
+      case kEqual:
+        cc = eq;
+        break;
+      case kNotEqual:
+        cc = ne;
+        break;
+      case kSignedLessThan:
+        cc = lt;
+        break;
+      case kSignedGreaterThanOrEqual:
+        cc = ge;
+        break;
+      case kSignedLessThanOrEqual:
+        cc = le;
+        break;
+      case kSignedGreaterThan:
+        cc = gt;
+        break;
+      case kUnsignedLessThan:
+        cc = lo;
+        break;
+      case kUnsignedGreaterThanOrEqual:
+        cc = hs;
+        break;
+      case kUnsignedLessThanOrEqual:
+        cc = ls;
+        break;
+      case kUnsignedGreaterThan:
+        cc = hi;
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64Cmp, branch->condition);
+        break;
+    }
+    __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
+
+    if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
+
+  } else if (instr->arch_opcode() == kMips64Cmp32) {
+    switch (branch->condition) {
+      case kEqual:
+        cc = eq;
+        break;
+      case kNotEqual:
+        cc = ne;
+        break;
+      case kSignedLessThan:
+        cc = lt;
+        break;
+      case kSignedGreaterThanOrEqual:
+        cc = ge;
+        break;
+      case kSignedLessThanOrEqual:
+        cc = le;
+        break;
+      case kSignedGreaterThan:
+        cc = gt;
+        break;
+      case kUnsignedLessThan:
+        cc = lo;
+        break;
+      case kUnsignedGreaterThanOrEqual:
+        cc = hs;
+        break;
+      case kUnsignedLessThanOrEqual:
+        cc = ls;
+        break;
+      case kUnsignedGreaterThan:
+        cc = hi;
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64Cmp32, branch->condition);
+        break;
+    }
+
+    switch (branch->condition) {
+      case kEqual:
+      case kNotEqual:
+      case kSignedLessThan:
+      case kSignedGreaterThanOrEqual:
+      case kSignedLessThanOrEqual:
+      case kSignedGreaterThan:
+        // Sign-extend registers on MIPS64 only 64-bit operand
+        // branch and compare op. is available.
+        __ sll(i.InputRegister(0), i.InputRegister(0), 0);
+        if (instr->InputAt(1)->IsRegister()) {
+          __ sll(i.InputRegister(1), i.InputRegister(1), 0);
+        }
+        break;
+      case kUnsignedLessThan:
+      case kUnsignedGreaterThanOrEqual:
+      case kUnsignedLessThanOrEqual:
+      case kUnsignedGreaterThan:
+        // Zero-extend registers on MIPS64 only 64-bit operand
+        // branch and compare op. is available.
+        __ Dext(i.InputRegister(0), i.InputRegister(0), 0, 32);
+        if (instr->InputAt(1)->IsRegister()) {
+          __ Dext(i.InputRegister(1), i.InputRegister(1), 0, 32);
+        }
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64Cmp, branch->condition);
+        break;
+    }
+    __ Branch(tlabel, cc, i.InputRegister(0), i.InputOperand(1));
+
+    if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
+  } else if (instr->arch_opcode() == kMips64CmpD) {
+    // TODO(dusmil) optimize unordered checks to use less instructions
+    // even if we have to unfold BranchF macro.
+    Label* nan = flabel;
+    switch (branch->condition) {
+      case kUnorderedEqual:
+        cc = eq;
+        break;
+      case kUnorderedNotEqual:
+        cc = ne;
+        nan = tlabel;
+        break;
+      case kUnorderedLessThan:
+        cc = lt;
+        break;
+      case kUnorderedGreaterThanOrEqual:
+        cc = ge;
+        nan = tlabel;
+        break;
+      case kUnorderedLessThanOrEqual:
+        cc = le;
+        break;
+      case kUnorderedGreaterThan:
+        cc = gt;
+        nan = tlabel;
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64CmpD, branch->condition);
+        break;
+    }
+    __ BranchF(tlabel, nan, cc, i.InputDoubleRegister(0),
+               i.InputDoubleRegister(1));
+
+    if (!branch->fallthru) __ Branch(flabel);  // no fallthru to flabel.
+  } else {
+    PrintF("AssembleArchBranch Unimplemented arch_opcode: %d\n",
+           instr->arch_opcode());
+    UNIMPLEMENTED();
+  }
+}
+
+
+void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+  if (!IsNextInAssemblyOrder(target)) __ Branch(GetLabel(target));
+}
+
+
+// Assembles boolean materializations after an instruction.
+void CodeGenerator::AssembleArchBoolean(Instruction* instr,
+                                        FlagsCondition condition) {
+  MipsOperandConverter i(this, instr);
+  Label done;
+
+  // Materialize a full 32-bit 1 or 0 value. The result register is always the
+  // last output of the instruction.
+  Label false_value;
+  DCHECK_NE(0, instr->OutputCount());
+  Register result = i.OutputRegister(instr->OutputCount() - 1);
+  Condition cc = kNoCondition;
+
+  // MIPS does not have condition code flags, so compare and branch are
+  // implemented differently than on the other arch's. The compare operations
+  // emit mips pseudo-instructions, which are checked and handled here.
+
+  // For materializations, we use delay slot to set the result true, and
+  // in the false case, where we fall through the branch, we reset the result
+  // false.
+
+  if (instr->arch_opcode() == kMips64Tst) {
+    switch (condition) {
+      case kNotEqual:
+        cc = ne;
+        break;
+      case kEqual:
+        cc = eq;
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64Tst, condition);
+        break;
+    }
+    __ And(at, i.InputRegister(0), i.InputOperand(1));
+    __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg));
+    __ li(result, Operand(1));  // In delay slot.
+  } else if (instr->arch_opcode() == kMips64Tst32) {
+    switch (condition) {
+      case kNotEqual:
+        cc = ne;
+        break;
+      case kEqual:
+        cc = eq;
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64Tst, condition);
+        break;
+    }
+    // Zero-extend register on MIPS64 only 64-bit operand
+    // branch and compare op. is available.
+    __ And(at, i.InputRegister(0), i.InputOperand(1));
+    __ Dext(at, at, 0, 32);
+    __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(zero_reg));
+    __ li(result, Operand(1));  // In delay slot.
+  } else if (instr->arch_opcode() == kMips64Dadd ||
+             instr->arch_opcode() == kMips64Dsub) {
+    switch (condition) {
+      case kOverflow:
+        cc = ne;
+        break;
+      case kNotOverflow:
+        cc = eq;
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64DAdd, condition);
+        break;
+    }
+    __ dsra32(kScratchReg, i.OutputRegister(), 0);
+    __ sra(at, i.OutputRegister(), 31);
+    __ Branch(USE_DELAY_SLOT, &done, cc, at, Operand(kScratchReg));
+    __ li(result, Operand(1));  // In delay slot.
+  } else if (instr->arch_opcode() == kMips64Cmp) {
+    Register left = i.InputRegister(0);
+    Operand right = i.InputOperand(1);
+    switch (condition) {
+      case kEqual:
+        cc = eq;
+        break;
+      case kNotEqual:
+        cc = ne;
+        break;
+      case kSignedLessThan:
+        cc = lt;
+        break;
+      case kSignedGreaterThanOrEqual:
+        cc = ge;
+        break;
+      case kSignedLessThanOrEqual:
+        cc = le;
+        break;
+      case kSignedGreaterThan:
+        cc = gt;
+        break;
+      case kUnsignedLessThan:
+        cc = lo;
+        break;
+      case kUnsignedGreaterThanOrEqual:
+        cc = hs;
+        break;
+      case kUnsignedLessThanOrEqual:
+        cc = ls;
+        break;
+      case kUnsignedGreaterThan:
+        cc = hi;
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64Cmp, condition);
+        break;
+    }
+    __ Branch(USE_DELAY_SLOT, &done, cc, left, right);
+    __ li(result, Operand(1));  // In delay slot.
+  } else if (instr->arch_opcode() == kMips64Cmp32) {
+    Register left = i.InputRegister(0);
+    Operand right = i.InputOperand(1);
+    switch (condition) {
+      case kEqual:
+        cc = eq;
+        break;
+      case kNotEqual:
+        cc = ne;
+        break;
+      case kSignedLessThan:
+        cc = lt;
+        break;
+      case kSignedGreaterThanOrEqual:
+        cc = ge;
+        break;
+      case kSignedLessThanOrEqual:
+        cc = le;
+        break;
+      case kSignedGreaterThan:
+        cc = gt;
+        break;
+      case kUnsignedLessThan:
+        cc = lo;
+        break;
+      case kUnsignedGreaterThanOrEqual:
+        cc = hs;
+        break;
+      case kUnsignedLessThanOrEqual:
+        cc = ls;
+        break;
+      case kUnsignedGreaterThan:
+        cc = hi;
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64Cmp, condition);
+        break;
+    }
+
+    switch (condition) {
+      case kEqual:
+      case kNotEqual:
+      case kSignedLessThan:
+      case kSignedGreaterThanOrEqual:
+      case kSignedLessThanOrEqual:
+      case kSignedGreaterThan:
+        // Sign-extend registers on MIPS64 only 64-bit operand
+        // branch and compare op. is available.
+        __ sll(left, left, 0);
+        if (instr->InputAt(1)->IsRegister()) {
+          __ sll(i.InputRegister(1), i.InputRegister(1), 0);
+        }
+        break;
+      case kUnsignedLessThan:
+      case kUnsignedGreaterThanOrEqual:
+      case kUnsignedLessThanOrEqual:
+      case kUnsignedGreaterThan:
+        // Zero-extend registers on MIPS64 only 64-bit operand
+        // branch and compare op. is available.
+        __ Dext(left, left, 0, 32);
+        if (instr->InputAt(1)->IsRegister()) {
+          __ Dext(i.InputRegister(1), i.InputRegister(1), 0, 32);
+        }
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64Cmp32, condition);
+        break;
+    }
+    __ Branch(USE_DELAY_SLOT, &done, cc, left, right);
+    __ li(result, Operand(1));  // In delay slot.
+  } else if (instr->arch_opcode() == kMips64CmpD) {
+    FPURegister left = i.InputDoubleRegister(0);
+    FPURegister right = i.InputDoubleRegister(1);
+    // TODO(plind): Provide NaN-testing macro-asm function without need for
+    // BranchF.
+    FPURegister dummy1 = f0;
+    FPURegister dummy2 = f2;
+    switch (condition) {
+      case kUnorderedEqual:
+        // TODO(plind):  improve the NaN testing throughout this function.
+        __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
+        cc = eq;
+        break;
+      case kUnorderedNotEqual:
+        __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
+        __ li(result, Operand(1));  // In delay slot - returns 1 on NaN.
+        cc = ne;
+        break;
+      case kUnorderedLessThan:
+        __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
+        cc = lt;
+        break;
+      case kUnorderedGreaterThanOrEqual:
+        __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
+        __ li(result, Operand(1));  // In delay slot - returns 1 on NaN.
+        cc = ge;
+        break;
+      case kUnorderedLessThanOrEqual:
+        __ BranchF(NULL, &false_value, kNoCondition, dummy1, dummy2);
+        cc = le;
+        break;
+      case kUnorderedGreaterThan:
+        __ BranchF(USE_DELAY_SLOT, NULL, &done, kNoCondition, dummy1, dummy2);
+        __ li(result, Operand(1));  // In delay slot - returns 1 on NaN.
+        cc = gt;
+        break;
+      default:
+        UNSUPPORTED_COND(kMips64Cmp, condition);
+        break;
+    }
+    __ BranchF(USE_DELAY_SLOT, &done, NULL, cc, left, right);
+    __ li(result, Operand(1));  // In delay slot - branch taken returns 1.
+                                // Fall-thru (branch not taken) returns 0.
+
+  } else {
+    PrintF("AssembleArchBranch Unimplemented arch_opcode is : %d\n",
+           instr->arch_opcode());
+    TRACE_UNIMPL();
+    UNIMPLEMENTED();
+  }
+  // Fallthru case is the false materialization.
+  __ bind(&false_value);
+  __ li(result, Operand(static_cast<int64_t>(0)));
+  __ bind(&done);
+}
+
+
+void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) {
+  Address deopt_entry = Deoptimizer::GetDeoptimizationEntry(
+      isolate(), deoptimization_id, Deoptimizer::LAZY);
+  __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY);
+}
+
+
+void CodeGenerator::AssemblePrologue() {
+  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
+  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+    __ Push(ra, fp);
+    __ mov(fp, sp);
+    const RegList saves = descriptor->CalleeSavedRegisters();
+    if (saves != 0) {  // Save callee-saved registers.
+      // TODO(plind): make callee save size const, possibly DCHECK it.
+      int register_save_area_size = 0;
+      for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
+        if (!((1 << i) & saves)) continue;
+        register_save_area_size += kPointerSize;
+      }
+      frame()->SetRegisterSaveAreaSize(register_save_area_size);
+      __ MultiPush(saves);
+    }
+  } else if (descriptor->IsJSFunctionCall()) {
+    CompilationInfo* info = this->info();
+    __ Prologue(info->IsCodePreAgingActive());
+    frame()->SetRegisterSaveAreaSize(
+        StandardFrameConstants::kFixedFrameSizeFromFp);
+
+    // Sloppy mode functions and builtins need to replace the receiver with the
+    // global proxy when called as functions (without an explicit receiver
+    // object).
+    // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
+    if (info->strict_mode() == SLOPPY && !info->is_native()) {
+      Label ok;
+      // +2 for return address and saved frame pointer.
+      int receiver_slot = info->scope()->num_parameters() + 2;
+      __ ld(a2, MemOperand(fp, receiver_slot * kPointerSize));
+      __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
+      __ Branch(&ok, ne, a2, Operand(at));
+
+      __ ld(a2, GlobalObjectOperand());
+      __ ld(a2, FieldMemOperand(a2, GlobalObject::kGlobalProxyOffset));
+      __ sd(a2, MemOperand(fp, receiver_slot * kPointerSize));
+      __ bind(&ok);
+    }
+  } else {
+    __ StubPrologue();
+    frame()->SetRegisterSaveAreaSize(
+        StandardFrameConstants::kFixedFrameSizeFromFp);
+  }
+  int stack_slots = frame()->GetSpillSlotCount();
+  if (stack_slots > 0) {
+    __ Dsubu(sp, sp, Operand(stack_slots * kPointerSize));
+  }
+}
+
+
+void CodeGenerator::AssembleReturn() {
+  CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
+  if (descriptor->kind() == CallDescriptor::kCallAddress) {
+    if (frame()->GetRegisterSaveAreaSize() > 0) {
+      // Remove this frame's spill slots first.
+      int stack_slots = frame()->GetSpillSlotCount();
+      if (stack_slots > 0) {
+        __ Daddu(sp, sp, Operand(stack_slots * kPointerSize));
+      }
+      // Restore registers.
+      const RegList saves = descriptor->CalleeSavedRegisters();
+      if (saves != 0) {
+        __ MultiPop(saves);
+      }
+    }
+    __ mov(sp, fp);
+    __ Pop(ra, fp);
+    __ Ret();
+  } else {
+    __ mov(sp, fp);
+    __ Pop(ra, fp);
+    int pop_count = descriptor->IsJSFunctionCall()
+                        ? static_cast<int>(descriptor->JSParameterCount())
+                        : 0;
+    __ DropAndRet(pop_count);
+  }
+}
+
+
+void CodeGenerator::AssembleMove(InstructionOperand* source,
+                                 InstructionOperand* destination) {
+  MipsOperandConverter g(this, NULL);
+  // Dispatch on the source and destination operand kinds.  Not all
+  // combinations are possible.
+  if (source->IsRegister()) {
+    DCHECK(destination->IsRegister() || destination->IsStackSlot());
+    Register src = g.ToRegister(source);
+    if (destination->IsRegister()) {
+      __ mov(g.ToRegister(destination), src);
+    } else {
+      __ sd(src, g.ToMemOperand(destination));
+    }
+  } else if (source->IsStackSlot()) {
+    DCHECK(destination->IsRegister() || destination->IsStackSlot());
+    MemOperand src = g.ToMemOperand(source);
+    if (destination->IsRegister()) {
+      __ ld(g.ToRegister(destination), src);
+    } else {
+      Register temp = kScratchReg;
+      __ ld(temp, src);
+      __ sd(temp, g.ToMemOperand(destination));
+    }
+  } else if (source->IsConstant()) {
+    Constant src = g.ToConstant(source);
+    if (destination->IsRegister() || destination->IsStackSlot()) {
+      Register dst =
+          destination->IsRegister() ? g.ToRegister(destination) : kScratchReg;
+      switch (src.type()) {
+        case Constant::kInt32:
+          __ li(dst, Operand(src.ToInt32()));
+          break;
+        case Constant::kFloat32:
+          __ li(dst, isolate()->factory()->NewNumber(src.ToFloat32(), TENURED));
+          break;
+        case Constant::kInt64:
+          __ li(dst, Operand(src.ToInt64()));
+          break;
+        case Constant::kFloat64:
+          __ li(dst, isolate()->factory()->NewNumber(src.ToFloat64(), TENURED));
+          break;
+        case Constant::kExternalReference:
+          __ li(dst, Operand(src.ToExternalReference()));
+          break;
+        case Constant::kHeapObject:
+          __ li(dst, src.ToHeapObject());
+          break;
+        case Constant::kRpoNumber:
+          UNREACHABLE();  // TODO(titzer): loading RPO numbers on mips64.
+          break;
+      }
+      if (destination->IsStackSlot()) __ sd(dst, g.ToMemOperand(destination));
+    } else if (src.type() == Constant::kFloat32) {
+      if (destination->IsDoubleStackSlot()) {
+        MemOperand dst = g.ToMemOperand(destination);
+        __ li(at, Operand(bit_cast<int32_t>(src.ToFloat32())));
+        __ sw(at, dst);
+      } else {
+        FloatRegister dst = g.ToSingleRegister(destination);
+        __ Move(dst, src.ToFloat32());
+      }
+    } else {
+      DCHECK_EQ(Constant::kFloat64, src.type());
+      DoubleRegister dst = destination->IsDoubleRegister()
+                               ? g.ToDoubleRegister(destination)
+                               : kScratchDoubleReg;
+      __ Move(dst, src.ToFloat64());
+      if (destination->IsDoubleStackSlot()) {
+        __ sdc1(dst, g.ToMemOperand(destination));
+      }
+    }
+  } else if (source->IsDoubleRegister()) {
+    FPURegister src = g.ToDoubleRegister(source);
+    if (destination->IsDoubleRegister()) {
+      FPURegister dst = g.ToDoubleRegister(destination);
+      __ Move(dst, src);
+    } else {
+      DCHECK(destination->IsDoubleStackSlot());
+      __ sdc1(src, g.ToMemOperand(destination));
+    }
+  } else if (source->IsDoubleStackSlot()) {
+    DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot());
+    MemOperand src = g.ToMemOperand(source);
+    if (destination->IsDoubleRegister()) {
+      __ ldc1(g.ToDoubleRegister(destination), src);
+    } else {
+      FPURegister temp = kScratchDoubleReg;
+      __ ldc1(temp, src);
+      __ sdc1(temp, g.ToMemOperand(destination));
+    }
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
+void CodeGenerator::AssembleSwap(InstructionOperand* source,
+                                 InstructionOperand* destination) {
+  MipsOperandConverter g(this, NULL);
+  // Dispatch on the source and destination operand kinds.  Not all
+  // combinations are possible.
+  if (source->IsRegister()) {
+    // Register-register.
+    Register temp = kScratchReg;
+    Register src = g.ToRegister(source);
+    if (destination->IsRegister()) {
+      Register dst = g.ToRegister(destination);
+      __ Move(temp, src);
+      __ Move(src, dst);
+      __ Move(dst, temp);
+    } else {
+      DCHECK(destination->IsStackSlot());
+      MemOperand dst = g.ToMemOperand(destination);
+      __ mov(temp, src);
+      __ ld(src, dst);
+      __ sd(temp, dst);
+    }
+  } else if (source->IsStackSlot()) {
+    DCHECK(destination->IsStackSlot());
+    Register temp_0 = kScratchReg;
+    Register temp_1 = kScratchReg2;
+    MemOperand src = g.ToMemOperand(source);
+    MemOperand dst = g.ToMemOperand(destination);
+    __ ld(temp_0, src);
+    __ ld(temp_1, dst);
+    __ sd(temp_0, dst);
+    __ sd(temp_1, src);
+  } else if (source->IsDoubleRegister()) {
+    FPURegister temp = kScratchDoubleReg;
+    FPURegister src = g.ToDoubleRegister(source);
+    if (destination->IsDoubleRegister()) {
+      FPURegister dst = g.ToDoubleRegister(destination);
+      __ Move(temp, src);
+      __ Move(src, dst);
+      __ Move(dst, temp);
+    } else {
+      DCHECK(destination->IsDoubleStackSlot());
+      MemOperand dst = g.ToMemOperand(destination);
+      __ Move(temp, src);
+      __ ldc1(src, dst);
+      __ sdc1(temp, dst);
+    }
+  } else if (source->IsDoubleStackSlot()) {
+    DCHECK(destination->IsDoubleStackSlot());
+    Register temp_0 = kScratchReg;
+    FPURegister temp_1 = kScratchDoubleReg;
+    MemOperand src0 = g.ToMemOperand(source);
+    MemOperand src1(src0.rm(), src0.offset() + kPointerSize);
+    MemOperand dst0 = g.ToMemOperand(destination);
+    MemOperand dst1(dst0.rm(), dst0.offset() + kPointerSize);
+    __ ldc1(temp_1, dst0);  // Save destination in temp_1.
+    __ lw(temp_0, src0);    // Then use temp_0 to copy source to destination.
+    __ sw(temp_0, dst0);
+    __ lw(temp_0, src1);
+    __ sw(temp_0, dst1);
+    __ sdc1(temp_1, src0);
+  } else {
+    // No other combinations are possible.
+    UNREACHABLE();
+  }
+}
+
+
+void CodeGenerator::AddNopForSmiCodeInlining() {
+  // Unused on 32-bit ARM. Still exists on 64-bit arm.
+  // TODO(plind): Unclear when this is called now. Understand, fix if needed.
+  __ nop();  // Maybe PROPERTY_ACCESS_INLINED?
+}
+
+
+void CodeGenerator::EnsureSpaceForLazyDeopt() {
+  int space_needed = Deoptimizer::patch_size();
+  if (!info()->IsStub()) {
+    // Ensure that we have enough space after the previous lazy-bailout
+    // instruction for patching the code here.
+    int current_pc = masm()->pc_offset();
+    if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+      // Block tramoline pool emission for duration of padding.
+      v8::internal::Assembler::BlockTrampolinePoolScope block_trampoline_pool(
+          masm());
+      int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+      DCHECK_EQ(0, padding_size % v8::internal::Assembler::kInstrSize);
+      while (padding_size > 0) {
+        __ nop();
+        padding_size -= v8::internal::Assembler::kInstrSize;
+      }
+    }
+  }
+  MarkLazyDeoptSite();
+}
+
+#undef __
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/mips64/instruction-codes-mips64.h b/src/compiler/mips64/instruction-codes-mips64.h
new file mode 100644
index 0000000..dd019f9
--- /dev/null
+++ b/src/compiler/mips64/instruction-codes-mips64.h
@@ -0,0 +1,108 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_MIPS_INSTRUCTION_CODES_MIPS_H_
+#define V8_COMPILER_MIPS_INSTRUCTION_CODES_MIPS_H_
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// MIPS64-specific opcodes that specify which assembly sequence to emit.
+// Most opcodes specify a single instruction.
+#define TARGET_ARCH_OPCODE_LIST(V) \
+  V(Mips64Add)                     \
+  V(Mips64Dadd)                    \
+  V(Mips64Sub)                     \
+  V(Mips64Dsub)                    \
+  V(Mips64Mul)                     \
+  V(Mips64MulHigh)                 \
+  V(Mips64MulHighU)                \
+  V(Mips64Dmul)                    \
+  V(Mips64Div)                     \
+  V(Mips64Ddiv)                    \
+  V(Mips64DivU)                    \
+  V(Mips64DdivU)                   \
+  V(Mips64Mod)                     \
+  V(Mips64Dmod)                    \
+  V(Mips64ModU)                    \
+  V(Mips64DmodU)                   \
+  V(Mips64And)                     \
+  V(Mips64Or)                      \
+  V(Mips64Xor)                     \
+  V(Mips64Shl)                     \
+  V(Mips64Shr)                     \
+  V(Mips64Sar)                     \
+  V(Mips64Ext)                     \
+  V(Mips64Dext)                    \
+  V(Mips64Dshl)                    \
+  V(Mips64Dshr)                    \
+  V(Mips64Dsar)                    \
+  V(Mips64Ror)                     \
+  V(Mips64Dror)                    \
+  V(Mips64Mov)                     \
+  V(Mips64Tst)                     \
+  V(Mips64Tst32)                   \
+  V(Mips64Cmp)                     \
+  V(Mips64Cmp32)                   \
+  V(Mips64CmpD)                    \
+  V(Mips64AddD)                    \
+  V(Mips64SubD)                    \
+  V(Mips64MulD)                    \
+  V(Mips64DivD)                    \
+  V(Mips64ModD)                    \
+  V(Mips64SqrtD)                   \
+  V(Mips64Float64Floor)            \
+  V(Mips64Float64Ceil)             \
+  V(Mips64Float64RoundTruncate)    \
+  V(Mips64CvtSD)                   \
+  V(Mips64CvtDS)                   \
+  V(Mips64TruncWD)                 \
+  V(Mips64TruncUwD)                \
+  V(Mips64CvtDW)                   \
+  V(Mips64CvtDUw)                  \
+  V(Mips64Lb)                      \
+  V(Mips64Lbu)                     \
+  V(Mips64Sb)                      \
+  V(Mips64Lh)                      \
+  V(Mips64Lhu)                     \
+  V(Mips64Sh)                      \
+  V(Mips64Ld)                      \
+  V(Mips64Lw)                      \
+  V(Mips64Sw)                      \
+  V(Mips64Sd)                      \
+  V(Mips64Lwc1)                    \
+  V(Mips64Swc1)                    \
+  V(Mips64Ldc1)                    \
+  V(Mips64Sdc1)                    \
+  V(Mips64Push)                    \
+  V(Mips64StoreToStackSlot)        \
+  V(Mips64StackClaim)              \
+  V(Mips64StoreWriteBarrier)
+
+
+// Addressing modes represent the "shape" of inputs to an instruction.
+// Many instructions support multiple addressing modes. Addressing modes
+// are encoded into the InstructionCode of the instruction and tell the
+// code generator after register allocation which assembler method to call.
+//
+// We use the following local notation for addressing modes:
+//
+// R = register
+// O = register or stack slot
+// D = double register
+// I = immediate (handle, external, int32)
+// MRI = [register + immediate]
+// MRR = [register + register]
+// TODO(plind): Add the new r6 address modes.
+#define TARGET_ADDRESSING_MODE_LIST(V) \
+  V(MRI) /* [%r0 + K] */               \
+  V(MRR) /* [%r0 + %r1] */
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_MIPS_INSTRUCTION_CODES_MIPS_H_
diff --git a/src/compiler/mips64/instruction-selector-mips64.cc b/src/compiler/mips64/instruction-selector-mips64.cc
new file mode 100644
index 0000000..35ad16b
--- /dev/null
+++ b/src/compiler/mips64/instruction-selector-mips64.cc
@@ -0,0 +1,1079 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/base/bits.h"
+#include "src/compiler/instruction-selector-impl.h"
+#include "src/compiler/node-matchers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+#define TRACE_UNIMPL() \
+  PrintF("UNIMPLEMENTED instr_sel: %s at line %d\n", __FUNCTION__, __LINE__)
+
+#define TRACE() PrintF("instr_sel: %s at line %d\n", __FUNCTION__, __LINE__)
+
+
+// Adds Mips-specific methods for generating InstructionOperands.
+class Mips64OperandGenerator FINAL : public OperandGenerator {
+ public:
+  explicit Mips64OperandGenerator(InstructionSelector* selector)
+      : OperandGenerator(selector) {}
+
+  InstructionOperand* UseOperand(Node* node, InstructionCode opcode) {
+    if (CanBeImmediate(node, opcode)) {
+      return UseImmediate(node);
+    }
+    return UseRegister(node);
+  }
+
+  bool CanBeImmediate(Node* node, InstructionCode opcode) {
+    int64_t value;
+    if (node->opcode() == IrOpcode::kInt32Constant)
+      value = OpParameter<int32_t>(node);
+    else if (node->opcode() == IrOpcode::kInt64Constant)
+      value = OpParameter<int64_t>(node);
+    else
+      return false;
+    switch (ArchOpcodeField::decode(opcode)) {
+      case kMips64Shl:
+      case kMips64Sar:
+      case kMips64Shr:
+        return is_uint5(value);
+      case kMips64Dshl:
+      case kMips64Dsar:
+      case kMips64Dshr:
+        return is_uint6(value);
+      case kMips64Xor:
+        return is_uint16(value);
+      case kMips64Ldc1:
+      case kMips64Sdc1:
+        return is_int16(value + kIntSize);
+      default:
+        return is_int16(value);
+    }
+  }
+
+
+  bool CanBeImmediate(Node* node, InstructionCode opcode,
+                      FlagsContinuation* cont) {
+    int64_t value;
+    if (node->opcode() == IrOpcode::kInt32Constant)
+      value = OpParameter<int32_t>(node);
+    else if (node->opcode() == IrOpcode::kInt64Constant)
+      value = OpParameter<int64_t>(node);
+    else
+      return false;
+    switch (ArchOpcodeField::decode(opcode)) {
+      case kMips64Cmp32:
+        switch (cont->condition()) {
+          case kUnsignedLessThan:
+          case kUnsignedGreaterThanOrEqual:
+          case kUnsignedLessThanOrEqual:
+          case kUnsignedGreaterThan:
+            // Immediate operands for unsigned 32-bit compare operations
+            // should not be sign-extended.
+            return is_uint15(value);
+          default:
+            return false;
+        }
+      default:
+        return is_int16(value);
+    }
+  }
+
+
+ private:
+  bool ImmediateFitsAddrMode1Instruction(int32_t imm) const {
+    TRACE_UNIMPL();
+    return false;
+  }
+};
+
+
+static void VisitRR(InstructionSelector* selector, ArchOpcode opcode,
+                    Node* node) {
+  Mips64OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)));
+}
+
+
+static void VisitRRR(InstructionSelector* selector, ArchOpcode opcode,
+                     Node* node) {
+  Mips64OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)),
+                 g.UseRegister(node->InputAt(1)));
+}
+
+
+static void VisitRRO(InstructionSelector* selector, ArchOpcode opcode,
+                     Node* node) {
+  Mips64OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)),
+                 g.UseOperand(node->InputAt(1), opcode));
+}
+
+
+static void VisitBinop(InstructionSelector* selector, Node* node,
+                       InstructionCode opcode, FlagsContinuation* cont) {
+  Mips64OperandGenerator g(selector);
+  Int32BinopMatcher m(node);
+  InstructionOperand* inputs[4];
+  size_t input_count = 0;
+  InstructionOperand* outputs[2];
+  size_t output_count = 0;
+
+  inputs[input_count++] = g.UseRegister(m.left().node());
+  inputs[input_count++] = g.UseOperand(m.right().node(), opcode);
+
+  if (cont->IsBranch()) {
+    inputs[input_count++] = g.Label(cont->true_block());
+    inputs[input_count++] = g.Label(cont->false_block());
+  }
+
+  outputs[output_count++] = g.DefineAsRegister(node);
+  if (cont->IsSet()) {
+    outputs[output_count++] = g.DefineAsRegister(cont->result());
+  }
+
+  DCHECK_NE(0, input_count);
+  DCHECK_NE(0, output_count);
+  DCHECK_GE(arraysize(inputs), input_count);
+  DCHECK_GE(arraysize(outputs), output_count);
+
+  Instruction* instr = selector->Emit(cont->Encode(opcode), output_count,
+                                      outputs, input_count, inputs);
+  if (cont->IsBranch()) instr->MarkAsControl();
+}
+
+
+static void VisitBinop(InstructionSelector* selector, Node* node,
+                       InstructionCode opcode) {
+  FlagsContinuation cont;
+  VisitBinop(selector, node, opcode, &cont);
+}
+
+
+void InstructionSelector::VisitLoad(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
+  MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
+  Mips64OperandGenerator g(this);
+  Node* base = node->InputAt(0);
+  Node* index = node->InputAt(1);
+
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepFloat32:
+      opcode = kMips64Lwc1;
+      break;
+    case kRepFloat64:
+      opcode = kMips64Ldc1;
+      break;
+    case kRepBit:  // Fall through.
+    case kRepWord8:
+      opcode = typ == kTypeUint32 ? kMips64Lbu : kMips64Lb;
+      break;
+    case kRepWord16:
+      opcode = typ == kTypeUint32 ? kMips64Lhu : kMips64Lh;
+      break;
+    case kRepWord32:
+      opcode = kMips64Lw;
+      break;
+    case kRepTagged:  // Fall through.
+    case kRepWord64:
+      opcode = kMips64Ld;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+
+  if (g.CanBeImmediate(index, opcode)) {
+    Emit(opcode | AddressingModeField::encode(kMode_MRI),
+         g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
+  } else {
+    InstructionOperand* addr_reg = g.TempRegister();
+    Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
+         g.UseRegister(index), g.UseRegister(base));
+    // Emit desired load opcode, using temp addr_reg.
+    Emit(opcode | AddressingModeField::encode(kMode_MRI),
+         g.DefineAsRegister(node), addr_reg, g.TempImmediate(0));
+  }
+}
+
+
+void InstructionSelector::VisitStore(Node* node) {
+  Mips64OperandGenerator g(this);
+  Node* base = node->InputAt(0);
+  Node* index = node->InputAt(1);
+  Node* value = node->InputAt(2);
+
+  StoreRepresentation store_rep = OpParameter<StoreRepresentation>(node);
+  MachineType rep = RepresentationOf(store_rep.machine_type());
+  if (store_rep.write_barrier_kind() == kFullWriteBarrier) {
+    DCHECK(rep == kRepTagged);
+    // TODO(dcarney): refactor RecordWrite function to take temp registers
+    //                and pass them here instead of using fixed regs
+    // TODO(dcarney): handle immediate indices.
+    InstructionOperand* temps[] = {g.TempRegister(t1), g.TempRegister(t2)};
+    Emit(kMips64StoreWriteBarrier, NULL, g.UseFixed(base, t0),
+         g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps);
+    return;
+  }
+  DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
+
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepFloat32:
+      opcode = kMips64Swc1;
+      break;
+    case kRepFloat64:
+      opcode = kMips64Sdc1;
+      break;
+    case kRepBit:  // Fall through.
+    case kRepWord8:
+      opcode = kMips64Sb;
+      break;
+    case kRepWord16:
+      opcode = kMips64Sh;
+      break;
+    case kRepWord32:
+      opcode = kMips64Sw;
+      break;
+    case kRepTagged:  // Fall through.
+    case kRepWord64:
+      opcode = kMips64Sd;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+
+  if (g.CanBeImmediate(index, opcode)) {
+    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
+         g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
+  } else {
+    InstructionOperand* addr_reg = g.TempRegister();
+    Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
+         g.UseRegister(index), g.UseRegister(base));
+    // Emit desired store opcode, using temp addr_reg.
+    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, addr_reg,
+         g.TempImmediate(0), g.UseRegister(value));
+  }
+}
+
+
+void InstructionSelector::VisitWord32And(Node* node) {
+  VisitBinop(this, node, kMips64And);
+}
+
+
+void InstructionSelector::VisitWord64And(Node* node) {
+  VisitBinop(this, node, kMips64And);
+}
+
+
+void InstructionSelector::VisitWord32Or(Node* node) {
+  VisitBinop(this, node, kMips64Or);
+}
+
+
+void InstructionSelector::VisitWord64Or(Node* node) {
+  VisitBinop(this, node, kMips64Or);
+}
+
+
+void InstructionSelector::VisitWord32Xor(Node* node) {
+  VisitBinop(this, node, kMips64Xor);
+}
+
+
+void InstructionSelector::VisitWord64Xor(Node* node) {
+  VisitBinop(this, node, kMips64Xor);
+}
+
+
+void InstructionSelector::VisitWord32Shl(Node* node) {
+  VisitRRO(this, kMips64Shl, node);
+}
+
+
+void InstructionSelector::VisitWord32Shr(Node* node) {
+  VisitRRO(this, kMips64Shr, node);
+}
+
+
+void InstructionSelector::VisitWord32Sar(Node* node) {
+  VisitRRO(this, kMips64Sar, node);
+}
+
+
+void InstructionSelector::VisitWord64Shl(Node* node) {
+  VisitRRO(this, kMips64Dshl, node);
+}
+
+
+void InstructionSelector::VisitWord64Shr(Node* node) {
+  VisitRRO(this, kMips64Dshr, node);
+}
+
+
+void InstructionSelector::VisitWord64Sar(Node* node) {
+  VisitRRO(this, kMips64Dsar, node);
+}
+
+
+void InstructionSelector::VisitWord32Ror(Node* node) {
+  VisitRRO(this, kMips64Ror, node);
+}
+
+
+void InstructionSelector::VisitWord64Ror(Node* node) {
+  VisitRRO(this, kMips64Dror, node);
+}
+
+
+void InstructionSelector::VisitInt32Add(Node* node) {
+  Mips64OperandGenerator g(this);
+  // TODO(plind): Consider multiply & add optimization from arm port.
+  VisitBinop(this, node, kMips64Add);
+}
+
+
+void InstructionSelector::VisitInt64Add(Node* node) {
+  Mips64OperandGenerator g(this);
+  // TODO(plind): Consider multiply & add optimization from arm port.
+  VisitBinop(this, node, kMips64Dadd);
+}
+
+
+void InstructionSelector::VisitInt32Sub(Node* node) {
+  VisitBinop(this, node, kMips64Sub);
+}
+
+
+void InstructionSelector::VisitInt64Sub(Node* node) {
+  VisitBinop(this, node, kMips64Dsub);
+}
+
+
+void InstructionSelector::VisitInt32Mul(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (m.right().HasValue() && m.right().Value() > 0) {
+    int32_t value = m.right().Value();
+    if (base::bits::IsPowerOfTwo32(value)) {
+      Emit(kMips64Shl | AddressingModeField::encode(kMode_None),
+           g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+           g.TempImmediate(WhichPowerOf2(value)));
+      return;
+    }
+    if (base::bits::IsPowerOfTwo32(value - 1)) {
+      InstructionOperand* temp = g.TempRegister();
+      Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp,
+           g.UseRegister(m.left().node()),
+           g.TempImmediate(WhichPowerOf2(value - 1)));
+      Emit(kMips64Add | AddressingModeField::encode(kMode_None),
+           g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp);
+      return;
+    }
+    if (base::bits::IsPowerOfTwo32(value + 1)) {
+      InstructionOperand* temp = g.TempRegister();
+      Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp,
+           g.UseRegister(m.left().node()),
+           g.TempImmediate(WhichPowerOf2(value + 1)));
+      Emit(kMips64Sub | AddressingModeField::encode(kMode_None),
+           g.DefineAsRegister(node), temp, g.UseRegister(m.left().node()));
+      return;
+    }
+  }
+  Emit(kMips64Mul, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitInt32MulHigh(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64MulHigh, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+}
+
+
+void InstructionSelector::VisitUint32MulHigh(Node* node) {
+  Mips64OperandGenerator g(this);
+  InstructionOperand* const dmul_operand = g.TempRegister();
+  Emit(kMips64MulHighU, dmul_operand, g.UseRegister(node->InputAt(0)),
+       g.UseRegister(node->InputAt(1)));
+  Emit(kMips64Ext, g.DefineAsRegister(node), dmul_operand, g.TempImmediate(0),
+       g.TempImmediate(32));
+}
+
+
+void InstructionSelector::VisitInt64Mul(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  // TODO(dusmil): Add optimization for shifts larger than 32.
+  if (m.right().HasValue() && m.right().Value() > 0) {
+    int64_t value = m.right().Value();
+    if (base::bits::IsPowerOfTwo32(value)) {
+      Emit(kMips64Dshl | AddressingModeField::encode(kMode_None),
+           g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+           g.TempImmediate(WhichPowerOf2(value)));
+      return;
+    }
+    if (base::bits::IsPowerOfTwo32(value - 1)) {
+      InstructionOperand* temp = g.TempRegister();
+      Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp,
+           g.UseRegister(m.left().node()),
+           g.TempImmediate(WhichPowerOf2(value - 1)));
+      Emit(kMips64Dadd | AddressingModeField::encode(kMode_None),
+           g.DefineAsRegister(node), g.UseRegister(m.left().node()), temp);
+      return;
+    }
+    if (base::bits::IsPowerOfTwo32(value + 1)) {
+      InstructionOperand* temp = g.TempRegister();
+      Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp,
+           g.UseRegister(m.left().node()),
+           g.TempImmediate(WhichPowerOf2(value + 1)));
+      Emit(kMips64Dsub | AddressingModeField::encode(kMode_None),
+           g.DefineAsRegister(node), temp, g.UseRegister(m.left().node()));
+      return;
+    }
+  }
+  Emit(kMips64Dmul, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitInt32Div(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  Emit(kMips64Div, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitUint32Div(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  Emit(kMips64DivU, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitInt32Mod(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  Emit(kMips64Mod, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitUint32Mod(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  Emit(kMips64ModU, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitInt64Div(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  Emit(kMips64Ddiv, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitUint64Div(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  Emit(kMips64DdivU, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitInt64Mod(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  Emit(kMips64Dmod, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitUint64Mod(Node* node) {
+  Mips64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  Emit(kMips64DmodU, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+       g.UseRegister(m.right().node()));
+}
+
+
+void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64CvtDS, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64CvtDW, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64CvtDUw, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64TruncWD, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64TruncUwD, g.DefineAsRegister(node),
+       g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitChangeInt32ToInt64(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64Shl, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
+       g.TempImmediate(0));
+}
+
+
+void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64Dext, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
+       g.TempImmediate(0), g.TempImmediate(32));
+}
+
+
+void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64Ext, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)),
+       g.TempImmediate(0), g.TempImmediate(32));
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64CvtSD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64Add(Node* node) {
+  VisitRRR(this, kMips64AddD, node);
+}
+
+
+void InstructionSelector::VisitFloat64Sub(Node* node) {
+  VisitRRR(this, kMips64SubD, node);
+}
+
+
+void InstructionSelector::VisitFloat64Mul(Node* node) {
+  VisitRRR(this, kMips64MulD, node);
+}
+
+
+void InstructionSelector::VisitFloat64Div(Node* node) {
+  VisitRRR(this, kMips64DivD, node);
+}
+
+
+void InstructionSelector::VisitFloat64Mod(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64ModD, g.DefineAsFixed(node, f0),
+       g.UseFixed(node->InputAt(0), f12),
+       g.UseFixed(node->InputAt(1), f14))->MarkAsCall();
+}
+
+
+void InstructionSelector::VisitFloat64Sqrt(Node* node) {
+  Mips64OperandGenerator g(this);
+  Emit(kMips64SqrtD, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)));
+}
+
+
+void InstructionSelector::VisitFloat64Floor(Node* node) {
+  VisitRR(this, kMips64Float64Floor, node);
+}
+
+
+void InstructionSelector::VisitFloat64Ceil(Node* node) {
+  VisitRR(this, kMips64Float64Ceil, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
+  VisitRR(this, kMips64Float64RoundTruncate, node);
+}
+
+
+void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
+  UNREACHABLE();
+}
+
+
+void InstructionSelector::VisitCall(Node* node) {
+  Mips64OperandGenerator g(this);
+  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
+
+  FrameStateDescriptor* frame_state_descriptor = NULL;
+  if (descriptor->NeedsFrameState()) {
+    frame_state_descriptor =
+        GetFrameStateDescriptor(node->InputAt(descriptor->InputCount()));
+  }
+
+  CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
+
+  // Compute InstructionOperands for inputs and outputs.
+  InitializeCallBuffer(node, &buffer, true, false);
+
+  int push_count = buffer.pushed_nodes.size();
+  if (push_count > 0) {
+    Emit(kMips64StackClaim | MiscField::encode(push_count), NULL);
+  }
+  int slot = buffer.pushed_nodes.size() - 1;
+  for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
+       input != buffer.pushed_nodes.rend(); input++) {
+    Emit(kMips64StoreToStackSlot | MiscField::encode(slot), NULL,
+         g.UseRegister(*input));
+    slot--;
+  }
+
+  // Select the appropriate opcode based on the call type.
+  InstructionCode opcode;
+  switch (descriptor->kind()) {
+    case CallDescriptor::kCallCodeObject: {
+      opcode = kArchCallCodeObject;
+      break;
+    }
+    case CallDescriptor::kCallJSFunction:
+      opcode = kArchCallJSFunction;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  opcode |= MiscField::encode(descriptor->flags());
+
+  // Emit the call instruction.
+  Instruction* call_instr =
+      Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
+           buffer.instruction_args.size(), &buffer.instruction_args.front());
+
+  call_instr->MarkAsCall();
+}
+
+
+void InstructionSelector::VisitCheckedLoad(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  Mips64OperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepWord8:
+      opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
+      break;
+    case kRepWord16:
+      opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
+      break;
+    case kRepWord32:
+      opcode = kCheckedLoadWord32;
+      break;
+    case kRepFloat32:
+      opcode = kCheckedLoadFloat32;
+      break;
+    case kRepFloat64:
+      opcode = kCheckedLoadFloat64;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
+                                           ? g.UseImmediate(offset)
+                                           : g.UseRegister(offset);
+
+  InstructionOperand* length_operand =
+      (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
+      ? g.UseImmediate(length)
+      : g.UseRegister(length)
+      : g.UseRegister(length);
+
+  Emit(opcode | AddressingModeField::encode(kMode_MRI),
+       g.DefineAsRegister(node), offset_operand, length_operand,
+       g.UseRegister(buffer));
+}
+
+
+void InstructionSelector::VisitCheckedStore(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  Mips64OperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  Node* const value = node->InputAt(3);
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepWord8:
+      opcode = kCheckedStoreWord8;
+      break;
+    case kRepWord16:
+      opcode = kCheckedStoreWord16;
+      break;
+    case kRepWord32:
+      opcode = kCheckedStoreWord32;
+      break;
+    case kRepFloat32:
+      opcode = kCheckedStoreFloat32;
+      break;
+    case kRepFloat64:
+      opcode = kCheckedStoreFloat64;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
+                                           ? g.UseImmediate(offset)
+                                           : g.UseRegister(offset);
+
+  InstructionOperand* length_operand =
+      (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
+      ? g.UseImmediate(length)
+      : g.UseRegister(length)
+      : g.UseRegister(length);
+
+  Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand,
+       length_operand, g.UseRegister(value), g.UseRegister(buffer));
+}
+
+
+namespace {
+
+// Shared routine for multiple compare operations.
+static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                         InstructionOperand* left, InstructionOperand* right,
+                         FlagsContinuation* cont) {
+  Mips64OperandGenerator g(selector);
+  opcode = cont->Encode(opcode);
+  if (cont->IsBranch()) {
+    selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()),
+                   g.Label(cont->false_block()))->MarkAsControl();
+  } else {
+    DCHECK(cont->IsSet());
+    selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
+  }
+}
+
+
+// Shared routine for multiple float compare operations.
+void VisitFloat64Compare(InstructionSelector* selector, Node* node,
+                         FlagsContinuation* cont) {
+  Mips64OperandGenerator g(selector);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  VisitCompare(selector, kMips64CmpD, g.UseRegister(left), g.UseRegister(right),
+               cont);
+}
+
+
+// Shared routine for multiple word compare operations.
+void VisitWordCompare(InstructionSelector* selector, Node* node,
+                      InstructionCode opcode, FlagsContinuation* cont,
+                      bool commutative) {
+  Mips64OperandGenerator g(selector);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+
+  // Match immediates on left or right side of comparison.
+  if (g.CanBeImmediate(right, opcode, cont)) {
+    VisitCompare(selector, opcode, g.UseRegister(left), g.UseImmediate(right),
+                 cont);
+  } else if (g.CanBeImmediate(left, opcode, cont)) {
+    if (!commutative) cont->Commute();
+    VisitCompare(selector, opcode, g.UseRegister(right), g.UseImmediate(left),
+                 cont);
+  } else {
+    VisitCompare(selector, opcode, g.UseRegister(left), g.UseRegister(right),
+                 cont);
+  }
+}
+
+
+void VisitWord32Compare(InstructionSelector* selector, Node* node,
+                        FlagsContinuation* cont) {
+  VisitWordCompare(selector, node, kMips64Cmp32, cont, false);
+}
+
+
+void VisitWord64Compare(InstructionSelector* selector, Node* node,
+                        FlagsContinuation* cont) {
+  VisitWordCompare(selector, node, kMips64Cmp, cont, false);
+}
+
+}  // namespace
+
+
+void EmitWordCompareZero(InstructionSelector* selector, InstructionCode opcode,
+                         Node* value, FlagsContinuation* cont) {
+  Mips64OperandGenerator g(selector);
+  opcode = cont->Encode(opcode);
+  InstructionOperand* const value_operand = g.UseRegister(value);
+  if (cont->IsBranch()) {
+    selector->Emit(opcode, nullptr, value_operand, g.TempImmediate(0),
+                   g.Label(cont->true_block()),
+                   g.Label(cont->false_block()))->MarkAsControl();
+  } else {
+    selector->Emit(opcode, g.DefineAsRegister(cont->result()), value_operand,
+                   g.TempImmediate(0));
+  }
+}
+
+
+// Shared routine for word comparisons against zero.
+void VisitWordCompareZero(InstructionSelector* selector, Node* user,
+                          Node* value, FlagsContinuation* cont) {
+  // Initially set comparison against 0 to be 64-bit variant for branches that
+  // cannot combine.
+  InstructionCode opcode = kMips64Cmp;
+  while (selector->CanCover(user, value)) {
+    if (user->opcode() == IrOpcode::kWord32Equal) {
+      opcode = kMips64Cmp32;
+    }
+    switch (value->opcode()) {
+      case IrOpcode::kWord32Equal: {
+        // Combine with comparisons against 0 by simply inverting the
+        // continuation.
+        Int32BinopMatcher m(value);
+        if (m.right().Is(0)) {
+          user = value;
+          value = m.left().node();
+          cont->Negate();
+          opcode = kMips64Cmp32;
+          continue;
+        }
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitWord32Compare(selector, value, cont);
+      }
+      case IrOpcode::kInt32LessThan:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThan);
+        return VisitWord32Compare(selector, value, cont);
+      case IrOpcode::kInt32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+        return VisitWord32Compare(selector, value, cont);
+      case IrOpcode::kUint32LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitWord32Compare(selector, value, cont);
+      case IrOpcode::kUint32LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWord32Compare(selector, value, cont);
+      case IrOpcode::kWord64Equal: {
+        // Combine with comparisons against 0 by simply inverting the
+        // continuation.
+        Int64BinopMatcher m(value);
+        if (m.right().Is(0)) {
+          user = value;
+          value = m.left().node();
+          cont->Negate();
+          continue;
+        }
+        cont->OverwriteAndNegateIfEqual(kEqual);
+        return VisitWord64Compare(selector, value, cont);
+      }
+      case IrOpcode::kInt64LessThan:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThan);
+        return VisitWord64Compare(selector, value, cont);
+      case IrOpcode::kInt64LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+        return VisitWord64Compare(selector, value, cont);
+      case IrOpcode::kUint64LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitWord64Compare(selector, value, cont);
+      case IrOpcode::kFloat64Equal:
+        cont->OverwriteAndNegateIfEqual(kUnorderedEqual);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kFloat64LessThan:
+        cont->OverwriteAndNegateIfEqual(kUnorderedLessThan);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kFloat64LessThanOrEqual:
+        cont->OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+        return VisitFloat64Compare(selector, value, cont);
+      case IrOpcode::kProjection:
+        // Check if this is the overflow output projection of an
+        // <Operation>WithOverflow node.
+        if (OpParameter<size_t>(value) == 1u) {
+          // We cannot combine the <Operation>WithOverflow with this branch
+          // unless the 0th projection (the use of the actual value of the
+          // <Operation> is either NULL, which means there's no use of the
+          // actual value, or was already defined, which means it is scheduled
+          // *AFTER* this branch).
+          Node* node = value->InputAt(0);
+          Node* result = node->FindProjection(0);
+          if (result == NULL || selector->IsDefined(result)) {
+            switch (node->opcode()) {
+              case IrOpcode::kInt32AddWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(selector, node, kMips64Dadd, cont);
+              case IrOpcode::kInt32SubWithOverflow:
+                cont->OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(selector, node, kMips64Dsub, cont);
+              default:
+                break;
+            }
+          }
+        }
+        break;
+      case IrOpcode::kWord32And:
+        return VisitWordCompare(selector, value, kMips64Tst32, cont, true);
+      case IrOpcode::kWord64And:
+        return VisitWordCompare(selector, value, kMips64Tst, cont, true);
+      default:
+        break;
+    }
+    break;
+  }
+
+  // Continuation could not be combined with a compare, emit compare against 0.
+  EmitWordCompareZero(selector, opcode, value, cont);
+}
+
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+                                      BasicBlock* fbranch) {
+  FlagsContinuation cont(kNotEqual, tbranch, fbranch);
+  VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
+}
+
+
+void InstructionSelector::VisitWord32Equal(Node* const node) {
+  FlagsContinuation cont(kEqual, node);
+  Int32BinopMatcher m(node);
+  if (m.right().Is(0)) {
+    return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
+  }
+
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWord32Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kMips64Dadd, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kMips64Dadd, &cont);
+}
+
+
+void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kMips64Dsub, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kMips64Dsub, &cont);
+}
+
+
+void InstructionSelector::VisitWord64Equal(Node* const node) {
+  FlagsContinuation cont(kEqual, node);
+  Int64BinopMatcher m(node);
+  if (m.right().Is(0)) {
+    return VisitWordCompareZero(this, m.node(), m.left().node(), &cont);
+  }
+
+  VisitWord64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt64LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWord64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWord64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitUint64LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWord64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64Equal(Node* node) {
+  FlagsContinuation cont(kUnorderedEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThan(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThan, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  return MachineOperatorBuilder::kFloat64Floor |
+         MachineOperatorBuilder::kFloat64Ceil |
+         MachineOperatorBuilder::kFloat64RoundTruncate;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/mips64/linkage-mips64.cc b/src/compiler/mips64/linkage-mips64.cc
new file mode 100644
index 0000000..0e1a590
--- /dev/null
+++ b/src/compiler/mips64/linkage-mips64.cc
@@ -0,0 +1,67 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/assembler.h"
+#include "src/code-stubs.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/linkage-impl.h"
+#include "src/zone.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+struct MipsLinkageHelperTraits {
+  static Register ReturnValueReg() { return v0; }
+  static Register ReturnValue2Reg() { return v1; }
+  static Register JSCallFunctionReg() { return a1; }
+  static Register ContextReg() { return cp; }
+  static Register RuntimeCallFunctionReg() { return a1; }
+  static Register RuntimeCallArgCountReg() { return a0; }
+  static RegList CCalleeSaveRegisters() {
+    return s0.bit() | s1.bit() | s2.bit() | s3.bit() | s4.bit() | s5.bit() |
+           s6.bit() | s7.bit();
+  }
+  static Register CRegisterParameter(int i) {
+    static Register register_parameters[] = {a0, a1, a2, a3, a4, a5, a6, a7};
+    return register_parameters[i];
+  }
+  static int CRegisterParametersLength() { return 8; }
+};
+
+
+typedef LinkageHelper<MipsLinkageHelperTraits> LH;
+
+CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
+                                             CallDescriptor::Flags flags) {
+  return LH::GetJSCallDescriptor(zone, parameter_count, flags);
+}
+
+
+CallDescriptor* Linkage::GetRuntimeCallDescriptor(
+    Runtime::FunctionId function, int parameter_count,
+    Operator::Properties properties, Zone* zone) {
+  return LH::GetRuntimeCallDescriptor(zone, function, parameter_count,
+                                      properties);
+}
+
+
+CallDescriptor* Linkage::GetStubCallDescriptor(
+    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
+    CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone) {
+  return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count,
+                                   flags, properties);
+}
+
+
+CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
+                                                  MachineSignature* sig) {
+  return LH::GetSimplifiedCDescriptor(zone, sig);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/move-optimizer.cc b/src/compiler/move-optimizer.cc
new file mode 100644
index 0000000..330f32f
--- /dev/null
+++ b/src/compiler/move-optimizer.cc
@@ -0,0 +1,205 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/move-optimizer.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+MoveOptimizer::MoveOptimizer(Zone* local_zone, InstructionSequence* code)
+    : local_zone_(local_zone),
+      code_(code),
+      temp_vector_0_(local_zone),
+      temp_vector_1_(local_zone) {}
+
+
+void MoveOptimizer::Run() {
+  // First smash all consecutive moves into the left most move slot.
+  for (auto* block : code()->instruction_blocks()) {
+    GapInstruction* prev_gap = nullptr;
+    for (int index = block->code_start(); index < block->code_end(); ++index) {
+      auto instr = code()->instructions()[index];
+      if (!instr->IsGapMoves()) {
+        if (instr->IsSourcePosition() || instr->IsNop()) continue;
+        FinalizeMoves(&temp_vector_0_, &temp_vector_1_, prev_gap);
+        prev_gap = nullptr;
+        continue;
+      }
+      auto gap = GapInstruction::cast(instr);
+      // Find first non-empty slot.
+      int i = GapInstruction::FIRST_INNER_POSITION;
+      for (; i <= GapInstruction::LAST_INNER_POSITION; i++) {
+        auto move = gap->parallel_moves()[i];
+        if (move == nullptr) continue;
+        auto move_ops = move->move_operands();
+        auto op = move_ops->begin();
+        for (; op != move_ops->end(); ++op) {
+          if (!op->IsRedundant()) break;
+        }
+        if (op == move_ops->end()) {
+          move_ops->Rewind(0);  // Clear this redundant move.
+        } else {
+          break;  // Found index of first non-redundant move.
+        }
+      }
+      // Nothing to do here.
+      if (i == GapInstruction::LAST_INNER_POSITION + 1) {
+        if (prev_gap != nullptr) {
+          // Slide prev_gap down so we always know where to look for it.
+          std::swap(prev_gap->parallel_moves()[0], gap->parallel_moves()[0]);
+          prev_gap = gap;
+        }
+        continue;
+      }
+      // Move the first non-empty gap to position 0.
+      std::swap(gap->parallel_moves()[0], gap->parallel_moves()[i]);
+      auto left = gap->parallel_moves()[0];
+      // Compress everything into position 0.
+      for (++i; i <= GapInstruction::LAST_INNER_POSITION; ++i) {
+        auto move = gap->parallel_moves()[i];
+        if (move == nullptr) continue;
+        CompressMoves(&temp_vector_0_, left, move);
+      }
+      if (prev_gap != nullptr) {
+        // Smash left into prev_gap, killing left.
+        auto pred_moves = prev_gap->parallel_moves()[0];
+        CompressMoves(&temp_vector_0_, pred_moves, left);
+        std::swap(prev_gap->parallel_moves()[0], gap->parallel_moves()[0]);
+      }
+      prev_gap = gap;
+    }
+    FinalizeMoves(&temp_vector_0_, &temp_vector_1_, prev_gap);
+  }
+}
+
+
+static MoveOperands* PrepareInsertAfter(ParallelMove* left, MoveOperands* move,
+                                        Zone* zone) {
+  auto move_ops = left->move_operands();
+  MoveOperands* replacement = nullptr;
+  MoveOperands* to_eliminate = nullptr;
+  for (auto curr = move_ops->begin(); curr != move_ops->end(); ++curr) {
+    if (curr->IsEliminated()) continue;
+    if (curr->destination()->Equals(move->source())) {
+      DCHECK_EQ(nullptr, replacement);
+      replacement = curr;
+      if (to_eliminate != nullptr) break;
+    } else if (curr->destination()->Equals(move->destination())) {
+      DCHECK_EQ(nullptr, to_eliminate);
+      to_eliminate = curr;
+      if (replacement != nullptr) break;
+    }
+  }
+  DCHECK(!(replacement == to_eliminate && replacement != nullptr));
+  if (replacement != nullptr) {
+    auto new_source = new (zone) InstructionOperand(
+        replacement->source()->kind(), replacement->source()->index());
+    move->set_source(new_source);
+  }
+  return to_eliminate;
+}
+
+
+void MoveOptimizer::CompressMoves(MoveOpVector* eliminated, ParallelMove* left,
+                                  ParallelMove* right) {
+  DCHECK(eliminated->empty());
+  auto move_ops = right->move_operands();
+  // Modify the right moves in place and collect moves that will be killed by
+  // merging the two gaps.
+  for (auto op = move_ops->begin(); op != move_ops->end(); ++op) {
+    if (op->IsRedundant()) continue;
+    MoveOperands* to_eliminate = PrepareInsertAfter(left, op, code_zone());
+    if (to_eliminate != nullptr) {
+      eliminated->push_back(to_eliminate);
+    }
+  }
+  // Eliminate dead moves.  Must happen before insertion of new moves as the
+  // contents of eliminated are pointers into a list.
+  for (auto to_eliminate : *eliminated) {
+    to_eliminate->Eliminate();
+  }
+  eliminated->clear();
+  // Add all possibly modified moves from right side.
+  for (auto op = move_ops->begin(); op != move_ops->end(); ++op) {
+    if (op->IsRedundant()) continue;
+    left->move_operands()->Add(*op, code_zone());
+  }
+  // Nuke right.
+  move_ops->Rewind(0);
+}
+
+
+void MoveOptimizer::FinalizeMoves(MoveOpVector* loads, MoveOpVector* new_moves,
+                                  GapInstruction* gap) {
+  DCHECK(loads->empty());
+  DCHECK(new_moves->empty());
+  if (gap == nullptr) return;
+  // Split multiple loads of the same constant or stack slot off into the second
+  // slot and keep remaining moves in the first slot.
+  auto move_ops = gap->parallel_moves()[0]->move_operands();
+  for (auto move = move_ops->begin(); move != move_ops->end(); ++move) {
+    if (move->IsRedundant()) {
+      move->Eliminate();
+      continue;
+    }
+    if (!(move->source()->IsConstant() || move->source()->IsStackSlot() ||
+          move->source()->IsDoubleStackSlot()))
+      continue;
+    // Search for existing move to this slot.
+    MoveOperands* found = nullptr;
+    for (auto load : *loads) {
+      if (load->source()->Equals(move->source())) {
+        found = load;
+        break;
+      }
+    }
+    // Not found so insert.
+    if (found == nullptr) {
+      loads->push_back(move);
+      // Replace source with copy for later use.
+      auto dest = move->destination();
+      move->set_destination(new (code_zone())
+                            InstructionOperand(dest->kind(), dest->index()));
+      continue;
+    }
+    if ((found->destination()->IsStackSlot() ||
+         found->destination()->IsDoubleStackSlot()) &&
+        !(move->destination()->IsStackSlot() ||
+          move->destination()->IsDoubleStackSlot())) {
+      // Found a better source for this load.  Smash it in place to affect other
+      // loads that have already been split.
+      InstructionOperand::Kind found_kind = found->destination()->kind();
+      int found_index = found->destination()->index();
+      auto next_dest =
+          new (code_zone()) InstructionOperand(found_kind, found_index);
+      auto dest = move->destination();
+      found->destination()->ConvertTo(dest->kind(), dest->index());
+      move->set_destination(next_dest);
+    }
+    // move from load destination.
+    move->set_source(found->destination());
+    new_moves->push_back(move);
+  }
+  loads->clear();
+  if (new_moves->empty()) return;
+  // Insert all new moves into slot 1.
+  auto slot_1 = gap->GetOrCreateParallelMove(
+      static_cast<GapInstruction::InnerPosition>(1), code_zone());
+  DCHECK(slot_1->move_operands()->is_empty());
+  slot_1->move_operands()->AddBlock(MoveOperands(nullptr, nullptr),
+                                    static_cast<int>(new_moves->size()),
+                                    code_zone());
+  auto it = slot_1->move_operands()->begin();
+  for (auto new_move : *new_moves) {
+    std::swap(*new_move, *it);
+    ++it;
+  }
+  DCHECK_EQ(it, slot_1->move_operands()->end());
+  new_moves->clear();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/move-optimizer.h b/src/compiler/move-optimizer.h
new file mode 100644
index 0000000..bbce686
--- /dev/null
+++ b/src/compiler/move-optimizer.h
@@ -0,0 +1,44 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_MOVE_OPTIMIZER_
+#define V8_COMPILER_MOVE_OPTIMIZER_
+
+#include "src/compiler/instruction.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class MoveOptimizer FINAL {
+ public:
+  MoveOptimizer(Zone* local_zone, InstructionSequence* code);
+  void Run();
+
+ private:
+  typedef ZoneVector<MoveOperands*> MoveOpVector;
+
+  InstructionSequence* code() const { return code_; }
+  Zone* local_zone() const { return local_zone_; }
+  Zone* code_zone() const { return code()->zone(); }
+
+  void CompressMoves(MoveOpVector* eliminated, ParallelMove* left,
+                     ParallelMove* right);
+  void FinalizeMoves(MoveOpVector* loads, MoveOpVector* new_moves,
+                     GapInstruction* gap);
+
+  Zone* const local_zone_;
+  InstructionSequence* const code_;
+  MoveOpVector temp_vector_0_;
+  MoveOpVector temp_vector_1_;
+
+  DISALLOW_COPY_AND_ASSIGN(MoveOptimizer);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_MOVE_OPTIMIZER_
diff --git a/src/compiler/node-aux-data-inl.h b/src/compiler/node-aux-data-inl.h
index 79f1abf..d8db4b9 100644
--- a/src/compiler/node-aux-data-inl.h
+++ b/src/compiler/node-aux-data-inl.h
@@ -29,7 +29,7 @@
 
 
 template <class T>
-T NodeAuxData<T>::Get(Node* node) {
+T NodeAuxData<T>::Get(Node* node) const {
   int id = node->id();
   if (id >= static_cast<int>(aux_data_.size())) {
     return T();
diff --git a/src/compiler/node-aux-data.h b/src/compiler/node-aux-data.h
index 7acce33..a08dc58 100644
--- a/src/compiler/node-aux-data.h
+++ b/src/compiler/node-aux-data.h
@@ -21,7 +21,7 @@
   inline explicit NodeAuxData(Zone* zone);
 
   inline void Set(Node* node, const T& data);
-  inline T Get(Node* node);
+  inline T Get(Node* node) const;
 
  private:
   ZoneVector<T> aux_data_;
diff --git a/src/compiler/node-cache.cc b/src/compiler/node-cache.cc
index 7cda167..92a3fa0 100644
--- a/src/compiler/node-cache.cc
+++ b/src/compiler/node-cache.cc
@@ -4,65 +4,51 @@
 
 #include "src/compiler/node-cache.h"
 
+#include <cstring>
+
+#include "src/zone.h"
+#include "src/zone-containers.h"
+
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-#define INITIAL_SIZE 16
-#define LINEAR_PROBE 5
+namespace {
 
-template <typename Key>
-int32_t NodeCacheHash(Key key) {
-  UNIMPLEMENTED();
-  return 0;
-}
+enum { kInitialSize = 16u, kLinearProbe = 5u };
 
-template <>
-inline int32_t NodeCacheHash(int32_t key) {
-  return ComputeIntegerHash(key, 0);
-}
+}  // namespace
 
 
-template <>
-inline int32_t NodeCacheHash(int64_t key) {
-  return ComputeLongHash(key);
-}
+template <typename Key, typename Hash, typename Pred>
+struct NodeCache<Key, Hash, Pred>::Entry {
+  Key key_;
+  Node* value_;
+};
 
 
-template <>
-inline int32_t NodeCacheHash(double key) {
-  return ComputeLongHash(bit_cast<int64_t>(key));
-}
-
-
-template <>
-inline int32_t NodeCacheHash(void* key) {
-  return ComputePointerHash(key);
-}
-
-
-template <typename Key>
-bool NodeCache<Key>::Resize(Zone* zone) {
+template <typename Key, typename Hash, typename Pred>
+bool NodeCache<Key, Hash, Pred>::Resize(Zone* zone) {
   if (size_ >= max_) return false;  // Don't grow past the maximum size.
 
   // Allocate a new block of entries 4x the size.
   Entry* old_entries = entries_;
-  int old_size = size_ + LINEAR_PROBE;
-  size_ = size_ * 4;
-  int num_entries = size_ + LINEAR_PROBE;
-  entries_ = zone->NewArray<Entry>(num_entries);
+  size_t old_size = size_ + kLinearProbe;
+  size_ *= 4;
+  size_t num_entries = size_ + kLinearProbe;
+  entries_ = zone->NewArray<Entry>(static_cast<int>(num_entries));
   memset(entries_, 0, sizeof(Entry) * num_entries);
 
   // Insert the old entries into the new block.
-  for (int i = 0; i < old_size; i++) {
+  for (size_t i = 0; i < old_size; ++i) {
     Entry* old = &old_entries[i];
-    if (old->value_ != NULL) {
-      int hash = NodeCacheHash(old->key_);
-      int start = hash & (size_ - 1);
-      int end = start + LINEAR_PROBE;
-      for (int j = start; j < end; j++) {
+    if (old->value_) {
+      size_t hash = hash_(old->key_);
+      size_t start = hash & (size_ - 1);
+      size_t end = start + kLinearProbe;
+      for (size_t j = start; j < end; ++j) {
         Entry* entry = &entries_[j];
-        if (entry->value_ == NULL) {
+        if (!entry->value_) {
           entry->key_ = old->key_;
           entry->value_ = old->value_;
           break;
@@ -74,28 +60,28 @@
 }
 
 
-template <typename Key>
-Node** NodeCache<Key>::Find(Zone* zone, Key key) {
-  int32_t hash = NodeCacheHash(key);
-  if (entries_ == NULL) {
+template <typename Key, typename Hash, typename Pred>
+Node** NodeCache<Key, Hash, Pred>::Find(Zone* zone, Key key) {
+  size_t hash = hash_(key);
+  if (!entries_) {
     // Allocate the initial entries and insert the first entry.
-    int num_entries = INITIAL_SIZE + LINEAR_PROBE;
-    entries_ = zone->NewArray<Entry>(num_entries);
-    size_ = INITIAL_SIZE;
+    size_t num_entries = kInitialSize + kLinearProbe;
+    entries_ = zone->NewArray<Entry>(static_cast<int>(num_entries));
+    size_ = kInitialSize;
     memset(entries_, 0, sizeof(Entry) * num_entries);
-    Entry* entry = &entries_[hash & (INITIAL_SIZE - 1)];
+    Entry* entry = &entries_[hash & (kInitialSize - 1)];
     entry->key_ = key;
     return &entry->value_;
   }
 
-  while (true) {
+  for (;;) {
     // Search up to N entries after (linear probing).
-    int start = hash & (size_ - 1);
-    int end = start + LINEAR_PROBE;
-    for (int i = start; i < end; i++) {
+    size_t start = hash & (size_ - 1);
+    size_t end = start + kLinearProbe;
+    for (size_t i = start; i < end; i++) {
       Entry* entry = &entries_[i];
-      if (entry->key_ == key) return &entry->value_;
-      if (entry->value_ == NULL) {
+      if (pred_(entry->key_, key)) return &entry->value_;
+      if (!entry->value_) {
         entry->key_ = key;
         return &entry->value_;
       }
@@ -107,14 +93,28 @@
   // If resized to maximum and still didn't find space, overwrite an entry.
   Entry* entry = &entries_[hash & (size_ - 1)];
   entry->key_ = key;
-  entry->value_ = NULL;
+  entry->value_ = nullptr;
   return &entry->value_;
 }
 
 
-template class NodeCache<int64_t>;
+template <typename Key, typename Hash, typename Pred>
+void NodeCache<Key, Hash, Pred>::GetCachedNodes(ZoneVector<Node*>* nodes) {
+  if (entries_) {
+    for (size_t i = 0; i < size_ + kLinearProbe; i++) {
+      if (entries_[i].value_) nodes->push_back(entries_[i].value_);
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Instantiations
+
+
 template class NodeCache<int32_t>;
-template class NodeCache<void*>;
-}
-}
-}  // namespace v8::internal::compiler
+template class NodeCache<int64_t>;
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/node-cache.h b/src/compiler/node-cache.h
index 35352ea..b123922 100644
--- a/src/compiler/node-cache.h
+++ b/src/compiler/node-cache.h
@@ -5,20 +5,33 @@
 #ifndef V8_COMPILER_NODE_CACHE_H_
 #define V8_COMPILER_NODE_CACHE_H_
 
-#include "src/v8.h"
-
-#include "src/compiler/node.h"
+#include "src/base/functional.h"
+#include "src/base/macros.h"
 
 namespace v8 {
 namespace internal {
+
+// Forward declarations.
+class Zone;
+template <typename>
+class ZoneVector;
+
+
 namespace compiler {
 
+// Forward declarations.
+class Node;
+
+
 // A cache for nodes based on a key. Useful for implementing canonicalization of
 // nodes such as constants, parameters, etc.
-template <typename Key>
-class NodeCache {
+template <typename Key, typename Hash = base::hash<Key>,
+          typename Pred = std::equal_to<Key> >
+class NodeCache FINAL {
  public:
-  explicit NodeCache(int max = 256) : entries_(NULL), size_(0), max_(max) {}
+  explicit NodeCache(unsigned max = 256)
+      : entries_(nullptr), size_(0), max_(max) {}
+  ~NodeCache() {}
 
   // Search for node associated with {key} and return a pointer to a memory
   // location in this cache that stores an entry for the key. If the location
@@ -29,25 +42,34 @@
   // too full or encounters too many hash collisions.
   Node** Find(Zone* zone, Key key);
 
+  // Appends all nodes from this cache to {nodes}.
+  void GetCachedNodes(ZoneVector<Node*>* nodes);
+
  private:
-  struct Entry {
-    Key key_;
-    Node* value_;
-  };
+  struct Entry;
 
   Entry* entries_;  // lazily-allocated hash entries.
-  int32_t size_;
-  int32_t max_;
+  size_t size_;
+  size_t max_;
+  Hash hash_;
+  Pred pred_;
 
   bool Resize(Zone* zone);
+
+  DISALLOW_COPY_AND_ASSIGN(NodeCache);
 };
 
 // Various default cache types.
-typedef NodeCache<int64_t> Int64NodeCache;
 typedef NodeCache<int32_t> Int32NodeCache;
-typedef NodeCache<void*> PtrNodeCache;
-}
-}
-}  // namespace v8::internal::compiler
+typedef NodeCache<int64_t> Int64NodeCache;
+#if V8_HOST_ARCH_32_BIT
+typedef Int32NodeCache IntPtrNodeCache;
+#else
+typedef Int64NodeCache IntPtrNodeCache;
+#endif
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_NODE_CACHE_H_
diff --git a/src/compiler/node-matchers.h b/src/compiler/node-matchers.h
index e62eaee..fc11a0a 100644
--- a/src/compiler/node-matchers.h
+++ b/src/compiler/node-matchers.h
@@ -5,8 +5,11 @@
 #ifndef V8_COMPILER_NODE_MATCHERS_H_
 #define V8_COMPILER_NODE_MATCHERS_H_
 
+#include <cmath>
+
 #include "src/compiler/node.h"
 #include "src/compiler/operator.h"
+#include "src/unique.h"
 
 namespace v8 {
 namespace internal {
@@ -38,6 +41,8 @@
 // A pattern matcher for abitrary value constants.
 template <typename T, IrOpcode::Value kOpcode>
 struct ValueMatcher : public NodeMatcher {
+  typedef T ValueType;
+
   explicit ValueMatcher(Node* node)
       : NodeMatcher(node), value_(), has_value_(opcode() == kOpcode) {
     if (has_value_) {
@@ -65,21 +70,62 @@
 };
 
 
+template <>
+inline ValueMatcher<int64_t, IrOpcode::kInt64Constant>::ValueMatcher(Node* node)
+    : NodeMatcher(node), value_(), has_value_(false) {
+  if (opcode() == IrOpcode::kInt32Constant) {
+    value_ = OpParameter<int32_t>(node);
+    has_value_ = true;
+  } else if (opcode() == IrOpcode::kInt64Constant) {
+    value_ = OpParameter<int64_t>(node);
+    has_value_ = true;
+  }
+}
+
+
+template <>
+inline ValueMatcher<uint64_t, IrOpcode::kInt64Constant>::ValueMatcher(
+    Node* node)
+    : NodeMatcher(node), value_(), has_value_(false) {
+  if (opcode() == IrOpcode::kInt32Constant) {
+    value_ = OpParameter<uint32_t>(node);
+    has_value_ = true;
+  } else if (opcode() == IrOpcode::kInt64Constant) {
+    value_ = OpParameter<uint64_t>(node);
+    has_value_ = true;
+  }
+}
+
+
 // A pattern matcher for integer constants.
 template <typename T, IrOpcode::Value kOpcode>
 struct IntMatcher FINAL : public ValueMatcher<T, kOpcode> {
   explicit IntMatcher(Node* node) : ValueMatcher<T, kOpcode>(node) {}
 
+  bool IsMultipleOf(T n) const {
+    return this->HasValue() && (this->Value() % n) == 0;
+  }
   bool IsPowerOf2() const {
     return this->HasValue() && this->Value() > 0 &&
            (this->Value() & (this->Value() - 1)) == 0;
   }
+  bool IsNegativePowerOf2() const {
+    return this->HasValue() && this->Value() < 0 &&
+           (-this->Value() & (-this->Value() - 1)) == 0;
+  }
 };
 
 typedef IntMatcher<int32_t, IrOpcode::kInt32Constant> Int32Matcher;
 typedef IntMatcher<uint32_t, IrOpcode::kInt32Constant> Uint32Matcher;
 typedef IntMatcher<int64_t, IrOpcode::kInt64Constant> Int64Matcher;
 typedef IntMatcher<uint64_t, IrOpcode::kInt64Constant> Uint64Matcher;
+#if V8_HOST_ARCH_32_BIT
+typedef Int32Matcher IntPtrMatcher;
+typedef Uint32Matcher UintPtrMatcher;
+#else
+typedef Int64Matcher IntPtrMatcher;
+typedef Uint64Matcher UintPtrMatcher;
+#endif
 
 
 // A pattern matcher for floating point constants.
@@ -87,6 +133,9 @@
 struct FloatMatcher FINAL : public ValueMatcher<T, kOpcode> {
   explicit FloatMatcher(Node* node) : ValueMatcher<T, kOpcode>(node) {}
 
+  bool IsMinusZero() const {
+    return this->Is(0.0) && std::signbit(this->Value());
+  }
   bool IsNaN() const { return this->HasValue() && std::isnan(this->Value()); }
 };
 
@@ -108,11 +157,18 @@
 // right hand sides of a binary operation and can put constants on the right
 // if they appear on the left hand side of a commutative operation.
 template <typename Left, typename Right>
-struct BinopMatcher FINAL : public NodeMatcher {
+struct BinopMatcher : public NodeMatcher {
   explicit BinopMatcher(Node* node)
       : NodeMatcher(node), left_(InputAt(0)), right_(InputAt(1)) {
     if (HasProperty(Operator::kCommutative)) PutConstantOnRight();
   }
+  BinopMatcher(Node* node, bool allow_input_swap)
+      : NodeMatcher(node), left_(InputAt(0)), right_(InputAt(1)) {
+    if (allow_input_swap) PutConstantOnRight();
+  }
+
+  typedef Left LeftMatcher;
+  typedef Right RightMatcher;
 
   const Left& left() const { return left_; }
   const Right& right() const { return right_; }
@@ -120,12 +176,17 @@
   bool IsFoldable() const { return left().HasValue() && right().HasValue(); }
   bool LeftEqualsRight() const { return left().node() == right().node(); }
 
+ protected:
+  void SwapInputs() {
+    std::swap(left_, right_);
+    node()->ReplaceInput(0, left().node());
+    node()->ReplaceInput(1, right().node());
+  }
+
  private:
   void PutConstantOnRight() {
     if (left().HasValue() && !right().HasValue()) {
-      std::swap(left_, right_);
-      node()->ReplaceInput(0, left().node());
-      node()->ReplaceInput(1, right().node());
+      SwapInputs();
     }
   }
 
@@ -137,7 +198,318 @@
 typedef BinopMatcher<Uint32Matcher, Uint32Matcher> Uint32BinopMatcher;
 typedef BinopMatcher<Int64Matcher, Int64Matcher> Int64BinopMatcher;
 typedef BinopMatcher<Uint64Matcher, Uint64Matcher> Uint64BinopMatcher;
+typedef BinopMatcher<IntPtrMatcher, IntPtrMatcher> IntPtrBinopMatcher;
+typedef BinopMatcher<UintPtrMatcher, UintPtrMatcher> UintPtrBinopMatcher;
 typedef BinopMatcher<Float64Matcher, Float64Matcher> Float64BinopMatcher;
+typedef BinopMatcher<NumberMatcher, NumberMatcher> NumberBinopMatcher;
+
+
+template <class BinopMatcher, IrOpcode::Value kMulOpcode,
+          IrOpcode::Value kShiftOpcode>
+struct ScaleMatcher {
+  explicit ScaleMatcher(Node* node, bool allow_power_of_two_plus_one = false)
+      : scale_(-1), power_of_two_plus_one_(false) {
+    if (node->InputCount() < 2) return;
+    BinopMatcher m(node);
+    if (node->opcode() == kShiftOpcode) {
+      if (m.right().HasValue()) {
+        typename BinopMatcher::RightMatcher::ValueType value =
+            m.right().Value();
+        if (value >= 0 && value <= 3) {
+          scale_ = static_cast<int>(value);
+        }
+      }
+    } else if (node->opcode() == kMulOpcode) {
+      if (m.right().HasValue()) {
+        typename BinopMatcher::RightMatcher::ValueType value =
+            m.right().Value();
+        if (value == 1) {
+          scale_ = 0;
+        } else if (value == 2) {
+          scale_ = 1;
+        } else if (value == 4) {
+          scale_ = 2;
+        } else if (value == 8) {
+          scale_ = 3;
+        } else if (allow_power_of_two_plus_one) {
+          if (value == 3) {
+            scale_ = 1;
+            power_of_two_plus_one_ = true;
+          } else if (value == 5) {
+            scale_ = 2;
+            power_of_two_plus_one_ = true;
+          } else if (value == 9) {
+            scale_ = 3;
+            power_of_two_plus_one_ = true;
+          }
+        }
+      }
+    }
+  }
+
+  bool matches() const { return scale_ != -1; }
+  int scale() const { return scale_; }
+  bool power_of_two_plus_one() const { return power_of_two_plus_one_; }
+
+ private:
+  int scale_;
+  bool power_of_two_plus_one_;
+};
+
+typedef ScaleMatcher<Int32BinopMatcher, IrOpcode::kInt32Mul,
+                     IrOpcode::kWord32Shl> Int32ScaleMatcher;
+typedef ScaleMatcher<Int64BinopMatcher, IrOpcode::kInt64Mul,
+                     IrOpcode::kWord64Shl> Int64ScaleMatcher;
+
+
+template <class BinopMatcher, IrOpcode::Value kAddOpcode,
+          IrOpcode::Value kMulOpcode, IrOpcode::Value kShiftOpcode>
+struct AddMatcher : public BinopMatcher {
+  static const IrOpcode::Value kOpcode = kAddOpcode;
+  typedef ScaleMatcher<BinopMatcher, kMulOpcode, kShiftOpcode> Matcher;
+
+  AddMatcher(Node* node, bool allow_input_swap)
+      : BinopMatcher(node, allow_input_swap),
+        scale_(-1),
+        power_of_two_plus_one_(false) {
+    Initialize(node, allow_input_swap);
+  }
+  explicit AddMatcher(Node* node)
+      : BinopMatcher(node, node->op()->HasProperty(Operator::kCommutative)),
+        scale_(-1),
+        power_of_two_plus_one_(false) {
+    Initialize(node, node->op()->HasProperty(Operator::kCommutative));
+  }
+
+  bool HasIndexInput() const { return scale_ != -1; }
+  Node* IndexInput() const {
+    DCHECK(HasIndexInput());
+    return this->left().node()->InputAt(0);
+  }
+  int scale() const {
+    DCHECK(HasIndexInput());
+    return scale_;
+  }
+  bool power_of_two_plus_one() const { return power_of_two_plus_one_; }
+
+ private:
+  void Initialize(Node* node, bool allow_input_swap) {
+    Matcher left_matcher(this->left().node(), true);
+    if (left_matcher.matches()) {
+      scale_ = left_matcher.scale();
+      power_of_two_plus_one_ = left_matcher.power_of_two_plus_one();
+      return;
+    }
+
+    if (!allow_input_swap) {
+      return;
+    }
+
+    Matcher right_matcher(this->right().node(), true);
+    if (right_matcher.matches()) {
+      scale_ = right_matcher.scale();
+      power_of_two_plus_one_ = right_matcher.power_of_two_plus_one();
+      this->SwapInputs();
+      return;
+    }
+
+    if (this->right().opcode() == kAddOpcode &&
+        this->left().opcode() != kAddOpcode) {
+      this->SwapInputs();
+    }
+  }
+
+  int scale_;
+  bool power_of_two_plus_one_;
+};
+
+typedef AddMatcher<Int32BinopMatcher, IrOpcode::kInt32Add, IrOpcode::kInt32Mul,
+                   IrOpcode::kWord32Shl> Int32AddMatcher;
+typedef AddMatcher<Int64BinopMatcher, IrOpcode::kInt64Add, IrOpcode::kInt64Mul,
+                   IrOpcode::kWord64Shl> Int64AddMatcher;
+
+
+template <class AddMatcher>
+struct BaseWithIndexAndDisplacementMatcher {
+  BaseWithIndexAndDisplacementMatcher(Node* node, bool allow_input_swap)
+      : matches_(false),
+        index_(NULL),
+        scale_(0),
+        base_(NULL),
+        displacement_(NULL) {
+    Initialize(node, allow_input_swap);
+  }
+
+  explicit BaseWithIndexAndDisplacementMatcher(Node* node)
+      : matches_(false),
+        index_(NULL),
+        scale_(0),
+        base_(NULL),
+        displacement_(NULL) {
+    Initialize(node, node->op()->HasProperty(Operator::kCommutative));
+  }
+
+  bool matches() const { return matches_; }
+  Node* index() const { return index_; }
+  int scale() const { return scale_; }
+  Node* base() const { return base_; }
+  Node* displacement() const { return displacement_; }
+
+ private:
+  bool matches_;
+  Node* index_;
+  int scale_;
+  Node* base_;
+  Node* displacement_;
+
+  void Initialize(Node* node, bool allow_input_swap) {
+    // The BaseWithIndexAndDisplacementMatcher canonicalizes the order of
+    // displacements and scale factors that are used as inputs, so instead of
+    // enumerating all possible patterns by brute force, checking for node
+    // clusters using the following templates in the following order suffices to
+    // find all of the interesting cases (S = index * scale, B = base input, D =
+    // displacement input):
+    // (S + (B + D))
+    // (S + (B + B))
+    // (S + D)
+    // (S + B)
+    // ((S + D) + B)
+    // ((S + B) + D)
+    // ((B + D) + B)
+    // ((B + B) + D)
+    // (B + D)
+    // (B + B)
+    if (node->InputCount() < 2) return;
+    AddMatcher m(node, allow_input_swap);
+    Node* left = m.left().node();
+    Node* right = m.right().node();
+    Node* displacement = NULL;
+    Node* base = NULL;
+    Node* index = NULL;
+    Node* scale_expression = NULL;
+    bool power_of_two_plus_one = false;
+    int scale = 0;
+    if (m.HasIndexInput() && left->OwnedBy(node)) {
+      index = m.IndexInput();
+      scale = m.scale();
+      scale_expression = left;
+      power_of_two_plus_one = m.power_of_two_plus_one();
+      if (right->opcode() == AddMatcher::kOpcode && right->OwnedBy(node)) {
+        AddMatcher right_matcher(right);
+        if (right_matcher.right().HasValue()) {
+          // (S + (B + D))
+          base = right_matcher.left().node();
+          displacement = right_matcher.right().node();
+        } else {
+          // (S + (B + B))
+          base = right;
+        }
+      } else if (m.right().HasValue()) {
+        // (S + D)
+        displacement = right;
+      } else {
+        // (S + B)
+        base = right;
+      }
+    } else {
+      if (left->opcode() == AddMatcher::kOpcode && left->OwnedBy(node)) {
+        AddMatcher left_matcher(left);
+        Node* left_left = left_matcher.left().node();
+        Node* left_right = left_matcher.right().node();
+        if (left_matcher.HasIndexInput() && left_left->OwnedBy(left)) {
+          if (left_matcher.right().HasValue()) {
+            // ((S + D) + B)
+            index = left_matcher.IndexInput();
+            scale = left_matcher.scale();
+            scale_expression = left_left;
+            power_of_two_plus_one = left_matcher.power_of_two_plus_one();
+            displacement = left_right;
+            base = right;
+          } else if (m.right().HasValue()) {
+            // ((S + B) + D)
+            index = left_matcher.IndexInput();
+            scale = left_matcher.scale();
+            scale_expression = left_left;
+            power_of_two_plus_one = left_matcher.power_of_two_plus_one();
+            base = left_right;
+            displacement = right;
+          } else {
+            // (B + B)
+            index = left;
+            base = right;
+          }
+        } else {
+          if (left_matcher.right().HasValue()) {
+            // ((B + D) + B)
+            index = left_left;
+            displacement = left_right;
+            base = right;
+          } else if (m.right().HasValue()) {
+            // ((B + B) + D)
+            index = left_left;
+            base = left_right;
+            displacement = right;
+          } else {
+            // (B + B)
+            index = left;
+            base = right;
+          }
+        }
+      } else {
+        if (m.right().HasValue()) {
+          // (B + D)
+          base = left;
+          displacement = right;
+        } else {
+          // (B + B)
+          base = left;
+          index = right;
+        }
+      }
+    }
+    int64_t value = 0;
+    if (displacement != NULL) {
+      switch (displacement->opcode()) {
+        case IrOpcode::kInt32Constant: {
+          value = OpParameter<int32_t>(displacement);
+          break;
+        }
+        case IrOpcode::kInt64Constant: {
+          value = OpParameter<int64_t>(displacement);
+          break;
+        }
+        default:
+          UNREACHABLE();
+          break;
+      }
+      if (value == 0) {
+        displacement = NULL;
+      }
+    }
+    if (power_of_two_plus_one) {
+      if (base != NULL) {
+        // If the scale requires explicitly using the index as the base, but a
+        // base is already part of the match, then the (1 << N + 1) scale factor
+        // can't be folded into the match and the entire index * scale
+        // calculation must be computed separately.
+        index = scale_expression;
+        scale = 0;
+      } else {
+        base = index;
+      }
+    }
+    base_ = base;
+    displacement_ = displacement;
+    index_ = index;
+    scale_ = scale;
+    matches_ = true;
+  }
+};
+
+typedef BaseWithIndexAndDisplacementMatcher<Int32AddMatcher>
+    BaseWithIndexAndDisplacement32Matcher;
+typedef BaseWithIndexAndDisplacementMatcher<Int64AddMatcher>
+    BaseWithIndexAndDisplacement64Matcher;
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/node-properties-inl.h b/src/compiler/node-properties-inl.h
index 3f6d531..0d29614 100644
--- a/src/compiler/node-properties-inl.h
+++ b/src/compiler/node-properties-inl.h
@@ -8,11 +8,9 @@
 #include "src/v8.h"
 
 #include "src/compiler/common-operator.h"
-#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/node-properties.h"
 #include "src/compiler/opcodes.h"
 #include "src/compiler/operator.h"
-#include "src/compiler/operator-properties-inl.h"
 #include "src/compiler/operator-properties.h"
 
 namespace v8 {
@@ -44,8 +42,7 @@
 
 
 inline int NodeProperties::PastValueIndex(Node* node) {
-  return FirstValueIndex(node) +
-         OperatorProperties::GetValueInputCount(node->op());
+  return FirstValueIndex(node) + node->op()->ValueInputCount();
 }
 
 inline int NodeProperties::PastContextIndex(Node* node) {
@@ -59,13 +56,11 @@
 }
 
 inline int NodeProperties::PastEffectIndex(Node* node) {
-  return FirstEffectIndex(node) +
-         OperatorProperties::GetEffectInputCount(node->op());
+  return FirstEffectIndex(node) + node->op()->EffectInputCount();
 }
 
 inline int NodeProperties::PastControlIndex(Node* node) {
-  return FirstControlIndex(node) +
-         OperatorProperties::GetControlInputCount(node->op());
+  return FirstControlIndex(node) + node->op()->ControlInputCount();
 }
 
 
@@ -73,8 +68,7 @@
 // Input accessors.
 
 inline Node* NodeProperties::GetValueInput(Node* node, int index) {
-  DCHECK(0 <= index &&
-         index < OperatorProperties::GetValueInputCount(node->op()));
+  DCHECK(0 <= index && index < node->op()->ValueInputCount());
   return node->InputAt(FirstValueIndex(node) + index);
 }
 
@@ -89,14 +83,12 @@
 }
 
 inline Node* NodeProperties::GetEffectInput(Node* node, int index) {
-  DCHECK(0 <= index &&
-         index < OperatorProperties::GetEffectInputCount(node->op()));
+  DCHECK(0 <= index && index < node->op()->EffectInputCount());
   return node->InputAt(FirstEffectIndex(node) + index);
 }
 
 inline Node* NodeProperties::GetControlInput(Node* node, int index) {
-  DCHECK(0 <= index &&
-         index < OperatorProperties::GetControlInputCount(node->op()));
+  DCHECK(0 <= index && index < node->op()->ControlInputCount());
   return node->InputAt(FirstControlIndex(node) + index);
 }
 
@@ -108,7 +100,7 @@
 // -----------------------------------------------------------------------------
 // Edge kinds.
 
-inline bool NodeProperties::IsInputRange(Node::Edge edge, int first, int num) {
+inline bool NodeProperties::IsInputRange(Edge edge, int first, int num) {
   // TODO(titzer): edge.index() is linear time;
   // edges maybe need to be marked as value/effect/control.
   if (num == 0) return false;
@@ -116,28 +108,28 @@
   return first <= index && index < first + num;
 }
 
-inline bool NodeProperties::IsValueEdge(Node::Edge edge) {
+inline bool NodeProperties::IsValueEdge(Edge edge) {
   Node* node = edge.from();
   return IsInputRange(edge, FirstValueIndex(node),
-                      OperatorProperties::GetValueInputCount(node->op()));
+                      node->op()->ValueInputCount());
 }
 
-inline bool NodeProperties::IsContextEdge(Node::Edge edge) {
+inline bool NodeProperties::IsContextEdge(Edge edge) {
   Node* node = edge.from();
   return IsInputRange(edge, FirstContextIndex(node),
                       OperatorProperties::GetContextInputCount(node->op()));
 }
 
-inline bool NodeProperties::IsEffectEdge(Node::Edge edge) {
+inline bool NodeProperties::IsEffectEdge(Edge edge) {
   Node* node = edge.from();
   return IsInputRange(edge, FirstEffectIndex(node),
-                      OperatorProperties::GetEffectInputCount(node->op()));
+                      node->op()->EffectInputCount());
 }
 
-inline bool NodeProperties::IsControlEdge(Node::Edge edge) {
+inline bool NodeProperties::IsControlEdge(Edge edge) {
   Node* node = edge.from();
   return IsInputRange(edge, FirstControlIndex(node),
-                      OperatorProperties::GetControlInputCount(node->op()));
+                      node->op()->ControlInputCount());
 }
 
 
@@ -158,7 +150,7 @@
 
 inline void NodeProperties::ReplaceEffectInput(Node* node, Node* effect,
                                                int index) {
-  DCHECK(index < OperatorProperties::GetEffectInputCount(node->op()));
+  DCHECK(index < node->op()->EffectInputCount());
   return node->ReplaceInput(FirstEffectIndex(node) + index, effect);
 }
 
@@ -169,7 +161,7 @@
 }
 
 inline void NodeProperties::RemoveNonValueInputs(Node* node) {
-  node->TrimInputCount(OperatorProperties::GetValueInputCount(node->op()));
+  node->TrimInputCount(node->op()->ValueInputCount());
 }
 
 
@@ -177,19 +169,18 @@
 // {effect}. If {effect == NULL}, then use the effect input to {node}.
 inline void NodeProperties::ReplaceWithValue(Node* node, Node* value,
                                              Node* effect) {
-  DCHECK(!OperatorProperties::HasControlOutput(node->op()));
-  if (effect == NULL && OperatorProperties::HasEffectInput(node->op())) {
+  DCHECK(node->op()->ControlOutputCount() == 0);
+  if (effect == NULL && node->op()->EffectInputCount() > 0) {
     effect = NodeProperties::GetEffectInput(node);
   }
 
   // Requires distinguishing between value and effect edges.
-  UseIter iter = node->uses().begin();
-  while (iter != node->uses().end()) {
-    if (NodeProperties::IsEffectEdge(iter.edge())) {
+  for (Edge edge : node->use_edges()) {
+    if (NodeProperties::IsEffectEdge(edge)) {
       DCHECK_NE(NULL, effect);
-      iter = iter.UpdateToAndIncrement(effect);
+      edge.UpdateTo(effect);
     } else {
-      iter = iter.UpdateToAndIncrement(value);
+      edge.UpdateTo(value);
     }
   }
 }
@@ -198,12 +189,35 @@
 // -----------------------------------------------------------------------------
 // Type Bounds.
 
-inline Bounds NodeProperties::GetBounds(Node* node) { return node->bounds(); }
+inline bool NodeProperties::IsTyped(Node* node) {
+  Bounds bounds = node->bounds();
+  DCHECK((bounds.lower == NULL) == (bounds.upper == NULL));
+  return bounds.upper != NULL;
+}
+
+inline Bounds NodeProperties::GetBounds(Node* node) {
+  DCHECK(IsTyped(node));
+  return node->bounds();
+}
+
+inline void NodeProperties::RemoveBounds(Node* node) {
+  Bounds empty;
+  node->set_bounds(empty);
+}
 
 inline void NodeProperties::SetBounds(Node* node, Bounds b) {
+  DCHECK(b.lower != NULL && b.upper != NULL);
   node->set_bounds(b);
 }
 
+inline bool NodeProperties::AllValueInputsAreTyped(Node* node) {
+  int input_count = node->op()->ValueInputCount();
+  for (int i = 0; i < input_count; ++i) {
+    if (!IsTyped(GetValueInput(node, i))) return false;
+  }
+  return true;
+}
+
 
 }
 }
diff --git a/src/compiler/node-properties.h b/src/compiler/node-properties.h
index 94bd731..025be78 100644
--- a/src/compiler/node-properties.h
+++ b/src/compiler/node-properties.h
@@ -25,10 +25,10 @@
 
   static inline int GetFrameStateIndex(Node* node);
 
-  static inline bool IsValueEdge(Node::Edge edge);
-  static inline bool IsContextEdge(Node::Edge edge);
-  static inline bool IsEffectEdge(Node::Edge edge);
-  static inline bool IsControlEdge(Node::Edge edge);
+  static inline bool IsValueEdge(Edge edge);
+  static inline bool IsContextEdge(Edge edge);
+  static inline bool IsEffectEdge(Edge edge);
+  static inline bool IsControlEdge(Edge edge);
 
   static inline bool IsControl(Node* node);
 
@@ -40,8 +40,11 @@
   static inline void ReplaceWithValue(Node* node, Node* value,
                                       Node* effect = NULL);
 
+  static inline bool IsTyped(Node* node);
   static inline Bounds GetBounds(Node* node);
   static inline void SetBounds(Node* node, Bounds bounds);
+  static inline void RemoveBounds(Node* node);
+  static inline bool AllValueInputsAreTyped(Node* node);
 
   static inline int FirstValueIndex(Node* node);
   static inline int FirstContextIndex(Node* node);
@@ -54,7 +57,7 @@
   static inline int PastEffectIndex(Node* node);
   static inline int PastControlIndex(Node* node);
 
-  static inline bool IsInputRange(Node::Edge edge, int first, int count);
+  static inline bool IsInputRange(Edge edge, int first, int count);
 };
 
 }  // namespace compiler
diff --git a/src/compiler/node.cc b/src/compiler/node.cc
index 7df736e..8f44c24 100644
--- a/src/compiler/node.cc
+++ b/src/compiler/node.cc
@@ -4,12 +4,54 @@
 
 #include "src/compiler/node.h"
 
-#include "src/compiler/generic-node-inl.h"
+#include "src/compiler/graph.h"
+#include "src/zone.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+Node::Node(NodeId id, int input_count, int reserved_input_count)
+    : id_(id),
+      bit_field_(InputCountField::encode(input_count) |
+                 ReservedInputCountField::encode(reserved_input_count) |
+                 HasAppendableInputsField::encode(false)),
+      first_use_(nullptr),
+      last_use_(nullptr) {
+  inputs_.static_ = reinterpret_cast<Input*>(this + 1);
+}
+
+
+Node* Node::New(Graph* graph, int input_count, Node** inputs,
+                bool has_extensible_inputs) {
+  size_t node_size = sizeof(Node);
+  int reserve_input_count = has_extensible_inputs ? kDefaultReservedInputs : 0;
+  size_t inputs_size = (input_count + reserve_input_count) * sizeof(Input);
+  size_t uses_size = input_count * sizeof(Use);
+  int size = static_cast<int>(node_size + inputs_size + uses_size);
+  Zone* zone = graph->zone();
+  void* buffer = zone->New(size);
+  Node* result =
+      new (buffer) Node(graph->NextNodeID(), input_count, reserve_input_count);
+  Input* input =
+      reinterpret_cast<Input*>(reinterpret_cast<char*>(buffer) + node_size);
+  Use* use =
+      reinterpret_cast<Use*>(reinterpret_cast<char*>(input) + inputs_size);
+
+  for (int current = 0; current < input_count; ++current) {
+    Node* to = *inputs++;
+    input->to = to;
+    input->use = use;
+    use->input_index = current;
+    use->from = result;
+    to->AppendUse(use);
+    ++use;
+    ++input;
+  }
+  return result;
+}
+
+
 void Node::Kill() {
   DCHECK_NOT_NULL(op());
   RemoveAllInputs();
@@ -42,14 +84,31 @@
 }
 
 
-OStream& operator<<(OStream& os, const Operator& op) { return op.PrintTo(os); }
+int Node::UseCount() const {
+  int use_count = 0;
+  for (const Use* use = first_use_; use; use = use->next) {
+    ++use_count;
+  }
+  return use_count;
+}
 
 
-OStream& operator<<(OStream& os, const Node& n) {
+Node* Node::UseAt(int index) const {
+  DCHECK_LE(0, index);
+  DCHECK_LT(index, UseCount());
+  Use* current = first_use_;
+  while (index-- != 0) {
+    current = current->next;
+  }
+  return current->from;
+}
+
+
+std::ostream& operator<<(std::ostream& os, const Node& n) {
   os << n.id() << ": " << *n.op();
-  if (n.op()->InputCount() != 0) {
+  if (n.InputCount() > 0) {
     os << "(";
-    for (int i = 0; i < n.op()->InputCount(); ++i) {
+    for (int i = 0; i < n.InputCount(); ++i) {
       if (i != 0) os << ", ";
       os << n.InputAt(i)->id();
     }
diff --git a/src/compiler/node.h b/src/compiler/node.h
index c3f5a53..2295b7b 100644
--- a/src/compiler/node.h
+++ b/src/compiler/node.h
@@ -9,20 +9,55 @@
 #include <set>
 #include <vector>
 
-#include "src/compiler/generic-algorithm.h"
-#include "src/compiler/generic-node.h"
+#include "src/v8.h"
+
 #include "src/compiler/opcodes.h"
 #include "src/compiler/operator.h"
 #include "src/types.h"
 #include "src/zone.h"
 #include "src/zone-allocator.h"
+#include "src/zone-containers.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-class NodeData {
+// Forward declarations.
+class Edge;
+class Graph;
+
+
+// Marks are used during traversal of the graph to distinguish states of nodes.
+// Each node has a mark which is a monotonically increasing integer, and a
+// {NodeMarker} has a range of values that indicate states of a node.
+typedef uint32_t Mark;
+
+// NodeIds are identifying numbers for nodes that can be used to index auxiliary
+// out-of-line data associated with each node.
+typedef int NodeId;
+
+// A Node is the basic primitive of graphs. Nodes are chained together by
+// input/use chains but by default otherwise contain only an identifying number
+// which specific applications of graphs and nodes can use to index auxiliary
+// out-of-line data, especially transient data.
+//
+// In addition Nodes only contain a mutable Operator that may change during
+// compilation, e.g. during lowering passes. Other information that needs to be
+// associated with Nodes during compilation must be stored out-of-line indexed
+// by the Node's id.
+class Node FINAL {
  public:
+  void Initialize(const Operator* op) {
+    set_op(op);
+    set_mark(0);
+  }
+
+  bool IsDead() const { return InputCount() > 0 && InputAt(0) == NULL; }
+  void Kill();
+
+  void CollectProjections(ZoneVector<Node*>* projections);
+  Node* FindProjection(size_t projection_index);
+
   const Operator* op() const { return op_; }
   void set_op(const Operator* op) { op_ = op; }
 
@@ -31,44 +66,387 @@
     return static_cast<IrOpcode::Value>(op_->opcode());
   }
 
-  Bounds bounds() { return bounds_; }
+  NodeId id() const { return id_; }
+
+  int InputCount() const { return input_count(); }
+  Node* InputAt(int index) const { return GetInputRecordPtr(index)->to; }
+  inline void ReplaceInput(int index, Node* new_input);
+  inline void AppendInput(Zone* zone, Node* new_input);
+  inline void InsertInput(Zone* zone, int index, Node* new_input);
+  inline void RemoveInput(int index);
+
+  int UseCount() const;
+  Node* UseAt(int index) const;
+  inline void ReplaceUses(Node* replace_to);
+  template <class UnaryPredicate>
+  inline void ReplaceUsesIf(UnaryPredicate pred, Node* replace_to);
+  inline void RemoveAllInputs();
+
+  inline void TrimInputCount(int input_count);
+
+  class InputEdges {
+   public:
+    class iterator;
+    iterator begin() const;
+    iterator end() const;
+    bool empty() const;
+
+    explicit InputEdges(Node* node) : node_(node) {}
+
+   private:
+    Node* node_;
+  };
+
+  class Inputs {
+   public:
+    class iterator;
+    iterator begin() const;
+    iterator end() const;
+    bool empty() const;
+
+    explicit Inputs(Node* node) : node_(node) {}
+
+   private:
+    Node* node_;
+  };
+
+  Inputs inputs() { return Inputs(this); }
+  InputEdges input_edges() { return InputEdges(this); }
+
+  class UseEdges {
+   public:
+    class iterator;
+    iterator begin() const;
+    iterator end() const;
+    bool empty() const;
+
+    explicit UseEdges(Node* node) : node_(node) {}
+
+   private:
+    Node* node_;
+  };
+
+  class Uses {
+   public:
+    class iterator;
+    iterator begin() const;
+    iterator end() const;
+    bool empty() const;
+
+    explicit Uses(Node* node) : node_(node) {}
+
+   private:
+    Node* node_;
+  };
+
+  Uses uses() { return Uses(this); }
+  UseEdges use_edges() { return UseEdges(this); }
+
+  bool OwnedBy(Node* owner) const;
+
+  static Node* New(Graph* graph, int input_count, Node** inputs,
+                   bool has_extensible_inputs);
 
  protected:
-  const Operator* op_;
-  Bounds bounds_;
-  explicit NodeData(Zone* zone) : bounds_(Bounds(Type::None(zone))) {}
+  friend class Graph;
+  friend class Edge;
+
+  class Use : public ZoneObject {
+   public:
+    Node* from;
+    Use* next;
+    Use* prev;
+    int input_index;
+  };
+
+  class Input {
+   public:
+    Node* to;
+    Use* use;
+
+    void Update(Node* new_to);
+  };
+
+  void EnsureAppendableInputs(Zone* zone);
+
+  Input* GetInputRecordPtr(int index) const {
+    if (has_appendable_inputs()) {
+      return &((*inputs_.appendable_)[index]);
+    } else {
+      return &inputs_.static_[index];
+    }
+  }
+
+  inline void AppendUse(Use* use);
+  inline void RemoveUse(Use* use);
+
+  void* operator new(size_t, void* location) { return location; }
+
+ private:
+  inline Node(NodeId id, int input_count, int reserve_input_count);
+
+  typedef ZoneDeque<Input> InputDeque;
 
   friend class NodeProperties;
+  template <typename State>
+  friend class NodeMarker;
+
+  // Only NodeProperties should manipulate the bounds.
+  Bounds bounds() { return bounds_; }
   void set_bounds(Bounds b) { bounds_ = b; }
+
+  // Only NodeMarkers should manipulate the marks on nodes.
+  Mark mark() { return mark_; }
+  void set_mark(Mark mark) { mark_ = mark; }
+
+  int input_count() const { return InputCountField::decode(bit_field_); }
+  void set_input_count(int input_count) {
+    DCHECK_LE(0, input_count);
+    bit_field_ = InputCountField::update(bit_field_, input_count);
+  }
+
+  int reserved_input_count() const {
+    return ReservedInputCountField::decode(bit_field_);
+  }
+  void set_reserved_input_count(int reserved_input_count) {
+    DCHECK_LE(0, reserved_input_count);
+    bit_field_ =
+        ReservedInputCountField::update(bit_field_, reserved_input_count);
+  }
+
+  bool has_appendable_inputs() const {
+    return HasAppendableInputsField::decode(bit_field_);
+  }
+  void set_has_appendable_inputs(bool has_appendable_inputs) {
+    bit_field_ =
+        HasAppendableInputsField::update(bit_field_, has_appendable_inputs);
+  }
+
+  typedef BitField<unsigned, 0, 29> InputCountField;
+  typedef BitField<unsigned, 29, 2> ReservedInputCountField;
+  typedef BitField<unsigned, 31, 1> HasAppendableInputsField;
+  static const int kDefaultReservedInputs = ReservedInputCountField::kMax;
+
+  const Operator* op_;
+  Bounds bounds_;
+  Mark mark_;
+  NodeId id_;
+  unsigned bit_field_;
+  union {
+    // When a node is initially allocated, it uses a static buffer to hold its
+    // inputs under the assumption that the number of outputs will not increase.
+    // When the first input is appended, the static buffer is converted into a
+    // deque to allow for space-efficient growing.
+    Input* static_;
+    InputDeque* appendable_;
+  } inputs_;
+  Use* first_use_;
+  Use* last_use_;
+
+  DISALLOW_COPY_AND_ASSIGN(Node);
 };
 
-// A Node is the basic primitive of an IR graph. In addition to the members
-// inherited from Vector, Nodes only contain a mutable Operator that may change
-// during compilation, e.g. during lowering passes.  Other information that
-// needs to be associated with Nodes during compilation must be stored
-// out-of-line indexed by the Node's id.
-class Node FINAL : public GenericNode<NodeData, Node> {
+
+// An encapsulation for information associated with a single use of node as a
+// input from another node, allowing access to both the defining node and
+// the node having the input.
+class Edge {
  public:
-  Node(GenericGraphBase* graph, int input_count)
-      : GenericNode<NodeData, Node>(graph, input_count) {}
+  Node* from() const { return input_->use->from; }
+  Node* to() const { return input_->to; }
+  int index() const {
+    int index = input_->use->input_index;
+    DCHECK(index < input_->use->from->input_count());
+    return index;
+  }
 
-  void Initialize(const Operator* op) { set_op(op); }
+  bool operator==(const Edge& other) { return input_ == other.input_; }
+  bool operator!=(const Edge& other) { return !(*this == other); }
 
-  bool IsDead() const { return InputCount() > 0 && InputAt(0) == NULL; }
-  void Kill();
+  void UpdateTo(Node* new_to) { input_->Update(new_to); }
 
-  void CollectProjections(ZoneVector<Node*>* projections);
-  Node* FindProjection(size_t projection_index);
+ private:
+  friend class Node::Uses::iterator;
+  friend class Node::Inputs::iterator;
+  friend class Node::UseEdges::iterator;
+  friend class Node::InputEdges::iterator;
+
+  explicit Edge(Node::Input* input) : input_(input) {}
+
+  Node::Input* input_;
 };
 
-OStream& operator<<(OStream& os, const Node& n);
 
-typedef GenericGraphVisit::NullNodeVisitor<NodeData, Node> NullNodeVisitor;
+// A forward iterator to visit the edges for the input dependencies of a node..
+class Node::InputEdges::iterator {
+ public:
+  typedef std::forward_iterator_tag iterator_category;
+  typedef int difference_type;
+  typedef Edge value_type;
+  typedef Edge* pointer;
+  typedef Edge& reference;
+  iterator(const Node::InputEdges::iterator& other)  // NOLINT
+      : input_(other.input_) {}
+  iterator() : input_(NULL) {}
+
+  Edge operator*() const { return Edge(input_); }
+  bool operator==(const iterator& other) const { return Equals(other); }
+  bool operator!=(const iterator& other) const { return !Equals(other); }
+  iterator& operator++() {
+    DCHECK(input_ != NULL);
+    Edge edge(input_);
+    Node* from = edge.from();
+    SetInput(from, input_->use->input_index + 1);
+    return *this;
+  }
+  iterator operator++(int) {
+    iterator result(*this);
+    ++(*this);
+    return result;
+  }
+
+ private:
+  friend class Node;
+
+  explicit iterator(Node* from, int index = 0) : input_(NULL) {
+    SetInput(from, index);
+  }
+
+  bool Equals(const iterator& other) const { return other.input_ == input_; }
+  void SetInput(Node* from, int index) {
+    DCHECK(index >= 0 && index <= from->InputCount());
+    if (index < from->InputCount()) {
+      input_ = from->GetInputRecordPtr(index);
+    } else {
+      input_ = NULL;
+    }
+  }
+
+  Input* input_;
+};
+
+
+// A forward iterator to visit the inputs of a node.
+class Node::Inputs::iterator {
+ public:
+  typedef std::forward_iterator_tag iterator_category;
+  typedef int difference_type;
+  typedef Node* value_type;
+  typedef Node** pointer;
+  typedef Node*& reference;
+
+  iterator(const Node::Inputs::iterator& other)  // NOLINT
+      : iter_(other.iter_) {}
+
+  Node* operator*() const { return (*iter_).to(); }
+  bool operator==(const iterator& other) const { return Equals(other); }
+  bool operator!=(const iterator& other) const { return !Equals(other); }
+  iterator& operator++() {
+    ++iter_;
+    return *this;
+  }
+  iterator operator++(int) {
+    iterator result(*this);
+    ++(*this);
+    return result;
+  }
+
+
+ private:
+  friend class Node::Inputs;
+
+  explicit iterator(Node* node, int index) : iter_(node, index) {}
+
+  bool Equals(const iterator& other) const { return other.iter_ == iter_; }
+
+  Node::InputEdges::iterator iter_;
+};
+
+// A forward iterator to visit the uses edges of a node. The edges are returned
+// in
+// the order in which they were added as inputs.
+class Node::UseEdges::iterator {
+ public:
+  iterator(const Node::UseEdges::iterator& other)  // NOLINT
+      : current_(other.current_),
+        next_(other.next_) {}
+
+  Edge operator*() const { return Edge(CurrentInput()); }
+
+  bool operator==(const iterator& other) { return Equals(other); }
+  bool operator!=(const iterator& other) { return !Equals(other); }
+  iterator& operator++() {
+    DCHECK(current_ != NULL);
+    current_ = next_;
+    next_ = (current_ == NULL) ? NULL : current_->next;
+    return *this;
+  }
+  iterator operator++(int) {
+    iterator result(*this);
+    ++(*this);
+    return result;
+  }
+
+ private:
+  friend class Node::UseEdges;
+
+  iterator() : current_(NULL), next_(NULL) {}
+  explicit iterator(Node* node)
+      : current_(node->first_use_),
+        next_(current_ == NULL ? NULL : current_->next) {}
+
+  bool Equals(const iterator& other) const {
+    return other.current_ == current_;
+  }
+
+  Input* CurrentInput() const {
+    return current_->from->GetInputRecordPtr(current_->input_index);
+  }
+
+  Node::Use* current_;
+  Node::Use* next_;
+};
+
+
+// A forward iterator to visit the uses of a node. The uses are returned in
+// the order in which they were added as inputs.
+class Node::Uses::iterator {
+ public:
+  iterator(const Node::Uses::iterator& other)  // NOLINT
+      : current_(other.current_) {}
+
+  Node* operator*() { return current_->from; }
+
+  bool operator==(const iterator& other) { return other.current_ == current_; }
+  bool operator!=(const iterator& other) { return other.current_ != current_; }
+  iterator& operator++() {
+    DCHECK(current_ != NULL);
+    current_ = current_->next;
+    return *this;
+  }
+
+ private:
+  friend class Node::Uses;
+
+  iterator() : current_(NULL) {}
+  explicit iterator(Node* node) : current_(node->first_use_) {}
+
+  Input* CurrentInput() const {
+    return current_->from->GetInputRecordPtr(current_->input_index);
+  }
+
+  Node::Use* current_;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const Node& n);
 
 typedef std::set<Node*, std::less<Node*>, zone_allocator<Node*> > NodeSet;
 typedef NodeSet::iterator NodeSetIter;
 typedef NodeSet::reverse_iterator NodeSetRIter;
 
+typedef ZoneDeque<Node*> NodeDeque;
+
 typedef ZoneVector<Node*> NodeVector;
 typedef NodeVector::iterator NodeVectorIter;
 typedef NodeVector::const_iterator NodeVectorConstIter;
@@ -87,6 +465,195 @@
   return OpParameter<T>(node->op());
 }
 
+inline Node::InputEdges::iterator Node::InputEdges::begin() const {
+  return Node::InputEdges::iterator(this->node_, 0);
+}
+
+inline Node::InputEdges::iterator Node::InputEdges::end() const {
+  return Node::InputEdges::iterator(this->node_, this->node_->InputCount());
+}
+
+inline Node::Inputs::iterator Node::Inputs::begin() const {
+  return Node::Inputs::iterator(this->node_, 0);
+}
+
+inline Node::Inputs::iterator Node::Inputs::end() const {
+  return Node::Inputs::iterator(this->node_, this->node_->InputCount());
+}
+
+inline Node::UseEdges::iterator Node::UseEdges::begin() const {
+  return Node::UseEdges::iterator(this->node_);
+}
+
+inline Node::UseEdges::iterator Node::UseEdges::end() const {
+  return Node::UseEdges::iterator();
+}
+
+inline Node::Uses::iterator Node::Uses::begin() const {
+  return Node::Uses::iterator(this->node_);
+}
+
+inline Node::Uses::iterator Node::Uses::end() const {
+  return Node::Uses::iterator();
+}
+
+inline bool Node::InputEdges::empty() const { return begin() == end(); }
+inline bool Node::Uses::empty() const { return begin() == end(); }
+inline bool Node::UseEdges::empty() const { return begin() == end(); }
+inline bool Node::Inputs::empty() const { return begin() == end(); }
+
+inline void Node::ReplaceUses(Node* replace_to) {
+  for (Use* use = first_use_; use != NULL; use = use->next) {
+    use->from->GetInputRecordPtr(use->input_index)->to = replace_to;
+  }
+  if (replace_to->last_use_ == NULL) {
+    DCHECK_EQ(NULL, replace_to->first_use_);
+    replace_to->first_use_ = first_use_;
+    replace_to->last_use_ = last_use_;
+  } else if (first_use_ != NULL) {
+    DCHECK_NE(NULL, replace_to->first_use_);
+    replace_to->last_use_->next = first_use_;
+    first_use_->prev = replace_to->last_use_;
+    replace_to->last_use_ = last_use_;
+  }
+  first_use_ = NULL;
+  last_use_ = NULL;
+}
+
+template <class UnaryPredicate>
+inline void Node::ReplaceUsesIf(UnaryPredicate pred, Node* replace_to) {
+  for (Use* use = first_use_; use != NULL;) {
+    Use* next = use->next;
+    if (pred(use->from)) {
+      RemoveUse(use);
+      replace_to->AppendUse(use);
+      use->from->GetInputRecordPtr(use->input_index)->to = replace_to;
+    }
+    use = next;
+  }
+}
+
+inline void Node::RemoveAllInputs() {
+  for (Edge edge : input_edges()) {
+    edge.UpdateTo(NULL);
+  }
+}
+
+inline void Node::TrimInputCount(int new_input_count) {
+  if (new_input_count == input_count()) return;  // Nothing to do.
+
+  DCHECK(new_input_count < input_count());
+
+  // Update inline inputs.
+  for (int i = new_input_count; i < input_count(); i++) {
+    Node::Input* input = GetInputRecordPtr(i);
+    input->Update(NULL);
+  }
+  set_input_count(new_input_count);
+}
+
+inline void Node::ReplaceInput(int index, Node* new_to) {
+  Input* input = GetInputRecordPtr(index);
+  input->Update(new_to);
+}
+
+inline void Node::Input::Update(Node* new_to) {
+  Node* old_to = this->to;
+  if (new_to == old_to) return;  // Nothing to do.
+  // Snip out the use from where it used to be
+  if (old_to != NULL) {
+    old_to->RemoveUse(use);
+  }
+  to = new_to;
+  // And put it into the new node's use list.
+  if (new_to != NULL) {
+    new_to->AppendUse(use);
+  } else {
+    use->next = NULL;
+    use->prev = NULL;
+  }
+}
+
+inline void Node::EnsureAppendableInputs(Zone* zone) {
+  if (!has_appendable_inputs()) {
+    void* deque_buffer = zone->New(sizeof(InputDeque));
+    InputDeque* deque = new (deque_buffer) InputDeque(zone);
+    for (int i = 0; i < input_count(); ++i) {
+      deque->push_back(inputs_.static_[i]);
+    }
+    inputs_.appendable_ = deque;
+    set_has_appendable_inputs(true);
+  }
+}
+
+inline void Node::AppendInput(Zone* zone, Node* to_append) {
+  Use* new_use = new (zone) Use;
+  Input new_input;
+  new_input.to = to_append;
+  new_input.use = new_use;
+  if (reserved_input_count() > 0) {
+    DCHECK(!has_appendable_inputs());
+    set_reserved_input_count(reserved_input_count() - 1);
+    inputs_.static_[input_count()] = new_input;
+  } else {
+    EnsureAppendableInputs(zone);
+    inputs_.appendable_->push_back(new_input);
+  }
+  new_use->input_index = input_count();
+  new_use->from = this;
+  to_append->AppendUse(new_use);
+  set_input_count(input_count() + 1);
+}
+
+inline void Node::InsertInput(Zone* zone, int index, Node* to_insert) {
+  DCHECK(index >= 0 && index < InputCount());
+  // TODO(turbofan): Optimize this implementation!
+  AppendInput(zone, InputAt(InputCount() - 1));
+  for (int i = InputCount() - 1; i > index; --i) {
+    ReplaceInput(i, InputAt(i - 1));
+  }
+  ReplaceInput(index, to_insert);
+}
+
+inline void Node::RemoveInput(int index) {
+  DCHECK(index >= 0 && index < InputCount());
+  // TODO(turbofan): Optimize this implementation!
+  for (; index < InputCount() - 1; ++index) {
+    ReplaceInput(index, InputAt(index + 1));
+  }
+  TrimInputCount(InputCount() - 1);
+}
+
+inline void Node::AppendUse(Use* use) {
+  use->next = NULL;
+  use->prev = last_use_;
+  if (last_use_ == NULL) {
+    first_use_ = use;
+  } else {
+    last_use_->next = use;
+  }
+  last_use_ = use;
+}
+
+inline void Node::RemoveUse(Use* use) {
+  if (last_use_ == use) {
+    last_use_ = use->prev;
+  }
+  if (use->prev != NULL) {
+    use->prev->next = use->next;
+  } else {
+    first_use_ = use->next;
+  }
+  if (use->next != NULL) {
+    use->next->prev = use->prev;
+  }
+}
+
+inline bool Node::OwnedBy(Node* owner) const {
+  return first_use_ != NULL && first_use_->from == owner &&
+         first_use_->next == NULL;
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/opcodes.cc b/src/compiler/opcodes.cc
new file mode 100644
index 0000000..044395c
--- /dev/null
+++ b/src/compiler/opcodes.cc
@@ -0,0 +1,34 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/opcodes.h"
+
+#include <algorithm>
+
+#include "src/base/macros.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+char const* const kMnemonics[] = {
+#define DECLARE_MNEMONIC(x) #x,
+    ALL_OP_LIST(DECLARE_MNEMONIC)
+#undef DECLARE_MNEMONIC
+        "UnknownOpcode"};
+
+}  // namespace
+
+
+// static
+char const* IrOpcode::Mnemonic(Value value) {
+  size_t const n = std::max<size_t>(value, arraysize(kMnemonics) - 1);
+  return kMnemonics[n];
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/opcodes.h b/src/compiler/opcodes.h
index e210abd..d229b6d 100644
--- a/src/compiler/opcodes.h
+++ b/src/compiler/opcodes.h
@@ -7,13 +7,14 @@
 
 // Opcodes for control operators.
 #define INNER_CONTROL_OP_LIST(V) \
-  V(Dead)                  \
-  V(Loop)                  \
-  V(Branch)                \
-  V(IfTrue)                \
-  V(IfFalse)               \
-  V(Merge)                 \
-  V(Return)                \
+  V(Dead)                        \
+  V(Loop)                        \
+  V(Branch)                      \
+  V(IfTrue)                      \
+  V(IfFalse)                     \
+  V(Merge)                       \
+  V(Return)                      \
+  V(Terminate)                   \
   V(Throw)
 
 #define CONTROL_OP_LIST(V) \
@@ -32,9 +33,9 @@
   V(HeapConstant)
 
 #define INNER_OP_LIST(V) \
+  V(Select)              \
   V(Phi)                 \
   V(EffectPhi)           \
-  V(ControlEffect)       \
   V(ValueEffect)         \
   V(Finish)              \
   V(FrameState)          \
@@ -113,7 +114,7 @@
   V(JSCreateWithContext)      \
   V(JSCreateBlockContext)     \
   V(JSCreateModuleContext)    \
-  V(JSCreateGlobalContext)
+  V(JSCreateScriptContext)
 
 #define JS_OTHER_OP_LIST(V) \
   V(JSCallConstruct)        \
@@ -131,6 +132,7 @@
 
 // Opcodes for VirtuaMachine-level operators.
 #define SIMPLIFIED_OP_LIST(V) \
+  V(AnyToBoolean)             \
   V(BooleanNot)               \
   V(BooleanToNumber)          \
   V(NumberEqual)              \
@@ -157,9 +159,13 @@
   V(ChangeBoolToBit)          \
   V(ChangeBitToBool)          \
   V(LoadField)                \
+  V(LoadBuffer)               \
   V(LoadElement)              \
   V(StoreField)               \
-  V(StoreElement)
+  V(StoreBuffer)              \
+  V(StoreElement)             \
+  V(ObjectIsSmi)              \
+  V(ObjectIsNonNegativeSmi)
 
 // Opcodes for Machine-level operators.
 #define MACHINE_OP_LIST(V)    \
@@ -186,23 +192,26 @@
   V(Int32Sub)                 \
   V(Int32SubWithOverflow)     \
   V(Int32Mul)                 \
+  V(Int32MulHigh)             \
   V(Int32Div)                 \
-  V(Int32UDiv)                \
   V(Int32Mod)                 \
-  V(Int32UMod)                \
   V(Int32LessThan)            \
   V(Int32LessThanOrEqual)     \
+  V(Uint32Div)                \
   V(Uint32LessThan)           \
   V(Uint32LessThanOrEqual)    \
+  V(Uint32Mod)                \
+  V(Uint32MulHigh)            \
   V(Int64Add)                 \
   V(Int64Sub)                 \
   V(Int64Mul)                 \
   V(Int64Div)                 \
-  V(Int64UDiv)                \
   V(Int64Mod)                 \
-  V(Int64UMod)                \
   V(Int64LessThan)            \
   V(Int64LessThanOrEqual)     \
+  V(Uint64Div)                \
+  V(Uint64LessThan)           \
+  V(Uint64Mod)                \
   V(ChangeFloat32ToFloat64)   \
   V(ChangeFloat64ToInt32)     \
   V(ChangeFloat64ToUint32)    \
@@ -221,7 +230,14 @@
   V(Float64Sqrt)              \
   V(Float64Equal)             \
   V(Float64LessThan)          \
-  V(Float64LessThanOrEqual)
+  V(Float64LessThanOrEqual)   \
+  V(Float64Floor)             \
+  V(Float64Ceil)              \
+  V(Float64RoundTruncate)     \
+  V(Float64RoundTiesAway)     \
+  V(LoadStackPointer)         \
+  V(CheckedLoad)              \
+  V(CheckedStore)
 
 #define VALUE_OP_LIST(V) \
   COMMON_OP_LIST(V)      \
@@ -253,20 +269,11 @@
   };
 
   // Returns the mnemonic name of an opcode.
-  static const char* Mnemonic(Value val) {
-    switch (val) {
-#define RETURN_NAME(x) \
-  case k##x:           \
-    return #x;
-      ALL_OP_LIST(RETURN_NAME)
-#undef RETURN_NAME
-      default:
-        return "UnknownOpcode";
-    }
-  }
+  static char const* Mnemonic(Value value);
 
   static bool IsJsOpcode(Value val) {
     switch (val) {
+// TODO(turbofan): make this a range check.
 #define RETURN_NAME(x) \
   case k##x:           \
     return true;
@@ -279,6 +286,7 @@
 
   static bool IsControlOpcode(Value val) {
     switch (val) {
+// TODO(turbofan): make this a range check.
 #define RETURN_NAME(x) \
   case k##x:           \
     return true;
@@ -289,8 +297,22 @@
     }
   }
 
+  static bool IsLeafOpcode(Value val) {
+    switch (val) {
+// TODO(turbofan): make this a table lookup.
+#define RETURN_NAME(x) \
+  case k##x:           \
+    return true;
+      LEAF_OP_LIST(RETURN_NAME)
+#undef RETURN_NAME
+      default:
+        return false;
+    }
+  }
+
   static bool IsCommonOpcode(Value val) {
     switch (val) {
+// TODO(turbofan): make this a table lookup or a range check.
 #define RETURN_NAME(x) \
   case k##x:           \
     return true;
diff --git a/src/compiler/operator-properties-inl.h b/src/compiler/operator-properties-inl.h
deleted file mode 100644
index 9dae106..0000000
--- a/src/compiler/operator-properties-inl.h
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_OPERATOR_PROPERTIES_INL_H_
-#define V8_COMPILER_OPERATOR_PROPERTIES_INL_H_
-
-#include "src/compiler/common-operator.h"
-#include "src/compiler/js-operator.h"
-#include "src/compiler/opcodes.h"
-#include "src/compiler/operator-properties.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-inline bool OperatorProperties::HasValueInput(const Operator* op) {
-  return OperatorProperties::GetValueInputCount(op) > 0;
-}
-
-inline bool OperatorProperties::HasContextInput(const Operator* op) {
-  IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode());
-  return IrOpcode::IsJsOpcode(opcode);
-}
-
-inline bool OperatorProperties::HasEffectInput(const Operator* op) {
-  return OperatorProperties::GetEffectInputCount(op) > 0;
-}
-
-inline bool OperatorProperties::HasControlInput(const Operator* op) {
-  return OperatorProperties::GetControlInputCount(op) > 0;
-}
-
-inline bool OperatorProperties::HasFrameStateInput(const Operator* op) {
-  if (!FLAG_turbo_deoptimization) {
-    return false;
-  }
-
-  switch (op->opcode()) {
-    case IrOpcode::kFrameState:
-      return true;
-    case IrOpcode::kJSCallRuntime: {
-      Runtime::FunctionId function = OpParameter<Runtime::FunctionId>(op);
-      return Linkage::NeedsFrameState(function);
-    }
-
-    // Strict equality cannot lazily deoptimize.
-    case IrOpcode::kJSStrictEqual:
-    case IrOpcode::kJSStrictNotEqual:
-      return false;
-
-    // Calls
-    case IrOpcode::kJSCallFunction:
-    case IrOpcode::kJSCallConstruct:
-
-    // Compare operations
-    case IrOpcode::kJSEqual:
-    case IrOpcode::kJSNotEqual:
-    case IrOpcode::kJSLessThan:
-    case IrOpcode::kJSGreaterThan:
-    case IrOpcode::kJSLessThanOrEqual:
-    case IrOpcode::kJSGreaterThanOrEqual:
-
-    // Binary operations
-    case IrOpcode::kJSBitwiseOr:
-    case IrOpcode::kJSBitwiseXor:
-    case IrOpcode::kJSBitwiseAnd:
-    case IrOpcode::kJSShiftLeft:
-    case IrOpcode::kJSShiftRight:
-    case IrOpcode::kJSShiftRightLogical:
-    case IrOpcode::kJSAdd:
-    case IrOpcode::kJSSubtract:
-    case IrOpcode::kJSMultiply:
-    case IrOpcode::kJSDivide:
-    case IrOpcode::kJSModulus:
-    case IrOpcode::kJSLoadProperty:
-    case IrOpcode::kJSStoreProperty:
-    case IrOpcode::kJSLoadNamed:
-    case IrOpcode::kJSStoreNamed:
-      return true;
-
-    default:
-      return false;
-  }
-}
-
-inline int OperatorProperties::GetValueInputCount(const Operator* op) {
-  return op->InputCount();
-}
-
-inline int OperatorProperties::GetContextInputCount(const Operator* op) {
-  return OperatorProperties::HasContextInput(op) ? 1 : 0;
-}
-
-inline int OperatorProperties::GetFrameStateInputCount(const Operator* op) {
-  return OperatorProperties::HasFrameStateInput(op) ? 1 : 0;
-}
-
-inline int OperatorProperties::GetEffectInputCount(const Operator* op) {
-  if (op->opcode() == IrOpcode::kEffectPhi ||
-      op->opcode() == IrOpcode::kFinish) {
-    return OpParameter<int>(op);
-  }
-  if (op->HasProperty(Operator::kNoRead) && op->HasProperty(Operator::kNoWrite))
-    return 0;  // no effects.
-  return 1;
-}
-
-inline int OperatorProperties::GetControlInputCount(const Operator* op) {
-  switch (op->opcode()) {
-    case IrOpcode::kPhi:
-    case IrOpcode::kEffectPhi:
-    case IrOpcode::kControlEffect:
-      return 1;
-#define OPCODE_CASE(x) case IrOpcode::k##x:
-      CONTROL_OP_LIST(OPCODE_CASE)
-#undef OPCODE_CASE
-      // Control operators are Operator1<int>.
-      return OpParameter<int>(op);
-    default:
-      // Operators that have write effects must have a control
-      // dependency. Effect dependencies only ensure the correct order of
-      // write/read operations without consideration of control flow. Without an
-      // explicit control dependency writes can be float in the schedule too
-      // early along a path that shouldn't generate a side-effect.
-      return op->HasProperty(Operator::kNoWrite) ? 0 : 1;
-  }
-  return 0;
-}
-
-inline int OperatorProperties::GetTotalInputCount(const Operator* op) {
-  return GetValueInputCount(op) + GetContextInputCount(op) +
-         GetFrameStateInputCount(op) + GetEffectInputCount(op) +
-         GetControlInputCount(op);
-}
-
-// -----------------------------------------------------------------------------
-// Output properties.
-
-inline bool OperatorProperties::HasValueOutput(const Operator* op) {
-  return GetValueOutputCount(op) > 0;
-}
-
-inline bool OperatorProperties::HasEffectOutput(const Operator* op) {
-  return op->opcode() == IrOpcode::kStart ||
-         op->opcode() == IrOpcode::kControlEffect ||
-         op->opcode() == IrOpcode::kValueEffect ||
-         (op->opcode() != IrOpcode::kFinish && GetEffectInputCount(op) > 0);
-}
-
-inline bool OperatorProperties::HasControlOutput(const Operator* op) {
-  IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode());
-  return (opcode != IrOpcode::kEnd && IrOpcode::IsControlOpcode(opcode));
-}
-
-
-inline int OperatorProperties::GetValueOutputCount(const Operator* op) {
-  return op->OutputCount();
-}
-
-inline int OperatorProperties::GetEffectOutputCount(const Operator* op) {
-  return HasEffectOutput(op) ? 1 : 0;
-}
-
-inline int OperatorProperties::GetControlOutputCount(const Operator* node) {
-  return node->opcode() == IrOpcode::kBranch ? 2 : HasControlOutput(node) ? 1
-                                                                          : 0;
-}
-
-
-inline bool OperatorProperties::IsBasicBlockBegin(const Operator* op) {
-  uint8_t opcode = op->opcode();
-  return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd ||
-         opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop ||
-         opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue ||
-         opcode == IrOpcode::kIfFalse;
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_COMPILER_OPERATOR_PROPERTIES_INL_H_
diff --git a/src/compiler/operator-properties.cc b/src/compiler/operator-properties.cc
new file mode 100644
index 0000000..abfc5fd
--- /dev/null
+++ b/src/compiler/operator-properties.cc
@@ -0,0 +1,103 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/operator-properties.h"
+
+#include "src/compiler/js-operator.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/opcodes.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// static
+bool OperatorProperties::HasContextInput(const Operator* op) {
+  IrOpcode::Value opcode = static_cast<IrOpcode::Value>(op->opcode());
+  return IrOpcode::IsJsOpcode(opcode);
+}
+
+
+// static
+bool OperatorProperties::HasFrameStateInput(const Operator* op) {
+  if (!FLAG_turbo_deoptimization) {
+    return false;
+  }
+  switch (op->opcode()) {
+    case IrOpcode::kFrameState:
+      return true;
+    case IrOpcode::kJSCallRuntime: {
+      const CallRuntimeParameters& p = CallRuntimeParametersOf(op);
+      return Linkage::NeedsFrameState(p.id());
+    }
+
+    // Strict equality cannot lazily deoptimize.
+    case IrOpcode::kJSStrictEqual:
+    case IrOpcode::kJSStrictNotEqual:
+      return false;
+
+    // Calls
+    case IrOpcode::kJSCallFunction:
+    case IrOpcode::kJSCallConstruct:
+
+    // Compare operations
+    case IrOpcode::kJSEqual:
+    case IrOpcode::kJSGreaterThan:
+    case IrOpcode::kJSGreaterThanOrEqual:
+    case IrOpcode::kJSHasProperty:
+    case IrOpcode::kJSInstanceOf:
+    case IrOpcode::kJSLessThan:
+    case IrOpcode::kJSLessThanOrEqual:
+    case IrOpcode::kJSNotEqual:
+
+    // Binary operations
+    case IrOpcode::kJSAdd:
+    case IrOpcode::kJSBitwiseAnd:
+    case IrOpcode::kJSBitwiseOr:
+    case IrOpcode::kJSBitwiseXor:
+    case IrOpcode::kJSDivide:
+    case IrOpcode::kJSLoadNamed:
+    case IrOpcode::kJSLoadProperty:
+    case IrOpcode::kJSModulus:
+    case IrOpcode::kJSMultiply:
+    case IrOpcode::kJSShiftLeft:
+    case IrOpcode::kJSShiftRight:
+    case IrOpcode::kJSShiftRightLogical:
+    case IrOpcode::kJSStoreNamed:
+    case IrOpcode::kJSStoreProperty:
+    case IrOpcode::kJSSubtract:
+
+    // Conversions
+    case IrOpcode::kJSToObject:
+
+    // Other
+    case IrOpcode::kJSDeleteProperty:
+      return true;
+
+    default:
+      return false;
+  }
+}
+
+
+// static
+int OperatorProperties::GetTotalInputCount(const Operator* op) {
+  return op->ValueInputCount() + GetContextInputCount(op) +
+         GetFrameStateInputCount(op) + op->EffectInputCount() +
+         op->ControlInputCount();
+}
+
+
+// static
+bool OperatorProperties::IsBasicBlockBegin(const Operator* op) {
+  Operator::Opcode const opcode = op->opcode();
+  return opcode == IrOpcode::kStart || opcode == IrOpcode::kEnd ||
+         opcode == IrOpcode::kDead || opcode == IrOpcode::kLoop ||
+         opcode == IrOpcode::kMerge || opcode == IrOpcode::kIfTrue ||
+         opcode == IrOpcode::kIfFalse;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/operator-properties.h b/src/compiler/operator-properties.h
index 718eea0..37c9755 100644
--- a/src/compiler/operator-properties.h
+++ b/src/compiler/operator-properties.h
@@ -5,36 +5,33 @@
 #ifndef V8_COMPILER_OPERATOR_PROPERTIES_H_
 #define V8_COMPILER_OPERATOR_PROPERTIES_H_
 
+#include "src/base/macros.h"
+
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+// Forward declarations.
 class Operator;
 
-class OperatorProperties {
+
+class OperatorProperties FINAL {
  public:
-  static inline bool HasValueInput(const Operator* op);
-  static inline bool HasContextInput(const Operator* op);
-  static inline bool HasEffectInput(const Operator* op);
-  static inline bool HasControlInput(const Operator* op);
-  static inline bool HasFrameStateInput(const Operator* op);
+  static bool HasContextInput(const Operator* op);
+  static bool HasFrameStateInput(const Operator* op);
 
-  static inline int GetValueInputCount(const Operator* op);
-  static inline int GetContextInputCount(const Operator* op);
-  static inline int GetEffectInputCount(const Operator* op);
-  static inline int GetControlInputCount(const Operator* op);
-  static inline int GetFrameStateInputCount(const Operator* op);
-  static inline int GetTotalInputCount(const Operator* op);
+  static int GetContextInputCount(const Operator* op) {
+    return HasContextInput(op) ? 1 : 0;
+  }
+  static int GetFrameStateInputCount(const Operator* op) {
+    return HasFrameStateInput(op) ? 1 : 0;
+  }
+  static int GetTotalInputCount(const Operator* op);
 
-  static inline bool HasValueOutput(const Operator* op);
-  static inline bool HasEffectOutput(const Operator* op);
-  static inline bool HasControlOutput(const Operator* op);
+  static bool IsBasicBlockBegin(const Operator* op);
 
-  static inline int GetValueOutputCount(const Operator* op);
-  static inline int GetEffectOutputCount(const Operator* op);
-  static inline int GetControlOutputCount(const Operator* op);
-
-  static inline bool IsBasicBlockBegin(const Operator* op);
+ private:
+  DISALLOW_COPY_AND_ASSIGN(OperatorProperties);
 };
 
 }  // namespace compiler
diff --git a/src/compiler/operator.cc b/src/compiler/operator.cc
index 35f9c88..c8687f4 100644
--- a/src/compiler/operator.cc
+++ b/src/compiler/operator.cc
@@ -4,22 +4,41 @@
 
 #include "src/compiler/operator.h"
 
+#include <limits>
+
 namespace v8 {
 namespace internal {
 namespace compiler {
 
-Operator::~Operator() {}
+
+template <typename N>
+static inline N CheckRange(size_t val) {
+  CHECK(val <= std::numeric_limits<N>::max());
+  return static_cast<N>(val);
+}
 
 
-SimpleOperator::SimpleOperator(Opcode opcode, Properties properties,
-                               int input_count, int output_count,
-                               const char* mnemonic)
-    : Operator(opcode, properties, mnemonic),
-      input_count_(input_count),
-      output_count_(output_count) {}
+Operator::Operator(Opcode opcode, Properties properties, const char* mnemonic,
+                   size_t value_in, size_t effect_in, size_t control_in,
+                   size_t value_out, size_t effect_out, size_t control_out)
+    : opcode_(opcode),
+      properties_(properties),
+      mnemonic_(mnemonic),
+      value_in_(CheckRange<uint32_t>(value_in)),
+      effect_in_(CheckRange<uint16_t>(effect_in)),
+      control_in_(CheckRange<uint16_t>(control_in)),
+      value_out_(CheckRange<uint16_t>(value_out)),
+      effect_out_(CheckRange<uint8_t>(effect_out)),
+      control_out_(CheckRange<uint8_t>(control_out)) {}
 
 
-SimpleOperator::~SimpleOperator() {}
+std::ostream& operator<<(std::ostream& os, const Operator& op) {
+  op.PrintTo(os);
+  return os;
+}
+
+
+void Operator::PrintTo(std::ostream& os) const { os << mnemonic(); }
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/operator.h b/src/compiler/operator.h
index 5137806..fb144ce 100644
--- a/src/compiler/operator.h
+++ b/src/compiler/operator.h
@@ -5,9 +5,11 @@
 #ifndef V8_COMPILER_OPERATOR_H_
 #define V8_COMPILER_OPERATOR_H_
 
+#include <ostream>  // NOLINT(readability/streams)
+
 #include "src/base/flags.h"
-#include "src/ostreams.h"
-#include "src/unique.h"
+#include "src/base/functional.h"
+#include "src/zone.h"
 
 namespace v8 {
 namespace internal {
@@ -47,9 +49,12 @@
   };
   typedef base::Flags<Property, uint8_t> Properties;
 
-  Operator(Opcode opcode, Properties properties, const char* mnemonic)
-      : opcode_(opcode), properties_(properties), mnemonic_(mnemonic) {}
-  virtual ~Operator();
+  // Constructor.
+  Operator(Opcode opcode, Properties properties, const char* mnemonic,
+           size_t value_in, size_t effect_in, size_t control_in,
+           size_t value_out, size_t effect_out, size_t control_out);
+
+  virtual ~Operator() {}
 
   // A small integer unique to all instances of a particular kind of operator,
   // useful for quick matching for specific kinds of operators. For fast access
@@ -63,196 +68,122 @@
   // Check if this operator equals another operator. Equivalent operators can
   // be merged, and nodes with equivalent operators and equivalent inputs
   // can be merged.
-  virtual bool Equals(const Operator* other) const = 0;
+  virtual bool Equals(const Operator* that) const {
+    return this->opcode() == that->opcode();
+  }
 
   // Compute a hashcode to speed up equivalence-set checking.
   // Equal operators should always have equal hashcodes, and unequal operators
   // should have unequal hashcodes with high probability.
-  virtual int HashCode() const = 0;
+  virtual size_t HashCode() const { return base::hash<Opcode>()(opcode()); }
 
   // Check whether this operator has the given property.
   bool HasProperty(Property property) const {
     return (properties() & property) == property;
   }
 
-  // Number of data inputs to the operator, for verifying graph structure.
-  virtual int InputCount() const = 0;
-
-  // Number of data outputs from the operator, for verifying graph structure.
-  virtual int OutputCount() const = 0;
-
   Properties properties() const { return properties_; }
 
+  // TODO(titzer): convert return values here to size_t.
+  int ValueInputCount() const { return value_in_; }
+  int EffectInputCount() const { return effect_in_; }
+  int ControlInputCount() const { return control_in_; }
+
+  int ValueOutputCount() const { return value_out_; }
+  int EffectOutputCount() const { return effect_out_; }
+  int ControlOutputCount() const { return control_out_; }
+
+  static inline size_t ZeroIfPure(Properties properties) {
+    return (properties & kPure) == kPure ? 0 : 1;
+  }
+
   // TODO(titzer): API for input and output types, for typechecking graph.
  protected:
   // Print the full operator into the given stream, including any
   // static parameters. Useful for debugging and visualizing the IR.
-  virtual OStream& PrintTo(OStream& os) const = 0;  // NOLINT
-  friend OStream& operator<<(OStream& os, const Operator& op);
+  virtual void PrintTo(std::ostream& os) const;
+  friend std::ostream& operator<<(std::ostream& os, const Operator& op);
 
  private:
   Opcode opcode_;
   Properties properties_;
   const char* mnemonic_;
+  uint32_t value_in_;
+  uint16_t effect_in_;
+  uint16_t control_in_;
+  uint16_t value_out_;
+  uint8_t effect_out_;
+  uint8_t control_out_;
 
   DISALLOW_COPY_AND_ASSIGN(Operator);
 };
 
 DEFINE_OPERATORS_FOR_FLAGS(Operator::Properties)
 
-OStream& operator<<(OStream& os, const Operator& op);
+std::ostream& operator<<(std::ostream& os, const Operator& op);
 
-// An implementation of Operator that has no static parameters. Such operators
-// have just a name, an opcode, and a fixed number of inputs and outputs.
-// They can represented by singletons and shared globally.
-class SimpleOperator : public Operator {
- public:
-  SimpleOperator(Opcode opcode, Properties properties, int input_count,
-                 int output_count, const char* mnemonic);
-  ~SimpleOperator();
-
-  virtual bool Equals(const Operator* that) const FINAL {
-    return opcode() == that->opcode();
-  }
-  virtual int HashCode() const FINAL { return opcode(); }
-  virtual int InputCount() const FINAL { return input_count_; }
-  virtual int OutputCount() const FINAL { return output_count_; }
-
- private:
-  virtual OStream& PrintTo(OStream& os) const FINAL {  // NOLINT
-    return os << mnemonic();
-  }
-
-  int input_count_;
-  int output_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(SimpleOperator);
-};
-
-// Template specialization implements a kind of type class for dealing with the
-// static parameters of Operator1 automatically.
-template <typename T>
-struct StaticParameterTraits {
-  static OStream& PrintTo(OStream& os, T val) {  // NOLINT
-    return os << "??";
-  }
-  static int HashCode(T a) { return 0; }
-  static bool Equals(T a, T b) {
-    return false;  // Not every T has a ==. By default, be conservative.
-  }
-};
-
-// Specialization for static parameters of type {int}.
-template <>
-struct StaticParameterTraits<int> {
-  static OStream& PrintTo(OStream& os, int val) {  // NOLINT
-    return os << val;
-  }
-  static int HashCode(int a) { return a; }
-  static bool Equals(int a, int b) { return a == b; }
-};
-
-// Specialization for static parameters of type {double}.
-template <>
-struct StaticParameterTraits<double> {
-  static OStream& PrintTo(OStream& os, double val) {  // NOLINT
-    return os << val;
-  }
-  static int HashCode(double a) {
-    return static_cast<int>(bit_cast<int64_t>(a));
-  }
-  static bool Equals(double a, double b) {
-    return bit_cast<int64_t>(a) == bit_cast<int64_t>(b);
-  }
-};
-
-// Specialization for static parameters of type {Unique<Object>}.
-template <>
-struct StaticParameterTraits<Unique<Object> > {
-  static OStream& PrintTo(OStream& os, Unique<Object> val) {  // NOLINT
-    return os << Brief(*val.handle());
-  }
-  static int HashCode(Unique<Object> a) {
-    return static_cast<int>(a.Hashcode());
-  }
-  static bool Equals(Unique<Object> a, Unique<Object> b) { return a == b; }
-};
-
-// Specialization for static parameters of type {Unique<Name>}.
-template <>
-struct StaticParameterTraits<Unique<Name> > {
-  static OStream& PrintTo(OStream& os, Unique<Name> val) {  // NOLINT
-    return os << Brief(*val.handle());
-  }
-  static int HashCode(Unique<Name> a) { return static_cast<int>(a.Hashcode()); }
-  static bool Equals(Unique<Name> a, Unique<Name> b) { return a == b; }
-};
-
-#if DEBUG
-// Specialization for static parameters of type {Handle<Object>} to prevent any
-// direct usage of Handles in constants.
-template <>
-struct StaticParameterTraits<Handle<Object> > {
-  static OStream& PrintTo(OStream& os, Handle<Object> val) {  // NOLINT
-    UNREACHABLE();  // Should use Unique<Object> instead
-    return os;
-  }
-  static int HashCode(Handle<Object> a) {
-    UNREACHABLE();  // Should use Unique<Object> instead
-    return 0;
-  }
-  static bool Equals(Handle<Object> a, Handle<Object> b) {
-    UNREACHABLE();  // Should use Unique<Object> instead
-    return false;
-  }
-};
-#endif
 
 // A templatized implementation of Operator that has one static parameter of
-// type {T}. If a specialization of StaticParameterTraits<{T}> exists, then
-// operators of this kind can automatically be hashed, compared, and printed.
-template <typename T>
+// type {T}.
+template <typename T, typename Pred = std::equal_to<T>,
+          typename Hash = base::hash<T>>
 class Operator1 : public Operator {
  public:
-  Operator1(Opcode opcode, Properties properties, int input_count,
-            int output_count, const char* mnemonic, T parameter)
-      : Operator(opcode, properties, mnemonic),
-        input_count_(input_count),
-        output_count_(output_count),
-        parameter_(parameter) {}
+  Operator1(Opcode opcode, Properties properties, const char* mnemonic,
+            size_t value_in, size_t effect_in, size_t control_in,
+            size_t value_out, size_t effect_out, size_t control_out,
+            T parameter, Pred const& pred = Pred(), Hash const& hash = Hash())
+      : Operator(opcode, properties, mnemonic, value_in, effect_in, control_in,
+                 value_out, effect_out, control_out),
+        parameter_(parameter),
+        pred_(pred),
+        hash_(hash) {}
 
-  const T& parameter() const { return parameter_; }
+  T const& parameter() const { return parameter_; }
 
-  virtual bool Equals(const Operator* other) const OVERRIDE {
+  bool Equals(const Operator* other) const FINAL {
     if (opcode() != other->opcode()) return false;
     const Operator1<T>* that = static_cast<const Operator1<T>*>(other);
-    return StaticParameterTraits<T>::Equals(this->parameter_, that->parameter_);
+    return this->pred_(this->parameter(), that->parameter());
   }
-  virtual int HashCode() const OVERRIDE {
-    return opcode() + 33 * StaticParameterTraits<T>::HashCode(this->parameter_);
+  size_t HashCode() const FINAL {
+    return base::hash_combine(this->opcode(), this->hash_(this->parameter()));
   }
-  virtual int InputCount() const OVERRIDE { return input_count_; }
-  virtual int OutputCount() const OVERRIDE { return output_count_; }
-  virtual OStream& PrintParameter(OStream& os) const {  // NOLINT
-    return StaticParameterTraits<T>::PrintTo(os << "[", parameter_) << "]";
+  virtual void PrintParameter(std::ostream& os) const {
+    os << "[" << this->parameter() << "]";
   }
 
  protected:
-  virtual OStream& PrintTo(OStream& os) const FINAL {  // NOLINT
-    return PrintParameter(os << mnemonic());
+  void PrintTo(std::ostream& os) const FINAL {
+    os << mnemonic();
+    PrintParameter(os);
   }
 
  private:
-  int input_count_;
-  int output_count_;
-  T parameter_;
+  T const parameter_;
+  Pred const pred_;
+  Hash const hash_;
 };
 
 
 // Helper to extract parameters from Operator1<*> operator.
 template <typename T>
-static inline const T& OpParameter(const Operator* op) {
-  return reinterpret_cast<const Operator1<T>*>(op)->parameter();
+inline T const& OpParameter(const Operator* op) {
+  return static_cast<const Operator1<T>*>(op)->parameter();
+}
+
+// NOTE: We have to be careful to use the right equal/hash functions below, for
+// float/double we always use the ones operating on the bit level.
+template <>
+inline float const& OpParameter(const Operator* op) {
+  return static_cast<const Operator1<float, base::bit_equal_to<float>,
+                                     base::bit_hash<float>>*>(op)->parameter();
+}
+
+template <>
+inline double const& OpParameter(const Operator* op) {
+  return static_cast<const Operator1<double, base::bit_equal_to<double>,
+                                     base::bit_hash<double>>*>(op)->parameter();
 }
 
 }  // namespace compiler
diff --git a/src/compiler/phi-reducer.h b/src/compiler/phi-reducer.h
deleted file mode 100644
index 5870d04..0000000
--- a/src/compiler/phi-reducer.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_COMPILER_PHI_REDUCER_H_
-#define V8_COMPILER_PHI_REDUCER_H_
-
-#include "src/compiler/graph-reducer.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-// Replaces redundant phis if all the inputs are the same or the phi itself.
-class PhiReducer FINAL : public Reducer {
- public:
-  virtual Reduction Reduce(Node* node) OVERRIDE {
-    if (node->opcode() != IrOpcode::kPhi &&
-        node->opcode() != IrOpcode::kEffectPhi)
-      return NoChange();
-
-    int n = node->op()->InputCount();
-    if (n == 1) return Replace(node->InputAt(0));
-
-    Node* replacement = NULL;
-    Node::Inputs inputs = node->inputs();
-    for (InputIter it = inputs.begin(); n > 0; --n, ++it) {
-      Node* input = *it;
-      if (input != node && input != replacement) {
-        if (replacement != NULL) return NoChange();
-        replacement = input;
-      }
-    }
-    DCHECK_NE(node, replacement);
-    return Replace(replacement);
-  }
-};
-}
-}
-}  // namespace v8::internal::compiler
-
-#endif  // V8_COMPILER_PHI_REDUCER_H_
diff --git a/src/compiler/pipeline-statistics.cc b/src/compiler/pipeline-statistics.cc
new file mode 100644
index 0000000..e58c396
--- /dev/null
+++ b/src/compiler/pipeline-statistics.cc
@@ -0,0 +1,103 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler.h"
+#include "src/compiler/pipeline-statistics.h"
+#include "src/compiler/zone-pool.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+void PipelineStatistics::CommonStats::Begin(
+    PipelineStatistics* pipeline_stats) {
+  DCHECK(scope_.is_empty());
+  scope_.Reset(new ZonePool::StatsScope(pipeline_stats->zone_pool_));
+  timer_.Start();
+  outer_zone_initial_size_ = pipeline_stats->OuterZoneSize();
+  allocated_bytes_at_start_ =
+      outer_zone_initial_size_ -
+      pipeline_stats->total_stats_.outer_zone_initial_size_ +
+      pipeline_stats->zone_pool_->GetCurrentAllocatedBytes();
+}
+
+
+void PipelineStatistics::CommonStats::End(
+    PipelineStatistics* pipeline_stats,
+    CompilationStatistics::BasicStats* diff) {
+  DCHECK(!scope_.is_empty());
+  diff->function_name_ = pipeline_stats->function_name_;
+  diff->delta_ = timer_.Elapsed();
+  size_t outer_zone_diff =
+      pipeline_stats->OuterZoneSize() - outer_zone_initial_size_;
+  diff->max_allocated_bytes_ = outer_zone_diff + scope_->GetMaxAllocatedBytes();
+  diff->absolute_max_allocated_bytes_ =
+      diff->max_allocated_bytes_ + allocated_bytes_at_start_;
+  diff->total_allocated_bytes_ =
+      outer_zone_diff + scope_->GetTotalAllocatedBytes();
+  scope_.Reset(NULL);
+  timer_.Stop();
+}
+
+
+PipelineStatistics::PipelineStatistics(CompilationInfo* info,
+                                       ZonePool* zone_pool)
+    : isolate_(info->zone()->isolate()),
+      outer_zone_(info->zone()),
+      zone_pool_(zone_pool),
+      compilation_stats_(isolate_->GetTurboStatistics()),
+      source_size_(0),
+      phase_kind_name_(NULL),
+      phase_name_(NULL) {
+  if (!info->shared_info().is_null()) {
+    source_size_ = static_cast<size_t>(info->shared_info()->SourceSize());
+    SmartArrayPointer<char> name =
+        info->shared_info()->DebugName()->ToCString();
+    function_name_ = name.get();
+  }
+  total_stats_.Begin(this);
+}
+
+
+PipelineStatistics::~PipelineStatistics() {
+  if (InPhaseKind()) EndPhaseKind();
+  CompilationStatistics::BasicStats diff;
+  total_stats_.End(this, &diff);
+  compilation_stats_->RecordTotalStats(source_size_, diff);
+}
+
+
+void PipelineStatistics::BeginPhaseKind(const char* phase_kind_name) {
+  DCHECK(!InPhase());
+  if (InPhaseKind()) EndPhaseKind();
+  phase_kind_name_ = phase_kind_name;
+  phase_kind_stats_.Begin(this);
+}
+
+
+void PipelineStatistics::EndPhaseKind() {
+  DCHECK(!InPhase());
+  CompilationStatistics::BasicStats diff;
+  phase_kind_stats_.End(this, &diff);
+  compilation_stats_->RecordPhaseKindStats(phase_kind_name_, diff);
+}
+
+
+void PipelineStatistics::BeginPhase(const char* name) {
+  DCHECK(InPhaseKind());
+  phase_name_ = name;
+  phase_stats_.Begin(this);
+}
+
+
+void PipelineStatistics::EndPhase() {
+  DCHECK(InPhaseKind());
+  CompilationStatistics::BasicStats diff;
+  phase_stats_.End(this, &diff);
+  compilation_stats_->RecordPhaseStats(phase_kind_name_, phase_name_, diff);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/pipeline-statistics.h b/src/compiler/pipeline-statistics.h
new file mode 100644
index 0000000..01cc9de
--- /dev/null
+++ b/src/compiler/pipeline-statistics.h
@@ -0,0 +1,95 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_PIPELINE_STATISTICS_H_
+#define V8_COMPILER_PIPELINE_STATISTICS_H_
+
+#include <string>
+
+#include "src/compilation-statistics.h"
+#include "src/compiler/zone-pool.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class PhaseScope;
+
+class PipelineStatistics : public Malloced {
+ public:
+  PipelineStatistics(CompilationInfo* info, ZonePool* zone_pool);
+  ~PipelineStatistics();
+
+  void BeginPhaseKind(const char* phase_kind_name);
+
+ private:
+  size_t OuterZoneSize() {
+    return static_cast<size_t>(outer_zone_->allocation_size());
+  }
+
+  class CommonStats {
+   public:
+    CommonStats() : outer_zone_initial_size_(0) {}
+
+    void Begin(PipelineStatistics* pipeline_stats);
+    void End(PipelineStatistics* pipeline_stats,
+             CompilationStatistics::BasicStats* diff);
+
+    SmartPointer<ZonePool::StatsScope> scope_;
+    base::ElapsedTimer timer_;
+    size_t outer_zone_initial_size_;
+    size_t allocated_bytes_at_start_;
+  };
+
+  bool InPhaseKind() { return !phase_kind_stats_.scope_.is_empty(); }
+  void EndPhaseKind();
+
+  friend class PhaseScope;
+  bool InPhase() { return !phase_stats_.scope_.is_empty(); }
+  void BeginPhase(const char* name);
+  void EndPhase();
+
+  Isolate* isolate_;
+  Zone* outer_zone_;
+  ZonePool* zone_pool_;
+  CompilationStatistics* compilation_stats_;
+  std::string function_name_;
+
+  // Stats for the entire compilation.
+  CommonStats total_stats_;
+  size_t source_size_;
+
+  // Stats for phase kind.
+  const char* phase_kind_name_;
+  CommonStats phase_kind_stats_;
+
+  // Stats for phase.
+  const char* phase_name_;
+  CommonStats phase_stats_;
+
+  DISALLOW_COPY_AND_ASSIGN(PipelineStatistics);
+};
+
+
+class PhaseScope {
+ public:
+  PhaseScope(PipelineStatistics* pipeline_stats, const char* name)
+      : pipeline_stats_(pipeline_stats) {
+    if (pipeline_stats_ != NULL) pipeline_stats_->BeginPhase(name);
+  }
+  ~PhaseScope() {
+    if (pipeline_stats_ != NULL) pipeline_stats_->EndPhase();
+  }
+
+ private:
+  PipelineStatistics* const pipeline_stats_;
+
+  DISALLOW_COPY_AND_ASSIGN(PhaseScope);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif
diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc
index 9889b6a..c7432c6 100644
--- a/src/compiler/pipeline.cc
+++ b/src/compiler/pipeline.cc
@@ -4,29 +4,42 @@
 
 #include "src/compiler/pipeline.h"
 
+#include <fstream>  // NOLINT(readability/streams)
+#include <sstream>
+
 #include "src/base/platform/elapsed-timer.h"
 #include "src/compiler/ast-graph-builder.h"
+#include "src/compiler/ast-loop-assignment-analyzer.h"
+#include "src/compiler/basic-block-instrumentor.h"
 #include "src/compiler/change-lowering.h"
 #include "src/compiler/code-generator.h"
+#include "src/compiler/common-operator-reducer.h"
+#include "src/compiler/control-reducer.h"
 #include "src/compiler/graph-replay.h"
 #include "src/compiler/graph-visualizer.h"
 #include "src/compiler/instruction.h"
 #include "src/compiler/instruction-selector.h"
+#include "src/compiler/js-builtin-reducer.h"
 #include "src/compiler/js-context-specialization.h"
 #include "src/compiler/js-generic-lowering.h"
 #include "src/compiler/js-inlining.h"
 #include "src/compiler/js-typed-lowering.h"
+#include "src/compiler/jump-threading.h"
+#include "src/compiler/load-elimination.h"
 #include "src/compiler/machine-operator-reducer.h"
-#include "src/compiler/phi-reducer.h"
+#include "src/compiler/move-optimizer.h"
+#include "src/compiler/pipeline-statistics.h"
 #include "src/compiler/register-allocator.h"
+#include "src/compiler/register-allocator-verifier.h"
 #include "src/compiler/schedule.h"
 #include "src/compiler/scheduler.h"
+#include "src/compiler/select-lowering.h"
 #include "src/compiler/simplified-lowering.h"
 #include "src/compiler/simplified-operator-reducer.h"
 #include "src/compiler/typer.h"
 #include "src/compiler/value-numbering-reducer.h"
 #include "src/compiler/verifier.h"
-#include "src/hydrogen.h"
+#include "src/compiler/zone-pool.h"
 #include "src/ostreams.h"
 #include "src/utils.h"
 
@@ -34,47 +47,202 @@
 namespace internal {
 namespace compiler {
 
-class PhaseStats {
+class PipelineData {
  public:
-  enum PhaseKind { CREATE_GRAPH, OPTIMIZATION, CODEGEN };
+  explicit PipelineData(ZonePool* zone_pool, CompilationInfo* info)
+      : isolate_(info->zone()->isolate()),
+        info_(info),
+        outer_zone_(nullptr),
+        zone_pool_(zone_pool),
+        pipeline_statistics_(nullptr),
+        compilation_failed_(false),
+        code_(Handle<Code>::null()),
+        graph_zone_scope_(zone_pool_),
+        graph_zone_(nullptr),
+        graph_(nullptr),
+        loop_assignment_(nullptr),
+        machine_(nullptr),
+        common_(nullptr),
+        javascript_(nullptr),
+        jsgraph_(nullptr),
+        typer_(nullptr),
+        context_node_(nullptr),
+        schedule_(nullptr),
+        instruction_zone_scope_(zone_pool_),
+        instruction_zone_(nullptr),
+        sequence_(nullptr),
+        frame_(nullptr),
+        register_allocator_(nullptr) {}
 
-  PhaseStats(CompilationInfo* info, PhaseKind kind, const char* name)
-      : info_(info),
-        kind_(kind),
-        name_(name),
-        size_(info->zone()->allocation_size()) {
-    if (FLAG_turbo_stats) {
-      timer_.Start();
-    }
+  ~PipelineData() {
+    DeleteInstructionZone();
+    DeleteGraphZone();
   }
 
-  ~PhaseStats() {
-    if (FLAG_turbo_stats) {
-      base::TimeDelta delta = timer_.Elapsed();
-      size_t bytes = info_->zone()->allocation_size() - size_;
-      HStatistics* stats = info_->isolate()->GetTStatistics();
-      stats->SaveTiming(name_, delta, static_cast<int>(bytes));
+  // For main entry point.
+  void Initialize(PipelineStatistics* pipeline_statistics) {
+    PhaseScope scope(pipeline_statistics, "init pipeline data");
+    outer_zone_ = info()->zone();
+    pipeline_statistics_ = pipeline_statistics;
+    graph_zone_ = graph_zone_scope_.zone();
+    graph_ = new (graph_zone()) Graph(graph_zone());
+    source_positions_.Reset(new SourcePositionTable(graph()));
+    machine_ = new (graph_zone()) MachineOperatorBuilder(
+        graph_zone(), kMachPtr,
+        InstructionSelector::SupportedMachineOperatorFlags());
+    common_ = new (graph_zone()) CommonOperatorBuilder(graph_zone());
+    javascript_ = new (graph_zone()) JSOperatorBuilder(graph_zone());
+    jsgraph_ =
+        new (graph_zone()) JSGraph(graph(), common(), javascript(), machine());
+    typer_.Reset(new Typer(graph(), info()->context()));
+    instruction_zone_ = instruction_zone_scope_.zone();
+  }
 
-      switch (kind_) {
-        case CREATE_GRAPH:
-          stats->IncrementCreateGraph(delta);
-          break;
-        case OPTIMIZATION:
-          stats->IncrementOptimizeGraph(delta);
-          break;
-        case CODEGEN:
-          stats->IncrementGenerateCode(delta);
-          break;
-      }
-    }
+  // For machine graph testing entry point.
+  void InitializeTorTesting(Graph* graph, Schedule* schedule) {
+    graph_ = graph;
+    source_positions_.Reset(new SourcePositionTable(graph));
+    schedule_ = schedule;
+    instruction_zone_ = instruction_zone_scope_.zone();
+  }
+
+  // For register allocation testing entry point.
+  void InitializeTorTesting(InstructionSequence* sequence) {
+    instruction_zone_ = sequence->zone();
+    sequence_ = sequence;
+  }
+
+  Isolate* isolate() const { return isolate_; }
+  CompilationInfo* info() const { return info_; }
+  ZonePool* zone_pool() const { return zone_pool_; }
+  PipelineStatistics* pipeline_statistics() { return pipeline_statistics_; }
+  bool compilation_failed() const { return compilation_failed_; }
+  void set_compilation_failed() { compilation_failed_ = true; }
+  Handle<Code> code() { return code_; }
+  void set_code(Handle<Code> code) {
+    DCHECK(code_.is_null());
+    code_ = code;
+  }
+
+  // RawMachineAssembler generally produces graphs which cannot be verified.
+  bool MayHaveUnverifiableGraph() const { return outer_zone_ == nullptr; }
+
+  Zone* graph_zone() const { return graph_zone_; }
+  Graph* graph() const { return graph_; }
+  SourcePositionTable* source_positions() const {
+    return source_positions_.get();
+  }
+  MachineOperatorBuilder* machine() const { return machine_; }
+  CommonOperatorBuilder* common() const { return common_; }
+  JSOperatorBuilder* javascript() const { return javascript_; }
+  JSGraph* jsgraph() const { return jsgraph_; }
+  Typer* typer() const { return typer_.get(); }
+
+  LoopAssignmentAnalysis* loop_assignment() const { return loop_assignment_; }
+  void set_loop_assignment(LoopAssignmentAnalysis* loop_assignment) {
+    DCHECK_EQ(nullptr, loop_assignment_);
+    loop_assignment_ = loop_assignment;
+  }
+
+  Node* context_node() const { return context_node_; }
+  void set_context_node(Node* context_node) {
+    DCHECK_EQ(nullptr, context_node_);
+    context_node_ = context_node;
+  }
+
+  Schedule* schedule() const { return schedule_; }
+  void set_schedule(Schedule* schedule) {
+    DCHECK_EQ(nullptr, schedule_);
+    schedule_ = schedule;
+  }
+
+  Zone* instruction_zone() const { return instruction_zone_; }
+  InstructionSequence* sequence() const { return sequence_; }
+  Frame* frame() const { return frame_; }
+  RegisterAllocator* register_allocator() const { return register_allocator_; }
+
+  void DeleteGraphZone() {
+    // Destroy objects with destructors first.
+    source_positions_.Reset(nullptr);
+    typer_.Reset(nullptr);
+    if (graph_zone_ == nullptr) return;
+    // Destroy zone and clear pointers.
+    graph_zone_scope_.Destroy();
+    graph_zone_ = nullptr;
+    graph_ = nullptr;
+    loop_assignment_ = nullptr;
+    machine_ = nullptr;
+    common_ = nullptr;
+    javascript_ = nullptr;
+    jsgraph_ = nullptr;
+    context_node_ = nullptr;
+    schedule_ = nullptr;
+  }
+
+  void DeleteInstructionZone() {
+    if (instruction_zone_ == nullptr) return;
+    instruction_zone_scope_.Destroy();
+    instruction_zone_ = nullptr;
+    sequence_ = nullptr;
+    frame_ = nullptr;
+    register_allocator_ = nullptr;
+  }
+
+  void InitializeInstructionSequence() {
+    DCHECK_EQ(nullptr, sequence_);
+    InstructionBlocks* instruction_blocks =
+        InstructionSequence::InstructionBlocksFor(instruction_zone(),
+                                                  schedule());
+    sequence_ = new (instruction_zone())
+        InstructionSequence(instruction_zone(), instruction_blocks);
+  }
+
+  void InitializeRegisterAllocator(Zone* local_zone,
+                                   const RegisterConfiguration* config,
+                                   const char* debug_name) {
+    DCHECK_EQ(nullptr, register_allocator_);
+    DCHECK_EQ(nullptr, frame_);
+    frame_ = new (instruction_zone()) Frame();
+    register_allocator_ = new (instruction_zone())
+        RegisterAllocator(config, local_zone, frame(), sequence(), debug_name);
   }
 
  private:
+  Isolate* isolate_;
   CompilationInfo* info_;
-  PhaseKind kind_;
-  const char* name_;
-  size_t size_;
-  base::ElapsedTimer timer_;
+  Zone* outer_zone_;
+  ZonePool* const zone_pool_;
+  PipelineStatistics* pipeline_statistics_;
+  bool compilation_failed_;
+  Handle<Code> code_;
+
+  // All objects in the following group of fields are allocated in graph_zone_.
+  // They are all set to NULL when the graph_zone_ is destroyed.
+  ZonePool::Scope graph_zone_scope_;
+  Zone* graph_zone_;
+  Graph* graph_;
+  // TODO(dcarney): make this into a ZoneObject.
+  SmartPointer<SourcePositionTable> source_positions_;
+  LoopAssignmentAnalysis* loop_assignment_;
+  MachineOperatorBuilder* machine_;
+  CommonOperatorBuilder* common_;
+  JSOperatorBuilder* javascript_;
+  JSGraph* jsgraph_;
+  // TODO(dcarney): make this into a ZoneObject.
+  SmartPointer<Typer> typer_;
+  Node* context_node_;
+  Schedule* schedule_;
+
+  // All objects in the following group of fields are allocated in
+  // instruction_zone_.  They are all set to NULL when the instruction_zone_ is
+  // destroyed.
+  ZonePool::Scope instruction_zone_scope_;
+  Zone* instruction_zone_;
+  InstructionSequence* sequence_;
+  Frame* frame_;
+  RegisterAllocator* register_allocator_;
+
+  DISALLOW_COPY_AND_ASSIGN(PipelineData);
 };
 
 
@@ -87,41 +255,46 @@
 }
 
 
-void Pipeline::VerifyAndPrintGraph(Graph* graph, const char* phase) {
-  if (FLAG_trace_turbo) {
-    char buffer[256];
-    Vector<char> filename(buffer, sizeof(buffer));
-    if (!info_->shared_info().is_null()) {
-      SmartArrayPointer<char> functionname =
-          info_->shared_info()->DebugName()->ToCString();
-      if (strlen(functionname.get()) > 0) {
-        SNPrintF(filename, "turbo-%s-%s.dot", functionname.get(), phase);
-      } else {
-        SNPrintF(filename, "turbo-%p-%s.dot", static_cast<void*>(info_), phase);
-      }
-    } else {
-      SNPrintF(filename, "turbo-none-%s.dot", phase);
-    }
-    std::replace(filename.start(), filename.start() + filename.length(), ' ',
-                 '_');
-    FILE* file = base::OS::FOpen(filename.start(), "w+");
-    OFStream of(file);
-    of << AsDOT(*graph);
-    fclose(file);
+struct TurboCfgFile : public std::ofstream {
+  explicit TurboCfgFile(Isolate* isolate)
+      : std::ofstream(isolate->GetTurboCfgFileName().c_str(),
+                      std::ios_base::app) {}
+};
 
-    OFStream os(stdout);
-    os << "-- " << phase << " graph printed to file " << filename.start()
-       << "\n";
+
+static void TraceSchedule(Schedule* schedule) {
+  if (!FLAG_trace_turbo_graph && !FLAG_trace_turbo_scheduler) return;
+  OFStream os(stdout);
+  os << "-- Schedule --------------------------------------\n" << *schedule;
+}
+
+
+static SmartArrayPointer<char> GetDebugName(CompilationInfo* info) {
+  SmartArrayPointer<char> name;
+  if (info->IsStub()) {
+    if (info->code_stub() != NULL) {
+      CodeStub::Major major_key = info->code_stub()->MajorKey();
+      const char* major_name = CodeStub::MajorName(major_key, false);
+      size_t len = strlen(major_name);
+      name.Reset(new char[len]);
+      memcpy(name.get(), major_name, len);
+    }
+  } else {
+    AllowHandleDereference allow_deref;
+    name = info->function()->debug_name()->ToCString();
   }
-  if (VerifyGraphs()) Verifier::Run(graph);
+  return name;
 }
 
 
 class AstGraphBuilderWithPositions : public AstGraphBuilder {
  public:
-  explicit AstGraphBuilderWithPositions(CompilationInfo* info, JSGraph* jsgraph,
-                                        SourcePositionTable* source_positions)
-      : AstGraphBuilder(info, jsgraph), source_positions_(source_positions) {}
+  AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info,
+                               JSGraph* jsgraph,
+                               LoopAssignmentAnalysis* loop_assignment,
+                               SourcePositionTable* source_positions)
+      : AstGraphBuilder(local_zone, info, jsgraph, loop_assignment),
+        source_positions_(source_positions) {}
 
   bool CreateGraph() {
     SourcePositionTable::Scope pos(source_positions_,
@@ -130,7 +303,7 @@
   }
 
 #define DEF_VISIT(type)                                               \
-  virtual void Visit##type(type* node) OVERRIDE {                  \
+  void Visit##type(type* node) OVERRIDE {                             \
     SourcePositionTable::Scope pos(source_positions_,                 \
                                    SourcePosition(node->position())); \
     AstGraphBuilder::Visit##type(node);                               \
@@ -138,220 +311,613 @@
   AST_NODE_LIST(DEF_VISIT)
 #undef DEF_VISIT
 
+  Node* GetFunctionContext() { return AstGraphBuilder::GetFunctionContext(); }
+
  private:
   SourcePositionTable* source_positions_;
 };
 
 
-static void TraceSchedule(Schedule* schedule) {
-  if (!FLAG_trace_turbo) return;
-  OFStream os(stdout);
-  os << "-- Schedule --------------------------------------\n" << *schedule;
+class PipelineRunScope {
+ public:
+  PipelineRunScope(PipelineData* data, const char* phase_name)
+      : phase_scope_(
+            phase_name == nullptr ? nullptr : data->pipeline_statistics(),
+            phase_name),
+        zone_scope_(data->zone_pool()) {}
+
+  Zone* zone() { return zone_scope_.zone(); }
+
+ private:
+  PhaseScope phase_scope_;
+  ZonePool::Scope zone_scope_;
+};
+
+
+template <typename Phase>
+void Pipeline::Run() {
+  PipelineRunScope scope(this->data_, Phase::phase_name());
+  Phase phase;
+  phase.Run(this->data_, scope.zone());
+}
+
+
+template <typename Phase, typename Arg0>
+void Pipeline::Run(Arg0 arg_0) {
+  PipelineRunScope scope(this->data_, Phase::phase_name());
+  Phase phase;
+  phase.Run(this->data_, scope.zone(), arg_0);
+}
+
+
+struct LoopAssignmentAnalysisPhase {
+  static const char* phase_name() { return "loop assignment analysis"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    AstLoopAssignmentAnalyzer analyzer(data->graph_zone(), data->info());
+    LoopAssignmentAnalysis* loop_assignment = analyzer.Analyze();
+    data->set_loop_assignment(loop_assignment);
+  }
+};
+
+
+struct GraphBuilderPhase {
+  static const char* phase_name() { return "graph builder"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    AstGraphBuilderWithPositions graph_builder(
+        temp_zone, data->info(), data->jsgraph(), data->loop_assignment(),
+        data->source_positions());
+    if (graph_builder.CreateGraph()) {
+      data->set_context_node(graph_builder.GetFunctionContext());
+    } else {
+      data->set_compilation_failed();
+    }
+  }
+};
+
+
+struct ContextSpecializerPhase {
+  static const char* phase_name() { return "context specializing"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    SourcePositionTable::Scope pos(data->source_positions(),
+                                   SourcePosition::Unknown());
+    JSContextSpecializer spec(data->info(), data->jsgraph(),
+                              data->context_node());
+    GraphReducer graph_reducer(data->graph(), temp_zone);
+    graph_reducer.AddReducer(&spec);
+    graph_reducer.ReduceGraph();
+  }
+};
+
+
+struct InliningPhase {
+  static const char* phase_name() { return "inlining"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    SourcePositionTable::Scope pos(data->source_positions(),
+                                   SourcePosition::Unknown());
+    JSInliner inliner(temp_zone, data->info(), data->jsgraph());
+    inliner.Inline();
+  }
+};
+
+
+struct TyperPhase {
+  static const char* phase_name() { return "typer"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) { data->typer()->Run(); }
+};
+
+
+struct TypedLoweringPhase {
+  static const char* phase_name() { return "typed lowering"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    SourcePositionTable::Scope pos(data->source_positions(),
+                                   SourcePosition::Unknown());
+    ValueNumberingReducer vn_reducer(temp_zone);
+    LoadElimination load_elimination;
+    JSBuiltinReducer builtin_reducer(data->jsgraph());
+    JSTypedLowering typed_lowering(data->jsgraph(), temp_zone);
+    SimplifiedOperatorReducer simple_reducer(data->jsgraph());
+    CommonOperatorReducer common_reducer;
+    GraphReducer graph_reducer(data->graph(), temp_zone);
+    graph_reducer.AddReducer(&vn_reducer);
+    graph_reducer.AddReducer(&builtin_reducer);
+    graph_reducer.AddReducer(&typed_lowering);
+    graph_reducer.AddReducer(&load_elimination);
+    graph_reducer.AddReducer(&simple_reducer);
+    graph_reducer.AddReducer(&common_reducer);
+    graph_reducer.ReduceGraph();
+  }
+};
+
+
+struct SimplifiedLoweringPhase {
+  static const char* phase_name() { return "simplified lowering"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    SourcePositionTable::Scope pos(data->source_positions(),
+                                   SourcePosition::Unknown());
+    SimplifiedLowering lowering(data->jsgraph(), temp_zone);
+    lowering.LowerAllNodes();
+    ValueNumberingReducer vn_reducer(temp_zone);
+    SimplifiedOperatorReducer simple_reducer(data->jsgraph());
+    MachineOperatorReducer machine_reducer(data->jsgraph());
+    CommonOperatorReducer common_reducer;
+    GraphReducer graph_reducer(data->graph(), temp_zone);
+    graph_reducer.AddReducer(&vn_reducer);
+    graph_reducer.AddReducer(&simple_reducer);
+    graph_reducer.AddReducer(&machine_reducer);
+    graph_reducer.AddReducer(&common_reducer);
+    graph_reducer.ReduceGraph();
+  }
+};
+
+
+struct ChangeLoweringPhase {
+  static const char* phase_name() { return "change lowering"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    SourcePositionTable::Scope pos(data->source_positions(),
+                                   SourcePosition::Unknown());
+    Linkage linkage(data->graph_zone(), data->info());
+    ValueNumberingReducer vn_reducer(temp_zone);
+    SimplifiedOperatorReducer simple_reducer(data->jsgraph());
+    ChangeLowering lowering(data->jsgraph(), &linkage);
+    MachineOperatorReducer machine_reducer(data->jsgraph());
+    CommonOperatorReducer common_reducer;
+    GraphReducer graph_reducer(data->graph(), temp_zone);
+    graph_reducer.AddReducer(&vn_reducer);
+    graph_reducer.AddReducer(&simple_reducer);
+    graph_reducer.AddReducer(&lowering);
+    graph_reducer.AddReducer(&machine_reducer);
+    graph_reducer.AddReducer(&common_reducer);
+    graph_reducer.ReduceGraph();
+  }
+};
+
+
+struct ControlReductionPhase {
+  void Run(PipelineData* data, Zone* temp_zone) {
+    SourcePositionTable::Scope pos(data->source_positions(),
+                                   SourcePosition::Unknown());
+    ControlReducer::ReduceGraph(temp_zone, data->jsgraph(), data->common());
+  }
+};
+
+
+struct EarlyControlReductionPhase : ControlReductionPhase {
+  static const char* phase_name() { return "early control reduction"; }
+};
+
+
+struct LateControlReductionPhase : ControlReductionPhase {
+  static const char* phase_name() { return "late control reduction"; }
+};
+
+
+struct GenericLoweringPhase {
+  static const char* phase_name() { return "generic lowering"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    SourcePositionTable::Scope pos(data->source_positions(),
+                                   SourcePosition::Unknown());
+    JSGenericLowering generic(data->info(), data->jsgraph());
+    SelectLowering select(data->jsgraph()->graph(), data->jsgraph()->common());
+    GraphReducer graph_reducer(data->graph(), temp_zone);
+    graph_reducer.AddReducer(&generic);
+    graph_reducer.AddReducer(&select);
+    graph_reducer.ReduceGraph();
+  }
+};
+
+
+struct ComputeSchedulePhase {
+  static const char* phase_name() { return "scheduling"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    Schedule* schedule = Scheduler::ComputeSchedule(temp_zone, data->graph());
+    TraceSchedule(schedule);
+    if (VerifyGraphs()) ScheduleVerifier::Run(schedule);
+    data->set_schedule(schedule);
+  }
+};
+
+
+struct InstructionSelectionPhase {
+  static const char* phase_name() { return "select instructions"; }
+
+  void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
+    InstructionSelector selector(temp_zone, data->graph(), linkage,
+                                 data->sequence(), data->schedule(),
+                                 data->source_positions());
+    selector.SelectInstructions();
+  }
+};
+
+
+struct MeetRegisterConstraintsPhase {
+  static const char* phase_name() { return "meet register constraints"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    data->register_allocator()->MeetRegisterConstraints();
+  }
+};
+
+
+struct ResolvePhisPhase {
+  static const char* phase_name() { return "resolve phis"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    data->register_allocator()->ResolvePhis();
+  }
+};
+
+
+struct BuildLiveRangesPhase {
+  static const char* phase_name() { return "build live ranges"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    data->register_allocator()->BuildLiveRanges();
+  }
+};
+
+
+struct AllocateGeneralRegistersPhase {
+  static const char* phase_name() { return "allocate general registers"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    data->register_allocator()->AllocateGeneralRegisters();
+  }
+};
+
+
+struct AllocateDoubleRegistersPhase {
+  static const char* phase_name() { return "allocate double registers"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    data->register_allocator()->AllocateDoubleRegisters();
+  }
+};
+
+
+struct ReuseSpillSlotsPhase {
+  static const char* phase_name() { return "reuse spill slots"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    data->register_allocator()->ReuseSpillSlots();
+  }
+};
+
+
+struct CommitAssignmentPhase {
+  static const char* phase_name() { return "commit assignment"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    data->register_allocator()->CommitAssignment();
+  }
+};
+
+
+struct PopulatePointerMapsPhase {
+  static const char* phase_name() { return "populate pointer maps"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    data->register_allocator()->PopulatePointerMaps();
+  }
+};
+
+
+struct ConnectRangesPhase {
+  static const char* phase_name() { return "connect ranges"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    data->register_allocator()->ConnectRanges();
+  }
+};
+
+
+struct ResolveControlFlowPhase {
+  static const char* phase_name() { return "resolve control flow"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    data->register_allocator()->ResolveControlFlow();
+  }
+};
+
+
+struct OptimizeMovesPhase {
+  static const char* phase_name() { return "optimize moves"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    MoveOptimizer move_optimizer(temp_zone, data->sequence());
+    move_optimizer.Run();
+  }
+};
+
+
+struct JumpThreadingPhase {
+  static const char* phase_name() { return "jump threading"; }
+
+  void Run(PipelineData* data, Zone* temp_zone) {
+    ZoneVector<BasicBlock::RpoNumber> result(temp_zone);
+    if (JumpThreading::ComputeForwarding(temp_zone, result, data->sequence())) {
+      JumpThreading::ApplyForwarding(result, data->sequence());
+    }
+  }
+};
+
+
+struct GenerateCodePhase {
+  static const char* phase_name() { return "generate code"; }
+
+  void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
+    CodeGenerator generator(data->frame(), linkage, data->sequence(),
+                            data->info());
+    data->set_code(generator.GenerateCode());
+  }
+};
+
+
+struct PrintGraphPhase {
+  static const char* phase_name() { return nullptr; }
+
+  void Run(PipelineData* data, Zone* temp_zone, const char* phase) {
+    CompilationInfo* info = data->info();
+    Graph* graph = data->graph();
+    char buffer[256];
+    Vector<char> filename(buffer, sizeof(buffer));
+    SmartArrayPointer<char> functionname;
+    if (!info->shared_info().is_null()) {
+      functionname = info->shared_info()->DebugName()->ToCString();
+      if (strlen(functionname.get()) > 0) {
+        SNPrintF(filename, "turbo-%s-%s", functionname.get(), phase);
+      } else {
+        SNPrintF(filename, "turbo-%p-%s", static_cast<void*>(info), phase);
+      }
+    } else {
+      SNPrintF(filename, "turbo-none-%s", phase);
+    }
+    std::replace(filename.start(), filename.start() + filename.length(), ' ',
+                 '_');
+
+    {  // Print dot.
+      char dot_buffer[256];
+      Vector<char> dot_filename(dot_buffer, sizeof(dot_buffer));
+      SNPrintF(dot_filename, "%s.dot", filename.start());
+      FILE* dot_file = base::OS::FOpen(dot_filename.start(), "w+");
+      if (dot_file == nullptr) return;
+      OFStream dot_of(dot_file);
+      dot_of << AsDOT(*graph);
+      fclose(dot_file);
+    }
+
+    {  // Print JSON.
+      char json_buffer[256];
+      Vector<char> json_filename(json_buffer, sizeof(json_buffer));
+      SNPrintF(json_filename, "%s.json", filename.start());
+      FILE* json_file = base::OS::FOpen(json_filename.start(), "w+");
+      if (json_file == nullptr) return;
+      OFStream json_of(json_file);
+      json_of << AsJSON(*graph);
+      fclose(json_file);
+    }
+
+    OFStream os(stdout);
+    if (FLAG_trace_turbo_graph) {  // Simple textual RPO.
+      os << "-- Graph after " << phase << " -- " << std::endl;
+      os << AsRPO(*graph);
+    }
+
+    os << "-- " << phase << " graph printed to file " << filename.start()
+       << std::endl;
+  }
+};
+
+
+struct VerifyGraphPhase {
+  static const char* phase_name() { return nullptr; }
+
+  void Run(PipelineData* data, Zone* temp_zone, const bool untyped) {
+    Verifier::Run(data->graph(), FLAG_turbo_types && !untyped
+                                     ? Verifier::TYPED
+                                     : Verifier::UNTYPED);
+  }
+};
+
+
+void Pipeline::BeginPhaseKind(const char* phase_kind_name) {
+  if (data_->pipeline_statistics() != NULL) {
+    data_->pipeline_statistics()->BeginPhaseKind(phase_kind_name);
+  }
+}
+
+
+void Pipeline::RunPrintAndVerify(const char* phase, bool untyped) {
+  if (FLAG_trace_turbo) {
+    Run<PrintGraphPhase>(phase);
+  }
+  if (VerifyGraphs()) {
+    Run<VerifyGraphPhase>(untyped);
+  }
 }
 
 
 Handle<Code> Pipeline::GenerateCode() {
+  // This list must be kept in sync with DONT_TURBOFAN_NODE in ast.cc.
   if (info()->function()->dont_optimize_reason() == kTryCatchStatement ||
       info()->function()->dont_optimize_reason() == kTryFinallyStatement ||
       // TODO(turbofan): Make ES6 for-of work and remove this bailout.
       info()->function()->dont_optimize_reason() == kForOfStatement ||
       // TODO(turbofan): Make super work and remove this bailout.
       info()->function()->dont_optimize_reason() == kSuperReference ||
+      // TODO(turbofan): Make class literals work and remove this bailout.
+      info()->function()->dont_optimize_reason() == kClassLiteral ||
       // TODO(turbofan): Make OSR work and remove this bailout.
       info()->is_osr()) {
     return Handle<Code>::null();
   }
 
-  if (FLAG_turbo_stats) isolate()->GetTStatistics()->Initialize(info_);
+  ZonePool zone_pool(isolate());
+  SmartPointer<PipelineStatistics> pipeline_statistics;
+
+  if (FLAG_turbo_stats) {
+    pipeline_statistics.Reset(new PipelineStatistics(info(), &zone_pool));
+    pipeline_statistics->BeginPhaseKind("initializing");
+  }
+
+  PipelineData data(&zone_pool, info());
+  this->data_ = &data;
+  data.Initialize(pipeline_statistics.get());
+
+  BeginPhaseKind("graph creation");
 
   if (FLAG_trace_turbo) {
     OFStream os(stdout);
     os << "---------------------------------------------------\n"
-       << "Begin compiling method "
-       << info()->function()->debug_name()->ToCString().get()
-       << " using Turbofan" << endl;
+       << "Begin compiling method " << GetDebugName(info()).get()
+       << " using Turbofan" << std::endl;
+    TurboCfgFile tcf(isolate());
+    tcf << AsC1VCompilation(info());
   }
 
-  // Build the graph.
-  Graph graph(zone());
-  SourcePositionTable source_positions(&graph);
-  source_positions.AddDecorator();
-  // TODO(turbofan): there is no need to type anything during initial graph
-  // construction.  This is currently only needed for the node cache, which the
-  // typer could sweep over later.
-  Typer typer(zone());
-  MachineOperatorBuilder machine;
-  CommonOperatorBuilder common(zone());
-  JSOperatorBuilder javascript(zone());
-  JSGraph jsgraph(&graph, &common, &javascript, &typer, &machine);
-  Node* context_node;
-  {
-    PhaseStats graph_builder_stats(info(), PhaseStats::CREATE_GRAPH,
-                                   "graph builder");
-    AstGraphBuilderWithPositions graph_builder(info(), &jsgraph,
-                                               &source_positions);
-    graph_builder.CreateGraph();
-    context_node = graph_builder.GetFunctionContext();
-  }
-  {
-    PhaseStats phi_reducer_stats(info(), PhaseStats::CREATE_GRAPH,
-                                 "phi reduction");
-    PhiReducer phi_reducer;
-    GraphReducer graph_reducer(&graph);
-    graph_reducer.AddReducer(&phi_reducer);
-    graph_reducer.ReduceGraph();
-    // TODO(mstarzinger): Running reducer once ought to be enough for everyone.
-    graph_reducer.ReduceGraph();
-    graph_reducer.ReduceGraph();
+  data.source_positions()->AddDecorator();
+
+  if (FLAG_loop_assignment_analysis) {
+    Run<LoopAssignmentAnalysisPhase>();
   }
 
-  VerifyAndPrintGraph(&graph, "Initial untyped");
+  Run<GraphBuilderPhase>();
+  if (data.compilation_failed()) return Handle<Code>::null();
+  RunPrintAndVerify("Initial untyped", true);
+
+  Run<EarlyControlReductionPhase>();
+  RunPrintAndVerify("Early Control reduced", true);
 
   if (info()->is_context_specializing()) {
-    SourcePositionTable::Scope pos(&source_positions,
-                                   SourcePosition::Unknown());
     // Specialize the code to the context as aggressively as possible.
-    JSContextSpecializer spec(info(), &jsgraph, context_node);
-    spec.SpecializeToContext();
-    VerifyAndPrintGraph(&graph, "Context specialized");
+    Run<ContextSpecializerPhase>();
+    RunPrintAndVerify("Context specialized", true);
   }
 
   if (info()->is_inlining_enabled()) {
-    SourcePositionTable::Scope pos(&source_positions,
-                                   SourcePosition::Unknown());
-    JSInliner inliner(info(), &jsgraph);
-    inliner.Inline();
-    VerifyAndPrintGraph(&graph, "Inlined");
+    Run<InliningPhase>();
+    RunPrintAndVerify("Inlined", true);
   }
 
-  // Print a replay of the initial graph.
   if (FLAG_print_turbo_replay) {
-    GraphReplayPrinter::PrintReplay(&graph);
+    // Print a replay of the initial graph.
+    GraphReplayPrinter::PrintReplay(data.graph());
   }
 
+  // Bailout here in case target architecture is not supported.
+  if (!SupportedTarget()) return Handle<Code>::null();
+
   if (info()->is_typing_enabled()) {
-    {
-      // Type the graph.
-      PhaseStats typer_stats(info(), PhaseStats::CREATE_GRAPH, "typer");
-      typer.Run(&graph, info()->context());
-      VerifyAndPrintGraph(&graph, "Typed");
-    }
-    // All new nodes must be typed.
-    typer.DecorateGraph(&graph);
-    {
-      // Lower JSOperators where we can determine types.
-      PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH,
-                                "typed lowering");
-      SourcePositionTable::Scope pos(&source_positions,
-                                     SourcePosition::Unknown());
-      JSTypedLowering lowering(&jsgraph);
-      GraphReducer graph_reducer(&graph);
-      graph_reducer.AddReducer(&lowering);
-      graph_reducer.ReduceGraph();
-
-      VerifyAndPrintGraph(&graph, "Lowered typed");
-    }
-    {
-      // Lower simplified operators and insert changes.
-      PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH,
-                                "simplified lowering");
-      SourcePositionTable::Scope pos(&source_positions,
-                                     SourcePosition::Unknown());
-      SimplifiedLowering lowering(&jsgraph);
-      lowering.LowerAllNodes();
-
-      VerifyAndPrintGraph(&graph, "Lowered simplified");
-    }
-    {
-      // Lower changes that have been inserted before.
-      PhaseStats lowering_stats(info(), PhaseStats::OPTIMIZATION,
-                                "change lowering");
-      SourcePositionTable::Scope pos(&source_positions,
-                                     SourcePosition::Unknown());
-      Linkage linkage(info());
-      // TODO(turbofan): Value numbering disabled for now.
-      // ValueNumberingReducer vn_reducer(zone());
-      SimplifiedOperatorReducer simple_reducer(&jsgraph);
-      ChangeLowering lowering(&jsgraph, &linkage);
-      MachineOperatorReducer mach_reducer(&jsgraph);
-      GraphReducer graph_reducer(&graph);
-      // TODO(titzer): Figure out if we should run all reducers at once here.
-      // graph_reducer.AddReducer(&vn_reducer);
-      graph_reducer.AddReducer(&simple_reducer);
-      graph_reducer.AddReducer(&lowering);
-      graph_reducer.AddReducer(&mach_reducer);
-      graph_reducer.ReduceGraph();
-
-      VerifyAndPrintGraph(&graph, "Lowered changes");
-    }
+    // Type the graph.
+    Run<TyperPhase>();
+    RunPrintAndVerify("Typed");
   }
 
-  Handle<Code> code = Handle<Code>::null();
-  if (SupportedTarget()) {
-    {
-      // Lower any remaining generic JSOperators.
-      PhaseStats lowering_stats(info(), PhaseStats::CREATE_GRAPH,
-                                "generic lowering");
-      SourcePositionTable::Scope pos(&source_positions,
-                                     SourcePosition::Unknown());
-      JSGenericLowering lowering(info(), &jsgraph);
-      GraphReducer graph_reducer(&graph);
-      graph_reducer.AddReducer(&lowering);
-      graph_reducer.ReduceGraph();
+  BeginPhaseKind("lowering");
 
-      VerifyAndPrintGraph(&graph, "Lowered generic");
-    }
+  if (info()->is_typing_enabled()) {
+    // Lower JSOperators where we can determine types.
+    Run<TypedLoweringPhase>();
+    RunPrintAndVerify("Lowered typed");
 
-    {
-      // Compute a schedule.
-      Schedule* schedule = ComputeSchedule(&graph);
-      // Generate optimized code.
-      PhaseStats codegen_stats(info(), PhaseStats::CODEGEN, "codegen");
-      Linkage linkage(info());
-      code = GenerateCode(&linkage, &graph, schedule, &source_positions);
-      info()->SetCode(code);
-    }
+    // Lower simplified operators and insert changes.
+    Run<SimplifiedLoweringPhase>();
+    RunPrintAndVerify("Lowered simplified");
 
-    // Print optimized code.
-    v8::internal::CodeGenerator::PrintCode(code, info());
+    // Lower changes that have been inserted before.
+    Run<ChangeLoweringPhase>();
+    // // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
+    RunPrintAndVerify("Lowered changes", true);
+
+    Run<LateControlReductionPhase>();
+    RunPrintAndVerify("Late Control reduced");
   }
 
+  // Lower any remaining generic JSOperators.
+  Run<GenericLoweringPhase>();
+  // TODO(jarin, rossberg): Remove UNTYPED once machine typing works.
+  RunPrintAndVerify("Lowered generic", true);
+
+  BeginPhaseKind("block building");
+
+  data.source_positions()->RemoveDecorator();
+
+  // Compute a schedule.
+  Run<ComputeSchedulePhase>();
+
+  {
+    // Generate optimized code.
+    Linkage linkage(data.instruction_zone(), info());
+    GenerateCode(&linkage);
+  }
+  Handle<Code> code = data.code();
+  info()->SetCode(code);
+
+  // Print optimized code.
+  v8::internal::CodeGenerator::PrintCode(code, info());
+
   if (FLAG_trace_turbo) {
     OFStream os(stdout);
-    os << "--------------------------------------------------\n"
-       << "Finished compiling method "
-       << info()->function()->debug_name()->ToCString().get()
-       << " using Turbofan" << endl;
+    os << "---------------------------------------------------\n"
+       << "Finished compiling method " << GetDebugName(info()).get()
+       << " using Turbofan" << std::endl;
   }
 
   return code;
 }
 
 
-Schedule* Pipeline::ComputeSchedule(Graph* graph) {
-  PhaseStats schedule_stats(info(), PhaseStats::CODEGEN, "scheduling");
-  Schedule* schedule = Scheduler::ComputeSchedule(graph);
-  TraceSchedule(schedule);
-  if (VerifyGraphs()) ScheduleVerifier::Run(schedule);
-  return schedule;
+Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info,
+                                              Graph* graph,
+                                              Schedule* schedule) {
+  CallDescriptor* call_descriptor =
+      Linkage::ComputeIncoming(info->zone(), info);
+  return GenerateCodeForTesting(info, call_descriptor, graph, schedule);
 }
 
 
-Handle<Code> Pipeline::GenerateCodeForMachineGraph(Linkage* linkage,
-                                                   Graph* graph,
-                                                   Schedule* schedule) {
-  CHECK(SupportedBackend());
-  if (schedule == NULL) {
-    VerifyAndPrintGraph(graph, "Machine");
-    schedule = ComputeSchedule(graph);
-  }
-  TraceSchedule(schedule);
+Handle<Code> Pipeline::GenerateCodeForTesting(CallDescriptor* call_descriptor,
+                                              Graph* graph,
+                                              Schedule* schedule) {
+  CompilationInfo info(graph->zone()->isolate(), graph->zone());
+  return GenerateCodeForTesting(&info, call_descriptor, graph, schedule);
+}
 
-  SourcePositionTable source_positions(graph);
-  Handle<Code> code = GenerateCode(linkage, graph, schedule, &source_positions);
+
+Handle<Code> Pipeline::GenerateCodeForTesting(CompilationInfo* info,
+                                              CallDescriptor* call_descriptor,
+                                              Graph* graph,
+                                              Schedule* schedule) {
+  CHECK(SupportedBackend());
+  ZonePool zone_pool(info->isolate());
+  Pipeline pipeline(info);
+  PipelineData data(&zone_pool, info);
+  pipeline.data_ = &data;
+  data.InitializeTorTesting(graph, schedule);
+  if (schedule == NULL) {
+    // TODO(rossberg): Should this really be untyped?
+    pipeline.RunPrintAndVerify("Machine", true);
+    pipeline.Run<ComputeSchedulePhase>();
+  } else {
+    TraceSchedule(schedule);
+  }
+
+  Linkage linkage(info->zone(), call_descriptor);
+  pipeline.GenerateCode(&linkage);
+  Handle<Code> code = data.code();
+
 #if ENABLE_DISASSEMBLER
   if (!code.is_null() && FLAG_print_opt_code) {
-    CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
+    CodeTracer::Scope tracing_scope(info->isolate()->GetCodeTracer());
     OFStream os(tracing_scope.file());
     code->Disassemble("test code", os);
   }
@@ -360,51 +926,157 @@
 }
 
 
-Handle<Code> Pipeline::GenerateCode(Linkage* linkage, Graph* graph,
-                                    Schedule* schedule,
-                                    SourcePositionTable* source_positions) {
-  DCHECK_NOT_NULL(graph);
+bool Pipeline::AllocateRegistersForTesting(const RegisterConfiguration* config,
+                                           InstructionSequence* sequence,
+                                           bool run_verifier) {
+  CompilationInfo info(sequence->zone()->isolate(), sequence->zone());
+  ZonePool zone_pool(sequence->zone()->isolate());
+  PipelineData data(&zone_pool, &info);
+  data.InitializeTorTesting(sequence);
+  Pipeline pipeline(&info);
+  pipeline.data_ = &data;
+  pipeline.AllocateRegisters(config, run_verifier);
+  return !data.compilation_failed();
+}
+
+
+void Pipeline::GenerateCode(Linkage* linkage) {
+  PipelineData* data = this->data_;
+
   DCHECK_NOT_NULL(linkage);
-  DCHECK_NOT_NULL(schedule);
+  DCHECK_NOT_NULL(data->graph());
+  DCHECK_NOT_NULL(data->schedule());
   CHECK(SupportedBackend());
 
-  InstructionSequence sequence(linkage, graph, schedule);
+  BasicBlockProfiler::Data* profiler_data = NULL;
+  if (FLAG_turbo_profiling) {
+    profiler_data = BasicBlockInstrumentor::Instrument(info(), data->graph(),
+                                                       data->schedule());
+  }
+
+  data->InitializeInstructionSequence();
 
   // Select and schedule instructions covering the scheduled graph.
-  {
-    InstructionSelector selector(&sequence, source_positions);
-    selector.SelectInstructions();
+  Run<InstructionSelectionPhase>(linkage);
+
+  if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
+    TurboCfgFile tcf(isolate());
+    tcf << AsC1V("CodeGen", data->schedule(), data->source_positions(),
+                 data->sequence());
   }
 
-  if (FLAG_trace_turbo) {
-    OFStream os(stdout);
-    os << "----- Instruction sequence before register allocation -----\n"
-       << sequence;
-  }
+  data->DeleteGraphZone();
 
+  BeginPhaseKind("register allocation");
+
+  bool run_verifier = false;
+#ifdef DEBUG
+  run_verifier = true;
+#endif
   // Allocate registers.
-  {
-    int node_count = graph->NodeCount();
-    if (node_count > UnallocatedOperand::kMaxVirtualRegisters) {
-      linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersForValues);
-      return Handle<Code>::null();
-    }
-    RegisterAllocator allocator(&sequence);
-    if (!allocator.Allocate()) {
-      linkage->info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
-      return Handle<Code>::null();
-    }
+  AllocateRegisters(RegisterConfiguration::ArchDefault(), run_verifier);
+  if (data->compilation_failed()) {
+    info()->AbortOptimization(kNotEnoughVirtualRegistersRegalloc);
+    return;
   }
 
-  if (FLAG_trace_turbo) {
+  BeginPhaseKind("code generation");
+
+  // Optimimize jumps.
+  if (FLAG_turbo_jt) {
+    Run<JumpThreadingPhase>();
+  }
+
+  // Generate final machine code.
+  Run<GenerateCodePhase>(linkage);
+
+  if (profiler_data != NULL) {
+#if ENABLE_DISASSEMBLER
+    std::ostringstream os;
+    data->code()->Disassemble(NULL, os);
+    profiler_data->SetCode(&os);
+#endif
+  }
+}
+
+
+void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
+                                 bool run_verifier) {
+  PipelineData* data = this->data_;
+
+  int node_count = data->sequence()->VirtualRegisterCount();
+  if (node_count > UnallocatedOperand::kMaxVirtualRegisters) {
+    data->set_compilation_failed();
+    return;
+  }
+
+  // Don't track usage for this zone in compiler stats.
+  SmartPointer<Zone> verifier_zone;
+  RegisterAllocatorVerifier* verifier = nullptr;
+  if (run_verifier) {
+    verifier_zone.Reset(new Zone(info()->isolate()));
+    verifier = new (verifier_zone.get()) RegisterAllocatorVerifier(
+        verifier_zone.get(), config, data->sequence());
+  }
+
+  SmartArrayPointer<char> debug_name;
+#ifdef DEBUG
+  debug_name = GetDebugName(data->info());
+#endif
+
+  ZonePool::Scope zone_scope(data->zone_pool());
+  data->InitializeRegisterAllocator(zone_scope.zone(), config,
+                                    debug_name.get());
+
+  Run<MeetRegisterConstraintsPhase>();
+  Run<ResolvePhisPhase>();
+  Run<BuildLiveRangesPhase>();
+  if (FLAG_trace_turbo_graph) {
     OFStream os(stdout);
-    os << "----- Instruction sequence after register allocation -----\n"
-       << sequence;
+    PrintableInstructionSequence printable = {config, data->sequence()};
+    os << "----- Instruction sequence before register allocation -----\n"
+       << printable;
+  }
+  if (verifier != nullptr) {
+    CHECK(!data->register_allocator()->ExistsUseWithoutDefinition());
+  }
+  Run<AllocateGeneralRegistersPhase>();
+  if (!data->register_allocator()->AllocationOk()) {
+    data->set_compilation_failed();
+    return;
+  }
+  Run<AllocateDoubleRegistersPhase>();
+  if (!data->register_allocator()->AllocationOk()) {
+    data->set_compilation_failed();
+    return;
+  }
+  if (FLAG_turbo_reuse_spill_slots) {
+    Run<ReuseSpillSlotsPhase>();
+  }
+  Run<CommitAssignmentPhase>();
+  Run<PopulatePointerMapsPhase>();
+  Run<ConnectRangesPhase>();
+  Run<ResolveControlFlowPhase>();
+  if (FLAG_turbo_move_optimization) {
+    Run<OptimizeMovesPhase>();
   }
 
-  // Generate native sequence.
-  CodeGenerator generator(&sequence);
-  return generator.GenerateCode();
+  if (FLAG_trace_turbo_graph) {
+    OFStream os(stdout);
+    PrintableInstructionSequence printable = {config, data->sequence()};
+    os << "----- Instruction sequence after register allocation -----\n"
+       << printable;
+  }
+
+  if (verifier != nullptr) {
+    verifier->VerifyAssignment();
+    verifier->VerifyGapMoves();
+  }
+
+  if (FLAG_trace_turbo && !data->MayHaveUnverifiableGraph()) {
+    TurboCfgFile tcf(data->isolate());
+    tcf << AsC1VAllocator("CodeGen", data->register_allocator());
+  }
 }
 
 
diff --git a/src/compiler/pipeline.h b/src/compiler/pipeline.h
index 9f8241a..73053dc 100644
--- a/src/compiler/pipeline.h
+++ b/src/compiler/pipeline.h
@@ -17,10 +17,13 @@
 namespace compiler {
 
 // Clients of this interface shouldn't depend on lots of compiler internals.
+class CallDescriptor;
 class Graph;
-class Schedule;
-class SourcePositionTable;
+class InstructionSequence;
 class Linkage;
+class PipelineData;
+class RegisterConfiguration;
+class Schedule;
 
 class Pipeline {
  public:
@@ -29,10 +32,22 @@
   // Run the entire pipeline and generate a handle to a code object.
   Handle<Code> GenerateCode();
 
-  // Run the pipeline on a machine graph and generate code. If {schedule}
-  // is {NULL}, then compute a new schedule for code generation.
-  Handle<Code> GenerateCodeForMachineGraph(Linkage* linkage, Graph* graph,
-                                           Schedule* schedule = NULL);
+  // Run the pipeline on a machine graph and generate code. If {schedule} is
+  // {nullptr}, then compute a new schedule for code generation.
+  static Handle<Code> GenerateCodeForTesting(CompilationInfo* info,
+                                             Graph* graph,
+                                             Schedule* schedule = nullptr);
+
+  // Run the pipeline on a machine graph and generate code. If {schedule} is
+  // {nullptr}, then compute a new schedule for code generation.
+  static Handle<Code> GenerateCodeForTesting(CallDescriptor* call_descriptor,
+                                             Graph* graph,
+                                             Schedule* schedule = nullptr);
+
+  // Run just the register allocator phases.
+  static bool AllocateRegistersForTesting(const RegisterConfiguration* config,
+                                          InstructionSequence* sequence,
+                                          bool run_verifier);
 
   static inline bool SupportedBackend() { return V8_TURBOFAN_BACKEND != 0; }
   static inline bool SupportedTarget() { return V8_TURBOFAN_TARGET != 0; }
@@ -41,19 +56,31 @@
   static void TearDown();
 
  private:
+  static Handle<Code> GenerateCodeForTesting(CompilationInfo* info,
+                                             CallDescriptor* call_descriptor,
+                                             Graph* graph, Schedule* schedule);
+
   CompilationInfo* info_;
+  PipelineData* data_;
+
+  // Helpers for executing pipeline phases.
+  template <typename Phase>
+  void Run();
+  template <typename Phase, typename Arg0>
+  void Run(Arg0 arg_0);
 
   CompilationInfo* info() const { return info_; }
   Isolate* isolate() { return info_->isolate(); }
-  Zone* zone() { return info_->zone(); }
 
-  Schedule* ComputeSchedule(Graph* graph);
-  void VerifyAndPrintGraph(Graph* graph, const char* phase);
-  Handle<Code> GenerateCode(Linkage* linkage, Graph* graph, Schedule* schedule,
-                            SourcePositionTable* source_positions);
+  void BeginPhaseKind(const char* phase_kind);
+  void RunPrintAndVerify(const char* phase, bool untyped = false);
+  void GenerateCode(Linkage* linkage);
+  void AllocateRegisters(const RegisterConfiguration* config,
+                         bool run_verifier);
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_PIPELINE_H_
diff --git a/src/compiler/raw-machine-assembler.cc b/src/compiler/raw-machine-assembler.cc
index 7f45eb9..b93ec66 100644
--- a/src/compiler/raw-machine-assembler.cc
+++ b/src/compiler/raw-machine-assembler.cc
@@ -13,10 +13,11 @@
 
 RawMachineAssembler::RawMachineAssembler(Graph* graph,
                                          MachineSignature* machine_sig,
-                                         MachineType word)
+                                         MachineType word,
+                                         MachineOperatorBuilder::Flags flags)
     : GraphBuilder(graph),
       schedule_(new (zone()) Schedule(zone())),
-      machine_(word),
+      machine_(zone(), word, flags),
       common_(zone()),
       machine_sig_(machine_sig),
       call_descriptor_(
@@ -39,7 +40,7 @@
 Schedule* RawMachineAssembler::Export() {
   // Compute the correct codegen order.
   DCHECK(schedule_->rpo_order()->empty());
-  Scheduler::ComputeSpecialRPO(schedule_);
+  Scheduler::ComputeSpecialRPO(zone(), schedule_);
   // Invalidate MachineAssembler.
   Schedule* schedule = schedule_;
   schedule_ = NULL;
@@ -86,7 +87,8 @@
                                              CallFunctionFlags flags) {
   Callable callable = CodeFactory::CallFunction(isolate(), 0, flags);
   CallDescriptor* desc = Linkage::GetStubCallDescriptor(
-      callable.descriptor(), 1, CallDescriptor::kNeedsFrameState, zone());
+      callable.descriptor(), 1, CallDescriptor::kNeedsFrameState,
+      Operator::kNoProperties, zone());
   Node* stub_code = HeapConstant(callable.code());
   Node* call = graph()->NewNode(common()->Call(desc), stub_code, function,
                                 receiver, context, frame_state);
@@ -97,7 +99,8 @@
 
 Node* RawMachineAssembler::CallJS0(Node* function, Node* receiver,
                                    Node* context, Node* frame_state) {
-  CallDescriptor* descriptor = Linkage::GetJSCallDescriptor(1, zone());
+  CallDescriptor* descriptor =
+      Linkage::GetJSCallDescriptor(1, zone(), CallDescriptor::kNeedsFrameState);
   Node* call = graph()->NewNode(common()->Call(descriptor), function, receiver,
                                 context, frame_state);
   schedule()->AddNode(CurrentBlock(), call);
@@ -150,10 +153,10 @@
 
 
 Node* RawMachineAssembler::MakeNode(const Operator* op, int input_count,
-                                    Node** inputs) {
+                                    Node** inputs, bool incomplete) {
   DCHECK(ScheduleValid());
   DCHECK(current_block_ != NULL);
-  Node* node = graph()->NewNode(op, input_count, inputs);
+  Node* node = graph()->NewNode(op, input_count, inputs, incomplete);
   BasicBlock* block = op->opcode() == IrOpcode::kParameter ? schedule()->start()
                                                            : CurrentBlock();
   schedule()->AddNode(block, node);
diff --git a/src/compiler/raw-machine-assembler.h b/src/compiler/raw-machine-assembler.h
index a4af55a..5455814 100644
--- a/src/compiler/raw-machine-assembler.h
+++ b/src/compiler/raw-machine-assembler.h
@@ -45,8 +45,10 @@
   };
 
   RawMachineAssembler(Graph* graph, MachineSignature* machine_sig,
-                      MachineType word = kMachPtr);
-  virtual ~RawMachineAssembler() {}
+                      MachineType word = kMachPtr,
+                      MachineOperatorBuilder::Flags flags =
+                          MachineOperatorBuilder::Flag::kNoFlags);
+  ~RawMachineAssembler() OVERRIDE {}
 
   Isolate* isolate() const { return zone()->isolate(); }
   Zone* zone() const { return graph()->zone(); }
@@ -57,7 +59,7 @@
   MachineSignature* machine_sig() const { return machine_sig_; }
 
   Node* UndefinedConstant() {
-    Unique<Object> unique = Unique<Object>::CreateImmovable(
+    Unique<HeapObject> unique = Unique<HeapObject>::CreateImmovable(
         isolate()->factory()->undefined_value());
     return NewNode(common()->HeapConstant(unique));
   }
@@ -80,11 +82,14 @@
   Node* NumberConstant(double value) {
     return NewNode(common()->NumberConstant(value));
   }
+  Node* Float32Constant(float value) {
+    return NewNode(common()->Float32Constant(value));
+  }
   Node* Float64Constant(double value) {
     return NewNode(common()->Float64Constant(value));
   }
-  Node* HeapConstant(Handle<Object> object) {
-    Unique<Object> val = Unique<Object>::CreateUninitialized(object);
+  Node* HeapConstant(Handle<HeapObject> object) {
+    Unique<HeapObject> val = Unique<HeapObject>::CreateUninitialized(object);
     return NewNode(common()->HeapConstant(val));
   }
 
@@ -97,14 +102,15 @@
     return Load(rep, base, Int32Constant(0));
   }
   Node* Load(MachineType rep, Node* base, Node* index) {
-    return NewNode(machine()->Load(rep), base, index);
+    return NewNode(machine()->Load(rep), base, index, graph()->start(),
+                   graph()->start());
   }
   void Store(MachineType rep, Node* base, Node* value) {
     Store(rep, base, Int32Constant(0), value);
   }
   void Store(MachineType rep, Node* base, Node* index, Node* value) {
     NewNode(machine()->Store(StoreRepresentation(rep, kNoWriteBarrier)), base,
-            index, value);
+            index, value, graph()->start(), graph()->start());
   }
   // Arithmetic Operations.
   Node* WordAnd(Node* a, Node* b) {
@@ -222,17 +228,14 @@
   Node* Int32Mul(Node* a, Node* b) {
     return NewNode(machine()->Int32Mul(), a, b);
   }
-  Node* Int32Div(Node* a, Node* b) {
-    return NewNode(machine()->Int32Div(), a, b);
+  Node* Int32MulHigh(Node* a, Node* b) {
+    return NewNode(machine()->Int32MulHigh(), a, b);
   }
-  Node* Int32UDiv(Node* a, Node* b) {
-    return NewNode(machine()->Int32UDiv(), a, b);
+  Node* Int32Div(Node* a, Node* b) {
+    return NewNode(machine()->Int32Div(), a, b, graph()->start());
   }
   Node* Int32Mod(Node* a, Node* b) {
-    return NewNode(machine()->Int32Mod(), a, b);
-  }
-  Node* Int32UMod(Node* a, Node* b) {
-    return NewNode(machine()->Int32UMod(), a, b);
+    return NewNode(machine()->Int32Mod(), a, b, graph()->start());
   }
   Node* Int32LessThan(Node* a, Node* b) {
     return NewNode(machine()->Int32LessThan(), a, b);
@@ -240,12 +243,21 @@
   Node* Int32LessThanOrEqual(Node* a, Node* b) {
     return NewNode(machine()->Int32LessThanOrEqual(), a, b);
   }
+  Node* Uint32Div(Node* a, Node* b) {
+    return NewNode(machine()->Uint32Div(), a, b, graph()->start());
+  }
   Node* Uint32LessThan(Node* a, Node* b) {
     return NewNode(machine()->Uint32LessThan(), a, b);
   }
   Node* Uint32LessThanOrEqual(Node* a, Node* b) {
     return NewNode(machine()->Uint32LessThanOrEqual(), a, b);
   }
+  Node* Uint32Mod(Node* a, Node* b) {
+    return NewNode(machine()->Uint32Mod(), a, b, graph()->start());
+  }
+  Node* Uint32MulHigh(Node* a, Node* b) {
+    return NewNode(machine()->Uint32MulHigh(), a, b);
+  }
   Node* Int32GreaterThan(Node* a, Node* b) { return Int32LessThan(b, a); }
   Node* Int32GreaterThanOrEqual(Node* a, Node* b) {
     return Int32LessThanOrEqual(b, a);
@@ -264,15 +276,9 @@
   Node* Int64Div(Node* a, Node* b) {
     return NewNode(machine()->Int64Div(), a, b);
   }
-  Node* Int64UDiv(Node* a, Node* b) {
-    return NewNode(machine()->Int64UDiv(), a, b);
-  }
   Node* Int64Mod(Node* a, Node* b) {
     return NewNode(machine()->Int64Mod(), a, b);
   }
-  Node* Int64UMod(Node* a, Node* b) {
-    return NewNode(machine()->Int64UMod(), a, b);
-  }
   Node* Int64Neg(Node* a) { return Int64Sub(Int64Constant(0), a); }
   Node* Int64LessThan(Node* a, Node* b) {
     return NewNode(machine()->Int64LessThan(), a, b);
@@ -284,6 +290,12 @@
   Node* Int64GreaterThanOrEqual(Node* a, Node* b) {
     return Int64LessThanOrEqual(b, a);
   }
+  Node* Uint64Div(Node* a, Node* b) {
+    return NewNode(machine()->Uint64Div(), a, b);
+  }
+  Node* Uint64Mod(Node* a, Node* b) {
+    return NewNode(machine()->Uint64Mod(), a, b);
+  }
 
   // TODO(turbofan): What is this used for?
   Node* ConvertIntPtrToInt32(Node* a) {
@@ -344,6 +356,9 @@
   }
 
   // Conversions.
+  Node* ChangeFloat32ToFloat64(Node* a) {
+    return NewNode(machine()->ChangeFloat32ToFloat64(), a);
+  }
   Node* ChangeInt32ToFloat64(Node* a) {
     return NewNode(machine()->ChangeInt32ToFloat64(), a);
   }
@@ -362,12 +377,23 @@
   Node* ChangeUint32ToUint64(Node* a) {
     return NewNode(machine()->ChangeUint32ToUint64(), a);
   }
+  Node* TruncateFloat64ToFloat32(Node* a) {
+    return NewNode(machine()->TruncateFloat64ToFloat32(), a);
+  }
   Node* TruncateFloat64ToInt32(Node* a) {
     return NewNode(machine()->TruncateFloat64ToInt32(), a);
   }
   Node* TruncateInt64ToInt32(Node* a) {
     return NewNode(machine()->TruncateInt64ToInt32(), a);
   }
+  Node* Float64Floor(Node* a) { return NewNode(machine()->Float64Floor(), a); }
+  Node* Float64Ceil(Node* a) { return NewNode(machine()->Float64Ceil(), a); }
+  Node* Float64RoundTruncate(Node* a) {
+    return NewNode(machine()->Float64RoundTruncate(), a);
+  }
+  Node* Float64RoundTiesAway(Node* a) {
+    return NewNode(machine()->Float64RoundTiesAway(), a);
+  }
 
   // Parameters.
   Node* Parameter(size_t index);
@@ -404,8 +430,8 @@
   Schedule* Export();
 
  protected:
-  virtual Node* MakeNode(const Operator* op, int input_count,
-                         Node** inputs) FINAL;
+  Node* MakeNode(const Operator* op, int input_count, Node** inputs,
+                 bool incomplete) FINAL;
 
   bool ScheduleValid() { return schedule_ != NULL; }
 
diff --git a/src/compiler/register-allocator-verifier.cc b/src/compiler/register-allocator-verifier.cc
new file mode 100644
index 0000000..dabfd59
--- /dev/null
+++ b/src/compiler/register-allocator-verifier.cc
@@ -0,0 +1,460 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/instruction.h"
+#include "src/compiler/register-allocator-verifier.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+static size_t OperandCount(const Instruction* instr) {
+  return instr->InputCount() + instr->OutputCount() + instr->TempCount();
+}
+
+
+static void VerifyGapEmpty(const GapInstruction* gap) {
+  for (int i = GapInstruction::FIRST_INNER_POSITION;
+       i <= GapInstruction::LAST_INNER_POSITION; i++) {
+    GapInstruction::InnerPosition inner_pos =
+        static_cast<GapInstruction::InnerPosition>(i);
+    CHECK_EQ(NULL, gap->GetParallelMove(inner_pos));
+  }
+}
+
+
+void RegisterAllocatorVerifier::VerifyInput(
+    const OperandConstraint& constraint) {
+  CHECK_NE(kSameAsFirst, constraint.type_);
+  if (constraint.type_ != kImmediate) {
+    CHECK_NE(UnallocatedOperand::kInvalidVirtualRegister,
+             constraint.virtual_register_);
+  }
+}
+
+
+void RegisterAllocatorVerifier::VerifyTemp(
+    const OperandConstraint& constraint) {
+  CHECK_NE(kSameAsFirst, constraint.type_);
+  CHECK_NE(kImmediate, constraint.type_);
+  CHECK_NE(kConstant, constraint.type_);
+  CHECK_EQ(UnallocatedOperand::kInvalidVirtualRegister,
+           constraint.virtual_register_);
+}
+
+
+void RegisterAllocatorVerifier::VerifyOutput(
+    const OperandConstraint& constraint) {
+  CHECK_NE(kImmediate, constraint.type_);
+  CHECK_NE(UnallocatedOperand::kInvalidVirtualRegister,
+           constraint.virtual_register_);
+}
+
+
+RegisterAllocatorVerifier::RegisterAllocatorVerifier(
+    Zone* zone, const RegisterConfiguration* config,
+    const InstructionSequence* sequence)
+    : zone_(zone), config_(config), sequence_(sequence), constraints_(zone) {
+  constraints_.reserve(sequence->instructions().size());
+  // TODO(dcarney): model unique constraints.
+  // Construct OperandConstraints for all InstructionOperands, eliminating
+  // kSameAsFirst along the way.
+  for (const auto* instr : sequence->instructions()) {
+    const size_t operand_count = OperandCount(instr);
+    auto* op_constraints =
+        zone->NewArray<OperandConstraint>(static_cast<int>(operand_count));
+    size_t count = 0;
+    for (size_t i = 0; i < instr->InputCount(); ++i, ++count) {
+      BuildConstraint(instr->InputAt(i), &op_constraints[count]);
+      VerifyInput(op_constraints[count]);
+    }
+    for (size_t i = 0; i < instr->TempCount(); ++i, ++count) {
+      BuildConstraint(instr->TempAt(i), &op_constraints[count]);
+      VerifyTemp(op_constraints[count]);
+    }
+    for (size_t i = 0; i < instr->OutputCount(); ++i, ++count) {
+      BuildConstraint(instr->OutputAt(i), &op_constraints[count]);
+      if (op_constraints[count].type_ == kSameAsFirst) {
+        CHECK(instr->InputCount() > 0);
+        op_constraints[count].type_ = op_constraints[0].type_;
+        op_constraints[count].value_ = op_constraints[0].value_;
+      }
+      VerifyOutput(op_constraints[count]);
+    }
+    // All gaps should be totally unallocated at this point.
+    if (instr->IsGapMoves()) {
+      CHECK(operand_count == 0);
+      VerifyGapEmpty(GapInstruction::cast(instr));
+    }
+    InstructionConstraint instr_constraint = {instr, operand_count,
+                                              op_constraints};
+    constraints()->push_back(instr_constraint);
+  }
+}
+
+
+void RegisterAllocatorVerifier::VerifyAssignment() {
+  CHECK(sequence()->instructions().size() == constraints()->size());
+  auto instr_it = sequence()->begin();
+  for (const auto& instr_constraint : *constraints()) {
+    const auto* instr = instr_constraint.instruction_;
+    const size_t operand_count = instr_constraint.operand_constaints_size_;
+    const auto* op_constraints = instr_constraint.operand_constraints_;
+    CHECK_EQ(instr, *instr_it);
+    CHECK(operand_count == OperandCount(instr));
+    size_t count = 0;
+    for (size_t i = 0; i < instr->InputCount(); ++i, ++count) {
+      CheckConstraint(instr->InputAt(i), &op_constraints[count]);
+    }
+    for (size_t i = 0; i < instr->TempCount(); ++i, ++count) {
+      CheckConstraint(instr->TempAt(i), &op_constraints[count]);
+    }
+    for (size_t i = 0; i < instr->OutputCount(); ++i, ++count) {
+      CheckConstraint(instr->OutputAt(i), &op_constraints[count]);
+    }
+    ++instr_it;
+  }
+}
+
+
+void RegisterAllocatorVerifier::BuildConstraint(const InstructionOperand* op,
+                                                OperandConstraint* constraint) {
+  constraint->value_ = kMinInt;
+  constraint->virtual_register_ = UnallocatedOperand::kInvalidVirtualRegister;
+  if (op->IsConstant()) {
+    constraint->type_ = kConstant;
+    constraint->value_ = ConstantOperand::cast(op)->index();
+    constraint->virtual_register_ = constraint->value_;
+  } else if (op->IsImmediate()) {
+    constraint->type_ = kImmediate;
+    constraint->value_ = ImmediateOperand::cast(op)->index();
+  } else {
+    CHECK(op->IsUnallocated());
+    const auto* unallocated = UnallocatedOperand::cast(op);
+    int vreg = unallocated->virtual_register();
+    constraint->virtual_register_ = vreg;
+    if (unallocated->basic_policy() == UnallocatedOperand::FIXED_SLOT) {
+      constraint->type_ = kFixedSlot;
+      constraint->value_ = unallocated->fixed_slot_index();
+    } else {
+      switch (unallocated->extended_policy()) {
+        case UnallocatedOperand::ANY:
+          CHECK(false);
+          break;
+        case UnallocatedOperand::NONE:
+          if (sequence()->IsDouble(vreg)) {
+            constraint->type_ = kNoneDouble;
+          } else {
+            constraint->type_ = kNone;
+          }
+          break;
+        case UnallocatedOperand::FIXED_REGISTER:
+          constraint->type_ = kFixedRegister;
+          constraint->value_ = unallocated->fixed_register_index();
+          break;
+        case UnallocatedOperand::FIXED_DOUBLE_REGISTER:
+          constraint->type_ = kFixedDoubleRegister;
+          constraint->value_ = unallocated->fixed_register_index();
+          break;
+        case UnallocatedOperand::MUST_HAVE_REGISTER:
+          if (sequence()->IsDouble(vreg)) {
+            constraint->type_ = kDoubleRegister;
+          } else {
+            constraint->type_ = kRegister;
+          }
+          break;
+        case UnallocatedOperand::SAME_AS_FIRST_INPUT:
+          constraint->type_ = kSameAsFirst;
+          break;
+      }
+    }
+  }
+}
+
+
+void RegisterAllocatorVerifier::CheckConstraint(
+    const InstructionOperand* op, const OperandConstraint* constraint) {
+  switch (constraint->type_) {
+    case kConstant:
+      CHECK(op->IsConstant());
+      CHECK_EQ(op->index(), constraint->value_);
+      return;
+    case kImmediate:
+      CHECK(op->IsImmediate());
+      CHECK_EQ(op->index(), constraint->value_);
+      return;
+    case kRegister:
+      CHECK(op->IsRegister());
+      return;
+    case kFixedRegister:
+      CHECK(op->IsRegister());
+      CHECK_EQ(op->index(), constraint->value_);
+      return;
+    case kDoubleRegister:
+      CHECK(op->IsDoubleRegister());
+      return;
+    case kFixedDoubleRegister:
+      CHECK(op->IsDoubleRegister());
+      CHECK_EQ(op->index(), constraint->value_);
+      return;
+    case kFixedSlot:
+      CHECK(op->IsStackSlot());
+      CHECK_EQ(op->index(), constraint->value_);
+      return;
+    case kNone:
+      CHECK(op->IsRegister() || op->IsStackSlot());
+      return;
+    case kNoneDouble:
+      CHECK(op->IsDoubleRegister() || op->IsDoubleStackSlot());
+      return;
+    case kSameAsFirst:
+      CHECK(false);
+      return;
+  }
+}
+
+
+class RegisterAllocatorVerifier::OutgoingMapping : public ZoneObject {
+ public:
+  struct OperandLess {
+    bool operator()(const InstructionOperand* a,
+                    const InstructionOperand* b) const {
+      if (a->kind() == b->kind()) return a->index() < b->index();
+      return a->kind() < b->kind();
+    }
+  };
+
+  typedef std::map<
+      const InstructionOperand*, int, OperandLess,
+      zone_allocator<std::pair<const InstructionOperand*, const int>>>
+      LocationMap;
+
+  explicit OutgoingMapping(Zone* zone)
+      : locations_(LocationMap::key_compare(),
+                   LocationMap::allocator_type(zone)),
+        predecessor_intersection_(LocationMap::key_compare(),
+                                  LocationMap::allocator_type(zone)) {}
+
+  LocationMap* locations() { return &locations_; }
+
+  void RunPhis(const InstructionSequence* sequence,
+               const InstructionBlock* block, size_t phi_index) {
+    // This operation is only valid in edge split form.
+    size_t predecessor_index = block->predecessors()[phi_index].ToSize();
+    CHECK(sequence->instruction_blocks()[predecessor_index]->SuccessorCount() ==
+          1);
+    for (const auto* phi : block->phis()) {
+      auto input = phi->inputs()[phi_index];
+      CHECK(locations()->find(input) != locations()->end());
+      auto it = locations()->find(phi->output());
+      CHECK(it != locations()->end());
+      if (input->IsConstant()) {
+        CHECK_EQ(it->second, input->index());
+      } else {
+        CHECK_EQ(it->second, phi->operands()[phi_index]);
+      }
+      it->second = phi->virtual_register();
+    }
+  }
+
+  void RunGapInstruction(Zone* zone, const GapInstruction* gap) {
+    for (int i = GapInstruction::FIRST_INNER_POSITION;
+         i <= GapInstruction::LAST_INNER_POSITION; i++) {
+      GapInstruction::InnerPosition inner_pos =
+          static_cast<GapInstruction::InnerPosition>(i);
+      const ParallelMove* move = gap->GetParallelMove(inner_pos);
+      if (move == nullptr) continue;
+      RunParallelMoves(zone, move);
+    }
+  }
+
+  void RunParallelMoves(Zone* zone, const ParallelMove* move) {
+    // Compute outgoing mappings.
+    LocationMap to_insert((LocationMap::key_compare()),
+                          LocationMap::allocator_type(zone));
+    auto* moves = move->move_operands();
+    for (auto i = moves->begin(); i != moves->end(); ++i) {
+      if (i->IsEliminated()) continue;
+      auto cur = locations()->find(i->source());
+      CHECK(cur != locations()->end());
+      to_insert.insert(std::make_pair(i->destination(), cur->second));
+    }
+    // Drop current mappings.
+    for (auto i = moves->begin(); i != moves->end(); ++i) {
+      if (i->IsEliminated()) continue;
+      auto cur = locations()->find(i->destination());
+      if (cur != locations()->end()) locations()->erase(cur);
+    }
+    // Insert new values.
+    locations()->insert(to_insert.begin(), to_insert.end());
+  }
+
+  void Map(const InstructionOperand* op, int virtual_register) {
+    locations()->insert(std::make_pair(op, virtual_register));
+  }
+
+  void Drop(const InstructionOperand* op) {
+    auto it = locations()->find(op);
+    if (it != locations()->end()) locations()->erase(it);
+  }
+
+  void DropRegisters(const RegisterConfiguration* config) {
+    for (int i = 0; i < config->num_general_registers(); ++i) {
+      InstructionOperand op(InstructionOperand::REGISTER, i);
+      Drop(&op);
+    }
+    for (int i = 0; i < config->num_double_registers(); ++i) {
+      InstructionOperand op(InstructionOperand::DOUBLE_REGISTER, i);
+      Drop(&op);
+    }
+  }
+
+  void InitializeFromFirstPredecessor(const InstructionSequence* sequence,
+                                      const OutgoingMappings* outgoing_mappings,
+                                      const InstructionBlock* block) {
+    if (block->predecessors().empty()) return;
+    size_t predecessor_index = block->predecessors()[0].ToSize();
+    CHECK(predecessor_index < block->rpo_number().ToSize());
+    auto* incoming = outgoing_mappings->at(predecessor_index);
+    if (block->PredecessorCount() > 1) {
+      // Update incoming map with phis. The remaining phis will be checked later
+      // as their mappings are not guaranteed to exist yet.
+      incoming->RunPhis(sequence, block, 0);
+    }
+    // Now initialize outgoing mapping for this block with incoming mapping.
+    CHECK(locations_.empty());
+    locations_ = incoming->locations_;
+  }
+
+  void InitializeFromIntersection() { locations_ = predecessor_intersection_; }
+
+  void InitializeIntersection(const OutgoingMapping* incoming) {
+    CHECK(predecessor_intersection_.empty());
+    predecessor_intersection_ = incoming->locations_;
+  }
+
+  void Intersect(const OutgoingMapping* other) {
+    if (predecessor_intersection_.empty()) return;
+    auto it = predecessor_intersection_.begin();
+    OperandLess less;
+    for (const auto& o : other->locations_) {
+      while (less(it->first, o.first)) {
+        ++it;
+        if (it == predecessor_intersection_.end()) return;
+      }
+      if (it->first->Equals(o.first)) {
+        if (o.second != it->second) {
+          predecessor_intersection_.erase(it++);
+        } else {
+          ++it;
+        }
+        if (it == predecessor_intersection_.end()) return;
+      }
+    }
+  }
+
+ private:
+  LocationMap locations_;
+  LocationMap predecessor_intersection_;
+
+  DISALLOW_COPY_AND_ASSIGN(OutgoingMapping);
+};
+
+
+// Verify that all gap moves move the operands for a virtual register into the
+// correct location for every instruction.
+void RegisterAllocatorVerifier::VerifyGapMoves() {
+  typedef ZoneVector<OutgoingMapping*> OutgoingMappings;
+  OutgoingMappings outgoing_mappings(
+      static_cast<int>(sequence()->instruction_blocks().size()), nullptr,
+      zone());
+  // Construct all mappings, ignoring back edges and multiple entries.
+  ConstructOutgoingMappings(&outgoing_mappings, true);
+  // Run all remaining phis and compute the intersection of all predecessor
+  // mappings.
+  for (const auto* block : sequence()->instruction_blocks()) {
+    if (block->PredecessorCount() == 0) continue;
+    const size_t block_index = block->rpo_number().ToSize();
+    auto* mapping = outgoing_mappings[block_index];
+    bool initialized = false;
+    // Walk predecessors in reverse to ensure Intersect is correctly working.
+    // If it did nothing, the second pass would do exactly what the first pass
+    // did.
+    for (size_t phi_input = block->PredecessorCount() - 1; true; --phi_input) {
+      const size_t pred_block_index = block->predecessors()[phi_input].ToSize();
+      auto* incoming = outgoing_mappings[pred_block_index];
+      if (phi_input != 0) incoming->RunPhis(sequence(), block, phi_input);
+      if (!initialized) {
+        mapping->InitializeIntersection(incoming);
+        initialized = true;
+      } else {
+        mapping->Intersect(incoming);
+      }
+      if (phi_input == 0) break;
+    }
+  }
+  // Construct all mappings again, this time using the instersection mapping
+  // above as the incoming mapping instead of the result from the first
+  // predecessor.
+  ConstructOutgoingMappings(&outgoing_mappings, false);
+}
+
+
+void RegisterAllocatorVerifier::ConstructOutgoingMappings(
+    OutgoingMappings* outgoing_mappings, bool initial_pass) {
+  // Compute the locations of all virtual registers leaving every block, using
+  // only the first predecessor as source for the input mapping.
+  for (const auto* block : sequence()->instruction_blocks()) {
+    const size_t block_index = block->rpo_number().ToSize();
+    auto* current = outgoing_mappings->at(block_index);
+    CHECK(initial_pass == (current == nullptr));
+    // Initialize current.
+    if (!initial_pass) {
+      // Skip check second time around for blocks without multiple predecessors
+      // as we have already executed this in the initial run.
+      if (block->PredecessorCount() <= 1) continue;
+      current->InitializeFromIntersection();
+    } else {
+      current = new (zone()) OutgoingMapping(zone());
+      outgoing_mappings->at(block_index) = current;
+      // Copy outgoing values from predecessor block.
+      current->InitializeFromFirstPredecessor(sequence(), outgoing_mappings,
+                                              block);
+    }
+    // Update current with gaps and operands for all instructions in block.
+    for (int instr_index = block->code_start(); instr_index < block->code_end();
+         ++instr_index) {
+      const auto& instr_constraint = constraints_[instr_index];
+      const auto* instr = instr_constraint.instruction_;
+      const auto* op_constraints = instr_constraint.operand_constraints_;
+      size_t count = 0;
+      for (size_t i = 0; i < instr->InputCount(); ++i, ++count) {
+        if (op_constraints[count].type_ == kImmediate) continue;
+        auto it = current->locations()->find(instr->InputAt(i));
+        int virtual_register = op_constraints[count].virtual_register_;
+        CHECK(it != current->locations()->end());
+        CHECK_EQ(it->second, virtual_register);
+      }
+      for (size_t i = 0; i < instr->TempCount(); ++i, ++count) {
+        current->Drop(instr->TempAt(i));
+      }
+      if (instr->IsCall()) {
+        current->DropRegisters(config());
+      }
+      for (size_t i = 0; i < instr->OutputCount(); ++i, ++count) {
+        current->Drop(instr->OutputAt(i));
+        int virtual_register = op_constraints[count].virtual_register_;
+        current->Map(instr->OutputAt(i), virtual_register);
+      }
+      if (instr->IsGapMoves()) {
+        const auto* gap = GapInstruction::cast(instr);
+        current->RunGapInstruction(zone(), gap);
+      }
+    }
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/register-allocator-verifier.h b/src/compiler/register-allocator-verifier.h
new file mode 100644
index 0000000..4e35dc2
--- /dev/null
+++ b/src/compiler/register-allocator-verifier.h
@@ -0,0 +1,86 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_REGISTER_ALLOCATOR_VERIFIER_H_
+#define V8_REGISTER_ALLOCATOR_VERIFIER_H_
+
+#include "src/v8.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class InstructionOperand;
+class InstructionSequence;
+
+class RegisterAllocatorVerifier FINAL : public ZoneObject {
+ public:
+  RegisterAllocatorVerifier(Zone* zone, const RegisterConfiguration* config,
+                            const InstructionSequence* sequence);
+
+  void VerifyAssignment();
+  void VerifyGapMoves();
+
+ private:
+  enum ConstraintType {
+    kConstant,
+    kImmediate,
+    kRegister,
+    kFixedRegister,
+    kDoubleRegister,
+    kFixedDoubleRegister,
+    kFixedSlot,
+    kNone,
+    kNoneDouble,
+    kSameAsFirst
+  };
+
+  struct OperandConstraint {
+    ConstraintType type_;
+    int value_;  // subkind index when relevant
+    int virtual_register_;
+  };
+
+  struct InstructionConstraint {
+    const Instruction* instruction_;
+    size_t operand_constaints_size_;
+    OperandConstraint* operand_constraints_;
+  };
+
+  class OutgoingMapping;
+
+  typedef ZoneVector<InstructionConstraint> Constraints;
+  typedef ZoneVector<OutgoingMapping*> OutgoingMappings;
+
+  Zone* zone() const { return zone_; }
+  const RegisterConfiguration* config() { return config_; }
+  const InstructionSequence* sequence() const { return sequence_; }
+  Constraints* constraints() { return &constraints_; }
+
+  static void VerifyInput(const OperandConstraint& constraint);
+  static void VerifyTemp(const OperandConstraint& constraint);
+  static void VerifyOutput(const OperandConstraint& constraint);
+
+  void BuildConstraint(const InstructionOperand* op,
+                       OperandConstraint* constraint);
+  void CheckConstraint(const InstructionOperand* op,
+                       const OperandConstraint* constraint);
+
+  void ConstructOutgoingMappings(OutgoingMappings* outgoing_mappings,
+                                 bool initial_pass);
+
+  Zone* const zone_;
+  const RegisterConfiguration* config_;
+  const InstructionSequence* const sequence_;
+  Constraints constraints_;
+
+  DISALLOW_COPY_AND_ASSIGN(RegisterAllocatorVerifier);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif
diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc
index 972a904..9eb4a47 100644
--- a/src/compiler/register-allocator.cc
+++ b/src/compiler/register-allocator.cc
@@ -2,10 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/compiler/register-allocator.h"
-
 #include "src/compiler/linkage.h"
-#include "src/hydrogen.h"
+#include "src/compiler/register-allocator.h"
 #include "src/string-stream.h"
 
 namespace v8 {
@@ -22,15 +20,32 @@
 }
 
 
+static void TraceAlloc(const char* msg, ...) {
+  if (FLAG_trace_alloc) {
+    va_list arguments;
+    va_start(arguments, msg);
+    base::OS::VPrint(msg, arguments);
+    va_end(arguments);
+  }
+}
+
+
+static void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) {
+  auto it = std::find(v->begin(), v->end(), range);
+  DCHECK(it != v->end());
+  v->erase(it);
+}
+
+
 UsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand,
                          InstructionOperand* hint)
     : operand_(operand),
       hint_(hint),
       pos_(pos),
-      next_(NULL),
+      next_(nullptr),
       requires_reg_(false),
       register_beneficial_(true) {
-  if (operand_ != NULL && operand_->IsUnallocated()) {
+  if (operand_ != nullptr && operand_->IsUnallocated()) {
     const UnallocatedOperand* unalloc = UnallocatedOperand::cast(operand_);
     requires_reg_ = unalloc->HasRegisterPolicy();
     register_beneficial_ = !unalloc->HasAnyPolicy();
@@ -40,7 +55,7 @@
 
 
 bool UsePosition::HasHint() const {
-  return hint_ != NULL && !hint_->IsUnallocated();
+  return hint_ != nullptr && !hint_->IsUnallocated();
 }
 
 
@@ -52,19 +67,29 @@
 
 void UseInterval::SplitAt(LifetimePosition pos, Zone* zone) {
   DCHECK(Contains(pos) && pos.Value() != start().Value());
-  UseInterval* after = new (zone) UseInterval(pos, end_);
+  auto after = new (zone) UseInterval(pos, end_);
   after->next_ = next_;
   next_ = after;
   end_ = pos;
 }
 
 
+struct LiveRange::SpillAtDefinitionList : ZoneObject {
+  SpillAtDefinitionList(int gap_index, InstructionOperand* operand,
+                        SpillAtDefinitionList* next)
+      : gap_index(gap_index), operand(operand), next(next) {}
+  const int gap_index;
+  InstructionOperand* const operand;
+  SpillAtDefinitionList* const next;
+};
+
+
 #ifdef DEBUG
 
 
 void LiveRange::Verify() const {
   UsePosition* cur = first_pos_;
-  while (cur != NULL) {
+  while (cur != nullptr) {
     DCHECK(Start().Value() <= cur->pos().Value() &&
            cur->pos().Value() <= End().Value());
     cur = cur->next();
@@ -74,7 +99,7 @@
 
 bool LiveRange::HasOverlap(UseInterval* target) const {
   UseInterval* current_interval = first_interval_;
-  while (current_interval != NULL) {
+  while (current_interval != nullptr) {
     // Intervals overlap if the start of one is contained in the other.
     if (current_interval->Contains(target->start()) ||
         target->Contains(current_interval->start())) {
@@ -96,52 +121,87 @@
       is_non_loop_phi_(false),
       kind_(UNALLOCATED_REGISTERS),
       assigned_register_(kInvalidAssignment),
-      last_interval_(NULL),
-      first_interval_(NULL),
-      first_pos_(NULL),
-      parent_(NULL),
-      next_(NULL),
-      current_interval_(NULL),
-      last_processed_use_(NULL),
-      current_hint_operand_(NULL),
-      spill_operand_(new (zone) InstructionOperand()),
-      spill_start_index_(kMaxInt) {}
+      last_interval_(nullptr),
+      first_interval_(nullptr),
+      first_pos_(nullptr),
+      parent_(nullptr),
+      next_(nullptr),
+      current_interval_(nullptr),
+      last_processed_use_(nullptr),
+      current_hint_operand_(nullptr),
+      spill_start_index_(kMaxInt),
+      spill_type_(SpillType::kNoSpillType),
+      spill_operand_(nullptr),
+      spills_at_definition_(nullptr) {}
 
 
 void LiveRange::set_assigned_register(int reg, Zone* zone) {
   DCHECK(!HasRegisterAssigned() && !IsSpilled());
   assigned_register_ = reg;
-  ConvertOperands(zone);
+  // TODO(dcarney): stop aliasing hint operands.
+  ConvertUsesToOperand(CreateAssignedOperand(zone));
 }
 
 
-void LiveRange::MakeSpilled(Zone* zone) {
+void LiveRange::MakeSpilled() {
   DCHECK(!IsSpilled());
-  DCHECK(TopLevel()->HasAllocatedSpillOperand());
+  DCHECK(!TopLevel()->HasNoSpillType());
   spilled_ = true;
   assigned_register_ = kInvalidAssignment;
-  ConvertOperands(zone);
 }
 
 
-bool LiveRange::HasAllocatedSpillOperand() const {
-  DCHECK(spill_operand_ != NULL);
-  return !spill_operand_->IsIgnored();
+void LiveRange::SpillAtDefinition(Zone* zone, int gap_index,
+                                  InstructionOperand* operand) {
+  DCHECK(HasNoSpillType());
+  spills_at_definition_ = new (zone)
+      SpillAtDefinitionList(gap_index, operand, spills_at_definition_);
+}
+
+
+void LiveRange::CommitSpillsAtDefinition(InstructionSequence* sequence,
+                                         InstructionOperand* op) {
+  auto to_spill = TopLevel()->spills_at_definition_;
+  if (to_spill == nullptr) return;
+  auto zone = sequence->zone();
+  for (; to_spill != nullptr; to_spill = to_spill->next) {
+    auto gap = sequence->GapAt(to_spill->gap_index);
+    auto move = gap->GetOrCreateParallelMove(GapInstruction::START, zone);
+    move->AddMove(to_spill->operand, op, zone);
+  }
+  TopLevel()->spills_at_definition_ = nullptr;
 }
 
 
 void LiveRange::SetSpillOperand(InstructionOperand* operand) {
+  DCHECK(HasNoSpillType());
   DCHECK(!operand->IsUnallocated());
-  DCHECK(spill_operand_ != NULL);
-  DCHECK(spill_operand_->IsIgnored());
-  spill_operand_->ConvertTo(operand->kind(), operand->index());
+  spill_type_ = SpillType::kSpillOperand;
+  spill_operand_ = operand;
+}
+
+
+void LiveRange::SetSpillRange(SpillRange* spill_range) {
+  DCHECK(HasNoSpillType() || HasSpillRange());
+  DCHECK_NE(spill_range, nullptr);
+  spill_type_ = SpillType::kSpillRange;
+  spill_range_ = spill_range;
+}
+
+
+void LiveRange::CommitSpillOperand(InstructionOperand* operand) {
+  DCHECK(HasSpillRange());
+  DCHECK(!operand->IsUnallocated());
+  DCHECK(!IsChild());
+  spill_type_ = SpillType::kSpillOperand;
+  spill_operand_ = operand;
 }
 
 
 UsePosition* LiveRange::NextUsePosition(LifetimePosition start) {
   UsePosition* use_pos = last_processed_use_;
-  if (use_pos == NULL) use_pos = first_pos();
-  while (use_pos != NULL && use_pos->pos().Value() < start.Value()) {
+  if (use_pos == nullptr) use_pos = first_pos();
+  while (use_pos != nullptr && use_pos->pos().Value() < start.Value()) {
     use_pos = use_pos->next();
   }
   last_processed_use_ = use_pos;
@@ -152,7 +212,7 @@
 UsePosition* LiveRange::NextUsePositionRegisterIsBeneficial(
     LifetimePosition start) {
   UsePosition* pos = NextUsePosition(start);
-  while (pos != NULL && !pos->RegisterIsBeneficial()) {
+  while (pos != nullptr && !pos->RegisterIsBeneficial()) {
     pos = pos->next();
   }
   return pos;
@@ -161,9 +221,9 @@
 
 UsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial(
     LifetimePosition start) {
-  UsePosition* pos = first_pos();
-  UsePosition* prev = NULL;
-  while (pos != NULL && pos->pos().Value() < start.Value()) {
+  auto pos = first_pos();
+  UsePosition* prev = nullptr;
+  while (pos != nullptr && pos->pos().Value() < start.Value()) {
     if (pos->RegisterIsBeneficial()) prev = pos;
     pos = pos->next();
   }
@@ -173,7 +233,7 @@
 
 UsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) {
   UsePosition* pos = NextUsePosition(start);
-  while (pos != NULL && !pos->RequiresRegister()) {
+  while (pos != nullptr && !pos->RequiresRegister()) {
     pos = pos->next();
   }
   return pos;
@@ -183,15 +243,15 @@
 bool LiveRange::CanBeSpilled(LifetimePosition pos) {
   // We cannot spill a live range that has a use requiring a register
   // at the current or the immediate next position.
-  UsePosition* use_pos = NextRegisterPosition(pos);
-  if (use_pos == NULL) return true;
+  auto use_pos = NextRegisterPosition(pos);
+  if (use_pos == nullptr) return true;
   return use_pos->pos().Value() >
          pos.NextInstruction().InstructionEnd().Value();
 }
 
 
-InstructionOperand* LiveRange::CreateAssignedOperand(Zone* zone) {
-  InstructionOperand* op = NULL;
+InstructionOperand* LiveRange::CreateAssignedOperand(Zone* zone) const {
+  InstructionOperand* op = nullptr;
   if (HasRegisterAssigned()) {
     DCHECK(!IsSpilled());
     switch (Kind()) {
@@ -204,15 +264,11 @@
       default:
         UNREACHABLE();
     }
-  } else if (IsSpilled()) {
+  } else {
+    DCHECK(IsSpilled());
     DCHECK(!HasRegisterAssigned());
     op = TopLevel()->GetSpillOperand();
     DCHECK(!op->IsUnallocated());
-  } else {
-    UnallocatedOperand* unalloc =
-        new (zone) UnallocatedOperand(UnallocatedOperand::NONE);
-    unalloc->set_virtual_register(id_);
-    op = unalloc;
   }
   return op;
 }
@@ -220,9 +276,9 @@
 
 UseInterval* LiveRange::FirstSearchIntervalForPosition(
     LifetimePosition position) const {
-  if (current_interval_ == NULL) return first_interval_;
+  if (current_interval_ == nullptr) return first_interval_;
   if (current_interval_->start().Value() > position.Value()) {
-    current_interval_ = NULL;
+    current_interval_ = nullptr;
     return first_interval_;
   }
   return current_interval_;
@@ -231,11 +287,10 @@
 
 void LiveRange::AdvanceLastProcessedMarker(
     UseInterval* to_start_of, LifetimePosition but_not_past) const {
-  if (to_start_of == NULL) return;
+  if (to_start_of == nullptr) return;
   if (to_start_of->start().Value() > but_not_past.Value()) return;
-  LifetimePosition start = current_interval_ == NULL
-                               ? LifetimePosition::Invalid()
-                               : current_interval_->start();
+  auto start = current_interval_ == nullptr ? LifetimePosition::Invalid()
+                                            : current_interval_->start();
   if (to_start_of->start().Value() > start.Value()) {
     current_interval_ = to_start_of;
   }
@@ -249,7 +304,7 @@
   // Find the last interval that ends before the position. If the
   // position is contained in one of the intervals in the chain, we
   // split that interval and use the first part.
-  UseInterval* current = FirstSearchIntervalForPosition(position);
+  auto current = FirstSearchIntervalForPosition(position);
 
   // If the split position coincides with the beginning of a use interval
   // we need to split use positons in a special way.
@@ -260,12 +315,12 @@
     current = first_interval_;
   }
 
-  while (current != NULL) {
+  while (current != nullptr) {
     if (current->Contains(position)) {
       current->SplitAt(position, zone);
       break;
     }
-    UseInterval* next = current->next();
+    auto next = current->next();
     if (next->start().Value() >= position.Value()) {
       split_at_start = (next->start().Value() == position.Value());
       break;
@@ -274,8 +329,8 @@
   }
 
   // Partition original use intervals to the two live ranges.
-  UseInterval* before = current;
-  UseInterval* after = before->next();
+  auto before = current;
+  auto after = before->next();
   result->last_interval_ =
       (last_interval_ == before)
           ? after            // Only interval in the range after split.
@@ -285,39 +340,41 @@
 
   // Find the last use position before the split and the first use
   // position after it.
-  UsePosition* use_after = first_pos_;
-  UsePosition* use_before = NULL;
+  auto use_after = first_pos_;
+  UsePosition* use_before = nullptr;
   if (split_at_start) {
     // The split position coincides with the beginning of a use interval (the
     // end of a lifetime hole). Use at this position should be attributed to
     // the split child because split child owns use interval covering it.
-    while (use_after != NULL && use_after->pos().Value() < position.Value()) {
+    while (use_after != nullptr &&
+           use_after->pos().Value() < position.Value()) {
       use_before = use_after;
       use_after = use_after->next();
     }
   } else {
-    while (use_after != NULL && use_after->pos().Value() <= position.Value()) {
+    while (use_after != nullptr &&
+           use_after->pos().Value() <= position.Value()) {
       use_before = use_after;
       use_after = use_after->next();
     }
   }
 
   // Partition original use positions to the two live ranges.
-  if (use_before != NULL) {
-    use_before->next_ = NULL;
+  if (use_before != nullptr) {
+    use_before->next_ = nullptr;
   } else {
-    first_pos_ = NULL;
+    first_pos_ = nullptr;
   }
   result->first_pos_ = use_after;
 
   // Discard cached iteration state. It might be pointing
   // to the use that no longer belongs to this live range.
-  last_processed_use_ = NULL;
-  current_interval_ = NULL;
+  last_processed_use_ = nullptr;
+  current_interval_ = nullptr;
 
   // Link the new live range in the chain before any of the other
   // ranges linked from the range before the split.
-  result->parent_ = (parent_ == NULL) ? this : parent_;
+  result->parent_ = (parent_ == nullptr) ? this : parent_;
   result->kind_ = result->parent_->kind_;
   result->next_ = next_;
   next_ = result;
@@ -339,9 +396,9 @@
   LifetimePosition other_start = other->Start();
   if (start.Value() == other_start.Value()) {
     UsePosition* pos = first_pos();
-    if (pos == NULL) return false;
+    if (pos == nullptr) return false;
     UsePosition* other_pos = other->first_pos();
-    if (other_pos == NULL) return true;
+    if (other_pos == nullptr) return true;
     return pos->pos().Value() < other_pos->pos().Value();
   }
   return start.Value() < other_start.Value();
@@ -349,9 +406,8 @@
 
 
 void LiveRange::ShortenTo(LifetimePosition start) {
-  RegisterAllocator::TraceAlloc("Shorten live range %d to [%d\n", id_,
-                                start.Value());
-  DCHECK(first_interval_ != NULL);
+  TraceAlloc("Shorten live range %d to [%d\n", id_, start.Value());
+  DCHECK(first_interval_ != nullptr);
   DCHECK(first_interval_->start().Value() <= start.Value());
   DCHECK(start.Value() < first_interval_->end().Value());
   first_interval_->set_start(start);
@@ -360,10 +416,10 @@
 
 void LiveRange::EnsureInterval(LifetimePosition start, LifetimePosition end,
                                Zone* zone) {
-  RegisterAllocator::TraceAlloc("Ensure live range %d in interval [%d %d[\n",
-                                id_, start.Value(), end.Value());
-  LifetimePosition new_end = end;
-  while (first_interval_ != NULL &&
+  TraceAlloc("Ensure live range %d in interval [%d %d[\n", id_, start.Value(),
+             end.Value());
+  auto new_end = end;
+  while (first_interval_ != nullptr &&
          first_interval_->start().Value() <= end.Value()) {
     if (first_interval_->end().Value() > end.Value()) {
       new_end = first_interval_->end();
@@ -371,10 +427,10 @@
     first_interval_ = first_interval_->next();
   }
 
-  UseInterval* new_interval = new (zone) UseInterval(start, new_end);
+  auto new_interval = new (zone) UseInterval(start, new_end);
   new_interval->next_ = first_interval_;
   first_interval_ = new_interval;
-  if (new_interval->next() == NULL) {
+  if (new_interval->next() == nullptr) {
     last_interval_ = new_interval;
   }
 }
@@ -382,17 +438,17 @@
 
 void LiveRange::AddUseInterval(LifetimePosition start, LifetimePosition end,
                                Zone* zone) {
-  RegisterAllocator::TraceAlloc("Add to live range %d interval [%d %d[\n", id_,
-                                start.Value(), end.Value());
-  if (first_interval_ == NULL) {
-    UseInterval* interval = new (zone) UseInterval(start, end);
+  TraceAlloc("Add to live range %d interval [%d %d[\n", id_, start.Value(),
+             end.Value());
+  if (first_interval_ == nullptr) {
+    auto interval = new (zone) UseInterval(start, end);
     first_interval_ = interval;
     last_interval_ = interval;
   } else {
     if (end.Value() == first_interval_->start().Value()) {
       first_interval_->set_start(start);
     } else if (end.Value() < first_interval_->start().Value()) {
-      UseInterval* interval = new (zone) UseInterval(start, end);
+      auto interval = new (zone) UseInterval(start, end);
       interval->set_next(first_interval_);
       first_interval_ = interval;
     } else {
@@ -410,19 +466,18 @@
 void LiveRange::AddUsePosition(LifetimePosition pos,
                                InstructionOperand* operand,
                                InstructionOperand* hint, Zone* zone) {
-  RegisterAllocator::TraceAlloc("Add to live range %d use position %d\n", id_,
-                                pos.Value());
-  UsePosition* use_pos = new (zone) UsePosition(pos, operand, hint);
-  UsePosition* prev_hint = NULL;
-  UsePosition* prev = NULL;
-  UsePosition* current = first_pos_;
-  while (current != NULL && current->pos().Value() < pos.Value()) {
+  TraceAlloc("Add to live range %d use position %d\n", id_, pos.Value());
+  auto use_pos = new (zone) UsePosition(pos, operand, hint);
+  UsePosition* prev_hint = nullptr;
+  UsePosition* prev = nullptr;
+  auto current = first_pos_;
+  while (current != nullptr && current->pos().Value() < pos.Value()) {
     prev_hint = current->HasHint() ? current : prev_hint;
     prev = current;
     current = current->next();
   }
 
-  if (prev == NULL) {
+  if (prev == nullptr) {
     use_pos->set_next(first_pos_);
     first_pos_ = use_pos;
   } else {
@@ -430,16 +485,15 @@
     prev->next_ = use_pos;
   }
 
-  if (prev_hint == NULL && use_pos->HasHint()) {
+  if (prev_hint == nullptr && use_pos->HasHint()) {
     current_hint_operand_ = hint;
   }
 }
 
 
-void LiveRange::ConvertOperands(Zone* zone) {
-  InstructionOperand* op = CreateAssignedOperand(zone);
-  UsePosition* use_pos = first_pos();
-  while (use_pos != NULL) {
+void LiveRange::ConvertUsesToOperand(InstructionOperand* op) {
+  auto use_pos = first_pos();
+  while (use_pos != nullptr) {
     DCHECK(Start().Value() <= use_pos->pos().Value() &&
            use_pos->pos().Value() <= End().Value());
 
@@ -462,10 +516,10 @@
 
 bool LiveRange::Covers(LifetimePosition position) {
   if (!CanCover(position)) return false;
-  UseInterval* start_search = FirstSearchIntervalForPosition(position);
-  for (UseInterval* interval = start_search; interval != NULL;
+  auto start_search = FirstSearchIntervalForPosition(position);
+  for (auto interval = start_search; interval != nullptr;
        interval = interval->next()) {
-    DCHECK(interval->next() == NULL ||
+    DCHECK(interval->next() == nullptr ||
            interval->next()->start().Value() >= interval->start().Value());
     AdvanceLastProcessedMarker(interval, position);
     if (interval->Contains(position)) return true;
@@ -476,20 +530,20 @@
 
 
 LifetimePosition LiveRange::FirstIntersection(LiveRange* other) {
-  UseInterval* b = other->first_interval();
-  if (b == NULL) return LifetimePosition::Invalid();
-  LifetimePosition advance_last_processed_up_to = b->start();
-  UseInterval* a = FirstSearchIntervalForPosition(b->start());
-  while (a != NULL && b != NULL) {
+  auto b = other->first_interval();
+  if (b == nullptr) return LifetimePosition::Invalid();
+  auto advance_last_processed_up_to = b->start();
+  auto a = FirstSearchIntervalForPosition(b->start());
+  while (a != nullptr && b != nullptr) {
     if (a->start().Value() > other->End().Value()) break;
     if (b->start().Value() > End().Value()) break;
-    LifetimePosition cur_intersection = a->Intersect(b);
+    auto cur_intersection = a->Intersect(b);
     if (cur_intersection.IsValid()) {
       return cur_intersection;
     }
     if (a->start().Value() < b->start().Value()) {
       a = a->next();
-      if (a == NULL || a->start().Value() > other->End().Value()) break;
+      if (a == nullptr || a->start().Value() > other->End().Value()) break;
       AdvanceLastProcessedMarker(a, advance_last_processed_up_to);
     } else {
       b = b->next();
@@ -499,84 +553,99 @@
 }
 
 
-RegisterAllocator::RegisterAllocator(InstructionSequence* code)
-    : zone_(code->isolate()),
+RegisterAllocator::RegisterAllocator(const RegisterConfiguration* config,
+                                     Zone* zone, Frame* frame,
+                                     InstructionSequence* code,
+                                     const char* debug_name)
+    : local_zone_(zone),
+      frame_(frame),
       code_(code),
-      live_in_sets_(code->BasicBlockCount(), zone()),
-      live_ranges_(code->VirtualRegisterCount() * 2, zone()),
-      fixed_live_ranges_(NULL),
-      fixed_double_live_ranges_(NULL),
-      unhandled_live_ranges_(code->VirtualRegisterCount() * 2, zone()),
-      active_live_ranges_(8, zone()),
-      inactive_live_ranges_(8, zone()),
-      reusable_slots_(8, zone()),
+      debug_name_(debug_name),
+      config_(config),
+      phi_map_(PhiMap::key_compare(), PhiMap::allocator_type(local_zone())),
+      live_in_sets_(code->InstructionBlockCount(), nullptr, local_zone()),
+      live_ranges_(code->VirtualRegisterCount() * 2, nullptr, local_zone()),
+      fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
+                         local_zone()),
+      fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
+                                local_zone()),
+      unhandled_live_ranges_(local_zone()),
+      active_live_ranges_(local_zone()),
+      inactive_live_ranges_(local_zone()),
+      reusable_slots_(local_zone()),
+      spill_ranges_(local_zone()),
       mode_(UNALLOCATED_REGISTERS),
       num_registers_(-1),
-      allocation_ok_(true) {}
-
-
-void RegisterAllocator::InitializeLivenessAnalysis() {
-  // Initialize the live_in sets for each block to NULL.
-  int block_count = code()->BasicBlockCount();
-  live_in_sets_.Initialize(block_count, zone());
-  live_in_sets_.AddBlock(NULL, block_count, zone());
+      allocation_ok_(true) {
+  DCHECK(this->config()->num_general_registers() <=
+         RegisterConfiguration::kMaxGeneralRegisters);
+  DCHECK(this->config()->num_double_registers() <=
+         RegisterConfiguration::kMaxDoubleRegisters);
+  // TryAllocateFreeReg and AllocateBlockedReg assume this
+  // when allocating local arrays.
+  DCHECK(RegisterConfiguration::kMaxDoubleRegisters >=
+         this->config()->num_general_registers());
+  unhandled_live_ranges().reserve(
+      static_cast<size_t>(code->VirtualRegisterCount() * 2));
+  active_live_ranges().reserve(8);
+  inactive_live_ranges().reserve(8);
+  reusable_slots().reserve(8);
+  spill_ranges().reserve(8);
+  assigned_registers_ =
+      new (code_zone()) BitVector(config->num_general_registers(), code_zone());
+  assigned_double_registers_ = new (code_zone())
+      BitVector(config->num_aliased_double_registers(), code_zone());
+  frame->SetAllocatedRegisters(assigned_registers_);
+  frame->SetAllocatedDoubleRegisters(assigned_double_registers_);
 }
 
 
-BitVector* RegisterAllocator::ComputeLiveOut(BasicBlock* block) {
+BitVector* RegisterAllocator::ComputeLiveOut(const InstructionBlock* block) {
   // Compute live out for the given block, except not including backward
   // successor edges.
-  BitVector* live_out =
-      new (zone()) BitVector(code()->VirtualRegisterCount(), zone());
+  auto live_out = new (local_zone())
+      BitVector(code()->VirtualRegisterCount(), local_zone());
 
   // Process all successor blocks.
-  BasicBlock::Successors successors = block->successors();
-  for (BasicBlock::Successors::iterator i = successors.begin();
-       i != successors.end(); ++i) {
+  for (auto succ : block->successors()) {
     // Add values live on entry to the successor. Note the successor's
     // live_in will not be computed yet for backwards edges.
-    BasicBlock* successor = *i;
-    BitVector* live_in = live_in_sets_[successor->rpo_number_];
-    if (live_in != NULL) live_out->Union(*live_in);
+    auto live_in = live_in_sets_[succ.ToSize()];
+    if (live_in != nullptr) live_out->Union(*live_in);
 
     // All phi input operands corresponding to this successor edge are live
     // out from this block.
-    int index = successor->PredecessorIndexOf(block);
-    DCHECK(index >= 0);
-    DCHECK(index < static_cast<int>(successor->PredecessorCount()));
-    for (BasicBlock::const_iterator j = successor->begin();
-         j != successor->end(); ++j) {
-      Node* phi = *j;
-      if (phi->opcode() != IrOpcode::kPhi) continue;
-      Node* input = phi->InputAt(index);
-      live_out->Add(input->id());
+    auto successor = code()->InstructionBlockAt(succ);
+    size_t index = successor->PredecessorIndexOf(block->rpo_number());
+    DCHECK(index < successor->PredecessorCount());
+    for (auto phi : successor->phis()) {
+      live_out->Add(phi->operands()[index]);
     }
   }
-
   return live_out;
 }
 
 
-void RegisterAllocator::AddInitialIntervals(BasicBlock* block,
+void RegisterAllocator::AddInitialIntervals(const InstructionBlock* block,
                                             BitVector* live_out) {
   // Add an interval that includes the entire block to the live range for
   // each live_out value.
-  LifetimePosition start =
+  auto start =
       LifetimePosition::FromInstructionIndex(block->first_instruction_index());
-  LifetimePosition end = LifetimePosition::FromInstructionIndex(
-                             block->last_instruction_index()).NextInstruction();
+  auto end = LifetimePosition::FromInstructionIndex(
+                 block->last_instruction_index()).NextInstruction();
   BitVector::Iterator iterator(live_out);
   while (!iterator.Done()) {
     int operand_index = iterator.Current();
-    LiveRange* range = LiveRangeFor(operand_index);
-    range->AddUseInterval(start, end, zone());
+    auto range = LiveRangeFor(operand_index);
+    range->AddUseInterval(start, end, local_zone());
     iterator.Advance();
   }
 }
 
 
 int RegisterAllocator::FixedDoubleLiveRangeID(int index) {
-  return -index - 1 - Register::kMaxNumAllocatableRegisters;
+  return -index - 1 - config()->num_general_registers();
 }
 
 
@@ -598,7 +667,7 @@
   }
   if (is_tagged) {
     TraceAlloc("Fixed reg is tagged at %d\n", pos);
-    Instruction* instr = InstructionAt(pos);
+    auto instr = InstructionAt(pos);
     if (instr->HasPointerMap()) {
       instr->pointer_map()->RecordPointer(operand, code_zone());
     }
@@ -608,51 +677,52 @@
 
 
 LiveRange* RegisterAllocator::FixedLiveRangeFor(int index) {
-  DCHECK(index < Register::kMaxNumAllocatableRegisters);
-  LiveRange* result = fixed_live_ranges_[index];
-  if (result == NULL) {
+  DCHECK(index < config()->num_general_registers());
+  auto result = fixed_live_ranges()[index];
+  if (result == nullptr) {
     // TODO(titzer): add a utility method to allocate a new LiveRange:
     // The LiveRange object itself can go in this zone, but the
     // InstructionOperand needs
     // to go in the code zone, since it may survive register allocation.
-    result = new (zone()) LiveRange(FixedLiveRangeID(index), code_zone());
+    result = new (local_zone()) LiveRange(FixedLiveRangeID(index), code_zone());
     DCHECK(result->IsFixed());
     result->kind_ = GENERAL_REGISTERS;
     SetLiveRangeAssignedRegister(result, index);
-    fixed_live_ranges_[index] = result;
+    fixed_live_ranges()[index] = result;
   }
   return result;
 }
 
 
 LiveRange* RegisterAllocator::FixedDoubleLiveRangeFor(int index) {
-  DCHECK(index < DoubleRegister::NumAllocatableRegisters());
-  LiveRange* result = fixed_double_live_ranges_[index];
-  if (result == NULL) {
-    result = new (zone()) LiveRange(FixedDoubleLiveRangeID(index), code_zone());
+  DCHECK(index < config()->num_aliased_double_registers());
+  auto result = fixed_double_live_ranges()[index];
+  if (result == nullptr) {
+    result = new (local_zone())
+        LiveRange(FixedDoubleLiveRangeID(index), code_zone());
     DCHECK(result->IsFixed());
     result->kind_ = DOUBLE_REGISTERS;
     SetLiveRangeAssignedRegister(result, index);
-    fixed_double_live_ranges_[index] = result;
+    fixed_double_live_ranges()[index] = result;
   }
   return result;
 }
 
 
 LiveRange* RegisterAllocator::LiveRangeFor(int index) {
-  if (index >= live_ranges_.length()) {
-    live_ranges_.AddBlock(NULL, index - live_ranges_.length() + 1, zone());
+  if (index >= static_cast<int>(live_ranges().size())) {
+    live_ranges().resize(index + 1, nullptr);
   }
-  LiveRange* result = live_ranges_[index];
-  if (result == NULL) {
-    result = new (zone()) LiveRange(index, code_zone());
-    live_ranges_[index] = result;
+  auto result = live_ranges()[index];
+  if (result == nullptr) {
+    result = new (local_zone()) LiveRange(index, code_zone());
+    live_ranges()[index] = result;
   }
   return result;
 }
 
 
-GapInstruction* RegisterAllocator::GetLastGap(BasicBlock* block) {
+GapInstruction* RegisterAllocator::GetLastGap(const InstructionBlock* block) {
   int last_instruction = block->last_instruction_index();
   return code()->GapAt(last_instruction - 1);
 }
@@ -666,7 +736,7 @@
   } else if (operand->IsDoubleRegister()) {
     return FixedDoubleLiveRangeFor(operand->index());
   } else {
-    return NULL;
+    return nullptr;
   }
 }
 
@@ -674,20 +744,21 @@
 void RegisterAllocator::Define(LifetimePosition position,
                                InstructionOperand* operand,
                                InstructionOperand* hint) {
-  LiveRange* range = LiveRangeFor(operand);
-  if (range == NULL) return;
+  auto range = LiveRangeFor(operand);
+  if (range == nullptr) return;
 
   if (range->IsEmpty() || range->Start().Value() > position.Value()) {
     // Can happen if there is a definition without use.
-    range->AddUseInterval(position, position.NextInstruction(), zone());
-    range->AddUsePosition(position.NextInstruction(), NULL, NULL, zone());
+    range->AddUseInterval(position, position.NextInstruction(), local_zone());
+    range->AddUsePosition(position.NextInstruction(), nullptr, nullptr,
+                          local_zone());
   } else {
     range->ShortenTo(position);
   }
 
   if (operand->IsUnallocated()) {
-    UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
-    range->AddUsePosition(position, unalloc_operand, hint, zone());
+    auto unalloc_operand = UnallocatedOperand::cast(operand);
+    range->AddUsePosition(position, unalloc_operand, hint, local_zone());
   }
 }
 
@@ -696,48 +767,279 @@
                             LifetimePosition position,
                             InstructionOperand* operand,
                             InstructionOperand* hint) {
-  LiveRange* range = LiveRangeFor(operand);
-  if (range == NULL) return;
+  auto range = LiveRangeFor(operand);
+  if (range == nullptr) return;
   if (operand->IsUnallocated()) {
     UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
-    range->AddUsePosition(position, unalloc_operand, hint, zone());
+    range->AddUsePosition(position, unalloc_operand, hint, local_zone());
   }
-  range->AddUseInterval(block_start, position, zone());
+  range->AddUseInterval(block_start, position, local_zone());
 }
 
 
-void RegisterAllocator::AddConstraintsGapMove(int index,
-                                              InstructionOperand* from,
-                                              InstructionOperand* to) {
-  GapInstruction* gap = code()->GapAt(index);
-  ParallelMove* move =
-      gap->GetOrCreateParallelMove(GapInstruction::START, code_zone());
-  if (from->IsUnallocated()) {
-    const ZoneList<MoveOperands>* move_operands = move->move_operands();
-    for (int i = 0; i < move_operands->length(); ++i) {
-      MoveOperands cur = move_operands->at(i);
-      InstructionOperand* cur_to = cur.destination();
-      if (cur_to->IsUnallocated()) {
-        if (UnallocatedOperand::cast(cur_to)->virtual_register() ==
-            UnallocatedOperand::cast(from)->virtual_register()) {
-          move->AddMove(cur.source(), to, code_zone());
-          return;
-        }
-      }
-    }
-  }
+void RegisterAllocator::AddGapMove(int index,
+                                   GapInstruction::InnerPosition position,
+                                   InstructionOperand* from,
+                                   InstructionOperand* to) {
+  auto gap = code()->GapAt(index);
+  auto move = gap->GetOrCreateParallelMove(position, code_zone());
   move->AddMove(from, to, code_zone());
 }
 
 
-void RegisterAllocator::MeetRegisterConstraints(BasicBlock* block) {
+static bool AreUseIntervalsIntersecting(UseInterval* interval1,
+                                        UseInterval* interval2) {
+  while (interval1 != nullptr && interval2 != nullptr) {
+    if (interval1->start().Value() < interval2->start().Value()) {
+      if (interval1->end().Value() > interval2->start().Value()) {
+        return true;
+      }
+      interval1 = interval1->next();
+    } else {
+      if (interval2->end().Value() > interval1->start().Value()) {
+        return true;
+      }
+      interval2 = interval2->next();
+    }
+  }
+  return false;
+}
+
+
+SpillRange::SpillRange(LiveRange* range, Zone* zone) : live_ranges_(zone) {
+  auto src = range->first_interval();
+  UseInterval* result = nullptr;
+  UseInterval* node = nullptr;
+  // Copy the nodes
+  while (src != nullptr) {
+    auto new_node = new (zone) UseInterval(src->start(), src->end());
+    if (result == nullptr) {
+      result = new_node;
+    } else {
+      node->set_next(new_node);
+    }
+    node = new_node;
+    src = src->next();
+  }
+  use_interval_ = result;
+  live_ranges().push_back(range);
+  end_position_ = node->end();
+  DCHECK(!range->HasSpillRange());
+  range->SetSpillRange(this);
+}
+
+
+bool SpillRange::IsIntersectingWith(SpillRange* other) const {
+  if (this->use_interval_ == nullptr || other->use_interval_ == nullptr ||
+      this->End().Value() <= other->use_interval_->start().Value() ||
+      other->End().Value() <= this->use_interval_->start().Value()) {
+    return false;
+  }
+  return AreUseIntervalsIntersecting(use_interval_, other->use_interval_);
+}
+
+
+bool SpillRange::TryMerge(SpillRange* other) {
+  if (Kind() != other->Kind() || IsIntersectingWith(other)) return false;
+
+  auto max = LifetimePosition::MaxPosition();
+  if (End().Value() < other->End().Value() &&
+      other->End().Value() != max.Value()) {
+    end_position_ = other->End();
+  }
+  other->end_position_ = max;
+
+  MergeDisjointIntervals(other->use_interval_);
+  other->use_interval_ = nullptr;
+
+  for (auto range : other->live_ranges()) {
+    DCHECK(range->GetSpillRange() == other);
+    range->SetSpillRange(this);
+  }
+
+  live_ranges().insert(live_ranges().end(), other->live_ranges().begin(),
+                       other->live_ranges().end());
+  other->live_ranges().clear();
+
+  return true;
+}
+
+
+void SpillRange::SetOperand(InstructionOperand* op) {
+  for (auto range : live_ranges()) {
+    DCHECK(range->GetSpillRange() == this);
+    range->CommitSpillOperand(op);
+  }
+}
+
+
+void SpillRange::MergeDisjointIntervals(UseInterval* other) {
+  UseInterval* tail = nullptr;
+  auto current = use_interval_;
+  while (other != nullptr) {
+    // Make sure the 'current' list starts first
+    if (current == nullptr ||
+        current->start().Value() > other->start().Value()) {
+      std::swap(current, other);
+    }
+    // Check disjointness
+    DCHECK(other == nullptr ||
+           current->end().Value() <= other->start().Value());
+    // Append the 'current' node to the result accumulator and move forward
+    if (tail == nullptr) {
+      use_interval_ = current;
+    } else {
+      tail->set_next(current);
+    }
+    tail = current;
+    current = current->next();
+  }
+  // Other list is empty => we are done
+}
+
+
+void RegisterAllocator::ReuseSpillSlots() {
+  DCHECK(FLAG_turbo_reuse_spill_slots);
+
+  // Merge disjoint spill ranges
+  for (size_t i = 0; i < spill_ranges().size(); i++) {
+    auto range = spill_ranges()[i];
+    if (range->IsEmpty()) continue;
+    for (size_t j = i + 1; j < spill_ranges().size(); j++) {
+      auto other = spill_ranges()[j];
+      if (!other->IsEmpty()) {
+        range->TryMerge(other);
+      }
+    }
+  }
+
+  // Allocate slots for the merged spill ranges.
+  for (auto range : spill_ranges()) {
+    if (range->IsEmpty()) continue;
+    // Allocate a new operand referring to the spill slot.
+    auto kind = range->Kind();
+    int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS);
+    auto op_kind = kind == DOUBLE_REGISTERS
+                       ? InstructionOperand::DOUBLE_STACK_SLOT
+                       : InstructionOperand::STACK_SLOT;
+    auto op = new (code_zone()) InstructionOperand(op_kind, index);
+    range->SetOperand(op);
+  }
+}
+
+
+void RegisterAllocator::CommitAssignment() {
+  for (auto range : live_ranges()) {
+    if (range == nullptr || range->IsEmpty()) continue;
+    // Register assignments were committed in set_assigned_register.
+    if (range->HasRegisterAssigned()) continue;
+    auto assigned = range->CreateAssignedOperand(code_zone());
+    range->ConvertUsesToOperand(assigned);
+    if (range->IsSpilled()) {
+      range->CommitSpillsAtDefinition(code(), assigned);
+    }
+  }
+}
+
+
+SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) {
+  DCHECK(FLAG_turbo_reuse_spill_slots);
+  auto spill_range = new (local_zone()) SpillRange(range, local_zone());
+  spill_ranges().push_back(spill_range);
+  return spill_range;
+}
+
+
+bool RegisterAllocator::TryReuseSpillForPhi(LiveRange* range) {
+  DCHECK(FLAG_turbo_reuse_spill_slots);
+  if (range->IsChild() || !range->is_phi()) return false;
+  DCHECK(range->HasNoSpillType());
+
+  auto lookup = phi_map_.find(range->id());
+  DCHECK(lookup != phi_map_.end());
+  auto phi = lookup->second.phi;
+  auto block = lookup->second.block;
+  // Count the number of spilled operands.
+  size_t spilled_count = 0;
+  LiveRange* first_op = nullptr;
+  for (size_t i = 0; i < phi->operands().size(); i++) {
+    int op = phi->operands()[i];
+    LiveRange* op_range = LiveRangeFor(op);
+    if (op_range->GetSpillRange() == nullptr) continue;
+    auto pred = code()->InstructionBlockAt(block->predecessors()[i]);
+    auto pred_end =
+        LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
+    while (op_range != nullptr && !op_range->CanCover(pred_end)) {
+      op_range = op_range->next();
+    }
+    if (op_range != nullptr && op_range->IsSpilled()) {
+      spilled_count++;
+      if (first_op == nullptr) {
+        first_op = op_range->TopLevel();
+      }
+    }
+  }
+
+  // Only continue if more than half of the operands are spilled.
+  if (spilled_count * 2 <= phi->operands().size()) {
+    return false;
+  }
+
+  // Try to merge the spilled operands and count the number of merged spilled
+  // operands.
+  DCHECK(first_op != nullptr);
+  auto first_op_spill = first_op->GetSpillRange();
+  size_t num_merged = 1;
+  for (size_t i = 1; i < phi->operands().size(); i++) {
+    int op = phi->operands()[i];
+    auto op_range = LiveRangeFor(op);
+    auto op_spill = op_range->GetSpillRange();
+    if (op_spill != nullptr &&
+        (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill))) {
+      num_merged++;
+    }
+  }
+
+  // Only continue if enough operands could be merged to the
+  // same spill slot.
+  if (num_merged * 2 <= phi->operands().size() ||
+      AreUseIntervalsIntersecting(first_op_spill->interval(),
+                                  range->first_interval())) {
+    return false;
+  }
+
+  // If the range does not need register soon, spill it to the merged
+  // spill range.
+  auto next_pos = range->Start();
+  if (code()->IsGapAt(next_pos.InstructionIndex())) {
+    next_pos = next_pos.NextInstruction();
+  }
+  auto pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
+  if (pos == nullptr) {
+    auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel());
+    CHECK(first_op_spill->TryMerge(spill_range));
+    Spill(range);
+    return true;
+  } else if (pos->pos().Value() > range->Start().NextInstruction().Value()) {
+    auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel());
+    CHECK(first_op_spill->TryMerge(spill_range));
+    SpillBetween(range, range->Start(), pos->pos());
+    if (!AllocationOk()) return false;
+    DCHECK(UnhandledIsSorted());
+    return true;
+  }
+  return false;
+}
+
+
+void RegisterAllocator::MeetRegisterConstraints(const InstructionBlock* block) {
   int start = block->first_instruction_index();
   int end = block->last_instruction_index();
   DCHECK_NE(-1, start);
   for (int i = start; i <= end; ++i) {
     if (code()->IsGapAt(i)) {
-      Instruction* instr = NULL;
-      Instruction* prev_instr = NULL;
+      Instruction* instr = nullptr;
+      Instruction* prev_instr = nullptr;
       if (i < end) instr = InstructionAt(i + 1);
       if (i > start) prev_instr = InstructionAt(i - 1);
       MeetConstraintsBetween(prev_instr, instr, i);
@@ -753,30 +1055,30 @@
 
 
 void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
-    BasicBlock* block) {
+    const InstructionBlock* block) {
   int end = block->last_instruction_index();
-  Instruction* last_instruction = InstructionAt(end);
+  auto last_instruction = InstructionAt(end);
   for (size_t i = 0; i < last_instruction->OutputCount(); i++) {
-    InstructionOperand* output_operand = last_instruction->OutputAt(i);
+    auto output_operand = last_instruction->OutputAt(i);
     DCHECK(!output_operand->IsConstant());
-    UnallocatedOperand* output = UnallocatedOperand::cast(output_operand);
+    auto output = UnallocatedOperand::cast(output_operand);
     int output_vreg = output->virtual_register();
-    LiveRange* range = LiveRangeFor(output_vreg);
+    auto range = LiveRangeFor(output_vreg);
     bool assigned = false;
     if (output->HasFixedPolicy()) {
       AllocateFixed(output, -1, false);
       // This value is produced on the stack, we never need to spill it.
       if (output->IsStackSlot()) {
+        DCHECK(output->index() < 0);
         range->SetSpillOperand(output);
         range->SetSpillStartIndex(end);
         assigned = true;
       }
 
-      BasicBlock::Successors successors = block->successors();
-      for (BasicBlock::Successors::iterator succ = successors.begin();
-           succ != successors.end(); ++succ) {
-        DCHECK((*succ)->PredecessorCount() == 1);
-        int gap_index = (*succ)->first_instruction_index() + 1;
+      for (auto succ : block->successors()) {
+        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
+        DCHECK(successor->PredecessorCount() == 1);
+        int gap_index = successor->first_instruction_index() + 1;
         DCHECK(code()->IsGapAt(gap_index));
 
         // Create an unconstrained operand for the same virtual register
@@ -785,26 +1087,17 @@
             new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY);
         output_copy->set_virtual_register(output_vreg);
 
-        code()->AddGapMove(gap_index, output, output_copy);
+        AddGapMove(gap_index, GapInstruction::START, output, output_copy);
       }
     }
 
     if (!assigned) {
-      BasicBlock::Successors successors = block->successors();
-      for (BasicBlock::Successors::iterator succ = successors.begin();
-           succ != successors.end(); ++succ) {
-        DCHECK((*succ)->PredecessorCount() == 1);
-        int gap_index = (*succ)->first_instruction_index() + 1;
+      for (auto succ : block->successors()) {
+        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
+        DCHECK(successor->PredecessorCount() == 1);
+        int gap_index = successor->first_instruction_index() + 1;
+        range->SpillAtDefinition(local_zone(), gap_index, output);
         range->SetSpillStartIndex(gap_index);
-
-        // This move to spill operand is not a real use. Liveness analysis
-        // and splitting of live ranges do not account for it.
-        // Thus it should be inserted to a lifetime position corresponding to
-        // the instruction end.
-        GapInstruction* gap = code()->GapAt(gap_index);
-        ParallelMove* move =
-            gap->GetOrCreateParallelMove(GapInstruction::BEFORE, code_zone());
-        move->AddMove(output, range->GetSpillOperand(), code_zone());
       }
     }
   }
@@ -814,10 +1107,10 @@
 void RegisterAllocator::MeetConstraintsBetween(Instruction* first,
                                                Instruction* second,
                                                int gap_index) {
-  if (first != NULL) {
+  if (first != nullptr) {
     // Handle fixed temporaries.
     for (size_t i = 0; i < first->TempCount(); i++) {
-      UnallocatedOperand* temp = UnallocatedOperand::cast(first->TempAt(i));
+      auto temp = UnallocatedOperand::cast(first->TempAt(i));
       if (temp->HasFixedPolicy()) {
         AllocateFixed(temp, gap_index - 1, false);
       }
@@ -828,66 +1121,58 @@
       InstructionOperand* output = first->OutputAt(i);
       if (output->IsConstant()) {
         int output_vreg = output->index();
-        LiveRange* range = LiveRangeFor(output_vreg);
+        auto range = LiveRangeFor(output_vreg);
         range->SetSpillStartIndex(gap_index - 1);
         range->SetSpillOperand(output);
       } else {
-        UnallocatedOperand* first_output = UnallocatedOperand::cast(output);
-        LiveRange* range = LiveRangeFor(first_output->virtual_register());
+        auto first_output = UnallocatedOperand::cast(output);
+        auto range = LiveRangeFor(first_output->virtual_register());
         bool assigned = false;
         if (first_output->HasFixedPolicy()) {
-          UnallocatedOperand* output_copy =
-              first_output->CopyUnconstrained(code_zone());
+          auto output_copy = first_output->CopyUnconstrained(code_zone());
           bool is_tagged = HasTaggedValue(first_output->virtual_register());
           AllocateFixed(first_output, gap_index, is_tagged);
 
           // This value is produced on the stack, we never need to spill it.
           if (first_output->IsStackSlot()) {
+            DCHECK(first_output->index() < 0);
             range->SetSpillOperand(first_output);
             range->SetSpillStartIndex(gap_index - 1);
             assigned = true;
           }
-          code()->AddGapMove(gap_index, first_output, output_copy);
+          AddGapMove(gap_index, GapInstruction::START, first_output,
+                     output_copy);
         }
 
         // Make sure we add a gap move for spilling (if we have not done
         // so already).
         if (!assigned) {
+          range->SpillAtDefinition(local_zone(), gap_index, first_output);
           range->SetSpillStartIndex(gap_index);
-
-          // This move to spill operand is not a real use. Liveness analysis
-          // and splitting of live ranges do not account for it.
-          // Thus it should be inserted to a lifetime position corresponding to
-          // the instruction end.
-          GapInstruction* gap = code()->GapAt(gap_index);
-          ParallelMove* move =
-              gap->GetOrCreateParallelMove(GapInstruction::BEFORE, code_zone());
-          move->AddMove(first_output, range->GetSpillOperand(), code_zone());
         }
       }
     }
   }
 
-  if (second != NULL) {
+  if (second != nullptr) {
     // Handle fixed input operands of second instruction.
     for (size_t i = 0; i < second->InputCount(); i++) {
-      InstructionOperand* input = second->InputAt(i);
+      auto input = second->InputAt(i);
       if (input->IsImmediate()) continue;  // Ignore immediates.
-      UnallocatedOperand* cur_input = UnallocatedOperand::cast(input);
+      auto cur_input = UnallocatedOperand::cast(input);
       if (cur_input->HasFixedPolicy()) {
-        UnallocatedOperand* input_copy =
-            cur_input->CopyUnconstrained(code_zone());
+        auto input_copy = cur_input->CopyUnconstrained(code_zone());
         bool is_tagged = HasTaggedValue(cur_input->virtual_register());
         AllocateFixed(cur_input, gap_index + 1, is_tagged);
-        AddConstraintsGapMove(gap_index, input_copy, cur_input);
+        AddGapMove(gap_index, GapInstruction::END, input_copy, cur_input);
       }
     }
 
     // Handle "output same as input" for second instruction.
     for (size_t i = 0; i < second->OutputCount(); i++) {
-      InstructionOperand* output = second->OutputAt(i);
+      auto output = second->OutputAt(i);
       if (!output->IsUnallocated()) continue;
-      UnallocatedOperand* second_output = UnallocatedOperand::cast(output);
+      auto second_output = UnallocatedOperand::cast(output);
       if (second_output->HasSameAsInputPolicy()) {
         DCHECK(i == 0);  // Only valid for first output.
         UnallocatedOperand* cur_input =
@@ -895,10 +1180,9 @@
         int output_vreg = second_output->virtual_register();
         int input_vreg = cur_input->virtual_register();
 
-        UnallocatedOperand* input_copy =
-            cur_input->CopyUnconstrained(code_zone());
+        auto input_copy = cur_input->CopyUnconstrained(code_zone());
         cur_input->set_virtual_register(second_output->virtual_register());
-        AddConstraintsGapMove(gap_index, input_copy, cur_input);
+        AddGapMove(gap_index, GapInstruction::END, input_copy, cur_input);
 
         if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) {
           int index = gap_index + 1;
@@ -922,7 +1206,7 @@
 
 bool RegisterAllocator::IsOutputRegisterOf(Instruction* instr, int index) {
   for (size_t i = 0; i < instr->OutputCount(); i++) {
-    InstructionOperand* output = instr->OutputAt(i);
+    auto output = instr->OutputAt(i);
     if (output->IsRegister() && output->index() == index) return true;
   }
   return false;
@@ -932,69 +1216,72 @@
 bool RegisterAllocator::IsOutputDoubleRegisterOf(Instruction* instr,
                                                  int index) {
   for (size_t i = 0; i < instr->OutputCount(); i++) {
-    InstructionOperand* output = instr->OutputAt(i);
+    auto output = instr->OutputAt(i);
     if (output->IsDoubleRegister() && output->index() == index) return true;
   }
   return false;
 }
 
 
-void RegisterAllocator::ProcessInstructions(BasicBlock* block,
+void RegisterAllocator::ProcessInstructions(const InstructionBlock* block,
                                             BitVector* live) {
   int block_start = block->first_instruction_index();
-
-  LifetimePosition block_start_position =
+  auto block_start_position =
       LifetimePosition::FromInstructionIndex(block_start);
 
   for (int index = block->last_instruction_index(); index >= block_start;
        index--) {
-    LifetimePosition curr_position =
-        LifetimePosition::FromInstructionIndex(index);
-
-    Instruction* instr = InstructionAt(index);
-    DCHECK(instr != NULL);
+    auto curr_position = LifetimePosition::FromInstructionIndex(index);
+    auto instr = InstructionAt(index);
+    DCHECK(instr != nullptr);
     if (instr->IsGapMoves()) {
       // Process the moves of the gap instruction, making their sources live.
-      GapInstruction* gap = code()->GapAt(index);
-
-      // TODO(titzer): no need to create the parallel move if it doesn't exist.
-      ParallelMove* move =
-          gap->GetOrCreateParallelMove(GapInstruction::START, code_zone());
-      const ZoneList<MoveOperands>* move_operands = move->move_operands();
-      for (int i = 0; i < move_operands->length(); ++i) {
-        MoveOperands* cur = &move_operands->at(i);
-        if (cur->IsIgnored()) continue;
-        InstructionOperand* from = cur->source();
-        InstructionOperand* to = cur->destination();
-        InstructionOperand* hint = to;
-        if (to->IsUnallocated()) {
-          int to_vreg = UnallocatedOperand::cast(to)->virtual_register();
-          LiveRange* to_range = LiveRangeFor(to_vreg);
-          if (to_range->is_phi()) {
-            if (to_range->is_non_loop_phi()) {
-              hint = to_range->current_hint_operand();
+      auto gap = code()->GapAt(index);
+      const GapInstruction::InnerPosition kPositions[] = {
+          GapInstruction::END, GapInstruction::START};
+      for (auto position : kPositions) {
+        auto move = gap->GetParallelMove(position);
+        if (move == nullptr) continue;
+        if (position == GapInstruction::END) {
+          curr_position = curr_position.InstructionEnd();
+        } else {
+          curr_position = curr_position.InstructionStart();
+        }
+        auto move_ops = move->move_operands();
+        for (auto cur = move_ops->begin(); cur != move_ops->end(); ++cur) {
+          auto from = cur->source();
+          auto to = cur->destination();
+          auto hint = to;
+          if (to->IsUnallocated()) {
+            int to_vreg = UnallocatedOperand::cast(to)->virtual_register();
+            auto to_range = LiveRangeFor(to_vreg);
+            if (to_range->is_phi()) {
+              DCHECK(!FLAG_turbo_delay_ssa_decon);
+              if (to_range->is_non_loop_phi()) {
+                hint = to_range->current_hint_operand();
+              }
+            } else {
+              if (live->Contains(to_vreg)) {
+                Define(curr_position, to, from);
+                live->Remove(to_vreg);
+              } else {
+                cur->Eliminate();
+                continue;
+              }
             }
           } else {
-            if (live->Contains(to_vreg)) {
-              Define(curr_position, to, from);
-              live->Remove(to_vreg);
-            } else {
-              cur->Eliminate();
-              continue;
-            }
+            Define(curr_position, to, from);
           }
-        } else {
-          Define(curr_position, to, from);
-        }
-        Use(block_start_position, curr_position, from, hint);
-        if (from->IsUnallocated()) {
-          live->Add(UnallocatedOperand::cast(from)->virtual_register());
+          Use(block_start_position, curr_position, from, hint);
+          if (from->IsUnallocated()) {
+            live->Add(UnallocatedOperand::cast(from)->virtual_register());
+          }
         }
       }
     } else {
       // Process output, inputs, and temps of this non-gap instruction.
       for (size_t i = 0; i < instr->OutputCount(); i++) {
-        InstructionOperand* output = instr->OutputAt(i);
+        auto output = instr->OutputAt(i);
         if (output->IsUnallocated()) {
           int out_vreg = UnallocatedOperand::cast(output)->virtual_register();
           live->Remove(out_vreg);
@@ -1002,31 +1289,31 @@
           int out_vreg = output->index();
           live->Remove(out_vreg);
         }
-        Define(curr_position, output, NULL);
+        Define(curr_position, output, nullptr);
       }
 
       if (instr->ClobbersRegisters()) {
-        for (int i = 0; i < Register::kMaxNumAllocatableRegisters; ++i) {
+        for (int i = 0; i < config()->num_general_registers(); ++i) {
           if (!IsOutputRegisterOf(instr, i)) {
-            LiveRange* range = FixedLiveRangeFor(i);
+            auto range = FixedLiveRangeFor(i);
             range->AddUseInterval(curr_position, curr_position.InstructionEnd(),
-                                  zone());
+                                  local_zone());
           }
         }
       }
 
       if (instr->ClobbersDoubleRegisters()) {
-        for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) {
+        for (int i = 0; i < config()->num_aliased_double_registers(); ++i) {
           if (!IsOutputDoubleRegisterOf(instr, i)) {
-            LiveRange* range = FixedDoubleLiveRangeFor(i);
+            auto range = FixedDoubleLiveRangeFor(i);
             range->AddUseInterval(curr_position, curr_position.InstructionEnd(),
-                                  zone());
+                                  local_zone());
           }
         }
       }
 
       for (size_t i = 0; i < instr->InputCount(); i++) {
-        InstructionOperand* input = instr->InputAt(i);
+        auto input = instr->InputAt(i);
         if (input->IsImmediate()) continue;  // Ignore immediates.
         LifetimePosition use_pos;
         if (input->IsUnallocated() &&
@@ -1036,14 +1323,14 @@
           use_pos = curr_position.InstructionEnd();
         }
 
-        Use(block_start_position, use_pos, input, NULL);
+        Use(block_start_position, use_pos, input, nullptr);
         if (input->IsUnallocated()) {
           live->Add(UnallocatedOperand::cast(input)->virtual_register());
         }
       }
 
       for (size_t i = 0; i < instr->TempCount(); i++) {
-        InstructionOperand* temp = instr->TempAt(i);
+        auto temp = instr->TempAt(i);
         if (instr->ClobbersTemps()) {
           if (temp->IsRegister()) continue;
           if (temp->IsUnallocated()) {
@@ -1053,142 +1340,58 @@
             }
           }
         }
-        Use(block_start_position, curr_position.InstructionEnd(), temp, NULL);
-        Define(curr_position, temp, NULL);
+        Use(block_start_position, curr_position.InstructionEnd(), temp,
+            nullptr);
+        Define(curr_position, temp, nullptr);
       }
     }
   }
 }
 
 
-void RegisterAllocator::ResolvePhis(BasicBlock* block) {
-  for (BasicBlock::const_iterator i = block->begin(); i != block->end(); ++i) {
-    Node* phi = *i;
-    if (phi->opcode() != IrOpcode::kPhi) continue;
-
-    UnallocatedOperand* phi_operand =
-        new (code_zone()) UnallocatedOperand(UnallocatedOperand::NONE);
-    phi_operand->set_virtual_register(phi->id());
-
-    int j = 0;
-    Node::Inputs inputs = phi->inputs();
-    for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
-         ++iter, ++j) {
-      Node* op = *iter;
-      // TODO(mstarzinger): Use a ValueInputIterator instead.
-      if (j >= block->PredecessorCount()) continue;
-      UnallocatedOperand* operand =
-          new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY);
-      operand->set_virtual_register(op->id());
-      BasicBlock* cur_block = block->PredecessorAt(j);
-      // The gap move must be added without any special processing as in
-      // the AddConstraintsGapMove.
-      code()->AddGapMove(cur_block->last_instruction_index() - 1, operand,
-                         phi_operand);
-
-      Instruction* branch = InstructionAt(cur_block->last_instruction_index());
-      DCHECK(!branch->HasPointerMap());
-      USE(branch);
+void RegisterAllocator::ResolvePhis(const InstructionBlock* block) {
+  for (auto phi : block->phis()) {
+    if (FLAG_turbo_reuse_spill_slots) {
+      auto res = phi_map_.insert(
+          std::make_pair(phi->virtual_register(), PhiMapValue(phi, block)));
+      DCHECK(res.second);
+      USE(res);
     }
-
-    LiveRange* live_range = LiveRangeFor(phi->id());
-    BlockStartInstruction* block_start = code()->GetBlockStart(block);
-    block_start->GetOrCreateParallelMove(GapInstruction::START, code_zone())
-        ->AddMove(phi_operand, live_range->GetSpillOperand(), code_zone());
-    live_range->SetSpillStartIndex(block->first_instruction_index());
-
+    auto output = phi->output();
+    int phi_vreg = phi->virtual_register();
+    if (!FLAG_turbo_delay_ssa_decon) {
+      for (size_t i = 0; i < phi->operands().size(); ++i) {
+        InstructionBlock* cur_block =
+            code()->InstructionBlockAt(block->predecessors()[i]);
+        AddGapMove(cur_block->last_instruction_index() - 1, GapInstruction::END,
+                   phi->inputs()[i], output);
+        DCHECK(!InstructionAt(cur_block->last_instruction_index())
+                    ->HasPointerMap());
+      }
+    }
+    auto live_range = LiveRangeFor(phi_vreg);
+    int gap_index = block->first_instruction_index();
+    live_range->SpillAtDefinition(local_zone(), gap_index, output);
+    live_range->SetSpillStartIndex(gap_index);
     // We use the phi-ness of some nodes in some later heuristics.
     live_range->set_is_phi(true);
-    if (!block->IsLoopHeader()) {
-      live_range->set_is_non_loop_phi(true);
-    }
+    live_range->set_is_non_loop_phi(!block->IsLoopHeader());
   }
 }
 
 
-bool RegisterAllocator::Allocate() {
-  assigned_registers_ = new (code_zone())
-      BitVector(Register::NumAllocatableRegisters(), code_zone());
-  assigned_double_registers_ = new (code_zone())
-      BitVector(DoubleRegister::NumAllocatableRegisters(), code_zone());
-  MeetRegisterConstraints();
-  if (!AllocationOk()) return false;
-  ResolvePhis();
-  BuildLiveRanges();
-  AllocateGeneralRegisters();
-  if (!AllocationOk()) return false;
-  AllocateDoubleRegisters();
-  if (!AllocationOk()) return false;
-  PopulatePointerMaps();
-  ConnectRanges();
-  ResolveControlFlow();
-  code()->frame()->SetAllocatedRegisters(assigned_registers_);
-  code()->frame()->SetAllocatedDoubleRegisters(assigned_double_registers_);
-  return true;
-}
-
-
 void RegisterAllocator::MeetRegisterConstraints() {
-  RegisterAllocatorPhase phase("L_Register constraints", this);
-  for (int i = 0; i < code()->BasicBlockCount(); ++i) {
-    MeetRegisterConstraints(code()->BlockAt(i));
-    if (!AllocationOk()) return;
+  for (auto block : code()->instruction_blocks()) {
+    MeetRegisterConstraints(block);
   }
 }
 
 
 void RegisterAllocator::ResolvePhis() {
-  RegisterAllocatorPhase phase("L_Resolve phis", this);
-
   // Process the blocks in reverse order.
-  for (int i = code()->BasicBlockCount() - 1; i >= 0; --i) {
-    ResolvePhis(code()->BlockAt(i));
-  }
-}
-
-
-void RegisterAllocator::ResolveControlFlow(LiveRange* range, BasicBlock* block,
-                                           BasicBlock* pred) {
-  LifetimePosition pred_end =
-      LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
-  LifetimePosition cur_start =
-      LifetimePosition::FromInstructionIndex(block->first_instruction_index());
-  LiveRange* pred_cover = NULL;
-  LiveRange* cur_cover = NULL;
-  LiveRange* cur_range = range;
-  while (cur_range != NULL && (cur_cover == NULL || pred_cover == NULL)) {
-    if (cur_range->CanCover(cur_start)) {
-      DCHECK(cur_cover == NULL);
-      cur_cover = cur_range;
-    }
-    if (cur_range->CanCover(pred_end)) {
-      DCHECK(pred_cover == NULL);
-      pred_cover = cur_range;
-    }
-    cur_range = cur_range->next();
-  }
-
-  if (cur_cover->IsSpilled()) return;
-  DCHECK(pred_cover != NULL && cur_cover != NULL);
-  if (pred_cover != cur_cover) {
-    InstructionOperand* pred_op =
-        pred_cover->CreateAssignedOperand(code_zone());
-    InstructionOperand* cur_op = cur_cover->CreateAssignedOperand(code_zone());
-    if (!pred_op->Equals(cur_op)) {
-      GapInstruction* gap = NULL;
-      if (block->PredecessorCount() == 1) {
-        gap = code()->GapAt(block->first_instruction_index());
-      } else {
-        DCHECK(pred->SuccessorCount() == 1);
-        gap = GetLastGap(pred);
-
-        Instruction* branch = InstructionAt(pred->last_instruction_index());
-        DCHECK(!branch->HasPointerMap());
-        USE(branch);
-      }
-      gap->GetOrCreateParallelMove(GapInstruction::START, code_zone())
-          ->AddMove(pred_op, cur_op, code_zone());
-    }
+  for (auto i = code()->instruction_blocks().rbegin();
+       i != code()->instruction_blocks().rend(); ++i) {
+    ResolvePhis(*i);
   }
 }
 
@@ -1197,7 +1400,7 @@
     LifetimePosition pos) {
   int index = pos.InstructionIndex();
   if (code()->IsGapAt(index)) {
-    GapInstruction* gap = code()->GapAt(index);
+    auto gap = code()->GapAt(index);
     return gap->GetOrCreateParallelMove(
         pos.IsInstructionStart() ? GapInstruction::START : GapInstruction::END,
         code_zone());
@@ -1209,40 +1412,35 @@
 }
 
 
-BasicBlock* RegisterAllocator::GetBlock(LifetimePosition pos) {
-  return code()->GetBasicBlock(pos.InstructionIndex());
+const InstructionBlock* RegisterAllocator::GetInstructionBlock(
+    LifetimePosition pos) {
+  return code()->GetInstructionBlock(pos.InstructionIndex());
 }
 
 
 void RegisterAllocator::ConnectRanges() {
-  RegisterAllocatorPhase phase("L_Connect ranges", this);
-  for (int i = 0; i < live_ranges()->length(); ++i) {
-    LiveRange* first_range = live_ranges()->at(i);
-    if (first_range == NULL || first_range->parent() != NULL) continue;
-
-    LiveRange* second_range = first_range->next();
-    while (second_range != NULL) {
-      LifetimePosition pos = second_range->Start();
-
+  for (auto first_range : live_ranges()) {
+    if (first_range == nullptr || first_range->IsChild()) continue;
+    auto second_range = first_range->next();
+    while (second_range != nullptr) {
+      auto pos = second_range->Start();
       if (!second_range->IsSpilled()) {
         // Add gap move if the two live ranges touch and there is no block
         // boundary.
         if (first_range->End().Value() == pos.Value()) {
           bool should_insert = true;
           if (IsBlockBoundary(pos)) {
-            should_insert = CanEagerlyResolveControlFlow(GetBlock(pos));
+            should_insert =
+                CanEagerlyResolveControlFlow(GetInstructionBlock(pos));
           }
           if (should_insert) {
-            ParallelMove* move = GetConnectingParallelMove(pos);
-            InstructionOperand* prev_operand =
-                first_range->CreateAssignedOperand(code_zone());
-            InstructionOperand* cur_operand =
-                second_range->CreateAssignedOperand(code_zone());
+            auto move = GetConnectingParallelMove(pos);
+            auto prev_operand = first_range->CreateAssignedOperand(code_zone());
+            auto cur_operand = second_range->CreateAssignedOperand(code_zone());
             move->AddMove(prev_operand, cur_operand, code_zone());
           }
         }
       }
-
       first_range = second_range;
       second_range = second_range->next();
     }
@@ -1250,27 +1448,186 @@
 }
 
 
-bool RegisterAllocator::CanEagerlyResolveControlFlow(BasicBlock* block) const {
+bool RegisterAllocator::CanEagerlyResolveControlFlow(
+    const InstructionBlock* block) const {
   if (block->PredecessorCount() != 1) return false;
-  return block->PredecessorAt(0)->rpo_number_ == block->rpo_number_ - 1;
+  return block->predecessors()[0].IsNext(block->rpo_number());
 }
 
 
+namespace {
+
+class LiveRangeBound {
+ public:
+  explicit LiveRangeBound(const LiveRange* range)
+      : range_(range), start_(range->Start()), end_(range->End()) {
+    DCHECK(!range->IsEmpty());
+  }
+
+  bool CanCover(LifetimePosition position) {
+    return start_.Value() <= position.Value() &&
+           position.Value() < end_.Value();
+  }
+
+  const LiveRange* const range_;
+  const LifetimePosition start_;
+  const LifetimePosition end_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(LiveRangeBound);
+};
+
+
+struct FindResult {
+  const LiveRange* cur_cover_;
+  const LiveRange* pred_cover_;
+};
+
+
+class LiveRangeBoundArray {
+ public:
+  LiveRangeBoundArray() : length_(0), start_(nullptr) {}
+
+  bool ShouldInitialize() { return start_ == nullptr; }
+
+  void Initialize(Zone* zone, const LiveRange* const range) {
+    size_t length = 0;
+    for (auto i = range; i != nullptr; i = i->next()) length++;
+    start_ = zone->NewArray<LiveRangeBound>(static_cast<int>(length));
+    length_ = length;
+    auto curr = start_;
+    for (auto i = range; i != nullptr; i = i->next(), ++curr) {
+      new (curr) LiveRangeBound(i);
+    }
+  }
+
+  LiveRangeBound* Find(const LifetimePosition position) const {
+    size_t left_index = 0;
+    size_t right_index = length_;
+    while (true) {
+      size_t current_index = left_index + (right_index - left_index) / 2;
+      DCHECK(right_index > current_index);
+      auto bound = &start_[current_index];
+      if (bound->start_.Value() <= position.Value()) {
+        if (position.Value() < bound->end_.Value()) return bound;
+        DCHECK(left_index < current_index);
+        left_index = current_index;
+      } else {
+        right_index = current_index;
+      }
+    }
+  }
+
+  LiveRangeBound* FindPred(const InstructionBlock* pred) {
+    auto pred_end =
+        LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
+    return Find(pred_end);
+  }
+
+  LiveRangeBound* FindSucc(const InstructionBlock* succ) {
+    auto succ_start =
+        LifetimePosition::FromInstructionIndex(succ->first_instruction_index());
+    return Find(succ_start);
+  }
+
+  void Find(const InstructionBlock* block, const InstructionBlock* pred,
+            FindResult* result) const {
+    auto pred_end =
+        LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
+    auto bound = Find(pred_end);
+    result->pred_cover_ = bound->range_;
+    auto cur_start = LifetimePosition::FromInstructionIndex(
+        block->first_instruction_index());
+    // Common case.
+    if (bound->CanCover(cur_start)) {
+      result->cur_cover_ = bound->range_;
+      return;
+    }
+    result->cur_cover_ = Find(cur_start)->range_;
+    DCHECK(result->pred_cover_ != nullptr && result->cur_cover_ != nullptr);
+  }
+
+ private:
+  size_t length_;
+  LiveRangeBound* start_;
+
+  DISALLOW_COPY_AND_ASSIGN(LiveRangeBoundArray);
+};
+
+
+class LiveRangeFinder {
+ public:
+  explicit LiveRangeFinder(const RegisterAllocator& allocator)
+      : allocator_(allocator),
+        bounds_length_(static_cast<int>(allocator.live_ranges().size())),
+        bounds_(allocator.local_zone()->NewArray<LiveRangeBoundArray>(
+            bounds_length_)) {
+    for (int i = 0; i < bounds_length_; ++i) {
+      new (&bounds_[i]) LiveRangeBoundArray();
+    }
+  }
+
+  LiveRangeBoundArray* ArrayFor(int operand_index) {
+    DCHECK(operand_index < bounds_length_);
+    auto range = allocator_.live_ranges()[operand_index];
+    DCHECK(range != nullptr && !range->IsEmpty());
+    auto array = &bounds_[operand_index];
+    if (array->ShouldInitialize()) {
+      array->Initialize(allocator_.local_zone(), range);
+    }
+    return array;
+  }
+
+ private:
+  const RegisterAllocator& allocator_;
+  const int bounds_length_;
+  LiveRangeBoundArray* const bounds_;
+
+  DISALLOW_COPY_AND_ASSIGN(LiveRangeFinder);
+};
+
+}  // namespace
+
+
 void RegisterAllocator::ResolveControlFlow() {
-  RegisterAllocatorPhase phase("L_Resolve control flow", this);
-  for (int block_id = 1; block_id < code()->BasicBlockCount(); ++block_id) {
-    BasicBlock* block = code()->BlockAt(block_id);
+  // Lazily linearize live ranges in memory for fast lookup.
+  LiveRangeFinder finder(*this);
+  for (auto block : code()->instruction_blocks()) {
     if (CanEagerlyResolveControlFlow(block)) continue;
-    BitVector* live = live_in_sets_[block->rpo_number_];
+    if (FLAG_turbo_delay_ssa_decon) {
+      // resolve phis
+      for (auto phi : block->phis()) {
+        auto* block_bound =
+            finder.ArrayFor(phi->virtual_register())->FindSucc(block);
+        auto phi_output =
+            block_bound->range_->CreateAssignedOperand(code_zone());
+        phi->output()->ConvertTo(phi_output->kind(), phi_output->index());
+        size_t pred_index = 0;
+        for (auto pred : block->predecessors()) {
+          const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
+          auto* pred_bound = finder.ArrayFor(phi->operands()[pred_index])
+                                 ->FindPred(pred_block);
+          auto pred_op = pred_bound->range_->CreateAssignedOperand(code_zone());
+          phi->inputs()[pred_index] = pred_op;
+          ResolveControlFlow(block, phi_output, pred_block, pred_op);
+          pred_index++;
+        }
+      }
+    }
+    auto live = live_in_sets_[block->rpo_number().ToInt()];
     BitVector::Iterator iterator(live);
     while (!iterator.Done()) {
-      int operand_index = iterator.Current();
-      BasicBlock::Predecessors predecessors = block->predecessors();
-      for (BasicBlock::Predecessors::iterator i = predecessors.begin();
-           i != predecessors.end(); ++i) {
-        BasicBlock* cur = *i;
-        LiveRange* cur_range = LiveRangeFor(operand_index);
-        ResolveControlFlow(cur_range, block, cur);
+      auto* array = finder.ArrayFor(iterator.Current());
+      for (auto pred : block->predecessors()) {
+        FindResult result;
+        const auto* pred_block = code()->InstructionBlockAt(pred);
+        array->Find(block, pred_block, &result);
+        if (result.cur_cover_ == result.pred_cover_ ||
+            result.cur_cover_->IsSpilled())
+          continue;
+        auto pred_op = result.pred_cover_->CreateAssignedOperand(code_zone());
+        auto cur_op = result.cur_cover_->CreateAssignedOperand(code_zone());
+        ResolveControlFlow(block, cur_op, pred_block, pred_op);
       }
       iterator.Advance();
     }
@@ -1278,14 +1635,33 @@
 }
 
 
+void RegisterAllocator::ResolveControlFlow(const InstructionBlock* block,
+                                           InstructionOperand* cur_op,
+                                           const InstructionBlock* pred,
+                                           InstructionOperand* pred_op) {
+  if (pred_op->Equals(cur_op)) return;
+  int gap_index;
+  GapInstruction::InnerPosition position;
+  if (block->PredecessorCount() == 1) {
+    gap_index = block->first_instruction_index();
+    position = GapInstruction::START;
+  } else {
+    DCHECK(pred->SuccessorCount() == 1);
+    DCHECK(!InstructionAt(pred->last_instruction_index())->HasPointerMap());
+    gap_index = pred->last_instruction_index() - 1;
+    position = GapInstruction::END;
+  }
+  AddGapMove(gap_index, position, pred_op, cur_op);
+}
+
+
 void RegisterAllocator::BuildLiveRanges() {
-  RegisterAllocatorPhase phase("L_Build live ranges", this);
-  InitializeLivenessAnalysis();
   // Process the blocks in reverse order.
-  for (int block_id = code()->BasicBlockCount() - 1; block_id >= 0;
+  for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
        --block_id) {
-    BasicBlock* block = code()->BlockAt(block_id);
-    BitVector* live = ComputeLiveOut(block);
+    auto block =
+        code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(block_id));
+    auto live = ComputeLiveOut(block);
     // Initially consider all live_out values live for the entire block. We
     // will shorten these intervals if necessary.
     AddInitialIntervals(block, live);
@@ -1294,36 +1670,32 @@
     // live values.
     ProcessInstructions(block, live);
     // All phi output operands are killed by this block.
-    for (BasicBlock::const_iterator i = block->begin(); i != block->end();
-         ++i) {
-      Node* phi = *i;
-      if (phi->opcode() != IrOpcode::kPhi) continue;
-
+    for (auto phi : block->phis()) {
       // The live range interval already ends at the first instruction of the
       // block.
-      live->Remove(phi->id());
-
-      InstructionOperand* hint = NULL;
-      InstructionOperand* phi_operand = NULL;
-      GapInstruction* gap = GetLastGap(block->PredecessorAt(0));
-
-      // TODO(titzer): no need to create the parallel move if it doesn't exit.
-      ParallelMove* move =
-          gap->GetOrCreateParallelMove(GapInstruction::START, code_zone());
-      for (int j = 0; j < move->move_operands()->length(); ++j) {
-        InstructionOperand* to = move->move_operands()->at(j).destination();
-        if (to->IsUnallocated() &&
-            UnallocatedOperand::cast(to)->virtual_register() == phi->id()) {
-          hint = move->move_operands()->at(j).source();
-          phi_operand = to;
-          break;
+      int phi_vreg = phi->virtual_register();
+      live->Remove(phi_vreg);
+      if (!FLAG_turbo_delay_ssa_decon) {
+        InstructionOperand* hint = nullptr;
+        InstructionOperand* phi_operand = nullptr;
+        auto gap =
+            GetLastGap(code()->InstructionBlockAt(block->predecessors()[0]));
+        auto move =
+            gap->GetOrCreateParallelMove(GapInstruction::END, code_zone());
+        for (int j = 0; j < move->move_operands()->length(); ++j) {
+          auto to = move->move_operands()->at(j).destination();
+          if (to->IsUnallocated() &&
+              UnallocatedOperand::cast(to)->virtual_register() == phi_vreg) {
+            hint = move->move_operands()->at(j).source();
+            phi_operand = to;
+            break;
+          }
         }
+        DCHECK(hint != nullptr);
+        auto block_start = LifetimePosition::FromInstructionIndex(
+            block->first_instruction_index());
+        Define(block_start, phi_operand, hint);
       }
-      DCHECK(hint != NULL);
-
-      LifetimePosition block_start = LifetimePosition::FromInstructionIndex(
-          block->first_instruction_index());
-      Define(block_start, phi_operand, hint);
     }
 
     // Now live is live_in for this block except not including values live
@@ -1334,71 +1706,39 @@
       // Add a live range stretching from the first loop instruction to the last
       // for each value live on entry to the header.
       BitVector::Iterator iterator(live);
-      LifetimePosition start = LifetimePosition::FromInstructionIndex(
+      auto start = LifetimePosition::FromInstructionIndex(
           block->first_instruction_index());
-      int end_index =
-          code()->BlockAt(block->loop_end_)->last_instruction_index();
-      LifetimePosition end =
-          LifetimePosition::FromInstructionIndex(end_index).NextInstruction();
+      auto end = LifetimePosition::FromInstructionIndex(
+                     code()->LastLoopInstructionIndex(block)).NextInstruction();
       while (!iterator.Done()) {
         int operand_index = iterator.Current();
-        LiveRange* range = LiveRangeFor(operand_index);
-        range->EnsureInterval(start, end, zone());
+        auto range = LiveRangeFor(operand_index);
+        range->EnsureInterval(start, end, local_zone());
         iterator.Advance();
       }
-
       // Insert all values into the live in sets of all blocks in the loop.
-      for (int i = block->rpo_number_ + 1; i < block->loop_end_; ++i) {
+      for (int i = block->rpo_number().ToInt() + 1;
+           i < block->loop_end().ToInt(); ++i) {
         live_in_sets_[i]->Union(*live);
       }
     }
-
-#ifdef DEBUG
-    if (block_id == 0) {
-      BitVector::Iterator iterator(live);
-      bool found = false;
-      while (!iterator.Done()) {
-        found = true;
-        int operand_index = iterator.Current();
-        PrintF("Register allocator error: live v%d reached first block.\n",
-               operand_index);
-        LiveRange* range = LiveRangeFor(operand_index);
-        PrintF("  (first use is at %d)\n", range->first_pos()->pos().Value());
-        CompilationInfo* info = code()->linkage()->info();
-        if (info->IsStub()) {
-          if (info->code_stub() == NULL) {
-            PrintF("\n");
-          } else {
-            CodeStub::Major major_key = info->code_stub()->MajorKey();
-            PrintF("  (function: %s)\n", CodeStub::MajorName(major_key, false));
-          }
-        } else {
-          DCHECK(info->IsOptimizing());
-          AllowHandleDereference allow_deref;
-          PrintF("  (function: %s)\n",
-                 info->function()->debug_name()->ToCString().get());
-        }
-        iterator.Advance();
-      }
-      DCHECK(!found);
-    }
-#endif
   }
 
-  for (int i = 0; i < live_ranges_.length(); ++i) {
-    if (live_ranges_[i] != NULL) {
-      live_ranges_[i]->kind_ = RequiredRegisterKind(live_ranges_[i]->id());
-
-      // TODO(bmeurer): This is a horrible hack to make sure that for constant
-      // live ranges, every use requires the constant to be in a register.
-      // Without this hack, all uses with "any" policy would get the constant
-      // operand assigned.
-      LiveRange* range = live_ranges_[i];
-      if (range->HasAllocatedSpillOperand() &&
-          range->GetSpillOperand()->IsConstant()) {
-        for (UsePosition* pos = range->first_pos(); pos != NULL;
-             pos = pos->next_) {
-          pos->register_beneficial_ = true;
+  for (auto range : live_ranges()) {
+    if (range == nullptr) continue;
+    range->kind_ = RequiredRegisterKind(range->id());
+    // TODO(bmeurer): This is a horrible hack to make sure that for constant
+    // live ranges, every use requires the constant to be in a register.
+    // Without this hack, all uses with "any" policy would get the constant
+    // operand assigned.
+    if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) {
+      for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next_) {
+        pos->register_beneficial_ = true;
+        // TODO(dcarney): should the else case assert requires_reg_ == false?
+        // Can't mark phis as needing a register.
+        if (!code()
+                 ->InstructionAt(pos->pos().InstructionIndex())
+                 ->IsGapMoves()) {
           pos->requires_reg_ = true;
         }
       }
@@ -1407,12 +1747,30 @@
 }
 
 
+bool RegisterAllocator::ExistsUseWithoutDefinition() {
+  bool found = false;
+  BitVector::Iterator iterator(live_in_sets_[0]);
+  while (!iterator.Done()) {
+    found = true;
+    int operand_index = iterator.Current();
+    PrintF("Register allocator error: live v%d reached first block.\n",
+           operand_index);
+    LiveRange* range = LiveRangeFor(operand_index);
+    PrintF("  (first use is at %d)\n", range->first_pos()->pos().Value());
+    if (debug_name() == nullptr) {
+      PrintF("\n");
+    } else {
+      PrintF("  (function: %s)\n", debug_name());
+    }
+    iterator.Advance();
+  }
+  return found;
+}
+
+
 bool RegisterAllocator::SafePointsAreInOrder() const {
   int safe_point = 0;
-  const PointerMapDeque* pointer_maps = code()->pointer_maps();
-  for (PointerMapDeque::const_iterator it = pointer_maps->begin();
-       it != pointer_maps->end(); ++it) {
-    PointerMap* map = *it;
+  for (auto map : *code()->pointer_maps()) {
     if (safe_point > map->instruction_position()) return false;
     safe_point = map->instruction_position();
   }
@@ -1421,20 +1779,17 @@
 
 
 void RegisterAllocator::PopulatePointerMaps() {
-  RegisterAllocatorPhase phase("L_Populate pointer maps", this);
-
   DCHECK(SafePointsAreInOrder());
 
   // Iterate over all safe point positions and record a pointer
   // for all spilled live ranges at this point.
   int last_range_start = 0;
-  const PointerMapDeque* pointer_maps = code()->pointer_maps();
+  auto pointer_maps = code()->pointer_maps();
   PointerMapDeque::const_iterator first_it = pointer_maps->begin();
-  for (int range_idx = 0; range_idx < live_ranges()->length(); ++range_idx) {
-    LiveRange* range = live_ranges()->at(range_idx);
-    if (range == NULL) continue;
+  for (LiveRange* range : live_ranges()) {
+    if (range == nullptr) continue;
     // Iterate over the first parts of multi-part live ranges.
-    if (range->parent() != NULL) continue;
+    if (range->IsChild()) continue;
     // Skip non-reference values.
     if (!HasTaggedValue(range->id())) continue;
     // Skip empty live ranges.
@@ -1443,8 +1798,8 @@
     // Find the extent of the range and its children.
     int start = range->Start().InstructionIndex();
     int end = 0;
-    for (LiveRange* cur = range; cur != NULL; cur = cur->next()) {
-      LifetimePosition this_end = cur->End();
+    for (auto cur = range; cur != nullptr; cur = cur->next()) {
+      auto this_end = cur->End();
       if (this_end.InstructionIndex() > end) end = this_end.InstructionIndex();
       DCHECK(cur->Start().InstructionIndex() >= start);
     }
@@ -1457,14 +1812,13 @@
     // Step across all the safe points that are before the start of this range,
     // recording how far we step in order to save doing this for the next range.
     for (; first_it != pointer_maps->end(); ++first_it) {
-      PointerMap* map = *first_it;
+      auto map = *first_it;
       if (map->instruction_position() >= start) break;
     }
 
     // Step through the safe points to see whether they are in the range.
-    for (PointerMapDeque::const_iterator it = first_it;
-         it != pointer_maps->end(); ++it) {
-      PointerMap* map = *it;
+    for (auto it = first_it; it != pointer_maps->end(); ++it) {
+      auto map = *it;
       int safe_point = map->instruction_position();
 
       // The safe points are sorted so we can stop searching here.
@@ -1472,17 +1826,16 @@
 
       // Advance to the next active range that covers the current
       // safe point position.
-      LifetimePosition safe_point_pos =
-          LifetimePosition::FromInstructionIndex(safe_point);
-      LiveRange* cur = range;
-      while (cur != NULL && !cur->Covers(safe_point_pos)) {
+      auto safe_point_pos = LifetimePosition::FromInstructionIndex(safe_point);
+      auto cur = range;
+      while (cur != nullptr && !cur->Covers(safe_point_pos)) {
         cur = cur->next();
       }
-      if (cur == NULL) continue;
+      if (cur == nullptr) continue;
 
       // Check if the live range is spilled and the safe point is after
       // the spill position.
-      if (range->HasAllocatedSpillOperand() &&
+      if (range->HasSpillOperand() &&
           safe_point >= range->spill_start_index() &&
           !range->GetSpillOperand()->IsConstant()) {
         TraceAlloc("Pointer for range %d (spilled at %d) at safe point %d\n",
@@ -1505,76 +1858,73 @@
 
 
 void RegisterAllocator::AllocateGeneralRegisters() {
-  RegisterAllocatorPhase phase("L_Allocate general registers", this);
-  num_registers_ = Register::NumAllocatableRegisters();
+  num_registers_ = config()->num_general_registers();
   mode_ = GENERAL_REGISTERS;
   AllocateRegisters();
 }
 
 
 void RegisterAllocator::AllocateDoubleRegisters() {
-  RegisterAllocatorPhase phase("L_Allocate double registers", this);
-  num_registers_ = DoubleRegister::NumAllocatableRegisters();
+  num_registers_ = config()->num_aliased_double_registers();
   mode_ = DOUBLE_REGISTERS;
   AllocateRegisters();
 }
 
 
 void RegisterAllocator::AllocateRegisters() {
-  DCHECK(unhandled_live_ranges_.is_empty());
+  DCHECK(unhandled_live_ranges().empty());
 
-  for (int i = 0; i < live_ranges_.length(); ++i) {
-    if (live_ranges_[i] != NULL) {
-      if (live_ranges_[i]->Kind() == mode_) {
-        AddToUnhandledUnsorted(live_ranges_[i]);
-      }
+  for (auto range : live_ranges()) {
+    if (range == nullptr) continue;
+    if (range->Kind() == mode_) {
+      AddToUnhandledUnsorted(range);
     }
   }
   SortUnhandled();
   DCHECK(UnhandledIsSorted());
 
-  DCHECK(reusable_slots_.is_empty());
-  DCHECK(active_live_ranges_.is_empty());
-  DCHECK(inactive_live_ranges_.is_empty());
+  DCHECK(reusable_slots().empty());
+  DCHECK(active_live_ranges().empty());
+  DCHECK(inactive_live_ranges().empty());
 
   if (mode_ == DOUBLE_REGISTERS) {
-    for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) {
-      LiveRange* current = fixed_double_live_ranges_.at(i);
-      if (current != NULL) {
+    for (int i = 0; i < config()->num_aliased_double_registers(); ++i) {
+      auto current = fixed_double_live_ranges()[i];
+      if (current != nullptr) {
         AddToInactive(current);
       }
     }
   } else {
     DCHECK(mode_ == GENERAL_REGISTERS);
-    for (int i = 0; i < fixed_live_ranges_.length(); ++i) {
-      LiveRange* current = fixed_live_ranges_.at(i);
-      if (current != NULL) {
+    for (auto current : fixed_live_ranges()) {
+      if (current != nullptr) {
         AddToInactive(current);
       }
     }
   }
 
-  while (!unhandled_live_ranges_.is_empty()) {
+  while (!unhandled_live_ranges().empty()) {
     DCHECK(UnhandledIsSorted());
-    LiveRange* current = unhandled_live_ranges_.RemoveLast();
+    auto current = unhandled_live_ranges().back();
+    unhandled_live_ranges().pop_back();
     DCHECK(UnhandledIsSorted());
-    LifetimePosition position = current->Start();
+    auto position = current->Start();
 #ifdef DEBUG
     allocation_finger_ = position;
 #endif
     TraceAlloc("Processing interval %d start=%d\n", current->id(),
                position.Value());
 
-    if (current->HasAllocatedSpillOperand()) {
+    if (!current->HasNoSpillType()) {
       TraceAlloc("Live range %d already has a spill operand\n", current->id());
-      LifetimePosition next_pos = position;
+      auto next_pos = position;
       if (code()->IsGapAt(next_pos.InstructionIndex())) {
         next_pos = next_pos.NextInstruction();
       }
-      UsePosition* pos = current->NextUsePositionRegisterIsBeneficial(next_pos);
+      auto pos = current->NextUsePositionRegisterIsBeneficial(next_pos);
       // If the range already has a spill operand and it doesn't need a
       // register immediately, split it and spill the first part of the range.
-      if (pos == NULL) {
+      if (pos == nullptr) {
         Spill(current);
         continue;
       } else if (pos->pos().Value() >
@@ -1588,8 +1938,15 @@
       }
     }
 
-    for (int i = 0; i < active_live_ranges_.length(); ++i) {
-      LiveRange* cur_active = active_live_ranges_.at(i);
+    if (FLAG_turbo_reuse_spill_slots) {
+      if (TryReuseSpillForPhi(current)) {
+        continue;
+      }
+      if (!AllocationOk()) return;
+    }
+
+    for (size_t i = 0; i < active_live_ranges().size(); ++i) {
+      auto cur_active = active_live_ranges()[i];
       if (cur_active->End().Value() <= position.Value()) {
         ActiveToHandled(cur_active);
         --i;  // The live range was removed from the list of active live ranges.
@@ -1599,8 +1956,8 @@
       }
     }
 
-    for (int i = 0; i < inactive_live_ranges_.length(); ++i) {
-      LiveRange* cur_inactive = inactive_live_ranges_.at(i);
+    for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
+      auto cur_inactive = inactive_live_ranges()[i];
       if (cur_inactive->End().Value() <= position.Value()) {
         InactiveToHandled(cur_inactive);
         --i;  // Live range was removed from the list of inactive live ranges.
@@ -1623,27 +1980,17 @@
     }
   }
 
-  reusable_slots_.Rewind(0);
-  active_live_ranges_.Rewind(0);
-  inactive_live_ranges_.Rewind(0);
+  reusable_slots().clear();
+  active_live_ranges().clear();
+  inactive_live_ranges().clear();
 }
 
 
 const char* RegisterAllocator::RegisterName(int allocation_index) {
   if (mode_ == GENERAL_REGISTERS) {
-    return Register::AllocationIndexToString(allocation_index);
+    return config()->general_register_name(allocation_index);
   } else {
-    return DoubleRegister::AllocationIndexToString(allocation_index);
-  }
-}
-
-
-void RegisterAllocator::TraceAlloc(const char* msg, ...) {
-  if (FLAG_trace_alloc) {
-    va_list arguments;
-    va_start(arguments, msg);
-    base::OS::VPrint(msg, arguments);
-    va_end(arguments);
+    return config()->double_register_name(allocation_index);
   }
 }
 
@@ -1662,49 +2009,49 @@
 
 void RegisterAllocator::AddToActive(LiveRange* range) {
   TraceAlloc("Add live range %d to active\n", range->id());
-  active_live_ranges_.Add(range, zone());
+  active_live_ranges().push_back(range);
 }
 
 
 void RegisterAllocator::AddToInactive(LiveRange* range) {
   TraceAlloc("Add live range %d to inactive\n", range->id());
-  inactive_live_ranges_.Add(range, zone());
+  inactive_live_ranges().push_back(range);
 }
 
 
 void RegisterAllocator::AddToUnhandledSorted(LiveRange* range) {
-  if (range == NULL || range->IsEmpty()) return;
+  if (range == nullptr || range->IsEmpty()) return;
   DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled());
   DCHECK(allocation_finger_.Value() <= range->Start().Value());
-  for (int i = unhandled_live_ranges_.length() - 1; i >= 0; --i) {
-    LiveRange* cur_range = unhandled_live_ranges_.at(i);
-    if (range->ShouldBeAllocatedBefore(cur_range)) {
-      TraceAlloc("Add live range %d to unhandled at %d\n", range->id(), i + 1);
-      unhandled_live_ranges_.InsertAt(i + 1, range, zone());
-      DCHECK(UnhandledIsSorted());
-      return;
-    }
+  for (int i = static_cast<int>(unhandled_live_ranges().size() - 1); i >= 0;
+       --i) {
+    auto cur_range = unhandled_live_ranges().at(i);
+    if (!range->ShouldBeAllocatedBefore(cur_range)) continue;
+    TraceAlloc("Add live range %d to unhandled at %d\n", range->id(), i + 1);
+    auto it = unhandled_live_ranges().begin() + (i + 1);
+    unhandled_live_ranges().insert(it, range);
+    DCHECK(UnhandledIsSorted());
+    return;
   }
   TraceAlloc("Add live range %d to unhandled at start\n", range->id());
-  unhandled_live_ranges_.InsertAt(0, range, zone());
+  unhandled_live_ranges().insert(unhandled_live_ranges().begin(), range);
   DCHECK(UnhandledIsSorted());
 }
 
 
 void RegisterAllocator::AddToUnhandledUnsorted(LiveRange* range) {
-  if (range == NULL || range->IsEmpty()) return;
+  if (range == nullptr || range->IsEmpty()) return;
   DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled());
   TraceAlloc("Add live range %d to unhandled unsorted at end\n", range->id());
-  unhandled_live_ranges_.Add(range, zone());
+  unhandled_live_ranges().push_back(range);
 }
 
 
-static int UnhandledSortHelper(LiveRange* const* a, LiveRange* const* b) {
-  DCHECK(!(*a)->ShouldBeAllocatedBefore(*b) ||
-         !(*b)->ShouldBeAllocatedBefore(*a));
-  if ((*a)->ShouldBeAllocatedBefore(*b)) return 1;
-  if ((*b)->ShouldBeAllocatedBefore(*a)) return -1;
-  return (*a)->id() - (*b)->id();
+static bool UnhandledSortHelper(LiveRange* a, LiveRange* b) {
+  DCHECK(!a->ShouldBeAllocatedBefore(b) || !b->ShouldBeAllocatedBefore(a));
+  if (a->ShouldBeAllocatedBefore(b)) return false;
+  if (b->ShouldBeAllocatedBefore(a)) return true;
+  return a->id() < b->id();
 }
 
 
@@ -1713,15 +2060,16 @@
 // algorithm because it is efficient to remove elements from the end.
 void RegisterAllocator::SortUnhandled() {
   TraceAlloc("Sort unhandled\n");
-  unhandled_live_ranges_.Sort(&UnhandledSortHelper);
+  std::sort(unhandled_live_ranges().begin(), unhandled_live_ranges().end(),
+            &UnhandledSortHelper);
 }
 
 
 bool RegisterAllocator::UnhandledIsSorted() {
-  int len = unhandled_live_ranges_.length();
-  for (int i = 1; i < len; i++) {
-    LiveRange* a = unhandled_live_ranges_.at(i - 1);
-    LiveRange* b = unhandled_live_ranges_.at(i);
+  size_t len = unhandled_live_ranges().size();
+  for (size_t i = 1; i < len; i++) {
+    auto a = unhandled_live_ranges().at(i - 1);
+    auto b = unhandled_live_ranges().at(i);
     if (a->Start().Value() < b->Start().Value()) return false;
   }
   return true;
@@ -1729,95 +2077,81 @@
 
 
 void RegisterAllocator::FreeSpillSlot(LiveRange* range) {
+  DCHECK(!FLAG_turbo_reuse_spill_slots);
   // Check that we are the last range.
-  if (range->next() != NULL) return;
-
-  if (!range->TopLevel()->HasAllocatedSpillOperand()) return;
-
-  InstructionOperand* spill_operand = range->TopLevel()->GetSpillOperand();
+  if (range->next() != nullptr) return;
+  if (!range->TopLevel()->HasSpillOperand()) return;
+  auto spill_operand = range->TopLevel()->GetSpillOperand();
   if (spill_operand->IsConstant()) return;
   if (spill_operand->index() >= 0) {
-    reusable_slots_.Add(range, zone());
+    reusable_slots().push_back(range);
   }
 }
 
 
 InstructionOperand* RegisterAllocator::TryReuseSpillSlot(LiveRange* range) {
-  if (reusable_slots_.is_empty()) return NULL;
-  if (reusable_slots_.first()->End().Value() >
+  DCHECK(!FLAG_turbo_reuse_spill_slots);
+  if (reusable_slots().empty()) return nullptr;
+  if (reusable_slots().front()->End().Value() >
       range->TopLevel()->Start().Value()) {
-    return NULL;
+    return nullptr;
   }
-  InstructionOperand* result =
-      reusable_slots_.first()->TopLevel()->GetSpillOperand();
-  reusable_slots_.Remove(0);
+  auto result = reusable_slots().front()->TopLevel()->GetSpillOperand();
+  reusable_slots().erase(reusable_slots().begin());
   return result;
 }
 
 
 void RegisterAllocator::ActiveToHandled(LiveRange* range) {
-  DCHECK(active_live_ranges_.Contains(range));
-  active_live_ranges_.RemoveElement(range);
+  RemoveElement(&active_live_ranges(), range);
   TraceAlloc("Moving live range %d from active to handled\n", range->id());
-  FreeSpillSlot(range);
+  if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range);
 }
 
 
 void RegisterAllocator::ActiveToInactive(LiveRange* range) {
-  DCHECK(active_live_ranges_.Contains(range));
-  active_live_ranges_.RemoveElement(range);
-  inactive_live_ranges_.Add(range, zone());
+  RemoveElement(&active_live_ranges(), range);
+  inactive_live_ranges().push_back(range);
   TraceAlloc("Moving live range %d from active to inactive\n", range->id());
 }
 
 
 void RegisterAllocator::InactiveToHandled(LiveRange* range) {
-  DCHECK(inactive_live_ranges_.Contains(range));
-  inactive_live_ranges_.RemoveElement(range);
+  RemoveElement(&inactive_live_ranges(), range);
   TraceAlloc("Moving live range %d from inactive to handled\n", range->id());
-  FreeSpillSlot(range);
+  if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range);
 }
 
 
 void RegisterAllocator::InactiveToActive(LiveRange* range) {
-  DCHECK(inactive_live_ranges_.Contains(range));
-  inactive_live_ranges_.RemoveElement(range);
-  active_live_ranges_.Add(range, zone());
+  RemoveElement(&inactive_live_ranges(), range);
+  active_live_ranges().push_back(range);
   TraceAlloc("Moving live range %d from inactive to active\n", range->id());
 }
 
 
-// TryAllocateFreeReg and AllocateBlockedReg assume this
-// when allocating local arrays.
-STATIC_ASSERT(DoubleRegister::kMaxNumAllocatableRegisters >=
-              Register::kMaxNumAllocatableRegisters);
-
-
 bool RegisterAllocator::TryAllocateFreeReg(LiveRange* current) {
-  LifetimePosition free_until_pos[DoubleRegister::kMaxNumAllocatableRegisters];
+  LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters];
 
   for (int i = 0; i < num_registers_; i++) {
     free_until_pos[i] = LifetimePosition::MaxPosition();
   }
 
-  for (int i = 0; i < active_live_ranges_.length(); ++i) {
-    LiveRange* cur_active = active_live_ranges_.at(i);
+  for (auto cur_active : active_live_ranges()) {
     free_until_pos[cur_active->assigned_register()] =
         LifetimePosition::FromInstructionIndex(0);
   }
 
-  for (int i = 0; i < inactive_live_ranges_.length(); ++i) {
-    LiveRange* cur_inactive = inactive_live_ranges_.at(i);
+  for (auto cur_inactive : inactive_live_ranges()) {
     DCHECK(cur_inactive->End().Value() > current->Start().Value());
-    LifetimePosition next_intersection =
-        cur_inactive->FirstIntersection(current);
+    auto next_intersection = cur_inactive->FirstIntersection(current);
     if (!next_intersection.IsValid()) continue;
     int cur_reg = cur_inactive->assigned_register();
     free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection);
   }
 
-  InstructionOperand* hint = current->FirstHint();
-  if (hint != NULL && (hint->IsRegister() || hint->IsDoubleRegister())) {
+  auto hint = current->FirstHint();
+  if (hint != nullptr && (hint->IsRegister() || hint->IsDoubleRegister())) {
     int register_index = hint->index();
     TraceAlloc(
         "Found reg hint %s (free until [%d) for live range %d (end %d[).\n",
@@ -1841,7 +2175,7 @@
     }
   }
 
-  LifetimePosition pos = free_until_pos[reg];
+  auto pos = free_until_pos[reg];
 
   if (pos.Value() <= current->Start().Value()) {
     // All registers are blocked.
@@ -1851,12 +2185,11 @@
   if (pos.Value() < current->End().Value()) {
     // Register reg is available at the range start but becomes blocked before
     // the range end. Split current at position where it becomes blocked.
-    LiveRange* tail = SplitRangeAt(current, pos);
+    auto tail = SplitRangeAt(current, pos);
     if (!AllocationOk()) return false;
     AddToUnhandledSorted(tail);
   }
 
-
   // Register reg is available at the range start and is free until
   // the range end.
   DCHECK(pos.Value() >= current->End().Value());
@@ -1869,32 +2202,30 @@
 
 
 void RegisterAllocator::AllocateBlockedReg(LiveRange* current) {
-  UsePosition* register_use = current->NextRegisterPosition(current->Start());
-  if (register_use == NULL) {
+  auto register_use = current->NextRegisterPosition(current->Start());
+  if (register_use == nullptr) {
     // There is no use in the current live range that requires a register.
     // We can just spill it.
     Spill(current);
     return;
   }
 
-
-  LifetimePosition use_pos[DoubleRegister::kMaxNumAllocatableRegisters];
-  LifetimePosition block_pos[DoubleRegister::kMaxNumAllocatableRegisters];
+  LifetimePosition use_pos[RegisterConfiguration::kMaxDoubleRegisters];
+  LifetimePosition block_pos[RegisterConfiguration::kMaxDoubleRegisters];
 
   for (int i = 0; i < num_registers_; i++) {
     use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
   }
 
-  for (int i = 0; i < active_live_ranges_.length(); ++i) {
-    LiveRange* range = active_live_ranges_[i];
+  for (auto range : active_live_ranges()) {
     int cur_reg = range->assigned_register();
     if (range->IsFixed() || !range->CanBeSpilled(current->Start())) {
       block_pos[cur_reg] = use_pos[cur_reg] =
           LifetimePosition::FromInstructionIndex(0);
     } else {
-      UsePosition* next_use =
+      auto next_use =
           range->NextUsePositionRegisterIsBeneficial(current->Start());
-      if (next_use == NULL) {
+      if (next_use == nullptr) {
         use_pos[cur_reg] = range->End();
       } else {
         use_pos[cur_reg] = next_use->pos();
@@ -1902,10 +2233,9 @@
     }
   }
 
-  for (int i = 0; i < inactive_live_ranges_.length(); ++i) {
-    LiveRange* range = inactive_live_ranges_.at(i);
+  for (auto range : inactive_live_ranges()) {
     DCHECK(range->End().Value() > current->Start().Value());
-    LifetimePosition next_intersection = range->FirstIntersection(current);
+    auto next_intersection = range->FirstIntersection(current);
     if (!next_intersection.IsValid()) continue;
     int cur_reg = range->assigned_register();
     if (range->IsFixed()) {
@@ -1923,7 +2253,7 @@
     }
   }
 
-  LifetimePosition pos = use_pos[reg];
+  auto pos = use_pos[reg];
 
   if (pos.Value() < register_use->pos().Value()) {
     // All registers are blocked before the first use that requires a register.
@@ -1954,32 +2284,40 @@
 }
 
 
+static const InstructionBlock* GetContainingLoop(
+    const InstructionSequence* sequence, const InstructionBlock* block) {
+  auto index = block->loop_header();
+  if (!index.IsValid()) return nullptr;
+  return sequence->InstructionBlockAt(index);
+}
+
+
 LifetimePosition RegisterAllocator::FindOptimalSpillingPos(
     LiveRange* range, LifetimePosition pos) {
-  BasicBlock* block = GetBlock(pos.InstructionStart());
-  BasicBlock* loop_header =
-      block->IsLoopHeader() ? block : code()->GetContainingLoop(block);
+  auto block = GetInstructionBlock(pos.InstructionStart());
+  auto loop_header =
+      block->IsLoopHeader() ? block : GetContainingLoop(code(), block);
 
-  if (loop_header == NULL) return pos;
+  if (loop_header == nullptr) return pos;
 
-  UsePosition* prev_use = range->PreviousUsePositionRegisterIsBeneficial(pos);
+  auto prev_use = range->PreviousUsePositionRegisterIsBeneficial(pos);
 
-  while (loop_header != NULL) {
+  while (loop_header != nullptr) {
     // We are going to spill live range inside the loop.
     // If possible try to move spilling position backwards to loop header.
     // This will reduce number of memory moves on the back edge.
-    LifetimePosition loop_start = LifetimePosition::FromInstructionIndex(
+    auto loop_start = LifetimePosition::FromInstructionIndex(
         loop_header->first_instruction_index());
 
     if (range->Covers(loop_start)) {
-      if (prev_use == NULL || prev_use->pos().Value() < loop_start.Value()) {
+      if (prev_use == nullptr || prev_use->pos().Value() < loop_start.Value()) {
         // No register beneficial use inside the loop before the pos.
         pos = loop_start;
       }
     }
 
     // Try hoisting out to an outer loop.
-    loop_header = code()->GetContainingLoop(loop_header);
+    loop_header = GetContainingLoop(code(), loop_header);
   }
 
   return pos;
@@ -1989,13 +2327,13 @@
 void RegisterAllocator::SplitAndSpillIntersecting(LiveRange* current) {
   DCHECK(current->HasRegisterAssigned());
   int reg = current->assigned_register();
-  LifetimePosition split_pos = current->Start();
-  for (int i = 0; i < active_live_ranges_.length(); ++i) {
-    LiveRange* range = active_live_ranges_[i];
+  auto split_pos = current->Start();
+  for (size_t i = 0; i < active_live_ranges().size(); ++i) {
+    auto range = active_live_ranges()[i];
     if (range->assigned_register() == reg) {
-      UsePosition* next_pos = range->NextRegisterPosition(current->Start());
-      LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos);
-      if (next_pos == NULL) {
+      auto next_pos = range->NextRegisterPosition(current->Start());
+      auto spill_pos = FindOptimalSpillingPos(range, split_pos);
+      if (next_pos == nullptr) {
         SpillAfter(range, spill_pos);
       } else {
         // When spilling between spill_pos and next_pos ensure that the range
@@ -2014,14 +2352,14 @@
     }
   }
 
-  for (int i = 0; i < inactive_live_ranges_.length(); ++i) {
-    LiveRange* range = inactive_live_ranges_[i];
+  for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
+    auto range = inactive_live_ranges()[i];
     DCHECK(range->End().Value() > current->Start().Value());
     if (range->assigned_register() == reg && !range->IsFixed()) {
       LifetimePosition next_intersection = range->FirstIntersection(current);
       if (next_intersection.IsValid()) {
         UsePosition* next_pos = range->NextRegisterPosition(current->Start());
-        if (next_pos == NULL) {
+        if (next_pos == nullptr) {
           SpillAfter(range, split_pos);
         } else {
           next_intersection = Min(next_intersection, next_pos->pos());
@@ -2055,9 +2393,9 @@
          !InstructionAt(pos.InstructionIndex())->IsControl());
 
   int vreg = GetVirtualRegister();
-  if (!AllocationOk()) return NULL;
-  LiveRange* result = LiveRangeFor(vreg);
-  range->SplitAt(pos, result, zone());
+  if (!AllocationOk()) return nullptr;
+  auto result = LiveRangeFor(vreg);
+  range->SplitAt(pos, result, local_zone());
   return result;
 }
 
@@ -2069,7 +2407,7 @@
   TraceAlloc("Splitting live range %d in position between [%d, %d]\n",
              range->id(), start.Value(), end.Value());
 
-  LifetimePosition split_pos = FindOptimalSplitPos(start, end);
+  auto split_pos = FindOptimalSplitPos(start, end);
   DCHECK(split_pos.Value() >= start.Value());
   return SplitRangeAt(range, split_pos);
 }
@@ -2084,8 +2422,8 @@
   // We have no choice
   if (start_instr == end_instr) return end;
 
-  BasicBlock* start_block = GetBlock(start);
-  BasicBlock* end_block = GetBlock(end);
+  auto start_block = GetInstructionBlock(start);
+  auto end_block = GetInstructionBlock(end);
 
   if (end_block == start_block) {
     // The interval is split in the same basic block. Split at the latest
@@ -2093,13 +2431,13 @@
     return end;
   }
 
-  BasicBlock* block = end_block;
+  auto block = end_block;
   // Find header of outermost loop.
   // TODO(titzer): fix redundancy below.
-  while (code()->GetContainingLoop(block) != NULL &&
-         code()->GetContainingLoop(block)->rpo_number_ >
-             start_block->rpo_number_) {
-    block = code()->GetContainingLoop(block);
+  while (GetContainingLoop(code(), block) != nullptr &&
+         GetContainingLoop(code(), block)->rpo_number().ToInt() >
+             start_block->rpo_number().ToInt()) {
+    block = GetContainingLoop(code(), block);
   }
 
   // We did not find any suitable outer loop. Split at the latest possible
@@ -2112,7 +2450,7 @@
 
 
 void RegisterAllocator::SpillAfter(LiveRange* range, LifetimePosition pos) {
-  LiveRange* second_part = SplitRangeAt(range, pos);
+  auto second_part = SplitRangeAt(range, pos);
   if (!AllocationOk()) return;
   Spill(second_part);
 }
@@ -2129,14 +2467,14 @@
                                           LifetimePosition until,
                                           LifetimePosition end) {
   CHECK(start.Value() < end.Value());
-  LiveRange* second_part = SplitRangeAt(range, start);
+  auto second_part = SplitRangeAt(range, start);
   if (!AllocationOk()) return;
 
   if (second_part->Start().Value() < end.Value()) {
     // The split result intersects with [start, end[.
     // Split it at position between ]start+1, end[, spill the middle part
     // and put the rest to unhandled.
-    LiveRange* third_part = SplitBetween(
+    auto third_part = SplitBetween(
         second_part, Max(second_part->Start().InstructionEnd(), until),
         end.PrevInstruction().InstructionEnd());
     if (!AllocationOk()) return;
@@ -2156,24 +2494,25 @@
 void RegisterAllocator::Spill(LiveRange* range) {
   DCHECK(!range->IsSpilled());
   TraceAlloc("Spilling live range %d\n", range->id());
-  LiveRange* first = range->TopLevel();
-
-  if (!first->HasAllocatedSpillOperand()) {
-    InstructionOperand* op = TryReuseSpillSlot(range);
-    if (op == NULL) {
-      // Allocate a new operand referring to the spill slot.
-      RegisterKind kind = range->Kind();
-      int index = code()->frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS);
-      if (kind == DOUBLE_REGISTERS) {
-        op = DoubleStackSlotOperand::Create(index, zone());
-      } else {
-        DCHECK(kind == GENERAL_REGISTERS);
-        op = StackSlotOperand::Create(index, zone());
+  auto first = range->TopLevel();
+  if (first->HasNoSpillType()) {
+    if (FLAG_turbo_reuse_spill_slots) {
+      AssignSpillRangeToLiveRange(first);
+    } else {
+      auto op = TryReuseSpillSlot(range);
+      if (op == nullptr) {
+        // Allocate a new operand referring to the spill slot.
+        RegisterKind kind = range->Kind();
+        int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS);
+        auto op_kind = kind == DOUBLE_REGISTERS
+                           ? InstructionOperand::DOUBLE_STACK_SLOT
+                           : InstructionOperand::STACK_SLOT;
+        op = new (code_zone()) InstructionOperand(op_kind, index);
       }
+      first->SetSpillOperand(op);
     }
-    first->SetSpillOperand(op);
   }
-  range->MakeSpilled(code_zone());
+  range->MakeSpilled();
 }
 
 
@@ -2184,9 +2523,8 @@
 
 
 void RegisterAllocator::Verify() const {
-  for (int i = 0; i < live_ranges()->length(); ++i) {
-    LiveRange* current = live_ranges()->at(i);
-    if (current != NULL) current->Verify();
+  for (auto current : live_ranges()) {
+    if (current != nullptr) current->Verify();
   }
 }
 
@@ -2205,28 +2543,6 @@
   range->set_assigned_register(reg, code_zone());
 }
 
-
-RegisterAllocatorPhase::RegisterAllocatorPhase(const char* name,
-                                               RegisterAllocator* allocator)
-    : CompilationPhase(name, allocator->code()->linkage()->info()),
-      allocator_(allocator) {
-  if (FLAG_turbo_stats) {
-    allocator_zone_start_allocation_size_ =
-        allocator->zone()->allocation_size();
-  }
-}
-
-
-RegisterAllocatorPhase::~RegisterAllocatorPhase() {
-  if (FLAG_turbo_stats) {
-    unsigned size = allocator_->zone()->allocation_size() -
-                    allocator_zone_start_allocation_size_;
-    isolate()->GetTStatistics()->SaveTiming(name(), base::TimeDelta(), size);
-  }
-#ifdef DEBUG
-  if (allocator_ != NULL) allocator_->Verify();
-#endif
-}
-}
-}
-}  // namespace v8::internal::compiler
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/register-allocator.h b/src/compiler/register-allocator.h
index 881ce37..b17837b 100644
--- a/src/compiler/register-allocator.h
+++ b/src/compiler/register-allocator.h
@@ -5,23 +5,11 @@
 #ifndef V8_REGISTER_ALLOCATOR_H_
 #define V8_REGISTER_ALLOCATOR_H_
 
-#include "src/allocation.h"
 #include "src/compiler/instruction.h"
-#include "src/compiler/node.h"
-#include "src/compiler/schedule.h"
-#include "src/macro-assembler.h"
-#include "src/zone.h"
+#include "src/zone-containers.h"
 
 namespace v8 {
 namespace internal {
-
-// Forward declarations.
-class BitVector;
-class InstructionOperand;
-class UnallocatedOperand;
-class ParallelMove;
-class PointerMap;
-
 namespace compiler {
 
 enum RegisterKind {
@@ -35,7 +23,7 @@
 // each instruction there are exactly two lifetime positions: the beginning and
 // the end of the instruction. Lifetime positions for different instructions are
 // disjoint.
-class LifetimePosition {
+class LifetimePosition FINAL {
  public:
   // Return the lifetime position that corresponds to the beginning of
   // the instruction with the given index.
@@ -114,10 +102,10 @@
 
 
 // Representation of the non-empty interval [start,end[.
-class UseInterval : public ZoneObject {
+class UseInterval FINAL : public ZoneObject {
  public:
   UseInterval(LifetimePosition start, LifetimePosition end)
-      : start_(start), end_(end), next_(NULL) {
+      : start_(start), end_(end), next_(nullptr) {
     DCHECK(start.Value() < end.Value());
   }
 
@@ -147,16 +135,20 @@
   LifetimePosition start_;
   LifetimePosition end_;
   UseInterval* next_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(UseInterval);
 };
 
+
 // Representation of a use position.
-class UsePosition : public ZoneObject {
+class UsePosition FINAL : public ZoneObject {
  public:
   UsePosition(LifetimePosition pos, InstructionOperand* operand,
               InstructionOperand* hint);
 
   InstructionOperand* operand() const { return operand_; }
-  bool HasOperand() const { return operand_ != NULL; }
+  bool HasOperand() const { return operand_ != nullptr; }
 
   InstructionOperand* hint() const { return hint_; }
   bool HasHint() const;
@@ -172,13 +164,18 @@
   InstructionOperand* const hint_;
   LifetimePosition const pos_;
   UsePosition* next_;
-  bool requires_reg_;
-  bool register_beneficial_;
+  bool requires_reg_ : 1;
+  bool register_beneficial_ : 1;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(UsePosition);
 };
 
+class SpillRange;
+
 // Representation of SSA values' live ranges as a collection of (continuous)
 // intervals over the instruction ordering.
-class LiveRange : public ZoneObject {
+class LiveRange FINAL : public ZoneObject {
  public:
   static const int kInvalidAssignment = 0x7fffffff;
 
@@ -187,17 +184,20 @@
   UseInterval* first_interval() const { return first_interval_; }
   UsePosition* first_pos() const { return first_pos_; }
   LiveRange* parent() const { return parent_; }
-  LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; }
+  LiveRange* TopLevel() { return (parent_ == nullptr) ? this : parent_; }
+  const LiveRange* TopLevel() const {
+    return (parent_ == nullptr) ? this : parent_;
+  }
   LiveRange* next() const { return next_; }
-  bool IsChild() const { return parent() != NULL; }
+  bool IsChild() const { return parent() != nullptr; }
   int id() const { return id_; }
   bool IsFixed() const { return id_ < 0; }
-  bool IsEmpty() const { return first_interval() == NULL; }
-  InstructionOperand* CreateAssignedOperand(Zone* zone);
+  bool IsEmpty() const { return first_interval() == nullptr; }
+  InstructionOperand* CreateAssignedOperand(Zone* zone) const;
   int assigned_register() const { return assigned_register_; }
   int spill_start_index() const { return spill_start_index_; }
   void set_assigned_register(int reg, Zone* zone);
-  void MakeSpilled(Zone* zone);
+  void MakeSpilled();
   bool is_phi() const { return is_phi_; }
   void set_is_phi(bool is_phi) { is_phi_ = is_phi; }
   bool is_non_loop_phi() const { return is_non_loop_phi_; }
@@ -245,9 +245,9 @@
   }
   InstructionOperand* FirstHint() const {
     UsePosition* pos = first_pos_;
-    while (pos != NULL && !pos->HasHint()) pos = pos->next();
-    if (pos != NULL) return pos->hint();
-    return NULL;
+    while (pos != nullptr && !pos->HasHint()) pos = pos->next();
+    if (pos != nullptr) return pos->hint();
+    return nullptr;
   }
 
   LifetimePosition Start() const {
@@ -260,9 +260,27 @@
     return last_interval_->end();
   }
 
-  bool HasAllocatedSpillOperand() const;
-  InstructionOperand* GetSpillOperand() const { return spill_operand_; }
+  enum class SpillType { kNoSpillType, kSpillOperand, kSpillRange };
+  SpillType spill_type() const { return spill_type_; }
+  InstructionOperand* GetSpillOperand() const {
+    return spill_type_ == SpillType::kSpillOperand ? spill_operand_ : nullptr;
+  }
+  SpillRange* GetSpillRange() const {
+    return spill_type_ == SpillType::kSpillRange ? spill_range_ : nullptr;
+  }
+  bool HasNoSpillType() const { return spill_type_ == SpillType::kNoSpillType; }
+  bool HasSpillOperand() const {
+    return spill_type_ == SpillType::kSpillOperand;
+  }
+  bool HasSpillRange() const { return spill_type_ == SpillType::kSpillRange; }
+
+  void SpillAtDefinition(Zone* zone, int gap_index,
+                         InstructionOperand* operand);
   void SetSpillOperand(InstructionOperand* operand);
+  void SetSpillRange(SpillRange* spill_range);
+  void CommitSpillOperand(InstructionOperand* operand);
+  void CommitSpillsAtDefinition(InstructionSequence* sequence,
+                                InstructionOperand* operand);
 
   void SetSpillStartIndex(int start) {
     spill_start_index_ = Min(start, spill_start_index_);
@@ -289,11 +307,14 @@
 #endif
 
  private:
-  void ConvertOperands(Zone* zone);
+  struct SpillAtDefinitionList;
+
+  void ConvertUsesToOperand(InstructionOperand* op);
   UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const;
   void AdvanceLastProcessedMarker(UseInterval* to_start_of,
                                   LifetimePosition but_not_past) const;
 
+  // TODO(dcarney): pack this structure better.
   int id_;
   bool spilled_;
   bool is_phi_;
@@ -310,45 +331,96 @@
   UsePosition* last_processed_use_;
   // This is used as a cache, it's invalid outside of BuildLiveRanges.
   InstructionOperand* current_hint_operand_;
-  InstructionOperand* spill_operand_;
   int spill_start_index_;
+  SpillType spill_type_;
+  union {
+    InstructionOperand* spill_operand_;
+    SpillRange* spill_range_;
+  };
+  SpillAtDefinitionList* spills_at_definition_;
 
   friend class RegisterAllocator;  // Assigns to kind_.
+
+  DISALLOW_COPY_AND_ASSIGN(LiveRange);
 };
 
 
-class RegisterAllocator BASE_EMBEDDED {
+class SpillRange FINAL : public ZoneObject {
  public:
-  explicit RegisterAllocator(InstructionSequence* code);
+  SpillRange(LiveRange* range, Zone* zone);
 
-  static void TraceAlloc(const char* msg, ...);
+  UseInterval* interval() const { return use_interval_; }
+  RegisterKind Kind() const { return live_ranges_[0]->Kind(); }
+  bool IsEmpty() const { return live_ranges_.empty(); }
+  bool TryMerge(SpillRange* other);
+  void SetOperand(InstructionOperand* op);
 
-  // Checks whether the value of a given virtual register is a reference.
-  // TODO(titzer): rename this to IsReference.
-  bool HasTaggedValue(int virtual_register) const;
+ private:
+  LifetimePosition End() const { return end_position_; }
+  ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; }
+  bool IsIntersectingWith(SpillRange* other) const;
+  // Merge intervals, making sure the use intervals are sorted
+  void MergeDisjointIntervals(UseInterval* other);
 
-  // Returns the register kind required by the given virtual register.
-  RegisterKind RequiredRegisterKind(int virtual_register) const;
+  ZoneVector<LiveRange*> live_ranges_;
+  UseInterval* use_interval_;
+  LifetimePosition end_position_;
 
-  bool Allocate();
+  DISALLOW_COPY_AND_ASSIGN(SpillRange);
+};
 
-  const ZoneList<LiveRange*>* live_ranges() const { return &live_ranges_; }
-  const Vector<LiveRange*>* fixed_live_ranges() const {
-    return &fixed_live_ranges_;
+
+class RegisterAllocator FINAL : public ZoneObject {
+ public:
+  explicit RegisterAllocator(const RegisterConfiguration* config,
+                             Zone* local_zone, Frame* frame,
+                             InstructionSequence* code,
+                             const char* debug_name = nullptr);
+
+  bool AllocationOk() { return allocation_ok_; }
+
+  const ZoneVector<LiveRange*>& live_ranges() const { return live_ranges_; }
+  const ZoneVector<LiveRange*>& fixed_live_ranges() const {
+    return fixed_live_ranges_;
   }
-  const Vector<LiveRange*>* fixed_double_live_ranges() const {
-    return &fixed_double_live_ranges_;
+  const ZoneVector<LiveRange*>& fixed_double_live_ranges() const {
+    return fixed_double_live_ranges_;
   }
-
-  inline InstructionSequence* code() const { return code_; }
-
+  InstructionSequence* code() const { return code_; }
   // This zone is for datastructures only needed during register allocation.
-  inline Zone* zone() { return &zone_; }
+  Zone* local_zone() const { return local_zone_; }
 
-  // This zone is for InstructionOperands and moves that live beyond register
-  // allocation.
-  inline Zone* code_zone() { return code()->zone(); }
+  // Phase 1 : insert moves to account for fixed register operands.
+  void MeetRegisterConstraints();
 
+  // Phase 2: deconstruct SSA by inserting moves in successors and the headers
+  // of blocks containing phis.
+  void ResolvePhis();
+
+  // Phase 3: compute liveness of all virtual register.
+  void BuildLiveRanges();
+  bool ExistsUseWithoutDefinition();
+
+  // Phase 4: compute register assignments.
+  void AllocateGeneralRegisters();
+  void AllocateDoubleRegisters();
+
+  // Phase 5: reassign spill splots for maximal reuse.
+  void ReuseSpillSlots();
+
+  // Phase 6: commit assignment.
+  void CommitAssignment();
+
+  // Phase 7: compute values for pointer maps.
+  void PopulatePointerMaps();  // TODO(titzer): rename to PopulateReferenceMaps.
+
+  // Phase 8: reconnect split ranges with moves.
+  void ConnectRanges();
+
+  // Phase 9: insert moves to connect ranges across basic blocks.
+  void ResolveControlFlow();
+
+ private:
   int GetVirtualRegister() {
     int vreg = code()->NextVirtualRegister();
     if (vreg >= UnallocatedOperand::kMaxVirtualRegisters) {
@@ -359,40 +431,40 @@
     return vreg;
   }
 
-  bool AllocationOk() { return allocation_ok_; }
+  // Checks whether the value of a given virtual register is a reference.
+  // TODO(titzer): rename this to IsReference.
+  bool HasTaggedValue(int virtual_register) const;
+
+  // Returns the register kind required by the given virtual register.
+  RegisterKind RequiredRegisterKind(int virtual_register) const;
+
+  // This zone is for InstructionOperands and moves that live beyond register
+  // allocation.
+  Zone* code_zone() const { return code()->zone(); }
+
+  BitVector* assigned_registers() { return assigned_registers_; }
+  BitVector* assigned_double_registers() { return assigned_double_registers_; }
 
 #ifdef DEBUG
   void Verify() const;
 #endif
 
-  BitVector* assigned_registers() { return assigned_registers_; }
-  BitVector* assigned_double_registers() { return assigned_double_registers_; }
-
- private:
-  void MeetRegisterConstraints();
-  void ResolvePhis();
-  void BuildLiveRanges();
-  void AllocateGeneralRegisters();
-  void AllocateDoubleRegisters();
-  void ConnectRanges();
-  void ResolveControlFlow();
-  void PopulatePointerMaps();  // TODO(titzer): rename to PopulateReferenceMaps.
   void AllocateRegisters();
-  bool CanEagerlyResolveControlFlow(BasicBlock* block) const;
-  inline bool SafePointsAreInOrder() const;
+  bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const;
+  bool SafePointsAreInOrder() const;
 
   // Liveness analysis support.
-  void InitializeLivenessAnalysis();
-  BitVector* ComputeLiveOut(BasicBlock* block);
-  void AddInitialIntervals(BasicBlock* block, BitVector* live_out);
+  BitVector* ComputeLiveOut(const InstructionBlock* block);
+  void AddInitialIntervals(const InstructionBlock* block, BitVector* live_out);
   bool IsOutputRegisterOf(Instruction* instr, int index);
   bool IsOutputDoubleRegisterOf(Instruction* instr, int index);
-  void ProcessInstructions(BasicBlock* block, BitVector* live);
-  void MeetRegisterConstraints(BasicBlock* block);
+  void ProcessInstructions(const InstructionBlock* block, BitVector* live);
+  void MeetRegisterConstraints(const InstructionBlock* block);
   void MeetConstraintsBetween(Instruction* first, Instruction* second,
                               int gap_index);
-  void MeetRegisterConstraintsForLastInstructionInBlock(BasicBlock* block);
-  void ResolvePhis(BasicBlock* block);
+  void MeetRegisterConstraintsForLastInstructionInBlock(
+      const InstructionBlock* block);
+  void ResolvePhis(const InstructionBlock* block);
 
   // Helper methods for building intervals.
   InstructionOperand* AllocateFixed(UnallocatedOperand* operand, int pos,
@@ -402,8 +474,8 @@
               InstructionOperand* hint);
   void Use(LifetimePosition block_start, LifetimePosition position,
            InstructionOperand* operand, InstructionOperand* hint);
-  void AddConstraintsGapMove(int index, InstructionOperand* from,
-                             InstructionOperand* to);
+  void AddGapMove(int index, GapInstruction::InnerPosition position,
+                  InstructionOperand* from, InstructionOperand* to);
 
   // Helper methods for updating the life range lists.
   void AddToActive(LiveRange* range);
@@ -416,12 +488,14 @@
   void ActiveToInactive(LiveRange* range);
   void InactiveToHandled(LiveRange* range);
   void InactiveToActive(LiveRange* range);
-  void FreeSpillSlot(LiveRange* range);
-  InstructionOperand* TryReuseSpillSlot(LiveRange* range);
 
   // Helper methods for allocating registers.
+  bool TryReuseSpillForPhi(LiveRange* range);
   bool TryAllocateFreeReg(LiveRange* range);
   void AllocateBlockedReg(LiveRange* range);
+  SpillRange* AssignSpillRangeToLiveRange(LiveRange* range);
+  void FreeSpillSlot(LiveRange* range);
+  InstructionOperand* TryReuseSpillSlot(LiveRange* range);
 
   // Live range splitting helpers.
 
@@ -466,52 +540,84 @@
   bool IsBlockBoundary(LifetimePosition pos);
 
   // Helper methods for resolving control flow.
-  void ResolveControlFlow(LiveRange* range, BasicBlock* block,
-                          BasicBlock* pred);
+  void ResolveControlFlow(const InstructionBlock* block,
+                          InstructionOperand* cur_op,
+                          const InstructionBlock* pred,
+                          InstructionOperand* pred_op);
 
-  inline void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
+  void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
 
   // Return parallel move that should be used to connect ranges split at the
   // given position.
   ParallelMove* GetConnectingParallelMove(LifetimePosition pos);
 
   // Return the block which contains give lifetime position.
-  BasicBlock* GetBlock(LifetimePosition pos);
+  const InstructionBlock* GetInstructionBlock(LifetimePosition pos);
 
   // Helper methods for the fixed registers.
   int RegisterCount() const;
   static int FixedLiveRangeID(int index) { return -index - 1; }
-  static int FixedDoubleLiveRangeID(int index);
+  int FixedDoubleLiveRangeID(int index);
   LiveRange* FixedLiveRangeFor(int index);
   LiveRange* FixedDoubleLiveRangeFor(int index);
   LiveRange* LiveRangeFor(int index);
-  GapInstruction* GetLastGap(BasicBlock* block);
+  GapInstruction* GetLastGap(const InstructionBlock* block);
 
   const char* RegisterName(int allocation_index);
 
-  inline Instruction* InstructionAt(int index) {
-    return code()->InstructionAt(index);
-  }
+  Instruction* InstructionAt(int index) { return code()->InstructionAt(index); }
 
-  Zone zone_;
-  InstructionSequence* code_;
+  Frame* frame() const { return frame_; }
+  const char* debug_name() const { return debug_name_; }
+  const RegisterConfiguration* config() const { return config_; }
+  ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; }
+  ZoneVector<LiveRange*>& fixed_live_ranges() { return fixed_live_ranges_; }
+  ZoneVector<LiveRange*>& fixed_double_live_ranges() {
+    return fixed_double_live_ranges_;
+  }
+  ZoneVector<LiveRange*>& unhandled_live_ranges() {
+    return unhandled_live_ranges_;
+  }
+  ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; }
+  ZoneVector<LiveRange*>& inactive_live_ranges() {
+    return inactive_live_ranges_;
+  }
+  ZoneVector<LiveRange*>& reusable_slots() { return reusable_slots_; }
+  ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; }
+
+  struct PhiMapValue {
+    PhiMapValue(PhiInstruction* phi, const InstructionBlock* block)
+        : phi(phi), block(block) {}
+    PhiInstruction* const phi;
+    const InstructionBlock* const block;
+  };
+  typedef std::map<int, PhiMapValue, std::less<int>,
+                   zone_allocator<std::pair<int, PhiMapValue>>> PhiMap;
+
+  Zone* const local_zone_;
+  Frame* const frame_;
+  InstructionSequence* const code_;
+  const char* const debug_name_;
+
+  const RegisterConfiguration* config_;
+
+  PhiMap phi_map_;
 
   // During liveness analysis keep a mapping from block id to live_in sets
   // for blocks already analyzed.
-  ZoneList<BitVector*> live_in_sets_;
+  ZoneVector<BitVector*> live_in_sets_;
 
   // Liveness analysis results.
-  ZoneList<LiveRange*> live_ranges_;
+  ZoneVector<LiveRange*> live_ranges_;
 
   // Lists of live ranges
-  EmbeddedVector<LiveRange*, Register::kMaxNumAllocatableRegisters>
-      fixed_live_ranges_;
-  EmbeddedVector<LiveRange*, DoubleRegister::kMaxNumAllocatableRegisters>
-      fixed_double_live_ranges_;
-  ZoneList<LiveRange*> unhandled_live_ranges_;
-  ZoneList<LiveRange*> active_live_ranges_;
-  ZoneList<LiveRange*> inactive_live_ranges_;
-  ZoneList<LiveRange*> reusable_slots_;
+  ZoneVector<LiveRange*> fixed_live_ranges_;
+  ZoneVector<LiveRange*> fixed_double_live_ranges_;
+  ZoneVector<LiveRange*> unhandled_live_ranges_;
+  ZoneVector<LiveRange*> active_live_ranges_;
+  ZoneVector<LiveRange*> inactive_live_ranges_;
+  ZoneVector<LiveRange*> reusable_slots_;
+  ZoneVector<SpillRange*> spill_ranges_;
 
   RegisterKind mode_;
   int num_registers_;
@@ -529,20 +635,8 @@
   DISALLOW_COPY_AND_ASSIGN(RegisterAllocator);
 };
 
-
-class RegisterAllocatorPhase : public CompilationPhase {
- public:
-  RegisterAllocatorPhase(const char* name, RegisterAllocator* allocator);
-  ~RegisterAllocatorPhase();
-
- private:
-  RegisterAllocator* allocator_;
-  unsigned allocator_zone_start_allocation_size_;
-
-  DISALLOW_COPY_AND_ASSIGN(RegisterAllocatorPhase);
-};
-}
-}
-}  // namespace v8::internal::compiler
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_REGISTER_ALLOCATOR_H_
diff --git a/src/compiler/register-configuration.cc b/src/compiler/register-configuration.cc
new file mode 100644
index 0000000..e7d8bbd
--- /dev/null
+++ b/src/compiler/register-configuration.cc
@@ -0,0 +1,68 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/register-configuration.h"
+#include "src/macro-assembler.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+STATIC_ASSERT(RegisterConfiguration::kMaxGeneralRegisters >=
+              Register::kNumRegisters);
+STATIC_ASSERT(RegisterConfiguration::kMaxDoubleRegisters >=
+              DoubleRegister::kMaxNumRegisters);
+
+class ArchDefaultRegisterConfiguration : public RegisterConfiguration {
+ public:
+  ArchDefaultRegisterConfiguration()
+      : RegisterConfiguration(Register::kMaxNumAllocatableRegisters,
+                              DoubleRegister::kMaxNumAllocatableRegisters,
+                              DoubleRegister::NumAllocatableAliasedRegisters(),
+                              general_register_name_table_,
+                              double_register_name_table_) {
+    DCHECK_EQ(Register::kMaxNumAllocatableRegisters,
+              Register::NumAllocatableRegisters());
+    for (int i = 0; i < Register::kMaxNumAllocatableRegisters; ++i) {
+      general_register_name_table_[i] = Register::AllocationIndexToString(i);
+    }
+    for (int i = 0; i < DoubleRegister::kMaxNumAllocatableRegisters; ++i) {
+      double_register_name_table_[i] =
+          DoubleRegister::AllocationIndexToString(i);
+    }
+  }
+
+  const char*
+      general_register_name_table_[Register::kMaxNumAllocatableRegisters];
+  const char*
+      double_register_name_table_[DoubleRegister::kMaxNumAllocatableRegisters];
+};
+
+
+static base::LazyInstance<ArchDefaultRegisterConfiguration>::type
+    kDefaultRegisterConfiguration = LAZY_INSTANCE_INITIALIZER;
+
+}  // namepace
+
+
+const RegisterConfiguration* RegisterConfiguration::ArchDefault() {
+  return &kDefaultRegisterConfiguration.Get();
+}
+
+RegisterConfiguration::RegisterConfiguration(
+    int num_general_registers, int num_double_registers,
+    int num_aliased_double_registers, const char* const* general_register_names,
+    const char* const* double_register_names)
+    : num_general_registers_(num_general_registers),
+      num_double_registers_(num_double_registers),
+      num_aliased_double_registers_(num_aliased_double_registers),
+      general_register_names_(general_register_names),
+      double_register_names_(double_register_names) {}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/register-configuration.h b/src/compiler/register-configuration.h
new file mode 100644
index 0000000..8178ba2
--- /dev/null
+++ b/src/compiler/register-configuration.h
@@ -0,0 +1,56 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_REGISTER_CONFIGURATION_H_
+#define V8_COMPILER_REGISTER_CONFIGURATION_H_
+
+#include "src/v8.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// An architecture independent representation of the sets of registers available
+// for instruction creation.
+class RegisterConfiguration {
+ public:
+  // Architecture independent maxes.
+  static const int kMaxGeneralRegisters = 32;
+  static const int kMaxDoubleRegisters = 32;
+
+  static const RegisterConfiguration* ArchDefault();
+
+  RegisterConfiguration(int num_general_registers, int num_double_registers,
+                        int num_aliased_double_registers,
+                        const char* const* general_register_name,
+                        const char* const* double_register_name);
+
+  int num_general_registers() const { return num_general_registers_; }
+  int num_double_registers() const { return num_double_registers_; }
+  int num_aliased_double_registers() const {
+    return num_aliased_double_registers_;
+  }
+
+  const char* general_register_name(int offset) const {
+    DCHECK(offset >= 0 && offset < kMaxGeneralRegisters);
+    return general_register_names_[offset];
+  }
+  const char* double_register_name(int offset) const {
+    DCHECK(offset >= 0 && offset < kMaxDoubleRegisters);
+    return double_register_names_[offset];
+  }
+
+ private:
+  const int num_general_registers_;
+  const int num_double_registers_;
+  const int num_aliased_double_registers_;
+  const char* const* general_register_names_;
+  const char* const* double_register_names_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_REGISTER_CONFIGURATION_H_
diff --git a/src/compiler/representation-change.h b/src/compiler/representation-change.h
index aaa248e..8720afd 100644
--- a/src/compiler/representation-change.h
+++ b/src/compiler/representation-change.h
@@ -5,6 +5,8 @@
 #ifndef V8_COMPILER_REPRESENTATION_CHANGE_H_
 #define V8_COMPILER_REPRESENTATION_CHANGE_H_
 
+#include <sstream>
+
 #include "src/base/bits.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/machine-operator.h"
@@ -51,10 +53,10 @@
     }
     if (use_type & kRepTagged) {
       return GetTaggedRepresentationFor(node, output_type);
+    } else if (use_type & kRepFloat32) {
+      return GetFloat32RepresentationFor(node, output_type);
     } else if (use_type & kRepFloat64) {
       return GetFloat64RepresentationFor(node, output_type);
-    } else if (use_type & kRepFloat32) {
-      return TypeError(node, output_type, use_type);  // TODO(titzer): handle
     } else if (use_type & kRepBit) {
       return GetBitRepresentationFor(node, output_type);
     } else if (use_type & rWord) {
@@ -88,6 +90,8 @@
         }
       case IrOpcode::kFloat64Constant:
         return jsgraph()->Constant(OpParameter<double>(node));
+      case IrOpcode::kFloat32Constant:
+        return jsgraph()->Constant(OpParameter<float>(node));
       default:
         break;
     }
@@ -103,6 +107,9 @@
       } else {
         return TypeError(node, output_type, kRepTagged);
       }
+    } else if (output_type & kRepFloat32) {  // float32 -> float64 -> tagged
+      node = InsertChangeFloat32ToFloat64(node);
+      op = simplified()->ChangeFloat64ToTagged();
     } else if (output_type & kRepFloat64) {
       op = simplified()->ChangeFloat64ToTagged();
     } else {
@@ -111,6 +118,52 @@
     return jsgraph()->graph()->NewNode(op, node);
   }
 
+  Node* GetFloat32RepresentationFor(Node* node, MachineTypeUnion output_type) {
+    // Eagerly fold representation changes for constants.
+    switch (node->opcode()) {
+      case IrOpcode::kFloat64Constant:
+      case IrOpcode::kNumberConstant:
+        return jsgraph()->Float32Constant(
+            DoubleToFloat32(OpParameter<double>(node)));
+      case IrOpcode::kInt32Constant:
+        if (output_type & kTypeUint32) {
+          uint32_t value = OpParameter<uint32_t>(node);
+          return jsgraph()->Float32Constant(static_cast<float>(value));
+        } else {
+          int32_t value = OpParameter<int32_t>(node);
+          return jsgraph()->Float32Constant(static_cast<float>(value));
+        }
+      case IrOpcode::kFloat32Constant:
+        return node;  // No change necessary.
+      default:
+        break;
+    }
+    // Select the correct X -> Float32 operator.
+    const Operator* op;
+    if (output_type & kRepBit) {
+      return TypeError(node, output_type, kRepFloat32);
+    } else if (output_type & rWord) {
+      if (output_type & kTypeUint32) {
+        op = machine()->ChangeUint32ToFloat64();
+      } else {
+        op = machine()->ChangeInt32ToFloat64();
+      }
+      // int32 -> float64 -> float32
+      node = jsgraph()->graph()->NewNode(op, node);
+      op = machine()->TruncateFloat64ToFloat32();
+    } else if (output_type & kRepTagged) {
+      op = simplified()
+               ->ChangeTaggedToFloat64();  // tagged -> float64 -> float32
+      node = jsgraph()->graph()->NewNode(op, node);
+      op = machine()->TruncateFloat64ToFloat32();
+    } else if (output_type & kRepFloat64) {
+      op = machine()->TruncateFloat64ToFloat32();
+    } else {
+      return TypeError(node, output_type, kRepFloat32);
+    }
+    return jsgraph()->graph()->NewNode(op, node);
+  }
+
   Node* GetFloat64RepresentationFor(Node* node, MachineTypeUnion output_type) {
     // Eagerly fold representation changes for constants.
     switch (node->opcode()) {
@@ -126,6 +179,8 @@
         }
       case IrOpcode::kFloat64Constant:
         return node;  // No change necessary.
+      case IrOpcode::kFloat32Constant:
+        return jsgraph()->Float64Constant(OpParameter<float>(node));
       default:
         break;
     }
@@ -141,31 +196,68 @@
       }
     } else if (output_type & kRepTagged) {
       op = simplified()->ChangeTaggedToFloat64();
+    } else if (output_type & kRepFloat32) {
+      op = machine()->ChangeFloat32ToFloat64();
     } else {
       return TypeError(node, output_type, kRepFloat64);
     }
     return jsgraph()->graph()->NewNode(op, node);
   }
 
+  Node* MakeInt32Constant(double value) {
+    if (value < 0) {
+      DCHECK(IsInt32Double(value));
+      int32_t iv = static_cast<int32_t>(value);
+      return jsgraph()->Int32Constant(iv);
+    } else {
+      DCHECK(IsUint32Double(value));
+      int32_t iv = static_cast<int32_t>(static_cast<uint32_t>(value));
+      return jsgraph()->Int32Constant(iv);
+    }
+  }
+
+  Node* GetTruncatedWord32For(Node* node, MachineTypeUnion output_type) {
+    // Eagerly fold truncations for constants.
+    switch (node->opcode()) {
+      case IrOpcode::kInt32Constant:
+        return node;  // No change necessary.
+      case IrOpcode::kFloat32Constant:
+        return jsgraph()->Int32Constant(
+            DoubleToInt32(OpParameter<float>(node)));
+      case IrOpcode::kNumberConstant:
+      case IrOpcode::kFloat64Constant:
+        return jsgraph()->Int32Constant(
+            DoubleToInt32(OpParameter<double>(node)));
+      default:
+        break;
+    }
+    // Select the correct X -> Word32 truncation operator.
+    const Operator* op = NULL;
+    if (output_type & kRepFloat64) {
+      op = machine()->TruncateFloat64ToInt32();
+    } else if (output_type & kRepFloat32) {
+      node = InsertChangeFloat32ToFloat64(node);
+      op = machine()->TruncateFloat64ToInt32();
+    } else if (output_type & kRepTagged) {
+      node = InsertChangeTaggedToFloat64(node);
+      op = machine()->TruncateFloat64ToInt32();
+    } else {
+      return TypeError(node, output_type, kRepWord32);
+    }
+    return jsgraph()->graph()->NewNode(op, node);
+  }
+
   Node* GetWord32RepresentationFor(Node* node, MachineTypeUnion output_type,
                                    bool use_unsigned) {
     // Eagerly fold representation changes for constants.
     switch (node->opcode()) {
       case IrOpcode::kInt32Constant:
         return node;  // No change necessary.
+      case IrOpcode::kFloat32Constant:
+        return MakeInt32Constant(OpParameter<float>(node));
       case IrOpcode::kNumberConstant:
-      case IrOpcode::kFloat64Constant: {
-        double value = OpParameter<double>(node);
-        if (value < 0) {
-          DCHECK(IsInt32Double(value));
-          int32_t iv = static_cast<int32_t>(value);
-          return jsgraph()->Int32Constant(iv);
-        } else {
-          DCHECK(IsUint32Double(value));
-          int32_t iv = static_cast<int32_t>(static_cast<uint32_t>(value));
-          return jsgraph()->Int32Constant(iv);
-        }
-      }
+      case IrOpcode::kFloat64Constant:
+        return MakeInt32Constant(OpParameter<double>(node));
       default:
         break;
     }
@@ -177,6 +269,13 @@
       } else {
         op = machine()->ChangeFloat64ToInt32();
       }
+    } else if (output_type & kRepFloat32) {
+      node = InsertChangeFloat32ToFloat64(node);  // float32 -> float64 -> int32
+      if (output_type & kTypeUint32 || use_unsigned) {
+        op = machine()->ChangeFloat64ToUint32();
+      } else {
+        op = machine()->ChangeFloat64ToInt32();
+      }
     } else if (output_type & kRepTagged) {
       if (output_type & kTypeUint32 || use_unsigned) {
         op = simplified()->ChangeTaggedToUint32();
@@ -195,7 +294,14 @@
       case IrOpcode::kInt32Constant: {
         int32_t value = OpParameter<int32_t>(node);
         if (value == 0 || value == 1) return node;
-        return jsgraph()->OneConstant();  // value != 0
+        return jsgraph()->Int32Constant(1);  // value != 0
+      }
+      case IrOpcode::kNumberConstant: {
+        double value = OpParameter<double>(node);
+        if (std::isnan(value) || value == 0.0) {
+          return jsgraph()->Int32Constant(0);
+        }
+        return jsgraph()->Int32Constant(1);
       }
       case IrOpcode::kHeapConstant: {
         Handle<Object> handle = OpParameter<Unique<Object> >(node).handle();
@@ -262,9 +368,9 @@
       case IrOpcode::kNumberMultiply:
         return machine()->Int32Mul();
       case IrOpcode::kNumberDivide:
-        return machine()->Int32UDiv();
+        return machine()->Uint32Div();
       case IrOpcode::kNumberModulus:
-        return machine()->Int32UMod();
+        return machine()->Uint32Mod();
       case IrOpcode::kNumberEqual:
         return machine()->Word32Equal();
       case IrOpcode::kNumberLessThan:
@@ -333,28 +439,39 @@
                   MachineTypeUnion use) {
     type_error_ = true;
     if (!testing_type_errors_) {
-      OStringStream out_str;
+      std::ostringstream out_str;
       out_str << static_cast<MachineType>(output_type);
 
-      OStringStream use_str;
+      std::ostringstream use_str;
       use_str << static_cast<MachineType>(use);
 
       V8_Fatal(__FILE__, __LINE__,
                "RepresentationChangerError: node #%d:%s of "
                "%s cannot be changed to %s",
-               node->id(), node->op()->mnemonic(), out_str.c_str(),
-               use_str.c_str());
+               node->id(), node->op()->mnemonic(), out_str.str().c_str(),
+               use_str.str().c_str());
     }
     return node;
   }
 
+  Node* InsertChangeFloat32ToFloat64(Node* node) {
+    return jsgraph()->graph()->NewNode(machine()->ChangeFloat32ToFloat64(),
+                                       node);
+  }
+
+  Node* InsertChangeTaggedToFloat64(Node* node) {
+    return jsgraph()->graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
+                                       node);
+  }
+
   JSGraph* jsgraph() { return jsgraph_; }
   Isolate* isolate() { return isolate_; }
   SimplifiedOperatorBuilder* simplified() { return simplified_; }
   MachineOperatorBuilder* machine() { return jsgraph()->machine(); }
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_REPRESENTATION_CHANGE_H_
diff --git a/src/compiler/schedule.cc b/src/compiler/schedule.cc
index a3b5ed3..30bfbc8 100644
--- a/src/compiler/schedule.cc
+++ b/src/compiler/schedule.cc
@@ -12,17 +12,86 @@
 namespace internal {
 namespace compiler {
 
-OStream& operator<<(OStream& os, const BasicBlockData::Control& c) {
+BasicBlock::BasicBlock(Zone* zone, Id id)
+    : loop_number_(-1),
+      rpo_number_(-1),
+      deferred_(false),
+      dominator_depth_(-1),
+      dominator_(NULL),
+      rpo_next_(NULL),
+      loop_header_(NULL),
+      loop_end_(NULL),
+      loop_depth_(0),
+      control_(kNone),
+      control_input_(NULL),
+      nodes_(zone),
+      successors_(zone),
+      predecessors_(zone),
+      id_(id) {}
+
+
+bool BasicBlock::LoopContains(BasicBlock* block) const {
+  // RPO numbers must be initialized.
+  DCHECK(rpo_number_ >= 0);
+  DCHECK(block->rpo_number_ >= 0);
+  if (loop_end_ == NULL) return false;  // This is not a loop.
+  return block->rpo_number_ >= rpo_number_ &&
+         block->rpo_number_ < loop_end_->rpo_number_;
+}
+
+
+void BasicBlock::AddSuccessor(BasicBlock* successor) {
+  successors_.push_back(successor);
+}
+
+
+void BasicBlock::AddPredecessor(BasicBlock* predecessor) {
+  predecessors_.push_back(predecessor);
+}
+
+
+void BasicBlock::AddNode(Node* node) { nodes_.push_back(node); }
+
+
+void BasicBlock::set_control(Control control) {
+  control_ = control;
+}
+
+
+void BasicBlock::set_control_input(Node* control_input) {
+  control_input_ = control_input;
+}
+
+
+void BasicBlock::set_loop_depth(int32_t loop_depth) {
+  loop_depth_ = loop_depth;
+}
+
+
+void BasicBlock::set_rpo_number(int32_t rpo_number) {
+  rpo_number_ = rpo_number;
+}
+
+
+void BasicBlock::set_loop_end(BasicBlock* loop_end) { loop_end_ = loop_end; }
+
+
+void BasicBlock::set_loop_header(BasicBlock* loop_header) {
+  loop_header_ = loop_header;
+}
+
+
+std::ostream& operator<<(std::ostream& os, const BasicBlock::Control& c) {
   switch (c) {
-    case BasicBlockData::kNone:
+    case BasicBlock::kNone:
       return os << "none";
-    case BasicBlockData::kGoto:
+    case BasicBlock::kGoto:
       return os << "goto";
-    case BasicBlockData::kBranch:
+    case BasicBlock::kBranch:
       return os << "branch";
-    case BasicBlockData::kReturn:
+    case BasicBlock::kReturn:
       return os << "return";
-    case BasicBlockData::kThrow:
+    case BasicBlock::kThrow:
       return os << "throw";
   }
   UNREACHABLE();
@@ -30,17 +99,181 @@
 }
 
 
-OStream& operator<<(OStream& os, const Schedule& s) {
+std::ostream& operator<<(std::ostream& os, const BasicBlock::Id& id) {
+  return os << id.ToSize();
+}
+
+
+std::ostream& operator<<(std::ostream& os, const BasicBlock::RpoNumber& rpo) {
+  return os << rpo.ToSize();
+}
+
+
+Schedule::Schedule(Zone* zone, size_t node_count_hint)
+    : zone_(zone),
+      all_blocks_(zone),
+      nodeid_to_block_(zone),
+      rpo_order_(zone),
+      start_(NewBasicBlock()),
+      end_(NewBasicBlock()) {
+  nodeid_to_block_.reserve(node_count_hint);
+}
+
+
+BasicBlock* Schedule::block(Node* node) const {
+  if (node->id() < static_cast<NodeId>(nodeid_to_block_.size())) {
+    return nodeid_to_block_[node->id()];
+  }
+  return NULL;
+}
+
+
+bool Schedule::IsScheduled(Node* node) {
+  int length = static_cast<int>(nodeid_to_block_.size());
+  if (node->id() >= length) return false;
+  return nodeid_to_block_[node->id()] != NULL;
+}
+
+
+BasicBlock* Schedule::GetBlockById(BasicBlock::Id block_id) {
+  DCHECK(block_id.ToSize() < all_blocks_.size());
+  return all_blocks_[block_id.ToSize()];
+}
+
+
+bool Schedule::SameBasicBlock(Node* a, Node* b) const {
+  BasicBlock* block = this->block(a);
+  return block != NULL && block == this->block(b);
+}
+
+
+BasicBlock* Schedule::NewBasicBlock() {
+  BasicBlock* block = new (zone_)
+      BasicBlock(zone_, BasicBlock::Id::FromSize(all_blocks_.size()));
+  all_blocks_.push_back(block);
+  return block;
+}
+
+
+void Schedule::PlanNode(BasicBlock* block, Node* node) {
+  if (FLAG_trace_turbo_scheduler) {
+    OFStream os(stdout);
+    os << "Planning #" << node->id() << ":" << node->op()->mnemonic()
+       << " for future add to B" << block->id() << "\n";
+  }
+  DCHECK(this->block(node) == NULL);
+  SetBlockForNode(block, node);
+}
+
+
+void Schedule::AddNode(BasicBlock* block, Node* node) {
+  if (FLAG_trace_turbo_scheduler) {
+    OFStream os(stdout);
+    os << "Adding #" << node->id() << ":" << node->op()->mnemonic() << " to B"
+       << block->id() << "\n";
+  }
+  DCHECK(this->block(node) == NULL || this->block(node) == block);
+  block->AddNode(node);
+  SetBlockForNode(block, node);
+}
+
+
+void Schedule::AddGoto(BasicBlock* block, BasicBlock* succ) {
+  DCHECK(block->control() == BasicBlock::kNone);
+  block->set_control(BasicBlock::kGoto);
+  AddSuccessor(block, succ);
+}
+
+
+void Schedule::AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock,
+                         BasicBlock* fblock) {
+  DCHECK(block->control() == BasicBlock::kNone);
+  DCHECK(branch->opcode() == IrOpcode::kBranch);
+  block->set_control(BasicBlock::kBranch);
+  AddSuccessor(block, tblock);
+  AddSuccessor(block, fblock);
+  SetControlInput(block, branch);
+}
+
+
+void Schedule::AddReturn(BasicBlock* block, Node* input) {
+  DCHECK(block->control() == BasicBlock::kNone);
+  block->set_control(BasicBlock::kReturn);
+  SetControlInput(block, input);
+  if (block != end()) AddSuccessor(block, end());
+}
+
+
+void Schedule::AddThrow(BasicBlock* block, Node* input) {
+  DCHECK(block->control() == BasicBlock::kNone);
+  block->set_control(BasicBlock::kThrow);
+  SetControlInput(block, input);
+  if (block != end()) AddSuccessor(block, end());
+}
+
+
+void Schedule::InsertBranch(BasicBlock* block, BasicBlock* end, Node* branch,
+                            BasicBlock* tblock, BasicBlock* fblock) {
+  DCHECK(block->control() != BasicBlock::kNone);
+  DCHECK(end->control() == BasicBlock::kNone);
+  end->set_control(block->control());
+  block->set_control(BasicBlock::kBranch);
+  MoveSuccessors(block, end);
+  AddSuccessor(block, tblock);
+  AddSuccessor(block, fblock);
+  if (block->control_input() != NULL) {
+    SetControlInput(end, block->control_input());
+  }
+  SetControlInput(block, branch);
+}
+
+
+void Schedule::AddSuccessor(BasicBlock* block, BasicBlock* succ) {
+  block->AddSuccessor(succ);
+  succ->AddPredecessor(block);
+}
+
+
+void Schedule::MoveSuccessors(BasicBlock* from, BasicBlock* to) {
+  for (BasicBlock::Predecessors::iterator i = from->successors_begin();
+       i != from->successors_end(); ++i) {
+    BasicBlock* succ = *i;
+    to->AddSuccessor(succ);
+    for (BasicBlock::Predecessors::iterator j = succ->predecessors_begin();
+         j != succ->predecessors_end(); ++j) {
+      if (*j == from) *j = to;
+    }
+  }
+  from->ClearSuccessors();
+}
+
+
+void Schedule::SetControlInput(BasicBlock* block, Node* node) {
+  block->set_control_input(node);
+  SetBlockForNode(block, node);
+}
+
+
+void Schedule::SetBlockForNode(BasicBlock* block, Node* node) {
+  int length = static_cast<int>(nodeid_to_block_.size());
+  if (node->id() >= length) {
+    nodeid_to_block_.resize(node->id() + 1);
+  }
+  nodeid_to_block_[node->id()] = block;
+}
+
+
+std::ostream& operator<<(std::ostream& os, const Schedule& s) {
   // TODO(svenpanne) Const-correct the RPO stuff/iterators.
   BasicBlockVector* rpo = const_cast<Schedule*>(&s)->rpo_order();
   for (BasicBlockVectorIter i = rpo->begin(); i != rpo->end(); ++i) {
     BasicBlock* block = *i;
     os << "--- BLOCK B" << block->id();
+    if (block->deferred()) os << " (deferred)";
     if (block->PredecessorCount() != 0) os << " <- ";
-    BasicBlock::Predecessors predecessors = block->predecessors();
     bool comma = false;
-    for (BasicBlock::Predecessors::iterator j = predecessors.begin();
-         j != predecessors.end(); ++j) {
+    for (BasicBlock::Predecessors::iterator j = block->predecessors_begin();
+         j != block->predecessors_end(); ++j) {
       if (comma) os << ", ";
       comma = true;
       os << "B" << (*j)->id();
@@ -50,7 +283,7 @@
          ++j) {
       Node* node = *j;
       os << "  " << *node;
-      if (!NodeProperties::IsControl(node)) {
+      if (NodeProperties::IsTyped(node)) {
         Bounds bounds = NodeProperties::GetBounds(node);
         os << " : ";
         bounds.lower->PrintTo(os);
@@ -61,19 +294,18 @@
       }
       os << "\n";
     }
-    BasicBlock::Control control = block->control_;
+    BasicBlock::Control control = block->control();
     if (control != BasicBlock::kNone) {
       os << "  ";
-      if (block->control_input_ != NULL) {
-        os << *block->control_input_;
+      if (block->control_input() != NULL) {
+        os << *block->control_input();
       } else {
         os << "Goto";
       }
       os << " -> ";
-      BasicBlock::Successors successors = block->successors();
       comma = false;
-      for (BasicBlock::Successors::iterator j = successors.begin();
-           j != successors.end(); ++j) {
+      for (BasicBlock::Successors::iterator j = block->successors_begin();
+           j != block->successors_end(); ++j) {
         if (comma) os << ", ";
         comma = true;
         os << "B" << (*j)->id();
@@ -83,6 +315,7 @@
   }
   return os;
 }
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/schedule.h b/src/compiler/schedule.h
index 070691e..0bba689 100644
--- a/src/compiler/schedule.h
+++ b/src/compiler/schedule.h
@@ -5,14 +5,11 @@
 #ifndef V8_COMPILER_SCHEDULE_H_
 #define V8_COMPILER_SCHEDULE_H_
 
+#include <iosfwd>
 #include <vector>
 
 #include "src/v8.h"
 
-#include "src/compiler/generic-algorithm.h"
-#include "src/compiler/generic-graph.h"
-#include "src/compiler/generic-node.h"
-#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/node.h"
 #include "src/compiler/opcodes.h"
 #include "src/zone.h"
@@ -22,11 +19,15 @@
 namespace compiler {
 
 class BasicBlock;
+class BasicBlockInstrumentor;
 class Graph;
 class ConstructScheduleData;
 class CodeGenerator;  // Because of a namespace bug in clang.
 
-class BasicBlockData {
+// A basic block contains an ordered list of nodes and ends with a control
+// node. Note that if a basic block has phis, then all phis must appear as the
+// first nodes in the block.
+class BasicBlock FINAL : public ZoneObject {
  public:
   // Possible control nodes that can end a block.
   enum Control {
@@ -37,94 +38,83 @@
     kThrow    // Throw an exception.
   };
 
-  int32_t rpo_number_;       // special RPO number of the block.
-  BasicBlock* dominator_;    // Immediate dominator of the block.
-  BasicBlock* loop_header_;  // Pointer to dominating loop header basic block,
-                             // NULL if none. For loop headers, this points to
-                             // enclosing loop header.
-  int32_t loop_depth_;       // loop nesting, 0 is top-level
-  int32_t loop_end_;         // end of the loop, if this block is a loop header.
-  int32_t code_start_;       // start index of arch-specific code.
-  int32_t code_end_;         // end index of arch-specific code.
-  bool deferred_;            // {true} if this block is considered the slow
-                             // path.
-  Control control_;          // Control at the end of the block.
-  Node* control_input_;      // Input value for control.
-  NodeVector nodes_;         // nodes of this block in forward order.
+  class Id {
+   public:
+    int ToInt() const { return static_cast<int>(index_); }
+    size_t ToSize() const { return index_; }
+    static Id FromSize(size_t index) { return Id(index); }
+    static Id FromInt(int index) { return Id(static_cast<size_t>(index)); }
 
-  explicit BasicBlockData(Zone* zone)
-      : rpo_number_(-1),
-        dominator_(NULL),
-        loop_header_(NULL),
-        loop_depth_(0),
-        loop_end_(-1),
-        code_start_(-1),
-        code_end_(-1),
-        deferred_(false),
-        control_(kNone),
-        control_input_(NULL),
-        nodes_(zone) {}
+   private:
+    explicit Id(size_t index) : index_(index) {}
+    size_t index_;
+  };
 
-  inline bool IsLoopHeader() const { return loop_end_ >= 0; }
-  inline bool LoopContains(BasicBlockData* block) const {
-    // RPO numbers must be initialized.
-    DCHECK(rpo_number_ >= 0);
-    DCHECK(block->rpo_number_ >= 0);
-    if (loop_end_ < 0) return false;  // This is not a loop.
-    return block->rpo_number_ >= rpo_number_ && block->rpo_number_ < loop_end_;
-  }
-  int first_instruction_index() {
-    DCHECK(code_start_ >= 0);
-    DCHECK(code_end_ > 0);
-    DCHECK(code_end_ >= code_start_);
-    return code_start_;
-  }
-  int last_instruction_index() {
-    DCHECK(code_start_ >= 0);
-    DCHECK(code_end_ > 0);
-    DCHECK(code_end_ >= code_start_);
-    return code_end_ - 1;
-  }
-};
-
-OStream& operator<<(OStream& os, const BasicBlockData::Control& c);
-
-// A basic block contains an ordered list of nodes and ends with a control
-// node. Note that if a basic block has phis, then all phis must appear as the
-// first nodes in the block.
-class BasicBlock FINAL : public GenericNode<BasicBlockData, BasicBlock> {
- public:
-  BasicBlock(GenericGraphBase* graph, int input_count)
-      : GenericNode<BasicBlockData, BasicBlock>(graph, input_count) {}
-
-  typedef Uses Successors;
-  typedef Inputs Predecessors;
-
-  Successors successors() { return static_cast<Successors>(uses()); }
-  Predecessors predecessors() { return static_cast<Predecessors>(inputs()); }
-
-  int PredecessorCount() { return InputCount(); }
-  BasicBlock* PredecessorAt(int index) { return InputAt(index); }
-
-  int SuccessorCount() { return UseCount(); }
-  BasicBlock* SuccessorAt(int index) { return UseAt(index); }
-
-  int PredecessorIndexOf(BasicBlock* predecessor) {
-    BasicBlock::Predecessors predecessors = this->predecessors();
-    for (BasicBlock::Predecessors::iterator i = predecessors.begin();
-         i != predecessors.end(); ++i) {
-      if (*i == predecessor) return i.index();
+  static const int kInvalidRpoNumber = -1;
+  class RpoNumber FINAL {
+   public:
+    int ToInt() const {
+      DCHECK(IsValid());
+      return index_;
     }
-    return -1;
-  }
+    size_t ToSize() const {
+      DCHECK(IsValid());
+      return static_cast<size_t>(index_);
+    }
+    bool IsValid() const { return index_ >= 0; }
+    static RpoNumber FromInt(int index) { return RpoNumber(index); }
+    static RpoNumber Invalid() { return RpoNumber(kInvalidRpoNumber); }
 
-  inline BasicBlock* loop_header() {
-    return static_cast<BasicBlock*>(loop_header_);
+    bool IsNext(const RpoNumber other) const {
+      DCHECK(IsValid());
+      return other.index_ == this->index_ + 1;
+    }
+
+    bool operator==(RpoNumber other) const {
+      return this->index_ == other.index_;
+    }
+
+   private:
+    explicit RpoNumber(int32_t index) : index_(index) {}
+    int32_t index_;
+  };
+
+  BasicBlock(Zone* zone, Id id);
+
+  Id id() const { return id_; }
+
+  // Predecessors and successors.
+  typedef ZoneVector<BasicBlock*> Predecessors;
+  Predecessors::iterator predecessors_begin() { return predecessors_.begin(); }
+  Predecessors::iterator predecessors_end() { return predecessors_.end(); }
+  Predecessors::const_iterator predecessors_begin() const {
+    return predecessors_.begin();
   }
-  inline BasicBlock* ContainingLoop() {
-    if (IsLoopHeader()) return this;
-    return static_cast<BasicBlock*>(loop_header_);
+  Predecessors::const_iterator predecessors_end() const {
+    return predecessors_.end();
   }
+  size_t PredecessorCount() const { return predecessors_.size(); }
+  BasicBlock* PredecessorAt(size_t index) { return predecessors_[index]; }
+  void ClearPredecessors() { predecessors_.clear(); }
+  void AddPredecessor(BasicBlock* predecessor);
+
+  typedef ZoneVector<BasicBlock*> Successors;
+  Successors::iterator successors_begin() { return successors_.begin(); }
+  Successors::iterator successors_end() { return successors_.end(); }
+  Successors::const_iterator successors_begin() const {
+    return successors_.begin();
+  }
+  Successors::const_iterator successors_end() const {
+    return successors_.end();
+  }
+  size_t SuccessorCount() const { return successors_.size(); }
+  BasicBlock* SuccessorAt(size_t index) { return successors_[index]; }
+  void ClearSuccessors() { successors_.clear(); }
+  void AddSuccessor(BasicBlock* successor);
+
+  // Nodes in the basic block.
+  Node* NodeAt(size_t index) { return nodes_[index]; }
+  size_t NodeCount() const { return nodes_.size(); }
 
   typedef NodeVector::iterator iterator;
   iterator begin() { return nodes_.begin(); }
@@ -138,12 +128,79 @@
   reverse_iterator rbegin() { return nodes_.rbegin(); }
   reverse_iterator rend() { return nodes_.rend(); }
 
+  void AddNode(Node* node);
+  template <class InputIterator>
+  void InsertNodes(iterator insertion_point, InputIterator insertion_start,
+                   InputIterator insertion_end) {
+    nodes_.insert(insertion_point, insertion_start, insertion_end);
+  }
+
+  // Accessors.
+  Control control() const { return control_; }
+  void set_control(Control control);
+
+  Node* control_input() const { return control_input_; }
+  void set_control_input(Node* control_input);
+
+  bool deferred() const { return deferred_; }
+  void set_deferred(bool deferred) { deferred_ = deferred; }
+
+  int32_t dominator_depth() const { return dominator_depth_; }
+  void set_dominator_depth(int32_t depth) { dominator_depth_ = depth; }
+
+  BasicBlock* dominator() const { return dominator_; }
+  void set_dominator(BasicBlock* dominator) { dominator_ = dominator; }
+
+  BasicBlock* rpo_next() const { return rpo_next_; }
+  void set_rpo_next(BasicBlock* rpo_next) { rpo_next_ = rpo_next; }
+
+  BasicBlock* loop_header() const { return loop_header_; }
+  void set_loop_header(BasicBlock* loop_header);
+
+  BasicBlock* loop_end() const { return loop_end_; }
+  void set_loop_end(BasicBlock* loop_end);
+
+  int32_t loop_depth() const { return loop_depth_; }
+  void set_loop_depth(int32_t loop_depth);
+
+  int32_t loop_number() const { return loop_number_; }
+  void set_loop_number(int32_t loop_number) { loop_number_ = loop_number; }
+
+  RpoNumber GetRpoNumber() const { return RpoNumber::FromInt(rpo_number_); }
+  int32_t rpo_number() const { return rpo_number_; }
+  void set_rpo_number(int32_t rpo_number);
+
+  // Loop membership helpers.
+  inline bool IsLoopHeader() const { return loop_end_ != NULL; }
+  bool LoopContains(BasicBlock* block) const;
+
  private:
+  int32_t loop_number_;      // loop number of the block.
+  int32_t rpo_number_;       // special RPO number of the block.
+  bool deferred_;            // true if the block contains deferred code.
+  int32_t dominator_depth_;  // Depth within the dominator tree.
+  BasicBlock* dominator_;    // Immediate dominator of the block.
+  BasicBlock* rpo_next_;     // Link to next block in special RPO order.
+  BasicBlock* loop_header_;  // Pointer to dominating loop header basic block,
+                             // NULL if none. For loop headers, this points to
+                             // enclosing loop header.
+  BasicBlock* loop_end_;     // end of the loop, if this block is a loop header.
+  int32_t loop_depth_;       // loop nesting, 0 is top-level
+
+  Control control_;          // Control at the end of the block.
+  Node* control_input_;      // Input value for control.
+  NodeVector nodes_;         // nodes of this block in forward order.
+
+  Successors successors_;
+  Predecessors predecessors_;
+  Id id_;
+
   DISALLOW_COPY_AND_ASSIGN(BasicBlock);
 };
 
-typedef GenericGraphVisit::NullNodeVisitor<BasicBlockData, BasicBlock>
-    NullBasicBlockVisitor;
+std::ostream& operator<<(std::ostream& os, const BasicBlock::Control& c);
+std::ostream& operator<<(std::ostream& os, const BasicBlock::Id& id);
+std::ostream& operator<<(std::ostream& os, const BasicBlock::RpoNumber& rpo);
 
 typedef ZoneVector<BasicBlock*> BasicBlockVector;
 typedef BasicBlockVector::iterator BasicBlockVectorIter;
@@ -153,154 +210,86 @@
 // and ordering them within basic blocks. Prior to computing a schedule,
 // a graph has no notion of control flow ordering other than that induced
 // by the graph's dependencies. A schedule is required to generate code.
-class Schedule : public GenericGraph<BasicBlock> {
+class Schedule FINAL : public ZoneObject {
  public:
-  explicit Schedule(Zone* zone)
-      : GenericGraph<BasicBlock>(zone),
-        zone_(zone),
-        all_blocks_(zone),
-        nodeid_to_block_(zone),
-        rpo_order_(zone) {
-    SetStart(NewBasicBlock());  // entry.
-    SetEnd(NewBasicBlock());    // exit.
-  }
+  explicit Schedule(Zone* zone, size_t node_count_hint = 0);
 
   // Return the block which contains {node}, if any.
-  BasicBlock* block(Node* node) const {
-    if (node->id() < static_cast<NodeId>(nodeid_to_block_.size())) {
-      return nodeid_to_block_[node->id()];
-    }
-    return NULL;
-  }
+  BasicBlock* block(Node* node) const;
 
-  bool IsScheduled(Node* node) {
-    int length = static_cast<int>(nodeid_to_block_.size());
-    if (node->id() >= length) return false;
-    return nodeid_to_block_[node->id()] != NULL;
-  }
+  bool IsScheduled(Node* node);
+  BasicBlock* GetBlockById(BasicBlock::Id block_id);
 
-  BasicBlock* GetBlockById(int block_id) { return all_blocks_[block_id]; }
-
-  int BasicBlockCount() const { return NodeCount(); }
-  int RpoBlockCount() const { return static_cast<int>(rpo_order_.size()); }
-
-  typedef ContainerPointerWrapper<BasicBlockVector> BasicBlocks;
-
-  // Return a list of all the blocks in the schedule, in arbitrary order.
-  BasicBlocks all_blocks() { return BasicBlocks(&all_blocks_); }
+  size_t BasicBlockCount() const { return all_blocks_.size(); }
+  size_t RpoBlockCount() const { return rpo_order_.size(); }
 
   // Check if nodes {a} and {b} are in the same block.
-  inline bool SameBasicBlock(Node* a, Node* b) const {
-    BasicBlock* block = this->block(a);
-    return block != NULL && block == this->block(b);
-  }
+  bool SameBasicBlock(Node* a, Node* b) const;
 
   // BasicBlock building: create a new block.
-  inline BasicBlock* NewBasicBlock() {
-    BasicBlock* block =
-        BasicBlock::New(this, 0, static_cast<BasicBlock**>(NULL));
-    all_blocks_.push_back(block);
-    return block;
-  }
+  BasicBlock* NewBasicBlock();
 
   // BasicBlock building: records that a node will later be added to a block but
   // doesn't actually add the node to the block.
-  inline void PlanNode(BasicBlock* block, Node* node) {
-    if (FLAG_trace_turbo_scheduler) {
-      PrintF("Planning #%d:%s for future add to B%d\n", node->id(),
-             node->op()->mnemonic(), block->id());
-    }
-    DCHECK(this->block(node) == NULL);
-    SetBlockForNode(block, node);
-  }
+  void PlanNode(BasicBlock* block, Node* node);
 
   // BasicBlock building: add a node to the end of the block.
-  inline void AddNode(BasicBlock* block, Node* node) {
-    if (FLAG_trace_turbo_scheduler) {
-      PrintF("Adding #%d:%s to B%d\n", node->id(), node->op()->mnemonic(),
-             block->id());
-    }
-    DCHECK(this->block(node) == NULL || this->block(node) == block);
-    block->nodes_.push_back(node);
-    SetBlockForNode(block, node);
-  }
+  void AddNode(BasicBlock* block, Node* node);
 
   // BasicBlock building: add a goto to the end of {block}.
-  void AddGoto(BasicBlock* block, BasicBlock* succ) {
-    DCHECK(block->control_ == BasicBlock::kNone);
-    block->control_ = BasicBlock::kGoto;
-    AddSuccessor(block, succ);
-  }
+  void AddGoto(BasicBlock* block, BasicBlock* succ);
 
   // BasicBlock building: add a branch at the end of {block}.
   void AddBranch(BasicBlock* block, Node* branch, BasicBlock* tblock,
-                 BasicBlock* fblock) {
-    DCHECK(block->control_ == BasicBlock::kNone);
-    DCHECK(branch->opcode() == IrOpcode::kBranch);
-    block->control_ = BasicBlock::kBranch;
-    AddSuccessor(block, tblock);
-    AddSuccessor(block, fblock);
-    SetControlInput(block, branch);
-    if (branch->opcode() == IrOpcode::kBranch) {
-      // TODO(titzer): require a Branch node here. (sloppy tests).
-      SetBlockForNode(block, branch);
-    }
-  }
+                 BasicBlock* fblock);
 
   // BasicBlock building: add a return at the end of {block}.
-  void AddReturn(BasicBlock* block, Node* input) {
-    DCHECK(block->control_ == BasicBlock::kNone);
-    block->control_ = BasicBlock::kReturn;
-    SetControlInput(block, input);
-    if (block != end()) AddSuccessor(block, end());
-    if (input->opcode() == IrOpcode::kReturn) {
-      // TODO(titzer): require a Return node here. (sloppy tests).
-      SetBlockForNode(block, input);
-    }
-  }
+  void AddReturn(BasicBlock* block, Node* input);
 
   // BasicBlock building: add a throw at the end of {block}.
-  void AddThrow(BasicBlock* block, Node* input) {
-    DCHECK(block->control_ == BasicBlock::kNone);
-    block->control_ = BasicBlock::kThrow;
-    SetControlInput(block, input);
-    if (block != end()) AddSuccessor(block, end());
-  }
+  void AddThrow(BasicBlock* block, Node* input);
 
-  friend class Scheduler;
-  friend class CodeGenerator;
+  // BasicBlock mutation: insert a branch into the end of {block}.
+  void InsertBranch(BasicBlock* block, BasicBlock* end, Node* branch,
+                    BasicBlock* tblock, BasicBlock* fblock);
 
-  void AddSuccessor(BasicBlock* block, BasicBlock* succ) {
-    succ->AppendInput(zone_, block);
+  // Exposed publicly for testing only.
+  void AddSuccessorForTesting(BasicBlock* block, BasicBlock* succ) {
+    return AddSuccessor(block, succ);
   }
 
   BasicBlockVector* rpo_order() { return &rpo_order_; }
+  const BasicBlockVector* rpo_order() const { return &rpo_order_; }
+
+  BasicBlock* start() { return start_; }
+  BasicBlock* end() { return end_; }
+
+  Zone* zone() const { return zone_; }
 
  private:
-  friend class ScheduleVisualizer;
+  friend class Scheduler;
+  friend class BasicBlockInstrumentor;
 
-  void SetControlInput(BasicBlock* block, Node* node) {
-    block->control_input_ = node;
-    SetBlockForNode(block, node);
-  }
+  void AddSuccessor(BasicBlock* block, BasicBlock* succ);
+  void MoveSuccessors(BasicBlock* from, BasicBlock* to);
 
-  void SetBlockForNode(BasicBlock* block, Node* node) {
-    int length = static_cast<int>(nodeid_to_block_.size());
-    if (node->id() >= length) {
-      nodeid_to_block_.resize(node->id() + 1);
-    }
-    nodeid_to_block_[node->id()] = block;
-  }
+  void SetControlInput(BasicBlock* block, Node* node);
+  void SetBlockForNode(BasicBlock* block, Node* node);
 
   Zone* zone_;
   BasicBlockVector all_blocks_;           // All basic blocks in the schedule.
   BasicBlockVector nodeid_to_block_;      // Map from node to containing block.
   BasicBlockVector rpo_order_;            // Reverse-post-order block list.
+  BasicBlock* start_;
+  BasicBlock* end_;
+
+  DISALLOW_COPY_AND_ASSIGN(Schedule);
 };
 
-OStream& operator<<(OStream& os, const Schedule& s);
-}
-}
-}  // namespace v8::internal::compiler
+std::ostream& operator<<(std::ostream& os, const Schedule& s);
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_SCHEDULE_H_
diff --git a/src/compiler/scheduler.cc b/src/compiler/scheduler.cc
index 4029950..f12c631 100644
--- a/src/compiler/scheduler.cc
+++ b/src/compiler/scheduler.cc
@@ -7,12 +7,13 @@
 
 #include "src/compiler/scheduler.h"
 
+#include "src/bit-vector.h"
+#include "src/compiler/control-equivalence.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/graph-inl.h"
 #include "src/compiler/node.h"
 #include "src/compiler/node-properties.h"
 #include "src/compiler/node-properties-inl.h"
-#include "src/data-flow.h"
 
 namespace v8 {
 namespace internal {
@@ -28,30 +29,225 @@
 }
 
 
-// Internal class to build a control flow graph (i.e the basic blocks and edges
-// between them within a Schedule) from the node graph.
-// Visits the control edges of the graph backwards from end in order to find
-// the connected control subgraph, needed for scheduling.
-class CFGBuilder {
- public:
-  Scheduler* scheduler_;
-  Schedule* schedule_;
-  ZoneQueue<Node*> queue_;
-  NodeVector control_;
+Scheduler::Scheduler(Zone* zone, Graph* graph, Schedule* schedule)
+    : zone_(zone),
+      graph_(graph),
+      schedule_(schedule),
+      scheduled_nodes_(zone),
+      schedule_root_nodes_(zone),
+      schedule_queue_(zone),
+      node_data_(graph_->NodeCount(), DefaultSchedulerData(), zone) {}
 
+
+Schedule* Scheduler::ComputeSchedule(Zone* zone, Graph* graph) {
+  Schedule* schedule = new (graph->zone())
+      Schedule(graph->zone(), static_cast<size_t>(graph->NodeCount()));
+  Scheduler scheduler(zone, graph, schedule);
+
+  scheduler.BuildCFG();
+  scheduler.ComputeSpecialRPONumbering();
+  scheduler.GenerateImmediateDominatorTree();
+
+  scheduler.PrepareUses();
+  scheduler.ScheduleEarly();
+  scheduler.ScheduleLate();
+
+  scheduler.SealFinalSchedule();
+
+  return schedule;
+}
+
+
+Scheduler::SchedulerData Scheduler::DefaultSchedulerData() {
+  SchedulerData def = {schedule_->start(), 0, kUnknown};
+  return def;
+}
+
+
+Scheduler::SchedulerData* Scheduler::GetData(Node* node) {
+  DCHECK(node->id() < static_cast<int>(node_data_.size()));
+  return &node_data_[node->id()];
+}
+
+
+Scheduler::Placement Scheduler::GetPlacement(Node* node) {
+  SchedulerData* data = GetData(node);
+  if (data->placement_ == kUnknown) {  // Compute placement, once, on demand.
+    switch (node->opcode()) {
+      case IrOpcode::kParameter:
+        // Parameters are always fixed to the start node.
+        data->placement_ = kFixed;
+        break;
+      case IrOpcode::kPhi:
+      case IrOpcode::kEffectPhi: {
+        // Phis and effect phis are fixed if their control inputs are, whereas
+        // otherwise they are coupled to a floating control node.
+        Placement p = GetPlacement(NodeProperties::GetControlInput(node));
+        data->placement_ = (p == kFixed ? kFixed : kCoupled);
+        break;
+      }
+#define DEFINE_CONTROL_CASE(V) case IrOpcode::k##V:
+      CONTROL_OP_LIST(DEFINE_CONTROL_CASE)
+#undef DEFINE_CONTROL_CASE
+      {
+        // Control nodes that were not control-reachable from end may float.
+        data->placement_ = kSchedulable;
+        break;
+      }
+      default:
+        data->placement_ = kSchedulable;
+        break;
+    }
+  }
+  return data->placement_;
+}
+
+
+void Scheduler::UpdatePlacement(Node* node, Placement placement) {
+  SchedulerData* data = GetData(node);
+  if (data->placement_ != kUnknown) {  // Trap on mutation, not initialization.
+    switch (node->opcode()) {
+      case IrOpcode::kParameter:
+        // Parameters are fixed once and for all.
+        UNREACHABLE();
+        break;
+      case IrOpcode::kPhi:
+      case IrOpcode::kEffectPhi: {
+        // Phis and effect phis are coupled to their respective blocks.
+        DCHECK_EQ(Scheduler::kCoupled, data->placement_);
+        DCHECK_EQ(Scheduler::kFixed, placement);
+        Node* control = NodeProperties::GetControlInput(node);
+        BasicBlock* block = schedule_->block(control);
+        schedule_->AddNode(block, node);
+        break;
+      }
+#define DEFINE_CONTROL_CASE(V) case IrOpcode::k##V:
+      CONTROL_OP_LIST(DEFINE_CONTROL_CASE)
+#undef DEFINE_CONTROL_CASE
+      {
+        // Control nodes force coupled uses to be placed.
+        Node::Uses uses = node->uses();
+        for (Node::Uses::iterator i = uses.begin(); i != uses.end(); ++i) {
+          if (GetPlacement(*i) == Scheduler::kCoupled) {
+            DCHECK_EQ(node, NodeProperties::GetControlInput(*i));
+            UpdatePlacement(*i, placement);
+          }
+        }
+        break;
+      }
+      default:
+        DCHECK_EQ(Scheduler::kSchedulable, data->placement_);
+        DCHECK_EQ(Scheduler::kScheduled, placement);
+        break;
+    }
+    // Reduce the use count of the node's inputs to potentially make them
+    // schedulable. If all the uses of a node have been scheduled, then the node
+    // itself can be scheduled.
+    for (Edge const edge : node->input_edges()) {
+      DecrementUnscheduledUseCount(edge.to(), edge.index(), edge.from());
+    }
+  }
+  data->placement_ = placement;
+}
+
+
+bool Scheduler::IsCoupledControlEdge(Node* node, int index) {
+  return GetPlacement(node) == kCoupled &&
+         NodeProperties::FirstControlIndex(node) == index;
+}
+
+
+void Scheduler::IncrementUnscheduledUseCount(Node* node, int index,
+                                             Node* from) {
+  // Make sure that control edges from coupled nodes are not counted.
+  if (IsCoupledControlEdge(from, index)) return;
+
+  // Tracking use counts for fixed nodes is useless.
+  if (GetPlacement(node) == kFixed) return;
+
+  // Use count for coupled nodes is summed up on their control.
+  if (GetPlacement(node) == kCoupled) {
+    Node* control = NodeProperties::GetControlInput(node);
+    return IncrementUnscheduledUseCount(control, index, from);
+  }
+
+  ++(GetData(node)->unscheduled_count_);
+  if (FLAG_trace_turbo_scheduler) {
+    Trace("  Use count of #%d:%s (used by #%d:%s)++ = %d\n", node->id(),
+          node->op()->mnemonic(), from->id(), from->op()->mnemonic(),
+          GetData(node)->unscheduled_count_);
+  }
+}
+
+
+void Scheduler::DecrementUnscheduledUseCount(Node* node, int index,
+                                             Node* from) {
+  // Make sure that control edges from coupled nodes are not counted.
+  if (IsCoupledControlEdge(from, index)) return;
+
+  // Tracking use counts for fixed nodes is useless.
+  if (GetPlacement(node) == kFixed) return;
+
+  // Use count for coupled nodes is summed up on their control.
+  if (GetPlacement(node) == kCoupled) {
+    Node* control = NodeProperties::GetControlInput(node);
+    return DecrementUnscheduledUseCount(control, index, from);
+  }
+
+  DCHECK(GetData(node)->unscheduled_count_ > 0);
+  --(GetData(node)->unscheduled_count_);
+  if (FLAG_trace_turbo_scheduler) {
+    Trace("  Use count of #%d:%s (used by #%d:%s)-- = %d\n", node->id(),
+          node->op()->mnemonic(), from->id(), from->op()->mnemonic(),
+          GetData(node)->unscheduled_count_);
+  }
+  if (GetData(node)->unscheduled_count_ == 0) {
+    Trace("    newly eligible #%d:%s\n", node->id(), node->op()->mnemonic());
+    schedule_queue_.push(node);
+  }
+}
+
+
+BasicBlock* Scheduler::GetCommonDominator(BasicBlock* b1, BasicBlock* b2) {
+  while (b1 != b2) {
+    int32_t b1_depth = b1->dominator_depth();
+    int32_t b2_depth = b2->dominator_depth();
+    if (b1_depth < b2_depth) {
+      b2 = b2->dominator();
+    } else {
+      b1 = b1->dominator();
+    }
+  }
+  return b1;
+}
+
+
+// -----------------------------------------------------------------------------
+// Phase 1: Build control-flow graph.
+
+
+// Internal class to build a control flow graph (i.e the basic blocks and edges
+// between them within a Schedule) from the node graph. Visits control edges of
+// the graph backwards from an end node in order to find the connected control
+// subgraph, needed for scheduling.
+class CFGBuilder : public ZoneObject {
+ public:
   CFGBuilder(Zone* zone, Scheduler* scheduler)
       : scheduler_(scheduler),
         schedule_(scheduler->schedule_),
+        queued_(scheduler->graph_, 2),
         queue_(zone),
-        control_(zone) {}
+        control_(zone),
+        component_entry_(NULL),
+        component_start_(NULL),
+        component_end_(NULL) {}
 
   // Run the control flow graph construction algorithm by walking the graph
   // backwards from end through control edges, building and connecting the
   // basic blocks for control nodes.
   void Run() {
-    Graph* graph = scheduler_->graph_;
-    FixNode(schedule_->start(), graph->start());
-    Queue(graph->end());
+    ResetDataStructures();
+    Queue(scheduler_->graph_->end());
 
     while (!queue_.empty()) {  // Breadth-first backwards traversal.
       Node* node = queue_.front();
@@ -65,33 +261,82 @@
     for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) {
       ConnectBlocks(*i);  // Connect block to its predecessor/successors.
     }
-
-    FixNode(schedule_->end(), graph->end());
   }
 
+  // Run the control flow graph construction for a minimal control-connected
+  // component ending in {exit} and merge that component into an existing
+  // control flow graph at the bottom of {block}.
+  void Run(BasicBlock* block, Node* exit) {
+    ResetDataStructures();
+    Queue(exit);
+
+    component_entry_ = NULL;
+    component_start_ = block;
+    component_end_ = schedule_->block(exit);
+    scheduler_->equivalence_->Run(exit);
+    while (!queue_.empty()) {  // Breadth-first backwards traversal.
+      Node* node = queue_.front();
+      queue_.pop();
+
+      // Use control dependence equivalence to find a canonical single-entry
+      // single-exit region that makes up a minimal component to be scheduled.
+      if (IsSingleEntrySingleExitRegion(node, exit)) {
+        Trace("Found SESE at #%d:%s\n", node->id(), node->op()->mnemonic());
+        DCHECK_EQ(NULL, component_entry_);
+        component_entry_ = node;
+        continue;
+      }
+
+      int max = NodeProperties::PastControlIndex(node);
+      for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) {
+        Queue(node->InputAt(i));
+      }
+    }
+    DCHECK_NE(NULL, component_entry_);
+
+    for (NodeVector::iterator i = control_.begin(); i != control_.end(); ++i) {
+      ConnectBlocks(*i);  // Connect block to its predecessor/successors.
+    }
+  }
+
+ private:
+  // TODO(mstarzinger): Only for Scheduler::FuseFloatingControl.
+  friend class Scheduler;
+
   void FixNode(BasicBlock* block, Node* node) {
     schedule_->AddNode(block, node);
-    scheduler_->GetData(node)->is_connected_control_ = true;
-    scheduler_->GetData(node)->placement_ = Scheduler::kFixed;
+    scheduler_->UpdatePlacement(node, Scheduler::kFixed);
   }
 
   void Queue(Node* node) {
-    // Mark the connected control nodes as they queued.
-    Scheduler::SchedulerData* data = scheduler_->GetData(node);
-    if (!data->is_connected_control_) {
+    // Mark the connected control nodes as they are queued.
+    if (!queued_.Get(node)) {
       BuildBlocks(node);
       queue_.push(node);
+      queued_.Set(node, true);
       control_.push_back(node);
-      data->is_connected_control_ = true;
     }
   }
 
   void BuildBlocks(Node* node) {
     switch (node->opcode()) {
+      case IrOpcode::kEnd:
+        FixNode(schedule_->end(), node);
+        break;
+      case IrOpcode::kStart:
+        FixNode(schedule_->start(), node);
+        break;
       case IrOpcode::kLoop:
       case IrOpcode::kMerge:
         BuildBlockForNode(node);
         break;
+      case IrOpcode::kTerminate: {
+        // Put Terminate in the loop to which it refers.
+        Node* loop = NodeProperties::GetControlInput(node);
+        BasicBlock* block = BuildBlockForNode(loop);
+        FixNode(block, node);
+        break;
+      }
       case IrOpcode::kBranch:
         BuildBlocksForSuccessors(node, IrOpcode::kIfTrue, IrOpcode::kIfFalse);
         break;
@@ -107,11 +352,11 @@
         ConnectMerge(node);
         break;
       case IrOpcode::kBranch:
-        scheduler_->schedule_root_nodes_.push_back(node);
+        scheduler_->UpdatePlacement(node, Scheduler::kFixed);
         ConnectBranch(node);
         break;
       case IrOpcode::kReturn:
-        scheduler_->schedule_root_nodes_.push_back(node);
+        scheduler_->UpdatePlacement(node, Scheduler::kFixed);
         ConnectReturn(node);
         break;
       default:
@@ -119,13 +364,15 @@
     }
   }
 
-  void BuildBlockForNode(Node* node) {
-    if (schedule_->block(node) == NULL) {
-      BasicBlock* block = schedule_->NewBasicBlock();
-      Trace("Create block B%d for #%d:%s\n", block->id(), node->id(),
+  BasicBlock* BuildBlockForNode(Node* node) {
+    BasicBlock* block = schedule_->block(node);
+    if (block == NULL) {
+      block = schedule_->NewBasicBlock();
+      Trace("Create block B%d for #%d:%s\n", block->id().ToInt(), node->id(),
             node->op()->mnemonic());
       FixNode(block, node);
     }
+    return block;
   }
 
   void BuildBlocksForSuccessors(Node* node, IrOpcode::Value a,
@@ -144,14 +391,14 @@
                                    IrOpcode::Value false_opcode) {
     buffer[0] = NULL;
     buffer[1] = NULL;
-    for (UseIter i = node->uses().begin(); i != node->uses().end(); ++i) {
-      if ((*i)->opcode() == true_opcode) {
+    for (Node* use : node->uses()) {
+      if (use->opcode() == true_opcode) {
         DCHECK_EQ(NULL, buffer[0]);
-        buffer[0] = *i;
+        buffer[0] = use;
       }
-      if ((*i)->opcode() == false_opcode) {
+      if (use->opcode() == false_opcode) {
         DCHECK_EQ(NULL, buffer[1]);
-        buffer[1] = *i;
+        buffer[1] = use;
       }
     }
     DCHECK_NE(NULL, buffer[0]);
@@ -168,33 +415,51 @@
   }
 
   void ConnectBranch(Node* branch) {
-    Node* branch_block_node = NodeProperties::GetControlInput(branch);
-    BasicBlock* branch_block = schedule_->block(branch_block_node);
-    DCHECK(branch_block != NULL);
-
     BasicBlock* successor_blocks[2];
     CollectSuccessorBlocks(branch, successor_blocks, IrOpcode::kIfTrue,
                            IrOpcode::kIfFalse);
 
-    TraceConnect(branch, branch_block, successor_blocks[0]);
-    TraceConnect(branch, branch_block, successor_blocks[1]);
+    // Consider branch hints.
+    switch (BranchHintOf(branch->op())) {
+      case BranchHint::kNone:
+        break;
+      case BranchHint::kTrue:
+        successor_blocks[1]->set_deferred(true);
+        break;
+      case BranchHint::kFalse:
+        successor_blocks[0]->set_deferred(true);
+        break;
+    }
 
-    schedule_->AddBranch(branch_block, branch, successor_blocks[0],
-                         successor_blocks[1]);
+    if (branch == component_entry_) {
+      TraceConnect(branch, component_start_, successor_blocks[0]);
+      TraceConnect(branch, component_start_, successor_blocks[1]);
+      schedule_->InsertBranch(component_start_, component_end_, branch,
+                              successor_blocks[0], successor_blocks[1]);
+    } else {
+      Node* branch_block_node = NodeProperties::GetControlInput(branch);
+      BasicBlock* branch_block = schedule_->block(branch_block_node);
+      DCHECK(branch_block != NULL);
+
+      TraceConnect(branch, branch_block, successor_blocks[0]);
+      TraceConnect(branch, branch_block, successor_blocks[1]);
+      schedule_->AddBranch(branch_block, branch, successor_blocks[0],
+                           successor_blocks[1]);
+    }
   }
 
   void ConnectMerge(Node* merge) {
+    // Don't connect the special merge at the end to its predecessors.
+    if (IsFinalMerge(merge)) return;
+
     BasicBlock* block = schedule_->block(merge);
     DCHECK(block != NULL);
     // For all of the merge's control inputs, add a goto at the end to the
     // merge's basic block.
-    for (InputIter j = merge->inputs().begin(); j != merge->inputs().end();
-         ++j) {
-      BasicBlock* predecessor_block = schedule_->block(*j);
-      if ((*j)->opcode() != IrOpcode::kReturn) {
-        TraceConnect(merge, predecessor_block, block);
-        schedule_->AddGoto(predecessor_block, block);
-      }
+    for (Node* const input : merge->inputs()) {
+      BasicBlock* predecessor_block = schedule_->block(input);
+      TraceConnect(merge, predecessor_block, block);
+      schedule_->AddGoto(predecessor_block, block);
     }
   }
 
@@ -209,713 +474,59 @@
     DCHECK_NE(NULL, block);
     if (succ == NULL) {
       Trace("Connect #%d:%s, B%d -> end\n", node->id(), node->op()->mnemonic(),
-            block->id());
+            block->id().ToInt());
     } else {
       Trace("Connect #%d:%s, B%d -> B%d\n", node->id(), node->op()->mnemonic(),
-            block->id(), succ->id());
+            block->id().ToInt(), succ->id().ToInt());
     }
   }
+
+  bool IsFinalMerge(Node* node) {
+    return (node->opcode() == IrOpcode::kMerge &&
+            node == scheduler_->graph_->end()->InputAt(0));
+  }
+
+  bool IsSingleEntrySingleExitRegion(Node* entry, Node* exit) const {
+    size_t entry_class = scheduler_->equivalence_->ClassOf(entry);
+    size_t exit_class = scheduler_->equivalence_->ClassOf(exit);
+    return entry != exit && entry_class == exit_class;
+  }
+
+  void ResetDataStructures() {
+    control_.clear();
+    DCHECK(queue_.empty());
+    DCHECK(control_.empty());
+  }
+
+  Scheduler* scheduler_;
+  Schedule* schedule_;
+  NodeMarker<bool> queued_;      // Mark indicating whether node is queued.
+  ZoneQueue<Node*> queue_;       // Queue used for breadth-first traversal.
+  NodeVector control_;           // List of encountered control nodes.
+  Node* component_entry_;        // Component single-entry node.
+  BasicBlock* component_start_;  // Component single-entry block.
+  BasicBlock* component_end_;    // Component single-exit block.
 };
 
 
-Scheduler::SchedulerData Scheduler::DefaultSchedulerData() {
-  SchedulerData def = {0, 0, false, false, kUnknown};
-  return def;
-}
-
-
-Scheduler::Scheduler(Zone* zone, Graph* graph, Schedule* schedule)
-    : zone_(zone),
-      graph_(graph),
-      schedule_(schedule),
-      scheduled_nodes_(zone),
-      schedule_root_nodes_(zone),
-      node_data_(graph_->NodeCount(), DefaultSchedulerData(), zone),
-      has_floating_control_(false) {}
-
-
-Schedule* Scheduler::ComputeSchedule(Graph* graph) {
-  Schedule* schedule;
-  bool had_floating_control = false;
-  do {
-    Zone tmp_zone(graph->zone()->isolate());
-    schedule = new (graph->zone()) Schedule(graph->zone());
-    Scheduler scheduler(&tmp_zone, graph, schedule);
-
-    scheduler.BuildCFG();
-
-    Scheduler::ComputeSpecialRPO(schedule);
-    scheduler.GenerateImmediateDominatorTree();
-
-    scheduler.PrepareUses();
-    scheduler.ScheduleEarly();
-    scheduler.ScheduleLate();
-
-    had_floating_control = scheduler.ConnectFloatingControl();
-  } while (had_floating_control);
-
-  return schedule;
-}
-
-
-Scheduler::Placement Scheduler::GetPlacement(Node* node) {
-  SchedulerData* data = GetData(node);
-  if (data->placement_ == kUnknown) {  // Compute placement, once, on demand.
-    switch (node->opcode()) {
-      case IrOpcode::kParameter:
-        // Parameters are always fixed to the start node.
-        data->placement_ = kFixed;
-        break;
-      case IrOpcode::kPhi:
-      case IrOpcode::kEffectPhi: {
-        // Phis and effect phis are fixed if their control inputs are.
-        data->placement_ = GetPlacement(NodeProperties::GetControlInput(node));
-        break;
-      }
-#define DEFINE_FLOATING_CONTROL_CASE(V) case IrOpcode::k##V:
-        CONTROL_OP_LIST(DEFINE_FLOATING_CONTROL_CASE)
-#undef DEFINE_FLOATING_CONTROL_CASE
-        {
-          // Control nodes that were not control-reachable from end may float.
-          data->placement_ = kSchedulable;
-          if (!data->is_connected_control_) {
-            data->is_floating_control_ = true;
-            has_floating_control_ = true;
-            Trace("Floating control found: #%d:%s\n", node->id(),
-                  node->op()->mnemonic());
-          }
-          break;
-        }
-      default:
-        data->placement_ = kSchedulable;
-        break;
-    }
-  }
-  return data->placement_;
-}
-
-
 void Scheduler::BuildCFG() {
-  Trace("---------------- CREATING CFG ------------------\n");
-  CFGBuilder cfg_builder(zone_, this);
-  cfg_builder.Run();
+  Trace("--- CREATING CFG -------------------------------------------\n");
+
+  // Instantiate a new control equivalence algorithm for the graph.
+  equivalence_ = new (zone_) ControlEquivalence(zone_, graph_);
+
+  // Build a control-flow graph for the main control-connected component that
+  // is being spanned by the graph's start and end nodes.
+  control_flow_builder_ = new (zone_) CFGBuilder(zone_, this);
+  control_flow_builder_->Run();
+
   // Initialize per-block data.
   scheduled_nodes_.resize(schedule_->BasicBlockCount(), NodeVector(zone_));
 }
 
 
-BasicBlock* Scheduler::GetCommonDominator(BasicBlock* b1, BasicBlock* b2) {
-  while (b1 != b2) {
-    int b1_rpo = GetRPONumber(b1);
-    int b2_rpo = GetRPONumber(b2);
-    DCHECK(b1_rpo != b2_rpo);
-    if (b1_rpo < b2_rpo) {
-      b2 = b2->dominator_;
-    } else {
-      b1 = b1->dominator_;
-    }
-  }
-  return b1;
-}
-
-
-void Scheduler::GenerateImmediateDominatorTree() {
-  // Build the dominator graph.  TODO(danno): consider using Lengauer & Tarjan's
-  // if this becomes really slow.
-  Trace("------------ IMMEDIATE BLOCK DOMINATORS -----------\n");
-  for (size_t i = 0; i < schedule_->rpo_order_.size(); i++) {
-    BasicBlock* current_rpo = schedule_->rpo_order_[i];
-    if (current_rpo != schedule_->start()) {
-      BasicBlock::Predecessors::iterator current_pred =
-          current_rpo->predecessors().begin();
-      BasicBlock::Predecessors::iterator end =
-          current_rpo->predecessors().end();
-      DCHECK(current_pred != end);
-      BasicBlock* dominator = *current_pred;
-      ++current_pred;
-      // For multiple predecessors, walk up the rpo ordering until a common
-      // dominator is found.
-      int current_rpo_pos = GetRPONumber(current_rpo);
-      while (current_pred != end) {
-        // Don't examine backwards edges
-        BasicBlock* pred = *current_pred;
-        if (GetRPONumber(pred) < current_rpo_pos) {
-          dominator = GetCommonDominator(dominator, *current_pred);
-        }
-        ++current_pred;
-      }
-      current_rpo->dominator_ = dominator;
-      Trace("Block %d's idom is %d\n", current_rpo->id(), dominator->id());
-    }
-  }
-}
-
-
-class ScheduleEarlyNodeVisitor : public NullNodeVisitor {
- public:
-  explicit ScheduleEarlyNodeVisitor(Scheduler* scheduler)
-      : has_changed_rpo_constraints_(true),
-        scheduler_(scheduler),
-        schedule_(scheduler->schedule_) {}
-
-  GenericGraphVisit::Control Pre(Node* node) {
-    int max_rpo = 0;
-    // Fixed nodes already know their schedule early position.
-    if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
-      BasicBlock* block = schedule_->block(node);
-      DCHECK(block != NULL);
-      max_rpo = block->rpo_number_;
-      if (scheduler_->GetData(node)->minimum_rpo_ != max_rpo) {
-        has_changed_rpo_constraints_ = true;
-      }
-      scheduler_->GetData(node)->minimum_rpo_ = max_rpo;
-      Trace("Preschedule #%d:%s minimum_rpo = %d\n", node->id(),
-            node->op()->mnemonic(), max_rpo);
-    }
-    return GenericGraphVisit::CONTINUE;
-  }
-
-  GenericGraphVisit::Control Post(Node* node) {
-    int max_rpo = 0;
-    // Otherwise, the minimum rpo for the node is the max of all of the inputs.
-    if (scheduler_->GetPlacement(node) != Scheduler::kFixed) {
-      for (InputIter i = node->inputs().begin(); i != node->inputs().end();
-           ++i) {
-        int control_rpo = scheduler_->GetData(*i)->minimum_rpo_;
-        if (control_rpo > max_rpo) {
-          max_rpo = control_rpo;
-        }
-      }
-      if (scheduler_->GetData(node)->minimum_rpo_ != max_rpo) {
-        has_changed_rpo_constraints_ = true;
-      }
-      scheduler_->GetData(node)->minimum_rpo_ = max_rpo;
-      Trace("Postschedule #%d:%s minimum_rpo = %d\n", node->id(),
-            node->op()->mnemonic(), max_rpo);
-    }
-    return GenericGraphVisit::CONTINUE;
-  }
-
-  // TODO(mstarzinger): Dirty hack to unblock others, schedule early should be
-  // rewritten to use a pre-order traversal from the start instead.
-  bool has_changed_rpo_constraints_;
-
- private:
-  Scheduler* scheduler_;
-  Schedule* schedule_;
-};
-
-
-void Scheduler::ScheduleEarly() {
-  Trace("------------------- SCHEDULE EARLY ----------------\n");
-
-  int fixpoint_count = 0;
-  ScheduleEarlyNodeVisitor visitor(this);
-  while (visitor.has_changed_rpo_constraints_) {
-    visitor.has_changed_rpo_constraints_ = false;
-    graph_->VisitNodeInputsFromEnd(&visitor);
-    fixpoint_count++;
-  }
-
-  Trace("It took %d iterations to determine fixpoint\n", fixpoint_count);
-}
-
-
-class PrepareUsesVisitor : public NullNodeVisitor {
- public:
-  explicit PrepareUsesVisitor(Scheduler* scheduler)
-      : scheduler_(scheduler), schedule_(scheduler->schedule_) {}
-
-  GenericGraphVisit::Control Pre(Node* node) {
-    if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
-      // Fixed nodes are always roots for schedule late.
-      scheduler_->schedule_root_nodes_.push_back(node);
-      if (!schedule_->IsScheduled(node)) {
-        // Make sure root nodes are scheduled in their respective blocks.
-        Trace("  Scheduling fixed position node #%d:%s\n", node->id(),
-              node->op()->mnemonic());
-        IrOpcode::Value opcode = node->opcode();
-        BasicBlock* block =
-            opcode == IrOpcode::kParameter
-                ? schedule_->start()
-                : schedule_->block(NodeProperties::GetControlInput(node));
-        DCHECK(block != NULL);
-        schedule_->AddNode(block, node);
-      }
-    }
-
-    return GenericGraphVisit::CONTINUE;
-  }
-
-  void PostEdge(Node* from, int index, Node* to) {
-    // If the edge is from an unscheduled node, then tally it in the use count
-    // for all of its inputs. The same criterion will be used in ScheduleLate
-    // for decrementing use counts.
-    if (!schedule_->IsScheduled(from)) {
-      DCHECK_NE(Scheduler::kFixed, scheduler_->GetPlacement(from));
-      ++(scheduler_->GetData(to)->unscheduled_count_);
-      Trace("  Use count of #%d:%s (used by #%d:%s)++ = %d\n", to->id(),
-            to->op()->mnemonic(), from->id(), from->op()->mnemonic(),
-            scheduler_->GetData(to)->unscheduled_count_);
-    }
-  }
-
- private:
-  Scheduler* scheduler_;
-  Schedule* schedule_;
-};
-
-
-void Scheduler::PrepareUses() {
-  Trace("------------------- PREPARE USES ------------------\n");
-  // Count the uses of every node, it will be used to ensure that all of a
-  // node's uses are scheduled before the node itself.
-  PrepareUsesVisitor prepare_uses(this);
-  graph_->VisitNodeInputsFromEnd(&prepare_uses);
-}
-
-
-class ScheduleLateNodeVisitor : public NullNodeVisitor {
- public:
-  explicit ScheduleLateNodeVisitor(Scheduler* scheduler)
-      : scheduler_(scheduler), schedule_(scheduler_->schedule_) {}
-
-  GenericGraphVisit::Control Pre(Node* node) {
-    // Don't schedule nodes that are already scheduled.
-    if (schedule_->IsScheduled(node)) {
-      return GenericGraphVisit::CONTINUE;
-    }
-    Scheduler::SchedulerData* data = scheduler_->GetData(node);
-    DCHECK_EQ(Scheduler::kSchedulable, data->placement_);
-
-    // If all the uses of a node have been scheduled, then the node itself can
-    // be scheduled.
-    bool eligible = data->unscheduled_count_ == 0;
-    Trace("Testing for schedule eligibility for #%d:%s = %s\n", node->id(),
-          node->op()->mnemonic(), eligible ? "true" : "false");
-    if (!eligible) return GenericGraphVisit::DEFER;
-
-    // Determine the dominating block for all of the uses of this node. It is
-    // the latest block that this node can be scheduled in.
-    BasicBlock* block = NULL;
-    for (Node::Uses::iterator i = node->uses().begin(); i != node->uses().end();
-         ++i) {
-      BasicBlock* use_block = GetBlockForUse(i.edge());
-      block = block == NULL ? use_block : use_block == NULL
-                                              ? block
-                                              : scheduler_->GetCommonDominator(
-                                                    block, use_block);
-    }
-    DCHECK(block != NULL);
-
-    int min_rpo = data->minimum_rpo_;
-    Trace(
-        "Schedule late conservative for #%d:%s is B%d at loop depth %d, "
-        "minimum_rpo = %d\n",
-        node->id(), node->op()->mnemonic(), block->id(), block->loop_depth_,
-        min_rpo);
-    // Hoist nodes out of loops if possible. Nodes can be hoisted iteratively
-    // into enclosing loop pre-headers until they would preceed their
-    // ScheduleEarly position.
-    BasicBlock* hoist_block = block;
-    while (hoist_block != NULL && hoist_block->rpo_number_ >= min_rpo) {
-      if (hoist_block->loop_depth_ < block->loop_depth_) {
-        block = hoist_block;
-        Trace("  hoisting #%d:%s to block %d\n", node->id(),
-              node->op()->mnemonic(), block->id());
-      }
-      // Try to hoist to the pre-header of the loop header.
-      hoist_block = hoist_block->loop_header();
-      if (hoist_block != NULL) {
-        BasicBlock* pre_header = hoist_block->dominator_;
-        DCHECK(pre_header == NULL ||
-               *hoist_block->predecessors().begin() == pre_header);
-        Trace(
-            "  hoist to pre-header B%d of loop header B%d, depth would be %d\n",
-            pre_header->id(), hoist_block->id(), pre_header->loop_depth_);
-        hoist_block = pre_header;
-      }
-    }
-
-    ScheduleNode(block, node);
-
-    return GenericGraphVisit::CONTINUE;
-  }
-
- private:
-  BasicBlock* GetBlockForUse(Node::Edge edge) {
-    Node* use = edge.from();
-    IrOpcode::Value opcode = use->opcode();
-    if (opcode == IrOpcode::kPhi || opcode == IrOpcode::kEffectPhi) {
-      // If the use is from a fixed (i.e. non-floating) phi, use the block
-      // of the corresponding control input to the merge.
-      int index = edge.index();
-      if (scheduler_->GetPlacement(use) == Scheduler::kFixed) {
-        Trace("  input@%d into a fixed phi #%d:%s\n", index, use->id(),
-              use->op()->mnemonic());
-        Node* merge = NodeProperties::GetControlInput(use, 0);
-        opcode = merge->opcode();
-        DCHECK(opcode == IrOpcode::kMerge || opcode == IrOpcode::kLoop);
-        use = NodeProperties::GetControlInput(merge, index);
-      }
-    }
-    BasicBlock* result = schedule_->block(use);
-    if (result == NULL) return NULL;
-    Trace("  must dominate use #%d:%s in B%d\n", use->id(),
-          use->op()->mnemonic(), result->id());
-    return result;
-  }
-
-  void ScheduleNode(BasicBlock* block, Node* node) {
-    schedule_->PlanNode(block, node);
-    scheduler_->scheduled_nodes_[block->id()].push_back(node);
-
-    // Reduce the use count of the node's inputs to potentially make them
-    // schedulable.
-    for (InputIter i = node->inputs().begin(); i != node->inputs().end(); ++i) {
-      Scheduler::SchedulerData* data = scheduler_->GetData(*i);
-      DCHECK(data->unscheduled_count_ > 0);
-      --data->unscheduled_count_;
-      if (FLAG_trace_turbo_scheduler) {
-        Trace("  Use count for #%d:%s (used by #%d:%s)-- = %d\n", (*i)->id(),
-              (*i)->op()->mnemonic(), i.edge().from()->id(),
-              i.edge().from()->op()->mnemonic(), data->unscheduled_count_);
-        if (data->unscheduled_count_ == 0) {
-          Trace("  newly eligible #%d:%s\n", (*i)->id(),
-                (*i)->op()->mnemonic());
-        }
-      }
-    }
-  }
-
-  Scheduler* scheduler_;
-  Schedule* schedule_;
-};
-
-
-void Scheduler::ScheduleLate() {
-  Trace("------------------- SCHEDULE LATE -----------------\n");
-  if (FLAG_trace_turbo_scheduler) {
-    Trace("roots: ");
-    for (NodeVectorIter i = schedule_root_nodes_.begin();
-         i != schedule_root_nodes_.end(); ++i) {
-      Trace("#%d:%s ", (*i)->id(), (*i)->op()->mnemonic());
-    }
-    Trace("\n");
-  }
-
-  // Schedule: Places nodes in dominator block of all their uses.
-  ScheduleLateNodeVisitor schedule_late_visitor(this);
-
-  {
-    Zone zone(zone_->isolate());
-    GenericGraphVisit::Visit<ScheduleLateNodeVisitor,
-                             NodeInputIterationTraits<Node> >(
-        graph_, &zone, schedule_root_nodes_.begin(), schedule_root_nodes_.end(),
-        &schedule_late_visitor);
-  }
-
-  // Add collected nodes for basic blocks to their blocks in the right order.
-  int block_num = 0;
-  for (NodeVectorVectorIter i = scheduled_nodes_.begin();
-       i != scheduled_nodes_.end(); ++i) {
-    for (NodeVectorRIter j = i->rbegin(); j != i->rend(); ++j) {
-      schedule_->AddNode(schedule_->all_blocks_.at(block_num), *j);
-    }
-    block_num++;
-  }
-}
-
-
-bool Scheduler::ConnectFloatingControl() {
-  if (!has_floating_control_) return false;
-
-  Trace("Connecting floating control...\n");
-
-  // Process blocks and instructions backwards to find and connect floating
-  // control nodes into the control graph according to the block they were
-  // scheduled into.
-  int max = static_cast<int>(schedule_->rpo_order()->size());
-  for (int i = max - 1; i >= 0; i--) {
-    BasicBlock* block = schedule_->rpo_order()->at(i);
-    // TODO(titzer): we place at most one floating control structure per
-    // basic block because scheduling currently can interleave phis from
-    // one subgraph with the merges from another subgraph.
-    bool one_placed = false;
-    for (int j = static_cast<int>(block->nodes_.size()) - 1; j >= 0; j--) {
-      Node* node = block->nodes_[j];
-      SchedulerData* data = GetData(node);
-      if (data->is_floating_control_ && !data->is_connected_control_ &&
-          !one_placed) {
-        Trace("  Floating control #%d:%s was scheduled in B%d\n", node->id(),
-              node->op()->mnemonic(), block->id());
-        ConnectFloatingControlSubgraph(block, node);
-        one_placed = true;
-      }
-    }
-  }
-
-  return true;
-}
-
-
-void Scheduler::ConnectFloatingControlSubgraph(BasicBlock* block, Node* end) {
-  Node* block_start = block->nodes_[0];
-  DCHECK(IrOpcode::IsControlOpcode(block_start->opcode()));
-  // Find the current "control successor" of the node that starts the block
-  // by searching the control uses for a control input edge from a connected
-  // control node.
-  Node* control_succ = NULL;
-  for (UseIter i = block_start->uses().begin(); i != block_start->uses().end();
-       ++i) {
-    Node::Edge edge = i.edge();
-    if (NodeProperties::IsControlEdge(edge) &&
-        GetData(edge.from())->is_connected_control_) {
-      DCHECK_EQ(NULL, control_succ);
-      control_succ = edge.from();
-      control_succ->ReplaceInput(edge.index(), end);
-    }
-  }
-  DCHECK_NE(NULL, control_succ);
-  Trace("  Inserting floating control end %d:%s between %d:%s -> %d:%s\n",
-        end->id(), end->op()->mnemonic(), control_succ->id(),
-        control_succ->op()->mnemonic(), block_start->id(),
-        block_start->op()->mnemonic());
-
-  // Find the "start" node of the control subgraph, which should be the
-  // unique node that is itself floating control but has a control input that
-  // is not floating.
-  Node* start = NULL;
-  ZoneQueue<Node*> queue(zone_);
-  queue.push(end);
-  GetData(end)->is_connected_control_ = true;
-  while (!queue.empty()) {
-    Node* node = queue.front();
-    queue.pop();
-    Trace("  Search #%d:%s for control subgraph start\n", node->id(),
-          node->op()->mnemonic());
-    int max = NodeProperties::PastControlIndex(node);
-    for (int i = NodeProperties::FirstControlIndex(node); i < max; i++) {
-      Node* input = node->InputAt(i);
-      SchedulerData* data = GetData(input);
-      if (data->is_floating_control_) {
-        // {input} is floating control.
-        if (!data->is_connected_control_) {
-          // First time seeing {input} during this traversal, queue it.
-          queue.push(input);
-          data->is_connected_control_ = true;
-        }
-      } else {
-        // Otherwise, {node} is the start node, because it is floating control
-        // but is connected to {input} that is not floating control.
-        DCHECK_EQ(NULL, start);  // There can be only one.
-        start = node;
-      }
-    }
-  }
-
-  DCHECK_NE(NULL, start);
-  start->ReplaceInput(NodeProperties::FirstControlIndex(start), block_start);
-
-  Trace("  Connecting floating control start %d:%s to %d:%s\n", start->id(),
-        start->op()->mnemonic(), block_start->id(),
-        block_start->op()->mnemonic());
-}
-
-
-// Numbering for BasicBlockData.rpo_number_ for this block traversal:
-static const int kBlockOnStack = -2;
-static const int kBlockVisited1 = -3;
-static const int kBlockVisited2 = -4;
-static const int kBlockUnvisited1 = -1;
-static const int kBlockUnvisited2 = kBlockVisited1;
-
-struct SpecialRPOStackFrame {
-  BasicBlock* block;
-  int index;
-};
-
-struct BlockList {
-  BasicBlock* block;
-  BlockList* next;
-
-  BlockList* Add(Zone* zone, BasicBlock* b) {
-    BlockList* list = static_cast<BlockList*>(zone->New(sizeof(BlockList)));
-    list->block = b;
-    list->next = this;
-    return list;
-  }
-
-  void Serialize(BasicBlockVector* final_order) {
-    for (BlockList* l = this; l != NULL; l = l->next) {
-      l->block->rpo_number_ = static_cast<int>(final_order->size());
-      final_order->push_back(l->block);
-    }
-  }
-};
-
-struct LoopInfo {
-  BasicBlock* header;
-  ZoneList<BasicBlock*>* outgoing;
-  BitVector* members;
-  LoopInfo* prev;
-  BlockList* end;
-  BlockList* start;
-
-  void AddOutgoing(Zone* zone, BasicBlock* block) {
-    if (outgoing == NULL) outgoing = new (zone) ZoneList<BasicBlock*>(2, zone);
-    outgoing->Add(block, zone);
-  }
-};
-
-
-static int Push(SpecialRPOStackFrame* stack, int depth, BasicBlock* child,
-                int unvisited) {
-  if (child->rpo_number_ == unvisited) {
-    stack[depth].block = child;
-    stack[depth].index = 0;
-    child->rpo_number_ = kBlockOnStack;
-    return depth + 1;
-  }
-  return depth;
-}
-
-
-// Computes loop membership from the backedges of the control flow graph.
-static LoopInfo* ComputeLoopInfo(
-    Zone* zone, SpecialRPOStackFrame* queue, int num_loops, int num_blocks,
-    ZoneList<std::pair<BasicBlock*, int> >* backedges) {
-  LoopInfo* loops = zone->NewArray<LoopInfo>(num_loops);
-  memset(loops, 0, num_loops * sizeof(LoopInfo));
-
-  // Compute loop membership starting from backedges.
-  // O(max(loop_depth) * max(|loop|)
-  for (int i = 0; i < backedges->length(); i++) {
-    BasicBlock* member = backedges->at(i).first;
-    BasicBlock* header = member->SuccessorAt(backedges->at(i).second);
-    int loop_num = header->loop_end_;
-    if (loops[loop_num].header == NULL) {
-      loops[loop_num].header = header;
-      loops[loop_num].members = new (zone) BitVector(num_blocks, zone);
-    }
-
-    int queue_length = 0;
-    if (member != header) {
-      // As long as the header doesn't have a backedge to itself,
-      // Push the member onto the queue and process its predecessors.
-      if (!loops[loop_num].members->Contains(member->id())) {
-        loops[loop_num].members->Add(member->id());
-      }
-      queue[queue_length++].block = member;
-    }
-
-    // Propagate loop membership backwards. All predecessors of M up to the
-    // loop header H are members of the loop too. O(|blocks between M and H|).
-    while (queue_length > 0) {
-      BasicBlock* block = queue[--queue_length].block;
-      for (int i = 0; i < block->PredecessorCount(); i++) {
-        BasicBlock* pred = block->PredecessorAt(i);
-        if (pred != header) {
-          if (!loops[loop_num].members->Contains(pred->id())) {
-            loops[loop_num].members->Add(pred->id());
-            queue[queue_length++].block = pred;
-          }
-        }
-      }
-    }
-  }
-  return loops;
-}
-
-
-#if DEBUG
-static void PrintRPO(int num_loops, LoopInfo* loops, BasicBlockVector* order) {
-  PrintF("-- RPO with %d loops ", num_loops);
-  if (num_loops > 0) {
-    PrintF("(");
-    for (int i = 0; i < num_loops; i++) {
-      if (i > 0) PrintF(" ");
-      PrintF("B%d", loops[i].header->id());
-    }
-    PrintF(") ");
-  }
-  PrintF("-- \n");
-
-  for (int i = 0; i < static_cast<int>(order->size()); i++) {
-    BasicBlock* block = (*order)[i];
-    int bid = block->id();
-    PrintF("%5d:", i);
-    for (int i = 0; i < num_loops; i++) {
-      bool membership = loops[i].members->Contains(bid);
-      bool range = loops[i].header->LoopContains(block);
-      PrintF(membership ? " |" : "  ");
-      PrintF(range ? "x" : " ");
-    }
-    PrintF("  B%d: ", bid);
-    if (block->loop_end_ >= 0) {
-      PrintF(" range: [%d, %d)", block->rpo_number_, block->loop_end_);
-    }
-    PrintF("\n");
-  }
-}
-
-
-static void VerifySpecialRPO(int num_loops, LoopInfo* loops,
-                             BasicBlockVector* order) {
-  DCHECK(order->size() > 0);
-  DCHECK((*order)[0]->id() == 0);  // entry should be first.
-
-  for (int i = 0; i < num_loops; i++) {
-    LoopInfo* loop = &loops[i];
-    BasicBlock* header = loop->header;
-
-    DCHECK(header != NULL);
-    DCHECK(header->rpo_number_ >= 0);
-    DCHECK(header->rpo_number_ < static_cast<int>(order->size()));
-    DCHECK(header->loop_end_ >= 0);
-    DCHECK(header->loop_end_ <= static_cast<int>(order->size()));
-    DCHECK(header->loop_end_ > header->rpo_number_);
-
-    // Verify the start ... end list relationship.
-    int links = 0;
-    BlockList* l = loop->start;
-    DCHECK(l != NULL && l->block == header);
-    bool end_found;
-    while (true) {
-      if (l == NULL || l == loop->end) {
-        end_found = (loop->end == l);
-        break;
-      }
-      // The list should be in same order as the final result.
-      DCHECK(l->block->rpo_number_ == links + loop->header->rpo_number_);
-      links++;
-      l = l->next;
-      DCHECK(links < static_cast<int>(2 * order->size()));  // cycle?
-    }
-    DCHECK(links > 0);
-    DCHECK(links == (header->loop_end_ - header->rpo_number_));
-    DCHECK(end_found);
-
-    // Check the contiguousness of loops.
-    int count = 0;
-    for (int j = 0; j < static_cast<int>(order->size()); j++) {
-      BasicBlock* block = order->at(j);
-      DCHECK(block->rpo_number_ == j);
-      if (j < header->rpo_number_ || j >= header->loop_end_) {
-        DCHECK(!loop->members->Contains(block->id()));
-      } else {
-        if (block == header) {
-          DCHECK(!loop->members->Contains(block->id()));
-        } else {
-          DCHECK(loop->members->Contains(block->id()));
-        }
-        count++;
-      }
-    }
-    DCHECK(links == count);
-  }
-}
-#endif  // DEBUG
+// -----------------------------------------------------------------------------
+// Phase 2: Compute special RPO and dominator tree.
 
 
 // Compute the special reverse-post-order block ordering, which is essentially
@@ -928,198 +539,945 @@
 //    headed at A.
 // 2. All loops are contiguous in the order (i.e. no intervening blocks that
 //    do not belong to the loop.)
-// Note a simple RPO traversal satisfies (1) but not (3).
-BasicBlockVector* Scheduler::ComputeSpecialRPO(Schedule* schedule) {
-  Zone tmp_zone(schedule->zone()->isolate());
-  Zone* zone = &tmp_zone;
-  Trace("------------- COMPUTING SPECIAL RPO ---------------\n");
-  // RPO should not have been computed for this schedule yet.
-  CHECK_EQ(kBlockUnvisited1, schedule->start()->rpo_number_);
-  CHECK_EQ(0, static_cast<int>(schedule->rpo_order_.size()));
+// Note a simple RPO traversal satisfies (1) but not (2).
+class SpecialRPONumberer : public ZoneObject {
+ public:
+  SpecialRPONumberer(Zone* zone, Schedule* schedule)
+      : zone_(zone),
+        schedule_(schedule),
+        order_(NULL),
+        beyond_end_(NULL),
+        loops_(zone),
+        backedges_(zone),
+        stack_(zone),
+        previous_block_count_(0) {}
 
-  // Perform an iterative RPO traversal using an explicit stack,
-  // recording backedges that form cycles. O(|B|).
-  ZoneList<std::pair<BasicBlock*, int> > backedges(1, zone);
-  SpecialRPOStackFrame* stack =
-      zone->NewArray<SpecialRPOStackFrame>(schedule->BasicBlockCount());
-  BasicBlock* entry = schedule->start();
-  BlockList* order = NULL;
-  int stack_depth = Push(stack, 0, entry, kBlockUnvisited1);
-  int num_loops = 0;
-
-  while (stack_depth > 0) {
-    int current = stack_depth - 1;
-    SpecialRPOStackFrame* frame = stack + current;
-
-    if (frame->index < frame->block->SuccessorCount()) {
-      // Process the next successor.
-      BasicBlock* succ = frame->block->SuccessorAt(frame->index++);
-      if (succ->rpo_number_ == kBlockVisited1) continue;
-      if (succ->rpo_number_ == kBlockOnStack) {
-        // The successor is on the stack, so this is a backedge (cycle).
-        backedges.Add(
-            std::pair<BasicBlock*, int>(frame->block, frame->index - 1), zone);
-        if (succ->loop_end_ < 0) {
-          // Assign a new loop number to the header if it doesn't have one.
-          succ->loop_end_ = num_loops++;
-        }
-      } else {
-        // Push the successor onto the stack.
-        DCHECK(succ->rpo_number_ == kBlockUnvisited1);
-        stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited1);
-      }
-    } else {
-      // Finished with all successors; pop the stack and add the block.
-      order = order->Add(zone, frame->block);
-      frame->block->rpo_number_ = kBlockVisited1;
-      stack_depth--;
-    }
+  // Computes the special reverse-post-order for the main control flow graph,
+  // that is for the graph spanned between the schedule's start and end blocks.
+  void ComputeSpecialRPO() {
+    DCHECK(schedule_->end()->SuccessorCount() == 0);
+    DCHECK_EQ(NULL, order_);  // Main order does not exist yet.
+    ComputeAndInsertSpecialRPO(schedule_->start(), schedule_->end());
   }
 
-  // If no loops were encountered, then the order we computed was correct.
-  LoopInfo* loops = NULL;
-  if (num_loops != 0) {
-    // Otherwise, compute the loop information from the backedges in order
-    // to perform a traversal that groups loop bodies together.
-    loops = ComputeLoopInfo(zone, stack, num_loops, schedule->BasicBlockCount(),
-                            &backedges);
+  // Computes the special reverse-post-order for a partial control flow graph,
+  // that is for the graph spanned between the given {entry} and {end} blocks,
+  // then updates the existing ordering with this new information.
+  void UpdateSpecialRPO(BasicBlock* entry, BasicBlock* end) {
+    DCHECK_NE(NULL, order_);  // Main order to be updated is present.
+    ComputeAndInsertSpecialRPO(entry, end);
+  }
 
-    // Initialize the "loop stack". Note the entry could be a loop header.
-    LoopInfo* loop = entry->IsLoopHeader() ? &loops[entry->loop_end_] : NULL;
-    order = NULL;
+  // Serialize the previously computed order as a special reverse-post-order
+  // numbering for basic blocks into the final schedule.
+  void SerializeRPOIntoSchedule() {
+    int32_t number = 0;
+    for (BasicBlock* b = order_; b != NULL; b = b->rpo_next()) {
+      b->set_rpo_number(number++);
+      schedule_->rpo_order()->push_back(b);
+    }
+    BeyondEndSentinel()->set_rpo_number(number);
+  }
 
-    // Perform an iterative post-order traversal, visiting loop bodies before
-    // edges that lead out of loops. Visits each block once, but linking loop
-    // sections together is linear in the loop size, so overall is
-    // O(|B| + max(loop_depth) * max(|loop|))
-    stack_depth = Push(stack, 0, entry, kBlockUnvisited2);
-    while (stack_depth > 0) {
-      SpecialRPOStackFrame* frame = stack + (stack_depth - 1);
-      BasicBlock* block = frame->block;
-      BasicBlock* succ = NULL;
+  // Print and verify the special reverse-post-order.
+  void PrintAndVerifySpecialRPO() {
+#if DEBUG
+    if (FLAG_trace_turbo_scheduler) PrintRPO();
+    VerifySpecialRPO();
+#endif
+  }
 
-      if (frame->index < block->SuccessorCount()) {
-        // Process the next normal successor.
-        succ = block->SuccessorAt(frame->index++);
-      } else if (block->IsLoopHeader()) {
-        // Process additional outgoing edges from the loop header.
-        if (block->rpo_number_ == kBlockOnStack) {
-          // Finish the loop body the first time the header is left on the
-          // stack.
-          DCHECK(loop != NULL && loop->header == block);
-          loop->start = order->Add(zone, block);
-          order = loop->end;
-          block->rpo_number_ = kBlockVisited2;
-          // Pop the loop stack and continue visiting outgoing edges within the
-          // the context of the outer loop, if any.
-          loop = loop->prev;
-          // We leave the loop header on the stack; the rest of this iteration
-          // and later iterations will go through its outgoing edges list.
-        }
+ private:
+  typedef std::pair<BasicBlock*, size_t> Backedge;
 
-        // Use the next outgoing edge if there are any.
-        int outgoing_index = frame->index - block->SuccessorCount();
-        LoopInfo* info = &loops[block->loop_end_];
-        DCHECK(loop != info);
-        if (info->outgoing != NULL &&
-            outgoing_index < info->outgoing->length()) {
-          succ = info->outgoing->at(outgoing_index);
-          frame->index++;
-        }
+  // Numbering for BasicBlock::rpo_number for this block traversal:
+  static const int kBlockOnStack = -2;
+  static const int kBlockVisited1 = -3;
+  static const int kBlockVisited2 = -4;
+  static const int kBlockUnvisited1 = -1;
+  static const int kBlockUnvisited2 = kBlockVisited1;
+
+  struct SpecialRPOStackFrame {
+    BasicBlock* block;
+    size_t index;
+  };
+
+  struct LoopInfo {
+    BasicBlock* header;
+    ZoneList<BasicBlock*>* outgoing;
+    BitVector* members;
+    LoopInfo* prev;
+    BasicBlock* end;
+    BasicBlock* start;
+
+    void AddOutgoing(Zone* zone, BasicBlock* block) {
+      if (outgoing == NULL) {
+        outgoing = new (zone) ZoneList<BasicBlock*>(2, zone);
       }
+      outgoing->Add(block, zone);
+    }
+  };
 
-      if (succ != NULL) {
+  int Push(ZoneVector<SpecialRPOStackFrame>& stack, int depth,
+           BasicBlock* child, int unvisited) {
+    if (child->rpo_number() == unvisited) {
+      stack[depth].block = child;
+      stack[depth].index = 0;
+      child->set_rpo_number(kBlockOnStack);
+      return depth + 1;
+    }
+    return depth;
+  }
+
+  BasicBlock* PushFront(BasicBlock* head, BasicBlock* block) {
+    block->set_rpo_next(head);
+    return block;
+  }
+
+  static int GetLoopNumber(BasicBlock* block) { return block->loop_number(); }
+  static void SetLoopNumber(BasicBlock* block, int loop_number) {
+    return block->set_loop_number(loop_number);
+  }
+  static bool HasLoopNumber(BasicBlock* block) {
+    return block->loop_number() >= 0;
+  }
+
+  // TODO(mstarzinger): We only need this special sentinel because some tests
+  // use the schedule's end block in actual control flow (e.g. with end having
+  // successors). Once this has been cleaned up we can use the end block here.
+  BasicBlock* BeyondEndSentinel() {
+    if (beyond_end_ == NULL) {
+      BasicBlock::Id id = BasicBlock::Id::FromInt(-1);
+      beyond_end_ = new (schedule_->zone()) BasicBlock(schedule_->zone(), id);
+    }
+    return beyond_end_;
+  }
+
+  // Compute special RPO for the control flow graph between {entry} and {end},
+  // mutating any existing order so that the result is still valid.
+  void ComputeAndInsertSpecialRPO(BasicBlock* entry, BasicBlock* end) {
+    // RPO should not have been serialized for this schedule yet.
+    CHECK_EQ(kBlockUnvisited1, schedule_->start()->loop_number());
+    CHECK_EQ(kBlockUnvisited1, schedule_->start()->rpo_number());
+    CHECK_EQ(0, static_cast<int>(schedule_->rpo_order()->size()));
+
+    // Find correct insertion point within existing order.
+    BasicBlock* insertion_point = entry->rpo_next();
+    BasicBlock* order = insertion_point;
+
+    // Perform an iterative RPO traversal using an explicit stack,
+    // recording backedges that form cycles. O(|B|).
+    DCHECK_LT(previous_block_count_, schedule_->BasicBlockCount());
+    stack_.resize(schedule_->BasicBlockCount() - previous_block_count_);
+    previous_block_count_ = schedule_->BasicBlockCount();
+    int stack_depth = Push(stack_, 0, entry, kBlockUnvisited1);
+    int num_loops = static_cast<int>(loops_.size());
+
+    while (stack_depth > 0) {
+      int current = stack_depth - 1;
+      SpecialRPOStackFrame* frame = &stack_[current];
+
+      if (frame->block != end &&
+          frame->index < frame->block->SuccessorCount()) {
         // Process the next successor.
-        if (succ->rpo_number_ == kBlockOnStack) continue;
-        if (succ->rpo_number_ == kBlockVisited2) continue;
-        DCHECK(succ->rpo_number_ == kBlockUnvisited2);
-        if (loop != NULL && !loop->members->Contains(succ->id())) {
-          // The successor is not in the current loop or any nested loop.
-          // Add it to the outgoing edges of this loop and visit it later.
-          loop->AddOutgoing(zone, succ);
+        BasicBlock* succ = frame->block->SuccessorAt(frame->index++);
+        if (succ->rpo_number() == kBlockVisited1) continue;
+        if (succ->rpo_number() == kBlockOnStack) {
+          // The successor is on the stack, so this is a backedge (cycle).
+          backedges_.push_back(Backedge(frame->block, frame->index - 1));
+          if (!HasLoopNumber(succ)) {
+            // Assign a new loop number to the header if it doesn't have one.
+            SetLoopNumber(succ, num_loops++);
+          }
         } else {
           // Push the successor onto the stack.
-          stack_depth = Push(stack, stack_depth, succ, kBlockUnvisited2);
-          if (succ->IsLoopHeader()) {
-            // Push the inner loop onto the loop stack.
-            DCHECK(succ->loop_end_ >= 0 && succ->loop_end_ < num_loops);
-            LoopInfo* next = &loops[succ->loop_end_];
-            next->end = order;
-            next->prev = loop;
-            loop = next;
-          }
+          DCHECK(succ->rpo_number() == kBlockUnvisited1);
+          stack_depth = Push(stack_, stack_depth, succ, kBlockUnvisited1);
         }
       } else {
-        // Finished with all successors of the current block.
-        if (block->IsLoopHeader()) {
-          // If we are going to pop a loop header, then add its entire body.
-          LoopInfo* info = &loops[block->loop_end_];
-          for (BlockList* l = info->start; true; l = l->next) {
-            if (l->next == info->end) {
-              l->next = order;
-              info->end = order;
-              break;
-            }
-          }
-          order = info->start;
-        } else {
-          // Pop a single node off the stack and add it to the order.
-          order = order->Add(zone, block);
-          block->rpo_number_ = kBlockVisited2;
-        }
+        // Finished with all successors; pop the stack and add the block.
+        order = PushFront(order, frame->block);
+        frame->block->set_rpo_number(kBlockVisited1);
         stack_depth--;
       }
     }
-  }
 
-  // Construct the final order from the list.
-  BasicBlockVector* final_order = &schedule->rpo_order_;
-  order->Serialize(final_order);
+    // If no loops were encountered, then the order we computed was correct.
+    if (num_loops > static_cast<int>(loops_.size())) {
+      // Otherwise, compute the loop information from the backedges in order
+      // to perform a traversal that groups loop bodies together.
+      ComputeLoopInfo(stack_, num_loops, &backedges_);
 
-  // Compute the correct loop header for every block and set the correct loop
-  // ends.
-  LoopInfo* current_loop = NULL;
-  BasicBlock* current_header = NULL;
-  int loop_depth = 0;
-  for (BasicBlockVectorIter i = final_order->begin(); i != final_order->end();
-       ++i) {
-    BasicBlock* current = *i;
-    current->loop_header_ = current_header;
-    if (current->IsLoopHeader()) {
-      loop_depth++;
-      current_loop = &loops[current->loop_end_];
-      BlockList* end = current_loop->end;
-      current->loop_end_ = end == NULL ? static_cast<int>(final_order->size())
-                                       : end->block->rpo_number_;
-      current_header = current_loop->header;
-      Trace("B%d is a loop header, increment loop depth to %d\n", current->id(),
-            loop_depth);
-    } else {
-      while (current_header != NULL &&
-             current->rpo_number_ >= current_header->loop_end_) {
+      // Initialize the "loop stack". Note the entry could be a loop header.
+      LoopInfo* loop =
+          HasLoopNumber(entry) ? &loops_[GetLoopNumber(entry)] : NULL;
+      order = insertion_point;
+
+      // Perform an iterative post-order traversal, visiting loop bodies before
+      // edges that lead out of loops. Visits each block once, but linking loop
+      // sections together is linear in the loop size, so overall is
+      // O(|B| + max(loop_depth) * max(|loop|))
+      stack_depth = Push(stack_, 0, entry, kBlockUnvisited2);
+      while (stack_depth > 0) {
+        SpecialRPOStackFrame* frame = &stack_[stack_depth - 1];
+        BasicBlock* block = frame->block;
+        BasicBlock* succ = NULL;
+
+        if (block != end && frame->index < block->SuccessorCount()) {
+          // Process the next normal successor.
+          succ = block->SuccessorAt(frame->index++);
+        } else if (HasLoopNumber(block)) {
+          // Process additional outgoing edges from the loop header.
+          if (block->rpo_number() == kBlockOnStack) {
+            // Finish the loop body the first time the header is left on the
+            // stack.
+            DCHECK(loop != NULL && loop->header == block);
+            loop->start = PushFront(order, block);
+            order = loop->end;
+            block->set_rpo_number(kBlockVisited2);
+            // Pop the loop stack and continue visiting outgoing edges within
+            // the context of the outer loop, if any.
+            loop = loop->prev;
+            // We leave the loop header on the stack; the rest of this iteration
+            // and later iterations will go through its outgoing edges list.
+          }
+
+          // Use the next outgoing edge if there are any.
+          int outgoing_index =
+              static_cast<int>(frame->index - block->SuccessorCount());
+          LoopInfo* info = &loops_[GetLoopNumber(block)];
+          DCHECK(loop != info);
+          if (block != entry && info->outgoing != NULL &&
+              outgoing_index < info->outgoing->length()) {
+            succ = info->outgoing->at(outgoing_index);
+            frame->index++;
+          }
+        }
+
+        if (succ != NULL) {
+          // Process the next successor.
+          if (succ->rpo_number() == kBlockOnStack) continue;
+          if (succ->rpo_number() == kBlockVisited2) continue;
+          DCHECK(succ->rpo_number() == kBlockUnvisited2);
+          if (loop != NULL && !loop->members->Contains(succ->id().ToInt())) {
+            // The successor is not in the current loop or any nested loop.
+            // Add it to the outgoing edges of this loop and visit it later.
+            loop->AddOutgoing(zone_, succ);
+          } else {
+            // Push the successor onto the stack.
+            stack_depth = Push(stack_, stack_depth, succ, kBlockUnvisited2);
+            if (HasLoopNumber(succ)) {
+              // Push the inner loop onto the loop stack.
+              DCHECK(GetLoopNumber(succ) < num_loops);
+              LoopInfo* next = &loops_[GetLoopNumber(succ)];
+              next->end = order;
+              next->prev = loop;
+              loop = next;
+            }
+          }
+        } else {
+          // Finished with all successors of the current block.
+          if (HasLoopNumber(block)) {
+            // If we are going to pop a loop header, then add its entire body.
+            LoopInfo* info = &loops_[GetLoopNumber(block)];
+            for (BasicBlock* b = info->start; true; b = b->rpo_next()) {
+              if (b->rpo_next() == info->end) {
+                b->set_rpo_next(order);
+                info->end = order;
+                break;
+              }
+            }
+            order = info->start;
+          } else {
+            // Pop a single node off the stack and add it to the order.
+            order = PushFront(order, block);
+            block->set_rpo_number(kBlockVisited2);
+          }
+          stack_depth--;
+        }
+      }
+    }
+
+    // Publish new order the first time.
+    if (order_ == NULL) order_ = order;
+
+    // Compute the correct loop headers and set the correct loop ends.
+    LoopInfo* current_loop = NULL;
+    BasicBlock* current_header = entry->loop_header();
+    int32_t loop_depth = entry->loop_depth();
+    if (entry->IsLoopHeader()) --loop_depth;  // Entry might be a loop header.
+    for (BasicBlock* b = order; b != insertion_point; b = b->rpo_next()) {
+      BasicBlock* current = b;
+
+      // Reset BasicBlock::rpo_number again.
+      current->set_rpo_number(kBlockUnvisited1);
+
+      // Finish the previous loop(s) if we just exited them.
+      while (current_header != NULL && current == current_header->loop_end()) {
         DCHECK(current_header->IsLoopHeader());
         DCHECK(current_loop != NULL);
         current_loop = current_loop->prev;
         current_header = current_loop == NULL ? NULL : current_loop->header;
         --loop_depth;
       }
+      current->set_loop_header(current_header);
+
+      // Push a new loop onto the stack if this loop is a loop header.
+      if (HasLoopNumber(current)) {
+        ++loop_depth;
+        current_loop = &loops_[GetLoopNumber(current)];
+        BasicBlock* end = current_loop->end;
+        current->set_loop_end(end == NULL ? BeyondEndSentinel() : end);
+        current_header = current_loop->header;
+        Trace("B%d is a loop header, increment loop depth to %d\n",
+              current->id().ToInt(), loop_depth);
+      }
+
+      current->set_loop_depth(loop_depth);
+
+      if (current->loop_header() == NULL) {
+        Trace("B%d is not in a loop (depth == %d)\n", current->id().ToInt(),
+              current->loop_depth());
+      } else {
+        Trace("B%d has loop header B%d, (depth == %d)\n", current->id().ToInt(),
+              current->loop_header()->id().ToInt(), current->loop_depth());
+      }
     }
-    current->loop_depth_ = loop_depth;
-    if (current->loop_header_ == NULL) {
-      Trace("B%d is not in a loop (depth == %d)\n", current->id(),
-            current->loop_depth_);
-    } else {
-      Trace("B%d has loop header B%d, (depth == %d)\n", current->id(),
-            current->loop_header_->id(), current->loop_depth_);
+  }
+
+  // Computes loop membership from the backedges of the control flow graph.
+  void ComputeLoopInfo(ZoneVector<SpecialRPOStackFrame>& queue,
+                       size_t num_loops, ZoneVector<Backedge>* backedges) {
+    // Extend existing loop membership vectors.
+    for (LoopInfo& loop : loops_) {
+      BitVector* new_members = new (zone_)
+          BitVector(static_cast<int>(schedule_->BasicBlockCount()), zone_);
+      new_members->CopyFrom(*loop.members);
+      loop.members = new_members;
+    }
+
+    // Extend loop information vector.
+    loops_.resize(num_loops, LoopInfo());
+
+    // Compute loop membership starting from backedges.
+    // O(max(loop_depth) * max(|loop|)
+    for (size_t i = 0; i < backedges->size(); i++) {
+      BasicBlock* member = backedges->at(i).first;
+      BasicBlock* header = member->SuccessorAt(backedges->at(i).second);
+      size_t loop_num = GetLoopNumber(header);
+      if (loops_[loop_num].header == NULL) {
+        loops_[loop_num].header = header;
+        loops_[loop_num].members = new (zone_)
+            BitVector(static_cast<int>(schedule_->BasicBlockCount()), zone_);
+      }
+
+      int queue_length = 0;
+      if (member != header) {
+        // As long as the header doesn't have a backedge to itself,
+        // Push the member onto the queue and process its predecessors.
+        if (!loops_[loop_num].members->Contains(member->id().ToInt())) {
+          loops_[loop_num].members->Add(member->id().ToInt());
+        }
+        queue[queue_length++].block = member;
+      }
+
+      // Propagate loop membership backwards. All predecessors of M up to the
+      // loop header H are members of the loop too. O(|blocks between M and H|).
+      while (queue_length > 0) {
+        BasicBlock* block = queue[--queue_length].block;
+        for (size_t i = 0; i < block->PredecessorCount(); i++) {
+          BasicBlock* pred = block->PredecessorAt(i);
+          if (pred != header) {
+            if (!loops_[loop_num].members->Contains(pred->id().ToInt())) {
+              loops_[loop_num].members->Add(pred->id().ToInt());
+              queue[queue_length++].block = pred;
+            }
+          }
+        }
+      }
     }
   }
 
 #if DEBUG
-  if (FLAG_trace_turbo_scheduler) PrintRPO(num_loops, loops, final_order);
-  VerifySpecialRPO(num_loops, loops, final_order);
+  void PrintRPO() {
+    OFStream os(stdout);
+    os << "RPO with " << loops_.size() << " loops";
+    if (loops_.size() > 0) {
+      os << " (";
+      for (size_t i = 0; i < loops_.size(); i++) {
+        if (i > 0) os << " ";
+        os << "B" << loops_[i].header->id();
+      }
+      os << ")";
+    }
+    os << ":\n";
+
+    for (BasicBlock* block = order_; block != NULL; block = block->rpo_next()) {
+      BasicBlock::Id bid = block->id();
+      // TODO(jarin,svenpanne): Add formatting here once we have support for
+      // that in streams (we want an equivalent of PrintF("%5d:", x) here).
+      os << "  " << block->rpo_number() << ":";
+      for (size_t i = 0; i < loops_.size(); i++) {
+        bool range = loops_[i].header->LoopContains(block);
+        bool membership = loops_[i].header != block && range;
+        os << (membership ? " |" : "  ");
+        os << (range ? "x" : " ");
+      }
+      os << "  B" << bid << ": ";
+      if (block->loop_end() != NULL) {
+        os << " range: [" << block->rpo_number() << ", "
+           << block->loop_end()->rpo_number() << ")";
+      }
+      if (block->loop_header() != NULL) {
+        os << " header: B" << block->loop_header()->id();
+      }
+      if (block->loop_depth() > 0) {
+        os << " depth: " << block->loop_depth();
+      }
+      os << "\n";
+    }
+  }
+
+  void VerifySpecialRPO() {
+    BasicBlockVector* order = schedule_->rpo_order();
+    DCHECK(order->size() > 0);
+    DCHECK((*order)[0]->id().ToInt() == 0);  // entry should be first.
+
+    for (size_t i = 0; i < loops_.size(); i++) {
+      LoopInfo* loop = &loops_[i];
+      BasicBlock* header = loop->header;
+      BasicBlock* end = header->loop_end();
+
+      DCHECK(header != NULL);
+      DCHECK(header->rpo_number() >= 0);
+      DCHECK(header->rpo_number() < static_cast<int>(order->size()));
+      DCHECK(end != NULL);
+      DCHECK(end->rpo_number() <= static_cast<int>(order->size()));
+      DCHECK(end->rpo_number() > header->rpo_number());
+      DCHECK(header->loop_header() != header);
+
+      // Verify the start ... end list relationship.
+      int links = 0;
+      BasicBlock* block = loop->start;
+      DCHECK_EQ(header, block);
+      bool end_found;
+      while (true) {
+        if (block == NULL || block == loop->end) {
+          end_found = (loop->end == block);
+          break;
+        }
+        // The list should be in same order as the final result.
+        DCHECK(block->rpo_number() == links + header->rpo_number());
+        links++;
+        block = block->rpo_next();
+        DCHECK(links < static_cast<int>(2 * order->size()));  // cycle?
+      }
+      DCHECK(links > 0);
+      DCHECK(links == end->rpo_number() - header->rpo_number());
+      DCHECK(end_found);
+
+      // Check loop depth of the header.
+      int loop_depth = 0;
+      for (LoopInfo* outer = loop; outer != NULL; outer = outer->prev) {
+        loop_depth++;
+      }
+      DCHECK_EQ(loop_depth, header->loop_depth());
+
+      // Check the contiguousness of loops.
+      int count = 0;
+      for (int j = 0; j < static_cast<int>(order->size()); j++) {
+        BasicBlock* block = order->at(j);
+        DCHECK(block->rpo_number() == j);
+        if (j < header->rpo_number() || j >= end->rpo_number()) {
+          DCHECK(!header->LoopContains(block));
+        } else {
+          DCHECK(header->LoopContains(block));
+          DCHECK_GE(block->loop_depth(), loop_depth);
+          count++;
+        }
+      }
+      DCHECK(links == count);
+    }
+  }
+#endif  // DEBUG
+
+  Zone* zone_;
+  Schedule* schedule_;
+  BasicBlock* order_;
+  BasicBlock* beyond_end_;
+  ZoneVector<LoopInfo> loops_;
+  ZoneVector<Backedge> backedges_;
+  ZoneVector<SpecialRPOStackFrame> stack_;
+  size_t previous_block_count_;
+};
+
+
+BasicBlockVector* Scheduler::ComputeSpecialRPO(Zone* zone, Schedule* schedule) {
+  SpecialRPONumberer numberer(zone, schedule);
+  numberer.ComputeSpecialRPO();
+  numberer.SerializeRPOIntoSchedule();
+  numberer.PrintAndVerifySpecialRPO();
+  return schedule->rpo_order();
+}
+
+
+void Scheduler::ComputeSpecialRPONumbering() {
+  Trace("--- COMPUTING SPECIAL RPO ----------------------------------\n");
+
+  // Compute the special reverse-post-order for basic blocks.
+  special_rpo_ = new (zone_) SpecialRPONumberer(zone_, schedule_);
+  special_rpo_->ComputeSpecialRPO();
+}
+
+
+void Scheduler::PropagateImmediateDominators(BasicBlock* block) {
+  for (/*nop*/; block != NULL; block = block->rpo_next()) {
+    BasicBlock::Predecessors::iterator pred = block->predecessors_begin();
+    BasicBlock::Predecessors::iterator end = block->predecessors_end();
+    DCHECK(pred != end);  // All blocks except start have predecessors.
+    BasicBlock* dominator = *pred;
+    // For multiple predecessors, walk up the dominator tree until a common
+    // dominator is found. Visitation order guarantees that all predecessors
+    // except for backwards edges have been visited.
+    for (++pred; pred != end; ++pred) {
+      // Don't examine backwards edges.
+      if ((*pred)->dominator_depth() < 0) continue;
+      dominator = GetCommonDominator(dominator, *pred);
+    }
+    block->set_dominator(dominator);
+    block->set_dominator_depth(dominator->dominator_depth() + 1);
+    // Propagate "deferredness" of the dominator.
+    if (dominator->deferred()) block->set_deferred(true);
+    Trace("Block B%d's idom is B%d, depth = %d\n", block->id().ToInt(),
+          dominator->id().ToInt(), block->dominator_depth());
+  }
+}
+
+
+void Scheduler::GenerateImmediateDominatorTree() {
+  Trace("--- IMMEDIATE BLOCK DOMINATORS -----------------------------\n");
+
+  // Seed start block to be the first dominator.
+  schedule_->start()->set_dominator_depth(0);
+
+  // Build the block dominator tree resulting from the above seed.
+  PropagateImmediateDominators(schedule_->start()->rpo_next());
+}
+
+
+// -----------------------------------------------------------------------------
+// Phase 3: Prepare use counts for nodes.
+
+
+class PrepareUsesVisitor : public NullNodeVisitor {
+ public:
+  explicit PrepareUsesVisitor(Scheduler* scheduler)
+      : scheduler_(scheduler), schedule_(scheduler->schedule_) {}
+
+  void Pre(Node* node) {
+    if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
+      // Fixed nodes are always roots for schedule late.
+      scheduler_->schedule_root_nodes_.push_back(node);
+      if (!schedule_->IsScheduled(node)) {
+        // Make sure root nodes are scheduled in their respective blocks.
+        Trace("Scheduling fixed position node #%d:%s\n", node->id(),
+              node->op()->mnemonic());
+        IrOpcode::Value opcode = node->opcode();
+        BasicBlock* block =
+            opcode == IrOpcode::kParameter
+                ? schedule_->start()
+                : schedule_->block(NodeProperties::GetControlInput(node));
+        DCHECK(block != NULL);
+        schedule_->AddNode(block, node);
+      }
+    }
+  }
+
+  void PostEdge(Node* from, int index, Node* to) {
+    // If the edge is from an unscheduled node, then tally it in the use count
+    // for all of its inputs. The same criterion will be used in ScheduleLate
+    // for decrementing use counts.
+    if (!schedule_->IsScheduled(from)) {
+      DCHECK_NE(Scheduler::kFixed, scheduler_->GetPlacement(from));
+      scheduler_->IncrementUnscheduledUseCount(to, index, from);
+    }
+  }
+
+ private:
+  Scheduler* scheduler_;
+  Schedule* schedule_;
+};
+
+
+void Scheduler::PrepareUses() {
+  Trace("--- PREPARE USES -------------------------------------------\n");
+
+  // Count the uses of every node, it will be used to ensure that all of a
+  // node's uses are scheduled before the node itself.
+  PrepareUsesVisitor prepare_uses(this);
+  graph_->VisitNodeInputsFromEnd(&prepare_uses);
+}
+
+
+// -----------------------------------------------------------------------------
+// Phase 4: Schedule nodes early.
+
+
+class ScheduleEarlyNodeVisitor {
+ public:
+  ScheduleEarlyNodeVisitor(Zone* zone, Scheduler* scheduler)
+      : scheduler_(scheduler), schedule_(scheduler->schedule_), queue_(zone) {}
+
+  // Run the schedule early algorithm on a set of fixed root nodes.
+  void Run(NodeVector* roots) {
+    for (NodeVectorIter i = roots->begin(); i != roots->end(); ++i) {
+      queue_.push(*i);
+      while (!queue_.empty()) {
+        VisitNode(queue_.front());
+        queue_.pop();
+      }
+    }
+  }
+
+ private:
+  // Visits one node from the queue and propagates its current schedule early
+  // position to all uses. This in turn might push more nodes onto the queue.
+  void VisitNode(Node* node) {
+    Scheduler::SchedulerData* data = scheduler_->GetData(node);
+
+    // Fixed nodes already know their schedule early position.
+    if (scheduler_->GetPlacement(node) == Scheduler::kFixed) {
+      data->minimum_block_ = schedule_->block(node);
+      Trace("Fixing #%d:%s minimum_block = B%d, dominator_depth = %d\n",
+            node->id(), node->op()->mnemonic(),
+            data->minimum_block_->id().ToInt(),
+            data->minimum_block_->dominator_depth());
+    }
+
+    // No need to propagate unconstrained schedule early positions.
+    if (data->minimum_block_ == schedule_->start()) return;
+
+    // Propagate schedule early position.
+    DCHECK(data->minimum_block_ != NULL);
+    Node::Uses uses = node->uses();
+    for (Node::Uses::iterator i = uses.begin(); i != uses.end(); ++i) {
+      PropagateMinimumPositionToNode(data->minimum_block_, *i);
+    }
+  }
+
+  // Propagates {block} as another minimum position into the given {node}. This
+  // has the net effect of computing the minimum dominator block of {node} that
+  // still post-dominates all inputs to {node} when the queue is processed.
+  void PropagateMinimumPositionToNode(BasicBlock* block, Node* node) {
+    Scheduler::SchedulerData* data = scheduler_->GetData(node);
+
+    // No need to propagate to fixed node, it's guaranteed to be a root.
+    if (scheduler_->GetPlacement(node) == Scheduler::kFixed) return;
+
+    // Coupled nodes influence schedule early position of their control.
+    if (scheduler_->GetPlacement(node) == Scheduler::kCoupled) {
+      Node* control = NodeProperties::GetControlInput(node);
+      PropagateMinimumPositionToNode(block, control);
+    }
+
+    // Propagate new position if it is deeper down the dominator tree than the
+    // current. Note that all inputs need to have minimum block position inside
+    // the dominator chain of {node}'s minimum block position.
+    DCHECK(InsideSameDominatorChain(block, data->minimum_block_));
+    if (block->dominator_depth() > data->minimum_block_->dominator_depth()) {
+      data->minimum_block_ = block;
+      queue_.push(node);
+      Trace("Propagating #%d:%s minimum_block = B%d, dominator_depth = %d\n",
+            node->id(), node->op()->mnemonic(),
+            data->minimum_block_->id().ToInt(),
+            data->minimum_block_->dominator_depth());
+    }
+  }
+
+#if DEBUG
+  bool InsideSameDominatorChain(BasicBlock* b1, BasicBlock* b2) {
+    BasicBlock* dominator = scheduler_->GetCommonDominator(b1, b2);
+    return dominator == b1 || dominator == b2;
+  }
 #endif
-  return final_order;
+
+  Scheduler* scheduler_;
+  Schedule* schedule_;
+  ZoneQueue<Node*> queue_;
+};
+
+
+void Scheduler::ScheduleEarly() {
+  Trace("--- SCHEDULE EARLY -----------------------------------------\n");
+  if (FLAG_trace_turbo_scheduler) {
+    Trace("roots: ");
+    for (Node* node : schedule_root_nodes_) {
+      Trace("#%d:%s ", node->id(), node->op()->mnemonic());
+    }
+    Trace("\n");
+  }
+
+  // Compute the minimum block for each node thereby determining the earliest
+  // position each node could be placed within a valid schedule.
+  ScheduleEarlyNodeVisitor schedule_early_visitor(zone_, this);
+  schedule_early_visitor.Run(&schedule_root_nodes_);
 }
+
+
+// -----------------------------------------------------------------------------
+// Phase 5: Schedule nodes late.
+
+
+class ScheduleLateNodeVisitor {
+ public:
+  ScheduleLateNodeVisitor(Zone* zone, Scheduler* scheduler)
+      : scheduler_(scheduler), schedule_(scheduler_->schedule_) {}
+
+  // Run the schedule late algorithm on a set of fixed root nodes.
+  void Run(NodeVector* roots) {
+    for (NodeVectorIter i = roots->begin(); i != roots->end(); ++i) {
+      ProcessQueue(*i);
+    }
+  }
+
+ private:
+  void ProcessQueue(Node* root) {
+    ZoneQueue<Node*>* queue = &(scheduler_->schedule_queue_);
+    for (Node* node : root->inputs()) {
+      // Don't schedule coupled nodes on their own.
+      if (scheduler_->GetPlacement(node) == Scheduler::kCoupled) {
+        node = NodeProperties::GetControlInput(node);
+      }
+
+      // Test schedulability condition by looking at unscheduled use count.
+      if (scheduler_->GetData(node)->unscheduled_count_ != 0) continue;
+
+      queue->push(node);
+      while (!queue->empty()) {
+        VisitNode(queue->front());
+        queue->pop();
+      }
+    }
+  }
+
+  // Visits one node from the queue of schedulable nodes and determines its
+  // schedule late position. Also hoists nodes out of loops to find a more
+  // optimal scheduling position.
+  void VisitNode(Node* node) {
+    DCHECK_EQ(0, scheduler_->GetData(node)->unscheduled_count_);
+
+    // Don't schedule nodes that are already scheduled.
+    if (schedule_->IsScheduled(node)) return;
+    DCHECK_EQ(Scheduler::kSchedulable, scheduler_->GetPlacement(node));
+
+    // Determine the dominating block for all of the uses of this node. It is
+    // the latest block that this node can be scheduled in.
+    Trace("Scheduling #%d:%s\n", node->id(), node->op()->mnemonic());
+    BasicBlock* block = GetCommonDominatorOfUses(node);
+    DCHECK_NOT_NULL(block);
+
+    // The schedule early block dominates the schedule late block.
+    BasicBlock* min_block = scheduler_->GetData(node)->minimum_block_;
+    DCHECK_EQ(min_block, scheduler_->GetCommonDominator(block, min_block));
+    Trace("Schedule late of #%d:%s is B%d at loop depth %d, minimum = B%d\n",
+          node->id(), node->op()->mnemonic(), block->id().ToInt(),
+          block->loop_depth(), min_block->id().ToInt());
+
+    // Hoist nodes out of loops if possible. Nodes can be hoisted iteratively
+    // into enclosing loop pre-headers until they would preceed their schedule
+    // early position.
+    BasicBlock* hoist_block = GetPreHeader(block);
+    while (hoist_block != NULL &&
+           hoist_block->dominator_depth() >= min_block->dominator_depth()) {
+      Trace("  hoisting #%d:%s to block B%d\n", node->id(),
+            node->op()->mnemonic(), hoist_block->id().ToInt());
+      DCHECK_LT(hoist_block->loop_depth(), block->loop_depth());
+      block = hoist_block;
+      hoist_block = GetPreHeader(hoist_block);
+    }
+
+    // Schedule the node or a floating control structure.
+    if (NodeProperties::IsControl(node)) {
+      ScheduleFloatingControl(block, node);
+    } else {
+      ScheduleNode(block, node);
+    }
+  }
+
+  BasicBlock* GetPreHeader(BasicBlock* block) {
+    if (block->IsLoopHeader()) {
+      return block->dominator();
+    } else if (block->loop_header() != NULL) {
+      return block->loop_header()->dominator();
+    } else {
+      return NULL;
+    }
+  }
+
+  BasicBlock* GetCommonDominatorOfUses(Node* node) {
+    BasicBlock* block = NULL;
+    for (Edge edge : node->use_edges()) {
+      BasicBlock* use_block = GetBlockForUse(edge);
+      block = block == NULL ? use_block : use_block == NULL
+                                              ? block
+                                              : scheduler_->GetCommonDominator(
+                                                    block, use_block);
+    }
+    return block;
+  }
+
+  BasicBlock* GetBlockForUse(Edge edge) {
+    Node* use = edge.from();
+    IrOpcode::Value opcode = use->opcode();
+    if (opcode == IrOpcode::kPhi || opcode == IrOpcode::kEffectPhi) {
+      // If the use is from a coupled (i.e. floating) phi, compute the common
+      // dominator of its uses. This will not recurse more than one level.
+      if (scheduler_->GetPlacement(use) == Scheduler::kCoupled) {
+        Trace("  inspecting uses of coupled #%d:%s\n", use->id(),
+              use->op()->mnemonic());
+        DCHECK_EQ(edge.to(), NodeProperties::GetControlInput(use));
+        return GetCommonDominatorOfUses(use);
+      }
+      // If the use is from a fixed (i.e. non-floating) phi, use the block
+      // of the corresponding control input to the merge.
+      if (scheduler_->GetPlacement(use) == Scheduler::kFixed) {
+        Trace("  input@%d into a fixed phi #%d:%s\n", edge.index(), use->id(),
+              use->op()->mnemonic());
+        Node* merge = NodeProperties::GetControlInput(use, 0);
+        opcode = merge->opcode();
+        DCHECK(opcode == IrOpcode::kMerge || opcode == IrOpcode::kLoop);
+        use = NodeProperties::GetControlInput(merge, edge.index());
+      }
+    }
+    BasicBlock* result = schedule_->block(use);
+    if (result == NULL) return NULL;
+    Trace("  must dominate use #%d:%s in B%d\n", use->id(),
+          use->op()->mnemonic(), result->id().ToInt());
+    return result;
+  }
+
+  void ScheduleFloatingControl(BasicBlock* block, Node* node) {
+    scheduler_->FuseFloatingControl(block, node);
+  }
+
+  void ScheduleNode(BasicBlock* block, Node* node) {
+    schedule_->PlanNode(block, node);
+    scheduler_->scheduled_nodes_[block->id().ToSize()].push_back(node);
+    scheduler_->UpdatePlacement(node, Scheduler::kScheduled);
+  }
+
+  Scheduler* scheduler_;
+  Schedule* schedule_;
+};
+
+
+void Scheduler::ScheduleLate() {
+  Trace("--- SCHEDULE LATE ------------------------------------------\n");
+  if (FLAG_trace_turbo_scheduler) {
+    Trace("roots: ");
+    for (Node* node : schedule_root_nodes_) {
+      Trace("#%d:%s ", node->id(), node->op()->mnemonic());
+    }
+    Trace("\n");
+  }
+
+  // Schedule: Places nodes in dominator block of all their uses.
+  ScheduleLateNodeVisitor schedule_late_visitor(zone_, this);
+  schedule_late_visitor.Run(&schedule_root_nodes_);
 }
+
+
+// -----------------------------------------------------------------------------
+// Phase 6: Seal the final schedule.
+
+
+void Scheduler::SealFinalSchedule() {
+  Trace("--- SEAL FINAL SCHEDULE ------------------------------------\n");
+
+  // Serialize the assembly order and reverse-post-order numbering.
+  special_rpo_->SerializeRPOIntoSchedule();
+  special_rpo_->PrintAndVerifySpecialRPO();
+
+  // Add collected nodes for basic blocks to their blocks in the right order.
+  int block_num = 0;
+  for (NodeVector& nodes : scheduled_nodes_) {
+    BasicBlock::Id id = BasicBlock::Id::FromInt(block_num++);
+    BasicBlock* block = schedule_->GetBlockById(id);
+    for (NodeVectorRIter i = nodes.rbegin(); i != nodes.rend(); ++i) {
+      schedule_->AddNode(block, *i);
+    }
+  }
 }
-}  // namespace v8::internal::compiler
+
+
+// -----------------------------------------------------------------------------
+
+
+void Scheduler::FuseFloatingControl(BasicBlock* block, Node* node) {
+  Trace("--- FUSE FLOATING CONTROL ----------------------------------\n");
+  if (FLAG_trace_turbo_scheduler) {
+    OFStream os(stdout);
+    os << "Schedule before control flow fusion:\n" << *schedule_;
+  }
+
+  // Iterate on phase 1: Build control-flow graph.
+  control_flow_builder_->Run(block, node);
+
+  // Iterate on phase 2: Compute special RPO and dominator tree.
+  special_rpo_->UpdateSpecialRPO(block, schedule_->block(node));
+  // TODO(mstarzinger): Currently "iterate on" means "re-run". Fix that.
+  for (BasicBlock* b = block->rpo_next(); b != NULL; b = b->rpo_next()) {
+    b->set_dominator_depth(-1);
+    b->set_dominator(NULL);
+  }
+  PropagateImmediateDominators(block->rpo_next());
+
+  // Iterate on phase 4: Schedule nodes early.
+  // TODO(mstarzinger): The following loop gathering the propagation roots is a
+  // temporary solution and should be merged into the rest of the scheduler as
+  // soon as the approach settled for all floating loops.
+  NodeVector propagation_roots(control_flow_builder_->control_);
+  for (Node* node : control_flow_builder_->control_) {
+    for (Node* use : node->uses()) {
+      if (use->opcode() == IrOpcode::kPhi ||
+          use->opcode() == IrOpcode::kEffectPhi) {
+        propagation_roots.push_back(use);
+      }
+    }
+  }
+  if (FLAG_trace_turbo_scheduler) {
+    Trace("propagation roots: ");
+    for (Node* node : propagation_roots) {
+      Trace("#%d:%s ", node->id(), node->op()->mnemonic());
+    }
+    Trace("\n");
+  }
+  ScheduleEarlyNodeVisitor schedule_early_visitor(zone_, this);
+  schedule_early_visitor.Run(&propagation_roots);
+
+  // Move previously planned nodes.
+  // TODO(mstarzinger): Improve that by supporting bulk moves.
+  scheduled_nodes_.resize(schedule_->BasicBlockCount(), NodeVector(zone_));
+  MovePlannedNodes(block, schedule_->block(node));
+
+  if (FLAG_trace_turbo_scheduler) {
+    OFStream os(stdout);
+    os << "Schedule after control flow fusion:\n" << *schedule_;
+  }
+}
+
+
+void Scheduler::MovePlannedNodes(BasicBlock* from, BasicBlock* to) {
+  Trace("Move planned nodes from B%d to B%d\n", from->id().ToInt(),
+        to->id().ToInt());
+  NodeVector* nodes = &(scheduled_nodes_[from->id().ToSize()]);
+  for (NodeVectorIter i = nodes->begin(); i != nodes->end(); ++i) {
+    schedule_->SetBlockForNode(to, *i);
+    scheduled_nodes_[to->id().ToSize()].push_back(*i);
+  }
+  nodes->clear();
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/scheduler.h b/src/compiler/scheduler.h
index b21662f..9da0b6d 100644
--- a/src/compiler/scheduler.h
+++ b/src/compiler/scheduler.h
@@ -9,89 +9,106 @@
 
 #include "src/compiler/opcodes.h"
 #include "src/compiler/schedule.h"
+#include "src/compiler/zone-pool.h"
 #include "src/zone-containers.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+class CFGBuilder;
+class ControlEquivalence;
+class SpecialRPONumberer;
+
 // Computes a schedule from a graph, placing nodes into basic blocks and
 // ordering the basic blocks in the special RPO order.
 class Scheduler {
  public:
-  // The complete scheduling algorithm.
-  // Create a new schedule and place all nodes from the graph into it.
-  static Schedule* ComputeSchedule(Graph* graph);
+  // The complete scheduling algorithm. Creates a new schedule and places all
+  // nodes from the graph into it.
+  static Schedule* ComputeSchedule(Zone* zone, Graph* graph);
 
   // Compute the RPO of blocks in an existing schedule.
-  static BasicBlockVector* ComputeSpecialRPO(Schedule* schedule);
-
-  // (Exposed for testing only)
-  // Build and connect the CFG for a node graph, but don't schedule nodes.
-  static void ComputeCFG(Graph* graph, Schedule* schedule);
+  static BasicBlockVector* ComputeSpecialRPO(Zone* zone, Schedule* schedule);
 
  private:
-  enum Placement { kUnknown, kSchedulable, kFixed };
+  // Placement of a node changes during scheduling. The placement state
+  // transitions over time while the scheduler is choosing a position:
+  //
+  //                   +---------------------+-----+----> kFixed
+  //                  /                     /     /
+  //    kUnknown ----+------> kCoupled ----+     /
+  //                  \                         /
+  //                   +----> kSchedulable ----+--------> kScheduled
+  //
+  // 1) GetPlacement(): kUnknown -> kCoupled|kSchedulable|kFixed
+  // 2) UpdatePlacement(): kCoupled|kSchedulable -> kFixed|kScheduled
+  enum Placement { kUnknown, kSchedulable, kFixed, kCoupled, kScheduled };
 
   // Per-node data tracked during scheduling.
   struct SchedulerData {
+    BasicBlock* minimum_block_;  // Minimum legal RPO placement.
     int unscheduled_count_;      // Number of unscheduled uses of this node.
-    int minimum_rpo_;            // Minimum legal RPO placement.
-    bool is_connected_control_;  // {true} if control-connected to the end node.
-    bool is_floating_control_;   // {true} if control, but not control-connected
-                                 // to the end node.
-    Placement placement_ : 3;    // Whether the node is fixed, schedulable,
-                                 // or not yet known.
+    Placement placement_;        // Whether the node is fixed, schedulable,
+                                 // coupled to another node, or not yet known.
   };
 
   Zone* zone_;
   Graph* graph_;
   Schedule* schedule_;
-  NodeVectorVector scheduled_nodes_;
-  NodeVector schedule_root_nodes_;
-  ZoneVector<SchedulerData> node_data_;
-  bool has_floating_control_;
+  NodeVectorVector scheduled_nodes_;     // Per-block list of nodes in reverse.
+  NodeVector schedule_root_nodes_;       // Fixed root nodes seed the worklist.
+  ZoneQueue<Node*> schedule_queue_;      // Worklist of schedulable nodes.
+  ZoneVector<SchedulerData> node_data_;  // Per-node data for all nodes.
+  CFGBuilder* control_flow_builder_;     // Builds basic blocks for controls.
+  SpecialRPONumberer* special_rpo_;      // Special RPO numbering of blocks.
+  ControlEquivalence* equivalence_;      // Control dependence equivalence.
 
   Scheduler(Zone* zone, Graph* graph, Schedule* schedule);
 
-  SchedulerData DefaultSchedulerData();
-
-  SchedulerData* GetData(Node* node) {
-    DCHECK(node->id() < static_cast<int>(node_data_.size()));
-    return &node_data_[node->id()];
-  }
-
-  void BuildCFG();
+  inline SchedulerData DefaultSchedulerData();
+  inline SchedulerData* GetData(Node* node);
 
   Placement GetPlacement(Node* node);
+  void UpdatePlacement(Node* node, Placement placement);
 
-  int GetRPONumber(BasicBlock* block) {
-    DCHECK(block->rpo_number_ >= 0 &&
-           block->rpo_number_ < static_cast<int>(schedule_->rpo_order_.size()));
-    DCHECK(schedule_->rpo_order_[block->rpo_number_] == block);
-    return block->rpo_number_;
-  }
+  inline bool IsCoupledControlEdge(Node* node, int index);
+  void IncrementUnscheduledUseCount(Node* node, int index, Node* from);
+  void DecrementUnscheduledUseCount(Node* node, int index, Node* from);
 
-  void GenerateImmediateDominatorTree();
   BasicBlock* GetCommonDominator(BasicBlock* b1, BasicBlock* b2);
+  void PropagateImmediateDominators(BasicBlock* block);
 
+  // Phase 1: Build control-flow graph.
   friend class CFGBuilder;
+  void BuildCFG();
 
-  friend class ScheduleEarlyNodeVisitor;
-  void ScheduleEarly();
+  // Phase 2: Compute special RPO and dominator tree.
+  friend class SpecialRPONumberer;
+  void ComputeSpecialRPONumbering();
+  void GenerateImmediateDominatorTree();
 
+  // Phase 3: Prepare use counts for nodes.
   friend class PrepareUsesVisitor;
   void PrepareUses();
 
+  // Phase 4: Schedule nodes early.
+  friend class ScheduleEarlyNodeVisitor;
+  void ScheduleEarly();
+
+  // Phase 5: Schedule nodes late.
   friend class ScheduleLateNodeVisitor;
   void ScheduleLate();
 
-  bool ConnectFloatingControl();
+  // Phase 6: Seal the final schedule.
+  void SealFinalSchedule();
 
-  void ConnectFloatingControlSubgraph(BasicBlock* block, Node* node);
+  void FuseFloatingControl(BasicBlock* block, Node* node);
+  void MovePlannedNodes(BasicBlock* from, BasicBlock* to);
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_SCHEDULER_H_
diff --git a/src/compiler/select-lowering.cc b/src/compiler/select-lowering.cc
new file mode 100644
index 0000000..edecf58
--- /dev/null
+++ b/src/compiler/select-lowering.cc
@@ -0,0 +1,86 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/select-lowering.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/diamond.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/node.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+SelectLowering::SelectLowering(Graph* graph, CommonOperatorBuilder* common)
+    : common_(common),
+      graph_(graph),
+      merges_(Merges::key_compare(), Merges::allocator_type(graph->zone())) {}
+
+
+SelectLowering::~SelectLowering() {}
+
+
+Reduction SelectLowering::Reduce(Node* node) {
+  if (node->opcode() != IrOpcode::kSelect) return NoChange();
+  SelectParameters const p = SelectParametersOf(node->op());
+
+  Node* cond = node->InputAt(0);
+  Node* vthen = node->InputAt(1);
+  Node* velse = node->InputAt(2);
+  Node* merge = nullptr;
+
+  // Check if we already have a diamond for this condition.
+  auto range = merges_.equal_range(cond);
+  for (auto i = range.first;; ++i) {
+    if (i == range.second) {
+      // Create a new diamond for this condition and remember its merge node.
+      Diamond d(graph(), common(), cond, p.hint());
+      merges_.insert(std::make_pair(cond, d.merge));
+      merge = d.merge;
+      break;
+    }
+
+    // If the diamond is reachable from the Select, merging them would result in
+    // an unschedulable graph, so we cannot reuse the diamond in that case.
+    merge = i->second;
+    if (!ReachableFrom(merge, node)) {
+      break;
+    }
+  }
+
+  // Create a Phi hanging off the previously determined merge.
+  node->set_op(common()->Phi(p.type(), 2));
+  node->ReplaceInput(0, vthen);
+  node->ReplaceInput(1, velse);
+  node->ReplaceInput(2, merge);
+  return Changed(node);
+}
+
+
+bool SelectLowering::ReachableFrom(Node* const sink, Node* const source) {
+  // TODO(turbofan): This is probably horribly expensive, and it should be moved
+  // into node.h or somewhere else?!
+  Zone zone(graph()->zone()->isolate());
+  std::queue<Node*, NodeDeque> queue((NodeDeque(&zone)));
+  BoolVector visited(graph()->NodeCount(), false, &zone);
+  queue.push(source);
+  visited[source->id()] = true;
+  while (!queue.empty()) {
+    Node* current = queue.front();
+    if (current == sink) return true;
+    queue.pop();
+    for (auto input : current->inputs()) {
+      if (!visited[input->id()]) {
+        queue.push(input);
+        visited[input->id()] = true;
+      }
+    }
+  }
+  return false;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/select-lowering.h b/src/compiler/select-lowering.h
new file mode 100644
index 0000000..05ea0e0
--- /dev/null
+++ b/src/compiler/select-lowering.h
@@ -0,0 +1,48 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_SELECT_LOWERING_H_
+#define V8_COMPILER_SELECT_LOWERING_H_
+
+#include <map>
+
+#include "src/compiler/graph-reducer.h"
+#include "src/zone-allocator.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// Forward declarations.
+class CommonOperatorBuilder;
+class Graph;
+
+
+// Lowers Select nodes to diamonds.
+class SelectLowering FINAL : public Reducer {
+ public:
+  SelectLowering(Graph* graph, CommonOperatorBuilder* common);
+  ~SelectLowering();
+
+  Reduction Reduce(Node* node) OVERRIDE;
+
+ private:
+  typedef std::multimap<Node*, Node*, std::less<Node*>,
+                        zone_allocator<std::pair<Node* const, Node*>>> Merges;
+
+  bool ReachableFrom(Node* const sink, Node* const source);
+
+  CommonOperatorBuilder* common() const { return common_; }
+  Graph* graph() const { return graph_; }
+
+  CommonOperatorBuilder* common_;
+  Graph* graph_;
+  Merges merges_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_COMPILER_SELECT_LOWERING_H_
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
index f794525..1461709 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -4,10 +4,15 @@
 
 #include "src/compiler/simplified-lowering.h"
 
+#include <limits>
+
 #include "src/base/bits.h"
 #include "src/code-factory.h"
 #include "src/compiler/common-operator.h"
+#include "src/compiler/diamond.h"
 #include "src/compiler/graph-inl.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/node-matchers.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/compiler/representation-change.h"
 #include "src/compiler/simplified-lowering.h"
@@ -66,11 +71,18 @@
         info_(zone->NewArray<NodeInfo>(count_)),
         nodes_(zone),
         replacements_(zone),
-        contains_js_nodes_(false),
         phase_(PROPAGATE),
         changer_(changer),
         queue_(zone) {
     memset(info_, 0, sizeof(NodeInfo) * count_);
+
+    Factory* f = zone->isolate()->factory();
+    safe_bit_range_ =
+        Type::Union(Type::Boolean(),
+                    Type::Range(f->NewNumber(0), f->NewNumber(1), zone), zone);
+    safe_int_additive_range_ =
+        Type::Range(f->NewNumber(-std::pow(2.0, 52.0)),
+                    f->NewNumber(std::pow(2.0, 52.0)), zone);
   }
 
   void Run(SimplifiedLowering* lowering) {
@@ -164,6 +176,30 @@
            NodeProperties::GetBounds(node->InputAt(1)).upper->Is(type);
   }
 
+  void ProcessTruncateWord32Input(Node* node, int index, MachineTypeUnion use) {
+    Node* input = node->InputAt(index);
+    if (phase_ == PROPAGATE) {
+      // In the propagate phase, propagate the usage information backward.
+      Enqueue(input, use);
+    } else {
+      // In the change phase, insert a change before the use if necessary.
+      MachineTypeUnion output = GetInfo(input)->output;
+      if ((output & (kRepBit | kRepWord8 | kRepWord16 | kRepWord32)) == 0) {
+        // Output representation doesn't match usage.
+        TRACE(("  truncate-to-int32: #%d:%s(@%d #%d:%s) ", node->id(),
+               node->op()->mnemonic(), index, input->id(),
+               input->op()->mnemonic()));
+        TRACE((" from "));
+        PrintInfo(output);
+        TRACE((" to "));
+        PrintInfo(use);
+        TRACE(("\n"));
+        Node* n = changer_->GetTruncatedWord32For(input, output);
+        node->ReplaceInput(index, n);
+      }
+    }
+  }
+
   void ProcessInput(Node* node, int index, MachineTypeUnion use) {
     Node* input = node->InputAt(index);
     if (phase_ == PROPAGATE) {
@@ -206,22 +242,19 @@
   // context, effect, and control inputs, assuming that value inputs should have
   // {kRepTagged} representation and can observe all output values {kTypeAny}.
   void VisitInputs(Node* node) {
-    InputIter i = node->inputs().begin();
-    for (int j = OperatorProperties::GetValueInputCount(node->op()); j > 0;
-         ++i, j--) {
-      ProcessInput(node, i.index(), kMachAnyTagged);  // Value inputs
+    auto i = node->input_edges().begin();
+    for (int j = node->op()->ValueInputCount(); j > 0; ++i, j--) {
+      ProcessInput(node, (*i).index(), kMachAnyTagged);  // Value inputs
     }
     for (int j = OperatorProperties::GetContextInputCount(node->op()); j > 0;
          ++i, j--) {
-      ProcessInput(node, i.index(), kMachAnyTagged);  // Context inputs
+      ProcessInput(node, (*i).index(), kMachAnyTagged);  // Context inputs
     }
-    for (int j = OperatorProperties::GetEffectInputCount(node->op()); j > 0;
-         ++i, j--) {
-      Enqueue(*i);  // Effect inputs: just visit
+    for (int j = node->op()->EffectInputCount(); j > 0; ++i, j--) {
+      Enqueue((*i).to());  // Effect inputs: just visit
     }
-    for (int j = OperatorProperties::GetControlInputCount(node->op()); j > 0;
-         ++i, j--) {
-      Enqueue(*i);  // Control inputs: just visit
+    for (int j = node->op()->ControlInputCount(); j > 0; ++i, j--) {
+      Enqueue((*i).to());  // Control inputs: just visit
     }
     SetOutput(node, kMachAnyTagged);
   }
@@ -267,60 +300,83 @@
   void VisitInt64Cmp(Node* node) { VisitBinop(node, kMachInt64, kRepBit); }
   void VisitUint64Cmp(Node* node) { VisitBinop(node, kMachUint64, kRepBit); }
 
-  // Helper for handling phis.
-  void VisitPhi(Node* node, MachineTypeUnion use,
-                SimplifiedLowering* lowering) {
-    // First, propagate the usage information to inputs of the phi.
-    if (!lower()) {
-      int values = OperatorProperties::GetValueInputCount(node->op());
-      // Propagate {use} of the phi to value inputs, and 0 to control.
-      Node::Inputs inputs = node->inputs();
-      for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
-           ++iter, --values) {
-        // TODO(titzer): it'd be nice to have distinguished edge kinds here.
-        ProcessInput(node, iter.index(), values > 0 ? use : 0);
-      }
-    }
-    // Phis adapt to whatever output representation their uses demand,
-    // pushing representation changes to their inputs.
-    MachineTypeUnion use_rep = GetUseInfo(node) & kRepMask;
-    MachineTypeUnion use_type = GetUseInfo(node) & kTypeMask;
-    MachineTypeUnion rep = 0;
-    if (use_rep & kRepTagged) {
-      rep = kRepTagged;  // Tagged overrides everything.
-    } else if (use_rep & kRepFloat64) {
-      rep = kRepFloat64;
-    } else if (use_rep & kRepWord64) {
-      rep = kRepWord64;
-    } else if (use_rep & kRepWord32) {
-      rep = kRepWord32;
-    } else if (use_rep & kRepBit) {
-      rep = kRepBit;
-    } else {
-      // There was no representation associated with any of the uses.
-      // TODO(titzer): Select the best rep using phi's type, not the usage type?
-      if (use_type & kTypeAny) {
-        rep = kRepTagged;
-      } else if (use_type & kTypeNumber) {
-        rep = kRepFloat64;
-      } else if (use_type & kTypeInt64 || use_type & kTypeUint64) {
-        rep = kRepWord64;
-      } else if (use_type & kTypeInt32 || use_type & kTypeUint32) {
-        rep = kRepWord32;
-      } else if (use_type & kTypeBool) {
-        rep = kRepBit;
-      } else {
-        UNREACHABLE();  // should have at least a usage type!
-      }
-    }
-    // Preserve the usage type, but set the representation.
+  // Infer representation for phi-like nodes.
+  MachineType GetRepresentationForPhi(Node* node, MachineTypeUnion use) {
+    // Phis adapt to the output representation their uses demand.
     Type* upper = NodeProperties::GetBounds(node).upper;
-    MachineTypeUnion output_type = rep | changer_->TypeFromUpperBound(upper);
+    if ((use & kRepMask) == kRepTagged) {
+      // only tagged uses.
+      return kRepTagged;
+    } else if (upper->Is(Type::Integral32())) {
+      // Integer within [-2^31, 2^32[ range.
+      if ((use & kRepMask) == kRepFloat64) {
+        // only float64 uses.
+        return kRepFloat64;
+      } else if (upper->Is(Type::Signed32()) || upper->Is(Type::Unsigned32())) {
+        // multiple uses, but we are within 32 bits range => pick kRepWord32.
+        return kRepWord32;
+      } else if ((use & kRepMask) == kRepWord32 ||
+                 (use & kTypeMask) == kTypeInt32 ||
+                 (use & kTypeMask) == kTypeUint32) {
+        // We only use 32 bits or we use the result consistently.
+        return kRepWord32;
+      } else {
+        return kRepFloat64;
+      }
+    } else if (IsSafeBitOperand(node)) {
+      // multiple uses => pick kRepBit.
+      return kRepBit;
+    } else if (upper->Is(Type::Number())) {
+      // multiple uses => pick kRepFloat64.
+      return kRepFloat64;
+    }
+    return kRepTagged;
+  }
+
+  // Helper for handling selects.
+  void VisitSelect(Node* node, MachineTypeUnion use,
+                   SimplifiedLowering* lowering) {
+    ProcessInput(node, 0, kRepBit);
+    MachineType output = GetRepresentationForPhi(node, use);
+
+    Type* upper = NodeProperties::GetBounds(node).upper;
+    MachineType output_type =
+        static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output);
     SetOutput(node, output_type);
 
     if (lower()) {
-      int values = OperatorProperties::GetValueInputCount(node->op());
+      // Update the select operator.
+      SelectParameters p = SelectParametersOf(node->op());
+      MachineType type = static_cast<MachineType>(output_type);
+      if (type != p.type()) {
+        node->set_op(lowering->common()->Select(type, p.hint()));
+      }
 
+      // Convert inputs to the output representation of this select.
+      ProcessInput(node, 1, output_type);
+      ProcessInput(node, 2, output_type);
+    } else {
+      // Propagate {use} of the select to value inputs.
+      MachineType use_type =
+          static_cast<MachineType>((use & kTypeMask) | output);
+      ProcessInput(node, 1, use_type);
+      ProcessInput(node, 2, use_type);
+    }
+  }
+
+  // Helper for handling phis.
+  void VisitPhi(Node* node, MachineTypeUnion use,
+                SimplifiedLowering* lowering) {
+    MachineType output = GetRepresentationForPhi(node, use);
+
+    Type* upper = NodeProperties::GetBounds(node).upper;
+    MachineType output_type =
+        static_cast<MachineType>(changer_->TypeFromUpperBound(upper) | output);
+    SetOutput(node, output_type);
+
+    int values = node->op()->ValueInputCount();
+
+    if (lower()) {
       // Update the phi operator.
       MachineType type = static_cast<MachineType>(output_type);
       if (type != OpParameter<MachineType>(node)) {
@@ -328,11 +384,19 @@
       }
 
       // Convert inputs to the output representation of this phi.
-      Node::Inputs inputs = node->inputs();
-      for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
-           ++iter, --values) {
+      for (Edge const edge : node->input_edges()) {
         // TODO(titzer): it'd be nice to have distinguished edge kinds here.
-        ProcessInput(node, iter.index(), values > 0 ? output_type : 0);
+        ProcessInput(node, edge.index(), values > 0 ? output_type : 0);
+        values--;
+      }
+    } else {
+      // Propagate {use} of the phi to value inputs, and 0 to control.
+      MachineType use_type =
+          static_cast<MachineType>((use & kTypeMask) | output);
+      for (Edge const edge : node->input_edges()) {
+        // TODO(titzer): it'd be nice to have distinguished edge kinds here.
+        ProcessInput(node, edge.index(), values > 0 ? use_type : 0);
+        values--;
       }
     }
   }
@@ -349,13 +413,55 @@
     return changer_->Float64OperatorFor(node->opcode());
   }
 
-  static MachineType AssumeImplicitFloat32Change(MachineType type) {
-    // TODO(titzer): Assume loads of float32 change representation to float64.
-    // Fix this with full support for float32 representations.
-    if (type & kRepFloat32) {
-      return static_cast<MachineType>((type & ~kRepFloat32) | kRepFloat64);
-    }
-    return type;
+  bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) {
+    return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use);
+  }
+
+  bool IsSafeBitOperand(Node* node) {
+    Type* type = NodeProperties::GetBounds(node).upper;
+    return type->Is(safe_bit_range_);
+  }
+
+  bool IsSafeIntAdditiveOperand(Node* node) {
+    Type* type = NodeProperties::GetBounds(node).upper;
+    // TODO(jarin): Unfortunately, bitset types are not subtypes of larger
+    // range types, so we have to explicitly check for Integral32 here
+    // (in addition to the safe integer range). Once we fix subtyping for
+    // ranges, we should simplify this.
+    return type->Is(safe_int_additive_range_) || type->Is(Type::Integral32());
+  }
+
+  bool CanLowerToInt32AdditiveBinop(Node* node, MachineTypeUnion use) {
+    return IsSafeIntAdditiveOperand(node->InputAt(0)) &&
+           IsSafeIntAdditiveOperand(node->InputAt(1)) &&
+           !CanObserveNonInt32(use);
+  }
+
+  bool CanLowerToUint32Binop(Node* node, MachineTypeUnion use) {
+    return BothInputsAre(node, Type::Unsigned32()) && !CanObserveNonUint32(use);
+  }
+
+  bool CanLowerToUint32AdditiveBinop(Node* node, MachineTypeUnion use) {
+    return IsSafeIntAdditiveOperand(node->InputAt(0)) &&
+           IsSafeIntAdditiveOperand(node->InputAt(1)) &&
+           !CanObserveNonUint32(use);
+  }
+
+  bool CanObserveNonInt32(MachineTypeUnion use) {
+    return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0;
+  }
+
+  bool CanObserveMinusZero(MachineTypeUnion use) {
+    // TODO(turbofan): technically Uint32 cannot observe minus zero either.
+    return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0;
+  }
+
+  bool CanObserveNaN(MachineTypeUnion use) {
+    return (use & (kTypeNumber | kTypeAny)) != 0;
+  }
+
+  bool CanObserveNonUint32(MachineTypeUnion use) {
+    return (use & (kTypeInt32 | kTypeNumber | kTypeAny)) != 0;
   }
 
   // Dispatching routine for visiting the node {node} with the usage {use}.
@@ -401,6 +507,8 @@
         ProcessInput(node, 0, kRepBit);
         Enqueue(NodeProperties::GetControlInput(node, 0));
         break;
+      case IrOpcode::kSelect:
+        return VisitSelect(node, use, lowering);
       case IrOpcode::kPhi:
         return VisitPhi(node, use, lowering);
 
@@ -415,19 +523,40 @@
 #define DEFINE_JS_CASE(x) case IrOpcode::k##x:
         JS_OP_LIST(DEFINE_JS_CASE)
 #undef DEFINE_JS_CASE
-        contains_js_nodes_ = true;
         VisitInputs(node);
         return SetOutput(node, kRepTagged);
 
       //------------------------------------------------------------------
       // Simplified operators.
       //------------------------------------------------------------------
+      case IrOpcode::kAnyToBoolean: {
+        if (IsSafeBitOperand(node->InputAt(0))) {
+          VisitUnop(node, kRepBit, kRepBit);
+          if (lower()) DeferReplacement(node, node->InputAt(0));
+        } else {
+          VisitUnop(node, kMachAnyTagged, kTypeBool | kRepTagged);
+          if (lower()) {
+            // AnyToBoolean(x) => Call(ToBooleanStub, x, no-context)
+            Operator::Properties properties = node->op()->properties();
+            Callable callable = CodeFactory::ToBoolean(
+                jsgraph_->isolate(), ToBooleanStub::RESULT_AS_ODDBALL);
+            CallDescriptor::Flags flags = CallDescriptor::kPatchableCallSite;
+            CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+                callable.descriptor(), 0, flags, properties, jsgraph_->zone());
+            node->set_op(jsgraph_->common()->Call(desc));
+            node->InsertInput(jsgraph_->zone(), 0,
+                              jsgraph_->HeapConstant(callable.code()));
+            node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
+          }
+        }
+        break;
+      }
       case IrOpcode::kBooleanNot: {
         if (lower()) {
           MachineTypeUnion input = GetInfo(node->InputAt(0))->output;
           if (input & kRepBit) {
-            // BooleanNot(x: kRepBit) => WordEqual(x, #0)
-            node->set_op(lowering->machine()->WordEqual());
+            // BooleanNot(x: kRepBit) => Word32Equal(x, #0)
+            node->set_op(lowering->machine()->Word32Equal());
             node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
           } else {
             // BooleanNot(x: kRepTagged) => WordEqual(x, #false)
@@ -482,16 +611,26 @@
       case IrOpcode::kNumberSubtract: {
         // Add and subtract reduce to Int32Add/Sub if the inputs
         // are already integers and all uses are truncating.
-        if (BothInputsAre(node, Type::Signed32()) &&
-            (use & (kTypeUint32 | kTypeNumber | kTypeAny)) == 0) {
+        if (CanLowerToInt32Binop(node, use)) {
           // => signed Int32Add/Sub
           VisitInt32Binop(node);
           if (lower()) node->set_op(Int32Op(node));
-        } else if (BothInputsAre(node, Type::Unsigned32()) &&
-                   (use & (kTypeInt32 | kTypeNumber | kTypeAny)) == 0) {
+        } else if (CanLowerToInt32AdditiveBinop(node, use)) {
+          // => signed Int32Add/Sub, truncating inputs
+          ProcessTruncateWord32Input(node, 0, kTypeInt32);
+          ProcessTruncateWord32Input(node, 1, kTypeInt32);
+          SetOutput(node, kMachInt32);
+          if (lower()) node->set_op(Int32Op(node));
+        } else if (CanLowerToUint32Binop(node, use)) {
           // => unsigned Int32Add/Sub
           VisitUint32Binop(node);
           if (lower()) node->set_op(Uint32Op(node));
+        } else if (CanLowerToUint32AdditiveBinop(node, use)) {
+          // => signed Int32Add/Sub, truncating inputs
+          ProcessTruncateWord32Input(node, 0, kTypeUint32);
+          ProcessTruncateWord32Input(node, 1, kTypeUint32);
+          SetOutput(node, kMachUint32);
+          if (lower()) node->set_op(Uint32Op(node));
         } else {
           // => Float64Add/Sub
           VisitFloat64Binop(node);
@@ -499,54 +638,110 @@
         }
         break;
       }
-      case IrOpcode::kNumberMultiply:
-      case IrOpcode::kNumberDivide:
+      case IrOpcode::kNumberMultiply: {
+        NumberMatcher right(node->InputAt(1));
+        if (right.IsInRange(-1048576, 1048576)) {  // must fit double mantissa.
+          if (CanLowerToInt32Binop(node, use)) {
+            // => signed Int32Mul
+            VisitInt32Binop(node);
+            if (lower()) node->set_op(Int32Op(node));
+            break;
+          }
+        }
+        // => Float64Mul
+        VisitFloat64Binop(node);
+        if (lower()) node->set_op(Float64Op(node));
+        break;
+      }
+      case IrOpcode::kNumberDivide: {
+        if (CanLowerToInt32Binop(node, use)) {
+          // => signed Int32Div
+          VisitInt32Binop(node);
+          if (lower()) DeferReplacement(node, lowering->Int32Div(node));
+          break;
+        }
+        if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) {
+          // => unsigned Uint32Div
+          VisitUint32Binop(node);
+          if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
+          break;
+        }
+        // => Float64Div
+        VisitFloat64Binop(node);
+        if (lower()) node->set_op(Float64Op(node));
+        break;
+      }
       case IrOpcode::kNumberModulus: {
-        // Float64Mul/Div/Mod
+        if (CanLowerToInt32Binop(node, use)) {
+          // => signed Int32Mod
+          VisitInt32Binop(node);
+          if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
+          break;
+        }
+        if (BothInputsAre(node, Type::Unsigned32()) && !CanObserveNaN(use)) {
+          // => unsigned Uint32Mod
+          VisitUint32Binop(node);
+          if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
+          break;
+        }
+        // => Float64Mod
         VisitFloat64Binop(node);
         if (lower()) node->set_op(Float64Op(node));
         break;
       }
       case IrOpcode::kNumberToInt32: {
         MachineTypeUnion use_rep = use & kRepMask;
-        if (lower()) {
-          MachineTypeUnion in = GetInfo(node->InputAt(0))->output;
-          if ((in & kTypeMask) == kTypeInt32 || (in & kRepMask) == kRepWord32) {
-            // If the input has type int32, or is already a word32, just change
-            // representation if necessary.
-            VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep);
-            DeferReplacement(node, node->InputAt(0));
-          } else {
-            // Require the input in float64 format and perform truncation.
-            // TODO(turbofan): avoid a truncation with a smi check.
-            VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32);
-            node->set_op(lowering->machine()->TruncateFloat64ToInt32());
-          }
+        Node* input = node->InputAt(0);
+        Type* in_upper = NodeProperties::GetBounds(input).upper;
+        MachineTypeUnion in = GetInfo(input)->output;
+        if (in_upper->Is(Type::Signed32())) {
+          // If the input has type int32, pass through representation.
+          VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep);
+          if (lower()) DeferReplacement(node, node->InputAt(0));
+        } else if ((in & kTypeMask) == kTypeUint32 ||
+                   in_upper->Is(Type::Unsigned32())) {
+          // Just change representation if necessary.
+          VisitUnop(node, kTypeUint32 | kRepWord32, kTypeInt32 | kRepWord32);
+          if (lower()) DeferReplacement(node, node->InputAt(0));
+        } else if ((in & kTypeMask) == kTypeInt32 ||
+                   (in & kRepMask) == kRepWord32) {
+          // Just change representation if necessary.
+          VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32);
+          if (lower()) DeferReplacement(node, node->InputAt(0));
         } else {
-          // Propagate a type to the input, but pass through representation.
-          VisitUnop(node, kTypeInt32, kTypeInt32 | use_rep);
+          // Require the input in float64 format and perform truncation.
+          // TODO(turbofan): avoid a truncation with a smi check.
+          VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32);
+          if (lower())
+            node->set_op(lowering->machine()->TruncateFloat64ToInt32());
         }
         break;
       }
       case IrOpcode::kNumberToUint32: {
         MachineTypeUnion use_rep = use & kRepMask;
-        if (lower()) {
-          MachineTypeUnion in = GetInfo(node->InputAt(0))->output;
-          if ((in & kTypeMask) == kTypeUint32 ||
-              (in & kRepMask) == kRepWord32) {
-            // The input has type int32, just change representation.
-            VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep);
-            DeferReplacement(node, node->InputAt(0));
-          } else {
-            // Require the input in float64 format to perform truncation.
-            // TODO(turbofan): avoid the truncation with a smi check.
-            VisitUnop(node, kTypeUint32 | kRepFloat64,
-                      kTypeUint32 | kRepWord32);
-            node->set_op(lowering->machine()->TruncateFloat64ToInt32());
-          }
+        Node* input = node->InputAt(0);
+        Type* in_upper = NodeProperties::GetBounds(input).upper;
+        MachineTypeUnion in = GetInfo(input)->output;
+        if (in_upper->Is(Type::Unsigned32())) {
+          // If the input has type uint32, pass through representation.
+          VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep);
+          if (lower()) DeferReplacement(node, node->InputAt(0));
+        } else if ((in & kTypeMask) == kTypeUint32 ||
+                   in_upper->Is(Type::Unsigned32())) {
+          // Just change representation if necessary.
+          VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32);
+          if (lower()) DeferReplacement(node, node->InputAt(0));
+        } else if ((in & kTypeMask) == kTypeInt32 ||
+                   (in & kRepMask) == kRepWord32) {
+          // Just change representation if necessary.
+          VisitUnop(node, kTypeInt32 | kRepWord32, kTypeUint32 | kRepWord32);
+          if (lower()) DeferReplacement(node, node->InputAt(0));
         } else {
-          // Propagate a type to the input, but pass through representation.
-          VisitUnop(node, kTypeUint32, kTypeUint32 | use_rep);
+          // Require the input in float64 format and perform truncation.
+          // TODO(turbofan): avoid a truncation with a smi check.
+          VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32);
+          if (lower())
+            node->set_op(lowering->machine()->TruncateFloat64ToInt32());
         }
         break;
       }
@@ -579,47 +774,115 @@
         FieldAccess access = FieldAccessOf(node->op());
         ProcessInput(node, 0, changer_->TypeForBasePointer(access));
         ProcessRemainingInputs(node, 1);
-        SetOutput(node, AssumeImplicitFloat32Change(access.machine_type));
+        SetOutput(node, access.machine_type);
         if (lower()) lowering->DoLoadField(node);
         break;
       }
       case IrOpcode::kStoreField: {
         FieldAccess access = FieldAccessOf(node->op());
         ProcessInput(node, 0, changer_->TypeForBasePointer(access));
-        ProcessInput(node, 1, AssumeImplicitFloat32Change(access.machine_type));
+        ProcessInput(node, 1, access.machine_type);
         ProcessRemainingInputs(node, 2);
         SetOutput(node, 0);
         if (lower()) lowering->DoStoreField(node);
         break;
       }
-      case IrOpcode::kLoadElement: {
-        ElementAccess access = ElementAccessOf(node->op());
-        ProcessInput(node, 0, changer_->TypeForBasePointer(access));
-        ProcessInput(node, 1, kMachInt32);  // element index
+      case IrOpcode::kLoadBuffer: {
+        BufferAccess access = BufferAccessOf(node->op());
+        ProcessInput(node, 0, kMachPtr);    // buffer
+        ProcessInput(node, 1, kMachInt32);  // offset
         ProcessInput(node, 2, kMachInt32);  // length
         ProcessRemainingInputs(node, 3);
-        SetOutput(node, AssumeImplicitFloat32Change(access.machine_type));
+        // Tagged overrides everything if we have to do a typed array bounds
+        // check, because we may need to return undefined then.
+        MachineType output_type;
+        if (use & kRepTagged) {
+          output_type = kMachAnyTagged;
+        } else if (use & kRepFloat64) {
+          if (access.machine_type() & kRepFloat32) {
+            output_type = access.machine_type();
+          } else {
+            output_type = kMachFloat64;
+          }
+        } else if (use & kRepFloat32) {
+          output_type = kMachFloat32;
+        } else {
+          output_type = access.machine_type();
+        }
+        SetOutput(node, output_type);
+        if (lower()) lowering->DoLoadBuffer(node, output_type, changer_);
+        break;
+      }
+      case IrOpcode::kStoreBuffer: {
+        BufferAccess access = BufferAccessOf(node->op());
+        ProcessInput(node, 0, kMachPtr);               // buffer
+        ProcessInput(node, 1, kMachInt32);             // offset
+        ProcessInput(node, 2, kMachInt32);             // length
+        ProcessInput(node, 3, access.machine_type());  // value
+        ProcessRemainingInputs(node, 4);
+        SetOutput(node, 0);
+        if (lower()) lowering->DoStoreBuffer(node);
+        break;
+      }
+      case IrOpcode::kLoadElement: {
+        ElementAccess access = ElementAccessOf(node->op());
+        ProcessInput(node, 0, changer_->TypeForBasePointer(access));  // base
+        ProcessInput(node, 1, kMachInt32);                            // index
+        ProcessRemainingInputs(node, 2);
+        SetOutput(node, access.machine_type);
         if (lower()) lowering->DoLoadElement(node);
         break;
       }
       case IrOpcode::kStoreElement: {
         ElementAccess access = ElementAccessOf(node->op());
-        ProcessInput(node, 0, changer_->TypeForBasePointer(access));
-        ProcessInput(node, 1, kMachInt32);  // element index
-        ProcessInput(node, 2, kMachInt32);  // length
-        ProcessInput(node, 3, AssumeImplicitFloat32Change(access.machine_type));
-        ProcessRemainingInputs(node, 4);
+        ProcessInput(node, 0, changer_->TypeForBasePointer(access));  // base
+        ProcessInput(node, 1, kMachInt32);                            // index
+        ProcessInput(node, 2, access.machine_type);                   // value
+        ProcessRemainingInputs(node, 3);
         SetOutput(node, 0);
         if (lower()) lowering->DoStoreElement(node);
         break;
       }
+      case IrOpcode::kObjectIsSmi: {
+        ProcessInput(node, 0, kMachAnyTagged);
+        SetOutput(node, kRepBit | kTypeBool);
+        if (lower()) {
+          Node* is_tagged = jsgraph_->graph()->NewNode(
+              jsgraph_->machine()->WordAnd(), node->InputAt(0),
+              jsgraph_->Int32Constant(static_cast<int>(kSmiTagMask)));
+          Node* is_smi = jsgraph_->graph()->NewNode(
+              jsgraph_->machine()->WordEqual(), is_tagged,
+              jsgraph_->Int32Constant(kSmiTag));
+          DeferReplacement(node, is_smi);
+        }
+        break;
+      }
+      case IrOpcode::kObjectIsNonNegativeSmi: {
+        ProcessInput(node, 0, kMachAnyTagged);
+        SetOutput(node, kRepBit | kTypeBool);
+        if (lower()) {
+          Node* is_tagged = jsgraph_->graph()->NewNode(
+              jsgraph_->machine()->WordAnd(), node->InputAt(0),
+              jsgraph_->Int32Constant(static_cast<int>(kSmiTagMask)));
+          Node* is_smi = jsgraph_->graph()->NewNode(
+              jsgraph_->machine()->WordEqual(), is_tagged,
+              jsgraph_->Int32Constant(kSmiTag));
+          Node* is_non_neg = jsgraph_->graph()->NewNode(
+              jsgraph_->machine()->IntLessThanOrEqual(),
+              jsgraph_->Int32Constant(0), node->InputAt(0));
+          Node* is_non_neg_smi = jsgraph_->graph()->NewNode(
+              jsgraph_->machine()->Word32And(), is_smi, is_non_neg);
+          DeferReplacement(node, is_non_neg_smi);
+        }
+        break;
+      }
 
       //------------------------------------------------------------------
       // Machine-level operators.
       //------------------------------------------------------------------
       case IrOpcode::kLoad: {
         // TODO(titzer): machine loads/stores need to know BaseTaggedness!?
-        MachineType tBase = kRepTagged;
+        MachineTypeUnion tBase = kRepTagged | kMachPtr;
         LoadRepresentation rep = OpParameter<LoadRepresentation>(node);
         ProcessInput(node, 0, tBase);   // pointer or object
         ProcessInput(node, 1, kMachInt32);  // index
@@ -629,7 +892,7 @@
       }
       case IrOpcode::kStore: {
         // TODO(titzer): machine loads/stores need to know BaseTaggedness!?
-        MachineType tBase = kRepTagged;
+        MachineTypeUnion tBase = kRepTagged | kMachPtr;
         StoreRepresentation rep = OpParameter<StoreRepresentation>(node);
         ProcessInput(node, 0, tBase);   // pointer or object
         ProcessInput(node, 1, kMachInt32);  // index
@@ -640,7 +903,7 @@
       }
       case IrOpcode::kWord32Shr:
         // We output unsigned int32 for shift right because JavaScript.
-        return VisitBinop(node, kRepWord32, kRepWord32 | kTypeUint32);
+        return VisitBinop(node, kMachUint32, kMachUint32);
       case IrOpcode::kWord32And:
       case IrOpcode::kWord32Or:
       case IrOpcode::kWord32Xor:
@@ -656,11 +919,13 @@
       case IrOpcode::kInt32Add:
       case IrOpcode::kInt32Sub:
       case IrOpcode::kInt32Mul:
+      case IrOpcode::kInt32MulHigh:
       case IrOpcode::kInt32Div:
       case IrOpcode::kInt32Mod:
         return VisitInt32Binop(node);
-      case IrOpcode::kInt32UDiv:
-      case IrOpcode::kInt32UMod:
+      case IrOpcode::kUint32Div:
+      case IrOpcode::kUint32Mod:
+      case IrOpcode::kUint32MulHigh:
         return VisitUint32Binop(node);
       case IrOpcode::kInt32LessThan:
       case IrOpcode::kInt32LessThanOrEqual:
@@ -680,8 +945,11 @@
       case IrOpcode::kInt64LessThanOrEqual:
         return VisitInt64Cmp(node);
 
-      case IrOpcode::kInt64UDiv:
-      case IrOpcode::kInt64UMod:
+      case IrOpcode::kUint64LessThan:
+        return VisitUint64Cmp(node);
+
+      case IrOpcode::kUint64Div:
+      case IrOpcode::kUint64Mod:
         return VisitUint64Binop(node);
 
       case IrOpcode::kWord64And:
@@ -700,11 +968,17 @@
       case IrOpcode::kChangeUint32ToUint64:
         return VisitUnop(node, kTypeUint32 | kRepWord32,
                          kTypeUint32 | kRepWord64);
+      case IrOpcode::kTruncateFloat64ToFloat32:
+        return VisitUnop(node, kTypeNumber | kRepFloat64,
+                         kTypeNumber | kRepFloat32);
       case IrOpcode::kTruncateInt64ToInt32:
         // TODO(titzer): Is kTypeInt32 correct here?
         return VisitUnop(node, kTypeInt32 | kRepWord64,
                          kTypeInt32 | kRepWord32);
 
+      case IrOpcode::kChangeFloat32ToFloat64:
+        return VisitUnop(node, kTypeNumber | kRepFloat32,
+                         kTypeNumber | kRepFloat64);
       case IrOpcode::kChangeInt32ToFloat64:
         return VisitUnop(node, kTypeInt32 | kRepWord32,
                          kTypeInt32 | kRepFloat64);
@@ -725,11 +999,23 @@
       case IrOpcode::kFloat64Mod:
         return VisitFloat64Binop(node);
       case IrOpcode::kFloat64Sqrt:
+      case IrOpcode::kFloat64Floor:
+      case IrOpcode::kFloat64Ceil:
+      case IrOpcode::kFloat64RoundTruncate:
+      case IrOpcode::kFloat64RoundTiesAway:
         return VisitUnop(node, kMachFloat64, kMachFloat64);
       case IrOpcode::kFloat64Equal:
       case IrOpcode::kFloat64LessThan:
       case IrOpcode::kFloat64LessThanOrEqual:
         return VisitFloat64Cmp(node);
+      case IrOpcode::kLoadStackPointer:
+        return VisitLeaf(node, kMachPtr);
+      case IrOpcode::kStateValues:
+        for (int i = 0; i < node->InputCount(); i++) {
+          ProcessInput(node, i, kTypeAny);
+        }
+        SetOutput(node, kMachAnyTagged);
+        break;
       default:
         VisitInputs(node);
         break;
@@ -737,6 +1023,11 @@
   }
 
   void DeferReplacement(Node* node, Node* replacement) {
+    if (FLAG_trace_representation) {
+      TRACE(("defer replacement #%d:%s with #%d:%s\n", node->id(),
+             node->op()->mnemonic(), replacement->id(),
+             replacement->op()->mnemonic()));
+    }
     if (replacement->id() < count_) {
       // Replace with a previously existing node eagerly.
       node->ReplaceUses(replacement);
@@ -770,10 +1061,11 @@
   NodeInfo* info_;                  // node id -> usage information
   NodeVector nodes_;                // collected nodes
   NodeVector replacements_;         // replacements to be done after lowering
-  bool contains_js_nodes_;          // {true} if a JS operator was seen
   Phase phase_;                     // current phase of algorithm
   RepresentationChanger* changer_;  // for inserting representation changes
   ZoneQueue<Node*> queue_;          // queue for traversing the graph
+  Type* safe_bit_range_;
+  Type* safe_int_additive_range_;
 
   NodeInfo* GetInfo(Node* node) {
     DCHECK(node->id() >= 0);
@@ -797,7 +1089,7 @@
   SimplifiedOperatorBuilder simplified(graph()->zone());
   RepresentationChanger changer(jsgraph(), &simplified,
                                 graph()->zone()->isolate());
-  RepresentationSelector selector(jsgraph(), zone(), &changer);
+  RepresentationSelector selector(jsgraph(), zone_, &changer);
   selector.Run(this);
 }
 
@@ -837,8 +1129,8 @@
 void SimplifiedLowering::DoLoadField(Node* node) {
   const FieldAccess& access = FieldAccessOf(node->op());
   node->set_op(machine()->Load(access.machine_type));
-  Node* offset = jsgraph()->Int32Constant(access.offset - access.tag());
-  node->InsertInput(zone(), 1, offset);
+  Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
+  node->InsertInput(graph()->zone(), 1, offset);
 }
 
 
@@ -848,22 +1140,96 @@
       access.base_is_tagged, access.machine_type, access.type);
   node->set_op(
       machine()->Store(StoreRepresentation(access.machine_type, kind)));
-  Node* offset = jsgraph()->Int32Constant(access.offset - access.tag());
-  node->InsertInput(zone(), 1, offset);
+  Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
+  node->InsertInput(graph()->zone(), 1, offset);
 }
 
 
 Node* SimplifiedLowering::ComputeIndex(const ElementAccess& access,
-                                       Node* index) {
-  int element_size = ElementSizeOf(access.machine_type);
-  if (element_size != 1) {
-    index = graph()->NewNode(machine()->Int32Mul(),
-                             jsgraph()->Int32Constant(element_size), index);
+                                       Node* const key) {
+  Node* index = key;
+  const int element_size_shift = ElementSizeLog2Of(access.machine_type);
+  if (element_size_shift) {
+    index = graph()->NewNode(machine()->Word32Shl(), index,
+                             jsgraph()->Int32Constant(element_size_shift));
   }
-  int fixed_offset = access.header_size - access.tag();
-  if (fixed_offset == 0) return index;
-  return graph()->NewNode(machine()->Int32Add(), index,
-                          jsgraph()->Int32Constant(fixed_offset));
+  const int fixed_offset = access.header_size - access.tag();
+  if (fixed_offset) {
+    index = graph()->NewNode(machine()->Int32Add(), index,
+                             jsgraph()->Int32Constant(fixed_offset));
+  }
+  if (machine()->Is64()) {
+    // TODO(turbofan): This is probably only correct for typed arrays, and only
+    // if the typed arrays are at most 2GiB in size, which happens to match
+    // exactly our current situation.
+    index = graph()->NewNode(machine()->ChangeUint32ToUint64(), index);
+  }
+  return index;
+}
+
+
+void SimplifiedLowering::DoLoadBuffer(Node* node, MachineType output_type,
+                                      RepresentationChanger* changer) {
+  DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode());
+  DCHECK_NE(kMachNone, RepresentationOf(output_type));
+  MachineType const type = BufferAccessOf(node->op()).machine_type();
+  if (output_type != type) {
+    Node* const buffer = node->InputAt(0);
+    Node* const offset = node->InputAt(1);
+    Node* const length = node->InputAt(2);
+    Node* const effect = node->InputAt(3);
+    Node* const control = node->InputAt(4);
+    Node* const index =
+        machine()->Is64()
+            ? graph()->NewNode(machine()->ChangeUint32ToUint64(), offset)
+            : offset;
+
+    Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length);
+    Node* branch =
+        graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+
+    Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+    Node* etrue =
+        graph()->NewNode(machine()->Load(type), buffer, index, effect, if_true);
+    Node* vtrue = changer->GetRepresentationFor(etrue, type, output_type);
+
+    Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+    Node* efalse = effect;
+    Node* vfalse;
+    if (output_type & kRepTagged) {
+      vfalse = jsgraph()->UndefinedConstant();
+    } else if (output_type & kRepFloat64) {
+      vfalse =
+          jsgraph()->Float64Constant(std::numeric_limits<double>::quiet_NaN());
+    } else if (output_type & kRepFloat32) {
+      vfalse =
+          jsgraph()->Float32Constant(std::numeric_limits<float>::quiet_NaN());
+    } else {
+      vfalse = jsgraph()->Int32Constant(0);
+    }
+
+    Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+    Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
+
+    // Replace effect uses of {node} with the {ephi}.
+    NodeProperties::ReplaceWithValue(node, node, ephi);
+
+    // Turn the {node} into a Phi.
+    node->set_op(common()->Phi(output_type, 2));
+    node->ReplaceInput(0, vtrue);
+    node->ReplaceInput(1, vfalse);
+    node->ReplaceInput(2, merge);
+    node->TrimInputCount(3);
+  } else {
+    node->set_op(machine()->CheckedLoad(type));
+  }
+}
+
+
+void SimplifiedLowering::DoStoreBuffer(Node* node) {
+  DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode());
+  MachineType const type = BufferAccessOf(node->op()).machine_type();
+  node->set_op(machine()->CheckedStore(type));
 }
 
 
@@ -871,32 +1237,32 @@
   const ElementAccess& access = ElementAccessOf(node->op());
   node->set_op(machine()->Load(access.machine_type));
   node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
-  node->RemoveInput(2);
 }
 
 
 void SimplifiedLowering::DoStoreElement(Node* node) {
   const ElementAccess& access = ElementAccessOf(node->op());
-  WriteBarrierKind kind = ComputeWriteBarrierKind(
-      access.base_is_tagged, access.machine_type, access.type);
-  node->set_op(
-      machine()->Store(StoreRepresentation(access.machine_type, kind)));
+  node->set_op(machine()->Store(StoreRepresentation(
+      access.machine_type,
+      ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type,
+                              access.type))));
   node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
-  node->RemoveInput(2);
 }
 
 
 void SimplifiedLowering::DoStringAdd(Node* node) {
+  Operator::Properties properties = node->op()->properties();
   Callable callable = CodeFactory::StringAdd(
       zone()->isolate(), STRING_ADD_CHECK_NONE, NOT_TENURED);
   CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
-  CallDescriptor* desc =
-      Linkage::GetStubCallDescriptor(callable.descriptor(), 0, flags, zone());
+  CallDescriptor* desc = Linkage::GetStubCallDescriptor(
+      callable.descriptor(), 0, flags, properties, zone());
   node->set_op(common()->Call(desc));
-  node->InsertInput(zone(), 0, jsgraph()->HeapConstant(callable.code()));
-  node->AppendInput(zone(), jsgraph()->UndefinedConstant());
-  node->AppendInput(zone(), graph()->start());
-  node->AppendInput(zone(), graph()->start());
+  node->InsertInput(graph()->zone(), 0,
+                    jsgraph()->HeapConstant(callable.code()));
+  node->AppendInput(graph()->zone(), jsgraph()->UndefinedConstant());
+  node->AppendInput(graph()->zone(), graph()->start());
+  node->AppendInput(graph()->zone(), graph()->start());
 }
 
 
@@ -919,6 +1285,213 @@
 }
 
 
+Node* SimplifiedLowering::Int32Div(Node* const node) {
+  Int32BinopMatcher m(node);
+  Node* const zero = jsgraph()->Int32Constant(0);
+  Node* const lhs = m.left().node();
+  Node* const rhs = m.right().node();
+
+  if (m.right().Is(-1)) {
+    return graph()->NewNode(machine()->Int32Sub(), zero, lhs);
+  } else if (m.right().Is(0)) {
+    return rhs;
+  } else if (machine()->Int32DivIsSafe() || m.right().HasValue()) {
+    return graph()->NewNode(machine()->Int32Div(), lhs, rhs, graph()->start());
+  }
+
+  Diamond if_zero(graph(), common(),
+                  graph()->NewNode(machine()->Word32Equal(), rhs, zero),
+                  BranchHint::kFalse);
+
+  Diamond if_minus_one(graph(), common(),
+                       graph()->NewNode(machine()->Word32Equal(), rhs,
+                                        jsgraph()->Int32Constant(-1)),
+                       BranchHint::kFalse);
+  if_minus_one.Nest(if_zero, false);
+  Node* sub = graph()->NewNode(machine()->Int32Sub(), zero, lhs);
+  Node* div =
+      graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_minus_one.if_false);
+
+  return if_zero.Phi(kMachInt32, zero, if_minus_one.Phi(kMachInt32, sub, div));
+}
+
+
+Node* SimplifiedLowering::Int32Mod(Node* const node) {
+  Int32BinopMatcher m(node);
+  Node* const zero = jsgraph()->Int32Constant(0);
+  Node* const minus_one = jsgraph()->Int32Constant(-1);
+  Node* const lhs = m.left().node();
+  Node* const rhs = m.right().node();
+
+  if (m.right().Is(-1) || m.right().Is(0)) {
+    return zero;
+  } else if (m.right().HasValue()) {
+    return graph()->NewNode(machine()->Int32Mod(), lhs, rhs, graph()->start());
+  }
+
+  // General case for signed integer modulus, with optimization for (unknown)
+  // power of 2 right hand side.
+  //
+  //   if 0 < rhs then
+  //     msk = rhs - 1
+  //     if rhs & msk != 0 then
+  //       lhs % rhs
+  //     else
+  //       if lhs < 0 then
+  //         -(-lhs & msk)
+  //       else
+  //         lhs & msk
+  //   else
+  //     if rhs < -1 then
+  //       lhs % rhs
+  //     else
+  //       zero
+  //
+  // Note: We do not use the Diamond helper class here, because it really hurts
+  // readability with nested diamonds.
+  const Operator* const merge_op = common()->Merge(2);
+  const Operator* const phi_op = common()->Phi(kMachInt32, 2);
+
+  Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
+  Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
+                                   graph()->start());
+
+  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+  Node* true0;
+  {
+    Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
+
+    Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
+    Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
+
+    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+    Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
+
+    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+    Node* false1;
+    {
+      Node* check2 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
+      Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+                                       check2, if_false1);
+
+      Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
+      Node* true2 = graph()->NewNode(
+          machine()->Int32Sub(), zero,
+          graph()->NewNode(machine()->Word32And(),
+                           graph()->NewNode(machine()->Int32Sub(), zero, lhs),
+                           msk));
+
+      Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
+      Node* false2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
+
+      if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
+      false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
+    }
+
+    if_true0 = graph()->NewNode(merge_op, if_true1, if_false1);
+    true0 = graph()->NewNode(phi_op, true1, false1, if_true0);
+  }
+
+  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+  Node* false0;
+  {
+    Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
+    Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
+                                     check1, if_false0);
+
+    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+    Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
+
+    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+    Node* false1 = zero;
+
+    if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
+    false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
+  }
+
+  Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
+  return graph()->NewNode(phi_op, true0, false0, merge0);
+}
+
+
+Node* SimplifiedLowering::Uint32Div(Node* const node) {
+  Uint32BinopMatcher m(node);
+  Node* const zero = jsgraph()->Uint32Constant(0);
+  Node* const lhs = m.left().node();
+  Node* const rhs = m.right().node();
+
+  if (m.right().Is(0)) {
+    return zero;
+  } else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) {
+    return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start());
+  }
+
+  Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
+  Diamond d(graph(), common(), check, BranchHint::kFalse);
+  Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false);
+  return d.Phi(kMachUint32, zero, div);
+}
+
+
+Node* SimplifiedLowering::Uint32Mod(Node* const node) {
+  Uint32BinopMatcher m(node);
+  Node* const minus_one = jsgraph()->Int32Constant(-1);
+  Node* const zero = jsgraph()->Uint32Constant(0);
+  Node* const lhs = m.left().node();
+  Node* const rhs = m.right().node();
+
+  if (m.right().Is(0)) {
+    return zero;
+  } else if (m.right().HasValue()) {
+    return graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, graph()->start());
+  }
+
+  // General case for unsigned integer modulus, with optimization for (unknown)
+  // power of 2 right hand side.
+  //
+  //   if rhs then
+  //     msk = rhs - 1
+  //     if rhs & msk != 0 then
+  //       lhs % rhs
+  //     else
+  //       lhs & msk
+  //   else
+  //     zero
+  //
+  // Note: We do not use the Diamond helper class here, because it really hurts
+  // readability with nested diamonds.
+  const Operator* const merge_op = common()->Merge(2);
+  const Operator* const phi_op = common()->Phi(kMachInt32, 2);
+
+  Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), rhs,
+                                   graph()->start());
+
+  Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
+  Node* true0;
+  {
+    Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
+
+    Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
+    Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
+
+    Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
+    Node* true1 = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, if_true1);
+
+    Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
+    Node* false1 = graph()->NewNode(machine()->Word32And(), lhs, msk);
+
+    if_true0 = graph()->NewNode(merge_op, if_true1, if_false1);
+    true0 = graph()->NewNode(phi_op, true1, false1, if_true0);
+  }
+
+  Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
+  Node* false0 = zero;
+
+  Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
+  return graph()->NewNode(phi_op, true0, false0, merge0);
+}
+
+
 void SimplifiedLowering::DoStringEqual(Node* node) {
   node->set_op(machine()->WordEqual());
   node->ReplaceInput(0, StringComparison(node, false));
@@ -939,7 +1512,6 @@
   node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
 }
 
-
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/simplified-lowering.h b/src/compiler/simplified-lowering.h
index 2ba7e3b..b21cf21 100644
--- a/src/compiler/simplified-lowering.h
+++ b/src/compiler/simplified-lowering.h
@@ -14,16 +14,26 @@
 namespace internal {
 namespace compiler {
 
-class SimplifiedLowering {
+// Forward declarations.
+class RepresentationChanger;
+
+
+class SimplifiedLowering FINAL {
  public:
-  explicit SimplifiedLowering(JSGraph* jsgraph) : jsgraph_(jsgraph) {}
-  virtual ~SimplifiedLowering() {}
+  SimplifiedLowering(JSGraph* jsgraph, Zone* zone)
+      : jsgraph_(jsgraph), zone_(zone) {}
+  ~SimplifiedLowering() {}
 
   void LowerAllNodes();
 
   // TODO(titzer): These are exposed for direct testing. Use a friend class.
   void DoLoadField(Node* node);
   void DoStoreField(Node* node);
+  // TODO(turbofan): The output_type can be removed once the result of the
+  // representation analysis is stored in the node bounds.
+  void DoLoadBuffer(Node* node, MachineType output_type,
+                    RepresentationChanger* changer);
+  void DoStoreBuffer(Node* node);
   void DoLoadElement(Node* node);
   void DoStoreElement(Node* node);
   void DoStringAdd(Node* node);
@@ -32,14 +42,19 @@
   void DoStringLessThanOrEqual(Node* node);
 
  private:
-  JSGraph* jsgraph_;
+  JSGraph* const jsgraph_;
+  Zone* const zone_;
 
   Node* SmiTag(Node* node);
   Node* IsTagged(Node* node);
   Node* Untag(Node* node);
   Node* OffsetMinusTagConstant(int32_t offset);
-  Node* ComputeIndex(const ElementAccess& access, Node* index);
+  Node* ComputeIndex(const ElementAccess& access, Node* const key);
   Node* StringComparison(Node* node, bool requires_ordering);
+  Node* Int32Div(Node* const node);
+  Node* Int32Mod(Node* const node);
+  Node* Uint32Div(Node* const node);
+  Node* Uint32Mod(Node* const node);
 
   friend class RepresentationSelector;
 
diff --git a/src/compiler/simplified-operator-reducer-unittest.cc b/src/compiler/simplified-operator-reducer-unittest.cc
deleted file mode 100644
index 739264e..0000000
--- a/src/compiler/simplified-operator-reducer-unittest.cc
+++ /dev/null
@@ -1,483 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/graph-unittest.h"
-#include "src/compiler/js-graph.h"
-#include "src/compiler/simplified-operator.h"
-#include "src/compiler/simplified-operator-reducer.h"
-#include "src/compiler/typer.h"
-#include "src/conversions.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class SimplifiedOperatorReducerTest : public GraphTest {
- public:
-  explicit SimplifiedOperatorReducerTest(int num_parameters = 1)
-      : GraphTest(num_parameters), simplified_(zone()) {}
-  virtual ~SimplifiedOperatorReducerTest() {}
-
- protected:
-  Reduction Reduce(Node* node) {
-    Typer typer(zone());
-    MachineOperatorBuilder machine;
-    JSOperatorBuilder javascript(zone());
-    JSGraph jsgraph(graph(), common(), &javascript, &typer, &machine);
-    SimplifiedOperatorReducer reducer(&jsgraph);
-    return reducer.Reduce(node);
-  }
-
-  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
-
- private:
-  SimplifiedOperatorBuilder simplified_;
-};
-
-
-template <typename T>
-class SimplifiedOperatorReducerTestWithParam
-    : public SimplifiedOperatorReducerTest,
-      public ::testing::WithParamInterface<T> {
- public:
-  explicit SimplifiedOperatorReducerTestWithParam(int num_parameters = 1)
-      : SimplifiedOperatorReducerTest(num_parameters) {}
-  virtual ~SimplifiedOperatorReducerTestWithParam() {}
-};
-
-
-namespace {
-
-static const double kFloat64Values[] = {
-    -V8_INFINITY,  -6.52696e+290, -1.05768e+290, -5.34203e+268, -1.01997e+268,
-    -8.22758e+266, -1.58402e+261, -5.15246e+241, -5.92107e+226, -1.21477e+226,
-    -1.67913e+188, -1.6257e+184,  -2.60043e+170, -2.52941e+168, -3.06033e+116,
-    -4.56201e+52,  -3.56788e+50,  -9.9066e+38,   -3.07261e+31,  -2.1271e+09,
-    -1.91489e+09,  -1.73053e+09,  -9.30675e+08,  -26030,        -20453,
-    -15790,        -11699,        -111,          -97,           -78,
-    -63,           -58,           -1.53858e-06,  -2.98914e-12,  -1.14741e-39,
-    -8.20347e-57,  -1.48932e-59,  -3.17692e-66,  -8.93103e-81,  -3.91337e-83,
-    -6.0489e-92,   -8.83291e-113, -4.28266e-117, -1.92058e-178, -2.0567e-192,
-    -1.68167e-194, -1.51841e-214, -3.98738e-234, -7.31851e-242, -2.21875e-253,
-    -1.11612e-293, -0.0,          0.0,           2.22507e-308,  1.06526e-307,
-    4.16643e-227,  6.76624e-223,  2.0432e-197,   3.16254e-184,  1.37315e-173,
-    2.88603e-172,  1.54155e-99,   4.42923e-81,   1.40539e-73,   5.4462e-73,
-    1.24064e-58,   3.11167e-58,   2.75826e-39,   0.143815,      58,
-    67,            601,           7941,          11644,         13697,
-    25680,         29882,         1.32165e+08,   1.62439e+08,   4.16837e+08,
-    9.59097e+08,   1.32491e+09,   1.8728e+09,    1.0672e+17,    2.69606e+46,
-    1.98285e+79,   1.0098e+82,    7.93064e+88,   3.67444e+121,  9.36506e+123,
-    7.27954e+162,  3.05316e+168,  1.16171e+175,  1.64771e+189,  1.1622e+202,
-    2.00748e+239,  2.51778e+244,  3.90282e+306,  1.79769e+308,  V8_INFINITY};
-
-
-static const int32_t kInt32Values[] = {
-    -2147483647 - 1, -2104508227, -2103151830, -1435284490, -1378926425,
-    -1318814539,     -1289388009, -1287537572, -1279026536, -1241605942,
-    -1226046939,     -941837148,  -779818051,  -413830641,  -245798087,
-    -184657557,      -127145950,  -105483328,  -32325,      -26653,
-    -23858,          -23834,      -22363,      -19858,      -19044,
-    -18744,          -15528,      -5309,       -3372,       -2093,
-    -104,            -98,         -97,         -93,         -84,
-    -80,             -78,         -76,         -72,         -58,
-    -57,             -56,         -55,         -45,         -40,
-    -34,             -32,         -25,         -24,         -5,
-    -2,              0,           3,           10,          24,
-    34,              42,          46,          47,          48,
-    52,              56,          64,          65,          71,
-    76,              79,          81,          82,          97,
-    102,             103,         104,         106,         107,
-    109,             116,         122,         3653,        4485,
-    12405,           16504,       26262,       28704,       29755,
-    30554,           16476817,    605431957,   832401070,   873617242,
-    914205764,       1062628108,  1087581664,  1488498068,  1534668023,
-    1661587028,      1696896187,  1866841746,  2032089723,  2147483647};
-
-
-static const uint32_t kUint32Values[] = {
-    0x0,        0x5,        0x8,        0xc,        0xd,        0x26,
-    0x28,       0x29,       0x30,       0x34,       0x3e,       0x42,
-    0x50,       0x5b,       0x63,       0x71,       0x77,       0x7c,
-    0x83,       0x88,       0x96,       0x9c,       0xa3,       0xfa,
-    0x7a7,      0x165d,     0x234d,     0x3acb,     0x43a5,     0x4573,
-    0x5b4f,     0x5f14,     0x6996,     0x6c6e,     0x7289,     0x7b9a,
-    0x7bc9,     0x86bb,     0xa839,     0xaa41,     0xb03b,     0xc942,
-    0xce68,     0xcf4c,     0xd3ad,     0xdea3,     0xe90c,     0xed86,
-    0xfba5,     0x172dcc6,  0x114d8fc1, 0x182d6c9d, 0x1b1e3fad, 0x1db033bf,
-    0x1e1de755, 0x1f625c80, 0x28f6cf00, 0x2acb6a94, 0x2c20240e, 0x2f0fe54e,
-    0x31863a7c, 0x33325474, 0x3532fae3, 0x3bab82ea, 0x4c4b83a2, 0x4cd93d1e,
-    0x4f7331d4, 0x5491b09b, 0x57cc6ff9, 0x60d3b4dc, 0x653f5904, 0x690ae256,
-    0x69fe3276, 0x6bebf0ba, 0x6e2c69a3, 0x73b84ff7, 0x7b3a1924, 0x7ed032d9,
-    0x84dd734b, 0x8552ea53, 0x8680754f, 0x8e9660eb, 0x94fe2b9c, 0x972d30cf,
-    0x9b98c482, 0xb158667e, 0xb432932c, 0xb5b70989, 0xb669971a, 0xb7c359d1,
-    0xbeb15c0d, 0xc171c53d, 0xc743dd38, 0xc8e2af50, 0xc98e2df0, 0xd9d1cdf9,
-    0xdcc91049, 0xe46f396d, 0xee991950, 0xef64e521, 0xf7aeefc9, 0xffffffff};
-
-
-MATCHER(IsNaN, std::string(negation ? "isn't" : "is") + " NaN") {
-  return std::isnan(arg);
-}
-
-}  // namespace
-
-
-// -----------------------------------------------------------------------------
-// Unary operators
-
-
-namespace {
-
-struct UnaryOperator {
-  const Operator* (SimplifiedOperatorBuilder::*constructor)();
-  const char* constructor_name;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) {
-  return os << unop.constructor_name;
-}
-
-
-static const UnaryOperator kUnaryOperators[] = {
-    {&SimplifiedOperatorBuilder::BooleanNot, "BooleanNot"},
-    {&SimplifiedOperatorBuilder::ChangeBitToBool, "ChangeBitToBool"},
-    {&SimplifiedOperatorBuilder::ChangeBoolToBit, "ChangeBoolToBit"},
-    {&SimplifiedOperatorBuilder::ChangeFloat64ToTagged,
-     "ChangeFloat64ToTagged"},
-    {&SimplifiedOperatorBuilder::ChangeInt32ToTagged, "ChangeInt32ToTagged"},
-    {&SimplifiedOperatorBuilder::ChangeTaggedToFloat64,
-     "ChangeTaggedToFloat64"},
-    {&SimplifiedOperatorBuilder::ChangeTaggedToInt32, "ChangeTaggedToInt32"},
-    {&SimplifiedOperatorBuilder::ChangeTaggedToUint32, "ChangeTaggedToUint32"},
-    {&SimplifiedOperatorBuilder::ChangeUint32ToTagged, "ChangeUint32ToTagged"}};
-
-}  // namespace
-
-
-typedef SimplifiedOperatorReducerTestWithParam<UnaryOperator>
-    SimplifiedUnaryOperatorTest;
-
-
-TEST_P(SimplifiedUnaryOperatorTest, Parameter) {
-  const UnaryOperator& unop = GetParam();
-  Reduction reduction = Reduce(
-      graph()->NewNode((simplified()->*unop.constructor)(), Parameter(0)));
-  EXPECT_FALSE(reduction.Changed());
-}
-
-
-INSTANTIATE_TEST_CASE_P(SimplifiedOperatorReducerTest,
-                        SimplifiedUnaryOperatorTest,
-                        ::testing::ValuesIn(kUnaryOperators));
-
-
-// -----------------------------------------------------------------------------
-// BooleanNot
-
-
-TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithBooleanNot) {
-  Node* param0 = Parameter(0);
-  Reduction reduction = Reduce(
-      graph()->NewNode(simplified()->BooleanNot(),
-                       graph()->NewNode(simplified()->BooleanNot(), param0)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_EQ(param0, reduction.replacement());
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithFalseConstant) {
-  Reduction reduction0 =
-      Reduce(graph()->NewNode(simplified()->BooleanNot(), FalseConstant()));
-  ASSERT_TRUE(reduction0.Changed());
-  EXPECT_THAT(reduction0.replacement(), IsTrueConstant());
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithTrueConstant) {
-  Reduction reduction1 =
-      Reduce(graph()->NewNode(simplified()->BooleanNot(), TrueConstant()));
-  ASSERT_TRUE(reduction1.Changed());
-  EXPECT_THAT(reduction1.replacement(), IsFalseConstant());
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeBoolToBit
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeBitToBoolWithChangeBoolToBit) {
-  Node* param0 = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      simplified()->ChangeBitToBool(),
-      graph()->NewNode(simplified()->ChangeBoolToBit(), param0)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_EQ(param0, reduction.replacement());
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeBitToBoolWithZeroConstant) {
-  Reduction reduction = Reduce(
-      graph()->NewNode(simplified()->ChangeBitToBool(), Int32Constant(0)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsFalseConstant());
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeBitToBoolWithOneConstant) {
-  Reduction reduction = Reduce(
-      graph()->NewNode(simplified()->ChangeBitToBool(), Int32Constant(1)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsTrueConstant());
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeBoolToBit
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithFalseConstant) {
-  Reduction reduction = Reduce(
-      graph()->NewNode(simplified()->ChangeBoolToBit(), FalseConstant()));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithTrueConstant) {
-  Reduction reduction =
-      Reduce(graph()->NewNode(simplified()->ChangeBoolToBit(), TrueConstant()));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsInt32Constant(1));
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithChangeBitToBool) {
-  Node* param0 = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      simplified()->ChangeBoolToBit(),
-      graph()->NewNode(simplified()->ChangeBitToBool(), param0)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_EQ(param0, reduction.replacement());
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeFloat64ToTagged
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeFloat64ToTaggedWithConstant) {
-  TRACED_FOREACH(double, n, kFloat64Values) {
-    Reduction reduction = Reduce(graph()->NewNode(
-        simplified()->ChangeFloat64ToTagged(), Float64Constant(n)));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsNumberConstant(n));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeInt32ToTagged
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeInt32ToTaggedWithConstant) {
-  TRACED_FOREACH(int32_t, n, kInt32Values) {
-    Reduction reduction = Reduce(graph()->NewNode(
-        simplified()->ChangeInt32ToTagged(), Int32Constant(n)));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsNumberConstant(FastI2D(n)));
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeTaggedToFloat64
-
-
-TEST_F(SimplifiedOperatorReducerTest,
-       ChangeTaggedToFloat64WithChangeFloat64ToTagged) {
-  Node* param0 = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      simplified()->ChangeTaggedToFloat64(),
-      graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_EQ(param0, reduction.replacement());
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest,
-       ChangeTaggedToFloat64WithChangeInt32ToTagged) {
-  Node* param0 = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      simplified()->ChangeTaggedToFloat64(),
-      graph()->NewNode(simplified()->ChangeInt32ToTagged(), param0)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsChangeInt32ToFloat64(param0));
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest,
-       ChangeTaggedToFloat64WithChangeUint32ToTagged) {
-  Node* param0 = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      simplified()->ChangeTaggedToFloat64(),
-      graph()->NewNode(simplified()->ChangeUint32ToTagged(), param0)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsChangeUint32ToFloat64(param0));
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithConstant) {
-  TRACED_FOREACH(double, n, kFloat64Values) {
-    Reduction reduction = Reduce(graph()->NewNode(
-        simplified()->ChangeTaggedToFloat64(), NumberConstant(n)));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsFloat64Constant(n));
-  }
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithNaNConstant1) {
-  Reduction reduction =
-      Reduce(graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
-                              NumberConstant(-base::OS::nan_value())));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsFloat64Constant(IsNaN()));
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithNaNConstant2) {
-  Reduction reduction =
-      Reduce(graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
-                              NumberConstant(base::OS::nan_value())));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsFloat64Constant(IsNaN()));
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeTaggedToInt32
-
-
-TEST_F(SimplifiedOperatorReducerTest,
-       ChangeTaggedToInt32WithChangeFloat64ToTagged) {
-  Node* param0 = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      simplified()->ChangeTaggedToInt32(),
-      graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsChangeFloat64ToInt32(param0));
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest,
-       ChangeTaggedToInt32WithChangeInt32ToTagged) {
-  Node* param0 = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      simplified()->ChangeTaggedToInt32(),
-      graph()->NewNode(simplified()->ChangeInt32ToTagged(), param0)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_EQ(param0, reduction.replacement());
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithConstant) {
-  TRACED_FOREACH(double, n, kFloat64Values) {
-    Reduction reduction = Reduce(graph()->NewNode(
-        simplified()->ChangeTaggedToInt32(), NumberConstant(n)));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(n)));
-  }
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithNaNConstant1) {
-  Reduction reduction =
-      Reduce(graph()->NewNode(simplified()->ChangeTaggedToInt32(),
-                              NumberConstant(-base::OS::nan_value())));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithNaNConstant2) {
-  Reduction reduction =
-      Reduce(graph()->NewNode(simplified()->ChangeTaggedToInt32(),
-                              NumberConstant(base::OS::nan_value())));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeTaggedToUint32
-
-
-TEST_F(SimplifiedOperatorReducerTest,
-       ChangeTaggedToUint32WithChangeFloat64ToTagged) {
-  Node* param0 = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      simplified()->ChangeTaggedToUint32(),
-      graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsChangeFloat64ToUint32(param0));
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest,
-       ChangeTaggedToUint32WithChangeUint32ToTagged) {
-  Node* param0 = Parameter(0);
-  Reduction reduction = Reduce(graph()->NewNode(
-      simplified()->ChangeTaggedToUint32(),
-      graph()->NewNode(simplified()->ChangeUint32ToTagged(), param0)));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_EQ(param0, reduction.replacement());
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithConstant) {
-  TRACED_FOREACH(double, n, kFloat64Values) {
-    Reduction reduction = Reduce(graph()->NewNode(
-        simplified()->ChangeTaggedToUint32(), NumberConstant(n)));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(),
-                IsInt32Constant(bit_cast<int32_t>(DoubleToUint32(n))));
-  }
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithNaNConstant1) {
-  Reduction reduction =
-      Reduce(graph()->NewNode(simplified()->ChangeTaggedToUint32(),
-                              NumberConstant(-base::OS::nan_value())));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
-}
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithNaNConstant2) {
-  Reduction reduction =
-      Reduce(graph()->NewNode(simplified()->ChangeTaggedToUint32(),
-                              NumberConstant(base::OS::nan_value())));
-  ASSERT_TRUE(reduction.Changed());
-  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
-}
-
-
-// -----------------------------------------------------------------------------
-// ChangeUint32ToTagged
-
-
-TEST_F(SimplifiedOperatorReducerTest, ChangeUint32ToTagged) {
-  TRACED_FOREACH(uint32_t, n, kUint32Values) {
-    Reduction reduction =
-        Reduce(graph()->NewNode(simplified()->ChangeUint32ToTagged(),
-                                Int32Constant(bit_cast<int32_t>(n))));
-    ASSERT_TRUE(reduction.Changed());
-    EXPECT_THAT(reduction.replacement(), IsNumberConstant(FastUI2D(n)));
-  }
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/simplified-operator-reducer.cc b/src/compiler/simplified-operator-reducer.cc
index f6181ea..9d45e5b 100644
--- a/src/compiler/simplified-operator-reducer.cc
+++ b/src/compiler/simplified-operator-reducer.cc
@@ -2,21 +2,29 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/compiler/generic-node-inl.h"
+#include "src/compiler/simplified-operator-reducer.h"
+
+#include "src/compiler/access-builder.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/machine-operator.h"
 #include "src/compiler/node-matchers.h"
-#include "src/compiler/simplified-operator-reducer.h"
+#include "src/compiler/node-properties-inl.h"
 
 namespace v8 {
 namespace internal {
 namespace compiler {
 
+SimplifiedOperatorReducer::SimplifiedOperatorReducer(JSGraph* jsgraph)
+    : jsgraph_(jsgraph), simplified_(jsgraph->zone()) {}
+
+
 SimplifiedOperatorReducer::~SimplifiedOperatorReducer() {}
 
 
 Reduction SimplifiedOperatorReducer::Reduce(Node* node) {
   switch (node->opcode()) {
+    case IrOpcode::kAnyToBoolean:
+      return ReduceAnyToBoolean(node);
     case IrOpcode::kBooleanNot: {
       HeapObjectMatcher<HeapObject> m(node->InputAt(0));
       if (m.Is(Unique<HeapObject>::CreateImmovable(factory()->false_value()))) {
@@ -102,8 +110,36 @@
 }
 
 
+Reduction SimplifiedOperatorReducer::ReduceAnyToBoolean(Node* node) {
+  Node* const input = NodeProperties::GetValueInput(node, 0);
+  Type* const input_type = NodeProperties::GetBounds(input).upper;
+  if (input_type->Is(Type::Boolean())) {
+    // AnyToBoolean(x:boolean) => x
+    return Replace(input);
+  }
+  if (input_type->Is(Type::OrderedNumber())) {
+    // AnyToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0))
+    Node* compare = graph()->NewNode(simplified()->NumberEqual(), input,
+                                     jsgraph()->ZeroConstant());
+    return Change(node, simplified()->BooleanNot(), compare);
+  }
+  if (input_type->Is(Type::String())) {
+    // AnyToBoolean(x:string) => BooleanNot(NumberEqual(x.length, #0))
+    FieldAccess const access = AccessBuilder::ForStringLength();
+    Node* length = graph()->NewNode(simplified()->LoadField(access), input,
+                                    graph()->start(), graph()->start());
+    Node* compare = graph()->NewNode(simplified()->NumberEqual(), length,
+                                     jsgraph()->ZeroConstant());
+    return Change(node, simplified()->BooleanNot(), compare);
+  }
+  return NoChange();
+}
+
+
 Reduction SimplifiedOperatorReducer::Change(Node* node, const Operator* op,
                                             Node* a) {
+  DCHECK_EQ(node->InputCount(), OperatorProperties::GetTotalInputCount(op));
+  DCHECK_LE(1, node->InputCount());
   node->set_op(op);
   node->ReplaceInput(0, a);
   return Changed(node);
@@ -138,6 +174,11 @@
 }
 
 
+CommonOperatorBuilder* SimplifiedOperatorReducer::common() const {
+  return jsgraph()->common();
+}
+
+
 MachineOperatorBuilder* SimplifiedOperatorReducer::machine() const {
   return jsgraph()->machine();
 }
diff --git a/src/compiler/simplified-operator-reducer.h b/src/compiler/simplified-operator-reducer.h
index 32f49ad..1e565b8 100644
--- a/src/compiler/simplified-operator-reducer.h
+++ b/src/compiler/simplified-operator-reducer.h
@@ -6,6 +6,7 @@
 #define V8_COMPILER_SIMPLIFIED_OPERATOR_REDUCER_H_
 
 #include "src/compiler/graph-reducer.h"
+#include "src/compiler/simplified-operator.h"
 
 namespace v8 {
 namespace internal {
@@ -16,17 +17,20 @@
 namespace compiler {
 
 // Forward declarations.
+class CommonOperatorBuilder;
 class JSGraph;
 class MachineOperatorBuilder;
 
 class SimplifiedOperatorReducer FINAL : public Reducer {
  public:
-  explicit SimplifiedOperatorReducer(JSGraph* jsgraph) : jsgraph_(jsgraph) {}
-  virtual ~SimplifiedOperatorReducer();
+  explicit SimplifiedOperatorReducer(JSGraph* jsgraph);
+  ~SimplifiedOperatorReducer() FINAL;
 
-  virtual Reduction Reduce(Node* node) OVERRIDE;
+  Reduction Reduce(Node* node) FINAL;
 
  private:
+  Reduction ReduceAnyToBoolean(Node* node);
+
   Reduction Change(Node* node, const Operator* op, Node* a);
   Reduction ReplaceFloat64(double value);
   Reduction ReplaceInt32(int32_t value);
@@ -39,9 +43,12 @@
   Graph* graph() const;
   Factory* factory() const;
   JSGraph* jsgraph() const { return jsgraph_; }
+  CommonOperatorBuilder* common() const;
   MachineOperatorBuilder* machine() const;
+  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
 
   JSGraph* jsgraph_;
+  SimplifiedOperatorBuilder simplified_;
 
   DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorReducer);
 };
diff --git a/src/compiler/simplified-operator-unittest.cc b/src/compiler/simplified-operator-unittest.cc
deleted file mode 100644
index 4014f24..0000000
--- a/src/compiler/simplified-operator-unittest.cc
+++ /dev/null
@@ -1,222 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/simplified-operator.h"
-
-#include "src/compiler/operator-properties-inl.h"
-#include "src/test/test-utils.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-// TODO(bmeurer): Drop once we use std::ostream instead of our OStream.
-inline std::ostream& operator<<(std::ostream& os, const ElementAccess& access) {
-  OStringStream ost;
-  ost << access;
-  return os << ost.c_str();
-}
-
-
-// -----------------------------------------------------------------------------
-// Pure operators.
-
-
-namespace {
-
-struct PureOperator {
-  const Operator* (SimplifiedOperatorBuilder::*constructor)();
-  IrOpcode::Value opcode;
-  Operator::Properties properties;
-  int value_input_count;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
-  return os << IrOpcode::Mnemonic(pop.opcode);
-}
-
-
-const PureOperator kPureOperators[] = {
-#define PURE(Name, properties, input_count)              \
-  {                                                      \
-    &SimplifiedOperatorBuilder::Name, IrOpcode::k##Name, \
-        Operator::kPure | properties, input_count        \
-  }
-    PURE(BooleanNot, Operator::kNoProperties, 1),
-    PURE(NumberEqual, Operator::kCommutative, 2),
-    PURE(NumberLessThan, Operator::kNoProperties, 2),
-    PURE(NumberLessThanOrEqual, Operator::kNoProperties, 2),
-    PURE(NumberAdd, Operator::kCommutative, 2),
-    PURE(NumberSubtract, Operator::kNoProperties, 2),
-    PURE(NumberMultiply, Operator::kCommutative, 2),
-    PURE(NumberDivide, Operator::kNoProperties, 2),
-    PURE(NumberModulus, Operator::kNoProperties, 2),
-    PURE(NumberToInt32, Operator::kNoProperties, 1),
-    PURE(NumberToUint32, Operator::kNoProperties, 1),
-    PURE(StringEqual, Operator::kCommutative, 2),
-    PURE(StringLessThan, Operator::kNoProperties, 2),
-    PURE(StringLessThanOrEqual, Operator::kNoProperties, 2),
-    PURE(StringAdd, Operator::kNoProperties, 2),
-    PURE(ChangeTaggedToInt32, Operator::kNoProperties, 1),
-    PURE(ChangeTaggedToUint32, Operator::kNoProperties, 1),
-    PURE(ChangeTaggedToFloat64, Operator::kNoProperties, 1),
-    PURE(ChangeInt32ToTagged, Operator::kNoProperties, 1),
-    PURE(ChangeUint32ToTagged, Operator::kNoProperties, 1),
-    PURE(ChangeFloat64ToTagged, Operator::kNoProperties, 1),
-    PURE(ChangeBoolToBit, Operator::kNoProperties, 1),
-    PURE(ChangeBitToBool, Operator::kNoProperties, 1)
-#undef PURE
-};
-
-}  // namespace
-
-
-class SimplifiedPureOperatorTest
-    : public TestWithZone,
-      public ::testing::WithParamInterface<PureOperator> {};
-
-
-TEST_P(SimplifiedPureOperatorTest, InstancesAreGloballyShared) {
-  const PureOperator& pop = GetParam();
-  SimplifiedOperatorBuilder simplified1(zone());
-  SimplifiedOperatorBuilder simplified2(zone());
-  EXPECT_EQ((simplified1.*pop.constructor)(), (simplified2.*pop.constructor)());
-}
-
-
-TEST_P(SimplifiedPureOperatorTest, NumberOfInputsAndOutputs) {
-  SimplifiedOperatorBuilder simplified(zone());
-  const PureOperator& pop = GetParam();
-  const Operator* op = (simplified.*pop.constructor)();
-
-  EXPECT_EQ(pop.value_input_count, OperatorProperties::GetValueInputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetEffectInputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
-  EXPECT_EQ(pop.value_input_count, OperatorProperties::GetTotalInputCount(op));
-
-  EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetEffectOutputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
-}
-
-
-TEST_P(SimplifiedPureOperatorTest, OpcodeIsCorrect) {
-  SimplifiedOperatorBuilder simplified(zone());
-  const PureOperator& pop = GetParam();
-  const Operator* op = (simplified.*pop.constructor)();
-  EXPECT_EQ(pop.opcode, op->opcode());
-}
-
-
-TEST_P(SimplifiedPureOperatorTest, Properties) {
-  SimplifiedOperatorBuilder simplified(zone());
-  const PureOperator& pop = GetParam();
-  const Operator* op = (simplified.*pop.constructor)();
-  EXPECT_EQ(pop.properties, op->properties() & pop.properties);
-}
-
-INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest, SimplifiedPureOperatorTest,
-                        ::testing::ValuesIn(kPureOperators));
-
-
-// -----------------------------------------------------------------------------
-// Element access operators.
-
-namespace {
-
-const ElementAccess kElementAccesses[] = {
-    {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), kMachAnyTagged},
-    {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
-     kMachInt8},
-    {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
-     kMachInt16},
-    {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
-     kMachInt32},
-    {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
-     kMachUint8},
-    {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
-     kMachUint16},
-    {kUntaggedBase, kNonHeapObjectHeaderSize - kHeapObjectTag, Type::Any(),
-     kMachUint32},
-    {kUntaggedBase, 0, Type::Signed32(), kMachInt8},
-    {kUntaggedBase, 0, Type::Unsigned32(), kMachUint8},
-    {kUntaggedBase, 0, Type::Signed32(), kMachInt16},
-    {kUntaggedBase, 0, Type::Unsigned32(), kMachUint16},
-    {kUntaggedBase, 0, Type::Signed32(), kMachInt32},
-    {kUntaggedBase, 0, Type::Unsigned32(), kMachUint32},
-    {kUntaggedBase, 0, Type::Number(), kRepFloat32},
-    {kUntaggedBase, 0, Type::Number(), kRepFloat64},
-    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
-     kMachInt8},
-    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
-     kMachUint8},
-    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
-     kMachInt16},
-    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
-     kMachUint16},
-    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
-     kMachInt32},
-    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
-     kMachUint32},
-    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
-     kRepFloat32},
-    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
-     kRepFloat64}};
-
-}  // namespace
-
-
-class SimplifiedElementAccessOperatorTest
-    : public TestWithZone,
-      public ::testing::WithParamInterface<ElementAccess> {};
-
-
-TEST_P(SimplifiedElementAccessOperatorTest, LoadElement) {
-  SimplifiedOperatorBuilder simplified(zone());
-  const ElementAccess& access = GetParam();
-  const Operator* op = simplified.LoadElement(access);
-
-  EXPECT_EQ(IrOpcode::kLoadElement, op->opcode());
-  EXPECT_EQ(Operator::kNoThrow | Operator::kNoWrite, op->properties());
-  EXPECT_EQ(access, ElementAccessOf(op));
-
-  EXPECT_EQ(3, OperatorProperties::GetValueInputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlInputCount(op));
-  EXPECT_EQ(4, OperatorProperties::GetTotalInputCount(op));
-
-  EXPECT_EQ(1, OperatorProperties::GetValueOutputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
-}
-
-
-TEST_P(SimplifiedElementAccessOperatorTest, StoreElement) {
-  SimplifiedOperatorBuilder simplified(zone());
-  const ElementAccess& access = GetParam();
-  const Operator* op = simplified.StoreElement(access);
-
-  EXPECT_EQ(IrOpcode::kStoreElement, op->opcode());
-  EXPECT_EQ(Operator::kNoRead | Operator::kNoThrow, op->properties());
-  EXPECT_EQ(access, ElementAccessOf(op));
-
-  EXPECT_EQ(4, OperatorProperties::GetValueInputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetEffectInputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetControlInputCount(op));
-  EXPECT_EQ(6, OperatorProperties::GetTotalInputCount(op));
-
-  EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
-  EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
-  EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
-}
-
-
-INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest,
-                        SimplifiedElementAccessOperatorTest,
-                        ::testing::ValuesIn(kElementAccesses));
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/simplified-operator.cc b/src/compiler/simplified-operator.cc
index 642ffc7..9d88d12 100644
--- a/src/compiler/simplified-operator.cc
+++ b/src/compiler/simplified-operator.cc
@@ -13,7 +13,7 @@
 namespace internal {
 namespace compiler {
 
-OStream& operator<<(OStream& os, BaseTaggedness base_taggedness) {
+std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) {
   switch (base_taggedness) {
     case kUntaggedBase:
       return os << "untagged base";
@@ -25,9 +25,99 @@
 }
 
 
+MachineType BufferAccess::machine_type() const {
+  switch (external_array_type_) {
+    case kExternalUint8Array:
+    case kExternalUint8ClampedArray:
+      return kMachUint8;
+    case kExternalInt8Array:
+      return kMachInt8;
+    case kExternalUint16Array:
+      return kMachUint16;
+    case kExternalInt16Array:
+      return kMachInt16;
+    case kExternalUint32Array:
+      return kMachUint32;
+    case kExternalInt32Array:
+      return kMachInt32;
+    case kExternalFloat32Array:
+      return kMachFloat32;
+    case kExternalFloat64Array:
+      return kMachFloat64;
+  }
+  UNREACHABLE();
+  return kMachNone;
+}
+
+
+bool operator==(BufferAccess lhs, BufferAccess rhs) {
+  return lhs.external_array_type() == rhs.external_array_type();
+}
+
+
+bool operator!=(BufferAccess lhs, BufferAccess rhs) { return !(lhs == rhs); }
+
+
+size_t hash_value(BufferAccess access) {
+  return base::hash<ExternalArrayType>()(access.external_array_type());
+}
+
+
+std::ostream& operator<<(std::ostream& os, BufferAccess access) {
+  switch (access.external_array_type()) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+  case kExternal##Type##Array:                          \
+    return os << #Type;
+    TYPED_ARRAYS(TYPED_ARRAY_CASE)
+#undef TYPED_ARRAY_CASE
+  }
+  UNREACHABLE();
+  return os;
+}
+
+
+BufferAccess const BufferAccessOf(const Operator* op) {
+  DCHECK(op->opcode() == IrOpcode::kLoadBuffer ||
+         op->opcode() == IrOpcode::kStoreBuffer);
+  return OpParameter<BufferAccess>(op);
+}
+
+
+bool operator==(FieldAccess const& lhs, FieldAccess const& rhs) {
+  return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset &&
+         lhs.machine_type == rhs.machine_type;
+}
+
+
+bool operator!=(FieldAccess const& lhs, FieldAccess const& rhs) {
+  return !(lhs == rhs);
+}
+
+
+size_t hash_value(FieldAccess const& access) {
+  return base::hash_combine(access.base_is_tagged, access.offset,
+                            access.machine_type);
+}
+
+
+std::ostream& operator<<(std::ostream& os, FieldAccess const& access) {
+  os << "[" << access.base_is_tagged << ", " << access.offset << ", ";
+#ifdef OBJECT_PRINT
+  Handle<Name> name;
+  if (access.name.ToHandle(&name)) {
+    name->Print(os);
+    os << ", ";
+  }
+#endif
+  access.type->PrintTo(os);
+  os << ", " << access.machine_type << "]";
+  return os;
+}
+
+
 bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) {
   return lhs.base_is_tagged == rhs.base_is_tagged &&
-         lhs.header_size == rhs.header_size && lhs.type == rhs.type &&
+         lhs.header_size == rhs.header_size &&
          lhs.machine_type == rhs.machine_type;
 }
 
@@ -37,10 +127,16 @@
 }
 
 
-OStream& operator<<(OStream& os, ElementAccess const& access) {
-  os << "[" << access.base_is_tagged << ", " << access.header_size << ", ";
+size_t hash_value(ElementAccess const& access) {
+  return base::hash_combine(access.base_is_tagged, access.header_size,
+                            access.machine_type);
+}
+
+
+std::ostream& operator<<(std::ostream& os, ElementAccess const& access) {
+  os << access.base_is_tagged << ", " << access.header_size << ", ";
   access.type->PrintTo(os);
-  os << ", " << access.machine_type << "]";
+  os << ", " << access.machine_type;
   return os;
 }
 
@@ -61,41 +157,8 @@
 }
 
 
-// Specialization for static parameters of type {FieldAccess}.
-template <>
-struct StaticParameterTraits<FieldAccess> {
-  static OStream& PrintTo(OStream& os, const FieldAccess& val) {
-    return os << val.offset;
-  }
-  static int HashCode(const FieldAccess& val) {
-    return (val.offset < 16) | (val.machine_type & 0xffff);
-  }
-  static bool Equals(const FieldAccess& lhs, const FieldAccess& rhs) {
-    return lhs.base_is_tagged == rhs.base_is_tagged &&
-           lhs.offset == rhs.offset && lhs.machine_type == rhs.machine_type &&
-           lhs.type->Is(rhs.type);
-  }
-};
-
-
-// Specialization for static parameters of type {ElementAccess}.
-template <>
-struct StaticParameterTraits<ElementAccess> {
-  static OStream& PrintTo(OStream& os, const ElementAccess& access) {
-    return os << access;
-  }
-  static int HashCode(const ElementAccess& access) {
-    return (access.header_size < 16) | (access.machine_type & 0xffff);
-  }
-  static bool Equals(const ElementAccess& lhs, const ElementAccess& rhs) {
-    return lhs.base_is_tagged == rhs.base_is_tagged &&
-           lhs.header_size == rhs.header_size &&
-           lhs.machine_type == rhs.machine_type && lhs.type->Is(rhs.type);
-  }
-};
-
-
 #define PURE_OP_LIST(V)                                \
+  V(AnyToBoolean, Operator::kNoProperties, 1)          \
   V(BooleanNot, Operator::kNoProperties, 1)            \
   V(BooleanToNumber, Operator::kNoProperties, 1)       \
   V(NumberEqual, Operator::kCommutative, 2)            \
@@ -119,56 +182,106 @@
   V(ChangeUint32ToTagged, Operator::kNoProperties, 1)  \
   V(ChangeFloat64ToTagged, Operator::kNoProperties, 1) \
   V(ChangeBoolToBit, Operator::kNoProperties, 1)       \
-  V(ChangeBitToBool, Operator::kNoProperties, 1)
+  V(ChangeBitToBool, Operator::kNoProperties, 1)       \
+  V(ObjectIsSmi, Operator::kNoProperties, 1)           \
+  V(ObjectIsNonNegativeSmi, Operator::kNoProperties, 1)
 
 
-#define ACCESS_OP_LIST(V)                                 \
-  V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1)     \
-  V(StoreField, FieldAccess, Operator::kNoRead, 2, 0)     \
-  V(LoadElement, ElementAccess, Operator::kNoWrite, 3, 1) \
-  V(StoreElement, ElementAccess, Operator::kNoRead, 4, 0)
-
-
-struct SimplifiedOperatorBuilderImpl FINAL {
-#define PURE(Name, properties, input_count)                               \
-  struct Name##Operator FINAL : public SimpleOperator {                   \
-    Name##Operator()                                                      \
-        : SimpleOperator(IrOpcode::k##Name, Operator::kPure | properties, \
-                         input_count, 1, #Name) {}                        \
-  };                                                                      \
+struct SimplifiedOperatorGlobalCache FINAL {
+#define PURE(Name, properties, input_count)                                \
+  struct Name##Operator FINAL : public Operator {                          \
+    Name##Operator()                                                       \
+        : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
+                   input_count, 0, 0, 1, 0, 0) {}                          \
+  };                                                                       \
   Name##Operator k##Name;
   PURE_OP_LIST(PURE)
 #undef PURE
+
+#define BUFFER_ACCESS(Type, type, TYPE, ctype, size)                          \
+  struct LoadBuffer##Type##Operator FINAL : public Operator1<BufferAccess> {  \
+    LoadBuffer##Type##Operator()                                              \
+        : Operator1<BufferAccess>(IrOpcode::kLoadBuffer,                      \
+                                  Operator::kNoThrow | Operator::kNoWrite,    \
+                                  "LoadBuffer", 3, 1, 1, 1, 1, 0,             \
+                                  BufferAccess(kExternal##Type##Array)) {}    \
+  };                                                                          \
+  struct StoreBuffer##Type##Operator FINAL : public Operator1<BufferAccess> { \
+    StoreBuffer##Type##Operator()                                             \
+        : Operator1<BufferAccess>(IrOpcode::kStoreBuffer,                     \
+                                  Operator::kNoRead | Operator::kNoThrow,     \
+                                  "StoreBuffer", 4, 1, 1, 0, 1, 0,            \
+                                  BufferAccess(kExternal##Type##Array)) {}    \
+  };                                                                          \
+  LoadBuffer##Type##Operator kLoadBuffer##Type;                               \
+  StoreBuffer##Type##Operator kStoreBuffer##Type;
+  TYPED_ARRAYS(BUFFER_ACCESS)
+#undef BUFFER_ACCESS
 };
 
 
-static base::LazyInstance<SimplifiedOperatorBuilderImpl>::type kImpl =
+static base::LazyInstance<SimplifiedOperatorGlobalCache>::type kCache =
     LAZY_INSTANCE_INITIALIZER;
 
 
 SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone)
-    : impl_(kImpl.Get()), zone_(zone) {}
+    : cache_(kCache.Get()), zone_(zone) {}
 
 
 #define PURE(Name, properties, input_count) \
-  const Operator* SimplifiedOperatorBuilder::Name() { return &impl_.k##Name; }
+  const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
 PURE_OP_LIST(PURE)
 #undef PURE
 
 
 const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) {
   // TODO(titzer): What about the type parameter?
-  return new (zone()) SimpleOperator(IrOpcode::kReferenceEqual,
-                                     Operator::kCommutative | Operator::kPure,
-                                     2, 1, "ReferenceEqual");
+  return new (zone()) Operator(IrOpcode::kReferenceEqual,
+                               Operator::kCommutative | Operator::kPure,
+                               "ReferenceEqual", 2, 0, 0, 1, 0, 0);
 }
 
 
-#define ACCESS(Name, Type, properties, input_count, output_count)           \
-  const Operator* SimplifiedOperatorBuilder::Name(const Type& access) {     \
-    return new (zone())                                                     \
-        Operator1<Type>(IrOpcode::k##Name, Operator::kNoThrow | properties, \
-                        input_count, output_count, #Name, access);          \
+const Operator* SimplifiedOperatorBuilder::LoadBuffer(BufferAccess access) {
+  switch (access.external_array_type()) {
+#define LOAD_BUFFER(Type, type, TYPE, ctype, size) \
+  case kExternal##Type##Array:                     \
+    return &cache_.kLoadBuffer##Type;
+    TYPED_ARRAYS(LOAD_BUFFER)
+#undef LOAD_BUFFER
+  }
+  UNREACHABLE();
+  return nullptr;
+}
+
+
+const Operator* SimplifiedOperatorBuilder::StoreBuffer(BufferAccess access) {
+  switch (access.external_array_type()) {
+#define STORE_BUFFER(Type, type, TYPE, ctype, size) \
+  case kExternal##Type##Array:                      \
+    return &cache_.kStoreBuffer##Type;
+    TYPED_ARRAYS(STORE_BUFFER)
+#undef STORE_BUFFER
+  }
+  UNREACHABLE();
+  return nullptr;
+}
+
+
+#define ACCESS_OP_LIST(V)                                    \
+  V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1)     \
+  V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0)     \
+  V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \
+  V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0)
+
+
+#define ACCESS(Name, Type, properties, value_input_count, control_input_count, \
+               output_count)                                                   \
+  const Operator* SimplifiedOperatorBuilder::Name(const Type& access) {        \
+    return new (zone())                                                        \
+        Operator1<Type>(IrOpcode::k##Name, Operator::kNoThrow | properties,    \
+                        #Name, value_input_count, 1, control_input_count,      \
+                        output_count, 1, 0, access);                           \
   }
 ACCESS_OP_LIST(ACCESS)
 #undef ACCESS
diff --git a/src/compiler/simplified-operator.h b/src/compiler/simplified-operator.h
index 32f0e8b..22664fa 100644
--- a/src/compiler/simplified-operator.h
+++ b/src/compiler/simplified-operator.h
@@ -5,6 +5,8 @@
 #ifndef V8_COMPILER_SIMPLIFIED_OPERATOR_H_
 #define V8_COMPILER_SIMPLIFIED_OPERATOR_H_
 
+#include <iosfwd>
+
 #include "src/compiler/machine-type.h"
 #include "src/handles.h"
 
@@ -23,12 +25,36 @@
 
 // Forward declarations.
 class Operator;
-struct SimplifiedOperatorBuilderImpl;
+struct SimplifiedOperatorGlobalCache;
 
 
 enum BaseTaggedness { kUntaggedBase, kTaggedBase };
 
-OStream& operator<<(OStream&, BaseTaggedness);
+std::ostream& operator<<(std::ostream&, BaseTaggedness);
+
+
+// An access descriptor for loads/stores of array buffers.
+class BufferAccess FINAL {
+ public:
+  explicit BufferAccess(ExternalArrayType external_array_type)
+      : external_array_type_(external_array_type) {}
+
+  ExternalArrayType external_array_type() const { return external_array_type_; }
+  MachineType machine_type() const;
+
+ private:
+  ExternalArrayType const external_array_type_;
+};
+
+bool operator==(BufferAccess, BufferAccess);
+bool operator!=(BufferAccess, BufferAccess);
+
+size_t hash_value(BufferAccess);
+
+std::ostream& operator<<(std::ostream&, BufferAccess);
+
+BufferAccess const BufferAccessOf(const Operator* op) WARN_UNUSED_RESULT;
+
 
 // An access descriptor for loads/stores of fixed structures like field
 // accesses of heap objects. Accesses from either tagged or untagged base
@@ -36,13 +62,22 @@
 struct FieldAccess {
   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
   int offset;                     // offset of the field, without tag.
-  Handle<Name> name;              // debugging only.
+  MaybeHandle<Name> name;         // debugging only.
   Type* type;                     // type of the field.
   MachineType machine_type;       // machine type of the field.
 
   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
 };
 
+bool operator==(FieldAccess const&, FieldAccess const&);
+bool operator!=(FieldAccess const&, FieldAccess const&);
+
+size_t hash_value(FieldAccess const&);
+
+std::ostream& operator<<(std::ostream&, FieldAccess const&);
+
+FieldAccess const& FieldAccessOf(const Operator* op) WARN_UNUSED_RESULT;
+
 
 // An access descriptor for loads/stores of indexed structures like characters
 // in strings or off-heap backing stores. Accesses from either tagged or
@@ -57,18 +92,14 @@
   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
 };
 
-bool operator==(ElementAccess const& lhs, ElementAccess const& rhs);
-bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs);
+bool operator==(ElementAccess const&, ElementAccess const&);
+bool operator!=(ElementAccess const&, ElementAccess const&);
 
-OStream& operator<<(OStream&, ElementAccess const&);
+size_t hash_value(ElementAccess const&);
 
+std::ostream& operator<<(std::ostream&, ElementAccess const&);
 
-// If the accessed object is not a heap object, add this to the header_size.
-static const int kNonHeapObjectHeaderSize = kHeapObjectTag;
-
-
-const FieldAccess& FieldAccessOf(const Operator* op) WARN_UNUSED_RESULT;
-const ElementAccess& ElementAccessOf(const Operator* op) WARN_UNUSED_RESULT;
+ElementAccess const& ElementAccessOf(const Operator* op) WARN_UNUSED_RESULT;
 
 
 // Interface for building simplified operators, which represent the
@@ -97,6 +128,8 @@
  public:
   explicit SimplifiedOperatorBuilder(Zone* zone);
 
+  const Operator* AnyToBoolean();
+
   const Operator* BooleanNot();
   const Operator* BooleanToNumber();
 
@@ -127,8 +160,17 @@
   const Operator* ChangeBoolToBit();
   const Operator* ChangeBitToBool();
 
-  const Operator* LoadField(const FieldAccess&);
-  const Operator* StoreField(const FieldAccess&);
+  const Operator* ObjectIsSmi();
+  const Operator* ObjectIsNonNegativeSmi();
+
+  const Operator* LoadField(FieldAccess const&);
+  const Operator* StoreField(FieldAccess const&);
+
+  // load-buffer buffer, offset, length
+  const Operator* LoadBuffer(BufferAccess);
+
+  // store-buffer buffer, offset, length, value
+  const Operator* StoreBuffer(BufferAccess);
 
   // load-element [base + index], length
   const Operator* LoadElement(ElementAccess const&);
@@ -139,7 +181,7 @@
  private:
   Zone* zone() const { return zone_; }
 
-  const SimplifiedOperatorBuilderImpl& impl_;
+  const SimplifiedOperatorGlobalCache& cache_;
   Zone* const zone_;
 
   DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorBuilder);
diff --git a/src/compiler/source-position.cc b/src/compiler/source-position.cc
index 1178390..9e21ae4 100644
--- a/src/compiler/source-position.cc
+++ b/src/compiler/source-position.cc
@@ -10,12 +10,12 @@
 namespace internal {
 namespace compiler {
 
-class SourcePositionTable::Decorator : public GraphDecorator {
+class SourcePositionTable::Decorator FINAL : public GraphDecorator {
  public:
   explicit Decorator(SourcePositionTable* source_positions)
       : source_positions_(source_positions) {}
 
-  virtual void Decorate(Node* node) {
+  void Decorate(Node* node) FINAL {
     DCHECK(!source_positions_->current_position_.IsInvalid());
     source_positions_->table_.Set(node, source_positions_->current_position_);
   }
@@ -46,7 +46,7 @@
 }
 
 
-SourcePosition SourcePositionTable::GetSourcePosition(Node* node) {
+SourcePosition SourcePositionTable::GetSourcePosition(Node* node) const {
   return table_.Get(node);
 }
 
diff --git a/src/compiler/source-position.h b/src/compiler/source-position.h
index 778f067..390a17d 100644
--- a/src/compiler/source-position.h
+++ b/src/compiler/source-position.h
@@ -79,7 +79,7 @@
   void AddDecorator();
   void RemoveDecorator();
 
-  SourcePosition GetSourcePosition(Node* node);
+  SourcePosition GetSourcePosition(Node* node) const;
 
  private:
   class Decorator;
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index bfecdef..137829e 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -2,7 +2,9 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/bootstrapper.h"
 #include "src/compiler/graph-inl.h"
+#include "src/compiler/graph-reducer.h"
 #include "src/compiler/js-operator.h"
 #include "src/compiler/node.h"
 #include "src/compiler/node-properties-inl.h"
@@ -14,64 +16,270 @@
 namespace internal {
 namespace compiler {
 
-Typer::Typer(Zone* zone) : zone_(zone) {
-  Type* number = Type::Number(zone);
-  Type* signed32 = Type::Signed32(zone);
-  Type* unsigned32 = Type::Unsigned32(zone);
-  Type* integral32 = Type::Integral32(zone);
-  Type* object = Type::Object(zone);
-  Type* undefined = Type::Undefined(zone);
+#define NATIVE_TYPES(V) \
+  V(Int8)               \
+  V(Uint8)              \
+  V(Int16)              \
+  V(Uint16)             \
+  V(Int32)              \
+  V(Uint32)             \
+  V(Float32)            \
+  V(Float64)
+
+enum LazyCachedType {
+  kNumberFunc0,
+  kNumberFunc1,
+  kNumberFunc2,
+  kImulFunc,
+  kClz32Func,
+  kArrayBufferFunc,
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+  k##Type, k##Type##Array, k##Type##ArrayFunc,
+  TYPED_ARRAYS(TYPED_ARRAY_CASE)
+#undef TYPED_ARRAY_CASE
+      kNumLazyCachedTypes
+};
+
+
+// Constructs and caches types lazily.
+// TODO(turbofan): these types could be globally cached or cached per isolate.
+class LazyTypeCache FINAL : public ZoneObject {
+ public:
+  explicit LazyTypeCache(Zone* zone) : zone_(zone) {
+    memset(cache_, 0, sizeof(cache_));
+  }
+
+  inline Type* Get(LazyCachedType type) {
+    int index = static_cast<int>(type);
+    DCHECK(index < kNumLazyCachedTypes);
+    if (cache_[index] == NULL) cache_[index] = Create(type);
+    return cache_[index];
+  }
+
+ private:
+  Type* Create(LazyCachedType type) {
+    switch (type) {
+      case kInt8:
+        return CreateNative(CreateRange<int8_t>(), Type::UntaggedSigned8());
+      case kUint8:
+        return CreateNative(CreateRange<uint8_t>(), Type::UntaggedUnsigned8());
+      case kInt16:
+        return CreateNative(CreateRange<int16_t>(), Type::UntaggedSigned16());
+      case kUint16:
+        return CreateNative(CreateRange<uint16_t>(),
+                            Type::UntaggedUnsigned16());
+      case kInt32:
+        return CreateNative(Type::Signed32(), Type::UntaggedSigned32());
+      case kUint32:
+        return CreateNative(Type::Unsigned32(), Type::UntaggedUnsigned32());
+      case kFloat32:
+        return CreateNative(Type::Number(), Type::UntaggedFloat32());
+      case kFloat64:
+        return CreateNative(Type::Number(), Type::UntaggedFloat64());
+      case kUint8Clamped:
+        return Get(kUint8);
+      case kNumberFunc0:
+        return Type::Function(Type::Number(), zone());
+      case kNumberFunc1:
+        return Type::Function(Type::Number(), Type::Number(), zone());
+      case kNumberFunc2:
+        return Type::Function(Type::Number(), Type::Number(), Type::Number(),
+                              zone());
+      case kImulFunc:
+        return Type::Function(Type::Signed32(), Type::Integral32(),
+                              Type::Integral32(), zone());
+      case kClz32Func:
+        return Type::Function(CreateRange(0, 32), Type::Number(), zone());
+      case kArrayBufferFunc:
+        return Type::Function(Type::Object(zone()), Type::Unsigned32(), zone());
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+  case k##Type##Array:                                  \
+    return CreateArray(Get(k##Type));                   \
+  case k##Type##ArrayFunc:                              \
+    return CreateArrayFunction(Get(k##Type##Array));
+        TYPED_ARRAYS(TYPED_ARRAY_CASE)
+#undef TYPED_ARRAY_CASE
+      case kNumLazyCachedTypes:
+        break;
+    }
+    UNREACHABLE();
+    return NULL;
+  }
+
+  Type* CreateArray(Type* element) const {
+    return Type::Array(element, zone());
+  }
+
+  Type* CreateArrayFunction(Type* array) const {
+    Type* arg1 = Type::Union(Type::Unsigned32(), Type::Object(), zone());
+    Type* arg2 = Type::Union(Type::Unsigned32(), Type::Undefined(), zone());
+    Type* arg3 = arg2;
+    return Type::Function(array, arg1, arg2, arg3, zone());
+  }
+
+  Type* CreateNative(Type* semantic, Type* representation) const {
+    return Type::Intersect(semantic, representation, zone());
+  }
+
+  template <typename T>
+  Type* CreateRange() const {
+    return CreateRange(std::numeric_limits<T>::min(),
+                       std::numeric_limits<T>::max());
+  }
+
+  Type* CreateRange(double min, double max) const {
+    return Type::Range(factory()->NewNumber(min), factory()->NewNumber(max),
+                       zone());
+  }
+
+  Factory* factory() const { return isolate()->factory(); }
+  Isolate* isolate() const { return zone()->isolate(); }
+  Zone* zone() const { return zone_; }
+
+  Type* cache_[kNumLazyCachedTypes];
+  Zone* zone_;
+};
+
+
+class Typer::Decorator FINAL : public GraphDecorator {
+ public:
+  explicit Decorator(Typer* typer) : typer_(typer) {}
+  void Decorate(Node* node) FINAL;
+
+ private:
+  Typer* typer_;
+};
+
+
+Typer::Typer(Graph* graph, MaybeHandle<Context> context)
+    : graph_(graph),
+      context_(context),
+      decorator_(NULL),
+      cache_(new (graph->zone()) LazyTypeCache(graph->zone())),
+      weaken_min_limits_(graph->zone()),
+      weaken_max_limits_(graph->zone()) {
+  Zone* zone = this->zone();
+  Factory* f = zone->isolate()->factory();
+
+  Handle<Object> zero = f->NewNumber(0);
+  Handle<Object> one = f->NewNumber(1);
+  Handle<Object> infinity = f->NewNumber(+V8_INFINITY);
+  Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY);
+
+  Type* number = Type::Number();
+  Type* signed32 = Type::Signed32();
+  Type* unsigned32 = Type::Unsigned32();
+  Type* nan_or_minuszero = Type::Union(Type::NaN(), Type::MinusZero(), zone);
+  Type* truncating_to_zero =
+      Type::Union(Type::Union(Type::Constant(infinity, zone),
+                              Type::Constant(minusinfinity, zone), zone),
+                  nan_or_minuszero, zone);
+
+  boolean_or_number = Type::Union(Type::Boolean(), Type::Number(), zone);
+  undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone);
+  undefined_or_number = Type::Union(Type::Undefined(), Type::Number(), zone);
+  singleton_false = Type::Constant(f->false_value(), zone);
+  singleton_true = Type::Constant(f->true_value(), zone);
+  singleton_zero = Type::Range(zero, zero, zone);
+  singleton_one = Type::Range(one, one, zone);
+  zero_or_one = Type::Union(singleton_zero, singleton_one, zone);
+  zeroish = Type::Union(singleton_zero, nan_or_minuszero, zone);
+  signed32ish = Type::Union(signed32, truncating_to_zero, zone);
+  unsigned32ish = Type::Union(unsigned32, truncating_to_zero, zone);
+  falsish = Type::Union(Type::Undetectable(),
+                        Type::Union(Type::Union(singleton_false, zeroish, zone),
+                                    undefined_or_null, zone),
+                        zone);
+  truish = Type::Union(
+      singleton_true,
+      Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone);
+  integer = Type::Range(minusinfinity, infinity, zone);
+  weakint = Type::Union(integer, nan_or_minuszero, zone);
+
   number_fun0_ = Type::Function(number, zone);
   number_fun1_ = Type::Function(number, number, zone);
   number_fun2_ = Type::Function(number, number, number, zone);
-  imul_fun_ = Type::Function(signed32, integral32, integral32, zone);
 
-#define NATIVE_TYPE(sem, rep) \
-  Type::Intersect(Type::sem(zone), Type::rep(zone), zone)
-  // TODO(rossberg): Use range types for more precision, once we have them.
-  Type* int8 = NATIVE_TYPE(SignedSmall, UntaggedInt8);
-  Type* int16 = NATIVE_TYPE(SignedSmall, UntaggedInt16);
-  Type* int32 = NATIVE_TYPE(Signed32, UntaggedInt32);
-  Type* uint8 = NATIVE_TYPE(UnsignedSmall, UntaggedInt8);
-  Type* uint16 = NATIVE_TYPE(UnsignedSmall, UntaggedInt16);
-  Type* uint32 = NATIVE_TYPE(Unsigned32, UntaggedInt32);
-  Type* float32 = NATIVE_TYPE(Number, UntaggedFloat32);
-  Type* float64 = NATIVE_TYPE(Number, UntaggedFloat64);
-#undef NATIVE_TYPE
-  Type* buffer = Type::Buffer(zone);
-  Type* int8_array = Type::Array(int8, zone);
-  Type* int16_array = Type::Array(int16, zone);
-  Type* int32_array = Type::Array(int32, zone);
-  Type* uint8_array = Type::Array(uint8, zone);
-  Type* uint16_array = Type::Array(uint16, zone);
-  Type* uint32_array = Type::Array(uint32, zone);
-  Type* float32_array = Type::Array(float32, zone);
-  Type* float64_array = Type::Array(float64, zone);
-  Type* arg1 = Type::Union(unsigned32, object, zone);
-  Type* arg2 = Type::Union(unsigned32, undefined, zone);
-  Type* arg3 = arg2;
-  array_buffer_fun_ = Type::Function(buffer, unsigned32, zone);
-  int8_array_fun_ = Type::Function(int8_array, arg1, arg2, arg3, zone);
-  int16_array_fun_ = Type::Function(int16_array, arg1, arg2, arg3, zone);
-  int32_array_fun_ = Type::Function(int32_array, arg1, arg2, arg3, zone);
-  uint8_array_fun_ = Type::Function(uint8_array, arg1, arg2, arg3, zone);
-  uint16_array_fun_ = Type::Function(uint16_array, arg1, arg2, arg3, zone);
-  uint32_array_fun_ = Type::Function(uint32_array, arg1, arg2, arg3, zone);
-  float32_array_fun_ = Type::Function(float32_array, arg1, arg2, arg3, zone);
-  float64_array_fun_ = Type::Function(float64_array, arg1, arg2, arg3, zone);
+  weakint_fun1_ = Type::Function(weakint, number, zone);
+  random_fun_ = Type::Function(Type::OrderedNumber(), zone);
+
+  const int limits_count = 20;
+
+  weaken_min_limits_.reserve(limits_count + 1);
+  weaken_max_limits_.reserve(limits_count + 1);
+
+  double limit = 1 << 30;
+  weaken_min_limits_.push_back(f->NewNumber(0));
+  weaken_max_limits_.push_back(f->NewNumber(0));
+  for (int i = 0; i < limits_count; i++) {
+    weaken_min_limits_.push_back(f->NewNumber(-limit));
+    weaken_max_limits_.push_back(f->NewNumber(limit - 1));
+    limit *= 2;
+  }
+
+  decorator_ = new (zone) Decorator(this);
+  graph_->AddDecorator(decorator_);
 }
 
 
-class Typer::Visitor : public NullNodeVisitor {
+Typer::~Typer() {
+  graph_->RemoveDecorator(decorator_);
+}
+
+
+class Typer::Visitor : public Reducer {
  public:
-  Visitor(Typer* typer, MaybeHandle<Context> context)
-      : typer_(typer), context_(context) {}
+  explicit Visitor(Typer* typer) : typer_(typer) {}
+
+  Reduction Reduce(Node* node) OVERRIDE {
+    if (node->op()->ValueOutputCount() == 0) return NoChange();
+    switch (node->opcode()) {
+#define DECLARE_CASE(x) \
+  case IrOpcode::k##x:  \
+    return UpdateBounds(node, TypeBinaryOp(node, x##Typer));
+      JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
+#undef DECLARE_CASE
+
+#define DECLARE_CASE(x) \
+  case IrOpcode::k##x:  \
+    return UpdateBounds(node, Type##x(node));
+      DECLARE_CASE(Start)
+      // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
+      COMMON_OP_LIST(DECLARE_CASE)
+      SIMPLIFIED_OP_LIST(DECLARE_CASE)
+      MACHINE_OP_LIST(DECLARE_CASE)
+      JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
+      JS_OBJECT_OP_LIST(DECLARE_CASE)
+      JS_CONTEXT_OP_LIST(DECLARE_CASE)
+      JS_OTHER_OP_LIST(DECLARE_CASE)
+#undef DECLARE_CASE
+
+#define DECLARE_CASE(x) case IrOpcode::k##x:
+      DECLARE_CASE(End)
+      INNER_CONTROL_OP_LIST(DECLARE_CASE)
+#undef DECLARE_CASE
+      break;
+    }
+    return NoChange();
+  }
 
   Bounds TypeNode(Node* node) {
     switch (node->opcode()) {
+#define DECLARE_CASE(x) \
+      case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
+      JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
+#undef DECLARE_CASE
+
 #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
       DECLARE_CASE(Start)
-      VALUE_OP_LIST(DECLARE_CASE)
+      // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
+      COMMON_OP_LIST(DECLARE_CASE)
+      SIMPLIFIED_OP_LIST(DECLARE_CASE)
+      MACHINE_OP_LIST(DECLARE_CASE)
+      JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
+      JS_OBJECT_OP_LIST(DECLARE_CASE)
+      JS_CONTEXT_OP_LIST(DECLARE_CASE)
+      JS_OTHER_OP_LIST(DECLARE_CASE)
 #undef DECLARE_CASE
 
 #define DECLARE_CASE(x) case IrOpcode::k##x:
@@ -86,142 +294,288 @@
 
   Type* TypeConstant(Handle<Object> value);
 
- protected:
+ private:
+  Typer* typer_;
+  MaybeHandle<Context> context_;
+
 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node);
   DECLARE_METHOD(Start)
   VALUE_OP_LIST(DECLARE_METHOD)
 #undef DECLARE_METHOD
 
-  Bounds OperandType(Node* node, int i) {
-    return NodeProperties::GetBounds(NodeProperties::GetValueInput(node, i));
+  Bounds BoundsOrNone(Node* node) {
+    return NodeProperties::IsTyped(node) ? NodeProperties::GetBounds(node)
+                                         : Bounds(Type::None());
   }
 
-  Type* ContextType(Node* node) {
-    Bounds result =
-        NodeProperties::GetBounds(NodeProperties::GetContextInput(node));
+  Bounds Operand(Node* node, int i) {
+    Node* operand_node = NodeProperties::GetValueInput(node, i);
+    return BoundsOrNone(operand_node);
+  }
+
+  Bounds ContextOperand(Node* node) {
+    Bounds result = BoundsOrNone(NodeProperties::GetContextInput(node));
     DCHECK(result.upper->Maybe(Type::Internal()));
     // TODO(rossberg): More precisely, instead of the above assertion, we should
     // back-propagate the constraint that it has to be a subtype of Internal.
-    return result.upper;
+    return result;
   }
 
+  Type* Weaken(Type* current_type, Type* previous_type);
+
   Zone* zone() { return typer_->zone(); }
   Isolate* isolate() { return typer_->isolate(); }
-  MaybeHandle<Context> context() { return context_; }
+  Graph* graph() { return typer_->graph(); }
+  MaybeHandle<Context> context() { return typer_->context(); }
 
- private:
-  Typer* typer_;
-  MaybeHandle<Context> context_;
+  typedef Type* (*UnaryTyperFun)(Type*, Typer* t);
+  typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t);
+
+  Bounds TypeUnaryOp(Node* node, UnaryTyperFun);
+  Bounds TypeBinaryOp(Node* node, BinaryTyperFun);
+
+  static Type* Invert(Type*, Typer*);
+  static Type* FalsifyUndefined(Type*, Typer*);
+  static Type* Rangify(Type*, Typer*);
+
+  static Type* ToPrimitive(Type*, Typer*);
+  static Type* ToBoolean(Type*, Typer*);
+  static Type* ToNumber(Type*, Typer*);
+  static Type* ToString(Type*, Typer*);
+  static Type* NumberToInt32(Type*, Typer*);
+  static Type* NumberToUint32(Type*, Typer*);
+
+  static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*);
+  static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*);
+  static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*);
+  static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*);
+  static Type* JSModulusRanger(Type::RangeType*, Type::RangeType*, Typer*);
+
+  static Type* JSCompareTyper(Type*, Type*, Typer*);
+
+#define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*);
+  JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
+#undef DECLARE_METHOD
+
+  static Type* JSUnaryNotTyper(Type*, Typer*);
+  static Type* JSLoadPropertyTyper(Type*, Type*, Typer*);
+  static Type* JSCallFunctionTyper(Type*, Typer*);
+
+  Reduction UpdateBounds(Node* node, Bounds current) {
+    if (NodeProperties::IsTyped(node)) {
+      // Widen the bounds of a previously typed node.
+      Bounds previous = NodeProperties::GetBounds(node);
+      // Speed up termination in the presence of range types:
+      current.upper = Weaken(current.upper, previous.upper);
+      current.lower = Weaken(current.lower, previous.lower);
+
+      // Types should not get less precise.
+      DCHECK(previous.lower->Is(current.lower));
+      DCHECK(previous.upper->Is(current.upper));
+
+      NodeProperties::SetBounds(node, current);
+      if (!(previous.Narrows(current) && current.Narrows(previous))) {
+        // If something changed, revisit all uses.
+        return Changed(node);
+      }
+      return NoChange();
+    } else {
+      // No previous type, simply update the bounds.
+      NodeProperties::SetBounds(node, current);
+      return Changed(node);
+    }
+  }
 };
 
 
-class Typer::RunVisitor : public Typer::Visitor {
- public:
-  RunVisitor(Typer* typer, MaybeHandle<Context> context)
-      : Visitor(typer, context),
-        redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {}
-
-  GenericGraphVisit::Control Post(Node* node) {
-    if (OperatorProperties::HasValueOutput(node->op())) {
-      Bounds bounds = TypeNode(node);
-      NodeProperties::SetBounds(node, bounds);
-      // Remember incompletely typed nodes for least fixpoint iteration.
-      int arity = OperatorProperties::GetValueInputCount(node->op());
-      for (int i = 0; i < arity; ++i) {
-        // TODO(rossberg): change once IsTyped is available.
-        // if (!NodeProperties::IsTyped(NodeProperties::GetValueInput(node, i)))
-        if (OperandType(node, i).upper->Is(Type::None())) {
-          redo.insert(node);
-          break;
+void Typer::Run() {
+  {
+    // TODO(titzer): this is a hack. Reset types for interior nodes first.
+    NodeDeque deque(zone());
+    NodeMarker<bool> marked(graph(), 2);
+    deque.push_front(graph()->end());
+    marked.Set(graph()->end(), true);
+    while (!deque.empty()) {
+      Node* node = deque.front();
+      deque.pop_front();
+      // TODO(titzer): there shouldn't be a need to retype constants.
+      if (node->op()->ValueOutputCount() > 0)
+        NodeProperties::RemoveBounds(node);
+      for (Node* input : node->inputs()) {
+        if (!marked.Get(input)) {
+          marked.Set(input, true);
+          deque.push_back(input);
         }
       }
     }
-    return GenericGraphVisit::CONTINUE;
   }
 
-  NodeSet redo;
-};
+  Visitor visitor(this);
+  GraphReducer graph_reducer(graph(), zone());
+  graph_reducer.AddReducer(&visitor);
+  graph_reducer.ReduceGraph();
+}
 
 
-class Typer::NarrowVisitor : public Typer::Visitor {
- public:
-  NarrowVisitor(Typer* typer, MaybeHandle<Context> context)
-      : Visitor(typer, context) {}
-
-  GenericGraphVisit::Control Pre(Node* node) {
-    if (OperatorProperties::HasValueOutput(node->op())) {
-      Bounds previous = NodeProperties::GetBounds(node);
-      Bounds bounds = TypeNode(node);
-      NodeProperties::SetBounds(node, Bounds::Both(bounds, previous, zone()));
-      DCHECK(bounds.Narrows(previous));
-      // Stop when nothing changed (but allow re-entry in case it does later).
-      return previous.Narrows(bounds)
-          ? GenericGraphVisit::DEFER : GenericGraphVisit::REENTER;
-    } else {
-      return GenericGraphVisit::SKIP;
+void Typer::Decorator::Decorate(Node* node) {
+  if (node->op()->ValueOutputCount() > 0) {
+    // Only eagerly type-decorate nodes with known input types.
+    // Other cases will generally require a proper fixpoint iteration with Run.
+    bool is_typed = NodeProperties::IsTyped(node);
+    if (is_typed || NodeProperties::AllValueInputsAreTyped(node)) {
+      Visitor typing(typer_);
+      Bounds bounds = typing.TypeNode(node);
+      if (is_typed) {
+        bounds =
+          Bounds::Both(bounds, NodeProperties::GetBounds(node), typer_->zone());
+      }
+      NodeProperties::SetBounds(node, bounds);
     }
   }
-
-  GenericGraphVisit::Control Post(Node* node) {
-    return GenericGraphVisit::REENTER;
-  }
-};
-
-
-class Typer::WidenVisitor : public Typer::Visitor {
- public:
-  WidenVisitor(Typer* typer, MaybeHandle<Context> context)
-      : Visitor(typer, context) {}
-
-  GenericGraphVisit::Control Pre(Node* node) {
-    if (OperatorProperties::HasValueOutput(node->op())) {
-      Bounds previous = NodeProperties::GetBounds(node);
-      Bounds bounds = TypeNode(node);
-      DCHECK(previous.lower->Is(bounds.lower));
-      DCHECK(previous.upper->Is(bounds.upper));
-      NodeProperties::SetBounds(node, bounds);  // TODO(rossberg): Either?
-      // Stop when nothing changed (but allow re-entry in case it does later).
-      return bounds.Narrows(previous)
-          ? GenericGraphVisit::DEFER : GenericGraphVisit::REENTER;
-    } else {
-      return GenericGraphVisit::SKIP;
-    }
-  }
-
-  GenericGraphVisit::Control Post(Node* node) {
-    return GenericGraphVisit::REENTER;
-  }
-};
-
-
-void Typer::Run(Graph* graph, MaybeHandle<Context> context) {
-  RunVisitor typing(this, context);
-  graph->VisitNodeInputsFromEnd(&typing);
-  // Find least fixpoint.
-  for (NodeSetIter i = typing.redo.begin(); i != typing.redo.end(); ++i) {
-    Widen(graph, *i, context);
-  }
 }
 
 
-void Typer::Narrow(Graph* graph, Node* start, MaybeHandle<Context> context) {
-  NarrowVisitor typing(this, context);
-  graph->VisitNodeUsesFrom(start, &typing);
+// -----------------------------------------------------------------------------
+
+// Helper functions that lift a function f on types to a function on bounds,
+// and uses that to type the given node.  Note that f is never called with None
+// as an argument.
+
+
+Bounds Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
+  Bounds input = Operand(node, 0);
+  Type* upper = input.upper->Is(Type::None())
+      ? Type::None()
+      : f(input.upper, typer_);
+  Type* lower = input.lower->Is(Type::None())
+      ? Type::None()
+      : (input.lower == input.upper || upper->IsConstant())
+      ? upper  // TODO(neis): Extend this to Range(x,x), NaN, MinusZero, ...?
+      : f(input.lower, typer_);
+  // TODO(neis): Figure out what to do with lower bound.
+  return Bounds(lower, upper);
 }
 
 
-void Typer::Widen(Graph* graph, Node* start, MaybeHandle<Context> context) {
-  WidenVisitor typing(this, context);
-  graph->VisitNodeUsesFrom(start, &typing);
+Bounds Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
+  Bounds left = Operand(node, 0);
+  Bounds right = Operand(node, 1);
+  Type* upper = left.upper->Is(Type::None()) || right.upper->Is(Type::None())
+      ? Type::None()
+      : f(left.upper, right.upper, typer_);
+  Type* lower = left.lower->Is(Type::None()) || right.lower->Is(Type::None())
+      ? Type::None()
+      : ((left.lower == left.upper && right.lower == right.upper) ||
+         upper->IsConstant())
+      ? upper
+      : f(left.lower, right.lower, typer_);
+  // TODO(neis): Figure out what to do with lower bound.
+  return Bounds(lower, upper);
 }
 
 
-void Typer::Init(Node* node) {
-  if (OperatorProperties::HasValueOutput(node->op())) {
-    Visitor typing(this, MaybeHandle<Context>());
-    Bounds bounds = typing.TypeNode(node);
-    NodeProperties::SetBounds(node, bounds);
+Type* Typer::Visitor::Invert(Type* type, Typer* t) {
+  if (type->Is(t->singleton_false)) return t->singleton_true;
+  if (type->Is(t->singleton_true)) return t->singleton_false;
+  return type;
+}
+
+
+Type* Typer::Visitor::FalsifyUndefined(Type* type, Typer* t) {
+  if (type->Is(Type::Undefined())) return t->singleton_false;
+  return type;
+}
+
+
+Type* Typer::Visitor::Rangify(Type* type, Typer* t) {
+  if (type->IsRange()) return type;        // Shortcut.
+  if (!type->Is(t->integer) && !type->Is(Type::Integral32())) {
+    return type;  // Give up on non-integer types.
   }
+  double min = type->Min();
+  double max = type->Max();
+  // Handle the degenerate case of empty bitset types (such as
+  // OtherUnsigned31 and OtherSigned32 on 64-bit architectures).
+  if (std::isnan(min)) {
+    DCHECK(std::isnan(max));
+    return type;
+  }
+  Factory* f = t->isolate()->factory();
+  return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
+}
+
+
+// Type conversion.
+
+
+Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) {
+  if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
+    return type;
+  }
+  return Type::Primitive();
+}
+
+
+Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) {
+  if (type->Is(Type::Boolean())) return type;
+  if (type->Is(t->falsish)) return t->singleton_false;
+  if (type->Is(t->truish)) return t->singleton_true;
+  if (type->Is(Type::PlainNumber()) && (type->Max() < 0 || 0 < type->Min())) {
+    return t->singleton_true;  // Ruled out nan, -0 and +0.
+  }
+  return Type::Boolean();
+}
+
+
+Type* Typer::Visitor::ToNumber(Type* type, Typer* t) {
+  if (type->Is(Type::Number())) return type;
+  if (type->Is(Type::Null())) return t->singleton_zero;
+  if (type->Is(Type::Undefined())) return Type::NaN();
+  if (type->Is(t->undefined_or_null)) {
+    return Type::Union(Type::NaN(), t->singleton_zero, t->zone());
+  }
+  if (type->Is(t->undefined_or_number)) {
+    return Type::Union(Type::Intersect(type, Type::Number(), t->zone()),
+                       Type::NaN(), t->zone());
+  }
+  if (type->Is(t->singleton_false)) return t->singleton_zero;
+  if (type->Is(t->singleton_true)) return t->singleton_one;
+  if (type->Is(Type::Boolean())) return t->zero_or_one;
+  if (type->Is(t->boolean_or_number)) {
+    return Type::Union(Type::Intersect(type, Type::Number(), t->zone()),
+                       t->zero_or_one, t->zone());
+  }
+  return Type::Number();
+}
+
+
+Type* Typer::Visitor::ToString(Type* type, Typer* t) {
+  if (type->Is(Type::String())) return type;
+  return Type::String();
+}
+
+
+Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) {
+  // TODO(neis): DCHECK(type->Is(Type::Number()));
+  if (type->Is(Type::Signed32())) return type;
+  if (type->Is(t->zeroish)) return t->singleton_zero;
+  if (type->Is(t->signed32ish)) {
+    return Type::Intersect(Type::Union(type, t->singleton_zero, t->zone()),
+                           Type::Signed32(), t->zone());
+  }
+  return Type::Signed32();
+}
+
+
+Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) {
+  // TODO(neis): DCHECK(type->Is(Type::Number()));
+  if (type->Is(Type::Unsigned32())) return type;
+  if (type->Is(t->zeroish)) return t->singleton_zero;
+  if (type->Is(t->unsigned32ish)) {
+    return Type::Intersect(Type::Union(type, t->singleton_zero, t->zone()),
+                           Type::Unsigned32(), t->zone());
+  }
+  return Type::Unsigned32();
 }
 
 
@@ -230,64 +584,75 @@
 
 // Control operators.
 
+
 Bounds Typer::Visitor::TypeStart(Node* node) {
-  return Bounds(Type::Internal(zone()));
+  return Bounds(Type::None(zone()), Type::Internal(zone()));
 }
 
 
 // Common operators.
 
+
 Bounds Typer::Visitor::TypeParameter(Node* node) {
   return Bounds::Unbounded(zone());
 }
 
 
 Bounds Typer::Visitor::TypeInt32Constant(Node* node) {
-  // TODO(titzer): only call Type::Of() if the type is not already known.
-  return Bounds(Type::Of(OpParameter<int32_t>(node), zone()));
+  Factory* f = isolate()->factory();
+  Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node));
+  return Bounds(Type::Intersect(
+      Type::Range(number, number, zone()), Type::UntaggedSigned32(), zone()));
 }
 
 
 Bounds Typer::Visitor::TypeInt64Constant(Node* node) {
-  // TODO(titzer): only call Type::Of() if the type is not already known.
-  return Bounds(
-      Type::Of(static_cast<double>(OpParameter<int64_t>(node)), zone()));
+  // TODO(rossberg): This actually seems to be a PointerConstant so far...
+  return Bounds(Type::Internal());  // TODO(rossberg): Add int64 bitset type?
 }
 
 
 Bounds Typer::Visitor::TypeFloat32Constant(Node* node) {
-  // TODO(titzer): only call Type::Of() if the type is not already known.
-  return Bounds(Type::Of(OpParameter<float>(node), zone()));
+  return Bounds(Type::Intersect(
+      Type::Of(OpParameter<float>(node), zone()),
+      Type::UntaggedFloat32(), zone()));
 }
 
 
 Bounds Typer::Visitor::TypeFloat64Constant(Node* node) {
-  // TODO(titzer): only call Type::Of() if the type is not already known.
-  return Bounds(Type::Of(OpParameter<double>(node), zone()));
+  return Bounds(Type::Intersect(
+      Type::Of(OpParameter<double>(node), zone()),
+      Type::UntaggedFloat64(), zone()));
 }
 
 
 Bounds Typer::Visitor::TypeNumberConstant(Node* node) {
-  // TODO(titzer): only call Type::Of() if the type is not already known.
-  return Bounds(Type::Of(OpParameter<double>(node), zone()));
+  Factory* f = isolate()->factory();
+  return Bounds(Type::Constant(
+      f->NewNumber(OpParameter<double>(node)), zone()));
 }
 
 
 Bounds Typer::Visitor::TypeHeapConstant(Node* node) {
-  return Bounds(TypeConstant(OpParameter<Unique<Object> >(node).handle()));
+  return Bounds(TypeConstant(OpParameter<Unique<HeapObject> >(node).handle()));
 }
 
 
 Bounds Typer::Visitor::TypeExternalConstant(Node* node) {
-  return Bounds(Type::Internal(zone()));
+  return Bounds(Type::None(zone()), Type::Internal(zone()));
+}
+
+
+Bounds Typer::Visitor::TypeSelect(Node* node) {
+  return Bounds::Either(Operand(node, 1), Operand(node, 2), zone());
 }
 
 
 Bounds Typer::Visitor::TypePhi(Node* node) {
-  int arity = OperatorProperties::GetValueInputCount(node->op());
-  Bounds bounds = OperandType(node, 0);
+  int arity = node->op()->ValueInputCount();
+  Bounds bounds = Operand(node, 0);
   for (int i = 1; i < arity; ++i) {
-    bounds = Bounds::Either(bounds, OperandType(node, i), zone());
+    bounds = Bounds::Either(bounds, Operand(node, i), zone());
   }
   return bounds;
 }
@@ -299,12 +664,6 @@
 }
 
 
-Bounds Typer::Visitor::TypeControlEffect(Node* node) {
-  UNREACHABLE();
-  return Bounds();
-}
-
-
 Bounds Typer::Visitor::TypeValueEffect(Node* node) {
   UNREACHABLE();
   return Bounds();
@@ -312,18 +671,18 @@
 
 
 Bounds Typer::Visitor::TypeFinish(Node* node) {
-  return OperandType(node, 0);
+  return Operand(node, 0);
 }
 
 
 Bounds Typer::Visitor::TypeFrameState(Node* node) {
   // TODO(rossberg): Ideally FrameState wouldn't have a value output.
-  return Bounds(Type::Internal(zone()));
+  return Bounds(Type::None(zone()), Type::Internal(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeStateValues(Node* node) {
-  return Bounds(Type::Internal(zone()));
+  return Bounds(Type::None(zone()), Type::Internal(zone()));
 }
 
 
@@ -340,159 +699,541 @@
 
 // JS comparison operators.
 
-#define DEFINE_METHOD(x)                       \
-  Bounds Typer::Visitor::Type##x(Node* node) { \
-    return Bounds(Type::Boolean(zone()));      \
+
+Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) {
+  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false;
+  if (lhs->Is(t->undefined_or_null) && rhs->Is(t->undefined_or_null)) {
+    return t->singleton_true;
   }
-JS_COMPARE_BINOP_LIST(DEFINE_METHOD)
-#undef DEFINE_METHOD
+  if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
+      (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
+      return t->singleton_false;
+  }
+  if (lhs->IsConstant() && rhs->Is(lhs)) {
+    // Types are equal and are inhabited only by a single semantic value,
+    // which is not nan due to the earlier check.
+    // TODO(neis): Extend this to Range(x,x), MinusZero, ...?
+    return t->singleton_true;
+  }
+  return Type::Boolean();
+}
+
+
+Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) {
+  return Invert(JSEqualTyper(lhs, rhs, t), t);
+}
+
+
+static Type* JSType(Type* type) {
+  if (type->Is(Type::Boolean())) return Type::Boolean();
+  if (type->Is(Type::String())) return Type::String();
+  if (type->Is(Type::Number())) return Type::Number();
+  if (type->Is(Type::Undefined())) return Type::Undefined();
+  if (type->Is(Type::Null())) return Type::Null();
+  if (type->Is(Type::Symbol())) return Type::Symbol();
+  if (type->Is(Type::Receiver())) return Type::Receiver();  // JS "Object"
+  return Type::Any();
+}
+
+
+Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) {
+  if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false;
+  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false;
+  if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
+      (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
+      return t->singleton_false;
+  }
+  if (lhs->IsConstant() && rhs->Is(lhs)) {
+    // Types are equal and are inhabited only by a single semantic value,
+    // which is not nan due to the earlier check.
+    return t->singleton_true;
+  }
+  return Type::Boolean();
+}
+
+
+Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) {
+  return Invert(JSStrictEqualTyper(lhs, rhs, t), t);
+}
+
+
+// The EcmaScript specification defines the four relational comparison operators
+// (<, <=, >=, >) with the help of a single abstract one.  It behaves like <
+// but returns undefined when the inputs cannot be compared.
+// We implement the typing analogously.
+Type* Typer::Visitor::JSCompareTyper(Type* lhs, Type* rhs, Typer* t) {
+  lhs = ToPrimitive(lhs, t);
+  rhs = ToPrimitive(rhs, t);
+  if (lhs->Maybe(Type::String()) && rhs->Maybe(Type::String())) {
+    return Type::Boolean();
+  }
+  lhs = ToNumber(lhs, t);
+  rhs = ToNumber(rhs, t);
+  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::Undefined();
+  if (lhs->IsConstant() && rhs->Is(lhs)) {
+    // Types are equal and are inhabited only by a single semantic value,
+    // which is not NaN due to the previous check.
+    return t->singleton_false;
+  }
+  if (lhs->Min() >= rhs->Max()) return t->singleton_false;
+  if (lhs->Max() < rhs->Min() &&
+      !lhs->Maybe(Type::NaN()) && !rhs->Maybe(Type::NaN())) {
+    return t->singleton_true;
+  }
+  return Type::Boolean();
+}
+
+
+Type* Typer::Visitor::JSLessThanTyper(Type* lhs, Type* rhs, Typer* t) {
+  return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
+}
+
+
+Type* Typer::Visitor::JSGreaterThanTyper(Type* lhs, Type* rhs, Typer* t) {
+  return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
+}
+
+
+Type* Typer::Visitor::JSLessThanOrEqualTyper(Type* lhs, Type* rhs, Typer* t) {
+  return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
+}
+
+
+Type* Typer::Visitor::JSGreaterThanOrEqualTyper(
+    Type* lhs, Type* rhs, Typer* t) {
+  return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
+}
 
 
 // JS bitwise operators.
 
-Bounds Typer::Visitor::TypeJSBitwiseOr(Node* node) {
-  Bounds left = OperandType(node, 0);
-  Bounds right = OperandType(node, 1);
-  Type* upper = Type::Union(left.upper, right.upper, zone());
-  if (!upper->Is(Type::Signed32())) upper = Type::Signed32(zone());
-  Type* lower = Type::Intersect(Type::SignedSmall(zone()), upper, zone());
-  return Bounds(lower, upper);
+
+Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
+  Factory* f = t->isolate()->factory();
+  lhs = NumberToInt32(ToNumber(lhs, t), t);
+  rhs = NumberToInt32(ToNumber(rhs, t), t);
+  double lmin = lhs->Min();
+  double rmin = rhs->Min();
+  double lmax = lhs->Max();
+  double rmax = rhs->Max();
+  // Or-ing any two values results in a value no smaller than their minimum.
+  // Even no smaller than their maximum if both values are non-negative.
+  double min =
+      lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin);
+  double max = Type::Signed32()->Max();
+
+  // Or-ing with 0 is essentially a conversion to int32.
+  if (rmin == 0 && rmax == 0) {
+    min = lmin;
+    max = lmax;
+  }
+  if (lmin == 0 && lmax == 0) {
+    min = rmin;
+    max = rmax;
+  }
+
+  if (lmax < 0 || rmax < 0) {
+    // Or-ing two values of which at least one is negative results in a negative
+    // value.
+    max = std::min(max, -1.0);
+  }
+  return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
+  // TODO(neis): Be precise for singleton inputs, here and elsewhere.
 }
 
 
-Bounds Typer::Visitor::TypeJSBitwiseAnd(Node* node) {
-  Bounds left = OperandType(node, 0);
-  Bounds right = OperandType(node, 1);
-  Type* upper = Type::Union(left.upper, right.upper, zone());
-  if (!upper->Is(Type::Signed32())) upper = Type::Signed32(zone());
-  Type* lower = Type::Intersect(Type::SignedSmall(zone()), upper, zone());
-  return Bounds(lower, upper);
+Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
+  Factory* f = t->isolate()->factory();
+  lhs = NumberToInt32(ToNumber(lhs, t), t);
+  rhs = NumberToInt32(ToNumber(rhs, t), t);
+  double lmin = lhs->Min();
+  double rmin = rhs->Min();
+  double lmax = lhs->Max();
+  double rmax = rhs->Max();
+  double min = Type::Signed32()->Min();
+  // And-ing any two values results in a value no larger than their maximum.
+  // Even no larger than their minimum if both values are non-negative.
+  double max =
+      lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax);
+  // And-ing with a non-negative value x causes the result to be between
+  // zero and x.
+  if (lmin >= 0) {
+    min = 0;
+    max = std::min(max, lmax);
+  }
+  if (rmin >= 0) {
+    min = 0;
+    max = std::min(max, rmax);
+  }
+  return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
 }
 
 
-Bounds Typer::Visitor::TypeJSBitwiseXor(Node* node) {
-  return Bounds(Type::SignedSmall(zone()), Type::Signed32(zone()));
+Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) {
+  lhs = NumberToInt32(ToNumber(lhs, t), t);
+  rhs = NumberToInt32(ToNumber(rhs, t), t);
+  double lmin = lhs->Min();
+  double rmin = rhs->Min();
+  double lmax = lhs->Max();
+  double rmax = rhs->Max();
+  if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) {
+    // Xor-ing negative or non-negative values results in a non-negative value.
+    return Type::NonNegativeSigned32();
+  }
+  if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) {
+    // Xor-ing a negative and a non-negative value results in a negative value.
+    // TODO(jarin) Use a range here.
+    return Type::NegativeSigned32();
+  }
+  return Type::Signed32();
 }
 
 
-Bounds Typer::Visitor::TypeJSShiftLeft(Node* node) {
-  return Bounds(Type::SignedSmall(zone()), Type::Signed32(zone()));
+Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) {
+  return Type::Signed32();
 }
 
 
-Bounds Typer::Visitor::TypeJSShiftRight(Node* node) {
-  return Bounds(Type::SignedSmall(zone()), Type::Signed32(zone()));
+Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
+  lhs = NumberToInt32(ToNumber(lhs, t), t);
+  rhs = NumberToUint32(ToNumber(rhs, t), t);
+  double min = kMinInt;
+  double max = kMaxInt;
+  if (lhs->Min() >= 0) {
+    // Right-shifting a non-negative value cannot make it negative, nor larger.
+    min = std::max(min, 0.0);
+    max = std::min(max, lhs->Max());
+  }
+  if (lhs->Max() < 0) {
+    // Right-shifting a negative value cannot make it non-negative, nor smaller.
+    min = std::max(min, lhs->Min());
+    max = std::min(max, -1.0);
+  }
+  if (rhs->Min() > 0 && rhs->Max() <= 31) {
+    // Right-shifting by a positive value yields a small integer value.
+    double shift_min = kMinInt >> static_cast<int>(rhs->Min());
+    double shift_max = kMaxInt >> static_cast<int>(rhs->Min());
+    min = std::max(min, shift_min);
+    max = std::min(max, shift_max);
+  }
+  // TODO(jarin) Ideally, the following micro-optimization should be performed
+  // by the type constructor.
+  if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) {
+    Factory* f = t->isolate()->factory();
+    return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
+  }
+  return Type::Signed32();
 }
 
 
-Bounds Typer::Visitor::TypeJSShiftRightLogical(Node* node) {
-  return Bounds(Type::UnsignedSmall(zone()), Type::Unsigned32(zone()));
+Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) {
+  lhs = NumberToUint32(ToNumber(lhs, t), t);
+  Factory* f = t->isolate()->factory();
+  // Logical right-shifting any value cannot make it larger.
+  Handle<Object> min = f->NewNumber(0);
+  Handle<Object> max = f->NewNumber(lhs->Max());
+  return Type::Range(min, max, t->zone());
 }
 
 
 // JS arithmetic operators.
 
-Bounds Typer::Visitor::TypeJSAdd(Node* node) {
-  Bounds left = OperandType(node, 0);
-  Bounds right = OperandType(node, 1);
-  Type* lower =
-      left.lower->Is(Type::None()) || right.lower->Is(Type::None()) ?
-          Type::None(zone()) :
-      left.lower->Is(Type::Number()) && right.lower->Is(Type::Number()) ?
-          Type::SignedSmall(zone()) :
-      left.lower->Is(Type::String()) || right.lower->Is(Type::String()) ?
-          Type::String(zone()) : Type::None(zone());
-  Type* upper =
-      left.upper->Is(Type::None()) && right.upper->Is(Type::None()) ?
-          Type::None(zone()) :
-      left.upper->Is(Type::Number()) && right.upper->Is(Type::Number()) ?
-          Type::Number(zone()) :
-      left.upper->Is(Type::String()) || right.upper->Is(Type::String()) ?
-          Type::String(zone()) : Type::NumberOrString(zone());
-  return Bounds(lower, upper);
+
+// Returns the array's least element, ignoring NaN.
+// There must be at least one non-NaN element.
+// Any -0 is converted to 0.
+static double array_min(double a[], size_t n) {
+  DCHECK(n != 0);
+  double x = +V8_INFINITY;
+  for (size_t i = 0; i < n; ++i) {
+    if (!std::isnan(a[i])) {
+      x = std::min(a[i], x);
+    }
+  }
+  DCHECK(!std::isnan(x));
+  return x == 0 ? 0 : x;  // -0 -> 0
 }
 
 
-Bounds Typer::Visitor::TypeJSSubtract(Node* node) {
-  return Bounds(Type::SignedSmall(zone()), Type::Number(zone()));
+// Returns the array's greatest element, ignoring NaN.
+// There must be at least one non-NaN element.
+// Any -0 is converted to 0.
+static double array_max(double a[], size_t n) {
+  DCHECK(n != 0);
+  double x = -V8_INFINITY;
+  for (size_t i = 0; i < n; ++i) {
+    if (!std::isnan(a[i])) {
+      x = std::max(a[i], x);
+    }
+  }
+  DCHECK(!std::isnan(x));
+  return x == 0 ? 0 : x;  // -0 -> 0
 }
 
 
-Bounds Typer::Visitor::TypeJSMultiply(Node* node) {
-  return Bounds(Type::SignedSmall(zone()), Type::Number(zone()));
+Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs,
+                                  Typer* t) {
+  double results[4];
+  results[0] = lhs->Min()->Number() + rhs->Min()->Number();
+  results[1] = lhs->Min()->Number() + rhs->Max()->Number();
+  results[2] = lhs->Max()->Number() + rhs->Min()->Number();
+  results[3] = lhs->Max()->Number() + rhs->Max()->Number();
+  // Since none of the inputs can be -0, the result cannot be -0 either.
+  // However, it can be nan (the sum of two infinities of opposite sign).
+  // On the other hand, if none of the "results" above is nan, then the actual
+  // result cannot be nan either.
+  int nans = 0;
+  for (int i = 0; i < 4; ++i) {
+    if (std::isnan(results[i])) ++nans;
+  }
+  if (nans == 4) return Type::NaN();  // [-inf..-inf] + [inf..inf] or vice versa
+  Factory* f = t->isolate()->factory();
+  Type* range = Type::Range(f->NewNumber(array_min(results, 4)),
+                            f->NewNumber(array_max(results, 4)), t->zone());
+  return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
+  // Examples:
+  //   [-inf, -inf] + [+inf, +inf] = NaN
+  //   [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN
+  //   [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN
+  //   [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN
 }
 
 
-Bounds Typer::Visitor::TypeJSDivide(Node* node) {
-  return Bounds(Type::SignedSmall(zone()), Type::Number(zone()));
+Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
+  lhs = ToPrimitive(lhs, t);
+  rhs = ToPrimitive(rhs, t);
+  if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) {
+    if (lhs->Is(Type::String()) || rhs->Is(Type::String())) {
+      return Type::String();
+    } else {
+      return Type::NumberOrString();
+    }
+  }
+  lhs = Rangify(ToNumber(lhs, t), t);
+  rhs = Rangify(ToNumber(rhs, t), t);
+  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
+  if (lhs->IsRange() && rhs->IsRange()) {
+    return JSAddRanger(lhs->AsRange(), rhs->AsRange(), t);
+  }
+  // TODO(neis): Deal with numeric bitsets here and elsewhere.
+  return Type::Number();
 }
 
 
-Bounds Typer::Visitor::TypeJSModulus(Node* node) {
-  return Bounds(Type::SignedSmall(zone()), Type::Number(zone()));
+Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs,
+                                       Type::RangeType* rhs, Typer* t) {
+  double results[4];
+  results[0] = lhs->Min()->Number() - rhs->Min()->Number();
+  results[1] = lhs->Min()->Number() - rhs->Max()->Number();
+  results[2] = lhs->Max()->Number() - rhs->Min()->Number();
+  results[3] = lhs->Max()->Number() - rhs->Max()->Number();
+  // Since none of the inputs can be -0, the result cannot be -0.
+  // However, it can be nan (the subtraction of two infinities of same sign).
+  // On the other hand, if none of the "results" above is nan, then the actual
+  // result cannot be nan either.
+  int nans = 0;
+  for (int i = 0; i < 4; ++i) {
+    if (std::isnan(results[i])) ++nans;
+  }
+  if (nans == 4) return Type::NaN();  // [inf..inf] - [inf..inf] (all same sign)
+  Factory* f = t->isolate()->factory();
+  Type* range = Type::Range(f->NewNumber(array_min(results, 4)),
+                            f->NewNumber(array_max(results, 4)), t->zone());
+  return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
+  // Examples:
+  //   [-inf, +inf] - [-inf, +inf] = [-inf, +inf] \/ NaN
+  //   [-inf, -inf] - [-inf, -inf] = NaN
+  //   [-inf, -inf] - [n, +inf] = [-inf, -inf] \/ NaN
+  //   [m, +inf] - [-inf, n] = [-inf, +inf] \/ NaN
+}
+
+
+Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
+  lhs = Rangify(ToNumber(lhs, t), t);
+  rhs = Rangify(ToNumber(rhs, t), t);
+  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
+  if (lhs->IsRange() && rhs->IsRange()) {
+    return JSSubtractRanger(lhs->AsRange(), rhs->AsRange(), t);
+  }
+  return Type::Number();
+}
+
+
+Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs,
+                                       Type::RangeType* rhs, Typer* t) {
+  double results[4];
+  double lmin = lhs->Min()->Number();
+  double lmax = lhs->Max()->Number();
+  double rmin = rhs->Min()->Number();
+  double rmax = rhs->Max()->Number();
+  results[0] = lmin * rmin;
+  results[1] = lmin * rmax;
+  results[2] = lmax * rmin;
+  results[3] = lmax * rmax;
+  // If the result may be nan, we give up on calculating a precise type, because
+  // the discontinuity makes it too complicated.  Note that even if none of the
+  // "results" above is nan, the actual result may still be, so we have to do a
+  // different check:
+  bool maybe_nan = (lhs->Maybe(t->singleton_zero) &&
+                    (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
+                   (rhs->Maybe(t->singleton_zero) &&
+                    (lmin == -V8_INFINITY || lmax == +V8_INFINITY));
+  if (maybe_nan) return t->weakint;  // Giving up.
+  bool maybe_minuszero = (lhs->Maybe(t->singleton_zero) && rmin < 0) ||
+                         (rhs->Maybe(t->singleton_zero) && lmin < 0);
+  Factory* f = t->isolate()->factory();
+  Type* range = Type::Range(f->NewNumber(array_min(results, 4)),
+                            f->NewNumber(array_max(results, 4)), t->zone());
+  return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone())
+                         : range;
+}
+
+
+Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
+  lhs = Rangify(ToNumber(lhs, t), t);
+  rhs = Rangify(ToNumber(rhs, t), t);
+  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
+  if (lhs->IsRange() && rhs->IsRange()) {
+    return JSMultiplyRanger(lhs->AsRange(), rhs->AsRange(), t);
+  }
+  return Type::Number();
+}
+
+
+Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
+  lhs = ToNumber(lhs, t);
+  rhs = ToNumber(rhs, t);
+  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
+  // Division is tricky, so all we do is try ruling out nan.
+  // TODO(neis): try ruling out -0 as well?
+  bool maybe_nan =
+      lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
+      ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
+       (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
+  return maybe_nan ? Type::Number() : Type::OrderedNumber();
+}
+
+
+Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs,
+                                      Type::RangeType* rhs, Typer* t) {
+  double lmin = lhs->Min()->Number();
+  double lmax = lhs->Max()->Number();
+  double rmin = rhs->Min()->Number();
+  double rmax = rhs->Max()->Number();
+
+  double labs = std::max(std::abs(lmin), std::abs(lmax));
+  double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1;
+  double abs = std::min(labs, rabs);
+  bool maybe_minus_zero = false;
+  double omin = 0;
+  double omax = 0;
+  if (lmin >= 0) {  // {lhs} positive.
+    omin = 0;
+    omax = abs;
+  } else if (lmax <= 0) {  // {lhs} negative.
+    omin = 0 - abs;
+    omax = 0;
+    maybe_minus_zero = true;
+  } else {
+    omin = 0 - abs;
+    omax = abs;
+    maybe_minus_zero = true;
+  }
+
+  Factory* f = t->isolate()->factory();
+  Type* result = Type::Range(f->NewNumber(omin), f->NewNumber(omax), t->zone());
+  if (maybe_minus_zero)
+    result = Type::Union(result, Type::MinusZero(), t->zone());
+  return result;
+}
+
+
+Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
+  lhs = ToNumber(lhs, t);
+  rhs = ToNumber(rhs, t);
+  if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
+
+  if (lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
+      lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) {
+    // Result maybe NaN.
+    return Type::Number();
+  }
+
+  lhs = Rangify(lhs, t);
+  rhs = Rangify(rhs, t);
+  if (lhs->IsRange() && rhs->IsRange()) {
+    return JSModulusRanger(lhs->AsRange(), rhs->AsRange(), t);
+  }
+  return Type::OrderedNumber();
 }
 
 
 // JS unary operators.
 
+
+Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) {
+  return Invert(ToBoolean(type, t), t);
+}
+
+
 Bounds Typer::Visitor::TypeJSUnaryNot(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return TypeUnaryOp(node, JSUnaryNotTyper);
 }
 
 
 Bounds Typer::Visitor::TypeJSTypeOf(Node* node) {
-  return Bounds(Type::InternalizedString(zone()));
+  return Bounds(Type::None(zone()), Type::InternalizedString(zone()));
 }
 
 
 // JS conversion operators.
 
+
 Bounds Typer::Visitor::TypeJSToBoolean(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return TypeUnaryOp(node, ToBoolean);
 }
 
 
 Bounds Typer::Visitor::TypeJSToNumber(Node* node) {
-  return Bounds(Type::SignedSmall(zone()), Type::Number(zone()));
+  return TypeUnaryOp(node, ToNumber);
 }
 
 
 Bounds Typer::Visitor::TypeJSToString(Node* node) {
-  return Bounds(Type::None(zone()), Type::String(zone()));
+  return TypeUnaryOp(node, ToString);
 }
 
 
 Bounds Typer::Visitor::TypeJSToName(Node* node) {
-  return Bounds(Type::None(zone()), Type::Name(zone()));
+  return Bounds(Type::None(), Type::Name());
 }
 
 
 Bounds Typer::Visitor::TypeJSToObject(Node* node) {
-  return Bounds(Type::None(zone()), Type::Receiver(zone()));
+  return Bounds(Type::None(), Type::Receiver());
 }
 
 
 // JS object operators.
 
+
 Bounds Typer::Visitor::TypeJSCreate(Node* node) {
-  return Bounds(Type::None(zone()), Type::Object(zone()));
+  return Bounds(Type::None(), Type::Object());
+}
+
+
+Type* Typer::Visitor::JSLoadPropertyTyper(Type* object, Type* name, Typer* t) {
+  // TODO(rossberg): Use range types and sized array types to filter undefined.
+  if (object->IsArray() && name->Is(Type::Integral32())) {
+    return Type::Union(
+        object->AsArray()->Element(), Type::Undefined(), t->zone());
+  }
+  return Type::Any();
 }
 
 
 Bounds Typer::Visitor::TypeJSLoadProperty(Node* node) {
-  Bounds object = OperandType(node, 0);
-  Bounds name = OperandType(node, 1);
-  Bounds result = Bounds::Unbounded(zone());
-  // TODO(rossberg): Use range types and sized array types to filter undefined.
-  if (object.lower->IsArray() && name.lower->Is(Type::Integral32())) {
-    result.lower = Type::Union(
-        object.lower->AsArray()->Element(), Type::Undefined(zone()), zone());
-  }
-  if (object.upper->IsArray() && name.upper->Is(Type::Integral32())) {
-    result.upper = Type::Union(
-        object.upper->AsArray()->Element(),  Type::Undefined(zone()), zone());
-  }
-  return result;
+  return TypeBinaryOp(node, JSLoadPropertyTyper);
 }
 
 
@@ -501,6 +1242,52 @@
 }
 
 
+// Returns a somewhat larger range if we previously assigned
+// a (smaller) range to this node. This is used  to speed up
+// the fixpoint calculation in case there appears to be a loop
+// in the graph. In the current implementation, we are
+// increasing the limits to the closest power of two.
+Type* Typer::Visitor::Weaken(Type* current_type, Type* previous_type) {
+  Type::RangeType* previous = previous_type->GetRange();
+  Type::RangeType* current = current_type->GetRange();
+  if (previous != NULL && current != NULL) {
+    double current_min = current->Min()->Number();
+    Handle<Object> new_min = current->Min();
+
+    // Find the closest lower entry in the list of allowed
+    // minima (or negative infinity if there is no such entry).
+    if (current_min != previous->Min()->Number()) {
+      new_min = typer_->integer->AsRange()->Min();
+      for (const auto val : typer_->weaken_min_limits_) {
+        if (val->Number() <= current_min) {
+          new_min = val;
+          break;
+        }
+      }
+    }
+
+    double current_max = current->Max()->Number();
+    Handle<Object> new_max = current->Max();
+    // Find the closest greater entry in the list of allowed
+    // maxima (or infinity if there is no such entry).
+    if (current_max != previous->Max()->Number()) {
+      new_max = typer_->integer->AsRange()->Max();
+      for (const auto val : typer_->weaken_max_limits_) {
+        if (val->Number() >= current_max) {
+          new_max = val;
+          break;
+        }
+      }
+    }
+
+    return Type::Union(current_type,
+                       Type::Range(new_min, new_max, typer_->zone()),
+                       typer_->zone());
+  }
+  return current_type;
+}
+
+
 Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) {
   UNREACHABLE();
   return Bounds();
@@ -514,30 +1301,36 @@
 
 
 Bounds Typer::Visitor::TypeJSDeleteProperty(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return Bounds(Type::None(zone()), Type::Boolean(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeJSHasProperty(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return Bounds(Type::None(zone()), Type::Boolean(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeJSInstanceOf(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return Bounds(Type::None(zone()), Type::Boolean(zone()));
 }
 
 
 // JS context operators.
 
+
 Bounds Typer::Visitor::TypeJSLoadContext(Node* node) {
-  Bounds outer = OperandType(node, 0);
-  DCHECK(outer.upper->Maybe(Type::Internal()));
+  Bounds outer = Operand(node, 0);
+  Type* context_type = outer.upper;
+  if (context_type->Is(Type::None())) {
+    // Upper bound of context is not yet known.
+    return Bounds(Type::None(), Type::Any());
+  }
+
+  DCHECK(context_type->Maybe(Type::Internal()));
   // TODO(rossberg): More precisely, instead of the above assertion, we should
   // back-propagate the constraint that it has to be a subtype of Internal.
 
   ContextAccess access = OpParameter<ContextAccess>(node);
-  Type* context_type = outer.upper;
   MaybeHandle<Context> context;
   if (context_type->IsConstant()) {
     context = Handle<Context>::cast(context_type->AsConstant()->Value());
@@ -547,7 +1340,7 @@
   // bound.
   // TODO(rossberg): Could use scope info to fix upper bounds for constant
   // bindings if we know that this code is never shared.
-  for (int i = access.depth(); i > 0; --i) {
+  for (size_t i = access.depth(); i > 0; --i) {
     if (context_type->IsContext()) {
       context_type = context_type->AsContext()->Outer();
       if (context_type->IsConstant()) {
@@ -561,9 +1354,10 @@
     return Bounds::Unbounded(zone());
   } else {
     Handle<Object> value =
-        handle(context.ToHandleChecked()->get(access.index()), isolate());
+        handle(context.ToHandleChecked()->get(static_cast<int>(access.index())),
+               isolate());
     Type* lower = TypeConstant(value);
-    return Bounds(lower, Type::Any(zone()));
+    return Bounds(lower, Type::Any());
   }
 }
 
@@ -575,61 +1369,62 @@
 
 
 Bounds Typer::Visitor::TypeJSCreateFunctionContext(Node* node) {
-  Type* outer = ContextType(node);
-  return Bounds(Type::Context(outer, zone()));
+  Bounds outer = ContextOperand(node);
+  return Bounds(Type::Context(outer.upper, zone()));
 }
 
 
 Bounds Typer::Visitor::TypeJSCreateCatchContext(Node* node) {
-  Type* outer = ContextType(node);
-  return Bounds(Type::Context(outer, zone()));
+  Bounds outer = ContextOperand(node);
+  return Bounds(Type::Context(outer.upper, zone()));
 }
 
 
 Bounds Typer::Visitor::TypeJSCreateWithContext(Node* node) {
-  Type* outer = ContextType(node);
-  return Bounds(Type::Context(outer, zone()));
+  Bounds outer = ContextOperand(node);
+  return Bounds(Type::Context(outer.upper, zone()));
 }
 
 
 Bounds Typer::Visitor::TypeJSCreateBlockContext(Node* node) {
-  Type* outer = ContextType(node);
-  return Bounds(Type::Context(outer, zone()));
+  Bounds outer = ContextOperand(node);
+  return Bounds(Type::Context(outer.upper, zone()));
 }
 
 
 Bounds Typer::Visitor::TypeJSCreateModuleContext(Node* node) {
   // TODO(rossberg): this is probably incorrect
-  Type* outer = ContextType(node);
-  return Bounds(Type::Context(outer, zone()));
+  Bounds outer = ContextOperand(node);
+  return Bounds(Type::Context(outer.upper, zone()));
 }
 
 
-Bounds Typer::Visitor::TypeJSCreateGlobalContext(Node* node) {
-  Type* outer = ContextType(node);
-  return Bounds(Type::Context(outer, zone()));
+Bounds Typer::Visitor::TypeJSCreateScriptContext(Node* node) {
+  Bounds outer = ContextOperand(node);
+  return Bounds(Type::Context(outer.upper, zone()));
 }
 
 
 // JS other operators.
 
+
 Bounds Typer::Visitor::TypeJSYield(Node* node) {
   return Bounds::Unbounded(zone());
 }
 
 
 Bounds Typer::Visitor::TypeJSCallConstruct(Node* node) {
-  return Bounds(Type::None(zone()), Type::Receiver(zone()));
+  return Bounds(Type::None(), Type::Receiver());
+}
+
+
+Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
+  return fun->IsFunction() ? fun->AsFunction()->Result() : Type::Any();
 }
 
 
 Bounds Typer::Visitor::TypeJSCallFunction(Node* node) {
-  Bounds fun = OperandType(node, 0);
-  Type* lower = fun.lower->IsFunction()
-      ? fun.lower->AsFunction()->Result() : Type::None(zone());
-  Type* upper = fun.upper->IsFunction()
-      ? fun.upper->AsFunction()->Result() : Type::Any(zone());
-  return Bounds(lower, upper);
+  return TypeUnaryOp(node, JSCallFunctionTyper);  // We ignore argument types.
 }
 
 
@@ -645,143 +1440,177 @@
 
 // Simplified operators.
 
+
+Bounds Typer::Visitor::TypeAnyToBoolean(Node* node) {
+  return TypeUnaryOp(node, ToBoolean);
+}
+
+
 Bounds Typer::Visitor::TypeBooleanNot(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return Bounds(Type::None(zone()), Type::Boolean(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeBooleanToNumber(Node* node) {
-  return Bounds(Type::Number(zone()));
+  return Bounds(Type::None(zone()), typer_->zero_or_one);
 }
 
 
 Bounds Typer::Visitor::TypeNumberEqual(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return Bounds(Type::None(zone()), Type::Boolean(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeNumberLessThan(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return Bounds(Type::None(zone()), Type::Boolean(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return Bounds(Type::None(zone()), Type::Boolean(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeNumberAdd(Node* node) {
-  return Bounds(Type::Number(zone()));
+  return Bounds(Type::None(zone()), Type::Number(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeNumberSubtract(Node* node) {
-  return Bounds(Type::Number(zone()));
+  return Bounds(Type::None(zone()), Type::Number(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeNumberMultiply(Node* node) {
-  return Bounds(Type::Number(zone()));
+  return Bounds(Type::None(zone()), Type::Number(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeNumberDivide(Node* node) {
-  return Bounds(Type::Number(zone()));
+  return Bounds(Type::None(zone()), Type::Number(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeNumberModulus(Node* node) {
-  return Bounds(Type::Number(zone()));
+  return Bounds(Type::None(zone()), Type::Number(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeNumberToInt32(Node* node) {
-  Bounds arg = OperandType(node, 0);
-  Type* s32 = Type::Signed32(zone());
-  Type* lower = arg.lower->Is(s32) ? arg.lower : s32;
-  Type* upper = arg.upper->Is(s32) ? arg.upper : s32;
-  return Bounds(lower, upper);
+  return TypeUnaryOp(node, NumberToInt32);
 }
 
 
 Bounds Typer::Visitor::TypeNumberToUint32(Node* node) {
-  Bounds arg = OperandType(node, 0);
-  Type* u32 = Type::Unsigned32(zone());
-  Type* lower = arg.lower->Is(u32) ? arg.lower : u32;
-  Type* upper = arg.upper->Is(u32) ? arg.upper : u32;
-  return Bounds(lower, upper);
+  return TypeUnaryOp(node, NumberToUint32);
 }
 
 
 Bounds Typer::Visitor::TypeReferenceEqual(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return Bounds(Type::None(zone()), Type::Boolean(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeStringEqual(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return Bounds(Type::None(zone()), Type::Boolean(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeStringLessThan(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return Bounds(Type::None(zone()), Type::Boolean(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
-  return Bounds(Type::Boolean(zone()));
+  return Bounds(Type::None(zone()), Type::Boolean(zone()));
 }
 
 
 Bounds Typer::Visitor::TypeStringAdd(Node* node) {
-  return Bounds(Type::String(zone()));
+  return Bounds(Type::None(zone()), Type::String(zone()));
+}
+
+
+static Type* ChangeRepresentation(Type* type, Type* rep, Zone* zone) {
+  // TODO(neis): Enable when expressible.
+  /*
+  return Type::Union(
+      Type::Intersect(type, Type::Semantic(), zone),
+      Type::Intersect(rep, Type::Representation(), zone), zone);
+  */
+  return type;
 }
 
 
 Bounds Typer::Visitor::TypeChangeTaggedToInt32(Node* node) {
-  // TODO(titzer): type is type of input, representation is Word32.
-  return Bounds(Type::Integral32());
+  Bounds arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg.upper->Is(Type::Signed32()));
+  return Bounds(
+      ChangeRepresentation(arg.lower, Type::UntaggedSigned32(), zone()),
+      ChangeRepresentation(arg.upper, Type::UntaggedSigned32(), zone()));
 }
 
 
 Bounds Typer::Visitor::TypeChangeTaggedToUint32(Node* node) {
-  return Bounds(Type::Integral32());  // TODO(titzer): add appropriate rep
+  Bounds arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg.upper->Is(Type::Unsigned32()));
+  return Bounds(
+      ChangeRepresentation(arg.lower, Type::UntaggedUnsigned32(), zone()),
+      ChangeRepresentation(arg.upper, Type::UntaggedUnsigned32(), zone()));
 }
 
 
 Bounds Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) {
-  // TODO(titzer): type is type of input, representation is Float64.
-  return Bounds(Type::Number());
+  Bounds arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg.upper->Is(Type::Number()));
+  return Bounds(
+      ChangeRepresentation(arg.lower, Type::UntaggedFloat64(), zone()),
+      ChangeRepresentation(arg.upper, Type::UntaggedFloat64(), zone()));
 }
 
 
 Bounds Typer::Visitor::TypeChangeInt32ToTagged(Node* node) {
-  // TODO(titzer): type is type of input, representation is Tagged.
-  return Bounds(Type::Integral32());
+  Bounds arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg.upper->Is(Type::Signed32()));
+  return Bounds(
+      ChangeRepresentation(arg.lower, Type::Tagged(), zone()),
+      ChangeRepresentation(arg.upper, Type::Tagged(), zone()));
 }
 
 
 Bounds Typer::Visitor::TypeChangeUint32ToTagged(Node* node) {
-  // TODO(titzer): type is type of input, representation is Tagged.
-  return Bounds(Type::Unsigned32());
+  Bounds arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg.upper->Is(Type::Unsigned32()));
+  return Bounds(
+      ChangeRepresentation(arg.lower, Type::Tagged(), zone()),
+      ChangeRepresentation(arg.upper, Type::Tagged(), zone()));
 }
 
 
 Bounds Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) {
-  // TODO(titzer): type is type of input, representation is Tagged.
-  return Bounds(Type::Number());
+  Bounds arg = Operand(node, 0);
+  // TODO(neis): CHECK(arg.upper->Is(Type::Number()));
+  return Bounds(
+      ChangeRepresentation(arg.lower, Type::Tagged(), zone()),
+      ChangeRepresentation(arg.upper, Type::Tagged(), zone()));
 }
 
 
 Bounds Typer::Visitor::TypeChangeBoolToBit(Node* node) {
-  // TODO(titzer): type is type of input, representation is Bit.
-  return Bounds(Type::Boolean());
+  Bounds arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
+  return Bounds(
+      ChangeRepresentation(arg.lower, Type::UntaggedBit(), zone()),
+      ChangeRepresentation(arg.upper, Type::UntaggedBit(), zone()));
 }
 
 
 Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) {
-  // TODO(titzer): type is type of input, representation is Tagged.
-  return Bounds(Type::Boolean());
+  Bounds arg = Operand(node, 0);
+  // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
+  return Bounds(
+      ChangeRepresentation(arg.lower, Type::TaggedPointer(), zone()),
+      ChangeRepresentation(arg.upper, Type::TaggedPointer(), zone()));
 }
 
 
@@ -790,6 +1619,21 @@
 }
 
 
+Bounds Typer::Visitor::TypeLoadBuffer(Node* node) {
+  // TODO(bmeurer): This typing is not yet correct. Since we can still access
+  // out of bounds, the type in the general case has to include Undefined.
+  switch (BufferAccessOf(node->op()).external_array_type()) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+  case kExternal##Type##Array:                          \
+    return Bounds(typer_->cache_->Get(k##Type));
+    TYPED_ARRAYS(TYPED_ARRAY_CASE)
+#undef TYPED_ARRAY_CASE
+  }
+  UNREACHABLE();
+  return Bounds();
+}
+
+
 Bounds Typer::Visitor::TypeLoadElement(Node* node) {
   return Bounds(ElementAccessOf(node->op()).type);
 }
@@ -801,104 +1645,465 @@
 }
 
 
+Bounds Typer::Visitor::TypeStoreBuffer(Node* node) {
+  UNREACHABLE();
+  return Bounds();
+}
+
+
 Bounds Typer::Visitor::TypeStoreElement(Node* node) {
   UNREACHABLE();
   return Bounds();
 }
 
 
+Bounds Typer::Visitor::TypeObjectIsSmi(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeObjectIsNonNegativeSmi(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
 // Machine operators.
 
-// TODO(rossberg): implement
-#define DEFINE_METHOD(x) \
-    Bounds Typer::Visitor::Type##x(Node* node) { return Bounds(Type::None()); }
-MACHINE_OP_LIST(DEFINE_METHOD)
-#undef DEFINE_METHOD
+Bounds Typer::Visitor::TypeLoad(Node* node) {
+  return Bounds::Unbounded(zone());
+}
+
+
+Bounds Typer::Visitor::TypeStore(Node* node) {
+  UNREACHABLE();
+  return Bounds();
+}
+
+
+Bounds Typer::Visitor::TypeWord32And(Node* node) {
+  return Bounds(Type::Integral32());
+}
+
+
+Bounds Typer::Visitor::TypeWord32Or(Node* node) {
+  return Bounds(Type::Integral32());
+}
+
+
+Bounds Typer::Visitor::TypeWord32Xor(Node* node) {
+  return Bounds(Type::Integral32());
+}
+
+
+Bounds Typer::Visitor::TypeWord32Shl(Node* node) {
+  return Bounds(Type::Integral32());
+}
+
+
+Bounds Typer::Visitor::TypeWord32Shr(Node* node) {
+  return Bounds(Type::Integral32());
+}
+
+
+Bounds Typer::Visitor::TypeWord32Sar(Node* node) {
+  return Bounds(Type::Integral32());
+}
+
+
+Bounds Typer::Visitor::TypeWord32Ror(Node* node) {
+  return Bounds(Type::Integral32());
+}
+
+
+Bounds Typer::Visitor::TypeWord32Equal(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeWord64And(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeWord64Or(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeWord64Xor(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeWord64Shl(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeWord64Shr(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeWord64Sar(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeWord64Ror(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeWord64Equal(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeInt32Add(Node* node) {
+  return Bounds(Type::Integral32());
+}
+
+
+Bounds Typer::Visitor::TypeInt32AddWithOverflow(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeInt32Sub(Node* node) {
+  return Bounds(Type::Integral32());
+}
+
+
+Bounds Typer::Visitor::TypeInt32SubWithOverflow(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeInt32Mul(Node* node) {
+  return Bounds(Type::Integral32());
+}
+
+
+Bounds Typer::Visitor::TypeInt32MulHigh(Node* node) {
+  return Bounds(Type::Signed32());
+}
+
+
+Bounds Typer::Visitor::TypeInt32Div(Node* node) {
+  return Bounds(Type::Integral32());
+}
+
+
+Bounds Typer::Visitor::TypeInt32Mod(Node* node) {
+  return Bounds(Type::Integral32());
+}
+
+
+Bounds Typer::Visitor::TypeInt32LessThan(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeInt32LessThanOrEqual(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeUint32Div(Node* node) {
+  return Bounds(Type::Unsigned32());
+}
+
+
+Bounds Typer::Visitor::TypeUint32LessThan(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeUint32LessThanOrEqual(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeUint32Mod(Node* node) {
+  return Bounds(Type::Unsigned32());
+}
+
+
+Bounds Typer::Visitor::TypeUint32MulHigh(Node* node) {
+  return Bounds(Type::Unsigned32());
+}
+
+
+Bounds Typer::Visitor::TypeInt64Add(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeInt64Sub(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeInt64Mul(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeInt64Div(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeInt64Mod(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeInt64LessThan(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeInt64LessThanOrEqual(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeUint64Div(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeUint64LessThan(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeUint64Mod(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeChangeFloat32ToFloat64(Node* node) {
+  return Bounds(Type::Intersect(
+      Type::Number(), Type::UntaggedFloat64(), zone()));
+}
+
+
+Bounds Typer::Visitor::TypeChangeFloat64ToInt32(Node* node) {
+  return Bounds(Type::Intersect(
+      Type::Signed32(), Type::UntaggedSigned32(), zone()));
+}
+
+
+Bounds Typer::Visitor::TypeChangeFloat64ToUint32(Node* node) {
+  return Bounds(Type::Intersect(
+      Type::Unsigned32(), Type::UntaggedUnsigned32(), zone()));
+}
+
+
+Bounds Typer::Visitor::TypeChangeInt32ToFloat64(Node* node) {
+  return Bounds(Type::Intersect(
+      Type::Signed32(), Type::UntaggedFloat64(), zone()));
+}
+
+
+Bounds Typer::Visitor::TypeChangeInt32ToInt64(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeChangeUint32ToFloat64(Node* node) {
+  return Bounds(Type::Intersect(
+      Type::Unsigned32(), Type::UntaggedFloat64(), zone()));
+}
+
+
+Bounds Typer::Visitor::TypeChangeUint32ToUint64(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeTruncateFloat64ToFloat32(Node* node) {
+  return Bounds(Type::Intersect(
+      Type::Number(), Type::UntaggedFloat32(), zone()));
+}
+
+
+Bounds Typer::Visitor::TypeTruncateFloat64ToInt32(Node* node) {
+  return Bounds(Type::Intersect(
+      Type::Signed32(), Type::UntaggedSigned32(), zone()));
+}
+
+
+Bounds Typer::Visitor::TypeTruncateInt64ToInt32(Node* node) {
+  return Bounds(Type::Intersect(
+      Type::Signed32(), Type::UntaggedSigned32(), zone()));
+}
+
+
+Bounds Typer::Visitor::TypeFloat64Add(Node* node) {
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64Sub(Node* node) {
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64Mul(Node* node) {
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64Div(Node* node) {
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64Mod(Node* node) {
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64Sqrt(Node* node) {
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64Equal(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64LessThan(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64LessThanOrEqual(Node* node) {
+  return Bounds(Type::Boolean());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64Floor(Node* node) {
+  // TODO(sigurds): We could have a tighter bound here.
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64Ceil(Node* node) {
+  // TODO(sigurds): We could have a tighter bound here.
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64RoundTruncate(Node* node) {
+  // TODO(sigurds): We could have a tighter bound here.
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeFloat64RoundTiesAway(Node* node) {
+  // TODO(sigurds): We could have a tighter bound here.
+  return Bounds(Type::Number());
+}
+
+
+Bounds Typer::Visitor::TypeLoadStackPointer(Node* node) {
+  return Bounds(Type::Internal());
+}
+
+
+Bounds Typer::Visitor::TypeCheckedLoad(Node* node) {
+  return Bounds::Unbounded(zone());
+}
+
+
+Bounds Typer::Visitor::TypeCheckedStore(Node* node) {
+  UNREACHABLE();
+  return Bounds();
+}
 
 
 // Heap constants.
 
+
 Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
-  if (value->IsJSFunction() && JSFunction::cast(*value)->IsBuiltin() &&
-      !context().is_null()) {
-    Handle<Context> native =
-        handle(context().ToHandleChecked()->native_context(), isolate());
-    if (*value == native->math_abs_fun()) {
-      return typer_->number_fun1_;  // TODO(rossberg): can't express overloading
-    } else if (*value == native->math_acos_fun()) {
-      return typer_->number_fun1_;
-    } else if (*value == native->math_asin_fun()) {
-      return typer_->number_fun1_;
-    } else if (*value == native->math_atan_fun()) {
-      return typer_->number_fun1_;
-    } else if (*value == native->math_atan2_fun()) {
-      return typer_->number_fun2_;
-    } else if (*value == native->math_ceil_fun()) {
-      return typer_->number_fun1_;
-    } else if (*value == native->math_cos_fun()) {
-      return typer_->number_fun1_;
-    } else if (*value == native->math_exp_fun()) {
-      return typer_->number_fun1_;
-    } else if (*value == native->math_floor_fun()) {
-      return typer_->number_fun1_;
-    } else if (*value == native->math_imul_fun()) {
-      return typer_->imul_fun_;
-    } else if (*value == native->math_log_fun()) {
-      return typer_->number_fun1_;
-    } else if (*value == native->math_pow_fun()) {
-      return typer_->number_fun2_;
-    } else if (*value == native->math_random_fun()) {
-      return typer_->number_fun0_;
-    } else if (*value == native->math_round_fun()) {
-      return typer_->number_fun1_;
-    } else if (*value == native->math_sin_fun()) {
-      return typer_->number_fun1_;
-    } else if (*value == native->math_sqrt_fun()) {
-      return typer_->number_fun1_;
-    } else if (*value == native->math_tan_fun()) {
-      return typer_->number_fun1_;
-    } else if (*value == native->array_buffer_fun()) {
-      return typer_->array_buffer_fun_;
-    } else if (*value == native->int8_array_fun()) {
-      return typer_->int8_array_fun_;
-    } else if (*value == native->int16_array_fun()) {
-      return typer_->int16_array_fun_;
-    } else if (*value == native->int32_array_fun()) {
-      return typer_->int32_array_fun_;
-    } else if (*value == native->uint8_array_fun()) {
-      return typer_->uint8_array_fun_;
-    } else if (*value == native->uint16_array_fun()) {
-      return typer_->uint16_array_fun_;
-    } else if (*value == native->uint32_array_fun()) {
-      return typer_->uint32_array_fun_;
-    } else if (*value == native->float32_array_fun()) {
-      return typer_->float32_array_fun_;
-    } else if (*value == native->float64_array_fun()) {
-      return typer_->float64_array_fun_;
+  if (value->IsJSFunction()) {
+    if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) {
+      switch (JSFunction::cast(*value)->shared()->builtin_function_id()) {
+        case kMathRandom:
+          return typer_->random_fun_;
+        case kMathFloor:
+          return typer_->weakint_fun1_;
+        case kMathRound:
+          return typer_->weakint_fun1_;
+        case kMathCeil:
+          return typer_->weakint_fun1_;
+        // Unary math functions.
+        case kMathAbs:  // TODO(rossberg): can't express overloading
+        case kMathLog:
+        case kMathExp:
+        case kMathSqrt:
+        case kMathCos:
+        case kMathSin:
+        case kMathTan:
+        case kMathAcos:
+        case kMathAsin:
+        case kMathAtan:
+        case kMathFround:
+          return typer_->cache_->Get(kNumberFunc1);
+        // Binary math functions.
+        case kMathAtan2:
+        case kMathPow:
+        case kMathMax:
+        case kMathMin:
+          return typer_->cache_->Get(kNumberFunc2);
+        case kMathImul:
+          return typer_->cache_->Get(kImulFunc);
+        case kMathClz32:
+          return typer_->cache_->Get(kClz32Func);
+        default:
+          break;
+      }
+    } else if (JSFunction::cast(*value)->IsBuiltin() && !context().is_null()) {
+      Handle<Context> native =
+          handle(context().ToHandleChecked()->native_context(), isolate());
+      if (*value == native->array_buffer_fun()) {
+        return typer_->cache_->Get(kArrayBufferFunc);
+      } else if (*value == native->int8_array_fun()) {
+        return typer_->cache_->Get(kInt8ArrayFunc);
+      } else if (*value == native->int16_array_fun()) {
+        return typer_->cache_->Get(kInt16ArrayFunc);
+      } else if (*value == native->int32_array_fun()) {
+        return typer_->cache_->Get(kInt32ArrayFunc);
+      } else if (*value == native->uint8_array_fun()) {
+        return typer_->cache_->Get(kUint8ArrayFunc);
+      } else if (*value == native->uint16_array_fun()) {
+        return typer_->cache_->Get(kUint16ArrayFunc);
+      } else if (*value == native->uint32_array_fun()) {
+        return typer_->cache_->Get(kUint32ArrayFunc);
+      } else if (*value == native->float32_array_fun()) {
+        return typer_->cache_->Get(kFloat32ArrayFunc);
+      } else if (*value == native->float64_array_fun()) {
+        return typer_->cache_->Get(kFloat64ArrayFunc);
+      }
+    }
+  } else if (value->IsJSTypedArray()) {
+    switch (JSTypedArray::cast(*value)->type()) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+  case kExternal##Type##Array:                          \
+    return typer_->cache_->Get(k##Type##Array);
+      TYPED_ARRAYS(TYPED_ARRAY_CASE)
+#undef TYPED_ARRAY_CASE
     }
   }
   return Type::Constant(value, zone());
 }
 
-
-namespace {
-
-class TyperDecorator : public GraphDecorator {
- public:
-  explicit TyperDecorator(Typer* typer) : typer_(typer) {}
-  virtual void Decorate(Node* node) { typer_->Init(node); }
-
- private:
-  Typer* typer_;
-};
-
-}
-
-
-void Typer::DecorateGraph(Graph* graph) {
-  graph->AddDecorator(new (zone()) TyperDecorator(this));
-}
-
-}
-}
-}  // namespace v8::internal::compiler
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/typer.h b/src/compiler/typer.h
index 2957e4b..b65a9a5 100644
--- a/src/compiler/typer.h
+++ b/src/compiler/typer.h
@@ -15,43 +15,62 @@
 namespace internal {
 namespace compiler {
 
+// Forward declarations.
+class LazyTypeCache;
+
+
 class Typer {
  public:
-  explicit Typer(Zone* zone);
+  explicit Typer(Graph* graph, MaybeHandle<Context> context);
+  ~Typer();
 
-  void Init(Node* node);
-  void Run(Graph* graph, MaybeHandle<Context> context);
-  void Narrow(Graph* graph, Node* node, MaybeHandle<Context> context);
-  void Widen(Graph* graph, Node* node, MaybeHandle<Context> context);
+  void Run();
 
-  void DecorateGraph(Graph* graph);
-
-  Zone* zone() { return zone_; }
-  Isolate* isolate() { return zone_->isolate(); }
+  Graph* graph() { return graph_; }
+  MaybeHandle<Context> context() { return context_; }
+  Zone* zone() { return graph_->zone(); }
+  Isolate* isolate() { return zone()->isolate(); }
 
  private:
   class Visitor;
-  class RunVisitor;
-  class NarrowVisitor;
-  class WidenVisitor;
+  class Decorator;
+
+  Graph* graph_;
+  MaybeHandle<Context> context_;
+  Decorator* decorator_;
 
   Zone* zone_;
+  Type* boolean_or_number;
+  Type* undefined_or_null;
+  Type* undefined_or_number;
+  Type* negative_signed32;
+  Type* non_negative_signed32;
+  Type* singleton_false;
+  Type* singleton_true;
+  Type* singleton_zero;
+  Type* singleton_one;
+  Type* zero_or_one;
+  Type* zeroish;
+  Type* signed32ish;
+  Type* unsigned32ish;
+  Type* falsish;
+  Type* truish;
+  Type* integer;
+  Type* weakint;
   Type* number_fun0_;
   Type* number_fun1_;
   Type* number_fun2_;
-  Type* imul_fun_;
-  Type* array_buffer_fun_;
-  Type* int8_array_fun_;
-  Type* int16_array_fun_;
-  Type* int32_array_fun_;
-  Type* uint8_array_fun_;
-  Type* uint16_array_fun_;
-  Type* uint32_array_fun_;
-  Type* float32_array_fun_;
-  Type* float64_array_fun_;
+  Type* weakint_fun1_;
+  Type* random_fun_;
+  LazyTypeCache* cache_;
+
+  ZoneVector<Handle<Object> > weaken_min_limits_;
+  ZoneVector<Handle<Object> > weaken_max_limits_;
+  DISALLOW_COPY_AND_ASSIGN(Typer);
 };
-}
-}
-}  // namespace v8::internal::compiler
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_COMPILER_TYPER_H_
diff --git a/src/compiler/value-numbering-reducer-unittest.cc b/src/compiler/value-numbering-reducer-unittest.cc
deleted file mode 100644
index 8db6458..0000000
--- a/src/compiler/value-numbering-reducer-unittest.cc
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <limits>
-
-#include "src/compiler/graph.h"
-#include "src/compiler/value-numbering-reducer.h"
-#include "src/test/test-utils.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-namespace {
-
-const SimpleOperator kOp0(0, Operator::kNoProperties, 0, 1, "op0");
-const SimpleOperator kOp1(1, Operator::kNoProperties, 1, 1, "op1");
-
-}  // namespace
-
-
-class ValueNumberingReducerTest : public TestWithZone {
- public:
-  ValueNumberingReducerTest() : graph_(zone()), reducer_(zone()) {}
-
- protected:
-  Reduction Reduce(Node* node) { return reducer_.Reduce(node); }
-
-  Graph* graph() { return &graph_; }
-
- private:
-  Graph graph_;
-  ValueNumberingReducer reducer_;
-};
-
-
-TEST_F(ValueNumberingReducerTest, AllInputsAreChecked) {
-  Node* na = graph()->NewNode(&kOp0);
-  Node* nb = graph()->NewNode(&kOp0);
-  Node* n1 = graph()->NewNode(&kOp0, na);
-  Node* n2 = graph()->NewNode(&kOp0, nb);
-  EXPECT_FALSE(Reduce(n1).Changed());
-  EXPECT_FALSE(Reduce(n2).Changed());
-}
-
-
-TEST_F(ValueNumberingReducerTest, DeadNodesAreNeverReturned) {
-  Node* n0 = graph()->NewNode(&kOp0);
-  Node* n1 = graph()->NewNode(&kOp1, n0);
-  EXPECT_FALSE(Reduce(n1).Changed());
-  n1->Kill();
-  EXPECT_FALSE(Reduce(graph()->NewNode(&kOp1, n0)).Changed());
-}
-
-
-TEST_F(ValueNumberingReducerTest, OperatorEqualityNotIdentity) {
-  static const size_t kMaxInputCount = 16;
-  Node* inputs[kMaxInputCount];
-  for (size_t i = 0; i < arraysize(inputs); ++i) {
-    Operator::Opcode opcode = static_cast<Operator::Opcode>(
-        std::numeric_limits<Operator::Opcode>::max() - i);
-    inputs[i] = graph()->NewNode(new (zone()) SimpleOperator(
-        opcode, Operator::kNoProperties, 0, 1, "Operator"));
-  }
-  TRACED_FORRANGE(size_t, input_count, 0, arraysize(inputs)) {
-    const SimpleOperator op1(static_cast<Operator::Opcode>(input_count),
-                             Operator::kNoProperties,
-                             static_cast<int>(input_count), 1, "op");
-    Node* n1 = graph()->NewNode(&op1, static_cast<int>(input_count), inputs);
-    Reduction r1 = Reduce(n1);
-    EXPECT_FALSE(r1.Changed());
-
-    const SimpleOperator op2(static_cast<Operator::Opcode>(input_count),
-                             Operator::kNoProperties,
-                             static_cast<int>(input_count), 1, "op");
-    Node* n2 = graph()->NewNode(&op2, static_cast<int>(input_count), inputs);
-    Reduction r2 = Reduce(n2);
-    EXPECT_TRUE(r2.Changed());
-    EXPECT_EQ(n1, r2.replacement());
-  }
-}
-
-
-TEST_F(ValueNumberingReducerTest, SubsequentReductionsYieldTheSameNode) {
-  static const size_t kMaxInputCount = 16;
-  Node* inputs[kMaxInputCount];
-  for (size_t i = 0; i < arraysize(inputs); ++i) {
-    Operator::Opcode opcode = static_cast<Operator::Opcode>(
-        std::numeric_limits<Operator::Opcode>::max() - i);
-    inputs[i] = graph()->NewNode(new (zone()) SimpleOperator(
-        opcode, Operator::kNoProperties, 0, 1, "Operator"));
-  }
-  TRACED_FORRANGE(size_t, input_count, 0, arraysize(inputs)) {
-    const SimpleOperator op1(1, Operator::kNoProperties,
-                             static_cast<int>(input_count), 1, "op1");
-    Node* n = graph()->NewNode(&op1, static_cast<int>(input_count), inputs);
-    Reduction r = Reduce(n);
-    EXPECT_FALSE(r.Changed());
-
-    r = Reduce(graph()->NewNode(&op1, static_cast<int>(input_count), inputs));
-    ASSERT_TRUE(r.Changed());
-    EXPECT_EQ(n, r.replacement());
-
-    r = Reduce(graph()->NewNode(&op1, static_cast<int>(input_count), inputs));
-    ASSERT_TRUE(r.Changed());
-    EXPECT_EQ(n, r.replacement());
-  }
-}
-
-
-TEST_F(ValueNumberingReducerTest, WontReplaceNodeWithItself) {
-  Node* n = graph()->NewNode(&kOp0);
-  EXPECT_FALSE(Reduce(n).Changed());
-  EXPECT_FALSE(Reduce(n).Changed());
-}
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/value-numbering-reducer.cc b/src/compiler/value-numbering-reducer.cc
index 595a4f3..734b3e8 100644
--- a/src/compiler/value-numbering-reducer.cc
+++ b/src/compiler/value-numbering-reducer.cc
@@ -4,6 +4,9 @@
 
 #include "src/compiler/value-numbering-reducer.h"
 
+#include <cstring>
+
+#include "src/base/functional.h"
 #include "src/compiler/node.h"
 
 namespace v8 {
@@ -12,7 +15,13 @@
 
 namespace {
 
-size_t HashCode(Node* node) { return node->op()->HashCode(); }
+size_t HashCode(Node* node) {
+  size_t h = base::hash_combine(node->op()->HashCode(), node->InputCount());
+  for (int j = 0; j < node->InputCount(); ++j) {
+    h = base::hash_combine(h, node->InputAt(j)->id());
+  }
+  return h;
+}
 
 
 bool Equals(Node* a, Node* b) {
@@ -33,40 +42,121 @@
 }  // namespace
 
 
-class ValueNumberingReducer::Entry FINAL : public ZoneObject {
- public:
-  Entry(Node* node, Entry* next) : node_(node), next_(next) {}
-
-  Node* node() const { return node_; }
-  Entry* next() const { return next_; }
-
- private:
-  Node* node_;
-  Entry* next_;
-};
-
-
-ValueNumberingReducer::ValueNumberingReducer(Zone* zone) : zone_(zone) {
-  for (size_t i = 0; i < arraysize(buckets_); ++i) {
-    buckets_[i] = NULL;
-  }
-}
+ValueNumberingReducer::ValueNumberingReducer(Zone* zone)
+    : entries_(nullptr), capacity_(0), size_(0), zone_(zone) {}
 
 
 ValueNumberingReducer::~ValueNumberingReducer() {}
 
 
 Reduction ValueNumberingReducer::Reduce(Node* node) {
-  Entry** head = &buckets_[HashCode(node) % arraysize(buckets_)];
-  for (Entry* entry = *head; entry; entry = entry->next()) {
-    if (entry->node()->IsDead()) continue;
-    if (entry->node() == node) return NoChange();
-    if (Equals(node, entry->node())) {
-      return Replace(entry->node());
+  if (!node->op()->HasProperty(Operator::kEliminatable)) return NoChange();
+
+  const size_t hash = HashCode(node);
+  if (!entries_) {
+    DCHECK(size_ == 0);
+    DCHECK(capacity_ == 0);
+    // Allocate the initial entries and insert the first entry.
+    capacity_ = kInitialCapacity;
+    entries_ = zone()->NewArray<Node*>(kInitialCapacity);
+    memset(entries_, 0, sizeof(*entries_) * kInitialCapacity);
+    entries_[hash & (kInitialCapacity - 1)] = node;
+    size_ = 1;
+    return NoChange();
+  }
+
+  DCHECK(size_ < capacity_);
+  DCHECK(size_ * kCapacityToSizeRatio < capacity_);
+
+  const size_t mask = capacity_ - 1;
+  size_t dead = capacity_;
+
+  for (size_t i = hash & mask;; i = (i + 1) & mask) {
+    Node* entry = entries_[i];
+    if (!entry) {
+      if (dead != capacity_) {
+        // Reuse dead entry that we discovered on the way.
+        entries_[dead] = node;
+      } else {
+        // Have to insert a new entry.
+        entries_[i] = node;
+        size_++;
+
+        // Resize to keep load factor below 1/kCapacityToSizeRatio.
+        if (size_ * kCapacityToSizeRatio >= capacity_) Grow();
+      }
+      DCHECK(size_ * kCapacityToSizeRatio < capacity_);
+      return NoChange();
+    }
+
+    if (entry == node) {
+      // We need to check for a certain class of collisions here. Imagine the
+      // following scenario:
+      //
+      //  1. We insert node1 with op1 and certain inputs at index i.
+      //  2. We insert node2 with op2 and certain inputs at index i+1.
+      //  3. Some other reducer changes node1 to op2 and the inputs from node2.
+      //
+      // Now we are called again to reduce node1, and we would return NoChange
+      // in this case because we find node1 first, but what we should actually
+      // do is return Replace(node2) instead.
+      for (size_t j = (i + 1) & mask;; j = (j + 1) & mask) {
+        Node* entry = entries_[j];
+        if (!entry) {
+          // No collision, {node} is fine.
+          return NoChange();
+        }
+        if (entry->IsDead()) {
+          continue;
+        }
+        if (Equals(entry, node)) {
+          // Overwrite the colliding entry with the actual entry.
+          entries_[i] = entry;
+          return Replace(entry);
+        }
+      }
+    }
+
+    // Skip dead entries, but remember their indices so we can reuse them.
+    if (entry->IsDead()) {
+      dead = i;
+      continue;
+    }
+    if (Equals(entry, node)) {
+      return Replace(entry);
     }
   }
-  *head = new (zone()) Entry(node, *head);
-  return NoChange();
+}
+
+
+void ValueNumberingReducer::Grow() {
+  // Allocate a new block of entries kCapacityToSizeRatio times the previous
+  // capacity.
+  Node** const old_entries = entries_;
+  size_t const old_capacity = capacity_;
+  capacity_ *= kCapacityToSizeRatio;
+  entries_ = zone()->NewArray<Node*>(static_cast<int>(capacity_));
+  memset(entries_, 0, sizeof(*entries_) * capacity_);
+  size_ = 0;
+  size_t const mask = capacity_ - 1;
+
+  // Insert the old entries into the new block (skipping dead nodes).
+  for (size_t i = 0; i < old_capacity; ++i) {
+    Node* const old_entry = old_entries[i];
+    if (!old_entry || old_entry->IsDead()) continue;
+    for (size_t j = HashCode(old_entry) & mask;; j = (j + 1) & mask) {
+      Node* const entry = entries_[j];
+      if (entry == old_entry) {
+        // Skip duplicate of the old entry.
+        break;
+      }
+      if (!entry) {
+        entries_[j] = old_entry;
+        size_++;
+        break;
+      }
+    }
+  }
 }
 
 }  // namespace compiler
diff --git a/src/compiler/value-numbering-reducer.h b/src/compiler/value-numbering-reducer.h
index 0d67e5d..546226c 100644
--- a/src/compiler/value-numbering-reducer.h
+++ b/src/compiler/value-numbering-reducer.h
@@ -16,16 +16,17 @@
   explicit ValueNumberingReducer(Zone* zone);
   ~ValueNumberingReducer();
 
-  virtual Reduction Reduce(Node* node) OVERRIDE;
+  Reduction Reduce(Node* node) OVERRIDE;
 
  private:
+  enum { kInitialCapacity = 256u, kCapacityToSizeRatio = 2u };
+
+  void Grow();
   Zone* zone() const { return zone_; }
 
-  // TODO(turbofan): We currently use separate chaining with linked lists here,
-  // we may want to replace that with a more sophisticated data structure at
-  // some point in the future.
-  class Entry;
-  Entry* buckets_[117u];
+  Node** entries_;
+  size_t capacity_;
+  size_t size_;
   Zone* zone_;
 };
 
diff --git a/src/compiler/verifier.cc b/src/compiler/verifier.cc
index 23cec7a..693b414 100644
--- a/src/compiler/verifier.cc
+++ b/src/compiler/verifier.cc
@@ -6,10 +6,11 @@
 
 #include <deque>
 #include <queue>
+#include <sstream>
+#include <string>
 
+#include "src/bit-vector.h"
 #include "src/compiler/generic-algorithm.h"
-#include "src/compiler/generic-node-inl.h"
-#include "src/compiler/generic-node.h"
 #include "src/compiler/graph-inl.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/node.h"
@@ -18,7 +19,8 @@
 #include "src/compiler/opcodes.h"
 #include "src/compiler/operator.h"
 #include "src/compiler/schedule.h"
-#include "src/data-flow.h"
+#include "src/compiler/simplified-operator.h"
+#include "src/ostreams.h"
 
 namespace v8 {
 namespace internal {
@@ -45,28 +47,84 @@
 
 class Verifier::Visitor : public NullNodeVisitor {
  public:
-  explicit Visitor(Zone* zone)
-      : reached_from_start(NodeSet::key_compare(),
-                           NodeSet::allocator_type(zone)),
-        reached_from_end(NodeSet::key_compare(),
-                         NodeSet::allocator_type(zone)) {}
+  Visitor(Zone* z, Typing typed) : zone(z), typing(typed) {}
 
   // Fulfills the PreNodeCallback interface.
-  GenericGraphVisit::Control Pre(Node* node);
+  void Pre(Node* node);
 
-  bool from_start;
-  NodeSet reached_from_start;
-  NodeSet reached_from_end;
+  Zone* zone;
+  Typing typing;
+
+ private:
+  // TODO(rossberg): Get rid of these once we got rid of NodeProperties.
+  Bounds bounds(Node* node) { return NodeProperties::GetBounds(node); }
+  Node* ValueInput(Node* node, int i = 0) {
+    return NodeProperties::GetValueInput(node, i);
+  }
+  FieldAccess Field(Node* node) {
+    DCHECK(node->opcode() == IrOpcode::kLoadField ||
+           node->opcode() == IrOpcode::kStoreField);
+    return OpParameter<FieldAccess>(node);
+  }
+  ElementAccess Element(Node* node) {
+    DCHECK(node->opcode() == IrOpcode::kLoadElement ||
+           node->opcode() == IrOpcode::kStoreElement);
+    return OpParameter<ElementAccess>(node);
+  }
+  void CheckNotTyped(Node* node) {
+    if (NodeProperties::IsTyped(node)) {
+      std::ostringstream str;
+      str << "TypeError: node #" << node->opcode() << ":"
+          << node->op()->mnemonic() << " should never have a type";
+      V8_Fatal(__FILE__, __LINE__, str.str().c_str());
+    }
+  }
+  void CheckUpperIs(Node* node, Type* type) {
+    if (typing == TYPED && !bounds(node).upper->Is(type)) {
+      std::ostringstream str;
+      str << "TypeError: node #" << node->opcode() << ":"
+          << node->op()->mnemonic() << " upper bound ";
+      bounds(node).upper->PrintTo(str);
+      str << " is not ";
+      type->PrintTo(str);
+      V8_Fatal(__FILE__, __LINE__, str.str().c_str());
+    }
+  }
+  void CheckUpperMaybe(Node* node, Type* type) {
+    if (typing == TYPED && !bounds(node).upper->Maybe(type)) {
+      std::ostringstream str;
+      str << "TypeError: node #" << node->opcode() << ":"
+          << node->op()->mnemonic() << " upper bound ";
+      bounds(node).upper->PrintTo(str);
+      str << " must intersect ";
+      type->PrintTo(str);
+      V8_Fatal(__FILE__, __LINE__, str.str().c_str());
+    }
+  }
+  void CheckValueInputIs(Node* node, int i, Type* type) {
+    Node* input = ValueInput(node, i);
+    if (typing == TYPED && !bounds(input).upper->Is(type)) {
+      std::ostringstream str;
+      str << "TypeError: node #" << node->opcode() << ":"
+          << node->op()->mnemonic() << "(input @" << i << " = "
+          << input->opcode() << ":" << input->op()->mnemonic()
+          << ") upper bound ";
+      bounds(input).upper->PrintTo(str);
+      str << " is not ";
+      type->PrintTo(str);
+      V8_Fatal(__FILE__, __LINE__, str.str().c_str());
+    }
+  }
 };
 
 
-GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) {
-  int value_count = OperatorProperties::GetValueInputCount(node->op());
+void Verifier::Visitor::Pre(Node* node) {
+  int value_count = node->op()->ValueInputCount();
   int context_count = OperatorProperties::GetContextInputCount(node->op());
   int frame_state_count =
       OperatorProperties::GetFrameStateInputCount(node->op());
-  int effect_count = OperatorProperties::GetEffectInputCount(node->op());
-  int control_count = OperatorProperties::GetControlInputCount(node->op());
+  int effect_count = node->op()->EffectInputCount();
+  int control_count = node->op()->ControlInputCount();
 
   // Verify number of inputs matches up.
   int input_count = value_count + context_count + frame_state_count +
@@ -87,7 +145,7 @@
   // Verify all value inputs actually produce a value.
   for (int i = 0; i < value_count; ++i) {
     Node* value = NodeProperties::GetValueInput(node, i);
-    CHECK(OperatorProperties::HasValueOutput(value->op()));
+    CHECK(value->op()->ValueOutputCount() > 0);
     CHECK(IsDefUseChainLinkPresent(value, node));
     CHECK(IsUseDefChainLinkPresent(value, node));
   }
@@ -95,7 +153,7 @@
   // Verify all context inputs are value nodes.
   for (int i = 0; i < context_count; ++i) {
     Node* context = NodeProperties::GetContextInput(node);
-    CHECK(OperatorProperties::HasValueOutput(context->op()));
+    CHECK(context->op()->ValueOutputCount() > 0);
     CHECK(IsDefUseChainLinkPresent(context, node));
     CHECK(IsUseDefChainLinkPresent(context, node));
   }
@@ -103,7 +161,7 @@
   // Verify all effect inputs actually have an effect.
   for (int i = 0; i < effect_count; ++i) {
     Node* effect = NodeProperties::GetEffectInput(node);
-    CHECK(OperatorProperties::HasEffectOutput(effect->op()));
+    CHECK(effect->op()->EffectOutputCount() > 0);
     CHECK(IsDefUseChainLinkPresent(effect, node));
     CHECK(IsUseDefChainLinkPresent(effect, node));
   }
@@ -111,18 +169,18 @@
   // Verify all control inputs are control nodes.
   for (int i = 0; i < control_count; ++i) {
     Node* control = NodeProperties::GetControlInput(node, i);
-    CHECK(OperatorProperties::HasControlOutput(control->op()));
+    CHECK(control->op()->ControlOutputCount() > 0);
     CHECK(IsDefUseChainLinkPresent(control, node));
     CHECK(IsUseDefChainLinkPresent(control, node));
   }
 
   // Verify all successors are projections if multiple value outputs exist.
-  if (OperatorProperties::GetValueOutputCount(node->op()) > 1) {
-    Node::Uses uses = node->uses();
-    for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) {
-      CHECK(!NodeProperties::IsValueEdge(it.edge()) ||
-            (*it)->opcode() == IrOpcode::kProjection ||
-            (*it)->opcode() == IrOpcode::kParameter);
+  if (node->op()->ValueOutputCount() > 1) {
+    for (Edge edge : node->use_edges()) {
+      Node* use = edge.from();
+      CHECK(!NodeProperties::IsValueEdge(edge) ||
+            use->opcode() == IrOpcode::kProjection ||
+            use->opcode() == IrOpcode::kParameter);
     }
   }
 
@@ -130,12 +188,17 @@
     case IrOpcode::kStart:
       // Start has no inputs.
       CHECK_EQ(0, input_count);
+      // Type is a tuple.
+      // TODO(rossberg): Multiple outputs are currently typed as Internal.
+      CheckUpperIs(node, Type::Internal());
       break;
     case IrOpcode::kEnd:
       // End has no outputs.
-      CHECK(!OperatorProperties::HasValueOutput(node->op()));
-      CHECK(!OperatorProperties::HasEffectOutput(node->op()));
-      CHECK(!OperatorProperties::HasControlOutput(node->op()));
+      CHECK(node->op()->ValueOutputCount() == 0);
+      CHECK(node->op()->EffectOutputCount() == 0);
+      CHECK(node->op()->ControlOutputCount() == 0);
+      // Type is empty.
+      CheckNotTyped(node);
       break;
     case IrOpcode::kDead:
       // Dead is never connected to the graph.
@@ -143,31 +206,50 @@
     case IrOpcode::kBranch: {
       // Branch uses are IfTrue and IfFalse.
       Node::Uses uses = node->uses();
-      bool got_true = false, got_false = false;
+      int count_true = 0, count_false = 0;
       for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) {
-        CHECK(((*it)->opcode() == IrOpcode::kIfTrue && !got_true) ||
-              ((*it)->opcode() == IrOpcode::kIfFalse && !got_false));
-        if ((*it)->opcode() == IrOpcode::kIfTrue) got_true = true;
-        if ((*it)->opcode() == IrOpcode::kIfFalse) got_false = true;
+        CHECK((*it)->opcode() == IrOpcode::kIfTrue ||
+              (*it)->opcode() == IrOpcode::kIfFalse);
+        if ((*it)->opcode() == IrOpcode::kIfTrue) ++count_true;
+        if ((*it)->opcode() == IrOpcode::kIfFalse) ++count_false;
       }
-      // TODO(rossberg): Currently fails for various tests.
-      // CHECK(got_true && got_false);
+      CHECK(count_true == 1 && count_false == 1);
+      // Type is empty.
+      CheckNotTyped(node);
       break;
     }
     case IrOpcode::kIfTrue:
     case IrOpcode::kIfFalse:
       CHECK_EQ(IrOpcode::kBranch,
                NodeProperties::GetControlInput(node, 0)->opcode());
+      // Type is empty.
+      CheckNotTyped(node);
       break;
     case IrOpcode::kLoop:
     case IrOpcode::kMerge:
+      CHECK_EQ(control_count, input_count);
+      // Type is empty.
+      CheckNotTyped(node);
       break;
     case IrOpcode::kReturn:
       // TODO(rossberg): check successor is End
+      // Type is empty.
+      CheckNotTyped(node);
       break;
     case IrOpcode::kThrow:
       // TODO(rossberg): what are the constraints on these?
+      // Type is empty.
+      CheckNotTyped(node);
       break;
+    case IrOpcode::kTerminate:
+      // Type is empty.
+      CheckNotTyped(node);
+      CHECK_EQ(1, control_count);
+      CHECK_EQ(input_count, 1 + effect_count);
+      break;
+
+    // Common operators
+    // ----------------
     case IrOpcode::kParameter: {
       // Parameters have the start node as inputs.
       CHECK_EQ(1, input_count);
@@ -177,95 +259,522 @@
       int index = OpParameter<int>(node);
       Node* input = NodeProperties::GetValueInput(node, 0);
       // Currently, parameter indices start at -1 instead of 0.
-      CHECK_GT(OperatorProperties::GetValueOutputCount(input->op()), index + 1);
+      CHECK_GT(input->op()->ValueOutputCount(), index + 1);
+      // Type can be anything.
+      CheckUpperIs(node, Type::Any());
       break;
     }
-    case IrOpcode::kInt32Constant:
+    case IrOpcode::kInt32Constant:  // TODO(rossberg): rename Word32Constant?
+      // Constants have no inputs.
+      CHECK_EQ(0, input_count);
+      // Type is a 32 bit integer, signed or unsigned.
+      CheckUpperIs(node, Type::Integral32());
+      break;
     case IrOpcode::kInt64Constant:
+      // Constants have no inputs.
+      CHECK_EQ(0, input_count);
+      // Type is internal.
+      // TODO(rossberg): Introduce proper Int64 type.
+      CheckUpperIs(node, Type::Internal());
+      break;
+    case IrOpcode::kFloat32Constant:
     case IrOpcode::kFloat64Constant:
-    case IrOpcode::kExternalConstant:
     case IrOpcode::kNumberConstant:
+      // Constants have no inputs.
+      CHECK_EQ(0, input_count);
+      // Type is a number.
+      CheckUpperIs(node, Type::Number());
+      break;
     case IrOpcode::kHeapConstant:
       // Constants have no inputs.
       CHECK_EQ(0, input_count);
+      // Type can be anything represented as a heap pointer.
+      CheckUpperIs(node, Type::TaggedPointer());
       break;
+    case IrOpcode::kExternalConstant:
+      // Constants have no inputs.
+      CHECK_EQ(0, input_count);
+      // Type is considered internal.
+      CheckUpperIs(node, Type::Internal());
+      break;
+    case IrOpcode::kProjection: {
+      // Projection has an input that produces enough values.
+      int index = static_cast<int>(OpParameter<size_t>(node->op()));
+      Node* input = NodeProperties::GetValueInput(node, 0);
+      CHECK_GT(input->op()->ValueOutputCount(), index);
+      // Type can be anything.
+      // TODO(rossberg): Introduce tuple types for this.
+      // TODO(titzer): Convince rossberg not to.
+      CheckUpperIs(node, Type::Any());
+      break;
+    }
+    case IrOpcode::kSelect: {
+      CHECK_EQ(0, effect_count);
+      CHECK_EQ(0, control_count);
+      CHECK_EQ(3, value_count);
+      break;
+    }
     case IrOpcode::kPhi: {
       // Phi input count matches parent control node.
+      CHECK_EQ(0, effect_count);
       CHECK_EQ(1, control_count);
       Node* control = NodeProperties::GetControlInput(node, 0);
-      CHECK_EQ(value_count,
-               OperatorProperties::GetControlInputCount(control->op()));
+      CHECK_EQ(value_count, control->op()->ControlInputCount());
+      CHECK_EQ(input_count, 1 + value_count);
+      // Type must be subsumed by all input types.
+      // TODO(rossberg): for now at least, narrowing does not really hold.
+      /*
+      for (int i = 0; i < value_count; ++i) {
+        // TODO(rossberg, jarin): Figure out what to do about lower bounds.
+        // CHECK(bounds(node).lower->Is(bounds(ValueInput(node, i)).lower));
+        CHECK(bounds(ValueInput(node, i)).upper->Is(bounds(node).upper));
+      }
+      */
       break;
     }
     case IrOpcode::kEffectPhi: {
       // EffectPhi input count matches parent control node.
+      CHECK_EQ(0, value_count);
       CHECK_EQ(1, control_count);
       Node* control = NodeProperties::GetControlInput(node, 0);
-      CHECK_EQ(effect_count,
-               OperatorProperties::GetControlInputCount(control->op()));
+      CHECK_EQ(effect_count, control->op()->ControlInputCount());
+      CHECK_EQ(input_count, 1 + effect_count);
+      break;
+    }
+    case IrOpcode::kValueEffect:
+      // TODO(rossberg): what are the constraints on these?
+      break;
+    case IrOpcode::kFinish: {
+      // TODO(rossberg): what are the constraints on these?
+      // Type must be subsumed by input type.
+      if (typing == TYPED) {
+        CHECK(bounds(ValueInput(node)).lower->Is(bounds(node).lower));
+        CHECK(bounds(ValueInput(node)).upper->Is(bounds(node).upper));
+      }
       break;
     }
     case IrOpcode::kFrameState:
       // TODO(jarin): what are the constraints on these?
       break;
+    case IrOpcode::kStateValues:
+      // TODO(jarin): what are the constraints on these?
+      break;
     case IrOpcode::kCall:
       // TODO(rossberg): what are the constraints on these?
       break;
-    case IrOpcode::kProjection: {
-      // Projection has an input that produces enough values.
-      size_t index = OpParameter<size_t>(node);
-      Node* input = NodeProperties::GetValueInput(node, 0);
-      CHECK_GT(OperatorProperties::GetValueOutputCount(input->op()),
-               static_cast<int>(index));
+
+    // JavaScript operators
+    // --------------------
+    case IrOpcode::kJSEqual:
+    case IrOpcode::kJSNotEqual:
+    case IrOpcode::kJSStrictEqual:
+    case IrOpcode::kJSStrictNotEqual:
+    case IrOpcode::kJSLessThan:
+    case IrOpcode::kJSGreaterThan:
+    case IrOpcode::kJSLessThanOrEqual:
+    case IrOpcode::kJSGreaterThanOrEqual:
+    case IrOpcode::kJSUnaryNot:
+      // Type is Boolean.
+      CheckUpperIs(node, Type::Boolean());
+      break;
+
+    case IrOpcode::kJSBitwiseOr:
+    case IrOpcode::kJSBitwiseXor:
+    case IrOpcode::kJSBitwiseAnd:
+    case IrOpcode::kJSShiftLeft:
+    case IrOpcode::kJSShiftRight:
+    case IrOpcode::kJSShiftRightLogical:
+      // Type is 32 bit integral.
+      CheckUpperIs(node, Type::Integral32());
+      break;
+    case IrOpcode::kJSAdd:
+      // Type is Number or String.
+      CheckUpperIs(node, Type::NumberOrString());
+      break;
+    case IrOpcode::kJSSubtract:
+    case IrOpcode::kJSMultiply:
+    case IrOpcode::kJSDivide:
+    case IrOpcode::kJSModulus:
+      // Type is Number.
+      CheckUpperIs(node, Type::Number());
+      break;
+
+    case IrOpcode::kJSToBoolean:
+      // Type is Boolean.
+      CheckUpperIs(node, Type::Boolean());
+      break;
+    case IrOpcode::kJSToNumber:
+      // Type is Number.
+      CheckUpperIs(node, Type::Number());
+      break;
+    case IrOpcode::kJSToString:
+      // Type is String.
+      CheckUpperIs(node, Type::String());
+      break;
+    case IrOpcode::kJSToName:
+      // Type is Name.
+      CheckUpperIs(node, Type::Name());
+      break;
+    case IrOpcode::kJSToObject:
+      // Type is Receiver.
+      CheckUpperIs(node, Type::Receiver());
+      break;
+
+    case IrOpcode::kJSCreate:
+      // Type is Object.
+      CheckUpperIs(node, Type::Object());
+      break;
+    case IrOpcode::kJSLoadProperty:
+    case IrOpcode::kJSLoadNamed:
+      // Type can be anything.
+      CheckUpperIs(node, Type::Any());
+      break;
+    case IrOpcode::kJSStoreProperty:
+    case IrOpcode::kJSStoreNamed:
+      // Type is empty.
+      CheckNotTyped(node);
+      break;
+    case IrOpcode::kJSDeleteProperty:
+    case IrOpcode::kJSHasProperty:
+    case IrOpcode::kJSInstanceOf:
+      // Type is Boolean.
+      CheckUpperIs(node, Type::Boolean());
+      break;
+    case IrOpcode::kJSTypeOf:
+      // Type is String.
+      CheckUpperIs(node, Type::String());
+      break;
+
+    case IrOpcode::kJSLoadContext:
+      // Type can be anything.
+      CheckUpperIs(node, Type::Any());
+      break;
+    case IrOpcode::kJSStoreContext:
+      // Type is empty.
+      CheckNotTyped(node);
+      break;
+    case IrOpcode::kJSCreateFunctionContext:
+    case IrOpcode::kJSCreateCatchContext:
+    case IrOpcode::kJSCreateWithContext:
+    case IrOpcode::kJSCreateBlockContext:
+    case IrOpcode::kJSCreateModuleContext:
+    case IrOpcode::kJSCreateScriptContext: {
+      // Type is Context, and operand is Internal.
+      Node* context = NodeProperties::GetContextInput(node);
+      // TODO(rossberg): This should really be Is(Internal), but the typer
+      // currently can't do backwards propagation.
+      CheckUpperMaybe(context, Type::Internal());
+      if (typing == TYPED) CHECK(bounds(node).upper->IsContext());
       break;
     }
-    default:
-      // TODO(rossberg): Check other node kinds.
+
+    case IrOpcode::kJSCallConstruct:
+      // Type is Receiver.
+      CheckUpperIs(node, Type::Receiver());
+      break;
+    case IrOpcode::kJSCallFunction:
+    case IrOpcode::kJSCallRuntime:
+    case IrOpcode::kJSYield:
+    case IrOpcode::kJSDebugger:
+      // Type can be anything.
+      CheckUpperIs(node, Type::Any());
+      break;
+
+    // Simplified operators
+    // -------------------------------
+    case IrOpcode::kAnyToBoolean:
+      // Type is Boolean.
+      CheckUpperIs(node, Type::Boolean());
+      break;
+    case IrOpcode::kBooleanNot:
+      // Boolean -> Boolean
+      CheckValueInputIs(node, 0, Type::Boolean());
+      CheckUpperIs(node, Type::Boolean());
+      break;
+    case IrOpcode::kBooleanToNumber:
+      // Boolean -> Number
+      CheckValueInputIs(node, 0, Type::Boolean());
+      CheckUpperIs(node, Type::Number());
+      break;
+    case IrOpcode::kNumberEqual:
+    case IrOpcode::kNumberLessThan:
+    case IrOpcode::kNumberLessThanOrEqual:
+      // (Number, Number) -> Boolean
+      CheckValueInputIs(node, 0, Type::Number());
+      CheckValueInputIs(node, 1, Type::Number());
+      CheckUpperIs(node, Type::Boolean());
+      break;
+    case IrOpcode::kNumberAdd:
+    case IrOpcode::kNumberSubtract:
+    case IrOpcode::kNumberMultiply:
+    case IrOpcode::kNumberDivide:
+    case IrOpcode::kNumberModulus:
+      // (Number, Number) -> Number
+      CheckValueInputIs(node, 0, Type::Number());
+      CheckValueInputIs(node, 1, Type::Number());
+      // TODO(rossberg): activate once we retype after opcode changes.
+      // CheckUpperIs(node, Type::Number());
+      break;
+    case IrOpcode::kNumberToInt32:
+      // Number -> Signed32
+      CheckValueInputIs(node, 0, Type::Number());
+      CheckUpperIs(node, Type::Signed32());
+      break;
+    case IrOpcode::kNumberToUint32:
+      // Number -> Unsigned32
+      CheckValueInputIs(node, 0, Type::Number());
+      CheckUpperIs(node, Type::Unsigned32());
+      break;
+    case IrOpcode::kStringEqual:
+    case IrOpcode::kStringLessThan:
+    case IrOpcode::kStringLessThanOrEqual:
+      // (String, String) -> Boolean
+      CheckValueInputIs(node, 0, Type::String());
+      CheckValueInputIs(node, 1, Type::String());
+      CheckUpperIs(node, Type::Boolean());
+      break;
+    case IrOpcode::kStringAdd:
+      // (String, String) -> String
+      CheckValueInputIs(node, 0, Type::String());
+      CheckValueInputIs(node, 1, Type::String());
+      CheckUpperIs(node, Type::String());
+      break;
+    case IrOpcode::kReferenceEqual: {
+      // (Unique, Any) -> Boolean  and
+      // (Any, Unique) -> Boolean
+      if (typing == TYPED) {
+        CHECK(bounds(ValueInput(node, 0)).upper->Is(Type::Unique()) ||
+              bounds(ValueInput(node, 1)).upper->Is(Type::Unique()));
+      }
+      CheckUpperIs(node, Type::Boolean());
+      break;
+    }
+    case IrOpcode::kObjectIsSmi:
+      CheckValueInputIs(node, 0, Type::Any());
+      CheckUpperIs(node, Type::Boolean());
+      break;
+    case IrOpcode::kObjectIsNonNegativeSmi:
+      CheckValueInputIs(node, 0, Type::Any());
+      CheckUpperIs(node, Type::Boolean());
+      break;
+
+    case IrOpcode::kChangeTaggedToInt32: {
+      // Signed32 /\ Tagged -> Signed32 /\ UntaggedInt32
+      // TODO(neis): Activate once ChangeRepresentation works in typer.
+      // Type* from = Type::Intersect(Type::Signed32(), Type::Tagged());
+      // Type* to = Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
+      // CheckValueInputIs(node, 0, from));
+      // CheckUpperIs(node, to));
+      break;
+    }
+    case IrOpcode::kChangeTaggedToUint32: {
+      // Unsigned32 /\ Tagged -> Unsigned32 /\ UntaggedInt32
+      // TODO(neis): Activate once ChangeRepresentation works in typer.
+      // Type* from = Type::Intersect(Type::Unsigned32(), Type::Tagged());
+      // Type* to =Type::Intersect(Type::Unsigned32(), Type::UntaggedInt32());
+      // CheckValueInputIs(node, 0, from));
+      // CheckUpperIs(node, to));
+      break;
+    }
+    case IrOpcode::kChangeTaggedToFloat64: {
+      // Number /\ Tagged -> Number /\ UntaggedFloat64
+      // TODO(neis): Activate once ChangeRepresentation works in typer.
+      // Type* from = Type::Intersect(Type::Number(), Type::Tagged());
+      // Type* to = Type::Intersect(Type::Number(), Type::UntaggedFloat64());
+      // CheckValueInputIs(node, 0, from));
+      // CheckUpperIs(node, to));
+      break;
+    }
+    case IrOpcode::kChangeInt32ToTagged: {
+      // Signed32 /\ UntaggedInt32 -> Signed32 /\ Tagged
+      // TODO(neis): Activate once ChangeRepresentation works in typer.
+      // Type* from =Type::Intersect(Type::Signed32(), Type::UntaggedInt32());
+      // Type* to = Type::Intersect(Type::Signed32(), Type::Tagged());
+      // CheckValueInputIs(node, 0, from));
+      // CheckUpperIs(node, to));
+      break;
+    }
+    case IrOpcode::kChangeUint32ToTagged: {
+      // Unsigned32 /\ UntaggedInt32 -> Unsigned32 /\ Tagged
+      // TODO(neis): Activate once ChangeRepresentation works in typer.
+      // Type* from=Type::Intersect(Type::Unsigned32(),Type::UntaggedInt32());
+      // Type* to = Type::Intersect(Type::Unsigned32(), Type::Tagged());
+      // CheckValueInputIs(node, 0, from));
+      // CheckUpperIs(node, to));
+      break;
+    }
+    case IrOpcode::kChangeFloat64ToTagged: {
+      // Number /\ UntaggedFloat64 -> Number /\ Tagged
+      // TODO(neis): Activate once ChangeRepresentation works in typer.
+      // Type* from =Type::Intersect(Type::Number(), Type::UntaggedFloat64());
+      // Type* to = Type::Intersect(Type::Number(), Type::Tagged());
+      // CheckValueInputIs(node, 0, from));
+      // CheckUpperIs(node, to));
+      break;
+    }
+    case IrOpcode::kChangeBoolToBit: {
+      // Boolean /\ TaggedPtr -> Boolean /\ UntaggedInt1
+      // TODO(neis): Activate once ChangeRepresentation works in typer.
+      // Type* from = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
+      // Type* to = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
+      // CheckValueInputIs(node, 0, from));
+      // CheckUpperIs(node, to));
+      break;
+    }
+    case IrOpcode::kChangeBitToBool: {
+      // Boolean /\ UntaggedInt1 -> Boolean /\ TaggedPtr
+      // TODO(neis): Activate once ChangeRepresentation works in typer.
+      // Type* from = Type::Intersect(Type::Boolean(), Type::UntaggedInt1());
+      // Type* to = Type::Intersect(Type::Boolean(), Type::TaggedPtr());
+      // CheckValueInputIs(node, 0, from));
+      // CheckUpperIs(node, to));
+      break;
+    }
+
+    case IrOpcode::kLoadField:
+      // Object -> fieldtype
+      // TODO(rossberg): activate once machine ops are typed.
+      // CheckValueInputIs(node, 0, Type::Object());
+      // CheckUpperIs(node, Field(node).type));
+      break;
+    case IrOpcode::kLoadBuffer:
+      break;
+    case IrOpcode::kLoadElement:
+      // Object -> elementtype
+      // TODO(rossberg): activate once machine ops are typed.
+      // CheckValueInputIs(node, 0, Type::Object());
+      // CheckUpperIs(node, Element(node).type));
+      break;
+    case IrOpcode::kStoreField:
+      // (Object, fieldtype) -> _|_
+      // TODO(rossberg): activate once machine ops are typed.
+      // CheckValueInputIs(node, 0, Type::Object());
+      // CheckValueInputIs(node, 1, Field(node).type));
+      CheckNotTyped(node);
+      break;
+    case IrOpcode::kStoreBuffer:
+      break;
+    case IrOpcode::kStoreElement:
+      // (Object, elementtype) -> _|_
+      // TODO(rossberg): activate once machine ops are typed.
+      // CheckValueInputIs(node, 0, Type::Object());
+      // CheckValueInputIs(node, 1, Element(node).type));
+      CheckNotTyped(node);
+      break;
+
+    // Machine operators
+    // -----------------------
+    case IrOpcode::kLoad:
+    case IrOpcode::kStore:
+    case IrOpcode::kWord32And:
+    case IrOpcode::kWord32Or:
+    case IrOpcode::kWord32Xor:
+    case IrOpcode::kWord32Shl:
+    case IrOpcode::kWord32Shr:
+    case IrOpcode::kWord32Sar:
+    case IrOpcode::kWord32Ror:
+    case IrOpcode::kWord32Equal:
+    case IrOpcode::kWord64And:
+    case IrOpcode::kWord64Or:
+    case IrOpcode::kWord64Xor:
+    case IrOpcode::kWord64Shl:
+    case IrOpcode::kWord64Shr:
+    case IrOpcode::kWord64Sar:
+    case IrOpcode::kWord64Ror:
+    case IrOpcode::kWord64Equal:
+    case IrOpcode::kInt32Add:
+    case IrOpcode::kInt32AddWithOverflow:
+    case IrOpcode::kInt32Sub:
+    case IrOpcode::kInt32SubWithOverflow:
+    case IrOpcode::kInt32Mul:
+    case IrOpcode::kInt32MulHigh:
+    case IrOpcode::kInt32Div:
+    case IrOpcode::kInt32Mod:
+    case IrOpcode::kInt32LessThan:
+    case IrOpcode::kInt32LessThanOrEqual:
+    case IrOpcode::kUint32Div:
+    case IrOpcode::kUint32Mod:
+    case IrOpcode::kUint32MulHigh:
+    case IrOpcode::kUint32LessThan:
+    case IrOpcode::kUint32LessThanOrEqual:
+    case IrOpcode::kInt64Add:
+    case IrOpcode::kInt64Sub:
+    case IrOpcode::kInt64Mul:
+    case IrOpcode::kInt64Div:
+    case IrOpcode::kInt64Mod:
+    case IrOpcode::kInt64LessThan:
+    case IrOpcode::kInt64LessThanOrEqual:
+    case IrOpcode::kUint64Div:
+    case IrOpcode::kUint64Mod:
+    case IrOpcode::kUint64LessThan:
+    case IrOpcode::kFloat64Add:
+    case IrOpcode::kFloat64Sub:
+    case IrOpcode::kFloat64Mul:
+    case IrOpcode::kFloat64Div:
+    case IrOpcode::kFloat64Mod:
+    case IrOpcode::kFloat64Sqrt:
+    case IrOpcode::kFloat64Floor:
+    case IrOpcode::kFloat64Ceil:
+    case IrOpcode::kFloat64RoundTruncate:
+    case IrOpcode::kFloat64RoundTiesAway:
+    case IrOpcode::kFloat64Equal:
+    case IrOpcode::kFloat64LessThan:
+    case IrOpcode::kFloat64LessThanOrEqual:
+    case IrOpcode::kTruncateInt64ToInt32:
+    case IrOpcode::kTruncateFloat64ToFloat32:
+    case IrOpcode::kTruncateFloat64ToInt32:
+    case IrOpcode::kChangeInt32ToInt64:
+    case IrOpcode::kChangeUint32ToUint64:
+    case IrOpcode::kChangeInt32ToFloat64:
+    case IrOpcode::kChangeUint32ToFloat64:
+    case IrOpcode::kChangeFloat32ToFloat64:
+    case IrOpcode::kChangeFloat64ToInt32:
+    case IrOpcode::kChangeFloat64ToUint32:
+    case IrOpcode::kLoadStackPointer:
+    case IrOpcode::kCheckedLoad:
+    case IrOpcode::kCheckedStore:
+      // TODO(rossberg): Check.
       break;
   }
-
-  if (from_start) {
-    reached_from_start.insert(node);
-  } else {
-    reached_from_end.insert(node);
-  }
-
-  return GenericGraphVisit::CONTINUE;
 }
 
 
-void Verifier::Run(Graph* graph) {
-  Visitor visitor(graph->zone());
-
+void Verifier::Run(Graph* graph, Typing typing) {
+  Visitor visitor(graph->zone(), typing);
   CHECK_NE(NULL, graph->start());
-  visitor.from_start = true;
-  graph->VisitNodeUsesFromStart(&visitor);
   CHECK_NE(NULL, graph->end());
-  visitor.from_start = false;
   graph->VisitNodeInputsFromEnd(&visitor);
-
-  // All control nodes reachable from end are reachable from start.
-  for (NodeSet::iterator it = visitor.reached_from_end.begin();
-       it != visitor.reached_from_end.end(); ++it) {
-    CHECK(!NodeProperties::IsControl(*it) ||
-          visitor.reached_from_start.count(*it));
-  }
 }
 
 
+// -----------------------------------------------------------------------------
+
 static bool HasDominatingDef(Schedule* schedule, Node* node,
                              BasicBlock* container, BasicBlock* use_block,
                              int use_pos) {
   BasicBlock* block = use_block;
   while (true) {
     while (use_pos >= 0) {
-      if (block->nodes_[use_pos] == node) return true;
+      if (block->NodeAt(use_pos) == node) return true;
       use_pos--;
     }
-    block = block->dominator_;
+    block = block->dominator();
     if (block == NULL) break;
-    use_pos = static_cast<int>(block->nodes_.size()) - 1;
-    if (node == block->control_input_) return true;
+    use_pos = static_cast<int>(block->NodeCount()) - 1;
+    if (node == block->control_input()) return true;
+  }
+  return false;
+}
+
+
+static bool Dominates(Schedule* schedule, Node* dominator, Node* dominatee) {
+  BasicBlock* dom = schedule->block(dominator);
+  BasicBlock* sub = schedule->block(dominatee);
+  while (sub != NULL) {
+    if (sub == dom) {
+      return true;
+    }
+    sub = sub->dominator();
   }
   return false;
 }
@@ -273,123 +782,146 @@
 
 static void CheckInputsDominate(Schedule* schedule, BasicBlock* block,
                                 Node* node, int use_pos) {
-  for (int j = OperatorProperties::GetValueInputCount(node->op()) - 1; j >= 0;
-       j--) {
+  for (int j = node->op()->ValueInputCount() - 1; j >= 0; j--) {
     BasicBlock* use_block = block;
     if (node->opcode() == IrOpcode::kPhi) {
       use_block = use_block->PredecessorAt(j);
-      use_pos = static_cast<int>(use_block->nodes_.size()) - 1;
+      use_pos = static_cast<int>(use_block->NodeCount()) - 1;
     }
     Node* input = node->InputAt(j);
     if (!HasDominatingDef(schedule, node->InputAt(j), block, use_block,
                           use_pos)) {
       V8_Fatal(__FILE__, __LINE__,
                "Node #%d:%s in B%d is not dominated by input@%d #%d:%s",
-               node->id(), node->op()->mnemonic(), block->id(), j, input->id(),
-               input->op()->mnemonic());
+               node->id(), node->op()->mnemonic(), block->id().ToInt(), j,
+               input->id(), input->op()->mnemonic());
+    }
+  }
+  // Ensure that nodes are dominated by their control inputs;
+  // kEnd is an exception, as unreachable blocks resulting from kMerge
+  // are not in the RPO.
+  if (node->op()->ControlInputCount() == 1 &&
+      node->opcode() != IrOpcode::kEnd) {
+    Node* ctl = NodeProperties::GetControlInput(node);
+    if (!Dominates(schedule, ctl, node)) {
+      V8_Fatal(__FILE__, __LINE__,
+               "Node #%d:%s in B%d is not dominated by control input #%d:%s",
+               node->id(), node->op()->mnemonic(), block->id(), ctl->id(),
+               ctl->op()->mnemonic());
     }
   }
 }
 
 
 void ScheduleVerifier::Run(Schedule* schedule) {
-  const int count = schedule->BasicBlockCount();
+  const size_t count = schedule->BasicBlockCount();
   Zone tmp_zone(schedule->zone()->isolate());
   Zone* zone = &tmp_zone;
   BasicBlock* start = schedule->start();
   BasicBlockVector* rpo_order = schedule->rpo_order();
 
   // Verify the RPO order contains only blocks from this schedule.
-  CHECK_GE(count, static_cast<int>(rpo_order->size()));
+  CHECK_GE(count, rpo_order->size());
   for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
        ++b) {
     CHECK_EQ((*b), schedule->GetBlockById((*b)->id()));
+    // All predecessors and successors should be in rpo and in this schedule.
+    for (BasicBlock::Predecessors::iterator j = (*b)->predecessors_begin();
+         j != (*b)->predecessors_end(); ++j) {
+      CHECK_GE((*j)->rpo_number(), 0);
+      CHECK_EQ((*j), schedule->GetBlockById((*j)->id()));
+    }
+    for (BasicBlock::Successors::iterator j = (*b)->successors_begin();
+         j != (*b)->successors_end(); ++j) {
+      CHECK_GE((*j)->rpo_number(), 0);
+      CHECK_EQ((*j), schedule->GetBlockById((*j)->id()));
+    }
   }
 
   // Verify RPO numbers of blocks.
   CHECK_EQ(start, rpo_order->at(0));  // Start should be first.
   for (size_t b = 0; b < rpo_order->size(); b++) {
     BasicBlock* block = rpo_order->at(b);
-    CHECK_EQ(static_cast<int>(b), block->rpo_number_);
-    BasicBlock* dom = block->dominator_;
+    CHECK_EQ(static_cast<int>(b), block->rpo_number());
+    BasicBlock* dom = block->dominator();
     if (b == 0) {
       // All blocks except start should have a dominator.
       CHECK_EQ(NULL, dom);
     } else {
       // Check that the immediate dominator appears somewhere before the block.
       CHECK_NE(NULL, dom);
-      CHECK_LT(dom->rpo_number_, block->rpo_number_);
+      CHECK_LT(dom->rpo_number(), block->rpo_number());
     }
   }
 
   // Verify that all blocks reachable from start are in the RPO.
-  BoolVector marked(count, false, zone);
+  BoolVector marked(static_cast<int>(count), false, zone);
   {
     ZoneQueue<BasicBlock*> queue(zone);
     queue.push(start);
-    marked[start->id()] = true;
+    marked[start->id().ToSize()] = true;
     while (!queue.empty()) {
       BasicBlock* block = queue.front();
       queue.pop();
-      for (int s = 0; s < block->SuccessorCount(); s++) {
+      for (size_t s = 0; s < block->SuccessorCount(); s++) {
         BasicBlock* succ = block->SuccessorAt(s);
-        if (!marked[succ->id()]) {
-          marked[succ->id()] = true;
+        if (!marked[succ->id().ToSize()]) {
+          marked[succ->id().ToSize()] = true;
           queue.push(succ);
         }
       }
     }
   }
   // Verify marked blocks are in the RPO.
-  for (int i = 0; i < count; i++) {
-    BasicBlock* block = schedule->GetBlockById(i);
+  for (size_t i = 0; i < count; i++) {
+    BasicBlock* block = schedule->GetBlockById(BasicBlock::Id::FromSize(i));
     if (marked[i]) {
-      CHECK_GE(block->rpo_number_, 0);
-      CHECK_EQ(block, rpo_order->at(block->rpo_number_));
+      CHECK_GE(block->rpo_number(), 0);
+      CHECK_EQ(block, rpo_order->at(block->rpo_number()));
     }
   }
   // Verify RPO blocks are marked.
   for (size_t b = 0; b < rpo_order->size(); b++) {
-    CHECK(marked[rpo_order->at(b)->id()]);
+    CHECK(marked[rpo_order->at(b)->id().ToSize()]);
   }
 
   {
     // Verify the dominance relation.
-    ZoneList<BitVector*> dominators(count, zone);
-    dominators.Initialize(count, zone);
-    dominators.AddBlock(NULL, count, zone);
+    ZoneVector<BitVector*> dominators(zone);
+    dominators.resize(count, NULL);
 
     // Compute a set of all the nodes that dominate a given node by using
     // a forward fixpoint. O(n^2).
     ZoneQueue<BasicBlock*> queue(zone);
     queue.push(start);
-    dominators[start->id()] = new (zone) BitVector(count, zone);
+    dominators[start->id().ToSize()] =
+        new (zone) BitVector(static_cast<int>(count), zone);
     while (!queue.empty()) {
       BasicBlock* block = queue.front();
       queue.pop();
-      BitVector* block_doms = dominators[block->id()];
-      BasicBlock* idom = block->dominator_;
-      if (idom != NULL && !block_doms->Contains(idom->id())) {
+      BitVector* block_doms = dominators[block->id().ToSize()];
+      BasicBlock* idom = block->dominator();
+      if (idom != NULL && !block_doms->Contains(idom->id().ToInt())) {
         V8_Fatal(__FILE__, __LINE__, "Block B%d is not dominated by B%d",
-                 block->id(), idom->id());
+                 block->id().ToInt(), idom->id().ToInt());
       }
-      for (int s = 0; s < block->SuccessorCount(); s++) {
+      for (size_t s = 0; s < block->SuccessorCount(); s++) {
         BasicBlock* succ = block->SuccessorAt(s);
-        BitVector* succ_doms = dominators[succ->id()];
+        BitVector* succ_doms = dominators[succ->id().ToSize()];
 
         if (succ_doms == NULL) {
           // First time visiting the node. S.doms = B U B.doms
-          succ_doms = new (zone) BitVector(count, zone);
+          succ_doms = new (zone) BitVector(static_cast<int>(count), zone);
           succ_doms->CopyFrom(*block_doms);
-          succ_doms->Add(block->id());
-          dominators[succ->id()] = succ_doms;
+          succ_doms->Add(block->id().ToInt());
+          dominators[succ->id().ToSize()] = succ_doms;
           queue.push(succ);
         } else {
           // Nth time visiting the successor. S.doms = S.doms ^ (B U B.doms)
-          bool had = succ_doms->Contains(block->id());
-          if (had) succ_doms->Remove(block->id());
+          bool had = succ_doms->Contains(block->id().ToInt());
+          if (had) succ_doms->Remove(block->id().ToInt());
           if (succ_doms->IntersectIsChanged(*block_doms)) queue.push(succ);
-          if (had) succ_doms->Add(block->id());
+          if (had) succ_doms->Add(block->id().ToInt());
         }
       }
     }
@@ -398,16 +930,18 @@
     for (BasicBlockVector::iterator b = rpo_order->begin();
          b != rpo_order->end(); ++b) {
       BasicBlock* block = *b;
-      BasicBlock* idom = block->dominator_;
+      BasicBlock* idom = block->dominator();
       if (idom == NULL) continue;
-      BitVector* block_doms = dominators[block->id()];
+      BitVector* block_doms = dominators[block->id().ToSize()];
 
       for (BitVector::Iterator it(block_doms); !it.Done(); it.Advance()) {
-        BasicBlock* dom = schedule->GetBlockById(it.Current());
-        if (dom != idom && !dominators[idom->id()]->Contains(dom->id())) {
+        BasicBlock* dom =
+            schedule->GetBlockById(BasicBlock::Id::FromInt(it.Current()));
+        if (dom != idom &&
+            !dominators[idom->id().ToSize()]->Contains(dom->id().ToInt())) {
           V8_Fatal(__FILE__, __LINE__,
-                   "Block B%d is not immediately dominated by B%d", block->id(),
-                   idom->id());
+                   "Block B%d is not immediately dominated by B%d",
+                   block->id().ToInt(), idom->id().ToInt());
         }
       }
     }
@@ -421,8 +955,7 @@
       if (phi->opcode() != IrOpcode::kPhi) continue;
       // TODO(titzer): Nasty special case. Phis from RawMachineAssembler
       // schedules don't have control inputs.
-      if (phi->InputCount() >
-          OperatorProperties::GetValueInputCount(phi->op())) {
+      if (phi->InputCount() > phi->op()->ValueInputCount()) {
         Node* control = NodeProperties::GetControlInput(phi);
         CHECK(control->opcode() == IrOpcode::kMerge ||
               control->opcode() == IrOpcode::kLoop);
@@ -437,15 +970,15 @@
     BasicBlock* block = *b;
 
     // Check inputs to control for this block.
-    Node* control = block->control_input_;
+    Node* control = block->control_input();
     if (control != NULL) {
       CHECK_EQ(block, schedule->block(control));
       CheckInputsDominate(schedule, block, control,
-                          static_cast<int>(block->nodes_.size()) - 1);
+                          static_cast<int>(block->NodeCount()) - 1);
     }
     // Check inputs for all nodes in the block.
-    for (size_t i = 0; i < block->nodes_.size(); i++) {
-      Node* node = block->nodes_[i];
+    for (size_t i = 0; i < block->NodeCount(); i++) {
+      Node* node = block->NodeAt(i);
       CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1);
     }
   }
diff --git a/src/compiler/verifier.h b/src/compiler/verifier.h
index b5c028e..67b7ba6 100644
--- a/src/compiler/verifier.h
+++ b/src/compiler/verifier.h
@@ -18,7 +18,9 @@
 // each node, etc.
 class Verifier {
  public:
-  static void Run(Graph* graph);
+  enum Typing { TYPED, UNTYPED };
+
+  static void Run(Graph* graph, Typing typing = TYPED);
 
  private:
   class Visitor;
diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc
index f71d3bf..0480f9d 100644
--- a/src/compiler/x64/code-generator-x64.cc
+++ b/src/compiler/x64/code-generator-x64.cc
@@ -19,186 +19,487 @@
 #define __ masm()->
 
 
-// TODO(turbofan): Cleanup these hacks.
-enum Immediate64Type { kImm64Value, kImm64Handle, kImm64Reference };
-
-
-struct Immediate64 {
-  uint64_t value;
-  Handle<Object> handle;
-  ExternalReference reference;
-  Immediate64Type type;
-};
-
-
-enum RegisterOrOperandType { kRegister, kDoubleRegister, kOperand };
-
-
-struct RegisterOrOperand {
-  RegisterOrOperand() : operand(no_reg, 0) {}
-  Register reg;
-  DoubleRegister double_reg;
-  Operand operand;
-  RegisterOrOperandType type;
-};
-
-
 // Adds X64 specific methods for decoding operands.
 class X64OperandConverter : public InstructionOperandConverter {
  public:
   X64OperandConverter(CodeGenerator* gen, Instruction* instr)
       : InstructionOperandConverter(gen, instr) {}
 
-  RegisterOrOperand InputRegisterOrOperand(int index) {
-    return ToRegisterOrOperand(instr_->InputAt(index));
-  }
-
   Immediate InputImmediate(int index) {
     return ToImmediate(instr_->InputAt(index));
   }
 
-  RegisterOrOperand OutputRegisterOrOperand() {
-    return ToRegisterOrOperand(instr_->Output());
-  }
+  Operand InputOperand(int index) { return ToOperand(instr_->InputAt(index)); }
 
-  Immediate64 InputImmediate64(int index) {
-    return ToImmediate64(instr_->InputAt(index));
-  }
-
-  Immediate64 ToImmediate64(InstructionOperand* operand) {
-    Constant constant = ToConstant(operand);
-    Immediate64 immediate;
-    immediate.value = 0xbeefdeaddeefbeed;
-    immediate.type = kImm64Value;
-    switch (constant.type()) {
-      case Constant::kInt32:
-      case Constant::kInt64:
-        immediate.value = constant.ToInt64();
-        return immediate;
-      case Constant::kFloat64:
-        immediate.type = kImm64Handle;
-        immediate.handle =
-            isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED);
-        return immediate;
-      case Constant::kExternalReference:
-        immediate.type = kImm64Reference;
-        immediate.reference = constant.ToExternalReference();
-        return immediate;
-      case Constant::kHeapObject:
-        immediate.type = kImm64Handle;
-        immediate.handle = constant.ToHeapObject();
-        return immediate;
-    }
-    UNREACHABLE();
-    return immediate;
-  }
+  Operand OutputOperand() { return ToOperand(instr_->Output()); }
 
   Immediate ToImmediate(InstructionOperand* operand) {
-    Constant constant = ToConstant(operand);
-    switch (constant.type()) {
-      case Constant::kInt32:
-        return Immediate(constant.ToInt32());
-      case Constant::kInt64:
-      case Constant::kFloat64:
-      case Constant::kExternalReference:
-      case Constant::kHeapObject:
-        break;
-    }
-    UNREACHABLE();
-    return Immediate(-1);
+    return Immediate(ToConstant(operand).ToInt32());
   }
 
   Operand ToOperand(InstructionOperand* op, int extra = 0) {
-    RegisterOrOperand result = ToRegisterOrOperand(op, extra);
-    DCHECK_EQ(kOperand, result.type);
-    return result.operand;
-  }
-
-  RegisterOrOperand ToRegisterOrOperand(InstructionOperand* op, int extra = 0) {
-    RegisterOrOperand result;
-    if (op->IsRegister()) {
-      DCHECK(extra == 0);
-      result.type = kRegister;
-      result.reg = ToRegister(op);
-      return result;
-    } else if (op->IsDoubleRegister()) {
-      DCHECK(extra == 0);
-      DCHECK(extra == 0);
-      result.type = kDoubleRegister;
-      result.double_reg = ToDoubleRegister(op);
-      return result;
-    }
-
     DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
-
-    result.type = kOperand;
     // The linkage computes where all spill slots are located.
     FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), extra);
-    result.operand =
-        Operand(offset.from_stack_pointer() ? rsp : rbp, offset.offset());
-    return result;
+    return Operand(offset.from_stack_pointer() ? rsp : rbp, offset.offset());
   }
 
-  Operand MemoryOperand(int* first_input) {
-    const int offset = *first_input;
-    switch (AddressingModeField::decode(instr_->opcode())) {
-      case kMode_MR1I: {
-        *first_input += 2;
-        Register index = InputRegister(offset + 1);
-        return Operand(InputRegister(offset + 0), index, times_1,
-                       0);  // TODO(dcarney): K != 0
+  static int NextOffset(int* offset) {
+    int i = *offset;
+    (*offset)++;
+    return i;
+  }
+
+  static ScaleFactor ScaleFor(AddressingMode one, AddressingMode mode) {
+    STATIC_ASSERT(0 == static_cast<int>(times_1));
+    STATIC_ASSERT(1 == static_cast<int>(times_2));
+    STATIC_ASSERT(2 == static_cast<int>(times_4));
+    STATIC_ASSERT(3 == static_cast<int>(times_8));
+    int scale = static_cast<int>(mode - one);
+    DCHECK(scale >= 0 && scale < 4);
+    return static_cast<ScaleFactor>(scale);
+  }
+
+  Operand MemoryOperand(int* offset) {
+    AddressingMode mode = AddressingModeField::decode(instr_->opcode());
+    switch (mode) {
+      case kMode_MR: {
+        Register base = InputRegister(NextOffset(offset));
+        int32_t disp = 0;
+        return Operand(base, disp);
       }
-      case kMode_MRI:
-        *first_input += 2;
-        return Operand(InputRegister(offset + 0), InputInt32(offset + 1));
-      default:
+      case kMode_MRI: {
+        Register base = InputRegister(NextOffset(offset));
+        int32_t disp = InputInt32(NextOffset(offset));
+        return Operand(base, disp);
+      }
+      case kMode_MR1:
+      case kMode_MR2:
+      case kMode_MR4:
+      case kMode_MR8: {
+        Register base = InputRegister(NextOffset(offset));
+        Register index = InputRegister(NextOffset(offset));
+        ScaleFactor scale = ScaleFor(kMode_MR1, mode);
+        int32_t disp = 0;
+        return Operand(base, index, scale, disp);
+      }
+      case kMode_MR1I:
+      case kMode_MR2I:
+      case kMode_MR4I:
+      case kMode_MR8I: {
+        Register base = InputRegister(NextOffset(offset));
+        Register index = InputRegister(NextOffset(offset));
+        ScaleFactor scale = ScaleFor(kMode_MR1I, mode);
+        int32_t disp = InputInt32(NextOffset(offset));
+        return Operand(base, index, scale, disp);
+      }
+      case kMode_M1: {
+        Register base = InputRegister(NextOffset(offset));
+        int32_t disp = 0;
+        return Operand(base, disp);
+      }
+      case kMode_M2:
+        UNREACHABLE();  // Should use kModeMR with more compact encoding instead
+        return Operand(no_reg, 0);
+      case kMode_M4:
+      case kMode_M8: {
+        Register index = InputRegister(NextOffset(offset));
+        ScaleFactor scale = ScaleFor(kMode_M1, mode);
+        int32_t disp = 0;
+        return Operand(index, scale, disp);
+      }
+      case kMode_M1I:
+      case kMode_M2I:
+      case kMode_M4I:
+      case kMode_M8I: {
+        Register index = InputRegister(NextOffset(offset));
+        ScaleFactor scale = ScaleFor(kMode_M1I, mode);
+        int32_t disp = InputInt32(NextOffset(offset));
+        return Operand(index, scale, disp);
+      }
+      case kMode_None:
         UNREACHABLE();
         return Operand(no_reg, 0);
     }
+    UNREACHABLE();
+    return Operand(no_reg, 0);
   }
 
-  Operand MemoryOperand() {
-    int first_input = 0;
+  Operand MemoryOperand(int first_input = 0) {
     return MemoryOperand(&first_input);
   }
 };
 
 
-static bool HasImmediateInput(Instruction* instr, int index) {
+namespace {
+
+bool HasImmediateInput(Instruction* instr, int index) {
   return instr->InputAt(index)->IsImmediate();
 }
 
 
-#define ASSEMBLE_BINOP(asm_instr)                            \
-  do {                                                       \
-    if (HasImmediateInput(instr, 1)) {                       \
-      RegisterOrOperand input = i.InputRegisterOrOperand(0); \
-      if (input.type == kRegister) {                         \
-        __ asm_instr(input.reg, i.InputImmediate(1));        \
-      } else {                                               \
-        __ asm_instr(input.operand, i.InputImmediate(1));    \
-      }                                                      \
-    } else {                                                 \
-      RegisterOrOperand input = i.InputRegisterOrOperand(1); \
-      if (input.type == kRegister) {                         \
-        __ asm_instr(i.InputRegister(0), input.reg);         \
-      } else {                                               \
-        __ asm_instr(i.InputRegister(0), input.operand);     \
-      }                                                      \
-    }                                                        \
+class OutOfLineLoadZero FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadZero(CodeGenerator* gen, Register result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL { __ xorl(result_, result_); }
+
+ private:
+  Register const result_;
+};
+
+
+class OutOfLineLoadNaN FINAL : public OutOfLineCode {
+ public:
+  OutOfLineLoadNaN(CodeGenerator* gen, XMMRegister result)
+      : OutOfLineCode(gen), result_(result) {}
+
+  void Generate() FINAL { __ pcmpeqd(result_, result_); }
+
+ private:
+  XMMRegister const result_;
+};
+
+
+class OutOfLineTruncateDoubleToI FINAL : public OutOfLineCode {
+ public:
+  OutOfLineTruncateDoubleToI(CodeGenerator* gen, Register result,
+                             XMMRegister input)
+      : OutOfLineCode(gen), result_(result), input_(input) {}
+
+  void Generate() FINAL {
+    __ subp(rsp, Immediate(kDoubleSize));
+    __ movsd(MemOperand(rsp, 0), input_);
+    __ SlowTruncateToI(result_, rsp, 0);
+    __ addp(rsp, Immediate(kDoubleSize));
+  }
+
+ private:
+  Register const result_;
+  XMMRegister const input_;
+};
+
+}  // namespace
+
+
+#define ASSEMBLE_UNOP(asm_instr)         \
+  do {                                   \
+    if (instr->Output()->IsRegister()) { \
+      __ asm_instr(i.OutputRegister());  \
+    } else {                             \
+      __ asm_instr(i.OutputOperand());   \
+    }                                    \
   } while (0)
 
 
-#define ASSEMBLE_SHIFT(asm_instr, width)                                 \
-  do {                                                                   \
-    if (HasImmediateInput(instr, 1)) {                                   \
-      __ asm_instr(i.OutputRegister(), Immediate(i.InputInt##width(1))); \
-    } else {                                                             \
-      __ asm_instr##_cl(i.OutputRegister());                             \
-    }                                                                    \
+#define ASSEMBLE_BINOP(asm_instr)                              \
+  do {                                                         \
+    if (HasImmediateInput(instr, 1)) {                         \
+      if (instr->InputAt(0)->IsRegister()) {                   \
+        __ asm_instr(i.InputRegister(0), i.InputImmediate(1)); \
+      } else {                                                 \
+        __ asm_instr(i.InputOperand(0), i.InputImmediate(1));  \
+      }                                                        \
+    } else {                                                   \
+      if (instr->InputAt(1)->IsRegister()) {                   \
+        __ asm_instr(i.InputRegister(0), i.InputRegister(1));  \
+      } else {                                                 \
+        __ asm_instr(i.InputRegister(0), i.InputOperand(1));   \
+      }                                                        \
+    }                                                          \
   } while (0)
 
 
+#define ASSEMBLE_MULT(asm_instr)                              \
+  do {                                                        \
+    if (HasImmediateInput(instr, 1)) {                        \
+      if (instr->InputAt(0)->IsRegister()) {                  \
+        __ asm_instr(i.OutputRegister(), i.InputRegister(0),  \
+                     i.InputImmediate(1));                    \
+      } else {                                                \
+        __ asm_instr(i.OutputRegister(), i.InputOperand(0),   \
+                     i.InputImmediate(1));                    \
+      }                                                       \
+    } else {                                                  \
+      if (instr->InputAt(1)->IsRegister()) {                  \
+        __ asm_instr(i.OutputRegister(), i.InputRegister(1)); \
+      } else {                                                \
+        __ asm_instr(i.OutputRegister(), i.InputOperand(1));  \
+      }                                                       \
+    }                                                         \
+  } while (0)
+
+
+#define ASSEMBLE_SHIFT(asm_instr, width)                                   \
+  do {                                                                     \
+    if (HasImmediateInput(instr, 1)) {                                     \
+      if (instr->Output()->IsRegister()) {                                 \
+        __ asm_instr(i.OutputRegister(), Immediate(i.InputInt##width(1))); \
+      } else {                                                             \
+        __ asm_instr(i.OutputOperand(), Immediate(i.InputInt##width(1)));  \
+      }                                                                    \
+    } else {                                                               \
+      if (instr->Output()->IsRegister()) {                                 \
+        __ asm_instr##_cl(i.OutputRegister());                             \
+      } else {                                                             \
+        __ asm_instr##_cl(i.OutputOperand());                              \
+      }                                                                    \
+    }                                                                      \
+  } while (0)
+
+
+#define ASSEMBLE_DOUBLE_BINOP(asm_instr)                                \
+  do {                                                                  \
+    if (instr->InputAt(1)->IsDoubleRegister()) {                        \
+      __ asm_instr(i.InputDoubleRegister(0), i.InputDoubleRegister(1)); \
+    } else {                                                            \
+      __ asm_instr(i.InputDoubleRegister(0), i.InputOperand(1));        \
+    }                                                                   \
+  } while (0)
+
+
+#define ASSEMBLE_AVX_DOUBLE_BINOP(asm_instr)                           \
+  do {                                                                 \
+    CpuFeatureScope avx_scope(masm(), AVX);                            \
+    if (instr->InputAt(1)->IsDoubleRegister()) {                       \
+      __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
+                   i.InputDoubleRegister(1));                          \
+    } else {                                                           \
+      __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \
+                   i.InputOperand(1));                                 \
+    }                                                                  \
+  } while (0)
+
+
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr)                               \
+  do {                                                                       \
+    auto result = i.OutputDoubleRegister();                                  \
+    auto buffer = i.InputRegister(0);                                        \
+    auto index1 = i.InputRegister(1);                                        \
+    auto index2 = i.InputInt32(2);                                           \
+    OutOfLineCode* ool;                                                      \
+    if (instr->InputAt(3)->IsRegister()) {                                   \
+      auto length = i.InputRegister(3);                                      \
+      DCHECK_EQ(0, index2);                                                  \
+      __ cmpl(index1, length);                                               \
+      ool = new (zone()) OutOfLineLoadNaN(this, result);                     \
+    } else {                                                                 \
+      auto length = i.InputInt32(3);                                         \
+      DCHECK_LE(index2, length);                                             \
+      __ cmpq(index1, Immediate(length - index2));                           \
+      class OutOfLineLoadFloat FINAL : public OutOfLineCode {                \
+       public:                                                               \
+        OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result,           \
+                           Register buffer, Register index1, int32_t index2, \
+                           int32_t length)                                   \
+            : OutOfLineCode(gen),                                            \
+              result_(result),                                               \
+              buffer_(buffer),                                               \
+              index1_(index1),                                               \
+              index2_(index2),                                               \
+              length_(length) {}                                             \
+                                                                             \
+        void Generate() FINAL {                                              \
+          __ leal(kScratchRegister, Operand(index1_, index2_));              \
+          __ pcmpeqd(result_, result_);                                      \
+          __ cmpl(kScratchRegister, Immediate(length_));                     \
+          __ j(above_equal, exit());                                         \
+          __ asm_instr(result_,                                              \
+                       Operand(buffer_, kScratchRegister, times_1, 0));      \
+        }                                                                    \
+                                                                             \
+       private:                                                              \
+        XMMRegister const result_;                                           \
+        Register const buffer_;                                              \
+        Register const index1_;                                              \
+        int32_t const index2_;                                               \
+        int32_t const length_;                                               \
+      };                                                                     \
+      ool = new (zone())                                                     \
+          OutOfLineLoadFloat(this, result, buffer, index1, index2, length);  \
+    }                                                                        \
+    __ j(above_equal, ool->entry());                                         \
+    __ asm_instr(result, Operand(buffer, index1, times_1, index2));          \
+    __ bind(ool->exit());                                                    \
+  } while (false)
+
+
+#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr)                               \
+  do {                                                                         \
+    auto result = i.OutputRegister();                                          \
+    auto buffer = i.InputRegister(0);                                          \
+    auto index1 = i.InputRegister(1);                                          \
+    auto index2 = i.InputInt32(2);                                             \
+    OutOfLineCode* ool;                                                        \
+    if (instr->InputAt(3)->IsRegister()) {                                     \
+      auto length = i.InputRegister(3);                                        \
+      DCHECK_EQ(0, index2);                                                    \
+      __ cmpl(index1, length);                                                 \
+      ool = new (zone()) OutOfLineLoadZero(this, result);                      \
+    } else {                                                                   \
+      auto length = i.InputInt32(3);                                           \
+      DCHECK_LE(index2, length);                                               \
+      __ cmpq(index1, Immediate(length - index2));                             \
+      class OutOfLineLoadInteger FINAL : public OutOfLineCode {                \
+       public:                                                                 \
+        OutOfLineLoadInteger(CodeGenerator* gen, Register result,              \
+                             Register buffer, Register index1, int32_t index2, \
+                             int32_t length)                                   \
+            : OutOfLineCode(gen),                                              \
+              result_(result),                                                 \
+              buffer_(buffer),                                                 \
+              index1_(index1),                                                 \
+              index2_(index2),                                                 \
+              length_(length) {}                                               \
+                                                                               \
+        void Generate() FINAL {                                                \
+          Label oob;                                                           \
+          __ leal(kScratchRegister, Operand(index1_, index2_));                \
+          __ cmpl(kScratchRegister, Immediate(length_));                       \
+          __ j(above_equal, &oob, Label::kNear);                               \
+          __ asm_instr(result_,                                                \
+                       Operand(buffer_, kScratchRegister, times_1, 0));        \
+          __ jmp(exit());                                                      \
+          __ bind(&oob);                                                       \
+          __ xorl(result_, result_);                                           \
+        }                                                                      \
+                                                                               \
+       private:                                                                \
+        Register const result_;                                                \
+        Register const buffer_;                                                \
+        Register const index1_;                                                \
+        int32_t const index2_;                                                 \
+        int32_t const length_;                                                 \
+      };                                                                       \
+      ool = new (zone())                                                       \
+          OutOfLineLoadInteger(this, result, buffer, index1, index2, length);  \
+    }                                                                          \
+    __ j(above_equal, ool->entry());                                           \
+    __ asm_instr(result, Operand(buffer, index1, times_1, index2));            \
+    __ bind(ool->exit());                                                      \
+  } while (false)
+
+
+#define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr)                              \
+  do {                                                                       \
+    auto buffer = i.InputRegister(0);                                        \
+    auto index1 = i.InputRegister(1);                                        \
+    auto index2 = i.InputInt32(2);                                           \
+    auto value = i.InputDoubleRegister(4);                                   \
+    if (instr->InputAt(3)->IsRegister()) {                                   \
+      auto length = i.InputRegister(3);                                      \
+      DCHECK_EQ(0, index2);                                                  \
+      Label done;                                                            \
+      __ cmpl(index1, length);                                               \
+      __ j(above_equal, &done, Label::kNear);                                \
+      __ asm_instr(Operand(buffer, index1, times_1, index2), value);         \
+      __ bind(&done);                                                        \
+    } else {                                                                 \
+      auto length = i.InputInt32(3);                                         \
+      DCHECK_LE(index2, length);                                             \
+      __ cmpq(index1, Immediate(length - index2));                           \
+      class OutOfLineStoreFloat FINAL : public OutOfLineCode {               \
+       public:                                                               \
+        OutOfLineStoreFloat(CodeGenerator* gen, Register buffer,             \
+                            Register index1, int32_t index2, int32_t length, \
+                            XMMRegister value)                               \
+            : OutOfLineCode(gen),                                            \
+              buffer_(buffer),                                               \
+              index1_(index1),                                               \
+              index2_(index2),                                               \
+              length_(length),                                               \
+              value_(value) {}                                               \
+                                                                             \
+        void Generate() FINAL {                                              \
+          __ leal(kScratchRegister, Operand(index1_, index2_));              \
+          __ cmpl(kScratchRegister, Immediate(length_));                     \
+          __ j(above_equal, exit());                                         \
+          __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0),       \
+                       value_);                                              \
+        }                                                                    \
+                                                                             \
+       private:                                                              \
+        Register const buffer_;                                              \
+        Register const index1_;                                              \
+        int32_t const index2_;                                               \
+        int32_t const length_;                                               \
+        XMMRegister const value_;                                            \
+      };                                                                     \
+      auto ool = new (zone())                                                \
+          OutOfLineStoreFloat(this, buffer, index1, index2, length, value);  \
+      __ j(above_equal, ool->entry());                                       \
+      __ asm_instr(Operand(buffer, index1, times_1, index2), value);         \
+      __ bind(ool->exit());                                                  \
+    }                                                                        \
+  } while (false)
+
+
+#define ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Value)                  \
+  do {                                                                         \
+    auto buffer = i.InputRegister(0);                                          \
+    auto index1 = i.InputRegister(1);                                          \
+    auto index2 = i.InputInt32(2);                                             \
+    if (instr->InputAt(3)->IsRegister()) {                                     \
+      auto length = i.InputRegister(3);                                        \
+      DCHECK_EQ(0, index2);                                                    \
+      Label done;                                                              \
+      __ cmpl(index1, length);                                                 \
+      __ j(above_equal, &done, Label::kNear);                                  \
+      __ asm_instr(Operand(buffer, index1, times_1, index2), value);           \
+      __ bind(&done);                                                          \
+    } else {                                                                   \
+      auto length = i.InputInt32(3);                                           \
+      DCHECK_LE(index2, length);                                               \
+      __ cmpq(index1, Immediate(length - index2));                             \
+      class OutOfLineStoreInteger FINAL : public OutOfLineCode {               \
+       public:                                                                 \
+        OutOfLineStoreInteger(CodeGenerator* gen, Register buffer,             \
+                              Register index1, int32_t index2, int32_t length, \
+                              Value value)                                     \
+            : OutOfLineCode(gen),                                              \
+              buffer_(buffer),                                                 \
+              index1_(index1),                                                 \
+              index2_(index2),                                                 \
+              length_(length),                                                 \
+              value_(value) {}                                                 \
+                                                                               \
+        void Generate() FINAL {                                                \
+          __ leal(kScratchRegister, Operand(index1_, index2_));                \
+          __ cmpl(kScratchRegister, Immediate(length_));                       \
+          __ j(above_equal, exit());                                           \
+          __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0),         \
+                       value_);                                                \
+        }                                                                      \
+                                                                               \
+       private:                                                                \
+        Register const buffer_;                                                \
+        Register const index1_;                                                \
+        int32_t const index2_;                                                 \
+        int32_t const length_;                                                 \
+        Value const value_;                                                    \
+      };                                                                       \
+      auto ool = new (zone())                                                  \
+          OutOfLineStoreInteger(this, buffer, index1, index2, length, value);  \
+      __ j(above_equal, ool->entry());                                         \
+      __ asm_instr(Operand(buffer, index1, times_1, index2), value);           \
+      __ bind(ool->exit());                                                    \
+    }                                                                          \
+  } while (false)
+
+
+#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr)                \
+  do {                                                           \
+    if (instr->InputAt(4)->IsRegister()) {                       \
+      Register value = i.InputRegister(4);                       \
+      ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Register);  \
+    } else {                                                     \
+      Immediate value = i.InputImmediate(4);                     \
+      ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Immediate); \
+    }                                                            \
+  } while (false)
+
+
 // Assembles an instruction after register allocation, producing machine code.
 void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
   X64OperandConverter i(this, instr);
@@ -230,7 +531,7 @@
       break;
     }
     case kArchJmp:
-      __ jmp(code_->GetLabel(i.InputBlock(0)));
+      AssembleArchJump(i.InputRpo(0));
       break;
     case kArchNop:
       // don't emit code for nops.
@@ -238,9 +539,19 @@
     case kArchRet:
       AssembleReturn();
       break;
-    case kArchTruncateDoubleToI:
-      __ TruncateDoubleToI(i.OutputRegister(), i.InputDoubleRegister(0));
+    case kArchStackPointer:
+      __ movq(i.OutputRegister(), rsp);
       break;
+    case kArchTruncateDoubleToI: {
+      auto result = i.OutputRegister();
+      auto input = i.InputDoubleRegister(0);
+      auto ool = new (zone()) OutOfLineTruncateDoubleToI(this, result, input);
+      __ cvttsd2siq(result, input);
+      __ cmpq(result, Immediate(1));
+      __ j(overflow, ool->entry());
+      __ bind(ool->exit());
+      break;
+    }
     case kX64Add32:
       ASSEMBLE_BINOP(addl);
       break;
@@ -272,39 +583,23 @@
       ASSEMBLE_BINOP(testq);
       break;
     case kX64Imul32:
-      if (HasImmediateInput(instr, 1)) {
-        RegisterOrOperand input = i.InputRegisterOrOperand(0);
-        if (input.type == kRegister) {
-          __ imull(i.OutputRegister(), input.reg, i.InputImmediate(1));
-        } else {
-          __ movq(kScratchRegister, input.operand);
-          __ imull(i.OutputRegister(), kScratchRegister, i.InputImmediate(1));
-        }
-      } else {
-        RegisterOrOperand input = i.InputRegisterOrOperand(1);
-        if (input.type == kRegister) {
-          __ imull(i.OutputRegister(), input.reg);
-        } else {
-          __ imull(i.OutputRegister(), input.operand);
-        }
-      }
+      ASSEMBLE_MULT(imull);
       break;
     case kX64Imul:
-      if (HasImmediateInput(instr, 1)) {
-        RegisterOrOperand input = i.InputRegisterOrOperand(0);
-        if (input.type == kRegister) {
-          __ imulq(i.OutputRegister(), input.reg, i.InputImmediate(1));
-        } else {
-          __ movq(kScratchRegister, input.operand);
-          __ imulq(i.OutputRegister(), kScratchRegister, i.InputImmediate(1));
-        }
+      ASSEMBLE_MULT(imulq);
+      break;
+    case kX64ImulHigh32:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ imull(i.InputRegister(1));
       } else {
-        RegisterOrOperand input = i.InputRegisterOrOperand(1);
-        if (input.type == kRegister) {
-          __ imulq(i.OutputRegister(), input.reg);
-        } else {
-          __ imulq(i.OutputRegister(), input.operand);
-        }
+        __ imull(i.InputOperand(1));
+      }
+      break;
+    case kX64UmulHigh32:
+      if (instr->InputAt(1)->IsRegister()) {
+        __ mull(i.InputRegister(1));
+      } else {
+        __ mull(i.InputOperand(1));
       }
       break;
     case kX64Idiv32:
@@ -323,42 +618,18 @@
       __ xorq(rdx, rdx);
       __ divq(i.InputRegister(1));
       break;
-    case kX64Not: {
-      RegisterOrOperand output = i.OutputRegisterOrOperand();
-      if (output.type == kRegister) {
-        __ notq(output.reg);
-      } else {
-        __ notq(output.operand);
-      }
+    case kX64Not:
+      ASSEMBLE_UNOP(notq);
       break;
-    }
-    case kX64Not32: {
-      RegisterOrOperand output = i.OutputRegisterOrOperand();
-      if (output.type == kRegister) {
-        __ notl(output.reg);
-      } else {
-        __ notl(output.operand);
-      }
+    case kX64Not32:
+      ASSEMBLE_UNOP(notl);
       break;
-    }
-    case kX64Neg: {
-      RegisterOrOperand output = i.OutputRegisterOrOperand();
-      if (output.type == kRegister) {
-        __ negq(output.reg);
-      } else {
-        __ negq(output.operand);
-      }
+    case kX64Neg:
+      ASSEMBLE_UNOP(negq);
       break;
-    }
-    case kX64Neg32: {
-      RegisterOrOperand output = i.OutputRegisterOrOperand();
-      if (output.type == kRegister) {
-        __ negl(output.reg);
-      } else {
-        __ negl(output.operand);
-      }
+    case kX64Neg32:
+      ASSEMBLE_UNOP(negl);
       break;
-    }
     case kX64Or32:
       ASSEMBLE_BINOP(orl);
       break;
@@ -395,26 +666,20 @@
     case kX64Ror:
       ASSEMBLE_SHIFT(rorq, 6);
       break;
-    case kSSEFloat64Cmp: {
-      RegisterOrOperand input = i.InputRegisterOrOperand(1);
-      if (input.type == kDoubleRegister) {
-        __ ucomisd(i.InputDoubleRegister(0), input.double_reg);
-      } else {
-        __ ucomisd(i.InputDoubleRegister(0), input.operand);
-      }
+    case kSSEFloat64Cmp:
+      ASSEMBLE_DOUBLE_BINOP(ucomisd);
       break;
-    }
     case kSSEFloat64Add:
-      __ addsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      ASSEMBLE_DOUBLE_BINOP(addsd);
       break;
     case kSSEFloat64Sub:
-      __ subsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      ASSEMBLE_DOUBLE_BINOP(subsd);
       break;
     case kSSEFloat64Mul:
-      __ mulsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      ASSEMBLE_DOUBLE_BINOP(mulsd);
       break;
     case kSSEFloat64Div:
-      __ divsd(i.InputDoubleRegister(0), i.InputDoubleRegister(1));
+      ASSEMBLE_DOUBLE_BINOP(divsd);
       break;
     case kSSEFloat64Mod: {
       __ subq(rsp, Immediate(kDoubleSize));
@@ -431,7 +696,8 @@
       __ fprem();
       // The following 2 instruction implicitly use rax.
       __ fnstsw_ax();
-      if (CpuFeatures::IsSupported(SAHF) && masm()->IsEnabled(SAHF)) {
+      if (CpuFeatures::IsSupported(SAHF)) {
+        CpuFeatureScope sahf_scope(masm(), SAHF);
         __ sahf();
       } else {
         __ shrl(rax, Immediate(8));
@@ -447,52 +713,97 @@
       __ addq(rsp, Immediate(kDoubleSize));
       break;
     }
-    case kSSEFloat64Sqrt: {
-      RegisterOrOperand input = i.InputRegisterOrOperand(0);
-      if (input.type == kDoubleRegister) {
-        __ sqrtsd(i.OutputDoubleRegister(), input.double_reg);
+    case kSSEFloat64Sqrt:
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ sqrtsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
       } else {
-        __ sqrtsd(i.OutputDoubleRegister(), input.operand);
+        __ sqrtsd(i.OutputDoubleRegister(), i.InputOperand(0));
       }
       break;
-    }
-    case kSSEFloat64ToInt32: {
-      RegisterOrOperand input = i.InputRegisterOrOperand(0);
-      if (input.type == kDoubleRegister) {
-        __ cvttsd2si(i.OutputRegister(), input.double_reg);
-      } else {
-        __ cvttsd2si(i.OutputRegister(), input.operand);
-      }
+    case kSSEFloat64Floor: {
+      CpuFeatureScope sse_scope(masm(), SSE4_1);
+      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                 v8::internal::Assembler::kRoundDown);
       break;
     }
+    case kSSEFloat64Ceil: {
+      CpuFeatureScope sse_scope(masm(), SSE4_1);
+      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                 v8::internal::Assembler::kRoundUp);
+      break;
+    }
+    case kSSEFloat64RoundTruncate: {
+      CpuFeatureScope sse_scope(masm(), SSE4_1);
+      __ roundsd(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
+                 v8::internal::Assembler::kRoundToZero);
+      break;
+    }
+    case kSSECvtss2sd:
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ cvtss2sd(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      } else {
+        __ cvtss2sd(i.OutputDoubleRegister(), i.InputOperand(0));
+      }
+      break;
+    case kSSECvtsd2ss:
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ cvtsd2ss(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
+      } else {
+        __ cvtsd2ss(i.OutputDoubleRegister(), i.InputOperand(0));
+      }
+      break;
+    case kSSEFloat64ToInt32:
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ cvttsd2si(i.OutputRegister(), i.InputDoubleRegister(0));
+      } else {
+        __ cvttsd2si(i.OutputRegister(), i.InputOperand(0));
+      }
+      break;
     case kSSEFloat64ToUint32: {
-      RegisterOrOperand input = i.InputRegisterOrOperand(0);
-      if (input.type == kDoubleRegister) {
-        __ cvttsd2siq(i.OutputRegister(), input.double_reg);
+      if (instr->InputAt(0)->IsDoubleRegister()) {
+        __ cvttsd2siq(i.OutputRegister(), i.InputDoubleRegister(0));
       } else {
-        __ cvttsd2siq(i.OutputRegister(), input.operand);
+        __ cvttsd2siq(i.OutputRegister(), i.InputOperand(0));
       }
-      __ andl(i.OutputRegister(), i.OutputRegister());  // clear upper bits.
-      // TODO(turbofan): generated code should not look at the upper 32 bits
-      // of the result, but those bits could escape to the outside world.
+      __ AssertZeroExtended(i.OutputRegister());
       break;
     }
-    case kSSEInt32ToFloat64: {
-      RegisterOrOperand input = i.InputRegisterOrOperand(0);
-      if (input.type == kRegister) {
-        __ cvtlsi2sd(i.OutputDoubleRegister(), input.reg);
+    case kSSEInt32ToFloat64:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ cvtlsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
       } else {
-        __ cvtlsi2sd(i.OutputDoubleRegister(), input.operand);
+        __ cvtlsi2sd(i.OutputDoubleRegister(), i.InputOperand(0));
       }
       break;
-    }
-    case kSSEUint32ToFloat64: {
-      // TODO(turbofan): X64 SSE cvtqsi2sd should support operands.
-      __ cvtqsi2sd(i.OutputDoubleRegister(), i.InputRegister(0));
+    case kSSEUint32ToFloat64:
+      if (instr->InputAt(0)->IsRegister()) {
+        __ movl(kScratchRegister, i.InputRegister(0));
+      } else {
+        __ movl(kScratchRegister, i.InputOperand(0));
+      }
+      __ cvtqsi2sd(i.OutputDoubleRegister(), kScratchRegister);
       break;
-    }
+    case kAVXFloat64Add:
+      ASSEMBLE_AVX_DOUBLE_BINOP(vaddsd);
+      break;
+    case kAVXFloat64Sub:
+      ASSEMBLE_AVX_DOUBLE_BINOP(vsubsd);
+      break;
+    case kAVXFloat64Mul:
+      ASSEMBLE_AVX_DOUBLE_BINOP(vmulsd);
+      break;
+    case kAVXFloat64Div:
+      ASSEMBLE_AVX_DOUBLE_BINOP(vdivsd);
+      break;
     case kX64Movsxbl:
-      __ movsxbl(i.OutputRegister(), i.MemoryOperand());
+      if (instr->addressing_mode() != kMode_None) {
+        __ movsxbl(i.OutputRegister(), i.MemoryOperand());
+      } else if (instr->InputAt(0)->IsRegister()) {
+        __ movsxbl(i.OutputRegister(), i.InputRegister(0));
+      } else {
+        __ movsxbl(i.OutputRegister(), i.InputOperand(0));
+      }
+      __ AssertZeroExtended(i.OutputRegister());
       break;
     case kX64Movzxbl:
       __ movzxbl(i.OutputRegister(), i.MemoryOperand());
@@ -508,10 +819,18 @@
       break;
     }
     case kX64Movsxwl:
-      __ movsxwl(i.OutputRegister(), i.MemoryOperand());
+      if (instr->addressing_mode() != kMode_None) {
+        __ movsxwl(i.OutputRegister(), i.MemoryOperand());
+      } else if (instr->InputAt(0)->IsRegister()) {
+        __ movsxwl(i.OutputRegister(), i.InputRegister(0));
+      } else {
+        __ movsxwl(i.OutputRegister(), i.InputOperand(0));
+      }
+      __ AssertZeroExtended(i.OutputRegister());
       break;
     case kX64Movzxwl:
       __ movzxwl(i.OutputRegister(), i.MemoryOperand());
+      __ AssertZeroExtended(i.OutputRegister());
       break;
     case kX64Movw: {
       int index = 0;
@@ -526,15 +845,15 @@
     case kX64Movl:
       if (instr->HasOutput()) {
         if (instr->addressing_mode() == kMode_None) {
-          RegisterOrOperand input = i.InputRegisterOrOperand(0);
-          if (input.type == kRegister) {
-            __ movl(i.OutputRegister(), input.reg);
+          if (instr->InputAt(0)->IsRegister()) {
+            __ movl(i.OutputRegister(), i.InputRegister(0));
           } else {
-            __ movl(i.OutputRegister(), input.operand);
+            __ movl(i.OutputRegister(), i.InputOperand(0));
           }
         } else {
           __ movl(i.OutputRegister(), i.MemoryOperand());
         }
+        __ AssertZeroExtended(i.OutputRegister());
       } else {
         int index = 0;
         Operand operand = i.MemoryOperand(&index);
@@ -546,11 +865,10 @@
       }
       break;
     case kX64Movsxlq: {
-      RegisterOrOperand input = i.InputRegisterOrOperand(0);
-      if (input.type == kRegister) {
-        __ movsxlq(i.OutputRegister(), input.reg);
+      if (instr->InputAt(0)->IsRegister()) {
+        __ movsxlq(i.OutputRegister(), i.InputRegister(0));
       } else {
-        __ movsxlq(i.OutputRegister(), input.operand);
+        __ movsxlq(i.OutputRegister(), i.InputOperand(0));
       }
       break;
     }
@@ -570,12 +888,10 @@
     case kX64Movss:
       if (instr->HasOutput()) {
         __ movss(i.OutputDoubleRegister(), i.MemoryOperand());
-        __ cvtss2sd(i.OutputDoubleRegister(), i.OutputDoubleRegister());
       } else {
         int index = 0;
         Operand operand = i.MemoryOperand(&index);
-        __ cvtsd2ss(xmm0, i.InputDoubleRegister(index));
-        __ movss(operand, xmm0);
+        __ movss(operand, i.InputDoubleRegister(index));
       }
       break;
     case kX64Movsd:
@@ -587,15 +903,57 @@
         __ movsd(operand, i.InputDoubleRegister(index));
       }
       break;
+    case kX64Lea32: {
+      AddressingMode mode = AddressingModeField::decode(instr->opcode());
+      // Shorten "leal" to "addl", "subl" or "shll" if the register allocation
+      // and addressing mode just happens to work out. The "addl"/"subl" forms
+      // in these cases are faster based on measurements.
+      if (i.InputRegister(0).is(i.OutputRegister())) {
+        if (mode == kMode_MRI) {
+          int32_t constant_summand = i.InputInt32(1);
+          if (constant_summand > 0) {
+            __ addl(i.OutputRegister(), Immediate(constant_summand));
+          } else if (constant_summand < 0) {
+            __ subl(i.OutputRegister(), Immediate(-constant_summand));
+          }
+        } else if (mode == kMode_MR1) {
+          if (i.InputRegister(1).is(i.OutputRegister())) {
+            __ shll(i.OutputRegister(), Immediate(1));
+          } else {
+            __ leal(i.OutputRegister(), i.MemoryOperand());
+          }
+        } else if (mode == kMode_M2) {
+          __ shll(i.OutputRegister(), Immediate(1));
+        } else if (mode == kMode_M4) {
+          __ shll(i.OutputRegister(), Immediate(2));
+        } else if (mode == kMode_M8) {
+          __ shll(i.OutputRegister(), Immediate(3));
+        } else {
+          __ leal(i.OutputRegister(), i.MemoryOperand());
+        }
+      } else {
+        __ leal(i.OutputRegister(), i.MemoryOperand());
+      }
+      __ AssertZeroExtended(i.OutputRegister());
+      break;
+    }
+    case kX64Lea:
+      __ leaq(i.OutputRegister(), i.MemoryOperand());
+      break;
+    case kX64Dec32:
+      __ decl(i.OutputRegister());
+      break;
+    case kX64Inc32:
+      __ incl(i.OutputRegister());
+      break;
     case kX64Push:
       if (HasImmediateInput(instr, 0)) {
         __ pushq(i.InputImmediate(0));
       } else {
-        RegisterOrOperand input = i.InputRegisterOrOperand(0);
-        if (input.type == kRegister) {
-          __ pushq(input.reg);
+        if (instr->InputAt(0)->IsRegister()) {
+          __ pushq(i.InputRegister(0));
         } else {
-          __ pushq(input.operand);
+          __ pushq(i.InputOperand(0));
         }
       }
       break;
@@ -606,31 +964,59 @@
       __ movsxlq(index, index);
       __ movq(Operand(object, index, times_1, 0), value);
       __ leaq(index, Operand(object, index, times_1, 0));
-      SaveFPRegsMode mode = code_->frame()->DidAllocateDoubleRegisters()
-                                ? kSaveFPRegs
-                                : kDontSaveFPRegs;
+      SaveFPRegsMode mode =
+          frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs;
       __ RecordWrite(object, index, value, mode);
       break;
     }
+    case kCheckedLoadInt8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movsxbl);
+      break;
+    case kCheckedLoadUint8:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movzxbl);
+      break;
+    case kCheckedLoadInt16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movsxwl);
+      break;
+    case kCheckedLoadUint16:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movzxwl);
+      break;
+    case kCheckedLoadWord32:
+      ASSEMBLE_CHECKED_LOAD_INTEGER(movl);
+      break;
+    case kCheckedLoadFloat32:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(movss);
+      break;
+    case kCheckedLoadFloat64:
+      ASSEMBLE_CHECKED_LOAD_FLOAT(movsd);
+      break;
+    case kCheckedStoreWord8:
+      ASSEMBLE_CHECKED_STORE_INTEGER(movb);
+      break;
+    case kCheckedStoreWord16:
+      ASSEMBLE_CHECKED_STORE_INTEGER(movw);
+      break;
+    case kCheckedStoreWord32:
+      ASSEMBLE_CHECKED_STORE_INTEGER(movl);
+      break;
+    case kCheckedStoreFloat32:
+      ASSEMBLE_CHECKED_STORE_FLOAT(movss);
+      break;
+    case kCheckedStoreFloat64:
+      ASSEMBLE_CHECKED_STORE_FLOAT(movsd);
+      break;
   }
 }
 
 
 // Assembles branches after this instruction.
-void CodeGenerator::AssembleArchBranch(Instruction* instr,
-                                       FlagsCondition condition) {
+void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
   X64OperandConverter i(this, instr);
-  Label done;
-
-  // Emit a branch. The true and false targets are always the last two inputs
-  // to the instruction.
-  BasicBlock* tblock = i.InputBlock(static_cast<int>(instr->InputCount()) - 2);
-  BasicBlock* fblock = i.InputBlock(static_cast<int>(instr->InputCount()) - 1);
-  bool fallthru = IsNextInAssemblyOrder(fblock);
-  Label* tlabel = code()->GetLabel(tblock);
-  Label* flabel = fallthru ? &done : code()->GetLabel(fblock);
-  Label::Distance flabel_distance = fallthru ? Label::kNear : Label::kFar;
-  switch (condition) {
+  Label::Distance flabel_distance =
+      branch->fallthru ? Label::kNear : Label::kFar;
+  Label* tlabel = branch->true_label;
+  Label* flabel = branch->false_label;
+  switch (branch->condition) {
     case kUnorderedEqual:
       __ j(parity_even, flabel, flabel_distance);
     // Fall through.
@@ -686,8 +1072,12 @@
       __ j(no_overflow, tlabel);
       break;
   }
-  if (!fallthru) __ jmp(flabel, flabel_distance);  // no fallthru to flabel.
-  __ bind(&done);
+  if (!branch->fallthru) __ jmp(flabel, flabel_distance);
+}
+
+
+void CodeGenerator::AssembleArchJump(BasicBlock::RpoNumber target) {
+  if (!IsNextInAssemblyOrder(target)) __ jmp(GetLabel(target));
 }
 
 
@@ -700,7 +1090,7 @@
   // Materialize a full 64-bit 1 or 0 value. The result register is always the
   // last output of the instruction.
   Label check;
-  DCHECK_NE(0, instr->OutputCount());
+  DCHECK_NE(0, static_cast<int>(instr->OutputCount()));
   Register reg = i.OutputRegister(static_cast<int>(instr->OutputCount() - 1));
   Condition cc = no_condition;
   switch (condition) {
@@ -802,27 +1192,10 @@
       frame()->SetRegisterSaveAreaSize(register_save_area_size);
     }
   } else if (descriptor->IsJSFunctionCall()) {
-    CompilationInfo* info = linkage()->info();
+    CompilationInfo* info = this->info();
     __ Prologue(info->IsCodePreAgingActive());
     frame()->SetRegisterSaveAreaSize(
         StandardFrameConstants::kFixedFrameSizeFromFp);
-
-    // Sloppy mode functions and builtins need to replace the receiver with the
-    // global proxy when called as functions (without an explicit receiver
-    // object).
-    // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
-    if (info->strict_mode() == SLOPPY && !info->is_native()) {
-      Label ok;
-      StackArgumentsAccessor args(rbp, info->scope()->num_parameters());
-      __ movp(rcx, args.GetReceiverOperand());
-      __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex);
-      __ j(not_equal, &ok, Label::kNear);
-      __ movp(rcx, GlobalObjectOperand());
-      __ movp(rcx, FieldOperand(rcx, GlobalObject::kGlobalProxyOffset));
-      __ movp(args.GetReceiverOperand(), rcx);
-      __ bind(&ok);
-    }
-
   } else {
     __ StubPrologue();
     frame()->SetRegisterSaveAreaSize(
@@ -899,31 +1272,57 @@
     }
   } else if (source->IsConstant()) {
     ConstantOperand* constant_source = ConstantOperand::cast(source);
+    Constant src = g.ToConstant(constant_source);
     if (destination->IsRegister() || destination->IsStackSlot()) {
       Register dst = destination->IsRegister() ? g.ToRegister(destination)
                                                : kScratchRegister;
-      Immediate64 imm = g.ToImmediate64(constant_source);
-      switch (imm.type) {
-        case kImm64Value:
-          __ Set(dst, imm.value);
+      switch (src.type()) {
+        case Constant::kInt32:
+          // TODO(dcarney): don't need scratch in this case.
+          __ Set(dst, src.ToInt32());
           break;
-        case kImm64Reference:
-          __ Move(dst, imm.reference);
+        case Constant::kInt64:
+          __ Set(dst, src.ToInt64());
           break;
-        case kImm64Handle:
-          __ Move(dst, imm.handle);
+        case Constant::kFloat32:
+          __ Move(dst,
+                  isolate()->factory()->NewNumber(src.ToFloat32(), TENURED));
+          break;
+        case Constant::kFloat64:
+          __ Move(dst,
+                  isolate()->factory()->NewNumber(src.ToFloat64(), TENURED));
+          break;
+        case Constant::kExternalReference:
+          __ Move(dst, src.ToExternalReference());
+          break;
+        case Constant::kHeapObject:
+          __ Move(dst, src.ToHeapObject());
+          break;
+        case Constant::kRpoNumber:
+          UNREACHABLE();  // TODO(dcarney): load of labels on x64.
           break;
       }
       if (destination->IsStackSlot()) {
         __ movq(g.ToOperand(destination), kScratchRegister);
       }
-    } else {
-      __ movq(kScratchRegister,
-              bit_cast<uint64_t, double>(g.ToDouble(constant_source)));
+    } else if (src.type() == Constant::kFloat32) {
+      // TODO(turbofan): Can we do better here?
+      uint32_t src_const = bit_cast<uint32_t>(src.ToFloat32());
       if (destination->IsDoubleRegister()) {
-        __ movq(g.ToDoubleRegister(destination), kScratchRegister);
+        __ Move(g.ToDoubleRegister(destination), src_const);
       } else {
         DCHECK(destination->IsDoubleStackSlot());
+        Operand dst = g.ToOperand(destination);
+        __ movl(dst, Immediate(src_const));
+      }
+    } else {
+      DCHECK_EQ(Constant::kFloat64, src.type());
+      uint64_t src_const = bit_cast<uint64_t>(src.ToFloat64());
+      if (destination->IsDoubleRegister()) {
+        __ Move(g.ToDoubleRegister(destination), src_const);
+      } else {
+        DCHECK(destination->IsDoubleStackSlot());
+        __ movq(kScratchRegister, src_const);
         __ movq(g.ToOperand(destination), kScratchRegister);
       }
     }
@@ -985,7 +1384,7 @@
     __ movsd(xmm0, src);
     __ movsd(src, dst);
     __ movsd(dst, xmm0);
-  } else if (source->IsDoubleRegister() && destination->IsDoubleRegister()) {
+  } else if (source->IsDoubleRegister() && destination->IsDoubleStackSlot()) {
     // XMM register-memory swap.  We rely on having xmm0
     // available as a fixed scratch register.
     XMMRegister src = g.ToDoubleRegister(source);
@@ -1005,7 +1404,7 @@
 
 void CodeGenerator::EnsureSpaceForLazyDeopt() {
   int space_needed = Deoptimizer::patch_size();
-  if (!linkage()->info()->IsStub()) {
+  if (!info()->IsStub()) {
     // Ensure that we have enough space after the previous lazy-bailout
     // instruction for patching the code here.
     int current_pc = masm()->pc_offset();
diff --git a/src/compiler/x64/instruction-codes-x64.h b/src/compiler/x64/instruction-codes-x64.h
index dfad203..77e3e52 100644
--- a/src/compiler/x64/instruction-codes-x64.h
+++ b/src/compiler/x64/instruction-codes-x64.h
@@ -28,6 +28,8 @@
   V(X64Sub32)                      \
   V(X64Imul)                       \
   V(X64Imul32)                     \
+  V(X64ImulHigh32)                 \
+  V(X64UmulHigh32)                 \
   V(X64Idiv)                       \
   V(X64Idiv32)                     \
   V(X64Udiv)                       \
@@ -51,10 +53,19 @@
   V(SSEFloat64Div)                 \
   V(SSEFloat64Mod)                 \
   V(SSEFloat64Sqrt)                \
+  V(SSEFloat64Floor)               \
+  V(SSEFloat64Ceil)                \
+  V(SSEFloat64RoundTruncate)       \
+  V(SSECvtss2sd)                   \
+  V(SSECvtsd2ss)                   \
   V(SSEFloat64ToInt32)             \
   V(SSEFloat64ToUint32)            \
   V(SSEInt32ToFloat64)             \
   V(SSEUint32ToFloat64)            \
+  V(AVXFloat64Add)                 \
+  V(AVXFloat64Sub)                 \
+  V(AVXFloat64Mul)                 \
+  V(AVXFloat64Div)                 \
   V(X64Movsxbl)                    \
   V(X64Movzxbl)                    \
   V(X64Movb)                       \
@@ -66,6 +77,10 @@
   V(X64Movq)                       \
   V(X64Movsd)                      \
   V(X64Movss)                      \
+  V(X64Lea32)                      \
+  V(X64Lea)                        \
+  V(X64Dec32)                      \
+  V(X64Inc32)                      \
   V(X64Push)                       \
   V(X64StoreWriteBarrier)
 
@@ -77,22 +92,30 @@
 //
 // We use the following local notation for addressing modes:
 //
-// R = register
-// O = register or stack slot
-// D = double register
-// I = immediate (handle, external, int32)
-// MR = [register]
-// MI = [immediate]
-// MRN = [register + register * N in {1, 2, 4, 8}]
-// MRI = [register + immediate]
-// MRNI = [register + register * N in {1, 2, 4, 8} + immediate]
+// M = memory operand
+// R = base register
+// N = index register * N for N in {1, 2, 4, 8}
+// I = immediate displacement (32-bit signed integer)
+
 #define TARGET_ADDRESSING_MODE_LIST(V) \
-  V(MR)   /* [%r1] */                  \
-  V(MRI)  /* [%r1 + K] */              \
-  V(MR1I) /* [%r1 + %r2 + K] */        \
+  V(MR)   /* [%r1            ] */      \
+  V(MRI)  /* [%r1         + K] */      \
+  V(MR1)  /* [%r1 + %r2*1    ] */      \
+  V(MR2)  /* [%r1 + %r2*2    ] */      \
+  V(MR4)  /* [%r1 + %r2*4    ] */      \
+  V(MR8)  /* [%r1 + %r2*8    ] */      \
+  V(MR1I) /* [%r1 + %r2*1 + K] */      \
   V(MR2I) /* [%r1 + %r2*2 + K] */      \
-  V(MR4I) /* [%r1 + %r2*4 + K] */      \
-  V(MR8I) /* [%r1 + %r2*8 + K] */
+  V(MR4I) /* [%r1 + %r2*3 + K] */      \
+  V(MR8I) /* [%r1 + %r2*4 + K] */      \
+  V(M1)   /* [      %r2*1    ] */      \
+  V(M2)   /* [      %r2*2    ] */      \
+  V(M4)   /* [      %r2*4    ] */      \
+  V(M8)   /* [      %r2*8    ] */      \
+  V(M1I)  /* [      %r2*1 + K] */      \
+  V(M2I)  /* [      %r2*2 + K] */      \
+  V(M4I)  /* [      %r2*4 + K] */      \
+  V(M8I)  /* [      %r2*8 + K] */
 
 }  // namespace compiler
 }  // namespace internal
diff --git a/src/compiler/x64/instruction-selector-x64-unittest.cc b/src/compiler/x64/instruction-selector-x64-unittest.cc
deleted file mode 100644
index 22f0bce..0000000
--- a/src/compiler/x64/instruction-selector-x64-unittest.cc
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/instruction-selector-unittest.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-// -----------------------------------------------------------------------------
-// Conversions.
-
-
-TEST_F(InstructionSelectorTest, ChangeInt32ToInt64WithParameter) {
-  StreamBuilder m(this, kMachInt64, kMachInt32);
-  m.Return(m.ChangeInt32ToInt64(m.Parameter(0)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kX64Movsxlq, s[0]->arch_opcode());
-}
-
-
-TEST_F(InstructionSelectorTest, ChangeUint32ToUint64WithParameter) {
-  StreamBuilder m(this, kMachUint64, kMachUint32);
-  m.Return(m.ChangeUint32ToUint64(m.Parameter(0)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kX64Movl, s[0]->arch_opcode());
-}
-
-
-TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithParameter) {
-  StreamBuilder m(this, kMachInt32, kMachInt64);
-  m.Return(m.TruncateInt64ToInt32(m.Parameter(0)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(kX64Movl, s[0]->arch_opcode());
-}
-
-
-// -----------------------------------------------------------------------------
-// Loads and stores
-
-namespace {
-
-struct MemoryAccess {
-  MachineType type;
-  ArchOpcode load_opcode;
-  ArchOpcode store_opcode;
-};
-
-
-std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
-  OStringStream ost;
-  ost << memacc.type;
-  return os << ost.c_str();
-}
-
-
-static const MemoryAccess kMemoryAccesses[] = {
-    {kMachInt8, kX64Movsxbl, kX64Movb},
-    {kMachUint8, kX64Movzxbl, kX64Movb},
-    {kMachInt16, kX64Movsxwl, kX64Movw},
-    {kMachUint16, kX64Movzxwl, kX64Movw},
-    {kMachInt32, kX64Movl, kX64Movl},
-    {kMachUint32, kX64Movl, kX64Movl},
-    {kMachInt64, kX64Movq, kX64Movq},
-    {kMachUint64, kX64Movq, kX64Movq},
-    {kMachFloat32, kX64Movss, kX64Movss},
-    {kMachFloat64, kX64Movsd, kX64Movsd}};
-
-}  // namespace
-
-
-typedef InstructionSelectorTestWithParam<MemoryAccess>
-    InstructionSelectorMemoryAccessTest;
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
-  const MemoryAccess memacc = GetParam();
-  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
-  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(2U, s[0]->InputCount());
-  EXPECT_EQ(1U, s[0]->OutputCount());
-}
-
-
-TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
-  const MemoryAccess memacc = GetParam();
-  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
-  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
-  m.Return(m.Int32Constant(0));
-  Stream s = m.Build();
-  ASSERT_EQ(1U, s.size());
-  EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
-  EXPECT_EQ(3U, s[0]->InputCount());
-  EXPECT_EQ(0U, s[0]->OutputCount());
-}
-
-
-INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
-                        InstructionSelectorMemoryAccessTest,
-                        ::testing::ValuesIn(kMemoryAccesses));
-
-}  // namespace compiler
-}  // namespace internal
-}  // namespace v8
diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc
index 5fe7bad..aba480d 100644
--- a/src/compiler/x64/instruction-selector-x64.cc
+++ b/src/compiler/x64/instruction-selector-x64.cc
@@ -20,37 +20,86 @@
                                            Register::ToAllocationIndex(reg));
   }
 
-  InstructionOperand* UseByteRegister(Node* node) {
-    // TODO(dcarney): relax constraint.
-    return UseFixed(node, rdx);
-  }
-
-  InstructionOperand* UseImmediate64(Node* node) { return UseImmediate(node); }
-
   bool CanBeImmediate(Node* node) {
     switch (node->opcode()) {
       case IrOpcode::kInt32Constant:
         return true;
+      case IrOpcode::kInt64Constant: {
+        const int64_t value = OpParameter<int64_t>(node);
+        return value == static_cast<int64_t>(static_cast<int32_t>(value));
+      }
       default:
         return false;
     }
   }
 
-  bool CanBeImmediate64(Node* node) {
-    switch (node->opcode()) {
-      case IrOpcode::kInt32Constant:
-        return true;
-      case IrOpcode::kNumberConstant:
-        return true;
-      case IrOpcode::kHeapConstant: {
-        // Constants in new space cannot be used as immediates in V8 because
-        // the GC does not scan code objects when collecting the new generation.
-        Unique<HeapObject> value = OpParameter<Unique<HeapObject> >(node);
-        return !isolate()->heap()->InNewSpace(*value.handle());
+  AddressingMode GenerateMemoryOperandInputs(Node* index, int scale_exponent,
+                                             Node* base, Node* displacement,
+                                             InstructionOperand* inputs[],
+                                             size_t* input_count) {
+    AddressingMode mode = kMode_MRI;
+    if (base != NULL) {
+      inputs[(*input_count)++] = UseRegister(base);
+      if (index != NULL) {
+        DCHECK(scale_exponent >= 0 && scale_exponent <= 3);
+        inputs[(*input_count)++] = UseRegister(index);
+        if (displacement != NULL) {
+          inputs[(*input_count)++] = UseImmediate(displacement);
+          static const AddressingMode kMRnI_modes[] = {kMode_MR1I, kMode_MR2I,
+                                                       kMode_MR4I, kMode_MR8I};
+          mode = kMRnI_modes[scale_exponent];
+        } else {
+          static const AddressingMode kMRn_modes[] = {kMode_MR1, kMode_MR2,
+                                                      kMode_MR4, kMode_MR8};
+          mode = kMRn_modes[scale_exponent];
+        }
+      } else {
+        if (displacement == NULL) {
+          mode = kMode_MR;
+        } else {
+          inputs[(*input_count)++] = UseImmediate(displacement);
+          mode = kMode_MRI;
+        }
       }
-      default:
-        return false;
+    } else {
+      DCHECK(index != NULL);
+      DCHECK(scale_exponent >= 0 && scale_exponent <= 3);
+      inputs[(*input_count)++] = UseRegister(index);
+      if (displacement != NULL) {
+        inputs[(*input_count)++] = UseImmediate(displacement);
+        static const AddressingMode kMnI_modes[] = {kMode_MRI, kMode_M2I,
+                                                    kMode_M4I, kMode_M8I};
+        mode = kMnI_modes[scale_exponent];
+      } else {
+        static const AddressingMode kMn_modes[] = {kMode_MR, kMode_MR1,
+                                                   kMode_M4, kMode_M8};
+        mode = kMn_modes[scale_exponent];
+        if (mode == kMode_MR1) {
+          // [%r1 + %r1*1] has a smaller encoding than [%r1*2+0]
+          inputs[(*input_count)++] = UseRegister(index);
+        }
+      }
     }
+    return mode;
+  }
+
+  AddressingMode GetEffectiveAddressMemoryOperand(Node* operand,
+                                                  InstructionOperand* inputs[],
+                                                  size_t* input_count) {
+    BaseWithIndexAndDisplacement64Matcher m(operand, true);
+    DCHECK(m.matches());
+    if ((m.displacement() == NULL || CanBeImmediate(m.displacement()))) {
+      return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(),
+                                         m.displacement(), inputs, input_count);
+    } else {
+      inputs[(*input_count)++] = UseRegister(operand->InputAt(0));
+      inputs[(*input_count)++] = UseRegister(operand->InputAt(1));
+      return kMode_MR1;
+    }
+  }
+
+  bool CanBeBetterLeftOperand(Node* node) const {
+    return !selector()->IsLive(node);
   }
 };
 
@@ -59,11 +108,8 @@
   MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node));
   MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node));
   X64OperandGenerator g(this);
-  Node* base = node->InputAt(0);
-  Node* index = node->InputAt(1);
 
   ArchOpcode opcode;
-  // TODO(titzer): signed/unsigned small loads
   switch (rep) {
     case kRepFloat32:
       opcode = kX64Movss;
@@ -89,18 +135,15 @@
       UNREACHABLE();
       return;
   }
-  if (g.CanBeImmediate(base)) {
-    // load [#base + %index]
-    Emit(opcode | AddressingModeField::encode(kMode_MRI),
-         g.DefineAsRegister(node), g.UseRegister(index), g.UseImmediate(base));
-  } else if (g.CanBeImmediate(index)) {  // load [%base + #index]
-    Emit(opcode | AddressingModeField::encode(kMode_MRI),
-         g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
-  } else {  // load [%base + %index + K]
-    Emit(opcode | AddressingModeField::encode(kMode_MR1I),
-         g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index));
-  }
-  // TODO(turbofan): addressing modes [r+r*{2,4,8}+K]
+
+  InstructionOperand* outputs[1];
+  outputs[0] = g.DefineAsRegister(node);
+  InstructionOperand* inputs[3];
+  size_t input_count = 0;
+  AddressingMode mode =
+      g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
+  InstructionCode code = opcode | AddressingModeField::encode(mode);
+  Emit(code, 1, outputs, input_count, inputs);
 }
 
 
@@ -124,14 +167,6 @@
     return;
   }
   DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind());
-  InstructionOperand* val;
-  if (g.CanBeImmediate(value)) {
-    val = g.UseImmediate(value);
-  } else if (rep == kRepWord8 || rep == kRepBit) {
-    val = g.UseByteRegister(value);
-  } else {
-    val = g.UseRegister(value);
-  }
   ArchOpcode opcode;
   switch (rep) {
     case kRepFloat32:
@@ -158,18 +193,112 @@
       UNREACHABLE();
       return;
   }
-  if (g.CanBeImmediate(base)) {
-    // store [#base + %index], %|#value
-    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
-         g.UseRegister(index), g.UseImmediate(base), val);
-  } else if (g.CanBeImmediate(index)) {  // store [%base + #index], %|#value
-    Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL,
-         g.UseRegister(base), g.UseImmediate(index), val);
-  } else {  // store [%base + %index], %|#value
-    Emit(opcode | AddressingModeField::encode(kMode_MR1I), NULL,
-         g.UseRegister(base), g.UseRegister(index), val);
+  InstructionOperand* inputs[4];
+  size_t input_count = 0;
+  AddressingMode mode =
+      g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count);
+  InstructionCode code = opcode | AddressingModeField::encode(mode);
+  InstructionOperand* value_operand =
+      g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
+  inputs[input_count++] = value_operand;
+  Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs);
+}
+
+
+void InstructionSelector::VisitCheckedLoad(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  MachineType typ = TypeOf(OpParameter<MachineType>(node));
+  X64OperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepWord8:
+      opcode = typ == kTypeInt32 ? kCheckedLoadInt8 : kCheckedLoadUint8;
+      break;
+    case kRepWord16:
+      opcode = typ == kTypeInt32 ? kCheckedLoadInt16 : kCheckedLoadUint16;
+      break;
+    case kRepWord32:
+      opcode = kCheckedLoadWord32;
+      break;
+    case kRepFloat32:
+      opcode = kCheckedLoadFloat32;
+      break;
+    case kRepFloat64:
+      opcode = kCheckedLoadFloat64;
+      break;
+    default:
+      UNREACHABLE();
+      return;
   }
-  // TODO(turbofan): addressing modes [r+r*{2,4,8}+K]
+  if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) {
+    Int32Matcher mlength(length);
+    Int32BinopMatcher moffset(offset);
+    if (mlength.HasValue() && moffset.right().HasValue() &&
+        moffset.right().Value() >= 0 &&
+        mlength.Value() >= moffset.right().Value()) {
+      Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer),
+           g.UseRegister(moffset.left().node()),
+           g.UseImmediate(moffset.right().node()), g.UseImmediate(length));
+      return;
+    }
+  }
+  InstructionOperand* length_operand =
+      g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
+  Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer),
+       g.UseRegister(offset), g.TempImmediate(0), length_operand);
+}
+
+
+void InstructionSelector::VisitCheckedStore(Node* node) {
+  MachineType rep = RepresentationOf(OpParameter<MachineType>(node));
+  X64OperandGenerator g(this);
+  Node* const buffer = node->InputAt(0);
+  Node* const offset = node->InputAt(1);
+  Node* const length = node->InputAt(2);
+  Node* const value = node->InputAt(3);
+  ArchOpcode opcode;
+  switch (rep) {
+    case kRepWord8:
+      opcode = kCheckedStoreWord8;
+      break;
+    case kRepWord16:
+      opcode = kCheckedStoreWord16;
+      break;
+    case kRepWord32:
+      opcode = kCheckedStoreWord32;
+      break;
+    case kRepFloat32:
+      opcode = kCheckedStoreFloat32;
+      break;
+    case kRepFloat64:
+      opcode = kCheckedStoreFloat64;
+      break;
+    default:
+      UNREACHABLE();
+      return;
+  }
+  InstructionOperand* value_operand =
+      g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value);
+  if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) {
+    Int32Matcher mlength(length);
+    Int32BinopMatcher moffset(offset);
+    if (mlength.HasValue() && moffset.right().HasValue() &&
+        moffset.right().Value() >= 0 &&
+        mlength.Value() >= moffset.right().Value()) {
+      Emit(opcode, nullptr, g.UseRegister(buffer),
+           g.UseRegister(moffset.left().node()),
+           g.UseImmediate(moffset.right().node()), g.UseImmediate(length),
+           value_operand);
+      return;
+    }
+  }
+  InstructionOperand* length_operand =
+      g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length);
+  Emit(opcode, nullptr, g.UseRegister(buffer), g.UseRegister(offset),
+       g.TempImmediate(0), length_operand, value_operand);
 }
 
 
@@ -178,20 +307,35 @@
                        InstructionCode opcode, FlagsContinuation* cont) {
   X64OperandGenerator g(selector);
   Int32BinopMatcher m(node);
+  Node* left = m.left().node();
+  Node* right = m.right().node();
   InstructionOperand* inputs[4];
   size_t input_count = 0;
   InstructionOperand* outputs[2];
   size_t output_count = 0;
 
   // TODO(turbofan): match complex addressing modes.
-  // TODO(turbofan): if commutative, pick the non-live-in operand as the left as
-  // this might be the last use and therefore its register can be reused.
-  if (g.CanBeImmediate(m.right().node())) {
-    inputs[input_count++] = g.Use(m.left().node());
-    inputs[input_count++] = g.UseImmediate(m.right().node());
+  if (left == right) {
+    // If both inputs refer to the same operand, enforce allocating a register
+    // for both of them to ensure that we don't end up generating code like
+    // this:
+    //
+    //   mov rax, [rbp-0x10]
+    //   add rax, [rbp-0x10]
+    //   jo label
+    InstructionOperand* const input = g.UseRegister(left);
+    inputs[input_count++] = input;
+    inputs[input_count++] = input;
+  } else if (g.CanBeImmediate(right)) {
+    inputs[input_count++] = g.UseRegister(left);
+    inputs[input_count++] = g.UseImmediate(right);
   } else {
-    inputs[input_count++] = g.UseRegister(m.left().node());
-    inputs[input_count++] = g.Use(m.right().node());
+    if (node->op()->HasProperty(Operator::kCommutative) &&
+        g.CanBeBetterLeftOperand(right)) {
+      std::swap(left, right);
+    }
+    inputs[input_count++] = g.UseRegister(left);
+    inputs[input_count++] = g.Use(right);
   }
 
   if (cont->IsBranch()) {
@@ -204,8 +348,8 @@
     outputs[output_count++] = g.DefineAsRegister(cont->result());
   }
 
-  DCHECK_NE(0, input_count);
-  DCHECK_NE(0, output_count);
+  DCHECK_NE(0, static_cast<int>(input_count));
+  DCHECK_NE(0, static_cast<int>(output_count));
   DCHECK_GE(arraysize(inputs), input_count);
   DCHECK_GE(arraysize(outputs), output_count);
 
@@ -247,7 +391,7 @@
   X64OperandGenerator g(this);
   Uint32BinopMatcher m(node);
   if (m.right().Is(-1)) {
-    Emit(kX64Not32, g.DefineSameAsFirst(node), g.Use(m.left().node()));
+    Emit(kX64Not32, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()));
   } else {
     VisitBinop(this, node, kX64Xor32);
   }
@@ -258,33 +402,28 @@
   X64OperandGenerator g(this);
   Uint64BinopMatcher m(node);
   if (m.right().Is(-1)) {
-    Emit(kX64Not, g.DefineSameAsFirst(node), g.Use(m.left().node()));
+    Emit(kX64Not, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()));
   } else {
     VisitBinop(this, node, kX64Xor);
   }
 }
 
 
+namespace {
+
 // Shared routine for multiple 32-bit shift operations.
 // TODO(bmeurer): Merge this with VisitWord64Shift using template magic?
-static void VisitWord32Shift(InstructionSelector* selector, Node* node,
-                             ArchOpcode opcode) {
+void VisitWord32Shift(InstructionSelector* selector, Node* node,
+                      ArchOpcode opcode) {
   X64OperandGenerator g(selector);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
+  Int32BinopMatcher m(node);
+  Node* left = m.left().node();
+  Node* right = m.right().node();
 
-  // TODO(turbofan): assembler only supports some addressing modes for shifts.
   if (g.CanBeImmediate(right)) {
     selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
                    g.UseImmediate(right));
   } else {
-    Int32BinopMatcher m(node);
-    if (m.right().IsWord32And()) {
-      Int32BinopMatcher mright(right);
-      if (mright.right().Is(0x1F)) {
-        right = mright.left().node();
-      }
-    }
     selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
                    g.UseFixed(right, rcx));
   }
@@ -293,18 +432,17 @@
 
 // Shared routine for multiple 64-bit shift operations.
 // TODO(bmeurer): Merge this with VisitWord32Shift using template magic?
-static void VisitWord64Shift(InstructionSelector* selector, Node* node,
-                             ArchOpcode opcode) {
+void VisitWord64Shift(InstructionSelector* selector, Node* node,
+                      ArchOpcode opcode) {
   X64OperandGenerator g(selector);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
+  Int64BinopMatcher m(node);
+  Node* left = m.left().node();
+  Node* right = m.right().node();
 
-  // TODO(turbofan): assembler only supports some addressing modes for shifts.
   if (g.CanBeImmediate(right)) {
     selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
                    g.UseImmediate(right));
   } else {
-    Int64BinopMatcher m(node);
     if (m.right().IsWord64And()) {
       Int64BinopMatcher mright(right);
       if (mright.right().Is(0x3F)) {
@@ -317,12 +455,54 @@
 }
 
 
+void EmitLea(InstructionSelector* selector, InstructionCode opcode,
+             Node* result, Node* index, int scale, Node* base,
+             Node* displacement) {
+  X64OperandGenerator g(selector);
+
+  InstructionOperand* inputs[4];
+  size_t input_count = 0;
+  AddressingMode mode = g.GenerateMemoryOperandInputs(
+      index, scale, base, displacement, inputs, &input_count);
+
+  DCHECK_NE(0, static_cast<int>(input_count));
+  DCHECK_GE(arraysize(inputs), input_count);
+
+  InstructionOperand* outputs[1];
+  outputs[0] = g.DefineAsRegister(result);
+
+  opcode = AddressingModeField::encode(mode) | opcode;
+
+  selector->Emit(opcode, 1, outputs, input_count, inputs);
+}
+
+}  // namespace
+
+
 void InstructionSelector::VisitWord32Shl(Node* node) {
+  Int32ScaleMatcher m(node, true);
+  if (m.matches()) {
+    Node* index = node->InputAt(0);
+    Node* base = m.power_of_two_plus_one() ? index : NULL;
+    EmitLea(this, kX64Lea32, node, index, m.scale(), base, NULL);
+    return;
+  }
   VisitWord32Shift(this, node, kX64Shl32);
 }
 
 
 void InstructionSelector::VisitWord64Shl(Node* node) {
+  X64OperandGenerator g(this);
+  Int64BinopMatcher m(node);
+  if ((m.left().IsChangeInt32ToInt64() || m.left().IsChangeUint32ToUint64()) &&
+      m.right().IsInRange(32, 63)) {
+    // There's no need to sign/zero-extend to 64-bit if we shift out the upper
+    // 32 bits anyway.
+    Emit(kX64Shl, g.DefineSameAsFirst(node),
+         g.UseRegister(m.left().node()->InputAt(0)),
+         g.UseImmediate(m.right().node()));
+    return;
+  }
   VisitWord64Shift(this, node, kX64Shl);
 }
 
@@ -338,6 +518,18 @@
 
 
 void InstructionSelector::VisitWord32Sar(Node* node) {
+  X64OperandGenerator g(this);
+  Int32BinopMatcher m(node);
+  if (CanCover(m.node(), m.left().node()) && m.left().IsWord32Shl()) {
+    Int32BinopMatcher mleft(m.left().node());
+    if (mleft.right().Is(16) && m.right().Is(16)) {
+      Emit(kX64Movsxwl, g.DefineAsRegister(node), g.Use(mleft.left().node()));
+      return;
+    } else if (mleft.right().Is(24) && m.right().Is(24)) {
+      Emit(kX64Movsxbl, g.DefineAsRegister(node), g.Use(mleft.left().node()));
+      return;
+    }
+  }
   VisitWord32Shift(this, node, kX64Sar32);
 }
 
@@ -358,6 +550,18 @@
 
 
 void InstructionSelector::VisitInt32Add(Node* node) {
+  X64OperandGenerator g(this);
+
+  // Try to match the Add to a leal pattern
+  BaseWithIndexAndDisplacement32Matcher m(node);
+  if (m.matches() &&
+      (m.displacement() == NULL || g.CanBeImmediate(m.displacement()))) {
+    EmitLea(this, kX64Lea32, node, m.index(), m.scale(), m.base(),
+            m.displacement());
+    return;
+  }
+
+  // No leal pattern match, use addl
   VisitBinop(this, node, kX64Add32);
 }
 
@@ -371,8 +575,16 @@
   X64OperandGenerator g(this);
   Int32BinopMatcher m(node);
   if (m.left().Is(0)) {
-    Emit(kX64Neg32, g.DefineSameAsFirst(node), g.Use(m.right().node()));
+    Emit(kX64Neg32, g.DefineSameAsFirst(node), g.UseRegister(m.right().node()));
   } else {
+    if (m.right().HasValue() && g.CanBeImmediate(m.right().node())) {
+      // Turn subtractions of constant values into immediate "leal" instructions
+      // by negating the value.
+      Emit(kX64Lea32 | AddressingModeField::encode(kMode_MRI),
+           g.DefineAsRegister(node), g.UseRegister(m.left().node()),
+           g.TempImmediate(-m.right().Value()));
+      return;
+    }
     VisitBinop(this, node, kX64Sub32);
   }
 }
@@ -382,33 +594,75 @@
   X64OperandGenerator g(this);
   Int64BinopMatcher m(node);
   if (m.left().Is(0)) {
-    Emit(kX64Neg, g.DefineSameAsFirst(node), g.Use(m.right().node()));
+    Emit(kX64Neg, g.DefineSameAsFirst(node), g.UseRegister(m.right().node()));
   } else {
     VisitBinop(this, node, kX64Sub);
   }
 }
 
 
-static void VisitMul(InstructionSelector* selector, Node* node,
-                     ArchOpcode opcode) {
+namespace {
+
+void VisitMul(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
   X64OperandGenerator g(selector);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
+  Int32BinopMatcher m(node);
+  Node* left = m.left().node();
+  Node* right = m.right().node();
   if (g.CanBeImmediate(right)) {
     selector->Emit(opcode, g.DefineAsRegister(node), g.Use(left),
                    g.UseImmediate(right));
-  } else if (g.CanBeImmediate(left)) {
-    selector->Emit(opcode, g.DefineAsRegister(node), g.Use(right),
-                   g.UseImmediate(left));
   } else {
-    // TODO(turbofan): select better left operand.
+    if (g.CanBeBetterLeftOperand(right)) {
+      std::swap(left, right);
+    }
     selector->Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(left),
                    g.Use(right));
   }
 }
 
 
+void VisitMulHigh(InstructionSelector* selector, Node* node,
+                  ArchOpcode opcode) {
+  X64OperandGenerator g(selector);
+  Node* left = node->InputAt(0);
+  Node* right = node->InputAt(1);
+  if (selector->IsLive(left) && !selector->IsLive(right)) {
+    std::swap(left, right);
+  }
+  // TODO(turbofan): We use UseUniqueRegister here to improve register
+  // allocation.
+  selector->Emit(opcode, g.DefineAsFixed(node, rdx), g.UseFixed(left, rax),
+                 g.UseUniqueRegister(right));
+}
+
+
+void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
+  X64OperandGenerator g(selector);
+  InstructionOperand* temps[] = {g.TempRegister(rdx)};
+  selector->Emit(
+      opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax),
+      g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
+}
+
+
+void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) {
+  X64OperandGenerator g(selector);
+  selector->Emit(opcode, g.DefineAsFixed(node, rdx),
+                 g.UseFixed(node->InputAt(0), rax),
+                 g.UseUniqueRegister(node->InputAt(1)));
+}
+
+}  // namespace
+
+
 void InstructionSelector::VisitInt32Mul(Node* node) {
+  Int32ScaleMatcher m(node, true);
+  if (m.matches()) {
+    Node* index = node->InputAt(0);
+    Node* base = m.power_of_two_plus_one() ? index : NULL;
+    EmitLea(this, kX64Lea32, node, index, m.scale(), base, NULL);
+    return;
+  }
   VisitMul(this, node, kX64Imul32);
 }
 
@@ -418,13 +672,8 @@
 }
 
 
-static void VisitDiv(InstructionSelector* selector, Node* node,
-                     ArchOpcode opcode) {
-  X64OperandGenerator g(selector);
-  InstructionOperand* temps[] = {g.TempRegister(rdx)};
-  selector->Emit(
-      opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax),
-      g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
+void InstructionSelector::VisitInt32MulHigh(Node* node) {
+  VisitMulHigh(this, node, kX64ImulHigh32);
 }
 
 
@@ -438,26 +687,16 @@
 }
 
 
-void InstructionSelector::VisitInt32UDiv(Node* node) {
+void InstructionSelector::VisitUint32Div(Node* node) {
   VisitDiv(this, node, kX64Udiv32);
 }
 
 
-void InstructionSelector::VisitInt64UDiv(Node* node) {
+void InstructionSelector::VisitUint64Div(Node* node) {
   VisitDiv(this, node, kX64Udiv);
 }
 
 
-static void VisitMod(InstructionSelector* selector, Node* node,
-                     ArchOpcode opcode) {
-  X64OperandGenerator g(selector);
-  InstructionOperand* temps[] = {g.TempRegister(rax), g.TempRegister(rdx)};
-  selector->Emit(
-      opcode, g.DefineAsFixed(node, rdx), g.UseFixed(node->InputAt(0), rax),
-      g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
-}
-
-
 void InstructionSelector::VisitInt32Mod(Node* node) {
   VisitMod(this, node, kX64Idiv32);
 }
@@ -468,16 +707,27 @@
 }
 
 
-void InstructionSelector::VisitInt32UMod(Node* node) {
+void InstructionSelector::VisitUint32Mod(Node* node) {
   VisitMod(this, node, kX64Udiv32);
 }
 
 
-void InstructionSelector::VisitInt64UMod(Node* node) {
+void InstructionSelector::VisitUint64Mod(Node* node) {
   VisitMod(this, node, kX64Udiv);
 }
 
 
+void InstructionSelector::VisitUint32MulHigh(Node* node) {
+  VisitMulHigh(this, node, kX64UmulHigh32);
+}
+
+
+void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kSSECvtss2sd, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+}
+
+
 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) {
   X64OperandGenerator g(this);
   Emit(kSSEInt32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
@@ -486,9 +736,7 @@
 
 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) {
   X64OperandGenerator g(this);
-  // TODO(turbofan): X64 SSE cvtqsi2sd should support operands.
-  Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node),
-       g.UseRegister(node->InputAt(0)));
+  Emit(kSSEUint32ToFloat64, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
 }
 
 
@@ -512,41 +760,115 @@
 
 void InstructionSelector::VisitChangeUint32ToUint64(Node* node) {
   X64OperandGenerator g(this);
-  Emit(kX64Movl, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+  Node* value = node->InputAt(0);
+  switch (value->opcode()) {
+    case IrOpcode::kWord32And:
+    case IrOpcode::kWord32Or:
+    case IrOpcode::kWord32Xor:
+    case IrOpcode::kWord32Shl:
+    case IrOpcode::kWord32Shr:
+    case IrOpcode::kWord32Sar:
+    case IrOpcode::kWord32Ror:
+    case IrOpcode::kWord32Equal:
+    case IrOpcode::kInt32Add:
+    case IrOpcode::kInt32Sub:
+    case IrOpcode::kInt32Mul:
+    case IrOpcode::kInt32MulHigh:
+    case IrOpcode::kInt32Div:
+    case IrOpcode::kInt32LessThan:
+    case IrOpcode::kInt32LessThanOrEqual:
+    case IrOpcode::kInt32Mod:
+    case IrOpcode::kUint32Div:
+    case IrOpcode::kUint32LessThan:
+    case IrOpcode::kUint32LessThanOrEqual:
+    case IrOpcode::kUint32Mod:
+    case IrOpcode::kUint32MulHigh: {
+      // These 32-bit operations implicitly zero-extend to 64-bit on x64, so the
+      // zero-extension is a no-op.
+      Emit(kArchNop, g.DefineSameAsFirst(node), g.Use(value));
+      return;
+    }
+    default:
+      break;
+  }
+  Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value));
+}
+
+
+void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) {
+  X64OperandGenerator g(this);
+  Emit(kSSECvtsd2ss, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
 }
 
 
 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) {
   X64OperandGenerator g(this);
-  Emit(kX64Movl, g.DefineAsRegister(node), g.Use(node->InputAt(0)));
+  Node* value = node->InputAt(0);
+  if (CanCover(node, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kWord64Sar:
+      case IrOpcode::kWord64Shr: {
+        Int64BinopMatcher m(value);
+        if (m.right().Is(32)) {
+          Emit(kX64Shr, g.DefineSameAsFirst(node),
+               g.UseRegister(m.left().node()), g.TempImmediate(32));
+          return;
+        }
+        break;
+      }
+      default:
+        break;
+    }
+  }
+  Emit(kX64Movl, g.DefineAsRegister(node), g.Use(value));
 }
 
 
 void InstructionSelector::VisitFloat64Add(Node* node) {
   X64OperandGenerator g(this);
-  Emit(kSSEFloat64Add, g.DefineSameAsFirst(node),
-       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+  if (IsSupported(AVX)) {
+    Emit(kAVXFloat64Add, g.DefineAsRegister(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  } else {
+    Emit(kSSEFloat64Add, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  }
 }
 
 
 void InstructionSelector::VisitFloat64Sub(Node* node) {
   X64OperandGenerator g(this);
-  Emit(kSSEFloat64Sub, g.DefineSameAsFirst(node),
-       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+  if (IsSupported(AVX)) {
+    Emit(kAVXFloat64Sub, g.DefineAsRegister(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  } else {
+    Emit(kSSEFloat64Sub, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  }
 }
 
 
 void InstructionSelector::VisitFloat64Mul(Node* node) {
   X64OperandGenerator g(this);
-  Emit(kSSEFloat64Mul, g.DefineSameAsFirst(node),
-       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+  if (IsSupported(AVX)) {
+    Emit(kAVXFloat64Mul, g.DefineAsRegister(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  } else {
+    Emit(kSSEFloat64Mul, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  }
 }
 
 
 void InstructionSelector::VisitFloat64Div(Node* node) {
   X64OperandGenerator g(this);
-  Emit(kSSEFloat64Div, g.DefineSameAsFirst(node),
-       g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)));
+  if (IsSupported(AVX)) {
+    Emit(kAVXFloat64Div, g.DefineAsRegister(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  } else {
+    Emit(kSSEFloat64Div, g.DefineSameAsFirst(node),
+         g.UseRegister(node->InputAt(0)), g.Use(node->InputAt(1)));
+  }
 }
 
 
@@ -565,123 +887,56 @@
 }
 
 
-void InstructionSelector::VisitInt32AddWithOverflow(Node* node,
-                                                    FlagsContinuation* cont) {
-  VisitBinop(this, node, kX64Add32, cont);
-}
+namespace {
 
-
-void InstructionSelector::VisitInt32SubWithOverflow(Node* node,
-                                                    FlagsContinuation* cont) {
-  VisitBinop(this, node, kX64Sub32, cont);
-}
-
-
-// Shared routine for multiple compare operations.
-static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
-                         InstructionOperand* left, InstructionOperand* right,
-                         FlagsContinuation* cont) {
+void VisitRRFloat64(InstructionSelector* selector, ArchOpcode opcode,
+                    Node* node) {
   X64OperandGenerator g(selector);
-  opcode = cont->Encode(opcode);
-  if (cont->IsBranch()) {
-    selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()),
-                   g.Label(cont->false_block()))->MarkAsControl();
-  } else {
-    DCHECK(cont->IsSet());
-    selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
-  }
+  selector->Emit(opcode, g.DefineAsRegister(node),
+                 g.UseRegister(node->InputAt(0)));
+}
+
+}  // namespace
+
+
+void InstructionSelector::VisitFloat64Floor(Node* node) {
+  DCHECK(CpuFeatures::IsSupported(SSE4_1));
+  VisitRRFloat64(this, kSSEFloat64Floor, node);
 }
 
 
-// Shared routine for multiple word compare operations.
-static void VisitWordCompare(InstructionSelector* selector, Node* node,
-                             InstructionCode opcode, FlagsContinuation* cont,
-                             bool commutative) {
-  X64OperandGenerator g(selector);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
-
-  // Match immediates on left or right side of comparison.
-  if (g.CanBeImmediate(right)) {
-    VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont);
-  } else if (g.CanBeImmediate(left)) {
-    if (!commutative) cont->Commute();
-    VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont);
-  } else {
-    VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont);
-  }
+void InstructionSelector::VisitFloat64Ceil(Node* node) {
+  DCHECK(CpuFeatures::IsSupported(SSE4_1));
+  VisitRRFloat64(this, kSSEFloat64Ceil, node);
 }
 
 
-void InstructionSelector::VisitWord32Test(Node* node, FlagsContinuation* cont) {
-  switch (node->opcode()) {
-    case IrOpcode::kInt32Sub:
-      return VisitWordCompare(this, node, kX64Cmp32, cont, false);
-    case IrOpcode::kWord32And:
-      return VisitWordCompare(this, node, kX64Test32, cont, true);
-    default:
-      break;
-  }
+void InstructionSelector::VisitFloat64RoundTruncate(Node* node) {
+  DCHECK(CpuFeatures::IsSupported(SSE4_1));
+  VisitRRFloat64(this, kSSEFloat64RoundTruncate, node);
+}
 
+
+void InstructionSelector::VisitFloat64RoundTiesAway(Node* node) {
+  UNREACHABLE();
+}
+
+
+void InstructionSelector::VisitCall(Node* node) {
   X64OperandGenerator g(this);
-  VisitCompare(this, kX64Test32, g.Use(node), g.TempImmediate(-1), cont);
-}
-
-
-void InstructionSelector::VisitWord64Test(Node* node, FlagsContinuation* cont) {
-  switch (node->opcode()) {
-    case IrOpcode::kInt64Sub:
-      return VisitWordCompare(this, node, kX64Cmp, cont, false);
-    case IrOpcode::kWord64And:
-      return VisitWordCompare(this, node, kX64Test, cont, true);
-    default:
-      break;
-  }
-
-  X64OperandGenerator g(this);
-  VisitCompare(this, kX64Test, g.Use(node), g.TempImmediate(-1), cont);
-}
-
-
-void InstructionSelector::VisitWord32Compare(Node* node,
-                                             FlagsContinuation* cont) {
-  VisitWordCompare(this, node, kX64Cmp32, cont, false);
-}
-
-
-void InstructionSelector::VisitWord64Compare(Node* node,
-                                             FlagsContinuation* cont) {
-  VisitWordCompare(this, node, kX64Cmp, cont, false);
-}
-
-
-void InstructionSelector::VisitFloat64Compare(Node* node,
-                                              FlagsContinuation* cont) {
-  X64OperandGenerator g(this);
-  Node* left = node->InputAt(0);
-  Node* right = node->InputAt(1);
-  VisitCompare(this, kSSEFloat64Cmp, g.UseRegister(left), g.Use(right), cont);
-}
-
-
-void InstructionSelector::VisitCall(Node* call, BasicBlock* continuation,
-                                    BasicBlock* deoptimization) {
-  X64OperandGenerator g(this);
-  CallDescriptor* descriptor = OpParameter<CallDescriptor*>(call);
+  const CallDescriptor* descriptor = OpParameter<const CallDescriptor*>(node);
 
   FrameStateDescriptor* frame_state_descriptor = NULL;
   if (descriptor->NeedsFrameState()) {
     frame_state_descriptor = GetFrameStateDescriptor(
-        call->InputAt(static_cast<int>(descriptor->InputCount())));
+        node->InputAt(static_cast<int>(descriptor->InputCount())));
   }
 
   CallBuffer buffer(zone(), descriptor, frame_state_descriptor);
 
   // Compute InstructionOperands for inputs and outputs.
-  InitializeCallBuffer(call, &buffer, true, true);
+  InitializeCallBuffer(node, &buffer, true, true);
 
-  // TODO(dcarney): stack alignment for c calls.
-  // TODO(dcarney): shadow space on window for c calls.
   // Push any stack arguments.
   for (NodeVectorRIter input = buffer.pushed_nodes.rbegin();
        input != buffer.pushed_nodes.rend(); input++) {
@@ -707,17 +962,358 @@
   opcode |= MiscField::encode(descriptor->flags());
 
   // Emit the call instruction.
+  InstructionOperand** first_output =
+      buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL;
   Instruction* call_instr =
-      Emit(opcode, buffer.outputs.size(), &buffer.outputs.front(),
+      Emit(opcode, buffer.outputs.size(), first_output,
            buffer.instruction_args.size(), &buffer.instruction_args.front());
-
   call_instr->MarkAsCall();
-  if (deoptimization != NULL) {
-    DCHECK(continuation != NULL);
-    call_instr->MarkAsControl();
+}
+
+
+// Shared routine for multiple compare operations.
+static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                         InstructionOperand* left, InstructionOperand* right,
+                         FlagsContinuation* cont) {
+  X64OperandGenerator g(selector);
+  opcode = cont->Encode(opcode);
+  if (cont->IsBranch()) {
+    selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()),
+                   g.Label(cont->false_block()))->MarkAsControl();
+  } else {
+    DCHECK(cont->IsSet());
+    selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
   }
 }
 
+
+// Shared routine for multiple compare operations.
+static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
+                         Node* left, Node* right, FlagsContinuation* cont,
+                         bool commutative) {
+  X64OperandGenerator g(selector);
+  if (commutative && g.CanBeBetterLeftOperand(right)) {
+    std::swap(left, right);
+  }
+  VisitCompare(selector, opcode, g.UseRegister(left), g.Use(right), cont);
+}
+
+
+// Shared routine for multiple word compare operations.
+static void VisitWordCompare(InstructionSelector* selector, Node* node,
+                             InstructionCode opcode, FlagsContinuation* cont) {
+  X64OperandGenerator g(selector);
+  Node* const left = node->InputAt(0);
+  Node* const right = node->InputAt(1);
+
+  // Match immediates on left or right side of comparison.
+  if (g.CanBeImmediate(right)) {
+    VisitCompare(selector, opcode, g.Use(left), g.UseImmediate(right), cont);
+  } else if (g.CanBeImmediate(left)) {
+    if (!node->op()->HasProperty(Operator::kCommutative)) cont->Commute();
+    VisitCompare(selector, opcode, g.Use(right), g.UseImmediate(left), cont);
+  } else {
+    VisitCompare(selector, opcode, left, right, cont,
+                 node->op()->HasProperty(Operator::kCommutative));
+  }
+}
+
+
+// Shared routine for comparison with zero.
+static void VisitCompareZero(InstructionSelector* selector, Node* node,
+                             InstructionCode opcode, FlagsContinuation* cont) {
+  X64OperandGenerator g(selector);
+  VisitCompare(selector, opcode, g.Use(node), g.TempImmediate(0), cont);
+}
+
+
+// Shared routine for multiple float64 compare operations.
+static void VisitFloat64Compare(InstructionSelector* selector, Node* node,
+                                FlagsContinuation* cont) {
+  VisitCompare(selector, kSSEFloat64Cmp, node->InputAt(0), node->InputAt(1),
+               cont, node->op()->HasProperty(Operator::kCommutative));
+}
+
+
+void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
+                                      BasicBlock* fbranch) {
+  X64OperandGenerator g(this);
+  Node* user = branch;
+  Node* value = branch->InputAt(0);
+
+  FlagsContinuation cont(kNotEqual, tbranch, fbranch);
+
+  // Try to combine with comparisons against 0 by simply inverting the branch.
+  while (CanCover(user, value)) {
+    if (value->opcode() == IrOpcode::kWord32Equal) {
+      Int32BinopMatcher m(value);
+      if (m.right().Is(0)) {
+        user = value;
+        value = m.left().node();
+        cont.Negate();
+      } else {
+        break;
+      }
+    } else if (value->opcode() == IrOpcode::kWord64Equal) {
+      Int64BinopMatcher m(value);
+      if (m.right().Is(0)) {
+        user = value;
+        value = m.left().node();
+        cont.Negate();
+      } else {
+        break;
+      }
+    } else {
+      break;
+    }
+  }
+
+  // Try to combine the branch with a comparison.
+  if (CanCover(user, value)) {
+    switch (value->opcode()) {
+      case IrOpcode::kWord32Equal:
+        cont.OverwriteAndNegateIfEqual(kEqual);
+        return VisitWordCompare(this, value, kX64Cmp32, &cont);
+      case IrOpcode::kInt32LessThan:
+        cont.OverwriteAndNegateIfEqual(kSignedLessThan);
+        return VisitWordCompare(this, value, kX64Cmp32, &cont);
+      case IrOpcode::kInt32LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+        return VisitWordCompare(this, value, kX64Cmp32, &cont);
+      case IrOpcode::kUint32LessThan:
+        cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitWordCompare(this, value, kX64Cmp32, &cont);
+      case IrOpcode::kUint32LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
+        return VisitWordCompare(this, value, kX64Cmp32, &cont);
+      case IrOpcode::kWord64Equal:
+        cont.OverwriteAndNegateIfEqual(kEqual);
+        return VisitWordCompare(this, value, kX64Cmp, &cont);
+      case IrOpcode::kInt64LessThan:
+        cont.OverwriteAndNegateIfEqual(kSignedLessThan);
+        return VisitWordCompare(this, value, kX64Cmp, &cont);
+      case IrOpcode::kInt64LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
+        return VisitWordCompare(this, value, kX64Cmp, &cont);
+      case IrOpcode::kUint64LessThan:
+        cont.OverwriteAndNegateIfEqual(kUnsignedLessThan);
+        return VisitWordCompare(this, value, kX64Cmp, &cont);
+      case IrOpcode::kFloat64Equal:
+        cont.OverwriteAndNegateIfEqual(kUnorderedEqual);
+        return VisitFloat64Compare(this, value, &cont);
+      case IrOpcode::kFloat64LessThan:
+        cont.OverwriteAndNegateIfEqual(kUnorderedLessThan);
+        return VisitFloat64Compare(this, value, &cont);
+      case IrOpcode::kFloat64LessThanOrEqual:
+        cont.OverwriteAndNegateIfEqual(kUnorderedLessThanOrEqual);
+        return VisitFloat64Compare(this, value, &cont);
+      case IrOpcode::kProjection:
+        // Check if this is the overflow output projection of an
+        // <Operation>WithOverflow node.
+        if (OpParameter<size_t>(value) == 1u) {
+          // We cannot combine the <Operation>WithOverflow with this branch
+          // unless the 0th projection (the use of the actual value of the
+          // <Operation> is either NULL, which means there's no use of the
+          // actual value, or was already defined, which means it is scheduled
+          // *AFTER* this branch).
+          Node* node = value->InputAt(0);
+          Node* result = node->FindProjection(0);
+          if (result == NULL || IsDefined(result)) {
+            switch (node->opcode()) {
+              case IrOpcode::kInt32AddWithOverflow:
+                cont.OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(this, node, kX64Add32, &cont);
+              case IrOpcode::kInt32SubWithOverflow:
+                cont.OverwriteAndNegateIfEqual(kOverflow);
+                return VisitBinop(this, node, kX64Sub32, &cont);
+              default:
+                break;
+            }
+          }
+        }
+        break;
+      case IrOpcode::kInt32Sub:
+        return VisitWordCompare(this, value, kX64Cmp32, &cont);
+      case IrOpcode::kInt64Sub:
+        return VisitWordCompare(this, value, kX64Cmp, &cont);
+      case IrOpcode::kWord32And:
+        return VisitWordCompare(this, value, kX64Test32, &cont);
+      case IrOpcode::kWord64And:
+        return VisitWordCompare(this, value, kX64Test, &cont);
+      default:
+        break;
+    }
+  }
+
+  // Branch could not be combined with a compare, emit compare against 0.
+  VisitCompareZero(this, value, kX64Cmp32, &cont);
+}
+
+
+void InstructionSelector::VisitWord32Equal(Node* const node) {
+  Node* user = node;
+  FlagsContinuation cont(kEqual, node);
+  Int32BinopMatcher m(user);
+  if (m.right().Is(0)) {
+    Node* value = m.left().node();
+
+    // Try to combine with comparisons against 0 by simply inverting the branch.
+    while (CanCover(user, value) && value->opcode() == IrOpcode::kWord32Equal) {
+      Int32BinopMatcher m(value);
+      if (m.right().Is(0)) {
+        user = value;
+        value = m.left().node();
+        cont.Negate();
+      } else {
+        break;
+      }
+    }
+
+    // Try to combine the branch with a comparison.
+    if (CanCover(user, value)) {
+      switch (value->opcode()) {
+        case IrOpcode::kInt32Sub:
+          return VisitWordCompare(this, value, kX64Cmp32, &cont);
+        case IrOpcode::kWord32And:
+          return VisitWordCompare(this, value, kX64Test32, &cont);
+        default:
+          break;
+      }
+    }
+    return VisitCompareZero(this, value, kX64Cmp32, &cont);
+  }
+  VisitWordCompare(this, node, kX64Cmp32, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWordCompare(this, node, kX64Cmp32, &cont);
+}
+
+
+void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, kX64Cmp32, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWordCompare(this, node, kX64Cmp32, &cont);
+}
+
+
+void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, kX64Cmp32, &cont);
+}
+
+
+void InstructionSelector::VisitWord64Equal(Node* const node) {
+  Node* user = node;
+  FlagsContinuation cont(kEqual, node);
+  Int64BinopMatcher m(user);
+  if (m.right().Is(0)) {
+    Node* value = m.left().node();
+
+    // Try to combine with comparisons against 0 by simply inverting the branch.
+    while (CanCover(user, value) && value->opcode() == IrOpcode::kWord64Equal) {
+      Int64BinopMatcher m(value);
+      if (m.right().Is(0)) {
+        user = value;
+        value = m.left().node();
+        cont.Negate();
+      } else {
+        break;
+      }
+    }
+
+    // Try to combine the branch with a comparison.
+    if (CanCover(user, value)) {
+      switch (value->opcode()) {
+        case IrOpcode::kInt64Sub:
+          return VisitWordCompare(this, value, kX64Cmp, &cont);
+        case IrOpcode::kWord64And:
+          return VisitWordCompare(this, value, kX64Test, &cont);
+        default:
+          break;
+      }
+    }
+    return VisitCompareZero(this, value, kX64Cmp, &cont);
+  }
+  VisitWordCompare(this, node, kX64Cmp, &cont);
+}
+
+
+void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    VisitBinop(this, node, kX64Add32, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kX64Add32, &cont);
+}
+
+
+void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
+  if (Node* ovf = node->FindProjection(1)) {
+    FlagsContinuation cont(kOverflow, ovf);
+    return VisitBinop(this, node, kX64Sub32, &cont);
+  }
+  FlagsContinuation cont;
+  VisitBinop(this, node, kX64Sub32, &cont);
+}
+
+
+void InstructionSelector::VisitInt64LessThan(Node* node) {
+  FlagsContinuation cont(kSignedLessThan, node);
+  VisitWordCompare(this, node, kX64Cmp, &cont);
+}
+
+
+void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kSignedLessThanOrEqual, node);
+  VisitWordCompare(this, node, kX64Cmp, &cont);
+}
+
+
+void InstructionSelector::VisitUint64LessThan(Node* node) {
+  FlagsContinuation cont(kUnsignedLessThan, node);
+  VisitWordCompare(this, node, kX64Cmp, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64Equal(Node* node) {
+  FlagsContinuation cont(kUnorderedEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThan(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThan, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
+  FlagsContinuation cont(kUnorderedLessThanOrEqual, node);
+  VisitFloat64Compare(this, node, &cont);
+}
+
+
+// static
+MachineOperatorBuilder::Flags
+InstructionSelector::SupportedMachineOperatorFlags() {
+  if (CpuFeatures::IsSupported(SSE4_1)) {
+    return MachineOperatorBuilder::kFloat64Floor |
+           MachineOperatorBuilder::kFloat64Ceil |
+           MachineOperatorBuilder::kFloat64RoundTruncate |
+           MachineOperatorBuilder::kWord32ShiftIsSafe;
+  }
+  return MachineOperatorBuilder::kNoFlags;
+}
+
 }  // namespace compiler
 }  // namespace internal
 }  // namespace v8
diff --git a/src/compiler/x64/linkage-x64.cc b/src/compiler/x64/linkage-x64.cc
index 8175bc6..0b76cc7 100644
--- a/src/compiler/x64/linkage-x64.cc
+++ b/src/compiler/x64/linkage-x64.cc
@@ -49,8 +49,9 @@
 
 typedef LinkageHelper<X64LinkageHelperTraits> LH;
 
-CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone) {
-  return LH::GetJSCallDescriptor(zone, parameter_count);
+CallDescriptor* Linkage::GetJSCallDescriptor(int parameter_count, Zone* zone,
+                                             CallDescriptor::Flags flags) {
+  return LH::GetJSCallDescriptor(zone, parameter_count, flags);
 }
 
 
@@ -63,10 +64,10 @@
 
 
 CallDescriptor* Linkage::GetStubCallDescriptor(
-    CallInterfaceDescriptor descriptor, int stack_parameter_count,
-    CallDescriptor::Flags flags, Zone* zone) {
+    const CallInterfaceDescriptor& descriptor, int stack_parameter_count,
+    CallDescriptor::Flags flags, Operator::Properties properties, Zone* zone) {
   return LH::GetStubCallDescriptor(zone, descriptor, stack_parameter_count,
-                                   flags);
+                                   flags, properties);
 }
 
 
diff --git a/src/compiler/zone-pool.cc b/src/compiler/zone-pool.cc
new file mode 100644
index 0000000..179988d
--- /dev/null
+++ b/src/compiler/zone-pool.cc
@@ -0,0 +1,140 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/zone-pool.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+ZonePool::StatsScope::StatsScope(ZonePool* zone_pool)
+    : zone_pool_(zone_pool),
+      total_allocated_bytes_at_start_(zone_pool->GetTotalAllocatedBytes()),
+      max_allocated_bytes_(0) {
+  zone_pool_->stats_.push_back(this);
+  for (auto zone : zone_pool_->used_) {
+    size_t size = static_cast<size_t>(zone->allocation_size());
+    std::pair<InitialValues::iterator, bool> res =
+        initial_values_.insert(std::make_pair(zone, size));
+    USE(res);
+    DCHECK(res.second);
+  }
+}
+
+
+ZonePool::StatsScope::~StatsScope() {
+  DCHECK_EQ(zone_pool_->stats_.back(), this);
+  zone_pool_->stats_.pop_back();
+}
+
+
+size_t ZonePool::StatsScope::GetMaxAllocatedBytes() {
+  return std::max(max_allocated_bytes_, GetCurrentAllocatedBytes());
+}
+
+
+size_t ZonePool::StatsScope::GetCurrentAllocatedBytes() {
+  size_t total = 0;
+  for (Zone* zone : zone_pool_->used_) {
+    total += static_cast<size_t>(zone->allocation_size());
+    // Adjust for initial values.
+    InitialValues::iterator it = initial_values_.find(zone);
+    if (it != initial_values_.end()) {
+      total -= it->second;
+    }
+  }
+  return total;
+}
+
+
+size_t ZonePool::StatsScope::GetTotalAllocatedBytes() {
+  return zone_pool_->GetTotalAllocatedBytes() - total_allocated_bytes_at_start_;
+}
+
+
+void ZonePool::StatsScope::ZoneReturned(Zone* zone) {
+  size_t current_total = GetCurrentAllocatedBytes();
+  // Update max.
+  max_allocated_bytes_ = std::max(max_allocated_bytes_, current_total);
+  // Drop zone from initial value map.
+  InitialValues::iterator it = initial_values_.find(zone);
+  if (it != initial_values_.end()) {
+    initial_values_.erase(it);
+  }
+}
+
+
+ZonePool::ZonePool(Isolate* isolate)
+    : isolate_(isolate), max_allocated_bytes_(0), total_deleted_bytes_(0) {}
+
+
+ZonePool::~ZonePool() {
+  DCHECK(used_.empty());
+  DCHECK(stats_.empty());
+  for (Zone* zone : unused_) {
+    delete zone;
+  }
+}
+
+
+size_t ZonePool::GetMaxAllocatedBytes() {
+  return std::max(max_allocated_bytes_, GetCurrentAllocatedBytes());
+}
+
+
+size_t ZonePool::GetCurrentAllocatedBytes() {
+  size_t total = 0;
+  for (Zone* zone : used_) {
+    total += static_cast<size_t>(zone->allocation_size());
+  }
+  return total;
+}
+
+
+size_t ZonePool::GetTotalAllocatedBytes() {
+  return total_deleted_bytes_ + GetCurrentAllocatedBytes();
+}
+
+
+Zone* ZonePool::NewEmptyZone() {
+  Zone* zone;
+  // Grab a zone from pool if possible.
+  if (!unused_.empty()) {
+    zone = unused_.back();
+    unused_.pop_back();
+  } else {
+    zone = new Zone(isolate_);
+  }
+  used_.push_back(zone);
+  DCHECK_EQ(0, zone->allocation_size());
+  return zone;
+}
+
+
+void ZonePool::ReturnZone(Zone* zone) {
+  size_t current_total = GetCurrentAllocatedBytes();
+  // Update max.
+  max_allocated_bytes_ = std::max(max_allocated_bytes_, current_total);
+  // Update stats.
+  for (auto stat_scope : stats_) {
+    stat_scope->ZoneReturned(zone);
+  }
+  // Remove from used.
+  Used::iterator it = std::find(used_.begin(), used_.end(), zone);
+  DCHECK(it != used_.end());
+  used_.erase(it);
+  total_deleted_bytes_ += static_cast<size_t>(zone->allocation_size());
+  // Delete zone or clear and stash on unused_.
+  if (unused_.size() >= kMaxUnusedSize) {
+    delete zone;
+  } else {
+    zone->DeleteAll();
+    DCHECK_EQ(0, zone->allocation_size());
+    unused_.push_back(zone);
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/src/compiler/zone-pool.h b/src/compiler/zone-pool.h
new file mode 100644
index 0000000..8b43265
--- /dev/null
+++ b/src/compiler/zone-pool.h
@@ -0,0 +1,93 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_ZONE_POOL_H_
+#define V8_COMPILER_ZONE_POOL_H_
+
+#include <map>
+#include <set>
+#include <vector>
+
+#include "src/v8.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class ZonePool FINAL {
+ public:
+  class Scope FINAL {
+   public:
+    explicit Scope(ZonePool* zone_pool) : zone_pool_(zone_pool), zone_(NULL) {}
+    ~Scope() { Destroy(); }
+
+    Zone* zone() {
+      if (zone_ == NULL) zone_ = zone_pool_->NewEmptyZone();
+      return zone_;
+    }
+    void Destroy() {
+      if (zone_ != NULL) zone_pool_->ReturnZone(zone_);
+      zone_ = NULL;
+    }
+
+   private:
+    ZonePool* const zone_pool_;
+    Zone* zone_;
+    DISALLOW_COPY_AND_ASSIGN(Scope);
+  };
+
+  class StatsScope FINAL {
+   public:
+    explicit StatsScope(ZonePool* zone_pool);
+    ~StatsScope();
+
+    size_t GetMaxAllocatedBytes();
+    size_t GetCurrentAllocatedBytes();
+    size_t GetTotalAllocatedBytes();
+
+   private:
+    friend class ZonePool;
+    void ZoneReturned(Zone* zone);
+
+    typedef std::map<Zone*, size_t> InitialValues;
+
+    ZonePool* const zone_pool_;
+    InitialValues initial_values_;
+    size_t total_allocated_bytes_at_start_;
+    size_t max_allocated_bytes_;
+
+    DISALLOW_COPY_AND_ASSIGN(StatsScope);
+  };
+
+  explicit ZonePool(Isolate* isolate);
+  ~ZonePool();
+
+  size_t GetMaxAllocatedBytes();
+  size_t GetTotalAllocatedBytes();
+  size_t GetCurrentAllocatedBytes();
+
+ private:
+  Zone* NewEmptyZone();
+  void ReturnZone(Zone* zone);
+
+  static const size_t kMaxUnusedSize = 3;
+  typedef std::vector<Zone*> Unused;
+  typedef std::vector<Zone*> Used;
+  typedef std::vector<StatsScope*> Stats;
+
+  Isolate* const isolate_;
+  Unused unused_;
+  Used used_;
+  Stats stats_;
+  size_t max_allocated_bytes_;
+  size_t total_deleted_bytes_;
+
+  DISALLOW_COPY_AND_ASSIGN(ZonePool);
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif
diff --git a/src/contexts.cc b/src/contexts.cc
index 30c474d..57490a1 100644
--- a/src/contexts.cc
+++ b/src/contexts.cc
@@ -11,9 +11,52 @@
 namespace v8 {
 namespace internal {
 
+
+Handle<ScriptContextTable> ScriptContextTable::Extend(
+    Handle<ScriptContextTable> table, Handle<Context> script_context) {
+  Handle<ScriptContextTable> result;
+  int used = table->used();
+  int length = table->length();
+  CHECK(used >= 0 && length > 0 && used < length);
+  if (used + 1 == length) {
+    CHECK(length < Smi::kMaxValue / 2);
+    result = Handle<ScriptContextTable>::cast(
+        FixedArray::CopySize(table, length * 2));
+  } else {
+    result = table;
+  }
+  result->set_used(used + 1);
+
+  DCHECK(script_context->IsScriptContext());
+  result->set(used + 1, *script_context);
+  return result;
+}
+
+
+bool ScriptContextTable::Lookup(Handle<ScriptContextTable> table,
+                                Handle<String> name, LookupResult* result) {
+  for (int i = 0; i < table->used(); i++) {
+    Handle<Context> context = GetContext(table, i);
+    DCHECK(context->IsScriptContext());
+    Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
+    int slot_index = ScopeInfo::ContextSlotIndex(
+        scope_info, name, &result->mode, &result->init_flag,
+        &result->maybe_assigned_flag);
+
+    if (slot_index >= 0) {
+      result->context_index = i;
+      result->slot_index = slot_index;
+      return true;
+    }
+  }
+  return false;
+}
+
+
 Context* Context::declaration_context() {
   Context* current = this;
-  while (!current->IsFunctionContext() && !current->IsNativeContext()) {
+  while (!current->IsFunctionContext() && !current->IsNativeContext() &&
+         !current->IsScriptContext()) {
     current = current->previous();
     DCHECK(current->closure() == closure());
   }
@@ -32,9 +75,9 @@
 }
 
 
-Context* Context::global_context() {
+Context* Context::script_context() {
   Context* current = this;
-  while (!current->IsGlobalContext()) {
+  while (!current->IsScriptContext()) {
     current = current->previous();
   }
   return current;
@@ -82,8 +125,7 @@
   DCHECK(attrs.has_value || isolate->has_pending_exception());
   if (!attrs.has_value || attrs.value == ABSENT) return attrs;
 
-  Handle<Symbol> unscopables_symbol(
-      isolate->native_context()->unscopables_symbol(), isolate);
+  Handle<Symbol> unscopables_symbol = isolate->factory()->unscopables_symbol();
   Handle<Object> receiver = it->GetReceiver();
   Handle<Object> unscopables;
   MaybeHandle<Object> maybe_unscopables =
@@ -92,16 +134,64 @@
     return Maybe<PropertyAttributes>();
   }
   if (!unscopables->IsSpecObject()) return attrs;
-  Maybe<bool> blacklist = JSReceiver::HasProperty(
-      Handle<JSReceiver>::cast(unscopables), it->name());
-  if (!blacklist.has_value) {
+  Handle<Object> blacklist;
+  MaybeHandle<Object> maybe_blacklist =
+      Object::GetProperty(unscopables, it->name());
+  if (!maybe_blacklist.ToHandle(&blacklist)) {
     DCHECK(isolate->has_pending_exception());
     return Maybe<PropertyAttributes>();
   }
-  if (blacklist.value) return maybe(ABSENT);
+  if (!blacklist->IsUndefined()) return maybe(ABSENT);
   return attrs;
 }
 
+static void GetAttributesAndBindingFlags(VariableMode mode,
+                                         InitializationFlag init_flag,
+                                         PropertyAttributes* attributes,
+                                         BindingFlags* binding_flags) {
+  switch (mode) {
+    case INTERNAL:  // Fall through.
+    case VAR:
+      *attributes = NONE;
+      *binding_flags = MUTABLE_IS_INITIALIZED;
+      break;
+    case LET:
+      *attributes = NONE;
+      *binding_flags = (init_flag == kNeedsInitialization)
+                           ? MUTABLE_CHECK_INITIALIZED
+                           : MUTABLE_IS_INITIALIZED;
+      break;
+    case CONST_LEGACY:
+      *attributes = READ_ONLY;
+      *binding_flags = (init_flag == kNeedsInitialization)
+                           ? IMMUTABLE_CHECK_INITIALIZED
+                           : IMMUTABLE_IS_INITIALIZED;
+      break;
+    case CONST:
+      *attributes = READ_ONLY;
+      *binding_flags = (init_flag == kNeedsInitialization)
+                           ? IMMUTABLE_CHECK_INITIALIZED_HARMONY
+                           : IMMUTABLE_IS_INITIALIZED_HARMONY;
+      break;
+    case MODULE:
+      *attributes = READ_ONLY;
+      *binding_flags = IMMUTABLE_IS_INITIALIZED_HARMONY;
+      break;
+    case DYNAMIC:
+    case DYNAMIC_GLOBAL:
+    case DYNAMIC_LOCAL:
+    case TEMPORARY:
+      // Note: Fixed context slots are statically allocated by the compiler.
+      // Statically allocated variables always have a statically known mode,
+      // which is the mode with which they were declared when added to the
+      // scope. Thus, the DYNAMIC mode (which corresponds to dynamically
+      // declared variables that were introduced through declaration nodes)
+      // must not appear here.
+      UNREACHABLE();
+      break;
+  }
+}
+
 
 Handle<Object> Context::Lookup(Handle<String> name,
                                ContextLookupFlags flags,
@@ -125,16 +215,42 @@
   do {
     if (FLAG_trace_contexts) {
       PrintF(" - looking in context %p", reinterpret_cast<void*>(*context));
+      if (context->IsScriptContext()) PrintF(" (script context)");
       if (context->IsNativeContext()) PrintF(" (native context)");
       PrintF("\n");
     }
 
+
     // 1. Check global objects, subjects of with, and extension objects.
     if (context->IsNativeContext() ||
         context->IsWithContext() ||
         (context->IsFunctionContext() && context->has_extension())) {
       Handle<JSReceiver> object(
           JSReceiver::cast(context->extension()), isolate);
+
+      if (context->IsNativeContext()) {
+        if (FLAG_trace_contexts) {
+          PrintF(" - trying other script contexts\n");
+        }
+        // Try other script contexts.
+        Handle<ScriptContextTable> script_contexts(
+            context->global_object()->native_context()->script_context_table());
+        ScriptContextTable::LookupResult r;
+        if (ScriptContextTable::Lookup(script_contexts, name, &r)) {
+          if (FLAG_trace_contexts) {
+            Handle<Context> c = ScriptContextTable::GetContext(script_contexts,
+                                                               r.context_index);
+            PrintF("=> found property in script context %d: %p\n",
+                   r.context_index, reinterpret_cast<void*>(*c));
+          }
+          *index = r.slot_index;
+          GetAttributesAndBindingFlags(r.mode, r.init_flag, attributes,
+                                       binding_flags);
+          return ScriptContextTable::GetContext(script_contexts,
+                                                r.context_index);
+        }
+      }
+
       // Context extension objects needs to behave as if they have no
       // prototype.  So even if we want to follow prototype chains, we need
       // to only do a local lookup for context extension objects.
@@ -163,7 +279,8 @@
     }
 
     // 2. Check the context proper if it has slots.
-    if (context->IsFunctionContext() || context->IsBlockContext()) {
+    if (context->IsFunctionContext() || context->IsBlockContext() ||
+        (FLAG_harmony_scoping && context->IsScriptContext())) {
       // Use serialized scope information of functions and blocks to search
       // for the context index.
       Handle<ScopeInfo> scope_info;
@@ -188,45 +305,8 @@
                  slot_index, mode);
         }
         *index = slot_index;
-        // Note: Fixed context slots are statically allocated by the compiler.
-        // Statically allocated variables always have a statically known mode,
-        // which is the mode with which they were declared when added to the
-        // scope. Thus, the DYNAMIC mode (which corresponds to dynamically
-        // declared variables that were introduced through declaration nodes)
-        // must not appear here.
-        switch (mode) {
-          case INTERNAL:  // Fall through.
-          case VAR:
-            *attributes = NONE;
-            *binding_flags = MUTABLE_IS_INITIALIZED;
-            break;
-          case LET:
-            *attributes = NONE;
-            *binding_flags = (init_flag == kNeedsInitialization)
-                ? MUTABLE_CHECK_INITIALIZED : MUTABLE_IS_INITIALIZED;
-            break;
-          case CONST_LEGACY:
-            *attributes = READ_ONLY;
-            *binding_flags = (init_flag == kNeedsInitialization)
-                ? IMMUTABLE_CHECK_INITIALIZED : IMMUTABLE_IS_INITIALIZED;
-            break;
-          case CONST:
-            *attributes = READ_ONLY;
-            *binding_flags = (init_flag == kNeedsInitialization)
-                ? IMMUTABLE_CHECK_INITIALIZED_HARMONY :
-                IMMUTABLE_IS_INITIALIZED_HARMONY;
-            break;
-          case MODULE:
-            *attributes = READ_ONLY;
-            *binding_flags = IMMUTABLE_IS_INITIALIZED_HARMONY;
-            break;
-          case DYNAMIC:
-          case DYNAMIC_GLOBAL:
-          case DYNAMIC_LOCAL:
-          case TEMPORARY:
-            UNREACHABLE();
-            break;
-        }
+        GetAttributesAndBindingFlags(mode, init_flag, attributes,
+                                     binding_flags);
         return context;
       }
 
@@ -401,7 +481,7 @@
   if (child->GetIsolate()->bootstrapper()->IsActive()) return true;
   if (!object->IsContext()) return false;
   Context* context = Context::cast(object);
-  return context->IsNativeContext() || context->IsGlobalContext() ||
+  return context->IsNativeContext() || context->IsScriptContext() ||
          context->IsModuleContext() || !child->IsModuleContext();
 }
 
diff --git a/src/contexts.h b/src/contexts.h
index ac25e48..cd3ff14 100644
--- a/src/contexts.h
+++ b/src/contexts.h
@@ -98,28 +98,10 @@
   V(TO_INTEGER_FUN_INDEX, JSFunction, to_integer_fun)                          \
   V(TO_UINT32_FUN_INDEX, JSFunction, to_uint32_fun)                            \
   V(TO_INT32_FUN_INDEX, JSFunction, to_int32_fun)                              \
+  V(TO_LENGTH_FUN_INDEX, JSFunction, to_length_fun)                            \
   V(GLOBAL_EVAL_FUN_INDEX, JSFunction, global_eval_fun)                        \
   V(INSTANTIATE_FUN_INDEX, JSFunction, instantiate_fun)                        \
   V(CONFIGURE_INSTANCE_FUN_INDEX, JSFunction, configure_instance_fun)          \
-  V(MATH_ABS_FUN_INDEX, JSFunction, math_abs_fun)                              \
-  V(MATH_ACOS_FUN_INDEX, JSFunction, math_acos_fun)                            \
-  V(MATH_ASIN_FUN_INDEX, JSFunction, math_asin_fun)                            \
-  V(MATH_ATAN_FUN_INDEX, JSFunction, math_atan_fun)                            \
-  V(MATH_ATAN2_FUN_INDEX, JSFunction, math_atan2_fun)                          \
-  V(MATH_CEIL_FUN_INDEX, JSFunction, math_ceil_fun)                            \
-  V(MATH_COS_FUN_INDEX, JSFunction, math_cos_fun)                              \
-  V(MATH_EXP_FUN_INDEX, JSFunction, math_exp_fun)                              \
-  V(MATH_FLOOR_FUN_INDEX, JSFunction, math_floor_fun)                          \
-  V(MATH_IMUL_FUN_INDEX, JSFunction, math_imul_fun)                            \
-  V(MATH_LOG_FUN_INDEX, JSFunction, math_log_fun)                              \
-  V(MATH_MAX_FUN_INDEX, JSFunction, math_max_fun)                              \
-  V(MATH_MIN_FUN_INDEX, JSFunction, math_min_fun)                              \
-  V(MATH_POW_FUN_INDEX, JSFunction, math_pow_fun)                              \
-  V(MATH_RANDOM_FUN_INDEX, JSFunction, math_random_fun)                        \
-  V(MATH_ROUND_FUN_INDEX, JSFunction, math_round_fun)                          \
-  V(MATH_SIN_FUN_INDEX, JSFunction, math_sin_fun)                              \
-  V(MATH_SQRT_FUN_INDEX, JSFunction, math_sqrt_fun)                            \
-  V(MATH_TAN_FUN_INDEX, JSFunction, math_tan_fun)                              \
   V(ARRAY_BUFFER_FUN_INDEX, JSFunction, array_buffer_fun)                      \
   V(UINT8_ARRAY_FUN_INDEX, JSFunction, uint8_array_fun)                        \
   V(INT8_ARRAY_FUN_INDEX, JSFunction, int8_array_fun)                          \
@@ -200,9 +182,63 @@
   V(ITERATOR_RESULT_MAP_INDEX, Map, iterator_result_map)                       \
   V(MAP_ITERATOR_MAP_INDEX, Map, map_iterator_map)                             \
   V(SET_ITERATOR_MAP_INDEX, Map, set_iterator_map)                             \
-  V(ITERATOR_SYMBOL_INDEX, Symbol, iterator_symbol)                            \
-  V(UNSCOPABLES_SYMBOL_INDEX, Symbol, unscopables_symbol)                      \
-  V(ARRAY_VALUES_ITERATOR_INDEX, JSFunction, array_values_iterator)
+  V(ARRAY_VALUES_ITERATOR_INDEX, JSFunction, array_values_iterator)            \
+  V(SCRIPT_CONTEXT_TABLE_INDEX, ScriptContextTable, script_context_table)
+
+
+// A table of all script contexts. Every loaded top-level script with top-level
+// lexical declarations contributes its ScriptContext into this table.
+//
+// The table is a fixed array, its first slot is the current used count and
+// the subsequent slots 1..used contain ScriptContexts.
+class ScriptContextTable : public FixedArray {
+ public:
+  // Conversions.
+  static ScriptContextTable* cast(Object* context) {
+    DCHECK(context->IsScriptContextTable());
+    return reinterpret_cast<ScriptContextTable*>(context);
+  }
+
+  struct LookupResult {
+    int context_index;
+    int slot_index;
+    VariableMode mode;
+    InitializationFlag init_flag;
+    MaybeAssignedFlag maybe_assigned_flag;
+  };
+
+  int used() const { return Smi::cast(get(kUsedSlot))->value(); }
+
+  void set_used(int used) { set(kUsedSlot, Smi::FromInt(used)); }
+
+  static Handle<Context> GetContext(Handle<ScriptContextTable> table, int i) {
+    DCHECK(i < table->used());
+    return Handle<Context>::cast(FixedArray::get(table, i + 1));
+  }
+
+  // Lookup a variable `name` in a ScriptContextTable.
+  // If it returns true, the variable is found and `result` contains
+  // valid information about its location.
+  // If it returns false, `result` is untouched.
+  MUST_USE_RESULT
+  static bool Lookup(Handle<ScriptContextTable> table, Handle<String> name,
+                     LookupResult* result);
+
+  MUST_USE_RESULT
+  static Handle<ScriptContextTable> Extend(Handle<ScriptContextTable> table,
+                                           Handle<Context> script_context);
+
+  static int GetContextOffset(int context_index) {
+    return kFirstContextOffset + context_index * kPointerSize;
+  }
+
+ private:
+  static const int kUsedSlot = 0;
+  static const int kFirstContextOffset =
+      FixedArray::kHeaderSize + (kUsedSlot + 1) * kPointerSize;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(ScriptContextTable);
+};
 
 // JSFunctions are pairs (context, function code), sometimes also called
 // closures. A Context object is used to represent function contexts and
@@ -247,7 +283,9 @@
 // properties.
 //
 // Finally, with Harmony scoping, the JSFunction representing a top level
-// script will have the GlobalContext rather than a FunctionContext.
+// script will have the ScriptContext rather than a FunctionContext.
+// Script contexts from all top-level scripts are gathered in
+// ScriptContextTable.
 
 class Context: public FixedArray {
  public:
@@ -312,25 +350,6 @@
     GLOBAL_EVAL_FUN_INDEX,
     INSTANTIATE_FUN_INDEX,
     CONFIGURE_INSTANCE_FUN_INDEX,
-    MATH_ABS_FUN_INDEX,
-    MATH_ACOS_FUN_INDEX,
-    MATH_ASIN_FUN_INDEX,
-    MATH_ATAN_FUN_INDEX,
-    MATH_ATAN2_FUN_INDEX,
-    MATH_CEIL_FUN_INDEX,
-    MATH_COS_FUN_INDEX,
-    MATH_EXP_FUN_INDEX,
-    MATH_FLOOR_FUN_INDEX,
-    MATH_IMUL_FUN_INDEX,
-    MATH_LOG_FUN_INDEX,
-    MATH_MAX_FUN_INDEX,
-    MATH_MIN_FUN_INDEX,
-    MATH_POW_FUN_INDEX,
-    MATH_RANDOM_FUN_INDEX,
-    MATH_ROUND_FUN_INDEX,
-    MATH_SIN_FUN_INDEX,
-    MATH_SQRT_FUN_INDEX,
-    MATH_TAN_FUN_INDEX,
     ARRAY_BUFFER_FUN_INDEX,
     UINT8_ARRAY_FUN_INDEX,
     INT8_ARRAY_FUN_INDEX,
@@ -395,16 +414,16 @@
     ITERATOR_RESULT_MAP_INDEX,
     MAP_ITERATOR_MAP_INDEX,
     SET_ITERATOR_MAP_INDEX,
-    ITERATOR_SYMBOL_INDEX,
-    UNSCOPABLES_SYMBOL_INDEX,
     ARRAY_VALUES_ITERATOR_INDEX,
+    SCRIPT_CONTEXT_TABLE_INDEX,
+    MAP_CACHE_INDEX,
+    TO_LENGTH_FUN_INDEX,
 
     // Properties from here are treated as weak references by the full GC.
     // Scavenge treats them as strong references.
     OPTIMIZED_FUNCTIONS_LIST,  // Weak.
     OPTIMIZED_CODE_LIST,       // Weak.
     DEOPTIMIZED_CODE_LIST,     // Weak.
-    MAP_CACHE_INDEX,           // Weak.
     NEXT_CONTEXT_LINK,         // Weak.
 
     // Total number of slots.
@@ -450,8 +469,8 @@
   // The builtins object.
   JSBuiltinsObject* builtins();
 
-  // Get the innermost global context by traversing the context chain.
-  Context* global_context();
+  // Get the script context by traversing the context chain.
+  Context* script_context();
 
   // Compute the native context by traversing the context chain.
   Context* native_context();
@@ -483,9 +502,9 @@
     Map* map = this->map();
     return map == map->GetHeap()->module_context_map();
   }
-  bool IsGlobalContext() {
+  bool IsScriptContext() {
     Map* map = this->map();
-    return map == map->GetHeap()->global_context_map();
+    return map == map->GetHeap()->script_context_map();
   }
 
   bool HasSameSecurityTokenAs(Context* that) {
diff --git a/src/conversions.cc b/src/conversions.cc
index 8b77623..663f4e8 100644
--- a/src/conversions.cc
+++ b/src/conversions.cc
@@ -483,19 +483,21 @@
 }
 
 
-double StringToDouble(UnicodeCache* unicode_cache,
-                      String* string,
-                      int flags,
-                      double empty_string_val) {
-  DisallowHeapAllocation no_gc;
-  String::FlatContent flat = string->GetFlatContent();
-  // ECMA-262 section 15.1.2.3, empty string is NaN
-  if (flat.IsOneByte()) {
-    return StringToDouble(
-        unicode_cache, flat.ToOneByteVector(), flags, empty_string_val);
-  } else {
-    return StringToDouble(
-        unicode_cache, flat.ToUC16Vector(), flags, empty_string_val);
+double StringToDouble(UnicodeCache* unicode_cache, Handle<String> string,
+                      int flags, double empty_string_val) {
+  Handle<String> flattened = String::Flatten(string);
+  {
+    DisallowHeapAllocation no_gc;
+    String::FlatContent flat = flattened->GetFlatContent();
+    DCHECK(flat.IsFlat());
+    // ECMA-262 section 15.1.2.3, empty string is NaN
+    if (flat.IsOneByte()) {
+      return StringToDouble(unicode_cache, flat.ToOneByteVector(), flags,
+                            empty_string_val);
+    } else {
+      return StringToDouble(unicode_cache, flat.ToUC16Vector(), flags,
+                            empty_string_val);
+    }
   }
 }
 
diff --git a/src/conversions.h b/src/conversions.h
index 6a28b5f..5afd4e1 100644
--- a/src/conversions.h
+++ b/src/conversions.h
@@ -198,10 +198,8 @@
 }
 
 
-double StringToDouble(UnicodeCache* unicode_cache,
-                      String* string,
-                      int flags,
-                      double empty_string_val = 0.0);
+double StringToDouble(UnicodeCache* unicode_cache, Handle<String> string,
+                      int flags, double empty_string_val = 0.0);
 
 
 inline bool TryNumberToSize(Isolate* isolate,
diff --git a/src/counters.cc b/src/counters.cc
index a8dcc0b..972bd68 100644
--- a/src/counters.cc
+++ b/src/counters.cc
@@ -7,6 +7,7 @@
 #include "src/base/platform/platform.h"
 #include "src/counters.h"
 #include "src/isolate.h"
+#include "src/log-inl.h"
 
 namespace v8 {
 namespace internal {
@@ -39,7 +40,7 @@
   if (Enabled()) {
     timer_.Start();
   }
-  isolate()->event_logger()(name(), Logger::START);
+  Logger::CallEventLogger(isolate(), name(), Logger::START, true);
 }
 
 
@@ -50,7 +51,7 @@
     AddSample(static_cast<int>(timer_.Elapsed().InMilliseconds()));
     timer_.Stop();
   }
-  isolate()->event_logger()(name(), Logger::END);
+  Logger::CallEventLogger(isolate(), name(), Logger::END, true);
 }
 
 
diff --git a/src/counters.h b/src/counters.h
index 651cf54..41107cf 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -489,7 +489,6 @@
   SC(for_in, V8.ForIn)                                                         \
   SC(enum_cache_hits, V8.EnumCacheHits)                                        \
   SC(enum_cache_misses, V8.EnumCacheMisses)                                    \
-  SC(zone_segment_bytes, V8.ZoneSegmentBytes)                                  \
   SC(fast_new_closure_total, V8.FastNewClosureTotal)                           \
   SC(fast_new_closure_try_optimized, V8.FastNewClosureTryOptimized)            \
   SC(fast_new_closure_install_optimized, V8.FastNewClosureInstallOptimized)    \
diff --git a/src/cpu-profiler.cc b/src/cpu-profiler.cc
index 68a565c..456770b 100644
--- a/src/cpu-profiler.cc
+++ b/src/cpu-profiler.cc
@@ -20,17 +20,16 @@
 static const int kProfilerStackSize = 64 * KB;
 
 
-ProfilerEventsProcessor::ProfilerEventsProcessor(
-    ProfileGenerator* generator,
-    Sampler* sampler,
-    base::TimeDelta period)
+ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator,
+                                                 Sampler* sampler,
+                                                 base::TimeDelta period)
     : Thread(Thread::Options("v8:ProfEvntProc", kProfilerStackSize)),
       generator_(generator),
       sampler_(sampler),
-      running_(true),
+      running_(1),
       period_(period),
-      last_code_event_id_(0), last_processed_code_event_id_(0) {
-}
+      last_code_event_id_(0),
+      last_processed_code_event_id_(0) {}
 
 
 void ProfilerEventsProcessor::Enqueue(const CodeEventsContainer& event) {
@@ -49,14 +48,13 @@
     regs.fp = frame->fp();
     regs.pc = frame->pc();
   }
-  record.sample.Init(isolate, regs);
+  record.sample.Init(isolate, regs, TickSample::kSkipCEntryFrame);
   ticks_from_vm_buffer_.Enqueue(record);
 }
 
 
 void ProfilerEventsProcessor::StopSynchronously() {
-  if (!running_) return;
-  running_ = false;
+  if (!base::NoBarrier_AtomicExchange(&running_, 0)) return;
   Join();
 }
 
@@ -107,7 +105,7 @@
 
 
 void ProfilerEventsProcessor::Run() {
-  while (running_) {
+  while (!!base::NoBarrier_Load(&running_)) {
     base::ElapsedTimer timer;
     timer.Start();
     // Keep processing existing events until we need to do next sample.
@@ -201,7 +199,10 @@
   CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
   CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
   rec->start = code->address();
-  rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name));
+  rec->entry = profiles_->NewCodeEntry(
+      tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
+      CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
+      CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
   rec->size = code->ExecutableSize();
   rec->shared = NULL;
   processor_->Enqueue(evt_rec);
@@ -215,7 +216,10 @@
   CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
   CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
   rec->start = code->address();
-  rec->entry = profiles_->NewCodeEntry(tag, profiles_->GetFunctionName(name));
+  rec->entry = profiles_->NewCodeEntry(
+      tag, profiles_->GetFunctionName(name), CodeEntry::kEmptyNamePrefix,
+      CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
+      CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
   rec->size = code->ExecutableSize();
   rec->shared = NULL;
   processor_->Enqueue(evt_rec);
@@ -231,7 +235,9 @@
   rec->start = code->address();
   rec->entry = profiles_->NewCodeEntry(
       tag, profiles_->GetFunctionName(shared->DebugName()),
-      CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name));
+      CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name),
+      CpuProfileNode::kNoLineNumberInfo, CpuProfileNode::kNoColumnNumberInfo,
+      NULL, code->instruction_start());
   if (info) {
     rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges());
   }
@@ -240,7 +246,7 @@
     Script* script = Script::cast(shared->script());
     rec->entry->set_script_id(script->id()->value());
     rec->entry->set_bailout_reason(
-        GetBailoutReason(shared->DisableOptimizationReason()));
+        GetBailoutReason(shared->disable_optimization_reason()));
   }
   rec->size = code->ExecutableSize();
   rec->shared = shared->address();
@@ -256,20 +262,34 @@
   CodeEventsContainer evt_rec(CodeEventRecord::CODE_CREATION);
   CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
   rec->start = code->address();
+  Script* script = Script::cast(shared->script());
+  JITLineInfoTable* line_table = NULL;
+  if (script) {
+    line_table = new JITLineInfoTable();
+    for (RelocIterator it(code); !it.done(); it.next()) {
+      RelocInfo::Mode mode = it.rinfo()->rmode();
+      if (RelocInfo::IsPosition(mode)) {
+        int position = static_cast<int>(it.rinfo()->data());
+        if (position >= 0) {
+          int pc_offset = static_cast<int>(it.rinfo()->pc() - code->address());
+          int line_number = script->GetLineNumber(position);
+          line_table->SetPosition(pc_offset, line_number + 1);
+        }
+      }
+    }
+  }
   rec->entry = profiles_->NewCodeEntry(
       tag, profiles_->GetFunctionName(shared->DebugName()),
       CodeEntry::kEmptyNamePrefix, profiles_->GetName(script_name), line,
-      column);
+      column, line_table, code->instruction_start());
   if (info) {
     rec->entry->set_no_frame_ranges(info->ReleaseNoFrameRanges());
   }
-  DCHECK(Script::cast(shared->script()));
-  Script* script = Script::cast(shared->script());
   rec->entry->set_script_id(script->id()->value());
   rec->size = code->ExecutableSize();
   rec->shared = shared->address();
   rec->entry->set_bailout_reason(
-      GetBailoutReason(shared->DisableOptimizationReason()));
+      GetBailoutReason(shared->disable_optimization_reason()));
   processor_->Enqueue(evt_rec);
 }
 
@@ -282,9 +302,9 @@
   CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
   rec->start = code->address();
   rec->entry = profiles_->NewCodeEntry(
-      tag,
-      profiles_->GetName(args_count),
-      "args_count: ");
+      tag, profiles_->GetName(args_count), "args_count: ",
+      CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
+      CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
   rec->size = code->ExecutableSize();
   rec->shared = NULL;
   processor_->Enqueue(evt_rec);
@@ -304,7 +324,7 @@
   CodeEventsContainer evt_rec(CodeEventRecord::CODE_DISABLE_OPT);
   CodeDisableOptEventRecord* rec = &evt_rec.CodeDisableOptEventRecord_;
   rec->start = code->address();
-  rec->bailout_reason = GetBailoutReason(shared->DisableOptimizationReason());
+  rec->bailout_reason = GetBailoutReason(shared->disable_optimization_reason());
   processor_->Enqueue(evt_rec);
 }
 
@@ -344,9 +364,9 @@
   CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
   rec->start = code->address();
   rec->entry = profiles_->NewCodeEntry(
-      Logger::REG_EXP_TAG,
-      profiles_->GetName(source),
-      "RegExp: ");
+      Logger::REG_EXP_TAG, profiles_->GetName(source), "RegExp: ",
+      CodeEntry::kEmptyResourceName, CpuProfileNode::kNoLineNumberInfo,
+      CpuProfileNode::kNoColumnNumberInfo, NULL, code->instruction_start());
   rec->size = code->ExecutableSize();
   processor_->Enqueue(evt_rec);
 }
diff --git a/src/cpu-profiler.h b/src/cpu-profiler.h
index c1e75a1..4dc5643 100644
--- a/src/cpu-profiler.h
+++ b/src/cpu-profiler.h
@@ -132,7 +132,7 @@
   // Thread control.
   virtual void Run();
   void StopSynchronously();
-  INLINE(bool running()) { return running_; }
+  INLINE(bool running()) { return !!base::NoBarrier_Load(&running_); }
   void Enqueue(const CodeEventsContainer& event);
 
   // Puts current stack into tick sample events buffer.
@@ -163,7 +163,7 @@
 
   ProfileGenerator* generator_;
   Sampler* sampler_;
-  bool running_;
+  base::Atomic32 running_;
   // Sampling period in microseconds.
   const base::TimeDelta period_;
   UnboundQueue<CodeEventsContainer> events_buffer_;
diff --git a/src/d8-debug.cc b/src/d8-debug.cc
index 71e006c..7032415 100644
--- a/src/d8-debug.cc
+++ b/src/d8-debug.cc
@@ -124,7 +124,7 @@
       printf("%s\n", *text_str);
     }
     running = response_details->Get(String::NewFromUtf8(isolate, "running"))
-                  ->ToBoolean()
+                  ->ToBoolean(isolate)
                   ->Value();
   }
 }
diff --git a/src/d8.cc b/src/d8.cc
index 9db7744..7157cb8 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -8,10 +8,6 @@
 #define V8_SHARED
 #endif
 
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-#include <bzlib.h>
-#endif
-
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
@@ -46,6 +42,7 @@
 #include "src/base/logging.h"
 #include "src/base/platform/platform.h"
 #include "src/base/sys-info.h"
+#include "src/basic-block-profiler.h"
 #include "src/d8-debug.h"
 #include "src/debug.h"
 #include "src/natives.h"
@@ -176,33 +173,77 @@
 }
 
 
+ScriptCompiler::CachedData* CompileForCachedData(
+    Local<String> source, Local<Value> name,
+    ScriptCompiler::CompileOptions compile_options) {
+  int source_length = source->Length();
+  uint16_t* source_buffer = new uint16_t[source_length];
+  source->Write(source_buffer, 0, source_length);
+  int name_length = 0;
+  uint16_t* name_buffer = NULL;
+  if (name->IsString()) {
+    Local<String> name_string = Local<String>::Cast(name);
+    name_length = name_string->Length();
+    name_buffer = new uint16_t[name_length];
+    name_string->Write(name_buffer, 0, name_length);
+  }
+  Isolate* temp_isolate = Isolate::New();
+  ScriptCompiler::CachedData* result = NULL;
+  {
+    Isolate::Scope isolate_scope(temp_isolate);
+    HandleScope handle_scope(temp_isolate);
+    Context::Scope context_scope(Context::New(temp_isolate));
+    Local<String> source_copy = v8::String::NewFromTwoByte(
+        temp_isolate, source_buffer, v8::String::kNormalString, source_length);
+    Local<Value> name_copy;
+    if (name_buffer) {
+      name_copy = v8::String::NewFromTwoByte(
+          temp_isolate, name_buffer, v8::String::kNormalString, name_length);
+    } else {
+      name_copy = v8::Undefined(temp_isolate);
+    }
+    ScriptCompiler::Source script_source(source_copy, ScriptOrigin(name_copy));
+    ScriptCompiler::CompileUnbound(temp_isolate, &script_source,
+                                   compile_options);
+    if (script_source.GetCachedData()) {
+      int length = script_source.GetCachedData()->length;
+      uint8_t* cache = new uint8_t[length];
+      memcpy(cache, script_source.GetCachedData()->data, length);
+      result = new ScriptCompiler::CachedData(
+          cache, length, ScriptCompiler::CachedData::BufferOwned);
+    }
+  }
+  temp_isolate->Dispose();
+  delete[] source_buffer;
+  delete[] name_buffer;
+  return result;
+}
+
+
 // Compile a string within the current v8 context.
 Local<UnboundScript> Shell::CompileString(
     Isolate* isolate, Local<String> source, Local<Value> name,
-    v8::ScriptCompiler::CompileOptions compile_options) {
+    ScriptCompiler::CompileOptions compile_options) {
   ScriptOrigin origin(name);
-  ScriptCompiler::Source script_source(source, origin);
-  Local<UnboundScript> script =
-      ScriptCompiler::CompileUnbound(isolate, &script_source, compile_options);
-
-  // Was caching requested & successful? Then compile again, now with cache.
-  if (script_source.GetCachedData()) {
-    if (compile_options == ScriptCompiler::kProduceCodeCache) {
-      compile_options = ScriptCompiler::kConsumeCodeCache;
-    } else if (compile_options == ScriptCompiler::kProduceParserCache) {
-      compile_options = ScriptCompiler::kConsumeParserCache;
-    } else {
-      DCHECK(false);  // A new compile option?
-    }
-    ScriptCompiler::Source cached_source(
-        source, origin, new v8::ScriptCompiler::CachedData(
-                            script_source.GetCachedData()->data,
-                            script_source.GetCachedData()->length,
-                            v8::ScriptCompiler::CachedData::BufferNotOwned));
-    script = ScriptCompiler::CompileUnbound(isolate, &cached_source,
-                                            compile_options);
+  if (compile_options == ScriptCompiler::kNoCompileOptions) {
+    ScriptCompiler::Source script_source(source, origin);
+    return ScriptCompiler::CompileUnbound(isolate, &script_source,
+                                          compile_options);
   }
-  return script;
+
+  ScriptCompiler::CachedData* data =
+      CompileForCachedData(source, name, compile_options);
+  ScriptCompiler::Source cached_source(source, origin, data);
+  if (compile_options == ScriptCompiler::kProduceCodeCache) {
+    compile_options = ScriptCompiler::kConsumeCodeCache;
+  } else if (compile_options == ScriptCompiler::kProduceParserCache) {
+    compile_options = ScriptCompiler::kConsumeParserCache;
+  } else {
+    DCHECK(false);  // A new compile option?
+  }
+  if (data == NULL) compile_options = ScriptCompiler::kNoCompileOptions;
+  return ScriptCompiler::CompileUnbound(isolate, &cached_source,
+                                        compile_options);
 }
 
 
@@ -365,7 +406,7 @@
     Throw(args.GetIsolate(), "Invalid argument");
     return;
   }
-  int index = data->RealmFind(args[0]->ToObject()->CreationContext());
+  int index = data->RealmFind(args[0]->ToObject(isolate)->CreationContext());
   if (index == -1) return;
   args.GetReturnValue().Set(index);
 }
@@ -435,7 +476,7 @@
     Throw(args.GetIsolate(), "Invalid argument");
     return;
   }
-  ScriptCompiler::Source script_source(args[1]->ToString());
+  ScriptCompiler::Source script_source(args[1]->ToString(isolate));
   Handle<UnboundScript> script = ScriptCompiler::CompileUnbound(
       isolate, &script_source);
   if (script.IsEmpty()) return;
@@ -481,7 +522,7 @@
 
     // Explicitly catch potential exceptions in toString().
     v8::TryCatch try_catch;
-    Handle<String> str_obj = args[i]->ToString();
+    Handle<String> str_obj = args[i]->ToString(args.GetIsolate());
     if (try_catch.HasCaught()) {
       try_catch.ReThrow();
       return;
@@ -572,7 +613,7 @@
 
 void Shell::Quit(const v8::FunctionCallbackInfo<v8::Value>& args) {
   int exit_code = args[0]->Int32Value();
-  OnExit();
+  OnExit(args.GetIsolate());
   exit(exit_code);
 }
 
@@ -810,7 +851,7 @@
   // Run the d8 shell utility script in the utility context
   int source_index = i::NativesCollection<i::D8>::GetIndex("d8");
   i::Vector<const char> shell_source =
-      i::NativesCollection<i::D8>::GetRawScriptSource(source_index);
+      i::NativesCollection<i::D8>::GetScriptSource(source_index);
   i::Vector<const char> shell_source_name =
       i::NativesCollection<i::D8>::GetScriptName(source_index);
   Handle<String> source =
@@ -838,34 +879,6 @@
 #endif  // !V8_SHARED
 
 
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-class BZip2Decompressor : public v8::StartupDataDecompressor {
- public:
-  virtual ~BZip2Decompressor() { }
-
- protected:
-  virtual int DecompressData(char* raw_data,
-                             int* raw_data_size,
-                             const char* compressed_data,
-                             int compressed_data_size) {
-    DCHECK_EQ(v8::StartupData::kBZip2,
-              v8::V8::GetCompressedStartupDataAlgorithm());
-    unsigned int decompressed_size = *raw_data_size;
-    int result =
-        BZ2_bzBuffToBuffDecompress(raw_data,
-                                   &decompressed_size,
-                                   const_cast<char*>(compressed_data),
-                                   compressed_data_size,
-                                   0, 1);
-    if (result == BZ_OK) {
-      *raw_data_size = decompressed_size;
-    }
-    return result;
-  }
-};
-#endif
-
-
 Handle<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
   Handle<ObjectTemplate> global_template = ObjectTemplate::New(isolate);
   global_template->Set(String::NewFromUtf8(isolate, "print"),
@@ -922,15 +935,6 @@
 
 
 void Shell::Initialize(Isolate* isolate) {
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-  BZip2Decompressor startup_data_decompressor;
-  int bz2_result = startup_data_decompressor.Decompress();
-  if (bz2_result != BZ_OK) {
-    fprintf(stderr, "bzip error code: %d\n", bz2_result);
-    Exit(1);
-  }
-#endif
-
 #ifndef V8_SHARED
   Shell::counter_map_ = new CounterMap();
   // Set up counters
@@ -1009,10 +1013,11 @@
 #endif  // !V8_SHARED
 
 
-void Shell::OnExit() {
+void Shell::OnExit(v8::Isolate* isolate) {
   LineEditor* line_editor = LineEditor::Get();
   if (line_editor) line_editor->Close();
 #ifndef V8_SHARED
+  reinterpret_cast<i::Isolate*>(isolate)->DumpAndResetCompilationStats();
   if (i::FLAG_dump_counters) {
     int number_of_counters = 0;
     for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) {
@@ -1534,25 +1539,30 @@
 
 class MockArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
  public:
-  virtual void* Allocate(size_t) OVERRIDE {
-    return malloc(0);
-  }
-  virtual void* AllocateUninitialized(size_t length) OVERRIDE {
-    return malloc(0);
-  }
-  virtual void Free(void* p, size_t) OVERRIDE {
-    free(p);
-  }
+  void* Allocate(size_t) OVERRIDE { return malloc(0); }
+  void* AllocateUninitialized(size_t length) OVERRIDE { return malloc(0); }
+  void Free(void* p, size_t) OVERRIDE { free(p); }
 };
 
 
 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
 class StartupDataHandler {
  public:
-  StartupDataHandler(const char* natives_blob,
+  StartupDataHandler(const char* exec_path, const char* natives_blob,
                      const char* snapshot_blob) {
-    Load(natives_blob, &natives_, v8::V8::SetNativesDataBlob);
-    Load(snapshot_blob, &snapshot_, v8::V8::SetSnapshotDataBlob);
+    // If we have (at least one) explicitly given blob, use those.
+    // If not, use the default blob locations next to the d8 binary.
+    if (natives_blob || snapshot_blob) {
+      LoadFromFiles(natives_blob, snapshot_blob);
+    } else {
+      char* natives;
+      char* snapshot;
+      LoadFromFiles(RelativePath(&natives, exec_path, "natives_blob.bin"),
+                    RelativePath(&snapshot, exec_path, "snapshot_blob.bin"));
+
+      free(natives);
+      free(snapshot);
+    }
   }
 
   ~StartupDataHandler() {
@@ -1561,11 +1571,32 @@
   }
 
  private:
+  static char* RelativePath(char** buffer, const char* exec_path,
+                            const char* name) {
+    DCHECK(exec_path);
+    const char* last_slash = strrchr(exec_path, '/');
+    if (last_slash) {
+      int after_slash = last_slash - exec_path + 1;
+      int name_length = static_cast<int>(strlen(name));
+      *buffer =
+          reinterpret_cast<char*>(calloc(after_slash + name_length + 1, 1));
+      strncpy(*buffer, exec_path, after_slash);
+      strncat(*buffer, name, name_length);
+    } else {
+      *buffer = strdup(name);
+    }
+    return *buffer;
+  }
+
+  void LoadFromFiles(const char* natives_blob, const char* snapshot_blob) {
+    Load(natives_blob, &natives_, v8::V8::SetNativesDataBlob);
+    Load(snapshot_blob, &snapshot_, v8::V8::SetSnapshotDataBlob);
+  }
+
   void Load(const char* blob_file,
             v8::StartupData* startup_data,
             void (*setter_fn)(v8::StartupData*)) {
     startup_data->data = NULL;
-    startup_data->compressed_size = 0;
     startup_data->raw_size = 0;
 
     if (!blob_file)
@@ -1580,13 +1611,12 @@
     rewind(file);
 
     startup_data->data = new char[startup_data->raw_size];
-    startup_data->compressed_size = fread(
-        const_cast<char*>(startup_data->data), 1, startup_data->raw_size,
-        file);
+    int read_size =
+        static_cast<int>(fread(const_cast<char*>(startup_data->data), 1,
+                               startup_data->raw_size, file));
     fclose(file);
 
-    if (startup_data->raw_size == startup_data->compressed_size)
-      (*setter_fn)(startup_data);
+    if (startup_data->raw_size == read_size) (*setter_fn)(startup_data);
   }
 
   v8::StartupData natives_;
@@ -1621,9 +1651,11 @@
   v8::V8::InitializePlatform(platform);
   v8::V8::Initialize();
 #ifdef V8_USE_EXTERNAL_STARTUP_DATA
-  StartupDataHandler startup_data(options.natives_blob, options.snapshot_blob);
+  StartupDataHandler startup_data(argv[0], options.natives_blob,
+                                  options.snapshot_blob);
 #endif
   SetFlagsFromString("--trace-hydrogen-file=hydrogen.cfg");
+  SetFlagsFromString("--trace-turbo-cfg-file=turbo.cfg");
   SetFlagsFromString("--redirect-code-traces-to=code.asm");
   ShellArrayBufferAllocator array_buffer_allocator;
   MockArrayBufferAllocator mock_arraybuffer_allocator;
@@ -1640,7 +1672,7 @@
   }
 #endif
 #ifdef ENABLE_VTUNE_JIT_INTERFACE
-  vTune::InitializeVtuneForV8(create_params);
+  create_params.code_event_handler = vTune::GetVtuneCodeEventHandler();
 #endif
 #ifndef V8_SHARED
   create_params.constraints.ConfigureDefaults(
@@ -1700,13 +1732,20 @@
       RunShell(isolate);
     }
   }
+  OnExit(isolate);
+#ifndef V8_SHARED
+  // Dump basic block profiling data.
+  if (i::BasicBlockProfiler* profiler =
+          reinterpret_cast<i::Isolate*>(isolate)->basic_block_profiler()) {
+    i::OFStream os(stdout);
+    os << *profiler;
+  }
+#endif  // !V8_SHARED
   isolate->Dispose();
   V8::Dispose();
   V8::ShutdownPlatform();
   delete platform;
 
-  OnExit();
-
   return result;
 }
 
diff --git a/src/d8.gyp b/src/d8.gyp
index a084979..e536584 100644
--- a/src/d8.gyp
+++ b/src/d8.gyp
@@ -129,7 +129,6 @@
             '../tools/js2c.py',
             '<@(_outputs)',
             'D8',
-            'off',  # compress startup data
             '<@(js_files)'
           ],
         },
diff --git a/src/d8.h b/src/d8.h
index 44ee09a..caa5a0a 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -263,7 +263,7 @@
   static int RunMain(Isolate* isolate, int argc, char* argv[]);
   static int Main(int argc, char* argv[]);
   static void Exit(int exit_code);
-  static void OnExit();
+  static void OnExit(Isolate* isolate);
 
 #ifndef V8_SHARED
   static Handle<Array> GetCompletions(Isolate* isolate,
diff --git a/src/data-flow.cc b/src/data-flow.cc
deleted file mode 100644
index bd92ea0..0000000
--- a/src/data-flow.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/data-flow.h"
-
-#include "src/base/bits.h"
-#include "src/scopes.h"
-
-namespace v8 {
-namespace internal {
-
-#ifdef DEBUG
-void BitVector::Print() {
-  bool first = true;
-  PrintF("{");
-  for (int i = 0; i < length(); i++) {
-    if (Contains(i)) {
-      if (!first) PrintF(",");
-      first = false;
-      PrintF("%d", i);
-    }
-  }
-  PrintF("}");
-}
-#endif
-
-
-void BitVector::Iterator::Advance() {
-  current_++;
-  uint32_t val = current_value_;
-  while (val == 0) {
-    current_index_++;
-    if (Done()) return;
-    val = target_->data_[current_index_];
-    current_ = current_index_ << 5;
-  }
-  val = SkipZeroBytes(val);
-  val = SkipZeroBits(val);
-  current_value_ = val >> 1;
-}
-
-
-int BitVector::Count() const {
-  int count = 0;
-  for (int i = 0; i < data_length_; i++) {
-    int data = data_[i];
-    if (data != 0) count += base::bits::CountPopulation32(data);
-  }
-  return count;
-}
-
-}  // namespace internal
-}  // namespace v8
diff --git a/src/data-flow.h b/src/data-flow.h
deleted file mode 100644
index bfd238d..0000000
--- a/src/data-flow.h
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_DATAFLOW_H_
-#define V8_DATAFLOW_H_
-
-#include "src/v8.h"
-
-#include "src/allocation.h"
-#include "src/ast.h"
-#include "src/compiler.h"
-#include "src/zone-inl.h"
-
-namespace v8 {
-namespace internal {
-
-class BitVector: public ZoneObject {
- public:
-  // Iterator for the elements of this BitVector.
-  class Iterator BASE_EMBEDDED {
-   public:
-    explicit Iterator(BitVector* target)
-        : target_(target),
-          current_index_(0),
-          current_value_(target->data_[0]),
-          current_(-1) {
-      DCHECK(target->data_length_ > 0);
-      Advance();
-    }
-    ~Iterator() { }
-
-    bool Done() const { return current_index_ >= target_->data_length_; }
-    void Advance();
-
-    int Current() const {
-      DCHECK(!Done());
-      return current_;
-    }
-
-   private:
-    uint32_t SkipZeroBytes(uint32_t val) {
-      while ((val & 0xFF) == 0) {
-        val >>= 8;
-        current_ += 8;
-      }
-      return val;
-    }
-    uint32_t SkipZeroBits(uint32_t val) {
-      while ((val & 0x1) == 0) {
-        val >>= 1;
-        current_++;
-      }
-      return val;
-    }
-
-    BitVector* target_;
-    int current_index_;
-    uint32_t current_value_;
-    int current_;
-
-    friend class BitVector;
-  };
-
-  BitVector(int length, Zone* zone)
-      : length_(length),
-        data_length_(SizeFor(length)),
-        data_(zone->NewArray<uint32_t>(data_length_)) {
-    DCHECK(length > 0);
-    Clear();
-  }
-
-  BitVector(const BitVector& other, Zone* zone)
-      : length_(other.length()),
-        data_length_(SizeFor(length_)),
-        data_(zone->NewArray<uint32_t>(data_length_)) {
-    CopyFrom(other);
-  }
-
-  static int SizeFor(int length) {
-    return 1 + ((length - 1) / 32);
-  }
-
-  BitVector& operator=(const BitVector& rhs) {
-    if (this != &rhs) CopyFrom(rhs);
-    return *this;
-  }
-
-  void CopyFrom(const BitVector& other) {
-    DCHECK(other.length() <= length());
-    for (int i = 0; i < other.data_length_; i++) {
-      data_[i] = other.data_[i];
-    }
-    for (int i = other.data_length_; i < data_length_; i++) {
-      data_[i] = 0;
-    }
-  }
-
-  bool Contains(int i) const {
-    DCHECK(i >= 0 && i < length());
-    uint32_t block = data_[i / 32];
-    return (block & (1U << (i % 32))) != 0;
-  }
-
-  void Add(int i) {
-    DCHECK(i >= 0 && i < length());
-    data_[i / 32] |= (1U << (i % 32));
-  }
-
-  void Remove(int i) {
-    DCHECK(i >= 0 && i < length());
-    data_[i / 32] &= ~(1U << (i % 32));
-  }
-
-  void Union(const BitVector& other) {
-    DCHECK(other.length() == length());
-    for (int i = 0; i < data_length_; i++) {
-      data_[i] |= other.data_[i];
-    }
-  }
-
-  bool UnionIsChanged(const BitVector& other) {
-    DCHECK(other.length() == length());
-    bool changed = false;
-    for (int i = 0; i < data_length_; i++) {
-      uint32_t old_data = data_[i];
-      data_[i] |= other.data_[i];
-      if (data_[i] != old_data) changed = true;
-    }
-    return changed;
-  }
-
-  void Intersect(const BitVector& other) {
-    DCHECK(other.length() == length());
-    for (int i = 0; i < data_length_; i++) {
-      data_[i] &= other.data_[i];
-    }
-  }
-
-  bool IntersectIsChanged(const BitVector& other) {
-    DCHECK(other.length() == length());
-    bool changed = false;
-    for (int i = 0; i < data_length_; i++) {
-      uint32_t old_data = data_[i];
-      data_[i] &= other.data_[i];
-      if (data_[i] != old_data) changed = true;
-    }
-    return changed;
-  }
-
-  void Subtract(const BitVector& other) {
-    DCHECK(other.length() == length());
-    for (int i = 0; i < data_length_; i++) {
-      data_[i] &= ~other.data_[i];
-    }
-  }
-
-  void Clear() {
-    for (int i = 0; i < data_length_; i++) {
-      data_[i] = 0;
-    }
-  }
-
-  bool IsEmpty() const {
-    for (int i = 0; i < data_length_; i++) {
-      if (data_[i] != 0) return false;
-    }
-    return true;
-  }
-
-  bool Equals(const BitVector& other) {
-    for (int i = 0; i < data_length_; i++) {
-      if (data_[i] != other.data_[i]) return false;
-    }
-    return true;
-  }
-
-  int Count() const;
-
-  int length() const { return length_; }
-
-#ifdef DEBUG
-  void Print();
-#endif
-
- private:
-  int length_;
-  int data_length_;
-  uint32_t* data_;
-};
-
-
-class GrowableBitVector BASE_EMBEDDED {
- public:
-  class Iterator BASE_EMBEDDED {
-   public:
-    Iterator(const GrowableBitVector* target, Zone* zone)
-        : it_(target->bits_ == NULL
-              ? new(zone) BitVector(1, zone)
-              : target->bits_) { }
-    bool Done() const { return it_.Done(); }
-    void Advance() { it_.Advance(); }
-    int Current() const { return it_.Current(); }
-   private:
-    BitVector::Iterator it_;
-  };
-
-  GrowableBitVector() : bits_(NULL) { }
-  GrowableBitVector(int length, Zone* zone)
-      : bits_(new(zone) BitVector(length, zone)) { }
-
-  bool Contains(int value) const {
-    if (!InBitsRange(value)) return false;
-    return bits_->Contains(value);
-  }
-
-  void Add(int value, Zone* zone) {
-    EnsureCapacity(value, zone);
-    bits_->Add(value);
-  }
-
-  void Union(const GrowableBitVector& other, Zone* zone) {
-    for (Iterator it(&other, zone); !it.Done(); it.Advance()) {
-      Add(it.Current(), zone);
-    }
-  }
-
-  void Clear() { if (bits_ != NULL) bits_->Clear(); }
-
- private:
-  static const int kInitialLength = 1024;
-
-  bool InBitsRange(int value) const {
-    return bits_ != NULL && bits_->length() > value;
-  }
-
-  void EnsureCapacity(int value, Zone* zone) {
-    if (InBitsRange(value)) return;
-    int new_length = bits_ == NULL ? kInitialLength : bits_->length();
-    while (new_length <= value) new_length *= 2;
-    BitVector* new_bits = new(zone) BitVector(new_length, zone);
-    if (bits_ != NULL) new_bits->CopyFrom(*bits_);
-    bits_ = new_bits;
-  }
-
-  BitVector* bits_;
-};
-
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_DATAFLOW_H_
diff --git a/src/debug-debugger.js b/src/debug-debugger.js
index a1468a0..c24b478 100644
--- a/src/debug-debugger.js
+++ b/src/debug-debugger.js
@@ -1,6 +1,7 @@
 // Copyright 2012 the V8 project authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
+"use strict";
 
 // Default number of frames to include in the response to backtrace request.
 var kDefaultBacktraceLength = 10;
@@ -33,7 +34,8 @@
                      StepNext: 1,
                      StepIn: 2,
                      StepMin: 3,
-                     StepInMin: 4 };
+                     StepInMin: 4,
+                     StepFrame: 5 };
 
 // The different types of scripts matching enum ScriptType in objects.h.
 Debug.ScriptType = { Native: 0,
@@ -431,7 +433,7 @@
   if (IS_NULL(position)) return;
 
   // Create a break point object and set the break point.
-  break_point = MakeBreakPoint(position, this);
+  var break_point = MakeBreakPoint(position, this);
   break_point.setIgnoreCount(this.ignoreCount());
   var actual_position = %SetScriptBreakPoint(script, position,
                                              this.position_alignment_,
@@ -671,7 +673,7 @@
                                                     condition, enabled,
                                                     opt_position_alignment)
 {
-  break_point = MakeBreakPoint(position);
+  var break_point = MakeBreakPoint(position);
   break_point.setCondition(condition);
   if (!enabled) {
     break_point.disable();
@@ -738,7 +740,7 @@
 
 Debug.clearAllBreakPoints = function() {
   for (var i = 0; i < break_points.length; i++) {
-    break_point = break_points[i];
+    var break_point = break_points[i];
     %ClearBreakPoint(break_point);
   }
   break_points = [];
@@ -1885,7 +1887,7 @@
   // Get the frame for which the scope or scopes are requested.
   // With no frameNumber argument use the currently selected frame.
   if (scope_description && !IS_UNDEFINED(scope_description.frameNumber)) {
-    frame_index = scope_description.frameNumber;
+    var frame_index = scope_description.frameNumber;
     if (frame_index < 0 || this.exec_state_.frameCount() <= frame_index) {
       throw new Error('Invalid frame number');
     }
@@ -1970,7 +1972,7 @@
     var value_mirror = LookupMirror(value_description.handle);
     if (!value_mirror) {
       throw new Error("Failed to resolve value by handle, ' #" +
-          mapping.handle + "# not found");
+          value_description.handle + "# not found");
     }
     return value_mirror.value();
   } else if ("stringDescription" in value_description) {
@@ -2125,7 +2127,7 @@
 
   // Set 'includeSource' option for script lookup.
   if (!IS_UNDEFINED(request.arguments.includeSource)) {
-    includeSource = %ToBoolean(request.arguments.includeSource);
+    var includeSource = %ToBoolean(request.arguments.includeSource);
     response.setOption('includeSource', includeSource);
   }
 
diff --git a/src/debug.cc b/src/debug.cc
index f0e7796..cdcb0a7 100644
--- a/src/debug.cc
+++ b/src/debug.cc
@@ -40,6 +40,7 @@
       live_edit_enabled_(true),  // TODO(yangguo): set to false by default.
       has_break_points_(false),
       break_disabled_(false),
+      in_debug_event_listener_(false),
       break_on_exception_(false),
       break_on_uncaught_exception_(false),
       script_cache_(NULL),
@@ -120,21 +121,37 @@
       DCHECK(statement_position_ >= 0);
     }
 
-    if (IsDebugBreakSlot()) {
-      // There is always a possible break point at a debug break slot.
+    // Check for break at return.
+    if (RelocInfo::IsJSReturn(rmode())) {
+      // Set the positions to the end of the function.
+      if (debug_info_->shared()->HasSourceCode()) {
+        position_ = debug_info_->shared()->end_position() -
+                    debug_info_->shared()->start_position() - 1;
+      } else {
+        position_ = 0;
+      }
+      statement_position_ = position_;
       break_point_++;
       return;
-    } else if (RelocInfo::IsCodeTarget(rmode())) {
+    }
+
+    if (RelocInfo::IsCodeTarget(rmode())) {
       // Check for breakable code target. Look in the original code as setting
       // break points can cause the code targets in the running (debugged) code
       // to be of a different kind than in the original code.
       Address target = original_rinfo()->target_address();
       Code* code = Code::GetCodeFromTargetAddress(target);
-      if ((code->is_inline_cache_stub() &&
-           !code->is_binary_op_stub() &&
-           !code->is_compare_ic_stub() &&
-           !code->is_to_boolean_ic_stub()) ||
-          RelocInfo::IsConstructCall(rmode())) {
+
+      if (RelocInfo::IsConstructCall(rmode()) || code->is_call_stub()) {
+        break_point_++;
+        return;
+      }
+
+      // Skip below if we only want locations for calls and returns.
+      if (type_ == CALLS_AND_RETURNS) continue;
+
+      if ((code->is_inline_cache_stub() && !code->is_binary_op_stub() &&
+           !code->is_compare_ic_stub() && !code->is_to_boolean_ic_stub())) {
         break_point_++;
         return;
       }
@@ -157,16 +174,8 @@
       }
     }
 
-    // Check for break at return.
-    if (RelocInfo::IsJSReturn(rmode())) {
-      // Set the positions to the end of the function.
-      if (debug_info_->shared()->HasSourceCode()) {
-        position_ = debug_info_->shared()->end_position() -
-                    debug_info_->shared()->start_position() - 1;
-      } else {
-        position_ = 0;
-      }
-      statement_position_ = position_;
+    if (IsDebugBreakSlot() && type_ != CALLS_AND_RETURNS) {
+      // There is always a possible break point at a debug break slot.
       break_point_++;
       return;
     }
@@ -563,7 +572,8 @@
   thread_local_.step_into_fp_ = 0;
   thread_local_.step_out_fp_ = 0;
   // TODO(isolates): frames_are_dropped_?
-  thread_local_.current_debug_scope_ = NULL;
+  base::NoBarrier_Store(&thread_local_.current_debug_scope_,
+                        static_cast<base::AtomicWord>(0));
   thread_local_.restarter_frame_function_pointer_ = NULL;
 }
 
@@ -593,10 +603,7 @@
   Heap* heap = isolate_->heap();
   HandleScope scope(isolate_);
 
-  // Perform two GCs to get rid of all unreferenced scripts. The first GC gets
-  // rid of all the cached script wrappers and the second gets rid of the
-  // scripts which are no longer referenced.
-  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
+  // Perform a GC to get rid of all unreferenced scripts.
   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "ScriptCache");
 
   // Scan heap for Script objects.
@@ -688,18 +695,11 @@
 }
 
 
-void Debug::HandleWeakDebugInfo(
-    const v8::WeakCallbackData<v8::Value, void>& data) {
+void Debug::HandlePhantomDebugInfo(
+    const v8::PhantomCallbackData<DebugInfoListNode>& data) {
   Debug* debug = reinterpret_cast<Isolate*>(data.GetIsolate())->debug();
-  DebugInfoListNode* node =
-      reinterpret_cast<DebugInfoListNode*>(data.GetParameter());
-  // We need to clear all breakpoints associated with the function to restore
-  // original code and avoid patching the code twice later because
-  // the function will live in the heap until next gc, and can be found by
-  // Debug::FindSharedFunctionInfoInScript.
-  BreakLocationIterator it(node->debug_info(), ALL_BREAK_LOCATIONS);
-  it.ClearAllDebugBreak();
-  debug->RemoveDebugInfo(node->debug_info());
+  DebugInfoListNode* node = data.GetParameter();
+  debug->RemoveDebugInfo(node);
 #ifdef DEBUG
   for (DebugInfoListNode* n = debug->debug_info_list_;
        n != NULL;
@@ -714,9 +714,10 @@
   // Globalize the request debug info object and make it weak.
   GlobalHandles* global_handles = debug_info->GetIsolate()->global_handles();
   debug_info_ = Handle<DebugInfo>::cast(global_handles->Create(debug_info));
-  GlobalHandles::MakeWeak(reinterpret_cast<Object**>(debug_info_.location()),
-                          this,
-                          Debug::HandleWeakDebugInfo);
+  typedef PhantomCallbackData<void>::Callback Callback;
+  GlobalHandles::MakePhantom(
+      reinterpret_cast<Object**>(debug_info_.location()), this,
+      reinterpret_cast<Callback>(Debug::HandlePhantomDebugInfo));
 }
 
 
@@ -872,7 +873,7 @@
   LiveEdit::InitializeThreadLocal(this);
 
   // Just continue if breaks are disabled or debugger cannot be loaded.
-  if (break_disabled_) return;
+  if (break_disabled()) return;
 
   // Enter the debugger.
   DebugScope debug_scope(this);
@@ -1095,7 +1096,7 @@
   it.FindBreakLocationFromPosition(*source_position, STATEMENT_ALIGNED);
   it.SetBreakPoint(break_point_object);
 
-  *source_position = it.position();
+  *source_position = it.statement_position();
 
   // At least one active break point now.
   return debug_info->GetBreakPointCount() > 0;
@@ -1139,7 +1140,10 @@
   it.FindBreakLocationFromPosition(position, alignment);
   it.SetBreakPoint(break_point_object);
 
-  *source_position = it.position() + shared->start_position();
+  position = (alignment == STATEMENT_ALIGNED) ? it.statement_position()
+                                              : it.position();
+
+  *source_position = position + shared->start_position();
 
   // At least one active break point now.
   DCHECK(debug_info->GetBreakPointCount() > 0);
@@ -1168,7 +1172,7 @@
       // If there are no more break points left remove the debug info for this
       // function.
       if (debug_info->GetBreakPointCount() == 0) {
-        RemoveDebugInfo(debug_info);
+        RemoveDebugInfoAndClearFromShared(debug_info);
       }
 
       return;
@@ -1189,12 +1193,16 @@
 
   // Remove all debug info.
   while (debug_info_list_ != NULL) {
-    RemoveDebugInfo(debug_info_list_->debug_info());
+    RemoveDebugInfoAndClearFromShared(debug_info_list_->debug_info());
   }
 }
 
 
-void Debug::FloodWithOneShot(Handle<JSFunction> function) {
+void Debug::FloodWithOneShot(Handle<JSFunction> function,
+                             BreakLocatorType type) {
+  // Do not ever break in native functions.
+  if (function->IsFromNativeScript()) return;
+
   PrepareForBreakPoints();
 
   // Make sure the function is compiled and has set up the debug info.
@@ -1205,7 +1213,7 @@
   }
 
   // Flood the function with break points.
-  BreakLocationIterator it(GetDebugInfo(shared), ALL_BREAK_LOCATIONS);
+  BreakLocationIterator it(GetDebugInfo(shared), type);
   while (!it.Done()) {
     it.SetOneShot();
     it.Next();
@@ -1221,7 +1229,48 @@
   if (!bindee.is_null() && bindee->IsJSFunction() &&
       !JSFunction::cast(*bindee)->IsFromNativeScript()) {
     Handle<JSFunction> bindee_function(JSFunction::cast(*bindee));
-    Debug::FloodWithOneShot(bindee_function);
+    FloodWithOneShotGeneric(bindee_function);
+  }
+}
+
+
+void Debug::FloodDefaultConstructorWithOneShot(Handle<JSFunction> function) {
+  DCHECK(function->shared()->is_default_constructor());
+  // Instead of stepping into the function we directly step into the super class
+  // constructor.
+  Isolate* isolate = function->GetIsolate();
+  PrototypeIterator iter(isolate, function);
+  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
+  if (!proto->IsJSFunction()) return;  // Object.prototype
+  Handle<JSFunction> function_proto = Handle<JSFunction>::cast(proto);
+  FloodWithOneShotGeneric(function_proto);
+}
+
+
+void Debug::FloodWithOneShotGeneric(Handle<JSFunction> function,
+                                    Handle<Object> holder) {
+  if (function->shared()->bound()) {
+    FloodBoundFunctionWithOneShot(function);
+  } else if (function->shared()->is_default_constructor()) {
+    FloodDefaultConstructorWithOneShot(function);
+  } else {
+    Isolate* isolate = function->GetIsolate();
+    // Don't allow step into functions in the native context.
+    if (function->shared()->code() ==
+            isolate->builtins()->builtin(Builtins::kFunctionApply) ||
+        function->shared()->code() ==
+            isolate->builtins()->builtin(Builtins::kFunctionCall)) {
+      // Handle function.apply and function.call separately to flood the
+      // function to be called and not the code for Builtins::FunctionApply or
+      // Builtins::FunctionCall. The receiver of call/apply is the target
+      // function.
+      if (!holder.is_null() && holder->IsJSFunction()) {
+        Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder);
+        FloodWithOneShotGeneric(js_function);
+      }
+    } else {
+      FloodWithOneShot(function);
+    }
   }
 }
 
@@ -1262,17 +1311,6 @@
 }
 
 
-bool Debug::PromiseHasRejectHandler(Handle<JSObject> promise) {
-  Handle<JSFunction> fun = Handle<JSFunction>::cast(
-      JSObject::GetDataProperty(isolate_->js_builtins_object(),
-                                isolate_->factory()->NewStringFromStaticChars(
-                                    "PromiseHasRejectHandler")));
-  Handle<Object> result =
-      Execution::Call(isolate_, fun, promise, 0, NULL).ToHandleChecked();
-  return result->IsTrue();
-}
-
-
 void Debug::PrepareStep(StepAction step_action,
                         int step_count,
                         StackFrame::Id frame_id) {
@@ -1312,7 +1350,7 @@
   FloodHandlerWithOneShot();
 
   // If the function on the top frame is unresolved perform step out. This will
-  // be the case when calling unknown functions and having the debugger stopped
+  // be the case when calling unknown function and having the debugger stopped
   // in an unhandled exception.
   if (!frame->function()->IsJSFunction()) {
     // Step out: Find the calling JavaScript frame and flood it with
@@ -1370,7 +1408,7 @@
       if ((maybe_call_function_stub->kind() == Code::STUB &&
            CodeStub::GetMajorKey(maybe_call_function_stub) ==
                CodeStub::CallFunction) ||
-          maybe_call_function_stub->kind() == Code::CALL_IC) {
+          maybe_call_function_stub->is_call_stub()) {
         // Save reference to the code as we may need it to find out arguments
         // count for 'step in' later.
         call_function_stub = Handle<Code>(maybe_call_function_stub);
@@ -1411,7 +1449,9 @@
     // Step next or step min.
 
     // Fill the current function with one-shot break points.
-    FloodWithOneShot(function);
+    // If we are stepping into another frame, only fill calls and returns.
+    FloodWithOneShot(function, step_action == StepFrame ? CALLS_AND_RETURNS
+                                                        : ALL_BREAK_LOCATIONS);
 
     // Remember source position and frame to handle step next.
     thread_local_.last_statement_position_ =
@@ -1469,13 +1509,7 @@
 
       if (fun->IsJSFunction()) {
         Handle<JSFunction> js_function(JSFunction::cast(fun));
-        if (js_function->shared()->bound()) {
-          Debug::FloodBoundFunctionWithOneShot(js_function);
-        } else if (!js_function->IsFromNativeScript()) {
-          // Don't step into builtins.
-          // It will also compile target function if it's not compiled yet.
-          FloodWithOneShot(js_function);
-        }
+        FloodWithOneShotGeneric(js_function);
       }
     }
 
@@ -1483,7 +1517,9 @@
     // a call target as the function called might be a native function for
     // which step in will not stop. It also prepares for stepping in
     // getters/setters.
-    FloodWithOneShot(function);
+    // If we are stepping into another frame, only fill calls and returns.
+    FloodWithOneShot(function, step_action == StepFrame ? CALLS_AND_RETURNS
+                                                        : ALL_BREAK_LOCATIONS);
 
     if (is_load_or_store) {
       // Remember source position and frame to handle step in getter/setter. If
@@ -1512,15 +1548,20 @@
                              JavaScriptFrame* frame) {
   // StepNext and StepOut shouldn't bring us deeper in code, so last frame
   // shouldn't be a parent of current frame.
-  if (thread_local_.last_step_action_ == StepNext ||
-      thread_local_.last_step_action_ == StepOut) {
+  StepAction step_action = thread_local_.last_step_action_;
+
+  if (step_action == StepNext || step_action == StepOut) {
     if (frame->fp() < thread_local_.last_fp_) return true;
   }
 
+  // We stepped into a new frame if the frame pointer changed.
+  if (step_action == StepFrame) {
+    return frame->UnpaddedFP() == thread_local_.last_fp_;
+  }
+
   // If the step last action was step next or step in make sure that a new
   // statement is hit.
-  if (thread_local_.last_step_action_ == StepNext ||
-      thread_local_.last_step_action_ == StepIn) {
+  if (step_action == StepNext || step_action == StepIn) {
     // Never continue if returning from function.
     if (break_location_iterator->IsExit()) return false;
 
@@ -1568,17 +1609,14 @@
       BreakPointInfo* break_point_info =
           BreakPointInfo::cast(debug_info->break_points()->get(i));
       if (break_point_info->GetBreakPointCount() > 0) {
-        Smi* position;
+        Smi* position = NULL;
         switch (position_alignment) {
-        case STATEMENT_ALIGNED:
-          position = break_point_info->statement_position();
-          break;
-        case BREAK_POSITION_ALIGNED:
-          position = break_point_info->source_position();
-          break;
-        default:
-          UNREACHABLE();
-          position = break_point_info->statement_position();
+          case STATEMENT_ALIGNED:
+            position = break_point_info->statement_position();
+            break;
+          case BREAK_POSITION_ALIGNED:
+            position = break_point_info->source_position();
+            break;
         }
 
         locations->set(count++, position);
@@ -1590,10 +1628,13 @@
 
 
 // Handle stepping into a function.
-void Debug::HandleStepIn(Handle<JSFunction> function,
-                         Handle<Object> holder,
-                         Address fp,
-                         bool is_constructor) {
+void Debug::HandleStepIn(Handle<Object> function_obj, Handle<Object> holder,
+                         Address fp, bool is_constructor) {
+  // Flood getter/setter if we either step in or step to another frame.
+  bool step_frame = thread_local_.last_step_action_ == StepFrame;
+  if (!StepInActive() && !step_frame) return;
+  if (!function_obj->IsJSFunction()) return;
+  Handle<JSFunction> function = Handle<JSFunction>::cast(function_obj);
   Isolate* isolate = function->GetIsolate();
   // If the frame pointer is not supplied by the caller find it.
   if (fp == 0) {
@@ -1608,34 +1649,9 @@
   }
 
   // Flood the function with one-shot break points if it is called from where
-  // step into was requested.
-  if (fp == thread_local_.step_into_fp_) {
-    if (function->shared()->bound()) {
-      // Handle Function.prototype.bind
-      Debug::FloodBoundFunctionWithOneShot(function);
-    } else if (!function->IsFromNativeScript()) {
-      // Don't allow step into functions in the native context.
-      if (function->shared()->code() ==
-          isolate->builtins()->builtin(Builtins::kFunctionApply) ||
-          function->shared()->code() ==
-          isolate->builtins()->builtin(Builtins::kFunctionCall)) {
-        // Handle function.apply and function.call separately to flood the
-        // function to be called and not the code for Builtins::FunctionApply or
-        // Builtins::FunctionCall. The receiver of call/apply is the target
-        // function.
-        if (!holder.is_null() && holder->IsJSFunction()) {
-          Handle<JSFunction> js_function = Handle<JSFunction>::cast(holder);
-          if (!js_function->IsFromNativeScript()) {
-            Debug::FloodWithOneShot(js_function);
-          } else if (js_function->shared()->bound()) {
-            // Handle Function.prototype.bind
-            Debug::FloodBoundFunctionWithOneShot(js_function);
-          }
-        }
-      } else {
-        Debug::FloodWithOneShot(function);
-      }
-    }
+  // step into was requested, or when stepping into a new frame.
+  if (fp == thread_local_.step_into_fp_ || step_frame) {
+    FloodWithOneShotGeneric(function, holder);
   }
 }
 
@@ -1904,6 +1920,23 @@
 }
 
 
+static bool SkipSharedFunctionInfo(SharedFunctionInfo* shared,
+                                   Object* active_code_marker) {
+  if (!shared->allows_lazy_compilation()) return true;
+  if (!shared->script()->IsScript()) return true;
+  Object* script = shared->script();
+  if (!script->IsScript()) return true;
+  if (Script::cast(script)->type()->value() == Script::TYPE_NATIVE) return true;
+  Code* shared_code = shared->code();
+  return shared_code->gc_metadata() == active_code_marker;
+}
+
+
+static inline bool HasDebugBreakSlots(Code* code) {
+  return code->kind() == Code::FUNCTION && code->has_debug_break_slots();
+}
+
+
 void Debug::PrepareForBreakPoints() {
   // If preparing for the first break point make sure to deoptimize all
   // functions as debugging does not work with optimized code.
@@ -1969,35 +2002,28 @@
         if (obj->IsJSFunction()) {
           JSFunction* function = JSFunction::cast(obj);
           SharedFunctionInfo* shared = function->shared();
-
-          if (!shared->allows_lazy_compilation()) continue;
-          if (!shared->script()->IsScript()) continue;
-          if (function->IsFromNativeScript()) continue;
-          if (shared->code()->gc_metadata() == active_code_marker) continue;
-
+          if (SkipSharedFunctionInfo(shared, active_code_marker)) continue;
           if (shared->is_generator()) {
             generator_functions.Add(Handle<JSFunction>(function, isolate_));
             continue;
           }
-
+          if (HasDebugBreakSlots(function->code())) continue;
+          Code* fallback = HasDebugBreakSlots(shared->code()) ? shared->code()
+                                                              : *lazy_compile;
           Code::Kind kind = function->code()->kind();
-          if (kind == Code::FUNCTION &&
-              !function->code()->has_debug_break_slots()) {
-            function->ReplaceCode(*lazy_compile);
-            function->shared()->ReplaceCode(*lazy_compile);
-          } else if (kind == Code::BUILTIN &&
-              (function->IsInOptimizationQueue() ||
-               function->IsMarkedForOptimization() ||
-               function->IsMarkedForConcurrentOptimization())) {
-            // Abort in-flight compilation.
-            Code* shared_code = function->shared()->code();
-            if (shared_code->kind() == Code::FUNCTION &&
-                shared_code->has_debug_break_slots()) {
-              function->ReplaceCode(shared_code);
-            } else {
-              function->ReplaceCode(*lazy_compile);
-              function->shared()->ReplaceCode(*lazy_compile);
-            }
+          if (kind == Code::FUNCTION ||
+              (kind == Code::BUILTIN &&  // Abort in-flight compilation.
+               (function->IsInOptimizationQueue() ||
+                function->IsMarkedForOptimization() ||
+                function->IsMarkedForConcurrentOptimization()))) {
+            function->ReplaceCode(fallback);
+          }
+          if (kind == Code::OPTIMIZED_FUNCTION) {
+            // Optimized code can only get here if DeoptimizeAll did not
+            // deoptimize turbo fan code.
+            DCHECK(!FLAG_turbo_deoptimization);
+            DCHECK(function->code()->is_turbofanned());
+            function->ReplaceCode(fallback);
           }
         } else if (obj->IsJSGeneratorObject()) {
           JSGeneratorObject* gen = JSGeneratorObject::cast(obj);
@@ -2017,6 +2043,12 @@
           gen->set_continuation(code_offset);
 
           suspended_generators.Add(Handle<JSGeneratorObject>(gen, isolate_));
+        } else if (obj->IsSharedFunctionInfo()) {
+          SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
+          if (SkipSharedFunctionInfo(shared, active_code_marker)) continue;
+          if (shared->is_generator()) continue;
+          if (HasDebugBreakSlots(shared->code())) continue;
+          shared->ReplaceCode(*lazy_compile);
         }
       }
 
@@ -2089,7 +2121,10 @@
   Heap* heap = isolate_->heap();
   while (!done) {
     { // Extra scope for iterator.
-      HeapIterator iterator(heap);
+      // If lazy compilation is off, we won't have duplicate shared function
+      // infos that need to be filtered.
+      HeapIterator iterator(heap, FLAG_lazy ? HeapIterator::kNoFiltering
+                                            : HeapIterator::kFilterUnreachable);
       for (HeapObject* obj = iterator.next();
            obj != NULL; obj = iterator.next()) {
         bool found_next_candidate = false;
@@ -2205,27 +2240,29 @@
 }
 
 
-void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) {
+void Debug::RemoveDebugInfo(DebugInfoListNode* prev, DebugInfoListNode* node) {
+  // Unlink from list. If prev is NULL we are looking at the first element.
+  if (prev == NULL) {
+    debug_info_list_ = node->next();
+  } else {
+    prev->set_next(node->next());
+  }
+  delete node;
+
+  // If there are no more debug info objects there are not more break
+  // points.
+  has_break_points_ = debug_info_list_ != NULL;
+}
+
+
+void Debug::RemoveDebugInfo(DebugInfo** debug_info) {
   DCHECK(debug_info_list_ != NULL);
   // Run through the debug info objects to find this one and remove it.
   DebugInfoListNode* prev = NULL;
   DebugInfoListNode* current = debug_info_list_;
   while (current != NULL) {
-    if (*current->debug_info() == *debug_info) {
-      // Unlink from list. If prev is NULL we are looking at the first element.
-      if (prev == NULL) {
-        debug_info_list_ = current->next();
-      } else {
-        prev->set_next(current->next());
-      }
-      current->debug_info()->shared()->set_debug_info(
-              isolate_->heap()->undefined_value());
-      delete current;
-
-      // If there are no more debug info objects there are not more break
-      // points.
-      has_break_points_ = debug_info_list_ != NULL;
-
+    if (current->debug_info().location() == debug_info) {
+      RemoveDebugInfo(prev, current);
       return;
     }
     // Move to next in list.
@@ -2236,6 +2273,34 @@
 }
 
 
+void Debug::RemoveDebugInfo(DebugInfoListNode* node) {
+  DCHECK(debug_info_list_ != NULL);
+  // Run through the debug info objects to find this one and remove it.
+  DebugInfoListNode* prev = NULL;
+  DebugInfoListNode* current = debug_info_list_;
+  while (current != NULL) {
+    if (current == node) {
+      RemoveDebugInfo(prev, node);
+      return;
+    }
+    // Move to next in list.
+    prev = current;
+    current = current->next();
+  }
+  UNREACHABLE();
+}
+
+
+void Debug::RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info) {
+  HandleScope scope(isolate_);
+  Handle<SharedFunctionInfo> shared(debug_info->shared());
+
+  RemoveDebugInfo(debug_info.location());
+
+  shared->set_debug_info(isolate_->heap()->undefined_value());
+}
+
+
 void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
   after_break_target_ = NULL;
 
@@ -2330,7 +2395,7 @@
   HandleScope scope(isolate_);
 
   // If there are no break points this cannot be break at return, as
-  // the debugger statement and stack guard bebug break cannot be at
+  // the debugger statement and stack guard debug break cannot be at
   // return.
   if (!has_break_points_) {
     return false;
@@ -2521,14 +2586,37 @@
 void Debug::OnPromiseReject(Handle<JSObject> promise, Handle<Object> value) {
   if (in_debug_scope() || ignore_events()) return;
   HandleScope scope(isolate_);
-  OnException(value, false, promise);
+  // Check whether the promise has been marked as having triggered a message.
+  Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
+  if (JSObject::GetDataProperty(promise, key)->IsUndefined()) {
+    OnException(value, false, promise);
+  }
+}
+
+
+MaybeHandle<Object> Debug::PromiseHasUserDefinedRejectHandler(
+    Handle<JSObject> promise) {
+  Handle<JSFunction> fun = Handle<JSFunction>::cast(
+      JSObject::GetDataProperty(isolate_->js_builtins_object(),
+                                isolate_->factory()->NewStringFromStaticChars(
+                                    "PromiseHasUserDefinedRejectHandler")));
+  return Execution::Call(isolate_, fun, promise, 0, NULL);
 }
 
 
 void Debug::OnException(Handle<Object> exception, bool uncaught,
                         Handle<Object> promise) {
-  if (promise->IsJSObject()) {
-    uncaught |= !PromiseHasRejectHandler(Handle<JSObject>::cast(promise));
+  if (!uncaught && promise->IsJSObject()) {
+    Handle<JSObject> jspromise = Handle<JSObject>::cast(promise);
+    // Mark the promise as already having triggered a message.
+    Handle<Symbol> key = isolate_->factory()->promise_debug_marker_symbol();
+    JSObject::SetProperty(jspromise, key, key, STRICT).Assert();
+    // Check whether the promise reject is considered an uncaught exception.
+    Handle<Object> has_reject_handler;
+    ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+        isolate_, has_reject_handler,
+        PromiseHasUserDefinedRejectHandler(jspromise), /* void */);
+    uncaught = has_reject_handler->IsFalse();
   }
   // Bail out if exception breaks are not active
   if (uncaught) {
@@ -2560,8 +2648,12 @@
 
 
 void Debug::OnCompileError(Handle<Script> script) {
-  // No more to do if not debugging.
-  if (in_debug_scope() || ignore_events()) return;
+  if (ignore_events()) return;
+
+  if (in_debug_scope()) {
+    ProcessCompileEventInDebugScope(v8::CompileError, script);
+    return;
+  }
 
   HandleScope scope(isolate_);
   DebugScope debug_scope(this);
@@ -2622,8 +2714,12 @@
   // Add the newly compiled script to the script cache.
   if (script_cache_ != NULL) script_cache_->Add(script);
 
-  // No more to do if not debugging.
-  if (in_debug_scope() || ignore_events()) return;
+  if (ignore_events()) return;
+
+  if (in_debug_scope()) {
+    ProcessCompileEventInDebugScope(v8::AfterCompile, script);
+    return;
+  }
 
   HandleScope scope(isolate_);
   DebugScope debug_scope(this);
@@ -2749,6 +2845,8 @@
                               Handle<Object> exec_state,
                               Handle<Object> event_data,
                               v8::Debug::ClientData* client_data) {
+  bool previous = in_debug_event_listener_;
+  in_debug_event_listener_ = true;
   if (event_listener_->IsForeign()) {
     // Invoke the C debug event listener.
     v8::Debug::EventCallback callback =
@@ -2772,6 +2870,28 @@
     Execution::TryCall(Handle<JSFunction>::cast(event_listener_),
                        global, arraysize(argv), argv);
   }
+  in_debug_event_listener_ = previous;
+}
+
+
+void Debug::ProcessCompileEventInDebugScope(v8::DebugEvent event,
+                                            Handle<Script> script) {
+  if (event_listener_.is_null()) return;
+
+  SuppressDebug while_processing(this);
+  DebugScope debug_scope(this);
+  if (debug_scope.failed()) return;
+
+  Handle<Object> event_data;
+  // Bail out and don't call debugger if exception.
+  if (!MakeCompileEvent(script, event).ToHandle(&event_data)) return;
+
+  // Create the execution state.
+  Handle<Object> exec_state;
+  // Bail out and don't call debugger if exception.
+  if (!MakeExecutionState().ToHandle(&exec_state)) return;
+
+  CallEventCallback(event, exec_state, event_data, NULL);
 }
 
 
@@ -3025,7 +3145,7 @@
   // Ignore debug break during bootstrapping.
   if (isolate_->bootstrapper()->IsActive()) return;
   // Just continue if breaks are disabled.
-  if (break_disabled_) return;
+  if (break_disabled()) return;
   // Ignore debug break if debugger is not active.
   if (!is_active()) return;
 
@@ -3077,7 +3197,8 @@
       no_termination_exceptons_(debug_->isolate_,
                                 StackGuard::TERMINATE_EXECUTION) {
   // Link recursive debugger entry.
-  debug_->thread_local_.current_debug_scope_ = this;
+  base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
+                        reinterpret_cast<base::AtomicWord>(this));
 
   // Store the previous break id and frame id.
   break_id_ = debug_->break_id();
@@ -3114,7 +3235,8 @@
   }
 
   // Leaving this debugger entry.
-  debug_->thread_local_.current_debug_scope_ = prev_;
+  base::NoBarrier_Store(&debug_->thread_local_.current_debug_scope_,
+                        reinterpret_cast<base::AtomicWord>(prev_));
 
   // Restore to the previous break state.
   debug_->thread_local_.break_frame_id_ = break_frame_id_;
@@ -3225,7 +3347,7 @@
 v8::Handle<v8::Context> MessageImpl::GetEventContext() const {
   Isolate* isolate = event_data_->GetIsolate();
   v8::Handle<v8::Context> context = GetDebugEventContext(isolate);
-  // Isolate::context() may be NULL when "script collected" event occures.
+  // Isolate::context() may be NULL when "script collected" event occurs.
   DCHECK(!context.IsEmpty());
   return context;
 }
diff --git a/src/debug.h b/src/debug.h
index a5119d0..0ec9024 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -8,6 +8,7 @@
 #include "src/allocation.h"
 #include "src/arguments.h"
 #include "src/assembler.h"
+#include "src/base/atomicops.h"
 #include "src/base/platform/platform.h"
 #include "src/execution.h"
 #include "src/factory.h"
@@ -31,13 +32,14 @@
 // Step actions. NOTE: These values are in macros.py as well.
 enum StepAction {
   StepNone = -1,  // Stepping not prepared.
-  StepOut = 0,   // Step out of the current function.
-  StepNext = 1,  // Step to the next statement in the current function.
-  StepIn = 2,    // Step into new functions invoked or the next statement
-                 // in the current function.
-  StepMin = 3,   // Perform a minimum step in the current function.
-  StepInMin = 4  // Step into new functions invoked or perform a minimum step
-                 // in the current function.
+  StepOut = 0,    // Step out of the current function.
+  StepNext = 1,   // Step to the next statement in the current function.
+  StepIn = 2,     // Step into new functions invoked or the next statement
+                  // in the current function.
+  StepMin = 3,    // Perform a minimum step in the current function.
+  StepInMin = 4,  // Step into new functions invoked or perform a minimum step
+                  // in the current function.
+  StepFrame = 5   // Step into a new frame or return to previous frame.
 };
 
 
@@ -48,10 +50,11 @@
 };
 
 
-// Type of exception break. NOTE: These values are in macros.py as well.
+// Type of exception break.
 enum BreakLocatorType {
   ALL_BREAK_LOCATIONS = 0,
-  SOURCE_BREAK_LOCATIONS = 1
+  SOURCE_BREAK_LOCATIONS = 1,
+  CALLS_AND_RETURNS = 2
 };
 
 
@@ -384,8 +387,12 @@
                               BreakPositionAlignment alignment);
   void ClearBreakPoint(Handle<Object> break_point_object);
   void ClearAllBreakPoints();
-  void FloodWithOneShot(Handle<JSFunction> function);
+  void FloodWithOneShot(Handle<JSFunction> function,
+                        BreakLocatorType type = ALL_BREAK_LOCATIONS);
   void FloodBoundFunctionWithOneShot(Handle<JSFunction> function);
+  void FloodDefaultConstructorWithOneShot(Handle<JSFunction> function);
+  void FloodWithOneShotGeneric(Handle<JSFunction> function,
+                               Handle<Object> holder = Handle<Object>());
   void FloodHandlerWithOneShot();
   void ChangeBreakOnException(ExceptionBreakType type, bool enable);
   bool IsBreakOnException(ExceptionBreakType type);
@@ -400,10 +407,8 @@
   bool StepNextContinue(BreakLocationIterator* break_location_iterator,
                         JavaScriptFrame* frame);
   bool StepInActive() { return thread_local_.step_into_fp_ != 0; }
-  void HandleStepIn(Handle<JSFunction> function,
-                    Handle<Object> holder,
-                    Address fp,
-                    bool is_constructor);
+  void HandleStepIn(Handle<Object> function_obj, Handle<Object> holder,
+                    Address fp, bool is_constructor);
   bool StepOutActive() { return thread_local_.step_out_fp_ != 0; }
 
   // Purge all code objects that have no debug break slots.
@@ -442,8 +447,8 @@
                              Object** restarter_frame_function_pointer);
 
   // Passed to MakeWeak.
-  static void HandleWeakDebugInfo(
-      const v8::WeakCallbackData<v8::Value, void>& data);
+  static void HandlePhantomDebugInfo(
+      const PhantomCallbackData<DebugInfoListNode>& data);
 
   // Threading support.
   char* ArchiveDebug(char* to);
@@ -454,8 +459,15 @@
   // Record function from which eval was called.
   static void RecordEvalCaller(Handle<Script> script);
 
+  bool CheckExecutionState(int id) {
+    return !debug_context().is_null() && break_id() != 0 && break_id() == id;
+  }
+
   // Flags and states.
-  DebugScope* debugger_entry() { return thread_local_.current_debug_scope_; }
+  DebugScope* debugger_entry() {
+    return reinterpret_cast<DebugScope*>(
+        base::NoBarrier_Load(&thread_local_.current_debug_scope_));
+  }
   inline Handle<Context> debug_context() { return debug_context_; }
   void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
   bool live_edit_enabled() const {
@@ -466,7 +478,7 @@
   inline bool is_loaded() const { return !debug_context_.is_null(); }
   inline bool has_break_points() const { return has_break_points_; }
   inline bool in_debug_scope() const {
-    return thread_local_.current_debug_scope_ != NULL;
+    return !!base::NoBarrier_Load(&thread_local_.current_debug_scope_);
   }
   void set_disable_break(bool v) { break_disabled_ = v; }
 
@@ -491,6 +503,8 @@
     return reinterpret_cast<Address>(&thread_local_.step_into_fp_);
   }
 
+  StepAction last_step_action() { return thread_local_.last_step_action_; }
+
  private:
   explicit Debug(Isolate* isolate);
 
@@ -503,6 +517,9 @@
   // Check whether there are commands in the command queue.
   inline bool has_commands() const { return !command_queue_.IsEmpty(); }
   inline bool ignore_events() const { return is_suppressed_ || !is_active_; }
+  inline bool break_disabled() const {
+    return break_disabled_ || in_debug_event_listener_;
+  }
 
   void OnException(Handle<Object> exception, bool uncaught,
                    Handle<Object> promise);
@@ -529,13 +546,15 @@
   // Mirror cache handling.
   void ClearMirrorCache();
 
-  // Returns a promise if the pushed try-catch handler matches the current one.
-  bool PromiseHasRejectHandler(Handle<JSObject> promise);
+  MaybeHandle<Object> PromiseHasUserDefinedRejectHandler(
+      Handle<JSObject> promise);
 
   void CallEventCallback(v8::DebugEvent event,
                          Handle<Object> exec_state,
                          Handle<Object> event_data,
                          v8::Debug::ClientData* client_data);
+  void ProcessCompileEventInDebugScope(v8::DebugEvent event,
+                                       Handle<Script> script);
   void ProcessDebugEvent(v8::DebugEvent event,
                          Handle<JSObject> event_data,
                          bool auto_continue);
@@ -551,8 +570,10 @@
   void ClearStepIn();
   void ActivateStepOut(StackFrame* frame);
   void ClearStepNext();
-  // Returns whether the compile succeeded.
-  void RemoveDebugInfo(Handle<DebugInfo> debug_info);
+  void RemoveDebugInfoAndClearFromShared(Handle<DebugInfo> debug_info);
+  void RemoveDebugInfo(DebugInfo** debug_info);
+  void RemoveDebugInfo(DebugInfoListNode* node);
+  void RemoveDebugInfo(DebugInfoListNode* prev, DebugInfoListNode* node);
   Handle<Object> CheckBreakPoints(Handle<Object> break_point);
   bool CheckBreakPoint(Handle<Object> break_point_object);
 
@@ -580,6 +601,7 @@
   bool live_edit_enabled_;
   bool has_break_points_;
   bool break_disabled_;
+  bool in_debug_event_listener_;
   bool break_on_exception_;
   bool break_on_uncaught_exception_;
 
@@ -595,7 +617,7 @@
   class ThreadLocal {
    public:
     // Top debugger entry.
-    DebugScope* current_debug_scope_;
+    base::AtomicWord current_debug_scope_;
 
     // Counter for generating next break id.
     int break_count_;
@@ -615,7 +637,7 @@
     // Number of steps left to perform before debug event.
     int step_count_;
 
-    // Frame pointer from last step next action.
+    // Frame pointer from last step next or step frame action.
     Address last_fp_;
 
     // Number of queued steps left to perform before debug event.
@@ -690,14 +712,21 @@
 class DisableBreak BASE_EMBEDDED {
  public:
   explicit DisableBreak(Debug* debug, bool disable_break)
-    : debug_(debug), old_state_(debug->break_disabled_) {
+      : debug_(debug),
+        previous_break_disabled_(debug->break_disabled_),
+        previous_in_debug_event_listener_(debug->in_debug_event_listener_) {
     debug_->break_disabled_ = disable_break;
+    debug_->in_debug_event_listener_ = disable_break;
   }
-  ~DisableBreak() { debug_->break_disabled_ = old_state_; }
+  ~DisableBreak() {
+    debug_->break_disabled_ = previous_break_disabled_;
+    debug_->in_debug_event_listener_ = previous_in_debug_event_listener_;
+  }
 
  private:
   Debug* debug_;
-  bool old_state_;
+  bool previous_break_disabled_;
+  bool previous_in_debug_event_listener_;
   DISALLOW_COPY_AND_ASSIGN(DisableBreak);
 };
 
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index dd274ed..748f95e 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -637,7 +637,7 @@
 
 void Deoptimizer::PrintFunctionName() {
   if (function_->IsJSFunction()) {
-    function_->PrintName(trace_scope_->file());
+    function_->ShortPrint(trace_scope_->file());
   } else {
     PrintF(trace_scope_->file(),
            "%s", Code::Kind2String(compiled_code_->kind()));
@@ -693,8 +693,7 @@
   DeoptimizerData* data = isolate->deoptimizer_data();
   MemoryChunk* base = data->deopt_entry_code_[type];
   Address start = base->area_start();
-  if (base == NULL ||
-      addr < start ||
+  if (addr < start ||
       addr >= start + (kMaxNumberOfEntries * table_entry_size_)) {
     return kNotDeoptimizationEntry;
   }
@@ -719,7 +718,7 @@
   OFStream os(stderr);
   os << "[couldn't find pc offset for node=" << id.ToInt() << "]\n"
      << "[method: " << shared->DebugName()->ToCString().get() << "]\n"
-     << "[source:\n" << SourceCodeOf(shared) << "\n]" << endl;
+     << "[source:\n" << SourceCodeOf(shared) << "\n]" << std::endl;
 
   FATAL("unable to find pc offset during deoptimization");
   return -1;
@@ -762,10 +761,8 @@
 
   if (trace_scope_ != NULL) {
     timer.Start();
-    PrintF(trace_scope_->file(),
-           "[deoptimizing (DEOPT %s): begin 0x%08" V8PRIxPTR " ",
-           MessageFor(bailout_type_),
-           reinterpret_cast<intptr_t>(function_));
+    PrintF(trace_scope_->file(), "[deoptimizing (DEOPT %s): begin ",
+           MessageFor(bailout_type_));
     PrintFunctionName();
     PrintF(trace_scope_->file(),
            " (opt #%d) @%d, FP to SP delta: %d]\n",
@@ -851,11 +848,8 @@
   if (trace_scope_ != NULL) {
     double ms = timer.Elapsed().InMillisecondsF();
     int index = output_count_ - 1;  // Index of the topmost frame.
-    JSFunction* function = output_[index]->GetFunction();
-    PrintF(trace_scope_->file(),
-           "[deoptimizing (%s): end 0x%08" V8PRIxPTR " ",
-           MessageFor(bailout_type_),
-           reinterpret_cast<intptr_t>(function));
+    PrintF(trace_scope_->file(), "[deoptimizing (%s): end ",
+           MessageFor(bailout_type_));
     PrintFunctionName();
     PrintF(trace_scope_->file(),
            " @%d => node=%d, pc=0x%08" V8PRIxPTR ", state=%s, alignment=%s,"
diff --git a/src/disassembler.cc b/src/disassembler.cc
index d9448ce..bedff45 100644
--- a/src/disassembler.cc
+++ b/src/disassembler.cc
@@ -19,21 +19,6 @@
 
 #ifdef ENABLE_DISASSEMBLER
 
-void Disassembler::Dump(FILE* f, byte* begin, byte* end) {
-  for (byte* pc = begin; pc < end; pc++) {
-    if (f == NULL) {
-      PrintF("%" V8PRIxPTR "  %4" V8PRIdPTR "  %02x\n",
-             reinterpret_cast<intptr_t>(pc),
-             pc - begin,
-             *pc);
-    } else {
-      PrintF(f, "%" V8PRIxPTR "  %4" V8PRIdPTR "  %02x\n",
-             reinterpret_cast<uintptr_t>(pc), pc - begin, *pc);
-    }
-  }
-}
-
-
 class V8NameConverter: public disasm::NameConverter {
  public:
   explicit V8NameConverter(Code* code) : code_(code) {}
@@ -74,12 +59,8 @@
 }
 
 
-static void DumpBuffer(FILE* f, StringBuilder* out) {
-  if (f == NULL) {
-    PrintF("%s\n", out->Finalize());
-  } else {
-    PrintF(f, "%s\n", out->Finalize());
-  }
+static void DumpBuffer(std::ostream* os, StringBuilder* out) {
+  (*os) << out->Finalize() << std::endl;
   out->Reset();
 }
 
@@ -87,11 +68,8 @@
 static const int kOutBufferSize = 2048 + String::kMaxShortPrintLength;
 static const int kRelocInfoPosition = 57;
 
-static int DecodeIt(Isolate* isolate,
-                    FILE* f,
-                    const V8NameConverter& converter,
-                    byte* begin,
-                    byte* end) {
+static int DecodeIt(Isolate* isolate, std::ostream* os,
+                    const V8NameConverter& converter, byte* begin, byte* end) {
   SealHandleScope shs(isolate);
   DisallowHeapAllocation no_alloc;
   ExternalReferenceEncoder ref_encoder(isolate);
@@ -164,7 +142,7 @@
     // Comments.
     for (int i = 0; i < comments.length(); i++) {
       out.AddFormatted("                  %s", comments[i]);
-      DumpBuffer(f, &out);
+      DumpBuffer(os, &out);
     }
 
     // Instruction address and instruction offset.
@@ -184,7 +162,7 @@
         out.AddPadding(' ', kRelocInfoPosition - out.position());
       } else {
         // Additional reloc infos are printed on separate lines.
-        DumpBuffer(f, &out);
+        DumpBuffer(os, &out);
         out.AddPadding(' ', kRelocInfoPosition);
       }
 
@@ -278,7 +256,7 @@
         out.AddFormatted("    ;; %s", RelocInfo::RelocModeName(rmode));
       }
     }
-    DumpBuffer(f, &out);
+    DumpBuffer(os, &out);
   }
 
   // Emit comments following the last instruction (if any).
@@ -287,7 +265,7 @@
       if (RelocInfo::IsComment(it->rinfo()->rmode())) {
         out.AddFormatted("                  %s",
                          reinterpret_cast<const char*>(it->rinfo()->data()));
-        DumpBuffer(f, &out);
+        DumpBuffer(os, &out);
       }
     }
   }
@@ -297,40 +275,19 @@
 }
 
 
-int Disassembler::Decode(Isolate* isolate, FILE* f, byte* begin, byte* end) {
-  V8NameConverter defaultConverter(NULL);
-  return DecodeIt(isolate, f, defaultConverter, begin, end);
-}
-
-
-// Called by Code::CodePrint.
-void Disassembler::Decode(FILE* f, Code* code) {
-  Isolate* isolate = code->GetIsolate();
-  int decode_size = code->is_crankshafted()
-      ? static_cast<int>(code->safepoint_table_offset())
-      : code->instruction_size();
-  // If there might be a back edge table, stop before reaching it.
-  if (code->kind() == Code::FUNCTION) {
-    decode_size =
-        Min(decode_size, static_cast<int>(code->back_edge_table_offset()));
-  }
-
-  byte* begin = code->instruction_start();
-  byte* end = begin + decode_size;
+int Disassembler::Decode(Isolate* isolate, std::ostream* os, byte* begin,
+                         byte* end, Code* code) {
   V8NameConverter v8NameConverter(code);
-  DecodeIt(isolate, f, v8NameConverter, begin, end);
+  return DecodeIt(isolate, os, v8NameConverter, begin, end);
 }
 
 #else  // ENABLE_DISASSEMBLER
 
-void Disassembler::Dump(FILE* f, byte* begin, byte* end) {}
-int Disassembler::Decode(Isolate* isolate, FILE* f, byte* begin, byte* end) {
+int Disassembler::Decode(Isolate* isolate, std::ostream* os, byte* begin,
+                         byte* end, Code* code) {
   return 0;
 }
 
-
-void Disassembler::Decode(FILE* f, Code* code) {}
-
 #endif  // ENABLE_DISASSEMBLER
 
 } }  // namespace v8::internal
diff --git a/src/disassembler.h b/src/disassembler.h
index f65f538..32e48c4 100644
--- a/src/disassembler.h
+++ b/src/disassembler.h
@@ -12,22 +12,12 @@
 
 class Disassembler : public AllStatic {
  public:
-  // Print the bytes in the interval [begin, end) into f.
-  static void Dump(FILE* f, byte* begin, byte* end);
-
   // Decode instructions in the the interval [begin, end) and print the
-  // code into f. Returns the number of bytes disassembled or 1 if no
+  // code into os. Returns the number of bytes disassembled or 1 if no
   // instruction could be decoded.
-  static int Decode(Isolate* isolate, FILE* f, byte* begin, byte* end);
-
-  // Decode instructions in code.
-  static void Decode(FILE* f, Code* code);
- private:
-  // Decode instruction at pc and print disassembled instruction into f.
-  // Returns the instruction length in bytes, or 1 if the instruction could
-  // not be decoded.  The number of characters written is written into
-  // the out parameter char_count.
-  static int Decode(FILE* f, byte* pc, int* char_count);
+  // the code object is used for name resolution and may be null.
+  static int Decode(Isolate* isolate, std::ostream* os, byte* begin, byte* end,
+                    Code* code = NULL);
 };
 
 } }  // namespace v8::internal
diff --git a/src/diy-fp.cc b/src/diy-fp.cc
index cdad2a8..b705df0 100644
--- a/src/diy-fp.cc
+++ b/src/diy-fp.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "include/v8stdint.h"
+#include <stdint.h>
 #include "src/base/logging.h"
 #include "src/diy-fp.h"
 #include "src/globals.h"
diff --git a/src/dtoa.cc b/src/dtoa.cc
index f39b0b0..fc02aca 100644
--- a/src/dtoa.cc
+++ b/src/dtoa.cc
@@ -4,7 +4,6 @@
 
 #include <cmath>
 
-#include "include/v8stdint.h"
 #include "src/base/logging.h"
 #include "src/utils.h"
 
diff --git a/src/elements.cc b/src/elements.cc
index e2127c4..4e9a052 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -247,15 +247,18 @@
 }
 
 
-static void CopyDoubleToObjectElements(Handle<FixedArrayBase> from_base,
+// NOTE: this method violates the handlified function signature convention:
+// raw pointer parameters in the function that allocates.
+// See ElementsAccessorBase::CopyElements() for details.
+static void CopyDoubleToObjectElements(FixedArrayBase* from_base,
                                        uint32_t from_start,
-                                       Handle<FixedArrayBase> to_base,
-                                       ElementsKind to_kind,
-                                       uint32_t to_start,
+                                       FixedArrayBase* to_base,
+                                       ElementsKind to_kind, uint32_t to_start,
                                        int raw_copy_size) {
   DCHECK(IsFastSmiOrObjectElementsKind(to_kind));
   int copy_size = raw_copy_size;
   if (raw_copy_size < 0) {
+    DisallowHeapAllocation no_allocation;
     DCHECK(raw_copy_size == ElementsAccessor::kCopyToEnd ||
            raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
     copy_size = Min(from_base->length() - from_start,
@@ -268,7 +271,7 @@
       int length = to_base->length() - start;
       if (length > 0) {
         Heap* heap = from_base->GetHeap();
-        MemsetPointer(FixedArray::cast(*to_base)->data_start() + start,
+        MemsetPointer(FixedArray::cast(to_base)->data_start() + start,
                       heap->the_hole_value(), length);
       }
     }
@@ -276,9 +279,12 @@
   DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() &&
          (copy_size + static_cast<int>(from_start)) <= from_base->length());
   if (copy_size == 0) return;
+
+  // From here on, the code below could actually allocate. Therefore the raw
+  // values are wrapped into handles.
   Isolate* isolate = from_base->GetIsolate();
-  Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base);
-  Handle<FixedArray> to = Handle<FixedArray>::cast(to_base);
+  Handle<FixedDoubleArray> from(FixedDoubleArray::cast(from_base), isolate);
+  Handle<FixedArray> to(FixedArray::cast(to_base), isolate);
   for (int i = 0; i < copy_size; ++i) {
     HandleScope scope(isolate);
     if (IsFastSmiElementsKind(to_kind)) {
@@ -554,9 +560,7 @@
   typedef ElementsTraitsParam ElementsTraits;
   typedef typename ElementsTraitsParam::BackingStore BackingStore;
 
-  virtual ElementsKind kind() const FINAL OVERRIDE {
-    return ElementsTraits::Kind;
-  }
+  ElementsKind kind() const FINAL { return ElementsTraits::Kind; }
 
   static void ValidateContents(Handle<JSObject> holder, int length) {
   }
@@ -578,7 +582,7 @@
     ElementsAccessorSubclass::ValidateContents(holder, length);
   }
 
-  virtual void Validate(Handle<JSObject> holder) FINAL OVERRIDE {
+  void Validate(Handle<JSObject> holder) FINAL {
     DisallowHeapAllocation no_gc;
     ElementsAccessorSubclass::ValidateImpl(holder);
   }
@@ -591,20 +595,16 @@
         receiver, holder, key, backing_store) != ABSENT;
   }
 
-  virtual bool HasElement(
-      Handle<Object> receiver,
-      Handle<JSObject> holder,
-      uint32_t key,
-      Handle<FixedArrayBase> backing_store) FINAL OVERRIDE {
+  virtual bool HasElement(Handle<Object> receiver, Handle<JSObject> holder,
+                          uint32_t key,
+                          Handle<FixedArrayBase> backing_store) FINAL {
     return ElementsAccessorSubclass::HasElementImpl(
         receiver, holder, key, backing_store);
   }
 
   MUST_USE_RESULT virtual MaybeHandle<Object> Get(
-      Handle<Object> receiver,
-      Handle<JSObject> holder,
-      uint32_t key,
-      Handle<FixedArrayBase> backing_store) FINAL OVERRIDE {
+      Handle<Object> receiver, Handle<JSObject> holder, uint32_t key,
+      Handle<FixedArrayBase> backing_store) FINAL {
     if (!IsExternalArrayElementsKind(ElementsTraits::Kind) &&
         FLAG_trace_js_array_abuse) {
       CheckArrayAbuse(holder, "elements read", key);
@@ -632,10 +632,8 @@
   }
 
   MUST_USE_RESULT virtual PropertyAttributes GetAttributes(
-      Handle<Object> receiver,
-      Handle<JSObject> holder,
-      uint32_t key,
-      Handle<FixedArrayBase> backing_store) FINAL OVERRIDE {
+      Handle<Object> receiver, Handle<JSObject> holder, uint32_t key,
+      Handle<FixedArrayBase> backing_store) FINAL {
     return ElementsAccessorSubclass::GetAttributesImpl(
         receiver, holder, key, backing_store);
   }
@@ -654,10 +652,8 @@
   }
 
   MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair(
-      Handle<Object> receiver,
-      Handle<JSObject> holder,
-      uint32_t key,
-      Handle<FixedArrayBase> backing_store) FINAL OVERRIDE {
+      Handle<Object> receiver, Handle<JSObject> holder, uint32_t key,
+      Handle<FixedArrayBase> backing_store) FINAL {
     return ElementsAccessorSubclass::GetAccessorPairImpl(
         receiver, holder, key, backing_store);
   }
@@ -671,8 +667,7 @@
   }
 
   MUST_USE_RESULT virtual MaybeHandle<Object> SetLength(
-      Handle<JSArray> array,
-      Handle<Object> length) FINAL OVERRIDE {
+      Handle<JSArray> array, Handle<Object> length) FINAL {
     return ElementsAccessorSubclass::SetLengthImpl(
         array, length, handle(array->elements()));
   }
@@ -682,10 +677,8 @@
       Handle<Object> length,
       Handle<FixedArrayBase> backing_store);
 
-  virtual void SetCapacityAndLength(
-      Handle<JSArray> array,
-      int capacity,
-      int length) FINAL OVERRIDE {
+  virtual void SetCapacityAndLength(Handle<JSArray> array, int capacity,
+                                    int length) FINAL {
     ElementsAccessorSubclass::
         SetFastElementsCapacityAndLength(array, capacity, length);
   }
@@ -702,36 +695,31 @@
       uint32_t key,
       JSReceiver::DeleteMode mode) OVERRIDE = 0;
 
-  static void CopyElementsImpl(Handle<FixedArrayBase> from,
-                               uint32_t from_start,
-                               Handle<FixedArrayBase> to,
-                               ElementsKind from_kind,
-                               uint32_t to_start,
-                               int packed_size,
+  static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
+                               FixedArrayBase* to, ElementsKind from_kind,
+                               uint32_t to_start, int packed_size,
                                int copy_size) {
     UNREACHABLE();
   }
 
-  virtual void CopyElements(
-      Handle<FixedArrayBase> from,
-      uint32_t from_start,
-      ElementsKind from_kind,
-      Handle<FixedArrayBase> to,
-      uint32_t to_start,
-      int copy_size) FINAL OVERRIDE {
+  virtual void CopyElements(Handle<FixedArrayBase> from, uint32_t from_start,
+                            ElementsKind from_kind, Handle<FixedArrayBase> to,
+                            uint32_t to_start, int copy_size) FINAL {
     DCHECK(!from.is_null());
-    ElementsAccessorSubclass::CopyElementsImpl(
-        from, from_start, to, from_kind, to_start, kPackedSizeNotKnown,
-        copy_size);
+    // NOTE: the ElementsAccessorSubclass::CopyElementsImpl() methods
+    // violate the handlified function signature convention:
+    // raw pointer parameters in the function that allocates. This is done
+    // intentionally to avoid ArrayConcat() builtin performance degradation.
+    // See the comment in another ElementsAccessorBase::CopyElements() for
+    // details.
+    ElementsAccessorSubclass::CopyElementsImpl(*from, from_start, *to,
+                                               from_kind, to_start,
+                                               kPackedSizeNotKnown, copy_size);
   }
 
-  virtual void CopyElements(
-      JSObject* from_holder,
-      uint32_t from_start,
-      ElementsKind from_kind,
-      Handle<FixedArrayBase> to,
-      uint32_t to_start,
-      int copy_size) FINAL OVERRIDE {
+  virtual void CopyElements(JSObject* from_holder, uint32_t from_start,
+                            ElementsKind from_kind, Handle<FixedArrayBase> to,
+                            uint32_t to_start, int copy_size) FINAL {
     int packed_size = kPackedSizeNotKnown;
     bool is_packed = IsFastPackedElementsKind(from_kind) &&
         from_holder->IsJSArray();
@@ -742,16 +730,23 @@
         packed_size = copy_size;
       }
     }
-    Handle<FixedArrayBase> from(from_holder->elements());
+    FixedArrayBase* from = from_holder->elements();
+    // NOTE: the ElementsAccessorSubclass::CopyElementsImpl() methods
+    // violate the handlified function signature convention:
+    // raw pointer parameters in the function that allocates. This is done
+    // intentionally to avoid ArrayConcat() builtin performance degradation.
+    //
+    // Details: The idea is that allocations actually happen only in case of
+    // copying from object with fast double elements to object with object
+    // elements. In all the other cases there are no allocations performed and
+    // handle creation causes noticeable performance degradation of the builtin.
     ElementsAccessorSubclass::CopyElementsImpl(
-        from, from_start, to, from_kind, to_start, packed_size, copy_size);
+        from, from_start, *to, from_kind, to_start, packed_size, copy_size);
   }
 
   virtual MaybeHandle<FixedArray> AddElementsToFixedArray(
-      Handle<Object> receiver,
-      Handle<JSObject> holder,
-      Handle<FixedArray> to,
-      Handle<FixedArrayBase> from) FINAL OVERRIDE {
+      Handle<Object> receiver, Handle<JSObject> holder, Handle<FixedArray> to,
+      Handle<FixedArrayBase> from, FixedArray::KeyFilter filter) FINAL {
     int len0 = to->length();
 #ifdef ENABLE_SLOW_DCHECKS
     if (FLAG_enable_slow_asserts) {
@@ -781,6 +776,9 @@
             FixedArray);
 
         DCHECK(!value->IsTheHole());
+        if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
+          continue;
+        }
         if (!HasKey(to, value)) {
           extra++;
         }
@@ -814,6 +812,9 @@
             isolate, value,
             ElementsAccessorSubclass::GetImpl(receiver, holder, key, from),
             FixedArray);
+        if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
+          continue;
+        }
         if (!value->IsTheHole() && !HasKey(to, value)) {
           result->set(len0 + index, *value);
           index++;
@@ -829,8 +830,7 @@
     return backing_store->length();
   }
 
-  virtual uint32_t GetCapacity(Handle<FixedArrayBase> backing_store)
-      FINAL OVERRIDE {
+  uint32_t GetCapacity(Handle<FixedArrayBase> backing_store) FINAL {
     return ElementsAccessorSubclass::GetCapacityImpl(backing_store);
   }
 
@@ -840,7 +840,7 @@
   }
 
   virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store,
-                                  uint32_t index) FINAL OVERRIDE {
+                                  uint32_t index) FINAL {
     return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index);
   }
 
@@ -974,10 +974,8 @@
     return isolate->factory()->true_value();
   }
 
-  virtual MaybeHandle<Object> Delete(
-      Handle<JSObject> obj,
-      uint32_t key,
-      JSReceiver::DeleteMode mode) FINAL OVERRIDE {
+  virtual MaybeHandle<Object> Delete(Handle<JSObject> obj, uint32_t key,
+                                     JSReceiver::DeleteMode mode) FINAL {
     return DeleteCommon(obj, key, mode);
   }
 
@@ -1018,7 +1016,7 @@
 };
 
 
-static inline ElementsKind ElementsKindForArray(Handle<FixedArrayBase> array) {
+static inline ElementsKind ElementsKindForArray(FixedArrayBase* array) {
   switch (array->map()->instance_type()) {
     case FIXED_ARRAY_TYPE:
       if (array->IsDictionary()) {
@@ -1054,38 +1052,42 @@
       : FastElementsAccessor<FastElementsAccessorSubclass,
                              KindTraits>(name) {}
 
-  static void CopyElementsImpl(Handle<FixedArrayBase> from,
-                               uint32_t from_start,
-                               Handle<FixedArrayBase> to,
-                               ElementsKind from_kind,
-                               uint32_t to_start,
-                               int packed_size,
+  // NOTE: this method violates the handlified function signature convention:
+  // raw pointer parameters in the function that allocates.
+  // See ElementsAccessor::CopyElements() for details.
+  // This method could actually allocate if copying from double elements to
+  // object elements.
+  static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
+                               FixedArrayBase* to, ElementsKind from_kind,
+                               uint32_t to_start, int packed_size,
                                int copy_size) {
+    DisallowHeapAllocation no_gc;
     ElementsKind to_kind = KindTraits::Kind;
     switch (from_kind) {
       case FAST_SMI_ELEMENTS:
       case FAST_HOLEY_SMI_ELEMENTS:
       case FAST_ELEMENTS:
       case FAST_HOLEY_ELEMENTS:
-        CopyObjectToObjectElements(*from, from_kind, from_start, *to, to_kind,
+        CopyObjectToObjectElements(from, from_kind, from_start, to, to_kind,
                                    to_start, copy_size);
         break;
       case FAST_DOUBLE_ELEMENTS:
-      case FAST_HOLEY_DOUBLE_ELEMENTS:
+      case FAST_HOLEY_DOUBLE_ELEMENTS: {
+        AllowHeapAllocation allow_allocation;
         CopyDoubleToObjectElements(
             from, from_start, to, to_kind, to_start, copy_size);
         break;
+      }
       case DICTIONARY_ELEMENTS:
-        CopyDictionaryToObjectElements(*from, from_start, *to, to_kind,
-                                       to_start, copy_size);
+        CopyDictionaryToObjectElements(from, from_start, to, to_kind, to_start,
+                                       copy_size);
         break;
       case SLOPPY_ARGUMENTS_ELEMENTS: {
         // TODO(verwaest): This is a temporary hack to support extending
         // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength.
         // This case should be UNREACHABLE().
-        Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(from);
-        Handle<FixedArrayBase> arguments(
-            FixedArrayBase::cast(parameter_map->get(1)));
+        FixedArray* parameter_map = FixedArray::cast(from);
+        FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
         ElementsKind from_kind = ElementsKindForArray(arguments);
         CopyElementsImpl(arguments, from_start, to, from_kind,
                          to_start, packed_size, copy_size);
@@ -1179,31 +1181,29 @@
   }
 
  protected:
-  static void CopyElementsImpl(Handle<FixedArrayBase> from,
-                               uint32_t from_start,
-                               Handle<FixedArrayBase> to,
-                               ElementsKind from_kind,
-                               uint32_t to_start,
-                               int packed_size,
+  static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
+                               FixedArrayBase* to, ElementsKind from_kind,
+                               uint32_t to_start, int packed_size,
                                int copy_size) {
+    DisallowHeapAllocation no_allocation;
     switch (from_kind) {
       case FAST_SMI_ELEMENTS:
-        CopyPackedSmiToDoubleElements(*from, from_start, *to, to_start,
+        CopyPackedSmiToDoubleElements(from, from_start, to, to_start,
                                       packed_size, copy_size);
         break;
       case FAST_HOLEY_SMI_ELEMENTS:
-        CopySmiToDoubleElements(*from, from_start, *to, to_start, copy_size);
+        CopySmiToDoubleElements(from, from_start, to, to_start, copy_size);
         break;
       case FAST_DOUBLE_ELEMENTS:
       case FAST_HOLEY_DOUBLE_ELEMENTS:
-        CopyDoubleToDoubleElements(*from, from_start, *to, to_start, copy_size);
+        CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size);
         break;
       case FAST_ELEMENTS:
       case FAST_HOLEY_ELEMENTS:
-        CopyObjectToDoubleElements(*from, from_start, *to, to_start, copy_size);
+        CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size);
         break;
       case DICTIONARY_ELEMENTS:
-        CopyDictionaryToDoubleElements(*from, from_start, *to, to_start,
+        CopyDictionaryToDoubleElements(from, from_start, to, to_start,
                                        copy_size);
         break;
       case SLOPPY_ARGUMENTS_ELEMENTS:
@@ -1298,9 +1298,7 @@
   }
 
   MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
-      Handle<JSObject> obj,
-      uint32_t key,
-      JSReceiver::DeleteMode mode) FINAL OVERRIDE {
+      Handle<JSObject> obj, uint32_t key, JSReceiver::DeleteMode mode) FINAL {
     // External arrays always ignore deletes.
     return obj->GetIsolate()->factory()->true_value();
   }
@@ -1439,12 +1437,9 @@
     return isolate->factory()->true_value();
   }
 
-  static void CopyElementsImpl(Handle<FixedArrayBase> from,
-                               uint32_t from_start,
-                               Handle<FixedArrayBase> to,
-                               ElementsKind from_kind,
-                               uint32_t to_start,
-                               int packed_size,
+  static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
+                               FixedArrayBase* to, ElementsKind from_kind,
+                               uint32_t to_start, int packed_size,
                                int copy_size) {
     UNREACHABLE();
   }
@@ -1455,9 +1450,7 @@
                                     ElementsKindTraits<DICTIONARY_ELEMENTS> >;
 
   MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
-      Handle<JSObject> obj,
-      uint32_t key,
-      JSReceiver::DeleteMode mode) FINAL OVERRIDE {
+      Handle<JSObject> obj, uint32_t key, JSReceiver::DeleteMode mode) FINAL {
     return DeleteCommon(obj, key, mode);
   }
 
@@ -1629,9 +1622,7 @@
   }
 
   MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
-      Handle<JSObject> obj,
-      uint32_t key,
-      JSReceiver::DeleteMode mode) FINAL OVERRIDE {
+      Handle<JSObject> obj, uint32_t key, JSReceiver::DeleteMode mode) FINAL {
     Isolate* isolate = obj->GetIsolate();
     Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
     Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
@@ -1654,12 +1645,9 @@
     return isolate->factory()->true_value();
   }
 
-  static void CopyElementsImpl(Handle<FixedArrayBase> from,
-                               uint32_t from_start,
-                               Handle<FixedArrayBase> to,
-                               ElementsKind from_kind,
-                               uint32_t to_start,
-                               int packed_size,
+  static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
+                               FixedArrayBase* to, ElementsKind from_kind,
+                               uint32_t to_start, int packed_size,
                                int copy_size) {
     UNREACHABLE();
   }
@@ -1715,7 +1703,7 @@
 
 
 ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) {
-  return elements_accessors_[ElementsKindForArray(array)];
+  return elements_accessors_[ElementsKindForArray(*array)];
 }
 
 
diff --git a/src/elements.h b/src/elements.h
index d0bddf9..05354ea 100644
--- a/src/elements.h
+++ b/src/elements.h
@@ -146,9 +146,10 @@
       uint32_t destination_start,
       int copy_size) = 0;
 
-  // TODO(ishell): Keeping |source_holder| parameter in a non-handlified form
-  // helps avoiding ArrayConcat() builtin performance degradation.
-  // Revisit this later.
+  // NOTE: this method violates the handlified function signature convention:
+  // raw pointer parameter |source_holder| in the function that allocates.
+  // This is done intentionally to avoid ArrayConcat() builtin performance
+  // degradation.
   virtual void CopyElements(
       JSObject* source_holder,
       uint32_t source_start,
@@ -166,22 +167,19 @@
   }
 
   MUST_USE_RESULT virtual MaybeHandle<FixedArray> AddElementsToFixedArray(
-      Handle<Object> receiver,
-      Handle<JSObject> holder,
-      Handle<FixedArray> to,
-      Handle<FixedArrayBase> from) = 0;
+      Handle<Object> receiver, Handle<JSObject> holder, Handle<FixedArray> to,
+      Handle<FixedArrayBase> from, FixedArray::KeyFilter filter) = 0;
 
   MUST_USE_RESULT inline MaybeHandle<FixedArray> AddElementsToFixedArray(
-      Handle<Object> receiver,
-      Handle<JSObject> holder,
-      Handle<FixedArray> to) {
-    return AddElementsToFixedArray(
-        receiver, holder, to, handle(holder->elements()));
+      Handle<Object> receiver, Handle<JSObject> holder, Handle<FixedArray> to,
+      FixedArray::KeyFilter filter) {
+    return AddElementsToFixedArray(receiver, holder, to,
+                                   handle(holder->elements()), filter);
   }
 
   // Returns a shared ElementsAccessor for the specified ElementsKind.
   static ElementsAccessor* ForKind(ElementsKind elements_kind) {
-    DCHECK(elements_kind < kElementsKindCount);
+    DCHECK(static_cast<int>(elements_kind) < kElementsKindCount);
     return elements_accessors_[elements_kind];
   }
 
diff --git a/src/execution.cc b/src/execution.cc
index 7aa4f33..a85effd 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -34,6 +34,17 @@
 }
 
 
+static void PrintDeserializedCodeInfo(Handle<JSFunction> function) {
+  if (function->code() == function->shared()->code() &&
+      function->shared()->deserialized()) {
+    PrintF("Running deserialized script ");
+    Object* script = function->shared()->script();
+    if (script->IsScript()) Script::cast(script)->name()->ShortPrint();
+    PrintF("\n");
+  }
+}
+
+
 MUST_USE_RESULT static MaybeHandle<Object> Invoke(
     bool is_construct,
     Handle<JSFunction> function,
@@ -87,6 +98,7 @@
     JSFunction* func = *function;
     Object* recv = *receiver;
     Object*** argv = reinterpret_cast<Object***>(args);
+    if (FLAG_profile_deserialization) PrintDeserializedCodeInfo(function);
     value =
         CALL_GENERATED_CODE(stub_entry, function_entry, func, recv, argc, argv);
   }
@@ -533,6 +545,12 @@
 }
 
 
+MaybeHandle<Object> Execution::ToLength(
+    Isolate* isolate, Handle<Object> obj) {
+  RETURN_NATIVE_CALL(to_length, { obj });
+}
+
+
 MaybeHandle<Object> Execution::NewDate(Isolate* isolate, double time) {
   Handle<Object> time_obj = isolate->factory()->NewNumber(time);
   RETURN_NATIVE_CALL(create_date, { time_obj });
@@ -695,8 +713,8 @@
   }
 
   if (CheckAndClearInterrupt(API_INTERRUPT)) {
-    // Callback must be invoked outside of ExecusionAccess lock.
-    isolate_->InvokeApiInterruptCallback();
+    // Callbacks must be invoked outside of ExecusionAccess lock.
+    isolate_->InvokeApiInterruptCallbacks();
   }
 
   isolate_->counters()->stack_interrupts()->Increment();
diff --git a/src/execution.h b/src/execution.h
index 89175cd..ae263bd 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -69,6 +69,11 @@
   MUST_USE_RESULT static MaybeHandle<Object> ToUint32(
       Isolate* isolate, Handle<Object> obj);
 
+
+  // ES6, draft 10-14-14, section 7.1.15
+  MUST_USE_RESULT static MaybeHandle<Object> ToLength(
+      Isolate* isolate, Handle<Object> obj);
+
   // ECMA-262 9.8
   MUST_USE_RESULT static MaybeHandle<Object> ToString(
       Isolate* isolate, Handle<Object> obj);
diff --git a/src/extensions/statistics-extension.cc b/src/extensions/statistics-extension.cc
index 6f63245..bb5ee33 100644
--- a/src/extensions/statistics-extension.cc
+++ b/src/extensions/statistics-extension.cc
@@ -53,7 +53,8 @@
   Heap* heap = isolate->heap();
 
   if (args.Length() > 0) {  // GC if first argument evaluates to true.
-    if (args[0]->IsBoolean() && args[0]->ToBoolean()->Value()) {
+    if (args[0]->IsBoolean() &&
+        args[0]->ToBoolean(args.GetIsolate())->Value()) {
       heap->CollectAllGarbage(Heap::kNoGCFlags, "counters extension");
     }
   }
diff --git a/src/factory.cc b/src/factory.cc
index 45a79c1..ba62341 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -139,12 +139,12 @@
 
 
 Handle<OrderedHashSet> Factory::NewOrderedHashSet() {
-  return OrderedHashSet::Allocate(isolate(), 4);
+  return OrderedHashSet::Allocate(isolate(), OrderedHashSet::kMinCapacity);
 }
 
 
 Handle<OrderedHashMap> Factory::NewOrderedHashMap() {
-  return OrderedHashMap::Allocate(isolate(), 4);
+  return OrderedHashMap::Allocate(isolate(), OrderedHashMap::kMinCapacity);
 }
 
 
@@ -693,21 +693,31 @@
 }
 
 
-Handle<Context> Factory::NewGlobalContext(Handle<JSFunction> function,
+Handle<Context> Factory::NewScriptContext(Handle<JSFunction> function,
                                           Handle<ScopeInfo> scope_info) {
   Handle<FixedArray> array =
       NewFixedArray(scope_info->ContextLength(), TENURED);
-  array->set_map_no_write_barrier(*global_context_map());
+  array->set_map_no_write_barrier(*script_context_map());
   Handle<Context> context = Handle<Context>::cast(array);
   context->set_closure(*function);
   context->set_previous(function->context());
   context->set_extension(*scope_info);
   context->set_global_object(function->context()->global_object());
-  DCHECK(context->IsGlobalContext());
+  DCHECK(context->IsScriptContext());
   return context;
 }
 
 
+Handle<ScriptContextTable> Factory::NewScriptContextTable() {
+  Handle<FixedArray> array = NewFixedArray(1);
+  array->set_map_no_write_barrier(*script_context_table_map());
+  Handle<ScriptContextTable> context_table =
+      Handle<ScriptContextTable>::cast(array);
+  context_table->set_used(0);
+  return context_table;
+}
+
+
 Handle<Context> Factory::NewModuleContext(Handle<ScopeInfo> scope_info) {
   Handle<FixedArray> array =
       NewFixedArray(scope_info->ContextLength(), TENURED);
@@ -792,6 +802,7 @@
       Handle<CodeCache>::cast(NewStruct(CODE_CACHE_TYPE));
   code_cache->set_default_cache(*empty_fixed_array(), SKIP_WRITE_BARRIER);
   code_cache->set_normal_type_cache(*undefined_value(), SKIP_WRITE_BARRIER);
+  code_cache->set_weak_cell_cache(*undefined_value(), SKIP_WRITE_BARRIER);
   return code_cache;
 }
 
@@ -837,7 +848,6 @@
   heap->set_last_script_id(Smi::FromInt(id));
 
   // Create and initialize script object.
-  Handle<Foreign> wrapper = NewForeign(0, TENURED);
   Handle<Script> script = Handle<Script>::cast(NewStruct(SCRIPT_TYPE));
   script->set_source(*source);
   script->set_name(heap->undefined_value());
@@ -846,7 +856,7 @@
   script->set_column_offset(Smi::FromInt(0));
   script->set_context_data(heap->undefined_value());
   script->set_type(Smi::FromInt(Script::TYPE_NORMAL));
-  script->set_wrapper(*wrapper);
+  script->set_wrapper(heap->undefined_value());
   script->set_line_ends(heap->undefined_value());
   script->set_eval_from_shared(heap->undefined_value());
   script->set_eval_from_instructions_offset(Smi::FromInt(0));
@@ -931,6 +941,13 @@
 }
 
 
+Handle<WeakCell> Factory::NewWeakCell(Handle<HeapObject> value) {
+  AllowDeferredHandleDereference convert_to_cell;
+  CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->AllocateWeakCell(*value),
+                     WeakCell);
+}
+
+
 Handle<AllocationSite> Factory::NewAllocationSite() {
   Handle<Map> map = allocation_site_map();
   Handle<AllocationSite> site = New<AllocationSite>(map, OLD_POINTER_SPACE);
@@ -1018,7 +1035,7 @@
   // patterns is faster than using fpclassify() et al.
   if (IsMinusZero(value)) return NewHeapNumber(-0.0, IMMUTABLE, pretenure);
 
-  int int_value = FastD2I(value);
+  int int_value = FastD2IChecked(value);
   if (value == int_value && Smi::IsValid(int_value)) {
     return handle(Smi::FromInt(int_value), isolate());
   }
@@ -1292,20 +1309,25 @@
 }
 
 
-Handle<JSFunction> Factory::NewFunction(Handle<String> name,
-                                        Handle<Code> code,
+Handle<JSFunction> Factory::NewFunction(Handle<String> name, Handle<Code> code,
                                         Handle<Object> prototype,
-                                        InstanceType type,
-                                        int instance_size,
-                                        bool read_only_prototype) {
+                                        InstanceType type, int instance_size,
+                                        bool read_only_prototype,
+                                        bool install_constructor) {
   // Allocate the function
   Handle<JSFunction> function = NewFunction(
       name, code, prototype, read_only_prototype);
 
-  Handle<Map> initial_map = NewMap(
-      type, instance_size, GetInitialFastElementsKind());
-  if (prototype->IsTheHole() && !function->shared()->is_generator()) {
-    prototype = NewFunctionPrototype(function);
+  ElementsKind elements_kind =
+      type == JS_ARRAY_TYPE ? FAST_SMI_ELEMENTS : FAST_HOLEY_SMI_ELEMENTS;
+  Handle<Map> initial_map = NewMap(type, instance_size, elements_kind);
+  if (!function->shared()->is_generator()) {
+    if (prototype->IsTheHole()) {
+      prototype = NewFunctionPrototype(function);
+    } else if (install_constructor) {
+      JSObject::AddProperty(Handle<JSObject>::cast(prototype),
+                            constructor_string(), function, DONT_ENUM);
+    }
   }
 
   JSFunction::SetInitialMap(function, initial_map,
@@ -1351,6 +1373,14 @@
 }
 
 
+static bool ShouldOptimizeNewClosure(Isolate* isolate,
+                                     Handle<SharedFunctionInfo> info) {
+  return isolate->use_crankshaft() && !info->is_toplevel() &&
+         info->is_compiled() && info->allows_lazy_compilation() &&
+         !info->optimization_disabled() && !isolate->DebuggerHasBreakPoints();
+}
+
+
 Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
     Handle<SharedFunctionInfo> info,
     Handle<Context> context,
@@ -1388,13 +1418,7 @@
     return result;
   }
 
-  if (isolate()->use_crankshaft() &&
-      FLAG_always_opt &&
-      result->is_compiled() &&
-      !info->is_toplevel() &&
-      info->allows_lazy_compilation() &&
-      !info->optimization_disabled() &&
-      !isolate()->DebuggerHasBreakPoints()) {
+  if (FLAG_always_opt && ShouldOptimizeNewClosure(isolate(), info)) {
     result->MarkForOptimization();
   }
   return result;
@@ -1568,7 +1592,7 @@
   for (int i = 0; i < map->NumberOfOwnDescriptors(); i++) {
     PropertyDetails details = descs->GetDetails(i);
     DCHECK(details.type() == CALLBACKS);  // Only accessors are expected.
-    PropertyDetails d = PropertyDetails(details.attributes(), CALLBACKS, i + 1);
+    PropertyDetails d(details.attributes(), CALLBACKS, i + 1);
     Handle<Name> name(descs->GetKey(i));
     Handle<Object> value(descs->GetCallbacksObject(i), isolate());
     Handle<PropertyCell> cell = NewPropertyCell(value);
@@ -1658,6 +1682,7 @@
     return;
   }
 
+  HandleScope inner_scope(isolate());
   Handle<FixedArrayBase> elms;
   ElementsKind elements_kind = array->GetElementsKind();
   if (IsFastDoubleElementsKind(elements_kind)) {
@@ -1715,8 +1740,51 @@
 }
 
 
-static JSFunction* GetTypedArrayFun(ExternalArrayType type,
-                                    Isolate* isolate) {
+Handle<JSMapIterator> Factory::NewJSMapIterator() {
+  Handle<Map> map(isolate()->native_context()->map_iterator_map());
+  CALL_HEAP_FUNCTION(isolate(),
+                     isolate()->heap()->AllocateJSObjectFromMap(*map),
+                     JSMapIterator);
+}
+
+
+Handle<JSSetIterator> Factory::NewJSSetIterator() {
+  Handle<Map> map(isolate()->native_context()->set_iterator_map());
+  CALL_HEAP_FUNCTION(isolate(),
+                     isolate()->heap()->AllocateJSObjectFromMap(*map),
+                     JSSetIterator);
+}
+
+
+namespace {
+
+ElementsKind GetExternalArrayElementsKind(ExternalArrayType type) {
+  switch (type) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+  case kExternal##Type##Array:                          \
+    return EXTERNAL_##TYPE##_ELEMENTS;
+    TYPED_ARRAYS(TYPED_ARRAY_CASE)
+  }
+  UNREACHABLE();
+  return FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND;
+#undef TYPED_ARRAY_CASE
+}
+
+
+size_t GetExternalArrayElementSize(ExternalArrayType type) {
+  switch (type) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+  case kExternal##Type##Array:                          \
+    return size;
+    TYPED_ARRAYS(TYPED_ARRAY_CASE)
+  }
+  UNREACHABLE();
+  return 0;
+#undef TYPED_ARRAY_CASE
+}
+
+
+JSFunction* GetTypedArrayFun(ExternalArrayType type, Isolate* isolate) {
   Context* native_context = isolate->context()->native_context();
   switch (type) {
 #define TYPED_ARRAY_FUN(Type, type, TYPE, ctype, size)                        \
@@ -1733,6 +1801,31 @@
 }
 
 
+void SetupArrayBufferView(i::Isolate* isolate,
+                          i::Handle<i::JSArrayBufferView> obj,
+                          i::Handle<i::JSArrayBuffer> buffer,
+                          size_t byte_offset, size_t byte_length) {
+  DCHECK(byte_offset + byte_length <=
+         static_cast<size_t>(buffer->byte_length()->Number()));
+
+  obj->set_buffer(*buffer);
+
+  obj->set_weak_next(buffer->weak_first_view());
+  buffer->set_weak_first_view(*obj);
+
+  i::Handle<i::Object> byte_offset_object =
+      isolate->factory()->NewNumberFromSize(byte_offset);
+  obj->set_byte_offset(*byte_offset_object);
+
+  i::Handle<i::Object> byte_length_object =
+      isolate->factory()->NewNumberFromSize(byte_length);
+  obj->set_byte_length(*byte_length_object);
+}
+
+
+}  // namespace
+
+
 Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type) {
   Handle<JSFunction> typed_array_fun_handle(GetTypedArrayFun(type, isolate()));
 
@@ -1743,13 +1836,50 @@
 }
 
 
+Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
+                                              Handle<JSArrayBuffer> buffer,
+                                              size_t byte_offset,
+                                              size_t length) {
+  Handle<JSTypedArray> obj = NewJSTypedArray(type);
+
+  size_t element_size = GetExternalArrayElementSize(type);
+  ElementsKind elements_kind = GetExternalArrayElementsKind(type);
+
+  CHECK(byte_offset % element_size == 0);
+
+  CHECK(length <= (std::numeric_limits<size_t>::max() / element_size));
+  CHECK(length <= static_cast<size_t>(Smi::kMaxValue));
+  size_t byte_length = length * element_size;
+  SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length);
+
+  Handle<Object> length_object = NewNumberFromSize(length);
+  obj->set_length(*length_object);
+
+  Handle<ExternalArray> elements = NewExternalArray(
+      static_cast<int>(length), type,
+      static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
+  Handle<Map> map = JSObject::GetElementsTransitionMap(obj, elements_kind);
+  JSObject::SetMapAndElements(obj, map, elements);
+  return obj;
+}
+
+
+Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer,
+                                          size_t byte_offset,
+                                          size_t byte_length) {
+  Handle<JSDataView> obj = NewJSDataView();
+  SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length);
+  return obj;
+}
+
+
 Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler,
                                     Handle<Object> prototype) {
   // Allocate map.
   // TODO(rossberg): Once we optimize proxies, think about a scheme to share
   // maps. Will probably depend on the identity of the handler object, too.
   Handle<Map> map = NewMap(JS_PROXY_TYPE, JSProxy::kSize);
-  map->set_prototype(*prototype);
+  map->SetPrototype(prototype);
 
   // Allocate the proxy object.
   Handle<JSProxy> result = New<JSProxy>(map, NEW_SPACE);
@@ -1768,7 +1898,7 @@
   // TODO(rossberg): Once we optimize proxies, think about a scheme to share
   // maps. Will probably depend on the identity of the handler object, too.
   Handle<Map> map = NewMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize);
-  map->set_prototype(*prototype);
+  map->SetPrototype(prototype);
 
   // Allocate the proxy object.
   Handle<JSFunctionProxy> result = New<JSFunctionProxy>(map, NEW_SPACE);
@@ -1793,7 +1923,7 @@
   int size_difference = proxy->map()->instance_size() - map->instance_size();
   DCHECK(size_difference >= 0);
 
-  map->set_prototype(proxy->map()->prototype());
+  map->SetPrototype(handle(proxy->map()->prototype(), proxy->GetIsolate()));
 
   // Allocate the backing storage for the properties.
   int prop_size = map->InitialPropertiesLength();
@@ -1886,20 +2016,9 @@
 }
 
 
-Handle<TypeFeedbackVector> Factory::NewTypeFeedbackVector(int slot_count) {
-  // Ensure we can skip the write barrier
-  DCHECK_EQ(isolate()->heap()->uninitialized_symbol(),
-            *TypeFeedbackVector::UninitializedSentinel(isolate()));
-
-  if (slot_count == 0) {
-    return Handle<TypeFeedbackVector>::cast(empty_fixed_array());
-  }
-
-  CALL_HEAP_FUNCTION(isolate(),
-                     isolate()->heap()->AllocateFixedArrayWithFiller(
-                         slot_count, TENURED,
-                         *TypeFeedbackVector::UninitializedSentinel(isolate())),
-                     TypeFeedbackVector);
+Handle<TypeFeedbackVector> Factory::NewTypeFeedbackVector(
+    const FeedbackVectorSpec& spec) {
+  return TypeFeedbackVector::Allocate(isolate(), spec);
 }
 
 
@@ -1974,8 +2093,13 @@
   share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
   share->set_debug_info(*undefined_value(), SKIP_WRITE_BARRIER);
   share->set_inferred_name(*empty_string(), SKIP_WRITE_BARRIER);
-  Handle<TypeFeedbackVector> feedback_vector = NewTypeFeedbackVector(0);
+  FeedbackVectorSpec empty_spec;
+  Handle<TypeFeedbackVector> feedback_vector =
+      NewTypeFeedbackVector(empty_spec);
   share->set_feedback_vector(*feedback_vector, SKIP_WRITE_BARRIER);
+#if TRACE_MAPS
+  share->set_unique_id(isolate()->GetNextUniqueSharedFunctionInfoId());
+#endif
   share->set_profiler_ticks(0);
   share->set_ast_node_count(0);
   share->set_counters(0);
@@ -2033,7 +2157,7 @@
       // cache in the snapshot to keep  boot-time memory usage down.
       // If we expand the number string cache already while creating
       // the snapshot then that didn't work out.
-      DCHECK(!isolate()->serializer_enabled() || FLAG_extra_code != NULL);
+      DCHECK(!isolate()->serializer_enabled());
       Handle<FixedArray> new_cache = NewFixedArray(full_size, TENURED);
       isolate()->heap()->set_number_string_cache(*new_cache);
       return;
@@ -2164,8 +2288,8 @@
         break;
     }
 
-    result = NewFunction(empty_string(), code, prototype, type,
-                         instance_size, obj->read_only_prototype());
+    result = NewFunction(empty_string(), code, prototype, type, instance_size,
+                         obj->read_only_prototype(), true);
   }
 
   result->shared()->set_length(obj->length());
@@ -2185,19 +2309,13 @@
     return result;
   }
 
-  if (prototype->IsTheHole()) {
 #ifdef DEBUG
-    LookupIterator it(handle(JSObject::cast(result->prototype())),
-                      constructor_string(),
-                      LookupIterator::OWN_SKIP_INTERCEPTOR);
-    MaybeHandle<Object> maybe_prop = Object::GetProperty(&it);
-    DCHECK(it.IsFound());
-    DCHECK(maybe_prop.ToHandleChecked().is_identical_to(result));
+  LookupIterator it(handle(JSObject::cast(result->prototype())),
+                    constructor_string(), LookupIterator::OWN_SKIP_INTERCEPTOR);
+  MaybeHandle<Object> maybe_prop = Object::GetProperty(&it);
+  DCHECK(it.IsFound());
+  DCHECK(maybe_prop.ToHandleChecked().is_identical_to(result));
 #endif
-  } else {
-    JSObject::AddProperty(handle(JSObject::cast(result->prototype())),
-                          constructor_string(), result, DONT_ENUM);
-  }
 
   // Down from here is only valid for API functions that can be used as a
   // constructor (don't set the "remove prototype" flag).
@@ -2306,35 +2424,42 @@
 }
 
 
-Handle<MapCache> Factory::AddToMapCache(Handle<Context> context,
-                                        Handle<FixedArray> keys,
-                                        Handle<Map> map) {
-  Handle<MapCache> map_cache = handle(MapCache::cast(context->map_cache()));
-  Handle<MapCache> result = MapCache::Put(map_cache, keys, map);
-  context->set_map_cache(*result);
-  return result;
-}
-
-
 Handle<Map> Factory::ObjectLiteralMapFromCache(Handle<Context> context,
-                                               Handle<FixedArray> keys) {
+                                               int number_of_properties,
+                                               bool* is_result_from_cache) {
+  const int kMapCacheSize = 128;
+
+  if (number_of_properties > kMapCacheSize) {
+    *is_result_from_cache = false;
+    return Map::Create(isolate(), number_of_properties);
+  }
+  *is_result_from_cache = true;
+  if (number_of_properties == 0) {
+    // Reuse the initial map of the Object function if the literal has no
+    // predeclared properties.
+    return handle(context->object_function()->initial_map(), isolate());
+  }
+  int cache_index = number_of_properties - 1;
   if (context->map_cache()->IsUndefined()) {
     // Allocate the new map cache for the native context.
-    Handle<MapCache> new_cache = MapCache::New(isolate(), 24);
+    Handle<FixedArray> new_cache = NewFixedArray(kMapCacheSize, TENURED);
     context->set_map_cache(*new_cache);
   }
   // Check to see whether there is a matching element in the cache.
-  Handle<MapCache> cache =
-      Handle<MapCache>(MapCache::cast(context->map_cache()));
-  Handle<Object> result = Handle<Object>(cache->Lookup(*keys), isolate());
-  if (result->IsMap()) return Handle<Map>::cast(result);
-  int length = keys->length();
-  // Create a new map and add it to the cache. Reuse the initial map of the
-  // Object function if the literal has no predeclared properties.
-  Handle<Map> map = length == 0
-                        ? handle(context->object_function()->initial_map())
-                        : Map::Create(isolate(), length);
-  AddToMapCache(context, keys, map);
+  Handle<FixedArray> cache(FixedArray::cast(context->map_cache()));
+  {
+    Object* result = cache->get(cache_index);
+    if (result->IsWeakCell()) {
+      WeakCell* cell = WeakCell::cast(result);
+      if (!cell->cleared()) {
+        return handle(Map::cast(cell->value()), isolate());
+      }
+    }
+  }
+  // Create a new map and add it to the cache.
+  Handle<Map> map = Map::Create(isolate(), number_of_properties);
+  Handle<WeakCell> cell = NewWeakCell(map);
+  cache->set(cache_index, *cell);
   return map;
 }
 
@@ -2353,6 +2478,7 @@
   regexp->set_data(*store);
 }
 
+
 void Factory::SetRegExpIrregexpData(Handle<JSRegExp> regexp,
                                     JSRegExp::Type type,
                                     Handle<String> source,
@@ -2374,7 +2500,6 @@
 }
 
 
-
 MaybeHandle<FunctionTemplateInfo> Factory::ConfigureInstance(
     Handle<FunctionTemplateInfo> desc, Handle<JSObject> instance) {
   // Configure the instance by adding the properties specified by the
diff --git a/src/factory.h b/src/factory.h
index 24b490c..24a6647 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -10,8 +10,9 @@
 namespace v8 {
 namespace internal {
 
-// Interface for handle based allocation.
+class FeedbackVectorSpec;
 
+// Interface for handle based allocation.
 class Factory FINAL {
  public:
   Handle<Oddball> NewOddball(Handle<Map> map,
@@ -225,10 +226,13 @@
   // Create a global (but otherwise uninitialized) context.
   Handle<Context> NewNativeContext();
 
-  // Create a global context.
-  Handle<Context> NewGlobalContext(Handle<JSFunction> function,
+  // Create a script context.
+  Handle<Context> NewScriptContext(Handle<JSFunction> function,
                                    Handle<ScopeInfo> scope_info);
 
+  // Create an empty script context table.
+  Handle<ScriptContextTable> NewScriptContextTable();
+
   // Create a module context.
   Handle<Context> NewModuleContext(Handle<ScopeInfo> scope_info);
 
@@ -296,6 +300,8 @@
 
   Handle<PropertyCell> NewPropertyCell(Handle<Object> value);
 
+  Handle<WeakCell> NewWeakCell(Handle<HeapObject> value);
+
   // Allocate a tenured AllocationSite. It's payload is null.
   Handle<AllocationSite> NewAllocationSite();
 
@@ -434,7 +440,18 @@
 
   Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type);
 
+  // Creates a new JSTypedArray with the specified buffer.
+  Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type,
+                                       Handle<JSArrayBuffer> buffer,
+                                       size_t byte_offset, size_t length);
+
   Handle<JSDataView> NewJSDataView();
+  Handle<JSDataView> NewJSDataView(Handle<JSArrayBuffer> buffer,
+                                   size_t byte_offset, size_t byte_length);
+
+  // TODO(aandrey): Maybe these should take table, index and kind arguments.
+  Handle<JSMapIterator> NewJSMapIterator();
+  Handle<JSSetIterator> NewJSSetIterator();
 
   // Allocates a Harmony proxy.
   Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype);
@@ -469,12 +486,11 @@
       Handle<Context> context,
       PretenureFlag pretenure = TENURED);
 
-  Handle<JSFunction> NewFunction(Handle<String> name,
-                                 Handle<Code> code,
-                                 Handle<Object> prototype,
-                                 InstanceType type,
+  Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
+                                 Handle<Object> prototype, InstanceType type,
                                  int instance_size,
-                                 bool read_only_prototype = false);
+                                 bool read_only_prototype = false,
+                                 bool install_constructor = false);
   Handle<JSFunction> NewFunction(Handle<String> name,
                                  Handle<Code> code,
                                  InstanceType type,
@@ -588,6 +604,22 @@
   INTERNALIZED_STRING_LIST(STRING_ACCESSOR)
 #undef STRING_ACCESSOR
 
+#define SYMBOL_ACCESSOR(name)                                   \
+  inline Handle<Symbol> name() {                                \
+    return Handle<Symbol>(bit_cast<Symbol**>(                   \
+        &isolate()->heap()->roots_[Heap::k##name##RootIndex])); \
+  }
+  PRIVATE_SYMBOL_LIST(SYMBOL_ACCESSOR)
+#undef SYMBOL_ACCESSOR
+
+#define SYMBOL_ACCESSOR(name, varname, description)             \
+  inline Handle<Symbol> name() {                                \
+    return Handle<Symbol>(bit_cast<Symbol**>(                   \
+        &isolate()->heap()->roots_[Heap::k##name##RootIndex])); \
+  }
+  PUBLIC_SYMBOL_LIST(SYMBOL_ACCESSOR)
+#undef SYMBOL_ACCESSOR
+
   inline void set_string_table(Handle<StringTable> table) {
     isolate()->heap()->set_string_table(*table);
   }
@@ -605,7 +637,8 @@
                                                    MaybeHandle<Code> code);
 
   // Allocate a new type feedback vector
-  Handle<TypeFeedbackVector> NewTypeFeedbackVector(int slot_count);
+  Handle<TypeFeedbackVector> NewTypeFeedbackVector(
+      const FeedbackVectorSpec& spec);
 
   // Allocates a new JSMessageObject object.
   Handle<JSMessageObject> NewJSMessageObject(
@@ -618,10 +651,11 @@
 
   Handle<DebugInfo> NewDebugInfo(Handle<SharedFunctionInfo> shared);
 
-  // Return a map using the map cache in the native context.
-  // The key the an ordered set of property names.
+  // Return a map for given number of properties using the map cache in the
+  // native context.
   Handle<Map> ObjectLiteralMapFromCache(Handle<Context> context,
-                                        Handle<FixedArray> keys);
+                                        int number_of_properties,
+                                        bool* is_result_from_cache);
 
   // Creates a new FixedArray that holds the data associated with the
   // atom regexp and stores it in the regexp.
@@ -664,14 +698,6 @@
   // Creates a code object that is not yet fully initialized yet.
   inline Handle<Code> NewCodeRaw(int object_size, bool immovable);
 
-  // Create a new map cache.
-  Handle<MapCache> NewMapCache(int at_least_space_for);
-
-  // Update the map cache in the native context with (keys, map)
-  Handle<MapCache> AddToMapCache(Handle<Context> context,
-                                 Handle<FixedArray> keys,
-                                 Handle<Map> map);
-
   // Attempt to find the number in a small cache.  If we finds it, return
   // the string representation of the number.  Otherwise return undefined.
   Handle<Object> GetNumberStringCache(Handle<Object> number);
diff --git a/src/fast-dtoa.cc b/src/fast-dtoa.cc
index 13b0463..d6edddc 100644
--- a/src/fast-dtoa.cc
+++ b/src/fast-dtoa.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "include/v8stdint.h"
+#include <stdint.h>
 #include "src/base/logging.h"
 #include "src/utils.h"
 
diff --git a/src/feedback-slots.h b/src/feedback-slots.h
deleted file mode 100644
index 9951fc8..0000000
--- a/src/feedback-slots.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_FEEDBACK_SLOTS_H_
-#define V8_FEEDBACK_SLOTS_H_
-
-#include "src/v8.h"
-
-#include "src/isolate.h"
-
-namespace v8 {
-namespace internal {
-
-class FeedbackSlotInterface {
- public:
-  static const int kInvalidFeedbackSlot = -1;
-
-  virtual ~FeedbackSlotInterface() {}
-
-  virtual int ComputeFeedbackSlotCount() = 0;
-  virtual void SetFirstFeedbackSlot(int slot) = 0;
-};
-
-} }  // namespace v8::internal
-
-#endif  // V8_FEEDBACK_SLOTS_H_
diff --git a/src/field-index.h b/src/field-index.h
index 2558529..76b1116 100644
--- a/src/field-index.h
+++ b/src/field-index.h
@@ -34,6 +34,8 @@
     return IsInObjectBits::decode(bit_field_);
   }
 
+  bool is_hidden_field() const { return IsHiddenField::decode(bit_field_); }
+
   bool is_double() const {
     return IsDoubleBits::decode(bit_field_);
   }
@@ -55,7 +57,7 @@
   // Zero-based from the first inobject property. Overflows to out-of-object
   // properties.
   int property_index() const {
-    DCHECK(!IsHiddenField::decode(bit_field_));
+    DCHECK(!is_hidden_field());
     int result = index() - first_inobject_property_offset() / kPointerSize;
     if (!is_inobject()) {
       result += InObjectPropertyBits::decode(bit_field_);
@@ -86,7 +88,7 @@
   explicit FieldIndex(int bit_field) : bit_field_(bit_field) {}
 
   int first_inobject_property_offset() const {
-    DCHECK(!IsHiddenField::decode(bit_field_));
+    DCHECK(!is_hidden_field());
     return FirstInobjectPropertyOffsetBits::decode(bit_field_);
   }
 
diff --git a/src/fixed-dtoa.cc b/src/fixed-dtoa.cc
index 56fe9ab..7856b13 100644
--- a/src/fixed-dtoa.cc
+++ b/src/fixed-dtoa.cc
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <stdint.h>
+
 #include <cmath>
 
-#include "include/v8stdint.h"
 #include "src/base/logging.h"
 #include "src/utils.h"
 
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 49f0714..348a52e 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -16,6 +16,9 @@
 #define DEFINE_NEG_IMPLICATION(whenflag, thenflag)          \
   DEFINE_VALUE_IMPLICATION(whenflag, thenflag, false)
 
+#define DEFINE_NEG_NEG_IMPLICATION(whenflag, thenflag) \
+  DEFINE_NEG_VALUE_IMPLICATION(whenflag, thenflag, false)
+
 // We want to declare the names of the variables for the header file.  Normally
 // this will just be an extern declaration, but for a readonly flag we let the
 // compiler make better optimizations by giving it the value.
@@ -54,6 +57,9 @@
 #define DEFINE_VALUE_IMPLICATION(whenflag, thenflag, value) \
   if (FLAG_##whenflag) FLAG_##thenflag = value;
 
+#define DEFINE_NEG_VALUE_IMPLICATION(whenflag, thenflag, value) \
+  if (!FLAG_##whenflag) FLAG_##thenflag = value;
+
 #else
 #error No mode supplied when including flags.defs
 #endif
@@ -75,6 +81,10 @@
 #define DEFINE_VALUE_IMPLICATION(whenflag, thenflag, value)
 #endif
 
+#ifndef DEFINE_NEG_VALUE_IMPLICATION
+#define DEFINE_NEG_VALUE_IMPLICATION(whenflag, thenflag, value)
+#endif
+
 #define COMMA ,
 
 #ifdef FLAG_MODE_DECLARE
@@ -114,6 +124,11 @@
 #else
 #define ENABLE_ARMV7_DEFAULT false
 #endif
+#if (defined CAN_USE_ARMV8_INSTRUCTIONS) || !(defined ARM_TEST_NO_FEATURE_PROBE)
+#define ENABLE_ARMV8_DEFAULT true
+#else
+#define ENABLE_ARMV8_DEFAULT false
+#endif
 #if (defined CAN_USE_VFP32DREGS) || !(defined ARM_TEST_NO_FEATURE_PROBE)
 #define ENABLE_32DREGS_DEFAULT true
 #else
@@ -126,6 +141,8 @@
 #endif
 
 #define DEFINE_BOOL(nam, def, cmt) FLAG(BOOL, bool, nam, def, cmt)
+#define DEFINE_BOOL_READONLY(nam, def, cmt) \
+  FLAG_READONLY(BOOL, bool, nam, def, cmt)
 #define DEFINE_MAYBE_BOOL(nam, cmt) \
   FLAG(MAYBE_BOOL, MaybeBoolFlag, nam, {false COMMA false}, cmt)
 #define DEFINE_INT(nam, def, cmt) FLAG(INT, int, nam, def, cmt)
@@ -147,45 +164,71 @@
 
 // Flags for language modes and experimental language features.
 DEFINE_BOOL(use_strict, false, "enforce strict mode")
-DEFINE_BOOL(es_staging, false, "enable upcoming ES6+ features")
 
-DEFINE_BOOL(harmony_scoping, false, "enable harmony block scoping")
-DEFINE_BOOL(harmony_modules, false,
-            "enable harmony modules (implies block scoping)")
-DEFINE_BOOL(harmony_proxies, false, "enable harmony proxies")
-DEFINE_BOOL(harmony_numeric_literals, false,
-            "enable harmony numeric literals (0o77, 0b11)")
-DEFINE_BOOL(harmony_strings, false, "enable harmony string")
-DEFINE_BOOL(harmony_arrays, false, "enable harmony arrays")
-DEFINE_BOOL(harmony_arrow_functions, false, "enable harmony arrow functions")
-DEFINE_BOOL(harmony_classes, false, "enable harmony classes")
-DEFINE_BOOL(harmony_object_literals, false,
-            "enable harmony object literal extensions")
-DEFINE_BOOL(harmony_regexps, false, "enable regexp-related harmony features")
-DEFINE_BOOL(harmony, false, "enable all harmony features (except proxies)")
+DEFINE_BOOL(es_staging, false, "enable all completed harmony features")
+DEFINE_BOOL(harmony, false, "enable all completed harmony features")
+DEFINE_BOOL(harmony_shipping, true, "enable all shipped harmony fetaures")
+DEFINE_IMPLICATION(harmony, es_staging)
+DEFINE_IMPLICATION(es_staging, harmony)
 
-DEFINE_IMPLICATION(harmony, harmony_scoping)
-DEFINE_IMPLICATION(harmony, harmony_modules)
-// TODO(rossberg): Reenable when problems are sorted out.
-// DEFINE_IMPLICATION(harmony, harmony_proxies)
-DEFINE_IMPLICATION(harmony, harmony_numeric_literals)
-DEFINE_IMPLICATION(harmony, harmony_strings)
-DEFINE_IMPLICATION(harmony, harmony_arrays)
-DEFINE_IMPLICATION(harmony, harmony_arrow_functions)
-DEFINE_IMPLICATION(harmony, harmony_classes)
-DEFINE_IMPLICATION(harmony, harmony_object_literals)
-DEFINE_IMPLICATION(harmony, harmony_regexps)
+// Features that are still work in progress (behind individual flags).
+#define HARMONY_INPROGRESS(V)                                             \
+  V(harmony_modules, "harmony modules (implies block scoping)")           \
+  V(harmony_arrays, "harmony array methods")                              \
+  V(harmony_array_includes, "harmony Array.prototype.includes")           \
+  V(harmony_regexps, "harmony regular expression extensions")             \
+  V(harmony_arrow_functions, "harmony arrow functions")                   \
+  V(harmony_proxies, "harmony proxies")                                   \
+  V(harmony_sloppy, "harmony features in sloppy mode")                    \
+  V(harmony_unicode, "harmony unicode escapes")
+
+// Features that are complete (but still behind --harmony/es-staging flag).
+#define HARMONY_STAGED(V)                                                 \
+  V(harmony_tostring, "harmony toString")                                 \
+  V(harmony_classes,                                                      \
+    "harmony classes (implies block scoping & object literal extension)") \
+  V(harmony_object_literals, "harmony object literal extensions")
+
+// Features that are shipping (turned on by default, but internal flag remains).
+#define HARMONY_SHIPPING(V)                                               \
+  V(harmony_numeric_literals, "harmony numeric literals")                 \
+  V(harmony_strings, "harmony string methods")                            \
+  V(harmony_scoping, "harmony block scoping")                             \
+  V(harmony_templates, "harmony template literals")
+
+// Once a shipping feature has proved stable in the wild, it will be dropped
+// from HARMONY_SHIPPING, all occurrences of the FLAG_ variable are removed,
+// and associated tests are moved from the harmony directory to the appropriate
+// esN directory.
+
+
+#define FLAG_INPROGRESS_FEATURES(id, description) \
+  DEFINE_BOOL(id, false, "enable " #description " (in progress)")
+HARMONY_INPROGRESS(FLAG_INPROGRESS_FEATURES)
+#undef FLAG_INPROGRESS_FEATURES
+
+#define FLAG_STAGED_FEATURES(id, description) \
+  DEFINE_BOOL(id, false, "enable " #description) \
+  DEFINE_IMPLICATION(es_staging, id)
+HARMONY_STAGED(FLAG_STAGED_FEATURES)
+#undef FLAG_STAGED_FEATURES
+
+#define FLAG_SHIPPING_FEATURES(id, description) \
+  DEFINE_BOOL(id, true, "enable " #description) \
+  DEFINE_NEG_NEG_IMPLICATION(harmony_shipping, id)
+HARMONY_SHIPPING(FLAG_SHIPPING_FEATURES)
+#undef FLAG_SHIPPING_FEATURES
+
+
+// Feature dependencies.
 DEFINE_IMPLICATION(harmony_modules, harmony_scoping)
 DEFINE_IMPLICATION(harmony_classes, harmony_scoping)
 DEFINE_IMPLICATION(harmony_classes, harmony_object_literals)
 
-DEFINE_IMPLICATION(harmony, es_staging)
 
 // Flags for experimental implementation features.
 DEFINE_BOOL(compiled_keyed_generic_loads, false,
             "use optimizing compiler to generate keyed generic load stubs")
-DEFINE_BOOL(clever_optimizations, true,
-            "Optimize object size, Array shift, DOM strings and string +")
 // TODO(hpayer): We will remove this flag as soon as we have pretenuring
 // support for specific allocation sites.
 DEFINE_BOOL(pretenuring_call_new, false, "pretenure call new")
@@ -307,12 +350,13 @@
            "maximum number of escape analysis fix-point iterations")
 
 DEFINE_BOOL(optimize_for_in, true, "optimize functions containing for-in loops")
-DEFINE_BOOL(opt_safe_uint32_operations, true,
-            "allow uint32 values on optimize frames if they are used only in "
-            "safe operations")
 
 DEFINE_BOOL(concurrent_recompilation, true,
             "optimizing hot functions asynchronously on a separate thread")
+DEFINE_BOOL(job_based_recompilation, false,
+            "post tasks to v8::Platform instead of using a thread for "
+            "concurrent recompilation")
+DEFINE_IMPLICATION(job_based_recompilation, concurrent_recompilation)
 DEFINE_BOOL(trace_concurrent_recompilation, false,
             "track concurrent recompilation")
 DEFINE_INT(concurrent_recompilation_queue_length, 8,
@@ -331,24 +375,39 @@
 // Flags for TurboFan.
 DEFINE_STRING(turbo_filter, "~", "optimization filter for TurboFan compiler")
 DEFINE_BOOL(trace_turbo, false, "trace generated TurboFan IR")
-DEFINE_BOOL(trace_turbo_types, true, "trace generated TurboFan types")
-DEFINE_BOOL(trace_turbo_scheduler, false, "trace generated TurboFan scheduler")
-DEFINE_BOOL(turbo_asm, false, "enable TurboFan for asm.js code")
+DEFINE_BOOL(trace_turbo_graph, false, "trace generated TurboFan graphs")
+DEFINE_IMPLICATION(trace_turbo_graph, trace_turbo)
+DEFINE_STRING(trace_turbo_cfg_file, NULL,
+              "trace turbo cfg graph (for C1 visualizer) to a given file name")
+DEFINE_BOOL(trace_turbo_types, true, "trace TurboFan's types")
+DEFINE_BOOL(trace_turbo_scheduler, false, "trace TurboFan's scheduler")
+DEFINE_BOOL(trace_turbo_reduction, false, "trace TurboFan's various reducers")
+DEFINE_BOOL(trace_turbo_jt, false, "trace TurboFan's jump threading")
+DEFINE_BOOL(turbo_asm, true, "enable TurboFan for asm.js code")
 DEFINE_BOOL(turbo_verify, false, "verify TurboFan graphs at each phase")
 DEFINE_BOOL(turbo_stats, false, "print TurboFan statistics")
-#if V8_TURBOFAN_BACKEND
 DEFINE_BOOL(turbo_types, true, "use typed lowering in TurboFan")
-#else
-DEFINE_BOOL(turbo_types, false, "use typed lowering in TurboFan")
-#endif
 DEFINE_BOOL(turbo_source_positions, false,
             "track source code positions when building TurboFan IR")
 DEFINE_BOOL(context_specialization, false,
             "enable context specialization in TurboFan")
 DEFINE_BOOL(turbo_deoptimization, false, "enable deoptimization in TurboFan")
 DEFINE_BOOL(turbo_inlining, false, "enable inlining in TurboFan")
+DEFINE_BOOL(turbo_inlining_intrinsics, false,
+            "enable inlining of intrinsics in TurboFan")
 DEFINE_BOOL(trace_turbo_inlining, false, "trace TurboFan inlining")
+DEFINE_BOOL(loop_assignment_analysis, true, "perform loop assignment analysis")
+DEFINE_IMPLICATION(turbo_inlining_intrinsics, turbo_inlining)
 DEFINE_IMPLICATION(turbo_inlining, turbo_types)
+DEFINE_BOOL(turbo_profiling, false, "enable profiling in TurboFan")
+// TODO(dcarney): this is just for experimentation, remove when default.
+DEFINE_BOOL(turbo_reuse_spill_slots, true, "reuse spill slots in TurboFan")
+// TODO(dcarney): this is just for experimentation, remove when default.
+DEFINE_BOOL(turbo_delay_ssa_decon, false,
+            "delay ssa deconstruction in TurboFan register allocator")
+// TODO(dcarney): this is just for debugging, remove eventually.
+DEFINE_BOOL(turbo_move_optimization, true, "optimize gap moves in TurboFan")
+DEFINE_BOOL(turbo_jt, true, "enable jump threading")
 
 DEFINE_INT(typed_array_max_size_in_heap, 64,
            "threshold for in-heap typed array")
@@ -375,10 +434,14 @@
             "enable use of SSE4.1 instructions if available")
 DEFINE_BOOL(enable_sahf, true,
             "enable use of SAHF instruction if available (X64 only)")
+DEFINE_BOOL(enable_avx, true, "enable use of AVX instructions if available")
+DEFINE_BOOL(enable_fma3, true, "enable use of FMA3 instructions if available")
 DEFINE_BOOL(enable_vfp3, ENABLE_VFP3_DEFAULT,
             "enable use of VFP3 instructions if available")
 DEFINE_BOOL(enable_armv7, ENABLE_ARMV7_DEFAULT,
             "enable use of ARMv7 instructions if available (ARM only)")
+DEFINE_BOOL(enable_armv8, ENABLE_ARMV8_DEFAULT,
+            "enable use of ARMv8 instructions if available (ARM 32-bit only)")
 DEFINE_BOOL(enable_neon, ENABLE_NEON_DEFAULT,
             "enable use of NEON instructions if available (ARM only)")
 DEFINE_BOOL(enable_sudiv, true,
@@ -397,11 +460,6 @@
 DEFINE_BOOL(force_long_branches, false,
             "force all emitted branches to be in long mode (MIPS only)")
 
-// cpu-arm64.cc
-DEFINE_BOOL(enable_always_align_csp, true,
-            "enable alignment of csp to 16 bytes on platforms which prefer "
-            "the register to always be aligned (ARM64 only)")
-
 // bootstrapper.cc
 DEFINE_STRING(expose_natives_as, NULL, "expose natives in global object")
 DEFINE_STRING(expose_debug_as, NULL, "expose debug in global object")
@@ -440,8 +498,9 @@
 DEFINE_BOOL(trace_stub_failures, false,
             "trace deoptimization of generated code stubs")
 
-DEFINE_BOOL(serialize_toplevel, false, "enable caching of toplevel scripts")
-DEFINE_BOOL(trace_code_serializer, false, "trace code serializer")
+DEFINE_BOOL(serialize_toplevel, true, "enable caching of toplevel scripts")
+DEFINE_BOOL(serialize_inner, true, "enable caching of inner functions")
+DEFINE_BOOL(trace_serializer, false, "print code serializer trace")
 
 // compiler.cc
 DEFINE_INT(min_preparse_length, 1024,
@@ -487,10 +546,17 @@
 DEFINE_INT(min_semi_space_size, 0,
            "min size of a semi-space (in MBytes), the new space consists of two"
            "semi-spaces")
+DEFINE_INT(target_semi_space_size, 0,
+           "target size of a semi-space (in MBytes) before triggering a GC")
 DEFINE_INT(max_semi_space_size, 0,
            "max size of a semi-space (in MBytes), the new space consists of two"
            "semi-spaces")
+DEFINE_INT(semi_space_growth_factor, 2, "factor by which to grow the new space")
+DEFINE_BOOL(experimental_new_space_growth_heuristic, false,
+            "Grow the new space based on the percentage of survivors instead "
+            "of their absolute value.")
 DEFINE_INT(max_old_space_size, 0, "max size of the old space (in Mbytes)")
+DEFINE_INT(initial_old_space_size, 0, "initial old space size (in Mbytes)")
 DEFINE_INT(max_executable_size, 0, "max size of executable memory (in Mbytes)")
 DEFINE_BOOL(gc_global, false, "always perform global GCs")
 DEFINE_INT(gc_interval, -1, "garbage collect after <n> allocations")
@@ -503,6 +569,8 @@
             "do not print trace line after scavenger collection")
 DEFINE_BOOL(trace_idle_notification, false,
             "print one trace line following each idle notification")
+DEFINE_BOOL(trace_idle_notification_verbose, false,
+            "prints the heap state used by the idle notification")
 DEFINE_BOOL(print_cumulative_gc_stat, false,
             "print cumulative GC statistics in name=value format on exit")
 DEFINE_BOOL(print_max_heap_committed, false,
@@ -514,8 +582,6 @@
             "report fragmentation for old pointer and data pages")
 DEFINE_BOOL(collect_maps, true,
             "garbage collect maps from which no objects can be reached")
-DEFINE_BOOL(weak_embedded_maps_in_ic, true,
-            "make maps embedded in inline cache stubs")
 DEFINE_BOOL(weak_embedded_maps_in_optimized_code, true,
             "make maps embedded in optimized code weak")
 DEFINE_BOOL(weak_embedded_objects_in_optimized_code, true,
@@ -530,15 +596,11 @@
             "old code (required for code flushing)")
 DEFINE_BOOL(incremental_marking, true, "use incremental marking")
 DEFINE_BOOL(incremental_marking_steps, true, "do incremental marking steps")
+DEFINE_BOOL(concurrent_sweeping, true, "use concurrent sweeping")
 DEFINE_BOOL(trace_incremental_marking, false,
             "trace progress of the incremental marking")
 DEFINE_BOOL(track_gc_object_stats, false,
             "track object counts and memory usage")
-DEFINE_BOOL(parallel_sweeping, false, "enable parallel sweeping")
-DEFINE_BOOL(concurrent_sweeping, true, "enable concurrent sweeping")
-DEFINE_INT(sweeper_threads, 0,
-           "number of parallel and concurrent sweeping threads")
-DEFINE_BOOL(job_based_sweeping, true, "enable job based sweeping")
 #ifdef VERIFY_HEAP
 DEFINE_BOOL(verify_heap, false, "verify heap pointers before and after GC")
 #endif
@@ -581,7 +643,13 @@
            "(0, the default, means to use system random).")
 
 // objects.cc
+DEFINE_BOOL(trace_weak_arrays, false, "trace WeakFixedArray usage")
+DEFINE_BOOL(track_prototype_users, false,
+            "keep track of which maps refer to a given prototype object")
 DEFINE_BOOL(use_verbose_printer, true, "allows verbose printing")
+#if TRACE_MAPS
+DEFINE_BOOL(trace_maps, false, "trace map creation")
+#endif
 
 // parser.cc
 DEFINE_BOOL(allow_natives_syntax, false, "allow natives syntax")
@@ -647,18 +715,8 @@
 #endif
 
 // mksnapshot.cc
-DEFINE_STRING(extra_code, NULL,
-              "A filename with extra code to be included in"
-              " the snapshot (mksnapshot only)")
-DEFINE_STRING(raw_file, NULL,
-              "A file to write the raw snapshot bytes to. "
-              "(mksnapshot only)")
-DEFINE_STRING(raw_context_file, NULL,
-              "A file to write the raw context "
-              "snapshot bytes to. (mksnapshot only)")
 DEFINE_STRING(startup_blob, NULL,
-              "Write V8 startup blob file. "
-              "(mksnapshot only)")
+              "Write V8 startup blob file. (mksnapshot only)")
 
 // code-stubs-hydrogen.cc
 DEFINE_BOOL(profile_hydrogen_code_stub_compilation, false,
@@ -668,7 +726,6 @@
 DEFINE_NEG_IMPLICATION(predictable, concurrent_recompilation)
 DEFINE_NEG_IMPLICATION(predictable, concurrent_osr)
 DEFINE_NEG_IMPLICATION(predictable, concurrent_sweeping)
-DEFINE_NEG_IMPLICATION(predictable, parallel_sweeping)
 
 
 //
@@ -739,8 +796,6 @@
 DEFINE_BOOL(gc_verbose, false, "print stuff during garbage collection")
 DEFINE_BOOL(heap_stats, false, "report heap statistics before and after GC")
 DEFINE_BOOL(code_stats, false, "report code statistics after GC")
-DEFINE_BOOL(verify_native_context_separation, false,
-            "verify that code holds on to at most one native context after GC")
 DEFINE_BOOL(print_handles, false, "report handles after GC")
 DEFINE_BOOL(print_global_handles, false, "report global handles after GC")
 
@@ -911,10 +966,15 @@
 #undef FLAG
 #define FLAG FLAG_READONLY
 
-// assembler-arm.h
+// assembler.h
 DEFINE_BOOL(enable_ool_constant_pool, V8_OOL_CONSTANT_POOL,
             "enable use of out-of-line constant pools (ARM only)")
 
+DEFINE_BOOL(unbox_double_fields, V8_DOUBLE_FIELDS_UNBOXING,
+            "enable in-object double fields unboxing (64-bit only)")
+DEFINE_IMPLICATION(unbox_double_fields, track_double_fields)
+
+
 // Cleanup...
 #undef FLAG_FULL
 #undef FLAG_READONLY
@@ -929,6 +989,7 @@
 #undef DEFINE_ARGS
 #undef DEFINE_IMPLICATION
 #undef DEFINE_NEG_IMPLICATION
+#undef DEFINE_NEG_VALUE_IMPLICATION
 #undef DEFINE_VALUE_IMPLICATION
 #undef DEFINE_ALIAS_BOOL
 #undef DEFINE_ALIAS_INT
diff --git a/src/flags.cc b/src/flags.cc
index 98f21ef..5e33bda 100644
--- a/src/flags.cc
+++ b/src/flags.cc
@@ -2,12 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <ctype.h>
-#include <stdlib.h>
+#include <cctype>
+#include <cstdlib>
+#include <sstream>
 
 #include "src/v8.h"
 
 #include "src/assembler.h"
+#include "src/base/functional.h"
 #include "src/base/platform/platform.h"
 #include "src/ostreams.h"
 
@@ -181,7 +183,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const Flag& flag) {  // NOLINT
+std::ostream& operator<<(std::ostream& os, const Flag& flag) {  // NOLINT
   switch (flag.type()) {
     case Flag::TYPE_BOOL:
       os << (*flag.bool_variable() ? "true" : "false");
@@ -231,21 +233,21 @@
       }
       {
         bool disabled = f->type() == Flag::TYPE_BOOL && !*f->bool_variable();
-        OStringStream os;
+        std::ostringstream os;
         os << (disabled ? "--no" : "--") << f->name();
-        args->Add(StrDup(os.c_str()));
+        args->Add(StrDup(os.str().c_str()));
       }
       if (f->type() != Flag::TYPE_BOOL) {
-        OStringStream os;
+        std::ostringstream os;
         os << *f;
-        args->Add(StrDup(os.c_str()));
+        args->Add(StrDup(os.str().c_str()));
       }
     }
   }
   if (args_flag != NULL) {
-    OStringStream os;
+    std::ostringstream os;
     os << "--" << args_flag->name();
-    args->Add(StrDup(os.c_str()));
+    args->Add(StrDup(os.str().c_str()));
     JSArguments jsargs = *args_flag->args_variable();
     for (int j = 0; j < jsargs.argc; j++) {
       args->Add(StrDup(jsargs[j]));
@@ -548,4 +550,18 @@
 #undef FLAG_MODE_DEFINE_IMPLICATIONS
 }
 
+
+uint32_t FlagList::Hash() {
+  std::ostringstream modified_args_as_string;
+  for (size_t i = 0; i < num_flags; ++i) {
+    Flag* current = &flags[i];
+    if (!current->IsDefault()) {
+      modified_args_as_string << i;
+      modified_args_as_string << *current;
+    }
+  }
+  std::string args(modified_args_as_string.str());
+  return static_cast<uint32_t>(
+      base::hash_range(args.c_str(), args.c_str() + args.length()));
+}
 } }  // namespace v8::internal
diff --git a/src/flags.h b/src/flags.h
index 78522ff..9ec5d30 100644
--- a/src/flags.h
+++ b/src/flags.h
@@ -57,6 +57,9 @@
 
   // Set flags as consequence of being implied by another flag.
   static void EnforceFlagImplications();
+
+  // Hash of current flags (to quickly determine flag changes).
+  static uint32_t Hash();
 };
 
 } }  // namespace v8::internal
diff --git a/src/frames-inl.h b/src/frames-inl.h
index 9241a44..d7f2f75 100644
--- a/src/frames-inl.h
+++ b/src/frames-inl.h
@@ -76,13 +76,13 @@
 
 
 inline StackHandler::Kind StackHandler::kind() const {
-  const int offset = StackHandlerConstants::kStateOffset;
+  const int offset = StackHandlerConstants::kStateIntOffset;
   return KindField::decode(Memory::unsigned_at(address() + offset));
 }
 
 
 inline unsigned StackHandler::index() const {
-  const int offset = StackHandlerConstants::kStateOffset;
+  const int offset = StackHandlerConstants::kStateIntOffset;
   return IndexField::decode(Memory::unsigned_at(address() + offset));
 }
 
diff --git a/src/frames.cc b/src/frames.cc
index f116fd2..0ba8ea0 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -2,6 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "src/frames.h"
+
+#include <sstream>
+
 #include "src/v8.h"
 
 #include "src/ast.h"
@@ -1288,12 +1292,12 @@
 
   // Print details about the function.
   if (FLAG_max_stack_trace_source_length != 0 && code != NULL) {
-    OStringStream os;
+    std::ostringstream os;
     SharedFunctionInfo* shared = function->shared();
     os << "--------- s o u r c e   c o d e ---------\n"
        << SourceCodeOf(shared, FLAG_max_stack_trace_source_length)
        << "\n-----------------------------------------\n";
-    accumulator->Add(os.c_str());
+    accumulator->Add(os.str().c_str());
   }
 
   accumulator->Add("}\n\n");
diff --git a/src/frames.h b/src/frames.h
index f7e60ae..03d53dd 100644
--- a/src/frames.h
+++ b/src/frames.h
@@ -71,6 +71,11 @@
   static const int kNextOffset     = 0 * kPointerSize;
   static const int kCodeOffset     = 1 * kPointerSize;
   static const int kStateOffset    = 2 * kPointerSize;
+#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
+  static const int kStateIntOffset = kStateOffset;
+#else
+  static const int kStateIntOffset = kStateOffset + kIntSize;
+#endif
   static const int kContextOffset  = 3 * kPointerSize;
   static const int kFPOffset       = 4 * kPointerSize;
 
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index 35d51d9..cb8f4aa 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -4,6 +4,8 @@
 
 #include "src/v8.h"
 
+#include "src/ast.h"
+#include "src/ast-numbering.h"
 #include "src/code-factory.h"
 #include "src/codegen.h"
 #include "src/compiler.h"
@@ -134,21 +136,19 @@
 
 
 void BreakableStatementChecker::VisitForStatement(ForStatement* stmt) {
-  // Mark for statements breakable if the condition expression is.
-  if (stmt->cond() != NULL) {
-    Visit(stmt->cond());
-  }
+  // We set positions for both init and condition, if they exist.
+  if (stmt->cond() != NULL || stmt->init() != NULL) is_breakable_ = true;
 }
 
 
 void BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) {
-  // Mark for in statements breakable if the enumerable expression is.
-  Visit(stmt->enumerable());
+  // For-in is breakable because we set the position for the enumerable.
+  is_breakable_ = true;
 }
 
 
 void BreakableStatementChecker::VisitForOfStatement(ForOfStatement* stmt) {
-  // For-of is breakable because of the next() call.
+  // For-of is breakable because we set the position for the next() call.
   is_breakable_ = true;
 }
 
@@ -306,6 +306,9 @@
 
   TimerEventScope<TimerEventCompileFullCode> timer(info->isolate());
 
+  // Ensure that the feedback vector is large enough.
+  info->EnsureFeedbackVector();
+
   Handle<Script> script = info->script();
   if (!script->IsUndefined() && !script->source()->IsUndefined()) {
     int len = String::cast(script->source())->length();
@@ -335,6 +338,7 @@
   cgen.PopulateDeoptimizationData(code);
   cgen.PopulateTypeFeedbackInfo(code);
   code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
+  code->set_has_reloc_info_for_serialization(info->will_serialize());
   code->set_handler_table(*cgen.handler_table());
   code->set_compiled_optimizable(info->IsOptimizable());
   code->set_allow_osr_at_loop_nesting_level(0);
@@ -344,6 +348,11 @@
   info->SetCode(code);
   void* line_info = masm.positions_recorder()->DetachJITHandlerData();
   LOG_CODE_EVENT(isolate, CodeEndLinePosInfoRecordEvent(*code, line_info));
+
+#ifdef DEBUG
+  // Check that no context-specific object has been embedded.
+  code->VerifyEmbeddedObjectsInFullCode();
+#endif  // DEBUG
   return true;
 }
 
@@ -365,12 +374,24 @@
 }
 
 
-void FullCodeGenerator::EnsureSlotContainsAllocationSite(int slot) {
-  Handle<FixedArray> vector = FeedbackVector();
-  if (!vector->get(slot)->IsAllocationSite()) {
+void FullCodeGenerator::EnsureSlotContainsAllocationSite(
+    FeedbackVectorSlot slot) {
+  Handle<TypeFeedbackVector> vector = FeedbackVector();
+  if (!vector->Get(slot)->IsAllocationSite()) {
     Handle<AllocationSite> allocation_site =
         isolate()->factory()->NewAllocationSite();
-    vector->set(slot, *allocation_site);
+    vector->Set(slot, *allocation_site);
+  }
+}
+
+
+void FullCodeGenerator::EnsureSlotContainsAllocationSite(
+    FeedbackVectorICSlot slot) {
+  Handle<TypeFeedbackVector> vector = FeedbackVector();
+  if (!vector->Get(slot)->IsAllocationSite()) {
+    Handle<AllocationSite> allocation_site =
+        isolate()->factory()->NewAllocationSite();
+    vector->Set(slot, *allocation_site);
   }
 }
 
@@ -584,7 +605,7 @@
 
 
 void FullCodeGenerator::AllocateModules(ZoneList<Declaration*>* declarations) {
-  DCHECK(scope_->is_global_scope());
+  DCHECK(scope_->is_script_scope());
 
   for (int i = 0; i < declarations->length(); i++) {
     ModuleDeclaration* declaration = declarations->at(i)->AsModuleDeclaration();
@@ -625,8 +646,8 @@
 // modules themselves, however, are simple data properties.)
 //
 // All modules have a _hosting_ scope/context, which (currently) is the
-// (innermost) enclosing global scope. To deal with recursion, nested modules
-// are hosted by the same scope as global ones.
+// enclosing script scope. To deal with recursion, nested modules are hosted
+// by the same scope as global ones.
 //
 // For every (global or nested) module literal, the hosting context has an
 // internal slot that points directly to the respective module context. This
@@ -656,7 +677,7 @@
 //
 // To deal with arbitrary recursion and aliases between modules,
 // they are created and initialized in several stages. Each stage applies to
-// all modules in the hosting global scope, including nested ones.
+// all modules in the hosting script scope, including nested ones.
 //
 // 1. Allocate: for each module _literal_, allocate the module contexts and
 //    respective instance object and wire them up. This happens in the
@@ -691,7 +712,7 @@
     // This is a scope hosting modules. Allocate a descriptor array to pass
     // to the runtime for initialization.
     Comment cmnt(masm_, "[ Allocate modules");
-    DCHECK(scope_->is_global_scope());
+    DCHECK(scope_->is_script_scope());
     modules_ =
         isolate()->factory()->NewFixedArray(scope_->num_modules(), TENURED);
     module_index_ = 0;
@@ -1053,41 +1074,12 @@
   NestedBlock nested_block(this, stmt);
   SetStatementPosition(stmt);
 
-  Scope* saved_scope = scope();
-  // Push a block context when entering a block with block scoped variables.
-  if (stmt->scope() == NULL) {
-    PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
-  } else {
-    scope_ = stmt->scope();
-    DCHECK(!scope_->is_module_scope());
-    { Comment cmnt(masm_, "[ Extend block context");
-      __ Push(scope_->GetScopeInfo());
-      PushFunctionArgumentForContextAllocation();
-      __ CallRuntime(Runtime::kPushBlockContext, 2);
-
-      // Replace the context stored in the frame.
-      StoreToFrameField(StandardFrameConstants::kContextOffset,
-                        context_register());
-      PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
-    }
-    { Comment cmnt(masm_, "[ Declarations");
-      VisitDeclarations(scope_->declarations());
-      PrepareForBailoutForId(stmt->DeclsId(), NO_REGISTERS);
-    }
+  {
+    EnterBlockScopeIfNeeded block_scope_state(
+        this, stmt->scope(), stmt->EntryId(), stmt->DeclsId(), stmt->ExitId());
+    VisitStatements(stmt->statements());
+    __ bind(nested_block.break_label());
   }
-
-  VisitStatements(stmt->statements());
-  scope_ = saved_scope;
-  __ bind(nested_block.break_label());
-
-  // Pop block context if necessary.
-  if (stmt->scope() != NULL) {
-    LoadContextField(context_register(), Context::PREVIOUS_INDEX);
-    // Update local stack frame context field.
-    StoreToFrameField(StandardFrameConstants::kContextOffset,
-                      context_register());
-  }
-  PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
 }
 
 
@@ -1326,6 +1318,7 @@
   SetStatementPosition(stmt);
 
   if (stmt->init() != NULL) {
+    SetStatementPosition(stmt->init());
     Visit(stmt->init());
   }
 
@@ -1340,6 +1333,7 @@
   PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS);
   __ bind(loop_statement.continue_label());
   if (stmt->next() != NULL) {
+    SetStatementPosition(stmt->next());
     Visit(stmt->next());
   }
 
@@ -1352,6 +1346,7 @@
 
   __ bind(&test);
   if (stmt->cond() != NULL) {
+    SetExpressionPosition(stmt->cond());
     VisitForControl(stmt->cond(),
                     &body,
                     loop_statement.break_label(),
@@ -1366,6 +1361,47 @@
 }
 
 
+void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
+  Comment cmnt(masm_, "[ ForOfStatement");
+  SetStatementPosition(stmt);
+
+  Iteration loop_statement(this, stmt);
+  increment_loop_depth();
+
+  // var iterator = iterable[Symbol.iterator]();
+  VisitForEffect(stmt->assign_iterator());
+
+  // Loop entry.
+  __ bind(loop_statement.continue_label());
+
+  // result = iterator.next()
+  SetExpressionPosition(stmt->next_result());
+  VisitForEffect(stmt->next_result());
+
+  // if (result.done) break;
+  Label result_not_done;
+  VisitForControl(stmt->result_done(), loop_statement.break_label(),
+                  &result_not_done, &result_not_done);
+  __ bind(&result_not_done);
+
+  // each = result.value
+  VisitForEffect(stmt->assign_each());
+
+  // Generate code for the body of the loop.
+  Visit(stmt->body());
+
+  // Check stack before looping.
+  PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
+  EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
+  __ jmp(loop_statement.continue_label());
+
+  // Exit and decrement the loop depth.
+  PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
+  __ bind(loop_statement.break_label());
+  decrement_loop_depth();
+}
+
+
 void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) {
   Comment cmnt(masm_, "[ TryCatchStatement");
   SetStatementPosition(stmt);
@@ -1541,13 +1577,43 @@
 }
 
 
-void FullCodeGenerator::VisitClassLiteral(ClassLiteral* expr) {
-  // TODO(arv): Implement
+void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
   Comment cmnt(masm_, "[ ClassLiteral");
-  if (expr->extends() != NULL) {
-    VisitForEffect(expr->extends());
+
+  {
+    EnterBlockScopeIfNeeded block_scope_state(
+        this, lit->scope(), BailoutId::None(), BailoutId::None(),
+        BailoutId::None());
+
+    if (lit->raw_name() != NULL) {
+      __ Push(lit->name());
+    } else {
+      __ Push(isolate()->factory()->undefined_value());
+    }
+
+    if (lit->extends() != NULL) {
+      VisitForStackValue(lit->extends());
+    } else {
+      __ Push(isolate()->factory()->the_hole_value());
+    }
+
+    VisitForStackValue(lit->constructor());
+
+    __ Push(script());
+    __ Push(Smi::FromInt(lit->start_position()));
+    __ Push(Smi::FromInt(lit->end_position()));
+
+    __ CallRuntime(Runtime::kDefineClass, 6);
+    EmitClassDefineProperties(lit);
+
+    if (lit->scope() != NULL) {
+      DCHECK_NOT_NULL(lit->class_variable_proxy());
+      EmitVariableAssignment(lit->class_variable_proxy()->var(),
+                             Token::INIT_CONST);
+    }
   }
-  context()->Plug(isolate()->factory()->undefined_value());
+
+  context()->Plug(result_register());
 }
 
 
@@ -1713,6 +1779,49 @@
 #endif  // DEBUG
 
 
+FullCodeGenerator::EnterBlockScopeIfNeeded::EnterBlockScopeIfNeeded(
+    FullCodeGenerator* codegen, Scope* scope, BailoutId entry_id,
+    BailoutId declarations_id, BailoutId exit_id)
+    : codegen_(codegen), scope_(scope), exit_id_(exit_id) {
+  saved_scope_ = codegen_->scope();
+
+  if (scope == NULL) {
+    codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS);
+  } else {
+    codegen_->scope_ = scope;
+    {
+      Comment cmnt(masm(), "[ Extend block context");
+      __ Push(scope->GetScopeInfo());
+      codegen_->PushFunctionArgumentForContextAllocation();
+      __ CallRuntime(Runtime::kPushBlockContext, 2);
+
+      // Replace the context stored in the frame.
+      codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
+                                  codegen_->context_register());
+      codegen_->PrepareForBailoutForId(entry_id, NO_REGISTERS);
+    }
+    {
+      Comment cmnt(masm(), "[ Declarations");
+      codegen_->VisitDeclarations(scope->declarations());
+      codegen_->PrepareForBailoutForId(declarations_id, NO_REGISTERS);
+    }
+  }
+}
+
+
+FullCodeGenerator::EnterBlockScopeIfNeeded::~EnterBlockScopeIfNeeded() {
+  if (scope_ != NULL) {
+    codegen_->LoadContextField(codegen_->context_register(),
+                               Context::PREVIOUS_INDEX);
+    // Update local stack frame context field.
+    codegen_->StoreToFrameField(StandardFrameConstants::kContextOffset,
+                                codegen_->context_register());
+  }
+  codegen_->PrepareForBailoutForId(exit_id_, NO_REGISTERS);
+  codegen_->scope_ = saved_scope_;
+}
+
+
 #undef __
 
 
diff --git a/src/full-codegen.h b/src/full-codegen.h
index 71e1b60..1439942 100644
--- a/src/full-codegen.h
+++ b/src/full-codegen.h
@@ -10,10 +10,10 @@
 #include "src/allocation.h"
 #include "src/assert-scope.h"
 #include "src/ast.h"
+#include "src/bit-vector.h"
 #include "src/code-stubs.h"
 #include "src/codegen.h"
 #include "src/compiler.h"
-#include "src/data-flow.h"
 #include "src/globals.h"
 #include "src/objects.h"
 
@@ -40,7 +40,7 @@
 
  private:
   // AST node visit functions.
-#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
+#define DECLARE_VISIT(type) virtual void Visit##type(type* node) OVERRIDE;
   AST_NODE_LIST(DECLARE_VISIT)
 #undef DECLARE_VISIT
 
@@ -392,7 +392,7 @@
 
   void VisitInDuplicateContext(Expression* expr);
 
-  void VisitDeclarations(ZoneList<Declaration*>* declarations);
+  void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE;
   void DeclareModules(Handle<FixedArray> descriptions);
   void DeclareGlobals(Handle<FixedArray> pairs);
   int DeclareGlobalsFlags();
@@ -429,10 +429,21 @@
 
   // Feedback slot support. The feedback vector will be cleared during gc and
   // collected by the type-feedback oracle.
-  Handle<FixedArray> FeedbackVector() {
+  Handle<TypeFeedbackVector> FeedbackVector() const {
     return info_->feedback_vector();
   }
-  void EnsureSlotContainsAllocationSite(int slot);
+  void EnsureSlotContainsAllocationSite(FeedbackVectorSlot slot);
+  void EnsureSlotContainsAllocationSite(FeedbackVectorICSlot slot);
+
+  // Returns a smi for the index into the FixedArray that backs the feedback
+  // vector
+  Smi* SmiFromSlot(FeedbackVectorSlot slot) const {
+    return Smi::FromInt(FeedbackVector()->GetIndex(slot));
+  }
+
+  Smi* SmiFromSlot(FeedbackVectorICSlot slot) const {
+    return Smi::FromInt(FeedbackVector()->GetIndex(slot));
+  }
 
   // Record a call's return site offset, used to rebuild the frame if the
   // called function was inlined at the site.
@@ -479,6 +490,7 @@
   void EmitCallWithLoadIC(Call* expr);
   void EmitSuperCallWithLoadIC(Call* expr);
   void EmitKeyedCallWithLoadIC(Call* expr, Expression* key);
+  void EmitKeyedSuperCallWithLoadIC(Call* expr);
 
   // Platform-specific code for inline runtime calls.
   InlineFunctionGenerator FindInlineFunctionGenerator(Runtime::FunctionId id);
@@ -517,16 +529,45 @@
 
   // Platform-specific support for compiling assignments.
 
+  // Left-hand side can only be a property, a global or a (parameter or local)
+  // slot.
+  enum LhsKind {
+    VARIABLE,
+    NAMED_PROPERTY,
+    KEYED_PROPERTY,
+    NAMED_SUPER_PROPERTY,
+    KEYED_SUPER_PROPERTY
+  };
+
+  static LhsKind GetAssignType(Property* property) {
+    if (property == NULL) return VARIABLE;
+    bool super_access = property->IsSuperAccess();
+    return (property->key()->IsPropertyName())
+               ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
+               : (super_access ? KEYED_SUPER_PROPERTY : KEYED_PROPERTY);
+  }
+
   // Load a value from a named property.
   // The receiver is left on the stack by the IC.
   void EmitNamedPropertyLoad(Property* expr);
 
+  // Load a value from super.named property.
+  // Expect receiver ('this' value) and home_object on the stack.
   void EmitNamedSuperPropertyLoad(Property* expr);
 
+  // Load a value from super[keyed] property.
+  // Expect receiver ('this' value), home_object and key on the stack.
+  void EmitKeyedSuperPropertyLoad(Property* expr);
+
   // Load a value from a keyed property.
   // The receiver and the key is left on the stack by the IC.
   void EmitKeyedPropertyLoad(Property* expr);
 
+  // Adds the properties to the class (function) object and to its prototype.
+  // Expects the class (function) in the accumulator. The class (function) is
+  // in the accumulator after installing all the properties.
+  void EmitClassDefineProperties(ClassLiteral* lit);
+
   // Apply the compound assignment operator. Expects the left operand on top
   // of the stack and the right one in the accumulator.
   void EmitBinaryOp(BinaryOperation* expr,
@@ -545,6 +586,19 @@
   // is expected in the accumulator.
   void EmitAssignment(Expression* expr);
 
+  // Shall an error be thrown if assignment with 'op' operation is perfomed
+  // on this variable in given language mode?
+  static bool IsSignallingAssignmentToConst(Variable* var, Token::Value op,
+                                            StrictMode strict_mode) {
+    if (var->mode() == CONST) return op != Token::INIT_CONST;
+
+    if (var->mode() == CONST_LEGACY) {
+      return strict_mode == STRICT && op != Token::INIT_CONST_LEGACY;
+    }
+
+    return false;
+  }
+
   // Complete a variable assignment.  The right-hand-side value is expected
   // in the accumulator.
   void EmitVariableAssignment(Variable* var,
@@ -558,6 +612,14 @@
   // of the stack and the right-hand-side value in the accumulator.
   void EmitNamedPropertyAssignment(Assignment* expr);
 
+  // Complete a super named property assignment. The right-hand-side value
+  // is expected in accumulator.
+  void EmitNamedSuperPropertyStore(Property* prop);
+
+  // Complete a super named property assignment. The right-hand-side value
+  // is expected in accumulator.
+  void EmitKeyedSuperPropertyStore(Property* prop);
+
   // Complete a keyed property assignment.  The receiver and key are
   // expected on top of the stack and the right-hand-side value in the
   // accumulator.
@@ -565,6 +627,17 @@
 
   void EmitLoadHomeObject(SuperReference* expr);
 
+  static bool NeedsHomeObject(Expression* expr) {
+    return FunctionLiteral::NeedsHomeObject(expr);
+  }
+
+  // Adds the [[HomeObject]] to |initializer| if it is a FunctionLiteral.
+  // The value of the initializer is expected to be at the top of the stack.
+  // |offset| is the offset in the stack where the home object can be found.
+  void EmitSetHomeObjectIfNeeded(Expression* initializer, int offset);
+
+  void EmitLoadSuperConstructor(SuperReference* expr);
+
   void CallIC(Handle<Code> code,
               TypeFeedbackId id = TypeFeedbackId::None());
 
@@ -619,7 +692,7 @@
   void PushFunctionArgumentForContextAllocation();
 
   // AST node visit functions.
-#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
+#define DECLARE_VISIT(type) virtual void Visit##type(type* node) OVERRIDE;
   AST_NODE_LIST(DECLARE_VISIT)
 #undef DECLARE_VISIT
 
@@ -822,6 +895,22 @@
     virtual bool IsEffect() const { return true; }
   };
 
+  class EnterBlockScopeIfNeeded {
+   public:
+    EnterBlockScopeIfNeeded(FullCodeGenerator* codegen, Scope* scope,
+                            BailoutId entry_id, BailoutId declarations_id,
+                            BailoutId exit_id);
+    ~EnterBlockScopeIfNeeded();
+
+   private:
+    MacroAssembler* masm() const { return codegen_->masm(); }
+
+    FullCodeGenerator* codegen_;
+    Scope* scope_;
+    Scope* saved_scope_;
+    BailoutId exit_id_;
+  };
+
   MacroAssembler* masm_;
   CompilationInfo* info_;
   Scope* scope_;
diff --git a/src/gdb-jit.cc b/src/gdb-jit.cc
index 776c662..a19fb51 100644
--- a/src/gdb-jit.cc
+++ b/src/gdb-jit.cc
@@ -1842,7 +1842,7 @@
   void __gdb_print_v8_object(Object* object) {
     OFStream os(stdout);
     object->Print(os);
-    os << flush;
+    os << std::flush;
   }
 #endif
 }
diff --git a/src/generator.js b/src/generator.js
index 72e64dc..9ab7dcb 100644
--- a/src/generator.js
+++ b/src/generator.js
@@ -20,8 +20,23 @@
                         ['[Generator].prototype.next', this]);
   }
 
-  if (DEBUG_IS_ACTIVE) %DebugPrepareStepInIfStepping(this);
-  return %_GeneratorNext(this, value);
+  var continuation = %GeneratorGetContinuation(this);
+  if (continuation > 0) {
+    // Generator is suspended.
+    if (DEBUG_IS_ACTIVE) %DebugPrepareStepInIfStepping(this);
+    try {
+      return %_GeneratorNext(this, value);
+    } catch (e) {
+      %GeneratorClose(this);
+      throw e;
+    }
+  } else if (continuation == 0) {
+    // Generator is already closed.
+    return { value: void 0, done: true };
+  } else {
+    // Generator is running.
+    throw MakeTypeError('generator_running', []);
+  }
 }
 
 function GeneratorObjectThrow(exn) {
@@ -30,7 +45,22 @@
                         ['[Generator].prototype.throw', this]);
   }
 
-  return %_GeneratorThrow(this, exn);
+  var continuation = %GeneratorGetContinuation(this);
+  if (continuation > 0) {
+    // Generator is suspended.
+    try {
+      return %_GeneratorThrow(this, exn);
+    } catch (e) {
+      %GeneratorClose(this);
+      throw e;
+    }
+  } else if (continuation == 0) {
+    // Generator is already closed.
+    throw exn;
+  } else {
+    // Generator is running.
+    throw MakeTypeError('generator_running', []);
+  }
 }
 
 function GeneratorObjectIterator() {
@@ -44,13 +74,7 @@
 }
 
 function GeneratorFunctionConstructor(arg1) {  // length == 1
-  var source = NewFunctionString(arguments, 'function*');
-  var global_proxy = %GlobalProxy(global);
-  // Compile the string in the constructor and not a helper so that errors
-  // appear to come from here.
-  var f = %_CallFunction(global_proxy, %CompileString(source, true));
-  %FunctionMarkNameShouldPrintAsAnonymous(f);
-  return f;
+  return NewFunctionFromString(arguments, 'function*');
 }
 
 
@@ -73,11 +97,15 @@
   %AddNamedProperty(GeneratorObjectPrototype, symbolIterator,
       GeneratorObjectIterator, DONT_ENUM | DONT_DELETE | READ_ONLY);
   %AddNamedProperty(GeneratorObjectPrototype, "constructor",
-      GeneratorFunctionPrototype, DONT_ENUM | DONT_DELETE | READ_ONLY);
+      GeneratorFunctionPrototype, DONT_ENUM | READ_ONLY);
+  %AddNamedProperty(GeneratorObjectPrototype,
+      symbolToStringTag, "Generator", DONT_ENUM | READ_ONLY);
   %InternalSetPrototype(GeneratorFunctionPrototype, $Function.prototype);
+  %AddNamedProperty(GeneratorFunctionPrototype,
+      symbolToStringTag, "GeneratorFunction", DONT_ENUM | READ_ONLY);
   %SetCode(GeneratorFunctionPrototype, GeneratorFunctionPrototypeConstructor);
   %AddNamedProperty(GeneratorFunctionPrototype, "constructor",
-      GeneratorFunction, DONT_ENUM | DONT_DELETE | READ_ONLY);
+      GeneratorFunction, DONT_ENUM | READ_ONLY);
   %InternalSetPrototype(GeneratorFunction, $Function);
   %SetCode(GeneratorFunction, GeneratorFunctionConstructor);
 }
diff --git a/src/global-handles.cc b/src/global-handles.cc
index 282ca2d..4f744d6 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -30,10 +30,11 @@
   // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE }
   enum State {
     FREE = 0,
-    NORMAL,     // Normal global handle.
-    WEAK,       // Flagged as weak but not yet finalized.
-    PENDING,    // Has been recognized as only reachable by weak handles.
-    NEAR_DEATH  // Callback has informed the handle is near death.
+    NORMAL,      // Normal global handle.
+    WEAK,        // Flagged as weak but not yet finalized.
+    PENDING,     // Has been recognized as only reachable by weak handles.
+    NEAR_DEATH,  // Callback has informed the handle is near death.
+    NUMBER_OF_NODE_STATES
   };
 
   // Maps handle location (slot) to the containing node.
@@ -92,8 +93,14 @@
     IncreaseBlockUses();
   }
 
+  void Zap() {
+    DCHECK(IsInUse());
+    // Zap the values for eager trapping.
+    object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
+  }
+
   void Release() {
-    DCHECK(state() != FREE);
+    DCHECK(IsInUse());
     set_state(FREE);
     // Zap the values for eager trapping.
     object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
@@ -146,6 +153,13 @@
     flags_ = IsInNewSpaceList::update(flags_, v);
   }
 
+  WeaknessType weakness_type() const {
+    return NodeWeaknessType::decode(flags_);
+  }
+  void set_weakness_type(WeaknessType weakness_type) {
+    flags_ = NodeWeaknessType::update(flags_, weakness_type);
+  }
+
   bool IsNearDeath() const {
     // Check for PENDING to ensure correct answer when processing callbacks.
     return state() == PENDING || state() == NEAR_DEATH;
@@ -153,6 +167,8 @@
 
   bool IsWeak() const { return state() == WEAK; }
 
+  bool IsInUse() const { return state() != FREE; }
+
   bool IsRetainer() const { return state() != FREE; }
 
   bool IsStrongRetainer() const { return state() == NORMAL; }
@@ -168,12 +184,12 @@
 
   // Independent flag accessors.
   void MarkIndependent() {
-    DCHECK(state() != FREE);
+    DCHECK(IsInUse());
     set_independent(true);
   }
 
   void MarkPartiallyDependent() {
-    DCHECK(state() != FREE);
+    DCHECK(IsInUse());
     if (GetGlobalHandles()->isolate()->heap()->InNewSpace(object_)) {
       set_partially_dependent(true);
     }
@@ -186,14 +202,39 @@
 
   // Callback parameter accessors.
   void set_parameter(void* parameter) {
-    DCHECK(state() != FREE);
+    DCHECK(IsInUse());
+    DCHECK(weakness_type() == NORMAL_WEAK || weakness_type() == PHANTOM_WEAK);
     parameter_or_next_free_.parameter = parameter;
   }
   void* parameter() const {
-    DCHECK(state() != FREE);
+    DCHECK(IsInUse());
     return parameter_or_next_free_.parameter;
   }
 
+  void set_internal_fields(int internal_field_index1,
+                           int internal_field_index2) {
+    DCHECK(weakness_type() == INTERNAL_FIELDS_WEAK);
+    // These are stored in an int16_t.
+    DCHECK(internal_field_index1 < 1 << 16);
+    DCHECK(internal_field_index1 >= -(1 << 16));
+    DCHECK(internal_field_index2 < 1 << 16);
+    DCHECK(internal_field_index2 >= -(1 << 16));
+    parameter_or_next_free_.internal_field_indeces.internal_field1 =
+        static_cast<int16_t>(internal_field_index1);
+    parameter_or_next_free_.internal_field_indeces.internal_field2 =
+        static_cast<int16_t>(internal_field_index2);
+  }
+
+  int internal_field1() const {
+    DCHECK(weakness_type() == INTERNAL_FIELDS_WEAK);
+    return parameter_or_next_free_.internal_field_indeces.internal_field1;
+  }
+
+  int internal_field2() const {
+    DCHECK(weakness_type() == INTERNAL_FIELDS_WEAK);
+    return parameter_or_next_free_.internal_field_indeces.internal_field2;
+  }
+
   // Accessors for next free node in the free list.
   Node* next_free() {
     DCHECK(state() == FREE);
@@ -206,49 +247,126 @@
 
   void MakeWeak(void* parameter, WeakCallback weak_callback) {
     DCHECK(weak_callback != NULL);
-    DCHECK(state() != FREE);
+    DCHECK(IsInUse());
     CHECK(object_ != NULL);
     set_state(WEAK);
+    set_weakness_type(NORMAL_WEAK);
     set_parameter(parameter);
     weak_callback_ = weak_callback;
   }
 
+  void MakePhantom(void* parameter,
+                   PhantomCallbackData<void>::Callback phantom_callback,
+                   int16_t internal_field_index1,
+                   int16_t internal_field_index2) {
+    DCHECK(phantom_callback != NULL);
+    DCHECK(IsInUse());
+    CHECK(object_ != NULL);
+    set_state(WEAK);
+    if (parameter == NULL) {
+      set_weakness_type(INTERNAL_FIELDS_WEAK);
+      set_internal_fields(internal_field_index1, internal_field_index2);
+    } else {
+      DCHECK(internal_field_index1 == v8::Object::kNoInternalFieldIndex);
+      DCHECK(internal_field_index2 == v8::Object::kNoInternalFieldIndex);
+      set_weakness_type(PHANTOM_WEAK);
+      set_parameter(parameter);
+    }
+    weak_callback_ = reinterpret_cast<WeakCallback>(phantom_callback);
+  }
+
   void* ClearWeakness() {
-    DCHECK(state() != FREE);
+    DCHECK(IsInUse());
     void* p = parameter();
     set_state(NORMAL);
     set_parameter(NULL);
     return p;
   }
 
+  void CollectPhantomCallbackData(
+      Isolate* isolate, List<PendingPhantomCallback>* pending_phantom_callbacks,
+      List<PendingInternalFieldsCallback>* pending_internal_fields_callbacks) {
+    if (state() != Node::PENDING) return;
+    bool do_release = true;
+    if (weak_callback_ != NULL) {
+      if (weakness_type() == NORMAL_WEAK) return;
+
+      v8::Isolate* api_isolate = reinterpret_cast<v8::Isolate*>(isolate);
+
+      if (weakness_type() == PHANTOM_WEAK) {
+        // Phantom weak pointer case. Zap with harmless value.
+        DCHECK(*location() == Smi::FromInt(0));
+        typedef PhantomCallbackData<void> Data;
+
+        Data data(api_isolate, parameter());
+        Data::Callback callback =
+            reinterpret_cast<Data::Callback>(weak_callback_);
+
+        pending_phantom_callbacks->Add(
+            PendingPhantomCallback(this, data, callback));
+
+        // Postpone the release of the handle. The embedder can't use the
+        // handle (it's zapped), but it may be using the location, and we
+        // don't want to confuse things by reusing that.
+        do_release = false;
+      } else {
+        DCHECK(weakness_type() == INTERNAL_FIELDS_WEAK);
+        typedef InternalFieldsCallbackData<void, void> Data;
+
+        // Phantom weak pointer case, passing internal fields instead of
+        // parameter. Don't use a handle here during GC, because it will
+        // create a handle pointing to a dying object, which can confuse
+        // the next GC.
+        JSObject* jsobject = reinterpret_cast<JSObject*>(object());
+        DCHECK(jsobject->IsJSObject());
+        Data data(api_isolate, jsobject->GetInternalField(internal_field1()),
+                  jsobject->GetInternalField(internal_field2()));
+        Data::Callback callback =
+            reinterpret_cast<Data::Callback>(weak_callback_);
+
+        // In the future, we want to delay the callback. In that case we will
+        // zap when we queue up, to stop the C++ side accessing the dead V8
+        // object, but we will call Release only after the callback (allowing
+        // the node to be reused).
+        pending_internal_fields_callbacks->Add(
+            PendingInternalFieldsCallback(data, callback));
+      }
+    }
+    // TODO(erikcorry): At the moment the callbacks are not postponed much,
+    // but if we really postpone them until after the mutator has run, we
+    // need to divide things up, so that an early callback clears the handle,
+    // while a later one destroys the objects involved, possibley triggering
+    // some work when decremented ref counts hit zero.
+    if (do_release) Release();
+  }
+
   bool PostGarbageCollectionProcessing(Isolate* isolate) {
     if (state() != Node::PENDING) return false;
     if (weak_callback_ == NULL) {
       Release();
       return false;
     }
-    void* par = parameter();
     set_state(NEAR_DEATH);
-    set_parameter(NULL);
 
+    // Check that we are not passing a finalized external string to
+    // the callback.
+    DCHECK(!object_->IsExternalOneByteString() ||
+           ExternalOneByteString::cast(object_)->resource() != NULL);
+    DCHECK(!object_->IsExternalTwoByteString() ||
+           ExternalTwoByteString::cast(object_)->resource() != NULL);
+    // Leaving V8.
+    VMState<EXTERNAL> vmstate(isolate);
+    HandleScope handle_scope(isolate);
+    if (weakness_type() == PHANTOM_WEAK) return false;
+    DCHECK(weakness_type() == NORMAL_WEAK);
     Object** object = location();
-    {
-      // Check that we are not passing a finalized external string to
-      // the callback.
-      DCHECK(!object_->IsExternalOneByteString() ||
-             ExternalOneByteString::cast(object_)->resource() != NULL);
-      DCHECK(!object_->IsExternalTwoByteString() ||
-             ExternalTwoByteString::cast(object_)->resource() != NULL);
-      // Leaving V8.
-      VMState<EXTERNAL> state(isolate);
-      HandleScope handle_scope(isolate);
-      Handle<Object> handle(*object, isolate);
-      v8::WeakCallbackData<v8::Value, void> data(
-          reinterpret_cast<v8::Isolate*>(isolate),
-          v8::Utils::ToLocal(handle),
-          par);
-      weak_callback_(data);
-    }
+    Handle<Object> handle(*object, isolate);
+    v8::WeakCallbackData<v8::Value, void> data(
+        reinterpret_cast<v8::Isolate*>(isolate), parameter(),
+        v8::Utils::ToLocal(handle));
+    set_parameter(NULL);
+    weak_callback_(data);
+
     // Absence of explicit cleanup or revival of weak handle
     // in most of the cases would lead to memory leak.
     CHECK(state() != NEAR_DEATH);
@@ -277,10 +395,11 @@
 
   // This stores three flags (independent, partially_dependent and
   // in_new_space_list) and a State.
-  class NodeState:            public BitField<State, 0, 4> {};
-  class IsIndependent:        public BitField<bool,  4, 1> {};
-  class IsPartiallyDependent: public BitField<bool,  5, 1> {};
-  class IsInNewSpaceList:     public BitField<bool,  6, 1> {};
+  class NodeState : public BitField<State, 0, 3> {};
+  class IsIndependent : public BitField<bool, 3, 1> {};
+  class IsPartiallyDependent : public BitField<bool, 4, 1> {};
+  class IsInNewSpaceList : public BitField<bool, 5, 1> {};
+  class NodeWeaknessType : public BitField<WeaknessType, 6, 2> {};
 
   uint8_t flags_;
 
@@ -291,6 +410,10 @@
   // the free list link.
   union {
     void* parameter;
+    struct {
+      int16_t internal_field1;
+      int16_t internal_field2;
+    } internal_field_indeces;
     Node* next_free;
   } parameter_or_next_free_;
 
@@ -475,13 +598,42 @@
 }
 
 
-void GlobalHandles::MakeWeak(Object** location,
-                             void* parameter,
+void GlobalHandles::MakeWeak(Object** location, void* parameter,
                              WeakCallback weak_callback) {
   Node::FromLocation(location)->MakeWeak(parameter, weak_callback);
 }
 
 
+typedef PhantomCallbackData<void>::Callback GenericCallback;
+
+
+void GlobalHandles::MakePhantom(
+    Object** location,
+    v8::InternalFieldsCallbackData<void, void>::Callback phantom_callback,
+    int16_t internal_field_index1, int16_t internal_field_index2) {
+  Node::FromLocation(location)
+      ->MakePhantom(NULL, reinterpret_cast<GenericCallback>(phantom_callback),
+                    internal_field_index1, internal_field_index2);
+}
+
+
+void GlobalHandles::MakePhantom(Object** location, void* parameter,
+                                GenericCallback phantom_callback) {
+  Node::FromLocation(location)->MakePhantom(parameter, phantom_callback,
+                                            v8::Object::kNoInternalFieldIndex,
+                                            v8::Object::kNoInternalFieldIndex);
+}
+
+
+void GlobalHandles::CollectPhantomCallbackData() {
+  for (NodeIterator it(this); !it.done(); it.Advance()) {
+    Node* node = it.node();
+    node->CollectPhantomCallbackData(isolate(), &pending_phantom_callbacks_,
+                                     &pending_internal_fields_callbacks_);
+  }
+}
+
+
 void* GlobalHandles::ClearWeakness(Object** location) {
   return Node::FromLocation(location)->ClearWeakness();
 }
@@ -514,7 +666,32 @@
 
 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
   for (NodeIterator it(this); !it.done(); it.Advance()) {
-    if (it.node()->IsWeakRetainer()) v->VisitPointer(it.node()->location());
+    Node* node = it.node();
+    if (node->IsWeakRetainer()) {
+      // Weakness type can be normal, phantom or internal fields.
+      // For normal weakness we mark through the handle so that
+      // the object and things reachable from it are available
+      // to the callback.
+      // In the case of phantom we can zap the object handle now
+      // and we won't need it, so we don't need to mark through it.
+      // In the internal fields case we will need the internal
+      // fields, so we can't zap the handle, but we don't need to
+      // mark through it, because it will die in this GC round.
+      if (node->state() == Node::PENDING) {
+        if (node->weakness_type() == PHANTOM_WEAK) {
+          *(node->location()) = Smi::FromInt(0);
+        } else if (node->weakness_type() == NORMAL_WEAK) {
+          v->VisitPointer(node->location());
+        } else {
+          DCHECK(node->weakness_type() == INTERNAL_FIELDS_WEAK);
+        }
+      } else {
+        // Node is not pending, so that means the object survived.  We still
+        // need to visit the pointer in case the object moved, eg. because of
+        // compaction.
+        v->VisitPointer(node->location());
+      }
+    }
   }
 }
 
@@ -559,7 +736,20 @@
     DCHECK(node->is_in_new_space_list());
     if ((node->is_independent() || node->is_partially_dependent()) &&
         node->IsWeakRetainer()) {
-      v->VisitPointer(node->location());
+      if (node->weakness_type() == PHANTOM_WEAK) {
+        *(node->location()) = Smi::FromInt(0);
+      } else if (node->weakness_type() == NORMAL_WEAK) {
+        v->VisitPointer(node->location());
+      } else {
+        DCHECK(node->weakness_type() == INTERNAL_FIELDS_WEAK);
+        // For this case we only need to trace if it's alive: The tracing of
+        // something that is already alive is just to get the pointer updated
+        // to the new location of the object).
+        DCHECK(node->state() != Node::NEAR_DEATH);
+        if (node->state() != Node::PENDING) {
+          v->VisitPointer(node->location());
+        }
+      }
     }
   }
 }
@@ -611,63 +801,66 @@
 }
 
 
-int GlobalHandles::PostGarbageCollectionProcessing(
-    GarbageCollector collector) {
-  // Process weak global handle callbacks. This must be done after the
-  // GC is completely done, because the callbacks may invoke arbitrary
-  // API functions.
-  DCHECK(isolate_->heap()->gc_state() == Heap::NOT_IN_GC);
-  const int initial_post_gc_processing_count = ++post_gc_processing_count_;
+int GlobalHandles::PostScavengeProcessing(
+    const int initial_post_gc_processing_count) {
   int freed_nodes = 0;
-  if (collector == SCAVENGER) {
-    for (int i = 0; i < new_space_nodes_.length(); ++i) {
-      Node* node = new_space_nodes_[i];
-      DCHECK(node->is_in_new_space_list());
-      if (!node->IsRetainer()) {
-        // Free nodes do not have weak callbacks. Do not use them to compute
-        // the freed_nodes.
-        continue;
-      }
-      // Skip dependent handles. Their weak callbacks might expect to be
-      // called between two global garbage collection callbacks which
-      // are not called for minor collections.
-      if (!node->is_independent() && !node->is_partially_dependent()) {
-        continue;
-      }
-      node->clear_partially_dependent();
-      if (node->PostGarbageCollectionProcessing(isolate_)) {
-        if (initial_post_gc_processing_count != post_gc_processing_count_) {
-          // Weak callback triggered another GC and another round of
-          // PostGarbageCollection processing.  The current node might
-          // have been deleted in that round, so we need to bail out (or
-          // restart the processing).
-          return freed_nodes;
-        }
-      }
-      if (!node->IsRetainer()) {
-        freed_nodes++;
+  for (int i = 0; i < new_space_nodes_.length(); ++i) {
+    Node* node = new_space_nodes_[i];
+    DCHECK(node->is_in_new_space_list());
+    if (!node->IsRetainer()) {
+      // Free nodes do not have weak callbacks. Do not use them to compute
+      // the freed_nodes.
+      continue;
+    }
+    // Skip dependent handles. Their weak callbacks might expect to be
+    // called between two global garbage collection callbacks which
+    // are not called for minor collections.
+    if (!node->is_independent() && !node->is_partially_dependent()) {
+      continue;
+    }
+    node->clear_partially_dependent();
+    if (node->PostGarbageCollectionProcessing(isolate_)) {
+      if (initial_post_gc_processing_count != post_gc_processing_count_) {
+        // Weak callback triggered another GC and another round of
+        // PostGarbageCollection processing.  The current node might
+        // have been deleted in that round, so we need to bail out (or
+        // restart the processing).
+        return freed_nodes;
       }
     }
-  } else {
-    for (NodeIterator it(this); !it.done(); it.Advance()) {
-      if (!it.node()->IsRetainer()) {
-        // Free nodes do not have weak callbacks. Do not use them to compute
-        // the freed_nodes.
-        continue;
-      }
-      it.node()->clear_partially_dependent();
-      if (it.node()->PostGarbageCollectionProcessing(isolate_)) {
-        if (initial_post_gc_processing_count != post_gc_processing_count_) {
-          // See the comment above.
-          return freed_nodes;
-        }
-      }
-      if (!it.node()->IsRetainer()) {
-        freed_nodes++;
-      }
+    if (!node->IsRetainer()) {
+      freed_nodes++;
     }
   }
-  // Update the list of new space nodes.
+  return freed_nodes;
+}
+
+
+int GlobalHandles::PostMarkSweepProcessing(
+    const int initial_post_gc_processing_count) {
+  int freed_nodes = 0;
+  for (NodeIterator it(this); !it.done(); it.Advance()) {
+    if (!it.node()->IsRetainer()) {
+      // Free nodes do not have weak callbacks. Do not use them to compute
+      // the freed_nodes.
+      continue;
+    }
+    it.node()->clear_partially_dependent();
+    if (it.node()->PostGarbageCollectionProcessing(isolate_)) {
+      if (initial_post_gc_processing_count != post_gc_processing_count_) {
+        // See the comment above.
+        return freed_nodes;
+      }
+    }
+    if (!it.node()->IsRetainer()) {
+      freed_nodes++;
+    }
+  }
+  return freed_nodes;
+}
+
+
+void GlobalHandles::UpdateListOfNewSpaceNodes() {
   int last = 0;
   for (int i = 0; i < new_space_nodes_.length(); ++i) {
     Node* node = new_space_nodes_[i];
@@ -686,10 +879,59 @@
     }
   }
   new_space_nodes_.Rewind(last);
+}
+
+
+int GlobalHandles::DispatchPendingPhantomCallbacks() {
+  int freed_nodes = 0;
+  while (pending_phantom_callbacks_.length() != 0) {
+    PendingPhantomCallback callback = pending_phantom_callbacks_.RemoveLast();
+    callback.invoke();
+    freed_nodes++;
+  }
+  while (pending_internal_fields_callbacks_.length() != 0) {
+    PendingInternalFieldsCallback callback =
+        pending_internal_fields_callbacks_.RemoveLast();
+    callback.invoke();
+    freed_nodes++;
+  }
   return freed_nodes;
 }
 
 
+int GlobalHandles::PostGarbageCollectionProcessing(GarbageCollector collector) {
+  // Process weak global handle callbacks. This must be done after the
+  // GC is completely done, because the callbacks may invoke arbitrary
+  // API functions.
+  DCHECK(isolate_->heap()->gc_state() == Heap::NOT_IN_GC);
+  const int initial_post_gc_processing_count = ++post_gc_processing_count_;
+  int freed_nodes = 0;
+  if (collector == SCAVENGER) {
+    freed_nodes = PostScavengeProcessing(initial_post_gc_processing_count);
+  } else {
+    freed_nodes = PostMarkSweepProcessing(initial_post_gc_processing_count);
+  }
+  if (initial_post_gc_processing_count != post_gc_processing_count_) {
+    // If the callbacks caused a nested GC, then return.  See comment in
+    // PostScavengeProcessing.
+    return freed_nodes;
+  }
+  freed_nodes += DispatchPendingPhantomCallbacks();
+  if (initial_post_gc_processing_count == post_gc_processing_count_) {
+    UpdateListOfNewSpaceNodes();
+  }
+  return freed_nodes;
+}
+
+
+void GlobalHandles::PendingPhantomCallback::invoke() {
+  if (node_->state() == Node::FREE) return;
+  DCHECK(node_->state() == Node::NEAR_DEATH);
+  callback_(data_);
+  if (node_->state() != Node::FREE) node_->Release();
+}
+
+
 void GlobalHandles::IterateStrongRoots(ObjectVisitor* v) {
   for (NodeIterator it(this); !it.done(); it.Advance()) {
     if (it.node()->IsStrongRetainer()) {
diff --git a/src/global-handles.h b/src/global-handles.h
index a06cba0..b3756d0 100644
--- a/src/global-handles.h
+++ b/src/global-handles.h
@@ -97,6 +97,13 @@
 };
 
 
+enum WeaknessType {
+  NORMAL_WEAK,          // Embedder gets a handle to the dying object.
+  PHANTOM_WEAK,         // Embedder gets the parameter they passed in earlier.
+  INTERNAL_FIELDS_WEAK  // Embedder gets 2 internal fields from dying object.
+};
+
+
 class GlobalHandles {
  public:
   ~GlobalHandles();
@@ -112,16 +119,35 @@
 
   typedef WeakCallbackData<v8::Value, void>::Callback WeakCallback;
 
+  // For a phantom weak reference, the callback does not have access to the
+  // dying object.  Phantom weak references are preferred because they allow
+  // memory to be reclaimed in one GC cycle rather than two.  However, for
+  // historical reasons the default is non-phantom.
+  enum PhantomState { Nonphantom, Phantom };
+
   // Make the global handle weak and set the callback parameter for the
   // handle.  When the garbage collector recognizes that only weak global
-  // handles point to an object the handles are cleared and the callback
-  // function is invoked (for each handle) with the handle and corresponding
-  // parameter as arguments.  Note: cleared means set to Smi::FromInt(0). The
-  // reason is that Smi::FromInt(0) does not change during garage collection.
-  static void MakeWeak(Object** location,
-                       void* parameter,
+  // handles point to an object the callback function is invoked (for each
+  // handle) with the handle and corresponding parameter as arguments.  By
+  // default the handle still contains a pointer to the object that is being
+  // collected.  For this reason the object is not collected until the next
+  // GC.  For a phantom weak handle the handle is cleared (set to a Smi)
+  // before the callback is invoked, but the handle can still be identified
+  // in the callback by using the location() of the handle.
+  static void MakeWeak(Object** location, void* parameter,
                        WeakCallback weak_callback);
 
+  // It would be nice to template this one, but it's really hard to get
+  // the template instantiator to work right if you do.
+  static void MakePhantom(Object** location, void* parameter,
+                          PhantomCallbackData<void>::Callback weak_callback);
+
+  static void MakePhantom(
+      Object** location,
+      v8::InternalFieldsCallbackData<void, void>::Callback weak_callback,
+      int16_t internal_field_index1,
+      int16_t internal_field_index2 = v8::Object::kNoInternalFieldIndex);
+
   void RecordStats(HeapStats* stats);
 
   // Returns the current number of weak handles.
@@ -136,6 +162,10 @@
     return number_of_global_handles_;
   }
 
+  // Collect up data for the weak handle callbacks after GC has completed, but
+  // before memory is reclaimed.
+  void CollectPhantomCallbackData();
+
   // Clear the weakness of a global handle.
   static void* ClearWeakness(Object** location);
 
@@ -261,10 +291,18 @@
   // don't assign any initial capacity.
   static const int kObjectGroupConnectionsCapacity = 20;
 
+  // Helpers for PostGarbageCollectionProcessing.
+  int PostScavengeProcessing(int initial_post_gc_processing_count);
+  int PostMarkSweepProcessing(int initial_post_gc_processing_count);
+  int DispatchPendingPhantomCallbacks();
+  void UpdateListOfNewSpaceNodes();
+
   // Internal node structures.
   class Node;
   class NodeBlock;
   class NodeIterator;
+  class PendingPhantomCallback;
+  class PendingInternalFieldsCallback;
 
   Isolate* isolate_;
 
@@ -297,12 +335,46 @@
   List<ObjectGroupRetainerInfo> retainer_infos_;
   List<ObjectGroupConnection> implicit_ref_connections_;
 
+  List<PendingPhantomCallback> pending_phantom_callbacks_;
+  List<PendingInternalFieldsCallback> pending_internal_fields_callbacks_;
+
   friend class Isolate;
 
   DISALLOW_COPY_AND_ASSIGN(GlobalHandles);
 };
 
 
+class GlobalHandles::PendingPhantomCallback {
+ public:
+  typedef PhantomCallbackData<void> Data;
+  PendingPhantomCallback(Node* node, Data data, Data::Callback callback)
+      : node_(node), data_(data), callback_(callback) {}
+
+  void invoke();
+
+  Node* node() { return node_; }
+
+ private:
+  Node* node_;
+  Data data_;
+  Data::Callback callback_;
+};
+
+
+class GlobalHandles::PendingInternalFieldsCallback {
+ public:
+  typedef InternalFieldsCallbackData<void, void> Data;
+  PendingInternalFieldsCallback(Data data, Data::Callback callback)
+      : data_(data), callback_(callback) {}
+
+  void invoke() { callback_(data_); }
+
+ private:
+  Data data_;
+  Data::Callback callback_;
+};
+
+
 class EternalHandles {
  public:
   enum SingletonHandle {
diff --git a/src/globals.h b/src/globals.h
index 609ab88..52ec2aa 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -5,7 +5,8 @@
 #ifndef V8_GLOBALS_H_
 #define V8_GLOBALS_H_
 
-#include "include/v8stdint.h"
+#include <stddef.h>
+#include <stdint.h>
 
 #include "src/base/build_config.h"
 #include "src/base/logging.h"
@@ -25,13 +26,14 @@
 # define V8_INFINITY INFINITY
 #endif
 
-#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM || \
-    V8_TARGET_ARCH_ARM64
+#if V8_TARGET_ARCH_IA32 || (V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_32_BIT) || \
+    V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS ||     \
+    V8_TARGET_ARCH_MIPS64
 #define V8_TURBOFAN_BACKEND 1
 #else
 #define V8_TURBOFAN_BACKEND 0
 #endif
-#if V8_TURBOFAN_BACKEND && !(V8_OS_WIN && V8_TARGET_ARCH_X64)
+#if V8_TURBOFAN_BACKEND
 #define V8_TURBOFAN_TARGET 1
 #else
 #define V8_TURBOFAN_TARGET 0
@@ -80,23 +82,14 @@
 #endif
 
 
-// Support for alternative bool type. This is only enabled if the code is
-// compiled with USE_MYBOOL defined. This catches some nasty type bugs.
-// For instance, 'bool b = "false";' results in b == true! This is a hidden
-// source of bugs.
-// However, redefining the bool type does have some negative impact on some
-// platforms. It gives rise to compiler warnings (i.e. with
-// MSVC) in the API header files when mixing code that uses the standard
-// bool with code that uses the redefined version.
-// This does not actually belong in the platform code, but needs to be
-// defined here because the platform code uses bool, and platform.h is
-// include very early in the main include file.
-
-#ifdef USE_MYBOOL
-typedef unsigned int __my_bool__;
-#define bool __my_bool__  // use 'indirection' to avoid name clashes
+// Determine whether double field unboxing feature is enabled.
+#if (V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64)
+#define V8_DOUBLE_FIELDS_UNBOXING 0
+#else
+#define V8_DOUBLE_FIELDS_UNBOXING 0
 #endif
 
+
 typedef uint8_t byte;
 typedef byte* Address;
 
@@ -143,6 +136,13 @@
 const uintptr_t kUintptrAllBitsSet = V8_UINT64_C(0xFFFFFFFFFFFFFFFF);
 const bool kRequiresCodeRange = true;
 const size_t kMaximalCodeRangeSize = 512 * MB;
+#if V8_OS_WIN
+const size_t kMinimumCodeRangeSize = 4 * MB;
+const size_t kReservedCodeRangePages = 1;
+#else
+const size_t kMinimumCodeRangeSize = 3 * MB;
+const size_t kReservedCodeRangePages = 0;
+#endif
 #else
 const int kPointerSizeLog2 = 2;
 const intptr_t kIntptrSignBit = 0x80000000;
@@ -151,9 +151,13 @@
 // x32 port also requires code range.
 const bool kRequiresCodeRange = true;
 const size_t kMaximalCodeRangeSize = 256 * MB;
+const size_t kMinimumCodeRangeSize = 3 * MB;
+const size_t kReservedCodeRangePages = 0;
 #else
 const bool kRequiresCodeRange = false;
 const size_t kMaximalCodeRangeSize = 0 * MB;
+const size_t kMinimumCodeRangeSize = 0 * MB;
+const size_t kReservedCodeRangePages = 0;
 #endif
 #endif
 
@@ -276,6 +280,7 @@
 #endif
 
 const int kCodeZapValue = 0xbadc0de;
+const uint32_t kPhantomReferenceZap = 0xca11bac;
 
 // On Intel architecture, cache line size is 64 bytes.
 // On ARM it may be less (32 bytes), but as far this constant is
@@ -339,8 +344,10 @@
 template <typename Config, class Allocator = FreeStoreAllocationPolicy>
     class SplayTree;
 class String;
+class Symbol;
 class Name;
 class Struct;
+class Symbol;
 class Variable;
 class RelocInfo;
 class Deserializer;
@@ -355,6 +362,7 @@
 
 // NOTE: SpaceIterator depends on AllocationSpace enumeration values being
 // consecutive.
+// Keep this enum in sync with the ObjectSpace enum in v8.h
 enum AllocationSpace {
   NEW_SPACE,            // Semispaces collected with copying collector.
   OLD_POINTER_SPACE,    // May contain pointers to new space.
@@ -364,7 +372,6 @@
   CELL_SPACE,           // Only and all cell objects.
   PROPERTY_CELL_SPACE,  // Only and all global property cell objects.
   LO_SPACE,             // Promoted large objects.
-  INVALID_SPACE,        // Only used in AllocationResult to signal success.
 
   FIRST_SPACE = NEW_SPACE,
   LAST_SPACE = LO_SPACE,
@@ -547,22 +554,6 @@
 };
 
 
-// Logging and profiling.  A StateTag represents a possible state of
-// the VM. The logger maintains a stack of these. Creating a VMState
-// object enters a state by pushing on the stack, and destroying a
-// VMState object leaves a state by popping the current state from the
-// stack.
-
-enum StateTag {
-  JS,
-  GC,
-  COMPILER,
-  OTHER,
-  EXTERNAL,
-  IDLE
-};
-
-
 // -----------------------------------------------------------------------------
 // Macros
 
@@ -609,28 +600,32 @@
 
 // CPU feature flags.
 enum CpuFeature {
-    // x86
-    SSE4_1,
-    SSE3,
-    SAHF,
-    // ARM
-    VFP3,
-    ARMv7,
-    SUDIV,
-    MLS,
-    UNALIGNED_ACCESSES,
-    MOVW_MOVT_IMMEDIATE_LOADS,
-    VFP32DREGS,
-    NEON,
-    // MIPS, MIPS64
-    FPU,
-    FP64FPU,
-    MIPSr1,
-    MIPSr2,
-    MIPSr6,
-    // ARM64
-    ALWAYS_ALIGN_CSP,
-    NUMBER_OF_CPU_FEATURES
+  // x86
+  SSE4_1,
+  SSE3,
+  SAHF,
+  AVX,
+  FMA3,
+  // ARM
+  VFP3,
+  ARMv7,
+  ARMv8,
+  SUDIV,
+  MLS,
+  UNALIGNED_ACCESSES,
+  MOVW_MOVT_IMMEDIATE_LOADS,
+  VFP32DREGS,
+  NEON,
+  // MIPS, MIPS64
+  FPU,
+  FP64FPU,
+  MIPSr1,
+  MIPSr2,
+  MIPSr6,
+  // ARM64
+  ALWAYS_ALIGN_CSP,
+  COHERENT_CACHE,
+  NUMBER_OF_CPU_FEATURES
 };
 
 
@@ -646,10 +641,11 @@
   EVAL_SCOPE,      // The top-level scope for an eval source.
   FUNCTION_SCOPE,  // The top-level scope for a function.
   MODULE_SCOPE,    // The scope introduced by a module literal
-  GLOBAL_SCOPE,    // The top-level scope for a program or a top-level eval.
+  SCRIPT_SCOPE,    // The top-level scope for a script or a top-level eval.
   CATCH_SCOPE,     // The scope introduced by catch.
   BLOCK_SCOPE,     // The scope introduced by a new block.
-  WITH_SCOPE       // The scope introduced by with.
+  WITH_SCOPE,      // The scope introduced by with.
+  ARROW_SCOPE      // The top-level scope for an arrow function literal.
 };
 
 
@@ -777,7 +773,8 @@
   kArrowFunction = 1,
   kGeneratorFunction = 2,
   kConciseMethod = 4,
-  kConciseGeneratorMethod = kGeneratorFunction | kConciseMethod
+  kConciseGeneratorMethod = kGeneratorFunction | kConciseMethod,
+  kDefaultConstructor = 8
 };
 
 
@@ -786,7 +783,8 @@
          kind == FunctionKind::kArrowFunction ||
          kind == FunctionKind::kGeneratorFunction ||
          kind == FunctionKind::kConciseMethod ||
-         kind == FunctionKind::kConciseGeneratorMethod;
+         kind == FunctionKind::kConciseGeneratorMethod ||
+         kind == FunctionKind::kDefaultConstructor;
 }
 
 
@@ -806,6 +804,14 @@
   DCHECK(IsValidFunctionKind(kind));
   return kind & FunctionKind::kConciseMethod;
 }
+
+
+inline bool IsDefaultConstructor(FunctionKind kind) {
+  DCHECK(IsValidFunctionKind(kind));
+  return kind & FunctionKind::kDefaultConstructor;
+}
+
+
 } }  // namespace v8::internal
 
 namespace i = v8::internal;
diff --git a/src/handles.h b/src/handles.h
index 577e83a..eb57f0e 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -53,7 +53,8 @@
   }
 
   // Convert to a Handle with a type that can be upcasted to.
-  template <class S> INLINE(bool ToHandle(Handle<S>* out)) {
+  template <class S>
+  V8_INLINE bool ToHandle(Handle<S>* out) const {
     if (location_ == NULL) {
       *out = Handle<T>::null();
       return false;
diff --git a/src/harmony-array-includes.js b/src/harmony-array-includes.js
new file mode 100644
index 0000000..d1a7790
--- /dev/null
+++ b/src/harmony-array-includes.js
@@ -0,0 +1,61 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+// This file relies on the fact that the following declaration has been made
+// in runtime.js:
+// var $Array = global.Array;
+
+// -------------------------------------------------------------------
+
+// Proposed for ES7
+// https://github.com/tc39/Array.prototype.includes
+// 6e3b78c927aeda20b9d40e81303f9d44596cd904
+function ArrayIncludes(searchElement, fromIndex) {
+  var array = ToObject(this);
+  var len = ToLength(array.length);
+
+  if (len === 0) {
+    return false;
+  }
+
+  var n = ToInteger(fromIndex);
+
+  var k;
+  if (n >= 0) {
+    k = n;
+  } else {
+    k = len + n;
+    if (k < 0) {
+      k = 0;
+    }
+  }
+
+  while (k < len) {
+    var elementK = array[k];
+    if (SameValueZero(searchElement, elementK)) {
+      return true;
+    }
+
+    ++k;
+  }
+
+  return false;
+}
+
+// -------------------------------------------------------------------
+
+function HarmonyArrayIncludesExtendArrayPrototype() {
+  %CheckIsBootstrapping();
+
+  %FunctionSetLength(ArrayIncludes, 1);
+
+  // Set up the non-enumerable functions on the Array prototype object.
+  InstallFunctions($Array.prototype, DONT_ENUM, $Array(
+    "includes", ArrayIncludes
+  ));
+}
+
+HarmonyArrayIncludesExtendArrayPrototype();
diff --git a/src/harmony-array.js b/src/harmony-array.js
index 88b878f..5d1262a 100644
--- a/src/harmony-array.js
+++ b/src/harmony-array.js
@@ -26,16 +26,18 @@
     thisArg = %_Arguments(1);
   }
 
+  var needs_wrapper = false;
   if (IS_NULL_OR_UNDEFINED(thisArg)) {
     thisArg = %GetDefaultReceiver(predicate) || thisArg;
-  } else if (!IS_SPEC_OBJECT(thisArg) && %IsSloppyModeFunction(predicate)) {
-    thisArg = ToObject(thisArg);
+  } else {
+    needs_wrapper = SHOULD_CREATE_WRAPPER(predicate, thisArg);
   }
 
   for (var i = 0; i < length; i++) {
     if (i in array) {
       var element = array[i];
-      if (%_CallFunction(thisArg, element, i, array, predicate)) {
+      var newThisArg = needs_wrapper ? ToObject(thisArg) : thisArg;
+      if (%_CallFunction(newThisArg, element, i, array, predicate)) {
         return element;
       }
     }
@@ -61,16 +63,18 @@
     thisArg = %_Arguments(1);
   }
 
+  var needs_wrapper = false;
   if (IS_NULL_OR_UNDEFINED(thisArg)) {
     thisArg = %GetDefaultReceiver(predicate) || thisArg;
-  } else if (!IS_SPEC_OBJECT(thisArg) && %IsSloppyModeFunction(predicate)) {
-    thisArg = ToObject(thisArg);
+  } else {
+    needs_wrapper = SHOULD_CREATE_WRAPPER(predicate, thisArg);
   }
 
   for (var i = 0; i < length; i++) {
     if (i in array) {
       var element = array[i];
-      if (%_CallFunction(thisArg, element, i, array, predicate)) {
+      var newThisArg = needs_wrapper ? ToObject(thisArg) : thisArg;
+      if (%_CallFunction(newThisArg, element, i, array, predicate)) {
         return i;
       }
     }
@@ -123,6 +127,56 @@
   return array;
 }
 
+// ES6, draft 10-14-14, section 22.1.2.1
+function ArrayFrom(arrayLike, mapfn, receiver) {
+  var items = ToObject(arrayLike);
+  var mapping = !IS_UNDEFINED(mapfn);
+
+  if (mapping) {
+    if (!IS_SPEC_FUNCTION(mapfn)) {
+      throw MakeTypeError('called_non_callable', [ mapfn ]);
+    } else if (IS_NULL_OR_UNDEFINED(receiver)) {
+      receiver = %GetDefaultReceiver(mapfn) || receiver;
+    } else if (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(mapfn)) {
+      receiver = ToObject(receiver);
+    }
+  }
+
+  var iterable = ToIterable(items);
+  var k;
+  var result;
+  var mappedValue;
+  var nextValue;
+
+  if (!IS_UNDEFINED(iterable)) {
+    result = IS_SPEC_FUNCTION(this) && this.prototype ? new this() : [];
+
+    k = 0;
+    for (nextValue of items) {
+      if (mapping) mappedValue = %_CallFunction(receiver, nextValue, k, mapfn);
+      else mappedValue = nextValue;
+      %AddElement(result, k++, mappedValue, NONE);
+    }
+
+    result.length = k;
+    return result;
+  } else {
+    var len = ToLength(items.length);
+    result = IS_SPEC_FUNCTION(this) && this.prototype ? new this(len) :
+        new $Array(len);
+
+    for (k = 0; k < len; ++k) {
+      nextValue = items[k];
+      if (mapping) mappedValue = %_CallFunction(receiver, nextValue, k, mapfn);
+      else mappedValue = nextValue;
+      %AddElement(result, k, mappedValue, NONE);
+    }
+
+    result.length = k;
+    return result;
+  }
+}
+
 // ES6, draft 05-22-14, section 22.1.2.3
 function ArrayOf() {
   var length = %_ArgumentsLength();
@@ -138,11 +192,25 @@
 
 // -------------------------------------------------------------------
 
+function HarmonyArrayExtendSymbolPrototype() {
+  %CheckIsBootstrapping();
+
+  InstallConstants($Symbol, $Array(
+    // TODO(dslomov, caitp): Move to symbol.js when shipping
+   "isConcatSpreadable", symbolIsConcatSpreadable
+  ));
+}
+
+HarmonyArrayExtendSymbolPrototype();
+
 function HarmonyArrayExtendArrayPrototype() {
   %CheckIsBootstrapping();
 
+  %FunctionSetLength(ArrayFrom, 1);
+
   // Set up non-enumerable functions on the Array object.
   InstallFunctions($Array, DONT_ENUM, $Array(
+    "from", ArrayFrom,
     "of", ArrayOf
   ));
 
diff --git a/src/harmony-classes.js b/src/harmony-classes.js
index b6605a9..ac06758 100644
--- a/src/harmony-classes.js
+++ b/src/harmony-classes.js
@@ -7,26 +7,29 @@
 // var $Function = global.Function;
 // var $Array = global.Array;
 
+"use strict";
 
-(function() {
-  function FunctionToMethod(homeObject) {
-    if (!IS_SPEC_FUNCTION(this)) {
-      throw MakeTypeError('toMethod_non_function',
-                          [%ToString(this), typeof this]);
+function FunctionToMethod(homeObject) {
+  if (!IS_SPEC_FUNCTION(this)) {
+    throw MakeTypeError('toMethod_non_function',
+                        [%ToString(this), typeof this]);
 
-    }
-
-    if (!IS_SPEC_OBJECT(homeObject)) {
-      throw MakeTypeError('toMethod_non_object',
-                          [%ToString(homeObject)]);
-    }
-
-    return %ToMethod(this, homeObject);
   }
 
+  if (!IS_SPEC_OBJECT(homeObject)) {
+    throw MakeTypeError('toMethod_non_object',
+                        [%ToString(homeObject)]);
+  }
+
+  return %ToMethod(this, homeObject);
+}
+
+function SetupHarmonyClasses() {
   %CheckIsBootstrapping();
 
   InstallFunctions($Function.prototype, DONT_ENUM, $Array(
       "toMethod", FunctionToMethod
   ));
-}());
+}
+
+SetupHarmonyClasses();
diff --git a/src/harmony-regexp.js b/src/harmony-regexp.js
new file mode 100644
index 0000000..a1b32ab
--- /dev/null
+++ b/src/harmony-regexp.js
@@ -0,0 +1,35 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+'use strict';
+
+var $RegExp = global.RegExp;
+
+// -------------------------------------------------------------------
+
+// ES6 draft 12-06-13, section 21.2.5.3
+// + https://bugs.ecmascript.org/show_bug.cgi?id=3423
+function RegExpGetFlags() {
+  if (!IS_SPEC_OBJECT(this)) {
+    throw MakeTypeError('flags_getter_non_object',
+                        [%ToString(this)]);
+  }
+  var result = '';
+  if (this.global) result += 'g';
+  if (this.ignoreCase) result += 'i';
+  if (this.multiline) result += 'm';
+  if (this.unicode) result += 'u';
+  if (this.sticky) result += 'y';
+  return result;
+}
+
+function ExtendRegExpPrototype() {
+  %CheckIsBootstrapping();
+
+  %DefineAccessorPropertyUnchecked($RegExp.prototype, 'flags', RegExpGetFlags,
+                                   null, DONT_ENUM);
+  %SetNativeFlag(RegExpGetFlags);
+}
+
+ExtendRegExpPrototype();
diff --git a/src/harmony-string.js b/src/harmony-string.js
index ae13745..6bbe139 100644
--- a/src/harmony-string.js
+++ b/src/harmony-string.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
+"use strict";
 
 // This file relies on the fact that the following declaration has been made
 // in runtime.js:
@@ -17,16 +17,19 @@
 
   var s = TO_STRING_INLINE(this);
   var n = ToInteger(count);
-  if (n < 0 || !NUMBER_IS_FINITE(n)) {
+  // The maximum string length is stored in a smi, so a longer repeat
+  // must result in a range error.
+  if (n < 0 || n > %_MaxSmi()) {
     throw MakeRangeError("invalid_count_value", []);
   }
 
-  var elements = new InternalArray(n);
-  for (var i = 0; i < n; i++) {
-    elements[i] = s;
+  var r = "";
+  while (true) {
+    if (n & 1) r += s;
+    n >>= 1;
+    if (n === 0) return r;
+    s += s;
   }
-
-  return %StringBuilderConcat(elements, n, "");
 }
 
 
@@ -92,14 +95,14 @@
 
 
 // ES6 draft 04-05-14, section 21.1.3.6
-function StringContains(searchString /* position */) {  // length == 1
-  CHECK_OBJECT_COERCIBLE(this, "String.prototype.contains");
+function StringIncludes(searchString /* position */) {  // length == 1
+  CHECK_OBJECT_COERCIBLE(this, "String.prototype.includes");
 
   var s = TO_STRING_INLINE(this);
 
   if (IS_REGEXP(searchString)) {
     throw MakeTypeError("first_argument_not_regexp",
-                        ["String.prototype.contains"]);
+                        ["String.prototype.includes"]);
   }
 
   var ss = TO_STRING_INLINE(searchString);
@@ -181,7 +184,7 @@
   // Set up the non-enumerable functions on the String prototype object.
   InstallFunctions($String.prototype, DONT_ENUM, $Array(
     "codePointAt", StringCodePointAt,
-    "contains", StringContains,
+    "includes", StringIncludes,
     "endsWith", StringEndsWith,
     "repeat", StringRepeat,
     "startsWith", StringStartsWith
diff --git a/src/harmony-templates.js b/src/harmony-templates.js
new file mode 100644
index 0000000..254f434
--- /dev/null
+++ b/src/harmony-templates.js
@@ -0,0 +1,94 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+"use strict";
+
+var callSiteCache = new $Map;
+
+function SameCallSiteElements(rawStrings, other) {
+  var length = rawStrings.length;
+  var other = other.raw;
+
+  if (length !== other.length) return false;
+
+  for (var i = 0; i < length; ++i) {
+    if (rawStrings[i] !== other[i]) return false;
+  }
+
+  return true;
+}
+
+
+function GetCachedCallSite(siteObj, hash) {
+  var obj = %MapGet(callSiteCache, hash);
+
+  if (IS_UNDEFINED(obj)) return;
+
+  var length = obj.length;
+  for (var i = 0; i < length; ++i) {
+    if (SameCallSiteElements(siteObj, obj[i])) return obj[i];
+  }
+}
+
+
+function SetCachedCallSite(siteObj, hash) {
+  var obj = %MapGet(callSiteCache, hash);
+  var array;
+
+  if (IS_UNDEFINED(obj)) {
+    array = new InternalArray(1);
+    array[0] = siteObj;
+    %MapSet(callSiteCache, hash, array);
+  } else {
+    obj.push(siteObj);
+  }
+
+  return siteObj;
+}
+
+
+function GetTemplateCallSite(siteObj, rawStrings, hash) {
+  var cached = GetCachedCallSite(rawStrings, hash);
+
+  if (!IS_UNDEFINED(cached)) return cached;
+
+  %AddNamedProperty(siteObj, "raw", %ObjectFreeze(rawStrings),
+      READ_ONLY | DONT_ENUM | DONT_DELETE);
+
+  return SetCachedCallSite(%ObjectFreeze(siteObj), hash);
+}
+
+
+// ES6 Draft 10-14-2014, section 21.1.2.4
+function StringRaw(callSite) {
+  // TODO(caitp): Use rest parameters when implemented
+  var numberOfSubstitutions = %_ArgumentsLength();
+  var cooked = ToObject(callSite);
+  var raw = ToObject(cooked.raw);
+  var literalSegments = ToLength(raw.length);
+  if (literalSegments <= 0) return "";
+
+  var result = ToString(raw[0]);
+
+  for (var i = 1; i < literalSegments; ++i) {
+    if (i < numberOfSubstitutions) {
+      result += ToString(%_Arguments(i));
+    }
+    result += ToString(raw[i]);
+  }
+
+  return result;
+}
+
+
+function ExtendStringForTemplates() {
+  %CheckIsBootstrapping();
+
+  // Set up the non-enumerable functions on the String object.
+  InstallFunctions($String, DONT_ENUM, $Array(
+    "raw", StringRaw
+  ));
+}
+
+ExtendStringForTemplates();
diff --git a/src/harmony-tostring.js b/src/harmony-tostring.js
new file mode 100644
index 0000000..0336456
--- /dev/null
+++ b/src/harmony-tostring.js
@@ -0,0 +1,72 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+"use strict";
+
+// This file relies on the fact that the following declaration has been made
+// in runtime.js and symbol.js:
+// var $Object = global.Object;
+// var $Symbol = global.Symbol;
+
+var kBuiltinStringTags = {
+  "__proto__": null,
+  "Arguments": true,
+  "Array": true,
+  "Boolean": true,
+  "Date": true,
+  "Error": true,
+  "Function": true,
+  "Number": true,
+  "RegExp": true,
+  "String": true
+};
+
+DefaultObjectToString = ObjectToStringHarmony;
+// ES6 draft 08-24-14, section 19.1.3.6
+function ObjectToStringHarmony() {
+  if (IS_UNDEFINED(this) && !IS_UNDETECTABLE(this)) return "[object Undefined]";
+  if (IS_NULL(this)) return "[object Null]";
+  var O = ToObject(this);
+  var builtinTag = %_ClassOf(O);
+  var tag = O[symbolToStringTag];
+  if (IS_UNDEFINED(tag)) {
+    tag = builtinTag;
+  } else if (!IS_STRING(tag)) {
+    return "[object ???]"
+  } else if (tag !== builtinTag && kBuiltinStringTags[tag]) {
+    return "[object ~" + tag + "]";
+  }
+  return "[object " + tag + "]";
+}
+
+function HarmonyToStringExtendSymbolPrototype() {
+  %CheckIsBootstrapping();
+
+  InstallConstants($Symbol, $Array(
+    // TODO(dslomov, caitp): Move to symbol.js when shipping
+   "toStringTag", symbolToStringTag
+  ));
+}
+
+HarmonyToStringExtendSymbolPrototype();
+
+function HarmonyToStringExtendObjectPrototype() {
+  %CheckIsBootstrapping();
+
+  // Can't use InstallFunctions() because will fail in Debug mode.
+  // Emulate InstallFunctions() here.
+  %FunctionSetName(ObjectToStringHarmony, "toString");
+  %FunctionRemovePrototype(ObjectToStringHarmony);
+  %SetNativeFlag(ObjectToStringHarmony);
+
+  // Set up the non-enumerable functions on the Array prototype object.
+  var desc = ToPropertyDescriptor({
+    value: ObjectToStringHarmony
+  });
+  DefineOwnProperty($Object.prototype, "toString", desc, false);
+
+  %ToFastProperties($Object.prototype);
+}
+
+HarmonyToStringExtendObjectPrototype();
diff --git a/src/harmony-typedarray.js b/src/harmony-typedarray.js
new file mode 100644
index 0000000..c2eb452
--- /dev/null
+++ b/src/harmony-typedarray.js
@@ -0,0 +1,95 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+"use strict";
+
+// This file relies on the fact that the following declaration has been made
+// in runtime.js:
+// var $Array = global.Array;
+
+// -------------------------------------------------------------------
+
+macro TYPED_ARRAYS(FUNCTION)
+// arrayIds below should be synchronized with Runtime_TypedArrayInitialize.
+FUNCTION(1, Uint8Array, 1)
+FUNCTION(2, Int8Array, 1)
+FUNCTION(3, Uint16Array, 2)
+FUNCTION(4, Int16Array, 2)
+FUNCTION(5, Uint32Array, 4)
+FUNCTION(6, Int32Array, 4)
+FUNCTION(7, Float32Array, 4)
+FUNCTION(8, Float64Array, 8)
+FUNCTION(9, Uint8ClampedArray, 1)
+endmacro
+
+
+macro TYPED_ARRAY_HARMONY_ADDITIONS(ARRAY_ID, NAME, ELEMENT_SIZE)
+
+// ES6 draft 08-24-14, section 22.2.3.12
+function NAMEForEach(f /* thisArg */) {  // length == 1
+  if (!%IsTypedArray(this)) {
+    throw MakeTypeError('not_typed_array', []);
+  }
+  if (!IS_SPEC_FUNCTION(f)) {
+    throw MakeTypeError('called_non_callable', [ f ]);
+  }
+
+  var length = %_TypedArrayGetLength(this);
+  var receiver;
+
+  if (%_ArgumentsLength() > 1) {
+    receiver = %_Arguments(1);
+  }
+
+  var needs_wrapper = false;
+  if (IS_NULL_OR_UNDEFINED(receiver)) {
+    receiver = %GetDefaultReceiver(f) || receiver;
+  } else {
+    needs_wrapper = SHOULD_CREATE_WRAPPER(f, receiver);
+  }
+
+  var stepping = DEBUG_IS_ACTIVE && %DebugCallbackSupportsStepping(f);
+  for (var i = 0; i < length; i++) {
+    var element = this[i];
+    // Prepare break slots for debugger step in.
+    if (stepping) %DebugPrepareStepInIfStepping(f);
+    var new_receiver = needs_wrapper ? ToObject(receiver) : receiver;
+    %_CallFunction(new_receiver, TO_OBJECT_INLINE(element), i, this, f);
+  }
+}
+
+// ES6 draft 08-24-14, section 22.2.2.2
+function NAMEOf() {  // length == 0
+  var length = %_ArgumentsLength();
+  var array = new this(length);
+  for (var i = 0; i < length; i++) {
+    array[i] = %_Arguments(i);
+  }
+  return array;
+}
+
+endmacro
+
+TYPED_ARRAYS(TYPED_ARRAY_HARMONY_ADDITIONS)
+
+
+function HarmonyTypedArrayExtendPrototypes() {
+macro EXTEND_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
+  %CheckIsBootstrapping();
+
+  // Set up non-enumerable functions on the object.
+  InstallFunctions(global.NAME, DONT_ENUM | DONT_DELETE | READ_ONLY, $Array(
+    "of", NAMEOf
+  ));
+
+  // Set up non-enumerable functions on the prototype object.
+  InstallFunctions(global.NAME.prototype, DONT_ENUM, $Array(
+    "forEach", NAMEForEach
+  ));
+endmacro
+
+  TYPED_ARRAYS(EXTEND_TYPED_ARRAY)
+}
+
+HarmonyTypedArrayExtendPrototypes();
diff --git a/src/heap-snapshot-generator-inl.h b/src/heap-snapshot-generator-inl.h
index 3f7e622..ad95776 100644
--- a/src/heap-snapshot-generator-inl.h
+++ b/src/heap-snapshot-generator-inl.h
@@ -12,7 +12,7 @@
 
 
 HeapEntry* HeapGraphEdge::from() const {
-  return &snapshot()->entries()[from_index_];
+  return &snapshot()->entries()[from_index()];
 }
 
 
diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc
index 4a4c914..196eb13 100644
--- a/src/heap-snapshot-generator.cc
+++ b/src/heap-snapshot-generator.cc
@@ -18,8 +18,7 @@
 
 
 HeapGraphEdge::HeapGraphEdge(Type type, const char* name, int from, int to)
-    : type_(type),
-      from_index_(from),
+    : bit_field_(TypeField::encode(type) | FromIndexField::encode(from)),
       to_index_(to),
       name_(name) {
   DCHECK(type == kContextVariable
@@ -31,8 +30,7 @@
 
 
 HeapGraphEdge::HeapGraphEdge(Type type, int index, int from, int to)
-    : type_(type),
-      from_index_(from),
+    : bit_field_(TypeField::encode(type) | FromIndexField::encode(from)),
       to_index_(to),
       index_(index) {
   DCHECK(type == kElement || type == kHidden);
@@ -1169,13 +1167,10 @@
                          "native_context", global_obj->native_context(),
                          GlobalObject::kNativeContextOffset);
     SetInternalReference(global_obj, entry,
-                         "global_context", global_obj->global_context(),
-                         GlobalObject::kGlobalContextOffset);
-    SetInternalReference(global_obj, entry,
                          "global_proxy", global_obj->global_proxy(),
                          GlobalObject::kGlobalProxyOffset);
     STATIC_ASSERT(GlobalObject::kHeaderSize - JSObject::kHeaderSize ==
-                 4 * kPointerSize);
+                 3 * kPointerSize);
   } else if (obj->IsJSArrayBufferView()) {
     JSArrayBufferView* view = JSArrayBufferView::cast(obj);
     SetInternalReference(view, entry, "buffer", view->buffer(),
@@ -1284,7 +1279,7 @@
                   Context::FIRST_WEAK_SLOT);
     STATIC_ASSERT(Context::NEXT_CONTEXT_LINK + 1 ==
                   Context::NATIVE_CONTEXT_SLOTS);
-    STATIC_ASSERT(Context::FIRST_WEAK_SLOT + 5 ==
+    STATIC_ASSERT(Context::FIRST_WEAK_SLOT + 4 ==
                   Context::NATIVE_CONTEXT_SLOTS);
   }
 }
@@ -1631,53 +1626,32 @@
     DescriptorArray* descs = js_obj->map()->instance_descriptors();
     int real_size = js_obj->map()->NumberOfOwnDescriptors();
     for (int i = 0; i < real_size; i++) {
-      switch (descs->GetType(i)) {
-        case FIELD: {
-          Representation r = descs->GetDetails(i).representation();
+      PropertyDetails details = descs->GetDetails(i);
+      switch (details.location()) {
+        case IN_OBJECT: {
+          Representation r = details.representation();
           if (r.IsSmi() || r.IsDouble()) break;
-          int index = descs->GetFieldIndex(i);
 
           Name* k = descs->GetKey(i);
-          if (index < js_obj->map()->inobject_properties()) {
-            Object* value = js_obj->InObjectPropertyAt(index);
-            if (k != heap_->hidden_string()) {
-              SetPropertyReference(
-                  js_obj, entry,
-                  k, value,
-                  NULL,
-                  js_obj->GetInObjectPropertyOffset(index));
-            } else {
-              TagObject(value, "(hidden properties)");
-              SetInternalReference(
-                  js_obj, entry,
-                  "hidden_properties", value,
-                  js_obj->GetInObjectPropertyOffset(index));
-            }
+          FieldIndex field_index = FieldIndex::ForDescriptor(js_obj->map(), i);
+          Object* value = js_obj->RawFastPropertyAt(field_index);
+          int field_offset =
+              field_index.is_inobject() ? field_index.offset() : -1;
+
+          if (k != heap_->hidden_string()) {
+            SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry, k,
+                                               value, NULL, field_offset);
           } else {
-            FieldIndex field_index =
-                FieldIndex::ForDescriptor(js_obj->map(), i);
-            Object* value = js_obj->RawFastPropertyAt(field_index);
-            if (k != heap_->hidden_string()) {
-              SetPropertyReference(js_obj, entry, k, value);
-            } else {
-              TagObject(value, "(hidden properties)");
-              SetInternalReference(js_obj, entry, "hidden_properties", value);
-            }
+            TagObject(value, "(hidden properties)");
+            SetInternalReference(js_obj, entry, "hidden_properties", value,
+                                 field_offset);
           }
           break;
         }
-        case CONSTANT:
-          SetPropertyReference(
-              js_obj, entry,
-              descs->GetKey(i), descs->GetConstant(i));
-          break;
-        case CALLBACKS:
-          ExtractAccessorPairProperty(
-              js_obj, entry,
-              descs->GetKey(i), descs->GetValue(i));
-          break;
-        case NORMAL:  // only in slow mode
-          UNREACHABLE();
+        case IN_DESCRIPTOR:
+          SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry,
+                                             descs->GetKey(i),
+                                             descs->GetValue(i));
           break;
       }
     }
@@ -1697,27 +1671,30 @@
           SetInternalReference(js_obj, entry, "hidden_properties", value);
           continue;
         }
-        if (ExtractAccessorPairProperty(js_obj, entry, k, value)) continue;
-        SetPropertyReference(js_obj, entry, String::cast(k), value);
+        PropertyDetails details = dictionary->DetailsAt(i);
+        SetDataOrAccessorPropertyReference(details.kind(), js_obj, entry,
+                                           Name::cast(k), value);
       }
     }
   }
 }
 
 
-bool V8HeapExplorer::ExtractAccessorPairProperty(
-    JSObject* js_obj, int entry, Object* key, Object* callback_obj) {
-  if (!callback_obj->IsAccessorPair()) return false;
+void V8HeapExplorer::ExtractAccessorPairProperty(JSObject* js_obj, int entry,
+                                                 Name* key,
+                                                 Object* callback_obj,
+                                                 int field_offset) {
+  if (!callback_obj->IsAccessorPair()) return;
   AccessorPair* accessors = AccessorPair::cast(callback_obj);
+  SetPropertyReference(js_obj, entry, key, accessors, NULL, field_offset);
   Object* getter = accessors->getter();
   if (!getter->IsOddball()) {
-    SetPropertyReference(js_obj, entry, String::cast(key), getter, "get %s");
+    SetPropertyReference(js_obj, entry, key, getter, "get %s");
   }
   Object* setter = accessors->setter();
   if (!setter->IsOddball()) {
-    SetPropertyReference(js_obj, entry, String::cast(key), setter, "set %s");
+    SetPropertyReference(js_obj, entry, key, setter, "set %s");
   }
-  return true;
 }
 
 
@@ -2056,6 +2033,20 @@
 }
 
 
+void V8HeapExplorer::SetDataOrAccessorPropertyReference(
+    PropertyKind kind, JSObject* parent_obj, int parent_entry,
+    Name* reference_name, Object* child_obj, const char* name_format_string,
+    int field_offset) {
+  if (kind == ACCESSOR) {
+    ExtractAccessorPairProperty(parent_obj, parent_entry, reference_name,
+                                child_obj, field_offset);
+  } else {
+    SetPropertyReference(parent_obj, parent_entry, reference_name, child_obj,
+                         name_format_string, field_offset);
+  }
+}
+
+
 void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
                                           int parent_entry,
                                           Name* reference_name,
@@ -2164,6 +2155,12 @@
 #define STRING_NAME(name, str) NAME_ENTRY(name)
     INTERNALIZED_STRING_LIST(STRING_NAME)
 #undef STRING_NAME
+#define SYMBOL_NAME(name) NAME_ENTRY(name)
+    PRIVATE_SYMBOL_LIST(SYMBOL_NAME)
+#undef SYMBOL_NAME
+#define SYMBOL_NAME(name, varname, description) NAME_ENTRY(name)
+    PUBLIC_SYMBOL_LIST(SYMBOL_NAME)
+#undef SYMBOL_NAME
 #undef NAME_ENTRY
     CHECK(!strong_gc_subroot_names_.is_empty());
   }
@@ -2297,7 +2294,6 @@
     : isolate_(snapshot->profiler()->heap_object_map()->heap()->isolate()),
       snapshot_(snapshot),
       names_(snapshot_->profiler()->names()),
-      progress_(progress),
       embedder_queried_(false),
       objects_by_info_(RetainedInfosMatch),
       native_groups_(StringsMatch),
diff --git a/src/heap-snapshot-generator.h b/src/heap-snapshot-generator.h
index 3e4ce71..8aef437 100644
--- a/src/heap-snapshot-generator.h
+++ b/src/heap-snapshot-generator.h
@@ -28,22 +28,18 @@
     kWeak = v8::HeapGraphEdge::kWeak
   };
 
-  HeapGraphEdge() { }
   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() const { return static_cast<Type>(type_); }
+  Type type() const { return TypeField::decode(bit_field_); }
   int index() const {
-    DCHECK(type_ == kElement || type_ == kHidden);
+    DCHECK(type() == kElement || type() == kHidden);
     return index_;
   }
   const char* name() const {
-    DCHECK(type_ == kContextVariable
-        || type_ == kProperty
-        || type_ == kInternal
-        || type_ == kShortcut
-        || type_ == kWeak);
+    DCHECK(type() == kContextVariable || type() == kProperty ||
+           type() == kInternal || type() == kShortcut || type() == kWeak);
     return name_;
   }
   INLINE(HeapEntry* from() const);
@@ -51,9 +47,11 @@
 
  private:
   INLINE(HeapSnapshot* snapshot() const);
+  int from_index() const { return FromIndexField::decode(bit_field_); }
 
-  unsigned type_ : 3;
-  int from_index_ : 29;
+  class TypeField : public BitField<Type, 0, 3> {};
+  class FromIndexField : public BitField<int, 3, 29> {};
+  uint32_t bit_field_;
   union {
     // During entries population |to_index_| is used for storing the index,
     // afterwards it is replaced with a pointer to the entry.
@@ -176,7 +174,6 @@
   void FillChildren();
 
   void Print(int max_depth);
-  void PrintEntriesSize();
 
  private:
   HeapEntry* AddRootEntry();
@@ -332,7 +329,6 @@
                  v8::HeapProfiler::ObjectNameResolver* resolver);
   virtual ~V8HeapExplorer();
   virtual HeapEntry* AllocateEntry(HeapThing ptr);
-  void AddRootEntries(SnapshotFiller* filler);
   int EstimateObjectsCount(HeapIterator* iterator);
   bool IterateAndExtractReferences(SnapshotFiller* filler);
   void TagGlobalObjects();
@@ -385,8 +381,8 @@
   void ExtractFixedArrayReferences(int entry, FixedArray* array);
   void ExtractClosureReferences(JSObject* js_obj, int entry);
   void ExtractPropertyReferences(JSObject* js_obj, int entry);
-  bool ExtractAccessorPairProperty(JSObject* js_obj, int entry,
-                                   Object* key, Object* callback_obj);
+  void ExtractAccessorPairProperty(JSObject* js_obj, int entry, Name* key,
+                                   Object* callback_obj, int field_offset = -1);
   void ExtractElementReferences(JSObject* js_obj, int entry);
   void ExtractInternalReferences(JSObject* js_obj, int entry);
 
@@ -434,6 +430,12 @@
                             Object* child,
                             const char* name_format_string = NULL,
                             int field_offset = -1);
+  void SetDataOrAccessorPropertyReference(PropertyKind kind,
+                                          JSObject* parent_obj, int parent,
+                                          Name* reference_name, Object* child,
+                                          const char* name_format_string = NULL,
+                                          int field_offset = -1);
+
   void SetUserGlobalReference(Object* user_global);
   void SetRootGcRootsReference();
   void SetGcRootsReference(VisitorSynchronization::SyncTag tag);
@@ -473,7 +475,6 @@
   NativeObjectsExplorer(HeapSnapshot* snapshot,
                         SnapshottingProgressReportingInterface* progress);
   virtual ~NativeObjectsExplorer();
-  void AddRootEntries(SnapshotFiller* filler);
   int EstimateObjectsCount();
   bool IterateAndExtractReferences(SnapshotFiller* filler);
 
@@ -506,7 +507,6 @@
   Isolate* isolate_;
   HeapSnapshot* snapshot_;
   StringsStorage* names_;
-  SnapshottingProgressReportingInterface* progress_;
   bool embedder_queried_;
   HeapObjectsSet in_groups_;
   // RetainedObjectInfo* -> List<HeapObject*>*
diff --git a/src/heap/gc-idle-time-handler-unittest.cc b/src/heap/gc-idle-time-handler-unittest.cc
deleted file mode 100644
index b4f2f74..0000000
--- a/src/heap/gc-idle-time-handler-unittest.cc
+++ /dev/null
@@ -1,348 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <limits>
-
-#include "src/heap/gc-idle-time-handler.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace v8 {
-namespace internal {
-
-namespace {
-
-class GCIdleTimeHandlerTest : public ::testing::Test {
- public:
-  GCIdleTimeHandlerTest() {}
-  virtual ~GCIdleTimeHandlerTest() {}
-
-  GCIdleTimeHandler* handler() { return &handler_; }
-
-  GCIdleTimeHandler::HeapState DefaultHeapState() {
-    GCIdleTimeHandler::HeapState result;
-    result.contexts_disposed = 0;
-    result.size_of_objects = kSizeOfObjects;
-    result.incremental_marking_stopped = false;
-    result.can_start_incremental_marking = true;
-    result.sweeping_in_progress = false;
-    result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed;
-    result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed;
-    result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed;
-    result.available_new_space_memory = kNewSpaceCapacity;
-    result.new_space_capacity = kNewSpaceCapacity;
-    result.new_space_allocation_throughput_in_bytes_per_ms =
-        kNewSpaceAllocationThroughput;
-    return result;
-  }
-
-  static const size_t kSizeOfObjects = 100 * MB;
-  static const size_t kMarkCompactSpeed = 200 * KB;
-  static const size_t kMarkingSpeed = 200 * KB;
-  static const size_t kScavengeSpeed = 100 * KB;
-  static const size_t kNewSpaceCapacity = 1 * MB;
-  static const size_t kNewSpaceAllocationThroughput = 10 * KB;
-
- private:
-  GCIdleTimeHandler handler_;
-};
-
-}  // namespace
-
-
-TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) {
-  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0);
-  EXPECT_EQ(
-      static_cast<size_t>(GCIdleTimeHandler::kInitialConservativeMarkingSpeed *
-                          GCIdleTimeHandler::kConservativeTimeRatio),
-      step_size);
-}
-
-
-TEST(GCIdleTimeHandler, EstimateMarkingStepSizeNonZero) {
-  size_t marking_speed_in_bytes_per_millisecond = 100;
-  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
-      1, marking_speed_in_bytes_per_millisecond);
-  EXPECT_EQ(static_cast<size_t>(marking_speed_in_bytes_per_millisecond *
-                                GCIdleTimeHandler::kConservativeTimeRatio),
-            step_size);
-}
-
-
-TEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow1) {
-  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
-      10, std::numeric_limits<size_t>::max());
-  EXPECT_EQ(static_cast<size_t>(GCIdleTimeHandler::kMaximumMarkingStepSize),
-            step_size);
-}
-
-
-TEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow2) {
-  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
-      std::numeric_limits<size_t>::max(), 10);
-  EXPECT_EQ(static_cast<size_t>(GCIdleTimeHandler::kMaximumMarkingStepSize),
-            step_size);
-}
-
-
-TEST(GCIdleTimeHandler, EstimateMarkCompactTimeInitial) {
-  size_t size = 100 * MB;
-  size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, 0);
-  EXPECT_EQ(size / GCIdleTimeHandler::kInitialConservativeMarkCompactSpeed,
-            time);
-}
-
-
-TEST(GCIdleTimeHandler, EstimateMarkCompactTimeNonZero) {
-  size_t size = 100 * MB;
-  size_t speed = 1 * MB;
-  size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed);
-  EXPECT_EQ(size / speed, time);
-}
-
-
-TEST(GCIdleTimeHandler, EstimateMarkCompactTimeMax) {
-  size_t size = std::numeric_limits<size_t>::max();
-  size_t speed = 1;
-  size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed);
-  EXPECT_EQ(GCIdleTimeHandler::kMaxMarkCompactTimeInMs, time);
-}
-
-
-TEST(GCIdleTimeHandler, EstimateScavengeTimeInitial) {
-  size_t size = 1 * MB;
-  size_t time = GCIdleTimeHandler::EstimateScavengeTime(size, 0);
-  EXPECT_EQ(size / GCIdleTimeHandler::kInitialConservativeScavengeSpeed, time);
-}
-
-
-TEST(GCIdleTimeHandler, EstimateScavengeTimeNonZero) {
-  size_t size = 1 * MB;
-  size_t speed = 1 * MB;
-  size_t time = GCIdleTimeHandler::EstimateScavengeTime(size, speed);
-  EXPECT_EQ(size / speed, time);
-}
-
-
-TEST(GCIdleTimeHandler, ScavangeMayHappenSoonInitial) {
-  size_t available = 100 * KB;
-  EXPECT_FALSE(GCIdleTimeHandler::ScavangeMayHappenSoon(available, 0));
-}
-
-
-TEST(GCIdleTimeHandler, ScavangeMayHappenSoonNonZeroFalse) {
-  size_t available = (GCIdleTimeHandler::kMaxFrameRenderingIdleTime + 1) * KB;
-  size_t speed = 1 * KB;
-  EXPECT_FALSE(GCIdleTimeHandler::ScavangeMayHappenSoon(available, speed));
-}
-
-
-TEST(GCIdleTimeHandler, ScavangeMayHappenSoonNonZeroTrue) {
-  size_t available = GCIdleTimeHandler::kMaxFrameRenderingIdleTime * KB;
-  size_t speed = 1 * KB;
-  EXPECT_TRUE(GCIdleTimeHandler::ScavangeMayHappenSoon(available, speed));
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeIdleTime) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  heap_state.contexts_disposed = 1;
-  heap_state.incremental_marking_stopped = true;
-  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
-  int idle_time_ms =
-      static_cast<int>((heap_state.size_of_objects + speed - 1) / speed);
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DO_FULL_GC, action.type);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  heap_state.contexts_disposed = 1;
-  heap_state.incremental_marking_stopped = true;
-  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
-  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed - 1);
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  heap_state.contexts_disposed = 1;
-  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
-  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed - 1);
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
-  int idle_time_ms = 10;
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
-  EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
-            static_cast<size_t>(action.parameter));
-  EXPECT_LT(0, action.parameter);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  heap_state.incremental_marking_stopped = true;
-  size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
-  int idle_time_ms = 10;
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
-  EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
-            static_cast<size_t>(action.parameter));
-  EXPECT_LT(0, action.parameter);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  heap_state.incremental_marking_stopped = true;
-  heap_state.can_start_incremental_marking = false;
-  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
-  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed - 1);
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DO_NOTHING, action.type);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, StopEventually1) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  heap_state.incremental_marking_stopped = true;
-  heap_state.can_start_incremental_marking = false;
-  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
-  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed + 1);
-  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
-    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-    EXPECT_EQ(DO_FULL_GC, action.type);
-    handler()->NotifyIdleMarkCompact();
-  }
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DONE, action.type);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, StopEventually2) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  int idle_time_ms = 10;
-  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
-    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-    EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
-    // In this case we emulate incremental marking steps that finish with a
-    // full gc.
-    handler()->NotifyIdleMarkCompact();
-  }
-  heap_state.can_start_incremental_marking = false;
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DONE, action.type);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  heap_state.incremental_marking_stopped = true;
-  heap_state.can_start_incremental_marking = false;
-  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
-  int idle_time_ms = static_cast<int>(heap_state.size_of_objects / speed + 1);
-  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
-    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-    EXPECT_EQ(DO_FULL_GC, action.type);
-    handler()->NotifyIdleMarkCompact();
-  }
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DONE, action.type);
-  // Emulate mutator work.
-  for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
-    handler()->NotifyScavenge();
-  }
-  action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DO_FULL_GC, action.type);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  int idle_time_ms = 10;
-  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
-    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-    if (action.type == DONE) break;
-    EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
-    // In this case we try to emulate incremental marking steps the finish with
-    // a full gc.
-    handler()->NotifyIdleMarkCompact();
-  }
-  heap_state.can_start_incremental_marking = false;
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DONE, action.type);
-  // Emulate mutator work.
-  for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
-    handler()->NotifyScavenge();
-  }
-  heap_state.can_start_incremental_marking = true;
-  action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, Scavenge) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  int idle_time_ms = 10;
-  heap_state.available_new_space_memory =
-      kNewSpaceAllocationThroughput * idle_time_ms;
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DO_SCAVENGE, action.type);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  int idle_time_ms = 10;
-  heap_state.can_start_incremental_marking = false;
-  heap_state.incremental_marking_stopped = true;
-  heap_state.available_new_space_memory =
-      kNewSpaceAllocationThroughput * idle_time_ms;
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DO_SCAVENGE, action.type);
-  heap_state.available_new_space_memory = kNewSpaceCapacity;
-  action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DO_NOTHING, action.type);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  int idle_time_ms = 0;
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  EXPECT_EQ(DO_NOTHING, action.type);
-}
-
-
-TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeDoNothingButStartIdleRound) {
-  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
-  int idle_time_ms = 10;
-  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
-    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-    if (action.type == DONE) break;
-    EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
-    // In this case we try to emulate incremental marking steps the finish with
-    // a full gc.
-    handler()->NotifyIdleMarkCompact();
-  }
-  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
-  // Emulate mutator work.
-  for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
-    handler()->NotifyScavenge();
-  }
-  action = handler()->Compute(0, heap_state);
-  EXPECT_EQ(DO_NOTHING, action.type);
-}
-
-}  // namespace internal
-}  // namespace v8
diff --git a/src/heap/gc-idle-time-handler.cc b/src/heap/gc-idle-time-handler.cc
index b9a99b2..ff2a559 100644
--- a/src/heap/gc-idle-time-handler.cc
+++ b/src/heap/gc-idle-time-handler.cc
@@ -11,9 +11,11 @@
 
 const double GCIdleTimeHandler::kConservativeTimeRatio = 0.9;
 const size_t GCIdleTimeHandler::kMaxMarkCompactTimeInMs = 1000;
+const size_t GCIdleTimeHandler::kMaxFinalIncrementalMarkCompactTimeInMs = 1000;
 const size_t GCIdleTimeHandler::kMinTimeForFinalizeSweeping = 100;
 const int GCIdleTimeHandler::kMaxMarkCompactsInIdleRound = 7;
 const int GCIdleTimeHandler::kIdleScavengeThreshold = 5;
+const double GCIdleTimeHandler::kHighContextDisposalRate = 100;
 
 
 void GCIdleTimeAction::Print() {
@@ -25,7 +27,11 @@
       PrintF("no action");
       break;
     case DO_INCREMENTAL_MARKING:
-      PrintF("incremental marking with step %" V8_PTR_PREFIX "d", parameter);
+      PrintF("incremental marking with step %" V8_PTR_PREFIX "d / ms",
+             parameter);
+      if (additional_work) {
+        PrintF("; finalized marking");
+      }
       break;
     case DO_SCAVENGE:
       PrintF("scavenge");
@@ -40,6 +46,25 @@
 }
 
 
+void GCIdleTimeHandler::HeapState::Print() {
+  PrintF("contexts_disposed=%d ", contexts_disposed);
+  PrintF("contexts_disposal_rate=%f ", contexts_disposal_rate);
+  PrintF("size_of_objects=%" V8_PTR_PREFIX "d ", size_of_objects);
+  PrintF("incremental_marking_stopped=%d ", incremental_marking_stopped);
+  PrintF("can_start_incremental_marking=%d ", can_start_incremental_marking);
+  PrintF("sweeping_in_progress=%d ", sweeping_in_progress);
+  PrintF("mark_compact_speed=%" V8_PTR_PREFIX "d ",
+         mark_compact_speed_in_bytes_per_ms);
+  PrintF("incremental_marking_speed=%" V8_PTR_PREFIX "d ",
+         incremental_marking_speed_in_bytes_per_ms);
+  PrintF("scavenge_speed=%" V8_PTR_PREFIX "d ", scavenge_speed_in_bytes_per_ms);
+  PrintF("new_space_size=%" V8_PTR_PREFIX "d ", used_new_space_size);
+  PrintF("new_space_capacity=%" V8_PTR_PREFIX "d ", new_space_capacity);
+  PrintF("new_space_allocation_throughput=%" V8_PTR_PREFIX "d",
+         new_space_allocation_throughput_in_bytes_per_ms);
+}
+
+
 size_t GCIdleTimeHandler::EstimateMarkingStepSize(
     size_t idle_time_in_ms, size_t marking_speed_in_bytes_per_ms) {
   DCHECK(idle_time_in_ms > 0);
@@ -63,6 +88,8 @@
 
 size_t GCIdleTimeHandler::EstimateMarkCompactTime(
     size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms) {
+  // TODO(hpayer): Be more precise about the type of mark-compact event. It
+  // makes a huge difference if compaction is happening.
   if (mark_compact_speed_in_bytes_per_ms == 0) {
     mark_compact_speed_in_bytes_per_ms = kInitialConservativeMarkCompactSpeed;
   }
@@ -71,73 +98,137 @@
 }
 
 
-size_t GCIdleTimeHandler::EstimateScavengeTime(
-    size_t new_space_size, size_t scavenge_speed_in_bytes_per_ms) {
-  if (scavenge_speed_in_bytes_per_ms == 0) {
-    scavenge_speed_in_bytes_per_ms = kInitialConservativeScavengeSpeed;
+size_t GCIdleTimeHandler::EstimateFinalIncrementalMarkCompactTime(
+    size_t size_of_objects,
+    size_t final_incremental_mark_compact_speed_in_bytes_per_ms) {
+  if (final_incremental_mark_compact_speed_in_bytes_per_ms == 0) {
+    final_incremental_mark_compact_speed_in_bytes_per_ms =
+        kInitialConservativeFinalIncrementalMarkCompactSpeed;
   }
-  return new_space_size / scavenge_speed_in_bytes_per_ms;
+  size_t result =
+      size_of_objects / final_incremental_mark_compact_speed_in_bytes_per_ms;
+  return Min(result, kMaxFinalIncrementalMarkCompactTimeInMs);
 }
 
 
-bool GCIdleTimeHandler::ScavangeMayHappenSoon(
-    size_t available_new_space_memory,
+bool GCIdleTimeHandler::ShouldDoScavenge(
+    size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size,
+    size_t scavenge_speed_in_bytes_per_ms,
     size_t new_space_allocation_throughput_in_bytes_per_ms) {
-  if (available_new_space_memory <=
-      new_space_allocation_throughput_in_bytes_per_ms *
-          kMaxFrameRenderingIdleTime) {
-    return true;
+  size_t new_space_allocation_limit =
+      kMaxFrameRenderingIdleTime * scavenge_speed_in_bytes_per_ms;
+
+  // If the limit is larger than the new space size, then scavenging used to be
+  // really fast. We can take advantage of the whole new space.
+  if (new_space_allocation_limit > new_space_size) {
+    new_space_allocation_limit = new_space_size;
+  }
+
+  // We do not know the allocation throughput before the first Scavenge.
+  // TODO(hpayer): Estimate allocation throughput before the first Scavenge.
+  if (new_space_allocation_throughput_in_bytes_per_ms == 0) {
+    new_space_allocation_limit =
+        static_cast<size_t>(new_space_size * kConservativeTimeRatio);
+  } else {
+    // We have to trigger scavenge before we reach the end of new space.
+    new_space_allocation_limit -=
+        new_space_allocation_throughput_in_bytes_per_ms *
+        kMaxFrameRenderingIdleTime;
+  }
+
+  if (scavenge_speed_in_bytes_per_ms == 0) {
+    scavenge_speed_in_bytes_per_ms = kInitialConservativeScavengeSpeed;
+  }
+
+  if (new_space_allocation_limit <= used_new_space_size) {
+    if (used_new_space_size / scavenge_speed_in_bytes_per_ms <=
+        idle_time_in_ms) {
+      return true;
+    }
   }
   return false;
 }
 
 
+bool GCIdleTimeHandler::ShouldDoMarkCompact(
+    size_t idle_time_in_ms, size_t size_of_objects,
+    size_t mark_compact_speed_in_bytes_per_ms) {
+  return idle_time_in_ms >=
+         EstimateMarkCompactTime(size_of_objects,
+                                 mark_compact_speed_in_bytes_per_ms);
+}
+
+
+bool GCIdleTimeHandler::ShouldDoContextDisposalMarkCompact(
+    int contexts_disposed, double contexts_disposal_rate) {
+  return contexts_disposed > 0 && contexts_disposal_rate > 0 &&
+         contexts_disposal_rate < kHighContextDisposalRate;
+}
+
+
+bool GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
+    size_t idle_time_in_ms, size_t size_of_objects,
+    size_t final_incremental_mark_compact_speed_in_bytes_per_ms) {
+  return idle_time_in_ms >=
+         EstimateFinalIncrementalMarkCompactTime(
+             size_of_objects,
+             final_incremental_mark_compact_speed_in_bytes_per_ms);
+}
+
+
 // The following logic is implemented by the controller:
-// (1) If the new space is almost full and we can effort a Scavenge, then a
-// Scavenge is performed.
-// (2) If there is currently no MarkCompact idle round going on, we start a
-// new idle round if enough garbage was created or we received a context
-// disposal event. Otherwise we do not perform garbage collection to keep
-// system utilization low.
-// (3) If incremental marking is done, we perform a full garbage collection
-// if context was disposed or if we are allowed to still do full garbage
-// collections during this idle round or if we are not allowed to start
-// incremental marking. Otherwise we do not perform garbage collection to
-// keep system utilization low.
-// (4) If sweeping is in progress and we received a large enough idle time
+// (1) If we don't have any idle time, do nothing, unless a context was
+// disposed, incremental marking is stopped, and the heap is small. Then do
+// a full GC.
+// (2) If the new space is almost full and we can affort a Scavenge or if the
+// next Scavenge will very likely take long, then a Scavenge is performed.
+// (3) If there is currently no MarkCompact idle round going on, we start a
+// new idle round if enough garbage was created. Otherwise we do not perform
+// garbage collection to keep system utilization low.
+// (4) If incremental marking is done, we perform a full garbage collection
+// if  we are allowed to still do full garbage collections during this idle
+// round or if we are not allowed to start incremental marking. Otherwise we
+// do not perform garbage collection to keep system utilization low.
+// (5) If sweeping is in progress and we received a large enough idle time
 // request, we finalize sweeping here.
-// (5) If incremental marking is in progress, we perform a marking step. Note,
+// (6) If incremental marking is in progress, we perform a marking step. Note,
 // that this currently may trigger a full garbage collection.
-GCIdleTimeAction GCIdleTimeHandler::Compute(size_t idle_time_in_ms,
+GCIdleTimeAction GCIdleTimeHandler::Compute(double idle_time_in_ms,
                                             HeapState heap_state) {
-  if (idle_time_in_ms <= kMaxFrameRenderingIdleTime &&
-      ScavangeMayHappenSoon(
-          heap_state.available_new_space_memory,
-          heap_state.new_space_allocation_throughput_in_bytes_per_ms) &&
-      idle_time_in_ms >=
-          EstimateScavengeTime(heap_state.new_space_capacity,
-                               heap_state.scavenge_speed_in_bytes_per_ms)) {
+  if (static_cast<int>(idle_time_in_ms) <= 0) {
+    if (heap_state.contexts_disposed > 0) {
+      StartIdleRound();
+    }
+    if (heap_state.incremental_marking_stopped) {
+      if (ShouldDoContextDisposalMarkCompact(
+              heap_state.contexts_disposed,
+              heap_state.contexts_disposal_rate)) {
+        return GCIdleTimeAction::FullGC();
+      }
+    }
+    return GCIdleTimeAction::Nothing();
+  }
+
+  if (ShouldDoScavenge(
+          static_cast<size_t>(idle_time_in_ms), heap_state.new_space_capacity,
+          heap_state.used_new_space_size,
+          heap_state.scavenge_speed_in_bytes_per_ms,
+          heap_state.new_space_allocation_throughput_in_bytes_per_ms)) {
     return GCIdleTimeAction::Scavenge();
   }
+
   if (IsMarkCompactIdleRoundFinished()) {
-    if (EnoughGarbageSinceLastIdleRound() || heap_state.contexts_disposed > 0) {
+    if (EnoughGarbageSinceLastIdleRound()) {
       StartIdleRound();
     } else {
       return GCIdleTimeAction::Done();
     }
   }
 
-  if (idle_time_in_ms == 0) {
-    return GCIdleTimeAction::Nothing();
-  }
-
   if (heap_state.incremental_marking_stopped) {
-    size_t estimated_time_in_ms =
-        EstimateMarkCompactTime(heap_state.size_of_objects,
-                                heap_state.mark_compact_speed_in_bytes_per_ms);
-    if (idle_time_in_ms >= estimated_time_in_ms ||
-        (heap_state.size_of_objects < kSmallHeapSize &&
-         heap_state.contexts_disposed > 0)) {
+    if (ShouldDoMarkCompact(static_cast<size_t>(idle_time_in_ms),
+                            heap_state.size_of_objects,
+                            heap_state.mark_compact_speed_in_bytes_per_ms)) {
       // If there are no more than two GCs left in this idle round and we are
       // allowed to do a full GC, then make those GCs full in order to compact
       // the code space.
@@ -145,10 +236,9 @@
       // can get rid of this special case and always start incremental marking.
       int remaining_mark_sweeps =
           kMaxMarkCompactsInIdleRound - mark_compacts_since_idle_round_started_;
-      if (heap_state.contexts_disposed > 0 ||
-          (idle_time_in_ms > kMaxFrameRenderingIdleTime &&
-           (remaining_mark_sweeps <= 2 ||
-            !heap_state.can_start_incremental_marking))) {
+      if (static_cast<size_t>(idle_time_in_ms) > kMaxFrameRenderingIdleTime &&
+          (remaining_mark_sweeps <= 2 ||
+           !heap_state.can_start_incremental_marking)) {
         return GCIdleTimeAction::FullGC();
       }
     }
@@ -158,7 +248,7 @@
   }
   // TODO(hpayer): Estimate finalize sweeping time.
   if (heap_state.sweeping_in_progress &&
-      idle_time_in_ms >= kMinTimeForFinalizeSweeping) {
+      static_cast<size_t>(idle_time_in_ms) >= kMinTimeForFinalizeSweeping) {
     return GCIdleTimeAction::FinalizeSweeping();
   }
 
@@ -167,7 +257,8 @@
     return GCIdleTimeAction::Nothing();
   }
   size_t step_size = EstimateMarkingStepSize(
-      idle_time_in_ms, heap_state.incremental_marking_speed_in_bytes_per_ms);
+      static_cast<size_t>(kIncrementalMarkingStepTimeInMs),
+      heap_state.incremental_marking_speed_in_bytes_per_ms);
   return GCIdleTimeAction::IncrementalMarking(step_size);
 }
 }
diff --git a/src/heap/gc-idle-time-handler.h b/src/heap/gc-idle-time-handler.h
index daab616..4dd190b 100644
--- a/src/heap/gc-idle-time-handler.h
+++ b/src/heap/gc-idle-time-handler.h
@@ -26,6 +26,7 @@
     GCIdleTimeAction result;
     result.type = DONE;
     result.parameter = 0;
+    result.additional_work = false;
     return result;
   }
 
@@ -33,6 +34,7 @@
     GCIdleTimeAction result;
     result.type = DO_NOTHING;
     result.parameter = 0;
+    result.additional_work = false;
     return result;
   }
 
@@ -40,6 +42,7 @@
     GCIdleTimeAction result;
     result.type = DO_INCREMENTAL_MARKING;
     result.parameter = step_size;
+    result.additional_work = false;
     return result;
   }
 
@@ -47,6 +50,7 @@
     GCIdleTimeAction result;
     result.type = DO_SCAVENGE;
     result.parameter = 0;
+    result.additional_work = false;
     return result;
   }
 
@@ -54,6 +58,7 @@
     GCIdleTimeAction result;
     result.type = DO_FULL_GC;
     result.parameter = 0;
+    result.additional_work = false;
     return result;
   }
 
@@ -61,6 +66,7 @@
     GCIdleTimeAction result;
     result.type = DO_FINALIZE_SWEEPING;
     result.parameter = 0;
+    result.additional_work = false;
     return result;
   }
 
@@ -68,6 +74,7 @@
 
   GCIdleTimeActionType type;
   intptr_t parameter;
+  bool additional_work;
 };
 
 
@@ -92,9 +99,18 @@
   // conservative lower bound for the mark-compact speed.
   static const size_t kInitialConservativeMarkCompactSpeed = 2 * MB;
 
+  // If we haven't recorded any final incremental mark-compact events yet, we
+  // use conservative lower bound for the mark-compact speed.
+  static const size_t kInitialConservativeFinalIncrementalMarkCompactSpeed =
+      2 * MB;
+
   // Maximum mark-compact time returned by EstimateMarkCompactTime.
   static const size_t kMaxMarkCompactTimeInMs;
 
+  // Maximum final incremental mark-compact time returned by
+  // EstimateFinalIncrementalMarkCompactTime.
+  static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
+
   // Minimum time to finalize sweeping phase. The main thread may wait for
   // sweeper threads.
   static const size_t kMinTimeForFinalizeSweeping;
@@ -106,31 +122,34 @@
   // Number of scavenges that will trigger start of new idle round.
   static const int kIdleScavengeThreshold;
 
-  // Heap size threshold below which we prefer mark-compact over incremental
-  // step.
-  static const size_t kSmallHeapSize = 4 * kPointerSize * MB;
-
   // That is the maximum idle time we will have during frame rendering.
   static const size_t kMaxFrameRenderingIdleTime = 16;
 
-  // If less than that much memory is left in the new space, we consider it
-  // as almost full and force a new space collection earlier in the idle time.
-  static const size_t kNewSpaceAlmostFullTreshold = 100 * KB;
-
   // If we haven't recorded any scavenger events yet, we use a conservative
   // lower bound for the scavenger speed.
   static const size_t kInitialConservativeScavengeSpeed = 100 * KB;
 
-  struct HeapState {
+  // If contexts are disposed at a higher rate a full gc is triggered.
+  static const double kHighContextDisposalRate;
+
+  // Incremental marking step time.
+  static const size_t kIncrementalMarkingStepTimeInMs = 1;
+
+  class HeapState {
+   public:
+    void Print();
+
     int contexts_disposed;
+    double contexts_disposal_rate;
     size_t size_of_objects;
     bool incremental_marking_stopped;
     bool can_start_incremental_marking;
     bool sweeping_in_progress;
     size_t mark_compact_speed_in_bytes_per_ms;
     size_t incremental_marking_speed_in_bytes_per_ms;
+    size_t final_incremental_mark_compact_speed_in_bytes_per_ms;
     size_t scavenge_speed_in_bytes_per_ms;
-    size_t available_new_space_memory;
+    size_t used_new_space_size;
     size_t new_space_capacity;
     size_t new_space_allocation_throughput_in_bytes_per_ms;
   };
@@ -139,7 +158,7 @@
       : mark_compacts_since_idle_round_started_(0),
         scavenges_since_last_idle_round_(0) {}
 
-  GCIdleTimeAction Compute(size_t idle_time_in_ms, HeapState heap_state);
+  GCIdleTimeAction Compute(double idle_time_in_ms, HeapState heap_state);
 
   void NotifyIdleMarkCompact() {
     if (mark_compacts_since_idle_round_started_ < kMaxMarkCompactsInIdleRound) {
@@ -159,11 +178,23 @@
   static size_t EstimateMarkCompactTime(
       size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
 
-  static size_t EstimateScavengeTime(size_t new_space_size,
-                                     size_t scavenger_speed_in_bytes_per_ms);
+  static size_t EstimateFinalIncrementalMarkCompactTime(
+      size_t size_of_objects, size_t mark_compact_speed_in_bytes_per_ms);
 
-  static bool ScavangeMayHappenSoon(
-      size_t available_new_space_memory,
+  static bool ShouldDoMarkCompact(size_t idle_time_in_ms,
+                                  size_t size_of_objects,
+                                  size_t mark_compact_speed_in_bytes_per_ms);
+
+  static bool ShouldDoContextDisposalMarkCompact(int context_disposed,
+                                                 double contexts_disposal_rate);
+
+  static bool ShouldDoFinalIncrementalMarkCompact(
+      size_t idle_time_in_ms, size_t size_of_objects,
+      size_t final_incremental_mark_compact_speed_in_bytes_per_ms);
+
+  static bool ShouldDoScavenge(
+      size_t idle_time_in_ms, size_t new_space_size, size_t used_new_space_size,
+      size_t scavenger_speed_in_bytes_per_ms,
       size_t new_space_allocation_throughput_in_bytes_per_ms);
 
  private:
diff --git a/src/heap/gc-tracer.cc b/src/heap/gc-tracer.cc
index 8a40b53..a35872d 100644
--- a/src/heap/gc-tracer.cc
+++ b/src/heap/gc-tracer.cc
@@ -26,6 +26,16 @@
 }
 
 
+GCTracer::ContextDisposalEvent::ContextDisposalEvent(double time) {
+  time_ = time;
+}
+
+
+GCTracer::SurvivalEvent::SurvivalEvent(double survival_rate) {
+  survival_rate_ = survival_rate;
+}
+
+
 GCTracer::Event::Event(Type type, const char* gc_reason,
                        const char* collector_reason)
     : type(type),
@@ -63,6 +73,7 @@
         return "Scavenge";
       }
     case MARK_COMPACTOR:
+    case INCREMENTAL_MARK_COMPACTOR:
       if (short_name) {
         return "ms";
       } else {
@@ -88,15 +99,19 @@
       longest_incremental_marking_step_(0.0),
       cumulative_marking_duration_(0.0),
       cumulative_sweeping_duration_(0.0),
-      new_space_top_after_gc_(0) {
+      new_space_top_after_gc_(0),
+      start_counter_(0) {
   current_ = Event(Event::START, NULL, NULL);
   current_.end_time = base::OS::TimeCurrentMillis();
-  previous_ = previous_mark_compactor_event_ = current_;
+  previous_ = previous_incremental_mark_compactor_event_ = current_;
 }
 
 
 void GCTracer::Start(GarbageCollector collector, const char* gc_reason,
                      const char* collector_reason) {
+  start_counter_++;
+  if (start_counter_ != 1) return;
+
   previous_ = current_;
   double start_time = base::OS::TimeCurrentMillis();
   if (new_space_top_after_gc_ != 0) {
@@ -105,13 +120,18 @@
         reinterpret_cast<intptr_t>((heap_->new_space()->top()) -
                                    new_space_top_after_gc_));
   }
-  if (current_.type == Event::MARK_COMPACTOR)
-    previous_mark_compactor_event_ = current_;
+  if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR)
+    previous_incremental_mark_compactor_event_ = current_;
 
   if (collector == SCAVENGER) {
     current_ = Event(Event::SCAVENGER, gc_reason, collector_reason);
-  } else {
-    current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason);
+  } else if (collector == MARK_COMPACTOR) {
+    if (heap_->incremental_marking()->WasActivated()) {
+      current_ =
+          Event(Event::INCREMENTAL_MARK_COMPACTOR, gc_reason, collector_reason);
+    } else {
+      current_ = Event(Event::MARK_COMPACTOR, gc_reason, collector_reason);
+    }
   }
 
   current_.start_time = start_time;
@@ -137,7 +157,23 @@
 }
 
 
-void GCTracer::Stop() {
+void GCTracer::Stop(GarbageCollector collector) {
+  start_counter_--;
+  if (start_counter_ != 0) {
+    if (FLAG_trace_gc) {
+      PrintF("[Finished reentrant %s during %s.]\n",
+             collector == SCAVENGER ? "Scavenge" : "Mark-sweep",
+             current_.TypeName(false));
+    }
+    return;
+  }
+
+  DCHECK(start_counter_ >= 0);
+  DCHECK((collector == SCAVENGER && current_.type == Event::SCAVENGER) ||
+         (collector == MARK_COMPACTOR &&
+          (current_.type == Event::MARK_COMPACTOR ||
+           current_.type == Event::INCREMENTAL_MARK_COMPACTOR)));
+
   current_.end_time = base::OS::TimeCurrentMillis();
   current_.end_object_size = heap_->SizeOfObjects();
   current_.end_memory_size = heap_->isolate()->memory_allocator()->Size();
@@ -159,21 +195,30 @@
         current_.cumulative_pure_incremental_marking_duration -
         previous_.cumulative_pure_incremental_marking_duration;
     scavenger_events_.push_front(current_);
-  } else {
+  } else if (current_.type == Event::INCREMENTAL_MARK_COMPACTOR) {
     current_.incremental_marking_steps =
         current_.cumulative_incremental_marking_steps -
-        previous_mark_compactor_event_.cumulative_incremental_marking_steps;
+        previous_incremental_mark_compactor_event_
+            .cumulative_incremental_marking_steps;
     current_.incremental_marking_bytes =
         current_.cumulative_incremental_marking_bytes -
-        previous_mark_compactor_event_.cumulative_incremental_marking_bytes;
+        previous_incremental_mark_compactor_event_
+            .cumulative_incremental_marking_bytes;
     current_.incremental_marking_duration =
         current_.cumulative_incremental_marking_duration -
-        previous_mark_compactor_event_.cumulative_incremental_marking_duration;
+        previous_incremental_mark_compactor_event_
+            .cumulative_incremental_marking_duration;
     current_.pure_incremental_marking_duration =
         current_.cumulative_pure_incremental_marking_duration -
-        previous_mark_compactor_event_
+        previous_incremental_mark_compactor_event_
             .cumulative_pure_incremental_marking_duration;
     longest_incremental_marking_step_ = 0.0;
+    incremental_mark_compactor_events_.push_front(current_);
+  } else {
+    DCHECK(current_.incremental_marking_bytes == 0);
+    DCHECK(current_.incremental_marking_duration == 0);
+    DCHECK(current_.pure_incremental_marking_duration == 0);
+    DCHECK(longest_incremental_marking_step_ == 0.0);
     mark_compactor_events_.push_front(current_);
   }
 
@@ -207,6 +252,16 @@
 }
 
 
+void GCTracer::AddContextDisposalTime(double time) {
+  context_disposal_events_.push_front(ContextDisposalEvent(time));
+}
+
+
+void GCTracer::AddSurvivalRate(double survival_rate) {
+  survival_events_.push_front(SurvivalEvent(survival_rate));
+}
+
+
 void GCTracer::AddIncrementalMarkingStep(double duration, intptr_t bytes) {
   cumulative_incremental_marking_steps_++;
   cumulative_incremental_marking_bytes_ += bytes;
@@ -294,6 +349,7 @@
          current_.scopes[Scope::MC_UPDATE_POINTERS_BETWEEN_EVACUATED]);
   PrintF("misc_compaction=%.1f ",
          current_.scopes[Scope::MC_UPDATE_MISC_POINTERS]);
+  PrintF("weak_closure=%.1f ", current_.scopes[Scope::MC_WEAKCLOSURE]);
   PrintF("weakcollection_process=%.1f ",
          current_.scopes[Scope::MC_WEAKCOLLECTION_PROCESS]);
   PrintF("weakcollection_clear=%.1f ",
@@ -315,10 +371,13 @@
   PrintF("nodes_died_in_new=%d ", heap_->nodes_died_in_new_space_);
   PrintF("nodes_copied_in_new=%d ", heap_->nodes_copied_in_new_space_);
   PrintF("nodes_promoted=%d ", heap_->nodes_promoted_);
+  PrintF("promotion_ratio=%.1f%% ", heap_->promotion_ratio_);
   PrintF("promotion_rate=%.1f%% ", heap_->promotion_rate_);
   PrintF("semi_space_copy_rate=%.1f%% ", heap_->semi_space_copied_rate_);
+  PrintF("average_survival_rate%.1f%% ", AverageSurvivalRate());
   PrintF("new_space_allocation_throughput=%" V8_PTR_PREFIX "d ",
          NewSpaceAllocationThroughputInBytesPerMillisecond());
+  PrintF("context_disposal_rate=%.1f ", ContextDisposalRateInMilliseconds());
 
   if (current_.type == Event::SCAVENGER) {
     PrintF("steps_count=%d ", current_.incremental_marking_steps);
@@ -370,15 +429,15 @@
 
   // We haven't completed an entire round of incremental marking, yet.
   // Use data from GCTracer instead of data from event buffers.
-  if (mark_compactor_events_.empty()) {
+  if (incremental_mark_compactor_events_.empty()) {
     return cumulative_incremental_marking_duration_ /
            cumulative_incremental_marking_steps_;
   }
 
   int steps = 0;
   double durations = 0.0;
-  EventBuffer::const_iterator iter = mark_compactor_events_.begin();
-  while (iter != mark_compactor_events_.end()) {
+  EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin();
+  while (iter != incremental_mark_compactor_events_.end()) {
     steps += iter->incremental_marking_steps;
     durations += iter->incremental_marking_duration;
     ++iter;
@@ -393,11 +452,12 @@
 double GCTracer::MaxIncrementalMarkingDuration() const {
   // We haven't completed an entire round of incremental marking, yet.
   // Use data from GCTracer instead of data from event buffers.
-  if (mark_compactor_events_.empty()) return longest_incremental_marking_step_;
+  if (incremental_mark_compactor_events_.empty())
+    return longest_incremental_marking_step_;
 
   double max_duration = 0.0;
-  EventBuffer::const_iterator iter = mark_compactor_events_.begin();
-  while (iter != mark_compactor_events_.end())
+  EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin();
+  while (iter != incremental_mark_compactor_events_.end())
     max_duration = Max(iter->longest_incremental_marking_step, max_duration);
 
   return max_duration;
@@ -409,15 +469,15 @@
 
   // We haven't completed an entire round of incremental marking, yet.
   // Use data from GCTracer instead of data from event buffers.
-  if (mark_compactor_events_.empty()) {
+  if (incremental_mark_compactor_events_.empty()) {
     return static_cast<intptr_t>(cumulative_incremental_marking_bytes_ /
                                  cumulative_pure_incremental_marking_duration_);
   }
 
   intptr_t bytes = 0;
   double durations = 0.0;
-  EventBuffer::const_iterator iter = mark_compactor_events_.begin();
-  while (iter != mark_compactor_events_.end()) {
+  EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin();
+  while (iter != incremental_mark_compactor_events_.end()) {
     bytes += iter->incremental_marking_bytes;
     durations += iter->pure_incremental_marking_duration;
     ++iter;
@@ -451,8 +511,24 @@
   EventBuffer::const_iterator iter = mark_compactor_events_.begin();
   while (iter != mark_compactor_events_.end()) {
     bytes += iter->start_object_size;
-    durations += iter->end_time - iter->start_time +
-                 iter->pure_incremental_marking_duration;
+    durations += iter->end_time - iter->start_time;
+    ++iter;
+  }
+
+  if (durations == 0.0) return 0;
+
+  return static_cast<intptr_t>(bytes / durations);
+}
+
+
+intptr_t GCTracer::FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()
+    const {
+  intptr_t bytes = 0;
+  double durations = 0.0;
+  EventBuffer::const_iterator iter = incremental_mark_compactor_events_.begin();
+  while (iter != incremental_mark_compactor_events_.end()) {
+    bytes += iter->start_object_size;
+    durations += iter->end_time - iter->start_time;
     ++iter;
   }
 
@@ -476,5 +552,43 @@
 
   return static_cast<intptr_t>(bytes / durations);
 }
+
+
+double GCTracer::ContextDisposalRateInMilliseconds() const {
+  if (context_disposal_events_.size() < kRingBufferMaxSize) return 0.0;
+
+  double begin = base::OS::TimeCurrentMillis();
+  double end = 0.0;
+  ContextDisposalEventBuffer::const_iterator iter =
+      context_disposal_events_.begin();
+  while (iter != context_disposal_events_.end()) {
+    end = iter->time_;
+    ++iter;
+  }
+
+  return (begin - end) / context_disposal_events_.size();
+}
+
+
+double GCTracer::AverageSurvivalRate() const {
+  if (survival_events_.size() == 0) return 0.0;
+
+  double sum_of_rates = 0.0;
+  SurvivalEventBuffer::const_iterator iter = survival_events_.begin();
+  while (iter != survival_events_.end()) {
+    sum_of_rates += iter->survival_rate_;
+    ++iter;
+  }
+
+  return sum_of_rates / static_cast<double>(survival_events_.size());
+}
+
+
+bool GCTracer::SurvivalEventsRecorded() const {
+  return survival_events_.size() > 0;
+}
+
+
+void GCTracer::ResetSurvivalEvents() { survival_events_.reset(); }
 }
 }  // namespace v8::internal
diff --git a/src/heap/gc-tracer.h b/src/heap/gc-tracer.h
index 4e70f07..528eb52 100644
--- a/src/heap/gc-tracer.h
+++ b/src/heap/gc-tracer.h
@@ -71,6 +71,11 @@
     elements_[begin_] = element;
   }
 
+  void reset() {
+    begin_ = 0;
+    end_ = 0;
+  }
+
  private:
   T elements_[MAX_SIZE + 1];
   size_t begin_;
@@ -103,6 +108,7 @@
       MC_UPDATE_POINTERS_TO_EVACUATED,
       MC_UPDATE_POINTERS_BETWEEN_EVACUATED,
       MC_UPDATE_MISC_POINTERS,
+      MC_WEAKCLOSURE,
       MC_WEAKCOLLECTION_PROCESS,
       MC_WEAKCOLLECTION_CLEAR,
       MC_WEAKCOLLECTION_ABORT,
@@ -145,9 +151,38 @@
     intptr_t allocation_in_bytes_;
   };
 
+
+  class ContextDisposalEvent {
+   public:
+    // Default constructor leaves the event uninitialized.
+    ContextDisposalEvent() {}
+
+    explicit ContextDisposalEvent(double time);
+
+    // Time when context disposal event happened.
+    double time_;
+  };
+
+
+  class SurvivalEvent {
+   public:
+    // Default constructor leaves the event uninitialized.
+    SurvivalEvent() {}
+
+    explicit SurvivalEvent(double survival_rate);
+
+    double survival_rate_;
+  };
+
+
   class Event {
    public:
-    enum Type { SCAVENGER = 0, MARK_COMPACTOR = 1, START = 2 };
+    enum Type {
+      SCAVENGER = 0,
+      MARK_COMPACTOR = 1,
+      INCREMENTAL_MARK_COMPACTOR = 2,
+      START = 3
+    };
 
     // Default constructor leaves the event uninitialized.
     Event() {}
@@ -198,7 +233,8 @@
 
     // Incremental marking steps since
     // - last event for SCAVENGER events
-    // - last MARK_COMPACTOR event for MARK_COMPACTOR events
+    // - last INCREMENTAL_MARK_COMPACTOR event for INCREMENTAL_MARK_COMPACTOR
+    // events
     int incremental_marking_steps;
 
     // Bytes marked since creation of tracer (value at start of event).
@@ -206,7 +242,8 @@
 
     // Bytes marked since
     // - last event for SCAVENGER events
-    // - last MARK_COMPACTOR event for MARK_COMPACTOR events
+    // - last INCREMENTAL_MARK_COMPACTOR event for INCREMENTAL_MARK_COMPACTOR
+    // events
     intptr_t incremental_marking_bytes;
 
     // Cumulative duration of incremental marking steps since creation of
@@ -215,7 +252,8 @@
 
     // Duration of incremental marking steps since
     // - last event for SCAVENGER events
-    // - last MARK_COMPACTOR event for MARK_COMPACTOR events
+    // - last INCREMENTAL_MARK_COMPACTOR event for INCREMENTAL_MARK_COMPACTOR
+    // events
     double incremental_marking_duration;
 
     // Cumulative pure duration of incremental marking steps since creation of
@@ -224,7 +262,8 @@
 
     // Duration of pure incremental marking steps since
     // - last event for SCAVENGER events
-    // - last MARK_COMPACTOR event for MARK_COMPACTOR events
+    // - last INCREMENTAL_MARK_COMPACTOR event for INCREMENTAL_MARK_COMPACTOR
+    // events
     double pure_incremental_marking_duration;
 
     // Longest incremental marking step since start of marking.
@@ -235,12 +274,17 @@
     double scopes[Scope::NUMBER_OF_SCOPES];
   };
 
-  static const int kRingBufferMaxSize = 10;
+  static const size_t kRingBufferMaxSize = 10;
 
   typedef RingBuffer<Event, kRingBufferMaxSize> EventBuffer;
 
   typedef RingBuffer<AllocationEvent, kRingBufferMaxSize> AllocationEventBuffer;
 
+  typedef RingBuffer<ContextDisposalEvent, kRingBufferMaxSize>
+      ContextDisposalEventBuffer;
+
+  typedef RingBuffer<SurvivalEvent, kRingBufferMaxSize> SurvivalEventBuffer;
+
   explicit GCTracer(Heap* heap);
 
   // Start collecting data.
@@ -248,11 +292,15 @@
              const char* collector_reason);
 
   // Stop collecting data and print results.
-  void Stop();
+  void Stop(GarbageCollector collector);
 
   // Log an allocation throughput event.
   void AddNewSpaceAllocationTime(double duration, intptr_t allocation_in_bytes);
 
+  void AddContextDisposalTime(double time);
+
+  void AddSurvivalRate(double survival_rate);
+
   // Log an incremental marking step.
   void AddIncrementalMarkingStep(double duration, intptr_t bytes);
 
@@ -298,6 +346,12 @@
     return MaxDuration(mark_compactor_events_);
   }
 
+  // Compute the mean duration of the last incremental mark compactor
+  // events. Returns 0 if no events have been recorded.
+  double MeanIncrementalMarkCompactorDuration() const {
+    return MeanDuration(incremental_mark_compactor_events_);
+  }
+
   // Compute the mean step duration of the last incremental marking round.
   // Returns 0 if no incremental marking round has been completed.
   double MeanIncrementalMarkingDuration() const;
@@ -314,14 +368,36 @@
   // Returns 0 if no events have been recorded.
   intptr_t ScavengeSpeedInBytesPerMillisecond() const;
 
-  // Compute the max mark-sweep speed in bytes/millisecond.
+  // Compute the average mark-sweep speed in bytes/millisecond.
   // Returns 0 if no events have been recorded.
   intptr_t MarkCompactSpeedInBytesPerMillisecond() const;
 
+  // Compute the average incremental mark-sweep finalize speed in
+  // bytes/millisecond.
+  // Returns 0 if no events have been recorded.
+  intptr_t FinalIncrementalMarkCompactSpeedInBytesPerMillisecond() const;
+
   // Allocation throughput in the new space in bytes/millisecond.
   // Returns 0 if no events have been recorded.
   intptr_t NewSpaceAllocationThroughputInBytesPerMillisecond() const;
 
+  // Computes the context disposal rate in milliseconds. It takes the time
+  // frame of the first recorded context disposal to the current time and
+  // divides it by the number of recorded events.
+  // Returns 0 if no events have been recorded.
+  double ContextDisposalRateInMilliseconds() const;
+
+  // Computes the average survival rate based on the last recorded survival
+  // events.
+  // Returns 0 if no events have been recorded.
+  double AverageSurvivalRate() const;
+
+  // Returns true if at least one survival event was recorded.
+  bool SurvivalEventsRecorded() const;
+
+  // Discard all recorded survival events.
+  void ResetSurvivalEvents();
+
  private:
   // Print one detailed trace line in name=value format.
   // TODO(ernstm): Move to Heap.
@@ -337,6 +413,16 @@
   // Compute the max duration of the events in the given ring buffer.
   double MaxDuration(const EventBuffer& events) const;
 
+  void ClearMarkCompactStatistics() {
+    cumulative_incremental_marking_steps_ = 0;
+    cumulative_incremental_marking_bytes_ = 0;
+    cumulative_incremental_marking_duration_ = 0;
+    cumulative_pure_incremental_marking_duration_ = 0;
+    longest_incremental_marking_step_ = 0;
+    cumulative_marking_duration_ = 0;
+    cumulative_sweeping_duration_ = 0;
+  }
+
   // Pointer to the heap that owns this tracer.
   Heap* heap_;
 
@@ -347,8 +433,8 @@
   // Previous tracer event.
   Event previous_;
 
-  // Previous MARK_COMPACTOR event.
-  Event previous_mark_compactor_event_;
+  // Previous INCREMENTAL_MARK_COMPACTOR event.
+  Event previous_incremental_mark_compactor_event_;
 
   // RingBuffers for SCAVENGER events.
   EventBuffer scavenger_events_;
@@ -356,9 +442,18 @@
   // RingBuffers for MARK_COMPACTOR events.
   EventBuffer mark_compactor_events_;
 
+  // RingBuffers for INCREMENTAL_MARK_COMPACTOR events.
+  EventBuffer incremental_mark_compactor_events_;
+
   // RingBuffer for allocation events.
   AllocationEventBuffer allocation_events_;
 
+  // RingBuffer for context disposal events.
+  ContextDisposalEventBuffer context_disposal_events_;
+
+  // RingBuffer for survival events.
+  SurvivalEventBuffer survival_events_;
+
   // Cumulative number of incremental marking steps since creation of tracer.
   int cumulative_incremental_marking_steps_;
 
@@ -393,6 +488,9 @@
   // collection.
   intptr_t new_space_top_after_gc_;
 
+  // Counts how many tracers were started without stopping.
+  int start_counter_;
+
   DISALLOW_COPY_AND_ASSIGN(GCTracer);
 };
 }
diff --git a/src/heap/heap-inl.h b/src/heap/heap-inl.h
index e658224..549ecbc 100644
--- a/src/heap/heap-inl.h
+++ b/src/heap/heap-inl.h
@@ -458,8 +458,6 @@
     case PROPERTY_CELL_SPACE:
     case LO_SPACE:
       return false;
-    case INVALID_SPACE:
-      break;
   }
   UNREACHABLE();
   return false;
@@ -589,7 +587,7 @@
 Isolate* Heap::isolate() {
   return reinterpret_cast<Isolate*>(
       reinterpret_cast<intptr_t>(this) -
-      reinterpret_cast<size_t>(reinterpret_cast<Isolate*>(4)->heap()) + 4);
+      reinterpret_cast<size_t>(reinterpret_cast<Isolate*>(16)->heap()) + 16);
 }
 
 
@@ -699,7 +697,7 @@
 
 
 void Heap::ClearInstanceofCache() {
-  set_instanceof_cache_function(the_hole_value());
+  set_instanceof_cache_function(Smi::FromInt(0));
 }
 
 
@@ -709,8 +707,8 @@
 
 
 void Heap::CompletelyClearInstanceofCache() {
-  set_instanceof_cache_map(the_hole_value());
-  set_instanceof_cache_function(the_hole_value());
+  set_instanceof_cache_map(Smi::FromInt(0));
+  set_instanceof_cache_function(Smi::FromInt(0));
 }
 
 
diff --git a/src/heap/heap.cc b/src/heap/heap.cc
index dfe60fe..0b817e4 100644
--- a/src/heap/heap.cc
+++ b/src/heap/heap.cc
@@ -28,6 +28,7 @@
 #include "src/natives.h"
 #include "src/runtime-profiler.h"
 #include "src/scopeinfo.h"
+#include "src/serialize.h"
 #include "src/snapshot.h"
 #include "src/utils.h"
 #include "src/v8threads.h"
@@ -60,7 +61,10 @@
       reserved_semispace_size_(8 * (kPointerSize / 4) * MB),
       max_semi_space_size_(8 * (kPointerSize / 4) * MB),
       initial_semispace_size_(Page::kPageSize),
+      target_semispace_size_(Page::kPageSize),
       max_old_generation_size_(700ul * (kPointerSize / 4) * MB),
+      initial_old_generation_size_(max_old_generation_size_ / 2),
+      old_generation_size_configured_(false),
       max_executable_size_(256ul * (kPointerSize / 4) * MB),
       // Variables set based on semispace_size_ and old_generation_size_ in
       // ConfigureHeap.
@@ -68,6 +72,7 @@
       // generation can be aligned to its size.
       maximum_committed_(0),
       survived_since_last_expansion_(0),
+      survived_last_scavenge_(0),
       sweep_generation_(0),
       always_allocate_scope_depth_(0),
       contexts_disposed_(0),
@@ -94,7 +99,7 @@
 #ifdef DEBUG
       allocation_timeout_(0),
 #endif  // DEBUG
-      old_generation_allocation_limit_(kMinimumOldGenerationAllocationLimit),
+      old_generation_allocation_limit_(initial_old_generation_size_),
       old_gen_exhausted_(false),
       inline_allocation_disabled_(false),
       store_buffer_rebuilder_(store_buffer()),
@@ -104,8 +109,9 @@
       tracer_(this),
       high_survival_rate_period_length_(0),
       promoted_objects_size_(0),
-      promotion_rate_(0),
+      promotion_ratio_(0),
       semi_space_copied_object_size_(0),
+      previous_semi_space_copied_object_size_(0),
       semi_space_copied_rate_(0),
       nodes_died_in_new_space_(0),
       nodes_copied_in_new_space_(0),
@@ -117,6 +123,7 @@
       min_in_mutator_(kMaxInt),
       marking_time_(0.0),
       sweeping_time_(0.0),
+      last_idle_notification_time_(0.0),
       mark_compact_collector_(this),
       store_buffer_(this),
       marking_(this),
@@ -133,7 +140,8 @@
       configured_(false),
       external_string_table_(this),
       chunks_queued_for_free_(NULL),
-      gc_callbacks_depth_(0) {
+      gc_callbacks_depth_(0),
+      deserialization_complete_(false) {
 // Allow build-time customization of the max semispace size. Building
 // V8 with snapshots and a non-default max semispace size is much
 // easier if you can define it as part of the build environment.
@@ -149,6 +157,7 @@
   set_array_buffers_list(Smi::FromInt(0));
   set_allocation_sites_list(Smi::FromInt(0));
   set_encountered_weak_collections(Smi::FromInt(0));
+  set_encountered_weak_cells(Smi::FromInt(0));
   // 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);
@@ -427,6 +436,7 @@
 
   // Reset GC statistics.
   promoted_objects_size_ = 0;
+  previous_semi_space_copied_object_size_ = semi_space_copied_object_size_;
   semi_space_copied_object_size_ = 0;
   nodes_died_in_new_space_ = 0;
   nodes_copied_in_new_space_ = 0;
@@ -763,7 +773,6 @@
   mark_compact_collector()->SetFlags(kNoGCFlags);
   new_space_.Shrink();
   UncommitFromSpace();
-  incremental_marking()->UncommitMarkingDeque();
 }
 
 
@@ -840,7 +849,7 @@
     }
 
     GarbageCollectionEpilogue();
-    tracer()->Stop();
+    tracer()->Stop(collector);
   }
 
   // Start incremental marking for the next cycle. The heap snapshot
@@ -854,13 +863,18 @@
 }
 
 
-int Heap::NotifyContextDisposed() {
+int Heap::NotifyContextDisposed(bool dependant_context) {
+  if (!dependant_context) {
+    tracer()->ResetSurvivalEvents();
+    old_generation_size_configured_ = false;
+  }
   if (isolate()->concurrent_recompilation_enabled()) {
     // Flush the queued recompilation tasks.
     isolate()->optimizing_compiler_thread()->Flush();
   }
   flush_monomorphic_ics_ = true;
   AgeInlineCaches();
+  tracer()->AddContextDisposalTime(base::OS::TimeCurrentMillis());
   return ++contexts_disposed_;
 }
 
@@ -917,47 +931,61 @@
 }
 
 
-void Heap::ReserveSpace(int* sizes, Address* locations_out) {
+bool Heap::ReserveSpace(Reservation* reservations) {
   bool gc_performed = true;
   int counter = 0;
   static const int kThreshold = 20;
   while (gc_performed && counter++ < kThreshold) {
     gc_performed = false;
-    DCHECK(NEW_SPACE == FIRST_PAGED_SPACE - 1);
-    for (int space = NEW_SPACE; space <= LAST_PAGED_SPACE; space++) {
-      if (sizes[space] != 0) {
-        AllocationResult allocation;
-        if (space == NEW_SPACE) {
-          allocation = new_space()->AllocateRaw(sizes[space]);
-        } else {
-          allocation = paged_space(space)->AllocateRaw(sizes[space]);
-        }
-        FreeListNode* node;
-        if (!allocation.To(&node)) {
+    for (int space = NEW_SPACE; space < Serializer::kNumberOfSpaces; space++) {
+      Reservation* reservation = &reservations[space];
+      DCHECK_LE(1, reservation->length());
+      if (reservation->at(0).size == 0) continue;
+      bool perform_gc = false;
+      if (space == LO_SPACE) {
+        DCHECK_EQ(1, reservation->length());
+        perform_gc = !lo_space()->CanAllocateSize(reservation->at(0).size);
+      } else {
+        for (auto& chunk : *reservation) {
+          AllocationResult allocation;
+          int size = chunk.size;
+          DCHECK_LE(size, MemoryAllocator::PageAreaSize(
+                              static_cast<AllocationSpace>(space)));
           if (space == NEW_SPACE) {
-            Heap::CollectGarbage(NEW_SPACE,
-                                 "failed to reserve space in the new space");
+            allocation = new_space()->AllocateRaw(size);
           } else {
-            AbortIncrementalMarkingAndCollectGarbage(
-                this, static_cast<AllocationSpace>(space),
-                "failed to reserve space in paged space");
+            allocation = paged_space(space)->AllocateRaw(size);
           }
-          gc_performed = true;
-          break;
-        } else {
-          // Mark with a free list node, in case we have a GC before
-          // deserializing.
-          node->set_size(this, sizes[space]);
-          locations_out[space] = node->address();
+          FreeListNode* node;
+          if (allocation.To(&node)) {
+            // Mark with a free list node, in case we have a GC before
+            // deserializing.
+            node->set_size(this, size);
+            DCHECK(space < Serializer::kNumberOfPreallocatedSpaces);
+            chunk.start = node->address();
+            chunk.end = node->address() + size;
+          } else {
+            perform_gc = true;
+            break;
+          }
         }
       }
+      if (perform_gc) {
+        if (space == NEW_SPACE) {
+          Heap::CollectGarbage(NEW_SPACE,
+                               "failed to reserve space in the new space");
+        } else {
+          AbortIncrementalMarkingAndCollectGarbage(
+              this, static_cast<AllocationSpace>(space),
+              "failed to reserve space in paged or large object space");
+        }
+        gc_performed = true;
+        break;  // Abort for-loop over spaces and retry.
+      }
     }
   }
 
-  if (gc_performed) {
-    // Failed to reserve the space after several attempts.
-    V8::FatalProcessOutOfMemory("Heap::ReserveSpace");
-  }
+  return !gc_performed;
 }
 
 
@@ -1016,14 +1044,23 @@
 void Heap::UpdateSurvivalStatistics(int start_new_space_size) {
   if (start_new_space_size == 0) return;
 
-  promotion_rate_ = (static_cast<double>(promoted_objects_size_) /
-                     static_cast<double>(start_new_space_size) * 100);
+  promotion_ratio_ = (static_cast<double>(promoted_objects_size_) /
+                      static_cast<double>(start_new_space_size) * 100);
+
+  if (previous_semi_space_copied_object_size_ > 0) {
+    promotion_rate_ =
+        (static_cast<double>(promoted_objects_size_) /
+         static_cast<double>(previous_semi_space_copied_object_size_) * 100);
+  } else {
+    promotion_rate_ = 0;
+  }
 
   semi_space_copied_rate_ =
       (static_cast<double>(semi_space_copied_object_size_) /
        static_cast<double>(start_new_space_size) * 100);
 
-  double survival_rate = promotion_rate_ + semi_space_copied_rate_;
+  double survival_rate = promotion_ratio_ + semi_space_copied_rate_;
+  tracer()->AddSurvivalRate(survival_rate);
 
   if (survival_rate > kYoungSurvivalRateHighThreshold) {
     high_survival_rate_period_length_++;
@@ -1081,11 +1118,13 @@
     old_generation_allocation_limit_ =
         OldGenerationAllocationLimit(PromotedSpaceSizeOfObjects(), 0);
     old_gen_exhausted_ = false;
+    old_generation_size_configured_ = true;
   } else {
     Scavenge();
   }
 
   UpdateSurvivalStatistics(start_new_space_size);
+  ConfigureInitialOldGenerationSize();
 
   isolate_->counters()->objs_since_last_young()->Set(0);
 
@@ -1113,6 +1152,9 @@
         amount_of_external_allocated_memory_;
     old_generation_allocation_limit_ = OldGenerationAllocationLimit(
         PromotedSpaceSizeOfObjects(), freed_global_handles);
+    // We finished a marking cycle. We can uncommit the marking deque until
+    // we start marking again.
+    mark_compact_collector_.UncommitMarkingDeque();
   }
 
   {
@@ -1187,15 +1229,22 @@
 
   LOG(isolate_, ResourceEvent("markcompact", "end"));
 
+  MarkCompactEpilogue();
+
+  if (FLAG_allocation_site_pretenuring) {
+    EvaluateOldSpaceLocalPretenuring(size_of_objects_before_gc);
+  }
+}
+
+
+void Heap::MarkCompactEpilogue() {
   gc_state_ = NOT_IN_GC;
 
   isolate_->counters()->objs_since_last_full()->Set(0);
 
   flush_monomorphic_ics_ = false;
 
-  if (FLAG_allocation_site_pretenuring) {
-    EvaluateOldSpaceLocalPretenuring(size_of_objects_before_gc);
-  }
+  incremental_marking()->Epilogue();
 }
 
 
@@ -1282,11 +1331,18 @@
 
 
 void Heap::CheckNewSpaceExpansionCriteria() {
-  if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() &&
-      survived_since_last_expansion_ > new_space_.TotalCapacity()) {
-    // Grow the size of new space if there is room to grow, enough data
-    // has survived scavenge since the last expansion and we are not in
-    // high promotion mode.
+  if (FLAG_experimental_new_space_growth_heuristic) {
+    if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() &&
+        survived_last_scavenge_ * 100 / new_space_.TotalCapacity() >= 10) {
+      // Grow the size of new space if there is room to grow, and more than 10%
+      // have survived the last scavenge.
+      new_space_.Grow();
+      survived_since_last_expansion_ = 0;
+    }
+  } else if (new_space_.TotalCapacity() < new_space_.MaximumCapacity() &&
+             survived_since_last_expansion_ > new_space_.TotalCapacity()) {
+    // Grow the size of new space if there is room to grow, and enough data
+    // has survived scavenge since the last expansion.
     new_space_.Grow();
     survived_since_last_expansion_ = 0;
   }
@@ -1383,6 +1439,10 @@
   while (head_start != head_end) {
     int size = static_cast<int>(*(head_start++));
     HeapObject* obj = reinterpret_cast<HeapObject*>(*(head_start++));
+    // New space allocation in SemiSpaceCopyObject marked the region
+    // overlapping with promotion queue as uninitialized.
+    MSAN_MEMORY_IS_INITIALIZED(&size, sizeof(size));
+    MSAN_MEMORY_IS_INITIALIZED(&obj, sizeof(obj));
     emergency_stack_->Add(Entry(obj, size));
   }
   rear_ = head_end;
@@ -1501,6 +1561,8 @@
 
   // Copy objects reachable from the encountered weak collections list.
   scavenge_visitor.VisitPointer(&encountered_weak_collections_);
+  // Copy objects reachable from the encountered weak cells.
+  scavenge_visitor.VisitPointer(&encountered_weak_cells_);
 
   // Copy objects reachable from the code flushing candidates list.
   MarkCompactCollector* collector = mark_compact_collector();
@@ -1517,9 +1579,10 @@
   isolate()->global_handles()->RemoveObjectGroups();
   isolate()->global_handles()->RemoveImplicitRefGroups();
 
-  isolate_->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
+  isolate()->global_handles()->IdentifyNewSpaceWeakIndependentHandles(
       &IsUnscavengedHeapObject);
-  isolate_->global_handles()->IterateNewSpaceWeakIndependentRoots(
+
+  isolate()->global_handles()->IterateNewSpaceWeakIndependentRoots(
       &scavenge_visitor);
   new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
 
@@ -1624,6 +1687,10 @@
   // TODO(mvstanton): AllocationSites only need to be processed during
   // MARK_COMPACT, as they live in old space. Verify and address.
   ProcessAllocationSites(retainer);
+  // Collects callback info for handles that are pending (about to be
+  // collected) and either phantom or internal-fields.  Releases the global
+  // handles.  See also PostGarbageCollectionProcessing.
+  isolate()->global_handles()->CollectPhantomCallbackData();
 }
 
 
@@ -1763,12 +1830,32 @@
         promotion_queue()->remove(&target, &size);
 
         // Promoted object might be already partially visited
-        // during old space pointer iteration. Thus we search specificly
+        // during old space pointer iteration. Thus we search specifically
         // for pointers to from semispace instead of looking for pointers
         // to new space.
         DCHECK(!target->IsMap());
-        IterateAndMarkPointersToFromSpace(
-            target->address(), target->address() + size, &ScavengeObject);
+        Address obj_address = target->address();
+#if V8_DOUBLE_FIELDS_UNBOXING
+        LayoutDescriptorHelper helper(target->map());
+        bool has_only_tagged_fields = helper.all_fields_tagged();
+
+        if (!has_only_tagged_fields) {
+          for (int offset = 0; offset < size;) {
+            int end_of_region_offset;
+            if (helper.IsTagged(offset, size, &end_of_region_offset)) {
+              IterateAndMarkPointersToFromSpace(
+                  obj_address + offset, obj_address + end_of_region_offset,
+                  &ScavengeObject);
+            }
+            offset = end_of_region_offset;
+          }
+        } else {
+#endif
+          IterateAndMarkPointersToFromSpace(obj_address, obj_address + size,
+                                            &ScavengeObject);
+#if V8_DOUBLE_FIELDS_UNBOXING
+        }
+#endif
       }
     }
 
@@ -1804,6 +1891,11 @@
 }
 
 
+HeapObject* Heap::DoubleAlignForDeserialization(HeapObject* object, int size) {
+  return EnsureDoubleAligned(this, object, size);
+}
+
+
 enum LoggingAndProfiling {
   LOGGING_AND_PROFILING_ENABLED,
   LOGGING_AND_PROFILING_DISABLED
@@ -2014,7 +2106,17 @@
       // 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.
-      *slot = target;
+
+      // Unfortunately, the allocation can also write over the slot if the slot
+      // was in free space and the allocation wrote free list data (such as the
+      // free list map or entry size) over the slot.  We guard against this by
+      // checking that the slot still points to the object being moved.  This
+      // should be sufficient because neither the free list map nor the free
+      // list entry size should look like a new space pointer (the former is an
+      // old space pointer, the latter is word-aligned).
+      if (*slot == object) {
+        *slot = target;
+      }
       MigrateObject(heap, object, target, object_size);
 
       if (object_contents == POINTER_OBJECT) {
@@ -2263,6 +2365,17 @@
 }
 
 
+void Heap::ConfigureInitialOldGenerationSize() {
+  if (!old_generation_size_configured_ && tracer()->SurvivalEventsRecorded()) {
+    old_generation_allocation_limit_ =
+        Max(kMinimumOldGenerationAllocationLimit,
+            static_cast<intptr_t>(
+                static_cast<double>(initial_old_generation_size_) *
+                (tracer()->AverageSurvivalRate() / 100)));
+  }
+}
+
+
 AllocationResult Heap::AllocatePartialMap(InstanceType instance_type,
                                           int instance_size) {
   Object* result;
@@ -2273,15 +2386,21 @@
   reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map());
   reinterpret_cast<Map*>(result)->set_instance_type(instance_type);
   reinterpret_cast<Map*>(result)->set_instance_size(instance_size);
+  // Initialize to only containing tagged fields.
   reinterpret_cast<Map*>(result)->set_visitor_id(
-      StaticVisitorBase::GetVisitorId(instance_type, instance_size));
+      StaticVisitorBase::GetVisitorId(instance_type, instance_size, false));
+  if (FLAG_unbox_double_fields) {
+    reinterpret_cast<Map*>(result)
+        ->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
+  }
   reinterpret_cast<Map*>(result)->set_inobject_properties(0);
   reinterpret_cast<Map*>(result)->set_pre_allocated_property_fields(0);
   reinterpret_cast<Map*>(result)->set_unused_property_fields(0);
   reinterpret_cast<Map*>(result)->set_bit_field(0);
   reinterpret_cast<Map*>(result)->set_bit_field2(0);
   int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
-                   Map::OwnsDescriptors::encode(true);
+                   Map::OwnsDescriptors::encode(true) |
+                   Map::Counter::encode(Map::kRetainingCounterStart);
   reinterpret_cast<Map*>(result)->set_bit_field3(bit_field3);
   return result;
 }
@@ -2297,8 +2416,6 @@
   result->set_map_no_write_barrier(meta_map());
   Map* map = Map::cast(result);
   map->set_instance_type(instance_type);
-  map->set_visitor_id(
-      StaticVisitorBase::GetVisitorId(instance_type, instance_size));
   map->set_prototype(null_value(), SKIP_WRITE_BARRIER);
   map->set_constructor(null_value(), SKIP_WRITE_BARRIER);
   map->set_instance_size(instance_size);
@@ -2310,10 +2427,17 @@
   map->init_back_pointer(undefined_value());
   map->set_unused_property_fields(0);
   map->set_instance_descriptors(empty_descriptor_array());
+  if (FLAG_unbox_double_fields) {
+    map->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
+  }
+  // Must be called only after |instance_type|, |instance_size| and
+  // |layout_descriptor| are set.
+  map->set_visitor_id(StaticVisitorBase::GetVisitorId(map));
   map->set_bit_field(0);
   map->set_bit_field2(1 << Map::kIsExtensible);
   int bit_field3 = Map::EnumLengthBits::encode(kInvalidEnumCacheSentinel) |
-                   Map::OwnsDescriptors::encode(true);
+                   Map::OwnsDescriptors::encode(true) |
+                   Map::Counter::encode(Map::kRetainingCounterStart);
   map->set_bit_field3(bit_field3);
   map->set_elements_kind(elements_kind);
 
@@ -2436,28 +2560,46 @@
   meta_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
   meta_map()->init_back_pointer(undefined_value());
   meta_map()->set_instance_descriptors(empty_descriptor_array());
+  if (FLAG_unbox_double_fields) {
+    meta_map()->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
+  }
 
   fixed_array_map()->set_code_cache(empty_fixed_array());
   fixed_array_map()->set_dependent_code(
       DependentCode::cast(empty_fixed_array()));
   fixed_array_map()->init_back_pointer(undefined_value());
   fixed_array_map()->set_instance_descriptors(empty_descriptor_array());
+  if (FLAG_unbox_double_fields) {
+    fixed_array_map()->set_layout_descriptor(
+        LayoutDescriptor::FastPointerLayout());
+  }
 
   undefined_map()->set_code_cache(empty_fixed_array());
   undefined_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
   undefined_map()->init_back_pointer(undefined_value());
   undefined_map()->set_instance_descriptors(empty_descriptor_array());
+  if (FLAG_unbox_double_fields) {
+    undefined_map()->set_layout_descriptor(
+        LayoutDescriptor::FastPointerLayout());
+  }
 
   null_map()->set_code_cache(empty_fixed_array());
   null_map()->set_dependent_code(DependentCode::cast(empty_fixed_array()));
   null_map()->init_back_pointer(undefined_value());
   null_map()->set_instance_descriptors(empty_descriptor_array());
+  if (FLAG_unbox_double_fields) {
+    null_map()->set_layout_descriptor(LayoutDescriptor::FastPointerLayout());
+  }
 
   constant_pool_array_map()->set_code_cache(empty_fixed_array());
   constant_pool_array_map()->set_dependent_code(
       DependentCode::cast(empty_fixed_array()));
   constant_pool_array_map()->init_back_pointer(undefined_value());
   constant_pool_array_map()->set_instance_descriptors(empty_descriptor_array());
+  if (FLAG_unbox_double_fields) {
+    constant_pool_array_map()->set_layout_descriptor(
+        LayoutDescriptor::FastPointerLayout());
+  }
 
   // Fix prototype object for existing maps.
   meta_map()->set_prototype(null_value());
@@ -2517,6 +2659,13 @@
       roots_[entry.index] = map;
     }
 
+    {  // Create a separate external one byte string map for native sources.
+      AllocationResult allocation = AllocateMap(EXTERNAL_ONE_BYTE_STRING_TYPE,
+                                                ExternalOneByteString::kSize);
+      if (!allocation.To(&obj)) return false;
+      set_native_source_string_map(Map::cast(obj));
+    }
+
     ALLOCATE_VARSIZE_MAP(STRING_TYPE, undetectable_string)
     undetectable_string_map()->set_is_undetectable();
 
@@ -2546,6 +2695,7 @@
 
     ALLOCATE_MAP(CELL_TYPE, Cell::kSize, cell)
     ALLOCATE_MAP(PROPERTY_CELL_TYPE, PropertyCell::kSize, global_property_cell)
+    ALLOCATE_MAP(WEAK_CELL_TYPE, WeakCell::kSize, weak_cell)
     ALLOCATE_MAP(FILLER_TYPE, kPointerSize, one_pointer_filler)
     ALLOCATE_MAP(FILLER_TYPE, 2 * kPointerSize, two_pointer_filler)
 
@@ -2565,7 +2715,8 @@
     ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, with_context)
     ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, block_context)
     ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, module_context)
-    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, global_context)
+    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, script_context)
+    ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, script_context_table)
 
     ALLOCATE_VARSIZE_MAP(FIXED_ARRAY_TYPE, native_context)
     native_context_map()->set_dictionary_map(true);
@@ -2672,6 +2823,22 @@
 }
 
 
+AllocationResult Heap::AllocateWeakCell(HeapObject* value) {
+  int size = WeakCell::kSize;
+  STATIC_ASSERT(WeakCell::kSize <= Page::kMaxRegularHeapObjectSize);
+  HeapObject* result;
+  {
+    AllocationResult allocation =
+        AllocateRaw(size, OLD_POINTER_SPACE, OLD_POINTER_SPACE);
+    if (!allocation.To(&result)) return allocation;
+  }
+  result->set_map_no_write_barrier(weak_cell_map());
+  WeakCell::cast(result)->initialize(value);
+  WeakCell::cast(result)->set_next(undefined_value(), SKIP_WRITE_BARRIER);
+  return result;
+}
+
+
 void Heap::CreateApiObjects() {
   HandleScope scope(isolate());
   Factory* factory = isolate()->factory();
@@ -2825,6 +2992,26 @@
   set_instanceof_cache_map(Smi::FromInt(0));
   set_instanceof_cache_answer(Smi::FromInt(0));
 
+  {
+    HandleScope scope(isolate());
+#define SYMBOL_INIT(name)                               \
+  Handle<Symbol> name = factory->NewPrivateOwnSymbol(); \
+  roots_[k##name##RootIndex] = *name;
+    PRIVATE_SYMBOL_LIST(SYMBOL_INIT)
+#undef SYMBOL_INIT
+  }
+
+  {
+    HandleScope scope(isolate());
+#define SYMBOL_INIT(name, varname, description)                             \
+  Handle<Symbol> name = factory->NewSymbol();                               \
+  Handle<String> name##d = factory->NewStringFromStaticChars(#description); \
+  name->set_name(*name##d);                                                 \
+  roots_[k##name##RootIndex] = *name;
+    PUBLIC_SYMBOL_LIST(SYMBOL_INIT)
+#undef SYMBOL_INIT
+  }
+
   CreateFixedStubs();
 
   // Allocate the dictionary of intrinsic function names.
@@ -2853,7 +3040,7 @@
   set_undefined_cell(*factory->NewCell(factory->undefined_value()));
 
   // The symbol registry is initialized lazily.
-  set_symbol_registry(undefined_value());
+  set_symbol_registry(Smi::FromInt(0));
 
   // Allocate object to hold object observation state.
   set_observation_state(*factory->NewJSObjectFromMap(
@@ -2863,19 +3050,6 @@
   // Number of queued microtasks stored in Isolate::pending_microtask_count().
   set_microtask_queue(empty_fixed_array());
 
-  set_detailed_stack_trace_symbol(*factory->NewPrivateOwnSymbol());
-  set_elements_transition_symbol(*factory->NewPrivateOwnSymbol());
-  set_frozen_symbol(*factory->NewPrivateOwnSymbol());
-  set_megamorphic_symbol(*factory->NewPrivateOwnSymbol());
-  set_premonomorphic_symbol(*factory->NewPrivateOwnSymbol());
-  set_generic_symbol(*factory->NewPrivateOwnSymbol());
-  set_nonexistent_symbol(*factory->NewPrivateOwnSymbol());
-  set_normal_ic_symbol(*factory->NewPrivateOwnSymbol());
-  set_observed_symbol(*factory->NewPrivateOwnSymbol());
-  set_stack_trace_symbol(*factory->NewPrivateOwnSymbol());
-  set_uninitialized_symbol(*factory->NewPrivateOwnSymbol());
-  set_home_object_symbol(*factory->NewPrivateOwnSymbol());
-
   Handle<SeededNumberDictionary> slow_element_dictionary =
       SeededNumberDictionary::New(isolate(), 0, TENURED);
   slow_element_dictionary->set_requires_slow_elements();
@@ -3681,12 +3855,14 @@
 
 
 AllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) {
-  // Never used to copy functions.  If functions need to be copied we
-  // have to be careful to clear the literals array.
-  SLOW_DCHECK(!source->IsJSFunction());
-
   // Make the clone.
   Map* map = source->map();
+
+  // We can only clone normal objects or arrays. Copying anything else
+  // will break invariants.
+  CHECK(map->instance_type() == JS_OBJECT_TYPE ||
+        map->instance_type() == JS_ARRAY_TYPE);
+
   int object_size = map->instance_size();
   HeapObject* clone;
 
@@ -4276,13 +4452,18 @@
 }
 
 
-void Heap::AdvanceIdleIncrementalMarking(intptr_t step_size) {
-  incremental_marking()->Step(step_size,
-                              IncrementalMarking::NO_GC_VIA_STACK_GUARD, true);
-
-  if (incremental_marking()->IsComplete()) {
-    IdleMarkCompact("idle notification: finalize incremental");
+bool Heap::TryFinalizeIdleIncrementalMarking(
+    double idle_time_in_ms, size_t size_of_objects,
+    size_t final_incremental_mark_compact_speed_in_bytes_per_ms) {
+  if (incremental_marking()->IsComplete() ||
+      (mark_compact_collector_.marking_deque()->IsEmpty() &&
+       gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact(
+           static_cast<size_t>(idle_time_in_ms), size_of_objects,
+           final_incremental_mark_compact_speed_in_bytes_per_ms))) {
+    CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental");
+    return true;
   }
+  return false;
 }
 
 
@@ -4292,56 +4473,91 @@
 }
 
 
+static double MonotonicallyIncreasingTimeInMs() {
+  return V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() *
+         static_cast<double>(base::Time::kMillisecondsPerSecond);
+}
+
+
 bool Heap::IdleNotification(int idle_time_in_ms) {
-  // If incremental marking is off, we do not perform idle notification.
-  if (!FLAG_incremental_marking) return true;
-  base::ElapsedTimer timer;
-  timer.Start();
-  isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
-      idle_time_in_ms);
+  return IdleNotification(
+      V8::GetCurrentPlatform()->MonotonicallyIncreasingTime() +
+      (static_cast<double>(idle_time_in_ms) /
+       static_cast<double>(base::Time::kMillisecondsPerSecond)));
+}
+
+
+bool Heap::IdleNotification(double deadline_in_seconds) {
+  double deadline_in_ms =
+      deadline_in_seconds *
+      static_cast<double>(base::Time::kMillisecondsPerSecond);
   HistogramTimerScope idle_notification_scope(
       isolate_->counters()->gc_idle_notification());
 
   GCIdleTimeHandler::HeapState heap_state;
   heap_state.contexts_disposed = contexts_disposed_;
+  heap_state.contexts_disposal_rate =
+      tracer()->ContextDisposalRateInMilliseconds();
   heap_state.size_of_objects = static_cast<size_t>(SizeOfObjects());
   heap_state.incremental_marking_stopped = incremental_marking()->IsStopped();
   // TODO(ulan): Start incremental marking only for large heaps.
   heap_state.can_start_incremental_marking =
-      incremental_marking()->ShouldActivate();
+      incremental_marking()->ShouldActivate() && FLAG_incremental_marking;
   heap_state.sweeping_in_progress =
       mark_compact_collector()->sweeping_in_progress();
   heap_state.mark_compact_speed_in_bytes_per_ms =
       static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond());
   heap_state.incremental_marking_speed_in_bytes_per_ms = static_cast<size_t>(
       tracer()->IncrementalMarkingSpeedInBytesPerMillisecond());
+  heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms =
+      static_cast<size_t>(
+          tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond());
   heap_state.scavenge_speed_in_bytes_per_ms =
       static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond());
-  heap_state.available_new_space_memory = new_space_.Available();
+  heap_state.used_new_space_size = new_space_.Size();
   heap_state.new_space_capacity = new_space_.Capacity();
   heap_state.new_space_allocation_throughput_in_bytes_per_ms =
       static_cast<size_t>(
           tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond());
 
+  double idle_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs();
   GCIdleTimeAction action =
       gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state);
+  isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample(
+      static_cast<int>(idle_time_in_ms));
 
   bool result = false;
   switch (action.type) {
     case DONE:
       result = true;
       break;
-    case DO_INCREMENTAL_MARKING:
+    case DO_INCREMENTAL_MARKING: {
       if (incremental_marking()->IsStopped()) {
         incremental_marking()->Start();
       }
-      AdvanceIdleIncrementalMarking(action.parameter);
+      double remaining_idle_time_in_ms = 0.0;
+      do {
+        incremental_marking()->Step(
+            action.parameter, IncrementalMarking::NO_GC_VIA_STACK_GUARD,
+            IncrementalMarking::FORCE_MARKING,
+            IncrementalMarking::DO_NOT_FORCE_COMPLETION);
+        remaining_idle_time_in_ms =
+            deadline_in_ms - MonotonicallyIncreasingTimeInMs();
+      } while (remaining_idle_time_in_ms >=
+                   2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs &&
+               !incremental_marking()->IsComplete() &&
+               !mark_compact_collector_.marking_deque()->IsEmpty());
+      if (remaining_idle_time_in_ms > 0.0) {
+        action.additional_work = TryFinalizeIdleIncrementalMarking(
+            remaining_idle_time_in_ms, heap_state.size_of_objects,
+            heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms);
+      }
       break;
+    }
     case DO_FULL_GC: {
-      HistogramTimerScope scope(isolate_->counters()->gc_context());
       if (contexts_disposed_) {
-        CollectAllGarbage(kReduceMemoryFootprintMask,
-                          "idle notification: contexts disposed");
+        HistogramTimerScope scope(isolate_->counters()->gc_context());
+        CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed");
         gc_idle_time_handler_.NotifyIdleMarkCompact();
         gc_count_at_last_idle_gc_ = gc_count_;
       } else {
@@ -4359,20 +4575,35 @@
       break;
   }
 
-  int actual_time_ms = static_cast<int>(timer.Elapsed().InMilliseconds());
-  if (actual_time_ms <= idle_time_in_ms) {
-    isolate()->counters()->gc_idle_time_limit_undershot()->AddSample(
-        idle_time_in_ms - actual_time_ms);
+  double current_time = MonotonicallyIncreasingTimeInMs();
+  last_idle_notification_time_ = current_time;
+  double deadline_difference = deadline_in_ms - current_time;
+
+  if (deadline_difference >= 0) {
+    if (action.type != DONE && action.type != DO_NOTHING) {
+      isolate()->counters()->gc_idle_time_limit_undershot()->AddSample(
+          static_cast<int>(deadline_difference));
+    }
   } else {
     isolate()->counters()->gc_idle_time_limit_overshot()->AddSample(
-        actual_time_ms - idle_time_in_ms);
+        static_cast<int>(-deadline_difference));
   }
 
-  if (FLAG_trace_idle_notification) {
-    PrintF("Idle notification: requested idle time %d ms, actual time %d ms [",
-           idle_time_in_ms, actual_time_ms);
+  if ((FLAG_trace_idle_notification && action.type > DO_NOTHING) ||
+      FLAG_trace_idle_notification_verbose) {
+    PrintF(
+        "Idle notification: requested idle time %.2f ms, used idle time %.2f "
+        "ms, deadline usage %.2f ms [",
+        idle_time_in_ms, idle_time_in_ms - deadline_difference,
+        deadline_difference);
     action.Print();
-    PrintF("]\n");
+    PrintF("]");
+    if (FLAG_trace_idle_notification_verbose) {
+      PrintF("[");
+      heap_state.Print();
+      PrintF("]");
+    }
+    PrintF("\n");
   }
 
   contexts_disposed_ = 0;
@@ -4380,6 +4611,13 @@
 }
 
 
+bool Heap::RecentIdleNotificationHappened() {
+  return (last_idle_notification_time_ +
+          GCIdleTimeHandler::kMaxFrameRenderingIdleTime) >
+         MonotonicallyIncreasingTimeInMs();
+}
+
+
 #ifdef DEBUG
 
 void Heap::Print() {
@@ -4482,14 +4720,25 @@
       return property_cell_space_->Contains(addr);
     case LO_SPACE:
       return lo_space_->SlowContains(addr);
-    case INVALID_SPACE:
-      break;
   }
   UNREACHABLE();
   return false;
 }
 
 
+bool Heap::RootIsImmortalImmovable(int root_index) {
+  switch (root_index) {
+#define CASE(name)               \
+  case Heap::k##name##RootIndex: \
+    return true;
+    IMMORTAL_IMMOVABLE_ROOT_LIST(CASE);
+#undef CASE
+    default:
+      return false;
+  }
+}
+
+
 #ifdef VERIFY_HEAP
 void Heap::Verify() {
   CHECK(HasBeenSetUp());
@@ -4893,9 +5142,9 @@
       initial_semispace_size_ = max_semi_space_size_;
       if (FLAG_trace_gc) {
         PrintPID(
-            "Min semi-space size cannot be more than the maximum"
+            "Min semi-space size cannot be more than the maximum "
             "semi-space size of %d MB\n",
-            max_semi_space_size_);
+            max_semi_space_size_ / MB);
       }
     } else {
       initial_semispace_size_ = initial_semispace_size;
@@ -4904,12 +5153,48 @@
 
   initial_semispace_size_ = Min(initial_semispace_size_, max_semi_space_size_);
 
+  if (FLAG_target_semi_space_size > 0) {
+    int target_semispace_size = FLAG_target_semi_space_size * MB;
+    if (target_semispace_size < initial_semispace_size_) {
+      target_semispace_size_ = initial_semispace_size_;
+      if (FLAG_trace_gc) {
+        PrintPID(
+            "Target semi-space size cannot be less than the minimum "
+            "semi-space size of %d MB\n",
+            initial_semispace_size_ / MB);
+      }
+    } else if (target_semispace_size > max_semi_space_size_) {
+      target_semispace_size_ = max_semi_space_size_;
+      if (FLAG_trace_gc) {
+        PrintPID(
+            "Target semi-space size cannot be less than the maximum "
+            "semi-space size of %d MB\n",
+            max_semi_space_size_ / MB);
+      }
+    } else {
+      target_semispace_size_ = target_semispace_size;
+    }
+  }
+
+  target_semispace_size_ = Max(initial_semispace_size_, target_semispace_size_);
+
+  if (FLAG_semi_space_growth_factor < 2) {
+    FLAG_semi_space_growth_factor = 2;
+  }
+
   // The old generation is paged and needs at least one page for each space.
   int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1;
   max_old_generation_size_ =
       Max(static_cast<intptr_t>(paged_space_count * Page::kPageSize),
           max_old_generation_size_);
 
+  if (FLAG_initial_old_space_size > 0) {
+    initial_old_generation_size_ = FLAG_initial_old_space_size * MB;
+  } else {
+    initial_old_generation_size_ = max_old_generation_size_ / 2;
+  }
+  old_generation_allocation_limit_ = initial_old_generation_size_;
+
   // We rely on being able to allocate new arrays in paged spaces.
   DCHECK(Page::kMaxRegularHeapObjectSize >=
          (JSArray::kSize +
@@ -5185,6 +5470,9 @@
 }
 
 
+void Heap::NotifyDeserializationComplete() { deserialization_complete_ = true; }
+
+
 void Heap::TearDown() {
 #ifdef VERIFY_HEAP
   if (FLAG_verify_heap) {
@@ -5202,7 +5490,7 @@
     PrintF("total_gc_time=%.1f ", total_gc_time_ms_);
     PrintF("min_in_mutator=%.1f ", get_min_in_mutator());
     PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ", get_max_alive_after_gc());
-    PrintF("total_marking_time=%.1f ", tracer_.cumulative_sweeping_duration());
+    PrintF("total_marking_time=%.1f ", tracer_.cumulative_marking_duration());
     PrintF("total_sweeping_time=%.1f ", tracer_.cumulative_sweeping_duration());
     PrintF("\n\n");
   }
@@ -5289,7 +5577,6 @@
   }
 
   store_buffer()->TearDown();
-  incremental_marking()->TearDown();
 
   isolate_->memory_allocator()->TearDown();
 }
diff --git a/src/heap/heap.gyp b/src/heap/heap.gyp
deleted file mode 100644
index 2970eb8..0000000
--- a/src/heap/heap.gyp
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2014 the V8 project authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
-  'variables': {
-    'v8_code': 1,
-  },
-  'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
-  'targets': [
-    {
-      'target_name': 'heap-unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../../testing/gtest.gyp:gtest',
-        '../../testing/gtest.gyp:gtest_main',
-        '../../tools/gyp/v8.gyp:v8_libplatform',
-      ],
-      'include_dirs': [
-        '../..',
-      ],
-      'sources': [  ### gcmole(all) ###
-        'gc-idle-time-handler-unittest.cc',
-      ],
-      'conditions': [
-        ['component=="shared_library"', {
-          # heap-unittests can't be built against a shared library, so we
-          # need to depend on the underlying static target in that case.
-          'conditions': [
-            ['v8_use_snapshot=="true"', {
-              'dependencies': ['../../tools/gyp/v8.gyp:v8_snapshot'],
-            },
-            {
-              'dependencies': [
-                '../../tools/gyp/v8.gyp:v8_nosnapshot',
-              ],
-            }],
-          ],
-        }, {
-          'dependencies': ['../../tools/gyp/v8.gyp:v8'],
-        }],
-        ['os_posix == 1', {
-          # TODO(svenpanne): This is a temporary work-around to fix the warnings
-          # that show up because we use -std=gnu++0x instead of -std=c++11.
-          'cflags!': [
-            '-pedantic',
-          ],
-        }],
-      ],
-    },
-  ],
-}
diff --git a/src/heap/heap.h b/src/heap/heap.h
index c9d0f31..e6ccf2e 100644
--- a/src/heap/heap.h
+++ b/src/heap/heap.h
@@ -52,6 +52,7 @@
   V(Map, fixed_cow_array_map, FixedCOWArrayMap)                                \
   V(Map, fixed_double_array_map, FixedDoubleArrayMap)                          \
   V(Map, constant_pool_array_map, ConstantPoolArrayMap)                        \
+  V(Map, weak_cell_map, WeakCellMap)                                           \
   V(Oddball, no_interceptor_result_sentinel, NoInterceptorResultSentinel)      \
   V(Map, hash_table_map, HashTableMap)                                         \
   V(Map, ordered_hash_table_map, OrderedHashTableMap)                          \
@@ -83,6 +84,7 @@
   V(Map, external_string_with_one_byte_data_map,                               \
     ExternalStringWithOneByteDataMap)                                          \
   V(Map, external_one_byte_string_map, ExternalOneByteStringMap)               \
+  V(Map, native_source_string_map, NativeSourceStringMap)                      \
   V(Map, short_external_string_map, ShortExternalStringMap)                    \
   V(Map, short_external_string_with_one_byte_data_map,                         \
     ShortExternalStringWithOneByteDataMap)                                     \
@@ -146,7 +148,8 @@
   V(Map, with_context_map, WithContextMap)                                     \
   V(Map, block_context_map, BlockContextMap)                                   \
   V(Map, module_context_map, ModuleContextMap)                                 \
-  V(Map, global_context_map, GlobalContextMap)                                 \
+  V(Map, script_context_map, ScriptContextMap)                                 \
+  V(Map, script_context_table_map, ScriptContextTableMap)                      \
   V(Map, undefined_map, UndefinedMap)                                          \
   V(Map, the_hole_map, TheHoleMap)                                             \
   V(Map, null_map, NullMap)                                                    \
@@ -175,20 +178,8 @@
   V(JSObject, observation_state, ObservationState)                             \
   V(Map, external_map, ExternalMap)                                            \
   V(Object, symbol_registry, SymbolRegistry)                                   \
-  V(Symbol, frozen_symbol, FrozenSymbol)                                       \
-  V(Symbol, nonexistent_symbol, NonExistentSymbol)                             \
-  V(Symbol, elements_transition_symbol, ElementsTransitionSymbol)              \
   V(SeededNumberDictionary, empty_slow_element_dictionary,                     \
     EmptySlowElementDictionary)                                                \
-  V(Symbol, observed_symbol, ObservedSymbol)                                   \
-  V(Symbol, uninitialized_symbol, UninitializedSymbol)                         \
-  V(Symbol, megamorphic_symbol, MegamorphicSymbol)                             \
-  V(Symbol, premonomorphic_symbol, PremonomorphicSymbol)                       \
-  V(Symbol, generic_symbol, GenericSymbol)                                     \
-  V(Symbol, stack_trace_symbol, StackTraceSymbol)                              \
-  V(Symbol, detailed_stack_trace_symbol, DetailedStackTraceSymbol)             \
-  V(Symbol, normal_ic_symbol, NormalICSymbol)                                  \
-  V(Symbol, home_object_symbol, HomeObjectSymbol)                              \
   V(FixedArray, materialized_objects, MaterializedObjects)                     \
   V(FixedArray, allocation_sites_scratchpad, AllocationSitesScratchpad)        \
   V(FixedArray, microtask_queue, MicrotaskQueue)
@@ -208,134 +199,171 @@
   SMI_ROOT_LIST(V)    \
   V(StringTable, string_table, StringTable)
 
-// Heap roots that are known to be immortal immovable, for which we can safely
-// skip write barriers.
-#define IMMORTAL_IMMOVABLE_ROOT_LIST(V) \
-  V(byte_array_map)                     \
-  V(free_space_map)                     \
-  V(one_pointer_filler_map)             \
-  V(two_pointer_filler_map)             \
-  V(undefined_value)                    \
-  V(the_hole_value)                     \
-  V(null_value)                         \
-  V(true_value)                         \
-  V(false_value)                        \
-  V(uninitialized_value)                \
-  V(cell_map)                           \
-  V(global_property_cell_map)           \
-  V(shared_function_info_map)           \
-  V(meta_map)                           \
-  V(heap_number_map)                    \
-  V(mutable_heap_number_map)            \
-  V(native_context_map)                 \
-  V(fixed_array_map)                    \
-  V(code_map)                           \
-  V(scope_info_map)                     \
-  V(fixed_cow_array_map)                \
-  V(fixed_double_array_map)             \
-  V(constant_pool_array_map)            \
-  V(no_interceptor_result_sentinel)     \
-  V(hash_table_map)                     \
-  V(ordered_hash_table_map)             \
-  V(empty_fixed_array)                  \
-  V(empty_byte_array)                   \
-  V(empty_descriptor_array)             \
-  V(empty_constant_pool_array)          \
-  V(arguments_marker)                   \
-  V(symbol_map)                         \
-  V(sloppy_arguments_elements_map)      \
-  V(function_context_map)               \
-  V(catch_context_map)                  \
-  V(with_context_map)                   \
-  V(block_context_map)                  \
-  V(module_context_map)                 \
-  V(global_context_map)                 \
-  V(undefined_map)                      \
-  V(the_hole_map)                       \
-  V(null_map)                           \
-  V(boolean_map)                        \
-  V(uninitialized_map)                  \
-  V(message_object_map)                 \
-  V(foreign_map)                        \
-  V(neander_map)
+#define INTERNALIZED_STRING_LIST(V)                        \
+  V(Object_string, "Object")                               \
+  V(proto_string, "__proto__")                             \
+  V(arguments_string, "arguments")                         \
+  V(Arguments_string, "Arguments")                         \
+  V(caller_string, "caller")                               \
+  V(boolean_string, "boolean")                             \
+  V(Boolean_string, "Boolean")                             \
+  V(callee_string, "callee")                               \
+  V(constructor_string, "constructor")                     \
+  V(dot_result_string, ".result")                          \
+  V(eval_string, "eval")                                   \
+  V(empty_string, "")                                      \
+  V(function_string, "function")                           \
+  V(Function_string, "Function")                           \
+  V(length_string, "length")                               \
+  V(name_string, "name")                                   \
+  V(null_string, "null")                                   \
+  V(number_string, "number")                               \
+  V(Number_string, "Number")                               \
+  V(nan_string, "NaN")                                     \
+  V(source_string, "source")                               \
+  V(source_url_string, "source_url")                       \
+  V(source_mapping_url_string, "source_mapping_url")       \
+  V(global_string, "global")                               \
+  V(ignore_case_string, "ignoreCase")                      \
+  V(multiline_string, "multiline")                         \
+  V(sticky_string, "sticky")                               \
+  V(harmony_regexps_string, "harmony_regexps")             \
+  V(input_string, "input")                                 \
+  V(index_string, "index")                                 \
+  V(last_index_string, "lastIndex")                        \
+  V(object_string, "object")                               \
+  V(prototype_string, "prototype")                         \
+  V(string_string, "string")                               \
+  V(String_string, "String")                               \
+  V(symbol_string, "symbol")                               \
+  V(Symbol_string, "Symbol")                               \
+  V(Map_string, "Map")                                     \
+  V(Set_string, "Set")                                     \
+  V(WeakMap_string, "WeakMap")                             \
+  V(WeakSet_string, "WeakSet")                             \
+  V(for_string, "for")                                     \
+  V(for_api_string, "for_api")                             \
+  V(for_intern_string, "for_intern")                       \
+  V(private_api_string, "private_api")                     \
+  V(private_intern_string, "private_intern")               \
+  V(Date_string, "Date")                                   \
+  V(char_at_string, "CharAt")                              \
+  V(undefined_string, "undefined")                         \
+  V(value_of_string, "valueOf")                            \
+  V(stack_string, "stack")                                 \
+  V(toJSON_string, "toJSON")                               \
+  V(KeyedLoadMonomorphic_string, "KeyedLoadMonomorphic")   \
+  V(KeyedStoreMonomorphic_string, "KeyedStoreMonomorphic") \
+  V(stack_overflow_string, "kStackOverflowBoilerplate")    \
+  V(illegal_access_string, "illegal access")               \
+  V(cell_value_string, "%cell_value")                      \
+  V(illegal_argument_string, "illegal argument")           \
+  V(identity_hash_string, "v8::IdentityHash")              \
+  V(closure_string, "(closure)")                           \
+  V(dot_string, ".")                                       \
+  V(compare_ic_string, "==")                               \
+  V(strict_compare_ic_string, "===")                       \
+  V(infinity_string, "Infinity")                           \
+  V(minus_infinity_string, "-Infinity")                    \
+  V(query_colon_string, "(?:)")                            \
+  V(Generator_string, "Generator")                         \
+  V(throw_string, "throw")                                 \
+  V(done_string, "done")                                   \
+  V(value_string, "value")                                 \
+  V(next_string, "next")                                   \
+  V(byte_length_string, "byteLength")                      \
+  V(byte_offset_string, "byteOffset")                      \
+  V(minus_zero_string, "-0")                               \
+  V(Array_string, "Array")                                 \
+  V(Error_string, "Error")                                 \
+  V(RegExp_string, "RegExp")
 
-#define INTERNALIZED_STRING_LIST(V)                                \
-  V(Object_string, "Object")                                       \
-  V(proto_string, "__proto__")                                     \
-  V(arguments_string, "arguments")                                 \
-  V(Arguments_string, "Arguments")                                 \
-  V(caller_string, "caller")                                       \
-  V(boolean_string, "boolean")                                     \
-  V(Boolean_string, "Boolean")                                     \
-  V(callee_string, "callee")                                       \
-  V(constructor_string, "constructor")                             \
-  V(dot_result_string, ".result")                                  \
-  V(dot_for_string, ".for.")                                       \
-  V(eval_string, "eval")                                           \
-  V(empty_string, "")                                              \
-  V(function_string, "function")                                   \
-  V(Function_string, "Function")                                   \
-  V(length_string, "length")                                       \
-  V(name_string, "name")                                           \
-  V(null_string, "null")                                           \
-  V(number_string, "number")                                       \
-  V(Number_string, "Number")                                       \
-  V(nan_string, "NaN")                                             \
-  V(source_string, "source")                                       \
-  V(source_url_string, "source_url")                               \
-  V(source_mapping_url_string, "source_mapping_url")               \
-  V(global_string, "global")                                       \
-  V(ignore_case_string, "ignoreCase")                              \
-  V(multiline_string, "multiline")                                 \
-  V(sticky_string, "sticky")                                       \
-  V(harmony_regexps_string, "harmony_regexps")                     \
-  V(input_string, "input")                                         \
-  V(index_string, "index")                                         \
-  V(last_index_string, "lastIndex")                                \
-  V(object_string, "object")                                       \
-  V(prototype_string, "prototype")                                 \
-  V(string_string, "string")                                       \
-  V(String_string, "String")                                       \
-  V(symbol_string, "symbol")                                       \
-  V(Symbol_string, "Symbol")                                       \
-  V(Map_string, "Map")                                             \
-  V(Set_string, "Set")                                             \
-  V(WeakMap_string, "WeakMap")                                     \
-  V(WeakSet_string, "WeakSet")                                     \
-  V(for_string, "for")                                             \
-  V(for_api_string, "for_api")                                     \
-  V(for_intern_string, "for_intern")                               \
-  V(private_api_string, "private_api")                             \
-  V(private_intern_string, "private_intern")                       \
-  V(Date_string, "Date")                                           \
-  V(char_at_string, "CharAt")                                      \
-  V(undefined_string, "undefined")                                 \
-  V(value_of_string, "valueOf")                                    \
-  V(stack_string, "stack")                                         \
-  V(toJSON_string, "toJSON")                                       \
-  V(KeyedLoadMonomorphic_string, "KeyedLoadMonomorphic")           \
-  V(KeyedStoreMonomorphic_string, "KeyedStoreMonomorphic")         \
-  V(stack_overflow_string, "kStackOverflowBoilerplate")            \
-  V(illegal_access_string, "illegal access")                       \
-  V(cell_value_string, "%cell_value")                              \
-  V(illegal_argument_string, "illegal argument")                   \
-  V(identity_hash_string, "v8::IdentityHash")                      \
-  V(closure_string, "(closure)")                                   \
-  V(dot_string, ".")                                               \
-  V(compare_ic_string, "==")                                       \
-  V(strict_compare_ic_string, "===")                               \
-  V(infinity_string, "Infinity")                                   \
-  V(minus_infinity_string, "-Infinity")                            \
-  V(query_colon_string, "(?:)")                                    \
-  V(Generator_string, "Generator")                                 \
-  V(throw_string, "throw")                                         \
-  V(done_string, "done")                                           \
-  V(value_string, "value")                                         \
-  V(next_string, "next")                                           \
-  V(byte_length_string, "byteLength")                              \
-  V(byte_offset_string, "byteOffset")                              \
-  V(intl_initialized_marker_string, "v8::intl_initialized_marker") \
-  V(intl_impl_object_string, "v8::intl_object")
+#define PRIVATE_SYMBOL_LIST(V)      \
+  V(nonextensible_symbol)           \
+  V(sealed_symbol)                  \
+  V(frozen_symbol)                  \
+  V(nonexistent_symbol)             \
+  V(elements_transition_symbol)     \
+  V(prototype_users_symbol)         \
+  V(observed_symbol)                \
+  V(uninitialized_symbol)           \
+  V(megamorphic_symbol)             \
+  V(premonomorphic_symbol)          \
+  V(generic_symbol)                 \
+  V(stack_trace_symbol)             \
+  V(detailed_stack_trace_symbol)    \
+  V(normal_ic_symbol)               \
+  V(home_object_symbol)             \
+  V(intl_initialized_marker_symbol) \
+  V(intl_impl_object_symbol)        \
+  V(promise_debug_marker_symbol)    \
+  V(promise_has_handler_symbol)     \
+  V(class_script_symbol)            \
+  V(class_start_position_symbol)    \
+  V(class_end_position_symbol)
+
+#define PUBLIC_SYMBOL_LIST(V)                                    \
+  V(has_instance_symbol, symbolHasInstance, Symbol.hasInstance)  \
+  V(is_concat_spreadable_symbol, symbolIsConcatSpreadable,       \
+    Symbol.isConcatSpreadable)                                   \
+  V(is_regexp_symbol, symbolIsRegExp, Symbol.isRegExp)           \
+  V(iterator_symbol, symbolIterator, Symbol.iterator)            \
+  V(to_string_tag_symbol, symbolToStringTag, Symbol.toStringTag) \
+  V(unscopables_symbol, symbolUnscopables, Symbol.unscopables)
+
+// Heap roots that are known to be immortal immovable, for which we can safely
+// skip write barriers. This list is not complete and has omissions.
+#define IMMORTAL_IMMOVABLE_ROOT_LIST(V) \
+  V(ByteArrayMap)                       \
+  V(FreeSpaceMap)                       \
+  V(OnePointerFillerMap)                \
+  V(TwoPointerFillerMap)                \
+  V(UndefinedValue)                     \
+  V(TheHoleValue)                       \
+  V(NullValue)                          \
+  V(TrueValue)                          \
+  V(FalseValue)                         \
+  V(UninitializedValue)                 \
+  V(CellMap)                            \
+  V(GlobalPropertyCellMap)              \
+  V(SharedFunctionInfoMap)              \
+  V(MetaMap)                            \
+  V(HeapNumberMap)                      \
+  V(MutableHeapNumberMap)               \
+  V(NativeContextMap)                   \
+  V(FixedArrayMap)                      \
+  V(CodeMap)                            \
+  V(ScopeInfoMap)                       \
+  V(FixedCOWArrayMap)                   \
+  V(FixedDoubleArrayMap)                \
+  V(ConstantPoolArrayMap)               \
+  V(WeakCellMap)                        \
+  V(NoInterceptorResultSentinel)        \
+  V(HashTableMap)                       \
+  V(OrderedHashTableMap)                \
+  V(EmptyFixedArray)                    \
+  V(EmptyByteArray)                     \
+  V(EmptyDescriptorArray)               \
+  V(EmptyConstantPoolArray)             \
+  V(ArgumentsMarker)                    \
+  V(SymbolMap)                          \
+  V(SloppyArgumentsElementsMap)         \
+  V(FunctionContextMap)                 \
+  V(CatchContextMap)                    \
+  V(WithContextMap)                     \
+  V(BlockContextMap)                    \
+  V(ModuleContextMap)                   \
+  V(ScriptContextMap)                   \
+  V(UndefinedMap)                       \
+  V(TheHoleMap)                         \
+  V(NullMap)                            \
+  V(BooleanMap)                         \
+  V(UninitializedMap)                   \
+  V(ArgumentsMarkerMap)                 \
+  V(JSMessageObjectMap)                 \
+  V(ForeignMap)                         \
+  V(NeanderMap)                         \
+  PRIVATE_SYMBOL_LIST(V)
 
 // Forward declarations.
 class HeapStats;
@@ -538,6 +566,10 @@
   // jslimit_/real_jslimit_ variable in the StackGuard.
   void SetStackLimits();
 
+  // Notifies the heap that is ok to start marking or other activities that
+  // should not happen during deserialization.
+  void NotifyDeserializationComplete();
+
   // Returns whether SetUp has been called.
   bool HasBeenSetUp();
 
@@ -552,6 +584,7 @@
   int MaxSemiSpaceSize() { return max_semi_space_size_; }
   int ReservedSemiSpaceSize() { return reserved_semispace_size_; }
   int InitialSemiSpaceSize() { return initial_semispace_size_; }
+  int TargetSemiSpaceSize() { return target_semispace_size_; }
   intptr_t MaxOldGenerationSize() { return max_old_generation_size_; }
   intptr_t MaxExecutableSize() { return max_executable_size_; }
 
@@ -734,7 +767,7 @@
   bool IsHeapIterable();
 
   // Notify the heap that a context has been disposed.
-  int NotifyContextDisposed();
+  int NotifyContextDisposed(bool dependant_context);
 
   inline void increment_scan_on_scavenge_pages() {
     scan_on_scavenge_pages_++;
@@ -783,6 +816,16 @@
   INTERNALIZED_STRING_LIST(STRING_ACCESSOR)
 #undef STRING_ACCESSOR
 
+#define SYMBOL_ACCESSOR(name) \
+  Symbol* name() { return Symbol::cast(roots_[k##name##RootIndex]); }
+  PRIVATE_SYMBOL_LIST(SYMBOL_ACCESSOR)
+#undef SYMBOL_ACCESSOR
+
+#define SYMBOL_ACCESSOR(name, varname, description) \
+  Symbol* name() { return Symbol::cast(roots_[k##name##RootIndex]); }
+  PUBLIC_SYMBOL_LIST(SYMBOL_ACCESSOR)
+#undef SYMBOL_ACCESSOR
+
   // The hidden_string is special because it is the empty string, but does
   // not match the empty string.
   String* hidden_string() { return hidden_string_; }
@@ -812,6 +855,11 @@
     return encountered_weak_collections_;
   }
 
+  void set_encountered_weak_cells(Object* weak_cell) {
+    encountered_weak_cells_ = weak_cell;
+  }
+  Object* encountered_weak_cells() const { return encountered_weak_cells_; }
+
   // Number of mark-sweeps.
   unsigned int ms_count() { return ms_count_; }
 
@@ -899,6 +947,8 @@
     return reinterpret_cast<Address*>(&roots_[kStoreBufferTopRootIndex]);
   }
 
+  static bool RootIsImmortalImmovable(int root_index);
+
 #ifdef VERIFY_HEAP
   // Verify the heap is in its normal state before or after a GC.
   void Verify();
@@ -985,7 +1035,16 @@
 
   // Support for partial snapshots.  After calling this we have a linear
   // space to write objects in each space.
-  void ReserveSpace(int* sizes, Address* addresses);
+  struct Chunk {
+    uint32_t size;
+    Address start;
+    Address end;
+  };
+
+  typedef List<Chunk> Reservation;
+
+  // Returns false if not able to reserve.
+  bool ReserveSpace(Reservation* reservations);
 
   //
   // Support for the API.
@@ -1048,6 +1107,7 @@
   void DisableInlineAllocation();
 
   // Implements the corresponding V8 API function.
+  bool IdleNotification(double deadline_in_seconds);
   bool IdleNotification(int idle_time_in_ms);
 
   // Declare all the root indices.  This defines the root list order.
@@ -1060,6 +1120,14 @@
     INTERNALIZED_STRING_LIST(STRING_INDEX_DECLARATION)
 #undef STRING_DECLARATION
 
+#define SYMBOL_INDEX_DECLARATION(name) k##name##RootIndex,
+    PRIVATE_SYMBOL_LIST(SYMBOL_INDEX_DECLARATION)
+#undef SYMBOL_INDEX_DECLARATION
+
+#define SYMBOL_INDEX_DECLARATION(name, varname, description) k##name##RootIndex,
+    PUBLIC_SYMBOL_LIST(SYMBOL_INDEX_DECLARATION)
+#undef SYMBOL_INDEX_DECLARATION
+
 // Utility type maps
 #define DECLARE_STRUCT_MAP(NAME, Name, name) k##Name##MapRootIndex,
     STRUCT_LIST(DECLARE_STRUCT_MAP)
@@ -1074,6 +1142,8 @@
     kSmiRootsStart = kStringTableRootIndex + 1
   };
 
+  Object* root(RootListIndex index) { return roots_[index]; }
+
   STATIC_ASSERT(kUndefinedValueRootIndex ==
                 Internals::kUndefinedValueRootIndex);
   STATIC_ASSERT(kNullValueRootIndex == Internals::kNullValueRootIndex);
@@ -1129,6 +1199,7 @@
 
   inline void IncrementYoungSurvivorsCounter(int survived) {
     DCHECK(survived >= 0);
+    survived_last_scavenge_ = survived;
     survived_since_last_expansion_ += survived;
   }
 
@@ -1227,6 +1298,8 @@
 
   int gc_count() const { return gc_count_; }
 
+  bool RecentIdleNotificationHappened();
+
   // Completely clear the Instanceof cache (to stop it keeping objects alive
   // around a GC).
   inline void CompletelyClearInstanceofCache();
@@ -1364,6 +1437,8 @@
   inline void OnMoveEvent(HeapObject* target, HeapObject* source,
                           int size_in_bytes);
 
+  bool deserialization_complete() const { return deserialization_complete_; }
+
  protected:
   // Methods made available to tests.
 
@@ -1429,7 +1504,10 @@
   int reserved_semispace_size_;
   int max_semi_space_size_;
   int initial_semispace_size_;
+  int target_semispace_size_;
   intptr_t max_old_generation_size_;
+  intptr_t initial_old_generation_size_;
+  bool old_generation_size_configured_;
   intptr_t max_executable_size_;
   intptr_t maximum_committed_;
 
@@ -1437,6 +1515,9 @@
   // scavenge since last new space expansion.
   int survived_since_last_expansion_;
 
+  // ... and since the last scavenge.
+  int survived_last_scavenge_;
+
   // For keeping track on when to flush RegExp code.
   int sweep_generation_;
 
@@ -1536,6 +1617,8 @@
   // contains Smi(0) while marking is not active.
   Object* encountered_weak_collections_;
 
+  Object* encountered_weak_cells_;
+
   StoreBufferRebuilder store_buffer_rebuilder_;
 
   struct StringTypeTable {
@@ -1655,6 +1738,8 @@
     return (pretenure == TENURED) ? preferred_old_space : NEW_SPACE;
   }
 
+  HeapObject* DoubleAlignForDeserialization(HeapObject* object, int size);
+
   // Allocate an uninitialized object.  The memory is non-executable if the
   // hardware and OS allow.  This is the single choke-point for allocations
   // performed by the runtime and should not be bypassed (to extend this to
@@ -1816,6 +1901,8 @@
   // Allocate a tenured JS global property cell initialized with the hole.
   MUST_USE_RESULT AllocationResult AllocatePropertyCell();
 
+  MUST_USE_RESULT AllocationResult AllocateWeakCell(HeapObject* value);
+
   // Allocates a new utility object in the old generation.
   MUST_USE_RESULT AllocationResult AllocateStruct(InstanceType type);
 
@@ -1854,6 +1941,7 @@
 
   // Code to be run before and after mark-compact.
   void MarkCompactPrologue();
+  void MarkCompactEpilogue();
 
   void ProcessNativeContexts(WeakObjectRetainer* retainer);
   void ProcessArrayBuffers(WeakObjectRetainer* retainer);
@@ -1907,8 +1995,10 @@
 
   int high_survival_rate_period_length_;
   intptr_t promoted_objects_size_;
+  double promotion_ratio_;
   double promotion_rate_;
   intptr_t semi_space_copied_object_size_;
+  intptr_t previous_semi_space_copied_object_size_;
   double semi_space_copied_rate_;
   int nodes_died_in_new_space_;
   int nodes_copied_in_new_space_;
@@ -1924,11 +2014,15 @@
   // Re-visit incremental marking heuristics.
   bool IsHighSurvivalRate() { return high_survival_rate_period_length_ > 0; }
 
+  void ConfigureInitialOldGenerationSize();
+
   void SelectScavengingVisitorsTable();
 
   void IdleMarkCompact(const char* message);
 
-  void AdvanceIdleIncrementalMarking(intptr_t step_size);
+  bool TryFinalizeIdleIncrementalMarking(
+      double idle_time_in_ms, size_t size_of_objects,
+      size_t mark_compact_speed_in_bytes_per_ms);
 
   bool WorthActivatingIncrementalMarking();
 
@@ -1975,6 +2069,9 @@
   // Cumulative GC time spent in sweeping
   double sweeping_time_;
 
+  // Last time an idle notification happened
+  double last_idle_notification_time_;
+
   MarkCompactCollector mark_compact_collector_;
 
   StoreBuffer store_buffer_;
@@ -2022,7 +2119,10 @@
 
   int gc_callbacks_depth_;
 
+  bool deserialization_complete_;
+
   friend class AlwaysAllocateScope;
+  friend class Deserializer;
   friend class Factory;
   friend class GCCallbacksScope;
   friend class GCTracer;
diff --git a/src/heap/incremental-marking-inl.h b/src/heap/incremental-marking-inl.h
index 5258c5c..496e02d 100644
--- a/src/heap/incremental-marking-inl.h
+++ b/src/heap/incremental-marking-inl.h
@@ -103,13 +103,13 @@
     }
   }
 
-  marking_deque_.UnshiftGrey(obj);
+  heap_->mark_compact_collector()->marking_deque()->UnshiftGrey(obj);
 }
 
 
 void IncrementalMarking::WhiteToGreyAndPush(HeapObject* obj, MarkBit mark_bit) {
   Marking::WhiteToGrey(mark_bit);
-  marking_deque_.PushGrey(obj);
+  heap_->mark_compact_collector()->marking_deque()->PushGrey(obj);
 }
 }
 }  // namespace v8::internal
diff --git a/src/heap/incremental-marking.cc b/src/heap/incremental-marking.cc
index d72423a..aadd17c 100644
--- a/src/heap/incremental-marking.cc
+++ b/src/heap/incremental-marking.cc
@@ -19,19 +19,16 @@
 IncrementalMarking::IncrementalMarking(Heap* heap)
     : heap_(heap),
       state_(STOPPED),
-      marking_deque_memory_(NULL),
-      marking_deque_memory_committed_(false),
       steps_count_(0),
       old_generation_space_available_at_start_of_incremental_(0),
       old_generation_space_used_at_start_of_incremental_(0),
       should_hurry_(false),
       marking_speed_(0),
       allocated_(0),
+      idle_marking_delay_counter_(0),
       no_marking_scope_depth_(0),
-      unscanned_bytes_of_large_object_(0) {}
-
-
-void IncrementalMarking::TearDown() { delete marking_deque_memory_; }
+      unscanned_bytes_of_large_object_(0),
+      was_activated_(false) {}
 
 
 void IncrementalMarking::RecordWriteSlow(HeapObject* obj, Object** slot,
@@ -194,11 +191,12 @@
                                 HeapObject::RawField(object, end_offset));
         start_offset = end_offset;
         end_offset = Min(object_size, end_offset + kProgressBarScanningChunk);
-        scan_until_end = heap->incremental_marking()->marking_deque()->IsFull();
+        scan_until_end =
+            heap->mark_compact_collector()->marking_deque()->IsFull();
       } while (scan_until_end && start_offset < object_size);
       chunk->set_progress_bar(start_offset);
       if (start_offset < object_size) {
-        heap->incremental_marking()->marking_deque()->UnshiftGrey(object);
+        heap->mark_compact_collector()->marking_deque()->UnshiftGrey(object);
         heap->incremental_marking()->NotifyIncompleteScanOfObject(
             object_size - (start_offset - already_scanned_offset));
       }
@@ -426,6 +424,9 @@
 }
 
 
+bool IncrementalMarking::WasActivated() { return was_activated_; }
+
+
 bool IncrementalMarking::WorthActivating() {
 #ifndef DEBUG
   static const intptr_t kActivationThreshold = 8 * MB;
@@ -439,8 +440,8 @@
   // 3) when we are currently not serializing or deserializing the heap.
   return FLAG_incremental_marking && FLAG_incremental_marking_steps &&
          heap_->gc_state() == Heap::NOT_IN_GC &&
+         heap_->deserialization_complete() &&
          !heap_->isolate()->serializer_enabled() &&
-         heap_->isolate()->IsInitialized() &&
          heap_->PromotedSpaceSizeOfObjects() > kActivationThreshold;
 }
 
@@ -481,32 +482,6 @@
 }
 
 
-void IncrementalMarking::EnsureMarkingDequeIsCommitted() {
-  if (marking_deque_memory_ == NULL) {
-    marking_deque_memory_ = new base::VirtualMemory(4 * MB);
-  }
-  if (!marking_deque_memory_committed_) {
-    bool success = marking_deque_memory_->Commit(
-        reinterpret_cast<Address>(marking_deque_memory_->address()),
-        marking_deque_memory_->size(),
-        false);  // Not executable.
-    CHECK(success);
-    marking_deque_memory_committed_ = true;
-  }
-}
-
-
-void IncrementalMarking::UncommitMarkingDeque() {
-  if (state_ == STOPPED && marking_deque_memory_committed_) {
-    bool success = marking_deque_memory_->Uncommit(
-        reinterpret_cast<Address>(marking_deque_memory_->address()),
-        marking_deque_memory_->size());
-    CHECK(success);
-    marking_deque_memory_committed_ = false;
-  }
-}
-
-
 void IncrementalMarking::Start(CompactionFlag flag) {
   if (FLAG_trace_incremental_marking) {
     PrintF("[IncrementalMarking] Start\n");
@@ -516,10 +491,11 @@
   DCHECK(state_ == STOPPED);
   DCHECK(heap_->gc_state() == Heap::NOT_IN_GC);
   DCHECK(!heap_->isolate()->serializer_enabled());
-  DCHECK(heap_->isolate()->IsInitialized());
 
   ResetStepCounters();
 
+  was_activated_ = true;
+
   if (!heap_->mark_compact_collector()->sweeping_in_progress()) {
     StartMarking(flag);
   } else {
@@ -550,13 +526,7 @@
 
   PatchIncrementalMarkingRecordWriteStubs(heap_, mode);
 
-  EnsureMarkingDequeIsCommitted();
-
-  // Initialize marking stack.
-  Address addr = static_cast<Address>(marking_deque_memory_->address());
-  size_t size = marking_deque_memory_->size();
-  if (FLAG_force_marking_deque_overflows) size = 64 * kPointerSize;
-  marking_deque_.Initialize(addr, addr + size);
+  heap_->mark_compact_collector()->EnsureMarkingDequeIsCommittedAndInitialize();
 
   ActivateIncrementalWriteBarrier();
 
@@ -602,10 +572,12 @@
 void IncrementalMarking::UpdateMarkingDequeAfterScavenge() {
   if (!IsMarking()) return;
 
-  int current = marking_deque_.bottom();
-  int mask = marking_deque_.mask();
-  int limit = marking_deque_.top();
-  HeapObject** array = marking_deque_.array();
+  MarkingDeque* marking_deque =
+      heap_->mark_compact_collector()->marking_deque();
+  int current = marking_deque->bottom();
+  int mask = marking_deque->mask();
+  int limit = marking_deque->top();
+  HeapObject** array = marking_deque->array();
   int new_top = current;
 
   Map* filler_map = heap_->one_pointer_filler_map();
@@ -620,7 +592,7 @@
         HeapObject* dest = map_word.ToForwardingAddress();
         array[new_top] = dest;
         new_top = ((new_top + 1) & mask);
-        DCHECK(new_top != marking_deque_.bottom());
+        DCHECK(new_top != marking_deque->bottom());
 #ifdef DEBUG
         MarkBit mark_bit = Marking::MarkBitFrom(obj);
         DCHECK(Marking::IsGrey(mark_bit) ||
@@ -632,7 +604,7 @@
       // stack when we perform in place array shift.
       array[new_top] = obj;
       new_top = ((new_top + 1) & mask);
-      DCHECK(new_top != marking_deque_.bottom());
+      DCHECK(new_top != marking_deque->bottom());
 #ifdef DEBUG
       MarkBit mark_bit = Marking::MarkBitFrom(obj);
       MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
@@ -643,7 +615,7 @@
 #endif
     }
   }
-  marking_deque_.set_top(new_top);
+  marking_deque->set_top(new_top);
 }
 
 
@@ -670,8 +642,10 @@
 intptr_t IncrementalMarking::ProcessMarkingDeque(intptr_t bytes_to_process) {
   intptr_t bytes_processed = 0;
   Map* filler_map = heap_->one_pointer_filler_map();
-  while (!marking_deque_.IsEmpty() && bytes_processed < bytes_to_process) {
-    HeapObject* obj = marking_deque_.Pop();
+  MarkingDeque* marking_deque =
+      heap_->mark_compact_collector()->marking_deque();
+  while (!marking_deque->IsEmpty() && bytes_processed < bytes_to_process) {
+    HeapObject* obj = marking_deque->Pop();
 
     // Explicitly skip one word fillers. Incremental markbit patterns are
     // correct only for objects that occupy at least two words.
@@ -692,8 +666,10 @@
 
 void IncrementalMarking::ProcessMarkingDeque() {
   Map* filler_map = heap_->one_pointer_filler_map();
-  while (!marking_deque_.IsEmpty()) {
-    HeapObject* obj = marking_deque_.Pop();
+  MarkingDeque* marking_deque =
+      heap_->mark_compact_collector()->marking_deque();
+  while (!marking_deque->IsEmpty()) {
+    HeapObject* obj = marking_deque->Pop();
 
     // Explicitly skip one word fillers. Incremental markbit patterns are
     // correct only for objects that occupy at least two words.
@@ -793,7 +769,7 @@
   PatchIncrementalMarkingRecordWriteStubs(heap_,
                                           RecordWriteStub::STORE_BUFFER_ONLY);
   DeactivateIncrementalWriteBarrier();
-  DCHECK(marking_deque_.IsEmpty());
+  DCHECK(heap_->mark_compact_collector()->marking_deque()->IsEmpty());
   heap_->isolate()->stack_guard()->ClearGC();
 }
 
@@ -815,6 +791,9 @@
 }
 
 
+void IncrementalMarking::Epilogue() { was_activated_ = false; }
+
+
 void IncrementalMarking::OldSpaceStep(intptr_t allocated) {
   if (IsStopped() && ShouldActivate()) {
     // TODO(hpayer): Let's play safe for now, but compaction should be
@@ -892,24 +871,33 @@
 }
 
 
-void IncrementalMarking::Step(intptr_t allocated_bytes, CompletionAction action,
-                              bool force_marking) {
+intptr_t IncrementalMarking::Step(intptr_t allocated_bytes,
+                                  CompletionAction action,
+                                  ForceMarkingAction marking,
+                                  ForceCompletionAction completion) {
   if (heap_->gc_state() != Heap::NOT_IN_GC || !FLAG_incremental_marking ||
       !FLAG_incremental_marking_steps ||
       (state_ != SWEEPING && state_ != MARKING)) {
-    return;
+    return 0;
   }
 
   allocated_ += allocated_bytes;
 
-  if (!force_marking && allocated_ < kAllocatedThreshold &&
+  if (marking == DO_NOT_FORCE_MARKING && allocated_ < kAllocatedThreshold &&
       write_barriers_invoked_since_last_step_ <
           kWriteBarriersInvokedThreshold) {
-    return;
+    return 0;
   }
 
-  if (state_ == MARKING && no_marking_scope_depth_ > 0) return;
+  // If an idle notification happened recently, we delay marking steps.
+  if (marking == DO_NOT_FORCE_MARKING &&
+      heap_->RecentIdleNotificationHappened()) {
+    return 0;
+  }
 
+  if (state_ == MARKING && no_marking_scope_depth_ > 0) return 0;
+
+  intptr_t bytes_processed = 0;
   {
     HistogramTimerScope incremental_marking_scope(
         heap_->isolate()->counters()->gc_incremental_marking());
@@ -930,11 +918,11 @@
     write_barriers_invoked_since_last_step_ = 0;
 
     bytes_scanned_ += bytes_to_process;
-    intptr_t bytes_processed = 0;
 
     if (state_ == SWEEPING) {
       if (heap_->mark_compact_collector()->sweeping_in_progress() &&
-          heap_->mark_compact_collector()->IsSweepingCompleted()) {
+          (heap_->mark_compact_collector()->IsSweepingCompleted() ||
+           !FLAG_concurrent_sweeping)) {
         heap_->mark_compact_collector()->EnsureSweepingCompleted();
       }
       if (!heap_->mark_compact_collector()->sweeping_in_progress()) {
@@ -943,7 +931,14 @@
       }
     } else if (state_ == MARKING) {
       bytes_processed = ProcessMarkingDeque(bytes_to_process);
-      if (marking_deque_.IsEmpty()) MarkingComplete(action);
+      if (heap_->mark_compact_collector()->marking_deque()->IsEmpty()) {
+        if (completion == FORCE_COMPLETION ||
+            IsIdleMarkingDelayCounterLimitReached()) {
+          MarkingComplete(action);
+        } else {
+          IncrementIdleMarkingDelayCounter();
+        }
+      }
     }
 
     steps_count_++;
@@ -959,6 +954,7 @@
     // process the marking deque.
     heap_->tracer()->AddIncrementalMarkingStep(duration, bytes_processed);
   }
+  return bytes_processed;
 }
 
 
@@ -978,5 +974,20 @@
 int64_t IncrementalMarking::SpaceLeftInOldSpace() {
   return heap_->MaxOldGenerationSize() - heap_->PromotedSpaceSizeOfObjects();
 }
+
+
+bool IncrementalMarking::IsIdleMarkingDelayCounterLimitReached() {
+  return idle_marking_delay_counter_ > kMaxIdleMarkingDelayCounter;
+}
+
+
+void IncrementalMarking::IncrementIdleMarkingDelayCounter() {
+  idle_marking_delay_counter_++;
+}
+
+
+void IncrementalMarking::ClearIdleMarkingDelayCounter() {
+  idle_marking_delay_counter_ = 0;
+}
 }
 }  // namespace v8::internal
diff --git a/src/heap/incremental-marking.h b/src/heap/incremental-marking.h
index e4a8e97..56c5a24 100644
--- a/src/heap/incremental-marking.h
+++ b/src/heap/incremental-marking.h
@@ -20,12 +20,14 @@
 
   enum CompletionAction { GC_VIA_STACK_GUARD, NO_GC_VIA_STACK_GUARD };
 
+  enum ForceMarkingAction { FORCE_MARKING, DO_NOT_FORCE_MARKING };
+
+  enum ForceCompletionAction { FORCE_COMPLETION, DO_NOT_FORCE_COMPLETION };
+
   explicit IncrementalMarking(Heap* heap);
 
   static void Initialize();
 
-  void TearDown();
-
   State state() {
     DCHECK(state_ == STOPPED || FLAG_incremental_marking);
     return state_;
@@ -46,6 +48,8 @@
 
   bool ShouldActivate();
 
+  bool WasActivated();
+
   enum CompactionFlag { ALLOW_COMPACTION, PREVENT_COMPACTION };
 
   void Start(CompactionFlag flag = ALLOW_COMPACTION);
@@ -64,6 +68,8 @@
 
   void MarkingComplete(CompletionAction action);
 
+  void Epilogue();
+
   // 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
   // of at a moderate rate of work and gradually increase the speed of the
@@ -83,10 +89,15 @@
   static const intptr_t kMarkingSpeedAccelleration = 2;
   static const intptr_t kMaxMarkingSpeed = 1000;
 
+  // This is the upper bound for how many times we allow finalization of
+  // incremental marking to be postponed.
+  static const size_t kMaxIdleMarkingDelayCounter = 3;
+
   void OldSpaceStep(intptr_t allocated);
 
-  void Step(intptr_t allocated, CompletionAction action,
-            bool force_marking = false);
+  intptr_t Step(intptr_t allocated, CompletionAction action,
+                ForceMarkingAction marking = DO_NOT_FORCE_MARKING,
+                ForceCompletionAction completion = FORCE_COMPLETION);
 
   inline void RestartIfNotMarking() {
     if (state_ == COMPLETE) {
@@ -135,8 +146,6 @@
     SetNewSpacePageFlags(chunk, IsMarking());
   }
 
-  MarkingDeque* marking_deque() { return &marking_deque_; }
-
   bool IsCompacting() { return IsMarking() && is_compacting_; }
 
   void ActivateGeneratedStub(Code* stub);
@@ -159,12 +168,14 @@
 
   void LeaveNoMarkingScope() { no_marking_scope_depth_--; }
 
-  void UncommitMarkingDeque();
-
   void NotifyIncompleteScanOfObject(int unscanned_bytes) {
     unscanned_bytes_of_large_object_ = unscanned_bytes;
   }
 
+  void ClearIdleMarkingDelayCounter();
+
+  bool IsIdleMarkingDelayCounterLimitReached();
+
  private:
   int64_t SpaceLeftInOldSpace();
 
@@ -187,23 +198,19 @@
 
   static void SetNewSpacePageFlags(NewSpacePage* chunk, bool is_marking);
 
-  void EnsureMarkingDequeIsCommitted();
-
   INLINE(void ProcessMarkingDeque());
 
   INLINE(intptr_t ProcessMarkingDeque(intptr_t bytes_to_process));
 
   INLINE(void VisitObject(Map* map, HeapObject* obj, int size));
 
+  void IncrementIdleMarkingDelayCounter();
+
   Heap* heap_;
 
   State state_;
   bool is_compacting_;
 
-  base::VirtualMemory* marking_deque_memory_;
-  bool marking_deque_memory_committed_;
-  MarkingDeque marking_deque_;
-
   int steps_count_;
   int64_t old_generation_space_available_at_start_of_incremental_;
   int64_t old_generation_space_used_at_start_of_incremental_;
@@ -213,11 +220,14 @@
   intptr_t bytes_scanned_;
   intptr_t allocated_;
   intptr_t write_barriers_invoked_since_last_step_;
+  size_t idle_marking_delay_counter_;
 
   int no_marking_scope_depth_;
 
   int unscanned_bytes_of_large_object_;
 
+  bool was_activated_;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(IncrementalMarking);
 };
 }
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index 9f9a658..c9a310a 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -18,7 +18,6 @@
 #include "src/heap/objects-visiting.h"
 #include "src/heap/objects-visiting-inl.h"
 #include "src/heap/spaces-inl.h"
-#include "src/heap/sweeper-thread.h"
 #include "src/heap-profiler.h"
 #include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
@@ -48,9 +47,11 @@
       was_marked_incrementally_(false),
       sweeping_in_progress_(false),
       pending_sweeper_jobs_semaphore_(0),
-      sequential_sweeping_(false),
+      evacuation_(false),
       migration_slots_buffer_(NULL),
       heap_(heap),
+      marking_deque_memory_(NULL),
+      marking_deque_memory_committed_(false),
       code_flusher_(NULL),
       have_code_to_deoptimize_(false) {
 }
@@ -228,110 +229,16 @@
 #endif  // VERIFY_HEAP
 
 
-#ifdef DEBUG
-class VerifyNativeContextSeparationVisitor : public ObjectVisitor {
- public:
-  VerifyNativeContextSeparationVisitor() : current_native_context_(NULL) {}
-
-  void VisitPointers(Object** start, Object** end) {
-    for (Object** current = start; current < end; current++) {
-      if ((*current)->IsHeapObject()) {
-        HeapObject* object = HeapObject::cast(*current);
-        if (object->IsString()) continue;
-        switch (object->map()->instance_type()) {
-          case JS_FUNCTION_TYPE:
-            CheckContext(JSFunction::cast(object)->context());
-            break;
-          case JS_GLOBAL_PROXY_TYPE:
-            CheckContext(JSGlobalProxy::cast(object)->native_context());
-            break;
-          case JS_GLOBAL_OBJECT_TYPE:
-          case JS_BUILTINS_OBJECT_TYPE:
-            CheckContext(GlobalObject::cast(object)->native_context());
-            break;
-          case JS_ARRAY_TYPE:
-          case JS_DATE_TYPE:
-          case JS_OBJECT_TYPE:
-          case JS_REGEXP_TYPE:
-            VisitPointer(HeapObject::RawField(object, JSObject::kMapOffset));
-            break;
-          case MAP_TYPE:
-            VisitPointer(HeapObject::RawField(object, Map::kPrototypeOffset));
-            VisitPointer(HeapObject::RawField(object, Map::kConstructorOffset));
-            break;
-          case FIXED_ARRAY_TYPE:
-            if (object->IsContext()) {
-              CheckContext(object);
-            } else {
-              FixedArray* array = FixedArray::cast(object);
-              int length = array->length();
-              // Set array length to zero to prevent cycles while iterating
-              // over array bodies, this is easier than intrusive marking.
-              array->set_length(0);
-              array->IterateBody(FIXED_ARRAY_TYPE, FixedArray::SizeFor(length),
-                                 this);
-              array->set_length(length);
-            }
-            break;
-          case CELL_TYPE:
-          case JS_PROXY_TYPE:
-          case JS_VALUE_TYPE:
-          case TYPE_FEEDBACK_INFO_TYPE:
-            object->Iterate(this);
-            break;
-          case DECLARED_ACCESSOR_INFO_TYPE:
-          case EXECUTABLE_ACCESSOR_INFO_TYPE:
-          case BYTE_ARRAY_TYPE:
-          case CALL_HANDLER_INFO_TYPE:
-          case CODE_TYPE:
-          case FIXED_DOUBLE_ARRAY_TYPE:
-          case HEAP_NUMBER_TYPE:
-          case MUTABLE_HEAP_NUMBER_TYPE:
-          case INTERCEPTOR_INFO_TYPE:
-          case ODDBALL_TYPE:
-          case SCRIPT_TYPE:
-          case SHARED_FUNCTION_INFO_TYPE:
-            break;
-          default:
-            UNREACHABLE();
-        }
-      }
-    }
-  }
-
- private:
-  void CheckContext(Object* context) {
-    if (!context->IsContext()) return;
-    Context* native_context = Context::cast(context)->native_context();
-    if (current_native_context_ == NULL) {
-      current_native_context_ = native_context;
-    } else {
-      CHECK_EQ(current_native_context_, native_context);
-    }
-  }
-
-  Context* current_native_context_;
-};
-
-
-static void VerifyNativeContextSeparation(Heap* heap) {
-  HeapObjectIterator it(heap->code_space());
-
-  for (Object* object = it.Next(); object != NULL; object = it.Next()) {
-    VerifyNativeContextSeparationVisitor visitor;
-    Code::cast(object)->CodeIterateBody(&visitor);
-  }
-}
-#endif
-
-
 void MarkCompactCollector::SetUp() {
   free_list_old_data_space_.Reset(new FreeList(heap_->old_data_space()));
   free_list_old_pointer_space_.Reset(new FreeList(heap_->old_pointer_space()));
 }
 
 
-void MarkCompactCollector::TearDown() { AbortCompaction(); }
+void MarkCompactCollector::TearDown() {
+  AbortCompaction();
+  delete marking_deque_memory_;
+}
 
 
 void MarkCompactCollector::AddEvacuationCandidate(Page* p) {
@@ -396,8 +303,14 @@
 
   if (FLAG_collect_maps) ClearNonLiveReferences();
 
+  ProcessAndClearWeakCells();
+
   ClearWeakCollections();
 
+  heap_->set_encountered_weak_cells(Smi::FromInt(0));
+
+  isolate()->global_handles()->CollectPhantomCallbackData();
+
 #ifdef VERIFY_HEAP
   if (FLAG_verify_heap) {
     VerifyMarking(heap_);
@@ -406,12 +319,6 @@
 
   SweepSpaces();
 
-#ifdef DEBUG
-  if (FLAG_verify_native_context_separation) {
-    VerifyNativeContextSeparation(heap_);
-  }
-#endif
-
 #ifdef VERIFY_HEAP
   if (heap()->weak_embedded_objects_verification_enabled()) {
     VerifyWeakEmbeddedObjectsInCode();
@@ -478,7 +385,7 @@
   for (HeapObject* obj = code_iterator.Next(); obj != NULL;
        obj = code_iterator.Next()) {
     Code* code = Code::cast(obj);
-    if (!code->is_optimized_code() && !code->is_weak_stub()) continue;
+    if (!code->is_optimized_code()) continue;
     if (WillBeDeoptimized(code)) continue;
     code->VerifyEmbeddedObjectsDependency();
   }
@@ -541,7 +448,7 @@
 
  private:
   // v8::Task overrides.
-  virtual void Run() OVERRIDE {
+  void Run() OVERRIDE {
     heap_->mark_compact_collector()->SweepInParallel(space_, 0);
     heap_->mark_compact_collector()->pending_sweeper_jobs_semaphore_.Signal();
   }
@@ -556,37 +463,26 @@
 void MarkCompactCollector::StartSweeperThreads() {
   DCHECK(free_list_old_pointer_space_.get()->IsEmpty());
   DCHECK(free_list_old_data_space_.get()->IsEmpty());
-  sweeping_in_progress_ = true;
-  for (int i = 0; i < isolate()->num_sweeper_threads(); i++) {
-    isolate()->sweeper_threads()[i]->StartSweeping();
-  }
-  if (FLAG_job_based_sweeping) {
-    V8::GetCurrentPlatform()->CallOnBackgroundThread(
-        new SweeperTask(heap(), heap()->old_data_space()),
-        v8::Platform::kShortRunningTask);
-    V8::GetCurrentPlatform()->CallOnBackgroundThread(
-        new SweeperTask(heap(), heap()->old_pointer_space()),
-        v8::Platform::kShortRunningTask);
-  }
+  V8::GetCurrentPlatform()->CallOnBackgroundThread(
+      new SweeperTask(heap(), heap()->old_data_space()),
+      v8::Platform::kShortRunningTask);
+  V8::GetCurrentPlatform()->CallOnBackgroundThread(
+      new SweeperTask(heap(), heap()->old_pointer_space()),
+      v8::Platform::kShortRunningTask);
 }
 
 
 void MarkCompactCollector::EnsureSweepingCompleted() {
   DCHECK(sweeping_in_progress_ == true);
 
-  // If sweeping is not completed, we try to complete it here. If we do not
-  // have sweeper threads we have to complete since we do not have a good
-  // indicator for a swept space in that case.
-  if (!AreSweeperThreadsActivated() || !IsSweepingCompleted()) {
+  // If sweeping is not completed or not running at all, we try to complete it
+  // here.
+  if (!FLAG_concurrent_sweeping || !IsSweepingCompleted()) {
     SweepInParallel(heap()->paged_space(OLD_DATA_SPACE), 0);
     SweepInParallel(heap()->paged_space(OLD_POINTER_SPACE), 0);
   }
-
-  for (int i = 0; i < isolate()->num_sweeper_threads(); i++) {
-    isolate()->sweeper_threads()[i]->WaitForSweeperThread();
-  }
-  if (FLAG_job_based_sweeping) {
-    // Wait twice for both jobs.
+  // Wait twice for both jobs.
+  if (FLAG_concurrent_sweeping) {
     pending_sweeper_jobs_semaphore_.Wait();
     pending_sweeper_jobs_semaphore_.Wait();
   }
@@ -598,7 +494,7 @@
   heap()->paged_space(OLD_POINTER_SPACE)->ResetUnsweptFreeBytes();
 
 #ifdef VERIFY_HEAP
-  if (FLAG_verify_heap) {
+  if (FLAG_verify_heap && !evacuation()) {
     VerifyEvacuation(heap_);
   }
 #endif
@@ -606,20 +502,11 @@
 
 
 bool MarkCompactCollector::IsSweepingCompleted() {
-  for (int i = 0; i < isolate()->num_sweeper_threads(); i++) {
-    if (!isolate()->sweeper_threads()[i]->SweepingCompleted()) {
-      return false;
-    }
+  if (!pending_sweeper_jobs_semaphore_.WaitFor(
+          base::TimeDelta::FromSeconds(0))) {
+    return false;
   }
-
-  if (FLAG_job_based_sweeping) {
-    if (!pending_sweeper_jobs_semaphore_.WaitFor(
-            base::TimeDelta::FromSeconds(0))) {
-      return false;
-    }
-    pending_sweeper_jobs_semaphore_.Signal();
-  }
-
+  pending_sweeper_jobs_semaphore_.Signal();
   return true;
 }
 
@@ -643,11 +530,6 @@
 }
 
 
-bool MarkCompactCollector::AreSweeperThreadsActivated() {
-  return isolate()->sweeper_threads() != NULL || FLAG_job_based_sweeping;
-}
-
-
 void Marking::TransferMark(Address old_start, Address new_start) {
   // This is only used when resizing an object.
   DCHECK(MemoryChunk::FromAddress(old_start) ==
@@ -952,6 +834,7 @@
     heap()->incremental_marking()->Abort();
     ClearMarkbits();
     AbortWeakCollections();
+    AbortWeakCells();
     AbortCompaction();
     was_marked_incrementally_ = false;
   }
@@ -992,6 +875,8 @@
     Deoptimizer::DeoptimizeMarkedCode(isolate());
     have_code_to_deoptimize_ = false;
   }
+
+  heap_->incremental_marking()->ClearIdleMarkingDelayCounter();
 }
 
 
@@ -1328,7 +1213,6 @@
   // except the maps for the object and its possible substrings might be
   // marked.
   HeapObject* object = HeapObject::cast(*p);
-  if (!FLAG_clever_optimizations) return object;
   Map* map = object->map();
   InstanceType type = map->instance_type();
   if (!IsShortcutCandidate(type)) return object;
@@ -2132,13 +2016,18 @@
 // After: the marking stack is empty, and all objects reachable from the
 // marking stack have been marked, or are overflowed in the heap.
 void MarkCompactCollector::EmptyMarkingDeque() {
+  Map* filler_map = heap_->one_pointer_filler_map();
   while (!marking_deque_.IsEmpty()) {
     HeapObject* object = marking_deque_.Pop();
+    // Explicitly skip one word fillers. Incremental markbit patterns are
+    // correct only for objects that occupy at least two words.
+    Map* map = object->map();
+    if (map == filler_map) continue;
+
     DCHECK(object->IsHeapObject());
     DCHECK(heap()->Contains(object));
-    DCHECK(Marking::IsBlack(Marking::MarkBitFrom(object)));
+    DCHECK(!Marking::IsWhite(Marking::MarkBitFrom(object)));
 
-    Map* map = object->map();
     MarkBit map_mark = Marking::MarkBitFrom(map);
     MarkObject(map, map_mark);
 
@@ -2201,13 +2090,16 @@
 
 // Mark all objects reachable (transitively) from objects on the marking
 // stack including references only considered in the atomic marking pause.
-void MarkCompactCollector::ProcessEphemeralMarking(ObjectVisitor* visitor) {
+void MarkCompactCollector::ProcessEphemeralMarking(
+    ObjectVisitor* visitor, bool only_process_harmony_weak_collections) {
   bool work_to_do = true;
-  DCHECK(marking_deque_.IsEmpty());
+  DCHECK(marking_deque_.IsEmpty() && !marking_deque_.overflowed());
   while (work_to_do) {
-    isolate()->global_handles()->IterateObjectGroups(
-        visitor, &IsUnmarkedHeapObjectWithHeap);
-    MarkImplicitRefGroups();
+    if (!only_process_harmony_weak_collections) {
+      isolate()->global_handles()->IterateObjectGroups(
+          visitor, &IsUnmarkedHeapObjectWithHeap);
+      MarkImplicitRefGroups();
+    }
     ProcessWeakCollections();
     work_to_do = !marking_deque_.IsEmpty();
     ProcessMarkingDeque();
@@ -2233,6 +2125,43 @@
 }
 
 
+void MarkCompactCollector::EnsureMarkingDequeIsCommittedAndInitialize() {
+  if (marking_deque_memory_ == NULL) {
+    marking_deque_memory_ = new base::VirtualMemory(4 * MB);
+  }
+  if (!marking_deque_memory_committed_) {
+    bool success = marking_deque_memory_->Commit(
+        reinterpret_cast<Address>(marking_deque_memory_->address()),
+        marking_deque_memory_->size(),
+        false);  // Not executable.
+    CHECK(success);
+    marking_deque_memory_committed_ = true;
+    InitializeMarkingDeque();
+  }
+}
+
+
+void MarkCompactCollector::InitializeMarkingDeque() {
+  if (marking_deque_memory_committed_) {
+    Address addr = static_cast<Address>(marking_deque_memory_->address());
+    size_t size = marking_deque_memory_->size();
+    if (FLAG_force_marking_deque_overflows) size = 64 * kPointerSize;
+    marking_deque_.Initialize(addr, addr + size);
+  }
+}
+
+
+void MarkCompactCollector::UncommitMarkingDeque() {
+  if (marking_deque_memory_committed_) {
+    bool success = marking_deque_memory_->Uncommit(
+        reinterpret_cast<Address>(marking_deque_memory_->address()),
+        marking_deque_memory_->size());
+    CHECK(success);
+    marking_deque_memory_committed_ = false;
+  }
+}
+
+
 void MarkCompactCollector::MarkLiveObjects() {
   GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_MARK);
   double start_time = 0.0;
@@ -2244,42 +2173,21 @@
   // with the C stack limit check.
   PostponeInterruptsScope postpone(isolate());
 
-  bool incremental_marking_overflowed = false;
   IncrementalMarking* incremental_marking = heap_->incremental_marking();
   if (was_marked_incrementally_) {
-    // Finalize the incremental marking and check whether we had an overflow.
-    // Both markers use grey color to mark overflowed objects so
-    // non-incremental marker can deal with them as if overflow
-    // occured during normal marking.
-    // But incremental marker uses a separate marking deque
-    // so we have to explicitly copy its overflow state.
     incremental_marking->Finalize();
-    incremental_marking_overflowed =
-        incremental_marking->marking_deque()->overflowed();
-    incremental_marking->marking_deque()->ClearOverflowed();
   } else {
     // Abort any pending incremental activities e.g. incremental sweeping.
     incremental_marking->Abort();
+    InitializeMarkingDeque();
   }
 
 #ifdef DEBUG
   DCHECK(state_ == PREPARE_GC);
   state_ = MARK_LIVE_OBJECTS;
 #endif
-  // The to space contains live objects, a page in from space is used as a
-  // marking stack.
-  Address marking_deque_start = heap()->new_space()->FromSpacePageLow();
-  Address marking_deque_end = heap()->new_space()->FromSpacePageHigh();
-  if (FLAG_force_marking_deque_overflows) {
-    marking_deque_end = marking_deque_start + 64 * kPointerSize;
-  }
-  marking_deque_.Initialize(marking_deque_start, marking_deque_end);
-  DCHECK(!marking_deque_.overflowed());
 
-  if (incremental_marking_overflowed) {
-    // There are overflowed objects left in the heap after incremental marking.
-    marking_deque_.SetOverflowed();
-  }
+  EnsureMarkingDequeIsCommittedAndInitialize();
 
   PrepareForCodeFlushing();
 
@@ -2316,30 +2224,35 @@
 
   ProcessTopOptimizedFrame(&root_visitor);
 
-  // The objects reachable from the roots are marked, yet unreachable
-  // objects are unmarked.  Mark objects reachable due to host
-  // application specific logic or through Harmony weak maps.
-  ProcessEphemeralMarking(&root_visitor);
+  {
+    GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_WEAKCLOSURE);
 
-  // The objects reachable from the roots, weak maps or object groups
-  // are marked, yet unreachable objects are unmarked.  Mark objects
-  // reachable only from weak global handles.
-  //
-  // First we identify nonlive weak handles and mark them as pending
-  // destruction.
-  heap()->isolate()->global_handles()->IdentifyWeakHandles(
-      &IsUnmarkedHeapObject);
-  // Then we mark the objects and process the transitive closure.
-  heap()->isolate()->global_handles()->IterateWeakRoots(&root_visitor);
-  while (marking_deque_.overflowed()) {
-    RefillMarkingDeque();
-    EmptyMarkingDeque();
+    // The objects reachable from the roots are marked, yet unreachable
+    // objects are unmarked.  Mark objects reachable due to host
+    // application specific logic or through Harmony weak maps.
+    ProcessEphemeralMarking(&root_visitor, false);
+
+    // The objects reachable from the roots, weak maps or object groups
+    // are marked. Objects pointed to only by weak global handles cannot be
+    // immediately reclaimed. Instead, we have to mark them as pending and mark
+    // objects reachable from them.
+    //
+    // First we identify nonlive weak handles and mark them as pending
+    // destruction.
+    heap()->isolate()->global_handles()->IdentifyWeakHandles(
+        &IsUnmarkedHeapObject);
+    // Then we mark the objects.
+    heap()->isolate()->global_handles()->IterateWeakRoots(&root_visitor);
+    ProcessMarkingDeque();
+
+    // Repeat Harmony weak maps marking to mark unmarked objects reachable from
+    // the weak roots we just marked as pending destruction.
+    //
+    // We only process harmony collections, as all object groups have been fully
+    // processed and no weakly reachable node can discover new objects groups.
+    ProcessEphemeralMarking(&root_visitor, true);
   }
 
-  // Repeat host application specific and Harmony weak maps marking to
-  // mark unmarked objects reachable from the weak roots.
-  ProcessEphemeralMarking(&root_visitor);
-
   AfterMarking();
 
   if (FLAG_print_cumulative_gc_stat) {
@@ -2349,12 +2262,6 @@
 
 
 void MarkCompactCollector::AfterMarking() {
-  // Object literal map caches reference strings (cache keys) and maps
-  // (cache values). At this point still useful maps have already been
-  // marked. Mark the keys for the alive values before we process the
-  // string table.
-  ProcessMapCaches();
-
   // Prune the string table removing all strings only pointed to by the
   // string table.  Cannot use string_table() here because the string
   // table is marked.
@@ -2391,57 +2298,6 @@
 }
 
 
-void MarkCompactCollector::ProcessMapCaches() {
-  Object* raw_context = heap()->native_contexts_list();
-  while (raw_context != heap()->undefined_value()) {
-    Context* context = reinterpret_cast<Context*>(raw_context);
-    if (IsMarked(context)) {
-      HeapObject* raw_map_cache =
-          HeapObject::cast(context->get(Context::MAP_CACHE_INDEX));
-      // A map cache may be reachable from the stack. In this case
-      // it's already transitively marked and it's too late to clean
-      // up its parts.
-      if (!IsMarked(raw_map_cache) &&
-          raw_map_cache != heap()->undefined_value()) {
-        MapCache* map_cache = reinterpret_cast<MapCache*>(raw_map_cache);
-        int existing_elements = map_cache->NumberOfElements();
-        int used_elements = 0;
-        for (int i = MapCache::kElementsStartIndex; i < map_cache->length();
-             i += MapCache::kEntrySize) {
-          Object* raw_key = map_cache->get(i);
-          if (raw_key == heap()->undefined_value() ||
-              raw_key == heap()->the_hole_value())
-            continue;
-          STATIC_ASSERT(MapCache::kEntrySize == 2);
-          Object* raw_map = map_cache->get(i + 1);
-          if (raw_map->IsHeapObject() && IsMarked(raw_map)) {
-            ++used_elements;
-          } else {
-            // Delete useless entries with unmarked maps.
-            DCHECK(raw_map->IsMap());
-            map_cache->set_the_hole(i);
-            map_cache->set_the_hole(i + 1);
-          }
-        }
-        if (used_elements == 0) {
-          context->set(Context::MAP_CACHE_INDEX, heap()->undefined_value());
-        } else {
-          // Note: we don't actually shrink the cache here to avoid
-          // extra complexity during GC. We rely on subsequent cache
-          // usages (EnsureCapacity) to do this.
-          map_cache->ElementsRemoved(existing_elements - used_elements);
-          MarkBit map_cache_markbit = Marking::MarkBitFrom(map_cache);
-          MarkObject(map_cache, map_cache_markbit);
-        }
-      }
-    }
-    // Move to next element in the list.
-    raw_context = context->get(Context::NEXT_CONTEXT_LINK);
-  }
-  ProcessMarkingDeque();
-}
-
-
 void MarkCompactCollector::ClearNonLiveReferences() {
   // Iterate over the map space, setting map transitions that go from
   // a marked map to an unmarked map to null transitions.  This action
@@ -2639,13 +2495,14 @@
 
   // Note that we never eliminate a transition array, though we might right-trim
   // such that number_of_transitions() == 0. If this assumption changes,
-  // TransitionArray::CopyInsert() will need to deal with the case that a
-  // transition array disappeared during GC.
-  int trim = t->number_of_transitions() - transition_index;
+  // TransitionArray::Insert() will need to deal with the case that a transition
+  // array disappeared during GC.
+  int trim = t->number_of_transitions_storage() - transition_index;
   if (trim > 0) {
     heap_->RightTrimFixedArray<Heap::FROM_GC>(
         t, t->IsSimpleTransition() ? trim
                                    : trim * TransitionArray::kTransitionSize);
+    t->SetNumberOfTransitions(transition_index);
   }
   DCHECK(map->HasTransitionArray());
 }
@@ -2688,34 +2545,12 @@
 }
 
 
-void MarkCompactCollector::ClearDependentICList(Object* head) {
-  Object* current = head;
-  Object* undefined = heap()->undefined_value();
-  while (current != undefined) {
-    Code* code = Code::cast(current);
-    if (IsMarked(code)) {
-      DCHECK(code->is_weak_stub());
-      IC::InvalidateMaps(code);
-    }
-    current = code->next_code_link();
-    code->set_next_code_link(undefined);
-  }
-}
-
-
 void MarkCompactCollector::ClearDependentCode(DependentCode* entries) {
   DisallowHeapAllocation no_allocation;
   DependentCode::GroupStartIndexes starts(entries);
   int number_of_entries = starts.number_of_entries();
   if (number_of_entries == 0) return;
-  int g = DependentCode::kWeakICGroup;
-  if (starts.at(g) != starts.at(g + 1)) {
-    int i = starts.at(g);
-    DCHECK(i + 1 == starts.at(g + 1));
-    Object* head = entries->object_at(i);
-    ClearDependentICList(head);
-  }
-  g = DependentCode::kWeakCodeGroup;
+  int g = DependentCode::kWeakCodeGroup;
   for (int i = starts.at(g); i < starts.at(g + 1); i++) {
     // If the entry is compilation info then the map must be alive,
     // and ClearDependentCode shouldn't be called.
@@ -2737,34 +2572,17 @@
 int MarkCompactCollector::ClearNonLiveDependentCodeInGroup(
     DependentCode* entries, int group, int start, int end, int new_start) {
   int survived = 0;
-  if (group == DependentCode::kWeakICGroup) {
-    // Dependent weak IC stubs form a linked list and only the head is stored
-    // in the dependent code array.
-    if (start != end) {
-      DCHECK(start + 1 == end);
-      Object* old_head = entries->object_at(start);
-      MarkCompactWeakObjectRetainer retainer;
-      Object* head = VisitWeakList<Code>(heap(), old_head, &retainer);
-      entries->set_object_at(new_start, head);
-      Object** slot = entries->slot_at(new_start);
-      RecordSlot(slot, slot, head);
-      // We do not compact this group even if the head is undefined,
-      // more dependent ICs are likely to be added later.
-      survived = 1;
-    }
-  } else {
-    for (int i = start; i < end; i++) {
-      Object* obj = entries->object_at(i);
-      DCHECK(obj->IsCode() || IsMarked(obj));
-      if (IsMarked(obj) &&
-          (!obj->IsCode() || !WillBeDeoptimized(Code::cast(obj)))) {
-        if (new_start + survived != i) {
-          entries->set_object_at(new_start + survived, obj);
-        }
-        Object** slot = entries->slot_at(new_start + survived);
-        RecordSlot(slot, slot, obj);
-        survived++;
+  for (int i = start; i < end; i++) {
+    Object* obj = entries->object_at(i);
+    DCHECK(obj->IsCode() || IsMarked(obj));
+    if (IsMarked(obj) &&
+        (!obj->IsCode() || !WillBeDeoptimized(Code::cast(obj)))) {
+      if (new_start + survived != i) {
+        entries->set_object_at(new_start + survived, obj);
       }
+      Object** slot = entries->slot_at(new_start + survived);
+      RecordSlot(slot, slot, obj);
+      survived++;
     }
   }
   entries->set_number_of_entries(
@@ -2857,6 +2675,39 @@
 }
 
 
+void MarkCompactCollector::ProcessAndClearWeakCells() {
+  HeapObject* undefined = heap()->undefined_value();
+  Object* weak_cell_obj = heap()->encountered_weak_cells();
+  while (weak_cell_obj != Smi::FromInt(0)) {
+    WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj);
+    // We do not insert cleared weak cells into the list, so the value
+    // cannot be a Smi here.
+    HeapObject* value = HeapObject::cast(weak_cell->value());
+    if (!MarkCompactCollector::IsMarked(value)) {
+      weak_cell->clear();
+    } else {
+      Object** slot = HeapObject::RawField(weak_cell, WeakCell::kValueOffset);
+      heap()->mark_compact_collector()->RecordSlot(slot, slot, value);
+    }
+    weak_cell_obj = weak_cell->next();
+    weak_cell->set_next(undefined, SKIP_WRITE_BARRIER);
+  }
+  heap()->set_encountered_weak_cells(Smi::FromInt(0));
+}
+
+
+void MarkCompactCollector::AbortWeakCells() {
+  Object* undefined = heap()->undefined_value();
+  Object* weak_cell_obj = heap()->encountered_weak_cells();
+  while (weak_cell_obj != Smi::FromInt(0)) {
+    WeakCell* weak_cell = reinterpret_cast<WeakCell*>(weak_cell_obj);
+    weak_cell_obj = weak_cell->next();
+    weak_cell->set_next(undefined, SKIP_WRITE_BARRIER);
+  }
+  heap()->set_encountered_weak_cells(Smi::FromInt(0));
+}
+
+
 void MarkCompactCollector::RecordMigratedSlot(Object* value, Address slot) {
   if (heap_->InNewSpace(value)) {
     heap_->store_buffer()->Mark(slot);
@@ -2868,7 +2719,7 @@
 }
 
 
-// We scavange new space simultaneously with sweeping. This is done in two
+// We scavenge new space simultaneously with sweeping. This is done in two
 // passes.
 //
 // The first pass migrates all alive objects from one semispace to another or
@@ -2893,12 +2744,24 @@
     Address dst_slot = dst_addr;
     DCHECK(IsAligned(size, kPointerSize));
 
+    bool may_contain_raw_values = src->MayContainRawValues();
+#if V8_DOUBLE_FIELDS_UNBOXING
+    LayoutDescriptorHelper helper(src->map());
+    bool has_only_tagged_fields = helper.all_fields_tagged();
+#endif
     for (int remaining = size / kPointerSize; remaining > 0; remaining--) {
       Object* value = Memory::Object_at(src_slot);
 
       Memory::Object_at(dst_slot) = value;
 
-      if (!src->MayContainRawValues()) {
+#if V8_DOUBLE_FIELDS_UNBOXING
+      if (!may_contain_raw_values &&
+          (has_only_tagged_fields ||
+           helper.IsTagged(static_cast<int>(src_slot - src_addr))))
+#else
+      if (!may_contain_raw_values)
+#endif
+      {
         RecordMigratedSlot(value, dst_slot);
       }
 
@@ -3011,7 +2874,8 @@
   }
 
   static inline void UpdateSlot(Heap* heap, Object** slot) {
-    Object* obj = *slot;
+    Object* obj = reinterpret_cast<Object*>(
+        base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
 
     if (!obj->IsHeapObject()) return;
 
@@ -3022,7 +2886,10 @@
       DCHECK(heap->InFromSpace(heap_obj) ||
              MarkCompactCollector::IsOnEvacuationCandidate(heap_obj));
       HeapObject* target = map_word.ToForwardingAddress();
-      *slot = target;
+      base::NoBarrier_CompareAndSwap(
+          reinterpret_cast<base::AtomicWord*>(slot),
+          reinterpret_cast<base::AtomicWord>(obj),
+          reinterpret_cast<base::AtomicWord>(target));
       DCHECK(!heap->InFromSpace(target) &&
              !MarkCompactCollector::IsOnEvacuationCandidate(target));
     }
@@ -3185,6 +3052,11 @@
       // have an emergency page and the space still has room for that.
       if (space->HasEmergencyMemory() && space->CanExpand()) {
         EvacuateLiveObjectsFromPage(p);
+        // Unlink the page from the list of pages here. We must not iterate
+        // over that page later (e.g. when scan on scavenge pages are
+        // processed). The page itself will be freed later and is still
+        // reachable from the evacuation candidates list.
+        p->Unlink();
       } else {
         // Without room for expansion evacuation is not guaranteed to succeed.
         // Pessimistically abandon unevacuated pages.
@@ -3339,7 +3211,7 @@
       }
       HeapObject* live_object = HeapObject::FromAddress(free_end);
       DCHECK(Marking::IsBlack(Marking::MarkBitFrom(live_object)));
-      Map* map = live_object->map();
+      Map* map = live_object->synchronized_map();
       int size = live_object->SizeFromMap(map);
       if (sweeping_mode == SWEEP_AND_VISIT_LIVE_OBJECTS) {
         live_object->IterateBody(map->instance_type(), size, v);
@@ -3519,6 +3391,7 @@
   {
     GCTracer::Scope gc_scope(heap()->tracer(),
                              GCTracer::Scope::MC_EVACUATE_PAGES);
+    EvacuationScope evacuation_scope(this);
     EvacuatePages();
   }
 
@@ -4194,7 +4067,6 @@
 
     switch (sweeper) {
       case CONCURRENT_SWEEPING:
-      case PARALLEL_SWEEPING:
         if (!parallel_sweeping_active) {
           if (FLAG_gc_verbose) {
             PrintF("Sweeping 0x%" V8PRIxPTR ".\n",
@@ -4245,18 +4117,6 @@
 }
 
 
-static bool ShouldStartSweeperThreads(MarkCompactCollector::SweeperType type) {
-  return type == MarkCompactCollector::PARALLEL_SWEEPING ||
-         type == MarkCompactCollector::CONCURRENT_SWEEPING;
-}
-
-
-static bool ShouldWaitForSweeperThreads(
-    MarkCompactCollector::SweeperType type) {
-  return type == MarkCompactCollector::PARALLEL_SWEEPING;
-}
-
-
 void MarkCompactCollector::SweepSpaces() {
   GCTracer::Scope gc_scope(heap()->tracer(), GCTracer::Scope::MC_SWEEP);
   double start_time = 0.0;
@@ -4267,10 +4127,6 @@
 #ifdef DEBUG
   state_ = SWEEP_SPACES;
 #endif
-  SweeperType how_to_sweep = CONCURRENT_SWEEPING;
-  if (FLAG_parallel_sweeping) how_to_sweep = PARALLEL_SWEEPING;
-  if (FLAG_concurrent_sweeping) how_to_sweep = CONCURRENT_SWEEPING;
-
   MoveEvacuationCandidatesToEndOfPagesList();
 
   // Noncompacting collections simply sweep the spaces to clear the mark
@@ -4282,18 +4138,13 @@
     GCTracer::Scope sweep_scope(heap()->tracer(),
                                 GCTracer::Scope::MC_SWEEP_OLDSPACE);
     {
-      SequentialSweepingScope scope(this);
-      SweepSpace(heap()->old_pointer_space(), how_to_sweep);
-      SweepSpace(heap()->old_data_space(), how_to_sweep);
+      SweepSpace(heap()->old_pointer_space(), CONCURRENT_SWEEPING);
+      SweepSpace(heap()->old_data_space(), CONCURRENT_SWEEPING);
     }
-
-    if (ShouldStartSweeperThreads(how_to_sweep)) {
+    sweeping_in_progress_ = true;
+    if (FLAG_concurrent_sweeping) {
       StartSweeperThreads();
     }
-
-    if (ShouldWaitForSweeperThreads(how_to_sweep)) {
-      EnsureSweepingCompleted();
-    }
   }
   RemoveDeadInvalidatedCode();
 
@@ -4326,6 +4177,10 @@
 
   // Deallocate evacuated candidate pages.
   ReleaseEvacuationCandidates();
+  CodeRange* code_range = heap()->isolate()->code_range();
+  if (code_range != NULL && code_range->valid()) {
+    code_range->ReserveEmergencyBlock();
+  }
 
   if (FLAG_print_cumulative_gc_stat) {
     heap_->tracer()->AddSweepingTime(base::OS::TimeCurrentMillis() -
diff --git a/src/heap/mark-compact.h b/src/heap/mark-compact.h
index c5087b4..e26e06c 100644
--- a/src/heap/mark-compact.h
+++ b/src/heap/mark-compact.h
@@ -547,7 +547,6 @@
   void EnableCodeFlushing(bool enable);
 
   enum SweeperType {
-    PARALLEL_SWEEPING,
     CONCURRENT_SWEEPING,
     SEQUENTIAL_SWEEPING
   };
@@ -641,16 +640,12 @@
 
   void RefillFreeList(PagedSpace* space);
 
-  bool AreSweeperThreadsActivated();
-
   // Checks if sweeping is in progress right now on any space.
   bool sweeping_in_progress() { return sweeping_in_progress_; }
 
-  void set_sequential_sweeping(bool sequential_sweeping) {
-    sequential_sweeping_ = sequential_sweeping;
-  }
+  void set_evacuation(bool evacuation) { evacuation_ = evacuation; }
 
-  bool sequential_sweeping() const { return sequential_sweeping_; }
+  bool evacuation() const { return evacuation_; }
 
   // Mark the global table which maps weak objects to dependent code without
   // marking its contents.
@@ -660,6 +655,14 @@
   // to artificially keep AllocationSites alive for a time.
   void MarkAllocationSite(AllocationSite* site);
 
+  MarkingDeque* marking_deque() { return &marking_deque_; }
+
+  void EnsureMarkingDequeIsCommittedAndInitialize();
+
+  void InitializeMarkingDeque();
+
+  void UncommitMarkingDeque();
+
  private:
   class SweeperTask;
 
@@ -705,7 +708,7 @@
 
   base::Semaphore pending_sweeper_jobs_semaphore_;
 
-  bool sequential_sweeping_;
+  bool evacuation_;
 
   SlotsBufferAllocator slots_buffer_allocator_;
 
@@ -769,7 +772,8 @@
   //    - Processing of objects reachable through Harmony WeakMaps.
   //    - Objects reachable due to host application logic like object groups
   //      or implicit references' groups.
-  void ProcessEphemeralMarking(ObjectVisitor* visitor);
+  void ProcessEphemeralMarking(ObjectVisitor* visitor,
+                               bool only_process_harmony_weak_collections);
 
   // If the call-site of the top optimized code was not prepared for
   // deoptimization, then treat the maps in the code as strong pointers,
@@ -787,10 +791,6 @@
   // flag on the marking stack.
   void RefillMarkingDeque();
 
-  // After reachable maps have been marked process per context object
-  // literal map caches removing unmarked entries.
-  void ProcessMapCaches();
-
   // Callback function for telling whether the object *p is an unmarked
   // heap object.
   static bool IsUnmarkedHeapObject(Object** p);
@@ -808,7 +808,6 @@
   void TrimEnumCache(Map* map, DescriptorArray* descriptors);
 
   void ClearDependentCode(DependentCode* dependent_code);
-  void ClearDependentICList(Object* head);
   void ClearNonLiveDependentCode(DependentCode* dependent_code);
   int ClearNonLiveDependentCodeInGroup(DependentCode* dependent_code, int group,
                                        int start, int end, int new_start);
@@ -827,6 +826,10 @@
   // collections when incremental marking is aborted.
   void AbortWeakCollections();
 
+
+  void ProcessAndClearWeakCells();
+  void AbortWeakCells();
+
   // -----------------------------------------------------------------------
   // Phase 2: Sweeping to clear mark bits and free non-live objects for
   // a non-compacting collection.
@@ -880,6 +883,8 @@
 #endif
 
   Heap* heap_;
+  base::VirtualMemory* marking_deque_memory_;
+  bool marking_deque_memory_committed_;
   MarkingDeque marking_deque_;
   CodeFlusher* code_flusher_;
   bool have_code_to_deoptimize_;
@@ -935,14 +940,14 @@
 };
 
 
-class SequentialSweepingScope BASE_EMBEDDED {
+class EvacuationScope BASE_EMBEDDED {
  public:
-  explicit SequentialSweepingScope(MarkCompactCollector* collector)
+  explicit EvacuationScope(MarkCompactCollector* collector)
       : collector_(collector) {
-    collector_->set_sequential_sweeping(true);
+    collector_->set_evacuation(true);
   }
 
-  ~SequentialSweepingScope() { collector_->set_sequential_sweeping(false); }
+  ~EvacuationScope() { collector_->set_evacuation(false); }
 
  private:
   MarkCompactCollector* collector_;
diff --git a/src/heap/objects-visiting-inl.h b/src/heap/objects-visiting-inl.h
index d220118..e6334f3 100644
--- a/src/heap/objects-visiting-inl.h
+++ b/src/heap/objects-visiting-inl.h
@@ -191,6 +191,8 @@
 
   table_.Register(kVisitPropertyCell, &VisitPropertyCell);
 
+  table_.Register(kVisitWeakCell, &VisitWeakCell);
+
   table_.template RegisterSpecializations<DataObjectVisitor, kVisitDataObject,
                                           kVisitDataObjectGeneric>();
 
@@ -260,12 +262,10 @@
   // when they might be keeping a Context alive, or when the heap is about
   // to be serialized.
   if (FLAG_cleanup_code_caches_at_gc && target->is_inline_cache_stub() &&
-      (target->ic_state() == MEGAMORPHIC || target->ic_state() == GENERIC ||
-       target->ic_state() == POLYMORPHIC ||
-       (heap->flush_monomorphic_ics() && !target->is_weak_stub()) ||
+      !target->is_call_stub() &&
+      ((heap->flush_monomorphic_ics() && !target->embeds_maps_weakly()) ||
        heap->isolate()->serializer_enabled() ||
-       target->ic_age() != heap->global_ic_age() ||
-       target->is_invalidated_weak_stub())) {
+       target->ic_age() != heap->global_ic_age())) {
     ICUtility::Clear(heap->isolate(), rinfo->pc(),
                      rinfo->host()->constant_pool());
     target = Code::GetCodeFromTargetAddress(rinfo->target_address());
@@ -350,6 +350,22 @@
 
 
 template <typename StaticVisitor>
+void StaticMarkingVisitor<StaticVisitor>::VisitWeakCell(Map* map,
+                                                        HeapObject* object) {
+  Heap* heap = map->GetHeap();
+  WeakCell* weak_cell = reinterpret_cast<WeakCell*>(object);
+  Object* undefined = heap->undefined_value();
+  // Enqueue weak cell in linked list of encountered weak collections.
+  // We can ignore weak cells with cleared values because they will always
+  // contain smi zero.
+  if (weak_cell->next() == undefined && !weak_cell->cleared()) {
+    weak_cell->set_next(heap->encountered_weak_cells());
+    heap->set_encountered_weak_cells(weak_cell);
+  }
+}
+
+
+template <typename StaticVisitor>
 void StaticMarkingVisitor<StaticVisitor>::VisitAllocationSite(
     Map* map, HeapObject* object) {
   Heap* heap = map->GetHeap();
@@ -491,10 +507,7 @@
     bool is_weak_object =
         (array->get_weak_object_state() ==
              ConstantPoolArray::WEAK_OBJECTS_IN_OPTIMIZED_CODE &&
-         Code::IsWeakObjectInOptimizedCode(object)) ||
-        (array->get_weak_object_state() ==
-             ConstantPoolArray::WEAK_OBJECTS_IN_IC &&
-         Code::IsWeakObjectInIC(object));
+         Code::IsWeakObjectInOptimizedCode(object));
     if (!is_weak_object) {
       StaticVisitor::MarkObject(heap, object);
     }
diff --git a/src/heap/objects-visiting.cc b/src/heap/objects-visiting.cc
index a0fc231..20d92de 100644
--- a/src/heap/objects-visiting.cc
+++ b/src/heap/objects-visiting.cc
@@ -11,7 +11,7 @@
 
 
 StaticVisitorBase::VisitorId StaticVisitorBase::GetVisitorId(
-    int instance_type, int instance_size) {
+    int instance_type, int instance_size, bool has_unboxed_fields) {
   if (instance_type < FIRST_NONSTRING_TYPE) {
     switch (instance_type & kStringRepresentationMask) {
       case kSeqStringTag:
@@ -33,7 +33,7 @@
 
       case kExternalStringTag:
         return GetVisitorIdForSize(kVisitDataObject, kVisitDataObjectGeneric,
-                                   instance_size);
+                                   instance_size, has_unboxed_fields);
     }
     UNREACHABLE();
   }
@@ -69,13 +69,16 @@
     case PROPERTY_CELL_TYPE:
       return kVisitPropertyCell;
 
+    case WEAK_CELL_TYPE:
+      return kVisitWeakCell;
+
     case JS_SET_TYPE:
       return GetVisitorIdForSize(kVisitStruct, kVisitStructGeneric,
-                                 JSSet::kSize);
+                                 JSSet::kSize, has_unboxed_fields);
 
     case JS_MAP_TYPE:
       return GetVisitorIdForSize(kVisitStruct, kVisitStructGeneric,
-                                 JSMap::kSize);
+                                 JSMap::kSize, has_unboxed_fields);
 
     case JS_WEAK_MAP_TYPE:
     case JS_WEAK_SET_TYPE:
@@ -89,15 +92,15 @@
 
     case JS_PROXY_TYPE:
       return GetVisitorIdForSize(kVisitStruct, kVisitStructGeneric,
-                                 JSProxy::kSize);
+                                 JSProxy::kSize, has_unboxed_fields);
 
     case JS_FUNCTION_PROXY_TYPE:
       return GetVisitorIdForSize(kVisitStruct, kVisitStructGeneric,
-                                 JSFunctionProxy::kSize);
+                                 JSFunctionProxy::kSize, has_unboxed_fields);
 
     case FOREIGN_TYPE:
       return GetVisitorIdForSize(kVisitDataObject, kVisitDataObjectGeneric,
-                                 Foreign::kSize);
+                                 Foreign::kSize, has_unboxed_fields);
 
     case SYMBOL_TYPE:
       return kVisitSymbol;
@@ -128,7 +131,7 @@
     case JS_SET_ITERATOR_TYPE:
     case JS_MAP_ITERATOR_TYPE:
       return GetVisitorIdForSize(kVisitJSObject, kVisitJSObjectGeneric,
-                                 instance_size);
+                                 instance_size, has_unboxed_fields);
 
     case JS_FUNCTION_TYPE:
       return kVisitJSFunction;
@@ -140,7 +143,7 @@
 
       TYPED_ARRAYS(EXTERNAL_ARRAY_CASE)
       return GetVisitorIdForSize(kVisitDataObject, kVisitDataObjectGeneric,
-                                 instance_size);
+                                 instance_size, has_unboxed_fields);
 #undef EXTERNAL_ARRAY_CASE
 
     case FIXED_UINT8_ARRAY_TYPE:
@@ -164,7 +167,7 @@
       }
 
       return GetVisitorIdForSize(kVisitStruct, kVisitStructGeneric,
-                                 instance_size);
+                                 instance_size, has_unboxed_fields);
 
     default:
       UNREACHABLE();
diff --git a/src/heap/objects-visiting.h b/src/heap/objects-visiting.h
index 919a800..a442867 100644
--- a/src/heap/objects-visiting.h
+++ b/src/heap/objects-visiting.h
@@ -6,6 +6,7 @@
 #define V8_OBJECTS_VISITING_H_
 
 #include "src/allocation.h"
+#include "src/layout-descriptor.h"
 
 // This file provides base classes and auxiliary methods for defining
 // static object visitors used during GC.
@@ -71,6 +72,7 @@
   V(Map)                   \
   V(Cell)                  \
   V(PropertyCell)          \
+  V(WeakCell)              \
   V(SharedFunctionInfo)    \
   V(JSFunction)            \
   V(JSWeakCollection)      \
@@ -104,26 +106,35 @@
 
   // Determine which specialized visitor should be used for given instance type
   // and instance type.
-  static VisitorId GetVisitorId(int instance_type, int instance_size);
+  static VisitorId GetVisitorId(int instance_type, int instance_size,
+                                bool has_unboxed_fields);
 
+  // Determine which specialized visitor should be used for given map.
   static VisitorId GetVisitorId(Map* map) {
-    return GetVisitorId(map->instance_type(), map->instance_size());
+    return GetVisitorId(
+        map->instance_type(), map->instance_size(),
+        FLAG_unbox_double_fields && !map->HasFastPointerLayout());
   }
 
   // For visitors that allow specialization by size calculate VisitorId based
   // on size, base visitor id and generic visitor id.
   static VisitorId GetVisitorIdForSize(VisitorId base, VisitorId generic,
-                                       int object_size) {
+                                       int object_size,
+                                       bool has_unboxed_fields) {
     DCHECK((base == kVisitDataObject) || (base == kVisitStruct) ||
            (base == kVisitJSObject));
     DCHECK(IsAligned(object_size, kPointerSize));
     DCHECK(kMinObjectSizeInWords * kPointerSize <= object_size);
     DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
+    DCHECK(!has_unboxed_fields || (base == kVisitJSObject));
 
-    const VisitorId specialization = static_cast<VisitorId>(
-        base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords);
+    if (has_unboxed_fields) return generic;
 
-    return Min(specialization, generic);
+    int visitor_id =
+        Min(base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords,
+            static_cast<int>(generic));
+
+    return static_cast<VisitorId>(visitor_id);
   }
 };
 
@@ -157,7 +168,7 @@
             StaticVisitorBase::VisitorId generic, int object_size_in_words>
   void RegisterSpecialization() {
     static const int size = object_size_in_words * kPointerSize;
-    Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size),
+    Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size, false),
              &Visitor::template VisitSpecialized<size>);
   }
 
@@ -188,11 +199,43 @@
  public:
   INLINE(static void IteratePointers(Heap* heap, HeapObject* object,
                                      int start_offset, int end_offset)) {
-    Object** start_slot =
-        reinterpret_cast<Object**>(object->address() + start_offset);
-    Object** end_slot =
-        reinterpret_cast<Object**>(object->address() + end_offset);
-    StaticVisitor::VisitPointers(heap, start_slot, end_slot);
+    DCHECK(!FLAG_unbox_double_fields || object->map()->HasFastPointerLayout());
+    IterateRawPointers(heap, object, start_offset, end_offset);
+  }
+
+  INLINE(static void IterateBody(Heap* heap, HeapObject* object,
+                                 int start_offset, int end_offset)) {
+    if (!FLAG_unbox_double_fields || object->map()->HasFastPointerLayout()) {
+      IterateRawPointers(heap, object, start_offset, end_offset);
+    } else {
+      IterateBodyUsingLayoutDescriptor(heap, object, start_offset, end_offset);
+    }
+  }
+
+ private:
+  INLINE(static void IterateRawPointers(Heap* heap, HeapObject* object,
+                                        int start_offset, int end_offset)) {
+    StaticVisitor::VisitPointers(heap,
+                                 HeapObject::RawField(object, start_offset),
+                                 HeapObject::RawField(object, end_offset));
+  }
+
+  static void IterateBodyUsingLayoutDescriptor(Heap* heap, HeapObject* object,
+                                               int start_offset,
+                                               int end_offset) {
+    DCHECK(FLAG_unbox_double_fields);
+    DCHECK(IsAligned(start_offset, kPointerSize) &&
+           IsAligned(end_offset, kPointerSize));
+
+    LayoutDescriptorHelper helper(object->map());
+    DCHECK(!helper.all_fields_tagged());
+    for (int offset = start_offset; offset < end_offset;) {
+      int end_of_region_offset;
+      if (helper.IsTagged(offset, end_offset, &end_of_region_offset)) {
+        IterateRawPointers(heap, object, offset, end_of_region_offset);
+      }
+      offset = end_of_region_offset;
+    }
   }
 };
 
@@ -202,7 +245,7 @@
  public:
   INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
     int object_size = BodyDescriptor::SizeOf(map, object);
-    BodyVisitorBase<StaticVisitor>::IteratePointers(
+    BodyVisitorBase<StaticVisitor>::IterateBody(
         map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size);
     return static_cast<ReturnType>(object_size);
   }
@@ -221,9 +264,9 @@
 class FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> {
  public:
   INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
-    BodyVisitorBase<StaticVisitor>::IteratePointers(
-        map->GetHeap(), object, BodyDescriptor::kStartOffset,
-        BodyDescriptor::kEndOffset);
+    BodyVisitorBase<StaticVisitor>::IterateBody(map->GetHeap(), object,
+                                                BodyDescriptor::kStartOffset,
+                                                BodyDescriptor::kEndOffset);
     return static_cast<ReturnType>(BodyDescriptor::kSize);
   }
 };
@@ -362,6 +405,7 @@
   }
 
   INLINE(static void VisitPropertyCell(Map* map, HeapObject* object));
+  INLINE(static void VisitWeakCell(Map* map, HeapObject* object));
   INLINE(static void VisitCodeEntry(Heap* heap, Address entry_address));
   INLINE(static void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo));
   INLINE(static void VisitCell(Heap* heap, RelocInfo* rinfo));
diff --git a/src/heap/spaces.cc b/src/heap/spaces.cc
index f8d340f..060052e 100644
--- a/src/heap/spaces.cc
+++ b/src/heap/spaces.cc
@@ -93,7 +93,8 @@
       code_range_(NULL),
       free_list_(0),
       allocation_list_(0),
-      current_allocation_block_index_(0) {}
+      current_allocation_block_index_(0),
+      emergency_block_() {}
 
 
 bool CodeRange::SetUp(size_t requested) {
@@ -110,6 +111,10 @@
     }
   }
 
+  if (requested <= kMinimumCodeRangeSize) {
+    requested = kMinimumCodeRangeSize;
+  }
+
   DCHECK(!kRequiresCodeRange || requested <= kMaximalCodeRangeSize);
   code_range_ = new base::VirtualMemory(requested);
   CHECK(code_range_ != NULL);
@@ -121,14 +126,27 @@
 
   // We are sure that we have mapped a block of requested addresses.
   DCHECK(code_range_->size() == requested);
-  LOG(isolate_, NewEvent("CodeRange", code_range_->address(), requested));
   Address base = reinterpret_cast<Address>(code_range_->address());
-  Address aligned_base =
-      RoundUp(reinterpret_cast<Address>(code_range_->address()),
-              MemoryChunk::kAlignment);
-  size_t size = code_range_->size() - (aligned_base - base);
+
+  // On some platforms, specifically Win64, we need to reserve some pages at
+  // the beginning of an executable space.
+  if (kReservedCodeRangePages) {
+    if (!code_range_->Commit(
+            base, kReservedCodeRangePages * base::OS::CommitPageSize(), true)) {
+      delete code_range_;
+      code_range_ = NULL;
+      return false;
+    }
+    base += kReservedCodeRangePages * base::OS::CommitPageSize();
+  }
+  Address aligned_base = RoundUp(base, MemoryChunk::kAlignment);
+  size_t size = code_range_->size() - (aligned_base - base) -
+                kReservedCodeRangePages * base::OS::CommitPageSize();
   allocation_list_.Add(FreeBlock(aligned_base, size));
   current_allocation_block_index_ = 0;
+
+  LOG(isolate_, NewEvent("CodeRange", code_range_->address(), requested));
+  ReserveEmergencyBlock();
   return true;
 }
 
@@ -187,35 +205,20 @@
                                      const size_t commit_size,
                                      size_t* allocated) {
   DCHECK(commit_size <= requested_size);
-  DCHECK(allocation_list_.length() == 0 ||
-         current_allocation_block_index_ < allocation_list_.length());
-  if (allocation_list_.length() == 0 ||
-      requested_size > allocation_list_[current_allocation_block_index_].size) {
-    // Find an allocation block large enough.
-    if (!GetNextAllocationBlock(requested_size)) return NULL;
+  FreeBlock current;
+  if (!ReserveBlock(requested_size, &current)) {
+    *allocated = 0;
+    return NULL;
   }
-  // Commit the requested memory at the start of the current allocation block.
-  size_t aligned_requested = RoundUp(requested_size, MemoryChunk::kAlignment);
-  FreeBlock current = allocation_list_[current_allocation_block_index_];
-  if (aligned_requested >= (current.size - Page::kPageSize)) {
-    // Don't leave a small free block, useless for a large object or chunk.
-    *allocated = current.size;
-  } else {
-    *allocated = aligned_requested;
-  }
+  *allocated = current.size;
   DCHECK(*allocated <= current.size);
   DCHECK(IsAddressAligned(current.start, MemoryChunk::kAlignment));
   if (!isolate_->memory_allocator()->CommitExecutableMemory(
           code_range_, current.start, commit_size, *allocated)) {
     *allocated = 0;
+    ReleaseBlock(&current);
     return NULL;
   }
-  allocation_list_[current_allocation_block_index_].start += *allocated;
-  allocation_list_[current_allocation_block_index_].size -= *allocated;
-  if (*allocated == current.size) {
-    // This block is used up, get the next one.
-    GetNextAllocationBlock(0);
-  }
   return current.start;
 }
 
@@ -245,6 +248,49 @@
 }
 
 
+bool CodeRange::ReserveBlock(const size_t requested_size, FreeBlock* block) {
+  DCHECK(allocation_list_.length() == 0 ||
+         current_allocation_block_index_ < allocation_list_.length());
+  if (allocation_list_.length() == 0 ||
+      requested_size > allocation_list_[current_allocation_block_index_].size) {
+    // Find an allocation block large enough.
+    if (!GetNextAllocationBlock(requested_size)) return false;
+  }
+  // Commit the requested memory at the start of the current allocation block.
+  size_t aligned_requested = RoundUp(requested_size, MemoryChunk::kAlignment);
+  *block = allocation_list_[current_allocation_block_index_];
+  // Don't leave a small free block, useless for a large object or chunk.
+  if (aligned_requested < (block->size - Page::kPageSize)) {
+    block->size = aligned_requested;
+  }
+  DCHECK(IsAddressAligned(block->start, MemoryChunk::kAlignment));
+  allocation_list_[current_allocation_block_index_].start += block->size;
+  allocation_list_[current_allocation_block_index_].size -= block->size;
+  return true;
+}
+
+
+void CodeRange::ReleaseBlock(const FreeBlock* block) { free_list_.Add(*block); }
+
+
+void CodeRange::ReserveEmergencyBlock() {
+  const size_t requested_size = MemoryAllocator::CodePageAreaSize();
+  if (emergency_block_.size == 0) {
+    ReserveBlock(requested_size, &emergency_block_);
+  } else {
+    DCHECK(emergency_block_.size >= requested_size);
+  }
+}
+
+
+void CodeRange::ReleaseEmergencyBlock() {
+  if (emergency_block_.size != 0) {
+    ReleaseBlock(&emergency_block_);
+    emergency_block_.size = 0;
+  }
+}
+
+
 // -----------------------------------------------------------------------------
 // MemoryAllocator
 //
@@ -877,18 +923,32 @@
 // -----------------------------------------------------------------------------
 // PagedSpace implementation
 
-PagedSpace::PagedSpace(Heap* heap, intptr_t max_capacity, AllocationSpace id,
+STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::NEW_SPACE) ==
+              ObjectSpace::kObjectSpaceNewSpace);
+STATIC_ASSERT(static_cast<ObjectSpace>(1
+                                       << AllocationSpace::OLD_POINTER_SPACE) ==
+              ObjectSpace::kObjectSpaceOldPointerSpace);
+STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::OLD_DATA_SPACE) ==
+              ObjectSpace::kObjectSpaceOldDataSpace);
+STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::CODE_SPACE) ==
+              ObjectSpace::kObjectSpaceCodeSpace);
+STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::CELL_SPACE) ==
+              ObjectSpace::kObjectSpaceCellSpace);
+STATIC_ASSERT(
+    static_cast<ObjectSpace>(1 << AllocationSpace::PROPERTY_CELL_SPACE) ==
+    ObjectSpace::kObjectSpacePropertyCellSpace);
+STATIC_ASSERT(static_cast<ObjectSpace>(1 << AllocationSpace::MAP_SPACE) ==
+              ObjectSpace::kObjectSpaceMapSpace);
+
+
+PagedSpace::PagedSpace(Heap* heap, intptr_t max_capacity, AllocationSpace space,
                        Executability executable)
-    : Space(heap, id, executable),
+    : Space(heap, space, executable),
       free_list_(this),
       unswept_free_bytes_(0),
       end_of_unswept_pages_(NULL),
       emergency_memory_(NULL) {
-  if (id == CODE_SPACE) {
-    area_size_ = heap->isolate()->memory_allocator()->CodePageAreaSize();
-  } else {
-    area_size_ = Page::kPageSize - Page::kObjectStartOffset;
-  }
+  area_size_ = MemoryAllocator::PageAreaSize(space);
   max_capacity_ =
       (RoundDown(max_capacity, Page::kPageSize) / Page::kPageSize) * AreaSize();
   accounting_stats_.Clear();
@@ -990,7 +1050,7 @@
   int size = 0;
   switch (identity()) {
     case OLD_POINTER_SPACE:
-      size = (112 + constant_pool_delta) * kPointerSize * KB;
+      size = (128 + constant_pool_delta) * kPointerSize * KB;
       break;
     case OLD_DATA_SPACE:
       size = 192 * KB;
@@ -1082,7 +1142,12 @@
     allocation_info_.set_limit(NULL);
   }
 
-  page->Unlink();
+  // If page is still in a list, unlink it from that list.
+  if (page->next_chunk() != NULL) {
+    DCHECK(page->prev_chunk() != NULL);
+    page->Unlink();
+  }
+
   if (page->IsFlagSet(MemoryChunk::CONTAINS_ONLY_DATA)) {
     heap()->isolate()->memory_allocator()->Free(page);
   } else {
@@ -1095,6 +1160,14 @@
 
 
 void PagedSpace::CreateEmergencyMemory() {
+  if (identity() == CODE_SPACE) {
+    // Make the emergency block available to the allocator.
+    CodeRange* code_range = heap()->isolate()->code_range();
+    if (code_range != NULL && code_range->valid()) {
+      code_range->ReleaseEmergencyBlock();
+    }
+    DCHECK(MemoryAllocator::CodePageAreaSize() == AreaSize());
+  }
   emergency_memory_ = heap()->isolate()->memory_allocator()->AllocateChunk(
       AreaSize(), AreaSize(), executable(), this);
 }
@@ -1180,6 +1253,8 @@
   // this chunk must be a power of two and it must be aligned to its size.
   int initial_semispace_capacity = heap()->InitialSemiSpaceSize();
 
+  int target_semispace_capacity = heap()->TargetSemiSpaceSize();
+
   size_t size = 2 * reserved_semispace_capacity;
   Address base = heap()->isolate()->memory_allocator()->ReserveAlignedMemory(
       size, size, &reservation_);
@@ -1208,9 +1283,10 @@
   DCHECK(IsAddressAligned(chunk_base_, 2 * reserved_semispace_capacity, 0));
 
   to_space_.SetUp(chunk_base_, initial_semispace_capacity,
-                  maximum_semispace_capacity);
+                  target_semispace_capacity, maximum_semispace_capacity);
   from_space_.SetUp(chunk_base_ + reserved_semispace_capacity,
-                    initial_semispace_capacity, maximum_semispace_capacity);
+                    initial_semispace_capacity, target_semispace_capacity,
+                    maximum_semispace_capacity);
   if (!to_space_.Commit()) {
     return false;
   }
@@ -1261,7 +1337,8 @@
   // Double the semispace size but only up to maximum capacity.
   DCHECK(TotalCapacity() < MaximumCapacity());
   int new_capacity =
-      Min(MaximumCapacity(), 2 * static_cast<int>(TotalCapacity()));
+      Min(MaximumCapacity(),
+          FLAG_semi_space_growth_factor * static_cast<int>(TotalCapacity()));
   if (to_space_.GrowTo(new_capacity)) {
     // Only grow from space if we managed to grow to-space.
     if (!from_space_.GrowTo(new_capacity)) {
@@ -1270,7 +1347,7 @@
       if (!to_space_.ShrinkTo(from_space_.TotalCapacity())) {
         // We are in an inconsistent state because we could not
         // commit/uncommit memory from new space.
-        V8::FatalProcessOutOfMemory("Failed to grow new space.");
+        CHECK(false);
       }
     }
   }
@@ -1278,6 +1355,36 @@
 }
 
 
+bool NewSpace::GrowOnePage() {
+  if (TotalCapacity() == MaximumCapacity()) return false;
+  int new_capacity = static_cast<int>(TotalCapacity()) + Page::kPageSize;
+  if (to_space_.GrowTo(new_capacity)) {
+    // Only grow from space if we managed to grow to-space and the from space
+    // is actually committed.
+    if (from_space_.is_committed()) {
+      if (!from_space_.GrowTo(new_capacity)) {
+        // If we managed to grow to-space but couldn't grow from-space,
+        // attempt to shrink to-space.
+        if (!to_space_.ShrinkTo(from_space_.TotalCapacity())) {
+          // We are in an inconsistent state because we could not
+          // commit/uncommit memory from new space.
+          CHECK(false);
+        }
+        return false;
+      }
+    } else {
+      if (!from_space_.SetTotalCapacity(new_capacity)) {
+        // Can't really happen, but better safe than sorry.
+        CHECK(false);
+      }
+    }
+    DCHECK_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
+    return true;
+  }
+  return false;
+}
+
+
 void NewSpace::Shrink() {
   int new_capacity = Max(InitialTotalCapacity(), 2 * SizeAsInt());
   int rounded_new_capacity = RoundUp(new_capacity, Page::kPageSize);
@@ -1291,7 +1398,7 @@
       if (!to_space_.GrowTo(from_space_.TotalCapacity())) {
         // We are in an inconsistent state because we could not
         // commit/uncommit memory from new space.
-        V8::FatalProcessOutOfMemory("Failed to shrink new space.");
+        CHECK(false);
       }
     }
   }
@@ -1352,8 +1459,19 @@
     return false;
   }
   if (!to_space_.AdvancePage()) {
-    // Failed to get a new page in to-space.
-    return false;
+    // Check if we reached the target capacity yet. If not, try to commit a page
+    // and continue.
+    if ((to_space_.TotalCapacity() < to_space_.TargetCapacity()) &&
+        GrowOnePage()) {
+      if (!to_space_.AdvancePage()) {
+        // It doesn't make sense that we managed to commit a page, but can't use
+        // it.
+        CHECK(false);
+      }
+    } else {
+      // Failed to get a new page in to-space.
+      return false;
+    }
   }
 
   // Clear remainder of current page.
@@ -1457,7 +1575,7 @@
 // -----------------------------------------------------------------------------
 // SemiSpace implementation
 
-void SemiSpace::SetUp(Address start, int initial_capacity,
+void SemiSpace::SetUp(Address start, int initial_capacity, int target_capacity,
                       int maximum_capacity) {
   // Creates a space in the young generation. The constructor does not
   // allocate memory from the OS.  A SemiSpace is given a contiguous chunk of
@@ -1466,8 +1584,11 @@
   // space is used as the marking stack. It requires contiguous memory
   // addresses.
   DCHECK(maximum_capacity >= Page::kPageSize);
+  DCHECK(initial_capacity <= target_capacity);
+  DCHECK(target_capacity <= maximum_capacity);
   initial_total_capacity_ = RoundDown(initial_capacity, Page::kPageSize);
   total_capacity_ = initial_capacity;
+  target_capacity_ = RoundDown(target_capacity, Page::kPageSize);
   maximum_total_capacity_ = RoundDown(maximum_capacity, Page::kPageSize);
   maximum_committed_ = 0;
   committed_ = false;
@@ -1596,6 +1717,17 @@
 }
 
 
+bool SemiSpace::SetTotalCapacity(int new_capacity) {
+  CHECK(!is_committed());
+  if (new_capacity >= initial_total_capacity_ &&
+      new_capacity <= maximum_total_capacity_) {
+    total_capacity_ = new_capacity;
+    return true;
+  }
+  return false;
+}
+
+
 void SemiSpace::FlipPages(intptr_t flags, intptr_t mask) {
   anchor_.set_owner(this);
   // Fixup back-pointers to anchor. Address of anchor changes
@@ -2500,7 +2632,8 @@
 
 
 intptr_t PagedSpace::SizeOfObjects() {
-  DCHECK(heap()->mark_compact_collector()->sweeping_in_progress() ||
+  DCHECK(!FLAG_concurrent_sweeping ||
+         heap()->mark_compact_collector()->sweeping_in_progress() ||
          (unswept_free_bytes_ == 0));
   return Size() - unswept_free_bytes_ - (limit() - top());
 }
@@ -2840,9 +2973,7 @@
     return AllocationResult::Retry(identity());
   }
 
-  if (Size() + object_size > max_capacity_) {
-    return AllocationResult::Retry(identity());
-  }
+  if (!CanAllocateSize(object_size)) return AllocationResult::Retry(identity());
 
   LargePage* page = heap()->isolate()->memory_allocator()->AllocateLargePage(
       object_size, this, executable);
diff --git a/src/heap/spaces.h b/src/heap/spaces.h
index 9ecb3c4..dcd3364 100644
--- a/src/heap/spaces.h
+++ b/src/heap/spaces.h
@@ -880,6 +880,10 @@
     DCHECK(valid());
     return static_cast<Address>(code_range_->address());
   }
+  size_t size() {
+    DCHECK(valid());
+    return code_range_->size();
+  }
   bool contains(Address address) {
     if (!valid()) return false;
     Address start = static_cast<Address>(code_range_->address());
@@ -896,6 +900,9 @@
   bool UncommitRawMemory(Address start, size_t length);
   void FreeRawMemory(Address buf, size_t length);
 
+  void ReserveEmergencyBlock();
+  void ReleaseEmergencyBlock();
+
  private:
   Isolate* isolate_;
 
@@ -904,6 +911,7 @@
   // Plain old data class, just a struct plus a constructor.
   class FreeBlock {
    public:
+    FreeBlock() : start(0), size(0) {}
     FreeBlock(Address start_arg, size_t size_arg)
         : start(start_arg), size(size_arg) {
       DCHECK(IsAddressAligned(start, MemoryChunk::kAlignment));
@@ -928,6 +936,12 @@
   List<FreeBlock> allocation_list_;
   int current_allocation_block_index_;
 
+  // Emergency block guarantees that we can always allocate a page for
+  // evacuation candidates when code space is compacted. Emergency block is
+  // reserved immediately after GC and is released immedietely before
+  // allocating a page for evacuation.
+  FreeBlock emergency_block_;
+
   // Finds a block on the allocation list that contains at least the
   // requested amount of memory.  If none is found, sorts and merges
   // the existing free memory blocks, and searches again.
@@ -936,6 +950,8 @@
   // Compares the start addresses of two free blocks.
   static int CompareFreeBlockAddress(const FreeBlock* left,
                                      const FreeBlock* right);
+  bool ReserveBlock(const size_t requested_size, FreeBlock* block);
+  void ReleaseBlock(const FreeBlock* block);
 
   DISALLOW_COPY_AND_ASSIGN(CodeRange);
 };
@@ -1100,6 +1116,12 @@
     return CodePageAreaEndOffset() - CodePageAreaStartOffset();
   }
 
+  static int PageAreaSize(AllocationSpace space) {
+    DCHECK_NE(LO_SPACE, space);
+    return (space == CODE_SPACE) ? CodePageAreaSize()
+                                 : Page::kMaxRegularHeapObjectSize;
+  }
+
   MUST_USE_RESULT bool CommitExecutableMemory(base::VirtualMemory* vm,
                                               Address start, size_t commit_size,
                                               size_t reserved_size);
@@ -1604,16 +1626,19 @@
  public:
   // Implicit constructor from Object*.
   AllocationResult(Object* object)  // NOLINT
-      : object_(object),
-        retry_space_(INVALID_SPACE) {}
+      : object_(object) {
+    // AllocationResults can't return Smis, which are used to represent
+    // failure and the space to retry in.
+    CHECK(!object->IsSmi());
+  }
 
-  AllocationResult() : object_(NULL), retry_space_(INVALID_SPACE) {}
+  AllocationResult() : object_(Smi::FromInt(NEW_SPACE)) {}
 
   static inline AllocationResult Retry(AllocationSpace space = NEW_SPACE) {
     return AllocationResult(space);
   }
 
-  inline bool IsRetry() { return retry_space_ != INVALID_SPACE; }
+  inline bool IsRetry() { return object_->IsSmi(); }
 
   template <typename T>
   bool To(T** obj) {
@@ -1629,18 +1654,20 @@
 
   AllocationSpace RetrySpace() {
     DCHECK(IsRetry());
-    return retry_space_;
+    return static_cast<AllocationSpace>(Smi::cast(object_)->value());
   }
 
  private:
   explicit AllocationResult(AllocationSpace space)
-      : object_(NULL), retry_space_(space) {}
+      : object_(Smi::FromInt(static_cast<int>(space))) {}
 
   Object* object_;
-  AllocationSpace retry_space_;
 };
 
 
+STATIC_ASSERT(sizeof(AllocationResult) == kPointerSize);
+
+
 class PagedSpace : public Space {
  public:
   // Creates a space with a maximum capacity, and an id.
@@ -2071,7 +2098,8 @@
         current_page_(NULL) {}
 
   // Sets up the semispace using the given chunk.
-  void SetUp(Address start, int initial_capacity, int maximum_capacity);
+  void SetUp(Address start, int initial_capacity, int target_capacity,
+             int maximum_capacity);
 
   // Tear down the space.  Heap memory was not allocated by the space, so it
   // is not deallocated here.
@@ -2090,6 +2118,9 @@
   // semispace and less than the current capacity.
   bool ShrinkTo(int new_capacity);
 
+  // Sets the total capacity. Only possible when the space is not committed.
+  bool SetTotalCapacity(int new_capacity);
+
   // Returns the start address of the first page of the space.
   Address space_start() {
     DCHECK(anchor_.next_page() != &anchor_);
@@ -2164,6 +2195,9 @@
   // Returns the current total capacity of the semispace.
   int TotalCapacity() { return total_capacity_; }
 
+  // Returns the target for total capacity of the semispace.
+  int TargetCapacity() { return target_capacity_; }
+
   // Returns the maximum total capacity of the semispace.
   int MaximumTotalCapacity() { return maximum_total_capacity_; }
 
@@ -2192,6 +2226,7 @@
 
   // The current and maximum total capacity of the space.
   int total_capacity_;
+  int target_capacity_;
   int maximum_total_capacity_;
   int initial_total_capacity_;
 
@@ -2337,6 +2372,9 @@
   // their maximum capacity.
   void Grow();
 
+  // Grow the capacity of the semispaces by one page.
+  bool GrowOnePage();
+
   // Shrink the capacity of the semispaces.
   void Shrink();
 
@@ -2728,6 +2766,8 @@
   MUST_USE_RESULT AllocationResult
       AllocateRaw(int object_size, Executability executable);
 
+  bool CanAllocateSize(int size) { return Size() + size <= max_capacity_; }
+
   // Available bytes for objects in this space.
   inline intptr_t Available();
 
diff --git a/src/heap/store-buffer.cc b/src/heap/store-buffer.cc
index 278e9f2..aac6811 100644
--- a/src/heap/store-buffer.cc
+++ b/src/heap/store-buffer.cc
@@ -109,7 +109,9 @@
   for (Address* read = old_start_; read < old_top_; read++) {
     Address current = *read;
     if (current != previous) {
-      if (heap_->InNewSpace(*reinterpret_cast<Object**>(current))) {
+      Object* object = reinterpret_cast<Object*>(
+          base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(current)));
+      if (heap_->InNewSpace(object)) {
         *write++ = current;
       }
     }
@@ -507,11 +509,37 @@
             for (HeapObject* heap_object = iterator.Next(); heap_object != NULL;
                  heap_object = iterator.Next()) {
               // We iterate over objects that contain new space pointers only.
-              if (!heap_object->MayContainRawValues()) {
-                FindPointersToNewSpaceInRegion(
-                    heap_object->address() + HeapObject::kHeaderSize,
-                    heap_object->address() + heap_object->Size(), slot_callback,
-                    clear_maps);
+              bool may_contain_raw_values = heap_object->MayContainRawValues();
+              if (!may_contain_raw_values) {
+                Address obj_address = heap_object->address();
+                const int start_offset = HeapObject::kHeaderSize;
+                const int end_offset = heap_object->Size();
+#if V8_DOUBLE_FIELDS_UNBOXING
+                LayoutDescriptorHelper helper(heap_object->map());
+                bool has_only_tagged_fields = helper.all_fields_tagged();
+
+                if (!has_only_tagged_fields) {
+                  for (int offset = start_offset; offset < end_offset;) {
+                    int end_of_region_offset;
+                    if (helper.IsTagged(offset, end_offset,
+                                        &end_of_region_offset)) {
+                      FindPointersToNewSpaceInRegion(
+                          obj_address + offset,
+                          obj_address + end_of_region_offset, slot_callback,
+                          clear_maps);
+                    }
+                    offset = end_of_region_offset;
+                  }
+                } else {
+#endif
+                  Address start_address = obj_address + start_offset;
+                  Address end_address = obj_address + end_offset;
+                  // Object has only tagged fields.
+                  FindPointersToNewSpaceInRegion(start_address, end_address,
+                                                 slot_callback, clear_maps);
+#if V8_DOUBLE_FIELDS_UNBOXING
+                }
+#endif
               }
             }
           }
diff --git a/src/heap/sweeper-thread.cc b/src/heap/sweeper-thread.cc
deleted file mode 100644
index b0e8cea..0000000
--- a/src/heap/sweeper-thread.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/heap/sweeper-thread.h"
-
-#include "src/v8.h"
-
-#include "src/isolate.h"
-#include "src/v8threads.h"
-
-namespace v8 {
-namespace internal {
-
-static const int kSweeperThreadStackSize = 64 * KB;
-
-SweeperThread::SweeperThread(Isolate* isolate)
-    : Thread(Thread::Options("v8:SweeperThread", kSweeperThreadStackSize)),
-      isolate_(isolate),
-      heap_(isolate->heap()),
-      collector_(heap_->mark_compact_collector()),
-      start_sweeping_semaphore_(0),
-      end_sweeping_semaphore_(0),
-      stop_semaphore_(0) {
-  DCHECK(!FLAG_job_based_sweeping);
-  base::NoBarrier_Store(&stop_thread_, static_cast<base::AtomicWord>(false));
-}
-
-
-void SweeperThread::Run() {
-  Isolate::SetIsolateThreadLocals(isolate_, NULL);
-  DisallowHeapAllocation no_allocation;
-  DisallowHandleAllocation no_handles;
-  DisallowHandleDereference no_deref;
-
-  while (true) {
-    start_sweeping_semaphore_.Wait();
-
-    if (base::Acquire_Load(&stop_thread_)) {
-      stop_semaphore_.Signal();
-      return;
-    }
-
-    collector_->SweepInParallel(heap_->old_data_space(), 0);
-    collector_->SweepInParallel(heap_->old_pointer_space(), 0);
-    end_sweeping_semaphore_.Signal();
-  }
-}
-
-
-void SweeperThread::Stop() {
-  base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(true));
-  start_sweeping_semaphore_.Signal();
-  stop_semaphore_.Wait();
-  Join();
-}
-
-
-void SweeperThread::StartSweeping() { start_sweeping_semaphore_.Signal(); }
-
-
-void SweeperThread::WaitForSweeperThread() { end_sweeping_semaphore_.Wait(); }
-
-
-bool SweeperThread::SweepingCompleted() {
-  bool value = end_sweeping_semaphore_.WaitFor(base::TimeDelta::FromSeconds(0));
-  if (value) {
-    end_sweeping_semaphore_.Signal();
-  }
-  return value;
-}
-
-
-int SweeperThread::NumberOfThreads(int max_available) {
-  if (!FLAG_concurrent_sweeping && !FLAG_parallel_sweeping) return 0;
-  if (FLAG_sweeper_threads > 0) return FLAG_sweeper_threads;
-  if (FLAG_concurrent_sweeping) return max_available - 1;
-  DCHECK(FLAG_parallel_sweeping);
-  return max_available;
-}
-}
-}  // namespace v8::internal
diff --git a/src/heap/sweeper-thread.h b/src/heap/sweeper-thread.h
deleted file mode 100644
index fc6bdda..0000000
--- a/src/heap/sweeper-thread.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_HEAP_SWEEPER_THREAD_H_
-#define V8_HEAP_SWEEPER_THREAD_H_
-
-#include "src/base/atomicops.h"
-#include "src/base/platform/platform.h"
-#include "src/flags.h"
-#include "src/utils.h"
-
-#include "src/heap/spaces.h"
-
-#include "src/heap/heap.h"
-
-namespace v8 {
-namespace internal {
-
-class SweeperThread : public base::Thread {
- public:
-  explicit SweeperThread(Isolate* isolate);
-  ~SweeperThread() {}
-
-  void Run();
-  void Stop();
-  void StartSweeping();
-  void WaitForSweeperThread();
-  bool SweepingCompleted();
-
-  static int NumberOfThreads(int max_available);
-
- private:
-  Isolate* isolate_;
-  Heap* heap_;
-  MarkCompactCollector* collector_;
-  base::Semaphore start_sweeping_semaphore_;
-  base::Semaphore end_sweeping_semaphore_;
-  base::Semaphore stop_semaphore_;
-  volatile base::AtomicWord stop_thread_;
-};
-}
-}  // namespace v8::internal
-
-#endif  // V8_HEAP_SWEEPER_THREAD_H_
diff --git a/src/hydrogen-bch.cc b/src/hydrogen-bch.cc
index 5af6030..2feb158 100644
--- a/src/hydrogen-bch.cc
+++ b/src/hydrogen-bch.cc
@@ -237,14 +237,13 @@
     // constant limit we will use that instead of the induction limit.
     bool has_upper_constant_limit = true;
     int32_t upper_constant_limit =
-        check != NULL && check->HasUpperLimit() ? check->upper_limit() : 0;
+        check->HasUpperLimit() ? check->upper_limit() : 0;
     for (InductionVariableData::InductionVariableCheck* current_check = check;
          current_check != NULL;
          current_check = current_check->next()) {
       has_upper_constant_limit =
-          has_upper_constant_limit &&
-          check->HasUpperLimit() &&
-          check->upper_limit() == upper_constant_limit;
+          has_upper_constant_limit && current_check->HasUpperLimit() &&
+          current_check->upper_limit() == upper_constant_limit;
       counters()->bounds_checks_eliminated()->Increment();
       current_check->check()->set_skip_check();
     }
diff --git a/src/hydrogen-dce.cc b/src/hydrogen-dce.cc
index c55426d..360b694 100644
--- a/src/hydrogen-dce.cc
+++ b/src/hydrogen-dce.cc
@@ -39,7 +39,7 @@
   } else {
     os << "root ";
   }
-  os << " -> " << *instr << "]" << endl;
+  os << " -> " << *instr << "]" << std::endl;
 }
 
 
diff --git a/src/hydrogen-gvn.cc b/src/hydrogen-gvn.cc
index be1e17b..da986e3 100644
--- a/src/hydrogen-gvn.cc
+++ b/src/hydrogen-gvn.cc
@@ -400,7 +400,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const TrackedEffects& te) {
+std::ostream& operator<<(std::ostream& os, const TrackedEffects& te) {
   SideEffectsTracker* t = te.tracker;
   const char* separator = "";
   os << "[";
@@ -450,7 +450,7 @@
     if (FLAG_trace_gvn) {
       OFStream os(stdout);
       os << "Tracking global var [" << *cell.handle() << "] "
-         << "(mapped to index " << num_global_vars_ << ")" << endl;
+         << "(mapped to index " << num_global_vars_ << ")" << std::endl;
     }
     *index = num_global_vars_;
     global_vars_[num_global_vars_++] = cell;
@@ -472,7 +472,7 @@
     if (FLAG_trace_gvn) {
       OFStream os(stdout);
       os << "Tracking inobject field access " << access << " (mapped to index "
-         << num_inobject_fields_ << ")" << endl;
+         << num_inobject_fields_ << ")" << std::endl;
     }
     *index = num_inobject_fields_;
     inobject_fields_[num_inobject_fields_++] = access;
@@ -567,7 +567,7 @@
       if (FLAG_trace_gvn) {
         OFStream os(stdout);
         os << "Try loop invariant motion for " << *block << " changes "
-           << Print(side_effects) << endl;
+           << Print(side_effects) << std::endl;
       }
       HBasicBlock* last = block->loop_information()->GetLastBackEdge();
       for (int j = block->block_id(); j <= last->block_id(); ++j) {
@@ -586,7 +586,7 @@
   if (FLAG_trace_gvn) {
     OFStream os(stdout);
     os << "Loop invariant code motion for " << *block << " depends on "
-       << Print(loop_kills) << endl;
+       << Print(loop_kills) << std::endl;
   }
   HInstruction* instr = block->first();
   while (instr != NULL) {
@@ -599,7 +599,7 @@
         os << "Checking instruction i" << instr->id() << " ("
            << instr->Mnemonic() << ") changes " << Print(changes)
            << ", depends on " << Print(depends_on) << ". Loop changes "
-           << Print(loop_kills) << endl;
+           << Print(loop_kills) << std::endl;
       }
       bool can_hoist = !depends_on.ContainsAnyOf(loop_kills);
       if (can_hoist && !graph()->use_optimistic_licm()) {
@@ -836,7 +836,7 @@
         if (FLAG_trace_gvn) {
           OFStream os(stdout);
           os << "Instruction i" << instr->id() << " changes " << Print(changes)
-             << endl;
+             << std::endl;
         }
       }
       if (instr->CheckFlag(HValue::kUseGVN) &&
diff --git a/src/hydrogen-gvn.h b/src/hydrogen-gvn.h
index 8cdeb99..421c6cc 100644
--- a/src/hydrogen-gvn.h
+++ b/src/hydrogen-gvn.h
@@ -5,6 +5,8 @@
 #ifndef V8_HYDROGEN_GVN_H_
 #define V8_HYDROGEN_GVN_H_
 
+#include <iosfwd>
+
 #include "src/compiler.h"
 #include "src/hydrogen.h"
 #include "src/hydrogen-instructions.h"
@@ -13,8 +15,6 @@
 namespace v8 {
 namespace internal {
 
-class OStream;
-
 // This class extends GVNFlagSet with additional "special" dynamic side effects,
 // which can be used to represent side effects that cannot be expressed using
 // the GVNFlags of an HInstruction. These special side effects are tracked by a
@@ -70,7 +70,7 @@
   SideEffects ComputeDependsOn(HInstruction* instr);
 
  private:
-  friend OStream& operator<<(OStream& os, const TrackedEffects& f);
+  friend std::ostream& operator<<(std::ostream& os, const TrackedEffects& f);
   bool ComputeGlobalVar(Unique<Cell> cell, int* index);
   bool ComputeInobjectField(HObjectAccess access, int* index);
 
@@ -107,7 +107,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const TrackedEffects& f);
+std::ostream& operator<<(std::ostream& os, const TrackedEffects& f);
 
 
 // Perform common subexpression elimination and loop-invariant code motion.
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index a057217..0e6a03d 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -528,10 +528,12 @@
 }
 
 
-OStream& operator<<(OStream& os, const HValue& v) { return v.PrintTo(os); }
+std::ostream& operator<<(std::ostream& os, const HValue& v) {
+  return v.PrintTo(os);
+}
 
 
-OStream& operator<<(OStream& os, const TypeOf& t) {
+std::ostream& operator<<(std::ostream& os, const TypeOf& t) {
   if (t.value->representation().IsTagged() &&
       !t.value->type().Equals(HType::Tagged()))
     return os;
@@ -539,7 +541,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const ChangesOf& c) {
+std::ostream& operator<<(std::ostream& os, const ChangesOf& c) {
   GVNFlagSet changes_flags = c.value->ChangesFlags();
   if (changes_flags.IsEmpty()) return os;
   os << " changes[";
@@ -618,7 +620,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const HSourcePosition& p) {
+std::ostream& operator<<(std::ostream& os, const HSourcePosition& p) {
   if (p.IsUnknown()) {
     return os << "<?>";
   } else if (FLAG_hydrogen_track_positions) {
@@ -629,7 +631,7 @@
 }
 
 
-OStream& HInstruction::PrintTo(OStream& os) const {  // NOLINT
+std::ostream& HInstruction::PrintTo(std::ostream& os) const {  // NOLINT
   os << Mnemonic() << " ";
   PrintDataTo(os) << ChangesOf(this) << TypeOf(this);
   if (CheckFlag(HValue::kHasNoObservableSideEffects)) os << " [noOSE]";
@@ -638,7 +640,7 @@
 }
 
 
-OStream& HInstruction::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HInstruction::PrintDataTo(std::ostream& os) const {  // NOLINT
   for (int i = 0; i < OperandCount(); ++i) {
     if (i > 0) os << " ";
     os << NameOf(OperandAt(i));
@@ -794,7 +796,6 @@
     case HValue::kCallNew:
     case HValue::kCallNewArray:
     case HValue::kCallStub:
-    case HValue::kCallWithDescriptor:
     case HValue::kCapturedObject:
     case HValue::kClassOfTestAndBranch:
     case HValue::kCompareGeneric:
@@ -861,6 +862,7 @@
     case HValue::kBranch:
     case HValue::kCallJSFunction:
     case HValue::kCallRuntime:
+    case HValue::kCallWithDescriptor:
     case HValue::kChange:
     case HValue::kCheckHeapObject:
     case HValue::kCheckInstanceType:
@@ -912,27 +914,28 @@
 }
 
 
-OStream& operator<<(OStream& os, const NameOf& v) {
+std::ostream& operator<<(std::ostream& os, const NameOf& v) {
   return os << v.value->representation().Mnemonic() << v.value->id();
 }
 
-OStream& HDummyUse::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HDummyUse::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(value());
 }
 
 
-OStream& HEnvironmentMarker::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HEnvironmentMarker::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   return os << (kind() == BIND ? "bind" : "lookup") << " var[" << index()
             << "]";
 }
 
 
-OStream& HUnaryCall::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HUnaryCall::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(value()) << " #" << argument_count();
 }
 
 
-OStream& HCallJSFunction::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCallJSFunction::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(function()) << " #" << argument_count();
 }
 
@@ -959,7 +962,7 @@
 }
 
 
-OStream& HBinaryCall::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HBinaryCall::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(first()) << " " << NameOf(second()) << " #"
             << argument_count();
 }
@@ -1015,7 +1018,7 @@
 }
 
 
-OStream& HBoundsCheck::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HBoundsCheck::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << NameOf(index()) << " " << NameOf(length());
   if (base() != NULL && (offset() != 0 || scale() != 0)) {
     os << " base: ((";
@@ -1070,15 +1073,16 @@
 }
 
 
-OStream& HBoundsCheckBaseIndexInformation::PrintDataTo(
-    OStream& os) const {  // NOLINT
+std::ostream& HBoundsCheckBaseIndexInformation::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   // TODO(svenpanne) This 2nd base_index() looks wrong...
   return os << "base: " << NameOf(base_index())
             << ", check: " << NameOf(base_index());
 }
 
 
-OStream& HCallWithDescriptor::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCallWithDescriptor::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   for (int i = 0; i < OperandCount(); i++) {
     os << NameOf(OperandAt(i)) << " ";
   }
@@ -1086,42 +1090,46 @@
 }
 
 
-OStream& HCallNewArray::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCallNewArray::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << ElementsKindToString(elements_kind()) << " ";
   return HBinaryCall::PrintDataTo(os);
 }
 
 
-OStream& HCallRuntime::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCallRuntime::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << name()->ToCString().get() << " ";
   if (save_doubles() == kSaveFPRegs) os << "[save doubles] ";
   return os << "#" << argument_count();
 }
 
 
-OStream& HClassOfTestAndBranch::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HClassOfTestAndBranch::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   return os << "class_of_test(" << NameOf(value()) << ", \""
             << class_name()->ToCString().get() << "\")";
 }
 
 
-OStream& HWrapReceiver::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HWrapReceiver::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(receiver()) << " " << NameOf(function());
 }
 
 
-OStream& HAccessArgumentsAt::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HAccessArgumentsAt::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   return os << NameOf(arguments()) << "[" << NameOf(index()) << "], length "
             << NameOf(length());
 }
 
 
-OStream& HAllocateBlockContext::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HAllocateBlockContext::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   return os << NameOf(context()) << " " << NameOf(function());
 }
 
 
-OStream& HControlInstruction::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HControlInstruction::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   os << " goto (";
   bool first_block = true;
   for (HSuccessorIterator it(this); !it.Done(); it.Advance()) {
@@ -1133,25 +1141,24 @@
 }
 
 
-OStream& HUnaryControlInstruction::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HUnaryControlInstruction::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   os << NameOf(value());
   return HControlInstruction::PrintDataTo(os);
 }
 
 
-OStream& HReturn::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HReturn::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(value()) << " (pop " << NameOf(parameter_count())
             << " values)";
 }
 
 
 Representation HBranch::observed_input_representation(int index) {
-  static const ToBooleanStub::Types tagged_types(
-      ToBooleanStub::NULL_TYPE |
-      ToBooleanStub::SPEC_OBJECT |
-      ToBooleanStub::STRING |
-      ToBooleanStub::SYMBOL);
-  if (expected_input_types_.ContainsAnyOf(tagged_types)) {
+  if (expected_input_types_.Contains(ToBooleanStub::NULL_TYPE) ||
+      expected_input_types_.Contains(ToBooleanStub::SPEC_OBJECT) ||
+      expected_input_types_.Contains(ToBooleanStub::STRING) ||
+      expected_input_types_.Contains(ToBooleanStub::SYMBOL)) {
     return Representation::Tagged();
   }
   if (expected_input_types_.Contains(ToBooleanStub::UNDEFINED)) {
@@ -1185,13 +1192,13 @@
 }
 
 
-OStream& HBranch::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HBranch::PrintDataTo(std::ostream& os) const {  // NOLINT
   return HUnaryControlInstruction::PrintDataTo(os) << " "
                                                    << expected_input_types();
 }
 
 
-OStream& HCompareMap::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCompareMap::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << NameOf(value()) << " (" << *map().handle() << ")";
   HControlInstruction::PrintDataTo(os);
   if (known_successor_index() == 0) {
@@ -1255,17 +1262,19 @@
 }
 
 
-OStream& HUnaryMathOperation::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HUnaryMathOperation::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   return os << OpName() << " " << NameOf(value());
 }
 
 
-OStream& HUnaryOperation::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HUnaryOperation::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(value());
 }
 
 
-OStream& HHasInstanceTypeAndBranch::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HHasInstanceTypeAndBranch::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   os << NameOf(value());
   switch (from_) {
     case FIRST_JS_RECEIVER_TYPE:
@@ -1287,7 +1296,8 @@
 }
 
 
-OStream& HTypeofIsAndBranch::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HTypeofIsAndBranch::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   os << NameOf(value()) << " == " << type_literal()->ToCString().get();
   return HControlInstruction::PrintDataTo(os);
 }
@@ -1340,7 +1350,7 @@
 }
 
 
-OStream& HCheckMapValue::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCheckMapValue::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(value()) << " " << NameOf(map());
 }
 
@@ -1356,18 +1366,19 @@
 }
 
 
-OStream& HForInPrepareMap::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HForInPrepareMap::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(enumerable());
 }
 
 
-OStream& HForInCacheArray::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HForInCacheArray::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(enumerable()) << " " << NameOf(map()) << "[" << idx_
             << "]";
 }
 
 
-OStream& HLoadFieldByIndex::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HLoadFieldByIndex::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   return os << NameOf(object()) << " " << NameOf(index());
 }
 
@@ -1504,7 +1515,7 @@
 }
 
 
-OStream& HTypeof::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HTypeof::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(value());
 }
 
@@ -1520,12 +1531,13 @@
 }
 
 
-OStream& HForceRepresentation::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HForceRepresentation::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   return os << representation().Mnemonic() << " " << NameOf(value());
 }
 
 
-OStream& HChange::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HChange::PrintDataTo(std::ostream& os) const {  // NOLINT
   HUnaryOperation::PrintDataTo(os);
   os << " " << from().Mnemonic() << " to " << to().Mnemonic();
 
@@ -1637,7 +1649,7 @@
 }
 
 
-OStream& HCheckMaps::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCheckMaps::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << NameOf(value()) << " [" << *maps()->at(0).handle();
   for (int i = 1; i < maps()->size(); ++i) {
     os << "," << *maps()->at(i).handle();
@@ -1668,7 +1680,7 @@
 }
 
 
-OStream& HCheckValue::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCheckValue::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(value()) << " " << Brief(*object().handle());
 }
 
@@ -1691,20 +1703,28 @@
 }
 
 
-OStream& HCheckInstanceType::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCheckInstanceType::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   os << GetCheckName() << " ";
   return HUnaryOperation::PrintDataTo(os);
 }
 
 
-OStream& HCallStub::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCallStub::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << CodeStub::MajorName(major_key_, false) << " ";
   return HUnaryCall::PrintDataTo(os);
 }
 
 
-OStream& HTailCallThroughMegamorphicCache::PrintDataTo(
-    OStream& os) const {  // NOLINT
+Code::Flags HTailCallThroughMegamorphicCache::flags() const {
+  Code::Flags code_flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::LOAD_IC));
+  return code_flags;
+}
+
+
+std::ostream& HTailCallThroughMegamorphicCache::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   for (int i = 0; i < OperandCount(); i++) {
     os << NameOf(OperandAt(i)) << " ";
   }
@@ -1712,7 +1732,7 @@
 }
 
 
-OStream& HUnknownOSRValue::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HUnknownOSRValue::PrintDataTo(std::ostream& os) const {  // NOLINT
   const char* type = "expression";
   if (environment_->is_local_index(index_)) type = "local";
   if (environment_->is_special_index(index_)) type = "special";
@@ -1721,7 +1741,7 @@
 }
 
 
-OStream& HInstanceOf::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HInstanceOf::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(left()) << " " << NameOf(right()) << " "
             << NameOf(context());
 }
@@ -1774,7 +1794,7 @@
 
 
 Range* HConstant::InferRange(Zone* zone) {
-  if (has_int32_value_) {
+  if (HasInteger32Value()) {
     Range* result = new(zone) Range(int32_value_, int32_value_);
     result->set_can_be_minus_zero(false);
     return result;
@@ -2196,7 +2216,7 @@
  */
 int32_t InductionVariableData::ComputeIncrement(HPhi* phi,
                                                 HValue* phi_operand) {
-  if (!phi_operand->representation().IsInteger32()) return 0;
+  if (!phi_operand->representation().IsSmiOrInteger32()) return 0;
 
   if (phi_operand->IsAdd()) {
     HAdd* operation = HAdd::cast(phi_operand);
@@ -2439,7 +2459,7 @@
 }
 
 
-OStream& HPhi::PrintTo(OStream& os) const {  // NOLINT
+std::ostream& HPhi::PrintTo(std::ostream& os) const {  // NOLINT
   os << "[";
   for (int i = 0; i < OperandCount(); ++i) {
     os << " " << NameOf(OperandAt(i)) << " ";
@@ -2571,7 +2591,7 @@
 }
 
 
-OStream& HSimulate::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HSimulate::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << "id=" << ast_id().ToInt();
   if (pop_count_ > 0) os << " pop " << pop_count_;
   if (values_.length() > 0) {
@@ -2591,7 +2611,7 @@
 
 
 void HSimulate::ReplayEnvironment(HEnvironment* env) {
-  if (done_with_replay_) return;
+  if (is_done_with_replay()) return;
   DCHECK(env != NULL);
   env->set_ast_id(ast_id());
   env->Drop(pop_count());
@@ -2603,7 +2623,7 @@
       env->Push(value);
     }
   }
-  done_with_replay_ = true;
+  set_done_with_replay();
 }
 
 
@@ -2633,7 +2653,7 @@
 }
 
 
-OStream& HCapturedObject::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCapturedObject::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << "#" << capture_id() << " ";
   return HDematerializedObject::PrintDataTo(os);
 }
@@ -2646,49 +2666,57 @@
 }
 
 
-OStream& HEnterInlined::PrintDataTo(OStream& os) const {  // NOLINT
-  return os << function()->debug_name()->ToCString().get()
-            << ", id=" << function()->id().ToInt();
+std::ostream& HEnterInlined::PrintDataTo(std::ostream& os) const {  // NOLINT
+  return os << function()->debug_name()->ToCString().get();
 }
 
 
 static bool IsInteger32(double value) {
-  double roundtrip_value = static_cast<double>(static_cast<int32_t>(value));
-  return bit_cast<int64_t>(roundtrip_value) == bit_cast<int64_t>(value);
+  if (value >= std::numeric_limits<int32_t>::min() &&
+      value <= std::numeric_limits<int32_t>::max()) {
+    double roundtrip_value = static_cast<double>(static_cast<int32_t>(value));
+    return bit_cast<int64_t>(roundtrip_value) == bit_cast<int64_t>(value);
+  }
+  return false;
 }
 
 
 HConstant::HConstant(Handle<Object> object, Representation r)
-  : HTemplateInstruction<0>(HType::FromValue(object)),
-    object_(Unique<Object>::CreateUninitialized(object)),
-    object_map_(Handle<Map>::null()),
-    has_stable_map_value_(false),
-    has_smi_value_(false),
-    has_int32_value_(false),
-    has_double_value_(false),
-    has_external_reference_value_(false),
-    is_not_in_new_space_(true),
-    boolean_value_(object->BooleanValue()),
-    is_undetectable_(false),
-    instance_type_(kUnknownInstanceType) {
+    : HTemplateInstruction<0>(HType::FromValue(object)),
+      object_(Unique<Object>::CreateUninitialized(object)),
+      object_map_(Handle<Map>::null()),
+      bit_field_(HasStableMapValueField::encode(false) |
+                 HasSmiValueField::encode(false) |
+                 HasInt32ValueField::encode(false) |
+                 HasDoubleValueField::encode(false) |
+                 HasExternalReferenceValueField::encode(false) |
+                 IsNotInNewSpaceField::encode(true) |
+                 BooleanValueField::encode(object->BooleanValue()) |
+                 IsUndetectableField::encode(false) |
+                 InstanceTypeField::encode(kUnknownInstanceType)) {
   if (object->IsHeapObject()) {
     Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
     Isolate* isolate = heap_object->GetIsolate();
     Handle<Map> map(heap_object->map(), isolate);
-    is_not_in_new_space_ = !isolate->heap()->InNewSpace(*object);
-    instance_type_ = map->instance_type();
-    is_undetectable_ = map->is_undetectable();
+    bit_field_ = IsNotInNewSpaceField::update(
+        bit_field_, !isolate->heap()->InNewSpace(*object));
+    bit_field_ = InstanceTypeField::update(bit_field_, map->instance_type());
+    bit_field_ =
+        IsUndetectableField::update(bit_field_, map->is_undetectable());
     if (map->is_stable()) object_map_ = Unique<Map>::CreateImmovable(map);
-    has_stable_map_value_ = (instance_type_ == MAP_TYPE &&
-                             Handle<Map>::cast(heap_object)->is_stable());
+    bit_field_ = HasStableMapValueField::update(
+        bit_field_,
+        HasMapValue() && Handle<Map>::cast(heap_object)->is_stable());
   }
   if (object->IsNumber()) {
     double n = object->Number();
-    has_int32_value_ = IsInteger32(n);
+    bool has_int32_value = IsInteger32(n);
+    bit_field_ = HasInt32ValueField::update(bit_field_, has_int32_value);
     int32_value_ = DoubleToInt32(n);
-    has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
+    bit_field_ = HasSmiValueField::update(
+        bit_field_, has_int32_value && Smi::IsValid(int32_value_));
     double_value_ = n;
-    has_double_value_ = true;
+    bit_field_ = HasDoubleValueField::update(bit_field_, true);
     // TODO(titzer): if this heap number is new space, tenure a new one.
   }
 
@@ -2696,112 +2724,104 @@
 }
 
 
-HConstant::HConstant(Unique<Object> object,
-                     Unique<Map> object_map,
-                     bool has_stable_map_value,
-                     Representation r,
-                     HType type,
-                     bool is_not_in_new_space,
-                     bool boolean_value,
-                     bool is_undetectable,
-                     InstanceType instance_type)
-  : HTemplateInstruction<0>(type),
-    object_(object),
-    object_map_(object_map),
-    has_stable_map_value_(has_stable_map_value),
-    has_smi_value_(false),
-    has_int32_value_(false),
-    has_double_value_(false),
-    has_external_reference_value_(false),
-    is_not_in_new_space_(is_not_in_new_space),
-    boolean_value_(boolean_value),
-    is_undetectable_(is_undetectable),
-    instance_type_(instance_type) {
+HConstant::HConstant(Unique<Object> object, Unique<Map> object_map,
+                     bool has_stable_map_value, Representation r, HType type,
+                     bool is_not_in_new_space, bool boolean_value,
+                     bool is_undetectable, InstanceType instance_type)
+    : HTemplateInstruction<0>(type),
+      object_(object),
+      object_map_(object_map),
+      bit_field_(HasStableMapValueField::encode(has_stable_map_value) |
+                 HasSmiValueField::encode(false) |
+                 HasInt32ValueField::encode(false) |
+                 HasDoubleValueField::encode(false) |
+                 HasExternalReferenceValueField::encode(false) |
+                 IsNotInNewSpaceField::encode(is_not_in_new_space) |
+                 BooleanValueField::encode(boolean_value) |
+                 IsUndetectableField::encode(is_undetectable) |
+                 InstanceTypeField::encode(instance_type)) {
   DCHECK(!object.handle().is_null());
   DCHECK(!type.IsTaggedNumber() || type.IsNone());
   Initialize(r);
 }
 
 
-HConstant::HConstant(int32_t integer_value,
-                     Representation r,
-                     bool is_not_in_new_space,
-                     Unique<Object> object)
-  : object_(object),
-    object_map_(Handle<Map>::null()),
-    has_stable_map_value_(false),
-    has_smi_value_(Smi::IsValid(integer_value)),
-    has_int32_value_(true),
-    has_double_value_(true),
-    has_external_reference_value_(false),
-    is_not_in_new_space_(is_not_in_new_space),
-    boolean_value_(integer_value != 0),
-    is_undetectable_(false),
-    int32_value_(integer_value),
-    double_value_(FastI2D(integer_value)),
-    instance_type_(kUnknownInstanceType) {
+HConstant::HConstant(int32_t integer_value, Representation r,
+                     bool is_not_in_new_space, Unique<Object> object)
+    : object_(object),
+      object_map_(Handle<Map>::null()),
+      bit_field_(HasStableMapValueField::encode(false) |
+                 HasSmiValueField::encode(Smi::IsValid(integer_value)) |
+                 HasInt32ValueField::encode(true) |
+                 HasDoubleValueField::encode(true) |
+                 HasExternalReferenceValueField::encode(false) |
+                 IsNotInNewSpaceField::encode(is_not_in_new_space) |
+                 BooleanValueField::encode(integer_value != 0) |
+                 IsUndetectableField::encode(false) |
+                 InstanceTypeField::encode(kUnknownInstanceType)),
+      int32_value_(integer_value),
+      double_value_(FastI2D(integer_value)) {
   // It's possible to create a constant with a value in Smi-range but stored
   // in a (pre-existing) HeapNumber. See crbug.com/349878.
   bool could_be_heapobject = r.IsTagged() && !object.handle().is_null();
-  bool is_smi = has_smi_value_ && !could_be_heapobject;
+  bool is_smi = HasSmiValue() && !could_be_heapobject;
   set_type(is_smi ? HType::Smi() : HType::TaggedNumber());
   Initialize(r);
 }
 
 
-HConstant::HConstant(double double_value,
-                     Representation r,
-                     bool is_not_in_new_space,
-                     Unique<Object> object)
-  : object_(object),
-    object_map_(Handle<Map>::null()),
-    has_stable_map_value_(false),
-    has_int32_value_(IsInteger32(double_value)),
-    has_double_value_(true),
-    has_external_reference_value_(false),
-    is_not_in_new_space_(is_not_in_new_space),
-    boolean_value_(double_value != 0 && !std::isnan(double_value)),
-    is_undetectable_(false),
-    int32_value_(DoubleToInt32(double_value)),
-    double_value_(double_value),
-    instance_type_(kUnknownInstanceType) {
-  has_smi_value_ = has_int32_value_ && Smi::IsValid(int32_value_);
+HConstant::HConstant(double double_value, Representation r,
+                     bool is_not_in_new_space, Unique<Object> object)
+    : object_(object),
+      object_map_(Handle<Map>::null()),
+      bit_field_(HasStableMapValueField::encode(false) |
+                 HasInt32ValueField::encode(IsInteger32(double_value)) |
+                 HasDoubleValueField::encode(true) |
+                 HasExternalReferenceValueField::encode(false) |
+                 IsNotInNewSpaceField::encode(is_not_in_new_space) |
+                 BooleanValueField::encode(double_value != 0 &&
+                                           !std::isnan(double_value)) |
+                 IsUndetectableField::encode(false) |
+                 InstanceTypeField::encode(kUnknownInstanceType)),
+      int32_value_(HasInteger32Value() ? DoubleToInt32(double_value) : 0),
+      double_value_(double_value) {
+  bit_field_ = HasSmiValueField::update(
+      bit_field_, HasInteger32Value() && Smi::IsValid(int32_value_));
   // It's possible to create a constant with a value in Smi-range but stored
   // in a (pre-existing) HeapNumber. See crbug.com/349878.
   bool could_be_heapobject = r.IsTagged() && !object.handle().is_null();
-  bool is_smi = has_smi_value_ && !could_be_heapobject;
+  bool is_smi = HasSmiValue() && !could_be_heapobject;
   set_type(is_smi ? HType::Smi() : HType::TaggedNumber());
   Initialize(r);
 }
 
 
 HConstant::HConstant(ExternalReference reference)
-  : HTemplateInstruction<0>(HType::Any()),
-    object_(Unique<Object>(Handle<Object>::null())),
-    object_map_(Handle<Map>::null()),
-    has_stable_map_value_(false),
-    has_smi_value_(false),
-    has_int32_value_(false),
-    has_double_value_(false),
-    has_external_reference_value_(true),
-    is_not_in_new_space_(true),
-    boolean_value_(true),
-    is_undetectable_(false),
-    external_reference_value_(reference),
-    instance_type_(kUnknownInstanceType) {
+    : HTemplateInstruction<0>(HType::Any()),
+      object_(Unique<Object>(Handle<Object>::null())),
+      object_map_(Handle<Map>::null()),
+      bit_field_(
+          HasStableMapValueField::encode(false) |
+          HasSmiValueField::encode(false) | HasInt32ValueField::encode(false) |
+          HasDoubleValueField::encode(false) |
+          HasExternalReferenceValueField::encode(true) |
+          IsNotInNewSpaceField::encode(true) | BooleanValueField::encode(true) |
+          IsUndetectableField::encode(false) |
+          InstanceTypeField::encode(kUnknownInstanceType)),
+      external_reference_value_(reference) {
   Initialize(Representation::External());
 }
 
 
 void HConstant::Initialize(Representation r) {
   if (r.IsNone()) {
-    if (has_smi_value_ && SmiValuesAre31Bits()) {
+    if (HasSmiValue() && SmiValuesAre31Bits()) {
       r = Representation::Smi();
-    } else if (has_int32_value_) {
+    } else if (HasInteger32Value()) {
       r = Representation::Integer32();
-    } else if (has_double_value_) {
+    } else if (HasDoubleValue()) {
       r = Representation::Double();
-    } else if (has_external_reference_value_) {
+    } else if (HasExternalReferenceValue()) {
       r = Representation::External();
     } else {
       Handle<Object> object = object_.handle();
@@ -2822,22 +2842,26 @@
     // could cause heap object checks not to get emitted.
     object_ = Unique<Object>(Handle<Object>::null());
   }
+  if (r.IsSmiOrInteger32()) {
+    // If it's not a heap object, it can't be in new space.
+    bit_field_ = IsNotInNewSpaceField::update(bit_field_, true);
+  }
   set_representation(r);
   SetFlag(kUseGVN);
 }
 
 
 bool HConstant::ImmortalImmovable() const {
-  if (has_int32_value_) {
+  if (HasInteger32Value()) {
     return false;
   }
-  if (has_double_value_) {
+  if (HasDoubleValue()) {
     if (IsSpecialDouble()) {
       return true;
     }
     return false;
   }
-  if (has_external_reference_value_) {
+  if (HasExternalReferenceValue()) {
     return false;
   }
 
@@ -2847,7 +2871,7 @@
   DCHECK(!object_.IsKnownGlobal(heap->nan_value()));
   return
 #define IMMORTAL_IMMOVABLE_ROOT(name) \
-      object_.IsKnownGlobal(heap->name()) ||
+  object_.IsKnownGlobal(heap->root(Heap::k##name##RootIndex)) ||
       IMMORTAL_IMMOVABLE_ROOT_LIST(IMMORTAL_IMMOVABLE_ROOT)
 #undef IMMORTAL_IMMOVABLE_ROOT
 #define INTERNALIZED_STRING(name, value) \
@@ -2878,44 +2902,35 @@
 
 
 HConstant* HConstant::CopyToRepresentation(Representation r, Zone* zone) const {
-  if (r.IsSmi() && !has_smi_value_) return NULL;
-  if (r.IsInteger32() && !has_int32_value_) return NULL;
-  if (r.IsDouble() && !has_double_value_) return NULL;
-  if (r.IsExternal() && !has_external_reference_value_) return NULL;
-  if (has_int32_value_) {
-    return new(zone) HConstant(int32_value_, r, is_not_in_new_space_, object_);
+  if (r.IsSmi() && !HasSmiValue()) return NULL;
+  if (r.IsInteger32() && !HasInteger32Value()) return NULL;
+  if (r.IsDouble() && !HasDoubleValue()) return NULL;
+  if (r.IsExternal() && !HasExternalReferenceValue()) return NULL;
+  if (HasInteger32Value()) {
+    return new (zone) HConstant(int32_value_, r, NotInNewSpace(), object_);
   }
-  if (has_double_value_) {
-    return new(zone) HConstant(double_value_, r, is_not_in_new_space_, object_);
+  if (HasDoubleValue()) {
+    return new (zone) HConstant(double_value_, r, NotInNewSpace(), object_);
   }
-  if (has_external_reference_value_) {
+  if (HasExternalReferenceValue()) {
     return new(zone) HConstant(external_reference_value_);
   }
   DCHECK(!object_.handle().is_null());
-  return new(zone) HConstant(object_,
-                             object_map_,
-                             has_stable_map_value_,
-                             r,
-                             type_,
-                             is_not_in_new_space_,
-                             boolean_value_,
-                             is_undetectable_,
-                             instance_type_);
+  return new (zone) HConstant(object_, object_map_, HasStableMapValue(), r,
+                              type_, NotInNewSpace(), BooleanValue(),
+                              IsUndetectable(), GetInstanceType());
 }
 
 
 Maybe<HConstant*> HConstant::CopyToTruncatedInt32(Zone* zone) {
   HConstant* res = NULL;
-  if (has_int32_value_) {
-    res = new(zone) HConstant(int32_value_,
-                              Representation::Integer32(),
-                              is_not_in_new_space_,
-                              object_);
-  } else if (has_double_value_) {
-    res = new(zone) HConstant(DoubleToInt32(double_value_),
-                              Representation::Integer32(),
-                              is_not_in_new_space_,
-                              object_);
+  if (HasInteger32Value()) {
+    res = new (zone) HConstant(int32_value_, Representation::Integer32(),
+                               NotInNewSpace(), object_);
+  } else if (HasDoubleValue()) {
+    res = new (zone)
+        HConstant(DoubleToInt32(double_value_), Representation::Integer32(),
+                  NotInNewSpace(), object_);
   }
   return Maybe<HConstant*>(res != NULL, res);
 }
@@ -2936,12 +2951,12 @@
 }
 
 
-OStream& HConstant::PrintDataTo(OStream& os) const {  // NOLINT
-  if (has_int32_value_) {
+std::ostream& HConstant::PrintDataTo(std::ostream& os) const {  // NOLINT
+  if (HasInteger32Value()) {
     os << int32_value_ << " ";
-  } else if (has_double_value_) {
+  } else if (HasDoubleValue()) {
     os << double_value_ << " ";
-  } else if (has_external_reference_value_) {
+  } else if (HasExternalReferenceValue()) {
     os << reinterpret_cast<void*>(external_reference_value_.address()) << " ";
   } else {
     // The handle() method is silently and lazily mutating the object.
@@ -2950,12 +2965,12 @@
     if (HasStableMapValue()) os << "[stable-map] ";
     if (HasObjectMap()) os << "[map " << *ObjectMap().handle() << "] ";
   }
-  if (!is_not_in_new_space_) os << "[new space] ";
+  if (!NotInNewSpace()) os << "[new space] ";
   return os;
 }
 
 
-OStream& HBinaryOperation::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HBinaryOperation::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << NameOf(left()) << " " << NameOf(right());
   if (CheckFlag(kCanOverflow)) os << " !";
   if (CheckFlag(kBailoutOnMinusZero)) os << " -0?";
@@ -3182,25 +3197,28 @@
 }
 
 
-OStream& HCompareGeneric::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCompareGeneric::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << Token::Name(token()) << " ";
   return HBinaryOperation::PrintDataTo(os);
 }
 
 
-OStream& HStringCompareAndBranch::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HStringCompareAndBranch::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   os << Token::Name(token()) << " ";
   return HControlInstruction::PrintDataTo(os);
 }
 
 
-OStream& HCompareNumericAndBranch::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCompareNumericAndBranch::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   os << Token::Name(token()) << " " << NameOf(left()) << " " << NameOf(right());
   return HControlInstruction::PrintDataTo(os);
 }
 
 
-OStream& HCompareObjectEqAndBranch::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HCompareObjectEqAndBranch::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   os << NameOf(left()) << " " << NameOf(right());
   return HControlInstruction::PrintDataTo(os);
 }
@@ -3340,7 +3358,7 @@
 }
 
 
-OStream& HGoto::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HGoto::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << *SuccessorAt(0);
 }
 
@@ -3384,12 +3402,12 @@
 }
 
 
-OStream& HParameter::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HParameter::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << index();
 }
 
 
-OStream& HLoadNamedField::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HLoadNamedField::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << NameOf(object()) << access_;
 
   if (maps() != NULL) {
@@ -3405,13 +3423,14 @@
 }
 
 
-OStream& HLoadNamedGeneric::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HLoadNamedGeneric::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   Handle<String> n = Handle<String>::cast(name());
   return os << NameOf(object()) << "." << n->ToCString().get();
 }
 
 
-OStream& HLoadKeyed::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HLoadKeyed::PrintDataTo(std::ostream& os) const {  // NOLINT
   if (!is_external()) {
     os << NameOf(elements());
   } else {
@@ -3499,7 +3518,8 @@
 }
 
 
-OStream& HLoadKeyedGeneric::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HLoadKeyedGeneric::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   return os << NameOf(object()) << "[" << NameOf(key()) << "]";
 }
 
@@ -3541,14 +3561,15 @@
 }
 
 
-OStream& HStoreNamedGeneric::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HStoreNamedGeneric::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   Handle<String> n = Handle<String>::cast(name());
   return os << NameOf(object()) << "." << n->ToCString().get() << " = "
             << NameOf(value());
 }
 
 
-OStream& HStoreNamedField::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HStoreNamedField::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << NameOf(object()) << access_ << " = " << NameOf(value());
   if (NeedsWriteBarrier()) os << " (write-barrier)";
   if (has_transition()) os << " (transition map " << *transition_map() << ")";
@@ -3556,7 +3577,7 @@
 }
 
 
-OStream& HStoreKeyed::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HStoreKeyed::PrintDataTo(std::ostream& os) const {  // NOLINT
   if (!is_external()) {
     os << NameOf(elements());
   } else {
@@ -3571,13 +3592,15 @@
 }
 
 
-OStream& HStoreKeyedGeneric::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HStoreKeyedGeneric::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   return os << NameOf(object()) << "[" << NameOf(key())
             << "] = " << NameOf(value());
 }
 
 
-OStream& HTransitionElementsKind::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HTransitionElementsKind::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   os << NameOf(object());
   ElementsKind from_kind = original_map().handle()->elements_kind();
   ElementsKind to_kind = transitioned_map().handle()->elements_kind();
@@ -3590,7 +3613,7 @@
 }
 
 
-OStream& HLoadGlobalCell::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HLoadGlobalCell::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << "[" << *cell().handle() << "]";
   if (details_.IsConfigurable()) os << " (configurable)";
   if (details_.IsReadOnly()) os << " (read-only)";
@@ -3608,18 +3631,20 @@
 }
 
 
-OStream& HLoadGlobalGeneric::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HLoadGlobalGeneric::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   return os << name()->ToCString().get() << " ";
 }
 
 
-OStream& HInnerAllocatedObject::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HInnerAllocatedObject::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   os << NameOf(base_object()) << " offset ";
   return offset()->PrintTo(os);
 }
 
 
-OStream& HStoreGlobalCell::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HStoreGlobalCell::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << "[" << *cell().handle() << "] = " << NameOf(value());
   if (details_.IsConfigurable()) os << " (configurable)";
   if (details_.IsReadOnly()) os << " (read-only)";
@@ -3627,12 +3652,13 @@
 }
 
 
-OStream& HLoadContextSlot::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HLoadContextSlot::PrintDataTo(std::ostream& os) const {  // NOLINT
   return os << NameOf(value()) << "[" << slot_index() << "]";
 }
 
 
-OStream& HStoreContextSlot::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HStoreContextSlot::PrintDataTo(
+    std::ostream& os) const {  // NOLINT
   return os << NameOf(context()) << "[" << slot_index()
             << "] = " << NameOf(value());
 }
@@ -3987,7 +4013,7 @@
 }
 
 
-OStream& HAllocate::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HAllocate::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << NameOf(size()) << " (";
   if (IsNewSpaceAllocation()) os << "N";
   if (IsOldPointerSpaceAllocation()) os << "P";
@@ -4096,7 +4122,7 @@
 }
 
 
-OStream& HStringAdd::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HStringAdd::PrintDataTo(std::ostream& os) const {  // NOLINT
   if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_BOTH) {
     os << "_CheckBoth";
   } else if ((flags() & STRING_ADD_CHECK_BOTH) == STRING_ADD_CHECK_LEFT) {
@@ -4431,7 +4457,7 @@
 #undef H_CONSTANT_DOUBLE
 
 
-OStream& HBitwise::PrintDataTo(OStream& os) const {  // NOLINT
+std::ostream& HBitwise::PrintDataTo(std::ostream& os) const {  // NOLINT
   os << Token::Name(op_) << " ";
   return HBitwiseBinaryOperation::PrintDataTo(os);
 }
@@ -4475,18 +4501,24 @@
 
 void HPhi::InferRepresentation(HInferRepresentationPhase* h_infer) {
   DCHECK(CheckFlag(kFlexibleRepresentation));
-  Representation new_rep = RepresentationFromInputs();
-  UpdateRepresentation(new_rep, h_infer, "inputs");
-  new_rep = RepresentationFromUses();
+  Representation new_rep = RepresentationFromUses();
   UpdateRepresentation(new_rep, h_infer, "uses");
+  new_rep = RepresentationFromInputs();
+  UpdateRepresentation(new_rep, h_infer, "inputs");
   new_rep = RepresentationFromUseRequirements();
   UpdateRepresentation(new_rep, h_infer, "use requirements");
 }
 
 
 Representation HPhi::RepresentationFromInputs() {
-  Representation r = Representation::None();
+  bool has_type_feedback =
+      smi_non_phi_uses() + int32_non_phi_uses() + double_non_phi_uses() > 0;
+  Representation r = representation();
   for (int i = 0; i < OperandCount(); ++i) {
+    // Ignore conservative Tagged assumption of parameters if we have
+    // reason to believe that it's too conservative.
+    if (has_type_feedback && OperandAt(i)->IsParameter()) continue;
+
     r = r.generalize(OperandAt(i)->KnownOptimalRepresentation());
   }
   return r;
@@ -4627,6 +4659,14 @@
 }
 
 
+HObjectAccess HObjectAccess::ForScriptContext(int index) {
+  DCHECK(index >= 0);
+  Portion portion = kInobject;
+  int offset = ScriptContextTable::GetContextOffset(index);
+  return HObjectAccess(portion, offset, Representation::Tagged());
+}
+
+
 HObjectAccess HObjectAccess::ForJSArrayOffset(int offset) {
   DCHECK(offset >= 0);
   Portion portion = kInobject;
@@ -4746,7 +4786,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const HObjectAccess& access) {
+std::ostream& operator<<(std::ostream& os, const HObjectAccess& access) {
   os << ".";
 
   switch (access.portion()) {
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 695c629..74f2711 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -5,15 +5,16 @@
 #ifndef V8_HYDROGEN_INSTRUCTIONS_H_
 #define V8_HYDROGEN_INSTRUCTIONS_H_
 
+#include <iosfwd>
+
 #include "src/v8.h"
 
 #include "src/allocation.h"
 #include "src/base/bits.h"
+#include "src/bit-vector.h"
 #include "src/code-stubs.h"
 #include "src/conversions.h"
-#include "src/data-flow.h"
 #include "src/deoptimizer.h"
-#include "src/feedback-slots.h"
 #include "src/hydrogen-types.h"
 #include "src/small-pointer-list.h"
 #include "src/unique.h"
@@ -35,7 +36,6 @@
 class HValue;
 class LInstruction;
 class LChunkBuilder;
-class OStream;
 
 #define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \
   V(ArithmeticBinaryOperation)                \
@@ -190,24 +190,21 @@
   V(TypedArrayElements)
 
 
-#define DECLARE_ABSTRACT_INSTRUCTION(type)                              \
-  virtual bool Is##type() const FINAL OVERRIDE { return true; }   \
-  static H##type* cast(HValue* value) {                                 \
-    DCHECK(value->Is##type());                                          \
-    return reinterpret_cast<H##type*>(value);                           \
+#define DECLARE_ABSTRACT_INSTRUCTION(type)     \
+  bool Is##type() const FINAL { return true; } \
+  static H##type* cast(HValue* value) {        \
+    DCHECK(value->Is##type());                 \
+    return reinterpret_cast<H##type*>(value);  \
   }
 
 
-#define DECLARE_CONCRETE_INSTRUCTION(type)              \
-  virtual LInstruction* CompileToLithium(               \
-     LChunkBuilder* builder) FINAL OVERRIDE;      \
-  static H##type* cast(HValue* value) {                 \
-    DCHECK(value->Is##type());                          \
-    return reinterpret_cast<H##type*>(value);           \
-  }                                                     \
-  virtual Opcode opcode() const FINAL OVERRIDE {  \
-    return HValue::k##type;                             \
-  }
+#define DECLARE_CONCRETE_INSTRUCTION(type)                      \
+  LInstruction* CompileToLithium(LChunkBuilder* builder) FINAL; \
+  static H##type* cast(HValue* value) {                         \
+    DCHECK(value->Is##type());                                  \
+    return reinterpret_cast<H##type*>(value);                   \
+  }                                                             \
+  Opcode opcode() const FINAL { return HValue::k##type; }
 
 
 enum PropertyAccessType { LOAD, STORE };
@@ -467,7 +464,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const HSourcePosition& p);
+std::ostream& operator<<(std::ostream& os, const HSourcePosition& p);
 
 
 class HValue : public ZoneObject {
@@ -770,7 +767,7 @@
   virtual void FinalizeUniqueness() { }
 
   // Printing support.
-  virtual OStream& PrintTo(OStream& os) const = 0;  // NOLINT
+  virtual std::ostream& PrintTo(std::ostream& os) const = 0;  // NOLINT
 
   const char* Mnemonic() const;
 
@@ -887,7 +884,7 @@
     result.Remove(kOsrEntries);
     return result;
   }
-  friend OStream& operator<<(OStream& os, const ChangesOf& v);
+  friend std::ostream& operator<<(std::ostream& os, const ChangesOf& v);
 
   // A flag mask of all side effects that can make observable changes in
   // an executing program (i.e. are not safe to repeat, move or remove);
@@ -948,10 +945,10 @@
 };
 
 
-OStream& operator<<(OStream& os, const HValue& v);
-OStream& operator<<(OStream& os, const NameOf& v);
-OStream& operator<<(OStream& os, const TypeOf& v);
-OStream& operator<<(OStream& os, const ChangesOf& v);
+std::ostream& operator<<(std::ostream& os, const HValue& v);
+std::ostream& operator<<(std::ostream& os, const NameOf& v);
+std::ostream& operator<<(std::ostream& os, const TypeOf& v);
+std::ostream& operator<<(std::ostream& os, const ChangesOf& v);
 
 
 #define DECLARE_INSTRUCTION_FACTORY_P0(I)                                      \
@@ -1147,8 +1144,8 @@
   HInstruction* next() const { return next_; }
   HInstruction* previous() const { return previous_; }
 
-  virtual OStream& PrintTo(OStream& os) const OVERRIDE;  // NOLINT
-  virtual OStream& PrintDataTo(OStream& os) const;          // NOLINT
+  std::ostream& PrintTo(std::ostream& os) const OVERRIDE;          // NOLINT
+  virtual std::ostream& PrintDataTo(std::ostream& os) const;       // NOLINT
 
   bool IsLinked() const { return block() != NULL; }
   void Unlink();
@@ -1168,7 +1165,7 @@
   }
 
   // The position is a write-once variable.
-  virtual HSourcePosition position() const OVERRIDE {
+  HSourcePosition position() const OVERRIDE {
     return HSourcePosition(position_.position());
   }
   bool has_position() const {
@@ -1180,7 +1177,7 @@
     position_.set_position(position);
   }
 
-  virtual HSourcePosition operand_position(int index) const OVERRIDE {
+  HSourcePosition operand_position(int index) const OVERRIDE {
     const HSourcePosition pos = position_.operand_position(index);
     return pos.IsUnknown() ? position() : pos;
   }
@@ -1197,7 +1194,7 @@
   virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0;
 
 #ifdef DEBUG
-  virtual void Verify() OVERRIDE;
+  void Verify() OVERRIDE;
 #endif
 
   bool CanDeoptimize();
@@ -1215,7 +1212,7 @@
     SetDependsOnFlag(kOsrEntries);
   }
 
-  virtual void DeleteFromGraph() OVERRIDE { Unlink(); }
+  void DeleteFromGraph() OVERRIDE { Unlink(); }
 
  private:
   void InitializeAsFirst(HBasicBlock* block) {
@@ -1234,18 +1231,14 @@
 template<int V>
 class HTemplateInstruction : public HInstruction {
  public:
-  virtual int OperandCount() const FINAL OVERRIDE { return V; }
-  virtual HValue* OperandAt(int i) const FINAL OVERRIDE {
-    return inputs_[i];
-  }
+  int OperandCount() const FINAL { return V; }
+  HValue* OperandAt(int i) const FINAL { return inputs_[i]; }
 
  protected:
   explicit HTemplateInstruction(HType type = HType::Tagged())
       : HInstruction(type) {}
 
-  virtual void InternalSetOperandAt(int i, HValue* value) FINAL OVERRIDE {
-    inputs_[i] = value;
-  }
+  void InternalSetOperandAt(int i, HValue* value) FINAL { inputs_[i] = value; }
 
  private:
   EmbeddedContainer<HValue*, V> inputs_;
@@ -1258,7 +1251,7 @@
   virtual int SuccessorCount() const = 0;
   virtual void SetSuccessorAt(int i, HBasicBlock* block) = 0;
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   virtual bool KnownSuccessorBlock(HBasicBlock** block) {
     *block = NULL;
@@ -1323,7 +1316,7 @@
 
 class HBlockEntry FINAL : public HTemplateInstruction<0> {
  public:
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
@@ -1343,12 +1336,12 @@
 
   HValue* value() const { return OperandAt(0); }
 
-  virtual bool HasEscapingOperandAt(int index) OVERRIDE { return false; }
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  bool HasEscapingOperandAt(int index) OVERRIDE { return false; }
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(DummyUse);
 };
@@ -1359,7 +1352,7 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P0(HDebugBreak);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
@@ -1373,16 +1366,16 @@
     SetSuccessorAt(0, target);
   }
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE {
+  bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE {
     *block = FirstSuccessor();
     return true;
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(Goto)
 };
@@ -1398,12 +1391,12 @@
     return new(zone) HDeoptimize(reason, type, unreachable_continuation);
   }
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE {
+  bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE {
     *block = NULL;
     return true;
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
@@ -1435,7 +1428,7 @@
     SetSuccessorAt(1, false_target);
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   HValue* value() const { return OperandAt(0); }
 };
@@ -1450,14 +1443,14 @@
                                  ToBooleanStub::Types,
                                  HBasicBlock*, HBasicBlock*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
-  virtual Representation observed_input_representation(int index) OVERRIDE;
+  Representation observed_input_representation(int index) OVERRIDE;
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
+  bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   ToBooleanStub::Types expected_input_types() const {
     return expected_input_types_;
@@ -1485,7 +1478,7 @@
   DECLARE_INSTRUCTION_FACTORY_P4(HCompareMap, HValue*, Handle<Map>,
                                  HBasicBlock*, HBasicBlock*);
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE {
+  bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE {
     if (known_successor_index() != kNoKnownSuccessorIndex) {
       *block = SuccessorAt(known_successor_index());
       return true;
@@ -1494,40 +1487,51 @@
     return false;
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   static const int kNoKnownSuccessorIndex = -1;
-  int known_successor_index() const { return known_successor_index_; }
-  void set_known_successor_index(int known_successor_index) {
-    known_successor_index_ = known_successor_index;
+  int known_successor_index() const {
+    return KnownSuccessorIndexField::decode(bit_field_) -
+           kInternalKnownSuccessorOffset;
+  }
+  void set_known_successor_index(int index) {
+    DCHECK(index >= 0 - kInternalKnownSuccessorOffset);
+    bit_field_ = KnownSuccessorIndexField::update(
+        bit_field_, index + kInternalKnownSuccessorOffset);
   }
 
   Unique<Map> map() const { return map_; }
-  bool map_is_stable() const { return map_is_stable_; }
+  bool map_is_stable() const { return MapIsStableField::decode(bit_field_); }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(CompareMap)
 
  protected:
-  virtual int RedefinedOperandIndex() { return 0; }
+  int RedefinedOperandIndex() OVERRIDE { return 0; }
 
  private:
-  HCompareMap(HValue* value,
-              Handle<Map> map,
-              HBasicBlock* true_target = NULL,
+  HCompareMap(HValue* value, Handle<Map> map, HBasicBlock* true_target = NULL,
               HBasicBlock* false_target = NULL)
       : HUnaryControlInstruction(value, true_target, false_target),
-        known_successor_index_(kNoKnownSuccessorIndex),
-        map_is_stable_(map->is_stable()),
+        bit_field_(KnownSuccessorIndexField::encode(
+                       kNoKnownSuccessorIndex + kInternalKnownSuccessorOffset) |
+                   MapIsStableField::encode(map->is_stable())),
         map_(Unique<Map>::CreateImmovable(map)) {
     set_representation(Representation::Tagged());
   }
 
-  int known_successor_index_ : 31;
-  bool map_is_stable_ : 1;
+  // BitFields can only store unsigned values, so use an offset.
+  // Adding kInternalKnownSuccessorOffset must yield an unsigned value.
+  static const int kInternalKnownSuccessorOffset = 1;
+  STATIC_ASSERT(kNoKnownSuccessorIndex + kInternalKnownSuccessorOffset >= 0);
+
+  class KnownSuccessorIndexField : public BitField<int, 0, 31> {};
+  class MapIsStableField : public BitField<bool, 31, 1> {};
+
+  uint32_t bit_field_;
   Unique<Map> map_;
 };
 
@@ -1538,14 +1542,14 @@
     return new(zone) HContext();
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(Context)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   HContext() {
@@ -1553,7 +1557,7 @@
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -1562,13 +1566,13 @@
   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HReturn, HValue*, HValue*);
   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HReturn, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     // TODO(titzer): require an Int32 input for faster returns.
     if (index == 2) return Representation::Smi();
     return Representation::Tagged();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   HValue* value() const { return OperandAt(0); }
   HValue* context() const { return OperandAt(1); }
@@ -1589,7 +1593,7 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P0(HAbnormalExit);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
@@ -1611,7 +1615,7 @@
   }
 
   HValue* value() const { return OperandAt(0); }
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 };
 
 
@@ -1619,7 +1623,7 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P1(HUseConst, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
@@ -1637,11 +1641,16 @@
 
   HValue* value() const { return OperandAt(0); }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation observed_input_representation(int index) OVERRIDE {
+    // We haven't actually *observed* this, but it's closer to the truth
+    // than 'None'.
+    return representation();  // Same as the output representation.
+  }
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return representation();  // Same as the output representation.
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(ForceRepresentation)
 
@@ -1683,29 +1692,29 @@
     return CheckUsesForFlag(kAllowUndefinedAsNaN);
   }
 
-  virtual HType CalculateInferredType() OVERRIDE;
-  virtual HValue* Canonicalize() OVERRIDE;
+  HType CalculateInferredType() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
   Representation from() const { return value()->representation(); }
   Representation to() const { return representation(); }
   bool deoptimize_on_minus_zero() const {
     return CheckFlag(kBailoutOnMinusZero);
   }
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return from();
   }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(Change)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
-  virtual bool IsDeletable() const OVERRIDE {
+  bool IsDeletable() const OVERRIDE {
     return !from().IsTagged() || value()->type().IsSmi();
   }
 };
@@ -1715,14 +1724,14 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P1(HClampToUint8, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(ClampToUint8)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   explicit HClampToUint8(HValue* value)
@@ -1732,7 +1741,7 @@
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -1741,7 +1750,7 @@
   enum Bits { HIGH, LOW };
   DECLARE_INSTRUCTION_FACTORY_P2(HDoubleBits, HValue*, Bits);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Double();
   }
 
@@ -1750,7 +1759,7 @@
   Bits bits() { return bits_; }
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     return other->IsDoubleBits() && HDoubleBits::cast(other)->bits() == bits();
   }
 
@@ -1761,7 +1770,7 @@
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 
   Bits bits_;
 };
@@ -1771,7 +1780,7 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P2(HConstructDouble, HValue*, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Integer32();
   }
 
@@ -1781,7 +1790,7 @@
   HValue* lo() { return OperandAt(1); }
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   explicit HConstructDouble(HValue* hi, HValue* lo) {
@@ -1791,7 +1800,7 @@
     SetOperandAt(1, lo);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -1803,20 +1812,18 @@
 
 class HSimulate FINAL : public HInstruction {
  public:
-  HSimulate(BailoutId ast_id,
-            int pop_count,
-            Zone* zone,
+  HSimulate(BailoutId ast_id, int pop_count, Zone* zone,
             RemovableSimulate removable)
       : ast_id_(ast_id),
         pop_count_(pop_count),
         values_(2, zone),
         assigned_indexes_(2, zone),
         zone_(zone),
-        removable_(removable),
-        done_with_replay_(false) {}
+        bit_field_(RemovableField::encode(removable) |
+                   DoneWithReplayField::encode(false)) {}
   ~HSimulate() {}
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   bool HasAstId() const { return !ast_id_.IsNone(); }
   BailoutId ast_id() const { return ast_id_; }
@@ -1846,18 +1853,18 @@
     }
     return -1;
   }
-  virtual int OperandCount() const OVERRIDE { return values_.length(); }
-  virtual HValue* OperandAt(int index) const OVERRIDE {
-    return values_[index];
-  }
+  int OperandCount() const OVERRIDE { return values_.length(); }
+  HValue* OperandAt(int index) const OVERRIDE { return values_[index]; }
 
-  virtual bool HasEscapingOperandAt(int index) OVERRIDE { return false; }
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  bool HasEscapingOperandAt(int index) OVERRIDE { return false; }
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
   void MergeWith(ZoneList<HSimulate*>* list);
-  bool is_candidate_for_removal() { return removable_ == REMOVABLE_SIMULATE; }
+  bool is_candidate_for_removal() {
+    return RemovableField::decode(bit_field_) == REMOVABLE_SIMULATE;
+  }
 
   // Replay effects of this instruction on the given environment.
   void ReplayEnvironment(HEnvironment* env);
@@ -1865,13 +1872,13 @@
   DECLARE_CONCRETE_INSTRUCTION(Simulate)
 
 #ifdef DEBUG
-  virtual void Verify() OVERRIDE;
+  void Verify() OVERRIDE;
   void set_closure(Handle<JSFunction> closure) { closure_ = closure; }
   Handle<JSFunction> closure() const { return closure_; }
 #endif
 
  protected:
-  virtual void InternalSetOperandAt(int index, HValue* value) OVERRIDE {
+  void InternalSetOperandAt(int index, HValue* value) OVERRIDE {
     values_[index] = value;
   }
 
@@ -1891,13 +1898,22 @@
     }
     return false;
   }
+  bool is_done_with_replay() const {
+    return DoneWithReplayField::decode(bit_field_);
+  }
+  void set_done_with_replay() {
+    bit_field_ = DoneWithReplayField::update(bit_field_, true);
+  }
+
+  class RemovableField : public BitField<RemovableSimulate, 0, 1> {};
+  class DoneWithReplayField : public BitField<bool, 1, 1> {};
+
   BailoutId ast_id_;
   int pop_count_;
   ZoneList<HValue*> values_;
   ZoneList<int> assigned_indexes_;
   Zone* zone_;
-  RemovableSimulate removable_ : 2;
-  bool done_with_replay_ : 1;
+  uint32_t bit_field_;
 
 #ifdef DEBUG
   Handle<JSFunction> closure_;
@@ -1918,11 +1934,11 @@
     next_simulate_ = simulate;
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
 #ifdef DEBUG
   void set_closure(Handle<JSFunction> closure) {
@@ -1960,7 +1976,7 @@
 
   HValue* context() { return OperandAt(0); }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -2015,7 +2031,7 @@
   void RegisterReturnTarget(HBasicBlock* return_target, Zone* zone);
   ZoneList<HBasicBlock*>* return_targets() { return &return_targets_; }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   Handle<JSFunction> closure() const { return closure_; }
   HConstant* closure_context() const { return closure_context_; }
@@ -2026,7 +2042,7 @@
   InliningKind inlining_kind() const { return inlining_kind_; }
   BailoutId ReturnId() const { return return_id_; }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
@@ -2072,11 +2088,11 @@
       : entry_(entry),
         drop_count_(drop_count) { }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
-  virtual int argument_delta() const OVERRIDE {
+  int argument_delta() const OVERRIDE {
     return entry_->arguments_pushed() ? -drop_count_ : 0;
   }
 
@@ -2123,28 +2139,22 @@
     return instr;
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual int argument_delta() const OVERRIDE { return inputs_.length(); }
+  int argument_delta() const OVERRIDE { return inputs_.length(); }
   HValue* argument(int i) { return OperandAt(i); }
 
-  virtual int OperandCount() const FINAL OVERRIDE {
-    return inputs_.length();
-  }
-  virtual HValue* OperandAt(int i) const FINAL OVERRIDE {
-    return inputs_[i];
-  }
+  int OperandCount() const FINAL { return inputs_.length(); }
+  HValue* OperandAt(int i) const FINAL { return inputs_[i]; }
 
   void AddInput(HValue* value);
 
   DECLARE_CONCRETE_INSTRUCTION(PushArguments)
 
  protected:
-  virtual void InternalSetOperandAt(int i, HValue* value) FINAL OVERRIDE {
-    inputs_[i] = value;
-  }
+  void InternalSetOperandAt(int i, HValue* value) FINAL { inputs_[i] = value; }
 
  private:
   explicit HPushArguments(Zone* zone)
@@ -2160,14 +2170,14 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P0(HThisFunction);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(ThisFunction)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   HThisFunction() {
@@ -2175,7 +2185,7 @@
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -2191,7 +2201,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals)
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -2220,17 +2230,13 @@
     this->SetAllSideEffects();
   }
 
-  virtual HType CalculateInferredType() FINAL OVERRIDE {
-    return HType::Tagged();
-  }
+  HType CalculateInferredType() FINAL { return HType::Tagged(); }
 
   virtual int argument_count() const {
     return argument_count_;
   }
 
-  virtual int argument_delta() const OVERRIDE {
-    return -argument_count();
-  }
+  int argument_delta() const OVERRIDE { return -argument_count(); }
 
  private:
   int argument_count_;
@@ -2244,12 +2250,11 @@
     SetOperandAt(0, value);
   }
 
-  virtual Representation RequiredInputRepresentation(
-      int index) FINAL OVERRIDE {
+  Representation RequiredInputRepresentation(int index) FINAL {
     return Representation::Tagged();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   HValue* value() const { return OperandAt(0); }
 };
@@ -2263,10 +2268,9 @@
     SetOperandAt(1, second);
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(
-      int index) FINAL OVERRIDE {
+  Representation RequiredInputRepresentation(int index) FINAL {
     return Representation::Tagged();
   }
 
@@ -2285,19 +2289,16 @@
 
   HValue* function() const { return OperandAt(0); }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(
-      int index) FINAL OVERRIDE {
+  Representation RequiredInputRepresentation(int index) FINAL {
     DCHECK(index == 0);
     return Representation::Tagged();
   }
 
   bool pass_argument_count() const { return pass_argument_count_; }
 
-  virtual bool HasStackCheck() FINAL OVERRIDE {
-    return has_stack_check_;
-  }
+  bool HasStackCheck() FINAL { return has_stack_check_; }
 
   DECLARE_CONCRETE_INSTRUCTION(CallJSFunction)
 
@@ -2318,27 +2319,26 @@
 };
 
 
+enum CallMode { NORMAL_CALL, TAIL_CALL };
+
+
 class HCallWithDescriptor FINAL : public HInstruction {
  public:
   static HCallWithDescriptor* New(Zone* zone, HValue* context, HValue* target,
                                   int argument_count,
                                   CallInterfaceDescriptor descriptor,
-                                  const Vector<HValue*>& operands) {
+                                  const Vector<HValue*>& operands,
+                                  CallMode call_mode = NORMAL_CALL) {
     DCHECK(operands.length() == descriptor.GetEnvironmentLength());
-    HCallWithDescriptor* res = new (zone)
-        HCallWithDescriptor(target, argument_count, descriptor, operands, zone);
+    HCallWithDescriptor* res = new (zone) HCallWithDescriptor(
+        target, argument_count, descriptor, operands, call_mode, zone);
     return res;
   }
 
-  virtual int OperandCount() const FINAL OVERRIDE {
-    return values_.length();
-  }
-  virtual HValue* OperandAt(int index) const FINAL OVERRIDE {
-    return values_[index];
-  }
+  int OperandCount() const FINAL { return values_.length(); }
+  HValue* OperandAt(int index) const FINAL { return values_[index]; }
 
-  virtual Representation RequiredInputRepresentation(
-      int index) FINAL OVERRIDE {
+  Representation RequiredInputRepresentation(int index) FINAL {
     if (index == 0) {
       return Representation::Tagged();
     } else {
@@ -2350,17 +2350,15 @@
 
   DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor)
 
-  virtual HType CalculateInferredType() FINAL OVERRIDE {
-    return HType::Tagged();
-  }
+  HType CalculateInferredType() FINAL { return HType::Tagged(); }
+
+  bool IsTailCall() const { return call_mode_ == TAIL_CALL; }
 
   virtual int argument_count() const {
     return argument_count_;
   }
 
-  virtual int argument_delta() const OVERRIDE {
-    return -argument_count_;
-  }
+  int argument_delta() const OVERRIDE { return -argument_count_; }
 
   CallInterfaceDescriptor descriptor() const { return descriptor_; }
 
@@ -2368,16 +2366,20 @@
     return OperandAt(0);
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
  private:
   // The argument count includes the receiver.
   HCallWithDescriptor(HValue* target, int argument_count,
                       CallInterfaceDescriptor descriptor,
-                      const Vector<HValue*>& operands, Zone* zone)
+                      const Vector<HValue*>& operands, CallMode call_mode,
+                      Zone* zone)
       : descriptor_(descriptor),
-        values_(descriptor.GetEnvironmentLength() + 1, zone) {
-    argument_count_ = argument_count;
+        values_(descriptor.GetEnvironmentLength() + 1, zone),
+        argument_count_(argument_count),
+        call_mode_(call_mode) {
+    // We can only tail call without any stack arguments.
+    DCHECK(call_mode != TAIL_CALL || argument_count == 0);
     AddOperand(target, zone);
     for (int i = 0; i < operands.length(); i++) {
       AddOperand(operands[i], zone);
@@ -2391,14 +2393,14 @@
     SetOperandAt(values_.length() - 1, v);
   }
 
-  void InternalSetOperandAt(int index,
-                            HValue* value) FINAL OVERRIDE {
+  void InternalSetOperandAt(int index, HValue* value) FINAL {
     values_[index] = value;
   }
 
   CallInterfaceDescriptor descriptor_;
   ZoneList<HValue*> values_;
   int argument_count_;
+  CallMode call_mode_;
 };
 
 
@@ -2433,9 +2435,7 @@
   Handle<JSFunction> known_function() { return known_function_; }
   int formal_parameter_count() const { return formal_parameter_count_; }
 
-  virtual bool HasStackCheck() FINAL OVERRIDE {
-    return has_stack_check_;
-  }
+  bool HasStackCheck() FINAL { return has_stack_check_; }
 
   DECLARE_CONCRETE_INSTRUCTION(InvokeFunction)
 
@@ -2463,7 +2463,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(CallFunction)
 
-  virtual int argument_delta() const OVERRIDE { return -argument_count(); }
+  int argument_delta() const OVERRIDE { return -argument_count(); }
 
  private:
   HCallFunction(HValue* context,
@@ -2501,7 +2501,7 @@
   HValue* context() { return first(); }
   HValue* constructor() { return second(); }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   ElementsKind elements_kind() const { return elements_kind_; }
 
@@ -2524,7 +2524,7 @@
                                               const Runtime::Function*,
                                               int);
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   HValue* context() { return OperandAt(0); }
   const Runtime::Function* function() const { return c_function_; }
@@ -2534,7 +2534,7 @@
     save_doubles_ = save_doubles;
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -2560,14 +2560,14 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P1(HMapEnumLength, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(MapEnumLength)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   explicit HMapEnumLength(HValue* value)
@@ -2577,7 +2577,7 @@
     SetDependsOnFlag(kMaps);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -2591,9 +2591,9 @@
   HValue* context() const { return OperandAt(0); }
   HValue* value() const { return OperandAt(1); }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     if (index == 0) {
       return Representation::Tagged();
     } else {
@@ -2617,11 +2617,11 @@
     }
   }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
-  virtual HValue* Canonicalize() OVERRIDE;
-  virtual Representation RepresentationFromUses() OVERRIDE;
-  virtual Representation RepresentationFromInputs() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
+  Representation RepresentationFromUses() OVERRIDE;
+  Representation RepresentationFromInputs() OVERRIDE;
 
   BuiltinFunctionId op() const { return op_; }
   const char* OpName() const;
@@ -2629,7 +2629,7 @@
   DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     HUnaryMathOperation* b = HUnaryMathOperation::cast(other);
     return op_ == b->op();
   }
@@ -2681,7 +2681,7 @@
     SetFlag(kAllowUndefinedAsNaN);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 
   HValue* SimplifiedDividendForMathFloorOfDiv(HDiv* hdiv);
   HValue* SimplifiedDivisorForMathFloorOfDiv(HDiv* hdiv);
@@ -2695,7 +2695,7 @@
   DECLARE_INSTRUCTION_FACTORY_P1(HLoadRoot, Heap::RootListIndex);
   DECLARE_INSTRUCTION_FACTORY_P2(HLoadRoot, Heap::RootListIndex, HType);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
@@ -2704,7 +2704,7 @@
   DECLARE_CONCRETE_INSTRUCTION(LoadRoot)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     HLoadRoot* b = HLoadRoot::cast(other);
     return index_ == b->index_;
   }
@@ -2716,9 +2716,10 @@
     // TODO(bmeurer): We'll need kDependsOnRoots once we add the
     // corresponding HStoreRoot instruction.
     SetDependsOnFlag(kCalls);
+    set_representation(Representation::Tagged());
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 
   const Heap::RootListIndex index_;
 };
@@ -2741,27 +2742,29 @@
     return new(zone) HCheckMaps(value, maps, typecheck);
   }
 
-  bool IsStabilityCheck() const { return is_stability_check_; }
+  bool IsStabilityCheck() const {
+    return IsStabilityCheckField::decode(bit_field_);
+  }
   void MarkAsStabilityCheck() {
-    maps_are_stable_ = true;
-    has_migration_target_ = false;
-    is_stability_check_ = true;
+    bit_field_ = MapsAreStableField::encode(true) |
+                 HasMigrationTargetField::encode(false) |
+                 IsStabilityCheckField::encode(true);
     ClearChangesFlag(kNewSpacePromotion);
     ClearDependsOnFlag(kElementsKind);
     ClearDependsOnFlag(kMaps);
   }
 
-  virtual bool HasEscapingOperandAt(int index) OVERRIDE { return false; }
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  bool HasEscapingOperandAt(int index) OVERRIDE { return false; }
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual HType CalculateInferredType() OVERRIDE {
+  HType CalculateInferredType() OVERRIDE {
     if (value()->type().IsHeapObject()) return value()->type();
     return HType::HeapObject();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   HValue* value() const { return OperandAt(0); }
   HValue* typecheck() const { return OperandAt(1); }
@@ -2769,11 +2772,15 @@
   const UniqueSet<Map>* maps() const { return maps_; }
   void set_maps(const UniqueSet<Map>* maps) { maps_ = maps; }
 
-  bool maps_are_stable() const { return maps_are_stable_; }
+  bool maps_are_stable() const {
+    return MapsAreStableField::decode(bit_field_);
+  }
 
-  bool HasMigrationTarget() const { return has_migration_target_; }
+  bool HasMigrationTarget() const {
+    return HasMigrationTargetField::decode(bit_field_);
+  }
 
-  virtual HValue* Canonicalize() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
   static HCheckMaps* CreateAndInsertAfter(Zone* zone,
                                           HValue* value,
@@ -2795,17 +2802,19 @@
   DECLARE_CONCRETE_INSTRUCTION(CheckMaps)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     return this->maps()->Equals(HCheckMaps::cast(other)->maps());
   }
 
-  virtual int RedefinedOperandIndex() { return 0; }
+  int RedefinedOperandIndex() OVERRIDE { return 0; }
 
  private:
   HCheckMaps(HValue* value, const UniqueSet<Map>* maps, bool maps_are_stable)
-      : HTemplateInstruction<2>(HType::HeapObject()), maps_(maps),
-        has_migration_target_(false), is_stability_check_(false),
-        maps_are_stable_(maps_are_stable) {
+      : HTemplateInstruction<2>(HType::HeapObject()),
+        maps_(maps),
+        bit_field_(HasMigrationTargetField::encode(false) |
+                   IsStabilityCheckField::encode(false) |
+                   MapsAreStableField::encode(maps_are_stable)) {
     DCHECK_NE(0, maps->size());
     SetOperandAt(0, value);
     // Use the object value for the dependency.
@@ -2817,9 +2826,11 @@
   }
 
   HCheckMaps(HValue* value, const UniqueSet<Map>* maps, HValue* typecheck)
-      : HTemplateInstruction<2>(HType::HeapObject()), maps_(maps),
-        has_migration_target_(false), is_stability_check_(false),
-        maps_are_stable_(true) {
+      : HTemplateInstruction<2>(HType::HeapObject()),
+        maps_(maps),
+        bit_field_(HasMigrationTargetField::encode(false) |
+                   IsStabilityCheckField::encode(false) |
+                   MapsAreStableField::encode(true)) {
     DCHECK_NE(0, maps->size());
     SetOperandAt(0, value);
     // Use the object value for the dependency if NULL is passed.
@@ -2830,16 +2841,22 @@
     SetDependsOnFlag(kElementsKind);
     for (int i = 0; i < maps->size(); ++i) {
       Handle<Map> map = maps->at(i).handle();
-      if (map->is_migration_target()) has_migration_target_ = true;
-      if (!map->is_stable()) maps_are_stable_ = false;
+      if (map->is_migration_target()) {
+        bit_field_ = HasMigrationTargetField::update(bit_field_, true);
+      }
+      if (!map->is_stable()) {
+        bit_field_ = MapsAreStableField::update(bit_field_, false);
+      }
     }
-    if (has_migration_target_) SetChangesFlag(kNewSpacePromotion);
+    if (HasMigrationTarget()) SetChangesFlag(kNewSpacePromotion);
   }
 
+  class HasMigrationTargetField : public BitField<bool, 0, 1> {};
+  class IsStabilityCheckField : public BitField<bool, 1, 1> {};
+  class MapsAreStableField : public BitField<bool, 2, 1> {};
+
   const UniqueSet<Map>* maps_;
-  bool has_migration_target_ : 1;
-  bool is_stability_check_ : 1;
-  bool maps_are_stable_ : 1;
+  uint32_t bit_field_;
 };
 
 
@@ -2862,19 +2879,19 @@
     return new(zone) HCheckValue(value, target, object_in_new_space);
   }
 
-  virtual void FinalizeUniqueness() OVERRIDE {
+  void FinalizeUniqueness() OVERRIDE {
     object_ = Unique<HeapObject>(object_.handle());
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual HValue* Canonicalize() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
 #ifdef DEBUG
-  virtual void Verify() OVERRIDE;
+  void Verify() OVERRIDE;
 #endif
 
   Unique<HeapObject> object() const { return object_; }
@@ -2883,7 +2900,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CheckValue)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     HCheckValue* b = HCheckValue::cast(other);
     return object_ == b->object_;
   }
@@ -2915,13 +2932,13 @@
 
   DECLARE_INSTRUCTION_FACTORY_P2(HCheckInstanceType, HValue*, Check);
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual HType CalculateInferredType() OVERRIDE {
+  HType CalculateInferredType() OVERRIDE {
     switch (check_) {
       case IS_SPEC_OBJECT: return HType::JSObject();
       case IS_JS_ARRAY: return HType::JSArray();
@@ -2932,7 +2949,7 @@
     return HType::Tagged();
   }
 
-  virtual HValue* Canonicalize() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
   bool is_interval_check() const { return check_ <= LAST_INTERVAL_CHECK; }
   void GetCheckInterval(InstanceType* first, InstanceType* last);
@@ -2946,12 +2963,12 @@
   // TODO(ager): It could be nice to allow the ommision of instance
   // type checks if we have already performed an instance type check
   // with a larger range.
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     HCheckInstanceType* b = HCheckInstanceType::cast(other);
     return check_ == b->check_;
   }
 
-  virtual int RedefinedOperandIndex() { return 0; }
+  int RedefinedOperandIndex() OVERRIDE { return 0; }
 
  private:
   const char* GetCheckName() const;
@@ -2970,11 +2987,11 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P1(HCheckSmi, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual HValue* Canonicalize() OVERRIDE {
+  HValue* Canonicalize() OVERRIDE {
     HType value_type = value()->type();
     if (value_type.IsSmi()) {
       return NULL;
@@ -2985,7 +3002,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CheckSmi)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   explicit HCheckSmi(HValue* value) : HUnaryOperation(value, HType::Smi()) {
@@ -2999,28 +3016,28 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*);
 
-  virtual bool HasEscapingOperandAt(int index) OVERRIDE { return false; }
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  bool HasEscapingOperandAt(int index) OVERRIDE { return false; }
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual HType CalculateInferredType() OVERRIDE {
+  HType CalculateInferredType() OVERRIDE {
     if (value()->type().IsHeapObject()) return value()->type();
     return HType::HeapObject();
   }
 
 #ifdef DEBUG
-  virtual void Verify() OVERRIDE;
+  void Verify() OVERRIDE;
 #endif
 
-  virtual HValue* Canonicalize() OVERRIDE {
+  HValue* Canonicalize() OVERRIDE {
     return value()->type().IsHeapObject() ? NULL : this;
   }
 
   DECLARE_CONCRETE_INSTRUCTION(CheckHeapObject)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   explicit HCheckHeapObject(HValue* value) : HUnaryOperation(value) {
@@ -3266,22 +3283,20 @@
     SetFlag(kAllowUndefinedAsNaN);
   }
 
-  virtual Representation RepresentationFromInputs() OVERRIDE;
+  Representation RepresentationFromInputs() OVERRIDE;
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
   virtual void InferRepresentation(
       HInferRepresentationPhase* h_infer) OVERRIDE;
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return representation();
   }
-  virtual Representation KnownOptimalRepresentation() OVERRIDE {
+  Representation KnownOptimalRepresentation() OVERRIDE {
     return representation();
   }
-  virtual HType CalculateInferredType() OVERRIDE;
-  virtual int OperandCount() const OVERRIDE { return inputs_.length(); }
-  virtual HValue* OperandAt(int index) const OVERRIDE {
-    return inputs_[index];
-  }
+  HType CalculateInferredType() OVERRIDE;
+  int OperandCount() const OVERRIDE { return inputs_.length(); }
+  HValue* OperandAt(int index) const OVERRIDE { return inputs_[index]; }
   HValue* GetRedundantReplacement();
   void AddInput(HValue* value);
   bool HasRealUses();
@@ -3289,7 +3304,7 @@
   bool IsReceiver() const { return merged_index_ == 0; }
   bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; }
 
-  virtual HSourcePosition position() const OVERRIDE;
+  HSourcePosition position() const OVERRIDE;
 
   int merged_index() const { return merged_index_; }
 
@@ -3308,10 +3323,10 @@
     induction_variable_data_ = InductionVariableData::ExaminePhi(this);
   }
 
-  virtual OStream& PrintTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
 #ifdef DEBUG
-  virtual void Verify() OVERRIDE;
+  void Verify() OVERRIDE;
 #endif
 
   void InitRealUses(int id);
@@ -3348,7 +3363,7 @@
     DCHECK(value->IsPhi());
     return reinterpret_cast<HPhi*>(value);
   }
-  virtual Opcode opcode() const OVERRIDE { return HValue::kPhi; }
+  Opcode opcode() const OVERRIDE { return HValue::kPhi; }
 
   void SimplifyConstantInputs();
 
@@ -3356,8 +3371,8 @@
   static const int kInvalidMergedIndex = -1;
 
  protected:
-  virtual void DeleteFromGraph() OVERRIDE;
-  virtual void InternalSetOperandAt(int index, HValue* value) OVERRIDE {
+  void DeleteFromGraph() OVERRIDE;
+  void InternalSetOperandAt(int index, HValue* value) OVERRIDE {
     inputs_[index] = value;
   }
 
@@ -3371,7 +3386,7 @@
   InductionVariableData* induction_variable_data_;
 
   // TODO(titzer): we can't eliminate the receiver for generating backtraces
-  virtual bool IsDeletable() const OVERRIDE { return !IsReceiver(); }
+  bool IsDeletable() const OVERRIDE { return !IsReceiver(); }
 };
 
 
@@ -3380,24 +3395,16 @@
  public:
   HDematerializedObject(int count, Zone* zone) : values_(count, zone) {}
 
-  virtual int OperandCount() const FINAL OVERRIDE {
-    return values_.length();
-  }
-  virtual HValue* OperandAt(int index) const FINAL OVERRIDE {
-    return values_[index];
-  }
+  int OperandCount() const FINAL { return values_.length(); }
+  HValue* OperandAt(int index) const FINAL { return values_[index]; }
 
-  virtual bool HasEscapingOperandAt(int index) FINAL OVERRIDE {
-    return false;
-  }
-  virtual Representation RequiredInputRepresentation(
-      int index) FINAL OVERRIDE {
+  bool HasEscapingOperandAt(int index) FINAL { return false; }
+  Representation RequiredInputRepresentation(int index) FINAL {
     return Representation::None();
   }
 
  protected:
-  virtual void InternalSetOperandAt(int index,
-                                    HValue* value) FINAL OVERRIDE {
+  void InternalSetOperandAt(int index, HValue* value) FINAL {
     values_[index] = value;
   }
 
@@ -3460,7 +3467,7 @@
   // Replay effects of this instruction on the given environment.
   void ReplayEnvironment(HEnvironment* env);
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(CapturedObject)
 
@@ -3470,7 +3477,7 @@
   // Note that we cannot DCE captured objects as they are used to replay
   // the environment. This method is here as an explicit reminder.
   // TODO(mstarzinger): Turn HSimulates into full snapshots maybe?
-  virtual bool IsDeletable() const FINAL OVERRIDE { return false; }
+  bool IsDeletable() const FINAL { return false; }
 };
 
 
@@ -3491,7 +3498,7 @@
         zone, context, value, representation));
   }
 
-  virtual Handle<Map> GetMonomorphicJSObjectMap() OVERRIDE {
+  Handle<Map> GetMonomorphicJSObjectMap() OVERRIDE {
     Handle<Object> object = object_.handle();
     if (!object.is_null() && object->IsHeapObject()) {
       return v8::internal::handle(HeapObject::cast(*object)->map());
@@ -3536,36 +3543,33 @@
           isolate->factory()->NewNumber(double_value_, TENURED));
     }
     AllowDeferredHandleDereference smi_check;
-    DCHECK(has_int32_value_ || !object_.handle()->IsSmi());
+    DCHECK(HasInteger32Value() || !object_.handle()->IsSmi());
     return object_.handle();
   }
 
   bool IsSpecialDouble() const {
-    return has_double_value_ &&
+    return HasDoubleValue() &&
            (bit_cast<int64_t>(double_value_) == bit_cast<int64_t>(-0.0) ||
             FixedDoubleArray::is_the_hole_nan(double_value_) ||
             std::isnan(double_value_));
   }
 
   bool NotInNewSpace() const {
-    return is_not_in_new_space_;
+    return IsNotInNewSpaceField::decode(bit_field_);
   }
 
   bool ImmortalImmovable() const;
 
   bool IsCell() const {
-    return instance_type_ == CELL_TYPE || instance_type_ == PROPERTY_CELL_TYPE;
+    InstanceType instance_type = GetInstanceType();
+    return instance_type == CELL_TYPE || instance_type == PROPERTY_CELL_TYPE;
   }
 
-  bool IsMap() const {
-    return instance_type_ == MAP_TYPE;
-  }
-
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
-  virtual Representation KnownOptimalRepresentation() OVERRIDE {
+  Representation KnownOptimalRepresentation() OVERRIDE {
     if (HasSmiValue() && SmiValuesAre31Bits()) return Representation::Smi();
     if (HasInteger32Value()) return Representation::Integer32();
     if (HasNumberValue()) return Representation::Double();
@@ -3573,18 +3577,22 @@
     return Representation::Tagged();
   }
 
-  virtual bool EmitAtUses() OVERRIDE;
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  bool EmitAtUses() OVERRIDE;
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
   HConstant* CopyToRepresentation(Representation r, Zone* zone) const;
   Maybe<HConstant*> CopyToTruncatedInt32(Zone* zone);
   Maybe<HConstant*> CopyToTruncatedNumber(Zone* zone);
-  bool HasInteger32Value() const { return has_int32_value_; }
+  bool HasInteger32Value() const {
+    return HasInt32ValueField::decode(bit_field_);
+  }
   int32_t Integer32Value() const {
     DCHECK(HasInteger32Value());
     return int32_value_;
   }
-  bool HasSmiValue() const { return has_smi_value_; }
-  bool HasDoubleValue() const { return has_double_value_; }
+  bool HasSmiValue() const { return HasSmiValueField::decode(bit_field_); }
+  bool HasDoubleValue() const {
+    return HasDoubleValueField::decode(bit_field_);
+  }
   double DoubleValue() const {
     DCHECK(HasDoubleValue());
     return double_value_;
@@ -3596,7 +3604,7 @@
     return object_.IsInitialized() &&
            object_.IsKnownGlobal(isolate()->heap()->the_hole_value());
   }
-  bool HasNumberValue() const { return has_double_value_; }
+  bool HasNumberValue() const { return HasDoubleValue(); }
   int32_t NumberValueAsInteger32() const {
     DCHECK(HasNumberValue());
     // Irrespective of whether a numeric HConstant can be safely
@@ -3605,38 +3613,42 @@
     return int32_value_;
   }
   bool HasStringValue() const {
-    if (has_double_value_ || has_int32_value_) return false;
+    if (HasNumberValue()) return false;
     DCHECK(!object_.handle().is_null());
-    return instance_type_ < FIRST_NONSTRING_TYPE;
+    return GetInstanceType() < FIRST_NONSTRING_TYPE;
   }
   Handle<String> StringValue() const {
     DCHECK(HasStringValue());
     return Handle<String>::cast(object_.handle());
   }
   bool HasInternalizedStringValue() const {
-    return HasStringValue() && StringShape(instance_type_).IsInternalized();
+    return HasStringValue() && StringShape(GetInstanceType()).IsInternalized();
   }
 
   bool HasExternalReferenceValue() const {
-    return has_external_reference_value_;
+    return HasExternalReferenceValueField::decode(bit_field_);
   }
   ExternalReference ExternalReferenceValue() const {
     return external_reference_value_;
   }
 
   bool HasBooleanValue() const { return type_.IsBoolean(); }
-  bool BooleanValue() const { return boolean_value_; }
-  bool IsUndetectable() const { return is_undetectable_; }
-  InstanceType GetInstanceType() const { return instance_type_; }
+  bool BooleanValue() const { return BooleanValueField::decode(bit_field_); }
+  bool IsUndetectable() const {
+    return IsUndetectableField::decode(bit_field_);
+  }
+  InstanceType GetInstanceType() const {
+    return InstanceTypeField::decode(bit_field_);
+  }
 
-  bool HasMapValue() const { return instance_type_ == MAP_TYPE; }
+  bool HasMapValue() const { return GetInstanceType() == MAP_TYPE; }
   Unique<Map> MapValue() const {
     DCHECK(HasMapValue());
     return Unique<Map>::cast(GetUnique());
   }
   bool HasStableMapValue() const {
-    DCHECK(HasMapValue() || !has_stable_map_value_);
-    return has_stable_map_value_;
+    DCHECK(HasMapValue() || !HasStableMapValueField::decode(bit_field_));
+    return HasStableMapValueField::decode(bit_field_);
   }
 
   bool HasObjectMap() const { return !object_map_.IsNull(); }
@@ -3645,12 +3657,12 @@
     return object_map_;
   }
 
-  virtual intptr_t Hashcode() OVERRIDE {
-    if (has_int32_value_) {
+  intptr_t Hashcode() OVERRIDE {
+    if (HasInteger32Value()) {
       return static_cast<intptr_t>(int32_value_);
-    } else if (has_double_value_) {
+    } else if (HasDoubleValue()) {
       return static_cast<intptr_t>(bit_cast<int64_t>(double_value_));
-    } else if (has_external_reference_value_) {
+    } else if (HasExternalReferenceValue()) {
       return reinterpret_cast<intptr_t>(external_reference_value_.address());
     } else {
       DCHECK(!object_.handle().is_null());
@@ -3658,8 +3670,8 @@
     }
   }
 
-  virtual void FinalizeUniqueness() OVERRIDE {
-    if (!has_double_value_ && !has_external_reference_value_) {
+  void FinalizeUniqueness() OVERRIDE {
+    if (!HasDoubleValue() && !HasExternalReferenceValue()) {
       DCHECK(!object_.handle().is_null());
       object_ = Unique<Object>(object_.handle());
     }
@@ -3673,23 +3685,23 @@
     return object_.IsInitialized() && object_ == other;
   }
 
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     HConstant* other_constant = HConstant::cast(other);
-    if (has_int32_value_) {
-      return other_constant->has_int32_value_ &&
-          int32_value_ == other_constant->int32_value_;
-    } else if (has_double_value_) {
-      return other_constant->has_double_value_ &&
+    if (HasInteger32Value()) {
+      return other_constant->HasInteger32Value() &&
+             int32_value_ == other_constant->int32_value_;
+    } else if (HasDoubleValue()) {
+      return other_constant->HasDoubleValue() &&
              bit_cast<int64_t>(double_value_) ==
                  bit_cast<int64_t>(other_constant->double_value_);
-    } else if (has_external_reference_value_) {
-      return other_constant->has_external_reference_value_ &&
-          external_reference_value_ ==
-          other_constant->external_reference_value_;
+    } else if (HasExternalReferenceValue()) {
+      return other_constant->HasExternalReferenceValue() &&
+             external_reference_value_ ==
+                 other_constant->external_reference_value_;
     } else {
-      if (other_constant->has_int32_value_ ||
-          other_constant->has_double_value_ ||
-          other_constant->has_external_reference_value_) {
+      if (other_constant->HasInteger32Value() ||
+          other_constant->HasDoubleValue() ||
+          other_constant->HasExternalReferenceValue()) {
         return false;
       }
       DCHECK(!object_.handle().is_null());
@@ -3698,13 +3710,13 @@
   }
 
 #ifdef DEBUG
-  virtual void Verify() OVERRIDE { }
+  void Verify() OVERRIDE {}
 #endif
 
   DECLARE_CONCRETE_INSTRUCTION(Constant)
 
  protected:
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
  private:
   friend class HGraph;
@@ -3732,7 +3744,26 @@
 
   void Initialize(Representation r);
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
+
+  // If object_ is a map, this indicates whether the map is stable.
+  class HasStableMapValueField : public BitField<bool, 0, 1> {};
+
+  // We store the HConstant in the most specific form safely possible.
+  // These flags tell us if the respective member fields hold valid, safe
+  // representations of the constant. More specific flags imply more general
+  // flags, but not the converse (i.e. smi => int32 => double).
+  class HasSmiValueField : public BitField<bool, 1, 1> {};
+  class HasInt32ValueField : public BitField<bool, 2, 1> {};
+  class HasDoubleValueField : public BitField<bool, 3, 1> {};
+
+  class HasExternalReferenceValueField : public BitField<bool, 4, 1> {};
+  class IsNotInNewSpaceField : public BitField<bool, 5, 1> {};
+  class BooleanValueField : public BitField<bool, 6, 1> {};
+  class IsUndetectableField : public BitField<bool, 7, 1> {};
+
+  static const InstanceType kUnknownInstanceType = FILLER_TYPE;
+  class InstanceTypeField : public BitField<InstanceType, 8, 8> {};
 
   // If this is a numerical constant, object_ either points to the
   // HeapObject the constant originated from or is null.  If the
@@ -3743,27 +3774,11 @@
   // If object_ is a heap object, this points to the stable map of the object.
   Unique<Map> object_map_;
 
-  // If object_ is a map, this indicates whether the map is stable.
-  bool has_stable_map_value_ : 1;
+  uint32_t bit_field_;
 
-  // We store the HConstant in the most specific form safely possible.
-  // The two flags, has_int32_value_ and has_double_value_ tell us if
-  // int32_value_ and double_value_ hold valid, safe representations
-  // of the constant.  has_int32_value_ implies has_double_value_ but
-  // not the converse.
-  bool has_smi_value_ : 1;
-  bool has_int32_value_ : 1;
-  bool has_double_value_ : 1;
-  bool has_external_reference_value_ : 1;
-  bool is_not_in_new_space_ : 1;
-  bool boolean_value_ : 1;
-  bool is_undetectable_: 1;
   int32_t int32_value_;
   double double_value_;
   ExternalReference external_reference_value_;
-
-  static const InstanceType kUnknownInstanceType = FILLER_TYPE;
-  InstanceType instance_type_;
 };
 
 
@@ -3817,7 +3832,7 @@
     observed_output_representation_ = observed;
   }
 
-  virtual Representation observed_input_representation(int index) OVERRIDE {
+  Representation observed_input_representation(int index) OVERRIDE {
     if (index == 0) return Representation::Tagged();
     return observed_input_representation_[index - 1];
   }
@@ -3832,15 +3847,15 @@
 
   virtual void InferRepresentation(
       HInferRepresentationPhase* h_infer) OVERRIDE;
-  virtual Representation RepresentationFromInputs() OVERRIDE;
+  Representation RepresentationFromInputs() OVERRIDE;
   Representation RepresentationFromOutput();
-  virtual void AssumeRepresentation(Representation r) OVERRIDE;
+  void AssumeRepresentation(Representation r) OVERRIDE;
 
   virtual bool IsCommutative() const { return false; }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     if (index == 0) return Representation::Tagged();
     return representation();
   }
@@ -3875,18 +3890,18 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P2(HWrapReceiver, HValue*, HValue*);
 
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
   HValue* receiver() const { return OperandAt(0); }
   HValue* function() const { return OperandAt(1); }
 
-  virtual HValue* Canonicalize() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
   bool known_function() const { return known_function_; }
 
   DECLARE_CONCRETE_INSTRUCTION(WrapReceiver)
@@ -3910,7 +3925,7 @@
   DECLARE_INSTRUCTION_FACTORY_P4(HApplyArguments, HValue*, HValue*, HValue*,
                                  HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     // The length is untagged, all other inputs are tagged.
     return (index == 2)
         ? Representation::Integer32()
@@ -3945,14 +3960,14 @@
 
   DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements)
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
   bool from_inlined() const { return from_inlined_; }
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   explicit HArgumentsElements(bool from_inlined) : from_inlined_(from_inlined) {
@@ -3962,7 +3977,7 @@
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 
   bool from_inlined_;
 };
@@ -3972,14 +3987,14 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P1(HArgumentsLength, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   explicit HArgumentsLength(HValue* value) : HUnaryOperation(value) {
@@ -3987,7 +4002,7 @@
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -3995,9 +4010,9 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P3(HAccessArgumentsAt, HValue*, HValue*, HValue*);
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     // The arguments elements is considered tagged.
     return index == 0
         ? Representation::Tagged()
@@ -4019,7 +4034,7 @@
     SetOperandAt(2, index);
   }
 
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 };
 
 
@@ -4055,11 +4070,11 @@
     }
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return representation();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
   virtual void InferRepresentation(
       HInferRepresentationPhase* h_infer) OVERRIDE;
 
@@ -4068,19 +4083,17 @@
   bool allow_equality() const { return allow_equality_; }
   void set_allow_equality(bool v) { allow_equality_ = v; }
 
-  virtual int RedefinedOperandIndex() OVERRIDE { return 0; }
-  virtual bool IsPurelyInformativeDefinition() OVERRIDE {
-    return skip_check();
-  }
+  int RedefinedOperandIndex() OVERRIDE { return 0; }
+  bool IsPurelyInformativeDefinition() OVERRIDE { return skip_check(); }
 
   DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
 
  protected:
   friend class HBoundsCheckBaseIndexInformation;
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
   bool skip_check_;
   HValue* base_;
   int offset_;
@@ -4102,9 +4115,7 @@
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsDeletable() const OVERRIDE {
-    return skip_check() && !FLAG_debug_code;
-  }
+  bool IsDeletable() const OVERRIDE { return skip_check() && !FLAG_debug_code; }
 };
 
 
@@ -4126,14 +4137,14 @@
 
   DECLARE_CONCRETE_INSTRUCTION(BoundsCheckBaseIndexInformation)
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return representation();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual int RedefinedOperandIndex() OVERRIDE { return 0; }
-  virtual bool IsPurelyInformativeDefinition() OVERRIDE { return true; }
+  int RedefinedOperandIndex() OVERRIDE { return 0; }
+  bool IsPurelyInformativeDefinition() OVERRIDE { return true; }
 };
 
 
@@ -4148,7 +4159,7 @@
     SetAllSideEffects();
   }
 
-  virtual void RepresentationChanged(Representation to) OVERRIDE {
+  void RepresentationChanged(Representation to) OVERRIDE {
     if (to.IsTagged() &&
         (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
       SetAllSideEffects();
@@ -4168,13 +4179,14 @@
     HBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
   }
 
-  virtual Representation observed_input_representation(int index) OVERRIDE {
+  Representation observed_input_representation(int index) OVERRIDE {
     Representation r = HBinaryOperation::observed_input_representation(index);
     if (r.IsDouble()) return Representation::Integer32();
     return r;
   }
 
-  virtual void initialize_output_representation(Representation observed) {
+  virtual void initialize_output_representation(
+      Representation observed) OVERRIDE {
     if (observed.IsDouble()) observed = Representation::Integer32();
     HBinaryOperation::initialize_output_representation(observed);
   }
@@ -4182,7 +4194,7 @@
   DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
 
  private:
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -4195,7 +4207,7 @@
   DECLARE_CONCRETE_INSTRUCTION(MathFloorOfDiv)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   HMathFloorOfDiv(HValue* context, HValue* left, HValue* right)
@@ -4210,9 +4222,9 @@
     SetFlag(kAllowUndefinedAsNaN);
   }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -4225,7 +4237,7 @@
     SetFlag(kAllowUndefinedAsNaN);
   }
 
-  virtual void RepresentationChanged(Representation to) OVERRIDE {
+  void RepresentationChanged(Representation to) OVERRIDE {
     if (to.IsTagged() &&
         (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
       SetAllSideEffects();
@@ -4240,7 +4252,7 @@
   DECLARE_ABSTRACT_INSTRUCTION(ArithmeticBinaryOperation)
 
  private:
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -4249,14 +4261,14 @@
   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HCompareGeneric, HValue*,
                                               HValue*, Token::Value);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return index == 0
         ? Representation::Tagged()
         : representation();
   }
 
   Token::Value token() const { return token_; }
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(CompareGeneric)
 
@@ -4297,16 +4309,16 @@
   virtual void InferRepresentation(
       HInferRepresentationPhase* h_infer) OVERRIDE;
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return representation();
   }
-  virtual Representation observed_input_representation(int index) OVERRIDE {
+  Representation observed_input_representation(int index) OVERRIDE {
     return observed_input_representation_[index];
   }
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
+  bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   void SetOperandPositions(Zone* zone,
                            HSourcePosition left_pos,
@@ -4346,7 +4358,7 @@
   virtual void InferRepresentation(
       HInferRepresentationPhase* h_infer) OVERRIDE;
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return representation();
   }
 
@@ -4370,11 +4382,11 @@
   virtual void InferRepresentation(
       HInferRepresentationPhase* h_infer) OVERRIDE;
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return representation();
   }
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
+  bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch)
 
@@ -4391,7 +4403,7 @@
   DECLARE_INSTRUCTION_FACTORY_P4(HCompareObjectEqAndBranch, HValue*, HValue*,
                                  HBasicBlock*, HBasicBlock*);
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
+  bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
 
   static const int kNoKnownSuccessorIndex = -1;
   int known_successor_index() const { return known_successor_index_; }
@@ -4402,13 +4414,13 @@
   HValue* left() const { return OperandAt(0); }
   HValue* right() const { return OperandAt(1); }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual Representation observed_input_representation(int index) OVERRIDE {
+  Representation observed_input_representation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -4436,11 +4448,11 @@
   DECLARE_INSTRUCTION_FACTORY_P3(HIsObjectAndBranch, HValue*,
                                  HBasicBlock*, HBasicBlock*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
+  bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch)
 
@@ -4458,11 +4470,11 @@
   DECLARE_INSTRUCTION_FACTORY_P3(HIsStringAndBranch, HValue*,
                                  HBasicBlock*, HBasicBlock*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
+  bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
 
   static const int kNoKnownSuccessorIndex = -1;
   int known_successor_index() const { return known_successor_index_; }
@@ -4473,14 +4485,15 @@
   DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch)
 
  protected:
-  virtual int RedefinedOperandIndex() { return 0; }
+  int RedefinedOperandIndex() OVERRIDE { return 0; }
 
  private:
-  HIsStringAndBranch(HValue* value,
-                     HBasicBlock* true_target = NULL,
+  HIsStringAndBranch(HValue* value, HBasicBlock* true_target = NULL,
                      HBasicBlock* false_target = NULL)
-    : HUnaryControlInstruction(value, true_target, false_target),
-      known_successor_index_(kNoKnownSuccessorIndex) { }
+      : HUnaryControlInstruction(value, true_target, false_target),
+        known_successor_index_(kNoKnownSuccessorIndex) {
+    set_representation(Representation::Tagged());
+  }
 
   int known_successor_index_;
 };
@@ -4494,13 +4507,13 @@
 
   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch)
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
-  virtual int RedefinedOperandIndex() { return 0; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
+  int RedefinedOperandIndex() OVERRIDE { return 0; }
 
  private:
   HIsSmiAndBranch(HValue* value,
@@ -4518,11 +4531,11 @@
   DECLARE_INSTRUCTION_FACTORY_P3(HIsUndetectableAndBranch, HValue*,
                                  HBasicBlock*, HBasicBlock*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
+  bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch)
 
@@ -4546,9 +4559,9 @@
   HValue* right() { return OperandAt(2); }
   Token::Value token() const { return token_; }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -4580,7 +4593,7 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P0(HIsConstructCallAndBranch);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
@@ -4600,13 +4613,13 @@
   InstanceType from() { return from_; }
   InstanceType to() { return to_; }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
+  bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch)
 
@@ -4627,7 +4640,7 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P1(HHasCachedArrayIndexAndBranch, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -4642,14 +4655,14 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P1(HGetCachedArrayIndex, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   explicit HGetCachedArrayIndex(HValue* value) : HUnaryOperation(value) {
@@ -4657,7 +4670,7 @@
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -4668,11 +4681,11 @@
 
   DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch)
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   Handle<String> class_name() const { return class_name_; }
 
@@ -4690,17 +4703,17 @@
   DECLARE_INSTRUCTION_FACTORY_P2(HTypeofIsAndBranch, HValue*, Handle<String>);
 
   Handle<String> type_literal() const { return type_literal_.handle(); }
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch)
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
-  virtual bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
+  bool KnownSuccessorBlock(HBasicBlock** block) OVERRIDE;
 
-  virtual void FinalizeUniqueness() OVERRIDE {
+  void FinalizeUniqueness() OVERRIDE {
     type_literal_ = Unique<String>(type_literal_.handle());
   }
 
@@ -4717,11 +4730,11 @@
  public:
   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HInstanceOf, HValue*, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(InstanceOf)
 
@@ -4744,7 +4757,7 @@
   HValue* left() { return OperandAt(1); }
   Handle<JSFunction> function() { return function_; }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -4775,19 +4788,19 @@
   HValue* left() { return OperandAt(0); }
   HValue* right() const { return OperandAt(1); }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return index == 0
       ? Representation::Double()
       : Representation::None();
   }
-  virtual Representation observed_input_representation(int index) OVERRIDE {
+  Representation observed_input_representation(int index) OVERRIDE {
     return RequiredInputRepresentation(index);
   }
 
   DECLARE_CONCRETE_INSTRUCTION(Power)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   HPower(HValue* left, HValue* right) {
@@ -4798,7 +4811,7 @@
     SetChangesFlag(kNewSpacePromotion);
   }
 
-  virtual bool IsDeletable() const OVERRIDE {
+  bool IsDeletable() const OVERRIDE {
     return !right()->representation().IsTagged();
   }
 };
@@ -4814,13 +4827,13 @@
   // Add is only commutative if two integer values are added and not if two
   // tagged values are added (because it might be a String concatenation).
   // We also do not commute (pointer + offset).
-  virtual bool IsCommutative() const OVERRIDE {
+  bool IsCommutative() const OVERRIDE {
     return !representation().IsTagged() && !representation().IsExternal();
   }
 
-  virtual HValue* Canonicalize() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
-  virtual bool TryDecompose(DecompositionResult* decomposition) OVERRIDE {
+  bool TryDecompose(DecompositionResult* decomposition) OVERRIDE {
     if (left()->IsInteger32Constant()) {
       decomposition->Apply(right(), left()->GetInteger32Constant());
       return true;
@@ -4832,7 +4845,7 @@
     }
   }
 
-  virtual void RepresentationChanged(Representation to) OVERRIDE {
+  void RepresentationChanged(Representation to) OVERRIDE {
     if (to.IsTagged() &&
         (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved() ||
          left()->ToStringCanBeObserved() || right()->ToStringCanBeObserved())) {
@@ -4848,16 +4861,16 @@
     }
   }
 
-  virtual Representation RepresentationFromInputs() OVERRIDE;
+  Representation RepresentationFromInputs() OVERRIDE;
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE;
+  Representation RequiredInputRepresentation(int index) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(Add)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
  private:
   HAdd(HValue* context, HValue* left, HValue* right)
@@ -4874,9 +4887,9 @@
                            HValue* left,
                            HValue* right);
 
-  virtual HValue* Canonicalize() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
-  virtual bool TryDecompose(DecompositionResult* decomposition) OVERRIDE {
+  bool TryDecompose(DecompositionResult* decomposition) OVERRIDE {
     if (right()->IsInteger32Constant()) {
       decomposition->Apply(left(), -right()->GetInteger32Constant());
       return true;
@@ -4888,9 +4901,9 @@
   DECLARE_CONCRETE_INSTRUCTION(Sub)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
  private:
   HSub(HValue* context, HValue* left, HValue* right)
@@ -4920,12 +4933,10 @@
     return mul;
   }
 
-  virtual HValue* Canonicalize() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
   // Only commutative if it is certain that not two objects are multiplicated.
-  virtual bool IsCommutative() const OVERRIDE {
-    return !representation().IsTagged();
-  }
+  bool IsCommutative() const OVERRIDE { return !representation().IsTagged(); }
 
   virtual void UpdateRepresentation(Representation new_rep,
                                     HInferRepresentationPhase* h_infer,
@@ -4938,9 +4949,9 @@
   DECLARE_CONCRETE_INSTRUCTION(Mul)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
  private:
   HMul(HValue* context, HValue* left, HValue* right)
@@ -4957,7 +4968,7 @@
                            HValue* left,
                            HValue* right);
 
-  virtual HValue* Canonicalize() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
   virtual void UpdateRepresentation(Representation new_rep,
                                     HInferRepresentationPhase* h_infer,
@@ -4969,9 +4980,9 @@
   DECLARE_CONCRETE_INSTRUCTION(Mod)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
  private:
   HMod(HValue* context,
@@ -4991,7 +5002,7 @@
                            HValue* left,
                            HValue* right);
 
-  virtual HValue* Canonicalize() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
   virtual void UpdateRepresentation(Representation new_rep,
                                     HInferRepresentationPhase* h_infer,
@@ -5003,9 +5014,9 @@
   DECLARE_CONCRETE_INSTRUCTION(Div)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
  private:
   HDiv(HValue* context, HValue* left, HValue* right)
@@ -5026,14 +5037,14 @@
                            HValue* right,
                            Operation op);
 
-  virtual Representation observed_input_representation(int index) OVERRIDE {
+  Representation observed_input_representation(int index) OVERRIDE {
     return RequiredInputRepresentation(index);
   }
 
   virtual void InferRepresentation(
       HInferRepresentationPhase* h_infer) OVERRIDE;
 
-  virtual Representation RepresentationFromInputs() OVERRIDE {
+  Representation RepresentationFromInputs() OVERRIDE {
     Representation left_rep = left()->representation();
     Representation right_rep = right()->representation();
     Representation result = Representation::Smi();
@@ -5043,19 +5054,19 @@
     return result;
   }
 
-  virtual bool IsCommutative() const OVERRIDE { return true; }
+  bool IsCommutative() const OVERRIDE { return true; }
 
   Operation operation() { return operation_; }
 
   DECLARE_CONCRETE_INSTRUCTION(MathMinMax)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     return other->IsMathMinMax() &&
         HMathMinMax::cast(other)->operation_ == operation_;
   }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
  private:
   HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op)
@@ -5076,20 +5087,20 @@
 
   Token::Value op() const { return op_; }
 
-  virtual bool IsCommutative() const OVERRIDE { return true; }
+  bool IsCommutative() const OVERRIDE { return true; }
 
-  virtual HValue* Canonicalize() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(Bitwise)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     return op() == HBitwise::cast(other)->op();
   }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
  private:
   HBitwise(HValue* context,
@@ -5135,7 +5146,7 @@
                            HValue* left,
                            HValue* right);
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
   virtual void UpdateRepresentation(Representation new_rep,
                                     HInferRepresentationPhase* h_infer,
@@ -5151,7 +5162,7 @@
   DECLARE_CONCRETE_INSTRUCTION(Shl)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   HShl(HValue* context, HValue* left, HValue* right)
@@ -5166,7 +5177,7 @@
                            HValue* left,
                            HValue* right);
 
-  virtual bool TryDecompose(DecompositionResult* decomposition) OVERRIDE {
+  bool TryDecompose(DecompositionResult* decomposition) OVERRIDE {
     if (right()->IsInteger32Constant()) {
       if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
         // This is intended to look for HAdd and HSub, to handle compounds
@@ -5178,7 +5189,7 @@
     return false;
   }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
   virtual void UpdateRepresentation(Representation new_rep,
                                     HInferRepresentationPhase* h_infer,
@@ -5190,7 +5201,7 @@
   DECLARE_CONCRETE_INSTRUCTION(Shr)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   HShr(HValue* context, HValue* left, HValue* right)
@@ -5205,7 +5216,7 @@
                            HValue* left,
                            HValue* right);
 
-  virtual bool TryDecompose(DecompositionResult* decomposition) OVERRIDE {
+  bool TryDecompose(DecompositionResult* decomposition) OVERRIDE {
     if (right()->IsInteger32Constant()) {
       if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
         // This is intended to look for HAdd and HSub, to handle compounds
@@ -5217,7 +5228,7 @@
     return false;
   }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
   virtual void UpdateRepresentation(Representation new_rep,
                                     HInferRepresentationPhase* h_infer,
@@ -5229,7 +5240,7 @@
   DECLARE_CONCRETE_INSTRUCTION(Sar)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   HSar(HValue* context, HValue* left, HValue* right)
@@ -5256,7 +5267,7 @@
   DECLARE_CONCRETE_INSTRUCTION(Ror)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   HRor(HValue* context, HValue* left, HValue* right)
@@ -5272,7 +5283,7 @@
 
   BailoutId ast_id() const { return ast_id_; }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
@@ -5303,12 +5314,18 @@
   unsigned index() const { return index_; }
   ParameterKind kind() const { return kind_; }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
+  Representation KnownOptimalRepresentation() OVERRIDE {
+    // If a parameter is an input to a phi, that phi should not
+    // choose any more optimistic representation than Tagged.
+    return Representation::Tagged();
+  }
+
   DECLARE_CONCRETE_INSTRUCTION(Parameter)
 
  private:
@@ -5339,7 +5356,7 @@
 
   HValue* context() { return value(); }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(CallStub)
 
@@ -5353,34 +5370,90 @@
 };
 
 
-class HTailCallThroughMegamorphicCache FINAL : public HTemplateInstruction<3> {
+class HTailCallThroughMegamorphicCache FINAL : public HInstruction {
  public:
-  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(HTailCallThroughMegamorphicCache,
-                                              HValue*, HValue*, Code::Flags);
+  enum Flags {
+    NONE = 0,
+    CALLED_FROM_KEYED_LOAD = 1 << 0,
+    PERFORM_MISS_ONLY = 1 << 1
+  };
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  static Flags ComputeFlags(bool called_from_keyed_load,
+                            bool perform_miss_only) {
+    Flags flags = NONE;
+    if (called_from_keyed_load) {
+      flags = static_cast<Flags>(flags | CALLED_FROM_KEYED_LOAD);
+    }
+    if (perform_miss_only) {
+      flags = static_cast<Flags>(flags | PERFORM_MISS_ONLY);
+    }
+    return flags;
+  }
+
+  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P5(
+      HTailCallThroughMegamorphicCache, HValue*, HValue*, HValue*, HValue*,
+      HTailCallThroughMegamorphicCache::Flags);
+
+  DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P2(HTailCallThroughMegamorphicCache,
+                                              HValue*, HValue*);
+
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
+  virtual int OperandCount() const FINAL OVERRIDE {
+    return FLAG_vector_ics ? 5 : 3;
+  }
+  virtual HValue* OperandAt(int i) const FINAL OVERRIDE { return inputs_[i]; }
+
   HValue* context() const { return OperandAt(0); }
   HValue* receiver() const { return OperandAt(1); }
   HValue* name() const { return OperandAt(2); }
-  Code::Flags flags() const { return flags_; }
+  HValue* slot() const {
+    DCHECK(FLAG_vector_ics);
+    return OperandAt(3);
+  }
+  HValue* vector() const {
+    DCHECK(FLAG_vector_ics);
+    return OperandAt(4);
+  }
+  Code::Flags flags() const;
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  bool is_keyed_load() const { return flags_ & CALLED_FROM_KEYED_LOAD; }
+  bool is_just_miss() const { return flags_ & PERFORM_MISS_ONLY; }
+
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache)
 
+ protected:
+  virtual void InternalSetOperandAt(int i, HValue* value) FINAL OVERRIDE {
+    inputs_[i] = value;
+  }
+
  private:
   HTailCallThroughMegamorphicCache(HValue* context, HValue* receiver,
-                                   HValue* name, Code::Flags flags)
+                                   HValue* name, HValue* slot, HValue* vector,
+                                   Flags flags)
       : flags_(flags) {
+    DCHECK(FLAG_vector_ics);
+    SetOperandAt(0, context);
+    SetOperandAt(1, receiver);
+    SetOperandAt(2, name);
+    SetOperandAt(3, slot);
+    SetOperandAt(4, vector);
+  }
+
+  HTailCallThroughMegamorphicCache(HValue* context, HValue* receiver,
+                                   HValue* name)
+      : flags_(NONE) {
     SetOperandAt(0, context);
     SetOperandAt(1, receiver);
     SetOperandAt(2, name);
   }
 
-  Code::Flags flags_;
+  EmbeddedContainer<HValue*, 5> inputs_;
+  Flags flags_;
 };
 
 
@@ -5388,9 +5461,9 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P2(HUnknownOSRValue, HEnvironment*, int);
 
-  virtual OStream& PrintDataTo(OStream& os) const;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
@@ -5399,7 +5472,7 @@
   HEnvironment *environment() { return environment_; }
   int index() { return index_; }
 
-  virtual Representation KnownOptimalRepresentation() OVERRIDE {
+  Representation KnownOptimalRepresentation() OVERRIDE {
     if (incoming_value_ == NULL) return Representation::None();
     return incoming_value_->KnownOptimalRepresentation();
   }
@@ -5428,24 +5501,20 @@
   Unique<Cell> cell() const { return cell_; }
   bool RequiresHoleCheck() const;
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual intptr_t Hashcode() OVERRIDE {
-    return cell_.Hashcode();
-  }
+  intptr_t Hashcode() OVERRIDE { return cell_.Hashcode(); }
 
-  virtual void FinalizeUniqueness() OVERRIDE {
-    cell_ = Unique<Cell>(cell_.handle());
-  }
+  void FinalizeUniqueness() OVERRIDE { cell_ = Unique<Cell>(cell_.handle()); }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::None();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     return cell_ == HLoadGlobalCell::cast(other)->cell_;
   }
 
@@ -5457,7 +5526,7 @@
     SetDependsOnFlag(kGlobalVars);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return !RequiresHoleCheck(); }
+  bool IsDeletable() const OVERRIDE { return !RequiresHoleCheck(); }
 
   Unique<Cell> cell_;
   PropertyDetails details_;
@@ -5473,21 +5542,21 @@
   HValue* global_object() { return OperandAt(1); }
   Handle<String> name() const { return name_; }
   bool for_typeof() const { return for_typeof_; }
-  int slot() const {
-    DCHECK(FLAG_vector_ics &&
-           slot_ != FeedbackSlotInterface::kInvalidFeedbackSlot);
-    return slot_;
+  FeedbackVectorICSlot slot() const { return slot_; }
+  Handle<TypeFeedbackVector> feedback_vector() const {
+    return feedback_vector_;
   }
-  Handle<FixedArray> feedback_vector() const { return feedback_vector_; }
-  void SetVectorAndSlot(Handle<FixedArray> vector, int slot) {
+  bool HasVectorAndSlot() const { return FLAG_vector_ics; }
+  void SetVectorAndSlot(Handle<TypeFeedbackVector> vector,
+                        FeedbackVectorICSlot slot) {
     DCHECK(FLAG_vector_ics);
     feedback_vector_ = vector;
     slot_ = slot;
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -5496,8 +5565,9 @@
  private:
   HLoadGlobalGeneric(HValue* context, HValue* global_object,
                      Handle<String> name, bool for_typeof)
-      : name_(name), for_typeof_(for_typeof),
-        slot_(FeedbackSlotInterface::kInvalidFeedbackSlot) {
+      : name_(name),
+        for_typeof_(for_typeof),
+        slot_(FeedbackVectorICSlot::Invalid()) {
     SetOperandAt(0, context);
     SetOperandAt(1, global_object);
     set_representation(Representation::Tagged());
@@ -5506,8 +5576,8 @@
 
   Handle<String> name_;
   bool for_typeof_;
-  Handle<FixedArray> feedback_vector_;
-  int slot_;
+  Handle<TypeFeedbackVector> feedback_vector_;
+  FeedbackVectorICSlot slot_;
 };
 
 
@@ -5544,7 +5614,7 @@
     size_upper_bound_ = value;
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     if (index == 0) {
       return Representation::Tagged();
     } else {
@@ -5552,7 +5622,7 @@
     }
   }
 
-  virtual Handle<Map> GetMonomorphicJSObjectMap() OVERRIDE {
+  Handle<Map> GetMonomorphicJSObjectMap() OVERRIDE {
     return known_initial_map_;
   }
 
@@ -5595,7 +5665,7 @@
   virtual bool HandleSideEffectDominator(GVNFlag side_effect,
                                          HValue* dominator) OVERRIDE;
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(Allocate)
 
@@ -5708,7 +5778,7 @@
     return new(zone) HStoreCodeEntry(function, code);
   }
 
-  virtual Representation RequiredInputRepresentation(int index) {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -5738,11 +5808,11 @@
   HValue* base_object() const { return OperandAt(0); }
   HValue* offset() const { return OperandAt(1); }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return index == 0 ? Representation::Tagged() : Representation::Integer32();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject)
 
@@ -5833,14 +5903,14 @@
     return StoringValueNeedsWriteBarrier(value());
   }
 
-  virtual void FinalizeUniqueness() OVERRIDE {
+  void FinalizeUniqueness() OVERRIDE {
     cell_ = Unique<PropertyCell>(cell_.handle());
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell)
 
@@ -5892,22 +5962,22 @@
     return mode_ != kNoCheck;
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     HLoadContextSlot* b = HLoadContextSlot::cast(other);
     return (slot_index() == b->slot_index());
   }
 
  private:
-  virtual bool IsDeletable() const OVERRIDE { return !RequiresHoleCheck(); }
+  bool IsDeletable() const OVERRIDE { return !RequiresHoleCheck(); }
 
   int slot_index_;
   Mode mode_;
@@ -5949,11 +6019,11 @@
     return mode_ != kNoCheck;
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot)
 
@@ -6123,6 +6193,10 @@
     return HObjectAccess(kMaps, JSObject::kMapOffset);
   }
 
+  static HObjectAccess ForPrototype() {
+    return HObjectAccess(kMaps, Map::kPrototypeOffset);
+  }
+
   static HObjectAccess ForMapAsInteger32() {
     return HObjectAccess(kMaps, JSObject::kMapOffset,
                          Representation::Integer32());
@@ -6182,6 +6256,10 @@
     return HObjectAccess(kInobject, Cell::kValueOffset);
   }
 
+  static HObjectAccess ForWeakCellValue() {
+    return HObjectAccess(kInobject, WeakCell::kValueOffset);
+  }
+
   static HObjectAccess ForAllocationMementoSite() {
     return HObjectAccess(kInobject, AllocationMemento::kAllocationSiteOffset);
   }
@@ -6220,6 +6298,8 @@
 
   static HObjectAccess ForContextSlot(int index);
 
+  static HObjectAccess ForScriptContext(int index);
+
   // Create an access to the backing store of an object.
   static HObjectAccess ForBackingStoreOffset(int offset,
       Representation representation = Representation::Tagged());
@@ -6281,6 +6361,51 @@
     return HObjectAccess(kInobject, GlobalObject::kNativeContextOffset);
   }
 
+  static HObjectAccess ForJSCollectionTable() {
+    return HObjectAccess::ForObservableJSObjectOffset(
+        JSCollection::kTableOffset);
+  }
+
+  template <typename CollectionType>
+  static HObjectAccess ForOrderedHashTableNumberOfBuckets() {
+    return HObjectAccess(kInobject, CollectionType::kNumberOfBucketsOffset,
+                         Representation::Smi());
+  }
+
+  template <typename CollectionType>
+  static HObjectAccess ForOrderedHashTableNumberOfElements() {
+    return HObjectAccess(kInobject, CollectionType::kNumberOfElementsOffset,
+                         Representation::Smi());
+  }
+
+  template <typename CollectionType>
+  static HObjectAccess ForOrderedHashTableNumberOfDeletedElements() {
+    return HObjectAccess(kInobject,
+                         CollectionType::kNumberOfDeletedElementsOffset,
+                         Representation::Smi());
+  }
+
+  template <typename CollectionType>
+  static HObjectAccess ForOrderedHashTableNextTable() {
+    return HObjectAccess(kInobject, CollectionType::kNextTableOffset);
+  }
+
+  template <typename CollectionType>
+  static HObjectAccess ForOrderedHashTableBucket(int bucket) {
+    return HObjectAccess(kInobject, CollectionType::kHashTableStartOffset +
+                                        (bucket * kPointerSize),
+                         Representation::Smi());
+  }
+
+  // Access into the data table of an OrderedHashTable with a
+  // known-at-compile-time bucket count.
+  template <typename CollectionType, int kBucketCount>
+  static HObjectAccess ForOrderedHashTableDataTableIndex(int index) {
+    return HObjectAccess(kInobject, CollectionType::kHashTableStartOffset +
+                                        (kBucketCount * kPointerSize) +
+                                        (index * kPointerSize));
+  }
+
   inline bool Equals(HObjectAccess that) const {
     return value_ == that.value_;  // portion and offset must match
   }
@@ -6336,7 +6461,8 @@
   friend class HLoadNamedField;
   friend class HStoreNamedField;
   friend class SideEffectsTracker;
-  friend OStream& operator<<(OStream& os, const HObjectAccess& access);
+  friend std::ostream& operator<<(std::ostream& os,
+                                  const HObjectAccess& access);
 
   inline Portion portion() const {
     return PortionField::decode(value_);
@@ -6344,7 +6470,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const HObjectAccess& access);
+std::ostream& operator<<(std::ostream& os, const HObjectAccess& access);
 
 
 class HLoadNamedField FINAL : public HTemplateInstruction<2> {
@@ -6367,19 +6493,21 @@
 
   const UniqueSet<Map>* maps() const { return maps_; }
 
-  virtual bool HasEscapingOperandAt(int index) OVERRIDE { return false; }
-  virtual bool HasOutOfBoundsAccess(int size) OVERRIDE {
+  bool HasEscapingOperandAt(int index) OVERRIDE { return false; }
+  bool HasOutOfBoundsAccess(int size) OVERRIDE {
     return !access().IsInobject() || access().offset() >= size;
   }
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
-    if (index == 0 && access().IsExternalMemory()) {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
+    if (index == 0) {
       // object must be external in case of external memory access
-      return Representation::External();
+      return access().IsExternalMemory() ? Representation::External()
+                                         : Representation::Tagged();
     }
-    return Representation::Tagged();
+    DCHECK(index == 1);
+    return Representation::None();
   }
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  Range* InferRange(Zone* zone) OVERRIDE;
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   bool CanBeReplacedWith(HValue* other) const {
     if (!CheckFlag(HValue::kCantBeReplaced)) return false;
@@ -6395,7 +6523,7 @@
   DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     HLoadNamedField* that = HLoadNamedField::cast(other);
     if (!this->access_.Equals(that->access_)) return false;
     if (this->maps_ == that->maps_) return true;
@@ -6459,7 +6587,7 @@
     access.SetGVNFlags(this, LOAD);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 
   HObjectAccess access_;
   const UniqueSet<Map>* maps_;
@@ -6475,30 +6603,29 @@
   HValue* object() const { return OperandAt(1); }
   Handle<Object> name() const { return name_; }
 
-  int slot() const {
-    DCHECK(FLAG_vector_ics &&
-           slot_ != FeedbackSlotInterface::kInvalidFeedbackSlot);
-    return slot_;
+  FeedbackVectorICSlot slot() const { return slot_; }
+  Handle<TypeFeedbackVector> feedback_vector() const {
+    return feedback_vector_;
   }
-  Handle<FixedArray> feedback_vector() const { return feedback_vector_; }
-  void SetVectorAndSlot(Handle<FixedArray> vector, int slot) {
+  bool HasVectorAndSlot() const { return FLAG_vector_ics; }
+  void SetVectorAndSlot(Handle<TypeFeedbackVector> vector,
+                        FeedbackVectorICSlot slot) {
     DCHECK(FLAG_vector_ics);
     feedback_vector_ = vector;
     slot_ = slot;
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric)
 
  private:
   HLoadNamedGeneric(HValue* context, HValue* object, Handle<Object> name)
-      : name_(name),
-        slot_(FeedbackSlotInterface::kInvalidFeedbackSlot) {
+      : name_(name), slot_(FeedbackVectorICSlot::Invalid()) {
     SetOperandAt(0, context);
     SetOperandAt(1, object);
     set_representation(Representation::Tagged());
@@ -6506,8 +6633,8 @@
   }
 
   Handle<Object> name_;
-  Handle<FixedArray> feedback_vector_;
-  int slot_;
+  Handle<TypeFeedbackVector> feedback_vector_;
+  FeedbackVectorICSlot slot_;
 };
 
 
@@ -6517,14 +6644,14 @@
 
   HValue* function() { return OperandAt(0); }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   explicit HLoadFunctionPrototype(HValue* function)
@@ -6588,21 +6715,23 @@
   }
   bool HasDependency() const { return OperandAt(0) != OperandAt(2); }
   uint32_t base_offset() const { return BaseOffsetField::decode(bit_field_); }
-  bool TryIncreaseBaseOffset(uint32_t increase_by_value);
-  HValue* GetKey() { return key(); }
-  void SetKey(HValue* key) { SetOperandAt(1, key); }
-  bool IsDehoisted() const { return IsDehoistedField::decode(bit_field_); }
-  void SetDehoisted(bool is_dehoisted) {
+  bool TryIncreaseBaseOffset(uint32_t increase_by_value) OVERRIDE;
+  HValue* GetKey() OVERRIDE { return key(); }
+  void SetKey(HValue* key) OVERRIDE { SetOperandAt(1, key); }
+  bool IsDehoisted() const OVERRIDE {
+    return IsDehoistedField::decode(bit_field_);
+  }
+  void SetDehoisted(bool is_dehoisted) OVERRIDE {
     bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
   }
-  virtual ElementsKind elements_kind() const OVERRIDE {
+  ElementsKind elements_kind() const OVERRIDE {
     return ElementsKindField::decode(bit_field_);
   }
   LoadKeyedHoleMode hole_mode() const {
     return HoleModeField::decode(bit_field_);
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     // kind_fast:                 tagged[int32] (none)
     // kind_double:               tagged[int32] (none)
     // kind_fixed_typed_array:    tagged[int32] (none)
@@ -6618,27 +6747,26 @@
     return Representation::None();
   }
 
-  virtual Representation observed_input_representation(int index) OVERRIDE {
+  Representation observed_input_representation(int index) OVERRIDE {
     return RequiredInputRepresentation(index);
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   bool UsesMustHandleHole() const;
   bool AllUsesCanTreatHoleAsNaN() const;
   bool RequiresHoleCheck() const;
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE;
+  Range* InferRange(Zone* zone) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(LoadKeyed)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     if (!other->IsLoadKeyed()) return false;
     HLoadKeyed* other_load = HLoadKeyed::cast(other);
 
-    if (IsDehoisted() && base_offset() != other_load->base_offset())
-      return false;
+    if (base_offset() != other_load->base_offset()) return false;
     return elements_kind() == other_load->elements_kind();
   }
 
@@ -6710,9 +6838,7 @@
     SetFlag(kUseGVN);
   }
 
-  virtual bool IsDeletable() const OVERRIDE {
-    return !RequiresHoleCheck();
-  }
+  bool IsDeletable() const OVERRIDE { return !RequiresHoleCheck(); }
 
   // Establish some checks around our packed fields
   enum LoadKeyedBits {
@@ -6727,8 +6853,8 @@
     kStartIsDehoisted = kStartBaseOffset + kBitsForBaseOffset
   };
 
-  STATIC_ASSERT((kBitsForElementsKind + kBitsForBaseOffset +
-                 kBitsForIsDehoisted) <= sizeof(uint32_t)*8);
+  STATIC_ASSERT((kBitsForElementsKind + kBitsForHoleMode + kBitsForBaseOffset +
+                 kBitsForIsDehoisted) <= sizeof(uint32_t) * 8);
   STATIC_ASSERT(kElementsKindCount <= (1 << kBitsForElementsKind));
   class ElementsKindField:
     public BitField<ElementsKind, kStartElementsKind, kBitsForElementsKind>
@@ -6753,32 +6879,32 @@
   HValue* object() const { return OperandAt(0); }
   HValue* key() const { return OperandAt(1); }
   HValue* context() const { return OperandAt(2); }
-  int slot() const {
-    DCHECK(FLAG_vector_ics &&
-           slot_ != FeedbackSlotInterface::kInvalidFeedbackSlot);
-    return slot_;
+  FeedbackVectorICSlot slot() const { return slot_; }
+  Handle<TypeFeedbackVector> feedback_vector() const {
+    return feedback_vector_;
   }
-  Handle<FixedArray> feedback_vector() const { return feedback_vector_; }
-  void SetVectorAndSlot(Handle<FixedArray> vector, int slot) {
+  bool HasVectorAndSlot() const { return FLAG_vector_ics; }
+  void SetVectorAndSlot(Handle<TypeFeedbackVector> vector,
+                        FeedbackVectorICSlot slot) {
     DCHECK(FLAG_vector_ics);
     feedback_vector_ = vector;
     slot_ = slot;
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     // tagged[tagged]
     return Representation::Tagged();
   }
 
-  virtual HValue* Canonicalize() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric)
 
  private:
   HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key)
-      : slot_(FeedbackSlotInterface::kInvalidFeedbackSlot) {
+      : slot_(FeedbackVectorICSlot::Invalid()) {
     set_representation(Representation::Tagged());
     SetOperandAt(0, obj);
     SetOperandAt(1, key);
@@ -6786,8 +6912,8 @@
     SetAllSideEffects();
   }
 
-  Handle<FixedArray> feedback_vector_;
-  int slot_;
+  Handle<TypeFeedbackVector> feedback_vector_;
+  FeedbackVectorICSlot slot_;
 };
 
 
@@ -6811,13 +6937,11 @@
 
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField)
 
-  virtual bool HasEscapingOperandAt(int index) OVERRIDE {
-    return index == 1;
-  }
-  virtual bool HasOutOfBoundsAccess(int size) OVERRIDE {
+  bool HasEscapingOperandAt(int index) OVERRIDE { return index == 1; }
+  bool HasOutOfBoundsAccess(int size) OVERRIDE {
     return !access().IsInobject() || access().offset() >= size;
   }
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     if (index == 0 && access().IsExternalMemory()) {
       // object must be external in case of external memory access
       return Representation::External();
@@ -6831,7 +6955,8 @@
       } else if (field_representation().IsDouble()) {
         return field_representation();
       } else if (field_representation().IsSmi()) {
-        if (SmiValuesAre32Bits() && store_mode_ == STORE_TO_INITIALIZED_ENTRY) {
+        if (SmiValuesAre32Bits() &&
+            store_mode() == STORE_TO_INITIALIZED_ENTRY) {
           return Representation::Integer32();
         }
         return field_representation();
@@ -6848,7 +6973,7 @@
     dominator_ = dominator;
     return false;
   }
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   HValue* object() const { return OperandAt(0); }
   HValue* value() const { return OperandAt(1); }
@@ -6856,8 +6981,10 @@
 
   HObjectAccess access() const { return access_; }
   HValue* dominator() const { return dominator_; }
-  bool has_transition() const { return has_transition_; }
-  StoreFieldOrKeyedMode store_mode() const { return store_mode_; }
+  bool has_transition() const { return HasTransitionField::decode(bit_field_); }
+  StoreFieldOrKeyedMode store_mode() const {
+    return StoreModeField::decode(bit_field_);
+  }
 
   Handle<Map> transition_map() const {
     if (has_transition()) {
@@ -6871,12 +6998,14 @@
   void SetTransition(HConstant* transition) {
     DCHECK(!has_transition());  // Only set once.
     SetOperandAt(2, transition);
-    has_transition_ = true;
+    bit_field_ = HasTransitionField::update(bit_field_, true);
     SetChangesFlag(kMaps);
   }
 
   bool NeedsWriteBarrier() const {
-    DCHECK(!field_representation().IsDouble() || !has_transition());
+    DCHECK(!field_representation().IsDouble() ||
+           (FLAG_unbox_double_fields && access_.IsInobject()) ||
+           !has_transition());
     if (field_representation().IsDouble()) return false;
     if (field_representation().IsSmi()) return false;
     if (field_representation().IsInteger32()) return false;
@@ -6922,14 +7051,12 @@
   }
 
  private:
-  HStoreNamedField(HValue* obj,
-                   HObjectAccess access,
-                   HValue* val,
+  HStoreNamedField(HValue* obj, HObjectAccess access, HValue* val,
                    StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE)
       : access_(access),
         dominator_(NULL),
-        has_transition_(false),
-        store_mode_(store_mode) {
+        bit_field_(HasTransitionField::encode(false) |
+                   StoreModeField::encode(store_mode)) {
     // Stores to a non existing in-object property are allowed only to the
     // newly allocated objects (via HAllocate or HInnerAllocatedObject).
     DCHECK(!access.IsInobject() || access.existing_inobject_property() ||
@@ -6940,10 +7067,12 @@
     access.SetGVNFlags(this, STORE);
   }
 
+  class HasTransitionField : public BitField<bool, 0, 1> {};
+  class StoreModeField : public BitField<StoreFieldOrKeyedMode, 1, 1> {};
+
   HObjectAccess access_;
   HValue* dominator_;
-  bool has_transition_ : 1;
-  StoreFieldOrKeyedMode store_mode_ : 1;
+  uint32_t bit_field_;
 };
 
 
@@ -6958,9 +7087,9 @@
   Handle<String> name() const { return name_; }
   StrictMode strict_mode() const { return strict_mode_; }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -6995,7 +7124,7 @@
   DECLARE_INSTRUCTION_FACTORY_P6(HStoreKeyed, HValue*, HValue*, HValue*,
                                  ElementsKind, StoreFieldOrKeyedMode, int);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     // kind_fast:               tagged[int32] = tagged
     // kind_double:             tagged[int32] = double
     // kind_smi   :             tagged[int32] = smi
@@ -7010,7 +7139,7 @@
     }
 
     DCHECK_EQ(index, 2);
-    return RequiredValueRepresentation(elements_kind_, store_mode_);
+    return RequiredValueRepresentation(elements_kind(), store_mode());
   }
 
   static Representation RequiredValueRepresentation(
@@ -7046,12 +7175,13 @@
     return is_external() || is_fixed_typed_array();
   }
 
-  virtual Representation observed_input_representation(int index) OVERRIDE {
+  Representation observed_input_representation(int index) OVERRIDE {
     if (index < 2) return RequiredInputRepresentation(index);
     if (IsUninitialized()) {
       return Representation::None();
     }
-    Representation r = RequiredValueRepresentation(elements_kind_, store_mode_);
+    Representation r =
+        RequiredValueRepresentation(elements_kind(), store_mode());
     // For fast object elements kinds, don't assume anything.
     if (r.IsTagged()) return Representation::None();
     return r;
@@ -7060,20 +7190,26 @@
   HValue* elements() const { return OperandAt(0); }
   HValue* key() const { return OperandAt(1); }
   HValue* value() const { return OperandAt(2); }
-  bool value_is_smi() const {
-    return IsFastSmiElementsKind(elements_kind_);
+  bool value_is_smi() const { return IsFastSmiElementsKind(elements_kind()); }
+  StoreFieldOrKeyedMode store_mode() const {
+    return StoreModeField::decode(bit_field_);
   }
-  StoreFieldOrKeyedMode store_mode() const { return store_mode_; }
-  ElementsKind elements_kind() const { return elements_kind_; }
+  ElementsKind elements_kind() const OVERRIDE {
+    return ElementsKindField::decode(bit_field_);
+  }
   uint32_t base_offset() const { return base_offset_; }
-  bool TryIncreaseBaseOffset(uint32_t increase_by_value);
-  HValue* GetKey() { return key(); }
-  void SetKey(HValue* key) { SetOperandAt(1, key); }
-  bool IsDehoisted() const { return is_dehoisted_; }
-  void SetDehoisted(bool is_dehoisted) { is_dehoisted_ = is_dehoisted; }
-  bool IsUninitialized() { return is_uninitialized_; }
+  bool TryIncreaseBaseOffset(uint32_t increase_by_value) OVERRIDE;
+  HValue* GetKey() OVERRIDE { return key(); }
+  void SetKey(HValue* key) OVERRIDE { SetOperandAt(1, key); }
+  bool IsDehoisted() const OVERRIDE {
+    return IsDehoistedField::decode(bit_field_);
+  }
+  void SetDehoisted(bool is_dehoisted) OVERRIDE {
+    bit_field_ = IsDehoistedField::update(bit_field_, is_dehoisted);
+  }
+  bool IsUninitialized() { return IsUninitializedField::decode(bit_field_); }
   void SetUninitialized(bool is_uninitialized) {
-    is_uninitialized_ = is_uninitialized;
+    bit_field_ = IsUninitializedField::update(bit_field_, is_uninitialized);
   }
 
   bool IsConstantHoleStore() {
@@ -7104,23 +7240,22 @@
 
   bool NeedsCanonicalization();
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyed)
 
  private:
-  HStoreKeyed(HValue* obj, HValue* key, HValue* val,
-              ElementsKind elements_kind,
+  HStoreKeyed(HValue* obj, HValue* key, HValue* val, ElementsKind elements_kind,
               StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE,
               int offset = kDefaultKeyedHeaderOffsetSentinel)
-      : elements_kind_(elements_kind),
-      base_offset_(offset == kDefaultKeyedHeaderOffsetSentinel
-          ? GetDefaultHeaderSizeForElementsKind(elements_kind)
-          : offset),
-      is_dehoisted_(false),
-      is_uninitialized_(false),
-      store_mode_(store_mode),
-      dominator_(NULL) {
+      : base_offset_(offset == kDefaultKeyedHeaderOffsetSentinel
+                         ? GetDefaultHeaderSizeForElementsKind(elements_kind)
+                         : offset),
+        bit_field_(IsDehoistedField::encode(false) |
+                   IsUninitializedField::encode(false) |
+                   StoreModeField::encode(store_mode) |
+                   ElementsKindField::encode(elements_kind)),
+        dominator_(NULL) {
     SetOperandAt(0, obj);
     SetOperandAt(1, key);
     SetOperandAt(2, val);
@@ -7152,11 +7287,13 @@
     }
   }
 
-  ElementsKind elements_kind_;
+  class IsDehoistedField : public BitField<bool, 0, 1> {};
+  class IsUninitializedField : public BitField<bool, 1, 1> {};
+  class StoreModeField : public BitField<StoreFieldOrKeyedMode, 2, 1> {};
+  class ElementsKindField : public BitField<ElementsKind, 3, 5> {};
+
   uint32_t base_offset_;
-  bool is_dehoisted_ : 1;
-  bool is_uninitialized_ : 1;
-  StoreFieldOrKeyedMode store_mode_: 1;
+  uint32_t bit_field_;
   HValue* dominator_;
 };
 
@@ -7172,12 +7309,12 @@
   HValue* context() const { return OperandAt(3); }
   StrictMode strict_mode() const { return strict_mode_; }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     // tagged[tagged] = tagged
     return Representation::Tagged();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric)
 
@@ -7210,7 +7347,7 @@
                                              original_map, transitioned_map);
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -7221,18 +7358,18 @@
   ElementsKind from_kind() const { return from_kind_; }
   ElementsKind to_kind() const { return to_kind_; }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     HTransitionElementsKind* instr = HTransitionElementsKind::cast(other);
     return original_map_ == instr->original_map_ &&
            transitioned_map_ == instr->transitioned_map_;
   }
 
-  virtual int RedefinedOperandIndex() { return 0; }
+  int RedefinedOperandIndex() OVERRIDE { return 0; }
 
  private:
   HTransitionElementsKind(HValue* context,
@@ -7275,16 +7412,16 @@
   StringAddFlags flags() const { return flags_; }
   PretenureFlag pretenure_flag() const { return pretenure_flag_; }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(StringAdd)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     return flags_ == HStringAdd::cast(other)->flags_ &&
         pretenure_flag_ == HStringAdd::cast(other)->pretenure_flag_;
   }
@@ -7312,7 +7449,7 @@
   }
 
   // No side-effects except possible allocation:
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 
   const StringAddFlags flags_;
   const PretenureFlag pretenure_flag_;
@@ -7325,7 +7462,7 @@
                                               HValue*,
                                               HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     // The index is supposed to be Integer32.
     return index == 2
         ? Representation::Integer32()
@@ -7339,9 +7476,9 @@
   DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE {
+  Range* InferRange(Zone* zone) OVERRIDE {
     return new(zone) Range(0, String::kMaxUtf16CodeUnit);
   }
 
@@ -7358,7 +7495,7 @@
   }
 
   // No side effects: runtime function assumes string + number inputs.
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -7368,7 +7505,7 @@
                            HValue* context,
                            HValue* char_code);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return index == 0
         ? Representation::Tagged()
         : Representation::Integer32();
@@ -7377,7 +7514,7 @@
   HValue* context() const { return OperandAt(0); }
   HValue* value() const { return OperandAt(1); }
 
-  virtual bool DataEquals(HValue* other) OVERRIDE { return true; }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
   DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode)
 
@@ -7391,7 +7528,7 @@
     SetChangesFlag(kNewSpacePromotion);
   }
 
-  virtual bool IsDeletable() const OVERRIDE {
+  bool IsDeletable() const OVERRIDE {
     return !value()->ToNumberCanBeObserved();
   }
 };
@@ -7418,7 +7555,7 @@
   }
 
  private:
-  virtual bool IsDeletable() const FINAL OVERRIDE { return true; }
+  bool IsDeletable() const FINAL { return true; }
 
   int literal_index_;
   int depth_;
@@ -7439,7 +7576,7 @@
   Handle<String> pattern() { return pattern_; }
   Handle<String> flags() { return flags_; }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -7473,42 +7610,47 @@
                                               bool);
   HValue* context() { return OperandAt(0); }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
   DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral)
 
   Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
-  bool pretenure() const { return pretenure_; }
-  bool has_no_literals() const { return has_no_literals_; }
-  bool is_arrow() const { return IsArrowFunction(kind_); }
-  bool is_generator() const { return IsGeneratorFunction(kind_); }
-  bool is_concise_method() const { return IsConciseMethod(kind_); }
-  FunctionKind kind() const { return kind_; }
-  StrictMode strict_mode() const { return strict_mode_; }
+  bool pretenure() const { return PretenureField::decode(bit_field_); }
+  bool has_no_literals() const {
+    return HasNoLiteralsField::decode(bit_field_);
+  }
+  bool is_arrow() const { return IsArrowFunction(kind()); }
+  bool is_generator() const { return IsGeneratorFunction(kind()); }
+  bool is_concise_method() const { return IsConciseMethod(kind()); }
+  bool is_default_constructor() const { return IsDefaultConstructor(kind()); }
+  FunctionKind kind() const { return FunctionKindField::decode(bit_field_); }
+  StrictMode strict_mode() const { return StrictModeField::decode(bit_field_); }
 
  private:
   HFunctionLiteral(HValue* context, Handle<SharedFunctionInfo> shared,
                    bool pretenure)
       : HTemplateInstruction<1>(HType::JSObject()),
         shared_info_(shared),
-        kind_(shared->kind()),
-        pretenure_(pretenure),
-        has_no_literals_(shared->num_literals() == 0),
-        strict_mode_(shared->strict_mode()) {
+        bit_field_(FunctionKindField::encode(shared->kind()) |
+                   PretenureField::encode(pretenure) |
+                   HasNoLiteralsField::encode(shared->num_literals() == 0) |
+                   StrictModeField::encode(shared->strict_mode())) {
     SetOperandAt(0, context);
     set_representation(Representation::Tagged());
     SetChangesFlag(kNewSpacePromotion);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
+
+  class FunctionKindField : public BitField<FunctionKind, 0, 4> {};
+  class PretenureField : public BitField<bool, 5, 1> {};
+  class HasNoLiteralsField : public BitField<bool, 6, 1> {};
+  class StrictModeField : public BitField<StrictMode, 7, 1> {};
 
   Handle<SharedFunctionInfo> shared_info_;
-  FunctionKind kind_;
-  bool pretenure_ : 1;
-  bool has_no_literals_ : 1;
-  StrictMode strict_mode_;
+  uint32_t bit_field_;
 };
 
 
@@ -7519,9 +7661,9 @@
   HValue* context() const { return OperandAt(0); }
   HValue* value() const { return OperandAt(1); }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -7534,7 +7676,7 @@
     set_representation(Representation::Tagged());
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -7542,7 +7684,7 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P1(HTrapAllocationMemento, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -7561,7 +7703,7 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P1(HToFastProperties, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -7582,7 +7724,7 @@
 #endif
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -7592,7 +7734,7 @@
 
   Smi* index() const { return index_; }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -7616,7 +7758,7 @@
                            HValue* string,
                            HValue* index);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return (index == 0) ? Representation::Tagged()
                         : Representation::Integer32();
   }
@@ -7628,11 +7770,11 @@
   DECLARE_CONCRETE_INSTRUCTION(SeqStringGetChar)
 
  protected:
-  virtual bool DataEquals(HValue* other) OVERRIDE {
+  bool DataEquals(HValue* other) OVERRIDE {
     return encoding() == HSeqStringGetChar::cast(other)->encoding();
   }
 
-  virtual Range* InferRange(Zone* zone) OVERRIDE {
+  Range* InferRange(Zone* zone) OVERRIDE {
     if (encoding() == String::ONE_BYTE_ENCODING) {
       return new(zone) Range(0, String::kMaxOneByteCharCode);
     } else {
@@ -7652,7 +7794,7 @@
     SetDependsOnFlag(kStringChars);
   }
 
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 
   String::Encoding encoding_;
 };
@@ -7670,7 +7812,7 @@
   HValue* index() { return OperandAt(2); }
   HValue* value() { return OperandAt(3); }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return (index <= 1) ? Representation::Tagged()
                         : Representation::Integer32();
   }
@@ -7699,13 +7841,13 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P2(HCheckMapValue, HValue*, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual HType CalculateInferredType() OVERRIDE {
+  HType CalculateInferredType() OVERRIDE {
     if (value()->type().IsHeapObject()) return value()->type();
     return HType::HeapObject();
   }
@@ -7713,16 +7855,14 @@
   HValue* value() const { return OperandAt(0); }
   HValue* map() const { return OperandAt(1); }
 
-  virtual HValue* Canonicalize() OVERRIDE;
+  HValue* Canonicalize() OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(CheckMapValue)
 
  protected:
-  virtual int RedefinedOperandIndex() { return 0; }
+  int RedefinedOperandIndex() OVERRIDE { return 0; }
 
-  virtual bool DataEquals(HValue* other) OVERRIDE {
-    return true;
-  }
+  bool DataEquals(HValue* other) OVERRIDE { return true; }
 
  private:
   HCheckMapValue(HValue* value, HValue* map)
@@ -7741,18 +7881,16 @@
  public:
   DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P1(HForInPrepareMap, HValue*);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
   HValue* context() const { return OperandAt(0); }
   HValue* enumerable() const { return OperandAt(1); }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual HType CalculateInferredType() OVERRIDE {
-    return HType::Tagged();
-  }
+  HType CalculateInferredType() OVERRIDE { return HType::Tagged(); }
 
   DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap);
 
@@ -7771,7 +7909,7 @@
  public:
   DECLARE_INSTRUCTION_FACTORY_P3(HForInCacheArray, HValue*, HValue*, int);
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -7787,11 +7925,9 @@
     index_cache_ = index_cache;
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual HType CalculateInferredType() OVERRIDE {
-    return HType::Tagged();
-  }
+  HType CalculateInferredType() OVERRIDE { return HType::Tagged(); }
 
   DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray);
 
@@ -7821,7 +7957,7 @@
     set_representation(Representation::Tagged());
   }
 
-  virtual Representation RequiredInputRepresentation(int index) OVERRIDE {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     if (index == 1) {
       return Representation::Smi();
     } else {
@@ -7832,16 +7968,14 @@
   HValue* object() const { return OperandAt(0); }
   HValue* index() const { return OperandAt(1); }
 
-  virtual OStream& PrintDataTo(OStream& os) const OVERRIDE;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
-  virtual HType CalculateInferredType() OVERRIDE {
-    return HType::Tagged();
-  }
+  HType CalculateInferredType() OVERRIDE { return HType::Tagged(); }
 
   DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex);
 
  private:
-  virtual bool IsDeletable() const OVERRIDE { return true; }
+  bool IsDeletable() const OVERRIDE { return true; }
 };
 
 
@@ -7851,7 +7985,7 @@
 
   HValue* context() { return OperandAt(0); }
 
-  virtual Representation RequiredInputRepresentation(int index) {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
@@ -7873,11 +8007,11 @@
   HValue* function() const { return OperandAt(1); }
   Handle<ScopeInfo> scope_info() const { return scope_info_; }
 
-  virtual Representation RequiredInputRepresentation(int index) {
+  Representation RequiredInputRepresentation(int index) OVERRIDE {
     return Representation::Tagged();
   }
 
-  virtual OStream& PrintDataTo(OStream& os) const;  // NOLINT
+  std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE;  // NOLINT
 
   DECLARE_CONCRETE_INSTRUCTION(AllocateBlockContext)
 
diff --git a/src/hydrogen-removable-simulates.cc b/src/hydrogen-removable-simulates.cc
index a28021d..73d7a8e 100644
--- a/src/hydrogen-removable-simulates.cc
+++ b/src/hydrogen-removable-simulates.cc
@@ -53,6 +53,13 @@
       FlushSimulates();
       return this;
     }
+    if (instr->IsCapturedObject()) {
+      // Do not merge simulates across captured objects - captured objects
+      // change environments during environment replay, and such changes
+      // would not be reflected in the simulate.
+      FlushSimulates();
+      return this;
+    }
     // Skip the non-simulates and the first simulate.
     if (!instr->IsSimulate()) return this;
     if (first_) {
diff --git a/src/hydrogen-representation-changes.cc b/src/hydrogen-representation-changes.cc
index ebb03b5..bfc8271 100644
--- a/src/hydrogen-representation-changes.cc
+++ b/src/hydrogen-representation-changes.cc
@@ -63,7 +63,17 @@
 void HRepresentationChangesPhase::InsertRepresentationChangesForValue(
     HValue* value) {
   Representation r = value->representation();
-  if (r.IsNone()) return;
+  if (r.IsNone()) {
+#ifdef DEBUG
+    for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) {
+      HValue* use_value = it.value();
+      int use_index = it.index();
+      Representation req = use_value->RequiredInputRepresentation(use_index);
+      DCHECK(req.IsNone());
+    }
+#endif
+    return;
+  }
   if (value->HasNoUses()) {
     if (value->IsForceRepresentation()) value->DeleteAndReplaceWith(NULL);
     return;
diff --git a/src/hydrogen-types.cc b/src/hydrogen-types.cc
index 87047a2..a05e30f 100644
--- a/src/hydrogen-types.cc
+++ b/src/hydrogen-types.cc
@@ -56,7 +56,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const HType& t) {
+std::ostream& operator<<(std::ostream& os, const HType& t) {
   // Note: The c1visualizer syntax for locals allows only a sequence of the
   // following characters: A-Za-z0-9_-|:
   switch (t.kind_) {
diff --git a/src/hydrogen-types.h b/src/hydrogen-types.h
index a42cba5..70870dd 100644
--- a/src/hydrogen-types.h
+++ b/src/hydrogen-types.h
@@ -6,6 +6,7 @@
 #define HYDROGEN_TYPES_H_
 
 #include <climits>
+#include <iosfwd>
 
 #include "src/base/macros.h"
 
@@ -15,7 +16,6 @@
 // Forward declarations.
 template <typename T> class Handle;
 class Object;
-class OStream;
 
 #define HTYPE_LIST(V)                                 \
   V(Any, 0x0)              /* 0000 0000 0000 0000 */  \
@@ -65,7 +65,7 @@
   static HType FromType(typename T::TypeHandle type) WARN_UNUSED_RESULT;
   static HType FromValue(Handle<Object> value) WARN_UNUSED_RESULT;
 
-  friend OStream& operator<<(OStream& os, const HType& t);
+  friend std::ostream& operator<<(std::ostream& os, const HType& t);
 
  private:
   enum Kind {
@@ -84,7 +84,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const HType& t);
+std::ostream& operator<<(std::ostream& os, const HType& t);
 } }  // namespace v8::internal
 
 #endif  // HYDROGEN_TYPES_H_
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 37ee2e4..a684311 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -4,14 +4,13 @@
 
 #include "src/hydrogen.h"
 
-#include <algorithm>
+#include <sstream>
 
 #include "src/v8.h"
 
 #include "src/allocation-site-scopes.h"
-#include "src/codegen.h"
+#include "src/ast-numbering.h"
 #include "src/full-codegen.h"
-#include "src/hashmap.h"
 #include "src/hydrogen-bce.h"
 #include "src/hydrogen-bch.h"
 #include "src/hydrogen-canonicalize.h"
@@ -40,9 +39,8 @@
 #include "src/ic/ic-inl.h"
 #include "src/lithium-allocator.h"
 #include "src/parser.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 #include "src/scopeinfo.h"
-#include "src/scopes.h"
 #include "src/typing.h"
 
 #if V8_TARGET_ARCH_IA32
@@ -147,7 +145,7 @@
       entry->set_position(position);
     } else {
       DCHECK(!FLAG_hydrogen_track_positions ||
-             !graph()->info()->IsOptimizing());
+             !graph()->info()->IsOptimizing() || instr->IsAbnormalExit());
     }
     first_ = last_ = entry;
   }
@@ -1219,8 +1217,8 @@
 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) {
   if (FLAG_native_code_counters && counter->Enabled()) {
     HValue* reference = Add<HConstant>(ExternalReference(counter));
-    HValue* old_value = Add<HLoadNamedField>(
-        reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter());
+    HValue* old_value =
+        Add<HLoadNamedField>(reference, nullptr, HObjectAccess::ForCounter());
     HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1());
     new_value->ClearFlag(HValue::kCanOverflow);  // Ignore counter overflow
     Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(),
@@ -1254,11 +1252,10 @@
 
 
 HValue* HGraphBuilder::BuildGetElementsKind(HValue* object) {
-  HValue* map = Add<HLoadNamedField>(object, static_cast<HValue*>(NULL),
-                                     HObjectAccess::ForMap());
+  HValue* map = Add<HLoadNamedField>(object, nullptr, HObjectAccess::ForMap());
 
-  HValue* bit_field2 = Add<HLoadNamedField>(map, static_cast<HValue*>(NULL),
-                                            HObjectAccess::ForMapBitField2());
+  HValue* bit_field2 =
+      Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField2());
   return BuildDecodeField<Map::ElementsKindBits>(bit_field2);
 }
 
@@ -1417,10 +1414,11 @@
 
     HInstruction* elements_length = AddLoadFixedArrayLength(elements);
 
-    HInstruction* array_length = is_jsarray
-        ? Add<HLoadNamedField>(object, static_cast<HValue*>(NULL),
-                               HObjectAccess::ForArrayLength(from_kind))
-        : elements_length;
+    HInstruction* array_length =
+        is_jsarray
+            ? Add<HLoadNamedField>(object, nullptr,
+                                   HObjectAccess::ForArrayLength(from_kind))
+            : elements_length;
 
     BuildGrowElementsCapacity(object, elements, from_kind, to_kind,
                               array_length, elements_length);
@@ -1438,14 +1436,14 @@
   Add<HCheckHeapObject>(receiver);
 
   // Get the map of the receiver.
-  HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
-                                     HObjectAccess::ForMap());
+  HValue* map =
+      Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap());
 
   // Check the instance type and if an access check is needed, this can be
   // done with a single load, since both bytes are adjacent in the map.
   HObjectAccess access(HObjectAccess::ForMapInstanceTypeAndBitField());
   HValue* instance_type_and_bit_field =
-      Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), access);
+      Add<HLoadNamedField>(map, nullptr, access);
 
   HValue* mask = Add<HConstant>(0x00FF | (bit_field_mask << 8));
   HValue* and_result = AddUncasted<HBitwise>(Token::BIT_AND,
@@ -1474,11 +1472,9 @@
   }
   key_smi_if.Else();
   {
-    HValue* map = Add<HLoadNamedField>(key, static_cast<HValue*>(NULL),
-                                       HObjectAccess::ForMap());
+    HValue* map = Add<HLoadNamedField>(key, nullptr, HObjectAccess::ForMap());
     HValue* instance_type =
-        Add<HLoadNamedField>(map, static_cast<HValue*>(NULL),
-                             HObjectAccess::ForMapInstanceType());
+        Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType());
 
     // Non-unique string, check for a string with a hash code that is actually
     // an index.
@@ -1510,9 +1506,8 @@
       {
         // String: check whether the String is a String of an index. If it is,
         // extract the index value from the hash.
-        HValue* hash =
-            Add<HLoadNamedField>(key, static_cast<HValue*>(NULL),
-                                 HObjectAccess::ForNameHashField());
+        HValue* hash = Add<HLoadNamedField>(key, nullptr,
+                                            HObjectAccess::ForNameHashField());
         HValue* not_index_mask = Add<HConstant>(static_cast<int>(
             String::kContainsCachedArrayIndexMask));
 
@@ -1571,11 +1566,10 @@
 void HGraphBuilder::BuildNonGlobalObjectCheck(HValue* receiver) {
   // Get the the instance type of the receiver, and make sure that it is
   // not one of the global object types.
-  HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL),
-                                     HObjectAccess::ForMap());
+  HValue* map =
+      Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap());
   HValue* instance_type =
-    Add<HLoadNamedField>(map, static_cast<HValue*>(NULL),
-                         HObjectAccess::ForMapInstanceType());
+      Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType());
   STATIC_ASSERT(JS_BUILTINS_OBJECT_TYPE == JS_GLOBAL_OBJECT_TYPE + 1);
   HValue* min_global_type = Add<HConstant>(JS_GLOBAL_OBJECT_TYPE);
   HValue* max_global_type = Add<HConstant>(JS_BUILTINS_OBJECT_TYPE);
@@ -1597,11 +1591,9 @@
     HValue* object,
     HIfContinuation* continuation) {
   HValue* properties = Add<HLoadNamedField>(
-      object, static_cast<HValue*>(NULL),
-      HObjectAccess::ForPropertiesPointer());
+      object, nullptr, HObjectAccess::ForPropertiesPointer());
   HValue* properties_map =
-      Add<HLoadNamedField>(properties, static_cast<HValue*>(NULL),
-                           HObjectAccess::ForMap());
+      Add<HLoadNamedField>(properties, nullptr, HObjectAccess::ForMap());
   HValue* hash_map = Add<HLoadRoot>(Heap::kHashTableMapRootIndex);
   IfBuilder builder(this);
   builder.If<HCompareObjectEqAndBranch>(properties_map, hash_map);
@@ -1614,13 +1606,11 @@
   // Load the map of the receiver, compute the keyed lookup cache hash
   // based on 32 bits of the map pointer and the string hash.
   HValue* object_map =
-      Add<HLoadNamedField>(object, static_cast<HValue*>(NULL),
-                           HObjectAccess::ForMapAsInteger32());
+      Add<HLoadNamedField>(object, nullptr, HObjectAccess::ForMapAsInteger32());
   HValue* shifted_map = AddUncasted<HShr>(
       object_map, Add<HConstant>(KeyedLookupCache::kMapHashShift));
   HValue* string_hash =
-      Add<HLoadNamedField>(key, static_cast<HValue*>(NULL),
-                           HObjectAccess::ForStringHashField());
+      Add<HLoadNamedField>(key, nullptr, HObjectAccess::ForStringHashField());
   HValue* shifted_hash = AddUncasted<HShr>(
       string_hash, Add<HConstant>(String::kHashShift));
   HValue* xor_result = AddUncasted<HBitwise>(Token::BIT_XOR, shifted_map,
@@ -1668,11 +1658,9 @@
                                                            HValue* elements,
                                                            HValue* key,
                                                            HValue* hash) {
-  HValue* capacity = Add<HLoadKeyed>(
-      elements,
-      Add<HConstant>(NameDictionary::kCapacityIndex),
-      static_cast<HValue*>(NULL),
-      FAST_ELEMENTS);
+  HValue* capacity =
+      Add<HLoadKeyed>(elements, Add<HConstant>(NameDictionary::kCapacityIndex),
+                      nullptr, FAST_ELEMENTS);
 
   HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1());
   mask->ChangeRepresentation(Representation::Integer32());
@@ -1702,8 +1690,8 @@
       AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset));
   key_index->ClearFlag(HValue::kCanOverflow);
 
-  HValue* candidate_key = Add<HLoadKeyed>(
-      elements, key_index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
+  HValue* candidate_key =
+      Add<HLoadKeyed>(elements, key_index, nullptr, FAST_ELEMENTS);
   IfBuilder if_undefined(this);
   if_undefined.If<HCompareObjectEqAndBranch>(candidate_key,
                                              graph()->GetConstantUndefined());
@@ -1729,8 +1717,8 @@
         if_update_with_internalized.IfNot<HIsSmiAndBranch>(candidate_key);
     if_update_with_internalized.And();
     HValue* map = AddLoadMap(candidate_key, smi_check);
-    HValue* instance_type = Add<HLoadNamedField>(
-        map, static_cast<HValue*>(NULL), HObjectAccess::ForMapInstanceType());
+    HValue* instance_type =
+        Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType());
     HValue* not_internalized_bit = AddUncasted<HBitwise>(
         Token::BIT_AND, instance_type,
         Add<HConstant>(static_cast<int>(kIsNotInternalizedMask)));
@@ -1757,8 +1745,8 @@
     HValue* details_index =
         AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 2));
     details_index->ClearFlag(HValue::kCanOverflow);
-    HValue* details = Add<HLoadKeyed>(
-        elements, details_index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
+    HValue* details =
+        Add<HLoadKeyed>(elements, details_index, nullptr, FAST_ELEMENTS);
     int details_mask = PropertyDetails::TypeField::kMask |
                        PropertyDetails::DeletedField::kMask;
     details = AddUncasted<HBitwise>(Token::BIT_AND, details,
@@ -1770,8 +1758,7 @@
     HValue* result_index =
         AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1));
     result_index->ClearFlag(HValue::kCanOverflow);
-    Push(Add<HLoadKeyed>(elements, result_index, static_cast<HValue*>(NULL),
-                         FAST_ELEMENTS));
+    Push(Add<HLoadKeyed>(elements, result_index, nullptr, FAST_ELEMENTS));
     details_compare.Else();
     Add<HPushArguments>(receiver, key);
     Push(Add<HCallRuntime>(isolate()->factory()->empty_string(),
@@ -1823,15 +1810,14 @@
 
   // Initialize the JSRegExpResult header.
   HValue* global_object = Add<HLoadNamedField>(
-      context(), static_cast<HValue*>(NULL),
+      context(), nullptr,
       HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
   HValue* native_context = Add<HLoadNamedField>(
-      global_object, static_cast<HValue*>(NULL),
-      HObjectAccess::ForGlobalObjectNativeContext());
+      global_object, nullptr, HObjectAccess::ForGlobalObjectNativeContext());
   Add<HStoreNamedField>(
       result, HObjectAccess::ForMap(),
       Add<HLoadNamedField>(
-          native_context, static_cast<HValue*>(NULL),
+          native_context, nullptr,
           HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX)));
   HConstant* empty_fixed_array =
       Add<HConstant>(isolate()->factory()->empty_fixed_array());
@@ -1910,8 +1896,7 @@
 
     // Load the key.
     HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1());
-    HValue* key = Add<HLoadKeyed>(number_string_cache, key_index,
-                                  static_cast<HValue*>(NULL),
+    HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, nullptr,
                                   FAST_ELEMENTS, ALLOW_RETURN_HOLE);
 
     // Check if object == key.
@@ -1947,8 +1932,7 @@
 
         // Load the key.
         HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1());
-        HValue* key = Add<HLoadKeyed>(number_string_cache, key_index,
-                                      static_cast<HValue*>(NULL),
+        HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, nullptr,
                                       FAST_ELEMENTS, ALLOW_RETURN_HOLE);
 
         // Check if the key is a heap number and compare it with the object.
@@ -2001,8 +1985,7 @@
     // Load the value in case of cache hit.
     HValue* key_index = Pop();
     HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1());
-    Push(Add<HLoadKeyed>(number_string_cache, value_index,
-                         static_cast<HValue*>(NULL),
+    Push(Add<HLoadKeyed>(number_string_cache, value_index, nullptr,
                          FAST_ELEMENTS, ALLOW_RETURN_HOLE));
   }
   if_found.Else();
@@ -2442,8 +2425,7 @@
     HValue* backing_store;
     if (IsExternalArrayElementsKind(elements_kind)) {
       backing_store = Add<HLoadNamedField>(
-          elements, static_cast<HValue*>(NULL),
-          HObjectAccess::ForExternalArrayExternalPointer());
+          elements, nullptr, HObjectAccess::ForExternalArrayExternalPointer());
     } else {
       backing_store = elements;
     }
@@ -2626,16 +2608,15 @@
 }
 
 
-HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
-    ElementsKind kind,
-    HValue* capacity) {
+HValue* HGraphBuilder::BuildAllocateAndInitializeArray(ElementsKind kind,
+                                                       HValue* capacity) {
   // The HForceRepresentation is to prevent possible deopt on int-smi
   // conversion after allocation but before the new object fields are set.
   capacity = AddUncasted<HForceRepresentation>(capacity, Representation::Smi());
   HValue* size_in_bytes = BuildCalculateElementsSize(kind, capacity);
-  HValue* new_elements = BuildAllocateElements(kind, size_in_bytes);
-  BuildInitializeElementsHeader(new_elements, kind, capacity);
-  return new_elements;
+  HValue* new_array = BuildAllocateElements(kind, size_in_bytes);
+  BuildInitializeElementsHeader(new_array, kind, capacity);
+  return new_array;
 }
 
 
@@ -2690,9 +2671,8 @@
   DCHECK(val == NULL);
   HLoadKeyed* load = Add<HLoadKeyed>(
       elements, checked_key, dependency, elements_kind, load_mode);
-  if (FLAG_opt_safe_uint32_operations &&
-      (elements_kind == EXTERNAL_UINT32_ELEMENTS ||
-       elements_kind == UINT32_ELEMENTS)) {
+  if (elements_kind == EXTERNAL_UINT32_ELEMENTS ||
+      elements_kind == UINT32_ELEMENTS) {
     graph()->RecordUint32Instruction(load);
   }
   return load;
@@ -2754,8 +2734,8 @@
           (Page::kMaxRegularHeapObjectSize - FixedArray::kHeaderSize) >>
           ElementsKindToShiftSize(new_kind)));
 
-  HValue* new_elements = BuildAllocateElementsAndInitializeElementsHeader(
-      new_kind, new_capacity);
+  HValue* new_elements =
+      BuildAllocateAndInitializeArray(new_kind, new_capacity);
 
   BuildCopyElements(elements, kind, new_elements,
                     new_kind, length, new_capacity);
@@ -2789,12 +2769,6 @@
     }
   }
 
-  // Since we're about to store a hole value, the store instruction below must
-  // assume an elements kind that supports heap object values.
-  if (IsFastSmiOrObjectElementsKind(elements_kind)) {
-    elements_kind = FAST_HOLEY_ELEMENTS;
-  }
-
   if (initial_capacity >= 0) {
     for (int i = 0; i < initial_capacity; i++) {
       HInstruction* key = Add<HConstant>(i);
@@ -2832,10 +2806,39 @@
       ? Add<HConstant>(factory->the_hole_value())
       : Add<HConstant>(nan_double);
 
+  // Since we're about to store a hole value, the store instruction below must
+  // assume an elements kind that supports heap object values.
+  if (IsFastSmiOrObjectElementsKind(elements_kind)) {
+    elements_kind = FAST_HOLEY_ELEMENTS;
+  }
+
   BuildFillElementsWithValue(elements, elements_kind, from, to, hole);
 }
 
 
+void HGraphBuilder::BuildCopyProperties(HValue* from_properties,
+                                        HValue* to_properties, HValue* length,
+                                        HValue* capacity) {
+  ElementsKind kind = FAST_ELEMENTS;
+
+  BuildFillElementsWithValue(to_properties, kind, length, capacity,
+                             graph()->GetConstantUndefined());
+
+  LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement);
+
+  HValue* key = builder.BeginBody(length, graph()->GetConstant0(), Token::GT);
+
+  key = AddUncasted<HSub>(key, graph()->GetConstant1());
+  key->ClearFlag(HValue::kCanOverflow);
+
+  HValue* element = Add<HLoadKeyed>(from_properties, key, nullptr, kind);
+
+  Add<HStoreKeyed>(to_properties, key, element, kind);
+
+  builder.EndBody();
+}
+
+
 void HGraphBuilder::BuildCopyElements(HValue* from_elements,
                                       ElementsKind from_elements_kind,
                                       HValue* to_elements,
@@ -2868,8 +2871,7 @@
     for (int i = 0; i < constant_capacity; i++) {
       HValue* key_constant = Add<HConstant>(i);
       HInstruction* value = Add<HLoadKeyed>(from_elements, key_constant,
-                                            static_cast<HValue*>(NULL),
-                                            from_elements_kind);
+                                            nullptr, from_elements_kind);
       Add<HStoreKeyed>(to_elements, key_constant, value, to_elements_kind);
     }
   } else {
@@ -2879,10 +2881,6 @@
                                 length, NULL);
     }
 
-    if (capacity == NULL) {
-      capacity = AddLoadFixedArrayLength(to_elements);
-    }
-
     LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement);
 
     HValue* key = builder.BeginBody(length, graph()->GetConstant0(),
@@ -2891,10 +2889,8 @@
     key = AddUncasted<HSub>(key, graph()->GetConstant1());
     key->ClearFlag(HValue::kCanOverflow);
 
-    HValue* element = Add<HLoadKeyed>(from_elements, key,
-                                      static_cast<HValue*>(NULL),
-                                      from_elements_kind,
-                                      ALLOW_RETURN_HOLE);
+    HValue* element = Add<HLoadKeyed>(from_elements, key, nullptr,
+                                      from_elements_kind, ALLOW_RETURN_HOLE);
 
     ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) &&
                          IsFastSmiElementsKind(to_elements_kind))
@@ -3005,9 +3001,9 @@
   // Copy the elements array header.
   for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) {
     HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i);
-    Add<HStoreNamedField>(elements, access,
-        Add<HLoadNamedField>(boilerplate_elements,
-                             static_cast<HValue*>(NULL), access));
+    Add<HStoreNamedField>(
+        elements, access,
+        Add<HLoadNamedField>(boilerplate_elements, nullptr, access));
   }
 
   // And the result of the length
@@ -3020,10 +3016,9 @@
 }
 
 
-void HGraphBuilder::BuildCompareNil(
-    HValue* value,
-    Type* type,
-    HIfContinuation* continuation) {
+void HGraphBuilder::BuildCompareNil(HValue* value, Type* type,
+                                    HIfContinuation* continuation,
+                                    MapEmbedding map_embedding) {
   IfBuilder if_nil(this);
   bool some_case_handled = false;
   bool some_case_missing = false;
@@ -3062,7 +3057,21 @@
       // the monomorphic map when the code is used as a template to generate a
       // new IC. For optimized functions, there is no sentinel map, the map
       // emitted below is the actual monomorphic map.
-      Add<HCheckMaps>(value, type->Classes().Current());
+      if (map_embedding == kEmbedMapsViaWeakCells) {
+        HValue* cell =
+            Add<HConstant>(Map::WeakCellForMap(type->Classes().Current()));
+        HValue* expected_map = Add<HLoadNamedField>(
+            cell, nullptr, HObjectAccess::ForWeakCellValue());
+        HValue* map =
+            Add<HLoadNamedField>(value, nullptr, HObjectAccess::ForMap());
+        IfBuilder map_check(this);
+        map_check.IfNot<HCompareObjectEqAndBranch>(expected_map, map);
+        map_check.ThenDeopt("Unknown map");
+        map_check.End();
+      } else {
+        DCHECK(map_embedding == kEmbedMapsDirectly);
+        Add<HCheckMaps>(value, type->Classes().Current());
+      }
     } else {
       if_nil.Deopt("Too many undetectable types");
     }
@@ -3086,10 +3095,10 @@
       HObjectAccess::ForAllocationMementoSite(),
       allocation_site);
   if (FLAG_allocation_site_pretenuring) {
-    HValue* memento_create_count = Add<HLoadNamedField>(
-        allocation_site, static_cast<HValue*>(NULL),
-        HObjectAccess::ForAllocationSiteOffset(
-            AllocationSite::kPretenureCreateCountOffset));
+    HValue* memento_create_count =
+        Add<HLoadNamedField>(allocation_site, nullptr,
+                             HObjectAccess::ForAllocationSiteOffset(
+                                 AllocationSite::kPretenureCreateCountOffset));
     memento_create_count = AddUncasted<HAdd>(
         memento_create_count, graph()->GetConstant1());
     // This smi value is reset to zero after every gc, overflow isn't a problem
@@ -3103,29 +3112,36 @@
 
 
 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) {
-  // Get the global context, then the native context
-  HInstruction* context =
-      Add<HLoadNamedField>(closure, static_cast<HValue*>(NULL),
-                           HObjectAccess::ForFunctionContextPointer());
+  // Get the global object, then the native context
+  HInstruction* context = Add<HLoadNamedField>(
+      closure, nullptr, HObjectAccess::ForFunctionContextPointer());
   HInstruction* global_object = Add<HLoadNamedField>(
-      context, static_cast<HValue*>(NULL),
+      context, nullptr,
       HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
   HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(
       GlobalObject::kNativeContextOffset);
-  return Add<HLoadNamedField>(
-      global_object, static_cast<HValue*>(NULL), access);
+  return Add<HLoadNamedField>(global_object, nullptr, access);
+}
+
+
+HInstruction* HGraphBuilder::BuildGetScriptContext(int context_index) {
+  HValue* native_context = BuildGetNativeContext();
+  HValue* script_context_table = Add<HLoadNamedField>(
+      native_context, nullptr,
+      HObjectAccess::ForContextSlot(Context::SCRIPT_CONTEXT_TABLE_INDEX));
+  return Add<HLoadNamedField>(script_context_table, nullptr,
+                              HObjectAccess::ForScriptContext(context_index));
 }
 
 
 HInstruction* HGraphBuilder::BuildGetNativeContext() {
-  // Get the global context, then the native context
+  // Get the global object, then the native context
   HValue* global_object = Add<HLoadNamedField>(
-      context(), static_cast<HValue*>(NULL),
+      context(), nullptr,
       HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
-  return Add<HLoadNamedField>(
-      global_object, static_cast<HValue*>(NULL),
-      HObjectAccess::ForObservableJSObjectOffset(
-          GlobalObject::kNativeContextOffset));
+  return Add<HLoadNamedField>(global_object, nullptr,
+                              HObjectAccess::ForObservableJSObjectOffset(
+                                  GlobalObject::kNativeContextOffset));
 }
 
 
@@ -3133,8 +3149,7 @@
   HInstruction* native_context = BuildGetNativeContext();
   HInstruction* index =
       Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX));
-  return Add<HLoadKeyed>(
-      native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
+  return Add<HLoadKeyed>(native_context, index, nullptr, FAST_ELEMENTS);
 }
 
 
@@ -3179,8 +3194,8 @@
     // No need for a context lookup if the kind_ matches the initial
     // map, because we can just load the map in that case.
     HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
-    return builder()->Add<HLoadNamedField>(
-        constructor_function_, static_cast<HValue*>(NULL), access);
+    return builder()->Add<HLoadNamedField>(constructor_function_, nullptr,
+                                           access);
   }
 
   // TODO(mvstanton): we should always have a constructor function if we
@@ -3192,21 +3207,21 @@
   HInstruction* index = builder()->Add<HConstant>(
       static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX));
 
-  HInstruction* map_array = builder()->Add<HLoadKeyed>(
-      native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
+  HInstruction* map_array =
+      builder()->Add<HLoadKeyed>(native_context, index, nullptr, FAST_ELEMENTS);
 
   HInstruction* kind_index = builder()->Add<HConstant>(kind_);
 
-  return builder()->Add<HLoadKeyed>(
-      map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS);
+  return builder()->Add<HLoadKeyed>(map_array, kind_index, nullptr,
+                                    FAST_ELEMENTS);
 }
 
 
 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
   // Find the map near the constructor function
   HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
-  return builder()->Add<HLoadNamedField>(
-      constructor_function_, static_cast<HValue*>(NULL), access);
+  return builder()->Add<HLoadNamedField>(constructor_function_, nullptr,
+                                         access);
 }
 
 
@@ -3305,16 +3320,14 @@
 
 HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) {
   HValue* global_object = Add<HLoadNamedField>(
-      context(), static_cast<HValue*>(NULL),
+      context(), nullptr,
       HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
   HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset(
       GlobalObject::kBuiltinsOffset);
-  HValue* builtins = Add<HLoadNamedField>(
-      global_object, static_cast<HValue*>(NULL), access);
+  HValue* builtins = Add<HLoadNamedField>(global_object, nullptr, access);
   HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset(
           JSBuiltinsObject::OffsetOfFunctionWithId(builtin));
-  return Add<HLoadNamedField>(
-      builtins, static_cast<HValue*>(NULL), function_access);
+  return Add<HLoadNamedField>(builtins, nullptr, function_access);
 }
 
 
@@ -3330,7 +3343,7 @@
   // This is not initialized in the initializer list because the
   // constructor for the initial state relies on function_state_ == NULL
   // to know it's the initial state.
-  function_state_= &initial_function_state_;
+  function_state_ = &initial_function_state_;
   InitializeAstVisitor(info->zone());
   if (FLAG_hydrogen_track_positions) {
     SetSourcePosition(info->shared_info()->start_position());
@@ -3408,7 +3421,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const HBasicBlock& b) {
+std::ostream& operator<<(std::ostream& os, const HBasicBlock& b) {
   return os << "B" << b.block_id();
 }
 
@@ -3431,8 +3444,9 @@
       maximum_environment_size_(0),
       no_side_effects_scope_count_(0),
       disallow_adding_new_values_(false),
-      next_inline_id_(0),
-      inlined_functions_(5, info->zone()) {
+      inlined_functions_(FLAG_hydrogen_track_positions ? 5 : 0, info->zone()),
+      inlining_id_to_function_id_(FLAG_hydrogen_track_positions ? 5 : 0,
+                                  info->zone()) {
   if (info->IsStub()) {
     CallInterfaceDescriptor descriptor =
         info->code_stub()->GetCallInterfaceDescriptor();
@@ -3492,9 +3506,7 @@
         os << "--- FUNCTION SOURCE (" << shared->DebugName()->ToCString().get()
            << ") id{" << info()->optimization_id() << "," << id << "} ---\n";
         {
-          ConsStringIteratorOp op;
           StringCharacterStream stream(String::cast(script->source()),
-                                       &op,
                                        shared->start_position());
           // fun->end_position() points to the last character in the stream. We
           // need to compensate by adding one to calculate the length.
@@ -3512,14 +3524,15 @@
     }
   }
 
-  int inline_id = next_inline_id_++;
+  int inline_id = inlining_id_to_function_id_.length();
+  inlining_id_to_function_id_.Add(id, zone());
 
   if (inline_id != 0) {
     CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
     OFStream os(tracing_scope.file());
     os << "INLINE (" << shared->DebugName()->ToCString().get() << ") id{"
        << info()->optimization_id() << "," << id << "} AS " << inline_id
-       << " AT " << position << endl;
+       << " AT " << position << std::endl;
   }
 
   return inline_id;
@@ -3531,8 +3544,8 @@
     return pos.raw();
   }
 
-  return inlined_functions_[pos.inlining_id()].start_position() +
-      pos.position();
+  const int id = inlining_id_to_function_id_[pos.inlining_id()];
+  return inlined_functions_[id].start_position() + pos.position();
 }
 
 
@@ -4024,8 +4037,12 @@
 void ValueContext::ReturnValue(HValue* value) {
   // The value is tracked in the bailout environment, and communicated
   // through the environment as the result of the expression.
-  if (!arguments_allowed() && value->CheckFlag(HValue::kIsArguments)) {
-    owner()->Bailout(kBadValueContextForArgumentsValue);
+  if (value->CheckFlag(HValue::kIsArguments)) {
+    if (flag_ == ARGUMENTS_FAKED) {
+      value = owner()->graph()->GetConstantUndefined();
+    } else if (!arguments_allowed()) {
+      owner()->Bailout(kBadValueContextForArgumentsValue);
+    }
   }
   owner()->Push(value);
 }
@@ -4251,20 +4268,16 @@
 }
 
 
+void HOptimizedGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs,
+                                              ArgumentsAllowedFlag flag) {
+  for (int i = 0; i < exprs->length(); ++i) {
+    CHECK_ALIVE(VisitForValue(exprs->at(i), flag));
+  }
+}
+
+
 bool HOptimizedGraphBuilder::BuildGraph() {
-  if (current_info()->function()->is_generator()) {
-    Bailout(kFunctionIsAGenerator);
-    return false;
-  }
   Scope* scope = current_info()->scope();
-  if (scope->HasIllegalRedeclaration()) {
-    Bailout(kFunctionWithIllegalRedeclaration);
-    return false;
-  }
-  if (scope->calls_eval()) {
-    Bailout(kFunctionCallsEval);
-    return false;
-  }
   SetUpScope(scope);
 
   // Add an edge to the body entry.  This is warty: the graph's start
@@ -4384,7 +4397,7 @@
   // Must be performed before canonicalization to ensure that Canonicalize
   // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with
   // zero.
-  if (FLAG_opt_safe_uint32_operations) Run<HUint32AnalysisPhase>();
+  Run<HUint32AnalysisPhase>();
 
   if (FLAG_use_canonicalizing) Run<HCanonicalizePhase>();
 
@@ -4500,10 +4513,6 @@
   // Handle the arguments and arguments shadow variables specially (they do
   // not have declarations).
   if (scope->arguments() != NULL) {
-    if (!scope->arguments()->IsStackAllocated()) {
-      return Bailout(kContextAllocatedArguments);
-    }
-
     environment()->Bind(scope->arguments(),
                         graph()->GetArgumentsObject());
   }
@@ -4539,7 +4548,7 @@
       Scope* declaration_scope = scope->DeclarationScope();
       HInstruction* function;
       HValue* outer_context = environment()->context();
-      if (declaration_scope->is_global_scope() ||
+      if (declaration_scope->is_script_scope() ||
           declaration_scope->is_eval_scope()) {
         function = new(zone()) HLoadContextSlot(
             outer_context, Context::CLOSURE_INDEX, HLoadContextSlot::kNoCheck);
@@ -4551,11 +4560,11 @@
       HInstruction* inner_context = Add<HAllocateBlockContext>(
           outer_context, function, scope->GetScopeInfo());
       HInstruction* instr = Add<HStoreFrameContext>(inner_context);
+      set_scope(scope);
+      environment()->BindContext(inner_context);
       if (instr->HasObservableSideEffects()) {
         AddSimulate(stmt->EntryId(), REMOVABLE_SIMULATE);
       }
-      set_scope(scope);
-      environment()->BindContext(inner_context);
       VisitDeclarations(scope->declarations());
       AddSimulate(stmt->DeclsId(), REMOVABLE_SIMULATE);
     }
@@ -4565,14 +4574,14 @@
   if (scope != NULL && current_block() != NULL) {
     HValue* inner_context = environment()->context();
     HValue* outer_context = Add<HLoadNamedField>(
-        inner_context, static_cast<HValue*>(NULL),
+        inner_context, nullptr,
         HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
 
     HInstruction* instr = Add<HStoreFrameContext>(outer_context);
+    environment()->BindContext(outer_context);
     if (instr->HasObservableSideEffects()) {
       AddSimulate(stmt->ExitId(), REMOVABLE_SIMULATE);
     }
-    environment()->BindContext(outer_context);
   }
   HBasicBlock* break_block = break_info.break_block();
   if (break_block != NULL) {
@@ -4696,7 +4705,7 @@
   if (context_pop_count > 0) {
     while (context_pop_count-- > 0) {
       HInstruction* context_instruction = Add<HLoadNamedField>(
-          context, static_cast<HValue*>(NULL),
+          context, nullptr,
           HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
       context = context_instruction;
     }
@@ -4728,7 +4737,7 @@
   if (context_pop_count > 0) {
     while (context_pop_count-- > 0) {
       HInstruction* context_instruction = Add<HLoadNamedField>(
-          context, static_cast<HValue*>(NULL),
+          context, nullptr,
           HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
       context = context_instruction;
     }
@@ -5328,7 +5337,7 @@
   int length = scope()->ContextChainLength(var->scope());
   while (length-- > 0) {
     context = Add<HLoadNamedField>(
-        context, static_cast<HValue*>(NULL),
+        context, nullptr,
         HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX));
   }
   return context;
@@ -5360,6 +5369,22 @@
       }
 
       Handle<GlobalObject> global(current_info()->global_object());
+
+      if (FLAG_harmony_scoping) {
+        Handle<ScriptContextTable> script_contexts(
+            global->native_context()->script_context_table());
+        ScriptContextTable::LookupResult lookup;
+        if (ScriptContextTable::Lookup(script_contexts, variable->name(),
+                                       &lookup)) {
+          Handle<Context> script_context = ScriptContextTable::GetContext(
+              script_contexts, lookup.context_index);
+          HInstruction* result = New<HLoadNamedField>(
+              Add<HConstant>(script_context), nullptr,
+              HObjectAccess::ForContextSlot(lookup.slot_index));
+          return ast_context()->ReturnInstruction(result, expr->id());
+        }
+      }
+
       LookupIterator it(global, variable->name(),
                         LookupIterator::OWN_SKIP_INTERCEPTOR);
       GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD);
@@ -5382,7 +5407,7 @@
         }
       } else {
         HValue* global_object = Add<HLoadNamedField>(
-            context(), static_cast<HValue*>(NULL),
+            context(), nullptr,
             HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
         HLoadGlobalGeneric* instr =
             New<HLoadGlobalGeneric>(global_object,
@@ -5487,7 +5512,7 @@
   Handle<FixedArrayBase> elements(boilerplate->elements());
   if (elements->length() > 0 &&
       elements->map() != isolate->heap()->fixed_cow_array_map()) {
-    if (boilerplate->HasFastObjectElements()) {
+    if (boilerplate->HasFastSmiOrObjectElements()) {
       Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements);
       int length = elements->length();
       for (int i = 0; i < length; i++) {
@@ -5517,9 +5542,11 @@
     for (int i = 0; i < limit; i++) {
       PropertyDetails details = descriptors->GetDetails(i);
       if (details.type() != FIELD) continue;
-      int index = descriptors->GetFieldIndex(i);
       if ((*max_properties)-- == 0) return false;
-      Handle<Object> value(boilerplate->InObjectPropertyAt(index), isolate);
+      FieldIndex field_index = FieldIndex::ForDescriptor(boilerplate->map(), i);
+      if (boilerplate->IsUnboxedDoubleField(field_index)) continue;
+      Handle<Object> value(boilerplate->RawFastPropertyAt(field_index),
+                           isolate);
       if (value->IsJSObject()) {
         Handle<JSObject> value_object = Handle<JSObject>::cast(value);
         if (!IsFastLiteral(value_object,
@@ -5603,10 +5630,23 @@
         DCHECK(!CompileTimeValue::IsCompileTimeValue(value));
         // Fall through.
       case ObjectLiteral::Property::COMPUTED:
+        // It is safe to use [[Put]] here because the boilerplate already
+        // contains computed properties with an uninitialized value.
         if (key->value()->IsInternalizedString()) {
           if (property->emit_store()) {
             CHECK_ALIVE(VisitForValue(value));
             HValue* value = Pop();
+
+            // Add [[HomeObject]] to function literals.
+            if (FunctionLiteral::NeedsHomeObject(property->value())) {
+              Handle<Symbol> sym = isolate()->factory()->home_object_symbol();
+              HInstruction* store_home = BuildKeyedGeneric(
+                  STORE, NULL, value, Add<HConstant>(sym), literal);
+              AddInstruction(store_home);
+              DCHECK(store_home->HasObservableSideEffects());
+              Add<HSimulate>(property->value()->id(), REMOVABLE_SIMULATE);
+            }
+
             Handle<Map> map = property->GetReceiverType();
             Handle<String> name = property->key()->AsPropertyName();
             HInstruction* store;
@@ -5628,9 +5668,8 @@
               }
             }
             AddInstruction(store);
-            if (store->HasObservableSideEffects()) {
-              Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
-            }
+            DCHECK(store->HasObservableSideEffects());
+            Add<HSimulate>(key->id(), REMOVABLE_SIMULATE);
           } else {
             CHECK_ALIVE(VisitForEffect(value));
           }
@@ -5734,17 +5773,13 @@
                         Add<HConstant>(constants),
                         Add<HConstant>(flags));
 
-    // TODO(mvstanton): Consider a flag to turn off creation of any
-    // AllocationMementos for this call: we are in crankshaft and should have
-    // learned enough about transition behavior to stop emitting mementos.
     Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral;
     literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
                                 Runtime::FunctionForId(function_id),
                                 4);
 
-    // De-opt if elements kind changed from boilerplate_elements_kind.
-    Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate());
-    literal = Add<HCheckMaps>(literal, map);
+    // Register to deopt if the boilerplate ElementsKind changes.
+    AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info());
   }
 
   // The array is expected in the bailout environment during computation
@@ -5820,10 +5855,11 @@
   }
 
   HObjectAccess access = info->access();
-  if (access.representation().IsDouble()) {
+  if (access.representation().IsDouble() &&
+      (!FLAG_unbox_double_fields || !access.IsInobject())) {
     // Load the heap number.
     checked_object = Add<HLoadNamedField>(
-        checked_object, static_cast<HValue*>(NULL),
+        checked_object, nullptr,
         access.WithRepresentation(Representation::Tagged()));
     // Load the double value from it.
     access = HObjectAccess::ForHeapNumberValue();
@@ -5852,7 +5888,8 @@
   HObjectAccess field_access = info->access();
 
   HStoreNamedField *instr;
-  if (field_access.representation().IsDouble()) {
+  if (field_access.representation().IsDouble() &&
+      (!FLAG_unbox_double_fields || !field_access.IsInobject())) {
     HObjectAccess heap_number_access =
         field_access.WithRepresentation(Representation::Tagged());
     if (transition_to_field) {
@@ -5874,8 +5911,8 @@
                                     heap_number);
     } else {
       // Already holds a HeapNumber; load the box and write its value field.
-      HInstruction* heap_number = Add<HLoadNamedField>(
-          checked_object, static_cast<HValue*>(NULL), heap_number_access);
+      HInstruction* heap_number =
+          Add<HLoadNamedField>(checked_object, nullptr, heap_number_access);
       instr = New<HStoreNamedField>(heap_number,
                                     HObjectAccess::ForHeapNumberValue(),
                                     value, STORE_TO_INITIALIZED_ENTRY);
@@ -6096,7 +6133,7 @@
 
   if (IsAccessor()) return true;
   Handle<Map> map = this->map();
-  map->LookupTransition(NULL, *name_, &lookup_);
+  map->LookupTransition(NULL, *name_, NONE, &lookup_);
   if (lookup_.IsTransitionToField() && map->unused_property_fields() > 0) {
     // Construct the object field access.
     int descriptor = transition()->LastAdded();
@@ -6289,7 +6326,7 @@
   HControlInstruction* smi_check = NULL;
   handled_string = false;
 
-  for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
+  for (i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) {
     PropertyAccessInfo info(this, access_type, ToType(types->at(i)), name);
     if (info.type()->Is(Type::String())) {
       if (handled_string) continue;
@@ -6367,7 +6404,7 @@
   // 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) {
-    FinishExitWithHardDeoptimization("Uknown map in polymorphic access");
+    FinishExitWithHardDeoptimization("Unknown map in polymorphic access");
   } else {
     HInstruction* instr = BuildNamedGeneric(access_type, expr, object, name,
                                             value);
@@ -6484,6 +6521,27 @@
     HValue* value,
     BailoutId ast_id) {
   Handle<GlobalObject> global(current_info()->global_object());
+
+  if (FLAG_harmony_scoping) {
+    Handle<ScriptContextTable> script_contexts(
+        global->native_context()->script_context_table());
+    ScriptContextTable::LookupResult lookup;
+    if (ScriptContextTable::Lookup(script_contexts, var->name(), &lookup)) {
+      if (lookup.mode == CONST) {
+        return Bailout(kNonInitializerAssignmentToConst);
+      }
+      Handle<Context> script_context =
+          ScriptContextTable::GetContext(script_contexts, lookup.context_index);
+      HStoreNamedField* instr = Add<HStoreNamedField>(
+          Add<HConstant>(script_context),
+          HObjectAccess::ForContextSlot(lookup.slot_index), value);
+      USE(instr);
+      DCHECK(instr->HasObservableSideEffects());
+      Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
+      return;
+    }
+  }
+
   LookupIterator it(global, var->name(), LookupIterator::OWN_SKIP_INTERCEPTOR);
   GlobalPropertyAccess type = LookupGlobalProperty(var, &it, STORE);
   if (type == kUseCell) {
@@ -6518,7 +6576,7 @@
     }
   } else {
     HValue* global_object = Add<HLoadNamedField>(
-        context(), static_cast<HValue*>(NULL),
+        context(), nullptr,
         HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
     HStoreNamedGeneric* instr =
         Add<HStoreNamedGeneric>(global_object, var->name(),
@@ -6560,6 +6618,9 @@
         if (var->mode() == CONST_LEGACY)  {
           return Bailout(kUnsupportedConstCompoundAssignment);
         }
+        if (var->mode() == CONST) {
+          return Bailout(kNonInitializerAssignmentToConst);
+        }
         BindIfLive(var, Top());
         break;
 
@@ -6586,9 +6647,7 @@
             mode = HStoreContextSlot::kCheckDeoptimize;
             break;
           case CONST:
-            // This case is checked statically so no need to
-            // perform checks here
-            UNREACHABLE();
+            return Bailout(kNonInitializerAssignmentToConst);
           case CONST_LEGACY:
             return ast_context()->ReturnValue(Pop());
           default:
@@ -6801,9 +6860,8 @@
     }
   }
   return Add<HLoadNamedField>(
-      Add<HLoadNamedField>(string, static_cast<HValue*>(NULL),
-                           HObjectAccess::ForMap()),
-      static_cast<HValue*>(NULL), HObjectAccess::ForMapInstanceType());
+      Add<HLoadNamedField>(string, nullptr, HObjectAccess::ForMap()), nullptr,
+      HObjectAccess::ForMapInstanceType());
 }
 
 
@@ -6814,7 +6872,7 @@
       return Add<HConstant>(c_string->StringValue()->length());
     }
   }
-  return Add<HLoadNamedField>(string, static_cast<HValue*>(NULL),
+  return Add<HLoadNamedField>(string, nullptr,
                               HObjectAccess::ForStringLength());
 }
 
@@ -6835,9 +6893,10 @@
     if (FLAG_vector_ics) {
       Handle<SharedFunctionInfo> current_shared =
           function_state()->compilation_info()->shared_info();
-      result->SetVectorAndSlot(
-          handle(current_shared->feedback_vector(), isolate()),
-          expr->AsProperty()->PropertyFeedbackSlot());
+      Handle<TypeFeedbackVector> vector =
+          handle(current_shared->feedback_vector(), isolate());
+      FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot();
+      result->SetVectorAndSlot(vector, slot);
     }
     return result;
   } else {
@@ -6858,9 +6917,10 @@
     if (FLAG_vector_ics) {
       Handle<SharedFunctionInfo> current_shared =
           function_state()->compilation_info()->shared_info();
-      result->SetVectorAndSlot(
-          handle(current_shared->feedback_vector(), isolate()),
-          expr->AsProperty()->PropertyFeedbackSlot());
+      Handle<TypeFeedbackVector> vector =
+          handle(current_shared->feedback_vector(), isolate());
+      FeedbackVectorICSlot slot = expr->AsProperty()->PropertyFeedbackSlot();
+      result->SetVectorAndSlot(vector, slot);
     }
     return result;
   } else {
@@ -6923,6 +6983,12 @@
 }
 
 
+static bool CanInlineElementAccess(Handle<Map> map) {
+  return map->IsJSObjectMap() && !map->has_slow_elements_kind() &&
+         !map->has_indexed_interceptor();
+}
+
+
 HInstruction* HOptimizedGraphBuilder::TryBuildConsolidatedElementLoad(
     HValue* object,
     HValue* key,
@@ -6940,7 +7006,7 @@
   Handle<Map> most_general_consolidated_map;
   for (int i = 0; i < maps->length(); ++i) {
     Handle<Map> map = maps->at(i);
-    if (!map->IsJSObjectMap()) return NULL;
+    if (!CanInlineElementAccess(map)) return NULL;
     // Don't allow mixing of JSArrays with JSObjects.
     if (map->instance_type() == JS_ARRAY_TYPE) {
       if (has_non_js_array_access) return NULL;
@@ -7016,8 +7082,11 @@
   MapHandleList possible_transitioned_maps(maps->length());
   for (int i = 0; i < maps->length(); ++i) {
     Handle<Map> map = maps->at(i);
+    // Loads from strings or loads with a mix of string and non-string maps
+    // shouldn't be handled polymorphically.
+    DCHECK(access_type != LOAD || !map->IsStringMap());
     ElementsKind elements_kind = map->elements_kind();
-    if (IsFastElementsKind(elements_kind) &&
+    if (CanInlineElementAccess(map) && IsFastElementsKind(elements_kind) &&
         elements_kind != GetInitialFastElementsKind()) {
       possible_transitioned_maps.Add(map);
     }
@@ -7058,8 +7127,7 @@
   if (untransitionable_maps.length() == 1) {
     Handle<Map> untransitionable_map = untransitionable_maps[0];
     HInstruction* instr = NULL;
-    if (untransitionable_map->has_slow_elements_kind() ||
-        !untransitionable_map->IsJSObjectMap()) {
+    if (!CanInlineElementAccess(untransitionable_map)) {
       instr = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key,
                                                val));
     } else {
@@ -7075,7 +7143,6 @@
 
   for (int i = 0; i < untransitionable_maps.length(); ++i) {
     Handle<Map> map = untransitionable_maps[i];
-    if (!map->IsJSObjectMap()) continue;
     ElementsKind elements_kind = map->elements_kind();
     HBasicBlock* this_map = graph()->CreateBasicBlock();
     HBasicBlock* other_map = graph()->CreateBasicBlock();
@@ -7085,7 +7152,7 @@
 
     set_current_block(this_map);
     HInstruction* access = NULL;
-    if (IsDictionaryElementsKind(elements_kind)) {
+    if (!CanInlineElementAccess(map)) {
       access = AddInstruction(BuildKeyedGeneric(access_type, expr, object, key,
                                                 val));
     } else {
@@ -7129,7 +7196,9 @@
     HValue* obj, HValue* key, HValue* val, Expression* expr, BailoutId ast_id,
     BailoutId return_id, PropertyAccessType access_type,
     bool* has_side_effects) {
-  if (key->ActualValue()->IsConstant()) {
+  // TODO(mvstanton): This optimization causes trouble for vector-based
+  // KeyedLoadICs, turn it off for now.
+  if (!FLAG_vector_ics && key->ActualValue()->IsConstant()) {
     Handle<Object> constant =
         HConstant::cast(key->ActualValue())->handle(isolate());
     uint32_t array_index;
@@ -7159,8 +7228,14 @@
   bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone());
 
   bool force_generic = false;
-  if (access_type == STORE &&
-      (monomorphic || (types != NULL && !types->is_empty()))) {
+  if (expr->GetKeyType() == PROPERTY) {
+    // Non-Generic accesses assume that elements are being accessed, and will
+    // deopt for non-index keys, which the IC knows will occur.
+    // TODO(jkummerow): Consider adding proper support for property accesses.
+    force_generic = true;
+    monomorphic = false;
+  } else if (access_type == STORE &&
+             (monomorphic || (types != NULL && !types->is_empty()))) {
     // Stores can't be mono/polymorphic if their prototype chain has dictionary
     // elements. However a receiver map that has dictionary elements itself
     // should be left to normal mono/poly behavior (the other maps may benefit
@@ -7173,11 +7248,24 @@
         break;
       }
     }
+  } else if (access_type == LOAD && !monomorphic &&
+             (types != NULL && !types->is_empty())) {
+    // Polymorphic loads have to go generic if any of the maps are strings.
+    // If some, but not all of the maps are strings, we should go generic
+    // because polymorphic access wants to key on ElementsKind and isn't
+    // compatible with strings.
+    for (int i = 0; i < types->length(); i++) {
+      Handle<Map> current_map = types->at(i);
+      if (current_map->IsStringMap()) {
+        force_generic = true;
+        break;
+      }
+    }
   }
 
   if (monomorphic) {
     Handle<Map> map = types->first();
-    if (map->has_slow_elements_kind() || !map->IsJSObjectMap()) {
+    if (!CanInlineElementAccess(map)) {
       instr = AddInstruction(BuildKeyedGeneric(access_type, expr, obj, key,
                                                val));
     } else {
@@ -7475,8 +7563,7 @@
   } else {
     HValue* param_count_value = Add<HConstant>(formal_parameter_count);
     HValue* context = Add<HLoadNamedField>(
-        target, static_cast<HValue*>(NULL),
-        HObjectAccess::ForFunctionContextPointer());
+        target, nullptr, HObjectAccess::ForFunctionContextPointer());
     return NewArgumentAdaptorCall(target, context,
         argument_count, param_count_value);
   }
@@ -7743,7 +7830,7 @@
     TraceInline(target, caller, "target not inlineable");
     return kNotInlinable;
   }
-  if (target_shared->DisableOptimizationReason() != kNoReason) {
+  if (target_shared->disable_optimization_reason() != kNoReason) {
     TraceInline(target, caller, "target contains unsupported syntax [early]");
     return kNotInlinable;
   }
@@ -7807,7 +7894,7 @@
   // step, but don't transfer ownership to target_info.
   target_info.SetAstValueFactory(top_info()->ast_value_factory(), false);
   Handle<SharedFunctionInfo> target_shared(target->shared());
-  if (!Parser::Parse(&target_info) || !Scope::Analyze(&target_info)) {
+  if (!Compiler::ParseAndAnalyze(&target_info)) {
     if (target_info.isolate()->has_pending_exception()) {
       // Parse or scope error, never optimize this function.
       SetStackOverflow();
@@ -7843,13 +7930,6 @@
       TraceInline(target, caller, "target uses arguments object");
       return false;
     }
-
-    if (!function->scope()->arguments()->IsStackAllocated()) {
-      TraceInline(target,
-                  caller,
-                  "target uses non-stackallocated arguments object");
-      return false;
-    }
   }
 
   // All declarations must be inlineable.
@@ -8085,9 +8165,9 @@
 }
 
 
-bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function,
-                                            Call* expr,
-                                            int arguments_count) {
+bool HOptimizedGraphBuilder::TryInlineIndirectCall(Handle<JSFunction> function,
+                                                   Call* expr,
+                                                   int arguments_count) {
   return TryInline(function,
                    arguments_count,
                    NULL,
@@ -8139,13 +8219,22 @@
 
 
 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall(
-    Call* expr,
-    HValue* receiver,
-    Handle<Map> receiver_map) {
+    Call* expr, Handle<JSFunction> function, Handle<Map> receiver_map,
+    int args_count_no_receiver) {
+  if (!function->shared()->HasBuiltinFunctionId()) return false;
+  BuiltinFunctionId id = function->shared()->builtin_function_id();
+  int argument_count = args_count_no_receiver + 1;  // Plus receiver.
+
+  if (receiver_map.is_null()) {
+    HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver);
+    if (receiver->IsConstant() &&
+        HConstant::cast(receiver)->handle(isolate())->IsHeapObject()) {
+      receiver_map =
+          handle(Handle<HeapObject>::cast(
+                     HConstant::cast(receiver)->handle(isolate()))->map());
+    }
+  }
   // Try to inline calls like Math.* as operations in the calling function.
-  if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
-  BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
-  int argument_count = expr->arguments()->length() + 1;  // Plus receiver.
   switch (id) {
     case kStringCharCodeAt:
     case kStringCharAt:
@@ -8250,19 +8339,20 @@
       if (receiver_map.is_null()) return false;
       if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
       ElementsKind elements_kind = receiver_map->elements_kind();
+      if (JSArray::IsReadOnlyLengthDescriptor(receiver_map)) return false;
       if (!IsFastElementsKind(elements_kind)) return false;
       if (receiver_map->is_observed()) return false;
       if (!receiver_map->is_extensible()) return false;
 
-      Drop(expr->arguments()->length());
+      Drop(args_count_no_receiver);
       HValue* result;
       HValue* reduced_length;
       HValue* receiver = Pop();
 
       HValue* checked_object = AddCheckMap(receiver, receiver_map);
-      HValue* length = Add<HLoadNamedField>(
-          checked_object, static_cast<HValue*>(NULL),
-          HObjectAccess::ForArrayLength(elements_kind));
+      HValue* length =
+          Add<HLoadNamedField>(checked_object, nullptr,
+                               HObjectAccess::ForArrayLength(elements_kind));
 
       Drop(1);  // Function.
 
@@ -8330,7 +8420,7 @@
       Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
       BuildCheckPrototypeMaps(prototype, Handle<JSObject>());
 
-      const int argc = expr->arguments()->length();
+      const int argc = args_count_no_receiver;
       if (argc != 1) return false;
 
       HValue* value_to_push = Pop();
@@ -8343,8 +8433,8 @@
       {
         NoObservableSideEffectsScope scope(this);
 
-        length = Add<HLoadNamedField>(array, static_cast<HValue*>(NULL),
-          HObjectAccess::ForArrayLength(elements_kind));
+        length = Add<HLoadNamedField>(
+            array, nullptr, HObjectAccess::ForArrayLength(elements_kind));
 
         new_size = AddUncasted<HAdd>(length, graph()->GetConstant1());
 
@@ -8367,6 +8457,7 @@
       if (receiver_map.is_null()) return false;
       if (receiver_map->instance_type() != JS_ARRAY_TYPE) return false;
       ElementsKind kind = receiver_map->elements_kind();
+      if (JSArray::IsReadOnlyLengthDescriptor(receiver_map)) return false;
       if (!IsFastElementsKind(kind)) return false;
       if (receiver_map->is_observed()) return false;
       if (!receiver_map->is_extensible()) return false;
@@ -8387,7 +8478,7 @@
       // Threshold for fast inlined Array.shift().
       HConstant* inline_threshold = Add<HConstant>(static_cast<int32_t>(16));
 
-      Drop(expr->arguments()->length());
+      Drop(args_count_no_receiver);
       HValue* receiver = Pop();
       HValue* function = Pop();
       HValue* result;
@@ -8396,8 +8487,7 @@
         NoObservableSideEffectsScope scope(this);
 
         HValue* length = Add<HLoadNamedField>(
-            receiver, static_cast<HValue*>(NULL),
-            HObjectAccess::ForArrayLength(kind));
+            receiver, nullptr, HObjectAccess::ForArrayLength(kind));
 
         IfBuilder if_lengthiszero(this);
         HValue* lengthiszero = if_lengthiszero.If<HCompareNumericAndBranch>(
@@ -8439,10 +8529,12 @@
                   graph()->GetConstant0(), new_length, Token::LT);
               HValue* key = AddUncasted<HAdd>(new_key, graph()->GetConstant1());
               key->ClearFlag(HValue::kCanOverflow);
+              ElementsKind copy_kind =
+                  kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind;
               HValue* element = AddUncasted<HLoadKeyed>(
-                  elements, key, lengthiszero, kind, ALLOW_RETURN_HOLE);
-              HStoreKeyed* store = Add<HStoreKeyed>(
-                  elements, new_key, element, kind);
+                  elements, key, lengthiszero, copy_kind, ALLOW_RETURN_HOLE);
+              HStoreKeyed* store =
+                  Add<HStoreKeyed>(elements, new_key, element, copy_kind);
               store->SetFlag(HValue::kAllowUndefinedAsNaN);
             }
             loop.EndBody();
@@ -8693,7 +8785,47 @@
 }
 
 
-bool HOptimizedGraphBuilder::TryCallApply(Call* expr) {
+void HOptimizedGraphBuilder::HandleIndirectCall(Call* expr, HValue* function,
+                                                int arguments_count) {
+  Handle<JSFunction> known_function;
+  int args_count_no_receiver = arguments_count - 1;
+  if (function->IsConstant() &&
+      HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
+    HValue* receiver = environment()->ExpressionStackAt(args_count_no_receiver);
+    Handle<Map> receiver_map;
+    if (receiver->IsConstant() &&
+        HConstant::cast(receiver)->handle(isolate())->IsHeapObject()) {
+      receiver_map =
+          handle(Handle<HeapObject>::cast(
+                     HConstant::cast(receiver)->handle(isolate()))->map());
+    }
+
+    known_function =
+        Handle<JSFunction>::cast(HConstant::cast(function)->handle(isolate()));
+    if (TryInlineBuiltinMethodCall(expr, known_function, receiver_map,
+                                   args_count_no_receiver)) {
+      if (FLAG_trace_inlining) {
+        PrintF("Inlining builtin ");
+        known_function->ShortPrint();
+        PrintF("\n");
+      }
+      return;
+    }
+
+    if (TryInlineIndirectCall(known_function, expr, args_count_no_receiver)) {
+      return;
+    }
+  }
+
+  PushArgumentsFromEnvironment(arguments_count);
+  HInvokeFunction* call =
+      New<HInvokeFunction>(function, known_function, arguments_count);
+  Drop(1);  // Function
+  ast_context()->ReturnInstruction(call, expr->id());
+}
+
+
+bool HOptimizedGraphBuilder::TryIndirectCall(Call* expr) {
   DCHECK(expr->expression()->IsProperty());
 
   if (!expr->IsMonomorphic()) {
@@ -8701,27 +8833,40 @@
   }
   Handle<Map> function_map = expr->GetReceiverTypes()->first();
   if (function_map->instance_type() != JS_FUNCTION_TYPE ||
-      !expr->target()->shared()->HasBuiltinFunctionId() ||
-      expr->target()->shared()->builtin_function_id() != kFunctionApply) {
+      !expr->target()->shared()->HasBuiltinFunctionId()) {
     return false;
   }
 
-  if (current_info()->scope()->arguments() == NULL) return false;
+  switch (expr->target()->shared()->builtin_function_id()) {
+    case kFunctionCall: {
+      if (expr->arguments()->length() == 0) return false;
+      BuildFunctionCall(expr);
+      return true;
+    }
+    case kFunctionApply: {
+      // For .apply, only the pattern f.apply(receiver, arguments)
+      // is supported.
+      if (current_info()->scope()->arguments() == NULL) return false;
 
+      if (!CanBeFunctionApplyArguments(expr)) return false;
+
+      BuildFunctionApply(expr);
+      return true;
+    }
+    default: { return false; }
+  }
+  UNREACHABLE();
+}
+
+
+void HOptimizedGraphBuilder::BuildFunctionApply(Call* expr) {
   ZoneList<Expression*>* args = expr->arguments();
-  if (args->length() != 2) return false;
-
-  VariableProxy* arg_two = args->at(1)->AsVariableProxy();
-  if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false;
-  HValue* arg_two_value = LookupAndMakeLive(arg_two->var());
-  if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
-
-  // Found pattern f.apply(receiver, arguments).
-  CHECK_ALIVE_OR_RETURN(VisitForValue(args->at(0)), true);
+  CHECK_ALIVE(VisitForValue(args->at(0)));
   HValue* receiver = Pop();  // receiver
   HValue* function = Pop();  // f
   Drop(1);  // apply
 
+  Handle<Map> function_map = expr->GetReceiverTypes()->first();
   HValue* checked_function = AddCheckMap(function, function_map);
 
   if (function_state()->outer() == NULL) {
@@ -8733,7 +8878,6 @@
                                                 length,
                                                 elements);
     ast_context()->ReturnInstruction(result, expr->id());
-    return true;
   } else {
     // We are inside inlined function and we know exactly what is inside
     // arguments object. But we need to be able to materialize at deopt.
@@ -8747,26 +8891,36 @@
     for (int i = 1; i < arguments_count; i++) {
       Push(arguments_values->at(i));
     }
-
-    Handle<JSFunction> known_function;
-    if (function->IsConstant() &&
-        HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
-      known_function = Handle<JSFunction>::cast(
-          HConstant::cast(function)->handle(isolate()));
-      int args_count = arguments_count - 1;  // Excluding receiver.
-      if (TryInlineApply(known_function, expr, args_count)) return true;
-    }
-
-    PushArgumentsFromEnvironment(arguments_count);
-    HInvokeFunction* call = New<HInvokeFunction>(
-        function, known_function, arguments_count);
-    Drop(1);  // Function.
-    ast_context()->ReturnInstruction(call, expr->id());
-    return true;
+    HandleIndirectCall(expr, function, arguments_count);
   }
 }
 
 
+// f.call(...)
+void HOptimizedGraphBuilder::BuildFunctionCall(Call* expr) {
+  HValue* function = Top();  // f
+  Handle<Map> function_map = expr->GetReceiverTypes()->first();
+  HValue* checked_function = AddCheckMap(function, function_map);
+
+  // f and call are on the stack in the unoptimized code
+  // during evaluation of the arguments.
+  CHECK_ALIVE(VisitExpressions(expr->arguments()));
+
+  int args_length = expr->arguments()->length();
+  int receiver_index = args_length - 1;
+  // Patch the receiver.
+  HValue* receiver = BuildWrapReceiver(
+      environment()->ExpressionStackAt(receiver_index), checked_function);
+  environment()->SetExpressionStackAt(receiver_index, receiver);
+
+  // Call must not be on the stack from now on.
+  int call_index = args_length + 1;
+  environment()->RemoveExpressionStackAt(call_index);
+
+  HandleIndirectCall(expr, function, args_length);
+}
+
+
 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function,
                                                     Handle<JSFunction> target) {
   SharedFunctionInfo* shared = target->shared();
@@ -8840,9 +8994,8 @@
     LoopBuilder loop(this, context(), direction);
     {
       HValue* index = loop.BeginBody(initial, terminating, token);
-      HValue* element = AddUncasted<HLoadKeyed>(
-          elements, index, static_cast<HValue*>(NULL),
-          kind, ALLOW_RETURN_HOLE);
+      HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, kind,
+                                                ALLOW_RETURN_HOLE);
       IfBuilder if_issame(this);
       if_issame.If<HCompareNumericAndBranch>(element, search_element,
                                              Token::EQ_STRICT);
@@ -8863,9 +9016,8 @@
       LoopBuilder loop(this, context(), direction);
       {
         HValue* index = loop.BeginBody(initial, terminating, token);
-        HValue* element = AddUncasted<HLoadKeyed>(
-            elements, index, static_cast<HValue*>(NULL),
-            kind, ALLOW_RETURN_HOLE);
+        HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr,
+                                                  kind, ALLOW_RETURN_HOLE);
         IfBuilder if_issame(this);
         if_issame.If<HIsStringAndBranch>(element);
         if_issame.AndIf<HStringCompareAndBranch>(
@@ -8894,9 +9046,8 @@
         LoopBuilder loop(this, context(), direction);
         {
           HValue* index = loop.BeginBody(initial, terminating, token);
-          HValue* element = AddUncasted<HLoadKeyed>(
-              elements, index, static_cast<HValue*>(NULL),
-              kind, ALLOW_RETURN_HOLE);
+          HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr,
+                                                    kind, ALLOW_RETURN_HOLE);
 
           IfBuilder if_element_isnumber(this);
           if_element_isnumber.If<HIsSmiAndBranch>(element);
@@ -8927,9 +9078,8 @@
         LoopBuilder loop(this, context(), direction);
         {
           HValue* index = loop.BeginBody(initial, terminating, token);
-          HValue* element = AddUncasted<HLoadKeyed>(
-              elements, index, static_cast<HValue*>(NULL),
-              kind, ALLOW_RETURN_HOLE);
+          HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr,
+                                                    kind, ALLOW_RETURN_HOLE);
           IfBuilder if_issame(this);
           if_issame.If<HCompareObjectEqAndBranch>(
               element, search_element);
@@ -8982,6 +9132,17 @@
 }
 
 
+bool HOptimizedGraphBuilder::CanBeFunctionApplyArguments(Call* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  if (args->length() != 2) return false;
+  VariableProxy* arg_two = args->at(1)->AsVariableProxy();
+  if (arg_two == NULL || !arg_two->var()->IsStackAllocated()) return false;
+  HValue* arg_two_value = LookupAndMakeLive(arg_two->var());
+  if (!arg_two_value->CheckFlag(HValue::kIsArguments)) return false;
+  return true;
+}
+
+
 void HOptimizedGraphBuilder::VisitCall(Call* expr) {
   DCHECK(!HasStackOverflow());
   DCHECK(current_block() != NULL);
@@ -9018,22 +9179,24 @@
 
     if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
 
-    // Push the function under the receiver.
-    environment()->SetExpressionStackAt(0, function);
 
-    Push(receiver);
 
     if (function->IsConstant() &&
         HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
+      // Push the function under the receiver.
+      environment()->SetExpressionStackAt(0, function);
+      Push(receiver);
+
       Handle<JSFunction> known_function = Handle<JSFunction>::cast(
           HConstant::cast(function)->handle(isolate()));
       expr->set_target(known_function);
 
-      if (TryCallApply(expr)) return;
+      if (TryIndirectCall(expr)) return;
       CHECK_ALIVE(VisitExpressions(expr->arguments()));
 
       Handle<Map> map = types->length() == 1 ? types->first() : Handle<Map>();
-      if (TryInlineBuiltinMethodCall(expr, receiver, map)) {
+      if (TryInlineBuiltinMethodCall(expr, known_function, map,
+                                     expr->arguments()->length())) {
         if (FLAG_trace_inlining) {
           PrintF("Inlining builtin ");
           known_function->ShortPrint();
@@ -9059,7 +9222,20 @@
       }
 
     } else {
-      CHECK_ALIVE(VisitExpressions(expr->arguments()));
+      ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED;
+      if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) {
+        // We have to use EAGER deoptimization here because Deoptimizer::SOFT
+        // gets ignored by the always-opt flag, which leads to incorrect code.
+        Add<HDeoptimize>("Insufficient type feedback for call with arguments",
+                         Deoptimizer::EAGER);
+        arguments_flag = ARGUMENTS_FAKED;
+      }
+
+      // Push the function under the receiver.
+      environment()->SetExpressionStackAt(0, function);
+      Push(receiver);
+
+      CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag));
       CallFunctionFlags flags = receiver->type().IsJSObject()
           ? NO_CALL_FUNCTION_FLAGS : CALL_AS_METHOD;
       call = New<HCallFunction>(function, argument_count, flags);
@@ -9087,7 +9263,6 @@
                         LookupIterator::OWN_SKIP_INTERCEPTOR);
       GlobalPropertyAccess type = LookupGlobalProperty(var, &it, LOAD);
       if (type == kUseCell) {
-        Handle<GlobalObject> global(current_info()->global_object());
         known_global_function = expr->ComputeGlobalTarget(global, &it);
       }
       if (known_global_function) {
@@ -9173,8 +9348,7 @@
   HValue* constructor = environment()->ExpressionStackAt(argument_count);
 
   // Register on the site for deoptimization if the transition feedback changes.
-  AllocationSite::AddDependentCompilationInfo(
-      site, AllocationSite::TRANSITIONS, top_info());
+  AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info());
   ElementsKind kind = site->GetElementsKind();
   HInstruction* site_instruction = Add<HConstant>(site);
 
@@ -9304,9 +9478,8 @@
         Handle<AllocationSite> allocation_site = expr->allocation_site();
         allocation_mode = HAllocationMode(allocation_site);
         // Take a dependency on allocation site.
-        AllocationSite::AddDependentCompilationInfo(allocation_site,
-                                                    AllocationSite::TENURING,
-                                                    top_info());
+        AllocationSite::RegisterForDeoptOnTenureChange(allocation_site,
+                                                       top_info());
       }
     }
 
@@ -9427,11 +9600,9 @@
         HObjectAccess::ForJSArrayBufferViewBuffer(), buffer);
     HObjectAccess weak_first_view_access =
         HObjectAccess::ForJSArrayBufferWeakFirstView();
-    Add<HStoreNamedField>(obj,
-        HObjectAccess::ForJSArrayBufferViewWeakNext(),
-        Add<HLoadNamedField>(buffer,
-                             static_cast<HValue*>(NULL),
-                             weak_first_view_access));
+    Add<HStoreNamedField>(
+        obj, HObjectAccess::ForJSArrayBufferViewWeakNext(),
+        Add<HLoadNamedField>(buffer, nullptr, weak_first_view_access));
     Add<HStoreNamedField>(buffer, weak_first_view_access, obj);
   } else {
     Add<HStoreNamedField>(
@@ -9511,8 +9682,7 @@
       HObjectAccess::ForFixedArrayLength(), length);
 
   HValue* backing_store = Add<HLoadNamedField>(
-      buffer, static_cast<HValue*>(NULL),
-      HObjectAccess::ForJSArrayBufferBackingStore());
+      buffer, nullptr, HObjectAccess::ForJSArrayBufferBackingStore());
 
   HValue* typed_array_start;
   if (is_zero_byte_offset) {
@@ -9730,9 +9900,7 @@
   CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
   HValue* buffer = Pop();
   HInstruction* result = New<HLoadNamedField>(
-    buffer,
-    static_cast<HValue*>(NULL),
-    HObjectAccess::ForJSArrayBufferByteLength());
+      buffer, nullptr, HObjectAccess::ForJSArrayBufferByteLength());
   return ast_context()->ReturnInstruction(result, expr->id());
 }
 
@@ -9743,9 +9911,7 @@
   CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
   HValue* buffer = Pop();
   HInstruction* result = New<HLoadNamedField>(
-    buffer,
-    static_cast<HValue*>(NULL),
-    HObjectAccess::ForJSArrayBufferViewByteLength());
+      buffer, nullptr, HObjectAccess::ForJSArrayBufferViewByteLength());
   return ast_context()->ReturnInstruction(result, expr->id());
 }
 
@@ -9756,9 +9922,7 @@
   CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
   HValue* buffer = Pop();
   HInstruction* result = New<HLoadNamedField>(
-    buffer,
-    static_cast<HValue*>(NULL),
-    HObjectAccess::ForJSArrayBufferViewByteOffset());
+      buffer, nullptr, HObjectAccess::ForJSArrayBufferViewByteOffset());
   return ast_context()->ReturnInstruction(result, expr->id());
 }
 
@@ -9769,9 +9933,7 @@
   CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
   HValue* buffer = Pop();
   HInstruction* result = New<HLoadNamedField>(
-    buffer,
-    static_cast<HValue*>(NULL),
-    HObjectAccess::ForJSTypedArrayLength());
+      buffer, nullptr, HObjectAccess::ForJSTypedArrayLength());
   return ast_context()->ReturnInstruction(result, expr->id());
 }
 
@@ -10004,6 +10166,9 @@
     if (var->mode() == CONST_LEGACY)  {
       return Bailout(kUnsupportedCountOperationWithConst);
     }
+    if (var->mode() == CONST) {
+      return Bailout(kNonInitializerAssignmentToConst);
+    }
     // Argument of the count operation is a variable, not a property.
     DCHECK(prop == NULL);
     CHECK_ALIVE(VisitForValue(target));
@@ -10153,7 +10318,7 @@
       !ShiftAmountsAllowReplaceByRotate(shr->right(), shl->right())) {
     return false;
   }
-  *operand= shr->left();
+  *operand = shr->left();
   *shift_amount = shr->right();
   return true;
 }
@@ -10349,8 +10514,7 @@
     if (!allocation_mode.feedback_site().is_null()) {
       DCHECK(!graph()->info()->IsStub());
       Handle<AllocationSite> site(allocation_mode.feedback_site());
-      AllocationSite::AddDependentCompilationInfo(
-          site, AllocationSite::TENURING, top_info());
+      AllocationSite::RegisterForDeoptOnTenureChange(site, top_info());
     }
 
     // Inline the string addition into the stub when creating allocation
@@ -10441,8 +10605,7 @@
         break;
       case Token::SHR:
         instr = AddUncasted<HShr>(left, right);
-        if (FLAG_opt_safe_uint32_operations && instr->IsShr() &&
-            CanBeZero(right)) {
+        if (instr->IsShr() && CanBeZero(right)) {
           graph()->RecordUint32Instruction(instr);
         }
         break;
@@ -10946,13 +11109,14 @@
       boilerplate_object->map()->instance_size());
 
   PretenureFlag pretenure_flag = NOT_TENURED;
+  Handle<AllocationSite> site(site_context->current());
   if (FLAG_allocation_site_pretenuring) {
     pretenure_flag = site_context->current()->GetPretenureMode();
-    Handle<AllocationSite> site(site_context->current());
-    AllocationSite::AddDependentCompilationInfo(
-        site, AllocationSite::TENURING, top_info());
+    AllocationSite::RegisterForDeoptOnTenureChange(site, top_info());
   }
 
+  AllocationSite::RegisterForDeoptOnTransitionChange(site, top_info());
+
   HInstruction* object = Add<HAllocate>(object_size_constant, type,
       pretenure_flag, instance_type, site_context->current());
 
@@ -11069,18 +11233,27 @@
     PropertyDetails details = descriptors->GetDetails(i);
     if (details.type() != FIELD) continue;
     copied_fields++;
-    int index = descriptors->GetFieldIndex(i);
-    int property_offset = boilerplate_object->GetInObjectPropertyOffset(index);
+    FieldIndex field_index = FieldIndex::ForDescriptor(*boilerplate_map, i);
+
+
+    int property_offset = field_index.offset();
     Handle<Name> name(descriptors->GetKey(i));
-    Handle<Object> value =
-        Handle<Object>(boilerplate_object->InObjectPropertyAt(index),
-        isolate());
 
     // The access for the store depends on the type of the boilerplate.
     HObjectAccess access = boilerplate_object->IsJSArray() ?
         HObjectAccess::ForJSArrayOffset(property_offset) :
         HObjectAccess::ForMapAndOffset(boilerplate_map, property_offset);
 
+    if (boilerplate_object->IsUnboxedDoubleField(field_index)) {
+      CHECK(!boilerplate_object->IsJSArray());
+      double value = boilerplate_object->RawFastDoublePropertyAt(field_index);
+      access = access.WithRepresentation(Representation::Double());
+      Add<HStoreNamedField>(object, access, Add<HConstant>(value));
+      continue;
+    }
+    Handle<Object> value(boilerplate_object->RawFastPropertyAt(field_index),
+                         isolate());
+
     if (value->IsJSObject()) {
       Handle<JSObject> value_object = Handle<JSObject>::cast(value);
       Handle<AllocationSite> current_site = site_context->EnterNewScope();
@@ -11167,10 +11340,8 @@
   int elements_length = elements->length();
   for (int i = 0; i < elements_length; i++) {
     HValue* key_constant = Add<HConstant>(i);
-    HInstruction* value_instruction =
-        Add<HLoadKeyed>(boilerplate_elements, key_constant,
-                        static_cast<HValue*>(NULL), kind,
-                        ALLOW_RETURN_HOLE);
+    HInstruction* value_instruction = Add<HLoadKeyed>(
+        boilerplate_elements, key_constant, nullptr, kind, ALLOW_RETURN_HOLE);
     HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant,
                                            value_instruction, kind);
     store->SetFlag(HValue::kAllowUndefinedAsNaN);
@@ -11197,11 +11368,13 @@
       site_context->ExitScope(current_site, value_object);
       Add<HStoreKeyed>(object_elements, key_constant, result, kind);
     } else {
+      ElementsKind copy_kind =
+          kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind;
       HInstruction* value_instruction =
-          Add<HLoadKeyed>(boilerplate_elements, key_constant,
-                          static_cast<HValue*>(NULL), kind,
-                          ALLOW_RETURN_HOLE);
-      Add<HStoreKeyed>(object_elements, key_constant, value_instruction, kind);
+          Add<HLoadKeyed>(boilerplate_elements, key_constant, nullptr,
+                          copy_kind, ALLOW_RETURN_HOLE);
+      Add<HStoreKeyed>(object_elements, key_constant, value_instruction,
+                       copy_kind);
     }
   }
 }
@@ -11440,6 +11613,58 @@
 }
 
 
+void HOptimizedGraphBuilder::GenerateIsJSProxy(CallRuntime* call) {
+  DCHECK(call->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  HValue* value = Pop();
+  HIfContinuation continuation;
+  IfBuilder if_proxy(this);
+
+  HValue* smicheck = if_proxy.IfNot<HIsSmiAndBranch>(value);
+  if_proxy.And();
+  HValue* map = Add<HLoadNamedField>(value, smicheck, HObjectAccess::ForMap());
+  HValue* instance_type =
+      Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType());
+  if_proxy.If<HCompareNumericAndBranch>(
+      instance_type, Add<HConstant>(FIRST_JS_PROXY_TYPE), Token::GTE);
+  if_proxy.And();
+  if_proxy.If<HCompareNumericAndBranch>(
+      instance_type, Add<HConstant>(LAST_JS_PROXY_TYPE), Token::LTE);
+
+  if_proxy.CaptureContinuation(&continuation);
+  return ast_context()->ReturnContinuation(&continuation, call->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateHasFastPackedElements(CallRuntime* call) {
+  DCHECK(call->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  HValue* object = Pop();
+  HIfContinuation continuation(graph()->CreateBasicBlock(),
+                               graph()->CreateBasicBlock());
+  IfBuilder if_not_smi(this);
+  if_not_smi.IfNot<HIsSmiAndBranch>(object);
+  if_not_smi.Then();
+  {
+    NoObservableSideEffectsScope no_effects(this);
+
+    IfBuilder if_fast_packed(this);
+    HValue* elements_kind = BuildGetElementsKind(object);
+    if_fast_packed.If<HCompareNumericAndBranch>(
+        elements_kind, Add<HConstant>(FAST_SMI_ELEMENTS), Token::EQ);
+    if_fast_packed.Or();
+    if_fast_packed.If<HCompareNumericAndBranch>(
+        elements_kind, Add<HConstant>(FAST_ELEMENTS), Token::EQ);
+    if_fast_packed.Or();
+    if_fast_packed.If<HCompareNumericAndBranch>(
+        elements_kind, Add<HConstant>(FAST_DOUBLE_ELEMENTS), Token::EQ);
+    if_fast_packed.JoinContinuation(&continuation);
+  }
+  if_not_smi.JoinContinuation(&continuation);
+  return ast_context()->ReturnContinuation(&continuation, call->id());
+}
+
+
 void HOptimizedGraphBuilder::GenerateIsNonNegativeSmi(CallRuntime* call) {
   return Bailout(kInlinedRuntimeFunctionIsNonNegativeSmi);
 }
@@ -11860,6 +12085,650 @@
 }
 
 
+HValue* HOptimizedGraphBuilder::BuildOrderedHashTableHashToBucket(
+    HValue* hash, HValue* num_buckets) {
+  HValue* mask = AddUncasted<HSub>(num_buckets, graph()->GetConstant1());
+  mask->ChangeRepresentation(Representation::Integer32());
+  mask->ClearFlag(HValue::kCanOverflow);
+  return AddUncasted<HBitwise>(Token::BIT_AND, hash, mask);
+}
+
+
+template <typename CollectionType>
+HValue* HOptimizedGraphBuilder::BuildOrderedHashTableHashToEntry(
+    HValue* table, HValue* hash, HValue* num_buckets) {
+  HValue* bucket = BuildOrderedHashTableHashToBucket(hash, num_buckets);
+  HValue* entry_index = AddUncasted<HAdd>(
+      bucket, Add<HConstant>(CollectionType::kHashTableStartIndex));
+  entry_index->ClearFlag(HValue::kCanOverflow);
+  HValue* entry = Add<HLoadKeyed>(table, entry_index, nullptr, FAST_ELEMENTS);
+  entry->set_type(HType::Smi());
+  return entry;
+}
+
+
+template <typename CollectionType>
+HValue* HOptimizedGraphBuilder::BuildOrderedHashTableEntryToIndex(
+    HValue* entry, HValue* num_buckets) {
+  HValue* index =
+      AddUncasted<HMul>(entry, Add<HConstant>(CollectionType::kEntrySize));
+  index->ClearFlag(HValue::kCanOverflow);
+  index = AddUncasted<HAdd>(index, num_buckets);
+  index->ClearFlag(HValue::kCanOverflow);
+  index = AddUncasted<HAdd>(
+      index, Add<HConstant>(CollectionType::kHashTableStartIndex));
+  index->ClearFlag(HValue::kCanOverflow);
+  return index;
+}
+
+
+template <typename CollectionType>
+HValue* HOptimizedGraphBuilder::BuildOrderedHashTableFindEntry(HValue* table,
+                                                               HValue* key,
+                                                               HValue* hash) {
+  HValue* num_buckets = Add<HLoadNamedField>(
+      table, nullptr,
+      HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>());
+
+  HValue* entry = BuildOrderedHashTableHashToEntry<CollectionType>(table, hash,
+                                                                   num_buckets);
+
+  Push(entry);
+
+  LoopBuilder loop(this);
+  loop.BeginBody(1);
+
+  entry = Pop();
+
+  {
+    IfBuilder if_not_found(this);
+    if_not_found.If<HCompareNumericAndBranch>(
+        entry, Add<HConstant>(CollectionType::kNotFound), Token::EQ);
+    if_not_found.Then();
+    Push(entry);
+    loop.Break();
+  }
+
+  HValue* key_index =
+      BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets);
+  HValue* candidate_key =
+      Add<HLoadKeyed>(table, key_index, nullptr, FAST_ELEMENTS);
+
+  {
+    IfBuilder if_keys_equal(this);
+    if_keys_equal.If<HIsStringAndBranch>(candidate_key);
+    if_keys_equal.AndIf<HStringCompareAndBranch>(candidate_key, key,
+                                                 Token::EQ_STRICT);
+    if_keys_equal.Then();
+    Push(key_index);
+    loop.Break();
+  }
+
+  // BuildChainAt
+  HValue* chain_index = AddUncasted<HAdd>(
+      key_index, Add<HConstant>(CollectionType::kChainOffset));
+  chain_index->ClearFlag(HValue::kCanOverflow);
+  entry = Add<HLoadKeyed>(table, chain_index, nullptr, FAST_ELEMENTS);
+  entry->set_type(HType::Smi());
+  Push(entry);
+
+  loop.EndBody();
+
+  return Pop();
+}
+
+
+void HOptimizedGraphBuilder::GenerateMapGet(CallRuntime* call) {
+  DCHECK(call->arguments()->length() == 2);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
+  HValue* key = Pop();
+  HValue* receiver = Pop();
+
+  NoObservableSideEffectsScope no_effects(this);
+
+  HIfContinuation continuation;
+  HValue* hash =
+      BuildStringHashLoadIfIsStringAndHashComputed(key, &continuation);
+  {
+    IfBuilder string_checker(this, &continuation);
+    string_checker.Then();
+    {
+      HValue* table = Add<HLoadNamedField>(
+          receiver, nullptr, HObjectAccess::ForJSCollectionTable());
+      HValue* key_index =
+          BuildOrderedHashTableFindEntry<OrderedHashMap>(table, key, hash);
+      IfBuilder if_found(this);
+      if_found.If<HCompareNumericAndBranch>(
+          key_index, Add<HConstant>(OrderedHashMap::kNotFound), Token::NE);
+      if_found.Then();
+      {
+        HValue* value_index = AddUncasted<HAdd>(
+            key_index, Add<HConstant>(OrderedHashMap::kValueOffset));
+        value_index->ClearFlag(HValue::kCanOverflow);
+        Push(Add<HLoadKeyed>(table, value_index, nullptr, FAST_ELEMENTS));
+      }
+      if_found.Else();
+      Push(graph()->GetConstantUndefined());
+      if_found.End();
+    }
+    string_checker.Else();
+    {
+      Add<HPushArguments>(receiver, key);
+      Push(Add<HCallRuntime>(call->name(),
+                             Runtime::FunctionForId(Runtime::kMapGet), 2));
+    }
+  }
+
+  return ast_context()->ReturnValue(Pop());
+}
+
+
+HValue* HOptimizedGraphBuilder::BuildStringHashLoadIfIsStringAndHashComputed(
+    HValue* object, HIfContinuation* continuation) {
+  IfBuilder string_checker(this);
+  string_checker.If<HIsStringAndBranch>(object);
+  string_checker.And();
+  HValue* hash = Add<HLoadNamedField>(object, nullptr,
+                                      HObjectAccess::ForStringHashField());
+  HValue* hash_not_computed_mask = Add<HConstant>(String::kHashNotComputedMask);
+  HValue* hash_computed_test =
+      AddUncasted<HBitwise>(Token::BIT_AND, hash, hash_not_computed_mask);
+  string_checker.If<HCompareNumericAndBranch>(
+      hash_computed_test, graph()->GetConstant0(), Token::EQ);
+  string_checker.Then();
+  HValue* shifted_hash =
+      AddUncasted<HShr>(hash, Add<HConstant>(String::kHashShift));
+  string_checker.CaptureContinuation(continuation);
+  return shifted_hash;
+}
+
+
+template <typename CollectionType>
+void HOptimizedGraphBuilder::BuildJSCollectionHas(
+    CallRuntime* call, const Runtime::Function* c_function) {
+  DCHECK(call->arguments()->length() == 2);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
+  HValue* key = Pop();
+  HValue* receiver = Pop();
+
+  NoObservableSideEffectsScope no_effects(this);
+
+  HIfContinuation continuation;
+  HValue* hash =
+      BuildStringHashLoadIfIsStringAndHashComputed(key, &continuation);
+  {
+    IfBuilder string_checker(this, &continuation);
+    string_checker.Then();
+    {
+      HValue* table = Add<HLoadNamedField>(
+          receiver, nullptr, HObjectAccess::ForJSCollectionTable());
+      HValue* key_index =
+          BuildOrderedHashTableFindEntry<CollectionType>(table, key, hash);
+      {
+        IfBuilder if_found(this);
+        if_found.If<HCompareNumericAndBranch>(
+            key_index, Add<HConstant>(CollectionType::kNotFound), Token::NE);
+        if_found.Then();
+        Push(graph()->GetConstantTrue());
+        if_found.Else();
+        Push(graph()->GetConstantFalse());
+      }
+    }
+    string_checker.Else();
+    {
+      Add<HPushArguments>(receiver, key);
+      Push(Add<HCallRuntime>(call->name(), c_function, 2));
+    }
+  }
+
+  return ast_context()->ReturnValue(Pop());
+}
+
+
+void HOptimizedGraphBuilder::GenerateMapHas(CallRuntime* call) {
+  BuildJSCollectionHas<OrderedHashMap>(
+      call, Runtime::FunctionForId(Runtime::kMapHas));
+}
+
+
+void HOptimizedGraphBuilder::GenerateSetHas(CallRuntime* call) {
+  BuildJSCollectionHas<OrderedHashSet>(
+      call, Runtime::FunctionForId(Runtime::kSetHas));
+}
+
+
+template <typename CollectionType>
+HValue* HOptimizedGraphBuilder::BuildOrderedHashTableAddEntry(
+    HValue* table, HValue* key, HValue* hash,
+    HIfContinuation* join_continuation) {
+  HValue* num_buckets = Add<HLoadNamedField>(
+      table, nullptr,
+      HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>());
+  HValue* capacity = AddUncasted<HMul>(
+      num_buckets, Add<HConstant>(CollectionType::kLoadFactor));
+  capacity->ClearFlag(HValue::kCanOverflow);
+  HValue* num_elements = Add<HLoadNamedField>(
+      table, nullptr,
+      HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>());
+  HValue* num_deleted = Add<HLoadNamedField>(
+      table, nullptr, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
+                          CollectionType>());
+  HValue* used = AddUncasted<HAdd>(num_elements, num_deleted);
+  used->ClearFlag(HValue::kCanOverflow);
+  IfBuilder if_space_available(this);
+  if_space_available.If<HCompareNumericAndBranch>(capacity, used, Token::GT);
+  if_space_available.Then();
+  HValue* bucket = BuildOrderedHashTableHashToBucket(hash, num_buckets);
+  HValue* entry = used;
+  HValue* key_index =
+      BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets);
+
+  HValue* bucket_index = AddUncasted<HAdd>(
+      bucket, Add<HConstant>(CollectionType::kHashTableStartIndex));
+  bucket_index->ClearFlag(HValue::kCanOverflow);
+  HValue* chain_entry =
+      Add<HLoadKeyed>(table, bucket_index, nullptr, FAST_ELEMENTS);
+  chain_entry->set_type(HType::Smi());
+
+  HValue* chain_index = AddUncasted<HAdd>(
+      key_index, Add<HConstant>(CollectionType::kChainOffset));
+  chain_index->ClearFlag(HValue::kCanOverflow);
+
+  Add<HStoreKeyed>(table, bucket_index, entry, FAST_ELEMENTS);
+  Add<HStoreKeyed>(table, chain_index, chain_entry, FAST_ELEMENTS);
+  Add<HStoreKeyed>(table, key_index, key, FAST_ELEMENTS);
+
+  HValue* new_num_elements =
+      AddUncasted<HAdd>(num_elements, graph()->GetConstant1());
+  new_num_elements->ClearFlag(HValue::kCanOverflow);
+  Add<HStoreNamedField>(
+      table,
+      HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>(),
+      new_num_elements);
+  if_space_available.JoinContinuation(join_continuation);
+  return key_index;
+}
+
+
+void HOptimizedGraphBuilder::GenerateMapSet(CallRuntime* call) {
+  DCHECK(call->arguments()->length() == 3);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
+  HValue* value = Pop();
+  HValue* key = Pop();
+  HValue* receiver = Pop();
+
+  NoObservableSideEffectsScope no_effects(this);
+
+  HIfContinuation return_or_call_runtime_continuation(
+      graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
+  HIfContinuation got_string_hash;
+  HValue* hash =
+      BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash);
+  IfBuilder string_checker(this, &got_string_hash);
+  string_checker.Then();
+  {
+    HValue* table = Add<HLoadNamedField>(receiver, nullptr,
+                                         HObjectAccess::ForJSCollectionTable());
+    HValue* key_index =
+        BuildOrderedHashTableFindEntry<OrderedHashMap>(table, key, hash);
+    {
+      IfBuilder if_found(this);
+      if_found.If<HCompareNumericAndBranch>(
+          key_index, Add<HConstant>(OrderedHashMap::kNotFound), Token::NE);
+      if_found.Then();
+      {
+        HValue* value_index = AddUncasted<HAdd>(
+            key_index, Add<HConstant>(OrderedHashMap::kValueOffset));
+        value_index->ClearFlag(HValue::kCanOverflow);
+        Add<HStoreKeyed>(table, value_index, value, FAST_ELEMENTS);
+      }
+      if_found.Else();
+      {
+        HIfContinuation did_add(graph()->CreateBasicBlock(),
+                                graph()->CreateBasicBlock());
+        HValue* key_index = BuildOrderedHashTableAddEntry<OrderedHashMap>(
+            table, key, hash, &did_add);
+        IfBuilder if_did_add(this, &did_add);
+        if_did_add.Then();
+        {
+          HValue* value_index = AddUncasted<HAdd>(
+              key_index, Add<HConstant>(OrderedHashMap::kValueOffset));
+          value_index->ClearFlag(HValue::kCanOverflow);
+          Add<HStoreKeyed>(table, value_index, value, FAST_ELEMENTS);
+        }
+        if_did_add.JoinContinuation(&return_or_call_runtime_continuation);
+      }
+    }
+  }
+  string_checker.JoinContinuation(&return_or_call_runtime_continuation);
+
+  {
+    IfBuilder return_or_call_runtime(this,
+                                     &return_or_call_runtime_continuation);
+    return_or_call_runtime.Then();
+    Push(receiver);
+    return_or_call_runtime.Else();
+    Add<HPushArguments>(receiver, key, value);
+    Push(Add<HCallRuntime>(call->name(),
+                           Runtime::FunctionForId(Runtime::kMapSet), 3));
+  }
+
+  return ast_context()->ReturnValue(Pop());
+}
+
+
+void HOptimizedGraphBuilder::GenerateSetAdd(CallRuntime* call) {
+  DCHECK(call->arguments()->length() == 2);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
+  HValue* key = Pop();
+  HValue* receiver = Pop();
+
+  NoObservableSideEffectsScope no_effects(this);
+
+  HIfContinuation return_or_call_runtime_continuation(
+      graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
+  HIfContinuation got_string_hash;
+  HValue* hash =
+      BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash);
+  IfBuilder string_checker(this, &got_string_hash);
+  string_checker.Then();
+  {
+    HValue* table = Add<HLoadNamedField>(receiver, nullptr,
+                                         HObjectAccess::ForJSCollectionTable());
+    HValue* key_index =
+        BuildOrderedHashTableFindEntry<OrderedHashSet>(table, key, hash);
+    {
+      IfBuilder if_not_found(this);
+      if_not_found.If<HCompareNumericAndBranch>(
+          key_index, Add<HConstant>(OrderedHashSet::kNotFound), Token::EQ);
+      if_not_found.Then();
+      BuildOrderedHashTableAddEntry<OrderedHashSet>(
+          table, key, hash, &return_or_call_runtime_continuation);
+    }
+  }
+  string_checker.JoinContinuation(&return_or_call_runtime_continuation);
+
+  {
+    IfBuilder return_or_call_runtime(this,
+                                     &return_or_call_runtime_continuation);
+    return_or_call_runtime.Then();
+    Push(receiver);
+    return_or_call_runtime.Else();
+    Add<HPushArguments>(receiver, key);
+    Push(Add<HCallRuntime>(call->name(),
+                           Runtime::FunctionForId(Runtime::kSetAdd), 2));
+  }
+
+  return ast_context()->ReturnValue(Pop());
+}
+
+
+template <typename CollectionType>
+void HOptimizedGraphBuilder::BuildJSCollectionDelete(
+    CallRuntime* call, const Runtime::Function* c_function) {
+  DCHECK(call->arguments()->length() == 2);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
+  HValue* key = Pop();
+  HValue* receiver = Pop();
+
+  NoObservableSideEffectsScope no_effects(this);
+
+  HIfContinuation return_or_call_runtime_continuation(
+      graph()->CreateBasicBlock(), graph()->CreateBasicBlock());
+  HIfContinuation got_string_hash;
+  HValue* hash =
+      BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash);
+  IfBuilder string_checker(this, &got_string_hash);
+  string_checker.Then();
+  {
+    HValue* table = Add<HLoadNamedField>(receiver, nullptr,
+                                         HObjectAccess::ForJSCollectionTable());
+    HValue* key_index =
+        BuildOrderedHashTableFindEntry<CollectionType>(table, key, hash);
+    {
+      IfBuilder if_found(this);
+      if_found.If<HCompareNumericAndBranch>(
+          key_index, Add<HConstant>(CollectionType::kNotFound), Token::NE);
+      if_found.Then();
+      {
+        // If we're removing an element, we might need to shrink.
+        // If we do need to shrink, we'll be bailing out to the runtime.
+        HValue* num_elements = Add<HLoadNamedField>(
+            table, nullptr, HObjectAccess::ForOrderedHashTableNumberOfElements<
+                                CollectionType>());
+        num_elements = AddUncasted<HSub>(num_elements, graph()->GetConstant1());
+        num_elements->ClearFlag(HValue::kCanOverflow);
+
+        HValue* num_buckets = Add<HLoadNamedField>(
+            table, nullptr, HObjectAccess::ForOrderedHashTableNumberOfBuckets<
+                                CollectionType>());
+        // threshold is capacity >> 2; we simplify this to num_buckets >> 1
+        // since kLoadFactor is 2.
+        STATIC_ASSERT(CollectionType::kLoadFactor == 2);
+        HValue* threshold =
+            AddUncasted<HShr>(num_buckets, graph()->GetConstant1());
+
+        IfBuilder if_need_not_shrink(this);
+        if_need_not_shrink.If<HCompareNumericAndBranch>(num_elements, threshold,
+                                                        Token::GTE);
+        if_need_not_shrink.Then();
+        {
+          Add<HStoreKeyed>(table, key_index, graph()->GetConstantHole(),
+                           FAST_ELEMENTS);
+
+          // For maps, also need to clear the value.
+          if (CollectionType::kChainOffset > 1) {
+            HValue* value_index =
+                AddUncasted<HAdd>(key_index, graph()->GetConstant1());
+            value_index->ClearFlag(HValue::kCanOverflow);
+            Add<HStoreKeyed>(table, value_index, graph()->GetConstantHole(),
+                             FAST_ELEMENTS);
+          }
+          STATIC_ASSERT(CollectionType::kChainOffset <= 2);
+
+          HValue* num_deleted = Add<HLoadNamedField>(
+              table, nullptr,
+              HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
+                  CollectionType>());
+          num_deleted = AddUncasted<HAdd>(num_deleted, graph()->GetConstant1());
+          num_deleted->ClearFlag(HValue::kCanOverflow);
+          Add<HStoreNamedField>(
+              table, HObjectAccess::ForOrderedHashTableNumberOfElements<
+                         CollectionType>(),
+              num_elements);
+          Add<HStoreNamedField>(
+              table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
+                         CollectionType>(),
+              num_deleted);
+          Push(graph()->GetConstantTrue());
+        }
+        if_need_not_shrink.JoinContinuation(
+            &return_or_call_runtime_continuation);
+      }
+      if_found.Else();
+      {
+        // Not found, so we're done.
+        Push(graph()->GetConstantFalse());
+      }
+    }
+  }
+  string_checker.JoinContinuation(&return_or_call_runtime_continuation);
+
+  {
+    IfBuilder return_or_call_runtime(this,
+                                     &return_or_call_runtime_continuation);
+    return_or_call_runtime.Then();
+    return_or_call_runtime.Else();
+    Add<HPushArguments>(receiver, key);
+    Push(Add<HCallRuntime>(call->name(), c_function, 2));
+  }
+
+  return ast_context()->ReturnValue(Pop());
+}
+
+
+void HOptimizedGraphBuilder::GenerateMapDelete(CallRuntime* call) {
+  BuildJSCollectionDelete<OrderedHashMap>(
+      call, Runtime::FunctionForId(Runtime::kMapDelete));
+}
+
+
+void HOptimizedGraphBuilder::GenerateSetDelete(CallRuntime* call) {
+  BuildJSCollectionDelete<OrderedHashSet>(
+      call, Runtime::FunctionForId(Runtime::kSetDelete));
+}
+
+
+void HOptimizedGraphBuilder::GenerateSetGetSize(CallRuntime* call) {
+  DCHECK(call->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  HValue* receiver = Pop();
+  HValue* table = Add<HLoadNamedField>(receiver, nullptr,
+                                       HObjectAccess::ForJSCollectionTable());
+  HInstruction* result = New<HLoadNamedField>(
+      table, nullptr,
+      HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashSet>());
+  return ast_context()->ReturnInstruction(result, call->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateMapGetSize(CallRuntime* call) {
+  DCHECK(call->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  HValue* receiver = Pop();
+  HValue* table = Add<HLoadNamedField>(receiver, nullptr,
+                                       HObjectAccess::ForJSCollectionTable());
+  HInstruction* result = New<HLoadNamedField>(
+      table, nullptr,
+      HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashMap>());
+  return ast_context()->ReturnInstruction(result, call->id());
+}
+
+
+template <typename CollectionType>
+HValue* HOptimizedGraphBuilder::BuildAllocateOrderedHashTable() {
+  static const int kCapacity = CollectionType::kMinCapacity;
+  static const int kBucketCount = kCapacity / CollectionType::kLoadFactor;
+  static const int kFixedArrayLength = CollectionType::kHashTableStartIndex +
+                                       kBucketCount +
+                                       (kCapacity * CollectionType::kEntrySize);
+  static const int kSizeInBytes =
+      FixedArray::kHeaderSize + (kFixedArrayLength * kPointerSize);
+
+  // Allocate the table and add the proper map.
+  HValue* table =
+      Add<HAllocate>(Add<HConstant>(kSizeInBytes), HType::HeapObject(),
+                     NOT_TENURED, FIXED_ARRAY_TYPE);
+  AddStoreMapConstant(table, isolate()->factory()->ordered_hash_table_map());
+
+  // Initialize the FixedArray...
+  HValue* length = Add<HConstant>(kFixedArrayLength);
+  Add<HStoreNamedField>(table, HObjectAccess::ForFixedArrayLength(), length);
+
+  // ...and the OrderedHashTable fields.
+  Add<HStoreNamedField>(
+      table,
+      HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>(),
+      Add<HConstant>(kBucketCount));
+  Add<HStoreNamedField>(
+      table,
+      HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>(),
+      graph()->GetConstant0());
+  Add<HStoreNamedField>(
+      table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
+                 CollectionType>(),
+      graph()->GetConstant0());
+
+  // Fill the buckets with kNotFound.
+  HValue* not_found = Add<HConstant>(CollectionType::kNotFound);
+  for (int i = 0; i < kBucketCount; ++i) {
+    Add<HStoreNamedField>(
+        table, HObjectAccess::ForOrderedHashTableBucket<CollectionType>(i),
+        not_found);
+  }
+
+  // Fill the data table with undefined.
+  HValue* undefined = graph()->GetConstantUndefined();
+  for (int i = 0; i < (kCapacity * CollectionType::kEntrySize); ++i) {
+    Add<HStoreNamedField>(table,
+                          HObjectAccess::ForOrderedHashTableDataTableIndex<
+                              CollectionType, kBucketCount>(i),
+                          undefined);
+  }
+
+  return table;
+}
+
+
+void HOptimizedGraphBuilder::GenerateSetInitialize(CallRuntime* call) {
+  DCHECK(call->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  HValue* receiver = Pop();
+
+  NoObservableSideEffectsScope no_effects(this);
+  HValue* table = BuildAllocateOrderedHashTable<OrderedHashSet>();
+  Add<HStoreNamedField>(receiver, HObjectAccess::ForJSCollectionTable(), table);
+  return ast_context()->ReturnValue(receiver);
+}
+
+
+void HOptimizedGraphBuilder::GenerateMapInitialize(CallRuntime* call) {
+  DCHECK(call->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  HValue* receiver = Pop();
+
+  NoObservableSideEffectsScope no_effects(this);
+  HValue* table = BuildAllocateOrderedHashTable<OrderedHashMap>();
+  Add<HStoreNamedField>(receiver, HObjectAccess::ForJSCollectionTable(), table);
+  return ast_context()->ReturnValue(receiver);
+}
+
+
+template <typename CollectionType>
+void HOptimizedGraphBuilder::BuildOrderedHashTableClear(HValue* receiver) {
+  HValue* old_table = Add<HLoadNamedField>(
+      receiver, nullptr, HObjectAccess::ForJSCollectionTable());
+  HValue* new_table = BuildAllocateOrderedHashTable<CollectionType>();
+  Add<HStoreNamedField>(
+      old_table, HObjectAccess::ForOrderedHashTableNextTable<CollectionType>(),
+      new_table);
+  Add<HStoreNamedField>(
+      old_table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements<
+                     CollectionType>(),
+      Add<HConstant>(CollectionType::kClearedTableSentinel));
+  Add<HStoreNamedField>(receiver, HObjectAccess::ForJSCollectionTable(),
+                        new_table);
+}
+
+
+void HOptimizedGraphBuilder::GenerateSetClear(CallRuntime* call) {
+  DCHECK(call->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  HValue* receiver = Pop();
+
+  NoObservableSideEffectsScope no_effects(this);
+  BuildOrderedHashTableClear<OrderedHashSet>(receiver);
+  return ast_context()->ReturnValue(graph()->GetConstantUndefined());
+}
+
+
+void HOptimizedGraphBuilder::GenerateMapClear(CallRuntime* call) {
+  DCHECK(call->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  HValue* receiver = Pop();
+
+  NoObservableSideEffectsScope no_effects(this);
+  BuildOrderedHashTableClear<OrderedHashMap>(receiver);
+  return ast_context()->ReturnValue(graph()->GetConstantUndefined());
+}
+
+
 void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) {
   DCHECK(call->arguments()->length() == 1);
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
@@ -11896,12 +12765,59 @@
   DCHECK(call->arguments()->length() == 0);
   HValue* ref =
       Add<HConstant>(ExternalReference::debug_is_active_address(isolate()));
-  HValue* value = Add<HLoadNamedField>(
-      ref, static_cast<HValue*>(NULL), HObjectAccess::ForExternalUInteger8());
+  HValue* value =
+      Add<HLoadNamedField>(ref, nullptr, HObjectAccess::ForExternalUInteger8());
   return ast_context()->ReturnValue(value);
 }
 
 
+void HOptimizedGraphBuilder::GenerateGetPrototype(CallRuntime* call) {
+  DCHECK(call->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  HValue* object = Pop();
+
+  NoObservableSideEffectsScope no_effects(this);
+
+  HValue* map = Add<HLoadNamedField>(object, nullptr, HObjectAccess::ForMap());
+  HValue* bit_field =
+      Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField());
+  HValue* is_access_check_needed_mask =
+      Add<HConstant>(1 << Map::kIsAccessCheckNeeded);
+  HValue* is_access_check_needed_test = AddUncasted<HBitwise>(
+      Token::BIT_AND, bit_field, is_access_check_needed_mask);
+
+  HValue* proto =
+      Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForPrototype());
+  HValue* proto_map =
+      Add<HLoadNamedField>(proto, nullptr, HObjectAccess::ForMap());
+  HValue* proto_bit_field =
+      Add<HLoadNamedField>(proto_map, nullptr, HObjectAccess::ForMapBitField());
+  HValue* is_hidden_prototype_mask =
+      Add<HConstant>(1 << Map::kIsHiddenPrototype);
+  HValue* is_hidden_prototype_test = AddUncasted<HBitwise>(
+      Token::BIT_AND, proto_bit_field, is_hidden_prototype_mask);
+
+  {
+    IfBuilder needs_runtime(this);
+    needs_runtime.If<HCompareNumericAndBranch>(
+        is_access_check_needed_test, graph()->GetConstant0(), Token::NE);
+    needs_runtime.OrIf<HCompareNumericAndBranch>(
+        is_hidden_prototype_test, graph()->GetConstant0(), Token::NE);
+
+    needs_runtime.Then();
+    {
+      Add<HPushArguments>(object);
+      Push(Add<HCallRuntime>(
+          call->name(), Runtime::FunctionForId(Runtime::kGetPrototype), 1));
+    }
+
+    needs_runtime.Else();
+    Push(proto);
+  }
+  return ast_context()->ReturnValue(Pop());
+}
+
+
 #undef CHECK_BAILOUT
 #undef CHECK_ALIVE
 
@@ -12071,6 +12987,18 @@
 }
 
 
+HValue* HEnvironment::RemoveExpressionStackAt(int index_from_top) {
+  int count = index_from_top + 1;
+  int index = values_.length() - count;
+  DCHECK(HasExpressionAt(index));
+  // Simulate popping 'count' elements and then
+  // pushing 'count - 1' elements back.
+  pop_count_ += Max(count - push_count_, 0);
+  push_count_ = Max(push_count_ - count, 0) + (count - 1);
+  return values_.Remove(index);
+}
+
+
 void HEnvironment::Drop(int count) {
   for (int i = 0; i < count; ++i) {
     Pop();
@@ -12170,7 +13098,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const HEnvironment& env) {
+std::ostream& operator<<(std::ostream& os, const HEnvironment& env) {
   for (int i = 0; i < env.length(); i++) {
     if (i == 0) os << "parameters\n";
     if (i == env.parameter_count()) os << "specials\n";
@@ -12302,9 +13230,9 @@
       for (int j = 0; j < total; ++j) {
         HPhi* phi = current->phis()->at(j);
         PrintIndent();
-        OStringStream os;
+        std::ostringstream os;
         os << phi->merged_index() << " " << NameOf(phi) << " " << *phi << "\n";
-        trace_.Add(os.c_str());
+        trace_.Add(os.str().c_str());
       }
     }
 
@@ -12314,7 +13242,7 @@
         HInstruction* instruction = it.Current();
         int uses = instruction->UseCount();
         PrintIndent();
-        OStringStream os;
+        std::ostringstream os;
         os << "0 " << uses << " " << NameOf(instruction) << " " << *instruction;
         if (FLAG_hydrogen_track_positions &&
             instruction->has_position() &&
@@ -12325,7 +13253,7 @@
           os << pos.position();
         }
         os << " <|@\n";
-        trace_.Add(os.c_str());
+        trace_.Add(os.str().c_str());
       }
     }
 
@@ -12343,9 +13271,9 @@
             trace_.Add("%d ",
                        LifetimePosition::FromInstructionIndex(i).Value());
             linstr->PrintTo(&trace_);
-            OStringStream os;
+            std::ostringstream os;
             os << " [hir:" << NameOf(linstr->hydrogen_value()) << "] <|@\n";
-            trace_.Add(os.c_str());
+            trace_.Add(os.str().c_str());
           }
         }
       }
@@ -12445,15 +13373,14 @@
 }
 
 
-void HStatistics::Print(const char* stats_name) {
+void HStatistics::Print() {
   PrintF(
       "\n"
       "----------------------------------------"
       "----------------------------------------\n"
-      "--- %s timing results:\n"
+      "--- Hydrogen timing results:\n"
       "----------------------------------------"
-      "----------------------------------------\n",
-      stats_name);
+      "----------------------------------------\n");
   base::TimeDelta sum;
   for (int i = 0; i < times_.length(); ++i) {
     sum += times_[i];
@@ -12492,9 +13419,10 @@
   double normalized_time =  source_size_in_kb > 0
       ? total.InMillisecondsF() / source_size_in_kb
       : 0;
-  double normalized_size_in_kb = source_size_in_kb > 0
-      ? total_size_ / 1024 / source_size_in_kb
-      : 0;
+  double normalized_size_in_kb =
+      source_size_in_kb > 0
+          ? static_cast<double>(total_size_) / 1024 / source_size_in_kb
+          : 0;
   PrintF("%33s %8.3f ms           %7.3f kB allocated\n",
          "Average per kB source", normalized_time, normalized_size_in_kb);
 }
diff --git a/src/hydrogen.h b/src/hydrogen.h
index d507643..c1ed797 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -215,7 +215,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const HBasicBlock& b);
+std::ostream& operator<<(std::ostream& os, const HBasicBlock& b);
 
 
 class HPredecessorIterator FINAL BASE_EMBEDDED {
@@ -315,7 +315,6 @@
   HEnvironment* start_environment() const { return start_environment_; }
 
   void FinalizeUniqueness();
-  bool ProcessArgumentsObject();
   void OrderBlocks();
   void AssignDominators();
   void RestoreActualValues();
@@ -479,8 +478,6 @@
     phase.Run();
   }
 
-  void EliminateRedundantBoundsChecksUsingInductionVariables();
-
   Isolate* isolate_;
   int next_block_id_;
   HBasicBlock* entry_block_;
@@ -527,8 +524,8 @@
     int start_position_;
   };
 
-  int next_inline_id_;
   ZoneList<InlinedFunctionInfo> inlined_functions_;
+  ZoneList<int> inlining_id_to_function_id_;
 
   DISALLOW_COPY_AND_ASSIGN(HGraph);
 };
@@ -645,6 +642,7 @@
   }
 
   void SetExpressionStackAt(int index_from_top, HValue* value);
+  HValue* RemoveExpressionStackAt(int index_from_top);
 
   HEnvironment* Copy() const;
   HEnvironment* CopyWithoutHistory() const;
@@ -743,14 +741,15 @@
 };
 
 
-OStream& operator<<(OStream& os, const HEnvironment& env);
+std::ostream& operator<<(std::ostream& os, const HEnvironment& env);
 
 
 class HOptimizedGraphBuilder;
 
 enum ArgumentsAllowedFlag {
   ARGUMENTS_NOT_ALLOWED,
-  ARGUMENTS_ALLOWED
+  ARGUMENTS_ALLOWED,
+  ARGUMENTS_FAKED
 };
 
 
@@ -820,7 +819,7 @@
   }
   virtual ~EffectContext();
 
-  virtual void ReturnValue(HValue* value) OVERRIDE;
+  void ReturnValue(HValue* value) OVERRIDE;
   virtual void ReturnInstruction(HInstruction* instr,
                                  BailoutId ast_id) OVERRIDE;
   virtual void ReturnControl(HControlInstruction* instr,
@@ -837,7 +836,7 @@
   }
   virtual ~ValueContext();
 
-  virtual void ReturnValue(HValue* value) OVERRIDE;
+  void ReturnValue(HValue* value) OVERRIDE;
   virtual void ReturnInstruction(HInstruction* instr,
                                  BailoutId ast_id) OVERRIDE;
   virtual void ReturnControl(HControlInstruction* instr,
@@ -864,7 +863,7 @@
         if_false_(if_false) {
   }
 
-  virtual void ReturnValue(HValue* value) OVERRIDE;
+  void ReturnValue(HValue* value) OVERRIDE;
   virtual void ReturnInstruction(HInstruction* instr,
                                  BailoutId ast_id) OVERRIDE;
   virtual void ReturnControl(HControlInstruction* instr,
@@ -1805,8 +1804,9 @@
                                      ElementsKind kind,
                                      HValue* capacity);
 
-  HValue* BuildAllocateElementsAndInitializeElementsHeader(ElementsKind kind,
-                                                           HValue* capacity);
+  // Build allocation and header initialization code for respective successor
+  // of FixedArrayBase.
+  HValue* BuildAllocateAndInitializeArray(ElementsKind kind, HValue* capacity);
 
   // |array| must have been allocated with enough room for
   // 1) the JSArray and 2) an AllocationMemento if mode requires it.
@@ -1838,6 +1838,9 @@
                                  HValue* from,
                                  HValue* to);
 
+  void BuildCopyProperties(HValue* from_properties, HValue* to_properties,
+                           HValue* length, HValue* capacity);
+
   void BuildCopyElements(HValue* from_elements,
                          ElementsKind from_elements_kind,
                          HValue* to_elements,
@@ -1861,10 +1864,10 @@
 
   HValue* BuildElementIndexHash(HValue* index);
 
-  void BuildCompareNil(
-      HValue* value,
-      Type* type,
-      HIfContinuation* continuation);
+  enum MapEmbedding { kEmbedMapsDirectly, kEmbedMapsViaWeakCells };
+
+  void BuildCompareNil(HValue* value, Type* type, HIfContinuation* continuation,
+                       MapEmbedding map_embedding = kEmbedMapsDirectly);
 
   void BuildCreateAllocationMemento(HValue* previous_object,
                                     HValue* previous_object_size,
@@ -1876,6 +1879,7 @@
 
   HInstruction* BuildGetNativeContext(HValue* closure);
   HInstruction* BuildGetNativeContext();
+  HInstruction* BuildGetScriptContext(int context_index);
   HInstruction* BuildGetArrayFunction();
 
  protected:
@@ -2104,13 +2108,13 @@
 
   explicit HOptimizedGraphBuilder(CompilationInfo* info);
 
-  virtual bool BuildGraph() OVERRIDE;
+  bool BuildGraph() OVERRIDE;
 
   // Simple accessors.
   BreakAndContinueScope* break_scope() const { return break_scope_; }
   void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; }
 
-  HValue* context() { return environment()->context(); }
+  HValue* context() OVERRIDE { return environment()->context(); }
 
   HOsrBuilder* osr() const { return osr_; }
 
@@ -2122,7 +2126,7 @@
 
   FunctionState* function_state() const { return function_state_; }
 
-  void VisitDeclarations(ZoneList<Declaration*>* declarations);
+  void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE;
 
   void* operator new(size_t size, Zone* zone) {
     return zone->New(static_cast<int>(size));
@@ -2200,7 +2204,6 @@
   void VisitLogicalExpression(BinaryOperation* expr);
   void VisitArithmeticExpression(BinaryOperation* expr);
 
-  bool PreProcessOsrEntry(IterationStatement* statement);
   void VisitLoopBody(IterationStatement* stmt,
                      HBasicBlock* loop_entry);
 
@@ -2255,7 +2258,6 @@
 #endif
     }
   }
-
   HValue* LookupAndMakeLive(Variable* var) {
     HEnvironment* env = environment();
     int index = env->IndexFor(var);
@@ -2283,7 +2285,9 @@
                        HBasicBlock* false_block);
 
   // Visit a list of expressions from left to right, each in a value context.
-  void VisitExpressions(ZoneList<Expression*>* exprs);
+  void VisitExpressions(ZoneList<Expression*>* exprs) OVERRIDE;
+  void VisitExpressions(ZoneList<Expression*>* exprs,
+                        ArgumentsAllowedFlag flag);
 
   // Remove the arguments from the bailout environment and emit instructions
   // to push them as outgoing parameters.
@@ -2291,7 +2295,7 @@
   void PushArgumentsFromEnvironment(int count);
 
   void SetUpScope(Scope* scope);
-  virtual void VisitStatements(ZoneList<Statement*>* statements) OVERRIDE;
+  void VisitStatements(ZoneList<Statement*>* statements) OVERRIDE;
 
 #define DECLARE_VISIT(type) virtual void Visit##type(type* node) OVERRIDE;
   AST_NODE_LIST(DECLARE_VISIT)
@@ -2311,8 +2315,13 @@
   void EnsureArgumentsArePushedForAccess();
   bool TryArgumentsAccess(Property* expr);
 
-  // Try to optimize fun.apply(receiver, arguments) pattern.
-  bool TryCallApply(Call* expr);
+  // Shared code for .call and .apply optimizations.
+  void HandleIndirectCall(Call* expr, HValue* function, int arguments_count);
+  // Try to optimize indirect calls such as fun.apply(receiver, arguments)
+  // or fun.call(...).
+  bool TryIndirectCall(Call* expr);
+  void BuildFunctionApply(Call* expr);
+  void BuildFunctionCall(Call* expr);
 
   bool TryHandleArrayCall(Call* expr, HValue* function);
   bool TryHandleArrayCallNew(CallNew* expr, HValue* function);
@@ -2348,12 +2357,11 @@
                        BailoutId id,
                        BailoutId assignment_id,
                        HValue* implicit_return_value);
-  bool TryInlineApply(Handle<JSFunction> function,
-                      Call* expr,
-                      int arguments_count);
-  bool TryInlineBuiltinMethodCall(Call* expr,
-                                  HValue* receiver,
-                                  Handle<Map> receiver_map);
+  bool TryInlineIndirectCall(Handle<JSFunction> function, Call* expr,
+                             int arguments_count);
+  bool TryInlineBuiltinMethodCall(Call* expr, Handle<JSFunction> function,
+                                  Handle<Map> receiver_map,
+                                  int args_count_no_receiver);
   bool TryInlineBuiltinFunctionCall(Call* expr);
   enum ApiCallType {
     kCallApiFunction,
@@ -2409,6 +2417,33 @@
       ElementsKind fixed_elements_kind,
       HValue* byte_length, HValue* length);
 
+  // TODO(adamk): Move all OrderedHashTable functions to their own class.
+  HValue* BuildOrderedHashTableHashToBucket(HValue* hash, HValue* num_buckets);
+  template <typename CollectionType>
+  HValue* BuildOrderedHashTableHashToEntry(HValue* table, HValue* hash,
+                                           HValue* num_buckets);
+  template <typename CollectionType>
+  HValue* BuildOrderedHashTableEntryToIndex(HValue* entry, HValue* num_buckets);
+  template <typename CollectionType>
+  HValue* BuildOrderedHashTableFindEntry(HValue* table, HValue* key,
+                                         HValue* hash);
+  template <typename CollectionType>
+  HValue* BuildOrderedHashTableAddEntry(HValue* table, HValue* key,
+                                        HValue* hash,
+                                        HIfContinuation* join_continuation);
+  template <typename CollectionType>
+  HValue* BuildAllocateOrderedHashTable();
+  template <typename CollectionType>
+  void BuildOrderedHashTableClear(HValue* receiver);
+  template <typename CollectionType>
+  void BuildJSCollectionDelete(CallRuntime* call,
+                               const Runtime::Function* c_function);
+  template <typename CollectionType>
+  void BuildJSCollectionHas(CallRuntime* call,
+                            const Runtime::Function* c_function);
+  HValue* BuildStringHashLoadIfIsStringAndHashComputed(
+      HValue* object, HIfContinuation* continuation);
+
   Handle<JSFunction> array_function() {
     return handle(isolate()->native_context()->array_function());
   }
@@ -2713,6 +2748,8 @@
   HInstruction* BuildCallConstantFunction(Handle<JSFunction> target,
                                           int argument_count);
 
+  bool CanBeFunctionApplyArguments(Call* expr);
+
   // The translation state of the currently-being-translated function.
   FunctionState* function_state_;
 
@@ -2755,7 +2792,7 @@
         source_size_(0) { }
 
   void Initialize(CompilationInfo* info);
-  void Print(const char* stats_name);
+  void Print();
   void SaveTiming(const char* name, base::TimeDelta time, unsigned size);
 
   void IncrementFullCodeGen(base::TimeDelta full_code_gen) {
diff --git a/src/i18n.cc b/src/i18n.cc
index cae3a32..69fa9ca 100644
--- a/src/i18n.cc
+++ b/src/i18n.cc
@@ -631,6 +631,8 @@
     return NULL;
   }
 
+  isolate->CountUsage(v8::Isolate::UseCounterFeature::kBreakIterator);
+
   return break_iterator;
 }
 
@@ -702,6 +704,10 @@
     icu::Locale no_extension_locale(icu_locale.getBaseName());
     date_format = CreateICUDateFormat(isolate, no_extension_locale, options);
 
+    if (!date_format) {
+      FATAL("Failed to create ICU date format, are ICU data files missing?");
+    }
+
     // Set resolved settings (pattern, numbering system, calendar).
     SetResolvedDateSettings(
         isolate, no_extension_locale, date_format, resolved);
@@ -778,6 +784,10 @@
     number_format = CreateICUNumberFormat(
         isolate, no_extension_locale, options);
 
+    if (!number_format) {
+      FATAL("Failed to create ICU number format, are ICU data files missing?");
+    }
+
     // Set resolved settings (pattern, numbering system).
     SetResolvedNumberSettings(
         isolate, no_extension_locale, number_format, resolved);
@@ -837,6 +847,10 @@
     icu::Locale no_extension_locale(icu_locale.getBaseName());
     collator = CreateICUCollator(isolate, no_extension_locale, options);
 
+    if (!collator) {
+      FATAL("Failed to create ICU collator, are ICU data files missing?");
+    }
+
     // Set resolved settings (pattern, numbering system).
     SetResolvedCollatorSettings(
         isolate, no_extension_locale, collator, resolved);
@@ -896,6 +910,10 @@
     break_iterator = CreateICUBreakIterator(
         isolate, no_extension_locale, options);
 
+    if (!break_iterator) {
+      FATAL("Failed to create ICU break iterator, are ICU data files missing?");
+    }
+
     // Set resolved settings (locale).
     SetResolvedBreakIteratorSettings(
         isolate, no_extension_locale, break_iterator, resolved);
diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc
index d16eea1..168a196 100644
--- a/src/ia32/assembler-ia32.cc
+++ b/src/ia32/assembler-ia32.cc
@@ -34,7 +34,11 @@
 // significantly by Google Inc.
 // Copyright 2012 the V8 project authors. All rights reserved.
 
-#include "src/v8.h"
+#include "src/ia32/assembler-ia32.h"
+
+#if V8_OS_MACOSX
+#include <sys/sysctl.h>
+#endif
 
 #if V8_TARGET_ARCH_IA32
 
@@ -42,7 +46,7 @@
 #include "src/base/cpu.h"
 #include "src/disassembler.h"
 #include "src/macro-assembler.h"
-#include "src/serialize.h"
+#include "src/v8.h"
 
 namespace v8 {
 namespace internal {
@@ -50,6 +54,29 @@
 // -----------------------------------------------------------------------------
 // Implementation of CpuFeatures
 
+namespace {
+
+bool EnableAVX() {
+#if V8_OS_MACOSX
+  // Mac OS X 10.9 has a bug where AVX transitions were indeed being caused by
+  // ISRs, so we detect Mac OS X 10.9 here and disable AVX in that case.
+  char buffer[128];
+  size_t buffer_size = arraysize(buffer);
+  int ctl_name[] = { CTL_KERN , KERN_OSRELEASE };
+  if (sysctl(ctl_name, 2, buffer, &buffer_size, nullptr, 0) != 0) {
+    V8_Fatal(__FILE__, __LINE__, "V8 failed to get kernel version");
+  }
+  // The buffer now contains a string of the form XX.YY.ZZ, where
+  // XX is the major kernel version component. 13.x.x (Mavericks) is
+  // affected by this bug, so disable AVX there.
+  if (memcmp(buffer, "13.", 3) == 0) return false;
+#endif  // V8_OS_MACOSX
+  return FLAG_enable_avx;
+}
+
+}  // namespace
+
+
 void CpuFeatures::ProbeImpl(bool cross_compile) {
   base::CPU cpu;
   CHECK(cpu.has_sse2());  // SSE2 support is mandatory.
@@ -60,11 +87,17 @@
 
   if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
   if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
+  if (cpu.has_avx() && EnableAVX()) supported_ |= 1u << AVX;
+  if (cpu.has_fma3() && FLAG_enable_fma3) supported_ |= 1u << FMA3;
 }
 
 
 void CpuFeatures::PrintTarget() { }
-void CpuFeatures::PrintFeatures() { }
+void CpuFeatures::PrintFeatures() {
+  printf("SSE3=%d SSE4_1=%d AVX=%d FMA3=%d\n", CpuFeatures::IsSupported(SSE3),
+         CpuFeatures::IsSupported(SSE4_1), CpuFeatures::IsSupported(AVX),
+         CpuFeatures::IsSupported(FMA3));
+}
 
 
 // -----------------------------------------------------------------------------
@@ -457,11 +490,11 @@
 }
 
 
-void Assembler::mov_b(const Operand& dst, int8_t imm8) {
+void Assembler::mov_b(const Operand& dst, const Immediate& src) {
   EnsureSpace ensure_space(this);
   EMIT(0xC6);
   emit_operand(eax, dst);
-  EMIT(imm8);
+  EMIT(static_cast<int8_t>(src.x_));
 }
 
 
@@ -489,13 +522,13 @@
 }
 
 
-void Assembler::mov_w(const Operand& dst, int16_t imm16) {
+void Assembler::mov_w(const Operand& dst, const Immediate& src) {
   EnsureSpace ensure_space(this);
   EMIT(0x66);
   EMIT(0xC7);
   emit_operand(eax, dst);
-  EMIT(static_cast<int8_t>(imm16 & 0xff));
-  EMIT(static_cast<int8_t>(imm16 >> 8));
+  EMIT(static_cast<int8_t>(src.x_ & 0xff));
+  EMIT(static_cast<int8_t>(src.x_ >> 8));
 }
 
 
@@ -982,24 +1015,24 @@
 }
 
 
-void Assembler::ror(Register dst, uint8_t imm8) {
+void Assembler::ror(const Operand& dst, uint8_t imm8) {
   EnsureSpace ensure_space(this);
   DCHECK(is_uint5(imm8));  // illegal shift count
   if (imm8 == 1) {
     EMIT(0xD1);
-    EMIT(0xC8 | dst.code());
+    emit_operand(ecx, dst);
   } else {
     EMIT(0xC1);
-    EMIT(0xC8 | dst.code());
+    emit_operand(ecx, dst);
     EMIT(imm8);
   }
 }
 
 
-void Assembler::ror_cl(Register dst) {
+void Assembler::ror_cl(const Operand& dst) {
   EnsureSpace ensure_space(this);
   EMIT(0xD3);
-  EMIT(0xC8 | dst.code());
+  emit_operand(ecx, dst);
 }
 
 
@@ -1951,7 +1984,7 @@
 }
 
 
-void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
+void Assembler::cvtss2sd(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   EMIT(0xF3);
   EMIT(0x0F);
@@ -1960,7 +1993,7 @@
 }
 
 
-void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
+void Assembler::cvtsd2ss(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   EMIT(0xF2);
   EMIT(0x0F);
@@ -1969,15 +2002,6 @@
 }
 
 
-void Assembler::addsd(XMMRegister dst, XMMRegister src) {
-  EnsureSpace ensure_space(this);
-  EMIT(0xF2);
-  EMIT(0x0F);
-  EMIT(0x58);
-  emit_sse_operand(dst, src);
-}
-
-
 void Assembler::addsd(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   EMIT(0xF2);
@@ -1987,15 +2011,6 @@
 }
 
 
-void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
-  EnsureSpace ensure_space(this);
-  EMIT(0xF2);
-  EMIT(0x0F);
-  EMIT(0x59);
-  emit_sse_operand(dst, src);
-}
-
-
 void Assembler::mulsd(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   EMIT(0xF2);
@@ -2005,15 +2020,6 @@
 }
 
 
-void Assembler::subsd(XMMRegister dst, XMMRegister src) {
-  EnsureSpace ensure_space(this);
-  EMIT(0xF2);
-  EMIT(0x0F);
-  EMIT(0x5C);
-  emit_sse_operand(dst, src);
-}
-
-
 void Assembler::subsd(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   EMIT(0xF2);
@@ -2023,7 +2029,7 @@
 }
 
 
-void Assembler::divsd(XMMRegister dst, XMMRegister src) {
+void Assembler::divsd(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   EMIT(0xF2);
   EMIT(0x0F);
@@ -2097,15 +2103,6 @@
 }
 
 
-void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
-  EnsureSpace ensure_space(this);
-  EMIT(0xF2);
-  EMIT(0x0F);
-  EMIT(0x51);
-  emit_sse_operand(dst, src);
-}
-
-
 void Assembler::sqrtsd(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   EMIT(0xF2);
@@ -2381,6 +2378,26 @@
 }
 
 
+void Assembler::pslld(XMMRegister reg, int8_t shift) {
+  EnsureSpace ensure_space(this);
+  EMIT(0x66);
+  EMIT(0x0F);
+  EMIT(0x72);
+  emit_sse_operand(esi, reg);  // esi == 6
+  EMIT(shift);
+}
+
+
+void Assembler::psrld(XMMRegister reg, int8_t shift) {
+  EnsureSpace ensure_space(this);
+  EMIT(0x66);
+  EMIT(0x0F);
+  EMIT(0x72);
+  emit_sse_operand(edx, reg);  // edx == 2
+  EMIT(shift);
+}
+
+
 void Assembler::psllq(XMMRegister reg, int8_t shift) {
   EnsureSpace ensure_space(this);
   EMIT(0x66);
@@ -2453,6 +2470,81 @@
 }
 
 
+void Assembler::addss(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  EMIT(0xF3);
+  EMIT(0x0F);
+  EMIT(0x58);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::subss(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  EMIT(0xF3);
+  EMIT(0x0F);
+  EMIT(0x5C);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::mulss(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  EMIT(0xF3);
+  EMIT(0x0F);
+  EMIT(0x59);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::divss(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  EMIT(0xF3);
+  EMIT(0x0F);
+  EMIT(0x5E);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::ucomiss(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  EMIT(0x0f);
+  EMIT(0x2e);
+  emit_sse_operand(dst, src);
+}
+
+
+// AVX instructions
+void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
+                       const Operand& src2) {
+  DCHECK(IsEnabled(FMA3));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(src1, kLIG, k66, k0F38, kW1);
+  EMIT(op);
+  emit_sse_operand(dst, src2);
+}
+
+
+void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
+                       const Operand& src2) {
+  DCHECK(IsEnabled(FMA3));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(src1, kLIG, k66, k0F38, kW0);
+  EMIT(op);
+  emit_sse_operand(dst, src2);
+}
+
+
+void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1,
+                    const Operand& src2) {
+  DCHECK(IsEnabled(AVX));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(src1, kLIG, kF2, k0F, kWIG);
+  EMIT(op);
+  emit_sse_operand(dst, src2);
+}
+
+
 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
   Register ireg = { reg.code() };
   emit_operand(ireg, adr);
@@ -2474,8 +2566,16 @@
 }
 
 
-void Assembler::Print() {
-  Disassembler::Decode(isolate(), stdout, buffer_, pc_);
+void Assembler::emit_vex_prefix(XMMRegister vreg, VectorLength l, SIMDPrefix pp,
+                                LeadingOpcode mm, VexW w) {
+  if (mm != k0F || w != kW0) {
+    EMIT(0xc4);
+    EMIT(0xc0 | mm);
+    EMIT(w | ((~vreg.code() & 0xf) << 3) | l | pp);
+  } else {
+    EMIT(0xc5);
+    EMIT(((~vreg.code()) << 3) | l | pp);
+  }
 }
 
 
diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h
index 8175778..b913f7a 100644
--- a/src/ia32/assembler-ia32.h
+++ b/src/ia32/assembler-ia32.h
@@ -148,6 +148,11 @@
     return kMaxNumAllocatableRegisters;
   }
 
+  // TODO(turbofan): Proper support for float32.
+  static int NumAllocatableAliasedRegisters() {
+    return NumAllocatableRegisters();
+  }
+
   static int ToAllocationIndex(XMMRegister reg) {
     DCHECK(reg.code() != 0);
     return reg.code() - 1;
@@ -614,12 +619,14 @@
   void mov_b(Register dst, Register src) { mov_b(dst, Operand(src)); }
   void mov_b(Register dst, const Operand& src);
   void mov_b(Register dst, int8_t imm8) { mov_b(Operand(dst), imm8); }
-  void mov_b(const Operand& dst, int8_t imm8);
+  void mov_b(const Operand& dst, int8_t src) { mov_b(dst, Immediate(src)); }
+  void mov_b(const Operand& dst, const Immediate& src);
   void mov_b(const Operand& dst, Register src);
 
   void mov_w(Register dst, const Operand& src);
+  void mov_w(const Operand& dst, int16_t src) { mov_w(dst, Immediate(src)); }
+  void mov_w(const Operand& dst, const Immediate& src);
   void mov_w(const Operand& dst, Register src);
-  void mov_w(const Operand& dst, int16_t imm16);
 
   void mov(Register dst, int32_t imm32);
   void mov(Register dst, const Immediate& x);
@@ -735,8 +742,11 @@
 
   void rcl(Register dst, uint8_t imm8);
   void rcr(Register dst, uint8_t imm8);
-  void ror(Register dst, uint8_t imm8);
-  void ror_cl(Register dst);
+
+  void ror(Register dst, uint8_t imm8) { ror(Operand(dst), imm8); }
+  void ror(const Operand& dst, uint8_t imm8);
+  void ror_cl(Register dst) { ror_cl(Operand(dst)); }
+  void ror_cl(const Operand& dst);
 
   void sar(Register dst, uint8_t imm8) { sar(Operand(dst), imm8); }
   void sar(const Operand& dst, uint8_t imm8);
@@ -918,6 +928,17 @@
   void cpuid();
 
   // SSE instructions
+  void addss(XMMRegister dst, XMMRegister src) { addss(dst, Operand(src)); }
+  void addss(XMMRegister dst, const Operand& src);
+  void subss(XMMRegister dst, XMMRegister src) { subss(dst, Operand(src)); }
+  void subss(XMMRegister dst, const Operand& src);
+  void mulss(XMMRegister dst, XMMRegister src) { mulss(dst, Operand(src)); }
+  void mulss(XMMRegister dst, const Operand& src);
+  void divss(XMMRegister dst, XMMRegister src) { divss(dst, Operand(src)); }
+  void divss(XMMRegister dst, const Operand& src);
+
+  void ucomiss(XMMRegister dst, XMMRegister src) { ucomiss(dst, Operand(src)); }
+  void ucomiss(XMMRegister dst, const Operand& src);
   void movaps(XMMRegister dst, XMMRegister src);
   void shufps(XMMRegister dst, XMMRegister src, byte imm8);
 
@@ -950,18 +971,24 @@
 
   void cvtsi2sd(XMMRegister dst, Register src) { cvtsi2sd(dst, Operand(src)); }
   void cvtsi2sd(XMMRegister dst, const Operand& src);
-  void cvtss2sd(XMMRegister dst, XMMRegister src);
-  void cvtsd2ss(XMMRegister dst, XMMRegister src);
-
-  void addsd(XMMRegister dst, XMMRegister src);
+  void cvtss2sd(XMMRegister dst, const Operand& src);
+  void cvtss2sd(XMMRegister dst, XMMRegister src) {
+    cvtss2sd(dst, Operand(src));
+  }
+  void cvtsd2ss(XMMRegister dst, const Operand& src);
+  void cvtsd2ss(XMMRegister dst, XMMRegister src) {
+    cvtsd2ss(dst, Operand(src));
+  }
+  void addsd(XMMRegister dst, XMMRegister src) { addsd(dst, Operand(src)); }
   void addsd(XMMRegister dst, const Operand& src);
-  void subsd(XMMRegister dst, XMMRegister src);
+  void subsd(XMMRegister dst, XMMRegister src) { subsd(dst, Operand(src)); }
   void subsd(XMMRegister dst, const Operand& src);
-  void mulsd(XMMRegister dst, XMMRegister src);
+  void mulsd(XMMRegister dst, XMMRegister src) { mulsd(dst, Operand(src)); }
   void mulsd(XMMRegister dst, const Operand& src);
-  void divsd(XMMRegister dst, XMMRegister src);
+  void divsd(XMMRegister dst, XMMRegister src) { divsd(dst, Operand(src)); }
+  void divsd(XMMRegister dst, const Operand& src);
   void xorpd(XMMRegister dst, XMMRegister src);
-  void sqrtsd(XMMRegister dst, XMMRegister src);
+  void sqrtsd(XMMRegister dst, XMMRegister src) { sqrtsd(dst, Operand(src)); }
   void sqrtsd(XMMRegister dst, const Operand& src);
 
   void andpd(XMMRegister dst, XMMRegister src);
@@ -1016,6 +1043,8 @@
   void por(XMMRegister dst, XMMRegister src);
   void ptest(XMMRegister dst, XMMRegister src);
 
+  void pslld(XMMRegister reg, int8_t shift);
+  void psrld(XMMRegister reg, int8_t shift);
   void psllq(XMMRegister reg, int8_t shift);
   void psllq(XMMRegister dst, XMMRegister src);
   void psrlq(XMMRegister reg, int8_t shift);
@@ -1033,15 +1062,188 @@
   // Parallel XMM operations.
   void movntdqa(XMMRegister dst, const Operand& src);
   void movntdq(const Operand& dst, XMMRegister src);
+
+  // AVX instructions
+  void vfmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmadd132sd(dst, src1, Operand(src2));
+  }
+  void vfmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmadd213sd(dst, src1, Operand(src2));
+  }
+  void vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmadd231sd(dst, src1, Operand(src2));
+  }
+  void vfmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0x99, dst, src1, src2);
+  }
+  void vfmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xa9, dst, src1, src2);
+  }
+  void vfmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xb9, dst, src1, src2);
+  }
+  void vfmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmsub132sd(dst, src1, Operand(src2));
+  }
+  void vfmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmsub213sd(dst, src1, Operand(src2));
+  }
+  void vfmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmsub231sd(dst, src1, Operand(src2));
+  }
+  void vfmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0x9b, dst, src1, src2);
+  }
+  void vfmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xab, dst, src1, src2);
+  }
+  void vfmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xbb, dst, src1, src2);
+  }
+  void vfnmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfnmadd132sd(dst, src1, Operand(src2));
+  }
+  void vfnmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfnmadd213sd(dst, src1, Operand(src2));
+  }
+  void vfnmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfnmadd231sd(dst, src1, Operand(src2));
+  }
+  void vfnmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0x9d, dst, src1, src2);
+  }
+  void vfnmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xad, dst, src1, src2);
+  }
+  void vfnmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xbd, dst, src1, src2);
+  }
+  void vfnmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfnmsub132sd(dst, src1, Operand(src2));
+  }
+  void vfnmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfnmsub213sd(dst, src1, Operand(src2));
+  }
+  void vfnmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfnmsub231sd(dst, src1, Operand(src2));
+  }
+  void vfnmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0x9f, dst, src1, src2);
+  }
+  void vfnmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xaf, dst, src1, src2);
+  }
+  void vfnmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xbf, dst, src1, src2);
+  }
+  void vfmasd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
+
+  void vfmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmadd132ss(dst, src1, Operand(src2));
+  }
+  void vfmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmadd213ss(dst, src1, Operand(src2));
+  }
+  void vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmadd231ss(dst, src1, Operand(src2));
+  }
+  void vfmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0x99, dst, src1, src2);
+  }
+  void vfmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xa9, dst, src1, src2);
+  }
+  void vfmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xb9, dst, src1, src2);
+  }
+  void vfmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmsub132ss(dst, src1, Operand(src2));
+  }
+  void vfmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmsub213ss(dst, src1, Operand(src2));
+  }
+  void vfmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmsub231ss(dst, src1, Operand(src2));
+  }
+  void vfmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0x9b, dst, src1, src2);
+  }
+  void vfmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xab, dst, src1, src2);
+  }
+  void vfmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xbb, dst, src1, src2);
+  }
+  void vfnmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfnmadd132ss(dst, src1, Operand(src2));
+  }
+  void vfnmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfnmadd213ss(dst, src1, Operand(src2));
+  }
+  void vfnmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfnmadd231ss(dst, src1, Operand(src2));
+  }
+  void vfnmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0x9d, dst, src1, src2);
+  }
+  void vfnmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xad, dst, src1, src2);
+  }
+  void vfnmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xbd, dst, src1, src2);
+  }
+  void vfnmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfnmsub132ss(dst, src1, Operand(src2));
+  }
+  void vfnmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfnmsub213ss(dst, src1, Operand(src2));
+  }
+  void vfnmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfnmsub231ss(dst, src1, Operand(src2));
+  }
+  void vfnmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0x9f, dst, src1, src2);
+  }
+  void vfnmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xaf, dst, src1, src2);
+  }
+  void vfnmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xbf, dst, src1, src2);
+  }
+  void vfmass(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
+
+  void vaddsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vaddsd(dst, src1, Operand(src2));
+  }
+  void vaddsd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vsd(0x58, dst, src1, src2);
+  }
+  void vsubsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vsubsd(dst, src1, Operand(src2));
+  }
+  void vsubsd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vsd(0x5c, dst, src1, src2);
+  }
+  void vmulsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vmulsd(dst, src1, Operand(src2));
+  }
+  void vmulsd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vsd(0x59, dst, src1, src2);
+  }
+  void vdivsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vdivsd(dst, src1, Operand(src2));
+  }
+  void vdivsd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vsd(0x5e, dst, src1, src2);
+  }
+  void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
+
   // Prefetch src position into cache level.
   // Level 1, 2 or 3 specifies CPU cache level. Level 0 specifies a
   // non-temporal
   void prefetch(const Operand& src, int level);
   // TODO(lrn): Need SFENCE for movnt?
 
-  // Debugging
-  void Print();
-
   // Check the code size generated from label to here.
   int SizeOfCodeGeneratedSince(Label* label) {
     return pc_offset() - label->pos();
@@ -1139,6 +1341,14 @@
 
   void emit_farith(int b1, int b2, int i);
 
+  // Emit vex prefix
+  enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 };
+  enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128 };
+  enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 };
+  enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x2 };
+  inline void emit_vex_prefix(XMMRegister v, VectorLength l, SIMDPrefix pp,
+                              LeadingOpcode m, VexW w);
+
   // labels
   void print(Label* L);
   void bind_to(Label* L, int pos);
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index c24e77f..5767489 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -160,18 +160,17 @@
       if (!is_api_function) {
         Label allocate;
         // The code below relies on these assumptions.
-        STATIC_ASSERT(JSFunction::kNoSlackTracking == 0);
-        STATIC_ASSERT(Map::ConstructionCount::kShift +
-                      Map::ConstructionCount::kSize == 32);
+        STATIC_ASSERT(Map::Counter::kShift + Map::Counter::kSize == 32);
         // Check if slack tracking is enabled.
         __ mov(esi, FieldOperand(eax, Map::kBitField3Offset));
-        __ shr(esi, Map::ConstructionCount::kShift);
-        __ j(zero, &allocate);  // JSFunction::kNoSlackTracking
+        __ shr(esi, Map::Counter::kShift);
+        __ cmp(esi, Map::kSlackTrackingCounterEnd);
+        __ j(less, &allocate);
         // Decrease generous allocation count.
         __ sub(FieldOperand(eax, Map::kBitField3Offset),
-               Immediate(1 << Map::ConstructionCount::kShift));
+               Immediate(1 << Map::Counter::kShift));
 
-        __ cmp(esi, JSFunction::kFinishSlackTracking);
+        __ cmp(esi, Map::kSlackTrackingCounterEnd);
         __ j(not_equal, &allocate);
 
         __ push(eax);
@@ -182,7 +181,7 @@
 
         __ pop(edi);
         __ pop(eax);
-        __ xor_(esi, esi);  // JSFunction::kNoSlackTracking
+        __ mov(esi, Map::kSlackTrackingCounterEnd - 1);
 
         __ bind(&allocate);
       }
@@ -219,8 +218,8 @@
         Label no_inobject_slack_tracking;
 
         // Check if slack tracking is enabled.
-        __ cmp(esi, JSFunction::kNoSlackTracking);
-        __ j(equal, &no_inobject_slack_tracking);
+        __ cmp(esi, Map::kSlackTrackingCounterEnd);
+        __ j(less, &no_inobject_slack_tracking);
 
         // Allocate object with a slack.
         __ movzx_b(esi,
@@ -1002,17 +1001,21 @@
     __ bind(&loop);
     __ mov(receiver, Operand(ebp, kArgumentsOffset));  // load arguments
 
-    // Use inline caching to speed up access to arguments.
     if (FLAG_vector_ics) {
-      __ mov(VectorLoadICDescriptor::SlotRegister(),
-             Immediate(Smi::FromInt(0)));
+      // TODO(mvstanton): Vector-based ics need additional infrastructure to
+      // be embedded here. For now, just call the runtime.
+      __ push(receiver);
+      __ push(key);
+      __ CallRuntime(Runtime::kGetProperty, 2);
+    } else {
+      // Use inline caching to speed up access to arguments.
+      Handle<Code> ic = CodeFactory::KeyedLoadIC(masm->isolate()).code();
+      __ call(ic, RelocInfo::CODE_TARGET);
+      // It is important that we do not have a test instruction after the
+      // call.  A test instruction after the call is used to indicate that
+      // we have generated an inline version of the keyed load.  In this
+      // case, we know that we are not generating a test instruction next.
     }
-    Handle<Code> ic = CodeFactory::KeyedLoadIC(masm->isolate()).code();
-    __ call(ic, RelocInfo::CODE_TARGET);
-    // It is important that we do not have a test instruction after the
-    // call.  A test instruction after the call is used to indicate that
-    // we have generated an inline version of the keyed load.  In this
-    // case, we know that we are not generating a test instruction next.
 
     // Push the nth argument.
     __ push(eax);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 4e14b69..b75ae3a 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -15,7 +15,7 @@
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -652,9 +652,20 @@
 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
   Label miss;
   Register receiver = LoadDescriptor::ReceiverRegister();
+  if (FLAG_vector_ics) {
+    // With careful management, we won't have to save slot and vector on
+    // the stack. Simply handle the possibly missing case first.
+    // TODO(mvstanton): this code can be more efficient.
+    __ cmp(FieldOperand(receiver, JSFunction::kPrototypeOrInitialMapOffset),
+           Immediate(isolate()->factory()->the_hole_value()));
+    __ j(equal, &miss);
+    __ TryGetFunctionPrototype(receiver, eax, ebx, &miss);
+    __ ret(0);
+  } else {
+    NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, eax,
+                                                            ebx, &miss);
+  }
 
-  NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, eax,
-                                                          ebx, &miss);
   __ bind(&miss);
   PropertyAccessCompiler::TailCallBuiltin(
       masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
@@ -691,6 +702,41 @@
 }
 
 
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+  // Return address is on the stack.
+  Label miss;
+
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register index = LoadDescriptor::NameRegister();
+  Register scratch = edi;
+  DCHECK(!scratch.is(receiver) && !scratch.is(index));
+  Register result = eax;
+  DCHECK(!result.is(scratch));
+  DCHECK(!FLAG_vector_ics ||
+         (!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
+          result.is(VectorLoadICDescriptor::SlotRegister())));
+
+  // StringCharAtGenerator doesn't use the result register until it's passed
+  // the different miss possibilities. If it did, we would have a conflict
+  // when FLAG_vector_ics is true.
+  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+                                          &miss,  // When not a string.
+                                          &miss,  // When not a number.
+                                          &miss,  // When index out of range.
+                                          STRING_INDEX_IS_ARRAY_INDEX,
+                                          RECEIVER_IS_STRING);
+  char_at_generator.GenerateFast(masm);
+  __ ret(0);
+
+  StubRuntimeCallHelper call_helper;
+  char_at_generator.GenerateSlow(masm, call_helper);
+
+  __ bind(&miss);
+  PropertyAccessCompiler::TailCallBuiltin(
+      masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
+
+
 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
   // The key is in edx and the parameter count is in eax.
   DCHECK(edx.is(ArgumentsAccessReadDescriptor::index()));
@@ -2185,6 +2231,10 @@
   // edi - function
   // edx - slot id
   Isolate* isolate = masm->isolate();
+  const int with_types_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
+  const int generic_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
   Label extra_checks_or_miss, slow_start;
   Label slow, non_function, wrap, cont;
   Label have_js_function;
@@ -2224,28 +2274,66 @@
   }
 
   __ bind(&extra_checks_or_miss);
-  Label miss;
+  Label uninitialized, miss;
 
   __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
                            FixedArray::kHeaderSize));
   __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
   __ j(equal, &slow_start);
-  __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate)));
-  __ j(equal, &miss);
 
-  if (!FLAG_trace_ic) {
-    // We are going megamorphic. If the feedback is a JSFunction, it is fine
-    // to handle it here. More complex cases are dealt with in the runtime.
-    __ AssertNotSmi(ecx);
-    __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
-    __ j(not_equal, &miss);
-    __ mov(FieldOperand(ebx, edx, times_half_pointer_size,
-                        FixedArray::kHeaderSize),
-           Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
-    __ jmp(&slow_start);
+  // The following cases attempt to handle MISS cases without going to the
+  // runtime.
+  if (FLAG_trace_ic) {
+    __ jmp(&miss);
   }
 
-  // We are here because tracing is on or we are going monomorphic.
+  __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate)));
+  __ j(equal, &uninitialized);
+
+  // We are going megamorphic. If the feedback is a JSFunction, it is fine
+  // to handle it here. More complex cases are dealt with in the runtime.
+  __ AssertNotSmi(ecx);
+  __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
+  __ j(not_equal, &miss);
+  __ mov(
+      FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize),
+      Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
+  // We have to update statistics for runtime profiling.
+  __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1)));
+  __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1)));
+  __ jmp(&slow_start);
+
+  __ bind(&uninitialized);
+
+  // We are going monomorphic, provided we actually have a JSFunction.
+  __ JumpIfSmi(edi, &miss);
+
+  // Goto miss case if we do not have a function.
+  __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
+  __ j(not_equal, &miss);
+
+  // Make sure the function is not the Array() function, which requires special
+  // behavior on MISS.
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx);
+  __ cmp(edi, ecx);
+  __ j(equal, &miss);
+
+  // Update stats.
+  __ add(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1)));
+
+  // Store the function.
+  __ mov(
+      FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize),
+      edi);
+
+  // Update the write barrier.
+  __ mov(eax, edi);
+  __ RecordWriteArray(ebx, eax, edx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
+                      OMIT_SMI_CHECK);
+  __ jmp(&have_js_function);
+
+  // We are here because tracing is on or we encountered a MISS case we can't
+  // handle here.
   __ bind(&miss);
   GenerateMiss(masm);
 
@@ -2747,14 +2835,16 @@
 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
   // If the receiver is a smi trigger the non-string case.
   STATIC_ASSERT(kSmiTag == 0);
-  __ JumpIfSmi(object_, receiver_not_string_);
+  if (check_mode_ == RECEIVER_IS_UNKNOWN) {
+    __ JumpIfSmi(object_, receiver_not_string_);
 
-  // Fetch the instance type of the receiver into result register.
-  __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
-  __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
-  // If the receiver is not a string trigger the non-string case.
-  __ test(result_, Immediate(kIsNotStringMask));
-  __ j(not_zero, receiver_not_string_);
+    // Fetch the instance type of the receiver into result register.
+    __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
+    __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
+    // If the receiver is not a string trigger the non-string case.
+    __ test(result_, Immediate(kIsNotStringMask));
+    __ j(not_zero, receiver_not_string_);
+  }
 
   // If the index is non-smi trigger the non-smi case.
   STATIC_ASSERT(kSmiTag == 0);
@@ -3126,14 +3216,61 @@
   // ebx: instance type
   // ecx: sub string length (smi)
   // edx: from index (smi)
-  StringCharAtGenerator generator(
-      eax, edx, ecx, eax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
+  StringCharAtGenerator generator(eax, edx, ecx, eax, &runtime, &runtime,
+                                  &runtime, STRING_INDEX_IS_NUMBER,
+                                  RECEIVER_IS_STRING);
   generator.GenerateFast(masm);
   __ ret(3 * kPointerSize);
   generator.SkipSlow(masm, &runtime);
 }
 
 
+void ToNumberStub::Generate(MacroAssembler* masm) {
+  // The ToNumber stub takes one argument in eax.
+  Label not_smi;
+  __ JumpIfNotSmi(eax, &not_smi, Label::kNear);
+  __ Ret();
+  __ bind(&not_smi);
+
+  Label not_heap_number;
+  __ CompareMap(eax, masm->isolate()->factory()->heap_number_map());
+  __ j(not_equal, &not_heap_number, Label::kNear);
+  __ Ret();
+  __ bind(&not_heap_number);
+
+  Label not_string, slow_string;
+  __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edi);
+  // eax: object
+  // edi: object map
+  __ j(above_equal, &not_string, Label::kNear);
+  // Check if string has a cached array index.
+  __ test(FieldOperand(eax, String::kHashFieldOffset),
+          Immediate(String::kContainsCachedArrayIndexMask));
+  __ j(not_zero, &slow_string, Label::kNear);
+  __ mov(eax, FieldOperand(eax, String::kHashFieldOffset));
+  __ IndexFromHash(eax, eax);
+  __ Ret();
+  __ bind(&slow_string);
+  __ pop(ecx);   // Pop return address.
+  __ push(eax);  // Push argument.
+  __ push(ecx);  // Push return address.
+  __ TailCallRuntime(Runtime::kStringToNumber, 1, 1);
+  __ bind(&not_string);
+
+  Label not_oddball;
+  __ CmpInstanceType(edi, ODDBALL_TYPE);
+  __ j(not_equal, &not_oddball, Label::kNear);
+  __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset));
+  __ Ret();
+  __ bind(&not_oddball);
+
+  __ pop(ecx);   // Pop return address.
+  __ push(eax);  // Push argument.
+  __ push(ecx);  // Push return address.
+  __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
+}
+
+
 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm,
                                                    Register left,
                                                    Register right,
diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h
index eabb5a5..0b12fd0 100644
--- a/src/ia32/code-stubs-ia32.h
+++ b/src/ia32/code-stubs-ia32.h
@@ -76,7 +76,7 @@
                                      Register r0,
                                      Register r1);
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
  private:
   static const int kInlinedProbes = 4;
@@ -142,7 +142,7 @@
     INCREMENTAL_COMPACTION
   };
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
   static const byte kTwoByteNopInstruction = 0x3c;  // Cmpb al, #imm8.
   static const byte kTwoByteJumpInstruction = 0xeb;  // Jmp #imm8.
@@ -339,9 +339,9 @@
     kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
   };
 
-  virtual inline Major MajorKey() const FINAL OVERRIDE { return RecordWrite; }
+  inline Major MajorKey() const FINAL { return RecordWrite; }
 
-  virtual void Generate(MacroAssembler* masm) OVERRIDE;
+  void Generate(MacroAssembler* masm) OVERRIDE;
   void GenerateIncremental(MacroAssembler* masm, Mode mode);
   void CheckNeedsToInformIncrementalMarker(
       MacroAssembler* masm,
@@ -349,7 +349,7 @@
       Mode mode);
   void InformIncrementalMarker(MacroAssembler* masm);
 
-  void Activate(Code* code) {
+  void Activate(Code* code) OVERRIDE {
     code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
   }
 
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index 52cf72b..083f5db 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -720,6 +720,19 @@
   __ mov(FieldOperand(eax, FixedArray::kLengthOffset), ebx);
   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
 
+  // Allocating heap numbers in the loop below can fail and cause a jump to
+  // gc_required. We can't leave a partly initialized FixedArray behind,
+  // so pessimistically fill it with holes now.
+  Label initialization_loop, initialization_loop_entry;
+  __ jmp(&initialization_loop_entry, Label::kNear);
+  __ bind(&initialization_loop);
+  __ mov(FieldOperand(eax, ebx, times_2, FixedArray::kHeaderSize),
+         masm->isolate()->factory()->the_hole_value());
+  __ bind(&initialization_loop_entry);
+  __ sub(ebx, Immediate(Smi::FromInt(1)));
+  __ j(not_sign, &initialization_loop);
+
+  __ mov(ebx, FieldOperand(edi, FixedDoubleArray::kLengthOffset));
   __ jmp(&entry);
 
   // ebx: target map
diff --git a/src/ia32/debug-ia32.cc b/src/ia32/debug-ia32.cc
index 4331b08..34b33b2 100644
--- a/src/ia32/debug-ia32.cc
+++ b/src/ia32/debug-ia32.cc
@@ -182,7 +182,11 @@
   // Register state for IC load call (from ic-ia32.cc).
   Register receiver = LoadDescriptor::ReceiverRegister();
   Register name = LoadDescriptor::NameRegister();
-  Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false);
+  RegList regs = receiver.bit() | name.bit();
+  if (FLAG_vector_ics) {
+    regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit();
+  }
+  Generate_DebugBreakCallHelper(masm, regs, 0, false);
 }
 
 
diff --git a/src/ia32/deoptimizer-ia32.cc b/src/ia32/deoptimizer-ia32.cc
index f40e23c..e451fcc 100644
--- a/src/ia32/deoptimizer-ia32.cc
+++ b/src/ia32/deoptimizer-ia32.cc
@@ -27,7 +27,7 @@
   HandleScope scope(isolate);
 
   // Compute the size of relocation information needed for the code
-  // patching in Deoptimizer::DeoptimizeFunction.
+  // patching in Deoptimizer::PatchCodeForDeoptimization below.
   int min_reloc_size = 0;
   int prev_pc_offset = 0;
   DeoptimizationInputData* deopt_data =
diff --git a/src/ia32/disasm-ia32.cc b/src/ia32/disasm-ia32.cc
index 22c2a55..bf88f69 100644
--- a/src/ia32/disasm-ia32.cc
+++ b/src/ia32/disasm-ia32.cc
@@ -246,6 +246,9 @@
   DisassemblerIA32(const NameConverter& converter,
                    bool abort_on_unimplemented = true)
       : converter_(converter),
+        vex_byte0_(0),
+        vex_byte1_(0),
+        vex_byte2_(0),
         instruction_table_(InstructionTable::get_instance()),
         tmp_buffer_pos_(0),
         abort_on_unimplemented_(abort_on_unimplemented) {
@@ -260,6 +263,9 @@
 
  private:
   const NameConverter& converter_;
+  byte vex_byte0_;  // 0xc4 or 0xc5
+  byte vex_byte1_;
+  byte vex_byte2_;  // only for 3 bytes vex prefix
   InstructionTable* instruction_table_;
   v8::internal::EmbeddedVector<char, 128> tmp_buffer_;
   unsigned int tmp_buffer_pos_;
@@ -287,6 +293,57 @@
     kSAR = 7
   };
 
+  bool vex_128() {
+    DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+    byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+    return (checked & 4) != 1;
+  }
+
+  bool vex_66() {
+    DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+    byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+    return (checked & 3) == 1;
+  }
+
+  bool vex_f3() {
+    DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+    byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+    return (checked & 3) == 2;
+  }
+
+  bool vex_f2() {
+    DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+    byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+    return (checked & 3) == 3;
+  }
+
+  bool vex_w() {
+    if (vex_byte0_ == 0xc5) return false;
+    return (vex_byte2_ & 0x80) != 0;
+  }
+
+  bool vex_0f() {
+    if (vex_byte0_ == 0xc5) return true;
+    return (vex_byte1_ & 3) == 1;
+  }
+
+  bool vex_0f38() {
+    if (vex_byte0_ == 0xc5) return false;
+    return (vex_byte1_ & 3) == 2;
+  }
+
+  bool vex_0f3a() {
+    if (vex_byte0_ == 0xc5) return false;
+    return (vex_byte1_ & 3) == 3;
+  }
+
+  int vex_vreg() {
+    DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+    byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+    return ~(checked >> 3) & 0xf;
+  }
+
+  char float_size_code() { return "sd"[vex_w()]; }
 
   const char* NameOfCPURegister(int reg) const {
     return converter_.NameOfCPURegister(reg);
@@ -340,6 +397,7 @@
   int FPUInstruction(byte* data);
   int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start);
   int RegisterFPUInstruction(int escape_opcode, byte modrm_byte);
+  int AVXInstruction(byte* data);
   void AppendToBuffer(const char* format, ...);
 
 
@@ -679,6 +737,111 @@
 }
 
 
+int DisassemblerIA32::AVXInstruction(byte* data) {
+  byte opcode = *data;
+  byte* current = data + 1;
+  if (vex_66() && vex_0f38()) {
+    int mod, regop, rm, vvvv = vex_vreg();
+    get_modrm(*current, &mod, &regop, &rm);
+    switch (opcode) {
+      case 0x99:
+        AppendToBuffer("vfmadd132s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xa9:
+        AppendToBuffer("vfmadd213s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xb9:
+        AppendToBuffer("vfmadd231s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x9b:
+        AppendToBuffer("vfmsub132s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xab:
+        AppendToBuffer("vfmsub213s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xbb:
+        AppendToBuffer("vfmsub231s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x9d:
+        AppendToBuffer("vfnmadd132s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xad:
+        AppendToBuffer("vfnmadd213s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xbd:
+        AppendToBuffer("vfnmadd231s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x9f:
+        AppendToBuffer("vfnmsub132s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xaf:
+        AppendToBuffer("vfnmsub213s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xbf:
+        AppendToBuffer("vfnmsub231s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      default:
+        UnimplementedInstruction();
+    }
+  } else if (vex_f2() && vex_0f()) {
+    int mod, regop, rm, vvvv = vex_vreg();
+    get_modrm(*current, &mod, &regop, &rm);
+    switch (opcode) {
+      case 0x58:
+        AppendToBuffer("vaddsd %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x59:
+        AppendToBuffer("vmulsd %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x5c:
+        AppendToBuffer("vsubsd %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x5e:
+        AppendToBuffer("vdivsd %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      default:
+        UnimplementedInstruction();
+    }
+  } else {
+    UnimplementedInstruction();
+  }
+
+  return static_cast<int>(current - data);
+}
+
+
 // Returns number of bytes used, including *data.
 int DisassemblerIA32::FPUInstruction(byte* data) {
   byte escape_opcode = *data;
@@ -903,65 +1066,81 @@
   } else if (*data == 0x2E /*cs*/) {
     branch_hint = "predicted not taken";
     data++;
+  } else if (*data == 0xC4 && *(data + 1) >= 0xc0) {
+    vex_byte0_ = *data;
+    vex_byte1_ = *(data + 1);
+    vex_byte2_ = *(data + 2);
+    data += 3;
+  } else if (*data == 0xC5 && *(data + 1) >= 0xc0) {
+    vex_byte0_ = *data;
+    vex_byte1_ = *(data + 1);
+    data += 2;
   }
+
   bool processed = true;  // Will be set to false if the current instruction
                           // is not in 'instructions' table.
-  const InstructionDesc& idesc = instruction_table_->Get(*data);
-  switch (idesc.type) {
-    case ZERO_OPERANDS_INSTR:
-      AppendToBuffer(idesc.mnem);
-      data++;
-      break;
+  // Decode AVX instructions.
+  if (vex_byte0_ != 0) {
+    data += AVXInstruction(data);
+  } else {
+    const InstructionDesc& idesc = instruction_table_->Get(*data);
+    switch (idesc.type) {
+      case ZERO_OPERANDS_INSTR:
+        AppendToBuffer(idesc.mnem);
+        data++;
+        break;
 
-    case TWO_OPERANDS_INSTR:
-      data++;
-      data += PrintOperands(idesc.mnem, idesc.op_order_, data);
-      break;
+      case TWO_OPERANDS_INSTR:
+        data++;
+        data += PrintOperands(idesc.mnem, idesc.op_order_, data);
+        break;
 
-    case JUMP_CONDITIONAL_SHORT_INSTR:
-      data += JumpConditionalShort(data, branch_hint);
-      break;
+      case JUMP_CONDITIONAL_SHORT_INSTR:
+        data += JumpConditionalShort(data, branch_hint);
+        break;
 
-    case REGISTER_INSTR:
-      AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
-      data++;
-      break;
+      case REGISTER_INSTR:
+        AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
+        data++;
+        break;
 
-    case MOVE_REG_INSTR: {
-      byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));
-      AppendToBuffer("mov %s,%s",
-                     NameOfCPURegister(*data & 0x07),
-                     NameOfAddress(addr));
-      data += 5;
-      break;
+      case MOVE_REG_INSTR: {
+        byte* addr =
+            reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
+        AppendToBuffer("mov %s,%s", NameOfCPURegister(*data & 0x07),
+                       NameOfAddress(addr));
+        data += 5;
+        break;
+      }
+
+      case CALL_JUMP_INSTR: {
+        byte* addr = data + *reinterpret_cast<int32_t*>(data + 1) + 5;
+        AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr));
+        data += 5;
+        break;
+      }
+
+      case SHORT_IMMEDIATE_INSTR: {
+        byte* addr =
+            reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
+        AppendToBuffer("%s eax,%s", idesc.mnem, NameOfAddress(addr));
+        data += 5;
+        break;
+      }
+
+      case BYTE_IMMEDIATE_INSTR: {
+        AppendToBuffer("%s al,0x%x", idesc.mnem, data[1]);
+        data += 2;
+        break;
+      }
+
+      case NO_INSTR:
+        processed = false;
+        break;
+
+      default:
+        UNIMPLEMENTED();  // This type is not implemented.
     }
-
-    case CALL_JUMP_INSTR: {
-      byte* addr = data + *reinterpret_cast<int32_t*>(data+1) + 5;
-      AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr));
-      data += 5;
-      break;
-    }
-
-    case SHORT_IMMEDIATE_INSTR: {
-      byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));
-      AppendToBuffer("%s eax,%s", idesc.mnem, NameOfAddress(addr));
-      data += 5;
-      break;
-    }
-
-    case BYTE_IMMEDIATE_INSTR: {
-      AppendToBuffer("%s al,0x%x", idesc.mnem, data[1]);
-      data += 2;
-      break;
-    }
-
-    case NO_INSTR:
-      processed = false;
-      break;
-
-    default:
-      UNIMPLEMENTED();  // This type is not implemented.
   }
   //----------------------------
   if (!processed) {
@@ -1047,6 +1226,12 @@
                            NameOfXMMRegister(regop),
                            NameOfXMMRegister(rm));
             data++;
+          } else if (f0byte == 0x2e) {
+            data += 2;
+            int mod, regop, rm;
+            get_modrm(*data, &mod, &regop, &rm);
+            AppendToBuffer("ucomiss %s,", NameOfXMMRegister(regop));
+            data += PrintRightXMMOperand(data);
           } else if (f0byte >= 0x53 && f0byte <= 0x5F) {
             const char* const pseudo_op[] = {
               "rcpps",
@@ -1386,6 +1571,15 @@
                            NameOfXMMRegister(regop),
                            NameOfXMMRegister(rm));
             data++;
+          } else if (*data == 0x72) {
+            data++;
+            int mod, regop, rm;
+            get_modrm(*data, &mod, &regop, &rm);
+            int8_t imm8 = static_cast<int8_t>(data[1]);
+            DCHECK(regop == esi || regop == edx);
+            AppendToBuffer("%s %s,%d", (regop == esi) ? "pslld" : "psrld",
+                           NameOfXMMRegister(rm), static_cast<int>(imm8));
+            data += 2;
           } else if (*data == 0x73) {
             data++;
             int mod, regop, rm;
@@ -1608,12 +1802,36 @@
             get_modrm(*data, &mod, &regop, &rm);
             AppendToBuffer("cvttss2si %s,", NameOfCPURegister(regop));
             data += PrintRightXMMOperand(data);
+          } else if (b2 == 0x58) {
+            data += 3;
+            int mod, regop, rm;
+            get_modrm(*data, &mod, &regop, &rm);
+            AppendToBuffer("addss %s,", NameOfXMMRegister(regop));
+            data += PrintRightXMMOperand(data);
+          } else if (b2 == 0x59) {
+            data += 3;
+            int mod, regop, rm;
+            get_modrm(*data, &mod, &regop, &rm);
+            AppendToBuffer("mulss %s,", NameOfXMMRegister(regop));
+            data += PrintRightXMMOperand(data);
           } else if (b2 == 0x5A) {
             data += 3;
             int mod, regop, rm;
             get_modrm(*data, &mod, &regop, &rm);
             AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop));
             data += PrintRightXMMOperand(data);
+          } else if (b2 == 0x5c) {
+            data += 3;
+            int mod, regop, rm;
+            get_modrm(*data, &mod, &regop, &rm);
+            AppendToBuffer("subss %s,", NameOfXMMRegister(regop));
+            data += PrintRightXMMOperand(data);
+          } else if (b2 == 0x5e) {
+            data += 3;
+            int mod, regop, rm;
+            get_modrm(*data, &mod, &regop, &rm);
+            AppendToBuffer("divss %s,", NameOfXMMRegister(regop));
+            data += PrintRightXMMOperand(data);
           } else if (b2 == 0x6F) {
             data += 3;
             int mod, regop, rm;
@@ -1681,17 +1899,17 @@
 //------------------------------------------------------------------------------
 
 
-static const char* cpu_regs[8] = {
+static const char* const cpu_regs[8] = {
   "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
 };
 
 
-static const char* byte_cpu_regs[8] = {
+static const char* const byte_cpu_regs[8] = {
   "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
 };
 
 
-static const char* xmm_regs[8] = {
+static const char* const xmm_regs[8] = {
   "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
 };
 
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 661d301..1ba4095 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -188,10 +188,10 @@
     Comment cmnt(masm_, "[ Allocate context");
     bool need_write_barrier = true;
     // Argument to NewContext is the function, which is still in edi.
-    if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
+    if (FLAG_harmony_scoping && info->scope()->is_script_scope()) {
       __ push(edi);
       __ Push(info->scope()->GetScopeInfo());
-      __ CallRuntime(Runtime::kNewGlobalContext, 2);
+      __ CallRuntime(Runtime::kNewScriptContext, 2);
     } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
       FastNewContextStub stub(isolate(), heap_slots);
       __ CallStub(&stub);
@@ -872,7 +872,7 @@
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
-  __ LoadContext(eax, scope_->ContextChainLength(scope_->GlobalScope()));
+  __ LoadContext(eax, scope_->ContextChainLength(scope_->ScriptScope()));
   __ mov(eax, ContextOperand(eax, variable->interface()->Index()));
   __ mov(eax, ContextOperand(eax, Context::EXTENSION_INDEX));
 
@@ -1035,7 +1035,7 @@
 
 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   Comment cmnt(masm_, "[ ForInStatement");
-  int slot = stmt->ForInFeedbackSlot();
+  FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
 
   SetStatementPosition(stmt);
 
@@ -1045,6 +1045,7 @@
 
   // Get the object to enumerate over. If the object is null or undefined, skip
   // over the loop.  See ECMA-262 version 5, section 12.6.4.
+  SetExpressionPosition(stmt->enumerable());
   VisitForAccumulatorValue(stmt->enumerable());
   __ cmp(eax, isolate()->factory()->undefined_value());
   __ j(equal, &exit);
@@ -1062,6 +1063,7 @@
   __ push(eax);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ push(eax);
 
   // Check for proxies.
@@ -1083,6 +1085,7 @@
   __ bind(&call_runtime);
   __ push(eax);
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
   __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
          isolate()->factory()->meta_map());
   __ j(not_equal, &fixed_array);
@@ -1117,7 +1120,8 @@
 
   // No need for a write barrier, we are storing a Smi in the feedback vector.
   __ LoadHeapObject(ebx, FeedbackVector());
-  __ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(slot)),
+  int vector_index = FeedbackVector()->GetIndex(slot);
+  __ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(vector_index)),
          Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate())));
 
   __ mov(ebx, Immediate(Smi::FromInt(1)));  // Smi indicates slow check
@@ -1136,6 +1140,8 @@
   // Generate code for doing the condition check.
   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
   __ bind(&loop);
+  SetExpressionPosition(stmt->each());
+
   __ mov(eax, Operand(esp, 0 * kPointerSize));  // Get the current index.
   __ cmp(eax, Operand(esp, 1 * kPointerSize));  // Compare to the array length.
   __ j(above_equal, loop_statement.break_label());
@@ -1202,48 +1208,6 @@
 }
 
 
-void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
-  Comment cmnt(masm_, "[ ForOfStatement");
-  SetStatementPosition(stmt);
-
-  Iteration loop_statement(this, stmt);
-  increment_loop_depth();
-
-  // var iterator = iterable[Symbol.iterator]();
-  VisitForEffect(stmt->assign_iterator());
-
-  // Loop entry.
-  __ bind(loop_statement.continue_label());
-
-  // result = iterator.next()
-  VisitForEffect(stmt->next_result());
-
-  // if (result.done) break;
-  Label result_not_done;
-  VisitForControl(stmt->result_done(),
-                  loop_statement.break_label(),
-                  &result_not_done,
-                  &result_not_done);
-  __ bind(&result_not_done);
-
-  // each = result.value
-  VisitForEffect(stmt->assign_each());
-
-  // Generate code for the body of the loop.
-  Visit(stmt->body());
-
-  // Check stack before looping.
-  PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
-  EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
-  __ jmp(loop_statement.continue_label());
-
-  // Exit and decrement the loop depth.
-  PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
-  __ bind(loop_statement.break_label());
-  decrement_loop_depth();
-}
-
-
 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
                                        bool pretenure) {
   // Use the fast case closure allocation code that allocates in new
@@ -1287,7 +1251,13 @@
   Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
   __ mov(LoadDescriptor::NameRegister(), home_object_symbol);
 
-  CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  if (FLAG_vector_ics) {
+    __ mov(VectorLoadICDescriptor::SlotRegister(),
+           Immediate(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
+    CallLoadIC(NOT_CONTEXTUAL);
+  } else {
+    CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  }
 
   __ cmp(eax, isolate()->factory()->undefined_value());
   Label done;
@@ -1297,6 +1267,19 @@
 }
 
 
+void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
+                                                  int offset) {
+  if (NeedsHomeObject(initializer)) {
+    __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
+    __ mov(StoreDescriptor::NameRegister(),
+           Immediate(isolate()->factory()->home_object_symbol()));
+    __ mov(StoreDescriptor::ValueRegister(),
+           Operand(esp, offset * kPointerSize));
+    CallStoreIC();
+  }
+}
+
+
 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
                                                       TypeofState typeof_state,
                                                       Label* slow) {
@@ -1351,7 +1334,7 @@
   __ mov(LoadDescriptor::NameRegister(), proxy->var()->name());
   if (FLAG_vector_ics) {
     __ mov(VectorLoadICDescriptor::SlotRegister(),
-           Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
+           Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
   }
 
   ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
@@ -1438,7 +1421,7 @@
       __ mov(LoadDescriptor::NameRegister(), var->name());
       if (FLAG_vector_ics) {
         __ mov(VectorLoadICDescriptor::SlotRegister(),
-               Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
+               Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
       }
       CallLoadIC(CONTEXTUAL);
       context()->Plug(eax);
@@ -1622,6 +1605,7 @@
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in eax.
@@ -1650,6 +1634,8 @@
         DCHECK(!CompileTimeValue::IsCompileTimeValue(value));
         // Fall through.
       case ObjectLiteral::Property::COMPUTED:
+        // It is safe to use [[Put]] here because the boilerplate already
+        // contains computed properties with an uninitialized value.
         if (key->value()->IsInternalizedString()) {
           if (property->emit_store()) {
             VisitForAccumulatorValue(value);
@@ -1658,6 +1644,14 @@
             __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
             CallStoreIC(key->LiteralFeedbackId());
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
+
+            if (NeedsHomeObject(value)) {
+              __ mov(StoreDescriptor::ReceiverRegister(), eax);
+              __ mov(StoreDescriptor::NameRegister(),
+                     Immediate(isolate()->factory()->home_object_symbol()));
+              __ mov(StoreDescriptor::ValueRegister(), Operand(esp, 0));
+              CallStoreIC();
+            }
           } else {
             VisitForEffect(value);
           }
@@ -1667,6 +1661,7 @@
         VisitForStackValue(key);
         VisitForStackValue(value);
         if (property->emit_store()) {
+          EmitSetHomeObjectIfNeeded(value, 2);
           __ push(Immediate(Smi::FromInt(SLOPPY)));  // Strict mode
           __ CallRuntime(Runtime::kSetProperty, 4);
         } else {
@@ -1677,7 +1672,7 @@
         __ push(Operand(esp, 0));  // Duplicate receiver.
         VisitForStackValue(value);
         if (property->emit_store()) {
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           __ Drop(2);
         }
@@ -1699,7 +1694,9 @@
     __ push(Operand(esp, 0));  // Duplicate receiver.
     VisitForStackValue(it->first);
     EmitAccessor(it->second->getter);
+    EmitSetHomeObjectIfNeeded(it->second->getter, 2);
     EmitAccessor(it->second->setter);
+    EmitSetHomeObjectIfNeeded(it->second->setter, 3);
     __ push(Immediate(Smi::FromInt(NONE)));
     __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
   }
@@ -1814,22 +1811,23 @@
 
   Comment cmnt(masm_, "[ Assignment");
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
-  if (property != NULL) {
-    assign_type = (property->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(property);
 
   // Evaluate LHS expression.
   switch (assign_type) {
     case VARIABLE:
       // Nothing to do here.
       break;
+    case NAMED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ push(result_register());
+      if (expr->is_compound()) {
+        __ push(MemOperand(esp, kPointerSize));
+        __ push(result_register());
+      }
+      break;
     case NAMED_PROPERTY:
       if (expr->is_compound()) {
         // We need the receiver both on the stack and in the register.
@@ -1839,6 +1837,18 @@
         VisitForStackValue(property->obj());
       }
       break;
+    case KEYED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(property->key());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        __ push(MemOperand(esp, 2 * kPointerSize));
+        __ push(MemOperand(esp, 2 * kPointerSize));
+        __ push(result_register());
+      }
+      break;
     case KEYED_PROPERTY: {
       if (expr->is_compound()) {
         VisitForStackValue(property->obj());
@@ -1863,10 +1873,18 @@
           EmitVariableLoad(expr->target()->AsVariableProxy());
           PrepareForBailout(expr->target(), TOS_REG);
           break;
+        case NAMED_SUPER_PROPERTY:
+          EmitNamedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
         case NAMED_PROPERTY:
           EmitNamedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
           break;
+        case KEYED_SUPER_PROPERTY:
+          EmitKeyedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
         case KEYED_PROPERTY:
           EmitKeyedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
@@ -1912,6 +1930,14 @@
     case NAMED_PROPERTY:
       EmitNamedPropertyAssignment(expr);
       break;
+    case NAMED_SUPER_PROPERTY:
+      EmitNamedSuperPropertyStore(property);
+      context()->Plug(result_register());
+      break;
+    case KEYED_SUPER_PROPERTY:
+      EmitKeyedSuperPropertyStore(property);
+      context()->Plug(result_register());
+      break;
     case KEYED_PROPERTY:
       EmitKeyedPropertyAssignment(expr);
       break;
@@ -2044,7 +2070,7 @@
       __ mov(load_receiver, Operand(esp, kPointerSize));
       if (FLAG_vector_ics) {
         __ mov(VectorLoadICDescriptor::SlotRegister(),
-               Immediate(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
+               Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
       }
       Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
       CallIC(ic, TypeFeedbackId::None());
@@ -2064,7 +2090,7 @@
              isolate()->factory()->done_string());       // "done"
       if (FLAG_vector_ics) {
         __ mov(VectorLoadICDescriptor::SlotRegister(),
-               Immediate(Smi::FromInt(expr->DoneFeedbackSlot())));
+               Immediate(SmiFromSlot(expr->DoneFeedbackSlot())));
       }
       CallLoadIC(NOT_CONTEXTUAL);                        // result.done in eax
       Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
@@ -2078,7 +2104,7 @@
              isolate()->factory()->value_string());       // "value"
       if (FLAG_vector_ics) {
         __ mov(VectorLoadICDescriptor::SlotRegister(),
-               Immediate(Smi::FromInt(expr->ValueFeedbackSlot())));
+               Immediate(SmiFromSlot(expr->ValueFeedbackSlot())));
       }
       CallLoadIC(NOT_CONTEXTUAL);                         // result.value in eax
       context()->DropAndPlug(2, eax);                     // drop iter and g
@@ -2099,15 +2125,6 @@
   VisitForAccumulatorValue(value);
   __ pop(ebx);
 
-  // Check generator state.
-  Label wrong_state, closed_state, done;
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
-  __ cmp(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset),
-         Immediate(Smi::FromInt(0)));
-  __ j(equal, &closed_state);
-  __ j(less, &wrong_state);
-
   // Load suspended function and context.
   __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset));
   __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
@@ -2129,7 +2146,7 @@
 
   // Enter a new JavaScript frame, and initialize its slots as they were when
   // the generator was suspended.
-  Label resume_frame;
+  Label resume_frame, done;
   __ bind(&push_frame);
   __ call(&resume_frame);
   __ jmp(&done);
@@ -2176,25 +2193,6 @@
   // Not reached: the runtime call returns elsewhere.
   __ Abort(kGeneratorFailedToResume);
 
-  // Reach here when generator is closed.
-  __ bind(&closed_state);
-  if (resume_mode == JSGeneratorObject::NEXT) {
-    // Return completed iterator result when generator is closed.
-    __ push(Immediate(isolate()->factory()->undefined_value()));
-    // Pop value from top-of-stack slot; box result into result register.
-    EmitCreateIteratorResult(true);
-  } else {
-    // Throw the provided value.
-    __ push(eax);
-    __ CallRuntime(Runtime::kThrow, 1);
-  }
-  __ jmp(&done);
-
-  // Throw error if we attempt to operate on a running generator.
-  __ bind(&wrong_state);
-  __ push(ebx);
-  __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
-
   __ bind(&done);
   context()->Plug(result_register());
 }
@@ -2204,22 +2202,25 @@
   Label gc_required;
   Label allocated;
 
-  Handle<Map> map(isolate()->native_context()->iterator_result_map());
+  const int instance_size = 5 * kPointerSize;
+  DCHECK_EQ(isolate()->native_context()->iterator_result_map()->instance_size(),
+            instance_size);
 
-  __ Allocate(map->instance_size(), eax, ecx, edx, &gc_required, TAG_OBJECT);
+  __ Allocate(instance_size, eax, ecx, edx, &gc_required, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&gc_required);
-  __ Push(Smi::FromInt(map->instance_size()));
+  __ Push(Smi::FromInt(instance_size));
   __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
   __ mov(context_register(),
          Operand(ebp, StandardFrameConstants::kContextOffset));
 
   __ bind(&allocated);
-  __ mov(ebx, map);
+  __ mov(ebx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+  __ mov(ebx, FieldOperand(ebx, GlobalObject::kNativeContextOffset));
+  __ mov(ebx, ContextOperand(ebx, Context::ITERATOR_RESULT_MAP_INDEX));
   __ pop(ecx);
   __ mov(edx, isolate()->factory()->ToBoolean(done));
-  DCHECK_EQ(map->instance_size(), 5 * kPointerSize);
   __ mov(FieldOperand(eax, HeapObject::kMapOffset), ebx);
   __ mov(FieldOperand(eax, JSObject::kPropertiesOffset),
          isolate()->factory()->empty_fixed_array());
@@ -2239,10 +2240,12 @@
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
   DCHECK(!key->value()->IsSmi());
+  DCHECK(!prop->IsSuperAccess());
+
   __ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
   if (FLAG_vector_ics) {
     __ mov(VectorLoadICDescriptor::SlotRegister(),
-           Immediate(Smi::FromInt(prop->PropertyFeedbackSlot())));
+           Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
     CallLoadIC(NOT_CONTEXTUAL);
   } else {
     CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
@@ -2251,15 +2254,12 @@
 
 
 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object.
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
   DCHECK(!key->value()->IsSmi());
   DCHECK(prop->IsSuperAccess());
 
-  SuperReference* super_ref = prop->obj()->AsSuperReference();
-  EmitLoadHomeObject(super_ref);
-  __ push(eax);
-  VisitForStackValue(super_ref->this_var());
   __ push(Immediate(key->value()));
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 }
@@ -2270,7 +2270,7 @@
   Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
   if (FLAG_vector_ics) {
     __ mov(VectorLoadICDescriptor::SlotRegister(),
-           Immediate(Smi::FromInt(prop->PropertyFeedbackSlot())));
+           Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
     CallIC(ic);
   } else {
     CallIC(ic, prop->PropertyFeedbackId());
@@ -2278,6 +2278,14 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object, key.
+  SetSourcePosition(prop->position());
+
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+}
+
+
 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
                                               Token::Value op,
                                               OverwriteMode mode,
@@ -2373,6 +2381,61 @@
 }
 
 
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
+  // Constructor is in eax.
+  DCHECK(lit != NULL);
+  __ push(eax);
+
+  // No access check is needed here since the constructor is created by the
+  // class literal.
+  Register scratch = ebx;
+  __ mov(scratch, FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset));
+  __ Push(scratch);
+
+  for (int i = 0; i < lit->properties()->length(); i++) {
+    ObjectLiteral::Property* property = lit->properties()->at(i);
+    Literal* key = property->key()->AsLiteral();
+    Expression* value = property->value();
+    DCHECK(key != NULL);
+
+    if (property->is_static()) {
+      __ push(Operand(esp, kPointerSize));  // constructor
+    } else {
+      __ push(Operand(esp, 0));  // prototype
+    }
+    VisitForStackValue(key);
+    VisitForStackValue(value);
+    EmitSetHomeObjectIfNeeded(value, 2);
+
+    switch (property->kind()) {
+      case ObjectLiteral::Property::CONSTANT:
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+      case ObjectLiteral::Property::COMPUTED:
+      case ObjectLiteral::Property::PROTOTYPE:
+        __ CallRuntime(Runtime::kDefineClassMethod, 3);
+        break;
+
+      case ObjectLiteral::Property::GETTER:
+        __ CallRuntime(Runtime::kDefineClassGetter, 3);
+        break;
+
+      case ObjectLiteral::Property::SETTER:
+        __ CallRuntime(Runtime::kDefineClassSetter, 3);
+        break;
+
+      default:
+        UNREACHABLE();
+    }
+  }
+
+  // prototype
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+
+  // constructor
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+}
+
+
 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
                                      Token::Value op,
                                      OverwriteMode mode) {
@@ -2388,16 +2451,8 @@
 void FullCodeGenerator::EmitAssignment(Expression* expr) {
   DCHECK(expr->IsValidReferenceExpression());
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->AsProperty();
-  if (prop != NULL) {
-    assign_type = (prop->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   switch (assign_type) {
     case VARIABLE: {
@@ -2416,6 +2471,42 @@
       CallStoreIC();
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      __ push(eax);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      // stack: value, this; eax: home_object
+      Register scratch = ecx;
+      Register scratch2 = edx;
+      __ mov(scratch, result_register());               // home_object
+      __ mov(eax, MemOperand(esp, kPointerSize));       // value
+      __ mov(scratch2, MemOperand(esp, 0));             // this
+      __ mov(MemOperand(esp, kPointerSize), scratch2);  // this
+      __ mov(MemOperand(esp, 0), scratch);              // home_object
+      // stack: this, home_object. eax: value
+      EmitNamedSuperPropertyStore(prop);
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      __ push(eax);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      __ push(result_register());
+      VisitForAccumulatorValue(prop->key());
+      Register scratch = ecx;
+      Register scratch2 = edx;
+      __ mov(scratch2, MemOperand(esp, 2 * kPointerSize));  // value
+      // stack: value, this, home_object; eax: key, edx: value
+      __ mov(scratch, MemOperand(esp, kPointerSize));  // this
+      __ mov(MemOperand(esp, 2 * kPointerSize), scratch);
+      __ mov(scratch, MemOperand(esp, 0));  // home_object
+      __ mov(MemOperand(esp, kPointerSize), scratch);
+      __ mov(MemOperand(esp, 0), eax);
+      __ mov(eax, scratch2);
+      // stack: this, home_object, key; eax: value.
+      EmitKeyedSuperPropertyStore(prop);
+      break;
+    }
     case KEYED_PROPERTY: {
       __ push(eax);  // Preserve value.
       VisitForStackValue(prop->obj());
@@ -2484,7 +2575,6 @@
     __ CallRuntime(Runtime::kThrowReferenceError, 1);
     __ bind(&assign);
     EmitStoreToStackLocalOrContextSlot(var, location);
-
   } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
     if (var->IsLookupSlot()) {
       // Assignment to var.
@@ -2506,8 +2596,9 @@
       }
       EmitStoreToStackLocalOrContextSlot(var, location);
     }
+  } else if (IsSignallingAssignmentToConst(var, op, strict_mode())) {
+    __ CallRuntime(Runtime::kThrowConstAssignError, 0);
   }
-  // Non-initializing assignments to consts are ignored.
 }
 
 
@@ -2530,6 +2621,34 @@
 }
 
 
+void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // eax : value
+  // stack : receiver ('this'), home_object
+  DCHECK(prop != NULL);
+  Literal* key = prop->key()->AsLiteral();
+  DCHECK(key != NULL);
+
+  __ push(Immediate(key->value()));
+  __ push(eax);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
+                                          : Runtime::kStoreToSuper_Sloppy),
+                 4);
+}
+
+
+void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // eax : value
+  // stack : receiver ('this'), home_object, key
+
+  __ push(eax);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict
+                                          : Runtime::kStoreKeyedToSuper_Sloppy),
+                 4);
+}
+
+
 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
   // Assignment to a property, using a keyed store IC.
   // eax               : value
@@ -2559,16 +2678,27 @@
       __ Move(LoadDescriptor::ReceiverRegister(), result_register());
       EmitNamedPropertyLoad(expr);
     } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ push(result_register());
       EmitNamedSuperPropertyLoad(expr);
     }
     PrepareForBailoutForId(expr->LoadId(), TOS_REG);
     context()->Plug(eax);
   } else {
-    VisitForStackValue(expr->obj());
-    VisitForAccumulatorValue(expr->key());
-    __ pop(LoadDescriptor::ReceiverRegister());                  // Object.
-    __ Move(LoadDescriptor::NameRegister(), result_register());  // Key.
-    EmitKeyedPropertyLoad(expr);
+    if (!expr->IsSuperAccess()) {
+      VisitForStackValue(expr->obj());
+      VisitForAccumulatorValue(expr->key());
+      __ pop(LoadDescriptor::ReceiverRegister());                  // Object.
+      __ Move(LoadDescriptor::NameRegister(), result_register());  // Key.
+      EmitKeyedPropertyLoad(expr);
+    } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ push(result_register());
+      VisitForStackValue(expr->key());
+      EmitKeyedSuperPropertyLoad(expr);
+    }
     context()->Plug(eax);
   }
 }
@@ -2627,14 +2757,14 @@
   __ push(eax);
   VisitForAccumulatorValue(super_ref->this_var());
   __ push(eax);
-  __ push(Operand(esp, kPointerSize));
   __ push(eax);
+  __ push(Operand(esp, kPointerSize * 2));
   __ push(Immediate(key->value()));
   // Stack here:
   //  - home_object
   //  - this (receiver)
-  //  - home_object <-- LoadFromSuper will pop here and below.
-  //  - this (receiver)
+  //  - this (receiver) <-- LoadFromSuper will pop here and below.
+  //  - home_object
   //  - key
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 
@@ -2671,6 +2801,40 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
+  Expression* callee = expr->expression();
+  DCHECK(callee->IsProperty());
+  Property* prop = callee->AsProperty();
+  DCHECK(prop->IsSuperAccess());
+
+  SetSourcePosition(prop->position());
+  // Load the function from the receiver.
+  SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference();
+  EmitLoadHomeObject(super_ref);
+  __ push(eax);
+  VisitForAccumulatorValue(super_ref->this_var());
+  __ push(eax);
+  __ push(eax);
+  __ push(Operand(esp, kPointerSize * 2));
+  VisitForStackValue(prop->key());
+  // Stack here:
+  //  - home_object
+  //  - this (receiver)
+  //  - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
+  //  - home_object
+  //  - key
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+
+  // Replace home_object with target function.
+  __ mov(Operand(esp, kPointerSize), eax);
+
+  // Stack here:
+  // - target function
+  // - this (receiver)
+  EmitCall(expr, CallICState::METHOD);
+}
+
+
 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Load the arguments.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2685,7 +2849,7 @@
   SetSourcePosition(expr->position());
   Handle<Code> ic = CallIC::initialize_stub(
       isolate(), arg_count, call_type);
-  __ Move(edx, Immediate(Smi::FromInt(expr->CallFeedbackSlot())));
+  __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot())));
   __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
   // Don't assign a type feedback id to the IC, since type feedback is provided
   // by the vector above.
@@ -2723,6 +2887,13 @@
 }
 
 
+void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
+  DCHECK(super_ref != NULL);
+  __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
+  __ CallRuntime(Runtime::kGetPrototype, 1);
+}
+
+
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -2758,6 +2929,8 @@
       // edx (receiver). Touch up the stack with the right values.
       __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx);
       __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
+
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
     // Record source position for debugger.
     SetSourcePosition(expr->position());
@@ -2789,6 +2962,7 @@
     __ CallRuntime(Runtime::kLoadLookupSlot, 2);
     __ push(eax);  // Function.
     __ push(edx);  // Receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
 
     // If fast case code has been generated, emit code to push the function
     // and receiver and have the slow path jump around this code.
@@ -2811,9 +2985,12 @@
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
     bool is_named_call = property->key()->IsPropertyName();
-    // super.x() is handled in EmitCallWithLoadIC.
-    if (property->IsSuperAccess() && is_named_call) {
-      EmitSuperCallWithLoadIC(expr);
+    if (property->IsSuperAccess()) {
+      if (is_named_call) {
+        EmitSuperCallWithLoadIC(expr);
+      } else {
+        EmitKeyedSuperCallWithLoadIC(expr);
+      }
     } else {
       {
         PreservePositionScope scope(masm()->positions_recorder());
@@ -2825,6 +3002,12 @@
         EmitKeyedCallWithLoadIC(expr, property->key());
       }
     }
+  } else if (call_type == Call::SUPER_CALL) {
+    SuperReference* super_ref = callee->AsSuperReference();
+    EmitLoadSuperConstructor(super_ref);
+    __ push(result_register());
+    VisitForStackValue(super_ref->this_var());
+    EmitCall(expr, CallICState::METHOD);
   } else {
     DCHECK(call_type == Call::OTHER_CALL);
     // Call to an arbitrary expression not handled specially above.
@@ -2852,7 +3035,12 @@
   // Push constructor on the stack.  If it's not a function it's used as
   // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
   // ignored.
-  VisitForStackValue(expr->expression());
+  if (expr->expression()->IsSuperReference()) {
+    EmitLoadSuperConstructor(expr->expression()->AsSuperReference());
+    __ push(result_register());
+  } else {
+    VisitForStackValue(expr->expression());
+  }
 
   // Push the arguments ("left-to-right") on the stack.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2872,12 +3060,12 @@
   // Record call targets in unoptimized code.
   if (FLAG_pretenuring_call_new) {
     EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
-    DCHECK(expr->AllocationSiteFeedbackSlot() ==
-           expr->CallNewFeedbackSlot() + 1);
+    DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
+           expr->CallNewFeedbackSlot().ToInt() + 1);
   }
 
   __ LoadHeapObject(ebx, FeedbackVector());
-  __ mov(edx, Immediate(Smi::FromInt(expr->CallNewFeedbackSlot())));
+  __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot())));
 
   CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
   __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
@@ -3191,6 +3379,31 @@
 }
 
 
+void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(eax, if_false);
+  Register map = ebx;
+  __ mov(map, FieldOperand(eax, HeapObject::kMapOffset));
+  __ CmpInstanceType(map, FIRST_JS_PROXY_TYPE);
+  __ j(less, if_false);
+  __ CmpInstanceType(map, LAST_JS_PROXY_TYPE);
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(less_equal, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
 
 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
   DCHECK(expr->arguments()->length() == 0);
@@ -4129,7 +4342,7 @@
     __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
     if (FLAG_vector_ics) {
       __ mov(VectorLoadICDescriptor::SlotRegister(),
-             Immediate(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
+             Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
       CallLoadIC(NOT_CONTEXTUAL);
     } else {
       CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
@@ -4290,17 +4503,8 @@
   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());
 
-  // Expression can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
-  // In case of a property we use the uninitialized expression context
-  // of the key to detect a named property.
-  if (prop != NULL) {
-    assign_type =
-        (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   // Evaluate expression and get value.
   if (assign_type == VARIABLE) {
@@ -4312,18 +4516,50 @@
     if (expr->is_postfix() && !context()->IsEffect()) {
       __ push(Immediate(Smi::FromInt(0)));
     }
-    if (assign_type == NAMED_PROPERTY) {
-      // Put the object both on the stack and in the register.
-      VisitForStackValue(prop->obj());
-      __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
-      EmitNamedPropertyLoad(prop);
-    } else {
-      VisitForStackValue(prop->obj());
-      VisitForStackValue(prop->key());
-      __ mov(LoadDescriptor::ReceiverRegister(),
-             Operand(esp, kPointerSize));                       // Object.
-      __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0));  // Key.
-      EmitKeyedPropertyLoad(prop);
+    switch (assign_type) {
+      case NAMED_PROPERTY: {
+        // Put the object both on the stack and in the register.
+        VisitForStackValue(prop->obj());
+        __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
+        EmitNamedPropertyLoad(prop);
+        break;
+      }
+
+      case NAMED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ push(result_register());
+        __ push(MemOperand(esp, kPointerSize));
+        __ push(result_register());
+        EmitNamedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ push(result_register());
+        VisitForAccumulatorValue(prop->key());
+        __ push(result_register());
+        __ push(MemOperand(esp, 2 * kPointerSize));
+        __ push(MemOperand(esp, 2 * kPointerSize));
+        __ push(result_register());
+        EmitKeyedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_PROPERTY: {
+        VisitForStackValue(prop->obj());
+        VisitForStackValue(prop->key());
+        __ mov(LoadDescriptor::ReceiverRegister(),
+               Operand(esp, kPointerSize));                       // Object.
+        __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0));  // Key.
+        EmitKeyedPropertyLoad(prop);
+        break;
+      }
+
+      case VARIABLE:
+        UNREACHABLE();
     }
   }
 
@@ -4355,9 +4591,15 @@
           case NAMED_PROPERTY:
             __ mov(Operand(esp, kPointerSize), eax);
             break;
+          case NAMED_SUPER_PROPERTY:
+            __ mov(Operand(esp, 2 * kPointerSize), eax);
+            break;
           case KEYED_PROPERTY:
             __ mov(Operand(esp, 2 * kPointerSize), eax);
             break;
+          case KEYED_SUPER_PROPERTY:
+            __ mov(Operand(esp, 3 * kPointerSize), eax);
+            break;
         }
       }
     }
@@ -4393,9 +4635,15 @@
         case NAMED_PROPERTY:
           __ mov(Operand(esp, kPointerSize), eax);
           break;
+        case NAMED_SUPER_PROPERTY:
+          __ mov(Operand(esp, 2 * kPointerSize), eax);
+          break;
         case KEYED_PROPERTY:
           __ mov(Operand(esp, 2 * kPointerSize), eax);
           break;
+        case KEYED_SUPER_PROPERTY:
+          __ mov(Operand(esp, 3 * kPointerSize), eax);
+          break;
       }
     }
   }
@@ -4452,6 +4700,28 @@
       }
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      EmitNamedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(eax);
+      }
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      EmitKeyedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(eax);
+      }
+      break;
+    }
     case KEYED_PROPERTY: {
       __ pop(StoreDescriptor::NameRegister());
       __ pop(StoreDescriptor::ReceiverRegister());
@@ -4484,7 +4754,7 @@
     __ mov(LoadDescriptor::NameRegister(), Immediate(proxy->name()));
     if (FLAG_vector_ics) {
       __ mov(VectorLoadICDescriptor::SlotRegister(),
-             Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
+             Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
     }
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
@@ -4719,7 +4989,7 @@
 
 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
   Scope* declaration_scope = scope()->DeclarationScope();
-  if (declaration_scope->is_global_scope() ||
+  if (declaration_scope->is_script_scope() ||
       declaration_scope->is_module_scope()) {
     // Contexts nested in the native context have a canonical empty function
     // as their closure, not the anonymous closure containing the global
diff --git a/src/ia32/interface-descriptors-ia32.cc b/src/ia32/interface-descriptors-ia32.cc
index 3a0d526..6c77ef8 100644
--- a/src/ia32/interface-descriptors-ia32.cc
+++ b/src/ia32/interface-descriptors-ia32.cc
@@ -29,6 +29,9 @@
 const Register StoreDescriptor::ValueRegister() { return eax; }
 
 
+const Register StoreTransitionDescriptor::MapRegister() { return ebx; }
+
+
 const Register ElementTransitionAndStoreDescriptor::MapRegister() {
   return ebx;
 }
@@ -152,6 +155,15 @@
 }
 
 
+void AllocateHeapNumberDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  // register state
+  // esi -- context
+  Register registers[] = {esi};
+  data->Initialize(arraysize(registers), registers, nullptr);
+}
+
+
 void ArrayConstructorConstantArgCountDescriptor::Initialize(
     CallInterfaceDescriptorData* data) {
   // register state
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 1d7c8c1..03a0d8a 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -31,9 +31,9 @@
         deopt_mode_(mode) {}
   virtual ~SafepointGenerator() {}
 
-  virtual void BeforeCall(int call_size) const OVERRIDE {}
+  void BeforeCall(int call_size) const OVERRIDE {}
 
-  virtual void AfterCall() const OVERRIDE {
+  void AfterCall() const OVERRIDE {
     codegen_->RecordSafepoint(pointers_, deopt_mode_);
   }
 
@@ -2627,10 +2627,10 @@
     DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
                                   LInstanceOfKnownGlobal* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
     Label* map_check() { return &map_check_; }
    private:
     LInstanceOfKnownGlobal* instr_;
@@ -2753,6 +2753,7 @@
     }
     __ Ret((parameter_count + extra_value_count) * kPointerSize, ecx);
   } else {
+    DCHECK(info()->IsStub());  // Functions would need to drop one more value.
     Register reg = ToRegister(instr->parameter_count());
     // The argument count parameter is a smi
     __ SmiUntag(reg);
@@ -2770,6 +2771,7 @@
     if (dynamic_frame_alignment) {
       __ inc(reg);  // 1 more for alignment
     }
+
     __ shl(reg, kPointerSizeLog2);
     __ add(esp, reg);
     __ jmp(return_addr_reg);
@@ -2828,13 +2830,18 @@
 template <class T>
 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
   DCHECK(FLAG_vector_ics);
-  Register vector = ToRegister(instr->temp_vector());
-  DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister()));
-  __ mov(vector, instr->hydrogen()->feedback_vector());
+  Register vector_register = ToRegister(instr->temp_vector());
+  Register slot_register = VectorLoadICDescriptor::SlotRegister();
+  DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
+  DCHECK(slot_register.is(eax));
+
+  AllowDeferredHandleDereference vector_structure_check;
+  Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
+  __ mov(vector_register, vector);
   // No need to allocate this register.
-  DCHECK(VectorLoadICDescriptor::SlotRegister().is(eax));
-  __ mov(VectorLoadICDescriptor::SlotRegister(),
-         Immediate(Smi::FromInt(instr->hydrogen()->slot())));
+  FeedbackVectorICSlot slot = instr->hydrogen()->slot();
+  int index = vector->GetIndex(slot);
+  __ mov(slot_register, Immediate(Smi::FromInt(index)));
 }
 
 
@@ -2849,7 +2856,7 @@
     EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
+  Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -2985,7 +2992,8 @@
   if (FLAG_vector_ics) {
     EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
+  Handle<Code> ic =
+      CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3211,7 +3219,7 @@
     EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
-  Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
+  Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3447,45 +3455,81 @@
   Register name = ToRegister(instr->name());
   DCHECK(receiver.is(LoadDescriptor::ReceiverRegister()));
   DCHECK(name.is(LoadDescriptor::NameRegister()));
+  Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg;
+  Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg;
 
   Register scratch = ebx;
-  Register extra = eax;
+  Register extra = edi;
+  DCHECK(!extra.is(slot) && !extra.is(vector));
   DCHECK(!scratch.is(receiver) && !scratch.is(name));
   DCHECK(!extra.is(receiver) && !extra.is(name));
 
   // Important for the tail-call.
   bool must_teardown_frame = NeedsEagerFrame();
 
-  // The probe will tail call to a handler if found.
-  isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
-                                         must_teardown_frame, receiver, name,
-                                         scratch, extra);
+  if (!instr->hydrogen()->is_just_miss()) {
+    if (FLAG_vector_ics) {
+      __ push(slot);
+      __ push(vector);
+    }
+
+    // The probe will tail call to a handler if found.
+    // If --vector-ics is on, then it knows to pop the two args first.
+    DCHECK(!instr->hydrogen()->is_keyed_load());
+    isolate()->stub_cache()->GenerateProbe(
+        masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
+        receiver, name, scratch, extra);
+
+    if (FLAG_vector_ics) {
+      __ pop(vector);
+      __ pop(slot);
+    }
+  }
 
   // Tail call to miss if we ended up here.
   if (must_teardown_frame) __ leave();
-  LoadIC::GenerateMiss(masm());
+  if (instr->hydrogen()->is_keyed_load()) {
+    KeyedLoadIC::GenerateMiss(masm());
+  } else {
+    LoadIC::GenerateMiss(masm());
+  }
 }
 
 
 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
   DCHECK(ToRegister(instr->result()).is(eax));
 
-  LPointerMap* pointers = instr->pointer_map();
-  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+  if (instr->hydrogen()->IsTailCall()) {
+    if (NeedsEagerFrame()) __ leave();
 
-  if (instr->target()->IsConstantOperand()) {
-    LConstantOperand* target = LConstantOperand::cast(instr->target());
-    Handle<Code> code = Handle<Code>::cast(ToHandle(target));
-    generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
-    __ call(code, RelocInfo::CODE_TARGET);
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      __ jmp(code, RelocInfo::CODE_TARGET);
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
+      __ jmp(target);
+    }
   } else {
-    DCHECK(instr->target()->IsRegister());
-    Register target = ToRegister(instr->target());
-    generator.BeforeCall(__ CallSize(Operand(target)));
-    __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
-    __ call(target);
+    LPointerMap* pointers = instr->pointer_map();
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
+      __ call(code, RelocInfo::CODE_TARGET);
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      generator.BeforeCall(__ CallSize(Operand(target)));
+      __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
+      __ call(target);
+    }
+    generator.AfterCall();
   }
-  generator.AfterCall();
 }
 
 
@@ -3581,10 +3625,11 @@
     DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
                                     LMathAbs* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LMathAbs* instr_;
   };
@@ -4335,10 +4380,9 @@
     DeferredStringCharCodeAt(LCodeGen* codegen,
                              LStringCharCodeAt* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredStringCharCodeAt(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredStringCharCodeAt(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStringCharCodeAt* instr_;
   };
@@ -4393,10 +4437,11 @@
     DeferredStringCharFromCode(LCodeGen* codegen,
                                LStringCharFromCode* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredStringCharFromCode(instr_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStringCharFromCode* instr_;
   };
@@ -4471,11 +4516,12 @@
     DeferredNumberTagI(LCodeGen* codegen,
                        LNumberTagI* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredNumberTagIU(
           instr_, instr_->value(), instr_->temp(), SIGNED_INT32);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagI* instr_;
   };
@@ -4497,11 +4543,12 @@
    public:
     DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredNumberTagIU(
           instr_, instr_->value(), instr_->temp(), UNSIGNED_INT32);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagU* instr_;
   };
@@ -4579,10 +4626,9 @@
    public:
     DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredNumberTagD(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredNumberTagD(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagD* instr_;
   };
@@ -4779,10 +4825,9 @@
    public:
     DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredTaggedToI(instr_, done());
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredTaggedToI(instr_, done()); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LTaggedToI* instr_;
   };
@@ -4983,11 +5028,12 @@
         : LDeferredCode(codegen), instr_(instr), object_(object) {
       SetExit(check_maps());
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredInstanceMigration(instr_, object_);
     }
     Label* check_maps() { return &check_maps_; }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LCheckMaps* instr_;
     Label check_maps_;
@@ -5124,10 +5170,9 @@
    public:
     DeferredAllocate(LCodeGen* codegen,  LAllocate* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredAllocate(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredAllocate(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LAllocate* instr_;
   };
@@ -5490,10 +5535,9 @@
    public:
     DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredStackCheck(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredStackCheck(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStackCheck* instr_;
   };
@@ -5640,10 +5684,11 @@
           object_(object),
           index_(index) {
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredLoadMutableDouble(instr_, object_, index_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LLoadFieldByIndex* instr_;
     Register object_;
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 3ed6623..3be2fc4 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <sstream>
+
 #include "src/v8.h"
 
 #if V8_TARGET_ARCH_IA32
@@ -365,9 +367,9 @@
 
 void LStoreNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
-  OStringStream os;
+  std::ostringstream os;
   os << hydrogen()->access() << " <- ";
-  stream->Add(os.c_str());
+  stream->Add(os.str().c_str());
   value()->PrintTo(stream);
 }
 
@@ -737,11 +739,7 @@
     // Shift operations can only deoptimize if we do a logical shift by 0 and
     // the result cannot be truncated to int32.
     if (op == Token::SHR && constant_value == 0) {
-      if (FLAG_opt_safe_uint32_operations) {
-        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-      } else {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
-      }
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
     }
 
     LInstruction* result =
@@ -1140,9 +1138,17 @@
       UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
   LOperand* name_register =
       UseFixed(instr->name(), LoadDescriptor::NameRegister());
+  LOperand* slot = NULL;
+  LOperand* vector = NULL;
+  if (FLAG_vector_ics) {
+    slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
+    vector =
+        UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
+  }
+
   // Not marked as call. It can't deoptimize, and it never returns.
   return new (zone()) LTailCallThroughMegamorphicCache(
-      context, receiver_register, name_register);
+      context, receiver_register, name_register, slot, vector);
 }
 
 
@@ -2117,7 +2123,7 @@
   LOperand* global_object =
       UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
@@ -2178,7 +2184,7 @@
   LOperand* object =
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
   LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(
@@ -2243,7 +2249,7 @@
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
   LLoadKeyedGeneric* result =
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index 75fed82..49eba66 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -167,17 +167,13 @@
   V(WrapReceiver)
 
 
-#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)                        \
-  virtual Opcode opcode() const FINAL OVERRIDE {                      \
-    return LInstruction::k##type;                                           \
-  }                                                                         \
-  virtual void CompileToNative(LCodeGen* generator) FINAL OVERRIDE;   \
-  virtual const char* Mnemonic() const FINAL OVERRIDE {               \
-    return mnemonic;                                                        \
-  }                                                                         \
-  static L##type* cast(LInstruction* instr) {                               \
-    DCHECK(instr->Is##type());                                              \
-    return reinterpret_cast<L##type*>(instr);                               \
+#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)            \
+  Opcode opcode() const FINAL { return LInstruction::k##type; } \
+  void CompileToNative(LCodeGen* generator) FINAL;              \
+  const char* Mnemonic() const FINAL { return mnemonic; }       \
+  static L##type* cast(LInstruction* instr) {                   \
+    DCHECK(instr->Is##type());                                  \
+    return reinterpret_cast<L##type*>(instr);                   \
   }
 
 
@@ -292,11 +288,9 @@
  public:
   // Allow 0 or 1 output operands.
   STATIC_ASSERT(R == 0 || R == 1);
-  virtual bool HasResult() const FINAL OVERRIDE {
-    return R != 0 && result() != NULL;
-  }
+  bool HasResult() const FINAL { return R != 0 && result() != NULL; }
   void set_result(LOperand* operand) { results_[0] = operand; }
-  LOperand* result() const { return results_[0]; }
+  LOperand* result() const OVERRIDE { return results_[0]; }
 
  protected:
   EmbeddedContainer<LOperand*, R> results_;
@@ -314,11 +308,11 @@
 
  private:
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return I; }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return I; }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return T; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return temps_[i]; }
+  int TempCount() FINAL { return T; }
+  LOperand* TempAt(int i) FINAL { return temps_[i]; }
 };
 
 
@@ -332,8 +326,8 @@
   }
 
   // Can't use the DECLARE-macro here because of sub-classes.
-  virtual bool IsGap() const FINAL OVERRIDE { return true; }
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsGap() const FINAL { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   static LGap* cast(LInstruction* instr) {
     DCHECK(instr->IsGap());
     return reinterpret_cast<LGap*>(instr);
@@ -373,7 +367,7 @@
  public:
   explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
     return !IsRedundant();
   }
 
@@ -385,13 +379,13 @@
  public:
   explicit LGoto(HBasicBlock* block) : block_(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
-  virtual bool IsControl() const OVERRIDE { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsControl() const OVERRIDE { return true; }
 
   int block_id() const { return block_->block_id(); }
-  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
+  bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
     return false;
   }
 
@@ -426,7 +420,7 @@
 
 class LDeoptimize FINAL : public LTemplateInstruction<0, 0, 0> {
  public:
-  virtual bool IsControl() const OVERRIDE { return true; }
+  bool IsControl() const OVERRIDE { return true; }
   DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
   DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
 };
@@ -437,12 +431,10 @@
   explicit LLabel(HBasicBlock* block)
       : LGap(block), replacement_(NULL) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Label, "label")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int block_id() const { return block()->block_id(); }
   bool is_loop_header() const { return block()->IsLoopHeader(); }
@@ -460,9 +452,7 @@
 
 class LParameter FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
 };
 
@@ -481,19 +471,23 @@
 
 
 class LTailCallThroughMegamorphicCache FINAL
-    : public LTemplateInstruction<0, 3, 0> {
+    : public LTemplateInstruction<0, 5, 0> {
  public:
-  explicit LTailCallThroughMegamorphicCache(LOperand* context,
-                                            LOperand* receiver,
-                                            LOperand* name) {
+  LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
+                                   LOperand* name, LOperand* slot,
+                                   LOperand* vector) {
     inputs_[0] = context;
     inputs_[1] = receiver;
     inputs_[2] = name;
+    inputs_[3] = slot;
+    inputs_[4] = vector;
   }
 
   LOperand* context() { return inputs_[0]; }
   LOperand* receiver() { return inputs_[1]; }
   LOperand* name() { return inputs_[2]; }
+  LOperand* slot() { return inputs_[3]; }
+  LOperand* vector() { return inputs_[4]; }
 
   DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
                                "tail-call-through-megamorphic-cache")
@@ -503,9 +497,7 @@
 
 class LUnknownOSRValue FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
 };
 
@@ -515,7 +507,7 @@
  public:
   LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
 
-  virtual bool IsControl() const FINAL OVERRIDE { return true; }
+  bool IsControl() const FINAL { return true; }
 
   int SuccessorCount() { return hydrogen()->SuccessorCount(); }
   HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
@@ -608,7 +600,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -857,7 +849,7 @@
     return hydrogen()->representation().IsDouble();
   }
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1038,7 +1030,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1055,7 +1047,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1070,7 +1062,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1088,7 +1080,7 @@
                                "is-undetectable-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1108,7 +1100,7 @@
                                "string-compare-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Token::Value op() const { return hydrogen()->token(); }
 };
@@ -1128,7 +1120,7 @@
                                "has-instance-type-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1157,7 +1149,7 @@
   DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
                                "has-cached-array-index-and-branch")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1190,7 +1182,7 @@
                                "class-of-test-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1391,7 +1383,7 @@
   DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
   DECLARE_HYDROGEN_ACCESSOR(Branch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1542,11 +1534,9 @@
 
   Token::Value op() const { return op_; }
 
-  virtual Opcode opcode() const OVERRIDE {
-    return LInstruction::kArithmeticD;
-  }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticD; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
  private:
   Token::Value op_;
@@ -1569,11 +1559,9 @@
   LOperand* left() { return inputs_[1]; }
   LOperand* right() { return inputs_[2]; }
 
-  virtual Opcode opcode() const OVERRIDE {
-    return LInstruction::kArithmeticT;
-  }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticT; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
   Token::Value op() const { return op_; }
 
@@ -1686,7 +1674,7 @@
   DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
   DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   uint32_t base_offset() const { return hydrogen()->base_offset(); }
   bool key_is_smi() {
     return hydrogen()->key()->representation().IsTagged();
@@ -1784,7 +1772,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1805,7 +1793,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1844,7 +1832,7 @@
   LOperand* function() { return inputs_[0]; }
   LOperand* code_object() { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
   DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
@@ -1861,7 +1849,7 @@
   LOperand* base_object() const { return inputs_[0]; }
   LOperand* offset() const { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
 };
@@ -1905,7 +1893,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
   DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1927,18 +1915,18 @@
  private:
   DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 
   ZoneList<LOperand*> inputs_;
 
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return inputs_.length(); }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return inputs_.length(); }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return 0; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return NULL; }
+  int TempCount() FINAL { return 0; }
+  LOperand* TempAt(int i) FINAL { return NULL; }
 };
 
 
@@ -1955,7 +1943,7 @@
   DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
   DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1991,7 +1979,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
   DECLARE_HYDROGEN_ACCESSOR(CallNew)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -2010,7 +1998,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
   DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -2027,7 +2015,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
   DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
 
-  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
+  bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
     return save_doubles() == kDontSaveFPRegs;
   }
 
@@ -2219,7 +2207,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -2238,7 +2226,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   Handle<Object> name() const { return hydrogen()->name(); }
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
@@ -2269,7 +2257,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   uint32_t base_offset() const { return hydrogen()->base_offset(); }
   bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
 };
@@ -2295,7 +2283,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
@@ -2322,7 +2310,7 @@
                                "transition-elements-kind")
   DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
   Handle<Map> transitioned_map() {
@@ -2612,15 +2600,13 @@
 
   Handle<String> type_literal() { return hydrogen()->type_literal(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
 class LOsrEntry FINAL : public LTemplateInstruction<0, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
 };
 
@@ -2829,7 +2815,7 @@
 
   // An input operand in register, stack slot or a constant operand.
   // Will not be moved to a register even if one is freely available.
-  virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
+  MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
 
   // Temporary operand that must be in a register.
   MUST_USE_RESULT LUnallocated* TempRegister();
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index 7480a6f..38259d7 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -13,7 +13,7 @@
 #include "src/cpu-profiler.h"
 #include "src/debug.h"
 #include "src/isolate-inl.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 #include "src/serialize.h"
 
 namespace v8 {
@@ -345,12 +345,10 @@
 }
 
 
-void MacroAssembler::LoadUint32(XMMRegister dst,
-                                Register src) {
+void MacroAssembler::LoadUint32(XMMRegister dst, const Operand& src) {
   Label done;
   cmp(src, Immediate(0));
-  ExternalReference uint32_bias =
-        ExternalReference::address_of_uint32_bias();
+  ExternalReference uint32_bias = ExternalReference::address_of_uint32_bias();
   Cvtsi2sd(dst, src);
   j(not_sign, &done, Label::kNear);
   addsd(dst, Operand::StaticVariable(uint32_bias));
@@ -742,16 +740,16 @@
 }
 
 
-void MacroAssembler::DispatchMap(Register obj,
-                                 Register unused,
-                                 Handle<Map> map,
-                                 Handle<Code> success,
-                                 SmiCheckType smi_check_type) {
+void MacroAssembler::DispatchWeakMap(Register obj, Register scratch1,
+                                     Register scratch2, Handle<WeakCell> cell,
+                                     Handle<Code> success,
+                                     SmiCheckType smi_check_type) {
   Label fail;
   if (smi_check_type == DO_SMI_CHECK) {
     JumpIfSmi(obj, &fail);
   }
-  cmp(FieldOperand(obj, HeapObject::kMapOffset), Immediate(map));
+  mov(scratch1, FieldOperand(obj, HeapObject::kMapOffset));
+  CmpWeakValue(scratch1, cell, scratch2);
   j(equal, success);
 
   bind(&fail);
@@ -898,6 +896,13 @@
 }
 
 
+void MacroAssembler::EnterFrame(StackFrame::Type type,
+                                bool load_constant_pool_pointer_reg) {
+  // Out-of-line constant pool not implemented on ia32.
+  UNREACHABLE();
+}
+
+
 void MacroAssembler::EnterFrame(StackFrame::Type type) {
   push(ebp);
   mov(ebp, esp);
@@ -937,8 +942,10 @@
   // Save the frame pointer and the context in top.
   ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate());
   ExternalReference context_address(Isolate::kContextAddress, isolate());
+  ExternalReference c_function_address(Isolate::kCFunctionAddress, isolate());
   mov(Operand::StaticVariable(c_entry_fp_address), ebp);
   mov(Operand::StaticVariable(context_address), esi);
+  mov(Operand::StaticVariable(c_function_address), ebx);
 }
 
 
@@ -1349,10 +1356,10 @@
   }
 
   bind(&done);
-  // Check that the value is a normal propety.
+  // Check that the value is a field property.
   const int kDetailsOffset =
       SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
-  DCHECK_EQ(NORMAL, 0);
+  DCHECK_EQ(FIELD, 0);
   test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
        Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize));
   j(not_zero, miss);
@@ -2573,6 +2580,21 @@
 }
 
 
+void MacroAssembler::CmpWeakValue(Register value, Handle<WeakCell> cell,
+                                  Register scratch) {
+  mov(scratch, cell);
+  cmp(value, FieldOperand(scratch, WeakCell::kValueOffset));
+}
+
+
+void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell,
+                                   Label* miss) {
+  mov(value, cell);
+  mov(value, FieldOperand(value, WeakCell::kValueOffset));
+  JumpIfSmi(value, miss);
+}
+
+
 void MacroAssembler::Ret() {
   ret(0);
 }
@@ -2618,18 +2640,65 @@
 }
 
 
-void MacroAssembler::Move(XMMRegister dst, double val) {
-  // TODO(titzer): recognize double constants with ExternalReferences.
-  uint64_t int_val = bit_cast<uint64_t, double>(val);
-  if (int_val == 0) {
-    xorps(dst, dst);
+void MacroAssembler::Move(XMMRegister dst, uint32_t src) {
+  if (src == 0) {
+    pxor(dst, dst);
   } else {
-    int32_t lower = static_cast<int32_t>(int_val);
-    int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt);
-    push(Immediate(upper));
-    push(Immediate(lower));
-    movsd(dst, Operand(esp, 0));
-    add(esp, Immediate(kDoubleSize));
+    unsigned cnt = base::bits::CountPopulation32(src);
+    unsigned nlz = base::bits::CountLeadingZeros32(src);
+    unsigned ntz = base::bits::CountTrailingZeros32(src);
+    if (nlz + cnt + ntz == 32) {
+      pcmpeqd(dst, dst);
+      if (ntz == 0) {
+        psrld(dst, 32 - cnt);
+      } else {
+        pslld(dst, 32 - cnt);
+        if (nlz != 0) psrld(dst, nlz);
+      }
+    } else {
+      push(eax);
+      mov(eax, Immediate(src));
+      movd(dst, Operand(eax));
+      pop(eax);
+    }
+  }
+}
+
+
+void MacroAssembler::Move(XMMRegister dst, uint64_t src) {
+  uint32_t lower = static_cast<uint32_t>(src);
+  uint32_t upper = static_cast<uint32_t>(src >> 32);
+  if (upper == 0) {
+    Move(dst, lower);
+  } else {
+    unsigned cnt = base::bits::CountPopulation64(src);
+    unsigned nlz = base::bits::CountLeadingZeros64(src);
+    unsigned ntz = base::bits::CountTrailingZeros64(src);
+    if (nlz + cnt + ntz == 64) {
+      pcmpeqd(dst, dst);
+      if (ntz == 0) {
+        psrlq(dst, 64 - cnt);
+      } else {
+        psllq(dst, 64 - cnt);
+        if (nlz != 0) psrlq(dst, nlz);
+      }
+    } else if (lower == 0) {
+      Move(dst, upper);
+      psllq(dst, 32);
+    } else if (CpuFeatures::IsSupported(SSE4_1)) {
+      CpuFeatureScope scope(this, SSE4_1);
+      push(eax);
+      Move(eax, Immediate(lower));
+      movd(dst, Operand(eax));
+      Move(eax, Immediate(upper));
+      pinsrd(dst, Operand(eax), 1);
+      pop(eax);
+    } else {
+      push(Immediate(upper));
+      push(Immediate(lower));
+      movsd(dst, Operand(esp, 0));
+      add(esp, Immediate(kDoubleSize));
+    }
   }
 }
 
@@ -3103,18 +3172,6 @@
 }
 
 
-void MacroAssembler::CheckMapDeprecated(Handle<Map> map,
-                                        Register scratch,
-                                        Label* if_deprecated) {
-  if (map->CanBeDeprecated()) {
-    mov(scratch, map);
-    mov(scratch, FieldOperand(scratch, Map::kBitField3Offset));
-    and_(scratch, Immediate(Map::Deprecated::kMask));
-    j(not_zero, if_deprecated);
-  }
-}
-
-
 void MacroAssembler::JumpIfBlack(Register object,
                                  Register scratch0,
                                  Register scratch1,
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index 81347e5..83f6216 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -94,10 +94,6 @@
       Label* condition_met,
       Label::Distance condition_met_distance = Label::kFar);
 
-  void CheckMapDeprecated(Handle<Map> map,
-                          Register scratch,
-                          Label* if_deprecated);
-
   // Check if object is in new space.  Jumps if the object is not in new space.
   // The register scratch can be object itself, but scratch will be clobbered.
   void JumpIfNotInNewSpace(Register object,
@@ -299,6 +295,13 @@
     }
   }
 
+  // Compare the given value and the value of weak cell.
+  void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch);
+
+  // Load the value of the weak cell in the value register. Branch to the given
+  // miss label if the weak cell was cleared.
+  void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss);
+
   // ---------------------------------------------------------------------------
   // JavaScript invokes
 
@@ -408,14 +411,12 @@
                 Label* fail,
                 SmiCheckType smi_check_type);
 
-  // Check if the map of an object is equal to a specified map and branch to a
-  // specified target if equal. Skip the smi check if not required (object is
-  // known to be a heap object)
-  void DispatchMap(Register obj,
-                   Register unused,
-                   Handle<Map> map,
-                   Handle<Code> success,
-                   SmiCheckType smi_check_type);
+  // Check if the map of an object is equal to a specified weak map and branch
+  // to a specified target if equal. Skip the smi check if not required
+  // (object is known to be a heap object)
+  void DispatchWeakMap(Register obj, Register scratch1, Register scratch2,
+                       Handle<WeakCell> cell, Handle<Code> success,
+                       SmiCheckType smi_check_type);
 
   // Check if the object in register heap_object is a string. Afterwards the
   // register map contains the object map and the register instance_type
@@ -486,7 +487,10 @@
     j(not_carry, is_smi);
   }
 
-  void LoadUint32(XMMRegister dst, Register src);
+  void LoadUint32(XMMRegister dst, Register src) {
+    LoadUint32(dst, Operand(src));
+  }
+  void LoadUint32(XMMRegister dst, const Operand& src);
 
   // Jump the register contains a smi.
   inline void JumpIfSmi(Register value,
@@ -839,7 +843,9 @@
   void Move(const Operand& dst, const Immediate& x);
 
   // Move an immediate into an XMM register.
-  void Move(XMMRegister dst, double val);
+  void Move(XMMRegister dst, uint32_t src);
+  void Move(XMMRegister dst, uint64_t src);
+  void Move(XMMRegister dst, double src) { Move(dst, bit_cast<uint64_t>(src)); }
 
   // Push a handle value.
   void Push(Handle<Object> handle) { push(Immediate(handle)); }
@@ -936,6 +942,7 @@
 
   // Activation support.
   void EnterFrame(StackFrame::Type type);
+  void EnterFrame(StackFrame::Type type, bool load_constant_pool_pointer_reg);
   void LeaveFrame(StackFrame::Type type);
 
   // Expects object in eax and returns map with validated enum cache
diff --git a/src/ic/access-compiler.h b/src/ic/access-compiler.h
index 928b70b..fe4369a 100644
--- a/src/ic/access-compiler.h
+++ b/src/ic/access-compiler.h
@@ -40,7 +40,10 @@
         kind_(kind),
         cache_holder_(cache_holder),
         isolate_(isolate),
-        masm_(isolate, NULL, 256) {}
+        masm_(isolate, NULL, 256) {
+    // TODO(yangguo): remove this once we can serialize IC stubs.
+    masm_.enable_serializer();
+  }
 
   Code::Kind kind() const { return kind_; }
   CacheHolderFlag cache_holder() const { return cache_holder_; }
@@ -51,6 +54,14 @@
 
   Register receiver() const { return registers_[0]; }
   Register name() const { return registers_[1]; }
+  Register slot() const {
+    DCHECK(FLAG_vector_ics);
+    return VectorLoadICDescriptor::SlotRegister();
+  }
+  Register vector() const {
+    DCHECK(FLAG_vector_ics);
+    return VectorLoadICDescriptor::VectorRegister();
+  }
   Register scratch1() const { return registers_[2]; }
   Register scratch2() const { return registers_[3]; }
   Register scratch3() const { return registers_[4]; }
diff --git a/src/ic/arm/handler-compiler-arm.cc b/src/ic/arm/handler-compiler-arm.cc
index 5314d48..9905e4e 100644
--- a/src/ic/arm/handler-compiler-arm.cc
+++ b/src/ic/arm/handler-compiler-arm.cc
@@ -92,6 +92,28 @@
 }
 
 
+void PropertyHandlerCompiler::PushVectorAndSlot(Register vector,
+                                                Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ push(vector);
+  __ push(slot);
+}
+
+
+void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ pop(slot);
+  __ pop(vector);
+}
+
+
+void PropertyHandlerCompiler::DiscardVectorAndSlot() {
+  MacroAssembler* masm = this->masm();
+  // Remove vector and slot.
+  __ add(sp, sp, Operand(2 * kPointerSize));
+}
+
+
 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
     MacroAssembler* masm, Label* miss_label, Register receiver,
     Handle<Name> name, Register scratch0, Register scratch1) {
@@ -140,26 +162,16 @@
 
 
 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
-    MacroAssembler* masm, int index, Register prototype, Label* miss) {
-  Isolate* isolate = masm->isolate();
-  // Get the global function with the given index.
-  Handle<JSFunction> function(
-      JSFunction::cast(isolate->native_context()->get(index)));
-
-  // Check we're still in the same context.
-  Register scratch = prototype;
+    MacroAssembler* masm, int index, Register result, Label* miss) {
   const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
-  __ ldr(scratch, MemOperand(cp, offset));
-  __ ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
-  __ ldr(scratch, MemOperand(scratch, Context::SlotOffset(index)));
-  __ Move(ip, function);
-  __ cmp(ip, scratch);
-  __ b(ne, miss);
-
+  __ ldr(result, MemOperand(cp, offset));
+  __ ldr(result, FieldMemOperand(result, GlobalObject::kNativeContextOffset));
+  __ ldr(result, MemOperand(result, Context::SlotOffset(index)));
   // Load its initial map. The global functions all have initial maps.
-  __ Move(prototype, Handle<Map>(function->initial_map()));
+  __ ldr(result,
+         FieldMemOperand(result, JSFunction::kPrototypeOrInitialMapOffset));
   // Load the prototype from the initial map.
-  __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
+  __ ldr(result, FieldMemOperand(result, Map::kPrototypeOffset));
 }
 
 
@@ -326,183 +338,61 @@
 }
 
 
-// Generate StoreTransition code, value is passed in r0 register.
-// When leaving generated code after success, the receiver_reg and name_reg
-// may be clobbered.  Upon branch to miss_label, the receiver and name
-// registers have their original values.
-void NamedStoreHandlerCompiler::GenerateStoreTransition(
-    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
-    Register storage_reg, Register value_reg, Register scratch1,
-    Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
-  // r0 : value
-  Label exit;
-
-  int descriptor = transition->LastAdded();
-  DescriptorArray* descriptors = transition->instance_descriptors();
-  PropertyDetails details = descriptors->GetDetails(descriptor);
-  Representation representation = details.representation();
-  DCHECK(!representation.IsNone());
-
-  if (details.type() == CONSTANT) {
-    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
-    __ Move(scratch1, constant);
-    __ cmp(value_reg, scratch1);
-    __ b(ne, miss_label);
-  } else if (representation.IsSmi()) {
-    __ JumpIfNotSmi(value_reg, miss_label);
-  } else if (representation.IsHeapObject()) {
-    __ JumpIfSmi(value_reg, miss_label);
-    HeapType* field_type = descriptors->GetFieldType(descriptor);
-    HeapType::Iterator<Map> it = field_type->Classes();
-    if (!it.Done()) {
-      __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
-      Label do_store;
-      while (true) {
-        __ CompareMap(scratch1, it.Current(), &do_store);
-        it.Advance();
-        if (it.Done()) {
-          __ b(ne, miss_label);
-          break;
-        }
-        __ b(eq, &do_store);
-      }
-      __ bind(&do_store);
-    }
-  } else if (representation.IsDouble()) {
-    Label do_store, heap_number;
-    __ LoadRoot(scratch3, Heap::kMutableHeapNumberMapRootIndex);
-    __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow,
-                          TAG_RESULT, MUTABLE);
-
-    __ JumpIfNotSmi(value_reg, &heap_number);
-    __ SmiUntag(scratch1, value_reg);
-    __ vmov(s0, scratch1);
-    __ vcvt_f64_s32(d0, s0);
-    __ jmp(&do_store);
-
-    __ bind(&heap_number);
-    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
-                DONT_DO_SMI_CHECK);
-    __ vldr(d0, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
-
-    __ bind(&do_store);
-    __ vstr(d0, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
-  }
-
-  // Stub never generated for objects that require access checks.
-  DCHECK(!transition->is_access_check_needed());
-
-  // Perform map transition for the receiver if necessary.
-  if (details.type() == FIELD &&
-      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
-    // The properties must be extended before we can store the value.
-    // We jump to a runtime call that extends the properties array.
-    __ push(receiver_reg);
-    __ mov(r2, Operand(transition));
-    __ Push(r2, r0);
-    __ TailCallExternalReference(
-        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                          isolate()),
-        3, 1);
-    return;
-  }
-
-  // Update the map of the object.
-  __ mov(scratch1, Operand(transition));
-  __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
-
-  // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
-                      kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
-                      OMIT_SMI_CHECK);
-
-  if (details.type() == CONSTANT) {
-    DCHECK(value_reg.is(r0));
-    __ Ret();
-    return;
-  }
-
-  int index = transition->instance_descriptors()->GetFieldIndex(
-      transition->LastAdded());
-
-  // Adjust for the number of properties stored in the object. Even in the
-  // face of a transition we can use the old map here because the size of the
-  // object and the number of in-object properties is not going to change.
-  index -= transition->inobject_properties();
-
-  // TODO(verwaest): Share this code as a code stub.
-  SmiCheck smi_check =
-      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
-  if (index < 0) {
-    // Set the property straight into the object.
-    int offset = transition->instance_size() + (index * kPointerSize);
-    if (representation.IsDouble()) {
-      __ str(storage_reg, FieldMemOperand(receiver_reg, offset));
-    } else {
-      __ str(value_reg, FieldMemOperand(receiver_reg, offset));
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
-                          kLRHasNotBeenSaved, kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET, smi_check);
-    }
-  } else {
-    // Write to the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    // Get the properties array
-    __ ldr(scratch1,
-           FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
-    if (representation.IsDouble()) {
-      __ str(storage_reg, FieldMemOperand(scratch1, offset));
-    } else {
-      __ str(value_reg, FieldMemOperand(scratch1, offset));
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
-                          kLRHasNotBeenSaved, kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET, smi_check);
-    }
-  }
-
-  // Return the value (register r0).
-  DCHECK(value_reg.is(r0));
-  __ bind(&exit);
-  __ Ret();
+void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
+  __ mov(this->name(), Operand(name));
 }
 
 
-void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
-                                                   Register value_reg,
-                                                   Label* miss_label) {
-  DCHECK(lookup->representation().IsHeapObject());
-  __ JumpIfSmi(value_reg, miss_label);
-  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
-  __ ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
-  Label do_store;
-  while (true) {
-    __ CompareMap(scratch1(), it.Current(), &do_store);
-    it.Advance();
-    if (it.Done()) {
-      __ b(ne, miss_label);
-      break;
-    }
-    __ b(eq, &do_store);
+void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition,
+                                                   Register scratch,
+                                                   Label* miss) {
+  Handle<WeakCell> cell = Map::WeakCellForMap(transition);
+  Register map_reg = StoreTransitionDescriptor::MapRegister();
+  DCHECK(!map_reg.is(scratch));
+  __ LoadWeakValue(map_reg, cell, miss);
+  if (transition->CanBeDeprecated()) {
+    __ ldr(scratch, FieldMemOperand(map_reg, Map::kBitField3Offset));
+    __ tst(scratch, Operand(Map::Deprecated::kMask));
+    __ b(ne, miss);
   }
-  __ bind(&do_store);
+}
 
-  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
-                      lookup->representation());
-  GenerateTailCall(masm(), stub.GetCode());
+
+void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg,
+                                                      int descriptor,
+                                                      Register value_reg,
+                                                      Register scratch,
+                                                      Label* miss_label) {
+  DCHECK(!map_reg.is(scratch));
+  DCHECK(!map_reg.is(value_reg));
+  DCHECK(!value_reg.is(scratch));
+  __ LoadInstanceDescriptors(map_reg, scratch);
+  __ ldr(scratch,
+         FieldMemOperand(scratch, DescriptorArray::GetValueOffset(descriptor)));
+  __ cmp(value_reg, scratch);
+  __ b(ne, miss_label);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
+                                                        Register value_reg,
+                                                        Label* miss_label) {
+  __ JumpIfSmi(value_reg, miss_label);
+  HeapType::Iterator<Map> it = field_type->Classes();
+  if (!it.Done()) {
+    __ ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
+    Label do_store;
+    while (true) {
+      __ CompareMap(scratch1(), it.Current(), &do_store);
+      it.Advance();
+      if (it.Done()) {
+        __ b(ne, miss_label);
+        break;
+      }
+      __ b(eq, &do_store);
+    }
+    __ bind(&do_store);
+  }
 }
 
 
@@ -558,11 +448,11 @@
       __ ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
     } else {
       Register map_reg = scratch1;
+      __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
       if (depth != 1 || check == CHECK_ALL_MAPS) {
-        // CheckMap implicitly loads the map of |reg| into |map_reg|.
-        __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK);
-      } else {
-        __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
+        Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+        __ CmpWeakValue(map_reg, cell, scratch2);
+        __ b(ne, miss);
       }
 
       // Check access rights to the global object.  This has to happen after
@@ -580,17 +470,7 @@
 
       reg = holder_reg;  // From now on the object will be in holder_reg.
 
-      // Two possible reasons for loading the prototype from the map:
-      // (1) Can't store references to new space in code.
-      // (2) Handler is shared for all receivers with the same prototype
-      //     map (but not necessarily the same prototype instance).
-      bool load_prototype_from_map =
-          heap()->InNewSpace(*prototype) || depth == 1;
-      if (load_prototype_from_map) {
-        __ ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
-      } else {
-        __ mov(reg, Operand(prototype));
-      }
+      __ ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
     }
 
     // Go to the next object in the prototype chain.
@@ -603,7 +483,10 @@
 
   if (depth != 0 || check == CHECK_ALL_MAPS) {
     // Check the holder map.
-    __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK);
+    __ ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
+    Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+    __ CmpWeakValue(scratch1, cell, scratch2);
+    __ b(ne, miss);
   }
 
   // Perform security check for access to the global object.
@@ -623,6 +506,10 @@
     Label success;
     __ b(&success);
     __ bind(miss);
+    if (IC::ICUseVector(kind())) {
+      DCHECK(kind() == Code::LOAD_IC);
+      PopVectorAndSlot();
+    }
     TailCallBuiltin(masm(), MissBuiltin(kind()));
     __ bind(&success);
   }
@@ -721,6 +608,7 @@
     } else {
       __ Push(holder_reg, this->name());
     }
+    InterceptorVectorSlotPush(holder_reg);
     // Invoke an interceptor.  Note: map checks from receiver to
     // interceptor's holder has been compiled before (see a caller
     // of this method.)
@@ -738,6 +626,7 @@
     __ Ret();
 
     __ bind(&interceptor_failed);
+    InterceptorVectorSlotPop(holder_reg);
     __ pop(this->name());
     __ pop(holder_reg);
     if (must_preserve_receiver_reg) {
@@ -767,7 +656,7 @@
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     Handle<JSObject> object, Handle<Name> name,
     Handle<ExecutableAccessorInfo> callback) {
-  Register holder_reg = Frontend(receiver(), name);
+  Register holder_reg = Frontend(name);
 
   __ push(receiver());  // receiver
   __ push(holder_reg);
@@ -808,11 +697,15 @@
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
   Label miss;
+  if (IC::ICUseVector(kind())) {
+    PushVectorAndSlot();
+  }
   FrontendHeader(receiver(), name, &miss);
 
   // Get the value from the cell.
   Register result = StoreDescriptor::ValueRegister();
-  __ mov(result, Operand(cell));
+  Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell);
+  __ LoadWeakValue(result, weak_cell, &miss);
   __ ldr(result, FieldMemOperand(result, Cell::kValueOffset));
 
   // Check for deleted property if property can actually be deleted.
@@ -824,6 +717,9 @@
 
   Counters* counters = isolate()->counters();
   __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3);
+  if (IC::ICUseVector(kind())) {
+    DiscardVectorAndSlot();
+  }
   __ Ret();
 
   FrontendFooter(name, &miss);
diff --git a/src/ic/arm/ic-arm.cc b/src/ic/arm/ic-arm.cc
index ae13161..70a5d84 100644
--- a/src/ic/arm/ic-arm.cc
+++ b/src/ic/arm/ic-arm.cc
@@ -265,18 +265,35 @@
 static const Register LoadIC_TempRegister() { return r3; }
 
 
+static void LoadIC_PushArgs(MacroAssembler* masm) {
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register name = LoadDescriptor::NameRegister();
+  if (FLAG_vector_ics) {
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+
+    __ Push(receiver, name, slot, vector);
+  } else {
+    __ Push(receiver, name);
+  }
+}
+
+
 void LoadIC::GenerateMiss(MacroAssembler* masm) {
   // The return address is in lr.
   Isolate* isolate = masm->isolate();
 
-  __ IncrementCounter(isolate->counters()->load_miss(), 1, r3, r4);
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(r4, r5, VectorLoadICDescriptor::SlotRegister(),
+                     VectorLoadICDescriptor::VectorRegister()));
+  __ IncrementCounter(isolate->counters()->load_miss(), 1, r4, r5);
 
-  __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
-  __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
+  LoadIC_PushArgs(masm);
 
   // Perform tail call to the entry.
   ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
@@ -403,15 +420,18 @@
   // The return address is in lr.
   Isolate* isolate = masm->isolate();
 
-  __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4);
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(r4, r5, VectorLoadICDescriptor::SlotRegister(),
+                     VectorLoadICDescriptor::VectorRegister()));
+  __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r4, r5);
 
-  __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
+  LoadIC_PushArgs(masm);
 
   // Perform tail call to the entry.
   ExternalReference ref =
       ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
-
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
@@ -587,32 +607,6 @@
 }
 
 
-void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
-  // Return address is in lr.
-  Label miss;
-
-  Register receiver = LoadDescriptor::ReceiverRegister();
-  Register index = LoadDescriptor::NameRegister();
-  Register scratch = r3;
-  Register result = r0;
-  DCHECK(!scratch.is(receiver) && !scratch.is(index));
-
-  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
-                                          &miss,  // When not a string.
-                                          &miss,  // When not a number.
-                                          &miss,  // When index out of range.
-                                          STRING_INDEX_IS_ARRAY_INDEX);
-  char_at_generator.GenerateFast(masm);
-  __ Ret();
-
-  StubRuntimeCallHelper call_helper;
-  char_at_generator.GenerateSlow(masm, call_helper);
-
-  __ bind(&miss);
-  GenerateMiss(masm);
-}
-
-
 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
   // Push receiver, key and value for runtime call.
   __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
@@ -624,7 +618,7 @@
 }
 
 
-static void KeyedStoreGenerateGenericHelper(
+static void KeyedStoreGenerateMegamorphicHelper(
     MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
     KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
     Register value, Register key, Register receiver, Register receiver_map,
@@ -765,8 +759,8 @@
 }
 
 
-void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
-                                   StrictMode strict_mode) {
+void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
+                                       StrictMode strict_mode) {
   // ---------- S t a t e --------------
   //  -- r0     : value
   //  -- r1     : key
@@ -775,7 +769,7 @@
   // -----------------------------------
   Label slow, fast_object, fast_object_grow;
   Label fast_double, fast_double_grow;
-  Label array, extra, check_if_double_array;
+  Label array, extra, check_if_double_array, maybe_name_key, miss;
 
   // Register usage.
   Register value = StoreDescriptor::ValueRegister();
@@ -790,7 +784,7 @@
   // r4 and r5 are used as general scratch registers.
 
   // Check that the key is a smi.
-  __ JumpIfNotSmi(key, &slow);
+  __ JumpIfNotSmi(key, &maybe_name_key);
   // Check that the object isn't a smi.
   __ JumpIfSmi(receiver, &slow);
   // Get the map of the object.
@@ -822,6 +816,18 @@
   // r1: key.
   // r2: receiver.
   PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
+  // Never returns to here.
+
+  __ bind(&maybe_name_key);
+  __ ldr(r4, FieldMemOperand(key, HeapObject::kMapOffset));
+  __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
+  __ JumpIfNotUniqueNameInstanceType(r4, &slow);
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::STORE_IC));
+  masm->isolate()->stub_cache()->GenerateProbe(
+      masm, Code::STORE_IC, flags, false, receiver, key, r3, r4, r5, r6);
+  // Cache miss.
+  __ b(&miss);
 
   // Extra capacity case: Check if there is extra capacity to
   // perform the store and update the length. Used for adding one
@@ -856,13 +862,16 @@
   __ cmp(key, Operand(ip));
   __ b(hs, &extra);
 
-  KeyedStoreGenerateGenericHelper(
+  KeyedStoreGenerateMegamorphicHelper(
       masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength,
       value, key, receiver, receiver_map, elements_map, elements);
-  KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
-                                  &slow, kDontCheckMap, kIncrementLength, value,
-                                  key, receiver, receiver_map, elements_map,
-                                  elements);
+  KeyedStoreGenerateMegamorphicHelper(masm, &fast_object_grow,
+                                      &fast_double_grow, &slow, kDontCheckMap,
+                                      kIncrementLength, value, key, receiver,
+                                      receiver_map, elements_map, elements);
+
+  __ bind(&miss);
+  GenerateMiss(masm);
 }
 
 
@@ -877,8 +886,8 @@
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::STORE_IC));
 
-  masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver,
-                                               name, r3, r4, r5, r6);
+  masm->isolate()->stub_cache()->GenerateProbe(
+      masm, Code::STORE_IC, flags, false, receiver, name, r3, r4, r5, r6);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
diff --git a/src/ic/arm/ic-compiler-arm.cc b/src/ic/arm/ic-compiler-arm.cc
index 7bef56e..b44702b 100644
--- a/src/ic/arm/ic-compiler-arm.cc
+++ b/src/ic/arm/ic-compiler-arm.cc
@@ -41,9 +41,12 @@
 
   if (check == PROPERTY &&
       (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
-    // In case we are compiling an IC for dictionary loads and stores, just
+    // In case we are compiling an IC for dictionary loads or stores, just
     // check whether the name is unique.
     if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
+      // Keyed loads with dictionaries shouldn't be here, they go generic.
+      // The DCHECK is to protect assumptions when --vector-ics is on.
+      DCHECK(kind() != Code::KEYED_LOAD_IC);
       Register tmp = scratch1();
       __ JumpIfSmi(this->name(), &miss);
       __ ldr(tmp, FieldMemOperand(this->name(), HeapObject::kMapOffset));
@@ -72,8 +75,8 @@
     Handle<Map> map = IC::TypeToMap(*type, isolate());
     if (!map->is_deprecated()) {
       number_of_handled_maps++;
-      __ mov(ip, Operand(map));
-      __ cmp(map_reg, ip);
+      Handle<WeakCell> cell = Map::WeakCellForMap(map);
+      __ CmpWeakValue(map_reg, cell, scratch2());
       if (type->Is(HeapType::Number())) {
         DCHECK(!number_case.is_unused());
         __ bind(&number_case);
@@ -100,16 +103,18 @@
   __ JumpIfSmi(receiver(), &miss);
 
   int receiver_count = receiver_maps->length();
-  __ ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  Register map_reg = scratch1();
+  __ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
   for (int i = 0; i < receiver_count; ++i) {
-    __ mov(ip, Operand(receiver_maps->at(i)));
-    __ cmp(scratch1(), ip);
+    Handle<WeakCell> cell = Map::WeakCellForMap(receiver_maps->at(i));
+    __ CmpWeakValue(map_reg, cell, scratch2());
     if (transitioned_maps->at(i).is_null()) {
       __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq);
     } else {
       Label next_map;
       __ b(ne, &next_map);
-      __ mov(transition_map(), Operand(transitioned_maps->at(i)));
+      Handle<WeakCell> cell = Map::WeakCellForMap(transitioned_maps->at(i));
+      __ LoadWeakValue(transition_map(), cell, &miss);
       __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al);
       __ bind(&next_map);
     }
diff --git a/src/ic/arm/stub-cache-arm.cc b/src/ic/arm/stub-cache-arm.cc
index bc8b0fb..1d6bd30 100644
--- a/src/ic/arm/stub-cache-arm.cc
+++ b/src/ic/arm/stub-cache-arm.cc
@@ -7,7 +7,9 @@
 #if V8_TARGET_ARCH_ARM
 
 #include "src/codegen.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
+#include "src/interface-descriptors.h"
 
 namespace v8 {
 namespace internal {
@@ -16,7 +18,7 @@
 
 
 static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
-                       Code::Flags flags, bool leave_frame,
+                       Code::Kind ic_kind, Code::Flags flags, bool leave_frame,
                        StubCache::Table table, Register receiver, Register name,
                        // Number of the cache entry, not scaled.
                        Register offset, Register scratch, Register scratch2,
@@ -94,10 +96,11 @@
 }
 
 
-void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags,
-                              bool leave_frame, Register receiver,
-                              Register name, Register scratch, Register extra,
-                              Register extra2, Register extra3) {
+void StubCache::GenerateProbe(MacroAssembler* masm, Code::Kind ic_kind,
+                              Code::Flags flags, bool leave_frame,
+                              Register receiver, Register name,
+                              Register scratch, Register extra, Register extra2,
+                              Register extra3) {
   Isolate* isolate = masm->isolate();
   Label miss;
 
@@ -109,15 +112,7 @@
   DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
 
   // Make sure that there are no register conflicts.
-  DCHECK(!scratch.is(receiver));
-  DCHECK(!scratch.is(name));
-  DCHECK(!extra.is(receiver));
-  DCHECK(!extra.is(name));
-  DCHECK(!extra.is(scratch));
-  DCHECK(!extra2.is(receiver));
-  DCHECK(!extra2.is(name));
-  DCHECK(!extra2.is(scratch));
-  DCHECK(!extra2.is(extra));
+  DCHECK(!AreAliased(receiver, name, scratch, extra, extra2, extra3));
 
   // Check scratch, extra and extra2 registers are valid.
   DCHECK(!scratch.is(no_reg));
@@ -125,6 +120,17 @@
   DCHECK(!extra2.is(no_reg));
   DCHECK(!extra3.is(no_reg));
 
+#ifdef DEBUG
+  // If vector-based ics are in use, ensure that scratch, extra, extra2 and
+  // extra3 don't conflict with the vector and slot registers, which need
+  // to be preserved for a handler call or miss.
+  if (IC::ICUseVector(ic_kind)) {
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    DCHECK(!AreAliased(vector, slot, scratch, extra, extra2, extra3));
+  }
+#endif
+
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, extra2,
                       extra3);
@@ -147,8 +153,8 @@
   __ and_(scratch, scratch, Operand(mask));
 
   // Probe the primary table.
-  ProbeTable(isolate, masm, flags, leave_frame, kPrimary, receiver, name,
-             scratch, extra, extra2, extra3);
+  ProbeTable(isolate, masm, ic_kind, flags, leave_frame, kPrimary, receiver,
+             name, scratch, extra, extra2, extra3);
 
   // Primary miss: Compute hash for secondary probe.
   __ sub(scratch, scratch, Operand(name, LSR, kCacheIndexShift));
@@ -157,8 +163,8 @@
   __ and_(scratch, scratch, Operand(mask2));
 
   // Probe the secondary table.
-  ProbeTable(isolate, masm, flags, leave_frame, kSecondary, receiver, name,
-             scratch, extra, extra2, extra3);
+  ProbeTable(isolate, masm, ic_kind, flags, leave_frame, kSecondary, receiver,
+             name, scratch, extra, extra2, extra3);
 
   // Cache miss: Fall-through and let caller handle the miss by
   // entering the runtime system.
diff --git a/src/ic/arm64/handler-compiler-arm64.cc b/src/ic/arm64/handler-compiler-arm64.cc
index f7f82bc..1c28bf5 100644
--- a/src/ic/arm64/handler-compiler-arm64.cc
+++ b/src/ic/arm64/handler-compiler-arm64.cc
@@ -15,6 +15,27 @@
 
 #define __ ACCESS_MASM(masm)
 
+void PropertyHandlerCompiler::PushVectorAndSlot(Register vector,
+                                                Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ Push(vector);
+  __ Push(slot);
+}
+
+
+void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ Pop(slot);
+  __ Pop(vector);
+}
+
+
+void PropertyHandlerCompiler::DiscardVectorAndSlot() {
+  MacroAssembler* masm = this->masm();
+  // Remove vector and slot.
+  __ Drop(2);
+}
+
 
 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
     MacroAssembler* masm, Label* miss_label, Register receiver,
@@ -57,24 +78,15 @@
 
 
 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
-    MacroAssembler* masm, int index, Register prototype, Label* miss) {
-  Isolate* isolate = masm->isolate();
-  // Get the global function with the given index.
-  Handle<JSFunction> function(
-      JSFunction::cast(isolate->native_context()->get(index)));
-
-  // Check we're still in the same context.
-  Register scratch = prototype;
-  __ Ldr(scratch, GlobalObjectMemOperand());
-  __ Ldr(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
-  __ Ldr(scratch, ContextMemOperand(scratch, index));
-  __ Cmp(scratch, Operand(function));
-  __ B(ne, miss);
-
+    MacroAssembler* masm, int index, Register result, Label* miss) {
+  __ Ldr(result, GlobalObjectMemOperand());
+  __ Ldr(result, FieldMemOperand(result, GlobalObject::kNativeContextOffset));
+  __ Ldr(result, ContextMemOperand(result, index));
   // Load its initial map. The global functions all have initial maps.
-  __ Mov(prototype, Operand(Handle<Map>(function->initial_map())));
+  __ Ldr(result,
+         FieldMemOperand(result, JSFunction::kPrototypeOrInitialMapOffset));
   // Load the prototype from the initial map.
-  __ Ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
+  __ Ldr(result, FieldMemOperand(result, Map::kPrototypeOffset));
 }
 
 
@@ -315,11 +327,15 @@
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
   Label miss;
+  if (IC::ICUseVector(kind())) {
+    PushVectorAndSlot();
+  }
   FrontendHeader(receiver(), name, &miss);
 
   // Get the value from the cell.
   Register result = StoreDescriptor::ValueRegister();
-  __ Mov(result, Operand(cell));
+  Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell);
+  __ LoadWeakValue(result, weak_cell, &miss);
   __ Ldr(result, FieldMemOperand(result, Cell::kValueOffset));
 
   // Check for deleted property if property can actually be deleted.
@@ -329,6 +345,9 @@
 
   Counters* counters = isolate()->counters();
   __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3);
+  if (IC::ICUseVector(kind())) {
+    DiscardVectorAndSlot();
+  }
   __ Ret();
 
   FrontendFooter(name, &miss);
@@ -370,176 +389,60 @@
 }
 
 
-// Generate StoreTransition code, value is passed in x0 register.
-// When leaving generated code after success, the receiver_reg and storage_reg
-// may be clobbered. Upon branch to miss_label, the receiver and name registers
-// have their original values.
-void NamedStoreHandlerCompiler::GenerateStoreTransition(
-    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
-    Register storage_reg, Register value_reg, Register scratch1,
-    Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
-  Label exit;
-
-  DCHECK(!AreAliased(receiver_reg, storage_reg, value_reg, scratch1, scratch2,
-                     scratch3));
-
-  // We don't need scratch3.
-  scratch3 = NoReg;
-
-  int descriptor = transition->LastAdded();
-  DescriptorArray* descriptors = transition->instance_descriptors();
-  PropertyDetails details = descriptors->GetDetails(descriptor);
-  Representation representation = details.representation();
-  DCHECK(!representation.IsNone());
-
-  if (details.type() == CONSTANT) {
-    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
-    __ LoadObject(scratch1, constant);
-    __ Cmp(value_reg, scratch1);
-    __ B(ne, miss_label);
-  } else if (representation.IsSmi()) {
-    __ JumpIfNotSmi(value_reg, miss_label);
-  } else if (representation.IsHeapObject()) {
-    __ JumpIfSmi(value_reg, miss_label);
-    HeapType* field_type = descriptors->GetFieldType(descriptor);
-    HeapType::Iterator<Map> it = field_type->Classes();
-    if (!it.Done()) {
-      __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
-      Label do_store;
-      while (true) {
-        __ CompareMap(scratch1, it.Current());
-        it.Advance();
-        if (it.Done()) {
-          __ B(ne, miss_label);
-          break;
-        }
-        __ B(eq, &do_store);
-      }
-      __ Bind(&do_store);
-    }
-  } else if (representation.IsDouble()) {
-    UseScratchRegisterScope temps(masm());
-    DoubleRegister temp_double = temps.AcquireD();
-    __ SmiUntagToDouble(temp_double, value_reg, kSpeculativeUntag);
-
-    Label do_store;
-    __ JumpIfSmi(value_reg, &do_store);
-
-    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
-                DONT_DO_SMI_CHECK);
-    __ Ldr(temp_double, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
-
-    __ Bind(&do_store);
-    __ AllocateHeapNumber(storage_reg, slow, scratch1, scratch2, temp_double,
-                          NoReg, MUTABLE);
-  }
-
-  // Stub never generated for objects that require access checks.
-  DCHECK(!transition->is_access_check_needed());
-
-  // Perform map transition for the receiver if necessary.
-  if (details.type() == FIELD &&
-      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
-    // The properties must be extended before we can store the value.
-    // We jump to a runtime call that extends the properties array.
-    __ Mov(scratch1, Operand(transition));
-    __ Push(receiver_reg, scratch1, value_reg);
-    __ TailCallExternalReference(
-        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                          isolate()),
-        3, 1);
-    return;
-  }
-
-  // Update the map of the object.
-  __ Mov(scratch1, Operand(transition));
-  __ Str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
-
-  // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
-                      kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
-                      OMIT_SMI_CHECK);
-
-  if (details.type() == CONSTANT) {
-    DCHECK(value_reg.is(x0));
-    __ Ret();
-    return;
-  }
-
-  int index = transition->instance_descriptors()->GetFieldIndex(
-      transition->LastAdded());
-
-  // Adjust for the number of properties stored in the object. Even in the
-  // face of a transition we can use the old map here because the size of the
-  // object and the number of in-object properties is not going to change.
-  index -= transition->inobject_properties();
-
-  // TODO(verwaest): Share this code as a code stub.
-  SmiCheck smi_check =
-      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
-  Register prop_reg = representation.IsDouble() ? storage_reg : value_reg;
-  if (index < 0) {
-    // Set the property straight into the object.
-    int offset = transition->instance_size() + (index * kPointerSize);
-    __ Str(prop_reg, FieldMemOperand(receiver_reg, offset));
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ Mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
-                          kLRHasNotBeenSaved, kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET, smi_check);
-    }
-  } else {
-    // Write to the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    // Get the properties array
-    __ Ldr(scratch1,
-           FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
-    __ Str(prop_reg, FieldMemOperand(scratch1, offset));
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ Mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
-                          kLRHasNotBeenSaved, kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET, smi_check);
-    }
-  }
-
-  __ Bind(&exit);
-  // Return the value (register x0).
-  DCHECK(value_reg.is(x0));
-  __ Ret();
+void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
+  __ Mov(this->name(), Operand(name));
 }
 
 
-void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
-                                                   Register value_reg,
-                                                   Label* miss_label) {
-  DCHECK(lookup->representation().IsHeapObject());
-  __ JumpIfSmi(value_reg, miss_label);
-  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
-  __ Ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
-  Label do_store;
-  while (true) {
-    __ CompareMap(scratch1(), it.Current());
-    it.Advance();
-    if (it.Done()) {
-      __ B(ne, miss_label);
-      break;
-    }
-    __ B(eq, &do_store);
+void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition,
+                                                   Register scratch,
+                                                   Label* miss) {
+  Handle<WeakCell> cell = Map::WeakCellForMap(transition);
+  Register map_reg = StoreTransitionDescriptor::MapRegister();
+  DCHECK(!map_reg.is(scratch));
+  __ LoadWeakValue(map_reg, cell, miss);
+  if (transition->CanBeDeprecated()) {
+    __ Ldrsw(scratch, FieldMemOperand(map_reg, Map::kBitField3Offset));
+    __ TestAndBranchIfAnySet(scratch, Map::Deprecated::kMask, miss);
   }
-  __ Bind(&do_store);
+}
 
-  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
-                      lookup->representation());
-  GenerateTailCall(masm(), stub.GetCode());
+
+void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg,
+                                                      int descriptor,
+                                                      Register value_reg,
+                                                      Register scratch,
+                                                      Label* miss_label) {
+  DCHECK(!map_reg.is(scratch));
+  DCHECK(!map_reg.is(value_reg));
+  DCHECK(!value_reg.is(scratch));
+  __ LoadInstanceDescriptors(map_reg, scratch);
+  __ Ldr(scratch,
+         FieldMemOperand(scratch, DescriptorArray::GetValueOffset(descriptor)));
+  __ Cmp(value_reg, scratch);
+  __ B(ne, miss_label);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
+                                                        Register value_reg,
+                                                        Label* miss_label) {
+  __ JumpIfSmi(value_reg, miss_label);
+  HeapType::Iterator<Map> it = field_type->Classes();
+  if (!it.Done()) {
+    __ Ldr(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
+    Label do_store;
+    while (true) {
+      __ CompareMap(scratch1(), it.Current());
+      it.Advance();
+      if (it.Done()) {
+        __ B(ne, miss_label);
+        break;
+      }
+      __ B(eq, &do_store);
+    }
+    __ Bind(&do_store);
+  }
 }
 
 
@@ -592,17 +495,13 @@
       reg = holder_reg;  // From now on the object will be in holder_reg.
       __ Ldr(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
     } else {
-      // Two possible reasons for loading the prototype from the map:
-      // (1) Can't store references to new space in code.
-      // (2) Handler is shared for all receivers with the same prototype
-      //     map (but not necessarily the same prototype instance).
-      bool load_prototype_from_map =
-          heap()->InNewSpace(*prototype) || depth == 1;
       Register map_reg = scratch1;
       __ Ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
 
       if (depth != 1 || check == CHECK_ALL_MAPS) {
-        __ CheckMap(map_reg, current_map, miss, DONT_DO_SMI_CHECK);
+        Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+        __ CmpWeakValue(map_reg, cell, scratch2);
+        __ B(ne, miss);
       }
 
       // Check access rights to the global object.  This has to happen after
@@ -621,11 +520,7 @@
 
       reg = holder_reg;  // From now on the object will be in holder_reg.
 
-      if (load_prototype_from_map) {
-        __ Ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
-      } else {
-        __ Mov(reg, Operand(prototype));
-      }
+      __ Ldr(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
     }
 
     // Go to the next object in the prototype chain.
@@ -639,7 +534,10 @@
   // Check the holder map.
   if (depth != 0 || check == CHECK_ALL_MAPS) {
     // Check the holder map.
-    __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK);
+    __ Ldr(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
+    Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+    __ CmpWeakValue(scratch1, cell, scratch2);
+    __ B(ne, miss);
   }
 
   // Perform security check for access to the global object.
@@ -660,6 +558,10 @@
     __ B(&success);
 
     __ Bind(miss);
+    if (IC::ICUseVector(kind())) {
+      DCHECK(kind() == Code::LOAD_IC);
+      PopVectorAndSlot();
+    }
     TailCallBuiltin(masm(), MissBuiltin(kind()));
 
     __ Bind(&success);
@@ -772,6 +674,7 @@
     } else {
       __ Push(holder_reg, this->name());
     }
+    InterceptorVectorSlotPush(holder_reg);
     // Invoke an interceptor.  Note: map checks from receiver to
     // interceptor's holder has been compiled before (see a caller
     // of this method.)
@@ -788,6 +691,7 @@
     __ Ret();
 
     __ Bind(&interceptor_failed);
+    InterceptorVectorSlotPop(holder_reg);
     if (must_preserve_receiver_reg) {
       __ Pop(this->name(), holder_reg, receiver());
     } else {
@@ -818,7 +722,7 @@
     Handle<JSObject> object, Handle<Name> name,
     Handle<ExecutableAccessorInfo> callback) {
   ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreCallback");
-  Register holder_reg = Frontend(receiver(), name);
+  Register holder_reg = Frontend(name);
 
   // Stub never generated for non-global objects that require access checks.
   DCHECK(holder()->IsJSGlobalProxy() || !holder()->IsAccessCheckNeeded());
diff --git a/src/ic/arm64/ic-arm64.cc b/src/ic/arm64/ic-arm64.cc
index 76f9c24..a01015c 100644
--- a/src/ic/arm64/ic-arm64.cc
+++ b/src/ic/arm64/ic-arm64.cc
@@ -354,12 +354,23 @@
   Isolate* isolate = masm->isolate();
   ASM_LOCATION("LoadIC::GenerateMiss");
 
-  __ IncrementCounter(isolate->counters()->load_miss(), 1, x3, x4);
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(x4, x5, VectorLoadICDescriptor::SlotRegister(),
+                     VectorLoadICDescriptor::VectorRegister()));
+  __ IncrementCounter(isolate->counters()->load_miss(), 1, x4, x5);
 
   // Perform tail call to the entry.
-  __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
+  if (FLAG_vector_ics) {
+    __ Push(VectorLoadICDescriptor::ReceiverRegister(),
+            VectorLoadICDescriptor::NameRegister(),
+            VectorLoadICDescriptor::SlotRegister(),
+            VectorLoadICDescriptor::VectorRegister());
+  } else {
+    __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
+  }
   ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
@@ -420,15 +431,25 @@
   // The return address is in lr.
   Isolate* isolate = masm->isolate();
 
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(x10, x11, VectorLoadICDescriptor::SlotRegister(),
+                     VectorLoadICDescriptor::VectorRegister()));
   __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, x10, x11);
 
-  __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
+  if (FLAG_vector_ics) {
+    __ Push(VectorLoadICDescriptor::ReceiverRegister(),
+            VectorLoadICDescriptor::NameRegister(),
+            VectorLoadICDescriptor::SlotRegister(),
+            VectorLoadICDescriptor::VectorRegister());
+  } else {
+    __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
+  }
 
   // Perform tail call to the entry.
   ExternalReference ref =
       ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
-
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
@@ -627,32 +648,6 @@
 }
 
 
-void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
-  // Return address is in lr.
-  Label miss;
-
-  Register receiver = LoadDescriptor::ReceiverRegister();
-  Register index = LoadDescriptor::NameRegister();
-  Register result = x0;
-  Register scratch = x3;
-  DCHECK(!scratch.is(receiver) && !scratch.is(index));
-
-  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
-                                          &miss,  // When not a string.
-                                          &miss,  // When not a number.
-                                          &miss,  // When index out of range.
-                                          STRING_INDEX_IS_ARRAY_INDEX);
-  char_at_generator.GenerateFast(masm);
-  __ Ret();
-
-  StubRuntimeCallHelper call_helper;
-  char_at_generator.GenerateSlow(masm, call_helper);
-
-  __ Bind(&miss);
-  GenerateMiss(masm);
-}
-
-
 void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
   ASM_LOCATION("KeyedStoreIC::GenerateMiss");
 
@@ -666,7 +661,7 @@
 }
 
 
-static void KeyedStoreGenerateGenericHelper(
+static void KeyedStoreGenerateMegamorphicHelper(
     MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
     KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
     Register value, Register key, Register receiver, Register receiver_map,
@@ -798,9 +793,9 @@
 }
 
 
-void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
-                                   StrictMode strict_mode) {
-  ASM_LOCATION("KeyedStoreIC::GenerateGeneric");
+void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
+                                       StrictMode strict_mode) {
+  ASM_LOCATION("KeyedStoreIC::GenerateMegamorphic");
   Label slow;
   Label array;
   Label fast_object;
@@ -808,6 +803,8 @@
   Label fast_object_grow;
   Label fast_double_grow;
   Label fast_double;
+  Label maybe_name_key;
+  Label miss;
 
   Register value = StoreDescriptor::ValueRegister();
   Register key = StoreDescriptor::NameRegister();
@@ -820,7 +817,7 @@
   Register elements = x4;
   Register elements_map = x5;
 
-  __ JumpIfNotSmi(key, &slow);
+  __ JumpIfNotSmi(key, &maybe_name_key);
   __ JumpIfSmi(receiver, &slow);
   __ Ldr(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
 
@@ -853,7 +850,18 @@
   //  x1: key
   //  x2: receiver
   PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
+  // Never returns to here.
 
+  __ bind(&maybe_name_key);
+  __ Ldr(x10, FieldMemOperand(key, HeapObject::kMapOffset));
+  __ Ldrb(x10, FieldMemOperand(x10, Map::kInstanceTypeOffset));
+  __ JumpIfNotUniqueNameInstanceType(x10, &slow);
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::STORE_IC));
+  masm->isolate()->stub_cache()->GenerateProbe(
+      masm, Code::STORE_IC, flags, false, receiver, key, x3, x4, x5, x6);
+  // Cache miss.
+  __ B(&miss);
 
   __ Bind(&extra);
   // Extra capacity case: Check if there is extra capacity to
@@ -888,13 +896,16 @@
   __ B(eq, &extra);  // We can handle the case where we are appending 1 element.
   __ B(lo, &slow);
 
-  KeyedStoreGenerateGenericHelper(
+  KeyedStoreGenerateMegamorphicHelper(
       masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength,
       value, key, receiver, receiver_map, elements_map, elements);
-  KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
-                                  &slow, kDontCheckMap, kIncrementLength, value,
-                                  key, receiver, receiver_map, elements_map,
-                                  elements);
+  KeyedStoreGenerateMegamorphicHelper(masm, &fast_object_grow,
+                                      &fast_double_grow, &slow, kDontCheckMap,
+                                      kIncrementLength, value, key, receiver,
+                                      receiver_map, elements_map, elements);
+
+  __ bind(&miss);
+  GenerateMiss(masm);
 }
 
 
@@ -907,8 +918,8 @@
   // Probe the stub cache.
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::STORE_IC));
-  masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver,
-                                               name, x3, x4, x5, x6);
+  masm->isolate()->stub_cache()->GenerateProbe(
+      masm, Code::STORE_IC, flags, false, receiver, name, x3, x4, x5, x6);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
diff --git a/src/ic/arm64/ic-compiler-arm64.cc b/src/ic/arm64/ic-compiler-arm64.cc
index ffc1069..a3d0d48 100644
--- a/src/ic/arm64/ic-compiler-arm64.cc
+++ b/src/ic/arm64/ic-compiler-arm64.cc
@@ -42,9 +42,12 @@
 
   if (check == PROPERTY &&
       (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
-    // In case we are compiling an IC for dictionary loads and stores, just
+    // In case we are compiling an IC for dictionary loads or stores, just
     // check whether the name is unique.
     if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
+      // Keyed loads with dictionaries shouldn't be here, they go generic.
+      // The DCHECK is to protect assumptions when --vector-ics is on.
+      DCHECK(kind() != Code::KEYED_LOAD_IC);
       Register tmp = scratch1();
       __ JumpIfSmi(this->name(), &miss);
       __ Ldr(tmp, FieldMemOperand(this->name(), HeapObject::kMapOffset));
@@ -71,8 +74,9 @@
     Handle<Map> map = IC::TypeToMap(*type, isolate());
     if (!map->is_deprecated()) {
       number_of_handled_maps++;
+      Handle<WeakCell> cell = Map::WeakCellForMap(map);
+      __ CmpWeakValue(map_reg, cell, scratch2());
       Label try_next;
-      __ Cmp(map_reg, Operand(map));
       __ B(ne, &try_next);
       if (type->Is(HeapType::Number())) {
         DCHECK(!number_case.is_unused());
@@ -104,16 +108,18 @@
   __ JumpIfSmi(receiver(), &miss);
 
   int receiver_count = receiver_maps->length();
-  __ Ldr(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  Register map_reg = scratch1();
+  __ Ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
   for (int i = 0; i < receiver_count; i++) {
-    __ Cmp(scratch1(), Operand(receiver_maps->at(i)));
-
+    Handle<WeakCell> cell = Map::WeakCellForMap(receiver_maps->at(i));
+    __ CmpWeakValue(map_reg, cell, scratch2());
     Label skip;
     __ B(&skip, ne);
     if (!transitioned_maps->at(i).is_null()) {
       // This argument is used by the handler stub. For example, see
       // ElementsTransitionGenerator::GenerateMapChangeElementsTransition.
-      __ Mov(transition_map(), Operand(transitioned_maps->at(i)));
+      Handle<WeakCell> cell = Map::WeakCellForMap(transitioned_maps->at(i));
+      __ LoadWeakValue(transition_map(), cell, &miss);
     }
     __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
     __ Bind(&skip);
diff --git a/src/ic/arm64/stub-cache-arm64.cc b/src/ic/arm64/stub-cache-arm64.cc
index 4d31d49..a9c56a3 100644
--- a/src/ic/arm64/stub-cache-arm64.cc
+++ b/src/ic/arm64/stub-cache-arm64.cc
@@ -7,7 +7,9 @@
 #if V8_TARGET_ARCH_ARM64
 
 #include "src/codegen.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
+#include "src/interface-descriptors.h"
 
 namespace v8 {
 namespace internal {
@@ -23,7 +25,7 @@
 //
 // 'receiver', 'name' and 'offset' registers are preserved on miss.
 static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
-                       Code::Flags flags, bool leave_frame,
+                       Code::Kind ic_kind, Code::Flags flags, bool leave_frame,
                        StubCache::Table table, Register receiver, Register name,
                        Register offset, Register scratch, Register scratch2,
                        Register scratch3) {
@@ -90,10 +92,11 @@
 }
 
 
-void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags,
-                              bool leave_frame, Register receiver,
-                              Register name, Register scratch, Register extra,
-                              Register extra2, Register extra3) {
+void StubCache::GenerateProbe(MacroAssembler* masm, Code::Kind ic_kind,
+                              Code::Flags flags, bool leave_frame,
+                              Register receiver, Register name,
+                              Register scratch, Register extra, Register extra2,
+                              Register extra3) {
   Isolate* isolate = masm->isolate();
   Label miss;
 
@@ -108,6 +111,17 @@
   DCHECK(!extra2.is(no_reg));
   DCHECK(!extra3.is(no_reg));
 
+#ifdef DEBUG
+  // If vector-based ics are in use, ensure that scratch, extra, extra2 and
+  // extra3 don't conflict with the vector and slot registers, which need
+  // to be preserved for a handler call or miss.
+  if (IC::ICUseVector(ic_kind)) {
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    DCHECK(!AreAliased(vector, slot, scratch, extra, extra2, extra3));
+  }
+#endif
+
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, extra2,
                       extra3);
@@ -125,8 +139,8 @@
           CountTrailingZeros(kPrimaryTableSize, 64));
 
   // Probe the primary table.
-  ProbeTable(isolate, masm, flags, leave_frame, kPrimary, receiver, name,
-             scratch, extra, extra2, extra3);
+  ProbeTable(isolate, masm, ic_kind, flags, leave_frame, kPrimary, receiver,
+             name, scratch, extra, extra2, extra3);
 
   // Primary miss: Compute hash for secondary table.
   __ Sub(scratch, scratch, Operand(name, LSR, kCacheIndexShift));
@@ -134,8 +148,8 @@
   __ And(scratch, scratch, kSecondaryTableSize - 1);
 
   // Probe the secondary table.
-  ProbeTable(isolate, masm, flags, leave_frame, kSecondary, receiver, name,
-             scratch, extra, extra2, extra3);
+  ProbeTable(isolate, masm, ic_kind, flags, leave_frame, kSecondary, receiver,
+             name, scratch, extra, extra2, extra3);
 
   // Cache miss: Fall-through and let caller handle the miss by
   // entering the runtime system.
diff --git a/src/ic/handler-compiler.cc b/src/ic/handler-compiler.cc
index 4ed92ec..ae977c3 100644
--- a/src/ic/handler-compiler.cc
+++ b/src/ic/handler-compiler.cc
@@ -129,11 +129,17 @@
 }
 
 
-Register PropertyHandlerCompiler::Frontend(Register object_reg,
-                                           Handle<Name> name) {
+Register PropertyHandlerCompiler::Frontend(Handle<Name> name) {
   Label miss;
-  Register reg = FrontendHeader(object_reg, name, &miss);
+  if (IC::ICUseVector(kind())) {
+    PushVectorAndSlot();
+  }
+  Register reg = FrontendHeader(receiver(), name, &miss);
   FrontendFooter(name, &miss);
+  // The footer consumes the vector and slot from the stack if miss occurs.
+  if (IC::ICUseVector(kind())) {
+    DiscardVectorAndSlot();
+  }
   return reg;
 }
 
@@ -179,7 +185,7 @@
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadField(Handle<Name> name,
                                                         FieldIndex field) {
-  Register reg = Frontend(receiver(), name);
+  Register reg = Frontend(name);
   __ Move(receiver(), reg);
   LoadFieldStub stub(isolate(), field);
   GenerateTailCall(masm(), stub.GetCode());
@@ -189,7 +195,7 @@
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(Handle<Name> name,
                                                            int constant_index) {
-  Register reg = Frontend(receiver(), name);
+  Register reg = Frontend(name);
   __ Move(receiver(), reg);
   LoadConstantStub stub(isolate(), constant_index);
   GenerateTailCall(masm(), stub.GetCode());
@@ -200,7 +206,14 @@
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent(
     Handle<Name> name) {
   Label miss;
+  if (IC::ICUseVector(kind())) {
+    DCHECK(kind() == Code::LOAD_IC);
+    PushVectorAndSlot();
+  }
   NonexistentFrontendHeader(name, &miss, scratch2(), scratch3());
+  if (IC::ICUseVector(kind())) {
+    DiscardVectorAndSlot();
+  }
   GenerateLoadConstant(isolate()->factory()->undefined_value());
   FrontendFooter(name, &miss);
   return GetCode(kind(), Code::FAST, name);
@@ -209,7 +222,7 @@
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
     Handle<Name> name, Handle<ExecutableAccessorInfo> callback) {
-  Register reg = Frontend(receiver(), name);
+  Register reg = Frontend(name);
   GenerateLoadCallback(reg, callback);
   return GetCode(kind(), Code::FAST, name);
 }
@@ -218,7 +231,7 @@
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadCallback(
     Handle<Name> name, const CallOptimization& call_optimization) {
   DCHECK(call_optimization.is_simple_api_call());
-  Frontend(receiver(), name);
+  Frontend(name);
   Handle<Map> receiver_map = IC::TypeToMap(*type(), isolate());
   GenerateFastApiCall(masm(), call_optimization, receiver_map, receiver(),
                       scratch1(), false, 0, NULL);
@@ -226,6 +239,35 @@
 }
 
 
+void NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) {
+  if (IC::ICUseVector(kind())) {
+    if (holder_reg.is(receiver())) {
+      PushVectorAndSlot();
+    } else {
+      DCHECK(holder_reg.is(scratch1()));
+      PushVectorAndSlot(scratch2(), scratch3());
+    }
+  }
+}
+
+
+void NamedLoadHandlerCompiler::InterceptorVectorSlotPop(Register holder_reg,
+                                                        PopMode mode) {
+  if (IC::ICUseVector(kind())) {
+    if (mode == DISCARD) {
+      DiscardVectorAndSlot();
+    } else {
+      if (holder_reg.is(receiver())) {
+        PopVectorAndSlot();
+      } else {
+        DCHECK(holder_reg.is(scratch1()));
+        PopVectorAndSlot(scratch2(), scratch3());
+      }
+    }
+  }
+}
+
+
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor(
     LookupIterator* it) {
   // So far the most popular follow ups for interceptor loads are FIELD and
@@ -241,7 +283,8 @@
     case LookupIterator::NOT_FOUND:
       break;
     case LookupIterator::DATA:
-      inline_followup = it->property_details().type() == FIELD;
+      inline_followup =
+          it->property_details().type() == FIELD && !it->is_dictionary_holder();
       break;
     case LookupIterator::ACCESSOR: {
       Handle<Object> accessors = it->GetAccessors();
@@ -255,7 +298,12 @@
     }
   }
 
-  Register reg = Frontend(receiver(), it->name());
+  Label miss;
+  InterceptorVectorSlotPush(receiver());
+  Register reg = FrontendHeader(receiver(), it->name(), &miss);
+  FrontendFooter(it->name(), &miss);
+  InterceptorVectorSlotPop(reg);
+
   if (inline_followup) {
     // TODO(368): Compile in the whole chain: all the interceptors in
     // prototypes and ultimate answer.
@@ -273,7 +321,13 @@
 
   set_type_for_object(holder());
   set_holder(real_named_property_holder);
-  Register reg = Frontend(interceptor_reg, it->name());
+
+  Label miss;
+  InterceptorVectorSlotPush(interceptor_reg);
+  Register reg = FrontendHeader(interceptor_reg, it->name(), &miss);
+  FrontendFooter(it->name(), &miss);
+  // We discard the vector and slot now because we don't miss below this point.
+  InterceptorVectorSlotPop(reg, DISCARD);
 
   switch (it->state()) {
     case LookupIterator::ACCESS_CHECK:
@@ -300,7 +354,7 @@
 
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter(
     Handle<Name> name, Handle<JSFunction> getter) {
-  Frontend(receiver(), name);
+  Frontend(name);
   GenerateLoadViaGetter(masm(), type(), receiver(), getter);
   return GetCode(kind(), Code::FAST, name);
 }
@@ -309,10 +363,7 @@
 // TODO(verwaest): Cleanup. holder() is actually the receiver.
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition(
     Handle<Map> transition, Handle<Name> name) {
-  Label miss, slow;
-
-  // Ensure no transitions to deprecated maps are followed.
-  __ CheckMapDeprecated(transition, scratch1(), &miss);
+  Label miss;
 
   // Check that we are allowed to write this.
   bool is_nonexistent = holder()->map() == transition->GetBackPointer();
@@ -331,21 +382,58 @@
     DCHECK(holder()->HasFastProperties());
   }
 
-  GenerateStoreTransition(transition, name, receiver(), this->name(), value(),
-                          scratch1(), scratch2(), scratch3(), &miss, &slow);
+  int descriptor = transition->LastAdded();
+  Handle<DescriptorArray> descriptors(transition->instance_descriptors());
+  PropertyDetails details = descriptors->GetDetails(descriptor);
+  Representation representation = details.representation();
+  DCHECK(!representation.IsNone());
+
+  // Stub is never generated for objects that require access checks.
+  DCHECK(!transition->is_access_check_needed());
+
+  // Call to respective StoreTransitionStub.
+  if (details.type() == CONSTANT) {
+    GenerateRestoreMap(transition, scratch2(), &miss);
+    DCHECK(descriptors->GetValue(descriptor)->IsJSFunction());
+    Register map_reg = StoreTransitionDescriptor::MapRegister();
+    GenerateConstantCheck(map_reg, descriptor, value(), scratch2(), &miss);
+    GenerateRestoreName(name);
+    StoreTransitionStub stub(isolate());
+    GenerateTailCall(masm(), stub.GetCode());
+
+  } else {
+    if (representation.IsHeapObject()) {
+      GenerateFieldTypeChecks(descriptors->GetFieldType(descriptor), value(),
+                              &miss);
+    }
+    StoreTransitionStub::StoreMode store_mode =
+        Map::cast(transition->GetBackPointer())->unused_property_fields() == 0
+            ? StoreTransitionStub::ExtendStorageAndStoreMapAndValue
+            : StoreTransitionStub::StoreMapAndValue;
+
+    GenerateRestoreMap(transition, scratch2(), &miss);
+    GenerateRestoreName(name);
+    StoreTransitionStub stub(isolate(),
+                             FieldIndex::ForDescriptor(*transition, descriptor),
+                             representation, store_mode);
+    GenerateTailCall(masm(), stub.GetCode());
+  }
 
   GenerateRestoreName(&miss, name);
   TailCallBuiltin(masm(), MissBuiltin(kind()));
 
-  GenerateRestoreName(&slow, name);
-  TailCallBuiltin(masm(), SlowBuiltin(kind()));
   return GetCode(kind(), Code::FAST, name);
 }
 
 
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) {
   Label miss;
-  GenerateStoreField(it, value(), &miss);
+  DCHECK(it->representation().IsHeapObject());
+
+  GenerateFieldTypeChecks(*it->GetFieldType(), value(), &miss);
+  StoreFieldStub stub(isolate(), it->GetFieldIndex(), it->representation());
+  GenerateTailCall(masm(), stub.GetCode());
+
   __ bind(&miss);
   TailCallBuiltin(masm(), MissBuiltin(kind()));
   return GetCode(kind(), Code::FAST, it->name());
@@ -354,7 +442,7 @@
 
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter(
     Handle<JSObject> object, Handle<Name> name, Handle<JSFunction> setter) {
-  Frontend(receiver(), name);
+  Frontend(name);
   GenerateStoreViaSetter(masm(), type(), receiver(), setter);
 
   return GetCode(kind(), Code::FAST, name);
@@ -364,7 +452,7 @@
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     Handle<JSObject> object, Handle<Name> name,
     const CallOptimization& call_optimization) {
-  Frontend(receiver(), name);
+  Frontend(name);
   Register values[] = {value()};
   GenerateFastApiCall(masm(), call_optimization, handle(object->map()),
                       receiver(), scratch1(), true, 1, values);
@@ -381,8 +469,8 @@
     Handle<Map> receiver_map = receiver_maps->at(i);
     Handle<Code> cached_stub;
 
-    if ((receiver_map->instance_type() & kNotStringTag) == 0) {
-      cached_stub = isolate()->builtins()->KeyedLoadIC_String();
+    if (receiver_map->IsStringMap()) {
+      cached_stub = LoadIndexedStringStub(isolate()).GetCode();
     } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) {
       cached_stub = isolate()->builtins()->KeyedLoadIC_Slow();
     } else {
diff --git a/src/ic/handler-compiler.h b/src/ic/handler-compiler.h
index f033f3f..bed6577 100644
--- a/src/ic/handler-compiler.h
+++ b/src/ic/handler-compiler.h
@@ -38,10 +38,21 @@
 
   virtual void FrontendFooter(Handle<Name> name, Label* miss) { UNREACHABLE(); }
 
-  Register Frontend(Register object_reg, Handle<Name> name);
+  // Frontend loads from receiver(), returns holder register which may be
+  // different.
+  Register Frontend(Handle<Name> name);
   void NonexistentFrontendHeader(Handle<Name> name, Label* miss,
                                  Register scratch1, Register scratch2);
 
+  // When FLAG_vector_ics is true, handlers that have the possibility of missing
+  // will need to save and pass these to miss handlers.
+  void PushVectorAndSlot() { PushVectorAndSlot(vector(), slot()); }
+  void PushVectorAndSlot(Register vector, Register slot);
+  void PopVectorAndSlot() { PopVectorAndSlot(vector(), slot()); }
+  void PopVectorAndSlot(Register vector, Register slot);
+
+  void DiscardVectorAndSlot();
+
   // TODO(verwaest): Make non-static.
   static void GenerateFastApiCall(MacroAssembler* masm,
                                   const CallOptimization& optimization,
@@ -170,6 +181,12 @@
                             Handle<ExecutableAccessorInfo> callback);
   void GenerateLoadCallback(const CallOptimization& call_optimization,
                             Handle<Map> receiver_map);
+
+  // Helper emits no code if vector-ics are disabled.
+  void InterceptorVectorSlotPush(Register holder_reg);
+  enum PopMode { POP, DISCARD };
+  void InterceptorVectorSlotPop(Register holder_reg, PopMode mode = POP);
+
   void GenerateLoadInterceptor(Register holder_reg);
   void GenerateLoadInterceptorWithFollowup(LookupIterator* it,
                                            Register holder_reg);
@@ -230,14 +247,16 @@
   void GenerateRestoreName(Label* label, Handle<Name> name);
 
  private:
-  void GenerateStoreTransition(Handle<Map> transition, Handle<Name> name,
-                               Register receiver_reg, Register name_reg,
-                               Register value_reg, Register scratch1,
-                               Register scratch2, Register scratch3,
-                               Label* miss_label, Label* slow);
+  void GenerateRestoreName(Handle<Name> name);
+  void GenerateRestoreMap(Handle<Map> transition, Register scratch,
+                          Label* miss);
 
-  void GenerateStoreField(LookupIterator* lookup, Register value_reg,
-                          Label* miss_label);
+  void GenerateConstantCheck(Register map_reg, int descriptor,
+                             Register value_reg, Register scratch,
+                             Label* miss_label);
+
+  void GenerateFieldTypeChecks(HeapType* field_type, Register value_reg,
+                               Label* miss_label);
 
   static Builtins::Name SlowBuiltin(Code::Kind kind) {
     switch (kind) {
diff --git a/src/ic/ia32/handler-compiler-ia32.cc b/src/ic/ia32/handler-compiler-ia32.cc
index fd97154..90512e9 100644
--- a/src/ic/ia32/handler-compiler-ia32.cc
+++ b/src/ic/ia32/handler-compiler-ia32.cc
@@ -47,6 +47,28 @@
 }
 
 
+void PropertyHandlerCompiler::PushVectorAndSlot(Register vector,
+                                                Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ push(vector);
+  __ push(slot);
+}
+
+
+void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ pop(slot);
+  __ pop(vector);
+}
+
+
+void PropertyHandlerCompiler::DiscardVectorAndSlot() {
+  MacroAssembler* masm = this->masm();
+  // Remove vector and slot.
+  __ add(esp, Immediate(2 * kPointerSize));
+}
+
+
 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
     MacroAssembler* masm, Label* miss_label, Register receiver,
     Handle<Name> name, Register scratch0, Register scratch1) {
@@ -88,28 +110,23 @@
 
 
 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
-    MacroAssembler* masm, int index, Register prototype, Label* miss) {
-  // Get the global function with the given index.
-  Handle<JSFunction> function(
-      JSFunction::cast(masm->isolate()->native_context()->get(index)));
-  // Check we're still in the same context.
-  Register scratch = prototype;
+    MacroAssembler* masm, int index, Register result, Label* miss) {
   const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
-  __ mov(scratch, Operand(esi, offset));
-  __ mov(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset));
-  __ cmp(Operand(scratch, Context::SlotOffset(index)), function);
-  __ j(not_equal, miss);
-
+  __ mov(result, Operand(esi, offset));
+  __ mov(result, FieldOperand(result, GlobalObject::kNativeContextOffset));
+  __ mov(result, Operand(result, Context::SlotOffset(index)));
   // Load its initial map. The global functions all have initial maps.
-  __ Move(prototype, Immediate(Handle<Map>(function->initial_map())));
+  __ mov(result,
+         FieldOperand(result, JSFunction::kPrototypeOrInitialMapOffset));
   // Load the prototype from the initial map.
-  __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
+  __ mov(result, FieldOperand(result, Map::kPrototypeOffset));
 }
 
 
 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
     MacroAssembler* masm, Register receiver, Register scratch1,
     Register scratch2, Label* miss_label) {
+  DCHECK(!FLAG_vector_ics);
   __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
   __ mov(eax, scratch1);
   __ ret(0);
@@ -329,170 +346,60 @@
 }
 
 
-// Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
-// store is successful.
-void NamedStoreHandlerCompiler::GenerateStoreTransition(
-    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
-    Register storage_reg, Register value_reg, Register scratch1,
-    Register scratch2, Register unused, Label* miss_label, Label* slow) {
-  int descriptor = transition->LastAdded();
-  DescriptorArray* descriptors = transition->instance_descriptors();
-  PropertyDetails details = descriptors->GetDetails(descriptor);
-  Representation representation = details.representation();
-  DCHECK(!representation.IsNone());
-
-  if (details.type() == CONSTANT) {
-    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
-    __ CmpObject(value_reg, constant);
-    __ j(not_equal, miss_label);
-  } else if (representation.IsSmi()) {
-    __ JumpIfNotSmi(value_reg, miss_label);
-  } else if (representation.IsHeapObject()) {
-    __ JumpIfSmi(value_reg, miss_label);
-    HeapType* field_type = descriptors->GetFieldType(descriptor);
-    HeapType::Iterator<Map> it = field_type->Classes();
-    if (!it.Done()) {
-      Label do_store;
-      while (true) {
-        __ CompareMap(value_reg, it.Current());
-        it.Advance();
-        if (it.Done()) {
-          __ j(not_equal, miss_label);
-          break;
-        }
-        __ j(equal, &do_store, Label::kNear);
-      }
-      __ bind(&do_store);
-    }
-  } else if (representation.IsDouble()) {
-    Label do_store, heap_number;
-    __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow, MUTABLE);
-
-    __ JumpIfNotSmi(value_reg, &heap_number);
-    __ SmiUntag(value_reg);
-    __ Cvtsi2sd(xmm0, value_reg);
-    __ SmiTag(value_reg);
-    __ jmp(&do_store);
-
-    __ bind(&heap_number);
-    __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
-                DONT_DO_SMI_CHECK);
-    __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
-
-    __ bind(&do_store);
-    __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
-  }
-
-  // Stub never generated for objects that require access checks.
-  DCHECK(!transition->is_access_check_needed());
-
-  // Perform map transition for the receiver if necessary.
-  if (details.type() == FIELD &&
-      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
-    // The properties must be extended before we can store the value.
-    // We jump to a runtime call that extends the properties array.
-    __ pop(scratch1);  // Return address.
-    __ push(receiver_reg);
-    __ push(Immediate(transition));
-    __ push(value_reg);
-    __ push(scratch1);
-    __ TailCallExternalReference(
-        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                          isolate()),
-        3, 1);
-    return;
-  }
-
-  // Update the map of the object.
-  __ mov(scratch1, Immediate(transition));
-  __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
-
-  // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
-                      kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
-
-  if (details.type() == CONSTANT) {
-    DCHECK(value_reg.is(eax));
-    __ ret(0);
-    return;
-  }
-
-  int index = transition->instance_descriptors()->GetFieldIndex(
-      transition->LastAdded());
-
-  // Adjust for the number of properties stored in the object. Even in the
-  // face of a transition we can use the old map here because the size of the
-  // object and the number of in-object properties is not going to change.
-  index -= transition->inobject_properties();
-
-  SmiCheck smi_check =
-      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
-  // TODO(verwaest): Share this code as a code stub.
-  if (index < 0) {
-    // Set the property straight into the object.
-    int offset = transition->instance_size() + (index * kPointerSize);
-    if (representation.IsDouble()) {
-      __ mov(FieldOperand(receiver_reg, offset), storage_reg);
-    } else {
-      __ mov(FieldOperand(receiver_reg, offset), value_reg);
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
-                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
-    }
-  } else {
-    // Write to the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    // Get the properties array (optimistically).
-    __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
-    if (representation.IsDouble()) {
-      __ mov(FieldOperand(scratch1, offset), storage_reg);
-    } else {
-      __ mov(FieldOperand(scratch1, offset), value_reg);
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
-                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
-    }
-  }
-
-  // Return the value (register eax).
-  DCHECK(value_reg.is(eax));
-  __ ret(0);
+void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
+  __ mov(this->name(), Immediate(name));
 }
 
 
-void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
-                                                   Register value_reg,
-                                                   Label* miss_label) {
-  DCHECK(lookup->representation().IsHeapObject());
-  __ JumpIfSmi(value_reg, miss_label);
-  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
-  Label do_store;
-  while (true) {
-    __ CompareMap(value_reg, it.Current());
-    it.Advance();
-    if (it.Done()) {
-      __ j(not_equal, miss_label);
-      break;
-    }
-    __ j(equal, &do_store, Label::kNear);
+void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition,
+                                                   Register scratch,
+                                                   Label* miss) {
+  Handle<WeakCell> cell = Map::WeakCellForMap(transition);
+  Register map_reg = StoreTransitionDescriptor::MapRegister();
+  DCHECK(!map_reg.is(scratch));
+  __ LoadWeakValue(map_reg, cell, miss);
+  if (transition->CanBeDeprecated()) {
+    __ mov(scratch, FieldOperand(map_reg, Map::kBitField3Offset));
+    __ and_(scratch, Immediate(Map::Deprecated::kMask));
+    __ j(not_zero, miss);
   }
-  __ bind(&do_store);
+}
 
-  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
-                      lookup->representation());
-  GenerateTailCall(masm(), stub.GetCode());
+
+void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg,
+                                                      int descriptor,
+                                                      Register value_reg,
+                                                      Register scratch,
+                                                      Label* miss_label) {
+  DCHECK(!map_reg.is(scratch));
+  DCHECK(!map_reg.is(value_reg));
+  DCHECK(!value_reg.is(scratch));
+  __ LoadInstanceDescriptors(map_reg, scratch);
+  __ mov(scratch,
+         FieldOperand(scratch, DescriptorArray::GetValueOffset(descriptor)));
+  __ cmp(value_reg, scratch);
+  __ j(not_equal, miss_label);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
+                                                        Register value_reg,
+                                                        Label* miss_label) {
+  __ JumpIfSmi(value_reg, miss_label);
+  HeapType::Iterator<Map> it = field_type->Classes();
+  if (!it.Done()) {
+    Label do_store;
+    while (true) {
+      __ CompareMap(value_reg, it.Current());
+      it.Advance();
+      if (it.Done()) {
+        __ j(not_equal, miss_label);
+        break;
+      }
+      __ j(equal, &do_store, Label::kNear);
+    }
+    __ bind(&do_store);
+  }
 }
 
 
@@ -546,14 +453,12 @@
       reg = holder_reg;  // From now on the object will be in holder_reg.
       __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
     } else {
-      bool in_new_space = heap()->InNewSpace(*prototype);
-      // Two possible reasons for loading the prototype from the map:
-      // (1) Can't store references to new space in code.
-      // (2) Handler is shared for all receivers with the same prototype
-      //     map (but not necessarily the same prototype instance).
-      bool load_prototype_from_map = in_new_space || depth == 1;
+      Register map_reg = scratch1;
+      __ mov(map_reg, FieldOperand(reg, HeapObject::kMapOffset));
       if (depth != 1 || check == CHECK_ALL_MAPS) {
-        __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
+        Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+        __ CmpWeakValue(map_reg, cell, scratch2);
+        __ j(not_equal, miss);
       }
 
       // Check access rights to the global object.  This has to happen after
@@ -563,24 +468,15 @@
       // global proxy (as opposed to using slow ICs). See corresponding code
       // in LookupForRead().
       if (current_map->IsJSGlobalProxyMap()) {
-        __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss);
+        __ CheckAccessGlobalProxy(reg, map_reg, scratch2, miss);
+        // Restore map_reg.
+        __ mov(map_reg, FieldOperand(reg, HeapObject::kMapOffset));
       } else if (current_map->IsJSGlobalObjectMap()) {
         GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
                                   name, scratch2, miss);
       }
-
-      if (load_prototype_from_map) {
-        // Save the map in scratch1 for later.
-        __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
-      }
-
       reg = holder_reg;  // From now on the object will be in holder_reg.
-
-      if (load_prototype_from_map) {
-        __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
-      } else {
-        __ mov(reg, prototype);
-      }
+      __ mov(reg, FieldOperand(map_reg, Map::kPrototypeOffset));
     }
 
     // Go to the next object in the prototype chain.
@@ -593,7 +489,10 @@
 
   if (depth != 0 || check == CHECK_ALL_MAPS) {
     // Check the holder map.
-    __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
+    __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
+    Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+    __ CmpWeakValue(scratch1, cell, scratch2);
+    __ j(not_equal, miss);
   }
 
   // Perform security check for access to the global object.
@@ -613,6 +512,10 @@
     Label success;
     __ jmp(&success);
     __ bind(miss);
+    if (IC::ICUseVector(kind())) {
+      DCHECK(kind() == Code::LOAD_IC);
+      PopVectorAndSlot();
+    }
     TailCallBuiltin(masm(), MissBuiltin(kind()));
     __ bind(&success);
   }
@@ -712,7 +615,7 @@
     }
     __ push(holder_reg);
     __ push(this->name());
-
+    InterceptorVectorSlotPush(holder_reg);
     // Invoke an interceptor.  Note: map checks from receiver to
     // interceptor's holder has been compiled before (see a caller
     // of this method.)
@@ -736,6 +639,7 @@
       __ mov(this->name(), Immediate(bit_cast<int32_t>(kZapValue)));
     }
 
+    InterceptorVectorSlotPop(holder_reg);
     __ pop(this->name());
     __ pop(holder_reg);
     if (must_preserve_receiver_reg) {
@@ -768,7 +672,7 @@
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     Handle<JSObject> object, Handle<Name> name,
     Handle<ExecutableAccessorInfo> callback) {
-  Register holder_reg = Frontend(receiver(), name);
+  Register holder_reg = Frontend(name);
 
   __ pop(scratch1());  // remove the return address
   __ push(receiver());
@@ -814,16 +718,15 @@
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
   Label miss;
-
+  if (IC::ICUseVector(kind())) {
+    PushVectorAndSlot();
+  }
   FrontendHeader(receiver(), name, &miss);
   // Get the value from the cell.
   Register result = StoreDescriptor::ValueRegister();
-  if (masm()->serializer_enabled()) {
-    __ mov(result, Immediate(cell));
-    __ mov(result, FieldOperand(result, PropertyCell::kValueOffset));
-  } else {
-    __ mov(result, Operand::ForCell(cell));
-  }
+  Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell);
+  __ LoadWeakValue(result, weak_cell, &miss);
+  __ mov(result, FieldOperand(result, PropertyCell::kValueOffset));
 
   // Check for deleted property if property can actually be deleted.
   if (is_configurable) {
@@ -837,6 +740,9 @@
   Counters* counters = isolate()->counters();
   __ IncrementCounter(counters->named_load_global_stub(), 1);
   // The code above already loads the result into the return register.
+  if (IC::ICUseVector(kind())) {
+    DiscardVectorAndSlot();
+  }
   __ ret(0);
 
   FrontendFooter(name, &miss);
diff --git a/src/ic/ia32/ic-compiler-ia32.cc b/src/ic/ia32/ic-compiler-ia32.cc
index ac42f30..f43b641 100644
--- a/src/ic/ia32/ic-compiler-ia32.cc
+++ b/src/ic/ia32/ic-compiler-ia32.cc
@@ -44,10 +44,13 @@
   Label miss;
 
   if (check == PROPERTY &&
-      (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
-    // In case we are compiling an IC for dictionary loads and stores, just
+      (kind() == Code::KEYED_STORE_IC || kind() == Code::KEYED_LOAD_IC)) {
+    // In case we are compiling an IC for dictionary loads or stores, just
     // check whether the name is unique.
     if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
+      // Keyed loads with dictionaries shouldn't be here, they go generic.
+      // The DCHECK is to protect assumptions when --vector-ics is on.
+      DCHECK(kind() != Code::KEYED_LOAD_IC);
       Register tmp = scratch1();
       __ JumpIfSmi(this->name(), &miss);
       __ mov(tmp, FieldOperand(this->name(), HeapObject::kMapOffset));
@@ -75,7 +78,8 @@
     Handle<Map> map = IC::TypeToMap(*type, isolate());
     if (!map->is_deprecated()) {
       number_of_handled_maps++;
-      __ cmp(map_reg, map);
+      Handle<WeakCell> cell = Map::WeakCellForMap(map);
+      __ CmpWeakValue(map_reg, cell, scratch2());
       if (type->Is(HeapType::Number())) {
         DCHECK(!number_case.is_unused());
         __ bind(&number_case);
@@ -99,16 +103,19 @@
     MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
     MapHandleList* transitioned_maps) {
   Label miss;
-  __ JumpIfSmi(receiver(), &miss, Label::kNear);
-  __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
+  __ JumpIfSmi(receiver(), &miss);
+  Register map_reg = scratch1();
+  __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
   for (int i = 0; i < receiver_maps->length(); ++i) {
-    __ cmp(scratch1(), receiver_maps->at(i));
+    Handle<WeakCell> cell = Map::WeakCellForMap(receiver_maps->at(i));
+    __ CmpWeakValue(map_reg, cell, scratch2());
     if (transitioned_maps->at(i).is_null()) {
       __ j(equal, handler_stubs->at(i));
     } else {
       Label next_map;
       __ j(not_equal, &next_map, Label::kNear);
-      __ mov(transition_map(), Immediate(transitioned_maps->at(i)));
+      Handle<WeakCell> cell = Map::WeakCellForMap(transitioned_maps->at(i));
+      __ LoadWeakValue(transition_map(), cell, &miss);
       __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
       __ bind(&next_map);
     }
diff --git a/src/ic/ia32/ic-ia32.cc b/src/ic/ia32/ic-ia32.cc
index 67247d2..9822f26 100644
--- a/src/ic/ia32/ic-ia32.cc
+++ b/src/ic/ia32/ic-ia32.cc
@@ -476,33 +476,6 @@
 }
 
 
-void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
-  // Return address is on the stack.
-  Label miss;
-
-  Register receiver = LoadDescriptor::ReceiverRegister();
-  Register index = LoadDescriptor::NameRegister();
-  Register scratch = ebx;
-  DCHECK(!scratch.is(receiver) && !scratch.is(index));
-  Register result = eax;
-  DCHECK(!result.is(scratch));
-
-  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
-                                          &miss,  // When not a string.
-                                          &miss,  // When not a number.
-                                          &miss,  // When index out of range.
-                                          STRING_INDEX_IS_ARRAY_INDEX);
-  char_at_generator.GenerateFast(masm);
-  __ ret(0);
-
-  StubRuntimeCallHelper call_helper;
-  char_at_generator.GenerateSlow(masm, call_helper);
-
-  __ bind(&miss);
-  GenerateMiss(masm);
-}
-
-
 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
   // Return address is on the stack.
   Label slow, notin;
@@ -534,7 +507,7 @@
 }
 
 
-static void KeyedStoreGenerateGenericHelper(
+static void KeyedStoreGenerateMegamorphicHelper(
     MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
     KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) {
   Label transition_smi_elements;
@@ -672,12 +645,12 @@
 }
 
 
-void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
-                                   StrictMode strict_mode) {
+void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
+                                       StrictMode strict_mode) {
   // Return address is on the stack.
   Label slow, fast_object, fast_object_grow;
   Label fast_double, fast_double_grow;
-  Label array, extra, check_if_double_array;
+  Label array, extra, check_if_double_array, maybe_name_key, miss;
   Register receiver = StoreDescriptor::ReceiverRegister();
   Register key = StoreDescriptor::NameRegister();
   DCHECK(receiver.is(edx));
@@ -693,7 +666,7 @@
             1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved);
   __ j(not_zero, &slow);
   // Check that the key is a smi.
-  __ JumpIfNotSmi(key, &slow);
+  __ JumpIfNotSmi(key, &maybe_name_key);
   __ CmpInstanceType(edi, JS_ARRAY_TYPE);
   __ j(equal, &array);
   // Check that the object is some kind of JSObject.
@@ -711,6 +684,18 @@
   // Slow case: call runtime.
   __ bind(&slow);
   PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
+  // Never returns to here.
+
+  __ bind(&maybe_name_key);
+  __ mov(ebx, FieldOperand(key, HeapObject::kMapOffset));
+  __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
+  __ JumpIfNotUniqueNameInstanceType(ebx, &slow);
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::STORE_IC));
+  masm->isolate()->stub_cache()->GenerateProbe(
+      masm, Code::STORE_IC, flags, false, receiver, key, ebx, no_reg);
+  // Cache miss.
+  __ jmp(&miss);
 
   // Extra capacity case: Check if there is extra capacity to
   // perform the store and update the length. Used for adding one
@@ -749,10 +734,14 @@
   __ cmp(key, FieldOperand(receiver, JSArray::kLengthOffset));  // Compare smis.
   __ j(above_equal, &extra);
 
-  KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow,
-                                  kCheckMap, kDontIncrementLength);
-  KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
-                                  &slow, kDontCheckMap, kIncrementLength);
+  KeyedStoreGenerateMegamorphicHelper(masm, &fast_object, &fast_double, &slow,
+                                      kCheckMap, kDontIncrementLength);
+  KeyedStoreGenerateMegamorphicHelper(masm, &fast_object_grow,
+                                      &fast_double_grow, &slow, kDontCheckMap,
+                                      kIncrementLength);
+
+  __ bind(&miss);
+  GenerateMiss(masm);
 }
 
 
@@ -778,31 +767,52 @@
 static void LoadIC_PushArgs(MacroAssembler* masm) {
   Register receiver = LoadDescriptor::ReceiverRegister();
   Register name = LoadDescriptor::NameRegister();
-  DCHECK(!ebx.is(receiver) && !ebx.is(name));
+  if (FLAG_vector_ics) {
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+    DCHECK(!edi.is(receiver) && !edi.is(name) && !edi.is(slot) &&
+           !edi.is(vector));
 
-  __ pop(ebx);
-  __ push(receiver);
-  __ push(name);
-  __ push(ebx);
+    __ pop(edi);
+    __ push(receiver);
+    __ push(name);
+    __ push(slot);
+    __ push(vector);
+    __ push(edi);
+  } else {
+    DCHECK(!ebx.is(receiver) && !ebx.is(name));
+
+    __ pop(ebx);
+    __ push(receiver);
+    __ push(name);
+    __ push(ebx);
+  }
 }
 
 
 void LoadIC::GenerateMiss(MacroAssembler* masm) {
   // Return address is on the stack.
   __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1);
-
   LoadIC_PushArgs(masm);
 
   // Perform tail call to the entry.
   ExternalReference ref =
       ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate());
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
   // Return address is on the stack.
-  LoadIC_PushArgs(masm);
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register name = LoadDescriptor::NameRegister();
+  DCHECK(!ebx.is(receiver) && !ebx.is(name));
+
+  __ pop(ebx);
+  __ push(receiver);
+  __ push(name);
+  __ push(ebx);
 
   // Perform tail call to the entry.
   __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
@@ -818,13 +828,21 @@
   // Perform tail call to the entry.
   ExternalReference ref =
       ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
   // Return address is on the stack.
-  LoadIC_PushArgs(masm);
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register name = LoadDescriptor::NameRegister();
+  DCHECK(!ebx.is(receiver) && !ebx.is(name));
+
+  __ pop(ebx);
+  __ push(receiver);
+  __ push(name);
+  __ push(ebx);
 
   // Perform tail call to the entry.
   __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
@@ -836,7 +854,7 @@
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::STORE_IC));
   masm->isolate()->stub_cache()->GenerateProbe(
-      masm, flags, false, StoreDescriptor::ReceiverRegister(),
+      masm, Code::STORE_IC, flags, false, StoreDescriptor::ReceiverRegister(),
       StoreDescriptor::NameRegister(), ebx, no_reg);
 
   // Cache miss: Jump to runtime.
diff --git a/src/ic/ia32/stub-cache-ia32.cc b/src/ic/ia32/stub-cache-ia32.cc
index c1f7c9a..cb560f1 100644
--- a/src/ic/ia32/stub-cache-ia32.cc
+++ b/src/ic/ia32/stub-cache-ia32.cc
@@ -7,7 +7,9 @@
 #if V8_TARGET_ARCH_IA32
 
 #include "src/codegen.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
+#include "src/interface-descriptors.h"
 
 namespace v8 {
 namespace internal {
@@ -16,7 +18,7 @@
 
 
 static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
-                       Code::Flags flags, bool leave_frame,
+                       Code::Kind ic_kind, Code::Flags flags, bool leave_frame,
                        StubCache::Table table, Register name, Register receiver,
                        // Number of the cache entry pointer-size scaled.
                        Register offset, Register extra) {
@@ -56,6 +58,13 @@
     }
 #endif
 
+    if (IC::ICUseVector(ic_kind)) {
+      // The vector and slot were pushed onto the stack before starting the
+      // probe, and need to be dropped before calling the handler.
+      __ pop(VectorLoadICDescriptor::VectorRegister());
+      __ pop(VectorLoadICDescriptor::SlotRegister());
+    }
+
     if (leave_frame) __ leave();
 
     // Jump to the first instruction in the code stub.
@@ -100,6 +109,17 @@
     __ pop(offset);
     __ mov(offset, Operand::StaticArray(offset, times_1, value_offset));
 
+    if (IC::ICUseVector(ic_kind)) {
+      // The vector and slot were pushed onto the stack before starting the
+      // probe, and need to be dropped before calling the handler.
+      Register vector = VectorLoadICDescriptor::VectorRegister();
+      Register slot = VectorLoadICDescriptor::SlotRegister();
+      DCHECK(!offset.is(vector) && !offset.is(slot));
+
+      __ pop(vector);
+      __ pop(slot);
+    }
+
     if (leave_frame) __ leave();
 
     // Jump to the first instruction in the code stub.
@@ -113,10 +133,11 @@
 }
 
 
-void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags,
-                              bool leave_frame, Register receiver,
-                              Register name, Register scratch, Register extra,
-                              Register extra2, Register extra3) {
+void StubCache::GenerateProbe(MacroAssembler* masm, Code::Kind ic_kind,
+                              Code::Flags flags, bool leave_frame,
+                              Register receiver, Register name,
+                              Register scratch, Register extra, Register extra2,
+                              Register extra3) {
   Label miss;
 
   // Assert that code is valid.  The multiplying code relies on the entry size
@@ -159,8 +180,8 @@
   DCHECK(kCacheIndexShift == kPointerSizeLog2);
 
   // Probe the primary table.
-  ProbeTable(isolate(), masm, flags, leave_frame, kPrimary, name, receiver,
-             offset, extra);
+  ProbeTable(isolate(), masm, ic_kind, flags, leave_frame, kPrimary, name,
+             receiver, offset, extra);
 
   // Primary miss: Compute hash for secondary probe.
   __ mov(offset, FieldOperand(name, Name::kHashFieldOffset));
@@ -172,8 +193,8 @@
   __ and_(offset, (kSecondaryTableSize - 1) << kCacheIndexShift);
 
   // Probe the secondary table.
-  ProbeTable(isolate(), masm, flags, leave_frame, kSecondary, name, receiver,
-             offset, extra);
+  ProbeTable(isolate(), masm, ic_kind, flags, leave_frame, kSecondary, name,
+             receiver, offset, extra);
 
   // Cache miss: Fall-through and let caller handle the miss by
   // entering the runtime system.
diff --git a/src/ic/ic-compiler.cc b/src/ic/ic-compiler.cc
index aeae4ba..e087acf 100644
--- a/src/ic/ic-compiler.cc
+++ b/src/ic/ic-compiler.cc
@@ -57,6 +57,16 @@
 
   CacheHolderFlag flag;
   Handle<Map> stub_holder = IC::GetICCacheHolder(*type, isolate, &flag);
+  if (kind == Code::KEYED_STORE_IC) {
+    // Always set the "property" bit.
+    extra_ic_state =
+        KeyedStoreIC::IcCheckTypeField::update(extra_ic_state, PROPERTY);
+    DCHECK(STANDARD_STORE ==
+           KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state));
+  } else if (kind == Code::KEYED_LOAD_IC) {
+    extra_ic_state = KeyedLoadIC::IcCheckTypeField::update(extra_ic_state,
+                                                           PROPERTY);
+  }
 
   Handle<Code> ic;
   // There are multiple string maps that all use the same prototype. That
@@ -68,13 +78,6 @@
     if (!ic.is_null()) return ic;
   }
 
-#ifdef DEBUG
-  if (kind == Code::KEYED_STORE_IC) {
-    DCHECK(STANDARD_STORE ==
-           KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state));
-  }
-#endif
-
   PropertyICCompiler ic_compiler(isolate, kind, extra_ic_state, flag);
   ic = ic_compiler.CompileMonomorphic(type, handler, name, PROPERTY);
 
@@ -86,16 +89,34 @@
 Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphic(
     Handle<Map> receiver_map) {
   Isolate* isolate = receiver_map->GetIsolate();
+  DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT);
   Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC);
   Handle<Name> name = isolate->factory()->KeyedLoadMonomorphic_string();
 
   Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags), isolate);
   if (probe->IsCode()) return Handle<Code>::cast(probe);
 
+  Handle<Code> stub = ComputeKeyedLoadMonomorphicHandler(receiver_map);
+  PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC);
+  Handle<Code> code =
+      compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub,
+                                  isolate->factory()->empty_string(), ELEMENT);
+
+  Map::UpdateCodeCache(receiver_map, name, code);
+  return code;
+}
+
+
+Handle<Code> PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(
+    Handle<Map> receiver_map) {
+  Isolate* isolate = receiver_map->GetIsolate();
   ElementsKind elements_kind = receiver_map->elements_kind();
   Handle<Code> stub;
   if (receiver_map->has_indexed_interceptor()) {
     stub = LoadIndexedInterceptorStub(isolate).GetCode();
+  } else if (receiver_map->IsStringMap()) {
+    // We have a string.
+    stub = LoadIndexedStringStub(isolate).GetCode();
   } else if (receiver_map->has_sloppy_arguments_elements()) {
     stub = KeyedLoadSloppyArgumentsStub(isolate).GetCode();
   } else if (receiver_map->has_fast_elements() ||
@@ -107,13 +128,7 @@
   } else {
     stub = LoadDictionaryElementStub(isolate).GetCode();
   }
-  PropertyICCompiler compiler(isolate, Code::KEYED_LOAD_IC);
-  Handle<Code> code =
-      compiler.CompileMonomorphic(HeapType::Class(receiver_map, isolate), stub,
-                                  isolate->factory()->empty_string(), ELEMENT);
-
-  Map::UpdateCodeCache(receiver_map, name, code);
-  return code;
+  return stub;
 }
 
 
@@ -229,7 +244,8 @@
   }
 
   Code::FindAndReplacePattern pattern;
-  pattern.Add(isolate->factory()->meta_map(), receiver_map);
+  Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
+  pattern.Add(isolate->factory()->meta_map(), cell);
   Handle<Code> ic = stub->GetCodeCopy(pattern);
 
   if (!receiver_map->is_dictionary_map()) {
@@ -244,6 +260,7 @@
 Handle<Code> PropertyICCompiler::ComputeKeyedLoadPolymorphic(
     MapHandleList* receiver_maps) {
   Isolate* isolate = receiver_maps->at(0)->GetIsolate();
+  DCHECK(KeyedLoadIC::GetKeyType(kNoExtraICState) == ELEMENT);
   Code::Flags flags = Code::ComputeFlags(Code::KEYED_LOAD_IC, POLYMORPHIC);
   Handle<PolymorphicCodeCache> cache =
       isolate->factory()->polymorphic_code_cache();
@@ -363,7 +380,6 @@
   Code::Flags flags =
       Code::ComputeFlags(kind, state, extra_ic_state_, type, cache_holder());
   Handle<Code> code = GetCodeWithFlags(flags, name);
-  IC::RegisterWeakMapDependency(code);
   PROFILE(isolate(), CodeCreateEvent(log_kind(code), *code, *name));
   return code;
 }
@@ -434,7 +450,10 @@
     stub = StoreElementStub(isolate(), elements_kind).GetCode();
   }
 
-  __ DispatchMap(receiver(), scratch1(), receiver_map, stub, DO_SMI_CHECK);
+  Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
+
+  __ DispatchWeakMap(receiver(), scratch1(), scratch2(), cell, stub,
+                     DO_SMI_CHECK);
 
   TailCallBuiltin(masm(), Builtins::kKeyedStoreIC_Miss);
 
diff --git a/src/ic/ic-compiler.h b/src/ic/ic-compiler.h
index 3b12157..dd898ae 100644
--- a/src/ic/ic-compiler.h
+++ b/src/ic/ic-compiler.h
@@ -11,9 +11,6 @@
 namespace internal {
 
 
-enum IcCheckType { ELEMENT, PROPERTY };
-
-
 class PropertyICCompiler : public PropertyAccessCompiler {
  public:
   // Finds the Code object stored in the Heap::non_monomorphic_cache().
@@ -37,6 +34,8 @@
                                          ExtraICState extra_ic_state);
 
   // Keyed
+  static Handle<Code> ComputeKeyedLoadMonomorphicHandler(
+      Handle<Map> receiver_map);
   static Handle<Code> ComputeKeyedLoadMonomorphic(Handle<Map> receiver_map);
 
   static Handle<Code> ComputeKeyedStoreMonomorphic(
diff --git a/src/ic/ic-inl.h b/src/ic/ic-inl.h
index e10fb45..58d7d46 100644
--- a/src/ic/ic-inl.h
+++ b/src/ic/ic-inl.h
@@ -96,6 +96,12 @@
 void IC::SetTargetAtAddress(Address address, Code* target,
                             ConstantPoolArray* constant_pool) {
   DCHECK(target->is_inline_cache_stub() || target->is_compare_ic_stub());
+
+  // Don't use this for load_ics when --vector-ics is turned on.
+  DCHECK(!(FLAG_vector_ics && target->is_inline_cache_stub()) ||
+         (target->kind() != Code::LOAD_IC &&
+          target->kind() != Code::KEYED_LOAD_IC));
+
   Heap* heap = target->GetHeap();
   Code* old_target = GetTargetAtAddress(address, constant_pool);
 #ifdef DEBUG
@@ -119,9 +125,6 @@
 
 
 void IC::set_target(Code* code) {
-#ifdef VERIFY_HEAP
-  code->VerifyEmbeddedObjectsDependency();
-#endif
   SetTargetAtAddress(address(), code, constant_pool());
   target_set_ = true;
 }
@@ -208,20 +211,11 @@
 }
 
 
-IC::State CallIC::FeedbackToState(Handle<TypeFeedbackVector> vector,
-                                  Handle<Smi> slot) const {
-  IC::State state = UNINITIALIZED;
-  Object* feedback = vector->get(slot->value());
-
-  if (feedback == *TypeFeedbackVector::MegamorphicSentinel(isolate())) {
-    state = GENERIC;
-  } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) {
-    state = MONOMORPHIC;
-  } else {
-    CHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()));
-  }
-
-  return state;
+inline Code* IC::get_host() {
+  return isolate()
+      ->inner_pointer_to_code_cache()
+      ->GetCacheEntry(address())
+      ->code;
 }
 }
 }  // namespace v8::internal
diff --git a/src/ic/ic-state.cc b/src/ic/ic-state.cc
index 4238a72..9c883ad 100644
--- a/src/ic/ic-state.cc
+++ b/src/ic/ic-state.cc
@@ -10,6 +10,7 @@
 namespace v8 {
 namespace internal {
 
+// static
 void ICUtility::Clear(Isolate* isolate, Address address,
                       ConstantPoolArray* constant_pool) {
   IC::Clear(isolate, address, constant_pool);
@@ -28,7 +29,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const CallICState& s) {
+std::ostream& operator<<(std::ostream& os, const CallICState& s) {
   return os << "(args(" << s.arg_count() << "), "
             << (s.call_type() == CallICState::METHOD ? "METHOD" : "FUNCTION")
             << ", ";
@@ -308,7 +309,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const BinaryOpICState& s) {
+std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s) {
   os << "(" << Token::Name(s.op_);
   if (s.mode_ == OVERWRITE_LEFT)
     os << "_ReuseLeft";
diff --git a/src/ic/ic-state.h b/src/ic/ic-state.h
index b84bdb9..72fc865 100644
--- a/src/ic/ic-state.h
+++ b/src/ic/ic-state.h
@@ -51,7 +51,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const CallICState& s);
+std::ostream& operator<<(std::ostream& os, const CallICState& s);
 
 
 // Mode to overwrite BinaryExpression values.
@@ -139,7 +139,7 @@
   Isolate* isolate() const { return isolate_; }
 
  private:
-  friend OStream& operator<<(OStream& os, const BinaryOpICState& s);
+  friend std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s);
 
   enum Kind { NONE, SMI, INT32, NUMBER, STRING, GENERIC };
 
@@ -173,7 +173,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const BinaryOpICState& s);
+std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s);
 
 
 class CompareICState {
diff --git a/src/ic/ic.cc b/src/ic/ic.cc
index 1f3c750..0707536 100644
--- a/src/ic/ic.cc
+++ b/src/ic/ic.cc
@@ -17,7 +17,7 @@
 #include "src/ic/ic-compiler.h"
 #include "src/ic/stub-cache.h"
 #include "src/prototype.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -89,8 +89,8 @@
 
 void IC::TraceIC(const char* type, Handle<Object> name) {
   if (FLAG_trace_ic) {
-    Code* new_target = raw_target();
-    State new_state = new_target->ic_state();
+    State new_state =
+        UseVector() ? nexus()->StateFromFeedback() : raw_target()->ic_state();
     TraceIC(type, name, state(), new_state);
   }
 }
@@ -122,7 +122,7 @@
       modifier = GetTransitionMarkModifier(
           KeyedStoreIC::GetKeyedAccessStoreMode(extra_state));
     }
-    PrintF(" (%c->%c%s)", TransitionMarkFromState(old_state),
+    PrintF(" (%c->%c%s) ", TransitionMarkFromState(old_state),
            TransitionMarkFromState(new_state), modifier);
 #ifdef OBJECT_PRINT
     OFStream os(stdout);
@@ -134,12 +134,16 @@
   }
 }
 
-#define TRACE_IC(type, name) TraceIC(type, name)
-#define TRACE_VECTOR_IC(type, name, old_state, new_state) \
-  TraceIC(type, name, old_state, new_state)
 
-IC::IC(FrameDepth depth, Isolate* isolate)
-    : isolate_(isolate), target_set_(false), target_maps_set_(false) {
+#define TRACE_IC(type, name) TraceIC(type, name)
+
+
+IC::IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus,
+       bool for_queries_only)
+    : isolate_(isolate),
+      target_set_(false),
+      target_maps_set_(false),
+      nexus_(nexus) {
   // To improve the performance of the (much used) IC code, we unfold a few
   // levels of the stack frame iteration code. This yields a ~35% speedup when
   // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag.
@@ -178,8 +182,10 @@
   }
   pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address);
   target_ = handle(raw_target(), isolate);
-  state_ = target_->ic_state();
   kind_ = target_->kind();
+  state_ = (!for_queries_only && UseVector()) ? nexus->StateFromFeedback()
+                                              : target_->ic_state();
+  old_state_ = state_;
   extra_ic_state_ = target_->extra_ic_state();
 }
 
@@ -252,7 +258,11 @@
                                                 Handle<String> name) {
   if (!IsNameCompatibleWithPrototypeFailure(name)) return false;
   Handle<Map> receiver_map = TypeToMap(*receiver_type(), isolate());
-  maybe_handler_ = target()->FindHandlerForMap(*receiver_map);
+  if (UseVector()) {
+    maybe_handler_ = nexus()->FindHandlerForMap(receiver_map);
+  } else {
+    maybe_handler_ = target()->FindHandlerForMap(*receiver_map);
+  }
 
   // The current map wasn't handled yet. There's no reason to stay monomorphic,
   // *unless* we're moving from a deprecated map to its replacement, or
@@ -304,7 +314,8 @@
   if (target()->is_keyed_stub()) {
     // Determine whether the failure is due to a name failure.
     if (!name->IsName()) return false;
-    Name* stub_name = target()->FindFirstName();
+    Name* stub_name =
+        UseVector() ? nexus()->FindFirstName() : target()->FindFirstName();
     if (*name != stub_name) return false;
   }
 
@@ -333,7 +344,7 @@
   // an inline cache miss for the builtins object after lazily loading
   // JavaScript builtins, we return uninitialized as the state to
   // force the inline cache back to monomorphic state.
-  if (receiver->IsJSBuiltinsObject()) state_ = UNINITIALIZED;
+  if (receiver->IsJSBuiltinsObject()) state_ = PREMONOMORPHIC;
 }
 
 
@@ -419,10 +430,34 @@
 }
 
 
+// static
+void IC::OnTypeFeedbackChanged(Isolate* isolate, Code* host,
+                               TypeFeedbackVector* vector, State old_state,
+                               State new_state) {
+  if (host->kind() != Code::FUNCTION) return;
+
+  if (FLAG_type_info_threshold > 0) {
+    int polymorphic_delta = 0;  // "Polymorphic" here includes monomorphic.
+    int generic_delta = 0;      // "Generic" here includes megamorphic.
+    ComputeTypeInfoCountDelta(old_state, new_state, &polymorphic_delta,
+                              &generic_delta);
+    vector->change_ic_with_type_info_count(polymorphic_delta);
+    vector->change_ic_generic_count(generic_delta);
+  }
+  TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info());
+  info->change_own_type_change_checksum();
+  host->set_profiler_ticks(0);
+  isolate->runtime_profiler()->NotifyICChanged();
+  // 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.
+}
+
+
 void IC::PostPatching(Address address, Code* target, Code* old_target) {
   // Type vector based ICs update these statistics at a different time because
   // they don't always patch on state change.
-  if (target->kind() == Code::CALL_IC) return;
+  if (ICUseVector(target->kind())) return;
 
   Isolate* isolate = target->GetHeap()->isolate();
   State old_state = UNINITIALIZED;
@@ -439,42 +474,6 @@
 }
 
 
-void IC::RegisterWeakMapDependency(Handle<Code> stub) {
-  if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_ic &&
-      stub->CanBeWeakStub()) {
-    DCHECK(!stub->is_weak_stub());
-    MapHandleList maps;
-    stub->FindAllMaps(&maps);
-    if (maps.length() == 1 && stub->IsWeakObjectInIC(*maps.at(0))) {
-      Map::AddDependentIC(maps.at(0), stub);
-      stub->mark_as_weak_stub();
-      if (FLAG_enable_ool_constant_pool) {
-        stub->constant_pool()->set_weak_object_state(
-            ConstantPoolArray::WEAK_OBJECTS_IN_IC);
-      }
-    }
-  }
-}
-
-
-void IC::InvalidateMaps(Code* stub) {
-  DCHECK(stub->is_weak_stub());
-  stub->mark_as_invalidated_weak_stub();
-  Isolate* isolate = stub->GetIsolate();
-  Heap* heap = isolate->heap();
-  Object* undefined = heap->undefined_value();
-  int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
-  for (RelocIterator it(stub, mode_mask); !it.done(); it.next()) {
-    RelocInfo::Mode mode = it.rinfo()->rmode();
-    if (mode == RelocInfo::EMBEDDED_OBJECT &&
-        it.rinfo()->target_object()->IsMap()) {
-      it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER);
-    }
-  }
-  CpuFeatures::FlushICache(stub->instruction_start(), stub->instruction_size());
-}
-
-
 void IC::Clear(Isolate* isolate, Address address,
                ConstantPoolArray* constant_pool) {
   Code* target = GetTargetAtAddress(address, constant_pool);
@@ -484,19 +483,20 @@
 
   switch (target->kind()) {
     case Code::LOAD_IC:
+      if (FLAG_vector_ics) return;
       return LoadIC::Clear(isolate, address, target, constant_pool);
     case Code::KEYED_LOAD_IC:
+      if (FLAG_vector_ics) return;
       return KeyedLoadIC::Clear(isolate, address, target, constant_pool);
     case Code::STORE_IC:
       return StoreIC::Clear(isolate, address, target, constant_pool);
     case Code::KEYED_STORE_IC:
       return KeyedStoreIC::Clear(isolate, address, target, constant_pool);
-    case Code::CALL_IC:
-      return CallIC::Clear(isolate, address, target, constant_pool);
     case Code::COMPARE_IC:
       return CompareIC::Clear(isolate, address, target, constant_pool);
     case Code::COMPARE_NIL_IC:
       return CompareNilIC::Clear(address, target, constant_pool);
+    case Code::CALL_IC:  // CallICs are vector-based and cleared differently.
     case Code::BINARY_OP_IC:
     case Code::TO_BOOLEAN_IC:
       // Clearing these is tricky and does not
@@ -510,7 +510,9 @@
 
 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target,
                         ConstantPoolArray* constant_pool) {
+  DCHECK(!FLAG_vector_ics);
   if (IsCleared(target)) return;
+
   // Make sure to also clear the map used in inline fast cases.  If we
   // do not clear these maps, cached code can keep objects alive
   // through the embedded maps.
@@ -518,14 +520,33 @@
 }
 
 
-void CallIC::Clear(Isolate* isolate, Address address, Code* target,
-                   ConstantPoolArray* constant_pool) {
-  // Currently, CallIC doesn't have state changes.
+void KeyedLoadIC::Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus) {
+  if (IsCleared(nexus)) return;
+  // Make sure to also clear the map used in inline fast cases.  If we
+  // do not clear these maps, cached code can keep objects alive
+  // through the embedded maps.
+  State state = nexus->StateFromFeedback();
+  nexus->ConfigurePremonomorphic();
+  OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC);
+}
+
+
+void CallIC::Clear(Isolate* isolate, Code* host, CallICNexus* nexus) {
+  // Determine our state.
+  Object* feedback = nexus->vector()->Get(nexus->slot());
+  State state = nexus->StateFromFeedback();
+
+  if (state != UNINITIALIZED && !feedback->IsAllocationSite()) {
+    nexus->ConfigureUninitialized();
+    // The change in state must be processed.
+    OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, UNINITIALIZED);
+  }
 }
 
 
 void LoadIC::Clear(Isolate* isolate, Address address, Code* target,
                    ConstantPoolArray* constant_pool) {
+  DCHECK(!FLAG_vector_ics);
   if (IsCleared(target)) return;
   Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::LOAD_IC,
                                                       target->extra_ic_state());
@@ -533,6 +554,14 @@
 }
 
 
+void LoadIC::Clear(Isolate* isolate, Code* host, LoadICNexus* nexus) {
+  if (IsCleared(nexus)) return;
+  State state = nexus->StateFromFeedback();
+  nexus->ConfigurePremonomorphic();
+  OnTypeFeedbackChanged(isolate, host, nexus->vector(), state, PREMONOMORPHIC);
+}
+
+
 void StoreIC::Clear(Isolate* isolate, Address address, Code* target,
                     ConstantPoolArray* constant_pool) {
   if (IsCleared(target)) return;
@@ -583,6 +612,69 @@
 }
 
 
+void IC::ConfigureVectorState(IC::State new_state) {
+  DCHECK(UseVector());
+  if (kind() == Code::LOAD_IC) {
+    LoadICNexus* nexus = casted_nexus<LoadICNexus>();
+    if (new_state == PREMONOMORPHIC) {
+      nexus->ConfigurePremonomorphic();
+    } else if (new_state == MEGAMORPHIC) {
+      nexus->ConfigureMegamorphic();
+    } else {
+      UNREACHABLE();
+    }
+  } else if (kind() == Code::KEYED_LOAD_IC) {
+    KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
+    if (new_state == GENERIC) {
+      nexus->ConfigureGeneric();
+    } else if (new_state == PREMONOMORPHIC) {
+      nexus->ConfigurePremonomorphic();
+    } else {
+      UNREACHABLE();
+    }
+  } else {
+    UNREACHABLE();
+  }
+
+  OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
+                        new_state);
+}
+
+
+void IC::ConfigureVectorState(Handle<Name> name, Handle<HeapType> type,
+                              Handle<Code> handler) {
+  DCHECK(UseVector());
+  if (kind() == Code::LOAD_IC) {
+    LoadICNexus* nexus = casted_nexus<LoadICNexus>();
+    nexus->ConfigureMonomorphic(type, handler);
+  } else {
+    DCHECK(kind() == Code::KEYED_LOAD_IC);
+    KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
+    nexus->ConfigureMonomorphic(name, type, handler);
+  }
+
+  OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
+                        MONOMORPHIC);
+}
+
+
+void IC::ConfigureVectorState(Handle<Name> name, TypeHandleList* types,
+                              CodeHandleList* handlers) {
+  DCHECK(UseVector());
+  if (kind() == Code::LOAD_IC) {
+    LoadICNexus* nexus = casted_nexus<LoadICNexus>();
+    nexus->ConfigurePolymorphic(types, handlers);
+  } else {
+    DCHECK(kind() == Code::KEYED_LOAD_IC);
+    KeyedLoadICNexus* nexus = casted_nexus<KeyedLoadICNexus>();
+    nexus->ConfigurePolymorphic(name, types, handlers);
+  }
+
+  OnTypeFeedbackChanged(isolate(), get_host(), *vector(), saved_state(),
+                        POLYMORPHIC);
+}
+
+
 MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) {
   // If the object is undefined or null it's illegal to try to get any
   // of its properties; throw a TypeError in that case.
@@ -596,7 +688,11 @@
   if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
     // Rewrite to the generic keyed load stub.
     if (FLAG_use_ic) {
-      set_target(*KeyedLoadIC::generic_stub(isolate()));
+      if (UseVector()) {
+        ConfigureVectorState(GENERIC);
+      } else {
+        set_target(*KeyedLoadIC::generic_stub(isolate()));
+      }
       TRACE_IC("LoadIC", name);
       TRACE_GENERIC_IC(isolate(), "LoadIC", "name as array index");
     }
@@ -609,6 +705,25 @@
 
   bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic;
 
+  if (FLAG_harmony_scoping && object->IsGlobalObject() && name->IsString()) {
+    // Look up in script context table.
+    Handle<String> str_name = Handle<String>::cast(name);
+    Handle<GlobalObject> global = Handle<GlobalObject>::cast(object);
+    Handle<ScriptContextTable> script_contexts(
+        global->native_context()->script_context_table());
+
+    ScriptContextTable::LookupResult lookup_result;
+    if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) {
+      if (use_ic && LoadScriptContextFieldStub::Accepted(&lookup_result)) {
+        LoadScriptContextFieldStub stub(isolate(), &lookup_result);
+        PatchCache(name, stub.GetCode());
+      }
+      return FixedArray::get(ScriptContextTable::GetContext(
+                                 script_contexts, lookup_result.context_index),
+                             lookup_result.slot_index);
+    }
+  }
+
   // Named lookup in the object.
   LookupIterator it(object, name);
   LookupForRead(&it);
@@ -681,15 +796,26 @@
       number_of_types - deprecated_types - (handler_to_overwrite != -1);
 
   if (number_of_valid_types >= 4) return false;
-  if (number_of_types == 0) return false;
-  if (!target()->FindHandlers(&handlers, types.length())) return false;
+  if (number_of_types == 0 && state() != MONOMORPHIC &&
+      state() != POLYMORPHIC) {
+    return false;
+  }
+  if (UseVector()) {
+    if (!nexus()->FindHandlers(&handlers, types.length())) return false;
+  } else {
+    if (!target()->FindHandlers(&handlers, types.length())) return false;
+  }
 
   number_of_valid_types++;
   if (number_of_valid_types > 1 && target()->is_keyed_stub()) return false;
   Handle<Code> ic;
   if (number_of_valid_types == 1) {
-    ic = PropertyICCompiler::ComputeMonomorphic(kind(), name, type, code,
-                                                extra_ic_state());
+    if (UseVector()) {
+      ConfigureVectorState(name, receiver_type(), code);
+    } else {
+      ic = PropertyICCompiler::ComputeMonomorphic(kind(), name, type, code,
+                                                  extra_ic_state());
+    }
   } else {
     if (handler_to_overwrite >= 0) {
       handlers.Set(handler_to_overwrite, code);
@@ -700,11 +826,17 @@
       types.Add(type);
       handlers.Add(code);
     }
-    ic = PropertyICCompiler::ComputePolymorphic(kind(), &types, &handlers,
-                                                number_of_valid_types, name,
-                                                extra_ic_state());
+
+    if (UseVector()) {
+      ConfigureVectorState(name, &types, &handlers);
+    } else {
+      ic = PropertyICCompiler::ComputePolymorphic(kind(), &types, &handlers,
+                                                  number_of_valid_types, name,
+                                                  extra_ic_state());
+    }
   }
-  set_target(*ic);
+
+  if (!UseVector()) set_target(*ic);
   return true;
 }
 
@@ -752,9 +884,13 @@
 
 void IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) {
   DCHECK(handler->is_handler());
-  Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic(
-      kind(), name, receiver_type(), handler, extra_ic_state());
-  set_target(*ic);
+  if (UseVector()) {
+    ConfigureVectorState(name, receiver_type(), handler);
+  } else {
+    Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic(
+        kind(), name, receiver_type(), handler, extra_ic_state());
+    set_target(*ic);
+  }
 }
 
 
@@ -795,29 +931,72 @@
     case POLYMORPHIC:
       if (!target()->is_keyed_stub() || state() == PROTOTYPE_FAILURE) {
         if (UpdatePolymorphicIC(name, code)) break;
+        // For keyed stubs, we can't know whether old handlers were for the
+        // same key.
         CopyICToMegamorphicCache(name);
       }
-      set_target(*megamorphic_stub());
+      if (UseVector()) {
+        ConfigureVectorState(kind() == Code::KEYED_LOAD_IC ? GENERIC
+                                                           : MEGAMORPHIC);
+      } else {
+        set_target(*megamorphic_stub());
+      }
     // Fall through.
     case MEGAMORPHIC:
       UpdateMegamorphicCache(*receiver_type(), *name, *code);
+      // Indicate that we've handled this case.
+      target_set_ = true;
       break;
     case DEBUG_STUB:
       break;
     case DEFAULT:
-    case GENERIC:
       UNREACHABLE();
       break;
+    case GENERIC:
+      // The generic keyed store stub re-uses store handlers, which can miss.
+      // That's ok, no reason to do anything.
+      DCHECK(target()->kind() == Code::KEYED_STORE_IC);
+      break;
   }
 }
 
 
 Handle<Code> LoadIC::initialize_stub(Isolate* isolate,
                                      ExtraICState extra_state) {
+  if (FLAG_vector_ics) {
+    return LoadICTrampolineStub(isolate, LoadICState(extra_state)).GetCode();
+  }
+
   return PropertyICCompiler::ComputeLoad(isolate, UNINITIALIZED, extra_state);
 }
 
 
+Handle<Code> LoadIC::initialize_stub_in_optimized_code(
+    Isolate* isolate, ExtraICState extra_state) {
+  if (FLAG_vector_ics) {
+    return VectorLoadStub(isolate, LoadICState(extra_state)).GetCode();
+  }
+  return initialize_stub(isolate, extra_state);
+}
+
+
+Handle<Code> KeyedLoadIC::initialize_stub(Isolate* isolate) {
+  if (FLAG_vector_ics) {
+    return KeyedLoadICTrampolineStub(isolate).GetCode();
+  }
+
+  return isolate->builtins()->KeyedLoadIC_Initialize();
+}
+
+
+Handle<Code> KeyedLoadIC::initialize_stub_in_optimized_code(Isolate* isolate) {
+  if (FLAG_vector_ics) {
+    return VectorKeyedLoadStub(isolate).GetCode();
+  }
+  return initialize_stub(isolate);
+}
+
+
 Handle<Code> LoadIC::megamorphic_stub() {
   if (kind() == Code::LOAD_IC) {
     MegamorphicLoadStub stub(isolate(), LoadICState(extra_ic_state()));
@@ -831,6 +1010,7 @@
 
 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate,
                                           ExtraICState extra_state) {
+  DCHECK(!FLAG_vector_ics);
   return PropertyICCompiler::ComputeLoad(isolate, PREMONOMORPHIC, extra_state);
 }
 
@@ -860,7 +1040,11 @@
   if (state() == UNINITIALIZED) {
     // This is the first time we execute this inline cache. Set the target to
     // the pre monomorphic stub to delay setting the monomorphic state.
-    set_target(*pre_monomorphic_stub());
+    if (UseVector()) {
+      ConfigureVectorState(PREMONOMORPHIC);
+    } else {
+      set_target(*pre_monomorphic_stub());
+    }
     TRACE_IC("LoadIC", lookup->name());
     return;
   }
@@ -888,7 +1072,8 @@
 
 
 void IC::UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) {
-  if (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC) return;
+  // Megamorphic state isn't implemented for keyed loads currently.
+  if (kind() == Code::KEYED_LOAD_IC) return;
   Map* map = *TypeToMap(type, isolate());
   isolate()->stub_cache()->Set(name, map, code);
 }
@@ -1121,15 +1306,20 @@
 }
 
 
-Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) {
+Handle<Code> KeyedLoadIC::LoadElementStub(Handle<HeapObject> receiver) {
+  Handle<Code> null_handle;
   Handle<Map> receiver_map(receiver->map(), isolate());
   MapHandleList target_receiver_maps;
-  if (target().is_identical_to(string_stub())) {
-    target_receiver_maps.Add(isolate()->factory()->string_map());
-  } else {
-    TargetMaps(&target_receiver_maps);
-  }
+  TargetMaps(&target_receiver_maps);
+
+
   if (target_receiver_maps.length() == 0) {
+    if (FLAG_vector_ics) {
+      Handle<Code> handler =
+          PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
+      ConfigureVectorState(Handle<Name>::null(), receiver_type(), handler);
+      return null_handle;
+    }
     return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
   }
 
@@ -1140,9 +1330,16 @@
   // monomorphic. If this optimistic assumption is not true, the IC will
   // miss again and it will become polymorphic and support both the
   // untransitioned and transitioned maps.
-  if (state() == MONOMORPHIC && IsMoreGeneralElementsKindTransition(
-                                    target_receiver_maps.at(0)->elements_kind(),
-                                    receiver->GetElementsKind())) {
+  if (state() == MONOMORPHIC && !receiver->IsString() &&
+      IsMoreGeneralElementsKindTransition(
+          target_receiver_maps.at(0)->elements_kind(),
+          Handle<JSObject>::cast(receiver)->GetElementsKind())) {
+    if (FLAG_vector_ics) {
+      Handle<Code> handler =
+          PropertyICCompiler::ComputeKeyedLoadMonomorphicHandler(receiver_map);
+      ConfigureVectorState(Handle<Name>::null(), receiver_type(), handler);
+      return null_handle;
+    }
     return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
   }
 
@@ -1154,6 +1351,10 @@
     // If the miss wasn't due to an unseen map, a polymorphic stub
     // won't help, use the generic stub.
     TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice");
+    if (FLAG_vector_ics) {
+      ConfigureVectorState(GENERIC);
+      return null_handle;
+    }
     return generic_stub();
   }
 
@@ -1161,9 +1362,25 @@
   // version of the IC.
   if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
     TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded");
+    if (FLAG_vector_ics) {
+      ConfigureVectorState(GENERIC);
+      return null_handle;
+    }
     return generic_stub();
   }
 
+  if (FLAG_vector_ics) {
+    CodeHandleList handlers(target_receiver_maps.length());
+    ElementHandlerCompiler compiler(isolate());
+    compiler.CompileElementHandlers(&target_receiver_maps, &handlers);
+    TypeHandleList types(target_receiver_maps.length());
+    for (int i = 0; i < target_receiver_maps.length(); i++) {
+      types.Add(HeapType::Class(target_receiver_maps.at(i), isolate()));
+    }
+    ConfigureVectorState(Handle<Name>::null(), &types, &handlers);
+    return null_handle;
+  }
+
   return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps);
 }
 
@@ -1190,22 +1407,23 @@
                                LoadIC::Load(object, Handle<Name>::cast(key)),
                                Object);
   } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) {
-    if (object->IsString() && key->IsNumber()) {
-      if (state() == UNINITIALIZED) stub = string_stub();
-    } else if (object->IsJSObject()) {
-      Handle<JSObject> receiver = Handle<JSObject>::cast(object);
-      if (!Object::ToSmi(isolate(), key).is_null()) {
+    if (object->IsJSObject() || (object->IsString() && key->IsNumber())) {
+      Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
+      if (object->IsString() || !Object::ToSmi(isolate(), key).is_null()) {
         stub = LoadElementStub(receiver);
       }
     }
   }
 
   if (!is_target_set()) {
-    Code* generic = *generic_stub();
-    if (*stub == generic) {
-      TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic");
+    if (!FLAG_vector_ics) {
+      Code* generic = *generic_stub();
+      if (*stub == generic) {
+        TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic");
+      }
+
+      set_target(*stub);
     }
-    set_target(*stub);
     TRACE_IC("LoadIC", key);
   }
 
@@ -1280,6 +1498,32 @@
 MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
                                    Handle<Object> value,
                                    JSReceiver::StoreFromKeyed store_mode) {
+  if (FLAG_harmony_scoping && object->IsGlobalObject() && name->IsString()) {
+    // Look up in script context table.
+    Handle<String> str_name = Handle<String>::cast(name);
+    Handle<GlobalObject> global = Handle<GlobalObject>::cast(object);
+    Handle<ScriptContextTable> script_contexts(
+        global->native_context()->script_context_table());
+
+    ScriptContextTable::LookupResult lookup_result;
+    if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) {
+      Handle<Context> script_context = ScriptContextTable::GetContext(
+          script_contexts, lookup_result.context_index);
+      if (lookup_result.mode == CONST) {
+        return TypeError("harmony_const_assign", object, name);
+      }
+
+      if (FLAG_use_ic &&
+          StoreScriptContextFieldStub::Accepted(&lookup_result)) {
+        StoreScriptContextFieldStub stub(isolate(), &lookup_result);
+        PatchCache(name, stub.GetCode());
+      }
+
+      script_context->set(lookup_result.slot_index, *value);
+      return value;
+    }
+  }
+
   // TODO(verwaest): Let SetProperty do the migration, since storing a property
   // might deprecate the current map again, if value does not fit.
   if (MigrateDeprecated(object) || object->IsJSProxy()) {
@@ -1359,9 +1603,9 @@
   } else {
     DCHECK(kind() == Code::KEYED_STORE_IC);
     if (strict_mode() == STRICT) {
-      return isolate()->builtins()->KeyedStoreIC_Generic_Strict();
+      return isolate()->builtins()->KeyedStoreIC_Megamorphic_Strict();
     } else {
-      return isolate()->builtins()->KeyedStoreIC_Generic();
+      return isolate()->builtins()->KeyedStoreIC_Megamorphic();
     }
   }
 }
@@ -1620,11 +1864,10 @@
     return generic_stub();
   }
 
-  // If the maximum number of receiver maps has been exceeded, use the generic
-  // version of the IC.
+  // If the maximum number of receiver maps has been exceeded, use the
+  // megamorphic version of the IC.
   if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
-    TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "max polymorph exceeded");
-    return generic_stub();
+    return megamorphic_stub();
   }
 
   // Make sure all polymorphic handlers have the same store mode, otherwise the
@@ -1807,12 +2050,12 @@
         StoreIC::Store(object, Handle<String>::cast(key), value,
                        JSReceiver::MAY_BE_STORE_FROM_KEYED),
         Object);
-    // TODO(jkummerow): Ideally we'd wrap this in "if (!is_target_set())",
-    // but doing so causes Hydrogen crashes. Needs investigation.
-    TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
-                     "unhandled internalized string key");
-    TRACE_IC("StoreIC", key);
-    set_target(*stub);
+    if (!is_target_set()) {
+      TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
+                       "unhandled internalized string key");
+      TRACE_IC("StoreIC", key);
+      set_target(*stub);
+    }
     return store_handle;
   }
 
@@ -1888,9 +2131,15 @@
 }
 
 
+// static
+void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
+                                   StrictMode strict_mode) {
+  PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
+}
+
+
 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
-                             Handle<TypeFeedbackVector> vector,
-                             Handle<Smi> slot, const CallICState& state) {
+                             const CallICState& callic_state) {
   DCHECK(FLAG_use_ic && function->IsJSFunction());
 
   // Are we the array function?
@@ -1898,43 +2147,33 @@
       Handle<JSFunction>(isolate()->native_context()->array_function());
   if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) {
     // Alter the slot.
-    IC::State old_state = FeedbackToState(vector, slot);
-    Object* feedback = vector->get(slot->value());
-    if (!feedback->IsAllocationSite()) {
-      Handle<AllocationSite> new_site =
-          isolate()->factory()->NewAllocationSite();
-      vector->set(slot->value(), *new_site);
-    }
+    CallICNexus* nexus = casted_nexus<CallICNexus>();
+    nexus->ConfigureMonomorphicArray();
 
-    CallIC_ArrayStub stub(isolate(), state);
+    CallIC_ArrayStub stub(isolate(), callic_state);
     set_target(*stub.GetCode());
     Handle<String> name;
     if (array_function->shared()->name()->IsString()) {
       name = Handle<String>(String::cast(array_function->shared()->name()),
                             isolate());
     }
-
-    IC::State new_state = FeedbackToState(vector, slot);
-    OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true);
-    TRACE_VECTOR_IC("CallIC (custom handler)", name, old_state, new_state);
+    TRACE_IC("CallIC", name);
+    OnTypeFeedbackChanged(isolate(), get_host(), nexus->vector(), state(),
+                          MONOMORPHIC);
     return true;
   }
   return false;
 }
 
 
-void CallIC::PatchMegamorphic(Handle<Object> function,
-                              Handle<TypeFeedbackVector> vector,
-                              Handle<Smi> slot) {
-  CallICState state(target()->extra_ic_state());
-  IC::State old_state = FeedbackToState(vector, slot);
+void CallIC::PatchMegamorphic(Handle<Object> function) {
+  CallICState callic_state(target()->extra_ic_state());
 
   // We are going generic.
-  vector->set(slot->value(),
-              *TypeFeedbackVector::MegamorphicSentinel(isolate()),
-              SKIP_WRITE_BARRIER);
+  CallICNexus* nexus = casted_nexus<CallICNexus>();
+  nexus->ConfigureGeneric();
 
-  CallICStub stub(isolate(), state);
+  CallICStub stub(isolate(), callic_state);
   Handle<Code> code = stub.GetCode();
   set_target(*code);
 
@@ -1944,27 +2183,24 @@
     name = handle(js_function->shared()->name(), isolate());
   }
 
-  IC::State new_state = FeedbackToState(vector, slot);
-  OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true);
-  TRACE_VECTOR_IC("CallIC", name, old_state, new_state);
+  TRACE_IC("CallIC", name);
+  OnTypeFeedbackChanged(isolate(), get_host(), nexus->vector(), state(),
+                        GENERIC);
 }
 
 
-void CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function,
-                        Handle<TypeFeedbackVector> vector, Handle<Smi> slot) {
-  CallICState state(target()->extra_ic_state());
-  IC::State old_state = FeedbackToState(vector, slot);
+void CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function) {
+  CallICState callic_state(target()->extra_ic_state());
   Handle<Object> name = isolate()->factory()->empty_string();
-  Object* feedback = vector->get(slot->value());
+  CallICNexus* nexus = casted_nexus<CallICNexus>();
+  Object* feedback = nexus->GetFeedback();
 
   // Hand-coded MISS handling is easier if CallIC slots don't contain smis.
   DCHECK(!feedback->IsSmi());
 
   if (feedback->IsJSFunction() || !function->IsJSFunction()) {
     // We are going generic.
-    vector->set(slot->value(),
-                *TypeFeedbackVector::MegamorphicSentinel(isolate()),
-                SKIP_WRITE_BARRIER);
+    nexus->ConfigureGeneric();
   } else {
     // The feedback is either uninitialized or an allocation site.
     // It might be an allocation site because if we re-compile the full code
@@ -1976,12 +2212,11 @@
            feedback->IsAllocationSite());
 
     // Do we want to install a custom handler?
-    if (FLAG_use_ic &&
-        DoCustomHandler(receiver, function, vector, slot, state)) {
+    if (FLAG_use_ic && DoCustomHandler(receiver, function, callic_state)) {
       return;
     }
 
-    vector->set(slot->value(), *function);
+    nexus->ConfigureMonomorphic(Handle<JSFunction>::cast(function));
   }
 
   if (function->IsJSFunction()) {
@@ -1989,9 +2224,9 @@
     name = handle(js_function->shared()->name(), isolate());
   }
 
-  IC::State new_state = FeedbackToState(vector, slot);
-  OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true);
-  TRACE_VECTOR_IC("CallIC", name, old_state, new_state);
+  IC::State new_state = nexus->StateFromFeedback();
+  OnTypeFeedbackChanged(isolate(), get_host(), *vector(), state(), new_state);
+  TRACE_IC("CallIC", name);
 }
 
 
@@ -2007,12 +2242,14 @@
   TimerEventScope<TimerEventIcMiss> timer(isolate);
   HandleScope scope(isolate);
   DCHECK(args.length() == 4);
-  CallIC ic(isolate);
   Handle<Object> receiver = args.at<Object>(0);
   Handle<Object> function = args.at<Object>(1);
   Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2);
   Handle<Smi> slot = args.at<Smi>(3);
-  ic.HandleMiss(receiver, function, vector, slot);
+  FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
+  CallICNexus nexus(vector, vector_slot);
+  CallIC ic(isolate, &nexus);
+  ic.HandleMiss(receiver, function);
   return *function;
 }
 
@@ -2021,12 +2258,14 @@
   TimerEventScope<TimerEventIcMiss> timer(isolate);
   HandleScope scope(isolate);
   DCHECK(args.length() == 4);
-  // A miss on a custom call ic always results in going megamorphic.
-  CallIC ic(isolate);
   Handle<Object> function = args.at<Object>(1);
   Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2);
   Handle<Smi> slot = args.at<Smi>(3);
-  ic.PatchMegamorphic(function, vector, slot);
+  FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
+  CallICNexus nexus(vector, vector_slot);
+  // A miss on a custom call ic always results in going megamorphic.
+  CallIC ic(isolate, &nexus);
+  ic.PatchMegamorphic(function);
   return *function;
 }
 
@@ -2035,13 +2274,38 @@
 RUNTIME_FUNCTION(LoadIC_Miss) {
   TimerEventScope<TimerEventIcMiss> timer(isolate);
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
   Handle<Object> receiver = args.at<Object>(0);
   Handle<Name> key = args.at<Name>(1);
-  ic.UpdateState(receiver, key);
   Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
+
+  if (FLAG_vector_ics) {
+    DCHECK(args.length() == 4);
+    Handle<Smi> slot = args.at<Smi>(2);
+    Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
+    FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
+    // A monomorphic or polymorphic KeyedLoadIC with a string key can call the
+    // LoadIC miss handler if the handler misses. Since the vector Nexus is
+    // set up outside the IC, handle that here.
+    if (vector->GetKind(vector_slot) == Code::LOAD_IC) {
+      LoadICNexus nexus(vector, vector_slot);
+      LoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
+      ic.UpdateState(receiver, key);
+      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                         ic.Load(receiver, key));
+    } else {
+      DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
+      KeyedLoadICNexus nexus(vector, vector_slot);
+      KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
+      ic.UpdateState(receiver, key);
+      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                         ic.Load(receiver, key));
+    }
+  } else {
+    DCHECK(args.length() == 2);
+    LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
+    ic.UpdateState(receiver, key);
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
+  }
   return *result;
 }
 
@@ -2050,13 +2314,26 @@
 RUNTIME_FUNCTION(KeyedLoadIC_Miss) {
   TimerEventScope<TimerEventIcMiss> timer(isolate);
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
   Handle<Object> receiver = args.at<Object>(0);
   Handle<Object> key = args.at<Object>(1);
-  ic.UpdateState(receiver, key);
   Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
+
+  if (FLAG_vector_ics) {
+    DCHECK(args.length() == 4);
+    Handle<Smi> slot = args.at<Smi>(2);
+    Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
+    FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
+    KeyedLoadICNexus nexus(vector, vector_slot);
+    KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate, &nexus);
+    ic.UpdateState(receiver, key);
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
+  } else {
+    DCHECK(args.length() == 2);
+    KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
+    ic.UpdateState(receiver, key);
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
+  }
+
   return *result;
 }
 
@@ -2064,13 +2341,26 @@
 RUNTIME_FUNCTION(KeyedLoadIC_MissFromStubFailure) {
   TimerEventScope<TimerEventIcMiss> timer(isolate);
   HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
   Handle<Object> receiver = args.at<Object>(0);
   Handle<Object> key = args.at<Object>(1);
-  ic.UpdateState(receiver, key);
   Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
+
+  if (FLAG_vector_ics) {
+    DCHECK(args.length() == 4);
+    Handle<Smi> slot = args.at<Smi>(2);
+    Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
+    FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
+    KeyedLoadICNexus nexus(vector, vector_slot);
+    KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
+    ic.UpdateState(receiver, key);
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
+  } else {
+    DCHECK(args.length() == 2);
+    KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
+    ic.UpdateState(receiver, key);
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
+  }
+
   return *result;
 }
 
@@ -2082,7 +2372,7 @@
   DCHECK(args.length() == 3);
   StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
   Handle<Object> receiver = args.at<Object>(0);
-  Handle<String> key = args.at<String>(1);
+  Handle<Name> key = args.at<Name>(1);
   ic.UpdateState(receiver, key);
   Handle<Object> result;
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
@@ -2094,10 +2384,10 @@
 RUNTIME_FUNCTION(StoreIC_MissFromStubFailure) {
   TimerEventScope<TimerEventIcMiss> timer(isolate);
   HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
+  DCHECK(args.length() == 3 || args.length() == 4);
   StoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
   Handle<Object> receiver = args.at<Object>(0);
-  Handle<String> key = args.at<String>(1);
+  Handle<Name> key = args.at<Name>(1);
   ic.UpdateState(receiver, key);
   Handle<Object> result;
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
@@ -2106,30 +2396,6 @@
 }
 
 
-// Extend storage is called in a store inline cache when
-// it is necessary to extend the properties array of a
-// JSObject.
-RUNTIME_FUNCTION(SharedStoreIC_ExtendStorage) {
-  TimerEventScope<TimerEventIcMiss> timer(isolate);
-  HandleScope shs(isolate);
-  DCHECK(args.length() == 3);
-
-  // Convert the parameters
-  Handle<JSObject> object = args.at<JSObject>(0);
-  Handle<Map> transition = args.at<Map>(1);
-  Handle<Object> value = args.at<Object>(2);
-
-  // Check the object has run out out property space.
-  DCHECK(object->HasFastProperties());
-  DCHECK(object->map()->unused_property_fields() == 0);
-
-  JSObject::MigrateToNewProperty(object, transition, value);
-
-  // Return the stored value.
-  return *value;
-}
-
-
 // Used from ic-<arch>.cc.
 RUNTIME_FUNCTION(KeyedStoreIC_Miss) {
   TimerEventScope<TimerEventIcMiss> timer(isolate);
@@ -2268,7 +2534,7 @@
     if (!allocation_site.is_null()) {
       os << " using allocation site " << static_cast<void*>(*allocation_site);
     }
-    os << "]" << endl;
+    os << "]" << std::endl;
   }
 
   // Patch the inlined smi code as necessary.
@@ -2544,19 +2810,17 @@
  */
 RUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly) {
   DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength);
-  Handle<Name> name_handle =
+  Handle<Name> name =
       args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex);
   Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(
       NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex);
 
-  // TODO(rossberg): Support symbols in the API.
-  if (name_handle->IsSymbol())
+  if (name->IsSymbol() && !interceptor_info->can_intercept_symbols())
     return isolate->heap()->no_interceptor_result_sentinel();
-  Handle<String> name = Handle<String>::cast(name_handle);
 
   Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
-  v8::NamedPropertyGetterCallback getter =
-      FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address);
+  v8::GenericNamedPropertyGetterCallback getter =
+      FUNCTION_CAST<v8::GenericNamedPropertyGetterCallback>(getter_address);
   DCHECK(getter != NULL);
 
   Handle<JSObject> receiver =
@@ -2586,7 +2850,7 @@
   // If the load is non-contextual, just return the undefined result.
   // Note that both keyed and non-keyed loads may end up here.
   HandleScope scope(isolate);
-  LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
+  LoadIC ic(IC::NO_EXTRA_FRAME, isolate, true);
   if (ic.contextual_mode() != CONTEXTUAL) {
     return isolate->heap()->undefined_value();
   }
@@ -2634,7 +2898,7 @@
   PrototypeIterator iter(isolate, receiver,
                          PrototypeIterator::START_AT_RECEIVER);
   bool found = false;
-  while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
+  for (; !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
     Handle<Object> current = PrototypeIterator::GetCurrent(iter);
     if (current->IsJSObject() &&
         Handle<JSObject>::cast(current)->HasNamedInterceptor()) {
@@ -2660,20 +2924,48 @@
   Handle<Object> result;
   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
       isolate, result,
-      JSObject::GetElementWithInterceptor(receiver, receiver, index));
+      JSObject::GetElementWithInterceptor(receiver, receiver, index, true));
   return *result;
 }
 
 
-RUNTIME_FUNCTION(VectorLoadIC_MissFromStubFailure) {
-  // TODO(mvstanton): To be enabled when ICs can accept a vector and slot
-  return NULL;
-}
+RUNTIME_FUNCTION(LoadIC_MissFromStubFailure) {
+  TimerEventScope<TimerEventIcMiss> timer(isolate);
+  HandleScope scope(isolate);
+  Handle<Object> receiver = args.at<Object>(0);
+  Handle<Name> key = args.at<Name>(1);
+  Handle<Object> result;
 
+  if (FLAG_vector_ics) {
+    DCHECK(args.length() == 4);
+    Handle<Smi> slot = args.at<Smi>(2);
+    Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(3);
+    FeedbackVectorICSlot vector_slot = vector->ToICSlot(slot->value());
+    // A monomorphic or polymorphic KeyedLoadIC with a string key can call the
+    // LoadIC miss handler if the handler misses. Since the vector Nexus is
+    // set up outside the IC, handle that here.
+    if (vector->GetKind(vector_slot) == Code::LOAD_IC) {
+      LoadICNexus nexus(vector, vector_slot);
+      LoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
+      ic.UpdateState(receiver, key);
+      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                         ic.Load(receiver, key));
+    } else {
+      DCHECK(vector->GetKind(vector_slot) == Code::KEYED_LOAD_IC);
+      KeyedLoadICNexus nexus(vector, vector_slot);
+      KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus);
+      ic.UpdateState(receiver, key);
+      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                         ic.Load(receiver, key));
+    }
+  } else {
+    DCHECK(args.length() == 2);
+    LoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
+    ic.UpdateState(receiver, key);
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key));
+  }
 
-RUNTIME_FUNCTION(VectorKeyedLoadIC_MissFromStubFailure) {
-  // TODO(mvstanton): To be enabled when ICs can accept a vector and slot
-  return NULL;
+  return *result;
 }
 
 
diff --git a/src/ic/ic.h b/src/ic/ic.h
index d86d2b7..541fa0c 100644
--- a/src/ic/ic.h
+++ b/src/ic/ic.h
@@ -21,7 +21,6 @@
   ICU(CallIC_Customization_Miss)       \
   ICU(StoreIC_Miss)                    \
   ICU(StoreIC_Slow)                    \
-  ICU(SharedStoreIC_ExtendStorage)     \
   ICU(KeyedStoreIC_Miss)               \
   ICU(KeyedStoreIC_Slow)               \
   /* Utilities for IC stubs. */        \
@@ -60,7 +59,8 @@
 
   // Construct the IC structure with the given number of extra
   // JavaScript frames on the stack.
-  IC(FrameDepth depth, Isolate* isolate);
+  IC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL,
+     bool for_queries_only = false);
   virtual ~IC() {}
 
   State state() const { return state_; }
@@ -72,17 +72,10 @@
   bool IsNameCompatibleWithPrototypeFailure(Handle<Object> name);
   void MarkPrototypeFailure(Handle<Object> name) {
     DCHECK(IsNameCompatibleWithPrototypeFailure(name));
+    old_state_ = state_;
     state_ = PROTOTYPE_FAILURE;
   }
 
-  // If the stub contains weak maps then this function adds the stub to
-  // the dependent code array of each weak map.
-  static void RegisterWeakMapDependency(Handle<Code> stub);
-
-  // This function is called when a weak map in the stub is dying,
-  // invalidates the stub by setting maps in it to undefined.
-  static void InvalidateMaps(Code* stub);
-
   // Clear the inline cache to initial state.
   static void Clear(Isolate* isolate, Address address,
                     ConstantPoolArray* constant_pool);
@@ -114,6 +107,11 @@
     return state == UNINITIALIZED || state == PREMONOMORPHIC;
   }
 
+  static bool IsCleared(FeedbackNexus* nexus) {
+    InlineCacheState state = nexus->StateFromFeedback();
+    return state == UNINITIALIZED || state == PREMONOMORPHIC;
+  }
+
   // Utility functions to convert maps to types and back. There are two special
   // cases:
   // - The heap_number_map is used as a marker which includes heap numbers as
@@ -127,6 +125,12 @@
   static Handle<HeapType> CurrentTypeOf(Handle<Object> object,
                                         Isolate* isolate);
 
+  static bool ICUseVector(Code::Kind kind) {
+    return (FLAG_vector_ics &&
+            (kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC)) ||
+           kind == Code::CALL_IC;
+  }
+
  protected:
   // Get the call-site target; used for determining the state.
   Handle<Code> target() const { return target_; }
@@ -146,6 +150,22 @@
   inline void set_target(Code* code);
   bool is_target_set() { return target_set_; }
 
+  bool UseVector() const {
+    bool use = ICUseVector(kind());
+    // If we are supposed to use the nexus, verify the nexus is non-null.
+    DCHECK(!use || nexus_ != NULL);
+    return use;
+  }
+
+  // Configure for most states.
+  void ConfigureVectorState(IC::State new_state);
+  // Configure the vector for MONOMORPHIC.
+  void ConfigureVectorState(Handle<Name> name, Handle<HeapType> type,
+                            Handle<Code> handler);
+  // Configure the vector for POLYMORPHIC.
+  void ConfigureVectorState(Handle<Name> name, TypeHandleList* types,
+                            CodeHandleList* handlers);
+
   char TransitionMarkFromState(IC::State state);
   void TraceIC(const char* type, Handle<Object> name);
   void TraceIC(const char* type, Handle<Object> name, State old_state,
@@ -163,6 +183,10 @@
   static void OnTypeFeedbackChanged(Isolate* isolate, Address address,
                                     State old_state, State new_state,
                                     bool target_remains_ic_stub);
+  // As a vector-based IC, type feedback must be updated differently.
+  static void OnTypeFeedbackChanged(Isolate* isolate, Code* host,
+                                    TypeFeedbackVector* vector, State old_state,
+                                    State new_state);
   static void PostPatching(Address address, Code* target, Code* old_target);
 
   // Compute the handler either by compiling or by retrieving a cached version.
@@ -224,9 +248,22 @@
     return target_maps_.length() > 0 ? *target_maps_.at(0) : NULL;
   }
 
- protected:
   inline void UpdateTarget();
 
+  Handle<TypeFeedbackVector> vector() const { return nexus()->vector_handle(); }
+  FeedbackVectorICSlot slot() const { return nexus()->slot(); }
+  State saved_state() const {
+    return state() == PROTOTYPE_FAILURE ? old_state_ : state();
+  }
+
+  template <class NexusClass>
+  NexusClass* casted_nexus() {
+    return static_cast<NexusClass*>(nexus_);
+  }
+  FeedbackNexus* nexus() const { return nexus_; }
+
+  inline Code* get_host();
+
  private:
   inline Code* raw_target() const;
   inline ConstantPoolArray* constant_pool() const;
@@ -235,11 +272,15 @@
   void FindTargetMaps() {
     if (target_maps_set_) return;
     target_maps_set_ = true;
-    if (state_ == MONOMORPHIC) {
-      Map* map = target_->FindFirstMap();
-      if (map != NULL) target_maps_.Add(handle(map));
-    } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) {
-      target_->FindAllMaps(&target_maps_);
+    if (UseVector()) {
+      nexus()->ExtractMaps(&target_maps_);
+    } else {
+      if (state_ == MONOMORPHIC) {
+        Map* map = target_->FindFirstMap();
+        if (map != NULL) target_maps_.Add(handle(map));
+      } else if (state_ != UNINITIALIZED && state_ != PREMONOMORPHIC) {
+        target_->FindAllMaps(&target_maps_);
+      }
     }
   }
 
@@ -261,6 +302,7 @@
   // The original code target that missed.
   Handle<Code> target_;
   bool target_set_;
+  State old_state_;  // For saving if we marked as prototype failure.
   State state_;
   Code::Kind kind_;
   Handle<HeapType> receiver_type_;
@@ -270,6 +312,8 @@
   MapHandleList target_maps_;
   bool target_maps_set_;
 
+  FeedbackNexus* nexus_;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(IC);
 };
 
@@ -293,29 +337,24 @@
 
 class CallIC : public IC {
  public:
-  explicit CallIC(Isolate* isolate) : IC(EXTRA_CALL_FRAME, isolate) {}
+  CallIC(Isolate* isolate, CallICNexus* nexus)
+      : IC(EXTRA_CALL_FRAME, isolate, nexus) {
+    DCHECK(nexus != NULL);
+  }
 
-  void PatchMegamorphic(Handle<Object> function,
-                        Handle<TypeFeedbackVector> vector, Handle<Smi> slot);
+  void PatchMegamorphic(Handle<Object> function);
 
-  void HandleMiss(Handle<Object> receiver, Handle<Object> function,
-                  Handle<TypeFeedbackVector> vector, Handle<Smi> slot);
+  void HandleMiss(Handle<Object> receiver, Handle<Object> function);
 
   // Returns true if a custom handler was installed.
   bool DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
-                       Handle<TypeFeedbackVector> vector, Handle<Smi> slot,
-                       const CallICState& state);
+                       const CallICState& callic_state);
 
   // Code generator routines.
   static Handle<Code> initialize_stub(Isolate* isolate, int argc,
                                       CallICState::CallType call_type);
 
-  static void Clear(Isolate* isolate, Address address, Code* target,
-                    ConstantPoolArray* constant_pool);
-
- private:
-  inline IC::State FeedbackToState(Handle<TypeFeedbackVector> vector,
-                                   Handle<Smi> slot) const;
+  static void Clear(Isolate* isolate, Code* host, CallICNexus* nexus);
 };
 
 
@@ -329,7 +368,18 @@
     return LoadICState::GetContextualMode(extra_ic_state());
   }
 
-  explicit LoadIC(FrameDepth depth, Isolate* isolate) : IC(depth, isolate) {
+  LoadIC(FrameDepth depth, Isolate* isolate, FeedbackNexus* nexus = NULL)
+      : IC(depth, isolate, nexus) {
+    DCHECK(!FLAG_vector_ics || nexus != NULL);
+    DCHECK(IsLoadStub());
+  }
+
+  // TODO(mvstanton): The for_queries_only is because we have a case where we
+  // construct an IC only to gather the contextual mode, and we don't have
+  // vector/slot information. for_queries_only is a temporary hack to enable the
+  // strong DCHECK protection around vector/slot.
+  LoadIC(FrameDepth depth, Isolate* isolate, bool for_queries_only)
+      : IC(depth, isolate, NULL, for_queries_only) {
     DCHECK(IsLoadStub());
   }
 
@@ -355,10 +405,14 @@
 
   static Handle<Code> initialize_stub(Isolate* isolate,
                                       ExtraICState extra_state);
+  static Handle<Code> initialize_stub_in_optimized_code(
+      Isolate* isolate, ExtraICState extra_state);
 
   MUST_USE_RESULT MaybeHandle<Object> Load(Handle<Object> object,
                                            Handle<Name> name);
 
+  static void Clear(Isolate* isolate, Code* host, LoadICNexus* nexus);
+
  protected:
   inline void set_target(Code* code);
 
@@ -371,7 +425,7 @@
     }
   }
 
-  virtual Handle<Code> megamorphic_stub() OVERRIDE;
+  Handle<Code> megamorphic_stub() OVERRIDE;
 
   // Update the inline cache and the global stub cache based on the
   // lookup result.
@@ -379,7 +433,7 @@
 
   virtual Handle<Code> CompileHandler(LookupIterator* lookup,
                                       Handle<Object> unused,
-                                      CacheHolderFlag cache_holder);
+                                      CacheHolderFlag cache_holder) OVERRIDE;
 
  private:
   virtual Handle<Code> pre_monomorphic_stub() const;
@@ -397,8 +451,23 @@
 
 class KeyedLoadIC : public LoadIC {
  public:
-  explicit KeyedLoadIC(FrameDepth depth, Isolate* isolate)
-      : LoadIC(depth, isolate) {
+  // ExtraICState bits (building on IC)
+  class IcCheckTypeField : public BitField<IcCheckType, 1, 1> {};
+
+  static ExtraICState ComputeExtraICState(ContextualMode contextual_mode,
+                                          IcCheckType key_type) {
+    return LoadICState(contextual_mode).GetExtraICState() |
+           IcCheckTypeField::encode(key_type);
+  }
+
+  static IcCheckType GetKeyType(ExtraICState extra_state) {
+    return IcCheckTypeField::decode(extra_state);
+  }
+
+  KeyedLoadIC(FrameDepth depth, Isolate* isolate,
+              KeyedLoadICNexus* nexus = NULL)
+      : LoadIC(depth, isolate, nexus) {
+    DCHECK(!FLAG_vector_ics || nexus != NULL);
     DCHECK(target()->is_keyed_load_stub());
   }
 
@@ -413,7 +482,6 @@
     GenerateMiss(masm);
   }
   static void GenerateGeneric(MacroAssembler* masm);
-  static void GenerateString(MacroAssembler* masm);
 
   // Bit mask to be tested against bit field for the cases when
   // generic stub should go into slow case.
@@ -422,20 +490,22 @@
   static const int kSlowCaseBitFieldMask =
       (1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor);
 
+  static Handle<Code> initialize_stub(Isolate* isolate);
+  static Handle<Code> initialize_stub_in_optimized_code(Isolate* isolate);
   static Handle<Code> generic_stub(Isolate* isolate);
   static Handle<Code> pre_monomorphic_stub(Isolate* isolate);
 
+  static void Clear(Isolate* isolate, Code* host, KeyedLoadICNexus* nexus);
+
  protected:
-  Handle<Code> LoadElementStub(Handle<JSObject> receiver);
+  // receiver is HeapObject because it could be a String or a JSObject
+  Handle<Code> LoadElementStub(Handle<HeapObject> receiver);
   virtual Handle<Code> pre_monomorphic_stub() const {
     return pre_monomorphic_stub(isolate());
   }
 
  private:
   Handle<Code> generic_stub() const { return generic_stub(isolate()); }
-  Handle<Code> string_stub() {
-    return isolate()->builtins()->KeyedLoadIC_String();
-  }
 
   static void Clear(Isolate* isolate, Address address, Code* target,
                     ConstantPoolArray* constant_pool);
@@ -489,7 +559,7 @@
                       JSReceiver::StoreFromKeyed store_mode);
 
  protected:
-  virtual Handle<Code> megamorphic_stub() OVERRIDE;
+  Handle<Code> megamorphic_stub() OVERRIDE;
 
   // Stub accessors.
   Handle<Code> generic_stub() const;
@@ -509,7 +579,7 @@
                     JSReceiver::StoreFromKeyed store_mode);
   virtual Handle<Code> CompileHandler(LookupIterator* lookup,
                                       Handle<Object> value,
-                                      CacheHolderFlag cache_holder);
+                                      CacheHolderFlag cache_holder) OVERRIDE;
 
  private:
   inline void set_target(Code* code);
@@ -534,10 +604,13 @@
   class ExtraICStateKeyedAccessStoreMode
       : public BitField<KeyedAccessStoreMode, 2, 4> {};  // NOLINT
 
+  class IcCheckTypeField : public BitField<IcCheckType, 6, 1> {};
+
   static ExtraICState ComputeExtraICState(StrictMode flag,
                                           KeyedAccessStoreMode mode) {
     return StrictModeState::encode(flag) |
-           ExtraICStateKeyedAccessStoreMode::encode(mode);
+           ExtraICStateKeyedAccessStoreMode::encode(mode) |
+           IcCheckTypeField::encode(ELEMENT);
   }
 
   static KeyedAccessStoreMode GetKeyedAccessStoreMode(
@@ -545,6 +618,10 @@
     return ExtraICStateKeyedAccessStoreMode::decode(extra_state);
   }
 
+  static IcCheckType GetKeyType(ExtraICState extra_state) {
+    return IcCheckTypeField::decode(extra_state);
+  }
+
   KeyedStoreIC(FrameDepth depth, Isolate* isolate) : StoreIC(depth, isolate) {
     DCHECK(target()->is_keyed_store_stub());
   }
@@ -560,6 +637,7 @@
   }
   static void GenerateMiss(MacroAssembler* masm);
   static void GenerateSlow(MacroAssembler* masm);
+  static void GenerateMegamorphic(MacroAssembler* masm, StrictMode strict_mode);
   static void GenerateGeneric(MacroAssembler* masm, StrictMode strict_mode);
   static void GenerateSloppyArguments(MacroAssembler* masm);
 
@@ -681,8 +759,7 @@
 DECLARE_RUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite);
 DECLARE_RUNTIME_FUNCTION(CompareNilIC_Miss);
 DECLARE_RUNTIME_FUNCTION(ToBooleanIC_Miss);
-DECLARE_RUNTIME_FUNCTION(VectorLoadIC_MissFromStubFailure);
-DECLARE_RUNTIME_FUNCTION(VectorKeyedLoadIC_MissFromStubFailure);
+DECLARE_RUNTIME_FUNCTION(LoadIC_MissFromStubFailure);
 
 // Support functions for callbacks handlers.
 DECLARE_RUNTIME_FUNCTION(StoreCallbackProperty);
diff --git a/src/ic/mips/handler-compiler-mips.cc b/src/ic/mips/handler-compiler-mips.cc
index 5b4555f..75032e1 100644
--- a/src/ic/mips/handler-compiler-mips.cc
+++ b/src/ic/mips/handler-compiler-mips.cc
@@ -92,6 +92,26 @@
 }
 
 
+void PropertyHandlerCompiler::PushVectorAndSlot(Register vector,
+                                                Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ Push(vector, slot);
+}
+
+
+void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ Pop(vector, slot);
+}
+
+
+void PropertyHandlerCompiler::DiscardVectorAndSlot() {
+  MacroAssembler* masm = this->masm();
+  // Remove vector and slot.
+  __ Addu(sp, sp, Operand(2 * kPointerSize));
+}
+
+
 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
     MacroAssembler* masm, Label* miss_label, Register receiver,
     Handle<Name> name, Register scratch0, Register scratch1) {
@@ -138,25 +158,16 @@
 
 
 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
-    MacroAssembler* masm, int index, Register prototype, Label* miss) {
-  Isolate* isolate = masm->isolate();
-  // Get the global function with the given index.
-  Handle<JSFunction> function(
-      JSFunction::cast(isolate->native_context()->get(index)));
-
-  // Check we're still in the same context.
-  Register scratch = prototype;
+    MacroAssembler* masm, int index, Register result, Label* miss) {
   const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
-  __ lw(scratch, MemOperand(cp, offset));
-  __ lw(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
-  __ lw(scratch, MemOperand(scratch, Context::SlotOffset(index)));
-  __ li(at, function);
-  __ Branch(miss, ne, at, Operand(scratch));
-
+  __ lw(result, MemOperand(cp, offset));
+  __ lw(result, FieldMemOperand(result, GlobalObject::kNativeContextOffset));
+  __ lw(result, MemOperand(result, Context::SlotOffset(index)));
   // Load its initial map. The global functions all have initial maps.
-  __ li(prototype, Handle<Map>(function->initial_map()));
+  __ lw(result,
+        FieldMemOperand(result, JSFunction::kPrototypeOrInitialMapOffset));
   // Load the prototype from the initial map.
-  __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
+  __ lw(result, FieldMemOperand(result, Map::kPrototypeOffset));
 }
 
 
@@ -321,186 +332,62 @@
 }
 
 
-// Generate StoreTransition code, value is passed in a0 register.
-// After executing generated code, the receiver_reg and name_reg
-// may be clobbered.
-void NamedStoreHandlerCompiler::GenerateStoreTransition(
-    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
-    Register storage_reg, Register value_reg, Register scratch1,
-    Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
-  // a0 : value.
-  Label exit;
-
-  int descriptor = transition->LastAdded();
-  DescriptorArray* descriptors = transition->instance_descriptors();
-  PropertyDetails details = descriptors->GetDetails(descriptor);
-  Representation representation = details.representation();
-  DCHECK(!representation.IsNone());
-
-  if (details.type() == CONSTANT) {
-    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
-    __ li(scratch1, constant);
-    __ Branch(miss_label, ne, value_reg, Operand(scratch1));
-  } else if (representation.IsSmi()) {
-    __ JumpIfNotSmi(value_reg, miss_label);
-  } else if (representation.IsHeapObject()) {
-    __ JumpIfSmi(value_reg, miss_label);
-    HeapType* field_type = descriptors->GetFieldType(descriptor);
-    HeapType::Iterator<Map> it = field_type->Classes();
-    Handle<Map> current;
-    if (!it.Done()) {
-      __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
-      Label do_store;
-      while (true) {
-        // Do the CompareMap() directly within the Branch() functions.
-        current = it.Current();
-        it.Advance();
-        if (it.Done()) {
-          __ Branch(miss_label, ne, scratch1, Operand(current));
-          break;
-        }
-        __ Branch(&do_store, eq, scratch1, Operand(current));
-      }
-      __ bind(&do_store);
-    }
-  } else if (representation.IsDouble()) {
-    Label do_store, heap_number;
-    __ LoadRoot(scratch3, Heap::kMutableHeapNumberMapRootIndex);
-    __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow,
-                          TAG_RESULT, MUTABLE);
-
-    __ JumpIfNotSmi(value_reg, &heap_number);
-    __ SmiUntag(scratch1, value_reg);
-    __ mtc1(scratch1, f6);
-    __ cvt_d_w(f4, f6);
-    __ jmp(&do_store);
-
-    __ bind(&heap_number);
-    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
-                DONT_DO_SMI_CHECK);
-    __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
-
-    __ bind(&do_store);
-    __ sdc1(f4, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
-  }
-
-  // Stub never generated for objects that require access checks.
-  DCHECK(!transition->is_access_check_needed());
-
-  // Perform map transition for the receiver if necessary.
-  if (details.type() == FIELD &&
-      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
-    // The properties must be extended before we can store the value.
-    // We jump to a runtime call that extends the properties array.
-    __ push(receiver_reg);
-    __ li(a2, Operand(transition));
-    __ Push(a2, a0);
-    __ TailCallExternalReference(
-        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                          isolate()),
-        3, 1);
-    return;
-  }
-
-  // Update the map of the object.
-  __ li(scratch1, Operand(transition));
-  __ sw(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
-
-  // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
-                      kRAHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
-                      OMIT_SMI_CHECK);
-
-  if (details.type() == CONSTANT) {
-    DCHECK(value_reg.is(a0));
-    __ Ret(USE_DELAY_SLOT);
-    __ mov(v0, a0);
-    return;
-  }
-
-  int index = transition->instance_descriptors()->GetFieldIndex(
-      transition->LastAdded());
-
-  // Adjust for the number of properties stored in the object. Even in the
-  // face of a transition we can use the old map here because the size of the
-  // object and the number of in-object properties is not going to change.
-  index -= transition->inobject_properties();
-
-  // TODO(verwaest): Share this code as a code stub.
-  SmiCheck smi_check =
-      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
-  if (index < 0) {
-    // Set the property straight into the object.
-    int offset = transition->instance_size() + (index * kPointerSize);
-    if (representation.IsDouble()) {
-      __ sw(storage_reg, FieldMemOperand(receiver_reg, offset));
-    } else {
-      __ sw(value_reg, FieldMemOperand(receiver_reg, offset));
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
-                          kRAHasNotBeenSaved, kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET, smi_check);
-    }
-  } else {
-    // Write to the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    // Get the properties array
-    __ lw(scratch1, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
-    if (representation.IsDouble()) {
-      __ sw(storage_reg, FieldMemOperand(scratch1, offset));
-    } else {
-      __ sw(value_reg, FieldMemOperand(scratch1, offset));
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
-                          kRAHasNotBeenSaved, kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET, smi_check);
-    }
-  }
-
-  // Return the value (register v0).
-  DCHECK(value_reg.is(a0));
-  __ bind(&exit);
-  __ Ret(USE_DELAY_SLOT);
-  __ mov(v0, a0);
+void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
+  __ li(this->name(), Operand(name));
 }
 
 
-void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
-                                                   Register value_reg,
-                                                   Label* miss_label) {
-  DCHECK(lookup->representation().IsHeapObject());
-  __ JumpIfSmi(value_reg, miss_label);
-  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
-  __ lw(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
-  Label do_store;
-  Handle<Map> current;
-  while (true) {
-    // Do the CompareMap() directly within the Branch() functions.
-    current = it.Current();
-    it.Advance();
-    if (it.Done()) {
-      __ Branch(miss_label, ne, scratch1(), Operand(current));
-      break;
-    }
-    __ Branch(&do_store, eq, scratch1(), Operand(current));
+void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition,
+                                                   Register scratch,
+                                                   Label* miss) {
+  Handle<WeakCell> cell = Map::WeakCellForMap(transition);
+  Register map_reg = StoreTransitionDescriptor::MapRegister();
+  DCHECK(!map_reg.is(scratch));
+  __ LoadWeakValue(map_reg, cell, miss);
+  if (transition->CanBeDeprecated()) {
+    __ lw(scratch, FieldMemOperand(map_reg, Map::kBitField3Offset));
+    __ And(at, scratch, Operand(Map::Deprecated::kMask));
+    __ Branch(miss, ne, at, Operand(zero_reg));
   }
-  __ bind(&do_store);
+}
 
-  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
-                      lookup->representation());
-  GenerateTailCall(masm(), stub.GetCode());
+
+void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg,
+                                                      int descriptor,
+                                                      Register value_reg,
+                                                      Register scratch,
+                                                      Label* miss_label) {
+  DCHECK(!map_reg.is(scratch));
+  DCHECK(!map_reg.is(value_reg));
+  DCHECK(!value_reg.is(scratch));
+  __ LoadInstanceDescriptors(map_reg, scratch);
+  __ lw(scratch,
+        FieldMemOperand(scratch, DescriptorArray::GetValueOffset(descriptor)));
+  __ Branch(miss_label, ne, value_reg, Operand(scratch));
+}
+
+
+void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
+                                                        Register value_reg,
+                                                        Label* miss_label) {
+  __ JumpIfSmi(value_reg, miss_label);
+  HeapType::Iterator<Map> it = field_type->Classes();
+  if (!it.Done()) {
+    __ lw(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
+    Label do_store;
+    Handle<Map> current;
+    while (true) {
+      // Do the CompareMap() directly within the Branch() functions.
+      current = it.Current();
+      it.Advance();
+      if (it.Done()) {
+        __ Branch(miss_label, ne, scratch1(), Operand(current));
+        break;
+      }
+      __ Branch(&do_store, eq, scratch1(), Operand(current));
+    }
+    __ bind(&do_store);
+  }
 }
 
 
@@ -556,11 +443,11 @@
       __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
     } else {
       Register map_reg = scratch1;
+      __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
       if (depth != 1 || check == CHECK_ALL_MAPS) {
-        // CheckMap implicitly loads the map of |reg| into |map_reg|.
-        __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK);
-      } else {
-        __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
+        Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+        __ GetWeakValue(scratch2, cell);
+        __ Branch(miss, ne, scratch2, Operand(map_reg));
       }
 
       // Check access rights to the global object.  This has to happen after
@@ -578,17 +465,7 @@
 
       reg = holder_reg;  // From now on the object will be in holder_reg.
 
-      // Two possible reasons for loading the prototype from the map:
-      // (1) Can't store references to new space in code.
-      // (2) Handler is shared for all receivers with the same prototype
-      //     map (but not necessarily the same prototype instance).
-      bool load_prototype_from_map =
-          heap()->InNewSpace(*prototype) || depth == 1;
-      if (load_prototype_from_map) {
-        __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
-      } else {
-        __ li(reg, Operand(prototype));
-      }
+      __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
     }
 
     // Go to the next object in the prototype chain.
@@ -601,7 +478,10 @@
 
   if (depth != 0 || check == CHECK_ALL_MAPS) {
     // Check the holder map.
-    __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK);
+    __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
+    Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+    __ GetWeakValue(scratch2, cell);
+    __ Branch(miss, ne, scratch2, Operand(scratch1));
   }
 
   // Perform security check for access to the global object.
@@ -621,6 +501,10 @@
     Label success;
     __ Branch(&success);
     __ bind(miss);
+    if (IC::ICUseVector(kind())) {
+      DCHECK(kind() == Code::LOAD_IC);
+      PopVectorAndSlot();
+    }
     TailCallBuiltin(masm(), MissBuiltin(kind()));
     __ bind(&success);
   }
@@ -722,6 +606,7 @@
     } else {
       __ Push(holder_reg, this->name());
     }
+    InterceptorVectorSlotPush(holder_reg);
     // Invoke an interceptor.  Note: map checks from receiver to
     // interceptor's holder has been compiled before (see a caller
     // of this method).
@@ -738,6 +623,7 @@
     __ Ret();
 
     __ bind(&interceptor_failed);
+    InterceptorVectorSlotPop(holder_reg);
     if (must_preserve_receiver_reg) {
       __ Pop(receiver(), holder_reg, this->name());
     } else {
@@ -767,7 +653,7 @@
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     Handle<JSObject> object, Handle<Name> name,
     Handle<ExecutableAccessorInfo> callback) {
-  Register holder_reg = Frontend(receiver(), name);
+  Register holder_reg = Frontend(name);
 
   __ Push(receiver(), holder_reg);  // Receiver.
   __ li(at, Operand(callback));     // Callback info.
@@ -807,12 +693,16 @@
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
   Label miss;
+  if (IC::ICUseVector(kind())) {
+    PushVectorAndSlot();
+  }
 
   FrontendHeader(receiver(), name, &miss);
 
   // Get the value from the cell.
   Register result = StoreDescriptor::ValueRegister();
-  __ li(result, Operand(cell));
+  Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell);
+  __ LoadWeakValue(result, weak_cell, &miss);
   __ lw(result, FieldMemOperand(result, Cell::kValueOffset));
 
   // Check for deleted property if property can actually be deleted.
@@ -823,6 +713,9 @@
 
   Counters* counters = isolate()->counters();
   __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3);
+  if (IC::ICUseVector(kind())) {
+    DiscardVectorAndSlot();
+  }
   __ Ret(USE_DELAY_SLOT);
   __ mov(v0, result);
 
diff --git a/src/ic/mips/ic-compiler-mips.cc b/src/ic/mips/ic-compiler-mips.cc
index c1e67f9..6169404 100644
--- a/src/ic/mips/ic-compiler-mips.cc
+++ b/src/ic/mips/ic-compiler-mips.cc
@@ -24,9 +24,12 @@
 
   if (check == PROPERTY &&
       (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
-    // In case we are compiling an IC for dictionary loads and stores, just
+    // In case we are compiling an IC for dictionary loads or stores, just
     // check whether the name is unique.
     if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
+      // Keyed loads with dictionaries shouldn't be here, they go generic.
+      // The DCHECK is to protect assumptions when --vector-ics is on.
+      DCHECK(kind() != Code::KEYED_LOAD_IC);
       Register tmp = scratch1();
       __ JumpIfSmi(this->name(), &miss);
       __ lw(tmp, FieldMemOperand(this->name(), HeapObject::kMapOffset));
@@ -57,7 +60,9 @@
       number_of_handled_maps++;
       // Check map and tail call if there's a match.
       // Separate compare from branch, to provide path for above JumpIfSmi().
-      __ Subu(match, map_reg, Operand(map));
+      Handle<WeakCell> cell = Map::WeakCellForMap(map);
+      __ GetWeakValue(match, cell);
+      __ Subu(match, match, Operand(map_reg));
       if (type->Is(HeapType::Number())) {
         DCHECK(!number_case.is_unused());
         __ bind(&number_case);
@@ -85,15 +90,20 @@
   __ JumpIfSmi(receiver(), &miss);
 
   int receiver_count = receiver_maps->length();
-  __ lw(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  Register map_reg = scratch1();
+  Register match = scratch2();
+  __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
   for (int i = 0; i < receiver_count; ++i) {
+    Handle<WeakCell> cell = Map::WeakCellForMap(receiver_maps->at(i));
+    __ GetWeakValue(match, cell);
     if (transitioned_maps->at(i).is_null()) {
-      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, scratch1(),
-              Operand(receiver_maps->at(i)));
+      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, match,
+              Operand(map_reg));
     } else {
       Label next_map;
-      __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i)));
-      __ li(transition_map(), Operand(transitioned_maps->at(i)));
+      __ Branch(&next_map, ne, match, Operand(map_reg));
+      Handle<WeakCell> cell = Map::WeakCellForMap(transitioned_maps->at(i));
+      __ LoadWeakValue(transition_map(), cell, &miss);
       __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
       __ bind(&next_map);
     }
diff --git a/src/ic/mips/ic-mips.cc b/src/ic/mips/ic-mips.cc
index d97a6ba..7c8a5ea 100644
--- a/src/ic/mips/ic-mips.cc
+++ b/src/ic/mips/ic-mips.cc
@@ -272,18 +272,35 @@
 static const Register LoadIC_TempRegister() { return a3; }
 
 
+static void LoadIC_PushArgs(MacroAssembler* masm) {
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register name = LoadDescriptor::NameRegister();
+  if (FLAG_vector_ics) {
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+
+    __ Push(receiver, name, slot, vector);
+  } else {
+    __ Push(receiver, name);
+  }
+}
+
+
 void LoadIC::GenerateMiss(MacroAssembler* masm) {
   // The return address is in ra.
   Isolate* isolate = masm->isolate();
 
-  __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, t0);
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(t0, t1, VectorLoadICDescriptor::SlotRegister(),
+                     VectorLoadICDescriptor::VectorRegister()));
+  __ IncrementCounter(isolate->counters()->load_miss(), 1, t0, t1);
 
-  __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
-  __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
+  LoadIC_PushArgs(masm);
 
   // Perform tail call to the entry.
   ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
@@ -412,15 +429,19 @@
   // The return address is in ra.
   Isolate* isolate = masm->isolate();
 
-  __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, t0);
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(t0, t1, VectorLoadICDescriptor::SlotRegister(),
+                     VectorLoadICDescriptor::VectorRegister()));
+  __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, t0, t1);
 
-  __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
+  LoadIC_PushArgs(masm);
 
   // Perform tail call to the entry.
   ExternalReference ref =
       ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
 
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
@@ -594,33 +615,7 @@
 }
 
 
-void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
-  // Return address is in ra.
-  Label miss;
-
-  Register receiver = LoadDescriptor::ReceiverRegister();
-  Register index = LoadDescriptor::NameRegister();
-  Register scratch = a3;
-  Register result = v0;
-  DCHECK(!scratch.is(receiver) && !scratch.is(index));
-
-  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
-                                          &miss,  // When not a string.
-                                          &miss,  // When not a number.
-                                          &miss,  // When index out of range.
-                                          STRING_INDEX_IS_ARRAY_INDEX);
-  char_at_generator.GenerateFast(masm);
-  __ Ret();
-
-  StubRuntimeCallHelper call_helper;
-  char_at_generator.GenerateSlow(masm, call_helper);
-
-  __ bind(&miss);
-  GenerateMiss(masm);
-}
-
-
-static void KeyedStoreGenerateGenericHelper(
+static void KeyedStoreGenerateMegamorphicHelper(
     MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
     KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
     Register value, Register key, Register receiver, Register receiver_map,
@@ -766,8 +761,8 @@
 }
 
 
-void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
-                                   StrictMode strict_mode) {
+void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
+                                       StrictMode strict_mode) {
   // ---------- S t a t e --------------
   //  -- a0     : value
   //  -- a1     : key
@@ -776,7 +771,7 @@
   // -----------------------------------
   Label slow, fast_object, fast_object_grow;
   Label fast_double, fast_double_grow;
-  Label array, extra, check_if_double_array;
+  Label array, extra, check_if_double_array, maybe_name_key, miss;
 
   // Register usage.
   Register value = StoreDescriptor::ValueRegister();
@@ -789,7 +784,7 @@
   // t0 and t1 are used as general scratch registers.
 
   // Check that the key is a smi.
-  __ JumpIfNotSmi(key, &slow);
+  __ JumpIfNotSmi(key, &maybe_name_key);
   // Check that the object isn't a smi.
   __ JumpIfSmi(receiver, &slow);
   // Get the map of the object.
@@ -819,6 +814,18 @@
   // a1: key.
   // a2: receiver.
   PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
+  // Never returns to here.
+
+  __ bind(&maybe_name_key);
+  __ lw(t0, FieldMemOperand(key, HeapObject::kMapOffset));
+  __ lb(t0, FieldMemOperand(t0, Map::kInstanceTypeOffset));
+  __ JumpIfNotUniqueNameInstanceType(t0, &slow);
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::STORE_IC));
+  masm->isolate()->stub_cache()->GenerateProbe(
+      masm, Code::STORE_IC, flags, false, receiver, key, a3, t0, t1, t2);
+  // Cache miss.
+  __ Branch(&miss);
 
   // Extra capacity case: Check if there is extra capacity to
   // perform the store and update the length. Used for adding one
@@ -851,13 +858,16 @@
   __ lw(t0, FieldMemOperand(receiver, JSArray::kLengthOffset));
   __ Branch(&extra, hs, key, Operand(t0));
 
-  KeyedStoreGenerateGenericHelper(
+  KeyedStoreGenerateMegamorphicHelper(
       masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength,
       value, key, receiver, receiver_map, elements_map, elements);
-  KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
-                                  &slow, kDontCheckMap, kIncrementLength, value,
-                                  key, receiver, receiver_map, elements_map,
-                                  elements);
+  KeyedStoreGenerateMegamorphicHelper(masm, &fast_object_grow,
+                                      &fast_double_grow, &slow, kDontCheckMap,
+                                      kIncrementLength, value, key, receiver,
+                                      receiver_map, elements_map, elements);
+
+  __ bind(&miss);
+  GenerateMiss(masm);
 }
 
 
@@ -882,8 +892,8 @@
   // Get the receiver from the stack and probe the stub cache.
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::STORE_IC));
-  masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver,
-                                               name, a3, t0, t1, t2);
+  masm->isolate()->stub_cache()->GenerateProbe(
+      masm, Code::STORE_IC, flags, false, receiver, name, a3, t0, t1, t2);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
diff --git a/src/ic/mips/stub-cache-mips.cc b/src/ic/mips/stub-cache-mips.cc
index e538712..fab66d8 100644
--- a/src/ic/mips/stub-cache-mips.cc
+++ b/src/ic/mips/stub-cache-mips.cc
@@ -7,7 +7,9 @@
 #if V8_TARGET_ARCH_MIPS
 
 #include "src/codegen.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
+#include "src/interface-descriptors.h"
 
 namespace v8 {
 namespace internal {
@@ -16,7 +18,7 @@
 
 
 static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
-                       Code::Flags flags, bool leave_frame,
+                       Code::Kind ic_kind, Code::Flags flags, bool leave_frame,
                        StubCache::Table table, Register receiver, Register name,
                        // Number of the cache entry, not scaled.
                        Register offset, Register scratch, Register scratch2,
@@ -90,10 +92,11 @@
 }
 
 
-void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags,
-                              bool leave_frame, Register receiver,
-                              Register name, Register scratch, Register extra,
-                              Register extra2, Register extra3) {
+void StubCache::GenerateProbe(MacroAssembler* masm, Code::Kind ic_kind,
+                              Code::Flags flags, bool leave_frame,
+                              Register receiver, Register name,
+                              Register scratch, Register extra, Register extra2,
+                              Register extra3) {
   Isolate* isolate = masm->isolate();
   Label miss;
 
@@ -105,15 +108,7 @@
   DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
 
   // Make sure that there are no register conflicts.
-  DCHECK(!scratch.is(receiver));
-  DCHECK(!scratch.is(name));
-  DCHECK(!extra.is(receiver));
-  DCHECK(!extra.is(name));
-  DCHECK(!extra.is(scratch));
-  DCHECK(!extra2.is(receiver));
-  DCHECK(!extra2.is(name));
-  DCHECK(!extra2.is(scratch));
-  DCHECK(!extra2.is(extra));
+  DCHECK(!AreAliased(receiver, name, scratch, extra, extra2, extra3));
 
   // Check register validity.
   DCHECK(!scratch.is(no_reg));
@@ -121,6 +116,17 @@
   DCHECK(!extra2.is(no_reg));
   DCHECK(!extra3.is(no_reg));
 
+#ifdef DEBUG
+  // If vector-based ics are in use, ensure that scratch, extra, extra2 and
+  // extra3 don't conflict with the vector and slot registers, which need
+  // to be preserved for a handler call or miss.
+  if (IC::ICUseVector(ic_kind)) {
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    DCHECK(!AreAliased(vector, slot, scratch, extra, extra2, extra3));
+  }
+#endif
+
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, extra2,
                       extra3);
@@ -140,8 +146,8 @@
   __ And(scratch, scratch, Operand(mask));
 
   // Probe the primary table.
-  ProbeTable(isolate, masm, flags, leave_frame, kPrimary, receiver, name,
-             scratch, extra, extra2, extra3);
+  ProbeTable(isolate, masm, ic_kind, flags, leave_frame, kPrimary, receiver,
+             name, scratch, extra, extra2, extra3);
 
   // Primary miss: Compute hash for secondary probe.
   __ srl(at, name, kCacheIndexShift);
@@ -151,8 +157,8 @@
   __ And(scratch, scratch, Operand(mask2));
 
   // Probe the secondary table.
-  ProbeTable(isolate, masm, flags, leave_frame, kSecondary, receiver, name,
-             scratch, extra, extra2, extra3);
+  ProbeTable(isolate, masm, ic_kind, flags, leave_frame, kSecondary, receiver,
+             name, scratch, extra, extra2, extra3);
 
   // Cache miss: Fall-through and let caller handle the miss by
   // entering the runtime system.
diff --git a/src/ic/mips64/handler-compiler-mips64.cc b/src/ic/mips64/handler-compiler-mips64.cc
index f44226f..d3b861b 100644
--- a/src/ic/mips64/handler-compiler-mips64.cc
+++ b/src/ic/mips64/handler-compiler-mips64.cc
@@ -92,6 +92,26 @@
 }
 
 
+void PropertyHandlerCompiler::PushVectorAndSlot(Register vector,
+                                                Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ Push(vector, slot);
+}
+
+
+void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ Pop(vector, slot);
+}
+
+
+void PropertyHandlerCompiler::DiscardVectorAndSlot() {
+  MacroAssembler* masm = this->masm();
+  // Remove vector and slot.
+  __ Daddu(sp, sp, Operand(2 * kPointerSize));
+}
+
+
 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
     MacroAssembler* masm, Label* miss_label, Register receiver,
     Handle<Name> name, Register scratch0, Register scratch1) {
@@ -138,25 +158,17 @@
 
 
 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
-    MacroAssembler* masm, int index, Register prototype, Label* miss) {
-  Isolate* isolate = masm->isolate();
-  // Get the global function with the given index.
-  Handle<JSFunction> function(
-      JSFunction::cast(isolate->native_context()->get(index)));
-
+    MacroAssembler* masm, int index, Register result, Label* miss) {
   // Check we're still in the same context.
-  Register scratch = prototype;
   const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
-  __ ld(scratch, MemOperand(cp, offset));
-  __ ld(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
-  __ ld(scratch, MemOperand(scratch, Context::SlotOffset(index)));
-  __ li(at, function);
-  __ Branch(miss, ne, at, Operand(scratch));
-
+  __ ld(result, MemOperand(cp, offset));
+  __ ld(result, FieldMemOperand(result, GlobalObject::kNativeContextOffset));
+  __ ld(result, MemOperand(result, Context::SlotOffset(index)));
   // Load its initial map. The global functions all have initial maps.
-  __ li(prototype, Handle<Map>(function->initial_map()));
+  __ ld(result,
+        FieldMemOperand(result, JSFunction::kPrototypeOrInitialMapOffset));
   // Load the prototype from the initial map.
-  __ ld(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
+  __ ld(result, FieldMemOperand(result, Map::kPrototypeOffset));
 }
 
 
@@ -321,186 +333,62 @@
 }
 
 
-// Generate StoreTransition code, value is passed in a0 register.
-// After executing generated code, the receiver_reg and name_reg
-// may be clobbered.
-void NamedStoreHandlerCompiler::GenerateStoreTransition(
-    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
-    Register storage_reg, Register value_reg, Register scratch1,
-    Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
-  // a0 : value.
-  Label exit;
-
-  int descriptor = transition->LastAdded();
-  DescriptorArray* descriptors = transition->instance_descriptors();
-  PropertyDetails details = descriptors->GetDetails(descriptor);
-  Representation representation = details.representation();
-  DCHECK(!representation.IsNone());
-
-  if (details.type() == CONSTANT) {
-    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
-    __ li(scratch1, constant);
-    __ Branch(miss_label, ne, value_reg, Operand(scratch1));
-  } else if (representation.IsSmi()) {
-    __ JumpIfNotSmi(value_reg, miss_label);
-  } else if (representation.IsHeapObject()) {
-    __ JumpIfSmi(value_reg, miss_label);
-    HeapType* field_type = descriptors->GetFieldType(descriptor);
-    HeapType::Iterator<Map> it = field_type->Classes();
-    Handle<Map> current;
-    if (!it.Done()) {
-      __ ld(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
-      Label do_store;
-      while (true) {
-        // Do the CompareMap() directly within the Branch() functions.
-        current = it.Current();
-        it.Advance();
-        if (it.Done()) {
-          __ Branch(miss_label, ne, scratch1, Operand(current));
-          break;
-        }
-        __ Branch(&do_store, eq, scratch1, Operand(current));
-      }
-      __ bind(&do_store);
-    }
-  } else if (representation.IsDouble()) {
-    Label do_store, heap_number;
-    __ LoadRoot(scratch3, Heap::kMutableHeapNumberMapRootIndex);
-    __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow,
-                          TAG_RESULT, MUTABLE);
-
-    __ JumpIfNotSmi(value_reg, &heap_number);
-    __ SmiUntag(scratch1, value_reg);
-    __ mtc1(scratch1, f6);
-    __ cvt_d_w(f4, f6);
-    __ jmp(&do_store);
-
-    __ bind(&heap_number);
-    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
-                DONT_DO_SMI_CHECK);
-    __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
-
-    __ bind(&do_store);
-    __ sdc1(f4, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
-  }
-
-  // Stub never generated for objects that require access checks.
-  DCHECK(!transition->is_access_check_needed());
-
-  // Perform map transition for the receiver if necessary.
-  if (details.type() == FIELD &&
-      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
-    // The properties must be extended before we can store the value.
-    // We jump to a runtime call that extends the properties array.
-    __ push(receiver_reg);
-    __ li(a2, Operand(transition));
-    __ Push(a2, a0);
-    __ TailCallExternalReference(
-        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                          isolate()),
-        3, 1);
-    return;
-  }
-
-  // Update the map of the object.
-  __ li(scratch1, Operand(transition));
-  __ sd(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
-
-  // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
-                      kRAHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
-                      OMIT_SMI_CHECK);
-
-  if (details.type() == CONSTANT) {
-    DCHECK(value_reg.is(a0));
-    __ Ret(USE_DELAY_SLOT);
-    __ mov(v0, a0);
-    return;
-  }
-
-  int index = transition->instance_descriptors()->GetFieldIndex(
-      transition->LastAdded());
-
-  // Adjust for the number of properties stored in the object. Even in the
-  // face of a transition we can use the old map here because the size of the
-  // object and the number of in-object properties is not going to change.
-  index -= transition->inobject_properties();
-
-  // TODO(verwaest): Share this code as a code stub.
-  SmiCheck smi_check =
-      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
-  if (index < 0) {
-    // Set the property straight into the object.
-    int offset = transition->instance_size() + (index * kPointerSize);
-    if (representation.IsDouble()) {
-      __ sd(storage_reg, FieldMemOperand(receiver_reg, offset));
-    } else {
-      __ sd(value_reg, FieldMemOperand(receiver_reg, offset));
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
-                          kRAHasNotBeenSaved, kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET, smi_check);
-    }
-  } else {
-    // Write to the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    // Get the properties array
-    __ ld(scratch1, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
-    if (representation.IsDouble()) {
-      __ sd(storage_reg, FieldMemOperand(scratch1, offset));
-    } else {
-      __ sd(value_reg, FieldMemOperand(scratch1, offset));
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
-                          kRAHasNotBeenSaved, kDontSaveFPRegs,
-                          EMIT_REMEMBERED_SET, smi_check);
-    }
-  }
-
-  // Return the value (register v0).
-  DCHECK(value_reg.is(a0));
-  __ bind(&exit);
-  __ Ret(USE_DELAY_SLOT);
-  __ mov(v0, a0);
+void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
+  __ li(this->name(), Operand(name));
 }
 
 
-void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
-                                                   Register value_reg,
-                                                   Label* miss_label) {
-  DCHECK(lookup->representation().IsHeapObject());
-  __ JumpIfSmi(value_reg, miss_label);
-  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
-  __ ld(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
-  Label do_store;
-  Handle<Map> current;
-  while (true) {
-    // Do the CompareMap() directly within the Branch() functions.
-    current = it.Current();
-    it.Advance();
-    if (it.Done()) {
-      __ Branch(miss_label, ne, scratch1(), Operand(current));
-      break;
-    }
-    __ Branch(&do_store, eq, scratch1(), Operand(current));
+void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition,
+                                                   Register scratch,
+                                                   Label* miss) {
+  Handle<WeakCell> cell = Map::WeakCellForMap(transition);
+  Register map_reg = StoreTransitionDescriptor::MapRegister();
+  DCHECK(!map_reg.is(scratch));
+  __ LoadWeakValue(map_reg, cell, miss);
+  if (transition->CanBeDeprecated()) {
+    __ ld(scratch, FieldMemOperand(map_reg, Map::kBitField3Offset));
+    __ And(at, scratch, Operand(Map::Deprecated::kMask));
+    __ Branch(miss, ne, at, Operand(zero_reg));
   }
-  __ bind(&do_store);
+}
 
-  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
-                      lookup->representation());
-  GenerateTailCall(masm(), stub.GetCode());
+
+void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg,
+                                                      int descriptor,
+                                                      Register value_reg,
+                                                      Register scratch,
+                                                      Label* miss_label) {
+  DCHECK(!map_reg.is(scratch));
+  DCHECK(!map_reg.is(value_reg));
+  DCHECK(!value_reg.is(scratch));
+  __ LoadInstanceDescriptors(map_reg, scratch);
+  __ ld(scratch,
+        FieldMemOperand(scratch, DescriptorArray::GetValueOffset(descriptor)));
+  __ Branch(miss_label, ne, value_reg, Operand(scratch));
+}
+
+
+void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
+                                                        Register value_reg,
+                                                        Label* miss_label) {
+  __ JumpIfSmi(value_reg, miss_label);
+  HeapType::Iterator<Map> it = field_type->Classes();
+  if (!it.Done()) {
+    __ ld(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
+    Label do_store;
+    Handle<Map> current;
+    while (true) {
+      // Do the CompareMap() directly within the Branch() functions.
+      current = it.Current();
+      it.Advance();
+      if (it.Done()) {
+        __ Branch(miss_label, ne, scratch1(), Operand(current));
+        break;
+      }
+      __ Branch(&do_store, eq, scratch1(), Operand(current));
+    }
+    __ bind(&do_store);
+  }
 }
 
 
@@ -555,18 +443,12 @@
       reg = holder_reg;  // From now on the object will be in holder_reg.
       __ ld(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
     } else {
-      // Two possible reasons for loading the prototype from the map:
-      // (1) Can't store references to new space in code.
-      // (2) Handler is shared for all receivers with the same prototype
-      //     map (but not necessarily the same prototype instance).
-      bool load_prototype_from_map =
-          heap()->InNewSpace(*prototype) || depth == 1;
       Register map_reg = scratch1;
+      __ ld(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
       if (depth != 1 || check == CHECK_ALL_MAPS) {
-        // CheckMap implicitly loads the map of |reg| into |map_reg|.
-        __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK);
-      } else {
-        __ ld(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
+        Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+        __ GetWeakValue(scratch2, cell);
+        __ Branch(miss, ne, scratch2, Operand(map_reg));
       }
 
       // Check access rights to the global object.  This has to happen after
@@ -584,11 +466,7 @@
 
       reg = holder_reg;  // From now on the object will be in holder_reg.
 
-      if (load_prototype_from_map) {
-        __ ld(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
-      } else {
-        __ li(reg, Operand(prototype));
-      }
+      __ ld(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
     }
 
     // Go to the next object in the prototype chain.
@@ -601,7 +479,10 @@
 
   if (depth != 0 || check == CHECK_ALL_MAPS) {
     // Check the holder map.
-    __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK);
+    __ ld(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
+    Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+    __ GetWeakValue(scratch2, cell);
+    __ Branch(miss, ne, scratch2, Operand(scratch1));
   }
 
   // Perform security check for access to the global object.
@@ -621,6 +502,10 @@
     Label success;
     __ Branch(&success);
     __ bind(miss);
+    if (IC::ICUseVector(kind())) {
+      DCHECK(kind() == Code::LOAD_IC);
+      PopVectorAndSlot();
+    }
     TailCallBuiltin(masm(), MissBuiltin(kind()));
     __ bind(&success);
   }
@@ -722,6 +607,7 @@
     } else {
       __ Push(holder_reg, this->name());
     }
+    InterceptorVectorSlotPush(holder_reg);
     // Invoke an interceptor.  Note: map checks from receiver to
     // interceptor's holder has been compiled before (see a caller
     // of this method).
@@ -738,6 +624,7 @@
     __ Ret();
 
     __ bind(&interceptor_failed);
+    InterceptorVectorSlotPop(holder_reg);
     if (must_preserve_receiver_reg) {
       __ Pop(receiver(), holder_reg, this->name());
     } else {
@@ -767,7 +654,7 @@
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     Handle<JSObject> object, Handle<Name> name,
     Handle<ExecutableAccessorInfo> callback) {
-  Register holder_reg = Frontend(receiver(), name);
+  Register holder_reg = Frontend(name);
 
   __ Push(receiver(), holder_reg);  // Receiver.
   __ li(at, Operand(callback));     // Callback info.
@@ -807,12 +694,16 @@
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
   Label miss;
+  if (IC::ICUseVector(kind())) {
+    PushVectorAndSlot();
+  }
 
   FrontendHeader(receiver(), name, &miss);
 
   // Get the value from the cell.
   Register result = StoreDescriptor::ValueRegister();
-  __ li(result, Operand(cell));
+  Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell);
+  __ LoadWeakValue(result, weak_cell, &miss);
   __ ld(result, FieldMemOperand(result, Cell::kValueOffset));
 
   // Check for deleted property if property can actually be deleted.
@@ -823,6 +714,9 @@
 
   Counters* counters = isolate()->counters();
   __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3);
+  if (IC::ICUseVector(kind())) {
+    DiscardVectorAndSlot();
+  }
   __ Ret(USE_DELAY_SLOT);
   __ mov(v0, result);
 
diff --git a/src/ic/mips64/ic-compiler-mips64.cc b/src/ic/mips64/ic-compiler-mips64.cc
index 796ed87..7ed4492 100644
--- a/src/ic/mips64/ic-compiler-mips64.cc
+++ b/src/ic/mips64/ic-compiler-mips64.cc
@@ -24,9 +24,12 @@
 
   if (check == PROPERTY &&
       (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
-    // In case we are compiling an IC for dictionary loads and stores, just
+    // In case we are compiling an IC for dictionary loads or stores, just
     // check whether the name is unique.
     if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
+      // Keyed loads with dictionaries shouldn't be here, they go generic.
+      // The DCHECK is to protect assumptions when --vector-ics is on.
+      DCHECK(kind() != Code::KEYED_LOAD_IC);
       Register tmp = scratch1();
       __ JumpIfSmi(this->name(), &miss);
       __ ld(tmp, FieldMemOperand(this->name(), HeapObject::kMapOffset));
@@ -57,7 +60,9 @@
       number_of_handled_maps++;
       // Check map and tail call if there's a match.
       // Separate compare from branch, to provide path for above JumpIfSmi().
-      __ Dsubu(match, map_reg, Operand(map));
+      Handle<WeakCell> cell = Map::WeakCellForMap(map);
+      __ GetWeakValue(match, cell);
+      __ Dsubu(match, match, Operand(map_reg));
       if (type->Is(HeapType::Number())) {
         DCHECK(!number_case.is_unused());
         __ bind(&number_case);
@@ -85,15 +90,20 @@
   __ JumpIfSmi(receiver(), &miss);
 
   int receiver_count = receiver_maps->length();
-  __ ld(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  Register map_reg = scratch1();
+  Register match = scratch2();
+  __ ld(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
   for (int i = 0; i < receiver_count; ++i) {
+    Handle<WeakCell> cell = Map::WeakCellForMap(receiver_maps->at(i));
+    __ GetWeakValue(match, cell);
     if (transitioned_maps->at(i).is_null()) {
-      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, scratch1(),
-              Operand(receiver_maps->at(i)));
+      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq, match,
+              Operand(map_reg));
     } else {
       Label next_map;
-      __ Branch(&next_map, ne, scratch1(), Operand(receiver_maps->at(i)));
-      __ li(transition_map(), Operand(transitioned_maps->at(i)));
+      __ Branch(&next_map, ne, match, Operand(map_reg));
+      Handle<WeakCell> cell = Map::WeakCellForMap(transitioned_maps->at(i));
+      __ LoadWeakValue(transition_map(), cell, &miss);
       __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
       __ bind(&next_map);
     }
diff --git a/src/ic/mips64/ic-mips64.cc b/src/ic/mips64/ic-mips64.cc
index a5d9fe7..7ac191c 100644
--- a/src/ic/mips64/ic-mips64.cc
+++ b/src/ic/mips64/ic-mips64.cc
@@ -270,18 +270,35 @@
 static const Register LoadIC_TempRegister() { return a3; }
 
 
+static void LoadIC_PushArgs(MacroAssembler* masm) {
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register name = LoadDescriptor::NameRegister();
+  if (FLAG_vector_ics) {
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+
+    __ Push(receiver, name, slot, vector);
+  } else {
+    __ Push(receiver, name);
+  }
+}
+
+
 void LoadIC::GenerateMiss(MacroAssembler* masm) {
   // The return address is on the stack.
   Isolate* isolate = masm->isolate();
 
-  __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, a4);
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(a4, a5, VectorLoadICDescriptor::SlotRegister(),
+                     VectorLoadICDescriptor::VectorRegister()));
+  __ IncrementCounter(isolate->counters()->load_miss(), 1, a4, a5);
 
-  __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
-  __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
+  LoadIC_PushArgs(masm);
 
   // Perform tail call to the entry.
   ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
@@ -410,15 +427,19 @@
   // The return address is in ra.
   Isolate* isolate = masm->isolate();
 
-  __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a3, a4);
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(a4, a5, VectorLoadICDescriptor::SlotRegister(),
+                     VectorLoadICDescriptor::VectorRegister()));
+  __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, a4, a5);
 
-  __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
+  LoadIC_PushArgs(masm);
 
   // Perform tail call to the entry.
   ExternalReference ref =
       ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
 
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
@@ -599,33 +620,7 @@
 }
 
 
-void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
-  // Return address is in ra.
-  Label miss;
-
-  Register receiver = LoadDescriptor::ReceiverRegister();
-  Register index = LoadDescriptor::NameRegister();
-  Register scratch = a3;
-  Register result = v0;
-  DCHECK(!scratch.is(receiver) && !scratch.is(index));
-
-  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
-                                          &miss,  // When not a string.
-                                          &miss,  // When not a number.
-                                          &miss,  // When index out of range.
-                                          STRING_INDEX_IS_ARRAY_INDEX);
-  char_at_generator.GenerateFast(masm);
-  __ Ret();
-
-  StubRuntimeCallHelper call_helper;
-  char_at_generator.GenerateSlow(masm, call_helper);
-
-  __ bind(&miss);
-  GenerateMiss(masm);
-}
-
-
-static void KeyedStoreGenerateGenericHelper(
+static void KeyedStoreGenerateMegamorphicHelper(
     MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
     KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
     Register value, Register key, Register receiver, Register receiver_map,
@@ -775,8 +770,8 @@
 }
 
 
-void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
-                                   StrictMode strict_mode) {
+void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
+                                       StrictMode strict_mode) {
   // ---------- S t a t e --------------
   //  -- a0     : value
   //  -- a1     : key
@@ -785,7 +780,7 @@
   // -----------------------------------
   Label slow, fast_object, fast_object_grow;
   Label fast_double, fast_double_grow;
-  Label array, extra, check_if_double_array;
+  Label array, extra, check_if_double_array, maybe_name_key, miss;
 
   // Register usage.
   Register value = StoreDescriptor::ValueRegister();
@@ -798,7 +793,7 @@
   // a4 and a5 are used as general scratch registers.
 
   // Check that the key is a smi.
-  __ JumpIfNotSmi(key, &slow);
+  __ JumpIfNotSmi(key, &maybe_name_key);
   // Check that the object isn't a smi.
   __ JumpIfSmi(receiver, &slow);
   // Get the map of the object.
@@ -828,6 +823,18 @@
   // a1: key.
   // a2: receiver.
   PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
+  // Never returns to here.
+
+  __ bind(&maybe_name_key);
+  __ ld(a4, FieldMemOperand(key, HeapObject::kMapOffset));
+  __ lb(a4, FieldMemOperand(a4, Map::kInstanceTypeOffset));
+  __ JumpIfNotUniqueNameInstanceType(a4, &slow);
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::STORE_IC));
+  masm->isolate()->stub_cache()->GenerateProbe(
+      masm, Code::STORE_IC, flags, false, receiver, key, a3, a4, a5, a6);
+  // Cache miss.
+  __ Branch(&miss);
 
   // Extra capacity case: Check if there is extra capacity to
   // perform the store and update the length. Used for adding one
@@ -860,13 +867,16 @@
   __ ld(a4, FieldMemOperand(receiver, JSArray::kLengthOffset));
   __ Branch(&extra, hs, key, Operand(a4));
 
-  KeyedStoreGenerateGenericHelper(
+  KeyedStoreGenerateMegamorphicHelper(
       masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength,
       value, key, receiver, receiver_map, elements_map, elements);
-  KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
-                                  &slow, kDontCheckMap, kIncrementLength, value,
-                                  key, receiver, receiver_map, elements_map,
-                                  elements);
+  KeyedStoreGenerateMegamorphicHelper(masm, &fast_object_grow,
+                                      &fast_double_grow, &slow, kDontCheckMap,
+                                      kIncrementLength, value, key, receiver,
+                                      receiver_map, elements_map, elements);
+
+  __ bind(&miss);
+  GenerateMiss(masm);
 }
 
 
@@ -891,8 +901,8 @@
   // Get the receiver from the stack and probe the stub cache.
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::STORE_IC));
-  masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver,
-                                               name, a3, a4, a5, a6);
+  masm->isolate()->stub_cache()->GenerateProbe(
+      masm, Code::STORE_IC, flags, false, receiver, name, a3, a4, a5, a6);
 
   // Cache miss: Jump to runtime.
   GenerateMiss(masm);
diff --git a/src/ic/mips64/stub-cache-mips64.cc b/src/ic/mips64/stub-cache-mips64.cc
index 272e5be..04883d7 100644
--- a/src/ic/mips64/stub-cache-mips64.cc
+++ b/src/ic/mips64/stub-cache-mips64.cc
@@ -7,7 +7,9 @@
 #if V8_TARGET_ARCH_MIPS64
 
 #include "src/codegen.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
+#include "src/interface-descriptors.h"
 
 namespace v8 {
 namespace internal {
@@ -16,7 +18,7 @@
 
 
 static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
-                       Code::Flags flags, bool leave_frame,
+                       Code::Kind ic_kind, Code::Flags flags, bool leave_frame,
                        StubCache::Table table, Register receiver, Register name,
                        // Number of the cache entry, not scaled.
                        Register offset, Register scratch, Register scratch2,
@@ -90,10 +92,11 @@
 }
 
 
-void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags,
-                              bool leave_frame, Register receiver,
-                              Register name, Register scratch, Register extra,
-                              Register extra2, Register extra3) {
+void StubCache::GenerateProbe(MacroAssembler* masm, Code::Kind ic_kind,
+                              Code::Flags flags, bool leave_frame,
+                              Register receiver, Register name,
+                              Register scratch, Register extra, Register extra2,
+                              Register extra3) {
   Isolate* isolate = masm->isolate();
   Label miss;
 
@@ -106,15 +109,7 @@
   DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
 
   // Make sure that there are no register conflicts.
-  DCHECK(!scratch.is(receiver));
-  DCHECK(!scratch.is(name));
-  DCHECK(!extra.is(receiver));
-  DCHECK(!extra.is(name));
-  DCHECK(!extra.is(scratch));
-  DCHECK(!extra2.is(receiver));
-  DCHECK(!extra2.is(name));
-  DCHECK(!extra2.is(scratch));
-  DCHECK(!extra2.is(extra));
+  DCHECK(!AreAliased(receiver, name, scratch, extra, extra2, extra3));
 
   // Check register validity.
   DCHECK(!scratch.is(no_reg));
@@ -122,6 +117,17 @@
   DCHECK(!extra2.is(no_reg));
   DCHECK(!extra3.is(no_reg));
 
+#ifdef DEBUG
+  // If vector-based ics are in use, ensure that scratch, extra, extra2 and
+  // extra3 don't conflict with the vector and slot registers, which need
+  // to be preserved for a handler call or miss.
+  if (IC::ICUseVector(ic_kind)) {
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    DCHECK(!AreAliased(vector, slot, scratch, extra, extra2, extra3));
+  }
+#endif
+
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, extra2,
                       extra3);
@@ -141,8 +147,8 @@
   __ And(scratch, scratch, Operand(mask));
 
   // Probe the primary table.
-  ProbeTable(isolate, masm, flags, leave_frame, kPrimary, receiver, name,
-             scratch, extra, extra2, extra3);
+  ProbeTable(isolate, masm, ic_kind, flags, leave_frame, kPrimary, receiver,
+             name, scratch, extra, extra2, extra3);
 
   // Primary miss: Compute hash for secondary probe.
   __ dsrl(at, name, kCacheIndexShift);
@@ -152,8 +158,8 @@
   __ And(scratch, scratch, Operand(mask2));
 
   // Probe the secondary table.
-  ProbeTable(isolate, masm, flags, leave_frame, kSecondary, receiver, name,
-             scratch, extra, extra2, extra3);
+  ProbeTable(isolate, masm, ic_kind, flags, leave_frame, kSecondary, receiver,
+             name, scratch, extra, extra2, extra3);
 
   // Cache miss: Fall-through and let caller handle the miss by
   // entering the runtime system.
diff --git a/src/ic/ppc/access-compiler-ppc.cc b/src/ic/ppc/access-compiler-ppc.cc
new file mode 100644
index 0000000..e98f517
--- /dev/null
+++ b/src/ic/ppc/access-compiler-ppc.cc
@@ -0,0 +1,46 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/ic/access-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void PropertyAccessCompiler::GenerateTailCall(MacroAssembler* masm,
+                                              Handle<Code> code) {
+  __ Jump(code, RelocInfo::CODE_TARGET);
+}
+
+
+Register* PropertyAccessCompiler::load_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3, scratch4.
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register name = LoadDescriptor::NameRegister();
+  static Register registers[] = {receiver, name, r6, r3, r7, r8};
+  return registers;
+}
+
+
+Register* PropertyAccessCompiler::store_calling_convention() {
+  // receiver, name, scratch1, scratch2, scratch3.
+  Register receiver = StoreDescriptor::ReceiverRegister();
+  Register name = StoreDescriptor::NameRegister();
+  DCHECK(r6.is(ElementTransitionAndStoreDescriptor::MapRegister()));
+  static Register registers[] = {receiver, name, r6, r7, r8};
+  return registers;
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ic/ppc/handler-compiler-ppc.cc b/src/ic/ppc/handler-compiler-ppc.cc
new file mode 100644
index 0000000..2f29c83
--- /dev/null
+++ b/src/ic/ppc/handler-compiler-ppc.cc
@@ -0,0 +1,698 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/ic/call-optimization.h"
+#include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void NamedLoadHandlerCompiler::GenerateLoadViaGetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> getter) {
+  // ----------- S t a t e -------------
+  //  -- r3    : receiver
+  //  -- r5    : name
+  //  -- lr    : return address
+  // -----------------------------------
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+
+    if (!getter.is_null()) {
+      // Call the JavaScript getter with the receiver on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ LoadP(receiver,
+                 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ push(receiver);
+      ParameterCount actual(0);
+      ParameterCount expected(getter);
+      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
+    }
+
+    // Restore context register.
+    __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ Ret();
+}
+
+
+void NamedStoreHandlerCompiler::GenerateStoreViaSetter(
+    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
+    Handle<JSFunction> setter) {
+  // ----------- S t a t e -------------
+  //  -- lr    : return address
+  // -----------------------------------
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+
+    // Save value register, so we can restore it later.
+    __ push(value());
+
+    if (!setter.is_null()) {
+      // Call the JavaScript setter with receiver and value on the stack.
+      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
+        // Swap in the global receiver.
+        __ LoadP(receiver,
+                 FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
+      }
+      __ Push(receiver, value());
+      ParameterCount actual(1);
+      ParameterCount expected(setter);
+      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
+                        NullCallWrapper());
+    } else {
+      // If we generate a global code snippet for deoptimization only, remember
+      // the place to continue after deoptimization.
+      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
+    }
+
+    // We have to return the passed value, not the return value of the setter.
+    __ pop(r3);
+
+    // Restore context register.
+    __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ Ret();
+}
+
+
+void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
+    MacroAssembler* masm, Label* miss_label, Register receiver,
+    Handle<Name> name, Register scratch0, Register scratch1) {
+  DCHECK(name->IsUniqueName());
+  DCHECK(!receiver.is(scratch0));
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
+  __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
+
+  Label done;
+
+  const int kInterceptorOrAccessCheckNeededMask =
+      (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
+
+  // Bail out if the receiver has a named interceptor or requires access checks.
+  Register map = scratch1;
+  __ LoadP(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  __ lbz(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
+  __ andi(r0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask));
+  __ bne(miss_label, cr0);
+
+  // Check that receiver is a JSObject.
+  __ lbz(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  __ cmpi(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
+  __ blt(miss_label);
+
+  // Load properties array.
+  Register properties = scratch0;
+  __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+  // Check that the properties array is a dictionary.
+  __ LoadP(map, FieldMemOperand(properties, HeapObject::kMapOffset));
+  Register tmp = properties;
+  __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
+  __ cmp(map, tmp);
+  __ bne(miss_label);
+
+  // Restore the temporarily used register.
+  __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+
+
+  NameDictionaryLookupStub::GenerateNegativeLookup(
+      masm, miss_label, &done, receiver, properties, name, scratch1);
+  __ bind(&done);
+  __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
+    MacroAssembler* masm, int index, Register prototype, Label* miss) {
+  Isolate* isolate = masm->isolate();
+  // Get the global function with the given index.
+  Handle<JSFunction> function(
+      JSFunction::cast(isolate->native_context()->get(index)));
+
+  // Check we're still in the same context.
+  Register scratch = prototype;
+  const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
+  __ LoadP(scratch, MemOperand(cp, offset));
+  __ LoadP(scratch,
+           FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
+  __ LoadP(scratch, MemOperand(scratch, Context::SlotOffset(index)));
+  __ Move(ip, function);
+  __ cmp(ip, scratch);
+  __ bne(miss);
+
+  // Load its initial map. The global functions all have initial maps.
+  __ Move(prototype, Handle<Map>(function->initial_map()));
+  // Load the prototype from the initial map.
+  __ LoadP(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
+    MacroAssembler* masm, Register receiver, Register scratch1,
+    Register scratch2, Label* miss_label) {
+  __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
+  __ mr(r3, scratch1);
+  __ Ret();
+}
+
+
+// Generate code to check that a global property cell is empty. Create
+// the property cell at compilation time if no cell exists for the
+// property.
+void PropertyHandlerCompiler::GenerateCheckPropertyCell(
+    MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
+    Register scratch, Label* miss) {
+  Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
+  DCHECK(cell->value()->IsTheHole());
+  __ mov(scratch, Operand(cell));
+  __ LoadP(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
+  __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+  __ cmp(scratch, ip);
+  __ bne(miss);
+}
+
+
+static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
+                                     Register holder, Register name,
+                                     Handle<JSObject> holder_obj) {
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
+  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
+  __ push(name);
+  Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
+  DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
+  Register scratch = name;
+  __ mov(scratch, Operand(interceptor));
+  __ push(scratch);
+  __ push(receiver);
+  __ push(holder);
+}
+
+
+static void CompileCallLoadPropertyWithInterceptor(
+    MacroAssembler* masm, Register receiver, Register holder, Register name,
+    Handle<JSObject> holder_obj, IC::UtilityId id) {
+  PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
+  __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
+                           NamedLoadHandlerCompiler::kInterceptorArgsLength);
+}
+
+
+// Generate call to api function.
+void PropertyHandlerCompiler::GenerateFastApiCall(
+    MacroAssembler* masm, const CallOptimization& optimization,
+    Handle<Map> receiver_map, Register receiver, Register scratch_in,
+    bool is_store, int argc, Register* values) {
+  DCHECK(!receiver.is(scratch_in));
+  __ push(receiver);
+  // Write the arguments to stack frame.
+  for (int i = 0; i < argc; i++) {
+    Register arg = values[argc - 1 - i];
+    DCHECK(!receiver.is(arg));
+    DCHECK(!scratch_in.is(arg));
+    __ push(arg);
+  }
+  DCHECK(optimization.is_simple_api_call());
+
+  // Abi for CallApiFunctionStub.
+  Register callee = r3;
+  Register call_data = r7;
+  Register holder = r5;
+  Register api_function_address = r4;
+
+  // Put holder in place.
+  CallOptimization::HolderLookup holder_lookup;
+  Handle<JSObject> api_holder =
+      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
+  switch (holder_lookup) {
+    case CallOptimization::kHolderIsReceiver:
+      __ Move(holder, receiver);
+      break;
+    case CallOptimization::kHolderFound:
+      __ Move(holder, api_holder);
+      break;
+    case CallOptimization::kHolderNotFound:
+      UNREACHABLE();
+      break;
+  }
+
+  Isolate* isolate = masm->isolate();
+  Handle<JSFunction> function = optimization.constant_function();
+  Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
+  Handle<Object> call_data_obj(api_call_info->data(), isolate);
+
+  // Put callee in place.
+  __ Move(callee, function);
+
+  bool call_data_undefined = false;
+  // Put call_data in place.
+  if (isolate->heap()->InNewSpace(*call_data_obj)) {
+    __ Move(call_data, api_call_info);
+    __ LoadP(call_data,
+             FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
+  } else if (call_data_obj->IsUndefined()) {
+    call_data_undefined = true;
+    __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
+  } else {
+    __ Move(call_data, call_data_obj);
+  }
+
+  // Put api_function_address in place.
+  Address function_address = v8::ToCData<Address>(api_call_info->callback());
+  ApiFunction fun(function_address);
+  ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
+  ExternalReference ref = ExternalReference(&fun, type, masm->isolate());
+  __ mov(api_function_address, Operand(ref));
+
+  // Jump to stub.
+  CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
+  __ TailCallStub(&stub);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
+  // Push receiver, key and value for runtime call.
+  __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
+          StoreDescriptor::ValueRegister());
+
+  // The slow case calls into the runtime to complete the store without causing
+  // an IC miss that would otherwise cause a transition to the generic stub.
+  ExternalReference ref =
+      ExternalReference(IC_Utility(IC::kStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+void ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) {
+  // Push receiver, key and value for runtime call.
+  __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
+          StoreDescriptor::ValueRegister());
+
+  // The slow case calls into the runtime to complete the store without causing
+  // an IC miss that would otherwise cause a transition to the generic stub.
+  ExternalReference ref =
+      ExternalReference(IC_Utility(IC::kKeyedStoreIC_Slow), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
+void NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
+                                                    Handle<Name> name) {
+  if (!label->is_unused()) {
+    __ bind(label);
+    __ mov(this->name(), Operand(name));
+  }
+}
+
+
+void NamedStoreHandlerCompiler::GenerateRestoreNameAndMap(
+    Handle<Name> name, Handle<Map> transition) {
+  __ mov(this->name(), Operand(name));
+  __ mov(StoreTransitionDescriptor::MapRegister(), Operand(transition));
+}
+
+
+void NamedStoreHandlerCompiler::GenerateConstantCheck(Object* constant,
+                                                      Register value_reg,
+                                                      Label* miss_label) {
+  __ Move(scratch1(), handle(constant, isolate()));
+  __ cmp(value_reg, scratch1());
+  __ bne(miss_label);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
+                                                        Register value_reg,
+                                                        Label* miss_label) {
+  __ JumpIfSmi(value_reg, miss_label);
+  HeapType::Iterator<Map> it = field_type->Classes();
+  if (!it.Done()) {
+    __ LoadP(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
+    Label do_store;
+    while (true) {
+      __ CompareMap(scratch1(), it.Current(), &do_store);
+      it.Advance();
+      if (it.Done()) {
+        __ bne(miss_label);
+        break;
+      }
+      __ beq(&do_store);
+    }
+    __ bind(&do_store);
+  }
+}
+
+
+Register PropertyHandlerCompiler::CheckPrototypes(
+    Register object_reg, Register holder_reg, Register scratch1,
+    Register scratch2, Handle<Name> name, Label* miss,
+    PrototypeCheckType check) {
+  Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
+
+  // Make sure there's no overlap between holder and object registers.
+  DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
+  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
+         !scratch2.is(scratch1));
+
+  // Keep track of the current object in register reg.
+  Register reg = object_reg;
+  int depth = 0;
+
+  Handle<JSObject> current = Handle<JSObject>::null();
+  if (type()->IsConstant()) {
+    current = Handle<JSObject>::cast(type()->AsConstant()->Value());
+  }
+  Handle<JSObject> prototype = Handle<JSObject>::null();
+  Handle<Map> current_map = receiver_map;
+  Handle<Map> holder_map(holder()->map());
+  // Traverse the prototype chain and check the maps in the prototype chain for
+  // fast and global objects or do negative lookup for normal objects.
+  while (!current_map.is_identical_to(holder_map)) {
+    ++depth;
+
+    // Only global objects and objects that do not require access
+    // checks are allowed in stubs.
+    DCHECK(current_map->IsJSGlobalProxyMap() ||
+           !current_map->is_access_check_needed());
+
+    prototype = handle(JSObject::cast(current_map->prototype()));
+    if (current_map->is_dictionary_map() &&
+        !current_map->IsJSGlobalObjectMap()) {
+      DCHECK(!current_map->IsJSGlobalProxyMap());  // Proxy maps are fast.
+      if (!name->IsUniqueName()) {
+        DCHECK(name->IsString());
+        name = factory()->InternalizeString(Handle<String>::cast(name));
+      }
+      DCHECK(current.is_null() ||
+             current->property_dictionary()->FindEntry(name) ==
+                 NameDictionary::kNotFound);
+
+      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
+                                       scratch2);
+
+      __ LoadP(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
+      reg = holder_reg;  // From now on the object will be in holder_reg.
+      __ LoadP(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
+    } else {
+      Register map_reg = scratch1;
+      if (depth != 1 || check == CHECK_ALL_MAPS) {
+        // CheckMap implicitly loads the map of |reg| into |map_reg|.
+        __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK);
+      } else {
+        __ LoadP(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
+      }
+
+      // Check access rights to the global object.  This has to happen after
+      // the map check so that we know that the object is actually a global
+      // object.
+      // This allows us to install generated handlers for accesses to the
+      // global proxy (as opposed to using slow ICs). See corresponding code
+      // in LookupForRead().
+      if (current_map->IsJSGlobalProxyMap()) {
+        __ CheckAccessGlobalProxy(reg, scratch2, miss);
+      } else if (current_map->IsJSGlobalObjectMap()) {
+        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
+                                  name, scratch2, miss);
+      }
+
+      reg = holder_reg;  // From now on the object will be in holder_reg.
+
+      // Two possible reasons for loading the prototype from the map:
+      // (1) Can't store references to new space in code.
+      // (2) Handler is shared for all receivers with the same prototype
+      //     map (but not necessarily the same prototype instance).
+      bool load_prototype_from_map =
+          heap()->InNewSpace(*prototype) || depth == 1;
+      if (load_prototype_from_map) {
+        __ LoadP(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
+      } else {
+        __ mov(reg, Operand(prototype));
+      }
+    }
+
+    // Go to the next object in the prototype chain.
+    current = prototype;
+    current_map = handle(current->map());
+  }
+
+  // Log the check depth.
+  LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
+
+  if (depth != 0 || check == CHECK_ALL_MAPS) {
+    // Check the holder map.
+    __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK);
+  }
+
+  // Perform security check for access to the global object.
+  DCHECK(current_map->IsJSGlobalProxyMap() ||
+         !current_map->is_access_check_needed());
+  if (current_map->IsJSGlobalProxyMap()) {
+    __ CheckAccessGlobalProxy(reg, scratch1, miss);
+  }
+
+  // Return the register containing the holder.
+  return reg;
+}
+
+
+void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
+  if (!miss->is_unused()) {
+    Label success;
+    __ b(&success);
+    __ bind(miss);
+    TailCallBuiltin(masm(), MissBuiltin(kind()));
+    __ bind(&success);
+  }
+}
+
+
+void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
+  if (!miss->is_unused()) {
+    Label success;
+    __ b(&success);
+    GenerateRestoreName(miss, name);
+    TailCallBuiltin(masm(), MissBuiltin(kind()));
+    __ bind(&success);
+  }
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
+  // Return the constant value.
+  __ Move(r3, value);
+  __ Ret();
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadCallback(
+    Register reg, Handle<ExecutableAccessorInfo> callback) {
+  // Build AccessorInfo::args_ list on the stack and push property name below
+  // the exit frame to make GC aware of them and store pointers to them.
+  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
+  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
+  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
+  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
+  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
+  STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
+  DCHECK(!scratch2().is(reg));
+  DCHECK(!scratch3().is(reg));
+  DCHECK(!scratch4().is(reg));
+  __ push(receiver());
+  if (heap()->InNewSpace(callback->data())) {
+    __ Move(scratch3(), callback);
+    __ LoadP(scratch3(),
+             FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset));
+  } else {
+    __ Move(scratch3(), Handle<Object>(callback->data(), isolate()));
+  }
+  __ push(scratch3());
+  __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
+  __ mr(scratch4(), scratch3());
+  __ Push(scratch3(), scratch4());
+  __ mov(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
+  __ Push(scratch4(), reg);
+  __ push(name());
+
+  // Abi for CallApiGetter
+  Register getter_address_reg = ApiGetterDescriptor::function_address();
+
+  Address getter_address = v8::ToCData<Address>(callback->getter());
+  ApiFunction fun(getter_address);
+  ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
+  ExternalReference ref = ExternalReference(&fun, type, isolate());
+  __ mov(getter_address_reg, Operand(ref));
+
+  CallApiGetterStub stub(isolate());
+  __ TailCallStub(&stub);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
+    LookupIterator* it, Register holder_reg) {
+  DCHECK(holder()->HasNamedInterceptor());
+  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
+
+  // Compile the interceptor call, followed by inline code to load the
+  // property from further up the prototype chain if the call fails.
+  // Check that the maps haven't changed.
+  DCHECK(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 ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
+  // case might cause a miss during the prototype check.
+  bool must_perform_prototype_check =
+      !holder().is_identical_to(it->GetHolder<JSObject>());
+  bool must_preserve_receiver_reg =
+      !receiver().is(holder_reg) &&
+      (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check);
+
+  // Save necessary data before invoking an interceptor.
+  // Requires a frame to make GC aware of pushed pointers.
+  {
+    FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL);
+    if (must_preserve_receiver_reg) {
+      __ Push(receiver(), holder_reg, this->name());
+    } else {
+      __ Push(holder_reg, this->name());
+    }
+    // Invoke an interceptor.  Note: map checks from receiver to
+    // interceptor's holder has been compiled before (see a caller
+    // of this method.)
+    CompileCallLoadPropertyWithInterceptor(
+        masm(), receiver(), holder_reg, this->name(), holder(),
+        IC::kLoadPropertyWithInterceptorOnly);
+
+    // Check if interceptor provided a value for property.  If it's
+    // the case, return immediately.
+    Label interceptor_failed;
+    __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
+    __ cmp(r3, scratch1());
+    __ beq(&interceptor_failed);
+    frame_scope.GenerateLeaveFrame();
+    __ Ret();
+
+    __ bind(&interceptor_failed);
+    __ pop(this->name());
+    __ pop(holder_reg);
+    if (must_preserve_receiver_reg) {
+      __ pop(receiver());
+    }
+    // Leave the internal frame.
+  }
+
+  GenerateLoadPostInterceptor(it, holder_reg);
+}
+
+
+void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
+  // Call the runtime system to load the interceptor.
+  DCHECK(holder()->HasNamedInterceptor());
+  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
+  PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
+                           holder());
+
+  ExternalReference ref = ExternalReference(
+      IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
+  __ TailCallExternalReference(
+      ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
+}
+
+
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
+    Handle<JSObject> object, Handle<Name> name,
+    Handle<ExecutableAccessorInfo> callback) {
+  Register holder_reg = Frontend(receiver(), name);
+
+  __ Push(receiver(), holder_reg);  // receiver
+  __ mov(ip, Operand(callback));    // callback info
+  __ push(ip);
+  __ mov(ip, Operand(name));
+  __ Push(ip, value());
+
+  // Do tail-call to the runtime system.
+  ExternalReference store_callback_property =
+      ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
+  __ TailCallExternalReference(store_callback_property, 5, 1);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Handle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
+    Handle<Name> name) {
+  __ Push(receiver(), this->name(), value());
+
+  // Do tail-call to the runtime system.
+  ExternalReference store_ic_property = ExternalReference(
+      IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
+  __ TailCallExternalReference(store_ic_property, 3, 1);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::FAST, name);
+}
+
+
+Register NamedStoreHandlerCompiler::value() {
+  return StoreDescriptor::ValueRegister();
+}
+
+
+Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
+    Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
+  Label miss;
+  FrontendHeader(receiver(), name, &miss);
+
+  // Get the value from the cell.
+  Register result = StoreDescriptor::ValueRegister();
+  __ mov(result, Operand(cell));
+  __ LoadP(result, FieldMemOperand(result, Cell::kValueOffset));
+
+  // Check for deleted property if property can actually be deleted.
+  if (is_configurable) {
+    __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+    __ cmp(result, ip);
+    __ beq(&miss);
+  }
+
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->named_load_global_stub(), 1, r4, r6);
+  __ Ret();
+
+  FrontendFooter(name, &miss);
+
+  // Return the generated code.
+  return GetCode(kind(), Code::NORMAL, name);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_ARM
diff --git a/src/ic/ppc/ic-compiler-ppc.cc b/src/ic/ppc/ic-compiler-ppc.cc
new file mode 100644
index 0000000..c868456
--- /dev/null
+++ b/src/ic/ppc/ic-compiler-ppc.cc
@@ -0,0 +1,130 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/ic/ic.h"
+#include "src/ic/ic-compiler.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+void PropertyICCompiler::GenerateRuntimeSetProperty(MacroAssembler* masm,
+                                                    StrictMode strict_mode) {
+  __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
+          StoreDescriptor::ValueRegister());
+
+  __ mov(r0, Operand(Smi::FromInt(strict_mode)));
+  __ Push(r0);
+
+  // Do tail-call to runtime routine.
+  __ TailCallRuntime(Runtime::kSetProperty, 4, 1);
+}
+
+
+#undef __
+#define __ ACCESS_MASM(masm())
+
+
+Handle<Code> PropertyICCompiler::CompilePolymorphic(TypeHandleList* types,
+                                                    CodeHandleList* handlers,
+                                                    Handle<Name> name,
+                                                    Code::StubType type,
+                                                    IcCheckType check) {
+  Label miss;
+
+  if (check == PROPERTY &&
+      (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
+    // In case we are compiling an IC for dictionary loads and stores, just
+    // check whether the name is unique.
+    if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
+      Register tmp = scratch1();
+      __ JumpIfSmi(this->name(), &miss);
+      __ LoadP(tmp, FieldMemOperand(this->name(), HeapObject::kMapOffset));
+      __ lbz(tmp, FieldMemOperand(tmp, Map::kInstanceTypeOffset));
+      __ JumpIfNotUniqueNameInstanceType(tmp, &miss);
+    } else {
+      __ Cmpi(this->name(), Operand(name), r0);
+      __ bne(&miss);
+    }
+  }
+
+  Label number_case;
+  Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
+  __ JumpIfSmi(receiver(), smi_target);
+
+  // Polymorphic keyed stores may use the map register
+  Register map_reg = scratch1();
+  DCHECK(kind() != Code::KEYED_STORE_IC ||
+         map_reg.is(ElementTransitionAndStoreDescriptor::MapRegister()));
+
+  int receiver_count = types->length();
+  int number_of_handled_maps = 0;
+  __ LoadP(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  for (int current = 0; current < receiver_count; ++current) {
+    Handle<HeapType> type = types->at(current);
+    Handle<Map> map = IC::TypeToMap(*type, isolate());
+    if (!map->is_deprecated()) {
+      number_of_handled_maps++;
+      __ mov(ip, Operand(map));
+      __ cmp(map_reg, ip);
+      if (type->Is(HeapType::Number())) {
+        DCHECK(!number_case.is_unused());
+        __ bind(&number_case);
+      }
+      __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq);
+    }
+  }
+  DCHECK(number_of_handled_maps != 0);
+
+  __ bind(&miss);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
+
+  // Return the generated code.
+  InlineCacheState state =
+      number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
+  return GetCode(kind(), type, name, state);
+}
+
+
+Handle<Code> PropertyICCompiler::CompileKeyedStorePolymorphic(
+    MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
+    MapHandleList* transitioned_maps) {
+  Label miss;
+  __ JumpIfSmi(receiver(), &miss);
+
+  int receiver_count = receiver_maps->length();
+  __ LoadP(scratch1(), FieldMemOperand(receiver(), HeapObject::kMapOffset));
+  for (int i = 0; i < receiver_count; ++i) {
+    __ mov(ip, Operand(receiver_maps->at(i)));
+    __ cmp(scratch1(), ip);
+    if (transitioned_maps->at(i).is_null()) {
+      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, eq);
+    } else {
+      Label next_map;
+      __ bne(&next_map);
+      __ mov(transition_map(), Operand(transitioned_maps->at(i)));
+      __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al);
+      __ bind(&next_map);
+    }
+  }
+
+  __ bind(&miss);
+  TailCallBuiltin(masm(), MissBuiltin(kind()));
+
+  // Return the generated code.
+  return GetCode(kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ic/ppc/ic-ppc.cc b/src/ic/ppc/ic-ppc.cc
new file mode 100644
index 0000000..97c3e2f
--- /dev/null
+++ b/src/ic/ppc/ic-ppc.cc
@@ -0,0 +1,1047 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/codegen.h"
+#include "src/ic/ic.h"
+#include "src/ic/ic-compiler.h"
+#include "src/ic/stub-cache.h"
+
+namespace v8 {
+namespace internal {
+
+
+// ----------------------------------------------------------------------------
+// Static IC stub generators.
+//
+
+#define __ ACCESS_MASM(masm)
+
+
+static void GenerateGlobalInstanceTypeCheck(MacroAssembler* masm, Register type,
+                                            Label* global_object) {
+  // Register usage:
+  //   type: holds the receiver instance type on entry.
+  __ cmpi(type, Operand(JS_GLOBAL_OBJECT_TYPE));
+  __ beq(global_object);
+  __ cmpi(type, Operand(JS_BUILTINS_OBJECT_TYPE));
+  __ beq(global_object);
+  __ cmpi(type, Operand(JS_GLOBAL_PROXY_TYPE));
+  __ beq(global_object);
+}
+
+
+// Helper function used from LoadIC GenerateNormal.
+//
+// elements: Property dictionary. It is not clobbered if a jump to the miss
+//           label is done.
+// name:     Property name. It is not clobbered if a jump to the miss label is
+//           done
+// result:   Register for the result. It is only updated if a jump to the miss
+//           label is not done. Can be the same as elements or name clobbering
+//           one of these in the case of not jumping to the miss label.
+// The two scratch registers need to be different from elements, name and
+// result.
+// The generated code assumes that the receiver has slow properties,
+// is not a global object and does not have interceptors.
+static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss,
+                                   Register elements, Register name,
+                                   Register result, Register scratch1,
+                                   Register scratch2) {
+  // Main use of the scratch registers.
+  // scratch1: Used as temporary and to hold the capacity of the property
+  //           dictionary.
+  // scratch2: Used as temporary.
+  Label done;
+
+  // Probe the dictionary.
+  NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements,
+                                                   name, scratch1, scratch2);
+
+  // If probing finds an entry check that the value is a normal
+  // property.
+  __ bind(&done);  // scratch2 == elements + 4 * index
+  const int kElementsStartOffset =
+      NameDictionary::kHeaderSize +
+      NameDictionary::kElementsStartIndex * kPointerSize;
+  const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
+  __ LoadP(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
+  __ mr(r0, scratch2);
+  __ LoadSmiLiteral(scratch2, Smi::FromInt(PropertyDetails::TypeField::kMask));
+  __ and_(scratch2, scratch1, scratch2, SetRC);
+  __ bne(miss, cr0);
+  __ mr(scratch2, r0);
+
+  // Get the value at the masked, scaled index and return.
+  __ LoadP(result,
+           FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize));
+}
+
+
+// Helper function used from StoreIC::GenerateNormal.
+//
+// elements: Property dictionary. It is not clobbered if a jump to the miss
+//           label is done.
+// name:     Property name. It is not clobbered if a jump to the miss label is
+//           done
+// value:    The value to store.
+// The two scratch registers need to be different from elements, name and
+// result.
+// The generated code assumes that the receiver has slow properties,
+// is not a global object and does not have interceptors.
+static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss,
+                                    Register elements, Register name,
+                                    Register value, Register scratch1,
+                                    Register scratch2) {
+  // Main use of the scratch registers.
+  // scratch1: Used as temporary and to hold the capacity of the property
+  //           dictionary.
+  // scratch2: Used as temporary.
+  Label done;
+
+  // Probe the dictionary.
+  NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements,
+                                                   name, scratch1, scratch2);
+
+  // If probing finds an entry in the dictionary check that the value
+  // is a normal property that is not read only.
+  __ bind(&done);  // scratch2 == elements + 4 * index
+  const int kElementsStartOffset =
+      NameDictionary::kHeaderSize +
+      NameDictionary::kElementsStartIndex * kPointerSize;
+  const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
+  int kTypeAndReadOnlyMask =
+      PropertyDetails::TypeField::kMask |
+      PropertyDetails::AttributesField::encode(READ_ONLY);
+  __ LoadP(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
+  __ mr(r0, scratch2);
+  __ LoadSmiLiteral(scratch2, Smi::FromInt(kTypeAndReadOnlyMask));
+  __ and_(scratch2, scratch1, scratch2, SetRC);
+  __ bne(miss, cr0);
+  __ mr(scratch2, r0);
+
+  // Store the value at the masked, scaled index and return.
+  const int kValueOffset = kElementsStartOffset + kPointerSize;
+  __ addi(scratch2, scratch2, Operand(kValueOffset - kHeapObjectTag));
+  __ StoreP(value, MemOperand(scratch2));
+
+  // Update the write barrier. Make sure not to clobber the value.
+  __ mr(scratch1, value);
+  __ RecordWrite(elements, scratch2, scratch1, kLRHasNotBeenSaved,
+                 kDontSaveFPRegs);
+}
+
+
+// Checks the receiver for special cases (value type, slow case bits).
+// Falls through for regular JS object.
+static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm,
+                                           Register receiver, Register map,
+                                           Register scratch,
+                                           int interceptor_bit, Label* slow) {
+  // Check that the object isn't a smi.
+  __ JumpIfSmi(receiver, slow);
+  // Get the map of the receiver.
+  __ LoadP(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  // Check bit field.
+  __ lbz(scratch, FieldMemOperand(map, Map::kBitFieldOffset));
+  DCHECK(((1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)) < 0x8000);
+  __ andi(r0, scratch,
+          Operand((1 << Map::kIsAccessCheckNeeded) | (1 << interceptor_bit)));
+  __ bne(slow, cr0);
+  // Check that the object is some kind of JS object EXCEPT JS Value type.
+  // In the case that the object is a value-wrapper object,
+  // we enter the runtime system to make sure that indexing into string
+  // objects work as intended.
+  DCHECK(JS_OBJECT_TYPE > JS_VALUE_TYPE);
+  __ lbz(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  __ cmpi(scratch, Operand(JS_OBJECT_TYPE));
+  __ blt(slow);
+}
+
+
+// Loads an indexed element from a fast case array.
+// If not_fast_array is NULL, doesn't perform the elements map check.
+static void GenerateFastArrayLoad(MacroAssembler* masm, Register receiver,
+                                  Register key, Register elements,
+                                  Register scratch1, Register scratch2,
+                                  Register result, Label* not_fast_array,
+                                  Label* out_of_range) {
+  // Register use:
+  //
+  // receiver - holds the receiver on entry.
+  //            Unchanged unless 'result' is the same register.
+  //
+  // key      - holds the smi key on entry.
+  //            Unchanged unless 'result' is the same register.
+  //
+  // elements - holds the elements of the receiver on exit.
+  //
+  // result   - holds the result on exit if the load succeeded.
+  //            Allowed to be the the same as 'receiver' or 'key'.
+  //            Unchanged on bailout so 'receiver' and 'key' can be safely
+  //            used by further computation.
+  //
+  // Scratch registers:
+  //
+  // scratch1 - used to hold elements map and elements length.
+  //            Holds the elements map if not_fast_array branch is taken.
+  //
+  // scratch2 - used to hold the loaded value.
+
+  __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  if (not_fast_array != NULL) {
+    // Check that the object is in fast mode and writable.
+    __ LoadP(scratch1, FieldMemOperand(elements, HeapObject::kMapOffset));
+    __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
+    __ cmp(scratch1, ip);
+    __ bne(not_fast_array);
+  } else {
+    __ AssertFastElements(elements);
+  }
+  // Check that the key (index) is within bounds.
+  __ LoadP(scratch1, FieldMemOperand(elements, FixedArray::kLengthOffset));
+  __ cmpl(key, scratch1);
+  __ bge(out_of_range);
+  // Fast case: Do the load.
+  __ addi(scratch1, elements,
+          Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  // The key is a smi.
+  __ SmiToPtrArrayOffset(scratch2, key);
+  __ LoadPX(scratch2, MemOperand(scratch2, scratch1));
+  __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+  __ cmp(scratch2, ip);
+  // In case the loaded value is the_hole we have to consult GetProperty
+  // to ensure the prototype chain is searched.
+  __ beq(out_of_range);
+  __ mr(result, scratch2);
+}
+
+
+// Checks whether a key is an array index string or a unique name.
+// Falls through if a key is a unique name.
+static void GenerateKeyNameCheck(MacroAssembler* masm, Register key,
+                                 Register map, Register hash,
+                                 Label* index_string, Label* not_unique) {
+  // The key is not a smi.
+  Label unique;
+  // Is it a name?
+  __ CompareObjectType(key, map, hash, LAST_UNIQUE_NAME_TYPE);
+  __ bgt(not_unique);
+  STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE);
+  __ beq(&unique);
+
+  // Is the string an array index, with cached numeric value?
+  __ lwz(hash, FieldMemOperand(key, Name::kHashFieldOffset));
+  __ mov(r8, Operand(Name::kContainsCachedArrayIndexMask));
+  __ and_(r0, hash, r8, SetRC);
+  __ beq(index_string, cr0);
+
+  // Is the string internalized? We know it's a string, so a single
+  // bit test is enough.
+  // map: key map
+  __ lbz(hash, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  STATIC_ASSERT(kInternalizedTag == 0);
+  __ andi(r0, hash, Operand(kIsNotInternalizedMask));
+  __ bne(not_unique, cr0);
+
+  __ bind(&unique);
+}
+
+
+void LoadIC::GenerateNormal(MacroAssembler* masm) {
+  Register dictionary = r3;
+  DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister()));
+  DCHECK(!dictionary.is(LoadDescriptor::NameRegister()));
+
+  Label slow;
+
+  __ LoadP(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(),
+                                       JSObject::kPropertiesOffset));
+  GenerateDictionaryLoad(masm, &slow, dictionary,
+                         LoadDescriptor::NameRegister(), r3, r6, r7);
+  __ Ret();
+
+  // Dictionary load failed, go slow (but don't miss).
+  __ bind(&slow);
+  GenerateRuntimeGetProperty(masm);
+}
+
+
+// A register that isn't one of the parameters to the load ic.
+static const Register LoadIC_TempRegister() { return r6; }
+
+
+void LoadIC::GenerateMiss(MacroAssembler* masm) {
+  // The return address is in lr.
+  Isolate* isolate = masm->isolate();
+
+  __ IncrementCounter(isolate->counters()->load_miss(), 1, r6, r7);
+
+  __ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
+  __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
+
+  // Perform tail call to the entry.
+  ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
+  __ TailCallExternalReference(ref, 2, 1);
+}
+
+
+void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
+  // The return address is in lr.
+
+  __ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister());
+  __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister());
+
+  __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
+}
+
+
+static MemOperand GenerateMappedArgumentsLookup(
+    MacroAssembler* masm, Register object, Register key, Register scratch1,
+    Register scratch2, Register scratch3, Label* unmapped_case,
+    Label* slow_case) {
+  Heap* heap = masm->isolate()->heap();
+
+  // Check that the receiver is a JSObject. Because of the map check
+  // later, we do not need to check for interceptors or whether it
+  // requires access checks.
+  __ JumpIfSmi(object, slow_case);
+  // Check that the object is some kind of JSObject.
+  __ CompareObjectType(object, scratch1, scratch2, FIRST_JS_RECEIVER_TYPE);
+  __ blt(slow_case);
+
+  // Check that the key is a positive smi.
+  __ mov(scratch1, Operand(0x80000001));
+  __ and_(r0, key, scratch1, SetRC);
+  __ bne(slow_case, cr0);
+
+  // Load the elements into scratch1 and check its map.
+  Handle<Map> arguments_map(heap->sloppy_arguments_elements_map());
+  __ LoadP(scratch1, FieldMemOperand(object, JSObject::kElementsOffset));
+  __ CheckMap(scratch1, scratch2, arguments_map, slow_case, DONT_DO_SMI_CHECK);
+
+  // Check if element is in the range of mapped arguments. If not, jump
+  // to the unmapped lookup with the parameter map in scratch1.
+  __ LoadP(scratch2, FieldMemOperand(scratch1, FixedArray::kLengthOffset));
+  __ SubSmiLiteral(scratch2, scratch2, Smi::FromInt(2), r0);
+  __ cmpl(key, scratch2);
+  __ bge(unmapped_case);
+
+  // Load element index and check whether it is the hole.
+  const int kOffset =
+      FixedArray::kHeaderSize + 2 * kPointerSize - kHeapObjectTag;
+
+  __ SmiToPtrArrayOffset(scratch3, key);
+  __ addi(scratch3, scratch3, Operand(kOffset));
+
+  __ LoadPX(scratch2, MemOperand(scratch1, scratch3));
+  __ LoadRoot(scratch3, Heap::kTheHoleValueRootIndex);
+  __ cmp(scratch2, scratch3);
+  __ beq(unmapped_case);
+
+  // Load value from context and return it. We can reuse scratch1 because
+  // we do not jump to the unmapped lookup (which requires the parameter
+  // map in scratch1).
+  __ LoadP(scratch1, FieldMemOperand(scratch1, FixedArray::kHeaderSize));
+  __ SmiToPtrArrayOffset(scratch3, scratch2);
+  __ addi(scratch3, scratch3, Operand(Context::kHeaderSize - kHeapObjectTag));
+  return MemOperand(scratch1, scratch3);
+}
+
+
+static MemOperand GenerateUnmappedArgumentsLookup(MacroAssembler* masm,
+                                                  Register key,
+                                                  Register parameter_map,
+                                                  Register scratch,
+                                                  Label* slow_case) {
+  // Element is in arguments backing store, which is referenced by the
+  // second element of the parameter_map. The parameter_map register
+  // must be loaded with the parameter map of the arguments object and is
+  // overwritten.
+  const int kBackingStoreOffset = FixedArray::kHeaderSize + kPointerSize;
+  Register backing_store = parameter_map;
+  __ LoadP(backing_store, FieldMemOperand(parameter_map, kBackingStoreOffset));
+  Handle<Map> fixed_array_map(masm->isolate()->heap()->fixed_array_map());
+  __ CheckMap(backing_store, scratch, fixed_array_map, slow_case,
+              DONT_DO_SMI_CHECK);
+  __ LoadP(scratch, FieldMemOperand(backing_store, FixedArray::kLengthOffset));
+  __ cmpl(key, scratch);
+  __ bge(slow_case);
+  __ SmiToPtrArrayOffset(scratch, key);
+  __ addi(scratch, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  return MemOperand(backing_store, scratch);
+}
+
+
+void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
+  Register receiver = StoreDescriptor::ReceiverRegister();
+  Register key = StoreDescriptor::NameRegister();
+  Register value = StoreDescriptor::ValueRegister();
+  DCHECK(receiver.is(r4));
+  DCHECK(key.is(r5));
+  DCHECK(value.is(r3));
+
+  Label slow, notin;
+  MemOperand mapped_location = GenerateMappedArgumentsLookup(
+      masm, receiver, key, r6, r7, r8, &notin, &slow);
+  Register mapped_base = mapped_location.ra();
+  Register mapped_offset = mapped_location.rb();
+  __ StorePX(value, mapped_location);
+  __ add(r9, mapped_base, mapped_offset);
+  __ mr(r11, value);
+  __ RecordWrite(mapped_base, r9, r11, kLRHasNotBeenSaved, kDontSaveFPRegs);
+  __ Ret();
+  __ bind(&notin);
+  // The unmapped lookup expects that the parameter map is in r6.
+  MemOperand unmapped_location =
+      GenerateUnmappedArgumentsLookup(masm, key, r6, r7, &slow);
+  Register unmapped_base = unmapped_location.ra();
+  Register unmapped_offset = unmapped_location.rb();
+  __ StorePX(value, unmapped_location);
+  __ add(r9, unmapped_base, unmapped_offset);
+  __ mr(r11, value);
+  __ RecordWrite(unmapped_base, r9, r11, kLRHasNotBeenSaved, kDontSaveFPRegs);
+  __ Ret();
+  __ bind(&slow);
+  GenerateMiss(masm);
+}
+
+
+void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
+  // The return address is in lr.
+  Isolate* isolate = masm->isolate();
+
+  __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r6, r7);
+
+  __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
+
+  // Perform tail call to the entry.
+  ExternalReference ref =
+      ExternalReference(IC_Utility(kKeyedLoadIC_Miss), isolate);
+
+  __ TailCallExternalReference(ref, 2, 1);
+}
+
+
+void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
+  // The return address is in lr.
+
+  __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister());
+
+  __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
+}
+
+
+void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
+  // The return address is in lr.
+  Label slow, check_name, index_smi, index_name, property_array_property;
+  Label probe_dictionary, check_number_dictionary;
+
+  Register key = LoadDescriptor::NameRegister();
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  DCHECK(key.is(r5));
+  DCHECK(receiver.is(r4));
+
+  Isolate* isolate = masm->isolate();
+
+  // Check that the key is a smi.
+  __ JumpIfNotSmi(key, &check_name);
+  __ bind(&index_smi);
+  // Now the key is known to be a smi. This place is also jumped to from below
+  // where a numeric string is converted to a smi.
+
+  GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6,
+                                 Map::kHasIndexedInterceptor, &slow);
+
+  // Check the receiver's map to see if it has fast elements.
+  __ CheckFastElements(r3, r6, &check_number_dictionary);
+
+  GenerateFastArrayLoad(masm, receiver, key, r3, r6, r7, r3, NULL, &slow);
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_smi(), 1, r7, r6);
+  __ Ret();
+
+  __ bind(&check_number_dictionary);
+  __ LoadP(r7, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  __ LoadP(r6, FieldMemOperand(r7, JSObject::kMapOffset));
+
+  // Check whether the elements is a number dictionary.
+  // r6: elements map
+  // r7: elements
+  __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
+  __ cmp(r6, ip);
+  __ bne(&slow);
+  __ SmiUntag(r3, key);
+  __ LoadFromNumberDictionary(&slow, r7, key, r3, r3, r6, r8);
+  __ Ret();
+
+  // Slow case, key and receiver still in r3 and r4.
+  __ bind(&slow);
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_slow(), 1, r7,
+                      r6);
+  GenerateRuntimeGetProperty(masm);
+
+  __ bind(&check_name);
+  GenerateKeyNameCheck(masm, key, r3, r6, &index_name, &slow);
+
+  GenerateKeyedLoadReceiverCheck(masm, receiver, r3, r6,
+                                 Map::kHasNamedInterceptor, &slow);
+
+  // If the receiver is a fast-case object, check the keyed lookup
+  // cache. Otherwise probe the dictionary.
+  __ LoadP(r6, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+  __ LoadP(r7, FieldMemOperand(r6, HeapObject::kMapOffset));
+  __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
+  __ cmp(r7, ip);
+  __ beq(&probe_dictionary);
+
+  // Load the map of the receiver, compute the keyed lookup cache hash
+  // based on 32 bits of the map pointer and the name hash.
+  __ LoadP(r3, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  __ srawi(r6, r3, KeyedLookupCache::kMapHashShift);
+  __ lwz(r7, FieldMemOperand(key, Name::kHashFieldOffset));
+  __ srawi(r7, r7, Name::kHashShift);
+  __ xor_(r6, r6, r7);
+  int mask = KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask;
+  __ mov(r7, Operand(mask));
+  __ and_(r6, r6, r7, LeaveRC);
+
+  // Load the key (consisting of map and unique name) from the cache and
+  // check for match.
+  Label load_in_object_property;
+  static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket;
+  Label hit_on_nth_entry[kEntriesPerBucket];
+  ExternalReference cache_keys =
+      ExternalReference::keyed_lookup_cache_keys(isolate);
+
+  __ mov(r7, Operand(cache_keys));
+  __ mr(r0, r5);
+  __ ShiftLeftImm(r5, r6, Operand(kPointerSizeLog2 + 1));
+  __ add(r7, r7, r5);
+  __ mr(r5, r0);
+
+  for (int i = 0; i < kEntriesPerBucket - 1; i++) {
+    Label try_next_entry;
+    // Load map and move r7 to next entry.
+    __ LoadP(r8, MemOperand(r7));
+    __ addi(r7, r7, Operand(kPointerSize * 2));
+    __ cmp(r3, r8);
+    __ bne(&try_next_entry);
+    __ LoadP(r8, MemOperand(r7, -kPointerSize));  // Load name
+    __ cmp(key, r8);
+    __ beq(&hit_on_nth_entry[i]);
+    __ bind(&try_next_entry);
+  }
+
+  // Last entry: Load map and move r7 to name.
+  __ LoadP(r8, MemOperand(r7));
+  __ addi(r7, r7, Operand(kPointerSize));
+  __ cmp(r3, r8);
+  __ bne(&slow);
+  __ LoadP(r8, MemOperand(r7));
+  __ cmp(key, r8);
+  __ bne(&slow);
+
+  // Get field offset.
+  // r3     : receiver's map
+  // r6     : lookup cache index
+  ExternalReference cache_field_offsets =
+      ExternalReference::keyed_lookup_cache_field_offsets(isolate);
+
+  // Hit on nth entry.
+  for (int i = kEntriesPerBucket - 1; i >= 0; i--) {
+    __ bind(&hit_on_nth_entry[i]);
+    __ mov(r7, Operand(cache_field_offsets));
+    if (i != 0) {
+      __ addi(r6, r6, Operand(i));
+    }
+    __ ShiftLeftImm(r8, r6, Operand(2));
+    __ lwzx(r8, MemOperand(r8, r7));
+    __ lbz(r9, FieldMemOperand(r3, Map::kInObjectPropertiesOffset));
+    __ sub(r8, r8, r9);
+    __ cmpi(r8, Operand::Zero());
+    __ bge(&property_array_property);
+    if (i != 0) {
+      __ b(&load_in_object_property);
+    }
+  }
+
+  // Load in-object property.
+  __ bind(&load_in_object_property);
+  __ lbz(r9, FieldMemOperand(r3, Map::kInstanceSizeOffset));
+  __ add(r9, r9, r8);  // Index from start of object.
+  __ subi(receiver, receiver, Operand(kHeapObjectTag));  // Remove the heap tag.
+  __ ShiftLeftImm(r3, r9, Operand(kPointerSizeLog2));
+  __ LoadPX(r3, MemOperand(r3, receiver));
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 1,
+                      r7, r6);
+  __ Ret();
+
+  // Load property array property.
+  __ bind(&property_array_property);
+  __ LoadP(receiver, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+  __ addi(receiver, receiver,
+          Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ ShiftLeftImm(r3, r8, Operand(kPointerSizeLog2));
+  __ LoadPX(r3, MemOperand(r3, receiver));
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_lookup_cache(), 1,
+                      r7, r6);
+  __ Ret();
+
+  // Do a quick inline probe of the receiver's dictionary, if it
+  // exists.
+  __ bind(&probe_dictionary);
+  // r6: elements
+  __ LoadP(r3, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  __ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
+  GenerateGlobalInstanceTypeCheck(masm, r3, &slow);
+  // Load the property to r3.
+  GenerateDictionaryLoad(masm, &slow, r6, key, r3, r8, r7);
+  __ IncrementCounter(isolate->counters()->keyed_load_generic_symbol(), 1, r7,
+                      r6);
+  __ Ret();
+
+  __ bind(&index_name);
+  __ IndexFromHash(r6, key);
+  // Now jump to the place where smi keys are handled.
+  __ b(&index_smi);
+}
+
+
+void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) {
+  // Push receiver, key and value for runtime call.
+  __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
+          StoreDescriptor::ValueRegister());
+
+  ExternalReference ref =
+      ExternalReference(IC_Utility(kKeyedStoreIC_Miss), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+static void KeyedStoreGenerateMegamorphicHelper(
+    MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
+    KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length,
+    Register value, Register key, Register receiver, Register receiver_map,
+    Register elements_map, Register elements) {
+  Label transition_smi_elements;
+  Label finish_object_store, non_double_value, transition_double_elements;
+  Label fast_double_without_map_check;
+
+  // Fast case: Do the store, could be either Object or double.
+  __ bind(fast_object);
+  Register scratch_value = r7;
+  Register address = r8;
+  if (check_map == kCheckMap) {
+    __ LoadP(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
+    __ mov(scratch_value,
+           Operand(masm->isolate()->factory()->fixed_array_map()));
+    __ cmp(elements_map, scratch_value);
+    __ bne(fast_double);
+  }
+
+  // HOLECHECK: guards "A[i] = V"
+  // We have to go to the runtime if the current value is the hole because
+  // there may be a callback on the element
+  Label holecheck_passed1;
+  __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ SmiToPtrArrayOffset(scratch_value, key);
+  __ LoadPX(scratch_value, MemOperand(address, scratch_value));
+  __ Cmpi(scratch_value, Operand(masm->isolate()->factory()->the_hole_value()),
+          r0);
+  __ bne(&holecheck_passed1);
+  __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value,
+                                      slow);
+
+  __ bind(&holecheck_passed1);
+
+  // Smi stores don't require further checks.
+  Label non_smi_value;
+  __ JumpIfNotSmi(value, &non_smi_value);
+
+  if (increment_length == kIncrementLength) {
+    // Add 1 to receiver->length.
+    __ AddSmiLiteral(scratch_value, key, Smi::FromInt(1), r0);
+    __ StoreP(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset),
+              r0);
+  }
+  // It's irrelevant whether array is smi-only or not when writing a smi.
+  __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ SmiToPtrArrayOffset(scratch_value, key);
+  __ StorePX(value, MemOperand(address, scratch_value));
+  __ Ret();
+
+  __ bind(&non_smi_value);
+  // Escape to elements kind transition case.
+  __ CheckFastObjectElements(receiver_map, scratch_value,
+                             &transition_smi_elements);
+
+  // Fast elements array, store the value to the elements backing store.
+  __ bind(&finish_object_store);
+  if (increment_length == kIncrementLength) {
+    // Add 1 to receiver->length.
+    __ AddSmiLiteral(scratch_value, key, Smi::FromInt(1), r0);
+    __ StoreP(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset),
+              r0);
+  }
+  __ addi(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ SmiToPtrArrayOffset(scratch_value, key);
+  __ StorePUX(value, MemOperand(address, scratch_value));
+  // Update write barrier for the elements array address.
+  __ mr(scratch_value, value);  // Preserve the value which is returned.
+  __ RecordWrite(elements, address, scratch_value, kLRHasNotBeenSaved,
+                 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+  __ Ret();
+
+  __ bind(fast_double);
+  if (check_map == kCheckMap) {
+    // Check for fast double array case. If this fails, call through to the
+    // runtime.
+    __ CompareRoot(elements_map, Heap::kFixedDoubleArrayMapRootIndex);
+    __ bne(slow);
+  }
+
+  // HOLECHECK: guards "A[i] double hole?"
+  // We have to see if the double version of the hole is present. If so
+  // go to the runtime.
+  __ addi(address, elements,
+          Operand((FixedDoubleArray::kHeaderSize + Register::kExponentOffset -
+                   kHeapObjectTag)));
+  __ SmiToDoubleArrayOffset(scratch_value, key);
+  __ lwzx(scratch_value, MemOperand(address, scratch_value));
+  __ Cmpi(scratch_value, Operand(kHoleNanUpper32), r0);
+  __ bne(&fast_double_without_map_check);
+  __ JumpIfDictionaryInPrototypeChain(receiver, elements_map, scratch_value,
+                                      slow);
+
+  __ bind(&fast_double_without_map_check);
+  __ StoreNumberToDoubleElements(value, key, elements, r6, d0,
+                                 &transition_double_elements);
+  if (increment_length == kIncrementLength) {
+    // Add 1 to receiver->length.
+    __ AddSmiLiteral(scratch_value, key, Smi::FromInt(1), r0);
+    __ StoreP(scratch_value, FieldMemOperand(receiver, JSArray::kLengthOffset),
+              r0);
+  }
+  __ Ret();
+
+  __ bind(&transition_smi_elements);
+  // Transition the array appropriately depending on the value type.
+  __ LoadP(r7, FieldMemOperand(value, HeapObject::kMapOffset));
+  __ CompareRoot(r7, Heap::kHeapNumberMapRootIndex);
+  __ bne(&non_double_value);
+
+  // Value is a double. Transition FAST_SMI_ELEMENTS ->
+  // FAST_DOUBLE_ELEMENTS and complete the store.
+  __ LoadTransitionedArrayMapConditional(
+      FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS, receiver_map, r7, slow);
+  AllocationSiteMode mode =
+      AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_DOUBLE_ELEMENTS);
+  ElementsTransitionGenerator::GenerateSmiToDouble(masm, receiver, key, value,
+                                                   receiver_map, mode, slow);
+  __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  __ b(&fast_double_without_map_check);
+
+  __ bind(&non_double_value);
+  // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS
+  __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, FAST_ELEMENTS,
+                                         receiver_map, r7, slow);
+  mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS);
+  ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
+      masm, receiver, key, value, receiver_map, mode, slow);
+  __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  __ b(&finish_object_store);
+
+  __ bind(&transition_double_elements);
+  // Elements are FAST_DOUBLE_ELEMENTS, but value is an Object that's not a
+  // HeapNumber. Make sure that the receiver is a Array with FAST_ELEMENTS and
+  // transition array from FAST_DOUBLE_ELEMENTS to FAST_ELEMENTS
+  __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS,
+                                         receiver_map, r7, slow);
+  mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS);
+  ElementsTransitionGenerator::GenerateDoubleToObject(
+      masm, receiver, key, value, receiver_map, mode, slow);
+  __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  __ b(&finish_object_store);
+}
+
+
+void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
+                                       StrictMode strict_mode) {
+  // ---------- S t a t e --------------
+  //  -- r3     : value
+  //  -- r4     : key
+  //  -- r5     : receiver
+  //  -- lr     : return address
+  // -----------------------------------
+  Label slow, fast_object, fast_object_grow;
+  Label fast_double, fast_double_grow;
+  Label array, extra, check_if_double_array, maybe_name_key, miss;
+
+  // Register usage.
+  Register value = StoreDescriptor::ValueRegister();
+  Register key = StoreDescriptor::NameRegister();
+  Register receiver = StoreDescriptor::ReceiverRegister();
+  DCHECK(receiver.is(r4));
+  DCHECK(key.is(r5));
+  DCHECK(value.is(r3));
+  Register receiver_map = r6;
+  Register elements_map = r9;
+  Register elements = r10;  // Elements array of the receiver.
+  // r7 and r8 are used as general scratch registers.
+
+  // Check that the key is a smi.
+  __ JumpIfNotSmi(key, &maybe_name_key);
+  // Check that the object isn't a smi.
+  __ JumpIfSmi(receiver, &slow);
+  // Get the map of the object.
+  __ LoadP(receiver_map, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  // Check that the receiver does not require access checks and is not observed.
+  // The generic stub does not perform map checks or handle observed objects.
+  __ lbz(ip, FieldMemOperand(receiver_map, Map::kBitFieldOffset));
+  __ andi(r0, ip,
+          Operand(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved));
+  __ bne(&slow, cr0);
+  // Check if the object is a JS array or not.
+  __ lbz(r7, FieldMemOperand(receiver_map, Map::kInstanceTypeOffset));
+  __ cmpi(r7, Operand(JS_ARRAY_TYPE));
+  __ beq(&array);
+  // Check that the object is some kind of JSObject.
+  __ cmpi(r7, Operand(FIRST_JS_OBJECT_TYPE));
+  __ blt(&slow);
+
+  // Object case: Check key against length in the elements array.
+  __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  // Check array bounds. Both the key and the length of FixedArray are smis.
+  __ LoadP(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
+  __ cmpl(key, ip);
+  __ blt(&fast_object);
+
+  // Slow case, handle jump to runtime.
+  __ bind(&slow);
+  // Entry registers are intact.
+  // r3: value.
+  // r4: key.
+  // r5: receiver.
+  PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
+  // Never returns to here.
+
+  __ bind(&maybe_name_key);
+  __ LoadP(r7, FieldMemOperand(key, HeapObject::kMapOffset));
+  __ lbz(r7, FieldMemOperand(r7, Map::kInstanceTypeOffset));
+  __ JumpIfNotUniqueNameInstanceType(r7, &slow);
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::STORE_IC));
+  masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver,
+                                               key, r6, r7, r8, r9);
+  // Cache miss.
+  __ b(&miss);
+
+  // Extra capacity case: Check if there is extra capacity to
+  // perform the store and update the length. Used for adding one
+  // element to the array by writing to array[array.length].
+  __ bind(&extra);
+  // Condition code from comparing key and array length is still available.
+  __ bne(&slow);  // Only support writing to writing to array[array.length].
+  // Check for room in the elements backing store.
+  // Both the key and the length of FixedArray are smis.
+  __ LoadP(ip, FieldMemOperand(elements, FixedArray::kLengthOffset));
+  __ cmpl(key, ip);
+  __ bge(&slow);
+  __ LoadP(elements_map, FieldMemOperand(elements, HeapObject::kMapOffset));
+  __ mov(ip, Operand(masm->isolate()->factory()->fixed_array_map()));
+  __ cmp(elements_map, ip);  // PPC - I think I can re-use ip here
+  __ bne(&check_if_double_array);
+  __ b(&fast_object_grow);
+
+  __ bind(&check_if_double_array);
+  __ mov(ip, Operand(masm->isolate()->factory()->fixed_double_array_map()));
+  __ cmp(elements_map, ip);  // PPC - another ip re-use
+  __ bne(&slow);
+  __ b(&fast_double_grow);
+
+  // Array case: Get the length and the elements array from the JS
+  // array. Check that the array is in fast mode (and writable); if it
+  // is the length is always a smi.
+  __ bind(&array);
+  __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+
+  // Check the key against the length in the array.
+  __ LoadP(ip, FieldMemOperand(receiver, JSArray::kLengthOffset));
+  __ cmpl(key, ip);
+  __ bge(&extra);
+
+  KeyedStoreGenerateMegamorphicHelper(
+      masm, &fast_object, &fast_double, &slow, kCheckMap, kDontIncrementLength,
+      value, key, receiver, receiver_map, elements_map, elements);
+  KeyedStoreGenerateMegamorphicHelper(masm, &fast_object_grow,
+                                      &fast_double_grow, &slow, kDontCheckMap,
+                                      kIncrementLength, value, key, receiver,
+                                      receiver_map, elements_map, elements);
+  __ bind(&miss);
+  GenerateMiss(masm);
+}
+
+
+void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
+  Register receiver = StoreDescriptor::ReceiverRegister();
+  Register name = StoreDescriptor::NameRegister();
+  DCHECK(receiver.is(r4));
+  DCHECK(name.is(r5));
+  DCHECK(StoreDescriptor::ValueRegister().is(r3));
+
+  // Get the receiver from the stack and probe the stub cache.
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::STORE_IC));
+
+  masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver,
+                                               name, r6, r7, r8, r9);
+
+  // Cache miss: Jump to runtime.
+  GenerateMiss(masm);
+}
+
+
+void StoreIC::GenerateMiss(MacroAssembler* masm) {
+  __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
+          StoreDescriptor::ValueRegister());
+
+  // Perform tail call to the entry.
+  ExternalReference ref =
+      ExternalReference(IC_Utility(kStoreIC_Miss), masm->isolate());
+  __ TailCallExternalReference(ref, 3, 1);
+}
+
+
+void StoreIC::GenerateNormal(MacroAssembler* masm) {
+  Label miss;
+  Register receiver = StoreDescriptor::ReceiverRegister();
+  Register name = StoreDescriptor::NameRegister();
+  Register value = StoreDescriptor::ValueRegister();
+  Register dictionary = r6;
+  DCHECK(receiver.is(r4));
+  DCHECK(name.is(r5));
+  DCHECK(value.is(r3));
+
+  __ LoadP(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+
+  GenerateDictionaryStore(masm, &miss, dictionary, name, value, r7, r8);
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->store_normal_hit(), 1, r7, r8);
+  __ Ret();
+
+  __ bind(&miss);
+  __ IncrementCounter(counters->store_normal_miss(), 1, r7, r8);
+  GenerateMiss(masm);
+}
+
+
+#undef __
+
+
+Condition CompareIC::ComputeCondition(Token::Value op) {
+  switch (op) {
+    case Token::EQ_STRICT:
+    case Token::EQ:
+      return eq;
+    case Token::LT:
+      return lt;
+    case Token::GT:
+      return gt;
+    case Token::LTE:
+      return le;
+    case Token::GTE:
+      return ge;
+    default:
+      UNREACHABLE();
+      return kNoCondition;
+  }
+}
+
+
+bool CompareIC::HasInlinedSmiCode(Address address) {
+  // The address of the instruction following the call.
+  Address cmp_instruction_address =
+      Assembler::return_address_from_call_start(address);
+
+  // If the instruction following the call is not a cmp rx, #yyy, nothing
+  // was inlined.
+  Instr instr = Assembler::instr_at(cmp_instruction_address);
+  return Assembler::IsCmpImmediate(instr);
+}
+
+
+//
+// This code is paired with the JumpPatchSite class in full-codegen-ppc.cc
+//
+void PatchInlinedSmiCode(Address address, InlinedSmiCheck check) {
+  Address cmp_instruction_address =
+      Assembler::return_address_from_call_start(address);
+
+  // If the instruction following the call is not a cmp rx, #yyy, nothing
+  // was inlined.
+  Instr instr = Assembler::instr_at(cmp_instruction_address);
+  if (!Assembler::IsCmpImmediate(instr)) {
+    return;
+  }
+
+  // The delta to the start of the map check instruction and the
+  // condition code uses at the patched jump.
+  int delta = Assembler::GetCmpImmediateRawImmediate(instr);
+  delta += Assembler::GetCmpImmediateRegister(instr).code() * kOff16Mask;
+  // If the delta is 0 the instruction is cmp r0, #0 which also signals that
+  // nothing was inlined.
+  if (delta == 0) {
+    return;
+  }
+
+  if (FLAG_trace_ic) {
+    PrintF("[  patching ic at %p, cmp=%p, delta=%d\n", address,
+           cmp_instruction_address, delta);
+  }
+
+  Address patch_address =
+      cmp_instruction_address - delta * Instruction::kInstrSize;
+  Instr instr_at_patch = Assembler::instr_at(patch_address);
+  Instr branch_instr =
+      Assembler::instr_at(patch_address + Instruction::kInstrSize);
+  // This is patching a conditional "jump if not smi/jump if smi" site.
+  // Enabling by changing from
+  //   cmp cr0, rx, rx
+  // to
+  //  rlwinm(r0, value, 0, 31, 31, SetRC);
+  //  bc(label, BT/BF, 2)
+  // and vice-versa to be disabled again.
+  CodePatcher patcher(patch_address, 2);
+  Register reg = Assembler::GetRA(instr_at_patch);
+  if (check == ENABLE_INLINED_SMI_CHECK) {
+    DCHECK(Assembler::IsCmpRegister(instr_at_patch));
+    DCHECK_EQ(Assembler::GetRA(instr_at_patch).code(),
+              Assembler::GetRB(instr_at_patch).code());
+    patcher.masm()->TestIfSmi(reg, r0);
+  } else {
+    DCHECK(check == DISABLE_INLINED_SMI_CHECK);
+#if V8_TARGET_ARCH_PPC64
+    DCHECK(Assembler::IsRldicl(instr_at_patch));
+#else
+    DCHECK(Assembler::IsRlwinm(instr_at_patch));
+#endif
+    patcher.masm()->cmp(reg, reg, cr0);
+  }
+  DCHECK(Assembler::IsBranch(branch_instr));
+
+  // Invert the logic of the branch
+  if (Assembler::GetCondition(branch_instr) == eq) {
+    patcher.EmitCondition(ne);
+  } else {
+    DCHECK(Assembler::GetCondition(branch_instr) == ne);
+    patcher.EmitCondition(eq);
+  }
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ic/ppc/stub-cache-ppc.cc b/src/ic/ppc/stub-cache-ppc.cc
new file mode 100644
index 0000000..816a2ae
--- /dev/null
+++ b/src/ic/ppc/stub-cache-ppc.cc
@@ -0,0 +1,191 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/codegen.h"
+#include "src/ic/stub-cache.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm)
+
+
+static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
+                       Code::Flags flags, bool leave_frame,
+                       StubCache::Table table, Register receiver, Register name,
+                       // Number of the cache entry, not scaled.
+                       Register offset, Register scratch, Register scratch2,
+                       Register offset_scratch) {
+  ExternalReference key_offset(isolate->stub_cache()->key_reference(table));
+  ExternalReference value_offset(isolate->stub_cache()->value_reference(table));
+  ExternalReference map_offset(isolate->stub_cache()->map_reference(table));
+
+  uintptr_t key_off_addr = reinterpret_cast<uintptr_t>(key_offset.address());
+  uintptr_t value_off_addr =
+      reinterpret_cast<uintptr_t>(value_offset.address());
+  uintptr_t map_off_addr = reinterpret_cast<uintptr_t>(map_offset.address());
+
+  // Check the relative positions of the address fields.
+  DCHECK(value_off_addr > key_off_addr);
+  DCHECK((value_off_addr - key_off_addr) % 4 == 0);
+  DCHECK((value_off_addr - key_off_addr) < (256 * 4));
+  DCHECK(map_off_addr > key_off_addr);
+  DCHECK((map_off_addr - key_off_addr) % 4 == 0);
+  DCHECK((map_off_addr - key_off_addr) < (256 * 4));
+
+  Label miss;
+  Register base_addr = scratch;
+  scratch = no_reg;
+
+  // Multiply by 3 because there are 3 fields per entry (name, code, map).
+  __ ShiftLeftImm(offset_scratch, offset, Operand(1));
+  __ add(offset_scratch, offset, offset_scratch);
+
+  // Calculate the base address of the entry.
+  __ mov(base_addr, Operand(key_offset));
+  __ ShiftLeftImm(scratch2, offset_scratch, Operand(kPointerSizeLog2));
+  __ add(base_addr, base_addr, scratch2);
+
+  // Check that the key in the entry matches the name.
+  __ LoadP(ip, MemOperand(base_addr, 0));
+  __ cmp(name, ip);
+  __ bne(&miss);
+
+  // Check the map matches.
+  __ LoadP(ip, MemOperand(base_addr, map_off_addr - key_off_addr));
+  __ LoadP(scratch2, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  __ cmp(ip, scratch2);
+  __ bne(&miss);
+
+  // Get the code entry from the cache.
+  Register code = scratch2;
+  scratch2 = no_reg;
+  __ LoadP(code, MemOperand(base_addr, value_off_addr - key_off_addr));
+
+  // Check that the flags match what we're looking for.
+  Register flags_reg = base_addr;
+  base_addr = no_reg;
+  __ lwz(flags_reg, FieldMemOperand(code, Code::kFlagsOffset));
+
+  DCHECK(!r0.is(flags_reg));
+  __ li(r0, Operand(Code::kFlagsNotUsedInLookup));
+  __ andc(flags_reg, flags_reg, r0);
+  __ mov(r0, Operand(flags));
+  __ cmpl(flags_reg, r0);
+  __ bne(&miss);
+
+#ifdef DEBUG
+  if (FLAG_test_secondary_stub_cache && table == StubCache::kPrimary) {
+    __ b(&miss);
+  } else if (FLAG_test_primary_stub_cache && table == StubCache::kSecondary) {
+    __ b(&miss);
+  }
+#endif
+
+  if (leave_frame) __ LeaveFrame(StackFrame::INTERNAL);
+
+  // Jump to the first instruction in the code stub.
+  __ addi(r0, code, Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ mtctr(r0);
+  __ bctr();
+
+  // Miss: fall through.
+  __ bind(&miss);
+}
+
+
+void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags,
+                              bool leave_frame, Register receiver,
+                              Register name, Register scratch, Register extra,
+                              Register extra2, Register extra3) {
+  Isolate* isolate = masm->isolate();
+  Label miss;
+
+#if V8_TARGET_ARCH_PPC64
+  // Make sure that code is valid. The multiplying code relies on the
+  // entry size being 24.
+  DCHECK(sizeof(Entry) == 24);
+#else
+  // Make sure that code is valid. The multiplying code relies on the
+  // entry size being 12.
+  DCHECK(sizeof(Entry) == 12);
+#endif
+
+  // Make sure the flags does not name a specific type.
+  DCHECK(Code::ExtractTypeFromFlags(flags) == 0);
+
+  // Make sure that there are no register conflicts.
+  DCHECK(!scratch.is(receiver));
+  DCHECK(!scratch.is(name));
+  DCHECK(!extra.is(receiver));
+  DCHECK(!extra.is(name));
+  DCHECK(!extra.is(scratch));
+  DCHECK(!extra2.is(receiver));
+  DCHECK(!extra2.is(name));
+  DCHECK(!extra2.is(scratch));
+  DCHECK(!extra2.is(extra));
+
+  // Check scratch, extra and extra2 registers are valid.
+  DCHECK(!scratch.is(no_reg));
+  DCHECK(!extra.is(no_reg));
+  DCHECK(!extra2.is(no_reg));
+  DCHECK(!extra3.is(no_reg));
+
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1, extra2,
+                      extra3);
+
+  // Check that the receiver isn't a smi.
+  __ JumpIfSmi(receiver, &miss);
+
+  // Get the map of the receiver and compute the hash.
+  __ lwz(scratch, FieldMemOperand(name, Name::kHashFieldOffset));
+  __ LoadP(ip, FieldMemOperand(receiver, HeapObject::kMapOffset));
+  __ add(scratch, scratch, ip);
+#if V8_TARGET_ARCH_PPC64
+  // Use only the low 32 bits of the map pointer.
+  __ rldicl(scratch, scratch, 0, 32);
+#endif
+  uint32_t mask = kPrimaryTableSize - 1;
+  // We shift out the last two bits because they are not part of the hash and
+  // they are always 01 for maps.
+  __ ShiftRightImm(scratch, scratch, Operand(kCacheIndexShift));
+  // Mask down the eor argument to the minimum to keep the immediate
+  // encodable.
+  __ xori(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask));
+  // Prefer and_ to ubfx here because ubfx takes 2 cycles.
+  __ andi(scratch, scratch, Operand(mask));
+
+  // Probe the primary table.
+  ProbeTable(isolate, masm, flags, leave_frame, kPrimary, receiver, name,
+             scratch, extra, extra2, extra3);
+
+  // Primary miss: Compute hash for secondary probe.
+  __ ShiftRightImm(extra, name, Operand(kCacheIndexShift));
+  __ sub(scratch, scratch, extra);
+  uint32_t mask2 = kSecondaryTableSize - 1;
+  __ addi(scratch, scratch, Operand((flags >> kCacheIndexShift) & mask2));
+  __ andi(scratch, scratch, Operand(mask2));
+
+  // Probe the secondary table.
+  ProbeTable(isolate, masm, flags, leave_frame, kSecondary, receiver, name,
+             scratch, extra, extra2, extra3);
+
+  // Cache miss: Fall-through and let caller handle the miss by
+  // entering the runtime system.
+  __ bind(&miss);
+  __ IncrementCounter(counters->megamorphic_stub_cache_misses(), 1, extra2,
+                      extra3);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ic/stub-cache.h b/src/ic/stub-cache.h
index 7aee6f1..4223b28 100644
--- a/src/ic/stub-cache.h
+++ b/src/ic/stub-cache.h
@@ -52,10 +52,10 @@
   // Arguments extra, extra2 and extra3 may be used to pass additional scratch
   // registers. Set to no_reg if not needed.
   // If leave_frame is true, then exit a frame before the tail call.
-  void GenerateProbe(MacroAssembler* masm, Code::Flags flags, bool leave_frame,
-                     Register receiver, Register name, Register scratch,
-                     Register extra, Register extra2 = no_reg,
-                     Register extra3 = no_reg);
+  void GenerateProbe(MacroAssembler* masm, Code::Kind ic_kind,
+                     Code::Flags flags, bool leave_frame, Register receiver,
+                     Register name, Register scratch, Register extra,
+                     Register extra2 = no_reg, Register extra3 = no_reg);
 
   enum Table { kPrimary, kSecondary };
 
diff --git a/src/ic/x64/handler-compiler-x64.cc b/src/ic/x64/handler-compiler-x64.cc
index c4d6ecf..46fa8cc 100644
--- a/src/ic/x64/handler-compiler-x64.cc
+++ b/src/ic/x64/handler-compiler-x64.cc
@@ -15,6 +15,28 @@
 
 #define __ ACCESS_MASM(masm)
 
+void PropertyHandlerCompiler::PushVectorAndSlot(Register vector,
+                                                Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ Push(vector);
+  __ Push(slot);
+}
+
+
+void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ Pop(slot);
+  __ Pop(vector);
+}
+
+
+void PropertyHandlerCompiler::DiscardVectorAndSlot() {
+  MacroAssembler* masm = this->masm();
+  // Remove vector and slot.
+  __ addp(rsp, Immediate(2 * kPointerSize));
+}
+
+
 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
     MacroAssembler* masm, Label* miss_label, Register receiver,
     Handle<Name> name, Register scratch0, Register scratch1) {
@@ -56,24 +78,16 @@
 
 
 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
-    MacroAssembler* masm, int index, Register prototype, Label* miss) {
-  Isolate* isolate = masm->isolate();
-  // Get the global function with the given index.
-  Handle<JSFunction> function(
-      JSFunction::cast(isolate->native_context()->get(index)));
-
-  // Check we're still in the same context.
-  Register scratch = prototype;
+    MacroAssembler* masm, int index, Register result, Label* miss) {
   const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
-  __ movp(scratch, Operand(rsi, offset));
-  __ movp(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset));
-  __ Cmp(Operand(scratch, Context::SlotOffset(index)), function);
-  __ j(not_equal, miss);
-
+  __ movp(result, Operand(rsi, offset));
+  __ movp(result, FieldOperand(result, GlobalObject::kNativeContextOffset));
+  __ movp(result, Operand(result, Context::SlotOffset(index)));
   // Load its initial map. The global functions all have initial maps.
-  __ Move(prototype, Handle<Map>(function->initial_map()));
+  __ movp(result,
+          FieldOperand(result, JSFunction::kPrototypeOrInitialMapOffset));
   // Load the prototype from the initial map.
-  __ movp(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
+  __ movp(result, FieldOperand(result, Map::kPrototypeOffset));
 }
 
 
@@ -324,169 +338,60 @@
 }
 
 
-// Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
-// store is successful.
-void NamedStoreHandlerCompiler::GenerateStoreTransition(
-    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
-    Register storage_reg, Register value_reg, Register scratch1,
-    Register scratch2, Register unused, Label* miss_label, Label* slow) {
-  int descriptor = transition->LastAdded();
-  DescriptorArray* descriptors = transition->instance_descriptors();
-  PropertyDetails details = descriptors->GetDetails(descriptor);
-  Representation representation = details.representation();
-  DCHECK(!representation.IsNone());
-
-  if (details.type() == CONSTANT) {
-    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
-    __ Cmp(value_reg, constant);
-    __ j(not_equal, miss_label);
-  } else if (representation.IsSmi()) {
-    __ JumpIfNotSmi(value_reg, miss_label);
-  } else if (representation.IsHeapObject()) {
-    __ JumpIfSmi(value_reg, miss_label);
-    HeapType* field_type = descriptors->GetFieldType(descriptor);
-    HeapType::Iterator<Map> it = field_type->Classes();
-    if (!it.Done()) {
-      Label do_store;
-      while (true) {
-        __ CompareMap(value_reg, it.Current());
-        it.Advance();
-        if (it.Done()) {
-          __ j(not_equal, miss_label);
-          break;
-        }
-        __ j(equal, &do_store, Label::kNear);
-      }
-      __ bind(&do_store);
-    }
-  } else if (representation.IsDouble()) {
-    Label do_store, heap_number;
-    __ AllocateHeapNumber(storage_reg, scratch1, slow, MUTABLE);
-
-    __ JumpIfNotSmi(value_reg, &heap_number);
-    __ SmiToInteger32(scratch1, value_reg);
-    __ Cvtlsi2sd(xmm0, scratch1);
-    __ jmp(&do_store);
-
-    __ bind(&heap_number);
-    __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
-                DONT_DO_SMI_CHECK);
-    __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset));
-
-    __ bind(&do_store);
-    __ movsd(FieldOperand(storage_reg, HeapNumber::kValueOffset), xmm0);
-  }
-
-  // Stub never generated for objects that require access checks.
-  DCHECK(!transition->is_access_check_needed());
-
-  // Perform map transition for the receiver if necessary.
-  if (details.type() == FIELD &&
-      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
-    // The properties must be extended before we can store the value.
-    // We jump to a runtime call that extends the properties array.
-    __ PopReturnAddressTo(scratch1);
-    __ Push(receiver_reg);
-    __ Push(transition);
-    __ Push(value_reg);
-    __ PushReturnAddressFrom(scratch1);
-    __ TailCallExternalReference(
-        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                          isolate()),
-        3, 1);
-    return;
-  }
-
-  // Update the map of the object.
-  __ Move(scratch1, transition);
-  __ movp(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
-
-  // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
-                      kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
-
-  if (details.type() == CONSTANT) {
-    DCHECK(value_reg.is(rax));
-    __ ret(0);
-    return;
-  }
-
-  int index = transition->instance_descriptors()->GetFieldIndex(
-      transition->LastAdded());
-
-  // Adjust for the number of properties stored in the object. Even in the
-  // face of a transition we can use the old map here because the size of the
-  // object and the number of in-object properties is not going to change.
-  index -= transition->inobject_properties();
-
-  // TODO(verwaest): Share this code as a code stub.
-  SmiCheck smi_check =
-      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
-  if (index < 0) {
-    // Set the property straight into the object.
-    int offset = transition->instance_size() + (index * kPointerSize);
-    if (representation.IsDouble()) {
-      __ movp(FieldOperand(receiver_reg, offset), storage_reg);
-    } else {
-      __ movp(FieldOperand(receiver_reg, offset), value_reg);
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ movp(storage_reg, value_reg);
-      }
-      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
-                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
-    }
-  } else {
-    // Write to the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    // Get the properties array (optimistically).
-    __ movp(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
-    if (representation.IsDouble()) {
-      __ movp(FieldOperand(scratch1, offset), storage_reg);
-    } else {
-      __ movp(FieldOperand(scratch1, offset), value_reg);
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ movp(storage_reg, value_reg);
-      }
-      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
-                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
-    }
-  }
-
-  // Return the value (register rax).
-  DCHECK(value_reg.is(rax));
-  __ ret(0);
+void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
+  __ Move(this->name(), name);
 }
 
 
-void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
-                                                   Register value_reg,
-                                                   Label* miss_label) {
-  DCHECK(lookup->representation().IsHeapObject());
-  __ JumpIfSmi(value_reg, miss_label);
-  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
-  Label do_store;
-  while (true) {
-    __ CompareMap(value_reg, it.Current());
-    it.Advance();
-    if (it.Done()) {
-      __ j(not_equal, miss_label);
-      break;
-    }
-    __ j(equal, &do_store, Label::kNear);
+void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition,
+                                                   Register scratch,
+                                                   Label* miss) {
+  Handle<WeakCell> cell = Map::WeakCellForMap(transition);
+  Register map_reg = StoreTransitionDescriptor::MapRegister();
+  DCHECK(!map_reg.is(scratch));
+  __ LoadWeakValue(map_reg, cell, miss);
+  if (transition->CanBeDeprecated()) {
+    __ movl(scratch, FieldOperand(map_reg, Map::kBitField3Offset));
+    __ andl(scratch, Immediate(Map::Deprecated::kMask));
+    __ j(not_zero, miss);
   }
-  __ bind(&do_store);
+}
 
-  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
-                      lookup->representation());
-  GenerateTailCall(masm(), stub.GetCode());
+
+void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg,
+                                                      int descriptor,
+                                                      Register value_reg,
+                                                      Register scratch,
+                                                      Label* miss_label) {
+  DCHECK(!map_reg.is(scratch));
+  DCHECK(!map_reg.is(value_reg));
+  DCHECK(!value_reg.is(scratch));
+  __ LoadInstanceDescriptors(map_reg, scratch);
+  __ movp(scratch,
+          FieldOperand(scratch, DescriptorArray::GetValueOffset(descriptor)));
+  __ cmpp(value_reg, scratch);
+  __ j(not_equal, miss_label);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
+                                                        Register value_reg,
+                                                        Label* miss_label) {
+  __ JumpIfSmi(value_reg, miss_label);
+  HeapType::Iterator<Map> it = field_type->Classes();
+  if (!it.Done()) {
+    Label do_store;
+    while (true) {
+      __ CompareMap(value_reg, it.Current());
+      it.Advance();
+      if (it.Done()) {
+        __ j(not_equal, miss_label);
+        break;
+      }
+      __ j(equal, &do_store, Label::kNear);
+    }
+    __ bind(&do_store);
+  }
 }
 
 
@@ -543,18 +448,13 @@
       reg = holder_reg;  // From now on the object will be in holder_reg.
       __ movp(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
     } else {
-      bool in_new_space = heap()->InNewSpace(*prototype);
-      // Two possible reasons for loading the prototype from the map:
-      // (1) Can't store references to new space in code.
-      // (2) Handler is shared for all receivers with the same prototype
-      //     map (but not necessarily the same prototype instance).
-      bool load_prototype_from_map = in_new_space || depth == 1;
-      if (load_prototype_from_map) {
-        // Save the map in scratch1 for later.
-        __ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
-      }
+      Register map_reg = scratch1;
+      __ movp(map_reg, FieldOperand(reg, HeapObject::kMapOffset));
+
       if (depth != 1 || check == CHECK_ALL_MAPS) {
-        __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
+        Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+        __ CmpWeakValue(map_reg, cell, scratch2);
+        __ j(not_equal, miss);
       }
 
       // Check access rights to the global object.  This has to happen after
@@ -571,11 +471,7 @@
       }
       reg = holder_reg;  // From now on the object will be in holder_reg.
 
-      if (load_prototype_from_map) {
-        __ movp(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
-      } else {
-        __ Move(reg, prototype);
-      }
+      __ movp(reg, FieldOperand(map_reg, Map::kPrototypeOffset));
     }
 
     // Go to the next object in the prototype chain.
@@ -587,8 +483,10 @@
   LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
 
   if (depth != 0 || check == CHECK_ALL_MAPS) {
-    // Check the holder map.
-    __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
+    __ movp(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
+    Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+    __ CmpWeakValue(scratch1, cell, scratch2);
+    __ j(not_equal, miss);
   }
 
   // Perform security check for access to the global object.
@@ -608,6 +506,10 @@
     Label success;
     __ jmp(&success);
     __ bind(miss);
+    if (IC::ICUseVector(kind())) {
+      DCHECK(kind() == Code::LOAD_IC);
+      PopVectorAndSlot();
+    }
     TailCallBuiltin(masm(), MissBuiltin(kind()));
     __ bind(&success);
   }
@@ -706,6 +608,7 @@
     }
     __ Push(holder_reg);
     __ Push(this->name());
+    InterceptorVectorSlotPush(holder_reg);
 
     // Invoke an interceptor.  Note: map checks from receiver to
     // interceptor's holder has been compiled before (see a caller
@@ -723,6 +626,7 @@
     __ ret(0);
 
     __ bind(&interceptor_failed);
+    InterceptorVectorSlotPop(holder_reg);
     __ Pop(this->name());
     __ Pop(holder_reg);
     if (must_preserve_receiver_reg) {
@@ -755,7 +659,7 @@
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     Handle<JSObject> object, Handle<Name> name,
     Handle<ExecutableAccessorInfo> callback) {
-  Register holder_reg = Frontend(receiver(), name);
+  Register holder_reg = Frontend(name);
 
   __ PopReturnAddressTo(scratch1());
   __ Push(receiver());
@@ -801,11 +705,15 @@
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
   Label miss;
+  if (IC::ICUseVector(kind())) {
+    PushVectorAndSlot();
+  }
   FrontendHeader(receiver(), name, &miss);
 
   // Get the value from the cell.
   Register result = StoreDescriptor::ValueRegister();
-  __ Move(result, cell);
+  Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell);
+  __ LoadWeakValue(result, weak_cell, &miss);
   __ movp(result, FieldOperand(result, PropertyCell::kValueOffset));
 
   // Check for deleted property if property can actually be deleted.
@@ -819,6 +727,9 @@
 
   Counters* counters = isolate()->counters();
   __ IncrementCounter(counters->named_load_global_stub(), 1);
+  if (IC::ICUseVector(kind())) {
+    DiscardVectorAndSlot();
+  }
   __ ret(0);
 
   FrontendFooter(name, &miss);
diff --git a/src/ic/x64/ic-compiler-x64.cc b/src/ic/x64/ic-compiler-x64.cc
index a5848b6..5be9c46 100644
--- a/src/ic/x64/ic-compiler-x64.cc
+++ b/src/ic/x64/ic-compiler-x64.cc
@@ -42,20 +42,22 @@
     MapHandleList* receiver_maps, CodeHandleList* handler_stubs,
     MapHandleList* transitioned_maps) {
   Label miss;
-  __ JumpIfSmi(receiver(), &miss, Label::kNear);
+  __ JumpIfSmi(receiver(), &miss);
 
-  __ movp(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
+  Register map_reg = scratch1();
+  __ movp(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
   int receiver_count = receiver_maps->length();
   for (int i = 0; i < receiver_count; ++i) {
+    Handle<WeakCell> cell = Map::WeakCellForMap(receiver_maps->at(i));
     // Check map and tail call if there's a match
-    __ Cmp(scratch1(), receiver_maps->at(i));
+    __ CmpWeakValue(map_reg, cell, scratch2());
     if (transitioned_maps->at(i).is_null()) {
       __ j(equal, handler_stubs->at(i), RelocInfo::CODE_TARGET);
     } else {
       Label next_map;
       __ j(not_equal, &next_map, Label::kNear);
-      __ Move(transition_map(), transitioned_maps->at(i),
-              RelocInfo::EMBEDDED_OBJECT);
+      Handle<WeakCell> cell = Map::WeakCellForMap(transitioned_maps->at(i));
+      __ LoadWeakValue(transition_map(), cell, &miss);
       __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
       __ bind(&next_map);
     }
@@ -79,9 +81,12 @@
 
   if (check == PROPERTY &&
       (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
-    // In case we are compiling an IC for dictionary loads and stores, just
+    // In case we are compiling an IC for dictionary loads or stores, just
     // check whether the name is unique.
     if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
+      // Keyed loads with dictionaries shouldn't be here, they go generic.
+      // The DCHECK is to protect assumptions when --vector-ics is on.
+      DCHECK(kind() != Code::KEYED_LOAD_IC);
       Register tmp = scratch1();
       __ JumpIfSmi(this->name(), &miss);
       __ movp(tmp, FieldOperand(this->name(), HeapObject::kMapOffset));
@@ -109,8 +114,9 @@
     Handle<Map> map = IC::TypeToMap(*type, isolate());
     if (!map->is_deprecated()) {
       number_of_handled_maps++;
+      Handle<WeakCell> cell = Map::WeakCellForMap(map);
       // Check map and tail call if there's a match
-      __ Cmp(map_reg, map);
+      __ CmpWeakValue(map_reg, cell, scratch2());
       if (type->Is(HeapType::Number())) {
         DCHECK(!number_case.is_unused());
         __ bind(&number_case);
diff --git a/src/ic/x64/ic-x64.cc b/src/ic/x64/ic-x64.cc
index ad79f30..2709a85 100644
--- a/src/ic/x64/ic-x64.cc
+++ b/src/ic/x64/ic-x64.cc
@@ -119,9 +119,8 @@
       NameDictionary::kElementsStartIndex * kPointerSize;
   const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
   const int kTypeAndReadOnlyMask =
-      (PropertyDetails::TypeField::kMask |
-       PropertyDetails::AttributesField::encode(READ_ONLY))
-      << kSmiTagSize;
+      PropertyDetails::TypeField::kMask |
+      PropertyDetails::AttributesField::encode(READ_ONLY);
   __ Test(Operand(elements, scratch1, times_pointer_size,
                   kDetailsOffset - kHeapObjectTag),
           Smi::FromInt(kTypeAndReadOnlyMask));
@@ -403,33 +402,7 @@
 }
 
 
-void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
-  // Return address is on the stack.
-  Label miss;
-
-  Register receiver = LoadDescriptor::ReceiverRegister();
-  Register index = LoadDescriptor::NameRegister();
-  Register scratch = rbx;
-  Register result = rax;
-  DCHECK(!scratch.is(receiver) && !scratch.is(index));
-
-  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
-                                          &miss,  // When not a string.
-                                          &miss,  // When not a number.
-                                          &miss,  // When index out of range.
-                                          STRING_INDEX_IS_ARRAY_INDEX);
-  char_at_generator.GenerateFast(masm);
-  __ ret(0);
-
-  StubRuntimeCallHelper call_helper;
-  char_at_generator.GenerateSlow(masm, call_helper);
-
-  __ bind(&miss);
-  GenerateMiss(masm);
-}
-
-
-static void KeyedStoreGenerateGenericHelper(
+static void KeyedStoreGenerateMegamorphicHelper(
     MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
     KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) {
   Label transition_smi_elements;
@@ -566,12 +539,12 @@
 }
 
 
-void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
-                                   StrictMode strict_mode) {
+void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
+                                       StrictMode strict_mode) {
   // Return address is on the stack.
   Label slow, slow_with_tagged_index, fast_object, fast_object_grow;
   Label fast_double, fast_double_grow;
-  Label array, extra, check_if_double_array;
+  Label array, extra, check_if_double_array, maybe_name_key, miss;
   Register receiver = StoreDescriptor::ReceiverRegister();
   Register key = StoreDescriptor::NameRegister();
   DCHECK(receiver.is(rdx));
@@ -587,7 +560,7 @@
            Immediate(1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved));
   __ j(not_zero, &slow_with_tagged_index);
   // Check that the key is a smi.
-  __ JumpIfNotSmi(key, &slow_with_tagged_index);
+  __ JumpIfNotSmi(key, &maybe_name_key);
   __ SmiToInteger32(key, key);
 
   __ CmpInstanceType(r9, JS_ARRAY_TYPE);
@@ -610,6 +583,17 @@
   PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
   // Never returns to here.
 
+  __ bind(&maybe_name_key);
+  __ movp(r9, FieldOperand(key, HeapObject::kMapOffset));
+  __ movzxbp(r9, FieldOperand(r9, Map::kInstanceTypeOffset));
+  __ JumpIfNotUniqueNameInstanceType(r9, &slow_with_tagged_index);
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::STORE_IC));
+  masm->isolate()->stub_cache()->GenerateProbe(
+      masm, Code::STORE_IC, flags, false, receiver, key, rbx, no_reg);
+  // Cache miss.
+  __ jmp(&miss);
+
   // Extra capacity case: Check if there is extra capacity to
   // perform the store and update the length. Used for adding one
   // element to the array by writing to array[array.length].
@@ -644,10 +628,14 @@
   __ SmiCompareInteger32(FieldOperand(receiver, JSArray::kLengthOffset), key);
   __ j(below_equal, &extra);
 
-  KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow,
-                                  kCheckMap, kDontIncrementLength);
-  KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
-                                  &slow, kDontCheckMap, kIncrementLength);
+  KeyedStoreGenerateMegamorphicHelper(masm, &fast_object, &fast_double, &slow,
+                                      kCheckMap, kDontIncrementLength);
+  KeyedStoreGenerateMegamorphicHelper(masm, &fast_object_grow,
+                                      &fast_double_grow, &slow, kDontCheckMap,
+                                      kIncrementLength);
+
+  __ bind(&miss);
+  GenerateMiss(masm);
 }
 
 
@@ -774,11 +762,30 @@
 }
 
 
-// A register that isn't one of the parameters to the load ic.
-static const Register LoadIC_TempRegister() { return rbx; }
+static void LoadIC_PushArgs(MacroAssembler* masm) {
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register name = LoadDescriptor::NameRegister();
+  if (FLAG_vector_ics) {
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+    DCHECK(!rdi.is(receiver) && !rdi.is(name) && !rdi.is(slot) &&
+           !rdi.is(vector));
 
+    __ PopReturnAddressTo(rdi);
+    __ Push(receiver);
+    __ Push(name);
+    __ Push(slot);
+    __ Push(vector);
+    __ PushReturnAddressFrom(rdi);
+  } else {
+    DCHECK(!rbx.is(receiver) && !rbx.is(name));
 
-static const Register KeyedLoadIC_TempRegister() { return rbx; }
+    __ PopReturnAddressTo(rbx);
+    __ Push(receiver);
+    __ Push(name);
+    __ PushReturnAddressFrom(rbx);
+  }
+}
 
 
 void LoadIC::GenerateMiss(MacroAssembler* masm) {
@@ -787,25 +794,26 @@
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->load_miss(), 1);
 
-  __ PopReturnAddressTo(LoadIC_TempRegister());
-  __ Push(LoadDescriptor::ReceiverRegister());  // receiver
-  __ Push(LoadDescriptor::NameRegister());      // name
-  __ PushReturnAddressFrom(LoadIC_TempRegister());
+  LoadIC_PushArgs(masm);
 
   // Perform tail call to the entry.
   ExternalReference ref =
       ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate());
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
   // The return address is on the stack.
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register name = LoadDescriptor::NameRegister();
+  DCHECK(!rbx.is(receiver) && !rbx.is(name));
 
-  __ PopReturnAddressTo(LoadIC_TempRegister());
-  __ Push(LoadDescriptor::ReceiverRegister());  // receiver
-  __ Push(LoadDescriptor::NameRegister());      // name
-  __ PushReturnAddressFrom(LoadIC_TempRegister());
+  __ PopReturnAddressTo(rbx);
+  __ Push(receiver);
+  __ Push(name);
+  __ PushReturnAddressFrom(rbx);
 
   // Perform tail call to the entry.
   __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
@@ -817,25 +825,26 @@
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->keyed_load_miss(), 1);
 
-  __ PopReturnAddressTo(KeyedLoadIC_TempRegister());
-  __ Push(LoadDescriptor::ReceiverRegister());  // receiver
-  __ Push(LoadDescriptor::NameRegister());      // name
-  __ PushReturnAddressFrom(KeyedLoadIC_TempRegister());
+  LoadIC_PushArgs(masm);
 
   // Perform tail call to the entry.
   ExternalReference ref =
       ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
   // The return address is on the stack.
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register name = LoadDescriptor::NameRegister();
+  DCHECK(!rbx.is(receiver) && !rbx.is(name));
 
-  __ PopReturnAddressTo(KeyedLoadIC_TempRegister());
-  __ Push(LoadDescriptor::ReceiverRegister());  // receiver
-  __ Push(LoadDescriptor::NameRegister());      // name
-  __ PushReturnAddressFrom(KeyedLoadIC_TempRegister());
+  __ PopReturnAddressTo(rbx);
+  __ Push(receiver);
+  __ Push(name);
+  __ PushReturnAddressFrom(rbx);
 
   // Perform tail call to the entry.
   __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
@@ -849,7 +858,7 @@
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::STORE_IC));
   masm->isolate()->stub_cache()->GenerateProbe(
-      masm, flags, false, StoreDescriptor::ReceiverRegister(),
+      masm, Code::STORE_IC, flags, false, StoreDescriptor::ReceiverRegister(),
       StoreDescriptor::NameRegister(), rbx, no_reg);
 
   // Cache miss: Jump to runtime.
diff --git a/src/ic/x64/stub-cache-x64.cc b/src/ic/x64/stub-cache-x64.cc
index a54ddca..f15635c 100644
--- a/src/ic/x64/stub-cache-x64.cc
+++ b/src/ic/x64/stub-cache-x64.cc
@@ -7,7 +7,9 @@
 #if V8_TARGET_ARCH_X64
 
 #include "src/codegen.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
+#include "src/interface-descriptors.h"
 
 namespace v8 {
 namespace internal {
@@ -16,7 +18,7 @@
 
 
 static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
-                       Code::Flags flags, bool leave_frame,
+                       Code::Kind ic_kind, Code::Flags flags, bool leave_frame,
                        StubCache::Table table, Register receiver, Register name,
                        // The offset is scaled by 4, based on
                        // kCacheIndexShift, which is two bits
@@ -41,14 +43,14 @@
   __ LoadAddress(kScratchRegister, key_offset);
 
   // Check that the key in the entry matches the name.
-  // Multiply entry offset by 16 to get the entry address. Since the
-  // offset register already holds the entry offset times four, multiply
-  // by a further four.
-  __ cmpl(name, Operand(kScratchRegister, offset, scale_factor, 0));
+  __ cmpp(name, Operand(kScratchRegister, offset, scale_factor, 0));
   __ j(not_equal, &miss);
 
   // Get the map entry from the cache.
   // Use key_offset + kPointerSize * 2, rather than loading map_offset.
+  DCHECK(isolate->stub_cache()->map_reference(table).address() -
+             isolate->stub_cache()->key_reference(table).address() ==
+         kPointerSize * 2);
   __ movp(kScratchRegister,
           Operand(kScratchRegister, offset, scale_factor, kPointerSize * 2));
   __ cmpp(kScratchRegister, FieldOperand(receiver, HeapObject::kMapOffset));
@@ -82,10 +84,11 @@
 }
 
 
-void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags,
-                              bool leave_frame, Register receiver,
-                              Register name, Register scratch, Register extra,
-                              Register extra2, Register extra3) {
+void StubCache::GenerateProbe(MacroAssembler* masm, Code::Kind ic_kind,
+                              Code::Flags flags, bool leave_frame,
+                              Register receiver, Register name,
+                              Register scratch, Register extra, Register extra2,
+                              Register extra3) {
   Isolate* isolate = masm->isolate();
   Label miss;
   USE(extra);   // The register extra is not used on the X64 platform.
@@ -107,6 +110,17 @@
   DCHECK(extra2.is(no_reg));
   DCHECK(extra3.is(no_reg));
 
+#ifdef DEBUG
+  // If vector-based ics are in use, ensure that scratch doesn't conflict with
+  // the vector and slot registers, which need to be preserved for a handler
+  // call or miss.
+  if (IC::ICUseVector(ic_kind)) {
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    DCHECK(!AreAliased(vector, slot, scratch));
+  }
+#endif
+
   Counters* counters = masm->isolate()->counters();
   __ IncrementCounter(counters->megamorphic_stub_cache_probes(), 1);
 
@@ -123,8 +137,8 @@
   __ andp(scratch, Immediate((kPrimaryTableSize - 1) << kCacheIndexShift));
 
   // Probe the primary table.
-  ProbeTable(isolate, masm, flags, leave_frame, kPrimary, receiver, name,
-             scratch);
+  ProbeTable(isolate, masm, ic_kind, flags, leave_frame, kPrimary, receiver,
+             name, scratch);
 
   // Primary miss: Compute hash for secondary probe.
   __ movl(scratch, FieldOperand(name, Name::kHashFieldOffset));
@@ -136,8 +150,8 @@
   __ andp(scratch, Immediate((kSecondaryTableSize - 1) << kCacheIndexShift));
 
   // Probe the secondary table.
-  ProbeTable(isolate, masm, flags, leave_frame, kSecondary, receiver, name,
-             scratch);
+  ProbeTable(isolate, masm, ic_kind, flags, leave_frame, kSecondary, receiver,
+             name, scratch);
 
   // Cache miss: Fall-through and let caller handle the miss by
   // entering the runtime system.
diff --git a/src/ic/x87/handler-compiler-x87.cc b/src/ic/x87/handler-compiler-x87.cc
index e706998..2ff3595 100644
--- a/src/ic/x87/handler-compiler-x87.cc
+++ b/src/ic/x87/handler-compiler-x87.cc
@@ -47,6 +47,28 @@
 }
 
 
+void PropertyHandlerCompiler::PushVectorAndSlot(Register vector,
+                                                Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ push(vector);
+  __ push(slot);
+}
+
+
+void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) {
+  MacroAssembler* masm = this->masm();
+  __ pop(slot);
+  __ pop(vector);
+}
+
+
+void PropertyHandlerCompiler::DiscardVectorAndSlot() {
+  MacroAssembler* masm = this->masm();
+  // Remove vector and slot.
+  __ add(esp, Immediate(2 * kPointerSize));
+}
+
+
 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
     MacroAssembler* masm, Label* miss_label, Register receiver,
     Handle<Name> name, Register scratch0, Register scratch1) {
@@ -88,28 +110,23 @@
 
 
 void NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
-    MacroAssembler* masm, int index, Register prototype, Label* miss) {
-  // Get the global function with the given index.
-  Handle<JSFunction> function(
-      JSFunction::cast(masm->isolate()->native_context()->get(index)));
-  // Check we're still in the same context.
-  Register scratch = prototype;
+    MacroAssembler* masm, int index, Register result, Label* miss) {
   const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
-  __ mov(scratch, Operand(esi, offset));
-  __ mov(scratch, FieldOperand(scratch, GlobalObject::kNativeContextOffset));
-  __ cmp(Operand(scratch, Context::SlotOffset(index)), function);
-  __ j(not_equal, miss);
-
+  __ mov(result, Operand(esi, offset));
+  __ mov(result, FieldOperand(result, GlobalObject::kNativeContextOffset));
+  __ mov(result, Operand(result, Context::SlotOffset(index)));
   // Load its initial map. The global functions all have initial maps.
-  __ Move(prototype, Immediate(Handle<Map>(function->initial_map())));
+  __ mov(result,
+         FieldOperand(result, JSFunction::kPrototypeOrInitialMapOffset));
   // Load the prototype from the initial map.
-  __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
+  __ mov(result, FieldOperand(result, Map::kPrototypeOffset));
 }
 
 
 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
     MacroAssembler* masm, Register receiver, Register scratch1,
     Register scratch2, Label* miss_label) {
+  DCHECK(!FLAG_vector_ics);
   __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
   __ mov(eax, scratch1);
   __ ret(0);
@@ -329,172 +346,60 @@
 }
 
 
-// Receiver_reg is preserved on jumps to miss_label, but may be destroyed if
-// store is successful.
-void NamedStoreHandlerCompiler::GenerateStoreTransition(
-    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
-    Register storage_reg, Register value_reg, Register scratch1,
-    Register scratch2, Register unused, Label* miss_label, Label* slow) {
-  int descriptor = transition->LastAdded();
-  DescriptorArray* descriptors = transition->instance_descriptors();
-  PropertyDetails details = descriptors->GetDetails(descriptor);
-  Representation representation = details.representation();
-  DCHECK(!representation.IsNone());
-
-  if (details.type() == CONSTANT) {
-    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
-    __ CmpObject(value_reg, constant);
-    __ j(not_equal, miss_label);
-  } else if (representation.IsSmi()) {
-    __ JumpIfNotSmi(value_reg, miss_label);
-  } else if (representation.IsHeapObject()) {
-    __ JumpIfSmi(value_reg, miss_label);
-    HeapType* field_type = descriptors->GetFieldType(descriptor);
-    HeapType::Iterator<Map> it = field_type->Classes();
-    if (!it.Done()) {
-      Label do_store;
-      while (true) {
-        __ CompareMap(value_reg, it.Current());
-        it.Advance();
-        if (it.Done()) {
-          __ j(not_equal, miss_label);
-          break;
-        }
-        __ j(equal, &do_store, Label::kNear);
-      }
-      __ bind(&do_store);
-    }
-  } else if (representation.IsDouble()) {
-    Label do_store, heap_number;
-    __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow, MUTABLE);
-
-    __ JumpIfNotSmi(value_reg, &heap_number);
-    __ SmiUntag(value_reg);
-    __ push(value_reg);
-    __ fild_s(Operand(esp, 0));
-    __ pop(value_reg);
-    __ SmiTag(value_reg);
-    __ jmp(&do_store);
-
-    __ bind(&heap_number);
-    __ CheckMap(value_reg, isolate()->factory()->heap_number_map(), miss_label,
-                DONT_DO_SMI_CHECK);
-    __ fld_d(FieldOperand(value_reg, HeapNumber::kValueOffset));
-
-    __ bind(&do_store);
-    __ fstp_d(FieldOperand(storage_reg, HeapNumber::kValueOffset));
-  }
-
-  // Stub never generated for objects that require access checks.
-  DCHECK(!transition->is_access_check_needed());
-
-  // Perform map transition for the receiver if necessary.
-  if (details.type() == FIELD &&
-      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
-    // The properties must be extended before we can store the value.
-    // We jump to a runtime call that extends the properties array.
-    __ pop(scratch1);  // Return address.
-    __ push(receiver_reg);
-    __ push(Immediate(transition));
-    __ push(value_reg);
-    __ push(scratch1);
-    __ TailCallExternalReference(
-        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
-                          isolate()),
-        3, 1);
-    return;
-  }
-
-  // Update the map of the object.
-  __ mov(scratch1, Immediate(transition));
-  __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
-
-  // Update the write barrier for the map field.
-  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
-                      kDontSaveFPRegs, OMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
-
-  if (details.type() == CONSTANT) {
-    DCHECK(value_reg.is(eax));
-    __ ret(0);
-    return;
-  }
-
-  int index = transition->instance_descriptors()->GetFieldIndex(
-      transition->LastAdded());
-
-  // Adjust for the number of properties stored in the object. Even in the
-  // face of a transition we can use the old map here because the size of the
-  // object and the number of in-object properties is not going to change.
-  index -= transition->inobject_properties();
-
-  SmiCheck smi_check =
-      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
-  // TODO(verwaest): Share this code as a code stub.
-  if (index < 0) {
-    // Set the property straight into the object.
-    int offset = transition->instance_size() + (index * kPointerSize);
-    if (representation.IsDouble()) {
-      __ mov(FieldOperand(receiver_reg, offset), storage_reg);
-    } else {
-      __ mov(FieldOperand(receiver_reg, offset), value_reg);
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
-                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
-    }
-  } else {
-    // Write to the properties array.
-    int offset = index * kPointerSize + FixedArray::kHeaderSize;
-    // Get the properties array (optimistically).
-    __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
-    if (representation.IsDouble()) {
-      __ mov(FieldOperand(scratch1, offset), storage_reg);
-    } else {
-      __ mov(FieldOperand(scratch1, offset), value_reg);
-    }
-
-    if (!representation.IsSmi()) {
-      // Update the write barrier for the array address.
-      if (!representation.IsDouble()) {
-        __ mov(storage_reg, value_reg);
-      }
-      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
-                          kDontSaveFPRegs, EMIT_REMEMBERED_SET, smi_check);
-    }
-  }
-
-  // Return the value (register eax).
-  DCHECK(value_reg.is(eax));
-  __ ret(0);
+void NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) {
+  __ mov(this->name(), Immediate(name));
 }
 
 
-void NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
-                                                   Register value_reg,
-                                                   Label* miss_label) {
-  DCHECK(lookup->representation().IsHeapObject());
-  __ JumpIfSmi(value_reg, miss_label);
-  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
-  Label do_store;
-  while (true) {
-    __ CompareMap(value_reg, it.Current());
-    it.Advance();
-    if (it.Done()) {
-      __ j(not_equal, miss_label);
-      break;
-    }
-    __ j(equal, &do_store, Label::kNear);
+void NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition,
+                                                   Register scratch,
+                                                   Label* miss) {
+  Handle<WeakCell> cell = Map::WeakCellForMap(transition);
+  Register map_reg = StoreTransitionDescriptor::MapRegister();
+  DCHECK(!map_reg.is(scratch));
+  __ LoadWeakValue(map_reg, cell, miss);
+  if (transition->CanBeDeprecated()) {
+    __ mov(scratch, FieldOperand(map_reg, Map::kBitField3Offset));
+    __ and_(scratch, Immediate(Map::Deprecated::kMask));
+    __ j(not_zero, miss);
   }
-  __ bind(&do_store);
+}
 
-  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
-                      lookup->representation());
-  GenerateTailCall(masm(), stub.GetCode());
+
+void NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg,
+                                                      int descriptor,
+                                                      Register value_reg,
+                                                      Register scratch,
+                                                      Label* miss_label) {
+  DCHECK(!map_reg.is(scratch));
+  DCHECK(!map_reg.is(value_reg));
+  DCHECK(!value_reg.is(scratch));
+  __ LoadInstanceDescriptors(map_reg, scratch);
+  __ mov(scratch,
+         FieldOperand(scratch, DescriptorArray::GetValueOffset(descriptor)));
+  __ cmp(value_reg, scratch);
+  __ j(not_equal, miss_label);
+}
+
+
+void NamedStoreHandlerCompiler::GenerateFieldTypeChecks(HeapType* field_type,
+                                                        Register value_reg,
+                                                        Label* miss_label) {
+  __ JumpIfSmi(value_reg, miss_label);
+  HeapType::Iterator<Map> it = field_type->Classes();
+  if (!it.Done()) {
+    Label do_store;
+    while (true) {
+      __ CompareMap(value_reg, it.Current());
+      it.Advance();
+      if (it.Done()) {
+        __ j(not_equal, miss_label);
+        break;
+      }
+      __ j(equal, &do_store, Label::kNear);
+    }
+    __ bind(&do_store);
+  }
 }
 
 
@@ -548,14 +453,12 @@
       reg = holder_reg;  // From now on the object will be in holder_reg.
       __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
     } else {
-      bool in_new_space = heap()->InNewSpace(*prototype);
-      // Two possible reasons for loading the prototype from the map:
-      // (1) Can't store references to new space in code.
-      // (2) Handler is shared for all receivers with the same prototype
-      //     map (but not necessarily the same prototype instance).
-      bool load_prototype_from_map = in_new_space || depth == 1;
+      Register map_reg = scratch1;
+      __ mov(map_reg, FieldOperand(reg, HeapObject::kMapOffset));
       if (depth != 1 || check == CHECK_ALL_MAPS) {
-        __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
+        Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+        __ CmpWeakValue(map_reg, cell, scratch2);
+        __ j(not_equal, miss);
       }
 
       // Check access rights to the global object.  This has to happen after
@@ -565,24 +468,15 @@
       // global proxy (as opposed to using slow ICs). See corresponding code
       // in LookupForRead().
       if (current_map->IsJSGlobalProxyMap()) {
-        __ CheckAccessGlobalProxy(reg, scratch1, scratch2, miss);
+        __ CheckAccessGlobalProxy(reg, map_reg, scratch2, miss);
+        // Restore map_reg.
+        __ mov(map_reg, FieldOperand(reg, HeapObject::kMapOffset));
       } else if (current_map->IsJSGlobalObjectMap()) {
         GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
                                   name, scratch2, miss);
       }
-
-      if (load_prototype_from_map) {
-        // Save the map in scratch1 for later.
-        __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
-      }
-
       reg = holder_reg;  // From now on the object will be in holder_reg.
-
-      if (load_prototype_from_map) {
-        __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
-      } else {
-        __ mov(reg, prototype);
-      }
+      __ mov(reg, FieldOperand(map_reg, Map::kPrototypeOffset));
     }
 
     // Go to the next object in the prototype chain.
@@ -595,7 +489,10 @@
 
   if (depth != 0 || check == CHECK_ALL_MAPS) {
     // Check the holder map.
-    __ CheckMap(reg, current_map, miss, DONT_DO_SMI_CHECK);
+    __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
+    Handle<WeakCell> cell = Map::WeakCellForMap(current_map);
+    __ CmpWeakValue(scratch1, cell, scratch2);
+    __ j(not_equal, miss);
   }
 
   // Perform security check for access to the global object.
@@ -615,6 +512,10 @@
     Label success;
     __ jmp(&success);
     __ bind(miss);
+    if (IC::ICUseVector(kind())) {
+      DCHECK(kind() == Code::LOAD_IC);
+      PopVectorAndSlot();
+    }
     TailCallBuiltin(masm(), MissBuiltin(kind()));
     __ bind(&success);
   }
@@ -714,7 +615,7 @@
     }
     __ push(holder_reg);
     __ push(this->name());
-
+    InterceptorVectorSlotPush(holder_reg);
     // Invoke an interceptor.  Note: map checks from receiver to
     // interceptor's holder has been compiled before (see a caller
     // of this method.)
@@ -738,6 +639,7 @@
       __ mov(this->name(), Immediate(bit_cast<int32_t>(kZapValue)));
     }
 
+    InterceptorVectorSlotPop(holder_reg);
     __ pop(this->name());
     __ pop(holder_reg);
     if (must_preserve_receiver_reg) {
@@ -770,7 +672,7 @@
 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
     Handle<JSObject> object, Handle<Name> name,
     Handle<ExecutableAccessorInfo> callback) {
-  Register holder_reg = Frontend(receiver(), name);
+  Register holder_reg = Frontend(name);
 
   __ pop(scratch1());  // remove the return address
   __ push(receiver());
@@ -816,16 +718,15 @@
 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
   Label miss;
-
+  if (IC::ICUseVector(kind())) {
+    PushVectorAndSlot();
+  }
   FrontendHeader(receiver(), name, &miss);
   // Get the value from the cell.
   Register result = StoreDescriptor::ValueRegister();
-  if (masm()->serializer_enabled()) {
-    __ mov(result, Immediate(cell));
-    __ mov(result, FieldOperand(result, PropertyCell::kValueOffset));
-  } else {
-    __ mov(result, Operand::ForCell(cell));
-  }
+  Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell);
+  __ LoadWeakValue(result, weak_cell, &miss);
+  __ mov(result, FieldOperand(result, PropertyCell::kValueOffset));
 
   // Check for deleted property if property can actually be deleted.
   if (is_configurable) {
@@ -839,6 +740,9 @@
   Counters* counters = isolate()->counters();
   __ IncrementCounter(counters->named_load_global_stub(), 1);
   // The code above already loads the result into the return register.
+  if (IC::ICUseVector(kind())) {
+    DiscardVectorAndSlot();
+  }
   __ ret(0);
 
   FrontendFooter(name, &miss);
diff --git a/src/ic/x87/ic-compiler-x87.cc b/src/ic/x87/ic-compiler-x87.cc
index 20b47e7..89bd937 100644
--- a/src/ic/x87/ic-compiler-x87.cc
+++ b/src/ic/x87/ic-compiler-x87.cc
@@ -44,10 +44,13 @@
   Label miss;
 
   if (check == PROPERTY &&
-      (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC)) {
-    // In case we are compiling an IC for dictionary loads and stores, just
+      (kind() == Code::KEYED_STORE_IC || kind() == Code::KEYED_LOAD_IC)) {
+    // In case we are compiling an IC for dictionary loads or stores, just
     // check whether the name is unique.
     if (name.is_identical_to(isolate()->factory()->normal_ic_symbol())) {
+      // Keyed loads with dictionaries shouldn't be here, they go generic.
+      // The DCHECK is to protect assumptions when --vector-ics is on.
+      DCHECK(kind() != Code::KEYED_LOAD_IC);
       Register tmp = scratch1();
       __ JumpIfSmi(this->name(), &miss);
       __ mov(tmp, FieldOperand(this->name(), HeapObject::kMapOffset));
@@ -75,7 +78,8 @@
     Handle<Map> map = IC::TypeToMap(*type, isolate());
     if (!map->is_deprecated()) {
       number_of_handled_maps++;
-      __ cmp(map_reg, map);
+      Handle<WeakCell> cell = Map::WeakCellForMap(map);
+      __ CmpWeakValue(map_reg, cell, scratch2());
       if (type->Is(HeapType::Number())) {
         DCHECK(!number_case.is_unused());
         __ bind(&number_case);
@@ -100,15 +104,18 @@
     MapHandleList* transitioned_maps) {
   Label miss;
   __ JumpIfSmi(receiver(), &miss, Label::kNear);
-  __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
+  Register map_reg = scratch1();
+  __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
   for (int i = 0; i < receiver_maps->length(); ++i) {
-    __ cmp(scratch1(), receiver_maps->at(i));
+    Handle<WeakCell> cell = Map::WeakCellForMap(receiver_maps->at(i));
+    __ CmpWeakValue(map_reg, cell, scratch2());
     if (transitioned_maps->at(i).is_null()) {
       __ j(equal, handler_stubs->at(i));
     } else {
       Label next_map;
       __ j(not_equal, &next_map, Label::kNear);
-      __ mov(transition_map(), Immediate(transitioned_maps->at(i)));
+      Handle<WeakCell> cell = Map::WeakCellForMap(transitioned_maps->at(i));
+      __ LoadWeakValue(transition_map(), cell, &miss);
       __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
       __ bind(&next_map);
     }
diff --git a/src/ic/x87/ic-x87.cc b/src/ic/x87/ic-x87.cc
index 9c090c5..1004ac0 100644
--- a/src/ic/x87/ic-x87.cc
+++ b/src/ic/x87/ic-x87.cc
@@ -478,33 +478,6 @@
 }
 
 
-void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
-  // Return address is on the stack.
-  Label miss;
-
-  Register receiver = LoadDescriptor::ReceiverRegister();
-  Register index = LoadDescriptor::NameRegister();
-  Register scratch = ebx;
-  DCHECK(!scratch.is(receiver) && !scratch.is(index));
-  Register result = eax;
-  DCHECK(!result.is(scratch));
-
-  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
-                                          &miss,  // When not a string.
-                                          &miss,  // When not a number.
-                                          &miss,  // When index out of range.
-                                          STRING_INDEX_IS_ARRAY_INDEX);
-  char_at_generator.GenerateFast(masm);
-  __ ret(0);
-
-  StubRuntimeCallHelper call_helper;
-  char_at_generator.GenerateSlow(masm, call_helper);
-
-  __ bind(&miss);
-  GenerateMiss(masm);
-}
-
-
 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
   // Return address is on the stack.
   Label slow, notin;
@@ -536,7 +509,7 @@
 }
 
 
-static void KeyedStoreGenerateGenericHelper(
+static void KeyedStoreGenerateMegamorphicHelper(
     MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow,
     KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) {
   Label transition_smi_elements;
@@ -674,12 +647,12 @@
 }
 
 
-void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
-                                   StrictMode strict_mode) {
+void KeyedStoreIC::GenerateMegamorphic(MacroAssembler* masm,
+                                       StrictMode strict_mode) {
   // Return address is on the stack.
   Label slow, fast_object, fast_object_grow;
   Label fast_double, fast_double_grow;
-  Label array, extra, check_if_double_array;
+  Label array, extra, check_if_double_array, maybe_name_key, miss;
   Register receiver = StoreDescriptor::ReceiverRegister();
   Register key = StoreDescriptor::NameRegister();
   DCHECK(receiver.is(edx));
@@ -695,7 +668,7 @@
             1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved);
   __ j(not_zero, &slow);
   // Check that the key is a smi.
-  __ JumpIfNotSmi(key, &slow);
+  __ JumpIfNotSmi(key, &maybe_name_key);
   __ CmpInstanceType(edi, JS_ARRAY_TYPE);
   __ j(equal, &array);
   // Check that the object is some kind of JSObject.
@@ -713,6 +686,18 @@
   // Slow case: call runtime.
   __ bind(&slow);
   PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode);
+  // Never returns to here.
+
+  __ bind(&maybe_name_key);
+  __ mov(ebx, FieldOperand(key, HeapObject::kMapOffset));
+  __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
+  __ JumpIfNotUniqueNameInstanceType(ebx, &slow);
+  Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
+      Code::ComputeHandlerFlags(Code::STORE_IC));
+  masm->isolate()->stub_cache()->GenerateProbe(
+      masm, Code::STORE_IC, flags, false, receiver, key, ebx, no_reg);
+  // Cache miss.
+  __ jmp(&miss);
 
   // Extra capacity case: Check if there is extra capacity to
   // perform the store and update the length. Used for adding one
@@ -751,10 +736,14 @@
   __ cmp(key, FieldOperand(receiver, JSArray::kLengthOffset));  // Compare smis.
   __ j(above_equal, &extra);
 
-  KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow,
-                                  kCheckMap, kDontIncrementLength);
-  KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow,
-                                  &slow, kDontCheckMap, kIncrementLength);
+  KeyedStoreGenerateMegamorphicHelper(masm, &fast_object, &fast_double, &slow,
+                                      kCheckMap, kDontIncrementLength);
+  KeyedStoreGenerateMegamorphicHelper(masm, &fast_object_grow,
+                                      &fast_double_grow, &slow, kDontCheckMap,
+                                      kIncrementLength);
+
+  __ bind(&miss);
+  GenerateMiss(masm);
 }
 
 
@@ -780,31 +769,52 @@
 static void LoadIC_PushArgs(MacroAssembler* masm) {
   Register receiver = LoadDescriptor::ReceiverRegister();
   Register name = LoadDescriptor::NameRegister();
-  DCHECK(!ebx.is(receiver) && !ebx.is(name));
+  if (FLAG_vector_ics) {
+    Register slot = VectorLoadICDescriptor::SlotRegister();
+    Register vector = VectorLoadICDescriptor::VectorRegister();
+    DCHECK(!edi.is(receiver) && !edi.is(name) && !edi.is(slot) &&
+           !edi.is(vector));
 
-  __ pop(ebx);
-  __ push(receiver);
-  __ push(name);
-  __ push(ebx);
+    __ pop(edi);
+    __ push(receiver);
+    __ push(name);
+    __ push(slot);
+    __ push(vector);
+    __ push(edi);
+  } else {
+    DCHECK(!ebx.is(receiver) && !ebx.is(name));
+
+    __ pop(ebx);
+    __ push(receiver);
+    __ push(name);
+    __ push(ebx);
+  }
 }
 
 
 void LoadIC::GenerateMiss(MacroAssembler* masm) {
   // Return address is on the stack.
   __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1);
-
   LoadIC_PushArgs(masm);
 
   // Perform tail call to the entry.
   ExternalReference ref =
       ExternalReference(IC_Utility(kLoadIC_Miss), masm->isolate());
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
 void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
   // Return address is on the stack.
-  LoadIC_PushArgs(masm);
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register name = LoadDescriptor::NameRegister();
+  DCHECK(!ebx.is(receiver) && !ebx.is(name));
+
+  __ pop(ebx);
+  __ push(receiver);
+  __ push(name);
+  __ push(ebx);
 
   // Perform tail call to the entry.
   __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
@@ -820,13 +830,21 @@
   // Perform tail call to the entry.
   ExternalReference ref =
       ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
-  __ TailCallExternalReference(ref, 2, 1);
+  int arg_count = FLAG_vector_ics ? 4 : 2;
+  __ TailCallExternalReference(ref, arg_count, 1);
 }
 
 
 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
   // Return address is on the stack.
-  LoadIC_PushArgs(masm);
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register name = LoadDescriptor::NameRegister();
+  DCHECK(!ebx.is(receiver) && !ebx.is(name));
+
+  __ pop(ebx);
+  __ push(receiver);
+  __ push(name);
+  __ push(ebx);
 
   // Perform tail call to the entry.
   __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
@@ -838,7 +856,7 @@
   Code::Flags flags = Code::RemoveTypeAndHolderFromFlags(
       Code::ComputeHandlerFlags(Code::STORE_IC));
   masm->isolate()->stub_cache()->GenerateProbe(
-      masm, flags, false, StoreDescriptor::ReceiverRegister(),
+      masm, Code::STORE_IC, flags, false, StoreDescriptor::ReceiverRegister(),
       StoreDescriptor::NameRegister(), ebx, no_reg);
 
   // Cache miss: Jump to runtime.
diff --git a/src/ic/x87/stub-cache-x87.cc b/src/ic/x87/stub-cache-x87.cc
index 0291ef3..be456ce 100644
--- a/src/ic/x87/stub-cache-x87.cc
+++ b/src/ic/x87/stub-cache-x87.cc
@@ -7,7 +7,9 @@
 #if V8_TARGET_ARCH_X87
 
 #include "src/codegen.h"
+#include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
+#include "src/interface-descriptors.h"
 
 namespace v8 {
 namespace internal {
@@ -16,7 +18,7 @@
 
 
 static void ProbeTable(Isolate* isolate, MacroAssembler* masm,
-                       Code::Flags flags, bool leave_frame,
+                       Code::Kind ic_kind, Code::Flags flags, bool leave_frame,
                        StubCache::Table table, Register name, Register receiver,
                        // Number of the cache entry pointer-size scaled.
                        Register offset, Register extra) {
@@ -56,6 +58,13 @@
     }
 #endif
 
+    if (IC::ICUseVector(ic_kind)) {
+      // The vector and slot were pushed onto the stack before starting the
+      // probe, and need to be dropped before calling the handler.
+      __ pop(VectorLoadICDescriptor::VectorRegister());
+      __ pop(VectorLoadICDescriptor::SlotRegister());
+    }
+
     if (leave_frame) __ leave();
 
     // Jump to the first instruction in the code stub.
@@ -100,6 +109,18 @@
     __ pop(offset);
     __ mov(offset, Operand::StaticArray(offset, times_1, value_offset));
 
+    if (IC::ICUseVector(ic_kind)) {
+      // The vector and slot were pushed onto the stack before starting the
+      // probe, and need to be dropped before calling the handler.
+      Register vector = VectorLoadICDescriptor::VectorRegister();
+      Register slot = VectorLoadICDescriptor::SlotRegister();
+      DCHECK(!offset.is(vector) && !offset.is(slot));
+
+      __ pop(vector);
+      __ pop(slot);
+    }
+
+
     if (leave_frame) __ leave();
 
     // Jump to the first instruction in the code stub.
@@ -113,10 +134,11 @@
 }
 
 
-void StubCache::GenerateProbe(MacroAssembler* masm, Code::Flags flags,
-                              bool leave_frame, Register receiver,
-                              Register name, Register scratch, Register extra,
-                              Register extra2, Register extra3) {
+void StubCache::GenerateProbe(MacroAssembler* masm, Code::Kind ic_kind,
+                              Code::Flags flags, bool leave_frame,
+                              Register receiver, Register name,
+                              Register scratch, Register extra, Register extra2,
+                              Register extra3) {
   Label miss;
 
   // Assert that code is valid.  The multiplying code relies on the entry size
@@ -159,8 +181,8 @@
   DCHECK(kCacheIndexShift == kPointerSizeLog2);
 
   // Probe the primary table.
-  ProbeTable(isolate(), masm, flags, leave_frame, kPrimary, name, receiver,
-             offset, extra);
+  ProbeTable(isolate(), masm, ic_kind, flags, leave_frame, kPrimary, name,
+             receiver, offset, extra);
 
   // Primary miss: Compute hash for secondary probe.
   __ mov(offset, FieldOperand(name, Name::kHashFieldOffset));
@@ -172,8 +194,8 @@
   __ and_(offset, (kSecondaryTableSize - 1) << kCacheIndexShift);
 
   // Probe the secondary table.
-  ProbeTable(isolate(), masm, flags, leave_frame, kSecondary, name, receiver,
-             offset, extra);
+  ProbeTable(isolate(), masm, ic_kind, flags, leave_frame, kSecondary, name,
+             receiver, offset, extra);
 
   // Cache miss: Fall-through and let caller handle the miss by
   // entering the runtime system.
diff --git a/src/interface-descriptors.cc b/src/interface-descriptors.cc
index 62d7105..b1ebc3f 100644
--- a/src/interface-descriptors.cc
+++ b/src/interface-descriptors.cc
@@ -42,7 +42,7 @@
 }
 
 
-const char* CallInterfaceDescriptor::DebugName(Isolate* isolate) {
+const char* CallInterfaceDescriptor::DebugName(Isolate* isolate) const {
   CallInterfaceDescriptorData* start = isolate->call_descriptor_data(0);
   size_t index = data_ - start;
   DCHECK(index < CallDescriptors::NUMBER_OF_DESCRIPTORS);
@@ -74,6 +74,13 @@
 }
 
 
+void StoreTransitionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {ContextRegister(), ReceiverRegister(), NameRegister(),
+                          ValueRegister(), MapRegister()};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
 void ElementTransitionAndStoreDescriptor::Initialize(
     CallInterfaceDescriptorData* data) {
   Register registers[] = {ContextRegister(), ValueRegister(), MapRegister(),
diff --git a/src/interface-descriptors.h b/src/interface-descriptors.h
index b773c91..5d02e84 100644
--- a/src/interface-descriptors.h
+++ b/src/interface-descriptors.h
@@ -16,6 +16,7 @@
 #define INTERFACE_DESCRIPTOR_LIST(V)          \
   V(Load)                                     \
   V(Store)                                    \
+  V(StoreTransition)                          \
   V(ElementTransitionAndStore)                \
   V(Instanceof)                               \
   V(VectorLoadICTrampoline)                   \
@@ -32,6 +33,7 @@
   V(CallConstruct)                            \
   V(RegExpConstructResult)                    \
   V(TransitionElementsKind)                   \
+  V(AllocateHeapNumber)                       \
   V(ArrayConstructorConstantArgCount)         \
   V(ArrayConstructor)                         \
   V(InternalArrayConstructorConstantArgCount) \
@@ -162,7 +164,7 @@
 
   static const Register ContextRegister();
 
-  const char* DebugName(Isolate* isolate);
+  const char* DebugName(Isolate* isolate) const;
 
  protected:
   const CallInterfaceDescriptorData* data() const { return data_; }
@@ -213,6 +215,22 @@
 };
 
 
+class StoreTransitionDescriptor : public StoreDescriptor {
+ public:
+  DECLARE_DESCRIPTOR(StoreTransitionDescriptor, StoreDescriptor)
+
+  // Extends StoreDescriptor with Map parameter.
+  enum ParameterIndices {
+    kReceiverIndex,
+    kNameIndex,
+    kValueIndex,
+    kMapIndex,
+    kParameterCount
+  };
+  static const Register MapRegister();
+};
+
+
 class ElementTransitionAndStoreDescriptor : public StoreDescriptor {
  public:
   DECLARE_DESCRIPTOR(ElementTransitionAndStoreDescriptor, StoreDescriptor)
@@ -329,6 +347,12 @@
 };
 
 
+class AllocateHeapNumberDescriptor : public CallInterfaceDescriptor {
+ public:
+  DECLARE_DESCRIPTOR(AllocateHeapNumberDescriptor, CallInterfaceDescriptor)
+};
+
+
 class ArrayConstructorConstantArgCountDescriptor
     : public CallInterfaceDescriptor {
  public:
diff --git a/src/interface.cc b/src/interface.cc
index 62169f5..a45804c 100644
--- a/src/interface.cc
+++ b/src/interface.cc
@@ -6,23 +6,64 @@
 
 #include "src/interface.h"
 
+#include "src/base/lazy-instance.h"
+
 namespace v8 {
 namespace internal {
 
+// ---------------------------------------------------------------------------
+// Initialization.
+
+struct Interface::Cache {
+  template<int flags>
+  struct Create {
+    static void Construct(Interface* ptr) { ::new (ptr) Interface(flags); }
+  };
+  typedef Create<VALUE + FROZEN> ValueCreate;
+  typedef Create<VALUE + CONST + FROZEN> ConstCreate;
+
+  static base::LazyInstance<Interface, ValueCreate>::type value_interface;
+  static base::LazyInstance<Interface, ConstCreate>::type const_interface;
+};
+
+
+base::LazyInstance<Interface, Interface::Cache::ValueCreate>::type
+    Interface::Cache::value_interface = LAZY_INSTANCE_INITIALIZER;
+
+base::LazyInstance<Interface, Interface::Cache::ConstCreate>::type
+    Interface::Cache::const_interface = LAZY_INSTANCE_INITIALIZER;
+
+
+Interface* Interface::NewValue() {
+  return Cache::value_interface.Pointer();  // Cached.
+}
+
+
+Interface* Interface::NewConst() {
+  return Cache::const_interface.Pointer();  // Cached.
+}
+
+
+// ---------------------------------------------------------------------------
+// Lookup.
+
 Interface* Interface::Lookup(Handle<String> name, Zone* zone) {
   DCHECK(IsModule());
   ZoneHashMap* map = Chase()->exports_;
-  if (map == NULL) return NULL;
+  if (map == nullptr) return nullptr;
   ZoneAllocationPolicy allocator(zone);
-  ZoneHashMap::Entry* p = map->Lookup(name.location(), name->Hash(), false,
-                                      allocator);
-  if (p == NULL) return NULL;
+  ZoneHashMap::Entry* p =
+      map->Lookup(name.location(), name->Hash(), false, allocator);
+  if (p == nullptr) return nullptr;
   DCHECK(*static_cast<String**>(p->key) == *name);
-  DCHECK(p->value != NULL);
+  DCHECK(p->value != nullptr);
   return static_cast<Interface*>(p->value);
 }
 
 
+// ---------------------------------------------------------------------------
+// Addition.
+
 #ifdef DEBUG
 // Current nesting depth for debug output.
 class Nesting {
@@ -48,9 +89,9 @@
     PrintF("%*s# Adding...\n", Nesting::current(), "");
     PrintF("%*sthis = ", Nesting::current(), "");
     this->Print(Nesting::current());
-    const AstRawString* symbol = static_cast<const AstRawString*>(name);
-    PrintF("%*s%.*s : ", Nesting::current(), "", symbol->length(),
-           symbol->raw_data());
+    const AstRawString* raw = static_cast<const AstRawString*>(name);
+    PrintF("%*s%.*s : ", Nesting::current(), "",
+           raw->length(), raw->raw_data());
     interface->Print(Nesting::current());
   }
 #endif
@@ -58,7 +99,7 @@
   ZoneHashMap** map = &Chase()->exports_;
   ZoneAllocationPolicy allocator(zone);
 
-  if (*map == NULL) {
+  if (*map == nullptr) {
     *map = new(zone->New(sizeof(ZoneHashMap)))
         ZoneHashMap(ZoneHashMap::PointersMatch,
                     ZoneHashMap::kDefaultHashMapCapacity, allocator);
@@ -66,10 +107,10 @@
 
   ZoneHashMap::Entry* p =
       (*map)->Lookup(const_cast<void*>(name), hash, !IsFrozen(), allocator);
-  if (p == NULL) {
+  if (p == nullptr) {
     // This didn't have name but was frozen already, that's an error.
     *ok = false;
-  } else if (p->value == NULL) {
+  } else if (p->value == nullptr) {
     p->value = interface;
   } else {
 #ifdef DEBUG
@@ -88,11 +129,14 @@
 }
 
 
+// ---------------------------------------------------------------------------
+// Unification.
+
 void Interface::Unify(Interface* that, Zone* zone, bool* ok) {
   if (this->forward_) return this->Chase()->Unify(that, zone, ok);
   if (that->forward_) return this->Unify(that->Chase(), zone, ok);
-  DCHECK(this->forward_ == NULL);
-  DCHECK(that->forward_ == NULL);
+  DCHECK(this->forward_ == nullptr);
+  DCHECK(that->forward_ == nullptr);
 
   *ok = true;
   if (this == that) return;
@@ -118,7 +162,7 @@
 #endif
 
   // Merge the smaller interface into the larger, for performance.
-  if (this->exports_ != NULL && (that->exports_ == NULL ||
+  if (this->exports_ != nullptr && (that->exports_ == nullptr ||
       this->exports_->occupancy() >= that->exports_->occupancy())) {
     this->DoUnify(that, ok, zone);
   } else {
@@ -138,8 +182,8 @@
 
 
 void Interface::DoUnify(Interface* that, bool* ok, Zone* zone) {
-  DCHECK(this->forward_ == NULL);
-  DCHECK(that->forward_ == NULL);
+  DCHECK(this->forward_ == nullptr);
+  DCHECK(that->forward_ == nullptr);
   DCHECK(!this->IsValue());
   DCHECK(!that->IsValue());
   DCHECK(this->index_ == -1);
@@ -152,8 +196,8 @@
 
   // Try to merge all members from that into this.
   ZoneHashMap* map = that->exports_;
-  if (map != NULL) {
-    for (ZoneHashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
+  if (map != nullptr) {
+    for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
       this->DoAdd(p->key, p->hash, static_cast<Interface*>(p->value), zone, ok);
       if (!*ok) return;
     }
@@ -161,8 +205,8 @@
 
   // If the new interface is larger than that's, then there were members in
   // 'this' which 'that' didn't have. If 'that' was frozen that is an error.
-  int this_size = this->exports_ == NULL ? 0 : this->exports_->occupancy();
-  int that_size = map == NULL ? 0 : map->occupancy();
+  int this_size = this->exports_ == nullptr ? 0 : this->exports_->occupancy();
+  int that_size = map == nullptr ? 0 : map->occupancy();
   if (that->IsFrozen() && this_size > that_size) {
     *ok = false;
     return;
@@ -174,14 +218,19 @@
 }
 
 
+// ---------------------------------------------------------------------------
+// Printing.
+
 #ifdef DEBUG
 void Interface::Print(int n) {
   int n0 = n > 0 ? n : 0;
 
   if (FLAG_print_interface_details) {
     PrintF("%p", static_cast<void*>(this));
-    for (Interface* link = this->forward_; link != NULL; link = link->forward_)
+    for (Interface* link = this->forward_; link != nullptr;
+        link = link->forward_) {
       PrintF("->%p", static_cast<void*>(link));
+    }
     PrintF(" ");
   }
 
@@ -194,14 +243,15 @@
   } else if (IsModule()) {
     PrintF("module %d %s{", Index(), IsFrozen() ? "" : "(unresolved) ");
     ZoneHashMap* map = Chase()->exports_;
-    if (map == NULL || map->occupancy() == 0) {
+    if (map == nullptr || map->occupancy() == 0) {
       PrintF("}\n");
     } else if (n < 0 || n0 >= 2 * FLAG_print_interface_depth) {
       // Avoid infinite recursion on cyclic types.
       PrintF("...}\n");
     } else {
       PrintF("\n");
-      for (ZoneHashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) {
+      for (ZoneHashMap::Entry* p = map->Start();
+           p != nullptr; p = map->Next(p)) {
         String* name = *static_cast<String**>(p->key);
         Interface* interface = static_cast<Interface*>(p->value);
         PrintF("%*s%s : ", n0 + 2, "", name->ToAsciiArray());
diff --git a/src/interface.h b/src/interface.h
index 598d038..1843f47 100644
--- a/src/interface.h
+++ b/src/interface.h
@@ -41,15 +41,9 @@
     return new(zone) Interface(NONE);
   }
 
-  static Interface* NewValue() {
-    static Interface value_interface(VALUE + FROZEN);  // Cached.
-    return &value_interface;
-  }
+  static Interface* NewValue();
 
-  static Interface* NewConst() {
-    static Interface value_interface(VALUE + CONST + FROZEN);  // Cached.
-    return &value_interface;
-  }
+  static Interface* NewConst();
 
   static Interface* NewModule(Zone* zone) {
     return new(zone) Interface(MODULE);
@@ -129,7 +123,7 @@
     return exports ? exports->occupancy() : 0;
   }
 
-  // The context slot in the hosting global context pointing to this module.
+  // The context slot in the hosting script context pointing to this module.
   int Index() {
     DCHECK(IsModule() && IsFrozen());
     return Chase()->index_;
@@ -178,6 +172,8 @@
   // ---------------------------------------------------------------------------
   // Implementation.
  private:
+  struct Cache;
+
   enum Flags {    // All flags are monotonic
     NONE = 0,
     VALUE = 1,    // This type describes a value
diff --git a/src/isolate.cc b/src/isolate.cc
index c6a8b81..b24182b 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -4,20 +4,24 @@
 
 #include <stdlib.h>
 
+#include <fstream>  // NOLINT(readability/streams)
+#include <sstream>
+
 #include "src/v8.h"
 
 #include "src/ast.h"
 #include "src/base/platform/platform.h"
 #include "src/base/sys-info.h"
 #include "src/base/utils/random-number-generator.h"
+#include "src/basic-block-profiler.h"
 #include "src/bootstrapper.h"
 #include "src/codegen.h"
 #include "src/compilation-cache.h"
+#include "src/compilation-statistics.h"
 #include "src/cpu-profiler.h"
 #include "src/debug.h"
 #include "src/deoptimizer.h"
 #include "src/heap/spaces.h"
-#include "src/heap/sweeper-thread.h"
 #include "src/heap-profiler.h"
 #include "src/hydrogen.h"
 #include "src/ic/stub-cache.h"
@@ -64,6 +68,7 @@
 
 void ThreadLocalTop::InitializeInternal() {
   c_entry_fp_ = 0;
+  c_function_ = 0;
   handler_ = 0;
 #ifdef USE_SIMULATOR
   simulator_ = NULL;
@@ -110,12 +115,12 @@
 base::Thread::LocalStorageKey Isolate::isolate_key_;
 base::Thread::LocalStorageKey Isolate::thread_id_key_;
 base::Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
-#ifdef DEBUG
-base::Thread::LocalStorageKey PerThreadAssertScopeBase::thread_local_key;
-#endif  // DEBUG
 base::LazyMutex Isolate::thread_data_table_mutex_ = LAZY_MUTEX_INITIALIZER;
 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
 base::Atomic32 Isolate::isolate_counter_ = 0;
+#if DEBUG
+base::Atomic32 Isolate::isolate_key_created_ = 0;
+#endif
 
 Isolate::PerIsolateThreadData*
     Isolate::FindOrAllocatePerThreadDataForThisThread() {
@@ -155,12 +160,11 @@
   base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
   CHECK(thread_data_table_ == NULL);
   isolate_key_ = base::Thread::CreateThreadLocalKey();
+#if DEBUG
+  base::NoBarrier_Store(&isolate_key_created_, 1);
+#endif
   thread_id_key_ = base::Thread::CreateThreadLocalKey();
   per_isolate_thread_data_key_ = base::Thread::CreateThreadLocalKey();
-#ifdef DEBUG
-  PerThreadAssertScopeBase::thread_local_key =
-      base::Thread::CreateThreadLocalKey();
-#endif  // DEBUG
   thread_data_table_ = new Isolate::ThreadDataTable();
 }
 
@@ -393,7 +397,6 @@
       }
       DCHECK(cursor + 4 <= elements->length());
 
-
       Handle<Code> code = frames[i].code();
       Handle<Smi> offset(Smi::FromInt(frames[i].offset()), this);
       // The stack trace API should not expose receivers and function
@@ -442,30 +445,198 @@
 }
 
 
+Handle<JSArray> Isolate::GetDetailedStackTrace(Handle<JSObject> error_object) {
+  Handle<Name> key_detailed = factory()->detailed_stack_trace_symbol();
+  Handle<Object> stack_trace =
+      JSObject::GetDataProperty(error_object, key_detailed);
+  if (stack_trace->IsJSArray()) return Handle<JSArray>::cast(stack_trace);
+
+  if (!capture_stack_trace_for_uncaught_exceptions_) return Handle<JSArray>();
+
+  // Try to get details from simple stack trace.
+  Handle<JSArray> detailed_stack_trace =
+      GetDetailedFromSimpleStackTrace(error_object);
+  if (!detailed_stack_trace.is_null()) {
+    // Save the detailed stack since the simple one might be withdrawn later.
+    JSObject::SetProperty(error_object, key_detailed, detailed_stack_trace,
+                          STRICT).Assert();
+  }
+  return detailed_stack_trace;
+}
+
+
+class CaptureStackTraceHelper {
+ public:
+  CaptureStackTraceHelper(Isolate* isolate,
+                          StackTrace::StackTraceOptions options)
+      : isolate_(isolate) {
+    if (options & StackTrace::kColumnOffset) {
+      column_key_ =
+          factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("column"));
+    }
+    if (options & StackTrace::kLineNumber) {
+      line_key_ =
+          factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("lineNumber"));
+    }
+    if (options & StackTrace::kScriptId) {
+      script_id_key_ =
+          factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptId"));
+    }
+    if (options & StackTrace::kScriptName) {
+      script_name_key_ =
+          factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptName"));
+    }
+    if (options & StackTrace::kScriptNameOrSourceURL) {
+      script_name_or_source_url_key_ = factory()->InternalizeOneByteString(
+          STATIC_CHAR_VECTOR("scriptNameOrSourceURL"));
+    }
+    if (options & StackTrace::kFunctionName) {
+      function_key_ = factory()->InternalizeOneByteString(
+          STATIC_CHAR_VECTOR("functionName"));
+    }
+    if (options & StackTrace::kIsEval) {
+      eval_key_ =
+          factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isEval"));
+    }
+    if (options & StackTrace::kIsConstructor) {
+      constructor_key_ = factory()->InternalizeOneByteString(
+          STATIC_CHAR_VECTOR("isConstructor"));
+    }
+  }
+
+  Handle<JSObject> NewStackFrameObject(Handle<JSFunction> fun,
+                                       Handle<Code> code, Address pc,
+                                       bool is_constructor) {
+    Handle<JSObject> stack_frame =
+        factory()->NewJSObject(isolate_->object_function());
+
+    Handle<Script> script(Script::cast(fun->shared()->script()));
+
+    if (!line_key_.is_null()) {
+      int script_line_offset = script->line_offset()->value();
+      int position = code->SourcePosition(pc);
+      int line_number = Script::GetLineNumber(script, position);
+      // line_number is already shifted by the script_line_offset.
+      int relative_line_number = line_number - script_line_offset;
+      if (!column_key_.is_null() && relative_line_number >= 0) {
+        Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
+        int start = (relative_line_number == 0) ? 0 :
+            Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
+        int column_offset = position - start;
+        if (relative_line_number == 0) {
+          // For the case where the code is on the same line as the script
+          // tag.
+          column_offset += script->column_offset()->value();
+        }
+        JSObject::AddProperty(stack_frame, column_key_,
+                              handle(Smi::FromInt(column_offset + 1), isolate_),
+                              NONE);
+      }
+      JSObject::AddProperty(stack_frame, line_key_,
+                            handle(Smi::FromInt(line_number + 1), isolate_),
+                            NONE);
+    }
+
+    if (!script_id_key_.is_null()) {
+      JSObject::AddProperty(stack_frame, script_id_key_,
+                            handle(script->id(), isolate_), NONE);
+    }
+
+    if (!script_name_key_.is_null()) {
+      JSObject::AddProperty(stack_frame, script_name_key_,
+                            handle(script->name(), isolate_), NONE);
+    }
+
+    if (!script_name_or_source_url_key_.is_null()) {
+      Handle<Object> result = Script::GetNameOrSourceURL(script);
+      JSObject::AddProperty(stack_frame, script_name_or_source_url_key_, result,
+                            NONE);
+    }
+
+    if (!function_key_.is_null()) {
+      Handle<Object> fun_name(fun->shared()->DebugName(), isolate_);
+      JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE);
+    }
+
+    if (!eval_key_.is_null()) {
+      Handle<Object> is_eval = factory()->ToBoolean(
+          script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
+      JSObject::AddProperty(stack_frame, eval_key_, is_eval, NONE);
+    }
+
+    if (!constructor_key_.is_null()) {
+      Handle<Object> is_constructor_obj = factory()->ToBoolean(is_constructor);
+      JSObject::AddProperty(stack_frame, constructor_key_, is_constructor_obj,
+                            NONE);
+    }
+
+    return stack_frame;
+  }
+
+ private:
+  inline Factory* factory() { return isolate_->factory(); }
+
+  Isolate* isolate_;
+  Handle<String> column_key_;
+  Handle<String> line_key_;
+  Handle<String> script_id_key_;
+  Handle<String> script_name_key_;
+  Handle<String> script_name_or_source_url_key_;
+  Handle<String> function_key_;
+  Handle<String> eval_key_;
+  Handle<String> constructor_key_;
+};
+
+
+Handle<JSArray> Isolate::GetDetailedFromSimpleStackTrace(
+    Handle<JSObject> error_object) {
+  Handle<Name> key = factory()->stack_trace_symbol();
+  Handle<Object> property = JSObject::GetDataProperty(error_object, key);
+  if (!property->IsJSArray()) return Handle<JSArray>();
+  Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property);
+
+  CaptureStackTraceHelper helper(this,
+                                 stack_trace_for_uncaught_exceptions_options_);
+
+  int frames_seen = 0;
+  Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements()));
+  int elements_limit = Smi::cast(simple_stack_trace->length())->value();
+
+  int frame_limit = stack_trace_for_uncaught_exceptions_frame_limit_;
+  if (frame_limit < 0) frame_limit = (elements_limit - 1) / 4;
+
+  Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
+  for (int i = 1; i < elements_limit && frames_seen < frame_limit; i += 4) {
+    Handle<Object> recv = handle(elements->get(i), this);
+    Handle<JSFunction> fun =
+        handle(JSFunction::cast(elements->get(i + 1)), this);
+    Handle<Code> code = handle(Code::cast(elements->get(i + 2)), this);
+    Handle<Smi> offset = handle(Smi::cast(elements->get(i + 3)), this);
+    Address pc = code->address() + offset->value();
+    bool is_constructor =
+        recv->IsJSObject() &&
+        Handle<JSObject>::cast(recv)->map()->constructor() == *fun;
+
+    Handle<JSObject> stack_frame =
+        helper.NewStackFrameObject(fun, code, pc, is_constructor);
+
+    FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame);
+    frames_seen++;
+  }
+
+  stack_trace->set_length(Smi::FromInt(frames_seen));
+  return stack_trace;
+}
+
+
 Handle<JSArray> Isolate::CaptureCurrentStackTrace(
     int frame_limit, StackTrace::StackTraceOptions options) {
+  CaptureStackTraceHelper helper(this, options);
+
   // Ensure no negative values.
   int limit = Max(frame_limit, 0);
   Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
 
-  Handle<String> column_key =
-      factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("column"));
-  Handle<String> line_key =
-      factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("lineNumber"));
-  Handle<String> script_id_key =
-      factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptId"));
-  Handle<String> script_name_key =
-      factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptName"));
-  Handle<String> script_name_or_source_url_key =
-      factory()->InternalizeOneByteString(
-          STATIC_CHAR_VECTOR("scriptNameOrSourceURL"));
-  Handle<String> function_key =
-      factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("functionName"));
-  Handle<String> eval_key =
-      factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isEval"));
-  Handle<String> constructor_key =
-      factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isConstructor"));
-
   StackTraceFrameIterator it(this);
   int frames_seen = 0;
   while (!it.done() && (frames_seen < limit)) {
@@ -480,70 +651,8 @@
       if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) &&
           !this->context()->HasSameSecurityTokenAs(fun->context())) continue;
 
-      // Create a JSObject to hold the information for the StackFrame.
-      Handle<JSObject> stack_frame = factory()->NewJSObject(object_function());
-
-      Handle<Script> script(Script::cast(fun->shared()->script()));
-
-      if (options & StackTrace::kLineNumber) {
-        int script_line_offset = script->line_offset()->value();
-        int position = frames[i].code()->SourcePosition(frames[i].pc());
-        int line_number = Script::GetLineNumber(script, position);
-        // line_number is already shifted by the script_line_offset.
-        int relative_line_number = line_number - script_line_offset;
-        if (options & StackTrace::kColumnOffset && relative_line_number >= 0) {
-          Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
-          int start = (relative_line_number == 0) ? 0 :
-              Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
-          int column_offset = position - start;
-          if (relative_line_number == 0) {
-            // For the case where the code is on the same line as the script
-            // tag.
-            column_offset += script->column_offset()->value();
-          }
-          JSObject::AddProperty(
-              stack_frame, column_key,
-              handle(Smi::FromInt(column_offset + 1), this), NONE);
-        }
-       JSObject::AddProperty(
-            stack_frame, line_key,
-            handle(Smi::FromInt(line_number + 1), this), NONE);
-      }
-
-      if (options & StackTrace::kScriptId) {
-        JSObject::AddProperty(
-            stack_frame, script_id_key, handle(script->id(), this), NONE);
-      }
-
-      if (options & StackTrace::kScriptName) {
-        JSObject::AddProperty(
-            stack_frame, script_name_key, handle(script->name(), this), NONE);
-      }
-
-      if (options & StackTrace::kScriptNameOrSourceURL) {
-        Handle<Object> result = Script::GetNameOrSourceURL(script);
-        JSObject::AddProperty(
-            stack_frame, script_name_or_source_url_key, result, NONE);
-      }
-
-      if (options & StackTrace::kFunctionName) {
-        Handle<Object> fun_name(fun->shared()->DebugName(), this);
-        JSObject::AddProperty(stack_frame, function_key, fun_name, NONE);
-      }
-
-      if (options & StackTrace::kIsEval) {
-        Handle<Object> is_eval =
-            script->compilation_type() == Script::COMPILATION_TYPE_EVAL ?
-                factory()->true_value() : factory()->false_value();
-        JSObject::AddProperty(stack_frame, eval_key, is_eval, NONE);
-      }
-
-      if (options & StackTrace::kIsConstructor) {
-        Handle<Object> is_constructor = (frames[i].is_constructor()) ?
-            factory()->true_value() : factory()->false_value();
-        JSObject::AddProperty(
-            stack_frame, constructor_key, is_constructor, NONE);
-      }
+      Handle<JSObject> stack_frame = helper.NewStackFrameObject(
+          fun, frames[i].code(), frames[i].pc(), frames[i].is_constructor());
 
       FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame);
       frames_seen++;
@@ -591,13 +700,6 @@
 
 
 void Isolate::PrintStack(StringStream* accumulator) {
-  if (!IsInitialized()) {
-    accumulator->Add(
-        "\n==== JS stack trace is not available =======================\n\n");
-    accumulator->Add(
-        "\n==== Isolate for the thread is not initialized =============\n\n");
-    return;
-  }
   // The MentionedObjectCache is not GC-proof at the moment.
   DisallowHeapAllocation no_gc;
   DCHECK(StringStream::IsMentionedObjectCacheClear(this));
@@ -700,14 +802,26 @@
 }
 
 
+bool Isolate::IsInternallyUsedPropertyName(Handle<Object> name) {
+  return name.is_identical_to(factory()->hidden_string()) ||
+         name.is_identical_to(factory()->prototype_users_symbol());
+}
+
+
+bool Isolate::IsInternallyUsedPropertyName(Object* name) {
+  return name == heap()->hidden_string() ||
+         name == heap()->prototype_users_symbol();
+}
+
+
 bool Isolate::MayNamedAccess(Handle<JSObject> receiver,
                              Handle<Object> key,
                              v8::AccessType type) {
   DCHECK(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
 
-  // Skip checks for hidden properties access.  Note, we do not
+  // Skip checks for internally used properties. Note, we do not
   // require existence of a context in this case.
-  if (key.is_identical_to(factory()->hidden_string())) return true;
+  if (IsInternallyUsedPropertyName(key)) return true;
 
   // Check for compatibility between the security tokens in the
   // current lexical context and the accessed object.
@@ -815,22 +929,26 @@
 }
 
 
-void Isolate::InvokeApiInterruptCallback() {
-  // Note: callback below should be called outside of execution access lock.
-  InterruptCallback callback = NULL;
-  void* data = NULL;
-  {
-    ExecutionAccess access(this);
-    callback = api_interrupt_callback_;
-    data = api_interrupt_callback_data_;
-    api_interrupt_callback_ = NULL;
-    api_interrupt_callback_data_ = NULL;
-  }
+void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
+  ExecutionAccess access(this);
+  api_interrupts_queue_.push(InterruptEntry(callback, data));
+  stack_guard()->RequestApiInterrupt();
+}
 
-  if (callback != NULL) {
+
+void Isolate::InvokeApiInterruptCallbacks() {
+  // Note: callback below should be called outside of execution access lock.
+  while (true) {
+    InterruptEntry entry;
+    {
+      ExecutionAccess access(this);
+      if (api_interrupts_queue_.empty()) return;
+      entry = api_interrupts_queue_.front();
+      api_interrupts_queue_.pop();
+    }
     VMState<EXTERNAL> state(this);
     HandleScope handle_scope(this);
-    callback(reinterpret_cast<v8::Isolate*>(this), data);
+    entry.first(reinterpret_cast<v8::Isolate*>(this), entry.second);
   }
 }
 
@@ -921,9 +1039,7 @@
     // Advance to the next JavaScript frame and determine if the
     // current frame is the top-level frame.
     it.Advance();
-    Handle<Object> is_top_level = it.done()
-        ? factory()->true_value()
-        : factory()->false_value();
+    Handle<Object> is_top_level = factory()->ToBoolean(it.done());
     // Generate and print stack trace line.
     Handle<String> line =
         Execution::GetStackTraceLine(recv, fun, pos_obj, is_top_level);
@@ -953,6 +1069,41 @@
 }
 
 
+bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target,
+                                            Handle<Object> exception) {
+  *target = MessageLocation(Handle<Script>(heap_.empty_script()), -1, -1);
+
+  if (!exception->IsJSObject()) return false;
+  Handle<Name> key = factory()->stack_trace_symbol();
+  Handle<Object> property =
+      JSObject::GetDataProperty(Handle<JSObject>::cast(exception), key);
+  if (!property->IsJSArray()) return false;
+  Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property);
+
+  Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements()));
+  int elements_limit = Smi::cast(simple_stack_trace->length())->value();
+
+  for (int i = 1; i < elements_limit; i += 4) {
+    Handle<JSFunction> fun =
+        handle(JSFunction::cast(elements->get(i + 1)), this);
+    if (fun->IsFromNativeScript()) continue;
+    Handle<Code> code = handle(Code::cast(elements->get(i + 2)), this);
+    Handle<Smi> offset = handle(Smi::cast(elements->get(i + 3)), this);
+    Address pc = code->address() + offset->value();
+
+    Object* script = fun->shared()->script();
+    if (script->IsScript() &&
+        !(Script::cast(script)->source()->IsUndefined())) {
+      int pos = code->SourcePosition(pc);
+      Handle<Script> casted_script(Script::cast(script));
+      *target = MessageLocation(casted_script, pos, pos + 1);
+      return true;
+    }
+  }
+  return false;
+}
+
+
 bool Isolate::ShouldReportException(bool* can_be_caught_externally,
                                     bool catchable_by_javascript) {
   // Find the top-most try-catch handler.
@@ -984,6 +1135,8 @@
 }
 
 
+// Traverse prototype chain to find out whether the object is derived from
+// the Error object.
 bool Isolate::IsErrorObject(Handle<Object> obj) {
   if (!obj->IsJSObject()) return false;
 
@@ -1006,6 +1159,98 @@
 
 static int fatal_exception_depth = 0;
 
+
+Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception,
+                                               MessageLocation* location) {
+  Handle<JSArray> stack_trace_object;
+  MessageLocation potential_computed_location;
+  if (capture_stack_trace_for_uncaught_exceptions_) {
+    if (IsErrorObject(exception)) {
+      // We fetch the stack trace that corresponds to this error object.
+      // If the lookup fails, the exception is probably not a valid Error
+      // object. In that case, we fall through and capture the stack trace
+      // at this throw site.
+      stack_trace_object =
+          GetDetailedStackTrace(Handle<JSObject>::cast(exception));
+    }
+    if (stack_trace_object.is_null()) {
+      // Not an error object, we capture stack and location at throw site.
+      stack_trace_object = CaptureCurrentStackTrace(
+          stack_trace_for_uncaught_exceptions_frame_limit_,
+          stack_trace_for_uncaught_exceptions_options_);
+    }
+  }
+  if (!location) {
+    if (!ComputeLocationFromStackTrace(&potential_computed_location,
+                                       exception)) {
+      ComputeLocation(&potential_computed_location);
+    }
+    location = &potential_computed_location;
+  }
+
+  // If the exception argument is a custom object, turn it into a string
+  // before throwing as uncaught exception.  Note that the pending
+  // exception object to be set later must not be turned into a string.
+  if (exception->IsJSObject() && !IsErrorObject(exception)) {
+    MaybeHandle<Object> maybe_exception =
+        Execution::ToDetailString(this, exception);
+    if (!maybe_exception.ToHandle(&exception)) {
+      exception =
+          factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("exception"));
+    }
+  }
+  return MessageHandler::MakeMessageObject(this, "uncaught_exception", location,
+                                           HandleVector<Object>(&exception, 1),
+                                           stack_trace_object);
+}
+
+
+void ReportBootstrappingException(Handle<Object> exception,
+                                  MessageLocation* location) {
+  base::OS::PrintError("Exception thrown during bootstrapping\n");
+  if (location == NULL || location->script().is_null()) return;
+  // We are bootstrapping and caught an error where the location is set
+  // and we have a script for the location.
+  // In this case we could have an extension (or an internal error
+  // somewhere) and we print out the line number at which the error occured
+  // to the console for easier debugging.
+  int line_number =
+      location->script()->GetLineNumber(location->start_pos()) + 1;
+  if (exception->IsString() && location->script()->name()->IsString()) {
+    base::OS::PrintError(
+        "Extension or internal compilation error: %s in %s at line %d.\n",
+        String::cast(*exception)->ToCString().get(),
+        String::cast(location->script()->name())->ToCString().get(),
+        line_number);
+  } else if (location->script()->name()->IsString()) {
+    base::OS::PrintError(
+        "Extension or internal compilation error in %s at line %d.\n",
+        String::cast(location->script()->name())->ToCString().get(),
+        line_number);
+  } else {
+    base::OS::PrintError("Extension or internal compilation error.\n");
+  }
+#ifdef OBJECT_PRINT
+  // Since comments and empty lines have been stripped from the source of
+  // builtins, print the actual source here so that line numbers match.
+  if (location->script()->source()->IsString()) {
+    Handle<String> src(String::cast(location->script()->source()));
+    PrintF("Failing script:\n");
+    int len = src->length();
+    int line_number = 1;
+    PrintF("%5d: ", line_number);
+    for (int i = 0; i < len; i++) {
+      uint16_t character = src->Get(i);
+      PrintF("%c", character);
+      if (character == '\n' && i < len - 2) {
+        PrintF("%5d: ", ++line_number);
+      }
+    }
+  }
+#endif
+}
+
+
 void Isolate::DoThrow(Object* exception, MessageLocation* location) {
   DCHECK(!has_pending_exception());
 
@@ -1020,7 +1265,6 @@
   bool report_exception = catchable_by_javascript && should_report_exception;
   bool try_catch_needs_message =
       can_be_caught_externally && try_catch_handler()->capture_message_;
-  bool bootstrapping = bootstrapper()->IsActive();
   bool rethrowing_message = thread_local_top()->rethrowing_message_;
 
   thread_local_top()->rethrowing_message_ = false;
@@ -1038,113 +1282,32 @@
       ComputeLocation(&potential_computed_location);
       location = &potential_computed_location;
     }
-    // It's not safe to try to make message objects or collect stack traces
-    // while the bootstrapper is active since the infrastructure may not have
-    // been properly initialized.
-    if (!bootstrapping) {
-      Handle<JSArray> stack_trace_object;
-      if (capture_stack_trace_for_uncaught_exceptions_) {
-        if (IsErrorObject(exception_handle)) {
-          // We fetch the stack trace that corresponds to this error object.
-          Handle<Name> key = factory()->detailed_stack_trace_symbol();
-          // Look up as own property.  If the lookup fails, the exception is
-          // probably not a valid Error object.  In that case, we fall through
-          // and capture the stack trace at this throw site.
-          LookupIterator lookup(exception_handle, key,
-                                LookupIterator::OWN_SKIP_INTERCEPTOR);
-          Handle<Object> stack_trace_property;
-          if (Object::GetProperty(&lookup).ToHandle(&stack_trace_property) &&
-              stack_trace_property->IsJSArray()) {
-            stack_trace_object = Handle<JSArray>::cast(stack_trace_property);
-          }
-        }
-        if (stack_trace_object.is_null()) {
-          // Not an error object, we capture at throw site.
-          stack_trace_object = CaptureCurrentStackTrace(
-              stack_trace_for_uncaught_exceptions_frame_limit_,
-              stack_trace_for_uncaught_exceptions_options_);
-        }
-      }
 
-      Handle<Object> exception_arg = exception_handle;
-      // If the exception argument is a custom object, turn it into a string
-      // before throwing as uncaught exception.  Note that the pending
-      // exception object to be set later must not be turned into a string.
-      if (exception_arg->IsJSObject() && !IsErrorObject(exception_arg)) {
-        MaybeHandle<Object> maybe_exception =
-            Execution::ToDetailString(this, exception_arg);
-        if (!maybe_exception.ToHandle(&exception_arg)) {
-          exception_arg = factory()->InternalizeOneByteString(
-              STATIC_CHAR_VECTOR("exception"));
-        }
-      }
-      Handle<Object> message_obj = MessageHandler::MakeMessageObject(
-          this,
-          "uncaught_exception",
-          location,
-          HandleVector<Object>(&exception_arg, 1),
-          stack_trace_object);
+    if (bootstrapper()->IsActive()) {
+      // It's not safe to try to make message objects or collect stack traces
+      // while the bootstrapper is active since the infrastructure may not have
+      // been properly initialized.
+      ReportBootstrappingException(exception_handle, location);
+    } else {
+      Handle<Object> message_obj = CreateMessage(exception_handle, location);
+
       thread_local_top()->pending_message_obj_ = *message_obj;
-      if (location != NULL) {
-        thread_local_top()->pending_message_script_ = *location->script();
-        thread_local_top()->pending_message_start_pos_ = location->start_pos();
-        thread_local_top()->pending_message_end_pos_ = location->end_pos();
-      }
+      thread_local_top()->pending_message_script_ = *location->script();
+      thread_local_top()->pending_message_start_pos_ = location->start_pos();
+      thread_local_top()->pending_message_end_pos_ = location->end_pos();
 
       // If the abort-on-uncaught-exception flag is specified, abort on any
       // exception not caught by JavaScript, even when an external handler is
       // present.  This flag is intended for use by JavaScript developers, so
       // print a user-friendly stack trace (not an internal one).
-      if (fatal_exception_depth == 0 &&
-          FLAG_abort_on_uncaught_exception &&
+      if (fatal_exception_depth == 0 && FLAG_abort_on_uncaught_exception &&
           (report_exception || can_be_caught_externally)) {
         fatal_exception_depth++;
-        PrintF(stderr,
-               "%s\n\nFROM\n",
+        PrintF(stderr, "%s\n\nFROM\n",
                MessageHandler::GetLocalizedMessage(this, message_obj).get());
         PrintCurrentStackTrace(stderr);
         base::OS::Abort();
       }
-    } else if (location != NULL && !location->script().is_null()) {
-      // We are bootstrapping and caught an error where the location is set
-      // and we have a script for the location.
-      // In this case we could have an extension (or an internal error
-      // somewhere) and we print out the line number at which the error occured
-      // to the console for easier debugging.
-      int line_number =
-          location->script()->GetLineNumber(location->start_pos()) + 1;
-      if (exception->IsString() && location->script()->name()->IsString()) {
-        base::OS::PrintError(
-            "Extension or internal compilation error: %s in %s at line %d.\n",
-            String::cast(exception)->ToCString().get(),
-            String::cast(location->script()->name())->ToCString().get(),
-            line_number);
-      } else if (location->script()->name()->IsString()) {
-        base::OS::PrintError(
-            "Extension or internal compilation error in %s at line %d.\n",
-            String::cast(location->script()->name())->ToCString().get(),
-            line_number);
-      } else {
-        base::OS::PrintError("Extension or internal compilation error.\n");
-      }
-#ifdef OBJECT_PRINT
-      // Since comments and empty lines have been stripped from the source of
-      // builtins, print the actual source here so that line numbers match.
-      if (location->script()->source()->IsString()) {
-        Handle<String> src(String::cast(location->script()->source()));
-        PrintF("Failing script:\n");
-        int len = src->length();
-        int line_number = 1;
-        PrintF("%5d: ", line_number);
-        for (int i = 0; i < len; i++) {
-          uint16_t character = src->Get(i);
-          PrintF("%c", character);
-          if (character == '\n' && i < len - 2) {
-            PrintF("%5d: ", ++line_number);
-          }
-        }
-      }
-#endif
     }
   }
 
@@ -1234,7 +1397,6 @@
 
   if (thread_local_top_.pending_exception_ != heap()->termination_exception() &&
       thread_local_top_.has_pending_message_ &&
-      !thread_local_top_.pending_message_obj_->IsTheHole() &&
       !thread_local_top_.pending_message_obj_->IsTheHole()) {
     Handle<Script> script(
         Script::cast(thread_local_top_.pending_message_script_));
@@ -1320,8 +1482,6 @@
   StackHandler* handler = StackHandler::FromAddress(Isolate::handler(tltop));
   do {
     if (handler == promise_try) {
-      // Mark the pushed try-catch handler to prevent a later duplicate event
-      // triggered with the following reject.
       return tltop->promise_on_stack_->promise();
     }
     handler = handler->next();
@@ -1347,11 +1507,6 @@
 }
 
 
-Handle<Context> Isolate::global_context() {
-  return handle(context()->global_object()->global_context());
-}
-
-
 Handle<Context> Isolate::GetCallingNativeContext() {
   JavaScriptFrameIterator it(this);
   if (debug_->in_debug_scope()) {
@@ -1464,9 +1619,8 @@
 #endif
 
 
-Isolate::Isolate()
+Isolate::Isolate(bool enable_serializer)
     : embedder_data_(),
-      state_(UNINITIALIZED),
       entry_stack_(NULL),
       stack_trace_nesting_level_(0),
       incomplete_message_(NULL),
@@ -1492,7 +1646,6 @@
       unicode_cache_(NULL),
       runtime_zone_(this),
       inner_pointer_to_code_cache_(NULL),
-      write_iterator_(NULL),
       global_handles_(NULL),
       eternal_handles_(NULL),
       thread_manager_(NULL),
@@ -1504,7 +1657,7 @@
       // TODO(bmeurer) Initialized lazily because it depends on flags; can
       // be fixed once the default isolate cleanup is done.
       random_number_generator_(NULL),
-      serializer_enabled_(false),
+      serializer_enabled_(enable_serializer),
       has_fatal_error_(false),
       initialized_from_snapshot_(false),
       cpu_profiler_(NULL),
@@ -1512,11 +1665,13 @@
       function_entry_hook_(NULL),
       deferred_handles_head_(NULL),
       optimizing_compiler_thread_(NULL),
-      sweeper_thread_(NULL),
-      num_sweeper_threads_(0),
       stress_deopt_count_(0),
       next_optimization_id_(0),
-      use_counter_callback_(NULL) {
+#if TRACE_MAPS
+      next_unique_sfi_id_(0),
+#endif
+      use_counter_callback_(NULL),
+      basic_block_profiler_(NULL) {
   {
     base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
     CHECK(thread_data_table_);
@@ -1594,63 +1749,52 @@
 
 
 void Isolate::Deinit() {
-  if (state_ == INITIALIZED) {
-    TRACE_ISOLATE(deinit);
+  TRACE_ISOLATE(deinit);
 
-    debug()->Unload();
+  debug()->Unload();
 
-    FreeThreadResources();
+  FreeThreadResources();
 
-    if (concurrent_recompilation_enabled()) {
-      optimizing_compiler_thread_->Stop();
-      delete optimizing_compiler_thread_;
-      optimizing_compiler_thread_ = NULL;
-    }
-
-    for (int i = 0; i < num_sweeper_threads_; i++) {
-      sweeper_thread_[i]->Stop();
-      delete sweeper_thread_[i];
-      sweeper_thread_[i] = NULL;
-    }
-    delete[] sweeper_thread_;
-    sweeper_thread_ = NULL;
-
-    if (FLAG_job_based_sweeping &&
-        heap_.mark_compact_collector()->sweeping_in_progress()) {
-      heap_.mark_compact_collector()->EnsureSweepingCompleted();
-    }
-
-    if (FLAG_turbo_stats) GetTStatistics()->Print("TurboFan");
-    if (FLAG_hydrogen_stats) GetHStatistics()->Print("Hydrogen");
-
-    if (FLAG_print_deopt_stress) {
-      PrintF(stdout, "=== Stress deopt counter: %u\n", stress_deopt_count_);
-    }
-
-    // We must stop the logger before we tear down other components.
-    Sampler* sampler = logger_->sampler();
-    if (sampler && sampler->IsActive()) sampler->Stop();
-
-    delete deoptimizer_data_;
-    deoptimizer_data_ = NULL;
-    builtins_.TearDown();
-    bootstrapper_->TearDown();
-
-    if (runtime_profiler_ != NULL) {
-      delete runtime_profiler_;
-      runtime_profiler_ = NULL;
-    }
-    heap_.TearDown();
-    logger_->TearDown();
-
-    delete heap_profiler_;
-    heap_profiler_ = NULL;
-    delete cpu_profiler_;
-    cpu_profiler_ = NULL;
-
-    // The default isolate is re-initializable due to legacy API.
-    state_ = UNINITIALIZED;
+  if (concurrent_recompilation_enabled()) {
+    optimizing_compiler_thread_->Stop();
+    delete optimizing_compiler_thread_;
+    optimizing_compiler_thread_ = NULL;
   }
+
+  if (heap_.mark_compact_collector()->sweeping_in_progress()) {
+    heap_.mark_compact_collector()->EnsureSweepingCompleted();
+  }
+
+  DumpAndResetCompilationStats();
+
+  if (FLAG_print_deopt_stress) {
+    PrintF(stdout, "=== Stress deopt counter: %u\n", stress_deopt_count_);
+  }
+
+  // We must stop the logger before we tear down other components.
+  Sampler* sampler = logger_->sampler();
+  if (sampler && sampler->IsActive()) sampler->Stop();
+
+  delete deoptimizer_data_;
+  deoptimizer_data_ = NULL;
+  builtins_.TearDown();
+  bootstrapper_->TearDown();
+
+  if (runtime_profiler_ != NULL) {
+    delete runtime_profiler_;
+    runtime_profiler_ = NULL;
+  }
+
+  delete basic_block_profiler_;
+  basic_block_profiler_ = NULL;
+
+  heap_.TearDown();
+  logger_->TearDown();
+
+  delete heap_profiler_;
+  heap_profiler_ = NULL;
+  delete cpu_profiler_;
+  cpu_profiler_ = NULL;
 }
 
 
@@ -1737,8 +1881,6 @@
   bootstrapper_ = NULL;
   delete inner_pointer_to_code_cache_;
   inner_pointer_to_code_cache_ = NULL;
-  delete write_iterator_;
-  write_iterator_ = NULL;
 
   delete thread_manager_;
   thread_manager_ = NULL;
@@ -1827,7 +1969,6 @@
 
 
 bool Isolate::Init(Deserializer* des) {
-  DCHECK(state_ != INITIALIZED);
   TRACE_ISOLATE(init);
 
   stress_deopt_count_ = FLAG_deopt_every_n_times;
@@ -1865,7 +2006,6 @@
   descriptor_lookup_cache_ = new DescriptorLookupCache();
   unicode_cache_ = new UnicodeCache();
   inner_pointer_to_code_cache_ = new InnerPointerToCodeCache(this);
-  write_iterator_ = new ConsStringIteratorOp();
   global_handles_ = new GlobalHandles(this);
   eternal_handles_ = new EternalHandles();
   bootstrapper_ = new Bootstrapper(this);
@@ -1927,9 +2067,7 @@
   builtins_.SetUp(this, create_heap_objects);
 
   if (FLAG_log_internal_timer_events) {
-    set_event_logger(Logger::DefaultTimerEventsLogger);
-  } else {
-    set_event_logger(Logger::EmptyTimerEventsLogger);
+    set_event_logger(Logger::DefaultEventLoggerSentinel);
   }
 
   // Set default value if not yet set.
@@ -1941,11 +2079,6 @@
         Max(Min(base::SysInfo::NumberOfProcessors(), 4), 1);
   }
 
-  if (!FLAG_job_based_sweeping) {
-    num_sweeper_threads_ =
-        SweeperThread::NumberOfThreads(max_available_threads_);
-  }
-
   if (FLAG_trace_hydrogen || FLAG_trace_hydrogen_stubs) {
     PrintF("Concurrent recompilation has been disabled for tracing.\n");
   } else if (OptimizingCompilerThread::Enabled(max_available_threads_)) {
@@ -1953,13 +2086,9 @@
     optimizing_compiler_thread_->Start();
   }
 
-  if (num_sweeper_threads_ > 0) {
-    sweeper_thread_ = new SweeperThread*[num_sweeper_threads_];
-    for (int i = 0; i < num_sweeper_threads_; i++) {
-      sweeper_thread_[i] = new SweeperThread(this);
-      sweeper_thread_[i]->Start();
-    }
-  }
+  // Initialize runtime profiler before deserialization, because collections may
+  // occur, clearing/updating ICs.
+  runtime_profiler_ = new RuntimeProfiler(this);
 
   // If we are deserializing, read the state into the now-empty heap.
   if (!create_heap_objects) {
@@ -1979,7 +2108,10 @@
   // Quiet the heap NaN if needed on target platform.
   if (!create_heap_objects) Assembler::QuietNaN(heap_.nan_value());
 
-  runtime_profiler_ = new RuntimeProfiler(this);
+  if (FLAG_trace_turbo) {
+    // Create an empty file.
+    std::ofstream(GetTurboCfgFileName().c_str(), std::ios_base::trunc);
+  }
 
   // If we are deserializing, log non-function code objects and compiled
   // functions found in the snapshot.
@@ -2006,9 +2138,10 @@
                heap_.amount_of_external_allocated_memory_at_last_global_gc_)),
            Internals::kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset);
 
-  state_ = INITIALIZED;
   time_millis_at_init_ = base::OS::TimeCurrentMillis();
 
+  heap_.NotifyDeserializationComplete();
+
   if (!create_heap_objects) {
     // Now that the heap is consistent, it's OK to generate the code for the
     // deopt entry table that might have been referred to by optimized code in
@@ -2031,6 +2164,8 @@
 
   initialized_from_snapshot_ = (des != NULL);
 
+  if (!FLAG_inline_new) heap_.DisableInlineAllocation();
+
   return true;
 }
 
@@ -2134,15 +2269,29 @@
 }
 
 
+void Isolate::DumpAndResetCompilationStats() {
+  if (turbo_statistics() != nullptr) {
+    OFStream os(stdout);
+    os << *turbo_statistics() << std::endl;
+  }
+  if (hstatistics() != nullptr) hstatistics()->Print();
+  delete turbo_statistics_;
+  turbo_statistics_ = nullptr;
+  delete hstatistics_;
+  hstatistics_ = nullptr;
+}
+
+
 HStatistics* Isolate::GetHStatistics() {
   if (hstatistics() == NULL) set_hstatistics(new HStatistics());
   return hstatistics();
 }
 
 
-HStatistics* Isolate::GetTStatistics() {
-  if (tstatistics() == NULL) set_tstatistics(new HStatistics());
-  return tstatistics();
+CompilationStatistics* Isolate::GetTurboStatistics() {
+  if (turbo_statistics() == NULL)
+    set_turbo_statistics(new CompilationStatistics());
+  return turbo_statistics();
 }
 
 
@@ -2227,18 +2376,18 @@
 
 
 Handle<JSObject> Isolate::GetSymbolRegistry() {
-  if (heap()->symbol_registry()->IsUndefined()) {
+  if (heap()->symbol_registry()->IsSmi()) {
     Handle<Map> map = factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
     Handle<JSObject> registry = factory()->NewJSObjectFromMap(map);
     heap()->set_symbol_registry(*registry);
 
-    static const char* nested[] = {
-      "for", "for_api", "for_intern", "keyFor", "private_api", "private_intern"
-    };
+    static const char* nested[] = {"for", "for_api", "keyFor", "private_api",
+                                   "private_intern"};
     for (unsigned i = 0; i < arraysize(nested); ++i) {
       Handle<String> name = factory()->InternalizeUtf8String(nested[i]);
       Handle<JSObject> obj = factory()->NewJSObjectFromMap(map);
-      JSObject::NormalizeProperties(obj, KEEP_INOBJECT_PROPERTIES, 8);
+      JSObject::NormalizeProperties(obj, KEEP_INOBJECT_PROPERTIES, 8,
+                                    "SetupSymbolRegistry");
       JSObject::SetProperty(registry, name, obj, STRICT).Assert();
     }
   }
@@ -2279,6 +2428,25 @@
 }
 
 
+void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
+  promise_reject_callback_ = callback;
+}
+
+
+void Isolate::ReportPromiseReject(Handle<JSObject> promise,
+                                  Handle<Object> value,
+                                  v8::PromiseRejectEvent event) {
+  if (promise_reject_callback_ == NULL) return;
+  Handle<JSArray> stack_trace;
+  if (event == v8::kPromiseRejectWithNoHandler && value->IsJSObject()) {
+    stack_trace = GetDetailedStackTrace(Handle<JSObject>::cast(value));
+  }
+  promise_reject_callback_(v8::PromiseRejectMessage(
+      v8::Utils::PromiseToLocal(promise), event, v8::Utils::ToLocal(value),
+      v8::Utils::StackTraceToLocal(stack_trace)));
+}
+
+
 void Isolate::EnqueueMicrotask(Handle<Object> microtask) {
   DCHECK(microtask->IsJSFunction() || microtask->IsCallHandlerInfo());
   Handle<FixedArray> queue(heap()->microtask_queue(), this);
@@ -2363,6 +2531,25 @@
 }
 
 
+BasicBlockProfiler* Isolate::GetOrCreateBasicBlockProfiler() {
+  if (basic_block_profiler_ == NULL) {
+    basic_block_profiler_ = new BasicBlockProfiler();
+  }
+  return basic_block_profiler_;
+}
+
+
+std::string Isolate::GetTurboCfgFileName() {
+  if (FLAG_trace_turbo_cfg_file == NULL) {
+    std::ostringstream os;
+    os << "turbo-" << base::OS::GetCurrentProcessId() << "-" << id() << ".cfg";
+    return os.str();
+  } else {
+    return FLAG_trace_turbo_cfg_file;
+  }
+}
+
+
 bool StackLimitCheck::JsHasOverflowed() const {
   StackGuard* stack_guard = isolate_->stack_guard();
 #ifdef USE_SIMULATOR
diff --git a/src/isolate.h b/src/isolate.h
index 24d4b08..42a814a 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -5,6 +5,7 @@
 #ifndef V8_ISOLATE_H_
 #define V8_ISOLATE_H_
 
+#include <queue>
 #include "include/v8-debug.h"
 #include "src/allocation.h"
 #include "src/assert-scope.h"
@@ -20,7 +21,7 @@
 #include "src/heap/heap.h"
 #include "src/optimizing-compiler-thread.h"
 #include "src/regexp-stack.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 #include "src/runtime-profiler.h"
 #include "src/zone.h"
 
@@ -32,6 +33,7 @@
 
 namespace internal {
 
+class BasicBlockProfiler;
 class Bootstrapper;
 class CallInterfaceDescriptorData;
 class CodeGenerator;
@@ -39,7 +41,7 @@
 class CodeStubDescriptor;
 class CodeTracer;
 class CompilationCache;
-class ConsStringIteratorOp;
+class CompilationStatistics;
 class ContextSlotCache;
 class Counters;
 class CpuFeatures;
@@ -168,6 +170,7 @@
 #define FOR_EACH_ISOLATE_ADDRESS_NAME(C)                \
   C(Handler, handler)                                   \
   C(CEntryFP, c_entry_fp)                               \
+  C(CFunction, c_function)                              \
   C(Context, context)                                   \
   C(PendingException, pending_exception)                \
   C(ExternalCaughtException, external_caught_exception) \
@@ -178,7 +181,12 @@
 class ThreadId {
  public:
   // Creates an invalid ThreadId.
-  ThreadId() : id_(kInvalidId) {}
+  ThreadId() { base::NoBarrier_Store(&id_, kInvalidId); }
+
+  ThreadId& operator=(const ThreadId& other) {
+    base::NoBarrier_Store(&id_, base::NoBarrier_Load(&other.id_));
+    return *this;
+  }
 
   // Returns ThreadId for current thread.
   static ThreadId Current() { return ThreadId(GetCurrentThreadId()); }
@@ -188,17 +196,17 @@
 
   // Compares ThreadIds for equality.
   INLINE(bool Equals(const ThreadId& other) const) {
-    return id_ == other.id_;
+    return base::NoBarrier_Load(&id_) == base::NoBarrier_Load(&other.id_);
   }
 
   // Checks whether this ThreadId refers to any thread.
   INLINE(bool IsValid() const) {
-    return id_ != kInvalidId;
+    return base::NoBarrier_Load(&id_) != kInvalidId;
   }
 
   // Converts ThreadId to an integer representation
   // (required for public API: V8::V8::GetCurrentThreadId).
-  int ToInteger() const { return id_; }
+  int ToInteger() const { return static_cast<int>(base::NoBarrier_Load(&id_)); }
 
   // Converts ThreadId to an integer representation
   // (required for public API: V8::V8::TerminateExecution).
@@ -207,13 +215,13 @@
  private:
   static const int kInvalidId = -1;
 
-  explicit ThreadId(int id) : id_(id) {}
+  explicit ThreadId(int id) { base::NoBarrier_Store(&id_, id); }
 
   static int AllocateThreadId();
 
   static int GetCurrentThreadId();
 
-  int id_;
+  base::Atomic32 id_;
 
   static base::Atomic32 highest_thread_id_;
 
@@ -282,6 +290,7 @@
   // Stack.
   Address c_entry_fp_;  // the frame pointer of the top c entry frame
   Address handler_;   // try-blocks are chained through the stack
+  Address c_function_;  // C function that was called at c entry.
 
   // Throwing an exception may cause a Promise rejection.  For this purpose
   // we keep track of a stack of nested promises and the corresponding
@@ -376,14 +385,13 @@
   V(int, pending_microtask_count, 0)                                           \
   V(bool, autorun_microtasks, true)                                            \
   V(HStatistics*, hstatistics, NULL)                                           \
-  V(HStatistics*, tstatistics, NULL)                                           \
+  V(CompilationStatistics*, turbo_statistics, NULL)                            \
   V(HTracer*, htracer, NULL)                                                   \
   V(CodeTracer*, code_tracer, NULL)                                            \
   V(bool, fp_stubs_generated, false)                                           \
   V(int, max_available_threads, 0)                                             \
   V(uint32_t, per_isolate_assert_data, 0xFFFFFFFFu)                            \
-  V(InterruptCallback, api_interrupt_callback, NULL)                           \
-  V(void*, api_interrupt_callback_data, NULL)                                  \
+  V(PromiseRejectCallback, promise_reject_callback, NULL)                      \
   ISOLATE_INIT_SIMULATOR_LIST(V)
 
 #define THREAD_LOCAL_TOP_ACCESSOR(type, name)                        \
@@ -477,6 +485,7 @@
 
   // Returns the isolate inside which the current thread is running.
   INLINE(static Isolate* Current()) {
+    DCHECK(base::NoBarrier_Load(&isolate_key_created_) == 1);
     Isolate* isolate = reinterpret_cast<Isolate*>(
         base::Thread::GetExistingThreadLocal(isolate_key_));
     DCHECK(isolate != NULL);
@@ -484,6 +493,7 @@
   }
 
   INLINE(static Isolate* UncheckedCurrent()) {
+    DCHECK(base::NoBarrier_Load(&isolate_key_created_) == 1);
     return reinterpret_cast<Isolate*>(
         base::Thread::GetThreadLocal(isolate_key_));
   }
@@ -504,8 +514,6 @@
 
   bool Init(Deserializer* des);
 
-  bool IsInitialized() { return state_ == INITIALIZED; }
-
   // True if at least one thread Enter'ed this isolate.
   bool IsInUse() { return entry_stack_ != NULL; }
 
@@ -647,11 +655,15 @@
     return thread->c_entry_fp_;
   }
   static Address handler(ThreadLocalTop* thread) { return thread->handler_; }
+  Address c_function() { return thread_local_top_.c_function_; }
 
   inline Address* c_entry_fp_address() {
     return &thread_local_top_.c_entry_fp_;
   }
   inline Address* handler_address() { return &thread_local_top_.handler_; }
+  inline Address* c_function_address() {
+    return &thread_local_top_.c_function_;
+  }
 
   // Bottom JS entry.
   Address js_entry_sp() {
@@ -735,6 +747,9 @@
   void CaptureAndSetDetailedStackTrace(Handle<JSObject> error_object);
   void CaptureAndSetSimpleStackTrace(Handle<JSObject> error_object,
                                      Handle<Object> caller);
+  Handle<JSArray> GetDetailedStackTrace(Handle<JSObject> error_object);
+  Handle<JSArray> GetDetailedFromSimpleStackTrace(
+      Handle<JSObject> error_object);
 
   // Returns if the top context may access the given global object. If
   // the result is false, the pending exception is guaranteed to be
@@ -746,6 +761,8 @@
   bool MayIndexedAccess(Handle<JSObject> receiver,
                         uint32_t index,
                         v8::AccessType type);
+  bool IsInternallyUsedPropertyName(Handle<Object> name);
+  bool IsInternallyUsedPropertyName(Object* name);
 
   void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
   void ReportFailedAccessCheck(Handle<JSObject> receiver, v8::AccessType type);
@@ -787,13 +804,19 @@
   // Attempts to compute the current source location, storing the
   // result in the target out parameter.
   void ComputeLocation(MessageLocation* target);
+  bool ComputeLocationFromStackTrace(MessageLocation* target,
+                                     Handle<Object> exception);
+
+  Handle<JSMessageObject> CreateMessage(Handle<Object> exception,
+                                        MessageLocation* location);
 
   // Out of resource exception helpers.
   Object* StackOverflow();
   Object* TerminateExecution();
   void CancelTerminateExecution();
 
-  void InvokeApiInterruptCallback();
+  void RequestInterrupt(InterruptCallback callback, void* data);
+  void InvokeApiInterruptCallbacks();
 
   // Administration
   void Iterate(ObjectVisitor* v);
@@ -802,9 +825,8 @@
   void IterateThread(ThreadVisitor* v, char* t);
 
 
-  // Returns the current native and global context.
+  // Returns the current native context.
   Handle<Context> native_context();
-  Handle<Context> global_context();
 
   // Returns the native context of the calling JavaScript code.  That
   // is, the native context of the top-most JavaScript frame.
@@ -911,8 +933,6 @@
     return inner_pointer_to_code_cache_;
   }
 
-  ConsStringIteratorOp* write_iterator() { return write_iterator_; }
-
   GlobalHandles* global_handles() { return global_handles_; }
 
   EternalHandles* eternal_handles() { return eternal_handles_; }
@@ -929,18 +949,6 @@
     return &jsregexp_canonrange_;
   }
 
-  ConsStringIteratorOp* objects_string_compare_iterator_a() {
-    return &objects_string_compare_iterator_a_;
-  }
-
-  ConsStringIteratorOp* objects_string_compare_iterator_b() {
-    return &objects_string_compare_iterator_b_;
-  }
-
-  StaticResource<ConsStringIteratorOp>* objects_string_iterator() {
-    return &objects_string_iterator_;
-  }
-
   RuntimeState* runtime_state() { return &runtime_state_; }
 
   Builtins* builtins() { return &builtins_; }
@@ -997,12 +1005,6 @@
 
   THREAD_LOCAL_TOP_ACCESSOR(LookupResult*, top_lookup_result)
 
-  void enable_serializer() {
-    // The serializer can only be enabled before the isolate init.
-    DCHECK(state_ != INITIALIZED);
-    serializer_enabled_ = true;
-  }
-
   bool serializer_enabled() const { return serializer_enabled_; }
 
   bool IsDead() { return has_fatal_error_; }
@@ -1059,21 +1061,15 @@
     return optimizing_compiler_thread_;
   }
 
-  int num_sweeper_threads() const {
-    return num_sweeper_threads_;
-  }
-
-  SweeperThread** sweeper_threads() {
-    return sweeper_thread_;
-  }
-
   int id() const { return static_cast<int>(id_); }
 
   HStatistics* GetHStatistics();
-  HStatistics* GetTStatistics();
+  CompilationStatistics* GetTurboStatistics();
   HTracer* GetHTracer();
   CodeTracer* GetCodeTracer();
 
+  void DumpAndResetCompilationStats();
+
   FunctionEntryHook function_entry_hook() { return function_entry_hook_; }
   void set_function_entry_hook(FunctionEntryHook function_entry_hook) {
     function_entry_hook_ = function_entry_hook;
@@ -1101,31 +1097,38 @@
   void RemoveCallCompletedCallback(CallCompletedCallback callback);
   void FireCallCompletedCallback();
 
+  void SetPromiseRejectCallback(PromiseRejectCallback callback);
+  void ReportPromiseReject(Handle<JSObject> promise, Handle<Object> value,
+                           v8::PromiseRejectEvent event);
+
   void EnqueueMicrotask(Handle<Object> microtask);
   void RunMicrotasks();
 
   void SetUseCounterCallback(v8::Isolate::UseCounterCallback callback);
   void CountUsage(v8::Isolate::UseCounterFeature feature);
 
-  static Isolate* NewForTesting() { return new Isolate(); }
+  BasicBlockProfiler* GetOrCreateBasicBlockProfiler();
+  BasicBlockProfiler* basic_block_profiler() { return basic_block_profiler_; }
+
+  static Isolate* NewForTesting() { return new Isolate(false); }
+
+  std::string GetTurboCfgFileName();
+
+#if TRACE_MAPS
+  int GetNextUniqueSharedFunctionInfoId() { return next_unique_sfi_id_++; }
+#endif
 
  private:
-  Isolate();
+  explicit Isolate(bool enable_serializer);
 
   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.
   void* embedder_data_[Internals::kNumIsolateDataSlots];
   Heap heap_;
-  State state_;  // Will be padded to kApiPointerSize.
 
   // The per-process lock should be acquired before the ThreadDataTable is
   // modified.
@@ -1178,6 +1181,10 @@
   // A global counter for all generated Isolates, might overflow.
   static base::Atomic32 isolate_counter_;
 
+#if DEBUG
+  static base::Atomic32 isolate_key_created_;
+#endif
+
   void Deinit();
 
   static void SetIsolateThreadLocals(Isolate* isolate,
@@ -1227,7 +1234,6 @@
   Counters* counters_;
   CodeRange* code_range_;
   base::RecursiveMutex break_access_;
-  base::Atomic32 debugger_initialized_;
   Logger* logger_;
   StackGuard stack_guard_;
   StatsTable* stats_table_;
@@ -1248,7 +1254,6 @@
   UnicodeCache* unicode_cache_;
   Zone runtime_zone_;
   InnerPointerToCodeCache* inner_pointer_to_code_cache_;
-  ConsStringIteratorOp* write_iterator_;
   GlobalHandles* global_handles_;
   EternalHandles* eternal_handles_;
   ThreadManager* thread_manager_;
@@ -1258,9 +1263,6 @@
   StringTracker* string_tracker_;
   unibrow::Mapping<unibrow::Ecma262UnCanonicalize> jsregexp_uncanonicalize_;
   unibrow::Mapping<unibrow::CanonicalizationRange> jsregexp_canonrange_;
-  ConsStringIteratorOp objects_string_compare_iterator_a_;
-  ConsStringIteratorOp objects_string_compare_iterator_b_;
-  StaticResource<ConsStringIteratorOp> objects_string_iterator_;
   unibrow::Mapping<unibrow::Ecma262Canonicalize>
       regexp_macro_assembler_canonicalize_;
   RegExpStack* regexp_stack_;
@@ -1292,6 +1294,9 @@
   HeapProfiler* heap_profiler_;
   FunctionEntryHook function_entry_hook_;
 
+  typedef std::pair<InterruptCallback, void*> InterruptEntry;
+  std::queue<InterruptEntry> api_interrupts_queue_;
+
 #define GLOBAL_BACKING_STORE(type, name, initialvalue)                         \
   type name##_;
   ISOLATE_INIT_LIST(GLOBAL_BACKING_STORE)
@@ -1315,18 +1320,21 @@
 
   DeferredHandles* deferred_handles_head_;
   OptimizingCompilerThread* optimizing_compiler_thread_;
-  SweeperThread** sweeper_thread_;
-  int num_sweeper_threads_;
 
   // Counts deopt points if deopt_every_n_times is enabled.
   unsigned int stress_deopt_count_;
 
   int next_optimization_id_;
 
+#if TRACE_MAPS
+  int next_unique_sfi_id_;
+#endif
+
   // List of callbacks when a Call completes.
   List<CallCompletedCallback> call_completed_callbacks_;
 
   v8::Isolate::UseCounterCallback use_counter_callback_;
+  BasicBlockProfiler* basic_block_profiler_;
 
   friend class ExecutionAccess;
   friend class HandleScopeImplementer;
diff --git a/src/json-parser.h b/src/json-parser.h
index 2993249..5ebbcdd 100644
--- a/src/json-parser.h
+++ b/src/json-parser.h
@@ -400,7 +400,8 @@
                            descriptor)->NowContains(value)) {
               Handle<HeapType> value_type(value->OptimalType(
                       isolate(), expected_representation));
-              Map::GeneralizeFieldType(target, descriptor, value_type);
+              Map::GeneralizeFieldType(target, descriptor,
+                                       expected_representation, value_type);
             }
             DCHECK(target->instance_descriptors()->GetFieldType(
                     descriptor)->NowContains(value));
diff --git a/src/json-stringifier.h b/src/json-stringifier.h
index f89a19f..393551d 100644
--- a/src/json-stringifier.h
+++ b/src/json-stringifier.h
@@ -8,6 +8,7 @@
 #include "src/v8.h"
 
 #include "src/conversions.h"
+#include "src/string-builder.h"
 #include "src/utils.h"
 
 namespace v8 {
@@ -24,42 +25,8 @@
       Handle<String> object));
 
  private:
-  static const int kInitialPartLength = 32;
-  static const int kMaxPartLength = 16 * 1024;
-  static const int kPartLengthGrowthFactor = 2;
-
   enum Result { UNCHANGED, SUCCESS, EXCEPTION };
 
-  void Accumulate();
-
-  void Extend();
-
-  void ChangeEncoding();
-
-  INLINE(void ShrinkCurrentPart());
-
-  template <bool is_one_byte, typename Char>
-  INLINE(void Append_(Char c));
-
-  template <bool is_one_byte, typename Char>
-  INLINE(void Append_(const Char* chars));
-
-  INLINE(void Append(uint8_t c)) {
-    if (is_one_byte_) {
-      Append_<true>(c);
-    } else {
-      Append_<false>(c);
-    }
-  }
-
-  INLINE(void AppendOneByte(const char* chars)) {
-    if (is_one_byte_) {
-      Append_<true>(reinterpret_cast<const uint8_t*>(chars));
-    } else {
-      Append_<false>(reinterpret_cast<const uint8_t*>(chars));
-    }
-  }
-
   MUST_USE_RESULT MaybeHandle<Object> ApplyToJsonFunction(
       Handle<Object> object,
       Handle<Object> key);
@@ -69,14 +36,9 @@
                           bool deferred_comma,
                           bool deferred_key);
 
-  template <typename ResultType, typename Char>
-  INLINE(static Handle<String> StringifyString_(Isolate* isolate,
-                                                Vector<Char> vector,
-                                                Handle<String> result));
-
   // Entry point to serialize the object.
   INLINE(Result SerializeObject(Handle<Object> obj)) {
-    return Serialize_<false>(obj, false, factory_->empty_string());
+    return Serialize_<false>(obj, false, factory()->empty_string());
   }
 
   // Serialize an array element.
@@ -103,9 +65,9 @@
   Result Serialize_(Handle<Object> object, bool comma, Handle<Object> key);
 
   void SerializeDeferredKey(bool deferred_comma, Handle<Object> deferred_key) {
-    if (deferred_comma) Append(',');
+    if (deferred_comma) builder_.AppendCharacter(',');
     SerializeString(Handle<String>::cast(deferred_key));
-    Append(':');
+    builder_.AppendCharacter(':');
   }
 
   Result SerializeSmi(Smi* object);
@@ -125,42 +87,25 @@
   void SerializeString(Handle<String> object);
 
   template <typename SrcChar, typename DestChar>
-  INLINE(static int SerializeStringUnchecked_(const SrcChar* src,
-                                              DestChar* dest,
-                                              int length));
+  INLINE(static void SerializeStringUnchecked_(
+      Vector<const SrcChar> src,
+      IncrementalStringBuilder::NoExtend<DestChar>* dest));
 
-  template <bool is_one_byte, typename Char>
+  template <typename SrcChar, typename DestChar>
   INLINE(void SerializeString_(Handle<String> string));
 
   template <typename Char>
   INLINE(static bool DoNotEscape(Char c));
 
-  template <typename Char>
-  INLINE(static Vector<const Char> GetCharVector(Handle<String> string));
-
   Result StackPush(Handle<Object> object);
   void StackPop();
 
-  INLINE(Handle<String> accumulator()) {
-    return Handle<String>(String::cast(accumulator_store_->value()), isolate_);
-  }
-
-  INLINE(void set_accumulator(Handle<String> string)) {
-    return accumulator_store_->set_value(*string);
-  }
+  Factory* factory() { return isolate_->factory(); }
 
   Isolate* isolate_;
-  Factory* factory_;
-  // We use a value wrapper for the string accumulator to keep the
-  // (indirect) handle to it in the outermost handle scope.
-  Handle<JSValue> accumulator_store_;
-  Handle<String> current_part_;
+  IncrementalStringBuilder builder_;
   Handle<String> tojson_string_;
   Handle<JSArray> stack_;
-  int current_index_;
-  int part_length_;
-  bool is_one_byte_;
-  bool overflowed_;
 
   static const int kJsonEscapeTableEntrySize = 8;
   static const char* const JsonEscapeTable;
@@ -237,31 +182,16 @@
 
 
 BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
-    : isolate_(isolate),
-      current_index_(0),
-      is_one_byte_(true),
-      overflowed_(false) {
-  factory_ = isolate_->factory();
-  accumulator_store_ = Handle<JSValue>::cast(
-      Object::ToObject(isolate, factory_->empty_string()).ToHandleChecked());
-  part_length_ = kInitialPartLength;
-  current_part_ = factory_->NewRawOneByteString(part_length_).ToHandleChecked();
-  tojson_string_ = factory_->toJSON_string();
-  stack_ = factory_->NewJSArray(8);
+    : isolate_(isolate), builder_(isolate) {
+  tojson_string_ = factory()->toJSON_string();
+  stack_ = factory()->NewJSArray(8);
 }
 
 
 MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object) {
   Result result = SerializeObject(object);
-  if (result == UNCHANGED) return isolate_->factory()->undefined_value();
-  if (result == SUCCESS) {
-    ShrinkCurrentPart();
-    Accumulate();
-    if (overflowed_) {
-      THROW_NEW_ERROR(isolate_, NewInvalidStringLengthError(), Object);
-    }
-    return accumulator();
-  }
+  if (result == UNCHANGED) return factory()->undefined_value();
+  if (result == SUCCESS) return builder_.Finish();
   DCHECK(result == EXCEPTION);
   return MaybeHandle<Object>();
 }
@@ -281,58 +211,29 @@
 
   object = String::Flatten(object);
   DCHECK(object->IsFlat());
+  Handle<SeqString> result;
   if (object->IsOneByteRepresentationUnderneath()) {
-    Handle<String> result = isolate->factory()->NewRawOneByteString(
-        worst_case_length).ToHandleChecked();
-    DisallowHeapAllocation no_gc;
-    return StringifyString_<SeqOneByteString>(
-        isolate,
-        object->GetFlatContent().ToOneByteVector(),
-        result);
+    result = isolate->factory()
+                 ->NewRawOneByteString(worst_case_length)
+                 .ToHandleChecked();
+    IncrementalStringBuilder::NoExtendString<uint8_t> no_extend(
+        result, worst_case_length);
+    no_extend.Append('\"');
+    SerializeStringUnchecked_(object->GetFlatContent().ToOneByteVector(),
+                              &no_extend);
+    no_extend.Append('\"');
   } else {
-    Handle<String> result = isolate->factory()->NewRawTwoByteString(
-        worst_case_length).ToHandleChecked();
-    DisallowHeapAllocation no_gc;
-    return StringifyString_<SeqTwoByteString>(
-        isolate,
-        object->GetFlatContent().ToUC16Vector(),
-        result);
+    result = isolate->factory()
+                 ->NewRawTwoByteString(worst_case_length)
+                 .ToHandleChecked();
+    IncrementalStringBuilder::NoExtendString<uc16> no_extend(result,
+                                                             worst_case_length);
+    no_extend.Append('\"');
+    SerializeStringUnchecked_(object->GetFlatContent().ToUC16Vector(),
+                              &no_extend);
+    no_extend.Append('\"');
   }
-}
-
-
-template <typename ResultType, typename Char>
-Handle<String> BasicJsonStringifier::StringifyString_(Isolate* isolate,
-                                                      Vector<Char> vector,
-                                                      Handle<String> result) {
-  DisallowHeapAllocation no_gc;
-  int final_size = 0;
-  ResultType* dest = ResultType::cast(*result);
-  dest->Set(final_size++, '\"');
-  final_size += SerializeStringUnchecked_(vector.start(),
-                                          dest->GetChars() + 1,
-                                          vector.length());
-  dest->Set(final_size++, '\"');
-  return SeqString::Truncate(Handle<SeqString>::cast(result), final_size);
-}
-
-
-template <bool is_one_byte, typename Char>
-void BasicJsonStringifier::Append_(Char c) {
-  if (is_one_byte) {
-    SeqOneByteString::cast(*current_part_)->SeqOneByteStringSet(
-        current_index_++, c);
-  } else {
-    SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet(
-        current_index_++, c);
-  }
-  if (current_index_ == part_length_) Extend();
-}
-
-
-template <bool is_one_byte, typename Char>
-void BasicJsonStringifier::Append_(const Char* chars) {
-  for (; *chars != '\0'; chars++) Append_<is_one_byte, Char>(*chars);
+  return result;
 }
 
 
@@ -345,7 +246,7 @@
   if (!fun->IsJSFunction()) return object;
 
   // Call toJSON function.
-  if (key->IsSmi()) key = factory_->NumberToString(key);
+  if (key->IsSmi()) key = factory()->NumberToString(key);
   Handle<Object> argv[] = { key };
   HandleScope scope(isolate_);
   ASSIGN_RETURN_ON_EXCEPTION(
@@ -372,7 +273,7 @@
       if (elements->get(i) == *object) {
         AllowHeapAllocation allow_to_return_error;
         Handle<Object> error;
-        MaybeHandle<Object> maybe_error = factory_->NewTypeError(
+        MaybeHandle<Object> maybe_error = factory()->NewTypeError(
             "circular_structure", HandleVector<Object>(NULL, 0));
         if (maybe_error.ToHandle(&error)) isolate_->Throw(*error);
         return EXCEPTION;
@@ -416,15 +317,15 @@
       switch (Oddball::cast(*object)->kind()) {
         case Oddball::kFalse:
           if (deferred_string_key) SerializeDeferredKey(comma, key);
-          AppendOneByte("false");
+          builder_.AppendCString("false");
           return SUCCESS;
         case Oddball::kTrue:
           if (deferred_string_key) SerializeDeferredKey(comma, key);
-          AppendOneByte("true");
+          builder_.AppendCString("true");
           return SUCCESS;
         case Oddball::kNull:
           if (deferred_string_key) SerializeDeferredKey(comma, key);
-          AppendOneByte("null");
+          builder_.AppendCString("null");
           return SUCCESS;
         default:
           return UNCHANGED;
@@ -472,23 +373,11 @@
       EXCEPTION);
   if (result->IsUndefined()) return UNCHANGED;
   if (deferred_key) {
-    if (key->IsSmi()) key = factory_->NumberToString(key);
+    if (key->IsSmi()) key = factory()->NumberToString(key);
     SerializeDeferredKey(deferred_comma, key);
   }
 
-  Handle<String> result_string = Handle<String>::cast(result);
-  // Shrink current part, attach it to the accumulator, also attach the result
-  // string to the accumulator, and allocate a new part.
-  ShrinkCurrentPart();  // Shrink.
-  part_length_ = kInitialPartLength;  // Allocate conservatively.
-  Extend();             // Attach current part and allocate new part.
-  // Attach result string to the accumulator.
-  Handle<String> cons;
-  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
-      isolate_, cons,
-      factory_->NewConsString(accumulator(), result_string),
-      EXCEPTION);
-  set_accumulator(cons);
+  builder_.AppendString(Handle<String>::cast(result));
   return SUCCESS;
 }
 
@@ -511,7 +400,7 @@
     DCHECK(class_name == isolate_->heap()->Boolean_string());
     Object* value = JSValue::cast(*object)->value();
     DCHECK(value->IsBoolean());
-    AppendOneByte(value->IsTrue() ? "true" : "false");
+    builder_.AppendCString(value->IsTrue() ? "true" : "false");
   }
   return SUCCESS;
 }
@@ -521,7 +410,7 @@
   static const int kBufferSize = 100;
   char chars[kBufferSize];
   Vector<char> buffer(chars, kBufferSize);
-  AppendOneByte(IntToCString(object->value(), buffer));
+  builder_.AppendCString(IntToCString(object->value(), buffer));
   return SUCCESS;
 }
 
@@ -529,13 +418,13 @@
 BasicJsonStringifier::Result BasicJsonStringifier::SerializeDouble(
     double number) {
   if (std::isinf(number) || std::isnan(number)) {
-    AppendOneByte("null");
+    builder_.AppendCString("null");
     return SUCCESS;
   }
   static const int kBufferSize = 100;
   char chars[kBufferSize];
   Vector<char> buffer(chars, kBufferSize);
-  AppendOneByte(DoubleToCString(number, buffer));
+  builder_.AppendCString(DoubleToCString(number, buffer));
   return SUCCESS;
 }
 
@@ -547,13 +436,13 @@
   if (stack_push != SUCCESS) return stack_push;
   uint32_t length = 0;
   CHECK(object->length()->ToArrayIndex(&length));
-  Append('[');
+  builder_.AppendCharacter('[');
   switch (object->GetElementsKind()) {
     case FAST_SMI_ELEMENTS: {
       Handle<FixedArray> elements(
           FixedArray::cast(object->elements()), isolate_);
       for (uint32_t i = 0; i < length; i++) {
-        if (i > 0) Append(',');
+        if (i > 0) builder_.AppendCharacter(',');
         SerializeSmi(Smi::cast(elements->get(i)));
       }
       break;
@@ -564,7 +453,7 @@
       Handle<FixedDoubleArray> elements(
           FixedDoubleArray::cast(object->elements()), isolate_);
       for (uint32_t i = 0; i < length; i++) {
-        if (i > 0) Append(',');
+        if (i > 0) builder_.AppendCharacter(',');
         SerializeDouble(elements->get_scalar(i));
       }
       break;
@@ -573,14 +462,14 @@
       Handle<FixedArray> elements(
           FixedArray::cast(object->elements()), isolate_);
       for (uint32_t i = 0; i < length; i++) {
-        if (i > 0) Append(',');
+        if (i > 0) builder_.AppendCharacter(',');
         Result result =
             SerializeElement(isolate_,
                              Handle<Object>(elements->get(i), isolate_),
                              i);
         if (result == SUCCESS) continue;
         if (result == UNCHANGED) {
-          AppendOneByte("null");
+          builder_.AppendCString("null");
         } else {
           return result;
         }
@@ -596,9 +485,8 @@
       break;
     }
   }
-  Append(']');
+  builder_.AppendCharacter(']');
   StackPop();
-  current_part_ = handle_scope.CloseAndEscape(current_part_);
   return SUCCESS;
 }
 
@@ -606,19 +494,19 @@
 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSArraySlow(
     Handle<JSArray> object, uint32_t length) {
   for (uint32_t i = 0; i < length; i++) {
-    if (i > 0) Append(',');
+    if (i > 0) builder_.AppendCharacter(',');
     Handle<Object> element;
     ASSIGN_RETURN_ON_EXCEPTION_VALUE(
         isolate_, element,
         Object::GetElement(isolate_, object, i),
         EXCEPTION);
     if (element->IsUndefined()) {
-      AppendOneByte("null");
+      builder_.AppendCString("null");
     } else {
       Result result = SerializeElement(isolate_, element, i);
       if (result == SUCCESS) continue;
       if (result == UNCHANGED) {
-        AppendOneByte("null");
+        builder_.AppendCString("null");
       } else {
         return result;
       }
@@ -635,7 +523,7 @@
   if (stack_push != SUCCESS) return stack_push;
   DCHECK(!object->IsJSGlobalProxy() && !object->IsGlobalObject());
 
-  Append('{');
+  builder_.AppendCharacter('{');
   bool comma = false;
 
   if (object->HasFastProperties() &&
@@ -652,8 +540,15 @@
       if (details.IsDontEnum()) continue;
       Handle<Object> property;
       if (details.type() == FIELD && *map == object->map()) {
-        property = Handle<Object>(object->RawFastPropertyAt(
-            FieldIndex::ForDescriptor(*map, i)), isolate_);
+        FieldIndex field_index = FieldIndex::ForDescriptor(*map, i);
+        Isolate* isolate = object->GetIsolate();
+        if (object->IsUnboxedDoubleField(field_index)) {
+          double value = object->RawFastDoublePropertyAt(field_index);
+          property = isolate->factory()->NewHeapNumber(value);
+
+        } else {
+          property = handle(object->RawFastPropertyAt(field_index), isolate);
+        }
       } else {
         ASSIGN_RETURN_ON_EXCEPTION_VALUE(
             isolate_, property,
@@ -680,7 +575,7 @@
         maybe_property = Object::GetPropertyOrElement(object, key_handle);
       } else {
         DCHECK(key->IsNumber());
-        key_handle = factory_->NumberToString(Handle<Object>(key, isolate_));
+        key_handle = factory()->NumberToString(Handle<Object>(key, isolate_));
         uint32_t index;
         if (key->IsSmi()) {
           maybe_property = Object::GetElement(
@@ -700,130 +595,59 @@
     }
   }
 
-  Append('}');
+  builder_.AppendCharacter('}');
   StackPop();
-  current_part_ = handle_scope.CloseAndEscape(current_part_);
   return SUCCESS;
 }
 
 
-void BasicJsonStringifier::ShrinkCurrentPart() {
-  DCHECK(current_index_ < part_length_);
-  current_part_ = SeqString::Truncate(Handle<SeqString>::cast(current_part_),
-                                      current_index_);
-}
+template <typename SrcChar, typename DestChar>
+void BasicJsonStringifier::SerializeStringUnchecked_(
+    Vector<const SrcChar> src,
+    IncrementalStringBuilder::NoExtend<DestChar>* dest) {
+  // Assert that uc16 character is not truncated down to 8 bit.
+  // The <uc16, char> version of this method must not be called.
+  DCHECK(sizeof(DestChar) >= sizeof(SrcChar));
 
-
-void BasicJsonStringifier::Accumulate() {
-  if (accumulator()->length() + current_part_->length() > String::kMaxLength) {
-    // Screw it.  Simply set the flag and carry on.  Throw exception at the end.
-    set_accumulator(factory_->empty_string());
-    overflowed_ = true;
-  } else {
-    set_accumulator(factory_->NewConsString(accumulator(),
-                                            current_part_).ToHandleChecked());
+  for (int i = 0; i < src.length(); i++) {
+    SrcChar c = src[i];
+    if (DoNotEscape(c)) {
+      dest->Append(c);
+    } else {
+      dest->AppendCString(&JsonEscapeTable[c * kJsonEscapeTableEntrySize]);
+    }
   }
 }
 
 
-void BasicJsonStringifier::Extend() {
-  Accumulate();
-  if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) {
-    part_length_ *= kPartLengthGrowthFactor;
-  }
-  if (is_one_byte_) {
-    current_part_ =
-        factory_->NewRawOneByteString(part_length_).ToHandleChecked();
-  } else {
-    current_part_ =
-        factory_->NewRawTwoByteString(part_length_).ToHandleChecked();
-  }
-  DCHECK(!current_part_.is_null());
-  current_index_ = 0;
-}
-
-
-void BasicJsonStringifier::ChangeEncoding() {
-  ShrinkCurrentPart();
-  Accumulate();
-  current_part_ =
-      factory_->NewRawTwoByteString(part_length_).ToHandleChecked();
-  DCHECK(!current_part_.is_null());
-  current_index_ = 0;
-  is_one_byte_ = false;
-}
-
-
 template <typename SrcChar, typename DestChar>
-int BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
-                                                    DestChar* dest,
-                                                    int length) {
-  DestChar* dest_start = dest;
-
-  // Assert that uc16 character is not truncated down to 8 bit.
-  // The <uc16, char> version of this method must not be called.
-  DCHECK(sizeof(*dest) >= sizeof(*src));
-
-  for (int i = 0; i < length; i++) {
-    SrcChar c = src[i];
-    if (DoNotEscape(c)) {
-      *(dest++) = static_cast<DestChar>(c);
-    } else {
-      const uint8_t* chars = reinterpret_cast<const uint8_t*>(
-          &JsonEscapeTable[c * kJsonEscapeTableEntrySize]);
-      while (*chars != '\0') *(dest++) = *(chars++);
-    }
-  }
-
-  return static_cast<int>(dest - dest_start);
-}
-
-
-template <bool is_one_byte, typename Char>
 void BasicJsonStringifier::SerializeString_(Handle<String> string) {
   int length = string->length();
-  Append_<is_one_byte, char>('"');
+  builder_.Append<uint8_t, DestChar>('"');
   // We make a rough estimate to find out if the current string can be
   // serialized without allocating a new string part. The worst case length of
   // an escaped character is 6.  Shifting the remainin string length right by 3
   // is a more pessimistic estimate, but faster to calculate.
-
-  if (((part_length_ - current_index_) >> 3) > length) {
+  int worst_case_length = length << 3;
+  if (builder_.CurrentPartCanFit(worst_case_length)) {
     DisallowHeapAllocation no_gc;
-    Vector<const Char> vector = GetCharVector<Char>(string);
-    if (is_one_byte) {
-      current_index_ += SerializeStringUnchecked_(
-          vector.start(),
-          SeqOneByteString::cast(*current_part_)->GetChars() + current_index_,
-          length);
-    } else {
-      current_index_ += SerializeStringUnchecked_(
-          vector.start(),
-          SeqTwoByteString::cast(*current_part_)->GetChars() + current_index_,
-          length);
-    }
+    Vector<const SrcChar> vector = string->GetCharVector<SrcChar>();
+    IncrementalStringBuilder::NoExtendBuilder<DestChar> no_extend(
+        &builder_, worst_case_length);
+    SerializeStringUnchecked_(vector, &no_extend);
   } else {
-    String* string_location = NULL;
-    Vector<const Char> vector(NULL, 0);
-    for (int i = 0; i < length; i++) {
-      // If GC moved the string, we need to refresh the vector.
-      if (*string != string_location) {
-        DisallowHeapAllocation no_gc;
-        // This does not actually prevent the string from being relocated later.
-        vector = GetCharVector<Char>(string);
-        string_location = *string;
-      }
-      Char c = vector[i];
+    FlatStringReader reader(isolate_, string);
+    for (int i = 0; i < reader.length(); i++) {
+      SrcChar c = reader.Get<SrcChar>(i);
       if (DoNotEscape(c)) {
-        Append_<is_one_byte, Char>(c);
+        builder_.Append<SrcChar, DestChar>(c);
       } else {
-        Append_<is_one_byte, uint8_t>(reinterpret_cast<const uint8_t*>(
-            &JsonEscapeTable[c * kJsonEscapeTableEntrySize]));
+        builder_.AppendCString(&JsonEscapeTable[c * kJsonEscapeTableEntrySize]);
       }
     }
   }
 
-  Append_<is_one_byte, uint8_t>('"');
+  builder_.Append<uint8_t, DestChar>('"');
 }
 
 
@@ -839,37 +663,20 @@
 }
 
 
-template <>
-Vector<const uint8_t> BasicJsonStringifier::GetCharVector(
-    Handle<String> string) {
-  String::FlatContent flat = string->GetFlatContent();
-  DCHECK(flat.IsOneByte());
-  return flat.ToOneByteVector();
-}
-
-
-template <>
-Vector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) {
-  String::FlatContent flat = string->GetFlatContent();
-  DCHECK(flat.IsTwoByte());
-  return flat.ToUC16Vector();
-}
-
-
 void BasicJsonStringifier::SerializeString(Handle<String> object) {
   object = String::Flatten(object);
-  if (is_one_byte_) {
+  if (builder_.CurrentEncoding() == String::ONE_BYTE_ENCODING) {
     if (object->IsOneByteRepresentationUnderneath()) {
-      SerializeString_<true, uint8_t>(object);
+      SerializeString_<uint8_t, uint8_t>(object);
     } else {
-      ChangeEncoding();
+      builder_.ChangeEncoding();
       SerializeString(object);
     }
   } else {
     if (object->IsOneByteRepresentationUnderneath()) {
-      SerializeString_<false, uint8_t>(object);
+      SerializeString_<uint8_t, uc16>(object);
     } else {
-      SerializeString_<false, uc16>(object);
+      SerializeString_<uc16, uc16>(object);
     }
   }
 }
diff --git a/src/json.js b/src/json.js
index f767f4a..e2b7dc8 100644
--- a/src/json.js
+++ b/src/json.js
@@ -220,6 +220,8 @@
 function SetUpJSON() {
   %CheckIsBootstrapping();
 
+  %AddNamedProperty($JSON, symbolToStringTag, "JSON", READ_ONLY | DONT_ENUM);
+
   // Set up non-enumerable properties of the JSON object.
   InstallFunctions($JSON, DONT_ENUM, $Array(
     "parse", JSONParse,
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 98aca72..81ad080 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -18,8 +18,9 @@
 #include "src/regexp-macro-assembler-irregexp.h"
 #include "src/regexp-macro-assembler-tracer.h"
 #include "src/regexp-stack.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 #include "src/string-search.h"
+#include "src/unicode-decoder.h"
 
 #ifndef V8_INTERPRETED_REGEXP
 #if V8_TARGET_ARCH_IA32
@@ -57,28 +58,6 @@
 }
 
 
-static JSRegExp::Flags RegExpFlagsFromString(Handle<String> str) {
-  int flags = JSRegExp::NONE;
-  for (int i = 0; i < str->length(); i++) {
-    switch (str->Get(i)) {
-      case 'i':
-        flags |= JSRegExp::IGNORE_CASE;
-        break;
-      case 'g':
-        flags |= JSRegExp::GLOBAL;
-        break;
-      case 'm':
-        flags |= JSRegExp::MULTILINE;
-        break;
-      case 'y':
-        if (FLAG_harmony_regexps) flags |= JSRegExp::STICKY;
-        break;
-    }
-  }
-  return JSRegExp::Flags(flags);
-}
-
-
 MUST_USE_RESULT
 static inline MaybeHandle<Object> ThrowRegExpException(
     Handle<JSRegExp> re,
@@ -155,10 +134,9 @@
 
 MaybeHandle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
                                         Handle<String> pattern,
-                                        Handle<String> flag_str) {
+                                        JSRegExp::Flags flags) {
   Isolate* isolate = re->GetIsolate();
   Zone zone(isolate);
-  JSRegExp::Flags flags = RegExpFlagsFromString(flag_str);
   CompilationCache* compilation_cache = isolate->compilation_cache();
   MaybeHandle<FixedArray> maybe_cached =
       compilation_cache->LookupRegExp(pattern, flags);
@@ -1026,6 +1004,8 @@
 
   inline bool ignore_case() { return ignore_case_; }
   inline bool one_byte() { return one_byte_; }
+  inline bool optimize() { return optimize_; }
+  inline void set_optimize(bool value) { optimize_ = value; }
   FrequencyCollator* frequency_collator() { return &frequency_collator_; }
 
   int current_expansion_factor() { return current_expansion_factor_; }
@@ -1046,6 +1026,7 @@
   bool ignore_case_;
   bool one_byte_;
   bool reg_exp_too_big_;
+  bool optimize_;
   int current_expansion_factor_;
   FrequencyCollator frequency_collator_;
   Zone* zone_;
@@ -1078,6 +1059,7 @@
       ignore_case_(ignore_case),
       one_byte_(one_byte),
       reg_exp_too_big_(false),
+      optimize_(FLAG_regexp_optimization),
       current_expansion_factor_(1),
       frequency_collator_(),
       zone_(zone) {
@@ -1093,16 +1075,6 @@
     Handle<String> pattern) {
   Heap* heap = pattern->GetHeap();
 
-  bool use_slow_safe_regexp_compiler = false;
-  if (heap->total_regexp_code_generated() >
-          RegExpImpl::kRegWxpCompiledLimit &&
-      heap->isolate()->memory_allocator()->SizeExecutable() >
-          RegExpImpl::kRegExpExecutableMemoryLimit) {
-    use_slow_safe_regexp_compiler = true;
-  }
-
-  macro_assembler->set_slow_safe(use_slow_safe_regexp_compiler);
-
 #ifdef DEBUG
   if (FLAG_trace_regexp_assembler)
     macro_assembler_ = new RegExpMacroAssemblerTracer(macro_assembler);
@@ -1126,12 +1098,14 @@
   Handle<HeapObject> code = macro_assembler_->GetCode(pattern);
   heap->IncreaseTotalRegexpCodeGenerated(code->Size());
   work_list_ = NULL;
-#ifdef DEBUG
+#ifdef ENABLE_DISASSEMBLER
   if (FLAG_print_code) {
     CodeTracer::Scope trace_scope(heap->isolate()->GetCodeTracer());
     OFStream os(trace_scope.file());
     Handle<Code>::cast(code)->Disassemble(pattern->ToCString().get(), os);
   }
+#endif
+#ifdef DEBUG
   if (FLAG_trace_regexp_assembler) {
     delete macro_assembler_;
   }
@@ -2256,8 +2230,7 @@
   // We are being asked to make a non-generic version.  Keep track of how many
   // non-generic versions we generate so as not to overdo it.
   trace_count_++;
-  if (FLAG_regexp_optimization &&
-      trace_count_ < kMaxCopiesCodeGenerated &&
+  if (compiler->optimize() && trace_count_ < kMaxCopiesCodeGenerated &&
       compiler->recursion_depth() <= RegExpCompiler::kMaxRecursion) {
     return CONTINUE;
   }
@@ -4136,15 +4109,12 @@
     }
     alt_gen->expects_preload = preload->preload_is_current_;
     bool generate_full_check_inline = false;
-    if (FLAG_regexp_optimization &&
+    if (compiler->optimize() &&
         try_to_emit_quick_check_for_alternative(i == 0) &&
-        alternative.node()->EmitQuickCheck(compiler,
-                                           trace,
-                                           &new_trace,
-                                           preload->preload_has_checked_bounds_,
-                                           &alt_gen->possible_success,
-                                           &alt_gen->quick_check_details,
-                                           fall_through_on_failure)) {
+        alternative.node()->EmitQuickCheck(
+            compiler, trace, &new_trace, preload->preload_has_checked_bounds_,
+            &alt_gen->possible_success, &alt_gen->quick_check_details,
+            fall_through_on_failure)) {
       // Quick check was generated for this choice.
       preload->preload_is_current_ = true;
       preload->preload_has_checked_bounds_ = true;
@@ -4386,7 +4356,7 @@
 
 class DotPrinter: public NodeVisitor {
  public:
-  DotPrinter(OStream& os, bool ignore_case)  // NOLINT
+  DotPrinter(std::ostream& os, bool ignore_case)  // NOLINT
       : os_(os),
         ignore_case_(ignore_case) {}
   void PrintNode(const char* label, RegExpNode* node);
@@ -4398,7 +4368,7 @@
 FOR_EACH_NODE_TYPE(DECLARE_VISIT)
 #undef DECLARE_VISIT
  private:
-  OStream& os_;
+  std::ostream& os_;
   bool ignore_case_;
 };
 
@@ -4420,7 +4390,7 @@
   }
   os_ << "\"];\n";
   Visit(node);
-  os_ << "}" << endl;
+  os_ << "}" << std::endl;
 }
 
 
@@ -4439,7 +4409,7 @@
 
 class TableEntryBodyPrinter {
  public:
-  TableEntryBodyPrinter(OStream& os, ChoiceNode* choice)  // NOLINT
+  TableEntryBodyPrinter(std::ostream& os, ChoiceNode* choice)  // NOLINT
       : os_(os),
         choice_(choice) {}
   void Call(uc16 from, DispatchTable::Entry entry) {
@@ -4453,14 +4423,14 @@
   }
  private:
   ChoiceNode* choice() { return choice_; }
-  OStream& os_;
+  std::ostream& os_;
   ChoiceNode* choice_;
 };
 
 
 class TableEntryHeaderPrinter {
  public:
-  explicit TableEntryHeaderPrinter(OStream& os)  // NOLINT
+  explicit TableEntryHeaderPrinter(std::ostream& os)  // NOLINT
       : first_(true),
         os_(os) {}
   void Call(uc16 from, DispatchTable::Entry entry) {
@@ -4484,13 +4454,13 @@
 
  private:
   bool first_;
-  OStream& os_;
+  std::ostream& os_;
 };
 
 
 class AttributePrinter {
  public:
-  explicit AttributePrinter(OStream& os)  // NOLINT
+  explicit AttributePrinter(std::ostream& os)  // NOLINT
       : os_(os),
         first_(true) {}
   void PrintSeparator() {
@@ -4512,7 +4482,7 @@
   }
 
  private:
-  OStream& os_;
+  std::ostream& os_;
   bool first_;
 };
 
@@ -4681,10 +4651,10 @@
 
 class DispatchTableDumper {
  public:
-  explicit DispatchTableDumper(OStream& os) : os_(os) {}
+  explicit DispatchTableDumper(std::ostream& os) : os_(os) {}
   void Call(uc16 key, DispatchTable::Entry entry);
  private:
-  OStream& os_;
+  std::ostream& os_;
 };
 
 
@@ -4942,7 +4912,7 @@
 
   if (body_can_be_empty) {
     body_start_reg = compiler->AllocateRegister();
-  } else if (FLAG_regexp_optimization && !needs_capture_clearing) {
+  } else if (compiler->optimize() && !needs_capture_clearing) {
     // Only unroll if there are no captures and the body can't be
     // empty.
     {
@@ -6040,6 +6010,8 @@
   }
   RegExpCompiler compiler(data->capture_count, ignore_case, is_one_byte, zone);
 
+  compiler.set_optimize(!TooMuchRegExpCode(pattern));
+
   // Sample some characters from the middle of the string.
   static const int kSampleSize = 128;
 
@@ -6142,6 +6114,8 @@
   RegExpMacroAssemblerIrregexp macro_assembler(codes, zone);
 #endif  // V8_INTERPRETED_REGEXP
 
+  macro_assembler.set_slow_safe(TooMuchRegExpCode(pattern));
+
   // Inserted here, instead of in Assembler, because it depends on information
   // in the AST that isn't replicated in the Node structure.
   static const int kMaxBacksearchLimit = 1024;
@@ -6165,4 +6139,14 @@
 }
 
 
+bool RegExpEngine::TooMuchRegExpCode(Handle<String> pattern) {
+  Heap* heap = pattern->GetHeap();
+  bool too_much = pattern->length() > RegExpImpl::kRegExpTooLargeToOptimize;
+  if (heap->total_regexp_code_generated() > RegExpImpl::kRegExpCompiledLimit &&
+      heap->isolate()->memory_allocator()->SizeExecutable() >
+          RegExpImpl::kRegExpExecutableMemoryLimit) {
+    too_much = true;
+  }
+  return too_much;
+}
 }}  // namespace v8::internal
diff --git a/src/jsregexp.h b/src/jsregexp.h
index c65adea..4b84c95 100644
--- a/src/jsregexp.h
+++ b/src/jsregexp.h
@@ -46,10 +46,9 @@
   // generic data and choice of implementation - as well as what
   // the implementation wants to store in the data field.
   // Returns false if compilation fails.
-  MUST_USE_RESULT static MaybeHandle<Object> Compile(
-      Handle<JSRegExp> re,
-      Handle<String> pattern,
-      Handle<String> flags);
+  MUST_USE_RESULT static MaybeHandle<Object> Compile(Handle<JSRegExp> re,
+                                                     Handle<String> pattern,
+                                                     JSRegExp::Flags flags);
 
   // See ECMA-262 section 15.10.6.2.
   // This function calls the garbage collector if necessary.
@@ -213,7 +212,8 @@
   // total regexp code compiled including code that has subsequently been freed
   // and the total executable memory at any point.
   static const int kRegExpExecutableMemoryLimit = 16 * MB;
-  static const int kRegWxpCompiledLimit = 1 * MB;
+  static const int kRegExpCompiledLimit = 1 * MB;
+  static const int kRegExpTooLargeToOptimize = 10 * KB;
 
  private:
   static bool CompileIrregexp(Handle<JSRegExp> re,
@@ -1666,6 +1666,8 @@
                                    Handle<String> sample_subject,
                                    bool is_one_byte, Zone* zone);
 
+  static bool TooMuchRegExpCode(Handle<String> pattern);
+
   static void DotPrint(const char* label, RegExpNode* node, bool ignore_case);
 };
 
diff --git a/src/layout-descriptor-inl.h b/src/layout-descriptor-inl.h
new file mode 100644
index 0000000..3352312
--- /dev/null
+++ b/src/layout-descriptor-inl.h
@@ -0,0 +1,191 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_LAYOUT_DESCRIPTOR_INL_H_
+#define V8_LAYOUT_DESCRIPTOR_INL_H_
+
+#include "src/layout-descriptor.h"
+
+namespace v8 {
+namespace internal {
+
+LayoutDescriptor* LayoutDescriptor::FromSmi(Smi* smi) {
+  return LayoutDescriptor::cast(smi);
+}
+
+
+Handle<LayoutDescriptor> LayoutDescriptor::New(Isolate* isolate, int length) {
+  if (length <= kSmiValueSize) {
+    // The whole bit vector fits into a smi.
+    return handle(LayoutDescriptor::FromSmi(Smi::FromInt(0)), isolate);
+  }
+
+  length = (length + kNumberOfBits - 1) / kNumberOfBits;
+  DCHECK(length > 0);
+
+  if (SmiValuesAre32Bits() && (length & 1)) {
+    // On 64-bit systems if the length is odd then the half-word space would be
+    // lost anyway (due to alignment and the fact that we are allocating
+    // uint32-typed array), so we increase the length of allocated array
+    // to utilize that "lost" space which could also help to avoid layout
+    // descriptor reallocations.
+    ++length;
+  }
+  return Handle<LayoutDescriptor>::cast(
+      isolate->factory()->NewFixedTypedArray(length, kExternalUint32Array));
+}
+
+
+bool LayoutDescriptor::InobjectUnboxedField(int inobject_properties,
+                                            PropertyDetails details) {
+  if (details.type() != FIELD || !details.representation().IsDouble()) {
+    return false;
+  }
+  // We care only about in-object properties.
+  return details.field_index() < inobject_properties;
+}
+
+
+LayoutDescriptor* LayoutDescriptor::FastPointerLayout() {
+  return LayoutDescriptor::FromSmi(Smi::FromInt(0));
+}
+
+
+bool LayoutDescriptor::GetIndexes(int field_index, int* layout_word_index,
+                                  int* layout_bit_index) {
+  if (static_cast<unsigned>(field_index) >= static_cast<unsigned>(capacity())) {
+    return false;
+  }
+
+  *layout_word_index = field_index / kNumberOfBits;
+  CHECK((!IsSmi() && (*layout_word_index < length())) ||
+        (IsSmi() && (*layout_word_index < 1)));
+
+  *layout_bit_index = field_index % kNumberOfBits;
+  return true;
+}
+
+
+LayoutDescriptor* LayoutDescriptor::SetTagged(int field_index, bool tagged) {
+  int layout_word_index;
+  int layout_bit_index;
+
+  if (!GetIndexes(field_index, &layout_word_index, &layout_bit_index)) {
+    CHECK(false);
+    return this;
+  }
+  uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;
+
+  if (IsSlowLayout()) {
+    uint32_t value = get_scalar(layout_word_index);
+    if (tagged) {
+      value &= ~layout_mask;
+    } else {
+      value |= layout_mask;
+    }
+    set(layout_word_index, value);
+    return this;
+  } else {
+    uint32_t value = static_cast<uint32_t>(Smi::cast(this)->value());
+    if (tagged) {
+      value &= ~layout_mask;
+    } else {
+      value |= layout_mask;
+    }
+    return LayoutDescriptor::FromSmi(Smi::FromInt(static_cast<int>(value)));
+  }
+}
+
+
+bool LayoutDescriptor::IsTagged(int field_index) {
+  if (IsFastPointerLayout()) return true;
+
+  int layout_word_index;
+  int layout_bit_index;
+
+  if (!GetIndexes(field_index, &layout_word_index, &layout_bit_index)) {
+    // All bits after Out of bounds queries
+    return true;
+  }
+  uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;
+
+  if (IsSlowLayout()) {
+    uint32_t value = get_scalar(layout_word_index);
+    return (value & layout_mask) == 0;
+  } else {
+    uint32_t value = static_cast<uint32_t>(Smi::cast(this)->value());
+    return (value & layout_mask) == 0;
+  }
+}
+
+
+bool LayoutDescriptor::IsFastPointerLayout() {
+  return this == FastPointerLayout();
+}
+
+
+bool LayoutDescriptor::IsFastPointerLayout(Object* layout_descriptor) {
+  return layout_descriptor == FastPointerLayout();
+}
+
+
+bool LayoutDescriptor::IsSlowLayout() { return !IsSmi(); }
+
+
+int LayoutDescriptor::capacity() {
+  return IsSlowLayout() ? (length() * kNumberOfBits) : kSmiValueSize;
+}
+
+
+LayoutDescriptor* LayoutDescriptor::cast_gc_safe(Object* object) {
+  if (object->IsSmi()) {
+    // Fast mode layout descriptor.
+    return reinterpret_cast<LayoutDescriptor*>(object);
+  }
+
+  // This is a mixed descriptor which is a fixed typed array.
+  MapWord map_word = reinterpret_cast<HeapObject*>(object)->map_word();
+  if (map_word.IsForwardingAddress()) {
+    // Mark-compact has already moved layout descriptor.
+    object = map_word.ToForwardingAddress();
+  }
+  return LayoutDescriptor::cast(object);
+}
+
+
+// InobjectPropertiesHelper is a helper class for querying whether inobject
+// property at offset is Double or not.
+LayoutDescriptorHelper::LayoutDescriptorHelper(Map* map)
+    : all_fields_tagged_(true),
+      header_size_(0),
+      layout_descriptor_(LayoutDescriptor::FastPointerLayout()) {
+  if (!FLAG_unbox_double_fields) return;
+
+  layout_descriptor_ = map->layout_descriptor_gc_safe();
+  if (layout_descriptor_->IsFastPointerLayout()) {
+    return;
+  }
+
+  int inobject_properties = map->inobject_properties();
+  DCHECK(inobject_properties > 0);
+  header_size_ = map->instance_size() - (inobject_properties * kPointerSize);
+  DCHECK(header_size_ >= 0);
+
+  all_fields_tagged_ = false;
+}
+
+
+bool LayoutDescriptorHelper::IsTagged(int offset_in_bytes) {
+  DCHECK(IsAligned(offset_in_bytes, kPointerSize));
+  if (all_fields_tagged_) return true;
+  // Object headers do not contain non-tagged fields.
+  if (offset_in_bytes < header_size_) return true;
+  int field_index = (offset_in_bytes - header_size_) / kPointerSize;
+
+  return layout_descriptor_->IsTagged(field_index);
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_LAYOUT_DESCRIPTOR_INL_H_
diff --git a/src/layout-descriptor.cc b/src/layout-descriptor.cc
new file mode 100644
index 0000000..77b8ec4
--- /dev/null
+++ b/src/layout-descriptor.cc
@@ -0,0 +1,256 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <sstream>
+
+#include "src/v8.h"
+
+#include "src/base/bits.h"
+#include "src/layout-descriptor.h"
+
+using v8::base::bits::CountTrailingZeros32;
+
+namespace v8 {
+namespace internal {
+
+Handle<LayoutDescriptor> LayoutDescriptor::New(
+    Handle<Map> map, Handle<DescriptorArray> descriptors, int num_descriptors) {
+  Isolate* isolate = descriptors->GetIsolate();
+  if (!FLAG_unbox_double_fields) return handle(FastPointerLayout(), isolate);
+
+  int inobject_properties = map->inobject_properties();
+  if (inobject_properties == 0) return handle(FastPointerLayout(), isolate);
+
+  DCHECK(num_descriptors <= descriptors->number_of_descriptors());
+
+  int layout_descriptor_length;
+  const int kMaxWordsPerField = kDoubleSize / kPointerSize;
+
+  if (num_descriptors <= kSmiValueSize / kMaxWordsPerField) {
+    // Even in the "worst" case (all fields are doubles) it would fit into
+    // a Smi, so no need to calculate length.
+    layout_descriptor_length = kSmiValueSize;
+
+  } else {
+    layout_descriptor_length = 0;
+
+    for (int i = 0; i < num_descriptors; i++) {
+      PropertyDetails details = descriptors->GetDetails(i);
+      if (!InobjectUnboxedField(inobject_properties, details)) continue;
+      int field_index = details.field_index();
+      int field_width_in_words = details.field_width_in_words();
+      layout_descriptor_length =
+          Max(layout_descriptor_length, field_index + field_width_in_words);
+    }
+
+    if (layout_descriptor_length == 0) {
+      // No double fields were found, use fast pointer layout.
+      return handle(FastPointerLayout(), isolate);
+    }
+  }
+  layout_descriptor_length = Min(layout_descriptor_length, inobject_properties);
+
+  // Initially, layout descriptor corresponds to an object with all fields
+  // tagged.
+  Handle<LayoutDescriptor> layout_descriptor_handle =
+      LayoutDescriptor::New(isolate, layout_descriptor_length);
+
+  DisallowHeapAllocation no_allocation;
+  LayoutDescriptor* layout_descriptor = *layout_descriptor_handle;
+
+  for (int i = 0; i < num_descriptors; i++) {
+    PropertyDetails details = descriptors->GetDetails(i);
+    if (!InobjectUnboxedField(inobject_properties, details)) continue;
+    int field_index = details.field_index();
+    layout_descriptor = layout_descriptor->SetRawData(field_index);
+    if (details.field_width_in_words() > 1) {
+      layout_descriptor = layout_descriptor->SetRawData(field_index + 1);
+    }
+  }
+  return handle(layout_descriptor, isolate);
+}
+
+
+Handle<LayoutDescriptor> LayoutDescriptor::Append(Handle<Map> map,
+                                                  PropertyDetails details) {
+  Isolate* isolate = map->GetIsolate();
+  Handle<LayoutDescriptor> layout_descriptor(map->GetLayoutDescriptor(),
+                                             isolate);
+
+  if (!InobjectUnboxedField(map->inobject_properties(), details)) {
+    return layout_descriptor;
+  }
+  int field_index = details.field_index();
+  layout_descriptor = LayoutDescriptor::EnsureCapacity(
+      isolate, layout_descriptor, field_index + details.field_width_in_words());
+
+  DisallowHeapAllocation no_allocation;
+  LayoutDescriptor* layout_desc = *layout_descriptor;
+  layout_desc = layout_desc->SetRawData(field_index);
+  if (details.field_width_in_words() > 1) {
+    layout_desc = layout_desc->SetRawData(field_index + 1);
+  }
+  return handle(layout_desc, isolate);
+}
+
+
+Handle<LayoutDescriptor> LayoutDescriptor::AppendIfFastOrUseFull(
+    Handle<Map> map, PropertyDetails details,
+    Handle<LayoutDescriptor> full_layout_descriptor) {
+  DisallowHeapAllocation no_allocation;
+  LayoutDescriptor* layout_descriptor = map->layout_descriptor();
+  if (layout_descriptor->IsSlowLayout()) {
+    return full_layout_descriptor;
+  }
+  if (!InobjectUnboxedField(map->inobject_properties(), details)) {
+    return handle(layout_descriptor, map->GetIsolate());
+  }
+  int field_index = details.field_index();
+  int new_capacity = field_index + details.field_width_in_words();
+  if (new_capacity > layout_descriptor->capacity()) {
+    // Current map's layout descriptor runs out of space, so use the full
+    // layout descriptor.
+    return full_layout_descriptor;
+  }
+
+  layout_descriptor = layout_descriptor->SetRawData(field_index);
+  if (details.field_width_in_words() > 1) {
+    layout_descriptor = layout_descriptor->SetRawData(field_index + 1);
+  }
+  return handle(layout_descriptor, map->GetIsolate());
+}
+
+
+Handle<LayoutDescriptor> LayoutDescriptor::EnsureCapacity(
+    Isolate* isolate, Handle<LayoutDescriptor> layout_descriptor,
+    int new_capacity) {
+  int old_capacity = layout_descriptor->capacity();
+  if (new_capacity <= old_capacity) {
+    // Nothing to do with layout in Smi-form.
+    return layout_descriptor;
+  }
+  Handle<LayoutDescriptor> new_layout_descriptor =
+      LayoutDescriptor::New(isolate, new_capacity);
+  DCHECK(new_layout_descriptor->IsSlowLayout());
+
+  if (layout_descriptor->IsSlowLayout()) {
+    memcpy(new_layout_descriptor->DataPtr(), layout_descriptor->DataPtr(),
+           layout_descriptor->DataSize());
+    return new_layout_descriptor;
+  } else {
+    // Fast layout.
+    uint32_t value =
+        static_cast<uint32_t>(Smi::cast(*layout_descriptor)->value());
+    new_layout_descriptor->set(0, value);
+    return new_layout_descriptor;
+  }
+}
+
+
+bool LayoutDescriptor::IsTagged(int field_index, int max_sequence_length,
+                                int* out_sequence_length) {
+  DCHECK(max_sequence_length > 0);
+  if (IsFastPointerLayout()) {
+    *out_sequence_length = max_sequence_length;
+    return true;
+  }
+
+  int layout_word_index;
+  int layout_bit_index;
+
+  if (!GetIndexes(field_index, &layout_word_index, &layout_bit_index)) {
+    // Out of bounds queries are considered tagged.
+    *out_sequence_length = max_sequence_length;
+    return true;
+  }
+  uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;
+
+  uint32_t value = IsSlowLayout()
+                       ? get_scalar(layout_word_index)
+                       : static_cast<uint32_t>(Smi::cast(this)->value());
+
+  bool is_tagged = (value & layout_mask) == 0;
+  if (!is_tagged) value = ~value;  // Count set bits instead of cleared bits.
+  value = value & ~(layout_mask - 1);  // Clear bits we are not interested in.
+  int sequence_length = CountTrailingZeros32(value) - layout_bit_index;
+
+  if (layout_bit_index + sequence_length == kNumberOfBits) {
+    // This is a contiguous sequence till the end of current word, proceed
+    // counting in the subsequent words.
+    if (IsSlowLayout()) {
+      int len = length();
+      ++layout_word_index;
+      for (; layout_word_index < len; layout_word_index++) {
+        value = get_scalar(layout_word_index);
+        bool cur_is_tagged = (value & 1) == 0;
+        if (cur_is_tagged != is_tagged) break;
+        if (!is_tagged) value = ~value;  // Count set bits instead.
+        int cur_sequence_length = CountTrailingZeros32(value);
+        sequence_length += cur_sequence_length;
+        if (sequence_length >= max_sequence_length) break;
+        if (cur_sequence_length != kNumberOfBits) break;
+      }
+    }
+    if (is_tagged && (field_index + sequence_length == capacity())) {
+      // The contiguous sequence of tagged fields lasts till the end of the
+      // layout descriptor which means that all the fields starting from
+      // field_index are tagged.
+      sequence_length = std::numeric_limits<int>::max();
+    }
+  }
+  *out_sequence_length = Min(sequence_length, max_sequence_length);
+  return is_tagged;
+}
+
+
+Handle<LayoutDescriptor> LayoutDescriptor::NewForTesting(Isolate* isolate,
+                                                         int length) {
+  return New(isolate, length);
+}
+
+
+LayoutDescriptor* LayoutDescriptor::SetTaggedForTesting(int field_index,
+                                                        bool tagged) {
+  return SetTagged(field_index, tagged);
+}
+
+
+bool LayoutDescriptorHelper::IsTagged(
+    int offset_in_bytes, int end_offset,
+    int* out_end_of_contiguous_region_offset) {
+  DCHECK(IsAligned(offset_in_bytes, kPointerSize));
+  DCHECK(IsAligned(end_offset, kPointerSize));
+  DCHECK(offset_in_bytes < end_offset);
+  if (all_fields_tagged_) {
+    *out_end_of_contiguous_region_offset = end_offset;
+    DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset);
+    return true;
+  }
+  int max_sequence_length = (end_offset - offset_in_bytes) / kPointerSize;
+  int field_index = Max(0, (offset_in_bytes - header_size_) / kPointerSize);
+  int sequence_length;
+  bool tagged = layout_descriptor_->IsTagged(field_index, max_sequence_length,
+                                             &sequence_length);
+  DCHECK(sequence_length > 0);
+  if (offset_in_bytes < header_size_) {
+    // Object headers do not contain non-tagged fields. Check if the contiguous
+    // region continues after the header.
+    if (tagged) {
+      // First field is tagged, calculate end offset from there.
+      *out_end_of_contiguous_region_offset =
+          header_size_ + sequence_length * kPointerSize;
+
+    } else {
+      *out_end_of_contiguous_region_offset = header_size_;
+    }
+    DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset);
+    return true;
+  }
+  *out_end_of_contiguous_region_offset =
+      offset_in_bytes + sequence_length * kPointerSize;
+  DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset);
+  return tagged;
+}
+}
+}  // namespace v8::internal
diff --git a/src/layout-descriptor.h b/src/layout-descriptor.h
new file mode 100644
index 0000000..cc2666a
--- /dev/null
+++ b/src/layout-descriptor.h
@@ -0,0 +1,141 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_LAYOUT_DESCRIPTOR_H_
+#define V8_LAYOUT_DESCRIPTOR_H_
+
+#include <iosfwd>
+
+#include "src/objects.h"
+
+namespace v8 {
+namespace internal {
+
+// LayoutDescriptor is a bit vector defining which fields contain non-tagged
+// values. It could either be a fixed typed array (slow form) or a Smi
+// if the length fits (fast form).
+// Each bit in the layout represents a FIELD. The bits are referenced by
+// field_index which is a field number. If the bit is set then the corresponding
+// field contains a non-tagged value and therefore must be skipped by GC.
+// Otherwise the field is considered tagged. If the queried bit lays "outside"
+// of the descriptor then the field is also considered tagged.
+// Once a layout descriptor is created it is allowed only to append properties
+// to it.
+class LayoutDescriptor : public FixedTypedArray<Uint32ArrayTraits> {
+ public:
+  V8_INLINE bool IsTagged(int field_index);
+
+  // Queries the contiguous region of fields that are either tagged or not.
+  // Returns true if the given field is tagged or false otherwise and writes
+  // the length of the contiguous region to |out_sequence_length|.
+  // If the sequence is longer than |max_sequence_length| then
+  // |out_sequence_length| is set to |max_sequence_length|.
+  bool IsTagged(int field_index, int max_sequence_length,
+                int* out_sequence_length);
+
+  // Returns true if this is a layout of the object having only tagged fields.
+  V8_INLINE bool IsFastPointerLayout();
+  V8_INLINE static bool IsFastPointerLayout(Object* layout_descriptor);
+
+  // Returns true if the layout descriptor is in non-Smi form.
+  V8_INLINE bool IsSlowLayout();
+
+  V8_INLINE static LayoutDescriptor* cast(Object* object);
+  V8_INLINE static const LayoutDescriptor* cast(const Object* object);
+
+  V8_INLINE static LayoutDescriptor* cast_gc_safe(Object* object);
+
+  // Builds layout descriptor optimized for given |map| by |num_descriptors|
+  // elements of given descriptors array. The |map|'s descriptors could be
+  // different.
+  static Handle<LayoutDescriptor> New(Handle<Map> map,
+                                      Handle<DescriptorArray> descriptors,
+                                      int num_descriptors);
+
+  // Creates new layout descriptor by appending property with |details| to
+  // |map|'s layout descriptor.
+  static Handle<LayoutDescriptor> Append(Handle<Map> map,
+                                         PropertyDetails details);
+
+  // Creates new layout descriptor by appending property with |details| to
+  // |map|'s layout descriptor and if it is still fast then returns it.
+  // Otherwise the |full_layout_descriptor| is returned.
+  static Handle<LayoutDescriptor> AppendIfFastOrUseFull(
+      Handle<Map> map, PropertyDetails details,
+      Handle<LayoutDescriptor> full_layout_descriptor);
+
+  // Layout descriptor that corresponds to an object all fields of which are
+  // tagged (FastPointerLayout).
+  V8_INLINE static LayoutDescriptor* FastPointerLayout();
+
+#ifdef DEBUG
+  // Check that this layout descriptor corresponds to given map.
+  bool IsConsistentWithMap(Map* map);
+#endif
+
+#ifdef OBJECT_PRINT
+  // For our gdb macros, we should perhaps change these in the future.
+  void Print();
+
+  void Print(std::ostream& os);  // NOLINT
+#endif
+
+  // Capacity of layout descriptors in bits.
+  V8_INLINE int capacity();
+
+  static Handle<LayoutDescriptor> NewForTesting(Isolate* isolate, int length);
+  LayoutDescriptor* SetTaggedForTesting(int field_index, bool tagged);
+
+ private:
+  static const int kNumberOfBits = 32;
+
+  V8_INLINE static Handle<LayoutDescriptor> New(Isolate* isolate, int length);
+  V8_INLINE static LayoutDescriptor* FromSmi(Smi* smi);
+
+  V8_INLINE static bool InobjectUnboxedField(int inobject_properties,
+                                             PropertyDetails details);
+
+  static Handle<LayoutDescriptor> EnsureCapacity(
+      Isolate* isolate, Handle<LayoutDescriptor> layout_descriptor,
+      int new_capacity);
+
+  // Returns false if requested field_index is out of bounds.
+  V8_INLINE bool GetIndexes(int field_index, int* layout_word_index,
+                            int* layout_bit_index);
+
+  V8_INLINE MUST_USE_RESULT LayoutDescriptor* SetRawData(int field_index) {
+    return SetTagged(field_index, false);
+  }
+
+  V8_INLINE MUST_USE_RESULT LayoutDescriptor* SetTagged(int field_index,
+                                                        bool tagged);
+};
+
+
+// LayoutDescriptorHelper is a helper class for querying layout descriptor
+// about whether the field at given offset is tagged or not.
+class LayoutDescriptorHelper {
+ public:
+  inline explicit LayoutDescriptorHelper(Map* map);
+
+  bool all_fields_tagged() { return all_fields_tagged_; }
+  inline bool IsTagged(int offset_in_bytes);
+
+  // Queries the contiguous region of fields that are either tagged or not.
+  // Returns true if fields starting at |offset_in_bytes| are tagged or false
+  // otherwise and writes the offset of the end of the contiguous region to
+  // |out_end_of_contiguous_region_offset|. The |end_offset| value is the
+  // upper bound for |out_end_of_contiguous_region_offset|.
+  bool IsTagged(int offset_in_bytes, int end_offset,
+                int* out_end_of_contiguous_region_offset);
+
+ private:
+  bool all_fields_tagged_;
+  int header_size_;
+  LayoutDescriptor* layout_descriptor_;
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_LAYOUT_DESCRIPTOR_H_
diff --git a/src/libplatform/default-platform.cc b/src/libplatform/default-platform.cc
index b5b8571..1ac52f9 100644
--- a/src/libplatform/default-platform.cc
+++ b/src/libplatform/default-platform.cc
@@ -9,6 +9,7 @@
 
 #include "src/base/logging.h"
 #include "src/base/platform/platform.h"
+#include "src/base/platform/time.h"
 #include "src/base/sys-info.h"
 #include "src/libplatform/worker-thread.h"
 
@@ -106,4 +107,9 @@
   main_thread_queue_[isolate].push(task);
 }
 
+
+double DefaultPlatform::MonotonicallyIncreasingTime() {
+  return base::TimeTicks::HighResolutionNow().ToInternalValue() /
+         static_cast<double>(base::Time::kMicrosecondsPerSecond);
+}
 } }  // namespace v8::platform
diff --git a/src/libplatform/default-platform.h b/src/libplatform/default-platform.h
index 1efd7b2..21ba9bd 100644
--- a/src/libplatform/default-platform.h
+++ b/src/libplatform/default-platform.h
@@ -37,6 +37,7 @@
       Task* task, ExpectedRuntime expected_runtime) OVERRIDE;
   virtual void CallOnForegroundThread(v8::Isolate* isolate,
                                       Task* task) OVERRIDE;
+  double MonotonicallyIncreasingTime() OVERRIDE;
 
  private:
   static const int kMaxThreadPoolSize;
diff --git a/src/libplatform/libplatform.gyp b/src/libplatform/libplatform.gyp
deleted file mode 100644
index 4321da7..0000000
--- a/src/libplatform/libplatform.gyp
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2014 the V8 project authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
-  'variables': {
-    'v8_code': 1,
-  },
-  'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
-  'targets': [
-    {
-      'target_name': 'libplatform-unittests',
-      'type': 'executable',
-      'dependencies': [
-        '../../testing/gtest.gyp:gtest',
-        '../../testing/gmock.gyp:gmock',
-        '../../testing/gmock.gyp:gmock_main',
-        '../../tools/gyp/v8.gyp:v8_libplatform',
-      ],
-      'include_dirs': [
-        '../..',
-      ],
-      'sources': [  ### gcmole(all) ###
-        'default-platform-unittest.cc',
-        'task-queue-unittest.cc',
-        'worker-thread-unittest.cc',
-      ],
-      'conditions': [
-        ['os_posix == 1', {
-          # TODO(svenpanne): This is a temporary work-around to fix the warnings
-          # that show up because we use -std=gnu++0x instead of -std=c++11.
-          'cflags!': [
-            '-pedantic',
-          ],
-        }],
-      ],
-    },
-  ],
-}
diff --git a/src/libplatform/worker-thread.h b/src/libplatform/worker-thread.h
index 67f086d..cf77e61 100644
--- a/src/libplatform/worker-thread.h
+++ b/src/libplatform/worker-thread.h
@@ -22,7 +22,7 @@
   virtual ~WorkerThread();
 
   // Thread implementation.
-  virtual void Run() OVERRIDE;
+  void Run() OVERRIDE;
 
  private:
   friend class QuitTask;
diff --git a/src/list-inl.h b/src/list-inl.h
index 60e8fab..9b122fd 100644
--- a/src/list-inl.h
+++ b/src/list-inl.h
@@ -7,6 +7,7 @@
 
 #include "src/list.h"
 
+#include "src/base/macros.h"
 #include "src/base/platform/platform.h"
 
 namespace v8 {
@@ -33,8 +34,10 @@
 void List<T, P>::AddAll(const Vector<T>& other, P alloc) {
   int result_length = length_ + other.length();
   if (capacity_ < result_length) Resize(result_length, alloc);
-  for (int i = 0; i < other.length(); i++) {
-    data_[length_ + i] = other.at(i);
+  if (base::is_fundamental<T>()) {
+    memcpy(data_ + length_, other.start(), sizeof(*data_) * other.length());
+  } else {
+    for (int i = 0; i < other.length(); i++) data_[length_ + i] = other.at(i);
   }
   length_ = result_length;
 }
diff --git a/src/list.h b/src/list.h
index ea5fd1e..c17c4ec 100644
--- a/src/list.h
+++ b/src/list.h
@@ -80,7 +80,9 @@
 
   Vector<T> ToVector() const { return Vector<T>(data_, length_); }
 
-  Vector<const T> ToConstVector() { return Vector<const T>(data_, length_); }
+  Vector<const T> ToConstVector() const {
+    return Vector<const T>(data_, length_);
+  }
 
   // Adds a copy of the given 'element' to the end of the list,
   // expanding the list if necessary.
diff --git a/src/lithium-codegen.cc b/src/lithium-codegen.cc
index ea6b83a..4534b46 100644
--- a/src/lithium-codegen.cc
+++ b/src/lithium-codegen.cc
@@ -2,10 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-
 #include "src/lithium-codegen.h"
 
+#include <sstream>
+
+#include "src/v8.h"
+
 #if V8_TARGET_ARCH_IA32
 #include "src/ia32/lithium-ia32.h"  // NOLINT
 #include "src/ia32/lithium-codegen-ia32.h"  // NOLINT
@@ -148,11 +150,11 @@
 
 
 void LCodeGenBase::DeoptComment(const Deoptimizer::Reason& reason) {
-  OStringStream os;
+  std::ostringstream os;
   os << ";;; deoptimize at " << HSourcePosition(reason.raw_position) << " "
      << reason.mnemonic;
   if (reason.detail != NULL) os << ": " << reason.detail;
-  Comment("%s", os.c_str());
+  Comment("%s", os.str().c_str());
 }
 
 
diff --git a/src/lithium.cc b/src/lithium.cc
index 7d992a1..d57a2dd 100644
--- a/src/lithium.cc
+++ b/src/lithium.cc
@@ -463,8 +463,8 @@
   LOG_CODE_EVENT(info()->isolate(),
                  CodeStartLinePosInfoRecordEvent(
                      assembler.positions_recorder()));
-  // TODO(yangguo) remove this once the code serializer handles code stubs.
-  if (info()->will_serialize()) assembler.enable_serializer();
+  // Code serializer only takes unoptimized code.
+  DCHECK(!info()->will_serialize());
   LCodeGen generator(this, &assembler, info());
 
   MarkEmptyBlocks();
diff --git a/src/liveedit-debugger.js b/src/liveedit-debugger.js
index 07214f9..eaa2383 100644
--- a/src/liveedit-debugger.js
+++ b/src/liveedit-debugger.js
@@ -19,6 +19,9 @@
 // All unchanged functions have their positions updated accordingly.
 //
 // LiveEdit namespace is declared inside a single function constructor.
+
+"use strict";
+
 Debug.LiveEdit = new function() {
 
   // Forward declaration for minifier.
@@ -953,7 +956,7 @@
 
   FunctionPatchabilityStatus.SymbolName = function(code) {
     var enumeration = FunctionPatchabilityStatus;
-    for (name in enumeration) {
+    for (var name in enumeration) {
       if (enumeration[name] == code) {
         return name;
       }
diff --git a/src/liveedit.cc b/src/liveedit.cc
index a87c31b..29eaa97 100644
--- a/src/liveedit.cc
+++ b/src/liveedit.cc
@@ -607,10 +607,8 @@
 
 void FunctionInfoWrapper::SetInitialProperties(Handle<String> name,
                                                int start_position,
-                                               int end_position,
-                                               int param_num,
+                                               int end_position, int param_num,
                                                int literal_count,
-                                               int slot_count,
                                                int parent_index) {
   HandleScope scope(isolate());
   this->SetField(kFunctionNameOffset_, name);
@@ -618,7 +616,6 @@
   this->SetSmiValueField(kEndPositionOffset_, end_position);
   this->SetSmiValueField(kParamNumOffset_, param_num);
   this->SetSmiValueField(kLiteralNumOffset_, literal_count);
-  this->SetSmiValueField(kSlotNumOffset_, slot_count);
   this->SetSmiValueField(kParentIndexOffset_, parent_index);
 }
 
@@ -649,23 +646,18 @@
 }
 
 
-Handle<TypeFeedbackVector> FunctionInfoWrapper::GetFeedbackVector() {
+MaybeHandle<TypeFeedbackVector> FunctionInfoWrapper::GetFeedbackVector() {
   Handle<Object> element = this->GetField(kSharedFunctionInfoOffset_);
-  Handle<TypeFeedbackVector> result;
   if (element->IsJSValue()) {
     Handle<JSValue> value_wrapper = Handle<JSValue>::cast(element);
     Handle<Object> raw_result = UnwrapJSValue(value_wrapper);
     Handle<SharedFunctionInfo> shared =
         Handle<SharedFunctionInfo>::cast(raw_result);
-    result = Handle<TypeFeedbackVector>(shared->feedback_vector(), isolate());
-    CHECK_EQ(result->length(), GetSlotCount());
+    return Handle<TypeFeedbackVector>(shared->feedback_vector(), isolate());
   } else {
-    // Scripts may never have a SharedFunctionInfo created, so
-    // create a type feedback vector here.
-    int slot_count = GetSlotCount();
-    result = isolate()->factory()->NewTypeFeedbackVector(slot_count);
+    // Scripts may never have a SharedFunctionInfo created.
+    return MaybeHandle<TypeFeedbackVector>();
   }
-  return result;
 }
 
 
@@ -709,7 +701,6 @@
     info.SetInitialProperties(fun->name(), fun->start_position(),
                               fun->end_position(), fun->parameter_count(),
                               fun->materialized_literal_count(),
-                              fun->slot_count(),
                               current_parent_index_);
     current_parent_index_ = len_;
     SetElementSloppy(result_, len_, info.GetJSArray());
@@ -1202,10 +1193,12 @@
       shared_info->set_scope_info(ScopeInfo::cast(*code_scope_info));
     }
     shared_info->DisableOptimization(kLiveEdit);
-    // Update the type feedback vector
-    Handle<TypeFeedbackVector> feedback_vector =
+    // Update the type feedback vector, if needed.
+    MaybeHandle<TypeFeedbackVector> feedback_vector =
         compile_info_wrapper.GetFeedbackVector();
-    shared_info->set_feedback_vector(*feedback_vector);
+    if (!feedback_vector.is_null()) {
+      shared_info->set_feedback_vector(*feedback_vector.ToHandleChecked());
+    }
   }
 
   if (shared_info->debug_info()->IsDebugInfo()) {
diff --git a/src/liveedit.h b/src/liveedit.h
index 53418b0..65fe1a6 100644
--- a/src/liveedit.h
+++ b/src/liveedit.h
@@ -280,12 +280,8 @@
       : JSArrayBasedStruct<FunctionInfoWrapper>(array) {
   }
 
-  void SetInitialProperties(Handle<String> name,
-                            int start_position,
-                            int end_position,
-                            int param_num,
-                            int literal_count,
-                            int slot_count,
+  void SetInitialProperties(Handle<String> name, int start_position,
+                            int end_position, int param_num, int literal_count,
                             int parent_index);
 
   void SetFunctionCode(Handle<Code> function_code,
@@ -307,7 +303,7 @@
 
   Handle<Code> GetFunctionCode();
 
-  Handle<TypeFeedbackVector> GetFeedbackVector();
+  MaybeHandle<TypeFeedbackVector> GetFeedbackVector();
 
   Handle<Object> GetCodeScopeInfo();
 
@@ -317,10 +313,6 @@
 
   int GetEndPosition() { return this->GetSmiValueField(kEndPositionOffset_); }
 
-  int GetSlotCount() {
-    return this->GetSmiValueField(kSlotNumOffset_);
-  }
-
  private:
   static const int kFunctionNameOffset_ = 0;
   static const int kStartPositionOffset_ = 1;
@@ -332,8 +324,7 @@
   static const int kParentIndexOffset_ = 7;
   static const int kSharedFunctionInfoOffset_ = 8;
   static const int kLiteralNumOffset_ = 9;
-  static const int kSlotNumOffset_ = 10;
-  static const int kSize_ = 11;
+  static const int kSize_ = 10;
 
   friend class JSArrayBasedStruct<FunctionInfoWrapper>;
 };
diff --git a/src/log-inl.h b/src/log-inl.h
index 28677ad..a96631d 100644
--- a/src/log-inl.h
+++ b/src/log-inl.h
@@ -6,6 +6,7 @@
 #define V8_LOG_INL_H_
 
 #include "src/log.h"
+#include "src/isolate.h"
 
 namespace v8 {
 namespace internal {
@@ -26,6 +27,16 @@
 }
 
 
+void Logger::CallEventLogger(Isolate* isolate, const char* name, StartEnd se,
+                             bool expose_to_api) {
+  if (isolate->event_logger() != NULL) {
+    if (isolate->event_logger() == DefaultEventLoggerSentinel) {
+      LOG(isolate, TimerEvent(se, name));
+    } else if (expose_to_api) {
+      isolate->event_logger()(name, se);
+    }
+  }
+}
 } }  // namespace v8::internal
 
 #endif  // V8_LOG_INL_H_
diff --git a/src/log-utils.cc b/src/log-utils.cc
index c94d07a..278cff1 100644
--- a/src/log-utils.cc
+++ b/src/log-utils.cc
@@ -6,6 +6,7 @@
 
 #include "src/log-utils.h"
 #include "src/string-stream.h"
+#include "src/version.h"
 
 namespace v8 {
 namespace internal {
@@ -49,6 +50,14 @@
     } else {
       OpenFile(log_file_name);
     }
+
+    if (output_handle_ != nullptr) {
+      Log::MessageBuilder msg(this);
+      msg.Append("v8-version,%d,%d,%d,%d,%d", Version::GetMajor(),
+                 Version::GetMinor(), Version::GetBuild(), Version::GetPatch(),
+                 Version::IsCandidate());
+      msg.WriteToLogFile();
+    }
   }
 }
 
diff --git a/src/log.cc b/src/log.cc
index 86f5ce0..3eede36 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -2,7 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <stdarg.h>
+#include "src/log.h"
+
+#include <cstdarg>
+#include <sstream>
 
 #include "src/v8.h"
 
@@ -13,7 +16,7 @@
 #include "src/cpu-profiler.h"
 #include "src/deoptimizer.h"
 #include "src/global-handles.h"
-#include "src/log.h"
+#include "src/log-inl.h"
 #include "src/log-utils.h"
 #include "src/macro-assembler.h"
 #include "src/perf-jit.h"
@@ -605,7 +608,7 @@
     if (paused_)
       return;
 
-    if (Succ(head_) == tail_) {
+    if (Succ(head_) == static_cast<int>(base::NoBarrier_Load(&tail_))) {
       overflow_ = true;
     } else {
       buffer_[head_] = *sample;
@@ -624,9 +627,10 @@
   // Waits for a signal and removes profiling data.
   bool Remove(TickSample* sample) {
     buffer_semaphore_.Wait();  // Wait for an element.
-    *sample = buffer_[tail_];
+    *sample = buffer_[base::NoBarrier_Load(&tail_)];
     bool result = overflow_;
-    tail_ = Succ(tail_);
+    base::NoBarrier_Store(&tail_, static_cast<base::Atomic32>(
+                                      Succ(base::NoBarrier_Load(&tail_))));
     overflow_ = false;
     return result;
   }
@@ -640,7 +644,7 @@
   static const int kBufferSize = 128;
   TickSample buffer_[kBufferSize];  // Buffer storage.
   int head_;  // Index to the buffer head.
-  int tail_;  // Index to the buffer tail.
+  base::Atomic32 tail_;             // Index to the buffer tail.
   bool overflow_;  // Tell whether a buffer overflow has occurred.
   // Sempahore used for buffer synchronization.
   base::Semaphore buffer_semaphore_;
@@ -649,7 +653,7 @@
   bool engaged_;
 
   // Tells whether worker thread should continue running.
-  bool running_;
+  base::Atomic32 running_;
 
   // Tells whether we are currently recording tick samples.
   bool paused_;
@@ -697,12 +701,13 @@
     : base::Thread(Options("v8:Profiler")),
       isolate_(isolate),
       head_(0),
-      tail_(0),
       overflow_(false),
       buffer_semaphore_(0),
       engaged_(false),
-      running_(false),
-      paused_(false) {}
+      paused_(false) {
+  base::NoBarrier_Store(&tail_, 0);
+  base::NoBarrier_Store(&running_, 0);
+}
 
 
 void Profiler::Engage() {
@@ -717,7 +722,7 @@
   }
 
   // Start thread processing the profiler buffer.
-  running_ = true;
+  base::NoBarrier_Store(&running_, 1);
   Start();
 
   // Register to get ticks.
@@ -737,7 +742,7 @@
   // Terminate the worker thread by setting running_ to false,
   // inserting a fake element in the queue and then wait for
   // the thread to terminate.
-  running_ = false;
+  base::NoBarrier_Store(&running_, 0);
   TickSample sample;
   // Reset 'paused_' flag, otherwise semaphore may not be signalled.
   resume();
@@ -751,7 +756,7 @@
 void Profiler::Run() {
   TickSample sample;
   bool overflow = Remove(&sample);
-  while (running_) {
+  while (base::NoBarrier_Load(&running_)) {
     LOG(isolate_, TickEvent(&sample, overflow));
     overflow = Remove(&sample);
   }
@@ -950,18 +955,10 @@
 }
 
 
-void Logger::DefaultTimerEventsLogger(const char* name, int se) {
-  Isolate* isolate = Isolate::Current();
-  LOG(isolate, TimerEvent(static_cast<StartEnd>(se), name));
-}
-
-
 template <class TimerEvent>
 void TimerEventScope<TimerEvent>::LogTimerEvent(Logger::StartEnd se) {
-  if (TimerEvent::expose_to_api() ||
-      isolate_->event_logger() == Logger::DefaultTimerEventsLogger) {
-    isolate_->event_logger()(TimerEvent::name(), se);
-  }
+  Logger::CallEventLogger(isolate_, TimerEvent::name(), se,
+                          TimerEvent::expose_to_api());
 }
 
 
@@ -1303,7 +1300,7 @@
   SmartArrayPointer<char> name =
       shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
   msg.Append("\"%s\",", name.get());
-  msg.Append("\"%s\"", GetBailoutReason(shared->DisableOptimizationReason()));
+  msg.Append("\"%s\"", GetBailoutReason(shared->disable_optimization_reason()));
   msg.WriteToLogFile();
 }
 
@@ -1785,13 +1782,13 @@
 }
 
 
-static void AddIsolateIdIfNeeded(OStream& os,  // NOLINT
+static void AddIsolateIdIfNeeded(std::ostream& os,  // NOLINT
                                  Isolate* isolate) {
   if (FLAG_logfile_per_isolate) os << "isolate-" << isolate << "-";
 }
 
 
-static void PrepareLogFileName(OStream& os,  // NOLINT
+static void PrepareLogFileName(std::ostream& os,  // NOLINT
                                Isolate* isolate, const char* file_name) {
   AddIsolateIdIfNeeded(os, isolate);
   for (const char* p = file_name; *p; p++) {
@@ -1836,9 +1833,9 @@
     FLAG_log_snapshot_positions = true;
   }
 
-  OStringStream log_file_name;
+  std::ostringstream log_file_name;
   PrepareLogFileName(log_file_name, isolate, FLAG_logfile);
-  log_->Initialize(log_file_name.c_str());
+  log_->Initialize(log_file_name.str().c_str());
 
 
   if (FLAG_perf_basic_prof) {
@@ -1852,7 +1849,7 @@
   }
 
   if (FLAG_ll_prof) {
-    ll_logger_ = new LowLevelLogger(log_file_name.c_str());
+    ll_logger_ = new LowLevelLogger(log_file_name.str().c_str());
     addCodeEventListener(ll_logger_);
   }
 
@@ -1862,14 +1859,14 @@
     is_logging_ = true;
   }
 
+  if (FLAG_log_internal_timer_events || FLAG_prof) timer_.Start();
+
   if (FLAG_prof) {
     profiler_ = new Profiler(isolate);
     is_logging_ = true;
     profiler_->Engage();
   }
 
-  if (FLAG_log_internal_timer_events || FLAG_prof) timer_.Start();
-
   return true;
 }
 
diff --git a/src/log.h b/src/log.h
index 51597dd..abf35f0 100644
--- a/src/log.h
+++ b/src/log.h
@@ -300,8 +300,10 @@
   static void EnterExternal(Isolate* isolate);
   static void LeaveExternal(Isolate* isolate);
 
-  static void EmptyTimerEventsLogger(const char* name, int se) {}
-  static void DefaultTimerEventsLogger(const char* name, int se);
+  static void DefaultEventLoggerSentinel(const char* name, int event) {}
+
+  INLINE(static void CallEventLogger(Isolate* isolate, const char* name,
+                                     StartEnd se, bool expose_to_api));
 
   // ==== Events logged by --log-regexp ====
   // Regexp compilation and execution events.
diff --git a/src/lookup-inl.h b/src/lookup-inl.h
index d4777a0..0c9cc91 100644
--- a/src/lookup-inl.h
+++ b/src/lookup-inl.h
@@ -63,12 +63,10 @@
         property_details_ = descriptors->GetDetails(number_);
       }
       has_property_ = true;
-      switch (property_details_.type()) {
-        case v8::internal::CONSTANT:
-        case v8::internal::FIELD:
-        case v8::internal::NORMAL:
+      switch (property_details_.kind()) {
+        case v8::internal::DATA:
           return DATA;
-        case v8::internal::CALLBACKS:
+        case v8::internal::ACCESSOR:
           return ACCESSOR;
       }
     case ACCESSOR:
diff --git a/src/lookup.cc b/src/lookup.cc
index b855abe..8088f4d 100644
--- a/src/lookup.cc
+++ b/src/lookup.cc
@@ -102,7 +102,7 @@
   DCHECK(HolderIsReceiverOrHiddenPrototype());
   Handle<JSObject> holder = GetHolder<JSObject>();
   if (holder_map_->is_dictionary_map()) {
-    PropertyDetails details(attributes, NORMAL, 0);
+    PropertyDetails details(attributes, FIELD, 0);
     JSObject::SetNormalizedProperty(holder, name(), value, details);
   } else {
     holder_map_ = Map::ReconfigureDataProperty(holder_map_, descriptor_number(),
@@ -127,7 +127,7 @@
   // observable.
   Handle<JSObject> receiver = GetStoreTarget();
 
-  if (!name().is_identical_to(isolate()->factory()->hidden_string()) &&
+  if (!isolate()->IsInternallyUsedPropertyName(name()) &&
       !receiver->map()->is_extensible()) {
     return;
   }
@@ -289,7 +289,7 @@
 }
 
 
-void LookupIterator::WriteDataValue(Handle<Object> value) {
+Handle<Object> LookupIterator::WriteDataValue(Handle<Object> value) {
   DCHECK_EQ(DATA, state_);
   Handle<JSObject> holder = GetHolder<JSObject>();
   if (holder_map_->is_dictionary_map()) {
@@ -297,7 +297,7 @@
     if (holder->IsGlobalObject()) {
       Handle<PropertyCell> cell(
           PropertyCell::cast(property_dictionary->ValueAt(dictionary_entry())));
-      PropertyCell::SetValueInferType(cell, value);
+      value = PropertyCell::SetValueInferType(cell, value);
     } else {
       property_dictionary->ValueAtPut(dictionary_entry(), *value);
     }
@@ -306,6 +306,29 @@
   } else {
     DCHECK_EQ(v8::internal::CONSTANT, property_details_.type());
   }
+  return value;
+}
+
+
+bool LookupIterator::IsSpecialNumericIndex() const {
+  if (GetStoreTarget()->IsJSTypedArray() && name()->IsString()) {
+    Handle<String> name_string = Handle<String>::cast(name());
+    if (name_string->length() > 0) {
+      double d =
+          StringToDouble(isolate()->unicode_cache(), name_string, NO_FLAGS);
+      if (!std::isnan(d)) {
+        if (String::Equals(isolate()->factory()->minus_zero_string(),
+                           name_string))
+          return true;
+
+        Factory* factory = isolate()->factory();
+        Handle<Object> num = factory->NewNumber(d);
+        Handle<String> roundtrip_string = factory->NumberToString(num);
+        if (String::Equals(name_string, roundtrip_string)) return true;
+      }
+    }
+  }
+  return false;
 }
 
 
diff --git a/src/lookup.h b/src/lookup.h
index 14ca010..a2e0d4d 100644
--- a/src/lookup.h
+++ b/src/lookup.h
@@ -46,7 +46,7 @@
                  Configuration configuration = PROTOTYPE_CHAIN)
       : configuration_(ComputeConfiguration(configuration, name)),
         state_(NOT_FOUND),
-        property_details_(NONE, NORMAL, Representation::None()),
+        property_details_(NONE, FIELD, 0),
         isolate_(name->GetIsolate()),
         name_(name),
         receiver_(receiver),
@@ -61,7 +61,7 @@
                  Configuration configuration = PROTOTYPE_CHAIN)
       : configuration_(ComputeConfiguration(configuration, name)),
         state_(NOT_FOUND),
-        property_details_(NONE, NORMAL, Representation::None()),
+        property_details_(NONE, FIELD, 0),
         isolate_(name->GetIsolate()),
         name_(name),
         holder_map_(holder->map(), isolate_),
@@ -136,7 +136,13 @@
   Handle<PropertyCell> GetPropertyCell() const;
   Handle<Object> GetAccessors() const;
   Handle<Object> GetDataValue() const;
-  void WriteDataValue(Handle<Object> value);
+  // Usually returns the value that was passed in, but may perform
+  // non-observable modifications on it, such as internalize strings.
+  Handle<Object> WriteDataValue(Handle<Object> value);
+
+  // Checks whether the receiver is an indexed exotic object
+  // and name is a special numeric index.
+  bool IsSpecialNumericIndex() const;
 
   void InternalizeName();
 
@@ -171,7 +177,8 @@
   static Configuration ComputeConfiguration(
       Configuration configuration, Handle<Name> name) {
     if (name->IsOwn()) {
-      return static_cast<Configuration>(configuration & HIDDEN);
+      return static_cast<Configuration>(configuration &
+                                        HIDDEN_SKIP_INTERCEPTOR);
     } else {
       return configuration;
     }
diff --git a/src/macro-assembler.h b/src/macro-assembler.h
index 54cebca..2501f80 100644
--- a/src/macro-assembler.h
+++ b/src/macro-assembler.h
@@ -124,6 +124,74 @@
   bool old_has_frame_;
 };
 
+class FrameAndConstantPoolScope {
+ public:
+  FrameAndConstantPoolScope(MacroAssembler* masm, StackFrame::Type type)
+      : masm_(masm),
+        type_(type),
+        old_has_frame_(masm->has_frame()),
+        old_constant_pool_available_(FLAG_enable_ool_constant_pool &&
+                                     masm->is_ool_constant_pool_available()) {
+    masm->set_has_frame(true);
+    if (FLAG_enable_ool_constant_pool) {
+      masm->set_ool_constant_pool_available(true);
+    }
+    if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
+      masm->EnterFrame(type, !old_constant_pool_available_);
+    }
+  }
+
+  ~FrameAndConstantPoolScope() {
+    masm_->LeaveFrame(type_);
+    masm_->set_has_frame(old_has_frame_);
+    if (FLAG_enable_ool_constant_pool) {
+      masm_->set_ool_constant_pool_available(old_constant_pool_available_);
+    }
+  }
+
+  // Normally we generate the leave-frame code when this object goes
+  // out of scope.  Sometimes we may need to generate the code somewhere else
+  // in addition.  Calling this will achieve that, but the object stays in
+  // scope, the MacroAssembler is still marked as being in a frame scope, and
+  // the code will be generated again when it goes out of scope.
+  void GenerateLeaveFrame() {
+    DCHECK(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
+    masm_->LeaveFrame(type_);
+  }
+
+ private:
+  MacroAssembler* masm_;
+  StackFrame::Type type_;
+  bool old_has_frame_;
+  bool old_constant_pool_available_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(FrameAndConstantPoolScope);
+};
+
+// Class for scoping the the unavailability of constant pool access.
+class ConstantPoolUnavailableScope {
+ public:
+  explicit ConstantPoolUnavailableScope(MacroAssembler* masm)
+      : masm_(masm),
+        old_constant_pool_available_(FLAG_enable_ool_constant_pool &&
+                                     masm->is_ool_constant_pool_available()) {
+    if (FLAG_enable_ool_constant_pool) {
+      masm_->set_ool_constant_pool_available(false);
+    }
+  }
+  ~ConstantPoolUnavailableScope() {
+    if (FLAG_enable_ool_constant_pool) {
+      masm_->set_ool_constant_pool_available(old_constant_pool_available_);
+    }
+  }
+
+ private:
+  MacroAssembler* masm_;
+  int old_constant_pool_available_;
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolUnavailableScope);
+};
+
 
 class AllowExternalCallThatCantCauseGC: public FrameScope {
  public:
diff --git a/src/macros.py b/src/macros.py
index b3ff0fc..1571144 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -167,6 +167,8 @@
 macro TO_OBJECT_INLINE(arg) = (IS_SPEC_OBJECT(%IS_VAR(arg)) ? arg : ToObject(arg));
 macro JSON_NUMBER_TO_STRING(arg) = ((%_IsSmi(%IS_VAR(arg)) || arg - arg == 0) ? %_NumberToString(arg) : "null");
 macro HAS_OWN_PROPERTY(obj, index) = (%_CallFunction(obj, index, ObjectHasOwnProperty));
+macro SHOULD_CREATE_WRAPPER(functionName, receiver) = (!IS_SPEC_OBJECT(receiver) && %IsSloppyModeFunction(functionName));
+macro HAS_INDEX(array, index, is_array) = ((is_array && %_HasFastPackedElements(%IS_VAR(array))) ? (index < array.length) : (index in array));
 
 # Private names.
 # GET_PRIVATE should only be used if the property is known to exists on obj
@@ -254,7 +256,7 @@
 macro OVERRIDE_CAPTURE(override, index) = ((override)[(index)]);
 
 # PropertyDescriptor return value indices - must match
-# PropertyDescriptorIndices in runtime.cc.
+# PropertyDescriptorIndices in runtime-object.cc.
 const IS_ACCESSOR_INDEX = 0;
 const VALUE_INDEX = 1;
 const GETTER_INDEX = 2;
@@ -290,3 +292,5 @@
 
 # Check whether debug is active.
 const DEBUG_IS_ACTIVE = (%_DebugIsActive() != 0);
+macro DEBUG_IS_STEPPING(function) = (%_DebugIsActive() != 0 && %DebugCallbackSupportsStepping(function));
+macro DEBUG_PREPARE_STEP_IN_IF_STEPPING(function) = if (DEBUG_IS_STEPPING(function)) %DebugPrepareStepInIfStepping(function);
diff --git a/src/math.js b/src/math.js
index f06249d..cc478d3 100644
--- a/src/math.js
+++ b/src/math.js
@@ -144,7 +144,7 @@
 // ECMA 262 - 15.8.2.14
 var rngstate;  // Initialized to a Uint32Array during genesis.
 function MathRandom() {
-  var r0 = (MathImul(18273, rngstate[0] & 0xFFFF) + (rngstate[0] >>> 16)) | 0;
+  var r0 = (MathImul(18030, rngstate[0] & 0xFFFF) + (rngstate[0] >>> 16)) | 0;
   rngstate[0] = r0;
   var r1 = (MathImul(36969, rngstate[1] & 0xFFFF) + (rngstate[1] >>> 16)) | 0;
   rngstate[1] = r1;
@@ -227,17 +227,6 @@
   return 0.5 * MathLog((1 + x) / (1 - x));
 }
 
-// ES6 draft 09-27-13, section 20.2.2.21.
-function MathLog10(x) {
-  return MathLog(x) * 0.434294481903251828;  // log10(x) = log(x)/log(10).
-}
-
-
-// ES6 draft 09-27-13, section 20.2.2.22.
-function MathLog2(x) {
-  return MathLog(x) * 1.442695040888963407;  // log2(x) = log(x)/log(2).
-}
-
 // ES6 draft 09-27-13, section 20.2.2.17.
 function MathHypot(x, y) {  // Function length is 2.
   // We may want to introduce fast paths for two arguments and when
@@ -321,6 +310,8 @@
   %AddNamedProperty(global, "Math", $Math, DONT_ENUM);
   %FunctionSetInstanceClassName(MathConstructor, 'Math');
 
+  %AddNamedProperty($Math, symbolToStringTag, "Math", READ_ONLY | DONT_ENUM);
+
   // Set up math constants.
   InstallConstants($Math, $Array(
     // ECMA-262, section 15.8.1.1.
@@ -367,8 +358,8 @@
     "asinh", MathAsinh,
     "acosh", MathAcosh,
     "atanh", MathAtanh,
-    "log10", MathLog10,
-    "log2", MathLog2,
+    "log10", MathLog10,   // implemented by third_party/fdlibm
+    "log2", MathLog2,     // implemented by third_party/fdlibm
     "hypot", MathHypot,
     "fround", MathFroundJS,
     "clz32", MathClz32,
diff --git a/src/messages.js b/src/messages.js
index 4a71a61..39887d6 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -9,9 +9,8 @@
   cyclic_proto:                  ["Cyclic __proto__ value"],
   code_gen_from_strings:         ["%0"],
   constructor_special_method:    ["Class constructor may not be an accessor"],
-  generator_running:             ["Generator is already running"],
-  generator_finished:            ["Generator has already finished"],
   // TypeError
+  generator_running:             ["Generator is already running"],
   unexpected_token:              ["Unexpected token ", "%0"],
   unexpected_token_number:       ["Unexpected number"],
   unexpected_token_string:       ["Unexpected string"],
@@ -19,8 +18,12 @@
   unexpected_reserved:           ["Unexpected reserved word"],
   unexpected_strict_reserved:    ["Unexpected strict mode reserved word"],
   unexpected_eos:                ["Unexpected end of input"],
+  unexpected_template_string:    ["Unexpected template string"],
   malformed_regexp:              ["Invalid regular expression: /", "%0", "/: ", "%1"],
+  malformed_regexp_flags:        ["Invalid regular expression flags"],
   unterminated_regexp:           ["Invalid regular expression: missing /"],
+  unterminated_template:         ["Unterminated template literal"],
+  unterminated_template_expr:    ["Missing } in template expression"],
   regexp_flags:                  ["Cannot supply flags when constructing one RegExp from another"],
   incompatible_method_receiver:  ["Method ", "%0", " called on incompatible receiver ", "%1"],
   multiple_defaults_in_switch:   ["More than one default clause in switch statement"],
@@ -49,6 +52,7 @@
   apply_wrong_args:              ["Function.prototype.apply: Arguments list has wrong type"],
   toMethod_non_function:         ["Function.prototype.toMethod was called on ", "%0", ", which is a ", "%1", " and not a function"],
   toMethod_non_object:           ["Function.prototype.toMethod: home object ", "%0", " is not an object"],
+  flags_getter_non_object:       ["RegExp.prototype.flags getter called on non-object ", "%0"],
   invalid_in_operator_use:       ["Cannot use 'in' operator to search for '", "%0", "' in ", "%1"],
   instanceof_function_expected:  ["Expecting a function in instanceof check, but got ", "%0"],
   instanceof_nonobject_proto:    ["Function has non-object prototype '", "%0", "' in instanceof check"],
@@ -150,6 +154,7 @@
   too_many_variables:            ["Too many variables declared (only 4194303 allowed)"],
   strict_param_dupe:             ["Strict mode function may not have duplicate parameter names"],
   strict_octal_literal:          ["Octal literals are not allowed in strict mode."],
+  template_octal_literal:        ["Octal literals are not allowed in template strings."],
   strict_duplicate_property:     ["Duplicate data property in object literal not allowed in strict mode"],
   accessor_data_property:        ["Object literal may not have data and accessor property with the same name"],
   accessor_get_set:              ["Object literal may not have multiple get/set accessors with the same name"],
@@ -174,7 +179,12 @@
   invalid_module_path:           ["Module does not export '", "%0", "', or export is not itself a module"],
   module_type_error:             ["Module '", "%0", "' used improperly"],
   module_export_undefined:       ["Export '", "%0", "' is not defined in module"],
-  unexpected_super:              ["'super' keyword unexpected here"]
+  unexpected_super:              ["'super' keyword unexpected here"],
+  extends_value_not_a_function:  ["Class extends value ", "%0", " is not a function or null"],
+  prototype_parent_not_an_object: ["Class extends value does not have valid prototype property ", "%0"],
+  duplicate_constructor:         ["A class may only have one constructor"],
+  sloppy_lexical:                ["Block-scoped declarations (let, const, function, class) not yet supported outside strict mode"],
+  super_constructor_call:        ["A 'super' constructor call may only appear as the first statement of a function, and its arguments may not access 'this'. Other forms are not yet supported."]
 };
 
 
@@ -221,7 +231,8 @@
     return str;
   }
   if (IS_SYMBOL(obj)) return %_CallFunction(obj, SymbolToString);
-  if (IS_OBJECT(obj) && %GetDataProperty(obj, "toString") === ObjectToString) {
+  if (IS_OBJECT(obj)
+      && %GetDataProperty(obj, "toString") === DefaultObjectToString) {
     var constructor = %GetDataProperty(obj, "constructor");
     if (typeof constructor == "function") {
       var constructorName = constructor.name;
@@ -233,7 +244,8 @@
   if (CanBeSafelyTreatedAsAnErrorObject(obj)) {
     return %_CallFunction(obj, ErrorToString);
   }
-  return %_CallFunction(obj, ObjectToString);
+
+  return %_CallFunction(obj, NoSideEffectsObjectToString);
 }
 
 // To determine whether we can safely stringify an object using ErrorToString
@@ -272,7 +284,7 @@
 
 
 function ToDetailString(obj) {
-  if (obj != null && IS_OBJECT(obj) && obj.toString === ObjectToString) {
+  if (obj != null && IS_OBJECT(obj) && obj.toString === DefaultObjectToString) {
     var constructor = obj.constructor;
     if (typeof constructor == "function") {
       var constructorName = constructor.name;
@@ -362,6 +374,23 @@
   return MakeGenericError($Error, type, args);
 }
 
+
+// The embedded versions are called from unoptimized code, with embedded
+// arguments. Those arguments cannot be arrays, which are context-dependent.
+function MakeTypeErrorEmbedded(type, arg) {
+  return MakeGenericError($TypeError, type, [arg]);
+}
+
+
+function MakeSyntaxErrorEmbedded(type, arg) {
+  return MakeGenericError($SyntaxError, type, [arg]);
+}
+
+
+function MakeReferenceErrorEmbedded(type, arg) {
+  return MakeGenericError($ReferenceError, type, [arg]);
+}
+
 /**
  * Find a line number given a specific source position.
  * @param {number} position The source position.
@@ -369,34 +398,26 @@
        else the line number.
  */
 function ScriptLineFromPosition(position) {
-  var lower = 0;
-  var upper = this.lineCount() - 1;
   var line_ends = this.line_ends;
+  var upper = line_ends.length - 1;
+  if (upper < 0) return -1;
 
   // We'll never find invalid positions so bail right away.
-  if (position > line_ends[upper]) {
-    return -1;
-  }
+  if (position > line_ends[upper]) return -1;
+  if (position <= line_ends[0]) return 0;
 
-  // This means we don't have to safe-guard indexing line_ends[i - 1].
-  if (position <= line_ends[0]) {
-    return 0;
-  }
-
-  // Binary search to find line # from position range.
-  while (upper >= 1) {
-    var i = (lower + upper) >> 1;
-
-    if (position > line_ends[i]) {
-      lower = i + 1;
-    } else if (position <= line_ends[i - 1]) {
-      upper = i - 1;
+  var lower = 1;
+  // Binary search.
+  while (true) {
+    var mid = (upper + lower) >> 1;
+    if (position <= line_ends[mid - 1]) {
+      upper = mid - 1;
+    } else if (position > line_ends[mid]){
+      lower = mid + 1;
     } else {
-      return i;
+      return mid;
     }
   }
-
-  return -1;
 }
 
 /**
@@ -1103,12 +1124,12 @@
   var constructor = receiver.constructor;
   if (!constructor) {
     return requireConstructor ? null :
-        %_CallFunction(receiver, ObjectToString);
+        %_CallFunction(receiver, NoSideEffectsObjectToString);
   }
   var constructorName = constructor.name;
   if (!constructorName) {
     return requireConstructor ? null :
-        %_CallFunction(receiver, ObjectToString);
+        %_CallFunction(receiver, NoSideEffectsObjectToString);
   }
   return constructorName;
 }
@@ -1132,7 +1153,7 @@
       if (IS_UNDEFINED(stack_trace)) {
         // Neither formatted nor structured stack trace available.
         // Look further up the prototype chain.
-        holder = %GetPrototype(holder);
+        holder = %_GetPrototype(holder);
         continue;
       }
       formatted_stack_trace = FormatStackTrace(holder, stack_trace);
@@ -1198,14 +1219,13 @@
     %AddNamedProperty(f.prototype, "name", name, DONT_ENUM);
     %SetCode(f, function(m) {
       if (%_IsConstructCall()) {
+        try { captureStackTrace(this, f); } catch (e) { }
         // Define all the expected properties directly on the error
         // object. This avoids going through getters and setters defined
         // on prototype objects.
-        %AddNamedProperty(this, 'stack', UNDEFINED, DONT_ENUM);
         if (!IS_UNDEFINED(m)) {
           %AddNamedProperty(this, 'message', ToString(m), DONT_ENUM);
         }
-        try { captureStackTrace(this, f); } catch (e) { }
       } else {
         return new f(m);
       }
@@ -1237,7 +1257,7 @@
   var current = error;
   // Climb the prototype chain until we find the holder.
   while (current && !%HasOwnProperty(current, name)) {
-    current = %GetPrototype(current);
+    current = %_GetPrototype(current);
   }
   if (IS_NULL(current)) return UNDEFINED;
   if (!IS_OBJECT(current)) return error[name];
diff --git a/src/mips/assembler-mips-inl.h b/src/mips/assembler-mips-inl.h
index 2666f6a..1cd9361 100644
--- a/src/mips/assembler-mips-inl.h
+++ b/src/mips/assembler-mips-inl.h
@@ -99,6 +99,11 @@
 }
 
 
+int DoubleRegister::NumAllocatableAliasedRegisters() {
+  return NumAllocatableRegisters();
+}
+
+
 int FPURegister::ToAllocationIndex(FPURegister reg) {
   DCHECK(reg.code() % 2 == 0);
   DCHECK(reg.code() / 2 < kMaxNumAllocatableRegisters);
diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc
index f1e5dfb..d6a4f79 100644
--- a/src/mips/assembler-mips.cc
+++ b/src/mips/assembler-mips.cc
@@ -2065,6 +2065,7 @@
 
 void Assembler::madd_d(FPURegister fd, FPURegister fr, FPURegister fs,
     FPURegister ft) {
+  DCHECK(IsMipsArchVariant(kMips32r2));
   GenInstrRegister(COP1X, fr, ft, fs, fd, MADD_D);
 }
 
diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h
index 5cdf16a..c6b12b7 100644
--- a/src/mips/assembler-mips.h
+++ b/src/mips/assembler-mips.h
@@ -222,6 +222,10 @@
 
   inline static int NumRegisters();
   inline static int NumAllocatableRegisters();
+
+  // TODO(turbofan): Proper support for float32.
+  inline static int NumAllocatableAliasedRegisters();
+
   inline static int ToAllocationIndex(FPURegister reg);
   static const char* AllocationIndexToString(int index);
 
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index 2813dd4..100195b 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -12,7 +12,7 @@
 #include "src/debug.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 
 namespace v8 {
@@ -45,11 +45,9 @@
     DCHECK(extra_args == NO_EXTRA_ARGUMENTS);
   }
 
-  // JumpToExternalReference expects s0 to contain the number of arguments
+  // JumpToExternalReference expects a0 to contain the number of arguments
   // including the receiver and the extra arguments.
-  __ Addu(s0, a0, num_extra_args + 1);
-  __ sll(s1, s0, kPointerSizeLog2);
-  __ Subu(s1, s1, kPointerSize);
+  __ Addu(a0, a0, num_extra_args + 1);
   __ JumpToExternalReference(ExternalReference(id, masm->isolate()));
 }
 
@@ -384,21 +382,21 @@
         MemOperand bit_field3 = FieldMemOperand(a2, Map::kBitField3Offset);
         // Check if slack tracking is enabled.
         __ lw(t0, bit_field3);
-        __ DecodeField<Map::ConstructionCount>(t2, t0);
-        __ Branch(&allocate, eq, t2, Operand(JSFunction::kNoSlackTracking));
+        __ DecodeField<Map::Counter>(t2, t0);
+        __ Branch(&allocate, lt, t2, Operand(Map::kSlackTrackingCounterEnd));
         // Decrease generous allocation count.
-        __ Subu(t0, t0, Operand(1 << Map::ConstructionCount::kShift));
-        __ Branch(USE_DELAY_SLOT,
-            &allocate, ne, t2, Operand(JSFunction::kFinishSlackTracking));
+        __ Subu(t0, t0, Operand(1 << Map::Counter::kShift));
+        __ Branch(USE_DELAY_SLOT, &allocate, ne, t2,
+                  Operand(Map::kSlackTrackingCounterEnd));
         __ sw(t0, bit_field3);  // In delay slot.
 
         __ Push(a1, a2, a1);  // a1 = Constructor.
         __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
 
         __ Pop(a1, a2);
-        // Slack tracking counter is kNoSlackTracking after runtime call.
-        DCHECK(JSFunction::kNoSlackTracking == 0);
-        __ mov(t2, zero_reg);
+        // Slack tracking counter is Map::kSlackTrackingCounterEnd after runtime
+        // call.
+        __ li(t2, Map::kSlackTrackingCounterEnd);
 
         __ bind(&allocate);
       }
@@ -445,8 +443,8 @@
         Label no_inobject_slack_tracking;
 
         // Check if slack tracking is enabled.
-        __ Branch(&no_inobject_slack_tracking,
-            eq, t2, Operand(JSFunction::kNoSlackTracking));
+        __ Branch(&no_inobject_slack_tracking, lt, t2,
+                  Operand(Map::kSlackTrackingCounterEnd));
 
         // Allocate object with a slack.
         __ lbu(a0, FieldMemOperand(a2, Map::kPreAllocatedPropertyFieldsOffset));
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index a9c10b8..97eed74 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -15,7 +15,7 @@
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -272,66 +272,6 @@
 }
 
 
-void WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(
-    Isolate* isolate) {
-  WriteInt32ToHeapNumberStub stub1(isolate, a1, v0, a2, a3);
-  WriteInt32ToHeapNumberStub stub2(isolate, a2, v0, a3, a0);
-  stub1.GetCode();
-  stub2.GetCode();
-}
-
-
-// See comment for class, this does NOT work for int32's that are in Smi range.
-void WriteInt32ToHeapNumberStub::Generate(MacroAssembler* masm) {
-  Label max_negative_int;
-  // the_int_ has the answer which is a signed int32 but not a Smi.
-  // We test for the special value that has a different exponent.
-  STATIC_ASSERT(HeapNumber::kSignMask == 0x80000000u);
-  // Test sign, and save for later conditionals.
-  __ And(sign(), the_int(), Operand(0x80000000u));
-  __ Branch(&max_negative_int, eq, the_int(), Operand(0x80000000u));
-
-  // Set up the correct exponent in scratch_.  All non-Smi int32s have the same.
-  // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased).
-  uint32_t non_smi_exponent =
-      (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift;
-  __ li(scratch(), Operand(non_smi_exponent));
-  // Set the sign bit in scratch_ if the value was negative.
-  __ or_(scratch(), scratch(), sign());
-  // Subtract from 0 if the value was negative.
-  __ subu(at, zero_reg, the_int());
-  __ Movn(the_int(), at, sign());
-  // We should be masking the implict first digit of the mantissa away here,
-  // but it just ends up combining harmlessly with the last digit of the
-  // exponent that happens to be 1.  The sign bit is 0 so we shift 10 to get
-  // the most significant 1 to hit the last bit of the 12 bit sign and exponent.
-  DCHECK(((1 << HeapNumber::kExponentShift) & non_smi_exponent) != 0);
-  const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2;
-  __ srl(at, the_int(), shift_distance);
-  __ or_(scratch(), scratch(), at);
-  __ sw(scratch(), FieldMemOperand(the_heap_number(),
-                                   HeapNumber::kExponentOffset));
-  __ sll(scratch(), the_int(), 32 - shift_distance);
-  __ Ret(USE_DELAY_SLOT);
-  __ sw(scratch(), FieldMemOperand(the_heap_number(),
-                                   HeapNumber::kMantissaOffset));
-
-  __ bind(&max_negative_int);
-  // The max negative int32 is stored as a positive number in the mantissa of
-  // a double because it uses a sign bit instead of using two's complement.
-  // The actual mantissa bits stored are all 0 because the implicit most
-  // significant 1 bit is not stored.
-  non_smi_exponent += 1 << HeapNumber::kExponentShift;
-  __ li(scratch(), Operand(HeapNumber::kSignMask | non_smi_exponent));
-  __ sw(scratch(),
-        FieldMemOperand(the_heap_number(), HeapNumber::kExponentOffset));
-  __ mov(scratch(), zero_reg);
-  __ Ret(USE_DELAY_SLOT);
-  __ sw(scratch(),
-        FieldMemOperand(the_heap_number(), HeapNumber::kMantissaOffset));
-}
-
-
 // Handle the case where the lhs and rhs are the same object.
 // Equality is almost reflexive (everything but NaN), so this is a test
 // for "identity and not NaN".
@@ -904,7 +844,6 @@
       // compile time and uses DoMathPowHalf instead.  We then skip this check
       // for non-constant cases of +/-0.5 as these hardly occur.
       Label not_plus_half;
-
       // Test for 0.5.
       __ Move(double_scratch, 0.5);
       __ BranchF(USE_DELAY_SLOT,
@@ -916,7 +855,7 @@
       // double_scratch can be overwritten in the delay slot.
       // Calculates square root of base.  Check for the special case of
       // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
-      __ Move(double_scratch, -V8_INFINITY);
+      __ Move(double_scratch, static_cast<double>(-V8_INFINITY));
       __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, double_base, double_scratch);
       __ neg_d(double_result, double_scratch);
 
@@ -936,13 +875,13 @@
       // double_scratch can be overwritten in the delay slot.
       // Calculates square root of base.  Check for the special case of
       // Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13).
-      __ Move(double_scratch, -V8_INFINITY);
+      __ Move(double_scratch, static_cast<double>(-V8_INFINITY));
       __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, double_base, double_scratch);
       __ Move(double_result, kDoubleRegZero);
 
       // Add +0 to convert -0 to +0.
       __ add_d(double_scratch, double_base, kDoubleRegZero);
-      __ Move(double_result, 1);
+      __ Move(double_result, 1.);
       __ sqrt_d(double_scratch, double_scratch);
       __ div_d(double_result, double_result, double_scratch);
       __ jmp(&done);
@@ -1058,7 +997,6 @@
 
 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
   CEntryStub::GenerateAheadOfTime(isolate);
-  WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate);
   StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
   StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
   ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
@@ -1099,22 +1037,18 @@
 
 void CEntryStub::Generate(MacroAssembler* masm) {
   // Called from JavaScript; parameters are on stack as if calling JS function
-  // s0: number of arguments including receiver
-  // s1: size of arguments excluding receiver
-  // s2: pointer to builtin function
+  // a0: number of arguments including receiver
+  // a1: pointer to builtin function
   // fp: frame pointer    (restored after C call)
   // sp: stack pointer    (restored as callee's sp after C call)
   // cp: current context  (C callee-saved)
 
   ProfileEntryHookStub::MaybeCallEntryHook(masm);
 
-  // NOTE: s0-s2 hold the arguments of this function instead of a0-a2.
-  // The reason for this is that these arguments would need to be saved anyway
-  // so it's faster to set them up directly.
-  // See MacroAssembler::PrepareCEntryArgs and PrepareCEntryFunction.
-
   // Compute the argv pointer in a callee-saved register.
+  __ sll(s1, a0, kPointerSizeLog2);
   __ Addu(s1, sp, s1);
+  __ Subu(s1, s1, kPointerSize);
 
   // Enter the exit frame that transitions from JavaScript to C++.
   FrameScope scope(masm, StackFrame::MANUAL);
@@ -1126,7 +1060,8 @@
 
   // Prepare arguments for C routine.
   // a0 = argc
-  __ mov(a0, s0);
+  __ mov(s0, a0);
+  __ mov(s2, a1);
   // a1 = argv (set in the delay slot after find_ra below).
 
   // We are calling compiled C/C++ code. a0 and a1 hold our two arguments. We
@@ -1406,6 +1341,40 @@
 }
 
 
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+  // Return address is in ra.
+  Label miss;
+
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register index = LoadDescriptor::NameRegister();
+  Register scratch = t1;
+  Register result = v0;
+  DCHECK(!scratch.is(receiver) && !scratch.is(index));
+  DCHECK(!FLAG_vector_ics ||
+         (!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
+          result.is(VectorLoadICDescriptor::SlotRegister())));
+
+  // StringCharAtGenerator doesn't use the result register until it's passed
+  // the different miss possibilities. If it did, we would have a conflict
+  // when FLAG_vector_ics is true.
+  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+                                          &miss,  // When not a string.
+                                          &miss,  // When not a number.
+                                          &miss,  // When index out of range.
+                                          STRING_INDEX_IS_ARRAY_INDEX,
+                                          RECEIVER_IS_STRING);
+  char_at_generator.GenerateFast(masm);
+  __ Ret();
+
+  StubRuntimeCallHelper call_helper;
+  char_at_generator.GenerateSlow(masm, call_helper);
+
+  __ bind(&miss);
+  PropertyAccessCompiler::TailCallBuiltin(
+      masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
+
+
 // Uses registers a0 to t0.
 // Expected input (depending on whether args are in registers or on the stack):
 // * object: a0 or at sp + 1 * kPointerSize.
@@ -1417,8 +1386,6 @@
 void InstanceofStub::Generate(MacroAssembler* masm) {
   // Call site inlining and patching implies arguments in registers.
   DCHECK(HasArgsInRegisters() || !HasCallSiteInlineCheck());
-  // ReturnTrueFalse is only implemented for inlined call sites.
-  DCHECK(!ReturnTrueFalseObject() || HasCallSiteInlineCheck());
 
   // Fixed register usage throughout the stub:
   const Register object = a0;  // Object (lhs).
@@ -1443,7 +1410,7 @@
 
   // If there is a call site cache don't look in the global cache, but do the
   // real lookup and update the call site cache.
-  if (!HasCallSiteInlineCheck()) {
+  if (!HasCallSiteInlineCheck() && !ReturnTrueFalseObject()) {
     Label miss;
     __ LoadRoot(at, Heap::kInstanceofCacheFunctionRootIndex);
     __ Branch(&miss, ne, function, Operand(at));
@@ -1502,6 +1469,9 @@
   if (!HasCallSiteInlineCheck()) {
     __ mov(v0, zero_reg);
     __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
+    if (ReturnTrueFalseObject()) {
+      __ LoadRoot(v0, Heap::kTrueValueRootIndex);
+    }
   } else {
     // Patch the call site to return true.
     __ LoadRoot(v0, Heap::kTrueValueRootIndex);
@@ -1520,6 +1490,9 @@
   if (!HasCallSiteInlineCheck()) {
     __ li(v0, Operand(Smi::FromInt(1)));
     __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
+    if (ReturnTrueFalseObject()) {
+      __ LoadRoot(v0, Heap::kFalseValueRootIndex);
+    }
   } else {
     // Patch the call site to return false.
     __ LoadRoot(v0, Heap::kFalseValueRootIndex);
@@ -1543,23 +1516,33 @@
   __ Branch(&slow, ne, scratch, Operand(JS_FUNCTION_TYPE));
 
   // Null is not instance of anything.
-  __ Branch(&object_not_null,
-            ne,
-            scratch,
+  __ Branch(&object_not_null, ne, object,
             Operand(isolate()->factory()->null_value()));
-  __ li(v0, Operand(Smi::FromInt(1)));
+  if (ReturnTrueFalseObject()) {
+    __ LoadRoot(v0, Heap::kFalseValueRootIndex);
+  } else {
+    __ li(v0, Operand(Smi::FromInt(1)));
+  }
   __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
 
   __ bind(&object_not_null);
   // Smi values are not instances of anything.
   __ JumpIfNotSmi(object, &object_not_null_or_smi);
-  __ li(v0, Operand(Smi::FromInt(1)));
+  if (ReturnTrueFalseObject()) {
+    __ LoadRoot(v0, Heap::kFalseValueRootIndex);
+  } else {
+    __ li(v0, Operand(Smi::FromInt(1)));
+  }
   __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
 
   __ bind(&object_not_null_or_smi);
   // String values are not instances of anything.
   __ IsObjectJSStringType(object, scratch, &slow);
-  __ li(v0, Operand(Smi::FromInt(1)));
+  if (ReturnTrueFalseObject()) {
+    __ LoadRoot(v0, Heap::kFalseValueRootIndex);
+  } else {
+    __ li(v0, Operand(Smi::FromInt(1)));
+  }
   __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
 
   // Slow-case.  Tail call builtin.
@@ -1587,8 +1570,14 @@
 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
   Label miss;
   Register receiver = LoadDescriptor::ReceiverRegister();
-  NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, a3,
-                                                          t0, &miss);
+  // Ensure that the vector and slot registers won't be clobbered before
+  // calling the miss handler.
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(t0, t1, VectorLoadICDescriptor::VectorRegister(),
+                     VectorLoadICDescriptor::SlotRegister()));
+
+  NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, t0,
+                                                          t1, &miss);
   __ bind(&miss);
   PropertyAccessCompiler::TailCallBuiltin(
       masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
@@ -2507,14 +2496,14 @@
 
   // A monomorphic miss (i.e, here the cache is not uninitialized) goes
   // megamorphic.
-  __ LoadRoot(at, Heap::kUninitializedSymbolRootIndex);
+  __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex);
   __ Branch(&initialize, eq, t0, Operand(at));
   // MegamorphicSentinel is an immortal immovable object (undefined) so no
   // write-barrier is needed.
   __ bind(&megamorphic);
   __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
   __ Addu(t0, a2, Operand(t0));
-  __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex);
+  __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
   __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize));
   __ jmp(&done);
 
@@ -2790,8 +2779,12 @@
 
 
 void CallICStub::Generate(MacroAssembler* masm) {
-  // r1 - function
-  // r3 - slot id (Smi)
+  // a1 - function
+  // a3 - slot id (Smi)
+  const int with_types_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
+  const int generic_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
   Label extra_checks_or_miss, slow_start;
   Label slow, non_function, wrap, cont;
   Label have_js_function;
@@ -2830,27 +2823,71 @@
   }
 
   __ bind(&extra_checks_or_miss);
-  Label miss;
+  Label uninitialized, miss;
 
-  __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex);
+  __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
   __ Branch(&slow_start, eq, t0, Operand(at));
-  __ LoadRoot(at, Heap::kUninitializedSymbolRootIndex);
-  __ Branch(&miss, eq, t0, Operand(at));
 
-  if (!FLAG_trace_ic) {
-    // We are going megamorphic. If the feedback is a JSFunction, it is fine
-    // to handle it here. More complex cases are dealt with in the runtime.
-    __ AssertNotSmi(t0);
-    __ GetObjectType(t0, t1, t1);
-    __ Branch(&miss, ne, t1, Operand(JS_FUNCTION_TYPE));
-    __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
-    __ Addu(t0, a2, Operand(t0));
-    __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex);
-    __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize));
-    __ Branch(&slow_start);
+  // The following cases attempt to handle MISS cases without going to the
+  // runtime.
+  if (FLAG_trace_ic) {
+    __ Branch(&miss);
   }
 
-  // We are here because tracing is on or we are going monomorphic.
+  __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex);
+  __ Branch(&uninitialized, eq, t0, Operand(at));
+
+  // We are going megamorphic. If the feedback is a JSFunction, it is fine
+  // to handle it here. More complex cases are dealt with in the runtime.
+  __ AssertNotSmi(t0);
+  __ GetObjectType(t0, t1, t1);
+  __ Branch(&miss, ne, t1, Operand(JS_FUNCTION_TYPE));
+  __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
+  __ Addu(t0, a2, Operand(t0));
+  __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
+  __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize));
+  // We have to update statistics for runtime profiling.
+  __ lw(t0, FieldMemOperand(a2, with_types_offset));
+  __ Subu(t0, t0, Operand(Smi::FromInt(1)));
+  __ sw(t0, FieldMemOperand(a2, with_types_offset));
+  __ lw(t0, FieldMemOperand(a2, generic_offset));
+  __ Addu(t0, t0, Operand(Smi::FromInt(1)));
+  __ Branch(USE_DELAY_SLOT, &slow_start);
+  __ sw(t0, FieldMemOperand(a2, generic_offset));  // In delay slot.
+
+  __ bind(&uninitialized);
+
+  // We are going monomorphic, provided we actually have a JSFunction.
+  __ JumpIfSmi(a1, &miss);
+
+  // Goto miss case if we do not have a function.
+  __ GetObjectType(a1, t0, t0);
+  __ Branch(&miss, ne, t0, Operand(JS_FUNCTION_TYPE));
+
+  // Make sure the function is not the Array() function, which requires special
+  // behavior on MISS.
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, t0);
+  __ Branch(&miss, eq, a1, Operand(t0));
+
+  // Update stats.
+  __ lw(t0, FieldMemOperand(a2, with_types_offset));
+  __ Addu(t0, t0, Operand(Smi::FromInt(1)));
+  __ sw(t0, FieldMemOperand(a2, with_types_offset));
+
+  // Store the function.
+  __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
+  __ Addu(t0, a2, Operand(t0));
+  __ Addu(t0, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ sw(a1, MemOperand(t0, 0));
+
+  // Update the write barrier.
+  __ mov(t1, a1);
+  __ RecordWrite(a2, t0, t1, kRAHasNotBeenSaved, kDontSaveFPRegs,
+                 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+  __ Branch(&have_js_function);
+
+  // We are here because tracing is on or we encountered a MISS case we can't
+  // handle here.
   __ bind(&miss);
   GenerateMiss(masm);
 
@@ -2896,16 +2933,17 @@
   DCHECK(!t0.is(index_));
   DCHECK(!t0.is(result_));
   DCHECK(!t0.is(object_));
+  if (check_mode_ == RECEIVER_IS_UNKNOWN) {
+    // If the receiver is a smi trigger the non-string case.
+    __ JumpIfSmi(object_, receiver_not_string_);
 
-  // If the receiver is a smi trigger the non-string case.
-  __ JumpIfSmi(object_, receiver_not_string_);
-
-  // Fetch the instance type of the receiver into result register.
-  __ lw(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
-  __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
-  // If the receiver is not a string trigger the non-string case.
-  __ And(t0, result_, Operand(kIsNotStringMask));
-  __ Branch(receiver_not_string_, ne, t0, Operand(zero_reg));
+    // Fetch the instance type of the receiver into result register.
+    __ lw(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
+    __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
+    // If the receiver is not a string trigger the non-string case.
+    __ And(t0, result_, Operand(kIsNotStringMask));
+    __ Branch(receiver_not_string_, ne, t0, Operand(zero_reg));
+  }
 
   // If the index is non-smi trigger the non-smi case.
   __ JumpIfNotSmi(index_, &index_not_smi_);
@@ -3292,14 +3330,57 @@
   // a2: length
   // a3: from index (untagged)
   __ SmiTag(a3, a3);
-  StringCharAtGenerator generator(
-      v0, a3, a2, v0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
+  StringCharAtGenerator generator(v0, a3, a2, v0, &runtime, &runtime, &runtime,
+                                  STRING_INDEX_IS_NUMBER, RECEIVER_IS_STRING);
   generator.GenerateFast(masm);
   __ DropAndRet(3);
   generator.SkipSlow(masm, &runtime);
 }
 
 
+void ToNumberStub::Generate(MacroAssembler* masm) {
+  // The ToNumber stub takes one argument in a0.
+  Label not_smi;
+  __ JumpIfNotSmi(a0, &not_smi);
+  __ Ret(USE_DELAY_SLOT);
+  __ mov(v0, a0);
+  __ bind(&not_smi);
+
+  Label not_heap_number;
+  __ lw(a1, FieldMemOperand(a0, HeapObject::kMapOffset));
+  __ lbu(a1, FieldMemOperand(a1, Map::kInstanceTypeOffset));
+  // a0: object
+  // a1: instance type.
+  __ Branch(&not_heap_number, ne, a1, Operand(HEAP_NUMBER_TYPE));
+  __ Ret(USE_DELAY_SLOT);
+  __ mov(v0, a0);
+  __ bind(&not_heap_number);
+
+  Label not_string, slow_string;
+  __ Branch(&not_string, hs, a1, Operand(FIRST_NONSTRING_TYPE));
+  // Check if string has a cached array index.
+  __ lw(a2, FieldMemOperand(a0, String::kHashFieldOffset));
+  __ And(at, a2, Operand(String::kContainsCachedArrayIndexMask));
+  __ Branch(&slow_string, ne, at, Operand(zero_reg));
+  __ IndexFromHash(a2, a0);
+  __ Ret(USE_DELAY_SLOT);
+  __ mov(v0, a0);
+  __ bind(&slow_string);
+  __ push(a0);  // Push argument.
+  __ TailCallRuntime(Runtime::kStringToNumber, 1, 1);
+  __ bind(&not_string);
+
+  Label not_oddball;
+  __ Branch(&not_oddball, ne, a1, Operand(ODDBALL_TYPE));
+  __ Ret(USE_DELAY_SLOT);
+  __ lw(v0, FieldMemOperand(a0, Oddball::kToNumberOffset));
+  __ bind(&not_oddball);
+
+  __ push(a0);  // Push argument.
+  __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
+}
+
+
 void StringHelper::GenerateFlatOneByteStringEquals(
     MacroAssembler* masm, Register left, Register right, Register scratch1,
     Register scratch2, Register scratch3) {
diff --git a/src/mips/code-stubs-mips.h b/src/mips/code-stubs-mips.h
index afad32b..9796fd4 100644
--- a/src/mips/code-stubs-mips.h
+++ b/src/mips/code-stubs-mips.h
@@ -73,55 +73,6 @@
 };
 
 
-// This stub can convert a signed int32 to a heap number (double).  It does
-// not work for int32s that are in Smi range!  No GC occurs during this stub
-// so you don't have to set up the frame.
-class WriteInt32ToHeapNumberStub : public PlatformCodeStub {
- public:
-  WriteInt32ToHeapNumberStub(Isolate* isolate, Register the_int,
-                             Register the_heap_number, Register scratch,
-                             Register scratch2)
-      : PlatformCodeStub(isolate) {
-    minor_key_ = IntRegisterBits::encode(the_int.code()) |
-                 HeapNumberRegisterBits::encode(the_heap_number.code()) |
-                 ScratchRegisterBits::encode(scratch.code()) |
-                 SignRegisterBits::encode(scratch2.code());
-    DCHECK(IntRegisterBits::is_valid(the_int.code()));
-    DCHECK(HeapNumberRegisterBits::is_valid(the_heap_number.code()));
-    DCHECK(ScratchRegisterBits::is_valid(scratch.code()));
-    DCHECK(SignRegisterBits::is_valid(scratch2.code()));
-  }
-
-  static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
-
- private:
-  Register the_int() const {
-    return Register::from_code(IntRegisterBits::decode(minor_key_));
-  }
-
-  Register the_heap_number() const {
-    return Register::from_code(HeapNumberRegisterBits::decode(minor_key_));
-  }
-
-  Register scratch() const {
-    return Register::from_code(ScratchRegisterBits::decode(minor_key_));
-  }
-
-  Register sign() const {
-    return Register::from_code(SignRegisterBits::decode(minor_key_));
-  }
-
-  // Minor key encoding in 16 bits.
-  class IntRegisterBits: public BitField<int, 0, 4> {};
-  class HeapNumberRegisterBits: public BitField<int, 4, 4> {};
-  class ScratchRegisterBits: public BitField<int, 8, 4> {};
-  class SignRegisterBits: public BitField<int, 12, 4> {};
-
-  DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
-  DEFINE_PLATFORM_CODE_STUB(WriteInt32ToHeapNumber, PlatformCodeStub);
-};
-
-
 class RecordWriteStub: public PlatformCodeStub {
  public:
   RecordWriteStub(Isolate* isolate,
@@ -150,7 +101,7 @@
     INCREMENTAL_COMPACTION
   };
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
   static void PatchBranchIntoNop(MacroAssembler* masm, int pos) {
     const unsigned offset = masm->instr_at(pos) & kImm16Mask;
@@ -277,9 +228,9 @@
     kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
   };
 
-  virtual inline Major MajorKey() const FINAL OVERRIDE { return RecordWrite; }
+  inline Major MajorKey() const FINAL { return RecordWrite; }
 
-  virtual void Generate(MacroAssembler* masm) OVERRIDE;
+  void Generate(MacroAssembler* masm) OVERRIDE;
   void GenerateIncremental(MacroAssembler* masm, Mode mode);
   void CheckNeedsToInformIncrementalMarker(
       MacroAssembler* masm,
@@ -287,7 +238,7 @@
       Mode mode);
   void InformIncrementalMarker(MacroAssembler* masm);
 
-  void Activate(Code* code) {
+  void Activate(Code* code) OVERRIDE {
     code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
   }
 
@@ -335,7 +286,7 @@
   void GenerateCall(MacroAssembler* masm, Register target);
 
  private:
-  bool NeedsImmovableCode() { return true; }
+  bool NeedsImmovableCode() OVERRIDE { return true; }
 
   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
   DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub);
@@ -367,7 +318,7 @@
                                      Register r0,
                                      Register r1);
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
  private:
   static const int kInlinedProbes = 4;
diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc
index 0ecac19..fbd4044 100644
--- a/src/mips/codegen-mips.cc
+++ b/src/mips/codegen-mips.cc
@@ -896,9 +896,23 @@
         FixedDoubleArray::kHeaderSize - kHeapObjectTag
         + Register::kExponentOffset));
   __ Addu(dst_elements, array, Operand(FixedArray::kHeaderSize));
-  __ Addu(array, array, Operand(kHeapObjectTag));
   __ sll(dst_end, dst_end, 1);
   __ Addu(dst_end, dst_elements, dst_end);
+
+  // Allocating heap numbers in the loop below can fail and cause a jump to
+  // gc_required. We can't leave a partly initialized FixedArray behind,
+  // so pessimistically fill it with holes now.
+  Label initialization_loop, initialization_loop_entry;
+  __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
+  __ Branch(&initialization_loop_entry);
+  __ bind(&initialization_loop);
+  __ sw(scratch, MemOperand(dst_elements));
+  __ Addu(dst_elements, dst_elements, Operand(kPointerSize));
+  __ bind(&initialization_loop_entry);
+  __ Branch(&initialization_loop, lt, dst_elements, Operand(dst_end));
+
+  __ Addu(dst_elements, array, Operand(FixedArray::kHeaderSize));
+  __ Addu(array, array, Operand(kHeapObjectTag));
   __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
   // Using offsetted addresses.
   // dst_elements: begin of destination FixedArray element fields, not tagged
@@ -1131,7 +1145,7 @@
   // Mov 1 in double_scratch2 as math_exp_constants_array[8] == 1.
   DCHECK(*reinterpret_cast<double*>
          (ExternalReference::math_exp_constants(8).address()) == 1);
-  __ Move(double_scratch2, 1);
+  __ Move(double_scratch2, 1.);
   __ add_d(result, result, double_scratch2);
   __ srl(temp1, temp2, 11);
   __ Ext(temp2, temp2, 0, 11);
diff --git a/src/mips/constants-mips.h b/src/mips/constants-mips.h
index c2eb4ca..668481e 100644
--- a/src/mips/constants-mips.h
+++ b/src/mips/constants-mips.h
@@ -560,52 +560,49 @@
 // because 'NegateCondition' function flips LSB to negate condition.
 enum Condition {
   // Any value < 0 is considered no_condition.
-  kNoCondition  = -1,
-
-  overflow      =  0,
-  no_overflow   =  1,
-  Uless         =  2,
-  Ugreater_equal=  3,
-  equal         =  4,
-  not_equal     =  5,
-  Uless_equal   =  6,
-  Ugreater      =  7,
-  negative      =  8,
-  positive      =  9,
-  parity_even   = 10,
-  parity_odd    = 11,
-  less          = 12,
+  kNoCondition = -1,
+  overflow = 0,
+  no_overflow = 1,
+  Uless = 2,
+  Ugreater_equal = 3,
+  equal = 4,
+  not_equal = 5,
+  Uless_equal = 6,
+  Ugreater = 7,
+  negative = 8,
+  positive = 9,
+  parity_even = 10,
+  parity_odd = 11,
+  less = 12,
   greater_equal = 13,
-  less_equal    = 14,
-  greater       = 15,
-  ueq           = 16,  // Unordered or Equal.
-  nue           = 17,  // Not (Unordered or Equal).
-
-  cc_always     = 18,
+  less_equal = 14,
+  greater = 15,
+  ueq = 16,  // Unordered or Equal.
+  nue = 17,  // Not (Unordered or Equal).
+  cc_always = 18,
 
   // Aliases.
-  carry         = Uless,
-  not_carry     = Ugreater_equal,
-  zero          = equal,
-  eq            = equal,
-  not_zero      = not_equal,
-  ne            = not_equal,
-  nz            = not_equal,
-  sign          = negative,
-  not_sign      = positive,
-  mi            = negative,
-  pl            = positive,
-  hi            = Ugreater,
-  ls            = Uless_equal,
-  ge            = greater_equal,
-  lt            = less,
-  gt            = greater,
-  le            = less_equal,
-  hs            = Ugreater_equal,
-  lo            = Uless,
-  al            = cc_always,
-
-  cc_default    = kNoCondition
+  carry = Uless,
+  not_carry = Ugreater_equal,
+  zero = equal,
+  eq = equal,
+  not_zero = not_equal,
+  ne = not_equal,
+  nz = not_equal,
+  sign = negative,
+  not_sign = positive,
+  mi = negative,
+  pl = positive,
+  hi = Ugreater,
+  ls = Uless_equal,
+  ge = greater_equal,
+  lt = less,
+  gt = greater,
+  le = less_equal,
+  hs = Ugreater_equal,
+  lo = Uless,
+  al = cc_always,
+  cc_default = kNoCondition
 };
 
 
diff --git a/src/mips/debug-mips.cc b/src/mips/debug-mips.cc
index 96a1467..5b3591c 100644
--- a/src/mips/debug-mips.cc
+++ b/src/mips/debug-mips.cc
@@ -187,7 +187,11 @@
 void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
   Register receiver = LoadDescriptor::ReceiverRegister();
   Register name = LoadDescriptor::NameRegister();
-  Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0);
+  RegList regs = receiver.bit() | name.bit();
+  if (FLAG_vector_ics) {
+    regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit();
+  }
+  Generate_DebugBreakCallHelper(masm, regs, 0);
 }
 
 
diff --git a/src/mips/deoptimizer-mips.cc b/src/mips/deoptimizer-mips.cc
index dd9832d..e39b368 100644
--- a/src/mips/deoptimizer-mips.cc
+++ b/src/mips/deoptimizer-mips.cc
@@ -20,6 +20,12 @@
 }
 
 
+void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
+  // Empty because there is no need for relocation information for the code
+  // patching in Deoptimizer::PatchCodeForDeoptimization below.
+}
+
+
 void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
   Address code_start_address = code->instruction_start();
   // Invalidate the relocation information, as it will become invalid by the
@@ -102,9 +108,8 @@
   ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_);
   intptr_t handler = reinterpret_cast<intptr_t>(xref.address());
   int params = descriptor->GetHandlerParameterCount();
-  output_frame->SetRegister(s0.code(), params);
-  output_frame->SetRegister(s1.code(), (params - 1) * kPointerSize);
-  output_frame->SetRegister(s2.code(), handler);
+  output_frame->SetRegister(a0.code(), params);
+  output_frame->SetRegister(a1.code(), handler);
 }
 
 
diff --git a/src/mips/disasm-mips.cc b/src/mips/disasm-mips.cc
index 564627e..4f725cf 100644
--- a/src/mips/disasm-mips.cc
+++ b/src/mips/disasm-mips.cc
@@ -555,7 +555,13 @@
           }
           break;
         case S:
-          UNIMPLEMENTED_MIPS();
+          switch (instr->FunctionFieldRaw()) {
+            case CVT_D_S:
+              Format(instr, "cvt.d.s 'fd, 'fs");
+              break;
+            default:
+              UNIMPLEMENTED_MIPS();
+          }
           break;
         case W:
           switch (instr->FunctionFieldRaw()) {
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 1dbfe09..c1a8291 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -204,10 +204,10 @@
     Comment cmnt(masm_, "[ Allocate context");
     // Argument to NewContext is the function, which is still in a1.
     bool need_write_barrier = true;
-    if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
+    if (FLAG_harmony_scoping && info->scope()->is_script_scope()) {
       __ push(a1);
       __ Push(info->scope()->GetScopeInfo());
-      __ CallRuntime(Runtime::kNewGlobalContext, 2);
+      __ CallRuntime(Runtime::kNewScriptContext, 2);
     } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
       FastNewContextStub stub(isolate(), heap_slots);
       __ CallStub(&stub);
@@ -929,7 +929,7 @@
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
-  __ LoadContext(a1, scope_->ContextChainLength(scope_->GlobalScope()));
+  __ LoadContext(a1, scope_->ContextChainLength(scope_->ScriptScope()));
   __ lw(a1, ContextOperand(a1, variable->interface()->Index()));
   __ lw(a1, ContextOperand(a1, Context::EXTENSION_INDEX));
 
@@ -1093,7 +1093,7 @@
 
 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   Comment cmnt(masm_, "[ ForInStatement");
-  int slot = stmt->ForInFeedbackSlot();
+  FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
   SetStatementPosition(stmt);
 
   Label loop, exit;
@@ -1102,6 +1102,7 @@
 
   // Get the object to enumerate over. If the object is null or undefined, skip
   // over the loop.  See ECMA-262 version 5, section 12.6.4.
+  SetExpressionPosition(stmt->enumerable());
   VisitForAccumulatorValue(stmt->enumerable());
   __ mov(a0, result_register());  // Result as param to InvokeBuiltin below.
   __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
@@ -1121,6 +1122,7 @@
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ mov(a0, v0);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ push(a0);
 
   // Check for proxies.
@@ -1145,6 +1147,7 @@
   __ bind(&call_runtime);
   __ push(a0);  // Duplicate the enumerable object on the stack.
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
 
   // If we got a map from the runtime call, we can do a fast
   // modification check. Otherwise, we got a fixed array, and we have
@@ -1181,7 +1184,8 @@
 
   __ li(a1, FeedbackVector());
   __ li(a2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
-  __ sw(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(slot)));
+  int vector_index = FeedbackVector()->GetIndex(slot);
+  __ sw(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(vector_index)));
 
   __ li(a1, Operand(Smi::FromInt(1)));  // Smi indicates slow check
   __ lw(a2, MemOperand(sp, 0 * kPointerSize));  // Get enumerated object
@@ -1198,6 +1202,8 @@
   // Generate code for doing the condition check.
   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
   __ bind(&loop);
+  SetExpressionPosition(stmt->each());
+
   // Load the current count to a0, load the length to a1.
   __ lw(a0, MemOperand(sp, 0 * kPointerSize));
   __ lw(a1, MemOperand(sp, 1 * kPointerSize));
@@ -1267,48 +1273,6 @@
 }
 
 
-void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
-  Comment cmnt(masm_, "[ ForOfStatement");
-  SetStatementPosition(stmt);
-
-  Iteration loop_statement(this, stmt);
-  increment_loop_depth();
-
-  // var iterator = iterable[Symbol.iterator]();
-  VisitForEffect(stmt->assign_iterator());
-
-  // Loop entry.
-  __ bind(loop_statement.continue_label());
-
-  // result = iterator.next()
-  VisitForEffect(stmt->next_result());
-
-  // if (result.done) break;
-  Label result_not_done;
-  VisitForControl(stmt->result_done(),
-                  loop_statement.break_label(),
-                  &result_not_done,
-                  &result_not_done);
-  __ bind(&result_not_done);
-
-  // each = result.value
-  VisitForEffect(stmt->assign_each());
-
-  // Generate code for the body of the loop.
-  Visit(stmt->body());
-
-  // Check stack before looping.
-  PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
-  EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
-  __ jmp(loop_statement.continue_label());
-
-  // Exit and decrement the loop depth.
-  PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
-  __ bind(loop_statement.break_label());
-  decrement_loop_depth();
-}
-
-
 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
                                        bool pretenure) {
   // Use the fast case closure allocation code that allocates in new
@@ -1351,7 +1315,13 @@
   Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
   __ li(LoadDescriptor::NameRegister(), home_object_symbol);
 
-  CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  if (FLAG_vector_ics) {
+    __ li(VectorLoadICDescriptor::SlotRegister(),
+          Operand(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
+    CallLoadIC(NOT_CONTEXTUAL);
+  } else {
+    CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  }
 
   Label done;
   __ Branch(&done, ne, v0, Operand(isolate()->factory()->undefined_value()));
@@ -1360,6 +1330,19 @@
 }
 
 
+void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
+                                                  int offset) {
+  if (NeedsHomeObject(initializer)) {
+    __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
+    __ li(StoreDescriptor::NameRegister(),
+          Operand(isolate()->factory()->home_object_symbol()));
+    __ lw(StoreDescriptor::ValueRegister(),
+          MemOperand(sp, offset * kPointerSize));
+    CallStoreIC();
+  }
+}
+
+
 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
                                                       TypeofState typeof_state,
                                                       Label* slow) {
@@ -1409,7 +1392,7 @@
   __ li(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
   if (FLAG_vector_ics) {
     __ li(VectorLoadICDescriptor::SlotRegister(),
-          Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
+          Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
   }
 
   ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
@@ -1498,7 +1481,7 @@
       __ li(LoadDescriptor::NameRegister(), Operand(var->name()));
       if (FLAG_vector_ics) {
         __ li(VectorLoadICDescriptor::SlotRegister(),
-              Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
+              Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
       }
       CallLoadIC(CONTEXTUAL);
       context()->Plug(v0);
@@ -1676,6 +1659,7 @@
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in v0.
@@ -1704,6 +1688,8 @@
         DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
         // Fall through.
       case ObjectLiteral::Property::COMPUTED:
+        // It is safe to use [[Put]] here because the boilerplate already
+        // contains computed properties with an uninitialized value.
         if (key->value()->IsInternalizedString()) {
           if (property->emit_store()) {
             VisitForAccumulatorValue(value);
@@ -1713,6 +1699,14 @@
             __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
             CallStoreIC(key->LiteralFeedbackId());
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
+
+            if (NeedsHomeObject(value)) {
+              __ Move(StoreDescriptor::ReceiverRegister(), v0);
+              __ li(StoreDescriptor::NameRegister(),
+                    Operand(isolate()->factory()->home_object_symbol()));
+              __ lw(StoreDescriptor::ValueRegister(), MemOperand(sp));
+              CallStoreIC();
+            }
           } else {
             VisitForEffect(value);
           }
@@ -1724,6 +1718,7 @@
         VisitForStackValue(key);
         VisitForStackValue(value);
         if (property->emit_store()) {
+          EmitSetHomeObjectIfNeeded(value, 2);
           __ li(a0, Operand(Smi::FromInt(SLOPPY)));  // PropertyAttributes.
           __ push(a0);
           __ CallRuntime(Runtime::kSetProperty, 4);
@@ -1737,7 +1732,7 @@
         __ push(a0);
         VisitForStackValue(value);
         if (property->emit_store()) {
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           __ Drop(2);
         }
@@ -1760,7 +1755,9 @@
     __ push(a0);
     VisitForStackValue(it->first);
     EmitAccessor(it->second->getter);
+    EmitSetHomeObjectIfNeeded(it->second->getter, 2);
     EmitAccessor(it->second->setter);
+    EmitSetHomeObjectIfNeeded(it->second->setter, 3);
     __ li(a0, Operand(Smi::FromInt(NONE)));
     __ push(a0);
     __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
@@ -1872,16 +1869,8 @@
 
   Comment cmnt(masm_, "[ Assignment");
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
-  if (property != NULL) {
-    assign_type = (property->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(property);
 
   // Evaluate LHS expression.
   switch (assign_type) {
@@ -1897,6 +1886,30 @@
         VisitForStackValue(property->obj());
       }
       break;
+    case NAMED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        const Register scratch = a1;
+        __ lw(scratch, MemOperand(sp, kPointerSize));
+        __ Push(scratch, result_register());
+      }
+      break;
+    case KEYED_SUPER_PROPERTY: {
+      const Register scratch = a1;
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Move(scratch, result_register());
+      VisitForAccumulatorValue(property->key());
+      __ Push(scratch, result_register());
+      if (expr->is_compound()) {
+        const Register scratch1 = t0;
+        __ lw(scratch1, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch1, scratch, result_register());
+      }
+      break;
+    }
     case KEYED_PROPERTY:
       // We need the key and receiver on both the stack and in v0 and a1.
       if (expr->is_compound()) {
@@ -1925,6 +1938,14 @@
           EmitNamedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
           break;
+        case NAMED_SUPER_PROPERTY:
+          EmitNamedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
+        case KEYED_SUPER_PROPERTY:
+          EmitKeyedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
         case KEYED_PROPERTY:
           EmitKeyedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
@@ -1971,6 +1992,14 @@
     case NAMED_PROPERTY:
       EmitNamedPropertyAssignment(expr);
       break;
+    case NAMED_SUPER_PROPERTY:
+      EmitNamedSuperPropertyStore(property);
+      context()->Plug(v0);
+      break;
+    case KEYED_SUPER_PROPERTY:
+      EmitKeyedSuperPropertyStore(property);
+      context()->Plug(v0);
+      break;
     case KEYED_PROPERTY:
       EmitKeyedPropertyAssignment(expr);
       break;
@@ -2102,7 +2131,7 @@
       __ lw(load_name, MemOperand(sp, 2 * kPointerSize));
       if (FLAG_vector_ics) {
         __ li(VectorLoadICDescriptor::SlotRegister(),
-              Operand(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
+              Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
       }
       Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
       CallIC(ic, TypeFeedbackId::None());
@@ -2122,7 +2151,7 @@
       __ LoadRoot(load_name, Heap::kdone_stringRootIndex);  // "done"
       if (FLAG_vector_ics) {
         __ li(VectorLoadICDescriptor::SlotRegister(),
-              Operand(Smi::FromInt(expr->DoneFeedbackSlot())));
+              Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
       }
       CallLoadIC(NOT_CONTEXTUAL);                           // v0=result.done
       __ mov(a0, v0);
@@ -2135,7 +2164,7 @@
       __ LoadRoot(load_name, Heap::kvalue_stringRootIndex);  // "value"
       if (FLAG_vector_ics) {
         __ li(VectorLoadICDescriptor::SlotRegister(),
-              Operand(Smi::FromInt(expr->ValueFeedbackSlot())));
+              Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
       }
       CallLoadIC(NOT_CONTEXTUAL);                            // v0=result.value
       context()->DropAndPlug(2, v0);                         // drop iter and g
@@ -2156,14 +2185,6 @@
   VisitForAccumulatorValue(value);
   __ pop(a1);
 
-  // Check generator state.
-  Label wrong_state, closed_state, done;
-  __ lw(a3, FieldMemOperand(a1, JSGeneratorObject::kContinuationOffset));
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
-  __ Branch(&closed_state, eq, a3, Operand(zero_reg));
-  __ Branch(&wrong_state, lt, a3, Operand(zero_reg));
-
   // Load suspended function and context.
   __ lw(cp, FieldMemOperand(a1, JSGeneratorObject::kContextOffset));
   __ lw(t0, FieldMemOperand(a1, JSGeneratorObject::kFunctionOffset));
@@ -2186,7 +2207,7 @@
 
   // Enter a new JavaScript frame, and initialize its slots as they were when
   // the generator was suspended.
-  Label resume_frame;
+  Label resume_frame, done;
   __ bind(&push_frame);
   __ Call(&resume_frame);
   __ jmp(&done);
@@ -2235,26 +2256,6 @@
   // Not reached: the runtime call returns elsewhere.
   __ stop("not-reached");
 
-  // Reach here when generator is closed.
-  __ bind(&closed_state);
-  if (resume_mode == JSGeneratorObject::NEXT) {
-    // Return completed iterator result when generator is closed.
-    __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
-    __ push(a2);
-    // Pop value from top-of-stack slot; box result into result register.
-    EmitCreateIteratorResult(true);
-  } else {
-    // Throw the provided value.
-    __ push(a0);
-    __ CallRuntime(Runtime::kThrow, 1);
-  }
-  __ jmp(&done);
-
-  // Throw error if we attempt to operate on a running generator.
-  __ bind(&wrong_state);
-  __ push(a1);
-  __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
-
   __ bind(&done);
   context()->Plug(result_register());
 }
@@ -2302,11 +2303,12 @@
 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
+  DCHECK(!prop->IsSuperAccess());
 
   __ li(LoadDescriptor::NameRegister(), Operand(key->value()));
   if (FLAG_vector_ics) {
     __ li(VectorLoadICDescriptor::SlotRegister(),
-          Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
+          Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
     CallLoadIC(NOT_CONTEXTUAL);
   } else {
     CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
@@ -2315,15 +2317,12 @@
 
 
 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object.
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
   DCHECK(!key->value()->IsSmi());
   DCHECK(prop->IsSuperAccess());
 
-  SuperReference* super_ref = prop->obj()->AsSuperReference();
-  EmitLoadHomeObject(super_ref);
-  __ Push(v0);
-  VisitForStackValue(super_ref->this_var());
   __ Push(key->value());
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 }
@@ -2334,7 +2333,7 @@
   Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
   if (FLAG_vector_ics) {
     __ li(VectorLoadICDescriptor::SlotRegister(),
-          Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
+          Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
     CallIC(ic);
   } else {
     CallIC(ic, prop->PropertyFeedbackId());
@@ -2342,6 +2341,14 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object, key.
+  SetSourcePosition(prop->position());
+
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+}
+
+
 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
                                               Token::Value op,
                                               OverwriteMode mode,
@@ -2435,6 +2442,63 @@
 }
 
 
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
+  // Constructor is in v0.
+  DCHECK(lit != NULL);
+  __ push(v0);
+
+  // No access check is needed here since the constructor is created by the
+  // class literal.
+  Register scratch = a1;
+  __ lw(scratch,
+        FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset));
+  __ push(scratch);
+
+  for (int i = 0; i < lit->properties()->length(); i++) {
+    ObjectLiteral::Property* property = lit->properties()->at(i);
+    Literal* key = property->key()->AsLiteral();
+    Expression* value = property->value();
+    DCHECK(key != NULL);
+
+    if (property->is_static()) {
+      __ lw(scratch, MemOperand(sp, kPointerSize));  // constructor
+    } else {
+      __ lw(scratch, MemOperand(sp, 0));  // prototype
+    }
+    __ push(scratch);
+    VisitForStackValue(key);
+    VisitForStackValue(value);
+    EmitSetHomeObjectIfNeeded(value, 2);
+
+    switch (property->kind()) {
+      case ObjectLiteral::Property::CONSTANT:
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+      case ObjectLiteral::Property::COMPUTED:
+      case ObjectLiteral::Property::PROTOTYPE:
+        __ CallRuntime(Runtime::kDefineClassMethod, 3);
+        break;
+
+      case ObjectLiteral::Property::GETTER:
+        __ CallRuntime(Runtime::kDefineClassGetter, 3);
+        break;
+
+      case ObjectLiteral::Property::SETTER:
+        __ CallRuntime(Runtime::kDefineClassSetter, 3);
+        break;
+
+      default:
+        UNREACHABLE();
+    }
+  }
+
+  // prototype
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+
+  // constructor
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+}
+
+
 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
                                      Token::Value op,
                                      OverwriteMode mode) {
@@ -2451,16 +2515,8 @@
 void FullCodeGenerator::EmitAssignment(Expression* expr) {
   DCHECK(expr->IsValidReferenceExpression());
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->AsProperty();
-  if (prop != NULL) {
-    assign_type = (prop->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   switch (assign_type) {
     case VARIABLE: {
@@ -2479,6 +2535,42 @@
       CallStoreIC();
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      __ Push(v0);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      // stack: value, this; v0: home_object
+      Register scratch = a2;
+      Register scratch2 = a3;
+      __ mov(scratch, result_register());             // home_object
+      __ lw(v0, MemOperand(sp, kPointerSize));        // value
+      __ lw(scratch2, MemOperand(sp, 0));             // this
+      __ sw(scratch2, MemOperand(sp, kPointerSize));  // this
+      __ sw(scratch, MemOperand(sp, 0));              // home_object
+      // stack: this, home_object; v0: value
+      EmitNamedSuperPropertyStore(prop);
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      __ Push(v0);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(prop->key());
+      Register scratch = a2;
+      Register scratch2 = a3;
+      __ lw(scratch2, MemOperand(sp, 2 * kPointerSize));  // value
+      // stack: value, this, home_object; v0: key, a3: value
+      __ lw(scratch, MemOperand(sp, kPointerSize));  // this
+      __ sw(scratch, MemOperand(sp, 2 * kPointerSize));
+      __ lw(scratch, MemOperand(sp, 0));  // home_object
+      __ sw(scratch, MemOperand(sp, kPointerSize));
+      __ sw(v0, MemOperand(sp, 0));
+      __ Move(v0, scratch2);
+      // stack: this, home_object, key; v0: value.
+      EmitKeyedSuperPropertyStore(prop);
+      break;
+    }
     case KEYED_PROPERTY: {
       __ push(result_register());  // Preserve value.
       VisitForStackValue(prop->obj());
@@ -2550,7 +2642,6 @@
     // Perform the assignment.
     __ bind(&assign);
     EmitStoreToStackLocalOrContextSlot(var, location);
-
   } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
     if (var->IsLookupSlot()) {
       // Assignment to var.
@@ -2571,8 +2662,9 @@
       }
       EmitStoreToStackLocalOrContextSlot(var, location);
     }
+  } else if (IsSignallingAssignmentToConst(var, op, strict_mode())) {
+    __ CallRuntime(Runtime::kThrowConstAssignError, 0);
   }
-  // Non-initializing assignments to consts are ignored.
 }
 
 
@@ -2595,6 +2687,35 @@
 }
 
 
+void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // v0 : value
+  // stack : receiver ('this'), home_object
+  DCHECK(prop != NULL);
+  Literal* key = prop->key()->AsLiteral();
+  DCHECK(key != NULL);
+
+  __ Push(key->value());
+  __ Push(v0);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
+                                          : Runtime::kStoreToSuper_Sloppy),
+                 4);
+}
+
+
+void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // v0 : value
+  // stack : receiver ('this'), home_object, key
+  DCHECK(prop != NULL);
+
+  __ Push(v0);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict
+                                          : Runtime::kStoreKeyedToSuper_Sloppy),
+                 4);
+}
+
+
 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
   // Assignment to a property, using a keyed store IC.
 
@@ -2627,16 +2748,27 @@
       __ Move(LoadDescriptor::ReceiverRegister(), v0);
       EmitNamedPropertyLoad(expr);
     } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ Push(result_register());
       EmitNamedSuperPropertyLoad(expr);
     }
     PrepareForBailoutForId(expr->LoadId(), TOS_REG);
     context()->Plug(v0);
   } else {
-    VisitForStackValue(expr->obj());
-    VisitForAccumulatorValue(expr->key());
-    __ Move(LoadDescriptor::NameRegister(), v0);
-    __ pop(LoadDescriptor::ReceiverRegister());
-    EmitKeyedPropertyLoad(expr);
+    if (!expr->IsSuperAccess()) {
+      VisitForStackValue(expr->obj());
+      VisitForAccumulatorValue(expr->key());
+      __ Move(LoadDescriptor::NameRegister(), v0);
+      __ pop(LoadDescriptor::ReceiverRegister());
+      EmitKeyedPropertyLoad(expr);
+    } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForStackValue(expr->key());
+      EmitKeyedSuperPropertyLoad(expr);
+    }
     context()->Plug(v0);
   }
 }
@@ -2695,18 +2827,16 @@
   const Register scratch = a1;
   SuperReference* super_ref = prop->obj()->AsSuperReference();
   EmitLoadHomeObject(super_ref);
-  __ Push(v0);
+  __ mov(scratch, v0);
   VisitForAccumulatorValue(super_ref->this_var());
-  __ Push(v0);
-  __ lw(scratch, MemOperand(sp, kPointerSize));
-  __ Push(scratch, v0);
+  __ Push(scratch, v0, v0, scratch);
   __ Push(key->value());
 
   // Stack here:
   //  - home_object
   //  - this (receiver)
-  //  - home_object <-- LoadFromSuper will pop here and below.
-  //  - this (receiver)
+  //  - this (receiver) <-- LoadFromSuper will pop here and below.
+  //  - home_object
   //  - key
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 
@@ -2744,6 +2874,40 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
+  Expression* callee = expr->expression();
+  DCHECK(callee->IsProperty());
+  Property* prop = callee->AsProperty();
+  DCHECK(prop->IsSuperAccess());
+
+  SetSourcePosition(prop->position());
+  // Load the function from the receiver.
+  const Register scratch = a1;
+  SuperReference* super_ref = prop->obj()->AsSuperReference();
+  EmitLoadHomeObject(super_ref);
+  __ Move(scratch, v0);
+  VisitForAccumulatorValue(super_ref->this_var());
+  __ Push(scratch, v0, v0, scratch);
+  VisitForStackValue(prop->key());
+
+  // Stack here:
+  //  - home_object
+  //  - this (receiver)
+  //  - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
+  //  - home_object
+  //  - key
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+
+  // Replace home_object with target function.
+  __ sw(v0, MemOperand(sp, kPointerSize));
+
+  // Stack here:
+  // - target function
+  // - this (receiver)
+  EmitCall(expr, CallICState::METHOD);
+}
+
+
 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Load the arguments.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2758,7 +2922,7 @@
   SetSourcePosition(expr->position());
   Handle<Code> ic = CallIC::initialize_stub(
       isolate(), arg_count, call_type);
-  __ li(a3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
+  __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackSlot())));
   __ lw(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
   // Don't assign a type feedback id to the IC, since type feedback is provided
   // by the vector above.
@@ -2799,6 +2963,14 @@
 }
 
 
+void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
+  DCHECK(super_ref != NULL);
+  __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ Push(a0);
+  __ CallRuntime(Runtime::kGetPrototype, 1);
+}
+
+
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -2838,6 +3010,8 @@
       // v1 (receiver). Touch up the stack with the right values.
       __ sw(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
       __ sw(v1, MemOperand(sp, arg_count * kPointerSize));
+
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
     // Record source position for debugger.
     SetSourcePosition(expr->position());
@@ -2869,6 +3043,7 @@
     __ Push(context_register(), a2);
     __ CallRuntime(Runtime::kLoadLookupSlot, 2);
     __ Push(v0, v1);  // Function, receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
 
     // If fast case code has been generated, emit code to push the
     // function and receiver and have the slow path jump around this
@@ -2892,9 +3067,12 @@
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
     bool is_named_call = property->key()->IsPropertyName();
-    // super.x() is handled in EmitCallWithLoadIC.
-    if (property->IsSuperAccess() && is_named_call) {
-      EmitSuperCallWithLoadIC(expr);
+    if (property->IsSuperAccess()) {
+      if (is_named_call) {
+        EmitSuperCallWithLoadIC(expr);
+      } else {
+        EmitKeyedSuperCallWithLoadIC(expr);
+      }
     } else {
       {
         PreservePositionScope scope(masm()->positions_recorder());
@@ -2906,6 +3084,12 @@
         EmitKeyedCallWithLoadIC(expr, property->key());
       }
     }
+  } else if (call_type == Call::SUPER_CALL) {
+    SuperReference* super_ref = callee->AsSuperReference();
+    EmitLoadSuperConstructor(super_ref);
+    __ Push(result_register());
+    VisitForStackValue(super_ref->this_var());
+    EmitCall(expr, CallICState::METHOD);
   } else {
     DCHECK(call_type == Call::OTHER_CALL);
     // Call to an arbitrary expression not handled specially above.
@@ -2934,7 +3118,12 @@
   // Push constructor on the stack.  If it's not a function it's used as
   // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
   // ignored.
-  VisitForStackValue(expr->expression());
+  if (expr->expression()->IsSuperReference()) {
+    EmitLoadSuperConstructor(expr->expression()->AsSuperReference());
+    __ Push(result_register());
+  } else {
+    VisitForStackValue(expr->expression());
+  }
 
   // Push the arguments ("left-to-right") on the stack.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2954,12 +3143,12 @@
   // Record call targets in unoptimized code.
   if (FLAG_pretenuring_call_new) {
     EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
-    DCHECK(expr->AllocationSiteFeedbackSlot() ==
-           expr->CallNewFeedbackSlot() + 1);
+    DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
+           expr->CallNewFeedbackSlot().ToInt() + 1);
   }
 
   __ li(a2, FeedbackVector());
-  __ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
+  __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
 
   CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
   __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
@@ -3274,6 +3463,32 @@
 }
 
 
+void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(v0, if_false);
+  Register map = a1;
+  Register type_reg = a2;
+  __ GetObjectType(v0, map, type_reg);
+  __ Subu(type_reg, type_reg, Operand(FIRST_JS_PROXY_TYPE));
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(ls, type_reg, Operand(LAST_JS_PROXY_TYPE - FIRST_JS_PROXY_TYPE),
+        if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
   DCHECK(expr->arguments()->length() == 0);
 
@@ -4191,7 +4406,7 @@
     __ li(LoadDescriptor::NameRegister(), Operand(expr->name()));
     if (FLAG_vector_ics) {
       __ li(VectorLoadICDescriptor::SlotRegister(),
-            Operand(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
+            Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
       CallLoadIC(NOT_CONTEXTUAL);
     } else {
       CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
@@ -4347,17 +4562,8 @@
   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());
 
-  // Expression can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
-  // In case of a property we use the uninitialized expression context
-  // of the key to detect a named property.
-  if (prop != NULL) {
-    assign_type =
-        (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   // Evaluate expression and get value.
   if (assign_type == VARIABLE) {
@@ -4370,18 +4576,52 @@
       __ li(at, Operand(Smi::FromInt(0)));
       __ push(at);
     }
-    if (assign_type == NAMED_PROPERTY) {
-      // Put the object both on the stack and in the register.
-      VisitForStackValue(prop->obj());
-      __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
-      EmitNamedPropertyLoad(prop);
-    } else {
-      VisitForStackValue(prop->obj());
-      VisitForStackValue(prop->key());
-      __ lw(LoadDescriptor::ReceiverRegister(),
-            MemOperand(sp, 1 * kPointerSize));
-      __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
-      EmitKeyedPropertyLoad(prop);
+    switch (assign_type) {
+      case NAMED_PROPERTY: {
+        // Put the object both on the stack and in the register.
+        VisitForStackValue(prop->obj());
+        __ lw(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
+        EmitNamedPropertyLoad(prop);
+        break;
+      }
+
+      case NAMED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        const Register scratch = a1;
+        __ lw(scratch, MemOperand(sp, kPointerSize));
+        __ Push(scratch, result_register());
+        EmitNamedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        const Register scratch = a1;
+        const Register scratch1 = t0;
+        __ Move(scratch, result_register());
+        VisitForAccumulatorValue(prop->key());
+        __ Push(scratch, result_register());
+        __ lw(scratch1, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch1, scratch, result_register());
+        EmitKeyedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_PROPERTY: {
+        VisitForStackValue(prop->obj());
+        VisitForStackValue(prop->key());
+        __ lw(LoadDescriptor::ReceiverRegister(),
+              MemOperand(sp, 1 * kPointerSize));
+        __ lw(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
+        EmitKeyedPropertyLoad(prop);
+        break;
+      }
+
+      case VARIABLE:
+        UNREACHABLE();
     }
   }
 
@@ -4416,9 +4656,15 @@
           case NAMED_PROPERTY:
             __ sw(v0, MemOperand(sp, kPointerSize));
             break;
+          case NAMED_SUPER_PROPERTY:
+            __ sw(v0, MemOperand(sp, 2 * kPointerSize));
+            break;
           case KEYED_PROPERTY:
             __ sw(v0, MemOperand(sp, 2 * kPointerSize));
             break;
+          case KEYED_SUPER_PROPERTY:
+            __ sw(v0, MemOperand(sp, 3 * kPointerSize));
+            break;
         }
       }
     }
@@ -4449,9 +4695,15 @@
         case NAMED_PROPERTY:
           __ sw(v0, MemOperand(sp, kPointerSize));
           break;
+        case NAMED_SUPER_PROPERTY:
+          __ sw(v0, MemOperand(sp, 2 * kPointerSize));
+          break;
         case KEYED_PROPERTY:
           __ sw(v0, MemOperand(sp, 2 * kPointerSize));
           break;
+        case KEYED_SUPER_PROPERTY:
+          __ sw(v0, MemOperand(sp, 3 * kPointerSize));
+          break;
       }
     }
   }
@@ -4507,6 +4759,28 @@
       }
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      EmitNamedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(v0);
+      }
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      EmitKeyedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(v0);
+      }
+      break;
+    }
     case KEYED_PROPERTY: {
       __ mov(StoreDescriptor::ValueRegister(), result_register());
       __ Pop(StoreDescriptor::ReceiverRegister(),
@@ -4538,7 +4812,7 @@
     __ li(LoadDescriptor::NameRegister(), Operand(proxy->name()));
     if (FLAG_vector_ics) {
       __ li(VectorLoadICDescriptor::SlotRegister(),
-            Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
+            Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
     }
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
@@ -4768,7 +5042,7 @@
 
 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
   Scope* declaration_scope = scope()->DeclarationScope();
-  if (declaration_scope->is_global_scope() ||
+  if (declaration_scope->is_script_scope() ||
       declaration_scope->is_module_scope()) {
     // Contexts nested in the native context have a canonical empty function
     // as their closure, not the anonymous closure containing the global
diff --git a/src/mips/interface-descriptors-mips.cc b/src/mips/interface-descriptors-mips.cc
index 936ce20..ecdaecf 100644
--- a/src/mips/interface-descriptors-mips.cc
+++ b/src/mips/interface-descriptors-mips.cc
@@ -29,6 +29,9 @@
 const Register StoreDescriptor::ValueRegister() { return a0; }
 
 
+const Register StoreTransitionDescriptor::MapRegister() { return a3; }
+
+
 const Register ElementTransitionAndStoreDescriptor::MapRegister() { return a3; }
 
 
@@ -149,6 +152,15 @@
 }
 
 
+void AllocateHeapNumberDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  // register state
+  // cp -- context
+  Register registers[] = {cp};
+  data->Initialize(arraysize(registers), registers, nullptr);
+}
+
+
 void ArrayConstructorConstantArgCountDescriptor::Initialize(
     CallInterfaceDescriptorData* data) {
   // register state
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 497d10f..cdc68c8 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -51,9 +51,9 @@
         deopt_mode_(mode) { }
   virtual ~SafepointGenerator() {}
 
-  virtual void BeforeCall(int call_size) const OVERRIDE {}
+  void BeforeCall(int call_size) const OVERRIDE {}
 
-  virtual void AfterCall() const OVERRIDE {
+  void AfterCall() const OVERRIDE {
     codegen_->RecordSafepoint(pointers_, deopt_mode_);
   }
 
@@ -816,8 +816,8 @@
 
 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
                             Deoptimizer::BailoutType bailout_type,
-                            Register src1, const Operand& src2,
-                            const char* detail) {
+                            const char* detail, Register src1,
+                            const Operand& src2) {
   LEnvironment* environment = instr->environment();
   RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
   DCHECK(environment->HasBeenRegistered());
@@ -882,12 +882,12 @@
 
 
 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
-                            Register src1, const Operand& src2,
-                            const char* detail) {
+                            const char* detail, Register src1,
+                            const Operand& src2) {
   Deoptimizer::BailoutType bailout_type = info()->IsStub()
       ? Deoptimizer::LAZY
       : Deoptimizer::EAGER;
-  DeoptimizeIf(condition, instr, bailout_type, src1, src2, detail);
+  DeoptimizeIf(condition, instr, bailout_type, detail, src1, src2);
 }
 
 
@@ -1117,7 +1117,7 @@
     __ subu(dividend, zero_reg, dividend);
     __ And(dividend, dividend, Operand(mask));
     if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
+      DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg));
     }
     __ Branch(USE_DELAY_SLOT, &done);
     __ subu(dividend, zero_reg, dividend);
@@ -1149,7 +1149,7 @@
   if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label remainder_not_zero;
     __ Branch(&remainder_not_zero, ne, result, Operand(zero_reg));
-    DeoptimizeIf(lt, instr, dividend, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "minus zero", dividend, Operand(zero_reg));
     __ bind(&remainder_not_zero);
   }
 }
@@ -1168,7 +1168,7 @@
   // Check for x % 0, we have to deopt in this case because we can't return a
   // NaN.
   if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
-    DeoptimizeIf(eq, instr, right_reg, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "division by zero", right_reg, Operand(zero_reg));
   }
 
   // Check for kMinInt % -1, div will return kMinInt, which is not what we
@@ -1177,7 +1177,7 @@
     Label no_overflow_possible;
     __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt));
     if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      DeoptimizeIf(eq, instr, right_reg, Operand(-1));
+      DeoptimizeIf(eq, instr, "minus zero", right_reg, Operand(-1));
     } else {
       __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1));
       __ Branch(USE_DELAY_SLOT, &done);
@@ -1189,7 +1189,7 @@
   // If we care about -0, test if the dividend is <0 and the result is 0.
   __ Branch(&done, ge, left_reg, Operand(zero_reg));
   if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    DeoptimizeIf(eq, instr, result_reg, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "minus zero", result_reg, Operand(zero_reg));
   }
   __ bind(&done);
 }
@@ -1205,18 +1205,18 @@
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
-    DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg));
   }
   // Check for (kMinInt / -1).
   if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
-    DeoptimizeIf(eq, instr, dividend, Operand(kMinInt));
+    DeoptimizeIf(eq, instr, "overflow", dividend, Operand(kMinInt));
   }
   // Deoptimize if remainder will not be 0.
   if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
       divisor != 1 && divisor != -1) {
     int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
     __ And(at, dividend, Operand(mask));
-    DeoptimizeIf(ne, instr, at, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "lost precision", at, Operand(zero_reg));
   }
 
   if (divisor == -1) {  // Nice shortcut, not needed for correctness.
@@ -1253,7 +1253,7 @@
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
-    DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg));
   }
 
   __ TruncatingDiv(result, dividend, Abs(divisor));
@@ -1262,7 +1262,7 @@
   if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
     __ Mul(scratch0(), result, Operand(divisor));
     __ Subu(scratch0(), scratch0(), dividend);
-    DeoptimizeIf(ne, instr, scratch0(), Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "lost precision", scratch0(), Operand(zero_reg));
   }
 }
 
@@ -1281,14 +1281,14 @@
 
   // Check for x / 0.
   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
-    DeoptimizeIf(eq, instr, divisor, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "division by zero", divisor, Operand(zero_reg));
   }
 
   // Check for (0 / -x) that will produce negative zero.
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label left_not_zero;
     __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg));
-    DeoptimizeIf(lt, instr, divisor, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "minus zero", divisor, Operand(zero_reg));
     __ bind(&left_not_zero);
   }
 
@@ -1297,12 +1297,12 @@
       !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     Label left_not_min_int;
     __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt));
-    DeoptimizeIf(eq, instr, divisor, Operand(-1));
+    DeoptimizeIf(eq, instr, "overflow", divisor, Operand(-1));
     __ bind(&left_not_min_int);
   }
 
   if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
-    DeoptimizeIf(ne, instr, remainder, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "lost precision", remainder, Operand(zero_reg));
   }
 }
 
@@ -1348,14 +1348,14 @@
 
   __ Subu(result, zero_reg, dividend);
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    DeoptimizeIf(eq, instr, result, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "minus zero", result, Operand(zero_reg));
   }
 
   // Dividing by -1 is basically negation, unless we overflow.
   __ Xor(scratch, scratch, result);
   if (divisor == -1) {
     if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
-      DeoptimizeIf(ge, instr, scratch, Operand(zero_reg));
+      DeoptimizeIf(ge, instr, "overflow", scratch, Operand(zero_reg));
     }
     return;
   }
@@ -1390,7 +1390,7 @@
   // Check for (0 / -x) that will produce negative zero.
   HMathFloorOfDiv* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
-    DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg));
   }
 
   // Easy case: We need no dynamic check for the dividend and the flooring
@@ -1434,14 +1434,14 @@
 
   // Check for x / 0.
   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
-    DeoptimizeIf(eq, instr, divisor, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "division by zero", divisor, Operand(zero_reg));
   }
 
   // Check for (0 / -x) that will produce negative zero.
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label left_not_zero;
     __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg));
-    DeoptimizeIf(lt, instr, divisor, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "minus zero", divisor, Operand(zero_reg));
     __ bind(&left_not_zero);
   }
 
@@ -1450,7 +1450,7 @@
       !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     Label left_not_min_int;
     __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt));
-    DeoptimizeIf(eq, instr, divisor, Operand(-1));
+    DeoptimizeIf(eq, instr, "overflow", divisor, Operand(-1));
     __ bind(&left_not_min_int);
   }
 
@@ -1481,14 +1481,14 @@
     if (bailout_on_minus_zero && (constant < 0)) {
       // The case of a null constant will be handled separately.
       // If constant is negative and left is null, the result should be -0.
-      DeoptimizeIf(eq, instr, left, Operand(zero_reg));
+      DeoptimizeIf(eq, instr, "minus zero", left, Operand(zero_reg));
     }
 
     switch (constant) {
       case -1:
         if (overflow) {
           __ SubuAndCheckForOverflow(result, zero_reg, left, scratch);
-          DeoptimizeIf(lt, instr, scratch, Operand(zero_reg));
+          DeoptimizeIf(lt, instr, "overflow", scratch, Operand(zero_reg));
         } else {
           __ Subu(result, zero_reg, left);
         }
@@ -1497,7 +1497,7 @@
         if (bailout_on_minus_zero) {
           // If left is strictly negative and the constant is null, the
           // result is -0. Deoptimize if required, otherwise return 0.
-          DeoptimizeIf(lt, instr, left, Operand(zero_reg));
+          DeoptimizeIf(lt, instr, "minus zero", left, Operand(zero_reg));
         }
         __ mov(result, zero_reg);
         break;
@@ -1549,7 +1549,7 @@
         __ Mul(scratch, result, left, right);
       }
       __ sra(at, result, 31);
-      DeoptimizeIf(ne, instr, scratch, Operand(at));
+      DeoptimizeIf(ne, instr, "overflow", scratch, Operand(at));
     } else {
       if (instr->hydrogen()->representation().IsSmi()) {
         __ SmiUntag(result, left);
@@ -1564,7 +1564,7 @@
       __ Xor(at, left, right);
       __ Branch(&done, ge, at, Operand(zero_reg));
       // Bail out if the result is minus zero.
-      DeoptimizeIf(eq, instr, result, Operand(zero_reg));
+      DeoptimizeIf(eq, instr, "minus zero", result, Operand(zero_reg));
       __ bind(&done);
     }
   }
@@ -1628,7 +1628,7 @@
       case Token::SHR:
         __ srlv(result, left, ToRegister(right_op));
         if (instr->can_deopt()) {
-          DeoptimizeIf(lt, instr, result, Operand(zero_reg));
+          DeoptimizeIf(lt, instr, "negative value", result, Operand(zero_reg));
         }
         break;
       case Token::SHL:
@@ -1663,7 +1663,7 @@
         } else {
           if (instr->can_deopt()) {
             __ And(at, left, Operand(0x80000000));
-            DeoptimizeIf(ne, instr, at, Operand(zero_reg));
+            DeoptimizeIf(ne, instr, "negative value", at, Operand(zero_reg));
           }
           __ Move(result, left);
         }
@@ -1678,7 +1678,7 @@
             } else {
               __ SmiTagCheckOverflow(result, left, scratch);
             }
-            DeoptimizeIf(lt, instr, scratch, Operand(zero_reg));
+            DeoptimizeIf(lt, instr, "overflow", scratch, Operand(zero_reg));
           } else {
             __ sll(result, left, shift_count);
           }
@@ -1726,7 +1726,7 @@
                                  ToRegister(right),
                                  overflow);  // Reg at also used as scratch.
     }
-    DeoptimizeIf(lt, instr, overflow, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "overflow", overflow, Operand(zero_reg));
   }
 }
 
@@ -1780,9 +1780,9 @@
   DCHECK(!scratch.is(object));
 
   __ SmiTst(object, at);
-  DeoptimizeIf(eq, instr, at, Operand(zero_reg));
+  DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg));
   __ GetObjectType(object, scratch, scratch);
-  DeoptimizeIf(ne, instr, scratch, Operand(JS_DATE_TYPE));
+  DeoptimizeIf(ne, instr, "not a date object", scratch, Operand(JS_DATE_TYPE));
 
   if (index->value() == 0) {
     __ lw(result, FieldMemOperand(object, JSDate::kValueOffset));
@@ -1917,7 +1917,7 @@
                                  ToRegister(right),
                                  overflow);  // Reg at also used as scratch.
     }
-    DeoptimizeIf(lt, instr, overflow, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "overflow", overflow, Operand(zero_reg));
   }
 }
 
@@ -2178,7 +2178,7 @@
       } else if (expected.NeedsMap()) {
         // If we need a map later and have a Smi -> deopt.
         __ SmiTst(reg, at);
-        DeoptimizeIf(eq, instr, at, Operand(zero_reg));
+        DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg));
       }
 
       const Register map = scratch0();
@@ -2234,7 +2234,8 @@
       if (!expected.IsGeneric()) {
         // We've seen something for the first time -> deopt.
         // This can only happen if we are not generic already.
-        DeoptimizeIf(al, instr, zero_reg, Operand(zero_reg));
+        DeoptimizeIf(al, instr, "unexpected object", zero_reg,
+                     Operand(zero_reg));
       }
     }
   }
@@ -2694,10 +2695,10 @@
     DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
                                   LInstanceOfKnownGlobal* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
     Label* map_check() { return &map_check_; }
 
    private:
@@ -2857,6 +2858,7 @@
       __ Addu(sp, sp, Operand(sp_delta));
     }
   } else {
+    DCHECK(info()->IsStub());  // Functions would need to drop one more value.
     Register reg = ToRegister(instr->parameter_count());
     // The argument count parameter is a smi
     __ SmiUntag(reg);
@@ -2878,7 +2880,7 @@
   __ lw(result, FieldMemOperand(at, Cell::kValueOffset));
   if (instr->hydrogen()->RequiresHoleCheck()) {
     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
-    DeoptimizeIf(eq, instr, result, Operand(at));
+    DeoptimizeIf(eq, instr, "hole", result, Operand(at));
   }
 }
 
@@ -2886,13 +2888,18 @@
 template <class T>
 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
   DCHECK(FLAG_vector_ics);
-  Register vector = ToRegister(instr->temp_vector());
-  DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister()));
-  __ li(vector, instr->hydrogen()->feedback_vector());
+  Register vector_register = ToRegister(instr->temp_vector());
+  Register slot_register = VectorLoadICDescriptor::SlotRegister();
+  DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
+  DCHECK(slot_register.is(a0));
+
+  AllowDeferredHandleDereference vector_structure_check;
+  Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
+  __ li(vector_register, vector);
   // No need to allocate this register.
-  DCHECK(VectorLoadICDescriptor::SlotRegister().is(a0));
-  __ li(VectorLoadICDescriptor::SlotRegister(),
-        Operand(Smi::FromInt(instr->hydrogen()->slot())));
+  FeedbackVectorICSlot slot = instr->hydrogen()->slot();
+  int index = vector->GetIndex(slot);
+  __ li(slot_register, Operand(Smi::FromInt(index)));
 }
 
 
@@ -2907,7 +2914,7 @@
     EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
+  Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -2928,7 +2935,7 @@
     Register payload = ToRegister(instr->temp());
     __ lw(payload, FieldMemOperand(cell, Cell::kValueOffset));
     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
-    DeoptimizeIf(eq, instr, payload, Operand(at));
+    DeoptimizeIf(eq, instr, "hole", payload, Operand(at));
   }
 
   // Store the value.
@@ -2947,7 +2954,7 @@
     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
 
     if (instr->hydrogen()->DeoptimizesOnHole()) {
-      DeoptimizeIf(eq, instr, result, Operand(at));
+      DeoptimizeIf(eq, instr, "hole", result, Operand(at));
     } else {
       Label is_not_hole;
       __ Branch(&is_not_hole, ne, result, Operand(at));
@@ -2971,7 +2978,7 @@
     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
 
     if (instr->hydrogen()->DeoptimizesOnHole()) {
-      DeoptimizeIf(eq, instr, scratch, Operand(at));
+      DeoptimizeIf(eq, instr, "hole", scratch, Operand(at));
     } else {
       __ Branch(&skip_assignment, ne, scratch, Operand(at));
     }
@@ -3034,7 +3041,8 @@
   if (FLAG_vector_ics) {
     EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
+  Handle<Code> ic =
+      CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3050,7 +3058,7 @@
 
   // Check that the function has a prototype or an initial map.
   __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
-  DeoptimizeIf(eq, instr, result, Operand(at));
+  DeoptimizeIf(eq, instr, "hole", result, Operand(at));
 
   // If the function does not have an initial map, we're done.
   Label done;
@@ -3186,7 +3194,8 @@
       case UINT32_ELEMENTS:
         __ lw(result, mem_operand);
         if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
-          DeoptimizeIf(Ugreater_equal, instr, result, Operand(0x80000000));
+          DeoptimizeIf(Ugreater_equal, instr, "negative value", result,
+                       Operand(0x80000000));
         }
         break;
       case FLOAT32_ELEMENTS:
@@ -3239,7 +3248,7 @@
 
   if (instr->hydrogen()->RequiresHoleCheck()) {
     __ lw(scratch, MemOperand(scratch, kHoleNanUpper32Offset));
-    DeoptimizeIf(eq, instr, scratch, Operand(kHoleNanUpper32));
+    DeoptimizeIf(eq, instr, "hole", scratch, Operand(kHoleNanUpper32));
   }
 }
 
@@ -3275,10 +3284,10 @@
   if (instr->hydrogen()->RequiresHoleCheck()) {
     if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
       __ SmiTst(result, scratch);
-      DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
+      DeoptimizeIf(ne, instr, "not a Smi", scratch, Operand(zero_reg));
     } else {
       __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
-      DeoptimizeIf(eq, instr, result, Operand(scratch));
+      DeoptimizeIf(eq, instr, "hole", result, Operand(scratch));
     }
   }
 }
@@ -3341,7 +3350,7 @@
     EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
-  Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
+  Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3424,10 +3433,11 @@
 
   // Deoptimize if the receiver is not a JS object.
   __ SmiTst(receiver, scratch);
-  DeoptimizeIf(eq, instr, scratch, Operand(zero_reg));
+  DeoptimizeIf(eq, instr, "Smi", scratch, Operand(zero_reg));
 
   __ GetObjectType(receiver, scratch, scratch);
-  DeoptimizeIf(lt, instr, scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
+  DeoptimizeIf(lt, instr, "not a JavaScript object", scratch,
+               Operand(FIRST_SPEC_OBJECT_TYPE));
 
   __ Branch(&result_in_receiver);
   __ bind(&global_object);
@@ -3462,7 +3472,8 @@
   // Copy the arguments to this function possibly from the
   // adaptor frame below it.
   const uint32_t kArgumentsLimit = 1 * KB;
-  DeoptimizeIf(hi, instr, length, Operand(kArgumentsLimit));
+  DeoptimizeIf(hi, instr, "too many arguments", length,
+               Operand(kArgumentsLimit));
 
   // Push the receiver and use the register to keep the original
   // number of arguments.
@@ -3592,7 +3603,7 @@
   // Deoptimize if not a heap number.
   __ lw(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
   __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
-  DeoptimizeIf(ne, instr, scratch, Operand(at));
+  DeoptimizeIf(ne, instr, "not a heap number", scratch, Operand(at));
 
   Label done;
   Register exponent = scratch0();
@@ -3659,7 +3670,7 @@
   __ mov(result, input);
   __ subu(result, zero_reg, input);
   // Overflow if result is still negative, i.e. 0x80000000.
-  DeoptimizeIf(lt, instr, result, Operand(zero_reg));
+  DeoptimizeIf(lt, instr, "overflow", result, Operand(zero_reg));
   __ bind(&done);
 }
 
@@ -3670,10 +3681,11 @@
    public:
     DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LMathAbs* instr_;
   };
@@ -3713,7 +3725,8 @@
                      except_flag);
 
   // Deopt if the operation did not succeed.
-  DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
+  DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag,
+               Operand(zero_reg));
 
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     // Test for -0.
@@ -3721,7 +3734,7 @@
     __ Branch(&done, ne, result, Operand(zero_reg));
     __ Mfhc1(scratch1, input);
     __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
-    DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg));
     __ bind(&done);
   }
 }
@@ -3754,7 +3767,8 @@
 
   // The following conversion will not work with numbers
   // outside of ]-2^32, 2^32[.
-  DeoptimizeIf(ge, instr, scratch, Operand(HeapNumber::kExponentBias + 32));
+  DeoptimizeIf(ge, instr, "overflow", scratch,
+               Operand(HeapNumber::kExponentBias + 32));
 
   // Save the original sign for later comparison.
   __ And(scratch, result, Operand(HeapNumber::kSignMask));
@@ -3768,7 +3782,7 @@
   __ Xor(result, result, Operand(scratch));
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     // ARM uses 'mi' here, which is 'lt'
-    DeoptimizeIf(lt, instr, result, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "minus zero", result, Operand(zero_reg));
   } else {
     Label skip2;
     // ARM uses 'mi' here, which is 'lt'
@@ -3787,7 +3801,8 @@
                      double_scratch1,
                      except_flag);
 
-  DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
+  DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag,
+               Operand(zero_reg));
 
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     // Test for -0.
@@ -3795,7 +3810,7 @@
     __ bind(&check_sign_on_zero);
     __ Mfhc1(scratch, input);
     __ And(scratch, scratch, Operand(HeapNumber::kSignMask));
-    DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "minus zero", scratch, Operand(zero_reg));
   }
   __ bind(&done);
 }
@@ -3827,7 +3842,7 @@
   // Math.pow(-Infinity, 0.5) == Infinity
   // Math.sqrt(-Infinity) == NaN
   Label done;
-  __ Move(temp, -V8_INFINITY);
+  __ Move(temp, static_cast<double>(-V8_INFINITY));
   __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input);
   // Set up Infinity in the delay slot.
   // result is overwritten if the branch is not taken.
@@ -3861,7 +3876,7 @@
     DCHECK(!t3.is(tagged_exponent));
     __ lw(t3, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset));
     __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
-    DeoptimizeIf(ne, instr, t3, Operand(at));
+    DeoptimizeIf(ne, instr, "not a heap number", t3, Operand(at));
     __ bind(&no_deopt);
     MathPowStub stub(isolate(), MathPowStub::TAGGED);
     __ CallStub(&stub);
@@ -3936,44 +3951,73 @@
   DCHECK(receiver.is(a1));
   DCHECK(name.is(a2));
 
-  Register scratch = a3;
-  Register extra = t0;
-  Register extra2 = t1;
-  Register extra3 = t2;
+  Register scratch = t0;
+  Register extra = t1;
+  Register extra2 = t2;
+  Register extra3 = t5;
+#ifdef DEBUG
+  Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg;
+  Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg;
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(slot, vector, scratch, extra, extra2, extra3));
+#endif
 
   // Important for the tail-call.
   bool must_teardown_frame = NeedsEagerFrame();
 
-  // The probe will tail call to a handler if found.
-  isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
-                                         must_teardown_frame, receiver, name,
-                                         scratch, extra, extra2, extra3);
+  if (!instr->hydrogen()->is_just_miss()) {
+    DCHECK(!instr->hydrogen()->is_keyed_load());
+
+    // The probe will tail call to a handler if found.
+    isolate()->stub_cache()->GenerateProbe(
+        masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
+        receiver, name, scratch, extra, extra2, extra3);
+  }
 
   // Tail call to miss if we ended up here.
   if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL);
-  LoadIC::GenerateMiss(masm());
+  if (instr->hydrogen()->is_keyed_load()) {
+    KeyedLoadIC::GenerateMiss(masm());
+  } else {
+    LoadIC::GenerateMiss(masm());
+  }
 }
 
 
 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
   DCHECK(ToRegister(instr->result()).is(v0));
 
-  LPointerMap* pointers = instr->pointer_map();
-  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+  if (instr->hydrogen()->IsTailCall()) {
+    if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL);
 
-  if (instr->target()->IsConstantOperand()) {
-    LConstantOperand* target = LConstantOperand::cast(instr->target());
-    Handle<Code> code = Handle<Code>::cast(ToHandle(target));
-    generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
-    __ Call(code, RelocInfo::CODE_TARGET);
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      __ Jump(code, RelocInfo::CODE_TARGET);
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      __ Addu(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
+      __ Jump(target);
+    }
   } else {
-    DCHECK(instr->target()->IsRegister());
-    Register target = ToRegister(instr->target());
-    generator.BeforeCall(__ CallSize(target));
-    __ Addu(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
-    __ Call(target);
+    LPointerMap* pointers = instr->pointer_map();
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
+      __ Call(code, RelocInfo::CODE_TARGET);
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      generator.BeforeCall(__ CallSize(target));
+      __ Addu(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
+      __ Call(target);
+    }
+    generator.AfterCall();
   }
-  generator.AfterCall();
 }
 
 
@@ -4204,7 +4248,7 @@
     __ stop("eliminated bounds check failed");
     __ bind(&done);
   } else {
-    DeoptimizeIf(cc, instr, reg, operand);
+    DeoptimizeIf(cc, instr, "out of bounds", reg, operand);
   }
 }
 
@@ -4483,10 +4527,9 @@
    public:
     DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredStringCharCodeAt(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredStringCharCodeAt(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStringCharCodeAt* instr_;
   };
@@ -4538,10 +4581,11 @@
    public:
     DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredStringCharFromCode(instr_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStringCharFromCode* instr_;
   };
@@ -4616,14 +4660,15 @@
    public:
     DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredNumberTagIU(instr_,
                                        instr_->value(),
                                        instr_->temp1(),
                                        instr_->temp2(),
                                        SIGNED_INT32);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagI* instr_;
   };
@@ -4644,14 +4689,15 @@
    public:
     DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredNumberTagIU(instr_,
                                        instr_->value(),
                                        instr_->temp1(),
                                        instr_->temp2(),
                                        UNSIGNED_INT32);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagU* instr_;
   };
@@ -4738,10 +4784,9 @@
    public:
     DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredNumberTagD(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredNumberTagD(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagD* instr_;
   };
@@ -4797,12 +4842,12 @@
   if (hchange->CheckFlag(HValue::kCanOverflow) &&
       hchange->value()->CheckFlag(HValue::kUint32)) {
     __ And(at, input, Operand(0xc0000000));
-    DeoptimizeIf(ne, instr, at, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "overflow", at, Operand(zero_reg));
   }
   if (hchange->CheckFlag(HValue::kCanOverflow) &&
       !hchange->value()->CheckFlag(HValue::kUint32)) {
     __ SmiTagCheckOverflow(output, input, at);
-    DeoptimizeIf(lt, instr, at, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "overflow", at, Operand(zero_reg));
   } else {
     __ SmiTag(output, input);
   }
@@ -4818,7 +4863,7 @@
     // If the input is a HeapObject, value of scratch won't be zero.
     __ And(scratch, input, Operand(kHeapObjectTag));
     __ SmiUntag(result, input);
-    DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "not a Smi", scratch, Operand(zero_reg));
   } else {
     __ SmiUntag(result, input);
   }
@@ -4843,7 +4888,7 @@
     if (can_convert_undefined_to_nan) {
       __ Branch(&convert, ne, scratch, Operand(at));
     } else {
-      DeoptimizeIf(ne, instr, scratch, Operand(at));
+      DeoptimizeIf(ne, instr, "not a heap number", scratch, Operand(at));
     }
     // Load heap number.
     __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset));
@@ -4851,14 +4896,16 @@
       __ mfc1(at, result_reg.low());
       __ Branch(&done, ne, at, Operand(zero_reg));
       __ Mfhc1(scratch, result_reg);
-      DeoptimizeIf(eq, instr, scratch, Operand(HeapNumber::kSignMask));
+      DeoptimizeIf(eq, instr, "minus zero", scratch,
+                   Operand(HeapNumber::kSignMask));
     }
     __ Branch(&done);
     if (can_convert_undefined_to_nan) {
       __ bind(&convert);
       // Convert undefined (and hole) to NaN.
       __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
-      DeoptimizeIf(ne, instr, input_reg, Operand(at));
+      DeoptimizeIf(ne, instr, "not a heap number/undefined", input_reg,
+                   Operand(at));
       __ LoadRoot(scratch, Heap::kNanValueRootIndex);
       __ ldc1(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset));
       __ Branch(&done);
@@ -4922,11 +4969,12 @@
 
     __ bind(&check_false);
     __ LoadRoot(at, Heap::kFalseValueRootIndex);
-    DeoptimizeIf(ne, instr, scratch2, Operand(at), "cannot truncate");
+    DeoptimizeIf(ne, instr, "not a heap number/undefined/true/false", scratch2,
+                 Operand(at));
     __ Branch(USE_DELAY_SLOT, &done);
     __ mov(input_reg, zero_reg);  // In delay slot.
   } else {
-    DeoptimizeIf(ne, instr, scratch1, Operand(at), "not a heap number");
+    DeoptimizeIf(ne, instr, "not a heap number", scratch1, Operand(at));
 
     // Load the double value.
     __ ldc1(double_scratch,
@@ -4941,15 +4989,15 @@
                        except_flag,
                        kCheckForInexactConversion);
 
-    DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg),
-                 "lost precision or NaN");
+    DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag,
+                 Operand(zero_reg));
 
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
       __ Branch(&done, ne, input_reg, Operand(zero_reg));
 
       __ Mfhc1(scratch1, double_scratch);
       __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
-      DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg), "minus zero");
+      DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg));
     }
   }
   __ bind(&done);
@@ -4961,10 +5009,9 @@
    public:
     DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredTaggedToI(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredTaggedToI(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LTaggedToI* instr_;
   };
@@ -5026,14 +5073,15 @@
                        kCheckForInexactConversion);
 
     // Deopt if the operation did not succeed (except_flag != 0).
-    DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag,
+                 Operand(zero_reg));
 
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
       Label done;
       __ Branch(&done, ne, result_reg, Operand(zero_reg));
       __ Mfhc1(scratch1, double_input);
       __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
-      DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
+      DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg));
       __ bind(&done);
     }
   }
@@ -5059,26 +5107,27 @@
                        kCheckForInexactConversion);
 
     // Deopt if the operation did not succeed (except_flag != 0).
-    DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag,
+                 Operand(zero_reg));
 
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
       Label done;
       __ Branch(&done, ne, result_reg, Operand(zero_reg));
       __ Mfhc1(scratch1, double_input);
       __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
-      DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
+      DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg));
       __ bind(&done);
     }
   }
   __ SmiTagCheckOverflow(result_reg, result_reg, scratch1);
-  DeoptimizeIf(lt, instr, scratch1, Operand(zero_reg));
+  DeoptimizeIf(lt, instr, "overflow", scratch1, Operand(zero_reg));
 }
 
 
 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
   LOperand* input = instr->value();
   __ SmiTst(ToRegister(input), at);
-  DeoptimizeIf(ne, instr, at, Operand(zero_reg));
+  DeoptimizeIf(ne, instr, "not a Smi", at, Operand(zero_reg));
 }
 
 
@@ -5086,7 +5135,7 @@
   if (!instr->hydrogen()->value()->type().IsHeapObject()) {
     LOperand* input = instr->value();
     __ SmiTst(ToRegister(input), at);
-    DeoptimizeIf(eq, instr, at, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg));
   }
 }
 
@@ -5104,12 +5153,12 @@
 
     // If there is only one type in the interval check for equality.
     if (first == last) {
-      DeoptimizeIf(ne, instr, scratch, Operand(first));
+      DeoptimizeIf(ne, instr, "wrong instance type", scratch, Operand(first));
     } else {
-      DeoptimizeIf(lo, instr, scratch, Operand(first));
+      DeoptimizeIf(lo, instr, "wrong instance type", scratch, Operand(first));
       // Omit check for the last type.
       if (last != LAST_TYPE) {
-        DeoptimizeIf(hi, instr, scratch, Operand(last));
+        DeoptimizeIf(hi, instr, "wrong instance type", scratch, Operand(last));
       }
     }
   } else {
@@ -5120,10 +5169,11 @@
     if (base::bits::IsPowerOfTwo32(mask)) {
       DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag));
       __ And(at, scratch, mask);
-      DeoptimizeIf(tag == 0 ? ne : eq, instr, at, Operand(zero_reg));
+      DeoptimizeIf(tag == 0 ? ne : eq, instr, "wrong instance type", at,
+                   Operand(zero_reg));
     } else {
       __ And(scratch, scratch, Operand(mask));
-      DeoptimizeIf(ne, instr, scratch, Operand(tag));
+      DeoptimizeIf(ne, instr, "wrong instance type", scratch, Operand(tag));
     }
   }
 }
@@ -5138,9 +5188,9 @@
     Handle<Cell> cell = isolate()->factory()->NewCell(object);
     __ li(at, Operand(Handle<Object>(cell)));
     __ lw(at, FieldMemOperand(at, Cell::kValueOffset));
-    DeoptimizeIf(ne, instr, reg, Operand(at));
+    DeoptimizeIf(ne, instr, "value mismatch", reg, Operand(at));
   } else {
-    DeoptimizeIf(ne, instr, reg, Operand(object));
+    DeoptimizeIf(ne, instr, "value mismatch", reg, Operand(object));
   }
 }
 
@@ -5156,7 +5206,7 @@
     __ StoreToSafepointRegisterSlot(v0, scratch0());
   }
   __ SmiTst(scratch0(), at);
-  DeoptimizeIf(eq, instr, at, Operand(zero_reg));
+  DeoptimizeIf(eq, instr, "instance migration failed", at, Operand(zero_reg));
 }
 
 
@@ -5167,11 +5217,12 @@
         : LDeferredCode(codegen), instr_(instr), object_(object) {
       SetExit(check_maps());
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredInstanceMigration(instr_, object_);
     }
     Label* check_maps() { return &check_maps_; }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LCheckMaps* instr_;
     Label check_maps_;
@@ -5209,7 +5260,7 @@
   if (instr->hydrogen()->HasMigrationTarget()) {
     __ Branch(deferred->entry(), ne, map_reg, Operand(map));
   } else {
-    DeoptimizeIf(ne, instr, map_reg, Operand(map));
+    DeoptimizeIf(ne, instr, "wrong map", map_reg, Operand(map));
   }
 
   __ bind(&success);
@@ -5247,7 +5298,8 @@
 
   // Check for undefined. Undefined is converted to zero for clamping
   // conversions.
-  DeoptimizeIf(ne, instr, input_reg, Operand(factory()->undefined_value()));
+  DeoptimizeIf(ne, instr, "not a heap number/undefined", input_reg,
+               Operand(factory()->undefined_value()));
   __ mov(result_reg, zero_reg);
   __ jmp(&done);
 
@@ -5289,10 +5341,9 @@
    public:
     DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredAllocate(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredAllocate(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LAllocate* instr_;
   };
@@ -5670,8 +5721,8 @@
     type = Deoptimizer::LAZY;
   }
 
-  DeoptimizeIf(al, instr, type, zero_reg, Operand(zero_reg),
-               instr->hydrogen()->reason());
+  DeoptimizeIf(al, instr, type, instr->hydrogen()->reason(), zero_reg,
+               Operand(zero_reg));
 }
 
 
@@ -5702,10 +5753,9 @@
    public:
     DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredStackCheck(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredStackCheck(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStackCheck* instr_;
   };
@@ -5762,18 +5812,19 @@
   Register result = ToRegister(instr->result());
   Register object = ToRegister(instr->object());
   __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
-  DeoptimizeIf(eq, instr, object, Operand(at));
+  DeoptimizeIf(eq, instr, "undefined", object, Operand(at));
 
   Register null_value = t1;
   __ LoadRoot(null_value, Heap::kNullValueRootIndex);
-  DeoptimizeIf(eq, instr, object, Operand(null_value));
+  DeoptimizeIf(eq, instr, "null", object, Operand(null_value));
 
   __ And(at, object, kSmiTagMask);
-  DeoptimizeIf(eq, instr, at, Operand(zero_reg));
+  DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg));
 
   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
   __ GetObjectType(object, a1, a1);
-  DeoptimizeIf(le, instr, a1, Operand(LAST_JS_PROXY_TYPE));
+  DeoptimizeIf(le, instr, "not a JavaScript object", a1,
+               Operand(LAST_JS_PROXY_TYPE));
 
   Label use_cache, call_runtime;
   DCHECK(object.is(a0));
@@ -5790,7 +5841,7 @@
   __ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
   DCHECK(result.is(v0));
   __ LoadRoot(at, Heap::kMetaMapRootIndex);
-  DeoptimizeIf(ne, instr, a1, Operand(at));
+  DeoptimizeIf(ne, instr, "wrong map", a1, Operand(at));
   __ bind(&use_cache);
 }
 
@@ -5810,7 +5861,7 @@
         FieldMemOperand(result, DescriptorArray::kEnumCacheOffset));
   __ lw(result,
         FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
-  DeoptimizeIf(eq, instr, result, Operand(zero_reg));
+  DeoptimizeIf(eq, instr, "no cache", result, Operand(zero_reg));
 
   __ bind(&done);
 }
@@ -5820,7 +5871,7 @@
   Register object = ToRegister(instr->value());
   Register map = ToRegister(instr->map());
   __ lw(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset));
-  DeoptimizeIf(ne, instr, map, Operand(scratch0()));
+  DeoptimizeIf(ne, instr, "wrong map", map, Operand(scratch0()));
 }
 
 
@@ -5852,10 +5903,11 @@
           object_(object),
           index_(index) {
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredLoadMutableDouble(instr_, result_, object_, index_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LLoadFieldByIndex* instr_;
     Register result_;
diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h
index 5402c9a..43316e4 100644
--- a/src/mips/lithium-codegen-mips.h
+++ b/src/mips/lithium-codegen-mips.h
@@ -229,14 +229,12 @@
   void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
                                             Safepoint::DeoptMode mode);
   void DeoptimizeIf(Condition condition, LInstruction* instr,
-                    Deoptimizer::BailoutType bailout_type,
+                    Deoptimizer::BailoutType bailout_type, const char* detail,
                     Register src1 = zero_reg,
-                    const Operand& src2 = Operand(zero_reg),
-                    const char* detail = NULL);
+                    const Operand& src2 = Operand(zero_reg));
   void DeoptimizeIf(Condition condition, LInstruction* instr,
-                    Register src1 = zero_reg,
-                    const Operand& src2 = Operand(zero_reg),
-                    const char* detail = NULL);
+                    const char* detail = NULL, Register src1 = zero_reg,
+                    const Operand& src2 = Operand(zero_reg));
 
   void AddToTranslation(LEnvironment* environment,
                         Translation* translation,
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 1757d92..77dea5b 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <sstream>
+
 #include "src/v8.h"
 
 #if V8_TARGET_ARCH_MIPS
@@ -323,9 +325,9 @@
 
 void LStoreNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
-  OStringStream os;
+  std::ostringstream os;
   os << hydrogen()->access() << " <- ";
-  stream->Add(os.c_str());
+  stream->Add(os.str().c_str());
   value()->PrintTo(stream);
 }
 
@@ -704,11 +706,7 @@
     // Shift operations can only deoptimize if we do a logical shift
     // by 0 and the result cannot be truncated to int32.
     if (op == Token::SHR && constant_value == 0) {
-      if (FLAG_opt_safe_uint32_operations) {
-        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-      } else {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
-      }
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
     }
 
     LInstruction* result =
@@ -1105,9 +1103,17 @@
       UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
   LOperand* name_register =
       UseFixed(instr->name(), LoadDescriptor::NameRegister());
+  LOperand* slot = NULL;
+  LOperand* vector = NULL;
+  if (FLAG_vector_ics) {
+    slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
+    vector =
+        UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
+  }
+
   // Not marked as call. It can't deoptimize, and it never returns.
   return new (zone()) LTailCallThroughMegamorphicCache(
-      context, receiver_register, name_register);
+      context, receiver_register, name_register, slot, vector);
 }
 
 
@@ -1403,8 +1409,14 @@
   DCHECK(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   LOperand* divisor = UseRegister(instr->right());
-  LFlooringDivI* div = new(zone()) LFlooringDivI(dividend, divisor);
-  return AssignEnvironment(DefineAsRegister(div));
+  LInstruction* result =
+      DefineAsRegister(new (zone()) LFlooringDivI(dividend, divisor));
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+      (instr->CheckFlag(HValue::kCanOverflow))) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -1519,7 +1531,7 @@
     return DefineAsRegister(mul);
 
   } else if (instr->representation().IsDouble()) {
-    if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+    if (IsMipsArchVariant(kMips32r2)) {
       if (instr->HasOneUse() && instr->uses().value()->IsAdd()) {
         HAdd* add = HAdd::cast(instr->uses().value());
         if (instr == add->left()) {
@@ -1592,7 +1604,7 @@
     LInstruction* result = DefineAsRegister(add);
     return result;
   } else if (instr->representation().IsDouble()) {
-    if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
+    if (IsMipsArchVariant(kMips32r2)) {
       if (instr->left()->IsMul())
         return DoMultiplyAdd(HMul::cast(instr->left()), instr->right());
 
@@ -2062,7 +2074,7 @@
   LOperand* global_object =
       UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
   LLoadGlobalGeneric* result =
@@ -2121,7 +2133,7 @@
   LOperand* object =
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
@@ -2188,7 +2200,7 @@
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 36e5b57..ecffef7 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -163,17 +163,13 @@
   V(UnknownOSRValue)                         \
   V(WrapReceiver)
 
-#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)                        \
-  virtual Opcode opcode() const FINAL OVERRIDE {                      \
-    return LInstruction::k##type;                                           \
-  }                                                                         \
-  virtual void CompileToNative(LCodeGen* generator) FINAL OVERRIDE;   \
-  virtual const char* Mnemonic() const FINAL OVERRIDE {               \
-    return mnemonic;                                                        \
-  }                                                                         \
-  static L##type* cast(LInstruction* instr) {                               \
-    DCHECK(instr->Is##type());                                              \
-    return reinterpret_cast<L##type*>(instr);                               \
+#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)            \
+  Opcode opcode() const FINAL { return LInstruction::k##type; } \
+  void CompileToNative(LCodeGen* generator) FINAL;              \
+  const char* Mnemonic() const FINAL { return mnemonic; }       \
+  static L##type* cast(LInstruction* instr) {                   \
+    DCHECK(instr->Is##type());                                  \
+    return reinterpret_cast<L##type*>(instr);                   \
   }
 
 
@@ -288,11 +284,9 @@
  public:
   // Allow 0 or 1 output operands.
   STATIC_ASSERT(R == 0 || R == 1);
-  virtual bool HasResult() const FINAL OVERRIDE {
-    return R != 0 && result() != NULL;
-  }
+  bool HasResult() const FINAL { return R != 0 && result() != NULL; }
   void set_result(LOperand* operand) { results_[0] = operand; }
-  LOperand* result() const { return results_[0]; }
+  LOperand* result() const OVERRIDE { return results_[0]; }
 
  protected:
   EmbeddedContainer<LOperand*, R> results_;
@@ -310,11 +304,11 @@
 
  private:
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return I; }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return I; }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return T; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return temps_[i]; }
+  int TempCount() FINAL { return T; }
+  LOperand* TempAt(int i) FINAL { return temps_[i]; }
 };
 
 
@@ -329,8 +323,8 @@
   }
 
   // Can't use the DECLARE-macro here because of sub-classes.
-  virtual bool IsGap() const FINAL OVERRIDE { return true; }
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsGap() const FINAL { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   static LGap* cast(LInstruction* instr) {
     DCHECK(instr->IsGap());
     return reinterpret_cast<LGap*>(instr);
@@ -370,7 +364,7 @@
  public:
   explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
     return !IsRedundant();
   }
 
@@ -382,10 +376,10 @@
  public:
   explicit LGoto(HBasicBlock* block) : block_(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
-  virtual bool IsControl() const OVERRIDE { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsControl() const OVERRIDE { return true; }
 
   int block_id() const { return block_->block_id(); }
 
@@ -428,7 +422,7 @@
 
 class LDeoptimize FINAL : public LTemplateInstruction<0, 0, 0> {
  public:
-  virtual bool IsControl() const OVERRIDE { return true; }
+  bool IsControl() const OVERRIDE { return true; }
   DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
   DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
 };
@@ -439,12 +433,10 @@
   explicit LLabel(HBasicBlock* block)
       : LGap(block), replacement_(NULL) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Label, "label")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int block_id() const { return block()->block_id(); }
   bool is_loop_header() const { return block()->IsLoopHeader(); }
@@ -462,9 +454,7 @@
 
 class LParameter FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
 };
 
@@ -483,19 +473,23 @@
 
 
 class LTailCallThroughMegamorphicCache FINAL
-    : public LTemplateInstruction<0, 3, 0> {
+    : public LTemplateInstruction<0, 5, 0> {
  public:
-  explicit LTailCallThroughMegamorphicCache(LOperand* context,
-                                            LOperand* receiver,
-                                            LOperand* name) {
+  LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
+                                   LOperand* name, LOperand* slot,
+                                   LOperand* vector) {
     inputs_[0] = context;
     inputs_[1] = receiver;
     inputs_[2] = name;
+    inputs_[3] = slot;
+    inputs_[4] = vector;
   }
 
   LOperand* context() { return inputs_[0]; }
   LOperand* receiver() { return inputs_[1]; }
   LOperand* name() { return inputs_[2]; }
+  LOperand* slot() { return inputs_[3]; }
+  LOperand* vector() { return inputs_[4]; }
 
   DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
                                "tail-call-through-megamorphic-cache")
@@ -505,9 +499,7 @@
 
 class LUnknownOSRValue FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
 };
 
@@ -517,7 +509,7 @@
  public:
   LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
 
-  virtual bool IsControl() const FINAL OVERRIDE { return true; }
+  bool IsControl() const FINAL { return true; }
 
   int SuccessorCount() { return hydrogen()->SuccessorCount(); }
   HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
@@ -606,7 +598,7 @@
   LOperand* length() { return inputs_[1]; }
   LOperand* index() { return inputs_[2]; }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -846,7 +838,7 @@
     return hydrogen()->representation().IsDouble();
   }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1034,7 +1026,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1051,7 +1043,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1066,7 +1058,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1084,7 +1076,7 @@
                                "is-undetectable-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1106,7 +1098,7 @@
 
   Token::Value op() const { return hydrogen()->token(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1122,7 +1114,7 @@
                                "has-instance-type-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1152,7 +1144,7 @@
                                "has-cached-array-index-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1170,7 +1162,7 @@
                                "class-of-test-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1367,7 +1359,7 @@
   DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
   DECLARE_HYDROGEN_ACCESSOR(Branch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1512,11 +1504,9 @@
   LOperand* left() { return inputs_[0]; }
   LOperand* right() { return inputs_[1]; }
 
-  virtual Opcode opcode() const OVERRIDE {
-    return LInstruction::kArithmeticD;
-  }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticD; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
  private:
   Token::Value op_;
@@ -1540,9 +1530,9 @@
   LOperand* right() { return inputs_[2]; }
   Token::Value op() const { return op_; }
 
-  virtual Opcode opcode() const FINAL  { return LInstruction::kArithmeticT; }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const FINAL { return LInstruction::kArithmeticT; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
  private:
   Token::Value op_;
@@ -1651,7 +1641,7 @@
   DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
   DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   uint32_t base_offset() const { return hydrogen()->base_offset(); }
 };
 
@@ -1732,7 +1722,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1751,7 +1741,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1790,7 +1780,7 @@
   LOperand* function() { return inputs_[0]; }
   LOperand* code_object() { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
   DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
@@ -1807,7 +1797,7 @@
   LOperand* base_object() const { return inputs_[0]; }
   LOperand* offset() const { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
 };
@@ -1851,7 +1841,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
   DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1871,11 +1861,12 @@
 
   const CallInterfaceDescriptor descriptor() { return descriptor_; }
 
- private:
-  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
   DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+ private:
+  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 
@@ -1883,11 +1874,11 @@
   ZoneList<LOperand*> inputs_;
 
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return inputs_.length(); }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return inputs_.length(); }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return 0; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return NULL; }
+  int TempCount() FINAL { return 0; }
+  LOperand* TempAt(int i) FINAL { return NULL; }
 };
 
 
@@ -1904,7 +1895,7 @@
   DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
   DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1940,7 +1931,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
   DECLARE_HYDROGEN_ACCESSOR(CallNew)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1959,7 +1950,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
   DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1976,7 +1967,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
   DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
 
-  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
+  bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
     return save_doubles() == kDontSaveFPRegs;
   }
 
@@ -2170,7 +2161,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Representation representation() const {
     return hydrogen()->field_representation();
@@ -2193,7 +2184,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Handle<Object> name() const { return hydrogen()->name(); }
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
@@ -2225,7 +2216,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
   uint32_t base_offset() const { return hydrogen()->base_offset(); }
 };
@@ -2251,7 +2242,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
@@ -2275,7 +2266,7 @@
                                "transition-elements-kind")
   DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
   Handle<Map> transitioned_map() {
@@ -2571,7 +2562,7 @@
 
   Handle<String> type_literal() { return hydrogen()->type_literal(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -2592,9 +2583,7 @@
  public:
   LOsrEntry() {}
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
 };
 
@@ -2797,7 +2786,7 @@
 
   // An input operand in register, stack slot or a constant operand.
   // Will not be moved to a register even if one is freely available.
-  virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
+  MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
 
   // Temporary operand that must be in a register.
   MUST_USE_RESULT LUnallocated* TempRegister();
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index 604293b..90c3499 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -15,7 +15,7 @@
 #include "src/cpu-profiler.h"
 #include "src/debug.h"
 #include "src/isolate-inl.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -23,7 +23,8 @@
 MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size)
     : Assembler(arg_isolate, buffer, size),
       generating_stub_(false),
-      has_frame_(false) {
+      has_frame_(false),
+      has_double_zero_reg_set_(false) {
   if (isolate() != NULL) {
     code_object_ = Handle<Object>(isolate()->heap()->undefined_value(),
                                   isolate());
@@ -590,11 +591,12 @@
   }
 
   bind(&done);
-  // Check that the value is a normal property.
+  // Check that the value is a field property.
   // reg2: elements + (index * kPointerSize).
   const int kDetailsOffset =
       SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
   lw(reg1, FieldMemOperand(reg2, kDetailsOffset));
+  DCHECK_EQ(FIELD, 0);
   And(at, reg1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask)));
   Branch(miss, ne, at, Operand(zero_reg));
 
@@ -739,6 +741,28 @@
 }
 
 
+void MacroAssembler::Mulhu(Register rd, Register rs, const Operand& rt) {
+  if (rt.is_reg()) {
+    if (!IsMipsArchVariant(kMips32r6)) {
+      multu(rs, rt.rm());
+      mfhi(rd);
+    } else {
+      muhu(rd, rs, rt.rm());
+    }
+  } else {
+    // li handles the relocation.
+    DCHECK(!rs.is(at));
+    li(at, rt);
+    if (!IsMipsArchVariant(kMips32r6)) {
+      multu(rs, at);
+      mfhi(rd);
+    } else {
+      muhu(rd, rs, at);
+    }
+  }
+}
+
+
 void MacroAssembler::Multu(Register rs, const Operand& rt) {
   if (rt.is_reg()) {
     multu(rs, rt.rm());
@@ -790,6 +814,28 @@
 }
 
 
+void MacroAssembler::Div(Register res, Register rs, const Operand& rt) {
+  if (rt.is_reg()) {
+    if (!IsMipsArchVariant(kMips32r6)) {
+      div(rs, rt.rm());
+      mflo(res);
+    } else {
+      div(res, rs, rt.rm());
+    }
+  } else {
+    // li handles the relocation.
+    DCHECK(!rs.is(at));
+    li(at, rt);
+    if (!IsMipsArchVariant(kMips32r6)) {
+      div(rs, at);
+      mflo(res);
+    } else {
+      div(res, rs, at);
+    }
+  }
+}
+
+
 void MacroAssembler::Mod(Register rd, Register rs, const Operand& rt) {
   if (rt.is_reg()) {
     if (!IsMipsArchVariant(kMips32r6)) {
@@ -812,6 +858,28 @@
 }
 
 
+void MacroAssembler::Modu(Register rd, Register rs, const Operand& rt) {
+  if (rt.is_reg()) {
+    if (!IsMipsArchVariant(kMips32r6)) {
+      divu(rs, rt.rm());
+      mfhi(rd);
+    } else {
+      modu(rd, rs, rt.rm());
+    }
+  } else {
+    // li handles the relocation.
+    DCHECK(!rs.is(at));
+    li(at, rt);
+    if (!IsMipsArchVariant(kMips32r6)) {
+      divu(rs, at);
+      mfhi(rd);
+    } else {
+      modu(rd, rs, at);
+    }
+  }
+}
+
+
 void MacroAssembler::Divu(Register rs, const Operand& rt) {
   if (rt.is_reg()) {
     divu(rs, rt.rm());
@@ -824,6 +892,28 @@
 }
 
 
+void MacroAssembler::Divu(Register res, Register rs, const Operand& rt) {
+  if (rt.is_reg()) {
+    if (!IsMipsArchVariant(kMips32r6)) {
+      divu(rs, rt.rm());
+      mflo(res);
+    } else {
+      divu(res, rs, rt.rm());
+    }
+  } else {
+    // li handles the relocation.
+    DCHECK(!rs.is(at));
+    li(at, rt);
+    if (!IsMipsArchVariant(kMips32r6)) {
+      divu(rs, at);
+      mflo(res);
+    } else {
+      divu(res, rs, at);
+    }
+  }
+}
+
+
 void MacroAssembler::And(Register rd, Register rs, const Operand& rt) {
   if (rt.is_reg()) {
     and_(rd, rs, rt.rm());
@@ -1459,15 +1549,20 @@
 }
 
 
+void MacroAssembler::Move(FPURegister dst, float imm) {
+  li(at, Operand(bit_cast<int32_t>(imm)));
+  mtc1(at, dst);
+}
+
+
 void MacroAssembler::Move(FPURegister dst, double imm) {
   static const DoubleRepresentation minus_zero(-0.0);
   static const DoubleRepresentation zero(0.0);
   DoubleRepresentation value_rep(imm);
   // Handle special values first.
-  bool force_load = dst.is(kDoubleRegZero);
-  if (value_rep == zero && !force_load) {
+  if (value_rep == zero && has_double_zero_reg_set_) {
     mov_d(dst, kDoubleRegZero);
-  } else if (value_rep == minus_zero && !force_load) {
+  } else if (value_rep == minus_zero && has_double_zero_reg_set_) {
     neg_d(dst, kDoubleRegZero);
   } else {
     uint32_t lo, hi;
@@ -1488,6 +1583,7 @@
     } else {
       Mthc1(zero_reg, dst);
     }
+    if (dst.is(kDoubleRegZero)) has_double_zero_reg_set_ = true;
   }
 }
 
@@ -1904,7 +2000,7 @@
       // Unsigned comparison.
       case Ugreater:
         if (r2.is(zero_reg)) {
-          bgtz(rs, offset);
+          bne(rs, zero_reg, offset);
         } else {
           sltu(scratch, r2, rs);
           bne(scratch, zero_reg, offset);
@@ -1912,7 +2008,7 @@
         break;
       case Ugreater_equal:
         if (r2.is(zero_reg)) {
-          bgez(rs, offset);
+          b(offset);
         } else {
           sltu(scratch, rs, r2);
           beq(scratch, zero_reg, offset);
@@ -1929,7 +2025,7 @@
         break;
       case Uless_equal:
         if (r2.is(zero_reg)) {
-          b(offset);
+          beq(rs, zero_reg, offset);
         } else {
           sltu(scratch, r2, rs);
           beq(scratch, zero_reg, offset);
@@ -1948,18 +2044,26 @@
         b(offset);
         break;
       case eq:
-        // We don't want any other register but scratch clobbered.
-        DCHECK(!scratch.is(rs));
-        r2 = scratch;
-        li(r2, rt);
-        beq(rs, r2, offset);
+        if (rt.imm32_ == 0) {
+          beq(rs, zero_reg, offset);
+        } else {
+          // We don't want any other register but scratch clobbered.
+          DCHECK(!scratch.is(rs));
+          r2 = scratch;
+          li(r2, rt);
+          beq(rs, r2, offset);
+        }
         break;
       case ne:
-        // We don't want any other register but scratch clobbered.
-        DCHECK(!scratch.is(rs));
-        r2 = scratch;
-        li(r2, rt);
-        bne(rs, r2, offset);
+        if (rt.imm32_ == 0) {
+          bne(rs, zero_reg, offset);
+        } else {
+          // We don't want any other register but scratch clobbered.
+          DCHECK(!scratch.is(rs));
+          r2 = scratch;
+          li(r2, rt);
+          bne(rs, r2, offset);
+        }
         break;
       // Signed comparison.
       case greater:
@@ -2011,7 +2115,7 @@
       // Unsigned comparison.
       case Ugreater:
         if (rt.imm32_ == 0) {
-          bgtz(rs, offset);
+          bne(rs, zero_reg, offset);
         } else {
           r2 = scratch;
           li(r2, rt);
@@ -2021,7 +2125,7 @@
         break;
       case Ugreater_equal:
         if (rt.imm32_ == 0) {
-          bgez(rs, offset);
+          b(offset);
         } else if (is_int16(rt.imm32_)) {
           sltiu(scratch, rs, rt.imm32_);
           beq(scratch, zero_reg, offset);
@@ -2048,7 +2152,7 @@
         break;
       case Uless_equal:
         if (rt.imm32_ == 0) {
-          b(offset);
+          beq(rs, zero_reg, offset);
         } else {
           r2 = scratch;
           li(r2, rt);
@@ -2150,7 +2254,7 @@
       case Ugreater:
         if (r2.is(zero_reg)) {
           offset = shifted_branch_offset(L, false);
-           bgtz(rs, offset);
+          bne(rs, zero_reg, offset);
         } else {
           sltu(scratch, r2, rs);
           offset = shifted_branch_offset(L, false);
@@ -2160,7 +2264,7 @@
       case Ugreater_equal:
         if (r2.is(zero_reg)) {
           offset = shifted_branch_offset(L, false);
-          bgez(rs, offset);
+          b(offset);
         } else {
           sltu(scratch, rs, r2);
           offset = shifted_branch_offset(L, false);
@@ -2180,7 +2284,7 @@
       case Uless_equal:
         if (r2.is(zero_reg)) {
           offset = shifted_branch_offset(L, false);
-          b(offset);
+          beq(rs, zero_reg, offset);
         } else {
           sltu(scratch, r2, rs);
           offset = shifted_branch_offset(L, false);
@@ -2201,18 +2305,28 @@
         b(offset);
         break;
       case eq:
-        DCHECK(!scratch.is(rs));
-        r2 = scratch;
-        li(r2, rt);
-        offset = shifted_branch_offset(L, false);
-        beq(rs, r2, offset);
+        if (rt.imm32_ == 0) {
+          offset = shifted_branch_offset(L, false);
+          beq(rs, zero_reg, offset);
+        } else {
+          DCHECK(!scratch.is(rs));
+          r2 = scratch;
+          li(r2, rt);
+          offset = shifted_branch_offset(L, false);
+          beq(rs, r2, offset);
+        }
         break;
       case ne:
-        DCHECK(!scratch.is(rs));
-        r2 = scratch;
-        li(r2, rt);
-        offset = shifted_branch_offset(L, false);
-        bne(rs, r2, offset);
+        if (rt.imm32_ == 0) {
+          offset = shifted_branch_offset(L, false);
+          bne(rs, zero_reg, offset);
+        } else {
+          DCHECK(!scratch.is(rs));
+          r2 = scratch;
+          li(r2, rt);
+          offset = shifted_branch_offset(L, false);
+          bne(rs, r2, offset);
+        }
         break;
       // Signed comparison.
       case greater:
@@ -2292,7 +2406,7 @@
       case Ugreater_equal:
         if (rt.imm32_ == 0) {
           offset = shifted_branch_offset(L, false);
-          bgez(rs, offset);
+          b(offset);
         } else if (is_int16(rt.imm32_)) {
           sltiu(scratch, rs, rt.imm32_);
           offset = shifted_branch_offset(L, false);
@@ -3884,17 +3998,17 @@
 }
 
 
-void MacroAssembler::DispatchMap(Register obj,
-                                 Register scratch,
-                                 Handle<Map> map,
-                                 Handle<Code> success,
-                                 SmiCheckType smi_check_type) {
+void MacroAssembler::DispatchWeakMap(Register obj, Register scratch1,
+                                     Register scratch2, Handle<WeakCell> cell,
+                                     Handle<Code> success,
+                                     SmiCheckType smi_check_type) {
   Label fail;
   if (smi_check_type == DO_SMI_CHECK) {
     JumpIfSmi(obj, &fail);
   }
-  lw(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
-  Jump(success, RelocInfo::CODE_TARGET, eq, scratch, Operand(map));
+  lw(scratch1, FieldMemOperand(obj, HeapObject::kMapOffset));
+  GetWeakValue(scratch2, cell);
+  Jump(success, RelocInfo::CODE_TARGET, eq, scratch1, Operand(scratch2));
   bind(&fail);
 }
 
@@ -3913,6 +4027,19 @@
 }
 
 
+void MacroAssembler::GetWeakValue(Register value, Handle<WeakCell> cell) {
+  li(value, Operand(cell));
+  lw(value, FieldMemOperand(value, WeakCell::kValueOffset));
+}
+
+
+void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell,
+                                   Label* miss) {
+  GetWeakValue(value, cell);
+  JumpIfSmi(value, miss);
+}
+
+
 void MacroAssembler::MovFromFloatResult(DoubleRegister dst) {
   if (IsMipsSoftFloatABI) {
     if (kArchEndian == kLittle) {
@@ -4477,8 +4604,34 @@
 }
 
 
-void MacroAssembler::AdduAndCheckForOverflow(Register dst,
-                                             Register left,
+void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left,
+                                             const Operand& right,
+                                             Register overflow_dst,
+                                             Register scratch) {
+  if (right.is_reg()) {
+    AdduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch);
+  } else {
+    if (dst.is(left)) {
+      mov(scratch, left);                   // Preserve left.
+      addiu(dst, left, right.immediate());  // Left is overwritten.
+      xor_(scratch, dst, scratch);          // Original left.
+      // Load right since xori takes uint16 as immediate.
+      addiu(t9, zero_reg, right.immediate());
+      xor_(overflow_dst, dst, t9);
+      and_(overflow_dst, overflow_dst, scratch);
+    } else {
+      addiu(dst, left, right.immediate());
+      xor_(overflow_dst, dst, left);
+      // Load right since xori takes uint16 as immediate.
+      addiu(t9, zero_reg, right.immediate());
+      xor_(scratch, dst, t9);
+      and_(overflow_dst, scratch, overflow_dst);
+    }
+  }
+}
+
+
+void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left,
                                              Register right,
                                              Register overflow_dst,
                                              Register scratch) {
@@ -4519,8 +4672,34 @@
 }
 
 
-void MacroAssembler::SubuAndCheckForOverflow(Register dst,
-                                             Register left,
+void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left,
+                                             const Operand& right,
+                                             Register overflow_dst,
+                                             Register scratch) {
+  if (right.is_reg()) {
+    SubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch);
+  } else {
+    if (dst.is(left)) {
+      mov(scratch, left);                      // Preserve left.
+      addiu(dst, left, -(right.immediate()));  // Left is overwritten.
+      xor_(overflow_dst, dst, scratch);        // scratch is original left.
+      // Load right since xori takes uint16 as immediate.
+      addiu(t9, zero_reg, right.immediate());
+      xor_(scratch, scratch, t9);  // scratch is original left.
+      and_(overflow_dst, scratch, overflow_dst);
+    } else {
+      addiu(dst, left, -(right.immediate()));
+      xor_(overflow_dst, dst, left);
+      // Load right since xori takes uint16 as immediate.
+      addiu(t9, zero_reg, right.immediate());
+      xor_(scratch, left, t9);
+      and_(overflow_dst, scratch, overflow_dst);
+    }
+  }
+}
+
+
+void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left,
                                              Register right,
                                              Register overflow_dst,
                                              Register scratch) {
@@ -4887,6 +5066,13 @@
 }
 
 
+void MacroAssembler::EnterFrame(StackFrame::Type type,
+                                bool load_constant_pool_pointer_reg) {
+  // Out-of-line constant pool not implemented on mips.
+  UNREACHABLE();
+}
+
+
 void MacroAssembler::EnterFrame(StackFrame::Type type) {
   addiu(sp, sp, -5 * kPointerSize);
   li(t8, Operand(Smi::FromInt(type)));
@@ -5619,18 +5805,6 @@
 }
 
 
-void MacroAssembler::CheckMapDeprecated(Handle<Map> map,
-                                        Register scratch,
-                                        Label* if_deprecated) {
-  if (map->CanBeDeprecated()) {
-    li(scratch, Operand(map));
-    lw(scratch, FieldMemOperand(scratch, Map::kBitField3Offset));
-    And(scratch, scratch, Operand(Map::Deprecated::kMask));
-    Branch(if_deprecated, ne, scratch, Operand(zero_reg));
-  }
-}
-
-
 void MacroAssembler::JumpIfBlack(Register object,
                                  Register scratch0,
                                  Register scratch1,
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index ce52986..0bc1e15 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -250,8 +250,10 @@
     Mthc1(src_high, dst);
   }
 
-  // Conditional move.
+  void Move(FPURegister dst, float imm);
   void Move(FPURegister dst, double imm);
+
+  // Conditional move.
   void Movz(Register rd, Register rs, Register rt);
   void Movn(Register rd, Register rs, Register rt);
   void Movt(Register rd, Register rs, uint16_t cc = 0);
@@ -313,10 +315,6 @@
                      Condition cc,
                      Label* condition_met);
 
-  void CheckMapDeprecated(Handle<Map> map,
-                          Register scratch,
-                          Label* if_deprecated);
-
   // Check if object is in new space.  Jumps if the object is not in new space.
   // The register scratch can be object itself, but it will be clobbered.
   void JumpIfNotInNewSpace(Register object,
@@ -587,9 +585,13 @@
   DEFINE_INSTRUCTION(Addu);
   DEFINE_INSTRUCTION(Subu);
   DEFINE_INSTRUCTION(Mul);
+  DEFINE_INSTRUCTION(Div);
+  DEFINE_INSTRUCTION(Divu);
   DEFINE_INSTRUCTION(Mod);
+  DEFINE_INSTRUCTION(Modu);
   DEFINE_INSTRUCTION(Mulh);
   DEFINE_INSTRUCTION2(Mult);
+  DEFINE_INSTRUCTION(Mulhu);
   DEFINE_INSTRUCTION2(Multu);
   DEFINE_INSTRUCTION2(Div);
   DEFINE_INSTRUCTION2(Divu);
@@ -1078,15 +1080,19 @@
                 Label* fail,
                 SmiCheckType smi_check_type);
 
-  // Check if the map of an object is equal to a specified map and branch to a
-  // specified target if equal. Skip the smi check if not required (object is
-  // known to be a heap object)
-  void DispatchMap(Register obj,
-                   Register scratch,
-                   Handle<Map> map,
-                   Handle<Code> success,
-                   SmiCheckType smi_check_type);
+  // Check if the map of an object is equal to a specified weak map and branch
+  // to a specified target if equal. Skip the smi check if not required
+  // (object is known to be a heap object)
+  void DispatchWeakMap(Register obj, Register scratch1, Register scratch2,
+                       Handle<WeakCell> cell, Handle<Code> success,
+                       SmiCheckType smi_check_type);
 
+  // Get value of the weak cell.
+  void GetWeakValue(Register value, Handle<WeakCell> cell);
+
+  // Load the value of the weak cell in the value register. Branch to the
+  // given miss label is the weak cell was cleared.
+  void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss);
 
   // Load and check the instance type of an object for being a string.
   // Loads the type into the second argument register.
@@ -1142,12 +1148,20 @@
                                Register overflow_dst,
                                Register scratch = at);
 
+  void AdduAndCheckForOverflow(Register dst, Register left,
+                               const Operand& right, Register overflow_dst,
+                               Register scratch = at);
+
   void SubuAndCheckForOverflow(Register dst,
                                Register left,
                                Register right,
                                Register overflow_dst,
                                Register scratch = at);
 
+  void SubuAndCheckForOverflow(Register dst, Register left,
+                               const Operand& right, Register overflow_dst,
+                               Register scratch = at);
+
   void BranchOnOverflow(Label* label,
                         Register overflow_check,
                         BranchDelaySlot bd = PROTECT) {
@@ -1172,13 +1186,10 @@
   // Runtime calls.
 
   // See comments at the beginning of CEntryStub::Generate.
-  inline void PrepareCEntryArgs(int num_args) {
-    li(s0, num_args);
-    li(s1, (num_args - 1) * kPointerSize);
-  }
+  inline void PrepareCEntryArgs(int num_args) { li(a0, num_args); }
 
   inline void PrepareCEntryFunction(const ExternalReference& ref) {
-    li(s2, Operand(ref));
+    li(a1, Operand(ref));
   }
 
 #define COND_ARGS Condition cond = al, Register rs = zero_reg, \
@@ -1555,6 +1566,7 @@
 
   // Activation support.
   void EnterFrame(StackFrame::Type type);
+  void EnterFrame(StackFrame::Type type, bool load_constant_pool_pointer_reg);
   void LeaveFrame(StackFrame::Type type);
 
   // Patch the relocated value (lui/ori pair).
@@ -1657,6 +1669,7 @@
 
   bool generating_stub_;
   bool has_frame_;
+  bool has_double_zero_reg_set_;
   // This handle will be patched with the code object on installation.
   Handle<Object> code_object_;
 
diff --git a/src/mips64/assembler-mips64-inl.h b/src/mips64/assembler-mips64-inl.h
index de294ee..76dd801 100644
--- a/src/mips64/assembler-mips64-inl.h
+++ b/src/mips64/assembler-mips64-inl.h
@@ -99,6 +99,11 @@
 }
 
 
+int DoubleRegister::NumAllocatableAliasedRegisters() {
+  return NumAllocatableRegisters();
+}
+
+
 int FPURegister::ToAllocationIndex(FPURegister reg) {
   DCHECK(reg.code() % 2 == 0);
   DCHECK(reg.code() / 2 < kMaxNumAllocatableRegisters);
diff --git a/src/mips64/assembler-mips64.cc b/src/mips64/assembler-mips64.cc
index 5d51e63..b8f5821 100644
--- a/src/mips64/assembler-mips64.cc
+++ b/src/mips64/assembler-mips64.cc
@@ -2192,6 +2192,14 @@
 }
 
 
+void Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
+  // Should be called via MacroAssembler::Ext.
+  // Dext instr has 'rt' field as dest, and two uint5: msb, lsb.
+  DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
+  GenInstrRegister(SPECIAL3, rs, rt, size - 1, pos, DEXT);
+}
+
+
 void Assembler::pref(int32_t hint, const MemOperand& rs) {
   DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
   Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
diff --git a/src/mips64/assembler-mips64.h b/src/mips64/assembler-mips64.h
index 5c754f4..5ca2f3a 100644
--- a/src/mips64/assembler-mips64.h
+++ b/src/mips64/assembler-mips64.h
@@ -211,6 +211,10 @@
 
   inline static int NumRegisters();
   inline static int NumAllocatableRegisters();
+
+  // TODO(turbofan): Proper support for float32.
+  inline static int NumAllocatableAliasedRegisters();
+
   inline static int ToAllocationIndex(FPURegister reg);
   static const char* AllocationIndexToString(int index);
 
@@ -882,6 +886,7 @@
   void clz(Register rd, Register rs);
   void ins_(Register rt, Register rs, uint16_t pos, uint16_t size);
   void ext_(Register rt, Register rs, uint16_t pos, uint16_t size);
+  void dext_(Register rt, Register rs, uint16_t pos, uint16_t size);
 
   // --------Coprocessor-instructions----------------
 
diff --git a/src/mips64/builtins-mips64.cc b/src/mips64/builtins-mips64.cc
index 5bdb56c..c95ff30 100644
--- a/src/mips64/builtins-mips64.cc
+++ b/src/mips64/builtins-mips64.cc
@@ -12,7 +12,7 @@
 #include "src/debug.h"
 #include "src/deoptimizer.h"
 #include "src/full-codegen.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -44,11 +44,9 @@
     DCHECK(extra_args == NO_EXTRA_ARGUMENTS);
   }
 
-  // JumpToExternalReference expects s0 to contain the number of arguments
+  // JumpToExternalReference expects a0 to contain the number of arguments
   // including the receiver and the extra arguments.
-  __ Daddu(s0, a0, num_extra_args + 1);
-  __ dsll(s1, s0, kPointerSizeLog2);
-  __ Dsubu(s1, s1, kPointerSize);
+  __ Daddu(a0, a0, num_extra_args + 1);
   __ JumpToExternalReference(ExternalReference(id, masm->isolate()));
 }
 
@@ -384,24 +382,22 @@
         MemOperand bit_field3 = FieldMemOperand(a2, Map::kBitField3Offset);
         // Check if slack tracking is enabled.
         __ lwu(a4, bit_field3);
-        __ DecodeField<Map::ConstructionCount>(a6, a4);
-        __ Branch(&allocate,
-                  eq,
-                  a6,
-                  Operand(static_cast<int64_t>(JSFunction::kNoSlackTracking)));
+        __ DecodeField<Map::Counter>(a6, a4);
+        __ Branch(&allocate, lt, a6,
+                  Operand(static_cast<int64_t>(Map::kSlackTrackingCounterEnd)));
         // Decrease generous allocation count.
-        __ Dsubu(a4, a4, Operand(1 << Map::ConstructionCount::kShift));
-        __ Branch(USE_DELAY_SLOT,
-            &allocate, ne, a6, Operand(JSFunction::kFinishSlackTracking));
+        __ Dsubu(a4, a4, Operand(1 << Map::Counter::kShift));
+        __ Branch(USE_DELAY_SLOT, &allocate, ne, a6,
+                  Operand(Map::kSlackTrackingCounterEnd));
         __ sw(a4, bit_field3);  // In delay slot.
 
         __ Push(a1, a2, a1);  // a1 = Constructor.
         __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
 
         __ Pop(a1, a2);
-        // Slack tracking counter is kNoSlackTracking after runtime call.
-        DCHECK(JSFunction::kNoSlackTracking == 0);
-        __ mov(a6, zero_reg);
+        // Slack tracking counter is Map::kSlackTrackingCounterEnd after runtime
+        // call.
+        __ li(a6, Map::kSlackTrackingCounterEnd);
 
         __ bind(&allocate);
       }
@@ -448,10 +444,8 @@
         Label no_inobject_slack_tracking;
 
         // Check if slack tracking is enabled.
-        __ Branch(&no_inobject_slack_tracking,
-                  eq,
-                  a6,
-                  Operand(static_cast<int64_t>(JSFunction::kNoSlackTracking)));
+        __ Branch(&no_inobject_slack_tracking, lt, a6,
+                  Operand(static_cast<int64_t>(Map::kSlackTrackingCounterEnd)));
 
         // Allocate object with a slack.
         __ lwu(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset));
@@ -782,11 +776,6 @@
     // a3: argc
     // s0: argv, i.e. points to first arg
     Label loop, entry;
-    // TODO(plind): At least on simulator, argc in a3 is an int32_t with junk
-    //    in upper bits. Should fix the root cause, rather than use below
-    //    workaround to clear upper bits.
-    __ dsll32(a3, a3, 0);  // int32_t -> int64_t.
-    __ dsrl32(a3, a3, 0);
     __ dsll(a4, a3, kPointerSizeLog2);
     __ daddu(a6, s0, a4);
     __ b(&entry);
@@ -1044,7 +1033,7 @@
 
   // Load deoptimization data from the code object.
   // <deopt_data> = <code>[#deoptimization_data_offset]
-  __ Uld(a1, MemOperand(v0, Code::kDeoptimizationDataOffset - kHeapObjectTag));
+  __ ld(a1, MemOperand(v0, Code::kDeoptimizationDataOffset - kHeapObjectTag));
 
   // Load the OSR entrypoint offset from the deoptimization data.
   // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset]
diff --git a/src/mips64/code-stubs-mips64.cc b/src/mips64/code-stubs-mips64.cc
index 60263b5..6bbd1a3 100644
--- a/src/mips64/code-stubs-mips64.cc
+++ b/src/mips64/code-stubs-mips64.cc
@@ -14,7 +14,7 @@
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -268,66 +268,6 @@
 }
 
 
-void WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(
-    Isolate* isolate) {
-  WriteInt32ToHeapNumberStub stub1(isolate, a1, v0, a2, a3);
-  WriteInt32ToHeapNumberStub stub2(isolate, a2, v0, a3, a0);
-  stub1.GetCode();
-  stub2.GetCode();
-}
-
-
-// See comment for class, this does NOT work for int32's that are in Smi range.
-void WriteInt32ToHeapNumberStub::Generate(MacroAssembler* masm) {
-  Label max_negative_int;
-  // the_int_ has the answer which is a signed int32 but not a Smi.
-  // We test for the special value that has a different exponent.
-  STATIC_ASSERT(HeapNumber::kSignMask == 0x80000000u);
-  // Test sign, and save for later conditionals.
-  __ And(sign(), the_int(), Operand(0x80000000u));
-  __ Branch(&max_negative_int, eq, the_int(), Operand(0x80000000u));
-
-  // Set up the correct exponent in scratch_.  All non-Smi int32s have the same.
-  // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased).
-  uint32_t non_smi_exponent =
-      (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift;
-  __ li(scratch(), Operand(non_smi_exponent));
-  // Set the sign bit in scratch_ if the value was negative.
-  __ or_(scratch(), scratch(), sign());
-  // Subtract from 0 if the value was negative.
-  __ subu(at, zero_reg, the_int());
-  __ Movn(the_int(), at, sign());
-  // We should be masking the implict first digit of the mantissa away here,
-  // but it just ends up combining harmlessly with the last digit of the
-  // exponent that happens to be 1.  The sign bit is 0 so we shift 10 to get
-  // the most significant 1 to hit the last bit of the 12 bit sign and exponent.
-  DCHECK(((1 << HeapNumber::kExponentShift) & non_smi_exponent) != 0);
-  const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2;
-  __ srl(at, the_int(), shift_distance);
-  __ or_(scratch(), scratch(), at);
-  __ sw(scratch(), FieldMemOperand(the_heap_number(),
-                                   HeapNumber::kExponentOffset));
-  __ sll(scratch(), the_int(), 32 - shift_distance);
-  __ Ret(USE_DELAY_SLOT);
-  __ sw(scratch(), FieldMemOperand(the_heap_number(),
-                                   HeapNumber::kMantissaOffset));
-
-  __ bind(&max_negative_int);
-  // The max negative int32 is stored as a positive number in the mantissa of
-  // a double because it uses a sign bit instead of using two's complement.
-  // The actual mantissa bits stored are all 0 because the implicit most
-  // significant 1 bit is not stored.
-  non_smi_exponent += 1 << HeapNumber::kExponentShift;
-  __ li(scratch(), Operand(HeapNumber::kSignMask | non_smi_exponent));
-  __ sw(scratch(),
-        FieldMemOperand(the_heap_number(), HeapNumber::kExponentOffset));
-  __ mov(scratch(), zero_reg);
-  __ Ret(USE_DELAY_SLOT);
-  __ sw(scratch(),
-        FieldMemOperand(the_heap_number(), HeapNumber::kMantissaOffset));
-}
-
-
 // Handle the case where the lhs and rhs are the same object.
 // Equality is almost reflexive (everything but NaN), so this is a test
 // for "identity and not NaN".
@@ -911,7 +851,7 @@
       // double_scratch can be overwritten in the delay slot.
       // Calculates square root of base.  Check for the special case of
       // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
-      __ Move(double_scratch, -V8_INFINITY);
+      __ Move(double_scratch, static_cast<double>(-V8_INFINITY));
       __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, double_base, double_scratch);
       __ neg_d(double_result, double_scratch);
 
@@ -931,13 +871,13 @@
       // double_scratch can be overwritten in the delay slot.
       // Calculates square root of base.  Check for the special case of
       // Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13).
-      __ Move(double_scratch, -V8_INFINITY);
+      __ Move(double_scratch, static_cast<double>(-V8_INFINITY));
       __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, double_base, double_scratch);
       __ Move(double_result, kDoubleRegZero);
 
       // Add +0 to convert -0 to +0.
       __ add_d(double_scratch, double_base, kDoubleRegZero);
-      __ Move(double_result, 1);
+      __ Move(double_result, 1.);
       __ sqrt_d(double_scratch, double_scratch);
       __ div_d(double_result, double_result, double_scratch);
       __ jmp(&done);
@@ -1053,7 +993,6 @@
 
 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
   CEntryStub::GenerateAheadOfTime(isolate);
-  WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate);
   StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
   StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
   ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
@@ -1094,22 +1033,18 @@
 
 void CEntryStub::Generate(MacroAssembler* masm) {
   // Called from JavaScript; parameters are on stack as if calling JS function
-  // s0: number of arguments including receiver
-  // s1: size of arguments excluding receiver
-  // s2: pointer to builtin function
+  // a0: number of arguments including receiver
+  // a1: pointer to builtin function
   // fp: frame pointer    (restored after C call)
   // sp: stack pointer    (restored as callee's sp after C call)
   // cp: current context  (C callee-saved)
 
   ProfileEntryHookStub::MaybeCallEntryHook(masm);
 
-  // NOTE: s0-s2 hold the arguments of this function instead of a0-a2.
-  // The reason for this is that these arguments would need to be saved anyway
-  // so it's faster to set them up directly.
-  // See MacroAssembler::PrepareCEntryArgs and PrepareCEntryFunction.
-
   // Compute the argv pointer in a callee-saved register.
+  __ dsll(s1, a0, kPointerSizeLog2);
   __ Daddu(s1, sp, s1);
+  __ Dsubu(s1, s1, kPointerSize);
 
   // Enter the exit frame that transitions from JavaScript to C++.
   FrameScope scope(masm, StackFrame::MANUAL);
@@ -1121,7 +1056,8 @@
 
   // Prepare arguments for C routine.
   // a0 = argc
-  __ mov(a0, s0);
+  __ mov(s0, a0);
+  __ mov(s2, a1);
   // a1 = argv (set in the delay slot after find_ra below).
 
   // We are calling compiled C/C++ code. a0 and a1 hold our two arguments. We
@@ -1405,6 +1341,40 @@
 }
 
 
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+  // Return address is in ra.
+  Label miss;
+
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register index = LoadDescriptor::NameRegister();
+  Register scratch = a4;
+  Register result = v0;
+  DCHECK(!scratch.is(receiver) && !scratch.is(index));
+  DCHECK(!FLAG_vector_ics ||
+         (!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
+          result.is(VectorLoadICDescriptor::SlotRegister())));
+
+  // StringCharAtGenerator doesn't use the result register until it's passed
+  // the different miss possibilities. If it did, we would have a conflict
+  // when FLAG_vector_ics is true.
+  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+                                          &miss,  // When not a string.
+                                          &miss,  // When not a number.
+                                          &miss,  // When index out of range.
+                                          STRING_INDEX_IS_ARRAY_INDEX,
+                                          RECEIVER_IS_STRING);
+  char_at_generator.GenerateFast(masm);
+  __ Ret();
+
+  StubRuntimeCallHelper call_helper;
+  char_at_generator.GenerateSlow(masm, call_helper);
+
+  __ bind(&miss);
+  PropertyAccessCompiler::TailCallBuiltin(
+      masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
+
+
 // Uses registers a0 to a4.
 // Expected input (depending on whether args are in registers or on the stack):
 // * object: a0 or at sp + 1 * kPointerSize.
@@ -1416,8 +1386,6 @@
 void InstanceofStub::Generate(MacroAssembler* masm) {
   // Call site inlining and patching implies arguments in registers.
   DCHECK(HasArgsInRegisters() || !HasCallSiteInlineCheck());
-  // ReturnTrueFalse is only implemented for inlined call sites.
-  DCHECK(!ReturnTrueFalseObject() || HasCallSiteInlineCheck());
 
   // Fixed register usage throughout the stub:
   const Register object = a0;  // Object (lhs).
@@ -1442,7 +1410,7 @@
 
   // If there is a call site cache don't look in the global cache, but do the
   // real lookup and update the call site cache.
-  if (!HasCallSiteInlineCheck()) {
+  if (!HasCallSiteInlineCheck() && !ReturnTrueFalseObject()) {
     Label miss;
     __ LoadRoot(at, Heap::kInstanceofCacheFunctionRootIndex);
     __ Branch(&miss, ne, function, Operand(at));
@@ -1501,6 +1469,9 @@
   if (!HasCallSiteInlineCheck()) {
     __ mov(v0, zero_reg);
     __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
+    if (ReturnTrueFalseObject()) {
+      __ LoadRoot(v0, Heap::kTrueValueRootIndex);
+    }
   } else {
     // Patch the call site to return true.
     __ LoadRoot(v0, Heap::kTrueValueRootIndex);
@@ -1519,6 +1490,9 @@
   if (!HasCallSiteInlineCheck()) {
     __ li(v0, Operand(Smi::FromInt(1)));
     __ StoreRoot(v0, Heap::kInstanceofCacheAnswerRootIndex);
+    if (ReturnTrueFalseObject()) {
+      __ LoadRoot(v0, Heap::kFalseValueRootIndex);
+    }
   } else {
     // Patch the call site to return false.
     __ LoadRoot(v0, Heap::kFalseValueRootIndex);
@@ -1542,23 +1516,33 @@
   __ Branch(&slow, ne, scratch, Operand(JS_FUNCTION_TYPE));
 
   // Null is not instance of anything.
-  __ Branch(&object_not_null,
-            ne,
-            scratch,
+  __ Branch(&object_not_null, ne, object,
             Operand(isolate()->factory()->null_value()));
-  __ li(v0, Operand(Smi::FromInt(1)));
+  if (ReturnTrueFalseObject()) {
+    __ LoadRoot(v0, Heap::kFalseValueRootIndex);
+  } else {
+    __ li(v0, Operand(Smi::FromInt(1)));
+  }
   __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
 
   __ bind(&object_not_null);
   // Smi values are not instances of anything.
   __ JumpIfNotSmi(object, &object_not_null_or_smi);
-  __ li(v0, Operand(Smi::FromInt(1)));
+  if (ReturnTrueFalseObject()) {
+    __ LoadRoot(v0, Heap::kFalseValueRootIndex);
+  } else {
+    __ li(v0, Operand(Smi::FromInt(1)));
+  }
   __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
 
   __ bind(&object_not_null_or_smi);
   // String values are not instances of anything.
   __ IsObjectJSStringType(object, scratch, &slow);
-  __ li(v0, Operand(Smi::FromInt(1)));
+  if (ReturnTrueFalseObject()) {
+    __ LoadRoot(v0, Heap::kFalseValueRootIndex);
+  } else {
+    __ li(v0, Operand(Smi::FromInt(1)));
+  }
   __ DropAndRet(HasArgsInRegisters() ? 0 : 2);
 
   // Slow-case.  Tail call builtin.
@@ -1586,8 +1570,14 @@
 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
   Label miss;
   Register receiver = LoadDescriptor::ReceiverRegister();
-  NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, a3,
-                                                          a4, &miss);
+  // Ensure that the vector and slot registers won't be clobbered before
+  // calling the miss handler.
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(a4, a5, VectorLoadICDescriptor::VectorRegister(),
+                     VectorLoadICDescriptor::SlotRegister()));
+
+  NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, a4,
+                                                          a5, &miss);
   __ bind(&miss);
   PropertyAccessCompiler::TailCallBuiltin(
       masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
@@ -2539,14 +2529,14 @@
 
   // A monomorphic miss (i.e, here the cache is not uninitialized) goes
   // megamorphic.
-  __ LoadRoot(at, Heap::kUninitializedSymbolRootIndex);
+  __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex);
   __ Branch(&initialize, eq, a4, Operand(at));
   // MegamorphicSentinel is an immortal immovable object (undefined) so no
   // write-barrier is needed.
   __ bind(&megamorphic);
   __ dsrl(a4, a3, 32- kPointerSizeLog2);
   __ Daddu(a4, a2, Operand(a4));
-  __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex);
+  __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
   __ sd(at, FieldMemOperand(a4, FixedArray::kHeaderSize));
   __ jmp(&done);
 
@@ -2783,14 +2773,16 @@
   DCHECK(!a4.is(object_));
 
   // If the receiver is a smi trigger the non-string case.
-  __ JumpIfSmi(object_, receiver_not_string_);
+  if (check_mode_ == RECEIVER_IS_UNKNOWN) {
+    __ JumpIfSmi(object_, receiver_not_string_);
 
-  // Fetch the instance type of the receiver into result register.
-  __ ld(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
-  __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
-  // If the receiver is not a string trigger the non-string case.
-  __ And(a4, result_, Operand(kIsNotStringMask));
-  __ Branch(receiver_not_string_, ne, a4, Operand(zero_reg));
+    // Fetch the instance type of the receiver into result register.
+    __ ld(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
+    __ lbu(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
+    // If the receiver is not a string trigger the non-string case.
+    __ And(a4, result_, Operand(kIsNotStringMask));
+    __ Branch(receiver_not_string_, ne, a4, Operand(zero_reg));
+  }
 
   // If the index is non-smi trigger the non-smi case.
   __ JumpIfNotSmi(index_, &index_not_smi_);
@@ -2864,6 +2856,10 @@
 void CallICStub::Generate(MacroAssembler* masm) {
   // a1 - function
   // a3 - slot id (Smi)
+  const int with_types_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
+  const int generic_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
   Label extra_checks_or_miss, slow_start;
   Label slow, non_function, wrap, cont;
   Label have_js_function;
@@ -2902,27 +2898,71 @@
   }
 
   __ bind(&extra_checks_or_miss);
-  Label miss;
+  Label uninitialized, miss;
 
-  __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex);
+  __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
   __ Branch(&slow_start, eq, a4, Operand(at));
-  __ LoadRoot(at, Heap::kUninitializedSymbolRootIndex);
-  __ Branch(&miss, eq, a4, Operand(at));
 
-  if (!FLAG_trace_ic) {
-    // We are going megamorphic. If the feedback is a JSFunction, it is fine
-    // to handle it here. More complex cases are dealt with in the runtime.
-    __ AssertNotSmi(a4);
-    __ GetObjectType(a4, a5, a5);
-    __ Branch(&miss, ne, a5, Operand(JS_FUNCTION_TYPE));
-    __ dsrl(a4, a3, 32 - kPointerSizeLog2);
-    __ Daddu(a4, a2, Operand(a4));
-    __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex);
-    __ sd(at, FieldMemOperand(a4, FixedArray::kHeaderSize));
-    __ Branch(&slow_start);
+  // The following cases attempt to handle MISS cases without going to the
+  // runtime.
+  if (FLAG_trace_ic) {
+    __ Branch(&miss);
   }
 
-  // We are here because tracing is on or we are going monomorphic.
+  __ LoadRoot(at, Heap::kuninitialized_symbolRootIndex);
+  __ Branch(&uninitialized, eq, a4, Operand(at));
+
+  // We are going megamorphic. If the feedback is a JSFunction, it is fine
+  // to handle it here. More complex cases are dealt with in the runtime.
+  __ AssertNotSmi(a4);
+  __ GetObjectType(a4, a5, a5);
+  __ Branch(&miss, ne, a5, Operand(JS_FUNCTION_TYPE));
+  __ dsrl(a4, a3, 32 - kPointerSizeLog2);
+  __ Daddu(a4, a2, Operand(a4));
+  __ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
+  __ sd(at, FieldMemOperand(a4, FixedArray::kHeaderSize));
+  // We have to update statistics for runtime profiling.
+  __ ld(a4, FieldMemOperand(a2, with_types_offset));
+  __ Dsubu(a4, a4, Operand(Smi::FromInt(1)));
+  __ sd(a4, FieldMemOperand(a2, with_types_offset));
+  __ ld(a4, FieldMemOperand(a2, generic_offset));
+  __ Daddu(a4, a4, Operand(Smi::FromInt(1)));
+  __ Branch(USE_DELAY_SLOT, &slow_start);
+  __ sd(a4, FieldMemOperand(a2, generic_offset));  // In delay slot.
+
+  __ bind(&uninitialized);
+
+  // We are going monomorphic, provided we actually have a JSFunction.
+  __ JumpIfSmi(a1, &miss);
+
+  // Goto miss case if we do not have a function.
+  __ GetObjectType(a1, a4, a4);
+  __ Branch(&miss, ne, a4, Operand(JS_FUNCTION_TYPE));
+
+  // Make sure the function is not the Array() function, which requires special
+  // behavior on MISS.
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, a4);
+  __ Branch(&miss, eq, a1, Operand(a4));
+
+  // Update stats.
+  __ ld(a4, FieldMemOperand(a2, with_types_offset));
+  __ Daddu(a4, a4, Operand(Smi::FromInt(1)));
+  __ sd(a4, FieldMemOperand(a2, with_types_offset));
+
+  // Store the function.
+  __ dsrl(a4, a3, 32 - kPointerSizeLog2);
+  __ Daddu(a4, a2, Operand(a4));
+  __ Daddu(a4, a4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ sd(a1, MemOperand(a4, 0));
+
+  // Update the write barrier.
+  __ mov(a5, a1);
+  __ RecordWrite(a2, a4, a5, kRAHasNotBeenSaved, kDontSaveFPRegs,
+                 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+  __ Branch(&have_js_function);
+
+  // We are here because tracing is on or we encountered a MISS case we can't
+  // handle here.
   __ bind(&miss);
   GenerateMiss(masm);
 
@@ -3329,14 +3369,57 @@
   // a1: instance type
   // a2: length
   // a3: from index (untagged)
-  StringCharAtGenerator generator(
-      v0, a3, a2, v0, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
+  StringCharAtGenerator generator(v0, a3, a2, v0, &runtime, &runtime, &runtime,
+                                  STRING_INDEX_IS_NUMBER, RECEIVER_IS_STRING);
   generator.GenerateFast(masm);
   __ DropAndRet(3);
   generator.SkipSlow(masm, &runtime);
 }
 
 
+void ToNumberStub::Generate(MacroAssembler* masm) {
+  // The ToNumber stub takes one argument in a0.
+  Label not_smi;
+  __ JumpIfNotSmi(a0, &not_smi);
+  __ Ret(USE_DELAY_SLOT);
+  __ mov(v0, a0);
+  __ bind(&not_smi);
+
+  Label not_heap_number;
+  __ ld(a1, FieldMemOperand(a0, HeapObject::kMapOffset));
+  __ lbu(a1, FieldMemOperand(a1, Map::kInstanceTypeOffset));
+  // a0: object
+  // a1: instance type.
+  __ Branch(&not_heap_number, ne, a1, Operand(HEAP_NUMBER_TYPE));
+  __ Ret(USE_DELAY_SLOT);
+  __ mov(v0, a0);
+  __ bind(&not_heap_number);
+
+  Label not_string, slow_string;
+  __ Branch(&not_string, hs, a1, Operand(FIRST_NONSTRING_TYPE));
+  // Check if string has a cached array index.
+  __ ld(a2, FieldMemOperand(a0, String::kHashFieldOffset));
+  __ And(at, a2, Operand(String::kContainsCachedArrayIndexMask));
+  __ Branch(&slow_string, ne, at, Operand(zero_reg));
+  __ IndexFromHash(a2, a0);
+  __ Ret(USE_DELAY_SLOT);
+  __ mov(v0, a0);
+  __ bind(&slow_string);
+  __ push(a0);  // Push argument.
+  __ TailCallRuntime(Runtime::kStringToNumber, 1, 1);
+  __ bind(&not_string);
+
+  Label not_oddball;
+  __ Branch(&not_oddball, ne, a1, Operand(ODDBALL_TYPE));
+  __ Ret(USE_DELAY_SLOT);
+  __ ld(v0, FieldMemOperand(a0, Oddball::kToNumberOffset));
+  __ bind(&not_oddball);
+
+  __ push(a0);  // Push argument.
+  __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
+}
+
+
 void StringHelper::GenerateFlatOneByteStringEquals(
     MacroAssembler* masm, Register left, Register right, Register scratch1,
     Register scratch2, Register scratch3) {
diff --git a/src/mips64/code-stubs-mips64.h b/src/mips64/code-stubs-mips64.h
index 6c324bb..edc1bd2 100644
--- a/src/mips64/code-stubs-mips64.h
+++ b/src/mips64/code-stubs-mips64.h
@@ -73,56 +73,6 @@
   DEFINE_PLATFORM_CODE_STUB(RestoreRegistersState, PlatformCodeStub);
 };
 
-// This stub can convert a signed int32 to a heap number (double).  It does
-// not work for int32s that are in Smi range!  No GC occurs during this stub
-// so you don't have to set up the frame.
-class WriteInt32ToHeapNumberStub : public PlatformCodeStub {
- public:
-  WriteInt32ToHeapNumberStub(Isolate* isolate, Register the_int,
-                             Register the_heap_number, Register scratch,
-                             Register scratch2)
-      : PlatformCodeStub(isolate) {
-    minor_key_ = IntRegisterBits::encode(the_int.code()) |
-                 HeapNumberRegisterBits::encode(the_heap_number.code()) |
-                 ScratchRegisterBits::encode(scratch.code()) |
-                 SignRegisterBits::encode(scratch2.code());
-    DCHECK(IntRegisterBits::is_valid(the_int.code()));
-    DCHECK(HeapNumberRegisterBits::is_valid(the_heap_number.code()));
-    DCHECK(ScratchRegisterBits::is_valid(scratch.code()));
-    DCHECK(SignRegisterBits::is_valid(scratch2.code()));
-  }
-
-  static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
-
- private:
-  void Generate(MacroAssembler* masm);
-
-  Register the_int() const {
-    return Register::from_code(IntRegisterBits::decode(minor_key_));
-  }
-
-  Register the_heap_number() const {
-    return Register::from_code(HeapNumberRegisterBits::decode(minor_key_));
-  }
-
-  Register scratch() const {
-    return Register::from_code(ScratchRegisterBits::decode(minor_key_));
-  }
-
-  Register sign() const {
-    return Register::from_code(SignRegisterBits::decode(minor_key_));
-  }
-
-  // Minor key encoding in 16 bits.
-  class IntRegisterBits: public BitField<int, 0, 4> {};
-  class HeapNumberRegisterBits: public BitField<int, 4, 4> {};
-  class ScratchRegisterBits: public BitField<int, 8, 4> {};
-  class SignRegisterBits: public BitField<int, 12, 4> {};
-
-  DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
-  DEFINE_CODE_STUB(WriteInt32ToHeapNumber, PlatformCodeStub);
-};
-
 
 class RecordWriteStub: public PlatformCodeStub {
  public:
@@ -152,7 +102,7 @@
     INCREMENTAL_COMPACTION
   };
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
   static void PatchBranchIntoNop(MacroAssembler* masm, int pos) {
     const unsigned offset = masm->instr_at(pos) & kImm16Mask;
@@ -279,9 +229,9 @@
     kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
   };
 
-  virtual inline Major MajorKey() const FINAL OVERRIDE { return RecordWrite; }
+  inline Major MajorKey() const FINAL { return RecordWrite; }
 
-  virtual void Generate(MacroAssembler* masm) OVERRIDE;
+  void Generate(MacroAssembler* masm) OVERRIDE;
   void GenerateIncremental(MacroAssembler* masm, Mode mode);
   void CheckNeedsToInformIncrementalMarker(
       MacroAssembler* masm,
@@ -289,7 +239,7 @@
       Mode mode);
   void InformIncrementalMarker(MacroAssembler* masm);
 
-  void Activate(Code* code) {
+  void Activate(Code* code) OVERRIDE {
     code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
   }
 
@@ -337,7 +287,7 @@
   void GenerateCall(MacroAssembler* masm, Register target);
 
  private:
-  bool NeedsImmovableCode() { return true; }
+  bool NeedsImmovableCode() OVERRIDE { return true; }
 
   DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
   DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub);
@@ -369,7 +319,7 @@
                                      Register r0,
                                      Register r1);
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
  private:
   static const int kInlinedProbes = 4;
diff --git a/src/mips64/codegen-mips64.cc b/src/mips64/codegen-mips64.cc
index fb395f7..b292506 100644
--- a/src/mips64/codegen-mips64.cc
+++ b/src/mips64/codegen-mips64.cc
@@ -786,9 +786,23 @@
   __ Daddu(src_elements, src_elements,
       Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag + 4));
   __ Daddu(dst_elements, array, Operand(FixedArray::kHeaderSize));
-  __ Daddu(array, array, Operand(kHeapObjectTag));
   __ SmiScale(dst_end, dst_end, kPointerSizeLog2);
   __ Daddu(dst_end, dst_elements, dst_end);
+
+  // Allocating heap numbers in the loop below can fail and cause a jump to
+  // gc_required. We can't leave a partly initialized FixedArray behind,
+  // so pessimistically fill it with holes now.
+  Label initialization_loop, initialization_loop_entry;
+  __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
+  __ Branch(&initialization_loop_entry);
+  __ bind(&initialization_loop);
+  __ sd(scratch, MemOperand(dst_elements));
+  __ Daddu(dst_elements, dst_elements, Operand(kPointerSize));
+  __ bind(&initialization_loop_entry);
+  __ Branch(&initialization_loop, lt, dst_elements, Operand(dst_end));
+
+  __ Daddu(dst_elements, array, Operand(FixedArray::kHeaderSize));
+  __ Daddu(array, array, Operand(kHeapObjectTag));
   __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
   // Using offsetted addresses.
   // dst_elements: begin of destination FixedArray element fields, not tagged
@@ -1019,7 +1033,7 @@
   // Mov 1 in double_scratch2 as math_exp_constants_array[8] == 1.
   DCHECK(*reinterpret_cast<double*>
          (ExternalReference::math_exp_constants(8).address()) == 1);
-  __ Move(double_scratch2, 1);
+  __ Move(double_scratch2, 1.);
   __ add_d(result, result, double_scratch2);
   __ dsrl(temp1, temp2, 11);
   __ Ext(temp2, temp2, 0, 11);
diff --git a/src/mips64/constants-mips64.cc b/src/mips64/constants-mips64.cc
index dfd6243..dd34c57 100644
--- a/src/mips64/constants-mips64.cc
+++ b/src/mips64/constants-mips64.cc
@@ -287,6 +287,7 @@
       switch (FunctionFieldRaw()) {
         case INS:
         case EXT:
+        case DEXT:
           return kRegisterType;
         default:
           return kUnsupported;
diff --git a/src/mips64/constants-mips64.h b/src/mips64/constants-mips64.h
index 521869b..d12148a 100644
--- a/src/mips64/constants-mips64.h
+++ b/src/mips64/constants-mips64.h
@@ -574,52 +574,49 @@
 // because 'NegateCondition' function flips LSB to negate condition.
 enum Condition {
   // Any value < 0 is considered no_condition.
-  kNoCondition  = -1,
-
-  overflow      =  0,
-  no_overflow   =  1,
-  Uless         =  2,
-  Ugreater_equal=  3,
-  equal         =  4,
-  not_equal     =  5,
-  Uless_equal   =  6,
-  Ugreater      =  7,
-  negative      =  8,
-  positive      =  9,
-  parity_even   = 10,
-  parity_odd    = 11,
-  less          = 12,
+  kNoCondition = -1,
+  overflow = 0,
+  no_overflow = 1,
+  Uless = 2,
+  Ugreater_equal = 3,
+  equal = 4,
+  not_equal = 5,
+  Uless_equal = 6,
+  Ugreater = 7,
+  negative = 8,
+  positive = 9,
+  parity_even = 10,
+  parity_odd = 11,
+  less = 12,
   greater_equal = 13,
-  less_equal    = 14,
-  greater       = 15,
-  ueq           = 16,  // Unordered or Equal.
-  nue           = 17,  // Not (Unordered or Equal).
-
-  cc_always     = 18,
+  less_equal = 14,
+  greater = 15,
+  ueq = 16,  // Unordered or Equal.
+  nue = 17,  // Not (Unordered or Equal).
+  cc_always = 18,
 
   // Aliases.
-  carry         = Uless,
-  not_carry     = Ugreater_equal,
-  zero          = equal,
-  eq            = equal,
-  not_zero      = not_equal,
-  ne            = not_equal,
-  nz            = not_equal,
-  sign          = negative,
-  not_sign      = positive,
-  mi            = negative,
-  pl            = positive,
-  hi            = Ugreater,
-  ls            = Uless_equal,
-  ge            = greater_equal,
-  lt            = less,
-  gt            = greater,
-  le            = less_equal,
-  hs            = Ugreater_equal,
-  lo            = Uless,
-  al            = cc_always,
-
-  cc_default    = kNoCondition
+  carry = Uless,
+  not_carry = Ugreater_equal,
+  zero = equal,
+  eq = equal,
+  not_zero = not_equal,
+  ne = not_equal,
+  nz = not_equal,
+  sign = negative,
+  not_sign = positive,
+  mi = negative,
+  pl = positive,
+  hi = Ugreater,
+  ls = Uless_equal,
+  ge = greater_equal,
+  lt = less,
+  gt = greater,
+  le = less_equal,
+  hs = Ugreater_equal,
+  lo = Uless,
+  al = cc_always,
+  cc_default = kNoCondition
 };
 
 
diff --git a/src/mips64/debug-mips64.cc b/src/mips64/debug-mips64.cc
index 831dc4e..0bb0c4a 100644
--- a/src/mips64/debug-mips64.cc
+++ b/src/mips64/debug-mips64.cc
@@ -190,7 +190,11 @@
 void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
   Register receiver = LoadDescriptor::ReceiverRegister();
   Register name = LoadDescriptor::NameRegister();
-  Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0);
+  RegList regs = receiver.bit() | name.bit();
+  if (FLAG_vector_ics) {
+    regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit();
+  }
+  Generate_DebugBreakCallHelper(masm, regs, 0);
 }
 
 
diff --git a/src/mips64/deoptimizer-mips64.cc b/src/mips64/deoptimizer-mips64.cc
index 2550b76..d7a7f05 100644
--- a/src/mips64/deoptimizer-mips64.cc
+++ b/src/mips64/deoptimizer-mips64.cc
@@ -19,6 +19,12 @@
 }
 
 
+void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
+  // Empty because there is no need for relocation information for the code
+  // patching in Deoptimizer::PatchCodeForDeoptimization below.
+}
+
+
 void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
   Address code_start_address = code->instruction_start();
   // Invalidate the relocation information, as it will become invalid by the
@@ -101,9 +107,8 @@
   ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_);
   intptr_t handler = reinterpret_cast<intptr_t>(xref.address());
   int params = descriptor->GetHandlerParameterCount();
-  output_frame->SetRegister(s0.code(), params);
-  output_frame->SetRegister(s1.code(), (params - 1) * kPointerSize);
-  output_frame->SetRegister(s2.code(), handler);
+  output_frame->SetRegister(a0.code(), params);
+  output_frame->SetRegister(a1.code(), handler);
 }
 
 
diff --git a/src/mips64/disasm-mips64.cc b/src/mips64/disasm-mips64.cc
index d47950f..3f0642d 100644
--- a/src/mips64/disasm-mips64.cc
+++ b/src/mips64/disasm-mips64.cc
@@ -963,6 +963,10 @@
           Format(instr, "ext     'rt, 'rs, 'sa, 'ss1");
           break;
         }
+        case DEXT: {
+          Format(instr, "dext    'rt, 'rs, 'sa, 'ss1");
+          break;
+        }
         default:
           UNREACHABLE();
       }
diff --git a/src/mips64/full-codegen-mips64.cc b/src/mips64/full-codegen-mips64.cc
index 8f8c376..9d4ed09 100644
--- a/src/mips64/full-codegen-mips64.cc
+++ b/src/mips64/full-codegen-mips64.cc
@@ -201,10 +201,10 @@
     Comment cmnt(masm_, "[ Allocate context");
     // Argument to NewContext is the function, which is still in a1.
     bool need_write_barrier = true;
-    if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
+    if (FLAG_harmony_scoping && info->scope()->is_script_scope()) {
       __ push(a1);
       __ Push(info->scope()->GetScopeInfo());
-      __ CallRuntime(Runtime::kNewGlobalContext, 2);
+      __ CallRuntime(Runtime::kNewScriptContext, 2);
     } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
       FastNewContextStub stub(isolate(), heap_slots);
       __ CallStub(&stub);
@@ -924,7 +924,7 @@
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
-  __ LoadContext(a1, scope_->ContextChainLength(scope_->GlobalScope()));
+  __ LoadContext(a1, scope_->ContextChainLength(scope_->ScriptScope()));
   __ ld(a1, ContextOperand(a1, variable->interface()->Index()));
   __ ld(a1, ContextOperand(a1, Context::EXTENSION_INDEX));
 
@@ -1088,7 +1088,7 @@
 
 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   Comment cmnt(masm_, "[ ForInStatement");
-  int slot = stmt->ForInFeedbackSlot();
+  FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
   SetStatementPosition(stmt);
 
   Label loop, exit;
@@ -1097,6 +1097,7 @@
 
   // Get the object to enumerate over. If the object is null or undefined, skip
   // over the loop.  See ECMA-262 version 5, section 12.6.4.
+  SetExpressionPosition(stmt->enumerable());
   VisitForAccumulatorValue(stmt->enumerable());
   __ mov(a0, result_register());  // Result as param to InvokeBuiltin below.
   __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
@@ -1116,6 +1117,7 @@
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ mov(a0, v0);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ push(a0);
 
   // Check for proxies.
@@ -1140,6 +1142,7 @@
   __ bind(&call_runtime);
   __ push(a0);  // Duplicate the enumerable object on the stack.
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
 
   // If we got a map from the runtime call, we can do a fast
   // modification check. Otherwise, we got a fixed array, and we have
@@ -1176,7 +1179,8 @@
 
   __ li(a1, FeedbackVector());
   __ li(a2, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
-  __ sd(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(slot)));
+  int vector_index = FeedbackVector()->GetIndex(slot);
+  __ sd(a2, FieldMemOperand(a1, FixedArray::OffsetOfElementAt(vector_index)));
 
   __ li(a1, Operand(Smi::FromInt(1)));  // Smi indicates slow check
   __ ld(a2, MemOperand(sp, 0 * kPointerSize));  // Get enumerated object
@@ -1193,6 +1197,8 @@
   // Generate code for doing the condition check.
   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
   __ bind(&loop);
+  SetExpressionPosition(stmt->each());
+
   // Load the current count to a0, load the length to a1.
   __ ld(a0, MemOperand(sp, 0 * kPointerSize));
   __ ld(a1, MemOperand(sp, 1 * kPointerSize));
@@ -1262,48 +1268,6 @@
 }
 
 
-void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
-  Comment cmnt(masm_, "[ ForOfStatement");
-  SetStatementPosition(stmt);
-
-  Iteration loop_statement(this, stmt);
-  increment_loop_depth();
-
-  // var iterator = iterable[Symbol.iterator]();
-  VisitForEffect(stmt->assign_iterator());
-
-  // Loop entry.
-  __ bind(loop_statement.continue_label());
-
-  // result = iterator.next()
-  VisitForEffect(stmt->next_result());
-
-  // if (result.done) break;
-  Label result_not_done;
-  VisitForControl(stmt->result_done(),
-                  loop_statement.break_label(),
-                  &result_not_done,
-                  &result_not_done);
-  __ bind(&result_not_done);
-
-  // each = result.value
-  VisitForEffect(stmt->assign_each());
-
-  // Generate code for the body of the loop.
-  Visit(stmt->body());
-
-  // Check stack before looping.
-  PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
-  EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
-  __ jmp(loop_statement.continue_label());
-
-  // Exit and decrement the loop depth.
-  PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
-  __ bind(loop_statement.break_label());
-  decrement_loop_depth();
-}
-
-
 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
                                        bool pretenure) {
   // Use the fast case closure allocation code that allocates in new
@@ -1346,7 +1310,13 @@
   Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
   __ li(LoadDescriptor::NameRegister(), home_object_symbol);
 
-  CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  if (FLAG_vector_ics) {
+    __ li(VectorLoadICDescriptor::SlotRegister(),
+          Operand(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
+    CallLoadIC(NOT_CONTEXTUAL);
+  } else {
+    CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  }
 
   Label done;
   __ Branch(&done, ne, v0, Operand(isolate()->factory()->undefined_value()));
@@ -1355,6 +1325,19 @@
 }
 
 
+void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
+                                                  int offset) {
+  if (NeedsHomeObject(initializer)) {
+    __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
+    __ li(StoreDescriptor::NameRegister(),
+          Operand(isolate()->factory()->home_object_symbol()));
+    __ ld(StoreDescriptor::ValueRegister(),
+          MemOperand(sp, offset * kPointerSize));
+    CallStoreIC();
+  }
+}
+
+
 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
                                                       TypeofState typeof_state,
                                                       Label* slow) {
@@ -1404,7 +1387,7 @@
   __ li(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
   if (FLAG_vector_ics) {
     __ li(VectorLoadICDescriptor::SlotRegister(),
-          Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
+          Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
   }
 
   ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
@@ -1495,7 +1478,7 @@
       __ li(LoadDescriptor::NameRegister(), Operand(var->name()));
       if (FLAG_vector_ics) {
         __ li(VectorLoadICDescriptor::SlotRegister(),
-              Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
+              Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
       }
       CallLoadIC(CONTEXTUAL);
       context()->Plug(v0);
@@ -1673,6 +1656,7 @@
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in v0.
@@ -1701,6 +1685,8 @@
         DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
         // Fall through.
       case ObjectLiteral::Property::COMPUTED:
+        // It is safe to use [[Put]] here because the boilerplate already
+        // contains computed properties with an uninitialized value.
         if (key->value()->IsInternalizedString()) {
           if (property->emit_store()) {
             VisitForAccumulatorValue(value);
@@ -1710,6 +1696,14 @@
             __ ld(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
             CallStoreIC(key->LiteralFeedbackId());
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
+
+            if (NeedsHomeObject(value)) {
+              __ Move(StoreDescriptor::ReceiverRegister(), v0);
+              __ li(StoreDescriptor::NameRegister(),
+                    Operand(isolate()->factory()->home_object_symbol()));
+              __ ld(StoreDescriptor::ValueRegister(), MemOperand(sp));
+              CallStoreIC();
+            }
           } else {
             VisitForEffect(value);
           }
@@ -1721,6 +1715,7 @@
         VisitForStackValue(key);
         VisitForStackValue(value);
         if (property->emit_store()) {
+          EmitSetHomeObjectIfNeeded(value, 2);
           __ li(a0, Operand(Smi::FromInt(SLOPPY)));  // PropertyAttributes.
           __ push(a0);
           __ CallRuntime(Runtime::kSetProperty, 4);
@@ -1734,7 +1729,7 @@
         __ push(a0);
         VisitForStackValue(value);
         if (property->emit_store()) {
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           __ Drop(2);
         }
@@ -1757,7 +1752,9 @@
     __ push(a0);
     VisitForStackValue(it->first);
     EmitAccessor(it->second->getter);
+    EmitSetHomeObjectIfNeeded(it->second->getter, 2);
     EmitAccessor(it->second->setter);
+    EmitSetHomeObjectIfNeeded(it->second->setter, 3);
     __ li(a0, Operand(Smi::FromInt(NONE)));
     __ push(a0);
     __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
@@ -1869,16 +1866,8 @@
 
   Comment cmnt(masm_, "[ Assignment");
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
-  if (property != NULL) {
-    assign_type = (property->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(property);
 
   // Evaluate LHS expression.
   switch (assign_type) {
@@ -1894,6 +1883,30 @@
         VisitForStackValue(property->obj());
       }
       break;
+    case NAMED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        const Register scratch = a1;
+        __ ld(scratch, MemOperand(sp, kPointerSize));
+        __ Push(scratch, result_register());
+      }
+      break;
+    case KEYED_SUPER_PROPERTY: {
+      const Register scratch = a1;
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Move(scratch, result_register());
+      VisitForAccumulatorValue(property->key());
+      __ Push(scratch, result_register());
+      if (expr->is_compound()) {
+        const Register scratch1 = a4;
+        __ ld(scratch1, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch1, scratch, result_register());
+      }
+      break;
+    }
     case KEYED_PROPERTY:
       // We need the key and receiver on both the stack and in v0 and a1.
       if (expr->is_compound()) {
@@ -1922,6 +1935,14 @@
           EmitNamedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
           break;
+        case NAMED_SUPER_PROPERTY:
+          EmitNamedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
+        case KEYED_SUPER_PROPERTY:
+          EmitKeyedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
         case KEYED_PROPERTY:
           EmitKeyedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
@@ -1968,6 +1989,14 @@
     case NAMED_PROPERTY:
       EmitNamedPropertyAssignment(expr);
       break;
+    case NAMED_SUPER_PROPERTY:
+      EmitNamedSuperPropertyStore(property);
+      context()->Plug(v0);
+      break;
+    case KEYED_SUPER_PROPERTY:
+      EmitKeyedSuperPropertyStore(property);
+      context()->Plug(v0);
+      break;
     case KEYED_PROPERTY:
       EmitKeyedPropertyAssignment(expr);
       break;
@@ -2097,7 +2126,7 @@
       __ ld(load_name, MemOperand(sp, 2 * kPointerSize));
       if (FLAG_vector_ics) {
         __ li(VectorLoadICDescriptor::SlotRegister(),
-              Operand(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
+              Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
       }
       Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
       CallIC(ic, TypeFeedbackId::None());
@@ -2117,7 +2146,7 @@
       __ LoadRoot(load_name, Heap::kdone_stringRootIndex);  // "done"
       if (FLAG_vector_ics) {
         __ li(VectorLoadICDescriptor::SlotRegister(),
-              Operand(Smi::FromInt(expr->DoneFeedbackSlot())));
+              Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
       }
       CallLoadIC(NOT_CONTEXTUAL);                           // v0=result.done
       __ mov(a0, v0);
@@ -2130,7 +2159,7 @@
       __ LoadRoot(load_name, Heap::kvalue_stringRootIndex);  // "value"
       if (FLAG_vector_ics) {
         __ li(VectorLoadICDescriptor::SlotRegister(),
-              Operand(Smi::FromInt(expr->ValueFeedbackSlot())));
+              Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
       }
       CallLoadIC(NOT_CONTEXTUAL);                            // v0=result.value
       context()->DropAndPlug(2, v0);                         // drop iter and g
@@ -2151,14 +2180,6 @@
   VisitForAccumulatorValue(value);
   __ pop(a1);
 
-  // Check generator state.
-  Label wrong_state, closed_state, done;
-  __ ld(a3, FieldMemOperand(a1, JSGeneratorObject::kContinuationOffset));
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
-  __ Branch(&closed_state, eq, a3, Operand(zero_reg));
-  __ Branch(&wrong_state, lt, a3, Operand(zero_reg));
-
   // Load suspended function and context.
   __ ld(cp, FieldMemOperand(a1, JSGeneratorObject::kContextOffset));
   __ ld(a4, FieldMemOperand(a1, JSGeneratorObject::kFunctionOffset));
@@ -2183,7 +2204,7 @@
 
   // Enter a new JavaScript frame, and initialize its slots as they were when
   // the generator was suspended.
-  Label resume_frame;
+  Label resume_frame, done;
   __ bind(&push_frame);
   __ Call(&resume_frame);
   __ jmp(&done);
@@ -2232,26 +2253,6 @@
   // Not reached: the runtime call returns elsewhere.
   __ stop("not-reached");
 
-  // Reach here when generator is closed.
-  __ bind(&closed_state);
-  if (resume_mode == JSGeneratorObject::NEXT) {
-    // Return completed iterator result when generator is closed.
-    __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
-    __ push(a2);
-    // Pop value from top-of-stack slot; box result into result register.
-    EmitCreateIteratorResult(true);
-  } else {
-    // Throw the provided value.
-    __ push(a0);
-    __ CallRuntime(Runtime::kThrow, 1);
-  }
-  __ jmp(&done);
-
-  // Throw error if we attempt to operate on a running generator.
-  __ bind(&wrong_state);
-  __ push(a1);
-  __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
-
   __ bind(&done);
   context()->Plug(result_register());
 }
@@ -2304,7 +2305,7 @@
   __ li(LoadDescriptor::NameRegister(), Operand(key->value()));
   if (FLAG_vector_ics) {
     __ li(VectorLoadICDescriptor::SlotRegister(),
-          Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
+          Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
     CallLoadIC(NOT_CONTEXTUAL);
   } else {
     CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
@@ -2313,15 +2314,12 @@
 
 
 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object.
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
   DCHECK(!key->value()->IsSmi());
   DCHECK(prop->IsSuperAccess());
 
-  SuperReference* super_ref = prop->obj()->AsSuperReference();
-  EmitLoadHomeObject(super_ref);
-  __ Push(v0);
-  VisitForStackValue(super_ref->this_var());
   __ Push(key->value());
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 }
@@ -2333,7 +2331,7 @@
   Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
   if (FLAG_vector_ics) {
     __ li(VectorLoadICDescriptor::SlotRegister(),
-          Operand(Smi::FromInt(prop->PropertyFeedbackSlot())));
+          Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
     CallIC(ic);
   } else {
     CallIC(ic, prop->PropertyFeedbackId());
@@ -2341,6 +2339,14 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object, key.
+  SetSourcePosition(prop->position());
+
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+}
+
+
 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
                                               Token::Value op,
                                               OverwriteMode mode,
@@ -2433,6 +2439,63 @@
 }
 
 
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
+  // Constructor is in v0.
+  DCHECK(lit != NULL);
+  __ push(v0);
+
+  // No access check is needed here since the constructor is created by the
+  // class literal.
+  Register scratch = a1;
+  __ ld(scratch,
+        FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset));
+  __ push(scratch);
+
+  for (int i = 0; i < lit->properties()->length(); i++) {
+    ObjectLiteral::Property* property = lit->properties()->at(i);
+    Literal* key = property->key()->AsLiteral();
+    Expression* value = property->value();
+    DCHECK(key != NULL);
+
+    if (property->is_static()) {
+      __ ld(scratch, MemOperand(sp, kPointerSize));  // constructor
+    } else {
+      __ ld(scratch, MemOperand(sp, 0));  // prototype
+    }
+    __ push(scratch);
+    VisitForStackValue(key);
+    VisitForStackValue(value);
+    EmitSetHomeObjectIfNeeded(value, 2);
+
+    switch (property->kind()) {
+      case ObjectLiteral::Property::CONSTANT:
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+      case ObjectLiteral::Property::COMPUTED:
+      case ObjectLiteral::Property::PROTOTYPE:
+        __ CallRuntime(Runtime::kDefineClassMethod, 3);
+        break;
+
+      case ObjectLiteral::Property::GETTER:
+        __ CallRuntime(Runtime::kDefineClassGetter, 3);
+        break;
+
+      case ObjectLiteral::Property::SETTER:
+        __ CallRuntime(Runtime::kDefineClassSetter, 3);
+        break;
+
+      default:
+        UNREACHABLE();
+    }
+  }
+
+  // prototype
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+
+  // constructor
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+}
+
+
 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
                                      Token::Value op,
                                      OverwriteMode mode) {
@@ -2449,16 +2512,8 @@
 void FullCodeGenerator::EmitAssignment(Expression* expr) {
   DCHECK(expr->IsValidReferenceExpression());
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->AsProperty();
-  if (prop != NULL) {
-    assign_type = (prop->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   switch (assign_type) {
     case VARIABLE: {
@@ -2477,6 +2532,42 @@
       CallStoreIC();
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      __ Push(v0);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      // stack: value, this; v0: home_object
+      Register scratch = a2;
+      Register scratch2 = a3;
+      __ mov(scratch, result_register());             // home_object
+      __ ld(v0, MemOperand(sp, kPointerSize));        // value
+      __ ld(scratch2, MemOperand(sp, 0));             // this
+      __ sd(scratch2, MemOperand(sp, kPointerSize));  // this
+      __ sd(scratch, MemOperand(sp, 0));              // home_object
+      // stack: this, home_object; v0: value
+      EmitNamedSuperPropertyStore(prop);
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      __ Push(v0);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(prop->key());
+      Register scratch = a2;
+      Register scratch2 = a3;
+      __ ld(scratch2, MemOperand(sp, 2 * kPointerSize));  // value
+      // stack: value, this, home_object; v0: key, a3: value
+      __ ld(scratch, MemOperand(sp, kPointerSize));  // this
+      __ sd(scratch, MemOperand(sp, 2 * kPointerSize));
+      __ ld(scratch, MemOperand(sp, 0));  // home_object
+      __ sd(scratch, MemOperand(sp, kPointerSize));
+      __ sd(v0, MemOperand(sp, 0));
+      __ Move(v0, scratch2);
+      // stack: this, home_object, key; v0: value.
+      EmitKeyedSuperPropertyStore(prop);
+      break;
+    }
     case KEYED_PROPERTY: {
       __ push(result_register());  // Preserve value.
       VisitForStackValue(prop->obj());
@@ -2547,7 +2638,6 @@
     // Perform the assignment.
     __ bind(&assign);
     EmitStoreToStackLocalOrContextSlot(var, location);
-
   } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
     if (var->IsLookupSlot()) {
       // Assignment to var.
@@ -2572,8 +2662,9 @@
       }
       EmitStoreToStackLocalOrContextSlot(var, location);
     }
+  } else if (IsSignallingAssignmentToConst(var, op, strict_mode())) {
+    __ CallRuntime(Runtime::kThrowConstAssignError, 0);
   }
-  // Non-initializing assignments to consts are ignored.
 }
 
 
@@ -2596,6 +2687,35 @@
 }
 
 
+void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // v0 : value
+  // stack : receiver ('this'), home_object
+  DCHECK(prop != NULL);
+  Literal* key = prop->key()->AsLiteral();
+  DCHECK(key != NULL);
+
+  __ Push(key->value());
+  __ Push(v0);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
+                                          : Runtime::kStoreToSuper_Sloppy),
+                 4);
+}
+
+
+void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // v0 : value
+  // stack : receiver ('this'), home_object, key
+  DCHECK(prop != NULL);
+
+  __ Push(v0);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict
+                                          : Runtime::kStoreKeyedToSuper_Sloppy),
+                 4);
+}
+
+
 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
   // Assignment to a property, using a keyed store IC.
 
@@ -2628,16 +2748,27 @@
       __ Move(LoadDescriptor::ReceiverRegister(), v0);
       EmitNamedPropertyLoad(expr);
     } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ Push(result_register());
       EmitNamedSuperPropertyLoad(expr);
     }
     PrepareForBailoutForId(expr->LoadId(), TOS_REG);
     context()->Plug(v0);
   } else {
-    VisitForStackValue(expr->obj());
-    VisitForAccumulatorValue(expr->key());
-    __ Move(LoadDescriptor::NameRegister(), v0);
-    __ pop(LoadDescriptor::ReceiverRegister());
-    EmitKeyedPropertyLoad(expr);
+    if (!expr->IsSuperAccess()) {
+      VisitForStackValue(expr->obj());
+      VisitForAccumulatorValue(expr->key());
+      __ Move(LoadDescriptor::NameRegister(), v0);
+      __ pop(LoadDescriptor::ReceiverRegister());
+      EmitKeyedPropertyLoad(expr);
+    } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForStackValue(expr->key());
+      EmitKeyedSuperPropertyLoad(expr);
+    }
     context()->Plug(v0);
   }
 }
@@ -2696,18 +2827,16 @@
   const Register scratch = a1;
   SuperReference* super_ref = prop->obj()->AsSuperReference();
   EmitLoadHomeObject(super_ref);
-  __ Push(v0);
+  __ mov(scratch, v0);
   VisitForAccumulatorValue(super_ref->this_var());
-  __ Push(v0);
-  __ ld(scratch, MemOperand(sp, kPointerSize));
-  __ Push(scratch, v0);
+  __ Push(scratch, v0, v0, scratch);
   __ Push(key->value());
 
   // Stack here:
   //  - home_object
   //  - this (receiver)
-  //  - home_object <-- LoadFromSuper will pop here and below.
-  //  - this (receiver)
+  //  - this (receiver) <-- LoadFromSuper will pop here and below.
+  //  - home_object
   //  - key
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 
@@ -2745,6 +2874,40 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
+  Expression* callee = expr->expression();
+  DCHECK(callee->IsProperty());
+  Property* prop = callee->AsProperty();
+  DCHECK(prop->IsSuperAccess());
+
+  SetSourcePosition(prop->position());
+  // Load the function from the receiver.
+  const Register scratch = a1;
+  SuperReference* super_ref = prop->obj()->AsSuperReference();
+  EmitLoadHomeObject(super_ref);
+  __ Move(scratch, v0);
+  VisitForAccumulatorValue(super_ref->this_var());
+  __ Push(scratch, v0, v0, scratch);
+  VisitForStackValue(prop->key());
+
+  // Stack here:
+  //  - home_object
+  //  - this (receiver)
+  //  - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
+  //  - home_object
+  //  - key
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+
+  // Replace home_object with target function.
+  __ sd(v0, MemOperand(sp, kPointerSize));
+
+  // Stack here:
+  // - target function
+  // - this (receiver)
+  EmitCall(expr, CallICState::METHOD);
+}
+
+
 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Load the arguments.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2759,7 +2922,7 @@
   SetSourcePosition(expr->position());
   Handle<Code> ic = CallIC::initialize_stub(
       isolate(), arg_count, call_type);
-  __ li(a3, Operand(Smi::FromInt(expr->CallFeedbackSlot())));
+  __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackSlot())));
   __ ld(a1, MemOperand(sp, (arg_count + 1) * kPointerSize));
   // Don't assign a type feedback id to the IC, since type feedback is provided
   // by the vector above.
@@ -2799,6 +2962,14 @@
 }
 
 
+void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
+  DCHECK(super_ref != NULL);
+  __ ld(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ Push(a0);
+  __ CallRuntime(Runtime::kGetPrototype, 1);
+}
+
+
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -2838,6 +3009,8 @@
       // v1 (receiver). Touch up the stack with the right values.
       __ sd(v0, MemOperand(sp, (arg_count + 1) * kPointerSize));
       __ sd(v1, MemOperand(sp, arg_count * kPointerSize));
+
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
     // Record source position for debugger.
     SetSourcePosition(expr->position());
@@ -2869,6 +3042,7 @@
     __ Push(context_register(), a2);
     __ CallRuntime(Runtime::kLoadLookupSlot, 2);
     __ Push(v0, v1);  // Function, receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
 
     // If fast case code has been generated, emit code to push the
     // function and receiver and have the slow path jump around this
@@ -2892,9 +3066,12 @@
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
     bool is_named_call = property->key()->IsPropertyName();
-    // super.x() is handled in EmitCallWithLoadIC.
-    if (property->IsSuperAccess() && is_named_call) {
-      EmitSuperCallWithLoadIC(expr);
+    if (property->IsSuperAccess()) {
+      if (is_named_call) {
+        EmitSuperCallWithLoadIC(expr);
+      } else {
+        EmitKeyedSuperCallWithLoadIC(expr);
+      }
     } else {
       {
         PreservePositionScope scope(masm()->positions_recorder());
@@ -2906,6 +3083,12 @@
         EmitKeyedCallWithLoadIC(expr, property->key());
       }
     }
+  } else if (call_type == Call::SUPER_CALL) {
+    SuperReference* super_ref = callee->AsSuperReference();
+    EmitLoadSuperConstructor(super_ref);
+    __ Push(result_register());
+    VisitForStackValue(super_ref->this_var());
+    EmitCall(expr, CallICState::METHOD);
   } else {
     DCHECK(call_type == Call::OTHER_CALL);
     // Call to an arbitrary expression not handled specially above.
@@ -2934,7 +3117,12 @@
   // Push constructor on the stack.  If it's not a function it's used as
   // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
   // ignored.
-  VisitForStackValue(expr->expression());
+  if (expr->expression()->IsSuperReference()) {
+    EmitLoadSuperConstructor(expr->expression()->AsSuperReference());
+    __ Push(result_register());
+  } else {
+    VisitForStackValue(expr->expression());
+  }
 
   // Push the arguments ("left-to-right") on the stack.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2953,12 +3141,12 @@
   // Record call targets in unoptimized code.
   if (FLAG_pretenuring_call_new) {
     EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
-    DCHECK(expr->AllocationSiteFeedbackSlot() ==
-           expr->CallNewFeedbackSlot() + 1);
+    DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
+           expr->CallNewFeedbackSlot().ToInt() + 1);
   }
 
   __ li(a2, FeedbackVector());
-  __ li(a3, Operand(Smi::FromInt(expr->CallNewFeedbackSlot())));
+  __ li(a3, Operand(SmiFromSlot(expr->CallNewFeedbackSlot())));
 
   CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
   __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
@@ -3274,6 +3462,32 @@
 }
 
 
+void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(v0, if_false);
+  Register map = a1;
+  Register type_reg = a2;
+  __ GetObjectType(v0, map, type_reg);
+  __ Subu(type_reg, type_reg, Operand(FIRST_JS_PROXY_TYPE));
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(ls, type_reg, Operand(LAST_JS_PROXY_TYPE - FIRST_JS_PROXY_TYPE),
+        if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
   DCHECK(expr->arguments()->length() == 0);
 
@@ -4192,7 +4406,7 @@
     __ li(LoadDescriptor::NameRegister(), Operand(expr->name()));
     if (FLAG_vector_ics) {
       __ li(VectorLoadICDescriptor::SlotRegister(),
-            Operand(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
+            Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
       CallLoadIC(NOT_CONTEXTUAL);
     } else {
       CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
@@ -4348,17 +4562,8 @@
   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());
 
-  // Expression can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
-  // In case of a property we use the uninitialized expression context
-  // of the key to detect a named property.
-  if (prop != NULL) {
-    assign_type =
-        (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   // Evaluate expression and get value.
   if (assign_type == VARIABLE) {
@@ -4371,18 +4576,52 @@
       __ li(at, Operand(Smi::FromInt(0)));
       __ push(at);
     }
-    if (assign_type == NAMED_PROPERTY) {
-      // Put the object both on the stack and in the register.
-      VisitForStackValue(prop->obj());
-      __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
-      EmitNamedPropertyLoad(prop);
-    } else {
-      VisitForStackValue(prop->obj());
-      VisitForStackValue(prop->key());
-      __ ld(LoadDescriptor::ReceiverRegister(),
-            MemOperand(sp, 1 * kPointerSize));
-      __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
-      EmitKeyedPropertyLoad(prop);
+    switch (assign_type) {
+      case NAMED_PROPERTY: {
+        // Put the object both on the stack and in the register.
+        VisitForStackValue(prop->obj());
+        __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
+        EmitNamedPropertyLoad(prop);
+        break;
+      }
+
+      case NAMED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        const Register scratch = a1;
+        __ ld(scratch, MemOperand(sp, kPointerSize));
+        __ Push(scratch, result_register());
+        EmitNamedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        const Register scratch = a1;
+        const Register scratch1 = a4;
+        __ Move(scratch, result_register());
+        VisitForAccumulatorValue(prop->key());
+        __ Push(scratch, result_register());
+        __ ld(scratch1, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch1, scratch, result_register());
+        EmitKeyedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_PROPERTY: {
+        VisitForStackValue(prop->obj());
+        VisitForStackValue(prop->key());
+        __ ld(LoadDescriptor::ReceiverRegister(),
+              MemOperand(sp, 1 * kPointerSize));
+        __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
+        EmitKeyedPropertyLoad(prop);
+        break;
+      }
+
+      case VARIABLE:
+        UNREACHABLE();
     }
   }
 
@@ -4417,9 +4656,15 @@
           case NAMED_PROPERTY:
             __ sd(v0, MemOperand(sp, kPointerSize));
             break;
+          case NAMED_SUPER_PROPERTY:
+            __ sd(v0, MemOperand(sp, 2 * kPointerSize));
+            break;
           case KEYED_PROPERTY:
             __ sd(v0, MemOperand(sp, 2 * kPointerSize));
             break;
+          case KEYED_SUPER_PROPERTY:
+            __ sd(v0, MemOperand(sp, 3 * kPointerSize));
+            break;
         }
       }
     }
@@ -4450,9 +4695,15 @@
         case NAMED_PROPERTY:
           __ sd(v0, MemOperand(sp, kPointerSize));
           break;
+        case NAMED_SUPER_PROPERTY:
+          __ sd(v0, MemOperand(sp, 2 * kPointerSize));
+          break;
         case KEYED_PROPERTY:
           __ sd(v0, MemOperand(sp, 2 * kPointerSize));
           break;
+        case KEYED_SUPER_PROPERTY:
+          __ sd(v0, MemOperand(sp, 3 * kPointerSize));
+          break;
       }
     }
   }
@@ -4508,6 +4759,28 @@
       }
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      EmitNamedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(v0);
+      }
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      EmitKeyedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(v0);
+      }
+      break;
+    }
     case KEYED_PROPERTY: {
       __ mov(StoreDescriptor::ValueRegister(), result_register());
       __ Pop(StoreDescriptor::ReceiverRegister(),
@@ -4539,7 +4812,7 @@
     __ li(LoadDescriptor::NameRegister(), Operand(proxy->name()));
     if (FLAG_vector_ics) {
       __ li(VectorLoadICDescriptor::SlotRegister(),
-            Operand(Smi::FromInt(proxy->VariableFeedbackSlot())));
+            Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
     }
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
@@ -4771,7 +5044,7 @@
 
 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
   Scope* declaration_scope = scope()->DeclarationScope();
-  if (declaration_scope->is_global_scope() ||
+  if (declaration_scope->is_script_scope() ||
       declaration_scope->is_module_scope()) {
     // Contexts nested in the native context have a canonical empty function
     // as their closure, not the anonymous closure containing the global
diff --git a/src/mips64/interface-descriptors-mips64.cc b/src/mips64/interface-descriptors-mips64.cc
index 8759bdd..44c8dff 100644
--- a/src/mips64/interface-descriptors-mips64.cc
+++ b/src/mips64/interface-descriptors-mips64.cc
@@ -29,6 +29,9 @@
 const Register StoreDescriptor::ValueRegister() { return a0; }
 
 
+const Register StoreTransitionDescriptor::MapRegister() { return a3; }
+
+
 const Register ElementTransitionAndStoreDescriptor::MapRegister() { return a3; }
 
 
@@ -149,6 +152,15 @@
 }
 
 
+void AllocateHeapNumberDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  // register state
+  // cp -- context
+  Register registers[] = {cp};
+  data->Initialize(arraysize(registers), registers, nullptr);
+}
+
+
 void ArrayConstructorConstantArgCountDescriptor::Initialize(
     CallInterfaceDescriptorData* data) {
   // register state
diff --git a/src/mips64/lithium-codegen-mips64.cc b/src/mips64/lithium-codegen-mips64.cc
index 8a0a449..a817a28 100644
--- a/src/mips64/lithium-codegen-mips64.cc
+++ b/src/mips64/lithium-codegen-mips64.cc
@@ -26,9 +26,9 @@
         deopt_mode_(mode) { }
   virtual ~SafepointGenerator() {}
 
-  virtual void BeforeCall(int call_size) const OVERRIDE {}
+  void BeforeCall(int call_size) const OVERRIDE {}
 
-  virtual void AfterCall() const OVERRIDE {
+  void AfterCall() const OVERRIDE {
     codegen_->RecordSafepoint(pointers_, deopt_mode_);
   }
 
@@ -766,8 +766,8 @@
 
 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
                             Deoptimizer::BailoutType bailout_type,
-                            Register src1, const Operand& src2,
-                            const char* detail) {
+                            const char* detail, Register src1,
+                            const Operand& src2) {
   LEnvironment* environment = instr->environment();
   RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
   DCHECK(environment->HasBeenRegistered());
@@ -832,12 +832,12 @@
 
 
 void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
-                            Register src1, const Operand& src2,
-                            const char* detail) {
+                            const char* detail, Register src1,
+                            const Operand& src2) {
   Deoptimizer::BailoutType bailout_type = info()->IsStub()
       ? Deoptimizer::LAZY
       : Deoptimizer::EAGER;
-  DeoptimizeIf(condition, instr, bailout_type, src1, src2, detail);
+  DeoptimizeIf(condition, instr, bailout_type, detail, src1, src2);
 }
 
 
@@ -1067,7 +1067,7 @@
     __ dsubu(dividend, zero_reg, dividend);
     __ And(dividend, dividend, Operand(mask));
     if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
+      DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg));
     }
     __ Branch(USE_DELAY_SLOT, &done);
     __ dsubu(dividend, zero_reg, dividend);
@@ -1086,7 +1086,7 @@
   DCHECK(!dividend.is(result));
 
   if (divisor == 0) {
-    DeoptimizeIf(al, instr);
+    DeoptimizeIf(al, instr, "division by zero");
     return;
   }
 
@@ -1099,7 +1099,7 @@
   if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label remainder_not_zero;
     __ Branch(&remainder_not_zero, ne, result, Operand(zero_reg));
-    DeoptimizeIf(lt, instr, dividend, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "minus zero", dividend, Operand(zero_reg));
     __ bind(&remainder_not_zero);
   }
 }
@@ -1118,7 +1118,7 @@
   // Check for x % 0, we have to deopt in this case because we can't return a
   // NaN.
   if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
-    DeoptimizeIf(eq, instr, right_reg, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "division by zero", right_reg, Operand(zero_reg));
   }
 
   // Check for kMinInt % -1, div will return kMinInt, which is not what we
@@ -1127,7 +1127,7 @@
     Label no_overflow_possible;
     __ Branch(&no_overflow_possible, ne, left_reg, Operand(kMinInt));
     if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
-      DeoptimizeIf(eq, instr, right_reg, Operand(-1));
+      DeoptimizeIf(eq, instr, "minus zero", right_reg, Operand(-1));
     } else {
       __ Branch(&no_overflow_possible, ne, right_reg, Operand(-1));
       __ Branch(USE_DELAY_SLOT, &done);
@@ -1140,7 +1140,7 @@
   __ Branch(&done, ge, left_reg, Operand(zero_reg));
 
   if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    DeoptimizeIf(eq, instr, result_reg, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "minus zero", result_reg, Operand(zero_reg));
   }
   __ bind(&done);
 }
@@ -1156,18 +1156,18 @@
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
-    DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg));
   }
   // Check for (kMinInt / -1).
   if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
-    DeoptimizeIf(eq, instr, dividend, Operand(kMinInt));
+    DeoptimizeIf(eq, instr, "overflow", dividend, Operand(kMinInt));
   }
   // Deoptimize if remainder will not be 0.
   if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
       divisor != 1 && divisor != -1) {
     int32_t mask = divisor < 0 ? -(divisor + 1) : (divisor - 1);
     __ And(at, dividend, Operand(mask));
-    DeoptimizeIf(ne, instr, at, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "lost precision", at, Operand(zero_reg));
   }
 
   if (divisor == -1) {  // Nice shortcut, not needed for correctness.
@@ -1197,14 +1197,14 @@
   DCHECK(!dividend.is(result));
 
   if (divisor == 0) {
-    DeoptimizeIf(al, instr);
+    DeoptimizeIf(al, instr, "division by zero");
     return;
   }
 
   // Check for (0 / -x) that will produce negative zero.
   HDiv* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
-    DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg));
   }
 
   __ TruncatingDiv(result, dividend, Abs(divisor));
@@ -1213,7 +1213,7 @@
   if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
     __ Dmul(scratch0(), result, Operand(divisor));
     __ Dsubu(scratch0(), scratch0(), dividend);
-    DeoptimizeIf(ne, instr, scratch0(), Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "lost precision", scratch0(), Operand(zero_reg));
   }
 }
 
@@ -1231,14 +1231,14 @@
 
   // Check for x / 0.
   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
-    DeoptimizeIf(eq, instr, divisor, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "division by zero", divisor, Operand(zero_reg));
   }
 
   // Check for (0 / -x) that will produce negative zero.
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label left_not_zero;
     __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg));
-    DeoptimizeIf(lt, instr, divisor, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "minus zero", divisor, Operand(zero_reg));
     __ bind(&left_not_zero);
   }
 
@@ -1247,7 +1247,7 @@
       !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     Label left_not_min_int;
     __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt));
-    DeoptimizeIf(eq, instr, divisor, Operand(-1));
+    DeoptimizeIf(eq, instr, "overflow", divisor, Operand(-1));
     __ bind(&left_not_min_int);
   }
 
@@ -1259,7 +1259,7 @@
     } else {
       __ dmod(remainder, dividend, divisor);
     }
-    DeoptimizeIf(ne, instr, remainder, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "lost precision", remainder, Operand(zero_reg));
   }
 }
 
@@ -1304,14 +1304,14 @@
 
   __ Dsubu(result, zero_reg, dividend);
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    DeoptimizeIf(eq, instr, result, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "minus zero", result, Operand(zero_reg));
   }
 
   __ Xor(scratch, scratch, result);
   // Dividing by -1 is basically negation, unless we overflow.
   if (divisor == -1) {
     if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
-      DeoptimizeIf(gt, instr, result, Operand(kMaxInt));
+      DeoptimizeIf(gt, instr, "overflow", result, Operand(kMaxInt));
     }
     return;
   }
@@ -1339,14 +1339,14 @@
   DCHECK(!dividend.is(result));
 
   if (divisor == 0) {
-    DeoptimizeIf(al, instr);
+    DeoptimizeIf(al, instr, "division by zero");
     return;
   }
 
   // Check for (0 / -x) that will produce negative zero.
   HMathFloorOfDiv* hdiv = instr->hydrogen();
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
-    DeoptimizeIf(eq, instr, dividend, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "minus zero", dividend, Operand(zero_reg));
   }
 
   // Easy case: We need no dynamic check for the dividend and the flooring
@@ -1390,14 +1390,14 @@
 
   // Check for x / 0.
   if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
-    DeoptimizeIf(eq, instr, divisor, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "division by zero", divisor, Operand(zero_reg));
   }
 
   // Check for (0 / -x) that will produce negative zero.
   if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
     Label left_not_zero;
     __ Branch(&left_not_zero, ne, dividend, Operand(zero_reg));
-    DeoptimizeIf(lt, instr, divisor, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "minus zero", divisor, Operand(zero_reg));
     __ bind(&left_not_zero);
   }
 
@@ -1406,7 +1406,7 @@
       !hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
     Label left_not_min_int;
     __ Branch(&left_not_min_int, ne, dividend, Operand(kMinInt));
-    DeoptimizeIf(eq, instr, divisor, Operand(-1));
+    DeoptimizeIf(eq, instr, "overflow", divisor, Operand(-1));
     __ bind(&left_not_min_int);
   }
 
@@ -1443,14 +1443,14 @@
     if (bailout_on_minus_zero && (constant < 0)) {
       // The case of a null constant will be handled separately.
       // If constant is negative and left is null, the result should be -0.
-      DeoptimizeIf(eq, instr, left, Operand(zero_reg));
+      DeoptimizeIf(eq, instr, "minus zero", left, Operand(zero_reg));
     }
 
     switch (constant) {
       case -1:
         if (overflow) {
           __ SubuAndCheckForOverflow(result, zero_reg, left, scratch);
-          DeoptimizeIf(gt, instr, scratch, Operand(kMaxInt));
+          DeoptimizeIf(gt, instr, "overflow", scratch, Operand(kMaxInt));
         } else {
           __ Dsubu(result, zero_reg, left);
         }
@@ -1459,7 +1459,7 @@
         if (bailout_on_minus_zero) {
           // If left is strictly negative and the constant is null, the
           // result is -0. Deoptimize if required, otherwise return 0.
-          DeoptimizeIf(lt, instr, left, Operand(zero_reg));
+          DeoptimizeIf(lt, instr, "minus zero", left, Operand(zero_reg));
         }
         __ mov(result, zero_reg);
         break;
@@ -1514,7 +1514,7 @@
       if (instr->hydrogen()->representation().IsSmi()) {
         __ SmiTag(result);
       }
-      DeoptimizeIf(ne, instr, scratch, Operand(at));
+      DeoptimizeIf(ne, instr, "overflow", scratch, Operand(at));
     } else {
       if (instr->hydrogen()->representation().IsSmi()) {
         __ SmiUntag(result, left);
@@ -1529,7 +1529,7 @@
       __ Xor(at, left, right);
       __ Branch(&done, ge, at, Operand(zero_reg));
       // Bail out if the result is minus zero.
-      DeoptimizeIf(eq, instr, result, Operand(zero_reg));
+      DeoptimizeIf(eq, instr, "minus zero", result, Operand(zero_reg));
       __ bind(&done);
     }
   }
@@ -1593,8 +1593,8 @@
         __ srlv(result, left, ToRegister(right_op));
         if (instr->can_deopt()) {
            // TODO(yy): (-1) >>> 0. anything else?
-          DeoptimizeIf(lt, instr, result, Operand(zero_reg));
-          DeoptimizeIf(gt, instr, result, Operand(kMaxInt));
+          DeoptimizeIf(lt, instr, "negative value", result, Operand(zero_reg));
+          DeoptimizeIf(gt, instr, "negative value", result, Operand(kMaxInt));
         }
         break;
       case Token::SHL:
@@ -1629,7 +1629,7 @@
         } else {
           if (instr->can_deopt()) {
             __ And(at, left, Operand(0x80000000));
-            DeoptimizeIf(ne, instr, at, Operand(zero_reg));
+            DeoptimizeIf(ne, instr, "negative value", at, Operand(zero_reg));
           }
           __ Move(result, left);
         }
@@ -1685,10 +1685,10 @@
                                  ToRegister(right),
                                  overflow);  // Reg at also used as scratch.
     }
-    DeoptimizeIf(lt, instr, overflow, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "overflow", overflow, Operand(zero_reg));
     if (!instr->hydrogen()->representation().IsSmi()) {
-      DeoptimizeIf(gt, instr, ToRegister(result), Operand(kMaxInt));
-      DeoptimizeIf(lt, instr, ToRegister(result), Operand(kMinInt));
+      DeoptimizeIf(gt, instr, "overflow", ToRegister(result), Operand(kMaxInt));
+      DeoptimizeIf(lt, instr, "overflow", ToRegister(result), Operand(kMinInt));
     }
   }
 }
@@ -1743,9 +1743,9 @@
   DCHECK(!scratch.is(object));
 
   __ SmiTst(object, at);
-  DeoptimizeIf(eq, instr, at, Operand(zero_reg));
+  DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg));
   __ GetObjectType(object, scratch, scratch);
-  DeoptimizeIf(ne, instr, scratch, Operand(JS_DATE_TYPE));
+  DeoptimizeIf(ne, instr, "not a date object", scratch, Operand(JS_DATE_TYPE));
 
   if (index->value() == 0) {
     __ ld(result, FieldMemOperand(object, JSDate::kValueOffset));
@@ -1880,11 +1880,11 @@
                                  ToRegister(right),
                                  overflow);  // Reg at also used as scratch.
     }
-    DeoptimizeIf(lt, instr, overflow, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "overflow", overflow, Operand(zero_reg));
     // if not smi, it must int32.
     if (!instr->hydrogen()->representation().IsSmi()) {
-      DeoptimizeIf(gt, instr, ToRegister(result), Operand(kMaxInt));
-      DeoptimizeIf(lt, instr, ToRegister(result), Operand(kMinInt));
+      DeoptimizeIf(gt, instr, "overflow", ToRegister(result), Operand(kMaxInt));
+      DeoptimizeIf(lt, instr, "overflow", ToRegister(result), Operand(kMinInt));
     }
   }
 }
@@ -2146,7 +2146,7 @@
       } else if (expected.NeedsMap()) {
         // If we need a map later and have a Smi -> deopt.
         __ SmiTst(reg, at);
-        DeoptimizeIf(eq, instr, at, Operand(zero_reg));
+        DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg));
       }
 
       const Register map = scratch0();
@@ -2202,7 +2202,8 @@
       if (!expected.IsGeneric()) {
         // We've seen something for the first time -> deopt.
         // This can only happen if we are not generic already.
-        DeoptimizeIf(al, instr, zero_reg, Operand(zero_reg));
+        DeoptimizeIf(al, instr, "unexpected object", zero_reg,
+                     Operand(zero_reg));
       }
     }
   }
@@ -2664,10 +2665,10 @@
     DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
                                   LInstanceOfKnownGlobal* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
     Label* map_check() { return &map_check_; }
 
    private:
@@ -2827,6 +2828,7 @@
       __ Daddu(sp, sp, Operand(sp_delta));
     }
   } else {
+    DCHECK(info()->IsStub());  // Functions would need to drop one more value.
     Register reg = ToRegister(instr->parameter_count());
     // The argument count parameter is a smi
     __ SmiUntag(reg);
@@ -2848,7 +2850,7 @@
   __ ld(result, FieldMemOperand(at, Cell::kValueOffset));
   if (instr->hydrogen()->RequiresHoleCheck()) {
     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
-    DeoptimizeIf(eq, instr, result, Operand(at));
+    DeoptimizeIf(eq, instr, "hole", result, Operand(at));
   }
 }
 
@@ -2856,13 +2858,18 @@
 template <class T>
 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
   DCHECK(FLAG_vector_ics);
-  Register vector = ToRegister(instr->temp_vector());
-  DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister()));
-  __ li(vector, instr->hydrogen()->feedback_vector());
+  Register vector_register = ToRegister(instr->temp_vector());
+  Register slot_register = VectorLoadICDescriptor::SlotRegister();
+  DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
+  DCHECK(slot_register.is(a0));
+
+  AllowDeferredHandleDereference vector_structure_check;
+  Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
+  __ li(vector_register, vector);
   // No need to allocate this register.
-  DCHECK(VectorLoadICDescriptor::SlotRegister().is(a0));
-  __ li(VectorLoadICDescriptor::SlotRegister(),
-        Operand(Smi::FromInt(instr->hydrogen()->slot())));
+  FeedbackVectorICSlot slot = instr->hydrogen()->slot();
+  int index = vector->GetIndex(slot);
+  __ li(slot_register, Operand(Smi::FromInt(index)));
 }
 
 
@@ -2877,7 +2884,7 @@
     EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
+  Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -2898,7 +2905,7 @@
     Register payload = ToRegister(instr->temp());
     __ ld(payload, FieldMemOperand(cell, Cell::kValueOffset));
     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
-    DeoptimizeIf(eq, instr, payload, Operand(at));
+    DeoptimizeIf(eq, instr, "hole", payload, Operand(at));
   }
 
   // Store the value.
@@ -2916,7 +2923,7 @@
     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
 
     if (instr->hydrogen()->DeoptimizesOnHole()) {
-      DeoptimizeIf(eq, instr, result, Operand(at));
+      DeoptimizeIf(eq, instr, "hole", result, Operand(at));
     } else {
       Label is_not_hole;
       __ Branch(&is_not_hole, ne, result, Operand(at));
@@ -2940,7 +2947,7 @@
     __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
 
     if (instr->hydrogen()->DeoptimizesOnHole()) {
-      DeoptimizeIf(eq, instr, scratch, Operand(at));
+      DeoptimizeIf(eq, instr, "hole", scratch, Operand(at));
     } else {
       __ Branch(&skip_assignment, ne, scratch, Operand(at));
     }
@@ -3018,7 +3025,8 @@
   if (FLAG_vector_ics) {
     EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
+  Handle<Code> ic =
+      CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3034,7 +3042,7 @@
 
   // Check that the function has a prototype or an initial map.
   __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
-  DeoptimizeIf(eq, instr, result, Operand(at));
+  DeoptimizeIf(eq, instr, "hole", result, Operand(at));
 
   // If the function does not have an initial map, we're done.
   Label done;
@@ -3180,7 +3188,8 @@
       case UINT32_ELEMENTS:
         __ lw(result, mem_operand);
         if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
-          DeoptimizeIf(Ugreater_equal, instr, result, Operand(0x80000000));
+          DeoptimizeIf(Ugreater_equal, instr, "negative value", result,
+                       Operand(0x80000000));
         }
         break;
       case FLOAT32_ELEMENTS:
@@ -3240,7 +3249,7 @@
 
   if (instr->hydrogen()->RequiresHoleCheck()) {
     __ lw(scratch, MemOperand(scratch, sizeof(kHoleNanLower32)));
-    DeoptimizeIf(eq, instr, scratch, Operand(kHoleNanUpper32));
+    DeoptimizeIf(eq, instr, "hole", scratch, Operand(kHoleNanUpper32));
   }
 }
 
@@ -3294,10 +3303,10 @@
   if (hinstr->RequiresHoleCheck()) {
     if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
       __ SmiTst(result, scratch);
-      DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
+      DeoptimizeIf(ne, instr, "not a Smi", scratch, Operand(zero_reg));
     } else {
       __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
-      DeoptimizeIf(eq, instr, result, Operand(scratch));
+      DeoptimizeIf(eq, instr, "hole", result, Operand(scratch));
     }
   }
 }
@@ -3366,7 +3375,7 @@
     EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
-  Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
+  Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3453,10 +3462,11 @@
 
   // Deoptimize if the receiver is not a JS object.
   __ SmiTst(receiver, scratch);
-  DeoptimizeIf(eq, instr, scratch, Operand(zero_reg));
+  DeoptimizeIf(eq, instr, "Smi", scratch, Operand(zero_reg));
 
   __ GetObjectType(receiver, scratch, scratch);
-  DeoptimizeIf(lt, instr, scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
+  DeoptimizeIf(lt, instr, "not a JavaScript object", scratch,
+               Operand(FIRST_SPEC_OBJECT_TYPE));
   __ Branch(&result_in_receiver);
 
   __ bind(&global_object);
@@ -3491,7 +3501,8 @@
   // Copy the arguments to this function possibly from the
   // adaptor frame below it.
   const uint32_t kArgumentsLimit = 1 * KB;
-  DeoptimizeIf(hi, instr, length, Operand(kArgumentsLimit));
+  DeoptimizeIf(hi, instr, "too many arguments", length,
+               Operand(kArgumentsLimit));
 
   // Push the receiver and use the register to keep the original
   // number of arguments.
@@ -3621,7 +3632,7 @@
   // Deoptimize if not a heap number.
   __ ld(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
   __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
-  DeoptimizeIf(ne, instr, scratch, Operand(at));
+  DeoptimizeIf(ne, instr, "not a heap number", scratch, Operand(at));
 
   Label done;
   Register exponent = scratch0();
@@ -3688,7 +3699,7 @@
   __ mov(result, input);
   __ dsubu(result, zero_reg, input);
   // Overflow if result is still negative, i.e. 0x80000000.
-  DeoptimizeIf(lt, instr, result, Operand(zero_reg));
+  DeoptimizeIf(lt, instr, "overflow", result, Operand(zero_reg));
   __ bind(&done);
 }
 
@@ -3699,10 +3710,11 @@
    public:
     DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LMathAbs* instr_;
   };
@@ -3742,7 +3754,8 @@
                      except_flag);
 
   // Deopt if the operation did not succeed.
-  DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
+  DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag,
+               Operand(zero_reg));
 
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     // Test for -0.
@@ -3750,7 +3763,7 @@
     __ Branch(&done, ne, result, Operand(zero_reg));
     __ mfhc1(scratch1, input);  // Get exponent/sign bits.
     __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
-    DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg));
     __ bind(&done);
   }
 }
@@ -3783,7 +3796,8 @@
 
   // The following conversion will not work with numbers
   // outside of ]-2^32, 2^32[.
-  DeoptimizeIf(ge, instr, scratch, Operand(HeapNumber::kExponentBias + 32));
+  DeoptimizeIf(ge, instr, "overflow", scratch,
+               Operand(HeapNumber::kExponentBias + 32));
 
   // Save the original sign for later comparison.
   __ And(scratch, result, Operand(HeapNumber::kSignMask));
@@ -3800,7 +3814,7 @@
   __ Xor(result, result, Operand(scratch));
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     // ARM uses 'mi' here, which is 'lt'
-    DeoptimizeIf(lt, instr, result, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "minus zero", result, Operand(zero_reg));
   } else {
     Label skip2;
     // ARM uses 'mi' here, which is 'lt'
@@ -3819,7 +3833,8 @@
                      double_scratch1,
                      except_flag);
 
-  DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
+  DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag,
+               Operand(zero_reg));
 
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     // Test for -0.
@@ -3827,7 +3842,7 @@
     __ bind(&check_sign_on_zero);
     __ mfhc1(scratch, input);  // Get exponent/sign bits.
     __ And(scratch, scratch, Operand(HeapNumber::kSignMask));
-    DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "minus zero", scratch, Operand(zero_reg));
   }
   __ bind(&done);
 }
@@ -3859,7 +3874,7 @@
   // Math.pow(-Infinity, 0.5) == Infinity
   // Math.sqrt(-Infinity) == NaN
   Label done;
-  __ Move(temp, -V8_INFINITY);
+  __ Move(temp, static_cast<double>(-V8_INFINITY));
   __ BranchF(USE_DELAY_SLOT, &done, NULL, eq, temp, input);
   // Set up Infinity in the delay slot.
   // result is overwritten if the branch is not taken.
@@ -3893,7 +3908,7 @@
     DCHECK(!a7.is(tagged_exponent));
     __ lw(a7, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset));
     __ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
-    DeoptimizeIf(ne, instr, a7, Operand(at));
+    DeoptimizeIf(ne, instr, "not a heap number", a7, Operand(at));
     __ bind(&no_deopt);
     MathPowStub stub(isolate(), MathPowStub::TAGGED);
     __ CallStub(&stub);
@@ -3968,44 +3983,73 @@
   DCHECK(receiver.is(a1));
   DCHECK(name.is(a2));
 
-  Register scratch = a3;
-  Register extra = a4;
-  Register extra2 = a5;
-  Register extra3 = a6;
+  Register scratch = a4;
+  Register extra = a5;
+  Register extra2 = a6;
+  Register extra3 = t1;
+#ifdef DEBUG
+  Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg;
+  Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg;
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(slot, vector, scratch, extra, extra2, extra3));
+#endif
 
   // Important for the tail-call.
   bool must_teardown_frame = NeedsEagerFrame();
 
-  // The probe will tail call to a handler if found.
-  isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
-                                         must_teardown_frame, receiver, name,
-                                         scratch, extra, extra2, extra3);
+  if (!instr->hydrogen()->is_just_miss()) {
+    DCHECK(!instr->hydrogen()->is_keyed_load());
+
+    // The probe will tail call to a handler if found.
+    isolate()->stub_cache()->GenerateProbe(
+        masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
+        receiver, name, scratch, extra, extra2, extra3);
+  }
 
   // Tail call to miss if we ended up here.
   if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL);
-  LoadIC::GenerateMiss(masm());
+  if (instr->hydrogen()->is_keyed_load()) {
+    KeyedLoadIC::GenerateMiss(masm());
+  } else {
+    LoadIC::GenerateMiss(masm());
+  }
 }
 
 
 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
   DCHECK(ToRegister(instr->result()).is(v0));
 
-  LPointerMap* pointers = instr->pointer_map();
-  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+  if (instr->hydrogen()->IsTailCall()) {
+    if (NeedsEagerFrame()) __ LeaveFrame(StackFrame::INTERNAL);
 
-  if (instr->target()->IsConstantOperand()) {
-    LConstantOperand* target = LConstantOperand::cast(instr->target());
-    Handle<Code> code = Handle<Code>::cast(ToHandle(target));
-    generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
-    __ Call(code, RelocInfo::CODE_TARGET);
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      __ Jump(code, RelocInfo::CODE_TARGET);
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      __ Daddu(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
+      __ Jump(target);
+    }
   } else {
-    DCHECK(instr->target()->IsRegister());
-    Register target = ToRegister(instr->target());
-    generator.BeforeCall(__ CallSize(target));
-    __ Daddu(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
-    __ Call(target);
+    LPointerMap* pointers = instr->pointer_map();
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
+      __ Call(code, RelocInfo::CODE_TARGET);
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      generator.BeforeCall(__ CallSize(target));
+      __ Daddu(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
+      __ Call(target);
+    }
+    generator.AfterCall();
   }
-  generator.AfterCall();
 }
 
 
@@ -4235,7 +4279,7 @@
     __ stop("eliminated bounds check failed");
     __ bind(&done);
   } else {
-    DeoptimizeIf(cc, instr, reg, operand);
+    DeoptimizeIf(cc, instr, "out of bounds", reg, operand);
   }
 }
 
@@ -4526,7 +4570,7 @@
   Label no_memento_found;
   __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found,
                                      ne, &no_memento_found);
-  DeoptimizeIf(al, instr);
+  DeoptimizeIf(al, instr, "memento found");
   __ bind(&no_memento_found);
 }
 
@@ -4547,10 +4591,9 @@
    public:
     DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredStringCharCodeAt(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredStringCharCodeAt(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStringCharCodeAt* instr_;
   };
@@ -4602,10 +4645,11 @@
    public:
     DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredStringCharFromCode(instr_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStringCharFromCode* instr_;
   };
@@ -4680,14 +4724,15 @@
    public:
     DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredNumberTagIU(instr_,
                                        instr_->value(),
                                        instr_->temp1(),
                                        instr_->temp2(),
                                        UNSIGNED_INT32);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagU* instr_;
   };
@@ -4770,10 +4815,9 @@
    public:
     DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredNumberTagD(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredNumberTagD(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagD* instr_;
   };
@@ -4829,12 +4873,12 @@
   if (hchange->CheckFlag(HValue::kCanOverflow) &&
       hchange->value()->CheckFlag(HValue::kUint32)) {
     __ And(at, input, Operand(0x80000000));
-    DeoptimizeIf(ne, instr, at, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "overflow", at, Operand(zero_reg));
   }
   if (hchange->CheckFlag(HValue::kCanOverflow) &&
       !hchange->value()->CheckFlag(HValue::kUint32)) {
     __ SmiTagCheckOverflow(output, input, at);
-    DeoptimizeIf(lt, instr, at, Operand(zero_reg));
+    DeoptimizeIf(lt, instr, "overflow", at, Operand(zero_reg));
   } else {
     __ SmiTag(output, input);
   }
@@ -4850,7 +4894,7 @@
     // If the input is a HeapObject, value of scratch won't be zero.
     __ And(scratch, input, Operand(kHeapObjectTag));
     __ SmiUntag(result, input);
-    DeoptimizeIf(ne, instr, scratch, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "not a Smi", scratch, Operand(zero_reg));
   } else {
     __ SmiUntag(result, input);
   }
@@ -4875,7 +4919,7 @@
     if (can_convert_undefined_to_nan) {
       __ Branch(&convert, ne, scratch, Operand(at));
     } else {
-      DeoptimizeIf(ne, instr, scratch, Operand(at));
+      DeoptimizeIf(ne, instr, "not a heap number", scratch, Operand(at));
     }
     // Load heap number.
     __ ldc1(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset));
@@ -4883,14 +4927,16 @@
       __ mfc1(at, result_reg);
       __ Branch(&done, ne, at, Operand(zero_reg));
       __ mfhc1(scratch, result_reg);  // Get exponent/sign bits.
-      DeoptimizeIf(eq, instr, scratch, Operand(HeapNumber::kSignMask));
+      DeoptimizeIf(eq, instr, "minus zero", scratch,
+                   Operand(HeapNumber::kSignMask));
     }
     __ Branch(&done);
     if (can_convert_undefined_to_nan) {
       __ bind(&convert);
       // Convert undefined (and hole) to NaN.
       __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
-      DeoptimizeIf(ne, instr, input_reg, Operand(at));
+      DeoptimizeIf(ne, instr, "not a heap number/undefined", input_reg,
+                   Operand(at));
       __ LoadRoot(scratch, Heap::kNanValueRootIndex);
       __ ldc1(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset));
       __ Branch(&done);
@@ -4954,11 +5000,12 @@
 
     __ bind(&check_false);
     __ LoadRoot(at, Heap::kFalseValueRootIndex);
-    DeoptimizeIf(ne, instr, scratch2, Operand(at), "cannot truncate");
+    DeoptimizeIf(ne, instr, "not a heap number/undefined/true/false", scratch2,
+                 Operand(at));
     __ Branch(USE_DELAY_SLOT, &done);
     __ mov(input_reg, zero_reg);  // In delay slot.
   } else {
-    DeoptimizeIf(ne, instr, scratch1, Operand(at), "not a heap number");
+    DeoptimizeIf(ne, instr, "not a heap number", scratch1, Operand(at));
 
     // Load the double value.
     __ ldc1(double_scratch,
@@ -4973,15 +5020,15 @@
                        except_flag,
                        kCheckForInexactConversion);
 
-    DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg),
-                 "lost precision or NaN");
+    DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag,
+                 Operand(zero_reg));
 
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
       __ Branch(&done, ne, input_reg, Operand(zero_reg));
 
       __ mfhc1(scratch1, double_scratch);  // Get exponent/sign bits.
       __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
-      DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg), "minus zero");
+      DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg));
     }
   }
   __ bind(&done);
@@ -4993,10 +5040,9 @@
    public:
     DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredTaggedToI(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredTaggedToI(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LTaggedToI* instr_;
   };
@@ -5058,14 +5104,15 @@
                        kCheckForInexactConversion);
 
     // Deopt if the operation did not succeed (except_flag != 0).
-    DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag,
+                 Operand(zero_reg));
 
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
       Label done;
       __ Branch(&done, ne, result_reg, Operand(zero_reg));
       __ mfhc1(scratch1, double_input);  // Get exponent/sign bits.
       __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
-      DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
+      DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg));
       __ bind(&done);
     }
   }
@@ -5091,14 +5138,15 @@
                        kCheckForInexactConversion);
 
     // Deopt if the operation did not succeed (except_flag != 0).
-    DeoptimizeIf(ne, instr, except_flag, Operand(zero_reg));
+    DeoptimizeIf(ne, instr, "lost precision or NaN", except_flag,
+                 Operand(zero_reg));
 
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
       Label done;
       __ Branch(&done, ne, result_reg, Operand(zero_reg));
       __ mfhc1(scratch1, double_input);  // Get exponent/sign bits.
       __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask));
-      DeoptimizeIf(ne, instr, scratch1, Operand(zero_reg));
+      DeoptimizeIf(ne, instr, "minus zero", scratch1, Operand(zero_reg));
       __ bind(&done);
     }
   }
@@ -5109,7 +5157,7 @@
 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
   LOperand* input = instr->value();
   __ SmiTst(ToRegister(input), at);
-  DeoptimizeIf(ne, instr, at, Operand(zero_reg));
+  DeoptimizeIf(ne, instr, "not a Smi", at, Operand(zero_reg));
 }
 
 
@@ -5117,7 +5165,7 @@
   if (!instr->hydrogen()->value()->type().IsHeapObject()) {
     LOperand* input = instr->value();
     __ SmiTst(ToRegister(input), at);
-    DeoptimizeIf(eq, instr, at, Operand(zero_reg));
+    DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg));
   }
 }
 
@@ -5135,12 +5183,12 @@
 
     // If there is only one type in the interval check for equality.
     if (first == last) {
-      DeoptimizeIf(ne, instr, scratch, Operand(first));
+      DeoptimizeIf(ne, instr, "wrong instance type", scratch, Operand(first));
     } else {
-      DeoptimizeIf(lo, instr, scratch, Operand(first));
+      DeoptimizeIf(lo, instr, "wrong instance type", scratch, Operand(first));
       // Omit check for the last type.
       if (last != LAST_TYPE) {
-        DeoptimizeIf(hi, instr, scratch, Operand(last));
+        DeoptimizeIf(hi, instr, "wrong instance type", scratch, Operand(last));
       }
     }
   } else {
@@ -5151,10 +5199,11 @@
     if (base::bits::IsPowerOfTwo32(mask)) {
       DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag));
       __ And(at, scratch, mask);
-      DeoptimizeIf(tag == 0 ? ne : eq, instr, at, Operand(zero_reg));
+      DeoptimizeIf(tag == 0 ? ne : eq, instr, "wrong instance type", at,
+                   Operand(zero_reg));
     } else {
       __ And(scratch, scratch, Operand(mask));
-      DeoptimizeIf(ne, instr, scratch, Operand(tag));
+      DeoptimizeIf(ne, instr, "wrong instance type", scratch, Operand(tag));
     }
   }
 }
@@ -5169,9 +5218,9 @@
     Handle<Cell> cell = isolate()->factory()->NewCell(object);
     __ li(at, Operand(Handle<Object>(cell)));
     __ ld(at, FieldMemOperand(at, Cell::kValueOffset));
-    DeoptimizeIf(ne, instr, reg, Operand(at));
+    DeoptimizeIf(ne, instr, "value mismatch", reg, Operand(at));
   } else {
-    DeoptimizeIf(ne, instr, reg, Operand(object));
+    DeoptimizeIf(ne, instr, "value mismatch", reg, Operand(object));
   }
 }
 
@@ -5187,7 +5236,7 @@
     __ StoreToSafepointRegisterSlot(v0, scratch0());
   }
   __ SmiTst(scratch0(), at);
-  DeoptimizeIf(eq, instr, at, Operand(zero_reg));
+  DeoptimizeIf(eq, instr, "instance migration failed", at, Operand(zero_reg));
 }
 
 
@@ -5198,11 +5247,12 @@
         : LDeferredCode(codegen), instr_(instr), object_(object) {
       SetExit(check_maps());
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredInstanceMigration(instr_, object_);
     }
     Label* check_maps() { return &check_maps_; }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LCheckMaps* instr_;
     Label check_maps_;
@@ -5240,7 +5290,7 @@
   if (instr->hydrogen()->HasMigrationTarget()) {
     __ Branch(deferred->entry(), ne, map_reg, Operand(map));
   } else {
-    DeoptimizeIf(ne, instr, map_reg, Operand(map));
+    DeoptimizeIf(ne, instr, "wrong map", map_reg, Operand(map));
   }
 
   __ bind(&success);
@@ -5278,7 +5328,8 @@
 
   // Check for undefined. Undefined is converted to zero for clamping
   // conversions.
-  DeoptimizeIf(ne, instr, input_reg, Operand(factory()->undefined_value()));
+  DeoptimizeIf(ne, instr, "not a heap number/undefined", input_reg,
+               Operand(factory()->undefined_value()));
   __ mov(result_reg, zero_reg);
   __ jmp(&done);
 
@@ -5320,10 +5371,9 @@
    public:
     DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredAllocate(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredAllocate(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LAllocate* instr_;
   };
@@ -5703,8 +5753,8 @@
     type = Deoptimizer::LAZY;
   }
 
-  DeoptimizeIf(al, instr, type, zero_reg, Operand(zero_reg),
-               instr->hydrogen()->reason());
+  DeoptimizeIf(al, instr, type, instr->hydrogen()->reason(), zero_reg,
+               Operand(zero_reg));
 }
 
 
@@ -5735,10 +5785,9 @@
    public:
     DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredStackCheck(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredStackCheck(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStackCheck* instr_;
   };
@@ -5795,18 +5844,19 @@
   Register result = ToRegister(instr->result());
   Register object = ToRegister(instr->object());
   __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
-  DeoptimizeIf(eq, instr, object, Operand(at));
+  DeoptimizeIf(eq, instr, "undefined", object, Operand(at));
 
   Register null_value = a5;
   __ LoadRoot(null_value, Heap::kNullValueRootIndex);
-  DeoptimizeIf(eq, instr, object, Operand(null_value));
+  DeoptimizeIf(eq, instr, "null", object, Operand(null_value));
 
   __ And(at, object, kSmiTagMask);
-  DeoptimizeIf(eq, instr, at, Operand(zero_reg));
+  DeoptimizeIf(eq, instr, "Smi", at, Operand(zero_reg));
 
   STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
   __ GetObjectType(object, a1, a1);
-  DeoptimizeIf(le, instr, a1, Operand(LAST_JS_PROXY_TYPE));
+  DeoptimizeIf(le, instr, "not a JavaScript object", a1,
+               Operand(LAST_JS_PROXY_TYPE));
 
   Label use_cache, call_runtime;
   DCHECK(object.is(a0));
@@ -5823,7 +5873,7 @@
   __ ld(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
   DCHECK(result.is(v0));
   __ LoadRoot(at, Heap::kMetaMapRootIndex);
-  DeoptimizeIf(ne, instr, a1, Operand(at));
+  DeoptimizeIf(ne, instr, "wrong map", a1, Operand(at));
   __ bind(&use_cache);
 }
 
@@ -5843,7 +5893,7 @@
         FieldMemOperand(result, DescriptorArray::kEnumCacheOffset));
   __ ld(result,
         FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
-  DeoptimizeIf(eq, instr, result, Operand(zero_reg));
+  DeoptimizeIf(eq, instr, "no cache", result, Operand(zero_reg));
 
   __ bind(&done);
 }
@@ -5853,7 +5903,7 @@
   Register object = ToRegister(instr->value());
   Register map = ToRegister(instr->map());
   __ ld(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset));
-  DeoptimizeIf(ne, instr, map, Operand(scratch0()));
+  DeoptimizeIf(ne, instr, "wrong map", map, Operand(scratch0()));
 }
 
 
@@ -5885,10 +5935,11 @@
           object_(object),
           index_(index) {
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredLoadMutableDouble(instr_, result_, object_, index_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LLoadFieldByIndex* instr_;
     Register result_;
diff --git a/src/mips64/lithium-codegen-mips64.h b/src/mips64/lithium-codegen-mips64.h
index a4b7adb..b320dcb 100644
--- a/src/mips64/lithium-codegen-mips64.h
+++ b/src/mips64/lithium-codegen-mips64.h
@@ -230,14 +230,12 @@
   void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
                                             Safepoint::DeoptMode mode);
   void DeoptimizeIf(Condition condition, LInstruction* instr,
-                    Deoptimizer::BailoutType bailout_type,
+                    Deoptimizer::BailoutType bailout_type, const char* detail,
                     Register src1 = zero_reg,
-                    const Operand& src2 = Operand(zero_reg),
-                    const char* detail = NULL);
+                    const Operand& src2 = Operand(zero_reg));
   void DeoptimizeIf(Condition condition, LInstruction* instr,
-                    Register src1 = zero_reg,
-                    const Operand& src2 = Operand(zero_reg),
-                    const char* detail = NULL);
+                    const char* detail, Register src1 = zero_reg,
+                    const Operand& src2 = Operand(zero_reg));
 
   void AddToTranslation(LEnvironment* environment,
                         Translation* translation,
diff --git a/src/mips64/lithium-mips64.cc b/src/mips64/lithium-mips64.cc
index 4892611..a12764b 100644
--- a/src/mips64/lithium-mips64.cc
+++ b/src/mips64/lithium-mips64.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <sstream>
+
 #include "src/v8.h"
 
 #if V8_TARGET_ARCH_MIPS64
@@ -323,9 +325,9 @@
 
 void LStoreNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
-  OStringStream os;
+  std::ostringstream os;
   os << hydrogen()->access() << " <- ";
-  stream->Add(os.c_str());
+  stream->Add(os.str().c_str());
   value()->PrintTo(stream);
 }
 
@@ -704,11 +706,7 @@
     // Shift operations can only deoptimize if we do a logical shift
     // by 0 and the result cannot be truncated to int32.
     if (op == Token::SHR && constant_value == 0) {
-      if (FLAG_opt_safe_uint32_operations) {
-        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-      } else {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
-      }
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
     }
 
     LInstruction* result =
@@ -1105,9 +1103,17 @@
       UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
   LOperand* name_register =
       UseFixed(instr->name(), LoadDescriptor::NameRegister());
+  LOperand* slot = NULL;
+  LOperand* vector = NULL;
+  if (FLAG_vector_ics) {
+    slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
+    vector =
+        UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
+  }
+
   // Not marked as call. It can't deoptimize, and it never returns.
   return new (zone()) LTailCallThroughMegamorphicCache(
-      context, receiver_register, name_register);
+      context, receiver_register, name_register, slot, vector);
 }
 
 
@@ -1404,8 +1410,14 @@
   DCHECK(instr->right()->representation().Equals(instr->representation()));
   LOperand* dividend = UseRegister(instr->left());
   LOperand* divisor = UseRegister(instr->right());
-  LFlooringDivI* div = new(zone()) LFlooringDivI(dividend, divisor);
-  return AssignEnvironment(DefineAsRegister(div));
+  LInstruction* result =
+      DefineAsRegister(new (zone()) LFlooringDivI(dividend, divisor));
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+      (instr->CheckFlag(HValue::kCanOverflow))) {
+    result = AssignEnvironment(result);
+  }
+  return result;
 }
 
 
@@ -2060,7 +2072,7 @@
   LOperand* global_object =
       UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
   LLoadGlobalGeneric* result =
@@ -2119,7 +2131,7 @@
   LOperand* object =
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
@@ -2187,7 +2199,7 @@
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
diff --git a/src/mips64/lithium-mips64.h b/src/mips64/lithium-mips64.h
index c6257a4..b89a9c4 100644
--- a/src/mips64/lithium-mips64.h
+++ b/src/mips64/lithium-mips64.h
@@ -162,17 +162,13 @@
   V(UnknownOSRValue)                         \
   V(WrapReceiver)
 
-#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)                        \
-  virtual Opcode opcode() const FINAL OVERRIDE {                      \
-    return LInstruction::k##type;                                           \
-  }                                                                         \
-  virtual void CompileToNative(LCodeGen* generator) FINAL OVERRIDE;   \
-  virtual const char* Mnemonic() const FINAL OVERRIDE {               \
-    return mnemonic;                                                        \
-  }                                                                         \
-  static L##type* cast(LInstruction* instr) {                               \
-    DCHECK(instr->Is##type());                                              \
-    return reinterpret_cast<L##type*>(instr);                               \
+#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)            \
+  Opcode opcode() const FINAL { return LInstruction::k##type; } \
+  void CompileToNative(LCodeGen* generator) FINAL;              \
+  const char* Mnemonic() const FINAL { return mnemonic; }       \
+  static L##type* cast(LInstruction* instr) {                   \
+    DCHECK(instr->Is##type());                                  \
+    return reinterpret_cast<L##type*>(instr);                   \
   }
 
 
@@ -287,11 +283,9 @@
  public:
   // Allow 0 or 1 output operands.
   STATIC_ASSERT(R == 0 || R == 1);
-  virtual bool HasResult() const FINAL OVERRIDE {
-    return R != 0 && result() != NULL;
-  }
+  bool HasResult() const FINAL { return R != 0 && result() != NULL; }
   void set_result(LOperand* operand) { results_[0] = operand; }
-  LOperand* result() const { return results_[0]; }
+  LOperand* result() const OVERRIDE { return results_[0]; }
 
  protected:
   EmbeddedContainer<LOperand*, R> results_;
@@ -309,11 +303,11 @@
 
  private:
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return I; }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return I; }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return T; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return temps_[i]; }
+  int TempCount() FINAL { return T; }
+  LOperand* TempAt(int i) FINAL { return temps_[i]; }
 };
 
 
@@ -328,8 +322,8 @@
   }
 
   // Can't use the DECLARE-macro here because of sub-classes.
-  virtual bool IsGap() const FINAL OVERRIDE { return true; }
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsGap() const FINAL { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   static LGap* cast(LInstruction* instr) {
     DCHECK(instr->IsGap());
     return reinterpret_cast<LGap*>(instr);
@@ -369,7 +363,7 @@
  public:
   explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
     return !IsRedundant();
   }
 
@@ -381,10 +375,10 @@
  public:
   explicit LGoto(HBasicBlock* block) : block_(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
-  virtual bool IsControl() const OVERRIDE { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsControl() const OVERRIDE { return true; }
 
   int block_id() const { return block_->block_id(); }
 
@@ -427,7 +421,7 @@
 
 class LDeoptimize FINAL : public LTemplateInstruction<0, 0, 0> {
  public:
-  virtual bool IsControl() const OVERRIDE { return true; }
+  bool IsControl() const OVERRIDE { return true; }
   DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
   DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
 };
@@ -438,12 +432,10 @@
   explicit LLabel(HBasicBlock* block)
       : LGap(block), replacement_(NULL) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Label, "label")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int block_id() const { return block()->block_id(); }
   bool is_loop_header() const { return block()->IsLoopHeader(); }
@@ -461,9 +453,7 @@
 
 class LParameter FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
 };
 
@@ -482,19 +472,23 @@
 
 
 class LTailCallThroughMegamorphicCache FINAL
-    : public LTemplateInstruction<0, 3, 0> {
+    : public LTemplateInstruction<0, 5, 0> {
  public:
-  explicit LTailCallThroughMegamorphicCache(LOperand* context,
-                                            LOperand* receiver,
-                                            LOperand* name) {
+  LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
+                                   LOperand* name, LOperand* slot,
+                                   LOperand* vector) {
     inputs_[0] = context;
     inputs_[1] = receiver;
     inputs_[2] = name;
+    inputs_[3] = slot;
+    inputs_[4] = vector;
   }
 
   LOperand* context() { return inputs_[0]; }
   LOperand* receiver() { return inputs_[1]; }
   LOperand* name() { return inputs_[2]; }
+  LOperand* slot() { return inputs_[3]; }
+  LOperand* vector() { return inputs_[4]; }
 
   DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
                                "tail-call-through-megamorphic-cache")
@@ -504,9 +498,7 @@
 
 class LUnknownOSRValue FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
 };
 
@@ -516,7 +508,7 @@
  public:
   LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
 
-  virtual bool IsControl() const FINAL OVERRIDE { return true; }
+  bool IsControl() const FINAL { return true; }
 
   int SuccessorCount() { return hydrogen()->SuccessorCount(); }
   HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
@@ -605,7 +597,7 @@
   LOperand* length() { return inputs_[1]; }
   LOperand* index() { return inputs_[2]; }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -845,7 +837,7 @@
     return hydrogen()->representation().IsDouble();
   }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1033,7 +1025,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1050,7 +1042,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1065,7 +1057,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1083,7 +1075,7 @@
                                "is-undetectable-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1105,7 +1097,7 @@
 
   Token::Value op() const { return hydrogen()->token(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1121,7 +1113,7 @@
                                "has-instance-type-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1151,7 +1143,7 @@
                                "has-cached-array-index-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1169,7 +1161,7 @@
                                "class-of-test-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1366,7 +1358,7 @@
   DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
   DECLARE_HYDROGEN_ACCESSOR(Branch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1511,11 +1503,9 @@
   LOperand* left() { return inputs_[0]; }
   LOperand* right() { return inputs_[1]; }
 
-  virtual Opcode opcode() const OVERRIDE {
-    return LInstruction::kArithmeticD;
-  }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticD; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
  private:
   Token::Value op_;
@@ -1539,9 +1529,9 @@
   LOperand* right() { return inputs_[2]; }
   Token::Value op() const { return op_; }
 
-  virtual Opcode opcode() const FINAL  { return LInstruction::kArithmeticT; }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const FINAL { return LInstruction::kArithmeticT; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
  private:
   Token::Value op_;
@@ -1650,7 +1640,7 @@
   DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
   DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   uint32_t base_offset() const { return hydrogen()->base_offset(); }
 };
 
@@ -1731,7 +1721,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1750,7 +1740,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1789,7 +1779,7 @@
   LOperand* function() { return inputs_[0]; }
   LOperand* code_object() { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
   DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
@@ -1806,7 +1796,7 @@
   LOperand* base_object() const { return inputs_[0]; }
   LOperand* offset() const { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
 };
@@ -1850,7 +1840,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
   DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1870,11 +1860,12 @@
 
   const CallInterfaceDescriptor descriptor() { return descriptor_; }
 
- private:
-  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
   DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+ private:
+  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 
@@ -1882,11 +1873,11 @@
   ZoneList<LOperand*> inputs_;
 
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return inputs_.length(); }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return inputs_.length(); }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return 0; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return NULL; }
+  int TempCount() FINAL { return 0; }
+  LOperand* TempAt(int i) FINAL { return NULL; }
 };
 
 
@@ -1904,7 +1895,7 @@
   DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
   DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1940,7 +1931,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
   DECLARE_HYDROGEN_ACCESSOR(CallNew)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1959,7 +1950,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
   DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1976,7 +1967,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
   DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
 
-  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
+  bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
     return save_doubles() == kDontSaveFPRegs;
   }
 
@@ -2154,7 +2145,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Representation representation() const {
     return hydrogen()->field_representation();
@@ -2177,7 +2168,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Handle<Object> name() const { return hydrogen()->name(); }
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
@@ -2209,7 +2200,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
   uint32_t base_offset() const { return hydrogen()->base_offset(); }
 };
@@ -2235,7 +2226,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
@@ -2259,7 +2250,7 @@
                                "transition-elements-kind")
   DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
   Handle<Map> transitioned_map() {
@@ -2555,7 +2546,7 @@
 
   Handle<String> type_literal() { return hydrogen()->type_literal(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -2576,9 +2567,7 @@
  public:
   LOsrEntry() {}
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
 };
 
@@ -2781,7 +2770,7 @@
 
   // An input operand in register, stack slot or a constant operand.
   // Will not be moved to a register even if one is freely available.
-  virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
+  MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
 
   // Temporary operand that must be in a register.
   MUST_USE_RESULT LUnallocated* TempRegister();
diff --git a/src/mips64/macro-assembler-mips64.cc b/src/mips64/macro-assembler-mips64.cc
index 12d81bc..2de1c2a 100644
--- a/src/mips64/macro-assembler-mips64.cc
+++ b/src/mips64/macro-assembler-mips64.cc
@@ -14,7 +14,7 @@
 #include "src/cpu-profiler.h"
 #include "src/debug.h"
 #include "src/isolate-inl.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -22,7 +22,8 @@
 MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size)
     : Assembler(arg_isolate, buffer, size),
       generating_stub_(false),
-      has_frame_(false) {
+      has_frame_(false),
+      has_double_zero_reg_set_(false) {
   if (isolate() != NULL) {
     code_object_ = Handle<Object>(isolate()->heap()->undefined_value(),
                                   isolate());
@@ -595,11 +596,12 @@
   }
 
   bind(&done);
-  // Check that the value is a normal property.
+  // Check that the value is a field property.
   // reg2: elements + (index * kPointerSize).
   const int kDetailsOffset =
       SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
   ld(reg1, FieldMemOperand(reg2, kDetailsOffset));
+  DCHECK_EQ(FIELD, 0);
   And(at, reg1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask)));
   Branch(miss, ne, at, Operand(zero_reg));
 
@@ -711,6 +713,28 @@
 }
 
 
+void MacroAssembler::Mulhu(Register rd, Register rs, const Operand& rt) {
+  if (rt.is_reg()) {
+    if (kArchVariant != kMips64r6) {
+      multu(rs, rt.rm());
+      mfhi(rd);
+    } else {
+      muhu(rd, rs, rt.rm());
+    }
+  } else {
+    // li handles the relocation.
+    DCHECK(!rs.is(at));
+    li(at, rt);
+    if (kArchVariant != kMips64r6) {
+      multu(rs, at);
+      mfhi(rd);
+    } else {
+      muhu(rd, rs, at);
+    }
+  }
+}
+
+
 void MacroAssembler::Dmul(Register rd, Register rs, const Operand& rt) {
   if (rt.is_reg()) {
     if (kArchVariant == kMips64r6) {
@@ -815,6 +839,72 @@
 }
 
 
+void MacroAssembler::Div(Register res, Register rs, const Operand& rt) {
+  if (rt.is_reg()) {
+    if (kArchVariant != kMips64r6) {
+      div(rs, rt.rm());
+      mflo(res);
+    } else {
+      div(res, rs, rt.rm());
+    }
+  } else {
+    // li handles the relocation.
+    DCHECK(!rs.is(at));
+    li(at, rt);
+    if (kArchVariant != kMips64r6) {
+      div(rs, at);
+      mflo(res);
+    } else {
+      div(res, rs, at);
+    }
+  }
+}
+
+
+void MacroAssembler::Mod(Register rd, Register rs, const Operand& rt) {
+  if (rt.is_reg()) {
+    if (kArchVariant != kMips64r6) {
+      div(rs, rt.rm());
+      mfhi(rd);
+    } else {
+      mod(rd, rs, rt.rm());
+    }
+  } else {
+    // li handles the relocation.
+    DCHECK(!rs.is(at));
+    li(at, rt);
+    if (kArchVariant != kMips64r6) {
+      div(rs, at);
+      mfhi(rd);
+    } else {
+      mod(rd, rs, at);
+    }
+  }
+}
+
+
+void MacroAssembler::Modu(Register rd, Register rs, const Operand& rt) {
+  if (rt.is_reg()) {
+    if (kArchVariant != kMips64r6) {
+      divu(rs, rt.rm());
+      mfhi(rd);
+    } else {
+      modu(rd, rs, rt.rm());
+    }
+  } else {
+    // li handles the relocation.
+    DCHECK(!rs.is(at));
+    li(at, rt);
+    if (kArchVariant != kMips64r6) {
+      divu(rs, at);
+      mfhi(rd);
+    } else {
+      modu(rd, rs, at);
+    }
+  }
+}
+
+
 void MacroAssembler::Ddiv(Register rs, const Operand& rt) {
   if (rt.is_reg()) {
     ddiv(rs, rt.rm());
@@ -864,6 +954,28 @@
 }
 
 
+void MacroAssembler::Divu(Register res, Register rs, const Operand& rt) {
+  if (rt.is_reg()) {
+    if (kArchVariant != kMips64r6) {
+      divu(rs, rt.rm());
+      mflo(res);
+    } else {
+      divu(res, rs, rt.rm());
+    }
+  } else {
+    // li handles the relocation.
+    DCHECK(!rs.is(at));
+    li(at, rt);
+    if (kArchVariant != kMips64r6) {
+      divu(rs, at);
+      mflo(res);
+    } else {
+      divu(res, rs, at);
+    }
+  }
+}
+
+
 void MacroAssembler::Ddivu(Register rs, const Operand& rt) {
   if (rt.is_reg()) {
     ddivu(rs, rt.rm());
@@ -876,6 +988,28 @@
 }
 
 
+void MacroAssembler::Ddivu(Register res, Register rs, const Operand& rt) {
+  if (rt.is_reg()) {
+    if (kArchVariant != kMips64r6) {
+      ddivu(rs, rt.rm());
+      mflo(res);
+    } else {
+      ddivu(res, rs, rt.rm());
+    }
+  } else {
+    // li handles the relocation.
+    DCHECK(!rs.is(at));
+    li(at, rt);
+    if (kArchVariant != kMips64r6) {
+      ddivu(rs, at);
+      mflo(res);
+    } else {
+      ddivu(res, rs, at);
+    }
+  }
+}
+
+
 void MacroAssembler::Dmod(Register rd, Register rs, const Operand& rt) {
   if (kArchVariant != kMips64r6) {
     if (rt.is_reg()) {
@@ -901,6 +1035,31 @@
 }
 
 
+void MacroAssembler::Dmodu(Register rd, Register rs, const Operand& rt) {
+  if (kArchVariant != kMips64r6) {
+    if (rt.is_reg()) {
+      ddivu(rs, rt.rm());
+      mfhi(rd);
+    } else {
+      // li handles the relocation.
+      DCHECK(!rs.is(at));
+      li(at, rt);
+      ddivu(rs, at);
+      mfhi(rd);
+    }
+  } else {
+    if (rt.is_reg()) {
+      dmodu(rd, rs, rt.rm());
+    } else {
+      // li handles the relocation.
+      DCHECK(!rs.is(at));
+      li(at, rt);
+      dmodu(rd, rs, at);
+    }
+  }
+}
+
+
 void MacroAssembler::And(Register rd, Register rs, const Operand& rt) {
   if (rt.is_reg()) {
     and_(rd, rs, rt.rm());
@@ -1003,27 +1162,10 @@
 
 
 void MacroAssembler::Ror(Register rd, Register rs, const Operand& rt) {
-  if (kArchVariant == kMips64r2) {
-    if (rt.is_reg()) {
-      rotrv(rd, rs, rt.rm());
-    } else {
-      rotr(rd, rs, rt.imm64_);
-    }
+  if (rt.is_reg()) {
+    rotrv(rd, rs, rt.rm());
   } else {
-    if (rt.is_reg()) {
-      subu(at, zero_reg, rt.rm());
-      sllv(at, rs, at);
-      srlv(rd, rs, rt.rm());
-      or_(rd, rd, at);
-    } else {
-      if (rt.imm64_ == 0) {
-        srl(rd, rs, 0);
-      } else {
-        srl(at, rs, rt.imm64_);
-        sll(rd, rs, (0x20 - rt.imm64_) & 0x1f);
-        or_(rd, rd, at);
-      }
-    }
+    rotr(rd, rs, rt.imm64_);
   }
 }
 
@@ -1281,6 +1423,14 @@
 }
 
 
+void MacroAssembler::Dext(Register rt, Register rs, uint16_t pos,
+                          uint16_t size) {
+  DCHECK(pos < 32);
+  DCHECK(pos + size < 33);
+  dext_(rt, rs, pos, size);
+}
+
+
 void MacroAssembler::Ins(Register rt,
                          Register rs,
                          uint16_t pos,
@@ -1567,15 +1717,20 @@
 }
 
 
+void MacroAssembler::Move(FPURegister dst, float imm) {
+  li(at, Operand(bit_cast<int32_t>(imm)));
+  mtc1(at, dst);
+}
+
+
 void MacroAssembler::Move(FPURegister dst, double imm) {
   static const DoubleRepresentation minus_zero(-0.0);
   static const DoubleRepresentation zero(0.0);
   DoubleRepresentation value_rep(imm);
   // Handle special values first.
-  bool force_load = dst.is(kDoubleRegZero);
-  if (value_rep == zero && !force_load) {
+  if (value_rep == zero && has_double_zero_reg_set_) {
     mov_d(dst, kDoubleRegZero);
-  } else if (value_rep == minus_zero && !force_load) {
+  } else if (value_rep == minus_zero && has_double_zero_reg_set_) {
     neg_d(dst, kDoubleRegZero);
   } else {
     uint32_t lo, hi;
@@ -1596,6 +1751,7 @@
     } else {
       mthc1(zero_reg, dst);
     }
+    if (dst.is(kDoubleRegZero)) has_double_zero_reg_set_ = true;
   }
 }
 
@@ -2000,18 +2156,26 @@
         b(offset);
         break;
       case eq:
-        // We don't want any other register but scratch clobbered.
-        DCHECK(!scratch.is(rs));
-        r2 = scratch;
-        li(r2, rt);
-        beq(rs, r2, offset);
+        if (rt.imm64_ == 0) {
+          beq(rs, zero_reg, offset);
+        } else {
+          // We don't want any other register but scratch clobbered.
+          DCHECK(!scratch.is(rs));
+          r2 = scratch;
+          li(r2, rt);
+          beq(rs, r2, offset);
+        }
         break;
       case ne:
-        // We don't want any other register but scratch clobbered.
-        DCHECK(!scratch.is(rs));
-        r2 = scratch;
-        li(r2, rt);
-        bne(rs, r2, offset);
+        if (rt.imm64_ == 0) {
+          bne(rs, zero_reg, offset);
+        } else {
+          // We don't want any other register but scratch clobbered.
+          DCHECK(!scratch.is(rs));
+          r2 = scratch;
+          li(r2, rt);
+          bne(rs, r2, offset);
+        }
         break;
       // Signed comparison.
       case greater:
@@ -2253,18 +2417,28 @@
         b(offset);
         break;
       case eq:
-        DCHECK(!scratch.is(rs));
-        r2 = scratch;
-        li(r2, rt);
-        offset = shifted_branch_offset(L, false);
-        beq(rs, r2, offset);
+        if (rt.imm64_ == 0) {
+          offset = shifted_branch_offset(L, false);
+          beq(rs, zero_reg, offset);
+        } else {
+          DCHECK(!scratch.is(rs));
+          r2 = scratch;
+          li(r2, rt);
+          offset = shifted_branch_offset(L, false);
+          beq(rs, r2, offset);
+        }
         break;
       case ne:
-        DCHECK(!scratch.is(rs));
-        r2 = scratch;
-        li(r2, rt);
-        offset = shifted_branch_offset(L, false);
-        bne(rs, r2, offset);
+        if (rt.imm64_ == 0) {
+          offset = shifted_branch_offset(L, false);
+          bne(rs, zero_reg, offset);
+        } else {
+          DCHECK(!scratch.is(rs));
+          r2 = scratch;
+          li(r2, rt);
+          offset = shifted_branch_offset(L, false);
+          bne(rs, r2, offset);
+        }
         break;
       // Signed comparison.
       case greater:
@@ -3091,7 +3265,7 @@
   // Compute the handler entry address and jump to it.  The handler table is
   // a fixed array of (smi-tagged) code offsets.
   // v0 = exception, a1 = code object, a2 = state.
-  Uld(a3, FieldMemOperand(a1, Code::kHandlerTableOffset));
+  ld(a3, FieldMemOperand(a1, Code::kHandlerTableOffset));
   Daddu(a3, a3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   dsrl(a2, a2, StackHandler::kKindWidth);  // Handler index.
   dsll(a2, a2, kPointerSizeLog2);
@@ -3791,17 +3965,17 @@
 }
 
 
-void MacroAssembler::DispatchMap(Register obj,
-                                 Register scratch,
-                                 Handle<Map> map,
-                                 Handle<Code> success,
-                                 SmiCheckType smi_check_type) {
+void MacroAssembler::DispatchWeakMap(Register obj, Register scratch1,
+                                     Register scratch2, Handle<WeakCell> cell,
+                                     Handle<Code> success,
+                                     SmiCheckType smi_check_type) {
   Label fail;
   if (smi_check_type == DO_SMI_CHECK) {
     JumpIfSmi(obj, &fail);
   }
-  ld(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
-  Jump(success, RelocInfo::CODE_TARGET, eq, scratch, Operand(map));
+  ld(scratch1, FieldMemOperand(obj, HeapObject::kMapOffset));
+  GetWeakValue(scratch2, cell);
+  Jump(success, RelocInfo::CODE_TARGET, eq, scratch1, Operand(scratch2));
   bind(&fail);
 }
 
@@ -3820,6 +3994,19 @@
 }
 
 
+void MacroAssembler::GetWeakValue(Register value, Handle<WeakCell> cell) {
+  li(value, Operand(cell));
+  ld(value, FieldMemOperand(value, WeakCell::kValueOffset));
+}
+
+
+void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell,
+                                   Label* miss) {
+  GetWeakValue(value, cell);
+  JumpIfSmi(value, miss);
+}
+
+
 void MacroAssembler::MovFromFloatResult(const DoubleRegister dst) {
   if (IsMipsSoftFloatABI) {
     Move(dst, v0, v1);
@@ -4367,6 +4554,33 @@
 }
 
 
+void MacroAssembler::AdduAndCheckForOverflow(Register dst, Register left,
+                                             const Operand& right,
+                                             Register overflow_dst,
+                                             Register scratch) {
+  if (right.is_reg()) {
+    AdduAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch);
+  } else {
+    if (dst.is(left)) {
+      mov(scratch, left);                    // Preserve left.
+      daddiu(dst, left, right.immediate());  // Left is overwritten.
+      xor_(scratch, dst, scratch);           // Original left.
+      // Load right since xori takes uint16 as immediate.
+      daddiu(t9, zero_reg, right.immediate());
+      xor_(overflow_dst, dst, t9);
+      and_(overflow_dst, overflow_dst, scratch);
+    } else {
+      daddiu(dst, left, right.immediate());
+      xor_(overflow_dst, dst, left);
+      // Load right since xori takes uint16 as immediate.
+      daddiu(t9, zero_reg, right.immediate());
+      xor_(scratch, dst, t9);
+      and_(overflow_dst, scratch, overflow_dst);
+    }
+  }
+}
+
+
 void MacroAssembler::AdduAndCheckForOverflow(Register dst,
                                              Register left,
                                              Register right,
@@ -4409,6 +4623,33 @@
 }
 
 
+void MacroAssembler::SubuAndCheckForOverflow(Register dst, Register left,
+                                             const Operand& right,
+                                             Register overflow_dst,
+                                             Register scratch) {
+  if (right.is_reg()) {
+    SubuAndCheckForOverflow(dst, left, right.rm(), overflow_dst, scratch);
+  } else {
+    if (dst.is(left)) {
+      mov(scratch, left);                       // Preserve left.
+      daddiu(dst, left, -(right.immediate()));  // Left is overwritten.
+      xor_(overflow_dst, dst, scratch);         // scratch is original left.
+      // Load right since xori takes uint16 as immediate.
+      daddiu(t9, zero_reg, right.immediate());
+      xor_(scratch, scratch, t9);  // scratch is original left.
+      and_(overflow_dst, scratch, overflow_dst);
+    } else {
+      daddiu(dst, left, -(right.immediate()));
+      xor_(overflow_dst, dst, left);
+      // Load right since xori takes uint16 as immediate.
+      daddiu(t9, zero_reg, right.immediate());
+      xor_(scratch, left, t9);
+      and_(overflow_dst, scratch, overflow_dst);
+    }
+  }
+}
+
+
 void MacroAssembler::SubuAndCheckForOverflow(Register dst,
                                              Register left,
                                              Register right,
@@ -4779,6 +5020,13 @@
 }
 
 
+void MacroAssembler::EnterFrame(StackFrame::Type type,
+                                bool load_constant_pool_pointer_reg) {
+  // Out-of-line constant pool not implemented on mips64.
+  UNREACHABLE();
+}
+
+
 void MacroAssembler::EnterFrame(StackFrame::Type type) {
   daddiu(sp, sp, -5 * kPointerSize);
   li(t8, Operand(Smi::FromInt(type)));
@@ -5602,18 +5850,6 @@
 }
 
 
-void MacroAssembler::CheckMapDeprecated(Handle<Map> map,
-                                        Register scratch,
-                                        Label* if_deprecated) {
-  if (map->CanBeDeprecated()) {
-    li(scratch, Operand(map));
-    ld(scratch, FieldMemOperand(scratch, Map::kBitField3Offset));
-    And(scratch, scratch, Operand(Map::Deprecated::kMask));
-    Branch(if_deprecated, ne, scratch, Operand(zero_reg));
-  }
-}
-
-
 void MacroAssembler::JumpIfBlack(Register object,
                                  Register scratch0,
                                  Register scratch1,
@@ -6069,7 +6305,7 @@
   DCHECK(!result.is(at));
   base::MagicNumbersForDivision<uint32_t> mag =
   base::SignedDivisionByConstant(static_cast<uint32_t>(divisor));
-  li(at, Operand(mag.multiplier));
+  li(at, Operand(static_cast<int32_t>(mag.multiplier)));
   Mulh(result, dividend, Operand(at));
   bool neg = (mag.multiplier & (static_cast<uint32_t>(1) << 31)) != 0;
   if (divisor > 0 && neg) {
diff --git a/src/mips64/macro-assembler-mips64.h b/src/mips64/macro-assembler-mips64.h
index 2da48fb..a9e8772 100644
--- a/src/mips64/macro-assembler-mips64.h
+++ b/src/mips64/macro-assembler-mips64.h
@@ -271,8 +271,10 @@
     mthc1(src_high, dst);
   }
 
-  // Conditional move.
+  void Move(FPURegister dst, float imm);
   void Move(FPURegister dst, double imm);
+
+  // Conditional move.
   void Movz(Register rd, Register rs, Register rt);
   void Movn(Register rd, Register rs, Register rt);
   void Movt(Register rd, Register rs, uint16_t cc = 0);
@@ -334,10 +336,6 @@
                      Condition cc,
                      Label* condition_met);
 
-  void CheckMapDeprecated(Handle<Map> map,
-                          Register scratch,
-                          Label* if_deprecated);
-
   // Check if object is in new space.  Jumps if the object is not in new space.
   // The register scratch can be object itself, but it will be clobbered.
   void JumpIfNotInNewSpace(Register object,
@@ -599,12 +597,19 @@
 
   DEFINE_INSTRUCTION(Addu);
   DEFINE_INSTRUCTION(Daddu);
+  DEFINE_INSTRUCTION(Div);
+  DEFINE_INSTRUCTION(Divu);
+  DEFINE_INSTRUCTION(Ddivu);
+  DEFINE_INSTRUCTION(Mod);
+  DEFINE_INSTRUCTION(Modu);
   DEFINE_INSTRUCTION(Ddiv);
   DEFINE_INSTRUCTION(Subu);
   DEFINE_INSTRUCTION(Dsubu);
   DEFINE_INSTRUCTION(Dmod);
+  DEFINE_INSTRUCTION(Dmodu);
   DEFINE_INSTRUCTION(Mul);
   DEFINE_INSTRUCTION(Mulh);
+  DEFINE_INSTRUCTION(Mulhu);
   DEFINE_INSTRUCTION(Dmul);
   DEFINE_INSTRUCTION(Dmulh);
   DEFINE_INSTRUCTION2(Mult);
@@ -758,6 +763,7 @@
   // MIPS64 R2 instruction macro.
   void Ins(Register rt, Register rs, uint16_t pos, uint16_t size);
   void Ext(Register rt, Register rs, uint16_t pos, uint16_t size);
+  void Dext(Register rt, Register rs, uint16_t pos, uint16_t size);
 
   // ---------------------------------------------------------------------------
   // FPU macros. These do not handle special cases like NaN or +- inf.
@@ -1104,15 +1110,19 @@
                 Label* fail,
                 SmiCheckType smi_check_type);
 
-  // Check if the map of an object is equal to a specified map and branch to a
-  // specified target if equal. Skip the smi check if not required (object is
-  // known to be a heap object)
-  void DispatchMap(Register obj,
-                   Register scratch,
-                   Handle<Map> map,
-                   Handle<Code> success,
-                   SmiCheckType smi_check_type);
+  // Check if the map of an object is equal to a specified weak map and branch
+  // to a specified target if equal. Skip the smi check if not required
+  // (object is known to be a heap object)
+  void DispatchWeakMap(Register obj, Register scratch1, Register scratch2,
+                       Handle<WeakCell> cell, Handle<Code> success,
+                       SmiCheckType smi_check_type);
 
+  // Get value of the weak cell.
+  void GetWeakValue(Register value, Handle<WeakCell> cell);
+
+  // Load the value of the weak cell in the value register. Branch to the
+  // given miss label is the weak cell was cleared.
+  void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss);
 
   // Load and check the instance type of an object for being a string.
   // Loads the type into the second argument register.
@@ -1168,12 +1178,20 @@
                                Register overflow_dst,
                                Register scratch = at);
 
+  void AdduAndCheckForOverflow(Register dst, Register left,
+                               const Operand& right, Register overflow_dst,
+                               Register scratch = at);
+
   void SubuAndCheckForOverflow(Register dst,
                                Register left,
                                Register right,
                                Register overflow_dst,
                                Register scratch = at);
 
+  void SubuAndCheckForOverflow(Register dst, Register left,
+                               const Operand& right, Register overflow_dst,
+                               Register scratch = at);
+
   void BranchOnOverflow(Label* label,
                         Register overflow_check,
                         BranchDelaySlot bd = PROTECT) {
@@ -1198,13 +1216,10 @@
   // Runtime calls.
 
   // See comments at the beginning of CEntryStub::Generate.
-  inline void PrepareCEntryArgs(int num_args) {
-    li(s0, num_args);
-    li(s1, (num_args - 1) * kPointerSize);
-  }
+  inline void PrepareCEntryArgs(int num_args) { li(a0, num_args); }
 
   inline void PrepareCEntryFunction(const ExternalReference& ref) {
-    li(s2, Operand(ref));
+    li(a1, Operand(ref));
   }
 
 #define COND_ARGS Condition cond = al, Register rs = zero_reg, \
@@ -1617,6 +1632,7 @@
 
   // Activation support.
   void EnterFrame(StackFrame::Type type);
+  void EnterFrame(StackFrame::Type type, bool load_constant_pool_pointer_reg);
   void LeaveFrame(StackFrame::Type type);
 
   // Patch the relocated value (lui/ori pair).
@@ -1719,6 +1735,7 @@
 
   bool generating_stub_;
   bool has_frame_;
+  bool has_double_zero_reg_set_;
   // This handle will be patched with the code object on installation.
   Handle<Object> code_object_;
 
diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc
index 4c74939..9899d47 100644
--- a/src/mips64/simulator-mips64.cc
+++ b/src/mips64/simulator-mips64.cc
@@ -2080,16 +2080,15 @@
         case MFLO:
           *alu_out = get_register(LO);
           break;
-        case MULT:  // MULT == D_MUL_MUH.
-          // TODO(plind) - Unify MULT/DMULT with single set of 64-bit HI/Lo
-          // regs.
-          // TODO(plind) - make the 32-bit MULT ops conform to spec regarding
-          //   checking of 32-bit input values, and un-define operations of HW.
-          *i64hilo = static_cast<int64_t>((int32_t)rs) *
-              static_cast<int64_t>((int32_t)rt);
+        case MULT: {  // MULT == D_MUL_MUH.
+          int32_t rs_lo = static_cast<int32_t>(rs);
+          int32_t rt_lo = static_cast<int32_t>(rt);
+          *i64hilo = static_cast<int64_t>(rs_lo) * static_cast<int64_t>(rt_lo);
           break;
+        }
         case MULTU:
-          *u64hilo = static_cast<uint64_t>(rs_u) * static_cast<uint64_t>(rt_u);
+          *u64hilo = static_cast<uint64_t>(rs_u & 0xffffffff) *
+                     static_cast<uint64_t>(rt_u & 0xffffffff);
           break;
         case DMULT:  // DMULT == D_MUL_MUH.
           if (kArchVariant != kMips64r6) {
@@ -2231,7 +2230,7 @@
           // Interpret sa field as 5-bit lsb of insert.
           uint16_t lsb = sa;
           uint16_t size = msb - lsb + 1;
-          uint32_t mask = (1 << size) - 1;
+          uint64_t mask = (1ULL << size) - 1;
           *alu_out = (rt_u & ~(mask << lsb)) | ((rs_u & mask) << lsb);
           break;
         }
@@ -2241,8 +2240,18 @@
           // Interpret sa field as 5-bit lsb of extract.
           uint16_t lsb = sa;
           uint16_t size = msb + 1;
-          uint32_t mask = (1 << size) - 1;
-          *alu_out = (rs_u & (mask << lsb)) >> lsb;
+          uint64_t mask = (1ULL << size) - 1;
+          *alu_out = static_cast<int32_t>((rs_u & (mask << lsb)) >> lsb);
+          break;
+        }
+        case DEXT: {  // Mips32r2 instruction.
+          // Interpret rd field as 5-bit msb of extract.
+          uint16_t msb = rd_reg;
+          // Interpret sa field as 5-bit lsb of extract.
+          uint16_t lsb = sa;
+          uint16_t size = msb + 1;
+          uint64_t mask = (1ULL << size) - 1;
+          *alu_out = static_cast<int64_t>((rs_u & (mask << lsb)) >> lsb);
           break;
         }
         default:
@@ -2784,7 +2793,8 @@
           TraceRegWr(alu_out);
           break;
         case EXT:
-          // Ext instr leaves result in Rt, rather than Rd.
+        case DEXT:
+          // Dext/Ext instr leaves result in Rt, rather than Rd.
           set_register(rt_reg, alu_out);
           TraceRegWr(alu_out);
           break;
@@ -2816,9 +2826,9 @@
   int64_t  ft     = get_fpu_register(ft_reg);
 
   // Zero extended immediate.
-  uint32_t  oe_imm16 = 0xffff & imm16;
+  uint64_t oe_imm16 = 0xffff & imm16;
   // Sign extended immediate.
-  int32_t   se_imm16 = imm16;
+  int64_t se_imm16 = imm16;
 
   // Get current pc.
   int64_t current_pc = get_pc();
diff --git a/src/mips64/simulator-mips64.h b/src/mips64/simulator-mips64.h
index 5241554..3087dcd 100644
--- a/src/mips64/simulator-mips64.h
+++ b/src/mips64/simulator-mips64.h
@@ -436,9 +436,12 @@
 
 // When running with the simulator transition into simulated execution at this
 // point.
-#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
-    reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->Call( \
-      FUNCTION_ADDR(entry), 5, p0, p1, p2, p3, p4))
+#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4)                    \
+  reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->Call( \
+      FUNCTION_ADDR(entry), 5, reinterpret_cast<int64_t*>(p0),            \
+      reinterpret_cast<int64_t*>(p1), reinterpret_cast<int64_t*>(p2),     \
+      reinterpret_cast<int64_t*>(p3), reinterpret_cast<int64_t*>(p4)))
+
 
 #ifdef MIPS_ABI_N64
 #define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \
diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js
index c36d6fd..c325e58 100644
--- a/src/mirror-debugger.js
+++ b/src/mirror-debugger.js
@@ -1,6 +1,7 @@
 // Copyright 2006-2012 the V8 project authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
+"use strict";
 
 // Handle id counters.
 var next_handle_ = 0;
@@ -44,7 +45,7 @@
 
   // Look for non transient mirrors in the mirror cache.
   if (!opt_transient && mirror_cache_enabled_) {
-    for (id in mirror_cache_) {
+    for (var id in mirror_cache_) {
       mirror = mirror_cache_[id];
       if (mirror.value() === value) {
         return mirror;
@@ -85,6 +86,8 @@
     mirror = new MapMirror(value);
   } else if (IS_SET(value) || IS_WEAKSET(value)) {
     mirror = new SetMirror(value);
+  } else if (IS_MAP_ITERATOR(value) || IS_SET_ITERATOR(value)) {
+    mirror = new IteratorMirror(value);
   } else if (ObjectIsPromise(value)) {
     mirror = new PromiseMirror(value);
   } else if (IS_GENERATOR(value)) {
@@ -163,6 +166,7 @@
 var PROMISE_TYPE = 'promise';
 var MAP_TYPE = 'map';
 var SET_TYPE = 'set';
+var ITERATOR_TYPE = 'iterator';
 var GENERATOR_TYPE = 'generator';
 
 // Maximum length when sending strings through the JSON protocol.
@@ -176,9 +180,8 @@
 
 // A copy of the PropertyType enum from property-details.h
 var PropertyType = {};
-PropertyType.Normal                  = 0;
-PropertyType.Field                   = 1;
-PropertyType.Constant                = 2;
+PropertyType.Field                   = 0;
+PropertyType.Constant                = 1;
 PropertyType.Callbacks               = 3;
 
 
@@ -190,13 +193,16 @@
 PropertyAttribute.DontDelete = DONT_DELETE;
 
 
-// A copy of the scope types from runtime.cc.
+// A copy of the scope types from runtime-debug.cc.
+// NOTE: these constants should be backward-compatible, so
+// add new ones to the end of this list.
 var ScopeType = { Global: 0,
                   Local: 1,
                   With: 2,
                   Closure: 3,
                   Catch: 4,
-                  Block: 5 };
+                  Block: 5,
+                  Script: 6 };
 
 
 // Mirror hierarchy:
@@ -217,6 +223,7 @@
 //         - PromiseMirror
 //         - MapMirror
 //         - SetMirror
+//         - IteratorMirror
 //         - GeneratorMirror
 //     - PropertyMirror
 //     - InternalPropertyMirror
@@ -456,6 +463,15 @@
 
 
 /**
+ * Check whether the mirror reflects an iterator.
+ * @returns {boolean} True if the mirror reflects an iterator
+ */
+Mirror.prototype.isIterator = function() {
+  return this instanceof IteratorMirror;
+};
+
+
+/**
  * Allocate a handle id for this object.
  */
 Mirror.prototype.allocateHandle_ = function() {
@@ -906,13 +922,37 @@
       result.push(new InternalPropertyMirror("[[BoundArgs]]", boundArgs));
     }
     return result;
-  } else if (ObjectIsPromise(value)) {
-    var result = [];
-    result.push(new InternalPropertyMirror("[[PromiseStatus]]",
-                                           PromiseGetStatus_(value)));
-    result.push(new InternalPropertyMirror("[[PromiseValue]]",
-                                           PromiseGetValue_(value)));
+  } else if (IS_MAP_ITERATOR(value) || IS_SET_ITERATOR(value)) {
+    var details = IS_MAP_ITERATOR(value) ? %MapIteratorDetails(value)
+                                         : %SetIteratorDetails(value);
+    var kind;
+    switch (details[2]) {
+      case 1: kind = "keys"; break;
+      case 2: kind = "values"; break;
+      case 3: kind = "entries"; break;
+    }
+    var result = [
+      new InternalPropertyMirror("[[IteratorHasMore]]", details[0]),
+      new InternalPropertyMirror("[[IteratorIndex]]", details[1])
+    ];
+    if (kind) {
+      result.push(new InternalPropertyMirror("[[IteratorKind]]", kind));
+    }
     return result;
+  } else if (IS_GENERATOR(value)) {
+    return [
+      new InternalPropertyMirror("[[GeneratorStatus]]",
+                                 GeneratorGetStatus_(value)),
+      new InternalPropertyMirror("[[GeneratorFunction]]",
+                                 %GeneratorGetFunction(value)),
+      new InternalPropertyMirror("[[GeneratorReceiver]]",
+                                 %GeneratorGetReceiver(value))
+    ];
+  } else if (ObjectIsPromise(value)) {
+    return [
+      new InternalPropertyMirror("[[PromiseStatus]]", PromiseGetStatus_(value)),
+      new InternalPropertyMirror("[[PromiseValue]]", PromiseGetValue_(value))
+    ];
   }
   return [];
 }
@@ -1256,11 +1296,11 @@
   // Use the same text representation as in messages.js.
   var text;
   try {
-    str = %_CallFunction(this.value_, builtins.ErrorToString);
+    text = %_CallFunction(this.value_, builtins.ErrorToString);
   } catch (e) {
-    str = '#<Error>';
+    text = '#<Error>';
   }
-  return str;
+  return text;
 };
 
 
@@ -1309,13 +1349,14 @@
  * Returns an array of key/value pairs of a map.
  * This will keep keys alive for WeakMaps.
  *
+ * @param {number=} opt_limit Max elements to return.
  * @returns {Array.<Object>} Array of key/value pairs of a map.
  */
-MapMirror.prototype.entries = function() {
+MapMirror.prototype.entries = function(opt_limit) {
   var result = [];
 
   if (IS_WEAKMAP(this.value_)) {
-    var entries = %GetWeakMapEntries(this.value_);
+    var entries = %GetWeakMapEntries(this.value_, opt_limit || 0);
     for (var i = 0; i < entries.length; i += 2) {
       result.push({
         key: entries[i],
@@ -1327,7 +1368,8 @@
 
   var iter = %_CallFunction(this.value_, builtins.MapEntries);
   var next;
-  while (!(next = iter.next()).done) {
+  while ((!opt_limit || result.length < opt_limit) &&
+         !(next = iter.next()).done) {
     result.push({
       key: next.value[0],
       value: next.value[1]
@@ -1343,24 +1385,57 @@
 inherits(SetMirror, ObjectMirror);
 
 
+function IteratorGetValues_(iter, next_function, opt_limit) {
+  var result = [];
+  var next;
+  while ((!opt_limit || result.length < opt_limit) &&
+         !(next = %_CallFunction(iter, next_function)).done) {
+    result.push(next.value);
+  }
+  return result;
+}
+
+
 /**
  * Returns an array of elements of a set.
  * This will keep elements alive for WeakSets.
  *
+ * @param {number=} opt_limit Max elements to return.
  * @returns {Array.<Object>} Array of elements of a set.
  */
-SetMirror.prototype.values = function() {
+SetMirror.prototype.values = function(opt_limit) {
   if (IS_WEAKSET(this.value_)) {
-    return %GetWeakSetValues(this.value_);
+    return %GetWeakSetValues(this.value_, opt_limit || 0);
   }
 
-  var result = [];
   var iter = %_CallFunction(this.value_, builtins.SetValues);
-  var next;
-  while (!(next = iter.next()).done) {
-    result.push(next.value);
+  return IteratorGetValues_(iter, builtins.SetIteratorNextJS, opt_limit);
+};
+
+
+function IteratorMirror(value) {
+  %_CallFunction(this, value, ITERATOR_TYPE, ObjectMirror);
+}
+inherits(IteratorMirror, ObjectMirror);
+
+
+/**
+ * Returns a preview of elements of an iterator.
+ * Does not change the backing iterator state.
+ *
+ * @param {number=} opt_limit Max elements to return.
+ * @returns {Array.<Object>} Array of elements of an iterator.
+ */
+IteratorMirror.prototype.preview = function(opt_limit) {
+  if (IS_MAP_ITERATOR(this.value_)) {
+    return IteratorGetValues_(%MapIteratorClone(this.value_),
+                              builtins.MapIteratorNextJS,
+                              opt_limit);
+  } else if (IS_SET_ITERATOR(this.value_)) {
+    return IteratorGetValues_(%SetIteratorClone(this.value_),
+                              builtins.SetIteratorNextJS,
+                              opt_limit);
   }
-  return result;
 };
 
 
@@ -1376,11 +1451,16 @@
 inherits(GeneratorMirror, ObjectMirror);
 
 
-GeneratorMirror.prototype.status = function() {
-  var continuation = %GeneratorGetContinuation(this.value_);
+function GeneratorGetStatus_(value) {
+  var continuation = %GeneratorGetContinuation(value);
   if (continuation < 0) return "running";
   if (continuation == 0) return "closed";
   return "suspended";
+}
+
+
+GeneratorMirror.prototype.status = function() {
+  return GeneratorGetStatus_(this.value_);
 };
 
 
@@ -2245,11 +2325,12 @@
 
 
 ScopeMirror.prototype.scopeObject = function() {
-  // For local and closure scopes create a transient mirror as these objects are
-  // created on the fly materializing the local or closure scopes and
-  // therefore will not preserve identity.
+  // For local, closure and script scopes create a transient mirror
+  // as these objects are created on the fly materializing the local
+  // or closure scopes and therefore will not preserve identity.
   var transient = this.scopeType() == ScopeType.Local ||
-                  this.scopeType() == ScopeType.Closure;
+                  this.scopeType() == ScopeType.Closure ||
+                  this.scopeType() == ScopeType.Script;
   return MakeMirror(this.details_.object(), transient);
 };
 
@@ -2834,10 +2915,9 @@
  *    "ref":<number>}
  *
  * If the attribute for the property is PropertyAttribute.None it is not added.
- * If the propertyType for the property is PropertyType.Normal it is not added.
  * Here are a couple of examples.
  *
- *   {"name":"hello","ref":1}
+ *   {"name":"hello","propertyType":0,"ref":1}
  *   {"name":"length","attributes":7,"propertyType":3,"ref":2}
  *
  * @param {PropertyMirror} propertyMirror The property to serialize.
@@ -2854,9 +2934,7 @@
     if (propertyMirror.attributes() != PropertyAttribute.None) {
       result.attributes = propertyMirror.attributes();
     }
-    if (propertyMirror.propertyType() != PropertyType.Normal) {
-      result.propertyType = propertyMirror.propertyType();
-    }
+    result.propertyType = propertyMirror.propertyType();
     result.ref = propertyValue.handle();
   }
   return result;
diff --git a/src/misc-intrinsics.h b/src/misc-intrinsics.h
deleted file mode 100644
index 5256a29..0000000
--- a/src/misc-intrinsics.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_MISC_INTRINSICS_H_
-#define V8_MISC_INTRINSICS_H_
-
-#include "include/v8.h"
-#include "src/globals.h"
-
-namespace v8 {
-namespace internal {
-
-// Returns the index of the leading 1 bit, counting the least significant bit at
-// index 0.  (1 << IntegerLog2(x)) is a mask for the most significant bit of x.
-// Result is undefined if input is zero.
-int IntegerLog2(uint32_t value);
-
-#if defined(__GNUC__)
-
-inline int IntegerLog2(uint32_t value) {
-  return 31 - __builtin_clz(value);
-}
-
-#elif defined(_MSC_VER)
-
-#pragma intrinsic(_BitScanReverse)
-
-inline int IntegerLog2(uint32_t value) {
-  unsigned long result;             // NOLINT: MSVC intrinsic demands this type.
-  _BitScanReverse(&result, value);
-  return result;
-}
-
-#else
-
-// Default version using regular operations. Code taken from:
-// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
-inline int IntegerLog2(uint32_t value) {
-  int result, shift;
-
-  shift = (value > 0xFFFF) << 4;
-  value >>= shift;
-  result = shift;
-
-  shift = (value > 0xFF) << 3;
-  value >>= shift;
-  result |= shift;
-
-  shift = (value > 0xF) << 2;
-  value >>= shift;
-  result |= shift;
-
-  shift = (value > 0x3) << 1;
-  value >>= shift;
-  result |= shift;
-
-  result |= (value >> 1);
-
-  return result;
-}
-#endif
-
-} }  // namespace v8::internal
-
-#endif  // V8_MISC_INTRINSICS_H_
diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc
index b4a4018..988e7da 100644
--- a/src/mksnapshot.cc
+++ b/src/mksnapshot.cc
@@ -3,11 +3,8 @@
 // found in the LICENSE file.
 
 #include <errno.h>
-#include <stdio.h>
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-#include <bzlib.h>
-#endif
 #include <signal.h>
+#include <stdio.h>
 
 #include "src/v8.h"
 
@@ -23,100 +20,43 @@
 
 using namespace v8;
 
-
-class Compressor {
- public:
-  virtual ~Compressor() {}
-  virtual bool Compress(i::Vector<i::byte> input) = 0;
-  virtual i::Vector<i::byte>* output() = 0;
-};
-
-
 class SnapshotWriter {
  public:
   explicit SnapshotWriter(const char* snapshot_file)
-      : fp_(GetFileDescriptorOrDie(snapshot_file))
-      , raw_file_(NULL)
-      , raw_context_file_(NULL)
-      , startup_blob_file_(NULL)
-      , compressor_(NULL) {
-  }
+      : fp_(GetFileDescriptorOrDie(snapshot_file)),
+        startup_blob_file_(NULL) {}
 
   ~SnapshotWriter() {
     fclose(fp_);
-    if (raw_file_) fclose(raw_file_);
-    if (raw_context_file_) fclose(raw_context_file_);
     if (startup_blob_file_) fclose(startup_blob_file_);
   }
 
-  void SetCompressor(Compressor* compressor) {
-    compressor_ = compressor;
-  }
-
-  void SetRawFiles(const char* raw_file, const char* raw_context_file) {
-    raw_file_ = GetFileDescriptorOrDie(raw_file);
-    raw_context_file_ = GetFileDescriptorOrDie(raw_context_file);
-  }
-
   void SetStartupBlobFile(const char* startup_blob_file) {
     if (startup_blob_file != NULL)
       startup_blob_file_ = GetFileDescriptorOrDie(startup_blob_file);
   }
 
-  void WriteSnapshot(const i::List<i::byte>& snapshot_data,
-                     const i::Serializer& serializer,
-                     const i::List<i::byte>& context_snapshot_data,
-                     const i::Serializer& context_serializer) const {
-    WriteSnapshotFile(snapshot_data, serializer,
-                      context_snapshot_data, context_serializer);
-    MaybeWriteStartupBlob(snapshot_data, serializer,
-                          context_snapshot_data, context_serializer);
+  void WriteSnapshot(v8::StartupData blob) const {
+    i::Vector<const i::byte> blob_vector(
+        reinterpret_cast<const i::byte*>(blob.data), blob.raw_size);
+    WriteSnapshotFile(blob_vector);
+    MaybeWriteStartupBlob(blob_vector);
   }
 
  private:
-  void MaybeWriteStartupBlob(const i::List<i::byte>& snapshot_data,
-                             const i::Serializer& serializer,
-                             const i::List<i::byte>& context_snapshot_data,
-                             const i::Serializer& context_serializer) const {
-    if (!startup_blob_file_)
-      return;
+  void MaybeWriteStartupBlob(const i::Vector<const i::byte>& blob) const {
+    if (!startup_blob_file_) return;
 
-    i::List<i::byte> startup_blob;
-    i::ListSnapshotSink sink(&startup_blob);
-
-    int spaces[] = {
-        i::NEW_SPACE, i::OLD_POINTER_SPACE, i::OLD_DATA_SPACE, i::CODE_SPACE,
-        i::MAP_SPACE, i::CELL_SPACE,  i::PROPERTY_CELL_SPACE
-    };
-
-    i::byte* snapshot_bytes = snapshot_data.begin();
-    sink.PutBlob(snapshot_bytes, snapshot_data.length(), "snapshot");
-    for (size_t i = 0; i < arraysize(spaces); ++i)
-      sink.PutInt(serializer.CurrentAllocationAddress(spaces[i]), "spaces");
-
-    i::byte* context_bytes = context_snapshot_data.begin();
-    sink.PutBlob(context_bytes, context_snapshot_data.length(), "context");
-    for (size_t i = 0; i < arraysize(spaces); ++i)
-      sink.PutInt(context_serializer.CurrentAllocationAddress(spaces[i]),
-                  "spaces");
-
-    size_t written = fwrite(startup_blob.begin(), 1, startup_blob.length(),
-                            startup_blob_file_);
-    if (written != (size_t)startup_blob.length()) {
+    size_t written = fwrite(blob.begin(), 1, blob.length(), startup_blob_file_);
+    if (written != static_cast<size_t>(blob.length())) {
       i::PrintF("Writing snapshot file failed.. Aborting.\n");
       exit(1);
     }
   }
 
-  void WriteSnapshotFile(const i::List<i::byte>& snapshot_data,
-                         const i::Serializer& serializer,
-                         const i::List<i::byte>& context_snapshot_data,
-                         const i::Serializer& context_serializer) const {
+  void WriteSnapshotFile(const i::Vector<const i::byte>& blob) const {
     WriteFilePrefix();
-    WriteData("", snapshot_data, raw_file_);
-    WriteData("context_", context_snapshot_data, raw_context_file_);
-    WriteMeta("context_", context_serializer);
-    WriteMeta("", serializer);
+    WriteData(blob);
     WriteFileSuffix();
   }
 
@@ -130,89 +70,29 @@
   }
 
   void WriteFileSuffix() const {
+    fprintf(fp_, "const v8::StartupData Snapshot::SnapshotBlob() {\n");
+    fprintf(fp_, "  v8::StartupData blob;\n");
+    fprintf(fp_, "  blob.data = reinterpret_cast<const char*>(blob_data);\n");
+    fprintf(fp_, "  blob.raw_size = blob_size;\n");
+    fprintf(fp_, "  return blob;\n");
+    fprintf(fp_, "}\n\n");
     fprintf(fp_, "}  // namespace internal\n");
     fprintf(fp_, "}  // namespace v8\n");
   }
 
-  void WriteData(const char* prefix, const i::List<i::byte>& source_data,
-                 FILE* raw_file) const {
-    const i::List<i::byte>* data_to_be_written = NULL;
-    i::List<i::byte> compressed_data;
-    if (!compressor_) {
-      data_to_be_written = &source_data;
-    } else if (compressor_->Compress(source_data.ToVector())) {
-      compressed_data.AddAll(*compressor_->output());
-      data_to_be_written = &compressed_data;
-    } else {
-      i::PrintF("Compression failed. Aborting.\n");
-      exit(1);
-    }
-
-    DCHECK(data_to_be_written);
-    MaybeWriteRawFile(data_to_be_written, raw_file);
-    WriteData(prefix, source_data, data_to_be_written);
-  }
-
-  void MaybeWriteRawFile(const i::List<i::byte>* data, FILE* raw_file) const {
-    if (!data || !raw_file)
-      return;
-
-    // Sanity check, whether i::List iterators truly return pointers to an
-    // internal array.
-    DCHECK(data->end() - data->begin() == data->length());
-
-    size_t written = fwrite(data->begin(), 1, data->length(), raw_file);
-    if (written != (size_t)data->length()) {
-      i::PrintF("Writing raw file failed.. Aborting.\n");
-      exit(1);
-    }
-  }
-
-  void WriteData(const char* prefix, const i::List<i::byte>& source_data,
-                 const i::List<i::byte>* data_to_be_written) const {
-    fprintf(fp_, "const byte Snapshot::%sdata_[] = {\n", prefix);
-    WriteSnapshotData(data_to_be_written);
+  void WriteData(const i::Vector<const i::byte>& blob) const {
+    fprintf(fp_, "static const byte blob_data[] = {\n");
+    WriteSnapshotData(blob);
     fprintf(fp_, "};\n");
-    fprintf(fp_, "const int Snapshot::%ssize_ = %d;\n", prefix,
-            data_to_be_written->length());
-
-    if (data_to_be_written == &source_data) {
-      fprintf(fp_, "const byte* Snapshot::%sraw_data_ = Snapshot::%sdata_;\n",
-              prefix, prefix);
-      fprintf(fp_, "const int Snapshot::%sraw_size_ = Snapshot::%ssize_;\n",
-              prefix, prefix);
-    } else {
-      fprintf(fp_, "const byte* Snapshot::%sraw_data_ = NULL;\n", prefix);
-      fprintf(fp_, "const int Snapshot::%sraw_size_ = %d;\n",
-              prefix, source_data.length());
-    }
+    fprintf(fp_, "static const int blob_size = %d;\n", blob.length());
     fprintf(fp_, "\n");
   }
 
-  void WriteMeta(const char* prefix, const i::Serializer& ser) const {
-    WriteSizeVar(ser, prefix, "new", i::NEW_SPACE);
-    WriteSizeVar(ser, prefix, "pointer", i::OLD_POINTER_SPACE);
-    WriteSizeVar(ser, prefix, "data", i::OLD_DATA_SPACE);
-    WriteSizeVar(ser, prefix, "code", i::CODE_SPACE);
-    WriteSizeVar(ser, prefix, "map", i::MAP_SPACE);
-    WriteSizeVar(ser, prefix, "cell", i::CELL_SPACE);
-    WriteSizeVar(ser, prefix, "property_cell", i::PROPERTY_CELL_SPACE);
-    fprintf(fp_, "\n");
-  }
-
-  void WriteSizeVar(const i::Serializer& ser, const char* prefix,
-                    const char* name, int space) const {
-    fprintf(fp_, "const int Snapshot::%s%s_space_used_ = %d;\n",
-            prefix, name, ser.CurrentAllocationAddress(space));
-  }
-
-  void WriteSnapshotData(const i::List<i::byte>* data) const {
-    for (int i = 0; i < data->length(); i++) {
-      if ((i & 0x1f) == 0x1f)
-        fprintf(fp_, "\n");
-      if (i > 0)
-        fprintf(fp_, ",");
-      fprintf(fp_, "%u", static_cast<unsigned char>(data->at(i)));
+  void WriteSnapshotData(const i::Vector<const i::byte>& blob) const {
+    for (int i = 0; i < blob.length(); i++) {
+      if ((i & 0x1f) == 0x1f) fprintf(fp_, "\n");
+      if (i > 0) fprintf(fp_, ",");
+      fprintf(fp_, "%u", static_cast<unsigned char>(blob.at(i)));
     }
     fprintf(fp_, "\n");
   }
@@ -227,85 +107,20 @@
   }
 
   FILE* fp_;
-  FILE* raw_file_;
-  FILE* raw_context_file_;
   FILE* startup_blob_file_;
-  Compressor* compressor_;
 };
 
 
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-class BZip2Compressor : public Compressor {
- public:
-  BZip2Compressor() : output_(NULL) {}
-  virtual ~BZip2Compressor() {
-    delete output_;
-  }
-  virtual bool Compress(i::Vector<char> input) {
-    delete output_;
-    output_ = new i::ScopedVector<char>((input.length() * 101) / 100 + 1000);
-    unsigned int output_length_ = output_->length();
-    int result = BZ2_bzBuffToBuffCompress(output_->start(), &output_length_,
-                                          input.start(), input.length(),
-                                          9, 1, 0);
-    if (result == BZ_OK) {
-      output_->Truncate(output_length_);
-      return true;
-    } else {
-      fprintf(stderr, "bzlib error code: %d\n", result);
-      return false;
-    }
-  }
-  virtual i::Vector<char>* output() { return output_; }
-
- private:
-  i::ScopedVector<char>* output_;
-};
-
-
-class BZip2Decompressor : public StartupDataDecompressor {
- public:
-  virtual ~BZip2Decompressor() { }
-
- protected:
-  virtual int DecompressData(char* raw_data,
-                             int* raw_data_size,
-                             const char* compressed_data,
-                             int compressed_data_size) {
-    DCHECK_EQ(StartupData::kBZip2,
-              V8::GetCompressedStartupDataAlgorithm());
-    unsigned int decompressed_size = *raw_data_size;
-    int result =
-        BZ2_bzBuffToBuffDecompress(raw_data,
-                                   &decompressed_size,
-                                   const_cast<char*>(compressed_data),
-                                   compressed_data_size,
-                                   0, 1);
-    if (result == BZ_OK) {
-      *raw_data_size = decompressed_size;
-    }
-    return result;
-  }
-};
-#endif
-
-
-void DumpException(Handle<Message> message) {
-  String::Utf8Value message_string(message->Get());
-  String::Utf8Value message_line(message->GetSourceLine());
-  fprintf(stderr, "%s at line %d\n", *message_string, message->GetLineNumber());
-  fprintf(stderr, "%s\n", *message_line);
-  for (int i = 0; i <= message->GetEndColumn(); ++i) {
-    fprintf(stderr, "%c", i < message->GetStartColumn() ? ' ' : '^');
-  }
-  fprintf(stderr, "\n");
-}
-
-
 int main(int argc, char** argv) {
   // By default, log code create information in the snapshot.
   i::FLAG_log_code = true;
 
+  // Omit from the snapshot natives for features that can be turned off
+  // at runtime.
+  i::FLAG_harmony_shipping = false;
+
+  i::FLAG_logfile_per_isolate = false;
+
   // Print the usage if an error occurs when parsing the command line
   // flags or if the help flag is set.
   int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true);
@@ -321,116 +136,15 @@
   v8::V8::InitializePlatform(platform);
   v8::V8::Initialize();
 
-#ifdef COMPRESS_STARTUP_DATA_BZ2
-  BZip2Decompressor natives_decompressor;
-  int bz2_result = natives_decompressor.Decompress();
-  if (bz2_result != BZ_OK) {
-    fprintf(stderr, "bzip error code: %d\n", bz2_result);
-    exit(1);
-  }
-#endif
-  i::FLAG_logfile_per_isolate = false;
-
-  Isolate::CreateParams params;
-  params.enable_serializer = true;
-  Isolate* isolate = v8::Isolate::New(params);
-  { Isolate::Scope isolate_scope(isolate);
-    i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
-
-    Persistent<Context> context;
-    {
-      HandleScope handle_scope(isolate);
-      context.Reset(isolate, Context::New(isolate));
-    }
-
-    if (context.IsEmpty()) {
-      fprintf(stderr,
-              "\nException thrown while compiling natives - see above.\n\n");
-      exit(1);
-    }
-    if (i::FLAG_extra_code != NULL) {
-      // Capture 100 frames if anything happens.
-      V8::SetCaptureStackTraceForUncaughtExceptions(true, 100);
-      HandleScope scope(isolate);
-      v8::Context::Scope cscope(v8::Local<v8::Context>::New(isolate, context));
-      const char* name = i::FLAG_extra_code;
-      FILE* file = base::OS::FOpen(name, "rb");
-      if (file == NULL) {
-        fprintf(stderr, "Failed to open '%s': errno %d\n", name, errno);
-        exit(1);
-      }
-
-      fseek(file, 0, SEEK_END);
-      int size = ftell(file);
-      rewind(file);
-
-      char* chars = new char[size + 1];
-      chars[size] = '\0';
-      for (int i = 0; i < size;) {
-        int read = static_cast<int>(fread(&chars[i], 1, size - i, file));
-        if (read < 0) {
-          fprintf(stderr, "Failed to read '%s': errno %d\n", name, errno);
-          exit(1);
-        }
-        i += read;
-      }
-      fclose(file);
-      Local<String> source = String::NewFromUtf8(isolate, chars);
-      TryCatch try_catch;
-      Local<Script> script = Script::Compile(source);
-      if (try_catch.HasCaught()) {
-        fprintf(stderr, "Failure compiling '%s'\n", name);
-        DumpException(try_catch.Message());
-        exit(1);
-      }
-      script->Run();
-      if (try_catch.HasCaught()) {
-        fprintf(stderr, "Failure running '%s'\n", name);
-        DumpException(try_catch.Message());
-        exit(1);
-      }
-    }
-    // Make sure all builtin scripts are cached.
-    { HandleScope scope(isolate);
-      for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
-        internal_isolate->bootstrapper()->NativesSourceLookup(i);
-      }
-    }
-    // If we don't do this then we end up with a stray root pointing at the
-    // context even after we have disposed of the context.
-    internal_isolate->heap()->CollectAllGarbage(
-        i::Heap::kNoGCFlags, "mksnapshot");
-    i::Object* raw_context = *v8::Utils::OpenPersistent(context);
-    context.Reset();
-
-    // This results in a somewhat smaller snapshot, probably because it gets
-    // rid of some things that are cached between garbage collections.
-    i::List<i::byte> snapshot_data;
-    i::ListSnapshotSink snapshot_sink(&snapshot_data);
-    i::StartupSerializer ser(internal_isolate, &snapshot_sink);
-    ser.SerializeStrongReferences();
-
-    i::List<i::byte> context_data;
-    i::ListSnapshotSink contex_sink(&context_data);
-    i::PartialSerializer context_ser(internal_isolate, &ser, &contex_sink);
-    context_ser.Serialize(&raw_context);
-    ser.SerializeWeakReferences();
-
-    {
-      SnapshotWriter writer(argv[1]);
-      if (i::FLAG_raw_file && i::FLAG_raw_context_file)
-        writer.SetRawFiles(i::FLAG_raw_file, i::FLAG_raw_context_file);
-      if (i::FLAG_startup_blob)
-        writer.SetStartupBlobFile(i::FLAG_startup_blob);
-  #ifdef COMPRESS_STARTUP_DATA_BZ2
-      BZip2Compressor bzip2;
-      writer.SetCompressor(&bzip2);
-  #endif
-      writer.WriteSnapshot(snapshot_data, ser, context_data, context_ser);
-    }
+  {
+    SnapshotWriter writer(argv[1]);
+    if (i::FLAG_startup_blob) writer.SetStartupBlobFile(i::FLAG_startup_blob);
+    StartupData blob = v8::V8::CreateSnapshotDataBlob();
+    CHECK(blob.data);
+    writer.WriteSnapshot(blob);
+    delete[] blob.data;
   }
 
-  isolate->Dispose();
   V8::Dispose();
   V8::ShutdownPlatform();
   delete platform;
diff --git a/src/natives-external.cc b/src/natives-external.cc
index fc66149..e601808 100644
--- a/src/natives-external.cc
+++ b/src/natives-external.cc
@@ -10,6 +10,11 @@
 #include "src/snapshot-source-sink.h"
 #include "src/vector.h"
 
+#ifndef V8_USE_EXTERNAL_STARTUP_DATA
+#error natives-external.cc is used only for the external snapshot build.
+#endif  // V8_USE_EXTERNAL_STARTUP_DATA
+
+
 namespace v8 {
 namespace internal {
 
@@ -23,20 +28,26 @@
  */
 class NativesStore {
  public:
-  ~NativesStore() {}
+  ~NativesStore() {
+    for (int i = 0; i < native_names_.length(); i++) {
+      native_names_[i].Dispose();
+    }
+  }
 
-  int GetBuiltinsCount() { return native_names_.length(); }
+  int GetBuiltinsCount() { return native_ids_.length(); }
   int GetDebuggerCount() { return debugger_count_; }
-  Vector<const char> GetScriptName(int index) { return native_names_[index]; }
-  Vector<const char> GetRawScriptSource(int index) {
+
+  Vector<const char> GetScriptSource(int index) {
     return native_source_[index];
   }
 
-  int GetIndex(const char* name) {
-    for (int i = 0; i < native_names_.length(); ++i) {
-      int native_name_length = native_names_[i].length();
-      if ((static_cast<int>(strlen(name)) == native_name_length) &&
-          (strncmp(name, native_names_[i].start(), native_name_length) == 0)) {
+  Vector<const char> GetScriptName(int index) { return native_names_[index]; }
+
+  int GetIndex(const char* id) {
+    for (int i = 0; i < native_ids_.length(); ++i) {
+      int native_id_length = native_ids_[i].length();
+      if ((static_cast<int>(strlen(id)) == native_id_length) &&
+          (strncmp(id, native_ids_[i].start(), native_id_length) == 0)) {
         return i;
       }
     }
@@ -44,14 +55,9 @@
     return -1;
   }
 
-  int GetRawScriptsSize() {
-    DCHECK(false);  // Used for compression. Doesn't really make sense here.
-    return 0;
-  }
-
-  Vector<const byte> GetScriptsSource() {
-    DCHECK(false);  // Used for compression. Doesn't really make sense here.
-    return Vector<const byte>();
+  Vector<const char> GetScriptsSource() {
+    DCHECK(false);  // Not implemented.
+    return Vector<const char>();
   }
 
   static NativesStore* MakeFromScriptsSource(SnapshotByteSource* source) {
@@ -75,24 +81,38 @@
  private:
   NativesStore() : debugger_count_(0) {}
 
+  Vector<const char> NameFromId(const byte* id, int id_length) {
+    const char native[] = "native ";
+    const char extension[] = ".js";
+    Vector<char> name(Vector<char>::New(id_length + sizeof(native) - 1 +
+                                        sizeof(extension) - 1));
+    memcpy(name.start(), native, sizeof(native) - 1);
+    memcpy(name.start() + sizeof(native) - 1, id, id_length);
+    memcpy(name.start() + sizeof(native) - 1 + id_length, extension,
+           sizeof(extension) - 1);
+    return Vector<const char>::cast(name);
+  }
+
   bool ReadNameAndContentPair(SnapshotByteSource* bytes) {
-    const byte* name;
-    int name_length;
+    const byte* id;
+    int id_length;
     const byte* source;
     int source_length;
-    bool success = bytes->GetBlob(&name, &name_length) &&
+    bool success = bytes->GetBlob(&id, &id_length) &&
                    bytes->GetBlob(&source, &source_length);
     if (success) {
-      Vector<const char> name_vector(
-          reinterpret_cast<const char*>(name), name_length);
+      Vector<const char> id_vector(reinterpret_cast<const char*>(id),
+                                   id_length);
       Vector<const char> source_vector(
           reinterpret_cast<const char*>(source), source_length);
-      native_names_.Add(name_vector);
+      native_ids_.Add(id_vector);
       native_source_.Add(source_vector);
+      native_names_.Add(NameFromId(id, id_length));
     }
     return success;
   }
 
+  List<Vector<const char> > native_ids_;
   List<Vector<const char> > native_names_;
   List<Vector<const char> > native_source_;
   int debugger_count_;
@@ -130,9 +150,7 @@
   DCHECK(natives_blob->data);
   DCHECK(natives_blob->raw_size > 0);
 
-  SnapshotByteSource bytes(
-      reinterpret_cast<const byte*>(natives_blob->data),
-      natives_blob->raw_size);
+  SnapshotByteSource bytes(natives_blob->data, natives_blob->raw_size);
   NativesHolder<CORE>::set(NativesStore::MakeFromScriptsSource(&bytes));
   NativesHolder<EXPERIMENTAL>::set(NativesStore::MakeFromScriptsSource(&bytes));
   DCHECK(!bytes.HasMore());
@@ -160,14 +178,9 @@
   return NativesHolder<type>::get()->GetIndex(name);
 }
 
-template<NativeType type>
-int NativesCollection<type>::GetRawScriptsSize() {
-  return NativesHolder<type>::get()->GetRawScriptsSize();
-}
-
-template<NativeType type>
-Vector<const char> NativesCollection<type>::GetRawScriptSource(int index) {
-  return NativesHolder<type>::get()->GetRawScriptSource(index);
+template <NativeType type>
+Vector<const char> NativesCollection<type>::GetScriptSource(int index) {
+  return NativesHolder<type>::get()->GetScriptSource(index);
 }
 
 template<NativeType type>
@@ -175,24 +188,16 @@
   return NativesHolder<type>::get()->GetScriptName(index);
 }
 
-template<NativeType type>
-Vector<const byte> NativesCollection<type>::GetScriptsSource() {
+template <NativeType type>
+Vector<const char> NativesCollection<type>::GetScriptsSource() {
   return NativesHolder<type>::get()->GetScriptsSource();
 }
 
-template<NativeType type>
-void NativesCollection<type>::SetRawScriptsSource(
-    Vector<const char> raw_source) {
-  CHECK(false);  // Use SetNativesFromFile for this implementation.
-}
-
 
 // The compiler can't 'see' all uses of the static methods and hence
-// my chose to elide them. This we'll explicitly instantiate these.
+// my choice to elide them. This we'll explicitly instantiate these.
 template class NativesCollection<CORE>;
 template class NativesCollection<EXPERIMENTAL>;
-template class NativesCollection<D8>;
-template class NativesCollection<TEST>;
 
 }  // namespace v8::internal
 }  // namespace v8
diff --git a/src/natives.h b/src/natives.h
index 6ddedf0..7ce7213 100644
--- a/src/natives.h
+++ b/src/natives.h
@@ -12,10 +12,6 @@
 namespace v8 {
 namespace internal {
 
-typedef bool (*NativeSourceCallback)(Vector<const char> name,
-                                     Vector<const char> source,
-                                     int index);
-
 enum NativeType {
   CORE, EXPERIMENTAL, D8, TEST
 };
@@ -33,11 +29,9 @@
   // non-debugger scripts have an index in the interval [GetDebuggerCount(),
   // GetNativesCount()).
   static int GetIndex(const char* name);
-  static int GetRawScriptsSize();
-  static Vector<const char> GetRawScriptSource(int index);
+  static Vector<const char> GetScriptSource(int index);
   static Vector<const char> GetScriptName(int index);
-  static Vector<const byte> GetScriptsSource();
-  static void SetRawScriptsSource(Vector<const char> raw_source);
+  static Vector<const char> GetScriptsSource();
 };
 
 typedef NativesCollection<CORE> Natives;
diff --git a/src/object-observe.js b/src/object-observe.js
index 76f3915..01ce805 100644
--- a/src/object-observe.js
+++ b/src/object-observe.js
@@ -35,10 +35,15 @@
 
 var observationState;
 
+// We have to wait until after bootstrapping to grab a reference to the
+// observationState object, since it's not possible to serialize that
+// reference into the snapshot.
 function GetObservationStateJS() {
-  if (IS_UNDEFINED(observationState))
+  if (IS_UNDEFINED(observationState)) {
     observationState = %GetObservationState();
+  }
 
+  // TODO(adamk): Consider moving this code into heap.cc
   if (IS_UNDEFINED(observationState.callbackInfoMap)) {
     observationState.callbackInfoMap = %ObservationWeakMapCreate();
     observationState.objectInfoMap = %ObservationWeakMapCreate();
@@ -51,55 +56,6 @@
   return observationState;
 }
 
-function GetWeakMapWrapper() {
-  function MapWrapper(map) {
-    this.map_ = map;
-  };
-
-  MapWrapper.prototype = {
-    __proto__: null,
-    get: function(key) {
-      return %WeakCollectionGet(this.map_, key);
-    },
-    set: function(key, value) {
-      %WeakCollectionSet(this.map_, key, value);
-    },
-    has: function(key) {
-      return !IS_UNDEFINED(this.get(key));
-    }
-  };
-
-  return MapWrapper;
-}
-
-var contextMaps;
-
-function GetContextMaps() {
-  if (IS_UNDEFINED(contextMaps)) {
-    var map = GetWeakMapWrapper();
-    var observationState = GetObservationStateJS();
-    contextMaps = {
-      callbackInfoMap: new map(observationState.callbackInfoMap),
-      objectInfoMap: new map(observationState.objectInfoMap),
-      notifierObjectInfoMap: new map(observationState.notifierObjectInfoMap)
-    };
-  }
-
-  return contextMaps;
-}
-
-function GetCallbackInfoMap() {
-  return GetContextMaps().callbackInfoMap;
-}
-
-function GetObjectInfoMap() {
-  return GetContextMaps().objectInfoMap;
-}
-
-function GetNotifierObjectInfoMap() {
-  return GetContextMaps().notifierObjectInfoMap;
-}
-
 function GetPendingObservers() {
   return GetObservationStateJS().pendingObservers;
 }
@@ -194,9 +150,9 @@
 function ObjectInfoGetOrCreate(object) {
   var objectInfo = ObjectInfoGet(object);
   if (IS_UNDEFINED(objectInfo)) {
-    if (!%IsJSProxy(object))
+    if (!%_IsJSProxy(object)) {
       %SetIsObserved(object);
-
+    }
     objectInfo = {
       object: object,
       changeObservers: null,
@@ -204,35 +160,34 @@
       performing: null,
       performingCount: 0,
     };
-    GetObjectInfoMap().set(object, objectInfo);
+    %WeakCollectionSet(GetObservationStateJS().objectInfoMap,
+                       object, objectInfo);
   }
   return objectInfo;
 }
 
 function ObjectInfoGet(object) {
-  return GetObjectInfoMap().get(object);
+  return %WeakCollectionGet(GetObservationStateJS().objectInfoMap, object);
 }
 
 function ObjectInfoGetFromNotifier(notifier) {
-  return GetNotifierObjectInfoMap().get(notifier);
+  return %WeakCollectionGet(GetObservationStateJS().notifierObjectInfoMap,
+                            notifier);
 }
 
 function ObjectInfoGetNotifier(objectInfo) {
   if (IS_NULL(objectInfo.notifier)) {
     objectInfo.notifier = { __proto__: notifierPrototype };
-    GetNotifierObjectInfoMap().set(objectInfo.notifier, objectInfo);
+    %WeakCollectionSet(GetObservationStateJS().notifierObjectInfoMap,
+                       objectInfo.notifier, objectInfo);
   }
 
   return objectInfo.notifier;
 }
 
-function ObjectInfoGetObject(objectInfo) {
-  return objectInfo.object;
-}
-
 function ChangeObserversIsOptimized(changeObservers) {
-  return typeof changeObservers === 'function' ||
-         typeof changeObservers.callback === 'function';
+  return IS_SPEC_FUNCTION(changeObservers) ||
+         IS_SPEC_FUNCTION(changeObservers.callback);
 }
 
 // The set of observers on an object is called 'changeObservers'. The first
@@ -328,16 +283,21 @@
 // priority. When a change record must be enqueued for the callback, it
 // normalizes. When delivery clears any pending change records, it re-optimizes.
 function CallbackInfoGet(callback) {
-  return GetCallbackInfoMap().get(callback);
+  return %WeakCollectionGet(GetObservationStateJS().callbackInfoMap, callback);
+}
+
+function CallbackInfoSet(callback, callbackInfo) {
+  %WeakCollectionSet(GetObservationStateJS().callbackInfoMap,
+                     callback, callbackInfo);
 }
 
 function CallbackInfoGetOrCreate(callback) {
-  var callbackInfo = GetCallbackInfoMap().get(callback);
+  var callbackInfo = CallbackInfoGet(callback);
   if (!IS_UNDEFINED(callbackInfo))
     return callbackInfo;
 
-  var priority =  GetNextCallbackPriority();
-  GetCallbackInfoMap().set(callback, priority);
+  var priority = GetNextCallbackPriority();
+  CallbackInfoSet(callback, priority);
   return priority;
 }
 
@@ -349,12 +309,12 @@
 }
 
 function CallbackInfoNormalize(callback) {
-  var callbackInfo = GetCallbackInfoMap().get(callback);
+  var callbackInfo = CallbackInfoGet(callback);
   if (IS_NUMBER(callbackInfo)) {
     var priority = callbackInfo;
     callbackInfo = new InternalArray;
     callbackInfo.priority = priority;
-    GetCallbackInfoMap().set(callback, callbackInfo);
+    CallbackInfoSet(callback, callbackInfo);
   }
   return callbackInfo;
 }
@@ -445,8 +405,8 @@
 
   var hasType = !IS_UNDEFINED(type);
   var newRecord = hasType ?
-      { object: ObjectInfoGetObject(objectInfo), type: type } :
-      { object: ObjectInfoGetObject(objectInfo) };
+      { object: objectInfo.object, type: type } :
+      { object: objectInfo.object };
 
   for (var prop in changeRecord) {
     if (prop === 'object' || (hasType && prop === 'type')) continue;
@@ -594,24 +554,24 @@
 }
 
 function CallbackDeliverPending(callback) {
-  var callbackInfo = GetCallbackInfoMap().get(callback);
+  var callbackInfo = CallbackInfoGet(callback);
   if (IS_UNDEFINED(callbackInfo) || IS_NUMBER(callbackInfo))
     return false;
 
   // Clear the pending change records from callback and return it to its
   // "optimized" state.
   var priority = callbackInfo.priority;
-  GetCallbackInfoMap().set(callback, priority);
+  CallbackInfoSet(callback, priority);
 
-  if (GetPendingObservers())
-    delete GetPendingObservers()[priority];
+  var pendingObservers = GetPendingObservers();
+  if (!IS_NULL(pendingObservers))
+    delete pendingObservers[priority];
 
+  // TODO: combine the following runtime calls for perf optimization.
   var delivered = [];
   %MoveArrayContents(callbackInfo, delivered);
+  %DeliverObservationChangeRecords(callback, delivered);
 
-  try {
-    %_CallFunction(UNDEFINED, delivered, callback);
-  } catch (ex) {}  // TODO(rossberg): perhaps log uncaught exceptions.
   return true;
 }
 
@@ -624,7 +584,7 @@
 
 function ObserveMicrotaskRunner() {
   var pendingObservers = GetPendingObservers();
-  if (pendingObservers) {
+  if (!IS_NULL(pendingObservers)) {
     SetPendingObservers(null);
     for (var i in pendingObservers) {
       CallbackDeliverPending(pendingObservers[i]);
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index a2395de..e990559 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -47,6 +47,10 @@
     return;
   }
 
+  // TODO(yangguo): Use this check once crbug/436911 has been fixed.
+  //  DCHECK(!NeedsToEnsureDoubleAlignment() ||
+  //         IsAligned(OffsetFrom(address()), kDoubleAlignment));
+
   switch (instance_type) {
     case SYMBOL_TYPE:
       Symbol::cast(this)->SymbolVerify();
@@ -125,6 +129,9 @@
     case PROPERTY_CELL_TYPE:
       PropertyCell::cast(this)->PropertyCellVerify();
       break;
+    case WEAK_CELL_TYPE:
+      WeakCell::cast(this)->WeakCellVerify();
+      break;
     case JS_ARRAY_TYPE:
       JSArray::cast(this)->JSArrayVerify();
       break;
@@ -256,14 +263,26 @@
   }
 
   if (HasFastProperties()) {
-    CHECK_EQ(map()->unused_property_fields(),
-             (map()->inobject_properties() + properties()->length() -
-              map()->NextFreePropertyIndex()));
+    int actual_unused_property_fields = map()->inobject_properties() +
+                                        properties()->length() -
+                                        map()->NextFreePropertyIndex();
+    if (map()->unused_property_fields() != actual_unused_property_fields) {
+      // This could actually happen in the middle of StoreTransitionStub
+      // when the new extended backing store is already set into the object and
+      // the allocation of the MutableHeapNumber triggers GC (in this case map
+      // is not updated yet).
+      CHECK_EQ(map()->unused_property_fields(),
+               actual_unused_property_fields - JSObject::kFieldsAdded);
+    }
     DescriptorArray* descriptors = map()->instance_descriptors();
     for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
       if (descriptors->GetDetails(i).type() == FIELD) {
         Representation r = descriptors->GetDetails(i).representation();
         FieldIndex index = FieldIndex::ForDescriptor(map(), i);
+        if (IsUnboxedDoubleField(index)) {
+          DCHECK(r.IsDouble());
+          continue;
+        }
         Object* value = RawFastPropertyAt(index);
         if (r.IsDouble()) DCHECK(value->IsMutableHeapNumber());
         if (value->IsUninitialized()) continue;
@@ -305,6 +324,8 @@
     SLOW_DCHECK(transitions()->IsSortedNoDuplicates());
     SLOW_DCHECK(transitions()->IsConsistentWithBackPointers(this));
   }
+  SLOW_DCHECK(!FLAG_unbox_double_fields ||
+              layout_descriptor()->IsConsistentWithMap(this));
 }
 
 
@@ -314,8 +335,7 @@
   CHECK(instance_descriptors()->IsEmpty());
   CHECK_EQ(0, pre_allocated_property_fields());
   CHECK_EQ(0, unused_property_fields());
-  CHECK_EQ(StaticVisitorBase::GetVisitorId(instance_type(), instance_size()),
-      visitor_id());
+  CHECK_EQ(StaticVisitorBase::GetVisitorId(this), visitor_id());
 }
 
 
@@ -547,7 +567,7 @@
   VerifyObjectField(JSGlobalProxy::kNativeContextOffset);
   // Make sure that this object has no properties, elements.
   CHECK_EQ(0, properties()->length());
-  CHECK(HasFastSmiElements());
+  CHECK_EQ(FAST_HOLEY_SMI_ELEMENTS, GetElementsKind());
   CHECK_EQ(0, FixedArray::cast(elements())->length());
 }
 
@@ -627,6 +647,13 @@
 }
 
 
+void WeakCell::WeakCellVerify() {
+  CHECK(IsWeakCell());
+  VerifyObjectField(kValueOffset);
+  VerifyObjectField(kNextOffset);
+}
+
+
 void Code::CodeVerify() {
   CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
                   kCodeAlignment));
@@ -657,9 +684,8 @@
     if (IsWeakObject(obj)) {
       if (obj->IsMap()) {
         Map* map = Map::cast(obj);
-        DependentCode::DependencyGroup group = is_optimized_code() ?
-            DependentCode::kWeakCodeGroup : DependentCode::kWeakICGroup;
-        CHECK(map->dependent_code()->Contains(group, this));
+        CHECK(map->dependent_code()->Contains(DependentCode::kWeakCodeGroup,
+                                              this));
       } else if (obj->IsJSObject()) {
         Object* raw_table = GetIsolate()->heap()->weak_object_to_code_table();
         WeakHashTable* table = WeakHashTable::cast(raw_table);
@@ -904,6 +930,7 @@
   VerifyPointer(deleter());
   VerifyPointer(enumerator());
   VerifyPointer(data());
+  VerifySmiField(kFlagsOffset);
 }
 
 
@@ -1146,15 +1173,13 @@
   for (int i = 0; i < number_of_descriptors(); i++) {
     Name* key = GetSortedKey(i);
     if (key == current_key) {
-      OFStream os(stdout);
-      PrintDescriptors(os);
+      Print();
       return false;
     }
     current_key = key;
     uint32_t hash = GetSortedKey(i)->Hash();
     if (hash < current) {
-      OFStream os(stdout);
-      PrintDescriptors(os);
+      Print();
       return false;
     }
     current = hash;
@@ -1163,25 +1188,58 @@
 }
 
 
+bool LayoutDescriptor::IsConsistentWithMap(Map* map) {
+  if (FLAG_unbox_double_fields) {
+    DescriptorArray* descriptors = map->instance_descriptors();
+    int nof_descriptors = map->NumberOfOwnDescriptors();
+    for (int i = 0; i < nof_descriptors; i++) {
+      PropertyDetails details = descriptors->GetDetails(i);
+      if (details.type() != FIELD) continue;
+      FieldIndex field_index = FieldIndex::ForDescriptor(map, i);
+      bool tagged_expected =
+          !field_index.is_inobject() || !details.representation().IsDouble();
+      for (int bit = 0; bit < details.field_width_in_words(); bit++) {
+        bool tagged_actual = IsTagged(details.field_index() + bit);
+        DCHECK_EQ(tagged_expected, tagged_actual);
+        if (tagged_actual != tagged_expected) return false;
+      }
+    }
+  }
+  return true;
+}
+
+
 bool TransitionArray::IsSortedNoDuplicates(int valid_entries) {
   DCHECK(valid_entries == -1);
-  Name* current_key = NULL;
-  uint32_t current = 0;
+  Name* prev_key = NULL;
+  PropertyKind prev_kind = DATA;
+  PropertyAttributes prev_attributes = NONE;
+  uint32_t prev_hash = 0;
   for (int i = 0; i < number_of_transitions(); i++) {
     Name* key = GetSortedKey(i);
-    if (key == current_key) {
-      OFStream os(stdout);
-      PrintTransitions(os);
+    uint32_t hash = key->Hash();
+    PropertyKind kind = DATA;
+    PropertyAttributes attributes = NONE;
+    if (!IsSpecialTransition(key)) {
+      Map* target = GetTarget(i);
+      PropertyDetails details = GetTargetDetails(key, target);
+      kind = details.kind();
+      attributes = details.attributes();
+    } else {
+      // Duplicate entries are not allowed for non-property transitions.
+      CHECK_NE(prev_key, key);
+    }
+
+    int cmp = CompareKeys(prev_key, prev_hash, prev_kind, prev_attributes, key,
+                          hash, kind, attributes);
+    if (cmp >= 0) {
+      Print();
       return false;
     }
-    current_key = key;
-    uint32_t hash = GetSortedKey(i)->Hash();
-    if (hash < current) {
-      OFStream os(stdout);
-      PrintTransitions(os);
-      return false;
-    }
-    current = hash;
+    prev_key = key;
+    prev_hash = hash;
+    prev_attributes = attributes;
+    prev_kind = kind;
   }
   return true;
 }
@@ -1200,6 +1258,24 @@
 }
 
 
+void Code::VerifyEmbeddedObjectsInFullCode() {
+  // Check that no context-specific object has been embedded.
+  Heap* heap = GetIsolate()->heap();
+  int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
+  for (RelocIterator it(this, mask); !it.done(); it.next()) {
+    Object* obj = it.rinfo()->target_object();
+    if (obj->IsCell()) obj = Cell::cast(obj)->value();
+    if (obj->IsPropertyCell()) obj = PropertyCell::cast(obj)->value();
+    if (!obj->IsHeapObject()) continue;
+    Map* map = obj->IsMap() ? Map::cast(obj) : HeapObject::cast(obj)->map();
+    int i = 0;
+    while (map != heap->roots_array_start()[i++]) {
+      CHECK_LT(i, Heap::kStrongRootListLength);
+    }
+  }
+}
+
+
 #endif  // DEBUG
 
 } }  // namespace v8::internal
diff --git a/src/objects-inl.h b/src/objects-inl.h
index e46dd8e..fdfadb1 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -26,6 +26,7 @@
 #include "src/heap/spaces.h"
 #include "src/heap/store-buffer.h"
 #include "src/isolate.h"
+#include "src/layout-descriptor-inl.h"
 #include "src/lookup.h"
 #include "src/objects.h"
 #include "src/property.h"
@@ -56,6 +57,14 @@
 }
 
 
+int PropertyDetails::field_width_in_words() const {
+  DCHECK(type() == FIELD);
+  if (!FLAG_unbox_double_fields) return 1;
+  if (kDoubleSize == kPointerSize) return 1;
+  return representation().IsDouble() ? kDoubleSize / kPointerSize : 1;
+}
+
+
 #define TYPE_CHECKER(type, instancetype)                                \
   bool Object::Is##type() const {                                       \
   return Object::IsHeapObject() &&                                      \
@@ -464,12 +473,24 @@
 
 STATIC_ASSERT(v8::String::TWO_BYTE_ENCODING == kTwoByteStringTag);
 
+
 uc32 FlatStringReader::Get(int index) {
-  DCHECK(0 <= index && index <= length_);
   if (is_one_byte_) {
-    return static_cast<const byte*>(start_)[index];
+    return Get<uint8_t>(index);
   } else {
-    return static_cast<const uc16*>(start_)[index];
+    return Get<uc16>(index);
+  }
+}
+
+
+template <typename Char>
+Char FlatStringReader::Get(int index) {
+  DCHECK_EQ(is_one_byte_, sizeof(Char) == 1);
+  DCHECK(0 <= index && index <= length_);
+  if (sizeof(Char) == 1) {
+    return static_cast<Char>(static_cast<const uint8_t*>(start_)[index]);
+  } else {
+    return static_cast<Char>(static_cast<const uc16*>(start_)[index]);
   }
 }
 
@@ -479,11 +500,6 @@
 }
 
 
-Handle<Object> MapCacheShape::AsHandle(Isolate* isolate, HashTableKey* key) {
-  return key->AsHandle(isolate);
-}
-
-
 Handle<Object> CompilationCacheShape::AsHandle(Isolate* isolate,
                                                HashTableKey* key) {
   return key->AsHandle(isolate);
@@ -501,7 +517,7 @@
   explicit SequentialStringKey(Vector<const Char> string, uint32_t seed)
       : string_(string), hash_field_(0), seed_(seed) { }
 
-  virtual uint32_t Hash() OVERRIDE {
+  uint32_t Hash() OVERRIDE {
     hash_field_ = StringHasher::HashSequentialString<Char>(string_.start(),
                                                            string_.length(),
                                                            seed_);
@@ -512,7 +528,7 @@
   }
 
 
-  virtual uint32_t HashForObject(Object* other) OVERRIDE {
+  uint32_t HashForObject(Object* other) OVERRIDE {
     return String::cast(other)->Hash();
   }
 
@@ -527,11 +543,11 @@
   OneByteStringKey(Vector<const uint8_t> str, uint32_t seed)
       : SequentialStringKey<uint8_t>(str, seed) { }
 
-  virtual bool IsMatch(Object* string) OVERRIDE {
+  bool IsMatch(Object* string) OVERRIDE {
     return String::cast(string)->IsOneByteEqualTo(string_);
   }
 
-  virtual Handle<Object> AsHandle(Isolate* isolate) OVERRIDE;
+  Handle<Object> AsHandle(Isolate* isolate) OVERRIDE;
 };
 
 
@@ -542,7 +558,7 @@
     DCHECK(string_->IsSeqOneByteString());
   }
 
-  virtual uint32_t Hash() OVERRIDE {
+  uint32_t Hash() OVERRIDE {
     DCHECK(length_ >= 0);
     DCHECK(from_ + length_ <= string_->length());
     const uint8_t* chars = string_->GetChars() + from_;
@@ -553,12 +569,12 @@
     return result;
   }
 
-  virtual uint32_t HashForObject(Object* other) OVERRIDE {
+  uint32_t HashForObject(Object* other) OVERRIDE {
     return String::cast(other)->Hash();
   }
 
-  virtual bool IsMatch(Object* string) OVERRIDE;
-  virtual Handle<Object> AsHandle(Isolate* isolate) OVERRIDE;
+  bool IsMatch(Object* string) OVERRIDE;
+  Handle<Object> AsHandle(Isolate* isolate) OVERRIDE;
 
  private:
   Handle<SeqOneByteString> string_;
@@ -573,11 +589,11 @@
   explicit TwoByteStringKey(Vector<const uc16> str, uint32_t seed)
       : SequentialStringKey<uc16>(str, seed) { }
 
-  virtual bool IsMatch(Object* string) OVERRIDE {
+  bool IsMatch(Object* string) OVERRIDE {
     return String::cast(string)->IsTwoByteEqualTo(string_);
   }
 
-  virtual Handle<Object> AsHandle(Isolate* isolate) OVERRIDE;
+  Handle<Object> AsHandle(Isolate* isolate) OVERRIDE;
 };
 
 
@@ -587,11 +603,11 @@
   explicit Utf8StringKey(Vector<const char> string, uint32_t seed)
       : string_(string), hash_field_(0), seed_(seed) { }
 
-  virtual bool IsMatch(Object* string) OVERRIDE {
+  bool IsMatch(Object* string) OVERRIDE {
     return String::cast(string)->IsUtf8EqualTo(string_);
   }
 
-  virtual uint32_t Hash() OVERRIDE {
+  uint32_t Hash() OVERRIDE {
     if (hash_field_ != 0) return hash_field_ >> String::kHashShift;
     hash_field_ = StringHasher::ComputeUtf8Hash(string_, seed_, &chars_);
     uint32_t result = hash_field_ >> String::kHashShift;
@@ -599,11 +615,11 @@
     return result;
   }
 
-  virtual uint32_t HashForObject(Object* other) OVERRIDE {
+  uint32_t HashForObject(Object* other) OVERRIDE {
     return String::cast(other)->Hash();
   }
 
-  virtual Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
+  Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
     if (hash_field_ == 0) Hash();
     return isolate->factory()->NewInternalizedStringFromUtf8(
         string_, chars_, hash_field_);
@@ -691,6 +707,7 @@
 TYPE_CHECKER(Map, MAP_TYPE)
 TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
 TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
+TYPE_CHECKER(WeakFixedArray, FIXED_ARRAY_TYPE)
 TYPE_CHECKER(ConstantPoolArray, CONSTANT_POOL_ARRAY_TYPE)
 
 
@@ -704,6 +721,11 @@
 }
 
 
+bool Object::IsLayoutDescriptor() const {
+  return IsSmi() || IsFixedTypedArrayBase();
+}
+
+
 bool Object::IsTransitionArray() const {
   return IsFixedArray();
 }
@@ -756,7 +778,7 @@
       map == heap->native_context_map() ||
       map == heap->block_context_map() ||
       map == heap->module_context_map() ||
-      map == heap->global_context_map());
+      map == heap->script_context_map());
 }
 
 
@@ -767,6 +789,14 @@
 }
 
 
+bool Object::IsScriptContextTable() const {
+  if (!Object::IsHeapObject()) return false;
+  Map* map = HeapObject::cast(this)->map();
+  Heap* heap = map->GetHeap();
+  return map == heap->script_context_table_map();
+}
+
+
 bool Object::IsScopeInfo() const {
   return Object::IsHeapObject() &&
       HeapObject::cast(this)->map() ==
@@ -786,6 +816,7 @@
 TYPE_CHECKER(Oddball, ODDBALL_TYPE)
 TYPE_CHECKER(Cell, CELL_TYPE)
 TYPE_CHECKER(PropertyCell, PROPERTY_CELL_TYPE)
+TYPE_CHECKER(WeakCell, WEAK_CELL_TYPE)
 TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
 TYPE_CHECKER(JSGeneratorObject, JS_GENERATOR_OBJECT_TYPE)
 TYPE_CHECKER(JSModule, JS_MODULE_TYPE)
@@ -1121,6 +1152,19 @@
 }
 
 
+Handle<Object> Object::GetPrototypeSkipHiddenPrototypes(
+    Isolate* isolate, Handle<Object> receiver) {
+  PrototypeIterator iter(isolate, receiver);
+  while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
+    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
+      return PrototypeIterator::GetCurrent(iter);
+    }
+    iter.Advance();
+  }
+  return PrototypeIterator::GetCurrent(iter);
+}
+
+
 MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> object,
                                                  Handle<Name> name) {
   uint32_t index;
@@ -1621,21 +1665,6 @@
 }
 
 
-inline DependentCode::DependencyGroup AllocationSite::ToDependencyGroup(
-    Reason reason) {
-  switch (reason) {
-    case TENURING:
-      return DependentCode::kAllocationSiteTenuringChangedGroup;
-      break;
-    case TRANSITIONS:
-      return DependentCode::kAllocationSiteTransitionChangedGroup;
-      break;
-  }
-  UNREACHABLE();
-  return DependentCode::kAllocationSiteTransitionChangedGroup;
-}
-
-
 inline void AllocationSite::set_memento_found_count(int count) {
   int value = pretenure_data()->value();
   // Verify that we can count more mementos than we can possibly find in one
@@ -1870,11 +1899,11 @@
   DisallowHeapAllocation no_allocation;
   if (!map->HasTransitionArray()) return Handle<Map>::null();
   TransitionArray* transitions = map->transitions();
-  int transition = transitions->Search(*key);
+  int transition = transitions->Search(DATA, *key, NONE);
   if (transition == TransitionArray::kNotFound) return Handle<Map>::null();
-  PropertyDetails target_details = transitions->GetTargetDetails(transition);
-  if (target_details.type() != FIELD) return Handle<Map>::null();
-  if (target_details.attributes() != NONE) return Handle<Map>::null();
+  PropertyDetails details = transitions->GetTargetDetails(transition);
+  if (details.type() != FIELD) return Handle<Map>::null();
+  DCHECK_EQ(NONE, details.attributes());
   return Handle<Map>(transitions->GetTarget(transition));
 }
 
@@ -1916,6 +1945,35 @@
 }
 
 
+Object* WeakCell::value() const { return READ_FIELD(this, kValueOffset); }
+
+
+void WeakCell::clear() {
+  DCHECK(GetHeap()->gc_state() == Heap::MARK_COMPACT);
+  WRITE_FIELD(this, kValueOffset, Smi::FromInt(0));
+}
+
+
+void WeakCell::initialize(HeapObject* val) {
+  WRITE_FIELD(this, kValueOffset, val);
+  WRITE_BARRIER(GetHeap(), this, kValueOffset, val);
+}
+
+
+bool WeakCell::cleared() const { return value() == Smi::FromInt(0); }
+
+
+Object* WeakCell::next() const { return READ_FIELD(this, kNextOffset); }
+
+
+void WeakCell::set_next(Object* val, WriteBarrierMode mode) {
+  WRITE_FIELD(this, kNextOffset, val);
+  if (mode == UPDATE_WRITE_BARRIER) {
+    WRITE_BARRIER(GetHeap(), this, kNextOffset, val);
+  }
+}
+
+
 int JSObject::GetHeaderSize() {
   InstanceType type = map()->instance_type();
   // Check for the most common kind of JavaScript object before
@@ -2019,10 +2077,24 @@
 }
 
 
+bool JSObject::IsUnboxedDoubleField(FieldIndex index) {
+  if (!FLAG_unbox_double_fields) return false;
+  return map()->IsUnboxedDoubleField(index);
+}
+
+
+bool Map::IsUnboxedDoubleField(FieldIndex index) {
+  if (!FLAG_unbox_double_fields) return false;
+  if (index.is_hidden_field() || !index.is_inobject()) return false;
+  return !layout_descriptor()->IsTagged(index.property_index());
+}
+
+
 // Access fast-case object properties at index. The use of these routines
 // is needed to correctly distinguish between properties stored in-object and
 // properties stored in the properties array.
 Object* JSObject::RawFastPropertyAt(FieldIndex index) {
+  DCHECK(!IsUnboxedDoubleField(index));
   if (index.is_inobject()) {
     return READ_FIELD(this, index.offset());
   } else {
@@ -2031,7 +2103,13 @@
 }
 
 
-void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
+double JSObject::RawFastDoublePropertyAt(FieldIndex index) {
+  DCHECK(IsUnboxedDoubleField(index));
+  return READ_DOUBLE_FIELD(this, index.offset());
+}
+
+
+void JSObject::RawFastPropertyAtPut(FieldIndex index, Object* value) {
   if (index.is_inobject()) {
     int offset = index.offset();
     WRITE_FIELD(this, offset, value);
@@ -2042,6 +2120,21 @@
 }
 
 
+void JSObject::RawFastDoublePropertyAtPut(FieldIndex index, double value) {
+  WRITE_DOUBLE_FIELD(this, index.offset(), value);
+}
+
+
+void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
+  if (IsUnboxedDoubleField(index)) {
+    DCHECK(value->IsMutableHeapNumber());
+    RawFastDoublePropertyAtPut(index, HeapNumber::cast(value)->value());
+  } else {
+    RawFastPropertyAtPut(index, value);
+  }
+}
+
+
 int JSObject::GetInObjectPropertyOffset(int index) {
   return map()->GetInObjectPropertyOffset(index);
 }
@@ -2162,7 +2255,7 @@
 }
 
 
-Object* FixedArray::get(int index) {
+Object* FixedArray::get(int index) const {
   SLOW_DCHECK(index >= 0 && index < this->length());
   return READ_FIELD(this, kHeaderSize + index * kPointerSize);
 }
@@ -2276,6 +2369,39 @@
 }
 
 
+Object* WeakFixedArray::Get(int index) const {
+  Object* raw = FixedArray::cast(this)->get(index + kFirstIndex);
+  if (raw->IsSmi()) return raw;
+  return WeakCell::cast(raw)->value();
+}
+
+
+bool WeakFixedArray::IsEmptySlot(int index) const {
+  DCHECK(index < Length());
+  return Get(index)->IsSmi();
+}
+
+
+void WeakFixedArray::clear(int index) {
+  FixedArray::cast(this)->set(index + kFirstIndex, Smi::FromInt(0));
+}
+
+
+int WeakFixedArray::Length() const {
+  return FixedArray::cast(this)->length() - kFirstIndex;
+}
+
+
+int WeakFixedArray::last_used_index() const {
+  return Smi::cast(FixedArray::cast(this)->get(kLastUsedIndexIndex))->value();
+}
+
+
+void WeakFixedArray::set_last_used_index(int index) {
+  FixedArray::cast(this)->set(kLastUsedIndexIndex, Smi::FromInt(index));
+}
+
+
 void ConstantPoolArray::NumberOfEntries::increment(Type type) {
   DCHECK(type < NUMBER_OF_TYPES);
   element_counts_[type]++;
@@ -2622,14 +2748,14 @@
 
   // Initialize the extended layout fields.
   int extended_header_offset = get_extended_section_header_offset();
-  WRITE_INT_FIELD(this, extended_header_offset + kExtendedInt64CountOffset,
-      extended.count_of(INT64));
-  WRITE_INT_FIELD(this, extended_header_offset + kExtendedCodePtrCountOffset,
-      extended.count_of(CODE_PTR));
-  WRITE_INT_FIELD(this, extended_header_offset + kExtendedHeapPtrCountOffset,
-      extended.count_of(HEAP_PTR));
-  WRITE_INT_FIELD(this, extended_header_offset + kExtendedInt32CountOffset,
-      extended.count_of(INT32));
+  WRITE_INT32_FIELD(this, extended_header_offset + kExtendedInt64CountOffset,
+                    extended.count_of(INT64));
+  WRITE_INT32_FIELD(this, extended_header_offset + kExtendedCodePtrCountOffset,
+                    extended.count_of(CODE_PTR));
+  WRITE_INT32_FIELD(this, extended_header_offset + kExtendedHeapPtrCountOffset,
+                    extended.count_of(HEAP_PTR));
+  WRITE_INT32_FIELD(this, extended_header_offset + kExtendedInt32CountOffset,
+                    extended.count_of(INT32));
 }
 
 
@@ -2666,6 +2792,17 @@
 }
 
 
+bool HeapObject::NeedsToEnsureDoubleAlignment() {
+#ifndef V8_HOST_ARCH_64_BIT
+  return (IsFixedFloat64Array() || IsFixedDoubleArray() ||
+          IsConstantPoolArray()) &&
+         FixedArrayBase::cast(this)->length() != 0;
+#else
+  return false;
+#endif  // V8_HOST_ARCH_64_BIT
+}
+
+
 void FixedArray::set(int index,
                      Object* value,
                      WriteBarrierMode mode) {
@@ -2758,8 +2895,10 @@
 // Perform a binary search in a fixed array. Low and high are entry indices. If
 // there are three entries in this array it should be called with low=0 and
 // high=2.
-template<SearchMode search_mode, typename T>
-int BinarySearch(T* array, Name* name, int low, int high, int valid_entries) {
+template <SearchMode search_mode, typename T>
+int BinarySearch(T* array, Name* name, int low, int high, int valid_entries,
+                 int* out_insertion_index) {
+  DCHECK(search_mode == ALL_ENTRIES || out_insertion_index == NULL);
   uint32_t hash = name->Hash();
   int limit = high;
 
@@ -2780,7 +2919,13 @@
   for (; low <= limit; ++low) {
     int sort_index = array->GetSortedKeyIndex(low);
     Name* entry = array->GetKey(sort_index);
-    if (entry->Hash() != hash) break;
+    uint32_t current_hash = entry->Hash();
+    if (current_hash != hash) {
+      if (out_insertion_index != NULL) {
+        *out_insertion_index = sort_index + (current_hash > hash ? 0 : 1);
+      }
+      return T::kNotFound;
+    }
     if (entry->Equals(name)) {
       if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
         return sort_index;
@@ -2789,37 +2934,45 @@
     }
   }
 
+  if (out_insertion_index != NULL) *out_insertion_index = limit + 1;
   return T::kNotFound;
 }
 
 
 // Perform a linear search in this fixed array. len is the number of entry
 // indices that are valid.
-template<SearchMode search_mode, typename T>
-int LinearSearch(T* array, Name* name, int len, int valid_entries) {
+template <SearchMode search_mode, typename T>
+int LinearSearch(T* array, Name* name, int len, int valid_entries,
+                 int* out_insertion_index) {
   uint32_t hash = name->Hash();
   if (search_mode == ALL_ENTRIES) {
     for (int number = 0; number < len; number++) {
       int sorted_index = array->GetSortedKeyIndex(number);
       Name* entry = array->GetKey(sorted_index);
       uint32_t current_hash = entry->Hash();
-      if (current_hash > hash) break;
+      if (current_hash > hash) {
+        if (out_insertion_index != NULL) *out_insertion_index = sorted_index;
+        return T::kNotFound;
+      }
       if (current_hash == hash && entry->Equals(name)) return sorted_index;
     }
+    if (out_insertion_index != NULL) *out_insertion_index = len;
+    return T::kNotFound;
   } else {
     DCHECK(len >= valid_entries);
+    DCHECK_EQ(NULL, out_insertion_index);  // Not supported here.
     for (int number = 0; number < valid_entries; number++) {
       Name* entry = array->GetKey(number);
       uint32_t current_hash = entry->Hash();
       if (current_hash == hash && entry->Equals(name)) return number;
     }
+    return T::kNotFound;
   }
-  return T::kNotFound;
 }
 
 
-template<SearchMode search_mode, typename T>
-int Search(T* array, Name* name, int valid_entries) {
+template <SearchMode search_mode, typename T>
+int Search(T* array, Name* name, int valid_entries, int* out_insertion_index) {
   if (search_mode == VALID_ENTRIES) {
     SLOW_DCHECK(array->IsSortedNoDuplicates(valid_entries));
   } else {
@@ -2827,7 +2980,10 @@
   }
 
   int nof = array->number_of_entries();
-  if (nof == 0) return T::kNotFound;
+  if (nof == 0) {
+    if (out_insertion_index != NULL) *out_insertion_index = 0;
+    return T::kNotFound;
+  }
 
   // Fast case: do linear search for small arrays.
   const int kMaxElementsForLinearSearch = 8;
@@ -2835,16 +2991,18 @@
        nof <= kMaxElementsForLinearSearch) ||
       (search_mode == VALID_ENTRIES &&
        valid_entries <= (kMaxElementsForLinearSearch * 3))) {
-    return LinearSearch<search_mode>(array, name, nof, valid_entries);
+    return LinearSearch<search_mode>(array, name, nof, valid_entries,
+                                     out_insertion_index);
   }
 
   // Slow case: perform binary search.
-  return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries);
+  return BinarySearch<search_mode>(array, name, 0, nof - 1, valid_entries,
+                                   out_insertion_index);
 }
 
 
 int DescriptorArray::Search(Name* name, int valid_descriptors) {
-  return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors);
+  return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors, NULL);
 }
 
 
@@ -2879,10 +3037,10 @@
 }
 
 
-void Map::LookupTransition(JSObject* holder,
-                           Name* name,
+void Map::LookupTransition(JSObject* holder, Name* name,
+                           PropertyAttributes attributes,
                            LookupResult* result) {
-  int transition_index = this->SearchTransition(name);
+  int transition_index = this->SearchTransition(DATA, name, attributes);
   if (transition_index == TransitionArray::kNotFound) return result->NotFound();
   result->TransitionResult(holder, this->GetTransition(transition_index));
 }
@@ -3039,8 +3197,7 @@
   NoIncrementalWriteBarrierSet(this,
                                ToValueIndex(descriptor_number),
                                *desc->GetValue());
-  NoIncrementalWriteBarrierSet(this,
-                               ToDetailsIndex(descriptor_number),
+  NoIncrementalWriteBarrierSet(this, ToDetailsIndex(descriptor_number),
                                desc->GetDetails().AsSmi());
 }
 
@@ -3215,8 +3372,8 @@
 CAST_ACCESSOR(JSValue)
 CAST_ACCESSOR(JSWeakMap)
 CAST_ACCESSOR(JSWeakSet)
+CAST_ACCESSOR(LayoutDescriptor)
 CAST_ACCESSOR(Map)
-CAST_ACCESSOR(MapCache)
 CAST_ACCESSOR(Name)
 CAST_ACCESSOR(NameDictionary)
 CAST_ACCESSOR(NormalizedMapCache)
@@ -3240,6 +3397,8 @@
 CAST_ACCESSOR(Struct)
 CAST_ACCESSOR(Symbol)
 CAST_ACCESSOR(UnseededNumberDictionary)
+CAST_ACCESSOR(WeakCell)
+CAST_ACCESSOR(WeakFixedArray)
 CAST_ACCESSOR(WeakHashTable)
 
 
@@ -3301,7 +3460,11 @@
 void Name::set_hash_field(uint32_t value) {
   WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
 #if V8_HOST_ARCH_64_BIT
-  WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
+#if V8_TARGET_LITTLE_ENDIAN
+  WRITE_UINT32_FIELD(this, kHashFieldSlot + kIntSize, 0);
+#else
+  WRITE_UINT32_FIELD(this, kHashFieldSlot, 0);
+#endif
 #endif
 }
 
@@ -3466,6 +3629,22 @@
 }
 
 
+template <>
+inline Vector<const uint8_t> String::GetCharVector() {
+  String::FlatContent flat = GetFlatContent();
+  DCHECK(flat.IsOneByte());
+  return flat.ToOneByteVector();
+}
+
+
+template <>
+inline Vector<const uc16> String::GetCharVector() {
+  String::FlatContent flat = GetFlatContent();
+  DCHECK(flat.IsTwoByte());
+  return flat.ToUC16Vector();
+}
+
+
 uint16_t SeqOneByteString::SeqOneByteStringGet(int index) {
   DCHECK(index >= 0 && index < length());
   return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
@@ -3645,28 +3824,26 @@
 }
 
 
-int ConsStringIteratorOp::OffsetForDepth(int depth) {
-  return depth & kDepthMask;
-}
+int ConsStringIterator::OffsetForDepth(int depth) { return depth & kDepthMask; }
 
 
-void ConsStringIteratorOp::PushLeft(ConsString* string) {
+void ConsStringIterator::PushLeft(ConsString* string) {
   frames_[depth_++ & kDepthMask] = string;
 }
 
 
-void ConsStringIteratorOp::PushRight(ConsString* string) {
+void ConsStringIterator::PushRight(ConsString* string) {
   // Inplace update.
   frames_[(depth_-1) & kDepthMask] = string;
 }
 
 
-void ConsStringIteratorOp::AdjustMaximumDepth() {
+void ConsStringIterator::AdjustMaximumDepth() {
   if (depth_ > maximum_depth_) maximum_depth_ = depth_;
 }
 
 
-void ConsStringIteratorOp::Pop() {
+void ConsStringIterator::Pop() {
   DCHECK(depth_ > 0);
   DCHECK(depth_ <= maximum_depth_);
   depth_--;
@@ -3682,11 +3859,8 @@
 }
 
 
-StringCharacterStream::StringCharacterStream(String* string,
-                                             ConsStringIteratorOp* op,
-                                             int offset)
-  : is_one_byte_(false),
-    op_(op) {
+StringCharacterStream::StringCharacterStream(String* string, int offset)
+    : is_one_byte_(false) {
   Reset(string, offset);
 }
 
@@ -3695,9 +3869,9 @@
   buffer8_ = NULL;
   end_ = NULL;
   ConsString* cons_string = String::VisitFlat(this, string, offset);
-  op_->Reset(cons_string, offset);
+  iter_.Reset(cons_string, offset);
   if (cons_string != NULL) {
-    string = op_->Next(&offset);
+    string = iter_.Next(&offset);
     if (string != NULL) String::VisitFlat(this, string, offset);
   }
 }
@@ -3706,7 +3880,7 @@
 bool StringCharacterStream::HasMore() {
   if (buffer8_ != end_) return true;
   int offset;
-  String* string = op_->Next(&offset);
+  String* string = iter_.Next(&offset);
   DCHECK_EQ(offset, 0);
   if (string == NULL) return false;
   String::VisitFlat(this, string);
@@ -4125,7 +4299,8 @@
 
 template<> inline
 uint8_t FixedTypedArray<Uint8ClampedArrayTraits>::from_double(double value) {
-  if (value < 0) return 0;
+  // Handle NaNs and less than zero values which clamp to zero.
+  if (!(value > 0)) return 0;
   if (value > 0xFF) return 0xFF;
   return static_cast<uint8_t>(lrint(value));
 }
@@ -4256,6 +4431,14 @@
 }
 
 
+Handle<Map> Map::CopyInstallDescriptorsForTesting(
+    Handle<Map> map, int new_descriptor, Handle<DescriptorArray> descriptors,
+    Handle<LayoutDescriptor> layout_descriptor) {
+  return CopyInstallDescriptors(map, new_descriptor, descriptors,
+                                layout_descriptor);
+}
+
+
 int HeapObject::SizeFromMap(Map* map) {
   int instance_size = map->instance_size();
   if (instance_size != kVariableSizeSentinel) return instance_size;
@@ -4266,8 +4449,10 @@
   }
   if (instance_type == ONE_BYTE_STRING_TYPE ||
       instance_type == ONE_BYTE_INTERNALIZED_STRING_TYPE) {
+    // Strings may get concurrently truncated, hence we have to access its
+    // length synchronized.
     return SeqOneByteString::SizeFor(
-        reinterpret_cast<SeqOneByteString*>(this)->length());
+        reinterpret_cast<SeqOneByteString*>(this)->synchronized_length());
   }
   if (instance_type == BYTE_ARRAY_TYPE) {
     return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
@@ -4277,8 +4462,10 @@
   }
   if (instance_type == STRING_TYPE ||
       instance_type == INTERNALIZED_STRING_TYPE) {
+    // Strings may get concurrently truncated, hence we have to access its
+    // length synchronized.
     return SeqTwoByteString::SizeFor(
-        reinterpret_cast<SeqTwoByteString*>(this)->length());
+        reinterpret_cast<SeqTwoByteString*>(this)->synchronized_length());
   }
   if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
     return FixedDoubleArray::SizeFor(
@@ -4477,34 +4664,12 @@
 }
 
 
-void Map::set_done_inobject_slack_tracking(bool value) {
-  set_bit_field3(DoneInobjectSlackTracking::update(bit_field3(), value));
+void Map::set_counter(int value) {
+  set_bit_field3(Counter::update(bit_field3(), value));
 }
 
 
-bool Map::done_inobject_slack_tracking() {
-  return DoneInobjectSlackTracking::decode(bit_field3());
-}
-
-
-void Map::set_construction_count(int value) {
-  set_bit_field3(ConstructionCount::update(bit_field3(), value));
-}
-
-
-int Map::construction_count() {
-  return ConstructionCount::decode(bit_field3());
-}
-
-
-void Map::freeze() {
-  set_bit_field3(IsFrozen::update(bit_field3(), true));
-}
-
-
-bool Map::is_frozen() {
-  return IsFrozen::decode(bit_field3());
-}
+int Map::counter() { return Counter::decode(bit_field3()); }
 
 
 void Map::mark_unstable() {
@@ -4756,6 +4921,21 @@
 }
 
 
+bool Code::has_reloc_info_for_serialization() {
+  DCHECK_EQ(FUNCTION, kind());
+  byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
+  return FullCodeFlagsHasRelocInfoForSerialization::decode(flags);
+}
+
+
+void Code::set_has_reloc_info_for_serialization(bool value) {
+  DCHECK_EQ(FUNCTION, kind());
+  byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
+  flags = FullCodeFlagsHasRelocInfoForSerialization::update(flags, value);
+  WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
+}
+
+
 int Code::allow_osr_at_loop_nesting_level() {
   DCHECK_EQ(FUNCTION, kind());
   int fields = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
@@ -4787,13 +4967,11 @@
 
 
 int Code::builtin_index() {
-  DCHECK_EQ(BUILTIN, kind());
   return READ_INT32_FIELD(this, kKindSpecificFlags1Offset);
 }
 
 
 void Code::set_builtin_index(int index) {
-  DCHECK_EQ(BUILTIN, kind());
   WRITE_INT32_FIELD(this, kKindSpecificFlags1Offset, index);
 }
 
@@ -4890,34 +5068,6 @@
 }
 
 
-bool Code::is_weak_stub() {
-  return CanBeWeakStub() && WeakStubField::decode(
-      READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
-}
-
-
-void Code::mark_as_weak_stub() {
-  DCHECK(CanBeWeakStub());
-  int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
-  int updated = WeakStubField::update(previous, true);
-  WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
-}
-
-
-bool Code::is_invalidated_weak_stub() {
-  return is_weak_stub() && InvalidatedWeakStubField::decode(
-      READ_UINT32_FIELD(this, kKindSpecificFlags1Offset));
-}
-
-
-void Code::mark_as_invalidated_weak_stub() {
-  DCHECK(is_inline_cache_stub());
-  int previous = READ_UINT32_FIELD(this, kKindSpecificFlags1Offset);
-  int updated = InvalidatedWeakStubField::update(previous, true);
-  WRITE_UINT32_FIELD(this, kKindSpecificFlags1Offset, updated);
-}
-
-
 bool Code::is_inline_cache_stub() {
   Kind kind = this->kind();
   switch (kind) {
@@ -5064,13 +5214,6 @@
 };
 
 
-bool Code::IsWeakObjectInIC(Object* object) {
-  return object->IsMap() && Map::cast(object)->CanTransition() &&
-         FLAG_collect_maps &&
-         FLAG_weak_embedded_maps_in_ic;
-}
-
-
 Object* Map::prototype() const {
   return READ_FIELD(this, kPrototypeOffset);
 }
@@ -5099,14 +5242,47 @@
 }
 
 
-void Map::InitializeDescriptors(DescriptorArray* descriptors) {
+LayoutDescriptor* Map::layout_descriptor_gc_safe() {
+  Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
+  return LayoutDescriptor::cast_gc_safe(layout_desc);
+}
+
+
+bool Map::HasFastPointerLayout() const {
+  Object* layout_desc = READ_FIELD(this, kLayoutDecriptorOffset);
+  return LayoutDescriptor::IsFastPointerLayout(layout_desc);
+}
+
+
+void Map::UpdateDescriptors(DescriptorArray* descriptors,
+                            LayoutDescriptor* layout_desc) {
+  set_instance_descriptors(descriptors);
+  if (FLAG_unbox_double_fields) {
+    if (layout_descriptor()->IsSlowLayout()) {
+      set_layout_descriptor(layout_desc);
+    }
+    SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
+    DCHECK(visitor_id() == StaticVisitorBase::GetVisitorId(this));
+  }
+}
+
+
+void Map::InitializeDescriptors(DescriptorArray* descriptors,
+                                LayoutDescriptor* layout_desc) {
   int len = descriptors->number_of_descriptors();
   set_instance_descriptors(descriptors);
   SetNumberOfOwnDescriptors(len);
+
+  if (FLAG_unbox_double_fields) {
+    set_layout_descriptor(layout_desc);
+    SLOW_DCHECK(layout_descriptor()->IsConsistentWithMap(this));
+    set_visitor_id(StaticVisitorBase::GetVisitorId(this));
+  }
 }
 
 
 ACCESSORS(Map, instance_descriptors, DescriptorArray, kDescriptorsOffset)
+ACCESSORS(Map, layout_descriptor, LayoutDescriptor, kLayoutDecriptorOffset)
 
 
 void Map::set_bit_field3(uint32_t bits) {
@@ -5122,18 +5298,31 @@
 }
 
 
+LayoutDescriptor* Map::GetLayoutDescriptor() {
+  return FLAG_unbox_double_fields ? layout_descriptor()
+                                  : LayoutDescriptor::FastPointerLayout();
+}
+
+
 void Map::AppendDescriptor(Descriptor* desc) {
   DescriptorArray* descriptors = instance_descriptors();
   int number_of_own_descriptors = NumberOfOwnDescriptors();
   DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors);
   descriptors->Append(desc);
   SetNumberOfOwnDescriptors(number_of_own_descriptors + 1);
+
+// This function does not support appending double field descriptors and
+// it should never try to (otherwise, layout descriptor must be updated too).
+#ifdef DEBUG
+  PropertyDetails details = desc->GetDetails();
+  CHECK(details.type() != FIELD || !details.representation().IsDouble());
+#endif
 }
 
 
 Object* Map::GetBackPointer() {
   Object* object = READ_FIELD(this, kTransitionsOrBackPointerOffset);
-  if (object->IsDescriptorArray()) {
+  if (object->IsTransitionArray()) {
     return TransitionArray::cast(object)->back_pointer_storage();
   } else {
     DCHECK(object->IsMap() || object->IsUndefined());
@@ -5154,16 +5343,16 @@
 
 
 Map* Map::elements_transition_map() {
-  int index = transitions()->Search(GetHeap()->elements_transition_symbol());
+  int index =
+      transitions()->SearchSpecial(GetHeap()->elements_transition_symbol());
   return transitions()->GetTarget(index);
 }
 
 
 bool Map::CanHaveMoreTransitions() {
   if (!HasTransitionArray()) return true;
-  return FixedArray::SizeFor(transitions()->length() +
-                             TransitionArray::kTransitionSize)
-      <= Page::kMaxRegularHeapObjectSize;
+  return transitions()->number_of_transitions() <
+         TransitionArray::kMaxNumberOfTransitions;
 }
 
 
@@ -5172,8 +5361,19 @@
 }
 
 
-int Map::SearchTransition(Name* name) {
-  if (HasTransitionArray()) return transitions()->Search(name);
+int Map::SearchSpecialTransition(Symbol* name) {
+  if (HasTransitionArray()) {
+    return transitions()->SearchSpecial(name);
+  }
+  return TransitionArray::kNotFound;
+}
+
+
+int Map::SearchTransition(PropertyKind kind, Name* name,
+                          PropertyAttributes attributes) {
+  if (HasTransitionArray()) {
+    return transitions()->Search(kind, name, attributes);
+  }
   return TransitionArray::kNotFound;
 }
 
@@ -5191,12 +5391,10 @@
     Handle<Map> map, Handle<FixedArray> proto_transitions) {
   EnsureHasTransitionArray(map);
   int old_number_of_transitions = map->NumberOfProtoTransitions();
-#ifdef DEBUG
-  if (map->HasPrototypeTransitions()) {
+  if (Heap::ShouldZapGarbage() && map->HasPrototypeTransitions()) {
     DCHECK(map->GetPrototypeTransitions() != *proto_transitions);
     map->ZapPrototypeTransitions();
   }
-#endif
   map->transitions()->SetPrototypeTransitions(*proto_transitions);
   map->SetNumberOfProtoTransitions(old_number_of_transitions);
 }
@@ -5226,9 +5424,17 @@
       Map* target = transitions()->GetTarget(i);
       if (target->instance_descriptors() == instance_descriptors()) {
         Name* key = transitions()->GetKey(i);
-        int new_target_index = transition_array->Search(key);
-        DCHECK(new_target_index != TransitionArray::kNotFound);
-        DCHECK(transition_array->GetTarget(new_target_index) == target);
+        int new_target_index;
+        if (TransitionArray::IsSpecialTransition(key)) {
+          new_target_index = transition_array->SearchSpecial(Symbol::cast(key));
+        } else {
+          PropertyDetails details =
+              TransitionArray::GetTargetDetails(key, target);
+          new_target_index = transition_array->Search(details.kind(), key,
+                                                      details.attributes());
+        }
+        DCHECK_NE(TransitionArray::kNotFound, new_target_index);
+        DCHECK_EQ(target, transition_array->GetTarget(new_target_index));
       }
     }
 #endif
@@ -5273,7 +5479,6 @@
 
 ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
 ACCESSORS(GlobalObject, native_context, Context, kNativeContextOffset)
-ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
 ACCESSORS(GlobalObject, global_proxy, JSObject, kGlobalProxyOffset)
 
 ACCESSORS(JSGlobalProxy, native_context, Object, kNativeContextOffset)
@@ -5309,6 +5514,10 @@
 ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
 ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
 ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
+SMI_ACCESSORS(InterceptorInfo, flags, kFlagsOffset)
+BOOL_ACCESSORS(InterceptorInfo, flags, can_intercept_symbols,
+               kCanInterceptSymbolsBit)
+BOOL_ACCESSORS(InterceptorInfo, flags, all_can_read, kAllCanReadBit)
 
 ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
 ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
@@ -5361,7 +5570,7 @@
 ACCESSORS_TO_SMI(Script, line_offset, kLineOffsetOffset)
 ACCESSORS_TO_SMI(Script, column_offset, kColumnOffsetOffset)
 ACCESSORS(Script, context_data, Object, kContextOffset)
-ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
+ACCESSORS(Script, wrapper, HeapObject, kWrapperOffset)
 ACCESSORS_TO_SMI(Script, type, kTypeOffset)
 ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
 ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
@@ -5406,6 +5615,9 @@
 ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
 ACCESSORS(SharedFunctionInfo, feedback_vector, TypeFeedbackVector,
           kFeedbackVectorOffset)
+#if TRACE_MAPS
+SMI_ACCESSORS(SharedFunctionInfo, unique_id, kUniqueIdOffset)
+#endif
 ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
           kInstanceClassNameOffset)
 ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
@@ -5431,9 +5643,7 @@
 BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
                kIsTopLevelBit)
 
-BOOL_ACCESSORS(SharedFunctionInfo,
-               compiler_hints,
-               allows_lazy_compilation,
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, allows_lazy_compilation,
                kAllowLazyCompilation)
 BOOL_ACCESSORS(SharedFunctionInfo,
                compiler_hints,
@@ -5448,6 +5658,7 @@
                has_duplicate_parameters,
                kHasDuplicateParameters)
 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, asm_function, kIsAsmFunction)
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, deserialized, kDeserialized)
 
 
 #if V8_HOST_ARCH_32_BIT
@@ -5472,25 +5683,30 @@
 
 #else
 
-#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset)             \
-  STATIC_ASSERT(holder::offset % kPointerSize == 0);              \
-  int holder::name() const {                                      \
-    int value = READ_INT_FIELD(this, offset);                     \
-    DCHECK(kHeapObjectTag == 1);                                  \
-    DCHECK((value & kHeapObjectTag) == 0);                        \
-    return value >> 1;                                            \
-  }                                                               \
-  void holder::set_##name(int value) {                            \
-    DCHECK(kHeapObjectTag == 1);                                  \
-    DCHECK((value & 0xC0000000) == 0xC0000000 ||                  \
-           (value & 0xC0000000) == 0x0);                          \
-    WRITE_INT_FIELD(this,                                         \
-                    offset,                                       \
-                    (value << 1) & ~kHeapObjectTag);              \
+#if V8_TARGET_LITTLE_ENDIAN
+#define PSEUDO_SMI_LO_ALIGN 0
+#define PSEUDO_SMI_HI_ALIGN kIntSize
+#else
+#define PSEUDO_SMI_LO_ALIGN kIntSize
+#define PSEUDO_SMI_HI_ALIGN 0
+#endif
+
+#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset)                          \
+  STATIC_ASSERT(holder::offset % kPointerSize == PSEUDO_SMI_LO_ALIGN);         \
+  int holder::name() const {                                                   \
+    int value = READ_INT_FIELD(this, offset);                                  \
+    DCHECK(kHeapObjectTag == 1);                                               \
+    DCHECK((value & kHeapObjectTag) == 0);                                     \
+    return value >> 1;                                                         \
+  }                                                                            \
+  void holder::set_##name(int value) {                                         \
+    DCHECK(kHeapObjectTag == 1);                                               \
+    DCHECK((value & 0xC0000000) == 0xC0000000 || (value & 0xC0000000) == 0x0); \
+    WRITE_INT_FIELD(this, offset, (value << 1) & ~kHeapObjectTag);             \
   }
 
-#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset)             \
-  STATIC_ASSERT(holder::offset % kPointerSize == kIntSize);       \
+#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset)                  \
+  STATIC_ASSERT(holder::offset % kPointerSize == PSEUDO_SMI_HI_ALIGN); \
   INT_ACCESSORS(holder, name, offset)
 
 
@@ -5577,6 +5793,10 @@
 }
 
 
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, uses_super_property,
+               kUsesSuperProperty)
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, uses_super_constructor_call,
+               kUsesSuperConstructorCall)
 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, inline_builtin,
                kInlineBuiltin)
@@ -5592,9 +5812,12 @@
 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_generator, kIsGenerator)
 BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_concise_method,
                kIsConciseMethod)
+BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_default_constructor,
+               kIsDefaultConstructor)
 
 ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
 ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
+ACCESSORS(CodeCache, weak_cell_cache, Object, kWeakCellCacheOffset)
 
 ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
 
@@ -5747,10 +5970,9 @@
 }
 
 
-BailoutReason SharedFunctionInfo::DisableOptimizationReason() {
-  BailoutReason reason = static_cast<BailoutReason>(
+BailoutReason SharedFunctionInfo::disable_optimization_reason() {
+  return static_cast<BailoutReason>(
       DisabledOptimizationReasonBits::decode(opt_count_and_bailout_reason()));
-  return reason;
 }
 
 
@@ -5831,7 +6053,7 @@
 
 bool JSFunction::IsInobjectSlackTrackingInProgress() {
   return has_initial_map() &&
-      initial_map()->construction_count() != JSFunction::kNoSlackTracking;
+         initial_map()->counter() >= Map::kSlackTrackingCounterEnd;
 }
 
 
@@ -6252,6 +6474,16 @@
 }
 
 
+bool JSArrayBuffer::is_neuterable() {
+  return BooleanBit::get(flag(), kIsNeuterableBit);
+}
+
+
+void JSArrayBuffer::set_is_neuterable(bool value) {
+  set_flag(BooleanBit::set(flag(), kIsNeuterableBit, value));
+}
+
+
 ACCESSORS(JSArrayBuffer, weak_next, Object, kWeakNextOffset)
 ACCESSORS(JSArrayBuffer, weak_first_view, Object, kWeakFirstViewOffset)
 
@@ -6297,7 +6529,7 @@
 String* JSRegExp::Pattern() {
   DCHECK(this->data()->IsFixedArray());
   Object* data = this->data();
-  String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
+  String* pattern = String::cast(FixedArray::cast(data)->get(kSourceIndex));
   return pattern;
 }
 
@@ -6317,7 +6549,7 @@
 
 ElementsKind JSObject::GetElementsKind() {
   ElementsKind kind = map()->elements_kind();
-#if DEBUG
+#if VERIFY_HEAP && DEBUG
   FixedArrayBase* fixed_array =
       reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
 
@@ -6509,6 +6741,30 @@
 }
 
 
+uint32_t StringHasher::ComputeRunningHash(uint32_t running_hash,
+                                          const uc16* chars, int length) {
+  DCHECK_NOT_NULL(chars);
+  DCHECK(length >= 0);
+  for (int i = 0; i < length; ++i) {
+    running_hash = AddCharacterCore(running_hash, *chars++);
+  }
+  return running_hash;
+}
+
+
+uint32_t StringHasher::ComputeRunningHashOneByte(uint32_t running_hash,
+                                                 const char* chars,
+                                                 int length) {
+  DCHECK_NOT_NULL(chars);
+  DCHECK(length >= 0);
+  for (int i = 0; i < length; ++i) {
+    uint16_t c = static_cast<uint16_t>(*chars++);
+    running_hash = AddCharacterCore(running_hash, c);
+  }
+  return running_hash;
+}
+
+
 void StringHasher::AddCharacter(uint16_t c) {
   // Use the Jenkins one-at-a-time hash function to update the hash
   // for the given character.
@@ -6574,14 +6830,8 @@
   // Nothing to do.
   if (hasher.has_trivial_hash()) return hasher.GetHashField();
   ConsString* cons_string = String::VisitFlat(&hasher, string);
-  // The string was flat.
-  if (cons_string == NULL) return hasher.GetHashField();
-  // This is a ConsString, iterate across it.
-  ConsStringIteratorOp op(cons_string);
-  int offset;
-  while (NULL != (string = op.Next(&offset))) {
-    String::VisitFlat(&hasher, string, offset);
-  }
+  if (cons_string == nullptr) return hasher.GetHashField();
+  hasher.VisitConsString(cons_string);
   return hasher.GetHashField();
 }
 
@@ -6619,7 +6869,7 @@
   DCHECK(SlowEquals(canonical));
   DCHECK(canonical->IsInternalizedString());
   DCHECK(canonical->HasHashCode());
-  WRITE_FIELD(this, kHashFieldOffset, canonical);
+  WRITE_FIELD(this, kHashFieldSlot, canonical);
   // Setting the hash field to a tagged value sets the LSB, causing the hash
   // code to be interpreted as uninitialized.  We use this fact to recognize
   // that we have a forwarded string.
@@ -6630,7 +6880,7 @@
 String* String::GetForwardedInternalizedString() {
   DCHECK(IsInternalizedString());
   if (HasHashCode()) return this;
-  String* canonical = String::cast(READ_FIELD(this, kHashFieldOffset));
+  String* canonical = String::cast(READ_FIELD(this, kHashFieldSlot));
   DCHECK(canonical->IsInternalizedString());
   DCHECK(SlowEquals(canonical));
   DCHECK(canonical->HasHashCode());
@@ -6638,11 +6888,6 @@
 }
 
 
-Object* JSReceiver::GetConstructor() {
-  return map()->constructor();
-}
-
-
 Maybe<bool> JSReceiver::HasProperty(Handle<JSReceiver> object,
                                     Handle<Name> name) {
   if (object->IsJSProxy()) {
@@ -6790,7 +7035,10 @@
 
 
 void ExecutableAccessorInfo::clear_setter() {
-  set_setter(GetIsolate()->heap()->undefined_value(), SKIP_WRITE_BARRIER);
+  auto foreign = GetIsolate()->factory()->NewForeign(
+      reinterpret_cast<v8::internal::Address>(
+          reinterpret_cast<intptr_t>(nullptr)));
+  set_setter(*foreign);
 }
 
 
@@ -6880,9 +7128,9 @@
 }
 
 
-void NameDictionary::DoGenerateNewEnumerationIndices(
+Handle<FixedArray> NameDictionary::DoGenerateNewEnumerationIndices(
     Handle<NameDictionary> dictionary) {
-  DerivedDictionary::GenerateNewEnumerationIndices(dictionary);
+  return DerivedDictionary::GenerateNewEnumerationIndices(dictionary);
 }
 
 
@@ -6952,6 +7200,14 @@
 }
 
 
+int Map::SlackForArraySize(int old_size, int size_limit) {
+  const int max_slack = size_limit - old_size;
+  CHECK(max_slack >= 0);
+  if (old_size < 4) return Min(max_slack, 1);
+  return Min(max_slack, old_size / 2);
+}
+
+
 void JSArray::EnsureSize(Handle<JSArray> array, int required_size) {
   DCHECK(array->HasFastSmiOrObjectElements());
   Handle<FixedArray> elts = handle(FixedArray::cast(array->elements()));
@@ -7158,12 +7414,36 @@
 }
 
 
+static inline void IterateBodyUsingLayoutDescriptor(HeapObject* object,
+                                                    int start_offset,
+                                                    int end_offset,
+                                                    ObjectVisitor* v) {
+  DCHECK(FLAG_unbox_double_fields);
+  DCHECK(IsAligned(start_offset, kPointerSize) &&
+         IsAligned(end_offset, kPointerSize));
+
+  LayoutDescriptorHelper helper(object->map());
+  DCHECK(!helper.all_fields_tagged());
+
+  for (int offset = start_offset; offset < end_offset; offset += kPointerSize) {
+    // Visit all tagged fields.
+    if (helper.IsTagged(offset)) {
+      v->VisitPointer(HeapObject::RawField(object, offset));
+    }
+  }
+}
+
+
 template<int start_offset, int end_offset, int size>
 void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
     HeapObject* obj,
     ObjectVisitor* v) {
+  if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) {
     v->VisitPointers(HeapObject::RawField(obj, start_offset),
                      HeapObject::RawField(obj, end_offset));
+  } else {
+    IterateBodyUsingLayoutDescriptor(obj, start_offset, end_offset, v);
+  }
 }
 
 
@@ -7171,8 +7451,12 @@
 void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
                                                        int object_size,
                                                        ObjectVisitor* v) {
-  v->VisitPointers(HeapObject::RawField(obj, start_offset),
-                   HeapObject::RawField(obj, object_size));
+  if (!FLAG_unbox_double_fields || obj->map()->HasFastPointerLayout()) {
+    v->VisitPointers(HeapObject::RawField(obj, start_offset),
+                     HeapObject::RawField(obj, object_size));
+  } else {
+    IterateBodyUsingLayoutDescriptor(obj, start_offset, object_size, v);
+  }
 }
 
 
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index d709a20..9805490 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -18,11 +18,11 @@
 void Object::Print() {
   OFStream os(stdout);
   this->Print(os);
-  os << flush;
+  os << std::flush;
 }
 
 
-void Object::Print(OStream& os) {  // NOLINT
+void Object::Print(std::ostream& os) {  // NOLINT
   if (IsSmi()) {
     Smi::cast(this)->SmiPrint(os);
   } else {
@@ -31,12 +31,12 @@
 }
 
 
-void HeapObject::PrintHeader(OStream& os, const char* id) {  // NOLINT
+void HeapObject::PrintHeader(std::ostream& os, const char* id) {  // NOLINT
   os << "" << reinterpret_cast<void*>(this) << ": [" << id << "]\n";
 }
 
 
-void HeapObject::HeapObjectPrint(OStream& os) {  // NOLINT
+void HeapObject::HeapObjectPrint(std::ostream& os) {  // NOLINT
   InstanceType instance_type = map()->instance_type();
 
   HandleScope scope(GetIsolate());
@@ -169,6 +169,9 @@
     case PROPERTY_CELL_TYPE:
       PropertyCell::cast(this)->PropertyCellPrint(os);
       break;
+    case WEAK_CELL_TYPE:
+      WeakCell::cast(this)->WeakCellPrint(os);
+      break;
     case JS_ARRAY_BUFFER_TYPE:
       JSArrayBuffer::cast(this)->JSArrayBufferPrint(os);
       break;
@@ -193,19 +196,19 @@
 }
 
 
-void ByteArray::ByteArrayPrint(OStream& os) {  // NOLINT
+void ByteArray::ByteArrayPrint(std::ostream& os) {  // NOLINT
   os << "byte array, data starts at " << GetDataStartAddress();
 }
 
 
-void FreeSpace::FreeSpacePrint(OStream& os) {  // NOLINT
+void FreeSpace::FreeSpacePrint(std::ostream& os) {  // NOLINT
   os << "free space, size " << Size();
 }
 
 
-#define EXTERNAL_ARRAY_PRINTER(Type, type, TYPE, ctype, size)           \
-  void External##Type##Array::External##Type##ArrayPrint(OStream& os) { \
-    os << "external " #type " array";                                   \
+#define EXTERNAL_ARRAY_PRINTER(Type, type, TYPE, ctype, size)                \
+  void External##Type##Array::External##Type##ArrayPrint(std::ostream& os) { \
+    os << "external " #type " array";                                        \
   }
 
 TYPED_ARRAYS(EXTERNAL_ARRAY_PRINTER)
@@ -214,12 +217,13 @@
 
 
 template <class Traits>
-void FixedTypedArray<Traits>::FixedTypedArrayPrint(OStream& os) {  // NOLINT
+void FixedTypedArray<Traits>::FixedTypedArrayPrint(
+    std::ostream& os) {  // NOLINT
   os << "fixed " << Traits::Designator();
 }
 
 
-void JSObject::PrintProperties(OStream& os) {  // NOLINT
+void JSObject::PrintProperties(std::ostream& os) {  // NOLINT
   if (HasFastProperties()) {
     DescriptorArray* descs = map()->instance_descriptors();
     for (int i = 0; i < map()->NumberOfOwnDescriptors(); i++) {
@@ -229,18 +233,24 @@
       switch (descs->GetType(i)) {
         case FIELD: {
           FieldIndex index = FieldIndex::ForDescriptor(map(), i);
-          os << Brief(RawFastPropertyAt(index)) << " (field at offset "
-             << index.property_index() << ")\n";
+          if (IsUnboxedDoubleField(index)) {
+            os << "<unboxed double> " << RawFastDoublePropertyAt(index);
+          } else {
+            os << Brief(RawFastPropertyAt(index));
+          }
+          os << " (field at offset " << index.property_index() << ")\n";
+          break;
+        }
+        case ACCESSOR_FIELD: {
+          FieldIndex index = FieldIndex::ForDescriptor(map(), i);
+          os << " (accessor at offset " << index.property_index() << ")\n";
           break;
         }
         case CONSTANT:
           os << Brief(descs->GetConstant(i)) << " (constant)\n";
           break;
         case CALLBACKS:
-          os << Brief(descs->GetCallbacksObject(i)) << " (callback)\n";
-          break;
-        case NORMAL:  // only in slow mode
-          UNREACHABLE();
+          os << Brief(descs->GetCallbacksObject(i)) << " (callbacks)\n";
           break;
       }
     }
@@ -251,7 +261,7 @@
 
 
 template <class T>
-static void DoPrintElements(OStream& os, Object* object) {  // NOLINT
+static void DoPrintElements(std::ostream& os, Object* object) {  // NOLINT
   T* p = T::cast(object);
   for (int i = 0; i < p->length(); i++) {
     os << "   " << i << ": " << p->get_scalar(i) << "\n";
@@ -259,7 +269,7 @@
 }
 
 
-void JSObject::PrintElements(OStream& os) {  // NOLINT
+void JSObject::PrintElements(std::ostream& os) {  // NOLINT
   // Don't call GetElementsKind, its validation code can cause the printer to
   // fail when debugging.
   switch (map()->elements_kind()) {
@@ -341,45 +351,7 @@
 }
 
 
-void JSObject::PrintTransitions(OStream& os) {  // NOLINT
-  if (!map()->HasTransitionArray()) return;
-  TransitionArray* transitions = map()->transitions();
-  for (int i = 0; i < transitions->number_of_transitions(); i++) {
-    Name* key = transitions->GetKey(i);
-    os << "   ";
-    key->NamePrint(os);
-    os << ": ";
-    if (key == GetHeap()->frozen_symbol()) {
-      os << " (transition to frozen)\n";
-    } else if (key == GetHeap()->elements_transition_symbol()) {
-      os << " (transition to "
-         << ElementsKindToString(transitions->GetTarget(i)->elements_kind())
-         << ")\n";
-    } else if (key == GetHeap()->observed_symbol()) {
-      os << " (transition to Object.observe)\n";
-    } else {
-      switch (transitions->GetTargetDetails(i).type()) {
-        case FIELD: {
-          os << " (transition to field)\n";
-          break;
-        }
-        case CONSTANT:
-          os << " (transition to constant)\n";
-          break;
-        case CALLBACKS:
-          os << " (transition to callback)\n";
-          break;
-        // Values below are never in the target descriptor array.
-        case NORMAL:
-          UNREACHABLE();
-          break;
-      }
-    }
-  }
-}
-
-
-void JSObject::JSObjectPrint(OStream& os) {  // NOLINT
+void JSObject::JSObjectPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSObject");
   // Don't call GetElementsKind, its validation code can cause the printer to
   // fail when debugging.
@@ -395,7 +367,7 @@
 }
 
 
-void JSModule::JSModulePrint(OStream& os) {  // NOLINT
+void JSModule::JSModulePrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSModule");
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n"
      << " - context = ";
@@ -419,17 +391,20 @@
 }
 
 
-void Symbol::SymbolPrint(OStream& os) {  // NOLINT
+void Symbol::SymbolPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "Symbol");
   os << " - hash: " << Hash();
   os << "\n - name: " << Brief(name());
+  if (name()->IsUndefined()) {
+    os << " (" << PrivateSymbolToName() << ")";
+  }
   os << "\n - private: " << is_private();
   os << "\n - own: " << is_own();
   os << "\n";
 }
 
 
-void Map::MapPrint(OStream& os) {  // NOLINT
+void Map::MapPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "Map");
   os << " - type: " << TypeToString(instance_type()) << "\n";
   os << " - instance size: " << instance_size() << "\n";
@@ -438,21 +413,23 @@
   os << "\n - pre-allocated property fields: "
      << pre_allocated_property_fields() << "\n";
   os << " - unused property fields: " << unused_property_fields() << "\n";
+  if (is_deprecated()) os << " - deprecated_map\n";
+  if (is_dictionary_map()) os << " - dictionary_map\n";
+  if (is_prototype_map()) os << " - prototype_map\n";
   if (is_hidden_prototype()) os << " - hidden_prototype\n";
   if (has_named_interceptor()) os << " - named_interceptor\n";
   if (has_indexed_interceptor()) os << " - indexed_interceptor\n";
   if (is_undetectable()) os << " - undetectable\n";
   if (has_instance_call_handler()) os << " - instance_call_handler\n";
   if (is_access_check_needed()) os << " - access_check_needed\n";
-  if (is_frozen()) {
-    os << " - frozen\n";
-  } else if (!is_extensible()) {
-    os << " - sealed\n";
-  }
+  if (!is_extensible()) os << " - non-extensible\n";
   os << " - back pointer: " << Brief(GetBackPointer());
   os << "\n - instance descriptors " << (owns_descriptors() ? "(own) " : "")
      << "#" << NumberOfOwnDescriptors() << ": "
      << Brief(instance_descriptors());
+  if (FLAG_unbox_double_fields) {
+    os << "\n - layout descriptor: " << Brief(layout_descriptor());
+  }
   if (HasTransitionArray()) {
     os << "\n - transitions: " << Brief(transitions());
   }
@@ -464,20 +441,21 @@
 }
 
 
-void CodeCache::CodeCachePrint(OStream& os) {  // NOLINT
+void CodeCache::CodeCachePrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "CodeCache");
   os << "\n - default_cache: " << Brief(default_cache());
   os << "\n - normal_type_cache: " << Brief(normal_type_cache());
 }
 
 
-void PolymorphicCodeCache::PolymorphicCodeCachePrint(OStream& os) {  // NOLINT
+void PolymorphicCodeCache::PolymorphicCodeCachePrint(
+    std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "PolymorphicCodeCache");
   os << "\n - cache: " << Brief(cache());
 }
 
 
-void TypeFeedbackInfo::TypeFeedbackInfoPrint(OStream& os) {  // NOLINT
+void TypeFeedbackInfo::TypeFeedbackInfoPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "TypeFeedbackInfo");
   os << " - ic_total_count: " << ic_total_count()
      << ", ic_with_type_info_count: " << ic_with_type_info_count()
@@ -485,13 +463,14 @@
 }
 
 
-void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(OStream& os) {  // NOLINT
+void AliasedArgumentsEntry::AliasedArgumentsEntryPrint(
+    std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "AliasedArgumentsEntry");
   os << "\n - aliased_context_slot: " << aliased_context_slot();
 }
 
 
-void FixedArray::FixedArrayPrint(OStream& os) {  // NOLINT
+void FixedArray::FixedArrayPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "FixedArray");
   os << " - length: " << length();
   for (int i = 0; i < length(); i++) {
@@ -501,7 +480,7 @@
 }
 
 
-void FixedDoubleArray::FixedDoubleArrayPrint(OStream& os) {  // NOLINT
+void FixedDoubleArray::FixedDoubleArrayPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "FixedDoubleArray");
   os << " - length: " << length();
   for (int i = 0; i < length(); i++) {
@@ -516,7 +495,7 @@
 }
 
 
-void ConstantPoolArray::ConstantPoolArrayPrint(OStream& os) {  // NOLINT
+void ConstantPoolArray::ConstantPoolArrayPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "ConstantPoolArray");
   os << " - length: " << length();
   for (int i = 0; i <= last_index(INT32, SMALL_SECTION); i++) {
@@ -553,13 +532,13 @@
 }
 
 
-void JSValue::JSValuePrint(OStream& os) {  // NOLINT
+void JSValue::JSValuePrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "ValueObject");
   value()->Print(os);
 }
 
 
-void JSMessageObject::JSMessageObjectPrint(OStream& os) {  // NOLINT
+void JSMessageObject::JSMessageObjectPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSMessageObject");
   os << " - type: " << Brief(type());
   os << "\n - arguments: " << Brief(arguments());
@@ -571,7 +550,7 @@
 }
 
 
-void String::StringPrint(OStream& os) {  // NOLINT
+void String::StringPrint(std::ostream& os) {  // NOLINT
   if (StringShape(this).IsInternalized()) {
     os << "#";
   } else if (StringShape(this).IsCons()) {
@@ -598,26 +577,14 @@
 }
 
 
-void Name::NamePrint(OStream& os) {  // NOLINT
-  if (IsString())
+void Name::NamePrint(std::ostream& os) {  // NOLINT
+  if (IsString()) {
     String::cast(this)->StringPrint(os);
-  else
+  } else if (IsSymbol()) {
+    Symbol::cast(this)->name()->Print(os);
+  } else {
     os << Brief(this);
-}
-
-
-// This method is only meant to be called from gdb for debugging purposes.
-// Since the string can also be in two-byte encoding, non-Latin1 characters
-// will be ignored in the output.
-char* String::ToAsciiArray() {
-  // Static so that subsequent calls frees previously allocated space.
-  // This also means that previous results will be overwritten.
-  static char* buffer = NULL;
-  if (buffer != NULL) free(buffer);
-  buffer = new char[length()+1];
-  WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length());
-  buffer[length()] = 0;
-  return buffer;
+  }
 }
 
 
@@ -626,7 +593,7 @@
 };
 
 
-void JSDate::JSDatePrint(OStream& os) {  // NOLINT
+void JSDate::JSDatePrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSDate");
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
   os << " - value = ";
@@ -650,7 +617,7 @@
 }
 
 
-void JSProxy::JSProxyPrint(OStream& os) {  // NOLINT
+void JSProxy::JSProxyPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSProxy");
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
   os << " - handler = ";
@@ -661,7 +628,7 @@
 }
 
 
-void JSFunctionProxy::JSFunctionProxyPrint(OStream& os) {  // NOLINT
+void JSFunctionProxy::JSFunctionProxyPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSFunctionProxy");
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
   os << " - handler = ";
@@ -674,7 +641,7 @@
 }
 
 
-void JSSet::JSSetPrint(OStream& os) {  // NOLINT
+void JSSet::JSSetPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSSet");
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
   os << " - table = " << Brief(table());
@@ -682,7 +649,7 @@
 }
 
 
-void JSMap::JSMapPrint(OStream& os) {  // NOLINT
+void JSMap::JSMapPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSMap");
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
   os << " - table = " << Brief(table());
@@ -691,8 +658,9 @@
 
 
 template <class Derived, class TableType>
-void OrderedHashTableIterator<
-    Derived, TableType>::OrderedHashTableIteratorPrint(OStream& os) {  // NOLINT
+void
+OrderedHashTableIterator<Derived, TableType>::OrderedHashTableIteratorPrint(
+    std::ostream& os) {  // NOLINT
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
   os << " - table = " << Brief(table());
   os << "\n - index = " << Brief(index());
@@ -703,27 +671,27 @@
 
 template void OrderedHashTableIterator<
     JSSetIterator,
-    OrderedHashSet>::OrderedHashTableIteratorPrint(OStream& os);  // NOLINT
+    OrderedHashSet>::OrderedHashTableIteratorPrint(std::ostream& os);  // NOLINT
 
 
 template void OrderedHashTableIterator<
     JSMapIterator,
-    OrderedHashMap>::OrderedHashTableIteratorPrint(OStream& os);  // NOLINT
+    OrderedHashMap>::OrderedHashTableIteratorPrint(std::ostream& os);  // NOLINT
 
 
-void JSSetIterator::JSSetIteratorPrint(OStream& os) {  // NOLINT
+void JSSetIterator::JSSetIteratorPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSSetIterator");
   OrderedHashTableIteratorPrint(os);
 }
 
 
-void JSMapIterator::JSMapIteratorPrint(OStream& os) {  // NOLINT
+void JSMapIterator::JSMapIteratorPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSMapIterator");
   OrderedHashTableIteratorPrint(os);
 }
 
 
-void JSWeakMap::JSWeakMapPrint(OStream& os) {  // NOLINT
+void JSWeakMap::JSWeakMapPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSWeakMap");
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
   os << " - table = " << Brief(table());
@@ -731,7 +699,7 @@
 }
 
 
-void JSWeakSet::JSWeakSetPrint(OStream& os) {  // NOLINT
+void JSWeakSet::JSWeakSetPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSWeakSet");
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
   os << " - table = " << Brief(table());
@@ -739,7 +707,7 @@
 }
 
 
-void JSArrayBuffer::JSArrayBufferPrint(OStream& os) {  // NOLINT
+void JSArrayBuffer::JSArrayBufferPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSArrayBuffer");
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
   os << " - backing_store = " << backing_store() << "\n";
@@ -748,7 +716,7 @@
 }
 
 
-void JSTypedArray::JSTypedArrayPrint(OStream& os) {  // NOLINT
+void JSTypedArray::JSTypedArrayPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSTypedArray");
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
   os << " - buffer = " << Brief(buffer());
@@ -760,7 +728,7 @@
 }
 
 
-void JSDataView::JSDataViewPrint(OStream& os) {  // NOLINT
+void JSDataView::JSDataViewPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "JSDataView");
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
   os << " - buffer =" << Brief(buffer());
@@ -770,7 +738,7 @@
 }
 
 
-void JSFunction::JSFunctionPrint(OStream& os) {  // NOLINT
+void JSFunction::JSFunctionPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "Function");
   os << " - map = " << reinterpret_cast<void*>(map()) << "\n";
   os << " - initial_map = ";
@@ -791,7 +759,7 @@
 }
 
 
-void SharedFunctionInfo::SharedFunctionInfoPrint(OStream& os) {  // NOLINT
+void SharedFunctionInfo::SharedFunctionInfoPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "SharedFunctionInfo");
   os << " - name: " << Brief(name());
   os << "\n - expected_nof_properties: " << expected_nof_properties();
@@ -826,7 +794,7 @@
 }
 
 
-void JSGlobalProxy::JSGlobalProxyPrint(OStream& os) {  // NOLINT
+void JSGlobalProxy::JSGlobalProxyPrint(std::ostream& os) {  // NOLINT
   os << "global_proxy ";
   JSObjectPrint(os);
   os << "native context : " << Brief(native_context());
@@ -834,7 +802,7 @@
 }
 
 
-void JSGlobalObject::JSGlobalObjectPrint(OStream& os) {  // NOLINT
+void JSGlobalObject::JSGlobalObjectPrint(std::ostream& os) {  // NOLINT
   os << "global ";
   JSObjectPrint(os);
   os << "native context : " << Brief(native_context());
@@ -842,23 +810,33 @@
 }
 
 
-void JSBuiltinsObject::JSBuiltinsObjectPrint(OStream& os) {  // NOLINT
+void JSBuiltinsObject::JSBuiltinsObjectPrint(std::ostream& os) {  // NOLINT
   os << "builtins ";
   JSObjectPrint(os);
 }
 
 
-void Cell::CellPrint(OStream& os) {  // NOLINT
+void Cell::CellPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "Cell");
 }
 
 
-void PropertyCell::PropertyCellPrint(OStream& os) {  // NOLINT
+void PropertyCell::PropertyCellPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "PropertyCell");
 }
 
 
-void Code::CodePrint(OStream& os) {  // NOLINT
+void WeakCell::WeakCellPrint(std::ostream& os) {  // NOLINT
+  HeapObject::PrintHeader(os, "WeakCell");
+  if (cleared()) {
+    os << "\n - cleared";
+  } else {
+    os << "\n - value: " << Brief(value());
+  }
+}
+
+
+void Code::CodePrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "Code");
 #ifdef ENABLE_DISASSEMBLER
   if (FLAG_use_verbose_printer) {
@@ -868,13 +846,13 @@
 }
 
 
-void Foreign::ForeignPrint(OStream& os) {  // NOLINT
+void Foreign::ForeignPrint(std::ostream& os) {  // NOLINT
   os << "foreign address : " << foreign_address();
 }
 
 
 void ExecutableAccessorInfo::ExecutableAccessorInfoPrint(
-    OStream& os) {  // NOLINT
+    std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "ExecutableAccessorInfo");
   os << "\n - name: " << Brief(name());
   os << "\n - flag: " << Brief(flag());
@@ -885,7 +863,8 @@
 }
 
 
-void DeclaredAccessorInfo::DeclaredAccessorInfoPrint(OStream& os) {  // NOLINT
+void DeclaredAccessorInfo::DeclaredAccessorInfoPrint(
+    std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "DeclaredAccessorInfo");
   os << "\n - name: " << Brief(name());
   os << "\n - flag: " << Brief(flag());
@@ -895,21 +874,21 @@
 
 
 void DeclaredAccessorDescriptor::DeclaredAccessorDescriptorPrint(
-    OStream& os) {  // NOLINT
+    std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "DeclaredAccessorDescriptor");
   os << "\n - internal field: " << Brief(serialized_data());
   os << "\n";
 }
 
 
-void Box::BoxPrint(OStream& os) {  // NOLINT
+void Box::BoxPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "Box");
   os << "\n - value: " << Brief(value());
   os << "\n";
 }
 
 
-void AccessorPair::AccessorPairPrint(OStream& os) {  // NOLINT
+void AccessorPair::AccessorPairPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "AccessorPair");
   os << "\n - getter: " << Brief(getter());
   os << "\n - setter: " << Brief(setter());
@@ -917,7 +896,7 @@
 }
 
 
-void AccessCheckInfo::AccessCheckInfoPrint(OStream& os) {  // NOLINT
+void AccessCheckInfo::AccessCheckInfoPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "AccessCheckInfo");
   os << "\n - named_callback: " << Brief(named_callback());
   os << "\n - indexed_callback: " << Brief(indexed_callback());
@@ -926,7 +905,7 @@
 }
 
 
-void InterceptorInfo::InterceptorInfoPrint(OStream& os) {  // NOLINT
+void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "InterceptorInfo");
   os << "\n - getter: " << Brief(getter());
   os << "\n - setter: " << Brief(setter());
@@ -938,7 +917,7 @@
 }
 
 
-void CallHandlerInfo::CallHandlerInfoPrint(OStream& os) {  // NOLINT
+void CallHandlerInfo::CallHandlerInfoPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "CallHandlerInfo");
   os << "\n - callback: " << Brief(callback());
   os << "\n - data: " << Brief(data());
@@ -946,7 +925,8 @@
 }
 
 
-void FunctionTemplateInfo::FunctionTemplateInfoPrint(OStream& os) {  // NOLINT
+void FunctionTemplateInfo::FunctionTemplateInfoPrint(
+    std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "FunctionTemplateInfo");
   os << "\n - class name: " << Brief(class_name());
   os << "\n - tag: " << Brief(tag());
@@ -968,7 +948,7 @@
 }
 
 
-void ObjectTemplateInfo::ObjectTemplateInfoPrint(OStream& os) {  // NOLINT
+void ObjectTemplateInfo::ObjectTemplateInfoPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "ObjectTemplateInfo");
   os << " - tag: " << Brief(tag());
   os << "\n - property_list: " << Brief(property_list());
@@ -979,7 +959,7 @@
 }
 
 
-void SignatureInfo::SignatureInfoPrint(OStream& os) {  // NOLINT
+void SignatureInfo::SignatureInfoPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "SignatureInfo");
   os << "\n - receiver: " << Brief(receiver());
   os << "\n - args: " << Brief(args());
@@ -987,14 +967,14 @@
 }
 
 
-void TypeSwitchInfo::TypeSwitchInfoPrint(OStream& os) {  // NOLINT
+void TypeSwitchInfo::TypeSwitchInfoPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "TypeSwitchInfo");
   os << "\n - types: " << Brief(types());
   os << "\n";
 }
 
 
-void AllocationSite::AllocationSitePrint(OStream& os) {  // NOLINT
+void AllocationSite::AllocationSitePrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "AllocationSite");
   os << " - weak_next: " << Brief(weak_next());
   os << "\n - dependent code: " << Brief(dependent_code());
@@ -1018,7 +998,7 @@
 }
 
 
-void AllocationMemento::AllocationMementoPrint(OStream& os) {  // NOLINT
+void AllocationMemento::AllocationMementoPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "AllocationMemento");
   os << " - allocation site: ";
   if (IsValid()) {
@@ -1029,7 +1009,7 @@
 }
 
 
-void Script::ScriptPrint(OStream& os) {  // NOLINT
+void Script::ScriptPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "Script");
   os << "\n - source: " << Brief(source());
   os << "\n - name: " << Brief(name());
@@ -1048,7 +1028,7 @@
 }
 
 
-void DebugInfo::DebugInfoPrint(OStream& os) {  // NOLINT
+void DebugInfo::DebugInfoPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "DebugInfo");
   os << "\n - shared: " << Brief(shared());
   os << "\n - original_code: " << Brief(original_code());
@@ -1058,7 +1038,7 @@
 }
 
 
-void BreakPointInfo::BreakPointInfoPrint(OStream& os) {  // NOLINT
+void BreakPointInfo::BreakPointInfoPrint(std::ostream& os) {  // NOLINT
   HeapObject::PrintHeader(os, "BreakPointInfo");
   os << "\n - code_position: " << code_position()->value();
   os << "\n - source_position: " << source_position()->value();
@@ -1068,38 +1048,37 @@
 }
 
 
-void DescriptorArray::PrintDescriptors(OStream& os) {  // NOLINT
-  os << "Descriptor array  " << number_of_descriptors() << "\n";
-  for (int i = 0; i < number_of_descriptors(); i++) {
-    Descriptor desc;
-    Get(i, &desc);
-    os << " " << i << ": " << desc;
+static void PrintBitMask(std::ostream& os, uint32_t value) {  // NOLINT
+  for (int i = 0; i < 32; i++) {
+    if ((i & 7) == 0) os << " ";
+    os << (((value & 1) == 0) ? "_" : "x");
+    value >>= 1;
   }
-  os << "\n";
 }
 
 
-void TransitionArray::PrintTransitions(OStream& os) {  // NOLINT
-  os << "Transition array  %d\n", number_of_transitions();
-  for (int i = 0; i < number_of_transitions(); i++) {
-    os << " " << i << ": ";
-    GetKey(i)->NamePrint(os);
-    os << ": ";
-    switch (GetTargetDetails(i).type()) {
-      case FIELD: {
-        os << " (transition to field)\n";
-        break;
-      }
-      case CONSTANT:
-        os << " (transition to constant)\n";
-        break;
-      case CALLBACKS:
-        os << " (transition to callback)\n";
-        break;
-      // Values below are never in the target descriptor array.
-      case NORMAL:
-        UNREACHABLE();
-        break;
+void LayoutDescriptor::Print() {
+  OFStream os(stdout);
+  this->Print(os);
+  os << std::flush;
+}
+
+
+void LayoutDescriptor::Print(std::ostream& os) {  // NOLINT
+  os << "Layout descriptor: ";
+  if (IsUninitialized()) {
+    os << "<uninitialized>";
+  } else if (IsFastPointerLayout()) {
+    os << "<all tagged>";
+  } else if (IsSmi()) {
+    os << "fast";
+    PrintBitMask(os, static_cast<uint32_t>(Smi::cast(this)->value()));
+  } else {
+    os << "slow";
+    int len = length();
+    for (int i = 0; i < len; i++) {
+      if (i > 0) os << " |";
+      PrintBitMask(os, get_scalar(i));
     }
   }
   os << "\n";
@@ -1109,4 +1088,130 @@
 #endif  // OBJECT_PRINT
 
 
+#if TRACE_MAPS
+
+
+void Name::NameShortPrint() {
+  if (this->IsString()) {
+    PrintF("%s", String::cast(this)->ToCString().get());
+  } else {
+    DCHECK(this->IsSymbol());
+    Symbol* s = Symbol::cast(this);
+    if (s->name()->IsUndefined()) {
+      PrintF("#<%s>", s->PrivateSymbolToName());
+    } else {
+      PrintF("<%s>", String::cast(s->name())->ToCString().get());
+    }
+  }
+}
+
+
+int Name::NameShortPrint(Vector<char> str) {
+  if (this->IsString()) {
+    return SNPrintF(str, "%s", String::cast(this)->ToCString().get());
+  } else {
+    DCHECK(this->IsSymbol());
+    Symbol* s = Symbol::cast(this);
+    if (s->name()->IsUndefined()) {
+      return SNPrintF(str, "#<%s>", s->PrivateSymbolToName());
+    } else {
+      return SNPrintF(str, "<%s>", String::cast(s->name())->ToCString().get());
+    }
+  }
+}
+
+
+#endif  // TRACE_MAPS
+
+
+#if defined(DEBUG) || defined(OBJECT_PRINT)
+// This method is only meant to be called from gdb for debugging purposes.
+// Since the string can also be in two-byte encoding, non-Latin1 characters
+// will be ignored in the output.
+char* String::ToAsciiArray() {
+  // Static so that subsequent calls frees previously allocated space.
+  // This also means that previous results will be overwritten.
+  static char* buffer = NULL;
+  if (buffer != NULL) delete[] buffer;
+  buffer = new char[length() + 1];
+  WriteToFlat(this, reinterpret_cast<uint8_t*>(buffer), 0, length());
+  buffer[length()] = 0;
+  return buffer;
+}
+
+
+void DescriptorArray::Print() {
+  OFStream os(stdout);
+  this->PrintDescriptors(os);
+  os << std::flush;
+}
+
+
+void DescriptorArray::PrintDescriptors(std::ostream& os) {  // NOLINT
+  HandleScope scope(GetIsolate());
+  os << "Descriptor array " << number_of_descriptors() << "\n";
+  for (int i = 0; i < number_of_descriptors(); i++) {
+    Descriptor desc;
+    Get(i, &desc);
+    os << " " << i << ": " << desc << "\n";
+  }
+  os << "\n";
+}
+
+
+void TransitionArray::Print() {
+  OFStream os(stdout);
+  this->PrintTransitions(os);
+  os << std::flush;
+}
+
+
+void TransitionArray::PrintTransitions(std::ostream& os,
+                                       bool print_header) {  // NOLINT
+  if (print_header) {
+    os << "Transition array " << number_of_transitions() << "\n";
+  }
+  for (int i = 0; i < number_of_transitions(); i++) {
+    Name* key = GetKey(i);
+    Map* target = GetTarget(i);
+    os << "   ";
+#ifdef OBJECT_PRINT
+    key->NamePrint(os);
+#else
+    key->ShortPrint(os);
+#endif
+    os << ": ";
+    if (key == GetHeap()->nonextensible_symbol()) {
+      os << " (transition to non-extensible)";
+    } else if (key == GetHeap()->sealed_symbol()) {
+      os << " (transition to sealed)";
+    } else if (key == GetHeap()->frozen_symbol()) {
+      os << " (transition to frozen)";
+    } else if (key == GetHeap()->elements_transition_symbol()) {
+      os << " (transition to " << ElementsKindToString(target->elements_kind())
+         << ")";
+    } else if (key == GetHeap()->observed_symbol()) {
+      os << " (transition to Object.observe)";
+    } else {
+      PropertyDetails details = GetTargetDetails(key, target);
+      os << " (transition to ";
+      if (details.location() == IN_DESCRIPTOR) {
+        os << "immutable ";
+      }
+      os << (details.kind() == DATA ? "data" : "accessor");
+      if (details.location() == IN_DESCRIPTOR) {
+        os << " " << Brief(GetTargetValue(i));
+      }
+      os << "), attrs: " << details.attributes();
+    }
+    os << " -> " << Brief(target) << "\n";
+  }
+}
+
+
+void JSObject::PrintTransitions(std::ostream& os) {  // NOLINT
+  if (!map()->HasTransitionArray()) return;
+  map()->transitions()->PrintTransitions(os, false);
+}
+#endif  // defined(DEBUG) || defined(OBJECT_PRINT)
 } }  // namespace v8::internal
diff --git a/src/objects.cc b/src/objects.cc
index 39d3d7c..6b64c3f 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <sstream>
+
 #include "src/v8.h"
 
 #include "src/accessors.h"
@@ -540,9 +542,8 @@
   Debug* debug = isolate->debug();
   // Handle stepping into a getter if step into is active.
   // TODO(rossberg): should this apply to getters that are function proxies?
-  if (debug->StepInActive() && getter->IsJSFunction()) {
-    debug->HandleStepIn(
-        Handle<JSFunction>::cast(getter), Handle<Object>::null(), 0, false);
+  if (debug->is_active()) {
+    debug->HandleStepIn(getter, Handle<Object>::null(), 0, false);
   }
 
   return Execution::Call(isolate, getter, receiver, 0, NULL, true);
@@ -558,9 +559,8 @@
   Debug* debug = isolate->debug();
   // Handle stepping into a setter if step into is active.
   // TODO(rossberg): should this apply to getters that are function proxies?
-  if (debug->StepInActive() && setter->IsJSFunction()) {
-    debug->HandleStepIn(
-        Handle<JSFunction>::cast(setter), Handle<Object>::null(), 0, false);
+  if (debug->is_active()) {
+    debug->HandleStepIn(setter, Handle<Object>::null(), 0, false);
   }
 
   Handle<Object> argv[] = { value };
@@ -572,12 +572,19 @@
 
 
 static bool FindAllCanReadHolder(LookupIterator* it) {
-  for (; it->IsFound(); it->Next()) {
+  // Skip current iteration, it's in state ACCESS_CHECK or INTERCEPTOR, both of
+  // which have already been checked.
+  DCHECK(it->state() == LookupIterator::ACCESS_CHECK ||
+         it->state() == LookupIterator::INTERCEPTOR);
+  for (it->Next(); it->IsFound(); it->Next()) {
     if (it->state() == LookupIterator::ACCESSOR) {
-      Handle<Object> accessors = it->GetAccessors();
+      auto accessors = it->GetAccessors();
       if (accessors->IsAccessorInfo()) {
         if (AccessorInfo::cast(*accessors)->all_can_read()) return true;
       }
+    } else if (it->state() == LookupIterator::INTERCEPTOR) {
+      auto holder = it->GetHolder<JSObject>();
+      if (holder->GetNamedInterceptor()->all_can_read()) return true;
     }
   }
   return false;
@@ -587,10 +594,18 @@
 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck(
     LookupIterator* it) {
   Handle<JSObject> checked = it->GetHolder<JSObject>();
-  if (FindAllCanReadHolder(it)) {
-    return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
-                                   it->GetHolder<JSObject>(),
-                                   it->GetAccessors());
+  while (FindAllCanReadHolder(it)) {
+    if (it->state() == LookupIterator::ACCESSOR) {
+      return GetPropertyWithAccessor(it->GetReceiver(), it->name(),
+                                     it->GetHolder<JSObject>(),
+                                     it->GetAccessors());
+    }
+    DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
+    auto receiver = Handle<JSObject>::cast(it->GetReceiver());
+    auto result = GetPropertyWithInterceptor(it->GetHolder<JSObject>(),
+                                             receiver, it->name());
+    if (it->isolate()->has_scheduled_exception()) break;
+    if (!result.is_null()) return result;
   }
   it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_GET);
   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
@@ -601,8 +616,16 @@
 Maybe<PropertyAttributes> JSObject::GetPropertyAttributesWithFailedAccessCheck(
     LookupIterator* it) {
   Handle<JSObject> checked = it->GetHolder<JSObject>();
-  if (FindAllCanReadHolder(it))
-    return maybe(it->property_details().attributes());
+  while (FindAllCanReadHolder(it)) {
+    if (it->state() == LookupIterator::ACCESSOR) {
+      return maybe(it->property_details().attributes());
+    }
+    DCHECK_EQ(LookupIterator::INTERCEPTOR, it->state());
+    auto result = GetPropertyAttributesWithInterceptor(
+        it->GetHolder<JSObject>(), it->GetReceiver(), it->name());
+    if (it->isolate()->has_scheduled_exception()) break;
+    if (result.has_value && result.value != ABSENT) return result;
+  }
   it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_HAS);
   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(it->isolate(),
                                       Maybe<PropertyAttributes>());
@@ -708,6 +731,13 @@
         // the hole value.
         Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
         DCHECK(new_map->is_dictionary_map());
+#if TRACE_MAPS
+        if (FLAG_trace_maps) {
+          PrintF("[TraceMaps: GlobalDeleteNormalized from= %p to= %p ]\n",
+                 reinterpret_cast<void*>(object->map()),
+                 reinterpret_cast<void*>(*new_map));
+        }
+#endif
         JSObject::MigrateToMap(object, new_map);
       }
       Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry)));
@@ -729,18 +759,62 @@
 }
 
 
-bool JSObject::IsDirty() {
-  Object* cons_obj = map()->constructor();
-  if (!cons_obj->IsJSFunction())
-    return true;
-  JSFunction* fun = JSFunction::cast(cons_obj);
-  if (!fun->shared()->IsApiFunction())
-    return true;
-  // If the object is fully fast case and has the same map it was
-  // created with then no changes can have been made to it.
-  return map() != fun->initial_map()
-      || !HasFastObjectElements()
-      || !HasFastProperties();
+static MaybeHandle<JSObject> FindIndexedAllCanReadHolder(
+    Isolate* isolate, Handle<JSObject> js_object,
+    PrototypeIterator::WhereToStart where_to_start) {
+  for (PrototypeIterator iter(isolate, js_object, where_to_start);
+       !iter.IsAtEnd(); iter.Advance()) {
+    auto curr = PrototypeIterator::GetCurrent(iter);
+    if (!curr->IsJSObject()) break;
+    auto obj = Handle<JSObject>::cast(curr);
+    if (!obj->HasIndexedInterceptor()) continue;
+    if (obj->GetIndexedInterceptor()->all_can_read()) return obj;
+  }
+  return MaybeHandle<JSObject>();
+}
+
+
+MaybeHandle<Object> JSObject::GetElementWithFailedAccessCheck(
+    Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
+    uint32_t index) {
+  Handle<JSObject> holder = object;
+  PrototypeIterator::WhereToStart where_to_start =
+      PrototypeIterator::START_AT_RECEIVER;
+  while (true) {
+    auto all_can_read_holder =
+        FindIndexedAllCanReadHolder(isolate, holder, where_to_start);
+    if (!all_can_read_holder.ToHandle(&holder)) break;
+    auto result =
+        JSObject::GetElementWithInterceptor(holder, receiver, index, false);
+    if (isolate->has_scheduled_exception()) break;
+    if (!result.is_null()) return result;
+    where_to_start = PrototypeIterator::START_AT_PROTOTYPE;
+  }
+  isolate->ReportFailedAccessCheck(object, v8::ACCESS_GET);
+  RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+  return isolate->factory()->undefined_value();
+}
+
+
+Maybe<PropertyAttributes> JSObject::GetElementAttributesWithFailedAccessCheck(
+    Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
+    uint32_t index) {
+  Handle<JSObject> holder = object;
+  PrototypeIterator::WhereToStart where_to_start =
+      PrototypeIterator::START_AT_RECEIVER;
+  while (true) {
+    auto all_can_read_holder =
+        FindIndexedAllCanReadHolder(isolate, holder, where_to_start);
+    if (!all_can_read_holder.ToHandle(&holder)) break;
+    auto result =
+        JSObject::GetElementAttributeFromInterceptor(object, receiver, index);
+    if (isolate->has_scheduled_exception()) break;
+    if (result.has_value && result.value != ABSENT) return result;
+    where_to_start = PrototypeIterator::START_AT_PROTOTYPE;
+  }
+  isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
+  RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
+  return maybe(ABSENT);
 }
 
 
@@ -776,14 +850,14 @@
     // Check access rights if needed.
     if (js_object->IsAccessCheckNeeded()) {
       if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_GET)) {
-        isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_GET);
-        RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
-        return isolate->factory()->undefined_value();
+        return JSObject::GetElementWithFailedAccessCheck(isolate, js_object,
+                                                         receiver, index);
       }
     }
 
     if (js_object->HasIndexedInterceptor()) {
-      return JSObject::GetElementWithInterceptor(js_object, receiver, index);
+      return JSObject::GetElementWithInterceptor(js_object, receiver, index,
+                                                 true);
     }
 
     if (js_object->elements() != isolate->heap()->empty_fixed_array()) {
@@ -800,6 +874,82 @@
 }
 
 
+MaybeHandle<Object> Object::SetElementWithReceiver(
+    Isolate* isolate, Handle<Object> object, Handle<Object> receiver,
+    uint32_t index, Handle<Object> value, StrictMode strict_mode) {
+  // Iterate up the prototype chain until an element is found or the null
+  // prototype is encountered.
+  bool done = false;
+  for (PrototypeIterator iter(isolate, object,
+                              object->IsJSProxy() || object->IsJSObject()
+                                  ? PrototypeIterator::START_AT_RECEIVER
+                                  : PrototypeIterator::START_AT_PROTOTYPE);
+       !iter.IsAtEnd() && !done; iter.Advance()) {
+    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
+      // TODO(dslomov): implement.
+      isolate->ThrowIllegalOperation();
+      return MaybeHandle<Object>();
+    }
+
+    Handle<JSObject> js_object =
+        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+
+    // Check access rights if needed.
+    if (js_object->IsAccessCheckNeeded()) {
+      if (!isolate->MayIndexedAccess(js_object, index, v8::ACCESS_SET)) {
+        isolate->ReportFailedAccessCheck(js_object, v8::ACCESS_SET);
+        RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+        return isolate->factory()->undefined_value();
+      }
+    }
+
+    if (js_object->HasIndexedInterceptor()) {
+      Maybe<PropertyAttributes> from_interceptor =
+          JSObject::GetElementAttributeFromInterceptor(js_object, receiver,
+                                                       index);
+      if (!from_interceptor.has_value) return MaybeHandle<Object>();
+      if ((from_interceptor.value & READ_ONLY) != 0) {
+        return WriteToReadOnlyElement(isolate, receiver, index, value,
+                                      strict_mode);
+      }
+      done = from_interceptor.value != ABSENT;
+    }
+
+    if (!done &&
+        js_object->elements() != isolate->heap()->empty_fixed_array()) {
+      ElementsAccessor* accessor = js_object->GetElementsAccessor();
+      PropertyAttributes attrs =
+          accessor->GetAttributes(receiver, js_object, index);
+      if ((attrs & READ_ONLY) != 0) {
+        return WriteToReadOnlyElement(isolate, receiver, index, value,
+                                      strict_mode);
+      }
+      Handle<AccessorPair> accessor_pair;
+      if (accessor->GetAccessorPair(receiver, js_object, index)
+              .ToHandle(&accessor_pair)) {
+        return JSObject::SetElementWithCallback(receiver, accessor_pair, index,
+                                                value, js_object, strict_mode);
+      } else {
+        done = attrs != ABSENT;
+      }
+    }
+  }
+
+  if (!receiver->IsJSObject()) {
+    return WriteToReadOnlyElement(isolate, receiver, index, value, strict_mode);
+  }
+  Handle<JSObject> target = Handle<JSObject>::cast(receiver);
+  ElementsAccessor* accessor = target->GetElementsAccessor();
+  PropertyAttributes attrs = accessor->GetAttributes(receiver, target, index);
+  if ((attrs & READ_ONLY) != 0) {
+    return WriteToReadOnlyElement(isolate, receiver, index, value, strict_mode);
+  }
+  PropertyAttributes new_attrs = attrs != ABSENT ? attrs : NONE;
+  return JSObject::SetElement(target, index, value, new_attrs, strict_mode,
+                              false);
+}
+
+
 Map* Object::GetRootMap(Isolate* isolate) {
   DisallowHeapAllocation no_alloc;
   if (IsSmi()) {
@@ -909,13 +1059,16 @@
 
 
 void Object::ShortPrint(StringStream* accumulator) {
-  OStringStream os;
+  std::ostringstream os;
   os << Brief(this);
-  accumulator->Add(os.c_str());
+  accumulator->Add(os.str().c_str());
 }
 
 
-OStream& operator<<(OStream& os, const Brief& v) {
+void Object::ShortPrint(std::ostream& os) { os << Brief(this); }
+
+
+std::ostream& operator<<(std::ostream& os, const Brief& v) {
   if (v.value->IsSmi()) {
     Smi::cast(v.value)->SmiPrint(os);
   } else {
@@ -927,7 +1080,7 @@
 }
 
 
-void Smi::SmiPrint(OStream& os) const {  // NOLINT
+void Smi::SmiPrint(std::ostream& os) const {  // NOLINT
   os << value();
 }
 
@@ -1120,8 +1273,7 @@
     return;
   }
 
-  ConsStringIteratorOp op;
-  StringCharacterStream stream(this, &op);
+  StringCharacterStream stream(this);
 
   bool truncated = false;
   if (len > kMaxShortPrintLength) {
@@ -1172,10 +1324,9 @@
 }
 
 
-void String::PrintUC16(OStream& os, int start, int end) {  // NOLINT
+void String::PrintUC16(std::ostream& os, int start, int end) {  // NOLINT
   if (end < 0) end = length();
-  ConsStringIteratorOp op;
-  StringCharacterStream stream(this, &op, start);
+  StringCharacterStream stream(this, start);
   for (int i = start; i < end && stream.HasMore(); i++) {
     os << AsUC16(stream.GetNext());
   }
@@ -1371,7 +1522,7 @@
 }
 
 
-void HeapObject::HeapObjectShortPrint(OStream& os) {  // NOLINT
+void HeapObject::HeapObjectShortPrint(std::ostream& os) {  // NOLINT
   Heap* heap = GetHeap();
   if (!heap->Contains(this)) {
     os << "!!!INVALID POINTER!!!";
@@ -1471,15 +1622,7 @@
     }
     case SYMBOL_TYPE: {
       Symbol* symbol = Symbol::cast(this);
-      os << "<Symbol: " << symbol->Hash();
-      if (!symbol->name()->IsUndefined()) {
-        os << " ";
-        HeapStringAllocator allocator;
-        StringStream accumulator(&allocator);
-        String::cast(symbol->name())->StringShortPrint(&accumulator);
-        os << accumulator.ToCString().get();
-      }
-      os << ">";
+      symbol->SymbolShortPrint(os);
       break;
     }
     case HEAP_NUMBER_TYPE: {
@@ -1519,6 +1662,14 @@
       os << accumulator.ToCString().get();
       break;
     }
+    case WEAK_CELL_TYPE: {
+      os << "WeakCell for ";
+      HeapStringAllocator allocator;
+      StringStream accumulator(&allocator);
+      WeakCell::cast(this)->value()->ShortPrint(&accumulator);
+      os << accumulator.ToCString().get();
+      break;
+    }
     default:
       os << "<Other heap object (" << map()->instance_type() << ")>";
       break;
@@ -1622,6 +1773,9 @@
     case PROPERTY_CELL_TYPE:
       PropertyCell::BodyDescriptor::IterateBody(this, v);
       break;
+    case WEAK_CELL_TYPE:
+      WeakCell::BodyDescriptor::IterateBody(this, v);
+      break;
     case SYMBOL_TYPE:
       Symbol::BodyDescriptor::IterateBody(this, v);
       break;
@@ -1668,7 +1822,7 @@
 }
 
 
-void HeapNumber::HeapNumberPrint(OStream& os) {  // NOLINT
+void HeapNumber::HeapNumberPrint(std::ostream& os) {  // NOLINT
   os << value();
 }
 
@@ -1775,7 +1929,7 @@
       // Assign an enumeration index to the property and update
       // SetNextEnumerationIndex.
       int index = dict->NextEnumerationIndex();
-      PropertyDetails details = PropertyDetails(attributes, NORMAL, index);
+      PropertyDetails details(attributes, FIELD, index);
       dict->SetNextEnumerationIndex(index + 1);
       dict->SetEntry(entry, name, cell, details);
       return;
@@ -1784,7 +1938,7 @@
     PropertyCell::SetValueInferType(cell, value);
     value = cell;
   }
-  PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
+  PropertyDetails details(attributes, FIELD, 0);
   Handle<NameDictionary> result =
       NameDictionary::Add(dict, name, value, details);
   if (*dict != *result) object->set_properties(*result);
@@ -1806,10 +1960,10 @@
 }
 
 
-void JSObject::EnqueueChangeRecord(Handle<JSObject> object,
-                                   const char* type_str,
-                                   Handle<Name> name,
-                                   Handle<Object> old_value) {
+MaybeHandle<Object> JSObject::EnqueueChangeRecord(Handle<JSObject> object,
+                                                  const char* type_str,
+                                                  Handle<Name> name,
+                                                  Handle<Object> old_value) {
   DCHECK(!object->IsJSGlobalProxy());
   DCHECK(!object->IsJSGlobalObject());
   Isolate* isolate = object->GetIsolate();
@@ -1818,10 +1972,9 @@
   Handle<Object> args[] = { type, object, name, old_value };
   int argc = name.is_null() ? 2 : old_value->IsTheHole() ? 3 : 4;
 
-  Execution::Call(isolate,
-                  Handle<JSFunction>(isolate->observers_notify_change()),
-                  isolate->factory()->undefined_value(),
-                  argc, args).Assert();
+  return Execution::Call(isolate,
+                         Handle<JSFunction>(isolate->observers_notify_change()),
+                         isolate->factory()->undefined_value(), argc, args);
 }
 
 
@@ -1879,7 +2032,7 @@
 void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) {
   Isolate* isolate = parent->GetIsolate();
   Handle<Name> name = isolate->factory()->elements_transition_symbol();
-  ConnectTransition(parent, child, name, FULL_TRANSITION);
+  ConnectTransition(parent, child, name, SPECIAL_TRANSITION);
 }
 
 
@@ -1893,7 +2046,8 @@
         // Clear out the old descriptor array to avoid problems to sharing
         // the descriptor array without using an explicit.
         old_map->InitializeDescriptors(
-            old_map->GetHeap()->empty_descriptor_array());
+            old_map->GetHeap()->empty_descriptor_array(),
+            LayoutDescriptor::FastPointerLayout());
         // Ensure that no transition was inserted for prototype migrations.
         DCHECK(!old_map->HasTransitionArray());
         DCHECK(new_map->GetBackPointer()->IsUndefined());
@@ -1952,17 +2106,21 @@
 
     if (old_map->unused_property_fields() > 0) {
       if (details.representation().IsDouble()) {
-        Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE);
         FieldIndex index =
             FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
-        object->FastPropertyAtPut(index, *value);
+        if (new_map->IsUnboxedDoubleField(index)) {
+          object->RawFastDoublePropertyAtPut(index, 0);
+        } else {
+          Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE);
+          object->RawFastPropertyAtPut(index, *value);
+        }
       }
       object->synchronized_set_map(*new_map);
       return;
     }
 
     DCHECK(number_of_fields == old_number_of_fields + 1);
-    // This migration is a transition from a map that has run out out property
+    // This migration is a transition from a map that has run out of property
     // space. Therefore it could be done by extending the backing store.
     Handle<FixedArray> old_storage = handle(object->properties(), isolate);
     Handle<FixedArray> new_storage =
@@ -2007,23 +2165,35 @@
       DCHECK(details.representation().IsTagged());
       continue;
     }
+    Representation old_representation = old_details.representation();
+    Representation representation = details.representation();
     DCHECK(old_details.type() == CONSTANT ||
            old_details.type() == FIELD);
-    Object* raw_value = old_details.type() == CONSTANT
-        ? old_descriptors->GetValue(i)
-        : object->RawFastPropertyAt(FieldIndex::ForDescriptor(*old_map, i));
-    Handle<Object> value(raw_value, isolate);
-    if (!old_details.representation().IsDouble() &&
-        details.representation().IsDouble()) {
-      if (old_details.representation().IsNone()) {
-        value = handle(Smi::FromInt(0), isolate);
+    Handle<Object> value;
+    if (old_details.type() == CONSTANT) {
+      value = handle(old_descriptors->GetValue(i), isolate);
+      DCHECK(!old_representation.IsDouble() && !representation.IsDouble());
+    } else {
+      FieldIndex index = FieldIndex::ForDescriptor(*old_map, i);
+      if (object->IsUnboxedDoubleField(index)) {
+        double old = object->RawFastDoublePropertyAt(index);
+        value = isolate->factory()->NewHeapNumber(
+            old, representation.IsDouble() ? MUTABLE : IMMUTABLE);
+
+      } else {
+        value = handle(object->RawFastPropertyAt(index), isolate);
+        if (!old_representation.IsDouble() && representation.IsDouble()) {
+          if (old_representation.IsNone()) {
+            value = handle(Smi::FromInt(0), isolate);
+          }
+          value = Object::NewStorageFor(isolate, value, representation);
+        } else if (old_representation.IsDouble() &&
+                   !representation.IsDouble()) {
+          value = Object::WrapForRead(isolate, value, old_representation);
+        }
       }
-      value = Object::NewStorageFor(isolate, value, details.representation());
-    } else if (old_details.representation().IsDouble() &&
-               !details.representation().IsDouble()) {
-      value = Object::WrapForRead(isolate, value, old_details.representation());
     }
-    DCHECK(!(details.representation().IsDouble() && value->IsSmi()));
+    DCHECK(!(representation.IsDouble() && value->IsSmi()));
     int target_index = new_descriptors->GetFieldIndex(i) - inobject;
     if (target_index < 0) target_index += total_size;
     array->set(target_index, *value);
@@ -2051,7 +2221,16 @@
   int limit = Min(inobject, number_of_fields);
   for (int i = 0; i < limit; i++) {
     FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
-    object->FastPropertyAtPut(index, array->get(external + i));
+    Object* value = array->get(external + i);
+    // Can't use JSObject::FastPropertyAtPut() because proper map was not set
+    // yet.
+    if (new_map->IsUnboxedDoubleField(index)) {
+      DCHECK(value->IsMutableHeapNumber());
+      object->RawFastDoublePropertyAtPut(index,
+                                         HeapNumber::cast(value)->value());
+    } else {
+      object->RawFastPropertyAtPut(index, value);
+    }
   }
 
   Heap* heap = isolate->heap();
@@ -2081,17 +2260,6 @@
 }
 
 
-void JSObject::GeneralizeFieldRepresentation(Handle<JSObject> object,
-                                             int modify_index,
-                                             Representation new_representation,
-                                             Handle<HeapType> new_field_type) {
-  Handle<Map> new_map = Map::GeneralizeRepresentation(
-      handle(object->map()), modify_index, new_representation, new_field_type,
-      FORCE_FIELD);
-  MigrateToMap(object, new_map);
-}
-
-
 int Map::NumberOfFields() {
   DescriptorArray* descriptors = instance_descriptors();
   int result = 0;
@@ -2108,20 +2276,27 @@
                                                   PropertyAttributes attributes,
                                                   const char* reason) {
   Isolate* isolate = map->GetIsolate();
-  Handle<Map> new_map = Copy(map);
+  Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
+  int number_of_own_descriptors = map->NumberOfOwnDescriptors();
+  Handle<DescriptorArray> descriptors =
+      DescriptorArray::CopyUpTo(old_descriptors, number_of_own_descriptors);
 
-  DescriptorArray* descriptors = new_map->instance_descriptors();
-  int length = descriptors->number_of_descriptors();
-  for (int i = 0; i < length; i++) {
+  for (int i = 0; i < number_of_own_descriptors; i++) {
     descriptors->SetRepresentation(i, Representation::Tagged());
     if (descriptors->GetDetails(i).type() == FIELD) {
       descriptors->SetValue(i, HeapType::Any());
     }
   }
 
+  Handle<LayoutDescriptor> new_layout_descriptor(
+      LayoutDescriptor::FastPointerLayout(), isolate);
+  Handle<Map> new_map = CopyReplaceDescriptors(
+      map, descriptors, new_layout_descriptor, OMIT_TRANSITION,
+      MaybeHandle<Name>(), reason, SPECIAL_TRANSITION);
+
   // Unless the instance is being migrated, ensure that modify_index is a field.
   PropertyDetails details = descriptors->GetDetails(modify_index);
-  if (store_mode == FORCE_FIELD &&
+  if (store_mode == FORCE_IN_OBJECT &&
       (details.type() != FIELD || details.attributes() != attributes)) {
     int field_index = details.type() == FIELD ? details.field_index()
                                               : new_map->NumberOfFields();
@@ -2143,12 +2318,12 @@
     HeapType* field_type = (details.type() == FIELD)
         ? map->instance_descriptors()->GetFieldType(modify_index)
         : NULL;
-    map->PrintGeneralization(stdout, reason, modify_index,
-                        new_map->NumberOfOwnDescriptors(),
-                        new_map->NumberOfOwnDescriptors(),
-                        details.type() == CONSTANT && store_mode == FORCE_FIELD,
-                        details.representation(), Representation::Tagged(),
-                        field_type, HeapType::Any());
+    map->PrintGeneralization(
+        stdout, reason, modify_index, new_map->NumberOfOwnDescriptors(),
+        new_map->NumberOfOwnDescriptors(),
+        details.type() == CONSTANT && store_mode == FORCE_IN_OBJECT,
+        details.representation(), Representation::Tagged(), field_type,
+        HeapType::Any());
   }
   return new_map;
 }
@@ -2184,30 +2359,37 @@
 // Invalidates a transition target at |key|, and installs |new_descriptors| over
 // the current instance_descriptors to ensure proper sharing of descriptor
 // arrays.
-void Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors) {
+// Returns true if the transition target at given key was deprecated.
+bool Map::DeprecateTarget(PropertyKind kind, Name* key,
+                          PropertyAttributes attributes,
+                          DescriptorArray* new_descriptors,
+                          LayoutDescriptor* new_layout_descriptor) {
+  bool transition_target_deprecated = false;
   if (HasTransitionArray()) {
     TransitionArray* transitions = this->transitions();
-    int transition = transitions->Search(key);
+    int transition = transitions->Search(kind, key, attributes);
     if (transition != TransitionArray::kNotFound) {
       transitions->GetTarget(transition)->DeprecateTransitionTree();
+      transition_target_deprecated = true;
     }
   }
 
   // Don't overwrite the empty descriptor array.
-  if (NumberOfOwnDescriptors() == 0) return;
+  if (NumberOfOwnDescriptors() == 0) return transition_target_deprecated;
 
   DescriptorArray* to_replace = instance_descriptors();
   Map* current = this;
   GetHeap()->incremental_marking()->RecordWrites(to_replace);
   while (current->instance_descriptors() == to_replace) {
     current->SetEnumLength(kInvalidEnumCacheSentinel);
-    current->set_instance_descriptors(new_descriptors);
+    current->UpdateDescriptors(new_descriptors, new_layout_descriptor);
     Object* next = current->GetBackPointer();
     if (next->IsUndefined()) break;
     current = Map::cast(next);
   }
 
   set_owns_descriptors(false);
+  return transition_target_deprecated;
 }
 
 
@@ -2234,14 +2416,15 @@
   for (int i = verbatim; i < length; i++) {
     if (!current->HasTransitionArray()) break;
     Name* name = descriptors->GetKey(i);
+    PropertyDetails details = descriptors->GetDetails(i);
     TransitionArray* transitions = current->transitions();
-    int transition = transitions->Search(name);
+    int transition =
+        transitions->Search(details.kind(), name, details.attributes());
     if (transition == TransitionArray::kNotFound) break;
 
     Map* next = transitions->GetTarget(transition);
     DescriptorArray* next_descriptors = next->instance_descriptors();
 
-    PropertyDetails details = descriptors->GetDetails(i);
     PropertyDetails next_details = next_descriptors->GetDetails(i);
     if (details.type() != next_details.type()) break;
     if (details.attributes() != next_details.attributes()) break;
@@ -2275,6 +2458,7 @@
 
 
 void Map::UpdateFieldType(int descriptor, Handle<Name> name,
+                          Representation new_representation,
                           Handle<HeapType> new_type) {
   DisallowHeapAllocation no_allocation;
   PropertyDetails details = instance_descriptors()->GetDetails(descriptor);
@@ -2282,13 +2466,18 @@
   if (HasTransitionArray()) {
     TransitionArray* transitions = this->transitions();
     for (int i = 0; i < transitions->number_of_transitions(); ++i) {
-      transitions->GetTarget(i)->UpdateFieldType(descriptor, name, new_type);
+      transitions->GetTarget(i)
+          ->UpdateFieldType(descriptor, name, new_representation, new_type);
     }
   }
+  // It is allowed to change representation here only from None to something.
+  DCHECK(details.representation().Equals(new_representation) ||
+         details.representation().IsNone());
+
   // Skip if already updated the shared descriptor.
   if (instance_descriptors()->GetFieldType(descriptor) == *new_type) return;
   FieldDescriptor d(name, instance_descriptors()->GetFieldIndex(descriptor),
-                    new_type, details.attributes(), details.representation());
+                    new_type, details.attributes(), new_representation);
   instance_descriptors()->Replace(descriptor, &d);
 }
 
@@ -2314,15 +2503,20 @@
 
 
 // static
-void Map::GeneralizeFieldType(Handle<Map> map,
-                              int modify_index,
+void Map::GeneralizeFieldType(Handle<Map> map, int modify_index,
+                              Representation new_representation,
                               Handle<HeapType> new_field_type) {
   Isolate* isolate = map->GetIsolate();
 
   // Check if we actually need to generalize the field type at all.
-  Handle<HeapType> old_field_type(
-      map->instance_descriptors()->GetFieldType(modify_index), isolate);
-  if (new_field_type->NowIs(old_field_type)) {
+  Handle<DescriptorArray> old_descriptors(map->instance_descriptors(), isolate);
+  Representation old_representation =
+      old_descriptors->GetDetails(modify_index).representation();
+  Handle<HeapType> old_field_type(old_descriptors->GetFieldType(modify_index),
+                                  isolate);
+
+  if (old_representation.Equals(new_representation) &&
+      new_field_type->NowIs(old_field_type)) {
     DCHECK(Map::GeneralizeFieldType(old_field_type,
                                     new_field_type,
                                     isolate)->NowIs(old_field_type));
@@ -2341,7 +2535,8 @@
 
   PropertyDetails details = descriptors->GetDetails(modify_index);
   Handle<Name> name(descriptors->GetKey(modify_index));
-  field_owner->UpdateFieldType(modify_index, name, new_field_type);
+  field_owner->UpdateFieldType(modify_index, name, new_representation,
+                               new_field_type);
   field_owner->dependent_code()->DeoptimizeDependentCodeGroup(
       isolate, DependentCode::kFieldTypeGroup);
 
@@ -2392,12 +2587,9 @@
   // modification to the object, because the default uninitialized value for
   // representation None can be overwritten by both smi and tagged values.
   // Doubles, however, would require a box allocation.
-  if (old_representation.IsNone() &&
-      !new_representation.IsNone() &&
+  if (old_representation.IsNone() && !new_representation.IsNone() &&
       !new_representation.IsDouble()) {
     DCHECK(old_details.type() == FIELD);
-    DCHECK(old_descriptors->GetFieldType(modify_index)->NowIs(
-            HeapType::None()));
     if (FLAG_trace_generalization) {
       old_map->PrintGeneralization(
           stdout, "uninitialized field",
@@ -2406,48 +2598,55 @@
           old_representation, new_representation,
           old_descriptors->GetFieldType(modify_index), *new_field_type);
     }
-    old_descriptors->SetRepresentation(modify_index, new_representation);
-    old_descriptors->SetValue(modify_index, *new_field_type);
+    Handle<Map> field_owner(old_map->FindFieldOwner(modify_index), isolate);
+
+    GeneralizeFieldType(field_owner, modify_index, new_representation,
+                        new_field_type);
+    DCHECK(old_descriptors->GetDetails(modify_index).representation().Equals(
+        new_representation));
+    DCHECK(old_descriptors->GetFieldType(modify_index)->NowIs(new_field_type));
     return old_map;
   }
 
   // Check the state of the root map.
   Handle<Map> root_map(old_map->FindRootMap(), isolate);
   if (!old_map->EquivalentToForTransition(*root_map)) {
-    return CopyGeneralizeAllRepresentations(
-        old_map, modify_index, store_mode, "not equivalent");
+    return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
+                                            "GenAll_NotEquivalent");
   }
   int root_nof = root_map->NumberOfOwnDescriptors();
   if (modify_index < root_nof) {
     PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
-    if ((old_details.type() != FIELD && store_mode == FORCE_FIELD) ||
+    if ((old_details.type() != FIELD && store_mode == FORCE_IN_OBJECT) ||
         (old_details.type() == FIELD &&
          (!new_field_type->NowIs(old_descriptors->GetFieldType(modify_index)) ||
           !new_representation.fits_into(old_details.representation())))) {
-      return CopyGeneralizeAllRepresentations(
-          old_map, modify_index, store_mode, "root modification");
+      return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
+                                              "GenAll_RootModification");
     }
   }
 
   Handle<Map> target_map = root_map;
   for (int i = root_nof; i < old_nof; ++i) {
-    int j = target_map->SearchTransition(old_descriptors->GetKey(i));
+    PropertyDetails old_details = old_descriptors->GetDetails(i);
+    int j = target_map->SearchTransition(old_details.kind(),
+                                         old_descriptors->GetKey(i),
+                                         old_details.attributes());
     if (j == TransitionArray::kNotFound) break;
     Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
     Handle<DescriptorArray> tmp_descriptors = handle(
         tmp_map->instance_descriptors(), isolate);
 
     // Check if target map is incompatible.
-    PropertyDetails old_details = old_descriptors->GetDetails(i);
     PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
     PropertyType old_type = old_details.type();
     PropertyType tmp_type = tmp_details.type();
-    if (tmp_details.attributes() != old_details.attributes() ||
-        ((tmp_type == CALLBACKS || old_type == CALLBACKS) &&
-         (tmp_type != old_type ||
-          tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
-      return CopyGeneralizeAllRepresentations(
-          old_map, modify_index, store_mode, "incompatible");
+    DCHECK_EQ(old_details.attributes(), tmp_details.attributes());
+    if ((tmp_type == CALLBACKS || old_type == CALLBACKS) &&
+        (tmp_type != old_type ||
+         tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) {
+      return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
+                                              "GenAll_Incompatible");
     }
     Representation old_representation = old_details.representation();
     Representation tmp_representation = tmp_details.representation();
@@ -2466,7 +2665,7 @@
         old_field_type = GeneralizeFieldType(
             new_field_type, old_field_type, isolate);
       }
-      GeneralizeFieldType(tmp_map, i, old_field_type);
+      GeneralizeFieldType(tmp_map, i, tmp_representation, old_field_type);
     } else if (tmp_type == CONSTANT) {
       if (old_type != CONSTANT ||
           old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) {
@@ -2484,7 +2683,7 @@
       target_map->instance_descriptors(), isolate);
   int target_nof = target_map->NumberOfOwnDescriptors();
   if (target_nof == old_nof &&
-      (store_mode != FORCE_FIELD ||
+      (store_mode != FORCE_IN_OBJECT ||
        target_descriptors->GetDetails(modify_index).type() == FIELD)) {
     DCHECK(modify_index < target_nof);
     DCHECK(new_representation.fits_into(
@@ -2497,21 +2696,23 @@
 
   // Find the last compatible target map in the transition tree.
   for (int i = target_nof; i < old_nof; ++i) {
-    int j = target_map->SearchTransition(old_descriptors->GetKey(i));
+    PropertyDetails old_details = old_descriptors->GetDetails(i);
+    int j = target_map->SearchTransition(old_details.kind(),
+                                         old_descriptors->GetKey(i),
+                                         old_details.attributes());
     if (j == TransitionArray::kNotFound) break;
     Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
     Handle<DescriptorArray> tmp_descriptors(
         tmp_map->instance_descriptors(), isolate);
 
     // Check if target map is compatible.
-    PropertyDetails old_details = old_descriptors->GetDetails(i);
     PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
-    if (tmp_details.attributes() != old_details.attributes() ||
-        ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) &&
-         (tmp_details.type() != old_details.type() ||
-          tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
-      return CopyGeneralizeAllRepresentations(
-          old_map, modify_index, store_mode, "incompatible");
+    DCHECK_EQ(old_details.attributes(), tmp_details.attributes());
+    if ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) &&
+        (tmp_details.type() != old_details.type() ||
+         tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) {
+      return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
+                                              "GenAll_Incompatible");
     }
     target_map = tmp_map;
   }
@@ -2535,7 +2736,9 @@
   int current_offset = 0;
   for (int i = 0; i < root_nof; ++i) {
     PropertyDetails old_details = old_descriptors->GetDetails(i);
-    if (old_details.type() == FIELD) current_offset++;
+    if (old_details.type() == FIELD) {
+      current_offset += old_details.field_width_in_words();
+    }
     Descriptor d(handle(old_descriptors->GetKey(i), isolate),
                  handle(old_descriptors->GetValue(i), isolate),
                  old_details);
@@ -2555,9 +2758,8 @@
           new_representation.generalize(target_details.representation()));
     }
     DCHECK_EQ(old_details.attributes(), target_details.attributes());
-    if (old_details.type() == FIELD ||
-        target_details.type() == FIELD ||
-        (modify_index == i && store_mode == FORCE_FIELD) ||
+    if (old_details.type() == FIELD || target_details.type() == FIELD ||
+        (modify_index == i && store_mode == FORCE_IN_OBJECT) ||
         (target_descriptors->GetValue(i) != old_descriptors->GetValue(i))) {
       Handle<HeapType> old_field_type = (old_details.type() == FIELD)
           ? handle(old_descriptors->GetFieldType(i), isolate)
@@ -2573,11 +2775,10 @@
         target_field_type = GeneralizeFieldType(
             target_field_type, new_field_type, isolate);
       }
-      FieldDescriptor d(target_key,
-                        current_offset++,
-                        target_field_type,
+      FieldDescriptor d(target_key, current_offset, target_field_type,
                         target_details.attributes(),
                         target_details.representation());
+      current_offset += d.GetDetails().field_width_in_words();
       new_descriptors->Set(i, &d);
     } else {
       DCHECK_NE(FIELD, target_details.type());
@@ -2603,23 +2804,20 @@
         old_field_type = GeneralizeFieldType(
             old_field_type, new_field_type, isolate);
       }
-      FieldDescriptor d(old_key,
-                        current_offset++,
-                        old_field_type,
-                        old_details.attributes(),
-                        old_details.representation());
+      FieldDescriptor d(old_key, current_offset, old_field_type,
+                        old_details.attributes(), old_details.representation());
+      current_offset += d.GetDetails().field_width_in_words();
       new_descriptors->Set(i, &d);
     } else {
       DCHECK(old_details.type() == CONSTANT || old_details.type() == CALLBACKS);
-      if (modify_index == i && store_mode == FORCE_FIELD) {
-        FieldDescriptor d(old_key,
-                          current_offset++,
-                          GeneralizeFieldType(
-                              old_descriptors->GetValue(i)->OptimalType(
-                                  isolate, old_details.representation()),
-                              new_field_type, isolate),
-                          old_details.attributes(),
-                          old_details.representation());
+      if (modify_index == i && store_mode == FORCE_IN_OBJECT) {
+        FieldDescriptor d(
+            old_key, current_offset,
+            GeneralizeFieldType(old_descriptors->GetValue(i)->OptimalType(
+                                    isolate, old_details.representation()),
+                                new_field_type, isolate),
+            old_details.attributes(), old_details.representation());
+        current_offset += d.GetDetails().field_width_in_words();
         new_descriptors->Set(i, &d);
       } else {
         DCHECK_NE(FIELD, old_details.type());
@@ -2633,7 +2831,7 @@
 
   new_descriptors->Sort();
 
-  DCHECK(store_mode != FORCE_FIELD ||
+  DCHECK(store_mode != FORCE_IN_OBJECT ||
          new_descriptors->GetDetails(modify_index).type() == FIELD);
 
   Handle<Map> split_map(root_map->FindLastMatchMap(
@@ -2641,8 +2839,21 @@
   int split_nof = split_map->NumberOfOwnDescriptors();
   DCHECK_NE(old_nof, split_nof);
 
-  split_map->DeprecateTarget(
-      old_descriptors->GetKey(split_nof), *new_descriptors);
+  Handle<LayoutDescriptor> new_layout_descriptor =
+      LayoutDescriptor::New(split_map, new_descriptors, old_nof);
+  PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof);
+  bool transition_target_deprecated = split_map->DeprecateTarget(
+      split_prop_details.kind(), old_descriptors->GetKey(split_nof),
+      split_prop_details.attributes(), *new_descriptors,
+      *new_layout_descriptor);
+
+  // If |transition_target_deprecated| is true then the transition array
+  // already contains entry for given descriptor. This means that the transition
+  // could be inserted regardless of whether transitions array is full or not.
+  if (!transition_target_deprecated && !split_map->CanHaveMoreTransitions()) {
+    return CopyGeneralizeAllRepresentations(old_map, modify_index, store_mode,
+                                            "GenAll_CantHaveMoreTransitions");
+  }
 
   if (FLAG_trace_generalization) {
     PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
@@ -2657,7 +2868,7 @@
                                     isolate), isolate);
     old_map->PrintGeneralization(
         stdout, "", modify_index, split_nof, old_nof,
-        old_details.type() == CONSTANT && store_mode == FORCE_FIELD,
+        old_details.type() == CONSTANT && store_mode == FORCE_IN_OBJECT,
         old_details.representation(), new_details.representation(),
         *old_field_type, *new_field_type);
   }
@@ -2665,7 +2876,8 @@
   // Add missing transitions.
   Handle<Map> new_map = split_map;
   for (int i = split_nof; i < old_nof; ++i) {
-    new_map = CopyInstallDescriptors(new_map, i, new_descriptors);
+    new_map = CopyInstallDescriptors(new_map, i, new_descriptors,
+                                     new_layout_descriptor);
   }
   new_map->set_owns_descriptors(true);
   return new_map;
@@ -2680,7 +2892,7 @@
     if (descriptors->GetDetails(i).type() == FIELD) {
       map = GeneralizeRepresentation(map, i, Representation::Tagged(),
                                      HeapType::Any(map->GetIsolate()),
-                                     FORCE_FIELD);
+                                     FORCE_IN_OBJECT);
     }
   }
   return map;
@@ -2706,7 +2918,7 @@
   if (!map->is_deprecated()) return map;
   return GeneralizeRepresentation(map, 0, Representation::None(),
                                   HeapType::None(map->GetIsolate()),
-                                  ALLOW_AS_CONSTANT);
+                                  ALLOW_IN_DESCRIPTOR);
 }
 
 
@@ -2727,42 +2939,47 @@
 
   Map* new_map = root_map;
   for (int i = root_nof; i < old_nof; ++i) {
-    int j = new_map->SearchTransition(old_descriptors->GetKey(i));
+    PropertyDetails old_details = old_descriptors->GetDetails(i);
+    int j = new_map->SearchTransition(old_details.kind(),
+                                      old_descriptors->GetKey(i),
+                                      old_details.attributes());
     if (j == TransitionArray::kNotFound) return MaybeHandle<Map>();
     new_map = new_map->GetTransition(j);
     DescriptorArray* new_descriptors = new_map->instance_descriptors();
 
     PropertyDetails new_details = new_descriptors->GetDetails(i);
-    PropertyDetails old_details = old_descriptors->GetDetails(i);
-    if (old_details.attributes() != new_details.attributes() ||
-        !old_details.representation().fits_into(new_details.representation())) {
+    DCHECK_EQ(old_details.kind(), new_details.kind());
+    DCHECK_EQ(old_details.attributes(), new_details.attributes());
+    if (!old_details.representation().fits_into(new_details.representation())) {
       return MaybeHandle<Map>();
     }
-    PropertyType new_type = new_details.type();
-    PropertyType old_type = old_details.type();
     Object* new_value = new_descriptors->GetValue(i);
     Object* old_value = old_descriptors->GetValue(i);
-    switch (new_type) {
-      case FIELD:
-        if ((old_type == FIELD &&
-             !HeapType::cast(old_value)->NowIs(HeapType::cast(new_value))) ||
-            (old_type == CONSTANT &&
-             !HeapType::cast(new_value)->NowContains(old_value)) ||
-            (old_type == CALLBACKS &&
-             !HeapType::Any()->Is(HeapType::cast(new_value)))) {
-          return MaybeHandle<Map>();
+    switch (new_details.type()) {
+      case FIELD: {
+        PropertyType old_type = old_details.type();
+        if (old_type == FIELD) {
+          if (!HeapType::cast(old_value)->NowIs(HeapType::cast(new_value))) {
+            return MaybeHandle<Map>();
+          }
+        } else {
+          DCHECK(old_type == CONSTANT);
+          if (!HeapType::cast(new_value)->NowContains(old_value)) {
+            return MaybeHandle<Map>();
+          }
         }
         break;
+      }
+      case ACCESSOR_FIELD:
+        DCHECK(HeapType::Any()->Is(HeapType::cast(new_value)));
+        break;
 
       case CONSTANT:
       case CALLBACKS:
-        if (old_type != new_type || old_value != new_value) {
+        if (old_details.location() == IN_OBJECT || old_value != new_value) {
           return MaybeHandle<Map>();
         }
         break;
-
-      case NORMAL:
-        UNREACHABLE();
     }
   }
   if (new_map->NumberOfOwnDescriptors() != old_nof) return MaybeHandle<Map>();
@@ -2772,22 +2989,23 @@
 
 MaybeHandle<Object> JSObject::SetPropertyWithInterceptor(LookupIterator* it,
                                                          Handle<Object> value) {
-  // TODO(rossberg): Support symbols in the API.
-  if (it->name()->IsSymbol()) return value;
-
-  Handle<String> name_string = Handle<String>::cast(it->name());
+  Handle<Name> name = it->name();
   Handle<JSObject> holder = it->GetHolder<JSObject>();
   Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor());
-  if (interceptor->setter()->IsUndefined()) return MaybeHandle<Object>();
+  if (interceptor->setter()->IsUndefined() ||
+      (name->IsSymbol() && !interceptor->can_intercept_symbols())) {
+    return MaybeHandle<Object>();
+  }
 
   LOG(it->isolate(),
-      ApiNamedPropertyAccess("interceptor-named-set", *holder, *name_string));
+      ApiNamedPropertyAccess("interceptor-named-set", *holder, *name));
   PropertyCallbackArguments args(it->isolate(), interceptor->data(), *holder,
                                  *holder);
-  v8::NamedPropertySetterCallback setter =
-      v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
-  v8::Handle<v8::Value> result = args.Call(
-      setter, v8::Utils::ToLocal(name_string), v8::Utils::ToLocal(value));
+  v8::GenericNamedPropertySetterCallback setter =
+      v8::ToCData<v8::GenericNamedPropertySetterCallback>(
+          interceptor->setter());
+  v8::Handle<v8::Value> result =
+      args.Call(setter, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value));
   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object);
   if (!result.IsEmpty()) return value;
 
@@ -2807,7 +3025,8 @@
 MaybeHandle<Object> Object::SetProperty(LookupIterator* it,
                                         Handle<Object> value,
                                         StrictMode strict_mode,
-                                        StoreFromKeyed store_mode) {
+                                        StoreFromKeyed store_mode,
+                                        StorePropertyMode data_store_mode) {
   // Make sure that the top context does not change when doing callbacks or
   // interceptor calls.
   AssertNoContextChange ncc(it->isolate());
@@ -2902,6 +3121,14 @@
                     Object);
   }
 
+  if (data_store_mode == SUPER_PROPERTY) {
+    LookupIterator own_lookup(it->GetReceiver(), it->name(),
+                              LookupIterator::OWN);
+
+    return JSObject::SetProperty(&own_lookup, value, strict_mode, store_mode,
+                                 NORMAL_PROPERTY);
+  }
+
   return AddDataProperty(it, value, NONE, strict_mode, store_mode);
 }
 
@@ -2919,8 +3146,23 @@
 }
 
 
-Handle<Object> Object::SetDataProperty(LookupIterator* it,
-                                       Handle<Object> value) {
+MaybeHandle<Object> Object::WriteToReadOnlyElement(Isolate* isolate,
+                                                   Handle<Object> receiver,
+                                                   uint32_t index,
+                                                   Handle<Object> value,
+                                                   StrictMode strict_mode) {
+  if (strict_mode != STRICT) return value;
+
+  Handle<Object> args[] = {isolate->factory()->NewNumberFromUint(index),
+                           receiver};
+  THROW_NEW_ERROR(isolate, NewTypeError("strict_read_only_property",
+                                        HandleVector(args, arraysize(args))),
+                  Object);
+}
+
+
+MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it,
+                                            Handle<Object> value) {
   // Proxies are handled on the WithHandler path. Other non-JSObjects cannot
   // have own properties.
   Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver());
@@ -2931,9 +3173,8 @@
   // Old value for the observation change record.
   // Fetch before transforming the object since the encoding may become
   // incompatible with what's cached in |it|.
-  bool is_observed =
-      receiver->map()->is_observed() &&
-      !it->name().is_identical_to(it->factory()->hidden_string());
+  bool is_observed = receiver->map()->is_observed() &&
+                     !it->isolate()->IsInternallyUsedPropertyName(it->name());
   MaybeHandle<Object> maybe_old;
   if (is_observed) maybe_old = it->GetDataValue();
 
@@ -2942,12 +3183,14 @@
   it->PrepareForDataProperty(value);
 
   // Write the property value.
-  it->WriteDataValue(value);
+  value = it->WriteDataValue(value);
 
   // Send the change record if there are observers.
   if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) {
-    JSObject::EnqueueChangeRecord(receiver, "update", it->name(),
-                                  maybe_old.ToHandleChecked());
+    RETURN_ON_EXCEPTION(it->isolate(), JSObject::EnqueueChangeRecord(
+                                           receiver, "update", it->name(),
+                                           maybe_old.ToHandleChecked()),
+                        Object);
   }
 
   return value;
@@ -2971,6 +3214,10 @@
   // instead. If the prototype is Null, the proxy is detached.
   if (receiver->IsJSGlobalProxy()) return value;
 
+  // If the receiver is Indexed Exotic object (currently only typed arrays),
+  // disallow adding properties with numeric names.
+  if (it->IsSpecialNumericIndex()) return value;
+
   // Possibly migrate to the most up-to-date map that will be able to store
   // |value| under it->name() with |attributes|.
   it->PrepareTransitionToDataProperty(value, attributes, store_mode);
@@ -2992,14 +3239,16 @@
     JSObject::AddSlowProperty(receiver, it->name(), value, attributes);
   } else {
     // Write the property value.
-    it->WriteDataValue(value);
+    value = it->WriteDataValue(value);
   }
 
   // Send the change record if there are observers.
   if (receiver->map()->is_observed() &&
-      !it->name().is_identical_to(it->factory()->hidden_string())) {
-    JSObject::EnqueueChangeRecord(receiver, "add", it->name(),
-                                  it->factory()->the_hole_value());
+      !it->isolate()->IsInternallyUsedPropertyName(it->name())) {
+    RETURN_ON_EXCEPTION(it->isolate(), JSObject::EnqueueChangeRecord(
+                                           receiver, "add", it->name(),
+                                           it->factory()->the_hole_value()),
+                        Object);
   }
 
   return value;
@@ -3054,8 +3303,12 @@
   Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo(
       descriptors, old_size, slack);
 
+  DisallowHeapAllocation no_allocation;
+  // The descriptors are still the same, so keep the layout descriptor.
+  LayoutDescriptor* layout_descriptor = map->GetLayoutDescriptor();
+
   if (old_size == 0) {
-    map->set_instance_descriptors(*new_descriptors);
+    map->UpdateDescriptors(*new_descriptors, layout_descriptor);
     return;
   }
 
@@ -3077,10 +3330,10 @@
        current = walk_map->GetBackPointer()) {
     walk_map = Map::cast(current);
     if (walk_map->instance_descriptors() != *descriptors) break;
-    walk_map->set_instance_descriptors(*new_descriptors);
+    walk_map->UpdateDescriptors(*new_descriptors, layout_descriptor);
   }
 
-  map->set_instance_descriptors(*new_descriptors);
+  map->UpdateDescriptors(*new_descriptors, layout_descriptor);
 }
 
 
@@ -3280,6 +3533,21 @@
 }
 
 
+Handle<WeakCell> Map::WeakCellForMap(Handle<Map> map) {
+  Isolate* isolate = map->GetIsolate();
+  if (map->code_cache()->IsFixedArray()) {
+    return isolate->factory()->NewWeakCell(map);
+  }
+  Handle<CodeCache> code_cache(CodeCache::cast(map->code_cache()), isolate);
+  if (code_cache->weak_cell_cache()->IsWeakCell()) {
+    return Handle<WeakCell>(WeakCell::cast(code_cache->weak_cell_cache()));
+  }
+  Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(map);
+  code_cache->set_weak_cell_cache(*weak_cell);
+  return weak_cell;
+}
+
+
 static Handle<Map> AddMissingElementsTransitions(Handle<Map> map,
                                                  ElementsKind to_kind) {
   DCHECK(IsTransitionElementsKind(map->elements_kind()));
@@ -3742,15 +4010,6 @@
 }
 
 
-void JSObject::MigrateToNewProperty(Handle<JSObject> object,
-                                    Handle<Map> map,
-                                    Handle<Object> value) {
-  JSObject::MigrateToMap(object, map);
-  if (map->GetLastDescriptorDetails().type() != FIELD) return;
-  object->WriteToField(map->LastAdded(), *value);
-}
-
-
 void JSObject::WriteToField(int descriptor, Object* value) {
   DisallowHeapAllocation no_gc;
 
@@ -3763,11 +4022,15 @@
   if (details.representation().IsDouble()) {
     // Nothing more to be done.
     if (value->IsUninitialized()) return;
-    HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index));
-    DCHECK(box->IsMutableHeapNumber());
-    box->set_value(value->Number());
+    if (IsUnboxedDoubleField(index)) {
+      RawFastDoublePropertyAtPut(index, value->Number());
+    } else {
+      HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index));
+      DCHECK(box->IsMutableHeapNumber());
+      box->set_value(value->Number());
+    }
   } else {
-    FastPropertyAtPut(index, value);
+    RawFastPropertyAtPut(index, value);
   }
 }
 
@@ -3785,7 +4048,7 @@
   DCHECK(maybe.has_value);
   DCHECK(!it.IsFound());
   DCHECK(object->map()->is_extensible() ||
-         name.is_identical_to(it.isolate()->factory()->hidden_string()));
+         it.isolate()->IsInternallyUsedPropertyName(name));
 #endif
   AddDataProperty(&it, value, attributes, STRICT,
                   CERTAINLY_NOT_STORE_FROM_KEYED).Check();
@@ -3803,7 +4066,7 @@
   DCHECK(!value->IsTheHole());
   LookupIterator it(object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
   bool is_observed = object->map()->is_observed() &&
-                     *name != it.isolate()->heap()->hidden_string();
+                     !it.isolate()->IsInternallyUsedPropertyName(name);
   for (; it.IsFound(); it.Next()) {
     switch (it.state()) {
       case LookupIterator::INTERCEPTOR:
@@ -3820,20 +4083,11 @@
 
       case LookupIterator::ACCESSOR: {
         PropertyDetails details = it.property_details();
-        Handle<Object> old_value = it.isolate()->factory()->the_hole_value();
         // Ensure the context isn't changed after calling into accessors.
         AssertNoContextChange ncc(it.isolate());
 
         Handle<Object> accessors = it.GetAccessors();
 
-        if (is_observed && accessors->IsAccessorInfo()) {
-          ASSIGN_RETURN_ON_EXCEPTION(
-              it.isolate(), old_value,
-              GetPropertyWithAccessor(it.GetReceiver(), it.name(),
-                                      it.GetHolder<JSObject>(), accessors),
-              Object);
-        }
-
         // Special handling for ExecutableAccessorInfo, which behaves like a
         // data property.
         if (handling == DONT_FORCE_FIELD &&
@@ -3848,18 +4102,6 @@
           DCHECK(result->SameValue(*value));
 
           if (details.attributes() == attributes) {
-            // Regular property update if the attributes match.
-            if (is_observed && !old_value->SameValue(*value)) {
-              // If we are setting the prototype of a function and are
-              // observed, don't send change records because the prototype
-              // handles that itself.
-              if (!object->IsJSFunction() ||
-                  !Name::Equals(it.isolate()->factory()->prototype_string(),
-                                name) ||
-                  !Handle<JSFunction>::cast(object)->should_have_prototype()) {
-                EnqueueChangeRecord(object, "update", name, old_value);
-              }
-            }
             return value;
           }
 
@@ -3873,23 +4115,25 @@
           if (attributes & READ_ONLY) new_data->clear_setter();
           SetPropertyCallback(object, name, new_data, attributes);
           if (is_observed) {
-            if (old_value->SameValue(*value)) {
-              old_value = it.isolate()->factory()->the_hole_value();
-            }
-            EnqueueChangeRecord(object, "reconfigure", name, old_value);
+            RETURN_ON_EXCEPTION(
+                it.isolate(),
+                EnqueueChangeRecord(object, "reconfigure", name,
+                                    it.isolate()->factory()->the_hole_value()),
+                Object);
           }
           return value;
         }
 
         it.ReconfigureDataProperty(value, attributes);
         it.PrepareForDataProperty(value);
-        it.WriteDataValue(value);
+        value = it.WriteDataValue(value);
 
         if (is_observed) {
-          if (old_value->SameValue(*value)) {
-            old_value = it.isolate()->factory()->the_hole_value();
-          }
-          EnqueueChangeRecord(object, "reconfigure", name, old_value);
+          RETURN_ON_EXCEPTION(
+              it.isolate(),
+              EnqueueChangeRecord(object, "reconfigure", name,
+                                  it.isolate()->factory()->the_hole_value()),
+              Object);
         }
 
         return value;
@@ -3907,13 +4151,16 @@
 
         it.ReconfigureDataProperty(value, attributes);
         it.PrepareForDataProperty(value);
-        it.WriteDataValue(value);
+        value = it.WriteDataValue(value);
 
         if (is_observed) {
           if (old_value->SameValue(*value)) {
             old_value = it.isolate()->factory()->the_hole_value();
           }
-          EnqueueChangeRecord(object, "reconfigure", name, old_value);
+          RETURN_ON_EXCEPTION(
+              it.isolate(),
+              EnqueueChangeRecord(object, "reconfigure", name, old_value),
+              Object);
         }
 
         return value;
@@ -3930,9 +4177,6 @@
     Handle<JSObject> holder,
     Handle<Object> receiver,
     Handle<Name> name) {
-  // TODO(rossberg): Support symbols in the API.
-  if (name->IsSymbol()) return maybe(ABSENT);
-
   Isolate* isolate = holder->GetIsolate();
   HandleScope scope(isolate);
 
@@ -3941,26 +4185,29 @@
   AssertNoContextChange ncc(isolate);
 
   Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor());
+  if (name->IsSymbol() && !interceptor->can_intercept_symbols()) {
+    return maybe(ABSENT);
+  }
   PropertyCallbackArguments args(
       isolate, interceptor->data(), *receiver, *holder);
   if (!interceptor->query()->IsUndefined()) {
-    v8::NamedPropertyQueryCallback query =
-        v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query());
+    v8::GenericNamedPropertyQueryCallback query =
+        v8::ToCData<v8::GenericNamedPropertyQueryCallback>(
+            interceptor->query());
     LOG(isolate,
         ApiNamedPropertyAccess("interceptor-named-has", *holder, *name));
-    v8::Handle<v8::Integer> result =
-        args.Call(query, v8::Utils::ToLocal(Handle<String>::cast(name)));
+    v8::Handle<v8::Integer> result = args.Call(query, v8::Utils::ToLocal(name));
     if (!result.IsEmpty()) {
       DCHECK(result->IsInt32());
       return maybe(static_cast<PropertyAttributes>(result->Int32Value()));
     }
   } else if (!interceptor->getter()->IsUndefined()) {
-    v8::NamedPropertyGetterCallback getter =
-        v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
+    v8::GenericNamedPropertyGetterCallback getter =
+        v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
+            interceptor->getter());
     LOG(isolate,
         ApiNamedPropertyAccess("interceptor-named-get-has", *holder, *name));
-    v8::Handle<v8::Value> result =
-        args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name)));
+    v8::Handle<v8::Value> result = args.Call(getter, v8::Utils::ToLocal(name));
     if (!result.IsEmpty()) return maybe(DONT_ENUM);
   }
 
@@ -4019,9 +4266,8 @@
   // Check access rights if needed.
   if (object->IsAccessCheckNeeded()) {
     if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) {
-      isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS);
-      RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
-      return maybe(ABSENT);
+      return GetElementAttributesWithFailedAccessCheck(isolate, object,
+                                                       receiver, index);
     }
   }
 
@@ -4055,6 +4301,21 @@
   // callbacks or interceptor calls.
   AssertNoContextChange ncc(isolate);
 
+  Maybe<PropertyAttributes> from_interceptor =
+      GetElementAttributeFromInterceptor(object, receiver, index);
+  if (!from_interceptor.has_value) return Maybe<PropertyAttributes>();
+  if (from_interceptor.value != ABSENT) return maybe(from_interceptor.value);
+
+  return GetElementAttributeWithoutInterceptor(object, receiver, index,
+                                               check_prototype);
+}
+
+
+Maybe<PropertyAttributes> JSObject::GetElementAttributeFromInterceptor(
+    Handle<JSObject> object, Handle<Object> receiver, uint32_t index) {
+  Isolate* isolate = object->GetIsolate();
+  AssertNoContextChange ncc(isolate);
+
   Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
   PropertyCallbackArguments args(
       isolate, interceptor->data(), *receiver, *object);
@@ -4075,9 +4336,8 @@
     v8::Handle<v8::Value> result = args.Call(getter, index);
     if (!result.IsEmpty()) return maybe(NONE);
   }
-
-  return GetElementAttributeWithoutInterceptor(
-       object, receiver, index, check_prototype);
+  RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>());
+  return maybe(ABSENT);
 }
 
 
@@ -4154,11 +4414,12 @@
 
 void JSObject::NormalizeProperties(Handle<JSObject> object,
                                    PropertyNormalizationMode mode,
-                                   int expected_additional_properties) {
+                                   int expected_additional_properties,
+                                   const char* reason) {
   if (!object->HasFastProperties()) return;
 
   Handle<Map> map(object->map());
-  Handle<Map> new_map = Map::Normalize(map, mode);
+  Handle<Map> new_map = Map::Normalize(map, mode, reason);
 
   MigrateFastToSlow(object, new_map, expected_additional_properties);
 }
@@ -4190,41 +4451,45 @@
   Handle<DescriptorArray> descs(map->instance_descriptors());
   for (int i = 0; i < real_size; i++) {
     PropertyDetails details = descs->GetDetails(i);
+    Handle<Name> key(descs->GetKey(i));
     switch (details.type()) {
       case CONSTANT: {
-        Handle<Name> key(descs->GetKey(i));
         Handle<Object> value(descs->GetConstant(i), isolate);
-        PropertyDetails d = PropertyDetails(
-            details.attributes(), NORMAL, i + 1);
+        PropertyDetails d(details.attributes(), FIELD, i + 1);
         dictionary = NameDictionary::Add(dictionary, key, value, d);
         break;
       }
       case FIELD: {
-        Handle<Name> key(descs->GetKey(i));
         FieldIndex index = FieldIndex::ForDescriptor(*map, i);
-        Handle<Object> value(
-            object->RawFastPropertyAt(index), isolate);
-        if (details.representation().IsDouble()) {
-          DCHECK(value->IsMutableHeapNumber());
-          Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
-          value = isolate->factory()->NewHeapNumber(old->value());
+        Handle<Object> value;
+        if (object->IsUnboxedDoubleField(index)) {
+          double old_value = object->RawFastDoublePropertyAt(index);
+          value = isolate->factory()->NewHeapNumber(old_value);
+        } else {
+          value = handle(object->RawFastPropertyAt(index), isolate);
+          if (details.representation().IsDouble()) {
+            DCHECK(value->IsMutableHeapNumber());
+            Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
+            value = isolate->factory()->NewHeapNumber(old->value());
+          }
         }
-        PropertyDetails d =
-            PropertyDetails(details.attributes(), NORMAL, i + 1);
+        PropertyDetails d(details.attributes(), FIELD, i + 1);
+        dictionary = NameDictionary::Add(dictionary, key, value, d);
+        break;
+      }
+      case ACCESSOR_FIELD: {
+        FieldIndex index = FieldIndex::ForDescriptor(*map, i);
+        Handle<Object> value(object->RawFastPropertyAt(index), isolate);
+        PropertyDetails d(details.attributes(), CALLBACKS, i + 1);
         dictionary = NameDictionary::Add(dictionary, key, value, d);
         break;
       }
       case CALLBACKS: {
-        Handle<Name> key(descs->GetKey(i));
         Handle<Object> value(descs->GetCallbacksObject(i), isolate);
-        PropertyDetails d = PropertyDetails(
-            details.attributes(), CALLBACKS, i + 1);
+        PropertyDetails d(details.attributes(), CALLBACKS, i + 1);
         dictionary = NameDictionary::Add(dictionary, key, value, d);
         break;
       }
-      case NORMAL:
-        UNREACHABLE();
-        break;
     }
   }
 
@@ -4253,6 +4518,14 @@
 
   object->set_properties(*dictionary);
 
+  // Ensure that in-object space of slow-mode object does not contain random
+  // garbage.
+  int inobject_properties = new_map->inobject_properties();
+  for (int i = 0; i < inobject_properties; i++) {
+    FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
+    object->RawFastPropertyAtPut(index, Smi::FromInt(0));
+  }
+
   isolate->counters()->props_to_dictionary()->Increment();
 
 #ifdef DEBUG
@@ -4266,7 +4539,8 @@
 
 
 void JSObject::MigrateSlowToFast(Handle<JSObject> object,
-                                 int unused_property_fields) {
+                                 int unused_property_fields,
+                                 const char* reason) {
   if (object->HasFastProperties()) return;
   DCHECK(!object->IsGlobalObject());
   Isolate* isolate = object->GetIsolate();
@@ -4278,25 +4552,26 @@
   int number_of_elements = dictionary->NumberOfElements();
   if (number_of_elements > kMaxNumberOfDescriptors) return;
 
+  Handle<FixedArray> iteration_order;
   if (number_of_elements != dictionary->NextEnumerationIndex()) {
-    NameDictionary::DoGenerateNewEnumerationIndices(dictionary);
+    iteration_order =
+        NameDictionary::DoGenerateNewEnumerationIndices(dictionary);
+  } else {
+    iteration_order = NameDictionary::BuildIterationIndicesArray(dictionary);
   }
 
-  int instance_descriptor_length = 0;
+  int instance_descriptor_length = iteration_order->length();
   int number_of_fields = 0;
 
   // Compute the length of the instance descriptor.
-  int capacity = dictionary->Capacity();
-  for (int i = 0; i < capacity; i++) {
-    Object* k = dictionary->KeyAt(i);
-    if (dictionary->IsKey(k)) {
-      Object* value = dictionary->ValueAt(i);
-      PropertyType type = dictionary->DetailsAt(i).type();
-      DCHECK(type != FIELD);
-      instance_descriptor_length++;
-      if (type == NORMAL && !value->IsJSFunction()) {
-        number_of_fields += 1;
-      }
+  for (int i = 0; i < instance_descriptor_length; i++) {
+    int index = Smi::cast(iteration_order->get(i))->value();
+    DCHECK(dictionary->IsKey(dictionary->KeyAt(index)));
+
+    Object* value = dictionary->ValueAt(index);
+    PropertyType type = dictionary->DetailsAt(index).type();
+    if (type == FIELD && !value->IsJSFunction()) {
+      number_of_fields += 1;
     }
   }
 
@@ -4306,6 +4581,14 @@
   Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
   new_map->set_dictionary_map(false);
 
+#if TRACE_MAPS
+  if (FLAG_trace_maps) {
+    PrintF("[TraceMaps: SlowToFast from= %p to= %p reason= %s ]\n",
+           reinterpret_cast<void*>(object->map()),
+           reinterpret_cast<void*>(*new_map), reason);
+  }
+#endif
+
   if (instance_descriptor_length == 0) {
     DisallowHeapAllocation no_gc;
     DCHECK_LE(unused_property_fields, inobject_props);
@@ -4336,59 +4619,57 @@
 
   // Fill in the instance descriptor and the fields.
   int current_offset = 0;
-  for (int i = 0; i < capacity; i++) {
-    Object* k = dictionary->KeyAt(i);
-    if (dictionary->IsKey(k)) {
-      Object* value = dictionary->ValueAt(i);
-      Handle<Name> key;
-      if (k->IsSymbol()) {
-        key = handle(Symbol::cast(k));
-      } else {
-        // Ensure the key is a unique name before writing into the
-        // instance descriptor.
-        key = factory->InternalizeString(handle(String::cast(k)));
-      }
+  for (int i = 0; i < instance_descriptor_length; i++) {
+    int index = Smi::cast(iteration_order->get(i))->value();
+    Object* k = dictionary->KeyAt(index);
+    DCHECK(dictionary->IsKey(k));
 
-      PropertyDetails details = dictionary->DetailsAt(i);
-      int enumeration_index = details.dictionary_index();
-      PropertyType type = details.type();
+    Object* value = dictionary->ValueAt(index);
+    Handle<Name> key;
+    if (k->IsSymbol()) {
+      key = handle(Symbol::cast(k));
+    } else {
+      // Ensure the key is a unique name before writing into the
+      // instance descriptor.
+      key = factory->InternalizeString(handle(String::cast(k)));
+    }
 
-      if (value->IsJSFunction()) {
-        ConstantDescriptor d(key,
-                             handle(value, isolate),
-                             details.attributes());
-        descriptors->Set(enumeration_index - 1, &d);
-      } else if (type == NORMAL) {
-        if (current_offset < inobject_props) {
-          object->InObjectPropertyAtPut(current_offset,
-                                        value,
-                                        UPDATE_WRITE_BARRIER);
-        } else {
-          int offset = current_offset - inobject_props;
-          fields->set(offset, value);
-        }
-        FieldDescriptor d(key,
-                          current_offset++,
-                          details.attributes(),
-                          // TODO(verwaest): value->OptimalRepresentation();
-                          Representation::Tagged());
-        descriptors->Set(enumeration_index - 1, &d);
-      } else if (type == CALLBACKS) {
-        CallbacksDescriptor d(key,
-                              handle(value, isolate),
-                              details.attributes());
-        descriptors->Set(enumeration_index - 1, &d);
+    PropertyDetails details = dictionary->DetailsAt(index);
+    int enumeration_index = details.dictionary_index();
+    PropertyType type = details.type();
+
+    if (value->IsJSFunction()) {
+      ConstantDescriptor d(key, handle(value, isolate), details.attributes());
+      descriptors->Set(enumeration_index - 1, &d);
+    } else if (type == FIELD) {
+      if (current_offset < inobject_props) {
+        object->InObjectPropertyAtPut(current_offset, value,
+                                      UPDATE_WRITE_BARRIER);
       } else {
-        UNREACHABLE();
+        int offset = current_offset - inobject_props;
+        fields->set(offset, value);
       }
+      FieldDescriptor d(key, current_offset, details.attributes(),
+                        // TODO(verwaest): value->OptimalRepresentation();
+                        Representation::Tagged());
+      current_offset += d.GetDetails().field_width_in_words();
+      descriptors->Set(enumeration_index - 1, &d);
+    } else if (type == CALLBACKS) {
+      CallbacksDescriptor d(key, handle(value, isolate), details.attributes());
+      descriptors->Set(enumeration_index - 1, &d);
+    } else {
+      UNREACHABLE();
     }
   }
   DCHECK(current_offset == number_of_fields);
 
   descriptors->Sort();
 
+  Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New(
+      new_map, descriptors, descriptors->number_of_descriptors());
+
   DisallowHeapAllocation no_gc;
-  new_map->InitializeDescriptors(*descriptors);
+  new_map->InitializeDescriptors(*descriptors, *layout_descriptor);
   new_map->set_unused_property_fields(unused_property_fields);
 
   // Transform the object.
@@ -4436,7 +4717,7 @@
       value = handle(Handle<FixedArray>::cast(array)->get(i), isolate);
     }
     if (!value->IsTheHole()) {
-      PropertyDetails details = PropertyDetails(NONE, NORMAL, 0);
+      PropertyDetails details(NONE, FIELD, 0);
       dictionary =
           SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details);
     }
@@ -4766,20 +5047,20 @@
     Handle<JSObject> holder, Handle<JSObject> receiver, Handle<Name> name) {
   Isolate* isolate = holder->GetIsolate();
 
-  // TODO(rossberg): Support symbols in the API.
-  if (name->IsSymbol()) return MaybeHandle<Object>();
-
   Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor());
-  if (interceptor->deleter()->IsUndefined()) return MaybeHandle<Object>();
+  if (interceptor->deleter()->IsUndefined() ||
+      (name->IsSymbol() && !interceptor->can_intercept_symbols())) {
+    return MaybeHandle<Object>();
+  }
 
-  v8::NamedPropertyDeleterCallback deleter =
-      v8::ToCData<v8::NamedPropertyDeleterCallback>(interceptor->deleter());
+  v8::GenericNamedPropertyDeleterCallback deleter =
+      v8::ToCData<v8::GenericNamedPropertyDeleterCallback>(
+          interceptor->deleter());
   LOG(isolate,
       ApiNamedPropertyAccess("interceptor-named-delete", *holder, *name));
   PropertyCallbackArguments args(isolate, interceptor->data(), *receiver,
                                  *holder);
-  v8::Handle<v8::Boolean> result =
-      args.Call(deleter, v8::Utils::ToLocal(Handle<String>::cast(name)));
+  v8::Handle<v8::Boolean> result = args.Call(deleter, v8::Utils::ToLocal(name));
   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
   if (result.IsEmpty()) return MaybeHandle<Object>();
 
@@ -4890,7 +5171,9 @@
     if (!maybe.has_value) return MaybeHandle<Object>();
     if (!maybe.value) {
       Handle<String> name = factory->Uint32ToString(index);
-      EnqueueChangeRecord(object, "delete", name, old_value);
+      RETURN_ON_EXCEPTION(
+          isolate, EnqueueChangeRecord(object, "delete", name, old_value),
+          Object);
     }
   }
 
@@ -4917,7 +5200,7 @@
   LookupIterator it(object, name, config);
 
   bool is_observed = object->map()->is_observed() &&
-                     *name != it.isolate()->heap()->hidden_string();
+                     !it.isolate()->IsInternallyUsedPropertyName(name);
   Handle<Object> old_value = it.isolate()->factory()->the_hole_value();
 
   for (; it.IsFound(); it.Next()) {
@@ -4970,13 +5253,15 @@
             !(object->IsJSGlobalProxy() && holder->IsJSGlobalObject())) {
           return it.isolate()->factory()->true_value();
         }
-        NormalizeProperties(holder, mode, 0);
+        NormalizeProperties(holder, mode, 0, "DeletingProperty");
         Handle<Object> result =
             DeleteNormalizedProperty(holder, name, delete_mode);
         ReoptimizeIfPrototype(holder);
 
         if (is_observed) {
-          EnqueueChangeRecord(object, "delete", name, old_value);
+          RETURN_ON_EXCEPTION(
+              it.isolate(),
+              EnqueueChangeRecord(object, "delete", name, old_value), Object);
         }
 
         return result;
@@ -5132,7 +5417,7 @@
     if (context->has_extension() && !context->IsCatchContext()) {
       // With harmony scoping, a JSFunction may have a global context.
       // TODO(mvstanton): walk into the ScopeInfo.
-      if (FLAG_harmony_scoping && context->IsGlobalContext()) {
+      if (FLAG_harmony_scoping && context->IsScriptContext()) {
         return false;
       }
 
@@ -5146,10 +5431,14 @@
 
 
 MaybeHandle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
-  Isolate* isolate = object->GetIsolate();
-
   if (!object->map()->is_extensible()) return object;
 
+  if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) {
+    return PreventExtensionsWithTransition<NONE>(object);
+  }
+
+  Isolate* isolate = object->GetIsolate();
+
   if (object->IsAccessCheckNeeded() &&
       !isolate->MayNamedAccess(
           object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
@@ -5186,36 +5475,62 @@
   // Do a map transition, other objects with this map may still
   // be extensible.
   // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
-  Handle<Map> new_map = Map::Copy(handle(object->map()));
+  Handle<Map> new_map = Map::Copy(handle(object->map()), "PreventExtensions");
 
   new_map->set_is_extensible(false);
   JSObject::MigrateToMap(object, new_map);
   DCHECK(!object->map()->is_extensible());
 
   if (object->map()->is_observed()) {
-    EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
-                        isolate->factory()->the_hole_value());
+    RETURN_ON_EXCEPTION(
+        isolate,
+        EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(),
+                            isolate->factory()->the_hole_value()),
+        Object);
   }
   return object;
 }
 
 
-template<typename Dictionary>
-static void FreezeDictionary(Dictionary* dictionary) {
+Handle<SeededNumberDictionary> JSObject::GetNormalizedElementDictionary(
+    Handle<JSObject> object) {
+  DCHECK(!object->elements()->IsDictionary());
+  Isolate* isolate = object->GetIsolate();
+  int length = object->IsJSArray()
+                   ? Smi::cast(Handle<JSArray>::cast(object)->length())->value()
+                   : object->elements()->length();
+  if (length > 0) {
+    int capacity = 0;
+    int used = 0;
+    object->GetElementsCapacityAndUsage(&capacity, &used);
+    Handle<SeededNumberDictionary> new_element_dictionary =
+        SeededNumberDictionary::New(isolate, used);
+
+    // Move elements to a dictionary; avoid calling NormalizeElements to avoid
+    // unnecessary transitions.
+    return CopyFastElementsToDictionary(handle(object->elements()), length,
+                                        new_element_dictionary);
+  }
+  // No existing elements, use a pre-allocated empty backing store
+  return isolate->factory()->empty_slow_element_dictionary();
+}
+
+
+template <typename Dictionary>
+static void ApplyAttributesToDictionary(Dictionary* dictionary,
+                                        const PropertyAttributes attributes) {
   int capacity = dictionary->Capacity();
   for (int i = 0; i < capacity; i++) {
     Object* k = dictionary->KeyAt(i);
     if (dictionary->IsKey(k) &&
         !(k->IsSymbol() && Symbol::cast(k)->is_private())) {
       PropertyDetails details = dictionary->DetailsAt(i);
-      int attrs = DONT_DELETE;
+      int attrs = attributes;
       // READ_ONLY is an invalid attribute for JS setters/getters.
-      if (details.type() == CALLBACKS) {
+      if ((attributes & READ_ONLY) && details.type() == CALLBACKS) {
         Object* v = dictionary->ValueAt(i);
         if (v->IsPropertyCell()) v = PropertyCell::cast(v)->value();
-        if (!v->IsAccessorPair()) attrs |= READ_ONLY;
-      } else {
-        attrs |= READ_ONLY;
+        if (v->IsAccessorPair()) attrs &= ~READ_ONLY;
       }
       details = details.CopyAddAttributes(
           static_cast<PropertyAttributes>(attrs));
@@ -5225,13 +5540,15 @@
 }
 
 
-MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) {
-  // Freezing sloppy arguments should be handled elsewhere.
+template <PropertyAttributes attrs>
+MaybeHandle<Object> JSObject::PreventExtensionsWithTransition(
+    Handle<JSObject> object) {
+  STATIC_ASSERT(attrs == NONE || attrs == SEALED || attrs == FROZEN);
+
+  // Sealing/freezing sloppy arguments should be handled elsewhere.
   DCHECK(!object->HasSloppyArgumentsElements());
   DCHECK(!object->map()->is_observed());
 
-  if (object->map()->is_frozen()) return object;
-
   Isolate* isolate = object->GetIsolate();
   if (object->IsAccessCheckNeeded() &&
       !isolate->MayNamedAccess(
@@ -5245,10 +5562,11 @@
     PrototypeIterator iter(isolate, object);
     if (iter.IsAtEnd()) return object;
     DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject());
-    return Freeze(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
+    return PreventExtensionsWithTransition<attrs>(
+        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
   }
 
-  // It's not possible to freeze objects with external array elements
+  // It's not possible to seal or freeze objects with external array elements
   if (object->HasExternalArrayElements() ||
       object->HasFixedTypedArrayElements()) {
     THROW_NEW_ERROR(isolate,
@@ -5259,54 +5577,48 @@
 
   Handle<SeededNumberDictionary> new_element_dictionary;
   if (!object->elements()->IsDictionary()) {
-    int length = object->IsJSArray()
-        ? Smi::cast(Handle<JSArray>::cast(object)->length())->value()
-        : object->elements()->length();
-    if (length > 0) {
-      int capacity = 0;
-      int used = 0;
-      object->GetElementsCapacityAndUsage(&capacity, &used);
-      new_element_dictionary = SeededNumberDictionary::New(isolate, used);
+    new_element_dictionary = GetNormalizedElementDictionary(object);
+  }
 
-      // Move elements to a dictionary; avoid calling NormalizeElements to avoid
-      // unnecessary transitions.
-      new_element_dictionary = CopyFastElementsToDictionary(
-          handle(object->elements()), length, new_element_dictionary);
-    } else {
-      // No existing elements, use a pre-allocated empty backing store
-      new_element_dictionary =
-          isolate->factory()->empty_slow_element_dictionary();
-    }
+  Handle<Symbol> transition_marker;
+  if (attrs == NONE) {
+    transition_marker = isolate->factory()->nonextensible_symbol();
+  } else if (attrs == SEALED) {
+    transition_marker = isolate->factory()->sealed_symbol();
+  } else {
+    DCHECK(attrs == FROZEN);
+    transition_marker = isolate->factory()->frozen_symbol();
   }
 
   Handle<Map> old_map(object->map(), isolate);
-  int transition_index = old_map->SearchTransition(
-      isolate->heap()->frozen_symbol());
+  int transition_index = old_map->SearchSpecialTransition(*transition_marker);
   if (transition_index != TransitionArray::kNotFound) {
     Handle<Map> transition_map(old_map->GetTransition(transition_index));
     DCHECK(transition_map->has_dictionary_elements());
-    DCHECK(transition_map->is_frozen());
     DCHECK(!transition_map->is_extensible());
     JSObject::MigrateToMap(object, transition_map);
   } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
-    // Create a new descriptor array with fully-frozen properties
-    Handle<Map> new_map = Map::CopyForFreeze(old_map);
+    // Create a new descriptor array with the appropriate property attributes
+    Handle<Map> new_map = Map::CopyForPreventExtensions(
+        old_map, attrs, transition_marker, "CopyForPreventExtensions");
     JSObject::MigrateToMap(object, new_map);
   } else {
     DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map());
     // Slow path: need to normalize properties for safety
-    NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
+    NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0,
+                        "SlowPreventExtensions");
 
     // Create a new map, since other objects with this map may be extensible.
     // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps.
-    Handle<Map> new_map = Map::Copy(handle(object->map()));
-    new_map->freeze();
+    Handle<Map> new_map =
+        Map::Copy(handle(object->map()), "SlowCopyForPreventExtensions");
     new_map->set_is_extensible(false);
     new_map->set_elements_kind(DICTIONARY_ELEMENTS);
     JSObject::MigrateToMap(object, new_map);
 
-    // Freeze dictionary-mode properties
-    FreezeDictionary(object->property_dictionary());
+    if (attrs != NONE) {
+      ApplyAttributesToDictionary(object->property_dictionary(), attrs);
+    }
   }
 
   DCHECK(object->map()->has_dictionary_elements());
@@ -5318,14 +5630,25 @@
     SeededNumberDictionary* dictionary = object->element_dictionary();
     // Make sure we never go back to the fast case
     dictionary->set_requires_slow_elements();
-    // Freeze all elements in the dictionary
-    FreezeDictionary(dictionary);
+    if (attrs != NONE) {
+      ApplyAttributesToDictionary(dictionary, attrs);
+    }
   }
 
   return object;
 }
 
 
+MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) {
+  return PreventExtensionsWithTransition<FROZEN>(object);
+}
+
+
+MaybeHandle<Object> JSObject::Seal(Handle<JSObject> object) {
+  return PreventExtensionsWithTransition<SEALED>(object);
+}
+
+
 void JSObject::SetObserved(Handle<JSObject> object) {
   DCHECK(!object->IsJSGlobalProxy());
   DCHECK(!object->IsJSGlobalObject());
@@ -5333,15 +5656,15 @@
   Handle<Map> new_map;
   Handle<Map> old_map(object->map(), isolate);
   DCHECK(!old_map->is_observed());
-  int transition_index = old_map->SearchTransition(
-      isolate->heap()->observed_symbol());
+  int transition_index =
+      old_map->SearchSpecialTransition(isolate->heap()->observed_symbol());
   if (transition_index != TransitionArray::kNotFound) {
     new_map = handle(old_map->GetTransition(transition_index), isolate);
     DCHECK(new_map->is_observed());
   } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) {
     new_map = Map::CopyForObserved(old_map);
   } else {
-    new_map = Map::Copy(old_map);
+    new_map = Map::Copy(old_map, "SlowObserved");
     new_map->set_is_observed();
   }
   JSObject::MigrateToMap(object, new_map);
@@ -5352,6 +5675,10 @@
                                         Representation representation,
                                         FieldIndex index) {
   Isolate* isolate = object->GetIsolate();
+  if (object->IsUnboxedDoubleField(index)) {
+    double value = object->RawFastDoublePropertyAt(index);
+    return isolate->factory()->NewHeapNumber(value);
+  }
   Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate);
   return Object::WrapForRead(isolate, raw_value, representation);
 }
@@ -5442,18 +5769,28 @@
         PropertyDetails details = descriptors->GetDetails(i);
         if (details.type() != FIELD) continue;
         FieldIndex index = FieldIndex::ForDescriptor(copy->map(), i);
-        Handle<Object> value(object->RawFastPropertyAt(index), isolate);
-        if (value->IsJSObject()) {
-          ASSIGN_RETURN_ON_EXCEPTION(
-              isolate, value,
-              VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
-              JSObject);
+        if (object->IsUnboxedDoubleField(index)) {
+          if (copying) {
+            double value = object->RawFastDoublePropertyAt(index);
+            copy->RawFastDoublePropertyAtPut(index, value);
+          }
         } else {
-          Representation representation = details.representation();
-          value = Object::NewStorageFor(isolate, value, representation);
-        }
-        if (copying) {
-          copy->FastPropertyAtPut(index, *value);
+          Handle<Object> value(object->RawFastPropertyAt(index), isolate);
+          if (value->IsJSObject()) {
+            ASSIGN_RETURN_ON_EXCEPTION(
+                isolate, value,
+                VisitElementOrProperty(copy, Handle<JSObject>::cast(value)),
+                JSObject);
+            if (copying) {
+              copy->FastPropertyAtPut(index, *value);
+            }
+          } else {
+            if (copying) {
+              Representation representation = details.representation();
+              value = Object::NewStorageFor(isolate, value, representation);
+              copy->FastPropertyAtPut(index, *value);
+            }
+          }
         }
       }
     } else {
@@ -5650,16 +5987,17 @@
 
 
 int Map::NextFreePropertyIndex() {
-  int max_index = -1;
+  int free_index = 0;
   int number_of_own_descriptors = NumberOfOwnDescriptors();
   DescriptorArray* descs = instance_descriptors();
   for (int i = 0; i < number_of_own_descriptors; i++) {
-    if (descs->GetType(i) == FIELD) {
-      int current_index = descs->GetFieldIndex(i);
-      if (current_index > max_index) max_index = current_index;
+    PropertyDetails details = descs->GetDetails(i);
+    if (details.type() == FIELD) {
+      int candidate = details.field_index() + details.field_width_in_words();
+      if (candidate > free_index) free_index = candidate;
     }
   }
-  return max_index + 1;
+  return free_index;
 }
 
 
@@ -5667,7 +6005,7 @@
   int len = array->length();
   for (int i = 0; i < len; i++) {
     Object* e = array->get(i);
-    if (!(e->IsString() || e->IsNumber())) return false;
+    if (!(e->IsName() || e->IsNumber())) return false;
   }
   return true;
 }
@@ -5875,14 +6213,14 @@
         FixedArray);
     DCHECK(ContainsOnlyValidKeys(content));
 
-    // Add the property keys from the interceptor.
+    // Add the non-symbol property keys from the interceptor.
     if (current->HasNamedInterceptor()) {
       Handle<JSObject> result;
       if (JSObject::GetKeysForNamedInterceptor(
               current, object).ToHandle(&result)) {
         ASSIGN_RETURN_ON_EXCEPTION(
-            isolate, content,
-            FixedArray::AddKeysFromArrayLike(content, result),
+            isolate, content, FixedArray::AddKeysFromArrayLike(
+                                  content, result, FixedArray::NON_SYMBOL_KEYS),
             FixedArray);
       }
       DCHECK(ContainsOnlyValidKeys(content));
@@ -6058,13 +6396,20 @@
                                        ? KEEP_INOBJECT_PROPERTIES
                                        : CLEAR_INOBJECT_PROPERTIES;
   // Normalize object to make this operation simple.
-  NormalizeProperties(object, mode, 0);
+  NormalizeProperties(object, mode, 0, "SetPropertyCallback");
 
   // For the global object allocate a new map to invalidate the global inline
   // caches which have a global property cell reference directly in the code.
   if (object->IsGlobalObject()) {
     Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
     DCHECK(new_map->is_dictionary_map());
+#if TRACE_MAPS
+    if (FLAG_trace_maps) {
+      PrintF("[TraceMaps: GlobalPropertyCallback from= %p to= %p ]\n",
+             reinterpret_cast<void*>(object->map()),
+             reinterpret_cast<void*>(*new_map));
+    }
+#endif
     JSObject::MigrateToMap(object, new_map);
 
     // When running crankshaft, changing the map is not enough. We
@@ -6116,7 +6461,7 @@
 
   Handle<Object> old_value = isolate->factory()->the_hole_value();
   bool is_observed = object->map()->is_observed() &&
-                     *name != isolate->heap()->hidden_string();
+                     !isolate->IsInternallyUsedPropertyName(name);
   bool preexists = false;
   if (is_observed) {
     if (is_element) {
@@ -6167,7 +6512,8 @@
 
   if (is_observed) {
     const char* type = preexists ? "reconfigure" : "add";
-    EnqueueChangeRecord(object, type, name, old_value);
+    RETURN_ON_EXCEPTION(
+        isolate, EnqueueChangeRecord(object, type, name, old_value), Object);
   }
 
   return isolate->factory()->undefined_value();
@@ -6336,17 +6682,27 @@
   if (HasFastProperties()) {
     int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
     DescriptorArray* descs = map()->instance_descriptors();
+    bool value_is_number = value->IsNumber();
     for (int i = 0; i < number_of_own_descriptors; i++) {
       if (descs->GetType(i) == FIELD) {
-        Object* property =
-            RawFastPropertyAt(FieldIndex::ForDescriptor(map(), i));
-        if (descs->GetDetails(i).representation().IsDouble()) {
-          DCHECK(property->IsMutableHeapNumber());
-          if (value->IsNumber() && property->Number() == value->Number()) {
+        FieldIndex field_index = FieldIndex::ForDescriptor(map(), i);
+        if (IsUnboxedDoubleField(field_index)) {
+          if (value_is_number) {
+            double property = RawFastDoublePropertyAt(field_index);
+            if (property == value->Number()) {
+              return descs->GetKey(i);
+            }
+          }
+        } else {
+          Object* property = RawFastPropertyAt(field_index);
+          if (field_index.is_double()) {
+            DCHECK(property->IsMutableHeapNumber());
+            if (value_is_number && property->Number() == value->Number()) {
+              return descs->GetKey(i);
+            }
+          } else if (property == value) {
             return descs->GetKey(i);
           }
-        } else if (property == value) {
-          return descs->GetKey(i);
         }
       } else if (descs->GetType(i) == CONSTANT) {
         if (descs->GetConstant(i) == value) {
@@ -6364,7 +6720,7 @@
 Handle<Map> Map::RawCopy(Handle<Map> map, int instance_size) {
   Handle<Map> result = map->GetIsolate()->factory()->NewMap(
       map->instance_type(), instance_size);
-  result->set_prototype(map->prototype());
+  result->SetPrototype(handle(map->prototype(), map->GetIsolate()));
   result->set_constructor(map->constructor());
   result->set_bit_field(map->bit_field());
   result->set_bit_field2(map->bit_field2());
@@ -6377,15 +6733,14 @@
   if (!map->is_dictionary_map()) {
     new_bit_field3 = IsUnstable::update(new_bit_field3, false);
   }
-  new_bit_field3 = ConstructionCount::update(new_bit_field3,
-                                             JSFunction::kNoSlackTracking);
+  new_bit_field3 = Counter::update(new_bit_field3, kRetainingCounterStart);
   result->set_bit_field3(new_bit_field3);
   return result;
 }
 
 
-Handle<Map> Map::Normalize(Handle<Map> fast_map,
-                           PropertyNormalizationMode mode) {
+Handle<Map> Map::Normalize(Handle<Map> fast_map, PropertyNormalizationMode mode,
+                           const char* reason) {
   DCHECK(!fast_map->is_dictionary_map());
 
   Isolate* isolate = fast_map->GetIsolate();
@@ -6424,6 +6779,13 @@
       cache->Set(fast_map, new_map);
       isolate->counters()->normalized_maps()->Increment();
     }
+#if TRACE_MAPS
+    if (FLAG_trace_maps) {
+      PrintF("[TraceMaps: Normalize from= %p to= %p reason= %s ]\n",
+             reinterpret_cast<void*>(*fast_map),
+             reinterpret_cast<void*>(*new_map), reason);
+    }
+#endif
   }
   fast_map->NotifyLeafMapLayoutChange();
   return new_map;
@@ -6487,50 +6849,99 @@
     if (old_size == 0) {
       descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1);
     } else {
-      EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2);
+      EnsureDescriptorSlack(
+          map, SlackForArraySize(old_size, kMaxNumberOfDescriptors));
       descriptors = handle(map->instance_descriptors());
     }
   }
 
+  Handle<LayoutDescriptor> layout_descriptor =
+      FLAG_unbox_double_fields
+          ? LayoutDescriptor::Append(map, descriptor->GetDetails())
+          : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate());
+
   {
     DisallowHeapAllocation no_gc;
     descriptors->Append(descriptor);
-    result->InitializeDescriptors(*descriptors);
+    result->InitializeDescriptors(*descriptors, *layout_descriptor);
   }
 
   DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
-  ConnectTransition(map, result, name, SIMPLE_TRANSITION);
+  ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION);
 
   return result;
 }
 
 
+#if TRACE_MAPS
+
+// static
+void Map::TraceTransition(const char* what, Map* from, Map* to, Name* name) {
+  if (FLAG_trace_maps) {
+    PrintF("[TraceMaps: %s from= %p to= %p name= ", what,
+           reinterpret_cast<void*>(from), reinterpret_cast<void*>(to));
+    name->NameShortPrint();
+    PrintF(" ]\n");
+  }
+}
+
+
+// static
+void Map::TraceAllTransitions(Map* map) {
+  if (!map->HasTransitionArray()) return;
+  TransitionArray* transitions = map->transitions();
+  for (int i = 0; i < transitions->number_of_transitions(); ++i) {
+    Map* target = transitions->GetTarget(i);
+    Map::TraceTransition("Transition", map, target, transitions->GetKey(i));
+    Map::TraceAllTransitions(target);
+  }
+}
+
+#endif  // TRACE_MAPS
+
+
 void Map::ConnectTransition(Handle<Map> parent, Handle<Map> child,
                             Handle<Name> name, SimpleTransitionFlag flag) {
   parent->set_owns_descriptors(false);
   if (parent->is_prototype_map()) {
     DCHECK(child->is_prototype_map());
+#if TRACE_MAPS
+    Map::TraceTransition("NoTransition", *parent, *child, *name);
+#endif
   } else {
     Handle<TransitionArray> transitions =
-        TransitionArray::CopyInsert(parent, name, child, flag);
-    parent->set_transitions(*transitions);
+        TransitionArray::Insert(parent, name, child, flag);
+    if (!parent->HasTransitionArray() ||
+        *transitions != parent->transitions()) {
+      parent->set_transitions(*transitions);
+    }
     child->SetBackPointer(*parent);
+    if (child->prototype()->IsJSObject()) {
+      Handle<JSObject> proto(JSObject::cast(child->prototype()));
+      if (!child->ShouldRegisterAsPrototypeUser(proto)) {
+        JSObject::UnregisterPrototypeUser(proto, child);
+      }
+    }
+#if TRACE_MAPS
+    Map::TraceTransition("Transition", *parent, *child, *name);
+#endif
   }
 }
 
 
-Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map,
-                                        Handle<DescriptorArray> descriptors,
-                                        TransitionFlag flag,
-                                        MaybeHandle<Name> maybe_name,
-                                        SimpleTransitionFlag simple_flag) {
+Handle<Map> Map::CopyReplaceDescriptors(
+    Handle<Map> map, Handle<DescriptorArray> descriptors,
+    Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
+    MaybeHandle<Name> maybe_name, const char* reason,
+    SimpleTransitionFlag simple_flag) {
   DCHECK(descriptors->IsSortedNoDuplicates());
 
   Handle<Map> result = CopyDropDescriptors(map);
-  result->InitializeDescriptors(*descriptors);
 
   if (!map->is_prototype_map()) {
     if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) {
+      result->InitializeDescriptors(*descriptors, *layout_descriptor);
+
       Handle<Name> name;
       CHECK(maybe_name.ToHandle(&name));
       ConnectTransition(map, result, name, simple_flag);
@@ -6542,8 +6953,22 @@
           descriptors->SetValue(i, HeapType::Any());
         }
       }
+      result->InitializeDescriptors(*descriptors,
+                                    LayoutDescriptor::FastPointerLayout());
     }
+  } else {
+    result->InitializeDescriptors(*descriptors, *layout_descriptor);
   }
+#if TRACE_MAPS
+  if (FLAG_trace_maps &&
+      // Mirror conditions above that did not call ConnectTransition().
+      (map->is_prototype_map() ||
+       !(flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()))) {
+    PrintF("[TraceMaps: ReplaceDescriptors from= %p to= %p reason= %s ]\n",
+           reinterpret_cast<void*>(*map), reinterpret_cast<void*>(*result),
+           reason);
+  }
+#endif
 
   return result;
 }
@@ -6551,28 +6976,37 @@
 
 // Since this method is used to rewrite an existing transition tree, it can
 // always insert transitions without checking.
-Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
-                                        int new_descriptor,
-                                        Handle<DescriptorArray> descriptors) {
+Handle<Map> Map::CopyInstallDescriptors(
+    Handle<Map> map, int new_descriptor, Handle<DescriptorArray> descriptors,
+    Handle<LayoutDescriptor> full_layout_descriptor) {
   DCHECK(descriptors->IsSortedNoDuplicates());
 
   Handle<Map> result = CopyDropDescriptors(map);
 
-  result->InitializeDescriptors(*descriptors);
+  result->set_instance_descriptors(*descriptors);
   result->SetNumberOfOwnDescriptors(new_descriptor + 1);
 
   int unused_property_fields = map->unused_property_fields();
-  if (descriptors->GetDetails(new_descriptor).type() == FIELD) {
+  PropertyDetails details = descriptors->GetDetails(new_descriptor);
+  if (details.type() == FIELD) {
     unused_property_fields = map->unused_property_fields() - 1;
     if (unused_property_fields < 0) {
       unused_property_fields += JSObject::kFieldsAdded;
     }
   }
-
   result->set_unused_property_fields(unused_property_fields);
 
+  if (FLAG_unbox_double_fields) {
+    Handle<LayoutDescriptor> layout_descriptor =
+        LayoutDescriptor::AppendIfFastOrUseFull(map, details,
+                                                full_layout_descriptor);
+    result->set_layout_descriptor(*layout_descriptor);
+    SLOW_DCHECK(result->layout_descriptor()->IsConsistentWithMap(*result));
+    result->set_visitor_id(StaticVisitorBase::GetVisitorId(*result));
+  }
+
   Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
-  ConnectTransition(map, result, name, SIMPLE_TRANSITION);
+  ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION);
 
   return result;
 }
@@ -6593,8 +7027,9 @@
     DCHECK(kind != map->elements_kind());
   }
 
-  bool insert_transition =
-      flag == INSERT_TRANSITION && !map->HasElementsTransition();
+  bool insert_transition = flag == INSERT_TRANSITION &&
+                           map->CanHaveMoreTransitions() &&
+                           !map->HasElementsTransition();
 
   if (insert_transition && map->owns_descriptors()) {
     // In case the map owned its own descriptors, share the descriptors and
@@ -6604,14 +7039,16 @@
     ConnectElementsTransition(map, new_map);
 
     new_map->set_elements_kind(kind);
-    new_map->InitializeDescriptors(map->instance_descriptors());
+    // The properties did not change, so reuse descriptors.
+    new_map->InitializeDescriptors(map->instance_descriptors(),
+                                   map->GetLayoutDescriptor());
     return new_map;
   }
 
   // In case the map did not own its own descriptors, a split is forced by
   // copying the map; creating a new descriptor array cell.
   // Create a new free-floating map only if we are not allowed to store it.
-  Handle<Map> new_map = Copy(map);
+  Handle<Map> new_map = Copy(map, "CopyAsElementsKind");
 
   new_map->set_elements_kind(kind);
 
@@ -6635,33 +7072,40 @@
     new_map = CopyDropDescriptors(map);
   } else {
     DCHECK(!map->is_prototype_map());
-    new_map = Copy(map);
+    new_map = Copy(map, "CopyForObserved");
   }
 
   new_map->set_is_observed();
   if (map->owns_descriptors()) {
-    new_map->InitializeDescriptors(map->instance_descriptors());
+    // The properties did not change, so reuse descriptors.
+    new_map->InitializeDescriptors(map->instance_descriptors(),
+                                   map->GetLayoutDescriptor());
   }
 
-  Handle<Name> name = isolate->factory()->observed_symbol();
-  ConnectTransition(map, new_map, name, FULL_TRANSITION);
-
+  if (map->CanHaveMoreTransitions()) {
+    Handle<Name> name = isolate->factory()->observed_symbol();
+    ConnectTransition(map, new_map, name, SPECIAL_TRANSITION);
+  }
   return new_map;
 }
 
 
-Handle<Map> Map::Copy(Handle<Map> map) {
+Handle<Map> Map::Copy(Handle<Map> map, const char* reason) {
   Handle<DescriptorArray> descriptors(map->instance_descriptors());
   int number_of_own_descriptors = map->NumberOfOwnDescriptors();
   Handle<DescriptorArray> new_descriptors =
       DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
-  return CopyReplaceDescriptors(
-      map, new_descriptors, OMIT_TRANSITION, MaybeHandle<Name>());
+  Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
+                                                 map->GetIsolate());
+  return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
+                                OMIT_TRANSITION, MaybeHandle<Name>(), reason,
+                                SPECIAL_TRANSITION);
 }
 
 
 Handle<Map> Map::Create(Isolate* isolate, int inobject_properties) {
-  Handle<Map> copy = Copy(handle(isolate->object_function()->initial_map()));
+  Handle<Map> copy =
+      Copy(handle(isolate->object_function()->initial_map()), "MapCreate");
 
   // Check that we do not overflow the instance size when adding the extra
   // inobject properties. If the instance size overflows, we allocate as many
@@ -6685,14 +7129,20 @@
 }
 
 
-Handle<Map> Map::CopyForFreeze(Handle<Map> map) {
+Handle<Map> Map::CopyForPreventExtensions(Handle<Map> map,
+                                          PropertyAttributes attrs_to_add,
+                                          Handle<Symbol> transition_marker,
+                                          const char* reason) {
   int num_descriptors = map->NumberOfOwnDescriptors();
   Isolate* isolate = map->GetIsolate();
   Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes(
-      handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN);
+      handle(map->instance_descriptors(), isolate), num_descriptors,
+      attrs_to_add);
+  Handle<LayoutDescriptor> new_layout_descriptor(map->GetLayoutDescriptor(),
+                                                 isolate);
   Handle<Map> new_map = CopyReplaceDescriptors(
-      map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol());
-  new_map->freeze();
+      map, new_desc, new_layout_descriptor, INSERT_TRANSITION,
+      transition_marker, reason, SPECIAL_TRANSITION);
   new_map->set_is_extensible(false);
   new_map->set_elements_kind(DICTIONARY_ELEMENTS);
   return new_map;
@@ -6711,12 +7161,9 @@
              value->FitsRepresentation(details.representation()));
       return GetConstant(descriptor) == value;
 
+    case ACCESSOR_FIELD:
     case CALLBACKS:
       return false;
-
-    case NORMAL:
-      UNREACHABLE();
-      break;
   }
 
   UNREACHABLE();
@@ -6741,7 +7188,7 @@
   Handle<HeapType> type = value->OptimalType(isolate, representation);
 
   return GeneralizeRepresentation(map, descriptor, representation, type,
-                                  FORCE_FIELD);
+                                  FORCE_IN_OBJECT);
 }
 
 
@@ -6755,16 +7202,14 @@
   // Migrate to the newest map before storing the property.
   map = Update(map);
 
-  int index = map->SearchTransition(*name);
+  int index = map->SearchTransition(DATA, *name, attributes);
   if (index != TransitionArray::kNotFound) {
     Handle<Map> transition(map->GetTransition(index));
     int descriptor = transition->LastAdded();
 
-    // TODO(verwaest): Handle attributes better.
-    DescriptorArray* descriptors = transition->instance_descriptors();
-    if (descriptors->GetDetails(descriptor).attributes() != attributes) {
-      return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES);
-    }
+    DCHECK_EQ(attributes, transition->instance_descriptors()
+                              ->GetDetails(descriptor)
+                              .attributes());
 
     return Map::PrepareForDataProperty(transition, descriptor, value);
   }
@@ -6783,7 +7228,17 @@
 
   Handle<Map> result;
   if (!maybe_map.ToHandle(&result)) {
-    return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES);
+#if TRACE_MAPS
+    if (FLAG_trace_maps) {
+      Vector<char> name_buffer = Vector<char>::New(100);
+      name->NameShortPrint(name_buffer);
+      Vector<char> buffer = Vector<char>::New(128);
+      SNPrintF(buffer, "TooManyFastProperties %s", name_buffer.start());
+      return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, buffer.start());
+    }
+#endif
+    return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES,
+                          "TooManyFastProperties");
   }
 
   return result;
@@ -6797,8 +7252,9 @@
 
   // For now, give up on transitioning and just create a unique map.
   // TODO(verwaest/ishell): Cache transitions with different attributes.
-  return CopyGeneralizeAllRepresentations(map, descriptor, FORCE_FIELD,
-                                          attributes, "attributes mismatch");
+  return CopyGeneralizeAllRepresentations(map, descriptor, FORCE_IN_OBJECT,
+                                          attributes,
+                                          "GenAll_AttributesMismatch");
 }
 
 
@@ -6813,7 +7269,7 @@
   if (map->is_dictionary_map()) {
     // For global objects, property cells are inlined. We need to change the
     // map.
-    if (map->IsGlobalObjectMap()) return Copy(map);
+    if (map->IsGlobalObjectMap()) return Copy(map, "GlobalAccessor");
     return map;
   }
 
@@ -6824,34 +7280,24 @@
                                        ? KEEP_INOBJECT_PROPERTIES
                                        : CLEAR_INOBJECT_PROPERTIES;
 
-  int index = map->SearchTransition(*name);
+  int index = map->SearchTransition(ACCESSOR, *name, attributes);
   if (index != TransitionArray::kNotFound) {
     Handle<Map> transition(map->GetTransition(index));
     DescriptorArray* descriptors = transition->instance_descriptors();
-    // Fast path, assume that we're modifying the last added descriptor.
     int descriptor = transition->LastAdded();
-    if (descriptors->GetKey(descriptor) != *name) {
-      // If not, search for the descriptor.
-      descriptor = descriptors->SearchWithCache(*name, *transition);
-    }
+    DCHECK(descriptors->GetKey(descriptor)->Equals(*name));
 
-    if (descriptors->GetDetails(descriptor).type() != CALLBACKS) {
-      return Map::Normalize(map, mode);
-    }
-
-    // TODO(verwaest): Handle attributes better.
-    if (descriptors->GetDetails(descriptor).attributes() != attributes) {
-      return Map::Normalize(map, mode);
-    }
+    DCHECK_EQ(ACCESSOR, descriptors->GetDetails(descriptor).kind());
+    DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes());
 
     Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate);
     if (!maybe_pair->IsAccessorPair()) {
-      return Map::Normalize(map, mode);
+      return Map::Normalize(map, mode, "TransitionToAccessorFromNonPair");
     }
 
     Handle<AccessorPair> pair = Handle<AccessorPair>::cast(maybe_pair);
     if (pair->get(component) != *accessor) {
-      return Map::Normalize(map, mode);
+      return Map::Normalize(map, mode, "TransitionToDifferentAccessor");
     }
 
     return transition;
@@ -6861,31 +7307,34 @@
   DescriptorArray* old_descriptors = map->instance_descriptors();
   int descriptor = old_descriptors->SearchWithCache(*name, *map);
   if (descriptor != DescriptorArray::kNotFound) {
+    if (descriptor != map->LastAdded()) {
+      return Map::Normalize(map, mode, "AccessorsOverwritingNonLast");
+    }
     PropertyDetails old_details = old_descriptors->GetDetails(descriptor);
     if (old_details.type() != CALLBACKS) {
-      return Map::Normalize(map, mode);
+      return Map::Normalize(map, mode, "AccessorsOverwritingNonAccessors");
     }
 
     if (old_details.attributes() != attributes) {
-      return Map::Normalize(map, mode);
+      return Map::Normalize(map, mode, "AccessorsWithAttributes");
     }
 
     Handle<Object> maybe_pair(old_descriptors->GetValue(descriptor), isolate);
     if (!maybe_pair->IsAccessorPair()) {
-      return Map::Normalize(map, mode);
+      return Map::Normalize(map, mode, "AccessorsOverwritingNonPair");
     }
 
     Object* current = Handle<AccessorPair>::cast(maybe_pair)->get(component);
     if (current == *accessor) return map;
 
     if (!current->IsTheHole()) {
-      return Map::Normalize(map, mode);
+      return Map::Normalize(map, mode, "AccessorsOverwritingAccessors");
     }
 
     pair = AccessorPair::Copy(Handle<AccessorPair>::cast(maybe_pair));
   } else if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors ||
              map->TooManyFastProperties(CERTAINLY_NOT_STORE_FROM_KEYED)) {
-    return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES);
+    return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES, "TooManyAccessors");
   } else {
     pair = isolate->factory()->NewAccessorPair();
   }
@@ -6915,8 +7364,14 @@
       descriptors, map->NumberOfOwnDescriptors(), 1);
   new_descriptors->Append(descriptor);
 
-  return CopyReplaceDescriptors(
-      map, new_descriptors, flag, descriptor->GetKey(), SIMPLE_TRANSITION);
+  Handle<LayoutDescriptor> new_layout_descriptor =
+      FLAG_unbox_double_fields
+          ? LayoutDescriptor::Append(map, descriptor->GetDetails())
+          : handle(LayoutDescriptor::FastPointerLayout(), map->GetIsolate());
+
+  return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
+                                flag, descriptor->GetKey(), "CopyAddDescriptor",
+                                SIMPLE_PROPERTY_TRANSITION);
 }
 
 
@@ -7007,12 +7462,16 @@
       descriptors, map->NumberOfOwnDescriptors());
 
   new_descriptors->Replace(insertion_index, descriptor);
+  Handle<LayoutDescriptor> new_layout_descriptor = LayoutDescriptor::New(
+      map, new_descriptors, new_descriptors->number_of_descriptors());
 
   SimpleTransitionFlag simple_flag =
       (insertion_index == descriptors->number_of_descriptors() - 1)
-      ? SIMPLE_TRANSITION
-      : FULL_TRANSITION;
-  return CopyReplaceDescriptors(map, new_descriptors, flag, key, simple_flag);
+          ? SIMPLE_PROPERTY_TRANSITION
+          : PROPERTY_TRANSITION;
+  return CopyReplaceDescriptors(map, new_descriptors, new_layout_descriptor,
+                                flag, key, "CopyReplaceDescriptor",
+                                simple_flag);
 }
 
 
@@ -7090,7 +7549,7 @@
     int value = Smi::cast(*IteratorField())->value();
     int index = -value - 1;
     int number_of_transitions = transition_array_->number_of_transitions();
-    while (index < number_of_transitions) {
+    if (index < number_of_transitions) {
       *IteratorField() = Smi::FromInt(value - 1);
       return transition_array_->GetTarget(index);
     }
@@ -7686,14 +8145,13 @@
 
 
 MaybeHandle<FixedArray> FixedArray::AddKeysFromArrayLike(
-    Handle<FixedArray> content,
-    Handle<JSObject> array) {
+    Handle<FixedArray> content, Handle<JSObject> array, KeyFilter filter) {
   DCHECK(array->IsJSArray() || array->HasSloppyArgumentsElements());
   ElementsAccessor* accessor = array->GetElementsAccessor();
   Handle<FixedArray> result;
   ASSIGN_RETURN_ON_EXCEPTION(
       array->GetIsolate(), result,
-      accessor->AddElementsToFixedArray(array, array, content),
+      accessor->AddElementsToFixedArray(array, array, content, filter),
       FixedArray);
 
 #ifdef ENABLE_SLOW_DCHECKS
@@ -7716,10 +8174,9 @@
   ASSIGN_RETURN_ON_EXCEPTION(
       first->GetIsolate(), result,
       accessor->AddElementsToFixedArray(
-          Handle<Object>::null(),     // receiver
-          Handle<JSObject>::null(),   // holder
-          first,
-          Handle<FixedArrayBase>::cast(second)),
+          Handle<Object>::null(),    // receiver
+          Handle<JSObject>::null(),  // holder
+          first, Handle<FixedArrayBase>::cast(second), ALL_KEYS),
       FixedArray);
 
 #ifdef ENABLE_SLOW_DCHECKS
@@ -7776,6 +8233,116 @@
 #endif
 
 
+// static
+void WeakFixedArray::Set(Handle<WeakFixedArray> array, int index,
+                         Handle<HeapObject> value) {
+  DCHECK(array->IsEmptySlot(index));  // Don't overwrite anything.
+  Handle<WeakCell> cell =
+      value->IsMap() ? Map::WeakCellForMap(Handle<Map>::cast(value))
+                     : array->GetIsolate()->factory()->NewWeakCell(value);
+  Handle<FixedArray>::cast(array)->set(index + kFirstIndex, *cell);
+  if (FLAG_trace_weak_arrays) {
+    PrintF("[WeakFixedArray: storing at index %d ]\n", index);
+  }
+  array->set_last_used_index(index);
+}
+
+
+// static
+Handle<WeakFixedArray> WeakFixedArray::Add(
+    Handle<Object> maybe_array, Handle<HeapObject> value,
+    SearchForDuplicates search_for_duplicates) {
+  Handle<WeakFixedArray> array =
+      (maybe_array.is_null() || !maybe_array->IsWeakFixedArray())
+          ? Allocate(value->GetIsolate(), 1, Handle<WeakFixedArray>::null())
+          : Handle<WeakFixedArray>::cast(maybe_array);
+
+  if (search_for_duplicates == kAddIfNotFound) {
+    for (int i = 0; i < array->Length(); ++i) {
+      if (array->Get(i) == *value) return array;
+    }
+  } else {
+#ifdef DEBUG
+    for (int i = 0; i < array->Length(); ++i) {
+      DCHECK_NE(*value, array->Get(i));
+    }
+#endif
+  }
+
+  // Try to store the new entry if there's room. Optimize for consecutive
+  // accesses.
+  int first_index = array->last_used_index();
+  for (int i = first_index;;) {
+    if (array->IsEmptySlot((i))) {
+      WeakFixedArray::Set(array, i, value);
+      return array;
+    }
+    if (FLAG_trace_weak_arrays) {
+      PrintF("[WeakFixedArray: searching for free slot]\n");
+    }
+    i = (i + 1) % array->Length();
+    if (i == first_index) break;
+  }
+
+  // No usable slot found, grow the array.
+  int new_length = array->Length() + (array->Length() >> 1) + 4;
+  Handle<WeakFixedArray> new_array =
+      Allocate(array->GetIsolate(), new_length, array);
+  if (FLAG_trace_weak_arrays) {
+    PrintF("[WeakFixedArray: growing to size %d ]\n", new_length);
+  }
+  WeakFixedArray::Set(new_array, array->Length(), value);
+  return new_array;
+}
+
+
+void WeakFixedArray::Remove(Handle<HeapObject> value) {
+  // Optimize for the most recently added element to be removed again.
+  int first_index = last_used_index();
+  for (int i = first_index;;) {
+    if (Get(i) == *value) {
+      clear(i);
+      // Users of WeakFixedArray should make sure that there are no duplicates,
+      // they can use Add(..., kAddIfNotFound) if necessary.
+      return;
+    }
+    i = (i + 1) % Length();
+    if (i == first_index) break;
+  }
+}
+
+
+// static
+Handle<WeakFixedArray> WeakFixedArray::Allocate(
+    Isolate* isolate, int size, Handle<WeakFixedArray> initialize_from) {
+  DCHECK(0 <= size);
+  Handle<FixedArray> result =
+      isolate->factory()->NewUninitializedFixedArray(size + kFirstIndex);
+  Handle<WeakFixedArray> casted_result = Handle<WeakFixedArray>::cast(result);
+  if (initialize_from.is_null()) {
+    for (int i = 0; i < result->length(); ++i) {
+      result->set(i, Smi::FromInt(0));
+    }
+  } else {
+    DCHECK(initialize_from->Length() <= size);
+    Handle<FixedArray> raw_source = Handle<FixedArray>::cast(initialize_from);
+    int target_index = kFirstIndex;
+    for (int source_index = kFirstIndex; source_index < raw_source->length();
+         ++source_index) {
+      // The act of allocating might have caused entries in the source array
+      // to be cleared. Copy only what's needed.
+      if (initialize_from->IsEmptySlot(source_index - kFirstIndex)) continue;
+      result->set(target_index++, raw_source->get(source_index));
+    }
+    casted_result->set_last_used_index(target_index - 1 - kFirstIndex);
+    for (; target_index < result->length(); ++target_index) {
+      result->set(target_index, Smi::FromInt(0));
+    }
+  }
+  return casted_result;
+}
+
+
 Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate,
                                                   int number_of_descriptors,
                                                   int slack) {
@@ -7819,8 +8386,7 @@
 }
 
 
-void DescriptorArray::CopyFrom(int index,
-                               DescriptorArray* src,
+void DescriptorArray::CopyFrom(int index, DescriptorArray* src,
                                const WhitenessWitness& witness) {
   Object* value = src->GetValue(index);
   PropertyDetails details = src->GetDetails(index);
@@ -7998,15 +8564,11 @@
   if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
     return SmartArrayPointer<char>(NULL);
   }
-  Heap* heap = GetHeap();
-
   // Negative length means the to the end of the string.
   if (length < 0) length = kMaxInt - offset;
 
   // Compute the size of the UTF-8 string. Start at the specified offset.
-  Access<ConsStringIteratorOp> op(
-      heap->isolate()->objects_string_iterator());
-  StringCharacterStream stream(this, op.value(), offset);
+  StringCharacterStream stream(this, offset);
   int character_position = offset;
   int utf8_bytes = 0;
   int last = unibrow::Utf16::kNoPreviousCharacter;
@@ -8073,11 +8635,7 @@
   if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
     return SmartArrayPointer<uc16>();
   }
-  Heap* heap = GetHeap();
-
-  Access<ConsStringIteratorOp> op(
-      heap->isolate()->objects_string_iterator());
-  StringCharacterStream stream(this, op.value());
+  StringCharacterStream stream(this);
 
   uc16* result = NewArray<uc16>(length() + 1);
 
@@ -8181,7 +8739,7 @@
 }
 
 
-void ConsStringIteratorOp::Initialize(ConsString* cons_string, int offset) {
+void ConsStringIterator::Initialize(ConsString* cons_string, int offset) {
   DCHECK(cons_string != NULL);
   root_ = cons_string;
   consumed_ = offset;
@@ -8192,7 +8750,7 @@
 }
 
 
-String* ConsStringIteratorOp::Continue(int* offset_out) {
+String* ConsStringIterator::Continue(int* offset_out) {
   DCHECK(depth_ != 0);
   DCHECK_EQ(0, *offset_out);
   bool blew_stack = StackBlown();
@@ -8210,7 +8768,7 @@
 }
 
 
-String* ConsStringIteratorOp::Search(int* offset_out) {
+String* ConsStringIterator::Search(int* offset_out) {
   ConsString* cons_string = root_;
   // Reset the stack, pushing the root string.
   depth_ = 1;
@@ -8271,7 +8829,7 @@
 }
 
 
-String* ConsStringIteratorOp::NextLeaf(bool* blew_stack) {
+String* ConsStringIterator::NextLeaf(bool* blew_stack) {
   while (true) {
     // Tree traversal complete.
     if (depth_ == 0) {
@@ -8548,15 +9106,14 @@
 class StringComparator {
   class State {
    public:
-    explicit inline State(ConsStringIteratorOp* op)
-      : op_(op), is_one_byte_(true), length_(0), buffer8_(NULL) {}
+    State() : is_one_byte_(true), length_(0), buffer8_(NULL) {}
 
-    inline void Init(String* string) {
+    void Init(String* string) {
       ConsString* cons_string = String::VisitFlat(this, string);
-      op_->Reset(cons_string);
+      iter_.Reset(cons_string);
       if (cons_string != NULL) {
         int offset;
-        string = op_->Next(&offset);
+        string = iter_.Next(&offset);
         String::VisitFlat(this, string, offset);
       }
     }
@@ -8587,13 +9144,13 @@
       }
       // Advance state.
       int offset;
-      String* next = op_->Next(&offset);
+      String* next = iter_.Next(&offset);
       DCHECK_EQ(0, offset);
       DCHECK(next != NULL);
       String::VisitFlat(this, next);
     }
 
-    ConsStringIteratorOp* const op_;
+    ConsStringIterator iter_;
     bool is_one_byte_;
     int length_;
     union {
@@ -8602,15 +9159,11 @@
     };
 
    private:
-    DISALLOW_IMPLICIT_CONSTRUCTORS(State);
+    DISALLOW_COPY_AND_ASSIGN(State);
   };
 
  public:
-  inline StringComparator(ConsStringIteratorOp* op_1,
-                          ConsStringIteratorOp* op_2)
-    : state_1_(op_1),
-      state_2_(op_2) {
-  }
+  inline StringComparator() {}
 
   template<typename Chars1, typename Chars2>
   static inline bool Equals(State* state_1, State* state_2, int to_check) {
@@ -8653,7 +9206,8 @@
  private:
   State state_1_;
   State state_2_;
-  DISALLOW_IMPLICIT_CONSTRUCTORS(StringComparator);
+
+  DISALLOW_COPY_AND_ASSIGN(StringComparator);
 };
 
 
@@ -8694,10 +9248,7 @@
     return CompareRawStringContents(str1, str2, len);
   }
 
-  Isolate* isolate = GetIsolate();
-  StringComparator comparator(isolate->objects_string_compare_iterator_a(),
-                              isolate->objects_string_compare_iterator_b());
-
+  StringComparator comparator;
   return comparator.Equals(this, other);
 }
 
@@ -8849,8 +9400,7 @@
 bool String::ComputeArrayIndex(uint32_t* index) {
   int length = this->length();
   if (length == 0 || length > kMaxArrayIndexSize) return false;
-  ConsStringIteratorOp op;
-  StringCharacterStream stream(this, &op);
+  StringCharacterStream stream(this);
   return StringToArrayIndex(&stream, index);
 }
 
@@ -8991,6 +9541,35 @@
 }
 
 
+void IteratingStringHasher::VisitConsString(ConsString* cons_string) {
+  // Run small ConsStrings through ConsStringIterator.
+  if (cons_string->length() < 64) {
+    ConsStringIterator iter(cons_string);
+    int offset;
+    String* string;
+    while (nullptr != (string = iter.Next(&offset))) {
+      DCHECK_EQ(0, offset);
+      String::VisitFlat(this, string, 0);
+    }
+    return;
+  }
+  // Slow case.
+  const int max_length = String::kMaxHashCalcLength;
+  int length = std::min(cons_string->length(), max_length);
+  if (cons_string->HasOnlyOneByteChars()) {
+    uint8_t* buffer = new uint8_t[length];
+    String::WriteToFlat(cons_string, buffer, 0, length);
+    AddCharacters(buffer, length);
+    delete[] buffer;
+  } else {
+    uint16_t* buffer = new uint16_t[length];
+    String::WriteToFlat(cons_string, buffer, 0, length);
+    AddCharacters(buffer, length);
+    delete[] buffer;
+  }
+}
+
+
 void String::PrintOn(FILE* file) {
   int length = this->length();
   for (int i = 0; i < length; i++) {
@@ -8999,19 +9578,25 @@
 }
 
 
+inline static uint32_t ObjectAddressForHashing(Object* object) {
+  uint32_t value = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(object));
+  return value & MemoryChunk::kAlignmentMask;
+}
+
+
 int Map::Hash() {
   // For performance reasons we only hash the 3 most variable fields of a map:
-  // constructor, prototype and bit_field2.
+  // constructor, prototype and bit_field2. For predictability reasons we
+  // use objects' offsets in respective pages for hashing instead of raw
+  // addresses.
 
   // Shift away the tag.
-  int hash = (static_cast<uint32_t>(
-        reinterpret_cast<uintptr_t>(constructor())) >> 2);
+  int hash = ObjectAddressForHashing(constructor()) >> 2;
 
   // XOR-ing the prototype and constructor directly yields too many zero bits
   // when the two pointers are close (which is fairly common).
-  // To avoid this we shift the prototype 4 bits relatively to the constructor.
-  hash ^= (static_cast<uint32_t>(
-        reinterpret_cast<uintptr_t>(prototype())) << 2);
+  // To avoid this we shift the prototype bits relatively to the constructor.
+  hash ^= ObjectAddressForHashing(prototype()) << (32 - kPageSizeBits);
 
   return hash ^ (hash >> 16) ^ bit_field2();
 }
@@ -9024,7 +9609,6 @@
     first->instance_type() == second->instance_type() &&
     first->bit_field() == second->bit_field() &&
     first->bit_field2() == second->bit_field2() &&
-    first->is_frozen() == second->is_frozen() &&
     first->has_instance_call_handler() == second->has_instance_call_handler();
 }
 
@@ -9095,22 +9679,40 @@
 
 
 void JSFunction::MarkForOptimization() {
+  Isolate* isolate = GetIsolate();
+  DCHECK(isolate->use_crankshaft());
   DCHECK(!IsOptimized());
   DCHECK(shared()->allows_lazy_compilation() ||
          code()->optimizable());
   DCHECK(!shared()->is_generator());
   set_code_no_write_barrier(
-      GetIsolate()->builtins()->builtin(Builtins::kCompileOptimized));
+      isolate->builtins()->builtin(Builtins::kCompileOptimized));
   // No write barrier required, since the builtin is part of the root set.
 }
 
 
-void JSFunction::MarkForConcurrentOptimization() {
-  DCHECK(is_compiled() || GetIsolate()->DebuggerHasBreakPoints());
+void JSFunction::AttemptConcurrentOptimization() {
+  Isolate* isolate = GetIsolate();
+  if (!isolate->concurrent_recompilation_enabled() ||
+      isolate->bootstrapper()->IsActive()) {
+    MarkForOptimization();
+    return;
+  }
+  if (isolate->concurrent_osr_enabled() &&
+      isolate->optimizing_compiler_thread()->IsQueuedForOSR(this)) {
+    // Do not attempt regular recompilation if we already queued this for OSR.
+    // TODO(yangguo): This is necessary so that we don't install optimized
+    // code on a function that is already optimized, since OSR and regular
+    // recompilation race.  This goes away as soon as OSR becomes one-shot.
+    return;
+  }
+  DCHECK(isolate->use_crankshaft());
+  DCHECK(!IsInOptimizationQueue());
+  DCHECK(is_compiled() || isolate->DebuggerHasBreakPoints());
   DCHECK(!IsOptimized());
   DCHECK(shared()->allows_lazy_compilation() || code()->optimizable());
   DCHECK(!shared()->is_generator());
-  DCHECK(GetIsolate()->concurrent_recompilation_enabled());
+  DCHECK(isolate->concurrent_recompilation_enabled());
   if (FLAG_trace_concurrent_recompilation) {
     PrintF("  ** Marking ");
     ShortPrint();
@@ -9122,24 +9724,6 @@
 }
 
 
-void JSFunction::MarkInOptimizationQueue() {
-  // We can only arrive here via the concurrent-recompilation builtin.  If
-  // break points were set, the code would point to the lazy-compile builtin.
-  DCHECK(!GetIsolate()->DebuggerHasBreakPoints());
-  DCHECK(IsMarkedForConcurrentOptimization() && !IsOptimized());
-  DCHECK(shared()->allows_lazy_compilation() || code()->optimizable());
-  DCHECK(GetIsolate()->concurrent_recompilation_enabled());
-  if (FLAG_trace_concurrent_recompilation) {
-    PrintF("  ** Queueing ");
-    ShortPrint();
-    PrintF(" for concurrent recompilation.\n");
-  }
-  set_code_no_write_barrier(
-      GetIsolate()->builtins()->builtin(Builtins::kInOptimizationQueue));
-  // No write barrier required, since the builtin is part of the root set.
-}
-
-
 Handle<JSFunction> JSFunction::CloneClosure(Handle<JSFunction> function) {
   Isolate* isolate = function->GetIsolate();
   Handle<Map> map(function->map());
@@ -9315,15 +9899,20 @@
   if (object->IsJSGlobalProxy()) return;
   if (mode == FAST_PROTOTYPE && !object->map()->is_prototype_map()) {
     // First normalize to ensure all JSFunctions are CONSTANT.
-    JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0);
+    JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0,
+                                  "NormalizeAsPrototype");
   }
+  bool has_just_copied_map = false;
   if (!object->HasFastProperties()) {
-    JSObject::MigrateSlowToFast(object, 0);
+    JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype");
+    has_just_copied_map = true;
   }
   if (mode == FAST_PROTOTYPE && object->HasFastProperties() &&
       !object->map()->is_prototype_map()) {
-    Handle<Map> new_map = Map::Copy(handle(object->map()));
-    JSObject::MigrateToMap(object, new_map);
+    if (!has_just_copied_map) {
+      Handle<Map> new_map = Map::Copy(handle(object->map()), "CopyAsPrototype");
+      JSObject::MigrateToMap(object, new_map);
+    }
     object->map()->set_is_prototype_map(true);
   }
 }
@@ -9335,6 +9924,74 @@
 }
 
 
+void JSObject::RegisterPrototypeUser(Handle<JSObject> prototype,
+                                     Handle<HeapObject> user) {
+  DCHECK(FLAG_track_prototype_users);
+  Isolate* isolate = prototype->GetIsolate();
+  Handle<Name> symbol = isolate->factory()->prototype_users_symbol();
+
+  // Get prototype users array, create it if it doesn't exist yet.
+  Handle<Object> maybe_array =
+      JSObject::GetProperty(prototype, symbol).ToHandleChecked();
+
+  Handle<WeakFixedArray> new_array = WeakFixedArray::Add(maybe_array, user);
+  if (!maybe_array.is_identical_to(new_array)) {
+    JSObject::SetOwnPropertyIgnoreAttributes(prototype, symbol, new_array,
+                                             DONT_ENUM).Assert();
+  }
+}
+
+
+void JSObject::UnregisterPrototypeUser(Handle<JSObject> prototype,
+                                       Handle<HeapObject> user) {
+  Isolate* isolate = prototype->GetIsolate();
+  Handle<Name> symbol = isolate->factory()->prototype_users_symbol();
+
+  Handle<Object> maybe_array =
+      JSObject::GetProperty(prototype, symbol).ToHandleChecked();
+  if (!maybe_array->IsWeakFixedArray()) return;
+  Handle<WeakFixedArray>::cast(maybe_array)->Remove(user);
+}
+
+
+void Map::SetPrototype(Handle<Object> prototype,
+                       PrototypeOptimizationMode proto_mode) {
+  if (this->prototype()->IsJSObject() && FLAG_track_prototype_users) {
+    Handle<JSObject> old_prototype(JSObject::cast(this->prototype()));
+    JSObject::UnregisterPrototypeUser(old_prototype, handle(this));
+  }
+  if (prototype->IsJSObject()) {
+    Handle<JSObject> prototype_jsobj = Handle<JSObject>::cast(prototype);
+    if (ShouldRegisterAsPrototypeUser(prototype_jsobj)) {
+      JSObject::RegisterPrototypeUser(prototype_jsobj, handle(this));
+    }
+    JSObject::OptimizeAsPrototype(prototype_jsobj, proto_mode);
+  }
+  WriteBarrierMode wb_mode =
+      prototype->IsNull() ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
+  set_prototype(*prototype, wb_mode);
+}
+
+
+bool Map::ShouldRegisterAsPrototypeUser(Handle<JSObject> prototype) {
+  if (!FLAG_track_prototype_users) return false;
+  if (this->is_prototype_map()) return true;
+  if (this->is_dictionary_map()) return false;
+  Object* back = GetBackPointer();
+  if (!back->IsMap()) return true;
+  if (Map::cast(back)->prototype() != *prototype) return true;
+  return false;
+}
+
+
+bool Map::CanUseOptimizationsBasedOnPrototypeRegistry() {
+  if (!FLAG_track_prototype_users) return false;
+  if (this->is_prototype_map()) return true;
+  if (GetBackPointer()->IsMap()) return true;
+  return false;
+}
+
+
 Handle<Object> CacheInitialJSArrayMaps(
     Handle<Context> native_context, Handle<Map> initial_map) {
   // Replace all of the cached initial array maps in the native context with
@@ -9392,7 +10049,7 @@
       // into the initial map where it belongs.
       function->set_prototype_or_initial_map(*value);
     } else {
-      Handle<Map> new_map = Map::Copy(initial_map);
+      Handle<Map> new_map = Map::Copy(initial_map, "SetInstancePrototype");
       JSFunction::SetInitialMap(function, new_map, value);
 
       // If the function is used as the global Array function, cache the
@@ -9432,7 +10089,7 @@
     // Copy the map so this does not affect unrelated functions.
     // Remove map transitions because they point to maps with a
     // different prototype.
-    Handle<Map> new_map = Map::Copy(handle(function->map()));
+    Handle<Map> new_map = Map::Copy(handle(function->map()), "SetPrototype");
 
     JSObject::MigrateToMap(function, new_map);
     new_map->set_constructor(*value);
@@ -9473,13 +10130,18 @@
 
 void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
                                Handle<Object> prototype) {
-  if (prototype->IsJSObject()) {
-    Handle<JSObject> js_proto = Handle<JSObject>::cast(prototype);
-    JSObject::OptimizeAsPrototype(js_proto, FAST_PROTOTYPE);
+  if (map->prototype() != *prototype) {
+    map->SetPrototype(prototype, FAST_PROTOTYPE);
   }
-  map->set_prototype(*prototype);
   function->set_prototype_or_initial_map(*map);
   map->set_constructor(*function);
+#if TRACE_MAPS
+  if (FLAG_trace_maps) {
+    PrintF("[TraceMaps: InitialMap map= %p SFI= %d_%s ]\n",
+           reinterpret_cast<void*>(*map), function->shared()->unique_id(),
+           function->shared()->DebugName()->ToCString().get());
+  }
+#endif
 }
 
 
@@ -9629,27 +10291,31 @@
 }
 
 
-int Script::GetLineNumberWithArray(int code_pos) {
+int Script::GetLineNumberWithArray(int position) {
   DisallowHeapAllocation no_allocation;
-  DCHECK(line_ends()->IsFixedArray());
-  FixedArray* line_ends_array = FixedArray::cast(line_ends());
-  int line_ends_len = line_ends_array->length();
-  if (line_ends_len == 0) return -1;
+  FixedArray* line_ends = FixedArray::cast(this->line_ends());
+  int upper = line_ends->length() - 1;
+  if (upper < 0) return -1;
+  int offset = line_offset()->value();
 
-  if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) {
-    return line_offset()->value();
+  if (position > Smi::cast(line_ends->get(upper))->value()) {
+    return upper + 1 + offset;
   }
+  if (position <= Smi::cast(line_ends->get(0))->value()) return offset;
 
-  int left = 0;
-  int right = line_ends_len;
-  while (int half = (right - left) / 2) {
-    if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) {
-      right -= half;
+  int lower = 1;
+  // Binary search.
+  while (true) {
+    int mid = (lower + upper) / 2;
+    if (position <= Smi::cast(line_ends->get(mid - 1))->value()) {
+      upper = mid - 1;
+    } else if (position > Smi::cast(line_ends->get(mid))->value()) {
+      lower = mid + 1;
     } else {
-      left += half;
+      return mid + offset;
     }
   }
-  return right + line_offset()->value();
+  return -1;
 }
 
 
@@ -9697,54 +10363,27 @@
 }
 
 
-// Wrappers for scripts are kept alive and cached in weak global
-// handles referred from foreign objects held by the scripts as long as
-// they are used. When they are not used anymore, the garbage
-// collector will call the weak callback on the global handle
-// associated with the wrapper and get rid of both the wrapper and the
-// handle.
-static void ClearWrapperCacheWeakCallback(
-    const v8::WeakCallbackData<v8::Value, void>& data) {
-  Object** location = reinterpret_cast<Object**>(data.GetParameter());
-  JSValue* wrapper = JSValue::cast(*location);
-  Script::cast(wrapper->value())->ClearWrapperCache();
-}
-
-
-void Script::ClearWrapperCache() {
-  Foreign* foreign = wrapper();
-  Object** location = reinterpret_cast<Object**>(foreign->foreign_address());
-  DCHECK_EQ(foreign->foreign_address(), reinterpret_cast<Address>(location));
-  foreign->set_foreign_address(0);
-  GlobalHandles::Destroy(location);
-  GetIsolate()->counters()->script_wrappers()->Decrement();
-}
-
-
 Handle<JSObject> Script::GetWrapper(Handle<Script> script) {
-  if (script->wrapper()->foreign_address() != NULL) {
-    // Return a handle for the existing script wrapper from the cache.
-    return Handle<JSValue>(
-        *reinterpret_cast<JSValue**>(script->wrapper()->foreign_address()));
-  }
   Isolate* isolate = script->GetIsolate();
+  if (!script->wrapper()->IsUndefined()) {
+    Handle<WeakCell> cell(WeakCell::cast(script->wrapper()));
+    if (!cell->cleared()) {
+      // Return a handle for the existing script wrapper from the cache.
+      return handle(JSObject::cast(cell->value()));
+    }
+    // If we found an empty WeakCell, that means the script wrapper was
+    // GCed.  We are not notified directly of that, so we decrement here
+    // so that we at least don't count double for any given script.
+    isolate->counters()->script_wrappers()->Decrement();
+  }
   // Construct a new script wrapper.
   isolate->counters()->script_wrappers()->Increment();
   Handle<JSFunction> constructor = isolate->script_function();
   Handle<JSValue> result =
       Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
-
   result->set_value(*script);
-
-  // Create a new weak global handle and use it to cache the wrapper
-  // for future use. The cache will automatically be cleared by the
-  // garbage collector when it is not used anymore.
-  Handle<Object> handle = isolate->global_handles()->Create(*result);
-  GlobalHandles::MakeWeak(handle.location(),
-                          reinterpret_cast<void*>(handle.location()),
-                          &ClearWrapperCacheWeakCallback);
-  script->wrapper()->set_foreign_address(
-      reinterpret_cast<Address>(handle.location()));
+  Handle<WeakCell> cell = isolate->factory()->NewWeakCell(result);
+  script->set_wrapper(*cell);
   return result;
 }
 
@@ -9802,7 +10441,7 @@
 
 
 // Output the source code without any allocation in the heap.
-OStream& operator<<(OStream& os, const SourceCodeOf& v) {
+std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v) {
   const SharedFunctionInfo* s = v.value;
   // For some native functions there is no source.
   if (!s->HasSourceCode()) return os << "<No Source>";
@@ -9875,8 +10514,9 @@
   // regenerated and set on the shared function info it is marked as
   // non-optimizable if optimization is disabled for the shared
   // function info.
+  DCHECK(reason != kNoReason);
   set_optimization_disabled(true);
-  set_bailout_reason(reason);
+  set_disable_optimization_reason(reason);
   // Code should be the lazy compilation stub or else unoptimized.  If the
   // latter, disable optimization for the code too.
   DCHECK(code()->kind() == Code::FUNCTION || code()->kind() == Code::BUILTIN);
@@ -9906,20 +10546,15 @@
 void JSFunction::StartInobjectSlackTracking() {
   DCHECK(has_initial_map() && !IsInobjectSlackTrackingInProgress());
 
-  if (!FLAG_clever_optimizations) return;
   Map* map = initial_map();
 
-  // Only initiate the tracking the first time.
-  if (map->done_inobject_slack_tracking()) return;
-  map->set_done_inobject_slack_tracking(true);
-
   // No tracking during the snapshot construction phase.
   Isolate* isolate = GetIsolate();
   if (isolate->serializer_enabled()) return;
 
   if (map->unused_property_fields() == 0) return;
 
-  map->set_construction_count(kGenerousAllocationCount);
+  map->set_counter(Map::kSlackTrackingCounterStart);
 }
 
 
@@ -9966,8 +10601,8 @@
   DCHECK(has_initial_map());
   Map* map = initial_map();
 
-  DCHECK(map->done_inobject_slack_tracking());
-  map->set_construction_count(kNoSlackTracking);
+  DCHECK(map->counter() >= Map::kSlackTrackingCounterEnd - 1);
+  map->set_counter(Map::kRetainingCounterStart);
 
   int slack = map->unused_property_fields();
   map->TraverseTransitionTree(&GetMinInobjectSlack, &slack);
@@ -10237,6 +10872,7 @@
   for (RelocIterator it(this, mask); !it.done(); it.next()) {
     RelocInfo* info = it.rinfo();
     Object* object = info->target_object();
+    if (object->IsWeakCell()) object = WeakCell::cast(object)->value();
     if (object->IsHeapObject()) {
       if (HeapObject::cast(object)->map() == match_map) {
         if (--n == 0) return object;
@@ -10269,6 +10905,9 @@
     RelocInfo* info = it.rinfo();
     Object* object = info->target_object();
     if (object->IsHeapObject()) {
+      if (object->IsWeakCell()) {
+        object = HeapObject::cast(WeakCell::cast(object)->value());
+      }
       Map* map = HeapObject::cast(object)->map();
       if (map == *pattern.find_[current_pattern]) {
         info->set_target_object(*pattern.replace_[current_pattern]);
@@ -10287,6 +10926,7 @@
   for (RelocIterator it(this, mask); !it.done(); it.next()) {
     RelocInfo* info = it.rinfo();
     Object* object = info->target_object();
+    if (object->IsWeakCell()) object = WeakCell::cast(object)->value();
     if (object->IsMap()) maps->Add(handle(Map::cast(object)));
   }
 }
@@ -10295,11 +10935,21 @@
 Code* Code::FindFirstHandler() {
   DCHECK(is_inline_cache_stub());
   DisallowHeapAllocation no_allocation;
-  int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
+  int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
+             RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
+  bool skip_next_handler = false;
   for (RelocIterator it(this, mask); !it.done(); it.next()) {
     RelocInfo* info = it.rinfo();
-    Code* code = Code::GetCodeFromTargetAddress(info->target_address());
-    if (code->kind() == Code::HANDLER) return code;
+    if (info->rmode() == RelocInfo::EMBEDDED_OBJECT) {
+      Object* obj = info->target_object();
+      skip_next_handler |= obj->IsWeakCell() && WeakCell::cast(obj)->cleared();
+    } else {
+      Code* code = Code::GetCodeFromTargetAddress(info->target_address());
+      if (code->kind() == Code::HANDLER) {
+        if (!skip_next_handler) return code;
+        skip_next_handler = false;
+      }
+    }
   }
   return NULL;
 }
@@ -10308,17 +10958,27 @@
 bool Code::FindHandlers(CodeHandleList* code_list, int length) {
   DCHECK(is_inline_cache_stub());
   DisallowHeapAllocation no_allocation;
-  int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
+  int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
+             RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
+  bool skip_next_handler = false;
   int i = 0;
   for (RelocIterator it(this, mask); !it.done(); it.next()) {
     if (i == length) return true;
     RelocInfo* info = it.rinfo();
-    Code* code = Code::GetCodeFromTargetAddress(info->target_address());
-    // IC stubs with handlers never contain non-handler code objects before
-    // handler targets.
-    if (code->kind() != Code::HANDLER) break;
-    code_list->Add(Handle<Code>(code));
-    i++;
+    if (info->rmode() == RelocInfo::EMBEDDED_OBJECT) {
+      Object* obj = info->target_object();
+      skip_next_handler |= obj->IsWeakCell() && WeakCell::cast(obj)->cleared();
+    } else {
+      Code* code = Code::GetCodeFromTargetAddress(info->target_address());
+      // IC stubs with handlers never contain non-handler code objects before
+      // handler targets.
+      if (code->kind() != Code::HANDLER) break;
+      if (!skip_next_handler) {
+        code_list->Add(Handle<Code>(code));
+        i++;
+      }
+      skip_next_handler = false;
+    }
   }
   return i == length;
 }
@@ -10333,6 +10993,7 @@
     RelocInfo* info = it.rinfo();
     if (info->rmode() == RelocInfo::EMBEDDED_OBJECT) {
       Object* object = info->target_object();
+      if (object->IsWeakCell()) object = WeakCell::cast(object)->value();
       if (object == map) return_next = true;
     } else if (return_next) {
       Code* code = Code::GetCodeFromTargetAddress(info->target_address());
@@ -10385,27 +11046,7 @@
 
 
 void SharedFunctionInfo::ClearTypeFeedbackInfo() {
-  TypeFeedbackVector* vector = feedback_vector();
-  Heap* heap = GetHeap();
-  int length = vector->length();
-
-  for (int i = 0; i < length; i++) {
-    Object* obj = vector->get(i);
-    if (obj->IsHeapObject()) {
-      InstanceType instance_type =
-          HeapObject::cast(obj)->map()->instance_type();
-      switch (instance_type) {
-        case ALLOCATION_SITE_TYPE:
-          // AllocationSites are not cleared because they do not store
-          // information that leaks.
-          break;
-          // Fall through...
-        default:
-          vector->set(i, TypeFeedbackVector::RawUninitializedSentinel(heap),
-                      SKIP_WRITE_BARRIER);
-      }
-    }
-  }
+  feedback_vector()->ClearSlots(this);
 }
 
 
@@ -10455,6 +11096,12 @@
 }
 
 
+void Code::MakeYoung(Isolate* isolate) {
+  byte* sequence = FindCodeAgeSequence();
+  if (sequence != NULL) MakeCodeAgeSequenceYoung(sequence, isolate);
+}
+
+
 void Code::MakeOlder(MarkingParity current_parity) {
   byte* sequence = FindCodeAgeSequence();
   if (sequence != NULL) {
@@ -10622,7 +11269,7 @@
 #ifdef ENABLE_DISASSEMBLER
 
 void DeoptimizationInputData::DeoptimizationInputDataPrint(
-    OStream& os) {  // NOLINT
+    std::ostream& os) {  // NOLINT
   disasm::NameConverter converter;
   int deopt_count = DeoptCount();
   os << "Deoptimization Input Data (deopt points = " << deopt_count << ")\n";
@@ -10783,7 +11430,7 @@
 
 
 void DeoptimizationOutputData::DeoptimizationOutputDataPrint(
-    OStream& os) {  // NOLINT
+    std::ostream& os) {  // NOLINT
   os << "Deoptimization Output Data (deopt points = " << this->DeoptPoints()
      << ")\n";
   if (this->DeoptPoints() == 0) return;
@@ -10831,7 +11478,7 @@
 }
 
 
-void Code::PrintExtraICState(OStream& os,  // NOLINT
+void Code::PrintExtraICState(std::ostream& os,  // NOLINT
                              Kind kind, ExtraICState extra) {
   os << "extra_ic_state = ";
   if ((kind == STORE_IC || kind == KEYED_STORE_IC) && (extra == STRICT)) {
@@ -10842,7 +11489,7 @@
 }
 
 
-void Code::Disassemble(const char* name, OStream& os) {  // NOLINT
+void Code::Disassemble(const char* name, std::ostream& os) {  // NOLINT
   os << "kind = " << Kind2String(kind()) << "\n";
   if (IsCodeStubOrIC()) {
     const char* n = CodeStub::MajorName(CodeStub::GetMajorKey(this), true);
@@ -10871,10 +11518,19 @@
   }
 
   os << "Instructions (size = " << instruction_size() << ")\n";
-  // TODO(svenpanne) The Disassembler should use streams, too!
   {
-    CodeTracer::Scope trace_scope(GetIsolate()->GetCodeTracer());
-    Disassembler::Decode(trace_scope.file(), this);
+    Isolate* isolate = GetIsolate();
+    int decode_size = is_crankshafted()
+                          ? static_cast<int>(safepoint_table_offset())
+                          : instruction_size();
+    // If there might be a back edge table, stop before reaching it.
+    if (kind() == Code::FUNCTION) {
+      decode_size =
+          Min(decode_size, static_cast<int>(back_edge_table_offset()));
+    }
+    byte* begin = instruction_start();
+    byte* end = begin + decode_size;
+    Disassembler::Decode(isolate, &os, begin, end, this);
   }
   os << "\n";
 
@@ -10894,7 +11550,7 @@
     os << "Safepoints (size = " << table.size() << ")\n";
     for (unsigned i = 0; i < table.length(); i++) {
       unsigned pc_offset = table.GetPcOffset(i);
-      os << (instruction_start() + pc_offset) << "  ";
+      os << static_cast<const void*>(instruction_start() + pc_offset) << "  ";
       // TODO(svenpanne) Add some basic formatting to our streams.
       Vector<char> buf1 = Vector<char>::New(30);
       SNPrintF(buf1, "%4d", pc_offset);
@@ -10949,6 +11605,17 @@
     it.rinfo()->Print(GetIsolate(), os);
   }
   os << "\n";
+
+#ifdef OBJECT_PRINT
+  if (FLAG_enable_ool_constant_pool) {
+    ConstantPoolArray* pool = constant_pool();
+    if (pool->length()) {
+      os << "Constant Pool\n";
+      pool->Print(os);
+      os << "\n";
+    }
+  }
+#endif
 }
 #endif  // ENABLE_DISASSEMBLER
 
@@ -11091,10 +11758,9 @@
   return true;
 }
 
-static void EnqueueSpliceRecord(Handle<JSArray> object,
-                                uint32_t index,
-                                Handle<JSArray> deleted,
-                                uint32_t add_count) {
+MUST_USE_RESULT static MaybeHandle<Object> EnqueueSpliceRecord(
+    Handle<JSArray> object, uint32_t index, Handle<JSArray> deleted,
+    uint32_t add_count) {
   Isolate* isolate = object->GetIsolate();
   HandleScope scope(isolate);
   Handle<Object> index_object = isolate->factory()->NewNumberFromUint(index);
@@ -11104,37 +11770,33 @@
   Handle<Object> args[] =
       { object, index_object, deleted, add_count_object };
 
-  Execution::Call(isolate,
-                  Handle<JSFunction>(isolate->observers_enqueue_splice()),
-                  isolate->factory()->undefined_value(),
-                  arraysize(args),
-                  args).Assert();
+  return Execution::Call(
+      isolate, Handle<JSFunction>(isolate->observers_enqueue_splice()),
+      isolate->factory()->undefined_value(), arraysize(args), args);
 }
 
 
-static void BeginPerformSplice(Handle<JSArray> object) {
+MUST_USE_RESULT static MaybeHandle<Object> BeginPerformSplice(
+    Handle<JSArray> object) {
   Isolate* isolate = object->GetIsolate();
   HandleScope scope(isolate);
   Handle<Object> args[] = { object };
 
-  Execution::Call(isolate,
-                  Handle<JSFunction>(isolate->observers_begin_perform_splice()),
-                  isolate->factory()->undefined_value(),
-                  arraysize(args),
-                  args).Assert();
+  return Execution::Call(
+      isolate, Handle<JSFunction>(isolate->observers_begin_perform_splice()),
+      isolate->factory()->undefined_value(), arraysize(args), args);
 }
 
 
-static void EndPerformSplice(Handle<JSArray> object) {
+MUST_USE_RESULT static MaybeHandle<Object> EndPerformSplice(
+    Handle<JSArray> object) {
   Isolate* isolate = object->GetIsolate();
   HandleScope scope(isolate);
   Handle<Object> args[] = { object };
 
-  Execution::Call(isolate,
-                  Handle<JSFunction>(isolate->observers_end_perform_splice()),
-                  isolate->factory()->undefined_value(),
-                  arraysize(args),
-                  args).Assert();
+  return Execution::Call(
+      isolate, Handle<JSFunction>(isolate->observers_end_perform_splice()),
+      isolate->factory()->undefined_value(), arraysize(args), args);
 }
 
 
@@ -11198,21 +11860,26 @@
   CHECK(array->length()->ToArrayIndex(&new_length));
   if (old_length == new_length) return hresult;
 
-  BeginPerformSplice(array);
+  RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object);
 
   for (int i = 0; i < indices.length(); ++i) {
     // For deletions where the property was an accessor, old_values[i]
     // will be the hole, which instructs EnqueueChangeRecord to elide
     // the "oldValue" property.
-    JSObject::EnqueueChangeRecord(
-        array, "delete", isolate->factory()->Uint32ToString(indices[i]),
-        old_values[i]);
+    RETURN_ON_EXCEPTION(
+        isolate,
+        JSObject::EnqueueChangeRecord(
+            array, "delete", isolate->factory()->Uint32ToString(indices[i]),
+            old_values[i]),
+        Object);
   }
-  JSObject::EnqueueChangeRecord(
-      array, "update", isolate->factory()->length_string(),
-      old_length_handle);
+  RETURN_ON_EXCEPTION(isolate,
+                      JSObject::EnqueueChangeRecord(
+                          array, "update", isolate->factory()->length_string(),
+                          old_length_handle),
+                      Object);
 
-  EndPerformSplice(array);
+  RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object);
 
   uint32_t index = Min(old_length, new_length);
   uint32_t add_count = new_length > old_length ? new_length - old_length : 0;
@@ -11223,8 +11890,8 @@
       // Skip deletions where the property was an accessor, leaving holes
       // in the array of old values.
       if (old_values[i]->IsTheHole()) continue;
-      JSObject::SetElement(
-          deleted, indices[i] - index, old_values[i], NONE, SLOPPY).Assert();
+      JSObject::SetOwnElement(deleted, indices[i] - index, old_values[i],
+                              SLOPPY).Assert();
     }
 
     SetProperty(deleted, isolate->factory()->length_string(),
@@ -11232,7 +11899,8 @@
                 STRICT).Assert();
   }
 
-  EnqueueSpliceRecord(array, index, deleted, add_count);
+  RETURN_ON_EXCEPTION(
+      isolate, EnqueueSpliceRecord(array, index, deleted, add_count), Object);
 
   return hresult;
 }
@@ -11337,23 +12005,6 @@
 }
 
 
-// static
-void Map::AddDependentIC(Handle<Map> map,
-                         Handle<Code> stub) {
-  DCHECK(stub->next_code_link()->IsUndefined());
-  int n = map->dependent_code()->number_of_entries(DependentCode::kWeakICGroup);
-  if (n == 0) {
-    // Slow path: insert the head of the list with possible heap allocation.
-    Map::AddDependentCode(map, DependentCode::kWeakICGroup, stub);
-  } else {
-    // Fast path: link the stub to the existing head of the list without any
-    // heap allocation.
-    DCHECK(n == 1);
-    map->dependent_code()->AddToDependentICList(stub);
-  }
-}
-
-
 DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) {
   Recompute(entries);
 }
@@ -11483,22 +12134,10 @@
 }
 
 
-static bool CodeListContains(Object* head, Code* code) {
-  while (!head->IsUndefined()) {
-    if (head == code) return true;
-    head = Code::cast(head)->next_code_link();
-  }
-  return false;
-}
-
-
 bool DependentCode::Contains(DependencyGroup group, Code* code) {
   GroupStartIndexes starts(this);
   int start = starts.at(group);
   int end = starts.at(group + 1);
-  if (group == kWeakICGroup) {
-    return CodeListContains(object_at(start), code);
-  }
   for (int i = start; i < end; i++) {
     if (object_at(i) == code) return true;
   }
@@ -11555,24 +12194,6 @@
 }
 
 
-void DependentCode::AddToDependentICList(Handle<Code> stub) {
-  DisallowHeapAllocation no_heap_allocation;
-  GroupStartIndexes starts(this);
-  int i = starts.at(kWeakICGroup);
-  Object* head = object_at(i);
-  // Try to insert the stub after the head of the list to minimize number of
-  // writes to the DependentCode array, since a write to the array can make it
-  // strong if it was alread marked by incremental marker.
-  if (head->IsCode()) {
-    stub->set_next_code_link(Code::cast(head)->next_code_link());
-    Code::cast(head)->set_next_code_link(*stub);
-  } else {
-    stub->set_next_code_link(head);
-    set_object_at(i, *stub);
-  }
-}
-
-
 void DependentCode::SetMarkedForDeoptimization(Code* code,
                                                DependencyGroup group) {
   code->set_marked_for_deoptimization(true);
@@ -11591,8 +12212,6 @@
 
 const char* DependentCode::DependencyGroupName(DependencyGroup group) {
   switch (group) {
-    case kWeakICGroup:
-      return "weak-ic";
     case kWeakCodeGroup:
       return "weak-code";
     case kTransitionGroup:
@@ -11618,12 +12237,13 @@
 
 
 Handle<Map> Map::TransitionToPrototype(Handle<Map> map,
-                                       Handle<Object> prototype) {
+                                       Handle<Object> prototype,
+                                       PrototypeOptimizationMode mode) {
   Handle<Map> new_map = GetPrototypeTransition(map, prototype);
   if (new_map.is_null()) {
-    new_map = Copy(map);
+    new_map = Copy(map, "TransitionToPrototype");
     PutPrototypeTransition(map, prototype, new_map);
-    new_map->set_prototype(*prototype);
+    new_map->SetPrototype(prototype, mode);
   }
   return new_map;
 }
@@ -11693,17 +12313,13 @@
   // Nothing to do if prototype is already set.
   if (map->prototype() == *value) return value;
 
-  if (value->IsJSObject()) {
-    PrototypeOptimizationMode mode =
-        from_javascript ? REGULAR_PROTOTYPE : FAST_PROTOTYPE;
-    JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value), mode);
-  }
-
-  Handle<Map> new_map = Map::TransitionToPrototype(map, value);
+  PrototypeOptimizationMode mode =
+      from_javascript ? REGULAR_PROTOTYPE : FAST_PROTOTYPE;
+  Handle<Map> new_map = Map::TransitionToPrototype(map, value, mode);
   DCHECK(new_map->prototype() == *value);
   JSObject::MigrateToMap(real_receiver, new_map);
 
-  if (!dictionary_elements_in_chain &&
+  if (from_javascript && !dictionary_elements_in_chain &&
       new_map->DictionaryElementsInPrototypeChainOnly()) {
     // If the prototype chain didn't previously have element callbacks, then
     // KeyedStoreICs need to be cleared to ensure any that involve this
@@ -11837,13 +12453,10 @@
 }
 
 
-MaybeHandle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object,
-                                                     Handle<Object> structure,
-                                                     uint32_t index,
-                                                     Handle<Object> value,
-                                                     Handle<JSObject> holder,
-                                                     StrictMode strict_mode) {
-  Isolate* isolate = object->GetIsolate();
+MaybeHandle<Object> JSObject::SetElementWithCallback(
+    Handle<Object> object, Handle<Object> structure, uint32_t index,
+    Handle<Object> value, Handle<JSObject> holder, StrictMode strict_mode) {
+  Isolate* isolate = holder->GetIsolate();
 
   // We should never get here to initialize a const with the hole
   // value since a const declaration would conflict with the setter.
@@ -11859,7 +12472,7 @@
     if (call_fun == NULL) return value;
     Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
     Handle<String> key(isolate->factory()->NumberToString(number));
-    LOG(isolate, ApiNamedPropertyAccess("store", *object, *key));
+    LOG(isolate, ApiNamedPropertyAccess("store", *holder, *key));
     PropertyCallbackArguments
         args(isolate, data->data(), *object, *holder);
     args.Call(call_fun,
@@ -12081,8 +12694,8 @@
       // is read-only (a declared const that has not been initialized).  If a
       // value is being defined we skip attribute checks completely.
       if (set_mode == DEFINE_PROPERTY) {
-        details = PropertyDetails(
-            attributes, NORMAL, details.dictionary_index());
+        details =
+            PropertyDetails(attributes, FIELD, details.dictionary_index());
         dictionary->DetailsAtPut(entry, details);
       } else if (details.IsReadOnly() && !element->IsTheHole()) {
         if (strict_mode == SLOPPY) {
@@ -12133,7 +12746,7 @@
       }
     }
 
-    PropertyDetails details = PropertyDetails(attributes, NORMAL, 0);
+    PropertyDetails details(attributes, FIELD, 0);
     Handle<SeededNumberDictionary> new_dictionary =
         SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
                                                details);
@@ -12417,28 +13030,44 @@
       CHECK(old_length_handle->ToArrayIndex(&old_length));
       CHECK(new_length_handle->ToArrayIndex(&new_length));
 
-      BeginPerformSplice(Handle<JSArray>::cast(object));
-      EnqueueChangeRecord(object, "add", name, old_value);
-      EnqueueChangeRecord(object, "update", isolate->factory()->length_string(),
-                          old_length_handle);
-      EndPerformSplice(Handle<JSArray>::cast(object));
+      RETURN_ON_EXCEPTION(
+          isolate, BeginPerformSplice(Handle<JSArray>::cast(object)), Object);
+      RETURN_ON_EXCEPTION(
+          isolate, EnqueueChangeRecord(object, "add", name, old_value), Object);
+      RETURN_ON_EXCEPTION(
+          isolate, EnqueueChangeRecord(object, "update",
+                                       isolate->factory()->length_string(),
+                                       old_length_handle),
+          Object);
+      RETURN_ON_EXCEPTION(
+          isolate, EndPerformSplice(Handle<JSArray>::cast(object)), Object);
       Handle<JSArray> deleted = isolate->factory()->NewJSArray(0);
-      EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted,
-                          new_length - old_length);
+      RETURN_ON_EXCEPTION(
+          isolate,
+          EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length,
+                              deleted, new_length - old_length),
+          Object);
     } else {
-      EnqueueChangeRecord(object, "add", name, old_value);
+      RETURN_ON_EXCEPTION(
+          isolate, EnqueueChangeRecord(object, "add", name, old_value), Object);
     }
   } else if (old_value->IsTheHole()) {
-    EnqueueChangeRecord(object, "reconfigure", name, old_value);
+    RETURN_ON_EXCEPTION(
+        isolate, EnqueueChangeRecord(object, "reconfigure", name, old_value),
+        Object);
   } else {
     Handle<Object> new_value =
         Object::GetElement(isolate, object, index).ToHandleChecked();
     bool value_changed = !old_value->SameValue(*new_value);
     if (old_attributes != new_attributes) {
       if (!value_changed) old_value = isolate->factory()->the_hole_value();
-      EnqueueChangeRecord(object, "reconfigure", name, old_value);
+      RETURN_ON_EXCEPTION(
+          isolate, EnqueueChangeRecord(object, "reconfigure", name, old_value),
+          Object);
     } else if (value_changed) {
-      EnqueueChangeRecord(object, "update", name, old_value);
+      RETURN_ON_EXCEPTION(
+          isolate, EnqueueChangeRecord(object, "update", name, old_value),
+          Object);
     }
   }
 
@@ -12631,10 +13260,32 @@
 
 
 // static
-void AllocationSite::AddDependentCompilationInfo(Handle<AllocationSite> site,
-                                                 Reason reason,
-                                                 CompilationInfo* info) {
-  DependentCode::DependencyGroup group = site->ToDependencyGroup(reason);
+void AllocationSite::RegisterForDeoptOnTenureChange(Handle<AllocationSite> site,
+                                                    CompilationInfo* info) {
+  AddDependentCompilationInfo(
+      site, DependentCode::kAllocationSiteTenuringChangedGroup, info);
+}
+
+
+// static
+void AllocationSite::RegisterForDeoptOnTransitionChange(
+    Handle<AllocationSite> site, CompilationInfo* info) {
+  // Do nothing if the object doesn't have any useful element transitions left.
+  ElementsKind kind =
+      site->SitePointsToLiteral()
+          ? JSObject::cast(site->transition_info())->GetElementsKind()
+          : site->GetElementsKind();
+  if (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) {
+    AddDependentCompilationInfo(
+        site, DependentCode::kAllocationSiteTransitionChangedGroup, info);
+  }
+}
+
+
+// static
+void AllocationSite::AddDependentCompilationInfo(
+    Handle<AllocationSite> site, DependentCode::DependencyGroup group,
+    CompilationInfo* info) {
   Handle<DependentCode> dep(site->dependent_code());
   Handle<DependentCode> codes =
       DependentCode::Insert(dep, group, info->object_wrapper());
@@ -12784,18 +13435,21 @@
 }
 
 
+bool JSArray::HasReadOnlyLength(Handle<JSArray> array) {
+  LookupIterator it(array, array->GetIsolate()->factory()->length_string(),
+                    LookupIterator::OWN_SKIP_INTERCEPTOR);
+  CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
+  CHECK(it.IsFound());
+  CHECK_EQ(LookupIterator::ACCESSOR, it.state());
+  return it.IsReadOnly();
+}
+
+
 bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array,
                                         uint32_t index) {
   uint32_t length = 0;
   CHECK(array->length()->ToArrayIndex(&length));
-  if (length <= index) {
-    LookupIterator it(array, array->GetIsolate()->factory()->length_string(),
-                      LookupIterator::OWN_SKIP_INTERCEPTOR);
-    CHECK_NE(LookupIterator::ACCESS_CHECK, it.state());
-    CHECK(it.IsFound());
-    CHECK_EQ(LookupIterator::ACCESSOR, it.state());
-    return it.IsReadOnly();
-  }
+  if (length <= index) return HasReadOnlyLength(array);
   return false;
 }
 
@@ -12810,10 +13464,10 @@
 }
 
 
-MaybeHandle<Object> JSObject::GetElementWithInterceptor(
-    Handle<JSObject> object,
-    Handle<Object> receiver,
-    uint32_t index) {
+MaybeHandle<Object> JSObject::GetElementWithInterceptor(Handle<JSObject> object,
+                                                        Handle<Object> receiver,
+                                                        uint32_t index,
+                                                        bool check_prototype) {
   Isolate* isolate = object->GetIsolate();
 
   // Make sure that the top context does not change when doing
@@ -12838,6 +13492,8 @@
     }
   }
 
+  if (!check_prototype) return MaybeHandle<Object>();
+
   ElementsAccessor* handler = object->GetElementsAccessor();
   Handle<Object> result;
   ASSIGN_RETURN_ON_EXCEPTION(
@@ -13039,7 +13695,7 @@
 // we keep it here instead to satisfy certain compilers.
 #ifdef OBJECT_PRINT
 template <typename Derived, typename Shape, typename Key>
-void Dictionary<Derived, Shape, Key>::Print(OStream& os) {  // NOLINT
+void Dictionary<Derived, Shape, Key>::Print(std::ostream& os) {  // NOLINT
   int capacity = DerivedHashTable::Capacity();
   for (int i = 0; i < capacity; i++) {
     Object* k = DerivedHashTable::KeyAt(i);
@@ -13050,7 +13706,7 @@
       } else {
         os << Brief(k);
       }
-      os << ": " << Brief(ValueAt(i)) << "\n";
+      os << ": " << Brief(ValueAt(i)) << " " << DetailsAt(i) << "\n";
     }
   }
 }
@@ -13099,22 +13755,21 @@
     Handle<Name> name) {
   Isolate* isolate = holder->GetIsolate();
 
-  // TODO(rossberg): Support symbols in the API.
-  if (name->IsSymbol()) return isolate->factory()->undefined_value();
-
   Handle<InterceptorInfo> interceptor(holder->GetNamedInterceptor(), isolate);
-  Handle<String> name_string = Handle<String>::cast(name);
-
   if (interceptor->getter()->IsUndefined()) return MaybeHandle<Object>();
 
-  v8::NamedPropertyGetterCallback getter =
-      v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
+  if (name->IsSymbol() && !interceptor->can_intercept_symbols()) {
+    return MaybeHandle<Object>();
+  }
+
+  v8::GenericNamedPropertyGetterCallback getter =
+      v8::ToCData<v8::GenericNamedPropertyGetterCallback>(
+          interceptor->getter());
   LOG(isolate,
       ApiNamedPropertyAccess("interceptor-named-get", *holder, *name));
   PropertyCallbackArguments
       args(isolate, interceptor->data(), *receiver, *holder);
-  v8::Handle<v8::Value> result =
-      args.Call(getter, v8::Utils::ToLocal(name_string));
+  v8::Handle<v8::Value> result = args.Call(getter, v8::Utils::ToLocal(name));
   RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
   if (result.IsEmpty()) return MaybeHandle<Object>();
 
@@ -13126,7 +13781,6 @@
 
 
 // Compute the property keys from the interceptor.
-// TODO(rossberg): support symbols in API, and filter here if needed.
 MaybeHandle<JSObject> JSObject::GetKeysForNamedInterceptor(
     Handle<JSObject> object, Handle<JSReceiver> receiver) {
   Isolate* isolate = receiver->GetIsolate();
@@ -13135,8 +13789,8 @@
       args(isolate, interceptor->data(), *receiver, *object);
   v8::Handle<v8::Object> result;
   if (!interceptor->enumerator()->IsUndefined()) {
-    v8::NamedPropertyEnumeratorCallback enum_fun =
-        v8::ToCData<v8::NamedPropertyEnumeratorCallback>(
+    v8::GenericNamedPropertyEnumeratorCallback enum_fun =
+        v8::ToCData<v8::GenericNamedPropertyEnumeratorCallback>(
             interceptor->enumerator());
     LOG(isolate, ApiObjectAccess("interceptor-named-enum", *object));
     result = args.Call(enum_fun);
@@ -13524,6 +14178,31 @@
 }
 
 
+const char* Symbol::PrivateSymbolToName() const {
+  Heap* heap = GetIsolate()->heap();
+#define SYMBOL_CHECK_AND_PRINT(name) \
+  if (this == heap->name()) return #name;
+  PRIVATE_SYMBOL_LIST(SYMBOL_CHECK_AND_PRINT)
+#undef SYMBOL_CHECK_AND_PRINT
+  return "UNKNOWN";
+}
+
+
+void Symbol::SymbolShortPrint(std::ostream& os) {
+  os << "<Symbol: " << Hash();
+  if (!name()->IsUndefined()) {
+    os << " ";
+    HeapStringAllocator allocator;
+    StringStream accumulator(&allocator);
+    String::cast(name())->StringShortPrint(&accumulator);
+    os << accumulator.ToCString().get();
+  } else {
+    os << " (" << PrivateSymbolToName() << ")";
+  }
+  os << ">";
+}
+
+
 // StringSharedKeys are used as keys in the eval cache.
 class StringSharedKey : public HashTableKey {
  public:
@@ -13538,7 +14217,11 @@
 
   bool IsMatch(Object* other) OVERRIDE {
     DisallowHeapAllocation no_allocation;
-    if (!other->IsFixedArray()) return false;
+    if (!other->IsFixedArray()) {
+      if (!other->IsNumber()) return false;
+      uint32_t other_hash = static_cast<uint32_t>(other->Number());
+      return Hash() == other_hash;
+    }
     FixedArray* other_array = FixedArray::cast(other);
     SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
     if (shared != *shared_) return false;
@@ -13578,6 +14261,9 @@
 
   uint32_t HashForObject(Object* obj) OVERRIDE {
     DisallowHeapAllocation no_allocation;
+    if (obj->IsNumber()) {
+      return static_cast<uint32_t>(obj->Number());
+    }
     FixedArray* other_array = FixedArray::cast(obj);
     SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
     String* source = String::cast(other_array->get(1));
@@ -13679,17 +14365,17 @@
   explicit InternalizedStringKey(Handle<String> string)
       : string_(string) { }
 
-  virtual bool IsMatch(Object* string) OVERRIDE {
+  bool IsMatch(Object* string) OVERRIDE {
     return String::cast(string)->Equals(*string_);
   }
 
-  virtual uint32_t Hash() OVERRIDE { return string_->Hash(); }
+  uint32_t Hash() OVERRIDE { return string_->Hash(); }
 
-  virtual uint32_t HashForObject(Object* other) OVERRIDE {
+  uint32_t HashForObject(Object* other) OVERRIDE {
     return String::cast(other)->Hash();
   }
 
-  virtual Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
+  Handle<Object> AsHandle(Isolate* isolate) OVERRIDE {
     // Internalize the string if possible.
     MaybeHandle<Map> maybe_map =
         isolate->factory()->InternalizedStringMapForString(string_);
@@ -13987,8 +14673,6 @@
                          CompilationCacheShape,
                          HashTableKey*>;
 
-template class HashTable<MapCache, MapCacheShape, HashTableKey*>;
-
 template class HashTable<ObjectHashTable,
                          ObjectHashTableShape,
                          Handle<Object> >;
@@ -14078,9 +14762,13 @@
 Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::Add(
     Handle<NameDictionary>, Handle<Name>, Handle<Object>, PropertyDetails);
 
-template void
-Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
-    GenerateNewEnumerationIndices(Handle<NameDictionary>);
+template Handle<FixedArray> Dictionary<
+    NameDictionary, NameDictionaryShape,
+    Handle<Name> >::BuildIterationIndicesArray(Handle<NameDictionary>);
+
+template Handle<FixedArray> Dictionary<
+    NameDictionary, NameDictionaryShape,
+    Handle<Name> >::GenerateNewEnumerationIndices(Handle<NameDictionary>);
 
 template int
 Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
@@ -14120,9 +14808,11 @@
 int Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >::
     NumberOfEnumElements();
 
-template
-int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>::
-    FindEntry(uint32_t);
+template bool Dictionary<SeededNumberDictionary, SeededNumberDictionaryShape,
+                         uint32_t>::HasComplexElements();
+
+template int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape,
+                       uint32_t>::FindEntry(uint32_t);
 
 
 Handle<Object> JSObject::PrepareSlowElementsForSort(
@@ -14189,7 +14879,7 @@
   }
 
   uint32_t result = pos;
-  PropertyDetails no_details = PropertyDetails(NONE, NORMAL, 0);
+  PropertyDetails no_details(NONE, FIELD, 0);
   while (undefs > 0) {
     if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
       // Adding an entry with the key beyond smi-range requires
@@ -14547,6 +15237,25 @@
 }
 
 
+void GlobalObject::InvalidatePropertyCell(Handle<GlobalObject> global,
+                                          Handle<Name> name) {
+  DCHECK(!global->HasFastProperties());
+  Isolate* isolate = global->GetIsolate();
+  int entry = global->property_dictionary()->FindEntry(name);
+  if (entry != NameDictionary::kNotFound) {
+    Handle<PropertyCell> cell(
+        PropertyCell::cast(global->property_dictionary()->ValueAt(entry)));
+
+    Handle<Object> value(cell->value(), isolate);
+    Handle<PropertyCell> new_cell = isolate->factory()->NewPropertyCell(value);
+    global->property_dictionary()->ValueAtPut(entry, *new_cell);
+
+    Handle<Object> hole = global->GetIsolate()->factory()->the_hole_value();
+    PropertyCell::SetValueInferType(cell, hole);
+  }
+}
+
+
 Handle<PropertyCell> JSGlobalObject::EnsurePropertyCell(
     Handle<JSGlobalObject> global,
     Handle<Name> name) {
@@ -14556,7 +15265,7 @@
     Isolate* isolate = global->GetIsolate();
     Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell(
         isolate->factory()->the_hole_value());
-    PropertyDetails details(NONE, NORMAL, 0);
+    PropertyDetails details(NONE, FIELD, 0);
     details = details.AsDeleted();
     Handle<NameDictionary> dictionary = NameDictionary::Add(
         handle(global->property_dictionary()), name, cell, details);
@@ -14677,6 +15386,16 @@
 }
 
 
+void StringTable::EnsureCapacityForDeserialization(Isolate* isolate,
+                                                   int expected) {
+  Handle<StringTable> table = isolate->factory()->string_table();
+  // We need a key instance for the virtual hash function.
+  InternalizedStringKey dummy_key(Handle<String>::null());
+  table = StringTable::EnsureCapacity(table, expected, &dummy_key);
+  isolate->factory()->set_string_table(table);
+}
+
+
 Handle<String> StringTable::LookupString(Isolate* isolate,
                                          Handle<String> string) {
   InternalizedStringKey key(string);
@@ -14720,7 +15439,9 @@
                       RelocInfo::kNoPosition);
   int entry = FindEntry(&key);
   if (entry == kNotFound) return isolate->factory()->undefined_value();
-  return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
+  int index = EntryToIndex(entry);
+  if (!get(index)->IsFixedArray()) return isolate->factory()->undefined_value();
+  return Handle<Object>(get(index + 1), isolate);
 }
 
 
@@ -14733,6 +15454,8 @@
   StringSharedKey key(src, outer_info, strict_mode, scope_position);
   int entry = FindEntry(&key);
   if (entry == kNotFound) return isolate->factory()->undefined_value();
+  int index = EntryToIndex(entry);
+  if (!get(index)->IsFixedArray()) return isolate->factory()->undefined_value();
   return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
 }
 
@@ -14755,11 +15478,23 @@
   Handle<SharedFunctionInfo> shared(context->closure()->shared());
   StringSharedKey key(src, shared, FLAG_use_strict ? STRICT : SLOPPY,
                       RelocInfo::kNoPosition);
+  {
+    Handle<Object> k = key.AsHandle(isolate);
+    DisallowHeapAllocation no_allocation_scope;
+    int entry = cache->FindEntry(&key);
+    if (entry != kNotFound) {
+      cache->set(EntryToIndex(entry), *k);
+      cache->set(EntryToIndex(entry) + 1, *value);
+      return cache;
+    }
+  }
+
   cache = EnsureCapacity(cache, 1, &key);
-  Handle<Object> k = key.AsHandle(isolate);
   int entry = cache->FindInsertionEntry(key.Hash());
+  Handle<Object> k =
+      isolate->factory()->NewNumber(static_cast<double>(key.Hash()));
   cache->set(EntryToIndex(entry), *k);
-  cache->set(EntryToIndex(entry) + 1, *value);
+  cache->set(EntryToIndex(entry) + 1, Smi::FromInt(kHashGenerations));
   cache->ElementAdded();
   return cache;
 }
@@ -14771,11 +15506,23 @@
     int scope_position) {
   Isolate* isolate = cache->GetIsolate();
   StringSharedKey key(src, outer_info, value->strict_mode(), scope_position);
+  {
+    Handle<Object> k = key.AsHandle(isolate);
+    DisallowHeapAllocation no_allocation_scope;
+    int entry = cache->FindEntry(&key);
+    if (entry != kNotFound) {
+      cache->set(EntryToIndex(entry), *k);
+      cache->set(EntryToIndex(entry) + 1, *value);
+      return cache;
+    }
+  }
+
   cache = EnsureCapacity(cache, 1, &key);
-  Handle<Object> k = key.AsHandle(isolate);
   int entry = cache->FindInsertionEntry(key.Hash());
+  Handle<Object> k =
+      isolate->factory()->NewNumber(static_cast<double>(key.Hash()));
   cache->set(EntryToIndex(entry), *k);
-  cache->set(EntryToIndex(entry) + 1, *value);
+  cache->set(EntryToIndex(entry) + 1, Smi::FromInt(kHashGenerations));
   cache->ElementAdded();
   return cache;
 }
@@ -14796,6 +15543,35 @@
 }
 
 
+void CompilationCacheTable::Age() {
+  DisallowHeapAllocation no_allocation;
+  Object* the_hole_value = GetHeap()->the_hole_value();
+  for (int entry = 0, size = Capacity(); entry < size; entry++) {
+    int entry_index = EntryToIndex(entry);
+    int value_index = entry_index + 1;
+
+    if (get(entry_index)->IsNumber()) {
+      Smi* count = Smi::cast(get(value_index));
+      count = Smi::FromInt(count->value() - 1);
+      if (count->value() == 0) {
+        NoWriteBarrierSet(this, entry_index, the_hole_value);
+        NoWriteBarrierSet(this, value_index, the_hole_value);
+        ElementRemoved();
+      } else {
+        NoWriteBarrierSet(this, value_index, count);
+      }
+    } else if (get(entry_index)->IsFixedArray()) {
+      SharedFunctionInfo* info = SharedFunctionInfo::cast(get(value_index));
+      if (info->code()->kind() != Code::FUNCTION || info->code()->IsOld()) {
+        NoWriteBarrierSet(this, entry_index, the_hole_value);
+        NoWriteBarrierSet(this, value_index, the_hole_value);
+        ElementRemoved();
+      }
+    }
+  }
+}
+
+
 void CompilationCacheTable::Remove(Object* value) {
   DisallowHeapAllocation no_allocation;
   Object* the_hole_value = GetHeap()->the_hole_value();
@@ -14846,28 +15622,6 @@
 };
 
 
-Object* MapCache::Lookup(FixedArray* array) {
-  DisallowHeapAllocation no_alloc;
-  StringsKey key(handle(array));
-  int entry = FindEntry(&key);
-  if (entry == kNotFound) return GetHeap()->undefined_value();
-  return get(EntryToIndex(entry) + 1);
-}
-
-
-Handle<MapCache> MapCache::Put(
-    Handle<MapCache> map_cache, Handle<FixedArray> array, Handle<Map> value) {
-  StringsKey key(array);
-
-  Handle<MapCache> new_cache = EnsureCapacity(map_cache, 1, &key);
-  int entry = new_cache->FindInsertionEntry(key.Hash());
-  new_cache->set(EntryToIndex(entry), *array);
-  new_cache->set(EntryToIndex(entry) + 1, *value);
-  new_cache->ElementAdded();
-  return new_cache;
-}
-
-
 template<typename Derived, typename Shape, typename Key>
 Handle<Derived> Dictionary<Derived, Shape, Key>::New(
     Isolate* isolate,
@@ -14885,56 +15639,61 @@
 }
 
 
-template<typename Derived, typename Shape, typename Key>
-void Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices(
+template <typename Derived, typename Shape, typename Key>
+Handle<FixedArray> Dictionary<Derived, Shape, Key>::BuildIterationIndicesArray(
     Handle<Derived> dictionary) {
   Factory* factory = dictionary->GetIsolate()->factory();
   int length = dictionary->NumberOfElements();
 
-  // Allocate and initialize iteration order array.
   Handle<FixedArray> iteration_order = factory->NewFixedArray(length);
-  for (int i = 0; i < length; i++) {
-    iteration_order->set(i, Smi::FromInt(i));
-  }
-
-  // Allocate array with enumeration order.
   Handle<FixedArray> enumeration_order = factory->NewFixedArray(length);
 
-  // Fill the enumeration order array with property details.
+  // Fill both the iteration order array and the enumeration order array
+  // with property details.
   int capacity = dictionary->Capacity();
   int pos = 0;
   for (int i = 0; i < capacity; i++) {
     if (dictionary->IsKey(dictionary->KeyAt(i))) {
       int index = dictionary->DetailsAt(i).dictionary_index();
-      enumeration_order->set(pos++, Smi::FromInt(index));
+      iteration_order->set(pos, Smi::FromInt(i));
+      enumeration_order->set(pos, Smi::FromInt(index));
+      pos++;
     }
   }
+  DCHECK(pos == length);
 
   // Sort the arrays wrt. enumeration order.
   iteration_order->SortPairs(*enumeration_order, enumeration_order->length());
+  return iteration_order;
+}
 
-  // Overwrite the enumeration_order with the enumeration indices.
+
+template <typename Derived, typename Shape, typename Key>
+Handle<FixedArray>
+Dictionary<Derived, Shape, Key>::GenerateNewEnumerationIndices(
+    Handle<Derived> dictionary) {
+  int length = dictionary->NumberOfElements();
+
+  Handle<FixedArray> iteration_order = BuildIterationIndicesArray(dictionary);
+  DCHECK(iteration_order->length() == length);
+
+  // Iterate over the dictionary using the enumeration order and update
+  // the dictionary with new enumeration indices.
   for (int i = 0; i < length; i++) {
     int index = Smi::cast(iteration_order->get(i))->value();
-    int enum_index = PropertyDetails::kInitialIndex + i;
-    enumeration_order->set(index, Smi::FromInt(enum_index));
-  }
+    DCHECK(dictionary->IsKey(dictionary->KeyAt(index)));
 
-  // Update the dictionary with new indices.
-  capacity = dictionary->Capacity();
-  pos = 0;
-  for (int i = 0; i < capacity; i++) {
-    if (dictionary->IsKey(dictionary->KeyAt(i))) {
-      int enum_index = Smi::cast(enumeration_order->get(pos++))->value();
-      PropertyDetails details = dictionary->DetailsAt(i);
-      PropertyDetails new_details = PropertyDetails(
-          details.attributes(), details.type(), enum_index);
-      dictionary->DetailsAtPut(i, new_details);
-    }
+    int enum_index = PropertyDetails::kInitialIndex + i;
+
+    PropertyDetails details = dictionary->DetailsAt(index);
+    PropertyDetails new_details =
+        PropertyDetails(details.attributes(), details.type(), enum_index);
+    dictionary->DetailsAtPut(index, new_details);
   }
 
   // Set the next enumeration index.
   dictionary->SetNextEnumerationIndex(PropertyDetails::kInitialIndex+length);
+  return iteration_order;
 }
 
 
@@ -14986,7 +15745,7 @@
 #ifdef DEBUG
   USE(Shape::AsHandle(dictionary->GetIsolate(), key));
 #endif
-  PropertyDetails details = PropertyDetails(NONE, NORMAL, 0);
+  PropertyDetails details(NONE, FIELD, 0);
 
   AddEntry(dictionary, key, value, details, dictionary->Hash(key));
   return dictionary;
@@ -15074,7 +15833,7 @@
     uint32_t key,
     Handle<Object> value) {
   SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound);
-  return Add(dictionary, key, value, PropertyDetails(NONE, NORMAL, 0));
+  return Add(dictionary, key, value, PropertyDetails(NONE, FIELD, 0));
 }
 
 
@@ -15154,10 +15913,26 @@
 }
 
 
-template<typename Derived, typename Shape, typename Key>
+template <typename Derived, typename Shape, typename Key>
+bool Dictionary<Derived, Shape, Key>::HasComplexElements() {
+  int capacity = DerivedHashTable::Capacity();
+  for (int i = 0; i < capacity; i++) {
+    Object* k = DerivedHashTable::KeyAt(i);
+    if (DerivedHashTable::IsKey(k) && !FilterKey(k, NONE)) {
+      PropertyDetails details = DetailsAt(i);
+      if (details.IsDeleted()) continue;
+      if (details.type() == CALLBACKS) return true;
+      PropertyAttributes attr = details.attributes();
+      if (attr & (READ_ONLY | DONT_DELETE | DONT_ENUM)) return true;
+    }
+  }
+  return false;
+}
+
+
+template <typename Derived, typename Shape, typename Key>
 void Dictionary<Derived, Shape, Key>::CopyKeysTo(
-    FixedArray* storage,
-    PropertyAttributes filter,
+    FixedArray* storage, PropertyAttributes filter,
     typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) {
   DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter));
   int capacity = DerivedHashTable::Capacity();
@@ -15448,7 +16223,7 @@
                table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED);
 
   table->SetNextTable(*new_table);
-  table->SetNumberOfDeletedElements(-1);
+  table->SetNumberOfDeletedElements(kClearedTableSentinel);
 
   return new_table;
 }
@@ -15693,8 +16468,7 @@
     if (index > 0) {
       int nod = table->NumberOfDeletedElements();
 
-      // When we clear the table we set the number of deleted elements to -1.
-      if (nod == -1) {
+      if (nod == TableType::kClearedTableSentinel) {
         index = 0;
       } else {
         int old_index = index;
@@ -16223,13 +16997,15 @@
 
 
 void JSArrayBuffer::Neuter() {
-  DCHECK(is_external());
+  CHECK(is_neuterable());
+  CHECK(is_external());
   set_backing_store(NULL);
   set_byte_length(Smi::FromInt(0));
 }
 
 
 void JSArrayBufferView::NeuterView() {
+  CHECK(JSArrayBuffer::cast(buffer())->is_neuterable());
   set_byte_offset(Smi::FromInt(0));
   set_byte_length(Smi::FromInt(0));
 }
@@ -16337,13 +17113,24 @@
 }
 
 
-void PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
-                                     Handle<Object> value) {
+Handle<Object> PropertyCell::SetValueInferType(Handle<PropertyCell> cell,
+                                               Handle<Object> value) {
+  // Heuristic: if a small-ish string is stored in a previously uninitialized
+  // property cell, internalize it.
+  const int kMaxLengthForInternalization = 200;
+  if ((cell->type()->Is(HeapType::None()) ||
+       cell->type()->Is(HeapType::Undefined())) &&
+      value->IsString() &&
+      Handle<String>::cast(value)->length() <= kMaxLengthForInternalization) {
+    value = cell->GetIsolate()->factory()->InternalizeString(
+        Handle<String>::cast(value));
+  }
   cell->set_value(*value);
   if (!HeapType::Any()->Is(cell->type())) {
     Handle<HeapType> new_type = UpdatedType(cell, value);
     cell->set_type(*new_type);
   }
+  return value;
 }
 
 
diff --git a/src/objects.h b/src/objects.h
index 3340350..c32f9f6 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -5,6 +5,8 @@
 #ifndef V8_OBJECTS_H_
 #define V8_OBJECTS_H_
 
+#include <iosfwd>
+
 #include "src/allocation.h"
 #include "src/assert-scope.h"
 #include "src/bailout-reason.h"
@@ -18,6 +20,7 @@
 #include "src/property-details.h"
 #include "src/smart-pointers.h"
 #include "src/unicode-inl.h"
+#include "src/unicode-decoder.h"
 #include "src/zone.h"
 
 #if V8_TARGET_ARCH_ARM
@@ -84,6 +87,8 @@
 //         - JSFunctionResultCache
 //         - ScopeInfo
 //         - TransitionArray
+//         - ScriptContextTable
+//         - WeakFixedArray
 //       - FixedDoubleArray
 //       - ExternalArray
 //         - ExternalUint8ClampedArray
@@ -140,6 +145,7 @@
 //       - DebugInfo
 //       - BreakPointInfo
 //       - CodeCache
+//     - WeakCell
 //
 // Formats of Object*:
 //  Smi:        [31 bit signed int] 0
@@ -148,8 +154,6 @@
 namespace v8 {
 namespace internal {
 
-class OStream;
-
 enum KeyedAccessStoreMode {
   STANDARD_STORE,
   STORE_TRANSITION_SMI_TO_OBJECT,
@@ -231,15 +235,15 @@
 }
 
 
+enum IcCheckType { ELEMENT, PROPERTY };
+
+
 // Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER.
 enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER };
 
 
 // Indicates whether a value can be loaded as a constant.
-enum StoreMode {
-  ALLOW_AS_CONSTANT,
-  FORCE_FIELD
-};
+enum StoreMode { ALLOW_IN_DESCRIPTOR, FORCE_IN_OBJECT };
 
 
 // PropertyNormalizationMode is used to specify whether to keep
@@ -275,8 +279,9 @@
 // either extends the current map with a new property, or it modifies the
 // property that was added last to the current map.
 enum SimpleTransitionFlag {
-  SIMPLE_TRANSITION,
-  FULL_TRANSITION
+  SIMPLE_PROPERTY_TRANSITION,
+  PROPERTY_TRANSITION,
+  SPECIAL_TRANSITION
 };
 
 
@@ -421,6 +426,7 @@
   V(FIXED_DOUBLE_ARRAY_TYPE)                                    \
   V(CONSTANT_POOL_ARRAY_TYPE)                                   \
   V(SHARED_FUNCTION_INFO_TYPE)                                  \
+  V(WEAK_CELL_TYPE)                                             \
                                                                 \
   V(JS_MESSAGE_OBJECT_TYPE)                                     \
                                                                 \
@@ -717,6 +723,7 @@
   FIXED_ARRAY_TYPE,
   CONSTANT_POOL_ARRAY_TYPE,
   SHARED_FUNCTION_INFO_TYPE,
+  WEAK_CELL_TYPE,
 
   // All the following types are subtypes of JSReceiver, which corresponds to
   // objects in the JS sense. The first and the last type in this range are
@@ -845,14 +852,17 @@
 class AllocationSite;
 class AllocationSiteCreationContext;
 class AllocationSiteUsageContext;
+class ConsString;
 class DictionaryElementsAccessor;
 class ElementsAccessor;
 class FixedArrayBase;
 class GlobalObject;
-class ObjectVisitor;
+class LayoutDescriptor;
 class LookupIterator;
+class ObjectVisitor;
 class StringStream;
 class TypeFeedbackVector;
+class WeakCell;
 // We cannot just say "class HeapType;" if it is created from a template... =8-?
 template<class> class TypeImpl;
 struct HeapTypeConfig;
@@ -869,7 +879,7 @@
 #endif
 
 #ifdef OBJECT_PRINT
-#define DECLARE_PRINTER(Name) void Name##Print(OStream& os);  // NOLINT
+#define DECLARE_PRINTER(Name) void Name##Print(std::ostream& os);  // NOLINT
 #else
 #define DECLARE_PRINTER(Name)
 #endif
@@ -924,6 +934,7 @@
   V(JSContextExtensionObject)      \
   V(JSGeneratorObject)             \
   V(JSModule)                      \
+  V(LayoutDescriptor)              \
   V(Map)                           \
   V(DescriptorArray)               \
   V(TransitionArray)               \
@@ -933,8 +944,10 @@
   V(DependentCode)                 \
   V(FixedArray)                    \
   V(FixedDoubleArray)              \
+  V(WeakFixedArray)                \
   V(ConstantPoolArray)             \
   V(Context)                       \
+  V(ScriptContextTable)            \
   V(NativeContext)                 \
   V(ScopeInfo)                     \
   V(JSFunction)                    \
@@ -980,6 +993,7 @@
   V(AccessCheckNeeded)             \
   V(Cell)                          \
   V(PropertyCell)                  \
+  V(WeakCell)                      \
   V(ObjectHashTable)               \
   V(WeakHashTable)                 \
   V(OrderedHashTable)
@@ -1007,6 +1021,8 @@
     CERTAINLY_NOT_STORE_FROM_KEYED
   };
 
+  enum StorePropertyMode { NORMAL_PROPERTY, SUPER_PROPERTY };
+
   INLINE(bool IsFixedArrayBase() const);
   INLINE(bool IsExternal() const);
   INLINE(bool IsAccessorInfo() const);
@@ -1116,11 +1132,15 @@
 
   MUST_USE_RESULT static MaybeHandle<Object> SetProperty(
       LookupIterator* it, Handle<Object> value, StrictMode strict_mode,
-      StoreFromKeyed store_mode);
+      StoreFromKeyed store_mode,
+      StorePropertyMode data_store_mode = NORMAL_PROPERTY);
   MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyProperty(
       LookupIterator* it, Handle<Object> value, StrictMode strict_mode);
-  static Handle<Object> SetDataProperty(LookupIterator* it,
-                                        Handle<Object> value);
+  MUST_USE_RESULT static MaybeHandle<Object> WriteToReadOnlyElement(
+      Isolate* isolate, Handle<Object> receiver, uint32_t index,
+      Handle<Object> value, StrictMode strict_mode);
+  MUST_USE_RESULT static MaybeHandle<Object> SetDataProperty(
+      LookupIterator* it, Handle<Object> value);
   MUST_USE_RESULT static MaybeHandle<Object> AddDataProperty(
       LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
       StrictMode strict_mode, StoreFromKeyed store_mode);
@@ -1164,6 +1184,13 @@
       Handle<Object> receiver,
       uint32_t index);
 
+  MUST_USE_RESULT static MaybeHandle<Object> SetElementWithReceiver(
+      Isolate* isolate, Handle<Object> object, Handle<Object> receiver,
+      uint32_t index, Handle<Object> value, StrictMode strict_mode);
+
+  static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
+      Isolate* isolate, Handle<Object> receiver);
+
   // Returns the permanent hash code associated with this object. May return
   // undefined if not yet created.
   Object* GetHash();
@@ -1206,6 +1233,8 @@
   // Prints this object without details to a message accumulator.
   void ShortPrint(StringStream* accumulator);
 
+  void ShortPrint(std::ostream& os);  // NOLINT
+
   DECLARE_CAST(Object)
 
   // Layout description.
@@ -1216,7 +1245,10 @@
   void Print();
 
   // Prints this object with details.
-  void Print(OStream& os);  // NOLINT
+  void Print(std::ostream& os);  // NOLINT
+#else
+  void Print() { ShortPrint(); }
+  void Print(std::ostream& os) { ShortPrint(os); }  // NOLINT
 #endif
 
  private:
@@ -1236,7 +1268,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const Brief& v);
+std::ostream& operator<<(std::ostream& os, const Brief& v);
 
 
 // Smi represents integer Numbers that can be stored in 31 bits.
@@ -1261,7 +1293,7 @@
   DECLARE_CAST(Smi)
 
   // Dispatched behavior.
-  void SmiPrint(OStream& os) const;  // NOLINT
+  void SmiPrint(std::ostream& os) const;  // NOLINT
   DECLARE_VERIFIER(Smi)
 
   static const int kMinValue =
@@ -1404,9 +1436,9 @@
       const DisallowHeapAllocation& promise);
 
   // Dispatched behavior.
-  void HeapObjectShortPrint(OStream& os);  // NOLINT
+  void HeapObjectShortPrint(std::ostream& os);  // NOLINT
 #ifdef OBJECT_PRINT
-  void PrintHeader(OStream& os, const char* id);  // NOLINT
+  void PrintHeader(std::ostream& os, const char* id);  // NOLINT
 #endif
   DECLARE_PRINTER(HeapObject)
   DECLARE_VERIFIER(HeapObject)
@@ -1419,6 +1451,8 @@
   static void VerifyHeapPointer(Object* p);
 #endif
 
+  inline bool NeedsToEnsureDoubleAlignment();
+
   // Layout description.
   // First field in a heap object is map.
   static const int kMapOffset = Object::kHeaderSize;
@@ -1493,7 +1527,7 @@
   // Dispatched behavior.
   bool HeapNumberBooleanValue();
 
-  void HeapNumberPrint(OStream& os);  // NOLINT
+  void HeapNumberPrint(std::ostream& os);  // NOLINT
   DECLARE_VERIFIER(HeapNumber)
 
   inline int get_exponent();
@@ -1618,9 +1652,6 @@
   MUST_USE_RESULT static inline Maybe<PropertyAttributes>
       GetOwnElementAttribute(Handle<JSReceiver> object, uint32_t index);
 
-  // Return the constructor function (may be Heap::null_value()).
-  inline Object* GetConstructor();
-
   // Retrieves a permanent object identity hash code. The undefined value might
   // be returned in case no hash was created yet.
   inline Object* GetIdentityHash();
@@ -1792,6 +1823,10 @@
   static void OptimizeAsPrototype(Handle<JSObject> object,
                                   PrototypeOptimizationMode mode);
   static void ReoptimizeIfPrototype(Handle<JSObject> object);
+  static void RegisterPrototypeUser(Handle<JSObject> prototype,
+                                    Handle<HeapObject> user);
+  static void UnregisterPrototypeUser(Handle<JSObject> prototype,
+                                      Handle<HeapObject> user);
 
   // Retrieve interceptors.
   InterceptorInfo* GetNamedInterceptor();
@@ -1834,10 +1869,6 @@
       Handle<Object> receiver,
       Handle<Name> name);
 
-  // Returns true if this is an instance of an api function and has
-  // been modified since it was created.  May give false positives.
-  bool IsDirty();
-
   // Accessors for hidden properties object.
   //
   // Hidden properties are not own properties of the object itself.
@@ -1912,8 +1943,7 @@
 
   // These methods do not perform access checks!
   MUST_USE_RESULT static MaybeHandle<AccessorPair> GetOwnElementAccessorPair(
-      Handle<JSObject> object,
-      uint32_t index);
+      Handle<JSObject> object, uint32_t index);
 
   MUST_USE_RESULT static MaybeHandle<Object> SetFastElement(
       Handle<JSObject> object,
@@ -1941,9 +1971,8 @@
   // Returns the index'th element.
   // The undefined object if index is out of bounds.
   MUST_USE_RESULT static MaybeHandle<Object> GetElementWithInterceptor(
-      Handle<JSObject> object,
-      Handle<Object> receiver,
-      uint32_t index);
+      Handle<JSObject> object, Handle<Object> receiver, uint32_t index,
+      bool check_prototype);
 
   enum SetFastElementsCapacitySmiMode {
     kAllowSmiElements,
@@ -2034,7 +2063,8 @@
   // an initial capacity for holding these properties.
   static void NormalizeProperties(Handle<JSObject> object,
                                   PropertyNormalizationMode mode,
-                                  int expected_additional_properties);
+                                  int expected_additional_properties,
+                                  const char* reason);
 
   // Convert and update the elements backing store to be a
   // SeededNumberDictionary dictionary.  Returns the backing after conversion.
@@ -2043,14 +2073,20 @@
 
   // Transform slow named properties to fast variants.
   static void MigrateSlowToFast(Handle<JSObject> object,
-                                int unused_property_fields);
+                                int unused_property_fields, const char* reason);
+
+  inline bool IsUnboxedDoubleField(FieldIndex index);
 
   // Access fast-case object properties at index.
   static Handle<Object> FastPropertyAt(Handle<JSObject> object,
                                        Representation representation,
                                        FieldIndex index);
   inline Object* RawFastPropertyAt(FieldIndex index);
+  inline double RawFastDoublePropertyAt(FieldIndex index);
+
   inline void FastPropertyAtPut(FieldIndex index, Object* value);
+  inline void RawFastPropertyAtPut(FieldIndex index, Object* value);
+  inline void RawFastDoublePropertyAtPut(FieldIndex index, double value);
   void WriteToField(int descriptor, Object* value);
 
   // Access to in object properties.
@@ -2081,6 +2117,9 @@
   MUST_USE_RESULT static MaybeHandle<Object> PreventExtensions(
       Handle<JSObject> object);
 
+  // ES5 Object.seal
+  MUST_USE_RESULT static MaybeHandle<Object> Seal(Handle<JSObject> object);
+
   // ES5 Object.freeze
   MUST_USE_RESULT static MaybeHandle<Object> Freeze(Handle<JSObject> object);
 
@@ -2110,9 +2149,11 @@
   DECLARE_PRINTER(JSObject)
   DECLARE_VERIFIER(JSObject)
 #ifdef OBJECT_PRINT
-  void PrintProperties(OStream& os);   // NOLINT
-  void PrintElements(OStream& os);     // NOLINT
-  void PrintTransitions(OStream& os);  // NOLINT
+  void PrintProperties(std::ostream& os);   // NOLINT
+  void PrintElements(std::ostream& os);     // NOLINT
+#endif
+#if defined(DEBUG) || defined(OBJECT_PRINT)
+  void PrintTransitions(std::ostream& os);  // NOLINT
 #endif
 
   static void PrintElementsTransition(
@@ -2201,14 +2242,9 @@
   Context* GetCreationContext();
 
   // Enqueue change record for Object.observe. May cause GC.
-  static void EnqueueChangeRecord(Handle<JSObject> object,
-                                  const char* type,
-                                  Handle<Name> name,
-                                  Handle<Object> old_value);
-
-  static void MigrateToNewProperty(Handle<JSObject> object,
-                                   Handle<Map> transition,
-                                   Handle<Object> value);
+  MUST_USE_RESULT static MaybeHandle<Object> EnqueueChangeRecord(
+      Handle<JSObject> object, const char* type, Handle<Name> name,
+      Handle<Object> old_value);
 
  private:
   friend class DictionaryElementsAccessor;
@@ -2220,11 +2256,6 @@
                                 Handle<Map> new_map,
                                 int expected_additional_properties);
 
-  static void GeneralizeFieldRepresentation(Handle<JSObject> object,
-                                            int modify_index,
-                                            Representation new_representation,
-                                            Handle<HeapType> new_field_type);
-
   static void UpdateAllocationSite(Handle<JSObject> object,
                                    ElementsKind to_kind);
 
@@ -2243,18 +2274,30 @@
       GetElementAttributeWithInterceptor(Handle<JSObject> object,
                                          Handle<JSReceiver> receiver,
                                          uint32_t index, bool continue_search);
+
+  // Queries indexed interceptor on an object for property attributes.
+  //
+  // We determine property attributes as follows:
+  // - if interceptor has a query callback, then the  property attributes are
+  //   the result of query callback for index.
+  // - otherwise if interceptor has a getter callback and it returns
+  //   non-empty value on index, then the property attributes is NONE
+  //   (property is present, and it is enumerable, configurable, writable)
+  // - otherwise there are no property attributes that can be inferred for
+  //   interceptor, and this function returns ABSENT.
+  MUST_USE_RESULT static Maybe<PropertyAttributes>
+      GetElementAttributeFromInterceptor(Handle<JSObject> object,
+                                         Handle<Object> receiver,
+                                         uint32_t index);
+
   MUST_USE_RESULT static Maybe<PropertyAttributes>
       GetElementAttributeWithoutInterceptor(Handle<JSObject> object,
                                             Handle<JSReceiver> receiver,
                                             uint32_t index,
                                             bool continue_search);
   MUST_USE_RESULT static MaybeHandle<Object> SetElementWithCallback(
-      Handle<JSObject> object,
-      Handle<Object> structure,
-      uint32_t index,
-      Handle<Object> value,
-      Handle<JSObject> holder,
-      StrictMode strict_mode);
+      Handle<Object> object, Handle<Object> structure, uint32_t index,
+      Handle<Object> value, Handle<JSObject> holder, StrictMode strict_mode);
   MUST_USE_RESULT static MaybeHandle<Object> SetElementWithInterceptor(
       Handle<JSObject> object,
       uint32_t index,
@@ -2292,6 +2335,14 @@
       Handle<Object> value,
       StrictMode strict_mode,
       bool check_prototype = true);
+  MUST_USE_RESULT static MaybeHandle<Object> GetElementWithFailedAccessCheck(
+      Isolate* isolate, Handle<JSObject> object, Handle<Object> receiver,
+      uint32_t index);
+  MUST_USE_RESULT static Maybe<PropertyAttributes>
+  GetElementAttributesWithFailedAccessCheck(Isolate* isolate,
+                                            Handle<JSObject> object,
+                                            Handle<Object> receiver,
+                                            uint32_t index);
 
   MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithFailedAccessCheck(
       LookupIterator* it, Handle<Object> value, StrictMode strict_mode);
@@ -2366,6 +2417,15 @@
 
   static Handle<Smi> GetOrCreateIdentityHash(Handle<JSObject> object);
 
+  static Handle<SeededNumberDictionary> GetNormalizedElementDictionary(
+      Handle<JSObject> object);
+
+  // Helper for fast versions of preventExtensions, seal, and freeze.
+  // attrs is one of NONE, SEALED, or FROZEN (depending on the operation).
+  template <PropertyAttributes attrs>
+  MUST_USE_RESULT static MaybeHandle<Object> PreventExtensionsWithTransition(
+      Handle<JSObject> object);
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
 };
 
@@ -2399,7 +2459,7 @@
 class FixedArray: public FixedArrayBase {
  public:
   // Setter and getter for elements.
-  inline Object* get(int index);
+  inline Object* get(int index) const;
   static inline Handle<Object> get(Handle<FixedArray> array, int index);
   // Setter that uses write barrier.
   inline void set(int index, Object* value);
@@ -2431,10 +2491,12 @@
                                      int new_length,
                                      PretenureFlag pretenure = NOT_TENURED);
 
+  enum KeyFilter { ALL_KEYS, NON_SYMBOL_KEYS };
+
   // Add the elements of a JSArray to this FixedArray.
   MUST_USE_RESULT static MaybeHandle<FixedArray> AddKeysFromArrayLike(
-      Handle<FixedArray> content,
-      Handle<JSObject> array);
+      Handle<FixedArray> content, Handle<JSObject> array,
+      KeyFilter filter = ALL_KEYS);
 
   // Computes the union of keys and return the result.
   // Used for implementing "for (n in object) { }"
@@ -2559,6 +2621,45 @@
 };
 
 
+class WeakFixedArray : public FixedArray {
+ public:
+  enum SearchForDuplicates { kAlwaysAdd, kAddIfNotFound };
+
+  // If |maybe_array| is not a WeakFixedArray, a fresh one will be allocated.
+  static Handle<WeakFixedArray> Add(
+      Handle<Object> maybe_array, Handle<HeapObject> value,
+      SearchForDuplicates search_for_duplicates = kAlwaysAdd);
+
+  void Remove(Handle<HeapObject> value);
+
+  inline Object* Get(int index) const;
+  inline int Length() const;
+
+  DECLARE_CAST(WeakFixedArray)
+
+ private:
+  static const int kLastUsedIndexIndex = 0;
+  static const int kFirstIndex = 1;
+
+  static Handle<WeakFixedArray> Allocate(
+      Isolate* isolate, int size, Handle<WeakFixedArray> initialize_from);
+
+  static void Set(Handle<WeakFixedArray> array, int index,
+                  Handle<HeapObject> value);
+  inline void clear(int index);
+  inline bool IsEmptySlot(int index) const;
+
+  inline int last_used_index() const;
+  inline void set_last_used_index(int index);
+
+  // Disallow inherited setters.
+  void set(int index, Smi* value);
+  void set(int index, Object* value);
+  void set(int index, Object* value, WriteBarrierMode mode);
+  DISALLOW_IMPLICIT_CONSTRUCTORS(WeakFixedArray);
+};
+
+
 // ConstantPoolArray describes a fixed-sized array containing constant pool
 // entries.
 //
@@ -2596,11 +2697,7 @@
 //
 class ConstantPoolArray: public HeapObject {
  public:
-  enum WeakObjectState {
-    NO_WEAK_OBJECTS,
-    WEAK_OBJECTS_IN_OPTIMIZED_CODE,
-    WEAK_OBJECTS_IN_IC
-  };
+  enum WeakObjectState { NO_WEAK_OBJECTS, WEAK_OBJECTS_IN_OPTIMIZED_CODE };
 
   enum Type {
     INT64 = 0,
@@ -2841,13 +2938,13 @@
   // get_extended_section_header_offset().
   static const int kExtendedInt64CountOffset = 0;
   static const int kExtendedCodePtrCountOffset =
-      kExtendedInt64CountOffset + kPointerSize;
+      kExtendedInt64CountOffset + kInt32Size;
   static const int kExtendedHeapPtrCountOffset =
-      kExtendedCodePtrCountOffset + kPointerSize;
+      kExtendedCodePtrCountOffset + kInt32Size;
   static const int kExtendedInt32CountOffset =
-      kExtendedHeapPtrCountOffset + kPointerSize;
+      kExtendedHeapPtrCountOffset + kInt32Size;
   static const int kExtendedFirstOffset =
-      kExtendedInt32CountOffset + kPointerSize;
+      kExtendedInt32CountOffset + kInt32Size;
 
   // Dispatched behavior.
   void ConstantPoolIterateBody(ObjectVisitor* v);
@@ -3034,9 +3131,12 @@
   static const int kDescriptorValue = 2;
   static const int kDescriptorSize = 3;
 
-#ifdef OBJECT_PRINT
+#if defined(DEBUG) || defined(OBJECT_PRINT)
+  // For our gdb macros, we should perhaps change these in the future.
+  void Print();
+
   // Print all the descriptors.
-  void PrintDescriptors(OStream& os);  // NOLINT
+  void PrintDescriptors(std::ostream& os);  // NOLINT
 #endif
 
 #ifdef DEBUG
@@ -3109,9 +3209,7 @@
 
   // Transfer a complete descriptor from the src descriptor array to this
   // descriptor array.
-  void CopyFrom(int index,
-                DescriptorArray* src,
-                const WhitenessWitness&);
+  void CopyFrom(int index, DescriptorArray* src, const WhitenessWitness&);
 
   inline void Set(int descriptor_number,
                   Descriptor* desc,
@@ -3126,12 +3224,9 @@
 
 enum SearchMode { ALL_ENTRIES, VALID_ENTRIES };
 
-template<SearchMode search_mode, typename T>
-inline int LinearSearch(T* array, Name* name, int len, int valid_entries);
-
-
-template<SearchMode search_mode, typename T>
-inline int Search(T* array, Name* name, int valid_entries = 0);
+template <SearchMode search_mode, typename T>
+inline int Search(T* array, Name* name, int valid_entries = 0,
+                  int* out_insertion_index = NULL);
 
 
 // HashTable is a subclass of FixedArray that implements a hash table
@@ -3430,6 +3525,8 @@
       uint16_t c1,
       uint16_t c2);
 
+  static void EnsureCapacityForDeserialization(Isolate* isolate, int expected);
+
   DECLARE_CAST(StringTable)
 
  private:
@@ -3440,44 +3537,6 @@
 };
 
 
-class MapCacheShape : public BaseShape<HashTableKey*> {
- public:
-  static inline bool IsMatch(HashTableKey* key, Object* value) {
-    return key->IsMatch(value);
-  }
-
-  static inline uint32_t Hash(HashTableKey* key) {
-    return key->Hash();
-  }
-
-  static inline uint32_t HashForObject(HashTableKey* key, Object* object) {
-    return key->HashForObject(object);
-  }
-
-  static inline Handle<Object> AsHandle(Isolate* isolate, HashTableKey* key);
-
-  static const int kPrefixSize = 0;
-  static const int kEntrySize = 2;
-};
-
-
-// MapCache.
-//
-// Maps keys that are a fixed array of unique names to a map.
-// Used for canonicalize maps for object literals.
-class MapCache: public HashTable<MapCache, MapCacheShape, HashTableKey*> {
- public:
-  // Find cached value for a name key, otherwise return null.
-  Object* Lookup(FixedArray* key);
-  static Handle<MapCache> Put(
-      Handle<MapCache> map_cache, Handle<FixedArray> key, Handle<Map> value);
-  DECLARE_CAST(MapCache)
-
- private:
-  DISALLOW_IMPLICIT_CONSTRUCTORS(MapCache);
-};
-
-
 template <typename Derived, typename Shape, typename Key>
 class Dictionary: public HashTable<Derived, Shape, Key> {
  protected:
@@ -3529,6 +3588,10 @@
   // Returns the number of enumerable elements in the dictionary.
   int NumberOfEnumElements();
 
+  // Returns true if the dictionary contains any elements that are non-writable,
+  // non-configurable, non-enumerable, or have getters/setters.
+  bool HasComplexElements();
+
   enum SortMode { UNSORTED, SORTED };
   // Copies keys to preallocated fixed array.
   void CopyKeysTo(FixedArray* storage,
@@ -3560,7 +3623,7 @@
   static Handle<Derived> EnsureCapacity(Handle<Derived> obj, int n, Key key);
 
 #ifdef OBJECT_PRINT
-  void Print(OStream& os);  // NOLINT
+  void Print(std::ostream& os);  // NOLINT
 #endif
   // Returns the key (slow).
   Object* SlowReverseLookup(Object* value);
@@ -3580,6 +3643,11 @@
       Handle<Object> value,
       PropertyDetails details);
 
+  // Returns iteration indices array for the |dictionary|.
+  // Values are direct indices in the |HashTable| array.
+  static Handle<FixedArray> BuildIterationIndicesArray(
+      Handle<Derived> dictionary);
+
  protected:
   // Generic at put operation.
   MUST_USE_RESULT static Handle<Derived> AtPut(
@@ -3596,7 +3664,9 @@
       uint32_t hash);
 
   // Generate new enumeration indices to avoid enumeration index overflow.
-  static void GenerateNewEnumerationIndices(Handle<Derived> dictionary);
+  // Returns iteration indices array for the |dictionary|.
+  static Handle<FixedArray> GenerateNewEnumerationIndices(
+      Handle<Derived> dictionary);
   static const int kMaxNumberKeyIndex = DerivedHashTable::kPrefixStartIndex;
   static const int kNextEnumerationIndexIndex = kMaxNumberKeyIndex + 1;
 };
@@ -3625,7 +3695,7 @@
 
   // Copies enumerable keys to preallocated fixed array.
   void CopyEnumKeysTo(FixedArray* storage);
-  inline static void DoGenerateNewEnumerationIndices(
+  inline static Handle<FixedArray> DoGenerateNewEnumerationIndices(
       Handle<NameDictionary> dictionary);
 
   // Find entry for key, otherwise return kNotFound. Optimized version of
@@ -3904,6 +3974,33 @@
   static const int kNotFound = -1;
   static const int kMinCapacity = 4;
 
+  static const int kNumberOfBucketsIndex = 0;
+  static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
+  static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
+  static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
+  static const int kNextTableIndex = kNumberOfElementsIndex;
+
+  static const int kNumberOfBucketsOffset =
+      kHeaderSize + kNumberOfBucketsIndex * kPointerSize;
+  static const int kNumberOfElementsOffset =
+      kHeaderSize + kNumberOfElementsIndex * kPointerSize;
+  static const int kNumberOfDeletedElementsOffset =
+      kHeaderSize + kNumberOfDeletedElementsIndex * kPointerSize;
+  static const int kHashTableStartOffset =
+      kHeaderSize + kHashTableStartIndex * kPointerSize;
+  static const int kNextTableOffset =
+      kHeaderSize + kNextTableIndex * kPointerSize;
+
+  static const int kEntrySize = entrysize + 1;
+  static const int kChainOffset = entrysize;
+
+  static const int kLoadFactor = 2;
+
+  // NumberOfDeletedElements is set to kClearedTableSentinel when
+  // the table is cleared, which allows iterator transitions to
+  // optimize that case.
+  static const int kClearedTableSentinel = -1;
+
  private:
   static Handle<Derived> Rehash(Handle<Derived> table, int new_capacity);
 
@@ -3945,18 +4042,8 @@
     return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
   }
 
-  static const int kNumberOfBucketsIndex = 0;
-  static const int kNumberOfElementsIndex = kNumberOfBucketsIndex + 1;
-  static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
-  static const int kHashTableStartIndex = kNumberOfDeletedElementsIndex + 1;
-
-  static const int kNextTableIndex = kNumberOfElementsIndex;
   static const int kRemovedHolesIndex = kHashTableStartIndex;
 
-  static const int kEntrySize = entrysize + 1;
-  static const int kChainOffset = entrysize;
-
-  static const int kLoadFactor = 2;
   static const int kMaxCapacity =
       (FixedArray::kMaxLength - kHashTableStartIndex)
       / (1 + (kEntrySize * kLoadFactor));
@@ -3995,7 +4082,6 @@
     return get(EntryToIndex(entry) + kValueOffset);
   }
 
- private:
   static const int kValueOffset = 1;
 };
 
@@ -4295,13 +4381,13 @@
   };
 
   // Properties of scopes.
-  class ScopeTypeField:        public BitField<ScopeType,            0, 3> {};
-  class CallsEvalField:        public BitField<bool,                 3, 1> {};
-  class StrictModeField:       public BitField<StrictMode,           4, 1> {};
-  class FunctionVariableField: public BitField<FunctionVariableInfo, 5, 2> {};
-  class FunctionVariableMode:  public BitField<VariableMode,         7, 3> {};
-  class AsmModuleField : public BitField<bool, 10, 1> {};
-  class AsmFunctionField : public BitField<bool, 11, 1> {};
+  class ScopeTypeField : public BitField<ScopeType, 0, 4> {};
+  class CallsEvalField : public BitField<bool, 4, 1> {};
+  class StrictModeField : public BitField<StrictMode, 5, 1> {};
+  class FunctionVariableField : public BitField<FunctionVariableInfo, 6, 2> {};
+  class FunctionVariableMode : public BitField<VariableMode, 8, 3> {};
+  class AsmModuleField : public BitField<bool, 11, 1> {};
+  class AsmFunctionField : public BitField<bool, 12, 1> {};
 
   // BitFields representing the encoded information for context locals in the
   // ContextLocalInfoEntries part.
@@ -4781,6 +4867,7 @@
 
 #undef FIXED_TYPED_ARRAY_TRAITS
 
+
 // DeoptimizationInputData is a fixed array used to hold the deoptimization
 // data for code generated by the Hydrogen/Lithium compiler.  It also
 // contains information about functions that were inlined.  If N different
@@ -4862,7 +4949,7 @@
   DECLARE_CAST(DeoptimizationInputData)
 
 #ifdef ENABLE_DISASSEMBLER
-  void DeoptimizationInputDataPrint(OStream& os);  // NOLINT
+  void DeoptimizationInputDataPrint(std::ostream& os);  // NOLINT
 #endif
 
  private:
@@ -4907,7 +4994,7 @@
   DECLARE_CAST(DeoptimizationOutputData)
 
 #if defined(OBJECT_PRINT) || defined(ENABLE_DISASSEMBLER)
-  void DeoptimizationOutputDataPrint(OStream& os);  // NOLINT
+  void DeoptimizationOutputDataPrint(std::ostream& os);  // NOLINT
 #endif
 };
 
@@ -4973,9 +5060,9 @@
   // Printing
   static const char* ICState2String(InlineCacheState state);
   static const char* StubType2String(StubType type);
-  static void PrintExtraICState(OStream& os,  // NOLINT
+  static void PrintExtraICState(std::ostream& os,  // NOLINT
                                 Kind kind, ExtraICState extra);
-  void Disassemble(const char* name, OStream& os);  // NOLINT
+  void Disassemble(const char* name, std::ostream& os);  // NOLINT
 #endif  // ENABLE_DISASSEMBLER
 
   // [instruction_size]: Size of the native instructions
@@ -5054,12 +5141,7 @@
   inline bool is_to_boolean_ic_stub() { return kind() == TO_BOOLEAN_IC; }
   inline bool is_keyed_stub();
   inline bool is_optimized_code() { return kind() == OPTIMIZED_FUNCTION; }
-  inline bool is_weak_stub();
-  inline void mark_as_weak_stub();
-  inline bool is_invalidated_weak_stub();
-  inline void mark_as_invalidated_weak_stub();
-
-  inline bool CanBeWeakStub() {
+  inline bool embeds_maps_weakly() {
     Kind k = kind();
     return (k == LOAD_IC || k == STORE_IC || k == KEYED_LOAD_IC ||
             k == KEYED_STORE_IC || k == COMPARE_NIL_IC) &&
@@ -5102,6 +5184,12 @@
   inline bool is_compiled_optimizable();
   inline void set_compiled_optimizable(bool value);
 
+  // [has_reloc_info_for_serialization]: For FUNCTION kind, tells if its
+  // reloc info includes runtime and external references to support
+  // serialization/deserialization.
+  inline bool has_reloc_info_for_serialization();
+  inline void set_has_reloc_info_for_serialization(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
@@ -5115,6 +5203,10 @@
   inline void set_profiler_ticks(int ticks);
 
   // [builtin_index]: For BUILTIN kind, tells which builtin index it has.
+  // For builtins, tells which builtin index it has.
+  // Note that builtins can have a code kind other than BUILTIN, which means
+  // that for arbitrary code objects, this index value may be random garbage.
+  // To verify in that case, compare the code object to the indexed builtin.
   inline int builtin_index();
   inline void set_builtin_index(int id);
 
@@ -5307,6 +5399,7 @@
   // compilation stub.
   static void MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate);
   static void MarkCodeAsExecuted(byte* sequence, Isolate* isolate);
+  void MakeYoung(Isolate* isolate);
   void MakeOlder(MarkingParity);
   static bool IsYoungSequence(Isolate* isolate, byte* sequence);
   bool IsOld();
@@ -5325,26 +5418,25 @@
   void VerifyEmbeddedObjectsDependency();
 #endif
 
-  inline bool CanContainWeakObjects() {
-    return is_optimized_code() || is_weak_stub();
-  }
+#ifdef DEBUG
+  void VerifyEmbeddedObjectsInFullCode();
+#endif  // DEBUG
+
+  inline bool CanContainWeakObjects() { return is_optimized_code(); }
 
   inline bool IsWeakObject(Object* object) {
     return (is_optimized_code() && !is_turbofanned() &&
-            IsWeakObjectInOptimizedCode(object)) ||
-           (is_weak_stub() && IsWeakObjectInIC(object));
+            IsWeakObjectInOptimizedCode(object));
   }
 
   static inline bool IsWeakObjectInOptimizedCode(Object* object);
-  static inline bool IsWeakObjectInIC(Object* object);
 
   // Max loop nesting marker used to postpose OSR. We don't take loop
   // nesting that is deeper than 5 levels into account.
   static const int kMaxLoopNestingMarker = 6;
 
   // Layout description.
-  static const int kInstructionSizeOffset = HeapObject::kHeaderSize;
-  static const int kRelocationInfoOffset = kInstructionSizeOffset + kIntSize;
+  static const int kRelocationInfoOffset = HeapObject::kHeaderSize;
   static const int kHandlerTableOffset = kRelocationInfoOffset + kPointerSize;
   static const int kDeoptimizationDataOffset =
       kHandlerTableOffset + kPointerSize;
@@ -5353,22 +5445,24 @@
       kDeoptimizationDataOffset + kPointerSize;
   static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset + kPointerSize;
   static const int kGCMetadataOffset = kNextCodeLinkOffset + kPointerSize;
-  static const int kICAgeOffset =
-      kGCMetadataOffset + kPointerSize;
+  static const int kInstructionSizeOffset = kGCMetadataOffset + kPointerSize;
+  static const int kICAgeOffset = kInstructionSizeOffset + kIntSize;
   static const int kFlagsOffset = kICAgeOffset + kIntSize;
   static const int kKindSpecificFlags1Offset = kFlagsOffset + kIntSize;
   static const int kKindSpecificFlags2Offset =
       kKindSpecificFlags1Offset + kIntSize;
   // Note: We might be able to squeeze this into the flags above.
   static const int kPrologueOffset = kKindSpecificFlags2Offset + kIntSize;
-  static const int kConstantPoolOffset = kPrologueOffset + kPointerSize;
+  static const int kConstantPoolOffset = kPrologueOffset + kIntSize;
 
-  static const int kHeaderPaddingStart = kConstantPoolOffset + kIntSize;
+  static const int kHeaderPaddingStart = kConstantPoolOffset + kPointerSize;
 
   // Add padding to align the instruction start following right after
   // the Code object header.
   static const int kHeaderSize =
       (kHeaderPaddingStart + kCodeAlignmentMask) & ~kCodeAlignmentMask;
+  // Ensure that the slot for the constant pool pointer is aligned.
+  STATIC_ASSERT((kConstantPoolOffset & kPointerAlignmentMask) == 0);
 
   // Byte offsets within kKindSpecificFlags1Offset.
   static const int kOptimizableOffset = kKindSpecificFlags1Offset;
@@ -5378,6 +5472,8 @@
       public BitField<bool, 0, 1> {};  // NOLINT
   class FullCodeFlagsHasDebugBreakSlotsField: public BitField<bool, 1, 1> {};
   class FullCodeFlagsIsCompiledOptimizable: public BitField<bool, 2, 1> {};
+  class FullCodeFlagsHasRelocInfoForSerialization
+      : public BitField<bool, 3, 1> {};
 
   static const int kProfilerTicksOffset = kFullCodeFlags + 1;
 
@@ -5395,9 +5491,7 @@
   static const int kHasFunctionCacheBit =
       kStackSlotsFirstBit + kStackSlotsBitCount;
   static const int kMarkedForDeoptimizationBit = kHasFunctionCacheBit + 1;
-  static const int kWeakStubBit = kMarkedForDeoptimizationBit + 1;
-  static const int kInvalidatedWeakStubBit = kWeakStubBit + 1;
-  static const int kIsTurbofannedBit = kInvalidatedWeakStubBit + 1;
+  static const int kIsTurbofannedBit = kMarkedForDeoptimizationBit + 1;
 
   STATIC_ASSERT(kStackSlotsFirstBit + kStackSlotsBitCount <= 32);
   STATIC_ASSERT(kIsTurbofannedBit + 1 <= 32);
@@ -5408,9 +5502,6 @@
   };  // NOLINT
   class MarkedForDeoptimizationField
       : public BitField<bool, kMarkedForDeoptimizationBit, 1> {};   // NOLINT
-  class WeakStubField : public BitField<bool, kWeakStubBit, 1> {};  // NOLINT
-  class InvalidatedWeakStubField
-      : public BitField<bool, kInvalidatedWeakStubBit, 1> {};  // NOLINT
   class IsTurbofannedField : public BitField<bool, kIsTurbofannedBit, 1> {
   };  // NOLINT
 
@@ -5492,11 +5583,6 @@
 class DependentCode: public FixedArray {
  public:
   enum DependencyGroup {
-    // Group of IC stubs that weakly embed this map and depend on being
-    // invalidated when the map is garbage collected. Dependent IC stubs form
-    // a linked list. This group stores only the head of the list. This means
-    // that the number_of_entries(kWeakICGroup) is 0 or 1.
-    kWeakICGroup,
     // Group of code that weakly embed this map and depend on being
     // deoptimized when the map is garbage collected.
     kWeakCodeGroup,
@@ -5557,7 +5643,6 @@
 
   bool MarkCodeForDeoptimization(Isolate* isolate,
                                  DependentCode::DependencyGroup group);
-  void AddToDependentICList(Handle<Code> stub);
 
   // The following low-level accessors should only be used by this class
   // and the mark compact collector.
@@ -5637,15 +5722,20 @@
   class OwnsDescriptors : public BitField<bool, 21, 1> {};
   class HasInstanceCallHandler : public BitField<bool, 22, 1> {};
   class Deprecated : public BitField<bool, 23, 1> {};
-  class IsFrozen : public BitField<bool, 24, 1> {};
-  class IsUnstable : public BitField<bool, 25, 1> {};
-  class IsMigrationTarget : public BitField<bool, 26, 1> {};
-  class DoneInobjectSlackTracking : public BitField<bool, 27, 1> {};
-  // Bit 28 is free.
+  class IsUnstable : public BitField<bool, 24, 1> {};
+  class IsMigrationTarget : public BitField<bool, 25, 1> {};
+  // Bits 26 and 27 are free.
 
   // Keep this bit field at the very end for better code in
   // Builtins::kJSConstructStubGeneric stub.
-  class ConstructionCount:          public BitField<int, 29, 3> {};
+  // This counter is used for in-object slack tracking and for map aging.
+  // The in-object slack tracking is considered enabled when the counter is
+  // in the range [kSlackTrackingCounterStart, kSlackTrackingCounterEnd].
+  class Counter : public BitField<int, 28, 4> {};
+  static const int kSlackTrackingCounterStart = 14;
+  static const int kSlackTrackingCounterEnd = 8;
+  static const int kRetainingCounterStart = kSlackTrackingCounterEnd - 1;
+  static const int kRetainingCounterEnd = 0;
 
   // Tells whether the object in the prototype property will be used
   // for instances created from this function.  If the prototype
@@ -5718,7 +5808,7 @@
   inline bool is_prototype_map();
 
   inline void set_elements_kind(ElementsKind elements_kind) {
-    DCHECK(elements_kind < kElementsKindCount);
+    DCHECK(static_cast<int>(elements_kind) < kElementsKindCount);
     DCHECK(kElementsKindCount <= (1 << Map::ElementsKindBits::kSize));
     set_bit_field2(Map::ElementsKindBits::update(bit_field2(), elements_kind));
     DCHECK(this->elements_kind() == elements_kind);
@@ -5783,7 +5873,9 @@
   inline Map* elements_transition_map();
 
   inline Map* GetTransition(int transition_index);
-  inline int SearchTransition(Name* name);
+  inline int SearchSpecialTransition(Symbol* name);
+  inline int SearchTransition(PropertyKind kind, Name* name,
+                              PropertyAttributes attributes);
   inline FixedArrayBase* GetInitialElements();
 
   DECL_ACCESSORS(transitions, TransitionArray)
@@ -5813,8 +5905,8 @@
       Handle<HeapType> type1,
       Handle<HeapType> type2,
       Isolate* isolate);
-  static void GeneralizeFieldType(Handle<Map> map,
-                                  int modify_index,
+  static void GeneralizeFieldType(Handle<Map> map, int modify_index,
+                                  Representation new_representation,
                                   Handle<HeapType> new_field_type);
   static Handle<Map> GeneralizeRepresentation(
       Handle<Map> map,
@@ -5838,7 +5930,8 @@
                                             int descriptor_number,
                                             Handle<Object> value);
 
-  static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode);
+  static Handle<Map> Normalize(Handle<Map> map, PropertyNormalizationMode mode,
+                               const char* reason);
 
   // Returns the constructor name (the name (possibly, inferred name) of the
   // function that was used to instantiate the object).
@@ -5861,13 +5954,33 @@
 
   // [prototype]: implicit prototype object.
   DECL_ACCESSORS(prototype, Object)
+  // TODO(jkummerow): make set_prototype private.
+  void SetPrototype(Handle<Object> prototype,
+                    PrototypeOptimizationMode proto_mode = FAST_PROTOTYPE);
+  bool ShouldRegisterAsPrototypeUser(Handle<JSObject> prototype);
+  bool CanUseOptimizationsBasedOnPrototypeRegistry();
 
   // [constructor]: points back to the function responsible for this map.
   DECL_ACCESSORS(constructor, Object)
 
   // [instance descriptors]: describes the object.
   DECL_ACCESSORS(instance_descriptors, DescriptorArray)
-  inline void InitializeDescriptors(DescriptorArray* descriptors);
+
+  // [layout descriptor]: describes the object layout.
+  DECL_ACCESSORS(layout_descriptor, LayoutDescriptor)
+  // |layout descriptor| accessor which can be used from GC.
+  inline LayoutDescriptor* layout_descriptor_gc_safe();
+  inline bool HasFastPointerLayout() const;
+
+  // |layout descriptor| accessor that is safe to call even when
+  // FLAG_unbox_double_fields is disabled (in this case Map does not contain
+  // |layout_descriptor| field at all).
+  inline LayoutDescriptor* GetLayoutDescriptor();
+
+  inline void UpdateDescriptors(DescriptorArray* descriptors,
+                                LayoutDescriptor* layout_descriptor);
+  inline void InitializeDescriptors(DescriptorArray* descriptors,
+                                    LayoutDescriptor* layout_descriptor);
 
   // [stub cache]: contains stubs compiled for this map.
   DECL_ACCESSORS(code_cache, Object)
@@ -5921,8 +6034,8 @@
                                Name* name,
                                LookupResult* result);
 
-  inline void LookupTransition(JSObject* holder,
-                               Name* name,
+  inline void LookupTransition(JSObject* holder, Name* name,
+                               PropertyAttributes attributes,
                                LookupResult* result);
 
   inline PropertyDetails GetLastDescriptorDetails();
@@ -5966,16 +6079,12 @@
   inline void set_owns_descriptors(bool owns_descriptors);
   inline bool has_instance_call_handler();
   inline void set_has_instance_call_handler();
-  inline void freeze();
-  inline bool is_frozen();
   inline void mark_unstable();
   inline bool is_stable();
   inline void set_migration_target(bool value);
   inline bool is_migration_target();
-  inline void set_done_inobject_slack_tracking(bool value);
-  inline bool done_inobject_slack_tracking();
-  inline void set_construction_count(int value);
-  inline int construction_count();
+  inline void set_counter(int value);
+  inline int counter();
   inline void deprecate();
   inline bool is_deprecated();
   inline bool CanBeDeprecated();
@@ -6027,7 +6136,10 @@
 
   static Handle<Map> CopyForObserved(Handle<Map> map);
 
-  static Handle<Map> CopyForFreeze(Handle<Map> map);
+  static Handle<Map> CopyForPreventExtensions(Handle<Map> map,
+                                              PropertyAttributes attrs_to_add,
+                                              Handle<Symbol> transition_marker,
+                                              const char* reason);
   // Maximal number of fast properties. Used to restrict the number of map
   // transitions to avoid an explosion in the number of maps for objects used as
   // dictionaries.
@@ -6047,7 +6159,7 @@
 
   // Returns a copy of the map, with all transitions dropped from the
   // instance descriptors.
-  static Handle<Map> Copy(Handle<Map> map);
+  static Handle<Map> Copy(Handle<Map> map, const char* reason);
   static Handle<Map> Create(Isolate* isolate, int inobject_properties);
 
   // Returns the next free property index (only valid for FAST MODE).
@@ -6082,6 +6194,8 @@
   static void AppendCallbackDescriptors(Handle<Map> map,
                                         Handle<Object> descriptors);
 
+  static inline int SlackForArraySize(int old_size, int size_limit);
+
   static void EnsureDescriptorSlack(Handle<Map> map, int slack);
 
   // Returns the found code or undefined if absent.
@@ -6122,6 +6236,7 @@
   bool IsJSObjectMap() {
     return instance_type() >= FIRST_JS_OBJECT_TYPE;
   }
+  bool IsStringMap() { return instance_type() < FIRST_NONSTRING_TYPE; }
   bool IsJSProxyMap() {
     InstanceType type = instance_type();
     return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
@@ -6146,11 +6261,11 @@
   static void AddDependentCode(Handle<Map> map,
                                DependentCode::DependencyGroup group,
                                Handle<Code> code);
-  static void AddDependentIC(Handle<Map> map,
-                             Handle<Code> stub);
 
   bool IsMapInArrayPrototypeChain();
 
+  static Handle<WeakCell> WeakCellForMap(Handle<Map> map);
+
   // Dispatched behavior.
   DECLARE_PRINTER(Map)
   DECLARE_VERIFIER(Map)
@@ -6173,10 +6288,11 @@
   // the original map.  That way we can transition to the same map if the same
   // prototype is set, rather than creating a new map every time.  The
   // transitions are in the form of a map where the keys are prototype objects
-  // and the values are the maps the are transitioned to.
+  // and the values are the maps they transition to.
   static const int kMaxCachedPrototypeTransitions = 256;
   static Handle<Map> TransitionToPrototype(Handle<Map> map,
-                                           Handle<Object> prototype);
+                                           Handle<Object> prototype,
+                                           PrototypeOptimizationMode mode);
 
   static const int kMaxPreAllocatedPropertyFields = 255;
 
@@ -6194,7 +6310,13 @@
       kConstructorOffset + kPointerSize;
   static const int kDescriptorsOffset =
       kTransitionsOrBackPointerOffset + kPointerSize;
+#if V8_DOUBLE_FIELDS_UNBOXING
+  static const int kLayoutDecriptorOffset = kDescriptorsOffset + kPointerSize;
+  static const int kCodeCacheOffset = kLayoutDecriptorOffset + kPointerSize;
+#else
+  static const int kLayoutDecriptorOffset = 1;  // Must not be ever accessed.
   static const int kCodeCacheOffset = kDescriptorsOffset + kPointerSize;
+#endif
   static const int kDependentCodeOffset = kCodeCacheOffset + kPointerSize;
   static const int kSize = kDependentCodeOffset + kPointerSize;
 
@@ -6272,6 +6394,18 @@
   // The "shared" flags of both this map and |other| are ignored.
   bool EquivalentToForNormalization(Map* other, PropertyNormalizationMode mode);
 
+  // Returns true if given field is unboxed double.
+  inline bool IsUnboxedDoubleField(FieldIndex index);
+
+#if TRACE_MAPS
+  static void TraceTransition(const char* what, Map* from, Map* to, Name* name);
+  static void TraceAllTransitions(Map* map);
+#endif
+
+  static inline Handle<Map> CopyInstallDescriptorsForTesting(
+      Handle<Map> map, int new_descriptor, Handle<DescriptorArray> descriptors,
+      Handle<LayoutDescriptor> layout_descriptor);
+
  private:
   static void ConnectElementsTransition(Handle<Map> parent, Handle<Map> child);
   static void ConnectTransition(Handle<Map> parent, Handle<Map> child,
@@ -6283,18 +6417,17 @@
                                      Handle<DescriptorArray> descriptors,
                                      Descriptor* descriptor);
   static Handle<Map> CopyInstallDescriptors(
-      Handle<Map> map,
-      int new_descriptor,
-      Handle<DescriptorArray> descriptors);
+      Handle<Map> map, int new_descriptor, Handle<DescriptorArray> descriptors,
+      Handle<LayoutDescriptor> layout_descriptor);
   static Handle<Map> CopyAddDescriptor(Handle<Map> map,
                                        Descriptor* descriptor,
                                        TransitionFlag flag);
   static Handle<Map> CopyReplaceDescriptors(
-      Handle<Map> map,
-      Handle<DescriptorArray> descriptors,
-      TransitionFlag flag,
-      MaybeHandle<Name> maybe_name,
-      SimpleTransitionFlag simple_flag = FULL_TRANSITION);
+      Handle<Map> map, Handle<DescriptorArray> descriptors,
+      Handle<LayoutDescriptor> layout_descriptor, TransitionFlag flag,
+      MaybeHandle<Name> maybe_name, const char* reason,
+      SimpleTransitionFlag simple_flag);
+
   static Handle<Map> CopyReplaceDescriptor(Handle<Map> map,
                                            Handle<DescriptorArray> descriptors,
                                            Descriptor* descriptor,
@@ -6322,11 +6455,15 @@
   void ZapTransitions();
 
   void DeprecateTransitionTree();
-  void DeprecateTarget(Name* key, DescriptorArray* new_descriptors);
+  bool DeprecateTarget(PropertyKind kind, Name* key,
+                       PropertyAttributes attributes,
+                       DescriptorArray* new_descriptors,
+                       LayoutDescriptor* new_layout_descriptor);
 
   Map* FindLastMatchMap(int verbatim, int length, DescriptorArray* descriptors);
 
   void UpdateFieldType(int descriptor_number, Handle<Name> name,
+                       Representation new_representation,
                        Handle<HeapType> new_type);
 
   void PrintGeneralization(FILE* file,
@@ -6428,8 +6565,8 @@
   // [context_data]: context data for the context this script was compiled in.
   DECL_ACCESSORS(context_data, Object)
 
-  // [wrapper]: the wrapper cache.
-  DECL_ACCESSORS(wrapper, Foreign)
+  // [wrapper]: the wrapper cache.  This is either undefined or a WeakCell.
+  DECL_ACCESSORS(wrapper, HeapObject)
 
   // [type]: the script type.
   DECL_ACCESSORS(type, Smi)
@@ -6491,7 +6628,6 @@
 
   // Get the JS object wrapping the given script; create it if none exists.
   static Handle<JSObject> GetWrapper(Handle<Script> script);
-  void ClearWrapperCache();
 
   // Dispatched behavior.
   DECLARE_PRINTER(Script)
@@ -6543,9 +6679,11 @@
   V(Array.prototype, pop, ArrayPop)                 \
   V(Array.prototype, shift, ArrayShift)             \
   V(Function.prototype, apply, FunctionApply)       \
+  V(Function.prototype, call, FunctionCall)         \
   V(String.prototype, charCodeAt, StringCharCodeAt) \
   V(String.prototype, charAt, StringCharAt)         \
   V(String, fromCharCode, StringFromCharCode)       \
+  V(Math, random, MathRandom)                       \
   V(Math, floor, MathFloor)                         \
   V(Math, round, MathRound)                         \
   V(Math, ceil, MathCeil)                           \
@@ -6556,6 +6694,13 @@
   V(Math, pow, MathPow)                             \
   V(Math, max, MathMax)                             \
   V(Math, min, MathMin)                             \
+  V(Math, cos, MathCos)                             \
+  V(Math, sin, MathSin)                             \
+  V(Math, tan, MathTan)                             \
+  V(Math, acos, MathAcos)                           \
+  V(Math, asin, MathAsin)                           \
+  V(Math, atan, MathAtan)                           \
+  V(Math, atan2, MathAtan2)                         \
   V(Math, imul, MathImul)                           \
   V(Math, clz32, MathClz32)                         \
   V(Math, fround, MathFround)
@@ -6657,6 +6802,13 @@
   // available.
   DECL_ACCESSORS(feedback_vector, TypeFeedbackVector)
 
+#if TRACE_MAPS
+  // [unique_id] - For --trace-maps purposes, an identifier that's persistent
+  // even if the GC moves this SharedFunctionInfo.
+  inline int unique_id() const;
+  inline void set_unique_id(int value);
+#endif
+
   // [instance class name]: class name for instances.
   DECL_ACCESSORS(instance_class_name, Object)
 
@@ -6759,6 +6911,13 @@
   // False if the function definitely does not allocate an arguments object.
   DECL_BOOLEAN_ACCESSORS(uses_arguments)
 
+  // Indicates that this function uses a super property.
+  // This is needed to set up the [[HomeObject]] on the function instance.
+  DECL_BOOLEAN_ACCESSORS(uses_super_property)
+
+  // Indicates that this function uses the super constructor.
+  DECL_BOOLEAN_ACCESSORS(uses_super_constructor_call)
+
   // True if the function has any duplicated parameter names.
   DECL_BOOLEAN_ACCESSORS(has_duplicate_parameters)
 
@@ -6803,9 +6962,15 @@
   // Indicates that this function is a concise method.
   DECL_BOOLEAN_ACCESSORS(is_concise_method)
 
+  // Indicates that this function is a default constructor.
+  DECL_BOOLEAN_ACCESSORS(is_default_constructor)
+
   // Indicates that this function is an asm function.
   DECL_BOOLEAN_ACCESSORS(asm_function)
 
+  // Indicates that the the shared function info is deserialized from cache.
+  DECL_BOOLEAN_ACCESSORS(deserialized)
+
   inline FunctionKind kind();
   inline void set_kind(FunctionKind kind);
 
@@ -6820,7 +6985,7 @@
   // shared function info.
   void DisableOptimization(BailoutReason reason);
 
-  inline BailoutReason DisableOptimizationReason();
+  inline BailoutReason disable_optimization_reason();
 
   // Lookup the bailout ID and DCHECK that it exists in the non-optimized
   // code, returns whether it asserted (i.e., always true if assertions are
@@ -6855,7 +7020,7 @@
   inline void set_opt_count_and_bailout_reason(int value);
   inline int opt_count_and_bailout_reason() const;
 
-  void set_bailout_reason(BailoutReason reason) {
+  void set_disable_optimization_reason(BailoutReason reason) {
     set_opt_count_and_bailout_reason(
         DisabledOptimizationReasonBits::update(opt_count_and_bailout_reason(),
                                                reason));
@@ -6900,10 +7065,16 @@
   static const int kInferredNameOffset = kDebugInfoOffset + kPointerSize;
   static const int kFeedbackVectorOffset =
       kInferredNameOffset + kPointerSize;
+#if TRACE_MAPS
+  static const int kUniqueIdOffset = kFeedbackVectorOffset + kPointerSize;
+  static const int kLastPointerFieldOffset = kUniqueIdOffset;
+#else
+  static const int kLastPointerFieldOffset = kFeedbackVectorOffset;
+#endif
+
 #if V8_HOST_ARCH_32_BIT
   // Smi fields.
-  static const int kLengthOffset =
-      kFeedbackVectorOffset + kPointerSize;
+  static const int kLengthOffset = kLastPointerFieldOffset + kPointerSize;
   static const int kFormalParameterCountOffset = kLengthOffset + kPointerSize;
   static const int kExpectedNofPropertiesOffset =
       kFormalParameterCountOffset + kPointerSize;
@@ -6934,12 +7105,12 @@
   // garbage collections.
   // To avoid wasting space on 64-bit architectures we use
   // the following trick: we group integer fields into pairs
-  // First integer in each pair is shifted left by 1.
-  // By doing this we guarantee that LSB of each kPointerSize aligned
-  // word is not set and thus this word cannot be treated as pointer
-  // to HeapObject during old space traversal.
-  static const int kLengthOffset =
-      kFeedbackVectorOffset + kPointerSize;
+// The least significant integer in each pair is shifted left by 1.
+// By doing this we guarantee that LSB of each kPointerSize aligned
+// word is not set and thus this word cannot be treated as pointer
+// to HeapObject during old space traversal.
+#if V8_TARGET_LITTLE_ENDIAN
+  static const int kLengthOffset = kLastPointerFieldOffset + kPointerSize;
   static const int kFormalParameterCountOffset =
       kLengthOffset + kIntSize;
 
@@ -6971,12 +7142,42 @@
   // Total size.
   static const int kSize = kProfilerTicksOffset + kIntSize;
 
-#endif
+#elif V8_TARGET_BIG_ENDIAN
+  static const int kFormalParameterCountOffset =
+      kLastPointerFieldOffset + kPointerSize;
+  static const int kLengthOffset = kFormalParameterCountOffset + kIntSize;
+
+  static const int kNumLiteralsOffset = kLengthOffset + kIntSize;
+  static const int kExpectedNofPropertiesOffset = kNumLiteralsOffset + kIntSize;
+
+  static const int kStartPositionAndTypeOffset =
+      kExpectedNofPropertiesOffset + kIntSize;
+  static const int kEndPositionOffset = kStartPositionAndTypeOffset + kIntSize;
+
+  static const int kCompilerHintsOffset = kEndPositionOffset + kIntSize;
+  static const int kFunctionTokenPositionOffset =
+      kCompilerHintsOffset + kIntSize;
+
+  static const int kCountersOffset = kFunctionTokenPositionOffset + kIntSize;
+  static const int kOptCountAndBailoutReasonOffset = kCountersOffset + kIntSize;
+
+  static const int kProfilerTicksOffset =
+      kOptCountAndBailoutReasonOffset + kIntSize;
+  static const int kAstNodeCountOffset = kProfilerTicksOffset + kIntSize;
+
+  // Total size.
+  static const int kSize = kAstNodeCountOffset + kIntSize;
+
+#else
+#error Unknown byte ordering
+#endif  // Big endian
+#endif  // 64-bit
+
 
   static const int kAlignedSize = POINTER_SIZE_ALIGN(kSize);
 
   typedef FixedBodyDescriptor<kNameOffset,
-                              kFeedbackVectorOffset + kPointerSize,
+                              kLastPointerFieldOffset + kPointerSize,
                               kSize> BodyDescriptor;
 
   // Bit positions in start_position_and_type.
@@ -6994,6 +7195,8 @@
     kOptimizationDisabled,
     kStrictModeFunction,
     kUsesArguments,
+    kUsesSuperProperty,
+    kUsesSuperConstructorCall,
     kHasDuplicateParameters,
     kNative,
     kInlineBuiltin,
@@ -7006,11 +7209,13 @@
     kIsArrow,
     kIsGenerator,
     kIsConciseMethod,
+    kIsDefaultConstructor,
     kIsAsmFunction,
+    kDeserialized,
     kCompilerHintsCount  // Pseudo entry
   };
 
-  class FunctionKindBits : public BitField<FunctionKind, kIsArrow, 3> {};
+  class FunctionKindBits : public BitField<FunctionKind, kIsArrow, 4> {};
 
   class DeoptCountBits : public BitField<int, 0, 4> {};
   class OptReenableTriesBits : public BitField<int, 4, 18> {};
@@ -7073,7 +7278,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const SourceCodeOf& v);
+std::ostream& operator<<(std::ostream& os, const SourceCodeOf& v);
 
 
 class JSGeneratorObject: public JSObject {
@@ -7215,8 +7420,7 @@
   // Mark this function for lazy recompilation. The function will be
   // recompiled the next time it is executed.
   void MarkForOptimization();
-  void MarkForConcurrentOptimization();
-  void MarkInOptimizationQueue();
+  void AttemptConcurrentOptimization();
 
   // Tells whether or not the function is already marked for lazy
   // recompilation.
@@ -7236,13 +7440,12 @@
   // Here is the algorithm to reclaim the unused inobject space:
   // - Detect the first constructor call for this JSFunction.
   //   When it happens enter the "in progress" state: initialize construction
-  //   counter in the initial_map and set the |done_inobject_slack_tracking|
-  //   flag.
+  //   counter in the initial_map.
   // - While the tracking is in progress create objects filled with
   //   one_pointer_filler_map instead of undefined_value. This way they can be
   //   resized quickly and safely.
-  // - Once enough (kGenerousAllocationCount) objects have been created
-  //   compute the 'slack' (traverse the map transition tree starting from the
+  // - Once enough objects have been created  compute the 'slack'
+  //   (traverse the map transition tree starting from the
   //   initial_map and find the lowest value of unused_property_fields).
   // - Traverse the transition tree again and decrease the instance size
   //   of every map. Existing objects will resize automatically (they are
@@ -7255,23 +7458,17 @@
   //  Important: inobject slack tracking is not attempted during the snapshot
   //  creation.
 
-  static const int kGenerousAllocationCount = Map::ConstructionCount::kMax;
-  static const int kFinishSlackTracking     = 1;
-  static const int kNoSlackTracking         = 0;
-
   // True if the initial_map is set and the object constructions countdown
   // counter is not zero.
+  static const int kGenerousAllocationCount =
+      Map::kSlackTrackingCounterStart - Map::kSlackTrackingCounterEnd + 1;
   inline bool IsInobjectSlackTrackingInProgress();
 
   // Starts the tracking.
   // Initializes object constructions countdown counter in the initial map.
-  // IsInobjectSlackTrackingInProgress is normally true after this call,
-  // except when tracking have not been started (e.g. the map has no unused
-  // properties or the snapshot is being built).
   void StartInobjectSlackTracking();
 
   // Completes the tracking.
-  // IsInobjectSlackTrackingInProgress is false after this call.
   void CompleteInobjectSlackTracking();
 
   // [literals_or_bindings]: Fixed array holding either
@@ -7443,19 +7640,18 @@
   // [native context]: the natives corresponding to this global object.
   DECL_ACCESSORS(native_context, Context)
 
-  // [global context]: the most recent (i.e. innermost) global context.
-  DECL_ACCESSORS(global_context, Context)
-
   // [global proxy]: the global proxy object of the context
   DECL_ACCESSORS(global_proxy, JSObject)
 
   DECLARE_CAST(GlobalObject)
 
+  static void InvalidatePropertyCell(Handle<GlobalObject> object,
+                                     Handle<Name> name);
+
   // Layout description.
   static const int kBuiltinsOffset = JSObject::kHeaderSize;
   static const int kNativeContextOffset = kBuiltinsOffset + kPointerSize;
-  static const int kGlobalContextOffset = kNativeContextOffset + kPointerSize;
-  static const int kGlobalProxyOffset = kGlobalContextOffset + kPointerSize;
+  static const int kGlobalProxyOffset = kNativeContextOffset + kPointerSize;
   static const int kHeaderSize = kGlobalProxyOffset + kPointerSize;
 
  private:
@@ -7815,12 +8011,11 @@
       FixedArray::kHeaderSize + kIrregexpCaptureCountIndex * kPointerSize;
 
   // In-object fields.
-  static const int kSourceFieldIndex = 0;
-  static const int kGlobalFieldIndex = 1;
-  static const int kIgnoreCaseFieldIndex = 2;
-  static const int kMultilineFieldIndex = 3;
-  static const int kLastIndexFieldIndex = 4;
-  static const int kInObjectFieldCount = 5;
+  static const int kGlobalFieldIndex = 0;
+  static const int kIgnoreCaseFieldIndex = 1;
+  static const int kMultilineFieldIndex = 2;
+  static const int kLastIndexFieldIndex = 3;
+  static const int kInObjectFieldCount = 4;
 
   // The uninitialized value for a regexp code object.
   static const int kUninitializedValue = -1;
@@ -7857,6 +8052,17 @@
 };
 
 
+// This cache is used in two different variants. For regexp caching, it simply
+// maps identifying info of the regexp to the cached regexp object. Scripts and
+// eval code only gets cached after a second probe for the code object. To do
+// so, on first "put" only a hash identifying the source is entered into the
+// cache, mapping it to a lifetime count of the hash. On each call to Age all
+// such lifetimes get reduced, and removed once they reach zero. If a second put
+// is called while such a hash is live in the cache, the hash gets replaced by
+// an actual cache entry. Age also removes stale live entries from the cache.
+// Such entries are identified by SharedFunctionInfos pointing to either the
+// recompilation stub, or to "old" code. This avoids memory leaks due to
+// premature caching of scripts and eval strings that are never needed later.
 class CompilationCacheTable: public HashTable<CompilationCacheTable,
                                               CompilationCacheShape,
                                               HashTableKey*> {
@@ -7878,6 +8084,8 @@
       Handle<CompilationCacheTable> cache, Handle<String> src,
       JSRegExp::Flags flags, Handle<FixedArray> value);
   void Remove(Object* value);
+  void Age();
+  static const int kHashGenerations = 10;
 
   DECLARE_CAST(CompilationCacheTable)
 
@@ -7890,6 +8098,7 @@
  public:
   DECL_ACCESSORS(default_cache, FixedArray)
   DECL_ACCESSORS(normal_type_cache, Object)
+  DECL_ACCESSORS(weak_cell_cache, Object)
 
   // Add the code object to the cache.
   static void Update(
@@ -7917,7 +8126,8 @@
   static const int kDefaultCacheOffset = HeapObject::kHeaderSize;
   static const int kNormalTypeCacheOffset =
       kDefaultCacheOffset + kPointerSize;
-  static const int kSize = kNormalTypeCacheOffset + kPointerSize;
+  static const int kWeakCellCacheOffset = kNormalTypeCacheOffset + kPointerSize;
+  static const int kSize = kWeakCellCacheOffset + kPointerSize;
 
  private:
   static void UpdateDefaultCache(
@@ -8048,7 +8258,6 @@
   inline void set_inlined_type_change_checksum(int checksum);
   inline bool matches_inlined_type_change_checksum(int checksum);
 
-
   DECLARE_CAST(TypeFeedbackInfo)
 
   // Dispatched behavior.
@@ -8231,14 +8440,11 @@
   static void DigestTransitionFeedback(Handle<AllocationSite> site,
                                        ElementsKind to_kind);
 
-  enum Reason {
-    TENURING,
-    TRANSITIONS
-  };
+  static void RegisterForDeoptOnTenureChange(Handle<AllocationSite> site,
+                                             CompilationInfo* info);
 
-  static void AddDependentCompilationInfo(Handle<AllocationSite> site,
-                                          Reason reason,
-                                          CompilationInfo* info);
+  static void RegisterForDeoptOnTransitionChange(Handle<AllocationSite> site,
+                                                 CompilationInfo* info);
 
   DECLARE_PRINTER(AllocationSite)
   DECLARE_VERIFIER(AllocationSite)
@@ -8270,7 +8476,10 @@
                               kSize> BodyDescriptor;
 
  private:
-  inline DependentCode::DependencyGroup ToDependencyGroup(Reason reason);
+  static void AddDependentCompilationInfo(Handle<AllocationSite> site,
+                                          DependentCode::DependencyGroup group,
+                                          CompilationInfo* info);
+
   bool PretenuringDecisionMade() {
     return pretenure_decision() != kUndecided;
   }
@@ -8363,6 +8572,11 @@
   // Reusable parts of the hashing algorithm.
   INLINE(static uint32_t AddCharacterCore(uint32_t running_hash, uint16_t c));
   INLINE(static uint32_t GetHashCore(uint32_t running_hash));
+  INLINE(static uint32_t ComputeRunningHash(uint32_t running_hash,
+                                            const uc16* chars, int length));
+  INLINE(static uint32_t ComputeRunningHashOneByte(uint32_t running_hash,
+                                                   const char* chars,
+                                                   int length));
 
  protected:
   // Returns the value to store in the hash field of a string with
@@ -8399,6 +8613,7 @@
  private:
   inline IteratingStringHasher(int len, uint32_t seed)
       : StringHasher(len, seed) {}
+  void VisitConsString(ConsString* cons_string);
   DISALLOW_COPY_AND_ASSIGN(IteratingStringHasher);
 };
 
@@ -8479,10 +8694,19 @@
   DECLARE_CAST(Name)
 
   DECLARE_PRINTER(Name)
+#if TRACE_MAPS
+  void NameShortPrint();
+  int NameShortPrint(Vector<char> str);
+#endif
 
   // Layout description.
-  static const int kHashFieldOffset = HeapObject::kHeaderSize;
-  static const int kSize = kHashFieldOffset + kPointerSize;
+  static const int kHashFieldSlot = HeapObject::kHeaderSize;
+#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
+  static const int kHashFieldOffset = kHashFieldSlot;
+#else
+  static const int kHashFieldOffset = kHashFieldSlot + kIntSize;
+#endif
+  static const int kSize = kHashFieldSlot + kPointerSize;
 
   // Mask constant for checking if a name has a computed hash code
   // and if it is a string that is an array index.  The least significant bit
@@ -8568,10 +8792,18 @@
 
   typedef FixedBodyDescriptor<kNameOffset, kFlagsOffset, kSize> BodyDescriptor;
 
+  void SymbolShortPrint(std::ostream& os);
+
  private:
   static const int kPrivateBit = 0;
   static const int kOwnBit = 1;
 
+  const char* PrivateSymbolToName() const;
+
+#if TRACE_MAPS
+  friend class Name;  // For PrivateSymbolToName.
+#endif
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(Symbol);
 };
 
@@ -8672,6 +8904,9 @@
     friend class String;
   };
 
+  template <typename Char>
+  INLINE(Vector<const Char> GetCharVector());
+
   // Get and set the length of the string.
   inline int length() const;
   inline void set_length(int value);
@@ -8787,8 +9022,8 @@
 
   // Dispatched behavior.
   void StringShortPrint(StringStream* accumulator);
-  void PrintUC16(OStream& os, int start = 0, int end = -1);  // NOLINT
-#ifdef OBJECT_PRINT
+  void PrintUC16(std::ostream& os, int start = 0, int end = -1);  // NOLINT
+#if defined(DEBUG) || defined(OBJECT_PRINT)
   char* ToAsciiArray();
 #endif
   DECLARE_PRINTER(String)
@@ -9257,6 +9492,8 @@
   FlatStringReader(Isolate* isolate, Vector<const char> input);
   void PostGarbageCollection();
   inline uc32 Get(int index);
+  template <typename Char>
+  inline Char Get(int index);
   int length() { return length_; }
  private:
   String** str_;
@@ -9266,26 +9503,13 @@
 };
 
 
-// A ConsStringOp that returns null.
-// Useful when the operation to apply on a ConsString
-// requires an expensive data structure.
-class ConsStringNullOp {
- public:
-  inline ConsStringNullOp() {}
-  static inline String* Operate(String*, unsigned*, int32_t*, unsigned*);
- private:
-  DISALLOW_COPY_AND_ASSIGN(ConsStringNullOp);
-};
-
-
 // This maintains an off-stack representation of the stack frames required
 // to traverse a ConsString, allowing an entirely iterative and restartable
 // traversal of the entire string
-class ConsStringIteratorOp {
+class ConsStringIterator {
  public:
-  inline ConsStringIteratorOp() {}
-  inline explicit ConsStringIteratorOp(ConsString* cons_string,
-                                       int offset = 0) {
+  inline ConsStringIterator() {}
+  inline explicit ConsStringIterator(ConsString* cons_string, int offset = 0) {
     Reset(cons_string, offset);
   }
   inline void Reset(ConsString* cons_string, int offset = 0) {
@@ -9325,14 +9549,13 @@
   int depth_;
   int maximum_depth_;
   int consumed_;
-  DISALLOW_COPY_AND_ASSIGN(ConsStringIteratorOp);
+  DISALLOW_COPY_AND_ASSIGN(ConsStringIterator);
 };
 
 
 class StringCharacterStream {
  public:
   inline StringCharacterStream(String* string,
-                               ConsStringIteratorOp* op,
                                int offset = 0);
   inline uint16_t GetNext();
   inline bool HasMore();
@@ -9341,13 +9564,13 @@
   inline void VisitTwoByteString(const uint16_t* chars, int length);
 
  private:
+  ConsStringIterator iter_;
   bool is_one_byte_;
   union {
     const uint8_t* buffer8_;
     const uint16_t* buffer16_;
   };
   const uint8_t* end_;
-  ConsStringIteratorOp* op_;
   DISALLOW_COPY_AND_ASSIGN(StringCharacterStream);
 };
 
@@ -9467,8 +9690,10 @@
   // of the cell's current type and the value's type. If the change causes
   // a change of the type of the cell's contents, code dependent on the cell
   // will be deoptimized.
-  static void SetValueInferType(Handle<PropertyCell> cell,
-                                Handle<Object> value);
+  // Usually returns the value that was passed in, but may perform
+  // non-observable modifications on it, such as internalize strings.
+  static Handle<Object> SetValueInferType(Handle<PropertyCell> cell,
+                                          Handle<Object> value);
 
   // Computes the new type of the cell's contents for the given value, but
   // without actually modifying the 'type' field.
@@ -9506,6 +9731,37 @@
 };
 
 
+class WeakCell : public HeapObject {
+ public:
+  inline Object* value() const;
+
+  // This should not be called by anyone except GC.
+  inline void clear();
+
+  // This should not be called by anyone except allocator.
+  inline void initialize(HeapObject* value);
+
+  inline bool cleared() const;
+
+  DECL_ACCESSORS(next, Object)
+
+  DECLARE_CAST(WeakCell)
+
+  DECLARE_PRINTER(WeakCell)
+  DECLARE_VERIFIER(WeakCell)
+
+  // Layout description.
+  static const int kValueOffset = HeapObject::kHeaderSize;
+  static const int kNextOffset = kValueOffset + kPointerSize;
+  static const int kSize = kNextOffset + kPointerSize;
+
+  typedef FixedBodyDescriptor<kValueOffset, kSize, kSize> BodyDescriptor;
+
+ private:
+  DISALLOW_IMPLICIT_CONSTRUCTORS(WeakCell);
+};
+
+
 // The JSProxy describes EcmaScript Harmony proxies
 class JSProxy: public JSReceiver {
  public:
@@ -9712,7 +9968,7 @@
   DECL_ACCESSORS(kind, Object)
 
 #ifdef OBJECT_PRINT
-  void OrderedHashTableIteratorPrint(OStream& os);  // NOLINT
+  void OrderedHashTableIteratorPrint(std::ostream& os);  // NOLINT
 #endif
 
   static const int kTableOffset = JSObject::kHeaderSize;
@@ -9856,6 +10112,9 @@
   inline bool should_be_freed();
   inline void set_should_be_freed(bool value);
 
+  inline bool is_neuterable();
+  inline void set_is_neuterable(bool value);
+
   // [weak_next]: linked list of array buffers.
   DECL_ACCESSORS(weak_next, Object)
 
@@ -9885,6 +10144,7 @@
   // Bit position in a flag
   static const int kIsExternalBit = 0;
   static const int kShouldBeFreed = 1;
+  static const int kIsNeuterableBit = 2;
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayBuffer);
 };
@@ -10027,10 +10287,13 @@
                                            uint32_t index,
                                            Handle<Object> value);
 
-  static bool IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map);
+  static bool HasReadOnlyLength(Handle<JSArray> array);
   static bool WouldChangeReadOnlyLength(Handle<JSArray> array, uint32_t index);
   static MaybeHandle<Object> ReadOnlyLengthError(Handle<JSArray> array);
 
+  // TODO(adamk): Remove this method in favor of HasReadOnlyLength().
+  static bool IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map);
+
   // Initialize the array with the given capacity. The function may
   // fail due to out-of-memory situations, but only if the requested
   // capacity is non-zero.
@@ -10383,6 +10646,11 @@
   DECL_ACCESSORS(deleter, Object)
   DECL_ACCESSORS(enumerator, Object)
   DECL_ACCESSORS(data, Object)
+  DECL_BOOLEAN_ACCESSORS(can_intercept_symbols)
+  DECL_BOOLEAN_ACCESSORS(all_can_read)
+
+  inline int flags() const;
+  inline void set_flags(int flags);
 
   DECLARE_CAST(InterceptorInfo)
 
@@ -10396,7 +10664,11 @@
   static const int kDeleterOffset = kQueryOffset + kPointerSize;
   static const int kEnumeratorOffset = kDeleterOffset + kPointerSize;
   static const int kDataOffset = kEnumeratorOffset + kPointerSize;
-  static const int kSize = kDataOffset + kPointerSize;
+  static const int kFlagsOffset = kDataOffset + kPointerSize;
+  static const int kSize = kFlagsOffset + kPointerSize;
+
+  static const int kCanInterceptSymbolsBit = 0;
+  static const int kAllCanReadBit = 1;
 
  private:
   DISALLOW_IMPLICIT_CONSTRUCTORS(InterceptorInfo);
diff --git a/src/optimizing-compiler-thread.cc b/src/optimizing-compiler-thread.cc
index 387e9c0..6926f47 100644
--- a/src/optimizing-compiler-thread.cc
+++ b/src/optimizing-compiler-thread.cc
@@ -15,6 +15,84 @@
 namespace v8 {
 namespace internal {
 
+namespace {
+
+void DisposeOptimizedCompileJob(OptimizedCompileJob* job,
+                                bool restore_function_code) {
+  // The recompile job is allocated in the CompilationInfo's zone.
+  CompilationInfo* info = job->info();
+  if (restore_function_code) {
+    if (info->is_osr()) {
+      if (!job->IsWaitingForInstall()) {
+        // Remove stack check that guards OSR entry on original code.
+        Handle<Code> code = info->unoptimized_code();
+        uint32_t offset = code->TranslateAstIdToPcOffset(info->osr_ast_id());
+        BackEdgeTable::RemoveStackCheck(code, offset);
+      }
+    } else {
+      Handle<JSFunction> function = info->closure();
+      function->ReplaceCode(function->shared()->code());
+    }
+  }
+  delete info;
+}
+
+}  // namespace
+
+
+class OptimizingCompilerThread::CompileTask : public v8::Task {
+ public:
+  explicit CompileTask(Isolate* isolate) : isolate_(isolate) {}
+
+  virtual ~CompileTask() {}
+
+ private:
+  // v8::Task overrides.
+  void Run() OVERRIDE {
+    DisallowHeapAllocation no_allocation;
+    DisallowHandleAllocation no_handles;
+    DisallowHandleDereference no_deref;
+
+    TimerEventScope<TimerEventRecompileConcurrent> timer(isolate_);
+
+    OptimizingCompilerThread* thread = isolate_->optimizing_compiler_thread();
+
+    if (thread->recompilation_delay_ != 0) {
+      base::OS::Sleep(thread->recompilation_delay_);
+    }
+
+    StopFlag flag;
+    OptimizedCompileJob* job = thread->NextInput(&flag);
+
+    if (flag == CONTINUE) {
+      thread->CompileNext(job);
+    } else {
+      AllowHandleDereference allow_handle_dereference;
+      if (!job->info()->is_osr()) {
+        DisposeOptimizedCompileJob(job, true);
+      }
+    }
+    bool signal = false;
+    {
+      base::LockGuard<base::RecursiveMutex> lock(&thread->task_count_mutex_);
+      if (--thread->task_count_ == 0) {
+        if (static_cast<StopFlag>(base::Acquire_Load(&thread->stop_thread_)) ==
+            FLUSH) {
+          base::Release_Store(&thread->stop_thread_,
+                              static_cast<base::AtomicWord>(CONTINUE));
+          signal = true;
+        }
+      }
+    }
+    if (signal) thread->stop_semaphore_.Signal();
+  }
+
+  Isolate* isolate_;
+
+  DISALLOW_COPY_AND_ASSIGN(CompileTask);
+};
+
+
 OptimizingCompilerThread::~OptimizingCompilerThread() {
   DCHECK_EQ(0, input_queue_length_);
   DeleteArray(input_queue_);
@@ -35,27 +113,30 @@
     thread_id_ = ThreadId::Current().ToInteger();
   }
 #endif
-  Isolate::SetIsolateThreadLocals(isolate_, NULL);
   DisallowHeapAllocation no_allocation;
   DisallowHandleAllocation no_handles;
   DisallowHandleDereference no_deref;
 
+  if (job_based_recompilation_) {
+    return;
+  }
+
   base::ElapsedTimer total_timer;
-  if (FLAG_trace_concurrent_recompilation) total_timer.Start();
+  if (tracing_enabled_) total_timer.Start();
 
   while (true) {
     input_queue_semaphore_.Wait();
     TimerEventScope<TimerEventRecompileConcurrent> timer(isolate_);
 
-    if (FLAG_concurrent_recompilation_delay != 0) {
-      base::OS::Sleep(FLAG_concurrent_recompilation_delay);
+    if (recompilation_delay_ != 0) {
+      base::OS::Sleep(recompilation_delay_);
     }
 
     switch (static_cast<StopFlag>(base::Acquire_Load(&stop_thread_))) {
       case CONTINUE:
         break;
       case STOP:
-        if (FLAG_trace_concurrent_recompilation) {
+        if (tracing_enabled_) {
           time_spent_total_ = total_timer.Elapsed();
         }
         stop_semaphore_.Signal();
@@ -73,30 +154,38 @@
     }
 
     base::ElapsedTimer compiling_timer;
-    if (FLAG_trace_concurrent_recompilation) compiling_timer.Start();
+    if (tracing_enabled_) compiling_timer.Start();
 
-    CompileNext();
+    CompileNext(NextInput());
 
-    if (FLAG_trace_concurrent_recompilation) {
+    if (tracing_enabled_) {
       time_spent_compiling_ += compiling_timer.Elapsed();
     }
   }
 }
 
 
-OptimizedCompileJob* OptimizingCompilerThread::NextInput() {
+OptimizedCompileJob* OptimizingCompilerThread::NextInput(StopFlag* flag) {
   base::LockGuard<base::Mutex> access_input_queue_(&input_queue_mutex_);
-  if (input_queue_length_ == 0) return NULL;
+  if (input_queue_length_ == 0) {
+    if (flag) {
+      UNREACHABLE();
+      *flag = CONTINUE;
+    }
+    return NULL;
+  }
   OptimizedCompileJob* job = input_queue_[InputQueueIndex(0)];
   DCHECK_NE(NULL, job);
   input_queue_shift_ = InputQueueIndex(1);
   input_queue_length_--;
+  if (flag) {
+    *flag = static_cast<StopFlag>(base::Acquire_Load(&stop_thread_));
+  }
   return job;
 }
 
 
-void OptimizingCompilerThread::CompileNext() {
-  OptimizedCompileJob* job = NextInput();
+void OptimizingCompilerThread::CompileNext(OptimizedCompileJob* job) {
   DCHECK_NE(NULL, job);
 
   // The function may have already been optimized by OSR.  Simply continue.
@@ -107,35 +196,17 @@
   // The function may have already been optimized by OSR.  Simply continue.
   // Use a mutex to make sure that functions marked for install
   // are always also queued.
+  if (job_based_recompilation_) output_queue_mutex_.Lock();
   output_queue_.Enqueue(job);
+  if (job_based_recompilation_) output_queue_mutex_.Unlock();
   isolate_->stack_guard()->RequestInstallCode();
 }
 
 
-static void DisposeOptimizedCompileJob(OptimizedCompileJob* job,
-                                       bool restore_function_code) {
-  // The recompile job is allocated in the CompilationInfo's zone.
-  CompilationInfo* info = job->info();
-  if (restore_function_code) {
-    if (info->is_osr()) {
-      if (!job->IsWaitingForInstall()) {
-        // Remove stack check that guards OSR entry on original code.
-        Handle<Code> code = info->unoptimized_code();
-        uint32_t offset = code->TranslateAstIdToPcOffset(info->osr_ast_id());
-        BackEdgeTable::RemoveStackCheck(code, offset);
-      }
-    } else {
-      Handle<JSFunction> function = info->closure();
-      function->ReplaceCode(function->shared()->code());
-    }
-  }
-  delete info;
-}
-
-
 void OptimizingCompilerThread::FlushInputQueue(bool restore_function_code) {
   OptimizedCompileJob* job;
   while ((job = NextInput())) {
+    DCHECK(!job_based_recompilation_);
     // This should not block, since we have one signal on the input queue
     // semaphore corresponding to each element in the input queue.
     input_queue_semaphore_.Wait();
@@ -148,6 +219,7 @@
 
 
 void OptimizingCompilerThread::FlushOutputQueue(bool restore_function_code) {
+  base::LockGuard<base::Mutex> access_output_queue_(&output_queue_mutex_);
   OptimizedCompileJob* job;
   while (output_queue_.Dequeue(&job)) {
     // OSR jobs are dealt with separately.
@@ -170,13 +242,23 @@
 
 void OptimizingCompilerThread::Flush() {
   DCHECK(!IsOptimizerThread());
-  base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH));
-  if (FLAG_block_concurrent_recompilation) Unblock();
-  input_queue_semaphore_.Signal();
-  stop_semaphore_.Wait();
+  bool block = true;
+  if (job_based_recompilation_) {
+    base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
+    block = task_count_ > 0 || blocked_jobs_ > 0;
+    if (block) {
+      base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH));
+    }
+    if (FLAG_block_concurrent_recompilation) Unblock();
+  } else {
+    base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH));
+    if (FLAG_block_concurrent_recompilation) Unblock();
+  }
+  if (!job_based_recompilation_) input_queue_semaphore_.Signal();
+  if (block) stop_semaphore_.Wait();
   FlushOutputQueue(true);
   if (FLAG_concurrent_osr) FlushOsrBuffer(true);
-  if (FLAG_trace_concurrent_recompilation) {
+  if (tracing_enabled_) {
     PrintF("  ** Flushed concurrent recompilation queues.\n");
   }
 }
@@ -184,15 +266,25 @@
 
 void OptimizingCompilerThread::Stop() {
   DCHECK(!IsOptimizerThread());
-  base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(STOP));
-  if (FLAG_block_concurrent_recompilation) Unblock();
-  input_queue_semaphore_.Signal();
-  stop_semaphore_.Wait();
+  bool block = true;
+  if (job_based_recompilation_) {
+    base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
+    block = task_count_ > 0 || blocked_jobs_ > 0;
+    if (block) {
+      base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(FLUSH));
+    }
+    if (FLAG_block_concurrent_recompilation) Unblock();
+  } else {
+    base::Release_Store(&stop_thread_, static_cast<base::AtomicWord>(STOP));
+    if (FLAG_block_concurrent_recompilation) Unblock();
+  }
+  if (!job_based_recompilation_) input_queue_semaphore_.Signal();
+  if (block) stop_semaphore_.Wait();
 
-  if (FLAG_concurrent_recompilation_delay != 0) {
+  if (recompilation_delay_ != 0) {
     // At this point the optimizing compiler thread's event loop has stopped.
     // There is no need for a mutex when reading input_queue_length_.
-    while (input_queue_length_ > 0) CompileNext();
+    while (input_queue_length_ > 0) CompileNext(NextInput());
     InstallOptimizedFunctions();
   } else {
     FlushInputQueue(false);
@@ -201,13 +293,13 @@
 
   if (FLAG_concurrent_osr) FlushOsrBuffer(false);
 
-  if (FLAG_trace_concurrent_recompilation) {
+  if (tracing_enabled_) {
     double percentage = time_spent_compiling_.PercentOf(time_spent_total_);
+    if (job_based_recompilation_) percentage = 100.0;
     PrintF("  ** Compiler thread did %.2f%% useful work\n", percentage);
   }
 
-  if ((FLAG_trace_osr || FLAG_trace_concurrent_recompilation) &&
-      FLAG_concurrent_osr) {
+  if ((FLAG_trace_osr || tracing_enabled_) && FLAG_concurrent_osr) {
     PrintF("[COSR hit rate %d / %d]\n", osr_hits_, osr_attempts_);
   }
 
@@ -237,7 +329,7 @@
       BackEdgeTable::RemoveStackCheck(code, offset);
     } else {
       if (function->IsOptimized()) {
-        if (FLAG_trace_concurrent_recompilation) {
+        if (tracing_enabled_) {
           PrintF("  ** Aborting compilation for ");
           function->ShortPrint();
           PrintF(" as it has already been optimized.\n");
@@ -276,6 +368,11 @@
   }
   if (FLAG_block_concurrent_recompilation) {
     blocked_jobs_++;
+  } else if (job_based_recompilation_) {
+    base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
+    ++task_count_;
+    V8::GetCurrentPlatform()->CallOnBackgroundThread(
+        new CompileTask(isolate_), v8::Platform::kShortRunningTask);
   } else {
     input_queue_semaphore_.Signal();
   }
@@ -284,8 +381,17 @@
 
 void OptimizingCompilerThread::Unblock() {
   DCHECK(!IsOptimizerThread());
+  {
+    base::LockGuard<base::RecursiveMutex> lock(&task_count_mutex_);
+    task_count_ += blocked_jobs_;
+  }
   while (blocked_jobs_ > 0) {
-    input_queue_semaphore_.Signal();
+    if (job_based_recompilation_) {
+      V8::GetCurrentPlatform()->CallOnBackgroundThread(
+          new CompileTask(isolate_), v8::Platform::kShortRunningTask);
+    } else {
+      input_queue_semaphore_.Signal();
+    }
     blocked_jobs_--;
   }
 }
diff --git a/src/optimizing-compiler-thread.h b/src/optimizing-compiler-thread.h
index 6ff4f2a..3088843 100644
--- a/src/optimizing-compiler-thread.h
+++ b/src/optimizing-compiler-thread.h
@@ -35,9 +35,13 @@
         input_queue_shift_(0),
         osr_buffer_capacity_(FLAG_concurrent_recompilation_queue_length + 4),
         osr_buffer_cursor_(0),
+        task_count_(0),
         osr_hits_(0),
         osr_attempts_(0),
-        blocked_jobs_(0) {
+        blocked_jobs_(0),
+        tracing_enabled_(FLAG_trace_concurrent_recompilation),
+        job_based_recompilation_(FLAG_job_based_recompilation),
+        recompilation_delay_(FLAG_concurrent_recompilation_delay) {
     base::NoBarrier_Store(&stop_thread_,
                           static_cast<base::AtomicWord>(CONTINUE));
     input_queue_ = NewArray<OptimizedCompileJob*>(input_queue_capacity_);
@@ -84,13 +88,15 @@
 #endif
 
  private:
+  class CompileTask;
+
   enum StopFlag { CONTINUE, STOP, FLUSH };
 
   void FlushInputQueue(bool restore_function_code);
   void FlushOutputQueue(bool restore_function_code);
   void FlushOsrBuffer(bool restore_function_code);
-  void CompileNext();
-  OptimizedCompileJob* NextInput();
+  void CompileNext(OptimizedCompileJob* job);
+  OptimizedCompileJob* NextInput(StopFlag* flag = NULL);
 
   // Add a recompilation task for OSR to the cyclic buffer, awaiting OSR entry.
   // Tasks evicted from the cyclic buffer are discarded.
@@ -121,6 +127,9 @@
 
   // Queue of recompilation tasks ready to be installed (excluding OSR).
   UnboundQueue<OptimizedCompileJob*> output_queue_;
+  // Used for job based recompilation which has multiple producers on
+  // different threads.
+  base::Mutex output_queue_mutex_;
 
   // Cyclic buffer of recompilation tasks for OSR.
   OptimizedCompileJob** osr_buffer_;
@@ -131,10 +140,27 @@
   base::TimeDelta time_spent_compiling_;
   base::TimeDelta time_spent_total_;
 
+  int task_count_;
+  // TODO(jochen): This is currently a RecursiveMutex since both Flush/Stop and
+  // Unblock try to get it, but the former methods both can call Unblock. Once
+  // job based recompilation is on by default, and the dedicated thread can be
+  // removed, this should be refactored to not use a RecursiveMutex.
+  base::RecursiveMutex task_count_mutex_;
+
   int osr_hits_;
   int osr_attempts_;
 
   int blocked_jobs_;
+
+  // Copies of FLAG_trace_concurrent_recompilation,
+  // FLAG_concurrent_recompilation_delay and
+  // FLAG_job_based_recompilation that will be used from the background thread.
+  //
+  // Since flags might get modified while the background thread is running, it
+  // is not safe to access them directly.
+  bool tracing_enabled_;
+  bool job_based_recompilation_;
+  int recompilation_delay_;
 };
 
 } }  // namespace v8::internal
diff --git a/src/ostreams.cc b/src/ostreams.cc
index e927e6b..ee0474d 100644
--- a/src/ostreams.cc
+++ b/src/ostreams.cc
@@ -4,11 +4,6 @@
 
 #include "src/ostreams.h"
 
-#include <algorithm>
-#include <cmath>
-
-#include "src/base/platform/platform.h"  // For isinf/isnan with MSVC
-
 #if V8_OS_WIN
 #define snprintf sprintf_s
 #endif
@@ -16,174 +11,57 @@
 namespace v8 {
 namespace internal {
 
-// Be lazy and delegate the value=>char conversion to snprintf.
-template<class T>
-OStream& OStream::print(const char* format, T x) {
-  char buf[32];
-  int n = snprintf(buf, sizeof(buf), format, x);
-  return (n < 0) ? *this : write(buf, n);
+OFStreamBase::OFStreamBase(FILE* f) : f_(f) {}
+
+
+OFStreamBase::~OFStreamBase() {}
+
+
+OFStreamBase::int_type OFStreamBase::sync() {
+  std::fflush(f_);
+  return 0;
 }
 
 
-OStream& OStream::operator<<(short x) {  // NOLINT(runtime/int)
-  return print(hex_ ? "%hx" : "%hd", x);
+OFStreamBase::int_type OFStreamBase::overflow(int_type c) {
+  return (c != EOF) ? std::fputc(c, f_) : c;
 }
 
 
-OStream& OStream::operator<<(unsigned short x) {  // NOLINT(runtime/int)
-  return print(hex_ ? "%hx" : "%hu", x);
+OFStream::OFStream(FILE* f) : OFStreamBase(f), std::ostream(this) {
+  DCHECK_NOT_NULL(f);
 }
 
 
-OStream& OStream::operator<<(int x) {
-  return print(hex_ ? "%x" : "%d", x);
-}
+OFStream::~OFStream() {}
 
 
-OStream& OStream::operator<<(unsigned int x) {
-  return print(hex_ ? "%x" : "%u", x);
-}
-
-
-OStream& OStream::operator<<(long x) {  // NOLINT(runtime/int)
-  return print(hex_ ? "%lx" : "%ld", x);
-}
-
-
-OStream& OStream::operator<<(unsigned long x) {  // NOLINT(runtime/int)
-  return print(hex_ ? "%lx" : "%lu", x);
-}
-
-
-OStream& OStream::operator<<(long long x) {  // NOLINT(runtime/int)
-  return print(hex_ ? "%llx" : "%lld", x);
-}
-
-
-OStream& OStream::operator<<(unsigned long long x) {  // NOLINT(runtime/int)
-  return print(hex_ ? "%llx" : "%llu", x);
-}
-
-
-OStream& OStream::operator<<(double x) {
-  if (std::isinf(x)) return *this << (x < 0 ? "-inf" : "inf");
-  if (std::isnan(x)) return *this << "nan";
-  return print("%g", x);
-}
-
-
-OStream& OStream::operator<<(void* x) {
-  return print("%p", x);
-}
-
-
-OStream& OStream::operator<<(char x) {
-  return put(x);
-}
-
-
-OStream& OStream::operator<<(signed char x) {
-  return put(x);
-}
-
-
-OStream& OStream::operator<<(unsigned char x) {
-  return put(x);
-}
-
-
-OStream& OStream::dec() {
-  hex_ = false;
-  return *this;
-}
-
-
-OStream& OStream::hex() {
-  hex_ = true;
-  return *this;
-}
-
-
-OStream& flush(OStream& os) {  // NOLINT(runtime/references)
-  return os.flush();
-}
-
-
-OStream& endl(OStream& os) {  // NOLINT(runtime/references)
-  return flush(os.put('\n'));
-}
-
-
-OStream& hex(OStream& os) {  // NOLINT(runtime/references)
-  return os.hex();
-}
-
-
-OStream& dec(OStream& os) {  // NOLINT(runtime/references)
-  return os.dec();
-}
-
-
-OStringStream& OStringStream::write(const char* s, size_t n) {
-  size_t new_size = size_ + n;
-  if (new_size < size_) return *this;  // Overflow => no-op.
-  reserve(new_size + 1);
-  memcpy(data_ + size_, s, n);
-  size_ = new_size;
-  data_[size_] = '\0';
-  return *this;
-}
-
-
-OStringStream& OStringStream::flush() {
-  return *this;
-}
-
-
-void OStringStream::reserve(size_t requested_capacity) {
-  if (requested_capacity <= capacity_) return;
-  size_t new_capacity =  // Handle possible overflow by not doubling.
-      std::max(std::max(capacity_ * 2, capacity_), requested_capacity);
-  char * new_data = allocate(new_capacity);
-  memcpy(new_data, data_, size_);
-  deallocate(data_, capacity_);
-  capacity_ = new_capacity;
-  data_ = new_data;
-}
-
-
-OFStream& OFStream::write(const char* s, size_t n) {
-  if (f_) fwrite(s, n, 1, f_);
-  return *this;
-}
-
-
-OFStream& OFStream::flush() {
-  if (f_) fflush(f_);
-  return *this;
-}
-
+namespace {
 
 // Locale-independent predicates.
-static bool IsPrint(uint16_t c) { return 0x20 <= c && c <= 0x7e; }
-static bool IsSpace(uint16_t c) { return (0x9 <= c && c <= 0xd) || c == 0x20; }
-static bool IsOK(uint16_t c) { return (IsPrint(c) || IsSpace(c)) && c != '\\'; }
+bool IsPrint(uint16_t c) { return 0x20 <= c && c <= 0x7e; }
+bool IsSpace(uint16_t c) { return (0x9 <= c && c <= 0xd) || c == 0x20; }
+bool IsOK(uint16_t c) { return (IsPrint(c) || IsSpace(c)) && c != '\\'; }
 
 
-static OStream& PrintUC16(OStream& os, uint16_t c, bool (*pred)(uint16_t)) {
+std::ostream& PrintUC16(std::ostream& os, uint16_t c, bool (*pred)(uint16_t)) {
   char buf[10];
   const char* format = pred(c) ? "%c" : (c <= 0xff) ? "\\x%02x" : "\\u%04x";
   snprintf(buf, sizeof(buf), format, c);
   return os << buf;
 }
 
+}  // namespace
 
-OStream& operator<<(OStream& os, const AsReversiblyEscapedUC16& c) {
+
+std::ostream& operator<<(std::ostream& os, const AsReversiblyEscapedUC16& c) {
   return PrintUC16(os, c.value, IsOK);
 }
 
 
-OStream& operator<<(OStream& os, const AsUC16& c) {
+std::ostream& operator<<(std::ostream& os, const AsUC16& c) {
   return PrintUC16(os, c.value, IsPrint);
 }
-} }  // namespace v8::internal
+
+}  // namespace internal
+}  // namespace v8
diff --git a/src/ostreams.h b/src/ostreams.h
index 508a88d..56787f7 100644
--- a/src/ostreams.h
+++ b/src/ostreams.h
@@ -5,9 +5,11 @@
 #ifndef V8_OSTREAMS_H_
 #define V8_OSTREAMS_H_
 
-#include <stddef.h>
-#include <stdio.h>
-#include <string.h>
+#include <cstddef>
+#include <cstdio>
+#include <cstring>
+#include <ostream>  // NOLINT
+#include <streambuf>
 
 #include "include/v8config.h"
 #include "src/base/macros.h"
@@ -15,104 +17,28 @@
 namespace v8 {
 namespace internal {
 
-// An abstract base class for output streams with a cut-down standard interface.
-class OStream {
- public:
-  OStream() : hex_(false) { }
-  virtual ~OStream() { }
+class OFStreamBase : public std::streambuf {
+ protected:
+  explicit OFStreamBase(FILE* f);
+  virtual ~OFStreamBase();
 
-  // For manipulators like 'os << endl' or 'os << flush', etc.
-  OStream& operator<<(OStream& (*manipulator)(OStream& os)) {
-    return manipulator(*this);
-  }
-
-  // Numeric conversions.
-  OStream& operator<<(short x);  // NOLINT(runtime/int)
-  OStream& operator<<(unsigned short x);  // NOLINT(runtime/int)
-  OStream& operator<<(int x);
-  OStream& operator<<(unsigned int x);
-  OStream& operator<<(long x);  // NOLINT(runtime/int)
-  OStream& operator<<(unsigned long x);  // NOLINT(runtime/int)
-  OStream& operator<<(long long x);  // NOLINT(runtime/int)
-  OStream& operator<<(unsigned long long x);  // NOLINT(runtime/int)
-  OStream& operator<<(double x);
-  OStream& operator<<(void* x);
-
-  // Character output.
-  OStream& operator<<(char x);
-  OStream& operator<<(signed char x);
-  OStream& operator<<(unsigned char x);
-  OStream& operator<<(const char* s) { return write(s, strlen(s)); }
-  OStream& put(char c) { return write(&c, 1); }
-
-  // Primitive format flag handling, can be extended if needed.
-  OStream& dec();
-  OStream& hex();
-
-  virtual OStream& write(const char* s, size_t n) = 0;
-  virtual OStream& flush() = 0;
-
- private:
-  template<class T> OStream& print(const char* format, T x);
-
-  bool hex_;
-
-  DISALLOW_COPY_AND_ASSIGN(OStream);
-};
-
-
-// Some manipulators.
-OStream& flush(OStream& os);  // NOLINT(runtime/references)
-OStream& endl(OStream& os);  // NOLINT(runtime/references)
-OStream& dec(OStream& os);  // NOLINT(runtime/references)
-OStream& hex(OStream& os);  // NOLINT(runtime/references)
-
-
-// An output stream writing to a character buffer.
-class OStringStream: public OStream {
- public:
-  OStringStream() : size_(0), capacity_(32), data_(allocate(capacity_)) {
-    data_[0] = '\0';
-  }
-  ~OStringStream() { deallocate(data_, capacity_); }
-
-  size_t size() const { return size_; }
-  size_t capacity() const { return capacity_; }
-  const char* data() const { return data_; }
-
-  // Internally, our character data is always 0-terminated.
-  const char* c_str() const { return data(); }
-
-  virtual OStringStream& write(const char* s, size_t n) OVERRIDE;
-  virtual OStringStream& flush() OVERRIDE;
-
- private:
-  // Primitive allocator interface, can be extracted if needed.
-  static char* allocate (size_t n) { return new char[n]; }
-  static void deallocate (char* s, size_t n) { delete[] s; }
-
-  void reserve(size_t requested_capacity);
-
-  size_t size_;
-  size_t capacity_;
-  char* data_;
-
-  DISALLOW_COPY_AND_ASSIGN(OStringStream);
-};
-
-
-// An output stream writing to a file.
-class OFStream: public OStream {
- public:
-  explicit OFStream(FILE* f) : f_(f) { }
-  virtual ~OFStream() { }
-
-  virtual OFStream& write(const char* s, size_t n) OVERRIDE;
-  virtual OFStream& flush() OVERRIDE;
+  int_type sync() FINAL;
+  int_type overflow(int_type c) FINAL;
 
  private:
   FILE* const f_;
 
+  DISALLOW_COPY_AND_ASSIGN(OFStreamBase);
+};
+
+
+// An output stream writing to a file.
+class OFStream FINAL : private virtual OFStreamBase, public std::ostream {
+ public:
+  explicit OFStream(FILE* f);
+  ~OFStream();
+
+ private:
   DISALLOW_COPY_AND_ASSIGN(OFStream);
 };
 
@@ -133,11 +59,13 @@
 // Writes the given character to the output escaping everything outside of
 // printable/space ASCII range. Additionally escapes '\' making escaping
 // reversible.
-OStream& operator<<(OStream& os, const AsReversiblyEscapedUC16& c);
+std::ostream& operator<<(std::ostream& os, const AsReversiblyEscapedUC16& c);
 
 // Writes the given character to the output escaping everything outside
 // of printable ASCII range.
-OStream& operator<<(OStream& os, const AsUC16& c);
-} }  // namespace v8::internal
+std::ostream& operator<<(std::ostream& os, const AsUC16& c);
+
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_OSTREAMS_H_
diff --git a/src/parser.cc b/src/parser.cc
index 7cef210..bfdeaa3 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -15,7 +15,7 @@
 #include "src/messages.h"
 #include "src/parser.h"
 #include "src/preparser.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 #include "src/scanner-character-streams.h"
 #include "src/scopeinfo.h"
 #include "src/string-stream.h"
@@ -111,7 +111,7 @@
   int num_terms = terms_.length();
   RegExpTree* alternative;
   if (num_terms == 0) {
-    alternative = RegExpEmpty::GetInstance();
+    alternative = new (zone()) RegExpEmpty();
   } else if (num_terms == 1) {
     alternative = terms_.last();
   } else {
@@ -126,12 +126,8 @@
 RegExpTree* RegExpBuilder::ToRegExp() {
   FlushTerms();
   int num_alternatives = alternatives_.length();
-  if (num_alternatives == 0) {
-    return RegExpEmpty::GetInstance();
-  }
-  if (num_alternatives == 1) {
-    return alternatives_.last();
-  }
+  if (num_alternatives == 0) return new (zone()) RegExpEmpty();
+  if (num_alternatives == 1) return alternatives_.last();
   return new(zone()) RegExpDisjunction(alternatives_.GetList(zone()));
 }
 
@@ -206,6 +202,7 @@
 
 
 bool ParseData::IsSane() {
+  if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false;
   // Check that the header data is valid and doesn't specify
   // point to positions outside the store.
   int data_length = Length();
@@ -260,7 +257,7 @@
   } else {
     DCHECK(info_->cached_data() != NULL);
     if (compile_options() == ScriptCompiler::kConsumeParserCache) {
-      cached_parse_data_ = new ParseData(*info_->cached_data());
+      cached_parse_data_ = ParseData::FromCachedData(*info_->cached_data());
     }
   }
 }
@@ -275,6 +272,55 @@
 }
 
 
+FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope,
+                                            int pos, int end_pos) {
+  int materialized_literal_count = -1;
+  int expected_property_count = -1;
+  int handler_count = 0;
+  int parameter_count = 0;
+  const AstRawString* name = ast_value_factory()->empty_string();
+
+  Scope* function_scope = NewScope(scope, FUNCTION_SCOPE);
+  function_scope->SetStrictMode(STRICT);
+  // Set start and end position to the same value
+  function_scope->set_start_position(pos);
+  function_scope->set_end_position(pos);
+  ZoneList<Statement*>* body = NULL;
+
+  {
+    AstNodeFactory function_factory(ast_value_factory());
+    FunctionState function_state(&function_state_, &scope_, function_scope,
+                                 &function_factory);
+
+    body = new (zone()) ZoneList<Statement*>(1, zone());
+    if (call_super) {
+      ZoneList<Expression*>* args =
+          new (zone()) ZoneList<Expression*>(0, zone());
+      CallRuntime* call = factory()->NewCallRuntime(
+          ast_value_factory()->empty_string(),
+          Runtime::FunctionForId(Runtime::kDefaultConstructorSuperCall), args,
+          pos);
+      body->Add(factory()->NewExpressionStatement(call, pos), zone());
+      function_scope->RecordSuperConstructorCallUsage();
+    }
+
+    materialized_literal_count = function_state.materialized_literal_count();
+    expected_property_count = function_state.expected_property_count();
+    handler_count = function_state.handler_count();
+  }
+
+  FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
+      name, ast_value_factory(), function_scope, body,
+      materialized_literal_count, expected_property_count, handler_count,
+      parameter_count, FunctionLiteral::kNoDuplicateParameters,
+      FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kIsFunction,
+      FunctionLiteral::kNotParenthesized, FunctionKind::kDefaultConstructor,
+      pos);
+
+  return function_literal;
+}
+
+
 // ----------------------------------------------------------------------------
 // Target is a support class to facilitate manipulation of the
 // Parser's target_stack_ (the stack of potential 'break' and
@@ -342,25 +388,6 @@
 // ----------------------------------------------------------------------------
 // Implementation of Parser
 
-class ParserTraits::Checkpoint
-    : public ParserBase<ParserTraits>::CheckpointBase {
- public:
-  explicit Checkpoint(ParserBase<ParserTraits>* parser)
-      : CheckpointBase(parser), parser_(parser) {
-    saved_ast_node_id_gen_ = *parser_->ast_node_id_gen_;
-  }
-
-  void Restore() {
-    CheckpointBase::Restore();
-    *parser_->ast_node_id_gen_ = saved_ast_node_id_gen_;
-  }
-
- private:
-  ParserBase<ParserTraits>* parser_;
-  AstNode::IdGen saved_ast_node_id_gen_;
-};
-
-
 bool ParserTraits::IsEvalOrArguments(const AstRawString* identifier) const {
   return identifier == parser_->ast_value_factory()->eval_string() ||
          identifier == parser_->ast_value_factory()->arguments_string();
@@ -433,7 +460,7 @@
 
 bool ParserTraits::ShortcutNumericLiteralBinaryExpression(
     Expression** x, Expression* y, Token::Value op, int pos,
-    AstNodeFactory<AstConstructionVisitor>* factory) {
+    AstNodeFactory* factory) {
   if ((*x)->AsLiteral() && (*x)->AsLiteral()->raw_value()->IsNumber() &&
       y->AsLiteral() && y->AsLiteral()->raw_value()->IsNumber()) {
     double x_val = (*x)->AsLiteral()->raw_value()->AsNumber();
@@ -491,9 +518,9 @@
 }
 
 
-Expression* ParserTraits::BuildUnaryExpression(
-    Expression* expression, Token::Value op, int pos,
-    AstNodeFactory<AstConstructionVisitor>* factory) {
+Expression* ParserTraits::BuildUnaryExpression(Expression* expression,
+                                               Token::Value op, int pos,
+                                               AstNodeFactory* factory) {
   DCHECK(expression != NULL);
   if (expression->IsLiteral()) {
     const AstValue* literal = expression->AsLiteral()->raw_value();
@@ -538,7 +565,7 @@
 Expression* ParserTraits::NewThrowReferenceError(const char* message, int pos) {
   return NewThrowError(
       parser_->ast_value_factory()->make_reference_error_string(), message,
-      NULL, pos);
+      parser_->ast_value_factory()->empty_string(), pos);
 }
 
 
@@ -560,17 +587,11 @@
     const AstRawString* constructor, const char* message,
     const AstRawString* arg, int pos) {
   Zone* zone = parser_->zone();
-  int argc = arg != NULL ? 1 : 0;
   const AstRawString* type =
       parser_->ast_value_factory()->GetOneByteString(message);
-  ZoneList<const AstRawString*>* array =
-      new (zone) ZoneList<const AstRawString*>(argc, zone);
-  if (arg != NULL) {
-    array->Add(arg, zone);
-  }
   ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(2, zone);
   args->Add(parser_->factory()->NewStringLiteral(type, pos), zone);
-  args->Add(parser_->factory()->NewStringListLiteral(array, pos), zone);
+  args->Add(parser_->factory()->NewStringLiteral(arg, pos), zone);
   CallRuntime* call_constructor =
       parser_->factory()->NewCallRuntime(constructor, NULL, args, pos);
   return parser_->factory()->NewThrow(call_constructor, pos);
@@ -653,29 +674,28 @@
 }
 
 
-Expression* ParserTraits::ThisExpression(
-    Scope* scope, AstNodeFactory<AstConstructionVisitor>* factory, int pos) {
+Expression* ParserTraits::ThisExpression(Scope* scope, AstNodeFactory* factory,
+                                         int pos) {
   return factory->NewVariableProxy(scope->receiver(), pos);
 }
 
-Expression* ParserTraits::SuperReference(
-    Scope* scope, AstNodeFactory<AstConstructionVisitor>* factory, int pos) {
+Expression* ParserTraits::SuperReference(Scope* scope, AstNodeFactory* factory,
+                                         int pos) {
   return factory->NewSuperReference(
       ThisExpression(scope, factory, pos)->AsVariableProxy(),
       pos);
 }
 
-Expression* ParserTraits::ClassLiteral(
-    const AstRawString* name, Expression* extends, Expression* constructor,
-    ZoneList<ObjectLiteral::Property*>* properties, int pos,
-    AstNodeFactory<AstConstructionVisitor>* factory) {
-  return factory->NewClassLiteral(name, extends, constructor, properties, pos);
+
+Expression* ParserTraits::DefaultConstructor(bool call_super, Scope* scope,
+                                             int pos, int end_pos) {
+  return parser_->DefaultConstructor(call_super, scope, pos, end_pos);
 }
 
-Literal* ParserTraits::ExpressionFromLiteral(
-    Token::Value token, int pos,
-    Scanner* scanner,
-    AstNodeFactory<AstConstructionVisitor>* factory) {
+
+Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos,
+                                             Scanner* scanner,
+                                             AstNodeFactory* factory) {
   switch (token) {
     case Token::NULL_LITERAL:
       return factory->NewNullLiteral(pos);
@@ -694,9 +714,9 @@
 }
 
 
-Expression* ParserTraits::ExpressionFromIdentifier(
-    const AstRawString* name, int pos, Scope* scope,
-    AstNodeFactory<AstConstructionVisitor>* factory) {
+Expression* ParserTraits::ExpressionFromIdentifier(const AstRawString* name,
+                                                   int pos, Scope* scope,
+                                                   AstNodeFactory* factory) {
   if (parser_->fni_ != NULL) parser_->fni_->PushVariableName(name);
   // The name may refer to a module instance object, so its type is unknown.
 #ifdef DEBUG
@@ -708,19 +728,18 @@
 }
 
 
-Expression* ParserTraits::ExpressionFromString(
-    int pos, Scanner* scanner,
-    AstNodeFactory<AstConstructionVisitor>* factory) {
+Expression* ParserTraits::ExpressionFromString(int pos, Scanner* scanner,
+                                               AstNodeFactory* factory) {
   const AstRawString* symbol = GetSymbol(scanner);
   if (parser_->fni_ != NULL) parser_->fni_->PushLiteralName(symbol);
   return factory->NewStringLiteral(symbol, pos);
 }
 
 
-Expression* ParserTraits::GetIterator(
-    Expression* iterable, AstNodeFactory<AstConstructionVisitor>* factory) {
+Expression* ParserTraits::GetIterator(Expression* iterable,
+                                      AstNodeFactory* factory) {
   Expression* iterator_symbol_literal =
-      factory->NewSymbolLiteral("symbolIterator", RelocInfo::kNoPosition);
+      factory->NewSymbolLiteral("iterator_symbol", RelocInfo::kNoPosition);
   int pos = iterable->position();
   Expression* prop =
       factory->NewProperty(iterable, iterator_symbol_literal, pos);
@@ -730,8 +749,8 @@
 }
 
 
-Literal* ParserTraits::GetLiteralTheHole(
-    int position, AstNodeFactory<AstConstructionVisitor>* factory) {
+Literal* ParserTraits::GetLiteralTheHole(int position,
+                                         AstNodeFactory* factory) {
   return factory->NewTheHoleLiteral(RelocInfo::kNoPosition);
 }
 
@@ -752,10 +771,17 @@
 }
 
 
+ClassLiteral* ParserTraits::ParseClassLiteral(
+    const AstRawString* name, Scanner::Location class_name_location,
+    bool name_is_strict_reserved, int pos, bool* ok) {
+  return parser_->ParseClassLiteral(name, class_name_location,
+                                    name_is_strict_reserved, pos, ok);
+}
+
+
 Parser::Parser(CompilationInfo* info, ParseInfo* parse_info)
     : ParserBase<ParserTraits>(&scanner_, parse_info->stack_limit,
-                               info->extension(), NULL, info->zone(),
-                               info->ast_node_id_gen(), this),
+                               info->extension(), NULL, info->zone(), this),
       scanner_(parse_info->unicode_cache),
       reusable_preparser_(NULL),
       original_scope_(NULL),
@@ -769,14 +795,17 @@
       total_preparse_skipped_(0),
       pre_parse_timer_(NULL) {
   DCHECK(!script().is_null() || info->source_stream() != NULL);
-  set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
-  set_allow_modules(!info->is_native() && FLAG_harmony_modules);
-  set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native());
   set_allow_lazy(false);  // Must be explicitly enabled.
-  set_allow_arrow_functions(FLAG_harmony_arrow_functions);
+  set_allow_natives(FLAG_allow_natives_syntax || info->is_native());
+  set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping);
+  set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules);
+  set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions);
   set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals);
-  set_allow_classes(FLAG_harmony_classes);
+  set_allow_harmony_classes(FLAG_harmony_classes);
   set_allow_harmony_object_literals(FLAG_harmony_object_literals);
+  set_allow_harmony_templates(FLAG_harmony_templates);
+  set_allow_harmony_sloppy(FLAG_harmony_sloppy);
+  set_allow_harmony_unicode(FLAG_harmony_unicode);
   for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
        ++feature) {
     use_counts_[feature] = 0;
@@ -807,9 +836,9 @@
   // Initialize parser state.
   CompleteParserRecorder recorder;
 
-  if (compile_options() == ScriptCompiler::kProduceParserCache) {
+  if (produce_cached_parse_data()) {
     log_ = &recorder;
-  } else if (compile_options() == ScriptCompiler::kConsumeParserCache) {
+  } else if (consume_cached_parse_data()) {
     cached_parse_data_->Initialize();
   }
 
@@ -850,7 +879,7 @@
     }
     PrintF(" - took %0.3f ms]\n", ms);
   }
-  if (compile_options() == ScriptCompiler::kProduceParserCache) {
+  if (produce_cached_parse_data()) {
     if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
     log_ = NULL;
   }
@@ -865,8 +894,8 @@
 
   FunctionLiteral* result = NULL;
   {
-    *scope = NewScope(scope_, GLOBAL_SCOPE);
-    info->SetGlobalScope(*scope);
+    *scope = NewScope(scope_, SCRIPT_SCOPE);
+    info->SetScriptScope(*scope);
     if (!info->context().is_null() && !info->context()->IsNativeContext()) {
       *scope = Scope::DeserializeScopeChain(*info->context(), *scope, zone());
       // The Scope is backed up by ScopeInfo (which is in the V8 heap); this
@@ -877,26 +906,27 @@
     }
     original_scope_ = *scope;
     if (info->is_eval()) {
-      if (!(*scope)->is_global_scope() || info->strict_mode() == STRICT) {
+      if (!(*scope)->is_script_scope() || info->strict_mode() == STRICT) {
         *scope = NewScope(*scope, EVAL_SCOPE);
       }
     } else if (info->is_global()) {
-      *scope = NewScope(*scope, GLOBAL_SCOPE);
+      *scope = NewScope(*scope, SCRIPT_SCOPE);
     }
     (*scope)->set_start_position(0);
     // End position will be set by the caller.
 
     // Compute the parsing mode.
     Mode mode = (FLAG_lazy && allow_lazy()) ? PARSE_LAZILY : PARSE_EAGERLY;
-    if (allow_natives_syntax() || extension_ != NULL ||
+    if (allow_natives() || extension_ != NULL ||
         (*scope)->is_eval_scope()) {
       mode = PARSE_EAGERLY;
     }
     ParsingModeScope parsing_mode(this, mode);
 
     // Enters 'scope'.
-    FunctionState function_state(&function_state_, &scope_, *scope, zone(),
-                                 ast_value_factory(), info->ast_node_id_gen());
+    AstNodeFactory function_factory(ast_value_factory());
+    FunctionState function_state(&function_state_, &scope_, *scope,
+                                 &function_factory);
 
     scope_->SetStrictMode(info->strict_mode());
     ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone());
@@ -906,7 +936,7 @@
                         &ok);
 
     if (ok && strict_mode() == STRICT) {
-      CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
+      CheckStrictOctalLiteral(beg_pos, scanner()->location().end_pos, &ok);
     }
 
     if (ok && allow_harmony_scoping() && strict_mode() == STRICT) {
@@ -932,9 +962,6 @@
           FunctionLiteral::kNoDuplicateParameters,
           FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval,
           FunctionLiteral::kNotParenthesized, FunctionKind::kNormalFunction, 0);
-      result->set_ast_properties(factory()->visitor()->ast_properties());
-      result->set_dont_optimize_reason(
-          factory()->visitor()->dont_optimize_reason());
     }
   }
 
@@ -1001,16 +1028,16 @@
 
   {
     // Parse the function literal.
-    Scope* scope = NewScope(scope_, GLOBAL_SCOPE);
-    info()->SetGlobalScope(scope);
+    Scope* scope = NewScope(scope_, SCRIPT_SCOPE);
+    info()->SetScriptScope(scope);
     if (!info()->closure().is_null()) {
       scope = Scope::DeserializeScopeChain(info()->closure()->context(), scope,
                                            zone());
     }
     original_scope_ = scope;
-    FunctionState function_state(&function_state_, &scope_, scope, zone(),
-                                 ast_value_factory(),
-                                 info()->ast_node_id_gen());
+    AstNodeFactory function_factory(ast_value_factory());
+    FunctionState function_state(&function_state_, &scope_, scope,
+                                 &function_factory);
     DCHECK(scope->strict_mode() == SLOPPY || info()->strict_mode() == STRICT);
     DCHECK(info()->strict_mode() == shared_info->strict_mode());
     scope->SetStrictMode(shared_info->strict_mode());
@@ -1025,6 +1052,10 @@
       Expression* expression = ParseExpression(false, &ok);
       DCHECK(expression->IsFunctionLiteral());
       result = expression->AsFunctionLiteral();
+    } else if (shared_info->is_default_constructor()) {
+      result = DefaultConstructor(shared_info->uses_super_constructor_call(),
+                                  scope, shared_info->start_position(),
+                                  shared_info->end_position());
     } else {
       result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
                                     false,  // Strict mode name already checked.
@@ -1100,7 +1131,7 @@
           // all over the code base, so we go with a quick-fix for now.
           // In the same manner, we have to patch the parsing mode.
           if (is_eval && !scope_->is_eval_scope()) {
-            DCHECK(scope_->is_global_scope());
+            DCHECK(scope_->is_script_scope());
             Scope* scope = NewScope(scope_, EVAL_SCOPE);
             scope->set_start_position(scope_->start_position());
             scope->set_end_position(scope_->end_position());
@@ -1734,14 +1765,9 @@
       declaration_scope->is_strict_eval_scope() ||
       declaration_scope->is_block_scope() ||
       declaration_scope->is_module_scope() ||
-      declaration_scope->is_global_scope()) {
+      declaration_scope->is_script_scope()) {
     // Declare the variable in the declaration scope.
-    // For the global scope, we have to check for collisions with earlier
-    // (i.e., enclosing) global scopes, to maintain the illusion of a single
-    // global scope.
-    var = declaration_scope->is_global_scope()
-        ? declaration_scope->Lookup(name)
-        : declaration_scope->LookupLocal(name);
+    var = declaration_scope->LookupLocal(name);
     if (var == NULL) {
       // Declare the name.
       var = declaration_scope->DeclareLocal(name, mode,
@@ -1749,10 +1775,10 @@
                                             kNotAssigned, proxy->interface());
     } else if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())
                || ((mode == CONST_LEGACY || var->mode() == CONST_LEGACY) &&
-                   !declaration_scope->is_global_scope())) {
+                   !declaration_scope->is_script_scope())) {
       // The name was declared in this scope before; check for conflicting
       // re-declarations. We have a conflict if either of the declarations is
-      // not a var (in the global scope, we also have to ignore legacy const for
+      // not a var (in script scope, we also have to ignore legacy const for
       // compatibility). There is similar code in runtime.cc in the Declare
       // functions. The function CheckConflictingVarDeclarations checks for
       // var and let bindings from different scopes whereas this is a check for
@@ -1797,7 +1823,7 @@
   // RuntimeHidden_DeclareLookupSlot calls.
   declaration_scope->AddDeclaration(declaration);
 
-  if (mode == CONST_LEGACY && declaration_scope->is_global_scope()) {
+  if (mode == CONST_LEGACY && declaration_scope->is_script_scope()) {
     // For global const variables we bind the proxy to a variable.
     DCHECK(resolve);  // should be set by all callers
     Variable::Kind kind = Variable::NORMAL;
@@ -1936,11 +1962,11 @@
   // Even if we're not at the top-level of the global or a function
   // scope, we treat it as such and introduce the function with its
   // initial value upon entering the corresponding scope.
-  // In ES6, a function behaves as a lexical binding, except in the
-  // global scope, or the initial scope of eval or another function.
+  // In ES6, a function behaves as a lexical binding, except in
+  // a script scope, or the initial scope of eval or another function.
   VariableMode mode =
       allow_harmony_scoping() && strict_mode() == STRICT &&
-      !(scope_->is_global_scope() || scope_->is_eval_scope() ||
+      !(scope_->is_script_scope() || scope_->is_eval_scope() ||
           scope_->is_function_scope()) ? LET : VAR;
   VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
   Declaration* declaration =
@@ -1967,28 +1993,31 @@
   // so rewrite it as such.
 
   Expect(Token::CLASS, CHECK_OK);
+  if (!allow_harmony_sloppy() && strict_mode() == SLOPPY) {
+    ReportMessage("sloppy_lexical");
+    *ok = false;
+    return NULL;
+  }
+
   int pos = position();
   bool is_strict_reserved = false;
   const AstRawString* name =
       ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
-  Expression* value = ParseClassLiteral(name, scanner()->location(),
-                                        is_strict_reserved, pos, CHECK_OK);
+  ClassLiteral* value = ParseClassLiteral(name, scanner()->location(),
+                                          is_strict_reserved, pos, CHECK_OK);
 
-  Block* block = factory()->NewBlock(NULL, 1, true, pos);
-  VariableMode mode = LET;
-  VariableProxy* proxy = NewUnresolved(name, mode, Interface::NewValue());
+  VariableProxy* proxy = NewUnresolved(name, LET, Interface::NewValue());
   Declaration* declaration =
-      factory()->NewVariableDeclaration(proxy, mode, scope_, pos);
+      factory()->NewVariableDeclaration(proxy, LET, scope_, pos);
   Declare(declaration, true, CHECK_OK);
+  proxy->var()->set_initializer_position(pos);
 
   Token::Value init_op = Token::INIT_LET;
   Assignment* assignment = factory()->NewAssignment(init_op, proxy, value, pos);
-  block->AddStatement(
-      factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
-      zone());
-
+  Statement* assignment_statement =
+      factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
   if (names) names->Add(name, zone());
-  return block;
+  return assignment_statement;
 }
 
 
@@ -2174,6 +2203,7 @@
   Block* block = factory()->NewBlock(NULL, 1, true, pos);
   int nvars = 0;  // the number of variables declared
   const AstRawString* name = NULL;
+  bool is_for_iteration_variable;
   do {
     if (fni_ != NULL) fni_->Enter();
 
@@ -2197,6 +2227,13 @@
     // For let/const declarations in harmony mode, we can also immediately
     // pre-resolve the proxy because it resides in the same scope as the
     // declaration.
+    is_for_iteration_variable =
+        var_context == kForStatement &&
+        (peek() == Token::IN || PeekContextualKeyword(CStrVector("of")));
+    if (is_for_iteration_variable && mode == CONST) {
+      needs_init = false;
+    }
+
     Interface* interface =
         is_const ? Interface::NewConst() : Interface::NewValue();
     VariableProxy* proxy = NewUnresolved(name, mode, interface);
@@ -2242,7 +2279,8 @@
     Expression* value = NULL;
     int pos = -1;
     // Harmony consts have non-optional initializers.
-    if (peek() == Token::ASSIGN || mode == CONST) {
+    if (peek() == Token::ASSIGN ||
+        (mode == CONST && !is_for_iteration_variable)) {
       Expect(Token::ASSIGN, CHECK_OK);
       pos = position();
       value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
@@ -2258,7 +2296,7 @@
     }
 
     // Record the end position of the initializer.
-    if (proxy->var() != NULL) {
+    if (proxy->is_resolved()) {
       proxy->var()->set_initializer_position(position());
     }
 
@@ -2285,7 +2323,7 @@
     // declaration statement has been executed. This is important in
     // browsers where the global object (window) has lots of
     // properties defined in prototype objects.
-    if (initialization_scope->is_global_scope() &&
+    if (initialization_scope->is_script_scope() &&
         !IsLexicalVariableMode(mode)) {
       // Compute the arguments for the runtime call.
       ZoneList<Expression*>* arguments =
@@ -2375,7 +2413,7 @@
 
   // If there was a single non-const declaration, return it in the output
   // parameter for possible use by for/in.
-  if (nvars == 1 && !is_const) {
+  if (nvars == 1 && (!is_const || is_for_iteration_variable)) {
     *out = name;
   }
 
@@ -2448,12 +2486,20 @@
 
   // Parsed expression statement, or the context-sensitive 'module' keyword.
   // Only expect semicolon in the former case.
+  // Also detect attempts at 'let' declarations in sloppy mode.
   if (!FLAG_harmony_modules || peek() != Token::IDENTIFIER ||
       scanner()->HasAnyLineTerminatorBeforeNext() ||
       expr->AsVariableProxy() == NULL ||
       expr->AsVariableProxy()->raw_name() !=
           ast_value_factory()->module_string() ||
       scanner()->literal_contains_escapes()) {
+    if (peek() == Token::IDENTIFIER && expr->AsVariableProxy() != NULL &&
+        expr->AsVariableProxy()->raw_name() ==
+            ast_value_factory()->let_string()) {
+      ReportMessage("sloppy_lexical", NULL);
+      *ok = false;
+      return NULL;
+    }
     ExpectSemicolon(CHECK_OK);
   }
   return factory()->NewExpressionStatement(expr, pos);
@@ -2582,7 +2628,7 @@
   }
 
   Scope* decl_scope = scope_->DeclarationScope();
-  if (decl_scope->is_global_scope() || decl_scope->is_eval_scope()) {
+  if (decl_scope->is_script_scope() || decl_scope->is_eval_scope()) {
     ReportMessageAt(loc, "illegal_return");
     *ok = false;
     return NULL;
@@ -2750,9 +2796,7 @@
     Expect(Token::RPAREN, CHECK_OK);
 
     Target target(&this->target_stack_, &catch_collector);
-    VariableMode mode =
-        allow_harmony_scoping() && strict_mode() == STRICT ? LET : VAR;
-    catch_variable = catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
+    catch_variable = catch_scope->DeclareLocal(name, VAR, kCreatedInitialized);
     BlockState block_state(&scope_, catch_scope);
     catch_block = ParseBlock(NULL, CHECK_OK);
 
@@ -2886,7 +2930,7 @@
     // var iterator = subject[Symbol.iterator]();
     assign_iterator = factory()->NewAssignment(
         Token::ASSIGN, factory()->NewVariableProxy(iterator),
-        GetIterator(subject, factory()), RelocInfo::kNoPosition);
+        GetIterator(subject, factory()), subject->position());
 
     // var result = iterator.next();
     {
@@ -2897,11 +2941,11 @@
           iterator_proxy, next_literal, RelocInfo::kNoPosition);
       ZoneList<Expression*>* next_arguments =
           new(zone()) ZoneList<Expression*>(0, zone());
-      Expression* next_call = factory()->NewCall(
-          next_property, next_arguments, RelocInfo::kNoPosition);
+      Expression* next_call = factory()->NewCall(next_property, next_arguments,
+                                                 subject->position());
       Expression* result_proxy = factory()->NewVariableProxy(result);
-      next_result = factory()->NewAssignment(
-          Token::ASSIGN, result_proxy, next_call, RelocInfo::kNoPosition);
+      next_result = factory()->NewAssignment(Token::ASSIGN, result_proxy,
+                                             next_call, subject->position());
     }
 
     // result.done
@@ -2920,8 +2964,8 @@
       Expression* result_proxy = factory()->NewVariableProxy(result);
       Expression* result_value = factory()->NewProperty(
           result_proxy, value_literal, RelocInfo::kNoPosition);
-      assign_each = factory()->NewAssignment(
-          Token::ASSIGN, each, result_value, RelocInfo::kNoPosition);
+      assign_each = factory()->NewAssignment(Token::ASSIGN, each, result_value,
+                                             each->position());
     }
 
     for_of->Initialize(each, subject, body,
@@ -2946,29 +2990,33 @@
   //
   // We rewrite a for statement of the form
   //
-  //  for (let x = i; cond; next) body
+  //  labels: for (let x = i; cond; next) body
   //
   // into
   //
   //  {
-  //     let x = i;
-  //     temp_x = x;
-  //     flag = 1;
-  //     for (;;) {
-  //        let x = temp_x;
-  //        if (flag == 1) {
-  //          flag = 0;
-  //        } else {
-  //          next;
-  //        }
+  //    let x = i;
+  //    temp_x = x;
+  //    first = 1;
+  //    outer: for (;;) {
+  //      let x = temp_x;
+  //      if (first == 1) {
+  //        first = 0;
+  //      } else {
+  //        next;
+  //      }
+  //      flag = 1;
+  //      labels: for (; flag == 1; flag = 0, temp_x = x) {
   //        if (cond) {
-  //          <empty>
+  //          body
   //        } else {
-  //          break;
+  //          break outer;
   //        }
-  //        b
-  //        temp_x = x;
-  //     }
+  //      }
+  //      if (flag == 1) {
+  //        break;
+  //      }
+  //    }
   //  }
 
   DCHECK(names->length() > 0);
@@ -2977,6 +3025,8 @@
 
   Block* outer_block = factory()->NewBlock(NULL, names->length() + 3, false,
                                            RelocInfo::kNoPosition);
+
+  // Add statement: let x = i.
   outer_block->AddStatement(init, zone());
 
   const AstRawString* temp_name = ast_value_factory()->dot_for_string();
@@ -2996,24 +3046,33 @@
     temps.Add(temp, zone());
   }
 
-  Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
-  // Make statement: flag = 1.
-  {
-    VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
+  Variable* first = NULL;
+  // Make statement: first = 1.
+  if (next) {
+    first = scope_->DeclarationScope()->NewTemporary(temp_name);
+    VariableProxy* first_proxy = factory()->NewVariableProxy(first);
     Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
     Assignment* assignment = factory()->NewAssignment(
-        Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
-    Statement* assignment_statement = factory()->NewExpressionStatement(
-        assignment, RelocInfo::kNoPosition);
+        Token::ASSIGN, first_proxy, const1, RelocInfo::kNoPosition);
+    Statement* assignment_statement =
+        factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
     outer_block->AddStatement(assignment_statement, zone());
   }
 
-  outer_block->AddStatement(loop, zone());
+  // Make statement: outer: for (;;)
+  // Note that we don't actually create the label, or set this loop up as an
+  // explicit break target, instead handing it directly to those nodes that
+  // need to know about it. This should be safe because we don't run any code
+  // in this function that looks up break targets.
+  ForStatement* outer_loop =
+      factory()->NewForStatement(NULL, RelocInfo::kNoPosition);
+  outer_block->AddStatement(outer_loop, zone());
+
   outer_block->set_scope(for_scope);
   scope_ = inner_scope;
 
-  Block* inner_block = factory()->NewBlock(NULL, 2 * names->length() + 3,
-                                           false, RelocInfo::kNoPosition);
+  Block* inner_block = factory()->NewBlock(NULL, names->length() + 4, false,
+                                           RelocInfo::kNoPosition);
   int pos = scanner()->location().beg_pos;
   ZoneList<Variable*> inner_vars(names->length(), zone());
 
@@ -3035,61 +3094,118 @@
     inner_block->AddStatement(assignment_statement, zone());
   }
 
-  // Make statement: if (flag == 1) { flag = 0; } else { next; }.
+  // Make statement: if (first == 1) { first = 0; } else { next; }
   if (next) {
+    DCHECK(first);
+    Expression* compare = NULL;
+    // Make compare expression: first == 1.
+    {
+      Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
+      VariableProxy* first_proxy = factory()->NewVariableProxy(first);
+      compare =
+          factory()->NewCompareOperation(Token::EQ, first_proxy, const1, pos);
+    }
+    Statement* clear_first = NULL;
+    // Make statement: first = 0.
+    {
+      VariableProxy* first_proxy = factory()->NewVariableProxy(first);
+      Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
+      Assignment* assignment = factory()->NewAssignment(
+          Token::ASSIGN, first_proxy, const0, RelocInfo::kNoPosition);
+      clear_first =
+          factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
+    }
+    Statement* clear_first_or_next = factory()->NewIfStatement(
+        compare, clear_first, next, RelocInfo::kNoPosition);
+    inner_block->AddStatement(clear_first_or_next, zone());
+  }
+
+  Variable* flag = scope_->DeclarationScope()->NewTemporary(temp_name);
+  // Make statement: flag = 1.
+  {
+    VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
+    Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
+    Assignment* assignment = factory()->NewAssignment(
+        Token::ASSIGN, flag_proxy, const1, RelocInfo::kNoPosition);
+    Statement* assignment_statement =
+        factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition);
+    inner_block->AddStatement(assignment_statement, zone());
+  }
+
+  // Make cond expression for main loop: flag == 1.
+  Expression* flag_cond = NULL;
+  {
+    Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
+    VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
+    flag_cond =
+        factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, pos);
+  }
+
+  // Create chain of expressions "flag = 0, temp_x = x, ..."
+  Statement* compound_next_statement = NULL;
+  {
+    Expression* compound_next = NULL;
+    // Make expression: flag = 0.
+    {
+      VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
+      Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
+      compound_next = factory()->NewAssignment(Token::ASSIGN, flag_proxy,
+                                               const0, RelocInfo::kNoPosition);
+    }
+
+    // Make the comma-separated list of temp_x = x assignments.
+    for (int i = 0; i < names->length(); i++) {
+      VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
+      VariableProxy* proxy = factory()->NewVariableProxy(inner_vars.at(i), pos);
+      Assignment* assignment = factory()->NewAssignment(
+          Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
+      compound_next = factory()->NewBinaryOperation(
+          Token::COMMA, compound_next, assignment, RelocInfo::kNoPosition);
+    }
+
+    compound_next_statement = factory()->NewExpressionStatement(
+        compound_next, RelocInfo::kNoPosition);
+  }
+
+  // Make statement: if (cond) { body; } else { break outer; }
+  Statement* body_or_stop = body;
+  if (cond) {
+    Statement* stop =
+        factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
+    body_or_stop =
+        factory()->NewIfStatement(cond, body, stop, cond->position());
+  }
+
+  // Make statement: labels: for (; flag == 1; flag = 0, temp_x = x)
+  // Note that we re-use the original loop node, which retains it labels
+  // and ensures that any break or continue statements in body point to
+  // the right place.
+  loop->Initialize(NULL, flag_cond, compound_next_statement, body_or_stop);
+  inner_block->AddStatement(loop, zone());
+
+  // Make statement: if (flag == 1) { break; }
+  {
     Expression* compare = NULL;
     // Make compare expresion: flag == 1.
     {
       Expression* const1 = factory()->NewSmiLiteral(1, RelocInfo::kNoPosition);
       VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
-      compare = factory()->NewCompareOperation(
-          Token::EQ, flag_proxy, const1, pos);
+      compare =
+          factory()->NewCompareOperation(Token::EQ, flag_proxy, const1, pos);
     }
-    Statement* clear_flag = NULL;
-    // Make statement: flag = 0.
-    {
-      VariableProxy* flag_proxy = factory()->NewVariableProxy(flag);
-      Expression* const0 = factory()->NewSmiLiteral(0, RelocInfo::kNoPosition);
-      Assignment* assignment = factory()->NewAssignment(
-          Token::ASSIGN, flag_proxy, const0, RelocInfo::kNoPosition);
-      clear_flag = factory()->NewExpressionStatement(assignment, pos);
-    }
-    Statement* clear_flag_or_next = factory()->NewIfStatement(
-        compare, clear_flag, next, RelocInfo::kNoPosition);
-    inner_block->AddStatement(clear_flag_or_next, zone());
-  }
-
-
-  // Make statement: if (cond) { } else { break; }.
-  if (cond) {
+    Statement* stop =
+        factory()->NewBreakStatement(outer_loop, RelocInfo::kNoPosition);
     Statement* empty = factory()->NewEmptyStatement(RelocInfo::kNoPosition);
-    BreakableStatement* t = LookupBreakTarget(NULL, CHECK_OK);
-    Statement* stop = factory()->NewBreakStatement(t, RelocInfo::kNoPosition);
-    Statement* if_not_cond_break = factory()->NewIfStatement(
-        cond, empty, stop, cond->position());
-    inner_block->AddStatement(if_not_cond_break, zone());
-  }
-
-  inner_block->AddStatement(body, zone());
-
-  // For each let variable x:
-  //   make statement: temp_x = x;
-  for (int i = 0; i < names->length(); i++) {
-    VariableProxy* temp_proxy = factory()->NewVariableProxy(temps.at(i));
-    int pos = scanner()->location().end_pos;
-    VariableProxy* proxy = factory()->NewVariableProxy(inner_vars.at(i), pos);
-    Assignment* assignment = factory()->NewAssignment(
-        Token::ASSIGN, temp_proxy, proxy, RelocInfo::kNoPosition);
-    Statement* assignment_statement = factory()->NewExpressionStatement(
-        assignment, RelocInfo::kNoPosition);
-    inner_block->AddStatement(assignment_statement, zone());
+    Statement* if_flag_break =
+        factory()->NewIfStatement(compare, stop, empty, RelocInfo::kNoPosition);
+    inner_block->AddStatement(if_flag_break, zone());
   }
 
   inner_scope->set_end_position(scanner()->location().end_pos);
   inner_block->set_scope(inner_scope);
   scope_ = for_scope;
 
-  loop->Initialize(NULL, NULL, NULL, inner_block);
+  outer_loop->Initialize(NULL, NULL, NULL, inner_block);
   return outer_block;
 }
 
@@ -3099,7 +3215,7 @@
   // ForStatement ::
   //   'for' '(' Expression? ';' Expression? ';' Expression? ')' Statement
 
-  int pos = peek_position();
+  int stmt_pos = peek_position();
   Statement* init = NULL;
   ZoneList<const AstRawString*> let_bindings(1, zone());
 
@@ -3111,8 +3227,10 @@
   Expect(Token::FOR, CHECK_OK);
   Expect(Token::LPAREN, CHECK_OK);
   for_scope->set_start_position(scanner()->location().beg_pos);
+  bool is_let_identifier_expression = false;
   if (peek() != Token::SEMICOLON) {
-    if (peek() == Token::VAR || peek() == Token::CONST) {
+    if (peek() == Token::VAR ||
+        (peek() == Token::CONST && strict_mode() == SLOPPY)) {
       bool is_const = peek() == Token::CONST;
       const AstRawString* name = NULL;
       VariableDeclarationProperties decl_props = kHasNoInitializers;
@@ -3121,19 +3239,20 @@
                                     CHECK_OK);
       bool accept_OF = decl_props == kHasNoInitializers;
       ForEachStatement::VisitMode mode;
+      int each_pos = position();
 
       if (name != NULL && CheckInOrOf(accept_OF, &mode)) {
         Interface* interface =
             is_const ? Interface::NewConst() : Interface::NewValue();
         ForEachStatement* loop =
-            factory()->NewForEachStatement(mode, labels, pos);
+            factory()->NewForEachStatement(mode, labels, stmt_pos);
         Target target(&this->target_stack_, loop);
 
         Expression* enumerable = ParseExpression(true, CHECK_OK);
         Expect(Token::RPAREN, CHECK_OK);
 
         VariableProxy* each =
-            scope_->NewUnresolved(factory(), name, interface);
+            scope_->NewUnresolved(factory(), name, interface, each_pos);
         Statement* body = ParseStatement(NULL, CHECK_OK);
         InitializeForEachStatement(loop, each, enumerable, body);
         Block* result =
@@ -3149,8 +3268,9 @@
       } else {
         init = variable_statement;
       }
-    } else if (peek() == Token::LET && strict_mode() == STRICT) {
-      DCHECK(allow_harmony_scoping());
+    } else if ((peek() == Token::LET || peek() == Token::CONST) &&
+               strict_mode() == STRICT) {
+      bool is_const = peek() == Token::CONST;
       const AstRawString* name = NULL;
       VariableDeclarationProperties decl_props = kHasNoInitializers;
       Block* variable_statement =
@@ -3159,17 +3279,18 @@
       bool accept_IN = name != NULL && decl_props != kHasInitializers;
       bool accept_OF = decl_props == kHasNoInitializers;
       ForEachStatement::VisitMode mode;
+      int each_pos = position();
 
       if (accept_IN && CheckInOrOf(accept_OF, &mode)) {
         // Rewrite a for-in statement of the form
         //
-        //   for (let x in e) b
+        //   for (let/const x in e) b
         //
         // into
         //
         //   <let x' be a temporary variable>
         //   for (x' in e) {
-        //     let x;
+        //     let/const x;
         //     x = x';
         //     b;
         //   }
@@ -3178,9 +3299,9 @@
         // implementing stack allocated block scoped variables.
         Variable* temp = scope_->DeclarationScope()->NewTemporary(
             ast_value_factory()->dot_for_string());
-        VariableProxy* temp_proxy = factory()->NewVariableProxy(temp);
+        VariableProxy* temp_proxy = factory()->NewVariableProxy(temp, each_pos);
         ForEachStatement* loop =
-            factory()->NewForEachStatement(mode, labels, pos);
+            factory()->NewForEachStatement(mode, labels, stmt_pos);
         Target target(&this->target_stack_, loop);
 
         // The expression does not see the loop variable.
@@ -3189,13 +3310,14 @@
         scope_ = for_scope;
         Expect(Token::RPAREN, CHECK_OK);
 
-        VariableProxy* each =
-            scope_->NewUnresolved(factory(), name, Interface::NewValue());
+        VariableProxy* each = scope_->NewUnresolved(
+            factory(), name, Interface::NewValue(), each_pos);
         Statement* body = ParseStatement(NULL, CHECK_OK);
         Block* body_block =
             factory()->NewBlock(NULL, 3, false, RelocInfo::kNoPosition);
+        Token::Value init_op = is_const ? Token::INIT_CONST : Token::ASSIGN;
         Assignment* assignment = factory()->NewAssignment(
-            Token::ASSIGN, each, temp_proxy, RelocInfo::kNoPosition);
+            init_op, each, temp_proxy, RelocInfo::kNoPosition);
         Statement* assignment_statement = factory()->NewExpressionStatement(
             assignment, RelocInfo::kNoPosition);
         body_block->AddStatement(variable_statement, zone());
@@ -3216,14 +3338,18 @@
       Scanner::Location lhs_location = scanner()->peek_location();
       Expression* expression = ParseExpression(false, CHECK_OK);
       ForEachStatement::VisitMode mode;
-      bool accept_OF = expression->AsVariableProxy();
+      bool accept_OF = expression->IsVariableProxy();
+      is_let_identifier_expression =
+        expression->IsVariableProxy() &&
+        expression->AsVariableProxy()->raw_name() ==
+            ast_value_factory()->let_string();
 
       if (CheckInOrOf(accept_OF, &mode)) {
         expression = this->CheckAndRewriteReferenceExpression(
             expression, lhs_location, "invalid_lhs_in_for", CHECK_OK);
 
         ForEachStatement* loop =
-            factory()->NewForEachStatement(mode, labels, pos);
+            factory()->NewForEachStatement(mode, labels, stmt_pos);
         Target target(&this->target_stack_, loop);
 
         Expression* enumerable = ParseExpression(true, CHECK_OK);
@@ -3239,17 +3365,23 @@
         return loop;
 
       } else {
-        init = factory()->NewExpressionStatement(
-            expression, RelocInfo::kNoPosition);
+        init = factory()->NewExpressionStatement(expression, position());
       }
     }
   }
 
   // Standard 'for' loop
-  ForStatement* loop = factory()->NewForStatement(labels, pos);
+  ForStatement* loop = factory()->NewForStatement(labels, stmt_pos);
   Target target(&this->target_stack_, loop);
 
   // Parsed initializer at this point.
+  // Detect attempts at 'let' declarations in sloppy mode.
+  if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY &&
+      is_let_identifier_expression) {
+    ReportMessage("sloppy_lexical", NULL);
+    *ok = false;
+    return NULL;
+  }
   Expect(Token::SEMICOLON, CHECK_OK);
 
   // If there are let bindings, then condition and the next statement of the
@@ -3269,8 +3401,9 @@
 
   Statement* next = NULL;
   if (peek() != Token::RPAREN) {
+    int next_pos = position();
     Expression* exp = ParseExpression(true, CHECK_OK);
-    next = factory()->NewExpressionStatement(exp, RelocInfo::kNoPosition);
+    next = factory()->NewExpressionStatement(exp, next_pos);
   }
   Expect(Token::RPAREN, CHECK_OK);
 
@@ -3380,7 +3513,7 @@
 
   // Too many parentheses around expression:
   //   (( ... )) => ...
-  if (expression->parenthesization_level() > 1) return false;
+  if (expression->is_multi_parenthesized()) return false;
 
   // Case for a single parameter:
   //   (foo) => ...
@@ -3508,13 +3641,11 @@
   FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
       ? FunctionLiteral::kIsParenthesized
       : FunctionLiteral::kNotParenthesized;
-  AstProperties ast_properties;
-  BailoutReason dont_optimize_reason = kNoReason;
   // Parse function body.
   {
-    FunctionState function_state(&function_state_, &scope_, scope, zone(),
-                                 ast_value_factory(),
-                                 info()->ast_node_id_gen());
+    AstNodeFactory function_factory(ast_value_factory());
+    FunctionState function_state(&function_state_, &scope_, scope,
+                                 &function_factory);
     scope_->SetScopeName(function_name);
 
     if (is_generator) {
@@ -3672,13 +3803,9 @@
                                            CHECK_OK);
     }
     if (strict_mode() == STRICT) {
-      CheckOctalLiteral(scope->start_position(),
-                        scope->end_position(),
-                        CHECK_OK);
+      CheckStrictOctalLiteral(scope->start_position(), scope->end_position(),
+                              CHECK_OK);
     }
-    ast_properties = *factory()->visitor()->ast_properties();
-    dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
-
     if (allow_harmony_scoping() && strict_mode() == STRICT) {
       CheckConflictingVarDeclarations(scope, CHECK_OK);
     }
@@ -3690,8 +3817,6 @@
       num_parameters, duplicate_parameters, function_type,
       FunctionLiteral::kIsFunction, parenthesized, kind, pos);
   function_literal->set_function_token_position(function_token_pos);
-  function_literal->set_ast_properties(&ast_properties);
-  function_literal->set_dont_optimize_reason(dont_optimize_reason);
 
   if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal);
   return function_literal;
@@ -3702,64 +3827,66 @@
                                   int* materialized_literal_count,
                                   int* expected_property_count,
                                   bool* ok) {
+  if (produce_cached_parse_data()) CHECK(log_);
+
   int function_block_pos = position();
-  if (compile_options() == ScriptCompiler::kConsumeParserCache) {
+  if (consume_cached_parse_data() && !cached_parse_data_->rejected()) {
     // If we have cached data, we use it to skip parsing the function body. The
     // data contains the information we need to construct the lazy function.
     FunctionEntry entry =
         cached_parse_data_->GetFunctionEntry(function_block_pos);
-    // Check that cached data is valid.
-    CHECK(entry.is_valid());
-    // End position greater than end of stream is safe, and hard to check.
-    CHECK(entry.end_pos() > function_block_pos);
-    scanner()->SeekForward(entry.end_pos() - 1);
+    // Check that cached data is valid. If not, mark it as invalid (the embedder
+    // handles it). Note that end position greater than end of stream is safe,
+    // and hard to check.
+    if (entry.is_valid() && entry.end_pos() > function_block_pos) {
+      scanner()->SeekForward(entry.end_pos() - 1);
 
-    scope_->set_end_position(entry.end_pos());
-    Expect(Token::RBRACE, ok);
-    if (!*ok) {
+      scope_->set_end_position(entry.end_pos());
+      Expect(Token::RBRACE, ok);
+      if (!*ok) {
+        return;
+      }
+      total_preparse_skipped_ += scope_->end_position() - function_block_pos;
+      *materialized_literal_count = entry.literal_count();
+      *expected_property_count = entry.property_count();
+      scope_->SetStrictMode(entry.strict_mode());
       return;
     }
-    total_preparse_skipped_ += scope_->end_position() - function_block_pos;
-    *materialized_literal_count = entry.literal_count();
-    *expected_property_count = entry.property_count();
-    scope_->SetStrictMode(entry.strict_mode());
-  } else {
-    // With no cached data, we partially parse the function, without building an
-    // AST. This gathers the data needed to build a lazy function.
-    SingletonLogger logger;
-    PreParser::PreParseResult result =
-        ParseLazyFunctionBodyWithPreParser(&logger);
-    if (result == PreParser::kPreParseStackOverflow) {
-      // Propagate stack overflow.
-      set_stack_overflow();
-      *ok = false;
-      return;
-    }
-    if (logger.has_error()) {
-      ParserTraits::ReportMessageAt(
-          Scanner::Location(logger.start(), logger.end()),
-          logger.message(), logger.argument_opt(), logger.is_reference_error());
-      *ok = false;
-      return;
-    }
-    scope_->set_end_position(logger.end());
-    Expect(Token::RBRACE, ok);
-    if (!*ok) {
-      return;
-    }
-    total_preparse_skipped_ += scope_->end_position() - function_block_pos;
-    *materialized_literal_count = logger.literals();
-    *expected_property_count = logger.properties();
-    scope_->SetStrictMode(logger.strict_mode());
-    if (compile_options() == ScriptCompiler::kProduceParserCache) {
-      DCHECK(log_);
-      // Position right after terminal '}'.
-      int body_end = scanner()->location().end_pos;
-      log_->LogFunction(function_block_pos, body_end,
-                        *materialized_literal_count,
-                        *expected_property_count,
-                        scope_->strict_mode());
-    }
+    cached_parse_data_->Reject();
+  }
+  // With no cached data, we partially parse the function, without building an
+  // AST. This gathers the data needed to build a lazy function.
+  SingletonLogger logger;
+  PreParser::PreParseResult result =
+      ParseLazyFunctionBodyWithPreParser(&logger);
+  if (result == PreParser::kPreParseStackOverflow) {
+    // Propagate stack overflow.
+    set_stack_overflow();
+    *ok = false;
+    return;
+  }
+  if (logger.has_error()) {
+    ParserTraits::ReportMessageAt(
+        Scanner::Location(logger.start(), logger.end()), logger.message(),
+        logger.argument_opt(), logger.is_reference_error());
+    *ok = false;
+    return;
+  }
+  scope_->set_end_position(logger.end());
+  Expect(Token::RBRACE, ok);
+  if (!*ok) {
+    return;
+  }
+  total_preparse_skipped_ += scope_->end_position() - function_block_pos;
+  *materialized_literal_count = logger.literals();
+  *expected_property_count = logger.properties();
+  scope_->SetStrictMode(logger.strict_mode());
+  if (produce_cached_parse_data()) {
+    DCHECK(log_);
+    // Position right after terminal '}'.
+    int body_end = scanner()->location().end_pos;
+    log_->LogFunction(function_block_pos, body_end, *materialized_literal_count,
+                      *expected_property_count, scope_->strict_mode());
   }
 }
 
@@ -3834,16 +3961,20 @@
 
   if (reusable_preparser_ == NULL) {
     reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_);
-    reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
-    reusable_preparser_->set_allow_modules(allow_modules());
-    reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax());
     reusable_preparser_->set_allow_lazy(true);
-    reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions());
+    reusable_preparser_->set_allow_natives(allow_natives());
+    reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
+    reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules());
+    reusable_preparser_->set_allow_harmony_arrow_functions(
+        allow_harmony_arrow_functions());
     reusable_preparser_->set_allow_harmony_numeric_literals(
         allow_harmony_numeric_literals());
-    reusable_preparser_->set_allow_classes(allow_classes());
+    reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes());
     reusable_preparser_->set_allow_harmony_object_literals(
         allow_harmony_object_literals());
+    reusable_preparser_->set_allow_harmony_templates(allow_harmony_templates());
+    reusable_preparser_->set_allow_harmony_sloppy(allow_harmony_sloppy());
+    reusable_preparser_->set_allow_harmony_unicode(allow_harmony_unicode());
   }
   PreParser::PreParseResult result =
       reusable_preparser_->PreParseLazyFunction(strict_mode(),
@@ -3856,6 +3987,90 @@
 }
 
 
+ClassLiteral* Parser::ParseClassLiteral(const AstRawString* name,
+                                        Scanner::Location class_name_location,
+                                        bool name_is_strict_reserved, int pos,
+                                        bool* ok) {
+  // All parts of a ClassDeclaration and ClassExpression are strict code.
+  if (name_is_strict_reserved) {
+    ReportMessageAt(class_name_location, "unexpected_strict_reserved");
+    *ok = false;
+    return NULL;
+  }
+  if (IsEvalOrArguments(name)) {
+    ReportMessageAt(class_name_location, "strict_eval_arguments");
+    *ok = false;
+    return NULL;
+  }
+
+  Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
+  BlockState block_state(&scope_, block_scope);
+  scope_->SetStrictMode(STRICT);
+  scope_->SetScopeName(name);
+
+  VariableProxy* proxy = NULL;
+  if (name != NULL) {
+    proxy = NewUnresolved(name, CONST, Interface::NewConst());
+    Declaration* declaration =
+        factory()->NewVariableDeclaration(proxy, CONST, block_scope, pos);
+    Declare(declaration, true, CHECK_OK);
+  }
+
+  Expression* extends = NULL;
+  if (Check(Token::EXTENDS)) {
+    block_scope->set_start_position(scanner()->location().end_pos);
+    extends = ParseLeftHandSideExpression(CHECK_OK);
+  } else {
+    block_scope->set_start_position(scanner()->location().end_pos);
+  }
+
+  ZoneList<ObjectLiteral::Property*>* properties = NewPropertyList(4, zone());
+  Expression* constructor = NULL;
+  bool has_seen_constructor = false;
+
+  Expect(Token::LBRACE, CHECK_OK);
+  while (peek() != Token::RBRACE) {
+    if (Check(Token::SEMICOLON)) continue;
+    if (fni_ != NULL) fni_->Enter();
+    const bool in_class = true;
+    const bool is_static = false;
+    ObjectLiteral::Property* property = ParsePropertyDefinition(
+        NULL, in_class, is_static, &has_seen_constructor, CHECK_OK);
+
+    if (has_seen_constructor && constructor == NULL) {
+      constructor = GetPropertyValue(property);
+    } else {
+      properties->Add(property, zone());
+    }
+
+    if (fni_ != NULL) {
+      fni_->Infer();
+      fni_->Leave();
+    }
+  }
+
+  Expect(Token::RBRACE, CHECK_OK);
+  int end_pos = scanner()->location().end_pos;
+
+  if (constructor == NULL) {
+    constructor =
+        DefaultConstructor(extends != NULL, block_scope, pos, end_pos);
+  }
+
+  block_scope->set_end_position(end_pos);
+  block_scope = block_scope->FinalizeBlockScope();
+
+  if (name != NULL) {
+    DCHECK_NOT_NULL(proxy);
+    DCHECK_NOT_NULL(block_scope);
+    proxy->var()->set_initializer_position(end_pos);
+  }
+
+  return factory()->NewClassLiteral(name, block_scope, proxy, extends,
+                                    constructor, properties, pos, end_pos);
+}
+
+
 Expression* Parser::ParseV8Intrinsic(bool* ok) {
   // CallRuntime ::
   //   '%' Identifier Arguments
@@ -4107,6 +4322,9 @@
     }
   } else {
     current_ = kEndMarker;
+    // Advance so that position() points to 1-after-the-last-character. This is
+    // important so that Reset() to this position works correctly.
+    next_pos_ = in()->length() + 1;
     has_more_ = false;
   }
 }
@@ -4894,7 +5112,7 @@
   DCHECK(info()->function() == NULL);
   FunctionLiteral* result = NULL;
   pre_parse_timer_ = isolate()->counters()->pre_parse();
-  if (FLAG_trace_parse || allow_natives_syntax() || extension_ != NULL) {
+  if (FLAG_trace_parse || allow_natives() || extension_ != NULL) {
     // If intrinsics are allowed, the Parser cannot operate independent of the
     // V8 heap because of Runtime. Tell the string table to internalize strings
     // and values right after they're created.
@@ -4926,9 +5144,7 @@
   fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
 
   CompleteParserRecorder recorder;
-  if (compile_options() == ScriptCompiler::kProduceParserCache) {
-    log_ = &recorder;
-  }
+  if (produce_cached_parse_data()) log_ = &recorder;
 
   DCHECK(info()->source_stream() != NULL);
   ExternalStreamingStream stream(info()->source_stream(),
@@ -4956,9 +5172,131 @@
   // We cannot internalize on a background thread; a foreground task will take
   // care of calling Parser::Internalize just before compilation.
 
-  if (compile_options() == ScriptCompiler::kProduceParserCache) {
+  if (produce_cached_parse_data()) {
     if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
     log_ = NULL;
   }
 }
+
+
+ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) {
+  return new (zone()) ParserTraits::TemplateLiteral(zone(), pos);
+}
+
+
+void Parser::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
+  int pos = scanner()->location().beg_pos;
+  int end = scanner()->location().end_pos - (tail ? 1 : 2);
+  const AstRawString* tv = scanner()->CurrentSymbol(ast_value_factory());
+  const AstRawString* trv = scanner()->CurrentRawSymbol(ast_value_factory());
+  Literal* cooked = factory()->NewStringLiteral(tv, pos);
+  Literal* raw = factory()->NewStringLiteral(trv, pos);
+  (*state)->AddTemplateSpan(cooked, raw, end, zone());
+}
+
+
+void Parser::AddTemplateExpression(TemplateLiteralState* state,
+                                   Expression* expression) {
+  (*state)->AddExpression(expression, zone());
+}
+
+
+Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
+                                         Expression* tag) {
+  TemplateLiteral* lit = *state;
+  int pos = lit->position();
+  const ZoneList<Expression*>* cooked_strings = lit->cooked();
+  const ZoneList<Expression*>* raw_strings = lit->raw();
+  const ZoneList<Expression*>* expressions = lit->expressions();
+  DCHECK_EQ(cooked_strings->length(), raw_strings->length());
+  DCHECK_EQ(cooked_strings->length(), expressions->length() + 1);
+
+  if (!tag) {
+    // Build tree of BinaryOps to simplify code-generation
+    Expression* expr = NULL;
+
+    if (expressions->length() == 0) {
+      // Simple case: treat as string literal
+      expr = cooked_strings->at(0);
+    } else {
+      int i;
+      Expression* cooked_str = cooked_strings->at(0);
+      expr = factory()->NewBinaryOperation(
+          Token::ADD, cooked_str, expressions->at(0), cooked_str->position());
+      for (i = 1; i < expressions->length(); ++i) {
+        cooked_str = cooked_strings->at(i);
+        expr = factory()->NewBinaryOperation(
+            Token::ADD, expr, factory()->NewBinaryOperation(
+                                  Token::ADD, cooked_str, expressions->at(i),
+                                  cooked_str->position()),
+            cooked_str->position());
+      }
+      cooked_str = cooked_strings->at(i);
+      expr = factory()->NewBinaryOperation(Token::ADD, expr, cooked_str,
+                                           cooked_str->position());
+    }
+    return expr;
+  } else {
+    uint32_t hash = ComputeTemplateLiteralHash(lit);
+
+    int cooked_idx = function_state_->NextMaterializedLiteralIndex();
+    int raw_idx = function_state_->NextMaterializedLiteralIndex();
+
+    // GetTemplateCallSite
+    ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(4, zone());
+    args->Add(factory()->NewArrayLiteral(
+                  const_cast<ZoneList<Expression*>*>(cooked_strings),
+                  cooked_idx, pos),
+              zone());
+    args->Add(
+        factory()->NewArrayLiteral(
+            const_cast<ZoneList<Expression*>*>(raw_strings), raw_idx, pos),
+        zone());
+
+    // Ensure hash is suitable as a Smi value
+    Smi* hash_obj = Smi::cast(Internals::IntToSmi(static_cast<int>(hash)));
+    args->Add(factory()->NewSmiLiteral(hash_obj->value(), pos), zone());
+
+    this->CheckPossibleEvalCall(tag, scope_);
+    Expression* call_site = factory()->NewCallRuntime(
+        ast_value_factory()->get_template_callsite_string(), NULL, args, start);
+
+    // Call TagFn
+    ZoneList<Expression*>* call_args =
+        new (zone()) ZoneList<Expression*>(expressions->length() + 1, zone());
+    call_args->Add(call_site, zone());
+    call_args->AddAll(*expressions, zone());
+    return factory()->NewCall(tag, call_args, pos);
+  }
+}
+
+
+uint32_t Parser::ComputeTemplateLiteralHash(const TemplateLiteral* lit) {
+  const ZoneList<Expression*>* raw_strings = lit->raw();
+  int total = raw_strings->length();
+  DCHECK(total);
+
+  uint32_t running_hash = 0;
+
+  for (int index = 0; index < total; ++index) {
+    if (index) {
+      running_hash = StringHasher::ComputeRunningHashOneByte(
+          running_hash, "${}", 3);
+    }
+
+    const AstRawString* raw_string =
+        raw_strings->at(index)->AsLiteral()->raw_value()->AsString();
+    if (raw_string->is_one_byte()) {
+      const char* data = reinterpret_cast<const char*>(raw_string->raw_data());
+      running_hash = StringHasher::ComputeRunningHashOneByte(
+          running_hash, data, raw_string->length());
+    } else {
+      const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data());
+      running_hash = StringHasher::ComputeRunningHash(running_hash, data,
+                                                      raw_string->length());
+    }
+  }
+
+  return running_hash;
+}
 } }  // namespace v8::internal
diff --git a/src/parser.h b/src/parser.h
index 40886f6..219f1c4 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -23,8 +23,6 @@
 class PositionStack;
 class Target;
 
-template <typename T> class ZoneListWrapper;
-
 
 class FunctionEntry BASE_EMBEDDED {
  public:
@@ -62,10 +60,14 @@
 // Wrapper around ScriptData to provide parser-specific functionality.
 class ParseData {
  public:
-  explicit ParseData(ScriptData* script_data) : script_data_(script_data) {
-    CHECK(IsAligned(script_data->length(), sizeof(unsigned)));
-    CHECK(IsSane());
+  static ParseData* FromCachedData(ScriptData* cached_data) {
+    ParseData* pd = new ParseData(cached_data);
+    if (pd->IsSane()) return pd;
+    cached_data->Reject();
+    delete pd;
+    return NULL;
   }
+
   void Initialize();
   FunctionEntry GetFunctionEntry(int start);
   int FunctionCount();
@@ -76,7 +78,13 @@
     return reinterpret_cast<unsigned*>(const_cast<byte*>(script_data_->data()));
   }
 
+  void Reject() { script_data_->Reject(); }
+
+  bool rejected() const { return script_data_->rejected(); }
+
  private:
+  explicit ParseData(ScriptData* script_data) : script_data_(script_data) {}
+
   bool IsSane();
   unsigned Magic();
   unsigned Version();
@@ -352,6 +360,8 @@
     // Used by FunctionState and BlockState.
     typedef v8::internal::Scope Scope;
     typedef v8::internal::Scope* ScopePtr;
+    inline static Scope* ptr_to_scope(ScopePtr scope) { return scope; }
+
     typedef Variable GeneratorVariable;
     typedef v8::internal::Zone Zone;
 
@@ -371,28 +381,11 @@
     typedef ZoneList<v8::internal::Statement*>* StatementList;
 
     // For constructing objects returned by the traversing functions.
-    typedef AstNodeFactory<AstConstructionVisitor> Factory;
+    typedef AstNodeFactory Factory;
   };
 
-  class Checkpoint;
-
   explicit ParserTraits(Parser* parser) : parser_(parser) {}
 
-  // Custom operations executed when FunctionStates are created and destructed.
-  template <typename FunctionState>
-  static void SetUpFunctionState(FunctionState* function_state) {
-    function_state->saved_id_gen_ = *function_state->ast_node_id_gen_;
-    *function_state->ast_node_id_gen_ =
-        AstNode::IdGen(BailoutId::FirstUsable().ToInt());
-  }
-
-  template <typename FunctionState>
-  static void TearDownFunctionState(FunctionState* function_state) {
-    if (function_state->outer_function_state_ != NULL) {
-      *function_state->ast_node_id_gen_ = function_state->saved_id_gen_;
-    }
-  }
-
   // Helper functions for recursive descent.
   bool IsEvalOrArguments(const AstRawString* identifier) const;
   V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const;
@@ -419,6 +412,15 @@
     return string->AsArrayIndex(index);
   }
 
+  bool IsConstructorProperty(ObjectLiteral::Property* property) {
+    return property->key()->raw_value()->EqualsString(
+        ast_value_factory()->constructor_string());
+  }
+
+  static Expression* GetPropertyValue(ObjectLiteral::Property* property) {
+    return property->value();
+  }
+
   // Functions for encapsulating the differences between parsing and preparsing;
   // operations interleaved with the recursive descent.
   static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) {
@@ -433,7 +435,7 @@
   static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
       Scope* scope, ObjectLiteralProperty* property, bool* has_function) {
     Expression* value = property->value();
-    if (scope->DeclarationScope()->is_global_scope() &&
+    if (scope->DeclarationScope()->is_script_scope() &&
         value->AsFunctionLiteral() != NULL) {
       *has_function = true;
       value->AsFunctionLiteral()->set_pretenure();
@@ -457,9 +459,9 @@
   // Returns true if we have a binary expression between two numeric
   // literals. In that case, *x will be changed to an expression which is the
   // computed value.
-  bool ShortcutNumericLiteralBinaryExpression(
-      Expression** x, Expression* y, Token::Value op, int pos,
-      AstNodeFactory<AstConstructionVisitor>* factory);
+  bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y,
+                                              Token::Value op, int pos,
+                                              AstNodeFactory* factory);
 
   // Rewrites the following types of unary expressions:
   // not <literal> -> true / false
@@ -472,9 +474,8 @@
   // + foo -> foo * 1
   // - foo -> foo * (-1)
   // ~ foo -> foo ^(~0)
-  Expression* BuildUnaryExpression(
-      Expression* expression, Token::Value op, int pos,
-      AstNodeFactory<AstConstructionVisitor>* factory);
+  Expression* BuildUnaryExpression(Expression* expression, Token::Value op,
+                                   int pos, AstNodeFactory* factory);
 
   // Generate AST node that throws a ReferenceError with the given type.
   Expression* NewThrowReferenceError(const char* type, int pos);
@@ -534,37 +535,26 @@
   V8_INLINE const AstRawString* EmptyIdentifierString();
 
   // Odd-ball literal creators.
-  Literal* GetLiteralTheHole(int position,
-                             AstNodeFactory<AstConstructionVisitor>* factory);
+  Literal* GetLiteralTheHole(int position, AstNodeFactory* factory);
 
   // Producing data during the recursive descent.
   const AstRawString* GetSymbol(Scanner* scanner);
   const AstRawString* GetNextSymbol(Scanner* scanner);
   const AstRawString* GetNumberAsSymbol(Scanner* scanner);
 
-  Expression* ThisExpression(Scope* scope,
-                             AstNodeFactory<AstConstructionVisitor>* factory,
+  Expression* ThisExpression(Scope* scope, AstNodeFactory* factory,
                              int pos = RelocInfo::kNoPosition);
-  Expression* SuperReference(Scope* scope,
-                             AstNodeFactory<AstConstructionVisitor>* factory,
+  Expression* SuperReference(Scope* scope, AstNodeFactory* factory,
                              int pos = RelocInfo::kNoPosition);
-  Expression* ClassLiteral(const AstRawString* name, Expression* extends,
-                           Expression* constructor,
-                           ZoneList<ObjectLiteral::Property*>* properties,
-                           int pos,
-                           AstNodeFactory<AstConstructionVisitor>* factory);
-
-  Literal* ExpressionFromLiteral(
-      Token::Value token, int pos, Scanner* scanner,
-      AstNodeFactory<AstConstructionVisitor>* factory);
-  Expression* ExpressionFromIdentifier(
-      const AstRawString* name, int pos, Scope* scope,
-      AstNodeFactory<AstConstructionVisitor>* factory);
-  Expression* ExpressionFromString(
-      int pos, Scanner* scanner,
-      AstNodeFactory<AstConstructionVisitor>* factory);
-  Expression* GetIterator(Expression* iterable,
-                          AstNodeFactory<AstConstructionVisitor>* factory);
+  Expression* DefaultConstructor(bool call_super, Scope* scope, int pos,
+                                 int end_pos);
+  Literal* ExpressionFromLiteral(Token::Value token, int pos, Scanner* scanner,
+                                 AstNodeFactory* factory);
+  Expression* ExpressionFromIdentifier(const AstRawString* name, int pos,
+                                       Scope* scope, AstNodeFactory* factory);
+  Expression* ExpressionFromString(int pos, Scanner* scanner,
+                                   AstNodeFactory* factory);
+  Expression* GetIterator(Expression* iterable, AstNodeFactory* factory);
   ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
     return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
   }
@@ -595,9 +585,57 @@
   V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody(
       const AstRawString* name, int pos, Variable* fvar,
       Token::Value fvar_init_op, bool is_generator, bool* ok);
+
+  ClassLiteral* ParseClassLiteral(const AstRawString* name,
+                                  Scanner::Location class_name_location,
+                                  bool name_is_strict_reserved, int pos,
+                                  bool* ok);
+
   V8_INLINE void CheckConflictingVarDeclarations(v8::internal::Scope* scope,
                                                  bool* ok);
 
+  class TemplateLiteral : public ZoneObject {
+   public:
+    TemplateLiteral(Zone* zone, int pos)
+        : cooked_(8, zone), raw_(8, zone), expressions_(8, zone), pos_(pos) {}
+
+    const ZoneList<Expression*>* cooked() const { return &cooked_; }
+    const ZoneList<Expression*>* raw() const { return &raw_; }
+    const ZoneList<Expression*>* expressions() const { return &expressions_; }
+    int position() const { return pos_; }
+
+    void AddTemplateSpan(Literal* cooked, Literal* raw, int end, Zone* zone) {
+      DCHECK_NOT_NULL(cooked);
+      DCHECK_NOT_NULL(raw);
+      cooked_.Add(cooked, zone);
+      raw_.Add(raw, zone);
+    }
+
+    void AddExpression(Expression* expression, Zone* zone) {
+      DCHECK_NOT_NULL(expression);
+      expressions_.Add(expression, zone);
+    }
+
+   private:
+    ZoneList<Expression*> cooked_;
+    ZoneList<Expression*> raw_;
+    ZoneList<Expression*> expressions_;
+    int pos_;
+  };
+
+  typedef TemplateLiteral* TemplateLiteralState;
+
+  V8_INLINE TemplateLiteralState OpenTemplateLiteral(int pos);
+  V8_INLINE void AddTemplateSpan(TemplateLiteralState* state, bool tail);
+  V8_INLINE void AddTemplateExpression(TemplateLiteralState* state,
+                                       Expression* expression);
+  V8_INLINE Expression* CloseTemplateLiteral(TemplateLiteralState* state,
+                                             int start, Expression* tag);
+  V8_INLINE Expression* NoTemplateTag() { return NULL; }
+  V8_INLINE static bool IsTaggedTemplate(const Expression* tag) {
+    return tag != NULL;
+  }
+
  private:
   Parser* parser_;
 };
@@ -644,6 +682,7 @@
   // Handle errors detected during parsing, move statistics to Isolate,
   // internalize strings (move them to the heap).
   void Internalize();
+  void HandleSourceURLComments();
 
  private:
   friend class ParserTraits;
@@ -693,6 +732,13 @@
   ScriptCompiler::CompileOptions compile_options() const {
     return info_->compile_options();
   }
+  bool consume_cached_parse_data() const {
+    return compile_options() == ScriptCompiler::kConsumeParserCache &&
+           cached_parse_data_ != NULL;
+  }
+  bool produce_cached_parse_data() const {
+    return compile_options() == ScriptCompiler::kProduceParserCache;
+  }
   Scope* DeclarationScope(VariableMode mode) {
     return IsLexicalVariableMode(mode)
         ? scope_ : scope_->DeclarationScope();
@@ -775,6 +821,12 @@
       int function_token_position, FunctionLiteral::FunctionType type,
       FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
 
+
+  ClassLiteral* ParseClassLiteral(const AstRawString* name,
+                                  Scanner::Location class_name_location,
+                                  bool name_is_strict_reserved, int pos,
+                                  bool* ok);
+
   // Magical syntax support.
   Expression* ParseV8Intrinsic(bool* ok);
 
@@ -810,6 +862,9 @@
 
   Scope* NewScope(Scope* parent, ScopeType type);
 
+  FunctionLiteral* DefaultConstructor(bool call_super, Scope* scope, int pos,
+                                      int end_pos);
+
   // Skip over a lazy function, either using cached data if we have it, or
   // by parsing the function with PreParser. Consumes the ending }.
   void SkipLazyFunctionBody(const AstRawString* function_name,
@@ -825,10 +880,16 @@
       const AstRawString* function_name, int pos, Variable* fvar,
       Token::Value fvar_init_op, bool is_generator, bool* ok);
 
-  void HandleSourceURLComments();
-
   void ThrowPendingError();
 
+  TemplateLiteralState OpenTemplateLiteral(int pos);
+  void AddTemplateSpan(TemplateLiteralState* state, bool tail);
+  void AddTemplateExpression(TemplateLiteralState* state,
+                             Expression* expression);
+  Expression* CloseTemplateLiteral(TemplateLiteralState* state, int start,
+                                   Expression* tag);
+  uint32_t ComputeTemplateLiteralHash(const TemplateLiteral* lit);
+
   Scanner scanner_;
   PreParser* reusable_preparser_;
   Scope* original_scope_;  // for ES5 function declarations in sloppy eval
@@ -855,8 +916,7 @@
 
 bool ParserTraits::IsFutureStrictReserved(
     const AstRawString* identifier) const {
-  return identifier->IsOneByteEqualTo("yield") ||
-         parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
+  return parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
 }
 
 
@@ -925,6 +985,27 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
 };
 
+
+ParserTraits::TemplateLiteralState ParserTraits::OpenTemplateLiteral(int pos) {
+  return parser_->OpenTemplateLiteral(pos);
+}
+
+
+void ParserTraits::AddTemplateSpan(TemplateLiteralState* state, bool tail) {
+  parser_->AddTemplateSpan(state, tail);
+}
+
+
+void ParserTraits::AddTemplateExpression(TemplateLiteralState* state,
+                                         Expression* expression) {
+  parser_->AddTemplateExpression(state, expression);
+}
+
+
+Expression* ParserTraits::CloseTemplateLiteral(TemplateLiteralState* state,
+                                               int start, Expression* tag) {
+  return parser_->CloseTemplateLiteral(state, start, tag);
+}
 } }  // namespace v8::internal
 
 #endif  // V8_PARSER_H_
diff --git a/src/ppc/assembler-ppc-inl.h b/src/ppc/assembler-ppc-inl.h
new file mode 100644
index 0000000..6779ee3
--- /dev/null
+++ b/src/ppc/assembler-ppc-inl.h
@@ -0,0 +1,593 @@
+// Copyright (c) 1994-2006 Sun Microsystems Inc.
+// 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.
+//
+// - Redistribution 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 Sun Microsystems or the names of 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.
+
+// The original source code covered by the above license above has been modified
+// significantly by Google Inc.
+// Copyright 2014 the V8 project authors. All rights reserved.
+
+#ifndef V8_PPC_ASSEMBLER_PPC_INL_H_
+#define V8_PPC_ASSEMBLER_PPC_INL_H_
+
+#include "src/ppc/assembler-ppc.h"
+
+#include "src/assembler.h"
+#include "src/debug.h"
+
+
+namespace v8 {
+namespace internal {
+
+
+bool CpuFeatures::SupportsCrankshaft() { return true; }
+
+
+void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) {
+#if ABI_USES_FUNCTION_DESCRIPTORS || V8_OOL_CONSTANT_POOL
+  if (RelocInfo::IsInternalReference(rmode_)) {
+    // absolute code pointer inside code object moves with the code object.
+    Assembler::RelocateInternalReference(pc_, delta, 0, icache_flush_mode);
+  }
+#endif
+  // We do not use pc relative addressing on PPC, so there is
+  // nothing else to do.
+}
+
+
+Address RelocInfo::target_address() {
+  DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
+  return Assembler::target_address_at(pc_, host_);
+}
+
+
+Address RelocInfo::target_address_address() {
+  DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_) ||
+         rmode_ == EMBEDDED_OBJECT || rmode_ == EXTERNAL_REFERENCE);
+
+#if V8_OOL_CONSTANT_POOL
+  if (Assembler::IsConstantPoolLoadStart(pc_)) {
+    // We return the PC for ool constant pool since this function is used by the
+    // serializerer and expects the address to reside within the code object.
+    return reinterpret_cast<Address>(pc_);
+  }
+#endif
+
+  // Read the address of the word containing the target_address in an
+  // instruction stream.
+  // The only architecture-independent user of this function is the serializer.
+  // The serializer uses it to find out how many raw bytes of instruction to
+  // output before the next target.
+  // For an instruction like LIS/ORI where the target bits are mixed into the
+  // instruction bits, the size of the target will be zero, indicating that the
+  // serializer should not step forward in memory after a target is resolved
+  // and written.
+  return reinterpret_cast<Address>(pc_);
+}
+
+
+Address RelocInfo::constant_pool_entry_address() {
+#if V8_OOL_CONSTANT_POOL
+  return Assembler::target_constant_pool_address_at(pc_,
+                                                    host_->constant_pool());
+#else
+  UNREACHABLE();
+  return NULL;
+#endif
+}
+
+
+int RelocInfo::target_address_size() { return Assembler::kSpecialTargetSize; }
+
+
+void RelocInfo::set_target_address(Address target,
+                                   WriteBarrierMode write_barrier_mode,
+                                   ICacheFlushMode icache_flush_mode) {
+  DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_));
+  Assembler::set_target_address_at(pc_, host_, target, icache_flush_mode);
+  if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL &&
+      IsCodeTarget(rmode_)) {
+    Object* target_code = Code::GetCodeFromTargetAddress(target);
+    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
+        host(), this, HeapObject::cast(target_code));
+  }
+}
+
+
+Address Assembler::break_address_from_return_address(Address pc) {
+  return target_address_from_return_address(pc);
+}
+
+
+Address Assembler::target_address_from_return_address(Address pc) {
+// Returns the address of the call target from the return address that will
+// be returned to after a call.
+// Call sequence is :
+//  mov   ip, @ call address
+//  mtlr  ip
+//  blrl
+//                      @ return address
+#if V8_OOL_CONSTANT_POOL
+  if (IsConstantPoolLoadEnd(pc - 3 * kInstrSize)) {
+    return pc - (kMovInstructionsConstantPool + 2) * kInstrSize;
+  }
+#endif
+  return pc - (kMovInstructionsNoConstantPool + 2) * kInstrSize;
+}
+
+
+Address Assembler::return_address_from_call_start(Address pc) {
+#if V8_OOL_CONSTANT_POOL
+  Address load_address = pc + (kMovInstructionsConstantPool - 1) * kInstrSize;
+  if (IsConstantPoolLoadEnd(load_address))
+    return pc + (kMovInstructionsConstantPool + 2) * kInstrSize;
+#endif
+  return pc + (kMovInstructionsNoConstantPool + 2) * kInstrSize;
+}
+
+
+Object* RelocInfo::target_object() {
+  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
+  return reinterpret_cast<Object*>(Assembler::target_address_at(pc_, host_));
+}
+
+
+Handle<Object> RelocInfo::target_object_handle(Assembler* origin) {
+  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
+  return Handle<Object>(
+      reinterpret_cast<Object**>(Assembler::target_address_at(pc_, host_)));
+}
+
+
+void RelocInfo::set_target_object(Object* target,
+                                  WriteBarrierMode write_barrier_mode,
+                                  ICacheFlushMode icache_flush_mode) {
+  DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT);
+  Assembler::set_target_address_at(
+      pc_, host_, reinterpret_cast<Address>(target), icache_flush_mode);
+  if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL &&
+      target->IsHeapObject()) {
+    host()->GetHeap()->incremental_marking()->RecordWrite(
+        host(), &Memory::Object_at(pc_), HeapObject::cast(target));
+  }
+}
+
+
+Address RelocInfo::target_reference() {
+  DCHECK(rmode_ == EXTERNAL_REFERENCE);
+  return Assembler::target_address_at(pc_, host_);
+}
+
+
+Address RelocInfo::target_runtime_entry(Assembler* origin) {
+  DCHECK(IsRuntimeEntry(rmode_));
+  return target_address();
+}
+
+
+void RelocInfo::set_target_runtime_entry(Address target,
+                                         WriteBarrierMode write_barrier_mode,
+                                         ICacheFlushMode icache_flush_mode) {
+  DCHECK(IsRuntimeEntry(rmode_));
+  if (target_address() != target)
+    set_target_address(target, write_barrier_mode, icache_flush_mode);
+}
+
+
+Handle<Cell> RelocInfo::target_cell_handle() {
+  DCHECK(rmode_ == RelocInfo::CELL);
+  Address address = Memory::Address_at(pc_);
+  return Handle<Cell>(reinterpret_cast<Cell**>(address));
+}
+
+
+Cell* RelocInfo::target_cell() {
+  DCHECK(rmode_ == RelocInfo::CELL);
+  return Cell::FromValueAddress(Memory::Address_at(pc_));
+}
+
+
+void RelocInfo::set_target_cell(Cell* cell, WriteBarrierMode write_barrier_mode,
+                                ICacheFlushMode icache_flush_mode) {
+  DCHECK(rmode_ == RelocInfo::CELL);
+  Address address = cell->address() + Cell::kValueOffset;
+  Memory::Address_at(pc_) = address;
+  if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) {
+    // TODO(1550) We are passing NULL as a slot because cell can never be on
+    // evacuation candidate.
+    host()->GetHeap()->incremental_marking()->RecordWrite(host(), NULL, cell);
+  }
+}
+
+
+#if V8_OOL_CONSTANT_POOL
+static const int kNoCodeAgeInstructions = 7;
+#else
+static const int kNoCodeAgeInstructions = 6;
+#endif
+static const int kCodeAgingInstructions =
+    Assembler::kMovInstructionsNoConstantPool + 3;
+static const int kNoCodeAgeSequenceInstructions =
+    ((kNoCodeAgeInstructions >= kCodeAgingInstructions)
+         ? kNoCodeAgeInstructions
+         : kCodeAgingInstructions);
+static const int kNoCodeAgeSequenceNops =
+    (kNoCodeAgeSequenceInstructions - kNoCodeAgeInstructions);
+static const int kCodeAgingSequenceNops =
+    (kNoCodeAgeSequenceInstructions - kCodeAgingInstructions);
+static const int kCodeAgingTargetDelta = 1 * Assembler::kInstrSize;
+static const int kNoCodeAgeSequenceLength =
+    (kNoCodeAgeSequenceInstructions * Assembler::kInstrSize);
+
+
+Handle<Object> RelocInfo::code_age_stub_handle(Assembler* origin) {
+  UNREACHABLE();  // This should never be reached on PPC.
+  return Handle<Object>();
+}
+
+
+Code* RelocInfo::code_age_stub() {
+  DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
+  return Code::GetCodeFromTargetAddress(
+      Assembler::target_address_at(pc_ + kCodeAgingTargetDelta, host_));
+}
+
+
+void RelocInfo::set_code_age_stub(Code* stub,
+                                  ICacheFlushMode icache_flush_mode) {
+  DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE);
+  Assembler::set_target_address_at(pc_ + kCodeAgingTargetDelta, host_,
+                                   stub->instruction_start(),
+                                   icache_flush_mode);
+}
+
+
+Address RelocInfo::call_address() {
+  DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
+         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
+  // The pc_ offset of 0 assumes patched return sequence per
+  // BreakLocationIterator::SetDebugBreakAtReturn(), or debug break
+  // slot per BreakLocationIterator::SetDebugBreakAtSlot().
+  return Assembler::target_address_at(pc_, host_);
+}
+
+
+void RelocInfo::set_call_address(Address target) {
+  DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
+         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
+  Assembler::set_target_address_at(pc_, host_, target);
+  if (host() != NULL) {
+    Object* target_code = Code::GetCodeFromTargetAddress(target);
+    host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(
+        host(), this, HeapObject::cast(target_code));
+  }
+}
+
+
+Object* RelocInfo::call_object() { return *call_object_address(); }
+
+
+void RelocInfo::set_call_object(Object* target) {
+  *call_object_address() = target;
+}
+
+
+Object** RelocInfo::call_object_address() {
+  DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) ||
+         (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()));
+  return reinterpret_cast<Object**>(pc_ + 2 * Assembler::kInstrSize);
+}
+
+
+void RelocInfo::WipeOut() {
+  DCHECK(IsEmbeddedObject(rmode_) || IsCodeTarget(rmode_) ||
+         IsRuntimeEntry(rmode_) || IsExternalReference(rmode_));
+  Assembler::set_target_address_at(pc_, host_, NULL);
+}
+
+
+bool RelocInfo::IsPatchedReturnSequence() {
+  //
+  // The patched return sequence is defined by
+  // BreakLocationIterator::SetDebugBreakAtReturn()
+  // FIXED_SEQUENCE
+
+  Instr instr0 = Assembler::instr_at(pc_);
+  Instr instr1 = Assembler::instr_at(pc_ + 1 * Assembler::kInstrSize);
+#if V8_TARGET_ARCH_PPC64
+  Instr instr3 = Assembler::instr_at(pc_ + (3 * Assembler::kInstrSize));
+  Instr instr4 = Assembler::instr_at(pc_ + (4 * Assembler::kInstrSize));
+  Instr binstr = Assembler::instr_at(pc_ + (7 * Assembler::kInstrSize));
+#else
+  Instr binstr = Assembler::instr_at(pc_ + 4 * Assembler::kInstrSize);
+#endif
+  bool patched_return =
+      ((instr0 & kOpcodeMask) == ADDIS && (instr1 & kOpcodeMask) == ORI &&
+#if V8_TARGET_ARCH_PPC64
+       (instr3 & kOpcodeMask) == ORIS && (instr4 & kOpcodeMask) == ORI &&
+#endif
+       (binstr == 0x7d821008));  // twge r2, r2
+
+  // printf("IsPatchedReturnSequence: %d\n", patched_return);
+  return patched_return;
+}
+
+
+bool RelocInfo::IsPatchedDebugBreakSlotSequence() {
+  Instr current_instr = Assembler::instr_at(pc_);
+  return !Assembler::IsNop(current_instr, Assembler::DEBUG_BREAK_NOP);
+}
+
+
+void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) {
+  RelocInfo::Mode mode = rmode();
+  if (mode == RelocInfo::EMBEDDED_OBJECT) {
+    visitor->VisitEmbeddedPointer(this);
+  } else if (RelocInfo::IsCodeTarget(mode)) {
+    visitor->VisitCodeTarget(this);
+  } else if (mode == RelocInfo::CELL) {
+    visitor->VisitCell(this);
+  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
+    visitor->VisitExternalReference(this);
+  } else if (RelocInfo::IsCodeAgeSequence(mode)) {
+    visitor->VisitCodeAgeSequence(this);
+  } else if (((RelocInfo::IsJSReturn(mode) && IsPatchedReturnSequence()) ||
+              (RelocInfo::IsDebugBreakSlot(mode) &&
+               IsPatchedDebugBreakSlotSequence())) &&
+             isolate->debug()->has_break_points()) {
+    visitor->VisitDebugTarget(this);
+  } else if (IsRuntimeEntry(mode)) {
+    visitor->VisitRuntimeEntry(this);
+  }
+}
+
+
+template <typename StaticVisitor>
+void RelocInfo::Visit(Heap* heap) {
+  RelocInfo::Mode mode = rmode();
+  if (mode == RelocInfo::EMBEDDED_OBJECT) {
+    StaticVisitor::VisitEmbeddedPointer(heap, this);
+  } else if (RelocInfo::IsCodeTarget(mode)) {
+    StaticVisitor::VisitCodeTarget(heap, this);
+  } else if (mode == RelocInfo::CELL) {
+    StaticVisitor::VisitCell(heap, this);
+  } else if (mode == RelocInfo::EXTERNAL_REFERENCE) {
+    StaticVisitor::VisitExternalReference(this);
+  } else if (RelocInfo::IsCodeAgeSequence(mode)) {
+    StaticVisitor::VisitCodeAgeSequence(heap, this);
+  } else if (heap->isolate()->debug()->has_break_points() &&
+             ((RelocInfo::IsJSReturn(mode) && IsPatchedReturnSequence()) ||
+              (RelocInfo::IsDebugBreakSlot(mode) &&
+               IsPatchedDebugBreakSlotSequence()))) {
+    StaticVisitor::VisitDebugTarget(heap, this);
+  } else if (IsRuntimeEntry(mode)) {
+    StaticVisitor::VisitRuntimeEntry(this);
+  }
+}
+
+Operand::Operand(intptr_t immediate, RelocInfo::Mode rmode) {
+  rm_ = no_reg;
+  imm_ = immediate;
+  rmode_ = rmode;
+}
+
+Operand::Operand(const ExternalReference& f) {
+  rm_ = no_reg;
+  imm_ = reinterpret_cast<intptr_t>(f.address());
+  rmode_ = RelocInfo::EXTERNAL_REFERENCE;
+}
+
+Operand::Operand(Smi* value) {
+  rm_ = no_reg;
+  imm_ = reinterpret_cast<intptr_t>(value);
+  rmode_ = kRelocInfo_NONEPTR;
+}
+
+Operand::Operand(Register rm) {
+  rm_ = rm;
+  rmode_ = kRelocInfo_NONEPTR;  // PPC -why doesn't ARM do this?
+}
+
+void Assembler::CheckBuffer() {
+  if (buffer_space() <= kGap) {
+    GrowBuffer();
+  }
+}
+
+void Assembler::CheckTrampolinePoolQuick() {
+  if (pc_offset() >= next_buffer_check_) {
+    CheckTrampolinePool();
+  }
+}
+
+void Assembler::emit(Instr x) {
+  CheckBuffer();
+  *reinterpret_cast<Instr*>(pc_) = x;
+  pc_ += kInstrSize;
+  CheckTrampolinePoolQuick();
+}
+
+bool Operand::is_reg() const { return rm_.is_valid(); }
+
+
+// Fetch the 32bit value from the FIXED_SEQUENCE lis/ori
+Address Assembler::target_address_at(Address pc,
+                                     ConstantPoolArray* constant_pool) {
+  Instr instr1 = instr_at(pc);
+  Instr instr2 = instr_at(pc + kInstrSize);
+  // Interpret 2 instructions generated by lis/ori
+  if (IsLis(instr1) && IsOri(instr2)) {
+#if V8_TARGET_ARCH_PPC64
+    Instr instr4 = instr_at(pc + (3 * kInstrSize));
+    Instr instr5 = instr_at(pc + (4 * kInstrSize));
+    // Assemble the 64 bit value.
+    uint64_t hi = (static_cast<uint32_t>((instr1 & kImm16Mask) << 16) |
+                   static_cast<uint32_t>(instr2 & kImm16Mask));
+    uint64_t lo = (static_cast<uint32_t>((instr4 & kImm16Mask) << 16) |
+                   static_cast<uint32_t>(instr5 & kImm16Mask));
+    return reinterpret_cast<Address>((hi << 32) | lo);
+#else
+    // Assemble the 32 bit value.
+    return reinterpret_cast<Address>(((instr1 & kImm16Mask) << 16) |
+                                     (instr2 & kImm16Mask));
+#endif
+  }
+#if V8_OOL_CONSTANT_POOL
+  return Memory::Address_at(target_constant_pool_address_at(pc, constant_pool));
+#else
+  DCHECK(false);
+  return (Address)0;
+#endif
+}
+
+
+#if V8_OOL_CONSTANT_POOL
+bool Assembler::IsConstantPoolLoadStart(Address pc) {
+#if V8_TARGET_ARCH_PPC64
+  if (!IsLi(instr_at(pc))) return false;
+  pc += kInstrSize;
+#endif
+  return GetRA(instr_at(pc)).is(kConstantPoolRegister);
+}
+
+
+bool Assembler::IsConstantPoolLoadEnd(Address pc) {
+#if V8_TARGET_ARCH_PPC64
+  pc -= kInstrSize;
+#endif
+  return IsConstantPoolLoadStart(pc);
+}
+
+
+int Assembler::GetConstantPoolOffset(Address pc) {
+  DCHECK(IsConstantPoolLoadStart(pc));
+  Instr instr = instr_at(pc);
+  int offset = SIGN_EXT_IMM16((instr & kImm16Mask));
+  return offset;
+}
+
+
+void Assembler::SetConstantPoolOffset(Address pc, int offset) {
+  DCHECK(IsConstantPoolLoadStart(pc));
+  DCHECK(is_int16(offset));
+  Instr instr = instr_at(pc);
+  instr &= ~kImm16Mask;
+  instr |= (offset & kImm16Mask);
+  instr_at_put(pc, instr);
+}
+
+
+Address Assembler::target_constant_pool_address_at(
+    Address pc, ConstantPoolArray* constant_pool) {
+  Address addr = reinterpret_cast<Address>(constant_pool);
+  DCHECK(addr);
+  addr += GetConstantPoolOffset(pc);
+  return addr;
+}
+#endif
+
+
+// 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 mov instructions etc.
+// There is a FIXED_SEQUENCE assumption here
+void Assembler::deserialization_set_special_target_at(
+    Address instruction_payload, Code* code, Address target) {
+  set_target_address_at(instruction_payload, code, target);
+}
+
+// This code assumes the FIXED_SEQUENCE of lis/ori
+void Assembler::set_target_address_at(Address pc,
+                                      ConstantPoolArray* constant_pool,
+                                      Address target,
+                                      ICacheFlushMode icache_flush_mode) {
+  Instr instr1 = instr_at(pc);
+  Instr instr2 = instr_at(pc + kInstrSize);
+  // Interpret 2 instructions generated by lis/ori
+  if (IsLis(instr1) && IsOri(instr2)) {
+#if V8_TARGET_ARCH_PPC64
+    Instr instr4 = instr_at(pc + (3 * kInstrSize));
+    Instr instr5 = instr_at(pc + (4 * kInstrSize));
+    // Needs to be fixed up when mov changes to handle 64-bit values.
+    uint32_t* p = reinterpret_cast<uint32_t*>(pc);
+    uintptr_t itarget = reinterpret_cast<uintptr_t>(target);
+
+    instr5 &= ~kImm16Mask;
+    instr5 |= itarget & kImm16Mask;
+    itarget = itarget >> 16;
+
+    instr4 &= ~kImm16Mask;
+    instr4 |= itarget & kImm16Mask;
+    itarget = itarget >> 16;
+
+    instr2 &= ~kImm16Mask;
+    instr2 |= itarget & kImm16Mask;
+    itarget = itarget >> 16;
+
+    instr1 &= ~kImm16Mask;
+    instr1 |= itarget & kImm16Mask;
+    itarget = itarget >> 16;
+
+    *p = instr1;
+    *(p + 1) = instr2;
+    *(p + 3) = instr4;
+    *(p + 4) = instr5;
+    if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
+      CpuFeatures::FlushICache(p, 5 * kInstrSize);
+    }
+#else
+    uint32_t* p = reinterpret_cast<uint32_t*>(pc);
+    uint32_t itarget = reinterpret_cast<uint32_t>(target);
+    int lo_word = itarget & kImm16Mask;
+    int hi_word = itarget >> 16;
+    instr1 &= ~kImm16Mask;
+    instr1 |= hi_word;
+    instr2 &= ~kImm16Mask;
+    instr2 |= lo_word;
+
+    *p = instr1;
+    *(p + 1) = instr2;
+    if (icache_flush_mode != SKIP_ICACHE_FLUSH) {
+      CpuFeatures::FlushICache(p, 2 * kInstrSize);
+    }
+#endif
+  } else {
+#if V8_OOL_CONSTANT_POOL
+    Memory::Address_at(target_constant_pool_address_at(pc, constant_pool)) =
+        target;
+#else
+    UNREACHABLE();
+#endif
+  }
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_PPC_ASSEMBLER_PPC_INL_H_
diff --git a/src/ppc/assembler-ppc.cc b/src/ppc/assembler-ppc.cc
new file mode 100644
index 0000000..4b8b165
--- /dev/null
+++ b/src/ppc/assembler-ppc.cc
@@ -0,0 +1,2493 @@
+// Copyright (c) 1994-2006 Sun Microsystems Inc.
+// 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.
+//
+// - Redistribution 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 Sun Microsystems or the names of 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.
+
+// The original source code covered by the above license above has been
+// modified significantly by Google Inc.
+// Copyright 2014 the V8 project authors. All rights reserved.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/base/bits.h"
+#include "src/base/cpu.h"
+#include "src/macro-assembler.h"
+#include "src/ppc/assembler-ppc-inl.h"
+#include "src/serialize.h"
+
+namespace v8 {
+namespace internal {
+
+// Get the CPU features enabled by the build.
+static unsigned CpuFeaturesImpliedByCompiler() {
+  unsigned answer = 0;
+  return answer;
+}
+
+
+void CpuFeatures::ProbeImpl(bool cross_compile) {
+  supported_ |= CpuFeaturesImpliedByCompiler();
+  cache_line_size_ = 128;
+
+  // Only use statically determined features for cross compile (snapshot).
+  if (cross_compile) return;
+
+// Detect whether frim instruction is supported (POWER5+)
+// For now we will just check for processors we know do not
+// support it
+#ifndef USE_SIMULATOR
+  // Probe for additional features at runtime.
+  base::CPU cpu;
+#if V8_TARGET_ARCH_PPC64
+  if (cpu.part() == base::CPU::PPC_POWER8) {
+    supported_ |= (1u << FPR_GPR_MOV);
+  }
+#endif
+  if (cpu.part() == base::CPU::PPC_POWER6 ||
+      cpu.part() == base::CPU::PPC_POWER7 ||
+      cpu.part() == base::CPU::PPC_POWER8) {
+    supported_ |= (1u << LWSYNC);
+  }
+#if V8_OS_LINUX
+  if (!(cpu.part() == base::CPU::PPC_G5 || cpu.part() == base::CPU::PPC_G4)) {
+    // Assume support
+    supported_ |= (1u << FPU);
+  }
+  if (cpu.cache_line_size() != 0) {
+    cache_line_size_ = cpu.cache_line_size();
+  }
+#elif V8_OS_AIX
+  // Assume support FP support and default cache line size
+  supported_ |= (1u << FPU);
+#endif
+#else  // Simulator
+  supported_ |= (1u << FPU);
+  supported_ |= (1u << LWSYNC);
+#if V8_TARGET_ARCH_PPC64
+  supported_ |= (1u << FPR_GPR_MOV);
+#endif
+#endif
+}
+
+
+void CpuFeatures::PrintTarget() {
+  const char* ppc_arch = NULL;
+
+#if V8_TARGET_ARCH_PPC64
+  ppc_arch = "ppc64";
+#else
+  ppc_arch = "ppc";
+#endif
+
+  printf("target %s\n", ppc_arch);
+}
+
+
+void CpuFeatures::PrintFeatures() {
+  printf("FPU=%d\n", CpuFeatures::IsSupported(FPU));
+}
+
+
+Register ToRegister(int num) {
+  DCHECK(num >= 0 && num < kNumRegisters);
+  const Register kRegisters[] = {r0,  sp,  r2,  r3,  r4,  r5,  r6,  r7,
+                                 r8,  r9,  r10, r11, ip,  r13, r14, r15,
+                                 r16, r17, r18, r19, r20, r21, r22, r23,
+                                 r24, r25, r26, r27, r28, r29, r30, fp};
+  return kRegisters[num];
+}
+
+
+const char* DoubleRegister::AllocationIndexToString(int index) {
+  DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+  const char* const names[] = {
+      "d1",  "d2",  "d3",  "d4",  "d5",  "d6",  "d7",  "d8",  "d9",  "d10",
+      "d11", "d12", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
+      "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
+  return names[index];
+}
+
+
+// -----------------------------------------------------------------------------
+// Implementation of RelocInfo
+
+const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE;
+
+
+bool RelocInfo::IsCodedSpecially() {
+  // The deserializer needs to know whether a pointer is specially
+  // coded.  Being specially coded on PPC means that it is a lis/ori
+  // instruction sequence or is an out of line constant pool entry,
+  // and these are always the case inside code objects.
+  return true;
+}
+
+
+bool RelocInfo::IsInConstantPool() {
+#if V8_OOL_CONSTANT_POOL
+  return Assembler::IsConstantPoolLoadStart(pc_);
+#else
+  return false;
+#endif
+}
+
+
+void RelocInfo::PatchCode(byte* instructions, int instruction_count) {
+  // Patch the code at the current address with the supplied instructions.
+  Instr* pc = reinterpret_cast<Instr*>(pc_);
+  Instr* instr = reinterpret_cast<Instr*>(instructions);
+  for (int i = 0; i < instruction_count; i++) {
+    *(pc + i) = *(instr + i);
+  }
+
+  // Indicate that code has changed.
+  CpuFeatures::FlushICache(pc_, instruction_count * Assembler::kInstrSize);
+}
+
+
+// Patch the code at the current PC with a call to the target address.
+// Additional guard instructions can be added if required.
+void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) {
+  // Patch the code at the current address with a call to the target.
+  UNIMPLEMENTED();
+}
+
+
+// -----------------------------------------------------------------------------
+// Implementation of Operand and MemOperand
+// See assembler-ppc-inl.h for inlined constructors
+
+Operand::Operand(Handle<Object> handle) {
+  AllowDeferredHandleDereference using_raw_address;
+  rm_ = no_reg;
+  // Verify all Objects referred by code are NOT in new space.
+  Object* obj = *handle;
+  if (obj->IsHeapObject()) {
+    DCHECK(!HeapObject::cast(obj)->GetHeap()->InNewSpace(obj));
+    imm_ = reinterpret_cast<intptr_t>(handle.location());
+    rmode_ = RelocInfo::EMBEDDED_OBJECT;
+  } else {
+    // no relocation needed
+    imm_ = reinterpret_cast<intptr_t>(obj);
+    rmode_ = kRelocInfo_NONEPTR;
+  }
+}
+
+
+MemOperand::MemOperand(Register rn, int32_t offset) {
+  ra_ = rn;
+  rb_ = no_reg;
+  offset_ = offset;
+}
+
+
+MemOperand::MemOperand(Register ra, Register rb) {
+  ra_ = ra;
+  rb_ = rb;
+  offset_ = 0;
+}
+
+
+// -----------------------------------------------------------------------------
+// Specific instructions, constants, and masks.
+
+// Spare buffer.
+static const int kMinimalBufferSize = 4 * KB;
+
+
+Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
+    : AssemblerBase(isolate, buffer, buffer_size),
+      recorded_ast_id_(TypeFeedbackId::None()),
+#if V8_OOL_CONSTANT_POOL
+      constant_pool_builder_(),
+#endif
+      positions_recorder_(this) {
+  reloc_info_writer.Reposition(buffer_ + buffer_size_, pc_);
+
+  no_trampoline_pool_before_ = 0;
+  trampoline_pool_blocked_nesting_ = 0;
+  // We leave space (kMaxBlockTrampolineSectionSize)
+  // for BlockTrampolinePoolScope buffer.
+  next_buffer_check_ =
+      FLAG_force_long_branches ? kMaxInt : kMaxCondBranchReach -
+                                               kMaxBlockTrampolineSectionSize;
+  internal_trampoline_exception_ = false;
+  last_bound_pos_ = 0;
+  trampoline_emitted_ = FLAG_force_long_branches;
+  unbound_labels_count_ = 0;
+  ClearRecordedAstId();
+}
+
+
+void Assembler::GetCode(CodeDesc* desc) {
+  // Set up code descriptor.
+  desc->buffer = buffer_;
+  desc->buffer_size = buffer_size_;
+  desc->instr_size = pc_offset();
+  desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
+  desc->origin = this;
+}
+
+
+void Assembler::Align(int m) {
+#if V8_TARGET_ARCH_PPC64
+  DCHECK(m >= 4 && base::bits::IsPowerOfTwo64(m));
+#else
+  DCHECK(m >= 4 && base::bits::IsPowerOfTwo32(m));
+#endif
+  while ((pc_offset() & (m - 1)) != 0) {
+    nop();
+  }
+}
+
+
+void Assembler::CodeTargetAlign() { Align(8); }
+
+
+Condition Assembler::GetCondition(Instr instr) {
+  switch (instr & kCondMask) {
+    case BT:
+      return eq;
+    case BF:
+      return ne;
+    default:
+      UNIMPLEMENTED();
+  }
+  return al;
+}
+
+
+bool Assembler::IsLis(Instr instr) {
+  return ((instr & kOpcodeMask) == ADDIS) && GetRA(instr).is(r0);
+}
+
+
+bool Assembler::IsLi(Instr instr) {
+  return ((instr & kOpcodeMask) == ADDI) && GetRA(instr).is(r0);
+}
+
+
+bool Assembler::IsAddic(Instr instr) { return (instr & kOpcodeMask) == ADDIC; }
+
+
+bool Assembler::IsOri(Instr instr) { return (instr & kOpcodeMask) == ORI; }
+
+
+bool Assembler::IsBranch(Instr instr) { return ((instr & kOpcodeMask) == BCX); }
+
+
+Register Assembler::GetRA(Instr instr) {
+  Register reg;
+  reg.code_ = Instruction::RAValue(instr);
+  return reg;
+}
+
+
+Register Assembler::GetRB(Instr instr) {
+  Register reg;
+  reg.code_ = Instruction::RBValue(instr);
+  return reg;
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+// This code assumes a FIXED_SEQUENCE for 64bit loads (lis/ori)
+bool Assembler::Is64BitLoadIntoR12(Instr instr1, Instr instr2, Instr instr3,
+                                   Instr instr4, Instr instr5) {
+  // Check the instructions are indeed a five part load (into r12)
+  // 3d800000       lis     r12, 0
+  // 618c0000       ori     r12, r12, 0
+  // 798c07c6       rldicr  r12, r12, 32, 31
+  // 658c00c3       oris    r12, r12, 195
+  // 618ccd40       ori     r12, r12, 52544
+  return (((instr1 >> 16) == 0x3d80) && ((instr2 >> 16) == 0x618c) &&
+          (instr3 == 0x798c07c6) && ((instr4 >> 16) == 0x658c) &&
+          ((instr5 >> 16) == 0x618c));
+}
+#else
+// This code assumes a FIXED_SEQUENCE for 32bit loads (lis/ori)
+bool Assembler::Is32BitLoadIntoR12(Instr instr1, Instr instr2) {
+  // Check the instruction is indeed a two part load (into r12)
+  // 3d802553       lis     r12, 9555
+  // 618c5000       ori   r12, r12, 20480
+  return (((instr1 >> 16) == 0x3d80) && ((instr2 >> 16) == 0x618c));
+}
+#endif
+
+
+bool Assembler::IsCmpRegister(Instr instr) {
+  return (((instr & kOpcodeMask) == EXT2) &&
+          ((instr & kExt2OpcodeMask) == CMP));
+}
+
+
+bool Assembler::IsRlwinm(Instr instr) {
+  return ((instr & kOpcodeMask) == RLWINMX);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+bool Assembler::IsRldicl(Instr instr) {
+  return (((instr & kOpcodeMask) == EXT5) &&
+          ((instr & kExt5OpcodeMask) == RLDICL));
+}
+#endif
+
+
+bool Assembler::IsCmpImmediate(Instr instr) {
+  return ((instr & kOpcodeMask) == CMPI);
+}
+
+
+bool Assembler::IsCrSet(Instr instr) {
+  return (((instr & kOpcodeMask) == EXT1) &&
+          ((instr & kExt1OpcodeMask) == CREQV));
+}
+
+
+Register Assembler::GetCmpImmediateRegister(Instr instr) {
+  DCHECK(IsCmpImmediate(instr));
+  return GetRA(instr);
+}
+
+
+int Assembler::GetCmpImmediateRawImmediate(Instr instr) {
+  DCHECK(IsCmpImmediate(instr));
+  return instr & kOff16Mask;
+}
+
+
+// Labels refer to positions in the (to be) generated code.
+// There are bound, linked, and unused labels.
+//
+// Bound labels refer to known positions in the already
+// generated code. pos() is the position the label refers to.
+//
+// Linked labels refer to unknown positions in the code
+// to be generated; pos() is the position of the last
+// instruction using the label.
+
+
+// The link chain is terminated by a negative code position (must be aligned)
+const int kEndOfChain = -4;
+
+
+int Assembler::target_at(int pos) {
+  Instr instr = instr_at(pos);
+  // check which type of branch this is 16 or 26 bit offset
+  int opcode = instr & kOpcodeMask;
+  if (BX == opcode) {
+    int imm26 = ((instr & kImm26Mask) << 6) >> 6;
+    imm26 &= ~(kAAMask | kLKMask);  // discard AA|LK bits if present
+    if (imm26 == 0) return kEndOfChain;
+    return pos + imm26;
+  } else if (BCX == opcode) {
+    int imm16 = SIGN_EXT_IMM16((instr & kImm16Mask));
+    imm16 &= ~(kAAMask | kLKMask);  // discard AA|LK bits if present
+    if (imm16 == 0) return kEndOfChain;
+    return pos + imm16;
+  } else if ((instr & ~kImm26Mask) == 0) {
+    // Emitted link to a label, not part of a branch (regexp PushBacktrack).
+    if (instr == 0) {
+      return kEndOfChain;
+    } else {
+      int32_t imm26 = SIGN_EXT_IMM26(instr);
+      return (imm26 + pos);
+    }
+  }
+
+  PPCPORT_UNIMPLEMENTED();
+  DCHECK(false);
+  return -1;
+}
+
+
+void Assembler::target_at_put(int pos, int target_pos) {
+  Instr instr = instr_at(pos);
+  int opcode = instr & kOpcodeMask;
+
+  // check which type of branch this is 16 or 26 bit offset
+  if (BX == opcode) {
+    int imm26 = target_pos - pos;
+    DCHECK((imm26 & (kAAMask | kLKMask)) == 0);
+    instr &= ((~kImm26Mask) | kAAMask | kLKMask);
+    DCHECK(is_int26(imm26));
+    instr_at_put(pos, instr | (imm26 & kImm26Mask));
+    return;
+  } else if (BCX == opcode) {
+    int imm16 = target_pos - pos;
+    DCHECK((imm16 & (kAAMask | kLKMask)) == 0);
+    instr &= ((~kImm16Mask) | kAAMask | kLKMask);
+    DCHECK(is_int16(imm16));
+    instr_at_put(pos, instr | (imm16 & kImm16Mask));
+    return;
+  } else if ((instr & ~kImm26Mask) == 0) {
+    DCHECK(target_pos == kEndOfChain || target_pos >= 0);
+    // Emitted link to a label, not part of a branch (regexp PushBacktrack).
+    // Load the position of the label relative to the generated code object
+    // pointer in a register.
+
+    Register dst = r3;  // we assume r3 for now
+    DCHECK(IsNop(instr_at(pos + kInstrSize)));
+    uint32_t target = target_pos + (Code::kHeaderSize - kHeapObjectTag);
+    CodePatcher patcher(reinterpret_cast<byte*>(buffer_ + pos), 2,
+                        CodePatcher::DONT_FLUSH);
+    int target_hi = static_cast<int>(target) >> 16;
+    int target_lo = static_cast<int>(target) & 0XFFFF;
+
+    patcher.masm()->lis(dst, Operand(SIGN_EXT_IMM16(target_hi)));
+    patcher.masm()->ori(dst, dst, Operand(target_lo));
+    return;
+  }
+
+  DCHECK(false);
+}
+
+
+int Assembler::max_reach_from(int pos) {
+  Instr instr = instr_at(pos);
+  int opcode = instr & kOpcodeMask;
+
+  // check which type of branch this is 16 or 26 bit offset
+  if (BX == opcode) {
+    return 26;
+  } else if (BCX == opcode) {
+    return 16;
+  } else if ((instr & ~kImm26Mask) == 0) {
+    // Emitted label constant, not part of a branch (regexp PushBacktrack).
+    return 26;
+  }
+
+  DCHECK(false);
+  return 0;
+}
+
+
+void Assembler::bind_to(Label* L, int pos) {
+  DCHECK(0 <= pos && pos <= pc_offset());  // must have a valid binding position
+  int32_t trampoline_pos = kInvalidSlotPos;
+  if (L->is_linked() && !trampoline_emitted_) {
+    unbound_labels_count_--;
+    next_buffer_check_ += kTrampolineSlotsSize;
+  }
+
+  while (L->is_linked()) {
+    int fixup_pos = L->pos();
+    int32_t offset = pos - fixup_pos;
+    int maxReach = max_reach_from(fixup_pos);
+    next(L);  // call next before overwriting link with target at fixup_pos
+    if (is_intn(offset, maxReach) == false) {
+      if (trampoline_pos == kInvalidSlotPos) {
+        trampoline_pos = get_trampoline_entry();
+        CHECK(trampoline_pos != kInvalidSlotPos);
+        target_at_put(trampoline_pos, pos);
+      }
+      target_at_put(fixup_pos, trampoline_pos);
+    } else {
+      target_at_put(fixup_pos, pos);
+    }
+  }
+  L->bind_to(pos);
+
+  // Keep track of the last bound label so we don't eliminate any instructions
+  // before a bound label.
+  if (pos > last_bound_pos_) last_bound_pos_ = pos;
+}
+
+
+void Assembler::bind(Label* L) {
+  DCHECK(!L->is_bound());  // label can only be bound once
+  bind_to(L, pc_offset());
+}
+
+
+void Assembler::next(Label* L) {
+  DCHECK(L->is_linked());
+  int link = target_at(L->pos());
+  if (link == kEndOfChain) {
+    L->Unuse();
+  } else {
+    DCHECK(link >= 0);
+    L->link_to(link);
+  }
+}
+
+
+bool Assembler::is_near(Label* L, Condition cond) {
+  DCHECK(L->is_bound());
+  if (L->is_bound() == false) return false;
+
+  int maxReach = ((cond == al) ? 26 : 16);
+  int offset = L->pos() - pc_offset();
+
+  return is_intn(offset, maxReach);
+}
+
+
+void Assembler::a_form(Instr instr, DoubleRegister frt, DoubleRegister fra,
+                       DoubleRegister frb, RCBit r) {
+  emit(instr | frt.code() * B21 | fra.code() * B16 | frb.code() * B11 | r);
+}
+
+
+void Assembler::d_form(Instr instr, Register rt, Register ra,
+                       const intptr_t val, bool signed_disp) {
+  if (signed_disp) {
+    if (!is_int16(val)) {
+      PrintF("val = %" V8PRIdPTR ", 0x%" V8PRIxPTR "\n", val, val);
+    }
+    DCHECK(is_int16(val));
+  } else {
+    if (!is_uint16(val)) {
+      PrintF("val = %" V8PRIdPTR ", 0x%" V8PRIxPTR
+             ", is_unsigned_imm16(val)=%d, kImm16Mask=0x%x\n",
+             val, val, is_uint16(val), kImm16Mask);
+    }
+    DCHECK(is_uint16(val));
+  }
+  emit(instr | rt.code() * B21 | ra.code() * B16 | (kImm16Mask & val));
+}
+
+
+void Assembler::x_form(Instr instr, Register ra, Register rs, Register rb,
+                       RCBit r) {
+  emit(instr | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 | r);
+}
+
+
+void Assembler::xo_form(Instr instr, Register rt, Register ra, Register rb,
+                        OEBit o, RCBit r) {
+  emit(instr | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 | o | r);
+}
+
+
+void Assembler::md_form(Instr instr, Register ra, Register rs, int shift,
+                        int maskbit, RCBit r) {
+  int sh0_4 = shift & 0x1f;
+  int sh5 = (shift >> 5) & 0x1;
+  int m0_4 = maskbit & 0x1f;
+  int m5 = (maskbit >> 5) & 0x1;
+
+  emit(instr | rs.code() * B21 | ra.code() * B16 | sh0_4 * B11 | m0_4 * B6 |
+       m5 * B5 | sh5 * B1 | r);
+}
+
+
+void Assembler::mds_form(Instr instr, Register ra, Register rs, Register rb,
+                         int maskbit, RCBit r) {
+  int m0_4 = maskbit & 0x1f;
+  int m5 = (maskbit >> 5) & 0x1;
+
+  emit(instr | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 | m0_4 * B6 |
+       m5 * B5 | r);
+}
+
+
+// Returns the next free trampoline entry.
+int32_t Assembler::get_trampoline_entry() {
+  int32_t trampoline_entry = kInvalidSlotPos;
+
+  if (!internal_trampoline_exception_) {
+    trampoline_entry = trampoline_.take_slot();
+
+    if (kInvalidSlotPos == trampoline_entry) {
+      internal_trampoline_exception_ = true;
+    }
+  }
+  return trampoline_entry;
+}
+
+
+int Assembler::branch_offset(Label* L, bool jump_elimination_allowed) {
+  int target_pos;
+  if (L->is_bound()) {
+    target_pos = L->pos();
+  } else {
+    if (L->is_linked()) {
+      target_pos = L->pos();  // L's link
+    } else {
+      // was: target_pos = kEndOfChain;
+      // However, using branch to self to mark the first reference
+      // should avoid most instances of branch offset overflow.  See
+      // target_at() for where this is converted back to kEndOfChain.
+      target_pos = pc_offset();
+      if (!trampoline_emitted_) {
+        unbound_labels_count_++;
+        next_buffer_check_ -= kTrampolineSlotsSize;
+      }
+    }
+    L->link_to(pc_offset());
+  }
+
+  return target_pos - pc_offset();
+}
+
+
+// Branch instructions.
+
+
+void Assembler::bclr(BOfield bo, LKBit lk) {
+  positions_recorder()->WriteRecordedPositions();
+  emit(EXT1 | bo | BCLRX | lk);
+}
+
+
+void Assembler::bcctr(BOfield bo, LKBit lk) {
+  positions_recorder()->WriteRecordedPositions();
+  emit(EXT1 | bo | BCCTRX | lk);
+}
+
+
+// Pseudo op - branch to link register
+void Assembler::blr() { bclr(BA, LeaveLK); }
+
+
+// Pseudo op - branch to count register -- used for "jump"
+void Assembler::bctr() { bcctr(BA, LeaveLK); }
+
+
+void Assembler::bctrl() { bcctr(BA, SetLK); }
+
+
+void Assembler::bc(int branch_offset, BOfield bo, int condition_bit, LKBit lk) {
+  if (lk == SetLK) {
+    positions_recorder()->WriteRecordedPositions();
+  }
+  DCHECK(is_int16(branch_offset));
+  emit(BCX | bo | condition_bit * B16 | (kImm16Mask & branch_offset) | lk);
+}
+
+
+void Assembler::b(int branch_offset, LKBit lk) {
+  if (lk == SetLK) {
+    positions_recorder()->WriteRecordedPositions();
+  }
+  DCHECK((branch_offset & 3) == 0);
+  int imm26 = branch_offset;
+  DCHECK(is_int26(imm26));
+  // todo add AA and LK bits
+  emit(BX | (imm26 & kImm26Mask) | lk);
+}
+
+
+void Assembler::xori(Register dst, Register src, const Operand& imm) {
+  d_form(XORI, src, dst, imm.imm_, false);
+}
+
+
+void Assembler::xoris(Register ra, Register rs, const Operand& imm) {
+  d_form(XORIS, rs, ra, imm.imm_, false);
+}
+
+
+void Assembler::xor_(Register dst, Register src1, Register src2, RCBit rc) {
+  x_form(EXT2 | XORX, dst, src1, src2, rc);
+}
+
+
+void Assembler::cntlzw_(Register ra, Register rs, RCBit rc) {
+  x_form(EXT2 | CNTLZWX, ra, rs, r0, rc);
+}
+
+
+void Assembler::and_(Register ra, Register rs, Register rb, RCBit rc) {
+  x_form(EXT2 | ANDX, ra, rs, rb, rc);
+}
+
+
+void Assembler::rlwinm(Register ra, Register rs, int sh, int mb, int me,
+                       RCBit rc) {
+  sh &= 0x1f;
+  mb &= 0x1f;
+  me &= 0x1f;
+  emit(RLWINMX | rs.code() * B21 | ra.code() * B16 | sh * B11 | mb * B6 |
+       me << 1 | rc);
+}
+
+
+void Assembler::rlwnm(Register ra, Register rs, Register rb, int mb, int me,
+                      RCBit rc) {
+  mb &= 0x1f;
+  me &= 0x1f;
+  emit(RLWNMX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 | mb * B6 |
+       me << 1 | rc);
+}
+
+
+void Assembler::rlwimi(Register ra, Register rs, int sh, int mb, int me,
+                       RCBit rc) {
+  sh &= 0x1f;
+  mb &= 0x1f;
+  me &= 0x1f;
+  emit(RLWIMIX | rs.code() * B21 | ra.code() * B16 | sh * B11 | mb * B6 |
+       me << 1 | rc);
+}
+
+
+void Assembler::slwi(Register dst, Register src, const Operand& val, RCBit rc) {
+  DCHECK((32 > val.imm_) && (val.imm_ >= 0));
+  rlwinm(dst, src, val.imm_, 0, 31 - val.imm_, rc);
+}
+
+
+void Assembler::srwi(Register dst, Register src, const Operand& val, RCBit rc) {
+  DCHECK((32 > val.imm_) && (val.imm_ >= 0));
+  rlwinm(dst, src, 32 - val.imm_, val.imm_, 31, rc);
+}
+
+
+void Assembler::clrrwi(Register dst, Register src, const Operand& val,
+                       RCBit rc) {
+  DCHECK((32 > val.imm_) && (val.imm_ >= 0));
+  rlwinm(dst, src, 0, 0, 31 - val.imm_, rc);
+}
+
+
+void Assembler::clrlwi(Register dst, Register src, const Operand& val,
+                       RCBit rc) {
+  DCHECK((32 > val.imm_) && (val.imm_ >= 0));
+  rlwinm(dst, src, 0, val.imm_, 31, rc);
+}
+
+
+void Assembler::srawi(Register ra, Register rs, int sh, RCBit r) {
+  emit(EXT2 | SRAWIX | rs.code() * B21 | ra.code() * B16 | sh * B11 | r);
+}
+
+
+void Assembler::srw(Register dst, Register src1, Register src2, RCBit r) {
+  x_form(EXT2 | SRWX, dst, src1, src2, r);
+}
+
+
+void Assembler::slw(Register dst, Register src1, Register src2, RCBit r) {
+  x_form(EXT2 | SLWX, dst, src1, src2, r);
+}
+
+
+void Assembler::sraw(Register ra, Register rs, Register rb, RCBit r) {
+  x_form(EXT2 | SRAW, ra, rs, rb, r);
+}
+
+
+void Assembler::rotlw(Register ra, Register rs, Register rb, RCBit r) {
+  rlwnm(ra, rs, rb, 0, 31, r);
+}
+
+
+void Assembler::rotlwi(Register ra, Register rs, int sh, RCBit r) {
+  rlwinm(ra, rs, sh, 0, 31, r);
+}
+
+
+void Assembler::rotrwi(Register ra, Register rs, int sh, RCBit r) {
+  rlwinm(ra, rs, 32 - sh, 0, 31, r);
+}
+
+
+void Assembler::subi(Register dst, Register src, const Operand& imm) {
+  addi(dst, src, Operand(-(imm.imm_)));
+}
+
+void Assembler::addc(Register dst, Register src1, Register src2, OEBit o,
+                     RCBit r) {
+  xo_form(EXT2 | ADDCX, dst, src1, src2, o, r);
+}
+
+
+void Assembler::addze(Register dst, Register src1, OEBit o, RCBit r) {
+  // a special xo_form
+  emit(EXT2 | ADDZEX | dst.code() * B21 | src1.code() * B16 | o | r);
+}
+
+
+void Assembler::sub(Register dst, Register src1, Register src2, OEBit o,
+                    RCBit r) {
+  xo_form(EXT2 | SUBFX, dst, src2, src1, o, r);
+}
+
+
+void Assembler::subfc(Register dst, Register src1, Register src2, OEBit o,
+                      RCBit r) {
+  xo_form(EXT2 | SUBFCX, dst, src2, src1, o, r);
+}
+
+
+void Assembler::subfic(Register dst, Register src, const Operand& imm) {
+  d_form(SUBFIC, dst, src, imm.imm_, true);
+}
+
+
+void Assembler::add(Register dst, Register src1, Register src2, OEBit o,
+                    RCBit r) {
+  xo_form(EXT2 | ADDX, dst, src1, src2, o, r);
+}
+
+
+// Multiply low word
+void Assembler::mullw(Register dst, Register src1, Register src2, OEBit o,
+                      RCBit r) {
+  xo_form(EXT2 | MULLW, dst, src1, src2, o, r);
+}
+
+
+// Multiply hi word
+void Assembler::mulhw(Register dst, Register src1, Register src2, OEBit o,
+                      RCBit r) {
+  xo_form(EXT2 | MULHWX, dst, src1, src2, o, r);
+}
+
+
+// Divide word
+void Assembler::divw(Register dst, Register src1, Register src2, OEBit o,
+                     RCBit r) {
+  xo_form(EXT2 | DIVW, dst, src1, src2, o, r);
+}
+
+
+void Assembler::addi(Register dst, Register src, const Operand& imm) {
+  DCHECK(!src.is(r0));  // use li instead to show intent
+  d_form(ADDI, dst, src, imm.imm_, true);
+}
+
+
+void Assembler::addis(Register dst, Register src, const Operand& imm) {
+  DCHECK(!src.is(r0));  // use lis instead to show intent
+  d_form(ADDIS, dst, src, imm.imm_, true);
+}
+
+
+void Assembler::addic(Register dst, Register src, const Operand& imm) {
+  d_form(ADDIC, dst, src, imm.imm_, true);
+}
+
+
+void Assembler::andi(Register ra, Register rs, const Operand& imm) {
+  d_form(ANDIx, rs, ra, imm.imm_, false);
+}
+
+
+void Assembler::andis(Register ra, Register rs, const Operand& imm) {
+  d_form(ANDISx, rs, ra, imm.imm_, false);
+}
+
+
+void Assembler::nor(Register dst, Register src1, Register src2, RCBit r) {
+  x_form(EXT2 | NORX, dst, src1, src2, r);
+}
+
+
+void Assembler::notx(Register dst, Register src, RCBit r) {
+  x_form(EXT2 | NORX, dst, src, src, r);
+}
+
+
+void Assembler::ori(Register ra, Register rs, const Operand& imm) {
+  d_form(ORI, rs, ra, imm.imm_, false);
+}
+
+
+void Assembler::oris(Register dst, Register src, const Operand& imm) {
+  d_form(ORIS, src, dst, imm.imm_, false);
+}
+
+
+void Assembler::orx(Register dst, Register src1, Register src2, RCBit rc) {
+  x_form(EXT2 | ORX, dst, src1, src2, rc);
+}
+
+
+void Assembler::cmpi(Register src1, const Operand& src2, CRegister cr) {
+  intptr_t imm16 = src2.imm_;
+#if V8_TARGET_ARCH_PPC64
+  int L = 1;
+#else
+  int L = 0;
+#endif
+  DCHECK(is_int16(imm16));
+  DCHECK(cr.code() >= 0 && cr.code() <= 7);
+  imm16 &= kImm16Mask;
+  emit(CMPI | cr.code() * B23 | L * B21 | src1.code() * B16 | imm16);
+}
+
+
+void Assembler::cmpli(Register src1, const Operand& src2, CRegister cr) {
+  uintptr_t uimm16 = src2.imm_;
+#if V8_TARGET_ARCH_PPC64
+  int L = 1;
+#else
+  int L = 0;
+#endif
+  DCHECK(is_uint16(uimm16));
+  DCHECK(cr.code() >= 0 && cr.code() <= 7);
+  uimm16 &= kImm16Mask;
+  emit(CMPLI | cr.code() * B23 | L * B21 | src1.code() * B16 | uimm16);
+}
+
+
+void Assembler::cmp(Register src1, Register src2, CRegister cr) {
+#if V8_TARGET_ARCH_PPC64
+  int L = 1;
+#else
+  int L = 0;
+#endif
+  DCHECK(cr.code() >= 0 && cr.code() <= 7);
+  emit(EXT2 | CMP | cr.code() * B23 | L * B21 | src1.code() * B16 |
+       src2.code() * B11);
+}
+
+
+void Assembler::cmpl(Register src1, Register src2, CRegister cr) {
+#if V8_TARGET_ARCH_PPC64
+  int L = 1;
+#else
+  int L = 0;
+#endif
+  DCHECK(cr.code() >= 0 && cr.code() <= 7);
+  emit(EXT2 | CMPL | cr.code() * B23 | L * B21 | src1.code() * B16 |
+       src2.code() * B11);
+}
+
+
+void Assembler::cmpwi(Register src1, const Operand& src2, CRegister cr) {
+  intptr_t imm16 = src2.imm_;
+  int L = 0;
+  DCHECK(is_int16(imm16));
+  DCHECK(cr.code() >= 0 && cr.code() <= 7);
+  imm16 &= kImm16Mask;
+  emit(CMPI | cr.code() * B23 | L * B21 | src1.code() * B16 | imm16);
+}
+
+
+void Assembler::cmplwi(Register src1, const Operand& src2, CRegister cr) {
+  uintptr_t uimm16 = src2.imm_;
+  int L = 0;
+  DCHECK(is_uint16(uimm16));
+  DCHECK(cr.code() >= 0 && cr.code() <= 7);
+  uimm16 &= kImm16Mask;
+  emit(CMPLI | cr.code() * B23 | L * B21 | src1.code() * B16 | uimm16);
+}
+
+
+void Assembler::cmpw(Register src1, Register src2, CRegister cr) {
+  int L = 0;
+  DCHECK(cr.code() >= 0 && cr.code() <= 7);
+  emit(EXT2 | CMP | cr.code() * B23 | L * B21 | src1.code() * B16 |
+       src2.code() * B11);
+}
+
+
+void Assembler::cmplw(Register src1, Register src2, CRegister cr) {
+  int L = 0;
+  DCHECK(cr.code() >= 0 && cr.code() <= 7);
+  emit(EXT2 | CMPL | cr.code() * B23 | L * B21 | src1.code() * B16 |
+       src2.code() * B11);
+}
+
+
+// Pseudo op - load immediate
+void Assembler::li(Register dst, const Operand& imm) {
+  d_form(ADDI, dst, r0, imm.imm_, true);
+}
+
+
+void Assembler::lis(Register dst, const Operand& imm) {
+  d_form(ADDIS, dst, r0, imm.imm_, true);
+}
+
+
+// Pseudo op - move register
+void Assembler::mr(Register dst, Register src) {
+  // actually or(dst, src, src)
+  orx(dst, src, src);
+}
+
+
+void Assembler::lbz(Register dst, const MemOperand& src) {
+  DCHECK(!src.ra_.is(r0));
+  d_form(LBZ, dst, src.ra(), src.offset(), true);
+}
+
+
+void Assembler::lbzx(Register rt, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | LBZX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::lbzux(Register rt, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | LBZUX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::lhz(Register dst, const MemOperand& src) {
+  DCHECK(!src.ra_.is(r0));
+  d_form(LHZ, dst, src.ra(), src.offset(), true);
+}
+
+
+void Assembler::lhzx(Register rt, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | LHZX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::lhzux(Register rt, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | LHZUX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::lwz(Register dst, const MemOperand& src) {
+  DCHECK(!src.ra_.is(r0));
+  d_form(LWZ, dst, src.ra(), src.offset(), true);
+}
+
+
+void Assembler::lwzu(Register dst, const MemOperand& src) {
+  DCHECK(!src.ra_.is(r0));
+  d_form(LWZU, dst, src.ra(), src.offset(), true);
+}
+
+
+void Assembler::lwzx(Register rt, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | LWZX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::lwzux(Register rt, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | LWZUX | rt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::lwa(Register dst, const MemOperand& src) {
+#if V8_TARGET_ARCH_PPC64
+  int offset = src.offset();
+  DCHECK(!src.ra_.is(r0));
+  DCHECK(!(offset & 3) && is_int16(offset));
+  offset = kImm16Mask & offset;
+  emit(LD | dst.code() * B21 | src.ra().code() * B16 | offset | 2);
+#else
+  lwz(dst, src);
+#endif
+}
+
+
+void Assembler::stb(Register dst, const MemOperand& src) {
+  DCHECK(!src.ra_.is(r0));
+  d_form(STB, dst, src.ra(), src.offset(), true);
+}
+
+
+void Assembler::stbx(Register rs, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | STBX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::stbux(Register rs, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | STBUX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::sth(Register dst, const MemOperand& src) {
+  DCHECK(!src.ra_.is(r0));
+  d_form(STH, dst, src.ra(), src.offset(), true);
+}
+
+
+void Assembler::sthx(Register rs, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | STHX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::sthux(Register rs, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | STHUX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::stw(Register dst, const MemOperand& src) {
+  DCHECK(!src.ra_.is(r0));
+  d_form(STW, dst, src.ra(), src.offset(), true);
+}
+
+
+void Assembler::stwu(Register dst, const MemOperand& src) {
+  DCHECK(!src.ra_.is(r0));
+  d_form(STWU, dst, src.ra(), src.offset(), true);
+}
+
+
+void Assembler::stwx(Register rs, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | STWX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::stwux(Register rs, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | STWUX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::extsb(Register rs, Register ra, RCBit rc) {
+  emit(EXT2 | EXTSB | ra.code() * B21 | rs.code() * B16 | rc);
+}
+
+
+void Assembler::extsh(Register rs, Register ra, RCBit rc) {
+  emit(EXT2 | EXTSH | ra.code() * B21 | rs.code() * B16 | rc);
+}
+
+
+void Assembler::neg(Register rt, Register ra, OEBit o, RCBit r) {
+  emit(EXT2 | NEGX | rt.code() * B21 | ra.code() * B16 | o | r);
+}
+
+
+void Assembler::andc(Register dst, Register src1, Register src2, RCBit rc) {
+  x_form(EXT2 | ANDCX, dst, src1, src2, rc);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+// 64bit specific instructions
+void Assembler::ld(Register rd, const MemOperand& src) {
+  int offset = src.offset();
+  DCHECK(!src.ra_.is(r0));
+  DCHECK(!(offset & 3) && is_int16(offset));
+  offset = kImm16Mask & offset;
+  emit(LD | rd.code() * B21 | src.ra().code() * B16 | offset);
+}
+
+
+void Assembler::ldx(Register rd, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | LDX | rd.code() * B21 | ra.code() * B16 | rb.code() * B11);
+}
+
+
+void Assembler::ldu(Register rd, const MemOperand& src) {
+  int offset = src.offset();
+  DCHECK(!src.ra_.is(r0));
+  DCHECK(!(offset & 3) && is_int16(offset));
+  offset = kImm16Mask & offset;
+  emit(LD | rd.code() * B21 | src.ra().code() * B16 | offset | 1);
+}
+
+
+void Assembler::ldux(Register rd, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | LDUX | rd.code() * B21 | ra.code() * B16 | rb.code() * B11);
+}
+
+
+void Assembler::std(Register rs, const MemOperand& src) {
+  int offset = src.offset();
+  DCHECK(!src.ra_.is(r0));
+  DCHECK(!(offset & 3) && is_int16(offset));
+  offset = kImm16Mask & offset;
+  emit(STD | rs.code() * B21 | src.ra().code() * B16 | offset);
+}
+
+
+void Assembler::stdx(Register rs, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | STDX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11);
+}
+
+
+void Assembler::stdu(Register rs, const MemOperand& src) {
+  int offset = src.offset();
+  DCHECK(!src.ra_.is(r0));
+  DCHECK(!(offset & 3) && is_int16(offset));
+  offset = kImm16Mask & offset;
+  emit(STD | rs.code() * B21 | src.ra().code() * B16 | offset | 1);
+}
+
+
+void Assembler::stdux(Register rs, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | STDUX | rs.code() * B21 | ra.code() * B16 | rb.code() * B11);
+}
+
+
+void Assembler::rldic(Register ra, Register rs, int sh, int mb, RCBit r) {
+  md_form(EXT5 | RLDIC, ra, rs, sh, mb, r);
+}
+
+
+void Assembler::rldicl(Register ra, Register rs, int sh, int mb, RCBit r) {
+  md_form(EXT5 | RLDICL, ra, rs, sh, mb, r);
+}
+
+
+void Assembler::rldcl(Register ra, Register rs, Register rb, int mb, RCBit r) {
+  mds_form(EXT5 | RLDCL, ra, rs, rb, mb, r);
+}
+
+
+void Assembler::rldicr(Register ra, Register rs, int sh, int me, RCBit r) {
+  md_form(EXT5 | RLDICR, ra, rs, sh, me, r);
+}
+
+
+void Assembler::sldi(Register dst, Register src, const Operand& val, RCBit rc) {
+  DCHECK((64 > val.imm_) && (val.imm_ >= 0));
+  rldicr(dst, src, val.imm_, 63 - val.imm_, rc);
+}
+
+
+void Assembler::srdi(Register dst, Register src, const Operand& val, RCBit rc) {
+  DCHECK((64 > val.imm_) && (val.imm_ >= 0));
+  rldicl(dst, src, 64 - val.imm_, val.imm_, rc);
+}
+
+
+void Assembler::clrrdi(Register dst, Register src, const Operand& val,
+                       RCBit rc) {
+  DCHECK((64 > val.imm_) && (val.imm_ >= 0));
+  rldicr(dst, src, 0, 63 - val.imm_, rc);
+}
+
+
+void Assembler::clrldi(Register dst, Register src, const Operand& val,
+                       RCBit rc) {
+  DCHECK((64 > val.imm_) && (val.imm_ >= 0));
+  rldicl(dst, src, 0, val.imm_, rc);
+}
+
+
+void Assembler::rldimi(Register ra, Register rs, int sh, int mb, RCBit r) {
+  md_form(EXT5 | RLDIMI, ra, rs, sh, mb, r);
+}
+
+
+void Assembler::sradi(Register ra, Register rs, int sh, RCBit r) {
+  int sh0_4 = sh & 0x1f;
+  int sh5 = (sh >> 5) & 0x1;
+
+  emit(EXT2 | SRADIX | rs.code() * B21 | ra.code() * B16 | sh0_4 * B11 |
+       sh5 * B1 | r);
+}
+
+
+void Assembler::srd(Register dst, Register src1, Register src2, RCBit r) {
+  x_form(EXT2 | SRDX, dst, src1, src2, r);
+}
+
+
+void Assembler::sld(Register dst, Register src1, Register src2, RCBit r) {
+  x_form(EXT2 | SLDX, dst, src1, src2, r);
+}
+
+
+void Assembler::srad(Register ra, Register rs, Register rb, RCBit r) {
+  x_form(EXT2 | SRAD, ra, rs, rb, r);
+}
+
+
+void Assembler::rotld(Register ra, Register rs, Register rb, RCBit r) {
+  rldcl(ra, rs, rb, 0, r);
+}
+
+
+void Assembler::rotldi(Register ra, Register rs, int sh, RCBit r) {
+  rldicl(ra, rs, sh, 0, r);
+}
+
+
+void Assembler::rotrdi(Register ra, Register rs, int sh, RCBit r) {
+  rldicl(ra, rs, 64 - sh, 0, r);
+}
+
+
+void Assembler::cntlzd_(Register ra, Register rs, RCBit rc) {
+  x_form(EXT2 | CNTLZDX, ra, rs, r0, rc);
+}
+
+
+void Assembler::extsw(Register rs, Register ra, RCBit rc) {
+  emit(EXT2 | EXTSW | ra.code() * B21 | rs.code() * B16 | rc);
+}
+
+
+void Assembler::mulld(Register dst, Register src1, Register src2, OEBit o,
+                      RCBit r) {
+  xo_form(EXT2 | MULLD, dst, src1, src2, o, r);
+}
+
+
+void Assembler::divd(Register dst, Register src1, Register src2, OEBit o,
+                     RCBit r) {
+  xo_form(EXT2 | DIVD, dst, src1, src2, o, r);
+}
+#endif
+
+
+void Assembler::fake_asm(enum FAKE_OPCODE_T fopcode) {
+  DCHECK(fopcode < fLastFaker);
+  emit(FAKE_OPCODE | FAKER_SUBOPCODE | fopcode);
+}
+
+
+void Assembler::marker_asm(int mcode) {
+  if (::v8::internal::FLAG_trace_sim_stubs) {
+    DCHECK(mcode < F_NEXT_AVAILABLE_STUB_MARKER);
+    emit(FAKE_OPCODE | MARKER_SUBOPCODE | mcode);
+  }
+}
+
+
+// Function descriptor for AIX.
+// Code address skips the function descriptor "header".
+// TOC and static chain are ignored and set to 0.
+void Assembler::function_descriptor() {
+  DCHECK(pc_offset() == 0);
+  RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
+  emit_ptr(reinterpret_cast<uintptr_t>(pc_) + 3 * kPointerSize);
+  emit_ptr(0);
+  emit_ptr(0);
+}
+
+
+#if ABI_USES_FUNCTION_DESCRIPTORS || V8_OOL_CONSTANT_POOL
+void Assembler::RelocateInternalReference(Address pc, intptr_t delta,
+                                          Address code_start,
+                                          ICacheFlushMode icache_flush_mode) {
+  DCHECK(delta || code_start);
+#if ABI_USES_FUNCTION_DESCRIPTORS
+  uintptr_t* fd = reinterpret_cast<uintptr_t*>(pc);
+  if (fd[1] == 0 && fd[2] == 0) {
+    // Function descriptor
+    if (delta) {
+      fd[0] += delta;
+    } else {
+      fd[0] = reinterpret_cast<uintptr_t>(code_start) + 3 * kPointerSize;
+    }
+    return;
+  }
+#endif
+#if V8_OOL_CONSTANT_POOL
+  // mov for LoadConstantPoolPointerRegister
+  ConstantPoolArray* constant_pool = NULL;
+  if (delta) {
+    code_start = target_address_at(pc, constant_pool) + delta;
+  }
+  set_target_address_at(pc, constant_pool, code_start, icache_flush_mode);
+#endif
+}
+
+
+int Assembler::DecodeInternalReference(Vector<char> buffer, Address pc) {
+#if ABI_USES_FUNCTION_DESCRIPTORS
+  uintptr_t* fd = reinterpret_cast<uintptr_t*>(pc);
+  if (fd[1] == 0 && fd[2] == 0) {
+    // Function descriptor
+    SNPrintF(buffer, "[%08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR
+                     "]"
+                     "   function descriptor",
+             fd[0], fd[1], fd[2]);
+    return kPointerSize * 3;
+  }
+#endif
+  return 0;
+}
+#endif
+
+
+int Assembler::instructions_required_for_mov(const Operand& x) const {
+#if V8_OOL_CONSTANT_POOL || DEBUG
+  bool canOptimize =
+      !(x.must_output_reloc_info(this) || is_trampoline_pool_blocked());
+#endif
+#if V8_OOL_CONSTANT_POOL
+  if (use_constant_pool_for_mov(x, canOptimize)) {
+    // Current usage guarantees that all constant pool references can
+    // use the same sequence.
+    return kMovInstructionsConstantPool;
+  }
+#endif
+  DCHECK(!canOptimize);
+  return kMovInstructionsNoConstantPool;
+}
+
+
+#if V8_OOL_CONSTANT_POOL
+bool Assembler::use_constant_pool_for_mov(const Operand& x,
+                                          bool canOptimize) const {
+  if (!is_ool_constant_pool_available() || is_constant_pool_full()) {
+    // If there is no constant pool available, we must use a mov
+    // immediate sequence.
+    return false;
+  }
+
+  intptr_t value = x.immediate();
+  if (canOptimize && is_int16(value)) {
+    // Prefer a single-instruction load-immediate.
+    return false;
+  }
+
+  return true;
+}
+
+
+void Assembler::EnsureSpaceFor(int space_needed) {
+  if (buffer_space() <= (kGap + space_needed)) {
+    GrowBuffer();
+  }
+}
+#endif
+
+
+bool Operand::must_output_reloc_info(const Assembler* assembler) const {
+  if (rmode_ == RelocInfo::EXTERNAL_REFERENCE) {
+    if (assembler != NULL && assembler->predictable_code_size()) return true;
+    return assembler->serializer_enabled();
+  } else if (RelocInfo::IsNone(rmode_)) {
+    return false;
+  }
+  return true;
+}
+
+
+// Primarily used for loading constants
+// This should really move to be in macro-assembler as it
+// is really a pseudo instruction
+// Some usages of this intend for a FIXED_SEQUENCE to be used
+// Todo - break this dependency so we can optimize mov() in general
+// and only use the generic version when we require a fixed sequence
+void Assembler::mov(Register dst, const Operand& src) {
+  intptr_t value = src.immediate();
+  bool canOptimize;
+  RelocInfo rinfo(pc_, src.rmode_, value, NULL);
+
+  if (src.must_output_reloc_info(this)) {
+    RecordRelocInfo(rinfo);
+  }
+
+  canOptimize =
+      !(src.must_output_reloc_info(this) || is_trampoline_pool_blocked());
+
+#if V8_OOL_CONSTANT_POOL
+  if (use_constant_pool_for_mov(src, canOptimize)) {
+    DCHECK(is_ool_constant_pool_available());
+    ConstantPoolAddEntry(rinfo);
+#if V8_TARGET_ARCH_PPC64
+    BlockTrampolinePoolScope block_trampoline_pool(this);
+    // We are forced to use 2 instruction sequence since the constant
+    // pool pointer is tagged.
+    li(dst, Operand::Zero());
+    ldx(dst, MemOperand(kConstantPoolRegister, dst));
+#else
+    lwz(dst, MemOperand(kConstantPoolRegister, 0));
+#endif
+    return;
+  }
+#endif
+
+  if (canOptimize) {
+    if (is_int16(value)) {
+      li(dst, Operand(value));
+    } else {
+      uint16_t u16;
+#if V8_TARGET_ARCH_PPC64
+      if (is_int32(value)) {
+#endif
+        lis(dst, Operand(value >> 16));
+#if V8_TARGET_ARCH_PPC64
+      } else {
+        if (is_int48(value)) {
+          li(dst, Operand(value >> 32));
+        } else {
+          lis(dst, Operand(value >> 48));
+          u16 = ((value >> 32) & 0xffff);
+          if (u16) {
+            ori(dst, dst, Operand(u16));
+          }
+        }
+        sldi(dst, dst, Operand(32));
+        u16 = ((value >> 16) & 0xffff);
+        if (u16) {
+          oris(dst, dst, Operand(u16));
+        }
+      }
+#endif
+      u16 = (value & 0xffff);
+      if (u16) {
+        ori(dst, dst, Operand(u16));
+      }
+    }
+    return;
+  }
+
+  DCHECK(!canOptimize);
+
+  {
+    BlockTrampolinePoolScope block_trampoline_pool(this);
+#if V8_TARGET_ARCH_PPC64
+    int32_t hi_32 = static_cast<int32_t>(value >> 32);
+    int32_t lo_32 = static_cast<int32_t>(value);
+    int hi_word = static_cast<int>(hi_32 >> 16);
+    int lo_word = static_cast<int>(hi_32 & 0xffff);
+    lis(dst, Operand(SIGN_EXT_IMM16(hi_word)));
+    ori(dst, dst, Operand(lo_word));
+    sldi(dst, dst, Operand(32));
+    hi_word = static_cast<int>(((lo_32 >> 16) & 0xffff));
+    lo_word = static_cast<int>(lo_32 & 0xffff);
+    oris(dst, dst, Operand(hi_word));
+    ori(dst, dst, Operand(lo_word));
+#else
+    int hi_word = static_cast<int>(value >> 16);
+    int lo_word = static_cast<int>(value & 0xffff);
+    lis(dst, Operand(SIGN_EXT_IMM16(hi_word)));
+    ori(dst, dst, Operand(lo_word));
+#endif
+  }
+}
+
+
+void Assembler::mov_label_offset(Register dst, Label* label) {
+  if (label->is_bound()) {
+    int target = label->pos();
+    mov(dst, Operand(target + Code::kHeaderSize - kHeapObjectTag));
+  } else {
+    bool is_linked = label->is_linked();
+    // Emit the link to the label in the code stream followed by extra
+    // nop instructions.
+    DCHECK(dst.is(r3));  // target_at_put assumes r3 for now
+    int link = is_linked ? label->pos() - pc_offset() : 0;
+    label->link_to(pc_offset());
+
+    if (!is_linked && !trampoline_emitted_) {
+      unbound_labels_count_++;
+      next_buffer_check_ -= kTrampolineSlotsSize;
+    }
+
+    // When the label is bound, these instructions will be patched
+    // with a 2 instruction mov sequence that will load the
+    // destination register with the position of the label from the
+    // beginning of the code.
+    //
+    // When the label gets bound: target_at extracts the link and
+    // target_at_put patches the instructions.
+    BlockTrampolinePoolScope block_trampoline_pool(this);
+    emit(link);
+    nop();
+  }
+}
+
+
+// Special register instructions
+void Assembler::crxor(int bt, int ba, int bb) {
+  emit(EXT1 | CRXOR | bt * B21 | ba * B16 | bb * B11);
+}
+
+
+void Assembler::creqv(int bt, int ba, int bb) {
+  emit(EXT1 | CREQV | bt * B21 | ba * B16 | bb * B11);
+}
+
+
+void Assembler::mflr(Register dst) {
+  emit(EXT2 | MFSPR | dst.code() * B21 | 256 << 11);  // Ignore RC bit
+}
+
+
+void Assembler::mtlr(Register src) {
+  emit(EXT2 | MTSPR | src.code() * B21 | 256 << 11);  // Ignore RC bit
+}
+
+
+void Assembler::mtctr(Register src) {
+  emit(EXT2 | MTSPR | src.code() * B21 | 288 << 11);  // Ignore RC bit
+}
+
+
+void Assembler::mtxer(Register src) {
+  emit(EXT2 | MTSPR | src.code() * B21 | 32 << 11);
+}
+
+
+void Assembler::mcrfs(int bf, int bfa) {
+  emit(EXT4 | MCRFS | bf * B23 | bfa * B18);
+}
+
+
+void Assembler::mfcr(Register dst) { emit(EXT2 | MFCR | dst.code() * B21); }
+
+
+#if V8_TARGET_ARCH_PPC64
+void Assembler::mffprd(Register dst, DoubleRegister src) {
+  emit(EXT2 | MFVSRD | src.code() * B21 | dst.code() * B16);
+}
+
+
+void Assembler::mffprwz(Register dst, DoubleRegister src) {
+  emit(EXT2 | MFVSRWZ | src.code() * B21 | dst.code() * B16);
+}
+
+
+void Assembler::mtfprd(DoubleRegister dst, Register src) {
+  emit(EXT2 | MTVSRD | dst.code() * B21 | src.code() * B16);
+}
+
+
+void Assembler::mtfprwz(DoubleRegister dst, Register src) {
+  emit(EXT2 | MTVSRWZ | dst.code() * B21 | src.code() * B16);
+}
+
+
+void Assembler::mtfprwa(DoubleRegister dst, Register src) {
+  emit(EXT2 | MTVSRWA | dst.code() * B21 | src.code() * B16);
+}
+#endif
+
+
+// Exception-generating instructions and debugging support.
+// Stops with a non-negative code less than kNumOfWatchedStops support
+// enabling/disabling and a counter feature. See simulator-ppc.h .
+void Assembler::stop(const char* msg, Condition cond, int32_t code,
+                     CRegister cr) {
+  if (cond != al) {
+    Label skip;
+    b(NegateCondition(cond), &skip, cr);
+    bkpt(0);
+    bind(&skip);
+  } else {
+    bkpt(0);
+  }
+}
+
+
+void Assembler::bkpt(uint32_t imm16) { emit(0x7d821008); }
+
+
+void Assembler::info(const char* msg, Condition cond, int32_t code,
+                     CRegister cr) {
+  if (::v8::internal::FLAG_trace_sim_stubs) {
+    emit(0x7d9ff808);
+#if V8_TARGET_ARCH_PPC64
+    uint64_t value = reinterpret_cast<uint64_t>(msg);
+    emit(static_cast<uint32_t>(value >> 32));
+    emit(static_cast<uint32_t>(value & 0xFFFFFFFF));
+#else
+    emit(reinterpret_cast<Instr>(msg));
+#endif
+  }
+}
+
+
+void Assembler::dcbf(Register ra, Register rb) {
+  emit(EXT2 | DCBF | ra.code() * B16 | rb.code() * B11);
+}
+
+
+void Assembler::sync() { emit(EXT2 | SYNC); }
+
+
+void Assembler::lwsync() { emit(EXT2 | SYNC | 1 * B21); }
+
+
+void Assembler::icbi(Register ra, Register rb) {
+  emit(EXT2 | ICBI | ra.code() * B16 | rb.code() * B11);
+}
+
+
+void Assembler::isync() { emit(EXT1 | ISYNC); }
+
+
+// Floating point support
+
+void Assembler::lfd(const DoubleRegister frt, const MemOperand& src) {
+  int offset = src.offset();
+  Register ra = src.ra();
+  DCHECK(is_int16(offset));
+  int imm16 = offset & kImm16Mask;
+  // could be x_form instruction with some casting magic
+  emit(LFD | frt.code() * B21 | ra.code() * B16 | imm16);
+}
+
+
+void Assembler::lfdu(const DoubleRegister frt, const MemOperand& src) {
+  int offset = src.offset();
+  Register ra = src.ra();
+  DCHECK(is_int16(offset));
+  int imm16 = offset & kImm16Mask;
+  // could be x_form instruction with some casting magic
+  emit(LFDU | frt.code() * B21 | ra.code() * B16 | imm16);
+}
+
+
+void Assembler::lfdx(const DoubleRegister frt, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | LFDX | frt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::lfdux(const DoubleRegister frt, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | LFDUX | frt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::lfs(const DoubleRegister frt, const MemOperand& src) {
+  int offset = src.offset();
+  Register ra = src.ra();
+  DCHECK(is_int16(offset));
+  DCHECK(!ra.is(r0));
+  int imm16 = offset & kImm16Mask;
+  // could be x_form instruction with some casting magic
+  emit(LFS | frt.code() * B21 | ra.code() * B16 | imm16);
+}
+
+
+void Assembler::lfsu(const DoubleRegister frt, const MemOperand& src) {
+  int offset = src.offset();
+  Register ra = src.ra();
+  DCHECK(is_int16(offset));
+  DCHECK(!ra.is(r0));
+  int imm16 = offset & kImm16Mask;
+  // could be x_form instruction with some casting magic
+  emit(LFSU | frt.code() * B21 | ra.code() * B16 | imm16);
+}
+
+
+void Assembler::lfsx(const DoubleRegister frt, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | LFSX | frt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::lfsux(const DoubleRegister frt, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | LFSUX | frt.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::stfd(const DoubleRegister frs, const MemOperand& src) {
+  int offset = src.offset();
+  Register ra = src.ra();
+  DCHECK(is_int16(offset));
+  DCHECK(!ra.is(r0));
+  int imm16 = offset & kImm16Mask;
+  // could be x_form instruction with some casting magic
+  emit(STFD | frs.code() * B21 | ra.code() * B16 | imm16);
+}
+
+
+void Assembler::stfdu(const DoubleRegister frs, const MemOperand& src) {
+  int offset = src.offset();
+  Register ra = src.ra();
+  DCHECK(is_int16(offset));
+  DCHECK(!ra.is(r0));
+  int imm16 = offset & kImm16Mask;
+  // could be x_form instruction with some casting magic
+  emit(STFDU | frs.code() * B21 | ra.code() * B16 | imm16);
+}
+
+
+void Assembler::stfdx(const DoubleRegister frs, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | STFDX | frs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::stfdux(const DoubleRegister frs, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | STFDUX | frs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::stfs(const DoubleRegister frs, const MemOperand& src) {
+  int offset = src.offset();
+  Register ra = src.ra();
+  DCHECK(is_int16(offset));
+  DCHECK(!ra.is(r0));
+  int imm16 = offset & kImm16Mask;
+  // could be x_form instruction with some casting magic
+  emit(STFS | frs.code() * B21 | ra.code() * B16 | imm16);
+}
+
+
+void Assembler::stfsu(const DoubleRegister frs, const MemOperand& src) {
+  int offset = src.offset();
+  Register ra = src.ra();
+  DCHECK(is_int16(offset));
+  DCHECK(!ra.is(r0));
+  int imm16 = offset & kImm16Mask;
+  // could be x_form instruction with some casting magic
+  emit(STFSU | frs.code() * B21 | ra.code() * B16 | imm16);
+}
+
+
+void Assembler::stfsx(const DoubleRegister frs, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | STFSX | frs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::stfsux(const DoubleRegister frs, const MemOperand& src) {
+  Register ra = src.ra();
+  Register rb = src.rb();
+  DCHECK(!ra.is(r0));
+  emit(EXT2 | STFSUX | frs.code() * B21 | ra.code() * B16 | rb.code() * B11 |
+       LeaveRC);
+}
+
+
+void Assembler::fsub(const DoubleRegister frt, const DoubleRegister fra,
+                     const DoubleRegister frb, RCBit rc) {
+  a_form(EXT4 | FSUB, frt, fra, frb, rc);
+}
+
+
+void Assembler::fadd(const DoubleRegister frt, const DoubleRegister fra,
+                     const DoubleRegister frb, RCBit rc) {
+  a_form(EXT4 | FADD, frt, fra, frb, rc);
+}
+
+
+void Assembler::fmul(const DoubleRegister frt, const DoubleRegister fra,
+                     const DoubleRegister frc, RCBit rc) {
+  emit(EXT4 | FMUL | frt.code() * B21 | fra.code() * B16 | frc.code() * B6 |
+       rc);
+}
+
+
+void Assembler::fdiv(const DoubleRegister frt, const DoubleRegister fra,
+                     const DoubleRegister frb, RCBit rc) {
+  a_form(EXT4 | FDIV, frt, fra, frb, rc);
+}
+
+
+void Assembler::fcmpu(const DoubleRegister fra, const DoubleRegister frb,
+                      CRegister cr) {
+  DCHECK(cr.code() >= 0 && cr.code() <= 7);
+  emit(EXT4 | FCMPU | cr.code() * B23 | fra.code() * B16 | frb.code() * B11);
+}
+
+
+void Assembler::fmr(const DoubleRegister frt, const DoubleRegister frb,
+                    RCBit rc) {
+  emit(EXT4 | FMR | frt.code() * B21 | frb.code() * B11 | rc);
+}
+
+
+void Assembler::fctiwz(const DoubleRegister frt, const DoubleRegister frb) {
+  emit(EXT4 | FCTIWZ | frt.code() * B21 | frb.code() * B11);
+}
+
+
+void Assembler::fctiw(const DoubleRegister frt, const DoubleRegister frb) {
+  emit(EXT4 | FCTIW | frt.code() * B21 | frb.code() * B11);
+}
+
+
+void Assembler::frim(const DoubleRegister frt, const DoubleRegister frb) {
+  emit(EXT4 | FRIM | frt.code() * B21 | frb.code() * B11);
+}
+
+
+void Assembler::frsp(const DoubleRegister frt, const DoubleRegister frb,
+                     RCBit rc) {
+  emit(EXT4 | FRSP | frt.code() * B21 | frb.code() * B11 | rc);
+}
+
+
+void Assembler::fcfid(const DoubleRegister frt, const DoubleRegister frb,
+                      RCBit rc) {
+  emit(EXT4 | FCFID | frt.code() * B21 | frb.code() * B11 | rc);
+}
+
+
+void Assembler::fctid(const DoubleRegister frt, const DoubleRegister frb,
+                      RCBit rc) {
+  emit(EXT4 | FCTID | frt.code() * B21 | frb.code() * B11 | rc);
+}
+
+
+void Assembler::fctidz(const DoubleRegister frt, const DoubleRegister frb,
+                       RCBit rc) {
+  emit(EXT4 | FCTIDZ | frt.code() * B21 | frb.code() * B11 | rc);
+}
+
+
+void Assembler::fsel(const DoubleRegister frt, const DoubleRegister fra,
+                     const DoubleRegister frc, const DoubleRegister frb,
+                     RCBit rc) {
+  emit(EXT4 | FSEL | frt.code() * B21 | fra.code() * B16 | frb.code() * B11 |
+       frc.code() * B6 | rc);
+}
+
+
+void Assembler::fneg(const DoubleRegister frt, const DoubleRegister frb,
+                     RCBit rc) {
+  emit(EXT4 | FNEG | frt.code() * B21 | frb.code() * B11 | rc);
+}
+
+
+void Assembler::mtfsfi(int bf, int immediate, RCBit rc) {
+  emit(EXT4 | MTFSFI | bf * B23 | immediate * B12 | rc);
+}
+
+
+void Assembler::mffs(const DoubleRegister frt, RCBit rc) {
+  emit(EXT4 | MFFS | frt.code() * B21 | rc);
+}
+
+
+void Assembler::mtfsf(const DoubleRegister frb, bool L, int FLM, bool W,
+                      RCBit rc) {
+  emit(EXT4 | MTFSF | frb.code() * B11 | W * B16 | FLM * B17 | L * B25 | rc);
+}
+
+
+void Assembler::fsqrt(const DoubleRegister frt, const DoubleRegister frb,
+                      RCBit rc) {
+  emit(EXT4 | FSQRT | frt.code() * B21 | frb.code() * B11 | rc);
+}
+
+
+void Assembler::fabs(const DoubleRegister frt, const DoubleRegister frb,
+                     RCBit rc) {
+  emit(EXT4 | FABS | frt.code() * B21 | frb.code() * B11 | rc);
+}
+
+
+void Assembler::fmadd(const DoubleRegister frt, const DoubleRegister fra,
+                      const DoubleRegister frc, const DoubleRegister frb,
+                      RCBit rc) {
+  emit(EXT4 | FMADD | frt.code() * B21 | fra.code() * B16 | frb.code() * B11 |
+       frc.code() * B6 | rc);
+}
+
+
+void Assembler::fmsub(const DoubleRegister frt, const DoubleRegister fra,
+                      const DoubleRegister frc, const DoubleRegister frb,
+                      RCBit rc) {
+  emit(EXT4 | FMSUB | frt.code() * B21 | fra.code() * B16 | frb.code() * B11 |
+       frc.code() * B6 | rc);
+}
+
+
+// Pseudo instructions.
+void Assembler::nop(int type) {
+  Register reg = r0;
+  switch (type) {
+    case NON_MARKING_NOP:
+      reg = r0;
+      break;
+    case GROUP_ENDING_NOP:
+      reg = r2;
+      break;
+    case DEBUG_BREAK_NOP:
+      reg = r3;
+      break;
+    default:
+      UNIMPLEMENTED();
+  }
+
+  ori(reg, reg, Operand::Zero());
+}
+
+
+bool Assembler::IsNop(Instr instr, int type) {
+  int reg = 0;
+  switch (type) {
+    case NON_MARKING_NOP:
+      reg = 0;
+      break;
+    case GROUP_ENDING_NOP:
+      reg = 2;
+      break;
+    case DEBUG_BREAK_NOP:
+      reg = 3;
+      break;
+    default:
+      UNIMPLEMENTED();
+  }
+  return instr == (ORI | reg * B21 | reg * B16);
+}
+
+
+// Debugging.
+void Assembler::RecordJSReturn() {
+  positions_recorder()->WriteRecordedPositions();
+  CheckBuffer();
+  RecordRelocInfo(RelocInfo::JS_RETURN);
+}
+
+
+void Assembler::RecordDebugBreakSlot() {
+  positions_recorder()->WriteRecordedPositions();
+  CheckBuffer();
+  RecordRelocInfo(RelocInfo::DEBUG_BREAK_SLOT);
+}
+
+
+void Assembler::RecordComment(const char* msg) {
+  if (FLAG_code_comments) {
+    CheckBuffer();
+    RecordRelocInfo(RelocInfo::COMMENT, reinterpret_cast<intptr_t>(msg));
+  }
+}
+
+
+void Assembler::GrowBuffer() {
+  if (!own_buffer_) FATAL("external code buffer is too small");
+
+  // Compute new buffer size.
+  CodeDesc desc;  // the new buffer
+  if (buffer_size_ < 4 * KB) {
+    desc.buffer_size = 4 * KB;
+  } else if (buffer_size_ < 1 * MB) {
+    desc.buffer_size = 2 * buffer_size_;
+  } else {
+    desc.buffer_size = buffer_size_ + 1 * MB;
+  }
+  CHECK_GT(desc.buffer_size, 0);  // no overflow
+
+  // Set up new buffer.
+  desc.buffer = NewArray<byte>(desc.buffer_size);
+
+  desc.instr_size = pc_offset();
+  desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
+
+  // Copy the data.
+  intptr_t pc_delta = desc.buffer - buffer_;
+  intptr_t rc_delta =
+      (desc.buffer + desc.buffer_size) - (buffer_ + buffer_size_);
+  memmove(desc.buffer, buffer_, desc.instr_size);
+  memmove(reloc_info_writer.pos() + rc_delta, reloc_info_writer.pos(),
+          desc.reloc_size);
+
+  // Switch buffers.
+  DeleteArray(buffer_);
+  buffer_ = desc.buffer;
+  buffer_size_ = desc.buffer_size;
+  pc_ += pc_delta;
+  reloc_info_writer.Reposition(reloc_info_writer.pos() + rc_delta,
+                               reloc_info_writer.last_pc() + pc_delta);
+
+// None of our relocation types are pc relative pointing outside the code
+// buffer nor pc absolute pointing inside the code buffer, so there is no need
+// to relocate any emitted relocation entries.
+
+#if ABI_USES_FUNCTION_DESCRIPTORS || V8_OOL_CONSTANT_POOL
+  // Relocate runtime entries.
+  for (RelocIterator it(desc); !it.done(); it.next()) {
+    RelocInfo::Mode rmode = it.rinfo()->rmode();
+    if (rmode == RelocInfo::INTERNAL_REFERENCE) {
+      RelocateInternalReference(it.rinfo()->pc(), pc_delta, 0);
+    }
+  }
+#if V8_OOL_CONSTANT_POOL
+  constant_pool_builder_.Relocate(pc_delta);
+#endif
+#endif
+}
+
+
+void Assembler::db(uint8_t data) {
+  CheckBuffer();
+  *reinterpret_cast<uint8_t*>(pc_) = data;
+  pc_ += sizeof(uint8_t);
+}
+
+
+void Assembler::dd(uint32_t data) {
+  CheckBuffer();
+  *reinterpret_cast<uint32_t*>(pc_) = data;
+  pc_ += sizeof(uint32_t);
+}
+
+
+void Assembler::emit_ptr(uintptr_t data) {
+  CheckBuffer();
+  *reinterpret_cast<uintptr_t*>(pc_) = data;
+  pc_ += sizeof(uintptr_t);
+}
+
+
+void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) {
+  RelocInfo rinfo(pc_, rmode, data, NULL);
+  RecordRelocInfo(rinfo);
+}
+
+
+void Assembler::RecordRelocInfo(const RelocInfo& rinfo) {
+  if (rinfo.rmode() >= RelocInfo::JS_RETURN &&
+      rinfo.rmode() <= RelocInfo::DEBUG_BREAK_SLOT) {
+    // Adjust code for new modes.
+    DCHECK(RelocInfo::IsDebugBreakSlot(rinfo.rmode()) ||
+           RelocInfo::IsJSReturn(rinfo.rmode()) ||
+           RelocInfo::IsComment(rinfo.rmode()) ||
+           RelocInfo::IsPosition(rinfo.rmode()));
+  }
+  if (!RelocInfo::IsNone(rinfo.rmode())) {
+    // Don't record external references unless the heap will be serialized.
+    if (rinfo.rmode() == RelocInfo::EXTERNAL_REFERENCE) {
+      if (!serializer_enabled() && !emit_debug_code()) {
+        return;
+      }
+    }
+    DCHECK(buffer_space() >= kMaxRelocSize);  // too late to grow buffer here
+    if (rinfo.rmode() == RelocInfo::CODE_TARGET_WITH_ID) {
+      RelocInfo reloc_info_with_ast_id(rinfo.pc(), rinfo.rmode(),
+                                       RecordedAstId().ToInt(), NULL);
+      ClearRecordedAstId();
+      reloc_info_writer.Write(&reloc_info_with_ast_id);
+    } else {
+      reloc_info_writer.Write(&rinfo);
+    }
+  }
+}
+
+
+void Assembler::BlockTrampolinePoolFor(int instructions) {
+  BlockTrampolinePoolBefore(pc_offset() + instructions * kInstrSize);
+}
+
+
+void Assembler::CheckTrampolinePool() {
+  // Some small sequences of instructions must not be broken up by the
+  // insertion of a trampoline pool; such sequences are protected by setting
+  // either trampoline_pool_blocked_nesting_ or no_trampoline_pool_before_,
+  // which are both checked here. Also, recursive calls to CheckTrampolinePool
+  // are blocked by trampoline_pool_blocked_nesting_.
+  if ((trampoline_pool_blocked_nesting_ > 0) ||
+      (pc_offset() < no_trampoline_pool_before_)) {
+    // Emission is currently blocked; make sure we try again as soon as
+    // possible.
+    if (trampoline_pool_blocked_nesting_ > 0) {
+      next_buffer_check_ = pc_offset() + kInstrSize;
+    } else {
+      next_buffer_check_ = no_trampoline_pool_before_;
+    }
+    return;
+  }
+
+  DCHECK(!trampoline_emitted_);
+  DCHECK(unbound_labels_count_ >= 0);
+  if (unbound_labels_count_ > 0) {
+    // First we emit jump, then we emit trampoline pool.
+    {
+      BlockTrampolinePoolScope block_trampoline_pool(this);
+      Label after_pool;
+      b(&after_pool);
+
+      int pool_start = pc_offset();
+      for (int i = 0; i < unbound_labels_count_; i++) {
+        b(&after_pool);
+      }
+      bind(&after_pool);
+      trampoline_ = Trampoline(pool_start, unbound_labels_count_);
+
+      trampoline_emitted_ = true;
+      // As we are only going to emit trampoline once, we need to prevent any
+      // further emission.
+      next_buffer_check_ = kMaxInt;
+    }
+  } else {
+    // Number of branches to unbound label at this point is zero, so we can
+    // move next buffer check to maximum.
+    next_buffer_check_ =
+        pc_offset() + kMaxCondBranchReach - kMaxBlockTrampolineSectionSize;
+  }
+  return;
+}
+
+
+Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
+#if V8_OOL_CONSTANT_POOL
+  return constant_pool_builder_.New(isolate);
+#else
+  // No out-of-line constant pool support.
+  DCHECK(!FLAG_enable_ool_constant_pool);
+  return isolate->factory()->empty_constant_pool_array();
+#endif
+}
+
+
+void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
+#if V8_OOL_CONSTANT_POOL
+  constant_pool_builder_.Populate(this, constant_pool);
+#else
+  // No out-of-line constant pool support.
+  DCHECK(!FLAG_enable_ool_constant_pool);
+#endif
+}
+
+
+#if V8_OOL_CONSTANT_POOL
+ConstantPoolBuilder::ConstantPoolBuilder()
+    : size_(0),
+      entries_(),
+      current_section_(ConstantPoolArray::SMALL_SECTION) {}
+
+
+bool ConstantPoolBuilder::IsEmpty() { return entries_.size() == 0; }
+
+
+ConstantPoolArray::Type ConstantPoolBuilder::GetConstantPoolType(
+    RelocInfo::Mode rmode) {
+#if V8_TARGET_ARCH_PPC64
+  // We don't support 32-bit entries at this time.
+  if (!RelocInfo::IsGCRelocMode(rmode)) {
+    return ConstantPoolArray::INT64;
+#else
+  if (rmode == RelocInfo::NONE64) {
+    return ConstantPoolArray::INT64;
+  } else if (!RelocInfo::IsGCRelocMode(rmode)) {
+    return ConstantPoolArray::INT32;
+#endif
+  } else if (RelocInfo::IsCodeTarget(rmode)) {
+    return ConstantPoolArray::CODE_PTR;
+  } else {
+    DCHECK(RelocInfo::IsGCRelocMode(rmode) && !RelocInfo::IsCodeTarget(rmode));
+    return ConstantPoolArray::HEAP_PTR;
+  }
+}
+
+
+ConstantPoolArray::LayoutSection ConstantPoolBuilder::AddEntry(
+    Assembler* assm, const RelocInfo& rinfo) {
+  RelocInfo::Mode rmode = rinfo.rmode();
+  DCHECK(rmode != RelocInfo::COMMENT && rmode != RelocInfo::POSITION &&
+         rmode != RelocInfo::STATEMENT_POSITION &&
+         rmode != RelocInfo::CONST_POOL);
+
+  // Try to merge entries which won't be patched.
+  int merged_index = -1;
+  ConstantPoolArray::LayoutSection entry_section = current_section_;
+  if (RelocInfo::IsNone(rmode) ||
+      (!assm->serializer_enabled() && (rmode >= RelocInfo::CELL))) {
+    size_t i;
+    std::vector<ConstantPoolEntry>::const_iterator it;
+    for (it = entries_.begin(), i = 0; it != entries_.end(); it++, i++) {
+      if (RelocInfo::IsEqual(rinfo, it->rinfo_)) {
+        // Merge with found entry.
+        merged_index = i;
+        entry_section = entries_[i].section_;
+        break;
+      }
+    }
+  }
+  DCHECK(entry_section <= current_section_);
+  entries_.push_back(ConstantPoolEntry(rinfo, entry_section, merged_index));
+
+  if (merged_index == -1) {
+    // Not merged, so update the appropriate count.
+    number_of_entries_[entry_section].increment(GetConstantPoolType(rmode));
+  }
+
+  // Check if we still have room for another entry in the small section
+  // given the limitations of the header's layout fields.
+  if (current_section_ == ConstantPoolArray::SMALL_SECTION) {
+    size_ = ConstantPoolArray::SizeFor(*small_entries());
+    if (!is_uint12(size_)) {
+      current_section_ = ConstantPoolArray::EXTENDED_SECTION;
+    }
+  } else {
+    size_ = ConstantPoolArray::SizeForExtended(*small_entries(),
+                                               *extended_entries());
+  }
+
+  return entry_section;
+}
+
+
+void ConstantPoolBuilder::Relocate(intptr_t pc_delta) {
+  for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin();
+       entry != entries_.end(); entry++) {
+    DCHECK(entry->rinfo_.rmode() != RelocInfo::JS_RETURN);
+    entry->rinfo_.set_pc(entry->rinfo_.pc() + pc_delta);
+  }
+}
+
+
+Handle<ConstantPoolArray> ConstantPoolBuilder::New(Isolate* isolate) {
+  if (IsEmpty()) {
+    return isolate->factory()->empty_constant_pool_array();
+  } else if (extended_entries()->is_empty()) {
+    return isolate->factory()->NewConstantPoolArray(*small_entries());
+  } else {
+    DCHECK(current_section_ == ConstantPoolArray::EXTENDED_SECTION);
+    return isolate->factory()->NewExtendedConstantPoolArray(
+        *small_entries(), *extended_entries());
+  }
+}
+
+
+void ConstantPoolBuilder::Populate(Assembler* assm,
+                                   ConstantPoolArray* constant_pool) {
+  DCHECK_EQ(extended_entries()->is_empty(),
+            !constant_pool->is_extended_layout());
+  DCHECK(small_entries()->equals(ConstantPoolArray::NumberOfEntries(
+      constant_pool, ConstantPoolArray::SMALL_SECTION)));
+  if (constant_pool->is_extended_layout()) {
+    DCHECK(extended_entries()->equals(ConstantPoolArray::NumberOfEntries(
+        constant_pool, ConstantPoolArray::EXTENDED_SECTION)));
+  }
+
+  // Set up initial offsets.
+  int offsets[ConstantPoolArray::NUMBER_OF_LAYOUT_SECTIONS]
+             [ConstantPoolArray::NUMBER_OF_TYPES];
+  for (int section = 0; section <= constant_pool->final_section(); section++) {
+    int section_start = (section == ConstantPoolArray::EXTENDED_SECTION)
+                            ? small_entries()->total_count()
+                            : 0;
+    for (int i = 0; i < ConstantPoolArray::NUMBER_OF_TYPES; i++) {
+      ConstantPoolArray::Type type = static_cast<ConstantPoolArray::Type>(i);
+      if (number_of_entries_[section].count_of(type) != 0) {
+        offsets[section][type] = constant_pool->OffsetOfElementAt(
+            number_of_entries_[section].base_of(type) + section_start);
+      }
+    }
+  }
+
+  for (std::vector<ConstantPoolEntry>::iterator entry = entries_.begin();
+       entry != entries_.end(); entry++) {
+    RelocInfo rinfo = entry->rinfo_;
+    RelocInfo::Mode rmode = entry->rinfo_.rmode();
+    ConstantPoolArray::Type type = GetConstantPoolType(rmode);
+
+    // Update constant pool if necessary and get the entry's offset.
+    int offset;
+    if (entry->merged_index_ == -1) {
+      offset = offsets[entry->section_][type];
+      offsets[entry->section_][type] += ConstantPoolArray::entry_size(type);
+      if (type == ConstantPoolArray::INT64) {
+#if V8_TARGET_ARCH_PPC64
+        constant_pool->set_at_offset(offset, rinfo.data());
+#else
+        constant_pool->set_at_offset(offset, rinfo.data64());
+      } else if (type == ConstantPoolArray::INT32) {
+        constant_pool->set_at_offset(offset,
+                                     static_cast<int32_t>(rinfo.data()));
+#endif
+      } else if (type == ConstantPoolArray::CODE_PTR) {
+        constant_pool->set_at_offset(offset,
+                                     reinterpret_cast<Address>(rinfo.data()));
+      } else {
+        DCHECK(type == ConstantPoolArray::HEAP_PTR);
+        constant_pool->set_at_offset(offset,
+                                     reinterpret_cast<Object*>(rinfo.data()));
+      }
+      offset -= kHeapObjectTag;
+      entry->merged_index_ = offset;  // Stash offset for merged entries.
+    } else {
+      DCHECK(entry->merged_index_ < (entry - entries_.begin()));
+      offset = entries_[entry->merged_index_].merged_index_;
+    }
+
+    // Patch load instruction with correct offset.
+    Assembler::SetConstantPoolOffset(rinfo.pc(), offset);
+  }
+}
+#endif
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/assembler-ppc.h b/src/ppc/assembler-ppc.h
new file mode 100644
index 0000000..2b112d6
--- /dev/null
+++ b/src/ppc/assembler-ppc.h
@@ -0,0 +1,1493 @@
+// Copyright (c) 1994-2006 Sun Microsystems Inc.
+// 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.
+//
+// - Redistribution 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 Sun Microsystems or the names of 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.
+
+// The original source code covered by the above license above has been
+// modified significantly by Google Inc.
+// Copyright 2014 the V8 project authors. All rights reserved.
+
+// A light-weight PPC Assembler
+// Generates user mode instructions for the PPC architecture up
+
+#ifndef V8_PPC_ASSEMBLER_PPC_H_
+#define V8_PPC_ASSEMBLER_PPC_H_
+
+#include <stdio.h>
+#include <vector>
+
+#include "src/assembler.h"
+#include "src/ppc/constants-ppc.h"
+#include "src/serialize.h"
+
+#define ABI_USES_FUNCTION_DESCRIPTORS \
+  (V8_HOST_ARCH_PPC && (V8_OS_AIX ||    \
+                      (V8_TARGET_ARCH_PPC64 && V8_TARGET_BIG_ENDIAN)))
+
+#define ABI_PASSES_HANDLES_IN_REGS \
+  (!V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64)
+
+#define ABI_RETURNS_HANDLES_IN_REGS \
+  (!V8_HOST_ARCH_PPC || V8_TARGET_LITTLE_ENDIAN)
+
+#define ABI_RETURNS_OBJECT_PAIRS_IN_REGS \
+  (!V8_HOST_ARCH_PPC || V8_TARGET_LITTLE_ENDIAN)
+
+#define ABI_TOC_ADDRESSABILITY_VIA_IP \
+  (V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN)
+
+#if !V8_HOST_ARCH_PPC || V8_OS_AIX || V8_TARGET_ARCH_PPC64
+#define ABI_TOC_REGISTER kRegister_r2_Code
+#else
+#define ABI_TOC_REGISTER kRegister_r13_Code
+#endif
+
+#define INSTR_AND_DATA_CACHE_COHERENCY LWSYNC
+
+namespace v8 {
+namespace internal {
+
+// CPU Registers.
+//
+// 1) We would prefer to use an enum, but enum values are assignment-
+// compatible with int, which has caused code-generation bugs.
+//
+// 2) We would prefer to use a class instead of a struct but we don't like
+// the register initialization to depend on the particular initialization
+// order (which appears to be different on OS X, Linux, and Windows for the
+// installed versions of C++ we tried). Using a struct permits C-style
+// "initialization". Also, the Register objects cannot be const as this
+// forces initialization stubs in MSVC, making us dependent on initialization
+// order.
+//
+// 3) By not using an enum, we are possibly preventing the compiler from
+// doing certain constant folds, which may significantly reduce the
+// code generated for some assembly instructions (because they boil down
+// to a few constants). If this is a problem, we could change the code
+// such that we use an enum in optimized mode, and the struct in debug
+// mode. This way we get the compile-time error checking in debug mode
+// and best performance in optimized code.
+
+// Core register
+struct Register {
+  static const int kNumRegisters = 32;
+  static const int kSizeInBytes = kPointerSize;
+
+#if V8_TARGET_LITTLE_ENDIAN
+  static const int kMantissaOffset = 0;
+  static const int kExponentOffset = 4;
+#else
+  static const int kMantissaOffset = 4;
+  static const int kExponentOffset = 0;
+#endif
+
+  static const int kAllocatableLowRangeBegin = 3;
+  static const int kAllocatableLowRangeEnd = 10;
+  static const int kAllocatableHighRangeBegin = 14;
+#if V8_OOL_CONSTANT_POOL
+  static const int kAllocatableHighRangeEnd = 27;
+#else
+  static const int kAllocatableHighRangeEnd = 28;
+#endif
+  static const int kAllocatableContext = 30;
+
+  static const int kNumAllocatableLow =
+      kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1;
+  static const int kNumAllocatableHigh =
+      kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1;
+  static const int kMaxNumAllocatableRegisters =
+      kNumAllocatableLow + kNumAllocatableHigh + 1;  // cp
+
+  static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; }
+
+  static int ToAllocationIndex(Register reg) {
+    int index;
+    int code = reg.code();
+    if (code == kAllocatableContext) {
+      // Context is the last index
+      index = NumAllocatableRegisters() - 1;
+    } else if (code <= kAllocatableLowRangeEnd) {
+      // low range
+      index = code - kAllocatableLowRangeBegin;
+    } else {
+      // high range
+      index = code - kAllocatableHighRangeBegin + kNumAllocatableLow;
+    }
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    return index;
+  }
+
+  static Register FromAllocationIndex(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    // Last index is always the 'cp' register.
+    if (index == kMaxNumAllocatableRegisters - 1) {
+      return from_code(kAllocatableContext);
+    }
+    return (index < kNumAllocatableLow)
+               ? from_code(index + kAllocatableLowRangeBegin)
+               : from_code(index - kNumAllocatableLow +
+                           kAllocatableHighRangeBegin);
+  }
+
+  static const char* AllocationIndexToString(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    const char* const names[] = {
+      "r3",
+      "r4",
+      "r5",
+      "r6",
+      "r7",
+      "r8",
+      "r9",
+      "r10",
+      "r14",
+      "r15",
+      "r16",
+      "r17",
+      "r18",
+      "r19",
+      "r20",
+      "r21",
+      "r22",
+      "r23",
+      "r24",
+      "r25",
+      "r26",
+      "r27",
+#if !V8_OOL_CONSTANT_POOL
+      "r28",
+#endif
+      "cp",
+    };
+    return names[index];
+  }
+
+  static Register from_code(int code) {
+    Register r = {code};
+    return r;
+  }
+
+  bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
+  bool is(Register reg) const { return code_ == reg.code_; }
+  int code() const {
+    DCHECK(is_valid());
+    return code_;
+  }
+  int bit() const {
+    DCHECK(is_valid());
+    return 1 << code_;
+  }
+
+  void set_code(int code) {
+    code_ = code;
+    DCHECK(is_valid());
+  }
+
+  // Unfortunately we can't make this private in a struct.
+  int code_;
+};
+
+// These constants are used in several locations, including static initializers
+const int kRegister_no_reg_Code = -1;
+const int kRegister_r0_Code = 0;  // general scratch
+const int kRegister_sp_Code = 1;  // stack pointer
+const int kRegister_r2_Code = 2;  // special on PowerPC
+const int kRegister_r3_Code = 3;
+const int kRegister_r4_Code = 4;
+const int kRegister_r5_Code = 5;
+const int kRegister_r6_Code = 6;
+const int kRegister_r7_Code = 7;
+const int kRegister_r8_Code = 8;
+const int kRegister_r9_Code = 9;
+const int kRegister_r10_Code = 10;
+const int kRegister_r11_Code = 11;  // lithium scratch
+const int kRegister_ip_Code = 12;   // ip (general scratch)
+const int kRegister_r13_Code = 13;  // special on PowerPC
+const int kRegister_r14_Code = 14;
+const int kRegister_r15_Code = 15;
+
+const int kRegister_r16_Code = 16;
+const int kRegister_r17_Code = 17;
+const int kRegister_r18_Code = 18;
+const int kRegister_r19_Code = 19;
+const int kRegister_r20_Code = 20;
+const int kRegister_r21_Code = 21;
+const int kRegister_r22_Code = 22;
+const int kRegister_r23_Code = 23;
+const int kRegister_r24_Code = 24;
+const int kRegister_r25_Code = 25;
+const int kRegister_r26_Code = 26;
+const int kRegister_r27_Code = 27;
+const int kRegister_r28_Code = 28;  // constant pool pointer
+const int kRegister_r29_Code = 29;  // roots array pointer
+const int kRegister_r30_Code = 30;  // context pointer
+const int kRegister_fp_Code = 31;   // frame pointer
+
+const Register no_reg = {kRegister_no_reg_Code};
+
+const Register r0 = {kRegister_r0_Code};
+const Register sp = {kRegister_sp_Code};
+const Register r2 = {kRegister_r2_Code};
+const Register r3 = {kRegister_r3_Code};
+const Register r4 = {kRegister_r4_Code};
+const Register r5 = {kRegister_r5_Code};
+const Register r6 = {kRegister_r6_Code};
+const Register r7 = {kRegister_r7_Code};
+const Register r8 = {kRegister_r8_Code};
+const Register r9 = {kRegister_r9_Code};
+const Register r10 = {kRegister_r10_Code};
+const Register r11 = {kRegister_r11_Code};
+const Register ip = {kRegister_ip_Code};
+const Register r13 = {kRegister_r13_Code};
+const Register r14 = {kRegister_r14_Code};
+const Register r15 = {kRegister_r15_Code};
+
+const Register r16 = {kRegister_r16_Code};
+const Register r17 = {kRegister_r17_Code};
+const Register r18 = {kRegister_r18_Code};
+const Register r19 = {kRegister_r19_Code};
+const Register r20 = {kRegister_r20_Code};
+const Register r21 = {kRegister_r21_Code};
+const Register r22 = {kRegister_r22_Code};
+const Register r23 = {kRegister_r23_Code};
+const Register r24 = {kRegister_r24_Code};
+const Register r25 = {kRegister_r25_Code};
+const Register r26 = {kRegister_r26_Code};
+const Register r27 = {kRegister_r27_Code};
+const Register r28 = {kRegister_r28_Code};
+const Register r29 = {kRegister_r29_Code};
+const Register r30 = {kRegister_r30_Code};
+const Register fp = {kRegister_fp_Code};
+
+// Give alias names to registers
+const Register cp = {kRegister_r30_Code};  // JavaScript context pointer
+const Register kRootRegister = {kRegister_r29_Code};  // Roots array pointer.
+#if V8_OOL_CONSTANT_POOL
+const Register kConstantPoolRegister = {kRegister_r28_Code};  // Constant pool
+#endif
+
+// Double word FP register.
+struct DoubleRegister {
+  static const int kNumRegisters = 32;
+  static const int kMaxNumRegisters = kNumRegisters;
+  static const int kNumVolatileRegisters = 14;  // d0-d13
+  static const int kSizeInBytes = 8;
+
+  static const int kAllocatableLowRangeBegin = 1;
+  static const int kAllocatableLowRangeEnd = 12;
+  static const int kAllocatableHighRangeBegin = 15;
+  static const int kAllocatableHighRangeEnd = 31;
+
+  static const int kNumAllocatableLow =
+      kAllocatableLowRangeEnd - kAllocatableLowRangeBegin + 1;
+  static const int kNumAllocatableHigh =
+      kAllocatableHighRangeEnd - kAllocatableHighRangeBegin + 1;
+  static const int kMaxNumAllocatableRegisters =
+      kNumAllocatableLow + kNumAllocatableHigh;
+  static int NumAllocatableRegisters() { return kMaxNumAllocatableRegisters; }
+
+  // TODO(turbofan)
+  inline static int NumAllocatableAliasedRegisters() {
+    return NumAllocatableRegisters();
+  }
+
+  static int ToAllocationIndex(DoubleRegister reg) {
+    int code = reg.code();
+    int index = (code <= kAllocatableLowRangeEnd)
+                    ? code - kAllocatableLowRangeBegin
+                    : code - kAllocatableHighRangeBegin + kNumAllocatableLow;
+    DCHECK(index < kMaxNumAllocatableRegisters);
+    return index;
+  }
+
+  static DoubleRegister FromAllocationIndex(int index) {
+    DCHECK(index >= 0 && index < kMaxNumAllocatableRegisters);
+    return (index < kNumAllocatableLow)
+               ? from_code(index + kAllocatableLowRangeBegin)
+               : from_code(index - kNumAllocatableLow +
+                           kAllocatableHighRangeBegin);
+  }
+
+  static const char* AllocationIndexToString(int index);
+
+  static DoubleRegister from_code(int code) {
+    DoubleRegister r = {code};
+    return r;
+  }
+
+  bool is_valid() const { return 0 <= code_ && code_ < kMaxNumRegisters; }
+  bool is(DoubleRegister reg) const { return code_ == reg.code_; }
+
+  int code() const {
+    DCHECK(is_valid());
+    return code_;
+  }
+  int bit() const {
+    DCHECK(is_valid());
+    return 1 << code_;
+  }
+  void split_code(int* vm, int* m) const {
+    DCHECK(is_valid());
+    *m = (code_ & 0x10) >> 4;
+    *vm = code_ & 0x0F;
+  }
+
+  int code_;
+};
+
+
+const DoubleRegister no_dreg = {-1};
+const DoubleRegister d0 = {0};
+const DoubleRegister d1 = {1};
+const DoubleRegister d2 = {2};
+const DoubleRegister d3 = {3};
+const DoubleRegister d4 = {4};
+const DoubleRegister d5 = {5};
+const DoubleRegister d6 = {6};
+const DoubleRegister d7 = {7};
+const DoubleRegister d8 = {8};
+const DoubleRegister d9 = {9};
+const DoubleRegister d10 = {10};
+const DoubleRegister d11 = {11};
+const DoubleRegister d12 = {12};
+const DoubleRegister d13 = {13};
+const DoubleRegister d14 = {14};
+const DoubleRegister d15 = {15};
+const DoubleRegister d16 = {16};
+const DoubleRegister d17 = {17};
+const DoubleRegister d18 = {18};
+const DoubleRegister d19 = {19};
+const DoubleRegister d20 = {20};
+const DoubleRegister d21 = {21};
+const DoubleRegister d22 = {22};
+const DoubleRegister d23 = {23};
+const DoubleRegister d24 = {24};
+const DoubleRegister d25 = {25};
+const DoubleRegister d26 = {26};
+const DoubleRegister d27 = {27};
+const DoubleRegister d28 = {28};
+const DoubleRegister d29 = {29};
+const DoubleRegister d30 = {30};
+const DoubleRegister d31 = {31};
+
+// Aliases for double registers.  Defined using #define instead of
+// "static const DoubleRegister&" because Clang complains otherwise when a
+// compilation unit that includes this header doesn't use the variables.
+#define kFirstCalleeSavedDoubleReg d14
+#define kLastCalleeSavedDoubleReg d31
+#define kDoubleRegZero d14
+#define kScratchDoubleReg d13
+
+Register ToRegister(int num);
+
+// Coprocessor register
+struct CRegister {
+  bool is_valid() const { return 0 <= code_ && code_ < 16; }
+  bool is(CRegister creg) const { return code_ == creg.code_; }
+  int code() const {
+    DCHECK(is_valid());
+    return code_;
+  }
+  int bit() const {
+    DCHECK(is_valid());
+    return 1 << code_;
+  }
+
+  // Unfortunately we can't make this private in a struct.
+  int code_;
+};
+
+
+const CRegister no_creg = {-1};
+
+const CRegister cr0 = {0};
+const CRegister cr1 = {1};
+const CRegister cr2 = {2};
+const CRegister cr3 = {3};
+const CRegister cr4 = {4};
+const CRegister cr5 = {5};
+const CRegister cr6 = {6};
+const CRegister cr7 = {7};
+const CRegister cr8 = {8};
+const CRegister cr9 = {9};
+const CRegister cr10 = {10};
+const CRegister cr11 = {11};
+const CRegister cr12 = {12};
+const CRegister cr13 = {13};
+const CRegister cr14 = {14};
+const CRegister cr15 = {15};
+
+// -----------------------------------------------------------------------------
+// Machine instruction Operands
+
+#if V8_TARGET_ARCH_PPC64
+const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE64;
+#else
+const RelocInfo::Mode kRelocInfo_NONEPTR = RelocInfo::NONE32;
+#endif
+
+// Class Operand represents a shifter operand in data processing instructions
+class Operand BASE_EMBEDDED {
+ public:
+  // immediate
+  INLINE(explicit Operand(intptr_t immediate,
+                          RelocInfo::Mode rmode = kRelocInfo_NONEPTR));
+  INLINE(static Operand Zero()) { return Operand(static_cast<intptr_t>(0)); }
+  INLINE(explicit Operand(const ExternalReference& f));
+  explicit Operand(Handle<Object> handle);
+  INLINE(explicit Operand(Smi* value));
+
+  // rm
+  INLINE(explicit Operand(Register rm));
+
+  // Return true if this is a register operand.
+  INLINE(bool is_reg() const);
+
+  // For mov.  Return the number of actual instructions required to
+  // load the operand into a register.  This can be anywhere from
+  // one (constant pool small section) to five instructions (full
+  // 64-bit sequence).
+  //
+  // The value returned is only valid as long as no entries are added to the
+  // constant pool between this call and the actual instruction being emitted.
+  bool must_output_reloc_info(const Assembler* assembler) const;
+
+  inline intptr_t immediate() const {
+    DCHECK(!rm_.is_valid());
+    return imm_;
+  }
+
+  Register rm() const { return rm_; }
+
+ private:
+  Register rm_;
+  intptr_t imm_;  // valid if rm_ == no_reg
+  RelocInfo::Mode rmode_;
+
+  friend class Assembler;
+  friend class MacroAssembler;
+};
+
+
+// Class MemOperand represents a memory operand in load and store instructions
+// On PowerPC we have base register + 16bit signed value
+// Alternatively we can have a 16bit signed value immediate
+class MemOperand BASE_EMBEDDED {
+ public:
+  explicit MemOperand(Register rn, int32_t offset = 0);
+
+  explicit MemOperand(Register ra, Register rb);
+
+  int32_t offset() const {
+    DCHECK(rb_.is(no_reg));
+    return offset_;
+  }
+
+  // PowerPC - base register
+  Register ra() const {
+    DCHECK(!ra_.is(no_reg));
+    return ra_;
+  }
+
+  Register rb() const {
+    DCHECK(offset_ == 0 && !rb_.is(no_reg));
+    return rb_;
+  }
+
+ private:
+  Register ra_;     // base
+  int32_t offset_;  // offset
+  Register rb_;     // index
+
+  friend class Assembler;
+};
+
+
+#if V8_OOL_CONSTANT_POOL
+// Class used to build a constant pool.
+class ConstantPoolBuilder BASE_EMBEDDED {
+ public:
+  ConstantPoolBuilder();
+  ConstantPoolArray::LayoutSection AddEntry(Assembler* assm,
+                                            const RelocInfo& rinfo);
+  void Relocate(intptr_t pc_delta);
+  bool IsEmpty();
+  Handle<ConstantPoolArray> New(Isolate* isolate);
+  void Populate(Assembler* assm, ConstantPoolArray* constant_pool);
+
+  inline ConstantPoolArray::LayoutSection current_section() const {
+    return current_section_;
+  }
+
+  // Rather than increasing the capacity of the ConstantPoolArray's
+  // small section to match the longer (16-bit) reach of PPC's load
+  // instruction (at the expense of a larger header to describe the
+  // layout), the PPC implementation utilizes the extended section to
+  // satisfy that reach.  I.e. all entries (regardless of their
+  // section) are reachable with a single load instruction.
+  //
+  // This implementation does not support an unlimited constant pool
+  // size (which would require a multi-instruction sequence).  [See
+  // ARM commit e27ab337 for a reference on the changes required to
+  // support the longer instruction sequence.]  Note, however, that
+  // going down that path will necessarily generate that longer
+  // sequence for all extended section accesses since the placement of
+  // a given entry within the section is not known at the time of
+  // code generation.
+  //
+  // TODO(mbrandy): Determine whether there is a benefit to supporting
+  // the longer sequence given that nops could be used for those
+  // entries which are reachable with a single instruction.
+  inline bool is_full() const { return !is_int16(size_); }
+
+  inline ConstantPoolArray::NumberOfEntries* number_of_entries(
+      ConstantPoolArray::LayoutSection section) {
+    return &number_of_entries_[section];
+  }
+
+  inline ConstantPoolArray::NumberOfEntries* small_entries() {
+    return number_of_entries(ConstantPoolArray::SMALL_SECTION);
+  }
+
+  inline ConstantPoolArray::NumberOfEntries* extended_entries() {
+    return number_of_entries(ConstantPoolArray::EXTENDED_SECTION);
+  }
+
+ private:
+  struct ConstantPoolEntry {
+    ConstantPoolEntry(RelocInfo rinfo, ConstantPoolArray::LayoutSection section,
+                      int merged_index)
+        : rinfo_(rinfo), section_(section), merged_index_(merged_index) {}
+
+    RelocInfo rinfo_;
+    ConstantPoolArray::LayoutSection section_;
+    int merged_index_;
+  };
+
+  ConstantPoolArray::Type GetConstantPoolType(RelocInfo::Mode rmode);
+
+  uint32_t size_;
+  std::vector<ConstantPoolEntry> entries_;
+  ConstantPoolArray::LayoutSection current_section_;
+  ConstantPoolArray::NumberOfEntries number_of_entries_[2];
+};
+#endif
+
+
+class Assembler : public AssemblerBase {
+ public:
+  // Create an assembler. Instructions and relocation information are emitted
+  // into a buffer, with the instructions starting from the beginning and the
+  // relocation information starting from the end of the buffer. See CodeDesc
+  // for a detailed comment on the layout (globals.h).
+  //
+  // If the provided buffer is NULL, the assembler allocates and grows its own
+  // buffer, and buffer_size determines the initial buffer size. The buffer is
+  // owned by the assembler and deallocated upon destruction of the assembler.
+  //
+  // If the provided buffer is not NULL, the assembler uses the provided buffer
+  // for code generation and assumes its size to be buffer_size. If the buffer
+  // is too small, a fatal error occurs. No deallocation of the buffer is done
+  // upon destruction of the assembler.
+  Assembler(Isolate* isolate, void* buffer, int buffer_size);
+  virtual ~Assembler() {}
+
+  // GetCode emits any pending (non-emitted) code and fills the descriptor
+  // desc. GetCode() is idempotent; it returns the same result if no other
+  // Assembler functions are invoked in between GetCode() calls.
+  void GetCode(CodeDesc* desc);
+
+  // Label operations & relative jumps (PPUM Appendix D)
+  //
+  // Takes a branch opcode (cc) and a label (L) and generates
+  // either a backward branch or a forward branch and links it
+  // to the label fixup chain. Usage:
+  //
+  // Label L;    // unbound label
+  // j(cc, &L);  // forward branch to unbound label
+  // bind(&L);   // bind label to the current pc
+  // j(cc, &L);  // backward branch to bound label
+  // bind(&L);   // illegal: a label may be bound only once
+  //
+  // Note: The same Label can be used for forward and backward branches
+  // but it may be bound only once.
+
+  void bind(Label* L);  // binds an unbound label L to the current code position
+  // Determines if Label is bound and near enough so that a single
+  // branch instruction can be used to reach it.
+  bool is_near(Label* L, Condition cond);
+
+  // Returns the branch offset to the given label from the current code position
+  // Links the label to the current position if it is still unbound
+  // Manages the jump elimination optimization if the second parameter is true.
+  int branch_offset(Label* L, bool jump_elimination_allowed);
+
+  // Puts a labels target address at the given position.
+  // The high 8 bits are set to zero.
+  void label_at_put(Label* L, int at_offset);
+
+#if V8_OOL_CONSTANT_POOL
+  INLINE(static bool IsConstantPoolLoadStart(Address pc));
+  INLINE(static bool IsConstantPoolLoadEnd(Address pc));
+  INLINE(static int GetConstantPoolOffset(Address pc));
+  INLINE(static void SetConstantPoolOffset(Address pc, int offset));
+
+  // Return the address in the constant pool of the code target address used by
+  // the branch/call instruction at pc, or the object in a mov.
+  INLINE(static Address target_constant_pool_address_at(
+      Address pc, ConstantPoolArray* constant_pool));
+#endif
+
+  // Read/Modify the code target address in the branch/call instruction at pc.
+  INLINE(static Address target_address_at(Address pc,
+                                          ConstantPoolArray* constant_pool));
+  INLINE(static void set_target_address_at(
+      Address pc, ConstantPoolArray* constant_pool, Address target,
+      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED));
+  INLINE(static Address target_address_at(Address pc, Code* code)) {
+    ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
+    return target_address_at(pc, constant_pool);
+  }
+  INLINE(static void set_target_address_at(
+      Address pc, Code* code, Address target,
+      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED)) {
+    ConstantPoolArray* constant_pool = code ? code->constant_pool() : NULL;
+    set_target_address_at(pc, constant_pool, target, icache_flush_mode);
+  }
+
+  // Return the code target address at a call site from the return address
+  // of that call in the instruction stream.
+  inline static Address target_address_from_return_address(Address pc);
+
+  // Given the address of the beginning of a call, return the address
+  // in the instruction stream that the call will return to.
+  INLINE(static Address return_address_from_call_start(Address pc));
+
+  // Return the code target address of the patch debug break slot
+  INLINE(static Address break_address_from_return_address(Address pc));
+
+  // This sets the branch destination.
+  // This is for calls and branches within generated code.
+  inline static void deserialization_set_special_target_at(
+      Address instruction_payload, Code* code, Address target);
+
+  // Size of an instruction.
+  static const int kInstrSize = sizeof(Instr);
+
+  // Here we are patching the address in the LUI/ORI instruction pair.
+  // These values are used in the serialization process and must be zero for
+  // PPC platform, as Code, Embedded Object or External-reference pointers
+  // are split across two consecutive instructions and don't exist separately
+  // in the code, so the serializer should not step forwards in memory after
+  // a target is resolved and written.
+  static const int kSpecialTargetSize = 0;
+
+// Number of instructions to load an address via a mov sequence.
+#if V8_TARGET_ARCH_PPC64
+  static const int kMovInstructionsConstantPool = 2;
+  static const int kMovInstructionsNoConstantPool = 5;
+#else
+  static const int kMovInstructionsConstantPool = 1;
+  static const int kMovInstructionsNoConstantPool = 2;
+#endif
+#if V8_OOL_CONSTANT_POOL
+  static const int kMovInstructions = kMovInstructionsConstantPool;
+#else
+  static const int kMovInstructions = kMovInstructionsNoConstantPool;
+#endif
+
+  // Distance between the instruction referring to the address of the call
+  // target and the return address.
+
+  // Call sequence is a FIXED_SEQUENCE:
+  // mov     r8, @ call address
+  // mtlr    r8
+  // blrl
+  //                      @ return address
+  static const int kCallTargetAddressOffset =
+      (kMovInstructions + 2) * kInstrSize;
+
+  // Distance between start of patched return sequence and the emitted address
+  // to jump to.
+  // Patched return sequence is a FIXED_SEQUENCE:
+  //   mov r0, <address>
+  //   mtlr r0
+  //   blrl
+  static const int kPatchReturnSequenceAddressOffset = 0 * kInstrSize;
+
+  // Distance between start of patched debug break slot and the emitted address
+  // to jump to.
+  // Patched debug break slot code is a FIXED_SEQUENCE:
+  //   mov r0, <address>
+  //   mtlr r0
+  //   blrl
+  static const int kPatchDebugBreakSlotAddressOffset = 0 * kInstrSize;
+
+  // This is the length of the BreakLocationIterator::SetDebugBreakAtReturn()
+  // code patch FIXED_SEQUENCE
+  static const int kJSReturnSequenceInstructions =
+      kMovInstructionsNoConstantPool + 3;
+
+  // This is the length of the code sequence from SetDebugBreakAtSlot()
+  // FIXED_SEQUENCE
+  static const int kDebugBreakSlotInstructions =
+      kMovInstructionsNoConstantPool + 2;
+  static const int kDebugBreakSlotLength =
+      kDebugBreakSlotInstructions * kInstrSize;
+
+  static inline int encode_crbit(const CRegister& cr, enum CRBit crbit) {
+    return ((cr.code() * CRWIDTH) + crbit);
+  }
+
+  // ---------------------------------------------------------------------------
+  // Code generation
+
+  // Insert the smallest number of nop instructions
+  // possible to align the pc offset to a multiple
+  // of m. m must be a power of 2 (>= 4).
+  void Align(int m);
+  // Aligns code to something that's optimal for a jump target for the platform.
+  void CodeTargetAlign();
+
+  // Branch instructions
+  void bclr(BOfield bo, LKBit lk);
+  void blr();
+  void bc(int branch_offset, BOfield bo, int condition_bit, LKBit lk = LeaveLK);
+  void b(int branch_offset, LKBit lk);
+
+  void bcctr(BOfield bo, LKBit lk);
+  void bctr();
+  void bctrl();
+
+  // Convenience branch instructions using labels
+  void b(Label* L, LKBit lk = LeaveLK) { b(branch_offset(L, false), lk); }
+
+  void bc_short(Condition cond, Label* L, CRegister cr = cr7,
+                LKBit lk = LeaveLK) {
+    DCHECK(cond != al);
+    DCHECK(cr.code() >= 0 && cr.code() <= 7);
+
+    int b_offset = branch_offset(L, false);
+
+    switch (cond) {
+      case eq:
+        bc(b_offset, BT, encode_crbit(cr, CR_EQ), lk);
+        break;
+      case ne:
+        bc(b_offset, BF, encode_crbit(cr, CR_EQ), lk);
+        break;
+      case gt:
+        bc(b_offset, BT, encode_crbit(cr, CR_GT), lk);
+        break;
+      case le:
+        bc(b_offset, BF, encode_crbit(cr, CR_GT), lk);
+        break;
+      case lt:
+        bc(b_offset, BT, encode_crbit(cr, CR_LT), lk);
+        break;
+      case ge:
+        bc(b_offset, BF, encode_crbit(cr, CR_LT), lk);
+        break;
+      case unordered:
+        bc(b_offset, BT, encode_crbit(cr, CR_FU), lk);
+        break;
+      case ordered:
+        bc(b_offset, BF, encode_crbit(cr, CR_FU), lk);
+        break;
+      case overflow:
+        bc(b_offset, BT, encode_crbit(cr, CR_SO), lk);
+        break;
+      case nooverflow:
+        bc(b_offset, BF, encode_crbit(cr, CR_SO), lk);
+        break;
+      default:
+        UNIMPLEMENTED();
+    }
+  }
+
+  void b(Condition cond, Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
+    if (cond == al) {
+      b(L, lk);
+      return;
+    }
+
+    if ((L->is_bound() && is_near(L, cond)) || !is_trampoline_emitted()) {
+      bc_short(cond, L, cr, lk);
+      return;
+    }
+
+    Label skip;
+    Condition neg_cond = NegateCondition(cond);
+    bc_short(neg_cond, &skip, cr);
+    b(L, lk);
+    bind(&skip);
+  }
+
+  void bne(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
+    b(ne, L, cr, lk);
+  }
+  void beq(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
+    b(eq, L, cr, lk);
+  }
+  void blt(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
+    b(lt, L, cr, lk);
+  }
+  void bge(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
+    b(ge, L, cr, lk);
+  }
+  void ble(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
+    b(le, L, cr, lk);
+  }
+  void bgt(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
+    b(gt, L, cr, lk);
+  }
+  void bunordered(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
+    b(unordered, L, cr, lk);
+  }
+  void bordered(Label* L, CRegister cr = cr7, LKBit lk = LeaveLK) {
+    b(ordered, L, cr, lk);
+  }
+  void boverflow(Label* L, CRegister cr = cr0, LKBit lk = LeaveLK) {
+    b(overflow, L, cr, lk);
+  }
+  void bnooverflow(Label* L, CRegister cr = cr0, LKBit lk = LeaveLK) {
+    b(nooverflow, L, cr, lk);
+  }
+
+  // Decrement CTR; branch if CTR != 0
+  void bdnz(Label* L, LKBit lk = LeaveLK) {
+    bc(branch_offset(L, false), DCBNZ, 0, lk);
+  }
+
+  // Data-processing instructions
+
+  void sub(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
+           RCBit r = LeaveRC);
+
+  void subfic(Register dst, Register src, const Operand& imm);
+
+  void subfc(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
+             RCBit r = LeaveRC);
+
+  void add(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
+           RCBit r = LeaveRC);
+
+  void addc(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
+            RCBit r = LeaveRC);
+
+  void addze(Register dst, Register src1, OEBit o, RCBit r);
+
+  void mullw(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
+             RCBit r = LeaveRC);
+
+  void mulhw(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
+             RCBit r = LeaveRC);
+
+  void divw(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
+            RCBit r = LeaveRC);
+
+  void addi(Register dst, Register src, const Operand& imm);
+  void addis(Register dst, Register src, const Operand& imm);
+  void addic(Register dst, Register src, const Operand& imm);
+
+  void and_(Register dst, Register src1, Register src2, RCBit rc = LeaveRC);
+  void andc(Register dst, Register src1, Register src2, RCBit rc = LeaveRC);
+  void andi(Register ra, Register rs, const Operand& imm);
+  void andis(Register ra, Register rs, const Operand& imm);
+  void nor(Register dst, Register src1, Register src2, RCBit r = LeaveRC);
+  void notx(Register dst, Register src, RCBit r = LeaveRC);
+  void ori(Register dst, Register src, const Operand& imm);
+  void oris(Register dst, Register src, const Operand& imm);
+  void orx(Register dst, Register src1, Register src2, RCBit rc = LeaveRC);
+  void xori(Register dst, Register src, const Operand& imm);
+  void xoris(Register ra, Register rs, const Operand& imm);
+  void xor_(Register dst, Register src1, Register src2, RCBit rc = LeaveRC);
+  void cmpi(Register src1, const Operand& src2, CRegister cr = cr7);
+  void cmpli(Register src1, const Operand& src2, CRegister cr = cr7);
+  void cmpwi(Register src1, const Operand& src2, CRegister cr = cr7);
+  void cmplwi(Register src1, const Operand& src2, CRegister cr = cr7);
+  void li(Register dst, const Operand& src);
+  void lis(Register dst, const Operand& imm);
+  void mr(Register dst, Register src);
+
+  void lbz(Register dst, const MemOperand& src);
+  void lbzx(Register dst, const MemOperand& src);
+  void lbzux(Register dst, const MemOperand& src);
+  void lhz(Register dst, const MemOperand& src);
+  void lhzx(Register dst, const MemOperand& src);
+  void lhzux(Register dst, const MemOperand& src);
+  void lwz(Register dst, const MemOperand& src);
+  void lwzu(Register dst, const MemOperand& src);
+  void lwzx(Register dst, const MemOperand& src);
+  void lwzux(Register dst, const MemOperand& src);
+  void lwa(Register dst, const MemOperand& src);
+  void stb(Register dst, const MemOperand& src);
+  void stbx(Register dst, const MemOperand& src);
+  void stbux(Register dst, const MemOperand& src);
+  void sth(Register dst, const MemOperand& src);
+  void sthx(Register dst, const MemOperand& src);
+  void sthux(Register dst, const MemOperand& src);
+  void stw(Register dst, const MemOperand& src);
+  void stwu(Register dst, const MemOperand& src);
+  void stwx(Register rs, const MemOperand& src);
+  void stwux(Register rs, const MemOperand& src);
+
+  void extsb(Register rs, Register ra, RCBit r = LeaveRC);
+  void extsh(Register rs, Register ra, RCBit r = LeaveRC);
+
+  void neg(Register rt, Register ra, OEBit o = LeaveOE, RCBit c = LeaveRC);
+
+#if V8_TARGET_ARCH_PPC64
+  void ld(Register rd, const MemOperand& src);
+  void ldx(Register rd, const MemOperand& src);
+  void ldu(Register rd, const MemOperand& src);
+  void ldux(Register rd, const MemOperand& src);
+  void std(Register rs, const MemOperand& src);
+  void stdx(Register rs, const MemOperand& src);
+  void stdu(Register rs, const MemOperand& src);
+  void stdux(Register rs, const MemOperand& src);
+  void rldic(Register dst, Register src, int sh, int mb, RCBit r = LeaveRC);
+  void rldicl(Register dst, Register src, int sh, int mb, RCBit r = LeaveRC);
+  void rldcl(Register ra, Register rs, Register rb, int mb, RCBit r = LeaveRC);
+  void rldicr(Register dst, Register src, int sh, int me, RCBit r = LeaveRC);
+  void rldimi(Register dst, Register src, int sh, int mb, RCBit r = LeaveRC);
+  void sldi(Register dst, Register src, const Operand& val, RCBit rc = LeaveRC);
+  void srdi(Register dst, Register src, const Operand& val, RCBit rc = LeaveRC);
+  void clrrdi(Register dst, Register src, const Operand& val,
+              RCBit rc = LeaveRC);
+  void clrldi(Register dst, Register src, const Operand& val,
+              RCBit rc = LeaveRC);
+  void sradi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
+  void srd(Register dst, Register src1, Register src2, RCBit r = LeaveRC);
+  void sld(Register dst, Register src1, Register src2, RCBit r = LeaveRC);
+  void srad(Register dst, Register src1, Register src2, RCBit r = LeaveRC);
+  void rotld(Register ra, Register rs, Register rb, RCBit r = LeaveRC);
+  void rotldi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
+  void rotrdi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
+  void cntlzd_(Register dst, Register src, RCBit rc = LeaveRC);
+  void extsw(Register rs, Register ra, RCBit r = LeaveRC);
+  void mulld(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
+             RCBit r = LeaveRC);
+  void divd(Register dst, Register src1, Register src2, OEBit o = LeaveOE,
+            RCBit r = LeaveRC);
+#endif
+
+  void rlwinm(Register ra, Register rs, int sh, int mb, int me,
+              RCBit rc = LeaveRC);
+  void rlwimi(Register ra, Register rs, int sh, int mb, int me,
+              RCBit rc = LeaveRC);
+  void rlwnm(Register ra, Register rs, Register rb, int mb, int me,
+             RCBit rc = LeaveRC);
+  void slwi(Register dst, Register src, const Operand& val, RCBit rc = LeaveRC);
+  void srwi(Register dst, Register src, const Operand& val, RCBit rc = LeaveRC);
+  void clrrwi(Register dst, Register src, const Operand& val,
+              RCBit rc = LeaveRC);
+  void clrlwi(Register dst, Register src, const Operand& val,
+              RCBit rc = LeaveRC);
+  void srawi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
+  void srw(Register dst, Register src1, Register src2, RCBit r = LeaveRC);
+  void slw(Register dst, Register src1, Register src2, RCBit r = LeaveRC);
+  void sraw(Register dst, Register src1, Register src2, RCBit r = LeaveRC);
+  void rotlw(Register ra, Register rs, Register rb, RCBit r = LeaveRC);
+  void rotlwi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
+  void rotrwi(Register ra, Register rs, int sh, RCBit r = LeaveRC);
+
+  void cntlzw_(Register dst, Register src, RCBit rc = LeaveRC);
+
+  void subi(Register dst, Register src1, const Operand& src2);
+
+  void cmp(Register src1, Register src2, CRegister cr = cr7);
+  void cmpl(Register src1, Register src2, CRegister cr = cr7);
+  void cmpw(Register src1, Register src2, CRegister cr = cr7);
+  void cmplw(Register src1, Register src2, CRegister cr = cr7);
+
+  void mov(Register dst, const Operand& src);
+
+  // Load the position of the label relative to the generated code object
+  // pointer in a register.
+  void mov_label_offset(Register dst, Label* label);
+
+  // Multiply instructions
+  void mul(Register dst, Register src1, Register src2, OEBit s = LeaveOE,
+           RCBit r = LeaveRC);
+
+  // Miscellaneous arithmetic instructions
+
+  // Special register access
+  void crxor(int bt, int ba, int bb);
+  void crclr(int bt) { crxor(bt, bt, bt); }
+  void creqv(int bt, int ba, int bb);
+  void crset(int bt) { creqv(bt, bt, bt); }
+  void mflr(Register dst);
+  void mtlr(Register src);
+  void mtctr(Register src);
+  void mtxer(Register src);
+  void mcrfs(int bf, int bfa);
+  void mfcr(Register dst);
+#if V8_TARGET_ARCH_PPC64
+  void mffprd(Register dst, DoubleRegister src);
+  void mffprwz(Register dst, DoubleRegister src);
+  void mtfprd(DoubleRegister dst, Register src);
+  void mtfprwz(DoubleRegister dst, Register src);
+  void mtfprwa(DoubleRegister dst, Register src);
+#endif
+
+  void fake_asm(enum FAKE_OPCODE_T fopcode);
+  void marker_asm(int mcode);
+  void function_descriptor();
+
+  // Exception-generating instructions and debugging support
+  void stop(const char* msg, Condition cond = al,
+            int32_t code = kDefaultStopCode, CRegister cr = cr7);
+
+  void bkpt(uint32_t imm16);  // v5 and above
+
+  // Informational messages when simulating
+  void info(const char* msg, Condition cond = al,
+            int32_t code = kDefaultStopCode, CRegister cr = cr7);
+
+  void dcbf(Register ra, Register rb);
+  void sync();
+  void lwsync();
+  void icbi(Register ra, Register rb);
+  void isync();
+
+  // Support for floating point
+  void lfd(const DoubleRegister frt, const MemOperand& src);
+  void lfdu(const DoubleRegister frt, const MemOperand& src);
+  void lfdx(const DoubleRegister frt, const MemOperand& src);
+  void lfdux(const DoubleRegister frt, const MemOperand& src);
+  void lfs(const DoubleRegister frt, const MemOperand& src);
+  void lfsu(const DoubleRegister frt, const MemOperand& src);
+  void lfsx(const DoubleRegister frt, const MemOperand& src);
+  void lfsux(const DoubleRegister frt, const MemOperand& src);
+  void stfd(const DoubleRegister frs, const MemOperand& src);
+  void stfdu(const DoubleRegister frs, const MemOperand& src);
+  void stfdx(const DoubleRegister frs, const MemOperand& src);
+  void stfdux(const DoubleRegister frs, const MemOperand& src);
+  void stfs(const DoubleRegister frs, const MemOperand& src);
+  void stfsu(const DoubleRegister frs, const MemOperand& src);
+  void stfsx(const DoubleRegister frs, const MemOperand& src);
+  void stfsux(const DoubleRegister frs, const MemOperand& src);
+
+  void fadd(const DoubleRegister frt, const DoubleRegister fra,
+            const DoubleRegister frb, RCBit rc = LeaveRC);
+  void fsub(const DoubleRegister frt, const DoubleRegister fra,
+            const DoubleRegister frb, RCBit rc = LeaveRC);
+  void fdiv(const DoubleRegister frt, const DoubleRegister fra,
+            const DoubleRegister frb, RCBit rc = LeaveRC);
+  void fmul(const DoubleRegister frt, const DoubleRegister fra,
+            const DoubleRegister frc, RCBit rc = LeaveRC);
+  void fcmpu(const DoubleRegister fra, const DoubleRegister frb,
+             CRegister cr = cr7);
+  void fmr(const DoubleRegister frt, const DoubleRegister frb,
+           RCBit rc = LeaveRC);
+  void fctiwz(const DoubleRegister frt, const DoubleRegister frb);
+  void fctiw(const DoubleRegister frt, const DoubleRegister frb);
+  void frim(const DoubleRegister frt, const DoubleRegister frb);
+  void frsp(const DoubleRegister frt, const DoubleRegister frb,
+            RCBit rc = LeaveRC);
+  void fcfid(const DoubleRegister frt, const DoubleRegister frb,
+             RCBit rc = LeaveRC);
+  void fctid(const DoubleRegister frt, const DoubleRegister frb,
+             RCBit rc = LeaveRC);
+  void fctidz(const DoubleRegister frt, const DoubleRegister frb,
+              RCBit rc = LeaveRC);
+  void fsel(const DoubleRegister frt, const DoubleRegister fra,
+            const DoubleRegister frc, const DoubleRegister frb,
+            RCBit rc = LeaveRC);
+  void fneg(const DoubleRegister frt, const DoubleRegister frb,
+            RCBit rc = LeaveRC);
+  void mtfsfi(int bf, int immediate, RCBit rc = LeaveRC);
+  void mffs(const DoubleRegister frt, RCBit rc = LeaveRC);
+  void mtfsf(const DoubleRegister frb, bool L = 1, int FLM = 0, bool W = 0,
+             RCBit rc = LeaveRC);
+  void fsqrt(const DoubleRegister frt, const DoubleRegister frb,
+             RCBit rc = LeaveRC);
+  void fabs(const DoubleRegister frt, const DoubleRegister frb,
+            RCBit rc = LeaveRC);
+  void fmadd(const DoubleRegister frt, const DoubleRegister fra,
+             const DoubleRegister frc, const DoubleRegister frb,
+             RCBit rc = LeaveRC);
+  void fmsub(const DoubleRegister frt, const DoubleRegister fra,
+             const DoubleRegister frc, const DoubleRegister frb,
+             RCBit rc = LeaveRC);
+
+  // Pseudo instructions
+
+  // Different nop operations are used by the code generator to detect certain
+  // states of the generated code.
+  enum NopMarkerTypes {
+    NON_MARKING_NOP = 0,
+    GROUP_ENDING_NOP,
+    DEBUG_BREAK_NOP,
+    // IC markers.
+    PROPERTY_ACCESS_INLINED,
+    PROPERTY_ACCESS_INLINED_CONTEXT,
+    PROPERTY_ACCESS_INLINED_CONTEXT_DONT_DELETE,
+    // Helper values.
+    LAST_CODE_MARKER,
+    FIRST_IC_MARKER = PROPERTY_ACCESS_INLINED
+  };
+
+  void nop(int type = 0);  // 0 is the default non-marking type.
+
+  void push(Register src) {
+#if V8_TARGET_ARCH_PPC64
+    stdu(src, MemOperand(sp, -kPointerSize));
+#else
+    stwu(src, MemOperand(sp, -kPointerSize));
+#endif
+  }
+
+  void pop(Register dst) {
+#if V8_TARGET_ARCH_PPC64
+    ld(dst, MemOperand(sp));
+#else
+    lwz(dst, MemOperand(sp));
+#endif
+    addi(sp, sp, Operand(kPointerSize));
+  }
+
+  void pop() { addi(sp, sp, Operand(kPointerSize)); }
+
+  // Jump unconditionally to given label.
+  void jmp(Label* L) { b(L); }
+
+  // Check the code size generated from label to here.
+  int SizeOfCodeGeneratedSince(Label* label) {
+    return pc_offset() - label->pos();
+  }
+
+  // Check the number of instructions generated from label to here.
+  int InstructionsGeneratedSince(Label* label) {
+    return SizeOfCodeGeneratedSince(label) / kInstrSize;
+  }
+
+  // Class for scoping postponing the trampoline pool generation.
+  class BlockTrampolinePoolScope {
+   public:
+    explicit BlockTrampolinePoolScope(Assembler* assem) : assem_(assem) {
+      assem_->StartBlockTrampolinePool();
+    }
+    ~BlockTrampolinePoolScope() { assem_->EndBlockTrampolinePool(); }
+
+   private:
+    Assembler* assem_;
+
+    DISALLOW_IMPLICIT_CONSTRUCTORS(BlockTrampolinePoolScope);
+  };
+
+  // Debugging
+
+  // Mark address of the ExitJSFrame code.
+  void RecordJSReturn();
+
+  // Mark address of a debug break slot.
+  void RecordDebugBreakSlot();
+
+  // Record the AST id of the CallIC being compiled, so that it can be placed
+  // in the relocation information.
+  void SetRecordedAstId(TypeFeedbackId ast_id) {
+    // Causes compiler to fail
+    // DCHECK(recorded_ast_id_.IsNone());
+    recorded_ast_id_ = ast_id;
+  }
+
+  TypeFeedbackId RecordedAstId() {
+    // Causes compiler to fail
+    // DCHECK(!recorded_ast_id_.IsNone());
+    return recorded_ast_id_;
+  }
+
+  void ClearRecordedAstId() { recorded_ast_id_ = TypeFeedbackId::None(); }
+
+  // Record a comment relocation entry that can be used by a disassembler.
+  // Use --code-comments to enable.
+  void RecordComment(const char* msg);
+
+  // Writes a single byte or word of data in the code stream.  Used
+  // for inline tables, e.g., jump-tables.
+  void db(uint8_t data);
+  void dd(uint32_t data);
+  void emit_ptr(uintptr_t data);
+
+  PositionsRecorder* positions_recorder() { return &positions_recorder_; }
+
+  // Read/patch instructions
+  Instr instr_at(int pos) { return *reinterpret_cast<Instr*>(buffer_ + pos); }
+  void instr_at_put(int pos, Instr instr) {
+    *reinterpret_cast<Instr*>(buffer_ + pos) = instr;
+  }
+  static Instr instr_at(byte* pc) { return *reinterpret_cast<Instr*>(pc); }
+  static void instr_at_put(byte* pc, Instr instr) {
+    *reinterpret_cast<Instr*>(pc) = instr;
+  }
+  static Condition GetCondition(Instr instr);
+
+  static bool IsLis(Instr instr);
+  static bool IsLi(Instr instr);
+  static bool IsAddic(Instr instr);
+  static bool IsOri(Instr instr);
+
+  static bool IsBranch(Instr instr);
+  static Register GetRA(Instr instr);
+  static Register GetRB(Instr instr);
+#if V8_TARGET_ARCH_PPC64
+  static bool Is64BitLoadIntoR12(Instr instr1, Instr instr2, Instr instr3,
+                                 Instr instr4, Instr instr5);
+#else
+  static bool Is32BitLoadIntoR12(Instr instr1, Instr instr2);
+#endif
+
+  static bool IsCmpRegister(Instr instr);
+  static bool IsCmpImmediate(Instr instr);
+  static bool IsRlwinm(Instr instr);
+#if V8_TARGET_ARCH_PPC64
+  static bool IsRldicl(Instr instr);
+#endif
+  static bool IsCrSet(Instr instr);
+  static Register GetCmpImmediateRegister(Instr instr);
+  static int GetCmpImmediateRawImmediate(Instr instr);
+  static bool IsNop(Instr instr, int type = NON_MARKING_NOP);
+
+  // Postpone the generation of the trampoline pool for the specified number of
+  // instructions.
+  void BlockTrampolinePoolFor(int instructions);
+  void CheckTrampolinePool();
+
+  int instructions_required_for_mov(const Operand& x) const;
+
+#if V8_OOL_CONSTANT_POOL
+  // Decide between using the constant pool vs. a mov immediate sequence.
+  bool use_constant_pool_for_mov(const Operand& x, bool canOptimize) const;
+
+  // The code currently calls CheckBuffer() too often. This has the side
+  // effect of randomly growing the buffer in the middle of multi-instruction
+  // sequences.
+  // MacroAssembler::LoadConstantPoolPointerRegister() includes a relocation
+  // and multiple instructions. We cannot grow the buffer until the
+  // relocation and all of the instructions are written.
+  //
+  // This function allows outside callers to check and grow the buffer
+  void EnsureSpaceFor(int space_needed);
+#endif
+
+  // Allocate a constant pool of the correct size for the generated code.
+  Handle<ConstantPoolArray> NewConstantPool(Isolate* isolate);
+
+  // Generate the constant pool for the generated code.
+  void PopulateConstantPool(ConstantPoolArray* constant_pool);
+
+#if V8_OOL_CONSTANT_POOL
+  bool is_constant_pool_full() const {
+    return constant_pool_builder_.is_full();
+  }
+
+  bool use_extended_constant_pool() const {
+    return constant_pool_builder_.current_section() ==
+           ConstantPoolArray::EXTENDED_SECTION;
+  }
+#endif
+
+#if ABI_USES_FUNCTION_DESCRIPTORS || V8_OOL_CONSTANT_POOL
+  static void RelocateInternalReference(
+      Address pc, intptr_t delta, Address code_start,
+      ICacheFlushMode icache_flush_mode = FLUSH_ICACHE_IF_NEEDED);
+  static int DecodeInternalReference(Vector<char> buffer, Address pc);
+#endif
+
+ protected:
+  // Relocation for a type-recording IC has the AST id added to it.  This
+  // member variable is a way to pass the information from the call site to
+  // the relocation info.
+  TypeFeedbackId recorded_ast_id_;
+
+  int buffer_space() const { return reloc_info_writer.pos() - pc_; }
+
+  // Decode branch instruction at pos and return branch target pos
+  int target_at(int pos);
+
+  // Patch branch instruction at pos to branch to given branch target pos
+  void target_at_put(int pos, int target_pos);
+
+  // Record reloc info for current pc_
+  void RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data = 0);
+  void RecordRelocInfo(const RelocInfo& rinfo);
+#if V8_OOL_CONSTANT_POOL
+  ConstantPoolArray::LayoutSection ConstantPoolAddEntry(
+      const RelocInfo& rinfo) {
+    return constant_pool_builder_.AddEntry(this, rinfo);
+  }
+#endif
+
+  // Block the emission of the trampoline pool before pc_offset.
+  void BlockTrampolinePoolBefore(int pc_offset) {
+    if (no_trampoline_pool_before_ < pc_offset)
+      no_trampoline_pool_before_ = pc_offset;
+  }
+
+  void StartBlockTrampolinePool() { trampoline_pool_blocked_nesting_++; }
+
+  void EndBlockTrampolinePool() { trampoline_pool_blocked_nesting_--; }
+
+  bool is_trampoline_pool_blocked() const {
+    return trampoline_pool_blocked_nesting_ > 0;
+  }
+
+  bool has_exception() const { return internal_trampoline_exception_; }
+
+  bool is_trampoline_emitted() const { return trampoline_emitted_; }
+
+#if V8_OOL_CONSTANT_POOL
+  void set_constant_pool_available(bool available) {
+    constant_pool_available_ = available;
+  }
+#endif
+
+ private:
+  // Code generation
+  // The relocation writer's position is at least kGap bytes below the end of
+  // the generated instructions. This is so that multi-instruction sequences do
+  // not have to check for overflow. The same is true for writes of large
+  // relocation info entries.
+  static const int kGap = 32;
+
+  // Repeated checking whether the trampoline pool should be emitted is rather
+  // expensive. By default we only check again once a number of instructions
+  // has been generated.
+  int next_buffer_check_;  // pc offset of next buffer check.
+
+  // Emission of the trampoline pool may be blocked in some code sequences.
+  int trampoline_pool_blocked_nesting_;  // Block emission if this is not zero.
+  int no_trampoline_pool_before_;  // Block emission before this pc offset.
+
+  // Relocation info generation
+  // Each relocation is encoded as a variable size value
+  static const int kMaxRelocSize = RelocInfoWriter::kMaxSize;
+  RelocInfoWriter reloc_info_writer;
+
+  // The bound position, before this we cannot do instruction elimination.
+  int last_bound_pos_;
+
+#if V8_OOL_CONSTANT_POOL
+  ConstantPoolBuilder constant_pool_builder_;
+#endif
+
+  // Code emission
+  inline void CheckBuffer();
+  void GrowBuffer();
+  inline void emit(Instr x);
+  inline void CheckTrampolinePoolQuick();
+
+  // Instruction generation
+  void a_form(Instr instr, DoubleRegister frt, DoubleRegister fra,
+              DoubleRegister frb, RCBit r);
+  void d_form(Instr instr, Register rt, Register ra, const intptr_t val,
+              bool signed_disp);
+  void x_form(Instr instr, Register ra, Register rs, Register rb, RCBit r);
+  void xo_form(Instr instr, Register rt, Register ra, Register rb, OEBit o,
+               RCBit r);
+  void md_form(Instr instr, Register ra, Register rs, int shift, int maskbit,
+               RCBit r);
+  void mds_form(Instr instr, Register ra, Register rs, Register rb, int maskbit,
+                RCBit r);
+
+  // Labels
+  void print(Label* L);
+  int max_reach_from(int pos);
+  void bind_to(Label* L, int pos);
+  void next(Label* L);
+
+  class Trampoline {
+   public:
+    Trampoline() {
+      next_slot_ = 0;
+      free_slot_count_ = 0;
+    }
+    Trampoline(int start, int slot_count) {
+      next_slot_ = start;
+      free_slot_count_ = slot_count;
+    }
+    int take_slot() {
+      int trampoline_slot = kInvalidSlotPos;
+      if (free_slot_count_ <= 0) {
+        // We have run out of space on trampolines.
+        // Make sure we fail in debug mode, so we become aware of each case
+        // when this happens.
+        DCHECK(0);
+        // Internal exception will be caught.
+      } else {
+        trampoline_slot = next_slot_;
+        free_slot_count_--;
+        next_slot_ += kTrampolineSlotsSize;
+      }
+      return trampoline_slot;
+    }
+
+   private:
+    int next_slot_;
+    int free_slot_count_;
+  };
+
+  int32_t get_trampoline_entry();
+  int unbound_labels_count_;
+  // If trampoline is emitted, generated code is becoming large. As
+  // this is already a slow case which can possibly break our code
+  // generation for the extreme case, we use this information to
+  // trigger different mode of branch instruction generation, where we
+  // no longer use a single branch instruction.
+  bool trampoline_emitted_;
+  static const int kTrampolineSlotsSize = kInstrSize;
+  static const int kMaxCondBranchReach = (1 << (16 - 1)) - 1;
+  static const int kMaxBlockTrampolineSectionSize = 64 * kInstrSize;
+  static const int kInvalidSlotPos = -1;
+
+  Trampoline trampoline_;
+  bool internal_trampoline_exception_;
+
+  friend class RegExpMacroAssemblerPPC;
+  friend class RelocInfo;
+  friend class CodePatcher;
+  friend class BlockTrampolinePoolScope;
+  PositionsRecorder positions_recorder_;
+  friend class PositionsRecorder;
+  friend class EnsureSpace;
+};
+
+
+class EnsureSpace BASE_EMBEDDED {
+ public:
+  explicit EnsureSpace(Assembler* assembler) { assembler->CheckBuffer(); }
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_PPC_ASSEMBLER_PPC_H_
diff --git a/src/ppc/builtins-ppc.cc b/src/ppc/builtins-ppc.cc
new file mode 100644
index 0000000..7817fcd
--- /dev/null
+++ b/src/ppc/builtins-ppc.cc
@@ -0,0 +1,1615 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/codegen.h"
+#include "src/debug.h"
+#include "src/deoptimizer.h"
+#include "src/full-codegen.h"
+#include "src/runtime/runtime.h"
+
+namespace v8 {
+namespace internal {
+
+
+#define __ ACCESS_MASM(masm)
+
+
+void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id,
+                                BuiltinExtraArguments extra_args) {
+  // ----------- S t a t e -------------
+  //  -- r3                 : number of arguments excluding receiver
+  //  -- r4                 : called function (only guaranteed when
+  //                          extra_args requires it)
+  //  -- cp                 : context
+  //  -- sp[0]              : last argument
+  //  -- ...
+  //  -- sp[4 * (argc - 1)] : first argument (argc == r0)
+  //  -- sp[4 * argc]       : receiver
+  // -----------------------------------
+
+  // Insert extra arguments.
+  int num_extra_args = 0;
+  if (extra_args == NEEDS_CALLED_FUNCTION) {
+    num_extra_args = 1;
+    __ push(r4);
+  } else {
+    DCHECK(extra_args == NO_EXTRA_ARGUMENTS);
+  }
+
+  // JumpToExternalReference expects r0 to contain the number of arguments
+  // including the receiver and the extra arguments.
+  __ addi(r3, r3, Operand(num_extra_args + 1));
+  __ JumpToExternalReference(ExternalReference(id, masm->isolate()));
+}
+
+
+// Load the built-in InternalArray function from the current context.
+static void GenerateLoadInternalArrayFunction(MacroAssembler* masm,
+                                              Register result) {
+  // Load the native context.
+
+  __ LoadP(result,
+           MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+  __ LoadP(result, FieldMemOperand(result, GlobalObject::kNativeContextOffset));
+  // Load the InternalArray function from the native context.
+  __ LoadP(result,
+           MemOperand(result, Context::SlotOffset(
+                                  Context::INTERNAL_ARRAY_FUNCTION_INDEX)));
+}
+
+
+// Load the built-in Array function from the current context.
+static void GenerateLoadArrayFunction(MacroAssembler* masm, Register result) {
+  // Load the native context.
+
+  __ LoadP(result,
+           MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+  __ LoadP(result, FieldMemOperand(result, GlobalObject::kNativeContextOffset));
+  // Load the Array function from the native context.
+  __ LoadP(
+      result,
+      MemOperand(result, Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
+}
+
+
+void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- r3     : number of arguments
+  //  -- lr     : return address
+  //  -- sp[...]: constructor arguments
+  // -----------------------------------
+  Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
+
+  // Get the InternalArray function.
+  GenerateLoadInternalArrayFunction(masm, r4);
+
+  if (FLAG_debug_code) {
+    // Initial map for the builtin InternalArray functions should be maps.
+    __ LoadP(r5, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset));
+    __ TestIfSmi(r5, r0);
+    __ Assert(ne, kUnexpectedInitialMapForInternalArrayFunction, cr0);
+    __ CompareObjectType(r5, r6, r7, MAP_TYPE);
+    __ Assert(eq, kUnexpectedInitialMapForInternalArrayFunction);
+  }
+
+  // Run the native code for the InternalArray function called as a normal
+  // function.
+  // tail call a stub
+  InternalArrayConstructorStub stub(masm->isolate());
+  __ TailCallStub(&stub);
+}
+
+
+void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- r3     : number of arguments
+  //  -- lr     : return address
+  //  -- sp[...]: constructor arguments
+  // -----------------------------------
+  Label generic_array_code, one_or_more_arguments, two_or_more_arguments;
+
+  // Get the Array function.
+  GenerateLoadArrayFunction(masm, r4);
+
+  if (FLAG_debug_code) {
+    // Initial map for the builtin Array functions should be maps.
+    __ LoadP(r5, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset));
+    __ TestIfSmi(r5, r0);
+    __ Assert(ne, kUnexpectedInitialMapForArrayFunction, cr0);
+    __ CompareObjectType(r5, r6, r7, MAP_TYPE);
+    __ Assert(eq, kUnexpectedInitialMapForArrayFunction);
+  }
+
+  // Run the native code for the Array function called as a normal function.
+  // tail call a stub
+  __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
+  ArrayConstructorStub stub(masm->isolate());
+  __ TailCallStub(&stub);
+}
+
+
+void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- r3                     : number of arguments
+  //  -- r4                     : constructor function
+  //  -- lr                     : return address
+  //  -- sp[(argc - n - 1) * 4] : arg[n] (zero based)
+  //  -- sp[argc * 4]           : receiver
+  // -----------------------------------
+  Counters* counters = masm->isolate()->counters();
+  __ IncrementCounter(counters->string_ctor_calls(), 1, r5, r6);
+
+  Register function = r4;
+  if (FLAG_debug_code) {
+    __ LoadGlobalFunction(Context::STRING_FUNCTION_INDEX, r5);
+    __ cmp(function, r5);
+    __ Assert(eq, kUnexpectedStringFunction);
+  }
+
+  // Load the first arguments in r3 and get rid of the rest.
+  Label no_arguments;
+  __ cmpi(r3, Operand::Zero());
+  __ beq(&no_arguments);
+  // First args = sp[(argc - 1) * 4].
+  __ subi(r3, r3, Operand(1));
+  __ ShiftLeftImm(r3, r3, Operand(kPointerSizeLog2));
+  __ add(sp, sp, r3);
+  __ LoadP(r3, MemOperand(sp));
+  // sp now point to args[0], drop args[0] + receiver.
+  __ Drop(2);
+
+  Register argument = r5;
+  Label not_cached, argument_is_string;
+  __ LookupNumberStringCache(r3,        // Input.
+                             argument,  // Result.
+                             r6,        // Scratch.
+                             r7,        // Scratch.
+                             r8,        // Scratch.
+                             &not_cached);
+  __ IncrementCounter(counters->string_ctor_cached_number(), 1, r6, r7);
+  __ bind(&argument_is_string);
+
+  // ----------- S t a t e -------------
+  //  -- r5     : argument converted to string
+  //  -- r4     : constructor function
+  //  -- lr     : return address
+  // -----------------------------------
+
+  Label gc_required;
+  __ Allocate(JSValue::kSize,
+              r3,  // Result.
+              r6,  // Scratch.
+              r7,  // Scratch.
+              &gc_required, TAG_OBJECT);
+
+  // Initialising the String Object.
+  Register map = r6;
+  __ LoadGlobalFunctionInitialMap(function, map, r7);
+  if (FLAG_debug_code) {
+    __ lbz(r7, FieldMemOperand(map, Map::kInstanceSizeOffset));
+    __ cmpi(r7, Operand(JSValue::kSize >> kPointerSizeLog2));
+    __ Assert(eq, kUnexpectedStringWrapperInstanceSize);
+    __ lbz(r7, FieldMemOperand(map, Map::kUnusedPropertyFieldsOffset));
+    __ cmpi(r7, Operand::Zero());
+    __ Assert(eq, kUnexpectedUnusedPropertiesOfStringWrapper);
+  }
+  __ StoreP(map, FieldMemOperand(r3, HeapObject::kMapOffset), r0);
+
+  __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex);
+  __ StoreP(r6, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0);
+  __ StoreP(r6, FieldMemOperand(r3, JSObject::kElementsOffset), r0);
+
+  __ StoreP(argument, FieldMemOperand(r3, JSValue::kValueOffset), r0);
+
+  // Ensure the object is fully initialized.
+  STATIC_ASSERT(JSValue::kSize == 4 * kPointerSize);
+
+  __ Ret();
+
+  // The argument was not found in the number to string cache. Check
+  // if it's a string already before calling the conversion builtin.
+  Label convert_argument;
+  __ bind(&not_cached);
+  __ JumpIfSmi(r3, &convert_argument);
+
+  // Is it a String?
+  __ LoadP(r5, FieldMemOperand(r3, HeapObject::kMapOffset));
+  __ lbz(r6, FieldMemOperand(r5, Map::kInstanceTypeOffset));
+  STATIC_ASSERT(kNotStringTag != 0);
+  __ andi(r0, r6, Operand(kIsNotStringMask));
+  __ bne(&convert_argument, cr0);
+  __ mr(argument, r3);
+  __ IncrementCounter(counters->string_ctor_conversions(), 1, r6, r7);
+  __ b(&argument_is_string);
+
+  // Invoke the conversion builtin and put the result into r5.
+  __ bind(&convert_argument);
+  __ push(function);  // Preserve the function.
+  __ IncrementCounter(counters->string_ctor_conversions(), 1, r6, r7);
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+    __ push(r3);
+    __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
+  }
+  __ pop(function);
+  __ mr(argument, r3);
+  __ b(&argument_is_string);
+
+  // Load the empty string into r5, remove the receiver from the
+  // stack, and jump back to the case where the argument is a string.
+  __ bind(&no_arguments);
+  __ LoadRoot(argument, Heap::kempty_stringRootIndex);
+  __ Drop(1);
+  __ b(&argument_is_string);
+
+  // At this point the argument is already a string. Call runtime to
+  // create a string wrapper.
+  __ bind(&gc_required);
+  __ IncrementCounter(counters->string_ctor_gc_required(), 1, r6, r7);
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+    __ push(argument);
+    __ CallRuntime(Runtime::kNewStringWrapper, 1);
+  }
+  __ Ret();
+}
+
+
+static void CallRuntimePassFunction(MacroAssembler* masm,
+                                    Runtime::FunctionId function_id) {
+  FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+  // Push a copy of the function onto the stack.
+  // Push function as parameter to the runtime call.
+  __ Push(r4, r4);
+
+  __ CallRuntime(function_id, 1);
+  // Restore reciever.
+  __ Pop(r4);
+}
+
+
+static void GenerateTailCallToSharedCode(MacroAssembler* masm) {
+  __ LoadP(ip, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
+  __ LoadP(ip, FieldMemOperand(ip, SharedFunctionInfo::kCodeOffset));
+  __ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ JumpToJSEntry(ip);
+}
+
+
+static void GenerateTailCallToReturnedCode(MacroAssembler* masm) {
+  __ addi(ip, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ JumpToJSEntry(ip);
+}
+
+
+void Builtins::Generate_InOptimizationQueue(MacroAssembler* masm) {
+  // Checking whether the queued function is ready for install is optional,
+  // since we come across interrupts and stack checks elsewhere.  However,
+  // not checking may delay installing ready functions, and always checking
+  // would be quite expensive.  A good compromise is to first check against
+  // stack limit as a cue for an interrupt signal.
+  Label ok;
+  __ LoadRoot(ip, Heap::kStackLimitRootIndex);
+  __ cmpl(sp, ip);
+  __ bge(&ok);
+
+  CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode);
+  GenerateTailCallToReturnedCode(masm);
+
+  __ bind(&ok);
+  GenerateTailCallToSharedCode(masm);
+}
+
+
+static void Generate_JSConstructStubHelper(MacroAssembler* masm,
+                                           bool is_api_function,
+                                           bool create_memento) {
+  // ----------- S t a t e -------------
+  //  -- r3     : number of arguments
+  //  -- r4     : constructor function
+  //  -- r5     : allocation site or undefined
+  //  -- lr     : return address
+  //  -- sp[...]: constructor arguments
+  // -----------------------------------
+
+  // Should never create mementos for api functions.
+  DCHECK(!is_api_function || !create_memento);
+
+  Isolate* isolate = masm->isolate();
+
+  // Enter a construct frame.
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
+
+    if (create_memento) {
+      __ AssertUndefinedOrAllocationSite(r5, r6);
+      __ push(r5);
+    }
+
+    // Preserve the two incoming parameters on the stack.
+    __ SmiTag(r3);
+    __ push(r3);  // Smi-tagged arguments count.
+    __ push(r4);  // Constructor function.
+
+    // Try to allocate the object without transitioning into C code. If any of
+    // the preconditions is not met, the code bails out to the runtime call.
+    Label rt_call, allocated;
+    if (FLAG_inline_new) {
+      Label undo_allocation;
+      ExternalReference debug_step_in_fp =
+          ExternalReference::debug_step_in_fp_address(isolate);
+      __ mov(r5, Operand(debug_step_in_fp));
+      __ LoadP(r5, MemOperand(r5));
+      __ cmpi(r5, Operand::Zero());
+      __ bne(&rt_call);
+
+      // Load the initial map and verify that it is in fact a map.
+      // r4: constructor function
+      __ LoadP(r5,
+               FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset));
+      __ JumpIfSmi(r5, &rt_call);
+      __ CompareObjectType(r5, r6, r7, MAP_TYPE);
+      __ bne(&rt_call);
+
+      // Check that the constructor is not constructing a JSFunction (see
+      // comments in Runtime_NewObject in runtime.cc). In which case the
+      // initial map's instance type would be JS_FUNCTION_TYPE.
+      // r4: constructor function
+      // r5: initial map
+      __ CompareInstanceType(r5, r6, JS_FUNCTION_TYPE);
+      __ beq(&rt_call);
+
+      if (!is_api_function) {
+        Label allocate;
+        MemOperand bit_field3 = FieldMemOperand(r5, Map::kBitField3Offset);
+        // Check if slack tracking is enabled.
+        __ lwz(r7, bit_field3);
+        __ DecodeField<Map::ConstructionCount>(r11, r7);
+        STATIC_ASSERT(JSFunction::kNoSlackTracking == 0);
+        __ cmpi(r11, Operand::Zero());  // JSFunction::kNoSlackTracking
+        __ beq(&allocate);
+        // Decrease generous allocation count.
+        __ Add(r7, r7, -(1 << Map::ConstructionCount::kShift), r0);
+        __ stw(r7, bit_field3);
+        __ cmpi(r11, Operand(JSFunction::kFinishSlackTracking));
+        __ bne(&allocate);
+
+        __ push(r4);
+
+        __ Push(r5, r4);  // r4 = constructor
+        __ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
+
+        __ Pop(r4, r5);
+
+        __ bind(&allocate);
+      }
+
+      // Now allocate the JSObject on the heap.
+      // r4: constructor function
+      // r5: initial map
+      __ lbz(r6, FieldMemOperand(r5, Map::kInstanceSizeOffset));
+      if (create_memento) {
+        __ addi(r6, r6, Operand(AllocationMemento::kSize / kPointerSize));
+      }
+
+      __ Allocate(r6, r7, r8, r9, &rt_call, SIZE_IN_WORDS);
+
+      // Allocated the JSObject, now initialize the fields. Map is set to
+      // initial map and properties and elements are set to empty fixed array.
+      // r4: constructor function
+      // r5: initial map
+      // r6: object size (not including memento if create_memento)
+      // r7: JSObject (not tagged)
+      __ LoadRoot(r9, Heap::kEmptyFixedArrayRootIndex);
+      __ mr(r8, r7);
+      __ StoreP(r5, MemOperand(r8, JSObject::kMapOffset));
+      __ StoreP(r9, MemOperand(r8, JSObject::kPropertiesOffset));
+      __ StoreP(r9, MemOperand(r8, JSObject::kElementsOffset));
+      __ addi(r8, r8, Operand(JSObject::kElementsOffset + kPointerSize));
+
+      __ ShiftLeftImm(r9, r6, Operand(kPointerSizeLog2));
+      __ add(r9, r7, r9);  // End of object.
+
+      // Fill all the in-object properties with the appropriate filler.
+      // r4: constructor function
+      // r5: initial map
+      // r6: object size (in words, including memento if create_memento)
+      // r7: JSObject (not tagged)
+      // r8: First in-object property of JSObject (not tagged)
+      // r9: End of object
+      DCHECK_EQ(3 * kPointerSize, JSObject::kHeaderSize);
+      __ LoadRoot(r10, Heap::kUndefinedValueRootIndex);
+
+      if (!is_api_function) {
+        Label no_inobject_slack_tracking;
+
+        // Check if slack tracking is enabled.
+        STATIC_ASSERT(JSFunction::kNoSlackTracking == 0);
+        __ cmpi(r11, Operand::Zero());  // JSFunction::kNoSlackTracking
+        __ beq(&no_inobject_slack_tracking);
+
+        // Allocate object with a slack.
+        __ lbz(r3, FieldMemOperand(r5, Map::kPreAllocatedPropertyFieldsOffset));
+        if (FLAG_debug_code) {
+          __ ShiftLeftImm(r0, r3, Operand(kPointerSizeLog2));
+          __ add(r0, r8, r0);
+          // r0: offset of first field after pre-allocated fields
+          __ cmp(r0, r9);
+          __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields);
+        }
+        {
+          Label done;
+          __ cmpi(r3, Operand::Zero());
+          __ beq(&done);
+          __ InitializeNFieldsWithFiller(r8, r3, r10);
+          __ bind(&done);
+        }
+        // To allow for truncation.
+        __ LoadRoot(r10, Heap::kOnePointerFillerMapRootIndex);
+        // Fill the remaining fields with one pointer filler map.
+
+        __ bind(&no_inobject_slack_tracking);
+      }
+
+      if (create_memento) {
+        __ subi(r3, r9, Operand(AllocationMemento::kSize));
+        __ InitializeFieldsWithFiller(r8, r3, r10);
+
+        // Fill in memento fields.
+        // r8: points to the allocated but uninitialized memento.
+        __ LoadRoot(r10, Heap::kAllocationMementoMapRootIndex);
+        __ StoreP(r10, MemOperand(r8, AllocationMemento::kMapOffset));
+        // Load the AllocationSite
+        __ LoadP(r10, MemOperand(sp, 2 * kPointerSize));
+        __ StoreP(r10,
+                  MemOperand(r8, AllocationMemento::kAllocationSiteOffset));
+        __ addi(r8, r8, Operand(AllocationMemento::kAllocationSiteOffset +
+                                kPointerSize));
+      } else {
+        __ InitializeFieldsWithFiller(r8, r9, r10);
+      }
+
+      // Add the object tag to make the JSObject real, so that we can continue
+      // and jump into the continuation code at any time from now on. Any
+      // failures need to undo the allocation, so that the heap is in a
+      // consistent state and verifiable.
+      __ addi(r7, r7, Operand(kHeapObjectTag));
+
+      // Check if a non-empty properties array is needed. Continue with
+      // allocated object if not fall through to runtime call if it is.
+      // r4: constructor function
+      // r7: JSObject
+      // r8: start of next object (not tagged)
+      __ lbz(r6, FieldMemOperand(r5, Map::kUnusedPropertyFieldsOffset));
+      // The field instance sizes contains both pre-allocated property fields
+      // and in-object properties.
+      __ lbz(r0, FieldMemOperand(r5, Map::kPreAllocatedPropertyFieldsOffset));
+      __ add(r6, r6, r0);
+      __ lbz(r0, FieldMemOperand(r5, Map::kInObjectPropertiesOffset));
+      __ sub(r6, r6, r0, LeaveOE, SetRC);
+
+      // Done if no extra properties are to be allocated.
+      __ beq(&allocated, cr0);
+      __ Assert(ge, kPropertyAllocationCountFailed, cr0);
+
+      // Scale the number of elements by pointer size and add the header for
+      // FixedArrays to the start of the next object calculation from above.
+      // r4: constructor
+      // r6: number of elements in properties array
+      // r7: JSObject
+      // r8: start of next object
+      __ addi(r3, r6, Operand(FixedArray::kHeaderSize / kPointerSize));
+      __ Allocate(
+          r3, r8, r9, r5, &undo_allocation,
+          static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | SIZE_IN_WORDS));
+
+      // Initialize the FixedArray.
+      // r4: constructor
+      // r6: number of elements in properties array
+      // r7: JSObject
+      // r8: FixedArray (not tagged)
+      __ LoadRoot(r9, Heap::kFixedArrayMapRootIndex);
+      __ mr(r5, r8);
+      DCHECK_EQ(0 * kPointerSize, JSObject::kMapOffset);
+      __ StoreP(r9, MemOperand(r5));
+      DCHECK_EQ(1 * kPointerSize, FixedArray::kLengthOffset);
+      __ SmiTag(r3, r6);
+      __ StoreP(r3, MemOperand(r5, kPointerSize));
+      __ addi(r5, r5, Operand(2 * kPointerSize));
+
+      // Initialize the fields to undefined.
+      // r4: constructor function
+      // r5: First element of FixedArray (not tagged)
+      // r6: number of elements in properties array
+      // r7: JSObject
+      // r8: FixedArray (not tagged)
+      DCHECK_EQ(2 * kPointerSize, FixedArray::kHeaderSize);
+      {
+        Label done;
+        __ cmpi(r6, Operand::Zero());
+        __ beq(&done);
+        if (!is_api_function || create_memento) {
+          __ LoadRoot(r10, Heap::kUndefinedValueRootIndex);
+        } else if (FLAG_debug_code) {
+          __ LoadRoot(r11, Heap::kUndefinedValueRootIndex);
+          __ cmp(r10, r11);
+          __ Assert(eq, kUndefinedValueNotLoaded);
+        }
+        __ InitializeNFieldsWithFiller(r5, r6, r10);
+        __ bind(&done);
+      }
+
+      // Store the initialized FixedArray into the properties field of
+      // the JSObject
+      // r4: constructor function
+      // r7: JSObject
+      // r8: FixedArray (not tagged)
+      __ addi(r8, r8, Operand(kHeapObjectTag));  // Add the heap tag.
+      __ StoreP(r8, FieldMemOperand(r7, JSObject::kPropertiesOffset), r0);
+
+      // Continue with JSObject being successfully allocated
+      // r4: constructor function
+      // r7: JSObject
+      __ b(&allocated);
+
+      // Undo the setting of the new top so that the heap is verifiable. For
+      // example, the map's unused properties potentially do not match the
+      // allocated objects unused properties.
+      // r7: JSObject (previous new top)
+      __ bind(&undo_allocation);
+      __ UndoAllocationInNewSpace(r7, r8);
+    }
+
+    // Allocate the new receiver object using the runtime call.
+    // r4: constructor function
+    __ bind(&rt_call);
+    if (create_memento) {
+      // Get the cell or allocation site.
+      __ LoadP(r5, MemOperand(sp, 2 * kPointerSize));
+      __ push(r5);
+    }
+
+    __ push(r4);  // argument for Runtime_NewObject
+    if (create_memento) {
+      __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 2);
+    } else {
+      __ CallRuntime(Runtime::kNewObject, 1);
+    }
+    __ mr(r7, r3);
+
+    // If we ended up using the runtime, and we want a memento, then the
+    // runtime call made it for us, and we shouldn't do create count
+    // increment.
+    Label count_incremented;
+    if (create_memento) {
+      __ b(&count_incremented);
+    }
+
+    // Receiver for constructor call allocated.
+    // r7: JSObject
+    __ bind(&allocated);
+
+    if (create_memento) {
+      __ LoadP(r5, MemOperand(sp, kPointerSize * 2));
+      __ LoadRoot(r8, Heap::kUndefinedValueRootIndex);
+      __ cmp(r5, r8);
+      __ beq(&count_incremented);
+      // r5 is an AllocationSite. We are creating a memento from it, so we
+      // need to increment the memento create count.
+      __ LoadP(
+          r6, FieldMemOperand(r5, AllocationSite::kPretenureCreateCountOffset));
+      __ AddSmiLiteral(r6, r6, Smi::FromInt(1), r0);
+      __ StoreP(
+          r6, FieldMemOperand(r5, AllocationSite::kPretenureCreateCountOffset),
+          r0);
+      __ bind(&count_incremented);
+    }
+
+    __ Push(r7, r7);
+
+    // Reload the number of arguments and the constructor from the stack.
+    // sp[0]: receiver
+    // sp[1]: receiver
+    // sp[2]: constructor function
+    // sp[3]: number of arguments (smi-tagged)
+    __ LoadP(r4, MemOperand(sp, 2 * kPointerSize));
+    __ LoadP(r6, MemOperand(sp, 3 * kPointerSize));
+
+    // Set up pointer to last argument.
+    __ addi(r5, fp, Operand(StandardFrameConstants::kCallerSPOffset));
+
+    // Set up number of arguments for function call below
+    __ SmiUntag(r3, r6);
+
+    // Copy arguments and receiver to the expression stack.
+    // r3: number of arguments
+    // r4: constructor function
+    // r5: address of last argument (caller sp)
+    // r6: number of arguments (smi-tagged)
+    // sp[0]: receiver
+    // sp[1]: receiver
+    // sp[2]: constructor function
+    // sp[3]: number of arguments (smi-tagged)
+    Label loop, no_args;
+    __ cmpi(r3, Operand::Zero());
+    __ beq(&no_args);
+    __ ShiftLeftImm(ip, r3, Operand(kPointerSizeLog2));
+    __ mtctr(r3);
+    __ bind(&loop);
+    __ subi(ip, ip, Operand(kPointerSize));
+    __ LoadPX(r0, MemOperand(r5, ip));
+    __ push(r0);
+    __ bdnz(&loop);
+    __ bind(&no_args);
+
+    // Call the function.
+    // r3: number of arguments
+    // r4: constructor function
+    if (is_api_function) {
+      __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
+      Handle<Code> code = masm->isolate()->builtins()->HandleApiCallConstruct();
+      __ Call(code, RelocInfo::CODE_TARGET);
+    } else {
+      ParameterCount actual(r3);
+      __ InvokeFunction(r4, actual, CALL_FUNCTION, NullCallWrapper());
+    }
+
+    // Store offset of return address for deoptimizer.
+    if (!is_api_function) {
+      masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
+    }
+
+    // Restore context from the frame.
+    // r3: result
+    // sp[0]: receiver
+    // sp[1]: constructor function
+    // sp[2]: number of arguments (smi-tagged)
+    __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+
+    // If the result is an object (in the ECMA sense), we should get rid
+    // of the receiver and use the result; see ECMA-262 section 13.2.2-7
+    // on page 74.
+    Label use_receiver, exit;
+
+    // If the result is a smi, it is *not* an object in the ECMA sense.
+    // r3: result
+    // sp[0]: receiver (newly allocated object)
+    // sp[1]: constructor function
+    // sp[2]: number of arguments (smi-tagged)
+    __ JumpIfSmi(r3, &use_receiver);
+
+    // If the type of the result (stored in its map) is less than
+    // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
+    __ CompareObjectType(r3, r4, r6, FIRST_SPEC_OBJECT_TYPE);
+    __ bge(&exit);
+
+    // Throw away the result of the constructor invocation and use the
+    // on-stack receiver as the result.
+    __ bind(&use_receiver);
+    __ LoadP(r3, MemOperand(sp));
+
+    // Remove receiver from the stack, remove caller arguments, and
+    // return.
+    __ bind(&exit);
+    // r3: result
+    // sp[0]: receiver (newly allocated object)
+    // sp[1]: constructor function
+    // sp[2]: number of arguments (smi-tagged)
+    __ LoadP(r4, MemOperand(sp, 2 * kPointerSize));
+
+    // Leave construct frame.
+  }
+
+  __ SmiToPtrArrayOffset(r4, r4);
+  __ add(sp, sp, r4);
+  __ addi(sp, sp, Operand(kPointerSize));
+  __ IncrementCounter(isolate->counters()->constructed_objects(), 1, r4, r5);
+  __ blr();
+}
+
+
+void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
+  Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new);
+}
+
+
+void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
+  Generate_JSConstructStubHelper(masm, true, false);
+}
+
+
+static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
+                                             bool is_construct) {
+  // Called from Generate_JS_Entry
+  // r3: code entry
+  // r4: function
+  // r5: receiver
+  // r6: argc
+  // r7: argv
+  // r0,r8-r9, cp may be clobbered
+  ProfileEntryHookStub::MaybeCallEntryHook(masm);
+
+  // Clear the context before we push it when entering the internal frame.
+  __ li(cp, Operand::Zero());
+
+  // Enter an internal frame.
+  {
+    FrameScope scope(masm, StackFrame::INTERNAL);
+
+    // Set up the context from the function argument.
+    __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
+
+    __ InitializeRootRegister();
+
+    // Push the function and the receiver onto the stack.
+    __ push(r4);
+    __ push(r5);
+
+    // Copy arguments to the stack in a loop.
+    // r4: function
+    // r6: argc
+    // r7: argv, i.e. points to first arg
+    Label loop, entry;
+    __ ShiftLeftImm(r0, r6, Operand(kPointerSizeLog2));
+    __ add(r5, r7, r0);
+    // r5 points past last arg.
+    __ b(&entry);
+    __ bind(&loop);
+    __ LoadP(r8, MemOperand(r7));  // read next parameter
+    __ addi(r7, r7, Operand(kPointerSize));
+    __ LoadP(r0, MemOperand(r8));  // dereference handle
+    __ push(r0);                   // push parameter
+    __ bind(&entry);
+    __ cmp(r7, r5);
+    __ bne(&loop);
+
+    // Initialize all JavaScript callee-saved registers, since they will be seen
+    // by the garbage collector as part of handlers.
+    __ LoadRoot(r7, Heap::kUndefinedValueRootIndex);
+    __ mr(r14, r7);
+    __ mr(r15, r7);
+    __ mr(r16, r7);
+    __ mr(r17, r7);
+
+    // Invoke the code and pass argc as r3.
+    __ mr(r3, r6);
+    if (is_construct) {
+      // No type feedback cell is available
+      __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
+      CallConstructStub stub(masm->isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
+      __ CallStub(&stub);
+    } else {
+      ParameterCount actual(r3);
+      __ InvokeFunction(r4, actual, CALL_FUNCTION, NullCallWrapper());
+    }
+    // Exit the JS frame and remove the parameters (except function), and
+    // return.
+  }
+  __ blr();
+
+  // r3: result
+}
+
+
+void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
+  Generate_JSEntryTrampolineHelper(masm, false);
+}
+
+
+void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
+  Generate_JSEntryTrampolineHelper(masm, true);
+}
+
+
+void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
+  CallRuntimePassFunction(masm, Runtime::kCompileLazy);
+  GenerateTailCallToReturnedCode(masm);
+}
+
+
+static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) {
+  FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+  // Push a copy of the function onto the stack.
+  // Push function as parameter to the runtime call.
+  __ Push(r4, r4);
+  // Whether to compile in a background thread.
+  __ Push(masm->isolate()->factory()->ToBoolean(concurrent));
+
+  __ CallRuntime(Runtime::kCompileOptimized, 2);
+  // Restore receiver.
+  __ pop(r4);
+}
+
+
+void Builtins::Generate_CompileOptimized(MacroAssembler* masm) {
+  CallCompileOptimized(masm, false);
+  GenerateTailCallToReturnedCode(masm);
+}
+
+
+void Builtins::Generate_CompileOptimizedConcurrent(MacroAssembler* masm) {
+  CallCompileOptimized(masm, true);
+  GenerateTailCallToReturnedCode(masm);
+}
+
+
+static void GenerateMakeCodeYoungAgainCommon(MacroAssembler* masm) {
+  // For now, we are relying on the fact that make_code_young doesn't do any
+  // garbage collection which allows us to save/restore the registers without
+  // worrying about which of them contain pointers. We also don't build an
+  // internal frame to make the code faster, since we shouldn't have to do stack
+  // crawls in MakeCodeYoung. This seems a bit fragile.
+
+  // Point r3 at the start of the PlatformCodeAge sequence.
+  __ mr(r3, ip);
+
+  // The following registers must be saved and restored when calling through to
+  // the runtime:
+  //   r3 - contains return address (beginning of patch sequence)
+  //   r4 - isolate
+  //   lr - return address
+  FrameScope scope(masm, StackFrame::MANUAL);
+  __ mflr(r0);
+  __ MultiPush(r0.bit() | r3.bit() | r4.bit() | fp.bit());
+  __ PrepareCallCFunction(2, 0, r5);
+  __ mov(r4, Operand(ExternalReference::isolate_address(masm->isolate())));
+  __ CallCFunction(
+      ExternalReference::get_make_code_young_function(masm->isolate()), 2);
+  __ MultiPop(r0.bit() | r3.bit() | r4.bit() | fp.bit());
+  __ mtlr(r0);
+  __ mr(ip, r3);
+  __ Jump(ip);
+}
+
+#define DEFINE_CODE_AGE_BUILTIN_GENERATOR(C)                  \
+  void Builtins::Generate_Make##C##CodeYoungAgainEvenMarking( \
+      MacroAssembler* masm) {                                 \
+    GenerateMakeCodeYoungAgainCommon(masm);                   \
+  }                                                           \
+  void Builtins::Generate_Make##C##CodeYoungAgainOddMarking(  \
+      MacroAssembler* masm) {                                 \
+    GenerateMakeCodeYoungAgainCommon(masm);                   \
+  }
+CODE_AGE_LIST(DEFINE_CODE_AGE_BUILTIN_GENERATOR)
+#undef DEFINE_CODE_AGE_BUILTIN_GENERATOR
+
+
+void Builtins::Generate_MarkCodeAsExecutedOnce(MacroAssembler* masm) {
+  // For now, we are relying on the fact that make_code_young doesn't do any
+  // garbage collection which allows us to save/restore the registers without
+  // worrying about which of them contain pointers. We also don't build an
+  // internal frame to make the code faster, since we shouldn't have to do stack
+  // crawls in MakeCodeYoung. This seems a bit fragile.
+
+  // Point r3 at the start of the PlatformCodeAge sequence.
+  __ mr(r3, ip);
+
+  // The following registers must be saved and restored when calling through to
+  // the runtime:
+  //   r3 - contains return address (beginning of patch sequence)
+  //   r4 - isolate
+  //   lr - return address
+  FrameScope scope(masm, StackFrame::MANUAL);
+  __ mflr(r0);
+  __ MultiPush(r0.bit() | r3.bit() | r4.bit() | fp.bit());
+  __ PrepareCallCFunction(2, 0, r5);
+  __ mov(r4, Operand(ExternalReference::isolate_address(masm->isolate())));
+  __ CallCFunction(
+      ExternalReference::get_mark_code_as_executed_function(masm->isolate()),
+      2);
+  __ MultiPop(r0.bit() | r3.bit() | r4.bit() | fp.bit());
+  __ mtlr(r0);
+  __ mr(ip, r3);
+
+  // Perform prologue operations usually performed by the young code stub.
+  __ PushFixedFrame(r4);
+  __ addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
+
+  // Jump to point after the code-age stub.
+  __ addi(r3, ip, Operand(kNoCodeAgeSequenceLength));
+  __ Jump(r3);
+}
+
+
+void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
+  GenerateMakeCodeYoungAgainCommon(masm);
+}
+
+
+static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
+                                             SaveFPRegsMode save_doubles) {
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+
+    // Preserve registers across notification, this is important for compiled
+    // stubs that tail call the runtime on deopts passing their parameters in
+    // registers.
+    __ MultiPush(kJSCallerSaved | kCalleeSaved);
+    // Pass the function and deoptimization type to the runtime system.
+    __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles);
+    __ MultiPop(kJSCallerSaved | kCalleeSaved);
+  }
+
+  __ addi(sp, sp, Operand(kPointerSize));  // Ignore state
+  __ blr();                                // Jump to miss handler
+}
+
+
+void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) {
+  Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs);
+}
+
+
+void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
+  Generate_NotifyStubFailureHelper(masm, kSaveFPRegs);
+}
+
+
+static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
+                                             Deoptimizer::BailoutType type) {
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+    // Pass the function and deoptimization type to the runtime system.
+    __ LoadSmiLiteral(r3, Smi::FromInt(static_cast<int>(type)));
+    __ push(r3);
+    __ CallRuntime(Runtime::kNotifyDeoptimized, 1);
+  }
+
+  // Get the full codegen state from the stack and untag it -> r9.
+  __ LoadP(r9, MemOperand(sp, 0 * kPointerSize));
+  __ SmiUntag(r9);
+  // Switch on the state.
+  Label with_tos_register, unknown_state;
+  __ cmpi(r9, Operand(FullCodeGenerator::NO_REGISTERS));
+  __ bne(&with_tos_register);
+  __ addi(sp, sp, Operand(1 * kPointerSize));  // Remove state.
+  __ Ret();
+
+  __ bind(&with_tos_register);
+  __ LoadP(r3, MemOperand(sp, 1 * kPointerSize));
+  __ cmpi(r9, Operand(FullCodeGenerator::TOS_REG));
+  __ bne(&unknown_state);
+  __ addi(sp, sp, Operand(2 * kPointerSize));  // Remove state.
+  __ Ret();
+
+  __ bind(&unknown_state);
+  __ stop("no cases left");
+}
+
+
+void Builtins::Generate_NotifyDeoptimized(MacroAssembler* masm) {
+  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
+}
+
+
+void Builtins::Generate_NotifySoftDeoptimized(MacroAssembler* masm) {
+  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
+}
+
+
+void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
+  Generate_NotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
+}
+
+
+void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
+  // Lookup the function in the JavaScript frame.
+  __ LoadP(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+    // Pass function as argument.
+    __ push(r3);
+    __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
+  }
+
+  // If the code object is null, just return to the unoptimized code.
+  Label skip;
+  __ CmpSmiLiteral(r3, Smi::FromInt(0), r0);
+  __ bne(&skip);
+  __ Ret();
+
+  __ bind(&skip);
+
+  // Load deoptimization data from the code object.
+  // <deopt_data> = <code>[#deoptimization_data_offset]
+  __ LoadP(r4, FieldMemOperand(r3, Code::kDeoptimizationDataOffset));
+
+#if V8_OOL_CONSTANT_POOL
+  {
+    ConstantPoolUnavailableScope constant_pool_unavailable(masm);
+    __ LoadP(kConstantPoolRegister,
+             FieldMemOperand(r3, Code::kConstantPoolOffset));
+#endif
+
+    // Load the OSR entrypoint offset from the deoptimization data.
+    // <osr_offset> = <deopt_data>[#header_size + #osr_pc_offset]
+    __ LoadP(r4, FieldMemOperand(
+                     r4, FixedArray::OffsetOfElementAt(
+                             DeoptimizationInputData::kOsrPcOffsetIndex)));
+    __ SmiUntag(r4);
+
+    // Compute the target address = code_obj + header_size + osr_offset
+    // <entry_addr> = <code_obj> + #header_size + <osr_offset>
+    __ add(r3, r3, r4);
+    __ addi(r0, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
+    __ mtlr(r0);
+
+    // And "return" to the OSR entry point of the function.
+    __ Ret();
+#if V8_OOL_CONSTANT_POOL
+  }
+#endif
+}
+
+
+void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) {
+  // We check the stack limit as indicator that recompilation might be done.
+  Label ok;
+  __ LoadRoot(ip, Heap::kStackLimitRootIndex);
+  __ cmpl(sp, ip);
+  __ bge(&ok);
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+    __ CallRuntime(Runtime::kStackGuard, 0);
+  }
+  __ Jump(masm->isolate()->builtins()->OnStackReplacement(),
+          RelocInfo::CODE_TARGET);
+
+  __ bind(&ok);
+  __ Ret();
+}
+
+
+void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
+  // 1. Make sure we have at least one argument.
+  // r3: actual number of arguments
+  {
+    Label done;
+    __ cmpi(r3, Operand::Zero());
+    __ bne(&done);
+    __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
+    __ push(r5);
+    __ addi(r3, r3, Operand(1));
+    __ bind(&done);
+  }
+
+  // 2. Get the function to call (passed as receiver) from the stack, check
+  //    if it is a function.
+  // r3: actual number of arguments
+  Label slow, non_function;
+  __ ShiftLeftImm(r4, r3, Operand(kPointerSizeLog2));
+  __ add(r4, sp, r4);
+  __ LoadP(r4, MemOperand(r4));
+  __ JumpIfSmi(r4, &non_function);
+  __ CompareObjectType(r4, r5, r5, JS_FUNCTION_TYPE);
+  __ bne(&slow);
+
+  // 3a. Patch the first argument if necessary when calling a function.
+  // r3: actual number of arguments
+  // r4: function
+  Label shift_arguments;
+  __ li(r7, Operand::Zero());  // indicate regular JS_FUNCTION
+  {
+    Label convert_to_object, use_global_proxy, patch_receiver;
+    // Change context eagerly in case we need the global receiver.
+    __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
+
+    // Do not transform the receiver for strict mode functions.
+    __ LoadP(r5, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
+    __ lwz(r6, FieldMemOperand(r5, SharedFunctionInfo::kCompilerHintsOffset));
+    __ TestBit(r6,
+#if V8_TARGET_ARCH_PPC64
+               SharedFunctionInfo::kStrictModeFunction,
+#else
+               SharedFunctionInfo::kStrictModeFunction + kSmiTagSize,
+#endif
+               r0);
+    __ bne(&shift_arguments, cr0);
+
+    // Do not transform the receiver for native (Compilerhints already in r6).
+    __ TestBit(r6,
+#if V8_TARGET_ARCH_PPC64
+               SharedFunctionInfo::kNative,
+#else
+               SharedFunctionInfo::kNative + kSmiTagSize,
+#endif
+               r0);
+    __ bne(&shift_arguments, cr0);
+
+    // Compute the receiver in sloppy mode.
+    __ ShiftLeftImm(ip, r3, Operand(kPointerSizeLog2));
+    __ add(r5, sp, ip);
+    __ LoadP(r5, MemOperand(r5, -kPointerSize));
+    // r3: actual number of arguments
+    // r4: function
+    // r5: first argument
+    __ JumpIfSmi(r5, &convert_to_object);
+
+    __ LoadRoot(r6, Heap::kUndefinedValueRootIndex);
+    __ cmp(r5, r6);
+    __ beq(&use_global_proxy);
+    __ LoadRoot(r6, Heap::kNullValueRootIndex);
+    __ cmp(r5, r6);
+    __ beq(&use_global_proxy);
+
+    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+    __ CompareObjectType(r5, r6, r6, FIRST_SPEC_OBJECT_TYPE);
+    __ bge(&shift_arguments);
+
+    __ bind(&convert_to_object);
+
+    {
+      // Enter an internal frame in order to preserve argument count.
+      FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+      __ SmiTag(r3);
+      __ Push(r3, r5);
+      __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
+      __ mr(r5, r3);
+
+      __ pop(r3);
+      __ SmiUntag(r3);
+
+      // Exit the internal frame.
+    }
+
+    // Restore the function to r4, and the flag to r7.
+    __ ShiftLeftImm(r7, r3, Operand(kPointerSizeLog2));
+    __ add(r7, sp, r7);
+    __ LoadP(r4, MemOperand(r7));
+    __ li(r7, Operand::Zero());
+    __ b(&patch_receiver);
+
+    __ bind(&use_global_proxy);
+    __ LoadP(r5, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+    __ LoadP(r5, FieldMemOperand(r5, GlobalObject::kGlobalProxyOffset));
+
+    __ bind(&patch_receiver);
+    __ ShiftLeftImm(ip, r3, Operand(kPointerSizeLog2));
+    __ add(r6, sp, ip);
+    __ StoreP(r5, MemOperand(r6, -kPointerSize));
+
+    __ b(&shift_arguments);
+  }
+
+  // 3b. Check for function proxy.
+  __ bind(&slow);
+  __ li(r7, Operand(1, RelocInfo::NONE32));  // indicate function proxy
+  __ cmpi(r5, Operand(JS_FUNCTION_PROXY_TYPE));
+  __ beq(&shift_arguments);
+  __ bind(&non_function);
+  __ li(r7, Operand(2, RelocInfo::NONE32));  // indicate non-function
+
+  // 3c. Patch the first argument when calling a non-function.  The
+  //     CALL_NON_FUNCTION builtin expects the non-function callee as
+  //     receiver, so overwrite the first argument which will ultimately
+  //     become the receiver.
+  // r3: actual number of arguments
+  // r4: function
+  // r7: call type (0: JS function, 1: function proxy, 2: non-function)
+  __ ShiftLeftImm(ip, r3, Operand(kPointerSizeLog2));
+  __ add(r5, sp, ip);
+  __ StoreP(r4, MemOperand(r5, -kPointerSize));
+
+  // 4. Shift arguments and return address one slot down on the stack
+  //    (overwriting the original receiver).  Adjust argument count to make
+  //    the original first argument the new receiver.
+  // r3: actual number of arguments
+  // r4: function
+  // r7: call type (0: JS function, 1: function proxy, 2: non-function)
+  __ bind(&shift_arguments);
+  {
+    Label loop;
+    // Calculate the copy start address (destination). Copy end address is sp.
+    __ ShiftLeftImm(ip, r3, Operand(kPointerSizeLog2));
+    __ add(r5, sp, ip);
+
+    __ bind(&loop);
+    __ LoadP(ip, MemOperand(r5, -kPointerSize));
+    __ StoreP(ip, MemOperand(r5));
+    __ subi(r5, r5, Operand(kPointerSize));
+    __ cmp(r5, sp);
+    __ bne(&loop);
+    // Adjust the actual number of arguments and remove the top element
+    // (which is a copy of the last argument).
+    __ subi(r3, r3, Operand(1));
+    __ pop();
+  }
+
+  // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin,
+  //     or a function proxy via CALL_FUNCTION_PROXY.
+  // r3: actual number of arguments
+  // r4: function
+  // r7: call type (0: JS function, 1: function proxy, 2: non-function)
+  {
+    Label function, non_proxy;
+    __ cmpi(r7, Operand::Zero());
+    __ beq(&function);
+    // Expected number of arguments is 0 for CALL_NON_FUNCTION.
+    __ li(r5, Operand::Zero());
+    __ cmpi(r7, Operand(1));
+    __ bne(&non_proxy);
+
+    __ push(r4);  // re-add proxy object as additional argument
+    __ addi(r3, r3, Operand(1));
+    __ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY);
+    __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+            RelocInfo::CODE_TARGET);
+
+    __ bind(&non_proxy);
+    __ GetBuiltinFunction(r4, Builtins::CALL_NON_FUNCTION);
+    __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+            RelocInfo::CODE_TARGET);
+    __ bind(&function);
+  }
+
+  // 5b. Get the code to call from the function and check that the number of
+  //     expected arguments matches what we're providing.  If so, jump
+  //     (tail-call) to the code in register edx without checking arguments.
+  // r3: actual number of arguments
+  // r4: function
+  __ LoadP(r6, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
+  __ LoadWordArith(
+      r5, FieldMemOperand(r6, SharedFunctionInfo::kFormalParameterCountOffset));
+#if !V8_TARGET_ARCH_PPC64
+  __ SmiUntag(r5);
+#endif
+  __ cmp(r5, r3);  // Check formal and actual parameter counts.
+  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+          RelocInfo::CODE_TARGET, ne);
+
+  __ LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
+  ParameterCount expected(0);
+  __ InvokeCode(ip, expected, expected, JUMP_FUNCTION, NullCallWrapper());
+}
+
+
+void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
+  const int kIndexOffset =
+      StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize);
+  const int kLimitOffset =
+      StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize);
+  const int kArgsOffset = 2 * kPointerSize;
+  const int kRecvOffset = 3 * kPointerSize;
+  const int kFunctionOffset = 4 * kPointerSize;
+
+  {
+    FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
+
+    __ LoadP(r3, MemOperand(fp, kFunctionOffset));  // get the function
+    __ push(r3);
+    __ LoadP(r3, MemOperand(fp, kArgsOffset));  // get the args array
+    __ push(r3);
+    __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
+
+    // Check the stack for overflow. We are not trying to catch
+    // interruptions (e.g. debug break and preemption) here, so the "real stack
+    // limit" is checked.
+    Label okay;
+    __ LoadRoot(r5, Heap::kRealStackLimitRootIndex);
+    // Make r5 the space we have left. The stack might already be overflowed
+    // here which will cause r5 to become negative.
+    __ sub(r5, sp, r5);
+    // Check if the arguments will overflow the stack.
+    __ SmiToPtrArrayOffset(r0, r3);
+    __ cmp(r5, r0);
+    __ bgt(&okay);  // Signed comparison.
+
+    // Out of stack space.
+    __ LoadP(r4, MemOperand(fp, kFunctionOffset));
+    __ Push(r4, r3);
+    __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
+    // End of stack check.
+
+    // Push current limit and index.
+    __ bind(&okay);
+    __ li(r4, Operand::Zero());
+    __ Push(r3, r4);  // limit and initial index.
+
+    // Get the receiver.
+    __ LoadP(r3, MemOperand(fp, kRecvOffset));
+
+    // Check that the function is a JS function (otherwise it must be a proxy).
+    Label push_receiver;
+    __ LoadP(r4, MemOperand(fp, kFunctionOffset));
+    __ CompareObjectType(r4, r5, r5, JS_FUNCTION_TYPE);
+    __ bne(&push_receiver);
+
+    // Change context eagerly to get the right global object if necessary.
+    __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
+    // Load the shared function info while the function is still in r4.
+    __ LoadP(r5, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
+
+    // Compute the receiver.
+    // Do not transform the receiver for strict mode functions.
+    Label call_to_object, use_global_proxy;
+    __ lwz(r5, FieldMemOperand(r5, SharedFunctionInfo::kCompilerHintsOffset));
+    __ TestBit(r5,
+#if V8_TARGET_ARCH_PPC64
+               SharedFunctionInfo::kStrictModeFunction,
+#else
+               SharedFunctionInfo::kStrictModeFunction + kSmiTagSize,
+#endif
+               r0);
+    __ bne(&push_receiver, cr0);
+
+    // Do not transform the receiver for strict mode functions.
+    __ TestBit(r5,
+#if V8_TARGET_ARCH_PPC64
+               SharedFunctionInfo::kNative,
+#else
+               SharedFunctionInfo::kNative + kSmiTagSize,
+#endif
+               r0);
+    __ bne(&push_receiver, cr0);
+
+    // Compute the receiver in sloppy mode.
+    __ JumpIfSmi(r3, &call_to_object);
+    __ LoadRoot(r4, Heap::kNullValueRootIndex);
+    __ cmp(r3, r4);
+    __ beq(&use_global_proxy);
+    __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
+    __ cmp(r3, r4);
+    __ beq(&use_global_proxy);
+
+    // Check if the receiver is already a JavaScript object.
+    // r3: receiver
+    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+    __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE);
+    __ bge(&push_receiver);
+
+    // Convert the receiver to a regular object.
+    // r3: receiver
+    __ bind(&call_to_object);
+    __ push(r3);
+    __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
+    __ b(&push_receiver);
+
+    __ bind(&use_global_proxy);
+    __ LoadP(r3, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+    __ LoadP(r3, FieldMemOperand(r3, GlobalObject::kGlobalProxyOffset));
+
+    // Push the receiver.
+    // r3: receiver
+    __ bind(&push_receiver);
+    __ push(r3);
+
+    // Copy all arguments from the array to the stack.
+    Label entry, loop;
+    __ LoadP(r3, MemOperand(fp, kIndexOffset));
+    __ b(&entry);
+
+    // Load the current argument from the arguments array and push it to the
+    // stack.
+    // r3: current argument index
+    __ bind(&loop);
+    __ LoadP(r4, MemOperand(fp, kArgsOffset));
+    __ Push(r4, r3);
+
+    // Call the runtime to access the property in the arguments array.
+    __ CallRuntime(Runtime::kGetProperty, 2);
+    __ push(r3);
+
+    // Use inline caching to access the arguments.
+    __ LoadP(r3, MemOperand(fp, kIndexOffset));
+    __ AddSmiLiteral(r3, r3, Smi::FromInt(1), r0);
+    __ StoreP(r3, MemOperand(fp, kIndexOffset));
+
+    // Test if the copy loop has finished copying all the elements from the
+    // arguments object.
+    __ bind(&entry);
+    __ LoadP(r4, MemOperand(fp, kLimitOffset));
+    __ cmp(r3, r4);
+    __ bne(&loop);
+
+    // Call the function.
+    Label call_proxy;
+    ParameterCount actual(r3);
+    __ SmiUntag(r3);
+    __ LoadP(r4, MemOperand(fp, kFunctionOffset));
+    __ CompareObjectType(r4, r5, r5, JS_FUNCTION_TYPE);
+    __ bne(&call_proxy);
+    __ InvokeFunction(r4, actual, CALL_FUNCTION, NullCallWrapper());
+
+    __ LeaveFrame(StackFrame::INTERNAL, 3 * kPointerSize);
+    __ blr();
+
+    // Call the function proxy.
+    __ bind(&call_proxy);
+    __ push(r4);  // add function proxy as last argument
+    __ addi(r3, r3, Operand(1));
+    __ li(r5, Operand::Zero());
+    __ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY);
+    __ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+            RelocInfo::CODE_TARGET);
+
+    // Tear down the internal frame and remove function, receiver and args.
+  }
+  __ addi(sp, sp, Operand(3 * kPointerSize));
+  __ blr();
+}
+
+
+static void ArgumentAdaptorStackCheck(MacroAssembler* masm,
+                                      Label* stack_overflow) {
+  // ----------- S t a t e -------------
+  //  -- r3 : actual number of arguments
+  //  -- r4 : function (passed through to callee)
+  //  -- r5 : expected number of arguments
+  // -----------------------------------
+  // Check the stack for overflow. We are not trying to catch
+  // interruptions (e.g. debug break and preemption) here, so the "real stack
+  // limit" is checked.
+  __ LoadRoot(r8, Heap::kRealStackLimitRootIndex);
+  // Make r8 the space we have left. The stack might already be overflowed
+  // here which will cause r8 to become negative.
+  __ sub(r8, sp, r8);
+  // Check if the arguments will overflow the stack.
+  __ ShiftLeftImm(r0, r5, Operand(kPointerSizeLog2));
+  __ cmp(r8, r0);
+  __ ble(stack_overflow);  // Signed comparison.
+}
+
+
+static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
+  __ SmiTag(r3);
+  __ LoadSmiLiteral(r7, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
+  __ mflr(r0);
+  __ push(r0);
+#if V8_OOL_CONSTANT_POOL
+  __ Push(fp, kConstantPoolRegister, r7, r4, r3);
+#else
+  __ Push(fp, r7, r4, r3);
+#endif
+  __ addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp +
+                          kPointerSize));
+}
+
+
+static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- r3 : result being passed through
+  // -----------------------------------
+  // Get the number of arguments passed (as a smi), tear down the frame and
+  // then tear down the parameters.
+  __ LoadP(r4, MemOperand(fp, -(StandardFrameConstants::kFixedFrameSizeFromFp +
+                                kPointerSize)));
+  int stack_adjustment = kPointerSize;  // adjust for receiver
+  __ LeaveFrame(StackFrame::ARGUMENTS_ADAPTOR, stack_adjustment);
+  __ SmiToPtrArrayOffset(r0, r4);
+  __ add(sp, sp, r0);
+}
+
+
+void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- r3 : actual number of arguments
+  //  -- r4 : function (passed through to callee)
+  //  -- r5 : expected number of arguments
+  // -----------------------------------
+
+  Label stack_overflow;
+  ArgumentAdaptorStackCheck(masm, &stack_overflow);
+  Label invoke, dont_adapt_arguments;
+
+  Label enough, too_few;
+  __ LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
+  __ cmp(r3, r5);
+  __ blt(&too_few);
+  __ cmpi(r5, Operand(SharedFunctionInfo::kDontAdaptArgumentsSentinel));
+  __ beq(&dont_adapt_arguments);
+
+  {  // Enough parameters: actual >= expected
+    __ bind(&enough);
+    EnterArgumentsAdaptorFrame(masm);
+
+    // Calculate copy start address into r3 and copy end address into r5.
+    // r3: actual number of arguments as a smi
+    // r4: function
+    // r5: expected number of arguments
+    // ip: code entry to call
+    __ SmiToPtrArrayOffset(r3, r3);
+    __ add(r3, r3, fp);
+    // adjust for return address and receiver
+    __ addi(r3, r3, Operand(2 * kPointerSize));
+    __ ShiftLeftImm(r5, r5, Operand(kPointerSizeLog2));
+    __ sub(r5, r3, r5);
+
+    // Copy the arguments (including the receiver) to the new stack frame.
+    // r3: copy start address
+    // r4: function
+    // r5: copy end address
+    // ip: code entry to call
+
+    Label copy;
+    __ bind(&copy);
+    __ LoadP(r0, MemOperand(r3, 0));
+    __ push(r0);
+    __ cmp(r3, r5);  // Compare before moving to next argument.
+    __ subi(r3, r3, Operand(kPointerSize));
+    __ bne(&copy);
+
+    __ b(&invoke);
+  }
+
+  {  // Too few parameters: Actual < expected
+    __ bind(&too_few);
+    EnterArgumentsAdaptorFrame(masm);
+
+    // Calculate copy start address into r0 and copy end address is fp.
+    // r3: actual number of arguments as a smi
+    // r4: function
+    // r5: expected number of arguments
+    // ip: code entry to call
+    __ SmiToPtrArrayOffset(r3, r3);
+    __ add(r3, r3, fp);
+
+    // Copy the arguments (including the receiver) to the new stack frame.
+    // r3: copy start address
+    // r4: function
+    // r5: expected number of arguments
+    // ip: code entry to call
+    Label copy;
+    __ bind(&copy);
+    // Adjust load for return address and receiver.
+    __ LoadP(r0, MemOperand(r3, 2 * kPointerSize));
+    __ push(r0);
+    __ cmp(r3, fp);  // Compare before moving to next argument.
+    __ subi(r3, r3, Operand(kPointerSize));
+    __ bne(&copy);
+
+    // Fill the remaining expected arguments with undefined.
+    // r4: function
+    // r5: expected number of arguments
+    // ip: code entry to call
+    __ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
+    __ ShiftLeftImm(r5, r5, Operand(kPointerSizeLog2));
+    __ sub(r5, fp, r5);
+    // Adjust for frame.
+    __ subi(r5, r5, Operand(StandardFrameConstants::kFixedFrameSizeFromFp +
+                            2 * kPointerSize));
+
+    Label fill;
+    __ bind(&fill);
+    __ push(r0);
+    __ cmp(sp, r5);
+    __ bne(&fill);
+  }
+
+  // Call the entry point.
+  __ bind(&invoke);
+  __ CallJSEntry(ip);
+
+  // Store offset of return address for deoptimizer.
+  masm->isolate()->heap()->SetArgumentsAdaptorDeoptPCOffset(masm->pc_offset());
+
+  // Exit frame and return.
+  LeaveArgumentsAdaptorFrame(masm);
+  __ blr();
+
+
+  // -------------------------------------------
+  // Dont adapt arguments.
+  // -------------------------------------------
+  __ bind(&dont_adapt_arguments);
+  __ JumpToJSEntry(ip);
+
+  __ bind(&stack_overflow);
+  {
+    FrameScope frame(masm, StackFrame::MANUAL);
+    EnterArgumentsAdaptorFrame(masm);
+    __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
+    __ bkpt(0);
+  }
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/code-stubs-ppc.cc b/src/ppc/code-stubs-ppc.cc
new file mode 100644
index 0000000..3e84a21
--- /dev/null
+++ b/src/ppc/code-stubs-ppc.cc
@@ -0,0 +1,4893 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/base/bits.h"
+#include "src/bootstrapper.h"
+#include "src/code-stubs.h"
+#include "src/codegen.h"
+#include "src/ic/handler-compiler.h"
+#include "src/ic/ic.h"
+#include "src/isolate.h"
+#include "src/jsregexp.h"
+#include "src/regexp-macro-assembler.h"
+#include "src/runtime/runtime.h"
+
+namespace v8 {
+namespace internal {
+
+
+static void InitializeArrayConstructorDescriptor(
+    Isolate* isolate, CodeStubDescriptor* descriptor,
+    int constant_stack_parameter_count) {
+  Address deopt_handler =
+      Runtime::FunctionForId(Runtime::kArrayConstructor)->entry;
+
+  if (constant_stack_parameter_count == 0) {
+    descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
+                           JS_FUNCTION_STUB_MODE);
+  } else {
+    descriptor->Initialize(r3, deopt_handler, constant_stack_parameter_count,
+                           JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS);
+  }
+}
+
+
+static void InitializeInternalArrayConstructorDescriptor(
+    Isolate* isolate, CodeStubDescriptor* descriptor,
+    int constant_stack_parameter_count) {
+  Address deopt_handler =
+      Runtime::FunctionForId(Runtime::kInternalArrayConstructor)->entry;
+
+  if (constant_stack_parameter_count == 0) {
+    descriptor->Initialize(deopt_handler, constant_stack_parameter_count,
+                           JS_FUNCTION_STUB_MODE);
+  } else {
+    descriptor->Initialize(r3, deopt_handler, constant_stack_parameter_count,
+                           JS_FUNCTION_STUB_MODE, PASS_ARGUMENTS);
+  }
+}
+
+
+void ArrayNoArgumentConstructorStub::InitializeDescriptor(
+    CodeStubDescriptor* descriptor) {
+  InitializeArrayConstructorDescriptor(isolate(), descriptor, 0);
+}
+
+
+void ArraySingleArgumentConstructorStub::InitializeDescriptor(
+    CodeStubDescriptor* descriptor) {
+  InitializeArrayConstructorDescriptor(isolate(), descriptor, 1);
+}
+
+
+void ArrayNArgumentsConstructorStub::InitializeDescriptor(
+    CodeStubDescriptor* descriptor) {
+  InitializeArrayConstructorDescriptor(isolate(), descriptor, -1);
+}
+
+
+void InternalArrayNoArgumentConstructorStub::InitializeDescriptor(
+    CodeStubDescriptor* descriptor) {
+  InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, 0);
+}
+
+
+void InternalArraySingleArgumentConstructorStub::InitializeDescriptor(
+    CodeStubDescriptor* descriptor) {
+  InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, 1);
+}
+
+
+void InternalArrayNArgumentsConstructorStub::InitializeDescriptor(
+    CodeStubDescriptor* descriptor) {
+  InitializeInternalArrayConstructorDescriptor(isolate(), descriptor, -1);
+}
+
+
+#define __ ACCESS_MASM(masm)
+
+
+static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
+                                          Condition cond);
+static void EmitSmiNonsmiComparison(MacroAssembler* masm, Register lhs,
+                                    Register rhs, Label* lhs_not_nan,
+                                    Label* slow, bool strict);
+static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, Register lhs,
+                                           Register rhs);
+
+
+void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm,
+                                               ExternalReference miss) {
+  // Update the static counter each time a new code stub is generated.
+  isolate()->counters()->code_stubs()->Increment();
+
+  CallInterfaceDescriptor descriptor = GetCallInterfaceDescriptor();
+  int param_count = descriptor.GetEnvironmentParameterCount();
+  {
+    // Call the runtime system in a fresh internal frame.
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+    DCHECK(param_count == 0 ||
+           r3.is(descriptor.GetEnvironmentParameterRegister(param_count - 1)));
+    // Push arguments
+    for (int i = 0; i < param_count; ++i) {
+      __ push(descriptor.GetEnvironmentParameterRegister(i));
+    }
+    __ CallExternalReference(miss, param_count);
+  }
+
+  __ Ret();
+}
+
+
+void DoubleToIStub::Generate(MacroAssembler* masm) {
+  Label out_of_range, only_low, negate, done, fastpath_done;
+  Register input_reg = source();
+  Register result_reg = destination();
+  DCHECK(is_truncating());
+
+  int double_offset = offset();
+
+  // Immediate values for this stub fit in instructions, so it's safe to use ip.
+  Register scratch = GetRegisterThatIsNotOneOf(input_reg, result_reg);
+  Register scratch_low =
+      GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch);
+  Register scratch_high =
+      GetRegisterThatIsNotOneOf(input_reg, result_reg, scratch, scratch_low);
+  DoubleRegister double_scratch = kScratchDoubleReg;
+
+  __ push(scratch);
+  // Account for saved regs if input is sp.
+  if (input_reg.is(sp)) double_offset += kPointerSize;
+
+  if (!skip_fastpath()) {
+    // Load double input.
+    __ lfd(double_scratch, MemOperand(input_reg, double_offset));
+
+    // Do fast-path convert from double to int.
+    __ ConvertDoubleToInt64(double_scratch,
+#if !V8_TARGET_ARCH_PPC64
+                            scratch,
+#endif
+                            result_reg, d0);
+
+// Test for overflow
+#if V8_TARGET_ARCH_PPC64
+    __ TestIfInt32(result_reg, scratch, r0);
+#else
+    __ TestIfInt32(scratch, result_reg, r0);
+#endif
+    __ beq(&fastpath_done);
+  }
+
+  __ Push(scratch_high, scratch_low);
+  // Account for saved regs if input is sp.
+  if (input_reg.is(sp)) double_offset += 2 * kPointerSize;
+
+  __ lwz(scratch_high,
+         MemOperand(input_reg, double_offset + Register::kExponentOffset));
+  __ lwz(scratch_low,
+         MemOperand(input_reg, double_offset + Register::kMantissaOffset));
+
+  __ ExtractBitMask(scratch, scratch_high, HeapNumber::kExponentMask);
+  // Load scratch with exponent - 1. This is faster than loading
+  // with exponent because Bias + 1 = 1024 which is a *PPC* immediate value.
+  STATIC_ASSERT(HeapNumber::kExponentBias + 1 == 1024);
+  __ subi(scratch, scratch, Operand(HeapNumber::kExponentBias + 1));
+  // If exponent is greater than or equal to 84, the 32 less significant
+  // bits are 0s (2^84 = 1, 52 significant bits, 32 uncoded bits),
+  // the result is 0.
+  // Compare exponent with 84 (compare exponent - 1 with 83).
+  __ cmpi(scratch, Operand(83));
+  __ bge(&out_of_range);
+
+  // If we reach this code, 31 <= exponent <= 83.
+  // So, we don't have to handle cases where 0 <= exponent <= 20 for
+  // which we would need to shift right the high part of the mantissa.
+  // Scratch contains exponent - 1.
+  // Load scratch with 52 - exponent (load with 51 - (exponent - 1)).
+  __ subfic(scratch, scratch, Operand(51));
+  __ cmpi(scratch, Operand::Zero());
+  __ ble(&only_low);
+  // 21 <= exponent <= 51, shift scratch_low and scratch_high
+  // to generate the result.
+  __ srw(scratch_low, scratch_low, scratch);
+  // Scratch contains: 52 - exponent.
+  // We needs: exponent - 20.
+  // So we use: 32 - scratch = 32 - 52 + exponent = exponent - 20.
+  __ subfic(scratch, scratch, Operand(32));
+  __ ExtractBitMask(result_reg, scratch_high, HeapNumber::kMantissaMask);
+  // Set the implicit 1 before the mantissa part in scratch_high.
+  STATIC_ASSERT(HeapNumber::kMantissaBitsInTopWord >= 16);
+  __ oris(result_reg, result_reg,
+          Operand(1 << ((HeapNumber::kMantissaBitsInTopWord) - 16)));
+  __ slw(r0, result_reg, scratch);
+  __ orx(result_reg, scratch_low, r0);
+  __ b(&negate);
+
+  __ bind(&out_of_range);
+  __ mov(result_reg, Operand::Zero());
+  __ b(&done);
+
+  __ bind(&only_low);
+  // 52 <= exponent <= 83, shift only scratch_low.
+  // On entry, scratch contains: 52 - exponent.
+  __ neg(scratch, scratch);
+  __ slw(result_reg, scratch_low, scratch);
+
+  __ bind(&negate);
+  // If input was positive, scratch_high ASR 31 equals 0 and
+  // scratch_high LSR 31 equals zero.
+  // New result = (result eor 0) + 0 = result.
+  // If the input was negative, we have to negate the result.
+  // Input_high ASR 31 equals 0xffffffff and scratch_high LSR 31 equals 1.
+  // New result = (result eor 0xffffffff) + 1 = 0 - result.
+  __ srawi(r0, scratch_high, 31);
+#if V8_TARGET_ARCH_PPC64
+  __ srdi(r0, r0, Operand(32));
+#endif
+  __ xor_(result_reg, result_reg, r0);
+  __ srwi(r0, scratch_high, Operand(31));
+  __ add(result_reg, result_reg, r0);
+
+  __ bind(&done);
+  __ Pop(scratch_high, scratch_low);
+
+  __ bind(&fastpath_done);
+  __ pop(scratch);
+
+  __ Ret();
+}
+
+
+// Handle the case where the lhs and rhs are the same object.
+// Equality is almost reflexive (everything but NaN), so this is a test
+// for "identity and not NaN".
+static void EmitIdenticalObjectComparison(MacroAssembler* masm, Label* slow,
+                                          Condition cond) {
+  Label not_identical;
+  Label heap_number, return_equal;
+  __ cmp(r3, r4);
+  __ bne(&not_identical);
+
+  // Test for NaN. Sadly, we can't just compare to Factory::nan_value(),
+  // so we do the second best thing - test it ourselves.
+  // They are both equal and they are not both Smis so both of them are not
+  // Smis.  If it's not a heap number, then return equal.
+  if (cond == lt || cond == gt) {
+    __ CompareObjectType(r3, r7, r7, FIRST_SPEC_OBJECT_TYPE);
+    __ bge(slow);
+  } else {
+    __ CompareObjectType(r3, r7, r7, HEAP_NUMBER_TYPE);
+    __ beq(&heap_number);
+    // Comparing JS objects with <=, >= is complicated.
+    if (cond != eq) {
+      __ cmpi(r7, Operand(FIRST_SPEC_OBJECT_TYPE));
+      __ bge(slow);
+      // Normally here we fall through to return_equal, but undefined is
+      // special: (undefined == undefined) == true, but
+      // (undefined <= undefined) == false!  See ECMAScript 11.8.5.
+      if (cond == le || cond == ge) {
+        __ cmpi(r7, Operand(ODDBALL_TYPE));
+        __ bne(&return_equal);
+        __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
+        __ cmp(r3, r5);
+        __ bne(&return_equal);
+        if (cond == le) {
+          // undefined <= undefined should fail.
+          __ li(r3, Operand(GREATER));
+        } else {
+          // undefined >= undefined should fail.
+          __ li(r3, Operand(LESS));
+        }
+        __ Ret();
+      }
+    }
+  }
+
+  __ bind(&return_equal);
+  if (cond == lt) {
+    __ li(r3, Operand(GREATER));  // Things aren't less than themselves.
+  } else if (cond == gt) {
+    __ li(r3, Operand(LESS));  // Things aren't greater than themselves.
+  } else {
+    __ li(r3, Operand(EQUAL));  // Things are <=, >=, ==, === themselves.
+  }
+  __ Ret();
+
+  // For less and greater we don't have to check for NaN since the result of
+  // x < x is false regardless.  For the others here is some code to check
+  // for NaN.
+  if (cond != lt && cond != gt) {
+    __ bind(&heap_number);
+    // It is a heap number, so return non-equal if it's NaN and equal if it's
+    // not NaN.
+
+    // The representation of NaN values has all exponent bits (52..62) set,
+    // and not all mantissa bits (0..51) clear.
+    // Read top bits of double representation (second word of value).
+    __ lwz(r5, FieldMemOperand(r3, HeapNumber::kExponentOffset));
+    // Test that exponent bits are all set.
+    STATIC_ASSERT(HeapNumber::kExponentMask == 0x7ff00000u);
+    __ ExtractBitMask(r6, r5, HeapNumber::kExponentMask);
+    __ cmpli(r6, Operand(0x7ff));
+    __ bne(&return_equal);
+
+    // Shift out flag and all exponent bits, retaining only mantissa.
+    __ slwi(r5, r5, Operand(HeapNumber::kNonMantissaBitsInTopWord));
+    // Or with all low-bits of mantissa.
+    __ lwz(r6, FieldMemOperand(r3, HeapNumber::kMantissaOffset));
+    __ orx(r3, r6, r5);
+    __ cmpi(r3, Operand::Zero());
+    // For equal we already have the right value in r3:  Return zero (equal)
+    // if all bits in mantissa are zero (it's an Infinity) and non-zero if
+    // not (it's a NaN).  For <= and >= we need to load r0 with the failing
+    // value if it's a NaN.
+    if (cond != eq) {
+      Label not_equal;
+      __ bne(&not_equal);
+      // All-zero means Infinity means equal.
+      __ Ret();
+      __ bind(&not_equal);
+      if (cond == le) {
+        __ li(r3, Operand(GREATER));  // NaN <= NaN should fail.
+      } else {
+        __ li(r3, Operand(LESS));  // NaN >= NaN should fail.
+      }
+    }
+    __ Ret();
+  }
+  // No fall through here.
+
+  __ bind(&not_identical);
+}
+
+
+// See comment at call site.
+static void EmitSmiNonsmiComparison(MacroAssembler* masm, Register lhs,
+                                    Register rhs, Label* lhs_not_nan,
+                                    Label* slow, bool strict) {
+  DCHECK((lhs.is(r3) && rhs.is(r4)) || (lhs.is(r4) && rhs.is(r3)));
+
+  Label rhs_is_smi;
+  __ JumpIfSmi(rhs, &rhs_is_smi);
+
+  // Lhs is a Smi.  Check whether the rhs is a heap number.
+  __ CompareObjectType(rhs, r6, r7, HEAP_NUMBER_TYPE);
+  if (strict) {
+    // If rhs is not a number and lhs is a Smi then strict equality cannot
+    // succeed.  Return non-equal
+    // If rhs is r3 then there is already a non zero value in it.
+    Label skip;
+    __ beq(&skip);
+    if (!rhs.is(r3)) {
+      __ mov(r3, Operand(NOT_EQUAL));
+    }
+    __ Ret();
+    __ bind(&skip);
+  } else {
+    // Smi compared non-strictly with a non-Smi non-heap-number.  Call
+    // the runtime.
+    __ bne(slow);
+  }
+
+  // Lhs is a smi, rhs is a number.
+  // Convert lhs to a double in d7.
+  __ SmiToDouble(d7, lhs);
+  // Load the double from rhs, tagged HeapNumber r3, to d6.
+  __ lfd(d6, FieldMemOperand(rhs, HeapNumber::kValueOffset));
+
+  // We now have both loaded as doubles but we can skip the lhs nan check
+  // since it's a smi.
+  __ b(lhs_not_nan);
+
+  __ bind(&rhs_is_smi);
+  // Rhs is a smi.  Check whether the non-smi lhs is a heap number.
+  __ CompareObjectType(lhs, r7, r7, HEAP_NUMBER_TYPE);
+  if (strict) {
+    // If lhs is not a number and rhs is a smi then strict equality cannot
+    // succeed.  Return non-equal.
+    // If lhs is r3 then there is already a non zero value in it.
+    Label skip;
+    __ beq(&skip);
+    if (!lhs.is(r3)) {
+      __ mov(r3, Operand(NOT_EQUAL));
+    }
+    __ Ret();
+    __ bind(&skip);
+  } else {
+    // Smi compared non-strictly with a non-smi non-heap-number.  Call
+    // the runtime.
+    __ bne(slow);
+  }
+
+  // Rhs is a smi, lhs is a heap number.
+  // Load the double from lhs, tagged HeapNumber r4, to d7.
+  __ lfd(d7, FieldMemOperand(lhs, HeapNumber::kValueOffset));
+  // Convert rhs to a double in d6.
+  __ SmiToDouble(d6, rhs);
+  // Fall through to both_loaded_as_doubles.
+}
+
+
+// See comment at call site.
+static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm, Register lhs,
+                                           Register rhs) {
+  DCHECK((lhs.is(r3) && rhs.is(r4)) || (lhs.is(r4) && rhs.is(r3)));
+
+  // If either operand is a JS object or an oddball value, then they are
+  // not equal since their pointers are different.
+  // There is no test for undetectability in strict equality.
+  STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
+  Label first_non_object;
+  // Get the type of the first operand into r5 and compare it with
+  // FIRST_SPEC_OBJECT_TYPE.
+  __ CompareObjectType(rhs, r5, r5, FIRST_SPEC_OBJECT_TYPE);
+  __ blt(&first_non_object);
+
+  // Return non-zero (r3 is not zero)
+  Label return_not_equal;
+  __ bind(&return_not_equal);
+  __ Ret();
+
+  __ bind(&first_non_object);
+  // Check for oddballs: true, false, null, undefined.
+  __ cmpi(r5, Operand(ODDBALL_TYPE));
+  __ beq(&return_not_equal);
+
+  __ CompareObjectType(lhs, r6, r6, FIRST_SPEC_OBJECT_TYPE);
+  __ bge(&return_not_equal);
+
+  // Check for oddballs: true, false, null, undefined.
+  __ cmpi(r6, Operand(ODDBALL_TYPE));
+  __ beq(&return_not_equal);
+
+  // Now that we have the types we might as well check for
+  // internalized-internalized.
+  STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
+  __ orx(r5, r5, r6);
+  __ andi(r0, r5, Operand(kIsNotStringMask | kIsNotInternalizedMask));
+  __ beq(&return_not_equal, cr0);
+}
+
+
+// See comment at call site.
+static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm, Register lhs,
+                                       Register rhs,
+                                       Label* both_loaded_as_doubles,
+                                       Label* not_heap_numbers, Label* slow) {
+  DCHECK((lhs.is(r3) && rhs.is(r4)) || (lhs.is(r4) && rhs.is(r3)));
+
+  __ CompareObjectType(rhs, r6, r5, HEAP_NUMBER_TYPE);
+  __ bne(not_heap_numbers);
+  __ LoadP(r5, FieldMemOperand(lhs, HeapObject::kMapOffset));
+  __ cmp(r5, r6);
+  __ bne(slow);  // First was a heap number, second wasn't.  Go slow case.
+
+  // Both are heap numbers.  Load them up then jump to the code we have
+  // for that.
+  __ lfd(d6, FieldMemOperand(rhs, HeapNumber::kValueOffset));
+  __ lfd(d7, FieldMemOperand(lhs, HeapNumber::kValueOffset));
+
+  __ b(both_loaded_as_doubles);
+}
+
+
+// Fast negative check for internalized-to-internalized equality.
+static void EmitCheckForInternalizedStringsOrObjects(MacroAssembler* masm,
+                                                     Register lhs, Register rhs,
+                                                     Label* possible_strings,
+                                                     Label* not_both_strings) {
+  DCHECK((lhs.is(r3) && rhs.is(r4)) || (lhs.is(r4) && rhs.is(r3)));
+
+  // r5 is object type of rhs.
+  Label object_test;
+  STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
+  __ andi(r0, r5, Operand(kIsNotStringMask));
+  __ bne(&object_test, cr0);
+  __ andi(r0, r5, Operand(kIsNotInternalizedMask));
+  __ bne(possible_strings, cr0);
+  __ CompareObjectType(lhs, r6, r6, FIRST_NONSTRING_TYPE);
+  __ bge(not_both_strings);
+  __ andi(r0, r6, Operand(kIsNotInternalizedMask));
+  __ bne(possible_strings, cr0);
+
+  // Both are internalized.  We already checked they weren't the same pointer
+  // so they are not equal.
+  __ li(r3, Operand(NOT_EQUAL));
+  __ Ret();
+
+  __ bind(&object_test);
+  __ cmpi(r5, Operand(FIRST_SPEC_OBJECT_TYPE));
+  __ blt(not_both_strings);
+  __ CompareObjectType(lhs, r5, r6, FIRST_SPEC_OBJECT_TYPE);
+  __ blt(not_both_strings);
+  // If both objects are undetectable, they are equal. Otherwise, they
+  // are not equal, since they are different objects and an object is not
+  // equal to undefined.
+  __ LoadP(r6, FieldMemOperand(rhs, HeapObject::kMapOffset));
+  __ lbz(r5, FieldMemOperand(r5, Map::kBitFieldOffset));
+  __ lbz(r6, FieldMemOperand(r6, Map::kBitFieldOffset));
+  __ and_(r3, r5, r6);
+  __ andi(r3, r3, Operand(1 << Map::kIsUndetectable));
+  __ xori(r3, r3, Operand(1 << Map::kIsUndetectable));
+  __ Ret();
+}
+
+
+static void CompareICStub_CheckInputType(MacroAssembler* masm, Register input,
+                                         Register scratch,
+                                         CompareICState::State expected,
+                                         Label* fail) {
+  Label ok;
+  if (expected == CompareICState::SMI) {
+    __ JumpIfNotSmi(input, fail);
+  } else if (expected == CompareICState::NUMBER) {
+    __ JumpIfSmi(input, &ok);
+    __ CheckMap(input, scratch, Heap::kHeapNumberMapRootIndex, fail,
+                DONT_DO_SMI_CHECK);
+  }
+  // We could be strict about internalized/non-internalized here, but as long as
+  // hydrogen doesn't care, the stub doesn't have to care either.
+  __ bind(&ok);
+}
+
+
+// On entry r4 and r5 are the values to be compared.
+// On exit r3 is 0, positive or negative to indicate the result of
+// the comparison.
+void CompareICStub::GenerateGeneric(MacroAssembler* masm) {
+  Register lhs = r4;
+  Register rhs = r3;
+  Condition cc = GetCondition();
+
+  Label miss;
+  CompareICStub_CheckInputType(masm, lhs, r5, left(), &miss);
+  CompareICStub_CheckInputType(masm, rhs, r6, right(), &miss);
+
+  Label slow;  // Call builtin.
+  Label not_smis, both_loaded_as_doubles, lhs_not_nan;
+
+  Label not_two_smis, smi_done;
+  __ orx(r5, r4, r3);
+  __ JumpIfNotSmi(r5, &not_two_smis);
+  __ SmiUntag(r4);
+  __ SmiUntag(r3);
+  __ sub(r3, r4, r3);
+  __ Ret();
+  __ bind(&not_two_smis);
+
+  // NOTICE! This code is only reached after a smi-fast-case check, so
+  // it is certain that at least one operand isn't a smi.
+
+  // Handle the case where the objects are identical.  Either returns the answer
+  // or goes to slow.  Only falls through if the objects were not identical.
+  EmitIdenticalObjectComparison(masm, &slow, cc);
+
+  // If either is a Smi (we know that not both are), then they can only
+  // be strictly equal if the other is a HeapNumber.
+  STATIC_ASSERT(kSmiTag == 0);
+  DCHECK_EQ(0, Smi::FromInt(0));
+  __ and_(r5, lhs, rhs);
+  __ JumpIfNotSmi(r5, &not_smis);
+  // One operand is a smi.  EmitSmiNonsmiComparison generates code that can:
+  // 1) Return the answer.
+  // 2) Go to slow.
+  // 3) Fall through to both_loaded_as_doubles.
+  // 4) Jump to lhs_not_nan.
+  // In cases 3 and 4 we have found out we were dealing with a number-number
+  // comparison.  The double values of the numbers have been loaded
+  // into d7 and d6.
+  EmitSmiNonsmiComparison(masm, lhs, rhs, &lhs_not_nan, &slow, strict());
+
+  __ bind(&both_loaded_as_doubles);
+  // The arguments have been converted to doubles and stored in d6 and d7
+  __ bind(&lhs_not_nan);
+  Label no_nan;
+  __ fcmpu(d7, d6);
+
+  Label nan, equal, less_than;
+  __ bunordered(&nan);
+  __ beq(&equal);
+  __ blt(&less_than);
+  __ li(r3, Operand(GREATER));
+  __ Ret();
+  __ bind(&equal);
+  __ li(r3, Operand(EQUAL));
+  __ Ret();
+  __ bind(&less_than);
+  __ li(r3, Operand(LESS));
+  __ Ret();
+
+  __ bind(&nan);
+  // If one of the sides was a NaN then the v flag is set.  Load r3 with
+  // whatever it takes to make the comparison fail, since comparisons with NaN
+  // always fail.
+  if (cc == lt || cc == le) {
+    __ li(r3, Operand(GREATER));
+  } else {
+    __ li(r3, Operand(LESS));
+  }
+  __ Ret();
+
+  __ bind(&not_smis);
+  // At this point we know we are dealing with two different objects,
+  // and neither of them is a Smi.  The objects are in rhs_ and lhs_.
+  if (strict()) {
+    // This returns non-equal for some object types, or falls through if it
+    // was not lucky.
+    EmitStrictTwoHeapObjectCompare(masm, lhs, rhs);
+  }
+
+  Label check_for_internalized_strings;
+  Label flat_string_check;
+  // Check for heap-number-heap-number comparison.  Can jump to slow case,
+  // or load both doubles into r3, r4, r5, r6 and jump to the code that handles
+  // that case.  If the inputs are not doubles then jumps to
+  // check_for_internalized_strings.
+  // In this case r5 will contain the type of rhs_.  Never falls through.
+  EmitCheckForTwoHeapNumbers(masm, lhs, rhs, &both_loaded_as_doubles,
+                             &check_for_internalized_strings,
+                             &flat_string_check);
+
+  __ bind(&check_for_internalized_strings);
+  // In the strict case the EmitStrictTwoHeapObjectCompare already took care of
+  // internalized strings.
+  if (cc == eq && !strict()) {
+    // Returns an answer for two internalized strings or two detectable objects.
+    // Otherwise jumps to string case or not both strings case.
+    // Assumes that r5 is the type of rhs_ on entry.
+    EmitCheckForInternalizedStringsOrObjects(masm, lhs, rhs, &flat_string_check,
+                                             &slow);
+  }
+
+  // Check for both being sequential one-byte strings,
+  // and inline if that is the case.
+  __ bind(&flat_string_check);
+
+  __ JumpIfNonSmisNotBothSequentialOneByteStrings(lhs, rhs, r5, r6, &slow);
+
+  __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, r5,
+                      r6);
+  if (cc == eq) {
+    StringHelper::GenerateFlatOneByteStringEquals(masm, lhs, rhs, r5, r6);
+  } else {
+    StringHelper::GenerateCompareFlatOneByteStrings(masm, lhs, rhs, r5, r6, r7);
+  }
+  // Never falls through to here.
+
+  __ bind(&slow);
+
+  __ Push(lhs, rhs);
+  // Figure out which native to call and setup the arguments.
+  Builtins::JavaScript native;
+  if (cc == eq) {
+    native = strict() ? Builtins::STRICT_EQUALS : Builtins::EQUALS;
+  } else {
+    native = Builtins::COMPARE;
+    int ncr;  // NaN compare result
+    if (cc == lt || cc == le) {
+      ncr = GREATER;
+    } else {
+      DCHECK(cc == gt || cc == ge);  // remaining cases
+      ncr = LESS;
+    }
+    __ LoadSmiLiteral(r3, Smi::FromInt(ncr));
+    __ push(r3);
+  }
+
+  // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
+  // tagged as a small integer.
+  __ InvokeBuiltin(native, JUMP_FUNCTION);
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+}
+
+
+void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
+  // We don't allow a GC during a store buffer overflow so there is no need to
+  // store the registers in any particular way, but we do have to store and
+  // restore them.
+  __ mflr(r0);
+  __ MultiPush(kJSCallerSaved | r0.bit());
+  if (save_doubles()) {
+    __ SaveFPRegs(sp, 0, DoubleRegister::kNumVolatileRegisters);
+  }
+  const int argument_count = 1;
+  const int fp_argument_count = 0;
+  const Register scratch = r4;
+
+  AllowExternalCallThatCantCauseGC scope(masm);
+  __ PrepareCallCFunction(argument_count, fp_argument_count, scratch);
+  __ mov(r3, Operand(ExternalReference::isolate_address(isolate())));
+  __ CallCFunction(ExternalReference::store_buffer_overflow_function(isolate()),
+                   argument_count);
+  if (save_doubles()) {
+    __ RestoreFPRegs(sp, 0, DoubleRegister::kNumVolatileRegisters);
+  }
+  __ MultiPop(kJSCallerSaved | r0.bit());
+  __ mtlr(r0);
+  __ Ret();
+}
+
+
+void StoreRegistersStateStub::Generate(MacroAssembler* masm) {
+  __ PushSafepointRegisters();
+  __ blr();
+}
+
+
+void RestoreRegistersStateStub::Generate(MacroAssembler* masm) {
+  __ PopSafepointRegisters();
+  __ blr();
+}
+
+
+void MathPowStub::Generate(MacroAssembler* masm) {
+  const Register base = r4;
+  const Register exponent = MathPowTaggedDescriptor::exponent();
+  DCHECK(exponent.is(r5));
+  const Register heapnumbermap = r8;
+  const Register heapnumber = r3;
+  const DoubleRegister double_base = d1;
+  const DoubleRegister double_exponent = d2;
+  const DoubleRegister double_result = d3;
+  const DoubleRegister double_scratch = d0;
+  const Register scratch = r11;
+  const Register scratch2 = r10;
+
+  Label call_runtime, done, int_exponent;
+  if (exponent_type() == ON_STACK) {
+    Label base_is_smi, unpack_exponent;
+    // The exponent and base are supplied as arguments on the stack.
+    // This can only happen if the stub is called from non-optimized code.
+    // Load input parameters from stack to double registers.
+    __ LoadP(base, MemOperand(sp, 1 * kPointerSize));
+    __ LoadP(exponent, MemOperand(sp, 0 * kPointerSize));
+
+    __ LoadRoot(heapnumbermap, Heap::kHeapNumberMapRootIndex);
+
+    __ UntagAndJumpIfSmi(scratch, base, &base_is_smi);
+    __ LoadP(scratch, FieldMemOperand(base, JSObject::kMapOffset));
+    __ cmp(scratch, heapnumbermap);
+    __ bne(&call_runtime);
+
+    __ lfd(double_base, FieldMemOperand(base, HeapNumber::kValueOffset));
+    __ b(&unpack_exponent);
+
+    __ bind(&base_is_smi);
+    __ ConvertIntToDouble(scratch, double_base);
+    __ bind(&unpack_exponent);
+
+    __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent);
+    __ LoadP(scratch, FieldMemOperand(exponent, JSObject::kMapOffset));
+    __ cmp(scratch, heapnumbermap);
+    __ bne(&call_runtime);
+
+    __ lfd(double_exponent,
+           FieldMemOperand(exponent, HeapNumber::kValueOffset));
+  } else if (exponent_type() == TAGGED) {
+    // Base is already in double_base.
+    __ UntagAndJumpIfSmi(scratch, exponent, &int_exponent);
+
+    __ lfd(double_exponent,
+           FieldMemOperand(exponent, HeapNumber::kValueOffset));
+  }
+
+  if (exponent_type() != INTEGER) {
+    // Detect integer exponents stored as double.
+    __ TryDoubleToInt32Exact(scratch, double_exponent, scratch2,
+                             double_scratch);
+    __ beq(&int_exponent);
+
+    if (exponent_type() == ON_STACK) {
+      // Detect square root case.  Crankshaft detects constant +/-0.5 at
+      // compile time and uses DoMathPowHalf instead.  We then skip this check
+      // for non-constant cases of +/-0.5 as these hardly occur.
+      Label not_plus_half, not_minus_inf1, not_minus_inf2;
+
+      // Test for 0.5.
+      __ LoadDoubleLiteral(double_scratch, 0.5, scratch);
+      __ fcmpu(double_exponent, double_scratch);
+      __ bne(&not_plus_half);
+
+      // Calculates square root of base.  Check for the special case of
+      // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
+      __ LoadDoubleLiteral(double_scratch, -V8_INFINITY, scratch);
+      __ fcmpu(double_base, double_scratch);
+      __ bne(&not_minus_inf1);
+      __ fneg(double_result, double_scratch);
+      __ b(&done);
+      __ bind(&not_minus_inf1);
+
+      // Add +0 to convert -0 to +0.
+      __ fadd(double_scratch, double_base, kDoubleRegZero);
+      __ fsqrt(double_result, double_scratch);
+      __ b(&done);
+
+      __ bind(&not_plus_half);
+      __ LoadDoubleLiteral(double_scratch, -0.5, scratch);
+      __ fcmpu(double_exponent, double_scratch);
+      __ bne(&call_runtime);
+
+      // Calculates square root of base.  Check for the special case of
+      // Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13).
+      __ LoadDoubleLiteral(double_scratch, -V8_INFINITY, scratch);
+      __ fcmpu(double_base, double_scratch);
+      __ bne(&not_minus_inf2);
+      __ fmr(double_result, kDoubleRegZero);
+      __ b(&done);
+      __ bind(&not_minus_inf2);
+
+      // Add +0 to convert -0 to +0.
+      __ fadd(double_scratch, double_base, kDoubleRegZero);
+      __ LoadDoubleLiteral(double_result, 1.0, scratch);
+      __ fsqrt(double_scratch, double_scratch);
+      __ fdiv(double_result, double_result, double_scratch);
+      __ b(&done);
+    }
+
+    __ mflr(r0);
+    __ push(r0);
+    {
+      AllowExternalCallThatCantCauseGC scope(masm);
+      __ PrepareCallCFunction(0, 2, scratch);
+      __ MovToFloatParameters(double_base, double_exponent);
+      __ CallCFunction(
+          ExternalReference::power_double_double_function(isolate()), 0, 2);
+    }
+    __ pop(r0);
+    __ mtlr(r0);
+    __ MovFromFloatResult(double_result);
+    __ b(&done);
+  }
+
+  // Calculate power with integer exponent.
+  __ bind(&int_exponent);
+
+  // Get two copies of exponent in the registers scratch and exponent.
+  if (exponent_type() == INTEGER) {
+    __ mr(scratch, exponent);
+  } else {
+    // Exponent has previously been stored into scratch as untagged integer.
+    __ mr(exponent, scratch);
+  }
+  __ fmr(double_scratch, double_base);  // Back up base.
+  __ li(scratch2, Operand(1));
+  __ ConvertIntToDouble(scratch2, double_result);
+
+  // Get absolute value of exponent.
+  Label positive_exponent;
+  __ cmpi(scratch, Operand::Zero());
+  __ bge(&positive_exponent);
+  __ neg(scratch, scratch);
+  __ bind(&positive_exponent);
+
+  Label while_true, no_carry, loop_end;
+  __ bind(&while_true);
+  __ andi(scratch2, scratch, Operand(1));
+  __ beq(&no_carry, cr0);
+  __ fmul(double_result, double_result, double_scratch);
+  __ bind(&no_carry);
+  __ ShiftRightArithImm(scratch, scratch, 1, SetRC);
+  __ beq(&loop_end, cr0);
+  __ fmul(double_scratch, double_scratch, double_scratch);
+  __ b(&while_true);
+  __ bind(&loop_end);
+
+  __ cmpi(exponent, Operand::Zero());
+  __ bge(&done);
+
+  __ li(scratch2, Operand(1));
+  __ ConvertIntToDouble(scratch2, double_scratch);
+  __ fdiv(double_result, double_scratch, double_result);
+  // Test whether result is zero.  Bail out to check for subnormal result.
+  // Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
+  __ fcmpu(double_result, kDoubleRegZero);
+  __ bne(&done);
+  // double_exponent may not containe the exponent value if the input was a
+  // smi.  We set it with exponent value before bailing out.
+  __ ConvertIntToDouble(exponent, double_exponent);
+
+  // Returning or bailing out.
+  Counters* counters = isolate()->counters();
+  if (exponent_type() == ON_STACK) {
+    // The arguments are still on the stack.
+    __ bind(&call_runtime);
+    __ TailCallRuntime(Runtime::kMathPowRT, 2, 1);
+
+    // The stub is called from non-optimized code, which expects the result
+    // as heap number in exponent.
+    __ bind(&done);
+    __ AllocateHeapNumber(heapnumber, scratch, scratch2, heapnumbermap,
+                          &call_runtime);
+    __ stfd(double_result,
+            FieldMemOperand(heapnumber, HeapNumber::kValueOffset));
+    DCHECK(heapnumber.is(r3));
+    __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2);
+    __ Ret(2);
+  } else {
+    __ mflr(r0);
+    __ push(r0);
+    {
+      AllowExternalCallThatCantCauseGC scope(masm);
+      __ PrepareCallCFunction(0, 2, scratch);
+      __ MovToFloatParameters(double_base, double_exponent);
+      __ CallCFunction(
+          ExternalReference::power_double_double_function(isolate()), 0, 2);
+    }
+    __ pop(r0);
+    __ mtlr(r0);
+    __ MovFromFloatResult(double_result);
+
+    __ bind(&done);
+    __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2);
+    __ Ret();
+  }
+}
+
+
+bool CEntryStub::NeedsImmovableCode() { return true; }
+
+
+void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
+  CEntryStub::GenerateAheadOfTime(isolate);
+  //  WriteInt32ToHeapNumberStub::GenerateFixedRegStubsAheadOfTime(isolate);
+  StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(isolate);
+  StubFailureTrampolineStub::GenerateAheadOfTime(isolate);
+  ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
+  CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
+  BinaryOpICStub::GenerateAheadOfTime(isolate);
+  StoreRegistersStateStub::GenerateAheadOfTime(isolate);
+  RestoreRegistersStateStub::GenerateAheadOfTime(isolate);
+  BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
+}
+
+
+void StoreRegistersStateStub::GenerateAheadOfTime(Isolate* isolate) {
+  StoreRegistersStateStub stub(isolate);
+  stub.GetCode();
+}
+
+
+void RestoreRegistersStateStub::GenerateAheadOfTime(Isolate* isolate) {
+  RestoreRegistersStateStub stub(isolate);
+  stub.GetCode();
+}
+
+
+void CodeStub::GenerateFPStubs(Isolate* isolate) {
+  // Generate if not already in cache.
+  SaveFPRegsMode mode = kSaveFPRegs;
+  CEntryStub(isolate, 1, mode).GetCode();
+  StoreBufferOverflowStub(isolate, mode).GetCode();
+  isolate->set_fp_stubs_generated(true);
+}
+
+
+void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
+  CEntryStub stub(isolate, 1, kDontSaveFPRegs);
+  stub.GetCode();
+}
+
+
+void CEntryStub::Generate(MacroAssembler* masm) {
+  // Called from JavaScript; parameters are on stack as if calling JS function.
+  // r3: number of arguments including receiver
+  // r4: pointer to builtin function
+  // fp: frame pointer  (restored after C call)
+  // sp: stack pointer  (restored as callee's sp after C call)
+  // cp: current context  (C callee-saved)
+
+  ProfileEntryHookStub::MaybeCallEntryHook(masm);
+
+  __ mr(r15, r4);
+
+  // Compute the argv pointer.
+  __ ShiftLeftImm(r4, r3, Operand(kPointerSizeLog2));
+  __ add(r4, r4, sp);
+  __ subi(r4, r4, Operand(kPointerSize));
+
+  // Enter the exit frame that transitions from JavaScript to C++.
+  FrameScope scope(masm, StackFrame::MANUAL);
+
+  // Need at least one extra slot for return address location.
+  int arg_stack_space = 1;
+
+// PPC LINUX ABI:
+#if V8_TARGET_ARCH_PPC64 && !ABI_RETURNS_OBJECT_PAIRS_IN_REGS
+  // Pass buffer for return value on stack if necessary
+  if (result_size() > 1) {
+    DCHECK_EQ(2, result_size());
+    arg_stack_space += 2;
+  }
+#endif
+
+  __ EnterExitFrame(save_doubles(), arg_stack_space);
+
+  // Store a copy of argc in callee-saved registers for later.
+  __ mr(r14, r3);
+
+  // r3, r14: number of arguments including receiver  (C callee-saved)
+  // r4: pointer to the first argument
+  // r15: pointer to builtin function  (C callee-saved)
+
+  // Result returned in registers or stack, depending on result size and ABI.
+
+  Register isolate_reg = r5;
+#if V8_TARGET_ARCH_PPC64 && !ABI_RETURNS_OBJECT_PAIRS_IN_REGS
+  if (result_size() > 1) {
+    // The return value is 16-byte non-scalar value.
+    // Use frame storage reserved by calling function to pass return
+    // buffer as implicit first argument.
+    __ mr(r5, r4);
+    __ mr(r4, r3);
+    __ addi(r3, sp, Operand((kStackFrameExtraParamSlot + 1) * kPointerSize));
+    isolate_reg = r6;
+  }
+#endif
+
+  // Call C built-in.
+  __ mov(isolate_reg, Operand(ExternalReference::isolate_address(isolate())));
+
+#if ABI_USES_FUNCTION_DESCRIPTORS && !defined(USE_SIMULATOR)
+  // Native AIX/PPC64 Linux use a function descriptor.
+  __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(r15, kPointerSize));
+  __ LoadP(ip, MemOperand(r15, 0));  // Instruction address
+  Register target = ip;
+#elif ABI_TOC_ADDRESSABILITY_VIA_IP
+  __ Move(ip, r15);
+  Register target = ip;
+#else
+  Register target = r15;
+#endif
+
+  // To let the GC traverse the return address of the exit frames, we need to
+  // know where the return address is. The CEntryStub is unmovable, so
+  // we can store the address on the stack to be able to find it again and
+  // we never have to restore it, because it will not change.
+  // Compute the return address in lr to return to after the jump below. Pc is
+  // already at '+ 8' from the current instruction but return is after three
+  // instructions so add another 4 to pc to get the return address.
+  {
+    Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm);
+    Label here;
+    __ b(&here, SetLK);
+    __ bind(&here);
+    __ mflr(r8);
+
+    // Constant used below is dependent on size of Call() macro instructions
+    __ addi(r0, r8, Operand(20));
+
+    __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize));
+    __ Call(target);
+  }
+
+#if V8_TARGET_ARCH_PPC64 && !ABI_RETURNS_OBJECT_PAIRS_IN_REGS
+  // If return value is on the stack, pop it to registers.
+  if (result_size() > 1) {
+    __ LoadP(r4, MemOperand(r3, kPointerSize));
+    __ LoadP(r3, MemOperand(r3));
+  }
+#endif
+
+  // Runtime functions should not return 'the hole'.  Allowing it to escape may
+  // lead to crashes in the IC code later.
+  if (FLAG_debug_code) {
+    Label okay;
+    __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
+    __ bne(&okay);
+    __ stop("The hole escaped");
+    __ bind(&okay);
+  }
+
+  // Check result for exception sentinel.
+  Label exception_returned;
+  __ CompareRoot(r3, Heap::kExceptionRootIndex);
+  __ beq(&exception_returned);
+
+  ExternalReference pending_exception_address(Isolate::kPendingExceptionAddress,
+                                              isolate());
+
+  // Check that there is no pending exception, otherwise we
+  // should have returned the exception sentinel.
+  if (FLAG_debug_code) {
+    Label okay;
+    __ mov(r5, Operand(pending_exception_address));
+    __ LoadP(r5, MemOperand(r5));
+    __ CompareRoot(r5, Heap::kTheHoleValueRootIndex);
+    // Cannot use check here as it attempts to generate call into runtime.
+    __ beq(&okay);
+    __ stop("Unexpected pending exception");
+    __ bind(&okay);
+  }
+
+  // Exit C frame and return.
+  // r3:r4: result
+  // sp: stack pointer
+  // fp: frame pointer
+  // r14: still holds argc (callee-saved).
+  __ LeaveExitFrame(save_doubles(), r14, true);
+  __ blr();
+
+  // Handling of exception.
+  __ bind(&exception_returned);
+
+  // Retrieve the pending exception.
+  __ mov(r5, Operand(pending_exception_address));
+  __ LoadP(r3, MemOperand(r5));
+
+  // Clear the pending exception.
+  __ LoadRoot(r6, Heap::kTheHoleValueRootIndex);
+  __ StoreP(r6, MemOperand(r5));
+
+  // Special handling of termination exceptions which are uncatchable
+  // by javascript code.
+  Label throw_termination_exception;
+  __ CompareRoot(r3, Heap::kTerminationExceptionRootIndex);
+  __ beq(&throw_termination_exception);
+
+  // Handle normal exception.
+  __ Throw(r3);
+
+  __ bind(&throw_termination_exception);
+  __ ThrowUncatchable(r3);
+}
+
+
+void JSEntryStub::Generate(MacroAssembler* masm) {
+  // r3: code entry
+  // r4: function
+  // r5: receiver
+  // r6: argc
+  // [sp+0]: argv
+
+  Label invoke, handler_entry, exit;
+
+// Called from C
+#if ABI_USES_FUNCTION_DESCRIPTORS
+  __ function_descriptor();
+#endif
+
+  ProfileEntryHookStub::MaybeCallEntryHook(masm);
+
+  // PPC LINUX ABI:
+  // preserve LR in pre-reserved slot in caller's frame
+  __ mflr(r0);
+  __ StoreP(r0, MemOperand(sp, kStackFrameLRSlot * kPointerSize));
+
+  // Save callee saved registers on the stack.
+  __ MultiPush(kCalleeSaved);
+
+  // Floating point regs FPR0 - FRP13 are volatile
+  // FPR14-FPR31 are non-volatile, but sub-calls will save them for us
+
+  //  int offset_to_argv = kPointerSize * 22; // matches (22*4) above
+  //  __ lwz(r7, MemOperand(sp, offset_to_argv));
+
+  // Push a frame with special values setup to mark it as an entry frame.
+  // r3: code entry
+  // r4: function
+  // r5: receiver
+  // r6: argc
+  // r7: argv
+  __ li(r0, Operand(-1));  // Push a bad frame pointer to fail if it is used.
+  __ push(r0);
+#if V8_OOL_CONSTANT_POOL
+  __ mov(kConstantPoolRegister,
+         Operand(isolate()->factory()->empty_constant_pool_array()));
+  __ push(kConstantPoolRegister);
+#endif
+  int marker = type();
+  __ LoadSmiLiteral(r0, Smi::FromInt(marker));
+  __ push(r0);
+  __ push(r0);
+  // Save copies of the top frame descriptor on the stack.
+  __ mov(r8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
+  __ LoadP(r0, MemOperand(r8));
+  __ push(r0);
+
+  // Set up frame pointer for the frame to be pushed.
+  __ addi(fp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
+
+  // If this is the outermost JS call, set js_entry_sp value.
+  Label non_outermost_js;
+  ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate());
+  __ mov(r8, Operand(ExternalReference(js_entry_sp)));
+  __ LoadP(r9, MemOperand(r8));
+  __ cmpi(r9, Operand::Zero());
+  __ bne(&non_outermost_js);
+  __ StoreP(fp, MemOperand(r8));
+  __ LoadSmiLiteral(ip, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME));
+  Label cont;
+  __ b(&cont);
+  __ bind(&non_outermost_js);
+  __ LoadSmiLiteral(ip, Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME));
+  __ bind(&cont);
+  __ push(ip);  // frame-type
+
+  // Jump to a faked try block that does the invoke, with a faked catch
+  // block that sets the pending exception.
+  __ b(&invoke);
+
+  __ bind(&handler_entry);
+  handler_offset_ = handler_entry.pos();
+  // Caught exception: Store result (exception) in the pending exception
+  // field in the JSEnv and return a failure sentinel.  Coming in here the
+  // fp will be invalid because the PushTryHandler below sets it to 0 to
+  // signal the existence of the JSEntry frame.
+  __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
+                                       isolate())));
+
+  __ StoreP(r3, MemOperand(ip));
+  __ LoadRoot(r3, Heap::kExceptionRootIndex);
+  __ b(&exit);
+
+  // Invoke: Link this frame into the handler chain.  There's only one
+  // handler block in this code object, so its index is 0.
+  __ bind(&invoke);
+  // Must preserve r0-r4, r5-r7 are available. (needs update for PPC)
+  __ PushTryHandler(StackHandler::JS_ENTRY, 0);
+  // If an exception not caught by another handler occurs, this handler
+  // returns control to the code after the b(&invoke) above, which
+  // restores all kCalleeSaved registers (including cp and fp) to their
+  // saved values before returning a failure to C.
+
+  // Clear any pending exceptions.
+  __ mov(r8, Operand(isolate()->factory()->the_hole_value()));
+  __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
+                                       isolate())));
+  __ StoreP(r8, MemOperand(ip));
+
+  // Invoke the function by calling through JS entry trampoline builtin.
+  // Notice that we cannot store a reference to the trampoline code directly in
+  // this stub, because runtime stubs are not traversed when doing GC.
+
+  // Expected registers by Builtins::JSEntryTrampoline
+  // r3: code entry
+  // r4: function
+  // r5: receiver
+  // r6: argc
+  // r7: argv
+  if (type() == StackFrame::ENTRY_CONSTRUCT) {
+    ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
+                                      isolate());
+    __ mov(ip, Operand(construct_entry));
+  } else {
+    ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
+    __ mov(ip, Operand(entry));
+  }
+  __ LoadP(ip, MemOperand(ip));  // deref address
+
+  // Branch and link to JSEntryTrampoline.
+  // the address points to the start of the code object, skip the header
+  __ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ mtctr(ip);
+  __ bctrl();  // make the call
+
+  // Unlink this frame from the handler chain.
+  __ PopTryHandler();
+
+  __ bind(&exit);  // r3 holds result
+  // Check if the current stack frame is marked as the outermost JS frame.
+  Label non_outermost_js_2;
+  __ pop(r8);
+  __ CmpSmiLiteral(r8, Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME), r0);
+  __ bne(&non_outermost_js_2);
+  __ mov(r9, Operand::Zero());
+  __ mov(r8, Operand(ExternalReference(js_entry_sp)));
+  __ StoreP(r9, MemOperand(r8));
+  __ bind(&non_outermost_js_2);
+
+  // Restore the top frame descriptors from the stack.
+  __ pop(r6);
+  __ mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
+  __ StoreP(r6, MemOperand(ip));
+
+  // Reset the stack to the callee saved registers.
+  __ addi(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
+
+// Restore callee-saved registers and return.
+#ifdef DEBUG
+  if (FLAG_debug_code) {
+    Label here;
+    __ b(&here, SetLK);
+    __ bind(&here);
+  }
+#endif
+
+  __ MultiPop(kCalleeSaved);
+
+  __ LoadP(r0, MemOperand(sp, kStackFrameLRSlot * kPointerSize));
+  __ mtctr(r0);
+  __ bctr();
+}
+
+
+// Uses registers r3 to r7.
+// Expected input (depending on whether args are in registers or on the stack):
+// * object: r3 or at sp + 1 * kPointerSize.
+// * function: r4 or at sp.
+//
+// An inlined call site may have been generated before calling this stub.
+// In this case the offset to the inline site to patch is passed in r8.
+// (See LCodeGen::DoInstanceOfKnownGlobal)
+void InstanceofStub::Generate(MacroAssembler* masm) {
+  // Call site inlining and patching implies arguments in registers.
+  DCHECK(HasArgsInRegisters() || !HasCallSiteInlineCheck());
+
+  // Fixed register usage throughout the stub:
+  const Register object = r3;     // Object (lhs).
+  Register map = r6;              // Map of the object.
+  const Register function = r4;   // Function (rhs).
+  const Register prototype = r7;  // Prototype of the function.
+  const Register inline_site = r9;
+  const Register scratch = r5;
+  Register scratch3 = no_reg;
+
+// delta = mov + unaligned LoadP + cmp + bne
+#if V8_TARGET_ARCH_PPC64
+  const int32_t kDeltaToLoadBoolResult =
+      (Assembler::kMovInstructions + 4) * Assembler::kInstrSize;
+#else
+  const int32_t kDeltaToLoadBoolResult =
+      (Assembler::kMovInstructions + 3) * Assembler::kInstrSize;
+#endif
+
+  Label slow, loop, is_instance, is_not_instance, not_js_object;
+
+  if (!HasArgsInRegisters()) {
+    __ LoadP(object, MemOperand(sp, 1 * kPointerSize));
+    __ LoadP(function, MemOperand(sp, 0));
+  }
+
+  // Check that the left hand is a JS object and load map.
+  __ JumpIfSmi(object, &not_js_object);
+  __ IsObjectJSObjectType(object, map, scratch, &not_js_object);
+
+  // If there is a call site cache don't look in the global cache, but do the
+  // real lookup and update the call site cache.
+  if (!HasCallSiteInlineCheck() && !ReturnTrueFalseObject()) {
+    Label miss;
+    __ CompareRoot(function, Heap::kInstanceofCacheFunctionRootIndex);
+    __ bne(&miss);
+    __ CompareRoot(map, Heap::kInstanceofCacheMapRootIndex);
+    __ bne(&miss);
+    __ LoadRoot(r3, Heap::kInstanceofCacheAnswerRootIndex);
+    __ Ret(HasArgsInRegisters() ? 0 : 2);
+
+    __ bind(&miss);
+  }
+
+  // Get the prototype of the function.
+  __ TryGetFunctionPrototype(function, prototype, scratch, &slow, true);
+
+  // Check that the function prototype is a JS object.
+  __ JumpIfSmi(prototype, &slow);
+  __ IsObjectJSObjectType(prototype, scratch, scratch, &slow);
+
+  // Update the global instanceof or call site inlined cache with the current
+  // map and function. The cached answer will be set when it is known below.
+  if (!HasCallSiteInlineCheck()) {
+    __ StoreRoot(function, Heap::kInstanceofCacheFunctionRootIndex);
+    __ StoreRoot(map, Heap::kInstanceofCacheMapRootIndex);
+  } else {
+    DCHECK(HasArgsInRegisters());
+    // Patch the (relocated) inlined map check.
+
+    // The offset was stored in r8
+    //   (See LCodeGen::DoDeferredLInstanceOfKnownGlobal).
+    const Register offset = r8;
+    __ mflr(inline_site);
+    __ sub(inline_site, inline_site, offset);
+    // Get the map location in r8 and patch it.
+    __ GetRelocatedValue(inline_site, offset, scratch);
+    __ StoreP(map, FieldMemOperand(offset, Cell::kValueOffset), r0);
+  }
+
+  // Register mapping: r6 is object map and r7 is function prototype.
+  // Get prototype of object into r5.
+  __ LoadP(scratch, FieldMemOperand(map, Map::kPrototypeOffset));
+
+  // We don't need map any more. Use it as a scratch register.
+  scratch3 = map;
+  map = no_reg;
+
+  // Loop through the prototype chain looking for the function prototype.
+  __ LoadRoot(scratch3, Heap::kNullValueRootIndex);
+  __ bind(&loop);
+  __ cmp(scratch, prototype);
+  __ beq(&is_instance);
+  __ cmp(scratch, scratch3);
+  __ beq(&is_not_instance);
+  __ LoadP(scratch, FieldMemOperand(scratch, HeapObject::kMapOffset));
+  __ LoadP(scratch, FieldMemOperand(scratch, Map::kPrototypeOffset));
+  __ b(&loop);
+  Factory* factory = isolate()->factory();
+
+  __ bind(&is_instance);
+  if (!HasCallSiteInlineCheck()) {
+    __ LoadSmiLiteral(r3, Smi::FromInt(0));
+    __ StoreRoot(r3, Heap::kInstanceofCacheAnswerRootIndex);
+    if (ReturnTrueFalseObject()) {
+      __ Move(r3, factory->true_value());
+    }
+  } else {
+    // Patch the call site to return true.
+    __ LoadRoot(r3, Heap::kTrueValueRootIndex);
+    __ addi(inline_site, inline_site, Operand(kDeltaToLoadBoolResult));
+    // Get the boolean result location in scratch and patch it.
+    __ SetRelocatedValue(inline_site, scratch, r3);
+
+    if (!ReturnTrueFalseObject()) {
+      __ LoadSmiLiteral(r3, Smi::FromInt(0));
+    }
+  }
+  __ Ret(HasArgsInRegisters() ? 0 : 2);
+
+  __ bind(&is_not_instance);
+  if (!HasCallSiteInlineCheck()) {
+    __ LoadSmiLiteral(r3, Smi::FromInt(1));
+    __ StoreRoot(r3, Heap::kInstanceofCacheAnswerRootIndex);
+    if (ReturnTrueFalseObject()) {
+      __ Move(r3, factory->false_value());
+    }
+  } else {
+    // Patch the call site to return false.
+    __ LoadRoot(r3, Heap::kFalseValueRootIndex);
+    __ addi(inline_site, inline_site, Operand(kDeltaToLoadBoolResult));
+    // Get the boolean result location in scratch and patch it.
+    __ SetRelocatedValue(inline_site, scratch, r3);
+
+    if (!ReturnTrueFalseObject()) {
+      __ LoadSmiLiteral(r3, Smi::FromInt(1));
+    }
+  }
+  __ Ret(HasArgsInRegisters() ? 0 : 2);
+
+  Label object_not_null, object_not_null_or_smi;
+  __ bind(&not_js_object);
+  // Before null, smi and string value checks, check that the rhs is a function
+  // as for a non-function rhs an exception needs to be thrown.
+  __ JumpIfSmi(function, &slow);
+  __ CompareObjectType(function, scratch3, scratch, JS_FUNCTION_TYPE);
+  __ bne(&slow);
+
+  // Null is not instance of anything.
+  __ Cmpi(object, Operand(isolate()->factory()->null_value()), r0);
+  __ bne(&object_not_null);
+  if (ReturnTrueFalseObject()) {
+    __ Move(r3, factory->false_value());
+  } else {
+    __ LoadSmiLiteral(r3, Smi::FromInt(1));
+  }
+  __ Ret(HasArgsInRegisters() ? 0 : 2);
+
+  __ bind(&object_not_null);
+  // Smi values are not instances of anything.
+  __ JumpIfNotSmi(object, &object_not_null_or_smi);
+  if (ReturnTrueFalseObject()) {
+    __ Move(r3, factory->false_value());
+  } else {
+    __ LoadSmiLiteral(r3, Smi::FromInt(1));
+  }
+  __ Ret(HasArgsInRegisters() ? 0 : 2);
+
+  __ bind(&object_not_null_or_smi);
+  // String values are not instances of anything.
+  __ IsObjectJSStringType(object, scratch, &slow);
+  if (ReturnTrueFalseObject()) {
+    __ Move(r3, factory->false_value());
+  } else {
+    __ LoadSmiLiteral(r3, Smi::FromInt(1));
+  }
+  __ Ret(HasArgsInRegisters() ? 0 : 2);
+
+  // Slow-case.  Tail call builtin.
+  __ bind(&slow);
+  if (!ReturnTrueFalseObject()) {
+    if (HasArgsInRegisters()) {
+      __ Push(r3, r4);
+    }
+    __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
+  } else {
+    {
+      FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+      __ Push(r3, r4);
+      __ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION);
+    }
+    Label true_value, done;
+    __ cmpi(r3, Operand::Zero());
+    __ beq(&true_value);
+
+    __ LoadRoot(r3, Heap::kFalseValueRootIndex);
+    __ b(&done);
+
+    __ bind(&true_value);
+    __ LoadRoot(r3, Heap::kTrueValueRootIndex);
+
+    __ bind(&done);
+    __ Ret(HasArgsInRegisters() ? 0 : 2);
+  }
+}
+
+
+void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
+  Label miss;
+  Register receiver = LoadDescriptor::ReceiverRegister();
+
+  NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r6,
+                                                          r7, &miss);
+  __ bind(&miss);
+  PropertyAccessCompiler::TailCallBuiltin(
+      masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
+}
+
+
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+  // Return address is in lr.
+  Label miss;
+
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register index = LoadDescriptor::NameRegister();
+  Register scratch = r6;
+  Register result = r3;
+  DCHECK(!scratch.is(receiver) && !scratch.is(index));
+
+  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+                                          &miss,  // When not a string.
+                                          &miss,  // When not a number.
+                                          &miss,  // When index out of range.
+                                          STRING_INDEX_IS_ARRAY_INDEX,
+                                          RECEIVER_IS_STRING);
+  char_at_generator.GenerateFast(masm);
+  __ Ret();
+
+  StubRuntimeCallHelper call_helper;
+  char_at_generator.GenerateSlow(masm, call_helper);
+
+  __ bind(&miss);
+  PropertyAccessCompiler::TailCallBuiltin(
+      masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
+
+
+void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
+  // The displacement is the offset of the last parameter (if any)
+  // relative to the frame pointer.
+  const int kDisplacement =
+      StandardFrameConstants::kCallerSPOffset - kPointerSize;
+  DCHECK(r4.is(ArgumentsAccessReadDescriptor::index()));
+  DCHECK(r3.is(ArgumentsAccessReadDescriptor::parameter_count()));
+
+  // Check that the key is a smi.
+  Label slow;
+  __ JumpIfNotSmi(r4, &slow);
+
+  // Check if the calling frame is an arguments adaptor frame.
+  Label adaptor;
+  __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ LoadP(r6, MemOperand(r5, StandardFrameConstants::kContextOffset));
+  STATIC_ASSERT(StackFrame::ARGUMENTS_ADAPTOR < 0x3fffu);
+  __ CmpSmiLiteral(r6, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0);
+  __ beq(&adaptor);
+
+  // Check index against formal parameters count limit passed in
+  // through register r3. Use unsigned comparison to get negative
+  // check for free.
+  __ cmpl(r4, r3);
+  __ bge(&slow);
+
+  // Read the argument from the stack and return it.
+  __ sub(r6, r3, r4);
+  __ SmiToPtrArrayOffset(r6, r6);
+  __ add(r6, fp, r6);
+  __ LoadP(r3, MemOperand(r6, kDisplacement));
+  __ blr();
+
+  // Arguments adaptor case: Check index against actual arguments
+  // limit found in the arguments adaptor frame. Use unsigned
+  // comparison to get negative check for free.
+  __ bind(&adaptor);
+  __ LoadP(r3, MemOperand(r5, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ cmpl(r4, r3);
+  __ bge(&slow);
+
+  // Read the argument from the adaptor frame and return it.
+  __ sub(r6, r3, r4);
+  __ SmiToPtrArrayOffset(r6, r6);
+  __ add(r6, r5, r6);
+  __ LoadP(r3, MemOperand(r6, kDisplacement));
+  __ blr();
+
+  // Slow-case: Handle non-smi or out-of-bounds access to arguments
+  // by calling the runtime system.
+  __ bind(&slow);
+  __ push(r4);
+  __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1);
+}
+
+
+void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
+  // sp[0] : number of parameters
+  // sp[1] : receiver displacement
+  // sp[2] : function
+
+  // Check if the calling frame is an arguments adaptor frame.
+  Label runtime;
+  __ LoadP(r6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ LoadP(r5, MemOperand(r6, StandardFrameConstants::kContextOffset));
+  STATIC_ASSERT(StackFrame::ARGUMENTS_ADAPTOR < 0x3fffu);
+  __ CmpSmiLiteral(r5, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0);
+  __ bne(&runtime);
+
+  // Patch the arguments.length and the parameters pointer in the current frame.
+  __ LoadP(r5, MemOperand(r6, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ StoreP(r5, MemOperand(sp, 0 * kPointerSize));
+  __ SmiToPtrArrayOffset(r5, r5);
+  __ add(r6, r6, r5);
+  __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset));
+  __ StoreP(r6, MemOperand(sp, 1 * kPointerSize));
+
+  __ bind(&runtime);
+  __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
+}
+
+
+void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
+  // Stack layout:
+  //  sp[0] : number of parameters (tagged)
+  //  sp[1] : address of receiver argument
+  //  sp[2] : function
+  // Registers used over whole function:
+  //  r9 : allocated object (tagged)
+  //  r11 : mapped parameter count (tagged)
+
+  __ LoadP(r4, MemOperand(sp, 0 * kPointerSize));
+  // r4 = parameter count (tagged)
+
+  // Check if the calling frame is an arguments adaptor frame.
+  Label runtime;
+  Label adaptor_frame, try_allocate;
+  __ LoadP(r6, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ LoadP(r5, MemOperand(r6, StandardFrameConstants::kContextOffset));
+  STATIC_ASSERT(StackFrame::ARGUMENTS_ADAPTOR < 0x3fffu);
+  __ CmpSmiLiteral(r5, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0);
+  __ beq(&adaptor_frame);
+
+  // No adaptor, parameter count = argument count.
+  __ mr(r5, r4);
+  __ b(&try_allocate);
+
+  // We have an adaptor frame. Patch the parameters pointer.
+  __ bind(&adaptor_frame);
+  __ LoadP(r5, MemOperand(r6, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ SmiToPtrArrayOffset(r7, r5);
+  __ add(r6, r6, r7);
+  __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset));
+  __ StoreP(r6, MemOperand(sp, 1 * kPointerSize));
+
+  // r4 = parameter count (tagged)
+  // r5 = argument count (tagged)
+  // Compute the mapped parameter count = min(r4, r5) in r4.
+  Label skip;
+  __ cmp(r4, r5);
+  __ blt(&skip);
+  __ mr(r4, r5);
+  __ bind(&skip);
+
+  __ bind(&try_allocate);
+
+  // Compute the sizes of backing store, parameter map, and arguments object.
+  // 1. Parameter map, has 2 extra words containing context and backing store.
+  const int kParameterMapHeaderSize =
+      FixedArray::kHeaderSize + 2 * kPointerSize;
+  // If there are no mapped parameters, we do not need the parameter_map.
+  Label skip2, skip3;
+  __ CmpSmiLiteral(r4, Smi::FromInt(0), r0);
+  __ bne(&skip2);
+  __ li(r11, Operand::Zero());
+  __ b(&skip3);
+  __ bind(&skip2);
+  __ SmiToPtrArrayOffset(r11, r4);
+  __ addi(r11, r11, Operand(kParameterMapHeaderSize));
+  __ bind(&skip3);
+
+  // 2. Backing store.
+  __ SmiToPtrArrayOffset(r7, r5);
+  __ add(r11, r11, r7);
+  __ addi(r11, r11, Operand(FixedArray::kHeaderSize));
+
+  // 3. Arguments object.
+  __ addi(r11, r11, Operand(Heap::kSloppyArgumentsObjectSize));
+
+  // Do the allocation of all three objects in one go.
+  __ Allocate(r11, r3, r6, r7, &runtime, TAG_OBJECT);
+
+  // r3 = address of new object(s) (tagged)
+  // r5 = argument count (smi-tagged)
+  // Get the arguments boilerplate from the current native context into r4.
+  const int kNormalOffset =
+      Context::SlotOffset(Context::SLOPPY_ARGUMENTS_MAP_INDEX);
+  const int kAliasedOffset =
+      Context::SlotOffset(Context::ALIASED_ARGUMENTS_MAP_INDEX);
+
+  __ LoadP(r7,
+           MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+  __ LoadP(r7, FieldMemOperand(r7, GlobalObject::kNativeContextOffset));
+  Label skip4, skip5;
+  __ cmpi(r4, Operand::Zero());
+  __ bne(&skip4);
+  __ LoadP(r7, MemOperand(r7, kNormalOffset));
+  __ b(&skip5);
+  __ bind(&skip4);
+  __ LoadP(r7, MemOperand(r7, kAliasedOffset));
+  __ bind(&skip5);
+
+  // r3 = address of new object (tagged)
+  // r4 = mapped parameter count (tagged)
+  // r5 = argument count (smi-tagged)
+  // r7 = address of arguments map (tagged)
+  __ StoreP(r7, FieldMemOperand(r3, JSObject::kMapOffset), r0);
+  __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex);
+  __ StoreP(r6, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0);
+  __ StoreP(r6, FieldMemOperand(r3, JSObject::kElementsOffset), r0);
+
+  // Set up the callee in-object property.
+  STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
+  __ LoadP(r6, MemOperand(sp, 2 * kPointerSize));
+  __ AssertNotSmi(r6);
+  const int kCalleeOffset =
+      JSObject::kHeaderSize + Heap::kArgumentsCalleeIndex * kPointerSize;
+  __ StoreP(r6, FieldMemOperand(r3, kCalleeOffset), r0);
+
+  // Use the length (smi tagged) and set that as an in-object property too.
+  __ AssertSmi(r5);
+  STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
+  const int kLengthOffset =
+      JSObject::kHeaderSize + Heap::kArgumentsLengthIndex * kPointerSize;
+  __ StoreP(r5, FieldMemOperand(r3, kLengthOffset), r0);
+
+  // Set up the elements pointer in the allocated arguments object.
+  // If we allocated a parameter map, r7 will point there, otherwise
+  // it will point to the backing store.
+  __ addi(r7, r3, Operand(Heap::kSloppyArgumentsObjectSize));
+  __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0);
+
+  // r3 = address of new object (tagged)
+  // r4 = mapped parameter count (tagged)
+  // r5 = argument count (tagged)
+  // r7 = address of parameter map or backing store (tagged)
+  // Initialize parameter map. If there are no mapped arguments, we're done.
+  Label skip_parameter_map, skip6;
+  __ CmpSmiLiteral(r4, Smi::FromInt(0), r0);
+  __ bne(&skip6);
+  // Move backing store address to r6, because it is
+  // expected there when filling in the unmapped arguments.
+  __ mr(r6, r7);
+  __ b(&skip_parameter_map);
+  __ bind(&skip6);
+
+  __ LoadRoot(r9, Heap::kSloppyArgumentsElementsMapRootIndex);
+  __ StoreP(r9, FieldMemOperand(r7, FixedArray::kMapOffset), r0);
+  __ AddSmiLiteral(r9, r4, Smi::FromInt(2), r0);
+  __ StoreP(r9, FieldMemOperand(r7, FixedArray::kLengthOffset), r0);
+  __ StoreP(cp, FieldMemOperand(r7, FixedArray::kHeaderSize + 0 * kPointerSize),
+            r0);
+  __ SmiToPtrArrayOffset(r9, r4);
+  __ add(r9, r7, r9);
+  __ addi(r9, r9, Operand(kParameterMapHeaderSize));
+  __ StoreP(r9, FieldMemOperand(r7, FixedArray::kHeaderSize + 1 * kPointerSize),
+            r0);
+
+  // Copy the parameter slots and the holes in the arguments.
+  // We need to fill in mapped_parameter_count slots. They index the context,
+  // where parameters are stored in reverse order, at
+  //   MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
+  // The mapped parameter thus need to get indices
+  //   MIN_CONTEXT_SLOTS+parameter_count-1 ..
+  //       MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
+  // We loop from right to left.
+  Label parameters_loop, parameters_test;
+  __ mr(r9, r4);
+  __ LoadP(r11, MemOperand(sp, 0 * kPointerSize));
+  __ AddSmiLiteral(r11, r11, Smi::FromInt(Context::MIN_CONTEXT_SLOTS), r0);
+  __ sub(r11, r11, r4);
+  __ LoadRoot(r10, Heap::kTheHoleValueRootIndex);
+  __ SmiToPtrArrayOffset(r6, r9);
+  __ add(r6, r7, r6);
+  __ addi(r6, r6, Operand(kParameterMapHeaderSize));
+
+  // r9 = loop variable (tagged)
+  // r4 = mapping index (tagged)
+  // r6 = address of backing store (tagged)
+  // r7 = address of parameter map (tagged)
+  // r8 = temporary scratch (a.o., for address calculation)
+  // r10 = the hole value
+  __ b(&parameters_test);
+
+  __ bind(&parameters_loop);
+  __ SubSmiLiteral(r9, r9, Smi::FromInt(1), r0);
+  __ SmiToPtrArrayOffset(r8, r9);
+  __ addi(r8, r8, Operand(kParameterMapHeaderSize - kHeapObjectTag));
+  __ StorePX(r11, MemOperand(r8, r7));
+  __ subi(r8, r8, Operand(kParameterMapHeaderSize - FixedArray::kHeaderSize));
+  __ StorePX(r10, MemOperand(r8, r6));
+  __ AddSmiLiteral(r11, r11, Smi::FromInt(1), r0);
+  __ bind(&parameters_test);
+  __ CmpSmiLiteral(r9, Smi::FromInt(0), r0);
+  __ bne(&parameters_loop);
+
+  __ bind(&skip_parameter_map);
+  // r5 = argument count (tagged)
+  // r6 = address of backing store (tagged)
+  // r8 = scratch
+  // Copy arguments header and remaining slots (if there are any).
+  __ LoadRoot(r8, Heap::kFixedArrayMapRootIndex);
+  __ StoreP(r8, FieldMemOperand(r6, FixedArray::kMapOffset), r0);
+  __ StoreP(r5, FieldMemOperand(r6, FixedArray::kLengthOffset), r0);
+
+  Label arguments_loop, arguments_test;
+  __ mr(r11, r4);
+  __ LoadP(r7, MemOperand(sp, 1 * kPointerSize));
+  __ SmiToPtrArrayOffset(r8, r11);
+  __ sub(r7, r7, r8);
+  __ b(&arguments_test);
+
+  __ bind(&arguments_loop);
+  __ subi(r7, r7, Operand(kPointerSize));
+  __ LoadP(r9, MemOperand(r7, 0));
+  __ SmiToPtrArrayOffset(r8, r11);
+  __ add(r8, r6, r8);
+  __ StoreP(r9, FieldMemOperand(r8, FixedArray::kHeaderSize), r0);
+  __ AddSmiLiteral(r11, r11, Smi::FromInt(1), r0);
+
+  __ bind(&arguments_test);
+  __ cmp(r11, r5);
+  __ blt(&arguments_loop);
+
+  // Return and remove the on-stack parameters.
+  __ addi(sp, sp, Operand(3 * kPointerSize));
+  __ Ret();
+
+  // Do the runtime call to allocate the arguments object.
+  // r5 = argument count (tagged)
+  __ bind(&runtime);
+  __ StoreP(r5, MemOperand(sp, 0 * kPointerSize));  // Patch argument count.
+  __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
+}
+
+
+void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) {
+  // Return address is in lr.
+  Label slow;
+
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register key = LoadDescriptor::NameRegister();
+
+  // Check that the key is an array index, that is Uint32.
+  __ TestIfPositiveSmi(key, r0);
+  __ bne(&slow, cr0);
+
+  // Everything is fine, call runtime.
+  __ Push(receiver, key);  // Receiver, key.
+
+  // Perform tail call to the entry.
+  __ TailCallExternalReference(
+      ExternalReference(IC_Utility(IC::kLoadElementWithInterceptor),
+                        masm->isolate()),
+      2, 1);
+
+  __ bind(&slow);
+  PropertyAccessCompiler::TailCallBuiltin(
+      masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
+
+
+void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
+  // sp[0] : number of parameters
+  // sp[4] : receiver displacement
+  // sp[8] : function
+  // Check if the calling frame is an arguments adaptor frame.
+  Label adaptor_frame, try_allocate, runtime;
+  __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ LoadP(r6, MemOperand(r5, StandardFrameConstants::kContextOffset));
+  STATIC_ASSERT(StackFrame::ARGUMENTS_ADAPTOR < 0x3fffu);
+  __ CmpSmiLiteral(r6, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0);
+  __ beq(&adaptor_frame);
+
+  // Get the length from the frame.
+  __ LoadP(r4, MemOperand(sp, 0));
+  __ b(&try_allocate);
+
+  // Patch the arguments.length and the parameters pointer.
+  __ bind(&adaptor_frame);
+  __ LoadP(r4, MemOperand(r5, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ StoreP(r4, MemOperand(sp, 0));
+  __ SmiToPtrArrayOffset(r6, r4);
+  __ add(r6, r5, r6);
+  __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset));
+  __ StoreP(r6, MemOperand(sp, 1 * kPointerSize));
+
+  // Try the new space allocation. Start out with computing the size
+  // of the arguments object and the elements array in words.
+  Label add_arguments_object;
+  __ bind(&try_allocate);
+  __ cmpi(r4, Operand::Zero());
+  __ beq(&add_arguments_object);
+  __ SmiUntag(r4);
+  __ addi(r4, r4, Operand(FixedArray::kHeaderSize / kPointerSize));
+  __ bind(&add_arguments_object);
+  __ addi(r4, r4, Operand(Heap::kStrictArgumentsObjectSize / kPointerSize));
+
+  // Do the allocation of both objects in one go.
+  __ Allocate(r4, r3, r5, r6, &runtime,
+              static_cast<AllocationFlags>(TAG_OBJECT | SIZE_IN_WORDS));
+
+  // Get the arguments boilerplate from the current native context.
+  __ LoadP(r7,
+           MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+  __ LoadP(r7, FieldMemOperand(r7, GlobalObject::kNativeContextOffset));
+  __ LoadP(
+      r7,
+      MemOperand(r7, Context::SlotOffset(Context::STRICT_ARGUMENTS_MAP_INDEX)));
+
+  __ StoreP(r7, FieldMemOperand(r3, JSObject::kMapOffset), r0);
+  __ LoadRoot(r6, Heap::kEmptyFixedArrayRootIndex);
+  __ StoreP(r6, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0);
+  __ StoreP(r6, FieldMemOperand(r3, JSObject::kElementsOffset), r0);
+
+  // Get the length (smi tagged) and set that as an in-object property too.
+  STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
+  __ LoadP(r4, MemOperand(sp, 0 * kPointerSize));
+  __ AssertSmi(r4);
+  __ StoreP(r4,
+            FieldMemOperand(r3, JSObject::kHeaderSize +
+                                    Heap::kArgumentsLengthIndex * kPointerSize),
+            r0);
+
+  // If there are no actual arguments, we're done.
+  Label done;
+  __ cmpi(r4, Operand::Zero());
+  __ beq(&done);
+
+  // Get the parameters pointer from the stack.
+  __ LoadP(r5, MemOperand(sp, 1 * kPointerSize));
+
+  // Set up the elements pointer in the allocated arguments object and
+  // initialize the header in the elements fixed array.
+  __ addi(r7, r3, Operand(Heap::kStrictArgumentsObjectSize));
+  __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0);
+  __ LoadRoot(r6, Heap::kFixedArrayMapRootIndex);
+  __ StoreP(r6, FieldMemOperand(r7, FixedArray::kMapOffset), r0);
+  __ StoreP(r4, FieldMemOperand(r7, FixedArray::kLengthOffset), r0);
+  // Untag the length for the loop.
+  __ SmiUntag(r4);
+
+  // Copy the fixed array slots.
+  Label loop;
+  // Set up r7 to point just prior to the first array slot.
+  __ addi(r7, r7,
+          Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize));
+  __ mtctr(r4);
+  __ bind(&loop);
+  // Pre-decrement r5 with kPointerSize on each iteration.
+  // Pre-decrement in order to skip receiver.
+  __ LoadPU(r6, MemOperand(r5, -kPointerSize));
+  // Pre-increment r7 with kPointerSize on each iteration.
+  __ StorePU(r6, MemOperand(r7, kPointerSize));
+  __ bdnz(&loop);
+
+  // Return and remove the on-stack parameters.
+  __ bind(&done);
+  __ addi(sp, sp, Operand(3 * kPointerSize));
+  __ Ret();
+
+  // Do the runtime call to allocate the arguments object.
+  __ bind(&runtime);
+  __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1);
+}
+
+
+void RegExpExecStub::Generate(MacroAssembler* masm) {
+// Just jump directly to runtime if native RegExp is not selected at compile
+// time or if regexp entry in generated code is turned off runtime switch or
+// at compilation.
+#ifdef V8_INTERPRETED_REGEXP
+  __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1);
+#else  // V8_INTERPRETED_REGEXP
+
+  // Stack frame on entry.
+  //  sp[0]: last_match_info (expected JSArray)
+  //  sp[4]: previous index
+  //  sp[8]: subject string
+  //  sp[12]: JSRegExp object
+
+  const int kLastMatchInfoOffset = 0 * kPointerSize;
+  const int kPreviousIndexOffset = 1 * kPointerSize;
+  const int kSubjectOffset = 2 * kPointerSize;
+  const int kJSRegExpOffset = 3 * kPointerSize;
+
+  Label runtime, br_over, encoding_type_UC16;
+
+  // Allocation of registers for this function. These are in callee save
+  // registers and will be preserved by the call to the native RegExp code, as
+  // this code is called using the normal C calling convention. When calling
+  // directly from generated code the native RegExp code will not do a GC and
+  // therefore the content of these registers are safe to use after the call.
+  Register subject = r14;
+  Register regexp_data = r15;
+  Register last_match_info_elements = r16;
+  Register code = r17;
+
+  // Ensure register assigments are consistent with callee save masks
+  DCHECK(subject.bit() & kCalleeSaved);
+  DCHECK(regexp_data.bit() & kCalleeSaved);
+  DCHECK(last_match_info_elements.bit() & kCalleeSaved);
+  DCHECK(code.bit() & kCalleeSaved);
+
+  // Ensure that a RegExp stack is allocated.
+  ExternalReference address_of_regexp_stack_memory_address =
+      ExternalReference::address_of_regexp_stack_memory_address(isolate());
+  ExternalReference address_of_regexp_stack_memory_size =
+      ExternalReference::address_of_regexp_stack_memory_size(isolate());
+  __ mov(r3, Operand(address_of_regexp_stack_memory_size));
+  __ LoadP(r3, MemOperand(r3, 0));
+  __ cmpi(r3, Operand::Zero());
+  __ beq(&runtime);
+
+  // Check that the first argument is a JSRegExp object.
+  __ LoadP(r3, MemOperand(sp, kJSRegExpOffset));
+  __ JumpIfSmi(r3, &runtime);
+  __ CompareObjectType(r3, r4, r4, JS_REGEXP_TYPE);
+  __ bne(&runtime);
+
+  // Check that the RegExp has been compiled (data contains a fixed array).
+  __ LoadP(regexp_data, FieldMemOperand(r3, JSRegExp::kDataOffset));
+  if (FLAG_debug_code) {
+    __ TestIfSmi(regexp_data, r0);
+    __ Check(ne, kUnexpectedTypeForRegExpDataFixedArrayExpected, cr0);
+    __ CompareObjectType(regexp_data, r3, r3, FIXED_ARRAY_TYPE);
+    __ Check(eq, kUnexpectedTypeForRegExpDataFixedArrayExpected);
+  }
+
+  // regexp_data: RegExp data (FixedArray)
+  // Check the type of the RegExp. Only continue if type is JSRegExp::IRREGEXP.
+  __ LoadP(r3, FieldMemOperand(regexp_data, JSRegExp::kDataTagOffset));
+  // DCHECK(Smi::FromInt(JSRegExp::IRREGEXP) < (char *)0xffffu);
+  __ CmpSmiLiteral(r3, Smi::FromInt(JSRegExp::IRREGEXP), r0);
+  __ bne(&runtime);
+
+  // regexp_data: RegExp data (FixedArray)
+  // Check that the number of captures fit in the static offsets vector buffer.
+  __ LoadP(r5,
+           FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset));
+  // Check (number_of_captures + 1) * 2 <= offsets vector size
+  // Or          number_of_captures * 2 <= offsets vector size - 2
+  // SmiToShortArrayOffset accomplishes the multiplication by 2 and
+  // SmiUntag (which is a nop for 32-bit).
+  __ SmiToShortArrayOffset(r5, r5);
+  STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2);
+  __ cmpli(r5, Operand(Isolate::kJSRegexpStaticOffsetsVectorSize - 2));
+  __ bgt(&runtime);
+
+  // Reset offset for possibly sliced string.
+  __ li(r11, Operand::Zero());
+  __ LoadP(subject, MemOperand(sp, kSubjectOffset));
+  __ JumpIfSmi(subject, &runtime);
+  __ mr(r6, subject);  // Make a copy of the original subject string.
+  __ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
+  __ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
+  // subject: subject string
+  // r6: subject string
+  // r3: subject string instance type
+  // regexp_data: RegExp data (FixedArray)
+  // Handle subject string according to its encoding and representation:
+  // (1) Sequential string?  If yes, go to (5).
+  // (2) Anything but sequential or cons?  If yes, go to (6).
+  // (3) Cons string.  If the string is flat, replace subject with first string.
+  //     Otherwise bailout.
+  // (4) Is subject external?  If yes, go to (7).
+  // (5) Sequential string.  Load regexp code according to encoding.
+  // (E) Carry on.
+  /// [...]
+
+  // Deferred code at the end of the stub:
+  // (6) Not a long external string?  If yes, go to (8).
+  // (7) External string.  Make it, offset-wise, look like a sequential string.
+  //     Go to (5).
+  // (8) Short external string or not a string?  If yes, bail out to runtime.
+  // (9) Sliced string.  Replace subject with parent.  Go to (4).
+
+  Label seq_string /* 5 */, external_string /* 7 */, check_underlying /* 4 */,
+      not_seq_nor_cons /* 6 */, not_long_external /* 8 */;
+
+  // (1) Sequential string?  If yes, go to (5).
+  STATIC_ASSERT((kIsNotStringMask | kStringRepresentationMask |
+                 kShortExternalStringMask) == 0x93);
+  __ andi(r4, r3, Operand(kIsNotStringMask | kStringRepresentationMask |
+                          kShortExternalStringMask));
+  STATIC_ASSERT((kStringTag | kSeqStringTag) == 0);
+  __ beq(&seq_string, cr0);  // Go to (5).
+
+  // (2) Anything but sequential or cons?  If yes, go to (6).
+  STATIC_ASSERT(kConsStringTag < kExternalStringTag);
+  STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
+  STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
+  STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
+  STATIC_ASSERT(kExternalStringTag < 0xffffu);
+  __ cmpi(r4, Operand(kExternalStringTag));
+  __ bge(&not_seq_nor_cons);  // Go to (6).
+
+  // (3) Cons string.  Check that it's flat.
+  // Replace subject with first string and reload instance type.
+  __ LoadP(r3, FieldMemOperand(subject, ConsString::kSecondOffset));
+  __ CompareRoot(r3, Heap::kempty_stringRootIndex);
+  __ bne(&runtime);
+  __ LoadP(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
+
+  // (4) Is subject external?  If yes, go to (7).
+  __ bind(&check_underlying);
+  __ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
+  __ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
+  STATIC_ASSERT(kSeqStringTag == 0);
+  STATIC_ASSERT(kStringRepresentationMask == 3);
+  __ andi(r0, r3, Operand(kStringRepresentationMask));
+  // The underlying external string is never a short external string.
+  STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
+  STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
+  __ bne(&external_string, cr0);  // Go to (7).
+
+  // (5) Sequential string.  Load regexp code according to encoding.
+  __ bind(&seq_string);
+  // subject: sequential subject string (or look-alike, external string)
+  // r6: original subject string
+  // Load previous index and check range before r6 is overwritten.  We have to
+  // use r6 instead of subject here because subject might have been only made
+  // to look like a sequential string when it actually is an external string.
+  __ LoadP(r4, MemOperand(sp, kPreviousIndexOffset));
+  __ JumpIfNotSmi(r4, &runtime);
+  __ LoadP(r6, FieldMemOperand(r6, String::kLengthOffset));
+  __ cmpl(r6, r4);
+  __ ble(&runtime);
+  __ SmiUntag(r4);
+
+  STATIC_ASSERT(4 == kOneByteStringTag);
+  STATIC_ASSERT(kTwoByteStringTag == 0);
+  STATIC_ASSERT(kStringEncodingMask == 4);
+  __ ExtractBitMask(r6, r3, kStringEncodingMask, SetRC);
+  __ beq(&encoding_type_UC16, cr0);
+  __ LoadP(code,
+           FieldMemOperand(regexp_data, JSRegExp::kDataOneByteCodeOffset));
+  __ b(&br_over);
+  __ bind(&encoding_type_UC16);
+  __ LoadP(code, FieldMemOperand(regexp_data, JSRegExp::kDataUC16CodeOffset));
+  __ bind(&br_over);
+
+  // (E) Carry on.  String handling is done.
+  // code: irregexp code
+  // Check that the irregexp code has been generated for the actual string
+  // encoding. If it has, the field contains a code object otherwise it contains
+  // a smi (code flushing support).
+  __ JumpIfSmi(code, &runtime);
+
+  // r4: previous index
+  // r6: encoding of subject string (1 if one_byte, 0 if two_byte);
+  // code: Address of generated regexp code
+  // subject: Subject string
+  // regexp_data: RegExp data (FixedArray)
+  // All checks done. Now push arguments for native regexp code.
+  __ IncrementCounter(isolate()->counters()->regexp_entry_native(), 1, r3, r5);
+
+  // Isolates: note we add an additional parameter here (isolate pointer).
+  const int kRegExpExecuteArguments = 10;
+  const int kParameterRegisters = 8;
+  __ EnterExitFrame(false, kRegExpExecuteArguments - kParameterRegisters);
+
+  // Stack pointer now points to cell where return address is to be written.
+  // Arguments are before that on the stack or in registers.
+
+  // Argument 10 (in stack parameter area): Pass current isolate address.
+  __ mov(r3, Operand(ExternalReference::isolate_address(isolate())));
+  __ StoreP(r3, MemOperand(sp, (kStackFrameExtraParamSlot + 1) * kPointerSize));
+
+  // Argument 9 is a dummy that reserves the space used for
+  // the return address added by the ExitFrame in native calls.
+
+  // Argument 8 (r10): Indicate that this is a direct call from JavaScript.
+  __ li(r10, Operand(1));
+
+  // Argument 7 (r9): Start (high end) of backtracking stack memory area.
+  __ mov(r3, Operand(address_of_regexp_stack_memory_address));
+  __ LoadP(r3, MemOperand(r3, 0));
+  __ mov(r5, Operand(address_of_regexp_stack_memory_size));
+  __ LoadP(r5, MemOperand(r5, 0));
+  __ add(r9, r3, r5);
+
+  // Argument 6 (r8): Set the number of capture registers to zero to force
+  // global egexps to behave as non-global.  This does not affect non-global
+  // regexps.
+  __ li(r8, Operand::Zero());
+
+  // Argument 5 (r7): static offsets vector buffer.
+  __ mov(
+      r7,
+      Operand(ExternalReference::address_of_static_offsets_vector(isolate())));
+
+  // For arguments 4 (r6) and 3 (r5) get string length, calculate start of data
+  // and calculate the shift of the index (0 for one-byte and 1 for two-byte).
+  __ addi(r18, subject, Operand(SeqString::kHeaderSize - kHeapObjectTag));
+  __ xori(r6, r6, Operand(1));
+  // Load the length from the original subject string from the previous stack
+  // frame. Therefore we have to use fp, which points exactly to two pointer
+  // sizes below the previous sp. (Because creating a new stack frame pushes
+  // the previous fp onto the stack and moves up sp by 2 * kPointerSize.)
+  __ LoadP(subject, MemOperand(fp, kSubjectOffset + 2 * kPointerSize));
+  // If slice offset is not 0, load the length from the original sliced string.
+  // Argument 4, r6: End of string data
+  // Argument 3, r5: Start of string data
+  // Prepare start and end index of the input.
+  __ ShiftLeft_(r11, r11, r6);
+  __ add(r11, r18, r11);
+  __ ShiftLeft_(r5, r4, r6);
+  __ add(r5, r11, r5);
+
+  __ LoadP(r18, FieldMemOperand(subject, String::kLengthOffset));
+  __ SmiUntag(r18);
+  __ ShiftLeft_(r6, r18, r6);
+  __ add(r6, r11, r6);
+
+  // Argument 2 (r4): Previous index.
+  // Already there
+
+  // Argument 1 (r3): Subject string.
+  __ mr(r3, subject);
+
+  // Locate the code entry and call it.
+  __ addi(code, code, Operand(Code::kHeaderSize - kHeapObjectTag));
+
+
+#if ABI_USES_FUNCTION_DESCRIPTORS && defined(USE_SIMULATOR)
+  // Even Simulated AIX/PPC64 Linux uses a function descriptor for the
+  // RegExp routine.  Extract the instruction address here since
+  // DirectCEntryStub::GenerateCall will not do it for calls out to
+  // what it thinks is C code compiled for the simulator/host
+  // platform.
+  __ LoadP(code, MemOperand(code, 0));  // Instruction address
+#endif
+
+  DirectCEntryStub stub(isolate());
+  stub.GenerateCall(masm, code);
+
+  __ LeaveExitFrame(false, no_reg, true);
+
+  // r3: result
+  // subject: subject string (callee saved)
+  // regexp_data: RegExp data (callee saved)
+  // last_match_info_elements: Last match info elements (callee saved)
+  // Check the result.
+  Label success;
+  __ cmpi(r3, Operand(1));
+  // We expect exactly one result since we force the called regexp to behave
+  // as non-global.
+  __ beq(&success);
+  Label failure;
+  __ cmpi(r3, Operand(NativeRegExpMacroAssembler::FAILURE));
+  __ beq(&failure);
+  __ cmpi(r3, Operand(NativeRegExpMacroAssembler::EXCEPTION));
+  // If not exception it can only be retry. Handle that in the runtime system.
+  __ bne(&runtime);
+  // Result must now be exception. If there is no pending exception already a
+  // stack overflow (on the backtrack stack) was detected in RegExp code but
+  // haven't created the exception yet. Handle that in the runtime system.
+  // TODO(592): Rerunning the RegExp to get the stack overflow exception.
+  __ mov(r4, Operand(isolate()->factory()->the_hole_value()));
+  __ mov(r5, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
+                                       isolate())));
+  __ LoadP(r3, MemOperand(r5, 0));
+  __ cmp(r3, r4);
+  __ beq(&runtime);
+
+  __ StoreP(r4, MemOperand(r5, 0));  // Clear pending exception.
+
+  // Check if the exception is a termination. If so, throw as uncatchable.
+  __ CompareRoot(r3, Heap::kTerminationExceptionRootIndex);
+
+  Label termination_exception;
+  __ beq(&termination_exception);
+
+  __ Throw(r3);
+
+  __ bind(&termination_exception);
+  __ ThrowUncatchable(r3);
+
+  __ bind(&failure);
+  // For failure and exception return null.
+  __ mov(r3, Operand(isolate()->factory()->null_value()));
+  __ addi(sp, sp, Operand(4 * kPointerSize));
+  __ Ret();
+
+  // Process the result from the native regexp code.
+  __ bind(&success);
+  __ LoadP(r4,
+           FieldMemOperand(regexp_data, JSRegExp::kIrregexpCaptureCountOffset));
+  // Calculate number of capture registers (number_of_captures + 1) * 2.
+  // SmiToShortArrayOffset accomplishes the multiplication by 2 and
+  // SmiUntag (which is a nop for 32-bit).
+  __ SmiToShortArrayOffset(r4, r4);
+  __ addi(r4, r4, Operand(2));
+
+  __ LoadP(r3, MemOperand(sp, kLastMatchInfoOffset));
+  __ JumpIfSmi(r3, &runtime);
+  __ CompareObjectType(r3, r5, r5, JS_ARRAY_TYPE);
+  __ bne(&runtime);
+  // Check that the JSArray is in fast case.
+  __ LoadP(last_match_info_elements,
+           FieldMemOperand(r3, JSArray::kElementsOffset));
+  __ LoadP(r3,
+           FieldMemOperand(last_match_info_elements, HeapObject::kMapOffset));
+  __ CompareRoot(r3, Heap::kFixedArrayMapRootIndex);
+  __ bne(&runtime);
+  // Check that the last match info has space for the capture registers and the
+  // additional information.
+  __ LoadP(
+      r3, FieldMemOperand(last_match_info_elements, FixedArray::kLengthOffset));
+  __ addi(r5, r4, Operand(RegExpImpl::kLastMatchOverhead));
+  __ SmiUntag(r0, r3);
+  __ cmp(r5, r0);
+  __ bgt(&runtime);
+
+  // r4: number of capture registers
+  // subject: subject string
+  // Store the capture count.
+  __ SmiTag(r5, r4);
+  __ StoreP(r5, FieldMemOperand(last_match_info_elements,
+                                RegExpImpl::kLastCaptureCountOffset),
+            r0);
+  // Store last subject and last input.
+  __ StoreP(subject, FieldMemOperand(last_match_info_elements,
+                                     RegExpImpl::kLastSubjectOffset),
+            r0);
+  __ mr(r5, subject);
+  __ RecordWriteField(last_match_info_elements, RegExpImpl::kLastSubjectOffset,
+                      subject, r10, kLRHasNotBeenSaved, kDontSaveFPRegs);
+  __ mr(subject, r5);
+  __ StoreP(subject, FieldMemOperand(last_match_info_elements,
+                                     RegExpImpl::kLastInputOffset),
+            r0);
+  __ RecordWriteField(last_match_info_elements, RegExpImpl::kLastInputOffset,
+                      subject, r10, kLRHasNotBeenSaved, kDontSaveFPRegs);
+
+  // Get the static offsets vector filled by the native regexp code.
+  ExternalReference address_of_static_offsets_vector =
+      ExternalReference::address_of_static_offsets_vector(isolate());
+  __ mov(r5, Operand(address_of_static_offsets_vector));
+
+  // r4: number of capture registers
+  // r5: offsets vector
+  Label next_capture;
+  // Capture register counter starts from number of capture registers and
+  // counts down until wraping after zero.
+  __ addi(
+      r3, last_match_info_elements,
+      Operand(RegExpImpl::kFirstCaptureOffset - kHeapObjectTag - kPointerSize));
+  __ addi(r5, r5, Operand(-kIntSize));  // bias down for lwzu
+  __ mtctr(r4);
+  __ bind(&next_capture);
+  // Read the value from the static offsets vector buffer.
+  __ lwzu(r6, MemOperand(r5, kIntSize));
+  // Store the smi value in the last match info.
+  __ SmiTag(r6);
+  __ StorePU(r6, MemOperand(r3, kPointerSize));
+  __ bdnz(&next_capture);
+
+  // Return last match info.
+  __ LoadP(r3, MemOperand(sp, kLastMatchInfoOffset));
+  __ addi(sp, sp, Operand(4 * kPointerSize));
+  __ Ret();
+
+  // Do the runtime call to execute the regexp.
+  __ bind(&runtime);
+  __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1);
+
+  // Deferred code for string handling.
+  // (6) Not a long external string?  If yes, go to (8).
+  __ bind(&not_seq_nor_cons);
+  // Compare flags are still set.
+  __ bgt(&not_long_external);  // Go to (8).
+
+  // (7) External string.  Make it, offset-wise, look like a sequential string.
+  __ bind(&external_string);
+  __ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
+  __ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
+  if (FLAG_debug_code) {
+    // Assert that we do not have a cons or slice (indirect strings) here.
+    // Sequential strings have already been ruled out.
+    STATIC_ASSERT(kIsIndirectStringMask == 1);
+    __ andi(r0, r3, Operand(kIsIndirectStringMask));
+    __ Assert(eq, kExternalStringExpectedButNotFound, cr0);
+  }
+  __ LoadP(subject,
+           FieldMemOperand(subject, ExternalString::kResourceDataOffset));
+  // Move the pointer so that offset-wise, it looks like a sequential string.
+  STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
+  __ subi(subject, subject,
+          Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
+  __ b(&seq_string);  // Go to (5).
+
+  // (8) Short external string or not a string?  If yes, bail out to runtime.
+  __ bind(&not_long_external);
+  STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag != 0);
+  __ andi(r0, r4, Operand(kIsNotStringMask | kShortExternalStringMask));
+  __ bne(&runtime, cr0);
+
+  // (9) Sliced string.  Replace subject with parent.  Go to (4).
+  // Load offset into r11 and replace subject string with parent.
+  __ LoadP(r11, FieldMemOperand(subject, SlicedString::kOffsetOffset));
+  __ SmiUntag(r11);
+  __ LoadP(subject, FieldMemOperand(subject, SlicedString::kParentOffset));
+  __ b(&check_underlying);  // Go to (4).
+#endif  // V8_INTERPRETED_REGEXP
+}
+
+
+static void GenerateRecordCallTarget(MacroAssembler* masm) {
+  // Cache the called function in a feedback vector slot.  Cache states
+  // are uninitialized, monomorphic (indicated by a JSFunction), and
+  // megamorphic.
+  // r3 : number of arguments to the construct function
+  // r4 : the function to call
+  // r5 : Feedback vector
+  // r6 : slot in feedback vector (Smi)
+  Label initialize, done, miss, megamorphic, not_array_function;
+
+  DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()),
+            masm->isolate()->heap()->megamorphic_symbol());
+  DCHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(masm->isolate()),
+            masm->isolate()->heap()->uninitialized_symbol());
+
+  // Load the cache state into r7.
+  __ SmiToPtrArrayOffset(r7, r6);
+  __ add(r7, r5, r7);
+  __ LoadP(r7, FieldMemOperand(r7, FixedArray::kHeaderSize));
+
+  // A monomorphic cache hit or an already megamorphic state: invoke the
+  // function without changing the state.
+  __ cmp(r7, r4);
+  __ b(eq, &done);
+
+  if (!FLAG_pretenuring_call_new) {
+    // If we came here, we need to see if we are the array function.
+    // If we didn't have a matching function, and we didn't find the megamorph
+    // sentinel, then we have in the slot either some other function or an
+    // AllocationSite. Do a map check on the object in ecx.
+    __ LoadP(r8, FieldMemOperand(r7, 0));
+    __ CompareRoot(r8, Heap::kAllocationSiteMapRootIndex);
+    __ bne(&miss);
+
+    // Make sure the function is the Array() function
+    __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r7);
+    __ cmp(r4, r7);
+    __ bne(&megamorphic);
+    __ b(&done);
+  }
+
+  __ bind(&miss);
+
+  // A monomorphic miss (i.e, here the cache is not uninitialized) goes
+  // megamorphic.
+  __ CompareRoot(r7, Heap::kuninitialized_symbolRootIndex);
+  __ beq(&initialize);
+  // MegamorphicSentinel is an immortal immovable object (undefined) so no
+  // write-barrier is needed.
+  __ bind(&megamorphic);
+  __ SmiToPtrArrayOffset(r7, r6);
+  __ add(r7, r5, r7);
+  __ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex);
+  __ StoreP(ip, FieldMemOperand(r7, FixedArray::kHeaderSize), r0);
+  __ jmp(&done);
+
+  // An uninitialized cache is patched with the function
+  __ bind(&initialize);
+
+  if (!FLAG_pretenuring_call_new) {
+    // Make sure the function is the Array() function.
+    __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r7);
+    __ cmp(r4, r7);
+    __ bne(&not_array_function);
+
+    // The target function is the Array constructor,
+    // Create an AllocationSite if we don't already have it, store it in the
+    // slot.
+    {
+      FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+
+      // Arguments register must be smi-tagged to call out.
+      __ SmiTag(r3);
+      __ Push(r6, r5, r4, r3);
+
+      CreateAllocationSiteStub create_stub(masm->isolate());
+      __ CallStub(&create_stub);
+
+      __ Pop(r6, r5, r4, r3);
+      __ SmiUntag(r3);
+    }
+    __ b(&done);
+
+    __ bind(&not_array_function);
+  }
+
+  __ SmiToPtrArrayOffset(r7, r6);
+  __ add(r7, r5, r7);
+  __ addi(r7, r7, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ StoreP(r4, MemOperand(r7, 0));
+
+  __ Push(r7, r5, r4);
+  __ RecordWrite(r5, r7, r4, kLRHasNotBeenSaved, kDontSaveFPRegs,
+                 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+  __ Pop(r7, r5, r4);
+
+  __ bind(&done);
+}
+
+
+static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
+  // Do not transform the receiver for strict mode functions and natives.
+  __ LoadP(r6, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
+  __ lwz(r7, FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset));
+  __ TestBit(r7,
+#if V8_TARGET_ARCH_PPC64
+             SharedFunctionInfo::kStrictModeFunction,
+#else
+             SharedFunctionInfo::kStrictModeFunction + kSmiTagSize,
+#endif
+             r0);
+  __ bne(cont, cr0);
+
+  // Do not transform the receiver for native.
+  __ TestBit(r7,
+#if V8_TARGET_ARCH_PPC64
+             SharedFunctionInfo::kNative,
+#else
+             SharedFunctionInfo::kNative + kSmiTagSize,
+#endif
+             r0);
+  __ bne(cont, cr0);
+}
+
+
+static void EmitSlowCase(MacroAssembler* masm, int argc, Label* non_function) {
+  // Check for function proxy.
+  STATIC_ASSERT(JS_FUNCTION_PROXY_TYPE < 0xffffu);
+  __ cmpi(r7, Operand(JS_FUNCTION_PROXY_TYPE));
+  __ bne(non_function);
+  __ push(r4);  // put proxy as additional argument
+  __ li(r3, Operand(argc + 1));
+  __ li(r5, Operand::Zero());
+  __ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY);
+  {
+    Handle<Code> adaptor =
+        masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
+    __ Jump(adaptor, RelocInfo::CODE_TARGET);
+  }
+
+  // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
+  // of the original receiver from the call site).
+  __ bind(non_function);
+  __ StoreP(r4, MemOperand(sp, argc * kPointerSize), r0);
+  __ li(r3, Operand(argc));  // Set up the number of arguments.
+  __ li(r5, Operand::Zero());
+  __ GetBuiltinFunction(r4, Builtins::CALL_NON_FUNCTION);
+  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+          RelocInfo::CODE_TARGET);
+}
+
+
+static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
+  // Wrap the receiver and patch it back onto the stack.
+  {
+    FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
+    __ Push(r4, r6);
+    __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
+    __ pop(r4);
+  }
+  __ StoreP(r3, MemOperand(sp, argc * kPointerSize), r0);
+  __ b(cont);
+}
+
+
+static void CallFunctionNoFeedback(MacroAssembler* masm, int argc,
+                                   bool needs_checks, bool call_as_method) {
+  // r4 : the function to call
+  Label slow, non_function, wrap, cont;
+
+  if (needs_checks) {
+    // Check that the function is really a JavaScript function.
+    // r4: pushed function (to be verified)
+    __ JumpIfSmi(r4, &non_function);
+
+    // Goto slow case if we do not have a function.
+    __ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE);
+    __ bne(&slow);
+  }
+
+  // Fast-case: Invoke the function now.
+  // r4: pushed function
+  ParameterCount actual(argc);
+
+  if (call_as_method) {
+    if (needs_checks) {
+      EmitContinueIfStrictOrNative(masm, &cont);
+    }
+
+    // Compute the receiver in sloppy mode.
+    __ LoadP(r6, MemOperand(sp, argc * kPointerSize), r0);
+
+    if (needs_checks) {
+      __ JumpIfSmi(r6, &wrap);
+      __ CompareObjectType(r6, r7, r7, FIRST_SPEC_OBJECT_TYPE);
+      __ blt(&wrap);
+    } else {
+      __ b(&wrap);
+    }
+
+    __ bind(&cont);
+  }
+
+  __ InvokeFunction(r4, actual, JUMP_FUNCTION, NullCallWrapper());
+
+  if (needs_checks) {
+    // Slow-case: Non-function called.
+    __ bind(&slow);
+    EmitSlowCase(masm, argc, &non_function);
+  }
+
+  if (call_as_method) {
+    __ bind(&wrap);
+    EmitWrapCase(masm, argc, &cont);
+  }
+}
+
+
+void CallFunctionStub::Generate(MacroAssembler* masm) {
+  CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod());
+}
+
+
+void CallConstructStub::Generate(MacroAssembler* masm) {
+  // r3 : number of arguments
+  // r4 : the function to call
+  // r5 : feedback vector
+  // r6 : (only if r5 is not the megamorphic symbol) slot in feedback
+  //      vector (Smi)
+  Label slow, non_function_call;
+
+  // Check that the function is not a smi.
+  __ JumpIfSmi(r4, &non_function_call);
+  // Check that the function is a JSFunction.
+  __ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE);
+  __ bne(&slow);
+
+  if (RecordCallTarget()) {
+    GenerateRecordCallTarget(masm);
+
+    __ SmiToPtrArrayOffset(r8, r6);
+    __ add(r8, r5, r8);
+    if (FLAG_pretenuring_call_new) {
+      // Put the AllocationSite from the feedback vector into r5.
+      // By adding kPointerSize we encode that we know the AllocationSite
+      // entry is at the feedback vector slot given by r6 + 1.
+      __ LoadP(r5, FieldMemOperand(r8, FixedArray::kHeaderSize + kPointerSize));
+    } else {
+      Label feedback_register_initialized;
+      // Put the AllocationSite from the feedback vector into r5, or undefined.
+      __ LoadP(r5, FieldMemOperand(r8, FixedArray::kHeaderSize));
+      __ LoadP(r8, FieldMemOperand(r5, AllocationSite::kMapOffset));
+      __ CompareRoot(r8, Heap::kAllocationSiteMapRootIndex);
+      __ beq(&feedback_register_initialized);
+      __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
+      __ bind(&feedback_register_initialized);
+    }
+
+    __ AssertUndefinedOrAllocationSite(r5, r8);
+  }
+
+  // Jump to the function-specific construct stub.
+  Register jmp_reg = r7;
+  __ LoadP(jmp_reg, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
+  __ LoadP(jmp_reg,
+           FieldMemOperand(jmp_reg, SharedFunctionInfo::kConstructStubOffset));
+  __ addi(ip, jmp_reg, Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ JumpToJSEntry(ip);
+
+  // r3: number of arguments
+  // r4: called object
+  // r7: object type
+  Label do_call;
+  __ bind(&slow);
+  STATIC_ASSERT(JS_FUNCTION_PROXY_TYPE < 0xffffu);
+  __ cmpi(r7, Operand(JS_FUNCTION_PROXY_TYPE));
+  __ bne(&non_function_call);
+  __ GetBuiltinFunction(r4, Builtins::CALL_FUNCTION_PROXY_AS_CONSTRUCTOR);
+  __ b(&do_call);
+
+  __ bind(&non_function_call);
+  __ GetBuiltinFunction(r4, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
+  __ bind(&do_call);
+  // Set expected number of arguments to zero (not changing r3).
+  __ li(r5, Operand::Zero());
+  __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
+          RelocInfo::CODE_TARGET);
+}
+
+
+static void EmitLoadTypeFeedbackVector(MacroAssembler* masm, Register vector) {
+  __ LoadP(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ LoadP(vector,
+           FieldMemOperand(vector, JSFunction::kSharedFunctionInfoOffset));
+  __ LoadP(vector,
+           FieldMemOperand(vector, SharedFunctionInfo::kFeedbackVectorOffset));
+}
+
+
+void CallIC_ArrayStub::Generate(MacroAssembler* masm) {
+  // r4 - function
+  // r6 - slot id
+  Label miss;
+  int argc = arg_count();
+  ParameterCount actual(argc);
+
+  EmitLoadTypeFeedbackVector(masm, r5);
+
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, r7);
+  __ cmp(r4, r7);
+  __ bne(&miss);
+
+  __ mov(r3, Operand(arg_count()));
+  __ SmiToPtrArrayOffset(r7, r6);
+  __ add(r7, r5, r7);
+  __ LoadP(r7, FieldMemOperand(r7, FixedArray::kHeaderSize));
+
+  // Verify that r7 contains an AllocationSite
+  __ LoadP(r8, FieldMemOperand(r7, HeapObject::kMapOffset));
+  __ CompareRoot(r8, Heap::kAllocationSiteMapRootIndex);
+  __ bne(&miss);
+
+  __ mr(r5, r7);
+  ArrayConstructorStub stub(masm->isolate(), arg_count());
+  __ TailCallStub(&stub);
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+
+  // The slow case, we need this no matter what to complete a call after a miss.
+  CallFunctionNoFeedback(masm, arg_count(), true, CallAsMethod());
+
+  // Unreachable.
+  __ stop("Unexpected code address");
+}
+
+
+void CallICStub::Generate(MacroAssembler* masm) {
+  // r4 - function
+  // r6 - slot id (Smi)
+  Label extra_checks_or_miss, slow_start;
+  Label slow, non_function, wrap, cont;
+  Label have_js_function;
+  int argc = arg_count();
+  ParameterCount actual(argc);
+
+  EmitLoadTypeFeedbackVector(masm, r5);
+
+  // The checks. First, does r4 match the recorded monomorphic target?
+  __ SmiToPtrArrayOffset(r7, r6);
+  __ add(r7, r5, r7);
+  __ LoadP(r7, FieldMemOperand(r7, FixedArray::kHeaderSize));
+  __ cmp(r4, r7);
+  __ bne(&extra_checks_or_miss);
+
+  __ bind(&have_js_function);
+  if (CallAsMethod()) {
+    EmitContinueIfStrictOrNative(masm, &cont);
+    // Compute the receiver in sloppy mode.
+    __ LoadP(r6, MemOperand(sp, argc * kPointerSize), r0);
+
+    __ JumpIfSmi(r6, &wrap);
+    __ CompareObjectType(r6, r7, r7, FIRST_SPEC_OBJECT_TYPE);
+    __ blt(&wrap);
+
+    __ bind(&cont);
+  }
+
+  __ InvokeFunction(r4, actual, JUMP_FUNCTION, NullCallWrapper());
+
+  __ bind(&slow);
+  EmitSlowCase(masm, argc, &non_function);
+
+  if (CallAsMethod()) {
+    __ bind(&wrap);
+    EmitWrapCase(masm, argc, &cont);
+  }
+
+  __ bind(&extra_checks_or_miss);
+  Label miss;
+
+  __ CompareRoot(r7, Heap::kmegamorphic_symbolRootIndex);
+  __ beq(&slow_start);
+  __ CompareRoot(r7, Heap::kuninitialized_symbolRootIndex);
+  __ beq(&miss);
+
+  if (!FLAG_trace_ic) {
+    // We are going megamorphic. If the feedback is a JSFunction, it is fine
+    // to handle it here. More complex cases are dealt with in the runtime.
+    __ AssertNotSmi(r7);
+    __ CompareObjectType(r7, r8, r8, JS_FUNCTION_TYPE);
+    __ bne(&miss);
+    __ SmiToPtrArrayOffset(r7, r6);
+    __ add(r7, r5, r7);
+    __ LoadRoot(ip, Heap::kmegamorphic_symbolRootIndex);
+    __ StoreP(ip, FieldMemOperand(r7, FixedArray::kHeaderSize), r0);
+    // We have to update statistics for runtime profiling.
+    const int with_types_offset =
+        FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
+    __ LoadP(r7, FieldMemOperand(r5, with_types_offset));
+    __ SubSmiLiteral(r7, r7, Smi::FromInt(1), r0);
+    __ StoreP(r7, FieldMemOperand(r5, with_types_offset), r0);
+    const int generic_offset =
+        FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
+    __ LoadP(r7, FieldMemOperand(r5, generic_offset));
+    __ AddSmiLiteral(r7, r7, Smi::FromInt(1), r0);
+    __ StoreP(r7, FieldMemOperand(r5, generic_offset), r0);
+    __ jmp(&slow_start);
+  }
+
+  // We are here because tracing is on or we are going monomorphic.
+  __ bind(&miss);
+  GenerateMiss(masm);
+
+  // the slow case
+  __ bind(&slow_start);
+  // Check that the function is really a JavaScript function.
+  // r4: pushed function (to be verified)
+  __ JumpIfSmi(r4, &non_function);
+
+  // Goto slow case if we do not have a function.
+  __ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE);
+  __ bne(&slow);
+  __ b(&have_js_function);
+}
+
+
+void CallICStub::GenerateMiss(MacroAssembler* masm) {
+  // Get the receiver of the function from the stack; 1 ~ return address.
+  __ LoadP(r7, MemOperand(sp, (arg_count() + 1) * kPointerSize), r0);
+
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+
+    // Push the receiver and the function and feedback info.
+    __ Push(r7, r4, r5, r6);
+
+    // Call the entry.
+    IC::UtilityId id = GetICState() == DEFAULT ? IC::kCallIC_Miss
+                                               : IC::kCallIC_Customization_Miss;
+
+    ExternalReference miss = ExternalReference(IC_Utility(id), masm->isolate());
+    __ CallExternalReference(miss, 4);
+
+    // Move result to r4 and exit the internal frame.
+    __ mr(r4, r3);
+  }
+}
+
+
+// StringCharCodeAtGenerator
+void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
+  // If the receiver is a smi trigger the non-string case.
+  if (check_mode_ == RECEIVER_IS_UNKNOWN) {
+    __ JumpIfSmi(object_, receiver_not_string_);
+
+    // Fetch the instance type of the receiver into result register.
+    __ LoadP(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
+    __ lbz(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
+    // If the receiver is not a string trigger the non-string case.
+    __ andi(r0, result_, Operand(kIsNotStringMask));
+    __ bne(receiver_not_string_, cr0);
+  }
+
+  // If the index is non-smi trigger the non-smi case.
+  __ JumpIfNotSmi(index_, &index_not_smi_);
+  __ bind(&got_smi_index_);
+
+  // Check for index out of range.
+  __ LoadP(ip, FieldMemOperand(object_, String::kLengthOffset));
+  __ cmpl(ip, index_);
+  __ ble(index_out_of_range_);
+
+  __ SmiUntag(index_);
+
+  StringCharLoadGenerator::Generate(masm, object_, index_, result_,
+                                    &call_runtime_);
+
+  __ SmiTag(result_);
+  __ bind(&exit_);
+}
+
+
+void StringCharCodeAtGenerator::GenerateSlow(
+    MacroAssembler* masm, const RuntimeCallHelper& call_helper) {
+  __ Abort(kUnexpectedFallthroughToCharCodeAtSlowCase);
+
+  // Index is not a smi.
+  __ bind(&index_not_smi_);
+  // If index is a heap number, try converting it to an integer.
+  __ CheckMap(index_, result_, Heap::kHeapNumberMapRootIndex, index_not_number_,
+              DONT_DO_SMI_CHECK);
+  call_helper.BeforeCall(masm);
+  __ push(object_);
+  __ push(index_);  // Consumed by runtime conversion function.
+  if (index_flags_ == STRING_INDEX_IS_NUMBER) {
+    __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1);
+  } else {
+    DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX);
+    // NumberToSmi discards numbers that are not exact integers.
+    __ CallRuntime(Runtime::kNumberToSmi, 1);
+  }
+  // Save the conversion result before the pop instructions below
+  // have a chance to overwrite it.
+  __ Move(index_, r3);
+  __ pop(object_);
+  // Reload the instance type.
+  __ LoadP(result_, FieldMemOperand(object_, HeapObject::kMapOffset));
+  __ lbz(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset));
+  call_helper.AfterCall(masm);
+  // If index is still not a smi, it must be out of range.
+  __ JumpIfNotSmi(index_, index_out_of_range_);
+  // Otherwise, return to the fast path.
+  __ b(&got_smi_index_);
+
+  // Call runtime. We get here when the receiver is a string and the
+  // index is a number, but the code of getting the actual character
+  // is too complex (e.g., when the string needs to be flattened).
+  __ bind(&call_runtime_);
+  call_helper.BeforeCall(masm);
+  __ SmiTag(index_);
+  __ Push(object_, index_);
+  __ CallRuntime(Runtime::kStringCharCodeAtRT, 2);
+  __ Move(result_, r3);
+  call_helper.AfterCall(masm);
+  __ b(&exit_);
+
+  __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase);
+}
+
+
+// -------------------------------------------------------------------------
+// StringCharFromCodeGenerator
+
+void StringCharFromCodeGenerator::GenerateFast(MacroAssembler* masm) {
+  // Fast case of Heap::LookupSingleCharacterStringFromCode.
+  DCHECK(base::bits::IsPowerOfTwo32(String::kMaxOneByteCharCode + 1));
+  __ LoadSmiLiteral(r0, Smi::FromInt(~String::kMaxOneByteCharCode));
+  __ ori(r0, r0, Operand(kSmiTagMask));
+  __ and_(r0, code_, r0);
+  __ cmpi(r0, Operand::Zero());
+  __ bne(&slow_case_);
+
+  __ LoadRoot(result_, Heap::kSingleCharacterStringCacheRootIndex);
+  // At this point code register contains smi tagged one-byte char code.
+  __ mr(r0, code_);
+  __ SmiToPtrArrayOffset(code_, code_);
+  __ add(result_, result_, code_);
+  __ mr(code_, r0);
+  __ LoadP(result_, FieldMemOperand(result_, FixedArray::kHeaderSize));
+  __ CompareRoot(result_, Heap::kUndefinedValueRootIndex);
+  __ beq(&slow_case_);
+  __ bind(&exit_);
+}
+
+
+void StringCharFromCodeGenerator::GenerateSlow(
+    MacroAssembler* masm, const RuntimeCallHelper& call_helper) {
+  __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase);
+
+  __ bind(&slow_case_);
+  call_helper.BeforeCall(masm);
+  __ push(code_);
+  __ CallRuntime(Runtime::kCharFromCode, 1);
+  __ Move(result_, r3);
+  call_helper.AfterCall(masm);
+  __ b(&exit_);
+
+  __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase);
+}
+
+
+enum CopyCharactersFlags { COPY_ONE_BYTE = 1, DEST_ALWAYS_ALIGNED = 2 };
+
+
+void StringHelper::GenerateCopyCharacters(MacroAssembler* masm, Register dest,
+                                          Register src, Register count,
+                                          Register scratch,
+                                          String::Encoding encoding) {
+  if (FLAG_debug_code) {
+    // Check that destination is word aligned.
+    __ andi(r0, dest, Operand(kPointerAlignmentMask));
+    __ Check(eq, kDestinationOfCopyNotAligned, cr0);
+  }
+
+  // Nothing to do for zero characters.
+  Label done;
+  if (encoding == String::TWO_BYTE_ENCODING) {
+    // double the length
+    __ add(count, count, count, LeaveOE, SetRC);
+    __ beq(&done, cr0);
+  } else {
+    __ cmpi(count, Operand::Zero());
+    __ beq(&done);
+  }
+
+  // Copy count bytes from src to dst.
+  Label byte_loop;
+  __ mtctr(count);
+  __ bind(&byte_loop);
+  __ lbz(scratch, MemOperand(src));
+  __ addi(src, src, Operand(1));
+  __ stb(scratch, MemOperand(dest));
+  __ addi(dest, dest, Operand(1));
+  __ bdnz(&byte_loop);
+
+  __ bind(&done);
+}
+
+
+void SubStringStub::Generate(MacroAssembler* masm) {
+  Label runtime;
+
+  // Stack frame on entry.
+  //  lr: return address
+  //  sp[0]: to
+  //  sp[4]: from
+  //  sp[8]: string
+
+  // This stub is called from the native-call %_SubString(...), so
+  // nothing can be assumed about the arguments. It is tested that:
+  //  "string" is a sequential string,
+  //  both "from" and "to" are smis, and
+  //  0 <= from <= to <= string.length.
+  // If any of these assumptions fail, we call the runtime system.
+
+  const int kToOffset = 0 * kPointerSize;
+  const int kFromOffset = 1 * kPointerSize;
+  const int kStringOffset = 2 * kPointerSize;
+
+  __ LoadP(r5, MemOperand(sp, kToOffset));
+  __ LoadP(r6, MemOperand(sp, kFromOffset));
+
+  // If either to or from had the smi tag bit set, then fail to generic runtime
+  __ JumpIfNotSmi(r5, &runtime);
+  __ JumpIfNotSmi(r6, &runtime);
+  __ SmiUntag(r5);
+  __ SmiUntag(r6, SetRC);
+  // Both r5 and r6 are untagged integers.
+
+  // We want to bailout to runtime here if From is negative.
+  __ blt(&runtime, cr0);  // From < 0.
+
+  __ cmpl(r6, r5);
+  __ bgt(&runtime);  // Fail if from > to.
+  __ sub(r5, r5, r6);
+
+  // Make sure first argument is a string.
+  __ LoadP(r3, MemOperand(sp, kStringOffset));
+  __ JumpIfSmi(r3, &runtime);
+  Condition is_string = masm->IsObjectStringType(r3, r4);
+  __ b(NegateCondition(is_string), &runtime, cr0);
+
+  Label single_char;
+  __ cmpi(r5, Operand(1));
+  __ b(eq, &single_char);
+
+  // Short-cut for the case of trivial substring.
+  Label return_r3;
+  // r3: original string
+  // r5: result string length
+  __ LoadP(r7, FieldMemOperand(r3, String::kLengthOffset));
+  __ SmiUntag(r0, r7);
+  __ cmpl(r5, r0);
+  // Return original string.
+  __ beq(&return_r3);
+  // Longer than original string's length or negative: unsafe arguments.
+  __ bgt(&runtime);
+  // 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 r8.
+  // r3: original string
+  // r4: instance type
+  // r5: length
+  // r6: from index (untagged)
+  Label underlying_unpacked, sliced_string, seq_or_external_string;
+  // If the string is not indirect, it can only be sequential or external.
+  STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag));
+  STATIC_ASSERT(kIsIndirectStringMask != 0);
+  __ andi(r0, r4, Operand(kIsIndirectStringMask));
+  __ beq(&seq_or_external_string, cr0);
+
+  __ andi(r0, r4, Operand(kSlicedNotConsMask));
+  __ bne(&sliced_string, cr0);
+  // Cons string.  Check whether it is flat, then fetch first part.
+  __ LoadP(r8, FieldMemOperand(r3, ConsString::kSecondOffset));
+  __ CompareRoot(r8, Heap::kempty_stringRootIndex);
+  __ bne(&runtime);
+  __ LoadP(r8, FieldMemOperand(r3, ConsString::kFirstOffset));
+  // Update instance type.
+  __ LoadP(r4, FieldMemOperand(r8, HeapObject::kMapOffset));
+  __ lbz(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
+  __ b(&underlying_unpacked);
+
+  __ bind(&sliced_string);
+  // Sliced string.  Fetch parent and correct start index by offset.
+  __ LoadP(r8, FieldMemOperand(r3, SlicedString::kParentOffset));
+  __ LoadP(r7, FieldMemOperand(r3, SlicedString::kOffsetOffset));
+  __ SmiUntag(r4, r7);
+  __ add(r6, r6, r4);  // Add offset to index.
+  // Update instance type.
+  __ LoadP(r4, FieldMemOperand(r8, HeapObject::kMapOffset));
+  __ lbz(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
+  __ b(&underlying_unpacked);
+
+  __ bind(&seq_or_external_string);
+  // Sequential or external string.  Just move string to the expected register.
+  __ mr(r8, r3);
+
+  __ bind(&underlying_unpacked);
+
+  if (FLAG_string_slices) {
+    Label copy_routine;
+    // r8: underlying subject string
+    // r4: instance type of underlying subject string
+    // r5: length
+    // r6: adjusted start index (untagged)
+    __ cmpi(r5, Operand(SlicedString::kMinLength));
+    // Short slice.  Copy instead of slicing.
+    __ blt(&copy_routine);
+    // Allocate new sliced string.  At this point we do not reload the instance
+    // type including the string encoding because we simply rely on the info
+    // provided by the original string.  It does not matter if the original
+    // string's encoding is wrong because we always have to recheck encoding of
+    // the newly created string's parent anyways due to externalized strings.
+    Label two_byte_slice, set_slice_header;
+    STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0);
+    STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
+    __ andi(r0, r4, Operand(kStringEncodingMask));
+    __ beq(&two_byte_slice, cr0);
+    __ AllocateOneByteSlicedString(r3, r5, r9, r10, &runtime);
+    __ b(&set_slice_header);
+    __ bind(&two_byte_slice);
+    __ AllocateTwoByteSlicedString(r3, r5, r9, r10, &runtime);
+    __ bind(&set_slice_header);
+    __ SmiTag(r6);
+    __ StoreP(r8, FieldMemOperand(r3, SlicedString::kParentOffset), r0);
+    __ StoreP(r6, FieldMemOperand(r3, SlicedString::kOffsetOffset), r0);
+    __ b(&return_r3);
+
+    __ bind(&copy_routine);
+  }
+
+  // r8: underlying subject string
+  // r4: instance type of underlying subject string
+  // r5: length
+  // r6: adjusted start index (untagged)
+  Label two_byte_sequential, sequential_string, allocate_result;
+  STATIC_ASSERT(kExternalStringTag != 0);
+  STATIC_ASSERT(kSeqStringTag == 0);
+  __ andi(r0, r4, Operand(kExternalStringTag));
+  __ beq(&sequential_string, cr0);
+
+  // Handle external string.
+  // Rule out short external strings.
+  STATIC_ASSERT(kShortExternalStringTag != 0);
+  __ andi(r0, r4, Operand(kShortExternalStringTag));
+  __ bne(&runtime, cr0);
+  __ LoadP(r8, FieldMemOperand(r8, ExternalString::kResourceDataOffset));
+  // r8 already points to the first character of underlying string.
+  __ b(&allocate_result);
+
+  __ bind(&sequential_string);
+  // Locate first character of underlying subject string.
+  STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
+  __ addi(r8, r8, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
+
+  __ bind(&allocate_result);
+  // Sequential acii string.  Allocate the result.
+  STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
+  __ andi(r0, r4, Operand(kStringEncodingMask));
+  __ beq(&two_byte_sequential, cr0);
+
+  // Allocate and copy the resulting one-byte string.
+  __ AllocateOneByteString(r3, r5, r7, r9, r10, &runtime);
+
+  // Locate first character of substring to copy.
+  __ add(r8, r8, r6);
+  // Locate first character of result.
+  __ addi(r4, r3, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
+
+  // r3: result string
+  // r4: first character of result string
+  // r5: result string length
+  // r8: first character of substring to copy
+  STATIC_ASSERT((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0);
+  StringHelper::GenerateCopyCharacters(masm, r4, r8, r5, r6,
+                                       String::ONE_BYTE_ENCODING);
+  __ b(&return_r3);
+
+  // Allocate and copy the resulting two-byte string.
+  __ bind(&two_byte_sequential);
+  __ AllocateTwoByteString(r3, r5, r7, r9, r10, &runtime);
+
+  // Locate first character of substring to copy.
+  __ ShiftLeftImm(r4, r6, Operand(1));
+  __ add(r8, r8, r4);
+  // Locate first character of result.
+  __ addi(r4, r3, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
+
+  // r3: result string.
+  // r4: first character of result.
+  // r5: result length.
+  // r8: first character of substring to copy.
+  STATIC_ASSERT((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
+  StringHelper::GenerateCopyCharacters(masm, r4, r8, r5, r6,
+                                       String::TWO_BYTE_ENCODING);
+
+  __ bind(&return_r3);
+  Counters* counters = isolate()->counters();
+  __ IncrementCounter(counters->sub_string_native(), 1, r6, r7);
+  __ Drop(3);
+  __ Ret();
+
+  // Just jump to runtime to create the sub string.
+  __ bind(&runtime);
+  __ TailCallRuntime(Runtime::kSubString, 3, 1);
+
+  __ bind(&single_char);
+  // r3: original string
+  // r4: instance type
+  // r5: length
+  // r6: from index (untagged)
+  __ SmiTag(r6, r6);
+  StringCharAtGenerator generator(r3, r6, r5, r3, &runtime, &runtime, &runtime,
+                                  STRING_INDEX_IS_NUMBER, RECEIVER_IS_STRING);
+  generator.GenerateFast(masm);
+  __ Drop(3);
+  __ Ret();
+  generator.SkipSlow(masm, &runtime);
+}
+
+
+void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm,
+                                                   Register left,
+                                                   Register right,
+                                                   Register scratch1,
+                                                   Register scratch2) {
+  Register length = scratch1;
+
+  // Compare lengths.
+  Label strings_not_equal, check_zero_length;
+  __ LoadP(length, FieldMemOperand(left, String::kLengthOffset));
+  __ LoadP(scratch2, FieldMemOperand(right, String::kLengthOffset));
+  __ cmp(length, scratch2);
+  __ beq(&check_zero_length);
+  __ bind(&strings_not_equal);
+  __ LoadSmiLiteral(r3, Smi::FromInt(NOT_EQUAL));
+  __ Ret();
+
+  // Check if the length is zero.
+  Label compare_chars;
+  __ bind(&check_zero_length);
+  STATIC_ASSERT(kSmiTag == 0);
+  __ cmpi(length, Operand::Zero());
+  __ bne(&compare_chars);
+  __ LoadSmiLiteral(r3, Smi::FromInt(EQUAL));
+  __ Ret();
+
+  // Compare characters.
+  __ bind(&compare_chars);
+  GenerateOneByteCharsCompareLoop(masm, left, right, length, scratch2,
+                                  &strings_not_equal);
+
+  // Characters are equal.
+  __ LoadSmiLiteral(r3, Smi::FromInt(EQUAL));
+  __ Ret();
+}
+
+
+void StringHelper::GenerateCompareFlatOneByteStrings(
+    MacroAssembler* masm, Register left, Register right, Register scratch1,
+    Register scratch2, Register scratch3) {
+  Label skip, result_not_equal, compare_lengths;
+  // Find minimum length and length difference.
+  __ LoadP(scratch1, FieldMemOperand(left, String::kLengthOffset));
+  __ LoadP(scratch2, FieldMemOperand(right, String::kLengthOffset));
+  __ sub(scratch3, scratch1, scratch2, LeaveOE, SetRC);
+  Register length_delta = scratch3;
+  __ ble(&skip, cr0);
+  __ mr(scratch1, scratch2);
+  __ bind(&skip);
+  Register min_length = scratch1;
+  STATIC_ASSERT(kSmiTag == 0);
+  __ cmpi(min_length, Operand::Zero());
+  __ beq(&compare_lengths);
+
+  // Compare loop.
+  GenerateOneByteCharsCompareLoop(masm, left, right, min_length, scratch2,
+                                  &result_not_equal);
+
+  // Compare lengths - strings up to min-length are equal.
+  __ bind(&compare_lengths);
+  DCHECK(Smi::FromInt(EQUAL) == static_cast<Smi*>(0));
+  // Use length_delta as result if it's zero.
+  __ mr(r3, length_delta);
+  __ cmpi(r3, Operand::Zero());
+  __ bind(&result_not_equal);
+  // Conditionally update the result based either on length_delta or
+  // the last comparion performed in the loop above.
+  Label less_equal, equal;
+  __ ble(&less_equal);
+  __ LoadSmiLiteral(r3, Smi::FromInt(GREATER));
+  __ Ret();
+  __ bind(&less_equal);
+  __ beq(&equal);
+  __ LoadSmiLiteral(r3, Smi::FromInt(LESS));
+  __ bind(&equal);
+  __ Ret();
+}
+
+
+void StringHelper::GenerateOneByteCharsCompareLoop(
+    MacroAssembler* masm, Register left, Register right, Register length,
+    Register scratch1, Label* chars_not_equal) {
+  // Change index to run from -length to -1 by adding length to string
+  // start. This means that loop ends when index reaches zero, which
+  // doesn't need an additional compare.
+  __ SmiUntag(length);
+  __ addi(scratch1, length,
+          Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
+  __ add(left, left, scratch1);
+  __ add(right, right, scratch1);
+  __ subfic(length, length, Operand::Zero());
+  Register index = length;  // index = -length;
+
+  // Compare loop.
+  Label loop;
+  __ bind(&loop);
+  __ lbzx(scratch1, MemOperand(left, index));
+  __ lbzx(r0, MemOperand(right, index));
+  __ cmp(scratch1, r0);
+  __ bne(chars_not_equal);
+  __ addi(index, index, Operand(1));
+  __ cmpi(index, Operand::Zero());
+  __ bne(&loop);
+}
+
+
+void StringCompareStub::Generate(MacroAssembler* masm) {
+  Label runtime;
+
+  Counters* counters = isolate()->counters();
+
+  // Stack frame on entry.
+  //  sp[0]: right string
+  //  sp[4]: left string
+  __ LoadP(r3, MemOperand(sp));  // Load right in r3, left in r4.
+  __ LoadP(r4, MemOperand(sp, kPointerSize));
+
+  Label not_same;
+  __ cmp(r3, r4);
+  __ bne(&not_same);
+  STATIC_ASSERT(EQUAL == 0);
+  STATIC_ASSERT(kSmiTag == 0);
+  __ LoadSmiLiteral(r3, Smi::FromInt(EQUAL));
+  __ IncrementCounter(counters->string_compare_native(), 1, r4, r5);
+  __ addi(sp, sp, Operand(2 * kPointerSize));
+  __ Ret();
+
+  __ bind(&not_same);
+
+  // Check that both objects are sequential one-byte strings.
+  __ JumpIfNotBothSequentialOneByteStrings(r4, r3, r5, r6, &runtime);
+
+  // Compare flat one-byte strings natively. Remove arguments from stack first.
+  __ IncrementCounter(counters->string_compare_native(), 1, r5, r6);
+  __ addi(sp, sp, Operand(2 * kPointerSize));
+  StringHelper::GenerateCompareFlatOneByteStrings(masm, r4, r3, r5, r6, r7);
+
+  // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
+  // tagged as a small integer.
+  __ bind(&runtime);
+  __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
+}
+
+
+void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- r4    : left
+  //  -- r3    : right
+  //  -- lr    : return address
+  // -----------------------------------
+
+  // Load r5 with the allocation site.  We stick an undefined dummy value here
+  // and replace it with the real allocation site later when we instantiate this
+  // stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate().
+  __ Move(r5, handle(isolate()->heap()->undefined_value()));
+
+  // Make sure that we actually patched the allocation site.
+  if (FLAG_debug_code) {
+    __ TestIfSmi(r5, r0);
+    __ Assert(ne, kExpectedAllocationSite, cr0);
+    __ push(r5);
+    __ LoadP(r5, FieldMemOperand(r5, HeapObject::kMapOffset));
+    __ LoadRoot(ip, Heap::kAllocationSiteMapRootIndex);
+    __ cmp(r5, ip);
+    __ pop(r5);
+    __ Assert(eq, kExpectedAllocationSite);
+  }
+
+  // Tail call into the stub that handles binary operations with allocation
+  // sites.
+  BinaryOpWithAllocationSiteStub stub(isolate(), state());
+  __ TailCallStub(&stub);
+}
+
+
+void CompareICStub::GenerateSmis(MacroAssembler* masm) {
+  DCHECK(state() == CompareICState::SMI);
+  Label miss;
+  __ orx(r5, r4, r3);
+  __ JumpIfNotSmi(r5, &miss);
+
+  if (GetCondition() == eq) {
+    // For equality we do not care about the sign of the result.
+    // __ sub(r3, r3, r4, SetCC);
+    __ sub(r3, r3, r4);
+  } else {
+    // Untag before subtracting to avoid handling overflow.
+    __ SmiUntag(r4);
+    __ SmiUntag(r3);
+    __ sub(r3, r4, r3);
+  }
+  __ Ret();
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+}
+
+
+void CompareICStub::GenerateNumbers(MacroAssembler* masm) {
+  DCHECK(state() == CompareICState::NUMBER);
+
+  Label generic_stub;
+  Label unordered, maybe_undefined1, maybe_undefined2;
+  Label miss;
+  Label equal, less_than;
+
+  if (left() == CompareICState::SMI) {
+    __ JumpIfNotSmi(r4, &miss);
+  }
+  if (right() == CompareICState::SMI) {
+    __ JumpIfNotSmi(r3, &miss);
+  }
+
+  // Inlining the double comparison and falling back to the general compare
+  // stub if NaN is involved.
+  // Load left and right operand.
+  Label done, left, left_smi, right_smi;
+  __ JumpIfSmi(r3, &right_smi);
+  __ CheckMap(r3, r5, Heap::kHeapNumberMapRootIndex, &maybe_undefined1,
+              DONT_DO_SMI_CHECK);
+  __ lfd(d1, FieldMemOperand(r3, HeapNumber::kValueOffset));
+  __ b(&left);
+  __ bind(&right_smi);
+  __ SmiToDouble(d1, r3);
+
+  __ bind(&left);
+  __ JumpIfSmi(r4, &left_smi);
+  __ CheckMap(r4, r5, Heap::kHeapNumberMapRootIndex, &maybe_undefined2,
+              DONT_DO_SMI_CHECK);
+  __ lfd(d0, FieldMemOperand(r4, HeapNumber::kValueOffset));
+  __ b(&done);
+  __ bind(&left_smi);
+  __ SmiToDouble(d0, r4);
+
+  __ bind(&done);
+
+  // Compare operands
+  __ fcmpu(d0, d1);
+
+  // Don't base result on status bits when a NaN is involved.
+  __ bunordered(&unordered);
+
+  // Return a result of -1, 0, or 1, based on status bits.
+  __ beq(&equal);
+  __ blt(&less_than);
+  //  assume greater than
+  __ li(r3, Operand(GREATER));
+  __ Ret();
+  __ bind(&equal);
+  __ li(r3, Operand(EQUAL));
+  __ Ret();
+  __ bind(&less_than);
+  __ li(r3, Operand(LESS));
+  __ Ret();
+
+  __ bind(&unordered);
+  __ bind(&generic_stub);
+  CompareICStub stub(isolate(), op(), CompareICState::GENERIC,
+                     CompareICState::GENERIC, CompareICState::GENERIC);
+  __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
+
+  __ bind(&maybe_undefined1);
+  if (Token::IsOrderedRelationalCompareOp(op())) {
+    __ CompareRoot(r3, Heap::kUndefinedValueRootIndex);
+    __ bne(&miss);
+    __ JumpIfSmi(r4, &unordered);
+    __ CompareObjectType(r4, r5, r5, HEAP_NUMBER_TYPE);
+    __ bne(&maybe_undefined2);
+    __ b(&unordered);
+  }
+
+  __ bind(&maybe_undefined2);
+  if (Token::IsOrderedRelationalCompareOp(op())) {
+    __ CompareRoot(r4, Heap::kUndefinedValueRootIndex);
+    __ beq(&unordered);
+  }
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+}
+
+
+void CompareICStub::GenerateInternalizedStrings(MacroAssembler* masm) {
+  DCHECK(state() == CompareICState::INTERNALIZED_STRING);
+  Label miss, not_equal;
+
+  // Registers containing left and right operands respectively.
+  Register left = r4;
+  Register right = r3;
+  Register tmp1 = r5;
+  Register tmp2 = r6;
+
+  // Check that both operands are heap objects.
+  __ JumpIfEitherSmi(left, right, &miss);
+
+  // Check that both operands are symbols.
+  __ LoadP(tmp1, FieldMemOperand(left, HeapObject::kMapOffset));
+  __ LoadP(tmp2, FieldMemOperand(right, HeapObject::kMapOffset));
+  __ lbz(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset));
+  __ lbz(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset));
+  STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
+  __ orx(tmp1, tmp1, tmp2);
+  __ andi(r0, tmp1, Operand(kIsNotStringMask | kIsNotInternalizedMask));
+  __ bne(&miss, cr0);
+
+  // Internalized strings are compared by identity.
+  __ cmp(left, right);
+  __ bne(&not_equal);
+  // Make sure r3 is non-zero. At this point input operands are
+  // guaranteed to be non-zero.
+  DCHECK(right.is(r3));
+  STATIC_ASSERT(EQUAL == 0);
+  STATIC_ASSERT(kSmiTag == 0);
+  __ LoadSmiLiteral(r3, Smi::FromInt(EQUAL));
+  __ bind(&not_equal);
+  __ Ret();
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+}
+
+
+void CompareICStub::GenerateUniqueNames(MacroAssembler* masm) {
+  DCHECK(state() == CompareICState::UNIQUE_NAME);
+  DCHECK(GetCondition() == eq);
+  Label miss;
+
+  // Registers containing left and right operands respectively.
+  Register left = r4;
+  Register right = r3;
+  Register tmp1 = r5;
+  Register tmp2 = r6;
+
+  // Check that both operands are heap objects.
+  __ JumpIfEitherSmi(left, right, &miss);
+
+  // Check that both operands are unique names. This leaves the instance
+  // types loaded in tmp1 and tmp2.
+  __ LoadP(tmp1, FieldMemOperand(left, HeapObject::kMapOffset));
+  __ LoadP(tmp2, FieldMemOperand(right, HeapObject::kMapOffset));
+  __ lbz(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset));
+  __ lbz(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset));
+
+  __ JumpIfNotUniqueNameInstanceType(tmp1, &miss);
+  __ JumpIfNotUniqueNameInstanceType(tmp2, &miss);
+
+  // Unique names are compared by identity.
+  __ cmp(left, right);
+  __ bne(&miss);
+  // Make sure r3 is non-zero. At this point input operands are
+  // guaranteed to be non-zero.
+  DCHECK(right.is(r3));
+  STATIC_ASSERT(EQUAL == 0);
+  STATIC_ASSERT(kSmiTag == 0);
+  __ LoadSmiLiteral(r3, Smi::FromInt(EQUAL));
+  __ Ret();
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+}
+
+
+void CompareICStub::GenerateStrings(MacroAssembler* masm) {
+  DCHECK(state() == CompareICState::STRING);
+  Label miss, not_identical, is_symbol;
+
+  bool equality = Token::IsEqualityOp(op());
+
+  // Registers containing left and right operands respectively.
+  Register left = r4;
+  Register right = r3;
+  Register tmp1 = r5;
+  Register tmp2 = r6;
+  Register tmp3 = r7;
+  Register tmp4 = r8;
+
+  // Check that both operands are heap objects.
+  __ JumpIfEitherSmi(left, right, &miss);
+
+  // Check that both operands are strings. This leaves the instance
+  // types loaded in tmp1 and tmp2.
+  __ LoadP(tmp1, FieldMemOperand(left, HeapObject::kMapOffset));
+  __ LoadP(tmp2, FieldMemOperand(right, HeapObject::kMapOffset));
+  __ lbz(tmp1, FieldMemOperand(tmp1, Map::kInstanceTypeOffset));
+  __ lbz(tmp2, FieldMemOperand(tmp2, Map::kInstanceTypeOffset));
+  STATIC_ASSERT(kNotStringTag != 0);
+  __ orx(tmp3, tmp1, tmp2);
+  __ andi(r0, tmp3, Operand(kIsNotStringMask));
+  __ bne(&miss, cr0);
+
+  // Fast check for identical strings.
+  __ cmp(left, right);
+  STATIC_ASSERT(EQUAL == 0);
+  STATIC_ASSERT(kSmiTag == 0);
+  __ bne(&not_identical);
+  __ LoadSmiLiteral(r3, Smi::FromInt(EQUAL));
+  __ Ret();
+  __ bind(&not_identical);
+
+  // Handle not identical strings.
+
+  // Check that both strings are internalized strings. If they are, we're done
+  // because we already know they are not identical. We know they are both
+  // strings.
+  if (equality) {
+    DCHECK(GetCondition() == eq);
+    STATIC_ASSERT(kInternalizedTag == 0);
+    __ orx(tmp3, tmp1, tmp2);
+    __ andi(r0, tmp3, Operand(kIsNotInternalizedMask));
+    __ bne(&is_symbol, cr0);
+    // Make sure r3 is non-zero. At this point input operands are
+    // guaranteed to be non-zero.
+    DCHECK(right.is(r3));
+    __ Ret();
+    __ bind(&is_symbol);
+  }
+
+  // Check that both strings are sequential one-byte.
+  Label runtime;
+  __ JumpIfBothInstanceTypesAreNotSequentialOneByte(tmp1, tmp2, tmp3, tmp4,
+                                                    &runtime);
+
+  // Compare flat one-byte strings. Returns when done.
+  if (equality) {
+    StringHelper::GenerateFlatOneByteStringEquals(masm, left, right, tmp1,
+                                                  tmp2);
+  } else {
+    StringHelper::GenerateCompareFlatOneByteStrings(masm, left, right, tmp1,
+                                                    tmp2, tmp3);
+  }
+
+  // Handle more complex cases in runtime.
+  __ bind(&runtime);
+  __ Push(left, right);
+  if (equality) {
+    __ TailCallRuntime(Runtime::kStringEquals, 2, 1);
+  } else {
+    __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
+  }
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+}
+
+
+void CompareICStub::GenerateObjects(MacroAssembler* masm) {
+  DCHECK(state() == CompareICState::OBJECT);
+  Label miss;
+  __ and_(r5, r4, r3);
+  __ JumpIfSmi(r5, &miss);
+
+  __ CompareObjectType(r3, r5, r5, JS_OBJECT_TYPE);
+  __ bne(&miss);
+  __ CompareObjectType(r4, r5, r5, JS_OBJECT_TYPE);
+  __ bne(&miss);
+
+  DCHECK(GetCondition() == eq);
+  __ sub(r3, r3, r4);
+  __ Ret();
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+}
+
+
+void CompareICStub::GenerateKnownObjects(MacroAssembler* masm) {
+  Label miss;
+  __ and_(r5, r4, r3);
+  __ JumpIfSmi(r5, &miss);
+  __ LoadP(r5, FieldMemOperand(r3, HeapObject::kMapOffset));
+  __ LoadP(r6, FieldMemOperand(r4, HeapObject::kMapOffset));
+  __ Cmpi(r5, Operand(known_map_), r0);
+  __ bne(&miss);
+  __ Cmpi(r6, Operand(known_map_), r0);
+  __ bne(&miss);
+
+  __ sub(r3, r3, r4);
+  __ Ret();
+
+  __ bind(&miss);
+  GenerateMiss(masm);
+}
+
+
+void CompareICStub::GenerateMiss(MacroAssembler* masm) {
+  {
+    // Call the runtime system in a fresh internal frame.
+    ExternalReference miss =
+        ExternalReference(IC_Utility(IC::kCompareIC_Miss), isolate());
+
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+    __ Push(r4, r3);
+    __ Push(r4, r3);
+    __ LoadSmiLiteral(r0, Smi::FromInt(op()));
+    __ push(r0);
+    __ CallExternalReference(miss, 3);
+    // Compute the entry point of the rewritten stub.
+    __ addi(r5, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
+    // Restore registers.
+    __ Pop(r4, r3);
+  }
+
+  __ JumpToJSEntry(r5);
+}
+
+
+// This stub is paired with DirectCEntryStub::GenerateCall
+void DirectCEntryStub::Generate(MacroAssembler* masm) {
+  // Place the return address on the stack, making the call
+  // GC safe. The RegExp backend also relies on this.
+  __ mflr(r0);
+  __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize));
+  __ Call(ip);  // Call the C++ function.
+  __ LoadP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize));
+  __ mtlr(r0);
+  __ blr();
+}
+
+
+void DirectCEntryStub::GenerateCall(MacroAssembler* masm, Register target) {
+#if ABI_USES_FUNCTION_DESCRIPTORS && !defined(USE_SIMULATOR)
+  // Native AIX/PPC64 Linux use a function descriptor.
+  __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(target, kPointerSize));
+  __ LoadP(ip, MemOperand(target, 0));  // Instruction address
+#else
+  // ip needs to be set for DirectCEentryStub::Generate, and also
+  // for ABI_TOC_ADDRESSABILITY_VIA_IP.
+  __ Move(ip, target);
+#endif
+
+  intptr_t code = reinterpret_cast<intptr_t>(GetCode().location());
+  __ mov(r0, Operand(code, RelocInfo::CODE_TARGET));
+  __ Call(r0);  // Call the stub.
+}
+
+
+void NameDictionaryLookupStub::GenerateNegativeLookup(
+    MacroAssembler* masm, Label* miss, Label* done, Register receiver,
+    Register properties, Handle<Name> name, Register scratch0) {
+  DCHECK(name->IsUniqueName());
+  // If names of slots in range from 1 to kProbes - 1 for the hash value are
+  // not equal to the name and kProbes-th slot is not used (its name is the
+  // undefined value), it guarantees the hash table doesn't contain the
+  // property. It's true even if some slots represent deleted properties
+  // (their names are the hole value).
+  for (int i = 0; i < kInlinedProbes; i++) {
+    // scratch0 points to properties hash.
+    // Compute the masked index: (hash + i + i * i) & mask.
+    Register index = scratch0;
+    // Capacity is smi 2^n.
+    __ LoadP(index, FieldMemOperand(properties, kCapacityOffset));
+    __ subi(index, index, Operand(1));
+    __ LoadSmiLiteral(
+        ip, Smi::FromInt(name->Hash() + NameDictionary::GetProbeOffset(i)));
+    __ and_(index, index, ip);
+
+    // Scale the index by multiplying by the entry size.
+    DCHECK(NameDictionary::kEntrySize == 3);
+    __ ShiftLeftImm(ip, index, Operand(1));
+    __ add(index, index, ip);  // index *= 3.
+
+    Register entity_name = scratch0;
+    // Having undefined at this place means the name is not contained.
+    Register tmp = properties;
+    __ SmiToPtrArrayOffset(ip, index);
+    __ add(tmp, properties, ip);
+    __ LoadP(entity_name, FieldMemOperand(tmp, kElementsStartOffset));
+
+    DCHECK(!tmp.is(entity_name));
+    __ LoadRoot(tmp, Heap::kUndefinedValueRootIndex);
+    __ cmp(entity_name, tmp);
+    __ beq(done);
+
+    // Load the hole ready for use below:
+    __ LoadRoot(tmp, Heap::kTheHoleValueRootIndex);
+
+    // Stop if found the property.
+    __ Cmpi(entity_name, Operand(Handle<Name>(name)), r0);
+    __ beq(miss);
+
+    Label good;
+    __ cmp(entity_name, tmp);
+    __ beq(&good);
+
+    // Check if the entry name is not a unique name.
+    __ LoadP(entity_name, FieldMemOperand(entity_name, HeapObject::kMapOffset));
+    __ lbz(entity_name, FieldMemOperand(entity_name, Map::kInstanceTypeOffset));
+    __ JumpIfNotUniqueNameInstanceType(entity_name, miss);
+    __ bind(&good);
+
+    // Restore the properties.
+    __ LoadP(properties,
+             FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+  }
+
+  const int spill_mask = (r0.bit() | r9.bit() | r8.bit() | r7.bit() | r6.bit() |
+                          r5.bit() | r4.bit() | r3.bit());
+
+  __ mflr(r0);
+  __ MultiPush(spill_mask);
+
+  __ LoadP(r3, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
+  __ mov(r4, Operand(Handle<Name>(name)));
+  NameDictionaryLookupStub stub(masm->isolate(), NEGATIVE_LOOKUP);
+  __ CallStub(&stub);
+  __ cmpi(r3, Operand::Zero());
+
+  __ MultiPop(spill_mask);  // MultiPop does not touch condition flags
+  __ mtlr(r0);
+
+  __ beq(done);
+  __ bne(miss);
+}
+
+
+// Probe the name dictionary in the |elements| register. Jump to the
+// |done| label if a property with the given name is found. Jump to
+// the |miss| label otherwise.
+// If lookup was successful |scratch2| will be equal to elements + 4 * index.
+void NameDictionaryLookupStub::GeneratePositiveLookup(
+    MacroAssembler* masm, Label* miss, Label* done, Register elements,
+    Register name, Register scratch1, Register scratch2) {
+  DCHECK(!elements.is(scratch1));
+  DCHECK(!elements.is(scratch2));
+  DCHECK(!name.is(scratch1));
+  DCHECK(!name.is(scratch2));
+
+  __ AssertName(name);
+
+  // Compute the capacity mask.
+  __ LoadP(scratch1, FieldMemOperand(elements, kCapacityOffset));
+  __ SmiUntag(scratch1);  // convert smi to int
+  __ subi(scratch1, scratch1, Operand(1));
+
+  // Generate an unrolled loop that performs a few probes before
+  // giving up. Measurements done on Gmail indicate that 2 probes
+  // cover ~93% of loads from dictionaries.
+  for (int i = 0; i < kInlinedProbes; i++) {
+    // Compute the masked index: (hash + i + i * i) & mask.
+    __ lwz(scratch2, FieldMemOperand(name, Name::kHashFieldOffset));
+    if (i > 0) {
+      // Add the probe offset (i + i * i) left shifted to avoid right shifting
+      // the hash in a separate instruction. The value hash + i + i * i is right
+      // shifted in the following and instruction.
+      DCHECK(NameDictionary::GetProbeOffset(i) <
+             1 << (32 - Name::kHashFieldOffset));
+      __ addi(scratch2, scratch2,
+              Operand(NameDictionary::GetProbeOffset(i) << Name::kHashShift));
+    }
+    __ srwi(scratch2, scratch2, Operand(Name::kHashShift));
+    __ and_(scratch2, scratch1, scratch2);
+
+    // Scale the index by multiplying by the element size.
+    DCHECK(NameDictionary::kEntrySize == 3);
+    // scratch2 = scratch2 * 3.
+    __ ShiftLeftImm(ip, scratch2, Operand(1));
+    __ add(scratch2, scratch2, ip);
+
+    // Check if the key is identical to the name.
+    __ ShiftLeftImm(ip, scratch2, Operand(kPointerSizeLog2));
+    __ add(scratch2, elements, ip);
+    __ LoadP(ip, FieldMemOperand(scratch2, kElementsStartOffset));
+    __ cmp(name, ip);
+    __ beq(done);
+  }
+
+  const int spill_mask = (r0.bit() | r9.bit() | r8.bit() | r7.bit() | r6.bit() |
+                          r5.bit() | r4.bit() | r3.bit()) &
+                         ~(scratch1.bit() | scratch2.bit());
+
+  __ mflr(r0);
+  __ MultiPush(spill_mask);
+  if (name.is(r3)) {
+    DCHECK(!elements.is(r4));
+    __ mr(r4, name);
+    __ mr(r3, elements);
+  } else {
+    __ mr(r3, elements);
+    __ mr(r4, name);
+  }
+  NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP);
+  __ CallStub(&stub);
+  __ cmpi(r3, Operand::Zero());
+  __ mr(scratch2, r5);
+  __ MultiPop(spill_mask);
+  __ mtlr(r0);
+
+  __ bne(done);
+  __ beq(miss);
+}
+
+
+void NameDictionaryLookupStub::Generate(MacroAssembler* masm) {
+  // This stub overrides SometimesSetsUpAFrame() to return false.  That means
+  // we cannot call anything that could cause a GC from this stub.
+  // Registers:
+  //  result: NameDictionary to probe
+  //  r4: key
+  //  dictionary: NameDictionary to probe.
+  //  index: will hold an index of entry if lookup is successful.
+  //         might alias with result_.
+  // Returns:
+  //  result_ is zero if lookup failed, non zero otherwise.
+
+  Register result = r3;
+  Register dictionary = r3;
+  Register key = r4;
+  Register index = r5;
+  Register mask = r6;
+  Register hash = r7;
+  Register undefined = r8;
+  Register entry_key = r9;
+  Register scratch = r9;
+
+  Label in_dictionary, maybe_in_dictionary, not_in_dictionary;
+
+  __ LoadP(mask, FieldMemOperand(dictionary, kCapacityOffset));
+  __ SmiUntag(mask);
+  __ subi(mask, mask, Operand(1));
+
+  __ lwz(hash, FieldMemOperand(key, Name::kHashFieldOffset));
+
+  __ LoadRoot(undefined, Heap::kUndefinedValueRootIndex);
+
+  for (int i = kInlinedProbes; i < kTotalProbes; i++) {
+    // Compute the masked index: (hash + i + i * i) & mask.
+    // Capacity is smi 2^n.
+    if (i > 0) {
+      // Add the probe offset (i + i * i) left shifted to avoid right shifting
+      // the hash in a separate instruction. The value hash + i + i * i is right
+      // shifted in the following and instruction.
+      DCHECK(NameDictionary::GetProbeOffset(i) <
+             1 << (32 - Name::kHashFieldOffset));
+      __ addi(index, hash,
+              Operand(NameDictionary::GetProbeOffset(i) << Name::kHashShift));
+    } else {
+      __ mr(index, hash);
+    }
+    __ srwi(r0, index, Operand(Name::kHashShift));
+    __ and_(index, mask, r0);
+
+    // Scale the index by multiplying by the entry size.
+    DCHECK(NameDictionary::kEntrySize == 3);
+    __ ShiftLeftImm(scratch, index, Operand(1));
+    __ add(index, index, scratch);  // index *= 3.
+
+    DCHECK_EQ(kSmiTagSize, 1);
+    __ ShiftLeftImm(scratch, index, Operand(kPointerSizeLog2));
+    __ add(index, dictionary, scratch);
+    __ LoadP(entry_key, FieldMemOperand(index, kElementsStartOffset));
+
+    // Having undefined at this place means the name is not contained.
+    __ cmp(entry_key, undefined);
+    __ beq(&not_in_dictionary);
+
+    // Stop if found the property.
+    __ cmp(entry_key, key);
+    __ beq(&in_dictionary);
+
+    if (i != kTotalProbes - 1 && mode() == NEGATIVE_LOOKUP) {
+      // Check if the entry name is not a unique name.
+      __ LoadP(entry_key, FieldMemOperand(entry_key, HeapObject::kMapOffset));
+      __ lbz(entry_key, FieldMemOperand(entry_key, Map::kInstanceTypeOffset));
+      __ JumpIfNotUniqueNameInstanceType(entry_key, &maybe_in_dictionary);
+    }
+  }
+
+  __ bind(&maybe_in_dictionary);
+  // If we are doing negative lookup then probing failure should be
+  // treated as a lookup success. For positive lookup probing failure
+  // should be treated as lookup failure.
+  if (mode() == POSITIVE_LOOKUP) {
+    __ li(result, Operand::Zero());
+    __ Ret();
+  }
+
+  __ bind(&in_dictionary);
+  __ li(result, Operand(1));
+  __ Ret();
+
+  __ bind(&not_in_dictionary);
+  __ li(result, Operand::Zero());
+  __ Ret();
+}
+
+
+void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
+    Isolate* isolate) {
+  StoreBufferOverflowStub stub1(isolate, kDontSaveFPRegs);
+  stub1.GetCode();
+  // Hydrogen code stubs need stub2 at snapshot time.
+  StoreBufferOverflowStub stub2(isolate, kSaveFPRegs);
+  stub2.GetCode();
+}
+
+
+// Takes the input in 3 registers: address_ value_ and object_.  A pointer to
+// the value has just been written into the object, now this stub makes sure
+// we keep the GC informed.  The word in the object where the value has been
+// written is in the address register.
+void RecordWriteStub::Generate(MacroAssembler* masm) {
+  Label skip_to_incremental_noncompacting;
+  Label skip_to_incremental_compacting;
+
+  // The first two branch instructions are generated with labels so as to
+  // get the offset fixed up correctly by the bind(Label*) call.  We patch
+  // it back and forth between branch condition True and False
+  // when we start and stop incremental heap marking.
+  // See RecordWriteStub::Patch for details.
+
+  // Clear the bit, branch on True for NOP action initially
+  __ crclr(Assembler::encode_crbit(cr2, CR_LT));
+  __ blt(&skip_to_incremental_noncompacting, cr2);
+  __ blt(&skip_to_incremental_compacting, cr2);
+
+  if (remembered_set_action() == EMIT_REMEMBERED_SET) {
+    __ RememberedSetHelper(object(), address(), value(), save_fp_regs_mode(),
+                           MacroAssembler::kReturnAtEnd);
+  }
+  __ Ret();
+
+  __ bind(&skip_to_incremental_noncompacting);
+  GenerateIncremental(masm, INCREMENTAL);
+
+  __ bind(&skip_to_incremental_compacting);
+  GenerateIncremental(masm, INCREMENTAL_COMPACTION);
+
+  // Initial mode of the stub is expected to be STORE_BUFFER_ONLY.
+  // Will be checked in IncrementalMarking::ActivateGeneratedStub.
+  // patching not required on PPC as the initial path is effectively NOP
+}
+
+
+void RecordWriteStub::GenerateIncremental(MacroAssembler* masm, Mode mode) {
+  regs_.Save(masm);
+
+  if (remembered_set_action() == EMIT_REMEMBERED_SET) {
+    Label dont_need_remembered_set;
+
+    __ LoadP(regs_.scratch0(), MemOperand(regs_.address(), 0));
+    __ JumpIfNotInNewSpace(regs_.scratch0(),  // Value.
+                           regs_.scratch0(), &dont_need_remembered_set);
+
+    __ CheckPageFlag(regs_.object(), regs_.scratch0(),
+                     1 << MemoryChunk::SCAN_ON_SCAVENGE, ne,
+                     &dont_need_remembered_set);
+
+    // First notify the incremental marker if necessary, then update the
+    // remembered set.
+    CheckNeedsToInformIncrementalMarker(
+        masm, kUpdateRememberedSetOnNoNeedToInformIncrementalMarker, mode);
+    InformIncrementalMarker(masm);
+    regs_.Restore(masm);
+    __ RememberedSetHelper(object(), address(), value(), save_fp_regs_mode(),
+                           MacroAssembler::kReturnAtEnd);
+
+    __ bind(&dont_need_remembered_set);
+  }
+
+  CheckNeedsToInformIncrementalMarker(
+      masm, kReturnOnNoNeedToInformIncrementalMarker, mode);
+  InformIncrementalMarker(masm);
+  regs_.Restore(masm);
+  __ Ret();
+}
+
+
+void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
+  regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode());
+  int argument_count = 3;
+  __ PrepareCallCFunction(argument_count, regs_.scratch0());
+  Register address =
+      r3.is(regs_.address()) ? regs_.scratch0() : regs_.address();
+  DCHECK(!address.is(regs_.object()));
+  DCHECK(!address.is(r3));
+  __ mr(address, regs_.address());
+  __ mr(r3, regs_.object());
+  __ mr(r4, address);
+  __ mov(r5, Operand(ExternalReference::isolate_address(isolate())));
+
+  AllowExternalCallThatCantCauseGC scope(masm);
+  __ CallCFunction(
+      ExternalReference::incremental_marking_record_write_function(isolate()),
+      argument_count);
+  regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode());
+}
+
+
+void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
+    MacroAssembler* masm, OnNoNeedToInformIncrementalMarker on_no_need,
+    Mode mode) {
+  Label on_black;
+  Label need_incremental;
+  Label need_incremental_pop_scratch;
+
+  DCHECK((~Page::kPageAlignmentMask & 0xffff) == 0);
+  __ lis(r0, Operand((~Page::kPageAlignmentMask >> 16)));
+  __ and_(regs_.scratch0(), regs_.object(), r0);
+  __ LoadP(
+      regs_.scratch1(),
+      MemOperand(regs_.scratch0(), MemoryChunk::kWriteBarrierCounterOffset));
+  __ subi(regs_.scratch1(), regs_.scratch1(), Operand(1));
+  __ StoreP(
+      regs_.scratch1(),
+      MemOperand(regs_.scratch0(), MemoryChunk::kWriteBarrierCounterOffset));
+  __ cmpi(regs_.scratch1(), Operand::Zero());  // PPC, we could do better here
+  __ blt(&need_incremental);
+
+  // Let's look at the color of the object:  If it is not black we don't have
+  // to inform the incremental marker.
+  __ JumpIfBlack(regs_.object(), regs_.scratch0(), regs_.scratch1(), &on_black);
+
+  regs_.Restore(masm);
+  if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) {
+    __ RememberedSetHelper(object(), address(), value(), save_fp_regs_mode(),
+                           MacroAssembler::kReturnAtEnd);
+  } else {
+    __ Ret();
+  }
+
+  __ bind(&on_black);
+
+  // Get the value from the slot.
+  __ LoadP(regs_.scratch0(), MemOperand(regs_.address(), 0));
+
+  if (mode == INCREMENTAL_COMPACTION) {
+    Label ensure_not_white;
+
+    __ CheckPageFlag(regs_.scratch0(),  // Contains value.
+                     regs_.scratch1(),  // Scratch.
+                     MemoryChunk::kEvacuationCandidateMask, eq,
+                     &ensure_not_white);
+
+    __ CheckPageFlag(regs_.object(),
+                     regs_.scratch1(),  // Scratch.
+                     MemoryChunk::kSkipEvacuationSlotsRecordingMask, eq,
+                     &need_incremental);
+
+    __ bind(&ensure_not_white);
+  }
+
+  // We need extra registers for this, so we push the object and the address
+  // register temporarily.
+  __ Push(regs_.object(), regs_.address());
+  __ EnsureNotWhite(regs_.scratch0(),  // The value.
+                    regs_.scratch1(),  // Scratch.
+                    regs_.object(),    // Scratch.
+                    regs_.address(),   // Scratch.
+                    &need_incremental_pop_scratch);
+  __ Pop(regs_.object(), regs_.address());
+
+  regs_.Restore(masm);
+  if (on_no_need == kUpdateRememberedSetOnNoNeedToInformIncrementalMarker) {
+    __ RememberedSetHelper(object(), address(), value(), save_fp_regs_mode(),
+                           MacroAssembler::kReturnAtEnd);
+  } else {
+    __ Ret();
+  }
+
+  __ bind(&need_incremental_pop_scratch);
+  __ Pop(regs_.object(), regs_.address());
+
+  __ bind(&need_incremental);
+
+  // Fall through when we need to inform the incremental marker.
+}
+
+
+void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- r3    : element value to store
+  //  -- r6    : element index as smi
+  //  -- sp[0] : array literal index in function as smi
+  //  -- sp[4] : array literal
+  // clobbers r3, r5, r7
+  // -----------------------------------
+
+  Label element_done;
+  Label double_elements;
+  Label smi_element;
+  Label slow_elements;
+  Label fast_elements;
+
+  // Get array literal index, array literal and its map.
+  __ LoadP(r7, MemOperand(sp, 0 * kPointerSize));
+  __ LoadP(r4, MemOperand(sp, 1 * kPointerSize));
+  __ LoadP(r5, FieldMemOperand(r4, JSObject::kMapOffset));
+
+  __ CheckFastElements(r5, r8, &double_elements);
+  // FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS
+  __ JumpIfSmi(r3, &smi_element);
+  __ CheckFastSmiElements(r5, r8, &fast_elements);
+
+  // Store into the array literal requires a elements transition. Call into
+  // the runtime.
+  __ bind(&slow_elements);
+  // call.
+  __ Push(r4, r6, r3);
+  __ LoadP(r8, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ LoadP(r8, FieldMemOperand(r8, JSFunction::kLiteralsOffset));
+  __ Push(r8, r7);
+  __ TailCallRuntime(Runtime::kStoreArrayLiteralElement, 5, 1);
+
+  // Array literal has ElementsKind of FAST_*_ELEMENTS and value is an object.
+  __ bind(&fast_elements);
+  __ LoadP(r8, FieldMemOperand(r4, JSObject::kElementsOffset));
+  __ SmiToPtrArrayOffset(r9, r6);
+  __ add(r9, r8, r9);
+#if V8_TARGET_ARCH_PPC64
+  // add due to offset alignment requirements of StorePU
+  __ addi(r9, r9, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ StoreP(r3, MemOperand(r9));
+#else
+  __ StorePU(r3, MemOperand(r9, FixedArray::kHeaderSize - kHeapObjectTag));
+#endif
+  // Update the write barrier for the array store.
+  __ RecordWrite(r8, r9, r3, kLRHasNotBeenSaved, kDontSaveFPRegs,
+                 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+  __ Ret();
+
+  // Array literal has ElementsKind of FAST_*_SMI_ELEMENTS or FAST_*_ELEMENTS,
+  // and value is Smi.
+  __ bind(&smi_element);
+  __ LoadP(r8, FieldMemOperand(r4, JSObject::kElementsOffset));
+  __ SmiToPtrArrayOffset(r9, r6);
+  __ add(r9, r8, r9);
+  __ StoreP(r3, FieldMemOperand(r9, FixedArray::kHeaderSize), r0);
+  __ Ret();
+
+  // Array literal has ElementsKind of FAST_DOUBLE_ELEMENTS.
+  __ bind(&double_elements);
+  __ LoadP(r8, FieldMemOperand(r4, JSObject::kElementsOffset));
+  __ StoreNumberToDoubleElements(r3, r6, r8, r9, d0, &slow_elements);
+  __ Ret();
+}
+
+
+void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
+  CEntryStub ces(isolate(), 1, kSaveFPRegs);
+  __ Call(ces.GetCode(), RelocInfo::CODE_TARGET);
+  int parameter_count_offset =
+      StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
+  __ LoadP(r4, MemOperand(fp, parameter_count_offset));
+  if (function_mode() == JS_FUNCTION_STUB_MODE) {
+    __ addi(r4, r4, Operand(1));
+  }
+  masm->LeaveFrame(StackFrame::STUB_FAILURE_TRAMPOLINE);
+  __ slwi(r4, r4, Operand(kPointerSizeLog2));
+  __ add(sp, sp, r4);
+  __ Ret();
+}
+
+
+void LoadICTrampolineStub::Generate(MacroAssembler* masm) {
+  EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister());
+  VectorLoadStub stub(isolate(), state());
+  __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
+}
+
+
+void KeyedLoadICTrampolineStub::Generate(MacroAssembler* masm) {
+  EmitLoadTypeFeedbackVector(masm, VectorLoadICDescriptor::VectorRegister());
+  VectorKeyedLoadStub stub(isolate());
+  __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
+}
+
+
+void ProfileEntryHookStub::MaybeCallEntryHook(MacroAssembler* masm) {
+  if (masm->isolate()->function_entry_hook() != NULL) {
+    PredictableCodeSizeScope predictable(masm,
+#if V8_TARGET_ARCH_PPC64
+                                         14 * Assembler::kInstrSize);
+#else
+                                         11 * Assembler::kInstrSize);
+#endif
+    ProfileEntryHookStub stub(masm->isolate());
+    __ mflr(r0);
+    __ Push(r0, ip);
+    __ CallStub(&stub);
+    __ Pop(r0, ip);
+    __ mtlr(r0);
+  }
+}
+
+
+void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
+  // The entry hook is a "push lr, ip" instruction, followed by a call.
+  const int32_t kReturnAddressDistanceFromFunctionStart =
+      Assembler::kCallTargetAddressOffset + 3 * Assembler::kInstrSize;
+
+  // This should contain all kJSCallerSaved registers.
+  const RegList kSavedRegs = kJSCallerSaved |  // Caller saved registers.
+                             r15.bit();        // Saved stack pointer.
+
+  // We also save lr, so the count here is one higher than the mask indicates.
+  const int32_t kNumSavedRegs = kNumJSCallerSaved + 2;
+
+  // Save all caller-save registers as this may be called from anywhere.
+  __ mflr(ip);
+  __ MultiPush(kSavedRegs | ip.bit());
+
+  // Compute the function's address for the first argument.
+  __ subi(r3, ip, Operand(kReturnAddressDistanceFromFunctionStart));
+
+  // The caller's return address is two slots above the saved temporaries.
+  // Grab that for the second argument to the hook.
+  __ addi(r4, sp, Operand((kNumSavedRegs + 1) * kPointerSize));
+
+  // Align the stack if necessary.
+  int frame_alignment = masm->ActivationFrameAlignment();
+  if (frame_alignment > kPointerSize) {
+    __ mr(r15, sp);
+    DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
+    __ ClearRightImm(sp, sp, Operand(WhichPowerOf2(frame_alignment)));
+  }
+
+#if !defined(USE_SIMULATOR)
+  uintptr_t entry_hook =
+      reinterpret_cast<uintptr_t>(isolate()->function_entry_hook());
+  __ mov(ip, Operand(entry_hook));
+
+#if ABI_USES_FUNCTION_DESCRIPTORS
+  // Function descriptor
+  __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(ip, kPointerSize));
+  __ LoadP(ip, MemOperand(ip, 0));
+#elif ABI_TOC_ADDRESSABILITY_VIA_IP
+// ip set above, so nothing to do.
+#endif
+
+  // PPC LINUX ABI:
+  __ li(r0, Operand::Zero());
+  __ StorePU(r0, MemOperand(sp, -kNumRequiredStackFrameSlots * kPointerSize));
+#else
+  // Under the simulator we need to indirect the entry hook through a
+  // trampoline function at a known address.
+  // It additionally takes an isolate as a third parameter
+  __ mov(r5, Operand(ExternalReference::isolate_address(isolate())));
+
+  ApiFunction dispatcher(FUNCTION_ADDR(EntryHookTrampoline));
+  __ mov(ip, Operand(ExternalReference(
+                 &dispatcher, ExternalReference::BUILTIN_CALL, isolate())));
+#endif
+  __ Call(ip);
+
+#if !defined(USE_SIMULATOR)
+  __ addi(sp, sp, Operand(kNumRequiredStackFrameSlots * kPointerSize));
+#endif
+
+  // Restore the stack pointer if needed.
+  if (frame_alignment > kPointerSize) {
+    __ mr(sp, r15);
+  }
+
+  // Also pop lr to get Ret(0).
+  __ MultiPop(kSavedRegs | ip.bit());
+  __ mtlr(ip);
+  __ Ret();
+}
+
+
+template <class T>
+static void CreateArrayDispatch(MacroAssembler* masm,
+                                AllocationSiteOverrideMode mode) {
+  if (mode == DISABLE_ALLOCATION_SITES) {
+    T stub(masm->isolate(), GetInitialFastElementsKind(), mode);
+    __ TailCallStub(&stub);
+  } else if (mode == DONT_OVERRIDE) {
+    int last_index =
+        GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND);
+    for (int i = 0; i <= last_index; ++i) {
+      ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
+      __ Cmpi(r6, Operand(kind), r0);
+      T stub(masm->isolate(), kind);
+      __ TailCallStub(&stub, eq);
+    }
+
+    // If we reached this point there is a problem.
+    __ Abort(kUnexpectedElementsKindInArrayConstructor);
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
+static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
+                                           AllocationSiteOverrideMode mode) {
+  // r5 - allocation site (if mode != DISABLE_ALLOCATION_SITES)
+  // r6 - kind (if mode != DISABLE_ALLOCATION_SITES)
+  // r3 - number of arguments
+  // r4 - constructor?
+  // sp[0] - last argument
+  Label normal_sequence;
+  if (mode == DONT_OVERRIDE) {
+    DCHECK(FAST_SMI_ELEMENTS == 0);
+    DCHECK(FAST_HOLEY_SMI_ELEMENTS == 1);
+    DCHECK(FAST_ELEMENTS == 2);
+    DCHECK(FAST_HOLEY_ELEMENTS == 3);
+    DCHECK(FAST_DOUBLE_ELEMENTS == 4);
+    DCHECK(FAST_HOLEY_DOUBLE_ELEMENTS == 5);
+
+    // is the low bit set? If so, we are holey and that is good.
+    __ andi(r0, r6, Operand(1));
+    __ bne(&normal_sequence, cr0);
+  }
+
+  // look at the first argument
+  __ LoadP(r8, MemOperand(sp, 0));
+  __ cmpi(r8, Operand::Zero());
+  __ beq(&normal_sequence);
+
+  if (mode == DISABLE_ALLOCATION_SITES) {
+    ElementsKind initial = GetInitialFastElementsKind();
+    ElementsKind holey_initial = GetHoleyElementsKind(initial);
+
+    ArraySingleArgumentConstructorStub stub_holey(
+        masm->isolate(), holey_initial, DISABLE_ALLOCATION_SITES);
+    __ TailCallStub(&stub_holey);
+
+    __ bind(&normal_sequence);
+    ArraySingleArgumentConstructorStub stub(masm->isolate(), initial,
+                                            DISABLE_ALLOCATION_SITES);
+    __ TailCallStub(&stub);
+  } else if (mode == DONT_OVERRIDE) {
+    // We are going to create a holey array, but our kind is non-holey.
+    // Fix kind and retry (only if we have an allocation site in the slot).
+    __ addi(r6, r6, Operand(1));
+
+    if (FLAG_debug_code) {
+      __ LoadP(r8, FieldMemOperand(r5, 0));
+      __ CompareRoot(r8, Heap::kAllocationSiteMapRootIndex);
+      __ Assert(eq, kExpectedAllocationSite);
+    }
+
+    // Save the resulting elements kind in type info. We can't just store r6
+    // in the AllocationSite::transition_info field because elements kind is
+    // restricted to a portion of the field...upper bits need to be left alone.
+    STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0);
+    __ LoadP(r7, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset));
+    __ AddSmiLiteral(r7, r7, Smi::FromInt(kFastElementsKindPackedToHoley), r0);
+    __ StoreP(r7, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset),
+              r0);
+
+    __ bind(&normal_sequence);
+    int last_index =
+        GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND);
+    for (int i = 0; i <= last_index; ++i) {
+      ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
+      __ mov(r0, Operand(kind));
+      __ cmp(r6, r0);
+      ArraySingleArgumentConstructorStub stub(masm->isolate(), kind);
+      __ TailCallStub(&stub, eq);
+    }
+
+    // If we reached this point there is a problem.
+    __ Abort(kUnexpectedElementsKindInArrayConstructor);
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
+template <class T>
+static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
+  int to_index =
+      GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND);
+  for (int i = 0; i <= to_index; ++i) {
+    ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
+    T stub(isolate, kind);
+    stub.GetCode();
+    if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
+      T stub1(isolate, kind, DISABLE_ALLOCATION_SITES);
+      stub1.GetCode();
+    }
+  }
+}
+
+
+void ArrayConstructorStubBase::GenerateStubsAheadOfTime(Isolate* isolate) {
+  ArrayConstructorStubAheadOfTimeHelper<ArrayNoArgumentConstructorStub>(
+      isolate);
+  ArrayConstructorStubAheadOfTimeHelper<ArraySingleArgumentConstructorStub>(
+      isolate);
+  ArrayConstructorStubAheadOfTimeHelper<ArrayNArgumentsConstructorStub>(
+      isolate);
+}
+
+
+void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime(
+    Isolate* isolate) {
+  ElementsKind kinds[2] = {FAST_ELEMENTS, FAST_HOLEY_ELEMENTS};
+  for (int i = 0; i < 2; i++) {
+    // For internal arrays we only need a few things
+    InternalArrayNoArgumentConstructorStub stubh1(isolate, kinds[i]);
+    stubh1.GetCode();
+    InternalArraySingleArgumentConstructorStub stubh2(isolate, kinds[i]);
+    stubh2.GetCode();
+    InternalArrayNArgumentsConstructorStub stubh3(isolate, kinds[i]);
+    stubh3.GetCode();
+  }
+}
+
+
+void ArrayConstructorStub::GenerateDispatchToArrayStub(
+    MacroAssembler* masm, AllocationSiteOverrideMode mode) {
+  if (argument_count() == ANY) {
+    Label not_zero_case, not_one_case;
+    __ cmpi(r3, Operand::Zero());
+    __ bne(&not_zero_case);
+    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
+
+    __ bind(&not_zero_case);
+    __ cmpi(r3, Operand(1));
+    __ bgt(&not_one_case);
+    CreateArrayDispatchOneArgument(masm, mode);
+
+    __ bind(&not_one_case);
+    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
+  } else if (argument_count() == NONE) {
+    CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode);
+  } else if (argument_count() == ONE) {
+    CreateArrayDispatchOneArgument(masm, mode);
+  } else if (argument_count() == MORE_THAN_ONE) {
+    CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode);
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
+void ArrayConstructorStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- r3 : argc (only if argument_count() == ANY)
+  //  -- r4 : constructor
+  //  -- r5 : AllocationSite or undefined
+  //  -- sp[0] : return address
+  //  -- sp[4] : last argument
+  // -----------------------------------
+
+  if (FLAG_debug_code) {
+    // The array construct code is only set for the global and natives
+    // builtin Array functions which always have maps.
+
+    // Initial map for the builtin Array function should be a map.
+    __ LoadP(r7, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset));
+    // Will both indicate a NULL and a Smi.
+    __ TestIfSmi(r7, r0);
+    __ Assert(ne, kUnexpectedInitialMapForArrayFunction, cr0);
+    __ CompareObjectType(r7, r7, r8, MAP_TYPE);
+    __ Assert(eq, kUnexpectedInitialMapForArrayFunction);
+
+    // We should either have undefined in r5 or a valid AllocationSite
+    __ AssertUndefinedOrAllocationSite(r5, r7);
+  }
+
+  Label no_info;
+  // Get the elements kind and case on that.
+  __ CompareRoot(r5, Heap::kUndefinedValueRootIndex);
+  __ beq(&no_info);
+
+  __ LoadP(r6, FieldMemOperand(r5, AllocationSite::kTransitionInfoOffset));
+  __ SmiUntag(r6);
+  STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0);
+  __ And(r6, r6, Operand(AllocationSite::ElementsKindBits::kMask));
+  GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
+
+  __ bind(&no_info);
+  GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
+}
+
+
+void InternalArrayConstructorStub::GenerateCase(MacroAssembler* masm,
+                                                ElementsKind kind) {
+  __ cmpli(r3, Operand(1));
+
+  InternalArrayNoArgumentConstructorStub stub0(isolate(), kind);
+  __ TailCallStub(&stub0, lt);
+
+  InternalArrayNArgumentsConstructorStub stubN(isolate(), kind);
+  __ TailCallStub(&stubN, gt);
+
+  if (IsFastPackedElementsKind(kind)) {
+    // We might need to create a holey array
+    // look at the first argument
+    __ LoadP(r6, MemOperand(sp, 0));
+    __ cmpi(r6, Operand::Zero());
+
+    InternalArraySingleArgumentConstructorStub stub1_holey(
+        isolate(), GetHoleyElementsKind(kind));
+    __ TailCallStub(&stub1_holey, ne);
+  }
+
+  InternalArraySingleArgumentConstructorStub stub1(isolate(), kind);
+  __ TailCallStub(&stub1);
+}
+
+
+void InternalArrayConstructorStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- r3 : argc
+  //  -- r4 : constructor
+  //  -- sp[0] : return address
+  //  -- sp[4] : last argument
+  // -----------------------------------
+
+  if (FLAG_debug_code) {
+    // The array construct code is only set for the global and natives
+    // builtin Array functions which always have maps.
+
+    // Initial map for the builtin Array function should be a map.
+    __ LoadP(r6, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset));
+    // Will both indicate a NULL and a Smi.
+    __ TestIfSmi(r6, r0);
+    __ Assert(ne, kUnexpectedInitialMapForArrayFunction, cr0);
+    __ CompareObjectType(r6, r6, r7, MAP_TYPE);
+    __ Assert(eq, kUnexpectedInitialMapForArrayFunction);
+  }
+
+  // Figure out the right elements kind
+  __ LoadP(r6, FieldMemOperand(r4, JSFunction::kPrototypeOrInitialMapOffset));
+  // Load the map's "bit field 2" into |result|.
+  __ lbz(r6, FieldMemOperand(r6, Map::kBitField2Offset));
+  // Retrieve elements_kind from bit field 2.
+  __ DecodeField<Map::ElementsKindBits>(r6);
+
+  if (FLAG_debug_code) {
+    Label done;
+    __ cmpi(r6, Operand(FAST_ELEMENTS));
+    __ beq(&done);
+    __ cmpi(r6, Operand(FAST_HOLEY_ELEMENTS));
+    __ Assert(eq, kInvalidElementsKindForInternalArrayOrInternalPackedArray);
+    __ bind(&done);
+  }
+
+  Label fast_elements_case;
+  __ cmpi(r6, Operand(FAST_ELEMENTS));
+  __ beq(&fast_elements_case);
+  GenerateCase(masm, FAST_HOLEY_ELEMENTS);
+
+  __ bind(&fast_elements_case);
+  GenerateCase(masm, FAST_ELEMENTS);
+}
+
+
+void CallApiFunctionStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- r3                  : callee
+  //  -- r7                  : call_data
+  //  -- r5                  : holder
+  //  -- r4                  : api_function_address
+  //  -- cp                  : context
+  //  --
+  //  -- sp[0]               : last argument
+  //  -- ...
+  //  -- sp[(argc - 1)* 4]   : first argument
+  //  -- sp[argc * 4]        : receiver
+  // -----------------------------------
+
+  Register callee = r3;
+  Register call_data = r7;
+  Register holder = r5;
+  Register api_function_address = r4;
+  Register context = cp;
+
+  int argc = this->argc();
+  bool is_store = this->is_store();
+  bool call_data_undefined = this->call_data_undefined();
+
+  typedef FunctionCallbackArguments FCA;
+
+  STATIC_ASSERT(FCA::kContextSaveIndex == 6);
+  STATIC_ASSERT(FCA::kCalleeIndex == 5);
+  STATIC_ASSERT(FCA::kDataIndex == 4);
+  STATIC_ASSERT(FCA::kReturnValueOffset == 3);
+  STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
+  STATIC_ASSERT(FCA::kIsolateIndex == 1);
+  STATIC_ASSERT(FCA::kHolderIndex == 0);
+  STATIC_ASSERT(FCA::kArgsLength == 7);
+
+  // context save
+  __ push(context);
+  // load context from callee
+  __ LoadP(context, FieldMemOperand(callee, JSFunction::kContextOffset));
+
+  // callee
+  __ push(callee);
+
+  // call data
+  __ push(call_data);
+
+  Register scratch = call_data;
+  if (!call_data_undefined) {
+    __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
+  }
+  // return value
+  __ push(scratch);
+  // return value default
+  __ push(scratch);
+  // isolate
+  __ mov(scratch, Operand(ExternalReference::isolate_address(isolate())));
+  __ push(scratch);
+  // holder
+  __ push(holder);
+
+  // Prepare arguments.
+  __ mr(scratch, sp);
+
+  // Allocate the v8::Arguments structure in the arguments' space since
+  // it's not controlled by GC.
+  // PPC LINUX ABI:
+  //
+  // Create 5 extra slots on stack:
+  //    [0] space for DirectCEntryStub's LR save
+  //    [1-4] FunctionCallbackInfo
+  const int kApiStackSpace = 5;
+
+  FrameScope frame_scope(masm, StackFrame::MANUAL);
+  __ EnterExitFrame(false, kApiStackSpace);
+
+  DCHECK(!api_function_address.is(r3) && !scratch.is(r3));
+  // r3 = FunctionCallbackInfo&
+  // Arguments is after the return address.
+  __ addi(r3, sp, Operand((kStackFrameExtraParamSlot + 1) * kPointerSize));
+  // FunctionCallbackInfo::implicit_args_
+  __ StoreP(scratch, MemOperand(r3, 0 * kPointerSize));
+  // FunctionCallbackInfo::values_
+  __ addi(ip, scratch, Operand((FCA::kArgsLength - 1 + argc) * kPointerSize));
+  __ StoreP(ip, MemOperand(r3, 1 * kPointerSize));
+  // FunctionCallbackInfo::length_ = argc
+  __ li(ip, Operand(argc));
+  __ stw(ip, MemOperand(r3, 2 * kPointerSize));
+  // FunctionCallbackInfo::is_construct_call = 0
+  __ li(ip, Operand::Zero());
+  __ stw(ip, MemOperand(r3, 2 * kPointerSize + kIntSize));
+
+  const int kStackUnwindSpace = argc + FCA::kArgsLength + 1;
+  ExternalReference thunk_ref =
+      ExternalReference::invoke_function_callback(isolate());
+
+  AllowExternalCallThatCantCauseGC scope(masm);
+  MemOperand context_restore_operand(
+      fp, (2 + FCA::kContextSaveIndex) * kPointerSize);
+  // Stores return the first js argument
+  int return_value_offset = 0;
+  if (is_store) {
+    return_value_offset = 2 + FCA::kArgsLength;
+  } else {
+    return_value_offset = 2 + FCA::kReturnValueOffset;
+  }
+  MemOperand return_value_operand(fp, return_value_offset * kPointerSize);
+
+  __ CallApiFunctionAndReturn(api_function_address, thunk_ref,
+                              kStackUnwindSpace, return_value_operand,
+                              &context_restore_operand);
+}
+
+
+void CallApiGetterStub::Generate(MacroAssembler* masm) {
+  // ----------- S t a t e -------------
+  //  -- sp[0]                  : name
+  //  -- sp[4 - kArgsLength*4]  : PropertyCallbackArguments object
+  //  -- ...
+  //  -- r5                     : api_function_address
+  // -----------------------------------
+
+  Register api_function_address = ApiGetterDescriptor::function_address();
+  DCHECK(api_function_address.is(r5));
+
+  __ mr(r3, sp);                               // r0 = Handle<Name>
+  __ addi(r4, r3, Operand(1 * kPointerSize));  // r4 = PCA
+
+// If ABI passes Handles (pointer-sized struct) in a register:
+//
+// Create 2 extra slots on stack:
+//    [0] space for DirectCEntryStub's LR save
+//    [1] AccessorInfo&
+//
+// Otherwise:
+//
+// Create 3 extra slots on stack:
+//    [0] space for DirectCEntryStub's LR save
+//    [1] copy of Handle (first arg)
+//    [2] AccessorInfo&
+#if ABI_PASSES_HANDLES_IN_REGS
+  const int kAccessorInfoSlot = kStackFrameExtraParamSlot + 1;
+  const int kApiStackSpace = 2;
+#else
+  const int kArg0Slot = kStackFrameExtraParamSlot + 1;
+  const int kAccessorInfoSlot = kArg0Slot + 1;
+  const int kApiStackSpace = 3;
+#endif
+
+  FrameScope frame_scope(masm, StackFrame::MANUAL);
+  __ EnterExitFrame(false, kApiStackSpace);
+
+#if !ABI_PASSES_HANDLES_IN_REGS
+  // pass 1st arg by reference
+  __ StoreP(r3, MemOperand(sp, kArg0Slot * kPointerSize));
+  __ addi(r3, sp, Operand(kArg0Slot * kPointerSize));
+#endif
+
+  // Create PropertyAccessorInfo instance on the stack above the exit frame with
+  // r4 (internal::Object** args_) as the data.
+  __ StoreP(r4, MemOperand(sp, kAccessorInfoSlot * kPointerSize));
+  // r4 = AccessorInfo&
+  __ addi(r4, sp, Operand(kAccessorInfoSlot * kPointerSize));
+
+  const int kStackUnwindSpace = PropertyCallbackArguments::kArgsLength + 1;
+
+  ExternalReference thunk_ref =
+      ExternalReference::invoke_accessor_getter_callback(isolate());
+  __ CallApiFunctionAndReturn(api_function_address, thunk_ref,
+                              kStackUnwindSpace,
+                              MemOperand(fp, 6 * kPointerSize), NULL);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/code-stubs-ppc.h b/src/ppc/code-stubs-ppc.h
new file mode 100644
index 0000000..a9d06fb
--- /dev/null
+++ b/src/ppc/code-stubs-ppc.h
@@ -0,0 +1,325 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_PPC_CODE_STUBS_PPC_H_
+#define V8_PPC_CODE_STUBS_PPC_H_
+
+namespace v8 {
+namespace internal {
+
+
+void ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code);
+
+
+class StringHelper : public AllStatic {
+ public:
+  // Generate code for copying a large number of characters. This function
+  // is allowed to spend extra time setting up conditions to make copying
+  // faster. Copying of overlapping regions is not supported.
+  // Dest register ends at the position after the last character written.
+  static void GenerateCopyCharacters(MacroAssembler* masm, Register dest,
+                                     Register src, Register count,
+                                     Register scratch,
+                                     String::Encoding encoding);
+
+  // Compares two flat one-byte strings and returns result in r0.
+  static void GenerateCompareFlatOneByteStrings(MacroAssembler* masm,
+                                                Register left, Register right,
+                                                Register scratch1,
+                                                Register scratch2,
+                                                Register scratch3);
+
+  // Compares two flat one-byte strings for equality and returns result in r0.
+  static void GenerateFlatOneByteStringEquals(MacroAssembler* masm,
+                                              Register left, Register right,
+                                              Register scratch1,
+                                              Register scratch2);
+
+ private:
+  static void GenerateOneByteCharsCompareLoop(MacroAssembler* masm,
+                                              Register left, Register right,
+                                              Register length,
+                                              Register scratch1,
+                                              Label* chars_not_equal);
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
+};
+
+
+class StoreRegistersStateStub : public PlatformCodeStub {
+ public:
+  explicit StoreRegistersStateStub(Isolate* isolate)
+      : PlatformCodeStub(isolate) {}
+
+  static void GenerateAheadOfTime(Isolate* isolate);
+
+ private:
+  DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
+  DEFINE_PLATFORM_CODE_STUB(StoreRegistersState, PlatformCodeStub);
+};
+
+
+class RestoreRegistersStateStub : public PlatformCodeStub {
+ public:
+  explicit RestoreRegistersStateStub(Isolate* isolate)
+      : PlatformCodeStub(isolate) {}
+
+  static void GenerateAheadOfTime(Isolate* isolate);
+
+ private:
+  DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
+  DEFINE_PLATFORM_CODE_STUB(RestoreRegistersState, PlatformCodeStub);
+};
+
+
+class RecordWriteStub : public PlatformCodeStub {
+ public:
+  RecordWriteStub(Isolate* isolate, Register object, Register value,
+                  Register address, RememberedSetAction remembered_set_action,
+                  SaveFPRegsMode fp_mode)
+      : PlatformCodeStub(isolate),
+        regs_(object,   // An input reg.
+              address,  // An input reg.
+              value) {  // One scratch reg.
+    minor_key_ = ObjectBits::encode(object.code()) |
+                 ValueBits::encode(value.code()) |
+                 AddressBits::encode(address.code()) |
+                 RememberedSetActionBits::encode(remembered_set_action) |
+                 SaveFPRegsModeBits::encode(fp_mode);
+  }
+
+  RecordWriteStub(uint32_t key, Isolate* isolate)
+      : PlatformCodeStub(key, isolate), regs_(object(), address(), value()) {}
+
+  enum Mode { STORE_BUFFER_ONLY, INCREMENTAL, INCREMENTAL_COMPACTION };
+
+  virtual bool SometimesSetsUpAFrame() { return false; }
+
+  static void PatchBranchIntoNop(MacroAssembler* masm, int pos) {
+    // Consider adding DCHECK here to catch bad patching
+    masm->instr_at_put(pos, (masm->instr_at(pos) & ~kBOfieldMask) | BT);
+  }
+
+  static void PatchNopIntoBranch(MacroAssembler* masm, int pos) {
+    // Consider adding DCHECK here to catch bad patching
+    masm->instr_at_put(pos, (masm->instr_at(pos) & ~kBOfieldMask) | BF);
+  }
+
+  static Mode GetMode(Code* stub) {
+    Instr first_instruction =
+        Assembler::instr_at(stub->instruction_start() + Assembler::kInstrSize);
+    Instr second_instruction = Assembler::instr_at(stub->instruction_start() +
+                                                   (Assembler::kInstrSize * 2));
+
+    // Consider adding DCHECK here to catch unexpected instruction sequence
+    if (BF == (first_instruction & kBOfieldMask)) {
+      return INCREMENTAL;
+    }
+
+    if (BF == (second_instruction & kBOfieldMask)) {
+      return INCREMENTAL_COMPACTION;
+    }
+
+    return STORE_BUFFER_ONLY;
+  }
+
+  static void Patch(Code* stub, Mode mode) {
+    MacroAssembler masm(NULL, stub->instruction_start(),
+                        stub->instruction_size());
+    switch (mode) {
+      case STORE_BUFFER_ONLY:
+        DCHECK(GetMode(stub) == INCREMENTAL ||
+               GetMode(stub) == INCREMENTAL_COMPACTION);
+
+        PatchBranchIntoNop(&masm, Assembler::kInstrSize);
+        PatchBranchIntoNop(&masm, Assembler::kInstrSize * 2);
+        break;
+      case INCREMENTAL:
+        DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
+        PatchNopIntoBranch(&masm, Assembler::kInstrSize);
+        break;
+      case INCREMENTAL_COMPACTION:
+        DCHECK(GetMode(stub) == STORE_BUFFER_ONLY);
+        PatchNopIntoBranch(&masm, Assembler::kInstrSize * 2);
+        break;
+    }
+    DCHECK(GetMode(stub) == mode);
+    CpuFeatures::FlushICache(stub->instruction_start() + Assembler::kInstrSize,
+                             2 * Assembler::kInstrSize);
+  }
+
+  DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
+
+ private:
+  // This is a helper class for freeing up 3 scratch registers.  The input is
+  // two registers that must be preserved and one scratch register provided by
+  // the caller.
+  class RegisterAllocation {
+   public:
+    RegisterAllocation(Register object, Register address, Register scratch0)
+        : object_(object), address_(address), scratch0_(scratch0) {
+      DCHECK(!AreAliased(scratch0, object, address, no_reg));
+      scratch1_ = GetRegisterThatIsNotOneOf(object_, address_, scratch0_);
+    }
+
+    void Save(MacroAssembler* masm) {
+      DCHECK(!AreAliased(object_, address_, scratch1_, scratch0_));
+      // We don't have to save scratch0_ because it was given to us as
+      // a scratch register.
+      masm->push(scratch1_);
+    }
+
+    void Restore(MacroAssembler* masm) { masm->pop(scratch1_); }
+
+    // If we have to call into C then we need to save and restore all caller-
+    // saved registers that were not already preserved.  The scratch registers
+    // will be restored by other means so we don't bother pushing them here.
+    void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) {
+      masm->mflr(r0);
+      masm->push(r0);
+      masm->MultiPush(kJSCallerSaved & ~scratch1_.bit());
+      if (mode == kSaveFPRegs) {
+        // Save all volatile FP registers except d0.
+        masm->SaveFPRegs(sp, 1, DoubleRegister::kNumVolatileRegisters - 1);
+      }
+    }
+
+    inline void RestoreCallerSaveRegisters(MacroAssembler* masm,
+                                           SaveFPRegsMode mode) {
+      if (mode == kSaveFPRegs) {
+        // Restore all volatile FP registers except d0.
+        masm->RestoreFPRegs(sp, 1, DoubleRegister::kNumVolatileRegisters - 1);
+      }
+      masm->MultiPop(kJSCallerSaved & ~scratch1_.bit());
+      masm->pop(r0);
+      masm->mtlr(r0);
+    }
+
+    inline Register object() { return object_; }
+    inline Register address() { return address_; }
+    inline Register scratch0() { return scratch0_; }
+    inline Register scratch1() { return scratch1_; }
+
+   private:
+    Register object_;
+    Register address_;
+    Register scratch0_;
+    Register scratch1_;
+
+    friend class RecordWriteStub;
+  };
+
+  enum OnNoNeedToInformIncrementalMarker {
+    kReturnOnNoNeedToInformIncrementalMarker,
+    kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
+  };
+
+  inline Major MajorKey() const FINAL { return RecordWrite; }
+
+  void Generate(MacroAssembler* masm) OVERRIDE;
+  void GenerateIncremental(MacroAssembler* masm, Mode mode);
+  void CheckNeedsToInformIncrementalMarker(
+      MacroAssembler* masm, OnNoNeedToInformIncrementalMarker on_no_need,
+      Mode mode);
+  void InformIncrementalMarker(MacroAssembler* masm);
+
+  void Activate(Code* code) {
+    code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
+  }
+
+  Register object() const {
+    return Register::from_code(ObjectBits::decode(minor_key_));
+  }
+
+  Register value() const {
+    return Register::from_code(ValueBits::decode(minor_key_));
+  }
+
+  Register address() const {
+    return Register::from_code(AddressBits::decode(minor_key_));
+  }
+
+  RememberedSetAction remembered_set_action() const {
+    return RememberedSetActionBits::decode(minor_key_);
+  }
+
+  SaveFPRegsMode save_fp_regs_mode() const {
+    return SaveFPRegsModeBits::decode(minor_key_);
+  }
+
+  class ObjectBits : public BitField<int, 0, 5> {};
+  class ValueBits : public BitField<int, 5, 5> {};
+  class AddressBits : public BitField<int, 10, 5> {};
+  class RememberedSetActionBits : public BitField<RememberedSetAction, 15, 1> {
+  };
+  class SaveFPRegsModeBits : public BitField<SaveFPRegsMode, 16, 1> {};
+
+  Label slow_;
+  RegisterAllocation regs_;
+
+  DISALLOW_COPY_AND_ASSIGN(RecordWriteStub);
+};
+
+
+// Trampoline stub to call into native code. To call safely into native code
+// in the presence of compacting GC (which can move code objects) we need to
+// keep the code which called into native pinned in the memory. Currently the
+// simplest approach is to generate such stub early enough so it can never be
+// moved by GC
+class DirectCEntryStub : public PlatformCodeStub {
+ public:
+  explicit DirectCEntryStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
+  void GenerateCall(MacroAssembler* masm, Register target);
+
+ private:
+  bool NeedsImmovableCode() { return true; }
+
+  DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
+  DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub);
+};
+
+
+class NameDictionaryLookupStub : public PlatformCodeStub {
+ public:
+  enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
+
+  NameDictionaryLookupStub(Isolate* isolate, LookupMode mode)
+      : PlatformCodeStub(isolate) {
+    minor_key_ = LookupModeBits::encode(mode);
+  }
+
+  static void GenerateNegativeLookup(MacroAssembler* masm, Label* miss,
+                                     Label* done, Register receiver,
+                                     Register properties, Handle<Name> name,
+                                     Register scratch0);
+
+  static void GeneratePositiveLookup(MacroAssembler* masm, Label* miss,
+                                     Label* done, Register elements,
+                                     Register name, Register r0, Register r1);
+
+  virtual bool SometimesSetsUpAFrame() { return false; }
+
+ private:
+  static const int kInlinedProbes = 4;
+  static const int kTotalProbes = 20;
+
+  static const int kCapacityOffset =
+      NameDictionary::kHeaderSize +
+      NameDictionary::kCapacityIndex * kPointerSize;
+
+  static const int kElementsStartOffset =
+      NameDictionary::kHeaderSize +
+      NameDictionary::kElementsStartIndex * kPointerSize;
+
+  LookupMode mode() const { return LookupModeBits::decode(minor_key_); }
+
+  class LookupModeBits : public BitField<LookupMode, 0, 1> {};
+
+  DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
+  DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub);
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_PPC_CODE_STUBS_PPC_H_
diff --git a/src/ppc/codegen-ppc.cc b/src/ppc/codegen-ppc.cc
new file mode 100644
index 0000000..1074e87
--- /dev/null
+++ b/src/ppc/codegen-ppc.cc
@@ -0,0 +1,700 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/codegen.h"
+#include "src/macro-assembler.h"
+#include "src/ppc/simulator-ppc.h"
+
+namespace v8 {
+namespace internal {
+
+
+#define __ masm.
+
+
+#if defined(USE_SIMULATOR)
+byte* fast_exp_ppc_machine_code = NULL;
+double fast_exp_simulator(double x) {
+  return Simulator::current(Isolate::Current())
+      ->CallFPReturnsDouble(fast_exp_ppc_machine_code, x, 0);
+}
+#endif
+
+
+UnaryMathFunction CreateExpFunction() {
+  if (!FLAG_fast_math) return &std::exp;
+  size_t actual_size;
+  byte* buffer =
+      static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true));
+  if (buffer == NULL) return &std::exp;
+  ExternalReference::InitializeMathExpData();
+
+  MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
+
+  {
+    DoubleRegister input = d1;
+    DoubleRegister result = d2;
+    DoubleRegister double_scratch1 = d3;
+    DoubleRegister double_scratch2 = d4;
+    Register temp1 = r7;
+    Register temp2 = r8;
+    Register temp3 = r9;
+
+// Called from C
+#if ABI_USES_FUNCTION_DESCRIPTORS
+    __ function_descriptor();
+#endif
+
+    __ Push(temp3, temp2, temp1);
+    MathExpGenerator::EmitMathExp(&masm, input, result, double_scratch1,
+                                  double_scratch2, temp1, temp2, temp3);
+    __ Pop(temp3, temp2, temp1);
+    __ fmr(d1, result);
+    __ Ret();
+  }
+
+  CodeDesc desc;
+  masm.GetCode(&desc);
+#if !ABI_USES_FUNCTION_DESCRIPTORS
+  DCHECK(!RelocInfo::RequiresRelocation(desc));
+#endif
+
+  CpuFeatures::FlushICache(buffer, actual_size);
+  base::OS::ProtectCode(buffer, actual_size);
+
+#if !defined(USE_SIMULATOR)
+  return FUNCTION_CAST<UnaryMathFunction>(buffer);
+#else
+  fast_exp_ppc_machine_code = buffer;
+  return &fast_exp_simulator;
+#endif
+}
+
+
+UnaryMathFunction CreateSqrtFunction() {
+#if defined(USE_SIMULATOR)
+  return &std::sqrt;
+#else
+  size_t actual_size;
+  byte* buffer =
+      static_cast<byte*>(base::OS::Allocate(1 * KB, &actual_size, true));
+  if (buffer == NULL) return &std::sqrt;
+
+  MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
+
+// Called from C
+#if ABI_USES_FUNCTION_DESCRIPTORS
+  __ function_descriptor();
+#endif
+
+  __ MovFromFloatParameter(d1);
+  __ fsqrt(d1, d1);
+  __ MovToFloatResult(d1);
+  __ Ret();
+
+  CodeDesc desc;
+  masm.GetCode(&desc);
+#if !ABI_USES_FUNCTION_DESCRIPTORS
+  DCHECK(!RelocInfo::RequiresRelocation(desc));
+#endif
+
+  CpuFeatures::FlushICache(buffer, actual_size);
+  base::OS::ProtectCode(buffer, actual_size);
+  return FUNCTION_CAST<UnaryMathFunction>(buffer);
+#endif
+}
+
+#undef __
+
+
+// -------------------------------------------------------------------------
+// Platform-specific RuntimeCallHelper functions.
+
+void StubRuntimeCallHelper::BeforeCall(MacroAssembler* masm) const {
+  masm->EnterFrame(StackFrame::INTERNAL);
+  DCHECK(!masm->has_frame());
+  masm->set_has_frame(true);
+}
+
+
+void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const {
+  masm->LeaveFrame(StackFrame::INTERNAL);
+  DCHECK(masm->has_frame());
+  masm->set_has_frame(false);
+}
+
+
+// -------------------------------------------------------------------------
+// Code generators
+
+#define __ ACCESS_MASM(masm)
+
+void ElementsTransitionGenerator::GenerateMapChangeElementsTransition(
+    MacroAssembler* masm, Register receiver, Register key, Register value,
+    Register target_map, AllocationSiteMode mode,
+    Label* allocation_memento_found) {
+  Register scratch_elements = r7;
+  DCHECK(!AreAliased(receiver, key, value, target_map, scratch_elements));
+
+  if (mode == TRACK_ALLOCATION_SITE) {
+    DCHECK(allocation_memento_found != NULL);
+    __ JumpIfJSArrayHasAllocationMemento(receiver, scratch_elements,
+                                         allocation_memento_found);
+  }
+
+  // Set transitioned map.
+  __ StoreP(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset), r0);
+  __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, r11,
+                      kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
+                      OMIT_SMI_CHECK);
+}
+
+
+void ElementsTransitionGenerator::GenerateSmiToDouble(
+    MacroAssembler* masm, Register receiver, Register key, Register value,
+    Register target_map, AllocationSiteMode mode, Label* fail) {
+  // lr contains the return address
+  Label loop, entry, convert_hole, gc_required, only_change_map, done;
+  Register elements = r7;
+  Register length = r8;
+  Register array = r9;
+  Register array_end = array;
+
+  // target_map parameter can be clobbered.
+  Register scratch1 = target_map;
+  Register scratch2 = r11;
+
+  // Verify input registers don't conflict with locals.
+  DCHECK(!AreAliased(receiver, key, value, target_map, elements, length, array,
+                     scratch2));
+
+  if (mode == TRACK_ALLOCATION_SITE) {
+    __ JumpIfJSArrayHasAllocationMemento(receiver, elements, fail);
+  }
+
+  // Check for empty arrays, which only require a map transition and no changes
+  // to the backing store.
+  __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex);
+  __ beq(&only_change_map);
+
+  // Preserve lr and use r17 as a temporary register.
+  __ mflr(r0);
+  __ Push(r0);
+
+  __ LoadP(length, FieldMemOperand(elements, FixedArray::kLengthOffset));
+  // length: number of elements (smi-tagged)
+
+  // Allocate new FixedDoubleArray.
+  __ SmiToDoubleArrayOffset(r17, length);
+  __ addi(r17, r17, Operand(FixedDoubleArray::kHeaderSize));
+  __ Allocate(r17, array, r10, scratch2, &gc_required, DOUBLE_ALIGNMENT);
+
+  // Set destination FixedDoubleArray's length and map.
+  __ LoadRoot(scratch2, Heap::kFixedDoubleArrayMapRootIndex);
+  __ StoreP(length, MemOperand(array, FixedDoubleArray::kLengthOffset));
+  // Update receiver's map.
+  __ StoreP(scratch2, MemOperand(array, HeapObject::kMapOffset));
+
+  __ StoreP(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset), r0);
+  __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, scratch2,
+                      kLRHasBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
+                      OMIT_SMI_CHECK);
+  // Replace receiver's backing store with newly created FixedDoubleArray.
+  __ addi(scratch1, array, Operand(kHeapObjectTag));
+  __ StoreP(scratch1, FieldMemOperand(receiver, JSObject::kElementsOffset), r0);
+  __ RecordWriteField(receiver, JSObject::kElementsOffset, scratch1, scratch2,
+                      kLRHasBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
+                      OMIT_SMI_CHECK);
+
+  // Prepare for conversion loop.
+  __ addi(target_map, elements,
+          Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ addi(r10, array, Operand(FixedDoubleArray::kHeaderSize));
+  __ SmiToDoubleArrayOffset(array, length);
+  __ add(array_end, r10, array);
+// Repurpose registers no longer in use.
+#if V8_TARGET_ARCH_PPC64
+  Register hole_int64 = elements;
+#else
+  Register hole_lower = elements;
+  Register hole_upper = length;
+#endif
+  // scratch1: begin of source FixedArray element fields, not tagged
+  // hole_lower: kHoleNanLower32 OR hol_int64
+  // hole_upper: kHoleNanUpper32
+  // array_end: end of destination FixedDoubleArray, not tagged
+  // scratch2: begin of FixedDoubleArray element fields, not tagged
+
+  __ b(&entry);
+
+  __ bind(&only_change_map);
+  __ StoreP(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset), r0);
+  __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, scratch2,
+                      kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
+                      OMIT_SMI_CHECK);
+  __ b(&done);
+
+  // Call into runtime if GC is required.
+  __ bind(&gc_required);
+  __ Pop(r0);
+  __ mtlr(r0);
+  __ b(fail);
+
+  // Convert and copy elements.
+  __ bind(&loop);
+  __ LoadP(r11, MemOperand(scratch1));
+  __ addi(scratch1, scratch1, Operand(kPointerSize));
+  // r11: current element
+  __ UntagAndJumpIfNotSmi(r11, r11, &convert_hole);
+
+  // Normal smi, convert to double and store.
+  __ ConvertIntToDouble(r11, d0);
+  __ stfd(d0, MemOperand(scratch2, 0));
+  __ addi(r10, r10, Operand(8));
+
+  __ b(&entry);
+
+  // Hole found, store the-hole NaN.
+  __ bind(&convert_hole);
+  if (FLAG_debug_code) {
+    // Restore a "smi-untagged" heap object.
+    __ LoadP(r11, MemOperand(r6, -kPointerSize));
+    __ CompareRoot(r11, Heap::kTheHoleValueRootIndex);
+    __ Assert(eq, kObjectFoundInSmiOnlyArray);
+  }
+#if V8_TARGET_ARCH_PPC64
+  __ std(hole_int64, MemOperand(r10, 0));
+#else
+  __ stw(hole_upper, MemOperand(r10, Register::kExponentOffset));
+  __ stw(hole_lower, MemOperand(r10, Register::kMantissaOffset));
+#endif
+  __ addi(r10, r10, Operand(8));
+
+  __ bind(&entry);
+  __ cmp(r10, array_end);
+  __ blt(&loop);
+
+  __ Pop(r0);
+  __ mtlr(r0);
+  __ bind(&done);
+}
+
+
+void ElementsTransitionGenerator::GenerateDoubleToObject(
+    MacroAssembler* masm, Register receiver, Register key, Register value,
+    Register target_map, AllocationSiteMode mode, Label* fail) {
+  // Register lr contains the return address.
+  Label entry, loop, convert_hole, gc_required, only_change_map;
+  Register elements = r7;
+  Register array = r9;
+  Register length = r8;
+  Register scratch = r11;
+
+  // Verify input registers don't conflict with locals.
+  DCHECK(!AreAliased(receiver, key, value, target_map, elements, array, length,
+                     scratch));
+
+  if (mode == TRACK_ALLOCATION_SITE) {
+    __ JumpIfJSArrayHasAllocationMemento(receiver, elements, fail);
+  }
+
+  // Check for empty arrays, which only require a map transition and no changes
+  // to the backing store.
+  __ LoadP(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
+  __ CompareRoot(elements, Heap::kEmptyFixedArrayRootIndex);
+  __ beq(&only_change_map);
+
+  __ Push(target_map, receiver, key, value);
+  __ LoadP(length, FieldMemOperand(elements, FixedArray::kLengthOffset));
+  // elements: source FixedDoubleArray
+  // length: number of elements (smi-tagged)
+
+  // Allocate new FixedArray.
+  // Re-use value and target_map registers, as they have been saved on the
+  // stack.
+  Register array_size = value;
+  Register allocate_scratch = target_map;
+  __ li(array_size, Operand(FixedDoubleArray::kHeaderSize));
+  __ SmiToPtrArrayOffset(r0, length);
+  __ add(array_size, array_size, r0);
+  __ Allocate(array_size, array, allocate_scratch, scratch, &gc_required,
+              NO_ALLOCATION_FLAGS);
+  // array: destination FixedArray, not tagged as heap object
+  // Set destination FixedDoubleArray's length and map.
+  __ LoadRoot(scratch, Heap::kFixedArrayMapRootIndex);
+  __ StoreP(length, MemOperand(array, FixedDoubleArray::kLengthOffset));
+  __ StoreP(scratch, MemOperand(array, HeapObject::kMapOffset));
+  __ addi(array, array, Operand(kHeapObjectTag));
+
+  // Prepare for conversion loop.
+  Register src_elements = elements;
+  Register dst_elements = target_map;
+  Register dst_end = length;
+  Register heap_number_map = scratch;
+  __ addi(src_elements, elements,
+          Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+  __ SmiToPtrArrayOffset(length, length);
+  __ LoadRoot(r10, Heap::kTheHoleValueRootIndex);
+
+  Label initialization_loop, loop_done;
+  __ ShiftRightImm(r0, length, Operand(kPointerSizeLog2), SetRC);
+  __ beq(&loop_done, cr0);
+
+  // Allocating heap numbers in the loop below can fail and cause a jump to
+  // gc_required. We can't leave a partly initialized FixedArray behind,
+  // so pessimistically fill it with holes now.
+  __ mtctr(r0);
+  __ addi(dst_elements, array,
+          Operand(FixedArray::kHeaderSize - kHeapObjectTag - kPointerSize));
+  __ bind(&initialization_loop);
+  __ StorePU(r10, MemOperand(dst_elements, kPointerSize));
+  __ bdnz(&initialization_loop);
+
+  __ addi(dst_elements, array,
+          Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ add(dst_end, dst_elements, length);
+  __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
+  // Using offsetted addresses in src_elements to fully take advantage of
+  // post-indexing.
+  // dst_elements: begin of destination FixedArray element fields, not tagged
+  // src_elements: begin of source FixedDoubleArray element fields,
+  //               not tagged, +4
+  // dst_end: end of destination FixedArray, not tagged
+  // array: destination FixedArray
+  // r10: the-hole pointer
+  // heap_number_map: heap number map
+  __ b(&loop);
+
+  // Call into runtime if GC is required.
+  __ bind(&gc_required);
+  __ Pop(target_map, receiver, key, value);
+  __ b(fail);
+
+  // Replace the-hole NaN with the-hole pointer.
+  __ bind(&convert_hole);
+  __ StoreP(r10, MemOperand(dst_elements));
+  __ addi(dst_elements, dst_elements, Operand(kPointerSize));
+  __ cmpl(dst_elements, dst_end);
+  __ bge(&loop_done);
+
+  __ bind(&loop);
+  Register upper_bits = key;
+  __ lwz(upper_bits, MemOperand(src_elements, Register::kExponentOffset));
+  __ addi(src_elements, src_elements, Operand(kDoubleSize));
+  // upper_bits: current element's upper 32 bit
+  // src_elements: address of next element's upper 32 bit
+  __ Cmpi(upper_bits, Operand(kHoleNanUpper32), r0);
+  __ beq(&convert_hole);
+
+  // Non-hole double, copy value into a heap number.
+  Register heap_number = receiver;
+  Register scratch2 = value;
+  __ AllocateHeapNumber(heap_number, scratch2, r11, heap_number_map,
+                        &gc_required);
+  // heap_number: new heap number
+#if V8_TARGET_ARCH_PPC64
+  __ ld(scratch2, MemOperand(src_elements, -kDoubleSize));
+  // subtract tag for std
+  __ addi(upper_bits, heap_number, Operand(-kHeapObjectTag));
+  __ std(scratch2, MemOperand(upper_bits, HeapNumber::kValueOffset));
+#else
+  __ lwz(scratch2,
+         MemOperand(src_elements, Register::kMantissaOffset - kDoubleSize));
+  __ lwz(upper_bits,
+         MemOperand(src_elements, Register::kExponentOffset - kDoubleSize));
+  __ stw(scratch2, FieldMemOperand(heap_number, HeapNumber::kMantissaOffset));
+  __ stw(upper_bits, FieldMemOperand(heap_number, HeapNumber::kExponentOffset));
+#endif
+  __ mr(scratch2, dst_elements);
+  __ StoreP(heap_number, MemOperand(dst_elements));
+  __ addi(dst_elements, dst_elements, Operand(kPointerSize));
+  __ RecordWrite(array, scratch2, heap_number, kLRHasNotBeenSaved,
+                 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+  __ b(&entry);
+
+  // Replace the-hole NaN with the-hole pointer.
+  __ bind(&convert_hole);
+  __ StoreP(r10, MemOperand(dst_elements));
+  __ addi(dst_elements, dst_elements, Operand(kPointerSize));
+
+  __ bind(&entry);
+  __ cmpl(dst_elements, dst_end);
+  __ blt(&loop);
+  __ bind(&loop_done);
+
+  __ Pop(target_map, receiver, key, value);
+  // Replace receiver's backing store with newly created and filled FixedArray.
+  __ StoreP(array, FieldMemOperand(receiver, JSObject::kElementsOffset), r0);
+  __ RecordWriteField(receiver, JSObject::kElementsOffset, array, scratch,
+                      kLRHasNotBeenSaved, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
+                      OMIT_SMI_CHECK);
+
+  __ bind(&only_change_map);
+  // Update receiver's map.
+  __ StoreP(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset), r0);
+  __ RecordWriteField(receiver, HeapObject::kMapOffset, target_map, scratch,
+                      kLRHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
+                      OMIT_SMI_CHECK);
+}
+
+
+// assume ip can be used as a scratch register below
+void StringCharLoadGenerator::Generate(MacroAssembler* masm, Register string,
+                                       Register index, Register result,
+                                       Label* call_runtime) {
+  // Fetch the instance type of the receiver into result register.
+  __ LoadP(result, FieldMemOperand(string, HeapObject::kMapOffset));
+  __ lbz(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
+
+  // We need special handling for indirect strings.
+  Label check_sequential;
+  __ andi(r0, result, Operand(kIsIndirectStringMask));
+  __ beq(&check_sequential, cr0);
+
+  // Dispatch on the indirect string shape: slice or cons.
+  Label cons_string;
+  __ mov(ip, Operand(kSlicedNotConsMask));
+  __ and_(r0, result, ip, SetRC);
+  __ beq(&cons_string, cr0);
+
+  // Handle slices.
+  Label indirect_string_loaded;
+  __ LoadP(result, FieldMemOperand(string, SlicedString::kOffsetOffset));
+  __ LoadP(string, FieldMemOperand(string, SlicedString::kParentOffset));
+  __ SmiUntag(ip, result);
+  __ add(index, index, ip);
+  __ b(&indirect_string_loaded);
+
+  // Handle cons strings.
+  // Check whether the right hand side is the empty string (i.e. if
+  // this is really a flat string in a cons string). If that is not
+  // the case we would rather go to the runtime system now to flatten
+  // the string.
+  __ bind(&cons_string);
+  __ LoadP(result, FieldMemOperand(string, ConsString::kSecondOffset));
+  __ CompareRoot(result, Heap::kempty_stringRootIndex);
+  __ bne(call_runtime);
+  // Get the first of the two strings and load its instance type.
+  __ LoadP(string, FieldMemOperand(string, ConsString::kFirstOffset));
+
+  __ bind(&indirect_string_loaded);
+  __ LoadP(result, FieldMemOperand(string, HeapObject::kMapOffset));
+  __ lbz(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
+
+  // Distinguish sequential and external strings. Only these two string
+  // representations can reach here (slices and flat cons strings have been
+  // reduced to the underlying sequential or external string).
+  Label external_string, check_encoding;
+  __ bind(&check_sequential);
+  STATIC_ASSERT(kSeqStringTag == 0);
+  __ andi(r0, result, Operand(kStringRepresentationMask));
+  __ bne(&external_string, cr0);
+
+  // Prepare sequential strings
+  STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
+  __ addi(string, string,
+          Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
+  __ b(&check_encoding);
+
+  // Handle external strings.
+  __ bind(&external_string);
+  if (FLAG_debug_code) {
+    // Assert that we do not have a cons or slice (indirect strings) here.
+    // Sequential strings have already been ruled out.
+    __ andi(r0, result, Operand(kIsIndirectStringMask));
+    __ Assert(eq, kExternalStringExpectedButNotFound, cr0);
+  }
+  // Rule out short external strings.
+  STATIC_ASSERT(kShortExternalStringTag != 0);
+  __ andi(r0, result, Operand(kShortExternalStringMask));
+  __ bne(call_runtime, cr0);
+  __ LoadP(string,
+           FieldMemOperand(string, ExternalString::kResourceDataOffset));
+
+  Label one_byte, done;
+  __ bind(&check_encoding);
+  STATIC_ASSERT(kTwoByteStringTag == 0);
+  __ andi(r0, result, Operand(kStringEncodingMask));
+  __ bne(&one_byte, cr0);
+  // Two-byte string.
+  __ ShiftLeftImm(result, index, Operand(1));
+  __ lhzx(result, MemOperand(string, result));
+  __ b(&done);
+  __ bind(&one_byte);
+  // One-byte string.
+  __ lbzx(result, MemOperand(string, index));
+  __ bind(&done);
+}
+
+
+static MemOperand ExpConstant(int index, Register base) {
+  return MemOperand(base, index * kDoubleSize);
+}
+
+
+void MathExpGenerator::EmitMathExp(MacroAssembler* masm, DoubleRegister input,
+                                   DoubleRegister result,
+                                   DoubleRegister double_scratch1,
+                                   DoubleRegister double_scratch2,
+                                   Register temp1, Register temp2,
+                                   Register temp3) {
+  DCHECK(!input.is(result));
+  DCHECK(!input.is(double_scratch1));
+  DCHECK(!input.is(double_scratch2));
+  DCHECK(!result.is(double_scratch1));
+  DCHECK(!result.is(double_scratch2));
+  DCHECK(!double_scratch1.is(double_scratch2));
+  DCHECK(!temp1.is(temp2));
+  DCHECK(!temp1.is(temp3));
+  DCHECK(!temp2.is(temp3));
+  DCHECK(ExternalReference::math_exp_constants(0).address() != NULL);
+  DCHECK(!masm->serializer_enabled());  // External references not serializable.
+
+  Label zero, infinity, done;
+
+  __ mov(temp3, Operand(ExternalReference::math_exp_constants(0)));
+
+  __ lfd(double_scratch1, ExpConstant(0, temp3));
+  __ fcmpu(double_scratch1, input);
+  __ fmr(result, input);
+  __ bunordered(&done);
+  __ bge(&zero);
+
+  __ lfd(double_scratch2, ExpConstant(1, temp3));
+  __ fcmpu(input, double_scratch2);
+  __ bge(&infinity);
+
+  __ lfd(double_scratch1, ExpConstant(3, temp3));
+  __ lfd(result, ExpConstant(4, temp3));
+  __ fmul(double_scratch1, double_scratch1, input);
+  __ fadd(double_scratch1, double_scratch1, result);
+  __ MovDoubleLowToInt(temp2, double_scratch1);
+  __ fsub(double_scratch1, double_scratch1, result);
+  __ lfd(result, ExpConstant(6, temp3));
+  __ lfd(double_scratch2, ExpConstant(5, temp3));
+  __ fmul(double_scratch1, double_scratch1, double_scratch2);
+  __ fsub(double_scratch1, double_scratch1, input);
+  __ fsub(result, result, double_scratch1);
+  __ fmul(double_scratch2, double_scratch1, double_scratch1);
+  __ fmul(result, result, double_scratch2);
+  __ lfd(double_scratch2, ExpConstant(7, temp3));
+  __ fmul(result, result, double_scratch2);
+  __ fsub(result, result, double_scratch1);
+  __ lfd(double_scratch2, ExpConstant(8, temp3));
+  __ fadd(result, result, double_scratch2);
+  __ srwi(temp1, temp2, Operand(11));
+  __ andi(temp2, temp2, Operand(0x7ff));
+  __ addi(temp1, temp1, Operand(0x3ff));
+
+  // Must not call ExpConstant() after overwriting temp3!
+  __ mov(temp3, Operand(ExternalReference::math_exp_log_table()));
+  __ slwi(temp2, temp2, Operand(3));
+#if V8_TARGET_ARCH_PPC64
+  __ ldx(temp2, MemOperand(temp3, temp2));
+  __ sldi(temp1, temp1, Operand(52));
+  __ orx(temp2, temp1, temp2);
+  __ MovInt64ToDouble(double_scratch1, temp2);
+#else
+  __ add(ip, temp3, temp2);
+  __ lwz(temp3, MemOperand(ip, Register::kExponentOffset));
+  __ lwz(temp2, MemOperand(ip, Register::kMantissaOffset));
+  __ slwi(temp1, temp1, Operand(20));
+  __ orx(temp3, temp1, temp3);
+  __ MovInt64ToDouble(double_scratch1, temp3, temp2);
+#endif
+
+  __ fmul(result, result, double_scratch1);
+  __ b(&done);
+
+  __ bind(&zero);
+  __ fmr(result, kDoubleRegZero);
+  __ b(&done);
+
+  __ bind(&infinity);
+  __ lfd(result, ExpConstant(2, temp3));
+
+  __ bind(&done);
+}
+
+#undef __
+
+CodeAgingHelper::CodeAgingHelper() {
+  DCHECK(young_sequence_.length() == kNoCodeAgeSequenceLength);
+  // Since patcher is a large object, allocate it dynamically when needed,
+  // to avoid overloading the stack in stress conditions.
+  // DONT_FLUSH is used because the CodeAgingHelper is initialized early in
+  // the process, before ARM simulator ICache is setup.
+  SmartPointer<CodePatcher> patcher(new CodePatcher(
+      young_sequence_.start(), young_sequence_.length() / Assembler::kInstrSize,
+      CodePatcher::DONT_FLUSH));
+  PredictableCodeSizeScope scope(patcher->masm(), young_sequence_.length());
+  patcher->masm()->PushFixedFrame(r4);
+  patcher->masm()->addi(fp, sp,
+                        Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
+  for (int i = 0; i < kNoCodeAgeSequenceNops; i++) {
+    patcher->masm()->nop();
+  }
+}
+
+
+#ifdef DEBUG
+bool CodeAgingHelper::IsOld(byte* candidate) const {
+  return Assembler::IsNop(Assembler::instr_at(candidate));
+}
+#endif
+
+
+bool Code::IsYoungSequence(Isolate* isolate, byte* sequence) {
+  bool result = isolate->code_aging_helper()->IsYoung(sequence);
+  DCHECK(result || isolate->code_aging_helper()->IsOld(sequence));
+  return result;
+}
+
+
+void Code::GetCodeAgeAndParity(Isolate* isolate, byte* sequence, Age* age,
+                               MarkingParity* parity) {
+  if (IsYoungSequence(isolate, sequence)) {
+    *age = kNoAgeCodeAge;
+    *parity = NO_MARKING_PARITY;
+  } else {
+    ConstantPoolArray* constant_pool = NULL;
+    Address target_address = Assembler::target_address_at(
+        sequence + kCodeAgingTargetDelta, constant_pool);
+    Code* stub = GetCodeFromTargetAddress(target_address);
+    GetCodeAgeAndParity(stub, age, parity);
+  }
+}
+
+
+void Code::PatchPlatformCodeAge(Isolate* isolate, byte* sequence, Code::Age age,
+                                MarkingParity parity) {
+  uint32_t young_length = isolate->code_aging_helper()->young_sequence_length();
+  if (age == kNoAgeCodeAge) {
+    isolate->code_aging_helper()->CopyYoungSequenceTo(sequence);
+    CpuFeatures::FlushICache(sequence, young_length);
+  } else {
+    // FIXED_SEQUENCE
+    Code* stub = GetCodeAgeStub(isolate, age, parity);
+    CodePatcher patcher(sequence, young_length / Assembler::kInstrSize);
+    Assembler::BlockTrampolinePoolScope block_trampoline_pool(patcher.masm());
+    intptr_t target = reinterpret_cast<intptr_t>(stub->instruction_start());
+    // Don't use Call -- we need to preserve ip and lr.
+    // GenerateMakeCodeYoungAgainCommon for the stub code.
+    patcher.masm()->nop();  // marker to detect sequence (see IsOld)
+    patcher.masm()->mov(r3, Operand(target));
+    patcher.masm()->Jump(r3);
+    for (int i = 0; i < kCodeAgingSequenceNops; i++) {
+      patcher.masm()->nop();
+    }
+  }
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/codegen-ppc.h b/src/ppc/codegen-ppc.h
new file mode 100644
index 0000000..500bf60
--- /dev/null
+++ b/src/ppc/codegen-ppc.h
@@ -0,0 +1,44 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_PPC_CODEGEN_PPC_H_
+#define V8_PPC_CODEGEN_PPC_H_
+
+#include "src/ast.h"
+#include "src/macro-assembler.h"
+
+namespace v8 {
+namespace internal {
+
+
+enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
+
+
+class StringCharLoadGenerator : public AllStatic {
+ public:
+  // Generates the code for handling different string types and loading the
+  // indexed character into |result|.  We expect |index| as untagged input and
+  // |result| as untagged output.
+  static void Generate(MacroAssembler* masm, Register string, Register index,
+                       Register result, Label* call_runtime);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(StringCharLoadGenerator);
+};
+
+class MathExpGenerator : public AllStatic {
+ public:
+  // Register input isn't modified. All other registers are clobbered.
+  static void EmitMathExp(MacroAssembler* masm, DoubleRegister input,
+                          DoubleRegister result, DoubleRegister double_scratch1,
+                          DoubleRegister double_scratch2, Register temp1,
+                          Register temp2, Register temp3);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MathExpGenerator);
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_PPC_CODEGEN_PPC_H_
diff --git a/src/ppc/constants-ppc.cc b/src/ppc/constants-ppc.cc
new file mode 100644
index 0000000..f32f25a
--- /dev/null
+++ b/src/ppc/constants-ppc.cc
@@ -0,0 +1,91 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/ppc/constants-ppc.h"
+
+
+namespace v8 {
+namespace internal {
+
+// These register names are defined in a way to match the native disassembler
+// formatting. See for example the command "objdump -d <binary file>".
+const char* Registers::names_[kNumRegisters] = {
+    "r0",  "sp",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",  "r8",  "r9",  "r10",
+    "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19", "r20", "r21",
+    "r22", "r23", "r24", "r25", "r26", "r27", "r28", "r29", "r30", "fp"};
+
+
+// List of alias names which can be used when referring to PPC registers.
+const Registers::RegisterAlias Registers::aliases_[] = {{10, "sl"},
+                                                        {11, "r11"},
+                                                        {12, "r12"},
+                                                        {13, "r13"},
+                                                        {14, "r14"},
+                                                        {15, "r15"},
+                                                        {kNoRegister, NULL}};
+
+
+const char* Registers::Name(int reg) {
+  const char* result;
+  if ((0 <= reg) && (reg < kNumRegisters)) {
+    result = names_[reg];
+  } else {
+    result = "noreg";
+  }
+  return result;
+}
+
+
+const char* FPRegisters::names_[kNumFPRegisters] = {
+    "d0",  "d1",  "d2",  "d3",  "d4",  "d5",  "d6",  "d7",  "d8",  "d9",  "d10",
+    "d11", "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21",
+    "d22", "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31"};
+
+
+const char* FPRegisters::Name(int reg) {
+  DCHECK((0 <= reg) && (reg < kNumFPRegisters));
+  return names_[reg];
+}
+
+
+int FPRegisters::Number(const char* name) {
+  for (int i = 0; i < kNumFPRegisters; i++) {
+    if (strcmp(names_[i], name) == 0) {
+      return i;
+    }
+  }
+
+  // No register with the requested name found.
+  return kNoRegister;
+}
+
+
+int Registers::Number(const char* name) {
+  // Look through the canonical names.
+  for (int i = 0; i < kNumRegisters; i++) {
+    if (strcmp(names_[i], name) == 0) {
+      return i;
+    }
+  }
+
+  // Look through the alias names.
+  int i = 0;
+  while (aliases_[i].reg != kNoRegister) {
+    if (strcmp(aliases_[i].name, name) == 0) {
+      return aliases_[i].reg;
+    }
+    i++;
+  }
+
+  // No register with the requested name found.
+  return kNoRegister;
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/constants-ppc.h b/src/ppc/constants-ppc.h
new file mode 100644
index 0000000..9434b8f
--- /dev/null
+++ b/src/ppc/constants-ppc.h
@@ -0,0 +1,600 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_PPC_CONSTANTS_PPC_H_
+#define V8_PPC_CONSTANTS_PPC_H_
+
+namespace v8 {
+namespace internal {
+
+// Number of registers
+const int kNumRegisters = 32;
+
+// FP support.
+const int kNumFPDoubleRegisters = 32;
+const int kNumFPRegisters = kNumFPDoubleRegisters;
+
+const int kNoRegister = -1;
+
+// sign-extend the least significant 16-bits of value <imm>
+#define SIGN_EXT_IMM16(imm) ((static_cast<int>(imm) << 16) >> 16)
+
+// sign-extend the least significant 26-bits of value <imm>
+#define SIGN_EXT_IMM26(imm) ((static_cast<int>(imm) << 6) >> 6)
+
+// -----------------------------------------------------------------------------
+// Conditions.
+
+// Defines constants and accessor classes to assemble, disassemble and
+// simulate PPC instructions.
+//
+// Section references in the code refer to the "PowerPC Microprocessor
+// Family: The Programmer.s Reference Guide" from 10/95
+// https://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF778525699600741775/$file/prg.pdf
+//
+
+// Constants for specific fields are defined in their respective named enums.
+// General constants are in an anonymous enum in class Instr.
+enum Condition {
+  kNoCondition = -1,
+  eq = 0,         // Equal.
+  ne = 1,         // Not equal.
+  ge = 2,         // Greater or equal.
+  lt = 3,         // Less than.
+  gt = 4,         // Greater than.
+  le = 5,         // Less then or equal
+  unordered = 6,  // Floating-point unordered
+  ordered = 7,
+  overflow = 8,  // Summary overflow
+  nooverflow = 9,
+  al = 10  // Always.
+};
+
+
+inline Condition NegateCondition(Condition cond) {
+  DCHECK(cond != al);
+  return static_cast<Condition>(cond ^ ne);
+}
+
+
+// Commute a condition such that {a cond b == b cond' a}.
+inline Condition CommuteCondition(Condition cond) {
+  switch (cond) {
+    case lt:
+      return gt;
+    case gt:
+      return lt;
+    case ge:
+      return le;
+    case le:
+      return ge;
+    default:
+      return cond;
+  }
+}
+
+// -----------------------------------------------------------------------------
+// Instructions encoding.
+
+// Instr is merely used by the Assembler to distinguish 32bit integers
+// representing instructions from usual 32 bit values.
+// Instruction objects are pointers to 32bit values, and provide methods to
+// access the various ISA fields.
+typedef int32_t Instr;
+
+// Opcodes as defined in section 4.2 table 34 (32bit PowerPC)
+enum Opcode {
+  TWI = 3 << 26,       // Trap Word Immediate
+  MULLI = 7 << 26,     // Multiply Low Immediate
+  SUBFIC = 8 << 26,    // Subtract from Immediate Carrying
+  CMPLI = 10 << 26,    // Compare Logical Immediate
+  CMPI = 11 << 26,     // Compare Immediate
+  ADDIC = 12 << 26,    // Add Immediate Carrying
+  ADDICx = 13 << 26,   // Add Immediate Carrying and Record
+  ADDI = 14 << 26,     // Add Immediate
+  ADDIS = 15 << 26,    // Add Immediate Shifted
+  BCX = 16 << 26,      // Branch Conditional
+  SC = 17 << 26,       // System Call
+  BX = 18 << 26,       // Branch
+  EXT1 = 19 << 26,     // Extended code set 1
+  RLWIMIX = 20 << 26,  // Rotate Left Word Immediate then Mask Insert
+  RLWINMX = 21 << 26,  // Rotate Left Word Immediate then AND with Mask
+  RLWNMX = 23 << 26,   // Rotate Left Word then AND with Mask
+  ORI = 24 << 26,      // OR Immediate
+  ORIS = 25 << 26,     // OR Immediate Shifted
+  XORI = 26 << 26,     // XOR Immediate
+  XORIS = 27 << 26,    // XOR Immediate Shifted
+  ANDIx = 28 << 26,    // AND Immediate
+  ANDISx = 29 << 26,   // AND Immediate Shifted
+  EXT5 = 30 << 26,     // Extended code set 5 - 64bit only
+  EXT2 = 31 << 26,     // Extended code set 2
+  LWZ = 32 << 26,      // Load Word and Zero
+  LWZU = 33 << 26,     // Load Word with Zero Update
+  LBZ = 34 << 26,      // Load Byte and Zero
+  LBZU = 35 << 26,     // Load Byte and Zero with Update
+  STW = 36 << 26,      // Store
+  STWU = 37 << 26,     // Store Word with Update
+  STB = 38 << 26,      // Store Byte
+  STBU = 39 << 26,     // Store Byte with Update
+  LHZ = 40 << 26,      // Load Half and Zero
+  LHZU = 41 << 26,     // Load Half and Zero with Update
+  LHA = 42 << 26,      // Load Half Algebraic
+  LHAU = 43 << 26,     // Load Half Algebraic with Update
+  STH = 44 << 26,      // Store Half
+  STHU = 45 << 26,     // Store Half with Update
+  LMW = 46 << 26,      // Load Multiple Word
+  STMW = 47 << 26,     // Store Multiple Word
+  LFS = 48 << 26,      // Load Floating-Point Single
+  LFSU = 49 << 26,     // Load Floating-Point Single with Update
+  LFD = 50 << 26,      // Load Floating-Point Double
+  LFDU = 51 << 26,     // Load Floating-Point Double with Update
+  STFS = 52 << 26,     // Store Floating-Point Single
+  STFSU = 53 << 26,    // Store Floating-Point Single with Update
+  STFD = 54 << 26,     // Store Floating-Point Double
+  STFDU = 55 << 26,    // Store Floating-Point Double with Update
+  LD = 58 << 26,       // Load Double Word
+  EXT3 = 59 << 26,     // Extended code set 3
+  STD = 62 << 26,      // Store Double Word (optionally with Update)
+  EXT4 = 63 << 26      // Extended code set 4
+};
+
+// Bits 10-1
+enum OpcodeExt1 {
+  MCRF = 0 << 1,      // Move Condition Register Field
+  BCLRX = 16 << 1,    // Branch Conditional Link Register
+  CRNOR = 33 << 1,    // Condition Register NOR)
+  RFI = 50 << 1,      // Return from Interrupt
+  CRANDC = 129 << 1,  // Condition Register AND with Complement
+  ISYNC = 150 << 1,   // Instruction Synchronize
+  CRXOR = 193 << 1,   // Condition Register XOR
+  CRNAND = 225 << 1,  // Condition Register NAND
+  CRAND = 257 << 1,   // Condition Register AND
+  CREQV = 289 << 1,   // Condition Register Equivalent
+  CRORC = 417 << 1,   // Condition Register OR with Complement
+  CROR = 449 << 1,    // Condition Register OR
+  BCCTRX = 528 << 1   // Branch Conditional to Count Register
+};
+
+// Bits 9-1 or 10-1
+enum OpcodeExt2 {
+  CMP = 0 << 1,
+  TW = 4 << 1,
+  SUBFCX = 8 << 1,
+  ADDCX = 10 << 1,
+  MULHWUX = 11 << 1,
+  MFCR = 19 << 1,
+  LWARX = 20 << 1,
+  LDX = 21 << 1,
+  LWZX = 23 << 1,  // load word zero w/ x-form
+  SLWX = 24 << 1,
+  CNTLZWX = 26 << 1,
+  SLDX = 27 << 1,
+  ANDX = 28 << 1,
+  CMPL = 32 << 1,
+  SUBFX = 40 << 1,
+  MFVSRD = 51 << 1,  // Move From VSR Doubleword
+  LDUX = 53 << 1,
+  DCBST = 54 << 1,
+  LWZUX = 55 << 1,  // load word zero w/ update x-form
+  CNTLZDX = 58 << 1,
+  ANDCX = 60 << 1,
+  MULHWX = 75 << 1,
+  DCBF = 86 << 1,
+  LBZX = 87 << 1,  // load byte zero w/ x-form
+  NEGX = 104 << 1,
+  MFVSRWZ = 115 << 1,  // Move From VSR Word And Zero
+  LBZUX = 119 << 1,    // load byte zero w/ update x-form
+  NORX = 124 << 1,
+  SUBFEX = 136 << 1,
+  ADDEX = 138 << 1,
+  STDX = 149 << 1,
+  STWX = 151 << 1,    // store word w/ x-form
+  MTVSRD = 179 << 1,  // Move To VSR Doubleword
+  STDUX = 181 << 1,
+  STWUX = 183 << 1,  // store word w/ update x-form
+                     /*
+    MTCRF
+    MTMSR
+    STWCXx
+    SUBFZEX
+  */
+  ADDZEX = 202 << 1,  // Add to Zero Extended
+                      /*
+    MTSR
+  */
+  MTVSRWA = 211 << 1,  // Move To VSR Word Algebraic
+  STBX = 215 << 1,     // store byte w/ x-form
+  MULLD = 233 << 1,    // Multiply Low Double Word
+  MULLW = 235 << 1,    // Multiply Low Word
+  MTVSRWZ = 243 << 1,  // Move To VSR Word And Zero
+  STBUX = 247 << 1,    // store byte w/ update x-form
+  ADDX = 266 << 1,     // Add
+  LHZX = 279 << 1,     // load half-word zero w/ x-form
+  LHZUX = 311 << 1,    // load half-word zero w/ update x-form
+  LHAX = 343 << 1,     // load half-word algebraic w/ x-form
+  LHAUX = 375 << 1,    // load half-word algebraic w/ update x-form
+  XORX = 316 << 1,     // Exclusive OR
+  MFSPR = 339 << 1,    // Move from Special-Purpose-Register
+  STHX = 407 << 1,     // store half-word w/ x-form
+  STHUX = 439 << 1,    // store half-word w/ update x-form
+  ORX = 444 << 1,      // Or
+  MTSPR = 467 << 1,    // Move to Special-Purpose-Register
+  DIVD = 489 << 1,     // Divide Double Word
+  DIVW = 491 << 1,     // Divide Word
+
+  // Below represent bits 10-1  (any value >= 512)
+  LFSX = 535 << 1,    // load float-single w/ x-form
+  SRWX = 536 << 1,    // Shift Right Word
+  SRDX = 539 << 1,    // Shift Right Double Word
+  LFSUX = 567 << 1,   // load float-single w/ update x-form
+  SYNC = 598 << 1,    // Synchronize
+  LFDX = 599 << 1,    // load float-double w/ x-form
+  LFDUX = 631 << 1,   // load float-double w/ update X-form
+  STFSX = 663 << 1,   // store float-single w/ x-form
+  STFSUX = 695 << 1,  // store float-single w/ update x-form
+  STFDX = 727 << 1,   // store float-double w/ x-form
+  STFDUX = 759 << 1,  // store float-double w/ update x-form
+  SRAW = 792 << 1,    // Shift Right Algebraic Word
+  SRAD = 794 << 1,    // Shift Right Algebraic Double Word
+  SRAWIX = 824 << 1,  // Shift Right Algebraic Word Immediate
+  SRADIX = 413 << 2,  // Shift Right Algebraic Double Word Immediate
+  EXTSH = 922 << 1,   // Extend Sign Halfword
+  EXTSB = 954 << 1,   // Extend Sign Byte
+  ICBI = 982 << 1,    // Instruction Cache Block Invalidate
+  EXTSW = 986 << 1    // Extend Sign Word
+};
+
+// Some use Bits 10-1 and other only 5-1 for the opcode
+enum OpcodeExt4 {
+  // Bits 5-1
+  FDIV = 18 << 1,   // Floating Divide
+  FSUB = 20 << 1,   // Floating Subtract
+  FADD = 21 << 1,   // Floating Add
+  FSQRT = 22 << 1,  // Floating Square Root
+  FSEL = 23 << 1,   // Floating Select
+  FMUL = 25 << 1,   // Floating Multiply
+  FMSUB = 28 << 1,  // Floating Multiply-Subtract
+  FMADD = 29 << 1,  // Floating Multiply-Add
+
+  // Bits 10-1
+  FCMPU = 0 << 1,     // Floating Compare Unordered
+  FRSP = 12 << 1,     // Floating-Point Rounding
+  FCTIW = 14 << 1,    // Floating Convert to Integer Word X-form
+  FCTIWZ = 15 << 1,   // Floating Convert to Integer Word with Round to Zero
+  FNEG = 40 << 1,     // Floating Negate
+  MCRFS = 64 << 1,    // Move to Condition Register from FPSCR
+  FMR = 72 << 1,      // Floating Move Register
+  MTFSFI = 134 << 1,  // Move to FPSCR Field Immediate
+  FABS = 264 << 1,    // Floating Absolute Value
+  FRIM = 488 << 1,    // Floating Round to Integer Minus
+  MFFS = 583 << 1,    // move from FPSCR x-form
+  MTFSF = 711 << 1,   // move to FPSCR fields XFL-form
+  FCFID = 846 << 1,   // Floating convert from integer doubleword
+  FCTID = 814 << 1,   // Floating convert from integer doubleword
+  FCTIDZ = 815 << 1   // Floating convert from integer doubleword
+};
+
+enum OpcodeExt5 {
+  // Bits 4-2
+  RLDICL = 0 << 1,  // Rotate Left Double Word Immediate then Clear Left
+  RLDICR = 2 << 1,  // Rotate Left Double Word Immediate then Clear Right
+  RLDIC = 4 << 1,   // Rotate Left Double Word Immediate then Clear
+  RLDIMI = 6 << 1,  // Rotate Left Double Word Immediate then Mask Insert
+  // Bits 4-1
+  RLDCL = 8 << 1,  // Rotate Left Double Word then Clear Left
+  RLDCR = 9 << 1   // Rotate Left Double Word then Clear Right
+};
+
+// Instruction encoding bits and masks.
+enum {
+  // Instruction encoding bit
+  B1 = 1 << 1,
+  B4 = 1 << 4,
+  B5 = 1 << 5,
+  B7 = 1 << 7,
+  B8 = 1 << 8,
+  B9 = 1 << 9,
+  B12 = 1 << 12,
+  B18 = 1 << 18,
+  B19 = 1 << 19,
+  B20 = 1 << 20,
+  B22 = 1 << 22,
+  B23 = 1 << 23,
+  B24 = 1 << 24,
+  B25 = 1 << 25,
+  B26 = 1 << 26,
+  B27 = 1 << 27,
+  B28 = 1 << 28,
+  B6 = 1 << 6,
+  B10 = 1 << 10,
+  B11 = 1 << 11,
+  B16 = 1 << 16,
+  B17 = 1 << 17,
+  B21 = 1 << 21,
+
+  // Instruction bit masks
+  kCondMask = 0x1F << 21,
+  kOff12Mask = (1 << 12) - 1,
+  kImm24Mask = (1 << 24) - 1,
+  kOff16Mask = (1 << 16) - 1,
+  kImm16Mask = (1 << 16) - 1,
+  kImm26Mask = (1 << 26) - 1,
+  kBOfieldMask = 0x1f << 21,
+  kOpcodeMask = 0x3f << 26,
+  kExt1OpcodeMask = 0x3ff << 1,
+  kExt2OpcodeMask = 0x1f << 1,
+  kExt5OpcodeMask = 0x3 << 2,
+  kBOMask = 0x1f << 21,
+  kBIMask = 0x1F << 16,
+  kBDMask = 0x14 << 2,
+  kAAMask = 0x01 << 1,
+  kLKMask = 0x01,
+  kRCMask = 0x01,
+  kTOMask = 0x1f << 21
+};
+
+// the following is to differentiate different faked opcodes for
+// the BOGUS PPC instruction we invented (when bit 25 is 0) or to mark
+// different stub code (when bit 25 is 1)
+//   - use primary opcode 1 for undefined instruction
+//   - use bit 25 to indicate whether the opcode is for fake-arm
+//     instr or stub-marker
+//   - use the least significant 6-bit to indicate FAKE_OPCODE_T or
+//     MARKER_T
+#define FAKE_OPCODE 1 << 26
+#define MARKER_SUBOPCODE_BIT 25
+#define MARKER_SUBOPCODE 1 << MARKER_SUBOPCODE_BIT
+#define FAKER_SUBOPCODE 0 << MARKER_SUBOPCODE_BIT
+
+enum FAKE_OPCODE_T {
+  fBKPT = 14,
+  fLastFaker  // can't be more than 128 (2^^7)
+};
+#define FAKE_OPCODE_HIGH_BIT 7  // fake opcode has to fall into bit 0~7
+#define F_NEXT_AVAILABLE_STUB_MARKER 369  // must be less than 2^^9 (512)
+#define STUB_MARKER_HIGH_BIT 9  // stub marker has to fall into bit 0~9
+// -----------------------------------------------------------------------------
+// Addressing modes and instruction variants.
+
+// Overflow Exception
+enum OEBit {
+  SetOE = 1 << 10,   // Set overflow exception
+  LeaveOE = 0 << 10  // No overflow exception
+};
+
+// Record bit
+enum RCBit {   // Bit 0
+  SetRC = 1,   // LT,GT,EQ,SO
+  LeaveRC = 0  // None
+};
+
+// Link bit
+enum LKBit {   // Bit 0
+  SetLK = 1,   // Load effective address of next instruction
+  LeaveLK = 0  // No action
+};
+
+enum BOfield {        // Bits 25-21
+  DCBNZF = 0 << 21,   // Decrement CTR; branch if CTR != 0 and condition false
+  DCBEZF = 2 << 21,   // Decrement CTR; branch if CTR == 0 and condition false
+  BF = 4 << 21,       // Branch if condition false
+  DCBNZT = 8 << 21,   // Decrement CTR; branch if CTR != 0 and condition true
+  DCBEZT = 10 << 21,  // Decrement CTR; branch if CTR == 0 and condition true
+  BT = 12 << 21,      // Branch if condition true
+  DCBNZ = 16 << 21,   // Decrement CTR; branch if CTR != 0
+  DCBEZ = 18 << 21,   // Decrement CTR; branch if CTR == 0
+  BA = 20 << 21       // Branch always
+};
+
+#if V8_OS_AIX
+#undef CR_LT
+#undef CR_GT
+#undef CR_EQ
+#undef CR_SO
+#endif
+
+enum CRBit { CR_LT = 0, CR_GT = 1, CR_EQ = 2, CR_SO = 3, CR_FU = 3 };
+
+#define CRWIDTH 4
+
+// -----------------------------------------------------------------------------
+// Supervisor Call (svc) specific support.
+
+// Special Software Interrupt codes when used in the presence of the PPC
+// simulator.
+// svc (formerly swi) provides a 24bit immediate value. Use bits 22:0 for
+// standard SoftwareInterrupCode. Bit 23 is reserved for the stop feature.
+enum SoftwareInterruptCodes {
+  // transition to C code
+  kCallRtRedirected = 0x10,
+  // break point
+  kBreakpoint = 0x821008,  // bits23-0 of 0x7d821008 = twge r2, r2
+  // stop
+  kStopCode = 1 << 23,
+  // info
+  kInfo = 0x9ff808  // bits23-0 of 0x7d9ff808 = twge r31, r31
+};
+const uint32_t kStopCodeMask = kStopCode - 1;
+const uint32_t kMaxStopCode = kStopCode - 1;
+const int32_t kDefaultStopCode = -1;
+
+// FP rounding modes.
+enum FPRoundingMode {
+  RN = 0,  // Round to Nearest.
+  RZ = 1,  // Round towards zero.
+  RP = 2,  // Round towards Plus Infinity.
+  RM = 3,  // Round towards Minus Infinity.
+
+  // Aliases.
+  kRoundToNearest = RN,
+  kRoundToZero = RZ,
+  kRoundToPlusInf = RP,
+  kRoundToMinusInf = RM
+};
+
+const uint32_t kFPRoundingModeMask = 3;
+
+enum CheckForInexactConversion {
+  kCheckForInexactConversion,
+  kDontCheckForInexactConversion
+};
+
+// -----------------------------------------------------------------------------
+// Specific instructions, constants, and masks.
+// These constants are declared in assembler-arm.cc, as they use named registers
+// and other constants.
+
+
+// add(sp, sp, 4) instruction (aka Pop())
+extern const Instr kPopInstruction;
+
+// str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r))
+// register r is not encoded.
+extern const Instr kPushRegPattern;
+
+// ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r))
+// register r is not encoded.
+extern const Instr kPopRegPattern;
+
+// use TWI to indicate redirection call for simulation mode
+const Instr rtCallRedirInstr = TWI;
+
+// -----------------------------------------------------------------------------
+// Instruction abstraction.
+
+// The class Instruction enables access to individual fields defined in the PPC
+// architecture instruction set encoding.
+// Note that the Assembler uses typedef int32_t Instr.
+//
+// Example: Test whether the instruction at ptr does set the condition code
+// bits.
+//
+// bool InstructionSetsConditionCodes(byte* ptr) {
+//   Instruction* instr = Instruction::At(ptr);
+//   int type = instr->TypeValue();
+//   return ((type == 0) || (type == 1)) && instr->HasS();
+// }
+//
+class Instruction {
+ public:
+  enum { kInstrSize = 4, kInstrSizeLog2 = 2, kPCReadOffset = 8 };
+
+// Helper macro to define static accessors.
+// We use the cast to char* trick to bypass the strict anti-aliasing rules.
+#define DECLARE_STATIC_TYPED_ACCESSOR(return_type, Name) \
+  static inline return_type Name(Instr instr) {          \
+    char* temp = reinterpret_cast<char*>(&instr);        \
+    return reinterpret_cast<Instruction*>(temp)->Name(); \
+  }
+
+#define DECLARE_STATIC_ACCESSOR(Name) DECLARE_STATIC_TYPED_ACCESSOR(int, Name)
+
+  // Get the raw instruction bits.
+  inline Instr InstructionBits() const {
+    return *reinterpret_cast<const Instr*>(this);
+  }
+
+  // Set the raw instruction bits to value.
+  inline void SetInstructionBits(Instr value) {
+    *reinterpret_cast<Instr*>(this) = value;
+  }
+
+  // Read one particular bit out of the instruction bits.
+  inline int Bit(int nr) const { return (InstructionBits() >> nr) & 1; }
+
+  // Read a bit field's value out of the instruction bits.
+  inline int Bits(int hi, int lo) const {
+    return (InstructionBits() >> lo) & ((2 << (hi - lo)) - 1);
+  }
+
+  // Read a bit field out of the instruction bits.
+  inline int BitField(int hi, int lo) const {
+    return InstructionBits() & (((2 << (hi - lo)) - 1) << lo);
+  }
+
+  // Static support.
+
+  // Read one particular bit out of the instruction bits.
+  static inline int Bit(Instr instr, int nr) { return (instr >> nr) & 1; }
+
+  // Read the value of a bit field out of the instruction bits.
+  static inline int Bits(Instr instr, int hi, int lo) {
+    return (instr >> lo) & ((2 << (hi - lo)) - 1);
+  }
+
+
+  // Read a bit field out of the instruction bits.
+  static inline int BitField(Instr instr, int hi, int lo) {
+    return instr & (((2 << (hi - lo)) - 1) << lo);
+  }
+
+  inline int RSValue() const { return Bits(25, 21); }
+  inline int RTValue() const { return Bits(25, 21); }
+  inline int RAValue() const { return Bits(20, 16); }
+  DECLARE_STATIC_ACCESSOR(RAValue);
+  inline int RBValue() const { return Bits(15, 11); }
+  DECLARE_STATIC_ACCESSOR(RBValue);
+  inline int RCValue() const { return Bits(10, 6); }
+  DECLARE_STATIC_ACCESSOR(RCValue);
+
+  inline int OpcodeValue() const { return static_cast<Opcode>(Bits(31, 26)); }
+  inline Opcode OpcodeField() const {
+    return static_cast<Opcode>(BitField(24, 21));
+  }
+
+  // Fields used in Software interrupt instructions
+  inline SoftwareInterruptCodes SvcValue() const {
+    return static_cast<SoftwareInterruptCodes>(Bits(23, 0));
+  }
+
+  // Instructions are read of out a code stream. The only way to get a
+  // reference to an instruction is to convert a pointer. There is no way
+  // to allocate or create instances of class Instruction.
+  // Use the At(pc) function to create references to Instruction.
+  static Instruction* At(byte* pc) {
+    return reinterpret_cast<Instruction*>(pc);
+  }
+
+
+ private:
+  // We need to prevent the creation of instances of class Instruction.
+  DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
+};
+
+
+// Helper functions for converting between register numbers and names.
+class Registers {
+ public:
+  // Return the name of the register.
+  static const char* Name(int reg);
+
+  // Lookup the register number for the name provided.
+  static int Number(const char* name);
+
+  struct RegisterAlias {
+    int reg;
+    const char* name;
+  };
+
+ private:
+  static const char* names_[kNumRegisters];
+  static const RegisterAlias aliases_[];
+};
+
+// Helper functions for converting between FP register numbers and names.
+class FPRegisters {
+ public:
+  // Return the name of the register.
+  static const char* Name(int reg);
+
+  // Lookup the register number for the name provided.
+  static int Number(const char* name);
+
+ private:
+  static const char* names_[kNumFPRegisters];
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_PPC_CONSTANTS_PPC_H_
diff --git a/src/ppc/cpu-ppc.cc b/src/ppc/cpu-ppc.cc
new file mode 100644
index 0000000..d42420c
--- /dev/null
+++ b/src/ppc/cpu-ppc.cc
@@ -0,0 +1,63 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// CPU specific code for ppc independent of OS goes here.
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/assembler.h"
+#include "src/macro-assembler.h"
+#include "src/simulator.h"  // for cache flushing.
+
+namespace v8 {
+namespace internal {
+
+void CpuFeatures::FlushICache(void* buffer, size_t size) {
+  // Nothing to do flushing no instructions.
+  if (size == 0) {
+    return;
+  }
+
+#if defined(USE_SIMULATOR)
+  // Not generating PPC instructions for C-code. This means that we are
+  // building an PPC emulator based target.  We should notify the simulator
+  // that the Icache was flushed.
+  // None of this code ends up in the snapshot so there are no issues
+  // around whether or not to generate the code when building snapshots.
+  Simulator::FlushICache(Isolate::Current()->simulator_i_cache(), buffer, size);
+#else
+
+  if (CpuFeatures::IsSupported(INSTR_AND_DATA_CACHE_COHERENCY)) {
+    __asm__ __volatile__(
+        "sync \n"
+        "icbi 0, %0  \n"
+        "isync  \n"
+        : /* no output */
+        : "r"(buffer)
+        : "memory");
+    return;
+  }
+
+  const int kCacheLineSize = CpuFeatures::cache_line_size();
+  intptr_t mask = kCacheLineSize - 1;
+  byte *start =
+      reinterpret_cast<byte *>(reinterpret_cast<intptr_t>(buffer) & ~mask);
+  byte *end = static_cast<byte *>(buffer) + size;
+  for (byte *pointer = start; pointer < end; pointer += kCacheLineSize) {
+    __asm__(
+        "dcbf 0, %0  \n"
+        "sync        \n"
+        "icbi 0, %0  \n"
+        "isync       \n"
+        : /* no output */
+        : "r"(pointer));
+  }
+
+#endif  // USE_SIMULATOR
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/debug-ppc.cc b/src/ppc/debug-ppc.cc
new file mode 100644
index 0000000..8106853
--- /dev/null
+++ b/src/ppc/debug-ppc.cc
@@ -0,0 +1,343 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/codegen.h"
+#include "src/debug.h"
+
+namespace v8 {
+namespace internal {
+
+bool BreakLocationIterator::IsDebugBreakAtReturn() {
+  return Debug::IsDebugBreakAtReturn(rinfo());
+}
+
+
+void BreakLocationIterator::SetDebugBreakAtReturn() {
+  // Patch the code changing the return from JS function sequence from
+  //
+  //   LeaveFrame
+  //   blr
+  //
+  // to a call to the debug break return code.
+  // this uses a FIXED_SEQUENCE to load an address constant
+  //
+  //   mov r0, <address>
+  //   mtlr r0
+  //   blrl
+  //   bkpt
+  //
+  CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions);
+  Assembler::BlockTrampolinePoolScope block_trampoline_pool(patcher.masm());
+  patcher.masm()->mov(
+      v8::internal::r0,
+      Operand(reinterpret_cast<intptr_t>(debug_info_->GetIsolate()
+                                             ->builtins()
+                                             ->Return_DebugBreak()
+                                             ->entry())));
+  patcher.masm()->mtctr(v8::internal::r0);
+  patcher.masm()->bctrl();
+  patcher.masm()->bkpt(0);
+}
+
+
+// Restore the JS frame exit code.
+void BreakLocationIterator::ClearDebugBreakAtReturn() {
+  rinfo()->PatchCode(original_rinfo()->pc(),
+                     Assembler::kJSReturnSequenceInstructions);
+}
+
+
+// A debug break in the frame exit code is identified by the JS frame exit code
+// having been patched with a call instruction.
+bool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) {
+  DCHECK(RelocInfo::IsJSReturn(rinfo->rmode()));
+  return rinfo->IsPatchedReturnSequence();
+}
+
+
+bool BreakLocationIterator::IsDebugBreakAtSlot() {
+  DCHECK(IsDebugBreakSlot());
+  // Check whether the debug break slot instructions have been patched.
+  return rinfo()->IsPatchedDebugBreakSlotSequence();
+}
+
+
+void BreakLocationIterator::SetDebugBreakAtSlot() {
+  DCHECK(IsDebugBreakSlot());
+  // Patch the code changing the debug break slot code from
+  //
+  //   ori r3, r3, 0
+  //   ori r3, r3, 0
+  //   ori r3, r3, 0
+  //   ori r3, r3, 0
+  //   ori r3, r3, 0
+  //
+  // to a call to the debug break code, using a FIXED_SEQUENCE.
+  //
+  //   mov r0, <address>
+  //   mtlr r0
+  //   blrl
+  //
+  CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions);
+  Assembler::BlockTrampolinePoolScope block_trampoline_pool(patcher.masm());
+  patcher.masm()->mov(
+      v8::internal::r0,
+      Operand(reinterpret_cast<intptr_t>(
+          debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry())));
+  patcher.masm()->mtctr(v8::internal::r0);
+  patcher.masm()->bctrl();
+}
+
+
+void BreakLocationIterator::ClearDebugBreakAtSlot() {
+  DCHECK(IsDebugBreakSlot());
+  rinfo()->PatchCode(original_rinfo()->pc(),
+                     Assembler::kDebugBreakSlotInstructions);
+}
+
+
+#define __ ACCESS_MASM(masm)
+
+
+static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
+                                          RegList object_regs,
+                                          RegList non_object_regs) {
+  {
+    FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
+
+    // Load padding words on stack.
+    __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingValue));
+    for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) {
+      __ push(ip);
+    }
+    __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingInitialSize));
+    __ push(ip);
+
+    // 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.
+    DCHECK((object_regs & ~kJSCallerSaved) == 0);
+    DCHECK((non_object_regs & ~kJSCallerSaved) == 0);
+    DCHECK((object_regs & non_object_regs) == 0);
+    if ((object_regs | non_object_regs) != 0) {
+      for (int i = 0; i < kNumJSCallerSaved; i++) {
+        int r = JSCallerSavedCode(i);
+        Register reg = {r};
+        if ((non_object_regs & (1 << r)) != 0) {
+          if (FLAG_debug_code) {
+            __ TestUnsignedSmiCandidate(reg, r0);
+            __ Assert(eq, kUnableToEncodeValueAsSmi, cr0);
+          }
+          __ SmiTag(reg);
+        }
+      }
+      __ MultiPush(object_regs | non_object_regs);
+    }
+
+#ifdef DEBUG
+    __ RecordComment("// Calling from debug break to runtime - come in - over");
+#endif
+    __ mov(r3, Operand::Zero());  // no arguments
+    __ mov(r4, Operand(ExternalReference::debug_break(masm->isolate())));
+
+    CEntryStub ceb(masm->isolate(), 1);
+    __ CallStub(&ceb);
+
+    // Restore the register values from the expression stack.
+    if ((object_regs | non_object_regs) != 0) {
+      __ MultiPop(object_regs | non_object_regs);
+      for (int i = 0; i < kNumJSCallerSaved; i++) {
+        int r = JSCallerSavedCode(i);
+        Register reg = {r};
+        if ((non_object_regs & (1 << r)) != 0) {
+          __ SmiUntag(reg);
+        }
+        if (FLAG_debug_code &&
+            (((object_regs | non_object_regs) & (1 << r)) == 0)) {
+          __ mov(reg, Operand(kDebugZapValue));
+        }
+      }
+    }
+
+    // Don't bother removing padding bytes pushed on the stack
+    // as the frame is going to be restored right away.
+
+    // Leave the internal frame.
+  }
+
+  // Now that the break point has been handled, resume normal execution by
+  // jumping to the target address intended by the caller and that was
+  // overwritten by the address of DebugBreakXXX.
+  ExternalReference after_break_target =
+      ExternalReference::debug_after_break_target_address(masm->isolate());
+  __ mov(ip, Operand(after_break_target));
+  __ LoadP(ip, MemOperand(ip));
+  __ JumpToJSEntry(ip);
+}
+
+
+void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
+  // Register state for CallICStub
+  // ----------- S t a t e -------------
+  //  -- r4 : function
+  //  -- r6 : slot in feedback array (smi)
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, r4.bit() | r6.bit(), 0);
+}
+
+
+void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
+  // Calling convention for IC load (from ic-ppc.cc).
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register name = LoadDescriptor::NameRegister();
+  RegList regs = receiver.bit() | name.bit();
+  if (FLAG_vector_ics) {
+    regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit();
+  }
+  Generate_DebugBreakCallHelper(masm, regs, 0);
+}
+
+
+void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
+  // Calling convention for IC store (from ic-ppc.cc).
+  Register receiver = StoreDescriptor::ReceiverRegister();
+  Register name = StoreDescriptor::NameRegister();
+  Register value = StoreDescriptor::ValueRegister();
+  Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit() | value.bit(),
+                                0);
+}
+
+
+void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
+  // Calling convention for keyed IC load (from ic-ppc.cc).
+  GenerateLoadICDebugBreak(masm);
+}
+
+
+void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
+  // Calling convention for IC keyed store call (from ic-ppc.cc).
+  Register receiver = StoreDescriptor::ReceiverRegister();
+  Register name = StoreDescriptor::NameRegister();
+  Register value = StoreDescriptor::ValueRegister();
+  Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit() | value.bit(),
+                                0);
+}
+
+
+void DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
+  // Register state for CompareNil IC
+  // ----------- S t a t e -------------
+  //  -- r3    : value
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, r3.bit(), 0);
+}
+
+
+void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
+  // In places other than IC call sites it is expected that r3 is TOS which
+  // is an object - this is not generally the case so this should be used with
+  // care.
+  Generate_DebugBreakCallHelper(masm, r3.bit(), 0);
+}
+
+
+void DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
+  // Register state for CallFunctionStub (from code-stubs-ppc.cc).
+  // ----------- S t a t e -------------
+  //  -- r4 : function
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, r4.bit(), 0);
+}
+
+
+void DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
+  // Calling convention for CallConstructStub (from code-stubs-ppc.cc)
+  // ----------- S t a t e -------------
+  //  -- r3     : number of arguments (not smi)
+  //  -- r4     : constructor function
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, r4.bit(), r3.bit());
+}
+
+
+void DebugCodegen::GenerateCallConstructStubRecordDebugBreak(
+    MacroAssembler* masm) {
+  // Calling convention for CallConstructStub (from code-stubs-ppc.cc)
+  // ----------- S t a t e -------------
+  //  -- r3     : number of arguments (not smi)
+  //  -- r4     : constructor function
+  //  -- r5     : feedback array
+  //  -- r6     : feedback slot (smi)
+  // -----------------------------------
+  Generate_DebugBreakCallHelper(masm, r4.bit() | r5.bit() | r6.bit(), r3.bit());
+}
+
+
+void DebugCodegen::GenerateSlot(MacroAssembler* masm) {
+  // Generate enough nop's to make space for a call instruction. Avoid emitting
+  // the trampoline pool in the debug break slot code.
+  Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm);
+  Label check_codesize;
+  __ bind(&check_codesize);
+  __ RecordDebugBreakSlot();
+  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
+    __ nop(MacroAssembler::DEBUG_BREAK_NOP);
+  }
+  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
+            masm->InstructionsGeneratedSince(&check_codesize));
+}
+
+
+void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) {
+  // In the places where a debug break slot is inserted no registers can contain
+  // object pointers.
+  Generate_DebugBreakCallHelper(masm, 0, 0);
+}
+
+
+void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
+  __ Ret();
+}
+
+
+void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
+  ExternalReference restarter_frame_function_slot =
+      ExternalReference::debug_restarter_frame_function_pointer_address(
+          masm->isolate());
+  __ mov(ip, Operand(restarter_frame_function_slot));
+  __ li(r4, Operand::Zero());
+  __ StoreP(r4, MemOperand(ip, 0));
+
+  // Load the function pointer off of our current stack frame.
+  __ LoadP(r4, MemOperand(fp, StandardFrameConstants::kConstantPoolOffset -
+                                  kPointerSize));
+
+  // Pop return address, frame and constant pool pointer (if
+  // FLAG_enable_ool_constant_pool).
+  __ LeaveFrame(StackFrame::INTERNAL);
+
+  // Load context from the function.
+  __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
+
+  // Get function code.
+  __ LoadP(ip, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
+  __ LoadP(ip, FieldMemOperand(ip, SharedFunctionInfo::kCodeOffset));
+  __ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
+
+  // Re-run JSFunction, r4 is function, cp is context.
+  __ Jump(ip);
+}
+
+
+const bool LiveEdit::kFrameDropperSupported = true;
+
+#undef __
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/deoptimizer-ppc.cc b/src/ppc/deoptimizer-ppc.cc
new file mode 100644
index 0000000..58e9e93
--- /dev/null
+++ b/src/ppc/deoptimizer-ppc.cc
@@ -0,0 +1,359 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/codegen.h"
+#include "src/deoptimizer.h"
+#include "src/full-codegen.h"
+#include "src/safepoint-table.h"
+
+namespace v8 {
+namespace internal {
+
+const int Deoptimizer::table_entry_size_ = 8;
+
+
+int Deoptimizer::patch_size() {
+#if V8_TARGET_ARCH_PPC64
+  const int kCallInstructionSizeInWords = 7;
+#else
+  const int kCallInstructionSizeInWords = 4;
+#endif
+  return kCallInstructionSizeInWords * Assembler::kInstrSize;
+}
+
+
+void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
+  Address code_start_address = code->instruction_start();
+
+  // Invalidate the relocation information, as it will become invalid by the
+  // code patching below, and is not needed any more.
+  code->InvalidateRelocation();
+
+  if (FLAG_zap_code_space) {
+    // Fail hard and early if we enter this code object again.
+    byte* pointer = code->FindCodeAgeSequence();
+    if (pointer != NULL) {
+      pointer += kNoCodeAgeSequenceLength;
+    } else {
+      pointer = code->instruction_start();
+    }
+    CodePatcher patcher(pointer, 1);
+    patcher.masm()->bkpt(0);
+
+    DeoptimizationInputData* data =
+        DeoptimizationInputData::cast(code->deoptimization_data());
+    int osr_offset = data->OsrPcOffset()->value();
+    if (osr_offset > 0) {
+      CodePatcher osr_patcher(code->instruction_start() + osr_offset, 1);
+      osr_patcher.masm()->bkpt(0);
+    }
+  }
+
+  DeoptimizationInputData* deopt_data =
+      DeoptimizationInputData::cast(code->deoptimization_data());
+#ifdef DEBUG
+  Address prev_call_address = NULL;
+#endif
+  // For each LLazyBailout instruction insert a call to the corresponding
+  // deoptimization entry.
+  for (int i = 0; i < deopt_data->DeoptCount(); i++) {
+    if (deopt_data->Pc(i)->value() == -1) continue;
+    Address call_address = code_start_address + deopt_data->Pc(i)->value();
+    Address deopt_entry = GetDeoptimizationEntry(isolate, i, LAZY);
+    // We need calls to have a predictable size in the unoptimized code, but
+    // this is optimized code, so we don't have to have a predictable size.
+    int call_size_in_bytes = MacroAssembler::CallSizeNotPredictableCodeSize(
+        deopt_entry, kRelocInfo_NONEPTR);
+    int call_size_in_words = call_size_in_bytes / Assembler::kInstrSize;
+    DCHECK(call_size_in_bytes % Assembler::kInstrSize == 0);
+    DCHECK(call_size_in_bytes <= patch_size());
+    CodePatcher patcher(call_address, call_size_in_words);
+    patcher.masm()->Call(deopt_entry, kRelocInfo_NONEPTR);
+    DCHECK(prev_call_address == NULL ||
+           call_address >= prev_call_address + patch_size());
+    DCHECK(call_address + patch_size() <= code->instruction_end());
+#ifdef DEBUG
+    prev_call_address = call_address;
+#endif
+  }
+}
+
+
+void Deoptimizer::FillInputFrame(Address tos, JavaScriptFrame* frame) {
+  // Set the register values. The values are not important as there are no
+  // callee saved registers in JavaScript frames, so all registers are
+  // spilled. Registers fp and sp are set to the correct values though.
+
+  for (int i = 0; i < Register::kNumRegisters; i++) {
+    input_->SetRegister(i, i * 4);
+  }
+  input_->SetRegister(sp.code(), reinterpret_cast<intptr_t>(frame->sp()));
+  input_->SetRegister(fp.code(), reinterpret_cast<intptr_t>(frame->fp()));
+  for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); i++) {
+    input_->SetDoubleRegister(i, 0.0);
+  }
+
+  // Fill the frame content from the actual data on the frame.
+  for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) {
+    input_->SetFrameSlot(
+        i, reinterpret_cast<intptr_t>(Memory::Address_at(tos + i)));
+  }
+}
+
+
+void Deoptimizer::SetPlatformCompiledStubRegisters(
+    FrameDescription* output_frame, CodeStubDescriptor* descriptor) {
+  ApiFunction function(descriptor->deoptimization_handler());
+  ExternalReference xref(&function, ExternalReference::BUILTIN_CALL, isolate_);
+  intptr_t handler = reinterpret_cast<intptr_t>(xref.address());
+  int params = descriptor->GetHandlerParameterCount();
+  output_frame->SetRegister(r3.code(), params);
+  output_frame->SetRegister(r4.code(), handler);
+}
+
+
+void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) {
+  for (int i = 0; i < DoubleRegister::kMaxNumRegisters; ++i) {
+    double double_value = input_->GetDoubleRegister(i);
+    output_frame->SetDoubleRegister(i, double_value);
+  }
+}
+
+
+bool Deoptimizer::HasAlignmentPadding(JSFunction* function) {
+  // There is no dynamic alignment padding on PPC in the input frame.
+  return false;
+}
+
+
+#define __ masm()->
+
+// This code tries to be close to ia32 code so that any changes can be
+// easily ported.
+void Deoptimizer::EntryGenerator::Generate() {
+  GeneratePrologue();
+
+  // Unlike on ARM we don't save all the registers, just the useful ones.
+  // For the rest, there are gaps on the stack, so the offsets remain the same.
+  const int kNumberOfRegisters = Register::kNumRegisters;
+
+  RegList restored_regs = kJSCallerSaved | kCalleeSaved;
+  RegList saved_regs = restored_regs | sp.bit();
+
+  const int kDoubleRegsSize =
+      kDoubleSize * DoubleRegister::kMaxNumAllocatableRegisters;
+
+  // Save all FPU registers before messing with them.
+  __ subi(sp, sp, Operand(kDoubleRegsSize));
+  for (int i = 0; i < DoubleRegister::kMaxNumAllocatableRegisters; ++i) {
+    DoubleRegister fpu_reg = DoubleRegister::FromAllocationIndex(i);
+    int offset = i * kDoubleSize;
+    __ stfd(fpu_reg, MemOperand(sp, offset));
+  }
+
+  // Push saved_regs (needed to populate FrameDescription::registers_).
+  // Leave gaps for other registers.
+  __ subi(sp, sp, Operand(kNumberOfRegisters * kPointerSize));
+  for (int16_t i = kNumberOfRegisters - 1; i >= 0; i--) {
+    if ((saved_regs & (1 << i)) != 0) {
+      __ StoreP(ToRegister(i), MemOperand(sp, kPointerSize * i));
+    }
+  }
+
+  const int kSavedRegistersAreaSize =
+      (kNumberOfRegisters * kPointerSize) + kDoubleRegsSize;
+
+  // Get the bailout id from the stack.
+  __ LoadP(r5, MemOperand(sp, kSavedRegistersAreaSize));
+
+  // Get the address of the location in the code object (r6) (return
+  // address for lazy deoptimization) and compute the fp-to-sp delta in
+  // register r7.
+  __ mflr(r6);
+  // Correct one word for bailout id.
+  __ addi(r7, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize)));
+  __ sub(r7, fp, r7);
+
+  // Allocate a new deoptimizer object.
+  // Pass six arguments in r3 to r8.
+  __ PrepareCallCFunction(6, r8);
+  __ LoadP(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ li(r4, Operand(type()));  // bailout type,
+  // r5: bailout id already loaded.
+  // r6: code address or 0 already loaded.
+  // r7: Fp-to-sp delta.
+  __ mov(r8, Operand(ExternalReference::isolate_address(isolate())));
+  // Call Deoptimizer::New().
+  {
+    AllowExternalCallThatCantCauseGC scope(masm());
+    __ CallCFunction(ExternalReference::new_deoptimizer_function(isolate()), 6);
+  }
+
+  // Preserve "deoptimizer" object in register r3 and get the input
+  // frame descriptor pointer to r4 (deoptimizer->input_);
+  __ LoadP(r4, MemOperand(r3, Deoptimizer::input_offset()));
+
+  // Copy core registers into FrameDescription::registers_[kNumRegisters].
+  DCHECK(Register::kNumRegisters == kNumberOfRegisters);
+  for (int i = 0; i < kNumberOfRegisters; i++) {
+    int offset = (i * kPointerSize) + FrameDescription::registers_offset();
+    __ LoadP(r5, MemOperand(sp, i * kPointerSize));
+    __ StoreP(r5, MemOperand(r4, offset));
+  }
+
+  int double_regs_offset = FrameDescription::double_registers_offset();
+  // Copy VFP registers to
+  // double_registers_[DoubleRegister::kNumAllocatableRegisters]
+  for (int i = 0; i < DoubleRegister::NumAllocatableRegisters(); ++i) {
+    int dst_offset = i * kDoubleSize + double_regs_offset;
+    int src_offset = i * kDoubleSize + kNumberOfRegisters * kPointerSize;
+    __ lfd(d0, MemOperand(sp, src_offset));
+    __ stfd(d0, MemOperand(r4, dst_offset));
+  }
+
+  // Remove the bailout id and the saved registers from the stack.
+  __ addi(sp, sp, Operand(kSavedRegistersAreaSize + (1 * kPointerSize)));
+
+  // Compute a pointer to the unwinding limit in register r5; that is
+  // the first stack slot not part of the input frame.
+  __ LoadP(r5, MemOperand(r4, FrameDescription::frame_size_offset()));
+  __ add(r5, r5, sp);
+
+  // Unwind the stack down to - but not including - the unwinding
+  // limit and copy the contents of the activation frame to the input
+  // frame description.
+  __ addi(r6, r4, Operand(FrameDescription::frame_content_offset()));
+  Label pop_loop;
+  Label pop_loop_header;
+  __ b(&pop_loop_header);
+  __ bind(&pop_loop);
+  __ pop(r7);
+  __ StoreP(r7, MemOperand(r6, 0));
+  __ addi(r6, r6, Operand(kPointerSize));
+  __ bind(&pop_loop_header);
+  __ cmp(r5, sp);
+  __ bne(&pop_loop);
+
+  // Compute the output frame in the deoptimizer.
+  __ push(r3);  // Preserve deoptimizer object across call.
+  // r3: deoptimizer object; r4: scratch.
+  __ PrepareCallCFunction(1, r4);
+  // Call Deoptimizer::ComputeOutputFrames().
+  {
+    AllowExternalCallThatCantCauseGC scope(masm());
+    __ CallCFunction(
+        ExternalReference::compute_output_frames_function(isolate()), 1);
+  }
+  __ pop(r3);  // Restore deoptimizer object (class Deoptimizer).
+
+  // Replace the current (input) frame with the output frames.
+  Label outer_push_loop, inner_push_loop, outer_loop_header, inner_loop_header;
+  // Outer loop state: r7 = current "FrameDescription** output_",
+  // r4 = one past the last FrameDescription**.
+  __ lwz(r4, MemOperand(r3, Deoptimizer::output_count_offset()));
+  __ LoadP(r7, MemOperand(r3, Deoptimizer::output_offset()));  // r7 is output_.
+  __ ShiftLeftImm(r4, r4, Operand(kPointerSizeLog2));
+  __ add(r4, r7, r4);
+  __ b(&outer_loop_header);
+
+  __ bind(&outer_push_loop);
+  // Inner loop state: r5 = current FrameDescription*, r6 = loop index.
+  __ LoadP(r5, MemOperand(r7, 0));  // output_[ix]
+  __ LoadP(r6, MemOperand(r5, FrameDescription::frame_size_offset()));
+  __ b(&inner_loop_header);
+
+  __ bind(&inner_push_loop);
+  __ addi(r6, r6, Operand(-sizeof(intptr_t)));
+  __ add(r9, r5, r6);
+  __ LoadP(r9, MemOperand(r9, FrameDescription::frame_content_offset()));
+  __ push(r9);
+
+  __ bind(&inner_loop_header);
+  __ cmpi(r6, Operand::Zero());
+  __ bne(&inner_push_loop);  // test for gt?
+
+  __ addi(r7, r7, Operand(kPointerSize));
+  __ bind(&outer_loop_header);
+  __ cmp(r7, r4);
+  __ blt(&outer_push_loop);
+
+  __ LoadP(r4, MemOperand(r3, Deoptimizer::input_offset()));
+  for (int i = 0; i < DoubleRegister::kMaxNumAllocatableRegisters; ++i) {
+    const DoubleRegister dreg = DoubleRegister::FromAllocationIndex(i);
+    int src_offset = i * kDoubleSize + double_regs_offset;
+    __ lfd(dreg, MemOperand(r4, src_offset));
+  }
+
+  // Push state, pc, and continuation from the last output frame.
+  __ LoadP(r9, MemOperand(r5, FrameDescription::state_offset()));
+  __ push(r9);
+  __ LoadP(r9, MemOperand(r5, FrameDescription::pc_offset()));
+  __ push(r9);
+  __ LoadP(r9, MemOperand(r5, FrameDescription::continuation_offset()));
+  __ push(r9);
+
+  // Restore the registers from the last output frame.
+  DCHECK(!(ip.bit() & restored_regs));
+  __ mr(ip, r5);
+  for (int i = kNumberOfRegisters - 1; i >= 0; i--) {
+    int offset = (i * kPointerSize) + FrameDescription::registers_offset();
+    if ((restored_regs & (1 << i)) != 0) {
+      __ LoadP(ToRegister(i), MemOperand(ip, offset));
+    }
+  }
+
+  __ InitializeRootRegister();
+
+  __ pop(ip);  // get continuation, leave pc on stack
+  __ pop(r0);
+  __ mtlr(r0);
+  __ Jump(ip);
+  __ stop("Unreachable.");
+}
+
+
+void Deoptimizer::TableEntryGenerator::GeneratePrologue() {
+  Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm());
+
+  // Create a sequence of deoptimization entries.
+  // Note that registers are still live when jumping to an entry.
+  Label done;
+  for (int i = 0; i < count(); i++) {
+    int start = masm()->pc_offset();
+    USE(start);
+    __ li(ip, Operand(i));
+    __ b(&done);
+    DCHECK(masm()->pc_offset() - start == table_entry_size_);
+  }
+  __ bind(&done);
+  __ push(ip);
+}
+
+
+void FrameDescription::SetCallerPc(unsigned offset, intptr_t value) {
+  SetFrameSlot(offset, value);
+}
+
+
+void FrameDescription::SetCallerFp(unsigned offset, intptr_t value) {
+  SetFrameSlot(offset, value);
+}
+
+
+void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) {
+#if V8_OOL_CONSTANT_POOL
+  DCHECK(FLAG_enable_ool_constant_pool);
+  SetFrameSlot(offset, value);
+#else
+  // No out-of-line constant pool support.
+  UNREACHABLE();
+#endif
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
diff --git a/src/ppc/disasm-ppc.cc b/src/ppc/disasm-ppc.cc
new file mode 100644
index 0000000..63cec8c
--- /dev/null
+++ b/src/ppc/disasm-ppc.cc
@@ -0,0 +1,1353 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// A Disassembler object is used to disassemble a block of code instruction by
+// instruction. The default implementation of the NameConverter object can be
+// overriden to modify register names or to do symbol lookup on addresses.
+//
+// The example below will disassemble a block of code and print it to stdout.
+//
+//   NameConverter converter;
+//   Disassembler d(converter);
+//   for (byte* pc = begin; pc < end;) {
+//     v8::internal::EmbeddedVector<char, 256> buffer;
+//     byte* prev_pc = pc;
+//     pc += d.InstructionDecode(buffer, pc);
+//     printf("%p    %08x      %s\n",
+//            prev_pc, *reinterpret_cast<int32_t*>(prev_pc), buffer);
+//   }
+//
+// The Disassembler class also has a convenience method to disassemble a block
+// of code into a FILE*, meaning that the above functionality could also be
+// achieved by just calling Disassembler::Disassemble(stdout, begin, end);
+
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/base/platform/platform.h"
+#include "src/disasm.h"
+#include "src/macro-assembler.h"
+#include "src/ppc/constants-ppc.h"
+
+
+namespace v8 {
+namespace internal {
+
+
+//------------------------------------------------------------------------------
+
+// Decoder decodes and disassembles instructions into an output buffer.
+// It uses the converter to convert register names and call destinations into
+// more informative description.
+class Decoder {
+ public:
+  Decoder(const disasm::NameConverter& converter, Vector<char> out_buffer)
+      : converter_(converter), out_buffer_(out_buffer), out_buffer_pos_(0) {
+    out_buffer_[out_buffer_pos_] = '\0';
+  }
+
+  ~Decoder() {}
+
+  // Writes one disassembled instruction into 'buffer' (0-terminated).
+  // Returns the length of the disassembled machine instruction in bytes.
+  int InstructionDecode(byte* instruction);
+
+ private:
+  // Bottleneck functions to print into the out_buffer.
+  void PrintChar(const char ch);
+  void Print(const char* str);
+
+  // Printing of common values.
+  void PrintRegister(int reg);
+  void PrintDRegister(int reg);
+  int FormatFPRegister(Instruction* instr, const char* format);
+  void PrintSoftwareInterrupt(SoftwareInterruptCodes svc);
+
+  // Handle formatting of instructions and their options.
+  int FormatRegister(Instruction* instr, const char* option);
+  int FormatOption(Instruction* instr, const char* option);
+  void Format(Instruction* instr, const char* format);
+  void Unknown(Instruction* instr);
+  void UnknownFormat(Instruction* instr, const char* opcname);
+  void MarkerFormat(Instruction* instr, const char* opcname, int id);
+
+  void DecodeExt1(Instruction* instr);
+  void DecodeExt2(Instruction* instr);
+  void DecodeExt4(Instruction* instr);
+  void DecodeExt5(Instruction* instr);
+
+  const disasm::NameConverter& converter_;
+  Vector<char> out_buffer_;
+  int out_buffer_pos_;
+
+  DISALLOW_COPY_AND_ASSIGN(Decoder);
+};
+
+
+// Support for assertions in the Decoder formatting functions.
+#define STRING_STARTS_WITH(string, compare_string) \
+  (strncmp(string, compare_string, strlen(compare_string)) == 0)
+
+
+// Append the ch to the output buffer.
+void Decoder::PrintChar(const char ch) { out_buffer_[out_buffer_pos_++] = ch; }
+
+
+// Append the str to the output buffer.
+void Decoder::Print(const char* str) {
+  char cur = *str++;
+  while (cur != '\0' && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
+    PrintChar(cur);
+    cur = *str++;
+  }
+  out_buffer_[out_buffer_pos_] = 0;
+}
+
+
+// Print the register name according to the active name converter.
+void Decoder::PrintRegister(int reg) {
+  Print(converter_.NameOfCPURegister(reg));
+}
+
+
+// Print the double FP register name according to the active name converter.
+void Decoder::PrintDRegister(int reg) { Print(FPRegisters::Name(reg)); }
+
+
+// Print SoftwareInterrupt codes. Factoring this out reduces the complexity of
+// the FormatOption method.
+void Decoder::PrintSoftwareInterrupt(SoftwareInterruptCodes svc) {
+  switch (svc) {
+    case kCallRtRedirected:
+      Print("call rt redirected");
+      return;
+    case kBreakpoint:
+      Print("breakpoint");
+      return;
+    default:
+      if (svc >= kStopCode) {
+        out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d - 0x%x",
+                                    svc & kStopCodeMask, svc & kStopCodeMask);
+      } else {
+        out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", svc);
+      }
+      return;
+  }
+}
+
+
+// Handle all register based formatting in this function to reduce the
+// complexity of FormatOption.
+int Decoder::FormatRegister(Instruction* instr, const char* format) {
+  DCHECK(format[0] == 'r');
+
+  if ((format[1] == 't') || (format[1] == 's')) {  // 'rt & 'rs register
+    int reg = instr->RTValue();
+    PrintRegister(reg);
+    return 2;
+  } else if (format[1] == 'a') {  // 'ra: RA register
+    int reg = instr->RAValue();
+    PrintRegister(reg);
+    return 2;
+  } else if (format[1] == 'b') {  // 'rb: RB register
+    int reg = instr->RBValue();
+    PrintRegister(reg);
+    return 2;
+  }
+
+  UNREACHABLE();
+  return -1;
+}
+
+
+// Handle all FP register based formatting in this function to reduce the
+// complexity of FormatOption.
+int Decoder::FormatFPRegister(Instruction* instr, const char* format) {
+  DCHECK(format[0] == 'D');
+
+  int retval = 2;
+  int reg = -1;
+  if (format[1] == 't') {
+    reg = instr->RTValue();
+  } else if (format[1] == 'a') {
+    reg = instr->RAValue();
+  } else if (format[1] == 'b') {
+    reg = instr->RBValue();
+  } else if (format[1] == 'c') {
+    reg = instr->RCValue();
+  } else {
+    UNREACHABLE();
+  }
+
+  PrintDRegister(reg);
+
+  return retval;
+}
+
+
+// FormatOption takes a formatting string and interprets it based on
+// the current instructions. The format string points to the first
+// character of the option string (the option escape has already been
+// consumed by the caller.)  FormatOption returns the number of
+// characters that were consumed from the formatting string.
+int Decoder::FormatOption(Instruction* instr, const char* format) {
+  switch (format[0]) {
+    case 'o': {
+      if (instr->Bit(10) == 1) {
+        Print("o");
+      }
+      return 1;
+    }
+    case '.': {
+      if (instr->Bit(0) == 1) {
+        Print(".");
+      } else {
+        Print(" ");  // ensure consistent spacing
+      }
+      return 1;
+    }
+    case 'r': {
+      return FormatRegister(instr, format);
+    }
+    case 'D': {
+      return FormatFPRegister(instr, format);
+    }
+    case 'i': {  // int16
+      int32_t value = (instr->Bits(15, 0) << 16) >> 16;
+      out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
+      return 5;
+    }
+    case 'u': {  // uint16
+      int32_t value = instr->Bits(15, 0);
+      out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
+      return 6;
+    }
+    case 'l': {
+      // Link (LK) Bit 0
+      if (instr->Bit(0) == 1) {
+        Print("l");
+      }
+      return 1;
+    }
+    case 'a': {
+      // Absolute Address Bit 1
+      if (instr->Bit(1) == 1) {
+        Print("a");
+      }
+      return 1;
+    }
+    case 't': {  // 'target: target of branch instructions
+      // target26 or target16
+      DCHECK(STRING_STARTS_WITH(format, "target"));
+      if ((format[6] == '2') && (format[7] == '6')) {
+        int off = ((instr->Bits(25, 2)) << 8) >> 6;
+        out_buffer_pos_ += SNPrintF(
+            out_buffer_ + out_buffer_pos_, "%+d -> %s", off,
+            converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off));
+        return 8;
+      } else if ((format[6] == '1') && (format[7] == '6')) {
+        int off = ((instr->Bits(15, 2)) << 18) >> 16;
+        out_buffer_pos_ += SNPrintF(
+            out_buffer_ + out_buffer_pos_, "%+d -> %s", off,
+            converter_.NameOfAddress(reinterpret_cast<byte*>(instr) + off));
+        return 8;
+      }
+      case 's': {
+        DCHECK(format[1] == 'h');
+        int32_t value = 0;
+        int32_t opcode = instr->OpcodeValue() << 26;
+        int32_t sh = instr->Bits(15, 11);
+        if (opcode == EXT5 ||
+            (opcode == EXT2 && instr->Bits(10, 2) << 2 == SRADIX)) {
+          // SH Bits 1 and 15-11 (split field)
+          value = (sh | (instr->Bit(1) << 5));
+        } else {
+          // SH Bits 15-11
+          value = (sh << 26) >> 26;
+        }
+        out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
+        return 2;
+      }
+      case 'm': {
+        int32_t value = 0;
+        if (format[1] == 'e') {
+          if (instr->OpcodeValue() << 26 != EXT5) {
+            // ME Bits 10-6
+            value = (instr->Bits(10, 6) << 26) >> 26;
+          } else {
+            // ME Bits 5 and 10-6 (split field)
+            value = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
+          }
+        } else if (format[1] == 'b') {
+          if (instr->OpcodeValue() << 26 != EXT5) {
+            // MB Bits 5-1
+            value = (instr->Bits(5, 1) << 26) >> 26;
+          } else {
+            // MB Bits 5 and 10-6 (split field)
+            value = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
+          }
+        } else {
+          UNREACHABLE();  // bad format
+        }
+        out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
+        return 2;
+      }
+    }
+#if V8_TARGET_ARCH_PPC64
+    case 'd': {  // ds value for offset
+      int32_t value = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3);
+      out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", value);
+      return 1;
+    }
+#endif
+    default: {
+      UNREACHABLE();
+      break;
+    }
+  }
+
+  UNREACHABLE();
+  return -1;
+}
+
+
+// Format takes a formatting string for a whole instruction and prints it into
+// the output buffer. All escaped options are handed to FormatOption to be
+// parsed further.
+void Decoder::Format(Instruction* instr, const char* format) {
+  char cur = *format++;
+  while ((cur != 0) && (out_buffer_pos_ < (out_buffer_.length() - 1))) {
+    if (cur == '\'') {  // Single quote is used as the formatting escape.
+      format += FormatOption(instr, format);
+    } else {
+      out_buffer_[out_buffer_pos_++] = cur;
+    }
+    cur = *format++;
+  }
+  out_buffer_[out_buffer_pos_] = '\0';
+}
+
+
+// The disassembler may end up decoding data inlined in the code. We do not want
+// it to crash if the data does not ressemble any known instruction.
+#define VERIFY(condition) \
+  if (!(condition)) {     \
+    Unknown(instr);       \
+    return;               \
+  }
+
+
+// For currently unimplemented decodings the disassembler calls Unknown(instr)
+// which will just print "unknown" of the instruction bits.
+void Decoder::Unknown(Instruction* instr) { Format(instr, "unknown"); }
+
+
+// For currently unimplemented decodings the disassembler calls
+// UnknownFormat(instr) which will just print opcode name of the
+// instruction bits.
+void Decoder::UnknownFormat(Instruction* instr, const char* name) {
+  char buffer[100];
+  snprintf(buffer, sizeof(buffer), "%s (unknown-format)", name);
+  Format(instr, buffer);
+}
+
+
+void Decoder::MarkerFormat(Instruction* instr, const char* name, int id) {
+  char buffer[100];
+  snprintf(buffer, sizeof(buffer), "%s %d", name, id);
+  Format(instr, buffer);
+}
+
+
+void Decoder::DecodeExt1(Instruction* instr) {
+  switch (instr->Bits(10, 1) << 1) {
+    case MCRF: {
+      UnknownFormat(instr, "mcrf");  // not used by V8
+      break;
+    }
+    case BCLRX: {
+      switch (instr->Bits(25, 21) << 21) {
+        case DCBNZF: {
+          UnknownFormat(instr, "bclrx-dcbnzf");
+          break;
+        }
+        case DCBEZF: {
+          UnknownFormat(instr, "bclrx-dcbezf");
+          break;
+        }
+        case BF: {
+          UnknownFormat(instr, "bclrx-bf");
+          break;
+        }
+        case DCBNZT: {
+          UnknownFormat(instr, "bclrx-dcbbzt");
+          break;
+        }
+        case DCBEZT: {
+          UnknownFormat(instr, "bclrx-dcbnezt");
+          break;
+        }
+        case BT: {
+          UnknownFormat(instr, "bclrx-bt");
+          break;
+        }
+        case DCBNZ: {
+          UnknownFormat(instr, "bclrx-dcbnz");
+          break;
+        }
+        case DCBEZ: {
+          UnknownFormat(instr, "bclrx-dcbez");  // not used by V8
+          break;
+        }
+        case BA: {
+          if (instr->Bit(0) == 1) {
+            Format(instr, "blrl");
+          } else {
+            Format(instr, "blr");
+          }
+          break;
+        }
+      }
+      break;
+    }
+    case BCCTRX: {
+      switch (instr->Bits(25, 21) << 21) {
+        case DCBNZF: {
+          UnknownFormat(instr, "bcctrx-dcbnzf");
+          break;
+        }
+        case DCBEZF: {
+          UnknownFormat(instr, "bcctrx-dcbezf");
+          break;
+        }
+        case BF: {
+          UnknownFormat(instr, "bcctrx-bf");
+          break;
+        }
+        case DCBNZT: {
+          UnknownFormat(instr, "bcctrx-dcbnzt");
+          break;
+        }
+        case DCBEZT: {
+          UnknownFormat(instr, "bcctrx-dcbezf");
+          break;
+        }
+        case BT: {
+          UnknownFormat(instr, "bcctrx-bt");
+          break;
+        }
+        case DCBNZ: {
+          UnknownFormat(instr, "bcctrx-dcbnz");
+          break;
+        }
+        case DCBEZ: {
+          UnknownFormat(instr, "bcctrx-dcbez");
+          break;
+        }
+        case BA: {
+          if (instr->Bit(0) == 1) {
+            Format(instr, "bctrl");
+          } else {
+            Format(instr, "bctr");
+          }
+          break;
+        }
+        default: { UNREACHABLE(); }
+      }
+      break;
+    }
+    case CRNOR: {
+      Format(instr, "crnor (stuff)");
+      break;
+    }
+    case RFI: {
+      Format(instr, "rfi (stuff)");
+      break;
+    }
+    case CRANDC: {
+      Format(instr, "crandc (stuff)");
+      break;
+    }
+    case ISYNC: {
+      Format(instr, "isync (stuff)");
+      break;
+    }
+    case CRXOR: {
+      Format(instr, "crxor (stuff)");
+      break;
+    }
+    case CRNAND: {
+      UnknownFormat(instr, "crnand");
+      break;
+    }
+    case CRAND: {
+      UnknownFormat(instr, "crand");
+      break;
+    }
+    case CREQV: {
+      UnknownFormat(instr, "creqv");
+      break;
+    }
+    case CRORC: {
+      UnknownFormat(instr, "crorc");
+      break;
+    }
+    case CROR: {
+      UnknownFormat(instr, "cror");
+      break;
+    }
+    default: {
+      Unknown(instr);  // not used by V8
+    }
+  }
+}
+
+
+void Decoder::DecodeExt2(Instruction* instr) {
+  // Some encodings are 10-1 bits, handle those first
+  switch (instr->Bits(10, 1) << 1) {
+    case SRWX: {
+      Format(instr, "srw'.    'ra, 'rs, 'rb");
+      return;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case SRDX: {
+      Format(instr, "srd'.    'ra, 'rs, 'rb");
+      return;
+    }
+#endif
+    case SRAW: {
+      Format(instr, "sraw'.   'ra, 'rs, 'rb");
+      return;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case SRAD: {
+      Format(instr, "srad'.   'ra, 'rs, 'rb");
+      return;
+    }
+#endif
+    case SRAWIX: {
+      Format(instr, "srawi'.  'ra,'rs,'sh");
+      return;
+    }
+    case EXTSH: {
+      Format(instr, "extsh'.  'ra, 'rs");
+      return;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case EXTSW: {
+      Format(instr, "extsw'.  'ra, 'rs");
+      return;
+    }
+#endif
+    case EXTSB: {
+      Format(instr, "extsb'.  'ra, 'rs");
+      return;
+    }
+    case LFSX: {
+      Format(instr, "lfsx    'rt, 'ra, 'rb");
+      return;
+    }
+    case LFSUX: {
+      Format(instr, "lfsux   'rt, 'ra, 'rb");
+      return;
+    }
+    case LFDX: {
+      Format(instr, "lfdx    'rt, 'ra, 'rb");
+      return;
+    }
+    case LFDUX: {
+      Format(instr, "lfdux   'rt, 'ra, 'rb");
+      return;
+    }
+    case STFSX: {
+      Format(instr, "stfsx    'rs, 'ra, 'rb");
+      return;
+    }
+    case STFSUX: {
+      Format(instr, "stfsux   'rs, 'ra, 'rb");
+      return;
+    }
+    case STFDX: {
+      Format(instr, "stfdx    'rs, 'ra, 'rb");
+      return;
+    }
+    case STFDUX: {
+      Format(instr, "stfdux   'rs, 'ra, 'rb");
+      return;
+    }
+  }
+
+  switch (instr->Bits(10, 2) << 2) {
+    case SRADIX: {
+      Format(instr, "sradi'.  'ra,'rs,'sh");
+      return;
+    }
+  }
+
+  // ?? are all of these xo_form?
+  switch (instr->Bits(9, 1) << 1) {
+    case CMP: {
+#if V8_TARGET_ARCH_PPC64
+      if (instr->Bit(21)) {
+#endif
+        Format(instr, "cmp     'ra, 'rb");
+#if V8_TARGET_ARCH_PPC64
+      } else {
+        Format(instr, "cmpw    'ra, 'rb");
+      }
+#endif
+      break;
+    }
+    case SLWX: {
+      Format(instr, "slw'.   'ra, 'rs, 'rb");
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case SLDX: {
+      Format(instr, "sld'.   'ra, 'rs, 'rb");
+      break;
+    }
+#endif
+    case SUBFCX: {
+      Format(instr, "subfc'. 'rt, 'ra, 'rb");
+      break;
+    }
+    case ADDCX: {
+      Format(instr, "addc'.   'rt, 'ra, 'rb");
+      break;
+    }
+    case CNTLZWX: {
+      Format(instr, "cntlzw'. 'ra, 'rs");
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case CNTLZDX: {
+      Format(instr, "cntlzd'. 'ra, 'rs");
+      break;
+    }
+#endif
+    case ANDX: {
+      Format(instr, "and'.    'ra, 'rs, 'rb");
+      break;
+    }
+    case ANDCX: {
+      Format(instr, "andc'.   'ra, 'rs, 'rb");
+      break;
+    }
+    case CMPL: {
+#if V8_TARGET_ARCH_PPC64
+      if (instr->Bit(21)) {
+#endif
+        Format(instr, "cmpl    'ra, 'rb");
+#if V8_TARGET_ARCH_PPC64
+      } else {
+        Format(instr, "cmplw   'ra, 'rb");
+      }
+#endif
+      break;
+    }
+    case NEGX: {
+      Format(instr, "neg'.    'rt, 'ra");
+      break;
+    }
+    case NORX: {
+      Format(instr, "nor'.    'rt, 'ra, 'rb");
+      break;
+    }
+    case SUBFX: {
+      Format(instr, "subf'.   'rt, 'ra, 'rb");
+      break;
+    }
+    case MULHWX: {
+      Format(instr, "mulhw'o'.  'rt, 'ra, 'rb");
+      break;
+    }
+    case ADDZEX: {
+      Format(instr, "addze'.   'rt, 'ra");
+      break;
+    }
+    case MULLW: {
+      Format(instr, "mullw'o'.  'rt, 'ra, 'rb");
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case MULLD: {
+      Format(instr, "mulld'o'.  'rt, 'ra, 'rb");
+      break;
+    }
+#endif
+    case DIVW: {
+      Format(instr, "divw'o'.   'rt, 'ra, 'rb");
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case DIVD: {
+      Format(instr, "divd'o'.   'rt, 'ra, 'rb");
+      break;
+    }
+#endif
+    case ADDX: {
+      Format(instr, "add'o     'rt, 'ra, 'rb");
+      break;
+    }
+    case XORX: {
+      Format(instr, "xor'.    'ra, 'rs, 'rb");
+      break;
+    }
+    case ORX: {
+      if (instr->RTValue() == instr->RBValue()) {
+        Format(instr, "mr      'ra, 'rb");
+      } else {
+        Format(instr, "or      'ra, 'rs, 'rb");
+      }
+      break;
+    }
+    case MFSPR: {
+      int spr = instr->Bits(20, 11);
+      if (256 == spr) {
+        Format(instr, "mflr    'rt");
+      } else {
+        Format(instr, "mfspr   'rt ??");
+      }
+      break;
+    }
+    case MTSPR: {
+      int spr = instr->Bits(20, 11);
+      if (256 == spr) {
+        Format(instr, "mtlr    'rt");
+      } else if (288 == spr) {
+        Format(instr, "mtctr   'rt");
+      } else {
+        Format(instr, "mtspr   'rt ??");
+      }
+      break;
+    }
+    case MFCR: {
+      Format(instr, "mfcr    'rt");
+      break;
+    }
+    case STWX: {
+      Format(instr, "stwx    'rs, 'ra, 'rb");
+      break;
+    }
+    case STWUX: {
+      Format(instr, "stwux   'rs, 'ra, 'rb");
+      break;
+    }
+    case STBX: {
+      Format(instr, "stbx    'rs, 'ra, 'rb");
+      break;
+    }
+    case STBUX: {
+      Format(instr, "stbux   'rs, 'ra, 'rb");
+      break;
+    }
+    case STHX: {
+      Format(instr, "sthx    'rs, 'ra, 'rb");
+      break;
+    }
+    case STHUX: {
+      Format(instr, "sthux   'rs, 'ra, 'rb");
+      break;
+    }
+    case LWZX: {
+      Format(instr, "lwzx    'rt, 'ra, 'rb");
+      break;
+    }
+    case LWZUX: {
+      Format(instr, "lwzux   'rt, 'ra, 'rb");
+      break;
+    }
+    case LBZX: {
+      Format(instr, "lbzx    'rt, 'ra, 'rb");
+      break;
+    }
+    case LBZUX: {
+      Format(instr, "lbzux   'rt, 'ra, 'rb");
+      break;
+    }
+    case LHZX: {
+      Format(instr, "lhzx    'rt, 'ra, 'rb");
+      break;
+    }
+    case LHZUX: {
+      Format(instr, "lhzux   'rt, 'ra, 'rb");
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case LDX: {
+      Format(instr, "ldx     'rt, 'ra, 'rb");
+      break;
+    }
+    case LDUX: {
+      Format(instr, "ldux    'rt, 'ra, 'rb");
+      break;
+    }
+    case STDX: {
+      Format(instr, "stdx    'rt, 'ra, 'rb");
+      break;
+    }
+    case STDUX: {
+      Format(instr, "stdux   'rt, 'ra, 'rb");
+      break;
+    }
+    case MFVSRD: {
+      Format(instr, "mffprd  'ra, 'Dt");
+      break;
+    }
+    case MFVSRWZ: {
+      Format(instr, "mffprwz 'ra, 'Dt");
+      break;
+    }
+    case MTVSRD: {
+      Format(instr, "mtfprd  'Dt, 'ra");
+      break;
+    }
+    case MTVSRWA: {
+      Format(instr, "mtfprwa 'Dt, 'ra");
+      break;
+    }
+    case MTVSRWZ: {
+      Format(instr, "mtfprwz 'Dt, 'ra");
+      break;
+    }
+#endif
+    default: {
+      Unknown(instr);  // not used by V8
+    }
+  }
+}
+
+
+void Decoder::DecodeExt4(Instruction* instr) {
+  switch (instr->Bits(5, 1) << 1) {
+    case FDIV: {
+      Format(instr, "fdiv'.   'Dt, 'Da, 'Db");
+      return;
+    }
+    case FSUB: {
+      Format(instr, "fsub'.   'Dt, 'Da, 'Db");
+      return;
+    }
+    case FADD: {
+      Format(instr, "fadd'.   'Dt, 'Da, 'Db");
+      return;
+    }
+    case FSQRT: {
+      Format(instr, "fsqrt'.  'Dt, 'Db");
+      return;
+    }
+    case FSEL: {
+      Format(instr, "fsel'.   'Dt, 'Da, 'Dc, 'Db");
+      return;
+    }
+    case FMUL: {
+      Format(instr, "fmul'.   'Dt, 'Da, 'Dc");
+      return;
+    }
+    case FMSUB: {
+      Format(instr, "fmsub'.  'Dt, 'Da, 'Dc, 'Db");
+      return;
+    }
+    case FMADD: {
+      Format(instr, "fmadd'.  'Dt, 'Da, 'Dc, 'Db");
+      return;
+    }
+  }
+
+  switch (instr->Bits(10, 1) << 1) {
+    case FCMPU: {
+      Format(instr, "fcmpu   'Da, 'Db");
+      break;
+    }
+    case FRSP: {
+      Format(instr, "frsp'.   'Dt, 'Db");
+      break;
+    }
+    case FCFID: {
+      Format(instr, "fcfid'.  'Dt, 'Db");
+      break;
+    }
+    case FCTID: {
+      Format(instr, "fctid   'Dt, 'Db");
+      break;
+    }
+    case FCTIDZ: {
+      Format(instr, "fctidz  'Dt, 'Db");
+      break;
+    }
+    case FCTIW: {
+      Format(instr, "fctiw'. 'Dt, 'Db");
+      break;
+    }
+    case FCTIWZ: {
+      Format(instr, "fctiwz'. 'Dt, 'Db");
+      break;
+    }
+    case FMR: {
+      Format(instr, "fmr'.    'Dt, 'Db");
+      break;
+    }
+    case MTFSFI: {
+      Format(instr, "mtfsfi'.  ?,?");
+      break;
+    }
+    case MFFS: {
+      Format(instr, "mffs'.   'Dt");
+      break;
+    }
+    case MTFSF: {
+      Format(instr, "mtfsf'.  'Db ?,?,?");
+      break;
+    }
+    case FABS: {
+      Format(instr, "fabs'.   'Dt, 'Db");
+      break;
+    }
+    case FRIM: {
+      Format(instr, "frim    'Dt, 'Db");
+      break;
+    }
+    case FNEG: {
+      Format(instr, "fneg'.   'Dt, 'Db");
+      break;
+    }
+    default: {
+      Unknown(instr);  // not used by V8
+    }
+  }
+}
+
+
+void Decoder::DecodeExt5(Instruction* instr) {
+  switch (instr->Bits(4, 2) << 2) {
+    case RLDICL: {
+      Format(instr, "rldicl'. 'ra, 'rs, 'sh, 'mb");
+      return;
+    }
+    case RLDICR: {
+      Format(instr, "rldicr'. 'ra, 'rs, 'sh, 'me");
+      return;
+    }
+    case RLDIC: {
+      Format(instr, "rldic'.  'ra, 'rs, 'sh, 'mb");
+      return;
+    }
+    case RLDIMI: {
+      Format(instr, "rldimi'. 'ra, 'rs, 'sh, 'mb");
+      return;
+    }
+  }
+  switch (instr->Bits(4, 1) << 1) {
+    case RLDCL: {
+      Format(instr, "rldcl'.  'ra, 'rs, 'sb, 'mb");
+      return;
+    }
+  }
+  Unknown(instr);  // not used by V8
+}
+
+#undef VERIFIY
+
+// Disassemble the instruction at *instr_ptr into the output buffer.
+int Decoder::InstructionDecode(byte* instr_ptr) {
+  Instruction* instr = Instruction::At(instr_ptr);
+  // Print raw instruction bytes.
+  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%08x       ",
+                              instr->InstructionBits());
+
+  switch (instr->OpcodeValue() << 26) {
+    case TWI: {
+      PrintSoftwareInterrupt(instr->SvcValue());
+      break;
+    }
+    case MULLI: {
+      UnknownFormat(instr, "mulli");
+      break;
+    }
+    case SUBFIC: {
+      Format(instr, "subfic  'rt, 'ra, 'int16");
+      break;
+    }
+    case CMPLI: {
+#if V8_TARGET_ARCH_PPC64
+      if (instr->Bit(21)) {
+#endif
+        Format(instr, "cmpli   'ra, 'uint16");
+#if V8_TARGET_ARCH_PPC64
+      } else {
+        Format(instr, "cmplwi  'ra, 'uint16");
+      }
+#endif
+      break;
+    }
+    case CMPI: {
+#if V8_TARGET_ARCH_PPC64
+      if (instr->Bit(21)) {
+#endif
+        Format(instr, "cmpi    'ra, 'int16");
+#if V8_TARGET_ARCH_PPC64
+      } else {
+        Format(instr, "cmpwi   'ra, 'int16");
+      }
+#endif
+      break;
+    }
+    case ADDIC: {
+      Format(instr, "addic   'rt, 'ra, 'int16");
+      break;
+    }
+    case ADDICx: {
+      UnknownFormat(instr, "addicx");
+      break;
+    }
+    case ADDI: {
+      if (instr->RAValue() == 0) {
+        // this is load immediate
+        Format(instr, "li      'rt, 'int16");
+      } else {
+        Format(instr, "addi    'rt, 'ra, 'int16");
+      }
+      break;
+    }
+    case ADDIS: {
+      if (instr->RAValue() == 0) {
+        Format(instr, "lis     'rt, 'int16");
+      } else {
+        Format(instr, "addis   'rt, 'ra, 'int16");
+      }
+      break;
+    }
+    case BCX: {
+      int bo = instr->Bits(25, 21) << 21;
+      int bi = instr->Bits(20, 16);
+      switch (bi) {
+        case 2:
+        case 30:
+          if (BT == bo) {
+            Format(instr, "beq'l'a 'target16");
+            break;
+          }
+          if (BF == bo) {
+            Format(instr, "bne'l'a 'target16");
+            break;
+          }
+          Format(instr, "bc'l'a 'target16");
+          break;
+        case 29:
+          if (BT == bo) {
+            Format(instr, "bgt'l'a 'target16");
+            break;
+          }
+          if (BF == bo) {
+            Format(instr, "ble'l'a 'target16");
+            break;
+          }
+          Format(instr, "bc'l'a 'target16");
+          break;
+        case 28:
+          if (BT == bo) {
+            Format(instr, "blt'l'a 'target16");
+            break;
+          }
+          if (BF == bo) {
+            Format(instr, "bge'l'a 'target16");
+            break;
+          }
+          Format(instr, "bc'l'a 'target16");
+          break;
+        default:
+          Format(instr, "bc'l'a 'target16");
+          break;
+      }
+      break;
+    }
+    case SC: {
+      UnknownFormat(instr, "sc");
+      break;
+    }
+    case BX: {
+      Format(instr, "b'l'a 'target26");
+      break;
+    }
+    case EXT1: {
+      DecodeExt1(instr);
+      break;
+    }
+    case RLWIMIX: {
+      Format(instr, "rlwimi'. 'ra, 'rs, 'sh, 'me, 'mb");
+      break;
+    }
+    case RLWINMX: {
+      Format(instr, "rlwinm'. 'ra, 'rs, 'sh, 'me, 'mb");
+      break;
+    }
+    case RLWNMX: {
+      Format(instr, "rlwnm'.  'ra, 'rs, 'rb, 'me, 'mb");
+      break;
+    }
+    case ORI: {
+      Format(instr, "ori     'ra, 'rs, 'uint16");
+      break;
+    }
+    case ORIS: {
+      Format(instr, "oris    'ra, 'rs, 'uint16");
+      break;
+    }
+    case XORI: {
+      Format(instr, "xori    'ra, 'rs, 'uint16");
+      break;
+    }
+    case XORIS: {
+      Format(instr, "xoris   'ra, 'rs, 'uint16");
+      break;
+    }
+    case ANDIx: {
+      Format(instr, "andi.   'ra, 'rs, 'uint16");
+      break;
+    }
+    case ANDISx: {
+      Format(instr, "andis.  'ra, 'rs, 'uint16");
+      break;
+    }
+    case EXT2: {
+      DecodeExt2(instr);
+      break;
+    }
+    case LWZ: {
+      Format(instr, "lwz     'rt, 'int16('ra)");
+      break;
+    }
+    case LWZU: {
+      Format(instr, "lwzu    'rt, 'int16('ra)");
+      break;
+    }
+    case LBZ: {
+      Format(instr, "lbz     'rt, 'int16('ra)");
+      break;
+    }
+    case LBZU: {
+      Format(instr, "lbzu    'rt, 'int16('ra)");
+      break;
+    }
+    case STW: {
+      Format(instr, "stw     'rs, 'int16('ra)");
+      break;
+    }
+    case STWU: {
+      Format(instr, "stwu    'rs, 'int16('ra)");
+      break;
+    }
+    case STB: {
+      Format(instr, "stb     'rs, 'int16('ra)");
+      break;
+    }
+    case STBU: {
+      Format(instr, "stbu    'rs, 'int16('ra)");
+      break;
+    }
+    case LHZ: {
+      Format(instr, "lhz     'rt, 'int16('ra)");
+      break;
+    }
+    case LHZU: {
+      Format(instr, "lhzu    'rt, 'int16('ra)");
+      break;
+    }
+    case LHA: {
+      Format(instr, "lha     'rt, 'int16('ra)");
+      break;
+    }
+    case LHAU: {
+      Format(instr, "lhau    'rt, 'int16('ra)");
+      break;
+    }
+    case STH: {
+      Format(instr, "sth 'rs, 'int16('ra)");
+      break;
+    }
+    case STHU: {
+      Format(instr, "sthu 'rs, 'int16('ra)");
+      break;
+    }
+    case LMW: {
+      UnknownFormat(instr, "lmw");
+      break;
+    }
+    case STMW: {
+      UnknownFormat(instr, "stmw");
+      break;
+    }
+    case LFS: {
+      Format(instr, "lfs     'Dt, 'int16('ra)");
+      break;
+    }
+    case LFSU: {
+      Format(instr, "lfsu    'Dt, 'int16('ra)");
+      break;
+    }
+    case LFD: {
+      Format(instr, "lfd     'Dt, 'int16('ra)");
+      break;
+    }
+    case LFDU: {
+      Format(instr, "lfdu    'Dt, 'int16('ra)");
+      break;
+    }
+    case STFS: {
+      Format(instr, "stfs    'Dt, 'int16('ra)");
+      break;
+    }
+    case STFSU: {
+      Format(instr, "stfsu   'Dt, 'int16('ra)");
+      break;
+    }
+    case STFD: {
+      Format(instr, "stfd    'Dt, 'int16('ra)");
+      break;
+    }
+    case STFDU: {
+      Format(instr, "stfdu   'Dt, 'int16('ra)");
+      break;
+    }
+    case EXT3:
+    case EXT4: {
+      DecodeExt4(instr);
+      break;
+    }
+    case EXT5: {
+      DecodeExt5(instr);
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case LD: {
+      switch (instr->Bits(1, 0)) {
+        case 0:
+          Format(instr, "ld      'rt, 'd('ra)");
+          break;
+        case 1:
+          Format(instr, "ldu     'rt, 'd('ra)");
+          break;
+        case 2:
+          Format(instr, "lwa     'rt, 'd('ra)");
+          break;
+      }
+      break;
+    }
+    case STD: {  // could be STD or STDU
+      if (instr->Bit(0) == 0) {
+        Format(instr, "std     'rs, 'd('ra)");
+      } else {
+        Format(instr, "stdu    'rs, 'd('ra)");
+      }
+      break;
+    }
+#endif
+
+    case FAKE_OPCODE: {
+      if (instr->Bits(MARKER_SUBOPCODE_BIT, MARKER_SUBOPCODE_BIT) == 1) {
+        int marker_code = instr->Bits(STUB_MARKER_HIGH_BIT, 0);
+        DCHECK(marker_code < F_NEXT_AVAILABLE_STUB_MARKER);
+        MarkerFormat(instr, "stub-marker ", marker_code);
+      } else {
+        int fake_opcode = instr->Bits(FAKE_OPCODE_HIGH_BIT, 0);
+        MarkerFormat(instr, "faker-opcode ", fake_opcode);
+      }
+      break;
+    }
+    default: {
+      Unknown(instr);
+      break;
+    }
+  }
+
+  return Instruction::kInstrSize;
+}
+}
+}  // namespace v8::internal
+
+
+//------------------------------------------------------------------------------
+
+namespace disasm {
+
+
+const char* NameConverter::NameOfAddress(byte* addr) const {
+  v8::internal::SNPrintF(tmp_buffer_, "%p", addr);
+  return tmp_buffer_.start();
+}
+
+
+const char* NameConverter::NameOfConstant(byte* addr) const {
+  return NameOfAddress(addr);
+}
+
+
+const char* NameConverter::NameOfCPURegister(int reg) const {
+  return v8::internal::Registers::Name(reg);
+}
+
+const char* NameConverter::NameOfByteCPURegister(int reg) const {
+  UNREACHABLE();  // PPC does not have the concept of a byte register
+  return "nobytereg";
+}
+
+
+const char* NameConverter::NameOfXMMRegister(int reg) const {
+  UNREACHABLE();  // PPC does not have any XMM registers
+  return "noxmmreg";
+}
+
+const char* NameConverter::NameInCode(byte* addr) const {
+  // The default name converter is called for unknown code. So we will not try
+  // to access any memory.
+  return "";
+}
+
+
+//------------------------------------------------------------------------------
+
+Disassembler::Disassembler(const NameConverter& converter)
+    : converter_(converter) {}
+
+
+Disassembler::~Disassembler() {}
+
+
+int Disassembler::InstructionDecode(v8::internal::Vector<char> buffer,
+                                    byte* instruction) {
+  v8::internal::Decoder d(converter_, buffer);
+  return d.InstructionDecode(instruction);
+}
+
+
+// The PPC assembler does not currently use constant pools.
+int Disassembler::ConstantPoolSizeAt(byte* instruction) { return -1; }
+
+
+void Disassembler::Disassemble(FILE* f, byte* begin, byte* end) {
+  NameConverter converter;
+  Disassembler d(converter);
+  for (byte* pc = begin; pc < end;) {
+    v8::internal::EmbeddedVector<char, 128> buffer;
+    buffer[0] = '\0';
+    byte* prev_pc = pc;
+    pc += d.InstructionDecode(buffer, pc);
+    v8::internal::PrintF(f, "%p    %08x      %s\n", prev_pc,
+                         *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
+  }
+}
+
+
+}  // namespace disasm
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/frames-ppc.cc b/src/ppc/frames-ppc.cc
new file mode 100644
index 0000000..4b52882
--- /dev/null
+++ b/src/ppc/frames-ppc.cc
@@ -0,0 +1,60 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/assembler.h"
+#include "src/frames.h"
+#include "src/macro-assembler.h"
+
+#include "src/ppc/assembler-ppc.h"
+#include "src/ppc/assembler-ppc-inl.h"
+#include "src/ppc/macro-assembler-ppc.h"
+
+namespace v8 {
+namespace internal {
+
+
+Register JavaScriptFrame::fp_register() { return v8::internal::fp; }
+Register JavaScriptFrame::context_register() { return cp; }
+Register JavaScriptFrame::constant_pool_pointer_register() {
+#if V8_OOL_CONSTANT_POOL
+  DCHECK(FLAG_enable_ool_constant_pool);
+  return kConstantPoolRegister;
+#else
+  UNREACHABLE();
+  return no_reg;
+#endif
+}
+
+
+Register StubFailureTrampolineFrame::fp_register() { return v8::internal::fp; }
+Register StubFailureTrampolineFrame::context_register() { return cp; }
+Register StubFailureTrampolineFrame::constant_pool_pointer_register() {
+#if V8_OOL_CONSTANT_POOL
+  DCHECK(FLAG_enable_ool_constant_pool);
+  return kConstantPoolRegister;
+#else
+  UNREACHABLE();
+  return no_reg;
+#endif
+}
+
+
+Object*& ExitFrame::constant_pool_slot() const {
+#if V8_OOL_CONSTANT_POOL
+  DCHECK(FLAG_enable_ool_constant_pool);
+  const int offset = ExitFrameConstants::kConstantPoolOffset;
+  return Memory::Object_at(fp() + offset);
+#else
+  UNREACHABLE();
+  return Memory::Object_at(NULL);
+#endif
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/frames-ppc.h b/src/ppc/frames-ppc.h
new file mode 100644
index 0000000..f00fa66
--- /dev/null
+++ b/src/ppc/frames-ppc.h
@@ -0,0 +1,202 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_PPC_FRAMES_PPC_H_
+#define V8_PPC_FRAMES_PPC_H_
+
+namespace v8 {
+namespace internal {
+
+
+// Register list in load/store instructions
+// Note that the bit values must match those used in actual instruction encoding
+const int kNumRegs = 32;
+
+
+// Caller-saved/arguments registers
+const RegList kJSCallerSaved = 1 << 3 |   // r3  a1
+                               1 << 4 |   // r4  a2
+                               1 << 5 |   // r5  a3
+                               1 << 6 |   // r6  a4
+                               1 << 7 |   // r7  a5
+                               1 << 8 |   // r8  a6
+                               1 << 9 |   // r9  a7
+                               1 << 10 |  // r10 a8
+                               1 << 11;
+
+const int kNumJSCallerSaved = 9;
+
+// Return the code of the n-th caller-saved register available to JavaScript
+// e.g. JSCallerSavedReg(0) returns r0.code() == 0
+int JSCallerSavedCode(int n);
+
+
+// Callee-saved registers preserved when switching from C to JavaScript
+const RegList kCalleeSaved = 1 << 14 |  // r14
+                             1 << 15 |  // r15
+                             1 << 16 |  // r16
+                             1 << 17 |  // r17
+                             1 << 18 |  // r18
+                             1 << 19 |  // r19
+                             1 << 20 |  // r20
+                             1 << 21 |  // r21
+                             1 << 22 |  // r22
+                             1 << 23 |  // r23
+                             1 << 24 |  // r24
+                             1 << 25 |  // r25
+                             1 << 26 |  // r26
+                             1 << 27 |  // r27
+                             1 << 28 |  // r28
+                             1 << 29 |  // r29
+                             1 << 30 |  // r20
+                             1 << 31;   // r31
+
+
+const int kNumCalleeSaved = 18;
+
+// Number of registers for which space is reserved in safepoints. Must be a
+// multiple of 8.
+// TODO(regis): Only 8 registers may actually be sufficient. Revisit.
+const int kNumSafepointRegisters = 32;
+
+// Define the list of registers actually saved at safepoints.
+// Note that the number of saved registers may be smaller than the reserved
+// space, i.e. kNumSafepointSavedRegisters <= kNumSafepointRegisters.
+const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved;
+const int kNumSafepointSavedRegisters = kNumJSCallerSaved + kNumCalleeSaved;
+
+// The following constants describe the stack frame linkage area as
+// defined by the ABI.  Note that kNumRequiredStackFrameSlots must
+// satisfy alignment requirements (rounding up if required).
+#if V8_TARGET_ARCH_PPC64 && V8_TARGET_LITTLE_ENDIAN
+// [0] back chain
+// [1] condition register save area
+// [2] link register save area
+// [3] TOC save area
+// [4] Parameter1 save area
+// ...
+// [11] Parameter8 save area
+// [12] Parameter9 slot (if necessary)
+// ...
+const int kNumRequiredStackFrameSlots = 12;
+const int kStackFrameLRSlot = 2;
+const int kStackFrameExtraParamSlot = 12;
+#elif V8_OS_AIX || V8_TARGET_ARCH_PPC64
+// [0] back chain
+// [1] condition register save area
+// [2] link register save area
+// [3] reserved for compiler
+// [4] reserved by binder
+// [5] TOC save area
+// [6] Parameter1 save area
+// ...
+// [13] Parameter8 save area
+// [14] Parameter9 slot (if necessary)
+// ...
+#if V8_TARGET_ARCH_PPC64
+const int kNumRequiredStackFrameSlots = 14;
+#else
+const int kNumRequiredStackFrameSlots = 16;
+#endif
+const int kStackFrameLRSlot = 2;
+const int kStackFrameExtraParamSlot = 14;
+#else
+// [0] back chain
+// [1] link register save area
+// [2] Parameter9 slot (if necessary)
+// ...
+const int kNumRequiredStackFrameSlots = 4;
+const int kStackFrameLRSlot = 1;
+const int kStackFrameExtraParamSlot = 2;
+#endif
+
+// ----------------------------------------------------
+
+
+class EntryFrameConstants : public AllStatic {
+ public:
+  static const int kCallerFPOffset =
+      -(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize);
+};
+
+
+class ExitFrameConstants : public AllStatic {
+ public:
+#if V8_OOL_CONSTANT_POOL
+  static const int kFrameSize = 3 * kPointerSize;
+  static const int kConstantPoolOffset = -3 * kPointerSize;
+#else
+  static const int kFrameSize = 2 * kPointerSize;
+  static const int kConstantPoolOffset = 0;  // Not used.
+#endif
+  static const int kCodeOffset = -2 * kPointerSize;
+  static const int kSPOffset = -1 * kPointerSize;
+
+  // The caller fields are below the frame pointer on the stack.
+  static const int kCallerFPOffset = 0 * kPointerSize;
+  // The calling JS function is below FP.
+  static const int kCallerPCOffset = 1 * kPointerSize;
+
+  // FP-relative displacement of the caller's SP.  It points just
+  // below the saved PC.
+  static const int kCallerSPDisplacement = 2 * kPointerSize;
+};
+
+
+class JavaScriptFrameConstants : public AllStatic {
+ public:
+  // FP-relative.
+  static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset;
+  static const int kLastParameterOffset = +2 * kPointerSize;
+  static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset;
+
+  // Caller SP-relative.
+  static const int kParam0Offset = -2 * kPointerSize;
+  static const int kReceiverOffset = -1 * kPointerSize;
+};
+
+
+class ArgumentsAdaptorFrameConstants : public AllStatic {
+ public:
+  // FP-relative.
+  static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset;
+
+  static const int kFrameSize =
+      StandardFrameConstants::kFixedFrameSize + kPointerSize;
+};
+
+
+class ConstructFrameConstants : public AllStatic {
+ public:
+  // FP-relative.
+  static const int kImplicitReceiverOffset = -6 * kPointerSize;
+  static const int kConstructorOffset = -5 * kPointerSize;
+  static const int kLengthOffset = -4 * kPointerSize;
+  static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
+
+  static const int kFrameSize =
+      StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize;
+};
+
+
+class InternalFrameConstants : public AllStatic {
+ public:
+  // FP-relative.
+  static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
+};
+
+
+inline Object* JavaScriptFrame::function_slot_object() const {
+  const int offset = JavaScriptFrameConstants::kFunctionOffset;
+  return Memory::Object_at(fp() + offset);
+}
+
+
+inline void StackHandler::SetFp(Address slot, Address fp) {
+  Memory::Address_at(slot) = fp;
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_PPC_FRAMES_PPC_H_
diff --git a/src/ppc/full-codegen-ppc.cc b/src/ppc/full-codegen-ppc.cc
new file mode 100644
index 0000000..1bb4f54
--- /dev/null
+++ b/src/ppc/full-codegen-ppc.cc
@@ -0,0 +1,5290 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/code-factory.h"
+#include "src/code-stubs.h"
+#include "src/codegen.h"
+#include "src/compiler.h"
+#include "src/debug.h"
+#include "src/full-codegen.h"
+#include "src/ic/ic.h"
+#include "src/isolate-inl.h"
+#include "src/parser.h"
+#include "src/scopes.h"
+
+#include "src/ppc/code-stubs-ppc.h"
+#include "src/ppc/macro-assembler-ppc.h"
+
+namespace v8 {
+namespace internal {
+
+#define __ ACCESS_MASM(masm_)
+
+// A patch site is a location in the code which it is possible to patch. This
+// class has a number of methods to emit the code which is patchable and the
+// method EmitPatchInfo to record a marker back to the patchable code. This
+// marker is a cmpi rx, #yyy instruction, and x * 0x0000ffff + yyy (raw 16 bit
+// immediate value is used) is the delta from the pc to the first instruction of
+// the patchable code.
+// See PatchInlinedSmiCode in ic-ppc.cc for the code that patches it
+class JumpPatchSite BASE_EMBEDDED {
+ public:
+  explicit JumpPatchSite(MacroAssembler* masm) : masm_(masm) {
+#ifdef DEBUG
+    info_emitted_ = false;
+#endif
+  }
+
+  ~JumpPatchSite() { DCHECK(patch_site_.is_bound() == info_emitted_); }
+
+  // When initially emitting this ensure that a jump is always generated to skip
+  // the inlined smi code.
+  void EmitJumpIfNotSmi(Register reg, Label* target) {
+    DCHECK(!patch_site_.is_bound() && !info_emitted_);
+    Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
+    __ bind(&patch_site_);
+    __ cmp(reg, reg, cr0);
+    __ beq(target, cr0);  // Always taken before patched.
+  }
+
+  // When initially emitting this ensure that a jump is never generated to skip
+  // the inlined smi code.
+  void EmitJumpIfSmi(Register reg, Label* target) {
+    Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
+    DCHECK(!patch_site_.is_bound() && !info_emitted_);
+    __ bind(&patch_site_);
+    __ cmp(reg, reg, cr0);
+    __ bne(target, cr0);  // Never taken before patched.
+  }
+
+  void EmitPatchInfo() {
+    if (patch_site_.is_bound()) {
+      int delta_to_patch_site = masm_->InstructionsGeneratedSince(&patch_site_);
+      Register reg;
+      // I believe this is using reg as the high bits of of the offset
+      reg.set_code(delta_to_patch_site / kOff16Mask);
+      __ cmpi(reg, Operand(delta_to_patch_site % kOff16Mask));
+#ifdef DEBUG
+      info_emitted_ = true;
+#endif
+    } else {
+      __ nop();  // Signals no inlined code.
+    }
+  }
+
+ private:
+  MacroAssembler* masm_;
+  Label patch_site_;
+#ifdef DEBUG
+  bool info_emitted_;
+#endif
+};
+
+
+// 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
+// function.
+//
+// The live registers are:
+//   o r4: the JS function object being called (i.e., ourselves)
+//   o cp: our context
+//   o fp: our caller's frame pointer (aka r31)
+//   o sp: stack pointer
+//   o lr: return address
+//   o ip: our own function entry (required by the prologue)
+//
+// The function builds a JS frame.  Please see JavaScriptFrameConstants in
+// frames-ppc.h for its layout.
+void FullCodeGenerator::Generate() {
+  CompilationInfo* info = info_;
+  handler_table_ =
+      isolate()->factory()->NewFixedArray(function()->handler_count(), TENURED);
+
+  profiling_counter_ = isolate()->factory()->NewCell(
+      Handle<Smi>(Smi::FromInt(FLAG_interrupt_budget), isolate()));
+  SetFunctionPosition(function());
+  Comment cmnt(masm_, "[ function compiled by full code generator");
+
+  ProfileEntryHookStub::MaybeCallEntryHook(masm_);
+
+#ifdef DEBUG
+  if (strlen(FLAG_stop_at) > 0 &&
+      info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
+    __ stop("stop-at");
+  }
+#endif
+
+  // Sloppy mode functions and builtins need to replace the receiver with the
+  // global proxy when called as functions (without an explicit receiver
+  // object).
+  if (info->strict_mode() == SLOPPY && !info->is_native()) {
+    Label ok;
+    int receiver_offset = info->scope()->num_parameters() * kPointerSize;
+    __ LoadP(r5, MemOperand(sp, receiver_offset), r0);
+    __ CompareRoot(r5, Heap::kUndefinedValueRootIndex);
+    __ bne(&ok);
+
+    __ LoadP(r5, GlobalObjectOperand());
+    __ LoadP(r5, FieldMemOperand(r5, GlobalObject::kGlobalProxyOffset));
+
+    __ StoreP(r5, MemOperand(sp, receiver_offset), r0);
+
+    __ bind(&ok);
+  }
+
+  // Open a frame scope to indicate that there is a frame on the stack.  The
+  // MANUAL indicates that the scope shouldn't actually generate code to set up
+  // the frame (that is done below).
+  FrameScope frame_scope(masm_, StackFrame::MANUAL);
+  int prologue_offset = masm_->pc_offset();
+
+  if (prologue_offset) {
+    // Prologue logic requires it's starting address in ip and the
+    // corresponding offset from the function entry.
+    prologue_offset += Instruction::kInstrSize;
+    __ addi(ip, ip, Operand(prologue_offset));
+  }
+  info->set_prologue_offset(prologue_offset);
+  __ Prologue(info->IsCodePreAgingActive(), prologue_offset);
+  info->AddNoFrameRange(0, masm_->pc_offset());
+
+  {
+    Comment cmnt(masm_, "[ Allocate locals");
+    int locals_count = info->scope()->num_stack_slots();
+    // Generators allocate locals, if any, in context slots.
+    DCHECK(!info->function()->is_generator() || locals_count == 0);
+    if (locals_count > 0) {
+      if (locals_count >= 128) {
+        Label ok;
+        __ Add(ip, sp, -(locals_count * kPointerSize), r0);
+        __ LoadRoot(r5, Heap::kRealStackLimitRootIndex);
+        __ cmpl(ip, r5);
+        __ bc_short(ge, &ok);
+        __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
+        __ bind(&ok);
+      }
+      __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+      int kMaxPushes = FLAG_optimize_for_size ? 4 : 32;
+      if (locals_count >= kMaxPushes) {
+        int loop_iterations = locals_count / kMaxPushes;
+        __ mov(r5, Operand(loop_iterations));
+        __ mtctr(r5);
+        Label loop_header;
+        __ bind(&loop_header);
+        // Do pushes.
+        for (int i = 0; i < kMaxPushes; i++) {
+          __ push(ip);
+        }
+        // Continue loop if not done.
+        __ bdnz(&loop_header);
+      }
+      int remaining = locals_count % kMaxPushes;
+      // Emit the remaining pushes.
+      for (int i = 0; i < remaining; i++) {
+        __ push(ip);
+      }
+    }
+  }
+
+  bool function_in_register = true;
+
+  // Possibly allocate a local context.
+  int heap_slots = info->scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+  if (heap_slots > 0) {
+    // Argument to NewContext is the function, which is still in r4.
+    Comment cmnt(masm_, "[ Allocate context");
+    bool need_write_barrier = true;
+    if (FLAG_harmony_scoping && info->scope()->is_script_scope()) {
+      __ push(r4);
+      __ Push(info->scope()->GetScopeInfo());
+      __ CallRuntime(Runtime::kNewScriptContext, 2);
+    } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
+      FastNewContextStub stub(isolate(), heap_slots);
+      __ CallStub(&stub);
+      // Result of FastNewContextStub is always in new space.
+      need_write_barrier = false;
+    } else {
+      __ push(r4);
+      __ CallRuntime(Runtime::kNewFunctionContext, 1);
+    }
+    function_in_register = false;
+    // Context is returned in r3.  It replaces the context passed to us.
+    // It's saved in the stack and kept live in cp.
+    __ mr(cp, r3);
+    __ StoreP(r3, MemOperand(fp, StandardFrameConstants::kContextOffset));
+    // Copy any necessary parameters into the context.
+    int num_parameters = info->scope()->num_parameters();
+    for (int i = 0; i < num_parameters; i++) {
+      Variable* var = scope()->parameter(i);
+      if (var->IsContextSlot()) {
+        int parameter_offset = StandardFrameConstants::kCallerSPOffset +
+                               (num_parameters - 1 - i) * kPointerSize;
+        // Load parameter from stack.
+        __ LoadP(r3, MemOperand(fp, parameter_offset), r0);
+        // Store it in the context.
+        MemOperand target = ContextOperand(cp, var->index());
+        __ StoreP(r3, target, r0);
+
+        // Update the write barrier.
+        if (need_write_barrier) {
+          __ RecordWriteContextSlot(cp, target.offset(), r3, r6,
+                                    kLRHasBeenSaved, kDontSaveFPRegs);
+        } else if (FLAG_debug_code) {
+          Label done;
+          __ JumpIfInNewSpace(cp, r3, &done);
+          __ Abort(kExpectedNewSpaceObject);
+          __ bind(&done);
+        }
+      }
+    }
+  }
+
+  Variable* arguments = scope()->arguments();
+  if (arguments != NULL) {
+    // Function uses arguments object.
+    Comment cmnt(masm_, "[ Allocate arguments object");
+    if (!function_in_register) {
+      // Load this again, if it's used by the local context below.
+      __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+    } else {
+      __ mr(r6, r4);
+    }
+    // Receiver is just before the parameters on the caller's stack.
+    int num_parameters = info->scope()->num_parameters();
+    int offset = num_parameters * kPointerSize;
+    __ addi(r5, fp, Operand(StandardFrameConstants::kCallerSPOffset + offset));
+    __ LoadSmiLiteral(r4, Smi::FromInt(num_parameters));
+    __ Push(r6, r5, r4);
+
+    // Arguments to ArgumentsAccessStub:
+    //   function, receiver address, parameter count.
+    // The stub will rewrite receiever and parameter count if the previous
+    // stack frame was an arguments adapter frame.
+    ArgumentsAccessStub::Type type;
+    if (strict_mode() == STRICT) {
+      type = ArgumentsAccessStub::NEW_STRICT;
+    } else if (function()->has_duplicate_parameters()) {
+      type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
+    } else {
+      type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
+    }
+    ArgumentsAccessStub stub(isolate(), type);
+    __ CallStub(&stub);
+
+    SetVar(arguments, r3, r4, r5);
+  }
+
+  if (FLAG_trace) {
+    __ CallRuntime(Runtime::kTraceEnter, 0);
+  }
+
+  // Visit the declarations and body unless there is an illegal
+  // redeclaration.
+  if (scope()->HasIllegalRedeclaration()) {
+    Comment cmnt(masm_, "[ Declarations");
+    scope()->VisitIllegalRedeclaration(this);
+
+  } else {
+    PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
+    {
+      Comment cmnt(masm_, "[ Declarations");
+      // For named function expressions, declare the function name as a
+      // constant.
+      if (scope()->is_function_scope() && scope()->function() != NULL) {
+        VariableDeclaration* function = scope()->function();
+        DCHECK(function->proxy()->var()->mode() == CONST ||
+               function->proxy()->var()->mode() == CONST_LEGACY);
+        DCHECK(function->proxy()->var()->location() != Variable::UNALLOCATED);
+        VisitVariableDeclaration(function);
+      }
+      VisitDeclarations(scope()->declarations());
+    }
+
+    {
+      Comment cmnt(masm_, "[ Stack check");
+      PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
+      Label ok;
+      __ LoadRoot(ip, Heap::kStackLimitRootIndex);
+      __ cmpl(sp, ip);
+      __ bc_short(ge, &ok);
+      __ Call(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET);
+      __ bind(&ok);
+    }
+
+    {
+      Comment cmnt(masm_, "[ Body");
+      DCHECK(loop_depth() == 0);
+      VisitStatements(function()->body());
+      DCHECK(loop_depth() == 0);
+    }
+  }
+
+  // Always emit a 'return undefined' in case control fell off the end of
+  // the body.
+  {
+    Comment cmnt(masm_, "[ return <undefined>;");
+    __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
+  }
+  EmitReturnSequence();
+}
+
+
+void FullCodeGenerator::ClearAccumulator() {
+  __ LoadSmiLiteral(r3, Smi::FromInt(0));
+}
+
+
+void FullCodeGenerator::EmitProfilingCounterDecrement(int delta) {
+  __ mov(r5, Operand(profiling_counter_));
+  __ LoadP(r6, FieldMemOperand(r5, Cell::kValueOffset));
+  __ SubSmiLiteral(r6, r6, Smi::FromInt(delta), r0);
+  __ StoreP(r6, FieldMemOperand(r5, Cell::kValueOffset), r0);
+}
+
+
+void FullCodeGenerator::EmitProfilingCounterReset() {
+  int reset_value = FLAG_interrupt_budget;
+  if (info_->is_debug()) {
+    // Detect debug break requests as soon as possible.
+    reset_value = FLAG_interrupt_budget >> 4;
+  }
+  __ mov(r5, Operand(profiling_counter_));
+  __ LoadSmiLiteral(r6, Smi::FromInt(reset_value));
+  __ StoreP(r6, FieldMemOperand(r5, Cell::kValueOffset), r0);
+}
+
+
+void FullCodeGenerator::EmitBackEdgeBookkeeping(IterationStatement* stmt,
+                                                Label* back_edge_target) {
+  Comment cmnt(masm_, "[ Back edge bookkeeping");
+  Label ok;
+
+  DCHECK(back_edge_target->is_bound());
+  int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target) +
+                 kCodeSizeMultiplier / 2;
+  int weight = Min(kMaxBackEdgeWeight, Max(1, distance / kCodeSizeMultiplier));
+  EmitProfilingCounterDecrement(weight);
+  {
+    Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
+    // BackEdgeTable::PatchAt manipulates this sequence.
+    __ cmpi(r6, Operand::Zero());
+    __ bc_short(ge, &ok);
+    __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
+
+    // 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.
+    RecordBackEdge(stmt->OsrEntryId());
+  }
+  EmitProfilingCounterReset();
+
+  __ bind(&ok);
+  PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
+  // Record a mapping of the OSR id to this PC.  This is used if the OSR
+  // entry becomes the target of a bailout.  We don't expect it to be, but
+  // we want it to work if it is.
+  PrepareForBailoutForId(stmt->OsrEntryId(), NO_REGISTERS);
+}
+
+
+void FullCodeGenerator::EmitReturnSequence() {
+  Comment cmnt(masm_, "[ Return sequence");
+  if (return_label_.is_bound()) {
+    __ b(&return_label_);
+  } else {
+    __ bind(&return_label_);
+    if (FLAG_trace) {
+      // Push the return value on the stack as the parameter.
+      // Runtime::TraceExit returns its parameter in r3
+      __ push(r3);
+      __ CallRuntime(Runtime::kTraceExit, 1);
+    }
+    // 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 {
+      int distance = masm_->pc_offset() + kCodeSizeMultiplier / 2;
+      weight = Min(kMaxBackEdgeWeight, Max(1, distance / kCodeSizeMultiplier));
+    }
+    EmitProfilingCounterDecrement(weight);
+    Label ok;
+    __ cmpi(r6, Operand::Zero());
+    __ bge(&ok);
+    __ push(r3);
+    __ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
+    __ pop(r3);
+    EmitProfilingCounterReset();
+    __ bind(&ok);
+
+#ifdef DEBUG
+    // Add a label for checking the size of the code used for returning.
+    Label check_exit_codesize;
+    __ bind(&check_exit_codesize);
+#endif
+    // Make sure that the constant pool is not emitted inside of the return
+    // sequence.
+    {
+      Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
+      int32_t sp_delta = (info_->scope()->num_parameters() + 1) * kPointerSize;
+      CodeGenerator::RecordPositions(masm_, function()->end_position() - 1);
+      __ RecordJSReturn();
+      int no_frame_start = __ LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta);
+#if V8_TARGET_ARCH_PPC64
+      // With 64bit we may need nop() instructions to ensure we have
+      // enough space to SetDebugBreakAtReturn()
+      if (is_int16(sp_delta)) {
+#if !V8_OOL_CONSTANT_POOL
+        masm_->nop();
+#endif
+        masm_->nop();
+      }
+#endif
+      __ blr();
+      info_->AddNoFrameRange(no_frame_start, masm_->pc_offset());
+    }
+
+#ifdef DEBUG
+    // Check that the size of the code used for returning is large enough
+    // for the debugger's requirements.
+    DCHECK(Assembler::kJSReturnSequenceInstructions <=
+           masm_->InstructionsGeneratedSince(&check_exit_codesize));
+#endif
+  }
+}
+
+
+void FullCodeGenerator::EffectContext::Plug(Variable* var) const {
+  DCHECK(var->IsStackAllocated() || var->IsContextSlot());
+}
+
+
+void FullCodeGenerator::AccumulatorValueContext::Plug(Variable* var) const {
+  DCHECK(var->IsStackAllocated() || var->IsContextSlot());
+  codegen()->GetVar(result_register(), var);
+}
+
+
+void FullCodeGenerator::StackValueContext::Plug(Variable* var) const {
+  DCHECK(var->IsStackAllocated() || var->IsContextSlot());
+  codegen()->GetVar(result_register(), var);
+  __ push(result_register());
+}
+
+
+void FullCodeGenerator::TestContext::Plug(Variable* var) const {
+  DCHECK(var->IsStackAllocated() || var->IsContextSlot());
+  // For simplicity we always test the accumulator register.
+  codegen()->GetVar(result_register(), var);
+  codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
+  codegen()->DoTest(this);
+}
+
+
+void FullCodeGenerator::EffectContext::Plug(Heap::RootListIndex index) const {}
+
+
+void FullCodeGenerator::AccumulatorValueContext::Plug(
+    Heap::RootListIndex index) const {
+  __ LoadRoot(result_register(), index);
+}
+
+
+void FullCodeGenerator::StackValueContext::Plug(
+    Heap::RootListIndex index) const {
+  __ LoadRoot(result_register(), index);
+  __ push(result_register());
+}
+
+
+void FullCodeGenerator::TestContext::Plug(Heap::RootListIndex index) const {
+  codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_,
+                                          false_label_);
+  if (index == Heap::kUndefinedValueRootIndex ||
+      index == Heap::kNullValueRootIndex ||
+      index == Heap::kFalseValueRootIndex) {
+    if (false_label_ != fall_through_) __ b(false_label_);
+  } else if (index == Heap::kTrueValueRootIndex) {
+    if (true_label_ != fall_through_) __ b(true_label_);
+  } else {
+    __ LoadRoot(result_register(), index);
+    codegen()->DoTest(this);
+  }
+}
+
+
+void FullCodeGenerator::EffectContext::Plug(Handle<Object> lit) const {}
+
+
+void FullCodeGenerator::AccumulatorValueContext::Plug(
+    Handle<Object> lit) const {
+  __ mov(result_register(), Operand(lit));
+}
+
+
+void FullCodeGenerator::StackValueContext::Plug(Handle<Object> lit) const {
+  // Immediates cannot be pushed directly.
+  __ mov(result_register(), Operand(lit));
+  __ push(result_register());
+}
+
+
+void FullCodeGenerator::TestContext::Plug(Handle<Object> lit) const {
+  codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_,
+                                          false_label_);
+  DCHECK(!lit->IsUndetectableObject());  // There are no undetectable literals.
+  if (lit->IsUndefined() || lit->IsNull() || lit->IsFalse()) {
+    if (false_label_ != fall_through_) __ b(false_label_);
+  } else if (lit->IsTrue() || lit->IsJSObject()) {
+    if (true_label_ != fall_through_) __ b(true_label_);
+  } else if (lit->IsString()) {
+    if (String::cast(*lit)->length() == 0) {
+      if (false_label_ != fall_through_) __ b(false_label_);
+    } else {
+      if (true_label_ != fall_through_) __ b(true_label_);
+    }
+  } else if (lit->IsSmi()) {
+    if (Smi::cast(*lit)->value() == 0) {
+      if (false_label_ != fall_through_) __ b(false_label_);
+    } else {
+      if (true_label_ != fall_through_) __ b(true_label_);
+    }
+  } else {
+    // For simplicity we always test the accumulator register.
+    __ mov(result_register(), Operand(lit));
+    codegen()->DoTest(this);
+  }
+}
+
+
+void FullCodeGenerator::EffectContext::DropAndPlug(int count,
+                                                   Register reg) const {
+  DCHECK(count > 0);
+  __ Drop(count);
+}
+
+
+void FullCodeGenerator::AccumulatorValueContext::DropAndPlug(
+    int count, Register reg) const {
+  DCHECK(count > 0);
+  __ Drop(count);
+  __ Move(result_register(), reg);
+}
+
+
+void FullCodeGenerator::StackValueContext::DropAndPlug(int count,
+                                                       Register reg) const {
+  DCHECK(count > 0);
+  if (count > 1) __ Drop(count - 1);
+  __ StoreP(reg, MemOperand(sp, 0));
+}
+
+
+void FullCodeGenerator::TestContext::DropAndPlug(int count,
+                                                 Register reg) const {
+  DCHECK(count > 0);
+  // For simplicity we always test the accumulator register.
+  __ Drop(count);
+  __ Move(result_register(), reg);
+  codegen()->PrepareForBailoutBeforeSplit(condition(), false, NULL, NULL);
+  codegen()->DoTest(this);
+}
+
+
+void FullCodeGenerator::EffectContext::Plug(Label* materialize_true,
+                                            Label* materialize_false) const {
+  DCHECK(materialize_true == materialize_false);
+  __ bind(materialize_true);
+}
+
+
+void FullCodeGenerator::AccumulatorValueContext::Plug(
+    Label* materialize_true, Label* materialize_false) const {
+  Label done;
+  __ bind(materialize_true);
+  __ LoadRoot(result_register(), Heap::kTrueValueRootIndex);
+  __ b(&done);
+  __ bind(materialize_false);
+  __ LoadRoot(result_register(), Heap::kFalseValueRootIndex);
+  __ bind(&done);
+}
+
+
+void FullCodeGenerator::StackValueContext::Plug(
+    Label* materialize_true, Label* materialize_false) const {
+  Label done;
+  __ bind(materialize_true);
+  __ LoadRoot(ip, Heap::kTrueValueRootIndex);
+  __ b(&done);
+  __ bind(materialize_false);
+  __ LoadRoot(ip, Heap::kFalseValueRootIndex);
+  __ bind(&done);
+  __ push(ip);
+}
+
+
+void FullCodeGenerator::TestContext::Plug(Label* materialize_true,
+                                          Label* materialize_false) const {
+  DCHECK(materialize_true == true_label_);
+  DCHECK(materialize_false == false_label_);
+}
+
+
+void FullCodeGenerator::EffectContext::Plug(bool flag) const {}
+
+
+void FullCodeGenerator::AccumulatorValueContext::Plug(bool flag) const {
+  Heap::RootListIndex value_root_index =
+      flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
+  __ LoadRoot(result_register(), value_root_index);
+}
+
+
+void FullCodeGenerator::StackValueContext::Plug(bool flag) const {
+  Heap::RootListIndex value_root_index =
+      flag ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex;
+  __ LoadRoot(ip, value_root_index);
+  __ push(ip);
+}
+
+
+void FullCodeGenerator::TestContext::Plug(bool flag) const {
+  codegen()->PrepareForBailoutBeforeSplit(condition(), true, true_label_,
+                                          false_label_);
+  if (flag) {
+    if (true_label_ != fall_through_) __ b(true_label_);
+  } else {
+    if (false_label_ != fall_through_) __ b(false_label_);
+  }
+}
+
+
+void FullCodeGenerator::DoTest(Expression* condition, Label* if_true,
+                               Label* if_false, Label* fall_through) {
+  Handle<Code> ic = ToBooleanStub::GetUninitialized(isolate());
+  CallIC(ic, condition->test_id());
+  __ cmpi(result_register(), Operand::Zero());
+  Split(ne, if_true, if_false, fall_through);
+}
+
+
+void FullCodeGenerator::Split(Condition cond, Label* if_true, Label* if_false,
+                              Label* fall_through, CRegister cr) {
+  if (if_false == fall_through) {
+    __ b(cond, if_true, cr);
+  } else if (if_true == fall_through) {
+    __ b(NegateCondition(cond), if_false, cr);
+  } else {
+    __ b(cond, if_true, cr);
+    __ b(if_false);
+  }
+}
+
+
+MemOperand FullCodeGenerator::StackOperand(Variable* var) {
+  DCHECK(var->IsStackAllocated());
+  // Offset is negative because higher indexes are at lower addresses.
+  int offset = -var->index() * kPointerSize;
+  // Adjust by a (parameter or local) base offset.
+  if (var->IsParameter()) {
+    offset += (info_->scope()->num_parameters() + 1) * kPointerSize;
+  } else {
+    offset += JavaScriptFrameConstants::kLocal0Offset;
+  }
+  return MemOperand(fp, offset);
+}
+
+
+MemOperand FullCodeGenerator::VarOperand(Variable* var, Register scratch) {
+  DCHECK(var->IsContextSlot() || var->IsStackAllocated());
+  if (var->IsContextSlot()) {
+    int context_chain_length = scope()->ContextChainLength(var->scope());
+    __ LoadContext(scratch, context_chain_length);
+    return ContextOperand(scratch, var->index());
+  } else {
+    return StackOperand(var);
+  }
+}
+
+
+void FullCodeGenerator::GetVar(Register dest, Variable* var) {
+  // Use destination as scratch.
+  MemOperand location = VarOperand(var, dest);
+  __ LoadP(dest, location, r0);
+}
+
+
+void FullCodeGenerator::SetVar(Variable* var, Register src, Register scratch0,
+                               Register scratch1) {
+  DCHECK(var->IsContextSlot() || var->IsStackAllocated());
+  DCHECK(!scratch0.is(src));
+  DCHECK(!scratch0.is(scratch1));
+  DCHECK(!scratch1.is(src));
+  MemOperand location = VarOperand(var, scratch0);
+  __ StoreP(src, location, r0);
+
+  // Emit the write barrier code if the location is in the heap.
+  if (var->IsContextSlot()) {
+    __ RecordWriteContextSlot(scratch0, location.offset(), src, scratch1,
+                              kLRHasBeenSaved, kDontSaveFPRegs);
+  }
+}
+
+
+void FullCodeGenerator::PrepareForBailoutBeforeSplit(Expression* expr,
+                                                     bool should_normalize,
+                                                     Label* if_true,
+                                                     Label* if_false) {
+  // Only prepare for bailouts before splits if we're in a test
+  // context. Otherwise, we let the Visit function deal with the
+  // preparation to avoid preparing with the same AST id twice.
+  if (!context()->IsTest() || !info_->IsOptimizable()) return;
+
+  Label skip;
+  if (should_normalize) __ b(&skip);
+  PrepareForBailout(expr, TOS_REG);
+  if (should_normalize) {
+    __ LoadRoot(ip, Heap::kTrueValueRootIndex);
+    __ cmp(r3, ip);
+    Split(eq, if_true, if_false, NULL);
+    __ bind(&skip);
+  }
+}
+
+
+void FullCodeGenerator::EmitDebugCheckDeclarationContext(Variable* variable) {
+  // The variable in the declaration always resides in the current function
+  // context.
+  DCHECK_EQ(0, scope()->ContextChainLength(variable->scope()));
+  if (generate_debug_code_) {
+    // Check that we're not inside a with or catch context.
+    __ LoadP(r4, FieldMemOperand(cp, HeapObject::kMapOffset));
+    __ CompareRoot(r4, Heap::kWithContextMapRootIndex);
+    __ Check(ne, kDeclarationInWithContext);
+    __ CompareRoot(r4, Heap::kCatchContextMapRootIndex);
+    __ Check(ne, kDeclarationInCatchContext);
+  }
+}
+
+
+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 hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
+  switch (variable->location()) {
+    case Variable::UNALLOCATED:
+      globals_->Add(variable->name(), zone());
+      globals_->Add(variable->binding_needs_init()
+                        ? isolate()->factory()->the_hole_value()
+                        : isolate()->factory()->undefined_value(),
+                    zone());
+      break;
+
+    case Variable::PARAMETER:
+    case Variable::LOCAL:
+      if (hole_init) {
+        Comment cmnt(masm_, "[ VariableDeclaration");
+        __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+        __ StoreP(ip, StackOperand(variable));
+      }
+      break;
+
+    case Variable::CONTEXT:
+      if (hole_init) {
+        Comment cmnt(masm_, "[ VariableDeclaration");
+        EmitDebugCheckDeclarationContext(variable);
+        __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+        __ StoreP(ip, ContextOperand(cp, variable->index()), r0);
+        // No write barrier since the_hole_value is in old space.
+        PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
+      }
+      break;
+
+    case Variable::LOOKUP: {
+      Comment cmnt(masm_, "[ VariableDeclaration");
+      __ mov(r5, Operand(variable->name()));
+      // Declaration nodes are always introduced in one of four modes.
+      DCHECK(IsDeclaredVariableMode(mode));
+      PropertyAttributes attr =
+          IsImmutableVariableMode(mode) ? READ_ONLY : NONE;
+      __ LoadSmiLiteral(r4, Smi::FromInt(attr));
+      // Push initial value, if any.
+      // Note: For variables we must not push an initial value (such as
+      // 'undefined') because we may have a (legal) redeclaration and we
+      // must not destroy the current value.
+      if (hole_init) {
+        __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
+        __ Push(cp, r5, r4, r3);
+      } else {
+        __ LoadSmiLiteral(r3, Smi::FromInt(0));  // Indicates no initial value.
+        __ Push(cp, r5, r4, r3);
+      }
+      __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
+      break;
+    }
+  }
+}
+
+
+void FullCodeGenerator::VisitFunctionDeclaration(
+    FunctionDeclaration* declaration) {
+  VariableProxy* proxy = declaration->proxy();
+  Variable* variable = proxy->var();
+  switch (variable->location()) {
+    case Variable::UNALLOCATED: {
+      globals_->Add(variable->name(), zone());
+      Handle<SharedFunctionInfo> function =
+          Compiler::BuildFunctionInfo(declaration->fun(), script(), info_);
+      // Check for stack-overflow exception.
+      if (function.is_null()) return SetStackOverflow();
+      globals_->Add(function, zone());
+      break;
+    }
+
+    case Variable::PARAMETER:
+    case Variable::LOCAL: {
+      Comment cmnt(masm_, "[ FunctionDeclaration");
+      VisitForAccumulatorValue(declaration->fun());
+      __ StoreP(result_register(), StackOperand(variable));
+      break;
+    }
+
+    case Variable::CONTEXT: {
+      Comment cmnt(masm_, "[ FunctionDeclaration");
+      EmitDebugCheckDeclarationContext(variable);
+      VisitForAccumulatorValue(declaration->fun());
+      __ StoreP(result_register(), ContextOperand(cp, variable->index()), r0);
+      int offset = Context::SlotOffset(variable->index());
+      // We know that we have written a function, which is not a smi.
+      __ RecordWriteContextSlot(cp, offset, result_register(), r5,
+                                kLRHasBeenSaved, kDontSaveFPRegs,
+                                EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+      PrepareForBailoutForId(proxy->id(), NO_REGISTERS);
+      break;
+    }
+
+    case Variable::LOOKUP: {
+      Comment cmnt(masm_, "[ FunctionDeclaration");
+      __ mov(r5, Operand(variable->name()));
+      __ LoadSmiLiteral(r4, Smi::FromInt(NONE));
+      __ Push(cp, r5, r4);
+      // Push initial value for function declaration.
+      VisitForStackValue(declaration->fun());
+      __ CallRuntime(Runtime::kDeclareLookupSlot, 4);
+      break;
+    }
+  }
+}
+
+
+void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
+  Variable* variable = declaration->proxy()->var();
+  DCHECK(variable->location() == Variable::CONTEXT);
+  DCHECK(variable->interface()->IsFrozen());
+
+  Comment cmnt(masm_, "[ ModuleDeclaration");
+  EmitDebugCheckDeclarationContext(variable);
+
+  // Load instance object.
+  __ LoadContext(r4, scope_->ContextChainLength(scope_->ScriptScope()));
+  __ LoadP(r4, ContextOperand(r4, variable->interface()->Index()));
+  __ LoadP(r4, ContextOperand(r4, Context::EXTENSION_INDEX));
+
+  // Assign it.
+  __ StoreP(r4, ContextOperand(cp, variable->index()), r0);
+  // We know that we have written a module, which is not a smi.
+  __ RecordWriteContextSlot(cp, Context::SlotOffset(variable->index()), r4, r6,
+                            kLRHasBeenSaved, kDontSaveFPRegs,
+                            EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
+  PrepareForBailoutForId(declaration->proxy()->id(), NO_REGISTERS);
+
+  // Traverse into body.
+  Visit(declaration->module());
+}
+
+
+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.
+  __ mov(r4, Operand(pairs));
+  __ LoadSmiLiteral(r3, Smi::FromInt(DeclareGlobalsFlags()));
+  __ Push(cp, r4, r3);
+  __ CallRuntime(Runtime::kDeclareGlobals, 3);
+  // Return value is ignored.
+}
+
+
+void FullCodeGenerator::DeclareModules(Handle<FixedArray> descriptions) {
+  // Call the runtime to declare the modules.
+  __ Push(descriptions);
+  __ CallRuntime(Runtime::kDeclareModules, 1);
+  // Return value is ignored.
+}
+
+
+void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
+  Comment cmnt(masm_, "[ SwitchStatement");
+  Breakable nested_statement(this, stmt);
+  SetStatementPosition(stmt);
+
+  // Keep the switch value on the stack until a case matches.
+  VisitForStackValue(stmt->tag());
+  PrepareForBailoutForId(stmt->EntryId(), NO_REGISTERS);
+
+  ZoneList<CaseClause*>* clauses = stmt->cases();
+  CaseClause* default_clause = NULL;  // Can occur anywhere in the list.
+
+  Label next_test;  // Recycled for each test.
+  // Compile all the tests with branches to their bodies.
+  for (int i = 0; i < clauses->length(); i++) {
+    CaseClause* clause = clauses->at(i);
+    clause->body_target()->Unuse();
+
+    // The default is not a test, but remember it as final fall through.
+    if (clause->is_default()) {
+      default_clause = clause;
+      continue;
+    }
+
+    Comment cmnt(masm_, "[ Case comparison");
+    __ bind(&next_test);
+    next_test.Unuse();
+
+    // Compile the label expression.
+    VisitForAccumulatorValue(clause->label());
+
+    // Perform the comparison as if via '==='.
+    __ LoadP(r4, MemOperand(sp, 0));  // Switch value.
+    bool inline_smi_code = ShouldInlineSmiCase(Token::EQ_STRICT);
+    JumpPatchSite patch_site(masm_);
+    if (inline_smi_code) {
+      Label slow_case;
+      __ orx(r5, r4, r3);
+      patch_site.EmitJumpIfNotSmi(r5, &slow_case);
+
+      __ cmp(r4, r3);
+      __ bne(&next_test);
+      __ Drop(1);  // Switch value is no longer needed.
+      __ b(clause->body_target());
+      __ bind(&slow_case);
+    }
+
+    // Record position before stub call for type feedback.
+    SetSourcePosition(clause->position());
+    Handle<Code> ic =
+        CodeFactory::CompareIC(isolate(), Token::EQ_STRICT).code();
+    CallIC(ic, clause->CompareId());
+    patch_site.EmitPatchInfo();
+
+    Label skip;
+    __ b(&skip);
+    PrepareForBailout(clause, TOS_REG);
+    __ LoadRoot(ip, Heap::kTrueValueRootIndex);
+    __ cmp(r3, ip);
+    __ bne(&next_test);
+    __ Drop(1);
+    __ b(clause->body_target());
+    __ bind(&skip);
+
+    __ cmpi(r3, Operand::Zero());
+    __ bne(&next_test);
+    __ Drop(1);  // Switch value is no longer needed.
+    __ b(clause->body_target());
+  }
+
+  // Discard the test value and jump to the default if present, otherwise to
+  // the end of the statement.
+  __ bind(&next_test);
+  __ Drop(1);  // Switch value is no longer needed.
+  if (default_clause == NULL) {
+    __ b(nested_statement.break_label());
+  } else {
+    __ b(default_clause->body_target());
+  }
+
+  // Compile all the case bodies.
+  for (int i = 0; i < clauses->length(); i++) {
+    Comment cmnt(masm_, "[ Case body");
+    CaseClause* clause = clauses->at(i);
+    __ bind(clause->body_target());
+    PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
+    VisitStatements(clause->statements());
+  }
+
+  __ bind(nested_statement.break_label());
+  PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
+}
+
+
+void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
+  Comment cmnt(masm_, "[ ForInStatement");
+  FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
+  SetStatementPosition(stmt);
+
+  Label loop, exit;
+  ForIn loop_statement(this, stmt);
+  increment_loop_depth();
+
+  // Get the object to enumerate over. If the object is null or undefined, skip
+  // over the loop.  See ECMA-262 version 5, section 12.6.4.
+  VisitForAccumulatorValue(stmt->enumerable());
+  __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+  __ cmp(r3, ip);
+  __ beq(&exit);
+  Register null_value = r7;
+  __ LoadRoot(null_value, Heap::kNullValueRootIndex);
+  __ cmp(r3, null_value);
+  __ beq(&exit);
+
+  PrepareForBailoutForId(stmt->PrepareId(), TOS_REG);
+
+  // Convert the object to a JS object.
+  Label convert, done_convert;
+  __ JumpIfSmi(r3, &convert);
+  __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE);
+  __ bge(&done_convert);
+  __ bind(&convert);
+  __ push(r3);
+  __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
+  __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
+  __ push(r3);
+
+  // Check for proxies.
+  Label call_runtime;
+  STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
+  __ CompareObjectType(r3, r4, r4, LAST_JS_PROXY_TYPE);
+  __ ble(&call_runtime);
+
+  // Check cache validity in generated code. This is a fast case for
+  // the JSObject::IsSimpleEnum cache validity checks. If we cannot
+  // guarantee cache validity, call the runtime system to check cache
+  // validity or get the property names in a fixed array.
+  __ CheckEnumCache(null_value, &call_runtime);
+
+  // The enum cache is valid.  Load the map of the object being
+  // iterated over and use the cache for the iteration.
+  Label use_cache;
+  __ LoadP(r3, FieldMemOperand(r3, HeapObject::kMapOffset));
+  __ b(&use_cache);
+
+  // Get the set of properties to enumerate.
+  __ bind(&call_runtime);
+  __ push(r3);  // Duplicate the enumerable object on the stack.
+  __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
+
+  // If we got a map from the runtime call, we can do a fast
+  // modification check. Otherwise, we got a fixed array, and we have
+  // to do a slow check.
+  Label fixed_array;
+  __ LoadP(r5, FieldMemOperand(r3, HeapObject::kMapOffset));
+  __ LoadRoot(ip, Heap::kMetaMapRootIndex);
+  __ cmp(r5, ip);
+  __ bne(&fixed_array);
+
+  // We got a map in register r3. Get the enumeration cache from it.
+  Label no_descriptors;
+  __ bind(&use_cache);
+
+  __ EnumLength(r4, r3);
+  __ CmpSmiLiteral(r4, Smi::FromInt(0), r0);
+  __ beq(&no_descriptors);
+
+  __ LoadInstanceDescriptors(r3, r5);
+  __ LoadP(r5, FieldMemOperand(r5, DescriptorArray::kEnumCacheOffset));
+  __ LoadP(r5,
+           FieldMemOperand(r5, DescriptorArray::kEnumCacheBridgeCacheOffset));
+
+  // Set up the four remaining stack slots.
+  __ push(r3);  // Map.
+  __ LoadSmiLiteral(r3, Smi::FromInt(0));
+  // Push enumeration cache, enumeration cache length (as smi) and zero.
+  __ Push(r5, r4, r3);
+  __ b(&loop);
+
+  __ bind(&no_descriptors);
+  __ Drop(1);
+  __ b(&exit);
+
+  // We got a fixed array in register r3. Iterate through that.
+  Label non_proxy;
+  __ bind(&fixed_array);
+
+  __ Move(r4, FeedbackVector());
+  __ mov(r5, Operand(TypeFeedbackVector::MegamorphicSentinel(isolate())));
+  int vector_index = FeedbackVector()->GetIndex(slot);
+  __ StoreP(
+      r5, FieldMemOperand(r4, FixedArray::OffsetOfElementAt(vector_index)), r0);
+
+  __ LoadSmiLiteral(r4, Smi::FromInt(1));          // Smi indicates slow check
+  __ LoadP(r5, MemOperand(sp, 0 * kPointerSize));  // Get enumerated object
+  STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
+  __ CompareObjectType(r5, r6, r6, LAST_JS_PROXY_TYPE);
+  __ bgt(&non_proxy);
+  __ LoadSmiLiteral(r4, Smi::FromInt(0));  // Zero indicates proxy
+  __ bind(&non_proxy);
+  __ Push(r4, r3);  // Smi and array
+  __ LoadP(r4, FieldMemOperand(r3, FixedArray::kLengthOffset));
+  __ LoadSmiLiteral(r3, Smi::FromInt(0));
+  __ Push(r4, r3);  // Fixed array length (as smi) and initial index.
+
+  // Generate code for doing the condition check.
+  PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
+  __ bind(&loop);
+  // Load the current count to r3, load the length to r4.
+  __ LoadP(r3, MemOperand(sp, 0 * kPointerSize));
+  __ LoadP(r4, MemOperand(sp, 1 * kPointerSize));
+  __ cmpl(r3, r4);  // Compare to the array length.
+  __ bge(loop_statement.break_label());
+
+  // Get the current entry of the array into register r6.
+  __ LoadP(r5, MemOperand(sp, 2 * kPointerSize));
+  __ addi(r5, r5, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ SmiToPtrArrayOffset(r6, r3);
+  __ LoadPX(r6, MemOperand(r6, r5));
+
+  // Get the expected map from the stack or a smi in the
+  // permanent slow case into register r5.
+  __ LoadP(r5, MemOperand(sp, 3 * kPointerSize));
+
+  // Check if the expected map still matches that of the enumerable.
+  // If not, we may have to filter the key.
+  Label update_each;
+  __ LoadP(r4, MemOperand(sp, 4 * kPointerSize));
+  __ LoadP(r7, FieldMemOperand(r4, HeapObject::kMapOffset));
+  __ cmp(r7, r5);
+  __ beq(&update_each);
+
+  // For proxies, no filtering is done.
+  // TODO(rossberg): What if only a prototype is a proxy? Not specified yet.
+  __ CmpSmiLiteral(r5, Smi::FromInt(0), r0);
+  __ beq(&update_each);
+
+  // Convert the entry to a string or (smi) 0 if it isn't a property
+  // any more. If the property has been removed while iterating, we
+  // just skip it.
+  __ Push(r4, r6);  // Enumerable and current entry.
+  __ InvokeBuiltin(Builtins::FILTER_KEY, CALL_FUNCTION);
+  __ mr(r6, r3);
+  __ cmpi(r6, Operand::Zero());
+  __ beq(loop_statement.continue_label());
+
+  // Update the 'each' property or variable from the possibly filtered
+  // entry in register r6.
+  __ bind(&update_each);
+  __ mr(result_register(), r6);
+  // Perform the assignment as if via '='.
+  {
+    EffectContext context(this);
+    EmitAssignment(stmt->each());
+  }
+
+  // Generate code for the body of the loop.
+  Visit(stmt->body());
+
+  // Generate code for the going to the next element by incrementing
+  // the index (smi) stored on top of the stack.
+  __ bind(loop_statement.continue_label());
+  __ pop(r3);
+  __ AddSmiLiteral(r3, r3, Smi::FromInt(1), r0);
+  __ push(r3);
+
+  EmitBackEdgeBookkeeping(stmt, &loop);
+  __ b(&loop);
+
+  // Remove the pointers stored on the stack.
+  __ bind(loop_statement.break_label());
+  __ Drop(5);
+
+  // Exit and decrement the loop depth.
+  PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
+  __ bind(&exit);
+  decrement_loop_depth();
+}
+
+
+void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
+  Comment cmnt(masm_, "[ ForOfStatement");
+  SetStatementPosition(stmt);
+
+  Iteration loop_statement(this, stmt);
+  increment_loop_depth();
+
+  // var iterator = iterable[Symbol.iterator]();
+  VisitForEffect(stmt->assign_iterator());
+
+  // Loop entry.
+  __ bind(loop_statement.continue_label());
+
+  // result = iterator.next()
+  VisitForEffect(stmt->next_result());
+
+  // if (result.done) break;
+  Label result_not_done;
+  VisitForControl(stmt->result_done(), loop_statement.break_label(),
+                  &result_not_done, &result_not_done);
+  __ bind(&result_not_done);
+
+  // each = result.value
+  VisitForEffect(stmt->assign_each());
+
+  // Generate code for the body of the loop.
+  Visit(stmt->body());
+
+  // Check stack before looping.
+  PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
+  EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
+  __ b(loop_statement.continue_label());
+
+  // Exit and decrement the loop depth.
+  PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
+  __ bind(loop_statement.break_label());
+  decrement_loop_depth();
+}
+
+
+void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
+                                       bool pretenure) {
+  // Use the fast case closure allocation code that allocates in new
+  // space for nested functions that don't need literals cloning. If
+  // we're running with the --always-opt or the --prepare-always-opt
+  // flag, we need to use the runtime function so that the new function
+  // we are creating here gets a chance to have its code optimized and
+  // doesn't just get a copy of the existing unoptimized code.
+  if (!FLAG_always_opt && !FLAG_prepare_always_opt && !pretenure &&
+      scope()->is_function_scope() && info->num_literals() == 0) {
+    FastNewClosureStub stub(isolate(), info->strict_mode(), info->kind());
+    __ mov(r5, Operand(info));
+    __ CallStub(&stub);
+  } else {
+    __ mov(r3, Operand(info));
+    __ LoadRoot(
+        r4, pretenure ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex);
+    __ Push(cp, r3, r4);
+    __ CallRuntime(Runtime::kNewClosure, 3);
+  }
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::VisitVariableProxy(VariableProxy* expr) {
+  Comment cmnt(masm_, "[ VariableProxy");
+  EmitVariableLoad(expr);
+}
+
+
+void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
+  Comment cnmt(masm_, "[ SuperReference ");
+
+  __ LoadP(LoadDescriptor::ReceiverRegister(),
+           MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+
+  Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
+  __ Move(LoadDescriptor::NameRegister(), home_object_symbol);
+
+  if (FLAG_vector_ics) {
+    __ mov(VectorLoadICDescriptor::SlotRegister(),
+           Operand(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
+    CallLoadIC(NOT_CONTEXTUAL);
+  } else {
+    CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  }
+
+  __ Cmpi(r3, Operand(isolate()->factory()->undefined_value()), r0);
+  Label done;
+  __ bne(&done);
+  __ CallRuntime(Runtime::kThrowNonMethodError, 0);
+  __ bind(&done);
+}
+
+
+void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
+                                                      TypeofState typeof_state,
+                                                      Label* slow) {
+  Register current = cp;
+  Register next = r4;
+  Register temp = r5;
+
+  Scope* s = scope();
+  while (s != NULL) {
+    if (s->num_heap_slots() > 0) {
+      if (s->calls_sloppy_eval()) {
+        // Check that extension is NULL.
+        __ LoadP(temp, ContextOperand(current, Context::EXTENSION_INDEX));
+        __ cmpi(temp, Operand::Zero());
+        __ bne(slow);
+      }
+      // Load next context in chain.
+      __ LoadP(next, ContextOperand(current, Context::PREVIOUS_INDEX));
+      // Walk the rest of the chain without clobbering cp.
+      current = next;
+    }
+    // If no outer scope calls eval, we do not need to check more
+    // context extensions.
+    if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break;
+    s = s->outer_scope();
+  }
+
+  if (s->is_eval_scope()) {
+    Label loop, fast;
+    if (!current.is(next)) {
+      __ Move(next, current);
+    }
+    __ bind(&loop);
+    // Terminate at native context.
+    __ LoadP(temp, FieldMemOperand(next, HeapObject::kMapOffset));
+    __ LoadRoot(ip, Heap::kNativeContextMapRootIndex);
+    __ cmp(temp, ip);
+    __ beq(&fast);
+    // Check that extension is NULL.
+    __ LoadP(temp, ContextOperand(next, Context::EXTENSION_INDEX));
+    __ cmpi(temp, Operand::Zero());
+    __ bne(slow);
+    // Load next context in chain.
+    __ LoadP(next, ContextOperand(next, Context::PREVIOUS_INDEX));
+    __ b(&loop);
+    __ bind(&fast);
+  }
+
+  __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
+  __ mov(LoadDescriptor::NameRegister(), Operand(proxy->var()->name()));
+  if (FLAG_vector_ics) {
+    __ mov(VectorLoadICDescriptor::SlotRegister(),
+           Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
+  }
+
+  ContextualMode mode =
+      (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL : CONTEXTUAL;
+  CallLoadIC(mode);
+}
+
+
+MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var,
+                                                                Label* slow) {
+  DCHECK(var->IsContextSlot());
+  Register context = cp;
+  Register next = r6;
+  Register temp = r7;
+
+  for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) {
+    if (s->num_heap_slots() > 0) {
+      if (s->calls_sloppy_eval()) {
+        // Check that extension is NULL.
+        __ LoadP(temp, ContextOperand(context, Context::EXTENSION_INDEX));
+        __ cmpi(temp, Operand::Zero());
+        __ bne(slow);
+      }
+      __ LoadP(next, ContextOperand(context, Context::PREVIOUS_INDEX));
+      // Walk the rest of the chain without clobbering cp.
+      context = next;
+    }
+  }
+  // Check that last extension is NULL.
+  __ LoadP(temp, ContextOperand(context, Context::EXTENSION_INDEX));
+  __ cmpi(temp, Operand::Zero());
+  __ bne(slow);
+
+  // This function is used only for loads, not stores, so it's safe to
+  // return an cp-based operand (the write barrier cannot be allowed to
+  // destroy the cp register).
+  return ContextOperand(context, var->index());
+}
+
+
+void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy,
+                                                  TypeofState typeof_state,
+                                                  Label* slow, Label* done) {
+  // Generate fast-case code for variables that might be shadowed by
+  // eval-introduced variables.  Eval is used a lot without
+  // introducing variables.  In those cases, we do not want to
+  // perform a runtime call for all variables in the scope
+  // containing the eval.
+  Variable* var = proxy->var();
+  if (var->mode() == DYNAMIC_GLOBAL) {
+    EmitLoadGlobalCheckExtensions(proxy, typeof_state, slow);
+    __ b(done);
+  } else if (var->mode() == DYNAMIC_LOCAL) {
+    Variable* local = var->local_if_not_shadowed();
+    __ LoadP(r3, ContextSlotOperandCheckExtensions(local, slow));
+    if (local->mode() == LET || local->mode() == CONST ||
+        local->mode() == CONST_LEGACY) {
+      __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
+      __ bne(done);
+      if (local->mode() == CONST_LEGACY) {
+        __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
+      } else {  // LET || CONST
+        __ mov(r3, Operand(var->name()));
+        __ push(r3);
+        __ CallRuntime(Runtime::kThrowReferenceError, 1);
+      }
+    }
+    __ b(done);
+  }
+}
+
+
+void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
+  // Record position before possible IC call.
+  SetSourcePosition(proxy->position());
+  Variable* var = proxy->var();
+
+  // Three cases: global variables, lookup variables, and all other types of
+  // variables.
+  switch (var->location()) {
+    case Variable::UNALLOCATED: {
+      Comment cmnt(masm_, "[ Global variable");
+      __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
+      __ mov(LoadDescriptor::NameRegister(), Operand(var->name()));
+      if (FLAG_vector_ics) {
+        __ mov(VectorLoadICDescriptor::SlotRegister(),
+               Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
+      }
+      CallLoadIC(CONTEXTUAL);
+      context()->Plug(r3);
+      break;
+    }
+
+    case Variable::PARAMETER:
+    case Variable::LOCAL:
+    case Variable::CONTEXT: {
+      Comment cmnt(masm_, var->IsContextSlot() ? "[ Context variable"
+                                               : "[ Stack variable");
+      if (var->binding_needs_init()) {
+        // var->scope() may be NULL when the proxy is located in eval code and
+        // refers to a potential outside binding. Currently those bindings are
+        // always looked up dynamically, i.e. in that case
+        //     var->location() == LOOKUP.
+        // always holds.
+        DCHECK(var->scope() != NULL);
+
+        // Check if the binding really needs an initialization check. The check
+        // can be skipped in the following situation: we have a LET or CONST
+        // binding in harmony mode, both the Variable and the VariableProxy have
+        // the same declaration scope (i.e. they are both in global code, in the
+        // same function or in the same eval code) and the VariableProxy is in
+        // the source physically located after the initializer of the variable.
+        //
+        // We cannot skip any initialization checks for CONST in non-harmony
+        // mode because const variables may be declared but never initialized:
+        //   if (false) { const x; }; var y = x;
+        //
+        // The condition on the declaration scopes is a conservative check for
+        // nested functions that access a binding and are called before the
+        // binding is initialized:
+        //   function() { f(); let x = 1; function f() { x = 2; } }
+        //
+        bool skip_init_check;
+        if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) {
+          skip_init_check = false;
+        } else {
+          // Check that we always have valid source position.
+          DCHECK(var->initializer_position() != RelocInfo::kNoPosition);
+          DCHECK(proxy->position() != RelocInfo::kNoPosition);
+          skip_init_check = var->mode() != CONST_LEGACY &&
+                            var->initializer_position() < proxy->position();
+        }
+
+        if (!skip_init_check) {
+          Label done;
+          // Let and const need a read barrier.
+          GetVar(r3, var);
+          __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
+          __ bne(&done);
+          if (var->mode() == LET || var->mode() == CONST) {
+            // Throw a reference error when using an uninitialized let/const
+            // binding in harmony mode.
+            __ mov(r3, Operand(var->name()));
+            __ push(r3);
+            __ CallRuntime(Runtime::kThrowReferenceError, 1);
+          } else {
+            // Uninitalized const bindings outside of harmony mode are unholed.
+            DCHECK(var->mode() == CONST_LEGACY);
+            __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
+          }
+          __ bind(&done);
+          context()->Plug(r3);
+          break;
+        }
+      }
+      context()->Plug(var);
+      break;
+    }
+
+    case Variable::LOOKUP: {
+      Comment cmnt(masm_, "[ Lookup variable");
+      Label done, slow;
+      // Generate code for loading from variables potentially shadowed
+      // by eval-introduced variables.
+      EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
+      __ bind(&slow);
+      __ mov(r4, Operand(var->name()));
+      __ Push(cp, r4);  // Context and name.
+      __ CallRuntime(Runtime::kLoadLookupSlot, 2);
+      __ bind(&done);
+      context()->Plug(r3);
+    }
+  }
+}
+
+
+void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
+  Comment cmnt(masm_, "[ RegExpLiteral");
+  Label materialized;
+  // Registers will be used as follows:
+  // r8 = materialized value (RegExp literal)
+  // r7 = JS function, literals array
+  // r6 = literal index
+  // r5 = RegExp pattern
+  // r4 = RegExp flags
+  // r3 = RegExp literal clone
+  __ LoadP(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ LoadP(r7, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
+  int literal_offset =
+      FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
+  __ LoadP(r8, FieldMemOperand(r7, literal_offset), r0);
+  __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+  __ cmp(r8, ip);
+  __ bne(&materialized);
+
+  // Create regexp literal using runtime function.
+  // Result will be in r3.
+  __ LoadSmiLiteral(r6, Smi::FromInt(expr->literal_index()));
+  __ mov(r5, Operand(expr->pattern()));
+  __ mov(r4, Operand(expr->flags()));
+  __ Push(r7, r6, r5, r4);
+  __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
+  __ mr(r8, r3);
+
+  __ bind(&materialized);
+  int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
+  Label allocated, runtime_allocate;
+  __ Allocate(size, r3, r5, r6, &runtime_allocate, TAG_OBJECT);
+  __ b(&allocated);
+
+  __ bind(&runtime_allocate);
+  __ LoadSmiLiteral(r3, Smi::FromInt(size));
+  __ Push(r8, r3);
+  __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
+  __ pop(r8);
+
+  __ bind(&allocated);
+  // After this, registers are used as follows:
+  // r3: Newly allocated regexp.
+  // r8: Materialized regexp.
+  // r5: temp.
+  __ CopyFields(r3, r8, r5.bit(), size / kPointerSize);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitAccessor(Expression* expression) {
+  if (expression == NULL) {
+    __ LoadRoot(r4, Heap::kNullValueRootIndex);
+    __ push(r4);
+  } else {
+    VisitForStackValue(expression);
+  }
+}
+
+
+void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
+  Comment cmnt(masm_, "[ ObjectLiteral");
+
+  expr->BuildConstantProperties(isolate());
+  Handle<FixedArray> constant_properties = expr->constant_properties();
+  __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ LoadP(r6, FieldMemOperand(r6, JSFunction::kLiteralsOffset));
+  __ LoadSmiLiteral(r5, Smi::FromInt(expr->literal_index()));
+  __ mov(r4, Operand(constant_properties));
+  int flags = expr->fast_elements() ? ObjectLiteral::kFastElements
+                                    : ObjectLiteral::kNoFlags;
+  flags |= expr->has_function() ? ObjectLiteral::kHasFunction
+                                : ObjectLiteral::kNoFlags;
+  __ LoadSmiLiteral(r3, Smi::FromInt(flags));
+  int properties_count = constant_properties->length() / 2;
+  if (expr->may_store_doubles() || expr->depth() > 1 ||
+      masm()->serializer_enabled() || flags != ObjectLiteral::kFastElements ||
+      properties_count > FastCloneShallowObjectStub::kMaximumClonedProperties) {
+    __ Push(r6, r5, r4, r3);
+    __ CallRuntime(Runtime::kCreateObjectLiteral, 4);
+  } else {
+    FastCloneShallowObjectStub stub(isolate(), properties_count);
+    __ CallStub(&stub);
+  }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
+
+  // If result_saved is true the result is on top of the stack.  If
+  // result_saved is false the result is in r3.
+  bool result_saved = false;
+
+  // Mark all computed expressions that are bound to a key that
+  // is shadowed by a later occurrence of the same key. For the
+  // marked expressions, no store code is emitted.
+  expr->CalculateEmitStore(zone());
+
+  AccessorTable accessor_table(zone());
+  for (int i = 0; i < expr->properties()->length(); i++) {
+    ObjectLiteral::Property* property = expr->properties()->at(i);
+    if (property->IsCompileTimeValue()) continue;
+
+    Literal* key = property->key();
+    Expression* value = property->value();
+    if (!result_saved) {
+      __ push(r3);  // Save result on stack
+      result_saved = true;
+    }
+    switch (property->kind()) {
+      case ObjectLiteral::Property::CONSTANT:
+        UNREACHABLE();
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+        DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
+      // Fall through.
+      case ObjectLiteral::Property::COMPUTED:
+        // It is safe to use [[Put]] here because the boilerplate already
+        // contains computed properties with an uninitialized value.
+        if (key->value()->IsInternalizedString()) {
+          if (property->emit_store()) {
+            VisitForAccumulatorValue(value);
+            DCHECK(StoreDescriptor::ValueRegister().is(r3));
+            __ mov(StoreDescriptor::NameRegister(), Operand(key->value()));
+            __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
+            CallStoreIC(key->LiteralFeedbackId());
+            PrepareForBailoutForId(key->id(), NO_REGISTERS);
+          } else {
+            VisitForEffect(value);
+          }
+          break;
+        }
+        // Duplicate receiver on stack.
+        __ LoadP(r3, MemOperand(sp));
+        __ push(r3);
+        VisitForStackValue(key);
+        VisitForStackValue(value);
+        if (property->emit_store()) {
+          __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY));  // PropertyAttributes
+          __ push(r3);
+          __ CallRuntime(Runtime::kSetProperty, 4);
+        } else {
+          __ Drop(3);
+        }
+        break;
+      case ObjectLiteral::Property::PROTOTYPE:
+        // Duplicate receiver on stack.
+        __ LoadP(r3, MemOperand(sp));
+        __ push(r3);
+        VisitForStackValue(value);
+        if (property->emit_store()) {
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
+        } else {
+          __ Drop(2);
+        }
+        break;
+      case ObjectLiteral::Property::GETTER:
+        accessor_table.lookup(key)->second->getter = value;
+        break;
+      case ObjectLiteral::Property::SETTER:
+        accessor_table.lookup(key)->second->setter = value;
+        break;
+    }
+  }
+
+  // Emit code to define accessors, using only a single call to the runtime for
+  // each pair of corresponding getters and setters.
+  for (AccessorTable::Iterator it = accessor_table.begin();
+       it != accessor_table.end(); ++it) {
+    __ LoadP(r3, MemOperand(sp));  // Duplicate receiver.
+    __ push(r3);
+    VisitForStackValue(it->first);
+    EmitAccessor(it->second->getter);
+    EmitAccessor(it->second->setter);
+    __ LoadSmiLiteral(r3, Smi::FromInt(NONE));
+    __ push(r3);
+    __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
+  }
+
+  if (expr->has_function()) {
+    DCHECK(result_saved);
+    __ LoadP(r3, MemOperand(sp));
+    __ push(r3);
+    __ CallRuntime(Runtime::kToFastProperties, 1);
+  }
+
+  if (result_saved) {
+    context()->PlugTOS();
+  } else {
+    context()->Plug(r3);
+  }
+}
+
+
+void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
+  Comment cmnt(masm_, "[ ArrayLiteral");
+
+  expr->BuildConstantElements(isolate());
+  int flags = expr->depth() == 1 ? ArrayLiteral::kShallowElements
+                                 : ArrayLiteral::kNoFlags;
+
+  ZoneList<Expression*>* subexprs = expr->values();
+  int length = subexprs->length();
+  Handle<FixedArray> constant_elements = expr->constant_elements();
+  DCHECK_EQ(2, constant_elements->length());
+  ElementsKind constant_elements_kind =
+      static_cast<ElementsKind>(Smi::cast(constant_elements->get(0))->value());
+  bool has_fast_elements = IsFastObjectElementsKind(constant_elements_kind);
+  Handle<FixedArrayBase> constant_elements_values(
+      FixedArrayBase::cast(constant_elements->get(1)));
+
+  AllocationSiteMode allocation_site_mode = TRACK_ALLOCATION_SITE;
+  if (has_fast_elements && !FLAG_allocation_site_pretenuring) {
+    // If the only customer of allocation sites is transitioning, then
+    // we can turn it off if we don't have anywhere else to transition to.
+    allocation_site_mode = DONT_TRACK_ALLOCATION_SITE;
+  }
+
+  __ LoadP(r6, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ LoadP(r6, FieldMemOperand(r6, JSFunction::kLiteralsOffset));
+  __ LoadSmiLiteral(r5, Smi::FromInt(expr->literal_index()));
+  __ mov(r4, Operand(constant_elements));
+  if (expr->depth() > 1 || length > JSObject::kInitialMaxFastElementArray) {
+    __ LoadSmiLiteral(r3, Smi::FromInt(flags));
+    __ Push(r6, r5, r4, r3);
+    __ CallRuntime(Runtime::kCreateArrayLiteral, 4);
+  } else {
+    FastCloneShallowArrayStub stub(isolate(), allocation_site_mode);
+    __ CallStub(&stub);
+  }
+
+  bool result_saved = false;  // Is the result saved to the stack?
+
+  // Emit code to evaluate all the non-constant subexpressions and to store
+  // them into the newly cloned array.
+  for (int i = 0; i < length; i++) {
+    Expression* subexpr = subexprs->at(i);
+    // If the subexpression is a literal or a simple materialized literal it
+    // is already set in the cloned array.
+    if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue;
+
+    if (!result_saved) {
+      __ push(r3);
+      __ Push(Smi::FromInt(expr->literal_index()));
+      result_saved = true;
+    }
+    VisitForAccumulatorValue(subexpr);
+
+    if (IsFastObjectElementsKind(constant_elements_kind)) {
+      int offset = FixedArray::kHeaderSize + (i * kPointerSize);
+      __ LoadP(r8, MemOperand(sp, kPointerSize));  // Copy of array literal.
+      __ LoadP(r4, FieldMemOperand(r8, JSObject::kElementsOffset));
+      __ StoreP(result_register(), FieldMemOperand(r4, offset), r0);
+      // Update the write barrier for the array store.
+      __ RecordWriteField(r4, offset, result_register(), r5, kLRHasBeenSaved,
+                          kDontSaveFPRegs, EMIT_REMEMBERED_SET,
+                          INLINE_SMI_CHECK);
+    } else {
+      __ LoadSmiLiteral(r6, Smi::FromInt(i));
+      StoreArrayLiteralElementStub stub(isolate());
+      __ CallStub(&stub);
+    }
+
+    PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
+  }
+
+  if (result_saved) {
+    __ pop();  // literal index
+    context()->PlugTOS();
+  } else {
+    context()->Plug(r3);
+  }
+}
+
+
+void FullCodeGenerator::VisitAssignment(Assignment* expr) {
+  DCHECK(expr->target()->IsValidReferenceExpression());
+
+  Comment cmnt(masm_, "[ Assignment");
+
+  Property* property = expr->target()->AsProperty();
+  LhsKind assign_type = GetAssignType(property);
+
+  // Evaluate LHS expression.
+  switch (assign_type) {
+    case VARIABLE:
+      // Nothing to do here.
+      break;
+    case NAMED_PROPERTY:
+      if (expr->is_compound()) {
+        // We need the receiver both on the stack and in the register.
+        VisitForStackValue(property->obj());
+        __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
+      } else {
+        VisitForStackValue(property->obj());
+      }
+      break;
+    case NAMED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        const Register scratch = r4;
+        __ LoadP(scratch, MemOperand(sp, kPointerSize));
+        __ Push(scratch, result_register());
+      }
+      break;
+    case KEYED_SUPER_PROPERTY: {
+      const Register scratch = r4;
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Move(scratch, result_register());
+      VisitForAccumulatorValue(property->key());
+      __ Push(scratch, result_register());
+      if (expr->is_compound()) {
+        const Register scratch1 = r5;
+        __ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch1, scratch, result_register());
+      }
+      break;
+    }
+    case KEYED_PROPERTY:
+      if (expr->is_compound()) {
+        VisitForStackValue(property->obj());
+        VisitForStackValue(property->key());
+        __ LoadP(LoadDescriptor::ReceiverRegister(),
+                 MemOperand(sp, 1 * kPointerSize));
+        __ LoadP(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
+      } else {
+        VisitForStackValue(property->obj());
+        VisitForStackValue(property->key());
+      }
+      break;
+  }
+
+  // For compound assignments we need another deoptimization point after the
+  // variable/property load.
+  if (expr->is_compound()) {
+    {
+      AccumulatorValueContext context(this);
+      switch (assign_type) {
+        case VARIABLE:
+          EmitVariableLoad(expr->target()->AsVariableProxy());
+          PrepareForBailout(expr->target(), TOS_REG);
+          break;
+        case NAMED_PROPERTY:
+          EmitNamedPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
+        case NAMED_SUPER_PROPERTY:
+          EmitNamedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
+        case KEYED_SUPER_PROPERTY:
+          EmitKeyedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
+        case KEYED_PROPERTY:
+          EmitKeyedPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
+      }
+    }
+
+    Token::Value op = expr->binary_op();
+    __ push(r3);  // Left operand goes on the stack.
+    VisitForAccumulatorValue(expr->value());
+
+    OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
+                             ? OVERWRITE_RIGHT
+                             : NO_OVERWRITE;
+    SetSourcePosition(expr->position() + 1);
+    AccumulatorValueContext context(this);
+    if (ShouldInlineSmiCase(op)) {
+      EmitInlineSmiBinaryOp(expr->binary_operation(), op, mode, expr->target(),
+                            expr->value());
+    } else {
+      EmitBinaryOp(expr->binary_operation(), op, mode);
+    }
+
+    // Deoptimization point in case the binary operation may have side effects.
+    PrepareForBailout(expr->binary_operation(), TOS_REG);
+  } else {
+    VisitForAccumulatorValue(expr->value());
+  }
+
+  // Record source position before possible IC call.
+  SetSourcePosition(expr->position());
+
+  // Store the value.
+  switch (assign_type) {
+    case VARIABLE:
+      EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
+                             expr->op());
+      PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
+      context()->Plug(r3);
+      break;
+    case NAMED_PROPERTY:
+      EmitNamedPropertyAssignment(expr);
+      break;
+    case NAMED_SUPER_PROPERTY:
+      EmitNamedSuperPropertyStore(property);
+      context()->Plug(r3);
+      break;
+    case KEYED_SUPER_PROPERTY:
+      EmitKeyedSuperPropertyStore(property);
+      context()->Plug(r3);
+      break;
+    case KEYED_PROPERTY:
+      EmitKeyedPropertyAssignment(expr);
+      break;
+  }
+}
+
+
+void FullCodeGenerator::VisitYield(Yield* expr) {
+  Comment cmnt(masm_, "[ Yield");
+  // Evaluate yielded value first; the initial iterator definition depends on
+  // this.  It stays on the stack while we update the iterator.
+  VisitForStackValue(expr->expression());
+
+  switch (expr->yield_kind()) {
+    case Yield::kSuspend:
+      // Pop value from top-of-stack slot; box result into result register.
+      EmitCreateIteratorResult(false);
+      __ push(result_register());
+    // Fall through.
+    case Yield::kInitial: {
+      Label suspend, continuation, post_runtime, resume;
+
+      __ b(&suspend);
+
+      __ bind(&continuation);
+      __ b(&resume);
+
+      __ bind(&suspend);
+      VisitForAccumulatorValue(expr->generator_object());
+      DCHECK(continuation.pos() > 0 && Smi::IsValid(continuation.pos()));
+      __ LoadSmiLiteral(r4, Smi::FromInt(continuation.pos()));
+      __ StoreP(r4, FieldMemOperand(r3, JSGeneratorObject::kContinuationOffset),
+                r0);
+      __ StoreP(cp, FieldMemOperand(r3, JSGeneratorObject::kContextOffset), r0);
+      __ mr(r4, cp);
+      __ RecordWriteField(r3, JSGeneratorObject::kContextOffset, r4, r5,
+                          kLRHasBeenSaved, kDontSaveFPRegs);
+      __ addi(r4, fp, Operand(StandardFrameConstants::kExpressionsOffset));
+      __ cmp(sp, r4);
+      __ beq(&post_runtime);
+      __ push(r3);  // generator object
+      __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
+      __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+      __ bind(&post_runtime);
+      __ pop(result_register());
+      EmitReturnSequence();
+
+      __ bind(&resume);
+      context()->Plug(result_register());
+      break;
+    }
+
+    case Yield::kFinal: {
+      VisitForAccumulatorValue(expr->generator_object());
+      __ LoadSmiLiteral(r4, Smi::FromInt(JSGeneratorObject::kGeneratorClosed));
+      __ StoreP(r4, FieldMemOperand(result_register(),
+                                    JSGeneratorObject::kContinuationOffset),
+                r0);
+      // Pop value from top-of-stack slot, box result into result register.
+      EmitCreateIteratorResult(true);
+      EmitUnwindBeforeReturn();
+      EmitReturnSequence();
+      break;
+    }
+
+    case Yield::kDelegating: {
+      VisitForStackValue(expr->generator_object());
+
+      // Initial stack layout is as follows:
+      // [sp + 1 * kPointerSize] iter
+      // [sp + 0 * kPointerSize] g
+
+      Label l_catch, l_try, l_suspend, l_continuation, l_resume;
+      Label l_next, l_call;
+      Register load_receiver = LoadDescriptor::ReceiverRegister();
+      Register load_name = LoadDescriptor::NameRegister();
+
+      // Initial send value is undefined.
+      __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
+      __ b(&l_next);
+
+      // catch (e) { receiver = iter; f = 'throw'; arg = e; goto l_call; }
+      __ bind(&l_catch);
+      handler_table()->set(expr->index(), Smi::FromInt(l_catch.pos()));
+      __ LoadRoot(load_name, Heap::kthrow_stringRootIndex);  // "throw"
+      __ LoadP(r6, MemOperand(sp, 1 * kPointerSize));        // iter
+      __ Push(load_name, r6, r3);  // "throw", iter, except
+      __ b(&l_call);
+
+      // try { received = %yield result }
+      // Shuffle the received result above a try handler and yield it without
+      // re-boxing.
+      __ bind(&l_try);
+      __ pop(r3);  // result
+      __ PushTryHandler(StackHandler::CATCH, expr->index());
+      const int handler_size = StackHandlerConstants::kSize;
+      __ push(r3);  // result
+      __ b(&l_suspend);
+      __ bind(&l_continuation);
+      __ b(&l_resume);
+      __ bind(&l_suspend);
+      const int generator_object_depth = kPointerSize + handler_size;
+      __ LoadP(r3, MemOperand(sp, generator_object_depth));
+      __ push(r3);  // g
+      DCHECK(l_continuation.pos() > 0 && Smi::IsValid(l_continuation.pos()));
+      __ LoadSmiLiteral(r4, Smi::FromInt(l_continuation.pos()));
+      __ StoreP(r4, FieldMemOperand(r3, JSGeneratorObject::kContinuationOffset),
+                r0);
+      __ StoreP(cp, FieldMemOperand(r3, JSGeneratorObject::kContextOffset), r0);
+      __ mr(r4, cp);
+      __ RecordWriteField(r3, JSGeneratorObject::kContextOffset, r4, r5,
+                          kLRHasBeenSaved, kDontSaveFPRegs);
+      __ CallRuntime(Runtime::kSuspendJSGeneratorObject, 1);
+      __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+      __ pop(r3);  // result
+      EmitReturnSequence();
+      __ bind(&l_resume);  // received in r3
+      __ PopTryHandler();
+
+      // receiver = iter; f = 'next'; arg = received;
+      __ bind(&l_next);
+
+      __ LoadRoot(load_name, Heap::knext_stringRootIndex);  // "next"
+      __ LoadP(r6, MemOperand(sp, 1 * kPointerSize));       // iter
+      __ Push(load_name, r6, r3);  // "next", iter, received
+
+      // result = receiver[f](arg);
+      __ bind(&l_call);
+      __ LoadP(load_receiver, MemOperand(sp, kPointerSize));
+      __ LoadP(load_name, MemOperand(sp, 2 * kPointerSize));
+      if (FLAG_vector_ics) {
+        __ mov(VectorLoadICDescriptor::SlotRegister(),
+               Operand(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
+      }
+      Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
+      CallIC(ic, TypeFeedbackId::None());
+      __ mr(r4, r3);
+      __ StoreP(r4, MemOperand(sp, 2 * kPointerSize));
+      CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
+      __ CallStub(&stub);
+
+      __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+      __ Drop(1);  // The function is still on the stack; drop it.
+
+      // if (!result.done) goto l_try;
+      __ Move(load_receiver, r3);
+
+      __ push(load_receiver);                               // save result
+      __ LoadRoot(load_name, Heap::kdone_stringRootIndex);  // "done"
+      if (FLAG_vector_ics) {
+        __ mov(VectorLoadICDescriptor::SlotRegister(),
+               Operand(SmiFromSlot(expr->DoneFeedbackSlot())));
+      }
+      CallLoadIC(NOT_CONTEXTUAL);  // r0=result.done
+      Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
+      CallIC(bool_ic);
+      __ cmpi(r3, Operand::Zero());
+      __ beq(&l_try);
+
+      // result.value
+      __ pop(load_receiver);                                 // result
+      __ LoadRoot(load_name, Heap::kvalue_stringRootIndex);  // "value"
+      if (FLAG_vector_ics) {
+        __ mov(VectorLoadICDescriptor::SlotRegister(),
+               Operand(SmiFromSlot(expr->ValueFeedbackSlot())));
+      }
+      CallLoadIC(NOT_CONTEXTUAL);     // r3=result.value
+      context()->DropAndPlug(2, r3);  // drop iter and g
+      break;
+    }
+  }
+}
+
+
+void FullCodeGenerator::EmitGeneratorResume(
+    Expression* generator, Expression* value,
+    JSGeneratorObject::ResumeMode resume_mode) {
+  // The value stays in r3, and is ultimately read by the resumed generator, as
+  // if CallRuntime(Runtime::kSuspendJSGeneratorObject) returned it. Or it
+  // is read to throw the value when the resumed generator is already closed.
+  // r4 will hold the generator object until the activation has been resumed.
+  VisitForStackValue(generator);
+  VisitForAccumulatorValue(value);
+  __ pop(r4);
+
+  // Check generator state.
+  Label wrong_state, closed_state, done;
+  __ LoadP(r6, FieldMemOperand(r4, JSGeneratorObject::kContinuationOffset));
+  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
+  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
+  __ CmpSmiLiteral(r6, Smi::FromInt(0), r0);
+  __ beq(&closed_state);
+  __ blt(&wrong_state);
+
+  // Load suspended function and context.
+  __ LoadP(cp, FieldMemOperand(r4, JSGeneratorObject::kContextOffset));
+  __ LoadP(r7, FieldMemOperand(r4, JSGeneratorObject::kFunctionOffset));
+
+  // Load receiver and store as the first argument.
+  __ LoadP(r5, FieldMemOperand(r4, JSGeneratorObject::kReceiverOffset));
+  __ push(r5);
+
+  // Push holes for the rest of the arguments to the generator function.
+  __ LoadP(r6, FieldMemOperand(r7, JSFunction::kSharedFunctionInfoOffset));
+  __ LoadWordArith(
+      r6, FieldMemOperand(r6, SharedFunctionInfo::kFormalParameterCountOffset));
+  __ LoadRoot(r5, Heap::kTheHoleValueRootIndex);
+  Label argument_loop, push_frame;
+#if V8_TARGET_ARCH_PPC64
+  __ cmpi(r6, Operand::Zero());
+  __ beq(&push_frame);
+#else
+  __ SmiUntag(r6, SetRC);
+  __ beq(&push_frame, cr0);
+#endif
+  __ mtctr(r6);
+  __ bind(&argument_loop);
+  __ push(r5);
+  __ bdnz(&argument_loop);
+
+  // Enter a new JavaScript frame, and initialize its slots as they were when
+  // the generator was suspended.
+  Label resume_frame;
+  __ bind(&push_frame);
+  __ b(&resume_frame, SetLK);
+  __ b(&done);
+  __ bind(&resume_frame);
+  // lr = return address.
+  // fp = caller's frame pointer.
+  // cp = callee's context,
+  // r7 = callee's JS function.
+  __ PushFixedFrame(r7);
+  // Adjust FP to point to saved FP.
+  __ addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
+
+  // Load the operand stack size.
+  __ LoadP(r6, FieldMemOperand(r4, JSGeneratorObject::kOperandStackOffset));
+  __ LoadP(r6, FieldMemOperand(r6, FixedArray::kLengthOffset));
+  __ SmiUntag(r6, SetRC);
+
+  // If we are sending a value and there is no operand stack, we can jump back
+  // in directly.
+  Label call_resume;
+  if (resume_mode == JSGeneratorObject::NEXT) {
+    Label slow_resume;
+    __ bne(&slow_resume, cr0);
+    __ LoadP(ip, FieldMemOperand(r7, JSFunction::kCodeEntryOffset));
+#if V8_OOL_CONSTANT_POOL
+    {
+      ConstantPoolUnavailableScope constant_pool_unavailable(masm_);
+      // Load the new code object's constant pool pointer.
+      __ LoadP(kConstantPoolRegister,
+               MemOperand(ip, Code::kConstantPoolOffset - Code::kHeaderSize));
+#endif
+      __ LoadP(r5, FieldMemOperand(r4, JSGeneratorObject::kContinuationOffset));
+      __ SmiUntag(r5);
+      __ add(ip, ip, r5);
+      __ LoadSmiLiteral(r5,
+                        Smi::FromInt(JSGeneratorObject::kGeneratorExecuting));
+      __ StoreP(r5, FieldMemOperand(r4, JSGeneratorObject::kContinuationOffset),
+                r0);
+      __ Jump(ip);
+      __ bind(&slow_resume);
+#if V8_OOL_CONSTANT_POOL
+    }
+#endif
+  } else {
+    __ beq(&call_resume, cr0);
+  }
+
+  // Otherwise, we push holes for the operand stack and call the runtime to fix
+  // up the stack and the handlers.
+  Label operand_loop;
+  __ mtctr(r6);
+  __ bind(&operand_loop);
+  __ push(r5);
+  __ bdnz(&operand_loop);
+
+  __ bind(&call_resume);
+  DCHECK(!result_register().is(r4));
+  __ Push(r4, result_register());
+  __ Push(Smi::FromInt(resume_mode));
+  __ CallRuntime(Runtime::kResumeJSGeneratorObject, 3);
+  // Not reached: the runtime call returns elsewhere.
+  __ stop("not-reached");
+
+  // Reach here when generator is closed.
+  __ bind(&closed_state);
+  if (resume_mode == JSGeneratorObject::NEXT) {
+    // Return completed iterator result when generator is closed.
+    __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
+    __ push(r5);
+    // Pop value from top-of-stack slot; box result into result register.
+    EmitCreateIteratorResult(true);
+  } else {
+    // Throw the provided value.
+    __ push(r3);
+    __ CallRuntime(Runtime::kThrow, 1);
+  }
+  __ b(&done);
+
+  // Throw error if we attempt to operate on a running generator.
+  __ bind(&wrong_state);
+  __ push(r4);
+  __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
+
+  __ bind(&done);
+  context()->Plug(result_register());
+}
+
+
+void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
+  Label gc_required;
+  Label allocated;
+
+  const int instance_size = 5 * kPointerSize;
+  DCHECK_EQ(isolate()->native_context()->iterator_result_map()->instance_size(),
+            instance_size);
+
+  __ Allocate(instance_size, r3, r5, r6, &gc_required, TAG_OBJECT);
+  __ b(&allocated);
+
+  __ bind(&gc_required);
+  __ Push(Smi::FromInt(instance_size));
+  __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
+  __ LoadP(context_register(),
+           MemOperand(fp, StandardFrameConstants::kContextOffset));
+
+  __ bind(&allocated);
+  __ LoadP(r4, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+  __ LoadP(r4, FieldMemOperand(r4, GlobalObject::kNativeContextOffset));
+  __ LoadP(r4, ContextOperand(r4, Context::ITERATOR_RESULT_MAP_INDEX));
+  __ pop(r5);
+  __ mov(r6, Operand(isolate()->factory()->ToBoolean(done)));
+  __ mov(r7, Operand(isolate()->factory()->empty_fixed_array()));
+  __ StoreP(r4, FieldMemOperand(r3, HeapObject::kMapOffset), r0);
+  __ StoreP(r7, FieldMemOperand(r3, JSObject::kPropertiesOffset), r0);
+  __ StoreP(r7, FieldMemOperand(r3, JSObject::kElementsOffset), r0);
+  __ StoreP(r5,
+            FieldMemOperand(r3, JSGeneratorObject::kResultValuePropertyOffset),
+            r0);
+  __ StoreP(r6,
+            FieldMemOperand(r3, JSGeneratorObject::kResultDonePropertyOffset),
+            r0);
+
+  // Only the value field needs a write barrier, as the other values are in the
+  // root set.
+  __ RecordWriteField(r3, JSGeneratorObject::kResultValuePropertyOffset, r5, r6,
+                      kLRHasBeenSaved, kDontSaveFPRegs);
+}
+
+
+void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
+  SetSourcePosition(prop->position());
+  Literal* key = prop->key()->AsLiteral();
+  DCHECK(!prop->IsSuperAccess());
+
+  __ mov(LoadDescriptor::NameRegister(), Operand(key->value()));
+  if (FLAG_vector_ics) {
+    __ mov(VectorLoadICDescriptor::SlotRegister(),
+           Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
+    CallLoadIC(NOT_CONTEXTUAL);
+  } else {
+    CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
+  }
+}
+
+
+void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object.
+  SetSourcePosition(prop->position());
+  Literal* key = prop->key()->AsLiteral();
+  DCHECK(!key->value()->IsSmi());
+  DCHECK(prop->IsSuperAccess());
+
+  __ Push(key->value());
+  __ CallRuntime(Runtime::kLoadFromSuper, 3);
+}
+
+
+void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
+  SetSourcePosition(prop->position());
+  Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
+  if (FLAG_vector_ics) {
+    __ mov(VectorLoadICDescriptor::SlotRegister(),
+           Operand(SmiFromSlot(prop->PropertyFeedbackSlot())));
+    CallIC(ic);
+  } else {
+    CallIC(ic, prop->PropertyFeedbackId());
+  }
+}
+
+
+void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object, key.
+  SetSourcePosition(prop->position());
+
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+}
+
+
+void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
+                                              Token::Value op,
+                                              OverwriteMode mode,
+                                              Expression* left_expr,
+                                              Expression* right_expr) {
+  Label done, smi_case, stub_call;
+
+  Register scratch1 = r5;
+  Register scratch2 = r6;
+
+  // Get the arguments.
+  Register left = r4;
+  Register right = r3;
+  __ pop(left);
+
+  // Perform combined smi check on both operands.
+  __ orx(scratch1, left, right);
+  STATIC_ASSERT(kSmiTag == 0);
+  JumpPatchSite patch_site(masm_);
+  patch_site.EmitJumpIfSmi(scratch1, &smi_case);
+
+  __ bind(&stub_call);
+  Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
+  CallIC(code, expr->BinaryOperationFeedbackId());
+  patch_site.EmitPatchInfo();
+  __ b(&done);
+
+  __ bind(&smi_case);
+  // Smi case. This code works the same way as the smi-smi case in the type
+  // recording binary operation stub.
+  switch (op) {
+    case Token::SAR:
+      __ GetLeastBitsFromSmi(scratch1, right, 5);
+      __ ShiftRightArith(right, left, scratch1);
+      __ ClearRightImm(right, right, Operand(kSmiTagSize + kSmiShiftSize));
+      break;
+    case Token::SHL: {
+      __ GetLeastBitsFromSmi(scratch2, right, 5);
+#if V8_TARGET_ARCH_PPC64
+      __ ShiftLeft_(right, left, scratch2);
+#else
+      __ SmiUntag(scratch1, left);
+      __ ShiftLeft_(scratch1, scratch1, scratch2);
+      // Check that the *signed* result fits in a smi
+      __ JumpIfNotSmiCandidate(scratch1, scratch2, &stub_call);
+      __ SmiTag(right, scratch1);
+#endif
+      break;
+    }
+    case Token::SHR: {
+      __ SmiUntag(scratch1, left);
+      __ GetLeastBitsFromSmi(scratch2, right, 5);
+      __ srw(scratch1, scratch1, scratch2);
+      // Unsigned shift is not allowed to produce a negative number.
+      __ JumpIfNotUnsignedSmiCandidate(scratch1, r0, &stub_call);
+      __ SmiTag(right, scratch1);
+      break;
+    }
+    case Token::ADD: {
+      __ AddAndCheckForOverflow(scratch1, left, right, scratch2, r0);
+      __ bne(&stub_call, cr0);
+      __ mr(right, scratch1);
+      break;
+    }
+    case Token::SUB: {
+      __ SubAndCheckForOverflow(scratch1, left, right, scratch2, r0);
+      __ bne(&stub_call, cr0);
+      __ mr(right, scratch1);
+      break;
+    }
+    case Token::MUL: {
+      Label mul_zero;
+#if V8_TARGET_ARCH_PPC64
+      // Remove tag from both operands.
+      __ SmiUntag(ip, right);
+      __ SmiUntag(r0, left);
+      __ Mul(scratch1, r0, ip);
+      // Check for overflowing the smi range - no overflow if higher 33 bits of
+      // the result are identical.
+      __ TestIfInt32(scratch1, scratch2, ip);
+      __ bne(&stub_call);
+#else
+      __ SmiUntag(ip, right);
+      __ mullw(scratch1, left, ip);
+      __ mulhw(scratch2, left, ip);
+      // Check for overflowing the smi range - no overflow if higher 33 bits of
+      // the result are identical.
+      __ TestIfInt32(scratch2, scratch1, ip);
+      __ bne(&stub_call);
+#endif
+      // Go slow on zero result to handle -0.
+      __ cmpi(scratch1, Operand::Zero());
+      __ beq(&mul_zero);
+#if V8_TARGET_ARCH_PPC64
+      __ SmiTag(right, scratch1);
+#else
+      __ mr(right, scratch1);
+#endif
+      __ b(&done);
+      // We need -0 if we were multiplying a negative number with 0 to get 0.
+      // We know one of them was zero.
+      __ bind(&mul_zero);
+      __ add(scratch2, right, left);
+      __ cmpi(scratch2, Operand::Zero());
+      __ blt(&stub_call);
+      __ LoadSmiLiteral(right, Smi::FromInt(0));
+      break;
+    }
+    case Token::BIT_OR:
+      __ orx(right, left, right);
+      break;
+    case Token::BIT_AND:
+      __ and_(right, left, right);
+      break;
+    case Token::BIT_XOR:
+      __ xor_(right, left, right);
+      break;
+    default:
+      UNREACHABLE();
+  }
+
+  __ bind(&done);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
+  // Constructor is in r3.
+  DCHECK(lit != NULL);
+  __ push(r3);
+
+  // No access check is needed here since the constructor is created by the
+  // class literal.
+  Register scratch = r4;
+  __ LoadP(scratch,
+           FieldMemOperand(r3, JSFunction::kPrototypeOrInitialMapOffset));
+  __ push(scratch);
+
+  for (int i = 0; i < lit->properties()->length(); i++) {
+    ObjectLiteral::Property* property = lit->properties()->at(i);
+    Literal* key = property->key()->AsLiteral();
+    Expression* value = property->value();
+    DCHECK(key != NULL);
+
+    if (property->is_static()) {
+      __ LoadP(scratch, MemOperand(sp, kPointerSize));  // constructor
+    } else {
+      __ LoadP(scratch, MemOperand(sp, 0));  // prototype
+    }
+    __ push(scratch);
+    VisitForStackValue(key);
+    VisitForStackValue(value);
+
+    switch (property->kind()) {
+      case ObjectLiteral::Property::CONSTANT:
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+      case ObjectLiteral::Property::COMPUTED:
+      case ObjectLiteral::Property::PROTOTYPE:
+        __ CallRuntime(Runtime::kDefineClassMethod, 3);
+        break;
+
+      case ObjectLiteral::Property::GETTER:
+        __ CallRuntime(Runtime::kDefineClassGetter, 3);
+        break;
+
+      case ObjectLiteral::Property::SETTER:
+        __ CallRuntime(Runtime::kDefineClassSetter, 3);
+        break;
+
+      default:
+        UNREACHABLE();
+    }
+  }
+
+  // prototype
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+
+  // constructor
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+}
+
+
+void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op,
+                                     OverwriteMode mode) {
+  __ pop(r4);
+  Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
+  JumpPatchSite patch_site(masm_);  // unbound, signals no inlined smi code.
+  CallIC(code, expr->BinaryOperationFeedbackId());
+  patch_site.EmitPatchInfo();
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitAssignment(Expression* expr) {
+  DCHECK(expr->IsValidReferenceExpression());
+
+  Property* prop = expr->AsProperty();
+  LhsKind assign_type = GetAssignType(prop);
+
+  switch (assign_type) {
+    case VARIABLE: {
+      Variable* var = expr->AsVariableProxy()->var();
+      EffectContext context(this);
+      EmitVariableAssignment(var, Token::ASSIGN);
+      break;
+    }
+    case NAMED_PROPERTY: {
+      __ push(r3);  // Preserve value.
+      VisitForAccumulatorValue(prop->obj());
+      __ Move(StoreDescriptor::ReceiverRegister(), r3);
+      __ pop(StoreDescriptor::ValueRegister());  // Restore value.
+      __ mov(StoreDescriptor::NameRegister(),
+             Operand(prop->key()->AsLiteral()->value()));
+      CallStoreIC();
+      break;
+    }
+    case NAMED_SUPER_PROPERTY: {
+      __ Push(r3);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      // stack: value, this; r3: home_object
+      Register scratch = r5;
+      Register scratch2 = r6;
+      __ mr(scratch, result_register());                  // home_object
+      __ LoadP(r3, MemOperand(sp, kPointerSize));         // value
+      __ LoadP(scratch2, MemOperand(sp, 0));              // this
+      __ StoreP(scratch2, MemOperand(sp, kPointerSize));  // this
+      __ StoreP(scratch, MemOperand(sp, 0));              // home_object
+      // stack: this, home_object; r3: value
+      EmitNamedSuperPropertyStore(prop);
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      __ Push(r3);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(prop->key());
+      Register scratch = r5;
+      Register scratch2 = r6;
+      __ LoadP(scratch2, MemOperand(sp, 2 * kPointerSize));  // value
+      // stack: value, this, home_object; r3: key, r6: value
+      __ LoadP(scratch, MemOperand(sp, kPointerSize));  // this
+      __ StoreP(scratch, MemOperand(sp, 2 * kPointerSize));
+      __ LoadP(scratch, MemOperand(sp, 0));  // home_object
+      __ StoreP(scratch, MemOperand(sp, kPointerSize));
+      __ StoreP(r3, MemOperand(sp, 0));
+      __ Move(r3, scratch2);
+      // stack: this, home_object, key; r3: value.
+      EmitKeyedSuperPropertyStore(prop);
+      break;
+    }
+    case KEYED_PROPERTY: {
+      __ push(r3);  // Preserve value.
+      VisitForStackValue(prop->obj());
+      VisitForAccumulatorValue(prop->key());
+      __ Move(StoreDescriptor::NameRegister(), r3);
+      __ Pop(StoreDescriptor::ValueRegister(),
+             StoreDescriptor::ReceiverRegister());
+      Handle<Code> ic =
+          CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
+      CallIC(ic);
+      break;
+    }
+  }
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
+    Variable* var, MemOperand location) {
+  __ StoreP(result_register(), location, r0);
+  if (var->IsContextSlot()) {
+    // RecordWrite may destroy all its register arguments.
+    __ mr(r6, result_register());
+    int offset = Context::SlotOffset(var->index());
+    __ RecordWriteContextSlot(r4, offset, r6, r5, kLRHasBeenSaved,
+                              kDontSaveFPRegs);
+  }
+}
+
+
+void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
+  if (var->IsUnallocated()) {
+    // Global var, const, or let.
+    __ mov(StoreDescriptor::NameRegister(), Operand(var->name()));
+    __ LoadP(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand());
+    CallStoreIC();
+
+  } else if (op == Token::INIT_CONST_LEGACY) {
+    // Const initializers need a write barrier.
+    DCHECK(!var->IsParameter());  // No const parameters.
+    if (var->IsLookupSlot()) {
+      __ push(r3);
+      __ mov(r3, Operand(var->name()));
+      __ Push(cp, r3);  // Context and name.
+      __ CallRuntime(Runtime::kInitializeLegacyConstLookupSlot, 3);
+    } else {
+      DCHECK(var->IsStackAllocated() || var->IsContextSlot());
+      Label skip;
+      MemOperand location = VarOperand(var, r4);
+      __ LoadP(r5, location);
+      __ CompareRoot(r5, Heap::kTheHoleValueRootIndex);
+      __ bne(&skip);
+      EmitStoreToStackLocalOrContextSlot(var, location);
+      __ bind(&skip);
+    }
+
+  } else if (var->mode() == LET && op != Token::INIT_LET) {
+    // Non-initializing assignment to let variable needs a write barrier.
+    DCHECK(!var->IsLookupSlot());
+    DCHECK(var->IsStackAllocated() || var->IsContextSlot());
+    Label assign;
+    MemOperand location = VarOperand(var, r4);
+    __ LoadP(r6, location);
+    __ CompareRoot(r6, Heap::kTheHoleValueRootIndex);
+    __ bne(&assign);
+    __ mov(r6, Operand(var->name()));
+    __ push(r6);
+    __ CallRuntime(Runtime::kThrowReferenceError, 1);
+    // Perform the assignment.
+    __ bind(&assign);
+    EmitStoreToStackLocalOrContextSlot(var, location);
+
+  } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
+    if (var->IsLookupSlot()) {
+      // Assignment to var.
+      __ push(r3);  // Value.
+      __ mov(r4, Operand(var->name()));
+      __ mov(r3, Operand(Smi::FromInt(strict_mode())));
+      __ Push(cp, r4, r3);  // Context, name, strict mode.
+      __ CallRuntime(Runtime::kStoreLookupSlot, 4);
+    } else {
+      // Assignment to var or initializing assignment to let/const in harmony
+      // mode.
+      DCHECK((var->IsStackAllocated() || var->IsContextSlot()));
+      MemOperand location = VarOperand(var, r4);
+      if (generate_debug_code_ && op == Token::INIT_LET) {
+        // Check for an uninitialized let binding.
+        __ LoadP(r5, location);
+        __ CompareRoot(r5, Heap::kTheHoleValueRootIndex);
+        __ Check(eq, kLetBindingReInitialization);
+      }
+      EmitStoreToStackLocalOrContextSlot(var, location);
+    }
+  }
+  // Non-initializing assignments to consts are ignored.
+}
+
+
+void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) {
+  // Assignment to a property, using a named store IC.
+  Property* prop = expr->target()->AsProperty();
+  DCHECK(prop != NULL);
+  DCHECK(prop->key()->IsLiteral());
+
+  // Record source code position before IC call.
+  SetSourcePosition(expr->position());
+  __ mov(StoreDescriptor::NameRegister(),
+         Operand(prop->key()->AsLiteral()->value()));
+  __ pop(StoreDescriptor::ReceiverRegister());
+  CallStoreIC(expr->AssignmentFeedbackId());
+
+  PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // r3 : value
+  // stack : receiver ('this'), home_object
+  DCHECK(prop != NULL);
+  Literal* key = prop->key()->AsLiteral();
+  DCHECK(key != NULL);
+
+  __ Push(key->value());
+  __ Push(r3);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
+                                          : Runtime::kStoreToSuper_Sloppy),
+                 4);
+}
+
+
+void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // r3 : value
+  // stack : receiver ('this'), home_object, key
+  DCHECK(prop != NULL);
+
+  __ Push(r3);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict
+                                          : Runtime::kStoreKeyedToSuper_Sloppy),
+                 4);
+}
+
+
+void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
+  // Assignment to a property, using a keyed store IC.
+
+  // Record source code position before IC call.
+  SetSourcePosition(expr->position());
+  __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister());
+  DCHECK(StoreDescriptor::ValueRegister().is(r3));
+
+  Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
+  CallIC(ic, expr->AssignmentFeedbackId());
+
+  PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::VisitProperty(Property* expr) {
+  Comment cmnt(masm_, "[ Property");
+  Expression* key = expr->key();
+
+  if (key->IsPropertyName()) {
+    if (!expr->IsSuperAccess()) {
+      VisitForAccumulatorValue(expr->obj());
+      __ Move(LoadDescriptor::ReceiverRegister(), r3);
+      EmitNamedPropertyLoad(expr);
+    } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ Push(result_register());
+      EmitNamedSuperPropertyLoad(expr);
+    }
+    PrepareForBailoutForId(expr->LoadId(), TOS_REG);
+    context()->Plug(r3);
+  } else {
+    if (!expr->IsSuperAccess()) {
+      VisitForStackValue(expr->obj());
+      VisitForAccumulatorValue(expr->key());
+      __ Move(LoadDescriptor::NameRegister(), r3);
+      __ pop(LoadDescriptor::ReceiverRegister());
+      EmitKeyedPropertyLoad(expr);
+    } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForStackValue(expr->key());
+      EmitKeyedSuperPropertyLoad(expr);
+    }
+    context()->Plug(r3);
+  }
+}
+
+
+void FullCodeGenerator::CallIC(Handle<Code> code, TypeFeedbackId ast_id) {
+  ic_total_count_++;
+  __ Call(code, RelocInfo::CODE_TARGET, ast_id);
+}
+
+
+// Code common for calls using the IC.
+void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
+  Expression* callee = expr->expression();
+
+  CallICState::CallType call_type =
+      callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD;
+
+  // Get the target function.
+  if (call_type == CallICState::FUNCTION) {
+    {
+      StackValueContext context(this);
+      EmitVariableLoad(callee->AsVariableProxy());
+      PrepareForBailout(callee, NO_REGISTERS);
+    }
+    // Push undefined as receiver. This is patched in the method prologue if it
+    // is a sloppy mode method.
+    __ Push(isolate()->factory()->undefined_value());
+  } else {
+    // Load the function from the receiver.
+    DCHECK(callee->IsProperty());
+    DCHECK(!callee->AsProperty()->IsSuperAccess());
+    __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
+    EmitNamedPropertyLoad(callee->AsProperty());
+    PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
+    // Push the target function under the receiver.
+    __ LoadP(ip, MemOperand(sp, 0));
+    __ push(ip);
+    __ StoreP(r3, MemOperand(sp, kPointerSize));
+  }
+
+  EmitCall(expr, call_type);
+}
+
+
+void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
+  Expression* callee = expr->expression();
+  DCHECK(callee->IsProperty());
+  Property* prop = callee->AsProperty();
+  DCHECK(prop->IsSuperAccess());
+
+  SetSourcePosition(prop->position());
+  Literal* key = prop->key()->AsLiteral();
+  DCHECK(!key->value()->IsSmi());
+  // Load the function from the receiver.
+  const Register scratch = r4;
+  SuperReference* super_ref = prop->obj()->AsSuperReference();
+  EmitLoadHomeObject(super_ref);
+  __ mr(scratch, r3);
+  VisitForAccumulatorValue(super_ref->this_var());
+  __ Push(scratch, r3, r3, scratch);
+  __ Push(key->value());
+
+  // Stack here:
+  //  - home_object
+  //  - this (receiver)
+  //  - this (receiver) <-- LoadFromSuper will pop here and below.
+  //  - home_object
+  //  - key
+  __ CallRuntime(Runtime::kLoadFromSuper, 3);
+
+  // Replace home_object with target function.
+  __ StoreP(r3, MemOperand(sp, kPointerSize));
+
+  // Stack here:
+  // - target function
+  // - this (receiver)
+  EmitCall(expr, CallICState::METHOD);
+}
+
+
+// Code common for calls using the IC.
+void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) {
+  // Load the key.
+  VisitForAccumulatorValue(key);
+
+  Expression* callee = expr->expression();
+
+  // Load the function from the receiver.
+  DCHECK(callee->IsProperty());
+  __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
+  __ Move(LoadDescriptor::NameRegister(), r3);
+  EmitKeyedPropertyLoad(callee->AsProperty());
+  PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
+
+  // Push the target function under the receiver.
+  __ LoadP(ip, MemOperand(sp, 0));
+  __ push(ip);
+  __ StoreP(r3, MemOperand(sp, kPointerSize));
+
+  EmitCall(expr, CallICState::METHOD);
+}
+
+
+void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
+  Expression* callee = expr->expression();
+  DCHECK(callee->IsProperty());
+  Property* prop = callee->AsProperty();
+  DCHECK(prop->IsSuperAccess());
+
+  SetSourcePosition(prop->position());
+  // Load the function from the receiver.
+  const Register scratch = r4;
+  SuperReference* super_ref = prop->obj()->AsSuperReference();
+  EmitLoadHomeObject(super_ref);
+  __ Push(r3);
+  VisitForAccumulatorValue(super_ref->this_var());
+  __ Push(r3);
+  __ Push(r3);
+  __ LoadP(scratch, MemOperand(sp, kPointerSize * 2));
+  __ Push(scratch);
+  VisitForStackValue(prop->key());
+
+  // Stack here:
+  //  - home_object
+  //  - this (receiver)
+  //  - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
+  //  - home_object
+  //  - key
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+
+  // Replace home_object with target function.
+  __ StoreP(r3, MemOperand(sp, kPointerSize));
+
+  // Stack here:
+  // - target function
+  // - this (receiver)
+  EmitCall(expr, CallICState::METHOD);
+}
+
+
+void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
+  // Load the arguments.
+  ZoneList<Expression*>* args = expr->arguments();
+  int arg_count = args->length();
+  {
+    PreservePositionScope scope(masm()->positions_recorder());
+    for (int i = 0; i < arg_count; i++) {
+      VisitForStackValue(args->at(i));
+    }
+  }
+
+  // Record source position of the IC call.
+  SetSourcePosition(expr->position());
+  Handle<Code> ic = CallIC::initialize_stub(isolate(), arg_count, call_type);
+  __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackSlot()));
+  __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
+  // Don't assign a type feedback id to the IC, since type feedback is provided
+  // by the vector above.
+  CallIC(ic);
+
+  RecordJSReturnSite(expr);
+  // Restore context register.
+  __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  context()->DropAndPlug(1, r3);
+}
+
+
+void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
+  // r8: copy of the first argument or undefined if it doesn't exist.
+  if (arg_count > 0) {
+    __ LoadP(r8, MemOperand(sp, arg_count * kPointerSize), r0);
+  } else {
+    __ LoadRoot(r8, Heap::kUndefinedValueRootIndex);
+  }
+
+  // r7: the receiver of the enclosing function.
+  __ LoadP(r7, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+
+  // r6: the receiver of the enclosing function.
+  int receiver_offset = 2 + info_->scope()->num_parameters();
+  __ LoadP(r6, MemOperand(fp, receiver_offset * kPointerSize), r0);
+
+  // r5: strict mode.
+  __ LoadSmiLiteral(r5, Smi::FromInt(strict_mode()));
+
+  // r4: the start position of the scope the calls resides in.
+  __ LoadSmiLiteral(r4, Smi::FromInt(scope()->start_position()));
+
+  // Do the runtime call.
+  __ Push(r8, r7, r6, r5, r4);
+  __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
+}
+
+
+void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
+  DCHECK(super_ref != NULL);
+  __ LoadP(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  __ Push(r3);
+  __ CallRuntime(Runtime::kGetPrototype, 1);
+}
+
+
+void FullCodeGenerator::VisitCall(Call* expr) {
+#ifdef DEBUG
+  // We want to verify that RecordJSReturnSite gets called on all paths
+  // through this function.  Avoid early returns.
+  expr->return_is_recorded_ = false;
+#endif
+
+  Comment cmnt(masm_, "[ Call");
+  Expression* callee = expr->expression();
+  Call::CallType call_type = expr->GetCallType(isolate());
+
+  if (call_type == Call::POSSIBLY_EVAL_CALL) {
+    // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval
+    // to resolve the function we need to call and the receiver of the
+    // call.  Then we call the resolved function using the given
+    // arguments.
+    ZoneList<Expression*>* args = expr->arguments();
+    int arg_count = args->length();
+
+    {
+      PreservePositionScope pos_scope(masm()->positions_recorder());
+      VisitForStackValue(callee);
+      __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
+      __ push(r5);  // Reserved receiver slot.
+
+      // Push the arguments.
+      for (int i = 0; i < arg_count; i++) {
+        VisitForStackValue(args->at(i));
+      }
+
+      // Push a copy of the function (found below the arguments) and
+      // resolve eval.
+      __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
+      __ push(r4);
+      EmitResolvePossiblyDirectEval(arg_count);
+
+      // The runtime call returns a pair of values in r3 (function) and
+      // r4 (receiver). Touch up the stack with the right values.
+      __ StoreP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
+      __ StoreP(r4, MemOperand(sp, arg_count * kPointerSize), r0);
+
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
+    }
+
+    // Record source position for debugger.
+    SetSourcePosition(expr->position());
+    CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
+    __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
+    __ CallStub(&stub);
+    RecordJSReturnSite(expr);
+    // Restore context register.
+    __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+    context()->DropAndPlug(1, r3);
+  } else if (call_type == Call::GLOBAL_CALL) {
+    EmitCallWithLoadIC(expr);
+
+  } else if (call_type == Call::LOOKUP_SLOT_CALL) {
+    // Call to a lookup slot (dynamically introduced variable).
+    VariableProxy* proxy = callee->AsVariableProxy();
+    Label slow, done;
+
+    {
+      PreservePositionScope scope(masm()->positions_recorder());
+      // Generate code for loading from variables potentially shadowed
+      // by eval-introduced variables.
+      EmitDynamicLookupFastCase(proxy, NOT_INSIDE_TYPEOF, &slow, &done);
+    }
+
+    __ bind(&slow);
+    // Call the runtime to find the function to call (returned in r3)
+    // and the object holding it (returned in edx).
+    DCHECK(!context_register().is(r5));
+    __ mov(r5, Operand(proxy->name()));
+    __ Push(context_register(), r5);
+    __ CallRuntime(Runtime::kLoadLookupSlot, 2);
+    __ Push(r3, r4);  // Function, receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
+
+    // If fast case code has been generated, emit code to push the
+    // function and receiver and have the slow path jump around this
+    // code.
+    if (done.is_linked()) {
+      Label call;
+      __ b(&call);
+      __ bind(&done);
+      // Push function.
+      __ push(r3);
+      // The receiver is implicitly the global receiver. Indicate this
+      // by passing the hole to the call function stub.
+      __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
+      __ push(r4);
+      __ bind(&call);
+    }
+
+    // The receiver is either the global receiver or an object found
+    // by LoadContextSlot.
+    EmitCall(expr);
+  } else if (call_type == Call::PROPERTY_CALL) {
+    Property* property = callee->AsProperty();
+    bool is_named_call = property->key()->IsPropertyName();
+    if (property->IsSuperAccess()) {
+      if (is_named_call) {
+        EmitSuperCallWithLoadIC(expr);
+      } else {
+        EmitKeyedSuperCallWithLoadIC(expr);
+      }
+    } else {
+      {
+        PreservePositionScope scope(masm()->positions_recorder());
+        VisitForStackValue(property->obj());
+      }
+      if (is_named_call) {
+        EmitCallWithLoadIC(expr);
+      } else {
+        EmitKeyedCallWithLoadIC(expr, property->key());
+      }
+    }
+  } else if (call_type == Call::SUPER_CALL) {
+    SuperReference* super_ref = callee->AsSuperReference();
+    EmitLoadSuperConstructor(super_ref);
+    __ Push(result_register());
+    VisitForStackValue(super_ref->this_var());
+    EmitCall(expr, CallICState::METHOD);
+  } else {
+    DCHECK(call_type == Call::OTHER_CALL);
+    // Call to an arbitrary expression not handled specially above.
+    {
+      PreservePositionScope scope(masm()->positions_recorder());
+      VisitForStackValue(callee);
+    }
+    __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
+    __ push(r4);
+    // Emit function call.
+    EmitCall(expr);
+  }
+
+#ifdef DEBUG
+  // RecordJSReturnSite should have been called.
+  DCHECK(expr->return_is_recorded_);
+#endif
+}
+
+
+void FullCodeGenerator::VisitCallNew(CallNew* expr) {
+  Comment cmnt(masm_, "[ CallNew");
+  // According to ECMA-262, section 11.2.2, page 44, the function
+  // expression in new calls must be evaluated before the
+  // arguments.
+
+  // Push constructor on the stack.  If it's not a function it's used as
+  // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
+  // ignored.
+  if (expr->expression()->IsSuperReference()) {
+    EmitLoadSuperConstructor(expr->expression()->AsSuperReference());
+    __ Push(result_register());
+  } else {
+    VisitForStackValue(expr->expression());
+  }
+
+  // Push the arguments ("left-to-right") on the stack.
+  ZoneList<Expression*>* args = expr->arguments();
+  int arg_count = args->length();
+  for (int i = 0; i < arg_count; i++) {
+    VisitForStackValue(args->at(i));
+  }
+
+  // Call the construct call builtin that handles allocation and
+  // constructor invocation.
+  SetSourcePosition(expr->position());
+
+  // Load function and argument count into r4 and r3.
+  __ mov(r3, Operand(arg_count));
+  __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize), r0);
+
+  // Record call targets in unoptimized code.
+  if (FLAG_pretenuring_call_new) {
+    EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
+    DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
+           expr->CallNewFeedbackSlot().ToInt() + 1);
+  }
+
+  __ Move(r5, FeedbackVector());
+  __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallNewFeedbackSlot()));
+
+  CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
+  __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
+  PrepareForBailoutForId(expr->ReturnId(), TOS_REG);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  __ TestIfSmi(r3, r0);
+  Split(eq, if_true, if_false, fall_through, cr0);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitIsNonNegativeSmi(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  __ TestIfPositiveSmi(r3, r0);
+  Split(eq, if_true, if_false, fall_through, cr0);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitIsObject(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(r3, if_false);
+  __ LoadRoot(ip, Heap::kNullValueRootIndex);
+  __ cmp(r3, ip);
+  __ beq(if_true);
+  __ LoadP(r5, FieldMemOperand(r3, HeapObject::kMapOffset));
+  // Undetectable objects behave like undefined when tested with typeof.
+  __ lbz(r4, FieldMemOperand(r5, Map::kBitFieldOffset));
+  __ andi(r0, r4, Operand(1 << Map::kIsUndetectable));
+  __ bne(if_false, cr0);
+  __ lbz(r4, FieldMemOperand(r5, Map::kInstanceTypeOffset));
+  __ cmpi(r4, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
+  __ blt(if_false);
+  __ cmpi(r4, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(le, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitIsSpecObject(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(r3, if_false);
+  __ CompareObjectType(r3, r4, r4, FIRST_SPEC_OBJECT_TYPE);
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(ge, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitIsUndetectableObject(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(r3, if_false);
+  __ LoadP(r4, FieldMemOperand(r3, HeapObject::kMapOffset));
+  __ lbz(r4, FieldMemOperand(r4, Map::kBitFieldOffset));
+  __ andi(r0, r4, Operand(1 << Map::kIsUndetectable));
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(ne, if_true, if_false, fall_through, cr0);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
+    CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false, skip_lookup;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ AssertNotSmi(r3);
+
+  __ LoadP(r4, FieldMemOperand(r3, HeapObject::kMapOffset));
+  __ lbz(ip, FieldMemOperand(r4, Map::kBitField2Offset));
+  __ andi(r0, ip, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
+  __ bne(&skip_lookup, cr0);
+
+  // Check for fast case object. Generate false result for slow case object.
+  __ LoadP(r5, FieldMemOperand(r3, JSObject::kPropertiesOffset));
+  __ LoadP(r5, FieldMemOperand(r5, HeapObject::kMapOffset));
+  __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
+  __ cmp(r5, ip);
+  __ beq(if_false);
+
+  // Look for valueOf name in the descriptor array, and indicate false if
+  // found. Since we omit an enumeration index check, if it is added via a
+  // transition that shares its descriptor array, this is a false positive.
+  Label entry, loop, done;
+
+  // Skip loop if no descriptors are valid.
+  __ NumberOfOwnDescriptors(r6, r4);
+  __ cmpi(r6, Operand::Zero());
+  __ beq(&done);
+
+  __ LoadInstanceDescriptors(r4, r7);
+  // r7: descriptor array.
+  // r6: valid entries in the descriptor array.
+  __ mov(ip, Operand(DescriptorArray::kDescriptorSize));
+  __ Mul(r6, r6, ip);
+  // Calculate location of the first key name.
+  __ addi(r7, r7, Operand(DescriptorArray::kFirstOffset - kHeapObjectTag));
+  // Calculate the end of the descriptor array.
+  __ mr(r5, r7);
+  __ ShiftLeftImm(ip, r6, Operand(kPointerSizeLog2));
+  __ add(r5, r5, ip);
+
+  // Loop through all the keys in the descriptor array. If one of these is the
+  // string "valueOf" the result is false.
+  // The use of ip to store the valueOf string assumes that it is not otherwise
+  // used in the loop below.
+  __ mov(ip, Operand(isolate()->factory()->value_of_string()));
+  __ b(&entry);
+  __ bind(&loop);
+  __ LoadP(r6, MemOperand(r7, 0));
+  __ cmp(r6, ip);
+  __ beq(if_false);
+  __ addi(r7, r7, Operand(DescriptorArray::kDescriptorSize * kPointerSize));
+  __ bind(&entry);
+  __ cmp(r7, r5);
+  __ bne(&loop);
+
+  __ bind(&done);
+
+  // Set the bit in the map to indicate that there is no local valueOf field.
+  __ lbz(r5, FieldMemOperand(r4, Map::kBitField2Offset));
+  __ ori(r5, r5, Operand(1 << Map::kStringWrapperSafeForDefaultValueOf));
+  __ stb(r5, FieldMemOperand(r4, Map::kBitField2Offset));
+
+  __ bind(&skip_lookup);
+
+  // If a valueOf property is not found on the object check that its
+  // prototype is the un-modified String prototype. If not result is false.
+  __ LoadP(r5, FieldMemOperand(r4, Map::kPrototypeOffset));
+  __ JumpIfSmi(r5, if_false);
+  __ LoadP(r5, FieldMemOperand(r5, HeapObject::kMapOffset));
+  __ LoadP(r6, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+  __ LoadP(r6, FieldMemOperand(r6, GlobalObject::kNativeContextOffset));
+  __ LoadP(r6,
+           ContextOperand(r6, Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX));
+  __ cmp(r5, r6);
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(eq, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(r3, if_false);
+  __ CompareObjectType(r3, r4, r5, JS_FUNCTION_TYPE);
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(eq, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ CheckMap(r3, r4, Heap::kHeapNumberMapRootIndex, if_false, DO_SMI_CHECK);
+#if V8_TARGET_ARCH_PPC64
+  __ LoadP(r4, FieldMemOperand(r3, HeapNumber::kValueOffset));
+  __ li(r5, Operand(1));
+  __ rotrdi(r5, r5, 1);  // r5 = 0x80000000_00000000
+  __ cmp(r4, r5);
+#else
+  __ lwz(r5, FieldMemOperand(r3, HeapNumber::kExponentOffset));
+  __ lwz(r4, FieldMemOperand(r3, HeapNumber::kMantissaOffset));
+  Label skip;
+  __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000)));
+  __ cmp(r5, r0);
+  __ bne(&skip);
+  __ cmpi(r4, Operand::Zero());
+  __ bind(&skip);
+#endif
+
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(eq, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(r3, if_false);
+  __ CompareObjectType(r3, r4, r4, JS_ARRAY_TYPE);
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(eq, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitIsRegExp(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(r3, if_false);
+  __ CompareObjectType(r3, r4, r4, JS_REGEXP_TYPE);
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(eq, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(r3, if_false);
+  Register map = r4;
+  Register type_reg = r5;
+  __ LoadP(map, FieldMemOperand(r3, HeapObject::kMapOffset));
+  __ lbz(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  __ subi(type_reg, type_reg, Operand(FIRST_JS_PROXY_TYPE));
+  __ cmpli(type_reg, Operand(LAST_JS_PROXY_TYPE - FIRST_JS_PROXY_TYPE));
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(le, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
+  DCHECK(expr->arguments()->length() == 0);
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  // Get the frame pointer for the calling frame.
+  __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+
+  // Skip the arguments adaptor frame if it exists.
+  Label check_frame_marker;
+  __ LoadP(r4, MemOperand(r5, StandardFrameConstants::kContextOffset));
+  __ CmpSmiLiteral(r4, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0);
+  __ bne(&check_frame_marker);
+  __ LoadP(r5, MemOperand(r5, StandardFrameConstants::kCallerFPOffset));
+
+  // Check the marker in the calling frame.
+  __ bind(&check_frame_marker);
+  __ LoadP(r4, MemOperand(r5, StandardFrameConstants::kMarkerOffset));
+  STATIC_ASSERT(StackFrame::CONSTRUCT < 0x4000);
+  __ CmpSmiLiteral(r4, Smi::FromInt(StackFrame::CONSTRUCT), r0);
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(eq, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitObjectEquals(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 2);
+
+  // Load the two objects into registers and perform the comparison.
+  VisitForStackValue(args->at(0));
+  VisitForAccumulatorValue(args->at(1));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ pop(r4);
+  __ cmp(r3, r4);
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(eq, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitArguments(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  // ArgumentsAccessStub expects the key in edx and the formal
+  // parameter count in r3.
+  VisitForAccumulatorValue(args->at(0));
+  __ mr(r4, r3);
+  __ LoadSmiLiteral(r3, Smi::FromInt(info_->scope()->num_parameters()));
+  ArgumentsAccessStub stub(isolate(), ArgumentsAccessStub::READ_ELEMENT);
+  __ CallStub(&stub);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitArgumentsLength(CallRuntime* expr) {
+  DCHECK(expr->arguments()->length() == 0);
+  Label exit;
+  // Get the number of formal parameters.
+  __ LoadSmiLiteral(r3, Smi::FromInt(info_->scope()->num_parameters()));
+
+  // Check if the calling frame is an arguments adaptor frame.
+  __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ LoadP(r6, MemOperand(r5, StandardFrameConstants::kContextOffset));
+  __ CmpSmiLiteral(r6, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0);
+  __ bne(&exit);
+
+  // Arguments adaptor case: Read the arguments length from the
+  // adaptor frame.
+  __ LoadP(r3, MemOperand(r5, ArgumentsAdaptorFrameConstants::kLengthOffset));
+
+  __ bind(&exit);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitClassOf(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+  Label done, null, function, non_function_constructor;
+
+  VisitForAccumulatorValue(args->at(0));
+
+  // If the object is a smi, we return null.
+  __ JumpIfSmi(r3, &null);
+
+  // Check that the object is a JS object but take special care of JS
+  // functions to make sure they have 'Function' as their class.
+  // Assume that there are only two callable types, and one of them is at
+  // either end of the type range for JS object types. Saves extra comparisons.
+  STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
+  __ CompareObjectType(r3, r3, r4, FIRST_SPEC_OBJECT_TYPE);
+  // Map is now in r3.
+  __ blt(&null);
+  STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
+                FIRST_SPEC_OBJECT_TYPE + 1);
+  __ beq(&function);
+
+  __ cmpi(r4, Operand(LAST_SPEC_OBJECT_TYPE));
+  STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_SPEC_OBJECT_TYPE - 1);
+  __ beq(&function);
+  // Assume that there is no larger type.
+  STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE - 1);
+
+  // Check if the constructor in the map is a JS function.
+  __ LoadP(r3, FieldMemOperand(r3, Map::kConstructorOffset));
+  __ CompareObjectType(r3, r4, r4, JS_FUNCTION_TYPE);
+  __ bne(&non_function_constructor);
+
+  // r3 now contains the constructor function. Grab the
+  // instance class name from there.
+  __ LoadP(r3, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
+  __ LoadP(r3,
+           FieldMemOperand(r3, SharedFunctionInfo::kInstanceClassNameOffset));
+  __ b(&done);
+
+  // Functions have class 'Function'.
+  __ bind(&function);
+  __ LoadRoot(r3, Heap::kFunction_stringRootIndex);
+  __ b(&done);
+
+  // Objects with a non-function constructor have class 'Object'.
+  __ bind(&non_function_constructor);
+  __ LoadRoot(r3, Heap::kObject_stringRootIndex);
+  __ b(&done);
+
+  // Non-JS objects have class null.
+  __ bind(&null);
+  __ LoadRoot(r3, Heap::kNullValueRootIndex);
+
+  // All done.
+  __ bind(&done);
+
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitSubString(CallRuntime* expr) {
+  // Load the arguments on the stack and call the stub.
+  SubStringStub stub(isolate());
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 3);
+  VisitForStackValue(args->at(0));
+  VisitForStackValue(args->at(1));
+  VisitForStackValue(args->at(2));
+  __ CallStub(&stub);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitRegExpExec(CallRuntime* expr) {
+  // Load the arguments on the stack and call the stub.
+  RegExpExecStub stub(isolate());
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 4);
+  VisitForStackValue(args->at(0));
+  VisitForStackValue(args->at(1));
+  VisitForStackValue(args->at(2));
+  VisitForStackValue(args->at(3));
+  __ CallStub(&stub);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitValueOf(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+  VisitForAccumulatorValue(args->at(0));  // Load the object.
+
+  Label done;
+  // If the object is a smi return the object.
+  __ JumpIfSmi(r3, &done);
+  // If the object is not a value type, return the object.
+  __ CompareObjectType(r3, r4, r4, JS_VALUE_TYPE);
+  __ bne(&done);
+  __ LoadP(r3, FieldMemOperand(r3, JSValue::kValueOffset));
+
+  __ bind(&done);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 2);
+  DCHECK_NE(NULL, args->at(1)->AsLiteral());
+  Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
+
+  VisitForAccumulatorValue(args->at(0));  // Load the object.
+
+  Label runtime, done, not_date_object;
+  Register object = r3;
+  Register result = r3;
+  Register scratch0 = r11;
+  Register scratch1 = r4;
+
+  __ JumpIfSmi(object, &not_date_object);
+  __ CompareObjectType(object, scratch1, scratch1, JS_DATE_TYPE);
+  __ bne(&not_date_object);
+
+  if (index->value() == 0) {
+    __ LoadP(result, FieldMemOperand(object, JSDate::kValueOffset));
+    __ b(&done);
+  } else {
+    if (index->value() < JSDate::kFirstUncachedField) {
+      ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
+      __ mov(scratch1, Operand(stamp));
+      __ LoadP(scratch1, MemOperand(scratch1));
+      __ LoadP(scratch0, FieldMemOperand(object, JSDate::kCacheStampOffset));
+      __ cmp(scratch1, scratch0);
+      __ bne(&runtime);
+      __ LoadP(result,
+               FieldMemOperand(object, JSDate::kValueOffset +
+                                           kPointerSize * index->value()),
+               scratch0);
+      __ b(&done);
+    }
+    __ bind(&runtime);
+    __ PrepareCallCFunction(2, scratch1);
+    __ LoadSmiLiteral(r4, index);
+    __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
+    __ b(&done);
+  }
+
+  __ bind(&not_date_object);
+  __ CallRuntime(Runtime::kThrowNotDateError, 0);
+  __ bind(&done);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK_EQ(3, args->length());
+
+  Register string = r3;
+  Register index = r4;
+  Register value = r5;
+
+  VisitForStackValue(args->at(0));        // index
+  VisitForStackValue(args->at(1));        // value
+  VisitForAccumulatorValue(args->at(2));  // string
+  __ Pop(index, value);
+
+  if (FLAG_debug_code) {
+    __ TestIfSmi(value, r0);
+    __ Check(eq, kNonSmiValue, cr0);
+    __ TestIfSmi(index, r0);
+    __ Check(eq, kNonSmiIndex, cr0);
+    __ SmiUntag(index, index);
+    static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
+    __ EmitSeqStringSetCharCheck(string, index, value, one_byte_seq_type);
+    __ SmiTag(index, index);
+  }
+
+  __ SmiUntag(value);
+  __ addi(ip, string, Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
+  __ SmiToByteArrayOffset(r0, index);
+  __ stbx(value, MemOperand(ip, r0));
+  context()->Plug(string);
+}
+
+
+void FullCodeGenerator::EmitTwoByteSeqStringSetChar(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK_EQ(3, args->length());
+
+  Register string = r3;
+  Register index = r4;
+  Register value = r5;
+
+  VisitForStackValue(args->at(0));        // index
+  VisitForStackValue(args->at(1));        // value
+  VisitForAccumulatorValue(args->at(2));  // string
+  __ Pop(index, value);
+
+  if (FLAG_debug_code) {
+    __ TestIfSmi(value, r0);
+    __ Check(eq, kNonSmiValue, cr0);
+    __ TestIfSmi(index, r0);
+    __ Check(eq, kNonSmiIndex, cr0);
+    __ SmiUntag(index, index);
+    static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
+    __ EmitSeqStringSetCharCheck(string, index, value, two_byte_seq_type);
+    __ SmiTag(index, index);
+  }
+
+  __ SmiUntag(value);
+  __ addi(ip, string, Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
+  __ SmiToShortArrayOffset(r0, index);
+  __ sthx(value, MemOperand(ip, r0));
+  context()->Plug(string);
+}
+
+
+void FullCodeGenerator::EmitMathPow(CallRuntime* expr) {
+  // Load the arguments on the stack and call the runtime function.
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 2);
+  VisitForStackValue(args->at(0));
+  VisitForStackValue(args->at(1));
+  MathPowStub stub(isolate(), MathPowStub::ON_STACK);
+  __ CallStub(&stub);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitSetValueOf(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 2);
+  VisitForStackValue(args->at(0));        // Load the object.
+  VisitForAccumulatorValue(args->at(1));  // Load the value.
+  __ pop(r4);                             // r3 = value. r4 = object.
+
+  Label done;
+  // If the object is a smi, return the value.
+  __ JumpIfSmi(r4, &done);
+
+  // If the object is not a value type, return the value.
+  __ CompareObjectType(r4, r5, r5, JS_VALUE_TYPE);
+  __ bne(&done);
+
+  // Store the value.
+  __ StoreP(r3, FieldMemOperand(r4, JSValue::kValueOffset), r0);
+  // Update the write barrier.  Save the value as it will be
+  // overwritten by the write barrier code and is needed afterward.
+  __ mr(r5, r3);
+  __ RecordWriteField(r4, JSValue::kValueOffset, r5, r6, kLRHasBeenSaved,
+                      kDontSaveFPRegs);
+
+  __ bind(&done);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitNumberToString(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK_EQ(args->length(), 1);
+  // Load the argument into r3 and call the stub.
+  VisitForAccumulatorValue(args->at(0));
+
+  NumberToStringStub stub(isolate());
+  __ CallStub(&stub);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitStringCharFromCode(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+  VisitForAccumulatorValue(args->at(0));
+
+  Label done;
+  StringCharFromCodeGenerator generator(r3, r4);
+  generator.GenerateFast(masm_);
+  __ b(&done);
+
+  NopRuntimeCallHelper call_helper;
+  generator.GenerateSlow(masm_, call_helper);
+
+  __ bind(&done);
+  context()->Plug(r4);
+}
+
+
+void FullCodeGenerator::EmitStringCharCodeAt(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 2);
+  VisitForStackValue(args->at(0));
+  VisitForAccumulatorValue(args->at(1));
+
+  Register object = r4;
+  Register index = r3;
+  Register result = r6;
+
+  __ pop(object);
+
+  Label need_conversion;
+  Label index_out_of_range;
+  Label done;
+  StringCharCodeAtGenerator generator(object, index, result, &need_conversion,
+                                      &need_conversion, &index_out_of_range,
+                                      STRING_INDEX_IS_NUMBER);
+  generator.GenerateFast(masm_);
+  __ b(&done);
+
+  __ bind(&index_out_of_range);
+  // When the index is out of range, the spec requires us to return
+  // NaN.
+  __ LoadRoot(result, Heap::kNanValueRootIndex);
+  __ b(&done);
+
+  __ bind(&need_conversion);
+  // Load the undefined value into the result register, which will
+  // trigger conversion.
+  __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
+  __ b(&done);
+
+  NopRuntimeCallHelper call_helper;
+  generator.GenerateSlow(masm_, call_helper);
+
+  __ bind(&done);
+  context()->Plug(result);
+}
+
+
+void FullCodeGenerator::EmitStringCharAt(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 2);
+  VisitForStackValue(args->at(0));
+  VisitForAccumulatorValue(args->at(1));
+
+  Register object = r4;
+  Register index = r3;
+  Register scratch = r6;
+  Register result = r3;
+
+  __ pop(object);
+
+  Label need_conversion;
+  Label index_out_of_range;
+  Label done;
+  StringCharAtGenerator generator(object, index, scratch, result,
+                                  &need_conversion, &need_conversion,
+                                  &index_out_of_range, STRING_INDEX_IS_NUMBER);
+  generator.GenerateFast(masm_);
+  __ b(&done);
+
+  __ bind(&index_out_of_range);
+  // When the index is out of range, the spec requires us to return
+  // the empty string.
+  __ LoadRoot(result, Heap::kempty_stringRootIndex);
+  __ b(&done);
+
+  __ bind(&need_conversion);
+  // Move smi zero into the result register, which will trigger
+  // conversion.
+  __ LoadSmiLiteral(result, Smi::FromInt(0));
+  __ b(&done);
+
+  NopRuntimeCallHelper call_helper;
+  generator.GenerateSlow(masm_, call_helper);
+
+  __ bind(&done);
+  context()->Plug(result);
+}
+
+
+void FullCodeGenerator::EmitStringAdd(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK_EQ(2, args->length());
+  VisitForStackValue(args->at(0));
+  VisitForAccumulatorValue(args->at(1));
+
+  __ pop(r4);
+  StringAddStub stub(isolate(), STRING_ADD_CHECK_BOTH, NOT_TENURED);
+  __ CallStub(&stub);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitStringCompare(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK_EQ(2, args->length());
+  VisitForStackValue(args->at(0));
+  VisitForStackValue(args->at(1));
+
+  StringCompareStub stub(isolate());
+  __ CallStub(&stub);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() >= 2);
+
+  int arg_count = args->length() - 2;  // 2 ~ receiver and function.
+  for (int i = 0; i < arg_count + 1; i++) {
+    VisitForStackValue(args->at(i));
+  }
+  VisitForAccumulatorValue(args->last());  // Function.
+
+  Label runtime, done;
+  // Check for non-function argument (including proxy).
+  __ JumpIfSmi(r3, &runtime);
+  __ CompareObjectType(r3, r4, r4, JS_FUNCTION_TYPE);
+  __ bne(&runtime);
+
+  // InvokeFunction requires the function in r4. Move it in there.
+  __ mr(r4, result_register());
+  ParameterCount count(arg_count);
+  __ InvokeFunction(r4, count, CALL_FUNCTION, NullCallWrapper());
+  __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  __ b(&done);
+
+  __ bind(&runtime);
+  __ push(r3);
+  __ CallRuntime(Runtime::kCall, args->length());
+  __ bind(&done);
+
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitRegExpConstructResult(CallRuntime* expr) {
+  RegExpConstructResultStub stub(isolate());
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 3);
+  VisitForStackValue(args->at(0));
+  VisitForStackValue(args->at(1));
+  VisitForAccumulatorValue(args->at(2));
+  __ Pop(r5, r4);
+  __ CallStub(&stub);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitGetFromCache(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK_EQ(2, args->length());
+  DCHECK_NE(NULL, args->at(0)->AsLiteral());
+  int cache_id = Smi::cast(*(args->at(0)->AsLiteral()->value()))->value();
+
+  Handle<FixedArray> jsfunction_result_caches(
+      isolate()->native_context()->jsfunction_result_caches());
+  if (jsfunction_result_caches->length() <= cache_id) {
+    __ Abort(kAttemptToUseUndefinedCache);
+    __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
+    context()->Plug(r3);
+    return;
+  }
+
+  VisitForAccumulatorValue(args->at(1));
+
+  Register key = r3;
+  Register cache = r4;
+  __ LoadP(cache, ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX));
+  __ LoadP(cache, FieldMemOperand(cache, GlobalObject::kNativeContextOffset));
+  __ LoadP(cache,
+           ContextOperand(cache, Context::JSFUNCTION_RESULT_CACHES_INDEX));
+  __ LoadP(cache,
+           FieldMemOperand(cache, FixedArray::OffsetOfElementAt(cache_id)), r0);
+
+  Label done, not_found;
+  __ LoadP(r5, FieldMemOperand(cache, JSFunctionResultCache::kFingerOffset));
+  // r5 now holds finger offset as a smi.
+  __ addi(r6, cache, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  // r6 now points to the start of fixed array elements.
+  __ SmiToPtrArrayOffset(r5, r5);
+  __ LoadPUX(r5, MemOperand(r6, r5));
+  // r6 now points to the key of the pair.
+  __ cmp(key, r5);
+  __ bne(&not_found);
+
+  __ LoadP(r3, MemOperand(r6, kPointerSize));
+  __ b(&done);
+
+  __ bind(&not_found);
+  // Call runtime to perform the lookup.
+  __ Push(cache, key);
+  __ CallRuntime(Runtime::kGetFromCache, 2);
+
+  __ bind(&done);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitHasCachedArrayIndex(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ lwz(r3, FieldMemOperand(r3, String::kHashFieldOffset));
+  // PPC - assume ip is free
+  __ mov(ip, Operand(String::kContainsCachedArrayIndexMask));
+  __ and_(r0, r3, ip);
+  __ cmpi(r0, Operand::Zero());
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(eq, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitGetCachedArrayIndex(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+  VisitForAccumulatorValue(args->at(0));
+
+  __ AssertString(r3);
+
+  __ lwz(r3, FieldMemOperand(r3, String::kHashFieldOffset));
+  __ IndexFromHash(r3, r3);
+
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitFastOneByteArrayJoin(CallRuntime* expr) {
+  Label bailout, done, one_char_separator, long_separator, non_trivial_array,
+      not_size_one_array, loop, empty_separator_loop, one_char_separator_loop,
+      one_char_separator_loop_entry, long_separator_loop;
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 2);
+  VisitForStackValue(args->at(1));
+  VisitForAccumulatorValue(args->at(0));
+
+  // All aliases of the same register have disjoint lifetimes.
+  Register array = r3;
+  Register elements = no_reg;  // Will be r3.
+  Register result = no_reg;    // Will be r3.
+  Register separator = r4;
+  Register array_length = r5;
+  Register result_pos = no_reg;  // Will be r5
+  Register string_length = r6;
+  Register string = r7;
+  Register element = r8;
+  Register elements_end = r9;
+  Register scratch1 = r10;
+  Register scratch2 = r11;
+
+  // Separator operand is on the stack.
+  __ pop(separator);
+
+  // Check that the array is a JSArray.
+  __ JumpIfSmi(array, &bailout);
+  __ CompareObjectType(array, scratch1, scratch2, JS_ARRAY_TYPE);
+  __ bne(&bailout);
+
+  // Check that the array has fast elements.
+  __ CheckFastElements(scratch1, scratch2, &bailout);
+
+  // If the array has length zero, return the empty string.
+  __ LoadP(array_length, FieldMemOperand(array, JSArray::kLengthOffset));
+  __ SmiUntag(array_length);
+  __ cmpi(array_length, Operand::Zero());
+  __ bne(&non_trivial_array);
+  __ LoadRoot(r3, Heap::kempty_stringRootIndex);
+  __ b(&done);
+
+  __ bind(&non_trivial_array);
+
+  // Get the FixedArray containing array's elements.
+  elements = array;
+  __ LoadP(elements, FieldMemOperand(array, JSArray::kElementsOffset));
+  array = no_reg;  // End of array's live range.
+
+  // Check that all array elements are sequential one-byte strings, and
+  // accumulate the sum of their lengths, as a smi-encoded value.
+  __ li(string_length, Operand::Zero());
+  __ addi(element, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ ShiftLeftImm(elements_end, array_length, Operand(kPointerSizeLog2));
+  __ add(elements_end, element, elements_end);
+  // Loop condition: while (element < elements_end).
+  // Live values in registers:
+  //   elements: Fixed array of strings.
+  //   array_length: Length of the fixed array of strings (not smi)
+  //   separator: Separator string
+  //   string_length: Accumulated sum of string lengths (smi).
+  //   element: Current array element.
+  //   elements_end: Array end.
+  if (generate_debug_code_) {
+    __ cmpi(array_length, Operand::Zero());
+    __ Assert(gt, kNoEmptyArraysHereInEmitFastOneByteArrayJoin);
+  }
+  __ bind(&loop);
+  __ LoadP(string, MemOperand(element));
+  __ addi(element, element, Operand(kPointerSize));
+  __ JumpIfSmi(string, &bailout);
+  __ LoadP(scratch1, FieldMemOperand(string, HeapObject::kMapOffset));
+  __ lbz(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
+  __ JumpIfInstanceTypeIsNotSequentialOneByte(scratch1, scratch2, &bailout);
+  __ LoadP(scratch1, FieldMemOperand(string, SeqOneByteString::kLengthOffset));
+
+  __ AddAndCheckForOverflow(string_length, string_length, scratch1, scratch2,
+                            r0);
+  __ BranchOnOverflow(&bailout);
+
+  __ cmp(element, elements_end);
+  __ blt(&loop);
+
+  // If array_length is 1, return elements[0], a string.
+  __ cmpi(array_length, Operand(1));
+  __ bne(&not_size_one_array);
+  __ LoadP(r3, FieldMemOperand(elements, FixedArray::kHeaderSize));
+  __ b(&done);
+
+  __ bind(&not_size_one_array);
+
+  // Live values in registers:
+  //   separator: Separator string
+  //   array_length: Length of the array.
+  //   string_length: Sum of string lengths (smi).
+  //   elements: FixedArray of strings.
+
+  // Check that the separator is a flat one-byte string.
+  __ JumpIfSmi(separator, &bailout);
+  __ LoadP(scratch1, FieldMemOperand(separator, HeapObject::kMapOffset));
+  __ lbz(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
+  __ JumpIfInstanceTypeIsNotSequentialOneByte(scratch1, scratch2, &bailout);
+
+  // Add (separator length times array_length) - separator length to the
+  // string_length to get the length of the result string.
+  __ LoadP(scratch1,
+           FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
+  __ sub(string_length, string_length, scratch1);
+#if V8_TARGET_ARCH_PPC64
+  __ SmiUntag(scratch1, scratch1);
+  __ Mul(scratch2, array_length, scratch1);
+  // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are
+  // zero.
+  __ ShiftRightImm(ip, scratch2, Operand(31), SetRC);
+  __ bne(&bailout, cr0);
+  __ SmiTag(scratch2, scratch2);
+#else
+  // array_length is not smi but the other values are, so the result is a smi
+  __ mullw(scratch2, array_length, scratch1);
+  __ mulhw(ip, array_length, scratch1);
+  // Check for smi overflow. No overflow if higher 33 bits of 64-bit result are
+  // zero.
+  __ cmpi(ip, Operand::Zero());
+  __ bne(&bailout);
+  __ cmpwi(scratch2, Operand::Zero());
+  __ blt(&bailout);
+#endif
+
+  __ AddAndCheckForOverflow(string_length, string_length, scratch2, scratch1,
+                            r0);
+  __ BranchOnOverflow(&bailout);
+  __ SmiUntag(string_length);
+
+  // Get first element in the array to free up the elements register to be used
+  // for the result.
+  __ addi(element, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  result = elements;  // End of live range for elements.
+  elements = no_reg;
+  // Live values in registers:
+  //   element: First array element
+  //   separator: Separator string
+  //   string_length: Length of result string (not smi)
+  //   array_length: Length of the array.
+  __ AllocateOneByteString(result, string_length, scratch1, scratch2,
+                           elements_end, &bailout);
+  // Prepare for looping. Set up elements_end to end of the array. Set
+  // result_pos to the position of the result where to write the first
+  // character.
+  __ ShiftLeftImm(elements_end, array_length, Operand(kPointerSizeLog2));
+  __ add(elements_end, element, elements_end);
+  result_pos = array_length;  // End of live range for array_length.
+  array_length = no_reg;
+  __ addi(result_pos, result,
+          Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
+
+  // Check the length of the separator.
+  __ LoadP(scratch1,
+           FieldMemOperand(separator, SeqOneByteString::kLengthOffset));
+  __ CmpSmiLiteral(scratch1, Smi::FromInt(1), r0);
+  __ beq(&one_char_separator);
+  __ bgt(&long_separator);
+
+  // Empty separator case
+  __ bind(&empty_separator_loop);
+  // Live values in registers:
+  //   result_pos: the position to which we are currently copying characters.
+  //   element: Current array element.
+  //   elements_end: Array end.
+
+  // Copy next array element to the result.
+  __ LoadP(string, MemOperand(element));
+  __ addi(element, element, Operand(kPointerSize));
+  __ LoadP(string_length, FieldMemOperand(string, String::kLengthOffset));
+  __ SmiUntag(string_length);
+  __ addi(string, string,
+          Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
+  __ CopyBytes(string, result_pos, string_length, scratch1);
+  __ cmp(element, elements_end);
+  __ blt(&empty_separator_loop);  // End while (element < elements_end).
+  DCHECK(result.is(r3));
+  __ b(&done);
+
+  // One-character separator case
+  __ bind(&one_char_separator);
+  // Replace separator with its one-byte character value.
+  __ lbz(separator, FieldMemOperand(separator, SeqOneByteString::kHeaderSize));
+  // Jump into the loop after the code that copies the separator, so the first
+  // element is not preceded by a separator
+  __ b(&one_char_separator_loop_entry);
+
+  __ bind(&one_char_separator_loop);
+  // Live values in registers:
+  //   result_pos: the position to which we are currently copying characters.
+  //   element: Current array element.
+  //   elements_end: Array end.
+  //   separator: Single separator one-byte char (in lower byte).
+
+  // Copy the separator character to the result.
+  __ stb(separator, MemOperand(result_pos));
+  __ addi(result_pos, result_pos, Operand(1));
+
+  // Copy next array element to the result.
+  __ bind(&one_char_separator_loop_entry);
+  __ LoadP(string, MemOperand(element));
+  __ addi(element, element, Operand(kPointerSize));
+  __ LoadP(string_length, FieldMemOperand(string, String::kLengthOffset));
+  __ SmiUntag(string_length);
+  __ addi(string, string,
+          Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
+  __ CopyBytes(string, result_pos, string_length, scratch1);
+  __ cmpl(element, elements_end);
+  __ blt(&one_char_separator_loop);  // End while (element < elements_end).
+  DCHECK(result.is(r3));
+  __ b(&done);
+
+  // Long separator case (separator is more than one character). Entry is at the
+  // label long_separator below.
+  __ bind(&long_separator_loop);
+  // Live values in registers:
+  //   result_pos: the position to which we are currently copying characters.
+  //   element: Current array element.
+  //   elements_end: Array end.
+  //   separator: Separator string.
+
+  // Copy the separator to the result.
+  __ LoadP(string_length, FieldMemOperand(separator, String::kLengthOffset));
+  __ SmiUntag(string_length);
+  __ addi(string, separator,
+          Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
+  __ CopyBytes(string, result_pos, string_length, scratch1);
+
+  __ bind(&long_separator);
+  __ LoadP(string, MemOperand(element));
+  __ addi(element, element, Operand(kPointerSize));
+  __ LoadP(string_length, FieldMemOperand(string, String::kLengthOffset));
+  __ SmiUntag(string_length);
+  __ addi(string, string,
+          Operand(SeqOneByteString::kHeaderSize - kHeapObjectTag));
+  __ CopyBytes(string, result_pos, string_length, scratch1);
+  __ cmpl(element, elements_end);
+  __ blt(&long_separator_loop);  // End while (element < elements_end).
+  DCHECK(result.is(r3));
+  __ b(&done);
+
+  __ bind(&bailout);
+  __ LoadRoot(r3, Heap::kUndefinedValueRootIndex);
+  __ bind(&done);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::EmitDebugIsActive(CallRuntime* expr) {
+  DCHECK(expr->arguments()->length() == 0);
+  ExternalReference debug_is_active =
+      ExternalReference::debug_is_active_address(isolate());
+  __ mov(ip, Operand(debug_is_active));
+  __ lbz(r3, MemOperand(ip));
+  __ SmiTag(r3);
+  context()->Plug(r3);
+}
+
+
+void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
+  if (expr->function() != NULL &&
+      expr->function()->intrinsic_type == Runtime::INLINE) {
+    Comment cmnt(masm_, "[ InlineRuntimeCall");
+    EmitInlineRuntimeCall(expr);
+    return;
+  }
+
+  Comment cmnt(masm_, "[ CallRuntime");
+  ZoneList<Expression*>* args = expr->arguments();
+  int arg_count = args->length();
+
+  if (expr->is_jsruntime()) {
+    // Push the builtins object as the receiver.
+    Register receiver = LoadDescriptor::ReceiverRegister();
+    __ LoadP(receiver, GlobalObjectOperand());
+    __ LoadP(receiver,
+             FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset));
+    __ push(receiver);
+
+    // Load the function from the receiver.
+    __ mov(LoadDescriptor::NameRegister(), Operand(expr->name()));
+    if (FLAG_vector_ics) {
+      __ mov(VectorLoadICDescriptor::SlotRegister(),
+             Operand(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
+      CallLoadIC(NOT_CONTEXTUAL);
+    } else {
+      CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
+    }
+
+    // Push the target function under the receiver.
+    __ LoadP(ip, MemOperand(sp, 0));
+    __ push(ip);
+    __ StoreP(r3, MemOperand(sp, kPointerSize));
+
+    // Push the arguments ("left-to-right").
+    int arg_count = args->length();
+    for (int i = 0; i < arg_count; i++) {
+      VisitForStackValue(args->at(i));
+    }
+
+    // Record source position of the IC call.
+    SetSourcePosition(expr->position());
+    CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
+    __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
+    __ CallStub(&stub);
+
+    // Restore context register.
+    __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+
+    context()->DropAndPlug(1, r3);
+  } else {
+    // Push the arguments ("left-to-right").
+    for (int i = 0; i < arg_count; i++) {
+      VisitForStackValue(args->at(i));
+    }
+
+    // Call the C runtime function.
+    __ CallRuntime(expr->function(), arg_count);
+    context()->Plug(r3);
+  }
+}
+
+
+void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
+  switch (expr->op()) {
+    case Token::DELETE: {
+      Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
+      Property* property = expr->expression()->AsProperty();
+      VariableProxy* proxy = expr->expression()->AsVariableProxy();
+
+      if (property != NULL) {
+        VisitForStackValue(property->obj());
+        VisitForStackValue(property->key());
+        __ LoadSmiLiteral(r4, Smi::FromInt(strict_mode()));
+        __ push(r4);
+        __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+        context()->Plug(r3);
+      } else if (proxy != NULL) {
+        Variable* var = proxy->var();
+        // Delete of an unqualified identifier is disallowed in strict mode
+        // but "delete this" is allowed.
+        DCHECK(strict_mode() == SLOPPY || var->is_this());
+        if (var->IsUnallocated()) {
+          __ LoadP(r5, GlobalObjectOperand());
+          __ mov(r4, Operand(var->name()));
+          __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY));
+          __ Push(r5, r4, r3);
+          __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
+          context()->Plug(r3);
+        } else if (var->IsStackAllocated() || var->IsContextSlot()) {
+          // Result of deleting non-global, non-dynamic variables is false.
+          // The subexpression does not have side effects.
+          context()->Plug(var->is_this());
+        } else {
+          // Non-global variable.  Call the runtime to try to delete from the
+          // context where the variable was introduced.
+          DCHECK(!context_register().is(r5));
+          __ mov(r5, Operand(var->name()));
+          __ Push(context_register(), r5);
+          __ CallRuntime(Runtime::kDeleteLookupSlot, 2);
+          context()->Plug(r3);
+        }
+      } else {
+        // Result of deleting non-property, non-variable reference is true.
+        // The subexpression may have side effects.
+        VisitForEffect(expr->expression());
+        context()->Plug(true);
+      }
+      break;
+    }
+
+    case Token::VOID: {
+      Comment cmnt(masm_, "[ UnaryOperation (VOID)");
+      VisitForEffect(expr->expression());
+      context()->Plug(Heap::kUndefinedValueRootIndex);
+      break;
+    }
+
+    case Token::NOT: {
+      Comment cmnt(masm_, "[ UnaryOperation (NOT)");
+      if (context()->IsEffect()) {
+        // Unary NOT has no side effects so it's only necessary to visit the
+        // subexpression.  Match the optimizing compiler by not branching.
+        VisitForEffect(expr->expression());
+      } else if (context()->IsTest()) {
+        const TestContext* test = TestContext::cast(context());
+        // The labels are swapped for the recursive call.
+        VisitForControl(expr->expression(), test->false_label(),
+                        test->true_label(), test->fall_through());
+        context()->Plug(test->true_label(), test->false_label());
+      } else {
+        // We handle value contexts explicitly rather than simply visiting
+        // for control and plugging the control flow into the context,
+        // because we need to prepare a pair of extra administrative AST ids
+        // for the optimizing compiler.
+        DCHECK(context()->IsAccumulatorValue() || context()->IsStackValue());
+        Label materialize_true, materialize_false, done;
+        VisitForControl(expr->expression(), &materialize_false,
+                        &materialize_true, &materialize_true);
+        __ bind(&materialize_true);
+        PrepareForBailoutForId(expr->MaterializeTrueId(), NO_REGISTERS);
+        __ LoadRoot(r3, Heap::kTrueValueRootIndex);
+        if (context()->IsStackValue()) __ push(r3);
+        __ b(&done);
+        __ bind(&materialize_false);
+        PrepareForBailoutForId(expr->MaterializeFalseId(), NO_REGISTERS);
+        __ LoadRoot(r3, Heap::kFalseValueRootIndex);
+        if (context()->IsStackValue()) __ push(r3);
+        __ bind(&done);
+      }
+      break;
+    }
+
+    case Token::TYPEOF: {
+      Comment cmnt(masm_, "[ UnaryOperation (TYPEOF)");
+      {
+        StackValueContext context(this);
+        VisitForTypeofValue(expr->expression());
+      }
+      __ CallRuntime(Runtime::kTypeof, 1);
+      context()->Plug(r3);
+      break;
+    }
+
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
+  DCHECK(expr->expression()->IsValidReferenceExpression());
+
+  Comment cmnt(masm_, "[ CountOperation");
+  SetSourcePosition(expr->position());
+
+  Property* prop = expr->expression()->AsProperty();
+  LhsKind assign_type = GetAssignType(prop);
+
+  // Evaluate expression and get value.
+  if (assign_type == VARIABLE) {
+    DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
+    AccumulatorValueContext context(this);
+    EmitVariableLoad(expr->expression()->AsVariableProxy());
+  } else {
+    // Reserve space for result of postfix operation.
+    if (expr->is_postfix() && !context()->IsEffect()) {
+      __ LoadSmiLiteral(ip, Smi::FromInt(0));
+      __ push(ip);
+    }
+    switch (assign_type) {
+      case NAMED_PROPERTY: {
+        // Put the object both on the stack and in the register.
+        VisitForStackValue(prop->obj());
+        __ LoadP(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0));
+        EmitNamedPropertyLoad(prop);
+        break;
+      }
+
+      case NAMED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        const Register scratch = r4;
+        __ LoadP(scratch, MemOperand(sp, kPointerSize));
+        __ Push(scratch, result_register());
+        EmitNamedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        const Register scratch = r4;
+        const Register scratch1 = r5;
+        __ Move(scratch, result_register());
+        VisitForAccumulatorValue(prop->key());
+        __ Push(scratch, result_register());
+        __ LoadP(scratch1, MemOperand(sp, 2 * kPointerSize));
+        __ Push(scratch1, scratch, result_register());
+        EmitKeyedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_PROPERTY: {
+        VisitForStackValue(prop->obj());
+        VisitForStackValue(prop->key());
+        __ LoadP(LoadDescriptor::ReceiverRegister(),
+                 MemOperand(sp, 1 * kPointerSize));
+        __ LoadP(LoadDescriptor::NameRegister(), MemOperand(sp, 0));
+        EmitKeyedPropertyLoad(prop);
+        break;
+      }
+
+      case VARIABLE:
+        UNREACHABLE();
+    }
+  }
+
+  // We need a second deoptimization point after loading the value
+  // in case evaluating the property load my have a side effect.
+  if (assign_type == VARIABLE) {
+    PrepareForBailout(expr->expression(), TOS_REG);
+  } else {
+    PrepareForBailoutForId(prop->LoadId(), TOS_REG);
+  }
+
+  // Inline smi case if we are in a loop.
+  Label stub_call, done;
+  JumpPatchSite patch_site(masm_);
+
+  int count_value = expr->op() == Token::INC ? 1 : -1;
+  if (ShouldInlineSmiCase(expr->op())) {
+    Label slow;
+    patch_site.EmitJumpIfNotSmi(r3, &slow);
+
+    // Save result for postfix expressions.
+    if (expr->is_postfix()) {
+      if (!context()->IsEffect()) {
+        // Save the result on the stack. If we have a named or keyed property
+        // we store the result under the receiver that is currently on top
+        // of the stack.
+        switch (assign_type) {
+          case VARIABLE:
+            __ push(r3);
+            break;
+          case NAMED_PROPERTY:
+            __ StoreP(r3, MemOperand(sp, kPointerSize));
+            break;
+          case NAMED_SUPER_PROPERTY:
+            __ StoreP(r3, MemOperand(sp, 2 * kPointerSize));
+            break;
+          case KEYED_PROPERTY:
+            __ StoreP(r3, MemOperand(sp, 2 * kPointerSize));
+            break;
+          case KEYED_SUPER_PROPERTY:
+            __ StoreP(r3, MemOperand(sp, 3 * kPointerSize));
+            break;
+        }
+      }
+    }
+
+    Register scratch1 = r4;
+    Register scratch2 = r5;
+    __ LoadSmiLiteral(scratch1, Smi::FromInt(count_value));
+    __ AddAndCheckForOverflow(r3, r3, scratch1, scratch2, r0);
+    __ BranchOnNoOverflow(&done);
+    // Call stub. Undo operation first.
+    __ sub(r3, r3, scratch1);
+    __ b(&stub_call);
+    __ bind(&slow);
+  }
+  ToNumberStub convert_stub(isolate());
+  __ CallStub(&convert_stub);
+
+  // Save result for postfix expressions.
+  if (expr->is_postfix()) {
+    if (!context()->IsEffect()) {
+      // Save the result on the stack. If we have a named or keyed property
+      // we store the result under the receiver that is currently on top
+      // of the stack.
+      switch (assign_type) {
+        case VARIABLE:
+          __ push(r3);
+          break;
+        case NAMED_PROPERTY:
+          __ StoreP(r3, MemOperand(sp, kPointerSize));
+          break;
+        case NAMED_SUPER_PROPERTY:
+          __ StoreP(r3, MemOperand(sp, 2 * kPointerSize));
+          break;
+        case KEYED_PROPERTY:
+          __ StoreP(r3, MemOperand(sp, 2 * kPointerSize));
+          break;
+        case KEYED_SUPER_PROPERTY:
+          __ StoreP(r3, MemOperand(sp, 3 * kPointerSize));
+          break;
+      }
+    }
+  }
+
+  __ bind(&stub_call);
+  __ mr(r4, r3);
+  __ LoadSmiLiteral(r3, Smi::FromInt(count_value));
+
+  // Record position before stub call.
+  SetSourcePosition(expr->position());
+
+  Handle<Code> code =
+      CodeFactory::BinaryOpIC(isolate(), Token::ADD, NO_OVERWRITE).code();
+  CallIC(code, expr->CountBinOpFeedbackId());
+  patch_site.EmitPatchInfo();
+  __ bind(&done);
+
+  // Store the value returned in r3.
+  switch (assign_type) {
+    case VARIABLE:
+      if (expr->is_postfix()) {
+        {
+          EffectContext context(this);
+          EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
+                                 Token::ASSIGN);
+          PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
+          context.Plug(r3);
+        }
+        // For all contexts except EffectConstant We have the result on
+        // top of the stack.
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
+                               Token::ASSIGN);
+        PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
+        context()->Plug(r3);
+      }
+      break;
+    case NAMED_PROPERTY: {
+      __ mov(StoreDescriptor::NameRegister(),
+             Operand(prop->key()->AsLiteral()->value()));
+      __ pop(StoreDescriptor::ReceiverRegister());
+      CallStoreIC(expr->CountStoreFeedbackId());
+      PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(r3);
+      }
+      break;
+    }
+    case NAMED_SUPER_PROPERTY: {
+      EmitNamedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(r3);
+      }
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      EmitKeyedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(r3);
+      }
+      break;
+    }
+    case KEYED_PROPERTY: {
+      __ Pop(StoreDescriptor::ReceiverRegister(),
+             StoreDescriptor::NameRegister());
+      Handle<Code> ic =
+          CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
+      CallIC(ic, expr->CountStoreFeedbackId());
+      PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(r3);
+      }
+      break;
+    }
+  }
+}
+
+
+void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
+  DCHECK(!context()->IsEffect());
+  DCHECK(!context()->IsTest());
+  VariableProxy* proxy = expr->AsVariableProxy();
+  if (proxy != NULL && proxy->var()->IsUnallocated()) {
+    Comment cmnt(masm_, "[ Global variable");
+    __ LoadP(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
+    __ mov(LoadDescriptor::NameRegister(), Operand(proxy->name()));
+    if (FLAG_vector_ics) {
+      __ mov(VectorLoadICDescriptor::SlotRegister(),
+             Operand(SmiFromSlot(proxy->VariableFeedbackSlot())));
+    }
+    // Use a regular load, not a contextual load, to avoid a reference
+    // error.
+    CallLoadIC(NOT_CONTEXTUAL);
+    PrepareForBailout(expr, TOS_REG);
+    context()->Plug(r3);
+  } else if (proxy != NULL && proxy->var()->IsLookupSlot()) {
+    Comment cmnt(masm_, "[ Lookup slot");
+    Label done, slow;
+
+    // Generate code for loading from variables potentially shadowed
+    // by eval-introduced variables.
+    EmitDynamicLookupFastCase(proxy, INSIDE_TYPEOF, &slow, &done);
+
+    __ bind(&slow);
+    __ mov(r3, Operand(proxy->name()));
+    __ Push(cp, r3);
+    __ CallRuntime(Runtime::kLoadLookupSlotNoReferenceError, 2);
+    PrepareForBailout(expr, TOS_REG);
+    __ bind(&done);
+
+    context()->Plug(r3);
+  } else {
+    // This expression cannot throw a reference error at the top level.
+    VisitInDuplicateContext(expr);
+  }
+}
+
+
+void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
+                                                 Expression* sub_expr,
+                                                 Handle<String> check) {
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  {
+    AccumulatorValueContext context(this);
+    VisitForTypeofValue(sub_expr);
+  }
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+
+  Factory* factory = isolate()->factory();
+  if (String::Equals(check, factory->number_string())) {
+    __ JumpIfSmi(r3, if_true);
+    __ LoadP(r3, FieldMemOperand(r3, HeapObject::kMapOffset));
+    __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
+    __ cmp(r3, ip);
+    Split(eq, if_true, if_false, fall_through);
+  } else if (String::Equals(check, factory->string_string())) {
+    __ JumpIfSmi(r3, if_false);
+    // Check for undetectable objects => false.
+    __ CompareObjectType(r3, r3, r4, FIRST_NONSTRING_TYPE);
+    __ bge(if_false);
+    __ lbz(r4, FieldMemOperand(r3, Map::kBitFieldOffset));
+    STATIC_ASSERT((1 << Map::kIsUndetectable) < 0x8000);
+    __ andi(r0, r4, Operand(1 << Map::kIsUndetectable));
+    Split(eq, if_true, if_false, fall_through, cr0);
+  } else if (String::Equals(check, factory->symbol_string())) {
+    __ JumpIfSmi(r3, if_false);
+    __ CompareObjectType(r3, r3, r4, SYMBOL_TYPE);
+    Split(eq, if_true, if_false, fall_through);
+  } else if (String::Equals(check, factory->boolean_string())) {
+    __ CompareRoot(r3, Heap::kTrueValueRootIndex);
+    __ beq(if_true);
+    __ CompareRoot(r3, Heap::kFalseValueRootIndex);
+    Split(eq, if_true, if_false, fall_through);
+  } else if (String::Equals(check, factory->undefined_string())) {
+    __ CompareRoot(r3, Heap::kUndefinedValueRootIndex);
+    __ beq(if_true);
+    __ JumpIfSmi(r3, if_false);
+    // Check for undetectable objects => true.
+    __ LoadP(r3, FieldMemOperand(r3, HeapObject::kMapOffset));
+    __ lbz(r4, FieldMemOperand(r3, Map::kBitFieldOffset));
+    __ andi(r0, r4, Operand(1 << Map::kIsUndetectable));
+    Split(ne, if_true, if_false, fall_through, cr0);
+
+  } else if (String::Equals(check, factory->function_string())) {
+    __ JumpIfSmi(r3, if_false);
+    STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
+    __ CompareObjectType(r3, r3, r4, JS_FUNCTION_TYPE);
+    __ beq(if_true);
+    __ cmpi(r4, Operand(JS_FUNCTION_PROXY_TYPE));
+    Split(eq, if_true, if_false, fall_through);
+  } else if (String::Equals(check, factory->object_string())) {
+    __ JumpIfSmi(r3, if_false);
+    __ CompareRoot(r3, Heap::kNullValueRootIndex);
+    __ beq(if_true);
+    // Check for JS objects => true.
+    __ CompareObjectType(r3, r3, r4, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
+    __ blt(if_false);
+    __ CompareInstanceType(r3, r4, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+    __ bgt(if_false);
+    // Check for undetectable objects => false.
+    __ lbz(r4, FieldMemOperand(r3, Map::kBitFieldOffset));
+    __ andi(r0, r4, Operand(1 << Map::kIsUndetectable));
+    Split(eq, if_true, if_false, fall_through, cr0);
+  } else {
+    if (if_false != fall_through) __ b(if_false);
+  }
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) {
+  Comment cmnt(masm_, "[ CompareOperation");
+  SetSourcePosition(expr->position());
+
+  // First we try a fast inlined version of the compare when one of
+  // the operands is a literal.
+  if (TryLiteralCompare(expr)) return;
+
+  // Always perform the comparison for its control flow.  Pack the result
+  // into the expression's context after the comparison is performed.
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  Token::Value op = expr->op();
+  VisitForStackValue(expr->left());
+  switch (op) {
+    case Token::IN:
+      VisitForStackValue(expr->right());
+      __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION);
+      PrepareForBailoutBeforeSplit(expr, false, NULL, NULL);
+      __ LoadRoot(ip, Heap::kTrueValueRootIndex);
+      __ cmp(r3, ip);
+      Split(eq, if_true, if_false, fall_through);
+      break;
+
+    case Token::INSTANCEOF: {
+      VisitForStackValue(expr->right());
+      InstanceofStub stub(isolate(), InstanceofStub::kNoFlags);
+      __ CallStub(&stub);
+      PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+      // The stub returns 0 for true.
+      __ cmpi(r3, Operand::Zero());
+      Split(eq, if_true, if_false, fall_through);
+      break;
+    }
+
+    default: {
+      VisitForAccumulatorValue(expr->right());
+      Condition cond = CompareIC::ComputeCondition(op);
+      __ pop(r4);
+
+      bool inline_smi_code = ShouldInlineSmiCase(op);
+      JumpPatchSite patch_site(masm_);
+      if (inline_smi_code) {
+        Label slow_case;
+        __ orx(r5, r3, r4);
+        patch_site.EmitJumpIfNotSmi(r5, &slow_case);
+        __ cmp(r4, r3);
+        Split(cond, if_true, if_false, NULL);
+        __ bind(&slow_case);
+      }
+
+      // Record position and call the compare IC.
+      SetSourcePosition(expr->position());
+      Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code();
+      CallIC(ic, expr->CompareOperationFeedbackId());
+      patch_site.EmitPatchInfo();
+      PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+      __ cmpi(r3, Operand::Zero());
+      Split(cond, if_true, if_false, fall_through);
+    }
+  }
+
+  // Convert the result of the comparison into one expected for this
+  // expression's context.
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::EmitLiteralCompareNil(CompareOperation* expr,
+                                              Expression* sub_expr,
+                                              NilValue nil) {
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  VisitForAccumulatorValue(sub_expr);
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  if (expr->op() == Token::EQ_STRICT) {
+    Heap::RootListIndex nil_value = nil == kNullValue
+                                        ? Heap::kNullValueRootIndex
+                                        : Heap::kUndefinedValueRootIndex;
+    __ LoadRoot(r4, nil_value);
+    __ cmp(r3, r4);
+    Split(eq, if_true, if_false, fall_through);
+  } else {
+    Handle<Code> ic = CompareNilICStub::GetUninitialized(isolate(), nil);
+    CallIC(ic, expr->CompareOperationFeedbackId());
+    __ cmpi(r3, Operand::Zero());
+    Split(ne, if_true, if_false, fall_through);
+  }
+  context()->Plug(if_true, if_false);
+}
+
+
+void FullCodeGenerator::VisitThisFunction(ThisFunction* expr) {
+  __ LoadP(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  context()->Plug(r3);
+}
+
+
+Register FullCodeGenerator::result_register() { return r3; }
+
+
+Register FullCodeGenerator::context_register() { return cp; }
+
+
+void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
+  DCHECK_EQ(static_cast<int>(POINTER_SIZE_ALIGN(frame_offset)), frame_offset);
+  __ StoreP(value, MemOperand(fp, frame_offset), r0);
+}
+
+
+void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
+  __ LoadP(dst, ContextOperand(cp, context_index), r0);
+}
+
+
+void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
+  Scope* declaration_scope = scope()->DeclarationScope();
+  if (declaration_scope->is_script_scope() ||
+      declaration_scope->is_module_scope()) {
+    // Contexts nested in the native 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
+    // function.
+    __ LoadSmiLiteral(ip, Smi::FromInt(0));
+  } else if (declaration_scope->is_eval_scope()) {
+    // Contexts created by a call to eval have the same closure as the
+    // context calling eval, not the anonymous closure containing the eval
+    // code.  Fetch it from the context.
+    __ LoadP(ip, ContextOperand(cp, Context::CLOSURE_INDEX));
+  } else {
+    DCHECK(declaration_scope->is_function_scope());
+    __ LoadP(ip, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+  }
+  __ push(ip);
+}
+
+
+// ----------------------------------------------------------------------------
+// Non-local control flow support.
+
+void FullCodeGenerator::EnterFinallyBlock() {
+  DCHECK(!result_register().is(r4));
+  // Store result register while executing finally block.
+  __ push(result_register());
+  // Cook return address in link register to stack (smi encoded Code* delta)
+  __ mflr(r4);
+  __ mov(ip, Operand(masm_->CodeObject()));
+  __ sub(r4, r4, ip);
+  __ SmiTag(r4);
+
+  // Store result register while executing finally block.
+  __ push(r4);
+
+  // Store pending message while executing finally block.
+  ExternalReference pending_message_obj =
+      ExternalReference::address_of_pending_message_obj(isolate());
+  __ mov(ip, Operand(pending_message_obj));
+  __ LoadP(r4, MemOperand(ip));
+  __ push(r4);
+
+  ExternalReference has_pending_message =
+      ExternalReference::address_of_has_pending_message(isolate());
+  __ mov(ip, Operand(has_pending_message));
+  __ lbz(r4, MemOperand(ip));
+  __ SmiTag(r4);
+  __ push(r4);
+
+  ExternalReference pending_message_script =
+      ExternalReference::address_of_pending_message_script(isolate());
+  __ mov(ip, Operand(pending_message_script));
+  __ LoadP(r4, MemOperand(ip));
+  __ push(r4);
+}
+
+
+void FullCodeGenerator::ExitFinallyBlock() {
+  DCHECK(!result_register().is(r4));
+  // Restore pending message from stack.
+  __ pop(r4);
+  ExternalReference pending_message_script =
+      ExternalReference::address_of_pending_message_script(isolate());
+  __ mov(ip, Operand(pending_message_script));
+  __ StoreP(r4, MemOperand(ip));
+
+  __ pop(r4);
+  __ SmiUntag(r4);
+  ExternalReference has_pending_message =
+      ExternalReference::address_of_has_pending_message(isolate());
+  __ mov(ip, Operand(has_pending_message));
+  __ stb(r4, MemOperand(ip));
+
+  __ pop(r4);
+  ExternalReference pending_message_obj =
+      ExternalReference::address_of_pending_message_obj(isolate());
+  __ mov(ip, Operand(pending_message_obj));
+  __ StoreP(r4, MemOperand(ip));
+
+  // Restore result register from stack.
+  __ pop(r4);
+
+  // Uncook return address and return.
+  __ pop(result_register());
+  __ SmiUntag(r4);
+  __ mov(ip, Operand(masm_->CodeObject()));
+  __ add(ip, ip, r4);
+  __ mtctr(ip);
+  __ bctr();
+}
+
+
+#undef __
+
+#define __ ACCESS_MASM(masm())
+
+FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit(
+    int* stack_depth, int* context_length) {
+  // The macros used here must preserve the result register.
+
+  // Because the handler block contains the context of the finally
+  // code, we can restore it directly from there for the finally code
+  // rather than iteratively unwinding contexts via their previous
+  // links.
+  __ Drop(*stack_depth);  // Down to the handler block.
+  if (*context_length > 0) {
+    // Restore the context to its dedicated register and the stack.
+    __ LoadP(cp, MemOperand(sp, StackHandlerConstants::kContextOffset));
+    __ StoreP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  }
+  __ PopTryHandler();
+  __ b(finally_entry_, SetLK);
+
+  *stack_depth = 0;
+  *context_length = 0;
+  return previous_;
+}
+
+#undef __
+
+
+void BackEdgeTable::PatchAt(Code* unoptimized_code, Address pc,
+                            BackEdgeState target_state,
+                            Code* replacement_code) {
+  Address mov_address = Assembler::target_address_from_return_address(pc);
+  Address cmp_address = mov_address - 2 * Assembler::kInstrSize;
+  CodePatcher patcher(cmp_address, 1);
+
+  switch (target_state) {
+    case INTERRUPT: {
+      //  <decrement profiling counter>
+      //         cmpi    r6, 0
+      //         bge     <ok>            ;; not changed
+      //         mov     r12, <interrupt stub address>
+      //         mtlr    r12
+      //         blrl
+      //  <reset profiling counter>
+      //  ok-label
+      patcher.masm()->cmpi(r6, Operand::Zero());
+      break;
+    }
+    case ON_STACK_REPLACEMENT:
+    case OSR_AFTER_STACK_CHECK:
+      //  <decrement profiling counter>
+      //         crset
+      //         bge     <ok>            ;; not changed
+      //         mov     r12, <on-stack replacement address>
+      //         mtlr    r12
+      //         blrl
+      //  <reset profiling counter>
+      //  ok-label ----- pc_after points here
+
+      // Set the LT bit such that bge is a NOP
+      patcher.masm()->crset(Assembler::encode_crbit(cr7, CR_LT));
+      break;
+  }
+
+  // Replace the stack check address in the mov sequence with the
+  // entry address of the replacement code.
+  Assembler::set_target_address_at(mov_address, unoptimized_code,
+                                   replacement_code->entry());
+
+  unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch(
+      unoptimized_code, mov_address, replacement_code);
+}
+
+
+BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState(
+    Isolate* isolate, Code* unoptimized_code, Address pc) {
+  Address mov_address = Assembler::target_address_from_return_address(pc);
+  Address cmp_address = mov_address - 2 * Assembler::kInstrSize;
+  Address interrupt_address =
+      Assembler::target_address_at(mov_address, unoptimized_code);
+
+  if (Assembler::IsCmpImmediate(Assembler::instr_at(cmp_address))) {
+    DCHECK(interrupt_address == isolate->builtins()->InterruptCheck()->entry());
+    return INTERRUPT;
+  }
+
+  DCHECK(Assembler::IsCrSet(Assembler::instr_at(cmp_address)));
+
+  if (interrupt_address == isolate->builtins()->OnStackReplacement()->entry()) {
+    return ON_STACK_REPLACEMENT;
+  }
+
+  DCHECK(interrupt_address ==
+         isolate->builtins()->OsrAfterStackCheck()->entry());
+  return OSR_AFTER_STACK_CHECK;
+}
+}
+}  // namespace v8::internal
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/interface-descriptors-ppc.cc b/src/ppc/interface-descriptors-ppc.cc
new file mode 100644
index 0000000..693f341
--- /dev/null
+++ b/src/ppc/interface-descriptors-ppc.cc
@@ -0,0 +1,306 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/interface-descriptors.h"
+
+namespace v8 {
+namespace internal {
+
+const Register CallInterfaceDescriptor::ContextRegister() { return cp; }
+
+
+const Register LoadDescriptor::ReceiverRegister() { return r4; }
+const Register LoadDescriptor::NameRegister() { return r5; }
+
+
+const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return r3; }
+
+
+const Register VectorLoadICDescriptor::VectorRegister() { return r6; }
+
+
+const Register StoreDescriptor::ReceiverRegister() { return r4; }
+const Register StoreDescriptor::NameRegister() { return r5; }
+const Register StoreDescriptor::ValueRegister() { return r3; }
+
+
+const Register StoreTransitionDescriptor::MapRegister() { return r6; }
+
+
+const Register ElementTransitionAndStoreDescriptor::MapRegister() { return r6; }
+
+
+const Register InstanceofDescriptor::left() { return r3; }
+const Register InstanceofDescriptor::right() { return r4; }
+
+
+const Register ArgumentsAccessReadDescriptor::index() { return r4; }
+const Register ArgumentsAccessReadDescriptor::parameter_count() { return r3; }
+
+
+const Register ApiGetterDescriptor::function_address() { return r5; }
+
+
+const Register MathPowTaggedDescriptor::exponent() { return r5; }
+
+
+const Register MathPowIntegerDescriptor::exponent() {
+  return MathPowTaggedDescriptor::exponent();
+}
+
+
+void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r5};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void FastNewContextDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r4};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void ToNumberDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r3};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void NumberToStringDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r3};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void FastCloneShallowArrayDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r6, r5, r4};
+  Representation representations[] = {
+      Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
+      Representation::Tagged()};
+  data->Initialize(arraysize(registers), registers, representations);
+}
+
+
+void FastCloneShallowObjectDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r6, r5, r4, r3};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void CreateAllocationSiteDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r5, r6};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void StoreArrayLiteralElementDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r6, r3};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r4};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void CallFunctionWithFeedbackDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r4, r6};
+  Representation representations[] = {Representation::Tagged(),
+                                      Representation::Tagged(),
+                                      Representation::Smi()};
+  data->Initialize(arraysize(registers), registers, representations);
+}
+
+
+void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  // r3 : number of arguments
+  // r4 : the function to call
+  // r5 : feedback vector
+  // r6 : (only if r5 is not the megamorphic symbol) slot in feedback
+  //      vector (Smi)
+  // TODO(turbofan): So far we don't gather type feedback and hence skip the
+  // slot parameter, but ArrayConstructStub needs the vector to be undefined.
+  Register registers[] = {cp, r3, r4, r5};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void RegExpConstructResultDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r5, r4, r3};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void TransitionElementsKindDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r3, r4};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void ArrayConstructorConstantArgCountDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  // register state
+  // cp -- context
+  // r3 -- number of arguments
+  // r4 -- function
+  // r5 -- allocation site with elements kind
+  Register registers[] = {cp, r4, r5};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void ArrayConstructorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  // stack param count needs (constructor pointer, and single argument)
+  Register registers[] = {cp, r4, r5, r3};
+  Representation representations[] = {
+      Representation::Tagged(), Representation::Tagged(),
+      Representation::Tagged(), Representation::Integer32()};
+  data->Initialize(arraysize(registers), registers, representations);
+}
+
+
+void InternalArrayConstructorConstantArgCountDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  // register state
+  // cp -- context
+  // r3 -- number of arguments
+  // r4 -- constructor function
+  Register registers[] = {cp, r4};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void InternalArrayConstructorDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  // stack param count needs (constructor pointer, and single argument)
+  Register registers[] = {cp, r4, r3};
+  Representation representations[] = {Representation::Tagged(),
+                                      Representation::Tagged(),
+                                      Representation::Integer32()};
+  data->Initialize(arraysize(registers), registers, representations);
+}
+
+
+void CompareNilDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r3};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void ToBooleanDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r3};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void BinaryOpDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r4, r3};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void BinaryOpWithAllocationSiteDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r5, r4, r3};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void StringAddDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {cp, r4, r3};
+  data->Initialize(arraysize(registers), registers, NULL);
+}
+
+
+void KeyedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {
+      cp,  // context
+      r5,  // key
+  };
+  Representation representations[] = {
+      Representation::Tagged(),  // context
+      Representation::Tagged(),  // key
+  };
+  data->Initialize(arraysize(registers), registers, representations);
+}
+
+
+void NamedDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {
+      cp,  // context
+      r5,  // name
+  };
+  Representation representations[] = {
+      Representation::Tagged(),  // context
+      Representation::Tagged(),  // name
+  };
+  data->Initialize(arraysize(registers), registers, representations);
+}
+
+
+void CallHandlerDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {
+      cp,  // context
+      r3,  // receiver
+  };
+  Representation representations[] = {
+      Representation::Tagged(),  // context
+      Representation::Tagged(),  // receiver
+  };
+  data->Initialize(arraysize(registers), registers, representations);
+}
+
+
+void ArgumentAdaptorDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {
+      cp,  // context
+      r4,  // JSFunction
+      r3,  // actual number of arguments
+      r5,  // expected number of arguments
+  };
+  Representation representations[] = {
+      Representation::Tagged(),     // context
+      Representation::Tagged(),     // JSFunction
+      Representation::Integer32(),  // actual number of arguments
+      Representation::Integer32(),  // expected number of arguments
+  };
+  data->Initialize(arraysize(registers), registers, representations);
+}
+
+
+void ApiFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) {
+  Register registers[] = {
+      cp,  // context
+      r3,  // callee
+      r7,  // call_data
+      r5,  // holder
+      r4,  // api_function_address
+  };
+  Representation representations[] = {
+      Representation::Tagged(),    // context
+      Representation::Tagged(),    // callee
+      Representation::Tagged(),    // call_data
+      Representation::Tagged(),    // holder
+      Representation::External(),  // api_function_address
+  };
+  data->Initialize(arraysize(registers), registers, representations);
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/lithium-codegen-ppc.cc b/src/ppc/lithium-codegen-ppc.cc
new file mode 100644
index 0000000..7b6052c
--- /dev/null
+++ b/src/ppc/lithium-codegen-ppc.cc
@@ -0,0 +1,6136 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/base/bits.h"
+#include "src/code-factory.h"
+#include "src/code-stubs.h"
+#include "src/hydrogen-osr.h"
+#include "src/ic/ic.h"
+#include "src/ic/stub-cache.h"
+#include "src/ppc/lithium-codegen-ppc.h"
+#include "src/ppc/lithium-gap-resolver-ppc.h"
+
+namespace v8 {
+namespace internal {
+
+
+class SafepointGenerator FINAL : public CallWrapper {
+ public:
+  SafepointGenerator(LCodeGen* codegen, LPointerMap* pointers,
+                     Safepoint::DeoptMode mode)
+      : codegen_(codegen), pointers_(pointers), deopt_mode_(mode) {}
+  virtual ~SafepointGenerator() {}
+
+  void BeforeCall(int call_size) const OVERRIDE {}
+
+  void AfterCall() const OVERRIDE {
+    codegen_->RecordSafepoint(pointers_, deopt_mode_);
+  }
+
+ private:
+  LCodeGen* codegen_;
+  LPointerMap* pointers_;
+  Safepoint::DeoptMode deopt_mode_;
+};
+
+
+#define __ masm()->
+
+bool LCodeGen::GenerateCode() {
+  LPhase phase("Z_Code generation", chunk());
+  DCHECK(is_unused());
+  status_ = GENERATING;
+
+  // Open a frame scope to indicate that there is a frame on the stack.  The
+  // NONE indicates that the scope shouldn't actually generate code to set up
+  // the frame (that is done in GeneratePrologue).
+  FrameScope frame_scope(masm_, StackFrame::NONE);
+
+  return GeneratePrologue() && GenerateBody() && GenerateDeferredCode() &&
+         GenerateJumpTable() && GenerateSafepointTable();
+}
+
+
+void LCodeGen::FinishCode(Handle<Code> code) {
+  DCHECK(is_done());
+  code->set_stack_slots(GetStackSlotCount());
+  code->set_safepoint_table_offset(safepoints_.GetCodeOffset());
+  if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code);
+  PopulateDeoptimizationData(code);
+}
+
+
+void LCodeGen::SaveCallerDoubles() {
+  DCHECK(info()->saves_caller_doubles());
+  DCHECK(NeedsEagerFrame());
+  Comment(";;; Save clobbered callee double registers");
+  int count = 0;
+  BitVector* doubles = chunk()->allocated_double_registers();
+  BitVector::Iterator save_iterator(doubles);
+  while (!save_iterator.Done()) {
+    __ stfd(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
+            MemOperand(sp, count * kDoubleSize));
+    save_iterator.Advance();
+    count++;
+  }
+}
+
+
+void LCodeGen::RestoreCallerDoubles() {
+  DCHECK(info()->saves_caller_doubles());
+  DCHECK(NeedsEagerFrame());
+  Comment(";;; Restore clobbered callee double registers");
+  BitVector* doubles = chunk()->allocated_double_registers();
+  BitVector::Iterator save_iterator(doubles);
+  int count = 0;
+  while (!save_iterator.Done()) {
+    __ lfd(DoubleRegister::FromAllocationIndex(save_iterator.Current()),
+           MemOperand(sp, count * kDoubleSize));
+    save_iterator.Advance();
+    count++;
+  }
+}
+
+
+bool LCodeGen::GeneratePrologue() {
+  DCHECK(is_generating());
+
+  if (info()->IsOptimizing()) {
+    ProfileEntryHookStub::MaybeCallEntryHook(masm_);
+
+#ifdef DEBUG
+    if (strlen(FLAG_stop_at) > 0 &&
+        info_->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
+      __ stop("stop_at");
+    }
+#endif
+
+    // r4: Callee's JS function.
+    // cp: Callee's context.
+    // pp: Callee's constant pool pointer (if FLAG_enable_ool_constant_pool)
+    // fp: Caller's frame pointer.
+    // lr: Caller's pc.
+    // ip: Our own function entry (required by the prologue)
+
+    // Sloppy mode functions and builtins need to replace the receiver with the
+    // global proxy when called as functions (without an explicit receiver
+    // object).
+    if (info_->this_has_uses() && info_->strict_mode() == SLOPPY &&
+        !info_->is_native()) {
+      Label ok;
+      int receiver_offset = info_->scope()->num_parameters() * kPointerSize;
+      __ LoadP(r5, MemOperand(sp, receiver_offset));
+      __ CompareRoot(r5, Heap::kUndefinedValueRootIndex);
+      __ bne(&ok);
+
+      __ LoadP(r5, GlobalObjectOperand());
+      __ LoadP(r5, FieldMemOperand(r5, GlobalObject::kGlobalProxyOffset));
+
+      __ StoreP(r5, MemOperand(sp, receiver_offset));
+
+      __ bind(&ok);
+    }
+  }
+
+  int prologue_offset = masm_->pc_offset();
+
+  if (prologue_offset) {
+    // Prologue logic requires it's starting address in ip and the
+    // corresponding offset from the function entry.
+    prologue_offset += Instruction::kInstrSize;
+    __ addi(ip, ip, Operand(prologue_offset));
+  }
+  info()->set_prologue_offset(prologue_offset);
+  if (NeedsEagerFrame()) {
+    if (info()->IsStub()) {
+      __ StubPrologue(prologue_offset);
+    } else {
+      __ Prologue(info()->IsCodePreAgingActive(), prologue_offset);
+    }
+    frame_is_built_ = true;
+    info_->AddNoFrameRange(0, masm_->pc_offset());
+  }
+
+  // Reserve space for the stack slots needed by the code.
+  int slots = GetStackSlotCount();
+  if (slots > 0) {
+    __ subi(sp, sp, Operand(slots * kPointerSize));
+    if (FLAG_debug_code) {
+      __ Push(r3, r4);
+      __ li(r0, Operand(slots));
+      __ mtctr(r0);
+      __ addi(r3, sp, Operand((slots + 2) * kPointerSize));
+      __ mov(r4, Operand(kSlotsZapValue));
+      Label loop;
+      __ bind(&loop);
+      __ StorePU(r4, MemOperand(r3, -kPointerSize));
+      __ bdnz(&loop);
+      __ Pop(r3, r4);
+    }
+  }
+
+  if (info()->saves_caller_doubles()) {
+    SaveCallerDoubles();
+  }
+
+  // Possibly allocate a local context.
+  int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
+  if (heap_slots > 0) {
+    Comment(";;; Allocate local context");
+    bool need_write_barrier = true;
+    // Argument to NewContext is the function, which is in r4.
+    if (heap_slots <= FastNewContextStub::kMaximumSlots) {
+      FastNewContextStub stub(isolate(), heap_slots);
+      __ CallStub(&stub);
+      // Result of FastNewContextStub is always in new space.
+      need_write_barrier = false;
+    } else {
+      __ push(r4);
+      __ CallRuntime(Runtime::kNewFunctionContext, 1);
+    }
+    RecordSafepoint(Safepoint::kNoLazyDeopt);
+    // Context is returned in both r3 and cp.  It replaces the context
+    // passed to us.  It's saved in the stack and kept live in cp.
+    __ mr(cp, r3);
+    __ StoreP(r3, MemOperand(fp, StandardFrameConstants::kContextOffset));
+    // Copy any necessary parameters into the context.
+    int num_parameters = scope()->num_parameters();
+    for (int i = 0; i < num_parameters; i++) {
+      Variable* var = scope()->parameter(i);
+      if (var->IsContextSlot()) {
+        int parameter_offset = StandardFrameConstants::kCallerSPOffset +
+                               (num_parameters - 1 - i) * kPointerSize;
+        // Load parameter from stack.
+        __ LoadP(r3, MemOperand(fp, parameter_offset));
+        // Store it in the context.
+        MemOperand target = ContextOperand(cp, var->index());
+        __ StoreP(r3, target, r0);
+        // Update the write barrier. This clobbers r6 and r3.
+        if (need_write_barrier) {
+          __ RecordWriteContextSlot(cp, target.offset(), r3, r6,
+                                    GetLinkRegisterState(), kSaveFPRegs);
+        } else if (FLAG_debug_code) {
+          Label done;
+          __ JumpIfInNewSpace(cp, r3, &done);
+          __ Abort(kExpectedNewSpaceObject);
+          __ bind(&done);
+        }
+      }
+    }
+    Comment(";;; End allocate local context");
+  }
+
+  // Trace the call.
+  if (FLAG_trace && info()->IsOptimizing()) {
+    // We have not executed any compiled code yet, so cp still holds the
+    // incoming context.
+    __ CallRuntime(Runtime::kTraceEnter, 0);
+  }
+  return !is_aborted();
+}
+
+
+void LCodeGen::GenerateOsrPrologue() {
+  // Generate the OSR entry prologue at the first unknown OSR value, or if there
+  // are none, at the OSR entrypoint instruction.
+  if (osr_pc_offset_ >= 0) return;
+
+  osr_pc_offset_ = masm()->pc_offset();
+
+  // Adjust the frame size, subsuming the unoptimized frame into the
+  // optimized frame.
+  int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots();
+  DCHECK(slots >= 0);
+  __ subi(sp, sp, Operand(slots * kPointerSize));
+}
+
+
+void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) {
+  if (instr->IsCall()) {
+    EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
+  }
+  if (!instr->IsLazyBailout() && !instr->IsGap()) {
+    safepoints_.BumpLastLazySafepointIndex();
+  }
+}
+
+
+bool LCodeGen::GenerateDeferredCode() {
+  DCHECK(is_generating());
+  if (deferred_.length() > 0) {
+    for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
+      LDeferredCode* code = deferred_[i];
+
+      HValue* value =
+          instructions_->at(code->instruction_index())->hydrogen_value();
+      RecordAndWritePosition(
+          chunk()->graph()->SourcePositionToScriptPosition(value->position()));
+
+      Comment(
+          ";;; <@%d,#%d> "
+          "-------------------- Deferred %s --------------------",
+          code->instruction_index(), code->instr()->hydrogen_value()->id(),
+          code->instr()->Mnemonic());
+      __ bind(code->entry());
+      if (NeedsDeferredFrame()) {
+        Comment(";;; Build frame");
+        DCHECK(!frame_is_built_);
+        DCHECK(info()->IsStub());
+        frame_is_built_ = true;
+        __ LoadSmiLiteral(scratch0(), Smi::FromInt(StackFrame::STUB));
+        __ PushFixedFrame(scratch0());
+        __ addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
+        Comment(";;; Deferred code");
+      }
+      code->Generate();
+      if (NeedsDeferredFrame()) {
+        Comment(";;; Destroy frame");
+        DCHECK(frame_is_built_);
+        __ PopFixedFrame(ip);
+        frame_is_built_ = false;
+      }
+      __ b(code->exit());
+    }
+  }
+
+  return !is_aborted();
+}
+
+
+bool LCodeGen::GenerateJumpTable() {
+  // Check that the jump table is accessible from everywhere in the function
+  // code, i.e. that offsets to the table can be encoded in the 24bit signed
+  // immediate of a branch instruction.
+  // To simplify we consider the code size from the first instruction to the
+  // end of the jump table. We also don't consider the pc load delta.
+  // Each entry in the jump table generates one instruction and inlines one
+  // 32bit data after it.
+  if (!is_int24((masm()->pc_offset() / Assembler::kInstrSize) +
+                jump_table_.length() * 7)) {
+    Abort(kGeneratedCodeIsTooLarge);
+  }
+
+  if (jump_table_.length() > 0) {
+    Label needs_frame, call_deopt_entry;
+
+    Comment(";;; -------------------- Jump table --------------------");
+    Address base = jump_table_[0].address;
+
+    Register entry_offset = scratch0();
+
+    int length = jump_table_.length();
+    for (int i = 0; i < length; i++) {
+      Deoptimizer::JumpTableEntry* table_entry = &jump_table_[i];
+      __ bind(&table_entry->label);
+
+      DCHECK_EQ(jump_table_[0].bailout_type, table_entry->bailout_type);
+      Address entry = table_entry->address;
+      DeoptComment(table_entry->reason);
+
+      // Second-level deopt table entries are contiguous and small, so instead
+      // of loading the full, absolute address of each one, load an immediate
+      // offset which will be added to the base address later.
+      __ mov(entry_offset, Operand(entry - base));
+
+      if (table_entry->needs_frame) {
+        DCHECK(!info()->saves_caller_doubles());
+        if (needs_frame.is_bound()) {
+          __ b(&needs_frame);
+        } else {
+          __ bind(&needs_frame);
+          Comment(";;; call deopt with frame");
+          // This variant of deopt can only be used with stubs. Since we don't
+          // have a function pointer to install in the stack frame that we're
+          // building, install a special marker there instead.
+          DCHECK(info()->IsStub());
+          __ LoadSmiLiteral(ip, Smi::FromInt(StackFrame::STUB));
+          __ PushFixedFrame(ip);
+          __ addi(fp, sp,
+                  Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
+          __ bind(&call_deopt_entry);
+          // Add the base address to the offset previously loaded in
+          // entry_offset.
+          __ mov(ip, Operand(ExternalReference::ForDeoptEntry(base)));
+          __ add(ip, entry_offset, ip);
+          __ Call(ip);
+        }
+      } else {
+        // The last entry can fall through into `call_deopt_entry`, avoiding a
+        // branch.
+        bool need_branch = ((i + 1) != length) || call_deopt_entry.is_bound();
+
+        if (need_branch) __ b(&call_deopt_entry);
+      }
+    }
+
+    if (!call_deopt_entry.is_bound()) {
+      Comment(";;; call deopt");
+      __ bind(&call_deopt_entry);
+
+      if (info()->saves_caller_doubles()) {
+        DCHECK(info()->IsStub());
+        RestoreCallerDoubles();
+      }
+
+      // Add the base address to the offset previously loaded in entry_offset.
+      __ mov(ip, Operand(ExternalReference::ForDeoptEntry(base)));
+      __ add(ip, entry_offset, ip);
+      __ Call(ip);
+    }
+  }
+
+  // The deoptimization jump table is the last part of the instruction
+  // sequence. Mark the generated code as done unless we bailed out.
+  if (!is_aborted()) status_ = DONE;
+  return !is_aborted();
+}
+
+
+bool LCodeGen::GenerateSafepointTable() {
+  DCHECK(is_done());
+  safepoints_.Emit(masm(), GetStackSlotCount());
+  return !is_aborted();
+}
+
+
+Register LCodeGen::ToRegister(int index) const {
+  return Register::FromAllocationIndex(index);
+}
+
+
+DoubleRegister LCodeGen::ToDoubleRegister(int index) const {
+  return DoubleRegister::FromAllocationIndex(index);
+}
+
+
+Register LCodeGen::ToRegister(LOperand* op) const {
+  DCHECK(op->IsRegister());
+  return ToRegister(op->index());
+}
+
+
+Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
+  if (op->IsRegister()) {
+    return ToRegister(op->index());
+  } else if (op->IsConstantOperand()) {
+    LConstantOperand* const_op = LConstantOperand::cast(op);
+    HConstant* constant = chunk_->LookupConstant(const_op);
+    Handle<Object> literal = constant->handle(isolate());
+    Representation r = chunk_->LookupLiteralRepresentation(const_op);
+    if (r.IsInteger32()) {
+      DCHECK(literal->IsNumber());
+      __ LoadIntLiteral(scratch, static_cast<int32_t>(literal->Number()));
+    } else if (r.IsDouble()) {
+      Abort(kEmitLoadRegisterUnsupportedDoubleImmediate);
+    } else {
+      DCHECK(r.IsSmiOrTagged());
+      __ Move(scratch, literal);
+    }
+    return scratch;
+  } else if (op->IsStackSlot()) {
+    __ LoadP(scratch, ToMemOperand(op));
+    return scratch;
+  }
+  UNREACHABLE();
+  return scratch;
+}
+
+
+void LCodeGen::EmitLoadIntegerConstant(LConstantOperand* const_op,
+                                       Register dst) {
+  DCHECK(IsInteger32(const_op));
+  HConstant* constant = chunk_->LookupConstant(const_op);
+  int32_t value = constant->Integer32Value();
+  if (IsSmi(const_op)) {
+    __ LoadSmiLiteral(dst, Smi::FromInt(value));
+  } else {
+    __ LoadIntLiteral(dst, value);
+  }
+}
+
+
+DoubleRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
+  DCHECK(op->IsDoubleRegister());
+  return ToDoubleRegister(op->index());
+}
+
+
+Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
+  HConstant* constant = chunk_->LookupConstant(op);
+  DCHECK(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
+  return constant->handle(isolate());
+}
+
+
+bool LCodeGen::IsInteger32(LConstantOperand* op) const {
+  return chunk_->LookupLiteralRepresentation(op).IsSmiOrInteger32();
+}
+
+
+bool LCodeGen::IsSmi(LConstantOperand* op) const {
+  return chunk_->LookupLiteralRepresentation(op).IsSmi();
+}
+
+
+int32_t LCodeGen::ToInteger32(LConstantOperand* op) const {
+  return ToRepresentation(op, Representation::Integer32());
+}
+
+
+intptr_t LCodeGen::ToRepresentation(LConstantOperand* op,
+                                    const Representation& r) const {
+  HConstant* constant = chunk_->LookupConstant(op);
+  int32_t value = constant->Integer32Value();
+  if (r.IsInteger32()) return value;
+  DCHECK(r.IsSmiOrTagged());
+  return reinterpret_cast<intptr_t>(Smi::FromInt(value));
+}
+
+
+Smi* LCodeGen::ToSmi(LConstantOperand* op) const {
+  HConstant* constant = chunk_->LookupConstant(op);
+  return Smi::FromInt(constant->Integer32Value());
+}
+
+
+double LCodeGen::ToDouble(LConstantOperand* op) const {
+  HConstant* constant = chunk_->LookupConstant(op);
+  DCHECK(constant->HasDoubleValue());
+  return constant->DoubleValue();
+}
+
+
+Operand LCodeGen::ToOperand(LOperand* op) {
+  if (op->IsConstantOperand()) {
+    LConstantOperand* const_op = LConstantOperand::cast(op);
+    HConstant* constant = chunk()->LookupConstant(const_op);
+    Representation r = chunk_->LookupLiteralRepresentation(const_op);
+    if (r.IsSmi()) {
+      DCHECK(constant->HasSmiValue());
+      return Operand(Smi::FromInt(constant->Integer32Value()));
+    } else if (r.IsInteger32()) {
+      DCHECK(constant->HasInteger32Value());
+      return Operand(constant->Integer32Value());
+    } else if (r.IsDouble()) {
+      Abort(kToOperandUnsupportedDoubleImmediate);
+    }
+    DCHECK(r.IsTagged());
+    return Operand(constant->handle(isolate()));
+  } else if (op->IsRegister()) {
+    return Operand(ToRegister(op));
+  } else if (op->IsDoubleRegister()) {
+    Abort(kToOperandIsDoubleRegisterUnimplemented);
+    return Operand::Zero();
+  }
+  // Stack slots not implemented, use ToMemOperand instead.
+  UNREACHABLE();
+  return Operand::Zero();
+}
+
+
+static int ArgumentsOffsetWithoutFrame(int index) {
+  DCHECK(index < 0);
+  return -(index + 1) * kPointerSize;
+}
+
+
+MemOperand LCodeGen::ToMemOperand(LOperand* op) const {
+  DCHECK(!op->IsRegister());
+  DCHECK(!op->IsDoubleRegister());
+  DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot());
+  if (NeedsEagerFrame()) {
+    return MemOperand(fp, StackSlotOffset(op->index()));
+  } else {
+    // Retrieve parameter without eager stack-frame relative to the
+    // stack-pointer.
+    return MemOperand(sp, ArgumentsOffsetWithoutFrame(op->index()));
+  }
+}
+
+
+MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const {
+  DCHECK(op->IsDoubleStackSlot());
+  if (NeedsEagerFrame()) {
+    return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize);
+  } else {
+    // Retrieve parameter without eager stack-frame relative to the
+    // stack-pointer.
+    return MemOperand(sp,
+                      ArgumentsOffsetWithoutFrame(op->index()) + kPointerSize);
+  }
+}
+
+
+void LCodeGen::WriteTranslation(LEnvironment* environment,
+                                Translation* translation) {
+  if (environment == NULL) return;
+
+  // The translation includes one command per value in the environment.
+  int translation_size = environment->translation_size();
+  // The output frame height does not include the parameters.
+  int height = translation_size - environment->parameter_count();
+
+  WriteTranslation(environment->outer(), translation);
+  bool has_closure_id =
+      !info()->closure().is_null() &&
+      !info()->closure().is_identical_to(environment->closure());
+  int closure_id = has_closure_id
+                       ? DefineDeoptimizationLiteral(environment->closure())
+                       : Translation::kSelfLiteralId;
+
+  switch (environment->frame_type()) {
+    case JS_FUNCTION:
+      translation->BeginJSFrame(environment->ast_id(), closure_id, height);
+      break;
+    case JS_CONSTRUCT:
+      translation->BeginConstructStubFrame(closure_id, translation_size);
+      break;
+    case JS_GETTER:
+      DCHECK(translation_size == 1);
+      DCHECK(height == 0);
+      translation->BeginGetterStubFrame(closure_id);
+      break;
+    case JS_SETTER:
+      DCHECK(translation_size == 2);
+      DCHECK(height == 0);
+      translation->BeginSetterStubFrame(closure_id);
+      break;
+    case STUB:
+      translation->BeginCompiledStubFrame();
+      break;
+    case ARGUMENTS_ADAPTOR:
+      translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
+      break;
+  }
+
+  int object_index = 0;
+  int dematerialized_index = 0;
+  for (int i = 0; i < translation_size; ++i) {
+    LOperand* value = environment->values()->at(i);
+    AddToTranslation(
+        environment, translation, value, environment->HasTaggedValueAt(i),
+        environment->HasUint32ValueAt(i), &object_index, &dematerialized_index);
+  }
+}
+
+
+void LCodeGen::AddToTranslation(LEnvironment* environment,
+                                Translation* translation, LOperand* op,
+                                bool is_tagged, bool is_uint32,
+                                int* object_index_pointer,
+                                int* dematerialized_index_pointer) {
+  if (op == LEnvironment::materialization_marker()) {
+    int object_index = (*object_index_pointer)++;
+    if (environment->ObjectIsDuplicateAt(object_index)) {
+      int dupe_of = environment->ObjectDuplicateOfAt(object_index);
+      translation->DuplicateObject(dupe_of);
+      return;
+    }
+    int object_length = environment->ObjectLengthAt(object_index);
+    if (environment->ObjectIsArgumentsAt(object_index)) {
+      translation->BeginArgumentsObject(object_length);
+    } else {
+      translation->BeginCapturedObject(object_length);
+    }
+    int dematerialized_index = *dematerialized_index_pointer;
+    int env_offset = environment->translation_size() + dematerialized_index;
+    *dematerialized_index_pointer += object_length;
+    for (int i = 0; i < object_length; ++i) {
+      LOperand* value = environment->values()->at(env_offset + i);
+      AddToTranslation(environment, translation, value,
+                       environment->HasTaggedValueAt(env_offset + i),
+                       environment->HasUint32ValueAt(env_offset + i),
+                       object_index_pointer, dematerialized_index_pointer);
+    }
+    return;
+  }
+
+  if (op->IsStackSlot()) {
+    if (is_tagged) {
+      translation->StoreStackSlot(op->index());
+    } else if (is_uint32) {
+      translation->StoreUint32StackSlot(op->index());
+    } else {
+      translation->StoreInt32StackSlot(op->index());
+    }
+  } else if (op->IsDoubleStackSlot()) {
+    translation->StoreDoubleStackSlot(op->index());
+  } else if (op->IsRegister()) {
+    Register reg = ToRegister(op);
+    if (is_tagged) {
+      translation->StoreRegister(reg);
+    } else if (is_uint32) {
+      translation->StoreUint32Register(reg);
+    } else {
+      translation->StoreInt32Register(reg);
+    }
+  } else if (op->IsDoubleRegister()) {
+    DoubleRegister reg = ToDoubleRegister(op);
+    translation->StoreDoubleRegister(reg);
+  } else if (op->IsConstantOperand()) {
+    HConstant* constant = chunk()->LookupConstant(LConstantOperand::cast(op));
+    int src_index = DefineDeoptimizationLiteral(constant->handle(isolate()));
+    translation->StoreLiteral(src_index);
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
+void LCodeGen::CallCode(Handle<Code> code, RelocInfo::Mode mode,
+                        LInstruction* instr) {
+  CallCodeGeneric(code, mode, instr, RECORD_SIMPLE_SAFEPOINT);
+}
+
+
+void LCodeGen::CallCodeGeneric(Handle<Code> code, RelocInfo::Mode mode,
+                               LInstruction* instr,
+                               SafepointMode safepoint_mode) {
+  DCHECK(instr != NULL);
+  __ Call(code, mode);
+  RecordSafepointWithLazyDeopt(instr, safepoint_mode);
+
+  // Signal that we don't inline smi code before these stubs in the
+  // optimizing code generator.
+  if (code->kind() == Code::BINARY_OP_IC || code->kind() == Code::COMPARE_IC) {
+    __ nop();
+  }
+}
+
+
+void LCodeGen::CallRuntime(const Runtime::Function* function, int num_arguments,
+                           LInstruction* instr, SaveFPRegsMode save_doubles) {
+  DCHECK(instr != NULL);
+
+  __ CallRuntime(function, num_arguments, save_doubles);
+
+  RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
+}
+
+
+void LCodeGen::LoadContextFromDeferred(LOperand* context) {
+  if (context->IsRegister()) {
+    __ Move(cp, ToRegister(context));
+  } else if (context->IsStackSlot()) {
+    __ LoadP(cp, ToMemOperand(context));
+  } else if (context->IsConstantOperand()) {
+    HConstant* constant =
+        chunk_->LookupConstant(LConstantOperand::cast(context));
+    __ Move(cp, Handle<Object>::cast(constant->handle(isolate())));
+  } else {
+    UNREACHABLE();
+  }
+}
+
+
+void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id, int argc,
+                                       LInstruction* instr, LOperand* context) {
+  LoadContextFromDeferred(context);
+  __ CallRuntimeSaveDoubles(id);
+  RecordSafepointWithRegisters(instr->pointer_map(), argc,
+                               Safepoint::kNoLazyDeopt);
+}
+
+
+void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment,
+                                                    Safepoint::DeoptMode mode) {
+  environment->set_has_been_used();
+  if (!environment->HasBeenRegistered()) {
+    // Physical stack frame layout:
+    // -x ............. -4  0 ..................................... y
+    // [incoming arguments] [spill slots] [pushed outgoing arguments]
+
+    // Layout of the environment:
+    // 0 ..................................................... size-1
+    // [parameters] [locals] [expression stack including arguments]
+
+    // Layout of the translation:
+    // 0 ........................................................ size - 1 + 4
+    // [expression stack including arguments] [locals] [4 words] [parameters]
+    // |>------------  translation_size ------------<|
+
+    int frame_count = 0;
+    int jsframe_count = 0;
+    for (LEnvironment* e = environment; e != NULL; e = e->outer()) {
+      ++frame_count;
+      if (e->frame_type() == JS_FUNCTION) {
+        ++jsframe_count;
+      }
+    }
+    Translation translation(&translations_, frame_count, jsframe_count, zone());
+    WriteTranslation(environment, &translation);
+    int deoptimization_index = deoptimizations_.length();
+    int pc_offset = masm()->pc_offset();
+    environment->Register(deoptimization_index, translation.index(),
+                          (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
+    deoptimizations_.Add(environment, zone());
+  }
+}
+
+
+void LCodeGen::DeoptimizeIf(Condition cond, LInstruction* instr,
+                            const char* detail,
+                            Deoptimizer::BailoutType bailout_type,
+                            CRegister cr) {
+  LEnvironment* environment = instr->environment();
+  RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
+  DCHECK(environment->HasBeenRegistered());
+  int id = environment->deoptimization_index();
+  DCHECK(info()->IsOptimizing() || info()->IsStub());
+  Address entry =
+      Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
+  if (entry == NULL) {
+    Abort(kBailoutWasNotPrepared);
+    return;
+  }
+
+  if (FLAG_deopt_every_n_times != 0 && !info()->IsStub()) {
+    CRegister alt_cr = cr6;
+    Register scratch = scratch0();
+    ExternalReference count = ExternalReference::stress_deopt_count(isolate());
+    Label no_deopt;
+    DCHECK(!alt_cr.is(cr));
+    __ Push(r4, scratch);
+    __ mov(scratch, Operand(count));
+    __ lwz(r4, MemOperand(scratch));
+    __ subi(r4, r4, Operand(1));
+    __ cmpi(r4, Operand::Zero(), alt_cr);
+    __ bne(&no_deopt, alt_cr);
+    __ li(r4, Operand(FLAG_deopt_every_n_times));
+    __ stw(r4, MemOperand(scratch));
+    __ Pop(r4, scratch);
+
+    __ Call(entry, RelocInfo::RUNTIME_ENTRY);
+    __ bind(&no_deopt);
+    __ stw(r4, MemOperand(scratch));
+    __ Pop(r4, scratch);
+  }
+
+  if (info()->ShouldTrapOnDeopt()) {
+    __ stop("trap_on_deopt", cond, kDefaultStopCode, cr);
+  }
+
+  Deoptimizer::Reason reason(instr->hydrogen_value()->position().raw(),
+                             instr->Mnemonic(), detail);
+  DCHECK(info()->IsStub() || frame_is_built_);
+  // Go through jump table if we need to handle condition, build frame, or
+  // restore caller doubles.
+  if (cond == al && frame_is_built_ && !info()->saves_caller_doubles()) {
+    DeoptComment(reason);
+    __ Call(entry, RelocInfo::RUNTIME_ENTRY);
+  } else {
+    Deoptimizer::JumpTableEntry table_entry(entry, reason, bailout_type,
+                                            !frame_is_built_);
+    // We often have several deopts to the same entry, reuse the last
+    // jump entry if this is the case.
+    if (jump_table_.is_empty() ||
+        !table_entry.IsEquivalentTo(jump_table_.last())) {
+      jump_table_.Add(table_entry, zone());
+    }
+    __ b(cond, &jump_table_.last().label, cr);
+  }
+}
+
+
+void LCodeGen::DeoptimizeIf(Condition condition, LInstruction* instr,
+                            const char* detail, CRegister cr) {
+  Deoptimizer::BailoutType bailout_type =
+      info()->IsStub() ? Deoptimizer::LAZY : Deoptimizer::EAGER;
+  DeoptimizeIf(condition, instr, detail, bailout_type, cr);
+}
+
+
+void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
+  int length = deoptimizations_.length();
+  if (length == 0) return;
+  Handle<DeoptimizationInputData> data =
+      DeoptimizationInputData::New(isolate(), length, TENURED);
+
+  Handle<ByteArray> translations =
+      translations_.CreateByteArray(isolate()->factory());
+  data->SetTranslationByteArray(*translations);
+  data->SetInlinedFunctionCount(Smi::FromInt(inlined_function_count_));
+  data->SetOptimizationId(Smi::FromInt(info_->optimization_id()));
+  if (info_->IsOptimizing()) {
+    // Reference to shared function info does not change between phases.
+    AllowDeferredHandleDereference allow_handle_dereference;
+    data->SetSharedFunctionInfo(*info_->shared_info());
+  } else {
+    data->SetSharedFunctionInfo(Smi::FromInt(0));
+  }
+
+  Handle<FixedArray> literals =
+      factory()->NewFixedArray(deoptimization_literals_.length(), TENURED);
+  {
+    AllowDeferredHandleDereference copy_handles;
+    for (int i = 0; i < deoptimization_literals_.length(); i++) {
+      literals->set(i, *deoptimization_literals_[i]);
+    }
+    data->SetLiteralArray(*literals);
+  }
+
+  data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt()));
+  data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_));
+
+  // Populate the deoptimization entries.
+  for (int i = 0; i < length; i++) {
+    LEnvironment* env = deoptimizations_[i];
+    data->SetAstId(i, env->ast_id());
+    data->SetTranslationIndex(i, Smi::FromInt(env->translation_index()));
+    data->SetArgumentsStackHeight(i,
+                                  Smi::FromInt(env->arguments_stack_height()));
+    data->SetPc(i, Smi::FromInt(env->pc_offset()));
+  }
+  code->set_deoptimization_data(*data);
+}
+
+
+int LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) {
+  int result = deoptimization_literals_.length();
+  for (int i = 0; i < deoptimization_literals_.length(); ++i) {
+    if (deoptimization_literals_[i].is_identical_to(literal)) return i;
+  }
+  deoptimization_literals_.Add(literal, zone());
+  return result;
+}
+
+
+void LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() {
+  DCHECK(deoptimization_literals_.length() == 0);
+
+  const ZoneList<Handle<JSFunction> >* inlined_closures =
+      chunk()->inlined_closures();
+
+  for (int i = 0, length = inlined_closures->length(); i < length; i++) {
+    DefineDeoptimizationLiteral(inlined_closures->at(i));
+  }
+
+  inlined_function_count_ = deoptimization_literals_.length();
+}
+
+
+void LCodeGen::RecordSafepointWithLazyDeopt(LInstruction* instr,
+                                            SafepointMode safepoint_mode) {
+  if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) {
+    RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt);
+  } else {
+    DCHECK(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
+    RecordSafepointWithRegisters(instr->pointer_map(), 0,
+                                 Safepoint::kLazyDeopt);
+  }
+}
+
+
+void LCodeGen::RecordSafepoint(LPointerMap* pointers, Safepoint::Kind kind,
+                               int arguments, Safepoint::DeoptMode deopt_mode) {
+  DCHECK(expected_safepoint_kind_ == kind);
+
+  const ZoneList<LOperand*>* operands = pointers->GetNormalizedOperands();
+  Safepoint safepoint =
+      safepoints_.DefineSafepoint(masm(), kind, arguments, deopt_mode);
+  for (int i = 0; i < operands->length(); i++) {
+    LOperand* pointer = operands->at(i);
+    if (pointer->IsStackSlot()) {
+      safepoint.DefinePointerSlot(pointer->index(), zone());
+    } else if (pointer->IsRegister() && (kind & Safepoint::kWithRegisters)) {
+      safepoint.DefinePointerRegister(ToRegister(pointer), zone());
+    }
+  }
+#if V8_OOL_CONSTANT_POOL
+  if (kind & Safepoint::kWithRegisters) {
+    // Register always contains a pointer to the constant pool.
+    safepoint.DefinePointerRegister(kConstantPoolRegister, zone());
+  }
+#endif
+}
+
+
+void LCodeGen::RecordSafepoint(LPointerMap* pointers,
+                               Safepoint::DeoptMode deopt_mode) {
+  RecordSafepoint(pointers, Safepoint::kSimple, 0, deopt_mode);
+}
+
+
+void LCodeGen::RecordSafepoint(Safepoint::DeoptMode deopt_mode) {
+  LPointerMap empty_pointers(zone());
+  RecordSafepoint(&empty_pointers, deopt_mode);
+}
+
+
+void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers,
+                                            int arguments,
+                                            Safepoint::DeoptMode deopt_mode) {
+  RecordSafepoint(pointers, Safepoint::kWithRegisters, arguments, deopt_mode);
+}
+
+
+void LCodeGen::RecordAndWritePosition(int position) {
+  if (position == RelocInfo::kNoPosition) return;
+  masm()->positions_recorder()->RecordPosition(position);
+  masm()->positions_recorder()->WriteRecordedPositions();
+}
+
+
+static const char* LabelType(LLabel* label) {
+  if (label->is_loop_header()) return " (loop header)";
+  if (label->is_osr_entry()) return " (OSR entry)";
+  return "";
+}
+
+
+void LCodeGen::DoLabel(LLabel* label) {
+  Comment(";;; <@%d,#%d> -------------------- B%d%s --------------------",
+          current_instruction_, label->hydrogen_value()->id(),
+          label->block_id(), LabelType(label));
+  __ bind(label->label());
+  current_block_ = label->block_id();
+  DoGap(label);
+}
+
+
+void LCodeGen::DoParallelMove(LParallelMove* move) { resolver_.Resolve(move); }
+
+
+void LCodeGen::DoGap(LGap* gap) {
+  for (int i = LGap::FIRST_INNER_POSITION; i <= LGap::LAST_INNER_POSITION;
+       i++) {
+    LGap::InnerPosition inner_pos = static_cast<LGap::InnerPosition>(i);
+    LParallelMove* move = gap->GetParallelMove(inner_pos);
+    if (move != NULL) DoParallelMove(move);
+  }
+}
+
+
+void LCodeGen::DoInstructionGap(LInstructionGap* instr) { DoGap(instr); }
+
+
+void LCodeGen::DoParameter(LParameter* instr) {
+  // Nothing to do.
+}
+
+
+void LCodeGen::DoCallStub(LCallStub* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->result()).is(r3));
+  switch (instr->hydrogen()->major_key()) {
+    case CodeStub::RegExpExec: {
+      RegExpExecStub stub(isolate());
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+      break;
+    }
+    case CodeStub::SubString: {
+      SubStringStub stub(isolate());
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+      break;
+    }
+    case CodeStub::StringCompare: {
+      StringCompareStub stub(isolate());
+      CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+      break;
+    }
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
+  GenerateOsrPrologue();
+}
+
+
+void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) {
+  Register dividend = ToRegister(instr->dividend());
+  int32_t divisor = instr->divisor();
+  DCHECK(dividend.is(ToRegister(instr->result())));
+
+  // Theoretically, a variation of the branch-free code for integer division by
+  // a power of 2 (calculating the remainder via an additional multiplication
+  // (which gets simplified to an 'and') and subtraction) should be faster, and
+  // this is exactly what GCC and clang emit. Nevertheless, benchmarks seem to
+  // indicate that positive dividends are heavily favored, so the branching
+  // version performs better.
+  HMod* hmod = instr->hydrogen();
+  int32_t shift = WhichPowerOf2Abs(divisor);
+  Label dividend_is_not_negative, done;
+  if (hmod->CheckFlag(HValue::kLeftCanBeNegative)) {
+    __ cmpwi(dividend, Operand::Zero());
+    __ bge(&dividend_is_not_negative);
+    if (shift) {
+      // Note that this is correct even for kMinInt operands.
+      __ neg(dividend, dividend);
+      __ ExtractBitRange(dividend, dividend, shift - 1, 0);
+      __ neg(dividend, dividend, LeaveOE, SetRC);
+      if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+        DeoptimizeIf(eq, instr, "minus zero", cr0);
+      }
+    } else if (!hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+      __ li(dividend, Operand::Zero());
+    } else {
+      DeoptimizeIf(al, instr, "minus zero");
+    }
+    __ b(&done);
+  }
+
+  __ bind(&dividend_is_not_negative);
+  if (shift) {
+    __ ExtractBitRange(dividend, dividend, shift - 1, 0);
+  } else {
+    __ li(dividend, Operand::Zero());
+  }
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoModByConstI(LModByConstI* instr) {
+  Register dividend = ToRegister(instr->dividend());
+  int32_t divisor = instr->divisor();
+  Register result = ToRegister(instr->result());
+  DCHECK(!dividend.is(result));
+
+  if (divisor == 0) {
+    DeoptimizeIf(al, instr, "division by zero");
+    return;
+  }
+
+  __ TruncatingDiv(result, dividend, Abs(divisor));
+  __ mov(ip, Operand(Abs(divisor)));
+  __ mullw(result, result, ip);
+  __ sub(result, dividend, result, LeaveOE, SetRC);
+
+  // Check for negative zero.
+  HMod* hmod = instr->hydrogen();
+  if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    Label remainder_not_zero;
+    __ bne(&remainder_not_zero, cr0);
+    __ cmpwi(dividend, Operand::Zero());
+    DeoptimizeIf(lt, instr, "minus zero");
+    __ bind(&remainder_not_zero);
+  }
+}
+
+
+void LCodeGen::DoModI(LModI* instr) {
+  HMod* hmod = instr->hydrogen();
+  Register left_reg = ToRegister(instr->left());
+  Register right_reg = ToRegister(instr->right());
+  Register result_reg = ToRegister(instr->result());
+  Register scratch = scratch0();
+  Label done;
+
+  if (hmod->CheckFlag(HValue::kCanOverflow)) {
+    __ li(r0, Operand::Zero());  // clear xer
+    __ mtxer(r0);
+  }
+
+  __ divw(scratch, left_reg, right_reg, SetOE, SetRC);
+
+  // Check for x % 0.
+  if (hmod->CheckFlag(HValue::kCanBeDivByZero)) {
+    __ cmpwi(right_reg, Operand::Zero());
+    DeoptimizeIf(eq, instr, "division by zero");
+  }
+
+  // Check for kMinInt % -1, divw will return undefined, which is not what we
+  // want. We have to deopt if we care about -0, because we can't return that.
+  if (hmod->CheckFlag(HValue::kCanOverflow)) {
+    Label no_overflow_possible;
+    if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+      DeoptimizeIf(overflow, instr, "minus zero", cr0);
+    } else {
+      __ bnooverflow(&no_overflow_possible, cr0);
+      __ li(result_reg, Operand::Zero());
+      __ b(&done);
+    }
+    __ bind(&no_overflow_possible);
+  }
+
+  __ mullw(scratch, right_reg, scratch);
+  __ sub(result_reg, left_reg, scratch, LeaveOE, SetRC);
+
+  // If we care about -0, test if the dividend is <0 and the result is 0.
+  if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    __ bne(&done, cr0);
+    __ cmpwi(left_reg, Operand::Zero());
+    DeoptimizeIf(lt, instr, "minus zero");
+  }
+
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
+  Register dividend = ToRegister(instr->dividend());
+  int32_t divisor = instr->divisor();
+  Register result = ToRegister(instr->result());
+  DCHECK(divisor == kMinInt || base::bits::IsPowerOfTwo32(Abs(divisor)));
+  DCHECK(!result.is(dividend));
+
+  // Check for (0 / -x) that will produce negative zero.
+  HDiv* hdiv = instr->hydrogen();
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
+    __ cmpwi(dividend, Operand::Zero());
+    DeoptimizeIf(eq, instr, "minus zero");
+  }
+  // Check for (kMinInt / -1).
+  if (hdiv->CheckFlag(HValue::kCanOverflow) && divisor == -1) {
+    __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000)));
+    __ cmpw(dividend, r0);
+    DeoptimizeIf(eq, instr, "overflow");
+  }
+
+  int32_t shift = WhichPowerOf2Abs(divisor);
+
+  // Deoptimize if remainder will not be 0.
+  if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) && shift) {
+    __ TestBitRange(dividend, shift - 1, 0, r0);
+    DeoptimizeIf(ne, instr, "lost precision", cr0);
+  }
+
+  if (divisor == -1) {  // Nice shortcut, not needed for correctness.
+    __ neg(result, dividend);
+    return;
+  }
+  if (shift == 0) {
+    __ mr(result, dividend);
+  } else {
+    if (shift == 1) {
+      __ srwi(result, dividend, Operand(31));
+    } else {
+      __ srawi(result, dividend, 31);
+      __ srwi(result, result, Operand(32 - shift));
+    }
+    __ add(result, dividend, result);
+    __ srawi(result, result, shift);
+  }
+  if (divisor < 0) __ neg(result, result);
+}
+
+
+void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
+  Register dividend = ToRegister(instr->dividend());
+  int32_t divisor = instr->divisor();
+  Register result = ToRegister(instr->result());
+  DCHECK(!dividend.is(result));
+
+  if (divisor == 0) {
+    DeoptimizeIf(al, instr, "division by zero");
+    return;
+  }
+
+  // Check for (0 / -x) that will produce negative zero.
+  HDiv* hdiv = instr->hydrogen();
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
+    __ cmpwi(dividend, Operand::Zero());
+    DeoptimizeIf(eq, instr, "minus zero");
+  }
+
+  __ TruncatingDiv(result, dividend, Abs(divisor));
+  if (divisor < 0) __ neg(result, result);
+
+  if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+    Register scratch = scratch0();
+    __ mov(ip, Operand(divisor));
+    __ mullw(scratch, result, ip);
+    __ cmpw(scratch, dividend);
+    DeoptimizeIf(ne, instr, "lost precision");
+  }
+}
+
+
+// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
+void LCodeGen::DoDivI(LDivI* instr) {
+  HBinaryOperation* hdiv = instr->hydrogen();
+  const Register dividend = ToRegister(instr->dividend());
+  const Register divisor = ToRegister(instr->divisor());
+  Register result = ToRegister(instr->result());
+
+  DCHECK(!dividend.is(result));
+  DCHECK(!divisor.is(result));
+
+  if (hdiv->CheckFlag(HValue::kCanOverflow)) {
+    __ li(r0, Operand::Zero());  // clear xer
+    __ mtxer(r0);
+  }
+
+  __ divw(result, dividend, divisor, SetOE, SetRC);
+
+  // Check for x / 0.
+  if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
+    __ cmpwi(divisor, Operand::Zero());
+    DeoptimizeIf(eq, instr, "division by zero");
+  }
+
+  // Check for (0 / -x) that will produce negative zero.
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    Label dividend_not_zero;
+    __ cmpwi(dividend, Operand::Zero());
+    __ bne(&dividend_not_zero);
+    __ cmpwi(divisor, Operand::Zero());
+    DeoptimizeIf(lt, instr, "minus zero");
+    __ bind(&dividend_not_zero);
+  }
+
+  // Check for (kMinInt / -1).
+  if (hdiv->CheckFlag(HValue::kCanOverflow)) {
+    Label no_overflow_possible;
+    if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+      DeoptimizeIf(overflow, instr, "overflow", cr0);
+    } else {
+      // When truncating, we want kMinInt / -1 = kMinInt.
+      __ bnooverflow(&no_overflow_possible, cr0);
+      __ mr(result, dividend);
+    }
+    __ bind(&no_overflow_possible);
+  }
+
+  if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+    // Deoptimize if remainder is not 0.
+    Register scratch = scratch0();
+    __ mullw(scratch, divisor, result);
+    __ cmpw(dividend, scratch);
+    DeoptimizeIf(ne, instr, "lost precision");
+  }
+}
+
+
+void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
+  HBinaryOperation* hdiv = instr->hydrogen();
+  Register dividend = ToRegister(instr->dividend());
+  Register result = ToRegister(instr->result());
+  int32_t divisor = instr->divisor();
+
+  // If the divisor is positive, things are easy: There can be no deopts and we
+  // can simply do an arithmetic right shift.
+  int32_t shift = WhichPowerOf2Abs(divisor);
+  if (divisor > 0) {
+    if (shift || !result.is(dividend)) {
+      __ srawi(result, dividend, shift);
+    }
+    return;
+  }
+
+  // If the divisor is negative, we have to negate and handle edge cases.
+  OEBit oe = LeaveOE;
+#if V8_TARGET_ARCH_PPC64
+  if (divisor == -1 && hdiv->CheckFlag(HValue::kLeftCanBeMinInt)) {
+    __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000)));
+    __ cmpw(dividend, r0);
+    DeoptimizeIf(eq, instr, "overflow");
+  }
+#else
+  if (hdiv->CheckFlag(HValue::kLeftCanBeMinInt)) {
+    __ li(r0, Operand::Zero());  // clear xer
+    __ mtxer(r0);
+    oe = SetOE;
+  }
+#endif
+
+  __ neg(result, dividend, oe, SetRC);
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    DeoptimizeIf(eq, instr, "minus zero", cr0);
+  }
+
+// If the negation could not overflow, simply shifting is OK.
+#if !V8_TARGET_ARCH_PPC64
+  if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
+#endif
+    if (shift) {
+      __ ShiftRightArithImm(result, result, shift);
+    }
+    return;
+#if !V8_TARGET_ARCH_PPC64
+  }
+
+  // Dividing by -1 is basically negation, unless we overflow.
+  if (divisor == -1) {
+    DeoptimizeIf(overflow, instr, "overflow", cr0);
+    return;
+  }
+
+  Label overflow, done;
+  __ boverflow(&overflow, cr0);
+  __ srawi(result, result, shift);
+  __ b(&done);
+  __ bind(&overflow);
+  __ mov(result, Operand(kMinInt / divisor));
+  __ bind(&done);
+#endif
+}
+
+
+void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
+  Register dividend = ToRegister(instr->dividend());
+  int32_t divisor = instr->divisor();
+  Register result = ToRegister(instr->result());
+  DCHECK(!dividend.is(result));
+
+  if (divisor == 0) {
+    DeoptimizeIf(al, instr, "division by zero");
+    return;
+  }
+
+  // Check for (0 / -x) that will produce negative zero.
+  HMathFloorOfDiv* hdiv = instr->hydrogen();
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) {
+    __ cmpwi(dividend, Operand::Zero());
+    DeoptimizeIf(eq, instr, "minus zero");
+  }
+
+  // Easy case: We need no dynamic check for the dividend and the flooring
+  // division is the same as the truncating division.
+  if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) ||
+      (divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) {
+    __ TruncatingDiv(result, dividend, Abs(divisor));
+    if (divisor < 0) __ neg(result, result);
+    return;
+  }
+
+  // In the general case we may need to adjust before and after the truncating
+  // division to get a flooring division.
+  Register temp = ToRegister(instr->temp());
+  DCHECK(!temp.is(dividend) && !temp.is(result));
+  Label needs_adjustment, done;
+  __ cmpwi(dividend, Operand::Zero());
+  __ b(divisor > 0 ? lt : gt, &needs_adjustment);
+  __ TruncatingDiv(result, dividend, Abs(divisor));
+  if (divisor < 0) __ neg(result, result);
+  __ b(&done);
+  __ bind(&needs_adjustment);
+  __ addi(temp, dividend, Operand(divisor > 0 ? 1 : -1));
+  __ TruncatingDiv(result, temp, Abs(divisor));
+  if (divisor < 0) __ neg(result, result);
+  __ subi(result, result, Operand(1));
+  __ bind(&done);
+}
+
+
+// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI.
+void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
+  HBinaryOperation* hdiv = instr->hydrogen();
+  const Register dividend = ToRegister(instr->dividend());
+  const Register divisor = ToRegister(instr->divisor());
+  Register result = ToRegister(instr->result());
+
+  DCHECK(!dividend.is(result));
+  DCHECK(!divisor.is(result));
+
+  if (hdiv->CheckFlag(HValue::kCanOverflow)) {
+    __ li(r0, Operand::Zero());  // clear xer
+    __ mtxer(r0);
+  }
+
+  __ divw(result, dividend, divisor, SetOE, SetRC);
+
+  // Check for x / 0.
+  if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
+    __ cmpwi(divisor, Operand::Zero());
+    DeoptimizeIf(eq, instr, "division by zero");
+  }
+
+  // Check for (0 / -x) that will produce negative zero.
+  if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    Label dividend_not_zero;
+    __ cmpwi(dividend, Operand::Zero());
+    __ bne(&dividend_not_zero);
+    __ cmpwi(divisor, Operand::Zero());
+    DeoptimizeIf(lt, instr, "minus zero");
+    __ bind(&dividend_not_zero);
+  }
+
+  // Check for (kMinInt / -1).
+  if (hdiv->CheckFlag(HValue::kCanOverflow)) {
+    Label no_overflow_possible;
+    if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
+      DeoptimizeIf(overflow, instr, "overflow", cr0);
+    } else {
+      // When truncating, we want kMinInt / -1 = kMinInt.
+      __ bnooverflow(&no_overflow_possible, cr0);
+      __ mr(result, dividend);
+    }
+    __ bind(&no_overflow_possible);
+  }
+
+  Label done;
+  Register scratch = scratch0();
+// If both operands have the same sign then we are done.
+#if V8_TARGET_ARCH_PPC64
+  __ xor_(scratch, dividend, divisor);
+  __ cmpwi(scratch, Operand::Zero());
+  __ bge(&done);
+#else
+  __ xor_(scratch, dividend, divisor, SetRC);
+  __ bge(&done, cr0);
+#endif
+
+  // If there is no remainder then we are done.
+  __ mullw(scratch, divisor, result);
+  __ cmpw(dividend, scratch);
+  __ beq(&done);
+
+  // We performed a truncating division. Correct the result.
+  __ subi(result, result, Operand(1));
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
+  DoubleRegister addend = ToDoubleRegister(instr->addend());
+  DoubleRegister multiplier = ToDoubleRegister(instr->multiplier());
+  DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand());
+  DoubleRegister result = ToDoubleRegister(instr->result());
+
+  __ fmadd(result, multiplier, multiplicand, addend);
+}
+
+
+void LCodeGen::DoMultiplySubD(LMultiplySubD* instr) {
+  DoubleRegister minuend = ToDoubleRegister(instr->minuend());
+  DoubleRegister multiplier = ToDoubleRegister(instr->multiplier());
+  DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand());
+  DoubleRegister result = ToDoubleRegister(instr->result());
+
+  __ fmsub(result, multiplier, multiplicand, minuend);
+}
+
+
+void LCodeGen::DoMulI(LMulI* instr) {
+  Register scratch = scratch0();
+  Register result = ToRegister(instr->result());
+  // Note that result may alias left.
+  Register left = ToRegister(instr->left());
+  LOperand* right_op = instr->right();
+
+  bool bailout_on_minus_zero =
+      instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
+  bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
+
+  if (right_op->IsConstantOperand()) {
+    int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
+
+    if (bailout_on_minus_zero && (constant < 0)) {
+      // The case of a null constant will be handled separately.
+      // If constant is negative and left is null, the result should be -0.
+      __ cmpi(left, Operand::Zero());
+      DeoptimizeIf(eq, instr, "minus zero");
+    }
+
+    switch (constant) {
+      case -1:
+        if (can_overflow) {
+#if V8_TARGET_ARCH_PPC64
+          if (instr->hydrogen()->representation().IsSmi()) {
+#endif
+            __ li(r0, Operand::Zero());  // clear xer
+            __ mtxer(r0);
+            __ neg(result, left, SetOE, SetRC);
+            DeoptimizeIf(overflow, instr, "overflow", cr0);
+#if V8_TARGET_ARCH_PPC64
+          } else {
+            __ neg(result, left);
+            __ TestIfInt32(result, scratch, r0);
+            DeoptimizeIf(ne, instr, "overflow");
+          }
+#endif
+        } else {
+          __ neg(result, left);
+        }
+        break;
+      case 0:
+        if (bailout_on_minus_zero) {
+// If left is strictly negative and the constant is null, the
+// result is -0. Deoptimize if required, otherwise return 0.
+#if V8_TARGET_ARCH_PPC64
+          if (instr->hydrogen()->representation().IsSmi()) {
+#endif
+            __ cmpi(left, Operand::Zero());
+#if V8_TARGET_ARCH_PPC64
+          } else {
+            __ cmpwi(left, Operand::Zero());
+          }
+#endif
+          DeoptimizeIf(lt, instr, "minus zero");
+        }
+        __ li(result, Operand::Zero());
+        break;
+      case 1:
+        __ Move(result, left);
+        break;
+      default:
+        // Multiplying by powers of two and powers of two plus or minus
+        // one can be done faster with shifted operands.
+        // For other constants we emit standard code.
+        int32_t mask = constant >> 31;
+        uint32_t constant_abs = (constant + mask) ^ mask;
+
+        if (base::bits::IsPowerOfTwo32(constant_abs)) {
+          int32_t shift = WhichPowerOf2(constant_abs);
+          __ ShiftLeftImm(result, left, Operand(shift));
+          // Correct the sign of the result if the constant is negative.
+          if (constant < 0) __ neg(result, result);
+        } else if (base::bits::IsPowerOfTwo32(constant_abs - 1)) {
+          int32_t shift = WhichPowerOf2(constant_abs - 1);
+          __ ShiftLeftImm(scratch, left, Operand(shift));
+          __ add(result, scratch, left);
+          // Correct the sign of the result if the constant is negative.
+          if (constant < 0) __ neg(result, result);
+        } else if (base::bits::IsPowerOfTwo32(constant_abs + 1)) {
+          int32_t shift = WhichPowerOf2(constant_abs + 1);
+          __ ShiftLeftImm(scratch, left, Operand(shift));
+          __ sub(result, scratch, left);
+          // Correct the sign of the result if the constant is negative.
+          if (constant < 0) __ neg(result, result);
+        } else {
+          // Generate standard code.
+          __ mov(ip, Operand(constant));
+          __ Mul(result, left, ip);
+        }
+    }
+
+  } else {
+    DCHECK(right_op->IsRegister());
+    Register right = ToRegister(right_op);
+
+    if (can_overflow) {
+#if V8_TARGET_ARCH_PPC64
+      // result = left * right.
+      if (instr->hydrogen()->representation().IsSmi()) {
+        __ SmiUntag(result, left);
+        __ SmiUntag(scratch, right);
+        __ Mul(result, result, scratch);
+      } else {
+        __ Mul(result, left, right);
+      }
+      __ TestIfInt32(result, scratch, r0);
+      DeoptimizeIf(ne, instr, "overflow");
+      if (instr->hydrogen()->representation().IsSmi()) {
+        __ SmiTag(result);
+      }
+#else
+      // scratch:result = left * right.
+      if (instr->hydrogen()->representation().IsSmi()) {
+        __ SmiUntag(result, left);
+        __ mulhw(scratch, result, right);
+        __ mullw(result, result, right);
+      } else {
+        __ mulhw(scratch, left, right);
+        __ mullw(result, left, right);
+      }
+      __ TestIfInt32(scratch, result, r0);
+      DeoptimizeIf(ne, instr, "overflow");
+#endif
+    } else {
+      if (instr->hydrogen()->representation().IsSmi()) {
+        __ SmiUntag(result, left);
+        __ Mul(result, result, right);
+      } else {
+        __ Mul(result, left, right);
+      }
+    }
+
+    if (bailout_on_minus_zero) {
+      Label done;
+#if V8_TARGET_ARCH_PPC64
+      if (instr->hydrogen()->representation().IsSmi()) {
+#endif
+        __ xor_(r0, left, right, SetRC);
+        __ bge(&done, cr0);
+#if V8_TARGET_ARCH_PPC64
+      } else {
+        __ xor_(r0, left, right);
+        __ cmpwi(r0, Operand::Zero());
+        __ bge(&done);
+      }
+#endif
+      // Bail out if the result is minus zero.
+      __ cmpi(result, Operand::Zero());
+      DeoptimizeIf(eq, instr, "minus zero");
+      __ bind(&done);
+    }
+  }
+}
+
+
+void LCodeGen::DoBitI(LBitI* instr) {
+  LOperand* left_op = instr->left();
+  LOperand* right_op = instr->right();
+  DCHECK(left_op->IsRegister());
+  Register left = ToRegister(left_op);
+  Register result = ToRegister(instr->result());
+  Operand right(no_reg);
+
+  if (right_op->IsStackSlot()) {
+    right = Operand(EmitLoadRegister(right_op, ip));
+  } else {
+    DCHECK(right_op->IsRegister() || right_op->IsConstantOperand());
+    right = ToOperand(right_op);
+
+    if (right_op->IsConstantOperand() && is_uint16(right.immediate())) {
+      switch (instr->op()) {
+        case Token::BIT_AND:
+          __ andi(result, left, right);
+          break;
+        case Token::BIT_OR:
+          __ ori(result, left, right);
+          break;
+        case Token::BIT_XOR:
+          __ xori(result, left, right);
+          break;
+        default:
+          UNREACHABLE();
+          break;
+      }
+      return;
+    }
+  }
+
+  switch (instr->op()) {
+    case Token::BIT_AND:
+      __ And(result, left, right);
+      break;
+    case Token::BIT_OR:
+      __ Or(result, left, right);
+      break;
+    case Token::BIT_XOR:
+      if (right_op->IsConstantOperand() && right.immediate() == int32_t(~0)) {
+        __ notx(result, left);
+      } else {
+        __ Xor(result, left, right);
+      }
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void LCodeGen::DoShiftI(LShiftI* instr) {
+  // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so
+  // result may alias either of them.
+  LOperand* right_op = instr->right();
+  Register left = ToRegister(instr->left());
+  Register result = ToRegister(instr->result());
+  Register scratch = scratch0();
+  if (right_op->IsRegister()) {
+    // Mask the right_op operand.
+    __ andi(scratch, ToRegister(right_op), Operand(0x1F));
+    switch (instr->op()) {
+      case Token::ROR:
+        // rotate_right(a, b) == rotate_left(a, 32 - b)
+        __ subfic(scratch, scratch, Operand(32));
+        __ rotlw(result, left, scratch);
+        break;
+      case Token::SAR:
+        __ sraw(result, left, scratch);
+        break;
+      case Token::SHR:
+        if (instr->can_deopt()) {
+          __ srw(result, left, scratch, SetRC);
+#if V8_TARGET_ARCH_PPC64
+          __ extsw(result, result, SetRC);
+#endif
+          DeoptimizeIf(lt, instr, "negative value", cr0);
+        } else {
+          __ srw(result, left, scratch);
+        }
+        break;
+      case Token::SHL:
+        __ slw(result, left, scratch);
+#if V8_TARGET_ARCH_PPC64
+        __ extsw(result, result);
+#endif
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+  } else {
+    // Mask the right_op operand.
+    int value = ToInteger32(LConstantOperand::cast(right_op));
+    uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
+    switch (instr->op()) {
+      case Token::ROR:
+        if (shift_count != 0) {
+          __ rotrwi(result, left, shift_count);
+        } else {
+          __ Move(result, left);
+        }
+        break;
+      case Token::SAR:
+        if (shift_count != 0) {
+          __ srawi(result, left, shift_count);
+        } else {
+          __ Move(result, left);
+        }
+        break;
+      case Token::SHR:
+        if (shift_count != 0) {
+          __ srwi(result, left, Operand(shift_count));
+        } else {
+          if (instr->can_deopt()) {
+            __ cmpwi(left, Operand::Zero());
+            DeoptimizeIf(lt, instr, "negative value");
+          }
+          __ Move(result, left);
+        }
+        break;
+      case Token::SHL:
+        if (shift_count != 0) {
+#if V8_TARGET_ARCH_PPC64
+          if (instr->hydrogen_value()->representation().IsSmi()) {
+            __ sldi(result, left, Operand(shift_count));
+#else
+          if (instr->hydrogen_value()->representation().IsSmi() &&
+              instr->can_deopt()) {
+            if (shift_count != 1) {
+              __ slwi(result, left, Operand(shift_count - 1));
+              __ SmiTagCheckOverflow(result, result, scratch);
+            } else {
+              __ SmiTagCheckOverflow(result, left, scratch);
+            }
+            DeoptimizeIf(lt, instr, "overflow", cr0);
+#endif
+          } else {
+            __ slwi(result, left, Operand(shift_count));
+#if V8_TARGET_ARCH_PPC64
+            __ extsw(result, result);
+#endif
+          }
+        } else {
+          __ Move(result, left);
+        }
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+  }
+}
+
+
+void LCodeGen::DoSubI(LSubI* instr) {
+  LOperand* right = instr->right();
+  Register left = ToRegister(instr->left());
+  Register result = ToRegister(instr->result());
+  bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
+  if (!can_overflow) {
+    if (right->IsConstantOperand()) {
+      __ Add(result, left, -(ToOperand(right).immediate()), r0);
+    } else {
+      __ sub(result, left, EmitLoadRegister(right, ip));
+    }
+  } else {
+    if (right->IsConstantOperand()) {
+      __ AddAndCheckForOverflow(result, left, -(ToOperand(right).immediate()),
+                                scratch0(), r0);
+    } else {
+      __ SubAndCheckForOverflow(result, left, EmitLoadRegister(right, ip),
+                                scratch0(), r0);
+    }
+// Doptimize on overflow
+#if V8_TARGET_ARCH_PPC64
+    if (!instr->hydrogen()->representation().IsSmi()) {
+      __ extsw(scratch0(), scratch0(), SetRC);
+    }
+#endif
+    DeoptimizeIf(lt, instr, "overflow", cr0);
+  }
+
+#if V8_TARGET_ARCH_PPC64
+  if (!instr->hydrogen()->representation().IsSmi()) {
+    __ extsw(result, result);
+  }
+#endif
+}
+
+
+void LCodeGen::DoRSubI(LRSubI* instr) {
+  LOperand* left = instr->left();
+  LOperand* right = instr->right();
+  LOperand* result = instr->result();
+
+  DCHECK(!instr->hydrogen()->CheckFlag(HValue::kCanOverflow) &&
+         right->IsConstantOperand());
+
+  Operand right_operand = ToOperand(right);
+  if (is_int16(right_operand.immediate())) {
+    __ subfic(ToRegister(result), ToRegister(left), right_operand);
+  } else {
+    __ mov(r0, right_operand);
+    __ sub(ToRegister(result), r0, ToRegister(left));
+  }
+}
+
+
+void LCodeGen::DoConstantI(LConstantI* instr) {
+  __ mov(ToRegister(instr->result()), Operand(instr->value()));
+}
+
+
+void LCodeGen::DoConstantS(LConstantS* instr) {
+  __ LoadSmiLiteral(ToRegister(instr->result()), instr->value());
+}
+
+
+// TODO(penguin): put const to constant pool instead
+// of storing double to stack
+void LCodeGen::DoConstantD(LConstantD* instr) {
+  DCHECK(instr->result()->IsDoubleRegister());
+  DoubleRegister result = ToDoubleRegister(instr->result());
+  double v = instr->value();
+  __ LoadDoubleLiteral(result, v, scratch0());
+}
+
+
+void LCodeGen::DoConstantE(LConstantE* instr) {
+  __ mov(ToRegister(instr->result()), Operand(instr->value()));
+}
+
+
+void LCodeGen::DoConstantT(LConstantT* instr) {
+  Handle<Object> object = instr->value(isolate());
+  AllowDeferredHandleDereference smi_check;
+  __ Move(ToRegister(instr->result()), object);
+}
+
+
+void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
+  Register result = ToRegister(instr->result());
+  Register map = ToRegister(instr->value());
+  __ EnumLength(result, map);
+}
+
+
+void LCodeGen::DoDateField(LDateField* instr) {
+  Register object = ToRegister(instr->date());
+  Register result = ToRegister(instr->result());
+  Register scratch = ToRegister(instr->temp());
+  Smi* index = instr->index();
+  Label runtime, done;
+  DCHECK(object.is(result));
+  DCHECK(object.is(r3));
+  DCHECK(!scratch.is(scratch0()));
+  DCHECK(!scratch.is(object));
+
+  __ TestIfSmi(object, r0);
+  DeoptimizeIf(eq, instr, "Smi", cr0);
+  __ CompareObjectType(object, scratch, scratch, JS_DATE_TYPE);
+  DeoptimizeIf(ne, instr, "not a date object");
+
+  if (index->value() == 0) {
+    __ LoadP(result, FieldMemOperand(object, JSDate::kValueOffset));
+  } else {
+    if (index->value() < JSDate::kFirstUncachedField) {
+      ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
+      __ mov(scratch, Operand(stamp));
+      __ LoadP(scratch, MemOperand(scratch));
+      __ LoadP(scratch0(), FieldMemOperand(object, JSDate::kCacheStampOffset));
+      __ cmp(scratch, scratch0());
+      __ bne(&runtime);
+      __ LoadP(result,
+               FieldMemOperand(object, JSDate::kValueOffset +
+                                           kPointerSize * index->value()));
+      __ b(&done);
+    }
+    __ bind(&runtime);
+    __ PrepareCallCFunction(2, scratch);
+    __ LoadSmiLiteral(r4, index);
+    __ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
+    __ bind(&done);
+  }
+}
+
+
+MemOperand LCodeGen::BuildSeqStringOperand(Register string, LOperand* index,
+                                           String::Encoding encoding) {
+  if (index->IsConstantOperand()) {
+    int offset = ToInteger32(LConstantOperand::cast(index));
+    if (encoding == String::TWO_BYTE_ENCODING) {
+      offset *= kUC16Size;
+    }
+    STATIC_ASSERT(kCharSize == 1);
+    return FieldMemOperand(string, SeqString::kHeaderSize + offset);
+  }
+  Register scratch = scratch0();
+  DCHECK(!scratch.is(string));
+  DCHECK(!scratch.is(ToRegister(index)));
+  if (encoding == String::ONE_BYTE_ENCODING) {
+    __ add(scratch, string, ToRegister(index));
+  } else {
+    STATIC_ASSERT(kUC16Size == 2);
+    __ ShiftLeftImm(scratch, ToRegister(index), Operand(1));
+    __ add(scratch, string, scratch);
+  }
+  return FieldMemOperand(scratch, SeqString::kHeaderSize);
+}
+
+
+void LCodeGen::DoSeqStringGetChar(LSeqStringGetChar* instr) {
+  String::Encoding encoding = instr->hydrogen()->encoding();
+  Register string = ToRegister(instr->string());
+  Register result = ToRegister(instr->result());
+
+  if (FLAG_debug_code) {
+    Register scratch = scratch0();
+    __ LoadP(scratch, FieldMemOperand(string, HeapObject::kMapOffset));
+    __ lbz(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
+
+    __ andi(scratch, scratch,
+            Operand(kStringRepresentationMask | kStringEncodingMask));
+    static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
+    static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
+    __ cmpi(scratch,
+            Operand(encoding == String::ONE_BYTE_ENCODING ? one_byte_seq_type
+                                                          : two_byte_seq_type));
+    __ Check(eq, kUnexpectedStringType);
+  }
+
+  MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding);
+  if (encoding == String::ONE_BYTE_ENCODING) {
+    __ lbz(result, operand);
+  } else {
+    __ lhz(result, operand);
+  }
+}
+
+
+void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
+  String::Encoding encoding = instr->hydrogen()->encoding();
+  Register string = ToRegister(instr->string());
+  Register value = ToRegister(instr->value());
+
+  if (FLAG_debug_code) {
+    Register index = ToRegister(instr->index());
+    static const uint32_t one_byte_seq_type = kSeqStringTag | kOneByteStringTag;
+    static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
+    int encoding_mask =
+        instr->hydrogen()->encoding() == String::ONE_BYTE_ENCODING
+            ? one_byte_seq_type
+            : two_byte_seq_type;
+    __ EmitSeqStringSetCharCheck(string, index, value, encoding_mask);
+  }
+
+  MemOperand operand = BuildSeqStringOperand(string, instr->index(), encoding);
+  if (encoding == String::ONE_BYTE_ENCODING) {
+    __ stb(value, operand);
+  } else {
+    __ sth(value, operand);
+  }
+}
+
+
+void LCodeGen::DoAddI(LAddI* instr) {
+  LOperand* right = instr->right();
+  Register left = ToRegister(instr->left());
+  Register result = ToRegister(instr->result());
+  bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
+#if V8_TARGET_ARCH_PPC64
+  bool isInteger = !(instr->hydrogen()->representation().IsSmi() ||
+                     instr->hydrogen()->representation().IsExternal());
+#endif
+
+  if (!can_overflow) {
+    if (right->IsConstantOperand()) {
+      __ Add(result, left, ToOperand(right).immediate(), r0);
+    } else {
+      __ add(result, left, EmitLoadRegister(right, ip));
+    }
+  } else {
+    if (right->IsConstantOperand()) {
+      __ AddAndCheckForOverflow(result, left, ToOperand(right).immediate(),
+                                scratch0(), r0);
+    } else {
+      __ AddAndCheckForOverflow(result, left, EmitLoadRegister(right, ip),
+                                scratch0(), r0);
+    }
+// Doptimize on overflow
+#if V8_TARGET_ARCH_PPC64
+    if (isInteger) {
+      __ extsw(scratch0(), scratch0(), SetRC);
+    }
+#endif
+    DeoptimizeIf(lt, instr, "overflow", cr0);
+  }
+
+#if V8_TARGET_ARCH_PPC64
+  if (isInteger) {
+    __ extsw(result, result);
+  }
+#endif
+}
+
+
+void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
+  LOperand* left = instr->left();
+  LOperand* right = instr->right();
+  HMathMinMax::Operation operation = instr->hydrogen()->operation();
+  Condition cond = (operation == HMathMinMax::kMathMin) ? le : ge;
+  if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
+    Register left_reg = ToRegister(left);
+    Register right_reg = EmitLoadRegister(right, ip);
+    Register result_reg = ToRegister(instr->result());
+    Label return_left, done;
+#if V8_TARGET_ARCH_PPC64
+    if (instr->hydrogen_value()->representation().IsSmi()) {
+#endif
+      __ cmp(left_reg, right_reg);
+#if V8_TARGET_ARCH_PPC64
+    } else {
+      __ cmpw(left_reg, right_reg);
+    }
+#endif
+    __ b(cond, &return_left);
+    __ Move(result_reg, right_reg);
+    __ b(&done);
+    __ bind(&return_left);
+    __ Move(result_reg, left_reg);
+    __ bind(&done);
+  } else {
+    DCHECK(instr->hydrogen()->representation().IsDouble());
+    DoubleRegister left_reg = ToDoubleRegister(left);
+    DoubleRegister right_reg = ToDoubleRegister(right);
+    DoubleRegister result_reg = ToDoubleRegister(instr->result());
+    Label check_nan_left, check_zero, return_left, return_right, done;
+    __ fcmpu(left_reg, right_reg);
+    __ bunordered(&check_nan_left);
+    __ beq(&check_zero);
+    __ b(cond, &return_left);
+    __ b(&return_right);
+
+    __ bind(&check_zero);
+    __ fcmpu(left_reg, kDoubleRegZero);
+    __ bne(&return_left);  // left == right != 0.
+
+    // At this point, both left and right are either 0 or -0.
+    // N.B. The following works because +0 + -0 == +0
+    if (operation == HMathMinMax::kMathMin) {
+      // For min we want logical-or of sign bit: -(-L + -R)
+      __ fneg(left_reg, left_reg);
+      __ fsub(result_reg, left_reg, right_reg);
+      __ fneg(result_reg, result_reg);
+    } else {
+      // For max we want logical-and of sign bit: (L + R)
+      __ fadd(result_reg, left_reg, right_reg);
+    }
+    __ b(&done);
+
+    __ bind(&check_nan_left);
+    __ fcmpu(left_reg, left_reg);
+    __ bunordered(&return_left);  // left == NaN.
+
+    __ bind(&return_right);
+    if (!right_reg.is(result_reg)) {
+      __ fmr(result_reg, right_reg);
+    }
+    __ b(&done);
+
+    __ bind(&return_left);
+    if (!left_reg.is(result_reg)) {
+      __ fmr(result_reg, left_reg);
+    }
+    __ bind(&done);
+  }
+}
+
+
+void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
+  DoubleRegister left = ToDoubleRegister(instr->left());
+  DoubleRegister right = ToDoubleRegister(instr->right());
+  DoubleRegister result = ToDoubleRegister(instr->result());
+  switch (instr->op()) {
+    case Token::ADD:
+      __ fadd(result, left, right);
+      break;
+    case Token::SUB:
+      __ fsub(result, left, right);
+      break;
+    case Token::MUL:
+      __ fmul(result, left, right);
+      break;
+    case Token::DIV:
+      __ fdiv(result, left, right);
+      break;
+    case Token::MOD: {
+      __ PrepareCallCFunction(0, 2, scratch0());
+      __ MovToFloatParameters(left, right);
+      __ CallCFunction(ExternalReference::mod_two_doubles_operation(isolate()),
+                       0, 2);
+      // Move the result in the double result register.
+      __ MovFromFloatResult(result);
+      break;
+    }
+    default:
+      UNREACHABLE();
+      break;
+  }
+}
+
+
+void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->left()).is(r4));
+  DCHECK(ToRegister(instr->right()).is(r3));
+  DCHECK(ToRegister(instr->result()).is(r3));
+
+  Handle<Code> code =
+      CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
+  CallCode(code, RelocInfo::CODE_TARGET, instr);
+}
+
+
+template <class InstrType>
+void LCodeGen::EmitBranch(InstrType instr, Condition cond, CRegister cr) {
+  int left_block = instr->TrueDestination(chunk_);
+  int right_block = instr->FalseDestination(chunk_);
+
+  int next_block = GetNextEmittedBlock();
+
+  if (right_block == left_block || cond == al) {
+    EmitGoto(left_block);
+  } else if (left_block == next_block) {
+    __ b(NegateCondition(cond), chunk_->GetAssemblyLabel(right_block), cr);
+  } else if (right_block == next_block) {
+    __ b(cond, chunk_->GetAssemblyLabel(left_block), cr);
+  } else {
+    __ b(cond, chunk_->GetAssemblyLabel(left_block), cr);
+    __ b(chunk_->GetAssemblyLabel(right_block));
+  }
+}
+
+
+template <class InstrType>
+void LCodeGen::EmitFalseBranch(InstrType instr, Condition cond, CRegister cr) {
+  int false_block = instr->FalseDestination(chunk_);
+  __ b(cond, chunk_->GetAssemblyLabel(false_block), cr);
+}
+
+
+void LCodeGen::DoDebugBreak(LDebugBreak* instr) { __ stop("LBreak"); }
+
+
+void LCodeGen::DoBranch(LBranch* instr) {
+  Representation r = instr->hydrogen()->value()->representation();
+  DoubleRegister dbl_scratch = double_scratch0();
+  const uint crZOrNaNBits = (1 << (31 - Assembler::encode_crbit(cr7, CR_EQ)) |
+                             1 << (31 - Assembler::encode_crbit(cr7, CR_FU)));
+
+  if (r.IsInteger32()) {
+    DCHECK(!info()->IsStub());
+    Register reg = ToRegister(instr->value());
+    __ cmpwi(reg, Operand::Zero());
+    EmitBranch(instr, ne);
+  } else if (r.IsSmi()) {
+    DCHECK(!info()->IsStub());
+    Register reg = ToRegister(instr->value());
+    __ cmpi(reg, Operand::Zero());
+    EmitBranch(instr, ne);
+  } else if (r.IsDouble()) {
+    DCHECK(!info()->IsStub());
+    DoubleRegister reg = ToDoubleRegister(instr->value());
+    // Test the double value. Zero and NaN are false.
+    __ fcmpu(reg, kDoubleRegZero, cr7);
+    __ mfcr(r0);
+    __ andi(r0, r0, Operand(crZOrNaNBits));
+    EmitBranch(instr, eq, cr0);
+  } else {
+    DCHECK(r.IsTagged());
+    Register reg = ToRegister(instr->value());
+    HType type = instr->hydrogen()->value()->type();
+    if (type.IsBoolean()) {
+      DCHECK(!info()->IsStub());
+      __ CompareRoot(reg, Heap::kTrueValueRootIndex);
+      EmitBranch(instr, eq);
+    } else if (type.IsSmi()) {
+      DCHECK(!info()->IsStub());
+      __ cmpi(reg, Operand::Zero());
+      EmitBranch(instr, ne);
+    } else if (type.IsJSArray()) {
+      DCHECK(!info()->IsStub());
+      EmitBranch(instr, al);
+    } else if (type.IsHeapNumber()) {
+      DCHECK(!info()->IsStub());
+      __ lfd(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
+      // Test the double value. Zero and NaN are false.
+      __ fcmpu(dbl_scratch, kDoubleRegZero, cr7);
+      __ mfcr(r0);
+      __ andi(r0, r0, Operand(crZOrNaNBits));
+      EmitBranch(instr, eq, cr0);
+    } else if (type.IsString()) {
+      DCHECK(!info()->IsStub());
+      __ LoadP(ip, FieldMemOperand(reg, String::kLengthOffset));
+      __ cmpi(ip, Operand::Zero());
+      EmitBranch(instr, ne);
+    } else {
+      ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
+      // Avoid deopts in the case where we've never executed this path before.
+      if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
+
+      if (expected.Contains(ToBooleanStub::UNDEFINED)) {
+        // undefined -> false.
+        __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
+        __ beq(instr->FalseLabel(chunk_));
+      }
+      if (expected.Contains(ToBooleanStub::BOOLEAN)) {
+        // Boolean -> its value.
+        __ CompareRoot(reg, Heap::kTrueValueRootIndex);
+        __ beq(instr->TrueLabel(chunk_));
+        __ CompareRoot(reg, Heap::kFalseValueRootIndex);
+        __ beq(instr->FalseLabel(chunk_));
+      }
+      if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
+        // 'null' -> false.
+        __ CompareRoot(reg, Heap::kNullValueRootIndex);
+        __ beq(instr->FalseLabel(chunk_));
+      }
+
+      if (expected.Contains(ToBooleanStub::SMI)) {
+        // Smis: 0 -> false, all other -> true.
+        __ cmpi(reg, Operand::Zero());
+        __ beq(instr->FalseLabel(chunk_));
+        __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
+      } else if (expected.NeedsMap()) {
+        // If we need a map later and have a Smi -> deopt.
+        __ TestIfSmi(reg, r0);
+        DeoptimizeIf(eq, instr, "Smi", cr0);
+      }
+
+      const Register map = scratch0();
+      if (expected.NeedsMap()) {
+        __ LoadP(map, FieldMemOperand(reg, HeapObject::kMapOffset));
+
+        if (expected.CanBeUndetectable()) {
+          // Undetectable -> false.
+          __ lbz(ip, FieldMemOperand(map, Map::kBitFieldOffset));
+          __ TestBit(ip, Map::kIsUndetectable, r0);
+          __ bne(instr->FalseLabel(chunk_), cr0);
+        }
+      }
+
+      if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
+        // spec object -> true.
+        __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE);
+        __ bge(instr->TrueLabel(chunk_));
+      }
+
+      if (expected.Contains(ToBooleanStub::STRING)) {
+        // String value -> false iff empty.
+        Label not_string;
+        __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
+        __ bge(&not_string);
+        __ LoadP(ip, FieldMemOperand(reg, String::kLengthOffset));
+        __ cmpi(ip, Operand::Zero());
+        __ bne(instr->TrueLabel(chunk_));
+        __ b(instr->FalseLabel(chunk_));
+        __ bind(&not_string);
+      }
+
+      if (expected.Contains(ToBooleanStub::SYMBOL)) {
+        // Symbol value -> true.
+        __ CompareInstanceType(map, ip, SYMBOL_TYPE);
+        __ beq(instr->TrueLabel(chunk_));
+      }
+
+      if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
+        // heap number -> false iff +0, -0, or NaN.
+        Label not_heap_number;
+        __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
+        __ bne(&not_heap_number);
+        __ lfd(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
+        // Test the double value. Zero and NaN are false.
+        __ fcmpu(dbl_scratch, kDoubleRegZero, cr7);
+        __ mfcr(r0);
+        __ andi(r0, r0, Operand(crZOrNaNBits));
+        __ bne(instr->FalseLabel(chunk_), cr0);
+        __ b(instr->TrueLabel(chunk_));
+        __ bind(&not_heap_number);
+      }
+
+      if (!expected.IsGeneric()) {
+        // We've seen something for the first time -> deopt.
+        // This can only happen if we are not generic already.
+        DeoptimizeIf(al, instr, "unexpected object");
+      }
+    }
+  }
+}
+
+
+void LCodeGen::EmitGoto(int block) {
+  if (!IsNextEmittedBlock(block)) {
+    __ b(chunk_->GetAssemblyLabel(LookupDestination(block)));
+  }
+}
+
+
+void LCodeGen::DoGoto(LGoto* instr) { EmitGoto(instr->block_id()); }
+
+
+Condition LCodeGen::TokenToCondition(Token::Value op) {
+  Condition cond = kNoCondition;
+  switch (op) {
+    case Token::EQ:
+    case Token::EQ_STRICT:
+      cond = eq;
+      break;
+    case Token::NE:
+    case Token::NE_STRICT:
+      cond = ne;
+      break;
+    case Token::LT:
+      cond = lt;
+      break;
+    case Token::GT:
+      cond = gt;
+      break;
+    case Token::LTE:
+      cond = le;
+      break;
+    case Token::GTE:
+      cond = ge;
+      break;
+    case Token::IN:
+    case Token::INSTANCEOF:
+    default:
+      UNREACHABLE();
+  }
+  return cond;
+}
+
+
+void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
+  LOperand* left = instr->left();
+  LOperand* right = instr->right();
+  bool is_unsigned =
+      instr->hydrogen()->left()->CheckFlag(HInstruction::kUint32) ||
+      instr->hydrogen()->right()->CheckFlag(HInstruction::kUint32);
+  Condition cond = TokenToCondition(instr->op());
+
+  if (left->IsConstantOperand() && right->IsConstantOperand()) {
+    // We can statically evaluate the comparison.
+    double left_val = ToDouble(LConstantOperand::cast(left));
+    double right_val = ToDouble(LConstantOperand::cast(right));
+    int next_block = EvalComparison(instr->op(), left_val, right_val)
+                         ? instr->TrueDestination(chunk_)
+                         : instr->FalseDestination(chunk_);
+    EmitGoto(next_block);
+  } else {
+    if (instr->is_double()) {
+      // Compare left and right operands as doubles and load the
+      // resulting flags into the normal status register.
+      __ fcmpu(ToDoubleRegister(left), ToDoubleRegister(right));
+      // If a NaN is involved, i.e. the result is unordered,
+      // jump to false block label.
+      __ bunordered(instr->FalseLabel(chunk_));
+    } else {
+      if (right->IsConstantOperand()) {
+        int32_t value = ToInteger32(LConstantOperand::cast(right));
+        if (instr->hydrogen_value()->representation().IsSmi()) {
+          if (is_unsigned) {
+            __ CmplSmiLiteral(ToRegister(left), Smi::FromInt(value), r0);
+          } else {
+            __ CmpSmiLiteral(ToRegister(left), Smi::FromInt(value), r0);
+          }
+        } else {
+          if (is_unsigned) {
+            __ Cmplwi(ToRegister(left), Operand(value), r0);
+          } else {
+            __ Cmpwi(ToRegister(left), Operand(value), r0);
+          }
+        }
+      } else if (left->IsConstantOperand()) {
+        int32_t value = ToInteger32(LConstantOperand::cast(left));
+        if (instr->hydrogen_value()->representation().IsSmi()) {
+          if (is_unsigned) {
+            __ CmplSmiLiteral(ToRegister(right), Smi::FromInt(value), r0);
+          } else {
+            __ CmpSmiLiteral(ToRegister(right), Smi::FromInt(value), r0);
+          }
+        } else {
+          if (is_unsigned) {
+            __ Cmplwi(ToRegister(right), Operand(value), r0);
+          } else {
+            __ Cmpwi(ToRegister(right), Operand(value), r0);
+          }
+        }
+        // We commuted the operands, so commute the condition.
+        cond = CommuteCondition(cond);
+      } else if (instr->hydrogen_value()->representation().IsSmi()) {
+        if (is_unsigned) {
+          __ cmpl(ToRegister(left), ToRegister(right));
+        } else {
+          __ cmp(ToRegister(left), ToRegister(right));
+        }
+      } else {
+        if (is_unsigned) {
+          __ cmplw(ToRegister(left), ToRegister(right));
+        } else {
+          __ cmpw(ToRegister(left), ToRegister(right));
+        }
+      }
+    }
+    EmitBranch(instr, cond);
+  }
+}
+
+
+void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
+  Register left = ToRegister(instr->left());
+  Register right = ToRegister(instr->right());
+
+  __ cmp(left, right);
+  EmitBranch(instr, eq);
+}
+
+
+void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
+  if (instr->hydrogen()->representation().IsTagged()) {
+    Register input_reg = ToRegister(instr->object());
+    __ mov(ip, Operand(factory()->the_hole_value()));
+    __ cmp(input_reg, ip);
+    EmitBranch(instr, eq);
+    return;
+  }
+
+  DoubleRegister input_reg = ToDoubleRegister(instr->object());
+  __ fcmpu(input_reg, input_reg);
+  EmitFalseBranch(instr, ordered);
+
+  Register scratch = scratch0();
+  __ MovDoubleHighToInt(scratch, input_reg);
+  __ Cmpi(scratch, Operand(kHoleNanUpper32), r0);
+  EmitBranch(instr, eq);
+}
+
+
+void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
+  Representation rep = instr->hydrogen()->value()->representation();
+  DCHECK(!rep.IsInteger32());
+  Register scratch = ToRegister(instr->temp());
+
+  if (rep.IsDouble()) {
+    DoubleRegister value = ToDoubleRegister(instr->value());
+    __ fcmpu(value, kDoubleRegZero);
+    EmitFalseBranch(instr, ne);
+#if V8_TARGET_ARCH_PPC64
+    __ MovDoubleToInt64(scratch, value);
+#else
+    __ MovDoubleHighToInt(scratch, value);
+#endif
+    __ cmpi(scratch, Operand::Zero());
+    EmitBranch(instr, lt);
+  } else {
+    Register value = ToRegister(instr->value());
+    __ CheckMap(value, scratch, Heap::kHeapNumberMapRootIndex,
+                instr->FalseLabel(chunk()), DO_SMI_CHECK);
+#if V8_TARGET_ARCH_PPC64
+    __ LoadP(scratch, FieldMemOperand(value, HeapNumber::kValueOffset));
+    __ li(ip, Operand(1));
+    __ rotrdi(ip, ip, 1);  // ip = 0x80000000_00000000
+    __ cmp(scratch, ip);
+#else
+    __ lwz(scratch, FieldMemOperand(value, HeapNumber::kExponentOffset));
+    __ lwz(ip, FieldMemOperand(value, HeapNumber::kMantissaOffset));
+    Label skip;
+    __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000)));
+    __ cmp(scratch, r0);
+    __ bne(&skip);
+    __ cmpi(ip, Operand::Zero());
+    __ bind(&skip);
+#endif
+    EmitBranch(instr, eq);
+  }
+}
+
+
+Condition LCodeGen::EmitIsObject(Register input, Register temp1,
+                                 Label* is_not_object, Label* is_object) {
+  Register temp2 = scratch0();
+  __ JumpIfSmi(input, is_not_object);
+
+  __ LoadRoot(temp2, Heap::kNullValueRootIndex);
+  __ cmp(input, temp2);
+  __ beq(is_object);
+
+  // Load map.
+  __ LoadP(temp1, FieldMemOperand(input, HeapObject::kMapOffset));
+  // Undetectable objects behave like undefined.
+  __ lbz(temp2, FieldMemOperand(temp1, Map::kBitFieldOffset));
+  __ TestBit(temp2, Map::kIsUndetectable, r0);
+  __ bne(is_not_object, cr0);
+
+  // Load instance type and check that it is in object type range.
+  __ lbz(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset));
+  __ cmpi(temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
+  __ blt(is_not_object);
+  __ cmpi(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
+  return le;
+}
+
+
+void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
+  Register reg = ToRegister(instr->value());
+  Register temp1 = ToRegister(instr->temp());
+
+  Condition true_cond = EmitIsObject(reg, temp1, instr->FalseLabel(chunk_),
+                                     instr->TrueLabel(chunk_));
+
+  EmitBranch(instr, true_cond);
+}
+
+
+Condition LCodeGen::EmitIsString(Register input, Register temp1,
+                                 Label* is_not_string,
+                                 SmiCheck check_needed = INLINE_SMI_CHECK) {
+  if (check_needed == INLINE_SMI_CHECK) {
+    __ JumpIfSmi(input, is_not_string);
+  }
+  __ CompareObjectType(input, temp1, temp1, FIRST_NONSTRING_TYPE);
+
+  return lt;
+}
+
+
+void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
+  Register reg = ToRegister(instr->value());
+  Register temp1 = ToRegister(instr->temp());
+
+  SmiCheck check_needed = instr->hydrogen()->value()->type().IsHeapObject()
+                              ? OMIT_SMI_CHECK
+                              : INLINE_SMI_CHECK;
+  Condition true_cond =
+      EmitIsString(reg, temp1, instr->FalseLabel(chunk_), check_needed);
+
+  EmitBranch(instr, true_cond);
+}
+
+
+void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
+  Register input_reg = EmitLoadRegister(instr->value(), ip);
+  __ TestIfSmi(input_reg, r0);
+  EmitBranch(instr, eq, cr0);
+}
+
+
+void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
+  Register input = ToRegister(instr->value());
+  Register temp = ToRegister(instr->temp());
+
+  if (!instr->hydrogen()->value()->type().IsHeapObject()) {
+    __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  }
+  __ LoadP(temp, FieldMemOperand(input, HeapObject::kMapOffset));
+  __ lbz(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
+  __ TestBit(temp, Map::kIsUndetectable, r0);
+  EmitBranch(instr, ne, cr0);
+}
+
+
+static Condition ComputeCompareCondition(Token::Value op) {
+  switch (op) {
+    case Token::EQ_STRICT:
+    case Token::EQ:
+      return eq;
+    case Token::LT:
+      return lt;
+    case Token::GT:
+      return gt;
+    case Token::LTE:
+      return le;
+    case Token::GTE:
+      return ge;
+    default:
+      UNREACHABLE();
+      return kNoCondition;
+  }
+}
+
+
+void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  Token::Value op = instr->op();
+
+  Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code();
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
+  // This instruction also signals no smi code inlined
+  __ cmpi(r3, Operand::Zero());
+
+  Condition condition = ComputeCompareCondition(op);
+
+  EmitBranch(instr, condition);
+}
+
+
+static InstanceType TestType(HHasInstanceTypeAndBranch* instr) {
+  InstanceType from = instr->from();
+  InstanceType to = instr->to();
+  if (from == FIRST_TYPE) return to;
+  DCHECK(from == to || to == LAST_TYPE);
+  return from;
+}
+
+
+static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
+  InstanceType from = instr->from();
+  InstanceType to = instr->to();
+  if (from == to) return eq;
+  if (to == LAST_TYPE) return ge;
+  if (from == FIRST_TYPE) return le;
+  UNREACHABLE();
+  return eq;
+}
+
+
+void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
+  Register scratch = scratch0();
+  Register input = ToRegister(instr->value());
+
+  if (!instr->hydrogen()->value()->type().IsHeapObject()) {
+    __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+  }
+
+  __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen()));
+  EmitBranch(instr, BranchCondition(instr->hydrogen()));
+}
+
+
+void LCodeGen::DoGetCachedArrayIndex(LGetCachedArrayIndex* instr) {
+  Register input = ToRegister(instr->value());
+  Register result = ToRegister(instr->result());
+
+  __ AssertString(input);
+
+  __ lwz(result, FieldMemOperand(input, String::kHashFieldOffset));
+  __ IndexFromHash(result, result);
+}
+
+
+void LCodeGen::DoHasCachedArrayIndexAndBranch(
+    LHasCachedArrayIndexAndBranch* instr) {
+  Register input = ToRegister(instr->value());
+  Register scratch = scratch0();
+
+  __ lwz(scratch, FieldMemOperand(input, String::kHashFieldOffset));
+  __ mov(r0, Operand(String::kContainsCachedArrayIndexMask));
+  __ and_(r0, scratch, r0, SetRC);
+  EmitBranch(instr, eq, cr0);
+}
+
+
+// Branches to a label or falls through with the answer in flags.  Trashes
+// the temp registers, but not the input.
+void LCodeGen::EmitClassOfTest(Label* is_true, Label* is_false,
+                               Handle<String> class_name, Register input,
+                               Register temp, Register temp2) {
+  DCHECK(!input.is(temp));
+  DCHECK(!input.is(temp2));
+  DCHECK(!temp.is(temp2));
+
+  __ JumpIfSmi(input, is_false);
+
+  if (String::Equals(isolate()->factory()->Function_string(), class_name)) {
+    // Assuming the following assertions, we can use the same compares to test
+    // for both being a function type and being in the object type range.
+    STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
+    STATIC_ASSERT(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE ==
+                  FIRST_SPEC_OBJECT_TYPE + 1);
+    STATIC_ASSERT(LAST_NONCALLABLE_SPEC_OBJECT_TYPE ==
+                  LAST_SPEC_OBJECT_TYPE - 1);
+    STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+    __ CompareObjectType(input, temp, temp2, FIRST_SPEC_OBJECT_TYPE);
+    __ blt(is_false);
+    __ beq(is_true);
+    __ cmpi(temp2, Operand(LAST_SPEC_OBJECT_TYPE));
+    __ beq(is_true);
+  } else {
+    // Faster code path to avoid two compares: subtract lower bound from the
+    // actual type and do a signed compare with the width of the type range.
+    __ LoadP(temp, FieldMemOperand(input, HeapObject::kMapOffset));
+    __ lbz(temp2, FieldMemOperand(temp, Map::kInstanceTypeOffset));
+    __ subi(temp2, temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
+    __ cmpi(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE -
+                           FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
+    __ bgt(is_false);
+  }
+
+  // Now we are in the FIRST-LAST_NONCALLABLE_SPEC_OBJECT_TYPE range.
+  // Check if the constructor in the map is a function.
+  __ LoadP(temp, FieldMemOperand(temp, Map::kConstructorOffset));
+
+  // Objects with a non-function constructor have class 'Object'.
+  __ CompareObjectType(temp, temp2, temp2, JS_FUNCTION_TYPE);
+  if (class_name->IsOneByteEqualTo(STATIC_CHAR_VECTOR("Object"))) {
+    __ bne(is_true);
+  } else {
+    __ bne(is_false);
+  }
+
+  // temp now contains the constructor function. Grab the
+  // instance class name from there.
+  __ LoadP(temp, FieldMemOperand(temp, JSFunction::kSharedFunctionInfoOffset));
+  __ LoadP(temp,
+           FieldMemOperand(temp, SharedFunctionInfo::kInstanceClassNameOffset));
+  // The class name we are testing against is internalized since it's a literal.
+  // The name in the constructor is internalized because of the way the context
+  // is booted.  This routine isn't expected to work for random API-created
+  // classes and it doesn't have to because you can't access it with natives
+  // syntax.  Since both sides are internalized it is sufficient to use an
+  // identity comparison.
+  __ Cmpi(temp, Operand(class_name), r0);
+  // End with the answer in flags.
+}
+
+
+void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
+  Register input = ToRegister(instr->value());
+  Register temp = scratch0();
+  Register temp2 = ToRegister(instr->temp());
+  Handle<String> class_name = instr->hydrogen()->class_name();
+
+  EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
+                  class_name, input, temp, temp2);
+
+  EmitBranch(instr, eq);
+}
+
+
+void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
+  Register reg = ToRegister(instr->value());
+  Register temp = ToRegister(instr->temp());
+
+  __ LoadP(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
+  __ Cmpi(temp, Operand(instr->map()), r0);
+  EmitBranch(instr, eq);
+}
+
+
+void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->left()).is(r3));   // Object is in r3.
+  DCHECK(ToRegister(instr->right()).is(r4));  // Function is in r4.
+
+  InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters);
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+
+  Label equal, done;
+  __ cmpi(r3, Operand::Zero());
+  __ beq(&equal);
+  __ mov(r3, Operand(factory()->false_value()));
+  __ b(&done);
+
+  __ bind(&equal);
+  __ mov(r3, Operand(factory()->true_value()));
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
+  class DeferredInstanceOfKnownGlobal FINAL : public LDeferredCode {
+   public:
+    DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
+                                  LInstanceOfKnownGlobal* instr)
+        : LDeferredCode(codegen), instr_(instr) {}
+    void Generate() OVERRIDE {
+      codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
+    }
+    LInstruction* instr() OVERRIDE { return instr_; }
+    Label* map_check() { return &map_check_; }
+
+   private:
+    LInstanceOfKnownGlobal* instr_;
+    Label map_check_;
+  };
+
+  DeferredInstanceOfKnownGlobal* deferred;
+  deferred = new (zone()) DeferredInstanceOfKnownGlobal(this, instr);
+
+  Label done, false_result;
+  Register object = ToRegister(instr->value());
+  Register temp = ToRegister(instr->temp());
+  Register result = ToRegister(instr->result());
+
+  // A Smi is not instance of anything.
+  __ JumpIfSmi(object, &false_result);
+
+  // This is the inlined call site instanceof cache. The two occurences of the
+  // hole value will be patched to the last map/result pair generated by the
+  // instanceof stub.
+  Label cache_miss;
+  Register map = temp;
+  __ LoadP(map, FieldMemOperand(object, HeapObject::kMapOffset));
+  {
+    // Block constant pool emission to ensure the positions of instructions are
+    // as expected by the patcher. See InstanceofStub::Generate().
+    Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
+    __ bind(deferred->map_check());  // Label for calculating code patching.
+    // We use Factory::the_hole_value() on purpose instead of loading from the
+    // root array to force relocation to be able to later patch with
+    // the cached map.
+    Handle<Cell> cell = factory()->NewCell(factory()->the_hole_value());
+    __ mov(ip, Operand(Handle<Object>(cell)));
+    __ LoadP(ip, FieldMemOperand(ip, PropertyCell::kValueOffset));
+    __ cmp(map, ip);
+    __ bne(&cache_miss);
+    // We use Factory::the_hole_value() on purpose instead of loading from the
+    // root array to force relocation to be able to later patch
+    // with true or false.
+    __ mov(result, Operand(factory()->the_hole_value()));
+  }
+  __ b(&done);
+
+  // The inlined call site cache did not match. Check null and string before
+  // calling the deferred code.
+  __ bind(&cache_miss);
+  // Null is not instance of anything.
+  __ LoadRoot(ip, Heap::kNullValueRootIndex);
+  __ cmp(object, ip);
+  __ beq(&false_result);
+
+  // String values is not instance of anything.
+  Condition is_string = masm_->IsObjectStringType(object, temp);
+  __ b(is_string, &false_result, cr0);
+
+  // Go to the deferred code.
+  __ b(deferred->entry());
+
+  __ bind(&false_result);
+  __ LoadRoot(result, Heap::kFalseValueRootIndex);
+
+  // Here result has either true or false. Deferred code also produces true or
+  // false object.
+  __ bind(deferred->exit());
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
+                                               Label* map_check) {
+  InstanceofStub::Flags flags = InstanceofStub::kNoFlags;
+  flags = static_cast<InstanceofStub::Flags>(flags |
+                                             InstanceofStub::kArgsInRegisters);
+  flags = static_cast<InstanceofStub::Flags>(
+      flags | InstanceofStub::kCallSiteInlineCheck);
+  flags = static_cast<InstanceofStub::Flags>(
+      flags | InstanceofStub::kReturnTrueFalseObject);
+  InstanceofStub stub(isolate(), flags);
+
+  PushSafepointRegistersScope scope(this);
+  LoadContextFromDeferred(instr->context());
+
+  __ Move(InstanceofStub::right(), instr->function());
+  // Include instructions below in delta: mov + call = mov + (mov + 2)
+  static const int kAdditionalDelta = (2 * Assembler::kMovInstructions) + 2;
+  int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta;
+  {
+    Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
+    // r8 is used to communicate the offset to the location of the map check.
+    __ mov(r8, Operand(delta * Instruction::kInstrSize));
+  }
+  CallCodeGeneric(stub.GetCode(), RelocInfo::CODE_TARGET, instr,
+                  RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
+  DCHECK(delta == masm_->InstructionsGeneratedSince(map_check));
+  LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
+  safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
+  // Put the result value (r3) into the result register slot and
+  // restore all registers.
+  __ StoreToSafepointRegisterSlot(r3, ToRegister(instr->result()));
+}
+
+
+void LCodeGen::DoCmpT(LCmpT* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  Token::Value op = instr->op();
+
+  Handle<Code> ic = CodeFactory::CompareIC(isolate(), op).code();
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
+  // This instruction also signals no smi code inlined
+  __ cmpi(r3, Operand::Zero());
+
+  Condition condition = ComputeCompareCondition(op);
+  Label true_value, done;
+
+  __ b(condition, &true_value);
+
+  __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
+  __ b(&done);
+
+  __ bind(&true_value);
+  __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
+
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoReturn(LReturn* instr) {
+  if (FLAG_trace && info()->IsOptimizing()) {
+    // Push the return value on the stack as the parameter.
+    // Runtime::TraceExit returns its parameter in r3.  We're leaving the code
+    // managed by the register allocator and tearing down the frame, it's
+    // safe to write to the context register.
+    __ push(r3);
+    __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+    __ CallRuntime(Runtime::kTraceExit, 1);
+  }
+  if (info()->saves_caller_doubles()) {
+    RestoreCallerDoubles();
+  }
+  int no_frame_start = -1;
+  if (instr->has_constant_parameter_count()) {
+    int parameter_count = ToInteger32(instr->constant_parameter_count());
+    int32_t sp_delta = (parameter_count + 1) * kPointerSize;
+    if (NeedsEagerFrame()) {
+      no_frame_start = masm_->LeaveFrame(StackFrame::JAVA_SCRIPT, sp_delta);
+    } else if (sp_delta != 0) {
+      __ addi(sp, sp, Operand(sp_delta));
+    }
+  } else {
+    Register reg = ToRegister(instr->parameter_count());
+    // The argument count parameter is a smi
+    if (NeedsEagerFrame()) {
+      no_frame_start = masm_->LeaveFrame(StackFrame::JAVA_SCRIPT);
+    }
+    __ SmiToPtrArrayOffset(r0, reg);
+    __ add(sp, sp, r0);
+  }
+
+  __ blr();
+
+  if (no_frame_start != -1) {
+    info_->AddNoFrameRange(no_frame_start, masm_->pc_offset());
+  }
+}
+
+
+void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
+  Register result = ToRegister(instr->result());
+  __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell().handle())));
+  __ LoadP(result, FieldMemOperand(ip, Cell::kValueOffset));
+  if (instr->hydrogen()->RequiresHoleCheck()) {
+    __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+    __ cmp(result, ip);
+    DeoptimizeIf(eq, instr, "hole");
+  }
+}
+
+
+template <class T>
+void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
+  DCHECK(FLAG_vector_ics);
+  Register vector = ToRegister(instr->temp_vector());
+  DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister()));
+  __ Move(vector, instr->hydrogen()->feedback_vector());
+  // No need to allocate this register.
+  DCHECK(VectorLoadICDescriptor::SlotRegister().is(r3));
+  __ mov(VectorLoadICDescriptor::SlotRegister(),
+         Operand(Smi::FromInt(instr->hydrogen()->slot())));
+}
+
+
+void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->global_object())
+             .is(LoadDescriptor::ReceiverRegister()));
+  DCHECK(ToRegister(instr->result()).is(r3));
+
+  __ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
+  if (FLAG_vector_ics) {
+    EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
+  }
+  ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
+  Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
+}
+
+
+void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) {
+  Register value = ToRegister(instr->value());
+  Register cell = scratch0();
+
+  // Load the cell.
+  __ mov(cell, Operand(instr->hydrogen()->cell().handle()));
+
+  // If the cell we are storing to contains the hole it could have
+  // been deleted from the property dictionary. In that case, we need
+  // to update the property details in the property dictionary to mark
+  // it as no longer deleted.
+  if (instr->hydrogen()->RequiresHoleCheck()) {
+    // We use a temp to check the payload (CompareRoot might clobber ip).
+    Register payload = ToRegister(instr->temp());
+    __ LoadP(payload, FieldMemOperand(cell, Cell::kValueOffset));
+    __ CompareRoot(payload, Heap::kTheHoleValueRootIndex);
+    DeoptimizeIf(eq, instr, "hole");
+  }
+
+  // Store the value.
+  __ StoreP(value, FieldMemOperand(cell, Cell::kValueOffset), r0);
+  // Cells are always rescanned, so no write barrier here.
+}
+
+
+void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) {
+  Register context = ToRegister(instr->context());
+  Register result = ToRegister(instr->result());
+  __ LoadP(result, ContextOperand(context, instr->slot_index()));
+  if (instr->hydrogen()->RequiresHoleCheck()) {
+    __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+    __ cmp(result, ip);
+    if (instr->hydrogen()->DeoptimizesOnHole()) {
+      DeoptimizeIf(eq, instr, "hole");
+    } else {
+      Label skip;
+      __ bne(&skip);
+      __ mov(result, Operand(factory()->undefined_value()));
+      __ bind(&skip);
+    }
+  }
+}
+
+
+void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
+  Register context = ToRegister(instr->context());
+  Register value = ToRegister(instr->value());
+  Register scratch = scratch0();
+  MemOperand target = ContextOperand(context, instr->slot_index());
+
+  Label skip_assignment;
+
+  if (instr->hydrogen()->RequiresHoleCheck()) {
+    __ LoadP(scratch, target);
+    __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+    __ cmp(scratch, ip);
+    if (instr->hydrogen()->DeoptimizesOnHole()) {
+      DeoptimizeIf(eq, instr, "hole");
+    } else {
+      __ bne(&skip_assignment);
+    }
+  }
+
+  __ StoreP(value, target, r0);
+  if (instr->hydrogen()->NeedsWriteBarrier()) {
+    SmiCheck check_needed = instr->hydrogen()->value()->type().IsHeapObject()
+                                ? OMIT_SMI_CHECK
+                                : INLINE_SMI_CHECK;
+    __ RecordWriteContextSlot(context, target.offset(), value, scratch,
+                              GetLinkRegisterState(), kSaveFPRegs,
+                              EMIT_REMEMBERED_SET, check_needed);
+  }
+
+  __ bind(&skip_assignment);
+}
+
+
+void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
+  HObjectAccess access = instr->hydrogen()->access();
+  int offset = access.offset();
+  Register object = ToRegister(instr->object());
+
+  if (access.IsExternalMemory()) {
+    Register result = ToRegister(instr->result());
+    MemOperand operand = MemOperand(object, offset);
+    __ LoadRepresentation(result, operand, access.representation(), r0);
+    return;
+  }
+
+  if (instr->hydrogen()->representation().IsDouble()) {
+    DoubleRegister result = ToDoubleRegister(instr->result());
+    __ lfd(result, FieldMemOperand(object, offset));
+    return;
+  }
+
+  Register result = ToRegister(instr->result());
+  if (!access.IsInobject()) {
+    __ LoadP(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
+    object = result;
+  }
+
+  Representation representation = access.representation();
+
+#if V8_TARGET_ARCH_PPC64
+  // 64-bit Smi optimization
+  if (representation.IsSmi() &&
+      instr->hydrogen()->representation().IsInteger32()) {
+    // Read int value directly from upper half of the smi.
+    STATIC_ASSERT(kSmiTag == 0);
+    STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
+#if V8_TARGET_LITTLE_ENDIAN
+    offset += kPointerSize / 2;
+#endif
+    representation = Representation::Integer32();
+  }
+#endif
+
+  __ LoadRepresentation(result, FieldMemOperand(object, offset), representation,
+                        r0);
+}
+
+
+void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
+  DCHECK(ToRegister(instr->result()).is(r3));
+
+  // Name is always in r5.
+  __ mov(LoadDescriptor::NameRegister(), Operand(instr->name()));
+  if (FLAG_vector_ics) {
+    EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
+  }
+  Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
+}
+
+
+void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
+  Register scratch = scratch0();
+  Register function = ToRegister(instr->function());
+  Register result = ToRegister(instr->result());
+
+  // Get the prototype or initial map from the function.
+  __ LoadP(result,
+           FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
+
+  // Check that the function has a prototype or an initial map.
+  __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
+  __ cmp(result, ip);
+  DeoptimizeIf(eq, instr, "hole");
+
+  // If the function does not have an initial map, we're done.
+  Label done;
+  __ CompareObjectType(result, scratch, scratch, MAP_TYPE);
+  __ bne(&done);
+
+  // Get the prototype from the initial map.
+  __ LoadP(result, FieldMemOperand(result, Map::kPrototypeOffset));
+
+  // All done.
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoLoadRoot(LLoadRoot* instr) {
+  Register result = ToRegister(instr->result());
+  __ LoadRoot(result, instr->index());
+}
+
+
+void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) {
+  Register arguments = ToRegister(instr->arguments());
+  Register result = ToRegister(instr->result());
+  // There are two words between the frame pointer and the last argument.
+  // Subtracting from length accounts for one of them add one more.
+  if (instr->length()->IsConstantOperand()) {
+    int const_length = ToInteger32(LConstantOperand::cast(instr->length()));
+    if (instr->index()->IsConstantOperand()) {
+      int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
+      int index = (const_length - const_index) + 1;
+      __ LoadP(result, MemOperand(arguments, index * kPointerSize), r0);
+    } else {
+      Register index = ToRegister(instr->index());
+      __ subfic(result, index, Operand(const_length + 1));
+      __ ShiftLeftImm(result, result, Operand(kPointerSizeLog2));
+      __ LoadPX(result, MemOperand(arguments, result));
+    }
+  } else if (instr->index()->IsConstantOperand()) {
+    Register length = ToRegister(instr->length());
+    int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
+    int loc = const_index - 1;
+    if (loc != 0) {
+      __ subi(result, length, Operand(loc));
+      __ ShiftLeftImm(result, result, Operand(kPointerSizeLog2));
+      __ LoadPX(result, MemOperand(arguments, result));
+    } else {
+      __ ShiftLeftImm(result, length, Operand(kPointerSizeLog2));
+      __ LoadPX(result, MemOperand(arguments, result));
+    }
+  } else {
+    Register length = ToRegister(instr->length());
+    Register index = ToRegister(instr->index());
+    __ sub(result, length, index);
+    __ addi(result, result, Operand(1));
+    __ ShiftLeftImm(result, result, Operand(kPointerSizeLog2));
+    __ LoadPX(result, MemOperand(arguments, result));
+  }
+}
+
+
+void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
+  Register external_pointer = ToRegister(instr->elements());
+  Register key = no_reg;
+  ElementsKind elements_kind = instr->elements_kind();
+  bool key_is_constant = instr->key()->IsConstantOperand();
+  int constant_key = 0;
+  if (key_is_constant) {
+    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+    if (constant_key & 0xF0000000) {
+      Abort(kArrayIndexConstantValueTooBig);
+    }
+  } else {
+    key = ToRegister(instr->key());
+  }
+  int element_size_shift = ElementsKindToShiftSize(elements_kind);
+  bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi();
+  int base_offset = instr->base_offset();
+
+  if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
+      elements_kind == FLOAT32_ELEMENTS ||
+      elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
+      elements_kind == FLOAT64_ELEMENTS) {
+    DoubleRegister result = ToDoubleRegister(instr->result());
+    if (key_is_constant) {
+      __ Add(scratch0(), external_pointer, constant_key << element_size_shift,
+             r0);
+    } else {
+      __ IndexToArrayOffset(r0, key, element_size_shift, key_is_smi);
+      __ add(scratch0(), external_pointer, r0);
+    }
+    if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
+        elements_kind == FLOAT32_ELEMENTS) {
+      __ lfs(result, MemOperand(scratch0(), base_offset));
+    } else {  // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
+      __ lfd(result, MemOperand(scratch0(), base_offset));
+    }
+  } else {
+    Register result = ToRegister(instr->result());
+    MemOperand mem_operand =
+        PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi,
+                            constant_key, element_size_shift, base_offset);
+    switch (elements_kind) {
+      case EXTERNAL_INT8_ELEMENTS:
+      case INT8_ELEMENTS:
+        if (key_is_constant) {
+          __ LoadByte(result, mem_operand, r0);
+        } else {
+          __ lbzx(result, mem_operand);
+        }
+        __ extsb(result, result);
+        break;
+      case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
+      case EXTERNAL_UINT8_ELEMENTS:
+      case UINT8_ELEMENTS:
+      case UINT8_CLAMPED_ELEMENTS:
+        if (key_is_constant) {
+          __ LoadByte(result, mem_operand, r0);
+        } else {
+          __ lbzx(result, mem_operand);
+        }
+        break;
+      case EXTERNAL_INT16_ELEMENTS:
+      case INT16_ELEMENTS:
+        if (key_is_constant) {
+          __ LoadHalfWord(result, mem_operand, r0);
+        } else {
+          __ lhzx(result, mem_operand);
+        }
+        __ extsh(result, result);
+        break;
+      case EXTERNAL_UINT16_ELEMENTS:
+      case UINT16_ELEMENTS:
+        if (key_is_constant) {
+          __ LoadHalfWord(result, mem_operand, r0);
+        } else {
+          __ lhzx(result, mem_operand);
+        }
+        break;
+      case EXTERNAL_INT32_ELEMENTS:
+      case INT32_ELEMENTS:
+        if (key_is_constant) {
+          __ LoadWord(result, mem_operand, r0);
+        } else {
+          __ lwzx(result, mem_operand);
+        }
+#if V8_TARGET_ARCH_PPC64
+        __ extsw(result, result);
+#endif
+        break;
+      case EXTERNAL_UINT32_ELEMENTS:
+      case UINT32_ELEMENTS:
+        if (key_is_constant) {
+          __ LoadWord(result, mem_operand, r0);
+        } else {
+          __ lwzx(result, mem_operand);
+        }
+        if (!instr->hydrogen()->CheckFlag(HInstruction::kUint32)) {
+          __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000)));
+          __ cmplw(result, r0);
+          DeoptimizeIf(ge, instr, "negative value");
+        }
+        break;
+      case FLOAT32_ELEMENTS:
+      case FLOAT64_ELEMENTS:
+      case EXTERNAL_FLOAT32_ELEMENTS:
+      case EXTERNAL_FLOAT64_ELEMENTS:
+      case FAST_HOLEY_DOUBLE_ELEMENTS:
+      case FAST_HOLEY_ELEMENTS:
+      case FAST_HOLEY_SMI_ELEMENTS:
+      case FAST_DOUBLE_ELEMENTS:
+      case FAST_ELEMENTS:
+      case FAST_SMI_ELEMENTS:
+      case DICTIONARY_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
+        UNREACHABLE();
+        break;
+    }
+  }
+}
+
+
+void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
+  Register elements = ToRegister(instr->elements());
+  bool key_is_constant = instr->key()->IsConstantOperand();
+  Register key = no_reg;
+  DoubleRegister result = ToDoubleRegister(instr->result());
+  Register scratch = scratch0();
+
+  int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
+  bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi();
+  int constant_key = 0;
+  if (key_is_constant) {
+    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+    if (constant_key & 0xF0000000) {
+      Abort(kArrayIndexConstantValueTooBig);
+    }
+  } else {
+    key = ToRegister(instr->key());
+  }
+
+  int base_offset = instr->base_offset() + constant_key * kDoubleSize;
+  if (!key_is_constant) {
+    __ IndexToArrayOffset(r0, key, element_size_shift, key_is_smi);
+    __ add(scratch, elements, r0);
+    elements = scratch;
+  }
+  if (!is_int16(base_offset)) {
+    __ Add(scratch, elements, base_offset, r0);
+    base_offset = 0;
+    elements = scratch;
+  }
+  __ lfd(result, MemOperand(elements, base_offset));
+
+  if (instr->hydrogen()->RequiresHoleCheck()) {
+    if (is_int16(base_offset + Register::kExponentOffset)) {
+      __ lwz(scratch,
+             MemOperand(elements, base_offset + Register::kExponentOffset));
+    } else {
+      __ addi(scratch, elements, Operand(base_offset));
+      __ lwz(scratch, MemOperand(scratch, Register::kExponentOffset));
+    }
+    __ Cmpi(scratch, Operand(kHoleNanUpper32), r0);
+    DeoptimizeIf(eq, instr, "hole");
+  }
+}
+
+
+void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
+  HLoadKeyed* hinstr = instr->hydrogen();
+  Register elements = ToRegister(instr->elements());
+  Register result = ToRegister(instr->result());
+  Register scratch = scratch0();
+  Register store_base = scratch;
+  int offset = instr->base_offset();
+
+  if (instr->key()->IsConstantOperand()) {
+    LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
+    offset += ToInteger32(const_operand) * kPointerSize;
+    store_base = elements;
+  } else {
+    Register key = ToRegister(instr->key());
+    // Even though the HLoadKeyed instruction forces the input
+    // representation for the key to be an integer, the input gets replaced
+    // during bound check elimination with the index argument to the bounds
+    // check, which can be tagged, so that case must be handled here, too.
+    if (hinstr->key()->representation().IsSmi()) {
+      __ SmiToPtrArrayOffset(r0, key);
+    } else {
+      __ ShiftLeftImm(r0, key, Operand(kPointerSizeLog2));
+    }
+    __ add(scratch, elements, r0);
+  }
+
+  bool requires_hole_check = hinstr->RequiresHoleCheck();
+  Representation representation = hinstr->representation();
+
+#if V8_TARGET_ARCH_PPC64
+  // 64-bit Smi optimization
+  if (representation.IsInteger32() &&
+      hinstr->elements_kind() == FAST_SMI_ELEMENTS) {
+    DCHECK(!requires_hole_check);
+    // Read int value directly from upper half of the smi.
+    STATIC_ASSERT(kSmiTag == 0);
+    STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
+#if V8_TARGET_LITTLE_ENDIAN
+    offset += kPointerSize / 2;
+#endif
+  }
+#endif
+
+  __ LoadRepresentation(result, MemOperand(store_base, offset), representation,
+                        r0);
+
+  // Check for the hole value.
+  if (requires_hole_check) {
+    if (IsFastSmiElementsKind(hinstr->elements_kind())) {
+      __ TestIfSmi(result, r0);
+      DeoptimizeIf(ne, instr, "not a Smi", cr0);
+    } else {
+      __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
+      __ cmp(result, scratch);
+      DeoptimizeIf(eq, instr, "hole");
+    }
+  }
+}
+
+
+void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
+  if (instr->is_typed_elements()) {
+    DoLoadKeyedExternalArray(instr);
+  } else if (instr->hydrogen()->representation().IsDouble()) {
+    DoLoadKeyedFixedDoubleArray(instr);
+  } else {
+    DoLoadKeyedFixedArray(instr);
+  }
+}
+
+
+MemOperand LCodeGen::PrepareKeyedOperand(Register key, Register base,
+                                         bool key_is_constant, bool key_is_smi,
+                                         int constant_key,
+                                         int element_size_shift,
+                                         int base_offset) {
+  Register scratch = scratch0();
+
+  if (key_is_constant) {
+    return MemOperand(base, (constant_key << element_size_shift) + base_offset);
+  }
+
+  bool needs_shift =
+      (element_size_shift != (key_is_smi ? kSmiTagSize + kSmiShiftSize : 0));
+
+  if (!(base_offset || needs_shift)) {
+    return MemOperand(base, key);
+  }
+
+  if (needs_shift) {
+    __ IndexToArrayOffset(scratch, key, element_size_shift, key_is_smi);
+    key = scratch;
+  }
+
+  if (base_offset) {
+    __ Add(scratch, key, base_offset, r0);
+  }
+
+  return MemOperand(base, scratch);
+}
+
+
+void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->object()).is(LoadDescriptor::ReceiverRegister()));
+  DCHECK(ToRegister(instr->key()).is(LoadDescriptor::NameRegister()));
+
+  if (FLAG_vector_ics) {
+    EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
+  }
+
+  Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
+}
+
+
+void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) {
+  Register scratch = scratch0();
+  Register result = ToRegister(instr->result());
+
+  if (instr->hydrogen()->from_inlined()) {
+    __ subi(result, sp, Operand(2 * kPointerSize));
+  } else {
+    // Check if the calling frame is an arguments adaptor frame.
+    Label done, adapted;
+    __ LoadP(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+    __ LoadP(result,
+             MemOperand(scratch, StandardFrameConstants::kContextOffset));
+    __ CmpSmiLiteral(result, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0);
+
+    // Result is the frame pointer for the frame if not adapted and for the real
+    // frame below the adaptor frame if adapted.
+    __ beq(&adapted);
+    __ mr(result, fp);
+    __ b(&done);
+
+    __ bind(&adapted);
+    __ mr(result, scratch);
+    __ bind(&done);
+  }
+}
+
+
+void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) {
+  Register elem = ToRegister(instr->elements());
+  Register result = ToRegister(instr->result());
+
+  Label done;
+
+  // If no arguments adaptor frame the number of arguments is fixed.
+  __ cmp(fp, elem);
+  __ mov(result, Operand(scope()->num_parameters()));
+  __ beq(&done);
+
+  // Arguments adaptor frame present. Get argument length from there.
+  __ LoadP(result, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+  __ LoadP(result,
+           MemOperand(result, ArgumentsAdaptorFrameConstants::kLengthOffset));
+  __ SmiUntag(result);
+
+  // Argument length is in result register.
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
+  Register receiver = ToRegister(instr->receiver());
+  Register function = ToRegister(instr->function());
+  Register result = ToRegister(instr->result());
+  Register scratch = scratch0();
+
+  // If the receiver is null or undefined, we have to pass the global
+  // object as a receiver to normal functions. Values have to be
+  // passed unchanged to builtins and strict-mode functions.
+  Label global_object, result_in_receiver;
+
+  if (!instr->hydrogen()->known_function()) {
+    // Do not transform the receiver to object for strict mode
+    // functions.
+    __ LoadP(scratch,
+             FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
+    __ lwz(scratch,
+           FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset));
+    __ TestBit(scratch,
+#if V8_TARGET_ARCH_PPC64
+               SharedFunctionInfo::kStrictModeFunction,
+#else
+               SharedFunctionInfo::kStrictModeFunction + kSmiTagSize,
+#endif
+               r0);
+    __ bne(&result_in_receiver, cr0);
+
+    // Do not transform the receiver to object for builtins.
+    __ TestBit(scratch,
+#if V8_TARGET_ARCH_PPC64
+               SharedFunctionInfo::kNative,
+#else
+               SharedFunctionInfo::kNative + kSmiTagSize,
+#endif
+               r0);
+    __ bne(&result_in_receiver, cr0);
+  }
+
+  // Normal function. Replace undefined or null with global receiver.
+  __ LoadRoot(scratch, Heap::kNullValueRootIndex);
+  __ cmp(receiver, scratch);
+  __ beq(&global_object);
+  __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
+  __ cmp(receiver, scratch);
+  __ beq(&global_object);
+
+  // Deoptimize if the receiver is not a JS object.
+  __ TestIfSmi(receiver, r0);
+  DeoptimizeIf(eq, instr, "Smi");
+  __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE);
+  DeoptimizeIf(lt, instr, "not a JavaScript object");
+
+  __ b(&result_in_receiver);
+  __ bind(&global_object);
+  __ LoadP(result, FieldMemOperand(function, JSFunction::kContextOffset));
+  __ LoadP(result, ContextOperand(result, Context::GLOBAL_OBJECT_INDEX));
+  __ LoadP(result, FieldMemOperand(result, GlobalObject::kGlobalProxyOffset));
+  if (result.is(receiver)) {
+    __ bind(&result_in_receiver);
+  } else {
+    Label result_ok;
+    __ b(&result_ok);
+    __ bind(&result_in_receiver);
+    __ mr(result, receiver);
+    __ bind(&result_ok);
+  }
+}
+
+
+void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
+  Register receiver = ToRegister(instr->receiver());
+  Register function = ToRegister(instr->function());
+  Register length = ToRegister(instr->length());
+  Register elements = ToRegister(instr->elements());
+  Register scratch = scratch0();
+  DCHECK(receiver.is(r3));  // Used for parameter count.
+  DCHECK(function.is(r4));  // Required by InvokeFunction.
+  DCHECK(ToRegister(instr->result()).is(r3));
+
+  // Copy the arguments to this function possibly from the
+  // adaptor frame below it.
+  const uint32_t kArgumentsLimit = 1 * KB;
+  __ cmpli(length, Operand(kArgumentsLimit));
+  DeoptimizeIf(gt, instr, "too many arguments");
+
+  // Push the receiver and use the register to keep the original
+  // number of arguments.
+  __ push(receiver);
+  __ mr(receiver, length);
+  // The arguments are at a one pointer size offset from elements.
+  __ addi(elements, elements, Operand(1 * kPointerSize));
+
+  // Loop through the arguments pushing them onto the execution
+  // stack.
+  Label invoke, loop;
+  // length is a small non-negative integer, due to the test above.
+  __ cmpi(length, Operand::Zero());
+  __ beq(&invoke);
+  __ mtctr(length);
+  __ bind(&loop);
+  __ ShiftLeftImm(r0, length, Operand(kPointerSizeLog2));
+  __ LoadPX(scratch, MemOperand(elements, r0));
+  __ push(scratch);
+  __ addi(length, length, Operand(-1));
+  __ bdnz(&loop);
+
+  __ bind(&invoke);
+  DCHECK(instr->HasPointerMap());
+  LPointerMap* pointers = instr->pointer_map();
+  SafepointGenerator safepoint_generator(this, pointers, Safepoint::kLazyDeopt);
+  // The number of arguments is stored in receiver which is r3, as expected
+  // by InvokeFunction.
+  ParameterCount actual(receiver);
+  __ InvokeFunction(function, actual, CALL_FUNCTION, safepoint_generator);
+}
+
+
+void LCodeGen::DoPushArgument(LPushArgument* instr) {
+  LOperand* argument = instr->value();
+  if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) {
+    Abort(kDoPushArgumentNotImplementedForDoubleType);
+  } else {
+    Register argument_reg = EmitLoadRegister(argument, ip);
+    __ push(argument_reg);
+  }
+}
+
+
+void LCodeGen::DoDrop(LDrop* instr) { __ Drop(instr->count()); }
+
+
+void LCodeGen::DoThisFunction(LThisFunction* instr) {
+  Register result = ToRegister(instr->result());
+  __ LoadP(result, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
+}
+
+
+void LCodeGen::DoContext(LContext* instr) {
+  // If there is a non-return use, the context must be moved to a register.
+  Register result = ToRegister(instr->result());
+  if (info()->IsOptimizing()) {
+    __ LoadP(result, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  } else {
+    // If there is no frame, the context must be in cp.
+    DCHECK(result.is(cp));
+  }
+}
+
+
+void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  __ push(cp);  // The context is the first argument.
+  __ Move(scratch0(), instr->hydrogen()->pairs());
+  __ push(scratch0());
+  __ LoadSmiLiteral(scratch0(), Smi::FromInt(instr->hydrogen()->flags()));
+  __ push(scratch0());
+  CallRuntime(Runtime::kDeclareGlobals, 3, instr);
+}
+
+
+void LCodeGen::CallKnownFunction(Handle<JSFunction> function,
+                                 int formal_parameter_count, int arity,
+                                 LInstruction* instr, R4State r4_state) {
+  bool dont_adapt_arguments =
+      formal_parameter_count == SharedFunctionInfo::kDontAdaptArgumentsSentinel;
+  bool can_invoke_directly =
+      dont_adapt_arguments || formal_parameter_count == arity;
+
+  LPointerMap* pointers = instr->pointer_map();
+
+  if (can_invoke_directly) {
+    if (r4_state == R4_UNINITIALIZED) {
+      __ Move(r4, function);
+    }
+
+    // Change context.
+    __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
+
+    // Set r3 to arguments count if adaption is not needed. Assumes that r3
+    // is available to write to at this point.
+    if (dont_adapt_arguments) {
+      __ mov(r3, Operand(arity));
+    }
+
+    bool is_self_call = function.is_identical_to(info()->closure());
+
+    // Invoke function.
+    if (is_self_call) {
+      __ CallSelf();
+    } else {
+      __ LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
+      __ CallJSEntry(ip);
+    }
+
+    // Set up deoptimization.
+    RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
+  } else {
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+    ParameterCount count(arity);
+    ParameterCount expected(formal_parameter_count);
+    __ InvokeFunction(function, expected, count, CALL_FUNCTION, generator);
+  }
+}
+
+
+void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) {
+  DCHECK(instr->context() != NULL);
+  DCHECK(ToRegister(instr->context()).is(cp));
+  Register input = ToRegister(instr->value());
+  Register result = ToRegister(instr->result());
+  Register scratch = scratch0();
+
+  // Deoptimize if not a heap number.
+  __ LoadP(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
+  __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
+  __ cmp(scratch, ip);
+  DeoptimizeIf(ne, instr, "not a heap number");
+
+  Label done;
+  Register exponent = scratch0();
+  scratch = no_reg;
+  __ lwz(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
+  // Check the sign of the argument. If the argument is positive, just
+  // return it.
+  __ cmpwi(exponent, Operand::Zero());
+  // Move the input to the result if necessary.
+  __ Move(result, input);
+  __ bge(&done);
+
+  // Input is negative. Reverse its sign.
+  // Preserve the value of all registers.
+  {
+    PushSafepointRegistersScope scope(this);
+
+    // Registers were saved at the safepoint, so we can use
+    // many scratch registers.
+    Register tmp1 = input.is(r4) ? r3 : r4;
+    Register tmp2 = input.is(r5) ? r3 : r5;
+    Register tmp3 = input.is(r6) ? r3 : r6;
+    Register tmp4 = input.is(r7) ? r3 : r7;
+
+    // exponent: floating point exponent value.
+
+    Label allocated, slow;
+    __ LoadRoot(tmp4, Heap::kHeapNumberMapRootIndex);
+    __ AllocateHeapNumber(tmp1, tmp2, tmp3, tmp4, &slow);
+    __ b(&allocated);
+
+    // Slow case: Call the runtime system to do the number allocation.
+    __ bind(&slow);
+
+    CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr,
+                            instr->context());
+    // Set the pointer to the new heap number in tmp.
+    if (!tmp1.is(r3)) __ mr(tmp1, r3);
+    // Restore input_reg after call to runtime.
+    __ LoadFromSafepointRegisterSlot(input, input);
+    __ lwz(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset));
+
+    __ bind(&allocated);
+    // exponent: floating point exponent value.
+    // tmp1: allocated heap number.
+    STATIC_ASSERT(HeapNumber::kSignMask == 0x80000000u);
+    __ clrlwi(exponent, exponent, Operand(1));  // clear sign bit
+    __ stw(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset));
+    __ lwz(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset));
+    __ stw(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset));
+
+    __ StoreToSafepointRegisterSlot(tmp1, result);
+  }
+
+  __ bind(&done);
+}
+
+
+void LCodeGen::EmitMathAbs(LMathAbs* instr) {
+  Register input = ToRegister(instr->value());
+  Register result = ToRegister(instr->result());
+  Label done;
+  __ cmpi(input, Operand::Zero());
+  __ Move(result, input);
+  __ bge(&done);
+  __ li(r0, Operand::Zero());  // clear xer
+  __ mtxer(r0);
+  __ neg(result, result, SetOE, SetRC);
+  // Deoptimize on overflow.
+  DeoptimizeIf(overflow, instr, "overflow", cr0);
+  __ bind(&done);
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void LCodeGen::EmitInteger32MathAbs(LMathAbs* instr) {
+  Register input = ToRegister(instr->value());
+  Register result = ToRegister(instr->result());
+  Label done;
+  __ cmpwi(input, Operand::Zero());
+  __ Move(result, input);
+  __ bge(&done);
+
+  // Deoptimize on overflow.
+  __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000)));
+  __ cmpw(input, r0);
+  DeoptimizeIf(eq, instr, "overflow");
+
+  __ neg(result, result);
+  __ bind(&done);
+}
+#endif
+
+
+void LCodeGen::DoMathAbs(LMathAbs* instr) {
+  // Class for deferred case.
+  class DeferredMathAbsTaggedHeapNumber FINAL : public LDeferredCode {
+   public:
+    DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
+        : LDeferredCode(codegen), instr_(instr) {}
+    void Generate() OVERRIDE {
+      codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
+    }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
+   private:
+    LMathAbs* instr_;
+  };
+
+  Representation r = instr->hydrogen()->value()->representation();
+  if (r.IsDouble()) {
+    DoubleRegister input = ToDoubleRegister(instr->value());
+    DoubleRegister result = ToDoubleRegister(instr->result());
+    __ fabs(result, input);
+#if V8_TARGET_ARCH_PPC64
+  } else if (r.IsInteger32()) {
+    EmitInteger32MathAbs(instr);
+  } else if (r.IsSmi()) {
+#else
+  } else if (r.IsSmiOrInteger32()) {
+#endif
+    EmitMathAbs(instr);
+  } else {
+    // Representation is tagged.
+    DeferredMathAbsTaggedHeapNumber* deferred =
+        new (zone()) DeferredMathAbsTaggedHeapNumber(this, instr);
+    Register input = ToRegister(instr->value());
+    // Smi check.
+    __ JumpIfNotSmi(input, deferred->entry());
+    // If smi, handle it directly.
+    EmitMathAbs(instr);
+    __ bind(deferred->exit());
+  }
+}
+
+
+void LCodeGen::DoMathFloor(LMathFloor* instr) {
+  DoubleRegister input = ToDoubleRegister(instr->value());
+  Register result = ToRegister(instr->result());
+  Register input_high = scratch0();
+  Register scratch = ip;
+  Label done, exact;
+
+  __ TryInt32Floor(result, input, input_high, scratch, double_scratch0(), &done,
+                   &exact);
+  DeoptimizeIf(al, instr, "lost precision or NaN");
+
+  __ bind(&exact);
+  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    // Test for -0.
+    __ cmpi(result, Operand::Zero());
+    __ bne(&done);
+    __ cmpwi(input_high, Operand::Zero());
+    DeoptimizeIf(lt, instr, "minus zero");
+  }
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoMathRound(LMathRound* instr) {
+  DoubleRegister input = ToDoubleRegister(instr->value());
+  Register result = ToRegister(instr->result());
+  DoubleRegister double_scratch1 = ToDoubleRegister(instr->temp());
+  DoubleRegister input_plus_dot_five = double_scratch1;
+  Register scratch1 = scratch0();
+  Register scratch2 = ip;
+  DoubleRegister dot_five = double_scratch0();
+  Label convert, done;
+
+  __ LoadDoubleLiteral(dot_five, 0.5, r0);
+  __ fabs(double_scratch1, input);
+  __ fcmpu(double_scratch1, dot_five);
+  DeoptimizeIf(unordered, instr, "lost precision or NaN");
+  // If input is in [-0.5, -0], the result is -0.
+  // If input is in [+0, +0.5[, the result is +0.
+  // If the input is +0.5, the result is 1.
+  __ bgt(&convert);  // Out of [-0.5, +0.5].
+  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+#if V8_TARGET_ARCH_PPC64
+    __ MovDoubleToInt64(scratch1, input);
+#else
+    __ MovDoubleHighToInt(scratch1, input);
+#endif
+    __ cmpi(scratch1, Operand::Zero());
+    // [-0.5, -0].
+    DeoptimizeIf(lt, instr, "minus zero");
+  }
+  Label return_zero;
+  __ fcmpu(input, dot_five);
+  __ bne(&return_zero);
+  __ li(result, Operand(1));  // +0.5.
+  __ b(&done);
+  // Remaining cases: [+0, +0.5[ or [-0.5, +0.5[, depending on
+  // flag kBailoutOnMinusZero.
+  __ bind(&return_zero);
+  __ li(result, Operand::Zero());
+  __ b(&done);
+
+  __ bind(&convert);
+  __ fadd(input_plus_dot_five, input, dot_five);
+  // Reuse dot_five (double_scratch0) as we no longer need this value.
+  __ TryInt32Floor(result, input_plus_dot_five, scratch1, scratch2,
+                   double_scratch0(), &done, &done);
+  DeoptimizeIf(al, instr, "lost precision or NaN");
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoMathFround(LMathFround* instr) {
+  DoubleRegister input_reg = ToDoubleRegister(instr->value());
+  DoubleRegister output_reg = ToDoubleRegister(instr->result());
+  __ frsp(output_reg, input_reg);
+}
+
+
+void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
+  DoubleRegister input = ToDoubleRegister(instr->value());
+  DoubleRegister result = ToDoubleRegister(instr->result());
+  __ fsqrt(result, input);
+}
+
+
+void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
+  DoubleRegister input = ToDoubleRegister(instr->value());
+  DoubleRegister result = ToDoubleRegister(instr->result());
+  DoubleRegister temp = double_scratch0();
+
+  // Note that according to ECMA-262 15.8.2.13:
+  // Math.pow(-Infinity, 0.5) == Infinity
+  // Math.sqrt(-Infinity) == NaN
+  Label skip, done;
+
+  __ LoadDoubleLiteral(temp, -V8_INFINITY, scratch0());
+  __ fcmpu(input, temp);
+  __ bne(&skip);
+  __ fneg(result, temp);
+  __ b(&done);
+
+  // Add +0 to convert -0 to +0.
+  __ bind(&skip);
+  __ fadd(result, input, kDoubleRegZero);
+  __ fsqrt(result, result);
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoPower(LPower* instr) {
+  Representation exponent_type = instr->hydrogen()->right()->representation();
+// Having marked this as a call, we can use any registers.
+// Just make sure that the input/output registers are the expected ones.
+#ifdef DEBUG
+  Register tagged_exponent = MathPowTaggedDescriptor::exponent();
+#endif
+  DCHECK(!instr->right()->IsDoubleRegister() ||
+         ToDoubleRegister(instr->right()).is(d2));
+  DCHECK(!instr->right()->IsRegister() ||
+         ToRegister(instr->right()).is(tagged_exponent));
+  DCHECK(ToDoubleRegister(instr->left()).is(d1));
+  DCHECK(ToDoubleRegister(instr->result()).is(d3));
+
+  if (exponent_type.IsSmi()) {
+    MathPowStub stub(isolate(), MathPowStub::TAGGED);
+    __ CallStub(&stub);
+  } else if (exponent_type.IsTagged()) {
+    Label no_deopt;
+    __ JumpIfSmi(r5, &no_deopt);
+    __ LoadP(r10, FieldMemOperand(r5, HeapObject::kMapOffset));
+    __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
+    __ cmp(r10, ip);
+    DeoptimizeIf(ne, instr, "not a heap number");
+    __ bind(&no_deopt);
+    MathPowStub stub(isolate(), MathPowStub::TAGGED);
+    __ CallStub(&stub);
+  } else if (exponent_type.IsInteger32()) {
+    MathPowStub stub(isolate(), MathPowStub::INTEGER);
+    __ CallStub(&stub);
+  } else {
+    DCHECK(exponent_type.IsDouble());
+    MathPowStub stub(isolate(), MathPowStub::DOUBLE);
+    __ CallStub(&stub);
+  }
+}
+
+
+void LCodeGen::DoMathExp(LMathExp* instr) {
+  DoubleRegister input = ToDoubleRegister(instr->value());
+  DoubleRegister result = ToDoubleRegister(instr->result());
+  DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp());
+  DoubleRegister double_scratch2 = double_scratch0();
+  Register temp1 = ToRegister(instr->temp1());
+  Register temp2 = ToRegister(instr->temp2());
+
+  MathExpGenerator::EmitMathExp(masm(), input, result, double_scratch1,
+                                double_scratch2, temp1, temp2, scratch0());
+}
+
+
+void LCodeGen::DoMathLog(LMathLog* instr) {
+  __ PrepareCallCFunction(0, 1, scratch0());
+  __ MovToFloatParameter(ToDoubleRegister(instr->value()));
+  __ CallCFunction(ExternalReference::math_log_double_function(isolate()), 0,
+                   1);
+  __ MovFromFloatResult(ToDoubleRegister(instr->result()));
+}
+
+
+void LCodeGen::DoMathClz32(LMathClz32* instr) {
+  Register input = ToRegister(instr->value());
+  Register result = ToRegister(instr->result());
+  __ cntlzw_(result, input);
+}
+
+
+void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->function()).is(r4));
+  DCHECK(instr->HasPointerMap());
+
+  Handle<JSFunction> known_function = instr->hydrogen()->known_function();
+  if (known_function.is_null()) {
+    LPointerMap* pointers = instr->pointer_map();
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+    ParameterCount count(instr->arity());
+    __ InvokeFunction(r4, count, CALL_FUNCTION, generator);
+  } else {
+    CallKnownFunction(known_function,
+                      instr->hydrogen()->formal_parameter_count(),
+                      instr->arity(), instr, R4_CONTAINS_TARGET);
+  }
+}
+
+
+void LCodeGen::DoTailCallThroughMegamorphicCache(
+    LTailCallThroughMegamorphicCache* instr) {
+  Register receiver = ToRegister(instr->receiver());
+  Register name = ToRegister(instr->name());
+  DCHECK(receiver.is(LoadDescriptor::ReceiverRegister()));
+  DCHECK(name.is(LoadDescriptor::NameRegister()));
+  DCHECK(receiver.is(r4));
+  DCHECK(name.is(r5));
+
+  Register scratch = r6;
+  Register extra = r7;
+  Register extra2 = r8;
+  Register extra3 = r9;
+
+  // Important for the tail-call.
+  bool must_teardown_frame = NeedsEagerFrame();
+
+  // The probe will tail call to a handler if found.
+  isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
+                                         must_teardown_frame, receiver, name,
+                                         scratch, extra, extra2, extra3);
+
+  // Tail call to miss if we ended up here.
+  if (must_teardown_frame) __ LeaveFrame(StackFrame::INTERNAL);
+  LoadIC::GenerateMiss(masm());
+}
+
+
+void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
+  DCHECK(ToRegister(instr->result()).is(r3));
+
+  LPointerMap* pointers = instr->pointer_map();
+  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+
+  if (instr->target()->IsConstantOperand()) {
+    LConstantOperand* target = LConstantOperand::cast(instr->target());
+    Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+    generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
+    __ Call(code, RelocInfo::CODE_TARGET);
+  } else {
+    DCHECK(instr->target()->IsRegister());
+    Register target = ToRegister(instr->target());
+    generator.BeforeCall(__ CallSize(target));
+    __ addi(ip, target, Operand(Code::kHeaderSize - kHeapObjectTag));
+    __ CallJSEntry(ip);
+  }
+  generator.AfterCall();
+}
+
+
+void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
+  DCHECK(ToRegister(instr->function()).is(r4));
+  DCHECK(ToRegister(instr->result()).is(r3));
+
+  if (instr->hydrogen()->pass_argument_count()) {
+    __ mov(r3, Operand(instr->arity()));
+  }
+
+  // Change context.
+  __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
+
+  bool is_self_call = false;
+  if (instr->hydrogen()->function()->IsConstant()) {
+    HConstant* fun_const = HConstant::cast(instr->hydrogen()->function());
+    Handle<JSFunction> jsfun =
+        Handle<JSFunction>::cast(fun_const->handle(isolate()));
+    is_self_call = jsfun.is_identical_to(info()->closure());
+  }
+
+  if (is_self_call) {
+    __ CallSelf();
+  } else {
+    __ LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
+    __ CallJSEntry(ip);
+  }
+
+  RecordSafepointWithLazyDeopt(instr, RECORD_SIMPLE_SAFEPOINT);
+}
+
+
+void LCodeGen::DoCallFunction(LCallFunction* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->function()).is(r4));
+  DCHECK(ToRegister(instr->result()).is(r3));
+
+  int arity = instr->arity();
+  CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}
+
+
+void LCodeGen::DoCallNew(LCallNew* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->constructor()).is(r4));
+  DCHECK(ToRegister(instr->result()).is(r3));
+
+  __ mov(r3, Operand(instr->arity()));
+  // No cell in r5 for construct type feedback in optimized code
+  __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
+  CallConstructStub stub(isolate(), NO_CALL_CONSTRUCTOR_FLAGS);
+  CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
+}
+
+
+void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->constructor()).is(r4));
+  DCHECK(ToRegister(instr->result()).is(r3));
+
+  __ mov(r3, Operand(instr->arity()));
+  __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
+  ElementsKind kind = instr->hydrogen()->elements_kind();
+  AllocationSiteOverrideMode override_mode =
+      (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
+          ? DISABLE_ALLOCATION_SITES
+          : DONT_OVERRIDE;
+
+  if (instr->arity() == 0) {
+    ArrayNoArgumentConstructorStub stub(isolate(), kind, override_mode);
+    CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
+  } else if (instr->arity() == 1) {
+    Label done;
+    if (IsFastPackedElementsKind(kind)) {
+      Label packed_case;
+      // We might need a change here
+      // look at the first argument
+      __ LoadP(r8, MemOperand(sp, 0));
+      __ cmpi(r8, Operand::Zero());
+      __ beq(&packed_case);
+
+      ElementsKind holey_kind = GetHoleyElementsKind(kind);
+      ArraySingleArgumentConstructorStub stub(isolate(), holey_kind,
+                                              override_mode);
+      CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
+      __ b(&done);
+      __ bind(&packed_case);
+    }
+
+    ArraySingleArgumentConstructorStub stub(isolate(), kind, override_mode);
+    CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
+    __ bind(&done);
+  } else {
+    ArrayNArgumentsConstructorStub stub(isolate(), kind, override_mode);
+    CallCode(stub.GetCode(), RelocInfo::CONSTRUCT_CALL, instr);
+  }
+}
+
+
+void LCodeGen::DoCallRuntime(LCallRuntime* instr) {
+  CallRuntime(instr->function(), instr->arity(), instr);
+}
+
+
+void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
+  Register function = ToRegister(instr->function());
+  Register code_object = ToRegister(instr->code_object());
+  __ addi(code_object, code_object,
+          Operand(Code::kHeaderSize - kHeapObjectTag));
+  __ StoreP(code_object,
+            FieldMemOperand(function, JSFunction::kCodeEntryOffset), r0);
+}
+
+
+void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
+  Register result = ToRegister(instr->result());
+  Register base = ToRegister(instr->base_object());
+  if (instr->offset()->IsConstantOperand()) {
+    LConstantOperand* offset = LConstantOperand::cast(instr->offset());
+    __ Add(result, base, ToInteger32(offset), r0);
+  } else {
+    Register offset = ToRegister(instr->offset());
+    __ add(result, base, offset);
+  }
+}
+
+
+void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
+  HStoreNamedField* hinstr = instr->hydrogen();
+  Representation representation = instr->representation();
+
+  Register object = ToRegister(instr->object());
+  Register scratch = scratch0();
+  HObjectAccess access = hinstr->access();
+  int offset = access.offset();
+
+  if (access.IsExternalMemory()) {
+    Register value = ToRegister(instr->value());
+    MemOperand operand = MemOperand(object, offset);
+    __ StoreRepresentation(value, operand, representation, r0);
+    return;
+  }
+
+  __ AssertNotSmi(object);
+
+#if V8_TARGET_ARCH_PPC64
+  DCHECK(!representation.IsSmi() || !instr->value()->IsConstantOperand() ||
+         IsInteger32(LConstantOperand::cast(instr->value())));
+#else
+  DCHECK(!representation.IsSmi() || !instr->value()->IsConstantOperand() ||
+         IsSmi(LConstantOperand::cast(instr->value())));
+#endif
+  if (representation.IsDouble()) {
+    DCHECK(access.IsInobject());
+    DCHECK(!hinstr->has_transition());
+    DCHECK(!hinstr->NeedsWriteBarrier());
+    DoubleRegister value = ToDoubleRegister(instr->value());
+    __ stfd(value, FieldMemOperand(object, offset));
+    return;
+  }
+
+  if (hinstr->has_transition()) {
+    Handle<Map> transition = hinstr->transition_map();
+    AddDeprecationDependency(transition);
+    __ mov(scratch, Operand(transition));
+    __ StoreP(scratch, FieldMemOperand(object, HeapObject::kMapOffset), r0);
+    if (hinstr->NeedsWriteBarrierForMap()) {
+      Register temp = ToRegister(instr->temp());
+      // Update the write barrier for the map field.
+      __ RecordWriteForMap(object, scratch, temp, GetLinkRegisterState(),
+                           kSaveFPRegs);
+    }
+  }
+
+  // Do the store.
+  Register value = ToRegister(instr->value());
+
+#if V8_TARGET_ARCH_PPC64
+  // 64-bit Smi optimization
+  if (representation.IsSmi() &&
+      hinstr->value()->representation().IsInteger32()) {
+    DCHECK(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY);
+    // Store int value directly to upper half of the smi.
+    STATIC_ASSERT(kSmiTag == 0);
+    STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
+#if V8_TARGET_LITTLE_ENDIAN
+    offset += kPointerSize / 2;
+#endif
+    representation = Representation::Integer32();
+  }
+#endif
+
+  if (access.IsInobject()) {
+    MemOperand operand = FieldMemOperand(object, offset);
+    __ StoreRepresentation(value, operand, representation, r0);
+    if (hinstr->NeedsWriteBarrier()) {
+      // Update the write barrier for the object for in-object properties.
+      __ RecordWriteField(
+          object, offset, value, scratch, GetLinkRegisterState(), kSaveFPRegs,
+          EMIT_REMEMBERED_SET, hinstr->SmiCheckForWriteBarrier(),
+          hinstr->PointersToHereCheckForValue());
+    }
+  } else {
+    __ LoadP(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset));
+    MemOperand operand = FieldMemOperand(scratch, offset);
+    __ StoreRepresentation(value, operand, representation, r0);
+    if (hinstr->NeedsWriteBarrier()) {
+      // Update the write barrier for the properties array.
+      // object is used as a scratch register.
+      __ RecordWriteField(
+          scratch, offset, value, object, GetLinkRegisterState(), kSaveFPRegs,
+          EMIT_REMEMBERED_SET, hinstr->SmiCheckForWriteBarrier(),
+          hinstr->PointersToHereCheckForValue());
+    }
+  }
+}
+
+
+void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister()));
+  DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister()));
+
+  __ mov(StoreDescriptor::NameRegister(), Operand(instr->name()));
+  Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
+}
+
+
+void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
+  Representation representation = instr->hydrogen()->length()->representation();
+  DCHECK(representation.Equals(instr->hydrogen()->index()->representation()));
+  DCHECK(representation.IsSmiOrInteger32());
+
+  Condition cc = instr->hydrogen()->allow_equality() ? lt : le;
+  if (instr->length()->IsConstantOperand()) {
+    int32_t length = ToInteger32(LConstantOperand::cast(instr->length()));
+    Register index = ToRegister(instr->index());
+    if (representation.IsSmi()) {
+      __ Cmpli(index, Operand(Smi::FromInt(length)), r0);
+    } else {
+      __ Cmplwi(index, Operand(length), r0);
+    }
+    cc = CommuteCondition(cc);
+  } else if (instr->index()->IsConstantOperand()) {
+    int32_t index = ToInteger32(LConstantOperand::cast(instr->index()));
+    Register length = ToRegister(instr->length());
+    if (representation.IsSmi()) {
+      __ Cmpli(length, Operand(Smi::FromInt(index)), r0);
+    } else {
+      __ Cmplwi(length, Operand(index), r0);
+    }
+  } else {
+    Register index = ToRegister(instr->index());
+    Register length = ToRegister(instr->length());
+    if (representation.IsSmi()) {
+      __ cmpl(length, index);
+    } else {
+      __ cmplw(length, index);
+    }
+  }
+  if (FLAG_debug_code && instr->hydrogen()->skip_check()) {
+    Label done;
+    __ b(NegateCondition(cc), &done);
+    __ stop("eliminated bounds check failed");
+    __ bind(&done);
+  } else {
+    DeoptimizeIf(cc, instr, "out of bounds");
+  }
+}
+
+
+void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
+  Register external_pointer = ToRegister(instr->elements());
+  Register key = no_reg;
+  ElementsKind elements_kind = instr->elements_kind();
+  bool key_is_constant = instr->key()->IsConstantOperand();
+  int constant_key = 0;
+  if (key_is_constant) {
+    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+    if (constant_key & 0xF0000000) {
+      Abort(kArrayIndexConstantValueTooBig);
+    }
+  } else {
+    key = ToRegister(instr->key());
+  }
+  int element_size_shift = ElementsKindToShiftSize(elements_kind);
+  bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi();
+  int base_offset = instr->base_offset();
+
+  if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
+      elements_kind == FLOAT32_ELEMENTS ||
+      elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
+      elements_kind == FLOAT64_ELEMENTS) {
+    Register address = scratch0();
+    DoubleRegister value(ToDoubleRegister(instr->value()));
+    if (key_is_constant) {
+      if (constant_key != 0) {
+        __ Add(address, external_pointer, constant_key << element_size_shift,
+               r0);
+      } else {
+        address = external_pointer;
+      }
+    } else {
+      __ IndexToArrayOffset(r0, key, element_size_shift, key_is_smi);
+      __ add(address, external_pointer, r0);
+    }
+    if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
+        elements_kind == FLOAT32_ELEMENTS) {
+      __ frsp(double_scratch0(), value);
+      __ stfs(double_scratch0(), MemOperand(address, base_offset));
+    } else {  // Storing doubles, not floats.
+      __ stfd(value, MemOperand(address, base_offset));
+    }
+  } else {
+    Register value(ToRegister(instr->value()));
+    MemOperand mem_operand =
+        PrepareKeyedOperand(key, external_pointer, key_is_constant, key_is_smi,
+                            constant_key, element_size_shift, base_offset);
+    switch (elements_kind) {
+      case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
+      case EXTERNAL_INT8_ELEMENTS:
+      case EXTERNAL_UINT8_ELEMENTS:
+      case UINT8_ELEMENTS:
+      case UINT8_CLAMPED_ELEMENTS:
+      case INT8_ELEMENTS:
+        if (key_is_constant) {
+          __ StoreByte(value, mem_operand, r0);
+        } else {
+          __ stbx(value, mem_operand);
+        }
+        break;
+      case EXTERNAL_INT16_ELEMENTS:
+      case EXTERNAL_UINT16_ELEMENTS:
+      case INT16_ELEMENTS:
+      case UINT16_ELEMENTS:
+        if (key_is_constant) {
+          __ StoreHalfWord(value, mem_operand, r0);
+        } else {
+          __ sthx(value, mem_operand);
+        }
+        break;
+      case EXTERNAL_INT32_ELEMENTS:
+      case EXTERNAL_UINT32_ELEMENTS:
+      case INT32_ELEMENTS:
+      case UINT32_ELEMENTS:
+        if (key_is_constant) {
+          __ StoreWord(value, mem_operand, r0);
+        } else {
+          __ stwx(value, mem_operand);
+        }
+        break;
+      case FLOAT32_ELEMENTS:
+      case FLOAT64_ELEMENTS:
+      case EXTERNAL_FLOAT32_ELEMENTS:
+      case EXTERNAL_FLOAT64_ELEMENTS:
+      case FAST_DOUBLE_ELEMENTS:
+      case FAST_ELEMENTS:
+      case FAST_SMI_ELEMENTS:
+      case FAST_HOLEY_DOUBLE_ELEMENTS:
+      case FAST_HOLEY_ELEMENTS:
+      case FAST_HOLEY_SMI_ELEMENTS:
+      case DICTIONARY_ELEMENTS:
+      case SLOPPY_ARGUMENTS_ELEMENTS:
+        UNREACHABLE();
+        break;
+    }
+  }
+}
+
+
+void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
+  DoubleRegister value = ToDoubleRegister(instr->value());
+  Register elements = ToRegister(instr->elements());
+  Register key = no_reg;
+  Register scratch = scratch0();
+  DoubleRegister double_scratch = double_scratch0();
+  bool key_is_constant = instr->key()->IsConstantOperand();
+  int constant_key = 0;
+
+  // Calculate the effective address of the slot in the array to store the
+  // double value.
+  if (key_is_constant) {
+    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+    if (constant_key & 0xF0000000) {
+      Abort(kArrayIndexConstantValueTooBig);
+    }
+  } else {
+    key = ToRegister(instr->key());
+  }
+  int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
+  bool key_is_smi = instr->hydrogen()->key()->representation().IsSmi();
+  int base_offset = instr->base_offset() + constant_key * kDoubleSize;
+  if (!key_is_constant) {
+    __ IndexToArrayOffset(scratch, key, element_size_shift, key_is_smi);
+    __ add(scratch, elements, scratch);
+    elements = scratch;
+  }
+  if (!is_int16(base_offset)) {
+    __ Add(scratch, elements, base_offset, r0);
+    base_offset = 0;
+    elements = scratch;
+  }
+
+  if (instr->NeedsCanonicalization()) {
+    // Force a canonical NaN.
+    __ CanonicalizeNaN(double_scratch, value);
+    __ stfd(double_scratch, MemOperand(elements, base_offset));
+  } else {
+    __ stfd(value, MemOperand(elements, base_offset));
+  }
+}
+
+
+void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
+  HStoreKeyed* hinstr = instr->hydrogen();
+  Register value = ToRegister(instr->value());
+  Register elements = ToRegister(instr->elements());
+  Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
+  Register scratch = scratch0();
+  Register store_base = scratch;
+  int offset = instr->base_offset();
+
+  // Do the store.
+  if (instr->key()->IsConstantOperand()) {
+    DCHECK(!hinstr->NeedsWriteBarrier());
+    LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
+    offset += ToInteger32(const_operand) * kPointerSize;
+    store_base = elements;
+  } else {
+    // Even though the HLoadKeyed instruction forces the input
+    // representation for the key to be an integer, the input gets replaced
+    // during bound check elimination with the index argument to the bounds
+    // check, which can be tagged, so that case must be handled here, too.
+    if (hinstr->key()->representation().IsSmi()) {
+      __ SmiToPtrArrayOffset(scratch, key);
+    } else {
+      __ ShiftLeftImm(scratch, key, Operand(kPointerSizeLog2));
+    }
+    __ add(scratch, elements, scratch);
+  }
+
+  Representation representation = hinstr->value()->representation();
+
+#if V8_TARGET_ARCH_PPC64
+  // 64-bit Smi optimization
+  if (representation.IsInteger32()) {
+    DCHECK(hinstr->store_mode() == STORE_TO_INITIALIZED_ENTRY);
+    DCHECK(hinstr->elements_kind() == FAST_SMI_ELEMENTS);
+    // Store int value directly to upper half of the smi.
+    STATIC_ASSERT(kSmiTag == 0);
+    STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
+#if V8_TARGET_LITTLE_ENDIAN
+    offset += kPointerSize / 2;
+#endif
+  }
+#endif
+
+  __ StoreRepresentation(value, MemOperand(store_base, offset), representation,
+                         r0);
+
+  if (hinstr->NeedsWriteBarrier()) {
+    SmiCheck check_needed = hinstr->value()->type().IsHeapObject()
+                                ? OMIT_SMI_CHECK
+                                : INLINE_SMI_CHECK;
+    // Compute address of modified element and store it into key register.
+    __ Add(key, store_base, offset, r0);
+    __ RecordWrite(elements, key, value, GetLinkRegisterState(), kSaveFPRegs,
+                   EMIT_REMEMBERED_SET, check_needed,
+                   hinstr->PointersToHereCheckForValue());
+  }
+}
+
+
+void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
+  // By cases: external, fast double
+  if (instr->is_typed_elements()) {
+    DoStoreKeyedExternalArray(instr);
+  } else if (instr->hydrogen()->value()->representation().IsDouble()) {
+    DoStoreKeyedFixedDoubleArray(instr);
+  } else {
+    DoStoreKeyedFixedArray(instr);
+  }
+}
+
+
+void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->object()).is(StoreDescriptor::ReceiverRegister()));
+  DCHECK(ToRegister(instr->key()).is(StoreDescriptor::NameRegister()));
+  DCHECK(ToRegister(instr->value()).is(StoreDescriptor::ValueRegister()));
+
+  Handle<Code> ic =
+      CodeFactory::KeyedStoreIC(isolate(), instr->strict_mode()).code();
+  CallCode(ic, RelocInfo::CODE_TARGET, instr);
+}
+
+
+void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
+  Register object_reg = ToRegister(instr->object());
+  Register scratch = scratch0();
+
+  Handle<Map> from_map = instr->original_map();
+  Handle<Map> to_map = instr->transitioned_map();
+  ElementsKind from_kind = instr->from_kind();
+  ElementsKind to_kind = instr->to_kind();
+
+  Label not_applicable;
+  __ LoadP(scratch, FieldMemOperand(object_reg, HeapObject::kMapOffset));
+  __ Cmpi(scratch, Operand(from_map), r0);
+  __ bne(&not_applicable);
+
+  if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
+    Register new_map_reg = ToRegister(instr->new_map_temp());
+    __ mov(new_map_reg, Operand(to_map));
+    __ StoreP(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset),
+              r0);
+    // Write barrier.
+    __ RecordWriteForMap(object_reg, new_map_reg, scratch,
+                         GetLinkRegisterState(), kDontSaveFPRegs);
+  } else {
+    DCHECK(ToRegister(instr->context()).is(cp));
+    DCHECK(object_reg.is(r3));
+    PushSafepointRegistersScope scope(this);
+    __ Move(r4, to_map);
+    bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
+    TransitionElementsKindStub stub(isolate(), from_kind, to_kind, is_js_array);
+    __ CallStub(&stub);
+    RecordSafepointWithRegisters(instr->pointer_map(), 0,
+                                 Safepoint::kLazyDeopt);
+  }
+  __ bind(&not_applicable);
+}
+
+
+void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
+  Register object = ToRegister(instr->object());
+  Register temp = ToRegister(instr->temp());
+  Label no_memento_found;
+  __ TestJSArrayForAllocationMemento(object, temp, &no_memento_found);
+  DeoptimizeIf(eq, instr, "memento found");
+  __ bind(&no_memento_found);
+}
+
+
+void LCodeGen::DoStringAdd(LStringAdd* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  DCHECK(ToRegister(instr->left()).is(r4));
+  DCHECK(ToRegister(instr->right()).is(r3));
+  StringAddStub stub(isolate(), instr->hydrogen()->flags(),
+                     instr->hydrogen()->pretenure_flag());
+  CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+}
+
+
+void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) {
+  class DeferredStringCharCodeAt FINAL : public LDeferredCode {
+   public:
+    DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
+        : LDeferredCode(codegen), instr_(instr) {}
+    void Generate() OVERRIDE { codegen()->DoDeferredStringCharCodeAt(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
+   private:
+    LStringCharCodeAt* instr_;
+  };
+
+  DeferredStringCharCodeAt* deferred =
+      new (zone()) DeferredStringCharCodeAt(this, instr);
+
+  StringCharLoadGenerator::Generate(
+      masm(), ToRegister(instr->string()), ToRegister(instr->index()),
+      ToRegister(instr->result()), deferred->entry());
+  __ bind(deferred->exit());
+}
+
+
+void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
+  Register string = ToRegister(instr->string());
+  Register result = ToRegister(instr->result());
+  Register scratch = scratch0();
+
+  // TODO(3095996): Get rid of this. For now, we need to make the
+  // result register contain a valid pointer because it is already
+  // contained in the register pointer map.
+  __ li(result, Operand::Zero());
+
+  PushSafepointRegistersScope scope(this);
+  __ push(string);
+  // Push the index as a smi. This is safe because of the checks in
+  // DoStringCharCodeAt above.
+  if (instr->index()->IsConstantOperand()) {
+    int const_index = ToInteger32(LConstantOperand::cast(instr->index()));
+    __ LoadSmiLiteral(scratch, Smi::FromInt(const_index));
+    __ push(scratch);
+  } else {
+    Register index = ToRegister(instr->index());
+    __ SmiTag(index);
+    __ push(index);
+  }
+  CallRuntimeFromDeferred(Runtime::kStringCharCodeAtRT, 2, instr,
+                          instr->context());
+  __ AssertSmi(r3);
+  __ SmiUntag(r3);
+  __ StoreToSafepointRegisterSlot(r3, result);
+}
+
+
+void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) {
+  class DeferredStringCharFromCode FINAL : public LDeferredCode {
+   public:
+    DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
+        : LDeferredCode(codegen), instr_(instr) {}
+    void Generate() OVERRIDE {
+      codegen()->DoDeferredStringCharFromCode(instr_);
+    }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
+   private:
+    LStringCharFromCode* instr_;
+  };
+
+  DeferredStringCharFromCode* deferred =
+      new (zone()) DeferredStringCharFromCode(this, instr);
+
+  DCHECK(instr->hydrogen()->value()->representation().IsInteger32());
+  Register char_code = ToRegister(instr->char_code());
+  Register result = ToRegister(instr->result());
+  DCHECK(!char_code.is(result));
+
+  __ cmpli(char_code, Operand(String::kMaxOneByteCharCode));
+  __ bgt(deferred->entry());
+  __ LoadRoot(result, Heap::kSingleCharacterStringCacheRootIndex);
+  __ ShiftLeftImm(r0, char_code, Operand(kPointerSizeLog2));
+  __ add(result, result, r0);
+  __ LoadP(result, FieldMemOperand(result, FixedArray::kHeaderSize));
+  __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+  __ cmp(result, ip);
+  __ beq(deferred->entry());
+  __ bind(deferred->exit());
+}
+
+
+void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
+  Register char_code = ToRegister(instr->char_code());
+  Register result = ToRegister(instr->result());
+
+  // TODO(3095996): Get rid of this. For now, we need to make the
+  // result register contain a valid pointer because it is already
+  // contained in the register pointer map.
+  __ li(result, Operand::Zero());
+
+  PushSafepointRegistersScope scope(this);
+  __ SmiTag(char_code);
+  __ push(char_code);
+  CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
+  __ StoreToSafepointRegisterSlot(r3, result);
+}
+
+
+void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
+  LOperand* input = instr->value();
+  DCHECK(input->IsRegister() || input->IsStackSlot());
+  LOperand* output = instr->result();
+  DCHECK(output->IsDoubleRegister());
+  if (input->IsStackSlot()) {
+    Register scratch = scratch0();
+    __ LoadP(scratch, ToMemOperand(input));
+    __ ConvertIntToDouble(scratch, ToDoubleRegister(output));
+  } else {
+    __ ConvertIntToDouble(ToRegister(input), ToDoubleRegister(output));
+  }
+}
+
+
+void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
+  LOperand* input = instr->value();
+  LOperand* output = instr->result();
+  __ ConvertUnsignedIntToDouble(ToRegister(input), ToDoubleRegister(output));
+}
+
+
+void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
+  class DeferredNumberTagI FINAL : public LDeferredCode {
+   public:
+    DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
+        : LDeferredCode(codegen), instr_(instr) {}
+    void Generate() OVERRIDE {
+      codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(),
+                                       instr_->temp2(), SIGNED_INT32);
+    }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
+   private:
+    LNumberTagI* instr_;
+  };
+
+  Register src = ToRegister(instr->value());
+  Register dst = ToRegister(instr->result());
+
+  DeferredNumberTagI* deferred = new (zone()) DeferredNumberTagI(this, instr);
+#if V8_TARGET_ARCH_PPC64
+  __ SmiTag(dst, src);
+#else
+  __ SmiTagCheckOverflow(dst, src, r0);
+  __ BranchOnOverflow(deferred->entry());
+#endif
+  __ bind(deferred->exit());
+}
+
+
+void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
+  class DeferredNumberTagU FINAL : public LDeferredCode {
+   public:
+    DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
+        : LDeferredCode(codegen), instr_(instr) {}
+    void Generate() OVERRIDE {
+      codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(),
+                                       instr_->temp2(), UNSIGNED_INT32);
+    }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
+   private:
+    LNumberTagU* instr_;
+  };
+
+  Register input = ToRegister(instr->value());
+  Register result = ToRegister(instr->result());
+
+  DeferredNumberTagU* deferred = new (zone()) DeferredNumberTagU(this, instr);
+  __ Cmpli(input, Operand(Smi::kMaxValue), r0);
+  __ bgt(deferred->entry());
+  __ SmiTag(result, input);
+  __ bind(deferred->exit());
+}
+
+
+void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr, LOperand* value,
+                                     LOperand* temp1, LOperand* temp2,
+                                     IntegerSignedness signedness) {
+  Label done, slow;
+  Register src = ToRegister(value);
+  Register dst = ToRegister(instr->result());
+  Register tmp1 = scratch0();
+  Register tmp2 = ToRegister(temp1);
+  Register tmp3 = ToRegister(temp2);
+  DoubleRegister dbl_scratch = double_scratch0();
+
+  if (signedness == SIGNED_INT32) {
+    // There was overflow, so bits 30 and 31 of the original integer
+    // disagree. Try to allocate a heap number in new space and store
+    // the value in there. If that fails, call the runtime system.
+    if (dst.is(src)) {
+      __ SmiUntag(src, dst);
+      __ xoris(src, src, Operand(HeapNumber::kSignMask >> 16));
+    }
+    __ ConvertIntToDouble(src, dbl_scratch);
+  } else {
+    __ ConvertUnsignedIntToDouble(src, dbl_scratch);
+  }
+
+  if (FLAG_inline_new) {
+    __ LoadRoot(tmp3, Heap::kHeapNumberMapRootIndex);
+    __ AllocateHeapNumber(dst, tmp1, tmp2, tmp3, &slow);
+    __ b(&done);
+  }
+
+  // Slow case: Call the runtime system to do the number allocation.
+  __ bind(&slow);
+  {
+    // TODO(3095996): Put a valid pointer value in the stack slot where the
+    // result register is stored, as this register is in the pointer map, but
+    // contains an integer value.
+    __ li(dst, Operand::Zero());
+
+    // Preserve the value of all registers.
+    PushSafepointRegistersScope scope(this);
+
+    // NumberTagI and NumberTagD use the context from the frame, rather than
+    // the environment's HContext or HInlinedContext value.
+    // They only call Runtime::kAllocateHeapNumber.
+    // The corresponding HChange instructions are added in a phase that does
+    // not have easy access to the local context.
+    __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+    __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
+    RecordSafepointWithRegisters(instr->pointer_map(), 0,
+                                 Safepoint::kNoLazyDeopt);
+    __ StoreToSafepointRegisterSlot(r3, dst);
+  }
+
+  // Done. Put the value in dbl_scratch into the value of the allocated heap
+  // number.
+  __ bind(&done);
+  __ stfd(dbl_scratch, FieldMemOperand(dst, HeapNumber::kValueOffset));
+}
+
+
+void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
+  class DeferredNumberTagD FINAL : public LDeferredCode {
+   public:
+    DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
+        : LDeferredCode(codegen), instr_(instr) {}
+    void Generate() OVERRIDE { codegen()->DoDeferredNumberTagD(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
+   private:
+    LNumberTagD* instr_;
+  };
+
+  DoubleRegister input_reg = ToDoubleRegister(instr->value());
+  Register scratch = scratch0();
+  Register reg = ToRegister(instr->result());
+  Register temp1 = ToRegister(instr->temp());
+  Register temp2 = ToRegister(instr->temp2());
+
+  DeferredNumberTagD* deferred = new (zone()) DeferredNumberTagD(this, instr);
+  if (FLAG_inline_new) {
+    __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
+    __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry());
+  } else {
+    __ b(deferred->entry());
+  }
+  __ bind(deferred->exit());
+  __ stfd(input_reg, FieldMemOperand(reg, HeapNumber::kValueOffset));
+}
+
+
+void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
+  // TODO(3095996): Get rid of this. For now, we need to make the
+  // result register contain a valid pointer because it is already
+  // contained in the register pointer map.
+  Register reg = ToRegister(instr->result());
+  __ li(reg, Operand::Zero());
+
+  PushSafepointRegistersScope scope(this);
+  // NumberTagI and NumberTagD use the context from the frame, rather than
+  // the environment's HContext or HInlinedContext value.
+  // They only call Runtime::kAllocateHeapNumber.
+  // The corresponding HChange instructions are added in a phase that does
+  // not have easy access to the local context.
+  __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
+  RecordSafepointWithRegisters(instr->pointer_map(), 0,
+                               Safepoint::kNoLazyDeopt);
+  __ StoreToSafepointRegisterSlot(r3, reg);
+}
+
+
+void LCodeGen::DoSmiTag(LSmiTag* instr) {
+  HChange* hchange = instr->hydrogen();
+  Register input = ToRegister(instr->value());
+  Register output = ToRegister(instr->result());
+  if (hchange->CheckFlag(HValue::kCanOverflow) &&
+      hchange->value()->CheckFlag(HValue::kUint32)) {
+    __ TestUnsignedSmiCandidate(input, r0);
+    DeoptimizeIf(ne, instr, "overflow", cr0);
+  }
+#if !V8_TARGET_ARCH_PPC64
+  if (hchange->CheckFlag(HValue::kCanOverflow) &&
+      !hchange->value()->CheckFlag(HValue::kUint32)) {
+    __ SmiTagCheckOverflow(output, input, r0);
+    DeoptimizeIf(lt, instr, "overflow", cr0);
+  } else {
+#endif
+    __ SmiTag(output, input);
+#if !V8_TARGET_ARCH_PPC64
+  }
+#endif
+}
+
+
+void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
+  Register scratch = scratch0();
+  Register input = ToRegister(instr->value());
+  Register result = ToRegister(instr->result());
+  if (instr->needs_check()) {
+    STATIC_ASSERT(kHeapObjectTag == 1);
+    // If the input is a HeapObject, value of scratch won't be zero.
+    __ andi(scratch, input, Operand(kHeapObjectTag));
+    __ SmiUntag(result, input);
+    DeoptimizeIf(ne, instr, "not a Smi", cr0);
+  } else {
+    __ SmiUntag(result, input);
+  }
+}
+
+
+void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg,
+                                DoubleRegister result_reg,
+                                NumberUntagDMode mode) {
+  bool can_convert_undefined_to_nan =
+      instr->hydrogen()->can_convert_undefined_to_nan();
+  bool deoptimize_on_minus_zero = instr->hydrogen()->deoptimize_on_minus_zero();
+
+  Register scratch = scratch0();
+  DCHECK(!result_reg.is(double_scratch0()));
+
+  Label convert, load_smi, done;
+
+  if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
+    // Smi check.
+    __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);
+
+    // Heap number map check.
+    __ LoadP(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
+    __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
+    __ cmp(scratch, ip);
+    if (can_convert_undefined_to_nan) {
+      __ bne(&convert);
+    } else {
+      DeoptimizeIf(ne, instr, "not a heap number");
+    }
+    // load heap number
+    __ lfd(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset));
+    if (deoptimize_on_minus_zero) {
+#if V8_TARGET_ARCH_PPC64
+      __ MovDoubleToInt64(scratch, result_reg);
+      // rotate left by one for simple compare.
+      __ rldicl(scratch, scratch, 1, 0);
+      __ cmpi(scratch, Operand(1));
+#else
+      __ MovDoubleToInt64(scratch, ip, result_reg);
+      __ cmpi(ip, Operand::Zero());
+      __ bne(&done);
+      __ Cmpi(scratch, Operand(HeapNumber::kSignMask), r0);
+#endif
+      DeoptimizeIf(eq, instr, "minus zero");
+    }
+    __ b(&done);
+    if (can_convert_undefined_to_nan) {
+      __ bind(&convert);
+      // Convert undefined (and hole) to NaN.
+      __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+      __ cmp(input_reg, ip);
+      DeoptimizeIf(ne, instr, "not a heap number/undefined");
+      __ LoadRoot(scratch, Heap::kNanValueRootIndex);
+      __ lfd(result_reg, FieldMemOperand(scratch, HeapNumber::kValueOffset));
+      __ b(&done);
+    }
+  } else {
+    __ SmiUntag(scratch, input_reg);
+    DCHECK(mode == NUMBER_CANDIDATE_IS_SMI);
+  }
+  // Smi to double register conversion
+  __ bind(&load_smi);
+  // scratch: untagged value of input_reg
+  __ ConvertIntToDouble(scratch, result_reg);
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
+  Register input_reg = ToRegister(instr->value());
+  Register scratch1 = scratch0();
+  Register scratch2 = ToRegister(instr->temp());
+  DoubleRegister double_scratch = double_scratch0();
+  DoubleRegister double_scratch2 = ToDoubleRegister(instr->temp2());
+
+  DCHECK(!scratch1.is(input_reg) && !scratch1.is(scratch2));
+  DCHECK(!scratch2.is(input_reg) && !scratch2.is(scratch1));
+
+  Label done;
+
+  // Heap number map check.
+  __ LoadP(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset));
+  __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
+  __ cmp(scratch1, ip);
+
+  if (instr->truncating()) {
+    // Performs a truncating conversion of a floating point number as used by
+    // the JS bitwise operations.
+    Label no_heap_number, check_bools, check_false;
+    __ bne(&no_heap_number);
+    __ mr(scratch2, input_reg);
+    __ TruncateHeapNumberToI(input_reg, scratch2);
+    __ b(&done);
+
+    // Check for Oddballs. Undefined/False is converted to zero and True to one
+    // for truncating conversions.
+    __ bind(&no_heap_number);
+    __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+    __ cmp(input_reg, ip);
+    __ bne(&check_bools);
+    __ li(input_reg, Operand::Zero());
+    __ b(&done);
+
+    __ bind(&check_bools);
+    __ LoadRoot(ip, Heap::kTrueValueRootIndex);
+    __ cmp(input_reg, ip);
+    __ bne(&check_false);
+    __ li(input_reg, Operand(1));
+    __ b(&done);
+
+    __ bind(&check_false);
+    __ LoadRoot(ip, Heap::kFalseValueRootIndex);
+    __ cmp(input_reg, ip);
+    DeoptimizeIf(ne, instr, "not a heap number/undefined/true/false", cr7);
+    __ li(input_reg, Operand::Zero());
+  } else {
+    DeoptimizeIf(ne, instr, "not a heap number", cr7);
+
+    __ lfd(double_scratch2,
+           FieldMemOperand(input_reg, HeapNumber::kValueOffset));
+    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+      // preserve heap number pointer in scratch2 for minus zero check below
+      __ mr(scratch2, input_reg);
+    }
+    __ TryDoubleToInt32Exact(input_reg, double_scratch2, scratch1,
+                             double_scratch);
+    DeoptimizeIf(ne, instr, "lost precision or NaN", cr7);
+
+    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+      __ cmpi(input_reg, Operand::Zero());
+      __ bne(&done);
+      __ lwz(scratch1,
+             FieldMemOperand(scratch2, HeapNumber::kValueOffset +
+                                           Register::kExponentOffset));
+      __ cmpwi(scratch1, Operand::Zero());
+      DeoptimizeIf(lt, instr, "minus zero", cr7);
+    }
+  }
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
+  class DeferredTaggedToI FINAL : public LDeferredCode {
+   public:
+    DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
+        : LDeferredCode(codegen), instr_(instr) {}
+    void Generate() OVERRIDE { codegen()->DoDeferredTaggedToI(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
+   private:
+    LTaggedToI* instr_;
+  };
+
+  LOperand* input = instr->value();
+  DCHECK(input->IsRegister());
+  DCHECK(input->Equals(instr->result()));
+
+  Register input_reg = ToRegister(input);
+
+  if (instr->hydrogen()->value()->representation().IsSmi()) {
+    __ SmiUntag(input_reg);
+  } else {
+    DeferredTaggedToI* deferred = new (zone()) DeferredTaggedToI(this, instr);
+
+    // Branch to deferred code if the input is a HeapObject.
+    __ JumpIfNotSmi(input_reg, deferred->entry());
+
+    __ SmiUntag(input_reg);
+    __ bind(deferred->exit());
+  }
+}
+
+
+void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
+  LOperand* input = instr->value();
+  DCHECK(input->IsRegister());
+  LOperand* result = instr->result();
+  DCHECK(result->IsDoubleRegister());
+
+  Register input_reg = ToRegister(input);
+  DoubleRegister result_reg = ToDoubleRegister(result);
+
+  HValue* value = instr->hydrogen()->value();
+  NumberUntagDMode mode = value->representation().IsSmi()
+                              ? NUMBER_CANDIDATE_IS_SMI
+                              : NUMBER_CANDIDATE_IS_ANY_TAGGED;
+
+  EmitNumberUntagD(instr, input_reg, result_reg, mode);
+}
+
+
+void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
+  Register result_reg = ToRegister(instr->result());
+  Register scratch1 = scratch0();
+  DoubleRegister double_input = ToDoubleRegister(instr->value());
+  DoubleRegister double_scratch = double_scratch0();
+
+  if (instr->truncating()) {
+    __ TruncateDoubleToI(result_reg, double_input);
+  } else {
+    __ TryDoubleToInt32Exact(result_reg, double_input, scratch1,
+                             double_scratch);
+    // Deoptimize if the input wasn't a int32 (inside a double).
+    DeoptimizeIf(ne, instr, "lost precision or NaN");
+    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+      Label done;
+      __ cmpi(result_reg, Operand::Zero());
+      __ bne(&done);
+#if V8_TARGET_ARCH_PPC64
+      __ MovDoubleToInt64(scratch1, double_input);
+#else
+      __ MovDoubleHighToInt(scratch1, double_input);
+#endif
+      __ cmpi(scratch1, Operand::Zero());
+      DeoptimizeIf(lt, instr, "minus zero");
+      __ bind(&done);
+    }
+  }
+}
+
+
+void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
+  Register result_reg = ToRegister(instr->result());
+  Register scratch1 = scratch0();
+  DoubleRegister double_input = ToDoubleRegister(instr->value());
+  DoubleRegister double_scratch = double_scratch0();
+
+  if (instr->truncating()) {
+    __ TruncateDoubleToI(result_reg, double_input);
+  } else {
+    __ TryDoubleToInt32Exact(result_reg, double_input, scratch1,
+                             double_scratch);
+    // Deoptimize if the input wasn't a int32 (inside a double).
+    DeoptimizeIf(ne, instr, "lost precision or NaN");
+    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+      Label done;
+      __ cmpi(result_reg, Operand::Zero());
+      __ bne(&done);
+#if V8_TARGET_ARCH_PPC64
+      __ MovDoubleToInt64(scratch1, double_input);
+#else
+      __ MovDoubleHighToInt(scratch1, double_input);
+#endif
+      __ cmpi(scratch1, Operand::Zero());
+      DeoptimizeIf(lt, instr, "minus zero");
+      __ bind(&done);
+    }
+  }
+#if V8_TARGET_ARCH_PPC64
+  __ SmiTag(result_reg);
+#else
+  __ SmiTagCheckOverflow(result_reg, r0);
+  DeoptimizeIf(lt, instr, "overflow", cr0);
+#endif
+}
+
+
+void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
+  LOperand* input = instr->value();
+  __ TestIfSmi(ToRegister(input), r0);
+  DeoptimizeIf(ne, instr, "not a Smi", cr0);
+}
+
+
+void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
+  if (!instr->hydrogen()->value()->type().IsHeapObject()) {
+    LOperand* input = instr->value();
+    __ TestIfSmi(ToRegister(input), r0);
+    DeoptimizeIf(eq, instr, "Smi", cr0);
+  }
+}
+
+
+void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
+  Register input = ToRegister(instr->value());
+  Register scratch = scratch0();
+
+  __ LoadP(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
+  __ lbz(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
+
+  if (instr->hydrogen()->is_interval_check()) {
+    InstanceType first;
+    InstanceType last;
+    instr->hydrogen()->GetCheckInterval(&first, &last);
+
+    __ cmpli(scratch, Operand(first));
+
+    // If there is only one type in the interval check for equality.
+    if (first == last) {
+      DeoptimizeIf(ne, instr, "wrong instance type");
+    } else {
+      DeoptimizeIf(lt, instr, "wrong instance type");
+      // Omit check for the last type.
+      if (last != LAST_TYPE) {
+        __ cmpli(scratch, Operand(last));
+        DeoptimizeIf(gt, instr, "wrong instance type");
+      }
+    }
+  } else {
+    uint8_t mask;
+    uint8_t tag;
+    instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
+
+    if (base::bits::IsPowerOfTwo32(mask)) {
+      DCHECK(tag == 0 || base::bits::IsPowerOfTwo32(tag));
+      __ andi(r0, scratch, Operand(mask));
+      DeoptimizeIf(tag == 0 ? ne : eq, instr, "wrong instance type", cr0);
+    } else {
+      __ andi(scratch, scratch, Operand(mask));
+      __ cmpi(scratch, Operand(tag));
+      DeoptimizeIf(ne, instr, "wrong instance type");
+    }
+  }
+}
+
+
+void LCodeGen::DoCheckValue(LCheckValue* instr) {
+  Register reg = ToRegister(instr->value());
+  Handle<HeapObject> object = instr->hydrogen()->object().handle();
+  AllowDeferredHandleDereference smi_check;
+  if (isolate()->heap()->InNewSpace(*object)) {
+    Register reg = ToRegister(instr->value());
+    Handle<Cell> cell = isolate()->factory()->NewCell(object);
+    __ mov(ip, Operand(Handle<Object>(cell)));
+    __ LoadP(ip, FieldMemOperand(ip, Cell::kValueOffset));
+    __ cmp(reg, ip);
+  } else {
+    __ Cmpi(reg, Operand(object), r0);
+  }
+  DeoptimizeIf(ne, instr, "value mismatch");
+}
+
+
+void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
+  {
+    PushSafepointRegistersScope scope(this);
+    __ push(object);
+    __ li(cp, Operand::Zero());
+    __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance);
+    RecordSafepointWithRegisters(instr->pointer_map(), 1,
+                                 Safepoint::kNoLazyDeopt);
+    __ StoreToSafepointRegisterSlot(r3, scratch0());
+  }
+  __ TestIfSmi(scratch0(), r0);
+  DeoptimizeIf(eq, instr, "instance migration failed", cr0);
+}
+
+
+void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
+  class DeferredCheckMaps FINAL : public LDeferredCode {
+   public:
+    DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
+        : LDeferredCode(codegen), instr_(instr), object_(object) {
+      SetExit(check_maps());
+    }
+    void Generate() OVERRIDE {
+      codegen()->DoDeferredInstanceMigration(instr_, object_);
+    }
+    Label* check_maps() { return &check_maps_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
+   private:
+    LCheckMaps* instr_;
+    Label check_maps_;
+    Register object_;
+  };
+
+  if (instr->hydrogen()->IsStabilityCheck()) {
+    const UniqueSet<Map>* maps = instr->hydrogen()->maps();
+    for (int i = 0; i < maps->size(); ++i) {
+      AddStabilityDependency(maps->at(i).handle());
+    }
+    return;
+  }
+
+  Register map_reg = scratch0();
+
+  LOperand* input = instr->value();
+  DCHECK(input->IsRegister());
+  Register reg = ToRegister(input);
+
+  __ LoadP(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
+
+  DeferredCheckMaps* deferred = NULL;
+  if (instr->hydrogen()->HasMigrationTarget()) {
+    deferred = new (zone()) DeferredCheckMaps(this, instr, reg);
+    __ bind(deferred->check_maps());
+  }
+
+  const UniqueSet<Map>* maps = instr->hydrogen()->maps();
+  Label success;
+  for (int i = 0; i < maps->size() - 1; i++) {
+    Handle<Map> map = maps->at(i).handle();
+    __ CompareMap(map_reg, map, &success);
+    __ beq(&success);
+  }
+
+  Handle<Map> map = maps->at(maps->size() - 1).handle();
+  __ CompareMap(map_reg, map, &success);
+  if (instr->hydrogen()->HasMigrationTarget()) {
+    __ bne(deferred->entry());
+  } else {
+    DeoptimizeIf(ne, instr, "wrong map");
+  }
+
+  __ bind(&success);
+}
+
+
+void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
+  DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
+  Register result_reg = ToRegister(instr->result());
+  __ ClampDoubleToUint8(result_reg, value_reg, double_scratch0());
+}
+
+
+void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
+  Register unclamped_reg = ToRegister(instr->unclamped());
+  Register result_reg = ToRegister(instr->result());
+  __ ClampUint8(result_reg, unclamped_reg);
+}
+
+
+void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
+  Register scratch = scratch0();
+  Register input_reg = ToRegister(instr->unclamped());
+  Register result_reg = ToRegister(instr->result());
+  DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
+  Label is_smi, done, heap_number;
+
+  // Both smi and heap number cases are handled.
+  __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi);
+
+  // Check for heap number
+  __ LoadP(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
+  __ Cmpi(scratch, Operand(factory()->heap_number_map()), r0);
+  __ beq(&heap_number);
+
+  // Check for undefined. Undefined is converted to zero for clamping
+  // conversions.
+  __ Cmpi(input_reg, Operand(factory()->undefined_value()), r0);
+  DeoptimizeIf(ne, instr, "not a heap number/undefined");
+  __ li(result_reg, Operand::Zero());
+  __ b(&done);
+
+  // Heap number
+  __ bind(&heap_number);
+  __ lfd(temp_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset));
+  __ ClampDoubleToUint8(result_reg, temp_reg, double_scratch0());
+  __ b(&done);
+
+  // smi
+  __ bind(&is_smi);
+  __ ClampUint8(result_reg, result_reg);
+
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoDoubleBits(LDoubleBits* instr) {
+  DoubleRegister value_reg = ToDoubleRegister(instr->value());
+  Register result_reg = ToRegister(instr->result());
+
+  if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
+    __ MovDoubleHighToInt(result_reg, value_reg);
+  } else {
+    __ MovDoubleLowToInt(result_reg, value_reg);
+  }
+}
+
+
+void LCodeGen::DoConstructDouble(LConstructDouble* instr) {
+  Register hi_reg = ToRegister(instr->hi());
+  Register lo_reg = ToRegister(instr->lo());
+  DoubleRegister result_reg = ToDoubleRegister(instr->result());
+#if V8_TARGET_ARCH_PPC64
+  __ MovInt64ComponentsToDouble(result_reg, hi_reg, lo_reg, r0);
+#else
+  __ MovInt64ToDouble(result_reg, hi_reg, lo_reg);
+#endif
+}
+
+
+void LCodeGen::DoAllocate(LAllocate* instr) {
+  class DeferredAllocate FINAL : public LDeferredCode {
+   public:
+    DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
+        : LDeferredCode(codegen), instr_(instr) {}
+    void Generate() OVERRIDE { codegen()->DoDeferredAllocate(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
+   private:
+    LAllocate* instr_;
+  };
+
+  DeferredAllocate* deferred = new (zone()) DeferredAllocate(this, instr);
+
+  Register result = ToRegister(instr->result());
+  Register scratch = ToRegister(instr->temp1());
+  Register scratch2 = ToRegister(instr->temp2());
+
+  // Allocate memory for the object.
+  AllocationFlags flags = TAG_OBJECT;
+  if (instr->hydrogen()->MustAllocateDoubleAligned()) {
+    flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT);
+  }
+  if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
+    DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation());
+    DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
+    flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE);
+  } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
+    DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
+    flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE);
+  }
+
+  if (instr->size()->IsConstantOperand()) {
+    int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
+    if (size <= Page::kMaxRegularHeapObjectSize) {
+      __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
+    } else {
+      __ b(deferred->entry());
+    }
+  } else {
+    Register size = ToRegister(instr->size());
+    __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags);
+  }
+
+  __ bind(deferred->exit());
+
+  if (instr->hydrogen()->MustPrefillWithFiller()) {
+    STATIC_ASSERT(kHeapObjectTag == 1);
+    if (instr->size()->IsConstantOperand()) {
+      int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
+      __ LoadIntLiteral(scratch, size - kHeapObjectTag);
+    } else {
+      __ subi(scratch, ToRegister(instr->size()), Operand(kHeapObjectTag));
+    }
+    __ mov(scratch2, Operand(isolate()->factory()->one_pointer_filler_map()));
+    Label loop;
+    __ bind(&loop);
+    __ subi(scratch, scratch, Operand(kPointerSize));
+    __ StorePX(scratch2, MemOperand(result, scratch));
+    __ cmpi(scratch, Operand::Zero());
+    __ bge(&loop);
+  }
+}
+
+
+void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
+  Register result = ToRegister(instr->result());
+
+  // TODO(3095996): Get rid of this. For now, we need to make the
+  // result register contain a valid pointer because it is already
+  // contained in the register pointer map.
+  __ LoadSmiLiteral(result, Smi::FromInt(0));
+
+  PushSafepointRegistersScope scope(this);
+  if (instr->size()->IsRegister()) {
+    Register size = ToRegister(instr->size());
+    DCHECK(!size.is(result));
+    __ SmiTag(size);
+    __ push(size);
+  } else {
+    int32_t size = ToInteger32(LConstantOperand::cast(instr->size()));
+#if !V8_TARGET_ARCH_PPC64
+    if (size >= 0 && size <= Smi::kMaxValue) {
+#endif
+      __ Push(Smi::FromInt(size));
+#if !V8_TARGET_ARCH_PPC64
+    } else {
+      // We should never get here at runtime => abort
+      __ stop("invalid allocation size");
+      return;
+    }
+#endif
+  }
+
+  int flags = AllocateDoubleAlignFlag::encode(
+      instr->hydrogen()->MustAllocateDoubleAligned());
+  if (instr->hydrogen()->IsOldPointerSpaceAllocation()) {
+    DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation());
+    DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
+    flags = AllocateTargetSpace::update(flags, OLD_POINTER_SPACE);
+  } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
+    DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
+    flags = AllocateTargetSpace::update(flags, OLD_DATA_SPACE);
+  } else {
+    flags = AllocateTargetSpace::update(flags, NEW_SPACE);
+  }
+  __ Push(Smi::FromInt(flags));
+
+  CallRuntimeFromDeferred(Runtime::kAllocateInTargetSpace, 2, instr,
+                          instr->context());
+  __ StoreToSafepointRegisterSlot(r3, result);
+}
+
+
+void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
+  DCHECK(ToRegister(instr->value()).is(r3));
+  __ push(r3);
+  CallRuntime(Runtime::kToFastProperties, 1, instr);
+}
+
+
+void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  Label materialized;
+  // Registers will be used as follows:
+  // r10 = literals array.
+  // r4 = regexp literal.
+  // r3 = regexp literal clone.
+  // r5 and r7-r9 are used as temporaries.
+  int literal_offset =
+      FixedArray::OffsetOfElementAt(instr->hydrogen()->literal_index());
+  __ Move(r10, instr->hydrogen()->literals());
+  __ LoadP(r4, FieldMemOperand(r10, literal_offset));
+  __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+  __ cmp(r4, ip);
+  __ bne(&materialized);
+
+  // Create regexp literal using runtime function
+  // Result will be in r3.
+  __ LoadSmiLiteral(r9, Smi::FromInt(instr->hydrogen()->literal_index()));
+  __ mov(r8, Operand(instr->hydrogen()->pattern()));
+  __ mov(r7, Operand(instr->hydrogen()->flags()));
+  __ Push(r10, r9, r8, r7);
+  CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
+  __ mr(r4, r3);
+
+  __ bind(&materialized);
+  int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
+  Label allocated, runtime_allocate;
+
+  __ Allocate(size, r3, r5, r6, &runtime_allocate, TAG_OBJECT);
+  __ b(&allocated);
+
+  __ bind(&runtime_allocate);
+  __ LoadSmiLiteral(r3, Smi::FromInt(size));
+  __ Push(r4, r3);
+  CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
+  __ pop(r4);
+
+  __ bind(&allocated);
+  // Copy the content into the newly allocated memory.
+  __ CopyFields(r3, r4, r5.bit(), size / kPointerSize);
+}
+
+
+void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
+  DCHECK(ToRegister(instr->context()).is(cp));
+  // Use the fast case closure allocation code that allocates in new
+  // space for nested functions that don't need literals cloning.
+  bool pretenure = instr->hydrogen()->pretenure();
+  if (!pretenure && instr->hydrogen()->has_no_literals()) {
+    FastNewClosureStub stub(isolate(), instr->hydrogen()->strict_mode(),
+                            instr->hydrogen()->kind());
+    __ mov(r5, Operand(instr->hydrogen()->shared_info()));
+    CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
+  } else {
+    __ mov(r5, Operand(instr->hydrogen()->shared_info()));
+    __ mov(r4, Operand(pretenure ? factory()->true_value()
+                                 : factory()->false_value()));
+    __ Push(cp, r5, r4);
+    CallRuntime(Runtime::kNewClosure, 3, instr);
+  }
+}
+
+
+void LCodeGen::DoTypeof(LTypeof* instr) {
+  Register input = ToRegister(instr->value());
+  __ push(input);
+  CallRuntime(Runtime::kTypeof, 1, instr);
+}
+
+
+void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
+  Register input = ToRegister(instr->value());
+
+  Condition final_branch_condition =
+      EmitTypeofIs(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), input,
+                   instr->type_literal());
+  if (final_branch_condition != kNoCondition) {
+    EmitBranch(instr, final_branch_condition);
+  }
+}
+
+
+Condition LCodeGen::EmitTypeofIs(Label* true_label, Label* false_label,
+                                 Register input, Handle<String> type_name) {
+  Condition final_branch_condition = kNoCondition;
+  Register scratch = scratch0();
+  Factory* factory = isolate()->factory();
+  if (String::Equals(type_name, factory->number_string())) {
+    __ JumpIfSmi(input, true_label);
+    __ LoadP(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
+    __ CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
+    final_branch_condition = eq;
+
+  } else if (String::Equals(type_name, factory->string_string())) {
+    __ JumpIfSmi(input, false_label);
+    __ CompareObjectType(input, scratch, no_reg, FIRST_NONSTRING_TYPE);
+    __ bge(false_label);
+    __ lbz(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
+    __ ExtractBit(r0, scratch, Map::kIsUndetectable);
+    __ cmpi(r0, Operand::Zero());
+    final_branch_condition = eq;
+
+  } else if (String::Equals(type_name, factory->symbol_string())) {
+    __ JumpIfSmi(input, false_label);
+    __ CompareObjectType(input, scratch, no_reg, SYMBOL_TYPE);
+    final_branch_condition = eq;
+
+  } else if (String::Equals(type_name, factory->boolean_string())) {
+    __ CompareRoot(input, Heap::kTrueValueRootIndex);
+    __ beq(true_label);
+    __ CompareRoot(input, Heap::kFalseValueRootIndex);
+    final_branch_condition = eq;
+
+  } else if (String::Equals(type_name, factory->undefined_string())) {
+    __ CompareRoot(input, Heap::kUndefinedValueRootIndex);
+    __ beq(true_label);
+    __ JumpIfSmi(input, false_label);
+    // Check for undetectable objects => true.
+    __ LoadP(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
+    __ lbz(scratch, FieldMemOperand(scratch, Map::kBitFieldOffset));
+    __ ExtractBit(r0, scratch, Map::kIsUndetectable);
+    __ cmpi(r0, Operand::Zero());
+    final_branch_condition = ne;
+
+  } else if (String::Equals(type_name, factory->function_string())) {
+    STATIC_ASSERT(NUM_OF_CALLABLE_SPEC_OBJECT_TYPES == 2);
+    Register type_reg = scratch;
+    __ JumpIfSmi(input, false_label);
+    __ CompareObjectType(input, scratch, type_reg, JS_FUNCTION_TYPE);
+    __ beq(true_label);
+    __ cmpi(type_reg, Operand(JS_FUNCTION_PROXY_TYPE));
+    final_branch_condition = eq;
+
+  } else if (String::Equals(type_name, factory->object_string())) {
+    Register map = scratch;
+    __ JumpIfSmi(input, false_label);
+    __ CompareRoot(input, Heap::kNullValueRootIndex);
+    __ beq(true_label);
+    __ CheckObjectTypeRange(input, map, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE,
+                            LAST_NONCALLABLE_SPEC_OBJECT_TYPE, false_label);
+    // Check for undetectable objects => false.
+    __ lbz(scratch, FieldMemOperand(map, Map::kBitFieldOffset));
+    __ ExtractBit(r0, scratch, Map::kIsUndetectable);
+    __ cmpi(r0, Operand::Zero());
+    final_branch_condition = eq;
+
+  } else {
+    __ b(false_label);
+  }
+
+  return final_branch_condition;
+}
+
+
+void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
+  Register temp1 = ToRegister(instr->temp());
+
+  EmitIsConstructCall(temp1, scratch0());
+  EmitBranch(instr, eq);
+}
+
+
+void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) {
+  DCHECK(!temp1.is(temp2));
+  // Get the frame pointer for the calling frame.
+  __ LoadP(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+
+  // Skip the arguments adaptor frame if it exists.
+  Label check_frame_marker;
+  __ LoadP(temp2, MemOperand(temp1, StandardFrameConstants::kContextOffset));
+  __ CmpSmiLiteral(temp2, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0);
+  __ bne(&check_frame_marker);
+  __ LoadP(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset));
+
+  // Check the marker in the calling frame.
+  __ bind(&check_frame_marker);
+  __ LoadP(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset));
+  __ CmpSmiLiteral(temp1, Smi::FromInt(StackFrame::CONSTRUCT), r0);
+}
+
+
+void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
+  if (!info()->IsStub()) {
+    // Ensure that we have enough space after the previous lazy-bailout
+    // instruction for patching the code here.
+    int current_pc = masm()->pc_offset();
+    if (current_pc < last_lazy_deopt_pc_ + space_needed) {
+      int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc;
+      DCHECK_EQ(0, padding_size % Assembler::kInstrSize);
+      while (padding_size > 0) {
+        __ nop();
+        padding_size -= Assembler::kInstrSize;
+      }
+    }
+  }
+  last_lazy_deopt_pc_ = masm()->pc_offset();
+}
+
+
+void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
+  last_lazy_deopt_pc_ = masm()->pc_offset();
+  DCHECK(instr->HasEnvironment());
+  LEnvironment* env = instr->environment();
+  RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
+  safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
+}
+
+
+void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
+  Deoptimizer::BailoutType type = instr->hydrogen()->type();
+  // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
+  // needed return address), even though the implementation of LAZY and EAGER is
+  // now identical. When LAZY is eventually completely folded into EAGER, remove
+  // the special case below.
+  if (info()->IsStub() && type == Deoptimizer::EAGER) {
+    type = Deoptimizer::LAZY;
+  }
+
+  DeoptimizeIf(al, instr, instr->hydrogen()->reason(), type);
+}
+
+
+void LCodeGen::DoDummy(LDummy* instr) {
+  // Nothing to see here, move on!
+}
+
+
+void LCodeGen::DoDummyUse(LDummyUse* instr) {
+  // Nothing to see here, move on!
+}
+
+
+void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) {
+  PushSafepointRegistersScope scope(this);
+  LoadContextFromDeferred(instr->context());
+  __ CallRuntimeSaveDoubles(Runtime::kStackGuard);
+  RecordSafepointWithLazyDeopt(
+      instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
+  DCHECK(instr->HasEnvironment());
+  LEnvironment* env = instr->environment();
+  safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
+}
+
+
+void LCodeGen::DoStackCheck(LStackCheck* instr) {
+  class DeferredStackCheck FINAL : public LDeferredCode {
+   public:
+    DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
+        : LDeferredCode(codegen), instr_(instr) {}
+    void Generate() OVERRIDE { codegen()->DoDeferredStackCheck(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
+   private:
+    LStackCheck* instr_;
+  };
+
+  DCHECK(instr->HasEnvironment());
+  LEnvironment* env = instr->environment();
+  // There is no LLazyBailout instruction for stack-checks. We have to
+  // prepare for lazy deoptimization explicitly here.
+  if (instr->hydrogen()->is_function_entry()) {
+    // Perform stack overflow check.
+    Label done;
+    __ LoadRoot(ip, Heap::kStackLimitRootIndex);
+    __ cmpl(sp, ip);
+    __ bge(&done);
+    DCHECK(instr->context()->IsRegister());
+    DCHECK(ToRegister(instr->context()).is(cp));
+    CallCode(isolate()->builtins()->StackCheck(), RelocInfo::CODE_TARGET,
+             instr);
+    __ bind(&done);
+  } else {
+    DCHECK(instr->hydrogen()->is_backwards_branch());
+    // Perform stack overflow check if this goto needs it before jumping.
+    DeferredStackCheck* deferred_stack_check =
+        new (zone()) DeferredStackCheck(this, instr);
+    __ LoadRoot(ip, Heap::kStackLimitRootIndex);
+    __ cmpl(sp, ip);
+    __ blt(deferred_stack_check->entry());
+    EnsureSpaceForLazyDeopt(Deoptimizer::patch_size());
+    __ bind(instr->done_label());
+    deferred_stack_check->SetExit(instr->done_label());
+    RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt);
+    // Don't record a deoptimization index for the safepoint here.
+    // This will be done explicitly when emitting call and the safepoint in
+    // the deferred code.
+  }
+}
+
+
+void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
+  // This is a pseudo-instruction that ensures that the environment here is
+  // properly registered for deoptimization and records the assembler's PC
+  // offset.
+  LEnvironment* environment = instr->environment();
+
+  // If the environment were already registered, we would have no way of
+  // backpatching it with the spill slot operands.
+  DCHECK(!environment->HasBeenRegistered());
+  RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
+
+  GenerateOsrPrologue();
+}
+
+
+void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
+  __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
+  __ cmp(r3, ip);
+  DeoptimizeIf(eq, instr, "undefined");
+
+  Register null_value = r8;
+  __ LoadRoot(null_value, Heap::kNullValueRootIndex);
+  __ cmp(r3, null_value);
+  DeoptimizeIf(eq, instr, "null");
+
+  __ TestIfSmi(r3, r0);
+  DeoptimizeIf(eq, instr, "Smi", cr0);
+
+  STATIC_ASSERT(FIRST_JS_PROXY_TYPE == FIRST_SPEC_OBJECT_TYPE);
+  __ CompareObjectType(r3, r4, r4, LAST_JS_PROXY_TYPE);
+  DeoptimizeIf(le, instr, "wrong instance type");
+
+  Label use_cache, call_runtime;
+  __ CheckEnumCache(null_value, &call_runtime);
+
+  __ LoadP(r3, FieldMemOperand(r3, HeapObject::kMapOffset));
+  __ b(&use_cache);
+
+  // Get the set of properties to enumerate.
+  __ bind(&call_runtime);
+  __ push(r3);
+  CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
+
+  __ LoadP(r4, FieldMemOperand(r3, HeapObject::kMapOffset));
+  __ LoadRoot(ip, Heap::kMetaMapRootIndex);
+  __ cmp(r4, ip);
+  DeoptimizeIf(ne, instr, "wrong map");
+  __ bind(&use_cache);
+}
+
+
+void LCodeGen::DoForInCacheArray(LForInCacheArray* instr) {
+  Register map = ToRegister(instr->map());
+  Register result = ToRegister(instr->result());
+  Label load_cache, done;
+  __ EnumLength(result, map);
+  __ CmpSmiLiteral(result, Smi::FromInt(0), r0);
+  __ bne(&load_cache);
+  __ mov(result, Operand(isolate()->factory()->empty_fixed_array()));
+  __ b(&done);
+
+  __ bind(&load_cache);
+  __ LoadInstanceDescriptors(map, result);
+  __ LoadP(result, FieldMemOperand(result, DescriptorArray::kEnumCacheOffset));
+  __ LoadP(result, FieldMemOperand(result, FixedArray::SizeFor(instr->idx())));
+  __ cmpi(result, Operand::Zero());
+  DeoptimizeIf(eq, instr, "no cache");
+
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoCheckMapValue(LCheckMapValue* instr) {
+  Register object = ToRegister(instr->value());
+  Register map = ToRegister(instr->map());
+  __ LoadP(scratch0(), FieldMemOperand(object, HeapObject::kMapOffset));
+  __ cmp(map, scratch0());
+  DeoptimizeIf(ne, instr, "wrong map");
+}
+
+
+void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
+                                           Register result, Register object,
+                                           Register index) {
+  PushSafepointRegistersScope scope(this);
+  __ Push(object, index);
+  __ li(cp, Operand::Zero());
+  __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble);
+  RecordSafepointWithRegisters(instr->pointer_map(), 2,
+                               Safepoint::kNoLazyDeopt);
+  __ StoreToSafepointRegisterSlot(r3, result);
+}
+
+
+void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
+  class DeferredLoadMutableDouble FINAL : public LDeferredCode {
+   public:
+    DeferredLoadMutableDouble(LCodeGen* codegen, LLoadFieldByIndex* instr,
+                              Register result, Register object, Register index)
+        : LDeferredCode(codegen),
+          instr_(instr),
+          result_(result),
+          object_(object),
+          index_(index) {}
+    void Generate() OVERRIDE {
+      codegen()->DoDeferredLoadMutableDouble(instr_, result_, object_, index_);
+    }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
+   private:
+    LLoadFieldByIndex* instr_;
+    Register result_;
+    Register object_;
+    Register index_;
+  };
+
+  Register object = ToRegister(instr->object());
+  Register index = ToRegister(instr->index());
+  Register result = ToRegister(instr->result());
+  Register scratch = scratch0();
+
+  DeferredLoadMutableDouble* deferred;
+  deferred = new (zone())
+      DeferredLoadMutableDouble(this, instr, result, object, index);
+
+  Label out_of_object, done;
+
+  __ TestBitMask(index, reinterpret_cast<uintptr_t>(Smi::FromInt(1)), r0);
+  __ bne(deferred->entry(), cr0);
+  __ ShiftRightArithImm(index, index, 1);
+
+  __ cmpi(index, Operand::Zero());
+  __ blt(&out_of_object);
+
+  __ SmiToPtrArrayOffset(r0, index);
+  __ add(scratch, object, r0);
+  __ LoadP(result, FieldMemOperand(scratch, JSObject::kHeaderSize));
+
+  __ b(&done);
+
+  __ bind(&out_of_object);
+  __ LoadP(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
+  // Index is equal to negated out of object property index plus 1.
+  __ SmiToPtrArrayOffset(r0, index);
+  __ sub(scratch, result, r0);
+  __ LoadP(result,
+           FieldMemOperand(scratch, FixedArray::kHeaderSize - kPointerSize));
+  __ bind(deferred->exit());
+  __ bind(&done);
+}
+
+
+void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) {
+  Register context = ToRegister(instr->context());
+  __ StoreP(context, MemOperand(fp, StandardFrameConstants::kContextOffset));
+}
+
+
+void LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) {
+  Handle<ScopeInfo> scope_info = instr->scope_info();
+  __ Push(scope_info);
+  __ push(ToRegister(instr->function()));
+  CallRuntime(Runtime::kPushBlockContext, 2, instr);
+  RecordSafepoint(Safepoint::kNoLazyDeopt);
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
diff --git a/src/ppc/lithium-codegen-ppc.h b/src/ppc/lithium-codegen-ppc.h
new file mode 100644
index 0000000..8ae3b3c
--- /dev/null
+++ b/src/ppc/lithium-codegen-ppc.h
@@ -0,0 +1,372 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_PPC_LITHIUM_CODEGEN_PPC_H_
+#define V8_PPC_LITHIUM_CODEGEN_PPC_H_
+
+#include "src/ppc/lithium-ppc.h"
+
+#include "src/ppc/lithium-gap-resolver-ppc.h"
+#include "src/deoptimizer.h"
+#include "src/lithium-codegen.h"
+#include "src/safepoint-table.h"
+#include "src/scopes.h"
+#include "src/utils.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class LDeferredCode;
+class SafepointGenerator;
+
+class LCodeGen : public LCodeGenBase {
+ public:
+  LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
+      : LCodeGenBase(chunk, assembler, info),
+        deoptimizations_(4, info->zone()),
+        jump_table_(4, info->zone()),
+        deoptimization_literals_(8, info->zone()),
+        inlined_function_count_(0),
+        scope_(info->scope()),
+        translations_(info->zone()),
+        deferred_(8, info->zone()),
+        osr_pc_offset_(-1),
+        frame_is_built_(false),
+        safepoints_(info->zone()),
+        resolver_(this),
+        expected_safepoint_kind_(Safepoint::kSimple) {
+    PopulateDeoptimizationLiteralsWithInlinedFunctions();
+  }
+
+
+  int LookupDestination(int block_id) const {
+    return chunk()->LookupDestination(block_id);
+  }
+
+  bool IsNextEmittedBlock(int block_id) const {
+    return LookupDestination(block_id) == GetNextEmittedBlock();
+  }
+
+  bool NeedsEagerFrame() const {
+    return GetStackSlotCount() > 0 || info()->is_non_deferred_calling() ||
+           !info()->IsStub() || info()->requires_frame();
+  }
+  bool NeedsDeferredFrame() const {
+    return !NeedsEagerFrame() && info()->is_deferred_calling();
+  }
+
+  LinkRegisterStatus GetLinkRegisterState() const {
+    return frame_is_built_ ? kLRHasBeenSaved : kLRHasNotBeenSaved;
+  }
+
+  // Support for converting LOperands to assembler types.
+  // LOperand must be a register.
+  Register ToRegister(LOperand* op) const;
+
+  // LOperand is loaded into scratch, unless already a register.
+  Register EmitLoadRegister(LOperand* op, Register scratch);
+
+  // LConstantOperand must be an Integer32 or Smi
+  void EmitLoadIntegerConstant(LConstantOperand* const_op, Register dst);
+
+  // LOperand must be a double register.
+  DoubleRegister ToDoubleRegister(LOperand* op) const;
+
+  intptr_t ToRepresentation(LConstantOperand* op,
+                            const Representation& r) const;
+  int32_t ToInteger32(LConstantOperand* op) const;
+  Smi* ToSmi(LConstantOperand* op) const;
+  double ToDouble(LConstantOperand* op) const;
+  Operand ToOperand(LOperand* op);
+  MemOperand ToMemOperand(LOperand* op) const;
+  // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
+  MemOperand ToHighMemOperand(LOperand* op) const;
+
+  bool IsInteger32(LConstantOperand* op) const;
+  bool IsSmi(LConstantOperand* op) const;
+  Handle<Object> ToHandle(LConstantOperand* op) const;
+
+  // Try to generate code for the entire chunk, but it may fail if the
+  // chunk contains constructs we cannot handle. Returns true if the
+  // code generation attempt succeeded.
+  bool GenerateCode();
+
+  // Finish the code by setting stack height, safepoint, and bailout
+  // information on it.
+  void FinishCode(Handle<Code> code);
+
+  // Deferred code support.
+  void DoDeferredNumberTagD(LNumberTagD* instr);
+
+  enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
+  void DoDeferredNumberTagIU(LInstruction* instr, LOperand* value,
+                             LOperand* temp1, LOperand* temp2,
+                             IntegerSignedness signedness);
+
+  void DoDeferredTaggedToI(LTaggedToI* instr);
+  void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
+  void DoDeferredStackCheck(LStackCheck* instr);
+  void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
+  void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
+  void DoDeferredAllocate(LAllocate* instr);
+  void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
+                                       Label* map_check);
+  void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
+  void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, Register result,
+                                   Register object, Register index);
+
+  // Parallel move support.
+  void DoParallelMove(LParallelMove* move);
+  void DoGap(LGap* instr);
+
+  MemOperand PrepareKeyedOperand(Register key, Register base,
+                                 bool key_is_constant, bool key_is_tagged,
+                                 int constant_key, int element_size_shift,
+                                 int base_offset);
+
+  // Emit frame translation commands for an environment.
+  void WriteTranslation(LEnvironment* environment, Translation* translation);
+
+// Declare methods that deal with the individual node types.
+#define DECLARE_DO(type) void Do##type(L##type* node);
+  LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
+#undef DECLARE_DO
+
+ private:
+  StrictMode strict_mode() const { return info()->strict_mode(); }
+
+  Scope* scope() const { return scope_; }
+
+  Register scratch0() { return r11; }
+  DoubleRegister double_scratch0() { return kScratchDoubleReg; }
+
+  LInstruction* GetNextInstruction();
+
+  void EmitClassOfTest(Label* if_true, Label* if_false,
+                       Handle<String> class_name, Register input,
+                       Register temporary, Register temporary2);
+
+  int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
+
+  void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
+
+  void SaveCallerDoubles();
+  void RestoreCallerDoubles();
+
+  // Code generation passes.  Returns true if code generation should
+  // continue.
+  void GenerateBodyInstructionPre(LInstruction* instr) OVERRIDE;
+  bool GeneratePrologue();
+  bool GenerateDeferredCode();
+  bool GenerateJumpTable();
+  bool GenerateSafepointTable();
+
+  // Generates the custom OSR entrypoint and sets the osr_pc_offset.
+  void GenerateOsrPrologue();
+
+  enum SafepointMode {
+    RECORD_SIMPLE_SAFEPOINT,
+    RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
+  };
+
+  void CallCode(Handle<Code> code, RelocInfo::Mode mode, LInstruction* instr);
+
+  void CallCodeGeneric(Handle<Code> code, RelocInfo::Mode mode,
+                       LInstruction* instr, SafepointMode safepoint_mode);
+
+  void CallRuntime(const Runtime::Function* function, int num_arguments,
+                   LInstruction* instr,
+                   SaveFPRegsMode save_doubles = kDontSaveFPRegs);
+
+  void CallRuntime(Runtime::FunctionId id, int num_arguments,
+                   LInstruction* instr) {
+    const Runtime::Function* function = Runtime::FunctionForId(id);
+    CallRuntime(function, num_arguments, instr);
+  }
+
+  void LoadContextFromDeferred(LOperand* context);
+  void CallRuntimeFromDeferred(Runtime::FunctionId id, int argc,
+                               LInstruction* instr, LOperand* context);
+
+  enum R4State { R4_UNINITIALIZED, R4_CONTAINS_TARGET };
+
+  // Generate a direct call to a known function.  Expects the function
+  // to be in r4.
+  void CallKnownFunction(Handle<JSFunction> function,
+                         int formal_parameter_count, int arity,
+                         LInstruction* instr, R4State r4_state);
+
+  void RecordSafepointWithLazyDeopt(LInstruction* instr,
+                                    SafepointMode safepoint_mode);
+
+  void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
+                                            Safepoint::DeoptMode mode);
+  void DeoptimizeIf(Condition condition, LInstruction* instr,
+                    const char* detail, Deoptimizer::BailoutType bailout_type,
+                    CRegister cr = cr7);
+  void DeoptimizeIf(Condition condition, LInstruction* instr,
+                    const char* detail, CRegister cr = cr7);
+
+  void AddToTranslation(LEnvironment* environment, Translation* translation,
+                        LOperand* op, bool is_tagged, bool is_uint32,
+                        int* object_index_pointer,
+                        int* dematerialized_index_pointer);
+  void PopulateDeoptimizationData(Handle<Code> code);
+  int DefineDeoptimizationLiteral(Handle<Object> literal);
+
+  void PopulateDeoptimizationLiteralsWithInlinedFunctions();
+
+  Register ToRegister(int index) const;
+  DoubleRegister ToDoubleRegister(int index) const;
+
+  MemOperand BuildSeqStringOperand(Register string, LOperand* index,
+                                   String::Encoding encoding);
+
+  void EmitMathAbs(LMathAbs* instr);
+#if V8_TARGET_ARCH_PPC64
+  void EmitInteger32MathAbs(LMathAbs* instr);
+#endif
+
+  // Support for recording safepoint and position information.
+  void RecordSafepoint(LPointerMap* pointers, Safepoint::Kind kind,
+                       int arguments, Safepoint::DeoptMode mode);
+  void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
+  void RecordSafepoint(Safepoint::DeoptMode mode);
+  void RecordSafepointWithRegisters(LPointerMap* pointers, int arguments,
+                                    Safepoint::DeoptMode mode);
+
+  void RecordAndWritePosition(int position) OVERRIDE;
+
+  static Condition TokenToCondition(Token::Value op);
+  void EmitGoto(int block);
+
+  // EmitBranch expects to be the last instruction of a block.
+  template <class InstrType>
+  void EmitBranch(InstrType instr, Condition condition, CRegister cr = cr7);
+  template <class InstrType>
+  void EmitFalseBranch(InstrType instr, Condition condition,
+                       CRegister cr = cr7);
+  void EmitNumberUntagD(LNumberUntagD* instr, Register input,
+                        DoubleRegister result, NumberUntagDMode mode);
+
+  // Emits optimized code for typeof x == "y".  Modifies input register.
+  // Returns the condition on which a final split to
+  // true and false label should be made, to optimize fallthrough.
+  Condition EmitTypeofIs(Label* true_label, Label* false_label, Register input,
+                         Handle<String> type_name);
+
+  // Emits optimized code for %_IsObject(x).  Preserves input register.
+  // Returns the condition on which a final split to
+  // true and false label should be made, to optimize fallthrough.
+  Condition EmitIsObject(Register input, Register temp1, Label* is_not_object,
+                         Label* is_object);
+
+  // Emits optimized code for %_IsString(x).  Preserves input register.
+  // Returns the condition on which a final split to
+  // true and false label should be made, to optimize fallthrough.
+  Condition EmitIsString(Register input, Register temp1, Label* is_not_string,
+                         SmiCheck check_needed);
+
+  // Emits optimized code for %_IsConstructCall().
+  // Caller should branch on equal condition.
+  void EmitIsConstructCall(Register temp1, Register temp2);
+
+  // Emits optimized code to deep-copy the contents of statically known
+  // object graphs (e.g. object literal boilerplate).
+  void EmitDeepCopy(Handle<JSObject> object, Register result, Register source,
+                    int* offset, AllocationSiteMode mode);
+
+  void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE;
+  void DoLoadKeyedExternalArray(LLoadKeyed* instr);
+  void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
+  void DoLoadKeyedFixedArray(LLoadKeyed* instr);
+  void DoStoreKeyedExternalArray(LStoreKeyed* instr);
+  void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
+  void DoStoreKeyedFixedArray(LStoreKeyed* instr);
+
+  template <class T>
+  void EmitVectorLoadICRegisters(T* instr);
+
+  ZoneList<LEnvironment*> deoptimizations_;
+  ZoneList<Deoptimizer::JumpTableEntry> jump_table_;
+  ZoneList<Handle<Object> > deoptimization_literals_;
+  int inlined_function_count_;
+  Scope* const scope_;
+  TranslationBuffer translations_;
+  ZoneList<LDeferredCode*> deferred_;
+  int osr_pc_offset_;
+  bool frame_is_built_;
+
+  // Builder that keeps track of safepoints in the code. The table
+  // itself is emitted at the end of the generated code.
+  SafepointTableBuilder safepoints_;
+
+  // Compiler from a set of parallel moves to a sequential list of moves.
+  LGapResolver resolver_;
+
+  Safepoint::Kind expected_safepoint_kind_;
+
+  class PushSafepointRegistersScope FINAL BASE_EMBEDDED {
+   public:
+    explicit PushSafepointRegistersScope(LCodeGen* codegen)
+        : codegen_(codegen) {
+      DCHECK(codegen_->info()->is_calling());
+      DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
+      codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters;
+      StoreRegistersStateStub stub(codegen_->isolate());
+      codegen_->masm_->CallStub(&stub);
+    }
+
+    ~PushSafepointRegistersScope() {
+      DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters);
+      RestoreRegistersStateStub stub(codegen_->isolate());
+      codegen_->masm_->CallStub(&stub);
+      codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
+    }
+
+   private:
+    LCodeGen* codegen_;
+  };
+
+  friend class LDeferredCode;
+  friend class LEnvironment;
+  friend class SafepointGenerator;
+  DISALLOW_COPY_AND_ASSIGN(LCodeGen);
+};
+
+
+class LDeferredCode : public ZoneObject {
+ public:
+  explicit LDeferredCode(LCodeGen* codegen)
+      : codegen_(codegen),
+        external_exit_(NULL),
+        instruction_index_(codegen->current_instruction_) {
+    codegen->AddDeferredCode(this);
+  }
+
+  virtual ~LDeferredCode() {}
+  virtual void Generate() = 0;
+  virtual LInstruction* instr() = 0;
+
+  void SetExit(Label* exit) { external_exit_ = exit; }
+  Label* entry() { return &entry_; }
+  Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
+  int instruction_index() const { return instruction_index_; }
+
+ protected:
+  LCodeGen* codegen() const { return codegen_; }
+  MacroAssembler* masm() const { return codegen_->masm(); }
+
+ private:
+  LCodeGen* codegen_;
+  Label entry_;
+  Label exit_;
+  Label* external_exit_;
+  int instruction_index_;
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_PPC_LITHIUM_CODEGEN_PPC_H_
diff --git a/src/ppc/lithium-gap-resolver-ppc.cc b/src/ppc/lithium-gap-resolver-ppc.cc
new file mode 100644
index 0000000..c261b66
--- /dev/null
+++ b/src/ppc/lithium-gap-resolver-ppc.cc
@@ -0,0 +1,288 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/ppc/lithium-codegen-ppc.h"
+#include "src/ppc/lithium-gap-resolver-ppc.h"
+
+namespace v8 {
+namespace internal {
+
+static const Register kSavedValueRegister = {11};
+
+LGapResolver::LGapResolver(LCodeGen* owner)
+    : cgen_(owner),
+      moves_(32, owner->zone()),
+      root_index_(0),
+      in_cycle_(false),
+      saved_destination_(NULL) {}
+
+
+void LGapResolver::Resolve(LParallelMove* parallel_move) {
+  DCHECK(moves_.is_empty());
+  // Build up a worklist of moves.
+  BuildInitialMoveList(parallel_move);
+
+  for (int i = 0; i < moves_.length(); ++i) {
+    LMoveOperands move = moves_[i];
+    // Skip constants to perform them last.  They don't block other moves
+    // and skipping such moves with register destinations keeps those
+    // registers free for the whole algorithm.
+    if (!move.IsEliminated() && !move.source()->IsConstantOperand()) {
+      root_index_ = i;  // Any cycle is found when by reaching this move again.
+      PerformMove(i);
+      if (in_cycle_) {
+        RestoreValue();
+      }
+    }
+  }
+
+  // Perform the moves with constant sources.
+  for (int i = 0; i < moves_.length(); ++i) {
+    if (!moves_[i].IsEliminated()) {
+      DCHECK(moves_[i].source()->IsConstantOperand());
+      EmitMove(i);
+    }
+  }
+
+  moves_.Rewind(0);
+}
+
+
+void LGapResolver::BuildInitialMoveList(LParallelMove* parallel_move) {
+  // Perform a linear sweep of the moves to add them to the initial list of
+  // moves to perform, ignoring any move that is redundant (the source is
+  // the same as the destination, the destination is ignored and
+  // unallocated, or the move was already eliminated).
+  const ZoneList<LMoveOperands>* moves = parallel_move->move_operands();
+  for (int i = 0; i < moves->length(); ++i) {
+    LMoveOperands move = moves->at(i);
+    if (!move.IsRedundant()) moves_.Add(move, cgen_->zone());
+  }
+  Verify();
+}
+
+
+void LGapResolver::PerformMove(int index) {
+  // Each call to this function performs a move and deletes it from the move
+  // graph.  We first recursively perform any move blocking this one.  We
+  // mark a move as "pending" on entry to PerformMove in order to detect
+  // cycles in the move graph.
+
+  // We can only find a cycle, when doing a depth-first traversal of moves,
+  // be encountering the starting move again. So by spilling the source of
+  // the starting move, we break the cycle.  All moves are then unblocked,
+  // and the starting move is completed by writing the spilled value to
+  // its destination.  All other moves from the spilled source have been
+  // completed prior to breaking the cycle.
+  // An additional complication is that moves to MemOperands with large
+  // offsets (more than 1K or 4K) require us to spill this spilled value to
+  // the stack, to free up the register.
+  DCHECK(!moves_[index].IsPending());
+  DCHECK(!moves_[index].IsRedundant());
+
+  // Clear this move's destination to indicate a pending move.  The actual
+  // destination is saved in a stack allocated local.  Multiple moves can
+  // be pending because this function is recursive.
+  DCHECK(moves_[index].source() != NULL);  // Or else it will look eliminated.
+  LOperand* destination = moves_[index].destination();
+  moves_[index].set_destination(NULL);
+
+  // Perform a depth-first traversal of the move graph to resolve
+  // dependencies.  Any unperformed, unpending move with a source the same
+  // as this one's destination blocks this one so recursively perform all
+  // such moves.
+  for (int i = 0; i < moves_.length(); ++i) {
+    LMoveOperands other_move = moves_[i];
+    if (other_move.Blocks(destination) && !other_move.IsPending()) {
+      PerformMove(i);
+      // If there is a blocking, pending move it must be moves_[root_index_]
+      // and all other moves with the same source as moves_[root_index_] are
+      // sucessfully executed (because they are cycle-free) by this loop.
+    }
+  }
+
+  // We are about to resolve this move and don't need it marked as
+  // pending, so restore its destination.
+  moves_[index].set_destination(destination);
+
+  // The move may be blocked on a pending move, which must be the starting move.
+  // In this case, we have a cycle, and we save the source of this move to
+  // a scratch register to break it.
+  LMoveOperands other_move = moves_[root_index_];
+  if (other_move.Blocks(destination)) {
+    DCHECK(other_move.IsPending());
+    BreakCycle(index);
+    return;
+  }
+
+  // This move is no longer blocked.
+  EmitMove(index);
+}
+
+
+void LGapResolver::Verify() {
+#ifdef ENABLE_SLOW_DCHECKS
+  // No operand should be the destination for more than one move.
+  for (int i = 0; i < moves_.length(); ++i) {
+    LOperand* destination = moves_[i].destination();
+    for (int j = i + 1; j < moves_.length(); ++j) {
+      SLOW_DCHECK(!destination->Equals(moves_[j].destination()));
+    }
+  }
+#endif
+}
+
+#define __ ACCESS_MASM(cgen_->masm())
+
+void LGapResolver::BreakCycle(int index) {
+  // We save in a register the value that should end up in the source of
+  // moves_[root_index].  After performing all moves in the tree rooted
+  // in that move, we save the value to that source.
+  DCHECK(moves_[index].destination()->Equals(moves_[root_index_].source()));
+  DCHECK(!in_cycle_);
+  in_cycle_ = true;
+  LOperand* source = moves_[index].source();
+  saved_destination_ = moves_[index].destination();
+  if (source->IsRegister()) {
+    __ mr(kSavedValueRegister, cgen_->ToRegister(source));
+  } else if (source->IsStackSlot()) {
+    __ LoadP(kSavedValueRegister, cgen_->ToMemOperand(source));
+  } else if (source->IsDoubleRegister()) {
+    __ fmr(kScratchDoubleReg, cgen_->ToDoubleRegister(source));
+  } else if (source->IsDoubleStackSlot()) {
+    __ lfd(kScratchDoubleReg, cgen_->ToMemOperand(source));
+  } else {
+    UNREACHABLE();
+  }
+  // This move will be done by restoring the saved value to the destination.
+  moves_[index].Eliminate();
+}
+
+
+void LGapResolver::RestoreValue() {
+  DCHECK(in_cycle_);
+  DCHECK(saved_destination_ != NULL);
+
+  // Spilled value is in kSavedValueRegister or kSavedDoubleValueRegister.
+  if (saved_destination_->IsRegister()) {
+    __ mr(cgen_->ToRegister(saved_destination_), kSavedValueRegister);
+  } else if (saved_destination_->IsStackSlot()) {
+    __ StoreP(kSavedValueRegister, cgen_->ToMemOperand(saved_destination_));
+  } else if (saved_destination_->IsDoubleRegister()) {
+    __ fmr(cgen_->ToDoubleRegister(saved_destination_), kScratchDoubleReg);
+  } else if (saved_destination_->IsDoubleStackSlot()) {
+    __ stfd(kScratchDoubleReg, cgen_->ToMemOperand(saved_destination_));
+  } else {
+    UNREACHABLE();
+  }
+
+  in_cycle_ = false;
+  saved_destination_ = NULL;
+}
+
+
+void LGapResolver::EmitMove(int index) {
+  LOperand* source = moves_[index].source();
+  LOperand* destination = moves_[index].destination();
+
+  // Dispatch on the source and destination operand kinds.  Not all
+  // combinations are possible.
+
+  if (source->IsRegister()) {
+    Register source_register = cgen_->ToRegister(source);
+    if (destination->IsRegister()) {
+      __ mr(cgen_->ToRegister(destination), source_register);
+    } else {
+      DCHECK(destination->IsStackSlot());
+      __ StoreP(source_register, cgen_->ToMemOperand(destination));
+    }
+  } else if (source->IsStackSlot()) {
+    MemOperand source_operand = cgen_->ToMemOperand(source);
+    if (destination->IsRegister()) {
+      __ LoadP(cgen_->ToRegister(destination), source_operand);
+    } else {
+      DCHECK(destination->IsStackSlot());
+      MemOperand destination_operand = cgen_->ToMemOperand(destination);
+      if (in_cycle_) {
+        __ LoadP(ip, source_operand);
+        __ StoreP(ip, destination_operand);
+      } else {
+        __ LoadP(kSavedValueRegister, source_operand);
+        __ StoreP(kSavedValueRegister, destination_operand);
+      }
+    }
+
+  } else if (source->IsConstantOperand()) {
+    LConstantOperand* constant_source = LConstantOperand::cast(source);
+    if (destination->IsRegister()) {
+      Register dst = cgen_->ToRegister(destination);
+      if (cgen_->IsInteger32(constant_source)) {
+        cgen_->EmitLoadIntegerConstant(constant_source, dst);
+      } else {
+        __ Move(dst, cgen_->ToHandle(constant_source));
+      }
+    } else if (destination->IsDoubleRegister()) {
+      DoubleRegister result = cgen_->ToDoubleRegister(destination);
+      double v = cgen_->ToDouble(constant_source);
+      __ LoadDoubleLiteral(result, v, ip);
+    } else {
+      DCHECK(destination->IsStackSlot());
+      DCHECK(!in_cycle_);  // Constant moves happen after all cycles are gone.
+      if (cgen_->IsInteger32(constant_source)) {
+        cgen_->EmitLoadIntegerConstant(constant_source, kSavedValueRegister);
+      } else {
+        __ Move(kSavedValueRegister, cgen_->ToHandle(constant_source));
+      }
+      __ StoreP(kSavedValueRegister, cgen_->ToMemOperand(destination));
+    }
+
+  } else if (source->IsDoubleRegister()) {
+    DoubleRegister source_register = cgen_->ToDoubleRegister(source);
+    if (destination->IsDoubleRegister()) {
+      __ fmr(cgen_->ToDoubleRegister(destination), source_register);
+    } else {
+      DCHECK(destination->IsDoubleStackSlot());
+      __ stfd(source_register, cgen_->ToMemOperand(destination));
+    }
+
+  } else if (source->IsDoubleStackSlot()) {
+    MemOperand source_operand = cgen_->ToMemOperand(source);
+    if (destination->IsDoubleRegister()) {
+      __ lfd(cgen_->ToDoubleRegister(destination), source_operand);
+    } else {
+      DCHECK(destination->IsDoubleStackSlot());
+      MemOperand destination_operand = cgen_->ToMemOperand(destination);
+      if (in_cycle_) {
+// kSavedDoubleValueRegister was used to break the cycle,
+// but kSavedValueRegister is free.
+#if V8_TARGET_ARCH_PPC64
+        __ ld(kSavedValueRegister, source_operand);
+        __ std(kSavedValueRegister, destination_operand);
+#else
+        MemOperand source_high_operand = cgen_->ToHighMemOperand(source);
+        MemOperand destination_high_operand =
+            cgen_->ToHighMemOperand(destination);
+        __ lwz(kSavedValueRegister, source_operand);
+        __ stw(kSavedValueRegister, destination_operand);
+        __ lwz(kSavedValueRegister, source_high_operand);
+        __ stw(kSavedValueRegister, destination_high_operand);
+#endif
+      } else {
+        __ lfd(kScratchDoubleReg, source_operand);
+        __ stfd(kScratchDoubleReg, destination_operand);
+      }
+    }
+  } else {
+    UNREACHABLE();
+  }
+
+  moves_[index].Eliminate();
+}
+
+
+#undef __
+}
+}  // namespace v8::internal
diff --git a/src/ppc/lithium-gap-resolver-ppc.h b/src/ppc/lithium-gap-resolver-ppc.h
new file mode 100644
index 0000000..78bd213
--- /dev/null
+++ b/src/ppc/lithium-gap-resolver-ppc.h
@@ -0,0 +1,60 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_PPC_LITHIUM_GAP_RESOLVER_PPC_H_
+#define V8_PPC_LITHIUM_GAP_RESOLVER_PPC_H_
+
+#include "src/v8.h"
+
+#include "src/lithium.h"
+
+namespace v8 {
+namespace internal {
+
+class LCodeGen;
+class LGapResolver;
+
+class LGapResolver FINAL BASE_EMBEDDED {
+ public:
+  explicit LGapResolver(LCodeGen* owner);
+
+  // Resolve a set of parallel moves, emitting assembler instructions.
+  void Resolve(LParallelMove* parallel_move);
+
+ private:
+  // Build the initial list of moves.
+  void BuildInitialMoveList(LParallelMove* parallel_move);
+
+  // Perform the move at the moves_ index in question (possibly requiring
+  // other moves to satisfy dependencies).
+  void PerformMove(int index);
+
+  // If a cycle is found in the series of moves, save the blocking value to
+  // a scratch register.  The cycle must be found by hitting the root of the
+  // depth-first search.
+  void BreakCycle(int index);
+
+  // After a cycle has been resolved, restore the value from the scratch
+  // register to its proper destination.
+  void RestoreValue();
+
+  // Emit a move and remove it from the move graph.
+  void EmitMove(int index);
+
+  // Verify the move list before performing moves.
+  void Verify();
+
+  LCodeGen* cgen_;
+
+  // List of moves not yet resolved.
+  ZoneList<LMoveOperands> moves_;
+
+  int root_index_;
+  bool in_cycle_;
+  LOperand* saved_destination_;
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_PPC_LITHIUM_GAP_RESOLVER_PPC_H_
diff --git a/src/ppc/lithium-ppc.cc b/src/ppc/lithium-ppc.cc
new file mode 100644
index 0000000..42470c5
--- /dev/null
+++ b/src/ppc/lithium-ppc.cc
@@ -0,0 +1,2626 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <sstream>
+
+#include "src/v8.h"
+
+#include "src/hydrogen-osr.h"
+#include "src/lithium-inl.h"
+#include "src/ppc/lithium-codegen-ppc.h"
+
+namespace v8 {
+namespace internal {
+
+#define DEFINE_COMPILE(type)                           \
+  void L##type::CompileToNative(LCodeGen* generator) { \
+    generator->Do##type(this);                         \
+  }
+LITHIUM_CONCRETE_INSTRUCTION_LIST(DEFINE_COMPILE)
+#undef DEFINE_COMPILE
+
+#ifdef DEBUG
+void LInstruction::VerifyCall() {
+  // Call instructions can use only fixed registers as temporaries and
+  // outputs because all registers are blocked by the calling convention.
+  // Inputs operands must use a fixed register or use-at-start policy or
+  // a non-register policy.
+  DCHECK(Output() == NULL || LUnallocated::cast(Output())->HasFixedPolicy() ||
+         !LUnallocated::cast(Output())->HasRegisterPolicy());
+  for (UseIterator it(this); !it.Done(); it.Advance()) {
+    LUnallocated* operand = LUnallocated::cast(it.Current());
+    DCHECK(operand->HasFixedPolicy() || operand->IsUsedAtStart());
+  }
+  for (TempIterator it(this); !it.Done(); it.Advance()) {
+    LUnallocated* operand = LUnallocated::cast(it.Current());
+    DCHECK(operand->HasFixedPolicy() || !operand->HasRegisterPolicy());
+  }
+}
+#endif
+
+
+void LInstruction::PrintTo(StringStream* stream) {
+  stream->Add("%s ", this->Mnemonic());
+
+  PrintOutputOperandTo(stream);
+
+  PrintDataTo(stream);
+
+  if (HasEnvironment()) {
+    stream->Add(" ");
+    environment()->PrintTo(stream);
+  }
+
+  if (HasPointerMap()) {
+    stream->Add(" ");
+    pointer_map()->PrintTo(stream);
+  }
+}
+
+
+void LInstruction::PrintDataTo(StringStream* stream) {
+  stream->Add("= ");
+  for (int i = 0; i < InputCount(); i++) {
+    if (i > 0) stream->Add(" ");
+    if (InputAt(i) == NULL) {
+      stream->Add("NULL");
+    } else {
+      InputAt(i)->PrintTo(stream);
+    }
+  }
+}
+
+
+void LInstruction::PrintOutputOperandTo(StringStream* stream) {
+  if (HasResult()) result()->PrintTo(stream);
+}
+
+
+void LLabel::PrintDataTo(StringStream* stream) {
+  LGap::PrintDataTo(stream);
+  LLabel* rep = replacement();
+  if (rep != NULL) {
+    stream->Add(" Dead block replaced with B%d", rep->block_id());
+  }
+}
+
+
+bool LGap::IsRedundant() const {
+  for (int i = 0; i < 4; i++) {
+    if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+
+void LGap::PrintDataTo(StringStream* stream) {
+  for (int i = 0; i < 4; i++) {
+    stream->Add("(");
+    if (parallel_moves_[i] != NULL) {
+      parallel_moves_[i]->PrintDataTo(stream);
+    }
+    stream->Add(") ");
+  }
+}
+
+
+const char* LArithmeticD::Mnemonic() const {
+  switch (op()) {
+    case Token::ADD:
+      return "add-d";
+    case Token::SUB:
+      return "sub-d";
+    case Token::MUL:
+      return "mul-d";
+    case Token::DIV:
+      return "div-d";
+    case Token::MOD:
+      return "mod-d";
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+const char* LArithmeticT::Mnemonic() const {
+  switch (op()) {
+    case Token::ADD:
+      return "add-t";
+    case Token::SUB:
+      return "sub-t";
+    case Token::MUL:
+      return "mul-t";
+    case Token::MOD:
+      return "mod-t";
+    case Token::DIV:
+      return "div-t";
+    case Token::BIT_AND:
+      return "bit-and-t";
+    case Token::BIT_OR:
+      return "bit-or-t";
+    case Token::BIT_XOR:
+      return "bit-xor-t";
+    case Token::ROR:
+      return "ror-t";
+    case Token::SHL:
+      return "shl-t";
+    case Token::SAR:
+      return "sar-t";
+    case Token::SHR:
+      return "shr-t";
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+bool LGoto::HasInterestingComment(LCodeGen* gen) const {
+  return !gen->IsNextEmittedBlock(block_id());
+}
+
+
+void LGoto::PrintDataTo(StringStream* stream) {
+  stream->Add("B%d", block_id());
+}
+
+
+void LBranch::PrintDataTo(StringStream* stream) {
+  stream->Add("B%d | B%d on ", true_block_id(), false_block_id());
+  value()->PrintTo(stream);
+}
+
+
+void LCompareNumericAndBranch::PrintDataTo(StringStream* stream) {
+  stream->Add("if ");
+  left()->PrintTo(stream);
+  stream->Add(" %s ", Token::String(op()));
+  right()->PrintTo(stream);
+  stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
+}
+
+
+void LIsObjectAndBranch::PrintDataTo(StringStream* stream) {
+  stream->Add("if is_object(");
+  value()->PrintTo(stream);
+  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
+}
+
+
+void LIsStringAndBranch::PrintDataTo(StringStream* stream) {
+  stream->Add("if is_string(");
+  value()->PrintTo(stream);
+  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
+}
+
+
+void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
+  stream->Add("if is_smi(");
+  value()->PrintTo(stream);
+  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
+}
+
+
+void LIsUndetectableAndBranch::PrintDataTo(StringStream* stream) {
+  stream->Add("if is_undetectable(");
+  value()->PrintTo(stream);
+  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
+}
+
+
+void LStringCompareAndBranch::PrintDataTo(StringStream* stream) {
+  stream->Add("if string_compare(");
+  left()->PrintTo(stream);
+  right()->PrintTo(stream);
+  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
+}
+
+
+void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
+  stream->Add("if has_instance_type(");
+  value()->PrintTo(stream);
+  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
+}
+
+
+void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
+  stream->Add("if has_cached_array_index(");
+  value()->PrintTo(stream);
+  stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
+}
+
+
+void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
+  stream->Add("if class_of_test(");
+  value()->PrintTo(stream);
+  stream->Add(", \"%o\") then B%d else B%d", *hydrogen()->class_name(),
+              true_block_id(), false_block_id());
+}
+
+
+void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
+  stream->Add("if typeof ");
+  value()->PrintTo(stream);
+  stream->Add(" == \"%s\" then B%d else B%d",
+              hydrogen()->type_literal()->ToCString().get(), true_block_id(),
+              false_block_id());
+}
+
+
+void LStoreCodeEntry::PrintDataTo(StringStream* stream) {
+  stream->Add(" = ");
+  function()->PrintTo(stream);
+  stream->Add(".code_entry = ");
+  code_object()->PrintTo(stream);
+}
+
+
+void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
+  stream->Add(" = ");
+  base_object()->PrintTo(stream);
+  stream->Add(" + ");
+  offset()->PrintTo(stream);
+}
+
+
+void LCallJSFunction::PrintDataTo(StringStream* stream) {
+  stream->Add("= ");
+  function()->PrintTo(stream);
+  stream->Add("#%d / ", arity());
+}
+
+
+void LCallWithDescriptor::PrintDataTo(StringStream* stream) {
+  for (int i = 0; i < InputCount(); i++) {
+    InputAt(i)->PrintTo(stream);
+    stream->Add(" ");
+  }
+  stream->Add("#%d / ", arity());
+}
+
+
+void LLoadContextSlot::PrintDataTo(StringStream* stream) {
+  context()->PrintTo(stream);
+  stream->Add("[%d]", slot_index());
+}
+
+
+void LStoreContextSlot::PrintDataTo(StringStream* stream) {
+  context()->PrintTo(stream);
+  stream->Add("[%d] <- ", slot_index());
+  value()->PrintTo(stream);
+}
+
+
+void LInvokeFunction::PrintDataTo(StringStream* stream) {
+  stream->Add("= ");
+  function()->PrintTo(stream);
+  stream->Add(" #%d / ", arity());
+}
+
+
+void LCallNew::PrintDataTo(StringStream* stream) {
+  stream->Add("= ");
+  constructor()->PrintTo(stream);
+  stream->Add(" #%d / ", arity());
+}
+
+
+void LCallNewArray::PrintDataTo(StringStream* stream) {
+  stream->Add("= ");
+  constructor()->PrintTo(stream);
+  stream->Add(" #%d / ", arity());
+  ElementsKind kind = hydrogen()->elements_kind();
+  stream->Add(" (%s) ", ElementsKindToString(kind));
+}
+
+
+void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
+  arguments()->PrintTo(stream);
+  stream->Add(" length ");
+  length()->PrintTo(stream);
+  stream->Add(" index ");
+  index()->PrintTo(stream);
+}
+
+
+void LStoreNamedField::PrintDataTo(StringStream* stream) {
+  object()->PrintTo(stream);
+  std::ostringstream os;
+  os << hydrogen()->access() << " <- ";
+  stream->Add(os.str().c_str());
+  value()->PrintTo(stream);
+}
+
+
+void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
+  object()->PrintTo(stream);
+  stream->Add(".");
+  stream->Add(String::cast(*name())->ToCString().get());
+  stream->Add(" <- ");
+  value()->PrintTo(stream);
+}
+
+
+void LLoadKeyed::PrintDataTo(StringStream* stream) {
+  elements()->PrintTo(stream);
+  stream->Add("[");
+  key()->PrintTo(stream);
+  if (hydrogen()->IsDehoisted()) {
+    stream->Add(" + %d]", base_offset());
+  } else {
+    stream->Add("]");
+  }
+}
+
+
+void LStoreKeyed::PrintDataTo(StringStream* stream) {
+  elements()->PrintTo(stream);
+  stream->Add("[");
+  key()->PrintTo(stream);
+  if (hydrogen()->IsDehoisted()) {
+    stream->Add(" + %d] <-", base_offset());
+  } else {
+    stream->Add("] <- ");
+  }
+
+  if (value() == NULL) {
+    DCHECK(hydrogen()->IsConstantHoleStore() &&
+           hydrogen()->value()->representation().IsDouble());
+    stream->Add("<the hole(nan)>");
+  } else {
+    value()->PrintTo(stream);
+  }
+}
+
+
+void LStoreKeyedGeneric::PrintDataTo(StringStream* stream) {
+  object()->PrintTo(stream);
+  stream->Add("[");
+  key()->PrintTo(stream);
+  stream->Add("] <- ");
+  value()->PrintTo(stream);
+}
+
+
+void LTransitionElementsKind::PrintDataTo(StringStream* stream) {
+  object()->PrintTo(stream);
+  stream->Add(" %p -> %p", *original_map(), *transitioned_map());
+}
+
+
+int LPlatformChunk::GetNextSpillIndex(RegisterKind kind) {
+  // Skip a slot if for a double-width slot.
+  if (kind == DOUBLE_REGISTERS) spill_slot_count_++;
+  return spill_slot_count_++;
+}
+
+
+LOperand* LPlatformChunk::GetNextSpillSlot(RegisterKind kind) {
+  int index = GetNextSpillIndex(kind);
+  if (kind == DOUBLE_REGISTERS) {
+    return LDoubleStackSlot::Create(index, zone());
+  } else {
+    DCHECK(kind == GENERAL_REGISTERS);
+    return LStackSlot::Create(index, zone());
+  }
+}
+
+
+LPlatformChunk* LChunkBuilder::Build() {
+  DCHECK(is_unused());
+  chunk_ = new (zone()) LPlatformChunk(info(), graph());
+  LPhase phase("L_Building chunk", chunk_);
+  status_ = BUILDING;
+
+  // If compiling for OSR, reserve space for the unoptimized frame,
+  // which will be subsumed into this frame.
+  if (graph()->has_osr()) {
+    for (int i = graph()->osr()->UnoptimizedFrameSlots(); i > 0; i--) {
+      chunk_->GetNextSpillIndex(GENERAL_REGISTERS);
+    }
+  }
+
+  const ZoneList<HBasicBlock*>* blocks = graph()->blocks();
+  for (int i = 0; i < blocks->length(); i++) {
+    HBasicBlock* next = NULL;
+    if (i < blocks->length() - 1) next = blocks->at(i + 1);
+    DoBasicBlock(blocks->at(i), next);
+    if (is_aborted()) return NULL;
+  }
+  status_ = DONE;
+  return chunk_;
+}
+
+
+LUnallocated* LChunkBuilder::ToUnallocated(Register reg) {
+  return new (zone()) LUnallocated(LUnallocated::FIXED_REGISTER,
+                                   Register::ToAllocationIndex(reg));
+}
+
+
+LUnallocated* LChunkBuilder::ToUnallocated(DoubleRegister reg) {
+  return new (zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
+                                   DoubleRegister::ToAllocationIndex(reg));
+}
+
+
+LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) {
+  return Use(value, ToUnallocated(fixed_register));
+}
+
+
+LOperand* LChunkBuilder::UseFixedDouble(HValue* value, DoubleRegister reg) {
+  return Use(value, ToUnallocated(reg));
+}
+
+
+LOperand* LChunkBuilder::UseRegister(HValue* value) {
+  return Use(value,
+             new (zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
+}
+
+
+LOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) {
+  return Use(value, new (zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER,
+                                              LUnallocated::USED_AT_START));
+}
+
+
+LOperand* LChunkBuilder::UseTempRegister(HValue* value) {
+  return Use(value, new (zone()) LUnallocated(LUnallocated::WRITABLE_REGISTER));
+}
+
+
+LOperand* LChunkBuilder::Use(HValue* value) {
+  return Use(value, new (zone()) LUnallocated(LUnallocated::NONE));
+}
+
+
+LOperand* LChunkBuilder::UseAtStart(HValue* value) {
+  return Use(value, new (zone())
+             LUnallocated(LUnallocated::NONE, LUnallocated::USED_AT_START));
+}
+
+
+LOperand* LChunkBuilder::UseOrConstant(HValue* value) {
+  return value->IsConstant()
+             ? chunk_->DefineConstantOperand(HConstant::cast(value))
+             : Use(value);
+}
+
+
+LOperand* LChunkBuilder::UseOrConstantAtStart(HValue* value) {
+  return value->IsConstant()
+             ? chunk_->DefineConstantOperand(HConstant::cast(value))
+             : UseAtStart(value);
+}
+
+
+LOperand* LChunkBuilder::UseRegisterOrConstant(HValue* value) {
+  return value->IsConstant()
+             ? chunk_->DefineConstantOperand(HConstant::cast(value))
+             : UseRegister(value);
+}
+
+
+LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) {
+  return value->IsConstant()
+             ? chunk_->DefineConstantOperand(HConstant::cast(value))
+             : UseRegisterAtStart(value);
+}
+
+
+LOperand* LChunkBuilder::UseConstant(HValue* value) {
+  return chunk_->DefineConstantOperand(HConstant::cast(value));
+}
+
+
+LOperand* LChunkBuilder::UseAny(HValue* value) {
+  return value->IsConstant()
+             ? chunk_->DefineConstantOperand(HConstant::cast(value))
+             : Use(value, new (zone()) LUnallocated(LUnallocated::ANY));
+}
+
+
+LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) {
+  if (value->EmitAtUses()) {
+    HInstruction* instr = HInstruction::cast(value);
+    VisitInstruction(instr);
+  }
+  operand->set_virtual_register(value->id());
+  return operand;
+}
+
+
+LInstruction* LChunkBuilder::Define(LTemplateResultInstruction<1>* instr,
+                                    LUnallocated* result) {
+  result->set_virtual_register(current_instruction_->id());
+  instr->set_result(result);
+  return instr;
+}
+
+
+LInstruction* LChunkBuilder::DefineAsRegister(
+    LTemplateResultInstruction<1>* instr) {
+  return Define(instr,
+                new (zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
+}
+
+
+LInstruction* LChunkBuilder::DefineAsSpilled(
+    LTemplateResultInstruction<1>* instr, int index) {
+  return Define(instr,
+                new (zone()) LUnallocated(LUnallocated::FIXED_SLOT, index));
+}
+
+
+LInstruction* LChunkBuilder::DefineSameAsFirst(
+    LTemplateResultInstruction<1>* instr) {
+  return Define(instr,
+                new (zone()) LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT));
+}
+
+
+LInstruction* LChunkBuilder::DefineFixed(LTemplateResultInstruction<1>* instr,
+                                         Register reg) {
+  return Define(instr, ToUnallocated(reg));
+}
+
+
+LInstruction* LChunkBuilder::DefineFixedDouble(
+    LTemplateResultInstruction<1>* instr, DoubleRegister reg) {
+  return Define(instr, ToUnallocated(reg));
+}
+
+
+LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
+  HEnvironment* hydrogen_env = current_block_->last_environment();
+  int argument_index_accumulator = 0;
+  ZoneList<HValue*> objects_to_materialize(0, zone());
+  instr->set_environment(CreateEnvironment(
+      hydrogen_env, &argument_index_accumulator, &objects_to_materialize));
+  return instr;
+}
+
+
+LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
+                                        HInstruction* hinstr,
+                                        CanDeoptimize can_deoptimize) {
+  info()->MarkAsNonDeferredCalling();
+#ifdef DEBUG
+  instr->VerifyCall();
+#endif
+  instr->MarkAsCall();
+  instr = AssignPointerMap(instr);
+
+  // If instruction does not have side-effects lazy deoptimization
+  // after the call will try to deoptimize to the point before the call.
+  // Thus we still need to attach environment to this call even if
+  // call sequence can not deoptimize eagerly.
+  bool needs_environment = (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) ||
+                           !hinstr->HasObservableSideEffects();
+  if (needs_environment && !instr->HasEnvironment()) {
+    instr = AssignEnvironment(instr);
+    // We can't really figure out if the environment is needed or not.
+    instr->environment()->set_has_been_used();
+  }
+
+  return instr;
+}
+
+
+LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
+  DCHECK(!instr->HasPointerMap());
+  instr->set_pointer_map(new (zone()) LPointerMap(zone()));
+  return instr;
+}
+
+
+LUnallocated* LChunkBuilder::TempRegister() {
+  LUnallocated* operand =
+      new (zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER);
+  int vreg = allocator_->GetVirtualRegister();
+  if (!allocator_->AllocationOk()) {
+    Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister);
+    vreg = 0;
+  }
+  operand->set_virtual_register(vreg);
+  return operand;
+}
+
+
+LUnallocated* LChunkBuilder::TempDoubleRegister() {
+  LUnallocated* operand =
+      new (zone()) LUnallocated(LUnallocated::MUST_HAVE_DOUBLE_REGISTER);
+  int vreg = allocator_->GetVirtualRegister();
+  if (!allocator_->AllocationOk()) {
+    Abort(kOutOfVirtualRegistersWhileTryingToAllocateTempRegister);
+    vreg = 0;
+  }
+  operand->set_virtual_register(vreg);
+  return operand;
+}
+
+
+LOperand* LChunkBuilder::FixedTemp(Register reg) {
+  LUnallocated* operand = ToUnallocated(reg);
+  DCHECK(operand->HasFixedPolicy());
+  return operand;
+}
+
+
+LOperand* LChunkBuilder::FixedTemp(DoubleRegister reg) {
+  LUnallocated* operand = ToUnallocated(reg);
+  DCHECK(operand->HasFixedPolicy());
+  return operand;
+}
+
+
+LInstruction* LChunkBuilder::DoBlockEntry(HBlockEntry* instr) {
+  return new (zone()) LLabel(instr->block());
+}
+
+
+LInstruction* LChunkBuilder::DoDummyUse(HDummyUse* instr) {
+  return DefineAsRegister(new (zone()) LDummyUse(UseAny(instr->value())));
+}
+
+
+LInstruction* LChunkBuilder::DoEnvironmentMarker(HEnvironmentMarker* instr) {
+  UNREACHABLE();
+  return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
+  return AssignEnvironment(new (zone()) LDeoptimize);
+}
+
+
+LInstruction* LChunkBuilder::DoShift(Token::Value op,
+                                     HBitwiseBinaryOperation* instr) {
+  if (instr->representation().IsSmiOrInteger32()) {
+    DCHECK(instr->left()->representation().Equals(instr->representation()));
+    DCHECK(instr->right()->representation().Equals(instr->representation()));
+    LOperand* left = UseRegisterAtStart(instr->left());
+
+    HValue* right_value = instr->right();
+    LOperand* right = NULL;
+    int constant_value = 0;
+    bool does_deopt = false;
+    if (right_value->IsConstant()) {
+      HConstant* constant = HConstant::cast(right_value);
+      right = chunk_->DefineConstantOperand(constant);
+      constant_value = constant->Integer32Value() & 0x1f;
+      // Left shifts can deoptimize if we shift by > 0 and the result cannot be
+      // truncated to smi.
+      if (instr->representation().IsSmi() && constant_value > 0) {
+        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToSmi);
+      }
+    } else {
+      right = UseRegisterAtStart(right_value);
+    }
+
+    // Shift operations can only deoptimize if we do a logical shift
+    // by 0 and the result cannot be truncated to int32.
+    if (op == Token::SHR && constant_value == 0) {
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
+    }
+
+    LInstruction* result =
+        DefineAsRegister(new (zone()) LShiftI(op, left, right, does_deopt));
+    return does_deopt ? AssignEnvironment(result) : result;
+  } else {
+    return DoArithmeticT(op, instr);
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
+                                           HArithmeticBinaryOperation* instr) {
+  DCHECK(instr->representation().IsDouble());
+  DCHECK(instr->left()->representation().IsDouble());
+  DCHECK(instr->right()->representation().IsDouble());
+  if (op == Token::MOD) {
+    LOperand* left = UseFixedDouble(instr->left(), d1);
+    LOperand* right = UseFixedDouble(instr->right(), d2);
+    LArithmeticD* result = new (zone()) LArithmeticD(op, left, right);
+    // We call a C function for double modulo. It can't trigger a GC. We need
+    // to use fixed result register for the call.
+    // TODO(fschneider): Allow any register as input registers.
+    return MarkAsCall(DefineFixedDouble(result, d1), instr);
+  } else {
+    LOperand* left = UseRegisterAtStart(instr->left());
+    LOperand* right = UseRegisterAtStart(instr->right());
+    LArithmeticD* result = new (zone()) LArithmeticD(op, left, right);
+    return DefineAsRegister(result);
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
+                                           HBinaryOperation* instr) {
+  HValue* left = instr->left();
+  HValue* right = instr->right();
+  DCHECK(left->representation().IsTagged());
+  DCHECK(right->representation().IsTagged());
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* left_operand = UseFixed(left, r4);
+  LOperand* right_operand = UseFixed(right, r3);
+  LArithmeticT* result =
+      new (zone()) LArithmeticT(op, context, left_operand, right_operand);
+  return MarkAsCall(DefineFixed(result, r3), instr);
+}
+
+
+void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
+  DCHECK(is_building());
+  current_block_ = block;
+  next_block_ = next_block;
+  if (block->IsStartBlock()) {
+    block->UpdateEnvironment(graph_->start_environment());
+    argument_count_ = 0;
+  } else if (block->predecessors()->length() == 1) {
+    // We have a single predecessor => copy environment and outgoing
+    // argument count from the predecessor.
+    DCHECK(block->phis()->length() == 0);
+    HBasicBlock* pred = block->predecessors()->at(0);
+    HEnvironment* last_environment = pred->last_environment();
+    DCHECK(last_environment != NULL);
+    // Only copy the environment, if it is later used again.
+    if (pred->end()->SecondSuccessor() == NULL) {
+      DCHECK(pred->end()->FirstSuccessor() == block);
+    } else {
+      if (pred->end()->FirstSuccessor()->block_id() > block->block_id() ||
+          pred->end()->SecondSuccessor()->block_id() > block->block_id()) {
+        last_environment = last_environment->Copy();
+      }
+    }
+    block->UpdateEnvironment(last_environment);
+    DCHECK(pred->argument_count() >= 0);
+    argument_count_ = pred->argument_count();
+  } else {
+    // We are at a state join => process phis.
+    HBasicBlock* pred = block->predecessors()->at(0);
+    // No need to copy the environment, it cannot be used later.
+    HEnvironment* last_environment = pred->last_environment();
+    for (int i = 0; i < block->phis()->length(); ++i) {
+      HPhi* phi = block->phis()->at(i);
+      if (phi->HasMergedIndex()) {
+        last_environment->SetValueAt(phi->merged_index(), phi);
+      }
+    }
+    for (int i = 0; i < block->deleted_phis()->length(); ++i) {
+      if (block->deleted_phis()->at(i) < last_environment->length()) {
+        last_environment->SetValueAt(block->deleted_phis()->at(i),
+                                     graph_->GetConstantUndefined());
+      }
+    }
+    block->UpdateEnvironment(last_environment);
+    // Pick up the outgoing argument count of one of the predecessors.
+    argument_count_ = pred->argument_count();
+  }
+  HInstruction* current = block->first();
+  int start = chunk_->instructions()->length();
+  while (current != NULL && !is_aborted()) {
+    // Code for constants in registers is generated lazily.
+    if (!current->EmitAtUses()) {
+      VisitInstruction(current);
+    }
+    current = current->next();
+  }
+  int end = chunk_->instructions()->length() - 1;
+  if (end >= start) {
+    block->set_first_instruction_index(start);
+    block->set_last_instruction_index(end);
+  }
+  block->set_argument_count(argument_count_);
+  next_block_ = NULL;
+  current_block_ = NULL;
+}
+
+
+void LChunkBuilder::VisitInstruction(HInstruction* current) {
+  HInstruction* old_current = current_instruction_;
+  current_instruction_ = current;
+
+  LInstruction* instr = NULL;
+  if (current->CanReplaceWithDummyUses()) {
+    if (current->OperandCount() == 0) {
+      instr = DefineAsRegister(new (zone()) LDummy());
+    } else {
+      DCHECK(!current->OperandAt(0)->IsControlInstruction());
+      instr = DefineAsRegister(new (zone())
+                               LDummyUse(UseAny(current->OperandAt(0))));
+    }
+    for (int i = 1; i < current->OperandCount(); ++i) {
+      if (current->OperandAt(i)->IsControlInstruction()) continue;
+      LInstruction* dummy =
+          new (zone()) LDummyUse(UseAny(current->OperandAt(i)));
+      dummy->set_hydrogen_value(current);
+      chunk_->AddInstruction(dummy, current_block_);
+    }
+  } else {
+    HBasicBlock* successor;
+    if (current->IsControlInstruction() &&
+        HControlInstruction::cast(current)->KnownSuccessorBlock(&successor) &&
+        successor != NULL) {
+      instr = new (zone()) LGoto(successor);
+    } else {
+      instr = current->CompileToLithium(this);
+    }
+  }
+
+  argument_count_ += current->argument_delta();
+  DCHECK(argument_count_ >= 0);
+
+  if (instr != NULL) {
+    AddInstruction(instr, current);
+  }
+
+  current_instruction_ = old_current;
+}
+
+
+void LChunkBuilder::AddInstruction(LInstruction* instr,
+                                   HInstruction* hydrogen_val) {
+  // Associate the hydrogen instruction first, since we may need it for
+  // the ClobbersRegisters() or ClobbersDoubleRegisters() calls below.
+  instr->set_hydrogen_value(hydrogen_val);
+
+#if DEBUG
+  // Make sure that the lithium instruction has either no fixed register
+  // constraints in temps or the result OR no uses that are only used at
+  // start. If this invariant doesn't hold, the register allocator can decide
+  // to insert a split of a range immediately before the instruction due to an
+  // already allocated register needing to be used for the instruction's fixed
+  // register constraint. In this case, The register allocator won't see an
+  // interference between the split child and the use-at-start (it would if
+  // the it was just a plain use), so it is free to move the split child into
+  // the same register that is used for the use-at-start.
+  // See https://code.google.com/p/chromium/issues/detail?id=201590
+  if (!(instr->ClobbersRegisters() &&
+        instr->ClobbersDoubleRegisters(isolate()))) {
+    int fixed = 0;
+    int used_at_start = 0;
+    for (UseIterator it(instr); !it.Done(); it.Advance()) {
+      LUnallocated* operand = LUnallocated::cast(it.Current());
+      if (operand->IsUsedAtStart()) ++used_at_start;
+    }
+    if (instr->Output() != NULL) {
+      if (LUnallocated::cast(instr->Output())->HasFixedPolicy()) ++fixed;
+    }
+    for (TempIterator it(instr); !it.Done(); it.Advance()) {
+      LUnallocated* operand = LUnallocated::cast(it.Current());
+      if (operand->HasFixedPolicy()) ++fixed;
+    }
+    DCHECK(fixed == 0 || used_at_start == 0);
+  }
+#endif
+
+  if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
+    instr = AssignPointerMap(instr);
+  }
+  if (FLAG_stress_environments && !instr->HasEnvironment()) {
+    instr = AssignEnvironment(instr);
+  }
+  chunk_->AddInstruction(instr, current_block_);
+
+  if (instr->IsCall()) {
+    HValue* hydrogen_value_for_lazy_bailout = hydrogen_val;
+    LInstruction* instruction_needing_environment = NULL;
+    if (hydrogen_val->HasObservableSideEffects()) {
+      HSimulate* sim = HSimulate::cast(hydrogen_val->next());
+      instruction_needing_environment = instr;
+      sim->ReplayEnvironment(current_block_->last_environment());
+      hydrogen_value_for_lazy_bailout = sim;
+    }
+    LInstruction* bailout = AssignEnvironment(new (zone()) LLazyBailout());
+    bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
+    chunk_->AddInstruction(bailout, current_block_);
+    if (instruction_needing_environment != NULL) {
+      // Store the lazy deopt environment with the instruction if needed.
+      // Right now it is only used for LInstanceOfKnownGlobal.
+      instruction_needing_environment->SetDeferredLazyDeoptimizationEnvironment(
+          bailout->environment());
+    }
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
+  return new (zone()) LGoto(instr->FirstSuccessor());
+}
+
+
+LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
+  HValue* value = instr->value();
+  Representation r = value->representation();
+  HType type = value->type();
+  ToBooleanStub::Types expected = instr->expected_input_types();
+  if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
+
+  bool easy_case = !r.IsTagged() || type.IsBoolean() || type.IsSmi() ||
+                   type.IsJSArray() || type.IsHeapNumber() || type.IsString();
+  LInstruction* branch = new (zone()) LBranch(UseRegister(value));
+  if (!easy_case &&
+      ((!expected.Contains(ToBooleanStub::SMI) && expected.NeedsMap()) ||
+       !expected.IsGeneric())) {
+    branch = AssignEnvironment(branch);
+  }
+  return branch;
+}
+
+
+LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
+  return new (zone()) LDebugBreak();
+}
+
+
+LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
+  DCHECK(instr->value()->representation().IsTagged());
+  LOperand* value = UseRegisterAtStart(instr->value());
+  LOperand* temp = TempRegister();
+  return new (zone()) LCmpMapAndBranch(value, temp);
+}
+
+
+LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* instr) {
+  info()->MarkAsRequiresFrame();
+  LOperand* value = UseRegister(instr->value());
+  return DefineAsRegister(new (zone()) LArgumentsLength(value));
+}
+
+
+LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
+  info()->MarkAsRequiresFrame();
+  return DefineAsRegister(new (zone()) LArgumentsElements);
+}
+
+
+LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LInstanceOf* result = new (zone()) LInstanceOf(
+      context, UseFixed(instr->left(), r3), UseFixed(instr->right(), r4));
+  return MarkAsCall(DefineFixed(result, r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
+    HInstanceOfKnownGlobal* instr) {
+  LInstanceOfKnownGlobal* result = new (zone())
+      LInstanceOfKnownGlobal(UseFixed(instr->context(), cp),
+                             UseFixed(instr->left(), r3), FixedTemp(r7));
+  return MarkAsCall(DefineFixed(result, r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoWrapReceiver(HWrapReceiver* instr) {
+  LOperand* receiver = UseRegisterAtStart(instr->receiver());
+  LOperand* function = UseRegisterAtStart(instr->function());
+  LWrapReceiver* result = new (zone()) LWrapReceiver(receiver, function);
+  return AssignEnvironment(DefineAsRegister(result));
+}
+
+
+LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
+  LOperand* function = UseFixed(instr->function(), r4);
+  LOperand* receiver = UseFixed(instr->receiver(), r3);
+  LOperand* length = UseFixed(instr->length(), r5);
+  LOperand* elements = UseFixed(instr->elements(), r6);
+  LApplyArguments* result =
+      new (zone()) LApplyArguments(function, receiver, length, elements);
+  return MarkAsCall(DefineFixed(result, r3), instr, CAN_DEOPTIMIZE_EAGERLY);
+}
+
+
+LInstruction* LChunkBuilder::DoPushArguments(HPushArguments* instr) {
+  int argc = instr->OperandCount();
+  for (int i = 0; i < argc; ++i) {
+    LOperand* argument = Use(instr->argument(i));
+    AddInstruction(new (zone()) LPushArgument(argument), instr);
+  }
+  return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoStoreCodeEntry(
+    HStoreCodeEntry* store_code_entry) {
+  LOperand* function = UseRegister(store_code_entry->function());
+  LOperand* code_object = UseTempRegister(store_code_entry->code_object());
+  return new (zone()) LStoreCodeEntry(function, code_object);
+}
+
+
+LInstruction* LChunkBuilder::DoInnerAllocatedObject(
+    HInnerAllocatedObject* instr) {
+  LOperand* base_object = UseRegisterAtStart(instr->base_object());
+  LOperand* offset = UseRegisterOrConstantAtStart(instr->offset());
+  return DefineAsRegister(new (zone())
+                          LInnerAllocatedObject(base_object, offset));
+}
+
+
+LInstruction* LChunkBuilder::DoThisFunction(HThisFunction* instr) {
+  return instr->HasNoUses() ? NULL
+                            : DefineAsRegister(new (zone()) LThisFunction);
+}
+
+
+LInstruction* LChunkBuilder::DoContext(HContext* instr) {
+  if (instr->HasNoUses()) return NULL;
+
+  if (info()->IsStub()) {
+    return DefineFixed(new (zone()) LContext, cp);
+  }
+
+  return DefineAsRegister(new (zone()) LContext);
+}
+
+
+LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  return MarkAsCall(new (zone()) LDeclareGlobals(context), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoCallJSFunction(HCallJSFunction* instr) {
+  LOperand* function = UseFixed(instr->function(), r4);
+
+  LCallJSFunction* result = new (zone()) LCallJSFunction(function);
+
+  return MarkAsCall(DefineFixed(result, r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoCallWithDescriptor(HCallWithDescriptor* instr) {
+  CallInterfaceDescriptor descriptor = instr->descriptor();
+
+  LOperand* target = UseRegisterOrConstantAtStart(instr->target());
+  ZoneList<LOperand*> ops(instr->OperandCount(), zone());
+  ops.Add(target, zone());
+  for (int i = 1; i < instr->OperandCount(); i++) {
+    LOperand* op =
+        UseFixed(instr->OperandAt(i), descriptor.GetParameterRegister(i - 1));
+    ops.Add(op, zone());
+  }
+
+  LCallWithDescriptor* result =
+      new (zone()) LCallWithDescriptor(descriptor, ops, zone());
+  return MarkAsCall(DefineFixed(result, r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoTailCallThroughMegamorphicCache(
+    HTailCallThroughMegamorphicCache* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* receiver_register =
+      UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
+  LOperand* name_register =
+      UseFixed(instr->name(), LoadDescriptor::NameRegister());
+  // Not marked as call. It can't deoptimize, and it never returns.
+  return new (zone()) LTailCallThroughMegamorphicCache(
+      context, receiver_register, name_register);
+}
+
+
+LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* function = UseFixed(instr->function(), r4);
+  LInvokeFunction* result = new (zone()) LInvokeFunction(context, function);
+  return MarkAsCall(DefineFixed(result, r3), instr, CANNOT_DEOPTIMIZE_EAGERLY);
+}
+
+
+LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
+  switch (instr->op()) {
+    case kMathFloor:
+      return DoMathFloor(instr);
+    case kMathRound:
+      return DoMathRound(instr);
+    case kMathFround:
+      return DoMathFround(instr);
+    case kMathAbs:
+      return DoMathAbs(instr);
+    case kMathLog:
+      return DoMathLog(instr);
+    case kMathExp:
+      return DoMathExp(instr);
+    case kMathSqrt:
+      return DoMathSqrt(instr);
+    case kMathPowHalf:
+      return DoMathPowHalf(instr);
+    case kMathClz32:
+      return DoMathClz32(instr);
+    default:
+      UNREACHABLE();
+      return NULL;
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoMathFloor(HUnaryMathOperation* instr) {
+  LOperand* input = UseRegister(instr->value());
+  LMathFloor* result = new (zone()) LMathFloor(input);
+  return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
+}
+
+
+LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) {
+  LOperand* input = UseRegister(instr->value());
+  LOperand* temp = TempDoubleRegister();
+  LMathRound* result = new (zone()) LMathRound(input, temp);
+  return AssignEnvironment(DefineAsRegister(result));
+}
+
+
+LInstruction* LChunkBuilder::DoMathFround(HUnaryMathOperation* instr) {
+  LOperand* input = UseRegister(instr->value());
+  LMathFround* result = new (zone()) LMathFround(input);
+  return DefineAsRegister(result);
+}
+
+
+LInstruction* LChunkBuilder::DoMathAbs(HUnaryMathOperation* instr) {
+  Representation r = instr->value()->representation();
+  LOperand* context = (r.IsDouble() || r.IsSmiOrInteger32())
+                          ? NULL
+                          : UseFixed(instr->context(), cp);
+  LOperand* input = UseRegister(instr->value());
+  LInstruction* result =
+      DefineAsRegister(new (zone()) LMathAbs(context, input));
+  if (!r.IsDouble() && !r.IsSmiOrInteger32()) result = AssignPointerMap(result);
+  if (!r.IsDouble()) result = AssignEnvironment(result);
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoMathLog(HUnaryMathOperation* instr) {
+  DCHECK(instr->representation().IsDouble());
+  DCHECK(instr->value()->representation().IsDouble());
+  LOperand* input = UseFixedDouble(instr->value(), d1);
+  return MarkAsCall(DefineFixedDouble(new (zone()) LMathLog(input), d1), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoMathClz32(HUnaryMathOperation* instr) {
+  LOperand* input = UseRegisterAtStart(instr->value());
+  LMathClz32* result = new (zone()) LMathClz32(input);
+  return DefineAsRegister(result);
+}
+
+
+LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
+  DCHECK(instr->representation().IsDouble());
+  DCHECK(instr->value()->representation().IsDouble());
+  LOperand* input = UseRegister(instr->value());
+  LOperand* temp1 = TempRegister();
+  LOperand* temp2 = TempRegister();
+  LOperand* double_temp = TempDoubleRegister();
+  LMathExp* result = new (zone()) LMathExp(input, double_temp, temp1, temp2);
+  return DefineAsRegister(result);
+}
+
+
+LInstruction* LChunkBuilder::DoMathSqrt(HUnaryMathOperation* instr) {
+  LOperand* input = UseRegisterAtStart(instr->value());
+  LMathSqrt* result = new (zone()) LMathSqrt(input);
+  return DefineAsRegister(result);
+}
+
+
+LInstruction* LChunkBuilder::DoMathPowHalf(HUnaryMathOperation* instr) {
+  LOperand* input = UseRegisterAtStart(instr->value());
+  LMathPowHalf* result = new (zone()) LMathPowHalf(input);
+  return DefineAsRegister(result);
+}
+
+
+LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* constructor = UseFixed(instr->constructor(), r4);
+  LCallNew* result = new (zone()) LCallNew(context, constructor);
+  return MarkAsCall(DefineFixed(result, r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* constructor = UseFixed(instr->constructor(), r4);
+  LCallNewArray* result = new (zone()) LCallNewArray(context, constructor);
+  return MarkAsCall(DefineFixed(result, r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* function = UseFixed(instr->function(), r4);
+  LCallFunction* call = new (zone()) LCallFunction(context, function);
+  return MarkAsCall(DefineFixed(call, r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoCallRuntime(HCallRuntime* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  return MarkAsCall(DefineFixed(new (zone()) LCallRuntime(context), r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoRor(HRor* instr) {
+  return DoShift(Token::ROR, instr);
+}
+
+
+LInstruction* LChunkBuilder::DoShr(HShr* instr) {
+  return DoShift(Token::SHR, instr);
+}
+
+
+LInstruction* LChunkBuilder::DoSar(HSar* instr) {
+  return DoShift(Token::SAR, instr);
+}
+
+
+LInstruction* LChunkBuilder::DoShl(HShl* instr) {
+  return DoShift(Token::SHL, instr);
+}
+
+
+LInstruction* LChunkBuilder::DoBitwise(HBitwise* instr) {
+  if (instr->representation().IsSmiOrInteger32()) {
+    DCHECK(instr->left()->representation().Equals(instr->representation()));
+    DCHECK(instr->right()->representation().Equals(instr->representation()));
+    DCHECK(instr->CheckFlag(HValue::kTruncatingToInt32));
+
+    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
+    LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
+    return DefineAsRegister(new (zone()) LBitI(left, right));
+  } else {
+    return DoArithmeticT(instr->op(), instr);
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoDivByPowerOf2I(HDiv* instr) {
+  DCHECK(instr->representation().IsSmiOrInteger32());
+  DCHECK(instr->left()->representation().Equals(instr->representation()));
+  DCHECK(instr->right()->representation().Equals(instr->representation()));
+  LOperand* dividend = UseRegister(instr->left());
+  int32_t divisor = instr->right()->GetInteger32Constant();
+  LInstruction* result =
+      DefineAsRegister(new (zone()) LDivByPowerOf2I(dividend, divisor));
+  if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+      (instr->CheckFlag(HValue::kCanOverflow) && divisor == -1) ||
+      (!instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32) &&
+       divisor != 1 && divisor != -1)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoDivByConstI(HDiv* instr) {
+  DCHECK(instr->representation().IsInteger32());
+  DCHECK(instr->left()->representation().Equals(instr->representation()));
+  DCHECK(instr->right()->representation().Equals(instr->representation()));
+  LOperand* dividend = UseRegister(instr->left());
+  int32_t divisor = instr->right()->GetInteger32Constant();
+  LInstruction* result =
+      DefineAsRegister(new (zone()) LDivByConstI(dividend, divisor));
+  if (divisor == 0 ||
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+      !instr->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoDivI(HDiv* instr) {
+  DCHECK(instr->representation().IsSmiOrInteger32());
+  DCHECK(instr->left()->representation().Equals(instr->representation()));
+  DCHECK(instr->right()->representation().Equals(instr->representation()));
+  LOperand* dividend = UseRegister(instr->left());
+  LOperand* divisor = UseRegister(instr->right());
+  LInstruction* result =
+      DefineAsRegister(new (zone()) LDivI(dividend, divisor));
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
+      (instr->CheckFlag(HValue::kCanOverflow) &&
+       !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32)) ||
+      (!instr->IsMathFloorOfDiv() &&
+       !instr->CheckFlag(HValue::kAllUsesTruncatingToInt32))) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
+  if (instr->representation().IsSmiOrInteger32()) {
+    if (instr->RightIsPowerOf2()) {
+      return DoDivByPowerOf2I(instr);
+    } else if (instr->right()->IsConstant()) {
+      return DoDivByConstI(instr);
+    } else {
+      return DoDivI(instr);
+    }
+  } else if (instr->representation().IsDouble()) {
+    return DoArithmeticD(Token::DIV, instr);
+  } else {
+    return DoArithmeticT(Token::DIV, instr);
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
+  LOperand* dividend = UseRegisterAtStart(instr->left());
+  int32_t divisor = instr->right()->GetInteger32Constant();
+  LInstruction* result =
+      DefineAsRegister(new (zone()) LFlooringDivByPowerOf2I(dividend, divisor));
+  if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
+      (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
+  DCHECK(instr->representation().IsInteger32());
+  DCHECK(instr->left()->representation().Equals(instr->representation()));
+  DCHECK(instr->right()->representation().Equals(instr->representation()));
+  LOperand* dividend = UseRegister(instr->left());
+  int32_t divisor = instr->right()->GetInteger32Constant();
+  LOperand* temp =
+      ((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
+       (divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive)))
+          ? NULL
+          : TempRegister();
+  LInstruction* result = DefineAsRegister(
+      new (zone()) LFlooringDivByConstI(dividend, divisor, temp));
+  if (divisor == 0 ||
+      (instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoFlooringDivI(HMathFloorOfDiv* instr) {
+  DCHECK(instr->representation().IsSmiOrInteger32());
+  DCHECK(instr->left()->representation().Equals(instr->representation()));
+  DCHECK(instr->right()->representation().Equals(instr->representation()));
+  LOperand* dividend = UseRegister(instr->left());
+  LOperand* divisor = UseRegister(instr->right());
+  LFlooringDivI* div = new (zone()) LFlooringDivI(dividend, divisor);
+  return AssignEnvironment(DefineAsRegister(div));
+}
+
+
+LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
+  if (instr->RightIsPowerOf2()) {
+    return DoFlooringDivByPowerOf2I(instr);
+  } else if (instr->right()->IsConstant()) {
+    return DoFlooringDivByConstI(instr);
+  } else {
+    return DoFlooringDivI(instr);
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoModByPowerOf2I(HMod* instr) {
+  DCHECK(instr->representation().IsSmiOrInteger32());
+  DCHECK(instr->left()->representation().Equals(instr->representation()));
+  DCHECK(instr->right()->representation().Equals(instr->representation()));
+  LOperand* dividend = UseRegisterAtStart(instr->left());
+  int32_t divisor = instr->right()->GetInteger32Constant();
+  LInstruction* result =
+      DefineSameAsFirst(new (zone()) LModByPowerOf2I(dividend, divisor));
+  if (instr->CheckFlag(HValue::kLeftCanBeNegative) &&
+      instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoModByConstI(HMod* instr) {
+  DCHECK(instr->representation().IsSmiOrInteger32());
+  DCHECK(instr->left()->representation().Equals(instr->representation()));
+  DCHECK(instr->right()->representation().Equals(instr->representation()));
+  LOperand* dividend = UseRegister(instr->left());
+  int32_t divisor = instr->right()->GetInteger32Constant();
+  LInstruction* result =
+      DefineAsRegister(new (zone()) LModByConstI(dividend, divisor));
+  if (divisor == 0 || instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoModI(HMod* instr) {
+  DCHECK(instr->representation().IsSmiOrInteger32());
+  DCHECK(instr->left()->representation().Equals(instr->representation()));
+  DCHECK(instr->right()->representation().Equals(instr->representation()));
+  LOperand* dividend = UseRegister(instr->left());
+  LOperand* divisor = UseRegister(instr->right());
+  LInstruction* result =
+      DefineAsRegister(new (zone()) LModI(dividend, divisor));
+  if (instr->CheckFlag(HValue::kCanBeDivByZero) ||
+      instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoMod(HMod* instr) {
+  if (instr->representation().IsSmiOrInteger32()) {
+    if (instr->RightIsPowerOf2()) {
+      return DoModByPowerOf2I(instr);
+    } else if (instr->right()->IsConstant()) {
+      return DoModByConstI(instr);
+    } else {
+      return DoModI(instr);
+    }
+  } else if (instr->representation().IsDouble()) {
+    return DoArithmeticD(Token::MOD, instr);
+  } else {
+    return DoArithmeticT(Token::MOD, instr);
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoMul(HMul* instr) {
+  if (instr->representation().IsSmiOrInteger32()) {
+    DCHECK(instr->left()->representation().Equals(instr->representation()));
+    DCHECK(instr->right()->representation().Equals(instr->representation()));
+    HValue* left = instr->BetterLeftOperand();
+    HValue* right = instr->BetterRightOperand();
+    LOperand* left_op;
+    LOperand* right_op;
+    bool can_overflow = instr->CheckFlag(HValue::kCanOverflow);
+    bool bailout_on_minus_zero = instr->CheckFlag(HValue::kBailoutOnMinusZero);
+
+    if (right->IsConstant()) {
+      HConstant* constant = HConstant::cast(right);
+      int32_t constant_value = constant->Integer32Value();
+      // Constants -1, 0 and 1 can be optimized if the result can overflow.
+      // For other constants, it can be optimized only without overflow.
+      if (!can_overflow || ((constant_value >= -1) && (constant_value <= 1))) {
+        left_op = UseRegisterAtStart(left);
+        right_op = UseConstant(right);
+      } else {
+        if (bailout_on_minus_zero) {
+          left_op = UseRegister(left);
+        } else {
+          left_op = UseRegisterAtStart(left);
+        }
+        right_op = UseRegister(right);
+      }
+    } else {
+      if (bailout_on_minus_zero) {
+        left_op = UseRegister(left);
+      } else {
+        left_op = UseRegisterAtStart(left);
+      }
+      right_op = UseRegister(right);
+    }
+    LMulI* mul = new (zone()) LMulI(left_op, right_op);
+    if (can_overflow || bailout_on_minus_zero) {
+      AssignEnvironment(mul);
+    }
+    return DefineAsRegister(mul);
+
+  } else if (instr->representation().IsDouble()) {
+    if (instr->HasOneUse() &&
+        (instr->uses().value()->IsAdd() || instr->uses().value()->IsSub())) {
+      HBinaryOperation* use = HBinaryOperation::cast(instr->uses().value());
+
+      if (use->IsAdd() && instr == use->left()) {
+        // This mul is the lhs of an add. The add and mul will be folded into a
+        // multiply-add in DoAdd.
+        return NULL;
+      }
+      if (instr == use->right() && use->IsAdd() &&
+          !(use->left()->IsMul() && use->left()->HasOneUse())) {
+        // This mul is the rhs of an add, where the lhs is not another mul.
+        // The add and mul will be folded into a multiply-add in DoAdd.
+        return NULL;
+      }
+      if (instr == use->left() && use->IsSub()) {
+        // This mul is the lhs of a sub. The mul and sub will be folded into a
+        // multiply-sub in DoSub.
+        return NULL;
+      }
+    }
+
+    return DoArithmeticD(Token::MUL, instr);
+  } else {
+    return DoArithmeticT(Token::MUL, instr);
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoSub(HSub* instr) {
+  if (instr->representation().IsSmiOrInteger32()) {
+    DCHECK(instr->left()->representation().Equals(instr->representation()));
+    DCHECK(instr->right()->representation().Equals(instr->representation()));
+
+    if (instr->left()->IsConstant() &&
+        !instr->CheckFlag(HValue::kCanOverflow)) {
+      // If lhs is constant, do reverse subtraction instead.
+      return DoRSub(instr);
+    }
+
+    LOperand* left = UseRegisterAtStart(instr->left());
+    LOperand* right = UseOrConstantAtStart(instr->right());
+    LSubI* sub = new (zone()) LSubI(left, right);
+    LInstruction* result = DefineAsRegister(sub);
+    if (instr->CheckFlag(HValue::kCanOverflow)) {
+      result = AssignEnvironment(result);
+    }
+    return result;
+  } else if (instr->representation().IsDouble()) {
+    if (instr->left()->IsMul() && instr->left()->HasOneUse()) {
+      return DoMultiplySub(instr->right(), HMul::cast(instr->left()));
+    }
+
+    return DoArithmeticD(Token::SUB, instr);
+  } else {
+    return DoArithmeticT(Token::SUB, instr);
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoRSub(HSub* instr) {
+  DCHECK(instr->representation().IsSmiOrInteger32());
+  DCHECK(instr->left()->representation().Equals(instr->representation()));
+  DCHECK(instr->right()->representation().Equals(instr->representation()));
+  DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
+
+  // Note: The lhs of the subtraction becomes the rhs of the
+  // reverse-subtraction.
+  LOperand* left = UseRegisterAtStart(instr->right());
+  LOperand* right = UseOrConstantAtStart(instr->left());
+  LRSubI* rsb = new (zone()) LRSubI(left, right);
+  LInstruction* result = DefineAsRegister(rsb);
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoMultiplyAdd(HMul* mul, HValue* addend) {
+  LOperand* multiplier_op = UseRegisterAtStart(mul->left());
+  LOperand* multiplicand_op = UseRegisterAtStart(mul->right());
+  LOperand* addend_op = UseRegisterAtStart(addend);
+  return DefineSameAsFirst(
+      new (zone()) LMultiplyAddD(addend_op, multiplier_op, multiplicand_op));
+}
+
+
+LInstruction* LChunkBuilder::DoMultiplySub(HValue* minuend, HMul* mul) {
+  LOperand* minuend_op = UseRegisterAtStart(minuend);
+  LOperand* multiplier_op = UseRegisterAtStart(mul->left());
+  LOperand* multiplicand_op = UseRegisterAtStart(mul->right());
+
+  return DefineSameAsFirst(
+      new (zone()) LMultiplySubD(minuend_op, multiplier_op, multiplicand_op));
+}
+
+
+LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
+  if (instr->representation().IsSmiOrInteger32()) {
+    DCHECK(instr->left()->representation().Equals(instr->representation()));
+    DCHECK(instr->right()->representation().Equals(instr->representation()));
+    LOperand* left = UseRegisterAtStart(instr->BetterLeftOperand());
+    LOperand* right = UseOrConstantAtStart(instr->BetterRightOperand());
+    LAddI* add = new (zone()) LAddI(left, right);
+    LInstruction* result = DefineAsRegister(add);
+    if (instr->CheckFlag(HValue::kCanOverflow)) {
+      result = AssignEnvironment(result);
+    }
+    return result;
+  } else if (instr->representation().IsExternal()) {
+    DCHECK(instr->left()->representation().IsExternal());
+    DCHECK(instr->right()->representation().IsInteger32());
+    DCHECK(!instr->CheckFlag(HValue::kCanOverflow));
+    LOperand* left = UseRegisterAtStart(instr->left());
+    LOperand* right = UseOrConstantAtStart(instr->right());
+    LAddI* add = new (zone()) LAddI(left, right);
+    LInstruction* result = DefineAsRegister(add);
+    return result;
+  } else if (instr->representation().IsDouble()) {
+    if (instr->left()->IsMul() && instr->left()->HasOneUse()) {
+      return DoMultiplyAdd(HMul::cast(instr->left()), instr->right());
+    }
+
+    if (instr->right()->IsMul() && instr->right()->HasOneUse()) {
+      DCHECK(!instr->left()->IsMul() || !instr->left()->HasOneUse());
+      return DoMultiplyAdd(HMul::cast(instr->right()), instr->left());
+    }
+
+    return DoArithmeticD(Token::ADD, instr);
+  } else {
+    return DoArithmeticT(Token::ADD, instr);
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoMathMinMax(HMathMinMax* instr) {
+  LOperand* left = NULL;
+  LOperand* right = NULL;
+  if (instr->representation().IsSmiOrInteger32()) {
+    DCHECK(instr->left()->representation().Equals(instr->representation()));
+    DCHECK(instr->right()->representation().Equals(instr->representation()));
+    left = UseRegisterAtStart(instr->BetterLeftOperand());
+    right = UseOrConstantAtStart(instr->BetterRightOperand());
+  } else {
+    DCHECK(instr->representation().IsDouble());
+    DCHECK(instr->left()->representation().IsDouble());
+    DCHECK(instr->right()->representation().IsDouble());
+    left = UseRegisterAtStart(instr->left());
+    right = UseRegisterAtStart(instr->right());
+  }
+  return DefineAsRegister(new (zone()) LMathMinMax(left, right));
+}
+
+
+LInstruction* LChunkBuilder::DoPower(HPower* instr) {
+  DCHECK(instr->representation().IsDouble());
+  // We call a C function for double power. It can't trigger a GC.
+  // We need to use fixed result register for the call.
+  Representation exponent_type = instr->right()->representation();
+  DCHECK(instr->left()->representation().IsDouble());
+  LOperand* left = UseFixedDouble(instr->left(), d1);
+  LOperand* right =
+      exponent_type.IsDouble()
+          ? UseFixedDouble(instr->right(), d2)
+          : UseFixed(instr->right(), MathPowTaggedDescriptor::exponent());
+  LPower* result = new (zone()) LPower(left, right);
+  return MarkAsCall(DefineFixedDouble(result, d3), instr,
+                    CAN_DEOPTIMIZE_EAGERLY);
+}
+
+
+LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
+  DCHECK(instr->left()->representation().IsTagged());
+  DCHECK(instr->right()->representation().IsTagged());
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* left = UseFixed(instr->left(), r4);
+  LOperand* right = UseFixed(instr->right(), r3);
+  LCmpT* result = new (zone()) LCmpT(context, left, right);
+  return MarkAsCall(DefineFixed(result, r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoCompareNumericAndBranch(
+    HCompareNumericAndBranch* instr) {
+  Representation r = instr->representation();
+  if (r.IsSmiOrInteger32()) {
+    DCHECK(instr->left()->representation().Equals(r));
+    DCHECK(instr->right()->representation().Equals(r));
+    LOperand* left = UseRegisterOrConstantAtStart(instr->left());
+    LOperand* right = UseRegisterOrConstantAtStart(instr->right());
+    return new (zone()) LCompareNumericAndBranch(left, right);
+  } else {
+    DCHECK(r.IsDouble());
+    DCHECK(instr->left()->representation().IsDouble());
+    DCHECK(instr->right()->representation().IsDouble());
+    LOperand* left = UseRegisterAtStart(instr->left());
+    LOperand* right = UseRegisterAtStart(instr->right());
+    return new (zone()) LCompareNumericAndBranch(left, right);
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoCompareObjectEqAndBranch(
+    HCompareObjectEqAndBranch* instr) {
+  LOperand* left = UseRegisterAtStart(instr->left());
+  LOperand* right = UseRegisterAtStart(instr->right());
+  return new (zone()) LCmpObjectEqAndBranch(left, right);
+}
+
+
+LInstruction* LChunkBuilder::DoCompareHoleAndBranch(
+    HCompareHoleAndBranch* instr) {
+  LOperand* value = UseRegisterAtStart(instr->value());
+  return new (zone()) LCmpHoleAndBranch(value);
+}
+
+
+LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
+    HCompareMinusZeroAndBranch* instr) {
+  LOperand* value = UseRegister(instr->value());
+  LOperand* scratch = TempRegister();
+  return new (zone()) LCompareMinusZeroAndBranch(value, scratch);
+}
+
+
+LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
+  DCHECK(instr->value()->representation().IsTagged());
+  LOperand* value = UseRegisterAtStart(instr->value());
+  LOperand* temp = TempRegister();
+  return new (zone()) LIsObjectAndBranch(value, temp);
+}
+
+
+LInstruction* LChunkBuilder::DoIsStringAndBranch(HIsStringAndBranch* instr) {
+  DCHECK(instr->value()->representation().IsTagged());
+  LOperand* value = UseRegisterAtStart(instr->value());
+  LOperand* temp = TempRegister();
+  return new (zone()) LIsStringAndBranch(value, temp);
+}
+
+
+LInstruction* LChunkBuilder::DoIsSmiAndBranch(HIsSmiAndBranch* instr) {
+  DCHECK(instr->value()->representation().IsTagged());
+  return new (zone()) LIsSmiAndBranch(Use(instr->value()));
+}
+
+
+LInstruction* LChunkBuilder::DoIsUndetectableAndBranch(
+    HIsUndetectableAndBranch* instr) {
+  DCHECK(instr->value()->representation().IsTagged());
+  LOperand* value = UseRegisterAtStart(instr->value());
+  return new (zone()) LIsUndetectableAndBranch(value, TempRegister());
+}
+
+
+LInstruction* LChunkBuilder::DoStringCompareAndBranch(
+    HStringCompareAndBranch* instr) {
+  DCHECK(instr->left()->representation().IsTagged());
+  DCHECK(instr->right()->representation().IsTagged());
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* left = UseFixed(instr->left(), r4);
+  LOperand* right = UseFixed(instr->right(), r3);
+  LStringCompareAndBranch* result =
+      new (zone()) LStringCompareAndBranch(context, left, right);
+  return MarkAsCall(result, instr);
+}
+
+
+LInstruction* LChunkBuilder::DoHasInstanceTypeAndBranch(
+    HHasInstanceTypeAndBranch* instr) {
+  DCHECK(instr->value()->representation().IsTagged());
+  LOperand* value = UseRegisterAtStart(instr->value());
+  return new (zone()) LHasInstanceTypeAndBranch(value);
+}
+
+
+LInstruction* LChunkBuilder::DoGetCachedArrayIndex(
+    HGetCachedArrayIndex* instr) {
+  DCHECK(instr->value()->representation().IsTagged());
+  LOperand* value = UseRegisterAtStart(instr->value());
+
+  return DefineAsRegister(new (zone()) LGetCachedArrayIndex(value));
+}
+
+
+LInstruction* LChunkBuilder::DoHasCachedArrayIndexAndBranch(
+    HHasCachedArrayIndexAndBranch* instr) {
+  DCHECK(instr->value()->representation().IsTagged());
+  return new (zone())
+      LHasCachedArrayIndexAndBranch(UseRegisterAtStart(instr->value()));
+}
+
+
+LInstruction* LChunkBuilder::DoClassOfTestAndBranch(
+    HClassOfTestAndBranch* instr) {
+  DCHECK(instr->value()->representation().IsTagged());
+  LOperand* value = UseRegister(instr->value());
+  return new (zone()) LClassOfTestAndBranch(value, TempRegister());
+}
+
+
+LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
+  LOperand* map = UseRegisterAtStart(instr->value());
+  return DefineAsRegister(new (zone()) LMapEnumLength(map));
+}
+
+
+LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
+  LOperand* object = UseFixed(instr->value(), r3);
+  LDateField* result =
+      new (zone()) LDateField(object, FixedTemp(r4), instr->index());
+  return MarkAsCall(DefineFixed(result, r3), instr, CAN_DEOPTIMIZE_EAGERLY);
+}
+
+
+LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
+  LOperand* string = UseRegisterAtStart(instr->string());
+  LOperand* index = UseRegisterOrConstantAtStart(instr->index());
+  return DefineAsRegister(new (zone()) LSeqStringGetChar(string, index));
+}
+
+
+LInstruction* LChunkBuilder::DoSeqStringSetChar(HSeqStringSetChar* instr) {
+  LOperand* string = UseRegisterAtStart(instr->string());
+  LOperand* index = FLAG_debug_code
+                        ? UseRegisterAtStart(instr->index())
+                        : UseRegisterOrConstantAtStart(instr->index());
+  LOperand* value = UseRegisterAtStart(instr->value());
+  LOperand* context = FLAG_debug_code ? UseFixed(instr->context(), cp) : NULL;
+  return new (zone()) LSeqStringSetChar(context, string, index, value);
+}
+
+
+LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
+  if (!FLAG_debug_code && instr->skip_check()) return NULL;
+  LOperand* index = UseRegisterOrConstantAtStart(instr->index());
+  LOperand* length = !index->IsConstantOperand()
+                         ? UseRegisterOrConstantAtStart(instr->length())
+                         : UseRegisterAtStart(instr->length());
+  LInstruction* result = new (zone()) LBoundsCheck(index, length);
+  if (!FLAG_debug_code || !instr->skip_check()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoBoundsCheckBaseIndexInformation(
+    HBoundsCheckBaseIndexInformation* instr) {
+  UNREACHABLE();
+  return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
+  // The control instruction marking the end of a block that completed
+  // abruptly (e.g., threw an exception).  There is nothing specific to do.
+  return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoUseConst(HUseConst* instr) { return NULL; }
+
+
+LInstruction* LChunkBuilder::DoForceRepresentation(HForceRepresentation* bad) {
+  // All HForceRepresentation instructions should be eliminated in the
+  // representation change phase of Hydrogen.
+  UNREACHABLE();
+  return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoChange(HChange* instr) {
+  Representation from = instr->from();
+  Representation to = instr->to();
+  HValue* val = instr->value();
+  if (from.IsSmi()) {
+    if (to.IsTagged()) {
+      LOperand* value = UseRegister(val);
+      return DefineSameAsFirst(new (zone()) LDummyUse(value));
+    }
+    from = Representation::Tagged();
+  }
+  if (from.IsTagged()) {
+    if (to.IsDouble()) {
+      LOperand* value = UseRegister(val);
+      LInstruction* result =
+          DefineAsRegister(new (zone()) LNumberUntagD(value));
+      if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+      return result;
+    } else if (to.IsSmi()) {
+      LOperand* value = UseRegister(val);
+      if (val->type().IsSmi()) {
+        return DefineSameAsFirst(new (zone()) LDummyUse(value));
+      }
+      return AssignEnvironment(
+          DefineSameAsFirst(new (zone()) LCheckSmi(value)));
+    } else {
+      DCHECK(to.IsInteger32());
+      if (val->type().IsSmi() || val->representation().IsSmi()) {
+        LOperand* value = UseRegisterAtStart(val);
+        return DefineAsRegister(new (zone()) LSmiUntag(value, false));
+      } else {
+        LOperand* value = UseRegister(val);
+        LOperand* temp1 = TempRegister();
+        LOperand* temp2 = TempDoubleRegister();
+        LInstruction* result =
+            DefineSameAsFirst(new (zone()) LTaggedToI(value, temp1, temp2));
+        if (!val->representation().IsSmi()) result = AssignEnvironment(result);
+        return result;
+      }
+    }
+  } else if (from.IsDouble()) {
+    if (to.IsTagged()) {
+      info()->MarkAsDeferredCalling();
+      LOperand* value = UseRegister(val);
+      LOperand* temp1 = TempRegister();
+      LOperand* temp2 = TempRegister();
+      LUnallocated* result_temp = TempRegister();
+      LNumberTagD* result = new (zone()) LNumberTagD(value, temp1, temp2);
+      return AssignPointerMap(Define(result, result_temp));
+    } else if (to.IsSmi()) {
+      LOperand* value = UseRegister(val);
+      return AssignEnvironment(
+          DefineAsRegister(new (zone()) LDoubleToSmi(value)));
+    } else {
+      DCHECK(to.IsInteger32());
+      LOperand* value = UseRegister(val);
+      LInstruction* result = DefineAsRegister(new (zone()) LDoubleToI(value));
+      if (!instr->CanTruncateToInt32()) result = AssignEnvironment(result);
+      return result;
+    }
+  } else if (from.IsInteger32()) {
+    info()->MarkAsDeferredCalling();
+    if (to.IsTagged()) {
+      if (!instr->CheckFlag(HValue::kCanOverflow)) {
+        LOperand* value = UseRegisterAtStart(val);
+        return DefineAsRegister(new (zone()) LSmiTag(value));
+      } else if (val->CheckFlag(HInstruction::kUint32)) {
+        LOperand* value = UseRegisterAtStart(val);
+        LOperand* temp1 = TempRegister();
+        LOperand* temp2 = TempRegister();
+        LNumberTagU* result = new (zone()) LNumberTagU(value, temp1, temp2);
+        return AssignPointerMap(DefineAsRegister(result));
+      } else {
+        LOperand* value = UseRegisterAtStart(val);
+        LOperand* temp1 = TempRegister();
+        LOperand* temp2 = TempRegister();
+        LNumberTagI* result = new (zone()) LNumberTagI(value, temp1, temp2);
+        return AssignPointerMap(DefineAsRegister(result));
+      }
+    } else if (to.IsSmi()) {
+      LOperand* value = UseRegister(val);
+      LInstruction* result = DefineAsRegister(new (zone()) LSmiTag(value));
+      if (instr->CheckFlag(HValue::kCanOverflow)) {
+        result = AssignEnvironment(result);
+      }
+      return result;
+    } else {
+      DCHECK(to.IsDouble());
+      if (val->CheckFlag(HInstruction::kUint32)) {
+        return DefineAsRegister(new (zone()) LUint32ToDouble(UseRegister(val)));
+      } else {
+        return DefineAsRegister(new (zone()) LInteger32ToDouble(Use(val)));
+      }
+    }
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoCheckHeapObject(HCheckHeapObject* instr) {
+  LOperand* value = UseRegisterAtStart(instr->value());
+  LInstruction* result = new (zone()) LCheckNonSmi(value);
+  if (!instr->value()->type().IsHeapObject()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
+  LOperand* value = UseRegisterAtStart(instr->value());
+  return AssignEnvironment(new (zone()) LCheckSmi(value));
+}
+
+
+LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
+  LOperand* value = UseRegisterAtStart(instr->value());
+  LInstruction* result = new (zone()) LCheckInstanceType(value);
+  return AssignEnvironment(result);
+}
+
+
+LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) {
+  LOperand* value = UseRegisterAtStart(instr->value());
+  return AssignEnvironment(new (zone()) LCheckValue(value));
+}
+
+
+LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
+  if (instr->IsStabilityCheck()) return new (zone()) LCheckMaps;
+  LOperand* value = UseRegisterAtStart(instr->value());
+  LInstruction* result = AssignEnvironment(new (zone()) LCheckMaps(value));
+  if (instr->HasMigrationTarget()) {
+    info()->MarkAsDeferredCalling();
+    result = AssignPointerMap(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) {
+  HValue* value = instr->value();
+  Representation input_rep = value->representation();
+  LOperand* reg = UseRegister(value);
+  if (input_rep.IsDouble()) {
+    return DefineAsRegister(new (zone()) LClampDToUint8(reg));
+  } else if (input_rep.IsInteger32()) {
+    return DefineAsRegister(new (zone()) LClampIToUint8(reg));
+  } else {
+    DCHECK(input_rep.IsSmiOrTagged());
+    LClampTToUint8* result =
+        new (zone()) LClampTToUint8(reg, TempDoubleRegister());
+    return AssignEnvironment(DefineAsRegister(result));
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) {
+  HValue* value = instr->value();
+  DCHECK(value->representation().IsDouble());
+  return DefineAsRegister(new (zone()) LDoubleBits(UseRegister(value)));
+}
+
+
+LInstruction* LChunkBuilder::DoConstructDouble(HConstructDouble* instr) {
+  LOperand* lo = UseRegister(instr->lo());
+  LOperand* hi = UseRegister(instr->hi());
+  return DefineAsRegister(new (zone()) LConstructDouble(hi, lo));
+}
+
+
+LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
+  LOperand* context = info()->IsStub() ? UseFixed(instr->context(), cp) : NULL;
+  LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count());
+  return new (zone())
+      LReturn(UseFixed(instr->value(), r3), context, parameter_count);
+}
+
+
+LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
+  Representation r = instr->representation();
+  if (r.IsSmi()) {
+    return DefineAsRegister(new (zone()) LConstantS);
+  } else if (r.IsInteger32()) {
+    return DefineAsRegister(new (zone()) LConstantI);
+  } else if (r.IsDouble()) {
+    return DefineAsRegister(new (zone()) LConstantD);
+  } else if (r.IsExternal()) {
+    return DefineAsRegister(new (zone()) LConstantE);
+  } else if (r.IsTagged()) {
+    return DefineAsRegister(new (zone()) LConstantT);
+  } else {
+    UNREACHABLE();
+    return NULL;
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
+  LLoadGlobalCell* result = new (zone()) LLoadGlobalCell;
+  return instr->RequiresHoleCheck()
+             ? AssignEnvironment(DefineAsRegister(result))
+             : DefineAsRegister(result);
+}
+
+
+LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* global_object =
+      UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister());
+  LOperand* vector = NULL;
+  if (FLAG_vector_ics) {
+    vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
+  }
+  LLoadGlobalGeneric* result =
+      new (zone()) LLoadGlobalGeneric(context, global_object, vector);
+  return MarkAsCall(DefineFixed(result, r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoStoreGlobalCell(HStoreGlobalCell* instr) {
+  LOperand* value = UseRegister(instr->value());
+  // Use a temp to check the value in the cell in the case where we perform
+  // a hole check.
+  return instr->RequiresHoleCheck()
+             ? AssignEnvironment(new (zone())
+                                 LStoreGlobalCell(value, TempRegister()))
+             : new (zone()) LStoreGlobalCell(value, NULL);
+}
+
+
+LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
+  LOperand* context = UseRegisterAtStart(instr->value());
+  LInstruction* result =
+      DefineAsRegister(new (zone()) LLoadContextSlot(context));
+  if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
+  LOperand* context;
+  LOperand* value;
+  if (instr->NeedsWriteBarrier()) {
+    context = UseTempRegister(instr->context());
+    value = UseTempRegister(instr->value());
+  } else {
+    context = UseRegister(instr->context());
+    value = UseRegister(instr->value());
+  }
+  LInstruction* result = new (zone()) LStoreContextSlot(context, value);
+  if (instr->RequiresHoleCheck() && instr->DeoptimizesOnHole()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
+  LOperand* obj = UseRegisterAtStart(instr->object());
+  return DefineAsRegister(new (zone()) LLoadNamedField(obj));
+}
+
+
+LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* object =
+      UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
+  LOperand* vector = NULL;
+  if (FLAG_vector_ics) {
+    vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
+  }
+
+  LInstruction* result =
+      DefineFixed(new (zone()) LLoadNamedGeneric(context, object, vector), r3);
+  return MarkAsCall(result, instr);
+}
+
+
+LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
+    HLoadFunctionPrototype* instr) {
+  return AssignEnvironment(DefineAsRegister(
+      new (zone()) LLoadFunctionPrototype(UseRegister(instr->function()))));
+}
+
+
+LInstruction* LChunkBuilder::DoLoadRoot(HLoadRoot* instr) {
+  return DefineAsRegister(new (zone()) LLoadRoot);
+}
+
+
+LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
+  DCHECK(instr->key()->representation().IsSmiOrInteger32());
+  ElementsKind elements_kind = instr->elements_kind();
+  LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+  LInstruction* result = NULL;
+
+  if (!instr->is_typed_elements()) {
+    LOperand* obj = NULL;
+    if (instr->representation().IsDouble()) {
+      obj = UseRegister(instr->elements());
+    } else {
+      obj = UseRegisterAtStart(instr->elements());
+    }
+    result = DefineAsRegister(new (zone()) LLoadKeyed(obj, key));
+  } else {
+    DCHECK((instr->representation().IsInteger32() &&
+            !IsDoubleOrFloatElementsKind(elements_kind)) ||
+           (instr->representation().IsDouble() &&
+            IsDoubleOrFloatElementsKind(elements_kind)));
+    LOperand* backing_store = UseRegister(instr->elements());
+    result = DefineAsRegister(new (zone()) LLoadKeyed(backing_store, key));
+  }
+
+  if ((instr->is_external() || instr->is_fixed_typed_array())
+          ?
+          // see LCodeGen::DoLoadKeyedExternalArray
+          ((elements_kind == EXTERNAL_UINT32_ELEMENTS ||
+            elements_kind == UINT32_ELEMENTS) &&
+           !instr->CheckFlag(HInstruction::kUint32))
+          :
+          // see LCodeGen::DoLoadKeyedFixedDoubleArray and
+          // LCodeGen::DoLoadKeyedFixedArray
+          instr->RequiresHoleCheck()) {
+    result = AssignEnvironment(result);
+  }
+  return result;
+}
+
+
+LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* object =
+      UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
+  LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
+  LOperand* vector = NULL;
+  if (FLAG_vector_ics) {
+    vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
+  }
+
+  LInstruction* result = DefineFixed(
+      new (zone()) LLoadKeyedGeneric(context, object, key, vector), r3);
+  return MarkAsCall(result, instr);
+}
+
+
+LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
+  if (!instr->is_typed_elements()) {
+    DCHECK(instr->elements()->representation().IsTagged());
+    bool needs_write_barrier = instr->NeedsWriteBarrier();
+    LOperand* object = NULL;
+    LOperand* key = NULL;
+    LOperand* val = NULL;
+
+    if (instr->value()->representation().IsDouble()) {
+      object = UseRegisterAtStart(instr->elements());
+      val = UseRegister(instr->value());
+      key = UseRegisterOrConstantAtStart(instr->key());
+    } else {
+      if (needs_write_barrier) {
+        object = UseTempRegister(instr->elements());
+        val = UseTempRegister(instr->value());
+        key = UseTempRegister(instr->key());
+      } else {
+        object = UseRegisterAtStart(instr->elements());
+        val = UseRegisterAtStart(instr->value());
+        key = UseRegisterOrConstantAtStart(instr->key());
+      }
+    }
+
+    return new (zone()) LStoreKeyed(object, key, val);
+  }
+
+  DCHECK((instr->value()->representation().IsInteger32() &&
+          !IsDoubleOrFloatElementsKind(instr->elements_kind())) ||
+         (instr->value()->representation().IsDouble() &&
+          IsDoubleOrFloatElementsKind(instr->elements_kind())));
+  DCHECK((instr->is_fixed_typed_array() &&
+          instr->elements()->representation().IsTagged()) ||
+         (instr->is_external() &&
+          instr->elements()->representation().IsExternal()));
+  LOperand* val = UseRegister(instr->value());
+  LOperand* key = UseRegisterOrConstantAtStart(instr->key());
+  LOperand* backing_store = UseRegister(instr->elements());
+  return new (zone()) LStoreKeyed(backing_store, key, val);
+}
+
+
+LInstruction* LChunkBuilder::DoStoreKeyedGeneric(HStoreKeyedGeneric* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* obj =
+      UseFixed(instr->object(), StoreDescriptor::ReceiverRegister());
+  LOperand* key = UseFixed(instr->key(), StoreDescriptor::NameRegister());
+  LOperand* val = UseFixed(instr->value(), StoreDescriptor::ValueRegister());
+
+  DCHECK(instr->object()->representation().IsTagged());
+  DCHECK(instr->key()->representation().IsTagged());
+  DCHECK(instr->value()->representation().IsTagged());
+
+  return MarkAsCall(new (zone()) LStoreKeyedGeneric(context, obj, key, val),
+                    instr);
+}
+
+
+LInstruction* LChunkBuilder::DoTransitionElementsKind(
+    HTransitionElementsKind* instr) {
+  if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
+    LOperand* object = UseRegister(instr->object());
+    LOperand* new_map_reg = TempRegister();
+    LTransitionElementsKind* result =
+        new (zone()) LTransitionElementsKind(object, NULL, new_map_reg);
+    return result;
+  } else {
+    LOperand* object = UseFixed(instr->object(), r3);
+    LOperand* context = UseFixed(instr->context(), cp);
+    LTransitionElementsKind* result =
+        new (zone()) LTransitionElementsKind(object, context, NULL);
+    return MarkAsCall(result, instr);
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoTrapAllocationMemento(
+    HTrapAllocationMemento* instr) {
+  LOperand* object = UseRegister(instr->object());
+  LOperand* temp = TempRegister();
+  LTrapAllocationMemento* result =
+      new (zone()) LTrapAllocationMemento(object, temp);
+  return AssignEnvironment(result);
+}
+
+
+LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
+  bool is_in_object = instr->access().IsInobject();
+  bool needs_write_barrier = instr->NeedsWriteBarrier();
+  bool needs_write_barrier_for_map =
+      instr->has_transition() && instr->NeedsWriteBarrierForMap();
+
+  LOperand* obj;
+  if (needs_write_barrier) {
+    obj = is_in_object ? UseRegister(instr->object())
+                       : UseTempRegister(instr->object());
+  } else {
+    obj = needs_write_barrier_for_map ? UseRegister(instr->object())
+                                      : UseRegisterAtStart(instr->object());
+  }
+
+  LOperand* val;
+  if (needs_write_barrier) {
+    val = UseTempRegister(instr->value());
+  } else if (instr->field_representation().IsDouble()) {
+    val = UseRegisterAtStart(instr->value());
+  } else {
+    val = UseRegister(instr->value());
+  }
+
+  // We need a temporary register for write barrier of the map field.
+  LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;
+
+  return new (zone()) LStoreNamedField(obj, val, temp);
+}
+
+
+LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* obj =
+      UseFixed(instr->object(), StoreDescriptor::ReceiverRegister());
+  LOperand* val = UseFixed(instr->value(), StoreDescriptor::ValueRegister());
+
+  LInstruction* result = new (zone()) LStoreNamedGeneric(context, obj, val);
+  return MarkAsCall(result, instr);
+}
+
+
+LInstruction* LChunkBuilder::DoStringAdd(HStringAdd* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* left = UseFixed(instr->left(), r4);
+  LOperand* right = UseFixed(instr->right(), r3);
+  return MarkAsCall(
+      DefineFixed(new (zone()) LStringAdd(context, left, right), r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
+  LOperand* string = UseTempRegister(instr->string());
+  LOperand* index = UseTempRegister(instr->index());
+  LOperand* context = UseAny(instr->context());
+  LStringCharCodeAt* result =
+      new (zone()) LStringCharCodeAt(context, string, index);
+  return AssignPointerMap(DefineAsRegister(result));
+}
+
+
+LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
+  LOperand* char_code = UseRegister(instr->value());
+  LOperand* context = UseAny(instr->context());
+  LStringCharFromCode* result =
+      new (zone()) LStringCharFromCode(context, char_code);
+  return AssignPointerMap(DefineAsRegister(result));
+}
+
+
+LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
+  info()->MarkAsDeferredCalling();
+  LOperand* context = UseAny(instr->context());
+  LOperand* size = UseRegisterOrConstant(instr->size());
+  LOperand* temp1 = TempRegister();
+  LOperand* temp2 = TempRegister();
+  LAllocate* result = new (zone()) LAllocate(context, size, temp1, temp2);
+  return AssignPointerMap(DefineAsRegister(result));
+}
+
+
+LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  return MarkAsCall(DefineFixed(new (zone()) LRegExpLiteral(context), r3),
+                    instr);
+}
+
+
+LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  return MarkAsCall(DefineFixed(new (zone()) LFunctionLiteral(context), r3),
+                    instr);
+}
+
+
+LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
+  DCHECK(argument_count_ == 0);
+  allocator_->MarkAsOsrEntry();
+  current_block_->last_environment()->set_ast_id(instr->ast_id());
+  return AssignEnvironment(new (zone()) LOsrEntry);
+}
+
+
+LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
+  LParameter* result = new (zone()) LParameter;
+  if (instr->kind() == HParameter::STACK_PARAMETER) {
+    int spill_index = chunk()->GetParameterStackSlot(instr->index());
+    return DefineAsSpilled(result, spill_index);
+  } else {
+    DCHECK(info()->IsStub());
+    CallInterfaceDescriptor descriptor =
+        info()->code_stub()->GetCallInterfaceDescriptor();
+    int index = static_cast<int>(instr->index());
+    Register reg = descriptor.GetEnvironmentParameterRegister(index);
+    return DefineFixed(result, reg);
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoUnknownOSRValue(HUnknownOSRValue* instr) {
+  // Use an index that corresponds to the location in the unoptimized frame,
+  // which the optimized frame will subsume.
+  int env_index = instr->index();
+  int spill_index = 0;
+  if (instr->environment()->is_parameter_index(env_index)) {
+    spill_index = chunk()->GetParameterStackSlot(env_index);
+  } else {
+    spill_index = env_index - instr->environment()->first_local_index();
+    if (spill_index > LUnallocated::kMaxFixedSlotIndex) {
+      Retry(kTooManySpillSlotsNeededForOSR);
+      spill_index = 0;
+    }
+  }
+  return DefineAsSpilled(new (zone()) LUnknownOSRValue, spill_index);
+}
+
+
+LInstruction* LChunkBuilder::DoCallStub(HCallStub* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  return MarkAsCall(DefineFixed(new (zone()) LCallStub(context), r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
+  // There are no real uses of the arguments object.
+  // arguments.length and element access are supported directly on
+  // stack arguments, and any real arguments object use causes a bailout.
+  // So this value is never used.
+  return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
+  instr->ReplayEnvironment(current_block_->last_environment());
+
+  // There are no real uses of a captured object.
+  return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
+  info()->MarkAsRequiresFrame();
+  LOperand* args = UseRegister(instr->arguments());
+  LOperand* length = UseRegisterOrConstantAtStart(instr->length());
+  LOperand* index = UseRegisterOrConstantAtStart(instr->index());
+  return DefineAsRegister(new (zone()) LAccessArgumentsAt(args, length, index));
+}
+
+
+LInstruction* LChunkBuilder::DoToFastProperties(HToFastProperties* instr) {
+  LOperand* object = UseFixed(instr->value(), r3);
+  LToFastProperties* result = new (zone()) LToFastProperties(object);
+  return MarkAsCall(DefineFixed(result, r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LTypeof* result = new (zone()) LTypeof(context, UseFixed(instr->value(), r3));
+  return MarkAsCall(DefineFixed(result, r3), instr);
+}
+
+
+LInstruction* LChunkBuilder::DoTypeofIsAndBranch(HTypeofIsAndBranch* instr) {
+  return new (zone()) LTypeofIsAndBranch(UseRegister(instr->value()));
+}
+
+
+LInstruction* LChunkBuilder::DoIsConstructCallAndBranch(
+    HIsConstructCallAndBranch* instr) {
+  return new (zone()) LIsConstructCallAndBranch(TempRegister());
+}
+
+
+LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
+  instr->ReplayEnvironment(current_block_->last_environment());
+  return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
+  if (instr->is_function_entry()) {
+    LOperand* context = UseFixed(instr->context(), cp);
+    return MarkAsCall(new (zone()) LStackCheck(context), instr);
+  } else {
+    DCHECK(instr->is_backwards_branch());
+    LOperand* context = UseAny(instr->context());
+    return AssignEnvironment(
+        AssignPointerMap(new (zone()) LStackCheck(context)));
+  }
+}
+
+
+LInstruction* LChunkBuilder::DoEnterInlined(HEnterInlined* instr) {
+  HEnvironment* outer = current_block_->last_environment();
+  outer->set_ast_id(instr->ReturnId());
+  HConstant* undefined = graph()->GetConstantUndefined();
+  HEnvironment* inner = outer->CopyForInlining(
+      instr->closure(), instr->arguments_count(), instr->function(), undefined,
+      instr->inlining_kind());
+  // Only replay binding of arguments object if it wasn't removed from graph.
+  if (instr->arguments_var() != NULL && instr->arguments_object()->IsLinked()) {
+    inner->Bind(instr->arguments_var(), instr->arguments_object());
+  }
+  inner->BindContext(instr->closure_context());
+  inner->set_entry(instr);
+  current_block_->UpdateEnvironment(inner);
+  chunk_->AddInlinedClosure(instr->closure());
+  return NULL;
+}
+
+
+LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
+  LInstruction* pop = NULL;
+
+  HEnvironment* env = current_block_->last_environment();
+
+  if (env->entry()->arguments_pushed()) {
+    int argument_count = env->arguments_environment()->parameter_count();
+    pop = new (zone()) LDrop(argument_count);
+    DCHECK(instr->argument_delta() == -argument_count);
+  }
+
+  HEnvironment* outer =
+      current_block_->last_environment()->DiscardInlined(false);
+  current_block_->UpdateEnvironment(outer);
+
+  return pop;
+}
+
+
+LInstruction* LChunkBuilder::DoForInPrepareMap(HForInPrepareMap* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* object = UseFixed(instr->enumerable(), r3);
+  LForInPrepareMap* result = new (zone()) LForInPrepareMap(context, object);
+  return MarkAsCall(DefineFixed(result, r3), instr, CAN_DEOPTIMIZE_EAGERLY);
+}
+
+
+LInstruction* LChunkBuilder::DoForInCacheArray(HForInCacheArray* instr) {
+  LOperand* map = UseRegister(instr->map());
+  return AssignEnvironment(
+      DefineAsRegister(new (zone()) LForInCacheArray(map)));
+}
+
+
+LInstruction* LChunkBuilder::DoCheckMapValue(HCheckMapValue* instr) {
+  LOperand* value = UseRegisterAtStart(instr->value());
+  LOperand* map = UseRegisterAtStart(instr->map());
+  return AssignEnvironment(new (zone()) LCheckMapValue(value, map));
+}
+
+
+LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
+  LOperand* object = UseRegister(instr->object());
+  LOperand* index = UseTempRegister(instr->index());
+  LLoadFieldByIndex* load = new (zone()) LLoadFieldByIndex(object, index);
+  LInstruction* result = DefineSameAsFirst(load);
+  return AssignPointerMap(result);
+}
+
+
+LInstruction* LChunkBuilder::DoStoreFrameContext(HStoreFrameContext* instr) {
+  LOperand* context = UseRegisterAtStart(instr->context());
+  return new (zone()) LStoreFrameContext(context);
+}
+
+
+LInstruction* LChunkBuilder::DoAllocateBlockContext(
+    HAllocateBlockContext* instr) {
+  LOperand* context = UseFixed(instr->context(), cp);
+  LOperand* function = UseRegisterAtStart(instr->function());
+  LAllocateBlockContext* result =
+      new (zone()) LAllocateBlockContext(context, function);
+  return MarkAsCall(DefineFixed(result, cp), instr);
+}
+}
+}  // namespace v8::internal
diff --git a/src/ppc/lithium-ppc.h b/src/ppc/lithium-ppc.h
new file mode 100644
index 0000000..2176fa6
--- /dev/null
+++ b/src/ppc/lithium-ppc.h
@@ -0,0 +1,2746 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_PPC_LITHIUM_PPC_H_
+#define V8_PPC_LITHIUM_PPC_H_
+
+#include "src/hydrogen.h"
+#include "src/lithium.h"
+#include "src/lithium-allocator.h"
+#include "src/safepoint-table.h"
+#include "src/utils.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class LCodeGen;
+
+#define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
+  V(AccessArgumentsAt)                       \
+  V(AddI)                                    \
+  V(Allocate)                                \
+  V(AllocateBlockContext)                    \
+  V(ApplyArguments)                          \
+  V(ArgumentsElements)                       \
+  V(ArgumentsLength)                         \
+  V(ArithmeticD)                             \
+  V(ArithmeticT)                             \
+  V(BitI)                                    \
+  V(BoundsCheck)                             \
+  V(Branch)                                  \
+  V(CallJSFunction)                          \
+  V(CallWithDescriptor)                      \
+  V(CallFunction)                            \
+  V(CallNew)                                 \
+  V(CallNewArray)                            \
+  V(CallRuntime)                             \
+  V(CallStub)                                \
+  V(CheckInstanceType)                       \
+  V(CheckNonSmi)                             \
+  V(CheckMaps)                               \
+  V(CheckMapValue)                           \
+  V(CheckSmi)                                \
+  V(CheckValue)                              \
+  V(ClampDToUint8)                           \
+  V(ClampIToUint8)                           \
+  V(ClampTToUint8)                           \
+  V(ClassOfTestAndBranch)                    \
+  V(CompareMinusZeroAndBranch)               \
+  V(CompareNumericAndBranch)                 \
+  V(CmpObjectEqAndBranch)                    \
+  V(CmpHoleAndBranch)                        \
+  V(CmpMapAndBranch)                         \
+  V(CmpT)                                    \
+  V(ConstantD)                               \
+  V(ConstantE)                               \
+  V(ConstantI)                               \
+  V(ConstantS)                               \
+  V(ConstantT)                               \
+  V(ConstructDouble)                         \
+  V(Context)                                 \
+  V(DateField)                               \
+  V(DebugBreak)                              \
+  V(DeclareGlobals)                          \
+  V(Deoptimize)                              \
+  V(DivByConstI)                             \
+  V(DivByPowerOf2I)                          \
+  V(DivI)                                    \
+  V(DoubleBits)                              \
+  V(DoubleToI)                               \
+  V(DoubleToSmi)                             \
+  V(Drop)                                    \
+  V(Dummy)                                   \
+  V(DummyUse)                                \
+  V(FlooringDivByConstI)                     \
+  V(FlooringDivByPowerOf2I)                  \
+  V(FlooringDivI)                            \
+  V(ForInCacheArray)                         \
+  V(ForInPrepareMap)                         \
+  V(FunctionLiteral)                         \
+  V(GetCachedArrayIndex)                     \
+  V(Goto)                                    \
+  V(HasCachedArrayIndexAndBranch)            \
+  V(HasInstanceTypeAndBranch)                \
+  V(InnerAllocatedObject)                    \
+  V(InstanceOf)                              \
+  V(InstanceOfKnownGlobal)                   \
+  V(InstructionGap)                          \
+  V(Integer32ToDouble)                       \
+  V(InvokeFunction)                          \
+  V(IsConstructCallAndBranch)                \
+  V(IsObjectAndBranch)                       \
+  V(IsStringAndBranch)                       \
+  V(IsSmiAndBranch)                          \
+  V(IsUndetectableAndBranch)                 \
+  V(Label)                                   \
+  V(LazyBailout)                             \
+  V(LoadContextSlot)                         \
+  V(LoadRoot)                                \
+  V(LoadFieldByIndex)                        \
+  V(LoadFunctionPrototype)                   \
+  V(LoadGlobalCell)                          \
+  V(LoadGlobalGeneric)                       \
+  V(LoadKeyed)                               \
+  V(LoadKeyedGeneric)                        \
+  V(LoadNamedField)                          \
+  V(LoadNamedGeneric)                        \
+  V(MapEnumLength)                           \
+  V(MathAbs)                                 \
+  V(MathClz32)                               \
+  V(MathExp)                                 \
+  V(MathFloor)                               \
+  V(MathFround)                              \
+  V(MathLog)                                 \
+  V(MathMinMax)                              \
+  V(MathPowHalf)                             \
+  V(MathRound)                               \
+  V(MathSqrt)                                \
+  V(ModByConstI)                             \
+  V(ModByPowerOf2I)                          \
+  V(ModI)                                    \
+  V(MulI)                                    \
+  V(MultiplyAddD)                            \
+  V(MultiplySubD)                            \
+  V(NumberTagD)                              \
+  V(NumberTagI)                              \
+  V(NumberTagU)                              \
+  V(NumberUntagD)                            \
+  V(OsrEntry)                                \
+  V(Parameter)                               \
+  V(Power)                                   \
+  V(PushArgument)                            \
+  V(RegExpLiteral)                           \
+  V(Return)                                  \
+  V(SeqStringGetChar)                        \
+  V(SeqStringSetChar)                        \
+  V(ShiftI)                                  \
+  V(SmiTag)                                  \
+  V(SmiUntag)                                \
+  V(StackCheck)                              \
+  V(StoreCodeEntry)                          \
+  V(StoreContextSlot)                        \
+  V(StoreFrameContext)                       \
+  V(StoreGlobalCell)                         \
+  V(StoreKeyed)                              \
+  V(StoreKeyedGeneric)                       \
+  V(StoreNamedField)                         \
+  V(StoreNamedGeneric)                       \
+  V(StringAdd)                               \
+  V(StringCharCodeAt)                        \
+  V(StringCharFromCode)                      \
+  V(StringCompareAndBranch)                  \
+  V(SubI)                                    \
+  V(RSubI)                                   \
+  V(TaggedToI)                               \
+  V(TailCallThroughMegamorphicCache)         \
+  V(ThisFunction)                            \
+  V(ToFastProperties)                        \
+  V(TransitionElementsKind)                  \
+  V(TrapAllocationMemento)                   \
+  V(Typeof)                                  \
+  V(TypeofIsAndBranch)                       \
+  V(Uint32ToDouble)                          \
+  V(UnknownOSRValue)                         \
+  V(WrapReceiver)
+
+
+#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)            \
+  Opcode opcode() const FINAL { return LInstruction::k##type; } \
+  void CompileToNative(LCodeGen* generator) FINAL;              \
+  const char* Mnemonic() const FINAL { return mnemonic; }       \
+  static L##type* cast(LInstruction* instr) {                   \
+    DCHECK(instr->Is##type());                                  \
+    return reinterpret_cast<L##type*>(instr);                   \
+  }
+
+
+#define DECLARE_HYDROGEN_ACCESSOR(type) \
+  H##type* hydrogen() const { return H##type::cast(hydrogen_value()); }
+
+
+class LInstruction : public ZoneObject {
+ public:
+  LInstruction()
+      : environment_(NULL),
+        hydrogen_value_(NULL),
+        bit_field_(IsCallBits::encode(false)) {}
+
+  virtual ~LInstruction() {}
+
+  virtual void CompileToNative(LCodeGen* generator) = 0;
+  virtual const char* Mnemonic() const = 0;
+  virtual void PrintTo(StringStream* stream);
+  virtual void PrintDataTo(StringStream* stream);
+  virtual void PrintOutputOperandTo(StringStream* stream);
+
+  enum Opcode {
+// Declare a unique enum value for each instruction.
+#define DECLARE_OPCODE(type) k##type,
+    LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE) kNumberOfInstructions
+#undef DECLARE_OPCODE
+  };
+
+  virtual Opcode opcode() const = 0;
+
+// Declare non-virtual type testers for all leaf IR classes.
+#define DECLARE_PREDICATE(type) \
+  bool Is##type() const { return opcode() == k##type; }
+  LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
+#undef DECLARE_PREDICATE
+
+  // Declare virtual predicates for instructions that don't have
+  // an opcode.
+  virtual bool IsGap() const { return false; }
+
+  virtual bool IsControl() const { return false; }
+
+  // Try deleting this instruction if possible.
+  virtual bool TryDelete() { return false; }
+
+  void set_environment(LEnvironment* env) { environment_ = env; }
+  LEnvironment* environment() const { return environment_; }
+  bool HasEnvironment() const { return environment_ != NULL; }
+
+  void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
+  LPointerMap* pointer_map() const { return pointer_map_.get(); }
+  bool HasPointerMap() const { return pointer_map_.is_set(); }
+
+  void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
+  HValue* hydrogen_value() const { return hydrogen_value_; }
+
+  virtual void SetDeferredLazyDeoptimizationEnvironment(LEnvironment* env) {}
+
+  void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); }
+  bool IsCall() const { return IsCallBits::decode(bit_field_); }
+
+  // Interface to the register allocator and iterators.
+  bool ClobbersTemps() const { return IsCall(); }
+  bool ClobbersRegisters() const { return IsCall(); }
+  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const {
+    return IsCall();
+  }
+
+  // Interface to the register allocator and iterators.
+  bool IsMarkedAsCall() const { return IsCall(); }
+
+  virtual bool HasResult() const = 0;
+  virtual LOperand* result() const = 0;
+
+  LOperand* FirstInput() { return InputAt(0); }
+  LOperand* Output() { return HasResult() ? result() : NULL; }
+
+  virtual bool HasInterestingComment(LCodeGen* gen) const { return true; }
+
+#ifdef DEBUG
+  void VerifyCall();
+#endif
+
+  virtual int InputCount() = 0;
+  virtual LOperand* InputAt(int i) = 0;
+
+ private:
+  // Iterator support.
+  friend class InputIterator;
+
+  friend class TempIterator;
+  virtual int TempCount() = 0;
+  virtual LOperand* TempAt(int i) = 0;
+
+  class IsCallBits : public BitField<bool, 0, 1> {};
+
+  LEnvironment* environment_;
+  SetOncePointer<LPointerMap> pointer_map_;
+  HValue* hydrogen_value_;
+  int bit_field_;
+};
+
+
+// R = number of result operands (0 or 1).
+template <int R>
+class LTemplateResultInstruction : public LInstruction {
+ public:
+  // Allow 0 or 1 output operands.
+  STATIC_ASSERT(R == 0 || R == 1);
+  bool HasResult() const FINAL { return R != 0 && result() != NULL; }
+  void set_result(LOperand* operand) { results_[0] = operand; }
+  LOperand* result() const { return results_[0]; }
+
+ protected:
+  EmbeddedContainer<LOperand*, R> results_;
+};
+
+
+// R = number of result operands (0 or 1).
+// I = number of input operands.
+// T = number of temporary operands.
+template <int R, int I, int T>
+class LTemplateInstruction : public LTemplateResultInstruction<R> {
+ protected:
+  EmbeddedContainer<LOperand*, I> inputs_;
+  EmbeddedContainer<LOperand*, T> temps_;
+
+ private:
+  // Iterator support.
+  int InputCount() FINAL { return I; }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
+
+  int TempCount() FINAL { return T; }
+  LOperand* TempAt(int i) FINAL { return temps_[i]; }
+};
+
+
+class LGap : public LTemplateInstruction<0, 0, 0> {
+ public:
+  explicit LGap(HBasicBlock* block) : block_(block) {
+    parallel_moves_[BEFORE] = NULL;
+    parallel_moves_[START] = NULL;
+    parallel_moves_[END] = NULL;
+    parallel_moves_[AFTER] = NULL;
+  }
+
+  // Can't use the DECLARE-macro here because of sub-classes.
+  bool IsGap() const OVERRIDE { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+  static LGap* cast(LInstruction* instr) {
+    DCHECK(instr->IsGap());
+    return reinterpret_cast<LGap*>(instr);
+  }
+
+  bool IsRedundant() const;
+
+  HBasicBlock* block() const { return block_; }
+
+  enum InnerPosition {
+    BEFORE,
+    START,
+    END,
+    AFTER,
+    FIRST_INNER_POSITION = BEFORE,
+    LAST_INNER_POSITION = AFTER
+  };
+
+  LParallelMove* GetOrCreateParallelMove(InnerPosition pos, Zone* zone) {
+    if (parallel_moves_[pos] == NULL) {
+      parallel_moves_[pos] = new (zone) LParallelMove(zone);
+    }
+    return parallel_moves_[pos];
+  }
+
+  LParallelMove* GetParallelMove(InnerPosition pos) {
+    return parallel_moves_[pos];
+  }
+
+ private:
+  LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
+  HBasicBlock* block_;
+};
+
+
+class LInstructionGap FINAL : public LGap {
+ public:
+  explicit LInstructionGap(HBasicBlock* block) : LGap(block) {}
+
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
+    return !IsRedundant();
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
+};
+
+
+class LGoto FINAL : public LTemplateInstruction<0, 0, 0> {
+ public:
+  explicit LGoto(HBasicBlock* block) : block_(block) {}
+
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
+  DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsControl() const OVERRIDE { return true; }
+
+  int block_id() const { return block_->block_id(); }
+
+ private:
+  HBasicBlock* block_;
+};
+
+
+class LLazyBailout FINAL : public LTemplateInstruction<0, 0, 0> {
+ public:
+  LLazyBailout() : gap_instructions_size_(0) {}
+
+  DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
+
+  void set_gap_instructions_size(int gap_instructions_size) {
+    gap_instructions_size_ = gap_instructions_size;
+  }
+  int gap_instructions_size() { return gap_instructions_size_; }
+
+ private:
+  int gap_instructions_size_;
+};
+
+
+class LDummy FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  LDummy() {}
+  DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy")
+};
+
+
+class LDummyUse FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LDummyUse(LOperand* value) { inputs_[0] = value; }
+  DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
+};
+
+
+class LDeoptimize FINAL : public LTemplateInstruction<0, 0, 0> {
+ public:
+  bool IsControl() const OVERRIDE { return true; }
+  DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
+  DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
+};
+
+
+class LLabel FINAL : public LGap {
+ public:
+  explicit LLabel(HBasicBlock* block) : LGap(block), replacement_(NULL) {}
+
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
+  DECLARE_CONCRETE_INSTRUCTION(Label, "label")
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+
+  int block_id() const { return block()->block_id(); }
+  bool is_loop_header() const { return block()->IsLoopHeader(); }
+  bool is_osr_entry() const { return block()->is_osr_entry(); }
+  Label* label() { return &label_; }
+  LLabel* replacement() const { return replacement_; }
+  void set_replacement(LLabel* label) { replacement_ = label; }
+  bool HasReplacement() const { return replacement_ != NULL; }
+
+ private:
+  Label label_;
+  LLabel* replacement_;
+};
+
+
+class LParameter FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  virtual bool HasInterestingComment(LCodeGen* gen) const { return false; }
+  DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
+};
+
+
+class LCallStub FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LCallStub(LOperand* context) { inputs_[0] = context; }
+
+  LOperand* context() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CallStub, "call-stub")
+  DECLARE_HYDROGEN_ACCESSOR(CallStub)
+};
+
+
+class LTailCallThroughMegamorphicCache FINAL
+    : public LTemplateInstruction<0, 3, 0> {
+ public:
+  explicit LTailCallThroughMegamorphicCache(LOperand* context,
+                                            LOperand* receiver,
+                                            LOperand* name) {
+    inputs_[0] = context;
+    inputs_[1] = receiver;
+    inputs_[2] = name;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* receiver() { return inputs_[1]; }
+  LOperand* name() { return inputs_[2]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
+                               "tail-call-through-megamorphic-cache")
+  DECLARE_HYDROGEN_ACCESSOR(TailCallThroughMegamorphicCache)
+};
+
+class LUnknownOSRValue FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
+  DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
+};
+
+
+template <int I, int T>
+class LControlInstruction : public LTemplateInstruction<0, I, T> {
+ public:
+  LControlInstruction() : false_label_(NULL), true_label_(NULL) {}
+
+  bool IsControl() const FINAL { return true; }
+
+  int SuccessorCount() { return hydrogen()->SuccessorCount(); }
+  HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
+
+  int TrueDestination(LChunk* chunk) {
+    return chunk->LookupDestination(true_block_id());
+  }
+  int FalseDestination(LChunk* chunk) {
+    return chunk->LookupDestination(false_block_id());
+  }
+
+  Label* TrueLabel(LChunk* chunk) {
+    if (true_label_ == NULL) {
+      true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk));
+    }
+    return true_label_;
+  }
+  Label* FalseLabel(LChunk* chunk) {
+    if (false_label_ == NULL) {
+      false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk));
+    }
+    return false_label_;
+  }
+
+ protected:
+  int true_block_id() { return SuccessorAt(0)->block_id(); }
+  int false_block_id() { return SuccessorAt(1)->block_id(); }
+
+ private:
+  HControlInstruction* hydrogen() {
+    return HControlInstruction::cast(this->hydrogen_value());
+  }
+
+  Label* false_label_;
+  Label* true_label_;
+};
+
+
+class LWrapReceiver FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LWrapReceiver(LOperand* receiver, LOperand* function) {
+    inputs_[0] = receiver;
+    inputs_[1] = function;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
+  DECLARE_HYDROGEN_ACCESSOR(WrapReceiver)
+
+  LOperand* receiver() { return inputs_[0]; }
+  LOperand* function() { return inputs_[1]; }
+};
+
+
+class LApplyArguments FINAL : public LTemplateInstruction<1, 4, 0> {
+ public:
+  LApplyArguments(LOperand* function, LOperand* receiver, LOperand* length,
+                  LOperand* elements) {
+    inputs_[0] = function;
+    inputs_[1] = receiver;
+    inputs_[2] = length;
+    inputs_[3] = elements;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
+
+  LOperand* function() { return inputs_[0]; }
+  LOperand* receiver() { return inputs_[1]; }
+  LOperand* length() { return inputs_[2]; }
+  LOperand* elements() { return inputs_[3]; }
+};
+
+
+class LAccessArgumentsAt FINAL : public LTemplateInstruction<1, 3, 0> {
+ public:
+  LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
+    inputs_[0] = arguments;
+    inputs_[1] = length;
+    inputs_[2] = index;
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
+
+  LOperand* arguments() { return inputs_[0]; }
+  LOperand* length() { return inputs_[1]; }
+  LOperand* index() { return inputs_[2]; }
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LArgumentsLength FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LArgumentsLength(LOperand* elements) { inputs_[0] = elements; }
+
+  LOperand* elements() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
+};
+
+
+class LArgumentsElements FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
+  DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements)
+};
+
+
+class LModByPowerOf2I FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  LModByPowerOf2I(LOperand* dividend, int32_t divisor) {
+    inputs_[0] = dividend;
+    divisor_ = divisor;
+  }
+
+  LOperand* dividend() { return inputs_[0]; }
+  int32_t divisor() const { return divisor_; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ModByPowerOf2I, "mod-by-power-of-2-i")
+  DECLARE_HYDROGEN_ACCESSOR(Mod)
+
+ private:
+  int32_t divisor_;
+};
+
+
+class LModByConstI FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  LModByConstI(LOperand* dividend, int32_t divisor) {
+    inputs_[0] = dividend;
+    divisor_ = divisor;
+  }
+
+  LOperand* dividend() { return inputs_[0]; }
+  int32_t divisor() const { return divisor_; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ModByConstI, "mod-by-const-i")
+  DECLARE_HYDROGEN_ACCESSOR(Mod)
+
+ private:
+  int32_t divisor_;
+};
+
+
+class LModI FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LModI(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
+  DECLARE_HYDROGEN_ACCESSOR(Mod)
+};
+
+
+class LDivByPowerOf2I FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  LDivByPowerOf2I(LOperand* dividend, int32_t divisor) {
+    inputs_[0] = dividend;
+    divisor_ = divisor;
+  }
+
+  LOperand* dividend() { return inputs_[0]; }
+  int32_t divisor() const { return divisor_; }
+
+  DECLARE_CONCRETE_INSTRUCTION(DivByPowerOf2I, "div-by-power-of-2-i")
+  DECLARE_HYDROGEN_ACCESSOR(Div)
+
+ private:
+  int32_t divisor_;
+};
+
+
+class LDivByConstI FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  LDivByConstI(LOperand* dividend, int32_t divisor) {
+    inputs_[0] = dividend;
+    divisor_ = divisor;
+  }
+
+  LOperand* dividend() { return inputs_[0]; }
+  int32_t divisor() const { return divisor_; }
+
+  DECLARE_CONCRETE_INSTRUCTION(DivByConstI, "div-by-const-i")
+  DECLARE_HYDROGEN_ACCESSOR(Div)
+
+ private:
+  int32_t divisor_;
+};
+
+
+class LDivI FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LDivI(LOperand* dividend, LOperand* divisor) {
+    inputs_[0] = dividend;
+    inputs_[1] = divisor;
+  }
+
+  LOperand* dividend() { return inputs_[0]; }
+  LOperand* divisor() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
+  DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
+};
+
+
+class LFlooringDivByPowerOf2I FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  LFlooringDivByPowerOf2I(LOperand* dividend, int32_t divisor) {
+    inputs_[0] = dividend;
+    divisor_ = divisor;
+  }
+
+  LOperand* dividend() { return inputs_[0]; }
+  int32_t divisor() { return divisor_; }
+
+  DECLARE_CONCRETE_INSTRUCTION(FlooringDivByPowerOf2I,
+                               "flooring-div-by-power-of-2-i")
+  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+
+ private:
+  int32_t divisor_;
+};
+
+
+class LFlooringDivByConstI FINAL : public LTemplateInstruction<1, 1, 1> {
+ public:
+  LFlooringDivByConstI(LOperand* dividend, int32_t divisor, LOperand* temp) {
+    inputs_[0] = dividend;
+    divisor_ = divisor;
+    temps_[0] = temp;
+  }
+
+  LOperand* dividend() { return inputs_[0]; }
+  int32_t divisor() const { return divisor_; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i")
+  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+
+ private:
+  int32_t divisor_;
+};
+
+
+class LFlooringDivI FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LFlooringDivI(LOperand* dividend, LOperand* divisor) {
+    inputs_[0] = dividend;
+    inputs_[1] = divisor;
+  }
+
+  LOperand* dividend() { return inputs_[0]; }
+  LOperand* divisor() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
+  DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
+};
+
+
+class LMulI FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LMulI(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
+  DECLARE_HYDROGEN_ACCESSOR(Mul)
+};
+
+
+// Instruction for computing multiplier * multiplicand + addend.
+class LMultiplyAddD FINAL : public LTemplateInstruction<1, 3, 0> {
+ public:
+  LMultiplyAddD(LOperand* addend, LOperand* multiplier,
+                LOperand* multiplicand) {
+    inputs_[0] = addend;
+    inputs_[1] = multiplier;
+    inputs_[2] = multiplicand;
+  }
+
+  LOperand* addend() { return inputs_[0]; }
+  LOperand* multiplier() { return inputs_[1]; }
+  LOperand* multiplicand() { return inputs_[2]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MultiplyAddD, "multiply-add-d")
+};
+
+
+// Instruction for computing minuend - multiplier * multiplicand.
+class LMultiplySubD FINAL : public LTemplateInstruction<1, 3, 0> {
+ public:
+  LMultiplySubD(LOperand* minuend, LOperand* multiplier,
+                LOperand* multiplicand) {
+    inputs_[0] = minuend;
+    inputs_[1] = multiplier;
+    inputs_[2] = multiplicand;
+  }
+
+  LOperand* minuend() { return inputs_[0]; }
+  LOperand* multiplier() { return inputs_[1]; }
+  LOperand* multiplicand() { return inputs_[2]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MultiplySubD, "multiply-sub-d")
+};
+
+
+class LDebugBreak FINAL : public LTemplateInstruction<0, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
+};
+
+
+class LCompareNumericAndBranch FINAL : public LControlInstruction<2, 0> {
+ public:
+  LCompareNumericAndBranch(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
+                               "compare-numeric-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
+
+  Token::Value op() const { return hydrogen()->token(); }
+  bool is_double() const { return hydrogen()->representation().IsDouble(); }
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LMathFloor FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LMathFloor(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MathFloor, "math-floor")
+  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
+};
+
+
+class LMathRound FINAL : public LTemplateInstruction<1, 1, 1> {
+ public:
+  LMathRound(LOperand* value, LOperand* temp) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MathRound, "math-round")
+  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
+};
+
+
+class LMathFround FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LMathFround(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MathFround, "math-fround")
+};
+
+
+class LMathAbs FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LMathAbs(LOperand* context, LOperand* value) {
+    inputs_[1] = context;
+    inputs_[0] = value;
+  }
+
+  LOperand* context() { return inputs_[1]; }
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs")
+  DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
+};
+
+
+class LMathLog FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LMathLog(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log")
+};
+
+
+class LMathClz32 FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LMathClz32(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MathClz32, "math-clz32")
+};
+
+
+class LMathExp FINAL : public LTemplateInstruction<1, 1, 3> {
+ public:
+  LMathExp(LOperand* value, LOperand* double_temp, LOperand* temp1,
+           LOperand* temp2) {
+    inputs_[0] = value;
+    temps_[0] = temp1;
+    temps_[1] = temp2;
+    temps_[2] = double_temp;
+    ExternalReference::InitializeMathExpData();
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp1() { return temps_[0]; }
+  LOperand* temp2() { return temps_[1]; }
+  LOperand* double_temp() { return temps_[2]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
+};
+
+
+class LMathSqrt FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LMathSqrt(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
+};
+
+
+class LMathPowHalf FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LMathPowHalf(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
+};
+
+
+class LCmpObjectEqAndBranch FINAL : public LControlInstruction<2, 0> {
+ public:
+  LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareObjectEqAndBranch)
+};
+
+
+class LCmpHoleAndBranch FINAL : public LControlInstruction<1, 0> {
+ public:
+  explicit LCmpHoleAndBranch(LOperand* object) { inputs_[0] = object; }
+
+  LOperand* object() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch)
+};
+
+
+class LCompareMinusZeroAndBranch FINAL : public LControlInstruction<1, 1> {
+ public:
+  LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
+                               "cmp-minus-zero-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
+};
+
+
+class LIsObjectAndBranch FINAL : public LControlInstruction<1, 1> {
+ public:
+  LIsObjectAndBranch(LOperand* value, LOperand* temp) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LIsStringAndBranch FINAL : public LControlInstruction<1, 1> {
+ public:
+  LIsStringAndBranch(LOperand* value, LOperand* temp) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LIsSmiAndBranch FINAL : public LControlInstruction<1, 0> {
+ public:
+  explicit LIsSmiAndBranch(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LIsUndetectableAndBranch FINAL : public LControlInstruction<1, 1> {
+ public:
+  explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
+                               "is-undetectable-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LStringCompareAndBranch FINAL : public LControlInstruction<3, 0> {
+ public:
+  LStringCompareAndBranch(LOperand* context, LOperand* left, LOperand* right) {
+    inputs_[0] = context;
+    inputs_[1] = left;
+    inputs_[2] = right;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* left() { return inputs_[1]; }
+  LOperand* right() { return inputs_[2]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
+                               "string-compare-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
+
+  Token::Value op() const { return hydrogen()->token(); }
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LHasInstanceTypeAndBranch FINAL : public LControlInstruction<1, 0> {
+ public:
+  explicit LHasInstanceTypeAndBranch(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
+                               "has-instance-type-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LGetCachedArrayIndex FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LGetCachedArrayIndex(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(GetCachedArrayIndex, "get-cached-array-index")
+  DECLARE_HYDROGEN_ACCESSOR(GetCachedArrayIndex)
+};
+
+
+class LHasCachedArrayIndexAndBranch FINAL : public LControlInstruction<1, 0> {
+ public:
+  explicit LHasCachedArrayIndexAndBranch(LOperand* value) {
+    inputs_[0] = value;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
+                               "has-cached-array-index-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LClassOfTestAndBranch FINAL : public LControlInstruction<1, 1> {
+ public:
+  LClassOfTestAndBranch(LOperand* value, LOperand* temp) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch, "class-of-test-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LCmpT FINAL : public LTemplateInstruction<1, 3, 0> {
+ public:
+  LCmpT(LOperand* context, LOperand* left, LOperand* right) {
+    inputs_[0] = context;
+    inputs_[1] = left;
+    inputs_[2] = right;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* left() { return inputs_[1]; }
+  LOperand* right() { return inputs_[2]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
+  DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
+
+  Token::Value op() const { return hydrogen()->token(); }
+};
+
+
+class LInstanceOf FINAL : public LTemplateInstruction<1, 3, 0> {
+ public:
+  LInstanceOf(LOperand* context, LOperand* left, LOperand* right) {
+    inputs_[0] = context;
+    inputs_[1] = left;
+    inputs_[2] = right;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* left() { return inputs_[1]; }
+  LOperand* right() { return inputs_[2]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of")
+};
+
+
+class LInstanceOfKnownGlobal FINAL : public LTemplateInstruction<1, 2, 1> {
+ public:
+  LInstanceOfKnownGlobal(LOperand* context, LOperand* value, LOperand* temp) {
+    inputs_[0] = context;
+    inputs_[1] = value;
+    temps_[0] = temp;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* value() { return inputs_[1]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal,
+                               "instance-of-known-global")
+  DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal)
+
+  Handle<JSFunction> function() const { return hydrogen()->function(); }
+  LEnvironment* GetDeferredLazyDeoptimizationEnvironment() {
+    return lazy_deopt_env_;
+  }
+  virtual void SetDeferredLazyDeoptimizationEnvironment(
+      LEnvironment* env) OVERRIDE {
+    lazy_deopt_env_ = env;
+  }
+
+ private:
+  LEnvironment* lazy_deopt_env_;
+};
+
+
+class LBoundsCheck FINAL : public LTemplateInstruction<0, 2, 0> {
+ public:
+  LBoundsCheck(LOperand* index, LOperand* length) {
+    inputs_[0] = index;
+    inputs_[1] = length;
+  }
+
+  LOperand* index() { return inputs_[0]; }
+  LOperand* length() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
+  DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
+};
+
+
+class LBitI FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LBitI(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  Token::Value op() const { return hydrogen()->op(); }
+
+  DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
+  DECLARE_HYDROGEN_ACCESSOR(Bitwise)
+};
+
+
+class LShiftI FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
+      : op_(op), can_deopt_(can_deopt) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  Token::Value op() const { return op_; }
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+  bool can_deopt() const { return can_deopt_; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
+
+ private:
+  Token::Value op_;
+  bool can_deopt_;
+};
+
+
+class LSubI FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LSubI(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
+  DECLARE_HYDROGEN_ACCESSOR(Sub)
+};
+
+
+class LRSubI FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LRSubI(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(RSubI, "rsub-i")
+  DECLARE_HYDROGEN_ACCESSOR(Sub)
+};
+
+
+class LConstantI FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
+  DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+  int32_t value() const { return hydrogen()->Integer32Value(); }
+};
+
+
+class LConstantS FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s")
+  DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+  Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); }
+};
+
+
+class LConstantD FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
+  DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+  double value() const { return hydrogen()->DoubleValue(); }
+};
+
+
+class LConstantE FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
+  DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+  ExternalReference value() const {
+    return hydrogen()->ExternalReferenceValue();
+  }
+};
+
+
+class LConstantT FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
+  DECLARE_HYDROGEN_ACCESSOR(Constant)
+
+  Handle<Object> value(Isolate* isolate) const {
+    return hydrogen()->handle(isolate);
+  }
+};
+
+
+class LBranch FINAL : public LControlInstruction<1, 0> {
+ public:
+  explicit LBranch(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
+  DECLARE_HYDROGEN_ACCESSOR(Branch)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LCmpMapAndBranch FINAL : public LControlInstruction<1, 1> {
+ public:
+  LCmpMapAndBranch(LOperand* value, LOperand* temp) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareMap)
+
+  Handle<Map> map() const { return hydrogen()->map().handle(); }
+};
+
+
+class LMapEnumLength FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LMapEnumLength(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MapEnumLength, "map-enum-length")
+};
+
+
+class LDateField FINAL : public LTemplateInstruction<1, 1, 1> {
+ public:
+  LDateField(LOperand* date, LOperand* temp, Smi* index) : index_(index) {
+    inputs_[0] = date;
+    temps_[0] = temp;
+  }
+
+  LOperand* date() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+  Smi* index() const { return index_; }
+
+  DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
+  DECLARE_HYDROGEN_ACCESSOR(DateField)
+
+ private:
+  Smi* index_;
+};
+
+
+class LSeqStringGetChar FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LSeqStringGetChar(LOperand* string, LOperand* index) {
+    inputs_[0] = string;
+    inputs_[1] = index;
+  }
+
+  LOperand* string() const { return inputs_[0]; }
+  LOperand* index() const { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(SeqStringGetChar, "seq-string-get-char")
+  DECLARE_HYDROGEN_ACCESSOR(SeqStringGetChar)
+};
+
+
+class LSeqStringSetChar FINAL : public LTemplateInstruction<1, 4, 0> {
+ public:
+  LSeqStringSetChar(LOperand* context, LOperand* string, LOperand* index,
+                    LOperand* value) {
+    inputs_[0] = context;
+    inputs_[1] = string;
+    inputs_[2] = index;
+    inputs_[3] = value;
+  }
+
+  LOperand* string() { return inputs_[1]; }
+  LOperand* index() { return inputs_[2]; }
+  LOperand* value() { return inputs_[3]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
+  DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
+};
+
+
+class LAddI FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LAddI(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
+  DECLARE_HYDROGEN_ACCESSOR(Add)
+};
+
+
+class LMathMinMax FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LMathMinMax(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max")
+  DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
+};
+
+
+class LPower FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LPower(LOperand* left, LOperand* right) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(Power, "power")
+  DECLARE_HYDROGEN_ACCESSOR(Power)
+};
+
+
+class LArithmeticD FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LArithmeticD(Token::Value op, LOperand* left, LOperand* right) : op_(op) {
+    inputs_[0] = left;
+    inputs_[1] = right;
+  }
+
+  Token::Value op() const { return op_; }
+  LOperand* left() { return inputs_[0]; }
+  LOperand* right() { return inputs_[1]; }
+
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticD; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
+
+ private:
+  Token::Value op_;
+};
+
+
+class LArithmeticT FINAL : public LTemplateInstruction<1, 3, 0> {
+ public:
+  LArithmeticT(Token::Value op, LOperand* context, LOperand* left,
+               LOperand* right)
+      : op_(op) {
+    inputs_[0] = context;
+    inputs_[1] = left;
+    inputs_[2] = right;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* left() { return inputs_[1]; }
+  LOperand* right() { return inputs_[2]; }
+  Token::Value op() const { return op_; }
+
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticT; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
+
+ private:
+  Token::Value op_;
+};
+
+
+class LReturn FINAL : public LTemplateInstruction<0, 3, 0> {
+ public:
+  LReturn(LOperand* value, LOperand* context, LOperand* parameter_count) {
+    inputs_[0] = value;
+    inputs_[1] = context;
+    inputs_[2] = parameter_count;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+
+  bool has_constant_parameter_count() {
+    return parameter_count()->IsConstantOperand();
+  }
+  LConstantOperand* constant_parameter_count() {
+    DCHECK(has_constant_parameter_count());
+    return LConstantOperand::cast(parameter_count());
+  }
+  LOperand* parameter_count() { return inputs_[2]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(Return, "return")
+};
+
+
+class LLoadNamedField FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LLoadNamedField(LOperand* object) { inputs_[0] = object; }
+
+  LOperand* object() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
+  DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
+};
+
+
+class LLoadNamedGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
+ public:
+  LLoadNamedGeneric(LOperand* context, LOperand* object, LOperand* vector) {
+    inputs_[0] = context;
+    inputs_[1] = object;
+    temps_[0] = vector;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* object() { return inputs_[1]; }
+  LOperand* temp_vector() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic")
+  DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric)
+
+  Handle<Object> name() const { return hydrogen()->name(); }
+};
+
+
+class LLoadFunctionPrototype FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LLoadFunctionPrototype(LOperand* function) { inputs_[0] = function; }
+
+  LOperand* function() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
+  DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
+};
+
+
+class LLoadRoot FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root")
+  DECLARE_HYDROGEN_ACCESSOR(LoadRoot)
+
+  Heap::RootListIndex index() const { return hydrogen()->index(); }
+};
+
+
+class LLoadKeyed FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LLoadKeyed(LOperand* elements, LOperand* key) {
+    inputs_[0] = elements;
+    inputs_[1] = key;
+  }
+
+  LOperand* elements() { return inputs_[0]; }
+  LOperand* key() { return inputs_[1]; }
+  ElementsKind elements_kind() const { return hydrogen()->elements_kind(); }
+  bool is_external() const { return hydrogen()->is_external(); }
+  bool is_fixed_typed_array() const {
+    return hydrogen()->is_fixed_typed_array();
+  }
+  bool is_typed_elements() const {
+    return is_external() || is_fixed_typed_array();
+  }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
+  DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+  uint32_t base_offset() const { return hydrogen()->base_offset(); }
+};
+
+
+class LLoadKeyedGeneric FINAL : public LTemplateInstruction<1, 3, 1> {
+ public:
+  LLoadKeyedGeneric(LOperand* context, LOperand* object, LOperand* key,
+                    LOperand* vector) {
+    inputs_[0] = context;
+    inputs_[1] = object;
+    inputs_[2] = key;
+    temps_[0] = vector;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* object() { return inputs_[1]; }
+  LOperand* key() { return inputs_[2]; }
+  LOperand* temp_vector() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic")
+  DECLARE_HYDROGEN_ACCESSOR(LoadKeyedGeneric)
+};
+
+
+class LLoadGlobalCell FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalCell, "load-global-cell")
+  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalCell)
+};
+
+
+class LLoadGlobalGeneric FINAL : public LTemplateInstruction<1, 2, 1> {
+ public:
+  LLoadGlobalGeneric(LOperand* context, LOperand* global_object,
+                     LOperand* vector) {
+    inputs_[0] = context;
+    inputs_[1] = global_object;
+    temps_[0] = vector;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* global_object() { return inputs_[1]; }
+  LOperand* temp_vector() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadGlobalGeneric, "load-global-generic")
+  DECLARE_HYDROGEN_ACCESSOR(LoadGlobalGeneric)
+
+  Handle<Object> name() const { return hydrogen()->name(); }
+  bool for_typeof() const { return hydrogen()->for_typeof(); }
+};
+
+
+class LStoreGlobalCell FINAL : public LTemplateInstruction<0, 1, 1> {
+ public:
+  LStoreGlobalCell(LOperand* value, LOperand* temp) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreGlobalCell, "store-global-cell")
+  DECLARE_HYDROGEN_ACCESSOR(StoreGlobalCell)
+};
+
+
+class LLoadContextSlot FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LLoadContextSlot(LOperand* context) { inputs_[0] = context; }
+
+  LOperand* context() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
+  DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
+
+  int slot_index() { return hydrogen()->slot_index(); }
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LStoreContextSlot FINAL : public LTemplateInstruction<0, 2, 0> {
+ public:
+  LStoreContextSlot(LOperand* context, LOperand* value) {
+    inputs_[0] = context;
+    inputs_[1] = value;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* value() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
+  DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
+
+  int slot_index() { return hydrogen()->slot_index(); }
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LPushArgument FINAL : public LTemplateInstruction<0, 1, 0> {
+ public:
+  explicit LPushArgument(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
+};
+
+
+class LDrop FINAL : 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 LStoreCodeEntry FINAL : public LTemplateInstruction<0, 2, 0> {
+ public:
+  LStoreCodeEntry(LOperand* function, LOperand* code_object) {
+    inputs_[0] = function;
+    inputs_[1] = code_object;
+  }
+
+  LOperand* function() { return inputs_[0]; }
+  LOperand* code_object() { return inputs_[1]; }
+
+  virtual void PrintDataTo(StringStream* stream);
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
+  DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
+};
+
+
+class LInnerAllocatedObject FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LInnerAllocatedObject(LOperand* base_object, LOperand* offset) {
+    inputs_[0] = base_object;
+    inputs_[1] = offset;
+  }
+
+  LOperand* base_object() const { return inputs_[0]; }
+  LOperand* offset() const { return inputs_[1]; }
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+
+  DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
+};
+
+
+class LThisFunction FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
+  DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
+};
+
+
+class LContext FINAL : public LTemplateInstruction<1, 0, 0> {
+ public:
+  DECLARE_CONCRETE_INSTRUCTION(Context, "context")
+  DECLARE_HYDROGEN_ACCESSOR(Context)
+};
+
+
+class LDeclareGlobals FINAL : public LTemplateInstruction<0, 1, 0> {
+ public:
+  explicit LDeclareGlobals(LOperand* context) { inputs_[0] = context; }
+
+  LOperand* context() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
+  DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals)
+};
+
+
+class LCallJSFunction FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LCallJSFunction(LOperand* function) { inputs_[0] = function; }
+
+  LOperand* function() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
+  DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+
+  int arity() const { return hydrogen()->argument_count() - 1; }
+};
+
+
+class LCallWithDescriptor FINAL : public LTemplateResultInstruction<1> {
+ public:
+  LCallWithDescriptor(CallInterfaceDescriptor descriptor,
+                      const ZoneList<LOperand*>& operands, Zone* zone)
+      : descriptor_(descriptor),
+        inputs_(descriptor.GetRegisterParameterCount() + 1, zone) {
+    DCHECK(descriptor.GetRegisterParameterCount() + 1 == operands.length());
+    inputs_.AddAll(operands, zone);
+  }
+
+  LOperand* target() const { return inputs_[0]; }
+
+  const CallInterfaceDescriptor descriptor() { return descriptor_; }
+
+ private:
+  DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
+  DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+
+  int arity() const { return hydrogen()->argument_count() - 1; }
+
+  CallInterfaceDescriptor descriptor_;
+  ZoneList<LOperand*> inputs_;
+
+  // Iterator support.
+  int InputCount() FINAL { return inputs_.length(); }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
+
+  int TempCount() FINAL { return 0; }
+  LOperand* TempAt(int i) FINAL { return NULL; }
+};
+
+
+class LInvokeFunction FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LInvokeFunction(LOperand* context, LOperand* function) {
+    inputs_[0] = context;
+    inputs_[1] = function;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* function() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
+  DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+
+  int arity() const { return hydrogen()->argument_count() - 1; }
+};
+
+
+class LCallFunction FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LCallFunction(LOperand* context, LOperand* function) {
+    inputs_[0] = context;
+    inputs_[1] = function;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* function() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
+  DECLARE_HYDROGEN_ACCESSOR(CallFunction)
+
+  int arity() const { return hydrogen()->argument_count() - 1; }
+};
+
+
+class LCallNew FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LCallNew(LOperand* context, LOperand* constructor) {
+    inputs_[0] = context;
+    inputs_[1] = constructor;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* constructor() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
+  DECLARE_HYDROGEN_ACCESSOR(CallNew)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+
+  int arity() const { return hydrogen()->argument_count() - 1; }
+};
+
+
+class LCallNewArray FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LCallNewArray(LOperand* context, LOperand* constructor) {
+    inputs_[0] = context;
+    inputs_[1] = constructor;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* constructor() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
+  DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+
+  int arity() const { return hydrogen()->argument_count() - 1; }
+};
+
+
+class LCallRuntime FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LCallRuntime(LOperand* context) { inputs_[0] = context; }
+
+  LOperand* context() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
+  DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
+
+  bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
+    return save_doubles() == kDontSaveFPRegs;
+  }
+
+  const Runtime::Function* function() const { return hydrogen()->function(); }
+  int arity() const { return hydrogen()->argument_count(); }
+  SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); }
+};
+
+
+class LInteger32ToDouble FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LInteger32ToDouble(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
+};
+
+
+class LUint32ToDouble FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LUint32ToDouble(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
+};
+
+
+class LNumberTagI FINAL : public LTemplateInstruction<1, 1, 2> {
+ public:
+  LNumberTagI(LOperand* value, LOperand* temp1, LOperand* temp2) {
+    inputs_[0] = value;
+    temps_[0] = temp1;
+    temps_[1] = temp2;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp1() { return temps_[0]; }
+  LOperand* temp2() { return temps_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
+};
+
+
+class LNumberTagU FINAL : public LTemplateInstruction<1, 1, 2> {
+ public:
+  LNumberTagU(LOperand* value, LOperand* temp1, LOperand* temp2) {
+    inputs_[0] = value;
+    temps_[0] = temp1;
+    temps_[1] = temp2;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp1() { return temps_[0]; }
+  LOperand* temp2() { return temps_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
+};
+
+
+class LNumberTagD FINAL : public LTemplateInstruction<1, 1, 2> {
+ public:
+  LNumberTagD(LOperand* value, LOperand* temp, LOperand* temp2) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+    temps_[1] = temp2;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+  LOperand* temp2() { return temps_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
+  DECLARE_HYDROGEN_ACCESSOR(Change)
+};
+
+
+class LDoubleToSmi FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LDoubleToSmi(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
+  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
+
+  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
+};
+
+
+// Sometimes truncating conversion from a tagged value to an int32.
+class LDoubleToI FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LDoubleToI(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
+  DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
+
+  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
+};
+
+
+// Truncating conversion from a tagged value to an int32.
+class LTaggedToI FINAL : public LTemplateInstruction<1, 1, 2> {
+ public:
+  LTaggedToI(LOperand* value, LOperand* temp, LOperand* temp2) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+    temps_[1] = temp2;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+  LOperand* temp2() { return temps_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
+  DECLARE_HYDROGEN_ACCESSOR(Change)
+
+  bool truncating() { return hydrogen()->CanTruncateToInt32(); }
+};
+
+
+class LSmiTag FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LSmiTag(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
+  DECLARE_HYDROGEN_ACCESSOR(Change)
+};
+
+
+class LNumberUntagD FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LNumberUntagD(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
+  DECLARE_HYDROGEN_ACCESSOR(Change)
+};
+
+
+class LSmiUntag FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  LSmiUntag(LOperand* value, bool needs_check) : needs_check_(needs_check) {
+    inputs_[0] = value;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  bool needs_check() const { return needs_check_; }
+
+  DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
+
+ private:
+  bool needs_check_;
+};
+
+
+class LStoreNamedField FINAL : public LTemplateInstruction<0, 2, 1> {
+ public:
+  LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) {
+    inputs_[0] = object;
+    inputs_[1] = value;
+    temps_[0] = temp;
+  }
+
+  LOperand* object() { return inputs_[0]; }
+  LOperand* value() { return inputs_[1]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
+  DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+
+  Representation representation() const {
+    return hydrogen()->field_representation();
+  }
+};
+
+
+class LStoreNamedGeneric FINAL : public LTemplateInstruction<0, 3, 0> {
+ public:
+  LStoreNamedGeneric(LOperand* context, LOperand* object, LOperand* value) {
+    inputs_[0] = context;
+    inputs_[1] = object;
+    inputs_[2] = value;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* object() { return inputs_[1]; }
+  LOperand* value() { return inputs_[2]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
+  DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+
+  Handle<Object> name() const { return hydrogen()->name(); }
+  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
+};
+
+
+class LStoreKeyed FINAL : public LTemplateInstruction<0, 3, 0> {
+ public:
+  LStoreKeyed(LOperand* object, LOperand* key, LOperand* value) {
+    inputs_[0] = object;
+    inputs_[1] = key;
+    inputs_[2] = value;
+  }
+
+  bool is_external() const { return hydrogen()->is_external(); }
+  bool is_fixed_typed_array() const {
+    return hydrogen()->is_fixed_typed_array();
+  }
+  bool is_typed_elements() const {
+    return is_external() || is_fixed_typed_array();
+  }
+  LOperand* elements() { return inputs_[0]; }
+  LOperand* key() { return inputs_[1]; }
+  LOperand* value() { return inputs_[2]; }
+  ElementsKind elements_kind() const { return hydrogen()->elements_kind(); }
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool NeedsCanonicalization() {
+    if (hydrogen()->value()->IsAdd() || hydrogen()->value()->IsSub() ||
+        hydrogen()->value()->IsMul() || hydrogen()->value()->IsDiv()) {
+      return false;
+    }
+    return hydrogen()->NeedsCanonicalization();
+  }
+  uint32_t base_offset() const { return hydrogen()->base_offset(); }
+};
+
+
+class LStoreKeyedGeneric FINAL : public LTemplateInstruction<0, 4, 0> {
+ public:
+  LStoreKeyedGeneric(LOperand* context, LOperand* obj, LOperand* key,
+                     LOperand* value) {
+    inputs_[0] = context;
+    inputs_[1] = obj;
+    inputs_[2] = key;
+    inputs_[3] = value;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* object() { return inputs_[1]; }
+  LOperand* key() { return inputs_[2]; }
+  LOperand* value() { return inputs_[3]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
+  DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+
+  StrictMode strict_mode() { return hydrogen()->strict_mode(); }
+};
+
+
+class LTransitionElementsKind FINAL : public LTemplateInstruction<0, 2, 1> {
+ public:
+  LTransitionElementsKind(LOperand* object, LOperand* context,
+                          LOperand* new_map_temp) {
+    inputs_[0] = object;
+    inputs_[1] = context;
+    temps_[0] = new_map_temp;
+  }
+
+  LOperand* context() { return inputs_[1]; }
+  LOperand* object() { return inputs_[0]; }
+  LOperand* new_map_temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
+                               "transition-elements-kind")
+  DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+
+  Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
+  Handle<Map> transitioned_map() {
+    return hydrogen()->transitioned_map().handle();
+  }
+  ElementsKind from_kind() { return hydrogen()->from_kind(); }
+  ElementsKind to_kind() { return hydrogen()->to_kind(); }
+};
+
+
+class LTrapAllocationMemento FINAL : public LTemplateInstruction<0, 1, 1> {
+ public:
+  LTrapAllocationMemento(LOperand* object, LOperand* temp) {
+    inputs_[0] = object;
+    temps_[0] = temp;
+  }
+
+  LOperand* object() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento, "trap-allocation-memento")
+};
+
+
+class LStringAdd FINAL : public LTemplateInstruction<1, 3, 0> {
+ public:
+  LStringAdd(LOperand* context, LOperand* left, LOperand* right) {
+    inputs_[0] = context;
+    inputs_[1] = left;
+    inputs_[2] = right;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* left() { return inputs_[1]; }
+  LOperand* right() { return inputs_[2]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
+  DECLARE_HYDROGEN_ACCESSOR(StringAdd)
+};
+
+
+class LStringCharCodeAt FINAL : public LTemplateInstruction<1, 3, 0> {
+ public:
+  LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) {
+    inputs_[0] = context;
+    inputs_[1] = string;
+    inputs_[2] = index;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* string() { return inputs_[1]; }
+  LOperand* index() { return inputs_[2]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
+  DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
+};
+
+
+class LStringCharFromCode FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  explicit LStringCharFromCode(LOperand* context, LOperand* char_code) {
+    inputs_[0] = context;
+    inputs_[1] = char_code;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* char_code() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
+  DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
+};
+
+
+class LCheckValue FINAL : public LTemplateInstruction<0, 1, 0> {
+ public:
+  explicit LCheckValue(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
+  DECLARE_HYDROGEN_ACCESSOR(CheckValue)
+};
+
+
+class LCheckInstanceType FINAL : public LTemplateInstruction<0, 1, 0> {
+ public:
+  explicit LCheckInstanceType(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
+  DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
+};
+
+
+class LCheckMaps FINAL : public LTemplateInstruction<0, 1, 0> {
+ public:
+  explicit LCheckMaps(LOperand* value = NULL) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
+  DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
+};
+
+
+class LCheckSmi FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LCheckSmi(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
+};
+
+
+class LCheckNonSmi FINAL : public LTemplateInstruction<0, 1, 0> {
+ public:
+  explicit LCheckNonSmi(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
+  DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
+};
+
+
+class LClampDToUint8 FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LClampDToUint8(LOperand* unclamped) { inputs_[0] = unclamped; }
+
+  LOperand* unclamped() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
+};
+
+
+class LClampIToUint8 FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LClampIToUint8(LOperand* unclamped) { inputs_[0] = unclamped; }
+
+  LOperand* unclamped() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8")
+};
+
+
+class LClampTToUint8 FINAL : public LTemplateInstruction<1, 1, 1> {
+ public:
+  LClampTToUint8(LOperand* unclamped, LOperand* temp) {
+    inputs_[0] = unclamped;
+    temps_[0] = temp;
+  }
+
+  LOperand* unclamped() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
+};
+
+
+class LDoubleBits FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LDoubleBits(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(DoubleBits, "double-bits")
+  DECLARE_HYDROGEN_ACCESSOR(DoubleBits)
+};
+
+
+class LConstructDouble FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LConstructDouble(LOperand* hi, LOperand* lo) {
+    inputs_[0] = hi;
+    inputs_[1] = lo;
+  }
+
+  LOperand* hi() { return inputs_[0]; }
+  LOperand* lo() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ConstructDouble, "construct-double")
+};
+
+
+class LAllocate FINAL : public LTemplateInstruction<1, 2, 2> {
+ public:
+  LAllocate(LOperand* context, LOperand* size, LOperand* temp1,
+            LOperand* temp2) {
+    inputs_[0] = context;
+    inputs_[1] = size;
+    temps_[0] = temp1;
+    temps_[1] = temp2;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* size() { return inputs_[1]; }
+  LOperand* temp1() { return temps_[0]; }
+  LOperand* temp2() { return temps_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate")
+  DECLARE_HYDROGEN_ACCESSOR(Allocate)
+};
+
+
+class LRegExpLiteral FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LRegExpLiteral(LOperand* context) { inputs_[0] = context; }
+
+  LOperand* context() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal")
+  DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral)
+};
+
+
+class LFunctionLiteral FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LFunctionLiteral(LOperand* context) { inputs_[0] = context; }
+
+  LOperand* context() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(FunctionLiteral, "function-literal")
+  DECLARE_HYDROGEN_ACCESSOR(FunctionLiteral)
+};
+
+
+class LToFastProperties FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LToFastProperties(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ToFastProperties, "to-fast-properties")
+  DECLARE_HYDROGEN_ACCESSOR(ToFastProperties)
+};
+
+
+class LTypeof FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LTypeof(LOperand* context, LOperand* value) {
+    inputs_[0] = context;
+    inputs_[1] = value;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* value() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
+};
+
+
+class LTypeofIsAndBranch FINAL : public LControlInstruction<1, 0> {
+ public:
+  explicit LTypeofIsAndBranch(LOperand* value) { inputs_[0] = value; }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
+
+  Handle<String> type_literal() { return hydrogen()->type_literal(); }
+
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+};
+
+
+class LIsConstructCallAndBranch FINAL : public LControlInstruction<0, 1> {
+ public:
+  explicit LIsConstructCallAndBranch(LOperand* temp) { temps_[0] = temp; }
+
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(IsConstructCallAndBranch,
+                               "is-construct-call-and-branch")
+};
+
+
+class LOsrEntry FINAL : public LTemplateInstruction<0, 0, 0> {
+ public:
+  LOsrEntry() {}
+
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
+  DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
+};
+
+
+class LStackCheck FINAL : public LTemplateInstruction<0, 1, 0> {
+ public:
+  explicit LStackCheck(LOperand* context) { inputs_[0] = context; }
+
+  LOperand* context() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
+  DECLARE_HYDROGEN_ACCESSOR(StackCheck)
+
+  Label* done_label() { return &done_label_; }
+
+ private:
+  Label done_label_;
+};
+
+
+class LForInPrepareMap FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LForInPrepareMap(LOperand* context, LOperand* object) {
+    inputs_[0] = context;
+    inputs_[1] = object;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* object() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map")
+};
+
+
+class LForInCacheArray FINAL : public LTemplateInstruction<1, 1, 0> {
+ public:
+  explicit LForInCacheArray(LOperand* map) { inputs_[0] = map; }
+
+  LOperand* map() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array")
+
+  int idx() { return HForInCacheArray::cast(this->hydrogen_value())->idx(); }
+};
+
+
+class LCheckMapValue FINAL : public LTemplateInstruction<0, 2, 0> {
+ public:
+  LCheckMapValue(LOperand* value, LOperand* map) {
+    inputs_[0] = value;
+    inputs_[1] = map;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* map() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value")
+};
+
+
+class LLoadFieldByIndex FINAL : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LLoadFieldByIndex(LOperand* object, LOperand* index) {
+    inputs_[0] = object;
+    inputs_[1] = index;
+  }
+
+  LOperand* object() { return inputs_[0]; }
+  LOperand* index() { return inputs_[1]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index")
+};
+
+
+class LStoreFrameContext : public LTemplateInstruction<0, 1, 0> {
+ public:
+  explicit LStoreFrameContext(LOperand* context) { inputs_[0] = context; }
+
+  LOperand* context() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(StoreFrameContext, "store-frame-context")
+};
+
+
+class LAllocateBlockContext : public LTemplateInstruction<1, 2, 0> {
+ public:
+  LAllocateBlockContext(LOperand* context, LOperand* function) {
+    inputs_[0] = context;
+    inputs_[1] = function;
+  }
+
+  LOperand* context() { return inputs_[0]; }
+  LOperand* function() { return inputs_[1]; }
+
+  Handle<ScopeInfo> scope_info() { return hydrogen()->scope_info(); }
+
+  DECLARE_CONCRETE_INSTRUCTION(AllocateBlockContext, "allocate-block-context")
+  DECLARE_HYDROGEN_ACCESSOR(AllocateBlockContext)
+};
+
+
+class LChunkBuilder;
+class LPlatformChunk FINAL : public LChunk {
+ public:
+  LPlatformChunk(CompilationInfo* info, HGraph* graph) : LChunk(info, graph) {}
+
+  int GetNextSpillIndex(RegisterKind kind);
+  LOperand* GetNextSpillSlot(RegisterKind kind);
+};
+
+
+class LChunkBuilder FINAL : public LChunkBuilderBase {
+ public:
+  LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
+      : LChunkBuilderBase(info, graph),
+        current_instruction_(NULL),
+        current_block_(NULL),
+        next_block_(NULL),
+        allocator_(allocator) {}
+
+  // Build the sequence for the graph.
+  LPlatformChunk* Build();
+
+// Declare methods that deal with the individual node types.
+#define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
+  HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
+#undef DECLARE_DO
+
+  LInstruction* DoMultiplyAdd(HMul* mul, HValue* addend);
+  LInstruction* DoMultiplySub(HValue* minuend, HMul* mul);
+  LInstruction* DoRSub(HSub* instr);
+
+  static bool HasMagicNumberForDivisor(int32_t divisor);
+
+  LInstruction* DoMathFloor(HUnaryMathOperation* instr);
+  LInstruction* DoMathRound(HUnaryMathOperation* instr);
+  LInstruction* DoMathFround(HUnaryMathOperation* instr);
+  LInstruction* DoMathAbs(HUnaryMathOperation* instr);
+  LInstruction* DoMathLog(HUnaryMathOperation* instr);
+  LInstruction* DoMathExp(HUnaryMathOperation* instr);
+  LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
+  LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
+  LInstruction* DoMathClz32(HUnaryMathOperation* instr);
+  LInstruction* DoDivByPowerOf2I(HDiv* instr);
+  LInstruction* DoDivByConstI(HDiv* instr);
+  LInstruction* DoDivI(HDiv* instr);
+  LInstruction* DoModByPowerOf2I(HMod* instr);
+  LInstruction* DoModByConstI(HMod* instr);
+  LInstruction* DoModI(HMod* instr);
+  LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
+  LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
+  LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
+
+ private:
+  // Methods for getting operands for Use / Define / Temp.
+  LUnallocated* ToUnallocated(Register reg);
+  LUnallocated* ToUnallocated(DoubleRegister reg);
+
+  // Methods for setting up define-use relationships.
+  MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
+  MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
+  MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
+                                           DoubleRegister fixed_register);
+
+  // A value that is guaranteed to be allocated to a register.
+  // Operand created by UseRegister is guaranteed to be live until the end of
+  // instruction. This means that register allocator will not reuse it's
+  // register for any other operand inside instruction.
+  // Operand created by UseRegisterAtStart is guaranteed to be live only at
+  // instruction start. Register allocator is free to assign the same register
+  // to some other operand used inside instruction (i.e. temporary or
+  // output).
+  MUST_USE_RESULT LOperand* UseRegister(HValue* value);
+  MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
+
+  // An input operand in a register that may be trashed.
+  MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
+
+  // An input operand in a register or stack slot.
+  MUST_USE_RESULT LOperand* Use(HValue* value);
+  MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
+
+  // An input operand in a register, stack slot or a constant operand.
+  MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
+  MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
+
+  // An input operand in a register or a constant operand.
+  MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
+  MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
+
+  // An input operand in a constant operand.
+  MUST_USE_RESULT LOperand* UseConstant(HValue* value);
+
+  // An input operand in register, stack slot or a constant operand.
+  // Will not be moved to a register even if one is freely available.
+  MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
+
+  // Temporary operand that must be in a register.
+  MUST_USE_RESULT LUnallocated* TempRegister();
+  MUST_USE_RESULT LUnallocated* TempDoubleRegister();
+  MUST_USE_RESULT LOperand* FixedTemp(Register reg);
+  MUST_USE_RESULT LOperand* FixedTemp(DoubleRegister reg);
+
+  // Methods for setting up define-use relationships.
+  // Return the same instruction that they are passed.
+  LInstruction* Define(LTemplateResultInstruction<1>* instr,
+                       LUnallocated* result);
+  LInstruction* DefineAsRegister(LTemplateResultInstruction<1>* instr);
+  LInstruction* DefineAsSpilled(LTemplateResultInstruction<1>* instr,
+                                int index);
+  LInstruction* DefineSameAsFirst(LTemplateResultInstruction<1>* instr);
+  LInstruction* DefineFixed(LTemplateResultInstruction<1>* instr, Register reg);
+  LInstruction* DefineFixedDouble(LTemplateResultInstruction<1>* instr,
+                                  DoubleRegister reg);
+  LInstruction* AssignEnvironment(LInstruction* instr);
+  LInstruction* AssignPointerMap(LInstruction* instr);
+
+  enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
+
+  // By default we assume that instruction sequences generated for calls
+  // cannot deoptimize eagerly and we do not attach environment to this
+  // instruction.
+  LInstruction* MarkAsCall(
+      LInstruction* instr, HInstruction* hinstr,
+      CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
+
+  void VisitInstruction(HInstruction* current);
+  void AddInstruction(LInstruction* instr, HInstruction* current);
+
+  void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
+  LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
+  LInstruction* DoArithmeticD(Token::Value op,
+                              HArithmeticBinaryOperation* instr);
+  LInstruction* DoArithmeticT(Token::Value op, HBinaryOperation* instr);
+
+  HInstruction* current_instruction_;
+  HBasicBlock* current_block_;
+  HBasicBlock* next_block_;
+  LAllocator* allocator_;
+
+  DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
+};
+
+#undef DECLARE_HYDROGEN_ACCESSOR
+#undef DECLARE_CONCRETE_INSTRUCTION
+}
+}  // namespace v8::internal
+
+#endif  // V8_PPC_LITHIUM_PPC_H_
diff --git a/src/ppc/macro-assembler-ppc.cc b/src/ppc/macro-assembler-ppc.cc
new file mode 100644
index 0000000..0b3d729
--- /dev/null
+++ b/src/ppc/macro-assembler-ppc.cc
@@ -0,0 +1,4819 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <assert.h>  // For assert
+#include <limits.h>  // For LONG_MIN, LONG_MAX.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/base/bits.h"
+#include "src/base/division-by-constant.h"
+#include "src/bootstrapper.h"
+#include "src/codegen.h"
+#include "src/cpu-profiler.h"
+#include "src/debug.h"
+#include "src/isolate-inl.h"
+#include "src/runtime/runtime.h"
+
+namespace v8 {
+namespace internal {
+
+MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size)
+    : Assembler(arg_isolate, buffer, size),
+      generating_stub_(false),
+      has_frame_(false) {
+  if (isolate() != NULL) {
+    code_object_ =
+        Handle<Object>(isolate()->heap()->undefined_value(), isolate());
+  }
+}
+
+
+void MacroAssembler::Jump(Register target) {
+  mtctr(target);
+  bctr();
+}
+
+
+void MacroAssembler::JumpToJSEntry(Register target) {
+  Move(ip, target);
+  Jump(ip);
+}
+
+
+void MacroAssembler::Jump(intptr_t target, RelocInfo::Mode rmode,
+                          Condition cond, CRegister cr) {
+  Label skip;
+
+  if (cond != al) b(NegateCondition(cond), &skip, cr);
+
+  DCHECK(rmode == RelocInfo::CODE_TARGET || rmode == RelocInfo::RUNTIME_ENTRY);
+
+  mov(ip, Operand(target, rmode));
+  mtctr(ip);
+  bctr();
+
+  bind(&skip);
+}
+
+
+void MacroAssembler::Jump(Address target, RelocInfo::Mode rmode, Condition cond,
+                          CRegister cr) {
+  DCHECK(!RelocInfo::IsCodeTarget(rmode));
+  Jump(reinterpret_cast<intptr_t>(target), rmode, cond, cr);
+}
+
+
+void MacroAssembler::Jump(Handle<Code> code, RelocInfo::Mode rmode,
+                          Condition cond) {
+  DCHECK(RelocInfo::IsCodeTarget(rmode));
+  // 'code' is always generated ppc code, never THUMB code
+  AllowDeferredHandleDereference embedding_raw_address;
+  Jump(reinterpret_cast<intptr_t>(code.location()), rmode, cond);
+}
+
+
+int MacroAssembler::CallSize(Register target) { return 2 * kInstrSize; }
+
+
+void MacroAssembler::Call(Register target) {
+  BlockTrampolinePoolScope block_trampoline_pool(this);
+  Label start;
+  bind(&start);
+
+  // Statement positions are expected to be recorded when the target
+  // address is loaded.
+  positions_recorder()->WriteRecordedPositions();
+
+  // branch via link register and set LK bit for return point
+  mtctr(target);
+  bctrl();
+
+  DCHECK_EQ(CallSize(target), SizeOfCodeGeneratedSince(&start));
+}
+
+
+void MacroAssembler::CallJSEntry(Register target) {
+  DCHECK(target.is(ip));
+  Call(target);
+}
+
+
+int MacroAssembler::CallSize(Address target, RelocInfo::Mode rmode,
+                             Condition cond) {
+  Operand mov_operand = Operand(reinterpret_cast<intptr_t>(target), rmode);
+  return (2 + instructions_required_for_mov(mov_operand)) * kInstrSize;
+}
+
+
+int MacroAssembler::CallSizeNotPredictableCodeSize(Address target,
+                                                   RelocInfo::Mode rmode,
+                                                   Condition cond) {
+  return (2 + kMovInstructionsNoConstantPool) * kInstrSize;
+}
+
+
+void MacroAssembler::Call(Address target, RelocInfo::Mode rmode,
+                          Condition cond) {
+  BlockTrampolinePoolScope block_trampoline_pool(this);
+  DCHECK(cond == al);
+
+#ifdef DEBUG
+  // Check the expected size before generating code to ensure we assume the same
+  // constant pool availability (e.g., whether constant pool is full or not).
+  int expected_size = CallSize(target, rmode, cond);
+  Label start;
+  bind(&start);
+#endif
+
+  // Statement positions are expected to be recorded when the target
+  // address is loaded.
+  positions_recorder()->WriteRecordedPositions();
+
+  // This can likely be optimized to make use of bc() with 24bit relative
+  //
+  // RecordRelocInfo(x.rmode_, x.imm_);
+  // bc( BA, .... offset, LKset);
+  //
+
+  mov(ip, Operand(reinterpret_cast<intptr_t>(target), rmode));
+  mtctr(ip);
+  bctrl();
+
+  DCHECK_EQ(expected_size, SizeOfCodeGeneratedSince(&start));
+}
+
+
+int MacroAssembler::CallSize(Handle<Code> code, RelocInfo::Mode rmode,
+                             TypeFeedbackId ast_id, Condition cond) {
+  AllowDeferredHandleDereference using_raw_address;
+  return CallSize(reinterpret_cast<Address>(code.location()), rmode, cond);
+}
+
+
+void MacroAssembler::Call(Handle<Code> code, RelocInfo::Mode rmode,
+                          TypeFeedbackId ast_id, Condition cond) {
+  BlockTrampolinePoolScope block_trampoline_pool(this);
+  DCHECK(RelocInfo::IsCodeTarget(rmode));
+
+#ifdef DEBUG
+  // Check the expected size before generating code to ensure we assume the same
+  // constant pool availability (e.g., whether constant pool is full or not).
+  int expected_size = CallSize(code, rmode, ast_id, cond);
+  Label start;
+  bind(&start);
+#endif
+
+  if (rmode == RelocInfo::CODE_TARGET && !ast_id.IsNone()) {
+    SetRecordedAstId(ast_id);
+    rmode = RelocInfo::CODE_TARGET_WITH_ID;
+  }
+  AllowDeferredHandleDereference using_raw_address;
+  Call(reinterpret_cast<Address>(code.location()), rmode, cond);
+  DCHECK_EQ(expected_size, SizeOfCodeGeneratedSince(&start));
+}
+
+
+void MacroAssembler::Ret(Condition cond) {
+  DCHECK(cond == al);
+  blr();
+}
+
+
+void MacroAssembler::Drop(int count, Condition cond) {
+  DCHECK(cond == al);
+  if (count > 0) {
+    Add(sp, sp, count * kPointerSize, r0);
+  }
+}
+
+
+void MacroAssembler::Ret(int drop, Condition cond) {
+  Drop(drop, cond);
+  Ret(cond);
+}
+
+
+void MacroAssembler::Call(Label* target) { b(target, SetLK); }
+
+
+void MacroAssembler::Push(Handle<Object> handle) {
+  mov(r0, Operand(handle));
+  push(r0);
+}
+
+
+void MacroAssembler::Move(Register dst, Handle<Object> value) {
+  AllowDeferredHandleDereference smi_check;
+  if (value->IsSmi()) {
+    LoadSmiLiteral(dst, reinterpret_cast<Smi*>(*value));
+  } else {
+    DCHECK(value->IsHeapObject());
+    if (isolate()->heap()->InNewSpace(*value)) {
+      Handle<Cell> cell = isolate()->factory()->NewCell(value);
+      mov(dst, Operand(cell));
+      LoadP(dst, FieldMemOperand(dst, Cell::kValueOffset));
+    } else {
+      mov(dst, Operand(value));
+    }
+  }
+}
+
+
+void MacroAssembler::Move(Register dst, Register src, Condition cond) {
+  DCHECK(cond == al);
+  if (!dst.is(src)) {
+    mr(dst, src);
+  }
+}
+
+
+void MacroAssembler::Move(DoubleRegister dst, DoubleRegister src) {
+  if (!dst.is(src)) {
+    fmr(dst, src);
+  }
+}
+
+
+void MacroAssembler::MultiPush(RegList regs) {
+  int16_t num_to_push = NumberOfBitsSet(regs);
+  int16_t stack_offset = num_to_push * kPointerSize;
+
+  subi(sp, sp, Operand(stack_offset));
+  for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
+    if ((regs & (1 << i)) != 0) {
+      stack_offset -= kPointerSize;
+      StoreP(ToRegister(i), MemOperand(sp, stack_offset));
+    }
+  }
+}
+
+
+void MacroAssembler::MultiPop(RegList regs) {
+  int16_t stack_offset = 0;
+
+  for (int16_t i = 0; i < kNumRegisters; i++) {
+    if ((regs & (1 << i)) != 0) {
+      LoadP(ToRegister(i), MemOperand(sp, stack_offset));
+      stack_offset += kPointerSize;
+    }
+  }
+  addi(sp, sp, Operand(stack_offset));
+}
+
+
+void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index,
+                              Condition cond) {
+  DCHECK(cond == al);
+  LoadP(destination, MemOperand(kRootRegister, index << kPointerSizeLog2), r0);
+}
+
+
+void MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index,
+                               Condition cond) {
+  DCHECK(cond == al);
+  StoreP(source, MemOperand(kRootRegister, index << kPointerSizeLog2), r0);
+}
+
+
+void MacroAssembler::InNewSpace(Register object, Register scratch,
+                                Condition cond, Label* branch) {
+  // N.B. scratch may be same register as object
+  DCHECK(cond == eq || cond == ne);
+  mov(r0, Operand(ExternalReference::new_space_mask(isolate())));
+  and_(scratch, object, r0);
+  mov(r0, Operand(ExternalReference::new_space_start(isolate())));
+  cmp(scratch, r0);
+  b(cond, branch);
+}
+
+
+void MacroAssembler::RecordWriteField(
+    Register object, int offset, Register value, Register dst,
+    LinkRegisterStatus lr_status, SaveFPRegsMode save_fp,
+    RememberedSetAction remembered_set_action, SmiCheck smi_check,
+    PointersToHereCheck pointers_to_here_check_for_value) {
+  // First, check if a write barrier is even needed. The tests below
+  // catch stores of Smis.
+  Label done;
+
+  // Skip barrier if writing a smi.
+  if (smi_check == INLINE_SMI_CHECK) {
+    JumpIfSmi(value, &done);
+  }
+
+  // Although the object register is tagged, the offset is relative to the start
+  // of the object, so so offset must be a multiple of kPointerSize.
+  DCHECK(IsAligned(offset, kPointerSize));
+
+  Add(dst, object, offset - kHeapObjectTag, r0);
+  if (emit_debug_code()) {
+    Label ok;
+    andi(r0, dst, Operand((1 << kPointerSizeLog2) - 1));
+    beq(&ok, cr0);
+    stop("Unaligned cell in write barrier");
+    bind(&ok);
+  }
+
+  RecordWrite(object, dst, value, lr_status, save_fp, remembered_set_action,
+              OMIT_SMI_CHECK, pointers_to_here_check_for_value);
+
+  bind(&done);
+
+  // Clobber clobbered input registers when running with the debug-code flag
+  // turned on to provoke errors.
+  if (emit_debug_code()) {
+    mov(value, Operand(bit_cast<intptr_t>(kZapValue + 4)));
+    mov(dst, Operand(bit_cast<intptr_t>(kZapValue + 8)));
+  }
+}
+
+
+// Will clobber 4 registers: object, map, dst, ip.  The
+// register 'object' contains a heap object pointer.
+void MacroAssembler::RecordWriteForMap(Register object, Register map,
+                                       Register dst,
+                                       LinkRegisterStatus lr_status,
+                                       SaveFPRegsMode fp_mode) {
+  if (emit_debug_code()) {
+    LoadP(dst, FieldMemOperand(map, HeapObject::kMapOffset));
+    Cmpi(dst, Operand(isolate()->factory()->meta_map()), r0);
+    Check(eq, kWrongAddressOrValuePassedToRecordWrite);
+  }
+
+  if (!FLAG_incremental_marking) {
+    return;
+  }
+
+  if (emit_debug_code()) {
+    LoadP(ip, FieldMemOperand(object, HeapObject::kMapOffset));
+    cmp(ip, map);
+    Check(eq, kWrongAddressOrValuePassedToRecordWrite);
+  }
+
+  Label done;
+
+  // A single check of the map's pages interesting flag suffices, since it is
+  // only set during incremental collection, and then it's also guaranteed that
+  // the from object's page's interesting flag is also set.  This optimization
+  // relies on the fact that maps can never be in new space.
+  CheckPageFlag(map,
+                map,  // Used as scratch.
+                MemoryChunk::kPointersToHereAreInterestingMask, eq, &done);
+
+  addi(dst, object, Operand(HeapObject::kMapOffset - kHeapObjectTag));
+  if (emit_debug_code()) {
+    Label ok;
+    andi(r0, dst, Operand((1 << kPointerSizeLog2) - 1));
+    beq(&ok, cr0);
+    stop("Unaligned cell in write barrier");
+    bind(&ok);
+  }
+
+  // Record the actual write.
+  if (lr_status == kLRHasNotBeenSaved) {
+    mflr(r0);
+    push(r0);
+  }
+  RecordWriteStub stub(isolate(), object, map, dst, OMIT_REMEMBERED_SET,
+                       fp_mode);
+  CallStub(&stub);
+  if (lr_status == kLRHasNotBeenSaved) {
+    pop(r0);
+    mtlr(r0);
+  }
+
+  bind(&done);
+
+  // Count number of write barriers in generated code.
+  isolate()->counters()->write_barriers_static()->Increment();
+  IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1, ip, dst);
+
+  // Clobber clobbered registers when running with the debug-code flag
+  // turned on to provoke errors.
+  if (emit_debug_code()) {
+    mov(dst, Operand(bit_cast<intptr_t>(kZapValue + 12)));
+    mov(map, Operand(bit_cast<intptr_t>(kZapValue + 16)));
+  }
+}
+
+
+// Will clobber 4 registers: object, address, scratch, ip.  The
+// register 'object' contains a heap object pointer.  The heap object
+// tag is shifted away.
+void MacroAssembler::RecordWrite(
+    Register object, Register address, Register value,
+    LinkRegisterStatus lr_status, SaveFPRegsMode fp_mode,
+    RememberedSetAction remembered_set_action, SmiCheck smi_check,
+    PointersToHereCheck pointers_to_here_check_for_value) {
+  DCHECK(!object.is(value));
+  if (emit_debug_code()) {
+    LoadP(r0, MemOperand(address));
+    cmp(r0, value);
+    Check(eq, kWrongAddressOrValuePassedToRecordWrite);
+  }
+
+  if (remembered_set_action == OMIT_REMEMBERED_SET &&
+      !FLAG_incremental_marking) {
+    return;
+  }
+
+  // First, check if a write barrier is even needed. The tests below
+  // catch stores of smis and stores into the young generation.
+  Label done;
+
+  if (smi_check == INLINE_SMI_CHECK) {
+    JumpIfSmi(value, &done);
+  }
+
+  if (pointers_to_here_check_for_value != kPointersToHereAreAlwaysInteresting) {
+    CheckPageFlag(value,
+                  value,  // Used as scratch.
+                  MemoryChunk::kPointersToHereAreInterestingMask, eq, &done);
+  }
+  CheckPageFlag(object,
+                value,  // Used as scratch.
+                MemoryChunk::kPointersFromHereAreInterestingMask, eq, &done);
+
+  // Record the actual write.
+  if (lr_status == kLRHasNotBeenSaved) {
+    mflr(r0);
+    push(r0);
+  }
+  RecordWriteStub stub(isolate(), object, value, address, remembered_set_action,
+                       fp_mode);
+  CallStub(&stub);
+  if (lr_status == kLRHasNotBeenSaved) {
+    pop(r0);
+    mtlr(r0);
+  }
+
+  bind(&done);
+
+  // Count number of write barriers in generated code.
+  isolate()->counters()->write_barriers_static()->Increment();
+  IncrementCounter(isolate()->counters()->write_barriers_dynamic(), 1, ip,
+                   value);
+
+  // Clobber clobbered registers when running with the debug-code flag
+  // turned on to provoke errors.
+  if (emit_debug_code()) {
+    mov(address, Operand(bit_cast<intptr_t>(kZapValue + 12)));
+    mov(value, Operand(bit_cast<intptr_t>(kZapValue + 16)));
+  }
+}
+
+
+void MacroAssembler::RememberedSetHelper(Register object,  // For debug tests.
+                                         Register address, Register scratch,
+                                         SaveFPRegsMode fp_mode,
+                                         RememberedSetFinalAction and_then) {
+  Label done;
+  if (emit_debug_code()) {
+    Label ok;
+    JumpIfNotInNewSpace(object, scratch, &ok);
+    stop("Remembered set pointer is in new space");
+    bind(&ok);
+  }
+  // Load store buffer top.
+  ExternalReference store_buffer =
+      ExternalReference::store_buffer_top(isolate());
+  mov(ip, Operand(store_buffer));
+  LoadP(scratch, MemOperand(ip));
+  // Store pointer to buffer and increment buffer top.
+  StoreP(address, MemOperand(scratch));
+  addi(scratch, scratch, Operand(kPointerSize));
+  // Write back new top of buffer.
+  StoreP(scratch, MemOperand(ip));
+  // Call stub on end of buffer.
+  // Check for end of buffer.
+  mov(r0, Operand(StoreBuffer::kStoreBufferOverflowBit));
+  and_(r0, scratch, r0, SetRC);
+
+  if (and_then == kFallThroughAtEnd) {
+    beq(&done, cr0);
+  } else {
+    DCHECK(and_then == kReturnAtEnd);
+    beq(&done, cr0);
+  }
+  mflr(r0);
+  push(r0);
+  StoreBufferOverflowStub store_buffer_overflow(isolate(), fp_mode);
+  CallStub(&store_buffer_overflow);
+  pop(r0);
+  mtlr(r0);
+  bind(&done);
+  if (and_then == kReturnAtEnd) {
+    Ret();
+  }
+}
+
+
+void MacroAssembler::PushFixedFrame(Register marker_reg) {
+  mflr(r0);
+#if V8_OOL_CONSTANT_POOL
+  if (marker_reg.is_valid()) {
+    Push(r0, fp, kConstantPoolRegister, cp, marker_reg);
+  } else {
+    Push(r0, fp, kConstantPoolRegister, cp);
+  }
+#else
+  if (marker_reg.is_valid()) {
+    Push(r0, fp, cp, marker_reg);
+  } else {
+    Push(r0, fp, cp);
+  }
+#endif
+}
+
+
+void MacroAssembler::PopFixedFrame(Register marker_reg) {
+#if V8_OOL_CONSTANT_POOL
+  if (marker_reg.is_valid()) {
+    Pop(r0, fp, kConstantPoolRegister, cp, marker_reg);
+  } else {
+    Pop(r0, fp, kConstantPoolRegister, cp);
+  }
+#else
+  if (marker_reg.is_valid()) {
+    Pop(r0, fp, cp, marker_reg);
+  } else {
+    Pop(r0, fp, cp);
+  }
+#endif
+  mtlr(r0);
+}
+
+
+// Push and pop all registers that can hold pointers.
+void MacroAssembler::PushSafepointRegisters() {
+  // Safepoints expect a block of kNumSafepointRegisters values on the
+  // stack, so adjust the stack for unsaved registers.
+  const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters;
+  DCHECK(num_unsaved >= 0);
+  if (num_unsaved > 0) {
+    subi(sp, sp, Operand(num_unsaved * kPointerSize));
+  }
+  MultiPush(kSafepointSavedRegisters);
+}
+
+
+void MacroAssembler::PopSafepointRegisters() {
+  const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters;
+  MultiPop(kSafepointSavedRegisters);
+  if (num_unsaved > 0) {
+    addi(sp, sp, Operand(num_unsaved * kPointerSize));
+  }
+}
+
+
+void MacroAssembler::StoreToSafepointRegisterSlot(Register src, Register dst) {
+  StoreP(src, SafepointRegisterSlot(dst));
+}
+
+
+void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) {
+  LoadP(dst, SafepointRegisterSlot(src));
+}
+
+
+int MacroAssembler::SafepointRegisterStackIndex(int reg_code) {
+  // The registers are pushed starting with the highest encoding,
+  // which means that lowest encodings are closest to the stack pointer.
+  RegList regs = kSafepointSavedRegisters;
+  int index = 0;
+
+  DCHECK(reg_code >= 0 && reg_code < kNumRegisters);
+
+  for (int16_t i = 0; i < reg_code; i++) {
+    if ((regs & (1 << i)) != 0) {
+      index++;
+    }
+  }
+
+  return index;
+}
+
+
+MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) {
+  return MemOperand(sp, SafepointRegisterStackIndex(reg.code()) * kPointerSize);
+}
+
+
+MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) {
+  // General purpose registers are pushed last on the stack.
+  int doubles_size = DoubleRegister::NumAllocatableRegisters() * kDoubleSize;
+  int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize;
+  return MemOperand(sp, doubles_size + register_offset);
+}
+
+
+void MacroAssembler::CanonicalizeNaN(const DoubleRegister dst,
+                                     const DoubleRegister src) {
+  Label done;
+
+  // Test for NaN
+  fcmpu(src, src);
+
+  if (dst.is(src)) {
+    bordered(&done);
+  } else {
+    Label is_nan;
+    bunordered(&is_nan);
+    fmr(dst, src);
+    b(&done);
+    bind(&is_nan);
+  }
+
+  // Replace with canonical NaN.
+  double nan_value = FixedDoubleArray::canonical_not_the_hole_nan_as_double();
+  LoadDoubleLiteral(dst, nan_value, r0);
+
+  bind(&done);
+}
+
+
+void MacroAssembler::ConvertIntToDouble(Register src,
+                                        DoubleRegister double_dst) {
+  MovIntToDouble(double_dst, src, r0);
+  fcfid(double_dst, double_dst);
+}
+
+
+void MacroAssembler::ConvertUnsignedIntToDouble(Register src,
+                                                DoubleRegister double_dst) {
+  MovUnsignedIntToDouble(double_dst, src, r0);
+  fcfid(double_dst, double_dst);
+}
+
+
+void MacroAssembler::ConvertIntToFloat(const DoubleRegister dst,
+                                       const Register src,
+                                       const Register int_scratch) {
+  MovIntToDouble(dst, src, int_scratch);
+  fcfid(dst, dst);
+  frsp(dst, dst);
+}
+
+
+void MacroAssembler::ConvertDoubleToInt64(const DoubleRegister double_input,
+#if !V8_TARGET_ARCH_PPC64
+                                          const Register dst_hi,
+#endif
+                                          const Register dst,
+                                          const DoubleRegister double_dst,
+                                          FPRoundingMode rounding_mode) {
+  if (rounding_mode == kRoundToZero) {
+    fctidz(double_dst, double_input);
+  } else {
+    SetRoundingMode(rounding_mode);
+    fctid(double_dst, double_input);
+    ResetRoundingMode();
+  }
+
+  MovDoubleToInt64(
+#if !V8_TARGET_ARCH_PPC64
+      dst_hi,
+#endif
+      dst, double_dst);
+}
+
+
+#if V8_OOL_CONSTANT_POOL
+void MacroAssembler::LoadConstantPoolPointerRegister(
+    CodeObjectAccessMethod access_method, int ip_code_entry_delta) {
+  Register base;
+  int constant_pool_offset = Code::kConstantPoolOffset - Code::kHeaderSize;
+  if (access_method == CAN_USE_IP) {
+    base = ip;
+    constant_pool_offset += ip_code_entry_delta;
+  } else {
+    DCHECK(access_method == CONSTRUCT_INTERNAL_REFERENCE);
+    base = kConstantPoolRegister;
+    ConstantPoolUnavailableScope constant_pool_unavailable(this);
+
+    // CheckBuffer() is called too frequently. This will pre-grow
+    // the buffer if needed to avoid spliting the relocation and instructions
+    EnsureSpaceFor(kMovInstructionsNoConstantPool * kInstrSize);
+
+    uintptr_t code_start = reinterpret_cast<uintptr_t>(pc_) - pc_offset();
+    mov(base, Operand(code_start, RelocInfo::INTERNAL_REFERENCE));
+  }
+  LoadP(kConstantPoolRegister, MemOperand(base, constant_pool_offset));
+}
+#endif
+
+
+void MacroAssembler::StubPrologue(int prologue_offset) {
+  LoadSmiLiteral(r11, Smi::FromInt(StackFrame::STUB));
+  PushFixedFrame(r11);
+  // Adjust FP to point to saved FP.
+  addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
+#if V8_OOL_CONSTANT_POOL
+  // ip contains prologue address
+  LoadConstantPoolPointerRegister(CAN_USE_IP, -prologue_offset);
+  set_ool_constant_pool_available(true);
+#endif
+}
+
+
+void MacroAssembler::Prologue(bool code_pre_aging, int prologue_offset) {
+  {
+    PredictableCodeSizeScope predictible_code_size_scope(
+        this, kNoCodeAgeSequenceLength);
+    Assembler::BlockTrampolinePoolScope block_trampoline_pool(this);
+    // The following instructions must remain together and unmodified
+    // for code aging to work properly.
+    if (code_pre_aging) {
+      // Pre-age the code.
+      // This matches the code found in PatchPlatformCodeAge()
+      Code* stub = Code::GetPreAgedCodeAgeStub(isolate());
+      intptr_t target = reinterpret_cast<intptr_t>(stub->instruction_start());
+      // Don't use Call -- we need to preserve ip and lr
+      nop();  // marker to detect sequence (see IsOld)
+      mov(r3, Operand(target));
+      Jump(r3);
+      for (int i = 0; i < kCodeAgingSequenceNops; i++) {
+        nop();
+      }
+    } else {
+      // This matches the code found in GetNoCodeAgeSequence()
+      PushFixedFrame(r4);
+      // Adjust fp to point to saved fp.
+      addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
+      for (int i = 0; i < kNoCodeAgeSequenceNops; i++) {
+        nop();
+      }
+    }
+  }
+#if V8_OOL_CONSTANT_POOL
+  // ip contains prologue address
+  LoadConstantPoolPointerRegister(CAN_USE_IP, -prologue_offset);
+  set_ool_constant_pool_available(true);
+#endif
+}
+
+
+void MacroAssembler::EnterFrame(StackFrame::Type type,
+                                bool load_constant_pool_pointer_reg) {
+  if (FLAG_enable_ool_constant_pool && load_constant_pool_pointer_reg) {
+    PushFixedFrame();
+#if V8_OOL_CONSTANT_POOL
+    // This path should not rely on ip containing code entry.
+    LoadConstantPoolPointerRegister(CONSTRUCT_INTERNAL_REFERENCE);
+#endif
+    LoadSmiLiteral(ip, Smi::FromInt(type));
+    push(ip);
+  } else {
+    LoadSmiLiteral(ip, Smi::FromInt(type));
+    PushFixedFrame(ip);
+  }
+  // Adjust FP to point to saved FP.
+  addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
+
+  mov(r0, Operand(CodeObject()));
+  push(r0);
+}
+
+
+int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) {
+#if V8_OOL_CONSTANT_POOL
+  ConstantPoolUnavailableScope constant_pool_unavailable(this);
+#endif
+  // r3: preserved
+  // r4: preserved
+  // r5: preserved
+
+  // Drop the execution stack down to the frame pointer and restore
+  // the caller frame pointer, return address and constant pool pointer.
+  int frame_ends;
+  LoadP(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
+  LoadP(ip, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+#if V8_OOL_CONSTANT_POOL
+  const int exitOffset = ExitFrameConstants::kConstantPoolOffset;
+  const int standardOffset = StandardFrameConstants::kConstantPoolOffset;
+  const int offset = ((type == StackFrame::EXIT) ? exitOffset : standardOffset);
+  LoadP(kConstantPoolRegister, MemOperand(fp, offset));
+#endif
+  mtlr(r0);
+  frame_ends = pc_offset();
+  Add(sp, fp, StandardFrameConstants::kCallerSPOffset + stack_adjustment, r0);
+  mr(fp, ip);
+  return frame_ends;
+}
+
+
+// ExitFrame layout (probably wrongish.. needs updating)
+//
+//  SP -> previousSP
+//        LK reserved
+//        code
+//        sp_on_exit (for debug?)
+// oldSP->prev SP
+//        LK
+//        <parameters on stack>
+
+// Prior to calling EnterExitFrame, we've got a bunch of parameters
+// on the stack that we need to wrap a real frame around.. so first
+// we reserve a slot for LK and push the previous SP which is captured
+// in the fp register (r31)
+// Then - we buy a new frame
+
+void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
+  // Set up the frame structure on the stack.
+  DCHECK_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement);
+  DCHECK_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset);
+  DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset);
+  DCHECK(stack_space > 0);
+
+  // This is an opportunity to build a frame to wrap
+  // all of the pushes that have happened inside of V8
+  // since we were called from C code
+
+  // replicate ARM frame - TODO make this more closely follow PPC ABI
+  mflr(r0);
+  Push(r0, fp);
+  mr(fp, sp);
+  // Reserve room for saved entry sp and code object.
+  subi(sp, sp, Operand(ExitFrameConstants::kFrameSize));
+
+  if (emit_debug_code()) {
+    li(r8, Operand::Zero());
+    StoreP(r8, MemOperand(fp, ExitFrameConstants::kSPOffset));
+  }
+#if V8_OOL_CONSTANT_POOL
+  StoreP(kConstantPoolRegister,
+         MemOperand(fp, ExitFrameConstants::kConstantPoolOffset));
+#endif
+  mov(r8, Operand(CodeObject()));
+  StoreP(r8, MemOperand(fp, ExitFrameConstants::kCodeOffset));
+
+  // Save the frame pointer and the context in top.
+  mov(r8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
+  StoreP(fp, MemOperand(r8));
+  mov(r8, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
+  StoreP(cp, MemOperand(r8));
+
+  // Optionally save all volatile double registers.
+  if (save_doubles) {
+    SaveFPRegs(sp, 0, DoubleRegister::kNumVolatileRegisters);
+    // Note that d0 will be accessible at
+    //   fp - ExitFrameConstants::kFrameSize -
+    //   kNumVolatileRegisters * kDoubleSize,
+    // since the sp slot and code slot were pushed after the fp.
+  }
+
+  addi(sp, sp, Operand(-stack_space * kPointerSize));
+
+  // Allocate and align the frame preparing for calling the runtime
+  // function.
+  const int frame_alignment = ActivationFrameAlignment();
+  if (frame_alignment > kPointerSize) {
+    DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
+    ClearRightImm(sp, sp, Operand(WhichPowerOf2(frame_alignment)));
+  }
+  li(r0, Operand::Zero());
+  StorePU(r0, MemOperand(sp, -kNumRequiredStackFrameSlots * kPointerSize));
+
+  // Set the exit frame sp value to point just before the return address
+  // location.
+  addi(r8, sp, Operand((kStackFrameExtraParamSlot + 1) * kPointerSize));
+  StoreP(r8, MemOperand(fp, ExitFrameConstants::kSPOffset));
+}
+
+
+void MacroAssembler::InitializeNewString(Register string, Register length,
+                                         Heap::RootListIndex map_index,
+                                         Register scratch1, Register scratch2) {
+  SmiTag(scratch1, length);
+  LoadRoot(scratch2, map_index);
+  StoreP(scratch1, FieldMemOperand(string, String::kLengthOffset), r0);
+  li(scratch1, Operand(String::kEmptyHashField));
+  StoreP(scratch2, FieldMemOperand(string, HeapObject::kMapOffset), r0);
+  StoreP(scratch1, FieldMemOperand(string, String::kHashFieldSlot), r0);
+}
+
+
+int MacroAssembler::ActivationFrameAlignment() {
+#if !defined(USE_SIMULATOR)
+  // Running on the real platform. Use the alignment as mandated by the local
+  // environment.
+  // Note: This will break if we ever start generating snapshots on one PPC
+  // platform for another PPC platform with a different alignment.
+  return base::OS::ActivationFrameAlignment();
+#else  // Simulated
+  // If we are using the simulator then we should always align to the expected
+  // alignment. As the simulator is used to generate snapshots we do not know
+  // if the target platform will need alignment, so this is controlled from a
+  // flag.
+  return FLAG_sim_stack_alignment;
+#endif
+}
+
+
+void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
+                                    bool restore_context) {
+#if V8_OOL_CONSTANT_POOL
+  ConstantPoolUnavailableScope constant_pool_unavailable(this);
+#endif
+  // Optionally restore all double registers.
+  if (save_doubles) {
+    // Calculate the stack location of the saved doubles and restore them.
+    const int kNumRegs = DoubleRegister::kNumVolatileRegisters;
+    const int offset =
+        (ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize);
+    addi(r6, fp, Operand(-offset));
+    RestoreFPRegs(r6, 0, kNumRegs);
+  }
+
+  // Clear top frame.
+  li(r6, Operand::Zero());
+  mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
+  StoreP(r6, MemOperand(ip));
+
+  // Restore current context from top and clear it in debug mode.
+  if (restore_context) {
+    mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
+    LoadP(cp, MemOperand(ip));
+  }
+#ifdef DEBUG
+  mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
+  StoreP(r6, MemOperand(ip));
+#endif
+
+  // Tear down the exit frame, pop the arguments, and return.
+  LeaveFrame(StackFrame::EXIT);
+
+  if (argument_count.is_valid()) {
+    ShiftLeftImm(argument_count, argument_count, Operand(kPointerSizeLog2));
+    add(sp, sp, argument_count);
+  }
+}
+
+
+void MacroAssembler::MovFromFloatResult(const DoubleRegister dst) {
+  Move(dst, d1);
+}
+
+
+void MacroAssembler::MovFromFloatParameter(const DoubleRegister dst) {
+  Move(dst, d1);
+}
+
+
+void MacroAssembler::InvokePrologue(const ParameterCount& expected,
+                                    const ParameterCount& actual,
+                                    Handle<Code> code_constant,
+                                    Register code_reg, Label* done,
+                                    bool* definitely_mismatches,
+                                    InvokeFlag flag,
+                                    const CallWrapper& call_wrapper) {
+  bool definitely_matches = false;
+  *definitely_mismatches = false;
+  Label regular_invoke;
+
+  // Check whether the expected and actual arguments count match. If not,
+  // setup registers according to contract with ArgumentsAdaptorTrampoline:
+  //  r3: actual arguments count
+  //  r4: function (passed through to callee)
+  //  r5: expected arguments count
+
+  // The code below is made a lot easier because the calling code already sets
+  // up actual and expected registers according to the contract if values are
+  // passed in registers.
+
+  // ARM has some sanity checks as per below, considering add them for PPC
+  //  DCHECK(actual.is_immediate() || actual.reg().is(r3));
+  //  DCHECK(expected.is_immediate() || expected.reg().is(r5));
+  //  DCHECK((!code_constant.is_null() && code_reg.is(no_reg))
+  //          || code_reg.is(r6));
+
+  if (expected.is_immediate()) {
+    DCHECK(actual.is_immediate());
+    if (expected.immediate() == actual.immediate()) {
+      definitely_matches = true;
+    } else {
+      mov(r3, Operand(actual.immediate()));
+      const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
+      if (expected.immediate() == sentinel) {
+        // Don't worry about adapting arguments for builtins that
+        // don't want that done. Skip adaption code by making it look
+        // like we have a match between expected and actual number of
+        // arguments.
+        definitely_matches = true;
+      } else {
+        *definitely_mismatches = true;
+        mov(r5, Operand(expected.immediate()));
+      }
+    }
+  } else {
+    if (actual.is_immediate()) {
+      cmpi(expected.reg(), Operand(actual.immediate()));
+      beq(&regular_invoke);
+      mov(r3, Operand(actual.immediate()));
+    } else {
+      cmp(expected.reg(), actual.reg());
+      beq(&regular_invoke);
+    }
+  }
+
+  if (!definitely_matches) {
+    if (!code_constant.is_null()) {
+      mov(r6, Operand(code_constant));
+      addi(r6, r6, Operand(Code::kHeaderSize - kHeapObjectTag));
+    }
+
+    Handle<Code> adaptor = isolate()->builtins()->ArgumentsAdaptorTrampoline();
+    if (flag == CALL_FUNCTION) {
+      call_wrapper.BeforeCall(CallSize(adaptor));
+      Call(adaptor);
+      call_wrapper.AfterCall();
+      if (!*definitely_mismatches) {
+        b(done);
+      }
+    } else {
+      Jump(adaptor, RelocInfo::CODE_TARGET);
+    }
+    bind(&regular_invoke);
+  }
+}
+
+
+void MacroAssembler::InvokeCode(Register code, const ParameterCount& expected,
+                                const ParameterCount& actual, InvokeFlag flag,
+                                const CallWrapper& call_wrapper) {
+  // You can't call a function without a valid frame.
+  DCHECK(flag == JUMP_FUNCTION || has_frame());
+
+  Label done;
+  bool definitely_mismatches = false;
+  InvokePrologue(expected, actual, Handle<Code>::null(), code, &done,
+                 &definitely_mismatches, flag, call_wrapper);
+  if (!definitely_mismatches) {
+    if (flag == CALL_FUNCTION) {
+      call_wrapper.BeforeCall(CallSize(code));
+      CallJSEntry(code);
+      call_wrapper.AfterCall();
+    } else {
+      DCHECK(flag == JUMP_FUNCTION);
+      JumpToJSEntry(code);
+    }
+
+    // Continue here if InvokePrologue does handle the invocation due to
+    // mismatched parameter counts.
+    bind(&done);
+  }
+}
+
+
+void MacroAssembler::InvokeFunction(Register fun, const ParameterCount& actual,
+                                    InvokeFlag flag,
+                                    const CallWrapper& call_wrapper) {
+  // You can't call a function without a valid frame.
+  DCHECK(flag == JUMP_FUNCTION || has_frame());
+
+  // Contract with called JS functions requires that function is passed in r4.
+  DCHECK(fun.is(r4));
+
+  Register expected_reg = r5;
+  Register code_reg = ip;
+
+  LoadP(code_reg, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
+  LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
+  LoadWordArith(expected_reg,
+                FieldMemOperand(
+                    code_reg, SharedFunctionInfo::kFormalParameterCountOffset));
+#if !defined(V8_TARGET_ARCH_PPC64)
+  SmiUntag(expected_reg);
+#endif
+  LoadP(code_reg, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
+
+  ParameterCount expected(expected_reg);
+  InvokeCode(code_reg, expected, actual, flag, call_wrapper);
+}
+
+
+void MacroAssembler::InvokeFunction(Register function,
+                                    const ParameterCount& expected,
+                                    const ParameterCount& actual,
+                                    InvokeFlag flag,
+                                    const CallWrapper& call_wrapper) {
+  // You can't call a function without a valid frame.
+  DCHECK(flag == JUMP_FUNCTION || has_frame());
+
+  // Contract with called JS functions requires that function is passed in r4.
+  DCHECK(function.is(r4));
+
+  // Get the function and setup the context.
+  LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
+
+  // We call indirectly through the code field in the function to
+  // allow recompilation to take effect without changing any of the
+  // call sites.
+  LoadP(ip, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
+  InvokeCode(ip, expected, actual, flag, call_wrapper);
+}
+
+
+void MacroAssembler::InvokeFunction(Handle<JSFunction> function,
+                                    const ParameterCount& expected,
+                                    const ParameterCount& actual,
+                                    InvokeFlag flag,
+                                    const CallWrapper& call_wrapper) {
+  Move(r4, function);
+  InvokeFunction(r4, expected, actual, flag, call_wrapper);
+}
+
+
+void MacroAssembler::IsObjectJSObjectType(Register heap_object, Register map,
+                                          Register scratch, Label* fail) {
+  LoadP(map, FieldMemOperand(heap_object, HeapObject::kMapOffset));
+  IsInstanceJSObjectType(map, scratch, fail);
+}
+
+
+void MacroAssembler::IsInstanceJSObjectType(Register map, Register scratch,
+                                            Label* fail) {
+  lbz(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  cmpi(scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
+  blt(fail);
+  cmpi(scratch, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
+  bgt(fail);
+}
+
+
+void MacroAssembler::IsObjectJSStringType(Register object, Register scratch,
+                                          Label* fail) {
+  DCHECK(kNotStringTag != 0);
+
+  LoadP(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
+  lbz(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
+  andi(r0, scratch, Operand(kIsNotStringMask));
+  bne(fail, cr0);
+}
+
+
+void MacroAssembler::IsObjectNameType(Register object, Register scratch,
+                                      Label* fail) {
+  LoadP(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
+  lbz(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
+  cmpi(scratch, Operand(LAST_NAME_TYPE));
+  bgt(fail);
+}
+
+
+void MacroAssembler::DebugBreak() {
+  li(r3, Operand::Zero());
+  mov(r4, Operand(ExternalReference(Runtime::kDebugBreak, isolate())));
+  CEntryStub ces(isolate(), 1);
+  DCHECK(AllowThisStubCall(&ces));
+  Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
+}
+
+
+void MacroAssembler::PushTryHandler(StackHandler::Kind kind,
+                                    int handler_index) {
+  // Adjust this code if not the case.
+  STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize);
+
+  // For the JSEntry handler, we must preserve r1-r7, r0,r8-r15 are available.
+  // We want the stack to look like
+  // sp -> NextOffset
+  //       CodeObject
+  //       state
+  //       context
+  //       frame pointer
+
+  // Link the current handler as the next handler.
+  mov(r8, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
+  LoadP(r0, MemOperand(r8));
+  StorePU(r0, MemOperand(sp, -StackHandlerConstants::kSize));
+  // Set this new handler as the current one.
+  StoreP(sp, MemOperand(r8));
+
+  if (kind == StackHandler::JS_ENTRY) {
+    li(r8, Operand::Zero());  // NULL frame pointer.
+    StoreP(r8, MemOperand(sp, StackHandlerConstants::kFPOffset));
+    LoadSmiLiteral(r8, Smi::FromInt(0));  // Indicates no context.
+    StoreP(r8, MemOperand(sp, StackHandlerConstants::kContextOffset));
+  } else {
+    // still not sure if fp is right
+    StoreP(fp, MemOperand(sp, StackHandlerConstants::kFPOffset));
+    StoreP(cp, MemOperand(sp, StackHandlerConstants::kContextOffset));
+  }
+  unsigned state = StackHandler::IndexField::encode(handler_index) |
+                   StackHandler::KindField::encode(kind);
+  LoadIntLiteral(r8, state);
+  StoreP(r8, MemOperand(sp, StackHandlerConstants::kStateOffset));
+  mov(r8, Operand(CodeObject()));
+  StoreP(r8, MemOperand(sp, StackHandlerConstants::kCodeOffset));
+}
+
+
+void MacroAssembler::PopTryHandler() {
+  STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
+  pop(r4);
+  mov(ip, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
+  addi(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize));
+  StoreP(r4, MemOperand(ip));
+}
+
+
+// PPC - make use of ip as a temporary register
+void MacroAssembler::JumpToHandlerEntry() {
+// Compute the handler entry address and jump to it.  The handler table is
+// a fixed array of (smi-tagged) code offsets.
+// r3 = exception, r4 = code object, r5 = state.
+#if V8_OOL_CONSTANT_POOL
+  ConstantPoolUnavailableScope constant_pool_unavailable(this);
+  LoadP(kConstantPoolRegister, FieldMemOperand(r4, Code::kConstantPoolOffset));
+#endif
+  LoadP(r6, FieldMemOperand(r4, Code::kHandlerTableOffset));  // Handler table.
+  addi(r6, r6, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+  srwi(r5, r5, Operand(StackHandler::kKindWidth));  // Handler index.
+  slwi(ip, r5, Operand(kPointerSizeLog2));
+  add(ip, r6, ip);
+  LoadP(r5, MemOperand(ip));  // Smi-tagged offset.
+  addi(r4, r4, Operand(Code::kHeaderSize - kHeapObjectTag));  // Code start.
+  SmiUntag(ip, r5);
+  add(r0, r4, ip);
+  mtctr(r0);
+  bctr();
+}
+
+
+void MacroAssembler::Throw(Register value) {
+  // Adjust this code if not the case.
+  STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
+  STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize);
+  Label skip;
+
+  // The exception is expected in r3.
+  if (!value.is(r3)) {
+    mr(r3, value);
+  }
+  // Drop the stack pointer to the top of the top handler.
+  mov(r6, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
+  LoadP(sp, MemOperand(r6));
+  // Restore the next handler.
+  pop(r5);
+  StoreP(r5, MemOperand(r6));
+
+  // Get the code object (r4) and state (r5).  Restore the context and frame
+  // pointer.
+  pop(r4);
+  pop(r5);
+  pop(cp);
+  pop(fp);
+
+  // If the handler is a JS frame, restore the context to the frame.
+  // (kind == ENTRY) == (fp == 0) == (cp == 0), so we could test either fp
+  // or cp.
+  cmpi(cp, Operand::Zero());
+  beq(&skip);
+  StoreP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  bind(&skip);
+
+  JumpToHandlerEntry();
+}
+
+
+void MacroAssembler::ThrowUncatchable(Register value) {
+  // Adjust this code if not the case.
+  STATIC_ASSERT(StackHandlerConstants::kSize == 5 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kCodeOffset == 1 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kStateOffset == 2 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kContextOffset == 3 * kPointerSize);
+  STATIC_ASSERT(StackHandlerConstants::kFPOffset == 4 * kPointerSize);
+
+  // The exception is expected in r3.
+  if (!value.is(r3)) {
+    mr(r3, value);
+  }
+  // Drop the stack pointer to the top of the top stack handler.
+  mov(r6, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
+  LoadP(sp, MemOperand(r6));
+
+  // Unwind the handlers until the ENTRY handler is found.
+  Label fetch_next, check_kind;
+  b(&check_kind);
+  bind(&fetch_next);
+  LoadP(sp, MemOperand(sp, StackHandlerConstants::kNextOffset));
+
+  bind(&check_kind);
+  STATIC_ASSERT(StackHandler::JS_ENTRY == 0);
+  LoadP(r5, MemOperand(sp, StackHandlerConstants::kStateOffset));
+  andi(r0, r5, Operand(StackHandler::KindField::kMask));
+  bne(&fetch_next, cr0);
+
+  // Set the top handler address to next handler past the top ENTRY handler.
+  pop(r5);
+  StoreP(r5, MemOperand(r6));
+  // Get the code object (r4) and state (r5).  Clear the context and frame
+  // pointer (0 was saved in the handler).
+  pop(r4);
+  pop(r5);
+  pop(cp);
+  pop(fp);
+
+  JumpToHandlerEntry();
+}
+
+
+void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg,
+                                            Register scratch, Label* miss) {
+  Label same_contexts;
+
+  DCHECK(!holder_reg.is(scratch));
+  DCHECK(!holder_reg.is(ip));
+  DCHECK(!scratch.is(ip));
+
+  // Load current lexical context from the stack frame.
+  LoadP(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset));
+// In debug mode, make sure the lexical context is set.
+#ifdef DEBUG
+  cmpi(scratch, Operand::Zero());
+  Check(ne, kWeShouldNotHaveAnEmptyLexicalContext);
+#endif
+
+  // Load the native context of the current context.
+  int offset =
+      Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
+  LoadP(scratch, FieldMemOperand(scratch, offset));
+  LoadP(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
+
+  // Check the context is a native context.
+  if (emit_debug_code()) {
+    // Cannot use ip as a temporary in this verification code. Due to the fact
+    // that ip is clobbered as part of cmp with an object Operand.
+    push(holder_reg);  // Temporarily save holder on the stack.
+    // Read the first word and compare to the native_context_map.
+    LoadP(holder_reg, FieldMemOperand(scratch, HeapObject::kMapOffset));
+    LoadRoot(ip, Heap::kNativeContextMapRootIndex);
+    cmp(holder_reg, ip);
+    Check(eq, kJSGlobalObjectNativeContextShouldBeANativeContext);
+    pop(holder_reg);  // Restore holder.
+  }
+
+  // Check if both contexts are the same.
+  LoadP(ip, FieldMemOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
+  cmp(scratch, ip);
+  beq(&same_contexts);
+
+  // Check the context is a native context.
+  if (emit_debug_code()) {
+    // Cannot use ip as a temporary in this verification code. Due to the fact
+    // that ip is clobbered as part of cmp with an object Operand.
+    push(holder_reg);    // Temporarily save holder on the stack.
+    mr(holder_reg, ip);  // Move ip to its holding place.
+    LoadRoot(ip, Heap::kNullValueRootIndex);
+    cmp(holder_reg, ip);
+    Check(ne, kJSGlobalProxyContextShouldNotBeNull);
+
+    LoadP(holder_reg, FieldMemOperand(holder_reg, HeapObject::kMapOffset));
+    LoadRoot(ip, Heap::kNativeContextMapRootIndex);
+    cmp(holder_reg, ip);
+    Check(eq, kJSGlobalObjectNativeContextShouldBeANativeContext);
+    // Restore ip is not needed. ip is reloaded below.
+    pop(holder_reg);  // Restore holder.
+    // Restore ip to holder's context.
+    LoadP(ip, FieldMemOperand(holder_reg, JSGlobalProxy::kNativeContextOffset));
+  }
+
+  // Check that the security token in the calling global object is
+  // compatible with the security token in the receiving global
+  // object.
+  int token_offset =
+      Context::kHeaderSize + Context::SECURITY_TOKEN_INDEX * kPointerSize;
+
+  LoadP(scratch, FieldMemOperand(scratch, token_offset));
+  LoadP(ip, FieldMemOperand(ip, token_offset));
+  cmp(scratch, ip);
+  bne(miss);
+
+  bind(&same_contexts);
+}
+
+
+// Compute the hash code from the untagged key.  This must be kept in sync with
+// ComputeIntegerHash in utils.h and KeyedLoadGenericStub in
+// code-stub-hydrogen.cc
+void MacroAssembler::GetNumberHash(Register t0, Register scratch) {
+  // First of all we assign the hash seed to scratch.
+  LoadRoot(scratch, Heap::kHashSeedRootIndex);
+  SmiUntag(scratch);
+
+  // Xor original key with a seed.
+  xor_(t0, t0, scratch);
+
+  // Compute the hash code from the untagged key.  This must be kept in sync
+  // with ComputeIntegerHash in utils.h.
+  //
+  // hash = ~hash + (hash << 15);
+  notx(scratch, t0);
+  slwi(t0, t0, Operand(15));
+  add(t0, scratch, t0);
+  // hash = hash ^ (hash >> 12);
+  srwi(scratch, t0, Operand(12));
+  xor_(t0, t0, scratch);
+  // hash = hash + (hash << 2);
+  slwi(scratch, t0, Operand(2));
+  add(t0, t0, scratch);
+  // hash = hash ^ (hash >> 4);
+  srwi(scratch, t0, Operand(4));
+  xor_(t0, t0, scratch);
+  // hash = hash * 2057;
+  mr(r0, t0);
+  slwi(scratch, t0, Operand(3));
+  add(t0, t0, scratch);
+  slwi(scratch, r0, Operand(11));
+  add(t0, t0, scratch);
+  // hash = hash ^ (hash >> 16);
+  srwi(scratch, t0, Operand(16));
+  xor_(t0, t0, scratch);
+}
+
+
+void MacroAssembler::LoadFromNumberDictionary(Label* miss, Register elements,
+                                              Register key, Register result,
+                                              Register t0, Register t1,
+                                              Register t2) {
+  // Register use:
+  //
+  // elements - holds the slow-case elements of the receiver on entry.
+  //            Unchanged unless 'result' is the same register.
+  //
+  // key      - holds the smi key on entry.
+  //            Unchanged unless 'result' is the same register.
+  //
+  // result   - holds the result on exit if the load succeeded.
+  //            Allowed to be the same as 'key' or 'result'.
+  //            Unchanged on bailout so 'key' or 'result' can be used
+  //            in further computation.
+  //
+  // Scratch registers:
+  //
+  // t0 - holds the untagged key on entry and holds the hash once computed.
+  //
+  // t1 - used to hold the capacity mask of the dictionary
+  //
+  // t2 - used for the index into the dictionary.
+  Label done;
+
+  GetNumberHash(t0, t1);
+
+  // Compute the capacity mask.
+  LoadP(t1, FieldMemOperand(elements, SeededNumberDictionary::kCapacityOffset));
+  SmiUntag(t1);
+  subi(t1, t1, Operand(1));
+
+  // Generate an unrolled loop that performs a few probes before giving up.
+  for (int i = 0; i < kNumberDictionaryProbes; i++) {
+    // Use t2 for index calculations and keep the hash intact in t0.
+    mr(t2, t0);
+    // Compute the masked index: (hash + i + i * i) & mask.
+    if (i > 0) {
+      addi(t2, t2, Operand(SeededNumberDictionary::GetProbeOffset(i)));
+    }
+    and_(t2, t2, t1);
+
+    // Scale the index by multiplying by the element size.
+    DCHECK(SeededNumberDictionary::kEntrySize == 3);
+    slwi(ip, t2, Operand(1));
+    add(t2, t2, ip);  // t2 = t2 * 3
+
+    // Check if the key is identical to the name.
+    slwi(t2, t2, Operand(kPointerSizeLog2));
+    add(t2, elements, t2);
+    LoadP(ip,
+          FieldMemOperand(t2, SeededNumberDictionary::kElementsStartOffset));
+    cmp(key, ip);
+    if (i != kNumberDictionaryProbes - 1) {
+      beq(&done);
+    } else {
+      bne(miss);
+    }
+  }
+
+  bind(&done);
+  // Check that the value is a field property.
+  // t2: elements + (index * kPointerSize)
+  const int kDetailsOffset =
+      SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
+  LoadP(t1, FieldMemOperand(t2, kDetailsOffset));
+  LoadSmiLiteral(ip, Smi::FromInt(PropertyDetails::TypeField::kMask));
+  DCHECK_EQ(FIELD, 0);
+  and_(r0, t1, ip, SetRC);
+  bne(miss, cr0);
+
+  // Get the value at the masked, scaled index and return.
+  const int kValueOffset =
+      SeededNumberDictionary::kElementsStartOffset + kPointerSize;
+  LoadP(result, FieldMemOperand(t2, kValueOffset));
+}
+
+
+void MacroAssembler::Allocate(int object_size, Register result,
+                              Register scratch1, Register scratch2,
+                              Label* gc_required, AllocationFlags flags) {
+  DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
+  if (!FLAG_inline_new) {
+    if (emit_debug_code()) {
+      // Trash the registers to simulate an allocation failure.
+      li(result, Operand(0x7091));
+      li(scratch1, Operand(0x7191));
+      li(scratch2, Operand(0x7291));
+    }
+    b(gc_required);
+    return;
+  }
+
+  DCHECK(!result.is(scratch1));
+  DCHECK(!result.is(scratch2));
+  DCHECK(!scratch1.is(scratch2));
+  DCHECK(!scratch1.is(ip));
+  DCHECK(!scratch2.is(ip));
+
+  // Make object size into bytes.
+  if ((flags & SIZE_IN_WORDS) != 0) {
+    object_size *= kPointerSize;
+  }
+  DCHECK_EQ(0, static_cast<int>(object_size & kObjectAlignmentMask));
+
+  // Check relative positions of allocation top and limit addresses.
+  ExternalReference allocation_top =
+      AllocationUtils::GetAllocationTopReference(isolate(), flags);
+  ExternalReference allocation_limit =
+      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
+
+  intptr_t top = reinterpret_cast<intptr_t>(allocation_top.address());
+  intptr_t limit = reinterpret_cast<intptr_t>(allocation_limit.address());
+  DCHECK((limit - top) == kPointerSize);
+
+  // Set up allocation top address register.
+  Register topaddr = scratch1;
+  mov(topaddr, Operand(allocation_top));
+
+  // This code stores a temporary value in ip. This is OK, as the code below
+  // does not need ip for implicit literal generation.
+  if ((flags & RESULT_CONTAINS_TOP) == 0) {
+    // Load allocation top into result and allocation limit into ip.
+    LoadP(result, MemOperand(topaddr));
+    LoadP(ip, MemOperand(topaddr, kPointerSize));
+  } else {
+    if (emit_debug_code()) {
+      // Assert that result actually contains top on entry. ip is used
+      // immediately below so this use of ip does not cause difference with
+      // respect to register content between debug and release mode.
+      LoadP(ip, MemOperand(topaddr));
+      cmp(result, ip);
+      Check(eq, kUnexpectedAllocationTop);
+    }
+    // Load allocation limit into ip. Result already contains allocation top.
+    LoadP(ip, MemOperand(topaddr, limit - top), r0);
+  }
+
+  if ((flags & DOUBLE_ALIGNMENT) != 0) {
+    // Align the next allocation. Storing the filler map without checking top is
+    // safe in new-space because the limit of the heap is aligned there.
+    DCHECK((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
+#if V8_TARGET_ARCH_PPC64
+    STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
+#else
+    STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
+    andi(scratch2, result, Operand(kDoubleAlignmentMask));
+    Label aligned;
+    beq(&aligned, cr0);
+    if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) {
+      cmpl(result, ip);
+      bge(gc_required);
+    }
+    mov(scratch2, Operand(isolate()->factory()->one_pointer_filler_map()));
+    stw(scratch2, MemOperand(result));
+    addi(result, result, Operand(kDoubleSize / 2));
+    bind(&aligned);
+#endif
+  }
+
+  // Calculate new top and bail out if new space is exhausted. Use result
+  // to calculate the new top.
+  sub(r0, ip, result);
+  if (is_int16(object_size)) {
+    cmpi(r0, Operand(object_size));
+    blt(gc_required);
+    addi(scratch2, result, Operand(object_size));
+  } else {
+    Cmpi(r0, Operand(object_size), scratch2);
+    blt(gc_required);
+    add(scratch2, result, scratch2);
+  }
+  StoreP(scratch2, MemOperand(topaddr));
+
+  // Tag object if requested.
+  if ((flags & TAG_OBJECT) != 0) {
+    addi(result, result, Operand(kHeapObjectTag));
+  }
+}
+
+
+void MacroAssembler::Allocate(Register object_size, Register result,
+                              Register scratch1, Register scratch2,
+                              Label* gc_required, AllocationFlags flags) {
+  if (!FLAG_inline_new) {
+    if (emit_debug_code()) {
+      // Trash the registers to simulate an allocation failure.
+      li(result, Operand(0x7091));
+      li(scratch1, Operand(0x7191));
+      li(scratch2, Operand(0x7291));
+    }
+    b(gc_required);
+    return;
+  }
+
+  // Assert that the register arguments are different and that none of
+  // them are ip. ip is used explicitly in the code generated below.
+  DCHECK(!result.is(scratch1));
+  DCHECK(!result.is(scratch2));
+  DCHECK(!scratch1.is(scratch2));
+  DCHECK(!object_size.is(ip));
+  DCHECK(!result.is(ip));
+  DCHECK(!scratch1.is(ip));
+  DCHECK(!scratch2.is(ip));
+
+  // Check relative positions of allocation top and limit addresses.
+  ExternalReference allocation_top =
+      AllocationUtils::GetAllocationTopReference(isolate(), flags);
+  ExternalReference allocation_limit =
+      AllocationUtils::GetAllocationLimitReference(isolate(), flags);
+  intptr_t top = reinterpret_cast<intptr_t>(allocation_top.address());
+  intptr_t limit = reinterpret_cast<intptr_t>(allocation_limit.address());
+  DCHECK((limit - top) == kPointerSize);
+
+  // Set up allocation top address.
+  Register topaddr = scratch1;
+  mov(topaddr, Operand(allocation_top));
+
+  // This code stores a temporary value in ip. This is OK, as the code below
+  // does not need ip for implicit literal generation.
+  if ((flags & RESULT_CONTAINS_TOP) == 0) {
+    // Load allocation top into result and allocation limit into ip.
+    LoadP(result, MemOperand(topaddr));
+    LoadP(ip, MemOperand(topaddr, kPointerSize));
+  } else {
+    if (emit_debug_code()) {
+      // Assert that result actually contains top on entry. ip is used
+      // immediately below so this use of ip does not cause difference with
+      // respect to register content between debug and release mode.
+      LoadP(ip, MemOperand(topaddr));
+      cmp(result, ip);
+      Check(eq, kUnexpectedAllocationTop);
+    }
+    // Load allocation limit into ip. Result already contains allocation top.
+    LoadP(ip, MemOperand(topaddr, limit - top));
+  }
+
+  if ((flags & DOUBLE_ALIGNMENT) != 0) {
+    // Align the next allocation. Storing the filler map without checking top is
+    // safe in new-space because the limit of the heap is aligned there.
+    DCHECK((flags & PRETENURE_OLD_POINTER_SPACE) == 0);
+#if V8_TARGET_ARCH_PPC64
+    STATIC_ASSERT(kPointerAlignment == kDoubleAlignment);
+#else
+    STATIC_ASSERT(kPointerAlignment * 2 == kDoubleAlignment);
+    andi(scratch2, result, Operand(kDoubleAlignmentMask));
+    Label aligned;
+    beq(&aligned, cr0);
+    if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) {
+      cmpl(result, ip);
+      bge(gc_required);
+    }
+    mov(scratch2, Operand(isolate()->factory()->one_pointer_filler_map()));
+    stw(scratch2, MemOperand(result));
+    addi(result, result, Operand(kDoubleSize / 2));
+    bind(&aligned);
+#endif
+  }
+
+  // Calculate new top and bail out if new space is exhausted. Use result
+  // to calculate the new top. Object size may be in words so a shift is
+  // required to get the number of bytes.
+  sub(r0, ip, result);
+  if ((flags & SIZE_IN_WORDS) != 0) {
+    ShiftLeftImm(scratch2, object_size, Operand(kPointerSizeLog2));
+    cmp(r0, scratch2);
+    blt(gc_required);
+    add(scratch2, result, scratch2);
+  } else {
+    cmp(r0, object_size);
+    blt(gc_required);
+    add(scratch2, result, object_size);
+  }
+
+  // Update allocation top. result temporarily holds the new top.
+  if (emit_debug_code()) {
+    andi(r0, scratch2, Operand(kObjectAlignmentMask));
+    Check(eq, kUnalignedAllocationInNewSpace, cr0);
+  }
+  StoreP(scratch2, MemOperand(topaddr));
+
+  // Tag object if requested.
+  if ((flags & TAG_OBJECT) != 0) {
+    addi(result, result, Operand(kHeapObjectTag));
+  }
+}
+
+
+void MacroAssembler::UndoAllocationInNewSpace(Register object,
+                                              Register scratch) {
+  ExternalReference new_space_allocation_top =
+      ExternalReference::new_space_allocation_top_address(isolate());
+
+  // Make sure the object has no tag before resetting top.
+  mov(r0, Operand(~kHeapObjectTagMask));
+  and_(object, object, r0);
+// was.. and_(object, object, Operand(~kHeapObjectTagMask));
+#ifdef DEBUG
+  // Check that the object un-allocated is below the current top.
+  mov(scratch, Operand(new_space_allocation_top));
+  LoadP(scratch, MemOperand(scratch));
+  cmp(object, scratch);
+  Check(lt, kUndoAllocationOfNonAllocatedMemory);
+#endif
+  // Write the address of the object to un-allocate as the current top.
+  mov(scratch, Operand(new_space_allocation_top));
+  StoreP(object, MemOperand(scratch));
+}
+
+
+void MacroAssembler::AllocateTwoByteString(Register result, Register length,
+                                           Register scratch1, Register scratch2,
+                                           Register scratch3,
+                                           Label* gc_required) {
+  // Calculate the number of bytes needed for the characters in the string while
+  // observing object alignment.
+  DCHECK((SeqTwoByteString::kHeaderSize & kObjectAlignmentMask) == 0);
+  slwi(scratch1, length, Operand(1));  // Length in bytes, not chars.
+  addi(scratch1, scratch1,
+       Operand(kObjectAlignmentMask + SeqTwoByteString::kHeaderSize));
+  mov(r0, Operand(~kObjectAlignmentMask));
+  and_(scratch1, scratch1, r0);
+
+  // Allocate two-byte string in new space.
+  Allocate(scratch1, result, scratch2, scratch3, gc_required, TAG_OBJECT);
+
+  // Set the map, length and hash field.
+  InitializeNewString(result, length, Heap::kStringMapRootIndex, scratch1,
+                      scratch2);
+}
+
+
+void MacroAssembler::AllocateOneByteString(Register result, Register length,
+                                           Register scratch1, Register scratch2,
+                                           Register scratch3,
+                                           Label* gc_required) {
+  // Calculate the number of bytes needed for the characters in the string while
+  // observing object alignment.
+  DCHECK((SeqOneByteString::kHeaderSize & kObjectAlignmentMask) == 0);
+  DCHECK(kCharSize == 1);
+  addi(scratch1, length,
+       Operand(kObjectAlignmentMask + SeqOneByteString::kHeaderSize));
+  li(r0, Operand(~kObjectAlignmentMask));
+  and_(scratch1, scratch1, r0);
+
+  // Allocate one-byte string in new space.
+  Allocate(scratch1, result, scratch2, scratch3, gc_required, TAG_OBJECT);
+
+  // Set the map, length and hash field.
+  InitializeNewString(result, length, Heap::kOneByteStringMapRootIndex,
+                      scratch1, scratch2);
+}
+
+
+void MacroAssembler::AllocateTwoByteConsString(Register result, Register length,
+                                               Register scratch1,
+                                               Register scratch2,
+                                               Label* gc_required) {
+  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
+
+  InitializeNewString(result, length, Heap::kConsStringMapRootIndex, scratch1,
+                      scratch2);
+}
+
+
+void MacroAssembler::AllocateOneByteConsString(Register result, Register length,
+                                               Register scratch1,
+                                               Register scratch2,
+                                               Label* gc_required) {
+  Allocate(ConsString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
+
+  InitializeNewString(result, length, Heap::kConsOneByteStringMapRootIndex,
+                      scratch1, scratch2);
+}
+
+
+void MacroAssembler::AllocateTwoByteSlicedString(Register result,
+                                                 Register length,
+                                                 Register scratch1,
+                                                 Register scratch2,
+                                                 Label* gc_required) {
+  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
+
+  InitializeNewString(result, length, Heap::kSlicedStringMapRootIndex, scratch1,
+                      scratch2);
+}
+
+
+void MacroAssembler::AllocateOneByteSlicedString(Register result,
+                                                 Register length,
+                                                 Register scratch1,
+                                                 Register scratch2,
+                                                 Label* gc_required) {
+  Allocate(SlicedString::kSize, result, scratch1, scratch2, gc_required,
+           TAG_OBJECT);
+
+  InitializeNewString(result, length, Heap::kSlicedOneByteStringMapRootIndex,
+                      scratch1, scratch2);
+}
+
+
+void MacroAssembler::CompareObjectType(Register object, Register map,
+                                       Register type_reg, InstanceType type) {
+  const Register temp = type_reg.is(no_reg) ? r0 : type_reg;
+
+  LoadP(map, FieldMemOperand(object, HeapObject::kMapOffset));
+  CompareInstanceType(map, temp, type);
+}
+
+
+void MacroAssembler::CheckObjectTypeRange(Register object, Register map,
+                                          InstanceType min_type,
+                                          InstanceType max_type,
+                                          Label* false_label) {
+  STATIC_ASSERT(Map::kInstanceTypeOffset < 4096);
+  STATIC_ASSERT(LAST_TYPE < 256);
+  LoadP(map, FieldMemOperand(object, HeapObject::kMapOffset));
+  lbz(ip, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  subi(ip, ip, Operand(min_type));
+  cmpli(ip, Operand(max_type - min_type));
+  bgt(false_label);
+}
+
+
+void MacroAssembler::CompareInstanceType(Register map, Register type_reg,
+                                         InstanceType type) {
+  STATIC_ASSERT(Map::kInstanceTypeOffset < 4096);
+  STATIC_ASSERT(LAST_TYPE < 256);
+  lbz(type_reg, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  cmpi(type_reg, Operand(type));
+}
+
+
+void MacroAssembler::CompareRoot(Register obj, Heap::RootListIndex index) {
+  DCHECK(!obj.is(r0));
+  LoadRoot(r0, index);
+  cmp(obj, r0);
+}
+
+
+void MacroAssembler::CheckFastElements(Register map, Register scratch,
+                                       Label* fail) {
+  STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
+  STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
+  STATIC_ASSERT(FAST_ELEMENTS == 2);
+  STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
+  lbz(scratch, FieldMemOperand(map, Map::kBitField2Offset));
+  STATIC_ASSERT(Map::kMaximumBitField2FastHoleyElementValue < 0x8000);
+  cmpli(scratch, Operand(Map::kMaximumBitField2FastHoleyElementValue));
+  bgt(fail);
+}
+
+
+void MacroAssembler::CheckFastObjectElements(Register map, Register scratch,
+                                             Label* fail) {
+  STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
+  STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
+  STATIC_ASSERT(FAST_ELEMENTS == 2);
+  STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
+  lbz(scratch, FieldMemOperand(map, Map::kBitField2Offset));
+  cmpli(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue));
+  ble(fail);
+  cmpli(scratch, Operand(Map::kMaximumBitField2FastHoleyElementValue));
+  bgt(fail);
+}
+
+
+void MacroAssembler::CheckFastSmiElements(Register map, Register scratch,
+                                          Label* fail) {
+  STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
+  STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
+  lbz(scratch, FieldMemOperand(map, Map::kBitField2Offset));
+  cmpli(scratch, Operand(Map::kMaximumBitField2FastHoleySmiElementValue));
+  bgt(fail);
+}
+
+
+void MacroAssembler::StoreNumberToDoubleElements(
+    Register value_reg, Register key_reg, Register elements_reg,
+    Register scratch1, DoubleRegister double_scratch, Label* fail,
+    int elements_offset) {
+  Label smi_value, store;
+
+  // Handle smi values specially.
+  JumpIfSmi(value_reg, &smi_value);
+
+  // Ensure that the object is a heap number
+  CheckMap(value_reg, scratch1, isolate()->factory()->heap_number_map(), fail,
+           DONT_DO_SMI_CHECK);
+
+  lfd(double_scratch, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
+  // Force a canonical NaN.
+  CanonicalizeNaN(double_scratch);
+  b(&store);
+
+  bind(&smi_value);
+  SmiToDouble(double_scratch, value_reg);
+
+  bind(&store);
+  SmiToDoubleArrayOffset(scratch1, key_reg);
+  add(scratch1, elements_reg, scratch1);
+  stfd(double_scratch, FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize -
+                                                     elements_offset));
+}
+
+
+void MacroAssembler::AddAndCheckForOverflow(Register dst, Register left,
+                                            Register right,
+                                            Register overflow_dst,
+                                            Register scratch) {
+  DCHECK(!dst.is(overflow_dst));
+  DCHECK(!dst.is(scratch));
+  DCHECK(!overflow_dst.is(scratch));
+  DCHECK(!overflow_dst.is(left));
+  DCHECK(!overflow_dst.is(right));
+
+  // C = A+B; C overflows if A/B have same sign and C has diff sign than A
+  if (dst.is(left)) {
+    mr(scratch, left);            // Preserve left.
+    add(dst, left, right);        // Left is overwritten.
+    xor_(scratch, dst, scratch);  // Original left.
+    xor_(overflow_dst, dst, right);
+  } else if (dst.is(right)) {
+    mr(scratch, right);           // Preserve right.
+    add(dst, left, right);        // Right is overwritten.
+    xor_(scratch, dst, scratch);  // Original right.
+    xor_(overflow_dst, dst, left);
+  } else {
+    add(dst, left, right);
+    xor_(overflow_dst, dst, left);
+    xor_(scratch, dst, right);
+  }
+  and_(overflow_dst, scratch, overflow_dst, SetRC);
+}
+
+
+void MacroAssembler::AddAndCheckForOverflow(Register dst, Register left,
+                                            intptr_t right,
+                                            Register overflow_dst,
+                                            Register scratch) {
+  Register original_left = left;
+  DCHECK(!dst.is(overflow_dst));
+  DCHECK(!dst.is(scratch));
+  DCHECK(!overflow_dst.is(scratch));
+  DCHECK(!overflow_dst.is(left));
+
+  // C = A+B; C overflows if A/B have same sign and C has diff sign than A
+  if (dst.is(left)) {
+    // Preserve left.
+    original_left = overflow_dst;
+    mr(original_left, left);
+  }
+  Add(dst, left, right, scratch);
+  xor_(overflow_dst, dst, original_left);
+  if (right >= 0) {
+    and_(overflow_dst, overflow_dst, dst, SetRC);
+  } else {
+    andc(overflow_dst, overflow_dst, dst, SetRC);
+  }
+}
+
+
+void MacroAssembler::SubAndCheckForOverflow(Register dst, Register left,
+                                            Register right,
+                                            Register overflow_dst,
+                                            Register scratch) {
+  DCHECK(!dst.is(overflow_dst));
+  DCHECK(!dst.is(scratch));
+  DCHECK(!overflow_dst.is(scratch));
+  DCHECK(!overflow_dst.is(left));
+  DCHECK(!overflow_dst.is(right));
+
+  // C = A-B; C overflows if A/B have diff signs and C has diff sign than A
+  if (dst.is(left)) {
+    mr(scratch, left);      // Preserve left.
+    sub(dst, left, right);  // Left is overwritten.
+    xor_(overflow_dst, dst, scratch);
+    xor_(scratch, scratch, right);
+    and_(overflow_dst, overflow_dst, scratch, SetRC);
+  } else if (dst.is(right)) {
+    mr(scratch, right);     // Preserve right.
+    sub(dst, left, right);  // Right is overwritten.
+    xor_(overflow_dst, dst, left);
+    xor_(scratch, left, scratch);
+    and_(overflow_dst, overflow_dst, scratch, SetRC);
+  } else {
+    sub(dst, left, right);
+    xor_(overflow_dst, dst, left);
+    xor_(scratch, left, right);
+    and_(overflow_dst, scratch, overflow_dst, SetRC);
+  }
+}
+
+
+void MacroAssembler::CompareMap(Register obj, Register scratch, Handle<Map> map,
+                                Label* early_success) {
+  LoadP(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
+  CompareMap(scratch, map, early_success);
+}
+
+
+void MacroAssembler::CompareMap(Register obj_map, Handle<Map> map,
+                                Label* early_success) {
+  mov(r0, Operand(map));
+  cmp(obj_map, r0);
+}
+
+
+void MacroAssembler::CheckMap(Register obj, Register scratch, Handle<Map> map,
+                              Label* fail, SmiCheckType smi_check_type) {
+  if (smi_check_type == DO_SMI_CHECK) {
+    JumpIfSmi(obj, fail);
+  }
+
+  Label success;
+  CompareMap(obj, scratch, map, &success);
+  bne(fail);
+  bind(&success);
+}
+
+
+void MacroAssembler::CheckMap(Register obj, Register scratch,
+                              Heap::RootListIndex index, Label* fail,
+                              SmiCheckType smi_check_type) {
+  if (smi_check_type == DO_SMI_CHECK) {
+    JumpIfSmi(obj, fail);
+  }
+  LoadP(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
+  LoadRoot(r0, index);
+  cmp(scratch, r0);
+  bne(fail);
+}
+
+
+void MacroAssembler::DispatchMap(Register obj, Register scratch,
+                                 Handle<Map> map, Handle<Code> success,
+                                 SmiCheckType smi_check_type) {
+  Label fail;
+  if (smi_check_type == DO_SMI_CHECK) {
+    JumpIfSmi(obj, &fail);
+  }
+  LoadP(scratch, FieldMemOperand(obj, HeapObject::kMapOffset));
+  mov(r0, Operand(map));
+  cmp(scratch, r0);
+  bne(&fail);
+  Jump(success, RelocInfo::CODE_TARGET, al);
+  bind(&fail);
+}
+
+
+void MacroAssembler::TryGetFunctionPrototype(Register function, Register result,
+                                             Register scratch, Label* miss,
+                                             bool miss_on_bound_function) {
+  Label non_instance;
+  if (miss_on_bound_function) {
+    // Check that the receiver isn't a smi.
+    JumpIfSmi(function, miss);
+
+    // Check that the function really is a function.  Load map into result reg.
+    CompareObjectType(function, result, scratch, JS_FUNCTION_TYPE);
+    bne(miss);
+
+    LoadP(scratch,
+          FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset));
+    lwz(scratch,
+        FieldMemOperand(scratch, SharedFunctionInfo::kCompilerHintsOffset));
+    TestBit(scratch,
+#if V8_TARGET_ARCH_PPC64
+            SharedFunctionInfo::kBoundFunction,
+#else
+            SharedFunctionInfo::kBoundFunction + kSmiTagSize,
+#endif
+            r0);
+    bne(miss, cr0);
+
+    // Make sure that the function has an instance prototype.
+    lbz(scratch, FieldMemOperand(result, Map::kBitFieldOffset));
+    andi(r0, scratch, Operand(1 << Map::kHasNonInstancePrototype));
+    bne(&non_instance, cr0);
+  }
+
+  // Get the prototype or initial map from the function.
+  LoadP(result,
+        FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
+
+  // If the prototype or initial map is the hole, don't return it and
+  // simply miss the cache instead. This will allow us to allocate a
+  // prototype object on-demand in the runtime system.
+  LoadRoot(r0, Heap::kTheHoleValueRootIndex);
+  cmp(result, r0);
+  beq(miss);
+
+  // If the function does not have an initial map, we're done.
+  Label done;
+  CompareObjectType(result, scratch, scratch, MAP_TYPE);
+  bne(&done);
+
+  // Get the prototype from the initial map.
+  LoadP(result, FieldMemOperand(result, Map::kPrototypeOffset));
+
+  if (miss_on_bound_function) {
+    b(&done);
+
+    // Non-instance prototype: Fetch prototype from constructor field
+    // in initial map.
+    bind(&non_instance);
+    LoadP(result, FieldMemOperand(result, Map::kConstructorOffset));
+  }
+
+  // All done.
+  bind(&done);
+}
+
+
+void MacroAssembler::CallStub(CodeStub* stub, TypeFeedbackId ast_id,
+                              Condition cond) {
+  DCHECK(AllowThisStubCall(stub));  // Stub calls are not allowed in some stubs.
+  Call(stub->GetCode(), RelocInfo::CODE_TARGET, ast_id, cond);
+}
+
+
+void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) {
+  Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
+}
+
+
+static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
+  return ref0.address() - ref1.address();
+}
+
+
+void MacroAssembler::CallApiFunctionAndReturn(
+    Register function_address, ExternalReference thunk_ref, int stack_space,
+    MemOperand return_value_operand, MemOperand* context_restore_operand) {
+  ExternalReference next_address =
+      ExternalReference::handle_scope_next_address(isolate());
+  const int kNextOffset = 0;
+  const int kLimitOffset = AddressOffset(
+      ExternalReference::handle_scope_limit_address(isolate()), next_address);
+  const int kLevelOffset = AddressOffset(
+      ExternalReference::handle_scope_level_address(isolate()), next_address);
+
+  DCHECK(function_address.is(r4) || function_address.is(r5));
+  Register scratch = r6;
+
+  Label profiler_disabled;
+  Label end_profiler_check;
+  mov(scratch, Operand(ExternalReference::is_profiling_address(isolate())));
+  lbz(scratch, MemOperand(scratch, 0));
+  cmpi(scratch, Operand::Zero());
+  beq(&profiler_disabled);
+
+  // Additional parameter is the address of the actual callback.
+  mov(scratch, Operand(thunk_ref));
+  jmp(&end_profiler_check);
+
+  bind(&profiler_disabled);
+  mr(scratch, function_address);
+  bind(&end_profiler_check);
+
+  // Allocate HandleScope in callee-save registers.
+  // r17 - next_address
+  // r14 - next_address->kNextOffset
+  // r15 - next_address->kLimitOffset
+  // r16 - next_address->kLevelOffset
+  mov(r17, Operand(next_address));
+  LoadP(r14, MemOperand(r17, kNextOffset));
+  LoadP(r15, MemOperand(r17, kLimitOffset));
+  lwz(r16, MemOperand(r17, kLevelOffset));
+  addi(r16, r16, Operand(1));
+  stw(r16, MemOperand(r17, kLevelOffset));
+
+  if (FLAG_log_timer_events) {
+    FrameScope frame(this, StackFrame::MANUAL);
+    PushSafepointRegisters();
+    PrepareCallCFunction(1, r3);
+    mov(r3, Operand(ExternalReference::isolate_address(isolate())));
+    CallCFunction(ExternalReference::log_enter_external_function(isolate()), 1);
+    PopSafepointRegisters();
+  }
+
+  // Native call returns to the DirectCEntry stub which redirects to the
+  // return address pushed on stack (could have moved after GC).
+  // DirectCEntry stub itself is generated early and never moves.
+  DirectCEntryStub stub(isolate());
+  stub.GenerateCall(this, scratch);
+
+  if (FLAG_log_timer_events) {
+    FrameScope frame(this, StackFrame::MANUAL);
+    PushSafepointRegisters();
+    PrepareCallCFunction(1, r3);
+    mov(r3, Operand(ExternalReference::isolate_address(isolate())));
+    CallCFunction(ExternalReference::log_leave_external_function(isolate()), 1);
+    PopSafepointRegisters();
+  }
+
+  Label promote_scheduled_exception;
+  Label exception_handled;
+  Label delete_allocated_handles;
+  Label leave_exit_frame;
+  Label return_value_loaded;
+
+  // load value from ReturnValue
+  LoadP(r3, return_value_operand);
+  bind(&return_value_loaded);
+  // No more valid handles (the result handle was the last one). Restore
+  // previous handle scope.
+  StoreP(r14, MemOperand(r17, kNextOffset));
+  if (emit_debug_code()) {
+    lwz(r4, MemOperand(r17, kLevelOffset));
+    cmp(r4, r16);
+    Check(eq, kUnexpectedLevelAfterReturnFromApiCall);
+  }
+  subi(r16, r16, Operand(1));
+  stw(r16, MemOperand(r17, kLevelOffset));
+  LoadP(r0, MemOperand(r17, kLimitOffset));
+  cmp(r15, r0);
+  bne(&delete_allocated_handles);
+
+  // Check if the function scheduled an exception.
+  bind(&leave_exit_frame);
+  LoadRoot(r14, Heap::kTheHoleValueRootIndex);
+  mov(r15, Operand(ExternalReference::scheduled_exception_address(isolate())));
+  LoadP(r15, MemOperand(r15));
+  cmp(r14, r15);
+  bne(&promote_scheduled_exception);
+  bind(&exception_handled);
+
+  bool restore_context = context_restore_operand != NULL;
+  if (restore_context) {
+    LoadP(cp, *context_restore_operand);
+  }
+  // LeaveExitFrame expects unwind space to be in a register.
+  mov(r14, Operand(stack_space));
+  LeaveExitFrame(false, r14, !restore_context);
+  blr();
+
+  bind(&promote_scheduled_exception);
+  {
+    FrameScope frame(this, StackFrame::INTERNAL);
+    CallExternalReference(
+        ExternalReference(Runtime::kPromoteScheduledException, isolate()), 0);
+  }
+  jmp(&exception_handled);
+
+  // HandleScope limit has changed. Delete allocated extensions.
+  bind(&delete_allocated_handles);
+  StoreP(r15, MemOperand(r17, kLimitOffset));
+  mr(r14, r3);
+  PrepareCallCFunction(1, r15);
+  mov(r3, Operand(ExternalReference::isolate_address(isolate())));
+  CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate()),
+                1);
+  mr(r3, r14);
+  b(&leave_exit_frame);
+}
+
+
+bool MacroAssembler::AllowThisStubCall(CodeStub* stub) {
+  return has_frame_ || !stub->SometimesSetsUpAFrame();
+}
+
+
+void MacroAssembler::IndexFromHash(Register hash, Register index) {
+  // If the hash field contains an array index pick it out. The assert checks
+  // that the constants for the maximum number of digits for an array index
+  // cached in the hash field and the number of bits reserved for it does not
+  // conflict.
+  DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) <
+         (1 << String::kArrayIndexValueBits));
+  DecodeFieldToSmi<String::ArrayIndexValueBits>(index, hash);
+}
+
+
+void MacroAssembler::SmiToDouble(DoubleRegister value, Register smi) {
+  SmiUntag(ip, smi);
+  ConvertIntToDouble(ip, value);
+}
+
+
+void MacroAssembler::TestDoubleIsInt32(DoubleRegister double_input,
+                                       Register scratch1, Register scratch2,
+                                       DoubleRegister double_scratch) {
+  TryDoubleToInt32Exact(scratch1, double_input, scratch2, double_scratch);
+}
+
+
+void MacroAssembler::TryDoubleToInt32Exact(Register result,
+                                           DoubleRegister double_input,
+                                           Register scratch,
+                                           DoubleRegister double_scratch) {
+  Label done;
+  DCHECK(!double_input.is(double_scratch));
+
+  ConvertDoubleToInt64(double_input,
+#if !V8_TARGET_ARCH_PPC64
+                       scratch,
+#endif
+                       result, double_scratch);
+
+#if V8_TARGET_ARCH_PPC64
+  TestIfInt32(result, scratch, r0);
+#else
+  TestIfInt32(scratch, result, r0);
+#endif
+  bne(&done);
+
+  // convert back and compare
+  fcfid(double_scratch, double_scratch);
+  fcmpu(double_scratch, double_input);
+  bind(&done);
+}
+
+
+void MacroAssembler::TryInt32Floor(Register result, DoubleRegister double_input,
+                                   Register input_high, Register scratch,
+                                   DoubleRegister double_scratch, Label* done,
+                                   Label* exact) {
+  DCHECK(!result.is(input_high));
+  DCHECK(!double_input.is(double_scratch));
+  Label exception;
+
+  MovDoubleHighToInt(input_high, double_input);
+
+  // Test for NaN/Inf
+  ExtractBitMask(result, input_high, HeapNumber::kExponentMask);
+  cmpli(result, Operand(0x7ff));
+  beq(&exception);
+
+  // Convert (rounding to -Inf)
+  ConvertDoubleToInt64(double_input,
+#if !V8_TARGET_ARCH_PPC64
+                       scratch,
+#endif
+                       result, double_scratch, kRoundToMinusInf);
+
+// Test for overflow
+#if V8_TARGET_ARCH_PPC64
+  TestIfInt32(result, scratch, r0);
+#else
+  TestIfInt32(scratch, result, r0);
+#endif
+  bne(&exception);
+
+  // Test for exactness
+  fcfid(double_scratch, double_scratch);
+  fcmpu(double_scratch, double_input);
+  beq(exact);
+  b(done);
+
+  bind(&exception);
+}
+
+
+void MacroAssembler::TryInlineTruncateDoubleToI(Register result,
+                                                DoubleRegister double_input,
+                                                Label* done) {
+  DoubleRegister double_scratch = kScratchDoubleReg;
+  Register scratch = ip;
+
+  ConvertDoubleToInt64(double_input,
+#if !V8_TARGET_ARCH_PPC64
+                       scratch,
+#endif
+                       result, double_scratch);
+
+// Test for overflow
+#if V8_TARGET_ARCH_PPC64
+  TestIfInt32(result, scratch, r0);
+#else
+  TestIfInt32(scratch, result, r0);
+#endif
+  beq(done);
+}
+
+
+void MacroAssembler::TruncateDoubleToI(Register result,
+                                       DoubleRegister double_input) {
+  Label done;
+
+  TryInlineTruncateDoubleToI(result, double_input, &done);
+
+  // If we fell through then inline version didn't succeed - call stub instead.
+  mflr(r0);
+  push(r0);
+  // Put input on stack.
+  stfdu(double_input, MemOperand(sp, -kDoubleSize));
+
+  DoubleToIStub stub(isolate(), sp, result, 0, true, true);
+  CallStub(&stub);
+
+  addi(sp, sp, Operand(kDoubleSize));
+  pop(r0);
+  mtlr(r0);
+
+  bind(&done);
+}
+
+
+void MacroAssembler::TruncateHeapNumberToI(Register result, Register object) {
+  Label done;
+  DoubleRegister double_scratch = kScratchDoubleReg;
+  DCHECK(!result.is(object));
+
+  lfd(double_scratch, FieldMemOperand(object, HeapNumber::kValueOffset));
+  TryInlineTruncateDoubleToI(result, double_scratch, &done);
+
+  // If we fell through then inline version didn't succeed - call stub instead.
+  mflr(r0);
+  push(r0);
+  DoubleToIStub stub(isolate(), object, result,
+                     HeapNumber::kValueOffset - kHeapObjectTag, true, true);
+  CallStub(&stub);
+  pop(r0);
+  mtlr(r0);
+
+  bind(&done);
+}
+
+
+void MacroAssembler::TruncateNumberToI(Register object, Register result,
+                                       Register heap_number_map,
+                                       Register scratch1, Label* not_number) {
+  Label done;
+  DCHECK(!result.is(object));
+
+  UntagAndJumpIfSmi(result, object, &done);
+  JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number);
+  TruncateHeapNumberToI(result, object);
+
+  bind(&done);
+}
+
+
+void MacroAssembler::GetLeastBitsFromSmi(Register dst, Register src,
+                                         int num_least_bits) {
+#if V8_TARGET_ARCH_PPC64
+  rldicl(dst, src, kBitsPerPointer - kSmiShift,
+         kBitsPerPointer - num_least_bits);
+#else
+  rlwinm(dst, src, kBitsPerPointer - kSmiShift,
+         kBitsPerPointer - num_least_bits, 31);
+#endif
+}
+
+
+void MacroAssembler::GetLeastBitsFromInt32(Register dst, Register src,
+                                           int num_least_bits) {
+  rlwinm(dst, src, 0, 32 - num_least_bits, 31);
+}
+
+
+void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
+                                 SaveFPRegsMode save_doubles) {
+  // All parameters are on the stack.  r3 has the return value after call.
+
+  // If the expected number of arguments of the runtime function is
+  // constant, we check that the actual number of arguments match the
+  // expectation.
+  CHECK(f->nargs < 0 || f->nargs == num_arguments);
+
+  // TODO(1236192): Most runtime routines don't need the number of
+  // arguments passed in because it is constant. At some point we
+  // should remove this need and make the runtime routine entry code
+  // smarter.
+  mov(r3, Operand(num_arguments));
+  mov(r4, Operand(ExternalReference(f, isolate())));
+  CEntryStub stub(isolate(),
+#if V8_TARGET_ARCH_PPC64
+                  f->result_size,
+#else
+                  1,
+#endif
+                  save_doubles);
+  CallStub(&stub);
+}
+
+
+void MacroAssembler::CallExternalReference(const ExternalReference& ext,
+                                           int num_arguments) {
+  mov(r3, Operand(num_arguments));
+  mov(r4, Operand(ext));
+
+  CEntryStub stub(isolate(), 1);
+  CallStub(&stub);
+}
+
+
+void MacroAssembler::TailCallExternalReference(const ExternalReference& ext,
+                                               int num_arguments,
+                                               int result_size) {
+  // TODO(1236192): Most runtime routines don't need the number of
+  // arguments passed in because it is constant. At some point we
+  // should remove this need and make the runtime routine entry code
+  // smarter.
+  mov(r3, Operand(num_arguments));
+  JumpToExternalReference(ext);
+}
+
+
+void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid, int num_arguments,
+                                     int result_size) {
+  TailCallExternalReference(ExternalReference(fid, isolate()), num_arguments,
+                            result_size);
+}
+
+
+void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin) {
+  mov(r4, Operand(builtin));
+  CEntryStub stub(isolate(), 1);
+  Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
+}
+
+
+void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag,
+                                   const CallWrapper& call_wrapper) {
+  // You can't call a builtin without a valid frame.
+  DCHECK(flag == JUMP_FUNCTION || has_frame());
+
+  GetBuiltinEntry(ip, id);
+  if (flag == CALL_FUNCTION) {
+    call_wrapper.BeforeCall(CallSize(ip));
+    CallJSEntry(ip);
+    call_wrapper.AfterCall();
+  } else {
+    DCHECK(flag == JUMP_FUNCTION);
+    JumpToJSEntry(ip);
+  }
+}
+
+
+void MacroAssembler::GetBuiltinFunction(Register target,
+                                        Builtins::JavaScript id) {
+  // Load the builtins object into target register.
+  LoadP(target,
+        MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+  LoadP(target, FieldMemOperand(target, GlobalObject::kBuiltinsOffset));
+  // Load the JavaScript builtin function from the builtins object.
+  LoadP(target,
+        FieldMemOperand(target, JSBuiltinsObject::OffsetOfFunctionWithId(id)),
+        r0);
+}
+
+
+void MacroAssembler::GetBuiltinEntry(Register target, Builtins::JavaScript id) {
+  DCHECK(!target.is(r4));
+  GetBuiltinFunction(r4, id);
+  // Load the code entry point from the builtins object.
+  LoadP(target, FieldMemOperand(r4, JSFunction::kCodeEntryOffset));
+}
+
+
+void MacroAssembler::SetCounter(StatsCounter* counter, int value,
+                                Register scratch1, Register scratch2) {
+  if (FLAG_native_code_counters && counter->Enabled()) {
+    mov(scratch1, Operand(value));
+    mov(scratch2, Operand(ExternalReference(counter)));
+    stw(scratch1, MemOperand(scratch2));
+  }
+}
+
+
+void MacroAssembler::IncrementCounter(StatsCounter* counter, int value,
+                                      Register scratch1, Register scratch2) {
+  DCHECK(value > 0);
+  if (FLAG_native_code_counters && counter->Enabled()) {
+    mov(scratch2, Operand(ExternalReference(counter)));
+    lwz(scratch1, MemOperand(scratch2));
+    addi(scratch1, scratch1, Operand(value));
+    stw(scratch1, MemOperand(scratch2));
+  }
+}
+
+
+void MacroAssembler::DecrementCounter(StatsCounter* counter, int value,
+                                      Register scratch1, Register scratch2) {
+  DCHECK(value > 0);
+  if (FLAG_native_code_counters && counter->Enabled()) {
+    mov(scratch2, Operand(ExternalReference(counter)));
+    lwz(scratch1, MemOperand(scratch2));
+    subi(scratch1, scratch1, Operand(value));
+    stw(scratch1, MemOperand(scratch2));
+  }
+}
+
+
+void MacroAssembler::Assert(Condition cond, BailoutReason reason,
+                            CRegister cr) {
+  if (emit_debug_code()) Check(cond, reason, cr);
+}
+
+
+void MacroAssembler::AssertFastElements(Register elements) {
+  if (emit_debug_code()) {
+    DCHECK(!elements.is(r0));
+    Label ok;
+    push(elements);
+    LoadP(elements, FieldMemOperand(elements, HeapObject::kMapOffset));
+    LoadRoot(r0, Heap::kFixedArrayMapRootIndex);
+    cmp(elements, r0);
+    beq(&ok);
+    LoadRoot(r0, Heap::kFixedDoubleArrayMapRootIndex);
+    cmp(elements, r0);
+    beq(&ok);
+    LoadRoot(r0, Heap::kFixedCOWArrayMapRootIndex);
+    cmp(elements, r0);
+    beq(&ok);
+    Abort(kJSObjectWithFastElementsMapHasSlowElements);
+    bind(&ok);
+    pop(elements);
+  }
+}
+
+
+void MacroAssembler::Check(Condition cond, BailoutReason reason, CRegister cr) {
+  Label L;
+  b(cond, &L, cr);
+  Abort(reason);
+  // will not return here
+  bind(&L);
+}
+
+
+void MacroAssembler::Abort(BailoutReason reason) {
+  Label abort_start;
+  bind(&abort_start);
+#ifdef DEBUG
+  const char* msg = GetBailoutReason(reason);
+  if (msg != NULL) {
+    RecordComment("Abort message: ");
+    RecordComment(msg);
+  }
+
+  if (FLAG_trap_on_abort) {
+    stop(msg);
+    return;
+  }
+#endif
+
+  LoadSmiLiteral(r0, Smi::FromInt(reason));
+  push(r0);
+  // Disable stub call restrictions to always allow calls to abort.
+  if (!has_frame_) {
+    // We don't actually want to generate a pile of code for this, so just
+    // claim there is a stack frame, without generating one.
+    FrameScope scope(this, StackFrame::NONE);
+    CallRuntime(Runtime::kAbort, 1);
+  } else {
+    CallRuntime(Runtime::kAbort, 1);
+  }
+  // will not return here
+}
+
+
+void MacroAssembler::LoadContext(Register dst, int context_chain_length) {
+  if (context_chain_length > 0) {
+    // Move up the chain of contexts to the context containing the slot.
+    LoadP(dst, MemOperand(cp, Context::SlotOffset(Context::PREVIOUS_INDEX)));
+    for (int i = 1; i < context_chain_length; i++) {
+      LoadP(dst, MemOperand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX)));
+    }
+  } else {
+    // Slot is in the current function context.  Move it into the
+    // destination register in case we store into it (the write barrier
+    // cannot be allowed to destroy the context in esi).
+    mr(dst, cp);
+  }
+}
+
+
+void MacroAssembler::LoadTransitionedArrayMapConditional(
+    ElementsKind expected_kind, ElementsKind transitioned_kind,
+    Register map_in_out, Register scratch, Label* no_map_match) {
+  // Load the global or builtins object from the current context.
+  LoadP(scratch,
+        MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+  LoadP(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
+
+  // Check that the function's map is the same as the expected cached map.
+  LoadP(scratch,
+        MemOperand(scratch, Context::SlotOffset(Context::JS_ARRAY_MAPS_INDEX)));
+  size_t offset = expected_kind * kPointerSize + FixedArrayBase::kHeaderSize;
+  LoadP(scratch, FieldMemOperand(scratch, offset));
+  cmp(map_in_out, scratch);
+  bne(no_map_match);
+
+  // Use the transitioned cached map.
+  offset = transitioned_kind * kPointerSize + FixedArrayBase::kHeaderSize;
+  LoadP(map_in_out, FieldMemOperand(scratch, offset));
+}
+
+
+void MacroAssembler::LoadGlobalFunction(int index, Register function) {
+  // Load the global or builtins object from the current context.
+  LoadP(function,
+        MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+  // Load the native context from the global or builtins object.
+  LoadP(function,
+        FieldMemOperand(function, GlobalObject::kNativeContextOffset));
+  // Load the function from the native context.
+  LoadP(function, MemOperand(function, Context::SlotOffset(index)), r0);
+}
+
+
+void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
+                                                  Register map,
+                                                  Register scratch) {
+  // Load the initial map. The global functions all have initial maps.
+  LoadP(map,
+        FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
+  if (emit_debug_code()) {
+    Label ok, fail;
+    CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, DO_SMI_CHECK);
+    b(&ok);
+    bind(&fail);
+    Abort(kGlobalFunctionsMustHaveInitialMap);
+    bind(&ok);
+  }
+}
+
+
+void MacroAssembler::JumpIfNotPowerOfTwoOrZero(
+    Register reg, Register scratch, Label* not_power_of_two_or_zero) {
+  subi(scratch, reg, Operand(1));
+  cmpi(scratch, Operand::Zero());
+  blt(not_power_of_two_or_zero);
+  and_(r0, scratch, reg, SetRC);
+  bne(not_power_of_two_or_zero, cr0);
+}
+
+
+void MacroAssembler::JumpIfNotPowerOfTwoOrZeroAndNeg(Register reg,
+                                                     Register scratch,
+                                                     Label* zero_and_neg,
+                                                     Label* not_power_of_two) {
+  subi(scratch, reg, Operand(1));
+  cmpi(scratch, Operand::Zero());
+  blt(zero_and_neg);
+  and_(r0, scratch, reg, SetRC);
+  bne(not_power_of_two, cr0);
+}
+
+#if !V8_TARGET_ARCH_PPC64
+void MacroAssembler::SmiTagCheckOverflow(Register reg, Register overflow) {
+  DCHECK(!reg.is(overflow));
+  mr(overflow, reg);  // Save original value.
+  SmiTag(reg);
+  xor_(overflow, overflow, reg, SetRC);  // Overflow if (value ^ 2 * value) < 0.
+}
+
+
+void MacroAssembler::SmiTagCheckOverflow(Register dst, Register src,
+                                         Register overflow) {
+  if (dst.is(src)) {
+    // Fall back to slower case.
+    SmiTagCheckOverflow(dst, overflow);
+  } else {
+    DCHECK(!dst.is(src));
+    DCHECK(!dst.is(overflow));
+    DCHECK(!src.is(overflow));
+    SmiTag(dst, src);
+    xor_(overflow, dst, src, SetRC);  // Overflow if (value ^ 2 * value) < 0.
+  }
+}
+#endif
+
+void MacroAssembler::JumpIfNotBothSmi(Register reg1, Register reg2,
+                                      Label* on_not_both_smi) {
+  STATIC_ASSERT(kSmiTag == 0);
+  DCHECK_EQ(1, static_cast<int>(kSmiTagMask));
+  orx(r0, reg1, reg2, LeaveRC);
+  JumpIfNotSmi(r0, on_not_both_smi);
+}
+
+
+void MacroAssembler::UntagAndJumpIfSmi(Register dst, Register src,
+                                       Label* smi_case) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+  TestBit(src, 0, r0);
+  SmiUntag(dst, src);
+  beq(smi_case, cr0);
+}
+
+
+void MacroAssembler::UntagAndJumpIfNotSmi(Register dst, Register src,
+                                          Label* non_smi_case) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+  TestBit(src, 0, r0);
+  SmiUntag(dst, src);
+  bne(non_smi_case, cr0);
+}
+
+
+void MacroAssembler::JumpIfEitherSmi(Register reg1, Register reg2,
+                                     Label* on_either_smi) {
+  STATIC_ASSERT(kSmiTag == 0);
+  JumpIfSmi(reg1, on_either_smi);
+  JumpIfSmi(reg2, on_either_smi);
+}
+
+
+void MacroAssembler::AssertNotSmi(Register object) {
+  if (emit_debug_code()) {
+    STATIC_ASSERT(kSmiTag == 0);
+    TestIfSmi(object, r0);
+    Check(ne, kOperandIsASmi, cr0);
+  }
+}
+
+
+void MacroAssembler::AssertSmi(Register object) {
+  if (emit_debug_code()) {
+    STATIC_ASSERT(kSmiTag == 0);
+    TestIfSmi(object, r0);
+    Check(eq, kOperandIsNotSmi, cr0);
+  }
+}
+
+
+void MacroAssembler::AssertString(Register object) {
+  if (emit_debug_code()) {
+    STATIC_ASSERT(kSmiTag == 0);
+    TestIfSmi(object, r0);
+    Check(ne, kOperandIsASmiAndNotAString, cr0);
+    push(object);
+    LoadP(object, FieldMemOperand(object, HeapObject::kMapOffset));
+    CompareInstanceType(object, object, FIRST_NONSTRING_TYPE);
+    pop(object);
+    Check(lt, kOperandIsNotAString);
+  }
+}
+
+
+void MacroAssembler::AssertName(Register object) {
+  if (emit_debug_code()) {
+    STATIC_ASSERT(kSmiTag == 0);
+    TestIfSmi(object, r0);
+    Check(ne, kOperandIsASmiAndNotAName, cr0);
+    push(object);
+    LoadP(object, FieldMemOperand(object, HeapObject::kMapOffset));
+    CompareInstanceType(object, object, LAST_NAME_TYPE);
+    pop(object);
+    Check(le, kOperandIsNotAName);
+  }
+}
+
+
+void MacroAssembler::AssertUndefinedOrAllocationSite(Register object,
+                                                     Register scratch) {
+  if (emit_debug_code()) {
+    Label done_checking;
+    AssertNotSmi(object);
+    CompareRoot(object, Heap::kUndefinedValueRootIndex);
+    beq(&done_checking);
+    LoadP(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
+    CompareRoot(scratch, Heap::kAllocationSiteMapRootIndex);
+    Assert(eq, kExpectedUndefinedOrCell);
+    bind(&done_checking);
+  }
+}
+
+
+void MacroAssembler::AssertIsRoot(Register reg, Heap::RootListIndex index) {
+  if (emit_debug_code()) {
+    CompareRoot(reg, index);
+    Check(eq, kHeapNumberMapRegisterClobbered);
+  }
+}
+
+
+void MacroAssembler::JumpIfNotHeapNumber(Register object,
+                                         Register heap_number_map,
+                                         Register scratch,
+                                         Label* on_not_heap_number) {
+  LoadP(scratch, FieldMemOperand(object, HeapObject::kMapOffset));
+  AssertIsRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
+  cmp(scratch, heap_number_map);
+  bne(on_not_heap_number);
+}
+
+
+void MacroAssembler::LookupNumberStringCache(Register object, Register result,
+                                             Register scratch1,
+                                             Register scratch2,
+                                             Register scratch3,
+                                             Label* not_found) {
+  // Use of registers. Register result is used as a temporary.
+  Register number_string_cache = result;
+  Register mask = scratch3;
+
+  // Load the number string cache.
+  LoadRoot(number_string_cache, Heap::kNumberStringCacheRootIndex);
+
+  // Make the hash mask from the length of the number string cache. It
+  // contains two elements (number and string) for each cache entry.
+  LoadP(mask, FieldMemOperand(number_string_cache, FixedArray::kLengthOffset));
+  // Divide length by two (length is a smi).
+  ShiftRightArithImm(mask, mask, kSmiTagSize + kSmiShiftSize + 1);
+  subi(mask, mask, Operand(1));  // Make mask.
+
+  // Calculate the entry in the number string cache. The hash value in the
+  // number string cache for smis is just the smi value, and the hash for
+  // doubles is the xor of the upper and lower words. See
+  // Heap::GetNumberStringCache.
+  Label is_smi;
+  Label load_result_from_cache;
+  JumpIfSmi(object, &is_smi);
+  CheckMap(object, scratch1, Heap::kHeapNumberMapRootIndex, not_found,
+           DONT_DO_SMI_CHECK);
+
+  STATIC_ASSERT(8 == kDoubleSize);
+  lwz(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset));
+  lwz(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset));
+  xor_(scratch1, scratch1, scratch2);
+  and_(scratch1, scratch1, mask);
+
+  // Calculate address of entry in string cache: each entry consists
+  // of two pointer sized fields.
+  ShiftLeftImm(scratch1, scratch1, Operand(kPointerSizeLog2 + 1));
+  add(scratch1, number_string_cache, scratch1);
+
+  Register probe = mask;
+  LoadP(probe, FieldMemOperand(scratch1, FixedArray::kHeaderSize));
+  JumpIfSmi(probe, not_found);
+  lfd(d0, FieldMemOperand(object, HeapNumber::kValueOffset));
+  lfd(d1, FieldMemOperand(probe, HeapNumber::kValueOffset));
+  fcmpu(d0, d1);
+  bne(not_found);  // The cache did not contain this value.
+  b(&load_result_from_cache);
+
+  bind(&is_smi);
+  Register scratch = scratch1;
+  SmiUntag(scratch, object);
+  and_(scratch, mask, scratch);
+  // Calculate address of entry in string cache: each entry consists
+  // of two pointer sized fields.
+  ShiftLeftImm(scratch, scratch, Operand(kPointerSizeLog2 + 1));
+  add(scratch, number_string_cache, scratch);
+
+  // Check if the entry is the smi we are looking for.
+  LoadP(probe, FieldMemOperand(scratch, FixedArray::kHeaderSize));
+  cmp(object, probe);
+  bne(not_found);
+
+  // Get the result from the cache.
+  bind(&load_result_from_cache);
+  LoadP(result,
+        FieldMemOperand(scratch, FixedArray::kHeaderSize + kPointerSize));
+  IncrementCounter(isolate()->counters()->number_to_string_native(), 1,
+                   scratch1, scratch2);
+}
+
+
+void MacroAssembler::JumpIfNonSmisNotBothSequentialOneByteStrings(
+    Register first, Register second, Register scratch1, Register scratch2,
+    Label* failure) {
+  // Test that both first and second are sequential one-byte strings.
+  // Assume that they are non-smis.
+  LoadP(scratch1, FieldMemOperand(first, HeapObject::kMapOffset));
+  LoadP(scratch2, FieldMemOperand(second, HeapObject::kMapOffset));
+  lbz(scratch1, FieldMemOperand(scratch1, Map::kInstanceTypeOffset));
+  lbz(scratch2, FieldMemOperand(scratch2, Map::kInstanceTypeOffset));
+
+  JumpIfBothInstanceTypesAreNotSequentialOneByte(scratch1, scratch2, scratch1,
+                                                 scratch2, failure);
+}
+
+void MacroAssembler::JumpIfNotBothSequentialOneByteStrings(Register first,
+                                                           Register second,
+                                                           Register scratch1,
+                                                           Register scratch2,
+                                                           Label* failure) {
+  // Check that neither is a smi.
+  and_(scratch1, first, second);
+  JumpIfSmi(scratch1, failure);
+  JumpIfNonSmisNotBothSequentialOneByteStrings(first, second, scratch1,
+                                               scratch2, failure);
+}
+
+
+void MacroAssembler::JumpIfNotUniqueNameInstanceType(Register reg,
+                                                     Label* not_unique_name) {
+  STATIC_ASSERT(kInternalizedTag == 0 && kStringTag == 0);
+  Label succeed;
+  andi(r0, reg, Operand(kIsNotStringMask | kIsNotInternalizedMask));
+  beq(&succeed, cr0);
+  cmpi(reg, Operand(SYMBOL_TYPE));
+  bne(not_unique_name);
+
+  bind(&succeed);
+}
+
+
+// Allocates a heap number or jumps to the need_gc label if the young space
+// is full and a scavenge is needed.
+void MacroAssembler::AllocateHeapNumber(Register result, Register scratch1,
+                                        Register scratch2,
+                                        Register heap_number_map,
+                                        Label* gc_required,
+                                        TaggingMode tagging_mode,
+                                        MutableMode mode) {
+  // Allocate an object in the heap for the heap number and tag it as a heap
+  // object.
+  Allocate(HeapNumber::kSize, result, scratch1, scratch2, gc_required,
+           tagging_mode == TAG_RESULT ? TAG_OBJECT : NO_ALLOCATION_FLAGS);
+
+  Heap::RootListIndex map_index = mode == MUTABLE
+                                      ? Heap::kMutableHeapNumberMapRootIndex
+                                      : Heap::kHeapNumberMapRootIndex;
+  AssertIsRoot(heap_number_map, map_index);
+
+  // Store heap number map in the allocated object.
+  if (tagging_mode == TAG_RESULT) {
+    StoreP(heap_number_map, FieldMemOperand(result, HeapObject::kMapOffset),
+           r0);
+  } else {
+    StoreP(heap_number_map, MemOperand(result, HeapObject::kMapOffset));
+  }
+}
+
+
+void MacroAssembler::AllocateHeapNumberWithValue(
+    Register result, DoubleRegister value, Register scratch1, Register scratch2,
+    Register heap_number_map, Label* gc_required) {
+  AllocateHeapNumber(result, scratch1, scratch2, heap_number_map, gc_required);
+  stfd(value, FieldMemOperand(result, HeapNumber::kValueOffset));
+}
+
+
+// Copies a fixed number of fields of heap objects from src to dst.
+void MacroAssembler::CopyFields(Register dst, Register src, RegList temps,
+                                int field_count) {
+  // At least one bit set in the first 15 registers.
+  DCHECK((temps & ((1 << 15) - 1)) != 0);
+  DCHECK((temps & dst.bit()) == 0);
+  DCHECK((temps & src.bit()) == 0);
+  // Primitive implementation using only one temporary register.
+
+  Register tmp = no_reg;
+  // Find a temp register in temps list.
+  for (int i = 0; i < 15; i++) {
+    if ((temps & (1 << i)) != 0) {
+      tmp.set_code(i);
+      break;
+    }
+  }
+  DCHECK(!tmp.is(no_reg));
+
+  for (int i = 0; i < field_count; i++) {
+    LoadP(tmp, FieldMemOperand(src, i * kPointerSize), r0);
+    StoreP(tmp, FieldMemOperand(dst, i * kPointerSize), r0);
+  }
+}
+
+
+void MacroAssembler::CopyBytes(Register src, Register dst, Register length,
+                               Register scratch) {
+  Label align_loop, aligned, word_loop, byte_loop, byte_loop_1, done;
+
+  DCHECK(!scratch.is(r0));
+
+  cmpi(length, Operand::Zero());
+  beq(&done);
+
+  // Check src alignment and length to see whether word_loop is possible
+  andi(scratch, src, Operand(kPointerSize - 1));
+  beq(&aligned, cr0);
+  subfic(scratch, scratch, Operand(kPointerSize * 2));
+  cmp(length, scratch);
+  blt(&byte_loop);
+
+  // Align src before copying in word size chunks.
+  subi(scratch, scratch, Operand(kPointerSize));
+  mtctr(scratch);
+  bind(&align_loop);
+  lbz(scratch, MemOperand(src));
+  addi(src, src, Operand(1));
+  subi(length, length, Operand(1));
+  stb(scratch, MemOperand(dst));
+  addi(dst, dst, Operand(1));
+  bdnz(&align_loop);
+
+  bind(&aligned);
+
+  // Copy bytes in word size chunks.
+  if (emit_debug_code()) {
+    andi(r0, src, Operand(kPointerSize - 1));
+    Assert(eq, kExpectingAlignmentForCopyBytes, cr0);
+  }
+
+  ShiftRightImm(scratch, length, Operand(kPointerSizeLog2));
+  cmpi(scratch, Operand::Zero());
+  beq(&byte_loop);
+
+  mtctr(scratch);
+  bind(&word_loop);
+  LoadP(scratch, MemOperand(src));
+  addi(src, src, Operand(kPointerSize));
+  subi(length, length, Operand(kPointerSize));
+  if (CpuFeatures::IsSupported(UNALIGNED_ACCESSES)) {
+    // currently false for PPC - but possible future opt
+    StoreP(scratch, MemOperand(dst));
+    addi(dst, dst, Operand(kPointerSize));
+  } else {
+#if V8_TARGET_LITTLE_ENDIAN
+    stb(scratch, MemOperand(dst, 0));
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 1));
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 2));
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 3));
+#if V8_TARGET_ARCH_PPC64
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 4));
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 5));
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 6));
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 7));
+#endif
+#else
+#if V8_TARGET_ARCH_PPC64
+    stb(scratch, MemOperand(dst, 7));
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 6));
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 5));
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 4));
+    ShiftRightImm(scratch, scratch, Operand(8));
+#endif
+    stb(scratch, MemOperand(dst, 3));
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 2));
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 1));
+    ShiftRightImm(scratch, scratch, Operand(8));
+    stb(scratch, MemOperand(dst, 0));
+#endif
+    addi(dst, dst, Operand(kPointerSize));
+  }
+  bdnz(&word_loop);
+
+  // Copy the last bytes if any left.
+  cmpi(length, Operand::Zero());
+  beq(&done);
+
+  bind(&byte_loop);
+  mtctr(length);
+  bind(&byte_loop_1);
+  lbz(scratch, MemOperand(src));
+  addi(src, src, Operand(1));
+  stb(scratch, MemOperand(dst));
+  addi(dst, dst, Operand(1));
+  bdnz(&byte_loop_1);
+
+  bind(&done);
+}
+
+
+void MacroAssembler::InitializeNFieldsWithFiller(Register start_offset,
+                                                 Register count,
+                                                 Register filler) {
+  Label loop;
+  mtctr(count);
+  bind(&loop);
+  StoreP(filler, MemOperand(start_offset));
+  addi(start_offset, start_offset, Operand(kPointerSize));
+  bdnz(&loop);
+}
+
+void MacroAssembler::InitializeFieldsWithFiller(Register start_offset,
+                                                Register end_offset,
+                                                Register filler) {
+  Label done;
+  sub(r0, end_offset, start_offset, LeaveOE, SetRC);
+  beq(&done, cr0);
+  ShiftRightImm(r0, r0, Operand(kPointerSizeLog2));
+  InitializeNFieldsWithFiller(start_offset, r0, filler);
+  bind(&done);
+}
+
+
+void MacroAssembler::SaveFPRegs(Register location, int first, int count) {
+  DCHECK(count > 0);
+  int cur = first;
+  subi(location, location, Operand(count * kDoubleSize));
+  for (int i = 0; i < count; i++) {
+    DoubleRegister reg = DoubleRegister::from_code(cur++);
+    stfd(reg, MemOperand(location, i * kDoubleSize));
+  }
+}
+
+
+void MacroAssembler::RestoreFPRegs(Register location, int first, int count) {
+  DCHECK(count > 0);
+  int cur = first + count - 1;
+  for (int i = count - 1; i >= 0; i--) {
+    DoubleRegister reg = DoubleRegister::from_code(cur--);
+    lfd(reg, MemOperand(location, i * kDoubleSize));
+  }
+  addi(location, location, Operand(count * kDoubleSize));
+}
+
+
+void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte(
+    Register first, Register second, Register scratch1, Register scratch2,
+    Label* failure) {
+  const int kFlatOneByteStringMask =
+      kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
+  const int kFlatOneByteStringTag =
+      kStringTag | kOneByteStringTag | kSeqStringTag;
+  andi(scratch1, first, Operand(kFlatOneByteStringMask));
+  andi(scratch2, second, Operand(kFlatOneByteStringMask));
+  cmpi(scratch1, Operand(kFlatOneByteStringTag));
+  bne(failure);
+  cmpi(scratch2, Operand(kFlatOneByteStringTag));
+  bne(failure);
+}
+
+
+void MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte(Register type,
+                                                              Register scratch,
+                                                              Label* failure) {
+  const int kFlatOneByteStringMask =
+      kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask;
+  const int kFlatOneByteStringTag =
+      kStringTag | kOneByteStringTag | kSeqStringTag;
+  andi(scratch, type, Operand(kFlatOneByteStringMask));
+  cmpi(scratch, Operand(kFlatOneByteStringTag));
+  bne(failure);
+}
+
+static const int kRegisterPassedArguments = 8;
+
+
+int MacroAssembler::CalculateStackPassedWords(int num_reg_arguments,
+                                              int num_double_arguments) {
+  int stack_passed_words = 0;
+  if (num_double_arguments > DoubleRegister::kNumRegisters) {
+    stack_passed_words +=
+        2 * (num_double_arguments - DoubleRegister::kNumRegisters);
+  }
+  // Up to 8 simple arguments are passed in registers r3..r10.
+  if (num_reg_arguments > kRegisterPassedArguments) {
+    stack_passed_words += num_reg_arguments - kRegisterPassedArguments;
+  }
+  return stack_passed_words;
+}
+
+
+void MacroAssembler::EmitSeqStringSetCharCheck(Register string, Register index,
+                                               Register value,
+                                               uint32_t encoding_mask) {
+  Label is_object;
+  TestIfSmi(string, r0);
+  Check(ne, kNonObject, cr0);
+
+  LoadP(ip, FieldMemOperand(string, HeapObject::kMapOffset));
+  lbz(ip, FieldMemOperand(ip, Map::kInstanceTypeOffset));
+
+  andi(ip, ip, Operand(kStringRepresentationMask | kStringEncodingMask));
+  cmpi(ip, Operand(encoding_mask));
+  Check(eq, kUnexpectedStringType);
+
+// The index is assumed to be untagged coming in, tag it to compare with the
+// string length without using a temp register, it is restored at the end of
+// this function.
+#if !V8_TARGET_ARCH_PPC64
+  Label index_tag_ok, index_tag_bad;
+  JumpIfNotSmiCandidate(index, r0, &index_tag_bad);
+#endif
+  SmiTag(index, index);
+#if !V8_TARGET_ARCH_PPC64
+  b(&index_tag_ok);
+  bind(&index_tag_bad);
+  Abort(kIndexIsTooLarge);
+  bind(&index_tag_ok);
+#endif
+
+  LoadP(ip, FieldMemOperand(string, String::kLengthOffset));
+  cmp(index, ip);
+  Check(lt, kIndexIsTooLarge);
+
+  DCHECK(Smi::FromInt(0) == 0);
+  cmpi(index, Operand::Zero());
+  Check(ge, kIndexIsNegative);
+
+  SmiUntag(index, index);
+}
+
+
+void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
+                                          int num_double_arguments,
+                                          Register scratch) {
+  int frame_alignment = ActivationFrameAlignment();
+  int stack_passed_arguments =
+      CalculateStackPassedWords(num_reg_arguments, num_double_arguments);
+  int stack_space = kNumRequiredStackFrameSlots;
+
+  if (frame_alignment > kPointerSize) {
+    // Make stack end at alignment and make room for stack arguments
+    // -- preserving original value of sp.
+    mr(scratch, sp);
+    addi(sp, sp, Operand(-(stack_passed_arguments + 1) * kPointerSize));
+    DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
+    ClearRightImm(sp, sp, Operand(WhichPowerOf2(frame_alignment)));
+    StoreP(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize));
+  } else {
+    // Make room for stack arguments
+    stack_space += stack_passed_arguments;
+  }
+
+  // Allocate frame with required slots to make ABI work.
+  li(r0, Operand::Zero());
+  StorePU(r0, MemOperand(sp, -stack_space * kPointerSize));
+}
+
+
+void MacroAssembler::PrepareCallCFunction(int num_reg_arguments,
+                                          Register scratch) {
+  PrepareCallCFunction(num_reg_arguments, 0, scratch);
+}
+
+
+void MacroAssembler::MovToFloatParameter(DoubleRegister src) { Move(d1, src); }
+
+
+void MacroAssembler::MovToFloatResult(DoubleRegister src) { Move(d1, src); }
+
+
+void MacroAssembler::MovToFloatParameters(DoubleRegister src1,
+                                          DoubleRegister src2) {
+  if (src2.is(d1)) {
+    DCHECK(!src1.is(d2));
+    Move(d2, src2);
+    Move(d1, src1);
+  } else {
+    Move(d1, src1);
+    Move(d2, src2);
+  }
+}
+
+
+void MacroAssembler::CallCFunction(ExternalReference function,
+                                   int num_reg_arguments,
+                                   int num_double_arguments) {
+  mov(ip, Operand(function));
+  CallCFunctionHelper(ip, num_reg_arguments, num_double_arguments);
+}
+
+
+void MacroAssembler::CallCFunction(Register function, int num_reg_arguments,
+                                   int num_double_arguments) {
+  CallCFunctionHelper(function, num_reg_arguments, num_double_arguments);
+}
+
+
+void MacroAssembler::CallCFunction(ExternalReference function,
+                                   int num_arguments) {
+  CallCFunction(function, num_arguments, 0);
+}
+
+
+void MacroAssembler::CallCFunction(Register function, int num_arguments) {
+  CallCFunction(function, num_arguments, 0);
+}
+
+
+void MacroAssembler::CallCFunctionHelper(Register function,
+                                         int num_reg_arguments,
+                                         int num_double_arguments) {
+  DCHECK(has_frame());
+// Just call directly. The function called cannot cause a GC, or
+// allow preemption, so the return address in the link register
+// stays correct.
+#if ABI_USES_FUNCTION_DESCRIPTORS && !defined(USE_SIMULATOR)
+  // AIX uses a function descriptor. When calling C code be aware
+  // of this descriptor and pick up values from it
+  LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(function, kPointerSize));
+  LoadP(ip, MemOperand(function, 0));
+  Register dest = ip;
+#elif ABI_TOC_ADDRESSABILITY_VIA_IP
+  Move(ip, function);
+  Register dest = ip;
+#else
+  Register dest = function;
+#endif
+
+  Call(dest);
+
+  // Remove frame bought in PrepareCallCFunction
+  int stack_passed_arguments =
+      CalculateStackPassedWords(num_reg_arguments, num_double_arguments);
+  int stack_space = kNumRequiredStackFrameSlots + stack_passed_arguments;
+  if (ActivationFrameAlignment() > kPointerSize) {
+    LoadP(sp, MemOperand(sp, stack_space * kPointerSize));
+  } else {
+    addi(sp, sp, Operand(stack_space * kPointerSize));
+  }
+}
+
+
+void MacroAssembler::FlushICache(Register address, size_t size,
+                                 Register scratch) {
+  if (CpuFeatures::IsSupported(INSTR_AND_DATA_CACHE_COHERENCY)) {
+    sync();
+    icbi(r0, address);
+    isync();
+    return;
+  }
+
+  Label done;
+
+  dcbf(r0, address);
+  sync();
+  icbi(r0, address);
+  isync();
+
+  // This code handles ranges which cross a single cacheline boundary.
+  // scratch is last cacheline which intersects range.
+  const int kCacheLineSizeLog2 = WhichPowerOf2(CpuFeatures::cache_line_size());
+
+  DCHECK(size > 0 && size <= (size_t)(1 << kCacheLineSizeLog2));
+  addi(scratch, address, Operand(size - 1));
+  ClearRightImm(scratch, scratch, Operand(kCacheLineSizeLog2));
+  cmpl(scratch, address);
+  ble(&done);
+
+  dcbf(r0, scratch);
+  sync();
+  icbi(r0, scratch);
+  isync();
+
+  bind(&done);
+}
+
+
+void MacroAssembler::SetRelocatedValue(Register location, Register scratch,
+                                       Register new_value) {
+  lwz(scratch, MemOperand(location));
+
+#if V8_OOL_CONSTANT_POOL
+  if (emit_debug_code()) {
+// Check that the instruction sequence is a load from the constant pool
+#if V8_TARGET_ARCH_PPC64
+    And(scratch, scratch, Operand(kOpcodeMask | (0x1f * B16)));
+    Cmpi(scratch, Operand(ADDI), r0);
+    Check(eq, kTheInstructionShouldBeALi);
+    lwz(scratch, MemOperand(location, kInstrSize));
+#endif
+    ExtractBitMask(scratch, scratch, 0x1f * B16);
+    cmpi(scratch, Operand(kConstantPoolRegister.code()));
+    Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool);
+    // Scratch was clobbered. Restore it.
+    lwz(scratch, MemOperand(location));
+  }
+  // Get the address of the constant and patch it.
+  andi(scratch, scratch, Operand(kImm16Mask));
+  StorePX(new_value, MemOperand(kConstantPoolRegister, scratch));
+#else
+  // This code assumes a FIXED_SEQUENCE for lis/ori
+
+  // At this point scratch is a lis instruction.
+  if (emit_debug_code()) {
+    And(scratch, scratch, Operand(kOpcodeMask | (0x1f * B16)));
+    Cmpi(scratch, Operand(ADDIS), r0);
+    Check(eq, kTheInstructionToPatchShouldBeALis);
+    lwz(scratch, MemOperand(location));
+  }
+
+// insert new high word into lis instruction
+#if V8_TARGET_ARCH_PPC64
+  srdi(ip, new_value, Operand(32));
+  rlwimi(scratch, ip, 16, 16, 31);
+#else
+  rlwimi(scratch, new_value, 16, 16, 31);
+#endif
+
+  stw(scratch, MemOperand(location));
+
+  lwz(scratch, MemOperand(location, kInstrSize));
+  // scratch is now ori.
+  if (emit_debug_code()) {
+    And(scratch, scratch, Operand(kOpcodeMask));
+    Cmpi(scratch, Operand(ORI), r0);
+    Check(eq, kTheInstructionShouldBeAnOri);
+    lwz(scratch, MemOperand(location, kInstrSize));
+  }
+
+// insert new low word into ori instruction
+#if V8_TARGET_ARCH_PPC64
+  rlwimi(scratch, ip, 0, 16, 31);
+#else
+  rlwimi(scratch, new_value, 0, 16, 31);
+#endif
+  stw(scratch, MemOperand(location, kInstrSize));
+
+#if V8_TARGET_ARCH_PPC64
+  if (emit_debug_code()) {
+    lwz(scratch, MemOperand(location, 2 * kInstrSize));
+    // scratch is now sldi.
+    And(scratch, scratch, Operand(kOpcodeMask | kExt5OpcodeMask));
+    Cmpi(scratch, Operand(EXT5 | RLDICR), r0);
+    Check(eq, kTheInstructionShouldBeASldi);
+  }
+
+  lwz(scratch, MemOperand(location, 3 * kInstrSize));
+  // scratch is now ori.
+  if (emit_debug_code()) {
+    And(scratch, scratch, Operand(kOpcodeMask));
+    Cmpi(scratch, Operand(ORIS), r0);
+    Check(eq, kTheInstructionShouldBeAnOris);
+    lwz(scratch, MemOperand(location, 3 * kInstrSize));
+  }
+
+  rlwimi(scratch, new_value, 16, 16, 31);
+  stw(scratch, MemOperand(location, 3 * kInstrSize));
+
+  lwz(scratch, MemOperand(location, 4 * kInstrSize));
+  // scratch is now ori.
+  if (emit_debug_code()) {
+    And(scratch, scratch, Operand(kOpcodeMask));
+    Cmpi(scratch, Operand(ORI), r0);
+    Check(eq, kTheInstructionShouldBeAnOri);
+    lwz(scratch, MemOperand(location, 4 * kInstrSize));
+  }
+  rlwimi(scratch, new_value, 0, 16, 31);
+  stw(scratch, MemOperand(location, 4 * kInstrSize));
+#endif
+
+// Update the I-cache so the new lis and addic can be executed.
+#if V8_TARGET_ARCH_PPC64
+  FlushICache(location, 5 * kInstrSize, scratch);
+#else
+  FlushICache(location, 2 * kInstrSize, scratch);
+#endif
+#endif
+}
+
+
+void MacroAssembler::GetRelocatedValue(Register location, Register result,
+                                       Register scratch) {
+  lwz(result, MemOperand(location));
+
+#if V8_OOL_CONSTANT_POOL
+  if (emit_debug_code()) {
+// Check that the instruction sequence is a load from the constant pool
+#if V8_TARGET_ARCH_PPC64
+    And(result, result, Operand(kOpcodeMask | (0x1f * B16)));
+    Cmpi(result, Operand(ADDI), r0);
+    Check(eq, kTheInstructionShouldBeALi);
+    lwz(result, MemOperand(location, kInstrSize));
+#endif
+    ExtractBitMask(result, result, 0x1f * B16);
+    cmpi(result, Operand(kConstantPoolRegister.code()));
+    Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool);
+    lwz(result, MemOperand(location));
+  }
+  // Get the address of the constant and retrieve it.
+  andi(result, result, Operand(kImm16Mask));
+  LoadPX(result, MemOperand(kConstantPoolRegister, result));
+#else
+  // This code assumes a FIXED_SEQUENCE for lis/ori
+  if (emit_debug_code()) {
+    And(result, result, Operand(kOpcodeMask | (0x1f * B16)));
+    Cmpi(result, Operand(ADDIS), r0);
+    Check(eq, kTheInstructionShouldBeALis);
+    lwz(result, MemOperand(location));
+  }
+
+  // result now holds a lis instruction. Extract the immediate.
+  slwi(result, result, Operand(16));
+
+  lwz(scratch, MemOperand(location, kInstrSize));
+  if (emit_debug_code()) {
+    And(scratch, scratch, Operand(kOpcodeMask));
+    Cmpi(scratch, Operand(ORI), r0);
+    Check(eq, kTheInstructionShouldBeAnOri);
+    lwz(scratch, MemOperand(location, kInstrSize));
+  }
+  // Copy the low 16bits from ori instruction into result
+  rlwimi(result, scratch, 0, 16, 31);
+
+#if V8_TARGET_ARCH_PPC64
+  if (emit_debug_code()) {
+    lwz(scratch, MemOperand(location, 2 * kInstrSize));
+    // scratch is now sldi.
+    And(scratch, scratch, Operand(kOpcodeMask | kExt5OpcodeMask));
+    Cmpi(scratch, Operand(EXT5 | RLDICR), r0);
+    Check(eq, kTheInstructionShouldBeASldi);
+  }
+
+  lwz(scratch, MemOperand(location, 3 * kInstrSize));
+  // scratch is now ori.
+  if (emit_debug_code()) {
+    And(scratch, scratch, Operand(kOpcodeMask));
+    Cmpi(scratch, Operand(ORIS), r0);
+    Check(eq, kTheInstructionShouldBeAnOris);
+    lwz(scratch, MemOperand(location, 3 * kInstrSize));
+  }
+  sldi(result, result, Operand(16));
+  rldimi(result, scratch, 0, 48);
+
+  lwz(scratch, MemOperand(location, 4 * kInstrSize));
+  // scratch is now ori.
+  if (emit_debug_code()) {
+    And(scratch, scratch, Operand(kOpcodeMask));
+    Cmpi(scratch, Operand(ORI), r0);
+    Check(eq, kTheInstructionShouldBeAnOri);
+    lwz(scratch, MemOperand(location, 4 * kInstrSize));
+  }
+  sldi(result, result, Operand(16));
+  rldimi(result, scratch, 0, 48);
+#endif
+#endif
+}
+
+
+void MacroAssembler::CheckPageFlag(
+    Register object,
+    Register scratch,  // scratch may be same register as object
+    int mask, Condition cc, Label* condition_met) {
+  DCHECK(cc == ne || cc == eq);
+  ClearRightImm(scratch, object, Operand(kPageSizeBits));
+  LoadP(scratch, MemOperand(scratch, MemoryChunk::kFlagsOffset));
+
+  And(r0, scratch, Operand(mask), SetRC);
+
+  if (cc == ne) {
+    bne(condition_met, cr0);
+  }
+  if (cc == eq) {
+    beq(condition_met, cr0);
+  }
+}
+
+
+void MacroAssembler::CheckMapDeprecated(Handle<Map> map, Register scratch,
+                                        Label* if_deprecated) {
+  if (map->CanBeDeprecated()) {
+    mov(scratch, Operand(map));
+    lwz(scratch, FieldMemOperand(scratch, Map::kBitField3Offset));
+    ExtractBitMask(scratch, scratch, Map::Deprecated::kMask, SetRC);
+    bne(if_deprecated, cr0);
+  }
+}
+
+
+void MacroAssembler::JumpIfBlack(Register object, Register scratch0,
+                                 Register scratch1, Label* on_black) {
+  HasColor(object, scratch0, scratch1, on_black, 1, 0);  // kBlackBitPattern.
+  DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0);
+}
+
+
+void MacroAssembler::HasColor(Register object, Register bitmap_scratch,
+                              Register mask_scratch, Label* has_color,
+                              int first_bit, int second_bit) {
+  DCHECK(!AreAliased(object, bitmap_scratch, mask_scratch, no_reg));
+
+  GetMarkBits(object, bitmap_scratch, mask_scratch);
+
+  Label other_color, word_boundary;
+  lwz(ip, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
+  // Test the first bit
+  and_(r0, ip, mask_scratch, SetRC);
+  b(first_bit == 1 ? eq : ne, &other_color, cr0);
+  // Shift left 1
+  // May need to load the next cell
+  slwi(mask_scratch, mask_scratch, Operand(1), SetRC);
+  beq(&word_boundary, cr0);
+  // Test the second bit
+  and_(r0, ip, mask_scratch, SetRC);
+  b(second_bit == 1 ? ne : eq, has_color, cr0);
+  b(&other_color);
+
+  bind(&word_boundary);
+  lwz(ip, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize + kIntSize));
+  andi(r0, ip, Operand(1));
+  b(second_bit == 1 ? ne : eq, has_color, cr0);
+  bind(&other_color);
+}
+
+
+// Detect some, but not all, common pointer-free objects.  This is used by the
+// incremental write barrier which doesn't care about oddballs (they are always
+// marked black immediately so this code is not hit).
+void MacroAssembler::JumpIfDataObject(Register value, Register scratch,
+                                      Label* not_data_object) {
+  Label is_data_object;
+  LoadP(scratch, FieldMemOperand(value, HeapObject::kMapOffset));
+  CompareRoot(scratch, Heap::kHeapNumberMapRootIndex);
+  beq(&is_data_object);
+  DCHECK(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1);
+  DCHECK(kNotStringTag == 0x80 && kIsNotStringMask == 0x80);
+  // If it's a string and it's not a cons string then it's an object containing
+  // no GC pointers.
+  lbz(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
+  STATIC_ASSERT((kIsIndirectStringMask | kIsNotStringMask) == 0x81);
+  andi(scratch, scratch, Operand(kIsIndirectStringMask | kIsNotStringMask));
+  bne(not_data_object, cr0);
+  bind(&is_data_object);
+}
+
+
+void MacroAssembler::GetMarkBits(Register addr_reg, Register bitmap_reg,
+                                 Register mask_reg) {
+  DCHECK(!AreAliased(addr_reg, bitmap_reg, mask_reg, no_reg));
+  DCHECK((~Page::kPageAlignmentMask & 0xffff) == 0);
+  lis(r0, Operand((~Page::kPageAlignmentMask >> 16)));
+  and_(bitmap_reg, addr_reg, r0);
+  const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2;
+  ExtractBitRange(mask_reg, addr_reg, kLowBits - 1, kPointerSizeLog2);
+  ExtractBitRange(ip, addr_reg, kPageSizeBits - 1, kLowBits);
+  ShiftLeftImm(ip, ip, Operand(Bitmap::kBytesPerCellLog2));
+  add(bitmap_reg, bitmap_reg, ip);
+  li(ip, Operand(1));
+  slw(mask_reg, ip, mask_reg);
+}
+
+
+void MacroAssembler::EnsureNotWhite(Register value, Register bitmap_scratch,
+                                    Register mask_scratch,
+                                    Register load_scratch,
+                                    Label* value_is_white_and_not_data) {
+  DCHECK(!AreAliased(value, bitmap_scratch, mask_scratch, ip));
+  GetMarkBits(value, bitmap_scratch, mask_scratch);
+
+  // If the value is black or grey we don't need to do anything.
+  DCHECK(strcmp(Marking::kWhiteBitPattern, "00") == 0);
+  DCHECK(strcmp(Marking::kBlackBitPattern, "10") == 0);
+  DCHECK(strcmp(Marking::kGreyBitPattern, "11") == 0);
+  DCHECK(strcmp(Marking::kImpossibleBitPattern, "01") == 0);
+
+  Label done;
+
+  // Since both black and grey have a 1 in the first position and white does
+  // not have a 1 there we only need to check one bit.
+  lwz(load_scratch, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
+  and_(r0, mask_scratch, load_scratch, SetRC);
+  bne(&done, cr0);
+
+  if (emit_debug_code()) {
+    // Check for impossible bit pattern.
+    Label ok;
+    // LSL may overflow, making the check conservative.
+    slwi(r0, mask_scratch, Operand(1));
+    and_(r0, load_scratch, r0, SetRC);
+    beq(&ok, cr0);
+    stop("Impossible marking bit pattern");
+    bind(&ok);
+  }
+
+  // Value is white.  We check whether it is data that doesn't need scanning.
+  // Currently only checks for HeapNumber and non-cons strings.
+  Register map = load_scratch;     // Holds map while checking type.
+  Register length = load_scratch;  // Holds length of object after testing type.
+  Label is_data_object, maybe_string_object, is_string_object, is_encoded;
+#if V8_TARGET_ARCH_PPC64
+  Label length_computed;
+#endif
+
+
+  // Check for heap-number
+  LoadP(map, FieldMemOperand(value, HeapObject::kMapOffset));
+  CompareRoot(map, Heap::kHeapNumberMapRootIndex);
+  bne(&maybe_string_object);
+  li(length, Operand(HeapNumber::kSize));
+  b(&is_data_object);
+  bind(&maybe_string_object);
+
+  // Check for strings.
+  DCHECK(kIsIndirectStringTag == 1 && kIsIndirectStringMask == 1);
+  DCHECK(kNotStringTag == 0x80 && kIsNotStringMask == 0x80);
+  // If it's a string and it's not a cons string then it's an object containing
+  // no GC pointers.
+  Register instance_type = load_scratch;
+  lbz(instance_type, FieldMemOperand(map, Map::kInstanceTypeOffset));
+  andi(r0, instance_type, Operand(kIsIndirectStringMask | kIsNotStringMask));
+  bne(value_is_white_and_not_data, cr0);
+  // It's a non-indirect (non-cons and non-slice) string.
+  // If it's external, the length is just ExternalString::kSize.
+  // Otherwise it's String::kHeaderSize + string->length() * (1 or 2).
+  // External strings are the only ones with the kExternalStringTag bit
+  // set.
+  DCHECK_EQ(0, kSeqStringTag & kExternalStringTag);
+  DCHECK_EQ(0, kConsStringTag & kExternalStringTag);
+  andi(r0, instance_type, Operand(kExternalStringTag));
+  beq(&is_string_object, cr0);
+  li(length, Operand(ExternalString::kSize));
+  b(&is_data_object);
+  bind(&is_string_object);
+
+  // Sequential string, either Latin1 or UC16.
+  // For Latin1 (char-size of 1) we untag the smi to get the length.
+  // For UC16 (char-size of 2):
+  //   - (32-bit) we just leave the smi tag in place, thereby getting
+  //              the length multiplied by 2.
+  //   - (64-bit) we compute the offset in the 2-byte array
+  DCHECK(kOneByteStringTag == 4 && kStringEncodingMask == 4);
+  LoadP(ip, FieldMemOperand(value, String::kLengthOffset));
+  andi(r0, instance_type, Operand(kStringEncodingMask));
+  beq(&is_encoded, cr0);
+  SmiUntag(ip);
+#if V8_TARGET_ARCH_PPC64
+  b(&length_computed);
+#endif
+  bind(&is_encoded);
+#if V8_TARGET_ARCH_PPC64
+  SmiToShortArrayOffset(ip, ip);
+  bind(&length_computed);
+#else
+  DCHECK(kSmiShift == 1);
+#endif
+  addi(length, ip, Operand(SeqString::kHeaderSize + kObjectAlignmentMask));
+  li(r0, Operand(~kObjectAlignmentMask));
+  and_(length, length, r0);
+
+  bind(&is_data_object);
+  // Value is a data object, and it is white.  Mark it black.  Since we know
+  // that the object is white we can make it black by flipping one bit.
+  lwz(ip, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
+  orx(ip, ip, mask_scratch);
+  stw(ip, MemOperand(bitmap_scratch, MemoryChunk::kHeaderSize));
+
+  mov(ip, Operand(~Page::kPageAlignmentMask));
+  and_(bitmap_scratch, bitmap_scratch, ip);
+  lwz(ip, MemOperand(bitmap_scratch, MemoryChunk::kLiveBytesOffset));
+  add(ip, ip, length);
+  stw(ip, MemOperand(bitmap_scratch, MemoryChunk::kLiveBytesOffset));
+
+  bind(&done);
+}
+
+
+// Saturate a value into 8-bit unsigned integer
+//   if input_value < 0, output_value is 0
+//   if input_value > 255, output_value is 255
+//   otherwise output_value is the input_value
+void MacroAssembler::ClampUint8(Register output_reg, Register input_reg) {
+  Label done, negative_label, overflow_label;
+  int satval = (1 << 8) - 1;
+
+  cmpi(input_reg, Operand::Zero());
+  blt(&negative_label);
+
+  cmpi(input_reg, Operand(satval));
+  bgt(&overflow_label);
+  if (!output_reg.is(input_reg)) {
+    mr(output_reg, input_reg);
+  }
+  b(&done);
+
+  bind(&negative_label);
+  li(output_reg, Operand::Zero());  // set to 0 if negative
+  b(&done);
+
+
+  bind(&overflow_label);  // set to satval if > satval
+  li(output_reg, Operand(satval));
+
+  bind(&done);
+}
+
+
+void MacroAssembler::SetRoundingMode(FPRoundingMode RN) { mtfsfi(7, RN); }
+
+
+void MacroAssembler::ResetRoundingMode() {
+  mtfsfi(7, kRoundToNearest);  // reset (default is kRoundToNearest)
+}
+
+
+void MacroAssembler::ClampDoubleToUint8(Register result_reg,
+                                        DoubleRegister input_reg,
+                                        DoubleRegister double_scratch) {
+  Label above_zero;
+  Label done;
+  Label in_bounds;
+
+  LoadDoubleLiteral(double_scratch, 0.0, result_reg);
+  fcmpu(input_reg, double_scratch);
+  bgt(&above_zero);
+
+  // Double value is less than zero, NaN or Inf, return 0.
+  LoadIntLiteral(result_reg, 0);
+  b(&done);
+
+  // Double value is >= 255, return 255.
+  bind(&above_zero);
+  LoadDoubleLiteral(double_scratch, 255.0, result_reg);
+  fcmpu(input_reg, double_scratch);
+  ble(&in_bounds);
+  LoadIntLiteral(result_reg, 255);
+  b(&done);
+
+  // In 0-255 range, round and truncate.
+  bind(&in_bounds);
+
+  // round to nearest (default rounding mode)
+  fctiw(double_scratch, input_reg);
+  MovDoubleLowToInt(result_reg, double_scratch);
+  bind(&done);
+}
+
+
+void MacroAssembler::LoadInstanceDescriptors(Register map,
+                                             Register descriptors) {
+  LoadP(descriptors, FieldMemOperand(map, Map::kDescriptorsOffset));
+}
+
+
+void MacroAssembler::NumberOfOwnDescriptors(Register dst, Register map) {
+  lwz(dst, FieldMemOperand(map, Map::kBitField3Offset));
+  DecodeField<Map::NumberOfOwnDescriptorsBits>(dst);
+}
+
+
+void MacroAssembler::EnumLength(Register dst, Register map) {
+  STATIC_ASSERT(Map::EnumLengthBits::kShift == 0);
+  lwz(dst, FieldMemOperand(map, Map::kBitField3Offset));
+  ExtractBitMask(dst, dst, Map::EnumLengthBits::kMask);
+  SmiTag(dst);
+}
+
+
+void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
+  Register empty_fixed_array_value = r9;
+  LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
+  Label next, start;
+  mr(r5, r3);
+
+  // Check if the enum length field is properly initialized, indicating that
+  // there is an enum cache.
+  LoadP(r4, FieldMemOperand(r5, HeapObject::kMapOffset));
+
+  EnumLength(r6, r4);
+  CmpSmiLiteral(r6, Smi::FromInt(kInvalidEnumCacheSentinel), r0);
+  beq(call_runtime);
+
+  b(&start);
+
+  bind(&next);
+  LoadP(r4, FieldMemOperand(r5, HeapObject::kMapOffset));
+
+  // For all objects but the receiver, check that the cache is empty.
+  EnumLength(r6, r4);
+  CmpSmiLiteral(r6, Smi::FromInt(0), r0);
+  bne(call_runtime);
+
+  bind(&start);
+
+  // Check that there are no elements. Register r5 contains the current JS
+  // object we've reached through the prototype chain.
+  Label no_elements;
+  LoadP(r5, FieldMemOperand(r5, JSObject::kElementsOffset));
+  cmp(r5, empty_fixed_array_value);
+  beq(&no_elements);
+
+  // Second chance, the object may be using the empty slow element dictionary.
+  CompareRoot(r5, Heap::kEmptySlowElementDictionaryRootIndex);
+  bne(call_runtime);
+
+  bind(&no_elements);
+  LoadP(r5, FieldMemOperand(r4, Map::kPrototypeOffset));
+  cmp(r5, null_value);
+  bne(&next);
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// New MacroAssembler Interfaces added for PPC
+//
+////////////////////////////////////////////////////////////////////////////////
+void MacroAssembler::LoadIntLiteral(Register dst, int value) {
+  mov(dst, Operand(value));
+}
+
+
+void MacroAssembler::LoadSmiLiteral(Register dst, Smi* smi) {
+  mov(dst, Operand(smi));
+}
+
+
+void MacroAssembler::LoadDoubleLiteral(DoubleRegister result, double value,
+                                       Register scratch) {
+#if V8_OOL_CONSTANT_POOL
+  // TODO(mbrandy): enable extended constant pool usage for doubles.
+  //                See ARM commit e27ab337 for a reference.
+  if (is_ool_constant_pool_available() && !is_constant_pool_full()) {
+    RelocInfo rinfo(pc_, value);
+    ConstantPoolAddEntry(rinfo);
+#if V8_TARGET_ARCH_PPC64
+    // We use 2 instruction sequence here for consistency with mov.
+    li(scratch, Operand::Zero());
+    lfdx(result, MemOperand(kConstantPoolRegister, scratch));
+#else
+    lfd(result, MemOperand(kConstantPoolRegister, 0));
+#endif
+    return;
+  }
+#endif
+
+  // avoid gcc strict aliasing error using union cast
+  union {
+    double dval;
+#if V8_TARGET_ARCH_PPC64
+    intptr_t ival;
+#else
+    intptr_t ival[2];
+#endif
+  } litVal;
+
+  litVal.dval = value;
+
+#if V8_TARGET_ARCH_PPC64
+  if (CpuFeatures::IsSupported(FPR_GPR_MOV)) {
+    mov(scratch, Operand(litVal.ival));
+    mtfprd(result, scratch);
+    return;
+  }
+#endif
+
+  addi(sp, sp, Operand(-kDoubleSize));
+#if V8_TARGET_ARCH_PPC64
+  mov(scratch, Operand(litVal.ival));
+  std(scratch, MemOperand(sp));
+#else
+  LoadIntLiteral(scratch, litVal.ival[0]);
+  stw(scratch, MemOperand(sp, 0));
+  LoadIntLiteral(scratch, litVal.ival[1]);
+  stw(scratch, MemOperand(sp, 4));
+#endif
+  nop(GROUP_ENDING_NOP);  // LHS/RAW optimization
+  lfd(result, MemOperand(sp, 0));
+  addi(sp, sp, Operand(kDoubleSize));
+}
+
+
+void MacroAssembler::MovIntToDouble(DoubleRegister dst, Register src,
+                                    Register scratch) {
+// sign-extend src to 64-bit
+#if V8_TARGET_ARCH_PPC64
+  if (CpuFeatures::IsSupported(FPR_GPR_MOV)) {
+    mtfprwa(dst, src);
+    return;
+  }
+#endif
+
+  DCHECK(!src.is(scratch));
+  subi(sp, sp, Operand(kDoubleSize));
+#if V8_TARGET_ARCH_PPC64
+  extsw(scratch, src);
+  std(scratch, MemOperand(sp, 0));
+#else
+  srawi(scratch, src, 31);
+  stw(scratch, MemOperand(sp, Register::kExponentOffset));
+  stw(src, MemOperand(sp, Register::kMantissaOffset));
+#endif
+  nop(GROUP_ENDING_NOP);  // LHS/RAW optimization
+  lfd(dst, MemOperand(sp, 0));
+  addi(sp, sp, Operand(kDoubleSize));
+}
+
+
+void MacroAssembler::MovUnsignedIntToDouble(DoubleRegister dst, Register src,
+                                            Register scratch) {
+// zero-extend src to 64-bit
+#if V8_TARGET_ARCH_PPC64
+  if (CpuFeatures::IsSupported(FPR_GPR_MOV)) {
+    mtfprwz(dst, src);
+    return;
+  }
+#endif
+
+  DCHECK(!src.is(scratch));
+  subi(sp, sp, Operand(kDoubleSize));
+#if V8_TARGET_ARCH_PPC64
+  clrldi(scratch, src, Operand(32));
+  std(scratch, MemOperand(sp, 0));
+#else
+  li(scratch, Operand::Zero());
+  stw(scratch, MemOperand(sp, Register::kExponentOffset));
+  stw(src, MemOperand(sp, Register::kMantissaOffset));
+#endif
+  nop(GROUP_ENDING_NOP);  // LHS/RAW optimization
+  lfd(dst, MemOperand(sp, 0));
+  addi(sp, sp, Operand(kDoubleSize));
+}
+
+
+void MacroAssembler::MovInt64ToDouble(DoubleRegister dst,
+#if !V8_TARGET_ARCH_PPC64
+                                      Register src_hi,
+#endif
+                                      Register src) {
+#if V8_TARGET_ARCH_PPC64
+  if (CpuFeatures::IsSupported(FPR_GPR_MOV)) {
+    mtfprd(dst, src);
+    return;
+  }
+#endif
+
+  subi(sp, sp, Operand(kDoubleSize));
+#if V8_TARGET_ARCH_PPC64
+  std(src, MemOperand(sp, 0));
+#else
+  stw(src_hi, MemOperand(sp, Register::kExponentOffset));
+  stw(src, MemOperand(sp, Register::kMantissaOffset));
+#endif
+  nop(GROUP_ENDING_NOP);  // LHS/RAW optimization
+  lfd(dst, MemOperand(sp, 0));
+  addi(sp, sp, Operand(kDoubleSize));
+}
+
+
+#if V8_TARGET_ARCH_PPC64
+void MacroAssembler::MovInt64ComponentsToDouble(DoubleRegister dst,
+                                                Register src_hi,
+                                                Register src_lo,
+                                                Register scratch) {
+  if (CpuFeatures::IsSupported(FPR_GPR_MOV)) {
+    sldi(scratch, src_hi, Operand(32));
+    rldimi(scratch, src_lo, 0, 32);
+    mtfprd(dst, scratch);
+    return;
+  }
+
+  subi(sp, sp, Operand(kDoubleSize));
+  stw(src_hi, MemOperand(sp, Register::kExponentOffset));
+  stw(src_lo, MemOperand(sp, Register::kMantissaOffset));
+  nop(GROUP_ENDING_NOP);  // LHS/RAW optimization
+  lfd(dst, MemOperand(sp));
+  addi(sp, sp, Operand(kDoubleSize));
+}
+#endif
+
+
+void MacroAssembler::MovDoubleLowToInt(Register dst, DoubleRegister src) {
+#if V8_TARGET_ARCH_PPC64
+  if (CpuFeatures::IsSupported(FPR_GPR_MOV)) {
+    mffprwz(dst, src);
+    return;
+  }
+#endif
+
+  subi(sp, sp, Operand(kDoubleSize));
+  stfd(src, MemOperand(sp));
+  nop(GROUP_ENDING_NOP);  // LHS/RAW optimization
+  lwz(dst, MemOperand(sp, Register::kMantissaOffset));
+  addi(sp, sp, Operand(kDoubleSize));
+}
+
+
+void MacroAssembler::MovDoubleHighToInt(Register dst, DoubleRegister src) {
+#if V8_TARGET_ARCH_PPC64
+  if (CpuFeatures::IsSupported(FPR_GPR_MOV)) {
+    mffprd(dst, src);
+    srdi(dst, dst, Operand(32));
+    return;
+  }
+#endif
+
+  subi(sp, sp, Operand(kDoubleSize));
+  stfd(src, MemOperand(sp));
+  nop(GROUP_ENDING_NOP);  // LHS/RAW optimization
+  lwz(dst, MemOperand(sp, Register::kExponentOffset));
+  addi(sp, sp, Operand(kDoubleSize));
+}
+
+
+void MacroAssembler::MovDoubleToInt64(
+#if !V8_TARGET_ARCH_PPC64
+    Register dst_hi,
+#endif
+    Register dst, DoubleRegister src) {
+#if V8_TARGET_ARCH_PPC64
+  if (CpuFeatures::IsSupported(FPR_GPR_MOV)) {
+    mffprd(dst, src);
+    return;
+  }
+#endif
+
+  subi(sp, sp, Operand(kDoubleSize));
+  stfd(src, MemOperand(sp));
+  nop(GROUP_ENDING_NOP);  // LHS/RAW optimization
+#if V8_TARGET_ARCH_PPC64
+  ld(dst, MemOperand(sp, 0));
+#else
+  lwz(dst_hi, MemOperand(sp, Register::kExponentOffset));
+  lwz(dst, MemOperand(sp, Register::kMantissaOffset));
+#endif
+  addi(sp, sp, Operand(kDoubleSize));
+}
+
+
+void MacroAssembler::Add(Register dst, Register src, intptr_t value,
+                         Register scratch) {
+  if (is_int16(value)) {
+    addi(dst, src, Operand(value));
+  } else {
+    mov(scratch, Operand(value));
+    add(dst, src, scratch);
+  }
+}
+
+
+void MacroAssembler::Cmpi(Register src1, const Operand& src2, Register scratch,
+                          CRegister cr) {
+  intptr_t value = src2.immediate();
+  if (is_int16(value)) {
+    cmpi(src1, src2, cr);
+  } else {
+    mov(scratch, src2);
+    cmp(src1, scratch, cr);
+  }
+}
+
+
+void MacroAssembler::Cmpli(Register src1, const Operand& src2, Register scratch,
+                           CRegister cr) {
+  intptr_t value = src2.immediate();
+  if (is_uint16(value)) {
+    cmpli(src1, src2, cr);
+  } else {
+    mov(scratch, src2);
+    cmpl(src1, scratch, cr);
+  }
+}
+
+
+void MacroAssembler::Cmpwi(Register src1, const Operand& src2, Register scratch,
+                           CRegister cr) {
+  intptr_t value = src2.immediate();
+  if (is_int16(value)) {
+    cmpwi(src1, src2, cr);
+  } else {
+    mov(scratch, src2);
+    cmpw(src1, scratch, cr);
+  }
+}
+
+
+void MacroAssembler::Cmplwi(Register src1, const Operand& src2,
+                            Register scratch, CRegister cr) {
+  intptr_t value = src2.immediate();
+  if (is_uint16(value)) {
+    cmplwi(src1, src2, cr);
+  } else {
+    mov(scratch, src2);
+    cmplw(src1, scratch, cr);
+  }
+}
+
+
+void MacroAssembler::And(Register ra, Register rs, const Operand& rb,
+                         RCBit rc) {
+  if (rb.is_reg()) {
+    and_(ra, rs, rb.rm(), rc);
+  } else {
+    if (is_uint16(rb.imm_) && RelocInfo::IsNone(rb.rmode_) && rc == SetRC) {
+      andi(ra, rs, rb);
+    } else {
+      // mov handles the relocation.
+      DCHECK(!rs.is(r0));
+      mov(r0, rb);
+      and_(ra, rs, r0, rc);
+    }
+  }
+}
+
+
+void MacroAssembler::Or(Register ra, Register rs, const Operand& rb, RCBit rc) {
+  if (rb.is_reg()) {
+    orx(ra, rs, rb.rm(), rc);
+  } else {
+    if (is_uint16(rb.imm_) && RelocInfo::IsNone(rb.rmode_) && rc == LeaveRC) {
+      ori(ra, rs, rb);
+    } else {
+      // mov handles the relocation.
+      DCHECK(!rs.is(r0));
+      mov(r0, rb);
+      orx(ra, rs, r0, rc);
+    }
+  }
+}
+
+
+void MacroAssembler::Xor(Register ra, Register rs, const Operand& rb,
+                         RCBit rc) {
+  if (rb.is_reg()) {
+    xor_(ra, rs, rb.rm(), rc);
+  } else {
+    if (is_uint16(rb.imm_) && RelocInfo::IsNone(rb.rmode_) && rc == LeaveRC) {
+      xori(ra, rs, rb);
+    } else {
+      // mov handles the relocation.
+      DCHECK(!rs.is(r0));
+      mov(r0, rb);
+      xor_(ra, rs, r0, rc);
+    }
+  }
+}
+
+
+void MacroAssembler::CmpSmiLiteral(Register src1, Smi* smi, Register scratch,
+                                   CRegister cr) {
+#if V8_TARGET_ARCH_PPC64
+  LoadSmiLiteral(scratch, smi);
+  cmp(src1, scratch, cr);
+#else
+  Cmpi(src1, Operand(smi), scratch, cr);
+#endif
+}
+
+
+void MacroAssembler::CmplSmiLiteral(Register src1, Smi* smi, Register scratch,
+                                    CRegister cr) {
+#if V8_TARGET_ARCH_PPC64
+  LoadSmiLiteral(scratch, smi);
+  cmpl(src1, scratch, cr);
+#else
+  Cmpli(src1, Operand(smi), scratch, cr);
+#endif
+}
+
+
+void MacroAssembler::AddSmiLiteral(Register dst, Register src, Smi* smi,
+                                   Register scratch) {
+#if V8_TARGET_ARCH_PPC64
+  LoadSmiLiteral(scratch, smi);
+  add(dst, src, scratch);
+#else
+  Add(dst, src, reinterpret_cast<intptr_t>(smi), scratch);
+#endif
+}
+
+
+void MacroAssembler::SubSmiLiteral(Register dst, Register src, Smi* smi,
+                                   Register scratch) {
+#if V8_TARGET_ARCH_PPC64
+  LoadSmiLiteral(scratch, smi);
+  sub(dst, src, scratch);
+#else
+  Add(dst, src, -(reinterpret_cast<intptr_t>(smi)), scratch);
+#endif
+}
+
+
+void MacroAssembler::AndSmiLiteral(Register dst, Register src, Smi* smi,
+                                   Register scratch, RCBit rc) {
+#if V8_TARGET_ARCH_PPC64
+  LoadSmiLiteral(scratch, smi);
+  and_(dst, src, scratch, rc);
+#else
+  And(dst, src, Operand(smi), rc);
+#endif
+}
+
+
+// Load a "pointer" sized value from the memory location
+void MacroAssembler::LoadP(Register dst, const MemOperand& mem,
+                           Register scratch) {
+  int offset = mem.offset();
+
+  if (!scratch.is(no_reg) && !is_int16(offset)) {
+    /* cannot use d-form */
+    LoadIntLiteral(scratch, offset);
+#if V8_TARGET_ARCH_PPC64
+    ldx(dst, MemOperand(mem.ra(), scratch));
+#else
+    lwzx(dst, MemOperand(mem.ra(), scratch));
+#endif
+  } else {
+#if V8_TARGET_ARCH_PPC64
+    int misaligned = (offset & 3);
+    if (misaligned) {
+      // adjust base to conform to offset alignment requirements
+      // Todo: enhance to use scratch if dst is unsuitable
+      DCHECK(!dst.is(r0));
+      addi(dst, mem.ra(), Operand((offset & 3) - 4));
+      ld(dst, MemOperand(dst, (offset & ~3) + 4));
+    } else {
+      ld(dst, mem);
+    }
+#else
+    lwz(dst, mem);
+#endif
+  }
+}
+
+
+// Store a "pointer" sized value to the memory location
+void MacroAssembler::StoreP(Register src, const MemOperand& mem,
+                            Register scratch) {
+  int offset = mem.offset();
+
+  if (!scratch.is(no_reg) && !is_int16(offset)) {
+    /* cannot use d-form */
+    LoadIntLiteral(scratch, offset);
+#if V8_TARGET_ARCH_PPC64
+    stdx(src, MemOperand(mem.ra(), scratch));
+#else
+    stwx(src, MemOperand(mem.ra(), scratch));
+#endif
+  } else {
+#if V8_TARGET_ARCH_PPC64
+    int misaligned = (offset & 3);
+    if (misaligned) {
+      // adjust base to conform to offset alignment requirements
+      // a suitable scratch is required here
+      DCHECK(!scratch.is(no_reg));
+      if (scratch.is(r0)) {
+        LoadIntLiteral(scratch, offset);
+        stdx(src, MemOperand(mem.ra(), scratch));
+      } else {
+        addi(scratch, mem.ra(), Operand((offset & 3) - 4));
+        std(src, MemOperand(scratch, (offset & ~3) + 4));
+      }
+    } else {
+      std(src, mem);
+    }
+#else
+    stw(src, mem);
+#endif
+  }
+}
+
+void MacroAssembler::LoadWordArith(Register dst, const MemOperand& mem,
+                                   Register scratch) {
+  int offset = mem.offset();
+
+  if (!scratch.is(no_reg) && !is_int16(offset)) {
+    /* cannot use d-form */
+    LoadIntLiteral(scratch, offset);
+#if V8_TARGET_ARCH_PPC64
+    // lwax(dst, MemOperand(mem.ra(), scratch));
+    DCHECK(0);  // lwax not yet implemented
+#else
+    lwzx(dst, MemOperand(mem.ra(), scratch));
+#endif
+  } else {
+#if V8_TARGET_ARCH_PPC64
+    int misaligned = (offset & 3);
+    if (misaligned) {
+      // adjust base to conform to offset alignment requirements
+      // Todo: enhance to use scratch if dst is unsuitable
+      DCHECK(!dst.is(r0));
+      addi(dst, mem.ra(), Operand((offset & 3) - 4));
+      lwa(dst, MemOperand(dst, (offset & ~3) + 4));
+    } else {
+      lwa(dst, mem);
+    }
+#else
+    lwz(dst, mem);
+#endif
+  }
+}
+
+
+// Variable length depending on whether offset fits into immediate field
+// MemOperand currently only supports d-form
+void MacroAssembler::LoadWord(Register dst, const MemOperand& mem,
+                              Register scratch) {
+  Register base = mem.ra();
+  int offset = mem.offset();
+
+  if (!is_int16(offset)) {
+    LoadIntLiteral(scratch, offset);
+    lwzx(dst, MemOperand(base, scratch));
+  } else {
+    lwz(dst, mem);
+  }
+}
+
+
+// Variable length depending on whether offset fits into immediate field
+// MemOperand current only supports d-form
+void MacroAssembler::StoreWord(Register src, const MemOperand& mem,
+                               Register scratch) {
+  Register base = mem.ra();
+  int offset = mem.offset();
+
+  if (!is_int16(offset)) {
+    LoadIntLiteral(scratch, offset);
+    stwx(src, MemOperand(base, scratch));
+  } else {
+    stw(src, mem);
+  }
+}
+
+
+// Variable length depending on whether offset fits into immediate field
+// MemOperand currently only supports d-form
+void MacroAssembler::LoadHalfWord(Register dst, const MemOperand& mem,
+                                  Register scratch) {
+  Register base = mem.ra();
+  int offset = mem.offset();
+
+  if (!is_int16(offset)) {
+    LoadIntLiteral(scratch, offset);
+    lhzx(dst, MemOperand(base, scratch));
+  } else {
+    lhz(dst, mem);
+  }
+}
+
+
+// Variable length depending on whether offset fits into immediate field
+// MemOperand current only supports d-form
+void MacroAssembler::StoreHalfWord(Register src, const MemOperand& mem,
+                                   Register scratch) {
+  Register base = mem.ra();
+  int offset = mem.offset();
+
+  if (!is_int16(offset)) {
+    LoadIntLiteral(scratch, offset);
+    sthx(src, MemOperand(base, scratch));
+  } else {
+    sth(src, mem);
+  }
+}
+
+
+// Variable length depending on whether offset fits into immediate field
+// MemOperand currently only supports d-form
+void MacroAssembler::LoadByte(Register dst, const MemOperand& mem,
+                              Register scratch) {
+  Register base = mem.ra();
+  int offset = mem.offset();
+
+  if (!is_int16(offset)) {
+    LoadIntLiteral(scratch, offset);
+    lbzx(dst, MemOperand(base, scratch));
+  } else {
+    lbz(dst, mem);
+  }
+}
+
+
+// Variable length depending on whether offset fits into immediate field
+// MemOperand current only supports d-form
+void MacroAssembler::StoreByte(Register src, const MemOperand& mem,
+                               Register scratch) {
+  Register base = mem.ra();
+  int offset = mem.offset();
+
+  if (!is_int16(offset)) {
+    LoadIntLiteral(scratch, offset);
+    stbx(src, MemOperand(base, scratch));
+  } else {
+    stb(src, mem);
+  }
+}
+
+
+void MacroAssembler::LoadRepresentation(Register dst, const MemOperand& mem,
+                                        Representation r, Register scratch) {
+  DCHECK(!r.IsDouble());
+  if (r.IsInteger8()) {
+    LoadByte(dst, mem, scratch);
+    extsb(dst, dst);
+  } else if (r.IsUInteger8()) {
+    LoadByte(dst, mem, scratch);
+  } else if (r.IsInteger16()) {
+    LoadHalfWord(dst, mem, scratch);
+    extsh(dst, dst);
+  } else if (r.IsUInteger16()) {
+    LoadHalfWord(dst, mem, scratch);
+#if V8_TARGET_ARCH_PPC64
+  } else if (r.IsInteger32()) {
+    LoadWord(dst, mem, scratch);
+#endif
+  } else {
+    LoadP(dst, mem, scratch);
+  }
+}
+
+
+void MacroAssembler::StoreRepresentation(Register src, const MemOperand& mem,
+                                         Representation r, Register scratch) {
+  DCHECK(!r.IsDouble());
+  if (r.IsInteger8() || r.IsUInteger8()) {
+    StoreByte(src, mem, scratch);
+  } else if (r.IsInteger16() || r.IsUInteger16()) {
+    StoreHalfWord(src, mem, scratch);
+#if V8_TARGET_ARCH_PPC64
+  } else if (r.IsInteger32()) {
+    StoreWord(src, mem, scratch);
+#endif
+  } else {
+    if (r.IsHeapObject()) {
+      AssertNotSmi(src);
+    } else if (r.IsSmi()) {
+      AssertSmi(src);
+    }
+    StoreP(src, mem, scratch);
+  }
+}
+
+
+void MacroAssembler::TestJSArrayForAllocationMemento(Register receiver_reg,
+                                                     Register scratch_reg,
+                                                     Label* no_memento_found) {
+  ExternalReference new_space_start =
+      ExternalReference::new_space_start(isolate());
+  ExternalReference new_space_allocation_top =
+      ExternalReference::new_space_allocation_top_address(isolate());
+  addi(scratch_reg, receiver_reg,
+       Operand(JSArray::kSize + AllocationMemento::kSize - kHeapObjectTag));
+  Cmpi(scratch_reg, Operand(new_space_start), r0);
+  blt(no_memento_found);
+  mov(ip, Operand(new_space_allocation_top));
+  LoadP(ip, MemOperand(ip));
+  cmp(scratch_reg, ip);
+  bgt(no_memento_found);
+  LoadP(scratch_reg, MemOperand(scratch_reg, -AllocationMemento::kSize));
+  Cmpi(scratch_reg, Operand(isolate()->factory()->allocation_memento_map()),
+       r0);
+}
+
+
+Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2, Register reg3,
+                                   Register reg4, Register reg5,
+                                   Register reg6) {
+  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();
+
+  for (int i = 0; i < Register::NumAllocatableRegisters(); i++) {
+    Register candidate = Register::FromAllocationIndex(i);
+    if (regs & candidate.bit()) continue;
+    return candidate;
+  }
+  UNREACHABLE();
+  return no_reg;
+}
+
+
+void MacroAssembler::JumpIfDictionaryInPrototypeChain(Register object,
+                                                      Register scratch0,
+                                                      Register scratch1,
+                                                      Label* found) {
+  DCHECK(!scratch1.is(scratch0));
+  Factory* factory = isolate()->factory();
+  Register current = scratch0;
+  Label loop_again;
+
+  // scratch contained elements pointer.
+  mr(current, object);
+
+  // Loop based on the map going up the prototype chain.
+  bind(&loop_again);
+  LoadP(current, FieldMemOperand(current, HeapObject::kMapOffset));
+  lbz(scratch1, FieldMemOperand(current, Map::kBitField2Offset));
+  DecodeField<Map::ElementsKindBits>(scratch1);
+  cmpi(scratch1, Operand(DICTIONARY_ELEMENTS));
+  beq(found);
+  LoadP(current, FieldMemOperand(current, Map::kPrototypeOffset));
+  Cmpi(current, Operand(factory->null_value()), r0);
+  bne(&loop_again);
+}
+
+
+#ifdef DEBUG
+bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4,
+                Register reg5, Register reg6, Register reg7, Register reg8) {
+  int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + reg3.is_valid() +
+                        reg4.is_valid() + reg5.is_valid() + reg6.is_valid() +
+                        reg7.is_valid() + reg8.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();
+  if (reg7.is_valid()) regs |= reg7.bit();
+  if (reg8.is_valid()) regs |= reg8.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,
+                         FlushICache flush_cache)
+    : address_(address),
+      size_(instructions * Assembler::kInstrSize),
+      masm_(NULL, address, size_ + Assembler::kGap),
+      flush_cache_(flush_cache) {
+  // 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.
+  DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
+}
+
+
+CodePatcher::~CodePatcher() {
+  // Indicate that code has changed.
+  if (flush_cache_ == FLUSH) {
+    CpuFeatures::FlushICache(address_, size_);
+  }
+
+  // Check that the code was patched as expected.
+  DCHECK(masm_.pc_ == address_ + size_);
+  DCHECK(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
+}
+
+
+void CodePatcher::Emit(Instr instr) { masm()->emit(instr); }
+
+
+void CodePatcher::EmitCondition(Condition cond) {
+  Instr instr = Assembler::instr_at(masm_.pc_);
+  switch (cond) {
+    case eq:
+      instr = (instr & ~kCondMask) | BT;
+      break;
+    case ne:
+      instr = (instr & ~kCondMask) | BF;
+      break;
+    default:
+      UNIMPLEMENTED();
+  }
+  masm_.emit(instr);
+}
+
+
+void MacroAssembler::TruncatingDiv(Register result, Register dividend,
+                                   int32_t divisor) {
+  DCHECK(!dividend.is(result));
+  DCHECK(!dividend.is(r0));
+  DCHECK(!result.is(r0));
+  base::MagicNumbersForDivision<uint32_t> mag =
+      base::SignedDivisionByConstant(static_cast<uint32_t>(divisor));
+  mov(r0, Operand(mag.multiplier));
+  mulhw(result, dividend, r0);
+  bool neg = (mag.multiplier & (static_cast<uint32_t>(1) << 31)) != 0;
+  if (divisor > 0 && neg) {
+    add(result, result, dividend);
+  }
+  if (divisor < 0 && !neg && mag.multiplier > 0) {
+    sub(result, result, dividend);
+  }
+  if (mag.shift > 0) srawi(result, result, mag.shift);
+  ExtractBit(r0, dividend, 31);
+  add(result, result, r0);
+}
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/macro-assembler-ppc.h b/src/ppc/macro-assembler-ppc.h
new file mode 100644
index 0000000..8f1aeab
--- /dev/null
+++ b/src/ppc/macro-assembler-ppc.h
@@ -0,0 +1,1554 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_PPC_MACRO_ASSEMBLER_PPC_H_
+#define V8_PPC_MACRO_ASSEMBLER_PPC_H_
+
+#include "src/assembler.h"
+#include "src/bailout-reason.h"
+#include "src/frames.h"
+#include "src/globals.h"
+
+namespace v8 {
+namespace internal {
+
+// ----------------------------------------------------------------------------
+// Static helper functions
+
+// Generate a MemOperand for loading a field from an object.
+inline MemOperand FieldMemOperand(Register object, int offset) {
+  return MemOperand(object, offset - kHeapObjectTag);
+}
+
+
+// Flags used for AllocateHeapNumber
+enum TaggingMode {
+  // Tag the result.
+  TAG_RESULT,
+  // Don't tag
+  DONT_TAG_RESULT
+};
+
+
+enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
+enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
+enum PointersToHereCheck {
+  kPointersToHereMaybeInteresting,
+  kPointersToHereAreAlwaysInteresting
+};
+enum LinkRegisterStatus { kLRHasNotBeenSaved, kLRHasBeenSaved };
+
+
+Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2 = no_reg,
+                                   Register reg3 = no_reg,
+                                   Register reg4 = no_reg,
+                                   Register reg5 = no_reg,
+                                   Register reg6 = no_reg);
+
+
+#ifdef DEBUG
+bool AreAliased(Register reg1, Register reg2, Register reg3 = no_reg,
+                Register reg4 = no_reg, Register reg5 = no_reg,
+                Register reg6 = no_reg, Register reg7 = no_reg,
+                Register reg8 = no_reg);
+#endif
+
+// These exist to provide portability between 32 and 64bit
+#if V8_TARGET_ARCH_PPC64
+#define LoadPU ldu
+#define LoadPX ldx
+#define LoadPUX ldux
+#define StorePU stdu
+#define StorePX stdx
+#define StorePUX stdux
+#define ShiftLeftImm sldi
+#define ShiftRightImm srdi
+#define ClearLeftImm clrldi
+#define ClearRightImm clrrdi
+#define ShiftRightArithImm sradi
+#define ShiftLeft_ sld
+#define ShiftRight_ srd
+#define ShiftRightArith srad
+#define Mul mulld
+#define Div divd
+#else
+#define LoadPU lwzu
+#define LoadPX lwzx
+#define LoadPUX lwzux
+#define StorePU stwu
+#define StorePX stwx
+#define StorePUX stwux
+#define ShiftLeftImm slwi
+#define ShiftRightImm srwi
+#define ClearLeftImm clrlwi
+#define ClearRightImm clrrwi
+#define ShiftRightArithImm srawi
+#define ShiftLeft_ slw
+#define ShiftRight_ srw
+#define ShiftRightArith sraw
+#define Mul mullw
+#define Div divw
+#endif
+
+
+// MacroAssembler implements a collection of frequently used macros.
+class MacroAssembler : public Assembler {
+ public:
+  // The isolate parameter can be NULL if the macro assembler should
+  // not use isolate-dependent functionality. In this case, it's the
+  // responsibility of the caller to never invoke such function on the
+  // macro assembler.
+  MacroAssembler(Isolate* isolate, void* buffer, int size);
+
+
+  // Returns the size of a call in instructions. Note, the value returned is
+  // only valid as long as no entries are added to the constant pool between
+  // checking the call size and emitting the actual call.
+  static int CallSize(Register target);
+  int CallSize(Address target, RelocInfo::Mode rmode, Condition cond = al);
+  static int CallSizeNotPredictableCodeSize(Address target,
+                                            RelocInfo::Mode rmode,
+                                            Condition cond = al);
+
+  // Jump, Call, and Ret pseudo instructions implementing inter-working.
+  void Jump(Register target);
+  void JumpToJSEntry(Register target);
+  void Jump(Address target, RelocInfo::Mode rmode, Condition cond = al,
+            CRegister cr = cr7);
+  void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
+  void Call(Register target);
+  void CallJSEntry(Register target);
+  void Call(Address target, RelocInfo::Mode rmode, Condition cond = al);
+  int CallSize(Handle<Code> code,
+               RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
+               TypeFeedbackId ast_id = TypeFeedbackId::None(),
+               Condition cond = al);
+  void Call(Handle<Code> code, RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
+            TypeFeedbackId ast_id = TypeFeedbackId::None(),
+            Condition cond = al);
+  void Ret(Condition cond = al);
+
+  // Emit code to discard a non-negative number of pointer-sized elements
+  // from the stack, clobbering only the sp register.
+  void Drop(int count, Condition cond = al);
+
+  void Ret(int drop, Condition cond = al);
+
+  void Call(Label* target);
+
+  // Emit call to the code we are currently generating.
+  void CallSelf() {
+    Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
+    Call(self, RelocInfo::CODE_TARGET);
+  }
+
+  // Register move. May do nothing if the registers are identical.
+  void Move(Register dst, Handle<Object> value);
+  void Move(Register dst, Register src, Condition cond = al);
+  void Move(DoubleRegister dst, DoubleRegister src);
+
+  void MultiPush(RegList regs);
+  void MultiPop(RegList regs);
+
+  // Load an object from the root table.
+  void LoadRoot(Register destination, Heap::RootListIndex index,
+                Condition cond = al);
+  // Store an object to the root table.
+  void StoreRoot(Register source, Heap::RootListIndex index,
+                 Condition cond = al);
+
+  // ---------------------------------------------------------------------------
+  // GC Support
+
+  void IncrementalMarkingRecordWriteHelper(Register object, Register value,
+                                           Register address);
+
+  enum RememberedSetFinalAction { kReturnAtEnd, kFallThroughAtEnd };
+
+  // Record in the remembered set the fact that we have a pointer to new space
+  // at the address pointed to by the addr register.  Only works if addr is not
+  // in new space.
+  void RememberedSetHelper(Register object,  // Used for debug code.
+                           Register addr, Register scratch,
+                           SaveFPRegsMode save_fp,
+                           RememberedSetFinalAction and_then);
+
+  void CheckPageFlag(Register object, Register scratch, int mask, Condition cc,
+                     Label* condition_met);
+
+  void CheckMapDeprecated(Handle<Map> map, Register scratch,
+                          Label* if_deprecated);
+
+  // Check if object is in new space.  Jumps if the object is not in new space.
+  // The register scratch can be object itself, but scratch will be clobbered.
+  void JumpIfNotInNewSpace(Register object, Register scratch, Label* branch) {
+    InNewSpace(object, scratch, ne, branch);
+  }
+
+  // Check if object is in new space.  Jumps if the object is in new space.
+  // The register scratch can be object itself, but it will be clobbered.
+  void JumpIfInNewSpace(Register object, Register scratch, Label* branch) {
+    InNewSpace(object, scratch, eq, branch);
+  }
+
+  // Check if an object has a given incremental marking color.
+  void HasColor(Register object, Register scratch0, Register scratch1,
+                Label* has_color, int first_bit, int second_bit);
+
+  void JumpIfBlack(Register object, Register scratch0, Register scratch1,
+                   Label* on_black);
+
+  // Checks the color of an object.  If the object is already grey or black
+  // then we just fall through, since it is already live.  If it is white and
+  // we can determine that it doesn't need to be scanned, then we just mark it
+  // black and fall through.  For the rest we jump to the label so the
+  // incremental marker can fix its assumptions.
+  void EnsureNotWhite(Register object, Register scratch1, Register scratch2,
+                      Register scratch3, Label* object_is_white_and_not_data);
+
+  // Detects conservatively whether an object is data-only, i.e. it does need to
+  // be scanned by the garbage collector.
+  void JumpIfDataObject(Register value, Register scratch,
+                        Label* not_data_object);
+
+  // Notify the garbage collector that we wrote a pointer into an object.
+  // |object| is the object being stored into, |value| is the object being
+  // stored.  value and scratch registers are clobbered by the operation.
+  // The offset is the offset from the start of the object, not the offset from
+  // the tagged HeapObject pointer.  For use with FieldOperand(reg, off).
+  void RecordWriteField(
+      Register object, int offset, Register value, Register scratch,
+      LinkRegisterStatus lr_status, SaveFPRegsMode save_fp,
+      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
+      SmiCheck smi_check = INLINE_SMI_CHECK,
+      PointersToHereCheck pointers_to_here_check_for_value =
+          kPointersToHereMaybeInteresting);
+
+  // As above, but the offset has the tag presubtracted.  For use with
+  // MemOperand(reg, off).
+  inline void RecordWriteContextSlot(
+      Register context, int offset, Register value, Register scratch,
+      LinkRegisterStatus lr_status, SaveFPRegsMode save_fp,
+      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
+      SmiCheck smi_check = INLINE_SMI_CHECK,
+      PointersToHereCheck pointers_to_here_check_for_value =
+          kPointersToHereMaybeInteresting) {
+    RecordWriteField(context, offset + kHeapObjectTag, value, scratch,
+                     lr_status, save_fp, remembered_set_action, smi_check,
+                     pointers_to_here_check_for_value);
+  }
+
+  void RecordWriteForMap(Register object, Register map, Register dst,
+                         LinkRegisterStatus lr_status, SaveFPRegsMode save_fp);
+
+  // For a given |object| notify the garbage collector that the slot |address|
+  // has been written.  |value| is the object being stored. The value and
+  // address registers are clobbered by the operation.
+  void RecordWrite(
+      Register object, Register address, Register value,
+      LinkRegisterStatus lr_status, SaveFPRegsMode save_fp,
+      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
+      SmiCheck smi_check = INLINE_SMI_CHECK,
+      PointersToHereCheck pointers_to_here_check_for_value =
+          kPointersToHereMaybeInteresting);
+
+  void Push(Register src) { push(src); }
+
+  // Push a handle.
+  void Push(Handle<Object> handle);
+  void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); }
+
+  // Push two registers.  Pushes leftmost register first (to highest address).
+  void Push(Register src1, Register src2) {
+    StorePU(src2, MemOperand(sp, -2 * kPointerSize));
+    StoreP(src1, MemOperand(sp, kPointerSize));
+  }
+
+  // Push three registers.  Pushes leftmost register first (to highest address).
+  void Push(Register src1, Register src2, Register src3) {
+    StorePU(src3, MemOperand(sp, -3 * kPointerSize));
+    StoreP(src2, MemOperand(sp, kPointerSize));
+    StoreP(src1, MemOperand(sp, 2 * kPointerSize));
+  }
+
+  // Push four registers.  Pushes leftmost register first (to highest address).
+  void Push(Register src1, Register src2, Register src3, Register src4) {
+    StorePU(src4, MemOperand(sp, -4 * kPointerSize));
+    StoreP(src3, MemOperand(sp, kPointerSize));
+    StoreP(src2, MemOperand(sp, 2 * kPointerSize));
+    StoreP(src1, MemOperand(sp, 3 * kPointerSize));
+  }
+
+  // Push five registers.  Pushes leftmost register first (to highest address).
+  void Push(Register src1, Register src2, Register src3, Register src4,
+            Register src5) {
+    StorePU(src5, MemOperand(sp, -5 * kPointerSize));
+    StoreP(src4, MemOperand(sp, kPointerSize));
+    StoreP(src3, MemOperand(sp, 2 * kPointerSize));
+    StoreP(src2, MemOperand(sp, 3 * kPointerSize));
+    StoreP(src1, MemOperand(sp, 4 * kPointerSize));
+  }
+
+  void Pop(Register dst) { pop(dst); }
+
+  // Pop two registers. Pops rightmost register first (from lower address).
+  void Pop(Register src1, Register src2) {
+    LoadP(src2, MemOperand(sp, 0));
+    LoadP(src1, MemOperand(sp, kPointerSize));
+    addi(sp, sp, Operand(2 * kPointerSize));
+  }
+
+  // Pop three registers.  Pops rightmost register first (from lower address).
+  void Pop(Register src1, Register src2, Register src3) {
+    LoadP(src3, MemOperand(sp, 0));
+    LoadP(src2, MemOperand(sp, kPointerSize));
+    LoadP(src1, MemOperand(sp, 2 * kPointerSize));
+    addi(sp, sp, Operand(3 * kPointerSize));
+  }
+
+  // Pop four registers.  Pops rightmost register first (from lower address).
+  void Pop(Register src1, Register src2, Register src3, Register src4) {
+    LoadP(src4, MemOperand(sp, 0));
+    LoadP(src3, MemOperand(sp, kPointerSize));
+    LoadP(src2, MemOperand(sp, 2 * kPointerSize));
+    LoadP(src1, MemOperand(sp, 3 * kPointerSize));
+    addi(sp, sp, Operand(4 * kPointerSize));
+  }
+
+  // Pop five registers.  Pops rightmost register first (from lower address).
+  void Pop(Register src1, Register src2, Register src3, Register src4,
+           Register src5) {
+    LoadP(src5, MemOperand(sp, 0));
+    LoadP(src4, MemOperand(sp, kPointerSize));
+    LoadP(src3, MemOperand(sp, 2 * kPointerSize));
+    LoadP(src2, MemOperand(sp, 3 * kPointerSize));
+    LoadP(src1, MemOperand(sp, 4 * kPointerSize));
+    addi(sp, sp, Operand(5 * kPointerSize));
+  }
+
+  // Push a fixed frame, consisting of lr, fp, context and
+  // JS function / marker id if marker_reg is a valid register.
+  void PushFixedFrame(Register marker_reg = no_reg);
+  void PopFixedFrame(Register marker_reg = no_reg);
+
+  // Push and pop the registers that can hold pointers, as defined by the
+  // RegList constant kSafepointSavedRegisters.
+  void PushSafepointRegisters();
+  void PopSafepointRegisters();
+  // Store value in register src in the safepoint stack slot for
+  // register dst.
+  void StoreToSafepointRegisterSlot(Register src, Register dst);
+  // Load the value of the src register from its safepoint stack slot
+  // into register dst.
+  void LoadFromSafepointRegisterSlot(Register dst, Register src);
+
+  // Flush the I-cache from asm code. You should use CpuFeatures::FlushICache
+  // from C.
+  // Does not handle errors.
+  void FlushICache(Register address, size_t size, Register scratch);
+
+  // If the value is a NaN, canonicalize the value else, do nothing.
+  void CanonicalizeNaN(const DoubleRegister dst, const DoubleRegister src);
+  void CanonicalizeNaN(const DoubleRegister value) {
+    CanonicalizeNaN(value, value);
+  }
+
+  // Converts the integer (untagged smi) in |src| to a double, storing
+  // the result to |double_dst|
+  void ConvertIntToDouble(Register src, DoubleRegister double_dst);
+
+  // Converts the unsigned integer (untagged smi) in |src| to
+  // a double, storing the result to |double_dst|
+  void ConvertUnsignedIntToDouble(Register src, DoubleRegister double_dst);
+
+  // Converts the integer (untagged smi) in |src| to
+  // a float, storing the result in |dst|
+  // Warning: The value in |int_scrach| will be changed in the process!
+  void ConvertIntToFloat(const DoubleRegister dst, const Register src,
+                         const Register int_scratch);
+
+  // Converts the double_input to an integer.  Note that, upon return,
+  // the contents of double_dst will also hold the fixed point representation.
+  void ConvertDoubleToInt64(const DoubleRegister double_input,
+#if !V8_TARGET_ARCH_PPC64
+                            const Register dst_hi,
+#endif
+                            const Register dst, const DoubleRegister double_dst,
+                            FPRoundingMode rounding_mode = kRoundToZero);
+
+  // Generates function and stub prologue code.
+  void StubPrologue(int prologue_offset = 0);
+  void Prologue(bool code_pre_aging, int prologue_offset = 0);
+
+  // Enter exit frame.
+  // stack_space - extra stack space, used for alignment before call to C.
+  void EnterExitFrame(bool save_doubles, int stack_space = 0);
+
+  // Leave the current exit frame. Expects the return value in r0.
+  // Expect the number of values, pushed prior to the exit frame, to
+  // remove in a register (or no_reg, if there is nothing to remove).
+  void LeaveExitFrame(bool save_doubles, Register argument_count,
+                      bool restore_context);
+
+  // Get the actual activation frame alignment for target environment.
+  static int ActivationFrameAlignment();
+
+  void LoadContext(Register dst, int context_chain_length);
+
+  // Conditionally load the cached Array transitioned map of type
+  // transitioned_kind from the native context if the map in register
+  // map_in_out is the cached Array map in the native context of
+  // expected_kind.
+  void LoadTransitionedArrayMapConditional(ElementsKind expected_kind,
+                                           ElementsKind transitioned_kind,
+                                           Register map_in_out,
+                                           Register scratch,
+                                           Label* no_map_match);
+
+  void LoadGlobalFunction(int index, Register function);
+
+  // Load the initial map from the global function. The registers
+  // function and map can be the same, function is then overwritten.
+  void LoadGlobalFunctionInitialMap(Register function, Register map,
+                                    Register scratch);
+
+  void InitializeRootRegister() {
+    ExternalReference roots_array_start =
+        ExternalReference::roots_array_start(isolate());
+    mov(kRootRegister, Operand(roots_array_start));
+  }
+
+  // ----------------------------------------------------------------
+  // new PPC macro-assembler interfaces that are slightly higher level
+  // than assembler-ppc and may generate variable length sequences
+
+  // load a literal signed int value <value> to GPR <dst>
+  void LoadIntLiteral(Register dst, int value);
+
+  // load an SMI value <value> to GPR <dst>
+  void LoadSmiLiteral(Register dst, Smi* smi);
+
+  // load a literal double value <value> to FPR <result>
+  void LoadDoubleLiteral(DoubleRegister result, double value, Register scratch);
+
+  void LoadWord(Register dst, const MemOperand& mem, Register scratch);
+
+  void LoadWordArith(Register dst, const MemOperand& mem,
+                     Register scratch = no_reg);
+
+  void StoreWord(Register src, const MemOperand& mem, Register scratch);
+
+  void LoadHalfWord(Register dst, const MemOperand& mem, Register scratch);
+
+  void StoreHalfWord(Register src, const MemOperand& mem, Register scratch);
+
+  void LoadByte(Register dst, const MemOperand& mem, Register scratch);
+
+  void StoreByte(Register src, const MemOperand& mem, Register scratch);
+
+  void LoadRepresentation(Register dst, const MemOperand& mem, Representation r,
+                          Register scratch = no_reg);
+
+  void StoreRepresentation(Register src, const MemOperand& mem,
+                           Representation r, Register scratch = no_reg);
+
+  // Move values between integer and floating point registers.
+  void MovIntToDouble(DoubleRegister dst, Register src, Register scratch);
+  void MovUnsignedIntToDouble(DoubleRegister dst, Register src,
+                              Register scratch);
+  void MovInt64ToDouble(DoubleRegister dst,
+#if !V8_TARGET_ARCH_PPC64
+                        Register src_hi,
+#endif
+                        Register src);
+#if V8_TARGET_ARCH_PPC64
+  void MovInt64ComponentsToDouble(DoubleRegister dst, Register src_hi,
+                                  Register src_lo, Register scratch);
+#endif
+  void MovDoubleLowToInt(Register dst, DoubleRegister src);
+  void MovDoubleHighToInt(Register dst, DoubleRegister src);
+  void MovDoubleToInt64(
+#if !V8_TARGET_ARCH_PPC64
+      Register dst_hi,
+#endif
+      Register dst, DoubleRegister src);
+
+  void Add(Register dst, Register src, intptr_t value, Register scratch);
+  void Cmpi(Register src1, const Operand& src2, Register scratch,
+            CRegister cr = cr7);
+  void Cmpli(Register src1, const Operand& src2, Register scratch,
+             CRegister cr = cr7);
+  void Cmpwi(Register src1, const Operand& src2, Register scratch,
+             CRegister cr = cr7);
+  void Cmplwi(Register src1, const Operand& src2, Register scratch,
+              CRegister cr = cr7);
+  void And(Register ra, Register rs, const Operand& rb, RCBit rc = LeaveRC);
+  void Or(Register ra, Register rs, const Operand& rb, RCBit rc = LeaveRC);
+  void Xor(Register ra, Register rs, const Operand& rb, RCBit rc = LeaveRC);
+
+  void AddSmiLiteral(Register dst, Register src, Smi* smi, Register scratch);
+  void SubSmiLiteral(Register dst, Register src, Smi* smi, Register scratch);
+  void CmpSmiLiteral(Register src1, Smi* smi, Register scratch,
+                     CRegister cr = cr7);
+  void CmplSmiLiteral(Register src1, Smi* smi, Register scratch,
+                      CRegister cr = cr7);
+  void AndSmiLiteral(Register dst, Register src, Smi* smi, Register scratch,
+                     RCBit rc = LeaveRC);
+
+  // Set new rounding mode RN to FPSCR
+  void SetRoundingMode(FPRoundingMode RN);
+
+  // reset rounding mode to default (kRoundToNearest)
+  void ResetRoundingMode();
+
+  // These exist to provide portability between 32 and 64bit
+  void LoadP(Register dst, const MemOperand& mem, Register scratch = no_reg);
+  void StoreP(Register src, const MemOperand& mem, Register scratch = no_reg);
+
+  // ---------------------------------------------------------------------------
+  // JavaScript invokes
+
+  // Invoke the JavaScript function code by either calling or jumping.
+  void InvokeCode(Register code, const ParameterCount& expected,
+                  const ParameterCount& actual, InvokeFlag flag,
+                  const CallWrapper& call_wrapper);
+
+  // Invoke the JavaScript function in the given register. Changes the
+  // current context to the context in the function before invoking.
+  void InvokeFunction(Register function, const ParameterCount& actual,
+                      InvokeFlag flag, const CallWrapper& call_wrapper);
+
+  void InvokeFunction(Register function, const ParameterCount& expected,
+                      const ParameterCount& actual, InvokeFlag flag,
+                      const CallWrapper& call_wrapper);
+
+  void InvokeFunction(Handle<JSFunction> function,
+                      const ParameterCount& expected,
+                      const ParameterCount& actual, InvokeFlag flag,
+                      const CallWrapper& call_wrapper);
+
+  void IsObjectJSObjectType(Register heap_object, Register map,
+                            Register scratch, Label* fail);
+
+  void IsInstanceJSObjectType(Register map, Register scratch, Label* fail);
+
+  void IsObjectJSStringType(Register object, Register scratch, Label* fail);
+
+  void IsObjectNameType(Register object, Register scratch, Label* fail);
+
+  // ---------------------------------------------------------------------------
+  // Debugger Support
+
+  void DebugBreak();
+
+  // ---------------------------------------------------------------------------
+  // Exception handling
+
+  // Push a new try handler and link into try handler chain.
+  void PushTryHandler(StackHandler::Kind kind, int handler_index);
+
+  // Unlink the stack handler on top of the stack from the try handler chain.
+  // Must preserve the result register.
+  void PopTryHandler();
+
+  // Passes thrown value to the handler of top of the try handler chain.
+  void Throw(Register value);
+
+  // Propagates an uncatchable exception to the top of the current JS stack's
+  // handler chain.
+  void ThrowUncatchable(Register value);
+
+  // ---------------------------------------------------------------------------
+  // Inline caching support
+
+  // Generate code for checking access rights - used for security checks
+  // on access to global objects across environments. The holder register
+  // is left untouched, whereas both scratch registers are clobbered.
+  void CheckAccessGlobalProxy(Register holder_reg, Register scratch,
+                              Label* miss);
+
+  void GetNumberHash(Register t0, Register scratch);
+
+  void LoadFromNumberDictionary(Label* miss, Register elements, Register key,
+                                Register result, Register t0, Register t1,
+                                Register t2);
+
+
+  inline void MarkCode(NopMarkerTypes type) { nop(type); }
+
+  // Check if the given instruction is a 'type' marker.
+  // i.e. check if is is a mov r<type>, r<type> (referenced as nop(type))
+  // These instructions are generated to mark special location in the code,
+  // like some special IC code.
+  static inline bool IsMarkedCode(Instr instr, int type) {
+    DCHECK((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER));
+    return IsNop(instr, type);
+  }
+
+
+  static inline int GetCodeMarker(Instr instr) {
+    int dst_reg_offset = 12;
+    int dst_mask = 0xf << dst_reg_offset;
+    int src_mask = 0xf;
+    int dst_reg = (instr & dst_mask) >> dst_reg_offset;
+    int src_reg = instr & src_mask;
+    uint32_t non_register_mask = ~(dst_mask | src_mask);
+    uint32_t mov_mask = al | 13 << 21;
+
+    // Return <n> if we have a mov rn rn, else return -1.
+    int type = ((instr & non_register_mask) == mov_mask) &&
+                       (dst_reg == src_reg) && (FIRST_IC_MARKER <= dst_reg) &&
+                       (dst_reg < LAST_CODE_MARKER)
+                   ? src_reg
+                   : -1;
+    DCHECK((type == -1) ||
+           ((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER)));
+    return type;
+  }
+
+
+  // ---------------------------------------------------------------------------
+  // Allocation support
+
+  // Allocate an object in new space or old pointer space. The object_size is
+  // specified either in bytes or in words if the allocation flag SIZE_IN_WORDS
+  // is passed. If the space is exhausted control continues at the gc_required
+  // label. The allocated object is returned in result. If the flag
+  // tag_allocated_object is true the result is tagged as as a heap object.
+  // All registers are clobbered also when control continues at the gc_required
+  // label.
+  void Allocate(int object_size, Register result, Register scratch1,
+                Register scratch2, Label* gc_required, AllocationFlags flags);
+
+  void Allocate(Register object_size, Register result, Register scratch1,
+                Register scratch2, Label* gc_required, AllocationFlags flags);
+
+  // Undo allocation in new space. The object passed and objects allocated after
+  // it will no longer be allocated. The caller must make sure that no pointers
+  // are left to the object(s) no longer allocated as they would be invalid when
+  // allocation is undone.
+  void UndoAllocationInNewSpace(Register object, Register scratch);
+
+
+  void AllocateTwoByteString(Register result, Register length,
+                             Register scratch1, Register scratch2,
+                             Register scratch3, Label* gc_required);
+  void AllocateOneByteString(Register result, Register length,
+                             Register scratch1, Register scratch2,
+                             Register scratch3, Label* gc_required);
+  void AllocateTwoByteConsString(Register result, Register length,
+                                 Register scratch1, Register scratch2,
+                                 Label* gc_required);
+  void AllocateOneByteConsString(Register result, Register length,
+                                 Register scratch1, Register scratch2,
+                                 Label* gc_required);
+  void AllocateTwoByteSlicedString(Register result, Register length,
+                                   Register scratch1, Register scratch2,
+                                   Label* gc_required);
+  void AllocateOneByteSlicedString(Register result, Register length,
+                                   Register scratch1, Register scratch2,
+                                   Label* gc_required);
+
+  // Allocates a heap number or jumps to the gc_required label if the young
+  // space is full and a scavenge is needed. All registers are clobbered also
+  // when control continues at the gc_required label.
+  void AllocateHeapNumber(Register result, Register scratch1, Register scratch2,
+                          Register heap_number_map, Label* gc_required,
+                          TaggingMode tagging_mode = TAG_RESULT,
+                          MutableMode mode = IMMUTABLE);
+  void AllocateHeapNumberWithValue(Register result, DoubleRegister value,
+                                   Register scratch1, Register scratch2,
+                                   Register heap_number_map,
+                                   Label* gc_required);
+
+  // Copies a fixed number of fields of heap objects from src to dst.
+  void CopyFields(Register dst, Register src, RegList temps, int field_count);
+
+  // Copies a number of bytes from src to dst. All registers are clobbered. On
+  // exit src and dst will point to the place just after where the last byte was
+  // read or written and length will be zero.
+  void CopyBytes(Register src, Register dst, Register length, Register scratch);
+
+  // Initialize fields with filler values.  |count| fields starting at
+  // |start_offset| are overwritten with the value in |filler|.  At the end the
+  // loop, |start_offset| points at the next uninitialized field.  |count| is
+  // assumed to be non-zero.
+  void InitializeNFieldsWithFiller(Register start_offset, Register count,
+                                   Register filler);
+
+  // Initialize fields with filler values.  Fields starting at |start_offset|
+  // not including end_offset are overwritten with the value in |filler|.  At
+  // the end the loop, |start_offset| takes the value of |end_offset|.
+  void InitializeFieldsWithFiller(Register start_offset, Register end_offset,
+                                  Register filler);
+
+  // ---------------------------------------------------------------------------
+  // Support functions.
+
+  // Try to get function prototype of a function and puts the value in
+  // the result register. Checks that the function really is a
+  // function and jumps to the miss label if the fast checks fail. The
+  // function register will be untouched; the other registers may be
+  // clobbered.
+  void TryGetFunctionPrototype(Register function, Register result,
+                               Register scratch, Label* miss,
+                               bool miss_on_bound_function = false);
+
+  // Compare object type for heap object.  heap_object contains a non-Smi
+  // whose object type should be compared with the given type.  This both
+  // sets the flags and leaves the object type in the type_reg register.
+  // It leaves the map in the map register (unless the type_reg and map register
+  // are the same register).  It leaves the heap object in the heap_object
+  // register unless the heap_object register is the same register as one of the
+  // other registers.
+  // Type_reg can be no_reg. In that case ip is used.
+  void CompareObjectType(Register heap_object, Register map, Register type_reg,
+                         InstanceType type);
+
+  // Compare object type for heap object. Branch to false_label if type
+  // is lower than min_type or greater than max_type.
+  // Load map into the register map.
+  void CheckObjectTypeRange(Register heap_object, Register map,
+                            InstanceType min_type, InstanceType max_type,
+                            Label* false_label);
+
+  // Compare instance type in a map.  map contains a valid map object whose
+  // object type should be compared with the given type.  This both
+  // sets the flags and leaves the object type in the type_reg register.
+  void CompareInstanceType(Register map, Register type_reg, InstanceType type);
+
+
+  // Check if a map for a JSObject indicates that the object has fast elements.
+  // Jump to the specified label if it does not.
+  void CheckFastElements(Register map, Register scratch, Label* fail);
+
+  // Check if a map for a JSObject indicates that the object can have both smi
+  // and HeapObject elements.  Jump to the specified label if it does not.
+  void CheckFastObjectElements(Register map, Register scratch, Label* fail);
+
+  // Check if a map for a JSObject indicates that the object has fast smi only
+  // elements.  Jump to the specified label if it does not.
+  void CheckFastSmiElements(Register map, Register scratch, Label* fail);
+
+  // Check to see if maybe_number can be stored as a double in
+  // FastDoubleElements. If it can, store it at the index specified by key in
+  // the FastDoubleElements array elements. Otherwise jump to fail.
+  void StoreNumberToDoubleElements(Register value_reg, Register key_reg,
+                                   Register elements_reg, Register scratch1,
+                                   DoubleRegister double_scratch, Label* fail,
+                                   int elements_offset = 0);
+
+  // Compare an object's map with the specified map and its transitioned
+  // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. Condition flags are
+  // set with result of map compare. If multiple map compares are required, the
+  // compare sequences branches to early_success.
+  void CompareMap(Register obj, Register scratch, Handle<Map> map,
+                  Label* early_success);
+
+  // As above, but the map of the object is already loaded into the register
+  // which is preserved by the code generated.
+  void CompareMap(Register obj_map, Handle<Map> map, Label* early_success);
+
+  // Check if the map of an object is equal to a specified map and branch to
+  // label if not. Skip the smi check if not required (object is known to be a
+  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
+  // against maps that are ElementsKind transition maps of the specified map.
+  void CheckMap(Register obj, Register scratch, Handle<Map> map, Label* fail,
+                SmiCheckType smi_check_type);
+
+
+  void CheckMap(Register obj, Register scratch, Heap::RootListIndex index,
+                Label* fail, SmiCheckType smi_check_type);
+
+
+  // Check if the map of an object is equal to a specified map and branch to a
+  // specified target if equal. Skip the smi check if not required (object is
+  // known to be a heap object)
+  void DispatchMap(Register obj, Register scratch, Handle<Map> map,
+                   Handle<Code> success, SmiCheckType smi_check_type);
+
+
+  // Compare the object in a register to a value from the root list.
+  // Uses the ip register as scratch.
+  void CompareRoot(Register obj, Heap::RootListIndex index);
+
+
+  // Load and check the instance type of an object for being a string.
+  // Loads the type into the second argument register.
+  // Returns a condition that will be enabled if the object was a string.
+  Condition IsObjectStringType(Register obj, Register type) {
+    LoadP(type, FieldMemOperand(obj, HeapObject::kMapOffset));
+    lbz(type, FieldMemOperand(type, Map::kInstanceTypeOffset));
+    andi(r0, type, Operand(kIsNotStringMask));
+    DCHECK_EQ(0, kStringTag);
+    return eq;
+  }
+
+
+  // Picks out an array index from the hash field.
+  // Register use:
+  //   hash - holds the index's hash. Clobbered.
+  //   index - holds the overwritten index on exit.
+  void IndexFromHash(Register hash, Register index);
+
+  // Get the number of least significant bits from a register
+  void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits);
+  void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits);
+
+  // Load the value of a smi object into a double register.
+  void SmiToDouble(DoubleRegister value, Register smi);
+
+  // Check if a double can be exactly represented as a signed 32-bit integer.
+  // CR_EQ in cr7 is set if true.
+  void TestDoubleIsInt32(DoubleRegister double_input, Register scratch1,
+                         Register scratch2, DoubleRegister double_scratch);
+
+  // Try to convert a double to a signed 32-bit integer.
+  // CR_EQ in cr7 is set and result assigned if the conversion is exact.
+  void TryDoubleToInt32Exact(Register result, DoubleRegister double_input,
+                             Register scratch, DoubleRegister double_scratch);
+
+  // Floor a double and writes the value to the result register.
+  // Go to exact if the conversion is exact (to be able to test -0),
+  // fall through calling code if an overflow occurred, else go to done.
+  // In return, input_high is loaded with high bits of input.
+  void TryInt32Floor(Register result, DoubleRegister double_input,
+                     Register input_high, Register scratch,
+                     DoubleRegister double_scratch, Label* done, Label* exact);
+
+  // Performs a truncating conversion of a floating point number as used by
+  // the JS bitwise operations. See ECMA-262 9.5: ToInt32. Goes to 'done' if it
+  // succeeds, otherwise falls through if result is saturated. On return
+  // 'result' either holds answer, or is clobbered on fall through.
+  //
+  // Only public for the test code in test-code-stubs-arm.cc.
+  void TryInlineTruncateDoubleToI(Register result, DoubleRegister input,
+                                  Label* done);
+
+  // Performs a truncating conversion of a floating point number as used by
+  // the JS bitwise operations. See ECMA-262 9.5: ToInt32.
+  // Exits with 'result' holding the answer.
+  void TruncateDoubleToI(Register result, DoubleRegister double_input);
+
+  // Performs a truncating conversion of a heap number as used by
+  // the JS bitwise operations. See ECMA-262 9.5: ToInt32. 'result' and 'input'
+  // must be different registers.  Exits with 'result' holding the answer.
+  void TruncateHeapNumberToI(Register result, Register object);
+
+  // Converts the smi or heap number in object to an int32 using the rules
+  // for ToInt32 as described in ECMAScript 9.5.: the value is truncated
+  // and brought into the range -2^31 .. +2^31 - 1. 'result' and 'input' must be
+  // different registers.
+  void TruncateNumberToI(Register object, Register result,
+                         Register heap_number_map, Register scratch1,
+                         Label* not_int32);
+
+  // Overflow handling functions.
+  // Usage: call the appropriate arithmetic function and then call one of the
+  // flow control functions with the corresponding label.
+
+  // Compute dst = left + right, setting condition codes. dst may be same as
+  // either left or right (or a unique register). left and right must not be
+  // the same register.
+  void AddAndCheckForOverflow(Register dst, Register left, Register right,
+                              Register overflow_dst, Register scratch = r0);
+  void AddAndCheckForOverflow(Register dst, Register left, intptr_t right,
+                              Register overflow_dst, Register scratch = r0);
+
+  // Compute dst = left - right, setting condition codes. dst may be same as
+  // either left or right (or a unique register). left and right must not be
+  // the same register.
+  void SubAndCheckForOverflow(Register dst, Register left, Register right,
+                              Register overflow_dst, Register scratch = r0);
+
+  void BranchOnOverflow(Label* label) { blt(label, cr0); }
+
+  void BranchOnNoOverflow(Label* label) { bge(label, cr0); }
+
+  void RetOnOverflow(void) {
+    Label label;
+
+    blt(&label, cr0);
+    Ret();
+    bind(&label);
+  }
+
+  void RetOnNoOverflow(void) {
+    Label label;
+
+    bge(&label, cr0);
+    Ret();
+    bind(&label);
+  }
+
+  // Pushes <count> double values to <location>, starting from d<first>.
+  void SaveFPRegs(Register location, int first, int count);
+
+  // Pops <count> double values from <location>, starting from d<first>.
+  void RestoreFPRegs(Register location, int first, int count);
+
+  // ---------------------------------------------------------------------------
+  // Runtime calls
+
+  // Call a code stub.
+  void CallStub(CodeStub* stub, TypeFeedbackId ast_id = TypeFeedbackId::None(),
+                Condition cond = al);
+
+  // Call a code stub.
+  void TailCallStub(CodeStub* stub, Condition cond = al);
+
+  // Call a runtime routine.
+  void CallRuntime(const Runtime::Function* f, int num_arguments,
+                   SaveFPRegsMode save_doubles = kDontSaveFPRegs);
+  void CallRuntimeSaveDoubles(Runtime::FunctionId id) {
+    const Runtime::Function* function = Runtime::FunctionForId(id);
+    CallRuntime(function, function->nargs, kSaveFPRegs);
+  }
+
+  // Convenience function: Same as above, but takes the fid instead.
+  void CallRuntime(Runtime::FunctionId id, int num_arguments,
+                   SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
+    CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles);
+  }
+
+  // Convenience function: call an external reference.
+  void CallExternalReference(const ExternalReference& ext, int num_arguments);
+
+  // Tail call of a runtime routine (jump).
+  // Like JumpToExternalReference, but also takes care of passing the number
+  // of parameters.
+  void TailCallExternalReference(const ExternalReference& ext,
+                                 int num_arguments, int result_size);
+
+  // Convenience function: tail call a runtime routine (jump).
+  void TailCallRuntime(Runtime::FunctionId fid, int num_arguments,
+                       int result_size);
+
+  int CalculateStackPassedWords(int num_reg_arguments,
+                                int num_double_arguments);
+
+  // Before calling a C-function from generated code, align arguments on stack.
+  // After aligning the frame, non-register arguments must be stored in
+  // sp[0], sp[4], etc., not pushed. The argument count assumes all arguments
+  // are word sized. If double arguments are used, this function assumes that
+  // all double arguments are stored before core registers; otherwise the
+  // correct alignment of the double values is not guaranteed.
+  // Some compilers/platforms require the stack to be aligned when calling
+  // C++ code.
+  // Needs a scratch register to do some arithmetic. This register will be
+  // trashed.
+  void PrepareCallCFunction(int num_reg_arguments, int num_double_registers,
+                            Register scratch);
+  void PrepareCallCFunction(int num_reg_arguments, Register scratch);
+
+  // There are two ways of passing double arguments on ARM, depending on
+  // whether soft or hard floating point ABI is used. These functions
+  // abstract parameter passing for the three different ways we call
+  // C functions from generated code.
+  void MovToFloatParameter(DoubleRegister src);
+  void MovToFloatParameters(DoubleRegister src1, DoubleRegister src2);
+  void MovToFloatResult(DoubleRegister src);
+
+  // Calls a C function and cleans up the space for arguments allocated
+  // by PrepareCallCFunction. The called function is not allowed to trigger a
+  // garbage collection, since that might move the code and invalidate the
+  // return address (unless this is somehow accounted for by the called
+  // function).
+  void CallCFunction(ExternalReference function, int num_arguments);
+  void CallCFunction(Register function, int num_arguments);
+  void CallCFunction(ExternalReference function, int num_reg_arguments,
+                     int num_double_arguments);
+  void CallCFunction(Register function, int num_reg_arguments,
+                     int num_double_arguments);
+
+  void MovFromFloatParameter(DoubleRegister dst);
+  void MovFromFloatResult(DoubleRegister dst);
+
+  // Calls an API function.  Allocates HandleScope, extracts returned value
+  // from handle and propagates exceptions.  Restores context.  stack_space
+  // - space to be unwound on exit (includes the call JS arguments space and
+  // the additional space allocated for the fast call).
+  void CallApiFunctionAndReturn(Register function_address,
+                                ExternalReference thunk_ref, int stack_space,
+                                MemOperand return_value_operand,
+                                MemOperand* context_restore_operand);
+
+  // Jump to a runtime routine.
+  void JumpToExternalReference(const ExternalReference& builtin);
+
+  // Invoke specified builtin JavaScript function. Adds an entry to
+  // the unresolved list if the name does not resolve.
+  void InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag,
+                     const CallWrapper& call_wrapper = NullCallWrapper());
+
+  // Store the code object for the given builtin in the target register and
+  // setup the function in r1.
+  void GetBuiltinEntry(Register target, Builtins::JavaScript id);
+
+  // Store the function for the given builtin in the target register.
+  void GetBuiltinFunction(Register target, Builtins::JavaScript id);
+
+  Handle<Object> CodeObject() {
+    DCHECK(!code_object_.is_null());
+    return code_object_;
+  }
+
+
+  // Emit code for a truncating division by a constant. The dividend register is
+  // unchanged and ip gets clobbered. Dividend and result must be different.
+  void TruncatingDiv(Register result, Register dividend, int32_t divisor);
+
+  // ---------------------------------------------------------------------------
+  // StatsCounter support
+
+  void SetCounter(StatsCounter* counter, int value, Register scratch1,
+                  Register scratch2);
+  void IncrementCounter(StatsCounter* counter, int value, Register scratch1,
+                        Register scratch2);
+  void DecrementCounter(StatsCounter* counter, int value, Register scratch1,
+                        Register scratch2);
+
+
+  // ---------------------------------------------------------------------------
+  // Debugging
+
+  // Calls Abort(msg) if the condition cond is not satisfied.
+  // Use --debug_code to enable.
+  void Assert(Condition cond, BailoutReason reason, CRegister cr = cr7);
+  void AssertFastElements(Register elements);
+
+  // Like Assert(), but always enabled.
+  void Check(Condition cond, BailoutReason reason, CRegister cr = cr7);
+
+  // Print a message to stdout and abort execution.
+  void Abort(BailoutReason reason);
+
+  // Verify restrictions about code generated in stubs.
+  void set_generating_stub(bool value) { generating_stub_ = value; }
+  bool generating_stub() { return generating_stub_; }
+  void set_has_frame(bool value) { has_frame_ = value; }
+  bool has_frame() { return has_frame_; }
+  inline bool AllowThisStubCall(CodeStub* stub);
+
+  // ---------------------------------------------------------------------------
+  // Number utilities
+
+  // Check whether the value of reg is a power of two and not zero. If not
+  // control continues at the label not_power_of_two. If reg is a power of two
+  // the register scratch contains the value of (reg - 1) when control falls
+  // through.
+  void JumpIfNotPowerOfTwoOrZero(Register reg, Register scratch,
+                                 Label* not_power_of_two_or_zero);
+  // Check whether the value of reg is a power of two and not zero.
+  // Control falls through if it is, with scratch containing the mask
+  // value (reg - 1).
+  // Otherwise control jumps to the 'zero_and_neg' label if the value of reg is
+  // zero or negative, or jumps to the 'not_power_of_two' label if the value is
+  // strictly positive but not a power of two.
+  void JumpIfNotPowerOfTwoOrZeroAndNeg(Register reg, Register scratch,
+                                       Label* zero_and_neg,
+                                       Label* not_power_of_two);
+
+  // ---------------------------------------------------------------------------
+  // Bit testing/extraction
+  //
+  // Bit numbering is such that the least significant bit is bit 0
+  // (for consistency between 32/64-bit).
+
+  // Extract consecutive bits (defined by rangeStart - rangeEnd) from src
+  // and place them into the least significant bits of dst.
+  inline void ExtractBitRange(Register dst, Register src, int rangeStart,
+                              int rangeEnd, RCBit rc = LeaveRC) {
+    DCHECK(rangeStart >= rangeEnd && rangeStart < kBitsPerPointer);
+    int rotate = (rangeEnd == 0) ? 0 : kBitsPerPointer - rangeEnd;
+    int width = rangeStart - rangeEnd + 1;
+#if V8_TARGET_ARCH_PPC64
+    rldicl(dst, src, rotate, kBitsPerPointer - width, rc);
+#else
+    rlwinm(dst, src, rotate, kBitsPerPointer - width, kBitsPerPointer - 1, rc);
+#endif
+  }
+
+  inline void ExtractBit(Register dst, Register src, uint32_t bitNumber,
+                         RCBit rc = LeaveRC) {
+    ExtractBitRange(dst, src, bitNumber, bitNumber, rc);
+  }
+
+  // Extract consecutive bits (defined by mask) from src and place them
+  // into the least significant bits of dst.
+  inline void ExtractBitMask(Register dst, Register src, uintptr_t mask,
+                             RCBit rc = LeaveRC) {
+    int start = kBitsPerPointer - 1;
+    int end;
+    uintptr_t bit = (1L << start);
+
+    while (bit && (mask & bit) == 0) {
+      start--;
+      bit >>= 1;
+    }
+    end = start;
+    bit >>= 1;
+
+    while (bit && (mask & bit)) {
+      end--;
+      bit >>= 1;
+    }
+
+    // 1-bits in mask must be contiguous
+    DCHECK(bit == 0 || (mask & ((bit << 1) - 1)) == 0);
+
+    ExtractBitRange(dst, src, start, end, rc);
+  }
+
+  // Test single bit in value.
+  inline void TestBit(Register value, int bitNumber, Register scratch = r0) {
+    ExtractBitRange(scratch, value, bitNumber, bitNumber, SetRC);
+  }
+
+  // Test consecutive bit range in value.  Range is defined by
+  // rangeStart - rangeEnd.
+  inline void TestBitRange(Register value, int rangeStart, int rangeEnd,
+                           Register scratch = r0) {
+    ExtractBitRange(scratch, value, rangeStart, rangeEnd, SetRC);
+  }
+
+  // Test consecutive bit range in value.  Range is defined by mask.
+  inline void TestBitMask(Register value, uintptr_t mask,
+                          Register scratch = r0) {
+    ExtractBitMask(scratch, value, mask, SetRC);
+  }
+
+
+  // ---------------------------------------------------------------------------
+  // Smi utilities
+
+  // Shift left by 1
+  void SmiTag(Register reg, RCBit rc = LeaveRC) { SmiTag(reg, reg, rc); }
+  void SmiTag(Register dst, Register src, RCBit rc = LeaveRC) {
+    ShiftLeftImm(dst, src, Operand(kSmiShift), rc);
+  }
+
+#if !V8_TARGET_ARCH_PPC64
+  // Test for overflow < 0: use BranchOnOverflow() or BranchOnNoOverflow().
+  void SmiTagCheckOverflow(Register reg, Register overflow);
+  void SmiTagCheckOverflow(Register dst, Register src, Register overflow);
+
+  inline void JumpIfNotSmiCandidate(Register value, Register scratch,
+                                    Label* not_smi_label) {
+    // High bits must be identical to fit into an Smi
+    addis(scratch, value, Operand(0x40000000u >> 16));
+    cmpi(scratch, Operand::Zero());
+    blt(not_smi_label);
+  }
+#endif
+  inline void TestUnsignedSmiCandidate(Register value, Register scratch) {
+    // 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 any of the high bits being set in the value.
+    TestBitRange(value, kBitsPerPointer - 1, kBitsPerPointer - 1 - kSmiShift,
+                 scratch);
+  }
+  inline void JumpIfNotUnsignedSmiCandidate(Register value, Register scratch,
+                                            Label* not_smi_label) {
+    TestUnsignedSmiCandidate(value, scratch);
+    bne(not_smi_label, cr0);
+  }
+
+  void SmiUntag(Register reg, RCBit rc = LeaveRC) { SmiUntag(reg, reg, rc); }
+
+  void SmiUntag(Register dst, Register src, RCBit rc = LeaveRC) {
+    ShiftRightArithImm(dst, src, kSmiShift, rc);
+  }
+
+  void SmiToPtrArrayOffset(Register dst, Register src) {
+#if V8_TARGET_ARCH_PPC64
+    STATIC_ASSERT(kSmiTag == 0 && kSmiShift > kPointerSizeLog2);
+    ShiftRightArithImm(dst, src, kSmiShift - kPointerSizeLog2);
+#else
+    STATIC_ASSERT(kSmiTag == 0 && kSmiShift < kPointerSizeLog2);
+    ShiftLeftImm(dst, src, Operand(kPointerSizeLog2 - kSmiShift));
+#endif
+  }
+
+  void SmiToByteArrayOffset(Register dst, Register src) { SmiUntag(dst, src); }
+
+  void SmiToShortArrayOffset(Register dst, Register src) {
+#if V8_TARGET_ARCH_PPC64
+    STATIC_ASSERT(kSmiTag == 0 && kSmiShift > 1);
+    ShiftRightArithImm(dst, src, kSmiShift - 1);
+#else
+    STATIC_ASSERT(kSmiTag == 0 && kSmiShift == 1);
+    if (!dst.is(src)) {
+      mr(dst, src);
+    }
+#endif
+  }
+
+  void SmiToIntArrayOffset(Register dst, Register src) {
+#if V8_TARGET_ARCH_PPC64
+    STATIC_ASSERT(kSmiTag == 0 && kSmiShift > 2);
+    ShiftRightArithImm(dst, src, kSmiShift - 2);
+#else
+    STATIC_ASSERT(kSmiTag == 0 && kSmiShift < 2);
+    ShiftLeftImm(dst, src, Operand(2 - kSmiShift));
+#endif
+  }
+
+#define SmiToFloatArrayOffset SmiToIntArrayOffset
+
+  void SmiToDoubleArrayOffset(Register dst, Register src) {
+#if V8_TARGET_ARCH_PPC64
+    STATIC_ASSERT(kSmiTag == 0 && kSmiShift > kDoubleSizeLog2);
+    ShiftRightArithImm(dst, src, kSmiShift - kDoubleSizeLog2);
+#else
+    STATIC_ASSERT(kSmiTag == 0 && kSmiShift < kDoubleSizeLog2);
+    ShiftLeftImm(dst, src, Operand(kDoubleSizeLog2 - kSmiShift));
+#endif
+  }
+
+  void SmiToArrayOffset(Register dst, Register src, int elementSizeLog2) {
+    if (kSmiShift < elementSizeLog2) {
+      ShiftLeftImm(dst, src, Operand(elementSizeLog2 - kSmiShift));
+    } else if (kSmiShift > elementSizeLog2) {
+      ShiftRightArithImm(dst, src, kSmiShift - elementSizeLog2);
+    } else if (!dst.is(src)) {
+      mr(dst, src);
+    }
+  }
+
+  void IndexToArrayOffset(Register dst, Register src, int elementSizeLog2,
+                          bool isSmi) {
+    if (isSmi) {
+      SmiToArrayOffset(dst, src, elementSizeLog2);
+    } else {
+      ShiftLeftImm(dst, src, Operand(elementSizeLog2));
+    }
+  }
+
+  // Untag the source value into destination and jump if source is a smi.
+  // Souce and destination can be the same register.
+  void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case);
+
+  // Untag the source value into destination and jump if source is not a smi.
+  // Souce and destination can be the same register.
+  void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case);
+
+  inline void TestIfSmi(Register value, Register scratch) {
+    TestBit(value, 0, scratch);  // tst(value, Operand(kSmiTagMask));
+  }
+
+  inline void TestIfPositiveSmi(Register value, Register scratch) {
+    STATIC_ASSERT((kSmiTagMask | kSmiSignMask) ==
+                  (intptr_t)(1UL << (kBitsPerPointer - 1) | 1));
+#if V8_TARGET_ARCH_PPC64
+    rldicl(scratch, value, 1, kBitsPerPointer - 2, SetRC);
+#else
+    rlwinm(scratch, value, 1, kBitsPerPointer - 2, kBitsPerPointer - 1, SetRC);
+#endif
+  }
+
+  // Jump the register contains a smi.
+  inline void JumpIfSmi(Register value, Label* smi_label) {
+    TestIfSmi(value, r0);
+    beq(smi_label, cr0);  // branch if SMI
+  }
+  // Jump if either of the registers contain a non-smi.
+  inline void JumpIfNotSmi(Register value, Label* not_smi_label) {
+    TestIfSmi(value, r0);
+    bne(not_smi_label, cr0);
+  }
+  // Jump if either of the registers contain a non-smi.
+  void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi);
+  // Jump if either of the registers contain a smi.
+  void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
+
+  // Abort execution if argument is a smi, enabled via --debug-code.
+  void AssertNotSmi(Register object);
+  void AssertSmi(Register object);
+
+
+#if V8_TARGET_ARCH_PPC64
+  inline void TestIfInt32(Register value, Register scratch1, Register scratch2,
+                          CRegister cr = cr7) {
+    // High bits must be identical to fit into an 32-bit integer
+    srawi(scratch1, value, 31);
+    sradi(scratch2, value, 32);
+    cmp(scratch1, scratch2, cr);
+  }
+#else
+  inline void TestIfInt32(Register hi_word, Register lo_word, Register scratch,
+                          CRegister cr = cr7) {
+    // High bits must be identical to fit into an 32-bit integer
+    srawi(scratch, lo_word, 31);
+    cmp(scratch, hi_word, cr);
+  }
+#endif
+
+  // Abort execution if argument is not a string, enabled via --debug-code.
+  void AssertString(Register object);
+
+  // Abort execution if argument is not a name, enabled via --debug-code.
+  void AssertName(Register object);
+
+  // Abort execution if argument is not undefined or an AllocationSite, enabled
+  // via --debug-code.
+  void AssertUndefinedOrAllocationSite(Register object, Register scratch);
+
+  // Abort execution if reg is not the root value with the given index,
+  // enabled via --debug-code.
+  void AssertIsRoot(Register reg, Heap::RootListIndex index);
+
+  // ---------------------------------------------------------------------------
+  // HeapNumber utilities
+
+  void JumpIfNotHeapNumber(Register object, Register heap_number_map,
+                           Register scratch, Label* on_not_heap_number);
+
+  // ---------------------------------------------------------------------------
+  // String utilities
+
+  // Generate code to do a lookup in the number string cache. If the number in
+  // the register object is found in the cache the generated code falls through
+  // with the result in the result register. The object and the result register
+  // can be the same. If the number is not found in the cache the code jumps to
+  // the label not_found with only the content of register object unchanged.
+  void LookupNumberStringCache(Register object, Register result,
+                               Register scratch1, Register scratch2,
+                               Register scratch3, Label* not_found);
+
+  // Checks if both objects are sequential one-byte strings and jumps to label
+  // if either is not. Assumes that neither object is a smi.
+  void JumpIfNonSmisNotBothSequentialOneByteStrings(Register object1,
+                                                    Register object2,
+                                                    Register scratch1,
+                                                    Register scratch2,
+                                                    Label* failure);
+
+  // Checks if both objects are sequential one-byte strings and jumps to label
+  // if either is not.
+  void JumpIfNotBothSequentialOneByteStrings(Register first, Register second,
+                                             Register scratch1,
+                                             Register scratch2,
+                                             Label* not_flat_one_byte_strings);
+
+  // Checks if both instance types are sequential one-byte strings and jumps to
+  // label if either is not.
+  void JumpIfBothInstanceTypesAreNotSequentialOneByte(
+      Register first_object_instance_type, Register second_object_instance_type,
+      Register scratch1, Register scratch2, Label* failure);
+
+  // Check if instance type is sequential one-byte string and jump to label if
+  // it is not.
+  void JumpIfInstanceTypeIsNotSequentialOneByte(Register type, Register scratch,
+                                                Label* failure);
+
+  void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name);
+
+  void EmitSeqStringSetCharCheck(Register string, Register index,
+                                 Register value, uint32_t encoding_mask);
+
+  // ---------------------------------------------------------------------------
+  // Patching helpers.
+
+  // Retrieve/patch the relocated value (lis/ori pair or constant pool load).
+  void GetRelocatedValue(Register location, Register result, Register scratch);
+  void SetRelocatedValue(Register location, Register scratch,
+                         Register new_value);
+
+  void ClampUint8(Register output_reg, Register input_reg);
+
+  // Saturate a value into 8-bit unsigned integer
+  //   if input_value < 0, output_value is 0
+  //   if input_value > 255, output_value is 255
+  //   otherwise output_value is the (int)input_value (round to nearest)
+  void ClampDoubleToUint8(Register result_reg, DoubleRegister input_reg,
+                          DoubleRegister temp_double_reg);
+
+
+  void LoadInstanceDescriptors(Register map, Register descriptors);
+  void EnumLength(Register dst, Register map);
+  void NumberOfOwnDescriptors(Register dst, Register map);
+
+  template <typename Field>
+  void DecodeField(Register dst, Register src) {
+    ExtractBitRange(dst, src, Field::kShift + Field::kSize - 1, Field::kShift);
+  }
+
+  template <typename Field>
+  void DecodeField(Register reg) {
+    DecodeField<Field>(reg, reg);
+  }
+
+  template <typename Field>
+  void DecodeFieldToSmi(Register dst, Register src) {
+#if V8_TARGET_ARCH_PPC64
+    DecodeField<Field>(dst, src);
+    SmiTag(dst);
+#else
+    // 32-bit can do this in one instruction:
+    int start = Field::kSize + kSmiShift - 1;
+    int end = kSmiShift;
+    int rotate = kSmiShift - Field::kShift;
+    if (rotate < 0) {
+      rotate += kBitsPerPointer;
+    }
+    rlwinm(dst, src, rotate, kBitsPerPointer - start - 1,
+           kBitsPerPointer - end - 1);
+#endif
+  }
+
+  template <typename Field>
+  void DecodeFieldToSmi(Register reg) {
+    DecodeFieldToSmi<Field>(reg, reg);
+  }
+
+  // Activation support.
+  void EnterFrame(StackFrame::Type type,
+                  bool load_constant_pool_pointer_reg = false);
+  // Returns the pc offset at which the frame ends.
+  int LeaveFrame(StackFrame::Type type, int stack_adjustment = 0);
+
+  // Expects object in r0 and returns map with validated enum cache
+  // in r0.  Assumes that any other register can be used as a scratch.
+  void CheckEnumCache(Register null_value, Label* call_runtime);
+
+  // AllocationMemento support. Arrays may have an associated
+  // AllocationMemento object that can be checked for in order to pretransition
+  // to another type.
+  // On entry, receiver_reg should point to the array object.
+  // scratch_reg gets clobbered.
+  // If allocation info is present, condition flags are set to eq.
+  void TestJSArrayForAllocationMemento(Register receiver_reg,
+                                       Register scratch_reg,
+                                       Label* no_memento_found);
+
+  void JumpIfJSArrayHasAllocationMemento(Register receiver_reg,
+                                         Register scratch_reg,
+                                         Label* memento_found) {
+    Label no_memento_found;
+    TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
+                                    &no_memento_found);
+    beq(memento_found);
+    bind(&no_memento_found);
+  }
+
+  // Jumps to found label if a prototype map has dictionary elements.
+  void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
+                                        Register scratch1, Label* found);
+
+ private:
+  static const int kSmiShift = kSmiTagSize + kSmiShiftSize;
+
+  void CallCFunctionHelper(Register function, int num_reg_arguments,
+                           int num_double_arguments);
+
+  void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al,
+            CRegister cr = cr7);
+
+  // Helper functions for generating invokes.
+  void InvokePrologue(const ParameterCount& expected,
+                      const ParameterCount& actual, Handle<Code> code_constant,
+                      Register code_reg, Label* done,
+                      bool* definitely_mismatches, InvokeFlag flag,
+                      const CallWrapper& call_wrapper);
+
+  void InitializeNewString(Register string, Register length,
+                           Heap::RootListIndex map_index, Register scratch1,
+                           Register scratch2);
+
+  // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
+  void InNewSpace(Register object, Register scratch,
+                  Condition cond,  // eq for new space, ne otherwise.
+                  Label* branch);
+
+  // Helper for finding the mark bits for an address.  Afterwards, the
+  // bitmap register points at the word with the mark bits and the mask
+  // the position of the first bit.  Leaves addr_reg unchanged.
+  inline void GetMarkBits(Register addr_reg, Register bitmap_reg,
+                          Register mask_reg);
+
+  // Helper for throwing exceptions.  Compute a handler address and jump to
+  // it.  See the implementation for register usage.
+  void JumpToHandlerEntry();
+
+  // Compute memory operands for safepoint stack slots.
+  static int SafepointRegisterStackIndex(int reg_code);
+  MemOperand SafepointRegisterSlot(Register reg);
+  MemOperand SafepointRegistersAndDoublesSlot(Register reg);
+
+#if V8_OOL_CONSTANT_POOL
+  // Loads the constant pool pointer (kConstantPoolRegister).
+  enum CodeObjectAccessMethod { CAN_USE_IP, CONSTRUCT_INTERNAL_REFERENCE };
+  void LoadConstantPoolPointerRegister(CodeObjectAccessMethod access_method,
+                                       int ip_code_entry_delta = 0);
+#endif
+
+  bool generating_stub_;
+  bool has_frame_;
+  // This handle will be patched with the code object on installation.
+  Handle<Object> code_object_;
+
+  // Needs access to SafepointRegisterStackIndex for compiled frame
+  // traversal.
+  friend class StandardFrame;
+};
+
+
+// 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
+// relocation information. If any of these constraints are violated it causes
+// an assertion to fail.
+class CodePatcher {
+ public:
+  enum FlushICache { FLUSH, DONT_FLUSH };
+
+  CodePatcher(byte* address, int instructions, FlushICache flush_cache = FLUSH);
+  virtual ~CodePatcher();
+
+  // Macro assembler to emit code.
+  MacroAssembler* masm() { return &masm_; }
+
+  // Emit an instruction directly.
+  void Emit(Instr instr);
+
+  // Emit the condition part of an instruction leaving the rest of the current
+  // instruction unchanged.
+  void EmitCondition(Condition cond);
+
+ private:
+  byte* address_;            // The address of the code being patched.
+  int size_;                 // Number of bytes of the expected patch size.
+  MacroAssembler masm_;      // Macro assembler used to generate the code.
+  FlushICache flush_cache_;  // Whether to flush the I cache after patching.
+};
+
+
+// -----------------------------------------------------------------------------
+// Static helper functions.
+
+inline MemOperand ContextOperand(Register context, int index) {
+  return MemOperand(context, Context::SlotOffset(index));
+}
+
+
+inline MemOperand GlobalObjectOperand() {
+  return ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX);
+}
+
+
+#ifdef GENERATED_CODE_COVERAGE
+#define CODE_COVERAGE_STRINGIFY(x) #x
+#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
+#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
+#define ACCESS_MASM(masm)    \
+  masm->stop(__FILE_LINE__); \
+  masm->
+#else
+#define ACCESS_MASM(masm) masm->
+#endif
+}
+}  // namespace v8::internal
+
+#endif  // V8_PPC_MACRO_ASSEMBLER_PPC_H_
diff --git a/src/ppc/regexp-macro-assembler-ppc.cc b/src/ppc/regexp-macro-assembler-ppc.cc
new file mode 100644
index 0000000..54acce1
--- /dev/null
+++ b/src/ppc/regexp-macro-assembler-ppc.cc
@@ -0,0 +1,1337 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/base/bits.h"
+#include "src/code-stubs.h"
+#include "src/cpu-profiler.h"
+#include "src/log.h"
+#include "src/macro-assembler.h"
+#include "src/regexp-macro-assembler.h"
+#include "src/regexp-stack.h"
+#include "src/unicode.h"
+
+#include "src/ppc/regexp-macro-assembler-ppc.h"
+
+namespace v8 {
+namespace internal {
+
+#ifndef V8_INTERPRETED_REGEXP
+/*
+ * This assembler uses the following register assignment convention
+ * - r25: Temporarily stores the index of capture start after a matching pass
+ *        for a global regexp.
+ * - r26: Pointer to current code object (Code*) including heap object tag.
+ * - r27: Current position in input, as negative offset from end of string.
+ *        Please notice that this is the byte offset, not the character offset!
+ * - r28: Currently loaded character. Must be loaded using
+ *        LoadCurrentCharacter before using any of the dispatch methods.
+ * - r29: Points to tip of backtrack stack
+ * - r30: End of input (points to byte after last character in input).
+ * - r31: Frame pointer. Used to access arguments, local variables and
+ *         RegExp registers.
+ * - r12: IP register, used by assembler. Very volatile.
+ * - r1/sp : Points to tip of C stack.
+ *
+ * The remaining registers are free for computations.
+ * Each call to a public method should retain this convention.
+ *
+ * The stack will have the following structure:
+ *  - fp[44]  Isolate* isolate   (address of the current isolate)
+ *  - fp[40]  secondary link/return address used by native call.
+ *  - fp[36]  lr save area (currently unused)
+ *  - fp[32]  backchain    (currently unused)
+ *  --- sp when called ---
+ *  - fp[28]  return address     (lr).
+ *  - fp[24]  old frame pointer  (r31).
+ *  - fp[0..20]  backup of registers r25..r30
+ *  --- frame pointer ----
+ *  - fp[-4]  direct_call        (if 1, direct call from JavaScript code,
+ *                                if 0, call through the runtime system).
+ *  - fp[-8]  stack_area_base    (high end of the memory area to use as
+ *                                backtracking stack).
+ *  - fp[-12] capture array size (may fit multiple sets of matches)
+ *  - fp[-16] int* capture_array (int[num_saved_registers_], for output).
+ *  - fp[-20] end of input       (address of end of string).
+ *  - fp[-24] start of input     (address of first character in string).
+ *  - fp[-28] start index        (character index of start).
+ *  - fp[-32] void* input_string (location of a handle containing the string).
+ *  - fp[-36] success counter    (only for global regexps to count matches).
+ *  - fp[-40] Offset of location before start of input (effectively character
+ *            position -1). Used to initialize capture registers to a
+ *            non-position.
+ *  - fp[-44] At start (if 1, we are starting at the start of the
+ *    string, otherwise 0)
+ *  - fp[-48] register 0         (Only positions must be stored in the first
+ *  -         register 1          num_saved_registers_ registers)
+ *  -         ...
+ *  -         register num_registers-1
+ *  --- sp ---
+ *
+ * The first num_saved_registers_ registers are initialized to point to
+ * "character -1" in the string (i.e., char_size() bytes before the first
+ * character of the string). The remaining registers start out as garbage.
+ *
+ * The data up to the return address must be placed there by the calling
+ * code and the remaining arguments are passed in registers, e.g. by calling the
+ * code entry as cast to a function with the signature:
+ * int (*match)(String* input_string,
+ *              int start_index,
+ *              Address start,
+ *              Address end,
+ *              int* capture_output_array,
+ *              byte* stack_area_base,
+ *              Address secondary_return_address,  // Only used by native call.
+ *              bool direct_call = false)
+ * The call is performed by NativeRegExpMacroAssembler::Execute()
+ * (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro
+ * in ppc/simulator-ppc.h.
+ * When calling as a non-direct call (i.e., from C++ code), the return address
+ * area is overwritten with the LR register by the RegExp code. When doing a
+ * direct call from generated code, the return address is placed there by
+ * the calling code, as in a normal exit frame.
+ */
+
+#define __ ACCESS_MASM(masm_)
+
+RegExpMacroAssemblerPPC::RegExpMacroAssemblerPPC(Mode mode,
+                                                 int registers_to_save,
+                                                 Zone* zone)
+    : NativeRegExpMacroAssembler(zone),
+      masm_(new MacroAssembler(zone->isolate(), NULL, kRegExpCodeSize)),
+      mode_(mode),
+      num_registers_(registers_to_save),
+      num_saved_registers_(registers_to_save),
+      entry_label_(),
+      start_label_(),
+      success_label_(),
+      backtrack_label_(),
+      exit_label_(),
+      internal_failure_label_() {
+  DCHECK_EQ(0, registers_to_save % 2);
+
+// Called from C
+#if ABI_USES_FUNCTION_DESCRIPTORS
+  __ function_descriptor();
+#endif
+
+  __ b(&entry_label_);  // We'll write the entry code later.
+  // If the code gets too big or corrupted, an internal exception will be
+  // raised, and we will exit right away.
+  __ bind(&internal_failure_label_);
+  __ li(r3, Operand(FAILURE));
+  __ Ret();
+  __ bind(&start_label_);  // And then continue from here.
+}
+
+
+RegExpMacroAssemblerPPC::~RegExpMacroAssemblerPPC() {
+  delete masm_;
+  // Unuse labels in case we throw away the assembler without calling GetCode.
+  entry_label_.Unuse();
+  start_label_.Unuse();
+  success_label_.Unuse();
+  backtrack_label_.Unuse();
+  exit_label_.Unuse();
+  check_preempt_label_.Unuse();
+  stack_overflow_label_.Unuse();
+  internal_failure_label_.Unuse();
+}
+
+
+int RegExpMacroAssemblerPPC::stack_limit_slack() {
+  return RegExpStack::kStackLimitSlack;
+}
+
+
+void RegExpMacroAssemblerPPC::AdvanceCurrentPosition(int by) {
+  if (by != 0) {
+    __ addi(current_input_offset(), current_input_offset(),
+            Operand(by * char_size()));
+  }
+}
+
+
+void RegExpMacroAssemblerPPC::AdvanceRegister(int reg, int by) {
+  DCHECK(reg >= 0);
+  DCHECK(reg < num_registers_);
+  if (by != 0) {
+    __ LoadP(r3, register_location(reg), r0);
+    __ mov(r0, Operand(by));
+    __ add(r3, r3, r0);
+    __ StoreP(r3, register_location(reg), r0);
+  }
+}
+
+
+void RegExpMacroAssemblerPPC::Backtrack() {
+  CheckPreemption();
+  // Pop Code* offset from backtrack stack, add Code* and jump to location.
+  Pop(r3);
+  __ add(r3, r3, code_pointer());
+  __ mtctr(r3);
+  __ bctr();
+}
+
+
+void RegExpMacroAssemblerPPC::Bind(Label* label) { __ bind(label); }
+
+
+void RegExpMacroAssemblerPPC::CheckCharacter(uint32_t c, Label* on_equal) {
+  __ Cmpli(current_character(), Operand(c), r0);
+  BranchOrBacktrack(eq, on_equal);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckCharacterGT(uc16 limit, Label* on_greater) {
+  __ Cmpli(current_character(), Operand(limit), r0);
+  BranchOrBacktrack(gt, on_greater);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckAtStart(Label* on_at_start) {
+  Label not_at_start;
+  // Did we start the match at the start of the string at all?
+  __ LoadP(r3, MemOperand(frame_pointer(), kStartIndex));
+  __ cmpi(r3, Operand::Zero());
+  BranchOrBacktrack(ne, &not_at_start);
+
+  // If we did, are we still at the start of the input?
+  __ LoadP(r4, MemOperand(frame_pointer(), kInputStart));
+  __ mr(r0, current_input_offset());
+  __ add(r3, end_of_input_address(), r0);
+  __ cmp(r4, r3);
+  BranchOrBacktrack(eq, on_at_start);
+  __ bind(&not_at_start);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckNotAtStart(Label* on_not_at_start) {
+  // Did we start the match at the start of the string at all?
+  __ LoadP(r3, MemOperand(frame_pointer(), kStartIndex));
+  __ cmpi(r3, Operand::Zero());
+  BranchOrBacktrack(ne, on_not_at_start);
+  // If we did, are we still at the start of the input?
+  __ LoadP(r4, MemOperand(frame_pointer(), kInputStart));
+  __ add(r3, end_of_input_address(), current_input_offset());
+  __ cmp(r3, r4);
+  BranchOrBacktrack(ne, on_not_at_start);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckCharacterLT(uc16 limit, Label* on_less) {
+  __ Cmpli(current_character(), Operand(limit), r0);
+  BranchOrBacktrack(lt, on_less);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckGreedyLoop(Label* on_equal) {
+  Label backtrack_non_equal;
+  __ LoadP(r3, MemOperand(backtrack_stackpointer(), 0));
+  __ cmp(current_input_offset(), r3);
+  __ bne(&backtrack_non_equal);
+  __ addi(backtrack_stackpointer(), backtrack_stackpointer(),
+          Operand(kPointerSize));
+
+  __ bind(&backtrack_non_equal);
+  BranchOrBacktrack(eq, on_equal);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckNotBackReferenceIgnoreCase(
+    int start_reg, Label* on_no_match) {
+  Label fallthrough;
+  __ LoadP(r3, register_location(start_reg), r0);  // Index of start of capture
+  __ LoadP(r4, register_location(start_reg + 1), r0);  // Index of end
+  __ sub(r4, r4, r3, LeaveOE, SetRC);                  // Length of capture.
+
+  // If length is zero, either the capture is empty or it is not participating.
+  // In either case succeed immediately.
+  __ beq(&fallthrough, cr0);
+
+  // Check that there are enough characters left in the input.
+  __ add(r0, r4, current_input_offset(), LeaveOE, SetRC);
+  //  __ cmn(r1, Operand(current_input_offset()));
+  BranchOrBacktrack(gt, on_no_match, cr0);
+
+  if (mode_ == LATIN1) {
+    Label success;
+    Label fail;
+    Label loop_check;
+
+    // r3 - offset of start of capture
+    // r4 - length of capture
+    __ add(r3, r3, end_of_input_address());
+    __ add(r5, end_of_input_address(), current_input_offset());
+    __ add(r4, r3, r4);
+
+    // r3 - Address of start of capture.
+    // r4 - Address of end of capture
+    // r5 - Address of current input position.
+
+    Label loop;
+    __ bind(&loop);
+    __ lbz(r6, MemOperand(r3));
+    __ addi(r3, r3, Operand(char_size()));
+    __ lbz(r25, MemOperand(r5));
+    __ addi(r5, r5, Operand(char_size()));
+    __ cmp(r25, r6);
+    __ beq(&loop_check);
+
+    // Mismatch, try case-insensitive match (converting letters to lower-case).
+    __ ori(r6, r6, Operand(0x20));  // Convert capture character to lower-case.
+    __ ori(r25, r25, Operand(0x20));  // Also convert input character.
+    __ cmp(r25, r6);
+    __ bne(&fail);
+    __ subi(r6, r6, Operand('a'));
+    __ cmpli(r6, Operand('z' - 'a'));  // Is r6 a lowercase letter?
+    __ ble(&loop_check);               // In range 'a'-'z'.
+    // Latin-1: Check for values in range [224,254] but not 247.
+    __ subi(r6, r6, Operand(224 - 'a'));
+    __ cmpli(r6, Operand(254 - 224));
+    __ bgt(&fail);                    // Weren't Latin-1 letters.
+    __ cmpi(r6, Operand(247 - 224));  // Check for 247.
+    __ beq(&fail);
+
+    __ bind(&loop_check);
+    __ cmp(r3, r4);
+    __ blt(&loop);
+    __ b(&success);
+
+    __ bind(&fail);
+    BranchOrBacktrack(al, on_no_match);
+
+    __ bind(&success);
+    // Compute new value of character position after the matched part.
+    __ sub(current_input_offset(), r5, end_of_input_address());
+  } else {
+    DCHECK(mode_ == UC16);
+    int argument_count = 4;
+    __ PrepareCallCFunction(argument_count, r5);
+
+    // r3 - offset of start of capture
+    // r4 - length of capture
+
+    // Put arguments into arguments registers.
+    // Parameters are
+    //   r3: Address byte_offset1 - Address captured substring's start.
+    //   r4: Address byte_offset2 - Address of current character position.
+    //   r5: size_t byte_length - length of capture in bytes(!)
+    //   r6: Isolate* isolate
+
+    // Address of start of capture.
+    __ add(r3, r3, end_of_input_address());
+    // Length of capture.
+    __ mr(r5, r4);
+    // Save length in callee-save register for use on return.
+    __ mr(r25, r4);
+    // Address of current input position.
+    __ add(r4, current_input_offset(), end_of_input_address());
+    // Isolate.
+    __ mov(r6, Operand(ExternalReference::isolate_address(isolate())));
+
+    {
+      AllowExternalCallThatCantCauseGC scope(masm_);
+      ExternalReference function =
+          ExternalReference::re_case_insensitive_compare_uc16(isolate());
+      __ CallCFunction(function, argument_count);
+    }
+
+    // Check if function returned non-zero for success or zero for failure.
+    __ cmpi(r3, Operand::Zero());
+    BranchOrBacktrack(eq, on_no_match);
+    // On success, increment position by length of capture.
+    __ add(current_input_offset(), current_input_offset(), r25);
+  }
+
+  __ bind(&fallthrough);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckNotBackReference(int start_reg,
+                                                    Label* on_no_match) {
+  Label fallthrough;
+  Label success;
+
+  // Find length of back-referenced capture.
+  __ LoadP(r3, register_location(start_reg), r0);
+  __ LoadP(r4, register_location(start_reg + 1), r0);
+  __ sub(r4, r4, r3, LeaveOE, SetRC);  // Length to check.
+  // Succeed on empty capture (including no capture).
+  __ beq(&fallthrough, cr0);
+
+  // Check that there are enough characters left in the input.
+  __ add(r0, r4, current_input_offset(), LeaveOE, SetRC);
+  BranchOrBacktrack(gt, on_no_match, cr0);
+
+  // Compute pointers to match string and capture string
+  __ add(r3, r3, end_of_input_address());
+  __ add(r5, end_of_input_address(), current_input_offset());
+  __ add(r4, r4, r3);
+
+  Label loop;
+  __ bind(&loop);
+  if (mode_ == LATIN1) {
+    __ lbz(r6, MemOperand(r3));
+    __ addi(r3, r3, Operand(char_size()));
+    __ lbz(r25, MemOperand(r5));
+    __ addi(r5, r5, Operand(char_size()));
+  } else {
+    DCHECK(mode_ == UC16);
+    __ lhz(r6, MemOperand(r3));
+    __ addi(r3, r3, Operand(char_size()));
+    __ lhz(r25, MemOperand(r5));
+    __ addi(r5, r5, Operand(char_size()));
+  }
+  __ cmp(r6, r25);
+  BranchOrBacktrack(ne, on_no_match);
+  __ cmp(r3, r4);
+  __ blt(&loop);
+
+  // Move current character position to position after match.
+  __ sub(current_input_offset(), r5, end_of_input_address());
+  __ bind(&fallthrough);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckNotCharacter(unsigned c,
+                                                Label* on_not_equal) {
+  __ Cmpli(current_character(), Operand(c), r0);
+  BranchOrBacktrack(ne, on_not_equal);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckCharacterAfterAnd(uint32_t c, uint32_t mask,
+                                                     Label* on_equal) {
+  __ mov(r0, Operand(mask));
+  if (c == 0) {
+    __ and_(r3, current_character(), r0, SetRC);
+  } else {
+    __ and_(r3, current_character(), r0);
+    __ Cmpli(r3, Operand(c), r0, cr0);
+  }
+  BranchOrBacktrack(eq, on_equal, cr0);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckNotCharacterAfterAnd(unsigned c,
+                                                        unsigned mask,
+                                                        Label* on_not_equal) {
+  __ mov(r0, Operand(mask));
+  if (c == 0) {
+    __ and_(r3, current_character(), r0, SetRC);
+  } else {
+    __ and_(r3, current_character(), r0);
+    __ Cmpli(r3, Operand(c), r0, cr0);
+  }
+  BranchOrBacktrack(ne, on_not_equal, cr0);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckNotCharacterAfterMinusAnd(
+    uc16 c, uc16 minus, uc16 mask, Label* on_not_equal) {
+  DCHECK(minus < String::kMaxUtf16CodeUnit);
+  __ subi(r3, current_character(), Operand(minus));
+  __ mov(r0, Operand(mask));
+  __ and_(r3, r3, r0);
+  __ Cmpli(r3, Operand(c), r0);
+  BranchOrBacktrack(ne, on_not_equal);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckCharacterInRange(uc16 from, uc16 to,
+                                                    Label* on_in_range) {
+  __ mov(r0, Operand(from));
+  __ sub(r3, current_character(), r0);
+  __ Cmpli(r3, Operand(to - from), r0);
+  BranchOrBacktrack(le, on_in_range);  // Unsigned lower-or-same condition.
+}
+
+
+void RegExpMacroAssemblerPPC::CheckCharacterNotInRange(uc16 from, uc16 to,
+                                                       Label* on_not_in_range) {
+  __ mov(r0, Operand(from));
+  __ sub(r3, current_character(), r0);
+  __ Cmpli(r3, Operand(to - from), r0);
+  BranchOrBacktrack(gt, on_not_in_range);  // Unsigned higher condition.
+}
+
+
+void RegExpMacroAssemblerPPC::CheckBitInTable(Handle<ByteArray> table,
+                                              Label* on_bit_set) {
+  __ mov(r3, Operand(table));
+  if (mode_ != LATIN1 || kTableMask != String::kMaxOneByteCharCode) {
+    __ andi(r4, current_character(), Operand(kTableSize - 1));
+    __ addi(r4, r4, Operand(ByteArray::kHeaderSize - kHeapObjectTag));
+  } else {
+    __ addi(r4, current_character(),
+            Operand(ByteArray::kHeaderSize - kHeapObjectTag));
+  }
+  __ lbzx(r3, MemOperand(r3, r4));
+  __ cmpi(r3, Operand::Zero());
+  BranchOrBacktrack(ne, on_bit_set);
+}
+
+
+bool RegExpMacroAssemblerPPC::CheckSpecialCharacterClass(uc16 type,
+                                                         Label* on_no_match) {
+  // Range checks (c in min..max) are generally implemented by an unsigned
+  // (c - min) <= (max - min) check
+  switch (type) {
+    case 's':
+      // Match space-characters
+      if (mode_ == LATIN1) {
+        // One byte space characters are '\t'..'\r', ' ' and \u00a0.
+        Label success;
+        __ cmpi(current_character(), Operand(' '));
+        __ beq(&success);
+        // Check range 0x09..0x0d
+        __ subi(r3, current_character(), Operand('\t'));
+        __ cmpli(r3, Operand('\r' - '\t'));
+        __ ble(&success);
+        // \u00a0 (NBSP).
+        __ cmpi(r3, Operand(0x00a0 - '\t'));
+        BranchOrBacktrack(ne, on_no_match);
+        __ bind(&success);
+        return true;
+      }
+      return false;
+    case 'S':
+      // The emitted code for generic character classes is good enough.
+      return false;
+    case 'd':
+      // Match ASCII digits ('0'..'9')
+      __ subi(r3, current_character(), Operand('0'));
+      __ cmpli(r3, Operand('9' - '0'));
+      BranchOrBacktrack(gt, on_no_match);
+      return true;
+    case 'D':
+      // Match non ASCII-digits
+      __ subi(r3, current_character(), Operand('0'));
+      __ cmpli(r3, Operand('9' - '0'));
+      BranchOrBacktrack(le, on_no_match);
+      return true;
+    case '.': {
+      // Match non-newlines (not 0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029)
+      __ xori(r3, current_character(), Operand(0x01));
+      // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c
+      __ subi(r3, r3, Operand(0x0b));
+      __ cmpli(r3, Operand(0x0c - 0x0b));
+      BranchOrBacktrack(le, on_no_match);
+      if (mode_ == UC16) {
+        // Compare original value to 0x2028 and 0x2029, using the already
+        // computed (current_char ^ 0x01 - 0x0b). I.e., check for
+        // 0x201d (0x2028 - 0x0b) or 0x201e.
+        __ subi(r3, r3, Operand(0x2028 - 0x0b));
+        __ cmpli(r3, Operand(1));
+        BranchOrBacktrack(le, on_no_match);
+      }
+      return true;
+    }
+    case 'n': {
+      // Match newlines (0x0a('\n'), 0x0d('\r'), 0x2028 and 0x2029)
+      __ xori(r3, current_character(), Operand(0x01));
+      // See if current character is '\n'^1 or '\r'^1, i.e., 0x0b or 0x0c
+      __ subi(r3, r3, Operand(0x0b));
+      __ cmpli(r3, Operand(0x0c - 0x0b));
+      if (mode_ == LATIN1) {
+        BranchOrBacktrack(gt, on_no_match);
+      } else {
+        Label done;
+        __ ble(&done);
+        // Compare original value to 0x2028 and 0x2029, using the already
+        // computed (current_char ^ 0x01 - 0x0b). I.e., check for
+        // 0x201d (0x2028 - 0x0b) or 0x201e.
+        __ subi(r3, r3, Operand(0x2028 - 0x0b));
+        __ cmpli(r3, Operand(1));
+        BranchOrBacktrack(gt, on_no_match);
+        __ bind(&done);
+      }
+      return true;
+    }
+    case 'w': {
+      if (mode_ != LATIN1) {
+        // Table is 256 entries, so all Latin1 characters can be tested.
+        __ cmpi(current_character(), Operand('z'));
+        BranchOrBacktrack(gt, on_no_match);
+      }
+      ExternalReference map = ExternalReference::re_word_character_map();
+      __ mov(r3, Operand(map));
+      __ lbzx(r3, MemOperand(r3, current_character()));
+      __ cmpli(r3, Operand::Zero());
+      BranchOrBacktrack(eq, on_no_match);
+      return true;
+    }
+    case 'W': {
+      Label done;
+      if (mode_ != LATIN1) {
+        // Table is 256 entries, so all Latin1 characters can be tested.
+        __ cmpli(current_character(), Operand('z'));
+        __ bgt(&done);
+      }
+      ExternalReference map = ExternalReference::re_word_character_map();
+      __ mov(r3, Operand(map));
+      __ lbzx(r3, MemOperand(r3, current_character()));
+      __ cmpli(r3, Operand::Zero());
+      BranchOrBacktrack(ne, on_no_match);
+      if (mode_ != LATIN1) {
+        __ bind(&done);
+      }
+      return true;
+    }
+    case '*':
+      // Match any character.
+      return true;
+    // No custom implementation (yet): s(UC16), S(UC16).
+    default:
+      return false;
+  }
+}
+
+
+void RegExpMacroAssemblerPPC::Fail() {
+  __ li(r3, Operand(FAILURE));
+  __ b(&exit_label_);
+}
+
+
+Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
+  Label return_r3;
+
+  if (masm_->has_exception()) {
+    // If the code gets corrupted due to long regular expressions and lack of
+    // space on trampolines, an internal exception flag is set. If this case
+    // is detected, we will jump into exit sequence right away.
+    __ bind_to(&entry_label_, internal_failure_label_.pos());
+  } else {
+    // Finalize code - write the entry point code now we know how many
+    // registers we need.
+
+    // Entry code:
+    __ bind(&entry_label_);
+
+    // Tell the system that we have a stack frame.  Because the type
+    // is MANUAL, no is generated.
+    FrameScope scope(masm_, StackFrame::MANUAL);
+
+    // Ensure register assigments are consistent with callee save mask
+    DCHECK(r25.bit() & kRegExpCalleeSaved);
+    DCHECK(code_pointer().bit() & kRegExpCalleeSaved);
+    DCHECK(current_input_offset().bit() & kRegExpCalleeSaved);
+    DCHECK(current_character().bit() & kRegExpCalleeSaved);
+    DCHECK(backtrack_stackpointer().bit() & kRegExpCalleeSaved);
+    DCHECK(end_of_input_address().bit() & kRegExpCalleeSaved);
+    DCHECK(frame_pointer().bit() & kRegExpCalleeSaved);
+
+    // Actually emit code to start a new stack frame.
+    // Push arguments
+    // Save callee-save registers.
+    // Start new stack frame.
+    // Store link register in existing stack-cell.
+    // Order here should correspond to order of offset constants in header file.
+    RegList registers_to_retain = kRegExpCalleeSaved;
+    RegList argument_registers = r3.bit() | r4.bit() | r5.bit() | r6.bit() |
+                                 r7.bit() | r8.bit() | r9.bit() | r10.bit();
+    __ mflr(r0);
+    __ push(r0);
+    __ MultiPush(argument_registers | registers_to_retain);
+    // Set frame pointer in space for it if this is not a direct call
+    // from generated code.
+    __ addi(frame_pointer(), sp, Operand(8 * kPointerSize));
+    __ li(r3, Operand::Zero());
+    __ push(r3);  // Make room for success counter and initialize it to 0.
+    __ push(r3);  // Make room for "position - 1" constant (value is irrelevant)
+    // Check if we have space on the stack for registers.
+    Label stack_limit_hit;
+    Label stack_ok;
+
+    ExternalReference stack_limit =
+        ExternalReference::address_of_stack_limit(isolate());
+    __ mov(r3, Operand(stack_limit));
+    __ LoadP(r3, MemOperand(r3));
+    __ sub(r3, sp, r3, LeaveOE, SetRC);
+    // Handle it if the stack pointer is already below the stack limit.
+    __ ble(&stack_limit_hit, cr0);
+    // Check if there is room for the variable number of registers above
+    // the stack limit.
+    __ Cmpli(r3, Operand(num_registers_ * kPointerSize), r0);
+    __ bge(&stack_ok);
+    // Exit with OutOfMemory exception. There is not enough space on the stack
+    // for our working registers.
+    __ li(r3, Operand(EXCEPTION));
+    __ b(&return_r3);
+
+    __ bind(&stack_limit_hit);
+    CallCheckStackGuardState(r3);
+    __ cmpi(r3, Operand::Zero());
+    // If returned value is non-zero, we exit with the returned value as result.
+    __ bne(&return_r3);
+
+    __ bind(&stack_ok);
+
+    // Allocate space on stack for registers.
+    __ Add(sp, sp, -num_registers_ * kPointerSize, r0);
+    // Load string end.
+    __ LoadP(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
+    // Load input start.
+    __ LoadP(r3, MemOperand(frame_pointer(), kInputStart));
+    // Find negative length (offset of start relative to end).
+    __ sub(current_input_offset(), r3, end_of_input_address());
+    // Set r3 to address of char before start of the input string
+    // (effectively string position -1).
+    __ LoadP(r4, MemOperand(frame_pointer(), kStartIndex));
+    __ subi(r3, current_input_offset(), Operand(char_size()));
+    if (mode_ == UC16) {
+      __ ShiftLeftImm(r0, r4, Operand(1));
+      __ sub(r3, r3, r0);
+    } else {
+      __ sub(r3, r3, r4);
+    }
+    // Store this value in a local variable, for use when clearing
+    // position registers.
+    __ StoreP(r3, MemOperand(frame_pointer(), kInputStartMinusOne));
+
+    // Initialize code pointer register
+    __ mov(code_pointer(), Operand(masm_->CodeObject()));
+
+    Label load_char_start_regexp, start_regexp;
+    // Load newline if index is at start, previous character otherwise.
+    __ cmpi(r4, Operand::Zero());
+    __ bne(&load_char_start_regexp);
+    __ li(current_character(), Operand('\n'));
+    __ b(&start_regexp);
+
+    // Global regexp restarts matching here.
+    __ bind(&load_char_start_regexp);
+    // Load previous char as initial value of current character register.
+    LoadCurrentCharacterUnchecked(-1, 1);
+    __ bind(&start_regexp);
+
+    // Initialize on-stack registers.
+    if (num_saved_registers_ > 0) {  // Always is, if generated from a regexp.
+      // Fill saved registers with initial value = start offset - 1
+      if (num_saved_registers_ > 8) {
+        // One slot beyond address of register 0.
+        __ addi(r4, frame_pointer(), Operand(kRegisterZero + kPointerSize));
+        __ li(r5, Operand(num_saved_registers_));
+        __ mtctr(r5);
+        Label init_loop;
+        __ bind(&init_loop);
+        __ StorePU(r3, MemOperand(r4, -kPointerSize));
+        __ bdnz(&init_loop);
+      } else {
+        for (int i = 0; i < num_saved_registers_; i++) {
+          __ StoreP(r3, register_location(i), r0);
+        }
+      }
+    }
+
+    // Initialize backtrack stack pointer.
+    __ LoadP(backtrack_stackpointer(),
+             MemOperand(frame_pointer(), kStackHighEnd));
+
+    __ b(&start_label_);
+
+    // Exit code:
+    if (success_label_.is_linked()) {
+      // Save captures when successful.
+      __ bind(&success_label_);
+      if (num_saved_registers_ > 0) {
+        // copy captures to output
+        __ LoadP(r4, MemOperand(frame_pointer(), kInputStart));
+        __ LoadP(r3, MemOperand(frame_pointer(), kRegisterOutput));
+        __ LoadP(r5, MemOperand(frame_pointer(), kStartIndex));
+        __ sub(r4, end_of_input_address(), r4);
+        // r4 is length of input in bytes.
+        if (mode_ == UC16) {
+          __ ShiftRightImm(r4, r4, Operand(1));
+        }
+        // r4 is length of input in characters.
+        __ add(r4, r4, r5);
+        // r4 is length of string in characters.
+
+        DCHECK_EQ(0, num_saved_registers_ % 2);
+        // Always an even number of capture registers. This allows us to
+        // unroll the loop once to add an operation between a load of a register
+        // and the following use of that register.
+        for (int i = 0; i < num_saved_registers_; i += 2) {
+          __ LoadP(r5, register_location(i), r0);
+          __ LoadP(r6, register_location(i + 1), r0);
+          if (i == 0 && global_with_zero_length_check()) {
+            // Keep capture start in r25 for the zero-length check later.
+            __ mr(r25, r5);
+          }
+          if (mode_ == UC16) {
+            __ ShiftRightArithImm(r5, r5, 1);
+            __ add(r5, r4, r5);
+            __ ShiftRightArithImm(r6, r6, 1);
+            __ add(r6, r4, r6);
+          } else {
+            __ add(r5, r4, r5);
+            __ add(r6, r4, r6);
+          }
+          __ stw(r5, MemOperand(r3));
+          __ addi(r3, r3, Operand(kIntSize));
+          __ stw(r6, MemOperand(r3));
+          __ addi(r3, r3, Operand(kIntSize));
+        }
+      }
+
+      if (global()) {
+        // Restart matching if the regular expression is flagged as global.
+        __ LoadP(r3, MemOperand(frame_pointer(), kSuccessfulCaptures));
+        __ LoadP(r4, MemOperand(frame_pointer(), kNumOutputRegisters));
+        __ LoadP(r5, MemOperand(frame_pointer(), kRegisterOutput));
+        // Increment success counter.
+        __ addi(r3, r3, Operand(1));
+        __ StoreP(r3, MemOperand(frame_pointer(), kSuccessfulCaptures));
+        // Capture results have been stored, so the number of remaining global
+        // output registers is reduced by the number of stored captures.
+        __ subi(r4, r4, Operand(num_saved_registers_));
+        // Check whether we have enough room for another set of capture results.
+        __ cmpi(r4, Operand(num_saved_registers_));
+        __ blt(&return_r3);
+
+        __ StoreP(r4, MemOperand(frame_pointer(), kNumOutputRegisters));
+        // Advance the location for output.
+        __ addi(r5, r5, Operand(num_saved_registers_ * kIntSize));
+        __ StoreP(r5, MemOperand(frame_pointer(), kRegisterOutput));
+
+        // Prepare r3 to initialize registers with its value in the next run.
+        __ LoadP(r3, MemOperand(frame_pointer(), kInputStartMinusOne));
+
+        if (global_with_zero_length_check()) {
+          // Special case for zero-length matches.
+          // r25: capture start index
+          __ cmp(current_input_offset(), r25);
+          // Not a zero-length match, restart.
+          __ bne(&load_char_start_regexp);
+          // Offset from the end is zero if we already reached the end.
+          __ cmpi(current_input_offset(), Operand::Zero());
+          __ beq(&exit_label_);
+          // Advance current position after a zero-length match.
+          __ addi(current_input_offset(), current_input_offset(),
+                  Operand((mode_ == UC16) ? 2 : 1));
+        }
+
+        __ b(&load_char_start_regexp);
+      } else {
+        __ li(r3, Operand(SUCCESS));
+      }
+    }
+
+    // Exit and return r3
+    __ bind(&exit_label_);
+    if (global()) {
+      __ LoadP(r3, MemOperand(frame_pointer(), kSuccessfulCaptures));
+    }
+
+    __ bind(&return_r3);
+    // Skip sp past regexp registers and local variables..
+    __ mr(sp, frame_pointer());
+    // Restore registers r25..r31 and return (restoring lr to pc).
+    __ MultiPop(registers_to_retain);
+    __ pop(r0);
+    __ mtctr(r0);
+    __ bctr();
+
+    // Backtrack code (branch target for conditional backtracks).
+    if (backtrack_label_.is_linked()) {
+      __ bind(&backtrack_label_);
+      Backtrack();
+    }
+
+    Label exit_with_exception;
+
+    // Preempt-code
+    if (check_preempt_label_.is_linked()) {
+      SafeCallTarget(&check_preempt_label_);
+
+      CallCheckStackGuardState(r3);
+      __ cmpi(r3, Operand::Zero());
+      // If returning non-zero, we should end execution with the given
+      // result as return value.
+      __ bne(&return_r3);
+
+      // String might have moved: Reload end of string from frame.
+      __ LoadP(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd));
+      SafeReturn();
+    }
+
+    // Backtrack stack overflow code.
+    if (stack_overflow_label_.is_linked()) {
+      SafeCallTarget(&stack_overflow_label_);
+      // Reached if the backtrack-stack limit has been hit.
+      Label grow_failed;
+
+      // Call GrowStack(backtrack_stackpointer(), &stack_base)
+      static const int num_arguments = 3;
+      __ PrepareCallCFunction(num_arguments, r3);
+      __ mr(r3, backtrack_stackpointer());
+      __ addi(r4, frame_pointer(), Operand(kStackHighEnd));
+      __ mov(r5, Operand(ExternalReference::isolate_address(isolate())));
+      ExternalReference grow_stack =
+          ExternalReference::re_grow_stack(isolate());
+      __ CallCFunction(grow_stack, num_arguments);
+      // If return NULL, we have failed to grow the stack, and
+      // must exit with a stack-overflow exception.
+      __ cmpi(r3, Operand::Zero());
+      __ beq(&exit_with_exception);
+      // Otherwise use return value as new stack pointer.
+      __ mr(backtrack_stackpointer(), r3);
+      // Restore saved registers and continue.
+      SafeReturn();
+    }
+
+    if (exit_with_exception.is_linked()) {
+      // If any of the code above needed to exit with an exception.
+      __ bind(&exit_with_exception);
+      // Exit with Result EXCEPTION(-1) to signal thrown exception.
+      __ li(r3, Operand(EXCEPTION));
+      __ b(&return_r3);
+    }
+  }
+
+  CodeDesc code_desc;
+  masm_->GetCode(&code_desc);
+  Handle<Code> code = isolate()->factory()->NewCode(
+      code_desc, Code::ComputeFlags(Code::REGEXP), masm_->CodeObject());
+  PROFILE(masm_->isolate(), RegExpCodeCreateEvent(*code, *source));
+  return Handle<HeapObject>::cast(code);
+}
+
+
+void RegExpMacroAssemblerPPC::GoTo(Label* to) { BranchOrBacktrack(al, to); }
+
+
+void RegExpMacroAssemblerPPC::IfRegisterGE(int reg, int comparand,
+                                           Label* if_ge) {
+  __ LoadP(r3, register_location(reg), r0);
+  __ Cmpi(r3, Operand(comparand), r0);
+  BranchOrBacktrack(ge, if_ge);
+}
+
+
+void RegExpMacroAssemblerPPC::IfRegisterLT(int reg, int comparand,
+                                           Label* if_lt) {
+  __ LoadP(r3, register_location(reg), r0);
+  __ Cmpi(r3, Operand(comparand), r0);
+  BranchOrBacktrack(lt, if_lt);
+}
+
+
+void RegExpMacroAssemblerPPC::IfRegisterEqPos(int reg, Label* if_eq) {
+  __ LoadP(r3, register_location(reg), r0);
+  __ cmp(r3, current_input_offset());
+  BranchOrBacktrack(eq, if_eq);
+}
+
+
+RegExpMacroAssembler::IrregexpImplementation
+RegExpMacroAssemblerPPC::Implementation() {
+  return kPPCImplementation;
+}
+
+
+void RegExpMacroAssemblerPPC::LoadCurrentCharacter(int cp_offset,
+                                                   Label* on_end_of_input,
+                                                   bool check_bounds,
+                                                   int characters) {
+  DCHECK(cp_offset >= -1);        // ^ and \b can look behind one character.
+  DCHECK(cp_offset < (1 << 30));  // Be sane! (And ensure negation works)
+  if (check_bounds) {
+    CheckPosition(cp_offset + characters - 1, on_end_of_input);
+  }
+  LoadCurrentCharacterUnchecked(cp_offset, characters);
+}
+
+
+void RegExpMacroAssemblerPPC::PopCurrentPosition() {
+  Pop(current_input_offset());
+}
+
+
+void RegExpMacroAssemblerPPC::PopRegister(int register_index) {
+  Pop(r3);
+  __ StoreP(r3, register_location(register_index), r0);
+}
+
+
+void RegExpMacroAssemblerPPC::PushBacktrack(Label* label) {
+  __ mov_label_offset(r3, label);
+  Push(r3);
+  CheckStackLimit();
+}
+
+
+void RegExpMacroAssemblerPPC::PushCurrentPosition() {
+  Push(current_input_offset());
+}
+
+
+void RegExpMacroAssemblerPPC::PushRegister(int register_index,
+                                           StackCheckFlag check_stack_limit) {
+  __ LoadP(r3, register_location(register_index), r0);
+  Push(r3);
+  if (check_stack_limit) CheckStackLimit();
+}
+
+
+void RegExpMacroAssemblerPPC::ReadCurrentPositionFromRegister(int reg) {
+  __ LoadP(current_input_offset(), register_location(reg), r0);
+}
+
+
+void RegExpMacroAssemblerPPC::ReadStackPointerFromRegister(int reg) {
+  __ LoadP(backtrack_stackpointer(), register_location(reg), r0);
+  __ LoadP(r3, MemOperand(frame_pointer(), kStackHighEnd));
+  __ add(backtrack_stackpointer(), backtrack_stackpointer(), r3);
+}
+
+
+void RegExpMacroAssemblerPPC::SetCurrentPositionFromEnd(int by) {
+  Label after_position;
+  __ Cmpi(current_input_offset(), Operand(-by * char_size()), r0);
+  __ bge(&after_position);
+  __ mov(current_input_offset(), Operand(-by * char_size()));
+  // On RegExp code entry (where this operation is used), the character before
+  // the current position is expected to be already loaded.
+  // We have advanced the position, so it's safe to read backwards.
+  LoadCurrentCharacterUnchecked(-1, 1);
+  __ bind(&after_position);
+}
+
+
+void RegExpMacroAssemblerPPC::SetRegister(int register_index, int to) {
+  DCHECK(register_index >= num_saved_registers_);  // Reserved for positions!
+  __ mov(r3, Operand(to));
+  __ StoreP(r3, register_location(register_index), r0);
+}
+
+
+bool RegExpMacroAssemblerPPC::Succeed() {
+  __ b(&success_label_);
+  return global();
+}
+
+
+void RegExpMacroAssemblerPPC::WriteCurrentPositionToRegister(int reg,
+                                                             int cp_offset) {
+  if (cp_offset == 0) {
+    __ StoreP(current_input_offset(), register_location(reg), r0);
+  } else {
+    __ mov(r0, Operand(cp_offset * char_size()));
+    __ add(r3, current_input_offset(), r0);
+    __ StoreP(r3, register_location(reg), r0);
+  }
+}
+
+
+void RegExpMacroAssemblerPPC::ClearRegisters(int reg_from, int reg_to) {
+  DCHECK(reg_from <= reg_to);
+  __ LoadP(r3, MemOperand(frame_pointer(), kInputStartMinusOne));
+  for (int reg = reg_from; reg <= reg_to; reg++) {
+    __ StoreP(r3, register_location(reg), r0);
+  }
+}
+
+
+void RegExpMacroAssemblerPPC::WriteStackPointerToRegister(int reg) {
+  __ LoadP(r4, MemOperand(frame_pointer(), kStackHighEnd));
+  __ sub(r3, backtrack_stackpointer(), r4);
+  __ StoreP(r3, register_location(reg), r0);
+}
+
+
+// Private methods:
+
+void RegExpMacroAssemblerPPC::CallCheckStackGuardState(Register scratch) {
+  int frame_alignment = masm_->ActivationFrameAlignment();
+  int stack_space = kNumRequiredStackFrameSlots;
+  int stack_passed_arguments = 1;  // space for return address pointer
+
+  // The following stack manipulation logic is similar to
+  // PrepareCallCFunction.  However, we need an extra slot on the
+  // stack to house the return address parameter.
+  if (frame_alignment > kPointerSize) {
+    // Make stack end at alignment and make room for stack arguments
+    // -- preserving original value of sp.
+    __ mr(scratch, sp);
+    __ addi(sp, sp, Operand(-(stack_passed_arguments + 1) * kPointerSize));
+    DCHECK(base::bits::IsPowerOfTwo32(frame_alignment));
+    __ ClearRightImm(sp, sp, Operand(WhichPowerOf2(frame_alignment)));
+    __ StoreP(scratch, MemOperand(sp, stack_passed_arguments * kPointerSize));
+  } else {
+    // Make room for stack arguments
+    stack_space += stack_passed_arguments;
+  }
+
+  // Allocate frame with required slots to make ABI work.
+  __ li(r0, Operand::Zero());
+  __ StorePU(r0, MemOperand(sp, -stack_space * kPointerSize));
+
+  // RegExp code frame pointer.
+  __ mr(r5, frame_pointer());
+  // Code* of self.
+  __ mov(r4, Operand(masm_->CodeObject()));
+  // r3 will point to the return address, placed by DirectCEntry.
+  __ addi(r3, sp, Operand(kStackFrameExtraParamSlot * kPointerSize));
+
+  ExternalReference stack_guard_check =
+      ExternalReference::re_check_stack_guard_state(isolate());
+  __ mov(ip, Operand(stack_guard_check));
+  DirectCEntryStub stub(isolate());
+  stub.GenerateCall(masm_, ip);
+
+  // Restore the stack pointer
+  stack_space = kNumRequiredStackFrameSlots + stack_passed_arguments;
+  if (frame_alignment > kPointerSize) {
+    __ LoadP(sp, MemOperand(sp, stack_space * kPointerSize));
+  } else {
+    __ addi(sp, sp, Operand(stack_space * kPointerSize));
+  }
+
+  __ mov(code_pointer(), Operand(masm_->CodeObject()));
+}
+
+
+// Helper function for reading a value out of a stack frame.
+template <typename T>
+static T& frame_entry(Address re_frame, int frame_offset) {
+  return reinterpret_cast<T&>(Memory::int32_at(re_frame + frame_offset));
+}
+
+
+int RegExpMacroAssemblerPPC::CheckStackGuardState(Address* return_address,
+                                                  Code* re_code,
+                                                  Address re_frame) {
+  Isolate* isolate = frame_entry<Isolate*>(re_frame, kIsolate);
+  StackLimitCheck check(isolate);
+  if (check.JsHasOverflowed()) {
+    isolate->StackOverflow();
+    return EXCEPTION;
+  }
+
+  // If not real stack overflow the stack guard was used to interrupt
+  // execution for another purpose.
+
+  // If this is a direct call from JavaScript retry the RegExp forcing the call
+  // through the runtime system. Currently the direct call cannot handle a GC.
+  if (frame_entry<int>(re_frame, kDirectCall) == 1) {
+    return RETRY;
+  }
+
+  // Prepare for possible GC.
+  HandleScope handles(isolate);
+  Handle<Code> code_handle(re_code);
+
+  Handle<String> subject(frame_entry<String*>(re_frame, kInputString));
+
+  // Current string.
+  bool is_one_byte = subject->IsOneByteRepresentationUnderneath();
+
+  DCHECK(re_code->instruction_start() <= *return_address);
+  DCHECK(*return_address <=
+         re_code->instruction_start() + re_code->instruction_size());
+
+  Object* result = isolate->stack_guard()->HandleInterrupts();
+
+  if (*code_handle != re_code) {  // Return address no longer valid
+    intptr_t delta = code_handle->address() - re_code->address();
+    // Overwrite the return address on the stack.
+    *return_address += delta;
+  }
+
+  if (result->IsException()) {
+    return EXCEPTION;
+  }
+
+  Handle<String> subject_tmp = subject;
+  int slice_offset = 0;
+
+  // Extract the underlying string and the slice offset.
+  if (StringShape(*subject_tmp).IsCons()) {
+    subject_tmp = Handle<String>(ConsString::cast(*subject_tmp)->first());
+  } else if (StringShape(*subject_tmp).IsSliced()) {
+    SlicedString* slice = SlicedString::cast(*subject_tmp);
+    subject_tmp = Handle<String>(slice->parent());
+    slice_offset = slice->offset();
+  }
+
+  // String might have changed.
+  if (subject_tmp->IsOneByteRepresentation() != is_one_byte) {
+    // If we changed between an Latin1 and an UC16 string, the specialized
+    // code cannot be used, and we need to restart regexp matching from
+    // scratch (including, potentially, compiling a new version of the code).
+    return RETRY;
+  }
+
+  // Otherwise, the content of the string might have moved. It must still
+  // be a sequential or external string with the same content.
+  // Update the start and end pointers in the stack frame to the current
+  // location (whether it has actually moved or not).
+  DCHECK(StringShape(*subject_tmp).IsSequential() ||
+         StringShape(*subject_tmp).IsExternal());
+
+  // The original start address of the characters to match.
+  const byte* start_address = frame_entry<const byte*>(re_frame, kInputStart);
+
+  // Find the current start address of the same character at the current string
+  // position.
+  int start_index = frame_entry<intptr_t>(re_frame, kStartIndex);
+  const byte* new_address =
+      StringCharacterPosition(*subject_tmp, start_index + slice_offset);
+
+  if (start_address != new_address) {
+    // If there is a difference, update the object pointer and start and end
+    // addresses in the RegExp stack frame to match the new value.
+    const byte* end_address = frame_entry<const byte*>(re_frame, kInputEnd);
+    int byte_length = static_cast<int>(end_address - start_address);
+    frame_entry<const String*>(re_frame, kInputString) = *subject;
+    frame_entry<const byte*>(re_frame, kInputStart) = new_address;
+    frame_entry<const byte*>(re_frame, kInputEnd) = new_address + byte_length;
+  } else if (frame_entry<const String*>(re_frame, kInputString) != *subject) {
+    // Subject string might have been a ConsString that underwent
+    // short-circuiting during GC. That will not change start_address but
+    // will change pointer inside the subject handle.
+    frame_entry<const String*>(re_frame, kInputString) = *subject;
+  }
+
+  return 0;
+}
+
+
+MemOperand RegExpMacroAssemblerPPC::register_location(int register_index) {
+  DCHECK(register_index < (1 << 30));
+  if (num_registers_ <= register_index) {
+    num_registers_ = register_index + 1;
+  }
+  return MemOperand(frame_pointer(),
+                    kRegisterZero - register_index * kPointerSize);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckPosition(int cp_offset,
+                                            Label* on_outside_input) {
+  __ Cmpi(current_input_offset(), Operand(-cp_offset * char_size()), r0);
+  BranchOrBacktrack(ge, on_outside_input);
+}
+
+
+void RegExpMacroAssemblerPPC::BranchOrBacktrack(Condition condition, Label* to,
+                                                CRegister cr) {
+  if (condition == al) {  // Unconditional.
+    if (to == NULL) {
+      Backtrack();
+      return;
+    }
+    __ b(to);
+    return;
+  }
+  if (to == NULL) {
+    __ b(condition, &backtrack_label_, cr);
+    return;
+  }
+  __ b(condition, to, cr);
+}
+
+
+void RegExpMacroAssemblerPPC::SafeCall(Label* to, Condition cond,
+                                       CRegister cr) {
+  __ b(cond, to, cr, SetLK);
+}
+
+
+void RegExpMacroAssemblerPPC::SafeReturn() {
+  __ pop(r0);
+  __ mov(ip, Operand(masm_->CodeObject()));
+  __ add(r0, r0, ip);
+  __ mtlr(r0);
+  __ blr();
+}
+
+
+void RegExpMacroAssemblerPPC::SafeCallTarget(Label* name) {
+  __ bind(name);
+  __ mflr(r0);
+  __ mov(ip, Operand(masm_->CodeObject()));
+  __ sub(r0, r0, ip);
+  __ push(r0);
+}
+
+
+void RegExpMacroAssemblerPPC::Push(Register source) {
+  DCHECK(!source.is(backtrack_stackpointer()));
+  __ StorePU(source, MemOperand(backtrack_stackpointer(), -kPointerSize));
+}
+
+
+void RegExpMacroAssemblerPPC::Pop(Register target) {
+  DCHECK(!target.is(backtrack_stackpointer()));
+  __ LoadP(target, MemOperand(backtrack_stackpointer()));
+  __ addi(backtrack_stackpointer(), backtrack_stackpointer(),
+          Operand(kPointerSize));
+}
+
+
+void RegExpMacroAssemblerPPC::CheckPreemption() {
+  // Check for preemption.
+  ExternalReference stack_limit =
+      ExternalReference::address_of_stack_limit(isolate());
+  __ mov(r3, Operand(stack_limit));
+  __ LoadP(r3, MemOperand(r3));
+  __ cmpl(sp, r3);
+  SafeCall(&check_preempt_label_, le);
+}
+
+
+void RegExpMacroAssemblerPPC::CheckStackLimit() {
+  ExternalReference stack_limit =
+      ExternalReference::address_of_regexp_stack_limit(isolate());
+  __ mov(r3, Operand(stack_limit));
+  __ LoadP(r3, MemOperand(r3));
+  __ cmpl(backtrack_stackpointer(), r3);
+  SafeCall(&stack_overflow_label_, le);
+}
+
+
+bool RegExpMacroAssemblerPPC::CanReadUnaligned() {
+  return CpuFeatures::IsSupported(UNALIGNED_ACCESSES) && !slow_safe();
+}
+
+
+void RegExpMacroAssemblerPPC::LoadCurrentCharacterUnchecked(int cp_offset,
+                                                            int characters) {
+  Register offset = current_input_offset();
+  if (cp_offset != 0) {
+    // r25 is not being used to store the capture start index at this point.
+    __ addi(r25, current_input_offset(), Operand(cp_offset * char_size()));
+    offset = r25;
+  }
+  // The lwz, stw, lhz, sth instructions can do unaligned accesses, if the CPU
+  // and the operating system running on the target allow it.
+  // We assume we don't want to do unaligned loads on PPC, so this function
+  // must only be used to load a single character at a time.
+
+  DCHECK(characters == 1);
+  __ add(current_character(), end_of_input_address(), offset);
+  if (mode_ == LATIN1) {
+    __ lbz(current_character(), MemOperand(current_character()));
+  } else {
+    DCHECK(mode_ == UC16);
+    __ lhz(current_character(), MemOperand(current_character()));
+  }
+}
+
+
+#undef __
+
+#endif  // V8_INTERPRETED_REGEXP
+}
+}  // namespace v8::internal
+
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/regexp-macro-assembler-ppc.h b/src/ppc/regexp-macro-assembler-ppc.h
new file mode 100644
index 0000000..1f9c3a0
--- /dev/null
+++ b/src/ppc/regexp-macro-assembler-ppc.h
@@ -0,0 +1,212 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_PPC_REGEXP_MACRO_ASSEMBLER_PPC_H_
+#define V8_PPC_REGEXP_MACRO_ASSEMBLER_PPC_H_
+
+#include "src/macro-assembler.h"
+#include "src/ppc/assembler-ppc.h"
+#include "src/ppc/assembler-ppc-inl.h"
+
+namespace v8 {
+namespace internal {
+
+
+#ifndef V8_INTERPRETED_REGEXP
+class RegExpMacroAssemblerPPC : public NativeRegExpMacroAssembler {
+ public:
+  RegExpMacroAssemblerPPC(Mode mode, int registers_to_save, Zone* zone);
+  virtual ~RegExpMacroAssemblerPPC();
+  virtual int stack_limit_slack();
+  virtual void AdvanceCurrentPosition(int by);
+  virtual void AdvanceRegister(int reg, int by);
+  virtual void Backtrack();
+  virtual void Bind(Label* label);
+  virtual void CheckAtStart(Label* on_at_start);
+  virtual void CheckCharacter(unsigned c, Label* on_equal);
+  virtual void CheckCharacterAfterAnd(unsigned c, unsigned mask,
+                                      Label* on_equal);
+  virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
+  virtual void CheckCharacterLT(uc16 limit, Label* on_less);
+  // A "greedy loop" is a loop that is both greedy and with a simple
+  // body. It has a particularly simple implementation.
+  virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
+  virtual void CheckNotAtStart(Label* on_not_at_start);
+  virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
+  virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
+                                               Label* on_no_match);
+  virtual void CheckNotCharacter(unsigned c, Label* on_not_equal);
+  virtual void CheckNotCharacterAfterAnd(unsigned c, unsigned mask,
+                                         Label* on_not_equal);
+  virtual void CheckNotCharacterAfterMinusAnd(uc16 c, 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);
+  virtual bool CheckSpecialCharacterClass(uc16 type, Label* on_no_match);
+  virtual void Fail();
+  virtual Handle<HeapObject> GetCode(Handle<String> source);
+  virtual void GoTo(Label* label);
+  virtual void IfRegisterGE(int reg, int comparand, Label* if_ge);
+  virtual void IfRegisterLT(int reg, int comparand, Label* if_lt);
+  virtual void IfRegisterEqPos(int reg, Label* if_eq);
+  virtual IrregexpImplementation Implementation();
+  virtual void LoadCurrentCharacter(int cp_offset, Label* on_end_of_input,
+                                    bool check_bounds = true,
+                                    int characters = 1);
+  virtual void PopCurrentPosition();
+  virtual void PopRegister(int register_index);
+  virtual void PushBacktrack(Label* label);
+  virtual void PushCurrentPosition();
+  virtual void PushRegister(int register_index,
+                            StackCheckFlag check_stack_limit);
+  virtual void ReadCurrentPositionFromRegister(int reg);
+  virtual void ReadStackPointerFromRegister(int reg);
+  virtual void SetCurrentPositionFromEnd(int by);
+  virtual void SetRegister(int register_index, int to);
+  virtual bool Succeed();
+  virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
+  virtual void ClearRegisters(int reg_from, int reg_to);
+  virtual void WriteStackPointerToRegister(int reg);
+  virtual bool CanReadUnaligned();
+
+  // Called from RegExp if the stack-guard is triggered.
+  // If the code object is relocated, the return address is fixed before
+  // returning.
+  static int CheckStackGuardState(Address* return_address, Code* re_code,
+                                  Address re_frame);
+
+ private:
+  // Offsets from frame_pointer() of function parameters and stored registers.
+  static const int kFramePointer = 0;
+
+  // Above the frame pointer - Stored registers and stack passed parameters.
+  // Register 25..31.
+  static const int kStoredRegisters = kFramePointer;
+  // Return address (stored from link register, read into pc on return).
+  static const int kReturnAddress = kStoredRegisters + 7 * kPointerSize;
+  static const int kCallerFrame = kReturnAddress + kPointerSize;
+  // Stack parameters placed by caller.
+  static const int kSecondaryReturnAddress =
+      kCallerFrame + kStackFrameExtraParamSlot * kPointerSize;
+  static const int kIsolate = kSecondaryReturnAddress + kPointerSize;
+
+  // Below the frame pointer.
+  // Register parameters stored by setup code.
+  static const int kDirectCall = kFramePointer - kPointerSize;
+  static const int kStackHighEnd = kDirectCall - kPointerSize;
+  static const int kNumOutputRegisters = kStackHighEnd - kPointerSize;
+  static const int kRegisterOutput = kNumOutputRegisters - kPointerSize;
+  static const int kInputEnd = kRegisterOutput - kPointerSize;
+  static const int kInputStart = kInputEnd - kPointerSize;
+  static const int kStartIndex = kInputStart - kPointerSize;
+  static const int kInputString = kStartIndex - kPointerSize;
+  // When adding local variables remember to push space for them in
+  // the frame in GetCode.
+  static const int kSuccessfulCaptures = kInputString - kPointerSize;
+  static const int kInputStartMinusOne = kSuccessfulCaptures - kPointerSize;
+  // First register address. Following registers are below it on the stack.
+  static const int kRegisterZero = kInputStartMinusOne - kPointerSize;
+
+  // Initial size of code buffer.
+  static const size_t kRegExpCodeSize = 1024;
+
+  // Load a number of characters at the given offset from the
+  // current position, into the current-character register.
+  void LoadCurrentCharacterUnchecked(int cp_offset, int character_count);
+
+  // Check whether preemption has been requested.
+  void CheckPreemption();
+
+  // Check whether we are exceeding the stack limit on the backtrack stack.
+  void CheckStackLimit();
+
+
+  // Generate a call to CheckStackGuardState.
+  void CallCheckStackGuardState(Register scratch);
+
+  // The ebp-relative location of a regexp register.
+  MemOperand register_location(int register_index);
+
+  // Register holding the current input position as negative offset from
+  // the end of the string.
+  inline Register current_input_offset() { return r27; }
+
+  // The register containing the current character after LoadCurrentCharacter.
+  inline Register current_character() { return r28; }
+
+  // Register holding address of the end of the input string.
+  inline Register end_of_input_address() { return r30; }
+
+  // Register holding the frame address. Local variables, parameters and
+  // regexp registers are addressed relative to this.
+  inline Register frame_pointer() { return fp; }
+
+  // The register containing the backtrack stack top. Provides a meaningful
+  // name to the register.
+  inline Register backtrack_stackpointer() { return r29; }
+
+  // Register holding pointer to the current code object.
+  inline Register code_pointer() { return r26; }
+
+  // Byte size of chars in the string to match (decided by the Mode argument)
+  inline int char_size() { return static_cast<int>(mode_); }
+
+  // Equivalent to a conditional branch to the label, unless the label
+  // is NULL, in which case it is a conditional Backtrack.
+  void BranchOrBacktrack(Condition condition, Label* to, CRegister cr = cr7);
+
+  // Call and return internally in the generated code in a way that
+  // is GC-safe (i.e., doesn't leave absolute code addresses on the stack)
+  inline void SafeCall(Label* to, Condition cond = al, CRegister cr = cr7);
+  inline void SafeReturn();
+  inline void SafeCallTarget(Label* name);
+
+  // Pushes the value of a register on the backtrack stack. Decrements the
+  // stack pointer by a word size and stores the register's value there.
+  inline void Push(Register source);
+
+  // Pops a value from the backtrack stack. Reads the word at the stack pointer
+  // and increments it by a word size.
+  inline void Pop(Register target);
+
+  Isolate* isolate() const { return masm_->isolate(); }
+
+  MacroAssembler* masm_;
+
+  // Which mode to generate code for (Latin1 or UC16).
+  Mode mode_;
+
+  // One greater than maximal register index actually used.
+  int num_registers_;
+
+  // Number of registers to output at the end (the saved registers
+  // are always 0..num_saved_registers_-1)
+  int num_saved_registers_;
+
+  // Labels used internally.
+  Label entry_label_;
+  Label start_label_;
+  Label success_label_;
+  Label backtrack_label_;
+  Label exit_label_;
+  Label check_preempt_label_;
+  Label stack_overflow_label_;
+  Label internal_failure_label_;
+};
+
+// Set of non-volatile registers saved/restored by generated regexp code.
+const RegList kRegExpCalleeSaved =
+    1 << 25 | 1 << 26 | 1 << 27 | 1 << 28 | 1 << 29 | 1 << 30 | 1 << 31;
+
+#endif  // V8_INTERPRETED_REGEXP
+}
+}  // namespace v8::internal
+
+#endif  // V8_PPC_REGEXP_MACRO_ASSEMBLER_PPC_H_
diff --git a/src/ppc/simulator-ppc.cc b/src/ppc/simulator-ppc.cc
new file mode 100644
index 0000000..0d10153
--- /dev/null
+++ b/src/ppc/simulator-ppc.cc
@@ -0,0 +1,3803 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <cmath>
+
+#include "src/v8.h"
+
+#if V8_TARGET_ARCH_PPC
+
+#include "src/assembler.h"
+#include "src/codegen.h"
+#include "src/disasm.h"
+#include "src/ppc/constants-ppc.h"
+#include "src/ppc/frames-ppc.h"
+#include "src/ppc/simulator-ppc.h"
+
+#if defined(USE_SIMULATOR)
+
+// Only build the simulator if not compiling for real PPC hardware.
+namespace v8 {
+namespace internal {
+
+// This macro provides a platform independent use of sscanf. The reason for
+// SScanF not being implemented in a platform independent way through
+// ::v8::internal::OS in the same way as SNPrintF is that the
+// Windows C Run-Time Library does not provide vsscanf.
+#define SScanF sscanf  // NOLINT
+
+// The PPCDebugger class is used by the simulator while debugging simulated
+// PowerPC code.
+class PPCDebugger {
+ public:
+  explicit PPCDebugger(Simulator* sim) : sim_(sim) {}
+  ~PPCDebugger();
+
+  void Stop(Instruction* instr);
+  void Info(Instruction* instr);
+  void Debug();
+
+ private:
+  static const Instr kBreakpointInstr = (TWI | 0x1f * B21);
+  static const Instr kNopInstr = (ORI);  // ori, 0,0,0
+
+  Simulator* sim_;
+
+  intptr_t GetRegisterValue(int regnum);
+  double GetRegisterPairDoubleValue(int regnum);
+  double GetFPDoubleRegisterValue(int regnum);
+  bool GetValue(const char* desc, intptr_t* value);
+  bool GetFPDoubleValue(const char* desc, double* value);
+
+  // Set or delete a breakpoint. Returns true if successful.
+  bool SetBreakpoint(Instruction* break_pc);
+  bool DeleteBreakpoint(Instruction* break_pc);
+
+  // Undo and redo all breakpoints. This is needed to bracket disassembly and
+  // execution to skip past breakpoints when run from the debugger.
+  void UndoBreakpoints();
+  void RedoBreakpoints();
+};
+
+
+PPCDebugger::~PPCDebugger() {}
+
+
+#ifdef GENERATED_CODE_COVERAGE
+static FILE* coverage_log = NULL;
+
+
+static void InitializeCoverage() {
+  char* file_name = getenv("V8_GENERATED_CODE_COVERAGE_LOG");
+  if (file_name != NULL) {
+    coverage_log = fopen(file_name, "aw+");
+  }
+}
+
+
+void PPCDebugger::Stop(Instruction* instr) {
+  // Get the stop code.
+  uint32_t code = instr->SvcValue() & kStopCodeMask;
+  // Retrieve the encoded address, which comes just after this stop.
+  char** msg_address =
+      reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize);
+  char* msg = *msg_address;
+  DCHECK(msg != NULL);
+
+  // Update this stop description.
+  if (isWatchedStop(code) && !watched_stops_[code].desc) {
+    watched_stops_[code].desc = msg;
+  }
+
+  if (strlen(msg) > 0) {
+    if (coverage_log != NULL) {
+      fprintf(coverage_log, "%s\n", msg);
+      fflush(coverage_log);
+    }
+    // Overwrite the instruction and address with nops.
+    instr->SetInstructionBits(kNopInstr);
+    reinterpret_cast<Instruction*>(msg_address)->SetInstructionBits(kNopInstr);
+  }
+  sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize);
+}
+
+#else  // ndef GENERATED_CODE_COVERAGE
+
+static void InitializeCoverage() {}
+
+
+void PPCDebugger::Stop(Instruction* instr) {
+  // Get the stop code.
+  // use of kStopCodeMask not right on PowerPC
+  uint32_t code = instr->SvcValue() & kStopCodeMask;
+  // Retrieve the encoded address, which comes just after this stop.
+  char* msg =
+      *reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize);
+  // Update this stop description.
+  if (sim_->isWatchedStop(code) && !sim_->watched_stops_[code].desc) {
+    sim_->watched_stops_[code].desc = msg;
+  }
+  // Print the stop message and code if it is not the default code.
+  if (code != kMaxStopCode) {
+    PrintF("Simulator hit stop %u: %s\n", code, msg);
+  } else {
+    PrintF("Simulator hit %s\n", msg);
+  }
+  sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize);
+  Debug();
+}
+#endif
+
+
+void PPCDebugger::Info(Instruction* instr) {
+  // Retrieve the encoded address immediately following the Info breakpoint.
+  char* msg =
+      *reinterpret_cast<char**>(sim_->get_pc() + Instruction::kInstrSize);
+  PrintF("Simulator info %s\n", msg);
+  sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize + kPointerSize);
+}
+
+
+intptr_t PPCDebugger::GetRegisterValue(int regnum) {
+  return sim_->get_register(regnum);
+}
+
+
+double PPCDebugger::GetRegisterPairDoubleValue(int regnum) {
+  return sim_->get_double_from_register_pair(regnum);
+}
+
+
+double PPCDebugger::GetFPDoubleRegisterValue(int regnum) {
+  return sim_->get_double_from_d_register(regnum);
+}
+
+
+bool PPCDebugger::GetValue(const char* desc, intptr_t* value) {
+  int regnum = Registers::Number(desc);
+  if (regnum != kNoRegister) {
+    *value = GetRegisterValue(regnum);
+    return true;
+  } else {
+    if (strncmp(desc, "0x", 2) == 0) {
+      return SScanF(desc + 2, "%" V8PRIxPTR,
+                    reinterpret_cast<uintptr_t*>(value)) == 1;
+    } else {
+      return SScanF(desc, "%" V8PRIuPTR, reinterpret_cast<uintptr_t*>(value)) ==
+             1;
+    }
+  }
+  return false;
+}
+
+
+bool PPCDebugger::GetFPDoubleValue(const char* desc, double* value) {
+  int regnum = FPRegisters::Number(desc);
+  if (regnum != kNoRegister) {
+    *value = sim_->get_double_from_d_register(regnum);
+    return true;
+  }
+  return false;
+}
+
+
+bool PPCDebugger::SetBreakpoint(Instruction* break_pc) {
+  // Check if a breakpoint can be set. If not return without any side-effects.
+  if (sim_->break_pc_ != NULL) {
+    return false;
+  }
+
+  // Set the breakpoint.
+  sim_->break_pc_ = break_pc;
+  sim_->break_instr_ = break_pc->InstructionBits();
+  // Not setting the breakpoint instruction in the code itself. It will be set
+  // when the debugger shell continues.
+  return true;
+}
+
+
+bool PPCDebugger::DeleteBreakpoint(Instruction* break_pc) {
+  if (sim_->break_pc_ != NULL) {
+    sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
+  }
+
+  sim_->break_pc_ = NULL;
+  sim_->break_instr_ = 0;
+  return true;
+}
+
+
+void PPCDebugger::UndoBreakpoints() {
+  if (sim_->break_pc_ != NULL) {
+    sim_->break_pc_->SetInstructionBits(sim_->break_instr_);
+  }
+}
+
+
+void PPCDebugger::RedoBreakpoints() {
+  if (sim_->break_pc_ != NULL) {
+    sim_->break_pc_->SetInstructionBits(kBreakpointInstr);
+  }
+}
+
+
+void PPCDebugger::Debug() {
+  intptr_t last_pc = -1;
+  bool done = false;
+
+#define COMMAND_SIZE 63
+#define ARG_SIZE 255
+
+#define STR(a) #a
+#define XSTR(a) STR(a)
+
+  char cmd[COMMAND_SIZE + 1];
+  char arg1[ARG_SIZE + 1];
+  char arg2[ARG_SIZE + 1];
+  char* argv[3] = {cmd, arg1, arg2};
+
+  // make sure to have a proper terminating character if reaching the limit
+  cmd[COMMAND_SIZE] = 0;
+  arg1[ARG_SIZE] = 0;
+  arg2[ARG_SIZE] = 0;
+
+  // Undo all set breakpoints while running in the debugger shell. This will
+  // make them invisible to all commands.
+  UndoBreakpoints();
+  // Disable tracing while simulating
+  bool trace = ::v8::internal::FLAG_trace_sim;
+  ::v8::internal::FLAG_trace_sim = false;
+
+  while (!done && !sim_->has_bad_pc()) {
+    if (last_pc != sim_->get_pc()) {
+      disasm::NameConverter converter;
+      disasm::Disassembler dasm(converter);
+      // use a reasonably large buffer
+      v8::internal::EmbeddedVector<char, 256> buffer;
+      dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(sim_->get_pc()));
+      PrintF("  0x%08" V8PRIxPTR "  %s\n", sim_->get_pc(), buffer.start());
+      last_pc = sim_->get_pc();
+    }
+    char* line = ReadLine("sim> ");
+    if (line == NULL) {
+      break;
+    } else {
+      char* last_input = sim_->last_debugger_input();
+      if (strcmp(line, "\n") == 0 && last_input != NULL) {
+        line = last_input;
+      } else {
+        // Ownership is transferred to sim_;
+        sim_->set_last_debugger_input(line);
+      }
+      // Use sscanf to parse the individual parts of the command line. At the
+      // moment no command expects more than two parameters.
+      int argc = SScanF(line,
+                        "%" XSTR(COMMAND_SIZE) "s "
+                        "%" XSTR(ARG_SIZE) "s "
+                        "%" XSTR(ARG_SIZE) "s",
+                        cmd, arg1, arg2);
+      if ((strcmp(cmd, "si") == 0) || (strcmp(cmd, "stepi") == 0)) {
+        intptr_t value;
+
+        // If at a breakpoint, proceed past it.
+        if ((reinterpret_cast<Instruction*>(sim_->get_pc()))
+                ->InstructionBits() == 0x7d821008) {
+          sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize);
+        } else {
+          sim_->ExecuteInstruction(
+              reinterpret_cast<Instruction*>(sim_->get_pc()));
+        }
+
+        if (argc == 2 && last_pc != sim_->get_pc() && GetValue(arg1, &value)) {
+          for (int i = 1; i < value; i++) {
+            disasm::NameConverter converter;
+            disasm::Disassembler dasm(converter);
+            // use a reasonably large buffer
+            v8::internal::EmbeddedVector<char, 256> buffer;
+            dasm.InstructionDecode(buffer,
+                                   reinterpret_cast<byte*>(sim_->get_pc()));
+            PrintF("  0x%08" V8PRIxPTR "  %s\n", sim_->get_pc(),
+                   buffer.start());
+            sim_->ExecuteInstruction(
+                reinterpret_cast<Instruction*>(sim_->get_pc()));
+          }
+        }
+      } else if ((strcmp(cmd, "c") == 0) || (strcmp(cmd, "cont") == 0)) {
+        // If at a breakpoint, proceed past it.
+        if ((reinterpret_cast<Instruction*>(sim_->get_pc()))
+                ->InstructionBits() == 0x7d821008) {
+          sim_->set_pc(sim_->get_pc() + Instruction::kInstrSize);
+        } else {
+          // Execute the one instruction we broke at with breakpoints disabled.
+          sim_->ExecuteInstruction(
+              reinterpret_cast<Instruction*>(sim_->get_pc()));
+        }
+        // Leave the debugger shell.
+        done = true;
+      } else if ((strcmp(cmd, "p") == 0) || (strcmp(cmd, "print") == 0)) {
+        if (argc == 2 || (argc == 3 && strcmp(arg2, "fp") == 0)) {
+          intptr_t value;
+          double dvalue;
+          if (strcmp(arg1, "all") == 0) {
+            for (int i = 0; i < kNumRegisters; i++) {
+              value = GetRegisterValue(i);
+              PrintF("    %3s: %08" V8PRIxPTR, Registers::Name(i), value);
+              if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
+                  (i % 2) == 0) {
+                dvalue = GetRegisterPairDoubleValue(i);
+                PrintF(" (%f)\n", dvalue);
+              } else if (i != 0 && !((i + 1) & 3)) {
+                PrintF("\n");
+              }
+            }
+            PrintF("  pc: %08" V8PRIxPTR "  lr: %08" V8PRIxPTR
+                   "  "
+                   "ctr: %08" V8PRIxPTR "  xer: %08x  cr: %08x\n",
+                   sim_->special_reg_pc_, sim_->special_reg_lr_,
+                   sim_->special_reg_ctr_, sim_->special_reg_xer_,
+                   sim_->condition_reg_);
+          } else if (strcmp(arg1, "alld") == 0) {
+            for (int i = 0; i < kNumRegisters; i++) {
+              value = GetRegisterValue(i);
+              PrintF("     %3s: %08" V8PRIxPTR " %11" V8PRIdPTR,
+                     Registers::Name(i), value, value);
+              if ((argc == 3 && strcmp(arg2, "fp") == 0) && i < 8 &&
+                  (i % 2) == 0) {
+                dvalue = GetRegisterPairDoubleValue(i);
+                PrintF(" (%f)\n", dvalue);
+              } else if (!((i + 1) % 2)) {
+                PrintF("\n");
+              }
+            }
+            PrintF("   pc: %08" V8PRIxPTR "  lr: %08" V8PRIxPTR
+                   "  "
+                   "ctr: %08" V8PRIxPTR "  xer: %08x  cr: %08x\n",
+                   sim_->special_reg_pc_, sim_->special_reg_lr_,
+                   sim_->special_reg_ctr_, sim_->special_reg_xer_,
+                   sim_->condition_reg_);
+          } else if (strcmp(arg1, "allf") == 0) {
+            for (int i = 0; i < DoubleRegister::kNumRegisters; i++) {
+              dvalue = GetFPDoubleRegisterValue(i);
+              uint64_t as_words = bit_cast<uint64_t>(dvalue);
+              PrintF("%3s: %f 0x%08x %08x\n", FPRegisters::Name(i), dvalue,
+                     static_cast<uint32_t>(as_words >> 32),
+                     static_cast<uint32_t>(as_words & 0xffffffff));
+            }
+          } else if (arg1[0] == 'r' &&
+                     (arg1[1] >= '0' && arg1[1] <= '9' &&
+                      (arg1[2] == '\0' || (arg1[2] >= '0' && arg1[2] <= '9' &&
+                                           arg1[3] == '\0')))) {
+            int regnum = strtoul(&arg1[1], 0, 10);
+            if (regnum != kNoRegister) {
+              value = GetRegisterValue(regnum);
+              PrintF("%s: 0x%08" V8PRIxPTR " %" V8PRIdPTR "\n", arg1, value,
+                     value);
+            } else {
+              PrintF("%s unrecognized\n", arg1);
+            }
+          } else {
+            if (GetValue(arg1, &value)) {
+              PrintF("%s: 0x%08" V8PRIxPTR " %" V8PRIdPTR "\n", arg1, value,
+                     value);
+            } else if (GetFPDoubleValue(arg1, &dvalue)) {
+              uint64_t as_words = bit_cast<uint64_t>(dvalue);
+              PrintF("%s: %f 0x%08x %08x\n", arg1, dvalue,
+                     static_cast<uint32_t>(as_words >> 32),
+                     static_cast<uint32_t>(as_words & 0xffffffff));
+            } else {
+              PrintF("%s unrecognized\n", arg1);
+            }
+          }
+        } else {
+          PrintF("print <register>\n");
+        }
+      } else if ((strcmp(cmd, "po") == 0) ||
+                 (strcmp(cmd, "printobject") == 0)) {
+        if (argc == 2) {
+          intptr_t value;
+          OFStream os(stdout);
+          if (GetValue(arg1, &value)) {
+            Object* obj = reinterpret_cast<Object*>(value);
+            os << arg1 << ": \n";
+#ifdef DEBUG
+            obj->Print(os);
+            os << "\n";
+#else
+            os << Brief(obj) << "\n";
+#endif
+          } else {
+            os << arg1 << " unrecognized\n";
+          }
+        } else {
+          PrintF("printobject <value>\n");
+        }
+      } else if (strcmp(cmd, "setpc") == 0) {
+        intptr_t value;
+
+        if (!GetValue(arg1, &value)) {
+          PrintF("%s unrecognized\n", arg1);
+          continue;
+        }
+        sim_->set_pc(value);
+      } else if (strcmp(cmd, "stack") == 0 || strcmp(cmd, "mem") == 0) {
+        intptr_t* cur = NULL;
+        intptr_t* end = NULL;
+        int next_arg = 1;
+
+        if (strcmp(cmd, "stack") == 0) {
+          cur = reinterpret_cast<intptr_t*>(sim_->get_register(Simulator::sp));
+        } else {  // "mem"
+          intptr_t value;
+          if (!GetValue(arg1, &value)) {
+            PrintF("%s unrecognized\n", arg1);
+            continue;
+          }
+          cur = reinterpret_cast<intptr_t*>(value);
+          next_arg++;
+        }
+
+        intptr_t words;  // likely inaccurate variable name for 64bit
+        if (argc == next_arg) {
+          words = 10;
+        } else {
+          if (!GetValue(argv[next_arg], &words)) {
+            words = 10;
+          }
+        }
+        end = cur + words;
+
+        while (cur < end) {
+          PrintF("  0x%08" V8PRIxPTR ":  0x%08" V8PRIxPTR " %10" V8PRIdPTR,
+                 reinterpret_cast<intptr_t>(cur), *cur, *cur);
+          HeapObject* obj = reinterpret_cast<HeapObject*>(*cur);
+          intptr_t value = *cur;
+          Heap* current_heap = v8::internal::Isolate::Current()->heap();
+          if (((value & 1) == 0) || current_heap->Contains(obj)) {
+            PrintF(" (");
+            if ((value & 1) == 0) {
+              PrintF("smi %d", PlatformSmiTagging::SmiToInt(obj));
+            } else {
+              obj->ShortPrint();
+            }
+            PrintF(")");
+          }
+          PrintF("\n");
+          cur++;
+        }
+      } else if (strcmp(cmd, "disasm") == 0 || strcmp(cmd, "di") == 0) {
+        disasm::NameConverter converter;
+        disasm::Disassembler dasm(converter);
+        // use a reasonably large buffer
+        v8::internal::EmbeddedVector<char, 256> buffer;
+
+        byte* prev = NULL;
+        byte* cur = NULL;
+        byte* end = NULL;
+
+        if (argc == 1) {
+          cur = reinterpret_cast<byte*>(sim_->get_pc());
+          end = cur + (10 * Instruction::kInstrSize);
+        } else if (argc == 2) {
+          int regnum = Registers::Number(arg1);
+          if (regnum != kNoRegister || strncmp(arg1, "0x", 2) == 0) {
+            // The argument is an address or a register name.
+            intptr_t value;
+            if (GetValue(arg1, &value)) {
+              cur = reinterpret_cast<byte*>(value);
+              // Disassemble 10 instructions at <arg1>.
+              end = cur + (10 * Instruction::kInstrSize);
+            }
+          } else {
+            // The argument is the number of instructions.
+            intptr_t value;
+            if (GetValue(arg1, &value)) {
+              cur = reinterpret_cast<byte*>(sim_->get_pc());
+              // Disassemble <arg1> instructions.
+              end = cur + (value * Instruction::kInstrSize);
+            }
+          }
+        } else {
+          intptr_t value1;
+          intptr_t value2;
+          if (GetValue(arg1, &value1) && GetValue(arg2, &value2)) {
+            cur = reinterpret_cast<byte*>(value1);
+            end = cur + (value2 * Instruction::kInstrSize);
+          }
+        }
+
+        while (cur < end) {
+          prev = cur;
+          cur += dasm.InstructionDecode(buffer, cur);
+          PrintF("  0x%08" V8PRIxPTR "  %s\n", reinterpret_cast<intptr_t>(prev),
+                 buffer.start());
+        }
+      } else if (strcmp(cmd, "gdb") == 0) {
+        PrintF("relinquishing control to gdb\n");
+        v8::base::OS::DebugBreak();
+        PrintF("regaining control from gdb\n");
+      } else if (strcmp(cmd, "break") == 0) {
+        if (argc == 2) {
+          intptr_t value;
+          if (GetValue(arg1, &value)) {
+            if (!SetBreakpoint(reinterpret_cast<Instruction*>(value))) {
+              PrintF("setting breakpoint failed\n");
+            }
+          } else {
+            PrintF("%s unrecognized\n", arg1);
+          }
+        } else {
+          PrintF("break <address>\n");
+        }
+      } else if (strcmp(cmd, "del") == 0) {
+        if (!DeleteBreakpoint(NULL)) {
+          PrintF("deleting breakpoint failed\n");
+        }
+      } else if (strcmp(cmd, "cr") == 0) {
+        PrintF("Condition reg: %08x\n", sim_->condition_reg_);
+      } else if (strcmp(cmd, "lr") == 0) {
+        PrintF("Link reg: %08" V8PRIxPTR "\n", sim_->special_reg_lr_);
+      } else if (strcmp(cmd, "ctr") == 0) {
+        PrintF("Ctr reg: %08" V8PRIxPTR "\n", sim_->special_reg_ctr_);
+      } else if (strcmp(cmd, "xer") == 0) {
+        PrintF("XER: %08x\n", sim_->special_reg_xer_);
+      } else if (strcmp(cmd, "fpscr") == 0) {
+        PrintF("FPSCR: %08x\n", sim_->fp_condition_reg_);
+      } else if (strcmp(cmd, "stop") == 0) {
+        intptr_t value;
+        intptr_t stop_pc =
+            sim_->get_pc() - (Instruction::kInstrSize + kPointerSize);
+        Instruction* stop_instr = reinterpret_cast<Instruction*>(stop_pc);
+        Instruction* msg_address =
+            reinterpret_cast<Instruction*>(stop_pc + Instruction::kInstrSize);
+        if ((argc == 2) && (strcmp(arg1, "unstop") == 0)) {
+          // Remove the current stop.
+          if (sim_->isStopInstruction(stop_instr)) {
+            stop_instr->SetInstructionBits(kNopInstr);
+            msg_address->SetInstructionBits(kNopInstr);
+          } else {
+            PrintF("Not at debugger stop.\n");
+          }
+        } else if (argc == 3) {
+          // Print information about all/the specified breakpoint(s).
+          if (strcmp(arg1, "info") == 0) {
+            if (strcmp(arg2, "all") == 0) {
+              PrintF("Stop information:\n");
+              for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
+                sim_->PrintStopInfo(i);
+              }
+            } else if (GetValue(arg2, &value)) {
+              sim_->PrintStopInfo(value);
+            } else {
+              PrintF("Unrecognized argument.\n");
+            }
+          } else if (strcmp(arg1, "enable") == 0) {
+            // Enable all/the specified breakpoint(s).
+            if (strcmp(arg2, "all") == 0) {
+              for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
+                sim_->EnableStop(i);
+              }
+            } else if (GetValue(arg2, &value)) {
+              sim_->EnableStop(value);
+            } else {
+              PrintF("Unrecognized argument.\n");
+            }
+          } else if (strcmp(arg1, "disable") == 0) {
+            // Disable all/the specified breakpoint(s).
+            if (strcmp(arg2, "all") == 0) {
+              for (uint32_t i = 0; i < sim_->kNumOfWatchedStops; i++) {
+                sim_->DisableStop(i);
+              }
+            } else if (GetValue(arg2, &value)) {
+              sim_->DisableStop(value);
+            } else {
+              PrintF("Unrecognized argument.\n");
+            }
+          }
+        } else {
+          PrintF("Wrong usage. Use help command for more information.\n");
+        }
+      } else if ((strcmp(cmd, "t") == 0) || strcmp(cmd, "trace") == 0) {
+        ::v8::internal::FLAG_trace_sim = !::v8::internal::FLAG_trace_sim;
+        PrintF("Trace of executed instructions is %s\n",
+               ::v8::internal::FLAG_trace_sim ? "on" : "off");
+      } else if ((strcmp(cmd, "h") == 0) || (strcmp(cmd, "help") == 0)) {
+        PrintF("cont\n");
+        PrintF("  continue execution (alias 'c')\n");
+        PrintF("stepi [num instructions]\n");
+        PrintF("  step one/num instruction(s) (alias 'si')\n");
+        PrintF("print <register>\n");
+        PrintF("  print register content (alias 'p')\n");
+        PrintF("  use register name 'all' to display all integer registers\n");
+        PrintF(
+            "  use register name 'alld' to display integer registers "
+            "with decimal values\n");
+        PrintF("  use register name 'rN' to display register number 'N'\n");
+        PrintF("  add argument 'fp' to print register pair double values\n");
+        PrintF(
+            "  use register name 'allf' to display floating-point "
+            "registers\n");
+        PrintF("printobject <register>\n");
+        PrintF("  print an object from a register (alias 'po')\n");
+        PrintF("cr\n");
+        PrintF("  print condition register\n");
+        PrintF("lr\n");
+        PrintF("  print link register\n");
+        PrintF("ctr\n");
+        PrintF("  print ctr register\n");
+        PrintF("xer\n");
+        PrintF("  print XER\n");
+        PrintF("fpscr\n");
+        PrintF("  print FPSCR\n");
+        PrintF("stack [<num words>]\n");
+        PrintF("  dump stack content, default dump 10 words)\n");
+        PrintF("mem <address> [<num words>]\n");
+        PrintF("  dump memory content, default dump 10 words)\n");
+        PrintF("disasm [<instructions>]\n");
+        PrintF("disasm [<address/register>]\n");
+        PrintF("disasm [[<address/register>] <instructions>]\n");
+        PrintF("  disassemble code, default is 10 instructions\n");
+        PrintF("  from pc (alias 'di')\n");
+        PrintF("gdb\n");
+        PrintF("  enter gdb\n");
+        PrintF("break <address>\n");
+        PrintF("  set a break point on the address\n");
+        PrintF("del\n");
+        PrintF("  delete the breakpoint\n");
+        PrintF("trace (alias 't')\n");
+        PrintF("  toogle the tracing of all executed statements\n");
+        PrintF("stop feature:\n");
+        PrintF("  Description:\n");
+        PrintF("    Stops are debug instructions inserted by\n");
+        PrintF("    the Assembler::stop() function.\n");
+        PrintF("    When hitting a stop, the Simulator will\n");
+        PrintF("    stop and and give control to the PPCDebugger.\n");
+        PrintF("    The first %d stop codes are watched:\n",
+               Simulator::kNumOfWatchedStops);
+        PrintF("    - They can be enabled / disabled: the Simulator\n");
+        PrintF("      will / won't stop when hitting them.\n");
+        PrintF("    - The Simulator keeps track of how many times they \n");
+        PrintF("      are met. (See the info command.) Going over a\n");
+        PrintF("      disabled stop still increases its counter. \n");
+        PrintF("  Commands:\n");
+        PrintF("    stop info all/<code> : print infos about number <code>\n");
+        PrintF("      or all stop(s).\n");
+        PrintF("    stop enable/disable all/<code> : enables / disables\n");
+        PrintF("      all or number <code> stop(s)\n");
+        PrintF("    stop unstop\n");
+        PrintF("      ignore the stop instruction at the current location\n");
+        PrintF("      from now on\n");
+      } else {
+        PrintF("Unknown command: %s\n", cmd);
+      }
+    }
+  }
+
+  // Add all the breakpoints back to stop execution and enter the debugger
+  // shell when hit.
+  RedoBreakpoints();
+  // Restore tracing
+  ::v8::internal::FLAG_trace_sim = trace;
+
+#undef COMMAND_SIZE
+#undef ARG_SIZE
+
+#undef STR
+#undef XSTR
+}
+
+
+static bool ICacheMatch(void* one, void* two) {
+  DCHECK((reinterpret_cast<intptr_t>(one) & CachePage::kPageMask) == 0);
+  DCHECK((reinterpret_cast<intptr_t>(two) & CachePage::kPageMask) == 0);
+  return one == two;
+}
+
+
+static uint32_t ICacheHash(void* key) {
+  return static_cast<uint32_t>(reinterpret_cast<uintptr_t>(key)) >> 2;
+}
+
+
+static bool AllOnOnePage(uintptr_t start, int size) {
+  intptr_t start_page = (start & ~CachePage::kPageMask);
+  intptr_t end_page = ((start + size) & ~CachePage::kPageMask);
+  return start_page == end_page;
+}
+
+
+void Simulator::set_last_debugger_input(char* input) {
+  DeleteArray(last_debugger_input_);
+  last_debugger_input_ = input;
+}
+
+
+void Simulator::FlushICache(v8::internal::HashMap* i_cache, void* start_addr,
+                            size_t size) {
+  intptr_t start = reinterpret_cast<intptr_t>(start_addr);
+  int intra_line = (start & CachePage::kLineMask);
+  start -= intra_line;
+  size += intra_line;
+  size = ((size - 1) | CachePage::kLineMask) + 1;
+  int offset = (start & CachePage::kPageMask);
+  while (!AllOnOnePage(start, size - 1)) {
+    int bytes_to_flush = CachePage::kPageSize - offset;
+    FlushOnePage(i_cache, start, bytes_to_flush);
+    start += bytes_to_flush;
+    size -= bytes_to_flush;
+    DCHECK_EQ(0, static_cast<int>(start & CachePage::kPageMask));
+    offset = 0;
+  }
+  if (size != 0) {
+    FlushOnePage(i_cache, start, size);
+  }
+}
+
+
+CachePage* Simulator::GetCachePage(v8::internal::HashMap* i_cache, void* page) {
+  v8::internal::HashMap::Entry* entry =
+      i_cache->Lookup(page, ICacheHash(page), true);
+  if (entry->value == NULL) {
+    CachePage* new_page = new CachePage();
+    entry->value = new_page;
+  }
+  return reinterpret_cast<CachePage*>(entry->value);
+}
+
+
+// Flush from start up to and not including start + size.
+void Simulator::FlushOnePage(v8::internal::HashMap* i_cache, intptr_t start,
+                             int size) {
+  DCHECK(size <= CachePage::kPageSize);
+  DCHECK(AllOnOnePage(start, size - 1));
+  DCHECK((start & CachePage::kLineMask) == 0);
+  DCHECK((size & CachePage::kLineMask) == 0);
+  void* page = reinterpret_cast<void*>(start & (~CachePage::kPageMask));
+  int offset = (start & CachePage::kPageMask);
+  CachePage* cache_page = GetCachePage(i_cache, page);
+  char* valid_bytemap = cache_page->ValidityByte(offset);
+  memset(valid_bytemap, CachePage::LINE_INVALID, size >> CachePage::kLineShift);
+}
+
+
+void Simulator::CheckICache(v8::internal::HashMap* i_cache,
+                            Instruction* instr) {
+  intptr_t address = reinterpret_cast<intptr_t>(instr);
+  void* page = reinterpret_cast<void*>(address & (~CachePage::kPageMask));
+  void* line = reinterpret_cast<void*>(address & (~CachePage::kLineMask));
+  int offset = (address & CachePage::kPageMask);
+  CachePage* cache_page = GetCachePage(i_cache, page);
+  char* cache_valid_byte = cache_page->ValidityByte(offset);
+  bool cache_hit = (*cache_valid_byte == CachePage::LINE_VALID);
+  char* cached_line = cache_page->CachedData(offset & ~CachePage::kLineMask);
+  if (cache_hit) {
+    // Check that the data in memory matches the contents of the I-cache.
+    CHECK_EQ(0,
+             memcmp(reinterpret_cast<void*>(instr),
+                    cache_page->CachedData(offset), Instruction::kInstrSize));
+  } else {
+    // Cache miss.  Load memory into the cache.
+    memcpy(cached_line, line, CachePage::kLineLength);
+    *cache_valid_byte = CachePage::LINE_VALID;
+  }
+}
+
+
+void Simulator::Initialize(Isolate* isolate) {
+  if (isolate->simulator_initialized()) return;
+  isolate->set_simulator_initialized(true);
+  ::v8::internal::ExternalReference::set_redirector(isolate,
+                                                    &RedirectExternalReference);
+}
+
+
+Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
+  i_cache_ = isolate_->simulator_i_cache();
+  if (i_cache_ == NULL) {
+    i_cache_ = new v8::internal::HashMap(&ICacheMatch);
+    isolate_->set_simulator_i_cache(i_cache_);
+  }
+  Initialize(isolate);
+// Set up simulator support first. Some of this information is needed to
+// setup the architecture state.
+#if V8_TARGET_ARCH_PPC64
+  size_t stack_size = 2 * 1024 * 1024;  // allocate 2MB for stack
+#else
+  size_t stack_size = 1 * 1024 * 1024;  // allocate 1MB for stack
+#endif
+  stack_ = reinterpret_cast<char*>(malloc(stack_size));
+  pc_modified_ = false;
+  icount_ = 0;
+  break_pc_ = NULL;
+  break_instr_ = 0;
+
+  // Set up architecture state.
+  // All registers are initialized to zero to start with.
+  for (int i = 0; i < kNumGPRs; i++) {
+    registers_[i] = 0;
+  }
+  condition_reg_ = 0;
+  fp_condition_reg_ = 0;
+  special_reg_pc_ = 0;
+  special_reg_lr_ = 0;
+  special_reg_ctr_ = 0;
+
+  // Initializing FP registers.
+  for (int i = 0; i < kNumFPRs; i++) {
+    fp_registers_[i] = 0.0;
+  }
+
+  // The sp is initialized to point to the bottom (high address) of the
+  // allocated stack area. To be safe in potential stack underflows we leave
+  // some buffer below.
+  registers_[sp] = reinterpret_cast<intptr_t>(stack_) + stack_size - 64;
+  InitializeCoverage();
+
+  last_debugger_input_ = NULL;
+}
+
+
+Simulator::~Simulator() {}
+
+
+// When the generated code calls an external reference we need to catch that in
+// the simulator.  The external reference will be a function compiled for the
+// host architecture.  We need to call that function instead of trying to
+// execute it with the simulator.  We do that by redirecting the external
+// reference to a svc (Supervisor Call) instruction that is handled by
+// the simulator.  We write the original destination of the jump just at a known
+// offset from the svc instruction so the simulator knows what to call.
+class Redirection {
+ public:
+  Redirection(void* external_function, ExternalReference::Type type)
+      : external_function_(external_function),
+        swi_instruction_(rtCallRedirInstr | kCallRtRedirected),
+        type_(type),
+        next_(NULL) {
+    Isolate* isolate = Isolate::Current();
+    next_ = isolate->simulator_redirection();
+    Simulator::current(isolate)->FlushICache(
+        isolate->simulator_i_cache(),
+        reinterpret_cast<void*>(&swi_instruction_), Instruction::kInstrSize);
+    isolate->set_simulator_redirection(this);
+  }
+
+  void* address_of_swi_instruction() {
+    return reinterpret_cast<void*>(&swi_instruction_);
+  }
+
+  void* external_function() { return external_function_; }
+  ExternalReference::Type type() { return type_; }
+
+  static Redirection* Get(void* external_function,
+                          ExternalReference::Type type) {
+    Isolate* isolate = Isolate::Current();
+    Redirection* current = isolate->simulator_redirection();
+    for (; current != NULL; current = current->next_) {
+      if (current->external_function_ == external_function) {
+        DCHECK_EQ(current->type(), type);
+        return current;
+      }
+    }
+    return new Redirection(external_function, type);
+  }
+
+  static Redirection* FromSwiInstruction(Instruction* swi_instruction) {
+    char* addr_of_swi = reinterpret_cast<char*>(swi_instruction);
+    char* addr_of_redirection =
+        addr_of_swi - OFFSET_OF(Redirection, swi_instruction_);
+    return reinterpret_cast<Redirection*>(addr_of_redirection);
+  }
+
+  static void* ReverseRedirection(intptr_t reg) {
+    Redirection* redirection = FromSwiInstruction(
+        reinterpret_cast<Instruction*>(reinterpret_cast<void*>(reg)));
+    return redirection->external_function();
+  }
+
+ private:
+  void* external_function_;
+  uint32_t swi_instruction_;
+  ExternalReference::Type type_;
+  Redirection* next_;
+};
+
+
+void* Simulator::RedirectExternalReference(void* external_function,
+                                           ExternalReference::Type type) {
+  Redirection* redirection = Redirection::Get(external_function, type);
+  return redirection->address_of_swi_instruction();
+}
+
+
+// Get the active Simulator for the current thread.
+Simulator* Simulator::current(Isolate* isolate) {
+  v8::internal::Isolate::PerIsolateThreadData* isolate_data =
+      isolate->FindOrAllocatePerThreadDataForThisThread();
+  DCHECK(isolate_data != NULL);
+
+  Simulator* sim = isolate_data->simulator();
+  if (sim == NULL) {
+    // TODO(146): delete the simulator object when a thread/isolate goes away.
+    sim = new Simulator(isolate);
+    isolate_data->set_simulator(sim);
+  }
+  return sim;
+}
+
+
+// Sets the register in the architecture state.
+void Simulator::set_register(int reg, intptr_t value) {
+  DCHECK((reg >= 0) && (reg < kNumGPRs));
+  registers_[reg] = value;
+}
+
+
+// Get the register from the architecture state.
+intptr_t Simulator::get_register(int reg) const {
+  DCHECK((reg >= 0) && (reg < kNumGPRs));
+  // Stupid code added to avoid bug in GCC.
+  // See: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43949
+  if (reg >= kNumGPRs) return 0;
+  // End stupid code.
+  return registers_[reg];
+}
+
+
+double Simulator::get_double_from_register_pair(int reg) {
+  DCHECK((reg >= 0) && (reg < kNumGPRs) && ((reg % 2) == 0));
+
+  double dm_val = 0.0;
+#if !V8_TARGET_ARCH_PPC64  // doesn't make sense in 64bit mode
+  // Read the bits from the unsigned integer register_[] array
+  // into the double precision floating point value and return it.
+  char buffer[sizeof(fp_registers_[0])];
+  memcpy(buffer, &registers_[reg], 2 * sizeof(registers_[0]));
+  memcpy(&dm_val, buffer, 2 * sizeof(registers_[0]));
+#endif
+  return (dm_val);
+}
+
+
+// Raw access to the PC register.
+void Simulator::set_pc(intptr_t value) {
+  pc_modified_ = true;
+  special_reg_pc_ = value;
+}
+
+
+bool Simulator::has_bad_pc() const {
+  return ((special_reg_pc_ == bad_lr) || (special_reg_pc_ == end_sim_pc));
+}
+
+
+// Raw access to the PC register without the special adjustment when reading.
+intptr_t Simulator::get_pc() const { return special_reg_pc_; }
+
+
+// Runtime FP routines take:
+// - two double arguments
+// - one double argument and zero or one integer arguments.
+// All are consructed here from d1, d2 and r3.
+void Simulator::GetFpArgs(double* x, double* y, intptr_t* z) {
+  *x = get_double_from_d_register(1);
+  *y = get_double_from_d_register(2);
+  *z = get_register(3);
+}
+
+
+// The return value is in d1.
+void Simulator::SetFpResult(const double& result) { fp_registers_[1] = result; }
+
+
+void Simulator::TrashCallerSaveRegisters() {
+// We don't trash the registers with the return value.
+#if 0  // A good idea to trash volatile registers, needs to be done
+  registers_[2] = 0x50Bad4U;
+  registers_[3] = 0x50Bad4U;
+  registers_[12] = 0x50Bad4U;
+#endif
+}
+
+
+uint32_t Simulator::ReadWU(intptr_t addr, Instruction* instr) {
+  uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
+  return *ptr;
+}
+
+
+int32_t Simulator::ReadW(intptr_t addr, Instruction* instr) {
+  int32_t* ptr = reinterpret_cast<int32_t*>(addr);
+  return *ptr;
+}
+
+
+void Simulator::WriteW(intptr_t addr, uint32_t value, Instruction* instr) {
+  uint32_t* ptr = reinterpret_cast<uint32_t*>(addr);
+  *ptr = value;
+  return;
+}
+
+
+void Simulator::WriteW(intptr_t addr, int32_t value, Instruction* instr) {
+  int32_t* ptr = reinterpret_cast<int32_t*>(addr);
+  *ptr = value;
+  return;
+}
+
+
+uint16_t Simulator::ReadHU(intptr_t addr, Instruction* instr) {
+  uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
+  return *ptr;
+}
+
+
+int16_t Simulator::ReadH(intptr_t addr, Instruction* instr) {
+  int16_t* ptr = reinterpret_cast<int16_t*>(addr);
+  return *ptr;
+}
+
+
+void Simulator::WriteH(intptr_t addr, uint16_t value, Instruction* instr) {
+  uint16_t* ptr = reinterpret_cast<uint16_t*>(addr);
+  *ptr = value;
+  return;
+}
+
+
+void Simulator::WriteH(intptr_t addr, int16_t value, Instruction* instr) {
+  int16_t* ptr = reinterpret_cast<int16_t*>(addr);
+  *ptr = value;
+  return;
+}
+
+
+uint8_t Simulator::ReadBU(intptr_t addr) {
+  uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
+  return *ptr;
+}
+
+
+int8_t Simulator::ReadB(intptr_t addr) {
+  int8_t* ptr = reinterpret_cast<int8_t*>(addr);
+  return *ptr;
+}
+
+
+void Simulator::WriteB(intptr_t addr, uint8_t value) {
+  uint8_t* ptr = reinterpret_cast<uint8_t*>(addr);
+  *ptr = value;
+}
+
+
+void Simulator::WriteB(intptr_t addr, int8_t value) {
+  int8_t* ptr = reinterpret_cast<int8_t*>(addr);
+  *ptr = value;
+}
+
+
+intptr_t* Simulator::ReadDW(intptr_t addr) {
+  intptr_t* ptr = reinterpret_cast<intptr_t*>(addr);
+  return ptr;
+}
+
+
+void Simulator::WriteDW(intptr_t addr, int64_t value) {
+  int64_t* ptr = reinterpret_cast<int64_t*>(addr);
+  *ptr = value;
+  return;
+}
+
+
+// Returns the limit of the stack area to enable checking for stack overflows.
+uintptr_t Simulator::StackLimit() const {
+  // Leave a safety margin of 1024 bytes to prevent overrunning the stack when
+  // pushing values.
+  return reinterpret_cast<uintptr_t>(stack_) + 1024;
+}
+
+
+// Unsupported instructions use Format to print an error and stop execution.
+void Simulator::Format(Instruction* instr, const char* format) {
+  PrintF("Simulator found unsupported instruction:\n 0x%08" V8PRIxPTR ": %s\n",
+         reinterpret_cast<intptr_t>(instr), format);
+  UNIMPLEMENTED();
+}
+
+
+// Calculate C flag value for additions.
+bool Simulator::CarryFrom(int32_t left, int32_t right, int32_t carry) {
+  uint32_t uleft = static_cast<uint32_t>(left);
+  uint32_t uright = static_cast<uint32_t>(right);
+  uint32_t urest = 0xffffffffU - uleft;
+
+  return (uright > urest) ||
+         (carry && (((uright + 1) > urest) || (uright > (urest - 1))));
+}
+
+
+// Calculate C flag value for subtractions.
+bool Simulator::BorrowFrom(int32_t left, int32_t right) {
+  uint32_t uleft = static_cast<uint32_t>(left);
+  uint32_t uright = static_cast<uint32_t>(right);
+
+  return (uright > uleft);
+}
+
+
+// Calculate V flag value for additions and subtractions.
+bool Simulator::OverflowFrom(int32_t alu_out, int32_t left, int32_t right,
+                             bool addition) {
+  bool overflow;
+  if (addition) {
+    // operands have the same sign
+    overflow = ((left >= 0 && right >= 0) || (left < 0 && right < 0))
+               // and operands and result have different sign
+               &&
+               ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
+  } else {
+    // operands have different signs
+    overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
+               // and first operand and result have different signs
+               &&
+               ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
+  }
+  return overflow;
+}
+
+
+#if !V8_TARGET_ARCH_PPC64
+// Calls into the V8 runtime are based on this very simple interface.
+// Note: To be able to return two values from some calls the code in runtime.cc
+// uses the ObjectPair which is essentially two 32-bit values stuffed into a
+// 64-bit value. With the code below we assume that all runtime calls return
+// 64 bits of result. If they don't, the r4 result register contains a bogus
+// value, which is fine because it is caller-saved.
+typedef int64_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1,
+                                        intptr_t arg2, intptr_t arg3,
+                                        intptr_t arg4, intptr_t arg5);
+#else
+// For 64-bit, we need to be more explicit.
+typedef intptr_t (*SimulatorRuntimeCall)(intptr_t arg0, intptr_t arg1,
+                                         intptr_t arg2, intptr_t arg3,
+                                         intptr_t arg4, intptr_t arg5);
+struct ObjectPair {
+  intptr_t x;
+  intptr_t y;
+};
+
+typedef struct ObjectPair (*SimulatorRuntimeObjectPairCall)(
+    intptr_t arg0, intptr_t arg1, intptr_t arg2, intptr_t arg3, intptr_t arg4,
+    intptr_t arg5);
+#endif
+
+// These prototypes handle the four types of FP calls.
+typedef int (*SimulatorRuntimeCompareCall)(double darg0, double darg1);
+typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1);
+typedef double (*SimulatorRuntimeFPCall)(double darg0);
+typedef double (*SimulatorRuntimeFPIntCall)(double darg0, intptr_t arg0);
+
+// This signature supports direct call in to API function native callback
+// (refer to InvocationCallback in v8.h).
+typedef void (*SimulatorRuntimeDirectApiCall)(intptr_t arg0);
+typedef void (*SimulatorRuntimeProfilingApiCall)(intptr_t arg0, void* arg1);
+
+// This signature supports direct call to accessor getter callback.
+typedef void (*SimulatorRuntimeDirectGetterCall)(intptr_t arg0, intptr_t arg1);
+typedef void (*SimulatorRuntimeProfilingGetterCall)(intptr_t arg0,
+                                                    intptr_t arg1, void* arg2);
+
+// Software interrupt instructions are used by the simulator to call into the
+// C-based V8 runtime.
+void Simulator::SoftwareInterrupt(Instruction* instr) {
+  int svc = instr->SvcValue();
+  switch (svc) {
+    case kCallRtRedirected: {
+      // Check if stack is aligned. Error if not aligned is reported below to
+      // include information on the function called.
+      bool stack_aligned =
+          (get_register(sp) & (::v8::internal::FLAG_sim_stack_alignment - 1)) ==
+          0;
+      Redirection* redirection = Redirection::FromSwiInstruction(instr);
+      const int kArgCount = 6;
+      int arg0_regnum = 3;
+#if V8_TARGET_ARCH_PPC64 && !ABI_RETURNS_OBJECT_PAIRS_IN_REGS
+      intptr_t result_buffer = 0;
+      if (redirection->type() == ExternalReference::BUILTIN_OBJECTPAIR_CALL) {
+        result_buffer = get_register(r3);
+        arg0_regnum++;
+      }
+#endif
+      intptr_t arg[kArgCount];
+      for (int i = 0; i < kArgCount; i++) {
+        arg[i] = get_register(arg0_regnum + i);
+      }
+      bool fp_call =
+          (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
+          (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
+          (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
+          (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
+      // This is dodgy but it works because the C entry stubs are never moved.
+      // See comment in codegen-arm.cc and bug 1242173.
+      intptr_t saved_lr = special_reg_lr_;
+      intptr_t external =
+          reinterpret_cast<intptr_t>(redirection->external_function());
+      if (fp_call) {
+        double dval0, dval1;  // one or two double parameters
+        intptr_t ival;        // zero or one integer parameters
+        int iresult = 0;      // integer return value
+        double dresult = 0;   // double return value
+        GetFpArgs(&dval0, &dval1, &ival);
+        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
+          SimulatorRuntimeCall generic_target =
+              reinterpret_cast<SimulatorRuntimeCall>(external);
+          switch (redirection->type()) {
+            case ExternalReference::BUILTIN_FP_FP_CALL:
+            case ExternalReference::BUILTIN_COMPARE_CALL:
+              PrintF("Call to host function at %p with args %f, %f",
+                     FUNCTION_ADDR(generic_target), dval0, dval1);
+              break;
+            case ExternalReference::BUILTIN_FP_CALL:
+              PrintF("Call to host function at %p with arg %f",
+                     FUNCTION_ADDR(generic_target), dval0);
+              break;
+            case ExternalReference::BUILTIN_FP_INT_CALL:
+              PrintF("Call to host function at %p with args %f, %" V8PRIdPTR,
+                     FUNCTION_ADDR(generic_target), dval0, ival);
+              break;
+            default:
+              UNREACHABLE();
+              break;
+          }
+          if (!stack_aligned) {
+            PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
+                   get_register(sp));
+          }
+          PrintF("\n");
+        }
+        CHECK(stack_aligned);
+        switch (redirection->type()) {
+          case ExternalReference::BUILTIN_COMPARE_CALL: {
+            SimulatorRuntimeCompareCall target =
+                reinterpret_cast<SimulatorRuntimeCompareCall>(external);
+            iresult = target(dval0, dval1);
+            set_register(r3, iresult);
+            break;
+          }
+          case ExternalReference::BUILTIN_FP_FP_CALL: {
+            SimulatorRuntimeFPFPCall target =
+                reinterpret_cast<SimulatorRuntimeFPFPCall>(external);
+            dresult = target(dval0, dval1);
+            SetFpResult(dresult);
+            break;
+          }
+          case ExternalReference::BUILTIN_FP_CALL: {
+            SimulatorRuntimeFPCall target =
+                reinterpret_cast<SimulatorRuntimeFPCall>(external);
+            dresult = target(dval0);
+            SetFpResult(dresult);
+            break;
+          }
+          case ExternalReference::BUILTIN_FP_INT_CALL: {
+            SimulatorRuntimeFPIntCall target =
+                reinterpret_cast<SimulatorRuntimeFPIntCall>(external);
+            dresult = target(dval0, ival);
+            SetFpResult(dresult);
+            break;
+          }
+          default:
+            UNREACHABLE();
+            break;
+        }
+        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
+          switch (redirection->type()) {
+            case ExternalReference::BUILTIN_COMPARE_CALL:
+              PrintF("Returned %08x\n", iresult);
+              break;
+            case ExternalReference::BUILTIN_FP_FP_CALL:
+            case ExternalReference::BUILTIN_FP_CALL:
+            case ExternalReference::BUILTIN_FP_INT_CALL:
+              PrintF("Returned %f\n", dresult);
+              break;
+            default:
+              UNREACHABLE();
+              break;
+          }
+        }
+      } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
+        // See callers of MacroAssembler::CallApiFunctionAndReturn for
+        // explanation of register usage.
+        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
+          PrintF("Call to host function at %p args %08" V8PRIxPTR,
+                 reinterpret_cast<void*>(external), arg[0]);
+          if (!stack_aligned) {
+            PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
+                   get_register(sp));
+          }
+          PrintF("\n");
+        }
+        CHECK(stack_aligned);
+        SimulatorRuntimeDirectApiCall target =
+            reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
+        target(arg[0]);
+      } else if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
+        // See callers of MacroAssembler::CallApiFunctionAndReturn for
+        // explanation of register usage.
+        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
+          PrintF("Call to host function at %p args %08" V8PRIxPTR
+                 " %08" V8PRIxPTR,
+                 reinterpret_cast<void*>(external), arg[0], arg[1]);
+          if (!stack_aligned) {
+            PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
+                   get_register(sp));
+          }
+          PrintF("\n");
+        }
+        CHECK(stack_aligned);
+        SimulatorRuntimeProfilingApiCall target =
+            reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
+        target(arg[0], Redirection::ReverseRedirection(arg[1]));
+      } else if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
+        // See callers of MacroAssembler::CallApiFunctionAndReturn for
+        // explanation of register usage.
+        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
+          PrintF("Call to host function at %p args %08" V8PRIxPTR
+                 " %08" V8PRIxPTR,
+                 reinterpret_cast<void*>(external), arg[0], arg[1]);
+          if (!stack_aligned) {
+            PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
+                   get_register(sp));
+          }
+          PrintF("\n");
+        }
+        CHECK(stack_aligned);
+        SimulatorRuntimeDirectGetterCall target =
+            reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
+#if !ABI_PASSES_HANDLES_IN_REGS
+        arg[0] = *(reinterpret_cast<intptr_t*>(arg[0]));
+#endif
+        target(arg[0], arg[1]);
+      } else if (redirection->type() ==
+                 ExternalReference::PROFILING_GETTER_CALL) {
+        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
+          PrintF("Call to host function at %p args %08" V8PRIxPTR
+                 " %08" V8PRIxPTR " %08" V8PRIxPTR,
+                 reinterpret_cast<void*>(external), arg[0], arg[1], arg[2]);
+          if (!stack_aligned) {
+            PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
+                   get_register(sp));
+          }
+          PrintF("\n");
+        }
+        CHECK(stack_aligned);
+        SimulatorRuntimeProfilingGetterCall target =
+            reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
+#if !ABI_PASSES_HANDLES_IN_REGS
+        arg[0] = *(reinterpret_cast<intptr_t*>(arg[0]));
+#endif
+        target(arg[0], arg[1], Redirection::ReverseRedirection(arg[2]));
+      } else {
+        // builtin call.
+        if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
+          SimulatorRuntimeCall target =
+              reinterpret_cast<SimulatorRuntimeCall>(external);
+          PrintF(
+              "Call to host function at %p,\n"
+              "\t\t\t\targs %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR
+              ", %08" V8PRIxPTR ", %08" V8PRIxPTR ", %08" V8PRIxPTR,
+              FUNCTION_ADDR(target), arg[0], arg[1], arg[2], arg[3], arg[4],
+              arg[5]);
+          if (!stack_aligned) {
+            PrintF(" with unaligned stack %08" V8PRIxPTR "\n",
+                   get_register(sp));
+          }
+          PrintF("\n");
+        }
+        CHECK(stack_aligned);
+#if !V8_TARGET_ARCH_PPC64
+        DCHECK(redirection->type() == ExternalReference::BUILTIN_CALL);
+        SimulatorRuntimeCall target =
+            reinterpret_cast<SimulatorRuntimeCall>(external);
+        int64_t result = target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
+        int32_t lo_res = static_cast<int32_t>(result);
+        int32_t hi_res = static_cast<int32_t>(result >> 32);
+#if V8_TARGET_BIG_ENDIAN
+        if (::v8::internal::FLAG_trace_sim) {
+          PrintF("Returned %08x\n", hi_res);
+        }
+        set_register(r3, hi_res);
+        set_register(r4, lo_res);
+#else
+        if (::v8::internal::FLAG_trace_sim) {
+          PrintF("Returned %08x\n", lo_res);
+        }
+        set_register(r3, lo_res);
+        set_register(r4, hi_res);
+#endif
+#else
+        if (redirection->type() == ExternalReference::BUILTIN_CALL) {
+          SimulatorRuntimeCall target =
+              reinterpret_cast<SimulatorRuntimeCall>(external);
+          intptr_t result =
+              target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
+          if (::v8::internal::FLAG_trace_sim) {
+            PrintF("Returned %08" V8PRIxPTR "\n", result);
+          }
+          set_register(r3, result);
+        } else {
+          DCHECK(redirection->type() ==
+                 ExternalReference::BUILTIN_OBJECTPAIR_CALL);
+          SimulatorRuntimeObjectPairCall target =
+              reinterpret_cast<SimulatorRuntimeObjectPairCall>(external);
+          struct ObjectPair result =
+              target(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
+          if (::v8::internal::FLAG_trace_sim) {
+            PrintF("Returned %08" V8PRIxPTR ", %08" V8PRIxPTR "\n", result.x,
+                   result.y);
+          }
+#if ABI_RETURNS_OBJECT_PAIRS_IN_REGS
+          set_register(r3, result.x);
+          set_register(r4, result.y);
+#else
+          memcpy(reinterpret_cast<void*>(result_buffer), &result,
+                 sizeof(struct ObjectPair));
+#endif
+        }
+#endif
+      }
+      set_pc(saved_lr);
+      break;
+    }
+    case kBreakpoint: {
+      PPCDebugger dbg(this);
+      dbg.Debug();
+      break;
+    }
+    case kInfo: {
+      PPCDebugger dbg(this);
+      dbg.Info(instr);
+      break;
+    }
+    // stop uses all codes greater than 1 << 23.
+    default: {
+      if (svc >= (1 << 23)) {
+        uint32_t code = svc & kStopCodeMask;
+        if (isWatchedStop(code)) {
+          IncreaseStopCounter(code);
+        }
+        // Stop if it is enabled, otherwise go on jumping over the stop
+        // and the message address.
+        if (isEnabledStop(code)) {
+          PPCDebugger dbg(this);
+          dbg.Stop(instr);
+        } else {
+          set_pc(get_pc() + Instruction::kInstrSize + kPointerSize);
+        }
+      } else {
+        // This is not a valid svc code.
+        UNREACHABLE();
+        break;
+      }
+    }
+  }
+}
+
+
+// Stop helper functions.
+bool Simulator::isStopInstruction(Instruction* instr) {
+  return (instr->Bits(27, 24) == 0xF) && (instr->SvcValue() >= kStopCode);
+}
+
+
+bool Simulator::isWatchedStop(uint32_t code) {
+  DCHECK(code <= kMaxStopCode);
+  return code < kNumOfWatchedStops;
+}
+
+
+bool Simulator::isEnabledStop(uint32_t code) {
+  DCHECK(code <= kMaxStopCode);
+  // Unwatched stops are always enabled.
+  return !isWatchedStop(code) ||
+         !(watched_stops_[code].count & kStopDisabledBit);
+}
+
+
+void Simulator::EnableStop(uint32_t code) {
+  DCHECK(isWatchedStop(code));
+  if (!isEnabledStop(code)) {
+    watched_stops_[code].count &= ~kStopDisabledBit;
+  }
+}
+
+
+void Simulator::DisableStop(uint32_t code) {
+  DCHECK(isWatchedStop(code));
+  if (isEnabledStop(code)) {
+    watched_stops_[code].count |= kStopDisabledBit;
+  }
+}
+
+
+void Simulator::IncreaseStopCounter(uint32_t code) {
+  DCHECK(code <= kMaxStopCode);
+  DCHECK(isWatchedStop(code));
+  if ((watched_stops_[code].count & ~(1 << 31)) == 0x7fffffff) {
+    PrintF(
+        "Stop counter for code %i has overflowed.\n"
+        "Enabling this code and reseting the counter to 0.\n",
+        code);
+    watched_stops_[code].count = 0;
+    EnableStop(code);
+  } else {
+    watched_stops_[code].count++;
+  }
+}
+
+
+// Print a stop status.
+void Simulator::PrintStopInfo(uint32_t code) {
+  DCHECK(code <= kMaxStopCode);
+  if (!isWatchedStop(code)) {
+    PrintF("Stop not watched.");
+  } else {
+    const char* state = isEnabledStop(code) ? "Enabled" : "Disabled";
+    int32_t count = watched_stops_[code].count & ~kStopDisabledBit;
+    // Don't print the state of unused breakpoints.
+    if (count != 0) {
+      if (watched_stops_[code].desc) {
+        PrintF("stop %i - 0x%x: \t%s, \tcounter = %i, \t%s\n", code, code,
+               state, count, watched_stops_[code].desc);
+      } else {
+        PrintF("stop %i - 0x%x: \t%s, \tcounter = %i\n", code, code, state,
+               count);
+      }
+    }
+  }
+}
+
+
+void Simulator::SetCR0(intptr_t result, bool setSO) {
+  int bf = 0;
+  if (result < 0) {
+    bf |= 0x80000000;
+  }
+  if (result > 0) {
+    bf |= 0x40000000;
+  }
+  if (result == 0) {
+    bf |= 0x20000000;
+  }
+  if (setSO) {
+    bf |= 0x10000000;
+  }
+  condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
+}
+
+
+void Simulator::ExecuteBranchConditional(Instruction* instr) {
+  int bo = instr->Bits(25, 21) << 21;
+  int offset = (instr->Bits(15, 2) << 18) >> 16;
+  int condition_bit = instr->Bits(20, 16);
+  int condition_mask = 0x80000000 >> condition_bit;
+  switch (bo) {
+    case DCBNZF:  // Decrement CTR; branch if CTR != 0 and condition false
+    case DCBEZF:  // Decrement CTR; branch if CTR == 0 and condition false
+      UNIMPLEMENTED();
+    case BF: {  // Branch if condition false
+      if (!(condition_reg_ & condition_mask)) {
+        if (instr->Bit(0) == 1) {  // LK flag set
+          special_reg_lr_ = get_pc() + 4;
+        }
+        set_pc(get_pc() + offset);
+      }
+      break;
+    }
+    case DCBNZT:  // Decrement CTR; branch if CTR != 0 and condition true
+    case DCBEZT:  // Decrement CTR; branch if CTR == 0 and condition true
+      UNIMPLEMENTED();
+    case BT: {  // Branch if condition true
+      if (condition_reg_ & condition_mask) {
+        if (instr->Bit(0) == 1) {  // LK flag set
+          special_reg_lr_ = get_pc() + 4;
+        }
+        set_pc(get_pc() + offset);
+      }
+      break;
+    }
+    case DCBNZ:  // Decrement CTR; branch if CTR != 0
+    case DCBEZ:  // Decrement CTR; branch if CTR == 0
+      special_reg_ctr_ -= 1;
+      if ((special_reg_ctr_ == 0) == (bo == DCBEZ)) {
+        if (instr->Bit(0) == 1) {  // LK flag set
+          special_reg_lr_ = get_pc() + 4;
+        }
+        set_pc(get_pc() + offset);
+      }
+      break;
+    case BA: {                   // Branch always
+      if (instr->Bit(0) == 1) {  // LK flag set
+        special_reg_lr_ = get_pc() + 4;
+      }
+      set_pc(get_pc() + offset);
+      break;
+    }
+    default:
+      UNIMPLEMENTED();  // Invalid encoding
+  }
+}
+
+
+// Handle execution based on instruction types.
+void Simulator::ExecuteExt1(Instruction* instr) {
+  switch (instr->Bits(10, 1) << 1) {
+    case MCRF:
+      UNIMPLEMENTED();  // Not used by V8.
+    case BCLRX: {
+      // need to check BO flag
+      intptr_t old_pc = get_pc();
+      set_pc(special_reg_lr_);
+      if (instr->Bit(0) == 1) {  // LK flag set
+        special_reg_lr_ = old_pc + 4;
+      }
+      break;
+    }
+    case BCCTRX: {
+      // need to check BO flag
+      intptr_t old_pc = get_pc();
+      set_pc(special_reg_ctr_);
+      if (instr->Bit(0) == 1) {  // LK flag set
+        special_reg_lr_ = old_pc + 4;
+      }
+      break;
+    }
+    case CRNOR:
+    case RFI:
+    case CRANDC:
+      UNIMPLEMENTED();
+    case ISYNC: {
+      // todo - simulate isync
+      break;
+    }
+    case CRXOR: {
+      int bt = instr->Bits(25, 21);
+      int ba = instr->Bits(20, 16);
+      int bb = instr->Bits(15, 11);
+      int ba_val = ((0x80000000 >> ba) & condition_reg_) == 0 ? 0 : 1;
+      int bb_val = ((0x80000000 >> bb) & condition_reg_) == 0 ? 0 : 1;
+      int bt_val = ba_val ^ bb_val;
+      bt_val = bt_val << (31 - bt);  // shift bit to correct destination
+      condition_reg_ &= ~(0x80000000 >> bt);
+      condition_reg_ |= bt_val;
+      break;
+    }
+    case CREQV: {
+      int bt = instr->Bits(25, 21);
+      int ba = instr->Bits(20, 16);
+      int bb = instr->Bits(15, 11);
+      int ba_val = ((0x80000000 >> ba) & condition_reg_) == 0 ? 0 : 1;
+      int bb_val = ((0x80000000 >> bb) & condition_reg_) == 0 ? 0 : 1;
+      int bt_val = 1 - (ba_val ^ bb_val);
+      bt_val = bt_val << (31 - bt);  // shift bit to correct destination
+      condition_reg_ &= ~(0x80000000 >> bt);
+      condition_reg_ |= bt_val;
+      break;
+    }
+    case CRNAND:
+    case CRAND:
+    case CRORC:
+    case CROR:
+    default: {
+      UNIMPLEMENTED();  // Not used by V8.
+    }
+  }
+}
+
+
+bool Simulator::ExecuteExt2_10bit(Instruction* instr) {
+  bool found = true;
+
+  int opcode = instr->Bits(10, 1) << 1;
+  switch (opcode) {
+    case SRWX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      uint32_t rs_val = get_register(rs);
+      uintptr_t rb_val = get_register(rb);
+      intptr_t result = rs_val >> (rb_val & 0x3f);
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case SRDX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      uintptr_t rs_val = get_register(rs);
+      uintptr_t rb_val = get_register(rb);
+      intptr_t result = rs_val >> (rb_val & 0x7f);
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      break;
+    }
+#endif
+    case SRAW: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      int32_t rs_val = get_register(rs);
+      intptr_t rb_val = get_register(rb);
+      intptr_t result = rs_val >> (rb_val & 0x3f);
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case SRAD: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t rs_val = get_register(rs);
+      intptr_t rb_val = get_register(rb);
+      intptr_t result = rs_val >> (rb_val & 0x7f);
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      break;
+    }
+#endif
+    case SRAWIX: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      int sh = instr->Bits(15, 11);
+      int32_t rs_val = get_register(rs);
+      intptr_t result = rs_val >> sh;
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case EXTSW: {
+      const int shift = kBitsPerPointer - 32;
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      intptr_t rs_val = get_register(rs);
+      intptr_t ra_val = (rs_val << shift) >> shift;
+      set_register(ra, ra_val);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(ra_val);
+      }
+      break;
+    }
+#endif
+    case EXTSH: {
+      const int shift = kBitsPerPointer - 16;
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      intptr_t rs_val = get_register(rs);
+      intptr_t ra_val = (rs_val << shift) >> shift;
+      set_register(ra, ra_val);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(ra_val);
+      }
+      break;
+    }
+    case EXTSB: {
+      const int shift = kBitsPerPointer - 8;
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      intptr_t rs_val = get_register(rs);
+      intptr_t ra_val = (rs_val << shift) >> shift;
+      set_register(ra, ra_val);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(ra_val);
+      }
+      break;
+    }
+    case LFSUX:
+    case LFSX: {
+      int frt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      intptr_t rb_val = get_register(rb);
+      int32_t val = ReadW(ra_val + rb_val, instr);
+      float* fptr = reinterpret_cast<float*>(&val);
+      set_d_register_from_double(frt, static_cast<double>(*fptr));
+      if (opcode == LFSUX) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + rb_val);
+      }
+      break;
+    }
+    case LFDUX:
+    case LFDX: {
+      int frt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      intptr_t rb_val = get_register(rb);
+      double* dptr = reinterpret_cast<double*>(ReadDW(ra_val + rb_val));
+      set_d_register_from_double(frt, *dptr);
+      if (opcode == LFDUX) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + rb_val);
+      }
+      break;
+    }
+    case STFSUX: {
+      case STFSX:
+        int frs = instr->RSValue();
+        int ra = instr->RAValue();
+        int rb = instr->RBValue();
+        intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+        intptr_t rb_val = get_register(rb);
+        float frs_val = static_cast<float>(get_double_from_d_register(frs));
+        int32_t* p = reinterpret_cast<int32_t*>(&frs_val);
+        WriteW(ra_val + rb_val, *p, instr);
+        if (opcode == STFSUX) {
+          DCHECK(ra != 0);
+          set_register(ra, ra_val + rb_val);
+        }
+        break;
+    }
+    case STFDUX: {
+      case STFDX:
+        int frs = instr->RSValue();
+        int ra = instr->RAValue();
+        int rb = instr->RBValue();
+        intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+        intptr_t rb_val = get_register(rb);
+        double frs_val = get_double_from_d_register(frs);
+        int64_t* p = reinterpret_cast<int64_t*>(&frs_val);
+        WriteDW(ra_val + rb_val, *p);
+        if (opcode == STFDUX) {
+          DCHECK(ra != 0);
+          set_register(ra, ra_val + rb_val);
+        }
+        break;
+    }
+    case SYNC: {
+      // todo - simulate sync
+      break;
+    }
+    case ICBI: {
+      // todo - simulate icbi
+      break;
+    }
+    default: {
+      found = false;
+      break;
+    }
+  }
+
+  if (found) return found;
+
+  found = true;
+  opcode = instr->Bits(10, 2) << 2;
+  switch (opcode) {
+    case SRADIX: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
+      intptr_t rs_val = get_register(rs);
+      intptr_t result = rs_val >> sh;
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      break;
+    }
+    default: {
+      found = false;
+      break;
+    }
+  }
+
+  return found;
+}
+
+
+bool Simulator::ExecuteExt2_9bit_part1(Instruction* instr) {
+  bool found = true;
+
+  int opcode = instr->Bits(9, 1) << 1;
+  switch (opcode) {
+    case TW: {
+      // used for call redirection in simulation mode
+      SoftwareInterrupt(instr);
+      break;
+    }
+    case CMP: {
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      int cr = instr->Bits(25, 23);
+      uint32_t bf = 0;
+#if V8_TARGET_ARCH_PPC64
+      int L = instr->Bit(21);
+      if (L) {
+#endif
+        intptr_t ra_val = get_register(ra);
+        intptr_t rb_val = get_register(rb);
+        if (ra_val < rb_val) {
+          bf |= 0x80000000;
+        }
+        if (ra_val > rb_val) {
+          bf |= 0x40000000;
+        }
+        if (ra_val == rb_val) {
+          bf |= 0x20000000;
+        }
+#if V8_TARGET_ARCH_PPC64
+      } else {
+        int32_t ra_val = get_register(ra);
+        int32_t rb_val = get_register(rb);
+        if (ra_val < rb_val) {
+          bf |= 0x80000000;
+        }
+        if (ra_val > rb_val) {
+          bf |= 0x40000000;
+        }
+        if (ra_val == rb_val) {
+          bf |= 0x20000000;
+        }
+      }
+#endif
+      uint32_t condition_mask = 0xF0000000U >> (cr * 4);
+      uint32_t condition = bf >> (cr * 4);
+      condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
+      break;
+    }
+    case SUBFCX: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      // int oe = instr->Bit(10);
+      uintptr_t ra_val = get_register(ra);
+      uintptr_t rb_val = get_register(rb);
+      uintptr_t alu_out = ~ra_val + rb_val + 1;
+      set_register(rt, alu_out);
+      // If the sign of rb and alu_out don't match, carry = 0
+      if ((alu_out ^ rb_val) & 0x80000000) {
+        special_reg_xer_ &= ~0xF0000000;
+      } else {
+        special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
+      }
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(alu_out);
+      }
+      // todo - handle OE bit
+      break;
+    }
+    case ADDCX: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      // int oe = instr->Bit(10);
+      uintptr_t ra_val = get_register(ra);
+      uintptr_t rb_val = get_register(rb);
+      uintptr_t alu_out = ra_val + rb_val;
+      // Check overflow
+      if (~ra_val < rb_val) {
+        special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
+      } else {
+        special_reg_xer_ &= ~0xF0000000;
+      }
+      set_register(rt, alu_out);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(static_cast<intptr_t>(alu_out));
+      }
+      // todo - handle OE bit
+      break;
+    }
+    case MULHWX: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      int32_t ra_val = (get_register(ra) & 0xFFFFFFFF);
+      int32_t rb_val = (get_register(rb) & 0xFFFFFFFF);
+      int64_t alu_out = (int64_t)ra_val * (int64_t)rb_val;
+      alu_out >>= 32;
+      set_register(rt, alu_out);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(static_cast<intptr_t>(alu_out));
+      }
+      // todo - handle OE bit
+      break;
+    }
+    case NEGX: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      intptr_t ra_val = get_register(ra);
+      intptr_t alu_out = 1 + ~ra_val;
+#if V8_TARGET_ARCH_PPC64
+      intptr_t one = 1;  // work-around gcc
+      intptr_t kOverflowVal = (one << 63);
+#else
+      intptr_t kOverflowVal = kMinInt;
+#endif
+      set_register(rt, alu_out);
+      if (instr->Bit(10)) {  // OE bit set
+        if (ra_val == kOverflowVal) {
+          special_reg_xer_ |= 0xC0000000;  // set SO,OV
+        } else {
+          special_reg_xer_ &= ~0x40000000;  // clear OV
+        }
+      }
+      if (instr->Bit(0)) {  // RC bit set
+        bool setSO = (special_reg_xer_ & 0x80000000);
+        SetCR0(alu_out, setSO);
+      }
+      break;
+    }
+    case SLWX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      uint32_t rs_val = get_register(rs);
+      uintptr_t rb_val = get_register(rb);
+      uint32_t result = rs_val << (rb_val & 0x3f);
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case SLDX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      uintptr_t rs_val = get_register(rs);
+      uintptr_t rb_val = get_register(rb);
+      uintptr_t result = rs_val << (rb_val & 0x7f);
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      break;
+    }
+    case MFVSRD: {
+      DCHECK(!instr->Bit(0));
+      int frt = instr->RTValue();
+      int ra = instr->RAValue();
+      double frt_val = get_double_from_d_register(frt);
+      int64_t* p = reinterpret_cast<int64_t*>(&frt_val);
+      set_register(ra, *p);
+      break;
+    }
+    case MFVSRWZ: {
+      DCHECK(!instr->Bit(0));
+      int frt = instr->RTValue();
+      int ra = instr->RAValue();
+      double frt_val = get_double_from_d_register(frt);
+      int64_t* p = reinterpret_cast<int64_t*>(&frt_val);
+      set_register(ra, static_cast<uint32_t>(*p));
+      break;
+    }
+    case MTVSRD: {
+      DCHECK(!instr->Bit(0));
+      int frt = instr->RTValue();
+      int ra = instr->RAValue();
+      int64_t ra_val = get_register(ra);
+      double* p = reinterpret_cast<double*>(&ra_val);
+      set_d_register_from_double(frt, *p);
+      break;
+    }
+    case MTVSRWA: {
+      DCHECK(!instr->Bit(0));
+      int frt = instr->RTValue();
+      int ra = instr->RAValue();
+      int64_t ra_val = static_cast<int32_t>(get_register(ra));
+      double* p = reinterpret_cast<double*>(&ra_val);
+      set_d_register_from_double(frt, *p);
+      break;
+    }
+    case MTVSRWZ: {
+      DCHECK(!instr->Bit(0));
+      int frt = instr->RTValue();
+      int ra = instr->RAValue();
+      uint64_t ra_val = static_cast<uint32_t>(get_register(ra));
+      double* p = reinterpret_cast<double*>(&ra_val);
+      set_d_register_from_double(frt, *p);
+      break;
+    }
+#endif
+    default: {
+      found = false;
+      break;
+    }
+  }
+
+  return found;
+}
+
+
+void Simulator::ExecuteExt2_9bit_part2(Instruction* instr) {
+  int opcode = instr->Bits(9, 1) << 1;
+  switch (opcode) {
+    case CNTLZWX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      uintptr_t rs_val = get_register(rs);
+      uintptr_t count = 0;
+      int n = 0;
+      uintptr_t bit = 0x80000000;
+      for (; n < 32; n++) {
+        if (bit & rs_val) break;
+        count++;
+        bit >>= 1;
+      }
+      set_register(ra, count);
+      if (instr->Bit(0)) {  // RC Bit set
+        int bf = 0;
+        if (count > 0) {
+          bf |= 0x40000000;
+        }
+        if (count == 0) {
+          bf |= 0x20000000;
+        }
+        condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
+      }
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case CNTLZDX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      uintptr_t rs_val = get_register(rs);
+      uintptr_t count = 0;
+      int n = 0;
+      uintptr_t bit = 0x8000000000000000UL;
+      for (; n < 64; n++) {
+        if (bit & rs_val) break;
+        count++;
+        bit >>= 1;
+      }
+      set_register(ra, count);
+      if (instr->Bit(0)) {  // RC Bit set
+        int bf = 0;
+        if (count > 0) {
+          bf |= 0x40000000;
+        }
+        if (count == 0) {
+          bf |= 0x20000000;
+        }
+        condition_reg_ = (condition_reg_ & ~0xF0000000) | bf;
+      }
+      break;
+    }
+#endif
+    case ANDX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t rs_val = get_register(rs);
+      intptr_t rb_val = get_register(rb);
+      intptr_t alu_out = rs_val & rb_val;
+      set_register(ra, alu_out);
+      if (instr->Bit(0)) {  // RC Bit set
+        SetCR0(alu_out);
+      }
+      break;
+    }
+    case ANDCX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t rs_val = get_register(rs);
+      intptr_t rb_val = get_register(rb);
+      intptr_t alu_out = rs_val & ~rb_val;
+      set_register(ra, alu_out);
+      if (instr->Bit(0)) {  // RC Bit set
+        SetCR0(alu_out);
+      }
+      break;
+    }
+    case CMPL: {
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      int cr = instr->Bits(25, 23);
+      uint32_t bf = 0;
+#if V8_TARGET_ARCH_PPC64
+      int L = instr->Bit(21);
+      if (L) {
+#endif
+        uintptr_t ra_val = get_register(ra);
+        uintptr_t rb_val = get_register(rb);
+        if (ra_val < rb_val) {
+          bf |= 0x80000000;
+        }
+        if (ra_val > rb_val) {
+          bf |= 0x40000000;
+        }
+        if (ra_val == rb_val) {
+          bf |= 0x20000000;
+        }
+#if V8_TARGET_ARCH_PPC64
+      } else {
+        uint32_t ra_val = get_register(ra);
+        uint32_t rb_val = get_register(rb);
+        if (ra_val < rb_val) {
+          bf |= 0x80000000;
+        }
+        if (ra_val > rb_val) {
+          bf |= 0x40000000;
+        }
+        if (ra_val == rb_val) {
+          bf |= 0x20000000;
+        }
+      }
+#endif
+      uint32_t condition_mask = 0xF0000000U >> (cr * 4);
+      uint32_t condition = bf >> (cr * 4);
+      condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
+      break;
+    }
+    case SUBFX: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      // int oe = instr->Bit(10);
+      intptr_t ra_val = get_register(ra);
+      intptr_t rb_val = get_register(rb);
+      intptr_t alu_out = rb_val - ra_val;
+      // todo - figure out underflow
+      set_register(rt, alu_out);
+      if (instr->Bit(0)) {  // RC Bit set
+        SetCR0(alu_out);
+      }
+      // todo - handle OE bit
+      break;
+    }
+    case ADDZEX: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      intptr_t ra_val = get_register(ra);
+      if (special_reg_xer_ & 0x20000000) {
+        ra_val += 1;
+      }
+      set_register(rt, ra_val);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(ra_val);
+      }
+      // todo - handle OE bit
+      break;
+    }
+    case NORX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t rs_val = get_register(rs);
+      intptr_t rb_val = get_register(rb);
+      intptr_t alu_out = ~(rs_val | rb_val);
+      set_register(ra, alu_out);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(alu_out);
+      }
+      break;
+    }
+    case MULLW: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      int32_t ra_val = (get_register(ra) & 0xFFFFFFFF);
+      int32_t rb_val = (get_register(rb) & 0xFFFFFFFF);
+      int32_t alu_out = ra_val * rb_val;
+      set_register(rt, alu_out);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(alu_out);
+      }
+      // todo - handle OE bit
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case MULLD: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      int64_t ra_val = get_register(ra);
+      int64_t rb_val = get_register(rb);
+      int64_t alu_out = ra_val * rb_val;
+      set_register(rt, alu_out);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(alu_out);
+      }
+      // todo - handle OE bit
+      break;
+    }
+#endif
+    case DIVW: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      int32_t ra_val = get_register(ra);
+      int32_t rb_val = get_register(rb);
+      bool overflow = (ra_val == kMinInt && rb_val == -1);
+      // result is undefined if divisor is zero or if operation
+      // is 0x80000000 / -1.
+      int32_t alu_out = (rb_val == 0 || overflow) ? -1 : ra_val / rb_val;
+      set_register(rt, alu_out);
+      if (instr->Bit(10)) {  // OE bit set
+        if (overflow) {
+          special_reg_xer_ |= 0xC0000000;  // set SO,OV
+        } else {
+          special_reg_xer_ &= ~0x40000000;  // clear OV
+        }
+      }
+      if (instr->Bit(0)) {  // RC bit set
+        bool setSO = (special_reg_xer_ & 0x80000000);
+        SetCR0(alu_out, setSO);
+      }
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case DIVD: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      int64_t ra_val = get_register(ra);
+      int64_t rb_val = get_register(rb);
+      int64_t one = 1;  // work-around gcc
+      int64_t kMinLongLong = (one << 63);
+      // result is undefined if divisor is zero or if operation
+      // is 0x80000000_00000000 / -1.
+      int64_t alu_out =
+          (rb_val == 0 || (ra_val == kMinLongLong && rb_val == -1))
+              ? -1
+              : ra_val / rb_val;
+      set_register(rt, alu_out);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(alu_out);
+      }
+      // todo - handle OE bit
+      break;
+    }
+#endif
+    case ADDX: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      // int oe = instr->Bit(10);
+      intptr_t ra_val = get_register(ra);
+      intptr_t rb_val = get_register(rb);
+      intptr_t alu_out = ra_val + rb_val;
+      set_register(rt, alu_out);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(alu_out);
+      }
+      // todo - handle OE bit
+      break;
+    }
+    case XORX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t rs_val = get_register(rs);
+      intptr_t rb_val = get_register(rb);
+      intptr_t alu_out = rs_val ^ rb_val;
+      set_register(ra, alu_out);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(alu_out);
+      }
+      break;
+    }
+    case ORX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t rs_val = get_register(rs);
+      intptr_t rb_val = get_register(rb);
+      intptr_t alu_out = rs_val | rb_val;
+      set_register(ra, alu_out);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(alu_out);
+      }
+      break;
+    }
+    case MFSPR: {
+      int rt = instr->RTValue();
+      int spr = instr->Bits(20, 11);
+      if (spr != 256) {
+        UNIMPLEMENTED();  // Only LRLR supported
+      }
+      set_register(rt, special_reg_lr_);
+      break;
+    }
+    case MTSPR: {
+      int rt = instr->RTValue();
+      intptr_t rt_val = get_register(rt);
+      int spr = instr->Bits(20, 11);
+      if (spr == 256) {
+        special_reg_lr_ = rt_val;
+      } else if (spr == 288) {
+        special_reg_ctr_ = rt_val;
+      } else if (spr == 32) {
+        special_reg_xer_ = rt_val;
+      } else {
+        UNIMPLEMENTED();  // Only LR supported
+      }
+      break;
+    }
+    case MFCR: {
+      int rt = instr->RTValue();
+      set_register(rt, condition_reg_);
+      break;
+    }
+    case STWUX:
+    case STWX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      int32_t rs_val = get_register(rs);
+      intptr_t rb_val = get_register(rb);
+      WriteW(ra_val + rb_val, rs_val, instr);
+      if (opcode == STWUX) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + rb_val);
+      }
+      break;
+    }
+    case STBUX:
+    case STBX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      int8_t rs_val = get_register(rs);
+      intptr_t rb_val = get_register(rb);
+      WriteB(ra_val + rb_val, rs_val);
+      if (opcode == STBUX) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + rb_val);
+      }
+      break;
+    }
+    case STHUX:
+    case STHX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      int16_t rs_val = get_register(rs);
+      intptr_t rb_val = get_register(rb);
+      WriteH(ra_val + rb_val, rs_val, instr);
+      if (opcode == STHUX) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + rb_val);
+      }
+      break;
+    }
+    case LWZX:
+    case LWZUX: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      intptr_t rb_val = get_register(rb);
+      set_register(rt, ReadWU(ra_val + rb_val, instr));
+      if (opcode == LWZUX) {
+        DCHECK(ra != 0 && ra != rt);
+        set_register(ra, ra_val + rb_val);
+      }
+      break;
+    }
+#if V8_TARGET_ARCH_PPC64
+    case LDX:
+    case LDUX: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      intptr_t rb_val = get_register(rb);
+      intptr_t* result = ReadDW(ra_val + rb_val);
+      set_register(rt, *result);
+      if (opcode == LDUX) {
+        DCHECK(ra != 0 && ra != rt);
+        set_register(ra, ra_val + rb_val);
+      }
+      break;
+    }
+    case STDX:
+    case STDUX: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      intptr_t rs_val = get_register(rs);
+      intptr_t rb_val = get_register(rb);
+      WriteDW(ra_val + rb_val, rs_val);
+      if (opcode == STDUX) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + rb_val);
+      }
+      break;
+    }
+#endif
+    case LBZX:
+    case LBZUX: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      intptr_t rb_val = get_register(rb);
+      set_register(rt, ReadBU(ra_val + rb_val) & 0xFF);
+      if (opcode == LBZUX) {
+        DCHECK(ra != 0 && ra != rt);
+        set_register(ra, ra_val + rb_val);
+      }
+      break;
+    }
+    case LHZX:
+    case LHZUX: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int rb = instr->RBValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      intptr_t rb_val = get_register(rb);
+      set_register(rt, ReadHU(ra_val + rb_val, instr) & 0xFFFF);
+      if (opcode == LHZUX) {
+        DCHECK(ra != 0 && ra != rt);
+        set_register(ra, ra_val + rb_val);
+      }
+      break;
+    }
+    case DCBF: {
+      // todo - simulate dcbf
+      break;
+    }
+    default: {
+      PrintF("Unimplemented: %08x\n", instr->InstructionBits());
+      UNIMPLEMENTED();  // Not used by V8.
+    }
+  }
+}
+
+
+void Simulator::ExecuteExt2(Instruction* instr) {
+  // Check first the 10-1 bit versions
+  if (ExecuteExt2_10bit(instr)) return;
+  // Now look at the lesser encodings
+  if (ExecuteExt2_9bit_part1(instr)) return;
+  ExecuteExt2_9bit_part2(instr);
+}
+
+
+void Simulator::ExecuteExt4(Instruction* instr) {
+  switch (instr->Bits(5, 1) << 1) {
+    case FDIV: {
+      int frt = instr->RTValue();
+      int fra = instr->RAValue();
+      int frb = instr->RBValue();
+      double fra_val = get_double_from_d_register(fra);
+      double frb_val = get_double_from_d_register(frb);
+      double frt_val = fra_val / frb_val;
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+    case FSUB: {
+      int frt = instr->RTValue();
+      int fra = instr->RAValue();
+      int frb = instr->RBValue();
+      double fra_val = get_double_from_d_register(fra);
+      double frb_val = get_double_from_d_register(frb);
+      double frt_val = fra_val - frb_val;
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+    case FADD: {
+      int frt = instr->RTValue();
+      int fra = instr->RAValue();
+      int frb = instr->RBValue();
+      double fra_val = get_double_from_d_register(fra);
+      double frb_val = get_double_from_d_register(frb);
+      double frt_val = fra_val + frb_val;
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+    case FSQRT: {
+      int frt = instr->RTValue();
+      int frb = instr->RBValue();
+      double frb_val = get_double_from_d_register(frb);
+      double frt_val = std::sqrt(frb_val);
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+    case FSEL: {
+      int frt = instr->RTValue();
+      int fra = instr->RAValue();
+      int frb = instr->RBValue();
+      int frc = instr->RCValue();
+      double fra_val = get_double_from_d_register(fra);
+      double frb_val = get_double_from_d_register(frb);
+      double frc_val = get_double_from_d_register(frc);
+      double frt_val = ((fra_val >= 0.0) ? frc_val : frb_val);
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+    case FMUL: {
+      int frt = instr->RTValue();
+      int fra = instr->RAValue();
+      int frc = instr->RCValue();
+      double fra_val = get_double_from_d_register(fra);
+      double frc_val = get_double_from_d_register(frc);
+      double frt_val = fra_val * frc_val;
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+    case FMSUB: {
+      int frt = instr->RTValue();
+      int fra = instr->RAValue();
+      int frb = instr->RBValue();
+      int frc = instr->RCValue();
+      double fra_val = get_double_from_d_register(fra);
+      double frb_val = get_double_from_d_register(frb);
+      double frc_val = get_double_from_d_register(frc);
+      double frt_val = (fra_val * frc_val) - frb_val;
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+    case FMADD: {
+      int frt = instr->RTValue();
+      int fra = instr->RAValue();
+      int frb = instr->RBValue();
+      int frc = instr->RCValue();
+      double fra_val = get_double_from_d_register(fra);
+      double frb_val = get_double_from_d_register(frb);
+      double frc_val = get_double_from_d_register(frc);
+      double frt_val = (fra_val * frc_val) + frb_val;
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+  }
+  int opcode = instr->Bits(10, 1) << 1;
+  switch (opcode) {
+    case FCMPU: {
+      int fra = instr->RAValue();
+      int frb = instr->RBValue();
+      double fra_val = get_double_from_d_register(fra);
+      double frb_val = get_double_from_d_register(frb);
+      int cr = instr->Bits(25, 23);
+      int bf = 0;
+      if (fra_val < frb_val) {
+        bf |= 0x80000000;
+      }
+      if (fra_val > frb_val) {
+        bf |= 0x40000000;
+      }
+      if (fra_val == frb_val) {
+        bf |= 0x20000000;
+      }
+      if (std::isunordered(fra_val, frb_val)) {
+        bf |= 0x10000000;
+      }
+      int condition_mask = 0xF0000000 >> (cr * 4);
+      int condition = bf >> (cr * 4);
+      condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
+      return;
+    }
+    case FRSP: {
+      int frt = instr->RTValue();
+      int frb = instr->RBValue();
+      double frb_val = get_double_from_d_register(frb);
+      // frsp round 8-byte double-precision value to 8-byte
+      // single-precision value, ignore the round here
+      set_d_register_from_double(frt, frb_val);
+      if (instr->Bit(0)) {  // RC bit set
+                            //  UNIMPLEMENTED();
+      }
+      return;
+    }
+    case FCFID: {
+      int frt = instr->RTValue();
+      int frb = instr->RBValue();
+      double t_val = get_double_from_d_register(frb);
+      int64_t* frb_val_p = reinterpret_cast<int64_t*>(&t_val);
+      double frt_val = static_cast<double>(*frb_val_p);
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+    case FCTID: {
+      int frt = instr->RTValue();
+      int frb = instr->RBValue();
+      double frb_val = get_double_from_d_register(frb);
+      int64_t frt_val;
+      int64_t one = 1;  // work-around gcc
+      int64_t kMinLongLong = (one << 63);
+      int64_t kMaxLongLong = kMinLongLong - 1;
+
+      if (frb_val > kMaxLongLong) {
+        frt_val = kMaxLongLong;
+      } else if (frb_val < kMinLongLong) {
+        frt_val = kMinLongLong;
+      } else {
+        switch (fp_condition_reg_ & kFPRoundingModeMask) {
+          case kRoundToZero:
+            frt_val = (int64_t)frb_val;
+            break;
+          case kRoundToPlusInf:
+            frt_val = (int64_t)std::ceil(frb_val);
+            break;
+          case kRoundToMinusInf:
+            frt_val = (int64_t)std::floor(frb_val);
+            break;
+          default:
+            frt_val = (int64_t)frb_val;
+            UNIMPLEMENTED();  // Not used by V8.
+            break;
+        }
+      }
+      double* p = reinterpret_cast<double*>(&frt_val);
+      set_d_register_from_double(frt, *p);
+      return;
+    }
+    case FCTIDZ: {
+      int frt = instr->RTValue();
+      int frb = instr->RBValue();
+      double frb_val = get_double_from_d_register(frb);
+      int64_t frt_val;
+      int64_t one = 1;  // work-around gcc
+      int64_t kMinLongLong = (one << 63);
+      int64_t kMaxLongLong = kMinLongLong - 1;
+
+      if (frb_val > kMaxLongLong) {
+        frt_val = kMaxLongLong;
+      } else if (frb_val < kMinLongLong) {
+        frt_val = kMinLongLong;
+      } else {
+        frt_val = (int64_t)frb_val;
+      }
+      double* p = reinterpret_cast<double*>(&frt_val);
+      set_d_register_from_double(frt, *p);
+      return;
+    }
+    case FCTIW:
+    case FCTIWZ: {
+      int frt = instr->RTValue();
+      int frb = instr->RBValue();
+      double frb_val = get_double_from_d_register(frb);
+      int64_t frt_val;
+      if (frb_val > kMaxInt) {
+        frt_val = kMaxInt;
+      } else if (frb_val < kMinInt) {
+        frt_val = kMinInt;
+      } else {
+        if (opcode == FCTIWZ) {
+          frt_val = (int64_t)frb_val;
+        } else {
+          switch (fp_condition_reg_ & kFPRoundingModeMask) {
+            case kRoundToZero:
+              frt_val = (int64_t)frb_val;
+              break;
+            case kRoundToPlusInf:
+              frt_val = (int64_t)std::ceil(frb_val);
+              break;
+            case kRoundToMinusInf:
+              frt_val = (int64_t)std::floor(frb_val);
+              break;
+            case kRoundToNearest:
+              frt_val = (int64_t)lround(frb_val);
+
+              // Round to even if exactly halfway.  (lround rounds up)
+              if (std::fabs(static_cast<double>(frt_val) - frb_val) == 0.5 &&
+                  (frt_val % 2)) {
+                frt_val += ((frt_val > 0) ? -1 : 1);
+              }
+
+              break;
+            default:
+              DCHECK(false);
+              frt_val = (int64_t)frb_val;
+              break;
+          }
+        }
+      }
+      double* p = reinterpret_cast<double*>(&frt_val);
+      set_d_register_from_double(frt, *p);
+      return;
+    }
+    case FNEG: {
+      int frt = instr->RTValue();
+      int frb = instr->RBValue();
+      double frb_val = get_double_from_d_register(frb);
+      double frt_val = -frb_val;
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+    case FMR: {
+      int frt = instr->RTValue();
+      int frb = instr->RBValue();
+      double frb_val = get_double_from_d_register(frb);
+      double frt_val = frb_val;
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+    case MTFSFI: {
+      int bf = instr->Bits(25, 23);
+      int imm = instr->Bits(15, 12);
+      int fp_condition_mask = 0xF0000000 >> (bf * 4);
+      fp_condition_reg_ &= ~fp_condition_mask;
+      fp_condition_reg_ |= (imm << (28 - (bf * 4)));
+      if (instr->Bit(0)) {  // RC bit set
+        condition_reg_ &= 0xF0FFFFFF;
+        condition_reg_ |= (imm << 23);
+      }
+      return;
+    }
+    case MTFSF: {
+      int frb = instr->RBValue();
+      double frb_dval = get_double_from_d_register(frb);
+      int64_t* p = reinterpret_cast<int64_t*>(&frb_dval);
+      int32_t frb_ival = static_cast<int32_t>((*p) & 0xffffffff);
+      int l = instr->Bits(25, 25);
+      if (l == 1) {
+        fp_condition_reg_ = frb_ival;
+      } else {
+        UNIMPLEMENTED();
+      }
+      if (instr->Bit(0)) {  // RC bit set
+        UNIMPLEMENTED();
+        // int w = instr->Bits(16, 16);
+        // int flm = instr->Bits(24, 17);
+      }
+      return;
+    }
+    case MFFS: {
+      int frt = instr->RTValue();
+      int64_t lval = static_cast<int64_t>(fp_condition_reg_);
+      double* p = reinterpret_cast<double*>(&lval);
+      set_d_register_from_double(frt, *p);
+      return;
+    }
+    case FABS: {
+      int frt = instr->RTValue();
+      int frb = instr->RBValue();
+      double frb_val = get_double_from_d_register(frb);
+      double frt_val = std::fabs(frb_val);
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+    case FRIM: {
+      int frt = instr->RTValue();
+      int frb = instr->RBValue();
+      double frb_val = get_double_from_d_register(frb);
+      int64_t floor_val = (int64_t)frb_val;
+      if (floor_val > frb_val) floor_val--;
+      double frt_val = static_cast<double>(floor_val);
+      set_d_register_from_double(frt, frt_val);
+      return;
+    }
+  }
+  UNIMPLEMENTED();  // Not used by V8.
+}
+
+#if V8_TARGET_ARCH_PPC64
+void Simulator::ExecuteExt5(Instruction* instr) {
+  switch (instr->Bits(4, 2) << 2) {
+    case RLDICL: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      uintptr_t rs_val = get_register(rs);
+      int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
+      int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
+      DCHECK(sh >= 0 && sh <= 63);
+      DCHECK(mb >= 0 && mb <= 63);
+      // rotate left
+      uintptr_t result = (rs_val << sh) | (rs_val >> (64 - sh));
+      uintptr_t mask = 0xffffffffffffffff >> mb;
+      result &= mask;
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      return;
+    }
+    case RLDICR: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      uintptr_t rs_val = get_register(rs);
+      int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
+      int me = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
+      DCHECK(sh >= 0 && sh <= 63);
+      DCHECK(me >= 0 && me <= 63);
+      // rotate left
+      uintptr_t result = (rs_val << sh) | (rs_val >> (64 - sh));
+      uintptr_t mask = 0xffffffffffffffff << (63 - me);
+      result &= mask;
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      return;
+    }
+    case RLDIC: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      uintptr_t rs_val = get_register(rs);
+      int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
+      int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
+      DCHECK(sh >= 0 && sh <= 63);
+      DCHECK(mb >= 0 && mb <= 63);
+      // rotate left
+      uintptr_t result = (rs_val << sh) | (rs_val >> (64 - sh));
+      uintptr_t mask = (0xffffffffffffffff >> mb) & (0xffffffffffffffff << sh);
+      result &= mask;
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      return;
+    }
+    case RLDIMI: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      uintptr_t rs_val = get_register(rs);
+      intptr_t ra_val = get_register(ra);
+      int sh = (instr->Bits(15, 11) | (instr->Bit(1) << 5));
+      int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
+      int me = 63 - sh;
+      // rotate left
+      uintptr_t result = (rs_val << sh) | (rs_val >> (64 - sh));
+      uintptr_t mask = 0;
+      if (mb < me + 1) {
+        uintptr_t bit = 0x8000000000000000 >> mb;
+        for (; mb <= me; mb++) {
+          mask |= bit;
+          bit >>= 1;
+        }
+      } else if (mb == me + 1) {
+        mask = 0xffffffffffffffff;
+      } else {                                           // mb > me+1
+        uintptr_t bit = 0x8000000000000000 >> (me + 1);  // needs to be tested
+        mask = 0xffffffffffffffff;
+        for (; me < mb; me++) {
+          mask ^= bit;
+          bit >>= 1;
+        }
+      }
+      result &= mask;
+      ra_val &= ~mask;
+      result |= ra_val;
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      return;
+    }
+  }
+  switch (instr->Bits(4, 1) << 1) {
+    case RLDCL: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      int rb = instr->RBValue();
+      uintptr_t rs_val = get_register(rs);
+      uintptr_t rb_val = get_register(rb);
+      int sh = (rb_val & 0x3f);
+      int mb = (instr->Bits(10, 6) | (instr->Bit(5) << 5));
+      DCHECK(sh >= 0 && sh <= 63);
+      DCHECK(mb >= 0 && mb <= 63);
+      // rotate left
+      uintptr_t result = (rs_val << sh) | (rs_val >> (64 - sh));
+      uintptr_t mask = 0xffffffffffffffff >> mb;
+      result &= mask;
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      return;
+    }
+  }
+  UNIMPLEMENTED();  // Not used by V8.
+}
+#endif
+
+
+void Simulator::ExecuteGeneric(Instruction* instr) {
+  int opcode = instr->OpcodeValue() << 26;
+  switch (opcode) {
+    case SUBFIC: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      intptr_t ra_val = get_register(ra);
+      int32_t im_val = instr->Bits(15, 0);
+      im_val = SIGN_EXT_IMM16(im_val);
+      intptr_t alu_out = im_val - ra_val;
+      set_register(rt, alu_out);
+      // todo - handle RC bit
+      break;
+    }
+    case CMPLI: {
+      int ra = instr->RAValue();
+      uint32_t im_val = instr->Bits(15, 0);
+      int cr = instr->Bits(25, 23);
+      uint32_t bf = 0;
+#if V8_TARGET_ARCH_PPC64
+      int L = instr->Bit(21);
+      if (L) {
+#endif
+        uintptr_t ra_val = get_register(ra);
+        if (ra_val < im_val) {
+          bf |= 0x80000000;
+        }
+        if (ra_val > im_val) {
+          bf |= 0x40000000;
+        }
+        if (ra_val == im_val) {
+          bf |= 0x20000000;
+        }
+#if V8_TARGET_ARCH_PPC64
+      } else {
+        uint32_t ra_val = get_register(ra);
+        if (ra_val < im_val) {
+          bf |= 0x80000000;
+        }
+        if (ra_val > im_val) {
+          bf |= 0x40000000;
+        }
+        if (ra_val == im_val) {
+          bf |= 0x20000000;
+        }
+      }
+#endif
+      uint32_t condition_mask = 0xF0000000U >> (cr * 4);
+      uint32_t condition = bf >> (cr * 4);
+      condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
+      break;
+    }
+    case CMPI: {
+      int ra = instr->RAValue();
+      int32_t im_val = instr->Bits(15, 0);
+      im_val = SIGN_EXT_IMM16(im_val);
+      int cr = instr->Bits(25, 23);
+      uint32_t bf = 0;
+#if V8_TARGET_ARCH_PPC64
+      int L = instr->Bit(21);
+      if (L) {
+#endif
+        intptr_t ra_val = get_register(ra);
+        if (ra_val < im_val) {
+          bf |= 0x80000000;
+        }
+        if (ra_val > im_val) {
+          bf |= 0x40000000;
+        }
+        if (ra_val == im_val) {
+          bf |= 0x20000000;
+        }
+#if V8_TARGET_ARCH_PPC64
+      } else {
+        int32_t ra_val = get_register(ra);
+        if (ra_val < im_val) {
+          bf |= 0x80000000;
+        }
+        if (ra_val > im_val) {
+          bf |= 0x40000000;
+        }
+        if (ra_val == im_val) {
+          bf |= 0x20000000;
+        }
+      }
+#endif
+      uint32_t condition_mask = 0xF0000000U >> (cr * 4);
+      uint32_t condition = bf >> (cr * 4);
+      condition_reg_ = (condition_reg_ & ~condition_mask) | condition;
+      break;
+    }
+    case ADDIC: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      uintptr_t ra_val = get_register(ra);
+      uintptr_t im_val = SIGN_EXT_IMM16(instr->Bits(15, 0));
+      uintptr_t alu_out = ra_val + im_val;
+      // Check overflow
+      if (~ra_val < im_val) {
+        special_reg_xer_ = (special_reg_xer_ & ~0xF0000000) | 0x20000000;
+      } else {
+        special_reg_xer_ &= ~0xF0000000;
+      }
+      set_register(rt, alu_out);
+      break;
+    }
+    case ADDI: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int32_t im_val = SIGN_EXT_IMM16(instr->Bits(15, 0));
+      intptr_t alu_out;
+      if (ra == 0) {
+        alu_out = im_val;
+      } else {
+        intptr_t ra_val = get_register(ra);
+        alu_out = ra_val + im_val;
+      }
+      set_register(rt, alu_out);
+      // todo - handle RC bit
+      break;
+    }
+    case ADDIS: {
+      int rt = instr->RTValue();
+      int ra = instr->RAValue();
+      int32_t im_val = (instr->Bits(15, 0) << 16);
+      intptr_t alu_out;
+      if (ra == 0) {  // treat r0 as zero
+        alu_out = im_val;
+      } else {
+        intptr_t ra_val = get_register(ra);
+        alu_out = ra_val + im_val;
+      }
+      set_register(rt, alu_out);
+      break;
+    }
+    case BCX: {
+      ExecuteBranchConditional(instr);
+      break;
+    }
+    case BX: {
+      int offset = (instr->Bits(25, 2) << 8) >> 6;
+      if (instr->Bit(0) == 1) {  // LK flag set
+        special_reg_lr_ = get_pc() + 4;
+      }
+      set_pc(get_pc() + offset);
+      // todo - AA flag
+      break;
+    }
+    case EXT1: {
+      ExecuteExt1(instr);
+      break;
+    }
+    case RLWIMIX: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      uint32_t rs_val = get_register(rs);
+      int32_t ra_val = get_register(ra);
+      int sh = instr->Bits(15, 11);
+      int mb = instr->Bits(10, 6);
+      int me = instr->Bits(5, 1);
+      // rotate left
+      uint32_t result = (rs_val << sh) | (rs_val >> (32 - sh));
+      int mask = 0;
+      if (mb < me + 1) {
+        int bit = 0x80000000 >> mb;
+        for (; mb <= me; mb++) {
+          mask |= bit;
+          bit >>= 1;
+        }
+      } else if (mb == me + 1) {
+        mask = 0xffffffff;
+      } else {                             // mb > me+1
+        int bit = 0x80000000 >> (me + 1);  // needs to be tested
+        mask = 0xffffffff;
+        for (; me < mb; me++) {
+          mask ^= bit;
+          bit >>= 1;
+        }
+      }
+      result &= mask;
+      ra_val &= ~mask;
+      result |= ra_val;
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      break;
+    }
+    case RLWINMX:
+    case RLWNMX: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      uint32_t rs_val = get_register(rs);
+      int sh = 0;
+      if (opcode == RLWINMX) {
+        sh = instr->Bits(15, 11);
+      } else {
+        int rb = instr->RBValue();
+        uint32_t rb_val = get_register(rb);
+        sh = (rb_val & 0x1f);
+      }
+      int mb = instr->Bits(10, 6);
+      int me = instr->Bits(5, 1);
+      // rotate left
+      uint32_t result = (rs_val << sh) | (rs_val >> (32 - sh));
+      int mask = 0;
+      if (mb < me + 1) {
+        int bit = 0x80000000 >> mb;
+        for (; mb <= me; mb++) {
+          mask |= bit;
+          bit >>= 1;
+        }
+      } else if (mb == me + 1) {
+        mask = 0xffffffff;
+      } else {                             // mb > me+1
+        int bit = 0x80000000 >> (me + 1);  // needs to be tested
+        mask = 0xffffffff;
+        for (; me < mb; me++) {
+          mask ^= bit;
+          bit >>= 1;
+        }
+      }
+      result &= mask;
+      set_register(ra, result);
+      if (instr->Bit(0)) {  // RC bit set
+        SetCR0(result);
+      }
+      break;
+    }
+    case ORI: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      intptr_t rs_val = get_register(rs);
+      uint32_t im_val = instr->Bits(15, 0);
+      intptr_t alu_out = rs_val | im_val;
+      set_register(ra, alu_out);
+      break;
+    }
+    case ORIS: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      intptr_t rs_val = get_register(rs);
+      uint32_t im_val = instr->Bits(15, 0);
+      intptr_t alu_out = rs_val | (im_val << 16);
+      set_register(ra, alu_out);
+      break;
+    }
+    case XORI: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      intptr_t rs_val = get_register(rs);
+      uint32_t im_val = instr->Bits(15, 0);
+      intptr_t alu_out = rs_val ^ im_val;
+      set_register(ra, alu_out);
+      // todo - set condition based SO bit
+      break;
+    }
+    case XORIS: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      intptr_t rs_val = get_register(rs);
+      uint32_t im_val = instr->Bits(15, 0);
+      intptr_t alu_out = rs_val ^ (im_val << 16);
+      set_register(ra, alu_out);
+      break;
+    }
+    case ANDIx: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      intptr_t rs_val = get_register(rs);
+      uint32_t im_val = instr->Bits(15, 0);
+      intptr_t alu_out = rs_val & im_val;
+      set_register(ra, alu_out);
+      SetCR0(alu_out);
+      break;
+    }
+    case ANDISx: {
+      int rs = instr->RSValue();
+      int ra = instr->RAValue();
+      intptr_t rs_val = get_register(rs);
+      uint32_t im_val = instr->Bits(15, 0);
+      intptr_t alu_out = rs_val & (im_val << 16);
+      set_register(ra, alu_out);
+      SetCR0(alu_out);
+      break;
+    }
+    case EXT2: {
+      ExecuteExt2(instr);
+      break;
+    }
+
+    case LWZU:
+    case LWZ: {
+      int ra = instr->RAValue();
+      int rt = instr->RTValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
+      set_register(rt, ReadWU(ra_val + offset, instr));
+      if (opcode == LWZU) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + offset);
+      }
+      break;
+    }
+
+    case LBZU:
+    case LBZ: {
+      int ra = instr->RAValue();
+      int rt = instr->RTValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
+      set_register(rt, ReadB(ra_val + offset) & 0xFF);
+      if (opcode == LBZU) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + offset);
+      }
+      break;
+    }
+
+    case STWU:
+    case STW: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      int32_t rs_val = get_register(rs);
+      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
+      WriteW(ra_val + offset, rs_val, instr);
+      if (opcode == STWU) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + offset);
+      }
+      // printf("r%d %08x -> %08x\n", rs, rs_val, offset); // 0xdead
+      break;
+    }
+
+    case STBU:
+    case STB: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      int8_t rs_val = get_register(rs);
+      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
+      WriteB(ra_val + offset, rs_val);
+      if (opcode == STBU) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + offset);
+      }
+      break;
+    }
+
+    case LHZU:
+    case LHZ: {
+      int ra = instr->RAValue();
+      int rt = instr->RTValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
+      uintptr_t result = ReadHU(ra_val + offset, instr) & 0xffff;
+      set_register(rt, result);
+      if (opcode == LHZU) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + offset);
+      }
+      break;
+    }
+
+    case LHA:
+    case LHAU: {
+      UNIMPLEMENTED();
+      break;
+    }
+
+    case STHU:
+    case STH: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      int16_t rs_val = get_register(rs);
+      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
+      WriteH(ra_val + offset, rs_val, instr);
+      if (opcode == STHU) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + offset);
+      }
+      break;
+    }
+
+    case LMW:
+    case STMW: {
+      UNIMPLEMENTED();
+      break;
+    }
+
+    case LFSU:
+    case LFS: {
+      int frt = instr->RTValue();
+      int ra = instr->RAValue();
+      int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      int32_t val = ReadW(ra_val + offset, instr);
+      float* fptr = reinterpret_cast<float*>(&val);
+      set_d_register_from_double(frt, static_cast<double>(*fptr));
+      if (opcode == LFSU) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + offset);
+      }
+      break;
+    }
+
+    case LFDU:
+    case LFD: {
+      int frt = instr->RTValue();
+      int ra = instr->RAValue();
+      int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      double* dptr = reinterpret_cast<double*>(ReadDW(ra_val + offset));
+      set_d_register_from_double(frt, *dptr);
+      if (opcode == LFDU) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + offset);
+      }
+      break;
+    }
+
+    case STFSU: {
+      case STFS:
+        int frs = instr->RSValue();
+        int ra = instr->RAValue();
+        int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
+        intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+        float frs_val = static_cast<float>(get_double_from_d_register(frs));
+        int32_t* p = reinterpret_cast<int32_t*>(&frs_val);
+        WriteW(ra_val + offset, *p, instr);
+        if (opcode == STFSU) {
+          DCHECK(ra != 0);
+          set_register(ra, ra_val + offset);
+        }
+        break;
+    }
+
+    case STFDU:
+    case STFD: {
+      int frs = instr->RSValue();
+      int ra = instr->RAValue();
+      int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
+      intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
+      double frs_val = get_double_from_d_register(frs);
+      int64_t* p = reinterpret_cast<int64_t*>(&frs_val);
+      WriteDW(ra_val + offset, *p);
+      if (opcode == STFDU) {
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + offset);
+      }
+      break;
+    }
+
+    case EXT3:
+      UNIMPLEMENTED();
+    case EXT4: {
+      ExecuteExt4(instr);
+      break;
+    }
+
+#if V8_TARGET_ARCH_PPC64
+    case EXT5: {
+      ExecuteExt5(instr);
+      break;
+    }
+    case LD: {
+      int ra = instr->RAValue();
+      int rt = instr->RTValue();
+      int64_t ra_val = ra == 0 ? 0 : get_register(ra);
+      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3);
+      switch (instr->Bits(1, 0)) {
+        case 0: {  // ld
+          intptr_t* result = ReadDW(ra_val + offset);
+          set_register(rt, *result);
+          break;
+        }
+        case 1: {  // ldu
+          intptr_t* result = ReadDW(ra_val + offset);
+          set_register(rt, *result);
+          DCHECK(ra != 0);
+          set_register(ra, ra_val + offset);
+          break;
+        }
+        case 2: {  // lwa
+          intptr_t result = ReadW(ra_val + offset, instr);
+          set_register(rt, result);
+          break;
+        }
+      }
+      break;
+    }
+
+    case STD: {
+      int ra = instr->RAValue();
+      int rs = instr->RSValue();
+      int64_t ra_val = ra == 0 ? 0 : get_register(ra);
+      int64_t rs_val = get_register(rs);
+      int offset = SIGN_EXT_IMM16(instr->Bits(15, 0) & ~3);
+      WriteDW(ra_val + offset, rs_val);
+      if (instr->Bit(0) == 1) {  // This is the STDU form
+        DCHECK(ra != 0);
+        set_register(ra, ra_val + offset);
+      }
+      break;
+    }
+#endif
+
+    case FAKE_OPCODE: {
+      if (instr->Bits(MARKER_SUBOPCODE_BIT, MARKER_SUBOPCODE_BIT) == 1) {
+        int marker_code = instr->Bits(STUB_MARKER_HIGH_BIT, 0);
+        DCHECK(marker_code < F_NEXT_AVAILABLE_STUB_MARKER);
+        PrintF("Hit stub-marker: %d (EMIT_STUB_MARKER)\n", marker_code);
+      } else {
+        int fake_opcode = instr->Bits(FAKE_OPCODE_HIGH_BIT, 0);
+        if (fake_opcode == fBKPT) {
+          PPCDebugger dbg(this);
+          PrintF("Simulator hit BKPT.\n");
+          dbg.Debug();
+        } else {
+          DCHECK(fake_opcode < fLastFaker);
+          PrintF("Hit ARM opcode: %d(FAKE_OPCODE defined in constant-ppc.h)\n",
+                 fake_opcode);
+          UNIMPLEMENTED();
+        }
+      }
+      break;
+    }
+
+    default: {
+      UNIMPLEMENTED();
+      break;
+    }
+  }
+}  // NOLINT
+
+
+void Simulator::Trace(Instruction* instr) {
+  disasm::NameConverter converter;
+  disasm::Disassembler dasm(converter);
+  // use a reasonably large buffer
+  v8::internal::EmbeddedVector<char, 256> buffer;
+  dasm.InstructionDecode(buffer, reinterpret_cast<byte*>(instr));
+  PrintF("%05d  %08" V8PRIxPTR "  %s\n", icount_,
+         reinterpret_cast<intptr_t>(instr), buffer.start());
+}
+
+
+// Executes the current instruction.
+void Simulator::ExecuteInstruction(Instruction* instr) {
+  if (v8::internal::FLAG_check_icache) {
+    CheckICache(isolate_->simulator_i_cache(), instr);
+  }
+  pc_modified_ = false;
+  if (::v8::internal::FLAG_trace_sim) {
+    Trace(instr);
+  }
+  int opcode = instr->OpcodeValue() << 26;
+  if (opcode == TWI) {
+    SoftwareInterrupt(instr);
+  } else {
+    ExecuteGeneric(instr);
+  }
+  if (!pc_modified_) {
+    set_pc(reinterpret_cast<intptr_t>(instr) + Instruction::kInstrSize);
+  }
+}
+
+
+void Simulator::Execute() {
+  // Get the PC to simulate. Cannot use the accessor here as we need the
+  // raw PC value and not the one used as input to arithmetic instructions.
+  intptr_t program_counter = get_pc();
+
+  if (::v8::internal::FLAG_stop_sim_at == 0) {
+    // Fast version of the dispatch loop without checking whether the simulator
+    // should be stopping at a particular executed instruction.
+    while (program_counter != end_sim_pc) {
+      Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
+      icount_++;
+      ExecuteInstruction(instr);
+      program_counter = get_pc();
+    }
+  } else {
+    // FLAG_stop_sim_at is at the non-default value. Stop in the debugger when
+    // we reach the particular instuction count.
+    while (program_counter != end_sim_pc) {
+      Instruction* instr = reinterpret_cast<Instruction*>(program_counter);
+      icount_++;
+      if (icount_ == ::v8::internal::FLAG_stop_sim_at) {
+        PPCDebugger dbg(this);
+        dbg.Debug();
+      } else {
+        ExecuteInstruction(instr);
+      }
+      program_counter = get_pc();
+    }
+  }
+}
+
+
+void Simulator::CallInternal(byte* entry) {
+// Prepare to execute the code at entry
+#if ABI_USES_FUNCTION_DESCRIPTORS
+  // entry is the function descriptor
+  set_pc(*(reinterpret_cast<intptr_t*>(entry)));
+#else
+  // entry is the instruction address
+  set_pc(reinterpret_cast<intptr_t>(entry));
+#endif
+
+  // Put down marker for end of simulation. The simulator will stop simulation
+  // when the PC reaches this value. By saving the "end simulation" value into
+  // the LR the simulation stops when returning to this call point.
+  special_reg_lr_ = end_sim_pc;
+
+  // Remember the values of non-volatile registers.
+  intptr_t r2_val = get_register(r2);
+  intptr_t r13_val = get_register(r13);
+  intptr_t r14_val = get_register(r14);
+  intptr_t r15_val = get_register(r15);
+  intptr_t r16_val = get_register(r16);
+  intptr_t r17_val = get_register(r17);
+  intptr_t r18_val = get_register(r18);
+  intptr_t r19_val = get_register(r19);
+  intptr_t r20_val = get_register(r20);
+  intptr_t r21_val = get_register(r21);
+  intptr_t r22_val = get_register(r22);
+  intptr_t r23_val = get_register(r23);
+  intptr_t r24_val = get_register(r24);
+  intptr_t r25_val = get_register(r25);
+  intptr_t r26_val = get_register(r26);
+  intptr_t r27_val = get_register(r27);
+  intptr_t r28_val = get_register(r28);
+  intptr_t r29_val = get_register(r29);
+  intptr_t r30_val = get_register(r30);
+  intptr_t r31_val = get_register(fp);
+
+  // Set up the non-volatile registers with a known value. To be able to check
+  // that they are preserved properly across JS execution.
+  intptr_t callee_saved_value = icount_;
+  set_register(r2, callee_saved_value);
+  set_register(r13, callee_saved_value);
+  set_register(r14, callee_saved_value);
+  set_register(r15, callee_saved_value);
+  set_register(r16, callee_saved_value);
+  set_register(r17, callee_saved_value);
+  set_register(r18, callee_saved_value);
+  set_register(r19, callee_saved_value);
+  set_register(r20, callee_saved_value);
+  set_register(r21, callee_saved_value);
+  set_register(r22, callee_saved_value);
+  set_register(r23, callee_saved_value);
+  set_register(r24, callee_saved_value);
+  set_register(r25, callee_saved_value);
+  set_register(r26, callee_saved_value);
+  set_register(r27, callee_saved_value);
+  set_register(r28, callee_saved_value);
+  set_register(r29, callee_saved_value);
+  set_register(r30, callee_saved_value);
+  set_register(fp, callee_saved_value);
+
+  // Start the simulation
+  Execute();
+
+  // Check that the non-volatile registers have been preserved.
+  CHECK_EQ(callee_saved_value, get_register(r2));
+  CHECK_EQ(callee_saved_value, get_register(r13));
+  CHECK_EQ(callee_saved_value, get_register(r14));
+  CHECK_EQ(callee_saved_value, get_register(r15));
+  CHECK_EQ(callee_saved_value, get_register(r16));
+  CHECK_EQ(callee_saved_value, get_register(r17));
+  CHECK_EQ(callee_saved_value, get_register(r18));
+  CHECK_EQ(callee_saved_value, get_register(r19));
+  CHECK_EQ(callee_saved_value, get_register(r20));
+  CHECK_EQ(callee_saved_value, get_register(r21));
+  CHECK_EQ(callee_saved_value, get_register(r22));
+  CHECK_EQ(callee_saved_value, get_register(r23));
+  CHECK_EQ(callee_saved_value, get_register(r24));
+  CHECK_EQ(callee_saved_value, get_register(r25));
+  CHECK_EQ(callee_saved_value, get_register(r26));
+  CHECK_EQ(callee_saved_value, get_register(r27));
+  CHECK_EQ(callee_saved_value, get_register(r28));
+  CHECK_EQ(callee_saved_value, get_register(r29));
+  CHECK_EQ(callee_saved_value, get_register(r30));
+  CHECK_EQ(callee_saved_value, get_register(fp));
+
+  // Restore non-volatile registers with the original value.
+  set_register(r2, r2_val);
+  set_register(r13, r13_val);
+  set_register(r14, r14_val);
+  set_register(r15, r15_val);
+  set_register(r16, r16_val);
+  set_register(r17, r17_val);
+  set_register(r18, r18_val);
+  set_register(r19, r19_val);
+  set_register(r20, r20_val);
+  set_register(r21, r21_val);
+  set_register(r22, r22_val);
+  set_register(r23, r23_val);
+  set_register(r24, r24_val);
+  set_register(r25, r25_val);
+  set_register(r26, r26_val);
+  set_register(r27, r27_val);
+  set_register(r28, r28_val);
+  set_register(r29, r29_val);
+  set_register(r30, r30_val);
+  set_register(fp, r31_val);
+}
+
+
+intptr_t Simulator::Call(byte* entry, int argument_count, ...) {
+  va_list parameters;
+  va_start(parameters, argument_count);
+  // Set up arguments
+
+  // First eight arguments passed in registers r3-r10.
+  int reg_arg_count = (argument_count > 8) ? 8 : argument_count;
+  int stack_arg_count = argument_count - reg_arg_count;
+  for (int i = 0; i < reg_arg_count; i++) {
+    set_register(i + 3, va_arg(parameters, intptr_t));
+  }
+
+  // Remaining arguments passed on stack.
+  intptr_t original_stack = get_register(sp);
+  // Compute position of stack on entry to generated code.
+  intptr_t entry_stack =
+      (original_stack -
+       (kNumRequiredStackFrameSlots + stack_arg_count) * sizeof(intptr_t));
+  if (base::OS::ActivationFrameAlignment() != 0) {
+    entry_stack &= -base::OS::ActivationFrameAlignment();
+  }
+  // Store remaining arguments on stack, from low to high memory.
+  // +2 is a hack for the LR slot + old SP on PPC
+  intptr_t* stack_argument =
+      reinterpret_cast<intptr_t*>(entry_stack) + kStackFrameExtraParamSlot;
+  for (int i = 0; i < stack_arg_count; i++) {
+    stack_argument[i] = va_arg(parameters, intptr_t);
+  }
+  va_end(parameters);
+  set_register(sp, entry_stack);
+
+  CallInternal(entry);
+
+  // Pop stack passed arguments.
+  CHECK_EQ(entry_stack, get_register(sp));
+  set_register(sp, original_stack);
+
+  intptr_t result = get_register(r3);
+  return result;
+}
+
+
+void Simulator::CallFP(byte* entry, double d0, double d1) {
+  set_d_register_from_double(1, d0);
+  set_d_register_from_double(2, d1);
+  CallInternal(entry);
+}
+
+
+int32_t Simulator::CallFPReturnsInt(byte* entry, double d0, double d1) {
+  CallFP(entry, d0, d1);
+  int32_t result = get_register(r3);
+  return result;
+}
+
+
+double Simulator::CallFPReturnsDouble(byte* entry, double d0, double d1) {
+  CallFP(entry, d0, d1);
+  return get_double_from_d_register(1);
+}
+
+
+uintptr_t Simulator::PushAddress(uintptr_t address) {
+  uintptr_t new_sp = get_register(sp) - sizeof(uintptr_t);
+  uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp);
+  *stack_slot = address;
+  set_register(sp, new_sp);
+  return new_sp;
+}
+
+
+uintptr_t Simulator::PopAddress() {
+  uintptr_t current_sp = get_register(sp);
+  uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp);
+  uintptr_t address = *stack_slot;
+  set_register(sp, current_sp + sizeof(uintptr_t));
+  return address;
+}
+}
+}  // namespace v8::internal
+
+#endif  // USE_SIMULATOR
+#endif  // V8_TARGET_ARCH_PPC
diff --git a/src/ppc/simulator-ppc.h b/src/ppc/simulator-ppc.h
new file mode 100644
index 0000000..98fe9a5
--- /dev/null
+++ b/src/ppc/simulator-ppc.h
@@ -0,0 +1,413 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+// Declares a Simulator for PPC instructions if we are not generating a native
+// PPC binary. This Simulator allows us to run and debug PPC code generation on
+// regular desktop machines.
+// V8 calls into generated code by "calling" the CALL_GENERATED_CODE macro,
+// which will start execution in the Simulator or forwards to the real entry
+// on a PPC HW platform.
+
+#ifndef V8_PPC_SIMULATOR_PPC_H_
+#define V8_PPC_SIMULATOR_PPC_H_
+
+#include "src/allocation.h"
+
+#if !defined(USE_SIMULATOR)
+// Running without a simulator on a native ppc platform.
+
+namespace v8 {
+namespace internal {
+
+// When running without a simulator we call the entry directly.
+#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4) \
+  (entry(p0, p1, p2, p3, p4))
+
+typedef int (*ppc_regexp_matcher)(String*, int, const byte*, const byte*, int*,
+                                  int, Address, int, void*, Isolate*);
+
+
+// Call the generated regexp code directly. The code at the entry address
+// should act as a function matching the type ppc_regexp_matcher.
+// The ninth argument is a dummy that reserves the space used for
+// the return address added by the ExitFrame in native calls.
+#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \
+  (FUNCTION_CAST<ppc_regexp_matcher>(entry)(p0, p1, p2, p3, p4, p5, p6, p7,   \
+                                            NULL, p8))
+
+// The stack limit beyond which we will throw stack overflow errors in
+// generated code. Because generated code on ppc uses the C stack, we
+// just use the C stack limit.
+class SimulatorStack : public v8::internal::AllStatic {
+ public:
+  static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
+                                            uintptr_t c_limit) {
+    USE(isolate);
+    return c_limit;
+  }
+
+  static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
+    return try_catch_address;
+  }
+
+  static inline void UnregisterCTryCatch() {}
+};
+}
+}  // namespace v8::internal
+
+#else  // !defined(USE_SIMULATOR)
+// Running with a simulator.
+
+#include "src/assembler.h"
+#include "src/hashmap.h"
+#include "src/ppc/constants-ppc.h"
+
+namespace v8 {
+namespace internal {
+
+class CachePage {
+ public:
+  static const int LINE_VALID = 0;
+  static const int LINE_INVALID = 1;
+
+  static const int kPageShift = 12;
+  static const int kPageSize = 1 << kPageShift;
+  static const int kPageMask = kPageSize - 1;
+  static const int kLineShift = 2;  // The cache line is only 4 bytes right now.
+  static const int kLineLength = 1 << kLineShift;
+  static const int kLineMask = kLineLength - 1;
+
+  CachePage() { memset(&validity_map_, LINE_INVALID, sizeof(validity_map_)); }
+
+  char* ValidityByte(int offset) {
+    return &validity_map_[offset >> kLineShift];
+  }
+
+  char* CachedData(int offset) { return &data_[offset]; }
+
+ private:
+  char data_[kPageSize];  // The cached data.
+  static const int kValidityMapSize = kPageSize >> kLineShift;
+  char validity_map_[kValidityMapSize];  // One byte per line.
+};
+
+
+class Simulator {
+ public:
+  friend class PPCDebugger;
+  enum Register {
+    no_reg = -1,
+    r0 = 0,
+    sp,
+    r2,
+    r3,
+    r4,
+    r5,
+    r6,
+    r7,
+    r8,
+    r9,
+    r10,
+    r11,
+    r12,
+    r13,
+    r14,
+    r15,
+    r16,
+    r17,
+    r18,
+    r19,
+    r20,
+    r21,
+    r22,
+    r23,
+    r24,
+    r25,
+    r26,
+    r27,
+    r28,
+    r29,
+    r30,
+    fp,
+    kNumGPRs = 32,
+    d0 = 0,
+    d1,
+    d2,
+    d3,
+    d4,
+    d5,
+    d6,
+    d7,
+    d8,
+    d9,
+    d10,
+    d11,
+    d12,
+    d13,
+    d14,
+    d15,
+    d16,
+    d17,
+    d18,
+    d19,
+    d20,
+    d21,
+    d22,
+    d23,
+    d24,
+    d25,
+    d26,
+    d27,
+    d28,
+    d29,
+    d30,
+    d31,
+    kNumFPRs = 32
+  };
+
+  explicit Simulator(Isolate* isolate);
+  ~Simulator();
+
+  // The currently executing Simulator instance. Potentially there can be one
+  // for each native thread.
+  static Simulator* current(v8::internal::Isolate* isolate);
+
+  // Accessors for register state.
+  void set_register(int reg, intptr_t value);
+  intptr_t get_register(int reg) const;
+  double get_double_from_register_pair(int reg);
+  void set_d_register_from_double(int dreg, const double dbl) {
+    DCHECK(dreg >= 0 && dreg < kNumFPRs);
+    fp_registers_[dreg] = dbl;
+  }
+  double get_double_from_d_register(int dreg) { return fp_registers_[dreg]; }
+
+  // Special case of set_register and get_register to access the raw PC value.
+  void set_pc(intptr_t value);
+  intptr_t get_pc() const;
+
+  Address get_sp() {
+    return reinterpret_cast<Address>(static_cast<intptr_t>(get_register(sp)));
+  }
+
+  // Accessor to the internal simulator stack area.
+  uintptr_t StackLimit() const;
+
+  // Executes PPC instructions until the PC reaches end_sim_pc.
+  void Execute();
+
+  // Call on program start.
+  static void Initialize(Isolate* isolate);
+
+  // V8 generally calls into generated JS code with 5 parameters and into
+  // generated RegExp code with 7 parameters. This is a convenience function,
+  // which sets up the simulator state and grabs the result on return.
+  intptr_t Call(byte* entry, int argument_count, ...);
+  // Alternative: call a 2-argument double function.
+  void CallFP(byte* entry, double d0, double d1);
+  int32_t CallFPReturnsInt(byte* entry, double d0, double d1);
+  double CallFPReturnsDouble(byte* entry, double d0, double d1);
+
+  // Push an address onto the JS stack.
+  uintptr_t PushAddress(uintptr_t address);
+
+  // Pop an address from the JS stack.
+  uintptr_t PopAddress();
+
+  // Debugger input.
+  void set_last_debugger_input(char* input);
+  char* last_debugger_input() { return last_debugger_input_; }
+
+  // ICache checking.
+  static void FlushICache(v8::internal::HashMap* i_cache, void* start,
+                          size_t size);
+
+  // Returns true if pc register contains one of the 'special_values' defined
+  // below (bad_lr, end_sim_pc).
+  bool has_bad_pc() const;
+
+ private:
+  enum special_values {
+    // Known bad pc value to ensure that the simulator does not execute
+    // without being properly setup.
+    bad_lr = -1,
+    // A pc value used to signal the simulator to stop execution.  Generally
+    // the lr is set to this value on transition from native C code to
+    // simulated execution, so that the simulator can "return" to the native
+    // C code.
+    end_sim_pc = -2
+  };
+
+  // Unsupported instructions use Format to print an error and stop execution.
+  void Format(Instruction* instr, const char* format);
+
+  // Helper functions to set the conditional flags in the architecture state.
+  bool CarryFrom(int32_t left, int32_t right, int32_t carry = 0);
+  bool BorrowFrom(int32_t left, int32_t right);
+  bool OverflowFrom(int32_t alu_out, int32_t left, int32_t right,
+                    bool addition);
+
+  // Helper functions to decode common "addressing" modes
+  int32_t GetShiftRm(Instruction* instr, bool* carry_out);
+  int32_t GetImm(Instruction* instr, bool* carry_out);
+  void ProcessPUW(Instruction* instr, int num_regs, int operand_size,
+                  intptr_t* start_address, intptr_t* end_address);
+  void HandleRList(Instruction* instr, bool load);
+  void HandleVList(Instruction* inst);
+  void SoftwareInterrupt(Instruction* instr);
+
+  // Stop helper functions.
+  inline bool isStopInstruction(Instruction* instr);
+  inline bool isWatchedStop(uint32_t bkpt_code);
+  inline bool isEnabledStop(uint32_t bkpt_code);
+  inline void EnableStop(uint32_t bkpt_code);
+  inline void DisableStop(uint32_t bkpt_code);
+  inline void IncreaseStopCounter(uint32_t bkpt_code);
+  void PrintStopInfo(uint32_t code);
+
+  // Read and write memory.
+  inline uint8_t ReadBU(intptr_t addr);
+  inline int8_t ReadB(intptr_t addr);
+  inline void WriteB(intptr_t addr, uint8_t value);
+  inline void WriteB(intptr_t addr, int8_t value);
+
+  inline uint16_t ReadHU(intptr_t addr, Instruction* instr);
+  inline int16_t ReadH(intptr_t addr, Instruction* instr);
+  // Note: Overloaded on the sign of the value.
+  inline void WriteH(intptr_t addr, uint16_t value, Instruction* instr);
+  inline void WriteH(intptr_t addr, int16_t value, Instruction* instr);
+
+  inline uint32_t ReadWU(intptr_t addr, Instruction* instr);
+  inline int32_t ReadW(intptr_t addr, Instruction* instr);
+  inline void WriteW(intptr_t addr, uint32_t value, Instruction* instr);
+  inline void WriteW(intptr_t addr, int32_t value, Instruction* instr);
+
+  intptr_t* ReadDW(intptr_t addr);
+  void WriteDW(intptr_t addr, int64_t value);
+
+  void Trace(Instruction* instr);
+  void SetCR0(intptr_t result, bool setSO = false);
+  void ExecuteBranchConditional(Instruction* instr);
+  void ExecuteExt1(Instruction* instr);
+  bool ExecuteExt2_10bit(Instruction* instr);
+  bool ExecuteExt2_9bit_part1(Instruction* instr);
+  void ExecuteExt2_9bit_part2(Instruction* instr);
+  void ExecuteExt2(Instruction* instr);
+  void ExecuteExt4(Instruction* instr);
+#if V8_TARGET_ARCH_PPC64
+  void ExecuteExt5(Instruction* instr);
+#endif
+  void ExecuteGeneric(Instruction* instr);
+
+  // Executes one instruction.
+  void ExecuteInstruction(Instruction* instr);
+
+  // ICache.
+  static void CheckICache(v8::internal::HashMap* i_cache, Instruction* instr);
+  static void FlushOnePage(v8::internal::HashMap* i_cache, intptr_t start,
+                           int size);
+  static CachePage* GetCachePage(v8::internal::HashMap* i_cache, void* page);
+
+  // Runtime call support.
+  static void* RedirectExternalReference(
+      void* external_function, v8::internal::ExternalReference::Type type);
+
+  // Handle arguments and return value for runtime FP functions.
+  void GetFpArgs(double* x, double* y, intptr_t* z);
+  void SetFpResult(const double& result);
+  void TrashCallerSaveRegisters();
+
+  void CallInternal(byte* entry);
+
+  // Architecture state.
+  // Saturating instructions require a Q flag to indicate saturation.
+  // There is currently no way to read the CPSR directly, and thus read the Q
+  // flag, so this is left unimplemented.
+  intptr_t registers_[kNumGPRs];
+  int32_t condition_reg_;
+  int32_t fp_condition_reg_;
+  intptr_t special_reg_lr_;
+  intptr_t special_reg_pc_;
+  intptr_t special_reg_ctr_;
+  int32_t special_reg_xer_;
+
+  double fp_registers_[kNumFPRs];
+
+  // Simulator support.
+  char* stack_;
+  bool pc_modified_;
+  int icount_;
+
+  // Debugger input.
+  char* last_debugger_input_;
+
+  // Icache simulation
+  v8::internal::HashMap* i_cache_;
+
+  // Registered breakpoints.
+  Instruction* break_pc_;
+  Instr break_instr_;
+
+  v8::internal::Isolate* isolate_;
+
+  // A stop is watched if its code is less than kNumOfWatchedStops.
+  // Only watched stops support enabling/disabling and the counter feature.
+  static const uint32_t kNumOfWatchedStops = 256;
+
+  // Breakpoint is disabled if bit 31 is set.
+  static const uint32_t kStopDisabledBit = 1 << 31;
+
+  // A stop is enabled, meaning the simulator will stop when meeting the
+  // instruction, if bit 31 of watched_stops_[code].count is unset.
+  // The value watched_stops_[code].count & ~(1 << 31) indicates how many times
+  // the breakpoint was hit or gone through.
+  struct StopCountAndDesc {
+    uint32_t count;
+    char* desc;
+  };
+  StopCountAndDesc watched_stops_[kNumOfWatchedStops];
+};
+
+
+// When running with the simulator transition into simulated execution at this
+// point.
+#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4)                    \
+  reinterpret_cast<Object*>(Simulator::current(Isolate::Current())->Call( \
+      FUNCTION_ADDR(entry), 5, (intptr_t)p0, (intptr_t)p1, (intptr_t)p2,  \
+      (intptr_t)p3, (intptr_t)p4))
+
+#define CALL_GENERATED_REGEXP_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7, p8) \
+  Simulator::current(Isolate::Current())                                      \
+      ->Call(entry, 10, (intptr_t)p0, (intptr_t)p1, (intptr_t)p2,             \
+             (intptr_t)p3, (intptr_t)p4, (intptr_t)p5, (intptr_t)p6,          \
+             (intptr_t)p7, (intptr_t)NULL, (intptr_t)p8)
+
+
+// The simulator has its own stack. Thus it has a different stack limit from
+// the C-based native code.  Setting the c_limit to indicate a very small
+// stack cause stack overflow errors, since the simulator ignores the input.
+// This is unlikely to be an issue in practice, though it might cause testing
+// trouble down the line.
+class SimulatorStack : public v8::internal::AllStatic {
+ public:
+  static inline uintptr_t JsLimitFromCLimit(v8::internal::Isolate* isolate,
+                                            uintptr_t c_limit) {
+    return Simulator::current(isolate)->StackLimit();
+  }
+
+  static inline uintptr_t RegisterCTryCatch(uintptr_t try_catch_address) {
+    Simulator* sim = Simulator::current(Isolate::Current());
+    return sim->PushAddress(try_catch_address);
+  }
+
+  static inline void UnregisterCTryCatch() {
+    Simulator::current(Isolate::Current())->PopAddress();
+  }
+};
+}
+}  // namespace v8::internal
+
+#endif  // !defined(USE_SIMULATOR)
+#endif  // V8_PPC_SIMULATOR_PPC_H_
diff --git a/src/preparse-data.cc b/src/preparse-data.cc
index 15509c0..c101493 100644
--- a/src/preparse-data.cc
+++ b/src/preparse-data.cc
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "include/v8stdint.h"
 #include "src/base/logging.h"
 #include "src/compiler.h"
 #include "src/globals.h"
diff --git a/src/preparser.cc b/src/preparser.cc
index 3173cc0..b552676 100644
--- a/src/preparser.cc
+++ b/src/preparser.cc
@@ -4,8 +4,6 @@
 
 #include <cmath>
 
-#include "include/v8stdint.h"
-
 #include "src/allocation.h"
 #include "src/base/logging.h"
 #include "src/conversions-inl.h"
@@ -19,26 +17,9 @@
 #include "src/unicode.h"
 #include "src/utils.h"
 
-#if V8_LIBC_MSVCRT && (_MSC_VER < 1800)
-namespace std {
-
-// Usually defined in math.h, but not in MSVC until VS2013+.
-// Abstracted to work
-int isfinite(double value);
-
-}  // namespace std
-#endif
-
 namespace v8 {
 namespace internal {
 
-class PreParserTraits::Checkpoint
-    : public ParserBase<PreParserTraits>::CheckpointBase {
- public:
-  explicit Checkpoint(ParserBase<PreParserTraits>* parser)
-      : ParserBase<PreParserTraits>::CheckpointBase(parser) {}
-};
-
 void PreParserTraits::ReportMessageAt(Scanner::Location location,
                                       const char* message,
                                       const char* arg,
@@ -69,6 +50,8 @@
     return PreParserIdentifier::FutureStrictReserved();
   } else if (scanner->current_token() == Token::LET) {
     return PreParserIdentifier::Let();
+  } else if (scanner->current_token() == Token::STATIC) {
+    return PreParserIdentifier::Static();
   } else if (scanner->current_token() == Token::YIELD) {
     return PreParserIdentifier::Yield();
   }
@@ -78,10 +61,10 @@
   if (scanner->UnescapedLiteralMatches("arguments", 9)) {
     return PreParserIdentifier::Arguments();
   }
-  if (scanner->UnescapedLiteralMatches("prototype", 9)) {
+  if (scanner->LiteralMatches("prototype", 9)) {
     return PreParserIdentifier::Prototype();
   }
-  if (scanner->UnescapedLiteralMatches("constructor", 11)) {
+  if (scanner->LiteralMatches("constructor", 11)) {
     return PreParserIdentifier::Constructor();
   }
   return PreParserIdentifier::Default();
@@ -122,13 +105,14 @@
     StrictMode strict_mode, bool is_generator, ParserRecorder* log) {
   log_ = log;
   // Lazy functions always have trivial outer scopes (no with/catch scopes).
-  PreParserScope top_scope(scope_, GLOBAL_SCOPE);
-  FunctionState top_state(&function_state_, &scope_, &top_scope, NULL,
-                          this->ast_value_factory());
+  PreParserScope top_scope(scope_, SCRIPT_SCOPE);
+  PreParserFactory top_factory(NULL);
+  FunctionState top_state(&function_state_, &scope_, &top_scope, &top_factory);
   scope_->SetStrictMode(strict_mode);
   PreParserScope function_scope(scope_, FUNCTION_SCOPE);
-  FunctionState function_state(&function_state_, &scope_, &function_scope, NULL,
-                               this->ast_value_factory());
+  PreParserFactory function_factory(NULL);
+  FunctionState function_state(&function_state_, &scope_, &function_scope,
+                               &function_factory);
   function_state.set_is_generator(is_generator);
   DCHECK_EQ(Token::LBRACE, scanner()->current_token());
   bool ok = true;
@@ -141,13 +125,21 @@
     DCHECK_EQ(Token::RBRACE, scanner()->peek());
     if (scope_->strict_mode() == STRICT) {
       int end_pos = scanner()->location().end_pos;
-      CheckOctalLiteral(start_position, end_pos, &ok);
+      CheckStrictOctalLiteral(start_position, end_pos, &ok);
     }
   }
   return kPreParseSuccess;
 }
 
 
+PreParserExpression PreParserTraits::ParseClassLiteral(
+    PreParserIdentifier name, Scanner::Location class_name_location,
+    bool name_is_strict_reserved, int pos, bool* ok) {
+  return pre_parser_->ParseClassLiteral(name, class_name_location,
+                                        name_is_strict_reserved, pos, ok);
+}
+
+
 // Preparsing checks a JavaScript program and emits preparse-data that helps
 // a later parsing to be faster.
 // See preparser-data.h for the data.
@@ -358,6 +350,12 @@
 
 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) {
   Expect(Token::CLASS, CHECK_OK);
+  if (!allow_harmony_sloppy() && strict_mode() == SLOPPY) {
+    ReportMessage("sloppy_lexical");
+    *ok = false;
+    return Statement::Default();
+  }
+
   int pos = position();
   bool is_strict_reserved = false;
   Identifier name =
@@ -427,6 +425,7 @@
   // ConstBinding ::
   //   BindingPattern '=' AssignmentExpression
   bool require_initializer = false;
+  bool is_strict_const = false;
   if (peek() == Token::VAR) {
     Consume(Token::VAR);
   } else if (peek() == Token::CONST) {
@@ -448,7 +447,8 @@
           *ok = false;
           return Statement::Default();
         }
-        require_initializer = true;
+        is_strict_const = true;
+        require_initializer = var_context != kForStatement;
       } else {
         Scanner::Location location = scanner()->peek_location();
         ReportMessageAt(location, "strict_const");
@@ -478,7 +478,9 @@
     if (nvars > 0) Consume(Token::COMMA);
     ParseIdentifier(kDontAllowEvalOrArguments, CHECK_OK);
     nvars++;
-    if (peek() == Token::ASSIGN || require_initializer) {
+    if (peek() == Token::ASSIGN || require_initializer ||
+        // require initializers for multiple consts.
+        (is_strict_const && peek() == Token::COMMA)) {
       Expect(Token::ASSIGN, CHECK_OK);
       ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
       if (decl_props != NULL) *decl_props = kHasInitializers;
@@ -505,8 +507,7 @@
     // identifier.
     DCHECK(!expr.AsIdentifier().IsFutureReserved());
     DCHECK(strict_mode() == SLOPPY ||
-           (!expr.AsIdentifier().IsFutureStrictReserved() &&
-            !expr.AsIdentifier().IsYield()));
+           !IsFutureStrictReserved(expr.AsIdentifier()));
     Consume(Token::COLON);
     return ParseStatement(ok);
     // Preparsing is disabled for extensions (because the extension details
@@ -514,6 +515,13 @@
     // accept "native function" in the preparser.
   }
   // Parsed expression statement.
+  // Detect attempts at 'let' declarations in sloppy mode.
+  if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY &&
+      expr.IsIdentifier() && expr.AsIdentifier().IsLet()) {
+    ReportMessage("sloppy_lexical", NULL);
+    *ok = false;
+    return Statement::Default();
+  }
   ExpectSemicolon(CHECK_OK);
   return Statement::ExpressionStatement(expr);
 }
@@ -693,16 +701,18 @@
 
   Expect(Token::FOR, CHECK_OK);
   Expect(Token::LPAREN, CHECK_OK);
+  bool is_let_identifier_expression = false;
   if (peek() != Token::SEMICOLON) {
     if (peek() == Token::VAR || peek() == Token::CONST ||
         (peek() == Token::LET && strict_mode() == STRICT)) {
-      bool is_let = peek() == Token::LET;
+      bool is_lexical = peek() == Token::LET ||
+                        (peek() == Token::CONST && strict_mode() == STRICT);
       int decl_count;
       VariableDeclarationProperties decl_props = kHasNoInitializers;
       ParseVariableDeclarations(
           kForStatement, &decl_props, &decl_count, CHECK_OK);
       bool has_initializers = decl_props == kHasInitializers;
-      bool accept_IN = decl_count == 1 && !(is_let && has_initializers);
+      bool accept_IN = decl_count == 1 && !(is_lexical && has_initializers);
       bool accept_OF = !has_initializers;
       if (accept_IN && CheckInOrOf(accept_OF)) {
         ParseExpression(true, CHECK_OK);
@@ -713,6 +723,8 @@
       }
     } else {
       Expression lhs = ParseExpression(false, CHECK_OK);
+      is_let_identifier_expression =
+          lhs.IsIdentifier() && lhs.AsIdentifier().IsLet();
       if (CheckInOrOf(lhs.IsIdentifier())) {
         ParseExpression(true, CHECK_OK);
         Expect(Token::RPAREN, CHECK_OK);
@@ -724,6 +736,13 @@
   }
 
   // Parsed initializer at this point.
+  // Detect attempts at 'let' declarations in sloppy mode.
+  if (peek() == Token::IDENTIFIER && strict_mode() == SLOPPY &&
+      is_let_identifier_expression) {
+    ReportMessage("sloppy_lexical", NULL);
+    *ok = false;
+    return Statement::Default();
+  }
   Expect(Token::SEMICOLON, CHECK_OK);
 
   if (peek() != Token::SEMICOLON) {
@@ -831,8 +850,9 @@
   // Parse function body.
   ScopeType outer_scope_type = scope_->type();
   PreParserScope function_scope(scope_, FUNCTION_SCOPE);
-  FunctionState function_state(&function_state_, &scope_, &function_scope, NULL,
-                               this->ast_value_factory());
+  PreParserFactory factory(NULL);
+  FunctionState function_state(&function_state_, &scope_, &function_scope,
+                               &factory);
   function_state.set_is_generator(IsGeneratorFunction(kind));
   //  FormalParameterList ::
   //    '(' (Identifier)*[','] ')'
@@ -874,7 +894,7 @@
 
   // See Parser::ParseFunctionLiteral for more information about lazy parsing
   // and lazy compilation.
-  bool is_lazily_parsed = (outer_scope_type == GLOBAL_SCOPE && allow_lazy() &&
+  bool is_lazily_parsed = (outer_scope_type == SCRIPT_SCOPE && allow_lazy() &&
                            !parenthesized_function_);
   parenthesized_function_ = false;
 
@@ -917,7 +937,7 @@
     }
 
     int end_position = scanner()->location().end_pos;
-    CheckOctalLiteral(start_position, end_position, CHECK_OK);
+    CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
   }
 
   return Expression::Default();
@@ -939,11 +959,52 @@
 }
 
 
+PreParserExpression PreParser::ParseClassLiteral(
+    PreParserIdentifier name, Scanner::Location class_name_location,
+    bool name_is_strict_reserved, int pos, bool* ok) {
+  // All parts of a ClassDeclaration and ClassExpression are strict code.
+  if (name_is_strict_reserved) {
+    ReportMessageAt(class_name_location, "unexpected_strict_reserved");
+    *ok = false;
+    return EmptyExpression();
+  }
+  if (IsEvalOrArguments(name)) {
+    ReportMessageAt(class_name_location, "strict_eval_arguments");
+    *ok = false;
+    return EmptyExpression();
+  }
+
+  PreParserScope scope = NewScope(scope_, BLOCK_SCOPE);
+  BlockState block_state(&scope_, &scope);
+  scope_->SetStrictMode(STRICT);
+  scope_->SetScopeName(name);
+
+  if (Check(Token::EXTENDS)) {
+    ParseLeftHandSideExpression(CHECK_OK);
+  }
+
+  bool has_seen_constructor = false;
+
+  Expect(Token::LBRACE, CHECK_OK);
+  while (peek() != Token::RBRACE) {
+    if (Check(Token::SEMICOLON)) continue;
+    const bool in_class = true;
+    const bool is_static = false;
+    ParsePropertyDefinition(NULL, in_class, is_static, &has_seen_constructor,
+                            CHECK_OK);
+  }
+
+  Expect(Token::RBRACE, CHECK_OK);
+
+  return Expression::Default();
+}
+
+
 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
   // CallRuntime ::
   //   '%' Identifier Arguments
   Expect(Token::MOD, CHECK_OK);
-  if (!allow_natives_syntax()) {
+  if (!allow_natives()) {
     *ok = false;
     return Expression::Default();
   }
diff --git a/src/preparser.h b/src/preparser.h
index 78f6a26..5fb60d0 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -70,7 +70,6 @@
 
   ParserBase(Scanner* scanner, uintptr_t stack_limit, v8::Extension* extension,
              ParserRecorder* log, typename Traits::Type::Zone* zone,
-             AstNode::IdGen* ast_node_id_gen,
              typename Traits::Type::Parser this_object)
       : Traits(this_object),
         parenthesized_function_(false),
@@ -84,47 +83,65 @@
         scanner_(scanner),
         stack_overflow_(false),
         allow_lazy_(false),
-        allow_natives_syntax_(false),
-        allow_arrow_functions_(false),
+        allow_natives_(false),
+        allow_harmony_arrow_functions_(false),
         allow_harmony_object_literals_(false),
-        zone_(zone),
-        ast_node_id_gen_(ast_node_id_gen) {}
+        allow_harmony_sloppy_(false),
+        zone_(zone) {}
 
   // Getters that indicate whether certain syntactical constructs are
   // allowed to be parsed by this instance of the parser.
   bool allow_lazy() const { return allow_lazy_; }
-  bool allow_natives_syntax() const { return allow_natives_syntax_; }
-  bool allow_arrow_functions() const { return allow_arrow_functions_; }
-  bool allow_modules() const { return scanner()->HarmonyModules(); }
+  bool allow_natives() const { return allow_natives_; }
+  bool allow_harmony_arrow_functions() const {
+    return allow_harmony_arrow_functions_;
+  }
+  bool allow_harmony_modules() const { return scanner()->HarmonyModules(); }
   bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
   bool allow_harmony_numeric_literals() const {
     return scanner()->HarmonyNumericLiterals();
   }
-  bool allow_classes() const { return scanner()->HarmonyClasses(); }
+  bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); }
   bool allow_harmony_object_literals() const {
     return allow_harmony_object_literals_;
   }
+  bool allow_harmony_templates() const { return scanner()->HarmonyTemplates(); }
+  bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; }
+  bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); }
 
   // Setters that determine whether certain syntactical constructs are
   // allowed to be parsed by this instance of the parser.
   void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
-  void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
-  void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; }
-  void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
+  void set_allow_natives(bool allow) { allow_natives_ = allow; }
+  void set_allow_harmony_arrow_functions(bool allow) {
+    allow_harmony_arrow_functions_ = allow;
+  }
+  void set_allow_harmony_modules(bool allow) {
+    scanner()->SetHarmonyModules(allow);
+  }
   void set_allow_harmony_scoping(bool allow) {
     scanner()->SetHarmonyScoping(allow);
   }
   void set_allow_harmony_numeric_literals(bool allow) {
     scanner()->SetHarmonyNumericLiterals(allow);
   }
-  void set_allow_classes(bool allow) { scanner()->SetHarmonyClasses(allow); }
+  void set_allow_harmony_classes(bool allow) {
+    scanner()->SetHarmonyClasses(allow);
+  }
   void set_allow_harmony_object_literals(bool allow) {
     allow_harmony_object_literals_ = allow;
   }
+  void set_allow_harmony_templates(bool allow) {
+    scanner()->SetHarmonyTemplates(allow);
+  }
+  void set_allow_harmony_sloppy(bool allow) {
+    allow_harmony_sloppy_ = allow;
+  }
+  void set_allow_harmony_unicode(bool allow) {
+    scanner()->SetHarmonyUnicode(allow);
+  }
 
  protected:
-  friend class Traits::Checkpoint;
-
   enum AllowEvalOrArgumentsAsIdentifier {
     kAllowEvalOrArguments,
     kDontAllowEvalOrArguments
@@ -135,7 +152,7 @@
     PARSE_EAGERLY
   };
 
-  class CheckpointBase;
+  class Checkpoint;
   class ObjectLiteralChecker;
 
   // ---------------------------------------------------------------------------
@@ -165,15 +182,7 @@
     FunctionState(FunctionState** function_state_stack,
                   typename Traits::Type::Scope** scope_stack,
                   typename Traits::Type::Scope* scope,
-                  typename Traits::Type::Zone* zone = NULL,
-                  AstValueFactory* ast_value_factory = NULL,
-                  AstNode::IdGen* ast_node_id_gen = NULL);
-    FunctionState(FunctionState** function_state_stack,
-                  typename Traits::Type::Scope** scope_stack,
-                  typename Traits::Type::Scope** scope,
-                  typename Traits::Type::Zone* zone = NULL,
-                  AstValueFactory* ast_value_factory = NULL,
-                  AstNode::IdGen* ast_node_id_gen = NULL);
+                  typename Traits::Type::Factory* factory);
     ~FunctionState();
 
     int NextMaterializedLiteralIndex() {
@@ -204,7 +213,7 @@
       return generator_object_variable_;
     }
 
-    typename Traits::Type::Factory* factory() { return &factory_; }
+    typename Traits::Type::Factory* factory() { return factory_; }
 
    private:
     // Used to assign an index to each literal that needs materialization in
@@ -229,22 +238,20 @@
     FunctionState* outer_function_state_;
     typename Traits::Type::Scope** scope_stack_;
     typename Traits::Type::Scope* outer_scope_;
-    AstNode::IdGen* ast_node_id_gen_;  // Only used by ParserTraits.
-    AstNode::IdGen saved_id_gen_;      // Ditto.
     typename Traits::Type::Zone* extra_param_;
-    typename Traits::Type::Factory factory_;
+    typename Traits::Type::Factory* factory_;
 
     friend class ParserTraits;
-    friend class CheckpointBase;
+    friend class Checkpoint;
   };
 
   // Annoyingly, arrow functions first parse as comma expressions, then when we
   // see the => we have to go back and reinterpret the arguments as being formal
   // parameters.  To do so we need to reset some of the parser state back to
   // what it was before the arguments were first seen.
-  class CheckpointBase BASE_EMBEDDED {
+  class Checkpoint BASE_EMBEDDED {
    public:
-    explicit CheckpointBase(ParserBase* parser) {
+    explicit Checkpoint(ParserBase* parser) {
       function_state_ = parser->function_state_;
       next_materialized_literal_index_ =
           function_state_->next_materialized_literal_index_;
@@ -289,7 +296,6 @@
   void set_stack_overflow() { stack_overflow_ = true; }
   Mode mode() const { return mode_; }
   typename Traits::Type::Zone* zone() const { return zone_; }
-  AstNode::IdGen* ast_node_id_gen() const { return ast_node_id_gen_; }
 
   INLINE(Token::Value peek()) {
     if (stack_overflow_) return Token::ILLEGAL;
@@ -351,22 +357,24 @@
 
   bool peek_any_identifier() {
     Token::Value next = peek();
-    return next == Token::IDENTIFIER ||
-        next == Token::FUTURE_RESERVED_WORD ||
-        next == Token::FUTURE_STRICT_RESERVED_WORD ||
-        next == Token::LET ||
-        next == Token::YIELD;
+    return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD ||
+           next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
+           next == Token::STATIC || next == Token::YIELD;
   }
 
   bool CheckContextualKeyword(Vector<const char> keyword) {
-    if (peek() == Token::IDENTIFIER &&
-        scanner()->is_next_contextual_keyword(keyword)) {
+    if (PeekContextualKeyword(keyword)) {
       Consume(Token::IDENTIFIER);
       return true;
     }
     return false;
   }
 
+  bool PeekContextualKeyword(Vector<const char> keyword) {
+    return peek() == Token::IDENTIFIER &&
+           scanner()->is_next_contextual_keyword(keyword);
+  }
+
   void ExpectContextualKeyword(Vector<const char> keyword, bool* ok) {
     Expect(Token::IDENTIFIER, ok);
     if (!*ok) return;
@@ -377,17 +385,26 @@
   }
 
   // Checks whether an octal literal was last seen between beg_pos and end_pos.
-  // If so, reports an error. Only called for strict mode.
-  void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
+  // If so, reports an error. Only called for strict mode and template strings.
+  void CheckOctalLiteral(int beg_pos, int end_pos, const char* error,
+                         bool* ok) {
     Scanner::Location octal = scanner()->octal_position();
     if (octal.IsValid() && beg_pos <= octal.beg_pos &&
         octal.end_pos <= end_pos) {
-      ReportMessageAt(octal, "strict_octal_literal");
+      ReportMessageAt(octal, error);
       scanner()->clear_octal_position();
       *ok = false;
     }
   }
 
+  inline void CheckStrictOctalLiteral(int beg_pos, int end_pos, bool* ok) {
+    CheckOctalLiteral(beg_pos, end_pos, "strict_octal_literal", ok);
+  }
+
+  inline void CheckTemplateOctalLiteral(int beg_pos, int end_pos, bool* ok) {
+    CheckOctalLiteral(beg_pos, end_pos, "template_octal_literal", ok);
+  }
+
   // Validates strict mode for function parameter lists. This has to be
   // done after parsing the function, since the function can declare
   // itself strict.
@@ -450,7 +467,7 @@
   void ReportMessageAt(Scanner::Location location, const char* message,
                        bool is_reference_error = false) {
     Traits::ReportMessageAt(location, message,
-                            reinterpret_cast<const char*>(NULL),
+                            reinterpret_cast<const char*>(0),
                             is_reference_error);
   }
 
@@ -487,6 +504,7 @@
   ExpressionT ParseObjectLiteral(bool* ok);
   ObjectLiteralPropertyT ParsePropertyDefinition(ObjectLiteralChecker* checker,
                                                  bool in_class, bool is_static,
+                                                 bool* has_seen_constructor,
                                                  bool* ok);
   typename Traits::Type::ExpressionList ParseArguments(bool* ok);
   ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok);
@@ -502,10 +520,8 @@
                                                 bool* ok);
   ExpressionT ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
                                         bool* ok);
-  ExpressionT ParseClassLiteral(IdentifierT name,
-                                Scanner::Location function_name_location,
-                                bool name_is_strict_reserved, int pos,
-                                bool* ok);
+  ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok);
+  void AddTemplateExpression(ExpressionT);
 
   // Checks if the expression is a valid reference expression (e.g., on the
   // left-hand side of assignments). Although ruled out by ECMA as early errors,
@@ -587,12 +603,12 @@
   bool stack_overflow_;
 
   bool allow_lazy_;
-  bool allow_natives_syntax_;
-  bool allow_arrow_functions_;
+  bool allow_natives_;
+  bool allow_harmony_arrow_functions_;
   bool allow_harmony_object_literals_;
+  bool allow_harmony_sloppy_;
 
   typename Traits::Type::Zone* zone_;  // Only used by Parser.
-  AstNode::IdGen* ast_node_id_gen_;
 };
 
 
@@ -617,6 +633,9 @@
   static PreParserIdentifier Let() {
     return PreParserIdentifier(kLetIdentifier);
   }
+  static PreParserIdentifier Static() {
+    return PreParserIdentifier(kStaticIdentifier);
+  }
   static PreParserIdentifier Yield() {
     return PreParserIdentifier(kYieldIdentifier);
   }
@@ -627,7 +646,11 @@
     return PreParserIdentifier(kConstructorIdentifier);
   }
   bool IsEval() const { return type_ == kEvalIdentifier; }
-  bool IsArguments() const { return type_ == kArgumentsIdentifier; }
+  bool IsArguments(const AstValueFactory* = NULL) const {
+    return type_ == kArgumentsIdentifier;
+  }
+  bool IsLet() const { return type_ == kLetIdentifier; }
+  bool IsStatic() const { return type_ == kStaticIdentifier; }
   bool IsYield() const { return type_ == kYieldIdentifier; }
   bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
   bool IsConstructor() const { return type_ == kConstructorIdentifier; }
@@ -636,9 +659,16 @@
   }
   bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
   bool IsFutureStrictReserved() const {
-    return type_ == kFutureStrictReservedIdentifier;
+    return type_ == kFutureStrictReservedIdentifier ||
+           type_ == kLetIdentifier || type_ == kStaticIdentifier ||
+           type_ == kYieldIdentifier;
   }
   bool IsValidStrictVariable() const { return type_ == kUnknownIdentifier; }
+  V8_INLINE bool IsValidArrowParam() const {
+    // A valid identifier can be an arrow function parameter
+    // except for eval, arguments, yield, and reserved keywords.
+    return !(IsEval() || IsArguments() || IsFutureStrictReserved());
+  }
 
   // Allow identifier->name()[->length()] to work. The preparser
   // does not need the actual positions/lengths of the identifiers.
@@ -654,6 +684,7 @@
     kFutureReservedIdentifier,
     kFutureStrictReservedIdentifier,
     kLetIdentifier,
+    kStaticIdentifier,
     kYieldIdentifier,
     kEvalIdentifier,
     kArgumentsIdentifier,
@@ -668,30 +699,27 @@
 };
 
 
-// Bits 0 and 1 are used to identify the type of expression:
-// If bit 0 is set, it's an identifier.
-// if bit 1 is set, it's a string literal.
-// If neither is set, it's no particular type, and both set isn't
-// use yet.
 class PreParserExpression {
  public:
   static PreParserExpression Default() {
-    return PreParserExpression(kUnknownExpression);
+    return PreParserExpression(TypeField::encode(kExpression));
   }
 
   static PreParserExpression FromIdentifier(PreParserIdentifier id) {
-    return PreParserExpression(kTypeIdentifier |
-                               (id.type_ << kIdentifierShift));
+    return PreParserExpression(TypeField::encode(kIdentifierExpression) |
+                               IdentifierTypeField::encode(id.type_));
   }
 
   static PreParserExpression BinaryOperation(PreParserExpression left,
                                              Token::Value op,
                                              PreParserExpression right) {
-    int code = ((op == Token::COMMA) && !left.is_parenthesized() &&
-                !right.is_parenthesized())
-                   ? left.ArrowParamListBit() & right.ArrowParamListBit()
-                   : 0;
-    return PreParserExpression(kTypeBinaryOperation | code);
+    bool valid_arrow_param_list =
+        op == Token::COMMA && !left.is_parenthesized() &&
+        !right.is_parenthesized() && left.IsValidArrowParams() &&
+        right.IsValidArrowParams();
+    return PreParserExpression(
+        TypeField::encode(kBinaryOperationExpression) |
+        IsValidArrowParamListField::encode(valid_arrow_param_list));
   }
 
   static PreParserExpression EmptyArrowParamList() {
@@ -701,88 +729,120 @@
   }
 
   static PreParserExpression StringLiteral() {
-    return PreParserExpression(kUnknownStringLiteral);
+    return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
+                               IsUseStrictField::encode(false));
   }
 
   static PreParserExpression UseStrictStringLiteral() {
-    return PreParserExpression(kUseStrictString);
+    return PreParserExpression(TypeField::encode(kStringLiteralExpression) |
+                               IsUseStrictField::encode(true));
   }
 
   static PreParserExpression This() {
-    return PreParserExpression(kThisExpression);
+    return PreParserExpression(TypeField::encode(kExpression) |
+                               ExpressionTypeField::encode(kThisExpression));
   }
 
   static PreParserExpression Super() {
-    return PreParserExpression(kSuperExpression);
+    return PreParserExpression(TypeField::encode(kExpression) |
+                               ExpressionTypeField::encode(kSuperExpression));
   }
 
   static PreParserExpression ThisProperty() {
-    return PreParserExpression(kThisPropertyExpression);
+    return PreParserExpression(
+        TypeField::encode(kExpression) |
+        ExpressionTypeField::encode(kThisPropertyExpression));
   }
 
   static PreParserExpression Property() {
-    return PreParserExpression(kPropertyExpression);
+    return PreParserExpression(
+        TypeField::encode(kExpression) |
+        ExpressionTypeField::encode(kPropertyExpression));
   }
 
   static PreParserExpression Call() {
-    return PreParserExpression(kCallExpression);
+    return PreParserExpression(TypeField::encode(kExpression) |
+                               ExpressionTypeField::encode(kCallExpression));
   }
 
-  bool IsIdentifier() const { return (code_ & kTypeMask) == kTypeIdentifier; }
+  static PreParserExpression NoTemplateTag() {
+    return PreParserExpression(TypeField::encode(kExpression) |
+                               ExpressionTypeField::encode(
+                                  kNoTemplateTagExpression));
+  }
+
+  bool IsIdentifier() const {
+    return TypeField::decode(code_) == kIdentifierExpression;
+  }
 
   PreParserIdentifier AsIdentifier() const {
     DCHECK(IsIdentifier());
-    return PreParserIdentifier(
-        static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
+    return PreParserIdentifier(IdentifierTypeField::decode(code_));
   }
 
   bool IsStringLiteral() const {
-    return (code_ & kTypeMask) == kTypeStringLiteral;
+    return TypeField::decode(code_) == kStringLiteralExpression;
   }
 
   bool IsUseStrictLiteral() const {
-    return (code_ & kUseStrictString) == kUseStrictString;
+    return TypeField::decode(code_) == kStringLiteralExpression &&
+           IsUseStrictField::decode(code_);
   }
 
-  bool IsThis() const { return (code_ & kThisExpression) == kThisExpression; }
+  bool IsThis() const {
+    return TypeField::decode(code_) == kExpression &&
+           ExpressionTypeField::decode(code_) == kThisExpression;
+  }
 
   bool IsThisProperty() const {
-    return (code_ & kThisPropertyExpression) == kThisPropertyExpression;
+    return TypeField::decode(code_) == kExpression &&
+           ExpressionTypeField::decode(code_) == kThisPropertyExpression;
   }
 
   bool IsProperty() const {
-    return (code_ & kPropertyExpression) == kPropertyExpression ||
-           (code_ & kThisPropertyExpression) == kThisPropertyExpression;
+    return TypeField::decode(code_) == kExpression &&
+           (ExpressionTypeField::decode(code_) == kPropertyExpression ||
+            ExpressionTypeField::decode(code_) == kThisPropertyExpression);
   }
 
-  bool IsCall() const { return (code_ & kCallExpression) == kCallExpression; }
+  bool IsCall() const {
+    return TypeField::decode(code_) == kExpression &&
+           ExpressionTypeField::decode(code_) == kCallExpression;
+  }
 
   bool IsValidReferenceExpression() const {
     return IsIdentifier() || IsProperty();
   }
 
   bool IsValidArrowParamList() const {
-    return (ArrowParamListBit() & kBinaryOperationArrowParamList) != 0 &&
-           (code_ & kMultiParenthesizedExpression) == 0;
+    return IsValidArrowParams() &&
+           ParenthesizationField::decode(code_) !=
+               kMultiParenthesizedExpression;
   }
 
   // At the moment PreParser doesn't track these expression types.
   bool IsFunctionLiteral() const { return false; }
   bool IsCallNew() const { return false; }
 
+  bool IsNoTemplateTag() const {
+    return TypeField::decode(code_) == kExpression &&
+           ExpressionTypeField::decode(code_) == kNoTemplateTagExpression;
+  }
+
   PreParserExpression AsFunctionLiteral() { return *this; }
 
   bool IsBinaryOperation() const {
-    return (code_ & kTypeMask) == kTypeBinaryOperation;
+    return TypeField::decode(code_) == kBinaryOperationExpression;
   }
 
   bool is_parenthesized() const {
-    return (code_ & kParenthesizedExpression) != 0;
+    return ParenthesizationField::decode(code_) != kNotParenthesized;
   }
 
   void increase_parenthesization_level() {
-    code_ |= is_parenthesized() ? kMultiParenthesizedExpression
-                                : kParenthesizedExpression;
+    code_ = ParenthesizationField::update(
+        code_, is_parenthesized() ? kMultiParenthesizedExpression
+                                  : kParanthesizedExpression);
   }
 
   // Dummy implementation for making expression->somefunc() work in both Parser
@@ -795,69 +855,54 @@
 
   int position() const { return RelocInfo::kNoPosition; }
   void set_function_token_position(int position) {}
-  void set_ast_properties(int* ast_properties) {}
-  void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {}
-
-  bool operator==(const PreParserExpression& other) const {
-    return code_ == other.code_;
-  }
-  bool operator!=(const PreParserExpression& other) const {
-    return code_ != other.code_;
-  }
 
  private:
-  // Least significant 2 bits are used as expression type. The third least
-  // significant bit tracks whether an expression is parenthesized. If the
-  // expression is an identifier or a string literal, the other bits
-  // describe the type/ (see PreParserIdentifier::Type and string literal
-  // constants below). For binary operations, the other bits are flags
-  // which further describe the contents of the expression.
-  enum {
-    kUnknownExpression = 0,
-    kTypeMask = 1 | 2,
-    kParenthesizedExpression = (1 << 2),
-    kMultiParenthesizedExpression = (1 << 3),
-
-    // Identifiers
-    kTypeIdentifier = 1,  // Used to detect labels.
-    kIdentifierShift = 5,
-    kTypeStringLiteral = 2,  // Used to detect directive prologue.
-    kUnknownStringLiteral = kTypeStringLiteral,
-    kUseStrictString = kTypeStringLiteral | 32,
-    kStringLiteralMask = kUseStrictString,
-
-    // Binary operations. Those are needed to detect certain keywords and
-    // duplicated identifier in parameter lists for arrow functions, because
-    // they are initially parsed as comma-separated expressions.
-    kTypeBinaryOperation = 3,
-    kBinaryOperationArrowParamList = (1 << 4),
-
-    // Below here applies if neither identifier nor string literal. Reserve the
-    // 2 least significant bits for flags.
-    kThisExpression = (1 << 4),
-    kThisPropertyExpression = (2 << 4),
-    kPropertyExpression = (3 << 4),
-    kCallExpression = (4 << 4),
-    kSuperExpression = (5 << 4)
+  enum Type {
+    kExpression,
+    kIdentifierExpression,
+    kStringLiteralExpression,
+    kBinaryOperationExpression
   };
 
-  explicit PreParserExpression(int expression_code) : code_(expression_code) {}
+  enum Parenthesization {
+    kNotParenthesized,
+    kParanthesizedExpression,
+    kMultiParenthesizedExpression
+  };
 
-  V8_INLINE int ArrowParamListBit() const {
-    if (IsBinaryOperation()) return code_ & kBinaryOperationArrowParamList;
-    if (IsIdentifier()) {
-      const PreParserIdentifier ident = AsIdentifier();
-      // A valid identifier can be an arrow function parameter list
-      // except for eval, arguments, yield, and reserved keywords.
-      if (ident.IsEval() || ident.IsArguments() || ident.IsYield() ||
-          ident.IsFutureStrictReserved())
-        return 0;
-      return kBinaryOperationArrowParamList;
-    }
-    return 0;
+  enum ExpressionType {
+    kThisExpression,
+    kThisPropertyExpression,
+    kPropertyExpression,
+    kCallExpression,
+    kSuperExpression,
+    kNoTemplateTagExpression
+  };
+
+  explicit PreParserExpression(uint32_t expression_code)
+      : code_(expression_code) {}
+
+  V8_INLINE bool IsValidArrowParams() const {
+    return IsBinaryOperation()
+               ? IsValidArrowParamListField::decode(code_)
+               : (IsIdentifier() && AsIdentifier().IsValidArrowParam());
   }
 
-  int code_;
+  // The first four bits are for the Type and Parenthesization.
+  typedef BitField<Type, 0, 2> TypeField;
+  typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField;
+
+  // The rest of the bits are interpreted depending on the value
+  // of the Type field, so they can share the storage.
+  typedef BitField<ExpressionType, ParenthesizationField::kNext, 3>
+      ExpressionTypeField;
+  typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField;
+  typedef BitField<bool, ParenthesizationField::kNext, 1>
+      IsValidArrowParamListField;
+  typedef BitField<PreParserIdentifier::Type, ParenthesizationField::kNext, 10>
+      IdentifierTypeField;
+
+  uint32_t code_;
 };
 
 
@@ -958,6 +1003,10 @@
 
   bool IsDeclared(const PreParserIdentifier& identifier) const { return false; }
   void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {}
+  void RecordArgumentsUsage() {}
+  void RecordSuperPropertyUsage() {}
+  void RecordSuperConstructorCallUsage() {}
+  void RecordThisUsage() {}
 
   // Allow scope->Foo() to work.
   PreParserScope* operator->() { return this; }
@@ -970,7 +1019,7 @@
 
 class PreParserFactory {
  public:
-  PreParserFactory(void*, void*, void*) {}
+  explicit PreParserFactory(void* unused_value_factory) {}
   PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
                                        int pos) {
     return PreParserExpression::Default();
@@ -1083,18 +1132,10 @@
       int position) {
     return PreParserExpression::Default();
   }
-  PreParserExpression NewClassLiteral(PreParserIdentifier name,
-                                      PreParserExpression extends,
-                                      PreParserExpression constructor,
-                                      PreParserExpressionList properties,
-                                      int position) {
-    return PreParserExpression::Default();
-  }
 
   // Return the object itself as AstVisitor and implement the needed
   // dummy method right in this class.
   PreParserFactory* visitor() { return this; }
-  BailoutReason dont_optimize_reason() { return kNoReason; }
   int* ast_properties() {
     static int dummy = 42;
     return &dummy;
@@ -1114,6 +1155,7 @@
     // Used by FunctionState and BlockState.
     typedef PreParserScope Scope;
     typedef PreParserScope ScopePtr;
+    inline static Scope* ptr_to_scope(ScopePtr& scope) { return &scope; }
 
     // PreParser doesn't need to store generator variables.
     typedef void GeneratorVariable;
@@ -1139,17 +1181,8 @@
     typedef PreParserFactory Factory;
   };
 
-  class Checkpoint;
-
   explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
 
-  // Custom operations executed when FunctionStates are created and
-  // destructed. (The PreParser doesn't need to do anything.)
-  template <typename FunctionState>
-  static void SetUpFunctionState(FunctionState* function_state) {}
-  template <typename FunctionState>
-  static void TearDownFunctionState(FunctionState* function_state) {}
-
   // Helper functions for recursive descent.
   static bool IsEvalOrArguments(PreParserIdentifier identifier) {
     return identifier.IsEvalOrArguments();
@@ -1177,7 +1210,7 @@
   }
 
   static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
-    return identifier.IsYield() || identifier.IsFutureStrictReserved();
+    return identifier.IsFutureStrictReserved();
   }
 
   static bool IsBoilerplateProperty(PreParserExpression property) {
@@ -1189,6 +1222,10 @@
     return false;
   }
 
+  static PreParserExpression GetPropertyValue(PreParserExpression property) {
+    return PreParserExpression::Default();
+  }
+
   // Functions for encapsulating the differences between parsing and preparsing;
   // operations interleaved with the recursive descent.
   static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
@@ -1314,12 +1351,9 @@
     return PreParserExpression::Super();
   }
 
-  static PreParserExpression ClassLiteral(PreParserIdentifier name,
-                                          PreParserExpression extends,
-                                          PreParserExpression constructor,
-                                          PreParserExpressionList properties,
-                                          int position,
-                                          PreParserFactory* factory) {
+  static PreParserExpression DefaultConstructor(bool call_super,
+                                                PreParserScope* scope, int pos,
+                                                int end_pos) {
     return PreParserExpression::Default();
   }
 
@@ -1377,6 +1411,29 @@
     return 0;
   }
 
+  struct TemplateLiteralState {};
+
+  TemplateLiteralState OpenTemplateLiteral(int pos) {
+    return TemplateLiteralState();
+  }
+  void AddTemplateSpan(TemplateLiteralState*, bool) {}
+  void AddTemplateExpression(TemplateLiteralState*, PreParserExpression) {}
+  PreParserExpression CloseTemplateLiteral(TemplateLiteralState*, int,
+                                           PreParserExpression tag) {
+    if (IsTaggedTemplate(tag)) {
+      // Emulate generation of array literals for tag callsite
+      // 1st is array of cooked strings, second is array of raw strings
+      MaterializeTemplateCallsiteLiterals();
+    }
+    return EmptyExpression();
+  }
+  inline void MaterializeTemplateCallsiteLiterals();
+  PreParserExpression NoTemplateTag() {
+    return PreParserExpression::NoTemplateTag();
+  }
+  static bool IsTaggedTemplate(const PreParserExpression tag) {
+    return !tag.IsNoTemplateTag();
+  }
   static AstValueFactory* ast_value_factory() { return NULL; }
 
   void CheckConflictingVarDeclarations(PreParserScope scope, bool* ok) {}
@@ -1389,6 +1446,11 @@
       int function_token_position, FunctionLiteral::FunctionType type,
       FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
 
+  PreParserExpression ParseClassLiteral(PreParserIdentifier name,
+                                        Scanner::Location class_name_location,
+                                        bool name_is_strict_reserved, int pos,
+                                        bool* ok);
+
  private:
   PreParser* pre_parser_;
 };
@@ -1418,16 +1480,17 @@
   };
 
   PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
-      : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, NULL,
+      : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL,
                                     this) {}
 
   // Pre-parse the program from the character stream; returns true on
   // success (even if parsing failed, the pre-parse data successfully
   // captured the syntax error), and false if a stack-overflow happened
   // during parsing.
-  PreParseResult PreParseProgram() {
-    PreParserScope scope(scope_, GLOBAL_SCOPE);
-    FunctionState top_scope(&function_state_, &scope_, &scope);
+  PreParseResult PreParseProgram(int* materialized_literals = 0) {
+    PreParserScope scope(scope_, SCRIPT_SCOPE);
+    PreParserFactory factory(NULL);
+    FunctionState top_scope(&function_state_, &scope_, &scope, &factory);
     bool ok = true;
     int start_position = scanner()->peek_location().beg_pos;
     ParseSourceElements(Token::EOS, &ok);
@@ -1435,7 +1498,11 @@
     if (!ok) {
       ReportUnexpectedToken(scanner()->current_token());
     } else if (scope_->strict_mode() == STRICT) {
-      CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
+      CheckStrictOctalLiteral(start_position, scanner()->location().end_pos,
+                              &ok);
+    }
+    if (materialized_literals) {
+      *materialized_literals = function_state_->materialized_literal_count();
     }
     return kPreParseSuccess;
   }
@@ -1525,10 +1592,21 @@
       FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
   void ParseLazyFunctionLiteralBody(bool* ok);
 
+  PreParserExpression ParseClassLiteral(PreParserIdentifier name,
+                                        Scanner::Location class_name_location,
+                                        bool name_is_strict_reserved, int pos,
+                                        bool* ok);
+
   bool CheckInOrOf(bool accept_OF);
 };
 
 
+void PreParserTraits::MaterializeTemplateCallsiteLiterals() {
+  pre_parser_->function_state_->NextMaterializedLiteralIndex();
+  pre_parser_->function_state_->NextMaterializedLiteralIndex();
+}
+
+
 PreParserStatementList PreParser::ParseEagerFunctionBody(
     PreParserIdentifier function_name, int pos, Variable* fvar,
     Token::Value fvar_init_op, bool is_generator, bool* ok) {
@@ -1554,8 +1632,8 @@
 ParserBase<Traits>::FunctionState::FunctionState(
     FunctionState** function_state_stack,
     typename Traits::Type::Scope** scope_stack,
-    typename Traits::Type::Scope* scope, typename Traits::Type::Zone* zone,
-    AstValueFactory* ast_value_factory, AstNode::IdGen* ast_node_id_gen)
+    typename Traits::Type::Scope* scope,
+    typename Traits::Type::Factory* factory)
     : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
       next_handler_index_(0),
       expected_property_count_(0),
@@ -1565,34 +1643,9 @@
       outer_function_state_(*function_state_stack),
       scope_stack_(scope_stack),
       outer_scope_(*scope_stack),
-      ast_node_id_gen_(ast_node_id_gen),
-      factory_(zone, ast_value_factory, ast_node_id_gen) {
+      factory_(factory) {
   *scope_stack_ = scope;
   *function_state_stack = this;
-  Traits::SetUpFunctionState(this);
-}
-
-
-template <class Traits>
-ParserBase<Traits>::FunctionState::FunctionState(
-    FunctionState** function_state_stack,
-    typename Traits::Type::Scope** scope_stack,
-    typename Traits::Type::Scope** scope, typename Traits::Type::Zone* zone,
-    AstValueFactory* ast_value_factory, AstNode::IdGen* ast_node_id_gen)
-    : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
-      next_handler_index_(0),
-      expected_property_count_(0),
-      is_generator_(false),
-      generator_object_variable_(NULL),
-      function_state_stack_(function_state_stack),
-      outer_function_state_(*function_state_stack),
-      scope_stack_(scope_stack),
-      outer_scope_(*scope_stack),
-      ast_node_id_gen_(ast_node_id_gen),
-      factory_(zone, ast_value_factory, ast_node_id_gen) {
-  *scope_stack_ = *scope;
-  *function_state_stack = this;
-  Traits::SetUpFunctionState(this);
 }
 
 
@@ -1600,7 +1653,6 @@
 ParserBase<Traits>::FunctionState::~FunctionState() {
   *scope_stack_ = outer_scope_;
   *function_state_stack_ = outer_function_state_;
-  Traits::TearDownFunctionState(this);
 }
 
 
@@ -1621,10 +1673,15 @@
     case Token::FUTURE_RESERVED_WORD:
       return ReportMessageAt(source_location, "unexpected_reserved");
     case Token::LET:
+    case Token::STATIC:
     case Token::YIELD:
     case Token::FUTURE_STRICT_RESERVED_WORD:
       return ReportMessageAt(source_location, strict_mode() == SLOPPY
           ? "unexpected_token_identifier" : "unexpected_strict_reserved");
+    case Token::TEMPLATE_SPAN:
+    case Token::TEMPLATE_TAIL:
+      return Traits::ReportMessageAt(source_location,
+          "unexpected_template_string");
     default:
       const char* name = Token::String(token);
       DCHECK(name != NULL);
@@ -1645,11 +1702,13 @@
       ReportMessage("strict_eval_arguments");
       *ok = false;
     }
+    if (name->IsArguments(this->ast_value_factory()))
+      scope_->RecordArgumentsUsage();
     return name;
   } else if (strict_mode() == SLOPPY &&
              (next == Token::FUTURE_STRICT_RESERVED_WORD ||
-             (next == Token::LET) ||
-             (next == Token::YIELD && !is_generator()))) {
+              next == Token::LET || next == Token::STATIC ||
+              (next == Token::YIELD && !is_generator()))) {
     return this->GetSymbol(scanner());
   } else {
     this->ReportUnexpectedToken(next);
@@ -1666,8 +1725,8 @@
   Token::Value next = Next();
   if (next == Token::IDENTIFIER) {
     *is_strict_reserved = false;
-  } else if (next == Token::FUTURE_STRICT_RESERVED_WORD ||
-             next == Token::LET ||
+  } else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
+             next == Token::STATIC ||
              (next == Token::YIELD && !this->is_generator())) {
     *is_strict_reserved = true;
   } else {
@@ -1675,7 +1734,11 @@
     *ok = false;
     return Traits::EmptyIdentifier();
   }
-  return this->GetSymbol(scanner());
+
+  IdentifierT name = this->GetSymbol(scanner());
+  if (name->IsArguments(this->ast_value_factory()))
+    scope_->RecordArgumentsUsage();
+  return name;
 }
 
 
@@ -1684,13 +1747,17 @@
 ParserBase<Traits>::ParseIdentifierName(bool* ok) {
   Token::Value next = Next();
   if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
-      next != Token::LET && next != Token::YIELD &&
+      next != Token::LET && next != Token::STATIC && next != Token::YIELD &&
       next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
     this->ReportUnexpectedToken(next);
     *ok = false;
     return Traits::EmptyIdentifier();
   }
-  return this->GetSymbol(scanner());
+
+  IdentifierT name = this->GetSymbol(scanner());
+  if (name->IsArguments(this->ast_value_factory()))
+    scope_->RecordArgumentsUsage();
+  return name;
 }
 
 
@@ -1722,7 +1789,7 @@
   IdentifierT js_pattern = this->GetNextSymbol(scanner());
   if (!scanner()->ScanRegExpFlags()) {
     Next();
-    ReportMessage("invalid_regexp_flags");
+    ReportMessage("malformed_regexp_flags");
     *ok = false;
     return Traits::EmptyExpression();
   }
@@ -1761,6 +1828,7 @@
   //   RegExpLiteral
   //   ClassLiteral
   //   '(' Expression ')'
+  //   TemplateLiteral
 
   int pos = peek_position();
   ExpressionT result = this->EmptyExpression();
@@ -1768,6 +1836,7 @@
   switch (token) {
     case Token::THIS: {
       Consume(Token::THIS);
+      scope_->RecordThisUsage();
       result = this->ThisExpression(scope_, factory());
       break;
     }
@@ -1782,6 +1851,7 @@
 
     case Token::IDENTIFIER:
     case Token::LET:
+    case Token::STATIC:
     case Token::YIELD:
     case Token::FUTURE_STRICT_RESERVED_WORD: {
       // Using eval or arguments in this context is OK even in strict mode.
@@ -1814,7 +1884,7 @@
 
     case Token::LPAREN:
       Consume(Token::LPAREN);
-      if (allow_arrow_functions() && peek() == Token::RPAREN) {
+      if (allow_harmony_arrow_functions() && peek() == Token::RPAREN) {
         // Arrow functions are the only expression type constructions
         // for which an empty parameter list "()" is valid input.
         Consume(Token::RPAREN);
@@ -1832,6 +1902,11 @@
 
     case Token::CLASS: {
       Consume(Token::CLASS);
+      if (!allow_harmony_sloppy() && strict_mode() == SLOPPY) {
+        ReportMessage("sloppy_lexical", NULL);
+        *ok = false;
+        break;
+      }
       int class_token_position = position();
       IdentifierT name = this->EmptyIdentifier();
       bool is_strict_reserved_name = false;
@@ -1847,8 +1922,14 @@
       break;
     }
 
+    case Token::TEMPLATE_SPAN:
+    case Token::TEMPLATE_TAIL:
+      result =
+          this->ParseTemplateLiteral(Traits::NoTemplateTag(), pos, CHECK_OK);
+      break;
+
     case Token::MOD:
-      if (allow_natives_syntax() || extension_ != NULL) {
+      if (allow_natives() || extension_ != NULL) {
         result = this->ParseV8Intrinsic(CHECK_OK);
         break;
       }
@@ -1940,7 +2021,9 @@
 template <class Traits>
 typename ParserBase<Traits>::ObjectLiteralPropertyT ParserBase<
     Traits>::ParsePropertyDefinition(ObjectLiteralChecker* checker,
-                                     bool in_class, bool is_static, bool* ok) {
+                                     bool in_class, bool is_static,
+                                     bool* has_seen_constructor, bool* ok) {
+  DCHECK(!in_class || is_static || has_seen_constructor != NULL);
   ExpressionT value = this->EmptyExpression();
   bool is_get = false;
   bool is_set = false;
@@ -1957,8 +2040,10 @@
 
   if (!in_class && !is_generator && peek() == Token::COLON) {
     // PropertyDefinition : PropertyName ':' AssignmentExpression
-    checker->CheckProperty(name_token, kValueProperty,
-                           CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+    if (checker != NULL) {
+      checker->CheckProperty(name_token, kValueProperty,
+                             CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+    }
     Consume(Token::COLON);
     value = this->ParseAssignmentExpression(
         true, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
@@ -1972,17 +2057,32 @@
       *ok = false;
       return this->EmptyObjectLiteralProperty();
     }
-    if (is_generator && in_class && !is_static && this->IsConstructor(name)) {
-      ReportMessageAt(scanner()->location(), "constructor_special_method");
-      *ok = false;
-      return this->EmptyObjectLiteralProperty();
-    }
 
-    checker->CheckProperty(name_token, kValueProperty,
-                           CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
     FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
                                      : FunctionKind::kConciseMethod;
 
+    if (in_class && !is_static && this->IsConstructor(name)) {
+      if (is_generator) {
+        ReportMessageAt(scanner()->location(), "constructor_special_method");
+        *ok = false;
+        return this->EmptyObjectLiteralProperty();
+      }
+
+      if (*has_seen_constructor) {
+        ReportMessageAt(scanner()->location(), "duplicate_constructor");
+        *ok = false;
+        return this->EmptyObjectLiteralProperty();
+      }
+
+      *has_seen_constructor = true;
+      kind = FunctionKind::kNormalFunction;
+    }
+
+    if (checker != NULL) {
+      checker->CheckProperty(name_token, kValueProperty,
+                             CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+    }
+
     value = this->ParseFunctionLiteral(
         name, scanner()->location(),
         false,  // reserved words are allowed here
@@ -1992,7 +2092,7 @@
 
   } else if (in_class && name_is_static && !is_static) {
     // static MethodDefinition
-    return ParsePropertyDefinition(checker, true, true, ok);
+    return ParsePropertyDefinition(checker, true, true, NULL, ok);
 
   } else if (is_get || is_set) {
     // Accessor
@@ -2007,16 +2107,15 @@
       *ok = false;
       return this->EmptyObjectLiteralProperty();
     } else if (in_class && !is_static && this->IsConstructor(name)) {
-      // ES6, spec draft rev 27, treats static get constructor as an error too.
-      // https://bugs.ecmascript.org/show_bug.cgi?id=3223
-      // TODO(arv): Update when bug is resolved.
       ReportMessageAt(scanner()->location(), "constructor_special_method");
       *ok = false;
       return this->EmptyObjectLiteralProperty();
     }
-    checker->CheckProperty(name_token,
-                           is_get ? kGetterProperty : kSetterProperty,
-                           CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+    if (checker != NULL) {
+      checker->CheckProperty(name_token,
+                             is_get ? kGetterProperty : kSetterProperty,
+                             CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
+    }
 
     typename Traits::Type::FunctionLiteral value = this->ParseFunctionLiteral(
         name, scanner()->location(),
@@ -2027,6 +2126,12 @@
         CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
     return factory()->NewObjectLiteralProperty(is_get, value, next_pos,
                                                is_static);
+
+  } else if (!in_class && allow_harmony_object_literals_ &&
+             Token::IsIdentifier(name_token, strict_mode(),
+                                 this->is_generator())) {
+    value = this->ExpressionFromIdentifier(name, next_pos, scope_, factory());
+
   } else {
     Token::Value next = Next();
     ReportUnexpectedToken(next);
@@ -2064,8 +2169,8 @@
 
     const bool in_class = false;
     const bool is_static = false;
-    ObjectLiteralPropertyT property =
-        this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK);
+    ObjectLiteralPropertyT property = this->ParsePropertyDefinition(
+        &checker, in_class, is_static, NULL, CHECK_OK);
 
     // Mark top-level object literals that contain function literals and
     // pretenure the literal so it can be added as a constant function
@@ -2148,11 +2253,11 @@
   }
 
   if (fni_ != NULL) fni_->Enter();
-  typename Traits::Checkpoint checkpoint(this);
+  ParserBase<Traits>::Checkpoint checkpoint(this);
   ExpressionT expression =
       this->ParseConditionalExpression(accept_IN, CHECK_OK);
 
-  if (allow_arrow_functions() && peek() == Token::ARROW) {
+  if (allow_harmony_arrow_functions() && peek() == Token::ARROW) {
     checkpoint.Restore();
     expression = this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
                                                  expression, CHECK_OK);
@@ -2446,6 +2551,23 @@
         break;
       }
 
+      case Token::TEMPLATE_SPAN:
+      case Token::TEMPLATE_TAIL: {
+        int pos;
+        if (scanner()->current_token() == Token::IDENTIFIER) {
+          pos = position();
+        } else {
+          pos = peek_position();
+          if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) {
+            // If the tag function looks like an IIFE, set_parenthesized() to
+            // force eager compilation.
+            result->AsFunctionLiteral()->set_parenthesized();
+          }
+        }
+        result = ParseTemplateLiteral(result, pos, CHECK_OK);
+        break;
+      }
+
       case Token::PERIOD: {
         Consume(Token::PERIOD);
         int pos = position();
@@ -2548,8 +2670,11 @@
     int beg_pos = position();
     Consume(Token::SUPER);
     Token::Value next = peek();
-    if (next == Token::PERIOD || next == Token::LBRACK ||
-        next == Token::LPAREN) {
+    if (next == Token::PERIOD || next == Token::LBRACK) {
+      scope_->RecordSuperPropertyUsage();
+      result = this->SuperReference(scope_, factory());
+    } else if (next == Token::LPAREN) {
+      scope_->RecordSuperConstructorCallUsage();
       result = this->SuperReference(scope_, factory());
     } else {
       ReportMessageAt(Scanner::Location(beg_pos, position()),
@@ -2609,20 +2734,18 @@
 typename ParserBase<Traits>::ExpressionT ParserBase<
     Traits>::ParseArrowFunctionLiteral(int start_pos, ExpressionT params_ast,
                                        bool* ok) {
-  // TODO(aperez): Change this to use ARROW_SCOPE
-  typename Traits::Type::ScopePtr scope =
-      this->NewScope(scope_, FUNCTION_SCOPE);
+  typename Traits::Type::ScopePtr scope = this->NewScope(scope_, ARROW_SCOPE);
   typename Traits::Type::StatementList body;
-  typename Traits::Type::AstProperties ast_properties;
-  BailoutReason dont_optimize_reason = kNoReason;
   int num_parameters = -1;
   int materialized_literal_count = -1;
   int expected_property_count = -1;
   int handler_count = 0;
 
   {
-    FunctionState function_state(&function_state_, &scope_, &scope, zone(),
-                                 this->ast_value_factory(), ast_node_id_gen_);
+    typename Traits::Type::Factory function_factory(this->ast_value_factory());
+    FunctionState function_state(&function_state_, &scope_,
+                                 Traits::Type::ptr_to_scope(scope),
+                                 &function_factory);
     Scanner::Location dupe_error_loc = Scanner::Location::invalid();
     num_parameters = Traits::DeclareArrowParametersFromExpression(
         params_ast, scope_, &dupe_error_loc, ok);
@@ -2689,14 +2812,12 @@
 
     // Validate strict mode.
     if (strict_mode() == STRICT) {
-      CheckOctalLiteral(start_pos, scanner()->location().end_pos, CHECK_OK);
+      CheckStrictOctalLiteral(start_pos, scanner()->location().end_pos,
+                              CHECK_OK);
     }
 
     if (allow_harmony_scoping() && strict_mode() == STRICT)
       this->CheckConflictingVarDeclarations(scope, CHECK_OK);
-
-    ast_properties = *factory()->visitor()->ast_properties();
-    dont_optimize_reason = factory()->visitor()->dont_optimize_reason();
   }
 
   FunctionLiteralT function_literal = factory()->NewFunctionLiteral(
@@ -2708,8 +2829,6 @@
       start_pos);
 
   function_literal->set_function_token_position(start_pos);
-  function_literal->set_ast_properties(&ast_properties);
-  function_literal->set_dont_optimize_reason(dont_optimize_reason);
 
   if (fni_ != NULL) this->InferFunctionName(fni_, function_literal);
 
@@ -2717,71 +2836,102 @@
 }
 
 
-template <class Traits>
-typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseClassLiteral(
-    IdentifierT name, Scanner::Location class_name_location,
-    bool name_is_strict_reserved, int pos, bool* ok) {
-  // All parts of a ClassDeclaration or a ClassExpression are strict code.
-  if (name_is_strict_reserved) {
-    ReportMessageAt(class_name_location, "unexpected_strict_reserved");
-    *ok = false;
-    return this->EmptyExpression();
-  }
-  if (this->IsEvalOrArguments(name)) {
-    ReportMessageAt(class_name_location, "strict_eval_arguments");
-    *ok = false;
-    return this->EmptyExpression();
+template <typename Traits>
+typename ParserBase<Traits>::ExpressionT
+ParserBase<Traits>::ParseTemplateLiteral(ExpressionT tag, int start, bool* ok) {
+  // A TemplateLiteral is made up of 0 or more TEMPLATE_SPAN tokens (literal
+  // text followed by a substitution expression), finalized by a single
+  // TEMPLATE_TAIL.
+  //
+  // In terms of draft language, TEMPLATE_SPAN may be either the TemplateHead or
+  // TemplateMiddle productions, while TEMPLATE_TAIL is either TemplateTail, or
+  // NoSubstitutionTemplate.
+  //
+  // When parsing a TemplateLiteral, we must have scanned either an initial
+  // TEMPLATE_SPAN, or a TEMPLATE_TAIL.
+  CHECK(peek() == Token::TEMPLATE_SPAN || peek() == Token::TEMPLATE_TAIL);
+
+  // If we reach a TEMPLATE_TAIL first, we are parsing a NoSubstitutionTemplate.
+  // In this case we may simply consume the token and build a template with a
+  // single TEMPLATE_SPAN and no expressions.
+  if (peek() == Token::TEMPLATE_TAIL) {
+    Consume(Token::TEMPLATE_TAIL);
+    int pos = position();
+    CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
+    typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
+    Traits::AddTemplateSpan(&ts, true);
+    return Traits::CloseTemplateLiteral(&ts, start, tag);
   }
 
-  // TODO(arv): Implement scopes and name binding in class body only.
-  // TODO(arv): Maybe add CLASS_SCOPE?
-  typename Traits::Type::ScopePtr extends_scope =
-      this->NewScope(scope_, BLOCK_SCOPE);
-  FunctionState extends_function_state(
-      &function_state_, &scope_, &extends_scope, zone(),
-      this->ast_value_factory(), ast_node_id_gen_);
-  scope_->SetStrictMode(STRICT);
-  scope_->SetScopeName(name);
+  Consume(Token::TEMPLATE_SPAN);
+  int pos = position();
+  typename Traits::TemplateLiteralState ts = Traits::OpenTemplateLiteral(pos);
+  Traits::AddTemplateSpan(&ts, false);
+  Token::Value next;
 
-  ExpressionT extends = this->EmptyExpression();
-  if (Check(Token::EXTENDS)) {
-    extends = this->ParseLeftHandSideExpression(CHECK_OK);
-  }
+  // If we open with a TEMPLATE_SPAN, we must scan the subsequent expression,
+  // and repeat if the following token is a TEMPLATE_SPAN as well (in this
+  // case, representing a TemplateMiddle).
 
-  ObjectLiteralChecker checker(this, STRICT);
-  typename Traits::Type::PropertyList properties =
-      this->NewPropertyList(4, zone_);
-  FunctionLiteralT constructor = this->EmptyFunctionLiteral();
-
-  Expect(Token::LBRACE, CHECK_OK);
-  while (peek() != Token::RBRACE) {
-    if (Check(Token::SEMICOLON)) continue;
-    if (fni_ != NULL) fni_->Enter();
-
-    const bool in_class = true;
-    const bool is_static = false;
-    ObjectLiteralPropertyT property =
-        this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK);
-
-    properties->Add(property, zone());
-
-    if (fni_ != NULL) {
-      fni_->Infer();
-      fni_->Leave();
+  do {
+    next = peek();
+    if (next == Token::EOS) {
+      ReportMessageAt(Scanner::Location(start, peek_position()),
+                      "unterminated_template");
+      *ok = false;
+      return Traits::EmptyExpression();
+    } else if (next == Token::ILLEGAL) {
+      Traits::ReportMessageAt(
+          Scanner::Location(position() + 1, peek_position()),
+          "unexpected_token", "ILLEGAL", false);
+      *ok = false;
+      return Traits::EmptyExpression();
     }
-  }
-  Expect(Token::RBRACE, CHECK_OK);
 
-  return this->ClassLiteral(name, extends, constructor, properties, pos,
-                            factory());
+    int expr_pos = peek_position();
+    ExpressionT expression = this->ParseExpression(true, CHECK_OK);
+    Traits::AddTemplateExpression(&ts, expression);
+
+    if (peek() != Token::RBRACE) {
+      ReportMessageAt(Scanner::Location(expr_pos, peek_position()),
+                      "unterminated_template_expr");
+      *ok = false;
+      return Traits::EmptyExpression();
+    }
+
+    // If we didn't die parsing that expression, our next token should be a
+    // TEMPLATE_SPAN or TEMPLATE_TAIL.
+    next = scanner()->ScanTemplateContinuation();
+    Next();
+
+    if (next == Token::EOS) {
+      ReportMessageAt(Scanner::Location(start, position()),
+                      "unterminated_template");
+      *ok = false;
+      return Traits::EmptyExpression();
+    } else if (next == Token::ILLEGAL) {
+      Traits::ReportMessageAt(
+          Scanner::Location(position() + 1, peek_position()),
+          "unexpected_token", "ILLEGAL", false);
+      *ok = false;
+      return Traits::EmptyExpression();
+    }
+
+    Traits::AddTemplateSpan(&ts, next == Token::TEMPLATE_TAIL);
+  } while (next == Token::TEMPLATE_SPAN);
+
+  DCHECK_EQ(next, Token::TEMPLATE_TAIL);
+  CheckTemplateOctalLiteral(pos, peek_position(), CHECK_OK);
+  // Once we've reached a TEMPLATE_TAIL, we can close the TemplateLiteral.
+  return Traits::CloseTemplateLiteral(&ts, start, tag);
 }
 
 
 template <typename Traits>
-typename ParserBase<Traits>::ExpressionT
-ParserBase<Traits>::CheckAndRewriteReferenceExpression(
-    ExpressionT expression,
-    Scanner::Location location, const char* message, bool* ok) {
+typename ParserBase<Traits>::ExpressionT ParserBase<
+    Traits>::CheckAndRewriteReferenceExpression(ExpressionT expression,
+                                                Scanner::Location location,
+                                                const char* message, bool* ok) {
   if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
       this->IsEvalOrArguments(this->AsIdentifier(expression))) {
     this->ReportMessageAt(location, "strict_eval_arguments", false);
diff --git a/src/prettyprinter.h b/src/prettyprinter.h
index d300d9a..bf01520 100644
--- a/src/prettyprinter.h
+++ b/src/prettyprinter.h
@@ -30,7 +30,7 @@
   static void PrintOut(Zone* zone, AstNode* node);
 
   // Individual nodes
-#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
+#define DECLARE_VISIT(type) void Visit##type(type* node) OVERRIDE;
   AST_NODE_LIST(DECLARE_VISIT)
 #undef DECLARE_VISIT
 
diff --git a/src/profile-generator-inl.h b/src/profile-generator-inl.h
index 58c124f..c53d749 100644
--- a/src/profile-generator-inl.h
+++ b/src/profile-generator-inl.h
@@ -10,14 +10,12 @@
 namespace v8 {
 namespace internal {
 
-CodeEntry::CodeEntry(Logger::LogEventsAndTags tag,
-                     const char* name,
-                     const char* name_prefix,
-                     const char* resource_name,
-                     int line_number,
-                     int column_number)
-    : tag_(tag),
-      builtin_id_(Builtins::builtin_count),
+CodeEntry::CodeEntry(Logger::LogEventsAndTags tag, const char* name,
+                     const char* name_prefix, const char* resource_name,
+                     int line_number, int column_number,
+                     JITLineInfoTable* line_info, Address instruction_start)
+    : bit_field_(TagField::encode(tag) |
+                 BuiltinIdField::encode(Builtins::builtin_count)),
       name_prefix_(name_prefix),
       name_(name),
       resource_name_(resource_name),
@@ -26,7 +24,9 @@
       shared_id_(0),
       script_id_(v8::UnboundScript::kNoScriptId),
       no_frame_ranges_(NULL),
-      bailout_reason_(kEmptyBailoutReason) { }
+      bailout_reason_(kEmptyBailoutReason),
+      line_info_(line_info),
+      instruction_start_(instruction_start) {}
 
 
 bool CodeEntry::is_js_function_tag(Logger::LogEventsAndTags tag) {
@@ -44,8 +44,8 @@
       entry_(entry),
       self_ticks_(0),
       children_(CodeEntriesMatch),
-      id_(tree->next_node_id()) { }
-
+      id_(tree->next_node_id()),
+      line_ticks_(LineTickMatch) {}
 } }  // namespace v8::internal
 
 #endif  // V8_PROFILE_GENERATOR_INL_H_
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 6017f12..7ad4910 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -132,6 +132,31 @@
 }
 
 
+JITLineInfoTable::JITLineInfoTable() {}
+
+
+JITLineInfoTable::~JITLineInfoTable() {}
+
+
+void JITLineInfoTable::SetPosition(int pc_offset, int line) {
+  DCHECK(pc_offset >= 0);
+  DCHECK(line > 0);  // The 1-based number of the source line.
+  if (GetSourceLineNumber(pc_offset) != line) {
+    pc_offset_map_.insert(std::make_pair(pc_offset, line));
+  }
+}
+
+
+int JITLineInfoTable::GetSourceLineNumber(int pc_offset) const {
+  PcOffsetMap::const_iterator it = pc_offset_map_.lower_bound(pc_offset);
+  if (it == pc_offset_map_.end()) {
+    if (pc_offset_map_.empty()) return v8::CpuProfileNode::kNoLineNumberInfo;
+    return (--pc_offset_map_.end())->second;
+  }
+  return it->second;
+}
+
+
 const char* const CodeEntry::kEmptyNamePrefix = "";
 const char* const CodeEntry::kEmptyResourceName = "";
 const char* const CodeEntry::kEmptyBailoutReason = "";
@@ -139,11 +164,12 @@
 
 CodeEntry::~CodeEntry() {
   delete no_frame_ranges_;
+  delete line_info_;
 }
 
 
 uint32_t CodeEntry::GetCallUid() const {
-  uint32_t hash = ComputeIntegerHash(tag_, v8::internal::kZeroHashSeed);
+  uint32_t hash = ComputeIntegerHash(tag(), v8::internal::kZeroHashSeed);
   if (shared_id_ != 0) {
     hash ^= ComputeIntegerHash(static_cast<uint32_t>(shared_id_),
                                v8::internal::kZeroHashSeed);
@@ -164,20 +190,26 @@
 
 
 bool CodeEntry::IsSameAs(CodeEntry* entry) const {
-  return this == entry
-      || (tag_ == entry->tag_
-          && shared_id_ == entry->shared_id_
-          && (shared_id_ != 0
-              || (name_prefix_ == entry->name_prefix_
-                  && name_ == entry->name_
-                  && resource_name_ == entry->resource_name_
-                  && line_number_ == entry->line_number_)));
+  return this == entry ||
+         (tag() == entry->tag() && shared_id_ == entry->shared_id_ &&
+          (shared_id_ != 0 ||
+           (name_prefix_ == entry->name_prefix_ && name_ == entry->name_ &&
+            resource_name_ == entry->resource_name_ &&
+            line_number_ == entry->line_number_)));
 }
 
 
 void CodeEntry::SetBuiltinId(Builtins::Name id) {
-  tag_ = Logger::BUILTIN_TAG;
-  builtin_id_ = id;
+  bit_field_ = TagField::update(bit_field_, Logger::BUILTIN_TAG);
+  bit_field_ = BuiltinIdField::update(bit_field_, id);
+}
+
+
+int CodeEntry::GetSourceLine(int pc_offset) const {
+  if (line_info_ && !line_info_->empty()) {
+    return line_info_->GetSourceLineNumber(pc_offset);
+  }
+  return v8::CpuProfileNode::kNoLineNumberInfo;
 }
 
 
@@ -202,6 +234,40 @@
 }
 
 
+void ProfileNode::IncrementLineTicks(int src_line) {
+  if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) return;
+  // Increment a hit counter of a certain source line.
+  // Add a new source line if not found.
+  HashMap::Entry* e =
+      line_ticks_.Lookup(reinterpret_cast<void*>(src_line), src_line, true);
+  DCHECK(e);
+  e->value = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(e->value) + 1);
+}
+
+
+bool ProfileNode::GetLineTicks(v8::CpuProfileNode::LineTick* entries,
+                               unsigned int length) const {
+  if (entries == NULL || length == 0) return false;
+
+  unsigned line_count = line_ticks_.occupancy();
+
+  if (line_count == 0) return true;
+  if (length < line_count) return false;
+
+  v8::CpuProfileNode::LineTick* entry = entries;
+
+  for (HashMap::Entry* p = line_ticks_.Start(); p != NULL;
+       p = line_ticks_.Next(p), entry++) {
+    entry->line =
+        static_cast<unsigned int>(reinterpret_cast<uintptr_t>(p->key));
+    entry->hit_count =
+        static_cast<unsigned int>(reinterpret_cast<uintptr_t>(p->value));
+  }
+
+  return true;
+}
+
+
 void ProfileNode::Print(int indent) {
   base::OS::Print("%5u %*s %s%s %d #%d %s", self_ticks_, indent, "",
                   entry_->name_prefix(), entry_->name(), entry_->script_id(),
@@ -242,7 +308,8 @@
 }
 
 
-ProfileNode* ProfileTree::AddPathFromEnd(const Vector<CodeEntry*>& path) {
+ProfileNode* ProfileTree::AddPathFromEnd(const Vector<CodeEntry*>& path,
+                                         int src_line) {
   ProfileNode* node = root_;
   for (CodeEntry** entry = path.start() + path.length() - 1;
        entry != path.start() - 1;
@@ -252,11 +319,15 @@
     }
   }
   node->IncrementSelfTicks();
+  if (src_line != v8::CpuProfileNode::kNoLineNumberInfo) {
+    node->IncrementLineTicks(src_line);
+  }
   return node;
 }
 
 
-void ProfileTree::AddPathFromStart(const Vector<CodeEntry*>& path) {
+void ProfileTree::AddPathFromStart(const Vector<CodeEntry*>& path,
+                                   int src_line) {
   ProfileNode* node = root_;
   for (CodeEntry** entry = path.start();
        entry != path.start() + path.length();
@@ -266,6 +337,9 @@
     }
   }
   node->IncrementSelfTicks();
+  if (src_line != v8::CpuProfileNode::kNoLineNumberInfo) {
+    node->IncrementLineTicks(src_line);
+  }
 }
 
 
@@ -327,8 +401,8 @@
 
 
 void CpuProfile::AddPath(base::TimeTicks timestamp,
-                         const Vector<CodeEntry*>& path) {
-  ProfileNode* top_frame_node = top_down_.AddPathFromEnd(path);
+                         const Vector<CodeEntry*>& path, int src_line) {
+  ProfileNode* top_frame_node = top_down_.AddPathFromEnd(path, src_line);
   if (record_samples_) {
     timestamps_.Add(timestamp);
     samples_.Add(top_frame_node);
@@ -517,31 +591,25 @@
 
 
 void CpuProfilesCollection::AddPathToCurrentProfiles(
-    base::TimeTicks timestamp, const Vector<CodeEntry*>& path) {
+    base::TimeTicks timestamp, const Vector<CodeEntry*>& path, int src_line) {
   // As starting / stopping profiles is rare relatively to this
   // method, we don't bother minimizing the duration of lock holding,
   // e.g. copying contents of the list to a local vector.
   current_profiles_semaphore_.Wait();
   for (int i = 0; i < current_profiles_.length(); ++i) {
-    current_profiles_[i]->AddPath(timestamp, path);
+    current_profiles_[i]->AddPath(timestamp, path, src_line);
   }
   current_profiles_semaphore_.Signal();
 }
 
 
 CodeEntry* CpuProfilesCollection::NewCodeEntry(
-      Logger::LogEventsAndTags tag,
-      const char* name,
-      const char* name_prefix,
-      const char* resource_name,
-      int line_number,
-      int column_number) {
-  CodeEntry* code_entry = new CodeEntry(tag,
-                                        name,
-                                        name_prefix,
-                                        resource_name,
-                                        line_number,
-                                        column_number);
+    Logger::LogEventsAndTags tag, const char* name, const char* name_prefix,
+    const char* resource_name, int line_number, int column_number,
+    JITLineInfoTable* line_info, Address instruction_start) {
+  CodeEntry* code_entry =
+      new CodeEntry(tag, name, name_prefix, resource_name, line_number,
+                    column_number, line_info, instruction_start);
   code_entries_.Add(code_entry);
   return code_entry;
 }
@@ -579,6 +647,15 @@
   // entries vector with NULL values.
   CodeEntry** entry = entries.start();
   memset(entry, 0, entries.length() * sizeof(*entry));
+
+  // The ProfileNode knows nothing about all versions of generated code for
+  // the same JS function. The line number information associated with
+  // the latest version of generated code is used to find a source line number
+  // for a JS function. Then, the detected source line is passed to
+  // ProfileNode to increase the tick count for this source line.
+  int src_line = v8::CpuProfileNode::kNoLineNumberInfo;
+  bool src_line_not_found = true;
+
   if (sample.pc != NULL) {
     if (sample.has_external_callback && sample.state == EXTERNAL &&
         sample.top_frame_type == StackFrame::EXIT) {
@@ -595,10 +672,9 @@
       // frame. Check for this case and just skip such samples.
       if (pc_entry) {
         List<OffsetRange>* ranges = pc_entry->no_frame_ranges();
+        int pc_offset =
+            static_cast<int>(sample.pc - pc_entry->instruction_start());
         if (ranges) {
-          Code* code = Code::cast(HeapObject::FromAddress(start));
-          int pc_offset = static_cast<int>(
-              sample.pc - code->instruction_start());
           for (int i = 0; i < ranges->length(); i++) {
             OffsetRange& range = ranges->at(i);
             if (range.from <= pc_offset && pc_offset < range.to) {
@@ -606,6 +682,11 @@
             }
           }
         }
+        src_line = pc_entry->GetSourceLine(pc_offset);
+        if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) {
+          src_line = pc_entry->line_number();
+        }
+        src_line_not_found = false;
         *entry++ = pc_entry;
 
         if (pc_entry->builtin_id() == Builtins::kFunctionCall ||
@@ -626,7 +707,22 @@
            *stack_end = stack_pos + sample.frames_count;
          stack_pos != stack_end;
          ++stack_pos) {
-      *entry++ = code_map_.FindEntry(*stack_pos);
+      Address start = NULL;
+      *entry = code_map_.FindEntry(*stack_pos, &start);
+
+      // Skip unresolved frames (e.g. internal frame) and get source line of
+      // the first JS caller.
+      if (src_line_not_found && *entry) {
+        int pc_offset =
+            static_cast<int>(*stack_pos - (*entry)->instruction_start());
+        src_line = (*entry)->GetSourceLine(pc_offset);
+        if (src_line == v8::CpuProfileNode::kNoLineNumberInfo) {
+          src_line = (*entry)->line_number();
+        }
+        src_line_not_found = false;
+      }
+
+      entry++;
     }
   }
 
@@ -644,7 +740,7 @@
     }
   }
 
-  profiles_->AddPathToCurrentProfiles(sample.timestamp, entries);
+  profiles_->AddPathToCurrentProfiles(sample.timestamp, entries, src_line);
 }
 
 
diff --git a/src/profile-generator.h b/src/profile-generator.h
index 5ebb92b..2127a1e 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -5,6 +5,7 @@
 #ifndef V8_PROFILE_GENERATOR_H_
 #define V8_PROFILE_GENERATOR_H_
 
+#include <map>
 #include "include/v8-profiler.h"
 #include "src/allocation.h"
 #include "src/hashmap.h"
@@ -44,24 +45,45 @@
 };
 
 
+// Provides a mapping from the offsets within generated code to
+// the source line.
+class JITLineInfoTable : public Malloced {
+ public:
+  JITLineInfoTable();
+  ~JITLineInfoTable();
+
+  void SetPosition(int pc_offset, int line);
+  int GetSourceLineNumber(int pc_offset) const;
+
+  bool empty() const { return pc_offset_map_.empty(); }
+
+ private:
+  // pc_offset -> source line
+  typedef std::map<int, int> PcOffsetMap;
+  PcOffsetMap pc_offset_map_;
+  DISALLOW_COPY_AND_ASSIGN(JITLineInfoTable);
+};
+
 class CodeEntry {
  public:
   // CodeEntry doesn't own name strings, just references them.
-  inline CodeEntry(Logger::LogEventsAndTags tag,
-                   const char* name,
+  inline CodeEntry(Logger::LogEventsAndTags tag, const char* name,
                    const char* name_prefix = CodeEntry::kEmptyNamePrefix,
                    const char* resource_name = CodeEntry::kEmptyResourceName,
                    int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
-                   int column_number = v8::CpuProfileNode::kNoColumnNumberInfo);
+                   int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
+                   JITLineInfoTable* line_info = NULL,
+                   Address instruction_start = NULL);
   ~CodeEntry();
 
-  bool is_js_function() const { return is_js_function_tag(tag_); }
+  bool is_js_function() const { return is_js_function_tag(tag()); }
   const char* name_prefix() const { return name_prefix_; }
   bool has_name_prefix() const { return name_prefix_[0] != '\0'; }
   const char* name() const { return name_; }
   const char* resource_name() const { return resource_name_; }
   int line_number() const { return line_number_; }
   int column_number() const { return column_number_; }
+  const JITLineInfoTable* line_info() const { return line_info_; }
   void set_shared_id(int shared_id) { shared_id_ = shared_id; }
   int script_id() const { return script_id_; }
   void set_script_id(int script_id) { script_id_ = script_id; }
@@ -78,18 +100,27 @@
   }
 
   void SetBuiltinId(Builtins::Name id);
-  Builtins::Name builtin_id() const { return builtin_id_; }
+  Builtins::Name builtin_id() const {
+    return BuiltinIdField::decode(bit_field_);
+  }
 
   uint32_t GetCallUid() const;
   bool IsSameAs(CodeEntry* entry) const;
 
+  int GetSourceLine(int pc_offset) const;
+
+  Address instruction_start() const { return instruction_start_; }
+
   static const char* const kEmptyNamePrefix;
   static const char* const kEmptyResourceName;
   static const char* const kEmptyBailoutReason;
 
  private:
-  Logger::LogEventsAndTags tag_ : 8;
-  Builtins::Name builtin_id_ : 8;
+  class TagField : public BitField<Logger::LogEventsAndTags, 0, 8> {};
+  class BuiltinIdField : public BitField<Builtins::Name, 8, 8> {};
+  Logger::LogEventsAndTags tag() const { return TagField::decode(bit_field_); }
+
+  uint32_t bit_field_;
   const char* name_prefix_;
   const char* name_;
   const char* resource_name_;
@@ -99,6 +130,8 @@
   int script_id_;
   List<OffsetRange>* no_frame_ranges_;
   const char* bailout_reason_;
+  JITLineInfoTable* line_info_;
+  Address instruction_start_;
 
   DISALLOW_COPY_AND_ASSIGN(CodeEntry);
 };
@@ -114,11 +147,15 @@
   ProfileNode* FindOrAddChild(CodeEntry* entry);
   void IncrementSelfTicks() { ++self_ticks_; }
   void IncreaseSelfTicks(unsigned amount) { self_ticks_ += amount; }
+  void IncrementLineTicks(int src_line);
 
   CodeEntry* entry() const { return entry_; }
   unsigned self_ticks() const { return self_ticks_; }
   const List<ProfileNode*>* children() const { return &children_list_; }
   unsigned id() const { return id_; }
+  unsigned int GetHitLineCount() const { return line_ticks_.occupancy(); }
+  bool GetLineTicks(v8::CpuProfileNode::LineTick* entries,
+                    unsigned int length) const;
 
   void Print(int indent);
 
@@ -132,6 +169,8 @@
     return entry->GetCallUid();
   }
 
+  static bool LineTickMatch(void* a, void* b) { return a == b; }
+
   ProfileTree* tree_;
   CodeEntry* entry_;
   unsigned self_ticks_;
@@ -139,6 +178,7 @@
   HashMap children_;
   List<ProfileNode*> children_list_;
   unsigned id_;
+  HashMap line_ticks_;
 
   DISALLOW_COPY_AND_ASSIGN(ProfileNode);
 };
@@ -149,8 +189,11 @@
   ProfileTree();
   ~ProfileTree();
 
-  ProfileNode* AddPathFromEnd(const Vector<CodeEntry*>& path);
-  void AddPathFromStart(const Vector<CodeEntry*>& path);
+  ProfileNode* AddPathFromEnd(
+      const Vector<CodeEntry*>& path,
+      int src_line = v8::CpuProfileNode::kNoLineNumberInfo);
+  void AddPathFromStart(const Vector<CodeEntry*>& path,
+                        int src_line = v8::CpuProfileNode::kNoLineNumberInfo);
   ProfileNode* root() const { return root_; }
   unsigned next_node_id() { return next_node_id_++; }
 
@@ -175,7 +218,8 @@
   CpuProfile(const char* title, bool record_samples);
 
   // Add pc -> ... -> main() call path to the profile.
-  void AddPath(base::TimeTicks timestamp, const Vector<CodeEntry*>& path);
+  void AddPath(base::TimeTicks timestamp, const Vector<CodeEntry*>& path,
+               int src_line);
   void CalculateTotalTicksAndSamplingRate();
 
   const char* title() const { return title_; }
@@ -277,16 +321,16 @@
   void RemoveProfile(CpuProfile* profile);
 
   CodeEntry* NewCodeEntry(
-      Logger::LogEventsAndTags tag,
-      const char* name,
+      Logger::LogEventsAndTags tag, const char* name,
       const char* name_prefix = CodeEntry::kEmptyNamePrefix,
       const char* resource_name = CodeEntry::kEmptyResourceName,
       int line_number = v8::CpuProfileNode::kNoLineNumberInfo,
-      int column_number = v8::CpuProfileNode::kNoColumnNumberInfo);
+      int column_number = v8::CpuProfileNode::kNoColumnNumberInfo,
+      JITLineInfoTable* line_info = NULL, Address instruction_start = NULL);
 
   // Called from profile generator thread.
-  void AddPathToCurrentProfiles(
-      base::TimeTicks timestamp, const Vector<CodeEntry*>& path);
+  void AddPathToCurrentProfiles(base::TimeTicks timestamp,
+                                const Vector<CodeEntry*>& path, int src_line);
 
   // Limits the number of profiles that can be simultaneously collected.
   static const int kMaxSimultaneousProfiles = 100;
diff --git a/src/promise.js b/src/promise.js
index 37c10ec..c096296 100644
--- a/src/promise.js
+++ b/src/promise.js
@@ -19,6 +19,7 @@
 var PromiseCatch;
 var PromiseThen;
 var PromiseHasRejectHandler;
+var PromiseHasUserDefinedRejectHandler;
 
 // mirror-debugger.js currently uses builtins.promiseStatus. It would be nice
 // if we could move these property names into the closure below.
@@ -30,9 +31,10 @@
 var promiseOnResolve = GLOBAL_PRIVATE("Promise#onResolve");
 var promiseOnReject = GLOBAL_PRIVATE("Promise#onReject");
 var promiseRaw = GLOBAL_PRIVATE("Promise#raw");
-var promiseDebug = GLOBAL_PRIVATE("Promise#debug");
+var promiseHasHandler = %PromiseHasHandlerSymbol();
 var lastMicrotaskId = 0;
 
+
 (function() {
 
   var $Promise = function Promise(resolver) {
@@ -65,6 +67,13 @@
     return promise;
   }
 
+  function PromiseCreateAndSet(status, value) {
+    var promise = new $Promise(promiseRaw);
+    // If debug is active, notify about the newly created promise first.
+    if (DEBUG_IS_ACTIVE) PromiseSet(promise, 0, UNDEFINED);
+    return PromiseSet(promise, status, value);
+  }
+
   function PromiseInit(promise) {
     return PromiseSet(
         promise, 0, UNDEFINED, new InternalArray, new InternalArray)
@@ -72,7 +81,8 @@
 
   function PromiseDone(promise, status, value, promiseQueue) {
     if (GET_PRIVATE(promise, promiseStatus) === 0) {
-      PromiseEnqueue(value, GET_PRIVATE(promise, promiseQueue), status);
+      var tasks = GET_PRIVATE(promise, promiseQueue);
+      if (tasks.length) PromiseEnqueue(value, tasks, status);
       PromiseSet(promise, status, value);
     }
   }
@@ -101,6 +111,7 @@
   function PromiseHandle(value, handler, deferred) {
     try {
       %DebugPushPromise(deferred.promise);
+      DEBUG_PREPARE_STEP_IN_IF_STEPPING(handler);
       var result = handler(value);
       if (result === deferred.promise)
         throw MakeTypeError('promise_cyclic', [result]);
@@ -159,11 +170,12 @@
 
   PromiseReject = function PromiseReject(promise, r) {
     // Check promise status to confirm that this reject has an effect.
-    // Check promiseDebug property to avoid duplicate event.
-    if (DEBUG_IS_ACTIVE &&
-        GET_PRIVATE(promise, promiseStatus) == 0 &&
-        !HAS_DEFINED_PRIVATE(promise, promiseDebug)) {
-      %DebugPromiseRejectEvent(promise, r);
+    // Call runtime for callbacks to the debugger or for unhandled reject.
+    if (GET_PRIVATE(promise, promiseStatus) == 0) {
+      var debug_is_active = DEBUG_IS_ACTIVE;
+      if (debug_is_active || !HAS_DEFINED_PRIVATE(promise, promiseHasHandler)) {
+        %PromiseRejectEvent(promise, r, debug_is_active);
+      }
     }
     PromiseDone(promise, -1, r, promiseOnReject)
   }
@@ -192,19 +204,24 @@
   function PromiseResolved(x) {
     if (this === $Promise) {
       // Optimized case, avoid extra closure.
-      return PromiseSet(new $Promise(promiseRaw), +1, x);
+      return PromiseCreateAndSet(+1, x);
     } else {
       return new this(function(resolve, reject) { resolve(x) });
     }
   }
 
   function PromiseRejected(r) {
+    var promise;
     if (this === $Promise) {
       // Optimized case, avoid extra closure.
-      return PromiseSet(new $Promise(promiseRaw), -1, r);
+      promise = PromiseCreateAndSet(-1, r);
+      // The debug event for this would always be an uncaught promise reject,
+      // which is usually simply noise. Do not trigger that debug event.
+      %PromiseRejectEvent(promise, r, false);
     } else {
-      return new this(function(resolve, reject) { reject(r) });
+      promise = new this(function(resolve, reject) { reject(r) });
     }
+    return promise;
   }
 
   // Simple chaining.
@@ -227,11 +244,18 @@
                        +1);
         break;
       case -1:  // Rejected
+        if (!HAS_DEFINED_PRIVATE(this, promiseHasHandler)) {
+          // Promise has already been rejected, but had no handler.
+          // Revoke previously triggered reject event.
+          %PromiseRevokeReject(this);
+        }
         PromiseEnqueue(GET_PRIVATE(this, promiseValue),
                        [onReject, deferred],
                        -1);
         break;
     }
+    // Mark this promise as having handler.
+    SET_PRIVATE(this, promiseHasHandler, true);
     if (DEBUG_IS_ACTIVE) {
       %DebugPromiseEvent({ promise: deferred.promise, parentPromise: this });
     }
@@ -255,8 +279,15 @@
       this,
       function(x) {
         x = PromiseCoerce(constructor, x);
-        return x === that ? onReject(MakeTypeError('promise_cyclic', [x])) :
-               IsPromise(x) ? x.then(onResolve, onReject) : onResolve(x);
+        if (x === that) {
+          DEBUG_PREPARE_STEP_IN_IF_STEPPING(onReject);
+          return onReject(MakeTypeError('promise_cyclic', [x]));
+        } else if (IsPromise(x)) {
+          return x.then(onResolve, onReject);
+        } else {
+          DEBUG_PREPARE_STEP_IN_IF_STEPPING(onResolve);
+          return onResolve(x);
+        }
       },
       onReject,
       PromiseChain
@@ -325,22 +356,24 @@
 
   // Utility for debugger
 
-  function PromiseHasRejectHandlerRecursive(promise) {
+  function PromiseHasUserDefinedRejectHandlerRecursive(promise) {
     var queue = GET_PRIVATE(promise, promiseOnReject);
     if (IS_UNDEFINED(queue)) return false;
-    // Do a depth first search for a reject handler that's not
-    // the default PromiseIdRejectHandler.
     for (var i = 0; i < queue.length; i += 2) {
       if (queue[i] != PromiseIdRejectHandler) return true;
-      if (PromiseHasRejectHandlerRecursive(queue[i + 1].promise)) return true;
+      if (PromiseHasUserDefinedRejectHandlerRecursive(queue[i + 1].promise)) {
+        return true;
+      }
     }
     return false;
   }
 
-  PromiseHasRejectHandler = function PromiseHasRejectHandler() {
-    // Mark promise as already having triggered a reject event.
-    SET_PRIVATE(this, promiseDebug, true);
-    return PromiseHasRejectHandlerRecursive(this);
+  // Return whether the promise will be handled by a user-defined reject
+  // handler somewhere down the promise chain. For this, we do a depth-first
+  // search for a reject handler that's not the default PromiseIdRejectHandler.
+  PromiseHasUserDefinedRejectHandler =
+      function PromiseHasUserDefinedRejectHandler() {
+    return PromiseHasUserDefinedRejectHandlerRecursive(this);
   };
 
   // -------------------------------------------------------------------
@@ -348,6 +381,8 @@
 
   %CheckIsBootstrapping();
   %AddNamedProperty(global, 'Promise', $Promise, DONT_ENUM);
+  %AddNamedProperty(
+      $Promise.prototype, symbolToStringTag, "Promise", DONT_ENUM | READ_ONLY);
   InstallFunctions($Promise, DONT_ENUM, [
     "defer", PromiseDeferred,
     "accept", PromiseResolved,
diff --git a/src/property-details.h b/src/property-details.h
index f75bcff..6140e0d 100644
--- a/src/property-details.h
+++ b/src/property-details.h
@@ -41,16 +41,24 @@
 class TypeInfo;
 
 // Type of properties.
+// Order of kinds is significant.
+// Must fit in the BitField PropertyDetails::KindField.
+enum PropertyKind { DATA = 0, ACCESSOR = 1 };
+
+
+// Order of modes is significant.
+// Must fit in the BitField PropertyDetails::StoreModeField.
+enum PropertyLocation { IN_OBJECT = 0, IN_DESCRIPTOR = 1 };
+
+
 // Order of properties is significant.
 // Must fit in the BitField PropertyDetails::TypeField.
 // A copy of this is in mirror-debugger.js.
 enum PropertyType {
-  // Only in slow mode.
-  NORMAL = 0,
-  // Only in fast mode.
-  FIELD = 1,
-  CONSTANT = 2,
-  CALLBACKS = 3
+  FIELD = (IN_OBJECT << 1) | DATA,
+  CONSTANT = (IN_DESCRIPTOR << 1) | DATA,
+  ACCESSOR_FIELD = (IN_OBJECT << 1) | ACCESSOR,
+  CALLBACKS = (IN_DESCRIPTOR << 1) | ACCESSOR
 };
 
 
@@ -229,6 +237,9 @@
     return Representation::FromKind(static_cast<Representation::Kind>(bits));
   }
 
+  PropertyKind kind() const { return KindField::decode(value_); }
+  PropertyLocation location() const { return LocationField::decode(value_); }
+
   PropertyType type() const { return TypeField::decode(value_); }
 
   PropertyAttributes attributes() const {
@@ -240,13 +251,12 @@
   }
 
   Representation representation() const {
-    DCHECK(type() != NORMAL);
     return DecodeRepresentation(RepresentationField::decode(value_));
   }
 
-  int field_index() const {
-    return FieldIndexField::decode(value_);
-  }
+  int field_index() const { return FieldIndexField::decode(value_); }
+
+  inline int field_width_in_words() const;
 
   inline PropertyDetails AsDeleted() const;
 
@@ -257,11 +267,12 @@
   bool IsReadOnly() const { return (attributes() & READ_ONLY) != 0; }
   bool IsConfigurable() const { return (attributes() & DONT_DELETE) == 0; }
   bool IsDontEnum() const { return (attributes() & DONT_ENUM) != 0; }
-  bool IsDeleted() const { return DeletedField::decode(value_) != 0;}
+  bool IsDeleted() const { return DeletedField::decode(value_) != 0; }
 
   // Bit fields in value_ (type, shift, size). Must be public so the
   // constants can be embedded in generated code.
-  class TypeField : public BitField<PropertyType, 0, 2> {};
+  class KindField : public BitField<PropertyKind, 0, 1> {};
+  class LocationField : public BitField<PropertyLocation, 1, 1> {};
   class AttributesField : public BitField<PropertyAttributes, 2, 3> {};
 
   // Bit fields for normalized objects.
@@ -275,11 +286,24 @@
   class FieldIndexField
       : public BitField<uint32_t, 9 + kDescriptorIndexBitCount,
                         kDescriptorIndexBitCount> {};  // NOLINT
-  // All bits for fast objects must fix in a smi.
-  STATIC_ASSERT(9 + kDescriptorIndexBitCount + kDescriptorIndexBitCount <= 31);
+
+  // NOTE: TypeField overlaps with KindField and LocationField.
+  class TypeField : public BitField<PropertyType, 0, 2> {};
+  STATIC_ASSERT(KindField::kNext == LocationField::kShift);
+  STATIC_ASSERT(TypeField::kShift == KindField::kShift);
+  STATIC_ASSERT(TypeField::kNext == LocationField::kNext);
+
+  // All bits for both fast and slow objects must fit in a smi.
+  STATIC_ASSERT(DictionaryStorageField::kNext <= 31);
+  STATIC_ASSERT(FieldIndexField::kNext <= 31);
 
   static const int kInitialIndex = 1;
 
+#ifdef OBJECT_PRINT
+  // For our gdb macros, we should perhaps change these in the future.
+  void Print(bool dictionary_mode);
+#endif
+
  private:
   PropertyDetails(int value, int pointer) {
     value_ = DescriptorPointer::update(value, pointer);
@@ -295,6 +319,10 @@
   uint32_t value_;
 };
 
+
+std::ostream& operator<<(std::ostream& os,
+                         const PropertyAttributes& attributes);
+std::ostream& operator<<(std::ostream& os, const PropertyDetails& details);
 } }  // namespace v8::internal
 
 #endif  // V8_PROPERTY_DETAILS_H_
diff --git a/src/property.cc b/src/property.cc
index f0ff95c..d00998c 100644
--- a/src/property.cc
+++ b/src/property.cc
@@ -20,7 +20,7 @@
 }
 
 
-OStream& operator<<(OStream& os, const LookupResult& r) {
+std::ostream& operator<<(std::ostream& os, const LookupResult& r) {
   if (!r.IsFound()) return os << "Not Found\n";
 
   os << "LookupResult:\n";
@@ -31,9 +31,76 @@
 }
 
 
-OStream& operator<<(OStream& os, const Descriptor& d) {
-  return os << "Descriptor " << Brief(*d.GetKey()) << " @ "
-            << Brief(*d.GetValue());
+std::ostream& operator<<(std::ostream& os,
+                         const PropertyAttributes& attributes) {
+  os << "[";
+  os << (((attributes & READ_ONLY) == 0) ? "W" : "_");    // writable
+  os << (((attributes & DONT_ENUM) == 0) ? "E" : "_");    // enumerable
+  os << (((attributes & DONT_DELETE) == 0) ? "C" : "_");  // configurable
+  os << "]";
+  return os;
+}
+
+
+struct FastPropertyDetails {
+  explicit FastPropertyDetails(const PropertyDetails& v) : details(v) {}
+  const PropertyDetails details;
+};
+
+
+// Outputs PropertyDetails as a dictionary details.
+std::ostream& operator<<(std::ostream& os, const PropertyDetails& details) {
+  os << "(";
+  if (details.location() == IN_DESCRIPTOR) {
+    os << "immutable ";
+  }
+  os << (details.kind() == DATA ? "data" : "accessor");
+  return os << ", dictionary_index: " << details.dictionary_index()
+            << ", attrs: " << details.attributes() << ")";
+}
+
+
+// Outputs PropertyDetails as a descriptor array details.
+std::ostream& operator<<(std::ostream& os,
+                         const FastPropertyDetails& details_fast) {
+  const PropertyDetails& details = details_fast.details;
+  os << "(";
+  if (details.location() == IN_DESCRIPTOR) {
+    os << "immutable ";
+  }
+  os << (details.kind() == DATA ? "data" : "accessor");
+  if (details.location() == IN_OBJECT) {
+    os << ": " << details.representation().Mnemonic()
+       << ", field_index: " << details.field_index();
+  }
+  return os << ", p: " << details.pointer()
+            << ", attrs: " << details.attributes() << ")";
+}
+
+
+#ifdef OBJECT_PRINT
+void PropertyDetails::Print(bool dictionary_mode) {
+  OFStream os(stdout);
+  if (dictionary_mode) {
+    os << *this;
+  } else {
+    os << FastPropertyDetails(*this);
+  }
+  os << "\n" << std::flush;
+}
+#endif
+
+
+std::ostream& operator<<(std::ostream& os, const Descriptor& d) {
+  Object* value = *d.GetValue();
+  os << "Descriptor " << Brief(*d.GetKey()) << " @ " << Brief(value) << " ";
+  if (value->IsAccessorPair()) {
+    AccessorPair* pair = AccessorPair::cast(value);
+    os << "(get: " << Brief(pair->getter())
+       << ", set: " << Brief(pair->setter()) << ") ";
+  }
+  os << FastPropertyDetails(d.GetDetails());
+  return os;
 }
 
 } }  // namespace v8::internal
diff --git a/src/property.h b/src/property.h
index 779d9fc..a9d8b09 100644
--- a/src/property.h
+++ b/src/property.h
@@ -5,6 +5,8 @@
 #ifndef V8_PROPERTY_H_
 #define V8_PROPERTY_H_
 
+#include <iosfwd>
+
 #include "src/factory.h"
 #include "src/field-index.h"
 #include "src/field-index-inl.h"
@@ -14,8 +16,6 @@
 namespace v8 {
 namespace internal {
 
-class OStream;
-
 // Abstraction for elements in instance-descriptor arrays.
 //
 // Each descriptor has a key, property attributes, property type,
@@ -70,7 +70,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const Descriptor& d);
+std::ostream& operator<<(std::ostream& os, const Descriptor& d);
 
 
 class FieldDescriptor FINAL : public Descriptor {
@@ -119,7 +119,7 @@
         lookup_type_(NOT_FOUND),
         holder_(NULL),
         transition_(NULL),
-        details_(NONE, NORMAL, Representation::None()) {
+        details_(NONE, FIELD, Representation::None()) {
     isolate->set_top_lookup_result(this);
   }
 
@@ -148,7 +148,7 @@
 
   void NotFound() {
     lookup_type_ = NOT_FOUND;
-    details_ = PropertyDetails(NONE, NORMAL, Representation::None());
+    details_ = PropertyDetails(NONE, FIELD, 0);
     holder_ = NULL;
     transition_ = NULL;
   }
@@ -160,7 +160,6 @@
 
   // Property callbacks does not include transitions to callbacks.
   bool IsPropertyCallbacks() const {
-    DCHECK(!(details_.type() == CALLBACKS && !IsFound()));
     return !IsTransition() && details_.type() == CALLBACKS;
   }
 
@@ -170,12 +169,10 @@
   }
 
   bool IsField() const {
-    DCHECK(!(details_.type() == FIELD && !IsFound()));
     return lookup_type_ == DESCRIPTOR_TYPE && details_.type() == FIELD;
   }
 
   bool IsConstant() const {
-    DCHECK(!(details_.type() == CONSTANT && !IsFound()));
     return lookup_type_ == DESCRIPTOR_TYPE && details_.type() == CONSTANT;
   }
 
@@ -249,7 +246,7 @@
 };
 
 
-OStream& operator<<(OStream& os, const LookupResult& r);
+std::ostream& operator<<(std::ostream& os, const LookupResult& r);
 } }  // namespace v8::internal
 
 #endif  // V8_PROPERTY_H_
diff --git a/src/regexp.js b/src/regexp.js
index 0f3dbb6..e1eac76 100644
--- a/src/regexp.js
+++ b/src/regexp.js
@@ -30,46 +30,7 @@
   pattern = IS_UNDEFINED(pattern) ? '' : ToString(pattern);
   flags = IS_UNDEFINED(flags) ? '' : ToString(flags);
 
-  var global = false;
-  var ignoreCase = false;
-  var multiline = false;
-  var sticky = false;
-  for (var i = 0; i < flags.length; i++) {
-    var c = %_CallFunction(flags, i, StringCharAt);
-    switch (c) {
-      case 'g':
-        if (global) {
-          throw MakeSyntaxError("invalid_regexp_flags", [flags]);
-        }
-        global = true;
-        break;
-      case 'i':
-        if (ignoreCase) {
-          throw MakeSyntaxError("invalid_regexp_flags", [flags]);
-        }
-        ignoreCase = true;
-        break;
-      case 'm':
-        if (multiline) {
-          throw MakeSyntaxError("invalid_regexp_flags", [flags]);
-        }
-        multiline = true;
-        break;
-      case 'y':
-        if (!harmony_regexps || sticky) {
-          throw MakeSyntaxError("invalid_regexp_flags", [flags]);
-        }
-        sticky = true;
-        break;
-      default:
-        throw MakeSyntaxError("invalid_regexp_flags", [flags]);
-    }
-  }
-
-  %RegExpInitializeObject(object, pattern, global, ignoreCase, multiline, sticky);
-
-  // Call internal function to compile the pattern.
-  %RegExpCompile(object, pattern, flags);
+  %RegExpInitializeAndCompile(object, pattern, flags);
 }
 
 
diff --git a/src/rewriter.cc b/src/rewriter.cc
index 867229a..c52051a 100644
--- a/src/rewriter.cc
+++ b/src/rewriter.cc
@@ -15,15 +15,13 @@
 
 class Processor: public AstVisitor {
  public:
-  Processor(Variable* result, Zone* zone, AstNode::IdGen* ast_node_id_gen)
+  Processor(Variable* result, AstValueFactory* ast_value_factory)
       : result_(result),
         result_assigned_(false),
         is_set_(false),
         in_try_(false),
-        // Passing a null AstValueFactory is fine, because Processor doesn't
-        // need to create strings or literals.
-        factory_(zone, NULL, ast_node_id_gen) {
-    InitializeAstVisitor(zone);
+        factory_(ast_value_factory) {
+    InitializeAstVisitor(ast_value_factory->zone());
   }
 
   virtual ~Processor() { }
@@ -31,9 +29,7 @@
   void Process(ZoneList<Statement*>* statements);
   bool result_assigned() const { return result_assigned_; }
 
-  AstNodeFactory<AstNullVisitor>* factory() {
-    return &factory_;
-  }
+  AstNodeFactory* factory() { return &factory_; }
 
  private:
   Variable* result_;
@@ -51,7 +47,7 @@
   bool is_set_;
   bool in_try_;
 
-  AstNodeFactory<AstNullVisitor> factory_;
+  AstNodeFactory factory_;
 
   Expression* SetResult(Expression* value) {
     result_assigned_ = true;
@@ -61,8 +57,7 @@
   }
 
   // Node visitors.
-#define DEF_VISIT(type) \
-  virtual void Visit##type(type* node);
+#define DEF_VISIT(type) virtual void Visit##type(type* node) OVERRIDE;
   AST_NODE_LIST(DEF_VISIT)
 #undef DEF_VISIT
 
@@ -232,7 +227,7 @@
   DCHECK(function != NULL);
   Scope* scope = function->scope();
   DCHECK(scope != NULL);
-  if (!scope->is_global_scope() && !scope->is_eval_scope()) return true;
+  if (!scope->is_script_scope() && !scope->is_eval_scope()) return true;
 
   ZoneList<Statement*>* body = function->body();
   if (!body->is_empty()) {
@@ -240,7 +235,7 @@
         scope->NewTemporary(info->ast_value_factory()->dot_result_string());
     // The name string must be internalized at this point.
     DCHECK(!result->name().is_null());
-    Processor processor(result, info->zone(), info->ast_node_id_gen());
+    Processor processor(result, info->ast_value_factory());
     processor.Process(body);
     if (processor.HasStackOverflow()) return false;
 
@@ -253,9 +248,8 @@
       // the end position of the function generated for executing the eval code
       // coincides with the end of the with scope which is the position of '1'.
       int pos = function->end_position();
-      VariableProxy* result_proxy = processor.factory()->NewVariableProxy(
-          result->raw_name(), false, result->interface(), pos);
-      result_proxy->BindTo(result);
+      VariableProxy* result_proxy =
+          processor.factory()->NewVariableProxy(result, pos);
       Statement* result_statement =
           processor.factory()->NewReturnStatement(result_proxy, pos);
       body->Add(result_statement, info->zone());
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index d6099d4..6c99714 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -57,9 +57,11 @@
 }
 
 
-static void GetICCounts(Code* shared_code, int* ic_with_type_info_count,
-                        int* ic_generic_count, int* ic_total_count,
-                        int* type_info_percentage, int* generic_percentage) {
+static void GetICCounts(SharedFunctionInfo* shared,
+                        int* ic_with_type_info_count, int* ic_generic_count,
+                        int* ic_total_count, int* type_info_percentage,
+                        int* generic_percentage) {
+  Code* shared_code = shared->code();
   *ic_total_count = 0;
   *ic_generic_count = 0;
   *ic_with_type_info_count = 0;
@@ -70,6 +72,12 @@
     *ic_generic_count = info->ic_generic_count();
     *ic_total_count = info->ic_total_count();
   }
+
+  // Harvest vector-ics as well
+  TypeFeedbackVector* vector = shared->feedback_vector();
+  *ic_with_type_info_count += vector->ic_with_type_info_count();
+  *ic_generic_count += vector->ic_generic_count();
+
   if (*ic_total_count > 0) {
     *type_info_percentage = 100 * *ic_with_type_info_count / *ic_total_count;
     *generic_percentage = 100 * *ic_generic_count / *ic_total_count;
@@ -89,7 +97,7 @@
     PrintF(" for recompilation, reason: %s", reason);
     if (FLAG_type_info_threshold > 0) {
       int typeinfo, generic, total, type_percentage, generic_percentage;
-      GetICCounts(function->shared()->code(), &typeinfo, &generic, &total,
+      GetICCounts(function->shared(), &typeinfo, &generic, &total,
                   &type_percentage, &generic_percentage);
       PrintF(", ICs with typeinfo: %d/%d (%d%%)", typeinfo, total,
              type_percentage);
@@ -98,23 +106,7 @@
     PrintF("]\n");
   }
 
-
-  if (isolate_->concurrent_recompilation_enabled() &&
-      !isolate_->bootstrapper()->IsActive()) {
-    if (isolate_->concurrent_osr_enabled() &&
-        isolate_->optimizing_compiler_thread()->IsQueuedForOSR(function)) {
-      // Do not attempt regular recompilation if we already queued this for OSR.
-      // TODO(yangguo): This is necessary so that we don't install optimized
-      // code on a function that is already optimized, since OSR and regular
-      // recompilation race.  This goes away as soon as OSR becomes one-shot.
-      return;
-    }
-    DCHECK(!function->IsInOptimizationQueue());
-    function->MarkForConcurrentOptimization();
-  } else {
-    // The next call to the function will trigger optimization.
-    function->MarkForOptimization();
-  }
+  function->AttemptConcurrentOptimization();
 }
 
 
@@ -155,7 +147,7 @@
 void RuntimeProfiler::OptimizeNow() {
   HandleScope scope(isolate_);
 
-  if (isolate_->DebuggerHasBreakPoints()) return;
+  if (!isolate_->use_crankshaft() || isolate_->DebuggerHasBreakPoints()) return;
 
   DisallowHeapAllocation no_gc;
 
@@ -236,7 +228,7 @@
 
     if (ticks >= kProfilerTicksBeforeOptimization) {
       int typeinfo, generic, total, type_percentage, generic_percentage;
-      GetICCounts(shared_code, &typeinfo, &generic, &total, &type_percentage,
+      GetICCounts(shared, &typeinfo, &generic, &total, &type_percentage,
                   &generic_percentage);
       if (type_percentage >= FLAG_type_info_threshold &&
           generic_percentage <= FLAG_generic_ic_threshold) {
@@ -259,7 +251,7 @@
       // If no IC was patched since the last tick and this function is very
       // small, optimistically optimize it now.
       int typeinfo, generic, total, type_percentage, generic_percentage;
-      GetICCounts(shared_code, &typeinfo, &generic, &total, &type_percentage,
+      GetICCounts(shared, &typeinfo, &generic, &total, &type_percentage,
                   &generic_percentage);
       if (type_percentage >= FLAG_type_info_threshold &&
           generic_percentage <= FLAG_generic_ic_threshold) {
diff --git a/src/runtime.cc b/src/runtime.cc
deleted file mode 100644
index cfef8c2..0000000
--- a/src/runtime.cc
+++ /dev/null
@@ -1,15771 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdlib.h>
-#include <limits>
-
-#include "src/v8.h"
-
-#include "src/accessors.h"
-#include "src/allocation-site-scopes.h"
-#include "src/api.h"
-#include "src/arguments.h"
-#include "src/bailout-reason.h"
-#include "src/base/cpu.h"
-#include "src/base/platform/platform.h"
-#include "src/bootstrapper.h"
-#include "src/codegen.h"
-#include "src/compilation-cache.h"
-#include "src/compiler.h"
-#include "src/conversions.h"
-#include "src/cpu-profiler.h"
-#include "src/date.h"
-#include "src/dateparser-inl.h"
-#include "src/debug.h"
-#include "src/deoptimizer.h"
-#include "src/execution.h"
-#include "src/full-codegen.h"
-#include "src/global-handles.h"
-#include "src/isolate-inl.h"
-#include "src/json-parser.h"
-#include "src/json-stringifier.h"
-#include "src/jsregexp-inl.h"
-#include "src/jsregexp.h"
-#include "src/liveedit.h"
-#include "src/misc-intrinsics.h"
-#include "src/parser.h"
-#include "src/prototype.h"
-#include "src/runtime.h"
-#include "src/runtime-profiler.h"
-#include "src/scopeinfo.h"
-#include "src/smart-pointers.h"
-#include "src/string-search.h"
-#include "src/uri.h"
-#include "src/utils.h"
-#include "src/v8threads.h"
-#include "src/vm-state-inl.h"
-#include "third_party/fdlibm/fdlibm.h"
-
-#ifdef V8_I18N_SUPPORT
-#include "src/i18n.h"
-#include "unicode/brkiter.h"
-#include "unicode/calendar.h"
-#include "unicode/coll.h"
-#include "unicode/curramt.h"
-#include "unicode/datefmt.h"
-#include "unicode/dcfmtsym.h"
-#include "unicode/decimfmt.h"
-#include "unicode/dtfmtsym.h"
-#include "unicode/dtptngen.h"
-#include "unicode/locid.h"
-#include "unicode/numfmt.h"
-#include "unicode/numsys.h"
-#include "unicode/rbbi.h"
-#include "unicode/smpdtfmt.h"
-#include "unicode/timezone.h"
-#include "unicode/uchar.h"
-#include "unicode/ucol.h"
-#include "unicode/ucurr.h"
-#include "unicode/uloc.h"
-#include "unicode/unum.h"
-#include "unicode/uversion.h"
-#endif
-
-#ifndef _STLP_VENDOR_CSTD
-// STLPort doesn't import fpclassify and isless into the std namespace.
-using std::fpclassify;
-using std::isless;
-#endif
-
-namespace v8 {
-namespace internal {
-
-
-#define RUNTIME_ASSERT(value) \
-  if (!(value)) return isolate->ThrowIllegalOperation();
-
-#define RUNTIME_ASSERT_HANDLIFIED(value, T)                          \
-  if (!(value)) {                                                    \
-    isolate->ThrowIllegalOperation();                                \
-    return MaybeHandle<T>();                                         \
-  }
-
-// Cast the given object to a value of the specified type and store
-// it in a variable with the given name.  If the object is not of the
-// expected type call IllegalOperation and return.
-#define CONVERT_ARG_CHECKED(Type, name, index)                       \
-  RUNTIME_ASSERT(args[index]->Is##Type());                           \
-  Type* name = Type::cast(args[index]);
-
-#define CONVERT_ARG_HANDLE_CHECKED(Type, name, index)                \
-  RUNTIME_ASSERT(args[index]->Is##Type());                           \
-  Handle<Type> name = args.at<Type>(index);
-
-#define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index)               \
-  RUNTIME_ASSERT(args[index]->IsNumber());                           \
-  Handle<Object> name = args.at<Object>(index);
-
-// Cast the given object to a boolean and store it in a variable with
-// the given name.  If the object is not a boolean call IllegalOperation
-// and return.
-#define CONVERT_BOOLEAN_ARG_CHECKED(name, index)                     \
-  RUNTIME_ASSERT(args[index]->IsBoolean());                          \
-  bool name = args[index]->IsTrue();
-
-// Cast the given argument to a Smi and store its value in an int variable
-// with the given name.  If the argument is not a Smi call IllegalOperation
-// and return.
-#define CONVERT_SMI_ARG_CHECKED(name, index)                         \
-  RUNTIME_ASSERT(args[index]->IsSmi());                              \
-  int name = args.smi_at(index);
-
-// Cast the given argument to a double and store it in a variable with
-// the given name.  If the argument is not a number (as opposed to
-// the number not-a-number) call IllegalOperation and return.
-#define CONVERT_DOUBLE_ARG_CHECKED(name, index)                      \
-  RUNTIME_ASSERT(args[index]->IsNumber());                           \
-  double name = args.number_at(index);
-
-// Call the specified converter on the object *comand store the result in
-// a variable of the specified type with the given name.  If the
-// object is not a Number call IllegalOperation and return.
-#define CONVERT_NUMBER_CHECKED(type, name, Type, obj)                \
-  RUNTIME_ASSERT(obj->IsNumber());                                   \
-  type name = NumberTo##Type(obj);
-
-
-// Cast the given argument to PropertyDetails and store its value in a
-// variable with the given name.  If the argument is not a Smi call
-// IllegalOperation and return.
-#define CONVERT_PROPERTY_DETAILS_CHECKED(name, index)                \
-  RUNTIME_ASSERT(args[index]->IsSmi());                              \
-  PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
-
-
-// Assert that the given argument has a valid value for a StrictMode
-// and store it in a StrictMode variable with the given name.
-#define CONVERT_STRICT_MODE_ARG_CHECKED(name, index)                 \
-  RUNTIME_ASSERT(args[index]->IsSmi());                              \
-  RUNTIME_ASSERT(args.smi_at(index) == STRICT ||                     \
-                 args.smi_at(index) == SLOPPY);                      \
-  StrictMode name = static_cast<StrictMode>(args.smi_at(index));
-
-
-// Assert that the given argument is a number within the Int32 range
-// and convert it to int32_t.  If the argument is not an Int32 call
-// IllegalOperation and return.
-#define CONVERT_INT32_ARG_CHECKED(name, index)                       \
-  RUNTIME_ASSERT(args[index]->IsNumber());                           \
-  int32_t name = 0;                                                  \
-  RUNTIME_ASSERT(args[index]->ToInt32(&name));
-
-
-static Handle<Map> ComputeObjectLiteralMap(
-    Handle<Context> context,
-    Handle<FixedArray> constant_properties,
-    bool* is_result_from_cache) {
-  Isolate* isolate = context->GetIsolate();
-  int properties_length = constant_properties->length();
-  int number_of_properties = properties_length / 2;
-  // Check that there are only internal strings and array indices among keys.
-  int number_of_string_keys = 0;
-  for (int p = 0; p != properties_length; p += 2) {
-    Object* key = constant_properties->get(p);
-    uint32_t element_index = 0;
-    if (key->IsInternalizedString()) {
-      number_of_string_keys++;
-    } else if (key->ToArrayIndex(&element_index)) {
-      // An index key does not require space in the property backing store.
-      number_of_properties--;
-    } else {
-      // Bail out as a non-internalized-string non-index key makes caching
-      // impossible.
-      // DCHECK to make sure that the if condition after the loop is false.
-      DCHECK(number_of_string_keys != number_of_properties);
-      break;
-    }
-  }
-  // If we only have internalized strings and array indices among keys then we
-  // can use the map cache in the native context.
-  const int kMaxKeys = 10;
-  if ((number_of_string_keys == number_of_properties) &&
-      (number_of_string_keys < kMaxKeys)) {
-    // Create the fixed array with the key.
-    Handle<FixedArray> keys =
-        isolate->factory()->NewFixedArray(number_of_string_keys);
-    if (number_of_string_keys > 0) {
-      int index = 0;
-      for (int p = 0; p < properties_length; p += 2) {
-        Object* key = constant_properties->get(p);
-        if (key->IsInternalizedString()) {
-          keys->set(index++, key);
-        }
-      }
-      DCHECK(index == number_of_string_keys);
-    }
-    *is_result_from_cache = true;
-    return isolate->factory()->ObjectLiteralMapFromCache(context, keys);
-  }
-  *is_result_from_cache = false;
-  return Map::Create(isolate, number_of_properties);
-}
-
-
-MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
-    Isolate* isolate,
-    Handle<FixedArray> literals,
-    Handle<FixedArray> constant_properties);
-
-
-MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
-    Isolate* isolate,
-    Handle<FixedArray> literals,
-    Handle<FixedArray> constant_properties,
-    bool should_have_fast_elements,
-    bool has_function_literal) {
-  // Get the native context from the literals array.  This is the
-  // context in which the function was created and we use the object
-  // function from this context to create the object literal.  We do
-  // not use the object function from the current native context
-  // because this might be the object function from another context
-  // which we should not have access to.
-  Handle<Context> context =
-      Handle<Context>(JSFunction::NativeContextFromLiterals(*literals));
-
-  // In case we have function literals, we want the object to be in
-  // slow properties mode for now. We don't go in the map cache because
-  // maps with constant functions can't be shared if the functions are
-  // not the same (which is the common case).
-  bool is_result_from_cache = false;
-  Handle<Map> map = has_function_literal
-      ? Handle<Map>(context->object_function()->initial_map())
-      : ComputeObjectLiteralMap(context,
-                                constant_properties,
-                                &is_result_from_cache);
-
-  PretenureFlag pretenure_flag =
-      isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
-
-  Handle<JSObject> boilerplate =
-      isolate->factory()->NewJSObjectFromMap(map, pretenure_flag);
-
-  // Normalize the elements of the boilerplate to save space if needed.
-  if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
-
-  // Add the constant properties to the boilerplate.
-  int length = constant_properties->length();
-  bool should_transform =
-      !is_result_from_cache && boilerplate->HasFastProperties();
-  bool should_normalize = should_transform || has_function_literal;
-  if (should_normalize) {
-    // TODO(verwaest): We might not want to ever normalize here.
-    JSObject::NormalizeProperties(
-        boilerplate, KEEP_INOBJECT_PROPERTIES, length / 2);
-  }
-  // TODO(verwaest): Support tracking representations in the boilerplate.
-  for (int index = 0; index < length; index +=2) {
-    Handle<Object> key(constant_properties->get(index+0), isolate);
-    Handle<Object> value(constant_properties->get(index+1), isolate);
-    if (value->IsFixedArray()) {
-      // The value contains the constant_properties of a
-      // simple object or array literal.
-      Handle<FixedArray> array = Handle<FixedArray>::cast(value);
-      ASSIGN_RETURN_ON_EXCEPTION(
-          isolate, value,
-          CreateLiteralBoilerplate(isolate, literals, array),
-          Object);
-    }
-    MaybeHandle<Object> maybe_result;
-    uint32_t element_index = 0;
-    if (key->IsInternalizedString()) {
-      if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
-        // Array index as string (uint32).
-        if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
-        maybe_result =
-            JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY);
-      } else {
-        Handle<String> name(String::cast(*key));
-        DCHECK(!name->AsArrayIndex(&element_index));
-        maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
-            boilerplate, name, value, NONE);
-      }
-    } else if (key->ToArrayIndex(&element_index)) {
-      // Array index (uint32).
-      if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
-      maybe_result =
-          JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY);
-    } else {
-      // Non-uint32 number.
-      DCHECK(key->IsNumber());
-      double num = key->Number();
-      char arr[100];
-      Vector<char> buffer(arr, arraysize(arr));
-      const char* str = DoubleToCString(num, buffer);
-      Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
-      maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name,
-                                                              value, NONE);
-    }
-    // If setting the property on the boilerplate throws an
-    // exception, the exception is converted to an empty handle in
-    // the handle based operations.  In that case, we need to
-    // convert back to an exception.
-    RETURN_ON_EXCEPTION(isolate, maybe_result, Object);
-  }
-
-  // Transform to fast properties if necessary. For object literals with
-  // containing function literals we defer this operation until after all
-  // computed properties have been assigned so that we can generate
-  // constant function properties.
-  if (should_transform && !has_function_literal) {
-    JSObject::MigrateSlowToFast(
-        boilerplate, boilerplate->map()->unused_property_fields());
-  }
-
-  return boilerplate;
-}
-
-
-MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
-    Handle<Object> object,
-    ElementsKind to_kind,
-    Isolate* isolate) {
-  HandleScope scope(isolate);
-  if (!object->IsJSObject()) {
-    isolate->ThrowIllegalOperation();
-    return MaybeHandle<Object>();
-  }
-  ElementsKind from_kind =
-      Handle<JSObject>::cast(object)->map()->elements_kind();
-  if (Map::IsValidElementsTransition(from_kind, to_kind)) {
-    JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
-    return object;
-  }
-  isolate->ThrowIllegalOperation();
-  return MaybeHandle<Object>();
-}
-
-
-MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
-    Isolate* isolate,
-    Handle<FixedArray> literals,
-    Handle<FixedArray> elements) {
-  // Create the JSArray.
-  Handle<JSFunction> constructor(
-      JSFunction::NativeContextFromLiterals(*literals)->array_function());
-
-  PretenureFlag pretenure_flag =
-      isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
-
-  Handle<JSArray> object = Handle<JSArray>::cast(
-      isolate->factory()->NewJSObject(constructor, pretenure_flag));
-
-  ElementsKind constant_elements_kind =
-      static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
-  Handle<FixedArrayBase> constant_elements_values(
-      FixedArrayBase::cast(elements->get(1)));
-
-  { DisallowHeapAllocation no_gc;
-    DCHECK(IsFastElementsKind(constant_elements_kind));
-    Context* native_context = isolate->context()->native_context();
-    Object* maps_array = native_context->js_array_maps();
-    DCHECK(!maps_array->IsUndefined());
-    Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind);
-    object->set_map(Map::cast(map));
-  }
-
-  Handle<FixedArrayBase> copied_elements_values;
-  if (IsFastDoubleElementsKind(constant_elements_kind)) {
-    copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
-        Handle<FixedDoubleArray>::cast(constant_elements_values));
-  } else {
-    DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind));
-    const bool is_cow =
-        (constant_elements_values->map() ==
-         isolate->heap()->fixed_cow_array_map());
-    if (is_cow) {
-      copied_elements_values = constant_elements_values;
-#if DEBUG
-      Handle<FixedArray> fixed_array_values =
-          Handle<FixedArray>::cast(copied_elements_values);
-      for (int i = 0; i < fixed_array_values->length(); i++) {
-        DCHECK(!fixed_array_values->get(i)->IsFixedArray());
-      }
-#endif
-    } else {
-      Handle<FixedArray> fixed_array_values =
-          Handle<FixedArray>::cast(constant_elements_values);
-      Handle<FixedArray> fixed_array_values_copy =
-          isolate->factory()->CopyFixedArray(fixed_array_values);
-      copied_elements_values = fixed_array_values_copy;
-      for (int i = 0; i < fixed_array_values->length(); i++) {
-        if (fixed_array_values->get(i)->IsFixedArray()) {
-          // The value contains the constant_properties of a
-          // simple object or array literal.
-          Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
-          Handle<Object> result;
-          ASSIGN_RETURN_ON_EXCEPTION(
-              isolate, result,
-              CreateLiteralBoilerplate(isolate, literals, fa),
-              Object);
-          fixed_array_values_copy->set(i, *result);
-        }
-      }
-    }
-  }
-  object->set_elements(*copied_elements_values);
-  object->set_length(Smi::FromInt(copied_elements_values->length()));
-
-  JSObject::ValidateElements(object);
-  return object;
-}
-
-
-MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
-    Isolate* isolate,
-    Handle<FixedArray> literals,
-    Handle<FixedArray> array) {
-  Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
-  const bool kHasNoFunctionLiteral = false;
-  switch (CompileTimeValue::GetLiteralType(array)) {
-    case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
-      return CreateObjectLiteralBoilerplate(isolate,
-                                            literals,
-                                            elements,
-                                            true,
-                                            kHasNoFunctionLiteral);
-    case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
-      return CreateObjectLiteralBoilerplate(isolate,
-                                            literals,
-                                            elements,
-                                            false,
-                                            kHasNoFunctionLiteral);
-    case CompileTimeValue::ARRAY_LITERAL:
-      return Runtime::CreateArrayLiteralBoilerplate(
-          isolate, literals, elements);
-    default:
-      UNREACHABLE();
-      return MaybeHandle<Object>();
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
-  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
-  CONVERT_SMI_ARG_CHECKED(flags, 3);
-  bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
-  bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
-
-  RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length());
-
-  // Check if boilerplate exists. If not, create it first.
-  Handle<Object> literal_site(literals->get(literals_index), isolate);
-  Handle<AllocationSite> site;
-  Handle<JSObject> boilerplate;
-  if (*literal_site == isolate->heap()->undefined_value()) {
-    Handle<Object> raw_boilerplate;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, raw_boilerplate,
-        CreateObjectLiteralBoilerplate(
-            isolate,
-            literals,
-            constant_properties,
-            should_have_fast_elements,
-            has_function_literal));
-    boilerplate = Handle<JSObject>::cast(raw_boilerplate);
-
-    AllocationSiteCreationContext creation_context(isolate);
-    site = creation_context.EnterNewScope();
-    RETURN_FAILURE_ON_EXCEPTION(
-        isolate,
-        JSObject::DeepWalk(boilerplate, &creation_context));
-    creation_context.ExitScope(site, boilerplate);
-
-    // Update the functions literal and return the boilerplate.
-    literals->set(literals_index, *site);
-  } else {
-    site = Handle<AllocationSite>::cast(literal_site);
-    boilerplate = Handle<JSObject>(JSObject::cast(site->transition_info()),
-                                   isolate);
-  }
-
-  AllocationSiteUsageContext usage_context(isolate, site, true);
-  usage_context.EnterNewScope();
-  MaybeHandle<Object> maybe_copy = JSObject::DeepCopy(
-      boilerplate, &usage_context);
-  usage_context.ExitScope(site, boilerplate);
-  Handle<Object> copy;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy);
-  return *copy;
-}
-
-
-MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
-    Isolate* isolate,
-    Handle<FixedArray> literals,
-    int literals_index,
-    Handle<FixedArray> elements) {
-  // Check if boilerplate exists. If not, create it first.
-  Handle<Object> literal_site(literals->get(literals_index), isolate);
-  Handle<AllocationSite> site;
-  if (*literal_site == isolate->heap()->undefined_value()) {
-    DCHECK(*elements != isolate->heap()->empty_fixed_array());
-    Handle<Object> boilerplate;
-    ASSIGN_RETURN_ON_EXCEPTION(
-        isolate, boilerplate,
-        Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements),
-        AllocationSite);
-
-    AllocationSiteCreationContext creation_context(isolate);
-    site = creation_context.EnterNewScope();
-    if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate),
-                           &creation_context).is_null()) {
-      return Handle<AllocationSite>::null();
-    }
-    creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
-
-    literals->set(literals_index, *site);
-  } else {
-    site = Handle<AllocationSite>::cast(literal_site);
-  }
-
-  return site;
-}
-
-
-static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate,
-                                           Handle<FixedArray> literals,
-                                           int literals_index,
-                                           Handle<FixedArray> elements,
-                                           int flags) {
-  RUNTIME_ASSERT_HANDLIFIED(literals_index >= 0 &&
-                            literals_index < literals->length(), JSObject);
-  Handle<AllocationSite> site;
-  ASSIGN_RETURN_ON_EXCEPTION(
-      isolate, site,
-      GetLiteralAllocationSite(isolate, literals, literals_index, elements),
-      JSObject);
-
-  bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
-  Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
-  AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
-  usage_context.EnterNewScope();
-  JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
-                                      ? JSObject::kNoHints
-                                      : JSObject::kObjectIsShallow;
-  MaybeHandle<JSObject> copy = JSObject::DeepCopy(boilerplate, &usage_context,
-                                                  hints);
-  usage_context.ExitScope(site, boilerplate);
-  return copy;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
-  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
-  CONVERT_SMI_ARG_CHECKED(flags, 3);
-
-  Handle<JSObject> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
-      CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
-                             flags));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
-  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
-
-  Handle<JSObject> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
-     CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
-                            ArrayLiteral::kShallowElements));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateSymbol) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
-  RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
-  Handle<Symbol> symbol = isolate->factory()->NewSymbol();
-  if (name->IsString()) symbol->set_name(*name);
-  return *symbol;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
-  RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
-  Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol();
-  if (name->IsString()) symbol->set_name(*name);
-  return *symbol;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreatePrivateOwnSymbol) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
-  RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
-  Handle<Symbol> symbol = isolate->factory()->NewPrivateOwnSymbol();
-  if (name->IsString()) symbol->set_name(*name);
-  return *symbol;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateOwnSymbol) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
-  Handle<JSObject> registry = isolate->GetSymbolRegistry();
-  Handle<String> part = isolate->factory()->private_intern_string();
-  Handle<Object> privates;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, privates, Object::GetPropertyOrElement(registry, part));
-  Handle<Object> symbol;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, symbol, Object::GetPropertyOrElement(privates, name));
-  if (!symbol->IsSymbol()) {
-    DCHECK(symbol->IsUndefined());
-    symbol = isolate->factory()->NewPrivateSymbol();
-    Handle<Symbol>::cast(symbol)->set_name(*name);
-    Handle<Symbol>::cast(symbol)->set_is_own(true);
-    JSObject::SetProperty(Handle<JSObject>::cast(privates), name, symbol,
-                          STRICT).Assert();
-  }
-  return *symbol;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewSymbolWrapper) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Symbol, symbol, 0);
-  return *Object::ToObject(isolate, symbol).ToHandleChecked();
-}
-
-
-RUNTIME_FUNCTION(Runtime_SymbolDescription) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Symbol, symbol, 0);
-  return symbol->name();
-}
-
-
-RUNTIME_FUNCTION(Runtime_SymbolRegistry) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  return *isolate->GetSymbolRegistry();
-}
-
-
-RUNTIME_FUNCTION(Runtime_SymbolIsPrivate) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Symbol, symbol, 0);
-  return isolate->heap()->ToBoolean(symbol->is_private());
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateJSProxy) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
-  if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
-  return *isolate->factory()->NewJSProxy(handler, prototype);
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1);
-  RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2);
-  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3);
-  if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
-  return *isolate->factory()->NewJSFunctionProxy(
-      handler, call_trap, construct_trap, prototype);
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsJSProxy) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
-  return isolate->heap()->ToBoolean(obj->IsJSProxy());
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
-  return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetHandler) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
-  return proxy->handler();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetCallTrap) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
-  return proxy->call_trap();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetConstructTrap) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
-  return proxy->construct_trap();
-}
-
-
-RUNTIME_FUNCTION(Runtime_Fix) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
-  JSProxy::Fix(proxy);
-  return isolate->heap()->undefined_value();
-}
-
-
-void Runtime::FreeArrayBuffer(Isolate* isolate,
-                              JSArrayBuffer* phantom_array_buffer) {
-  if (phantom_array_buffer->should_be_freed()) {
-    DCHECK(phantom_array_buffer->is_external());
-    free(phantom_array_buffer->backing_store());
-  }
-  if (phantom_array_buffer->is_external()) return;
-
-  size_t allocated_length = NumberToSize(
-      isolate, phantom_array_buffer->byte_length());
-
-  reinterpret_cast<v8::Isolate*>(isolate)
-      ->AdjustAmountOfExternalAllocatedMemory(
-          -static_cast<int64_t>(allocated_length));
-  CHECK(V8::ArrayBufferAllocator() != NULL);
-  V8::ArrayBufferAllocator()->Free(
-      phantom_array_buffer->backing_store(),
-      allocated_length);
-}
-
-
-void Runtime::SetupArrayBuffer(Isolate* isolate,
-                               Handle<JSArrayBuffer> array_buffer,
-                               bool is_external,
-                               void* data,
-                               size_t allocated_length) {
-  DCHECK(array_buffer->GetInternalFieldCount() ==
-      v8::ArrayBuffer::kInternalFieldCount);
-  for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
-    array_buffer->SetInternalField(i, Smi::FromInt(0));
-  }
-  array_buffer->set_backing_store(data);
-  array_buffer->set_flag(Smi::FromInt(0));
-  array_buffer->set_is_external(is_external);
-
-  Handle<Object> byte_length =
-      isolate->factory()->NewNumberFromSize(allocated_length);
-  CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
-  array_buffer->set_byte_length(*byte_length);
-
-  array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
-  isolate->heap()->set_array_buffers_list(*array_buffer);
-  array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
-}
-
-
-bool Runtime::SetupArrayBufferAllocatingData(
-    Isolate* isolate,
-    Handle<JSArrayBuffer> array_buffer,
-    size_t allocated_length,
-    bool initialize) {
-  void* data;
-  CHECK(V8::ArrayBufferAllocator() != NULL);
-  if (allocated_length != 0) {
-    if (initialize) {
-      data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
-    } else {
-      data =
-          V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
-    }
-    if (data == NULL) return false;
-  } else {
-    data = NULL;
-  }
-
-  SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
-
-  reinterpret_cast<v8::Isolate*>(isolate)
-      ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
-
-  return true;
-}
-
-
-void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
-  Isolate* isolate = array_buffer->GetIsolate();
-  for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate);
-       !view_obj->IsUndefined();) {
-    Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj));
-    if (view->IsJSTypedArray()) {
-      JSTypedArray::cast(*view)->Neuter();
-    } else if (view->IsJSDataView()) {
-      JSDataView::cast(*view)->Neuter();
-    } else {
-      UNREACHABLE();
-    }
-    view_obj = handle(view->weak_next(), isolate);
-  }
-  array_buffer->Neuter();
-}
-
-
-RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
-  if (!holder->byte_length()->IsUndefined()) {
-    // ArrayBuffer is already initialized; probably a fuzz test.
-    return *holder;
-  }
-  size_t allocated_length = 0;
-  if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewRangeError("invalid_array_buffer_length",
-                               HandleVector<Object>(NULL, 0)));
-  }
-  if (!Runtime::SetupArrayBufferAllocatingData(isolate,
-                                               holder, allocated_length)) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewRangeError("invalid_array_buffer_length",
-                               HandleVector<Object>(NULL, 0)));
-  }
-  return *holder;
-}
-
-
-RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
-  return holder->byte_length();
-}
-
-
-RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
-  RUNTIME_ASSERT(!source.is_identical_to(target));
-  size_t start = 0;
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
-  size_t target_length = NumberToSize(isolate, target->byte_length());
-
-  if (target_length == 0) return isolate->heap()->undefined_value();
-
-  size_t source_byte_length = NumberToSize(isolate, source->byte_length());
-  RUNTIME_ASSERT(start <= source_byte_length);
-  RUNTIME_ASSERT(source_byte_length - start >= target_length);
-  uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
-  uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
-  CopyBytes(target_data, source_data + start, target_length);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, object, 0);
-  return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
-}
-
-
-RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
-  if (array_buffer->backing_store() == NULL) {
-    CHECK(Smi::FromInt(0) == array_buffer->byte_length());
-    return isolate->heap()->undefined_value();
-  }
-  DCHECK(!array_buffer->is_external());
-  void* backing_store = array_buffer->backing_store();
-  size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
-  array_buffer->set_is_external(true);
-  Runtime::NeuterArrayBuffer(array_buffer);
-  V8::ArrayBufferAllocator()->Free(backing_store, byte_length);
-  return isolate->heap()->undefined_value();
-}
-
-
-void Runtime::ArrayIdToTypeAndSize(
-    int arrayId,
-    ExternalArrayType* array_type,
-    ElementsKind* external_elements_kind,
-    ElementsKind* fixed_elements_kind,
-    size_t* element_size) {
-  switch (arrayId) {
-#define ARRAY_ID_CASE(Type, type, TYPE, ctype, size)                           \
-    case ARRAY_ID_##TYPE:                                                      \
-      *array_type = kExternal##Type##Array;                                    \
-      *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS;                    \
-      *fixed_elements_kind = TYPE##_ELEMENTS;                                  \
-      *element_size = size;                                                    \
-      break;
-
-    TYPED_ARRAYS(ARRAY_ID_CASE)
-#undef ARRAY_ID_CASE
-
-    default:
-      UNREACHABLE();
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 5);
-  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
-  CONVERT_SMI_ARG_CHECKED(arrayId, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
-
-  RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
-                 arrayId <= Runtime::ARRAY_ID_LAST);
-
-  ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
-  size_t element_size = 1;  // Bogus initialization.
-  ElementsKind external_elements_kind =
-      EXTERNAL_INT8_ELEMENTS;  // Bogus initialization.
-  ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
-  Runtime::ArrayIdToTypeAndSize(arrayId,
-      &array_type,
-      &external_elements_kind,
-      &fixed_elements_kind,
-      &element_size);
-  RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
-
-  size_t byte_offset = 0;
-  size_t byte_length = 0;
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
-
-  if (maybe_buffer->IsJSArrayBuffer()) {
-    Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
-    size_t array_buffer_byte_length =
-        NumberToSize(isolate, buffer->byte_length());
-    RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
-    RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
-  } else {
-    RUNTIME_ASSERT(maybe_buffer->IsNull());
-  }
-
-  RUNTIME_ASSERT(byte_length % element_size == 0);
-  size_t length = byte_length / element_size;
-
-  if (length > static_cast<unsigned>(Smi::kMaxValue)) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewRangeError("invalid_typed_array_length",
-                               HandleVector<Object>(NULL, 0)));
-  }
-
-  // All checks are done, now we can modify objects.
-
-  DCHECK(holder->GetInternalFieldCount() ==
-      v8::ArrayBufferView::kInternalFieldCount);
-  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
-    holder->SetInternalField(i, Smi::FromInt(0));
-  }
-  Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
-  holder->set_length(*length_obj);
-  holder->set_byte_offset(*byte_offset_object);
-  holder->set_byte_length(*byte_length_object);
-
-  if (!maybe_buffer->IsNull()) {
-    Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
-    holder->set_buffer(*buffer);
-    holder->set_weak_next(buffer->weak_first_view());
-    buffer->set_weak_first_view(*holder);
-
-    Handle<ExternalArray> elements =
-        isolate->factory()->NewExternalArray(
-            static_cast<int>(length), array_type,
-            static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
-    Handle<Map> map =
-        JSObject::GetElementsTransitionMap(holder, external_elements_kind);
-    JSObject::SetMapAndElements(holder, map, elements);
-    DCHECK(IsExternalArrayElementsKind(holder->map()->elements_kind()));
-  } else {
-    holder->set_buffer(Smi::FromInt(0));
-    holder->set_weak_next(isolate->heap()->undefined_value());
-    Handle<FixedTypedArrayBase> elements =
-        isolate->factory()->NewFixedTypedArray(
-            static_cast<int>(length), array_type);
-    holder->set_elements(*elements);
-  }
-  return isolate->heap()->undefined_value();
-}
-
-
-// Initializes a typed array from an array-like object.
-// If an array-like object happens to be a typed array of the same type,
-// initializes backing store using memove.
-//
-// Returns true if backing store was initialized or false otherwise.
-RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
-  CONVERT_SMI_ARG_CHECKED(arrayId, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
-
-  RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
-                 arrayId <= Runtime::ARRAY_ID_LAST);
-
-  ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
-  size_t element_size = 1;  // Bogus initialization.
-  ElementsKind external_elements_kind =
-      EXTERNAL_INT8_ELEMENTS;  // Bogus intialization.
-  ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
-  Runtime::ArrayIdToTypeAndSize(arrayId,
-      &array_type,
-      &external_elements_kind,
-      &fixed_elements_kind,
-      &element_size);
-
-  RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
-
-  Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
-  if (source->IsJSTypedArray() &&
-      JSTypedArray::cast(*source)->type() == array_type) {
-    length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
-  }
-  size_t length = 0;
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
-
-  if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
-      (length > (kMaxInt / element_size))) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewRangeError("invalid_typed_array_length",
-                               HandleVector<Object>(NULL, 0)));
-  }
-  size_t byte_length = length * element_size;
-
-  DCHECK(holder->GetInternalFieldCount() ==
-      v8::ArrayBufferView::kInternalFieldCount);
-  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
-    holder->SetInternalField(i, Smi::FromInt(0));
-  }
-
-  // NOTE: not initializing backing store.
-  // We assume that the caller of this function will initialize holder
-  // with the loop
-  //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
-  // We assume that the caller of this function is always a typed array
-  // constructor.
-  // If source is a typed array, this loop will always run to completion,
-  // so we are sure that the backing store will be initialized.
-  // Otherwise, the indexing operation might throw, so the loop will not
-  // run to completion and the typed array might remain partly initialized.
-  // However we further assume that the caller of this function is a typed array
-  // constructor, and the exception will propagate out of the constructor,
-  // therefore uninitialized memory will not be accessible by a user program.
-  //
-  // TODO(dslomov): revise this once we support subclassing.
-
-  if (!Runtime::SetupArrayBufferAllocatingData(
-        isolate, buffer, byte_length, false)) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewRangeError("invalid_array_buffer_length",
-                               HandleVector<Object>(NULL, 0)));
-  }
-
-  holder->set_buffer(*buffer);
-  holder->set_byte_offset(Smi::FromInt(0));
-  Handle<Object> byte_length_obj(
-      isolate->factory()->NewNumberFromSize(byte_length));
-  holder->set_byte_length(*byte_length_obj);
-  holder->set_length(*length_obj);
-  holder->set_weak_next(buffer->weak_first_view());
-  buffer->set_weak_first_view(*holder);
-
-  Handle<ExternalArray> elements =
-      isolate->factory()->NewExternalArray(
-          static_cast<int>(length), array_type,
-          static_cast<uint8_t*>(buffer->backing_store()));
-  Handle<Map> map = JSObject::GetElementsTransitionMap(
-      holder, external_elements_kind);
-  JSObject::SetMapAndElements(holder, map, elements);
-
-  if (source->IsJSTypedArray()) {
-    Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
-
-    if (typed_array->type() == holder->type()) {
-      uint8_t* backing_store =
-        static_cast<uint8_t*>(
-          typed_array->GetBuffer()->backing_store());
-      size_t source_byte_offset =
-          NumberToSize(isolate, typed_array->byte_offset());
-      memcpy(
-          buffer->backing_store(),
-          backing_store + source_byte_offset,
-          byte_length);
-      return isolate->heap()->true_value();
-    }
-  }
-
-  return isolate->heap()->false_value();
-}
-
-
-#define BUFFER_VIEW_GETTER(Type, getter, accessor) \
-  RUNTIME_FUNCTION(Runtime_##Type##Get##getter) {                    \
-    HandleScope scope(isolate);                                               \
-    DCHECK(args.length() == 1);                                               \
-    CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0);                          \
-    return holder->accessor();                                                \
-  }
-
-BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
-BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
-BUFFER_VIEW_GETTER(TypedArray, Length, length)
-BUFFER_VIEW_GETTER(DataView, Buffer, buffer)
-
-#undef BUFFER_VIEW_GETTER
-
-RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
-  return *holder->GetBuffer();
-}
-
-
-// Return codes for Runtime_TypedArraySetFastCases.
-// Should be synchronized with typedarray.js natives.
-enum TypedArraySetResultCodes {
-  // Set from typed array of the same type.
-  // This is processed by TypedArraySetFastCases
-  TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
-  // Set from typed array of the different type, overlapping in memory.
-  TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
-  // Set from typed array of the different type, non-overlapping.
-  TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
-  // Set from non-typed array.
-  TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
-};
-
-
-RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  if (!args[0]->IsJSTypedArray()) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate,
-        NewTypeError("not_typed_array", HandleVector<Object>(NULL, 0)));
-  }
-
-  if (!args[1]->IsJSTypedArray())
-    return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
-
-  Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
-  Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
-  size_t offset = 0;
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
-  size_t target_length = NumberToSize(isolate, target->length());
-  size_t source_length = NumberToSize(isolate, source->length());
-  size_t target_byte_length = NumberToSize(isolate, target->byte_length());
-  size_t source_byte_length = NumberToSize(isolate, source->byte_length());
-  if (offset > target_length || offset + source_length > target_length ||
-      offset + source_length < offset) {  // overflow
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewRangeError("typed_array_set_source_too_large",
-                               HandleVector<Object>(NULL, 0)));
-  }
-
-  size_t target_offset = NumberToSize(isolate, target->byte_offset());
-  size_t source_offset = NumberToSize(isolate, source->byte_offset());
-  uint8_t* target_base =
-      static_cast<uint8_t*>(
-        target->GetBuffer()->backing_store()) + target_offset;
-  uint8_t* source_base =
-      static_cast<uint8_t*>(
-        source->GetBuffer()->backing_store()) + source_offset;
-
-  // Typed arrays of the same type: use memmove.
-  if (target->type() == source->type()) {
-    memmove(target_base + offset * target->element_size(),
-        source_base, source_byte_length);
-    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
-  }
-
-  // Typed arrays of different types over the same backing store
-  if ((source_base <= target_base &&
-        source_base + source_byte_length > target_base) ||
-      (target_base <= source_base &&
-        target_base + target_byte_length > source_base)) {
-    // We do not support overlapping ArrayBuffers
-    DCHECK(
-      target->GetBuffer()->backing_store() ==
-      source->GetBuffer()->backing_store());
-    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
-  } else {  // Non-overlapping typed arrays
-    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
-  DCHECK(args.length() == 0);
-  DCHECK_OBJECT_SIZE(
-      FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset);
-  return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
-}
-
-
-RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
-
-  DCHECK(holder->GetInternalFieldCount() ==
-      v8::ArrayBufferView::kInternalFieldCount);
-  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
-    holder->SetInternalField(i, Smi::FromInt(0));
-  }
-  size_t buffer_length = 0;
-  size_t offset = 0;
-  size_t length = 0;
-  RUNTIME_ASSERT(
-      TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
-  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
-
-  // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
-  // Entire range [offset, offset + length] must be in bounds.
-  RUNTIME_ASSERT(offset <= buffer_length);
-  RUNTIME_ASSERT(offset + length <= buffer_length);
-  // No overflow.
-  RUNTIME_ASSERT(offset + length >= offset);
-
-  holder->set_buffer(*buffer);
-  holder->set_byte_offset(*byte_offset);
-  holder->set_byte_length(*byte_length);
-
-  holder->set_weak_next(buffer->weak_first_view());
-  buffer->set_weak_first_view(*holder);
-
-  return isolate->heap()->undefined_value();
-}
-
-
-inline static bool NeedToFlipBytes(bool is_little_endian) {
-#ifdef V8_TARGET_LITTLE_ENDIAN
-  return !is_little_endian;
-#else
-  return is_little_endian;
-#endif
-}
-
-
-template<int n>
-inline void CopyBytes(uint8_t* target, uint8_t* source) {
-  for (int i = 0; i < n; i++) {
-    *(target++) = *(source++);
-  }
-}
-
-
-template<int n>
-inline void FlipBytes(uint8_t* target, uint8_t* source) {
-  source = source + (n-1);
-  for (int i = 0; i < n; i++) {
-    *(target++) = *(source--);
-  }
-}
-
-
-template<typename T>
-inline static bool DataViewGetValue(
-    Isolate* isolate,
-    Handle<JSDataView> data_view,
-    Handle<Object> byte_offset_obj,
-    bool is_little_endian,
-    T* result) {
-  size_t byte_offset = 0;
-  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
-    return false;
-  }
-  Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
-
-  size_t data_view_byte_offset =
-      NumberToSize(isolate, data_view->byte_offset());
-  size_t data_view_byte_length =
-      NumberToSize(isolate, data_view->byte_length());
-  if (byte_offset + sizeof(T) > data_view_byte_length ||
-      byte_offset + sizeof(T) < byte_offset)  {  // overflow
-    return false;
-  }
-
-  union Value {
-    T data;
-    uint8_t bytes[sizeof(T)];
-  };
-
-  Value value;
-  size_t buffer_offset = data_view_byte_offset + byte_offset;
-  DCHECK(
-      NumberToSize(isolate, buffer->byte_length())
-      >= buffer_offset + sizeof(T));
-  uint8_t* source =
-        static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
-  if (NeedToFlipBytes(is_little_endian)) {
-    FlipBytes<sizeof(T)>(value.bytes, source);
-  } else {
-    CopyBytes<sizeof(T)>(value.bytes, source);
-  }
-  *result = value.data;
-  return true;
-}
-
-
-template<typename T>
-static bool DataViewSetValue(
-    Isolate* isolate,
-    Handle<JSDataView> data_view,
-    Handle<Object> byte_offset_obj,
-    bool is_little_endian,
-    T data) {
-  size_t byte_offset = 0;
-  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
-    return false;
-  }
-  Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
-
-  size_t data_view_byte_offset =
-      NumberToSize(isolate, data_view->byte_offset());
-  size_t data_view_byte_length =
-      NumberToSize(isolate, data_view->byte_length());
-  if (byte_offset + sizeof(T) > data_view_byte_length ||
-      byte_offset + sizeof(T) < byte_offset)  {  // overflow
-    return false;
-  }
-
-  union Value {
-    T data;
-    uint8_t bytes[sizeof(T)];
-  };
-
-  Value value;
-  value.data = data;
-  size_t buffer_offset = data_view_byte_offset + byte_offset;
-  DCHECK(
-      NumberToSize(isolate, buffer->byte_length())
-      >= buffer_offset + sizeof(T));
-  uint8_t* target =
-        static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
-  if (NeedToFlipBytes(is_little_endian)) {
-    FlipBytes<sizeof(T)>(target, value.bytes);
-  } else {
-    CopyBytes<sizeof(T)>(target, value.bytes);
-  }
-  return true;
-}
-
-
-#define DATA_VIEW_GETTER(TypeName, Type, Converter)                   \
-  RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) {                   \
-    HandleScope scope(isolate);                                       \
-    DCHECK(args.length() == 3);                                       \
-    CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                \
-    CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                     \
-    CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                 \
-    Type result;                                                      \
-    if (DataViewGetValue(isolate, holder, offset, is_little_endian,   \
-                         &result)) {                                  \
-      return *isolate->factory()->Converter(result);                  \
-    } else {                                                          \
-      THROW_NEW_ERROR_RETURN_FAILURE(                                 \
-          isolate, NewRangeError("invalid_data_view_accessor_offset", \
-                                 HandleVector<Object>(NULL, 0)));     \
-    }                                                                 \
-  }
-
-DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
-DATA_VIEW_GETTER(Int8, int8_t, NewNumberFromInt)
-DATA_VIEW_GETTER(Uint16, uint16_t, NewNumberFromUint)
-DATA_VIEW_GETTER(Int16, int16_t, NewNumberFromInt)
-DATA_VIEW_GETTER(Uint32, uint32_t, NewNumberFromUint)
-DATA_VIEW_GETTER(Int32, int32_t, NewNumberFromInt)
-DATA_VIEW_GETTER(Float32, float, NewNumber)
-DATA_VIEW_GETTER(Float64, double, NewNumber)
-
-#undef DATA_VIEW_GETTER
-
-
-template <typename T>
-static T DataViewConvertValue(double value);
-
-
-template <>
-int8_t DataViewConvertValue<int8_t>(double value) {
-  return static_cast<int8_t>(DoubleToInt32(value));
-}
-
-
-template <>
-int16_t DataViewConvertValue<int16_t>(double value) {
-  return static_cast<int16_t>(DoubleToInt32(value));
-}
-
-
-template <>
-int32_t DataViewConvertValue<int32_t>(double value) {
-  return DoubleToInt32(value);
-}
-
-
-template <>
-uint8_t DataViewConvertValue<uint8_t>(double value) {
-  return static_cast<uint8_t>(DoubleToUint32(value));
-}
-
-
-template <>
-uint16_t DataViewConvertValue<uint16_t>(double value) {
-  return static_cast<uint16_t>(DoubleToUint32(value));
-}
-
-
-template <>
-uint32_t DataViewConvertValue<uint32_t>(double value) {
-  return DoubleToUint32(value);
-}
-
-
-template <>
-float DataViewConvertValue<float>(double value) {
-  return static_cast<float>(value);
-}
-
-
-template <>
-double DataViewConvertValue<double>(double value) {
-  return value;
-}
-
-
-#define DATA_VIEW_SETTER(TypeName, Type)                                  \
-  RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) {                       \
-    HandleScope scope(isolate);                                           \
-    DCHECK(args.length() == 4);                                           \
-    CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                    \
-    CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                         \
-    CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);                          \
-    CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                     \
-    Type v = DataViewConvertValue<Type>(value->Number());                 \
-    if (DataViewSetValue(isolate, holder, offset, is_little_endian, v)) { \
-      return isolate->heap()->undefined_value();                          \
-    } else {                                                              \
-      THROW_NEW_ERROR_RETURN_FAILURE(                                     \
-          isolate, NewRangeError("invalid_data_view_accessor_offset",     \
-                                 HandleVector<Object>(NULL, 0)));         \
-    }                                                                     \
-  }
-
-DATA_VIEW_SETTER(Uint8, uint8_t)
-DATA_VIEW_SETTER(Int8, int8_t)
-DATA_VIEW_SETTER(Uint16, uint16_t)
-DATA_VIEW_SETTER(Int16, int16_t)
-DATA_VIEW_SETTER(Uint32, uint32_t)
-DATA_VIEW_SETTER(Int32, int32_t)
-DATA_VIEW_SETTER(Float32, float)
-DATA_VIEW_SETTER(Float64, double)
-
-#undef DATA_VIEW_SETTER
-
-
-RUNTIME_FUNCTION(Runtime_SetInitialize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
-  holder->set_table(*table);
-  return *holder;
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetAdd) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  table = OrderedHashSet::Add(table, key);
-  holder->set_table(*table);
-  return *holder;
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetHas) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  return isolate->heap()->ToBoolean(table->Contains(key));
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetDelete) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  bool was_present = false;
-  table = OrderedHashSet::Remove(table, key, &was_present);
-  holder->set_table(*table);
-  return isolate->heap()->ToBoolean(was_present);
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetClear) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  table = OrderedHashSet::Clear(table);
-  holder->set_table(*table);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetGetSize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
-  return Smi::FromInt(table->NumberOfElements());
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
-  CONVERT_SMI_ARG_CHECKED(kind, 2)
-  RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
-                 kind == JSSetIterator::kKindEntries);
-  Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
-  holder->set_table(*table);
-  holder->set_index(Smi::FromInt(0));
-  holder->set_kind(Smi::FromInt(kind));
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(JSSetIterator, holder, 0);
-  CONVERT_ARG_CHECKED(JSArray, value_array, 1);
-  return holder->Next(value_array);
-}
-
-
-RUNTIME_FUNCTION(Runtime_MapInitialize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
-  holder->set_table(*table);
-  return *holder;
-}
-
-
-RUNTIME_FUNCTION(Runtime_MapGet) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  Handle<Object> lookup(table->Lookup(key), isolate);
-  return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
-}
-
-
-RUNTIME_FUNCTION(Runtime_MapHas) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  Handle<Object> lookup(table->Lookup(key), isolate);
-  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
-}
-
-
-RUNTIME_FUNCTION(Runtime_MapDelete) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  bool was_present = false;
-  Handle<OrderedHashMap> new_table =
-      OrderedHashMap::Remove(table, key, &was_present);
-  holder->set_table(*new_table);
-  return isolate->heap()->ToBoolean(was_present);
-}
-
-
-RUNTIME_FUNCTION(Runtime_MapClear) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  table = OrderedHashMap::Clear(table);
-  holder->set_table(*table);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_MapSet) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
-  holder->set_table(*new_table);
-  return *holder;
-}
-
-
-RUNTIME_FUNCTION(Runtime_MapGetSize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
-  return Smi::FromInt(table->NumberOfElements());
-}
-
-
-RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
-  CONVERT_SMI_ARG_CHECKED(kind, 2)
-  RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys
-      || kind == JSMapIterator::kKindValues
-      || kind == JSMapIterator::kKindEntries);
-  Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
-  holder->set_table(*table);
-  holder->set_index(Smi::FromInt(0));
-  holder->set_kind(Smi::FromInt(kind));
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
-  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
-  Handle<FixedArray> entries =
-      isolate->factory()->NewFixedArray(table->NumberOfElements() * 2);
-  {
-    DisallowHeapAllocation no_gc;
-    int number_of_non_hole_elements = 0;
-    for (int i = 0; i < table->Capacity(); i++) {
-      Handle<Object> key(table->KeyAt(i), isolate);
-      if (table->IsKey(*key)) {
-        entries->set(number_of_non_hole_elements++, *key);
-        Object* value = table->Lookup(key);
-        entries->set(number_of_non_hole_elements++, value);
-      }
-    }
-    DCHECK_EQ(table->NumberOfElements() * 2, number_of_non_hole_elements);
-  }
-  return *isolate->factory()->NewJSArrayWithElements(entries);
-}
-
-
-RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(JSMapIterator, holder, 0);
-  CONVERT_ARG_CHECKED(JSArray, value_array, 1);
-  return holder->Next(value_array);
-}
-
-
-static Handle<JSWeakCollection> WeakCollectionInitialize(
-    Isolate* isolate,
-    Handle<JSWeakCollection> weak_collection) {
-  DCHECK(weak_collection->map()->inobject_properties() == 0);
-  Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
-  weak_collection->set_table(*table);
-  return weak_collection;
-}
-
-
-RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
-  return *WeakCollectionInitialize(isolate, weak_collection);
-}
-
-
-RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
-  Handle<ObjectHashTable> table(
-      ObjectHashTable::cast(weak_collection->table()));
-  RUNTIME_ASSERT(table->IsKey(*key));
-  Handle<Object> lookup(table->Lookup(key), isolate);
-  return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
-}
-
-
-RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
-  Handle<ObjectHashTable> table(
-      ObjectHashTable::cast(weak_collection->table()));
-  RUNTIME_ASSERT(table->IsKey(*key));
-  Handle<Object> lookup(table->Lookup(key), isolate);
-  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
-}
-
-
-RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
-  Handle<ObjectHashTable> table(ObjectHashTable::cast(
-      weak_collection->table()));
-  RUNTIME_ASSERT(table->IsKey(*key));
-  bool was_present = false;
-  Handle<ObjectHashTable> new_table =
-      ObjectHashTable::Remove(table, key, &was_present);
-  weak_collection->set_table(*new_table);
-  return isolate->heap()->ToBoolean(was_present);
-}
-
-
-RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  Handle<ObjectHashTable> table(
-      ObjectHashTable::cast(weak_collection->table()));
-  RUNTIME_ASSERT(table->IsKey(*key));
-  Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
-  weak_collection->set_table(*new_table);
-  return *weak_collection;
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetWeakSetValues) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
-  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
-  Handle<FixedArray> values =
-      isolate->factory()->NewFixedArray(table->NumberOfElements());
-  {
-    DisallowHeapAllocation no_gc;
-    int number_of_non_hole_elements = 0;
-    for (int i = 0; i < table->Capacity(); i++) {
-      Handle<Object> key(table->KeyAt(i), isolate);
-      if (table->IsKey(*key)) {
-        values->set(number_of_non_hole_elements++, *key);
-      }
-    }
-    DCHECK_EQ(table->NumberOfElements(), number_of_non_hole_elements);
-  }
-  return *isolate->factory()->NewJSArrayWithElements(values);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetPrototype) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
-  // We don't expect access checks to be needed on JSProxy objects.
-  DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
-  PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
-  do {
-    if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
-        !isolate->MayNamedAccess(
-            Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
-            isolate->factory()->proto_string(), v8::ACCESS_GET)) {
-      isolate->ReportFailedAccessCheck(
-          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
-          v8::ACCESS_GET);
-      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-      return isolate->heap()->undefined_value();
-    }
-    iter.AdvanceIgnoringProxies();
-    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
-      return *PrototypeIterator::GetCurrent(iter);
-    }
-  } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
-  return *PrototypeIterator::GetCurrent(iter);
-}
-
-
-static inline Handle<Object> GetPrototypeSkipHiddenPrototypes(
-    Isolate* isolate, Handle<Object> receiver) {
-  PrototypeIterator iter(isolate, receiver);
-  while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
-    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
-      return PrototypeIterator::GetCurrent(iter);
-    }
-    iter.Advance();
-  }
-  return PrototypeIterator::GetCurrent(iter);
-}
-
-
-RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
-  DCHECK(!obj->IsAccessCheckNeeded());
-  DCHECK(!obj->map()->is_observed());
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, JSObject::SetPrototype(obj, prototype, false));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetPrototype) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
-  if (obj->IsAccessCheckNeeded() &&
-      !isolate->MayNamedAccess(
-          obj, isolate->factory()->proto_string(), v8::ACCESS_SET)) {
-    isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
-    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-    return isolate->heap()->undefined_value();
-  }
-  if (obj->map()->is_observed()) {
-    Handle<Object> old_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
-    Handle<Object> result;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, result,
-        JSObject::SetPrototype(obj, prototype, true));
-
-    Handle<Object> new_value = GetPrototypeSkipHiddenPrototypes(isolate, obj);
-    if (!new_value->SameValue(*old_value)) {
-      JSObject::EnqueueChangeRecord(obj, "setPrototype",
-                                    isolate->factory()->proto_string(),
-                                    old_value);
-    }
-    return *result;
-  }
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      JSObject::SetPrototype(obj, prototype, true));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
-  HandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
-  CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
-  PrototypeIterator iter(isolate, V, PrototypeIterator::START_AT_RECEIVER);
-  while (true) {
-    iter.AdvanceIgnoringProxies();
-    if (iter.IsAtEnd()) return isolate->heap()->false_value();
-    if (iter.IsAtEnd(O)) return isolate->heap()->true_value();
-  }
-}
-
-
-// Enumerator used as indices into the array returned from GetOwnProperty
-enum PropertyDescriptorIndices {
-  IS_ACCESSOR_INDEX,
-  VALUE_INDEX,
-  GETTER_INDEX,
-  SETTER_INDEX,
-  WRITABLE_INDEX,
-  ENUMERABLE_INDEX,
-  CONFIGURABLE_INDEX,
-  DESCRIPTOR_SIZE
-};
-
-
-MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
-                                                          Handle<JSObject> obj,
-                                                          Handle<Name> name) {
-  Heap* heap = isolate->heap();
-  Factory* factory = isolate->factory();
-
-  PropertyAttributes attrs;
-  uint32_t index = 0;
-  Handle<Object> value;
-  MaybeHandle<AccessorPair> maybe_accessors;
-  // TODO(verwaest): Unify once indexed properties can be handled by the
-  // LookupIterator.
-  if (name->AsArrayIndex(&index)) {
-    // Get attributes.
-    Maybe<PropertyAttributes> maybe =
-        JSReceiver::GetOwnElementAttribute(obj, index);
-    if (!maybe.has_value) return MaybeHandle<Object>();
-    attrs = maybe.value;
-    if (attrs == ABSENT) return factory->undefined_value();
-
-    // Get AccessorPair if present.
-    maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index);
-
-    // Get value if not an AccessorPair.
-    if (maybe_accessors.is_null()) {
-      ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
-          Runtime::GetElementOrCharAt(isolate, obj, index), Object);
-    }
-  } else {
-    // Get attributes.
-    LookupIterator it(obj, name, LookupIterator::HIDDEN);
-    Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
-    if (!maybe.has_value) return MaybeHandle<Object>();
-    attrs = maybe.value;
-    if (attrs == ABSENT) return factory->undefined_value();
-
-    // Get AccessorPair if present.
-    if (it.state() == LookupIterator::ACCESSOR &&
-        it.GetAccessors()->IsAccessorPair()) {
-      maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors());
-    }
-
-    // Get value if not an AccessorPair.
-    if (maybe_accessors.is_null()) {
-      ASSIGN_RETURN_ON_EXCEPTION(
-          isolate, value, Object::GetProperty(&it), Object);
-    }
-  }
-  DCHECK(!isolate->has_pending_exception());
-  Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
-  elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
-  elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
-  elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null()));
-
-  Handle<AccessorPair> accessors;
-  if (maybe_accessors.ToHandle(&accessors)) {
-    Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
-    Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
-    elms->set(GETTER_INDEX, *getter);
-    elms->set(SETTER_INDEX, *setter);
-  } else {
-    elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
-    elms->set(VALUE_INDEX, *value);
-  }
-
-  return factory->NewJSArrayWithElements(elms);
-}
-
-
-// Returns an array with the property description:
-//  if args[1] is not a property on args[0]
-//          returns undefined
-//  if args[1] is a data property on args[0]
-//         [false, value, Writeable, Enumerable, Configurable]
-//  if args[1] is an accessor on args[0]
-//         [true, GetFunction, SetFunction, Enumerable, Configurable]
-RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, GetOwnProperty(isolate, obj, name));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_PreventExtensions) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, JSObject::PreventExtensions(obj));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_ToMethod) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
-  Handle<JSFunction> clone = JSFunction::CloneClosure(fun);
-  Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol());
-  JSObject::SetOwnPropertyIgnoreAttributes(clone, home_object_symbol,
-                                           home_object, DONT_ENUM).Assert();
-  return *clone;
-}
-
-
-RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
-  DCHECK(args.length() == 0);
-  return isolate->heap()->home_object_symbol();
-}
-
-
-RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
-
-  if (home_object->IsAccessCheckNeeded() &&
-      !isolate->MayNamedAccess(home_object, name, v8::ACCESS_GET)) {
-    isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_GET);
-    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-  }
-
-  PrototypeIterator iter(isolate, home_object);
-  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
-  if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
-
-  LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsExtensible) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSObject, obj, 0);
-  if (obj->IsJSGlobalProxy()) {
-    PrototypeIterator iter(isolate, obj);
-    if (iter.IsAtEnd()) return isolate->heap()->false_value();
-    DCHECK(iter.GetCurrent()->IsJSGlobalObject());
-    obj = JSObject::cast(iter.GetCurrent());
-  }
-  return isolate->heap()->ToBoolean(obj->map()->is_extensible());
-}
-
-
-RUNTIME_FUNCTION(Runtime_RegExpCompile) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, re, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, flags, 2);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, RegExpImpl::Compile(re, pattern, flags));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
-  return *isolate->factory()->CreateApiFunction(data, prototype);
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsTemplate) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
-  bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
-  return isolate->heap()->ToBoolean(result);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetTemplateField) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(HeapObject, templ, 0);
-  CONVERT_SMI_ARG_CHECKED(index, 1);
-  int offset = index * kPointerSize + HeapObject::kHeaderSize;
-  InstanceType type = templ->map()->instance_type();
-  RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
-                 type == OBJECT_TEMPLATE_INFO_TYPE);
-  RUNTIME_ASSERT(offset > 0);
-  if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
-    RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
-  } else {
-    RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
-  }
-  return *HeapObject::RawField(templ, offset);
-}
-
-
-RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
-  Handle<Map> old_map(object->map());
-  bool needs_access_checks = old_map->is_access_check_needed();
-  if (needs_access_checks) {
-    // Copy map so it won't interfere constructor's initial map.
-    Handle<Map> new_map = Map::Copy(old_map);
-    new_map->set_is_access_check_needed(false);
-    JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
-  }
-  return isolate->heap()->ToBoolean(needs_access_checks);
-}
-
-
-RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  Handle<Map> old_map(object->map());
-  RUNTIME_ASSERT(!old_map->is_access_check_needed());
-  // Copy map so it won't interfere constructor's initial map.
-  Handle<Map> new_map = Map::Copy(old_map);
-  new_map->set_is_access_check_needed(true);
-  JSObject::MigrateToMap(object, new_map);
-  return isolate->heap()->undefined_value();
-}
-
-
-static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
-  HandleScope scope(isolate);
-  Handle<Object> args[1] = { name };
-  THROW_NEW_ERROR_RETURN_FAILURE(
-      isolate, NewTypeError("var_redeclaration", HandleVector(args, 1)));
-}
-
-
-// May throw a RedeclarationError.
-static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global,
-                              Handle<String> name, Handle<Object> value,
-                              PropertyAttributes attr, bool is_var,
-                              bool is_const, bool is_function) {
-  // Do the lookup own properties only, see ES5 erratum.
-  LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
-  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
-  if (!maybe.has_value) return isolate->heap()->exception();
-
-  if (it.IsFound()) {
-    PropertyAttributes old_attributes = maybe.value;
-    // The name was declared before; check for conflicting re-declarations.
-    if (is_const) return ThrowRedeclarationError(isolate, name);
-
-    // Skip var re-declarations.
-    if (is_var) return isolate->heap()->undefined_value();
-
-    DCHECK(is_function);
-    if ((old_attributes & DONT_DELETE) != 0) {
-      // Only allow reconfiguring globals to functions in user code (no
-      // natives, which are marked as read-only).
-      DCHECK((attr & READ_ONLY) == 0);
-
-      // Check whether we can reconfigure the existing property into a
-      // function.
-      PropertyDetails old_details = it.property_details();
-      // TODO(verwaest): CALLBACKS invalidly includes ExecutableAccessInfo,
-      // which are actually data properties, not accessor properties.
-      if (old_details.IsReadOnly() || old_details.IsDontEnum() ||
-          old_details.type() == CALLBACKS) {
-        return ThrowRedeclarationError(isolate, name);
-      }
-      // If the existing property is not configurable, keep its attributes. Do
-      attr = old_attributes;
-    }
-  }
-
-  // Define or redefine own property.
-  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
-                                           global, name, value, attr));
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  Handle<GlobalObject> global(isolate->global_object());
-
-  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
-  CONVERT_SMI_ARG_CHECKED(flags, 2);
-
-  // Traverse the name/value pairs and set the properties.
-  int length = pairs->length();
-  for (int i = 0; i < length; i += 2) {
-    HandleScope scope(isolate);
-    Handle<String> name(String::cast(pairs->get(i)));
-    Handle<Object> initial_value(pairs->get(i + 1), isolate);
-
-    // We have to declare a global const property. To capture we only
-    // assign to it when evaluating the assignment for "const x =
-    // <expr>" the initial value is the hole.
-    bool is_var = initial_value->IsUndefined();
-    bool is_const = initial_value->IsTheHole();
-    bool is_function = initial_value->IsSharedFunctionInfo();
-    DCHECK(is_var + is_const + is_function == 1);
-
-    Handle<Object> value;
-    if (is_function) {
-      // Copy the function and update its context. Use it as value.
-      Handle<SharedFunctionInfo> shared =
-          Handle<SharedFunctionInfo>::cast(initial_value);
-      Handle<JSFunction> function =
-          isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
-                                                                TENURED);
-      value = function;
-    } else {
-      value = isolate->factory()->undefined_value();
-    }
-
-    // Compute the property attributes. According to ECMA-262,
-    // the property must be non-configurable except in eval.
-    bool is_native = DeclareGlobalsNativeFlag::decode(flags);
-    bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
-    int attr = NONE;
-    if (is_const) attr |= READ_ONLY;
-    if (is_function && is_native) attr |= READ_ONLY;
-    if (!is_const && !is_eval) attr |= DONT_DELETE;
-
-    Object* result = DeclareGlobals(isolate, global, name, value,
-                                    static_cast<PropertyAttributes>(attr),
-                                    is_var, is_const, is_function);
-    if (isolate->has_pending_exception()) return result;
-  }
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
-  HandleScope scope(isolate);
-  // args[0] == name
-  // args[1] == language_mode
-  // args[2] == value (optional)
-
-  // Determine if we need to assign to the variable if it already
-  // exists (based on the number of arguments).
-  RUNTIME_ASSERT(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
-  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-
-  Handle<GlobalObject> global(isolate->context()->global_object());
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, Object::SetProperty(global, name, value, strict_mode));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) {
-  HandleScope handle_scope(isolate);
-  // All constants are declared with an initial value. The name
-  // of the constant is the first argument and the initial value
-  // is the second.
-  RUNTIME_ASSERT(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
-
-  Handle<GlobalObject> global = isolate->global_object();
-
-  // Lookup the property as own on the global object.
-  LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
-  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
-  DCHECK(maybe.has_value);
-  PropertyAttributes old_attributes = maybe.value;
-
-  PropertyAttributes attr =
-      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
-  // Set the value if the property is either missing, or the property attributes
-  // allow setting the value without invoking an accessor.
-  if (it.IsFound()) {
-    // Ignore if we can't reconfigure the value.
-    if ((old_attributes & DONT_DELETE) != 0) {
-      if ((old_attributes & READ_ONLY) != 0 ||
-          it.state() == LookupIterator::ACCESSOR) {
-        return *value;
-      }
-      attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
-    }
-  }
-
-  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
-                                           global, name, value, attr));
-
-  return *value;
-}
-
-
-RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-
-  // Declarations are always made in a function, native, or global context. In
-  // the case of eval code, the context passed is the context of the caller,
-  // which may be some nested context and not the declaration context.
-  CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
-  Handle<Context> context(context_arg->declaration_context());
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
-  CONVERT_SMI_ARG_CHECKED(attr_arg, 2);
-  PropertyAttributes attr = static_cast<PropertyAttributes>(attr_arg);
-  RUNTIME_ASSERT(attr == READ_ONLY || attr == NONE);
-  CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
-
-  // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals.
-  bool is_var = *initial_value == NULL;
-  bool is_const = initial_value->IsTheHole();
-  bool is_function = initial_value->IsJSFunction();
-  DCHECK(is_var + is_const + is_function == 1);
-
-  int index;
-  PropertyAttributes attributes;
-  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
-  BindingFlags binding_flags;
-  Handle<Object> holder =
-      context->Lookup(name, flags, &index, &attributes, &binding_flags);
-
-  Handle<JSObject> object;
-  Handle<Object> value =
-      is_function ? initial_value
-                  : Handle<Object>::cast(isolate->factory()->undefined_value());
-
-  // TODO(verwaest): This case should probably not be covered by this function,
-  // but by DeclareGlobals instead.
-  if ((attributes != ABSENT && holder->IsJSGlobalObject()) ||
-      (context_arg->has_extension() &&
-       context_arg->extension()->IsJSGlobalObject())) {
-    return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name,
-                          value, attr, is_var, is_const, is_function);
-  }
-
-  if (attributes != ABSENT) {
-    // The name was declared before; check for conflicting re-declarations.
-    if (is_const || (attributes & READ_ONLY) != 0) {
-      return ThrowRedeclarationError(isolate, name);
-    }
-
-    // Skip var re-declarations.
-    if (is_var) return isolate->heap()->undefined_value();
-
-    DCHECK(is_function);
-    if (index >= 0) {
-      DCHECK(holder.is_identical_to(context));
-      context->set(index, *initial_value);
-      return isolate->heap()->undefined_value();
-    }
-
-    object = Handle<JSObject>::cast(holder);
-
-  } else if (context->has_extension()) {
-    object = handle(JSObject::cast(context->extension()));
-    DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject());
-  } else {
-    DCHECK(context->IsFunctionContext());
-    object =
-        isolate->factory()->NewJSObject(isolate->context_extension_function());
-    context->set_extension(*object);
-  }
-
-  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
-                                           object, name, value, attr));
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
-  DCHECK(!value->IsTheHole());
-  // Initializations are always done in a function or native context.
-  CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
-  Handle<Context> context(context_arg->declaration_context());
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
-
-  int index;
-  PropertyAttributes attributes;
-  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
-  BindingFlags binding_flags;
-  Handle<Object> holder =
-      context->Lookup(name, flags, &index, &attributes, &binding_flags);
-
-  if (index >= 0) {
-    DCHECK(holder->IsContext());
-    // Property was found in a context.  Perform the assignment if the constant
-    // was uninitialized.
-    Handle<Context> context = Handle<Context>::cast(holder);
-    DCHECK((attributes & READ_ONLY) != 0);
-    if (context->get(index)->IsTheHole()) context->set(index, *value);
-    return *value;
-  }
-
-  PropertyAttributes attr =
-      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
-
-  // Strict mode handling not needed (legacy const is disallowed in strict
-  // mode).
-
-  // The declared const was configurable, and may have been deleted in the
-  // meanwhile. If so, re-introduce the variable in the context extension.
-  DCHECK(context_arg->has_extension());
-  if (attributes == ABSENT) {
-    holder = handle(context_arg->extension(), isolate);
-  } else {
-    // For JSContextExtensionObjects, the initializer can be run multiple times
-    // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the
-    // first assignment should go through. For JSGlobalObjects, additionally any
-    // code can run in between that modifies the declared property.
-    DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
-
-    LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
-    Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
-    if (!maybe.has_value) return isolate->heap()->exception();
-    PropertyAttributes old_attributes = maybe.value;
-
-    // Ignore if we can't reconfigure the value.
-    if ((old_attributes & DONT_DELETE) != 0) {
-      if ((old_attributes & READ_ONLY) != 0 ||
-          it.state() == LookupIterator::ACCESSOR) {
-        return *value;
-      }
-      attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
-    }
-  }
-
-  RETURN_FAILURE_ON_EXCEPTION(
-      isolate, JSObject::SetOwnPropertyIgnoreAttributes(
-                   Handle<JSObject>::cast(holder), name, value, attr));
-
-  return *value;
-}
-
-
-RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_SMI_ARG_CHECKED(properties, 1);
-  // Conservative upper limit to prevent fuzz tests from going OOM.
-  RUNTIME_ASSERT(properties <= 100000);
-  if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
-    JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
-  }
-  return *object;
-}
-
-
-RUNTIME_FUNCTION(Runtime_RegExpExecRT) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
-  CONVERT_INT32_ARG_CHECKED(index, 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
-  // Due to the way the JS calls are constructed this must be less than the
-  // length of a string, i.e. it is always a Smi.  We check anyway for security.
-  RUNTIME_ASSERT(index >= 0);
-  RUNTIME_ASSERT(index <= subject->length());
-  isolate->counters()->regexp_entry_runtime()->Increment();
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      RegExpImpl::Exec(regexp, subject, index, last_match_info));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_RegExpConstructResult) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_SMI_ARG_CHECKED(size, 0);
-  RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength);
-  CONVERT_ARG_HANDLE_CHECKED(Object, index, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, input, 2);
-  Handle<FixedArray> elements =  isolate->factory()->NewFixedArray(size);
-  Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
-  Handle<JSObject> object =
-      isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED, false);
-  Handle<JSArray> array = Handle<JSArray>::cast(object);
-  array->set_elements(*elements);
-  array->set_length(Smi::FromInt(size));
-  // Write in-object properties after the length of the array.
-  array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index);
-  array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
-  return *array;
-}
-
-
-RUNTIME_FUNCTION(Runtime_RegExpInitializeObject) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 6);
-  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
-  CONVERT_ARG_HANDLE_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->factory()->query_colon_string();
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, global, 2);
-  if (!global->IsTrue()) global = isolate->factory()->false_value();
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, ignoreCase, 3);
-  if (!ignoreCase->IsTrue()) ignoreCase = isolate->factory()->false_value();
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, multiline, 4);
-  if (!multiline->IsTrue()) multiline = isolate->factory()->false_value();
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, sticky, 5);
-  if (!sticky->IsTrue()) sticky = isolate->factory()->false_value();
-
-  Map* map = regexp->map();
-  Object* constructor = map->constructor();
-  if (!FLAG_harmony_regexps &&
-      constructor->IsJSFunction() &&
-      JSFunction::cast(constructor)->initial_map() == map) {
-    // If we still have the original map, set in-object properties directly.
-    regexp->InObjectPropertyAtPut(JSRegExp::kSourceFieldIndex, *source);
-    // Both true and false are immovable immortal objects so no need for write
-    // barrier.
-    regexp->InObjectPropertyAtPut(
-        JSRegExp::kGlobalFieldIndex, *global, SKIP_WRITE_BARRIER);
-    regexp->InObjectPropertyAtPut(
-        JSRegExp::kIgnoreCaseFieldIndex, *ignoreCase, SKIP_WRITE_BARRIER);
-    regexp->InObjectPropertyAtPut(
-        JSRegExp::kMultilineFieldIndex, *multiline, SKIP_WRITE_BARRIER);
-    regexp->InObjectPropertyAtPut(
-        JSRegExp::kLastIndexFieldIndex, Smi::FromInt(0), SKIP_WRITE_BARRIER);
-    return *regexp;
-  }
-
-  // Map has changed, so use generic, but slower, method.  We also end here if
-  // the --harmony-regexp flag is set, because the initial map does not have
-  // space for the 'sticky' flag, since it is from the snapshot, but must work
-  // both with and without --harmony-regexp.  When sticky comes out from under
-  // the flag, we will be able to use the fast initial map.
-  PropertyAttributes final =
-      static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
-  PropertyAttributes writable =
-      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
-  Handle<Object> zero(Smi::FromInt(0), isolate);
-  Factory* factory = isolate->factory();
-  JSObject::SetOwnPropertyIgnoreAttributes(
-      regexp, factory->source_string(), source, final).Check();
-  JSObject::SetOwnPropertyIgnoreAttributes(
-      regexp, factory->global_string(), global, final).Check();
-  JSObject::SetOwnPropertyIgnoreAttributes(
-      regexp, factory->ignore_case_string(), ignoreCase, final).Check();
-  JSObject::SetOwnPropertyIgnoreAttributes(
-      regexp, factory->multiline_string(), multiline, final).Check();
-  if (FLAG_harmony_regexps) {
-    JSObject::SetOwnPropertyIgnoreAttributes(
-        regexp, factory->sticky_string(), sticky, final).Check();
-  }
-  JSObject::SetOwnPropertyIgnoreAttributes(
-      regexp, factory->last_index_string(), zero, writable).Check();
-  return *regexp;
-}
-
-
-RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
-  Object* length = prototype->length();
-  RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0);
-  RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements());
-  // This is necessary to enable fast checks for absence of elements
-  // on Array.prototype and below.
-  prototype->set_elements(isolate->heap()->empty_fixed_array());
-  return Smi::FromInt(0);
-}
-
-
-static void InstallBuiltin(Isolate* isolate,
-                           Handle<JSObject> holder,
-                           const char* name,
-                           Builtins::Name builtin_name) {
-  Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
-  Handle<Code> code(isolate->builtins()->builtin(builtin_name));
-  Handle<JSFunction> optimized =
-      isolate->factory()->NewFunctionWithoutPrototype(key, code);
-  optimized->shared()->DontAdaptArguments();
-  JSObject::AddProperty(holder, key, optimized, NONE);
-}
-
-
-RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  Handle<JSObject> holder =
-      isolate->factory()->NewJSObject(isolate->object_function());
-
-  InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
-  InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
-  InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
-  InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
-  InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
-  InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
-  InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
-
-  return *holder;
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
-  if (!callable->IsJSFunction()) {
-    HandleScope scope(isolate);
-    Handle<Object> delegate;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, delegate,
-        Execution::TryGetFunctionDelegate(
-            isolate, Handle<JSReceiver>(callable)));
-    callable = JSFunction::cast(*delegate);
-  }
-  JSFunction* function = JSFunction::cast(callable);
-  SharedFunctionInfo* shared = function->shared();
-  return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
-
-  if (!callable->IsJSFunction()) {
-    HandleScope scope(isolate);
-    Handle<Object> delegate;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, delegate,
-        Execution::TryGetFunctionDelegate(
-            isolate, Handle<JSReceiver>(callable)));
-    callable = JSFunction::cast(*delegate);
-  }
-  JSFunction* function = JSFunction::cast(callable);
-
-  SharedFunctionInfo* shared = function->shared();
-  if (shared->native() || shared->strict_mode() == STRICT) {
-    return isolate->heap()->undefined_value();
-  }
-  // Returns undefined for strict or native functions, or
-  // the associated global receiver for "normal" functions.
-
-  return function->global_proxy();
-}
-
-
-RUNTIME_FUNCTION(Runtime_MaterializeRegExpLiteral) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
-  CONVERT_SMI_ARG_CHECKED(index, 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
-  CONVERT_ARG_HANDLE_CHECKED(String, flags, 3);
-
-  // Get the RegExp function from the context in the literals array.
-  // This is the RegExp function from the context in which the
-  // function was created.  We do not use the RegExp function from the
-  // current native context because this might be the RegExp function
-  // from another context which we should not have access to.
-  Handle<JSFunction> constructor =
-      Handle<JSFunction>(
-          JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
-  // Compute the regular expression literal.
-  Handle<Object> regexp;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, regexp,
-      RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags));
-  literals->set(index, *regexp);
-  return *regexp;
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionGetName) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return f->shared()->name();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionSetName) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  CONVERT_ARG_CHECKED(String, name, 1);
-  f->shared()->set_name(name);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return isolate->heap()->ToBoolean(
-      f->shared()->name_should_print_as_anonymous());
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  f->shared()->set_name_should_print_as_anonymous(true);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return isolate->heap()->ToBoolean(f->shared()->is_generator());
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionIsArrow) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return isolate->heap()->ToBoolean(f->shared()->is_arrow());
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionIsConciseMethod) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return isolate->heap()->ToBoolean(f->shared()->is_concise_method());
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  RUNTIME_ASSERT(f->RemovePrototype());
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
-  Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
-  if (!script->IsScript()) return isolate->heap()->undefined_value();
-
-  return *Script::GetWrapper(Handle<Script>::cast(script));
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
-  Handle<SharedFunctionInfo> shared(f->shared());
-  return *shared->GetSourceCode();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
-  int pos = fun->shared()->start_position();
-  return Smi::FromInt(pos);
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_CHECKED(Code, code, 0);
-  CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
-
-  RUNTIME_ASSERT(0 <= offset && offset < code->Size());
-
-  Address pc = code->address() + offset;
-  return Smi::FromInt(code->SourcePosition(pc));
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
-  CONVERT_ARG_CHECKED(String, name, 1);
-  fun->SetInstanceClassName(name);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
-  CONVERT_SMI_ARG_CHECKED(length, 1);
-  RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 ||
-                 (length & 0xC0000000) == 0x0);
-  fun->shared()->set_length(length);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
-  RUNTIME_ASSERT(fun->should_have_prototype());
-  Accessors::FunctionSetPrototype(fun, value);
-  return args[0];  // return TOS
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return isolate->heap()->ToBoolean(f->IsBuiltin());
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetCode) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
-
-  Handle<SharedFunctionInfo> target_shared(target->shared());
-  Handle<SharedFunctionInfo> source_shared(source->shared());
-  RUNTIME_ASSERT(!source_shared->bound());
-
-  if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) {
-    return isolate->heap()->exception();
-  }
-
-  // Mark both, the source and the target, as un-flushable because the
-  // shared unoptimized code makes them impossible to enqueue in a list.
-  DCHECK(target_shared->code()->gc_metadata() == NULL);
-  DCHECK(source_shared->code()->gc_metadata() == NULL);
-  target_shared->set_dont_flush(true);
-  source_shared->set_dont_flush(true);
-
-  // Set the code, scope info, formal parameter count, and the length
-  // of the target shared function info.
-  target_shared->ReplaceCode(source_shared->code());
-  target_shared->set_scope_info(source_shared->scope_info());
-  target_shared->set_length(source_shared->length());
-  target_shared->set_feedback_vector(source_shared->feedback_vector());
-  target_shared->set_formal_parameter_count(
-      source_shared->formal_parameter_count());
-  target_shared->set_script(source_shared->script());
-  target_shared->set_start_position_and_type(
-      source_shared->start_position_and_type());
-  target_shared->set_end_position(source_shared->end_position());
-  bool was_native = target_shared->native();
-  target_shared->set_compiler_hints(source_shared->compiler_hints());
-  target_shared->set_native(was_native);
-  target_shared->set_profiler_ticks(source_shared->profiler_ticks());
-
-  // Set the code of the target function.
-  target->ReplaceCode(source_shared->code());
-  DCHECK(target->next_function_link()->IsUndefined());
-
-  // Make sure we get a fresh copy of the literal vector to avoid cross
-  // context contamination.
-  Handle<Context> context(source->context());
-  int number_of_literals = source->NumberOfLiterals();
-  Handle<FixedArray> literals =
-      isolate->factory()->NewFixedArray(number_of_literals, TENURED);
-  if (number_of_literals > 0) {
-    literals->set(JSFunction::kLiteralNativeContextIndex,
-                  context->native_context());
-  }
-  target->set_context(*context);
-  target->set_literals(*literals);
-
-  if (isolate->logger()->is_logging_code_events() ||
-      isolate->cpu_profiler()->is_profiling()) {
-    isolate->logger()->LogExistingFunction(
-        source_shared, Handle<Code>(source_shared->code()));
-  }
-
-  return *target;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-
-  JavaScriptFrameIterator it(isolate);
-  JavaScriptFrame* frame = it.frame();
-  Handle<JSFunction> function(frame->function());
-  RUNTIME_ASSERT(function->shared()->is_generator());
-
-  Handle<JSGeneratorObject> generator;
-  if (frame->IsConstructor()) {
-    generator = handle(JSGeneratorObject::cast(frame->receiver()));
-  } else {
-    generator = isolate->factory()->NewJSGeneratorObject(function);
-  }
-  generator->set_function(*function);
-  generator->set_context(Context::cast(frame->context()));
-  generator->set_receiver(frame->receiver());
-  generator->set_continuation(0);
-  generator->set_operand_stack(isolate->heap()->empty_fixed_array());
-  generator->set_stack_handler_index(-1);
-
-  return *generator;
-}
-
-
-RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
-
-  JavaScriptFrameIterator stack_iterator(isolate);
-  JavaScriptFrame* frame = stack_iterator.frame();
-  RUNTIME_ASSERT(frame->function()->shared()->is_generator());
-  DCHECK_EQ(frame->function(), generator_object->function());
-
-  // The caller should have saved the context and continuation already.
-  DCHECK_EQ(generator_object->context(), Context::cast(frame->context()));
-  DCHECK_LT(0, generator_object->continuation());
-
-  // We expect there to be at least two values on the operand stack: the return
-  // value of the yield expression, and the argument to this runtime call.
-  // Neither of those should be saved.
-  int operands_count = frame->ComputeOperandsCount();
-  DCHECK_GE(operands_count, 2);
-  operands_count -= 2;
-
-  if (operands_count == 0) {
-    // Although it's semantically harmless to call this function with an
-    // operands_count of zero, it is also unnecessary.
-    DCHECK_EQ(generator_object->operand_stack(),
-              isolate->heap()->empty_fixed_array());
-    DCHECK_EQ(generator_object->stack_handler_index(), -1);
-    // If there are no operands on the stack, there shouldn't be a handler
-    // active either.
-    DCHECK(!frame->HasHandler());
-  } else {
-    int stack_handler_index = -1;
-    Handle<FixedArray> operand_stack =
-        isolate->factory()->NewFixedArray(operands_count);
-    frame->SaveOperandStack(*operand_stack, &stack_handler_index);
-    generator_object->set_operand_stack(*operand_stack);
-    generator_object->set_stack_handler_index(stack_handler_index);
-  }
-
-  return isolate->heap()->undefined_value();
-}
-
-
-// Note that this function is the slow path for resuming generators.  It is only
-// called if the suspended activation had operands on the stack, stack handlers
-// needing rewinding, or if the resume should throw an exception.  The fast path
-// is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
-// inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
-// called in any case, as it needs to reconstruct the stack frame and make space
-// for arguments and operands.
-RUNTIME_FUNCTION(Runtime_ResumeJSGeneratorObject) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
-  CONVERT_ARG_CHECKED(Object, value, 1);
-  CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
-  JavaScriptFrameIterator stack_iterator(isolate);
-  JavaScriptFrame* frame = stack_iterator.frame();
-
-  DCHECK_EQ(frame->function(), generator_object->function());
-  DCHECK(frame->function()->is_compiled());
-
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
-
-  Address pc = generator_object->function()->code()->instruction_start();
-  int offset = generator_object->continuation();
-  DCHECK(offset > 0);
-  frame->set_pc(pc + offset);
-  if (FLAG_enable_ool_constant_pool) {
-    frame->set_constant_pool(
-        generator_object->function()->code()->constant_pool());
-  }
-  generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
-
-  FixedArray* operand_stack = generator_object->operand_stack();
-  int operands_count = operand_stack->length();
-  if (operands_count != 0) {
-    frame->RestoreOperandStack(operand_stack,
-                               generator_object->stack_handler_index());
-    generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
-    generator_object->set_stack_handler_index(-1);
-  }
-
-  JSGeneratorObject::ResumeMode resume_mode =
-      static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
-  switch (resume_mode) {
-    case JSGeneratorObject::NEXT:
-      return value;
-    case JSGeneratorObject::THROW:
-      return isolate->Throw(value);
-  }
-
-  UNREACHABLE();
-  return isolate->ThrowIllegalOperation();
-}
-
-
-RUNTIME_FUNCTION(Runtime_ThrowGeneratorStateError) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
-  int continuation = generator->continuation();
-  const char* message = continuation == JSGeneratorObject::kGeneratorClosed ?
-      "generator_finished" : "generator_running";
-  Vector< Handle<Object> > argv = HandleVector<Object>(NULL, 0);
-  THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewError(message, argv));
-}
-
-
-RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-
-  // %ObjectFreeze is a fast path and these cases are handled elsewhere.
-  RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
-                 !object->map()->is_observed() &&
-                 !object->IsJSProxy());
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
-  CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
-
-  // Flatten the string.  If someone wants to get a char at an index
-  // in a cons string, it is likely that more indices will be
-  // accessed.
-  subject = String::Flatten(subject);
-
-  if (i >= static_cast<uint32_t>(subject->length())) {
-    return isolate->heap()->nan_value();
-  }
-
-  return Smi::FromInt(subject->Get(i));
-}
-
-
-RUNTIME_FUNCTION(Runtime_CharFromCode) {
-  HandleScope handlescope(isolate);
-  DCHECK(args.length() == 1);
-  if (args[0]->IsNumber()) {
-    CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]);
-    code &= 0xffff;
-    return *isolate->factory()->LookupSingleCharacterStringFromCode(code);
-  }
-  return isolate->heap()->empty_string();
-}
-
-
-class FixedArrayBuilder {
- public:
-  explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
-      : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
-        length_(0),
-        has_non_smi_elements_(false) {
-    // Require a non-zero initial size. Ensures that doubling the size to
-    // extend the array will work.
-    DCHECK(initial_capacity > 0);
-  }
-
-  explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
-      : array_(backing_store),
-        length_(0),
-        has_non_smi_elements_(false) {
-    // Require a non-zero initial size. Ensures that doubling the size to
-    // extend the array will work.
-    DCHECK(backing_store->length() > 0);
-  }
-
-  bool HasCapacity(int elements) {
-    int length = array_->length();
-    int required_length = length_ + elements;
-    return (length >= required_length);
-  }
-
-  void EnsureCapacity(int elements) {
-    int length = array_->length();
-    int required_length = length_ + elements;
-    if (length < required_length) {
-      int new_length = length;
-      do {
-        new_length *= 2;
-      } while (new_length < required_length);
-      Handle<FixedArray> extended_array =
-          array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
-      array_->CopyTo(0, *extended_array, 0, length_);
-      array_ = extended_array;
-    }
-  }
-
-  void Add(Object* value) {
-    DCHECK(!value->IsSmi());
-    DCHECK(length_ < capacity());
-    array_->set(length_, value);
-    length_++;
-    has_non_smi_elements_ = true;
-  }
-
-  void Add(Smi* value) {
-    DCHECK(value->IsSmi());
-    DCHECK(length_ < capacity());
-    array_->set(length_, value);
-    length_++;
-  }
-
-  Handle<FixedArray> array() {
-    return array_;
-  }
-
-  int length() {
-    return length_;
-  }
-
-  int capacity() {
-    return array_->length();
-  }
-
-  Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
-    JSArray::SetContent(target_array, array_);
-    target_array->set_length(Smi::FromInt(length_));
-    return target_array;
-  }
-
-
- private:
-  Handle<FixedArray> array_;
-  int length_;
-  bool has_non_smi_elements_;
-};
-
-
-// Forward declarations.
-const int kStringBuilderConcatHelperLengthBits = 11;
-const int kStringBuilderConcatHelperPositionBits = 19;
-
-template <typename schar>
-static inline void StringBuilderConcatHelper(String*,
-                                             schar*,
-                                             FixedArray*,
-                                             int);
-
-typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
-    StringBuilderSubstringLength;
-typedef BitField<int,
-                 kStringBuilderConcatHelperLengthBits,
-                 kStringBuilderConcatHelperPositionBits>
-    StringBuilderSubstringPosition;
-
-
-class ReplacementStringBuilder {
- public:
-  ReplacementStringBuilder(Heap* heap, Handle<String> subject,
-                           int estimated_part_count)
-      : heap_(heap),
-        array_builder_(heap->isolate(), estimated_part_count),
-        subject_(subject),
-        character_count_(0),
-        is_one_byte_(subject->IsOneByteRepresentation()) {
-    // Require a non-zero initial size. Ensures that doubling the size to
-    // extend the array will work.
-    DCHECK(estimated_part_count > 0);
-  }
-
-  static inline void AddSubjectSlice(FixedArrayBuilder* builder,
-                                     int from,
-                                     int to) {
-    DCHECK(from >= 0);
-    int length = to - from;
-    DCHECK(length > 0);
-    if (StringBuilderSubstringLength::is_valid(length) &&
-        StringBuilderSubstringPosition::is_valid(from)) {
-      int encoded_slice = StringBuilderSubstringLength::encode(length) |
-          StringBuilderSubstringPosition::encode(from);
-      builder->Add(Smi::FromInt(encoded_slice));
-    } else {
-      // Otherwise encode as two smis.
-      builder->Add(Smi::FromInt(-length));
-      builder->Add(Smi::FromInt(from));
-    }
-  }
-
-
-  void EnsureCapacity(int elements) {
-    array_builder_.EnsureCapacity(elements);
-  }
-
-
-  void AddSubjectSlice(int from, int to) {
-    AddSubjectSlice(&array_builder_, from, to);
-    IncrementCharacterCount(to - from);
-  }
-
-
-  void AddString(Handle<String> string) {
-    int length = string->length();
-    DCHECK(length > 0);
-    AddElement(*string);
-    if (!string->IsOneByteRepresentation()) {
-      is_one_byte_ = false;
-    }
-    IncrementCharacterCount(length);
-  }
-
-
-  MaybeHandle<String> ToString() {
-    Isolate* isolate = heap_->isolate();
-    if (array_builder_.length() == 0) {
-      return isolate->factory()->empty_string();
-    }
-
-    Handle<String> joined_string;
-    if (is_one_byte_) {
-      Handle<SeqOneByteString> seq;
-      ASSIGN_RETURN_ON_EXCEPTION(
-          isolate, seq,
-          isolate->factory()->NewRawOneByteString(character_count_),
-          String);
-
-      DisallowHeapAllocation no_gc;
-      uint8_t* char_buffer = seq->GetChars();
-      StringBuilderConcatHelper(*subject_,
-                                char_buffer,
-                                *array_builder_.array(),
-                                array_builder_.length());
-      joined_string = Handle<String>::cast(seq);
-    } else {
-      // Two-byte.
-      Handle<SeqTwoByteString> seq;
-      ASSIGN_RETURN_ON_EXCEPTION(
-          isolate, seq,
-          isolate->factory()->NewRawTwoByteString(character_count_),
-          String);
-
-      DisallowHeapAllocation no_gc;
-      uc16* char_buffer = seq->GetChars();
-      StringBuilderConcatHelper(*subject_,
-                                char_buffer,
-                                *array_builder_.array(),
-                                array_builder_.length());
-      joined_string = Handle<String>::cast(seq);
-    }
-    return joined_string;
-  }
-
-
-  void IncrementCharacterCount(int by) {
-    if (character_count_ > String::kMaxLength - by) {
-      STATIC_ASSERT(String::kMaxLength < kMaxInt);
-      character_count_ = kMaxInt;
-    } else {
-      character_count_ += by;
-    }
-  }
-
- private:
-  void AddElement(Object* element) {
-    DCHECK(element->IsSmi() || element->IsString());
-    DCHECK(array_builder_.capacity() > array_builder_.length());
-    array_builder_.Add(element);
-  }
-
-  Heap* heap_;
-  FixedArrayBuilder array_builder_;
-  Handle<String> subject_;
-  int character_count_;
-  bool is_one_byte_;
-};
-
-
-class CompiledReplacement {
- public:
-  explicit CompiledReplacement(Zone* zone)
-      : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {}
-
-  // Return whether the replacement is simple.
-  bool Compile(Handle<String> replacement,
-               int capture_count,
-               int subject_length);
-
-  // Use Apply only if Compile returned false.
-  void Apply(ReplacementStringBuilder* builder,
-             int match_from,
-             int match_to,
-             int32_t* match);
-
-  // Number of distinct parts of the replacement pattern.
-  int parts() {
-    return parts_.length();
-  }
-
-  Zone* zone() const { return zone_; }
-
- private:
-  enum PartType {
-    SUBJECT_PREFIX = 1,
-    SUBJECT_SUFFIX,
-    SUBJECT_CAPTURE,
-    REPLACEMENT_SUBSTRING,
-    REPLACEMENT_STRING,
-
-    NUMBER_OF_PART_TYPES
-  };
-
-  struct ReplacementPart {
-    static inline ReplacementPart SubjectMatch() {
-      return ReplacementPart(SUBJECT_CAPTURE, 0);
-    }
-    static inline ReplacementPart SubjectCapture(int capture_index) {
-      return ReplacementPart(SUBJECT_CAPTURE, capture_index);
-    }
-    static inline ReplacementPart SubjectPrefix() {
-      return ReplacementPart(SUBJECT_PREFIX, 0);
-    }
-    static inline ReplacementPart SubjectSuffix(int subject_length) {
-      return ReplacementPart(SUBJECT_SUFFIX, subject_length);
-    }
-    static inline ReplacementPart ReplacementString() {
-      return ReplacementPart(REPLACEMENT_STRING, 0);
-    }
-    static inline ReplacementPart ReplacementSubString(int from, int to) {
-      DCHECK(from >= 0);
-      DCHECK(to > from);
-      return ReplacementPart(-from, to);
-    }
-
-    // If tag <= 0 then it is the negation of a start index of a substring of
-    // the replacement pattern, otherwise it's a value from PartType.
-    ReplacementPart(int tag, int data)
-        : tag(tag), data(data) {
-      // Must be non-positive or a PartType value.
-      DCHECK(tag < NUMBER_OF_PART_TYPES);
-    }
-    // Either a value of PartType or a non-positive number that is
-    // the negation of an index into the replacement string.
-    int tag;
-    // The data value's interpretation depends on the value of tag:
-    // tag == SUBJECT_PREFIX ||
-    // tag == SUBJECT_SUFFIX:  data is unused.
-    // tag == SUBJECT_CAPTURE: data is the number of the capture.
-    // tag == REPLACEMENT_SUBSTRING ||
-    // tag == REPLACEMENT_STRING:    data is index into array of substrings
-    //                               of the replacement string.
-    // tag <= 0: Temporary representation of the substring of the replacement
-    //           string ranging over -tag .. data.
-    //           Is replaced by REPLACEMENT_{SUB,}STRING when we create the
-    //           substring objects.
-    int data;
-  };
-
-  template<typename Char>
-  bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
-                               Vector<Char> characters,
-                               int capture_count,
-                               int subject_length,
-                               Zone* zone) {
-    int length = characters.length();
-    int last = 0;
-    for (int i = 0; i < length; i++) {
-      Char c = characters[i];
-      if (c == '$') {
-        int next_index = i + 1;
-        if (next_index == length) {  // No next character!
-          break;
-        }
-        Char c2 = characters[next_index];
-        switch (c2) {
-        case '$':
-          if (i > last) {
-            // There is a substring before. Include the first "$".
-            parts->Add(ReplacementPart::ReplacementSubString(last, next_index),
-                       zone);
-            last = next_index + 1;  // Continue after the second "$".
-          } else {
-            // Let the next substring start with the second "$".
-            last = next_index;
-          }
-          i = next_index;
-          break;
-        case '`':
-          if (i > last) {
-            parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
-          }
-          parts->Add(ReplacementPart::SubjectPrefix(), zone);
-          i = next_index;
-          last = i + 1;
-          break;
-        case '\'':
-          if (i > last) {
-            parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
-          }
-          parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone);
-          i = next_index;
-          last = i + 1;
-          break;
-        case '&':
-          if (i > last) {
-            parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
-          }
-          parts->Add(ReplacementPart::SubjectMatch(), zone);
-          i = next_index;
-          last = i + 1;
-          break;
-        case '0':
-        case '1':
-        case '2':
-        case '3':
-        case '4':
-        case '5':
-        case '6':
-        case '7':
-        case '8':
-        case '9': {
-          int capture_ref = c2 - '0';
-          if (capture_ref > capture_count) {
-            i = next_index;
-            continue;
-          }
-          int second_digit_index = next_index + 1;
-          if (second_digit_index < length) {
-            // Peek ahead to see if we have two digits.
-            Char c3 = characters[second_digit_index];
-            if ('0' <= c3 && c3 <= '9') {  // Double digits.
-              int double_digit_ref = capture_ref * 10 + c3 - '0';
-              if (double_digit_ref <= capture_count) {
-                next_index = second_digit_index;
-                capture_ref = double_digit_ref;
-              }
-            }
-          }
-          if (capture_ref > 0) {
-            if (i > last) {
-              parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
-            }
-            DCHECK(capture_ref <= capture_count);
-            parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone);
-            last = next_index + 1;
-          }
-          i = next_index;
-          break;
-        }
-        default:
-          i = next_index;
-          break;
-        }
-      }
-    }
-    if (length > last) {
-      if (last == 0) {
-        // Replacement is simple.  Do not use Apply to do the replacement.
-        return true;
-      } else {
-        parts->Add(ReplacementPart::ReplacementSubString(last, length), zone);
-      }
-    }
-    return false;
-  }
-
-  ZoneList<ReplacementPart> parts_;
-  ZoneList<Handle<String> > replacement_substrings_;
-  Zone* zone_;
-};
-
-
-bool CompiledReplacement::Compile(Handle<String> replacement,
-                                  int capture_count,
-                                  int subject_length) {
-  {
-    DisallowHeapAllocation no_gc;
-    String::FlatContent content = replacement->GetFlatContent();
-    DCHECK(content.IsFlat());
-    bool simple = false;
-    if (content.IsOneByte()) {
-      simple = ParseReplacementPattern(&parts_,
-                                       content.ToOneByteVector(),
-                                       capture_count,
-                                       subject_length,
-                                       zone());
-    } else {
-      DCHECK(content.IsTwoByte());
-      simple = ParseReplacementPattern(&parts_,
-                                       content.ToUC16Vector(),
-                                       capture_count,
-                                       subject_length,
-                                       zone());
-    }
-    if (simple) return true;
-  }
-
-  Isolate* isolate = replacement->GetIsolate();
-  // Find substrings of replacement string and create them as String objects.
-  int substring_index = 0;
-  for (int i = 0, n = parts_.length(); i < n; i++) {
-    int tag = parts_[i].tag;
-    if (tag <= 0) {  // A replacement string slice.
-      int from = -tag;
-      int to = parts_[i].data;
-      replacement_substrings_.Add(
-          isolate->factory()->NewSubString(replacement, from, to), zone());
-      parts_[i].tag = REPLACEMENT_SUBSTRING;
-      parts_[i].data = substring_index;
-      substring_index++;
-    } else if (tag == REPLACEMENT_STRING) {
-      replacement_substrings_.Add(replacement, zone());
-      parts_[i].data = substring_index;
-      substring_index++;
-    }
-  }
-  return false;
-}
-
-
-void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
-                                int match_from,
-                                int match_to,
-                                int32_t* match) {
-  DCHECK_LT(0, parts_.length());
-  for (int i = 0, n = parts_.length(); i < n; i++) {
-    ReplacementPart part = parts_[i];
-    switch (part.tag) {
-      case SUBJECT_PREFIX:
-        if (match_from > 0) builder->AddSubjectSlice(0, match_from);
-        break;
-      case SUBJECT_SUFFIX: {
-        int subject_length = part.data;
-        if (match_to < subject_length) {
-          builder->AddSubjectSlice(match_to, subject_length);
-        }
-        break;
-      }
-      case SUBJECT_CAPTURE: {
-        int capture = part.data;
-        int from = match[capture * 2];
-        int to = match[capture * 2 + 1];
-        if (from >= 0 && to > from) {
-          builder->AddSubjectSlice(from, to);
-        }
-        break;
-      }
-      case REPLACEMENT_SUBSTRING:
-      case REPLACEMENT_STRING:
-        builder->AddString(replacement_substrings_[part.data]);
-        break;
-      default:
-        UNREACHABLE();
-    }
-  }
-}
-
-
-void FindOneByteStringIndices(Vector<const uint8_t> subject, char pattern,
-                              ZoneList<int>* indices, unsigned int limit,
-                              Zone* zone) {
-  DCHECK(limit > 0);
-  // Collect indices of pattern in subject using memchr.
-  // Stop after finding at most limit values.
-  const uint8_t* subject_start = subject.start();
-  const uint8_t* subject_end = subject_start + subject.length();
-  const uint8_t* pos = subject_start;
-  while (limit > 0) {
-    pos = reinterpret_cast<const uint8_t*>(
-        memchr(pos, pattern, subject_end - pos));
-    if (pos == NULL) return;
-    indices->Add(static_cast<int>(pos - subject_start), zone);
-    pos++;
-    limit--;
-  }
-}
-
-
-void FindTwoByteStringIndices(const Vector<const uc16> subject,
-                              uc16 pattern,
-                              ZoneList<int>* indices,
-                              unsigned int limit,
-                              Zone* zone) {
-  DCHECK(limit > 0);
-  const uc16* subject_start = subject.start();
-  const uc16* subject_end = subject_start + subject.length();
-  for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
-    if (*pos == pattern) {
-      indices->Add(static_cast<int>(pos - subject_start), zone);
-      limit--;
-    }
-  }
-}
-
-
-template <typename SubjectChar, typename PatternChar>
-void FindStringIndices(Isolate* isolate,
-                       Vector<const SubjectChar> subject,
-                       Vector<const PatternChar> pattern,
-                       ZoneList<int>* indices,
-                       unsigned int limit,
-                       Zone* zone) {
-  DCHECK(limit > 0);
-  // Collect indices of pattern in subject.
-  // Stop after finding at most limit values.
-  int pattern_length = pattern.length();
-  int index = 0;
-  StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
-  while (limit > 0) {
-    index = search.Search(subject, index);
-    if (index < 0) return;
-    indices->Add(index, zone);
-    index += pattern_length;
-    limit--;
-  }
-}
-
-
-void FindStringIndicesDispatch(Isolate* isolate,
-                               String* subject,
-                               String* pattern,
-                               ZoneList<int>* indices,
-                               unsigned int limit,
-                               Zone* zone) {
-  {
-    DisallowHeapAllocation no_gc;
-    String::FlatContent subject_content = subject->GetFlatContent();
-    String::FlatContent pattern_content = pattern->GetFlatContent();
-    DCHECK(subject_content.IsFlat());
-    DCHECK(pattern_content.IsFlat());
-    if (subject_content.IsOneByte()) {
-      Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
-      if (pattern_content.IsOneByte()) {
-        Vector<const uint8_t> pattern_vector =
-            pattern_content.ToOneByteVector();
-        if (pattern_vector.length() == 1) {
-          FindOneByteStringIndices(subject_vector, pattern_vector[0], indices,
-                                   limit, zone);
-        } else {
-          FindStringIndices(isolate,
-                            subject_vector,
-                            pattern_vector,
-                            indices,
-                            limit,
-                            zone);
-        }
-      } else {
-        FindStringIndices(isolate,
-                          subject_vector,
-                          pattern_content.ToUC16Vector(),
-                          indices,
-                          limit,
-                          zone);
-      }
-    } else {
-      Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
-      if (pattern_content.IsOneByte()) {
-        Vector<const uint8_t> pattern_vector =
-            pattern_content.ToOneByteVector();
-        if (pattern_vector.length() == 1) {
-          FindTwoByteStringIndices(subject_vector,
-                                   pattern_vector[0],
-                                   indices,
-                                   limit,
-                                   zone);
-        } else {
-          FindStringIndices(isolate,
-                            subject_vector,
-                            pattern_vector,
-                            indices,
-                            limit,
-                            zone);
-        }
-      } else {
-        Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector();
-        if (pattern_vector.length() == 1) {
-          FindTwoByteStringIndices(subject_vector,
-                                   pattern_vector[0],
-                                   indices,
-                                   limit,
-                                   zone);
-        } else {
-          FindStringIndices(isolate,
-                            subject_vector,
-                            pattern_vector,
-                            indices,
-                            limit,
-                            zone);
-        }
-      }
-    }
-  }
-}
-
-
-template<typename ResultSeqString>
-MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
-    Isolate* isolate,
-    Handle<String> subject,
-    Handle<JSRegExp> pattern_regexp,
-    Handle<String> replacement,
-    Handle<JSArray> last_match_info) {
-  DCHECK(subject->IsFlat());
-  DCHECK(replacement->IsFlat());
-
-  ZoneScope zone_scope(isolate->runtime_zone());
-  ZoneList<int> indices(8, zone_scope.zone());
-  DCHECK_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
-  String* pattern =
-      String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
-  int subject_len = subject->length();
-  int pattern_len = pattern->length();
-  int replacement_len = replacement->length();
-
-  FindStringIndicesDispatch(
-      isolate, *subject, pattern, &indices, 0xffffffff, zone_scope.zone());
-
-  int matches = indices.length();
-  if (matches == 0) return *subject;
-
-  // Detect integer overflow.
-  int64_t result_len_64 =
-      (static_cast<int64_t>(replacement_len) -
-       static_cast<int64_t>(pattern_len)) *
-      static_cast<int64_t>(matches) +
-      static_cast<int64_t>(subject_len);
-  int result_len;
-  if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) {
-    STATIC_ASSERT(String::kMaxLength < kMaxInt);
-    result_len = kMaxInt;  // Provoke exception.
-  } else {
-    result_len = static_cast<int>(result_len_64);
-  }
-
-  int subject_pos = 0;
-  int result_pos = 0;
-
-  MaybeHandle<SeqString> maybe_res;
-  if (ResultSeqString::kHasOneByteEncoding) {
-    maybe_res = isolate->factory()->NewRawOneByteString(result_len);
-  } else {
-    maybe_res = isolate->factory()->NewRawTwoByteString(result_len);
-  }
-  Handle<SeqString> untyped_res;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res);
-  Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res);
-
-  for (int i = 0; i < matches; i++) {
-    // Copy non-matched subject content.
-    if (subject_pos < indices.at(i)) {
-      String::WriteToFlat(*subject,
-                          result->GetChars() + result_pos,
-                          subject_pos,
-                          indices.at(i));
-      result_pos += indices.at(i) - subject_pos;
-    }
-
-    // Replace match.
-    if (replacement_len > 0) {
-      String::WriteToFlat(*replacement,
-                          result->GetChars() + result_pos,
-                          0,
-                          replacement_len);
-      result_pos += replacement_len;
-    }
-
-    subject_pos = indices.at(i) + pattern_len;
-  }
-  // Add remaining subject content at the end.
-  if (subject_pos < subject_len) {
-    String::WriteToFlat(*subject,
-                        result->GetChars() + result_pos,
-                        subject_pos,
-                        subject_len);
-  }
-
-  int32_t match_indices[] = { indices.at(matches - 1),
-                              indices.at(matches - 1) + pattern_len };
-  RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
-
-  return *result;
-}
-
-
-MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString(
-    Isolate* isolate,
-    Handle<String> subject,
-    Handle<JSRegExp> regexp,
-    Handle<String> replacement,
-    Handle<JSArray> last_match_info) {
-  DCHECK(subject->IsFlat());
-  DCHECK(replacement->IsFlat());
-
-  int capture_count = regexp->CaptureCount();
-  int subject_length = subject->length();
-
-  // CompiledReplacement uses zone allocation.
-  ZoneScope zone_scope(isolate->runtime_zone());
-  CompiledReplacement compiled_replacement(zone_scope.zone());
-  bool simple_replace = compiled_replacement.Compile(replacement,
-                                                     capture_count,
-                                                     subject_length);
-
-  // Shortcut for simple non-regexp global replacements
-  if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) {
-    if (subject->HasOnlyOneByteChars() &&
-        replacement->HasOnlyOneByteChars()) {
-      return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
-          isolate, subject, regexp, replacement, last_match_info);
-    } else {
-      return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
-          isolate, subject, regexp, replacement, last_match_info);
-    }
-  }
-
-  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
-  if (global_cache.HasException()) return isolate->heap()->exception();
-
-  int32_t* current_match = global_cache.FetchNext();
-  if (current_match == NULL) {
-    if (global_cache.HasException()) return isolate->heap()->exception();
-    return *subject;
-  }
-
-  // Guessing the number of parts that the final result string is built
-  // from. Global regexps can match any number of times, so we guess
-  // conservatively.
-  int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1;
-  ReplacementStringBuilder builder(isolate->heap(),
-                                   subject,
-                                   expected_parts);
-
-  // Number of parts added by compiled replacement plus preceeding
-  // string and possibly suffix after last match.  It is possible for
-  // all components to use two elements when encoded as two smis.
-  const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
-
-  int prev = 0;
-
-  do {
-    builder.EnsureCapacity(parts_added_per_loop);
-
-    int start = current_match[0];
-    int end = current_match[1];
-
-    if (prev < start) {
-      builder.AddSubjectSlice(prev, start);
-    }
-
-    if (simple_replace) {
-      builder.AddString(replacement);
-    } else {
-      compiled_replacement.Apply(&builder,
-                                 start,
-                                 end,
-                                 current_match);
-    }
-    prev = end;
-
-    current_match = global_cache.FetchNext();
-  } while (current_match != NULL);
-
-  if (global_cache.HasException()) return isolate->heap()->exception();
-
-  if (prev < subject_length) {
-    builder.EnsureCapacity(2);
-    builder.AddSubjectSlice(prev, subject_length);
-  }
-
-  RegExpImpl::SetLastMatchInfo(last_match_info,
-                               subject,
-                               capture_count,
-                               global_cache.LastSuccessfulMatch());
-
-  Handle<String> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, builder.ToString());
-  return *result;
-}
-
-
-template <typename ResultSeqString>
-MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
-    Isolate* isolate,
-    Handle<String> subject,
-    Handle<JSRegExp> regexp,
-    Handle<JSArray> last_match_info) {
-  DCHECK(subject->IsFlat());
-
-  // Shortcut for simple non-regexp global replacements
-  if (regexp->TypeTag() == JSRegExp::ATOM) {
-    Handle<String> empty_string = isolate->factory()->empty_string();
-    if (subject->IsOneByteRepresentation()) {
-      return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
-          isolate, subject, regexp, empty_string, last_match_info);
-    } else {
-      return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
-          isolate, subject, regexp, empty_string, last_match_info);
-    }
-  }
-
-  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
-  if (global_cache.HasException()) return isolate->heap()->exception();
-
-  int32_t* current_match = global_cache.FetchNext();
-  if (current_match == NULL) {
-    if (global_cache.HasException()) return isolate->heap()->exception();
-    return *subject;
-  }
-
-  int start = current_match[0];
-  int end = current_match[1];
-  int capture_count = regexp->CaptureCount();
-  int subject_length = subject->length();
-
-  int new_length = subject_length - (end - start);
-  if (new_length == 0) return isolate->heap()->empty_string();
-
-  Handle<ResultSeqString> answer;
-  if (ResultSeqString::kHasOneByteEncoding) {
-    answer = Handle<ResultSeqString>::cast(
-        isolate->factory()->NewRawOneByteString(new_length).ToHandleChecked());
-  } else {
-    answer = Handle<ResultSeqString>::cast(
-        isolate->factory()->NewRawTwoByteString(new_length).ToHandleChecked());
-  }
-
-  int prev = 0;
-  int position = 0;
-
-  do {
-    start = current_match[0];
-    end = current_match[1];
-    if (prev < start) {
-      // Add substring subject[prev;start] to answer string.
-      String::WriteToFlat(*subject, answer->GetChars() + position, prev, start);
-      position += start - prev;
-    }
-    prev = end;
-
-    current_match = global_cache.FetchNext();
-  } while (current_match != NULL);
-
-  if (global_cache.HasException()) return isolate->heap()->exception();
-
-  RegExpImpl::SetLastMatchInfo(last_match_info,
-                               subject,
-                               capture_count,
-                               global_cache.LastSuccessfulMatch());
-
-  if (prev < subject_length) {
-    // Add substring subject[prev;length] to answer string.
-    String::WriteToFlat(
-        *subject, answer->GetChars() + position, prev, subject_length);
-    position += subject_length - prev;
-  }
-
-  if (position == 0) return isolate->heap()->empty_string();
-
-  // Shorten string and fill
-  int string_size = ResultSeqString::SizeFor(position);
-  int allocated_string_size = ResultSeqString::SizeFor(new_length);
-  int delta = allocated_string_size - string_size;
-
-  answer->set_length(position);
-  if (delta == 0) return *answer;
-
-  Address end_of_string = answer->address() + string_size;
-  Heap* heap = isolate->heap();
-
-  // The trimming is performed on a newly allocated object, which is on a
-  // fresly allocated page or on an already swept page. Hence, the sweeper
-  // thread can not get confused with the filler creation. No synchronization
-  // needed.
-  heap->CreateFillerObjectAt(end_of_string, delta);
-  heap->AdjustLiveBytes(answer->address(), -delta, Heap::FROM_MUTATOR);
-  return *answer;
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
-
-  RUNTIME_ASSERT(regexp->GetFlags().is_global());
-  RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
-
-  subject = String::Flatten(subject);
-
-  if (replacement->length() == 0) {
-    if (subject->HasOnlyOneByteChars()) {
-      return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
-          isolate, subject, regexp, last_match_info);
-    } else {
-      return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
-          isolate, subject, regexp, last_match_info);
-    }
-  }
-
-  replacement = String::Flatten(replacement);
-
-  return StringReplaceGlobalRegExpWithString(
-      isolate, subject, regexp, replacement, last_match_info);
-}
-
-
-// This may return an empty MaybeHandle if an exception is thrown or
-// we abort due to reaching the recursion limit.
-MaybeHandle<String> StringReplaceOneCharWithString(Isolate* isolate,
-                                                   Handle<String> subject,
-                                                   Handle<String> search,
-                                                   Handle<String> replace,
-                                                   bool* found,
-                                                   int recursion_limit) {
-  StackLimitCheck stackLimitCheck(isolate);
-  if (stackLimitCheck.HasOverflowed() || (recursion_limit == 0)) {
-    return MaybeHandle<String>();
-  }
-  recursion_limit--;
-  if (subject->IsConsString()) {
-    ConsString* cons = ConsString::cast(*subject);
-    Handle<String> first = Handle<String>(cons->first());
-    Handle<String> second = Handle<String>(cons->second());
-    Handle<String> new_first;
-    if (!StringReplaceOneCharWithString(
-            isolate, first, search, replace, found, recursion_limit)
-            .ToHandle(&new_first)) {
-      return MaybeHandle<String>();
-    }
-    if (*found) return isolate->factory()->NewConsString(new_first, second);
-
-    Handle<String> new_second;
-    if (!StringReplaceOneCharWithString(
-            isolate, second, search, replace, found, recursion_limit)
-            .ToHandle(&new_second)) {
-      return MaybeHandle<String>();
-    }
-    if (*found) return isolate->factory()->NewConsString(first, new_second);
-
-    return subject;
-  } else {
-    int index = Runtime::StringMatch(isolate, subject, search, 0);
-    if (index == -1) return subject;
-    *found = true;
-    Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
-    Handle<String> cons1;
-    ASSIGN_RETURN_ON_EXCEPTION(
-        isolate, cons1,
-        isolate->factory()->NewConsString(first, replace),
-        String);
-    Handle<String> second =
-        isolate->factory()->NewSubString(subject, index + 1, subject->length());
-    return isolate->factory()->NewConsString(cons1, second);
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
-
-  // If the cons string tree is too deep, we simply abort the recursion and
-  // retry with a flattened subject string.
-  const int kRecursionLimit = 0x1000;
-  bool found = false;
-  Handle<String> result;
-  if (StringReplaceOneCharWithString(
-          isolate, subject, search, replace, &found, kRecursionLimit)
-          .ToHandle(&result)) {
-    return *result;
-  }
-  if (isolate->has_pending_exception()) return isolate->heap()->exception();
-
-  subject = String::Flatten(subject);
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      StringReplaceOneCharWithString(
-          isolate, subject, search, replace, &found, kRecursionLimit));
-  return *result;
-}
-
-
-// Perform string match of pattern on subject, starting at start index.
-// Caller must ensure that 0 <= start_index <= sub->length(),
-// and should check that pat->length() + start_index <= sub->length().
-int Runtime::StringMatch(Isolate* isolate,
-                         Handle<String> sub,
-                         Handle<String> pat,
-                         int start_index) {
-  DCHECK(0 <= start_index);
-  DCHECK(start_index <= sub->length());
-
-  int pattern_length = pat->length();
-  if (pattern_length == 0) return start_index;
-
-  int subject_length = sub->length();
-  if (start_index + pattern_length > subject_length) return -1;
-
-  sub = String::Flatten(sub);
-  pat = String::Flatten(pat);
-
-  DisallowHeapAllocation no_gc;  // ensure vectors stay valid
-  // Extract flattened substrings of cons strings before getting encoding.
-  String::FlatContent seq_sub = sub->GetFlatContent();
-  String::FlatContent seq_pat = pat->GetFlatContent();
-
-  // dispatch on type of strings
-  if (seq_pat.IsOneByte()) {
-    Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
-    if (seq_sub.IsOneByte()) {
-      return SearchString(isolate,
-                          seq_sub.ToOneByteVector(),
-                          pat_vector,
-                          start_index);
-    }
-    return SearchString(isolate,
-                        seq_sub.ToUC16Vector(),
-                        pat_vector,
-                        start_index);
-  }
-  Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
-  if (seq_sub.IsOneByte()) {
-    return SearchString(isolate,
-                        seq_sub.ToOneByteVector(),
-                        pat_vector,
-                        start_index);
-  }
-  return SearchString(isolate,
-                      seq_sub.ToUC16Vector(),
-                      pat_vector,
-                      start_index);
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringIndexOf) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
-
-  uint32_t start_index;
-  if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
-
-  RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
-  int position = Runtime::StringMatch(isolate, sub, pat, start_index);
-  return Smi::FromInt(position);
-}
-
-
-template <typename schar, typename pchar>
-static int StringMatchBackwards(Vector<const schar> subject,
-                                Vector<const pchar> pattern,
-                                int idx) {
-  int pattern_length = pattern.length();
-  DCHECK(pattern_length >= 1);
-  DCHECK(idx + pattern_length <= subject.length());
-
-  if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
-    for (int i = 0; i < pattern_length; i++) {
-      uc16 c = pattern[i];
-      if (c > String::kMaxOneByteCharCode) {
-        return -1;
-      }
-    }
-  }
-
-  pchar pattern_first_char = pattern[0];
-  for (int i = idx; i >= 0; i--) {
-    if (subject[i] != pattern_first_char) continue;
-    int j = 1;
-    while (j < pattern_length) {
-      if (pattern[j] != subject[i+j]) {
-        break;
-      }
-      j++;
-    }
-    if (j == pattern_length) {
-      return i;
-    }
-  }
-  return -1;
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringLastIndexOf) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
-
-  uint32_t start_index;
-  if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
-
-  uint32_t pat_length = pat->length();
-  uint32_t sub_length = sub->length();
-
-  if (start_index + pat_length > sub_length) {
-    start_index = sub_length - pat_length;
-  }
-
-  if (pat_length == 0) {
-    return Smi::FromInt(start_index);
-  }
-
-  sub = String::Flatten(sub);
-  pat = String::Flatten(pat);
-
-  int position = -1;
-  DisallowHeapAllocation no_gc;  // ensure vectors stay valid
-
-  String::FlatContent sub_content = sub->GetFlatContent();
-  String::FlatContent pat_content = pat->GetFlatContent();
-
-  if (pat_content.IsOneByte()) {
-    Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
-    if (sub_content.IsOneByte()) {
-      position = StringMatchBackwards(sub_content.ToOneByteVector(),
-                                      pat_vector,
-                                      start_index);
-    } else {
-      position = StringMatchBackwards(sub_content.ToUC16Vector(),
-                                      pat_vector,
-                                      start_index);
-    }
-  } else {
-    Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
-    if (sub_content.IsOneByte()) {
-      position = StringMatchBackwards(sub_content.ToOneByteVector(),
-                                      pat_vector,
-                                      start_index);
-    } else {
-      position = StringMatchBackwards(sub_content.ToUC16Vector(),
-                                      pat_vector,
-                                      start_index);
-    }
-  }
-
-  return Smi::FromInt(position);
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringLocaleCompare) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
-
-  if (str1.is_identical_to(str2)) return Smi::FromInt(0);  // Equal.
-  int str1_length = str1->length();
-  int str2_length = str2->length();
-
-  // Decide trivial cases without flattening.
-  if (str1_length == 0) {
-    if (str2_length == 0) return Smi::FromInt(0);  // Equal.
-    return Smi::FromInt(-str2_length);
-  } else {
-    if (str2_length == 0) return Smi::FromInt(str1_length);
-  }
-
-  int end = str1_length < str2_length ? str1_length : str2_length;
-
-  // No need to flatten if we are going to find the answer on the first
-  // character.  At this point we know there is at least one character
-  // in each string, due to the trivial case handling above.
-  int d = str1->Get(0) - str2->Get(0);
-  if (d != 0) return Smi::FromInt(d);
-
-  str1 = String::Flatten(str1);
-  str2 = String::Flatten(str2);
-
-  DisallowHeapAllocation no_gc;
-  String::FlatContent flat1 = str1->GetFlatContent();
-  String::FlatContent flat2 = str2->GetFlatContent();
-
-  for (int i = 0; i < end; i++) {
-    if (flat1.Get(i) != flat2.Get(i)) {
-      return Smi::FromInt(flat1.Get(i) - flat2.Get(i));
-    }
-  }
-
-  return Smi::FromInt(str1_length - str2_length);
-}
-
-
-RUNTIME_FUNCTION(Runtime_SubString) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
-  int start, end;
-  // We have a fast integer-only case here to avoid a conversion to double in
-  // the common case where from and to are Smis.
-  if (args[1]->IsSmi() && args[2]->IsSmi()) {
-    CONVERT_SMI_ARG_CHECKED(from_number, 1);
-    CONVERT_SMI_ARG_CHECKED(to_number, 2);
-    start = from_number;
-    end = to_number;
-  } else {
-    CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
-    CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
-    start = FastD2IChecked(from_number);
-    end = FastD2IChecked(to_number);
-  }
-  RUNTIME_ASSERT(end >= start);
-  RUNTIME_ASSERT(start >= 0);
-  RUNTIME_ASSERT(end <= string->length());
-  isolate->counters()->sub_string_runtime()->Increment();
-
-  return *isolate->factory()->NewSubString(string, start, end);
-}
-
-
-RUNTIME_FUNCTION(Runtime_InternalizeString) {
-  HandleScope handles(isolate);
-  RUNTIME_ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
-  return *isolate->factory()->InternalizeString(string);
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringMatch) {
-  HandleScope handles(isolate);
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
-
-  RUNTIME_ASSERT(regexp_info->HasFastObjectElements());
-
-  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
-  if (global_cache.HasException()) return isolate->heap()->exception();
-
-  int capture_count = regexp->CaptureCount();
-
-  ZoneScope zone_scope(isolate->runtime_zone());
-  ZoneList<int> offsets(8, zone_scope.zone());
-
-  while (true) {
-    int32_t* match = global_cache.FetchNext();
-    if (match == NULL) break;
-    offsets.Add(match[0], zone_scope.zone());  // start
-    offsets.Add(match[1], zone_scope.zone());  // end
-  }
-
-  if (global_cache.HasException()) return isolate->heap()->exception();
-
-  if (offsets.length() == 0) {
-    // Not a single match.
-    return isolate->heap()->null_value();
-  }
-
-  RegExpImpl::SetLastMatchInfo(regexp_info,
-                               subject,
-                               capture_count,
-                               global_cache.LastSuccessfulMatch());
-
-  int matches = offsets.length() / 2;
-  Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
-  Handle<String> substring =
-      isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
-  elements->set(0, *substring);
-  for (int i = 1; i < matches; i++) {
-    HandleScope temp_scope(isolate);
-    int from = offsets.at(i * 2);
-    int to = offsets.at(i * 2 + 1);
-    Handle<String> substring =
-        isolate->factory()->NewProperSubString(subject, from, to);
-    elements->set(i, *substring);
-  }
-  Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
-  result->set_length(Smi::FromInt(matches));
-  return *result;
-}
-
-
-// Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
-// separate last match info.  See comment on that function.
-template<bool has_capture>
-static Object* SearchRegExpMultiple(
-    Isolate* isolate,
-    Handle<String> subject,
-    Handle<JSRegExp> regexp,
-    Handle<JSArray> last_match_array,
-    Handle<JSArray> result_array) {
-  DCHECK(subject->IsFlat());
-  DCHECK_NE(has_capture, regexp->CaptureCount() == 0);
-
-  int capture_count = regexp->CaptureCount();
-  int subject_length = subject->length();
-
-  static const int kMinLengthToCache = 0x1000;
-
-  if (subject_length > kMinLengthToCache) {
-    Handle<Object> cached_answer(RegExpResultsCache::Lookup(
-        isolate->heap(),
-        *subject,
-        regexp->data(),
-        RegExpResultsCache::REGEXP_MULTIPLE_INDICES), isolate);
-    if (*cached_answer != Smi::FromInt(0)) {
-      Handle<FixedArray> cached_fixed_array =
-          Handle<FixedArray>(FixedArray::cast(*cached_answer));
-      // The cache FixedArray is a COW-array and can therefore be reused.
-      JSArray::SetContent(result_array, cached_fixed_array);
-      // The actual length of the result array is stored in the last element of
-      // the backing store (the backing FixedArray may have a larger capacity).
-      Object* cached_fixed_array_last_element =
-          cached_fixed_array->get(cached_fixed_array->length() - 1);
-      Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
-      result_array->set_length(js_array_length);
-      RegExpImpl::SetLastMatchInfo(
-          last_match_array, subject, capture_count, NULL);
-      return *result_array;
-    }
-  }
-
-  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
-  if (global_cache.HasException()) return isolate->heap()->exception();
-
-  // Ensured in Runtime_RegExpExecMultiple.
-  DCHECK(result_array->HasFastObjectElements());
-  Handle<FixedArray> result_elements(
-      FixedArray::cast(result_array->elements()));
-  if (result_elements->length() < 16) {
-    result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
-  }
-
-  FixedArrayBuilder builder(result_elements);
-
-  // Position to search from.
-  int match_start = -1;
-  int match_end = 0;
-  bool first = true;
-
-  // Two smis before and after the match, for very long strings.
-  static const int kMaxBuilderEntriesPerRegExpMatch = 5;
-
-  while (true) {
-    int32_t* current_match = global_cache.FetchNext();
-    if (current_match == NULL) break;
-    match_start = current_match[0];
-    builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
-    if (match_end < match_start) {
-      ReplacementStringBuilder::AddSubjectSlice(&builder,
-                                                match_end,
-                                                match_start);
-    }
-    match_end = current_match[1];
-    {
-      // Avoid accumulating new handles inside loop.
-      HandleScope temp_scope(isolate);
-      Handle<String> match;
-      if (!first) {
-        match = isolate->factory()->NewProperSubString(subject,
-                                                       match_start,
-                                                       match_end);
-      } else {
-        match = isolate->factory()->NewSubString(subject,
-                                                 match_start,
-                                                 match_end);
-        first = false;
-      }
-
-      if (has_capture) {
-        // Arguments array to replace function is match, captures, index and
-        // subject, i.e., 3 + capture count in total.
-        Handle<FixedArray> elements =
-            isolate->factory()->NewFixedArray(3 + capture_count);
-
-        elements->set(0, *match);
-        for (int i = 1; i <= capture_count; i++) {
-          int start = current_match[i * 2];
-          if (start >= 0) {
-            int end = current_match[i * 2 + 1];
-            DCHECK(start <= end);
-            Handle<String> substring =
-                isolate->factory()->NewSubString(subject, start, end);
-            elements->set(i, *substring);
-          } else {
-            DCHECK(current_match[i * 2 + 1] < 0);
-            elements->set(i, isolate->heap()->undefined_value());
-          }
-        }
-        elements->set(capture_count + 1, Smi::FromInt(match_start));
-        elements->set(capture_count + 2, *subject);
-        builder.Add(*isolate->factory()->NewJSArrayWithElements(elements));
-      } else {
-        builder.Add(*match);
-      }
-    }
-  }
-
-  if (global_cache.HasException()) return isolate->heap()->exception();
-
-  if (match_start >= 0) {
-    // Finished matching, with at least one match.
-    if (match_end < subject_length) {
-      ReplacementStringBuilder::AddSubjectSlice(&builder,
-                                                match_end,
-                                                subject_length);
-    }
-
-    RegExpImpl::SetLastMatchInfo(
-        last_match_array, subject, capture_count, NULL);
-
-    if (subject_length > kMinLengthToCache) {
-      // Store the length of the result array into the last element of the
-      // backing FixedArray.
-      builder.EnsureCapacity(1);
-      Handle<FixedArray> fixed_array = builder.array();
-      fixed_array->set(fixed_array->length() - 1,
-                       Smi::FromInt(builder.length()));
-      // Cache the result and turn the FixedArray into a COW array.
-      RegExpResultsCache::Enter(isolate,
-                                subject,
-                                handle(regexp->data(), isolate),
-                                fixed_array,
-                                RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
-    }
-    return *builder.ToJSArray(result_array);
-  } else {
-    return isolate->heap()->null_value();  // No matches at all.
-  }
-}
-
-
-// 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(Runtime_RegExpExecMultiple) {
-  HandleScope handles(isolate);
-  DCHECK(args.length() == 4);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
-  RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
-  RUNTIME_ASSERT(result_array->HasFastObjectElements());
-
-  subject = String::Flatten(subject);
-  RUNTIME_ASSERT(regexp->GetFlags().is_global());
-
-  if (regexp->CaptureCount() == 0) {
-    return SearchRegExpMultiple<false>(
-        isolate, subject, regexp, last_match_info, result_array);
-  } else {
-    return SearchRegExpMultiple<true>(
-        isolate, subject, regexp, last_match_info, result_array);
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToRadixString) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_SMI_ARG_CHECKED(radix, 1);
-  RUNTIME_ASSERT(2 <= radix && radix <= 36);
-
-  // Fast case where the result is a one character string.
-  if (args[0]->IsSmi()) {
-    int value = args.smi_at(0);
-    if (value >= 0 && value < radix) {
-      // Character array used for conversion.
-      static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-      return *isolate->factory()->
-          LookupSingleCharacterStringFromCode(kCharTable[value]);
-    }
-  }
-
-  // Slow case.
-  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
-  if (std::isnan(value)) {
-    return isolate->heap()->nan_string();
-  }
-  if (std::isinf(value)) {
-    if (value < 0) {
-      return isolate->heap()->minus_infinity_string();
-    }
-    return isolate->heap()->infinity_string();
-  }
-  char* str = DoubleToRadixCString(value, radix);
-  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
-  DeleteArray(str);
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToFixed) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
-  int f = FastD2IChecked(f_number);
-  // See DoubleToFixedCString for these constants:
-  RUNTIME_ASSERT(f >= 0 && f <= 20);
-  RUNTIME_ASSERT(!Double(value).IsSpecial());
-  char* str = DoubleToFixedCString(value, f);
-  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
-  DeleteArray(str);
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToExponential) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
-  int f = FastD2IChecked(f_number);
-  RUNTIME_ASSERT(f >= -1 && f <= 20);
-  RUNTIME_ASSERT(!Double(value).IsSpecial());
-  char* str = DoubleToExponentialCString(value, f);
-  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
-  DeleteArray(str);
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToPrecision) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
-  int f = FastD2IChecked(f_number);
-  RUNTIME_ASSERT(f >= 1 && f <= 21);
-  RUNTIME_ASSERT(!Double(value).IsSpecial());
-  char* str = DoubleToPrecisionCString(value, f);
-  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
-  DeleteArray(str);
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsValidSmi) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
-  return isolate->heap()->ToBoolean(Smi::IsValid(number));
-}
-
-
-// Returns a single character string where first character equals
-// string->Get(index).
-static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
-  if (index < static_cast<uint32_t>(string->length())) {
-    Factory* factory = string->GetIsolate()->factory();
-    return factory->LookupSingleCharacterStringFromCode(
-        String::Flatten(string)->Get(index));
-  }
-  return Execution::CharAt(string, index);
-}
-
-
-MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
-                                                Handle<Object> object,
-                                                uint32_t index) {
-  // Handle [] indexing on Strings
-  if (object->IsString()) {
-    Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
-    if (!result->IsUndefined()) return result;
-  }
-
-  // Handle [] indexing on String objects
-  if (object->IsStringObjectWithCharacterAt(index)) {
-    Handle<JSValue> js_value = Handle<JSValue>::cast(object);
-    Handle<Object> result =
-        GetCharAt(Handle<String>(String::cast(js_value->value())), index);
-    if (!result->IsUndefined()) return result;
-  }
-
-  Handle<Object> result;
-  if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
-    PrototypeIterator iter(isolate, object);
-    return Object::GetElement(isolate, PrototypeIterator::GetCurrent(iter),
-                              index);
-  } else {
-    return Object::GetElement(isolate, object, index);
-  }
-}
-
-
-MUST_USE_RESULT
-static MaybeHandle<Name> ToName(Isolate* isolate, Handle<Object> key) {
-  if (key->IsName()) {
-    return Handle<Name>::cast(key);
-  } else {
-    Handle<Object> converted;
-    ASSIGN_RETURN_ON_EXCEPTION(
-        isolate, converted, Execution::ToString(isolate, key), Name);
-    return Handle<Name>::cast(converted);
-  }
-}
-
-
-MaybeHandle<Object> Runtime::HasObjectProperty(Isolate* isolate,
-                                               Handle<JSReceiver> object,
-                                               Handle<Object> key) {
-  Maybe<bool> maybe;
-  // Check if the given key is an array index.
-  uint32_t index;
-  if (key->ToArrayIndex(&index)) {
-    maybe = JSReceiver::HasElement(object, index);
-  } else {
-    // Convert the key to a name - possibly by calling back into JavaScript.
-    Handle<Name> name;
-    ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
-
-    maybe = JSReceiver::HasProperty(object, name);
-  }
-
-  if (!maybe.has_value) return MaybeHandle<Object>();
-  return isolate->factory()->ToBoolean(maybe.value);
-}
-
-
-MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
-                                               Handle<Object> object,
-                                               Handle<Object> key) {
-  if (object->IsUndefined() || object->IsNull()) {
-    Handle<Object> args[2] = { key, object };
-    THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_load",
-                                          HandleVector(args, 2)),
-                    Object);
-  }
-
-  // Check if the given key is an array index.
-  uint32_t index;
-  if (key->ToArrayIndex(&index)) {
-    return GetElementOrCharAt(isolate, object, index);
-  }
-
-  // Convert the key to a name - possibly by calling back into JavaScript.
-  Handle<Name> name;
-  ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
-
-  // Check if the name is trivially convertible to an index and get
-  // the element if so.
-  if (name->AsArrayIndex(&index)) {
-    return GetElementOrCharAt(isolate, object, index);
-  } else {
-    return Object::GetProperty(object, name);
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Runtime::GetObjectProperty(isolate, object, key));
-  return *result;
-}
-
-
-// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
-RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
-
-  // Fast cases for getting named properties of the receiver JSObject
-  // itself.
-  //
-  // The global proxy objects has to be excluded since LookupOwn on
-  // the global proxy object can return a valid result even though the
-  // global proxy object never has properties.  This is the case
-  // because the global proxy object forwards everything to its hidden
-  // prototype including own lookups.
-  //
-  // Additionally, we need to make sure that we do not cache results
-  // for objects that require access checks.
-  if (receiver_obj->IsJSObject()) {
-    if (!receiver_obj->IsJSGlobalProxy() &&
-        !receiver_obj->IsAccessCheckNeeded() &&
-        key_obj->IsName()) {
-      DisallowHeapAllocation no_allocation;
-      Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
-      Handle<Name> key = Handle<Name>::cast(key_obj);
-      if (receiver->HasFastProperties()) {
-        // Attempt to use lookup cache.
-        Handle<Map> receiver_map(receiver->map(), isolate);
-        KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
-        int index = keyed_lookup_cache->Lookup(receiver_map, key);
-        if (index != -1) {
-          // Doubles are not cached, so raw read the value.
-          return receiver->RawFastPropertyAt(
-              FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index));
-        }
-        // Lookup cache miss.  Perform lookup and update the cache if
-        // appropriate.
-        LookupIterator it(receiver, key, LookupIterator::OWN);
-        if (it.state() == LookupIterator::DATA &&
-            it.property_details().type() == FIELD) {
-          FieldIndex field_index = it.GetFieldIndex();
-          // Do not track double fields in the keyed lookup cache. Reading
-          // double values requires boxing.
-          if (!it.representation().IsDouble()) {
-            keyed_lookup_cache->Update(receiver_map, key,
-                field_index.GetKeyedLookupCacheIndex());
-          }
-          AllowHeapAllocation allow_allocation;
-          return *JSObject::FastPropertyAt(receiver, it.representation(),
-                                           field_index);
-        }
-      } else {
-        // Attempt dictionary lookup.
-        NameDictionary* dictionary = receiver->property_dictionary();
-        int entry = dictionary->FindEntry(key);
-        if ((entry != NameDictionary::kNotFound) &&
-            (dictionary->DetailsAt(entry).type() == NORMAL)) {
-          Object* value = dictionary->ValueAt(entry);
-          if (!receiver->IsGlobalObject()) return value;
-          value = PropertyCell::cast(value)->value();
-          if (!value->IsTheHole()) return value;
-          // If value is the hole (meaning, absent) do the general lookup.
-        }
-      }
-    } else if (key_obj->IsSmi()) {
-      // JSObject without a name key. If the key is a Smi, check for a
-      // definite out-of-bounds access to elements, which is a strong indicator
-      // that subsequent accesses will also call the runtime. Proactively
-      // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
-      // doubles for those future calls in the case that the elements would
-      // become FAST_DOUBLE_ELEMENTS.
-      Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
-      ElementsKind elements_kind = js_object->GetElementsKind();
-      if (IsFastDoubleElementsKind(elements_kind)) {
-        Handle<Smi> key = Handle<Smi>::cast(key_obj);
-        if (key->value() >= js_object->elements()->length()) {
-          if (IsFastHoleyElementsKind(elements_kind)) {
-            elements_kind = FAST_HOLEY_ELEMENTS;
-          } else {
-            elements_kind = FAST_ELEMENTS;
-          }
-          RETURN_FAILURE_ON_EXCEPTION(
-              isolate, TransitionElements(js_object, elements_kind, isolate));
-        }
-      } else {
-        DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
-               !IsFastElementsKind(elements_kind));
-      }
-    }
-  } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
-    // Fast case for string indexing using [] with a smi index.
-    Handle<String> str = Handle<String>::cast(receiver_obj);
-    int index = args.smi_at(1);
-    if (index >= 0 && index < str->length()) {
-      return *GetCharAt(str, index);
-    }
-  }
-
-  // Fall back to GetObjectProperty.
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
-  return *result;
-}
-
-
-static bool IsValidAccessor(Handle<Object> obj) {
-  return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
-}
-
-
-// Transform getter or setter into something DefineAccessor can handle.
-static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
-                                                   Handle<Object> component) {
-  if (component->IsUndefined()) return isolate->factory()->undefined_value();
-  Handle<FunctionTemplateInfo> info =
-      Handle<FunctionTemplateInfo>::cast(component);
-  return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
-}
-
-
-RUNTIME_FUNCTION(Runtime_DefineApiAccessorProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 5);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
-  CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
-  CONVERT_SMI_ARG_CHECKED(attribute, 4);
-  RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
-  RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
-  RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
-      static_cast<PropertyAttributes>(attribute)));
-  RETURN_FAILURE_ON_EXCEPTION(
-      isolate, JSObject::DefineAccessor(
-                   object, name, InstantiateAccessorComponent(isolate, getter),
-                   InstantiateAccessorComponent(isolate, setter),
-                   static_cast<PropertyAttributes>(attribute)));
-  return isolate->heap()->undefined_value();
-}
-
-
-// Implements part of 8.12.9 DefineOwnProperty.
-// There are 3 cases that lead here:
-// Step 4b - define a new accessor property.
-// Steps 9c & 12 - replace an existing data property with an accessor property.
-// Step 12 - update an existing accessor property with an accessor or generic
-//           descriptor.
-RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 5);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  RUNTIME_ASSERT(!obj->IsNull());
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
-  RUNTIME_ASSERT(IsValidAccessor(getter));
-  CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
-  RUNTIME_ASSERT(IsValidAccessor(setter));
-  CONVERT_SMI_ARG_CHECKED(unchecked, 4);
-  RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
-  PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
-
-  bool fast = obj->HasFastProperties();
-  RETURN_FAILURE_ON_EXCEPTION(
-      isolate, JSObject::DefineAccessor(obj, name, getter, setter, attr));
-  if (fast) JSObject::MigrateSlowToFast(obj, 0);
-  return isolate->heap()->undefined_value();
-}
-
-
-// Implements part of 8.12.9 DefineOwnProperty.
-// There are 3 cases that lead here:
-// Step 4a - define a new data property.
-// Steps 9b & 12 - replace an existing accessor property with a data property.
-// Step 12 - update an existing data property with a data or generic
-//           descriptor.
-RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
-  CONVERT_SMI_ARG_CHECKED(unchecked, 3);
-  RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
-  PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
-
-  LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
-  if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) {
-    if (!isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
-      return isolate->heap()->undefined_value();
-    }
-    it.Next();
-  }
-
-  // Take special care when attributes are different and there is already
-  // a property.
-  if (it.state() == LookupIterator::ACCESSOR) {
-    // Use IgnoreAttributes version since a readonly property may be
-    // overridden and SetProperty does not allow this.
-    Handle<Object> result;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, result,
-        JSObject::SetOwnPropertyIgnoreAttributes(
-            js_object, name, obj_value, attr,
-            JSObject::DONT_FORCE_FIELD));
-    return *result;
-  }
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Runtime::DefineObjectProperty(js_object, name, obj_value, attr));
-  return *result;
-}
-
-
-// Return property without being observable by accessors or interceptors.
-RUNTIME_FUNCTION(Runtime_GetDataProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-  return *JSObject::GetDataProperty(object, key);
-}
-
-
-MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
-                                               Handle<Object> object,
-                                               Handle<Object> key,
-                                               Handle<Object> value,
-                                               StrictMode strict_mode) {
-  if (object->IsUndefined() || object->IsNull()) {
-    Handle<Object> args[2] = { key, object };
-    THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_store",
-                                          HandleVector(args, 2)),
-                    Object);
-  }
-
-  if (object->IsJSProxy()) {
-    Handle<Object> name_object;
-    if (key->IsSymbol()) {
-      name_object = key;
-    } else {
-      ASSIGN_RETURN_ON_EXCEPTION(
-          isolate, name_object, Execution::ToString(isolate, key), Object);
-    }
-    Handle<Name> name = Handle<Name>::cast(name_object);
-    return Object::SetProperty(Handle<JSProxy>::cast(object), name, value,
-                               strict_mode);
-  }
-
-  // Check if the given key is an array index.
-  uint32_t index;
-  if (key->ToArrayIndex(&index)) {
-    // TODO(verwaest): Support non-JSObject receivers.
-    if (!object->IsJSObject()) return value;
-    Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-
-    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
-    // of a string using [] notation.  We need to support this too in
-    // JavaScript.
-    // In the case of a String object we just need to redirect the assignment to
-    // the underlying string if the index is in range.  Since the underlying
-    // string does nothing with the assignment then we can ignore such
-    // assignments.
-    if (js_object->IsStringObjectWithCharacterAt(index)) {
-      return value;
-    }
-
-    JSObject::ValidateElements(js_object);
-    if (js_object->HasExternalArrayElements() ||
-        js_object->HasFixedTypedArrayElements()) {
-      if (!value->IsNumber() && !value->IsUndefined()) {
-        ASSIGN_RETURN_ON_EXCEPTION(
-            isolate, value, Execution::ToNumber(isolate, value), Object);
-      }
-    }
-
-    MaybeHandle<Object> result = JSObject::SetElement(
-        js_object, index, value, NONE, strict_mode, true, SET_PROPERTY);
-    JSObject::ValidateElements(js_object);
-
-    return result.is_null() ? result : value;
-  }
-
-  if (key->IsName()) {
-    Handle<Name> name = Handle<Name>::cast(key);
-    if (name->AsArrayIndex(&index)) {
-      // TODO(verwaest): Support non-JSObject receivers.
-      if (!object->IsJSObject()) return value;
-      Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-      if (js_object->HasExternalArrayElements()) {
-        if (!value->IsNumber() && !value->IsUndefined()) {
-          ASSIGN_RETURN_ON_EXCEPTION(
-              isolate, value, Execution::ToNumber(isolate, value), Object);
-        }
-      }
-      return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
-                                  true, SET_PROPERTY);
-    } else {
-      if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
-      return Object::SetProperty(object, name, value, strict_mode);
-    }
-  }
-
-  // Call-back into JavaScript to convert the key to a string.
-  Handle<Object> converted;
-  ASSIGN_RETURN_ON_EXCEPTION(
-      isolate, converted, Execution::ToString(isolate, key), Object);
-  Handle<String> name = Handle<String>::cast(converted);
-
-  if (name->AsArrayIndex(&index)) {
-    // TODO(verwaest): Support non-JSObject receivers.
-    if (!object->IsJSObject()) return value;
-    Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-    return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
-                                true, SET_PROPERTY);
-  }
-  return Object::SetProperty(object, name, value, strict_mode);
-}
-
-
-MaybeHandle<Object> Runtime::DefineObjectProperty(Handle<JSObject> js_object,
-                                                  Handle<Object> key,
-                                                  Handle<Object> value,
-                                                  PropertyAttributes attr) {
-  Isolate* isolate = js_object->GetIsolate();
-  // Check if the given key is an array index.
-  uint32_t index;
-  if (key->ToArrayIndex(&index)) {
-    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
-    // of a string using [] notation.  We need to support this too in
-    // JavaScript.
-    // In the case of a String object we just need to redirect the assignment to
-    // the underlying string if the index is in range.  Since the underlying
-    // string does nothing with the assignment then we can ignore such
-    // assignments.
-    if (js_object->IsStringObjectWithCharacterAt(index)) {
-      return value;
-    }
-
-    return JSObject::SetElement(js_object, index, value, attr,
-                                SLOPPY, false, DEFINE_PROPERTY);
-  }
-
-  if (key->IsName()) {
-    Handle<Name> name = Handle<Name>::cast(key);
-    if (name->AsArrayIndex(&index)) {
-      return JSObject::SetElement(js_object, index, value, attr,
-                                  SLOPPY, false, DEFINE_PROPERTY);
-    } else {
-      if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
-      return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
-                                                      attr);
-    }
-  }
-
-  // Call-back into JavaScript to convert the key to a string.
-  Handle<Object> converted;
-  ASSIGN_RETURN_ON_EXCEPTION(
-      isolate, converted, Execution::ToString(isolate, key), Object);
-  Handle<String> name = Handle<String>::cast(converted);
-
-  if (name->AsArrayIndex(&index)) {
-    return JSObject::SetElement(js_object, index, value, attr,
-                                SLOPPY, false, DEFINE_PROPERTY);
-  } else {
-    return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
-                                                    attr);
-  }
-}
-
-
-MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
-                                                  Handle<JSReceiver> receiver,
-                                                  Handle<Object> key,
-                                                  JSReceiver::DeleteMode mode) {
-  // Check if the given key is an array index.
-  uint32_t index;
-  if (key->ToArrayIndex(&index)) {
-    // In Firefox/SpiderMonkey, Safari and Opera you can access the
-    // characters of a string using [] notation.  In the case of a
-    // String object we just need to redirect the deletion to the
-    // underlying string if the index is in range.  Since the
-    // underlying string does nothing with the deletion, we can ignore
-    // such deletions.
-    if (receiver->IsStringObjectWithCharacterAt(index)) {
-      return isolate->factory()->true_value();
-    }
-
-    return JSReceiver::DeleteElement(receiver, index, mode);
-  }
-
-  Handle<Name> name;
-  if (key->IsName()) {
-    name = Handle<Name>::cast(key);
-  } else {
-    // Call-back into JavaScript to convert the key to a string.
-    Handle<Object> converted;
-    ASSIGN_RETURN_ON_EXCEPTION(
-        isolate, converted, Execution::ToString(isolate, key), Object);
-    name = Handle<String>::cast(converted);
-  }
-
-  if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
-  return JSReceiver::DeleteProperty(receiver, name, mode);
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetHiddenProperty) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, key, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  RUNTIME_ASSERT(key->IsUniqueName());
-  return *JSObject::SetHiddenProperty(object, key, value);
-}
-
-
-RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 4);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
-  RUNTIME_ASSERT(
-      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
-  // Compute attributes.
-  PropertyAttributes attributes =
-      static_cast<PropertyAttributes>(unchecked_attributes);
-
-#ifdef DEBUG
-  uint32_t index = 0;
-  DCHECK(!key->ToArrayIndex(&index));
-  LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
-  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
-  if (!maybe.has_value) return isolate->heap()->exception();
-  RUNTIME_ASSERT(!it.IsFound());
-#endif
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      JSObject::SetOwnPropertyIgnoreAttributes(object, key, value, attributes));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_AddPropertyForTemplate) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 4);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
-  RUNTIME_ASSERT(
-      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
-  // Compute attributes.
-  PropertyAttributes attributes =
-      static_cast<PropertyAttributes>(unchecked_attributes);
-
-#ifdef DEBUG
-  bool duplicate;
-  if (key->IsName()) {
-    LookupIterator it(object, Handle<Name>::cast(key),
-                      LookupIterator::OWN_SKIP_INTERCEPTOR);
-    Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
-    DCHECK(maybe.has_value);
-    duplicate = it.IsFound();
-  } else {
-    uint32_t index = 0;
-    RUNTIME_ASSERT(key->ToArrayIndex(&index));
-    Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index);
-    if (!maybe.has_value) return isolate->heap()->exception();
-    duplicate = maybe.value;
-  }
-  if (duplicate) {
-    Handle<Object> args[1] = { key };
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate,
-        NewTypeError("duplicate_template_property", HandleVector(args, 1)));
-  }
-#endif
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Runtime::DefineObjectProperty(object, key, value, attributes));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetProperty) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 4);
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 3);
-  StrictMode strict_mode = strict_mode_arg;
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Runtime::SetObjectProperty(isolate, object, key, value, strict_mode));
-  return *result;
-}
-
-
-// Adds an element to an array.
-// This is used to create an indexed data property into an array.
-RUNTIME_FUNCTION(Runtime_AddElement) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 4);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
-  RUNTIME_ASSERT(
-      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
-  // Compute attributes.
-  PropertyAttributes attributes =
-      static_cast<PropertyAttributes>(unchecked_attributes);
-
-  uint32_t index = 0;
-  key->ToArrayIndex(&index);
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, JSObject::SetElement(object, index, value, attributes,
-                                            SLOPPY, false, DEFINE_PROPERTY));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_TransitionElementsKind) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
-  JSObject::TransitionElementsKind(array, map->elements_kind());
-  return *array;
-}
-
-
-// Set the native flag on the function.
-// This is used to decide if we should transform null and undefined
-// into the global object when doing call and apply.
-RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
-  SealHandleScope shs(isolate);
-  RUNTIME_ASSERT(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(Object, object, 0);
-
-  if (object->IsJSFunction()) {
-    JSFunction* func = JSFunction::cast(object);
-    func->shared()->set_native(true);
-  }
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) {
-  SealHandleScope shs(isolate);
-  RUNTIME_ASSERT(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-
-  if (object->IsJSFunction()) {
-    JSFunction* func = JSFunction::cast(*object);
-    func->shared()->set_inline_builtin(true);
-  }
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 5);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_SMI_ARG_CHECKED(store_index, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
-  CONVERT_SMI_ARG_CHECKED(literal_index, 4);
-
-  Object* raw_literal_cell = literals->get(literal_index);
-  JSArray* boilerplate = NULL;
-  if (raw_literal_cell->IsAllocationSite()) {
-    AllocationSite* site = AllocationSite::cast(raw_literal_cell);
-    boilerplate = JSArray::cast(site->transition_info());
-  } else {
-    boilerplate = JSArray::cast(raw_literal_cell);
-  }
-  Handle<JSArray> boilerplate_object(boilerplate);
-  ElementsKind elements_kind = object->GetElementsKind();
-  DCHECK(IsFastElementsKind(elements_kind));
-  // Smis should never trigger transitions.
-  DCHECK(!value->IsSmi());
-
-  if (value->IsNumber()) {
-    DCHECK(IsFastSmiElementsKind(elements_kind));
-    ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
-        ? FAST_HOLEY_DOUBLE_ELEMENTS
-        : FAST_DOUBLE_ELEMENTS;
-    if (IsMoreGeneralElementsKindTransition(
-            boilerplate_object->GetElementsKind(),
-            transitioned_kind)) {
-      JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
-    }
-    JSObject::TransitionElementsKind(object, transitioned_kind);
-    DCHECK(IsFastDoubleElementsKind(object->GetElementsKind()));
-    FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
-    HeapNumber* number = HeapNumber::cast(*value);
-    double_array->set(store_index, number->Number());
-  } else {
-    if (!IsFastObjectElementsKind(elements_kind)) {
-      ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
-          ? FAST_HOLEY_ELEMENTS
-          : FAST_ELEMENTS;
-      JSObject::TransitionElementsKind(object, transitioned_kind);
-      ElementsKind boilerplate_elements_kind =
-          boilerplate_object->GetElementsKind();
-      if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind,
-                                              transitioned_kind)) {
-        JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
-      }
-    }
-    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(Runtime_DebugCallbackSupportsStepping) {
-  DCHECK(args.length() == 1);
-  if (!isolate->debug()->is_active() || !isolate->debug()->StepInActive()) {
-    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.
-  return isolate->heap()->ToBoolean(
-      callback->IsJSFunction() && !JSFunction::cast(callback)->IsBuiltin());
-}
-
-
-// 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(Runtime_DebugPrepareStepInIfStepping) {
-  DCHECK(args.length() == 1);
-  Debug* debug = isolate->debug();
-  if (!debug->IsStepping()) return isolate->heap()->undefined_value();
-
-  HandleScope scope(isolate);
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-  RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject());
-  Handle<JSFunction> fun;
-  if (object->IsJSFunction()) {
-    fun = Handle<JSFunction>::cast(object);
-  } else {
-    fun = Handle<JSFunction>(
-        Handle<JSGeneratorObject>::cast(object)->function(), isolate);
-  }
-  // When leaving the function, step out has been activated, but not performed
-  // if we do not leave the builtin.  To be able to step into the function
-  // again, we need to clear the step out at this point.
-  debug->ClearStepOut();
-  debug->FloodWithOneShot(fun);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
-  DCHECK(args.length() == 1);
-  HandleScope scope(isolate);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
-  isolate->PushPromise(promise);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
-  DCHECK(args.length() == 0);
-  SealHandleScope shs(isolate);
-  isolate->PopPromise();
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
-  DCHECK(args.length() == 1);
-  HandleScope scope(isolate);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
-  isolate->debug()->OnPromiseEvent(data);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugPromiseRejectEvent) {
-  DCHECK(args.length() == 2);
-  HandleScope scope(isolate);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
-  isolate->debug()->OnPromiseReject(promise, value);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
-  DCHECK(args.length() == 1);
-  HandleScope scope(isolate);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
-  isolate->debug()->OnAsyncTaskEvent(data);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DeleteProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
-  JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
-      ? JSReceiver::STRICT_DELETION : JSReceiver::NORMAL_DELETION;
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      JSReceiver::DeleteProperty(object, key, delete_mode));
-  return *result;
-}
-
-
-static Object* HasOwnPropertyImplementation(Isolate* isolate,
-                                            Handle<JSObject> object,
-                                            Handle<Name> key) {
-  Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key);
-  if (!maybe.has_value) return isolate->heap()->exception();
-  if (maybe.value) return isolate->heap()->true_value();
-  // Handle hidden prototypes.  If there's a hidden prototype above this thing
-  // then we have to check it for properties, because they are supposed to
-  // look like they are on this object.
-  PrototypeIterator iter(isolate, object);
-  if (!iter.IsAtEnd() &&
-      Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))
-          ->map()
-          ->is_hidden_prototype()) {
-    // TODO(verwaest): The recursion is not necessary for keys that are array
-    // indices. Removing this.
-    return HasOwnPropertyImplementation(
-        isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
-        key);
-  }
-  RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-  return isolate->heap()->false_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-
-  uint32_t index;
-  const bool key_is_array_index = key->AsArrayIndex(&index);
-
-  // Only JS objects can have properties.
-  if (object->IsJSObject()) {
-    Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
-    // Fast case: either the key is a real named property or it is not
-    // an array index and there are no interceptors or hidden
-    // prototypes.
-    Maybe<bool> maybe = JSObject::HasRealNamedProperty(js_obj, key);
-    if (!maybe.has_value) return isolate->heap()->exception();
-    DCHECK(!isolate->has_pending_exception());
-    if (maybe.value) {
-      return isolate->heap()->true_value();
-    }
-    Map* map = js_obj->map();
-    if (!key_is_array_index &&
-        !map->has_named_interceptor() &&
-        !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
-      return isolate->heap()->false_value();
-    }
-    // Slow case.
-    return HasOwnPropertyImplementation(isolate,
-                                        Handle<JSObject>(js_obj),
-                                        Handle<Name>(key));
-  } else if (object->IsString() && key_is_array_index) {
-    // Well, there is one exception:  Handle [] on strings.
-    Handle<String> string = Handle<String>::cast(object);
-    if (index < static_cast<uint32_t>(string->length())) {
-      return isolate->heap()->true_value();
-    }
-  }
-  return isolate->heap()->false_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_HasProperty) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-
-  Maybe<bool> maybe = JSReceiver::HasProperty(receiver, key);
-  if (!maybe.has_value) return isolate->heap()->exception();
-  return isolate->heap()->ToBoolean(maybe.value);
-}
-
-
-RUNTIME_FUNCTION(Runtime_HasElement) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
-  CONVERT_SMI_ARG_CHECKED(index, 1);
-
-  Maybe<bool> maybe = JSReceiver::HasElement(receiver, index);
-  if (!maybe.has_value) return isolate->heap()->exception();
-  return isolate->heap()->ToBoolean(maybe.value);
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
-
-  Maybe<PropertyAttributes> maybe =
-      JSReceiver::GetOwnPropertyAttributes(object, key);
-  if (!maybe.has_value) return isolate->heap()->exception();
-  if (maybe.value == ABSENT) maybe.value = DONT_ENUM;
-  return isolate->heap()->ToBoolean((maybe.value & DONT_ENUM) == 0);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetPropertyNames) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
-  Handle<JSArray> result;
-
-  isolate->counters()->for_in()->Increment();
-  Handle<FixedArray> elements;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, elements,
-      JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
-  return *isolate->factory()->NewJSArrayWithElements(elements);
-}
-
-
-// Returns either a FixedArray as Runtime_GetPropertyNames,
-// or, if the given object has an enum cache that contains
-// all enumerable properties of the object and its prototypes
-// have none, the map of the object. This is used to speed up
-// the check for deletions during a for-in.
-RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
-
-  if (raw_object->IsSimpleEnum()) return raw_object->map();
-
-  HandleScope scope(isolate);
-  Handle<JSReceiver> object(raw_object);
-  Handle<FixedArray> content;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, content,
-      JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
-
-  // Test again, since cache may have been built by preceding call.
-  if (object->IsSimpleEnum()) return object->map();
-
-  return *content;
-}
-
-
-// Find the length of the prototype chain that is to be handled as one. If a
-// prototype object is hidden it is to be viewed as part of the the object it
-// is prototype for.
-static int OwnPrototypeChainLength(JSObject* obj) {
-  int count = 1;
-  for (PrototypeIterator iter(obj->GetIsolate(), obj);
-       !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
-    count++;
-  }
-  return count;
-}
-
-
-// Return the names of the own named properties.
-// args[0]: object
-// args[1]: PropertyAttributes as int
-RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  if (!args[0]->IsJSObject()) {
-    return isolate->heap()->undefined_value();
-  }
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  CONVERT_SMI_ARG_CHECKED(filter_value, 1);
-  PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
-
-  // Skip the global proxy as it has no properties and always delegates to the
-  // real global object.
-  if (obj->IsJSGlobalProxy()) {
-    // Only collect names if access is permitted.
-    if (obj->IsAccessCheckNeeded() &&
-        !isolate->MayNamedAccess(
-            obj, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
-      isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
-      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-      return *isolate->factory()->NewJSArray(0);
-    }
-    PrototypeIterator iter(isolate, obj);
-    obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
-  }
-
-  // Find the number of objects making up this.
-  int length = OwnPrototypeChainLength(*obj);
-
-  // Find the number of own properties for each of the objects.
-  ScopedVector<int> own_property_count(length);
-  int total_property_count = 0;
-  {
-    PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
-    for (int i = 0; i < length; i++) {
-      DCHECK(!iter.IsAtEnd());
-      Handle<JSObject> jsproto =
-          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
-      // Only collect names if access is permitted.
-      if (jsproto->IsAccessCheckNeeded() &&
-          !isolate->MayNamedAccess(jsproto,
-                                   isolate->factory()->undefined_value(),
-                                   v8::ACCESS_KEYS)) {
-        isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
-        RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-        return *isolate->factory()->NewJSArray(0);
-      }
-      int n;
-      n = jsproto->NumberOfOwnProperties(filter);
-      own_property_count[i] = n;
-      total_property_count += n;
-      iter.Advance();
-    }
-  }
-
-  // Allocate an array with storage for all the property names.
-  Handle<FixedArray> names =
-      isolate->factory()->NewFixedArray(total_property_count);
-
-  // Get the property names.
-  int next_copy_index = 0;
-  int hidden_strings = 0;
-  {
-    PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
-    for (int i = 0; i < length; i++) {
-      DCHECK(!iter.IsAtEnd());
-      Handle<JSObject> jsproto =
-          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
-      jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
-      if (i > 0) {
-        // Names from hidden prototypes may already have been added
-        // for inherited function template instances. Count the duplicates
-        // and stub them out; the final copy pass at the end ignores holes.
-        for (int j = next_copy_index;
-             j < next_copy_index + own_property_count[i]; j++) {
-          Object* name_from_hidden_proto = names->get(j);
-          for (int k = 0; k < next_copy_index; k++) {
-            if (names->get(k) != isolate->heap()->hidden_string()) {
-              Object* name = names->get(k);
-              if (name_from_hidden_proto == name) {
-                names->set(j, isolate->heap()->hidden_string());
-                hidden_strings++;
-                break;
-              }
-            }
-          }
-        }
-      }
-      next_copy_index += own_property_count[i];
-
-      // Hidden properties only show up if the filter does not skip strings.
-      if ((filter & STRING) == 0 && JSObject::HasHiddenProperties(jsproto)) {
-        hidden_strings++;
-      }
-      iter.Advance();
-    }
-  }
-
-  // Filter out name of hidden properties object and
-  // hidden prototype duplicates.
-  if (hidden_strings > 0) {
-    Handle<FixedArray> old_names = names;
-    names = isolate->factory()->NewFixedArray(
-        names->length() - hidden_strings);
-    int dest_pos = 0;
-    for (int i = 0; i < total_property_count; i++) {
-      Object* name = old_names->get(i);
-      if (name == isolate->heap()->hidden_string()) {
-        hidden_strings--;
-        continue;
-      }
-      names->set(dest_pos++, name);
-    }
-    DCHECK_EQ(0, hidden_strings);
-  }
-
-  return *isolate->factory()->NewJSArrayWithElements(names);
-}
-
-
-// Return the names of the own indexed properties.
-// args[0]: object
-RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  if (!args[0]->IsJSObject()) {
-    return isolate->heap()->undefined_value();
-  }
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-
-  int n = obj->NumberOfOwnElements(static_cast<PropertyAttributes>(NONE));
-  Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
-  obj->GetOwnElementKeys(*names, static_cast<PropertyAttributes>(NONE));
-  return *isolate->factory()->NewJSArrayWithElements(names);
-}
-
-
-// Return information on whether an object has a named or indexed interceptor.
-// args[0]: object
-RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  if (!args[0]->IsJSObject()) {
-    return Smi::FromInt(0);
-  }
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-
-  int result = 0;
-  if (obj->HasNamedInterceptor()) result |= 2;
-  if (obj->HasIndexedInterceptor()) result |= 1;
-
-  return Smi::FromInt(result);
-}
-
-
-// Return property names from named interceptor.
-// args[0]: object
-RUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-
-  if (obj->HasNamedInterceptor()) {
-    Handle<JSObject> result;
-    if (JSObject::GetKeysForNamedInterceptor(obj, obj).ToHandle(&result)) {
-      return *result;
-    }
-  }
-  return isolate->heap()->undefined_value();
-}
-
-
-// Return element names from indexed interceptor.
-// args[0]: object
-RUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-
-  if (obj->HasIndexedInterceptor()) {
-    Handle<JSObject> result;
-    if (JSObject::GetKeysForIndexedInterceptor(obj, obj).ToHandle(&result)) {
-      return *result;
-    }
-  }
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_OwnKeys) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
-  Handle<JSObject> object(raw_object);
-
-  if (object->IsJSGlobalProxy()) {
-    // Do access checks before going to the global object.
-    if (object->IsAccessCheckNeeded() &&
-        !isolate->MayNamedAccess(
-            object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) {
-      isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
-      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
-      return *isolate->factory()->NewJSArray(0);
-    }
-
-    PrototypeIterator iter(isolate, object);
-    // If proxy is detached we simply return an empty array.
-    if (iter.IsAtEnd()) return *isolate->factory()->NewJSArray(0);
-    object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
-  }
-
-  Handle<FixedArray> contents;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, contents,
-      JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY));
-
-  // Some fast paths through GetKeysInFixedArrayFor reuse a cached
-  // property array and since the result is mutable we have to create
-  // a fresh clone on each invocation.
-  int length = contents->length();
-  Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
-  for (int i = 0; i < length; i++) {
-    Object* entry = contents->get(i);
-    if (entry->IsString()) {
-      copy->set(i, entry);
-    } else {
-      DCHECK(entry->IsNumber());
-      HandleScope scope(isolate);
-      Handle<Object> entry_handle(entry, isolate);
-      Handle<Object> entry_str =
-          isolate->factory()->NumberToString(entry_handle);
-      copy->set(i, *entry_str);
-    }
-  }
-  return *isolate->factory()->NewJSArrayWithElements(copy);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
-
-  // Compute the frame holding the arguments.
-  JavaScriptFrameIterator it(isolate);
-  it.AdvanceToArgumentsFrame();
-  JavaScriptFrame* frame = it.frame();
-
-  // Get the actual number of provided arguments.
-  const uint32_t n = frame->ComputeParametersCount();
-
-  // Try to convert the key to an index. If successful and within
-  // index return the the argument from the frame.
-  uint32_t index;
-  if (raw_key->ToArrayIndex(&index) && index < n) {
-    return frame->GetParameter(index);
-  }
-
-  HandleScope scope(isolate);
-  if (raw_key->IsSymbol()) {
-    Handle<Symbol> symbol = Handle<Symbol>::cast(raw_key);
-    if (symbol->Equals(isolate->native_context()->iterator_symbol())) {
-      return isolate->native_context()->array_values_iterator();
-    }
-    // Lookup in the initial Object.prototype object.
-    Handle<Object> result;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, result,
-        Object::GetProperty(isolate->initial_object_prototype(),
-                            Handle<Symbol>::cast(raw_key)));
-    return *result;
-  }
-
-  // Convert the key to a string.
-  Handle<Object> converted;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, converted, Execution::ToString(isolate, raw_key));
-  Handle<String> key = Handle<String>::cast(converted);
-
-  // Try to convert the string key into an array index.
-  if (key->AsArrayIndex(&index)) {
-    if (index < n) {
-      return frame->GetParameter(index);
-    } else {
-      Handle<Object> initial_prototype(isolate->initial_object_prototype());
-      Handle<Object> result;
-      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-          isolate, result,
-          Object::GetElement(isolate, initial_prototype, index));
-      return *result;
-    }
-  }
-
-  // Handle special arguments properties.
-  if (String::Equals(isolate->factory()->length_string(), key)) {
-    return Smi::FromInt(n);
-  }
-  if (String::Equals(isolate->factory()->callee_string(), key)) {
-    JSFunction* function = frame->function();
-    if (function->shared()->strict_mode() == STRICT) {
-      THROW_NEW_ERROR_RETURN_FAILURE(
-          isolate, NewTypeError("strict_arguments_callee",
-                                HandleVector<Object>(NULL, 0)));
-    }
-    return function;
-  }
-
-  // Lookup in the initial Object.prototype object.
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Object::GetProperty(isolate->initial_object_prototype(), key));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_ToFastProperties) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-  if (object->IsJSObject() && !object->IsGlobalObject()) {
-    JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0);
-  }
-  return *object;
-}
-
-
-RUNTIME_FUNCTION(Runtime_ToBool) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, object, 0);
-
-  return isolate->heap()->ToBoolean(object->BooleanValue());
-}
-
-
-// Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
-// Possible optimizations: put the type string into the oddballs.
-RUNTIME_FUNCTION(Runtime_Typeof) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  if (obj->IsNumber()) return isolate->heap()->number_string();
-  HeapObject* heap_obj = HeapObject::cast(obj);
-
-  // typeof an undetectable object is 'undefined'
-  if (heap_obj->map()->is_undetectable()) {
-    return isolate->heap()->undefined_string();
-  }
-
-  InstanceType instance_type = heap_obj->map()->instance_type();
-  if (instance_type < FIRST_NONSTRING_TYPE) {
-    return isolate->heap()->string_string();
-  }
-
-  switch (instance_type) {
-    case ODDBALL_TYPE:
-      if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
-        return isolate->heap()->boolean_string();
-      }
-      if (heap_obj->IsNull()) {
-        return isolate->heap()->object_string();
-      }
-      DCHECK(heap_obj->IsUndefined());
-      return isolate->heap()->undefined_string();
-    case SYMBOL_TYPE:
-      return isolate->heap()->symbol_string();
-    case JS_FUNCTION_TYPE:
-    case JS_FUNCTION_PROXY_TYPE:
-      return isolate->heap()->function_string();
-    default:
-      // For any kind of object not handled above, the spec rule for
-      // host objects gives that it is okay to return "object"
-      return isolate->heap()->object_string();
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_Booleanize) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(Object, value_raw, 0);
-  CONVERT_SMI_ARG_CHECKED(token_raw, 1);
-  intptr_t value = reinterpret_cast<intptr_t>(value_raw);
-  Token::Value token = static_cast<Token::Value>(token_raw);
-  switch (token) {
-    case Token::EQ:
-    case Token::EQ_STRICT:
-      return isolate->heap()->ToBoolean(value == 0);
-    case Token::NE:
-    case Token::NE_STRICT:
-      return isolate->heap()->ToBoolean(value != 0);
-    case Token::LT:
-      return isolate->heap()->ToBoolean(value < 0);
-    case Token::GT:
-      return isolate->heap()->ToBoolean(value > 0);
-    case Token::LTE:
-      return isolate->heap()->ToBoolean(value <= 0);
-    case Token::GTE:
-      return isolate->heap()->ToBoolean(value >= 0);
-    default:
-      // This should only happen during natives fuzzing.
-      return isolate->heap()->undefined_value();
-  }
-}
-
-
-static bool AreDigits(const uint8_t*s, int from, int to) {
-  for (int i = from; i < to; i++) {
-    if (s[i] < '0' || s[i] > '9') return false;
-  }
-
-  return true;
-}
-
-
-static int ParseDecimalInteger(const uint8_t*s, int from, int to) {
-  DCHECK(to - from < 10);  // Overflow is not possible.
-  DCHECK(from < to);
-  int d = s[from] - '0';
-
-  for (int i = from + 1; i < to; i++) {
-    d = 10 * d + (s[i] - '0');
-  }
-
-  return d;
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringToNumber) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
-  subject = String::Flatten(subject);
-
-  // Fast case: short integer or some sorts of junk values.
-  if (subject->IsSeqOneByteString()) {
-    int len = subject->length();
-    if (len == 0) return Smi::FromInt(0);
-
-    DisallowHeapAllocation no_gc;
-    uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
-    bool minus = (data[0] == '-');
-    int start_pos = (minus ? 1 : 0);
-
-    if (start_pos == len) {
-      return isolate->heap()->nan_value();
-    } else if (data[start_pos] > '9') {
-      // Fast check for a junk value. A valid string may start from a
-      // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
-      // or the 'I' character ('Infinity'). All of that have codes not greater
-      // than '9' except 'I' and &nbsp;.
-      if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
-        return isolate->heap()->nan_value();
-      }
-    } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
-      // The maximal/minimal smi has 10 digits. If the string has less digits
-      // we know it will fit into the smi-data type.
-      int d = ParseDecimalInteger(data, start_pos, len);
-      if (minus) {
-        if (d == 0) return isolate->heap()->minus_zero_value();
-        d = -d;
-      } else if (!subject->HasHashCode() &&
-                 len <= String::kMaxArrayIndexSize &&
-                 (len == 1 || data[0] != '0')) {
-        // String hash is not calculated yet but all the data are present.
-        // Update the hash field to speed up sequential convertions.
-        uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
-#ifdef DEBUG
-        subject->Hash();  // Force hash calculation.
-        DCHECK_EQ(static_cast<int>(subject->hash_field()),
-                  static_cast<int>(hash));
-#endif
-        subject->set_hash_field(hash);
-      }
-      return Smi::FromInt(d);
-    }
-  }
-
-  // Slower case.
-  int flags = ALLOW_HEX;
-  if (FLAG_harmony_numeric_literals) {
-    // The current spec draft has not updated "ToNumber Applied to the String
-    // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
-    flags |= ALLOW_OCTAL | ALLOW_BINARY;
-  }
-
-  return *isolate->factory()->NewNumber(StringToDouble(
-      isolate->unicode_cache(), *subject, flags));
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewString) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_INT32_ARG_CHECKED(length, 0);
-  CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
-  if (length == 0) return isolate->heap()->empty_string();
-  Handle<String> result;
-  if (is_one_byte) {
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, result, isolate->factory()->NewRawOneByteString(length));
-  } else {
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, result, isolate->factory()->NewRawTwoByteString(length));
-  }
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_TruncateString) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
-  CONVERT_INT32_ARG_CHECKED(new_length, 1);
-  RUNTIME_ASSERT(new_length >= 0);
-  return *SeqString::Truncate(string, new_length);
-}
-
-
-RUNTIME_FUNCTION(Runtime_URIEscape) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
-  Handle<String> string = String::Flatten(source);
-  DCHECK(string->IsFlat());
-  Handle<String> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      string->IsOneByteRepresentationUnderneath()
-            ? URIEscape::Escape<uint8_t>(isolate, source)
-            : URIEscape::Escape<uc16>(isolate, source));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_URIUnescape) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
-  Handle<String> string = String::Flatten(source);
-  DCHECK(string->IsFlat());
-  Handle<String> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      string->IsOneByteRepresentationUnderneath()
-            ? URIUnescape::Unescape<uint8_t>(isolate, source)
-            : URIUnescape::Unescape<uc16>(isolate, source));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_QuoteJSONString) {
-  HandleScope scope(isolate);
-  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
-  DCHECK(args.length() == 1);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, BasicJsonStringifier::StringifyString(isolate, string));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_BasicJSONStringify) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-  BasicJsonStringifier stringifier(isolate);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, stringifier.Stringify(object));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringParseInt) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
-  CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
-  RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
-
-  subject = String::Flatten(subject);
-  double value;
-
-  { DisallowHeapAllocation no_gc;
-    String::FlatContent flat = subject->GetFlatContent();
-
-    // ECMA-262 section 15.1.2.3, empty string is NaN
-    if (flat.IsOneByte()) {
-      value = StringToInt(
-          isolate->unicode_cache(), flat.ToOneByteVector(), radix);
-    } else {
-      value = StringToInt(
-          isolate->unicode_cache(), flat.ToUC16Vector(), radix);
-    }
-  }
-
-  return *isolate->factory()->NewNumber(value);
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringParseFloat) {
-  HandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
-
-  subject = String::Flatten(subject);
-  double value = StringToDouble(isolate->unicode_cache(), *subject,
-                                ALLOW_TRAILING_JUNK, base::OS::nan_value());
-
-  return *isolate->factory()->NewNumber(value);
-}
-
-
-static inline bool ToUpperOverflows(uc32 character) {
-  // y with umlauts and the micro sign are the only characters that stop
-  // fitting into one-byte when converting to uppercase.
-  static const uc32 yuml_code = 0xff;
-  static const uc32 micro_code = 0xb5;
-  return (character == yuml_code || character == micro_code);
-}
-
-
-template <class Converter>
-MUST_USE_RESULT static Object* ConvertCaseHelper(
-    Isolate* isolate,
-    String* string,
-    SeqString* result,
-    int result_length,
-    unibrow::Mapping<Converter, 128>* mapping) {
-  DisallowHeapAllocation no_gc;
-  // We try this twice, once with the assumption that the result is no longer
-  // than the input and, if that assumption breaks, again with the exact
-  // length.  This may not be pretty, but it is nicer than what was here before
-  // and I hereby claim my vaffel-is.
-  //
-  // NOTE: This assumes that the upper/lower case of an ASCII
-  // character is also ASCII.  This is currently the case, but it
-  // might break in the future if we implement more context and locale
-  // dependent upper/lower conversions.
-  bool has_changed_character = false;
-
-  // Convert all characters to upper case, assuming that they will fit
-  // in the buffer
-  Access<ConsStringIteratorOp> op(
-      isolate->runtime_state()->string_iterator());
-  StringCharacterStream stream(string, op.value());
-  unibrow::uchar chars[Converter::kMaxWidth];
-  // We can assume that the string is not empty
-  uc32 current = stream.GetNext();
-  bool ignore_overflow = Converter::kIsToLower || result->IsSeqTwoByteString();
-  for (int i = 0; i < result_length;) {
-    bool has_next = stream.HasMore();
-    uc32 next = has_next ? stream.GetNext() : 0;
-    int char_length = mapping->get(current, next, chars);
-    if (char_length == 0) {
-      // The case conversion of this character is the character itself.
-      result->Set(i, current);
-      i++;
-    } else if (char_length == 1 &&
-               (ignore_overflow || !ToUpperOverflows(current))) {
-      // Common case: converting the letter resulted in one character.
-      DCHECK(static_cast<uc32>(chars[0]) != current);
-      result->Set(i, chars[0]);
-      has_changed_character = true;
-      i++;
-    } else if (result_length == string->length()) {
-      bool overflows = ToUpperOverflows(current);
-      // We've assumed that the result would be as long as the
-      // input but here is a character that converts to several
-      // characters.  No matter, we calculate the exact length
-      // of the result and try the whole thing again.
-      //
-      // Note that this leaves room for optimization.  We could just
-      // memcpy what we already have to the result string.  Also,
-      // the result string is the last object allocated we could
-      // "realloc" it and probably, in the vast majority of cases,
-      // extend the existing string to be able to hold the full
-      // result.
-      int next_length = 0;
-      if (has_next) {
-        next_length = mapping->get(next, 0, chars);
-        if (next_length == 0) next_length = 1;
-      }
-      int current_length = i + char_length + next_length;
-      while (stream.HasMore()) {
-        current = stream.GetNext();
-        overflows |= ToUpperOverflows(current);
-        // NOTE: we use 0 as the next character here because, while
-        // the next character may affect what a character converts to,
-        // it does not in any case affect the length of what it convert
-        // to.
-        int char_length = mapping->get(current, 0, chars);
-        if (char_length == 0) char_length = 1;
-        current_length += char_length;
-        if (current_length > String::kMaxLength) {
-          AllowHeapAllocation allocate_error_and_return;
-          THROW_NEW_ERROR_RETURN_FAILURE(isolate,
-                                         NewInvalidStringLengthError());
-        }
-      }
-      // Try again with the real length.  Return signed if we need
-      // to allocate a two-byte string for to uppercase.
-      return (overflows && !ignore_overflow) ? Smi::FromInt(-current_length)
-                                             : Smi::FromInt(current_length);
-    } else {
-      for (int j = 0; j < char_length; j++) {
-        result->Set(i, chars[j]);
-        i++;
-      }
-      has_changed_character = true;
-    }
-    current = next;
-  }
-  if (has_changed_character) {
-    return result;
-  } else {
-    // If we didn't actually change anything in doing the conversion
-    // we simple return the result and let the converted string
-    // become garbage; there is no reason to keep two identical strings
-    // alive.
-    return string;
-  }
-}
-
-
-namespace {
-
-static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
-static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
-
-// Given a word and two range boundaries returns a word with high bit
-// set in every byte iff the corresponding input byte was strictly in
-// the range (m, n). All the other bits in the result are cleared.
-// This function is only useful when it can be inlined and the
-// boundaries are statically known.
-// Requires: all bytes in the input word and the boundaries must be
-// ASCII (less than 0x7F).
-static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
-  // Use strict inequalities since in edge cases the function could be
-  // further simplified.
-  DCHECK(0 < m && m < n);
-  // Has high bit set in every w byte less than n.
-  uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
-  // Has high bit set in every w byte greater than m.
-  uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
-  return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
-}
-
-
-#ifdef DEBUG
-static bool CheckFastAsciiConvert(char* dst,
-                                  const char* src,
-                                  int length,
-                                  bool changed,
-                                  bool is_to_lower) {
-  bool expected_changed = false;
-  for (int i = 0; i < length; i++) {
-    if (dst[i] == src[i]) continue;
-    expected_changed = true;
-    if (is_to_lower) {
-      DCHECK('A' <= src[i] && src[i] <= 'Z');
-      DCHECK(dst[i] == src[i] + ('a' - 'A'));
-    } else {
-      DCHECK('a' <= src[i] && src[i] <= 'z');
-      DCHECK(dst[i] == src[i] - ('a' - 'A'));
-    }
-  }
-  return (expected_changed == changed);
-}
-#endif
-
-
-template<class Converter>
-static bool FastAsciiConvert(char* dst,
-                             const char* src,
-                             int length,
-                             bool* changed_out) {
-#ifdef DEBUG
-    char* saved_dst = dst;
-    const char* saved_src = src;
-#endif
-  DisallowHeapAllocation no_gc;
-  // We rely on the distance between upper and lower case letters
-  // being a known power of 2.
-  DCHECK('a' - 'A' == (1 << 5));
-  // Boundaries for the range of input characters than require conversion.
-  static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
-  static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
-  bool changed = false;
-  uintptr_t or_acc = 0;
-  const char* const limit = src + length;
-
-  // dst is newly allocated and always aligned.
-  DCHECK(IsAligned(reinterpret_cast<intptr_t>(dst), sizeof(uintptr_t)));
-  // Only attempt processing one word at a time if src is also aligned.
-  if (IsAligned(reinterpret_cast<intptr_t>(src), sizeof(uintptr_t))) {
-    // Process the prefix of the input that requires no conversion one aligned
-    // (machine) word at a time.
-    while (src <= limit - sizeof(uintptr_t)) {
-      const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
-      or_acc |= w;
-      if (AsciiRangeMask(w, lo, hi) != 0) {
-        changed = true;
-        break;
-      }
-      *reinterpret_cast<uintptr_t*>(dst) = w;
-      src += sizeof(uintptr_t);
-      dst += sizeof(uintptr_t);
-    }
-    // Process the remainder of the input performing conversion when
-    // required one word at a time.
-    while (src <= limit - sizeof(uintptr_t)) {
-      const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
-      or_acc |= w;
-      uintptr_t m = AsciiRangeMask(w, lo, hi);
-      // The mask has high (7th) bit set in every byte that needs
-      // conversion and we know that the distance between cases is
-      // 1 << 5.
-      *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
-      src += sizeof(uintptr_t);
-      dst += sizeof(uintptr_t);
-    }
-  }
-  // Process the last few bytes of the input (or the whole input if
-  // unaligned access is not supported).
-  while (src < limit) {
-    char c = *src;
-    or_acc |= c;
-    if (lo < c && c < hi) {
-      c ^= (1 << 5);
-      changed = true;
-    }
-    *dst = c;
-    ++src;
-    ++dst;
-  }
-
-  if ((or_acc & kAsciiMask) != 0) return false;
-
-  DCHECK(CheckFastAsciiConvert(
-             saved_dst, saved_src, length, changed, Converter::kIsToLower));
-
-  *changed_out = changed;
-  return true;
-}
-
-}  // namespace
-
-
-template <class Converter>
-MUST_USE_RESULT static Object* ConvertCase(
-    Handle<String> s,
-    Isolate* isolate,
-    unibrow::Mapping<Converter, 128>* mapping) {
-  s = String::Flatten(s);
-  int length = s->length();
-  // Assume that the string is not empty; we need this assumption later
-  if (length == 0) return *s;
-
-  // Simpler handling of ASCII strings.
-  //
-  // NOTE: This assumes that the upper/lower case of an ASCII
-  // character is also ASCII.  This is currently the case, but it
-  // might break in the future if we implement more context and locale
-  // dependent upper/lower conversions.
-  if (s->IsOneByteRepresentationUnderneath()) {
-    // Same length as input.
-    Handle<SeqOneByteString> result =
-        isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
-    DisallowHeapAllocation no_gc;
-    String::FlatContent flat_content = s->GetFlatContent();
-    DCHECK(flat_content.IsFlat());
-    bool has_changed_character = false;
-    bool is_ascii = FastAsciiConvert<Converter>(
-        reinterpret_cast<char*>(result->GetChars()),
-        reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()),
-        length,
-        &has_changed_character);
-    // If not ASCII, we discard the result and take the 2 byte path.
-    if (is_ascii) return has_changed_character ? *result : *s;
-  }
-
-  Handle<SeqString> result;  // Same length as input.
-  if (s->IsOneByteRepresentation()) {
-    result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
-  } else {
-    result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked();
-  }
-
-  Object* answer = ConvertCaseHelper(isolate, *s, *result, length, mapping);
-  if (answer->IsException() || answer->IsString()) return answer;
-
-  DCHECK(answer->IsSmi());
-  length = Smi::cast(answer)->value();
-  if (s->IsOneByteRepresentation() && length > 0) {
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, result, isolate->factory()->NewRawOneByteString(length));
-  } else {
-    if (length < 0) length = -length;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, result, isolate->factory()->NewRawTwoByteString(length));
-  }
-  return ConvertCaseHelper(isolate, *s, *result, length, mapping);
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringToLowerCase) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
-  return ConvertCase(
-      s, isolate, isolate->runtime_state()->to_lower_mapping());
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringToUpperCase) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
-  return ConvertCase(
-      s, isolate, isolate->runtime_state()->to_upper_mapping());
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringTrim) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
-  CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
-  CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
-
-  string = String::Flatten(string);
-  int length = string->length();
-
-  int left = 0;
-  UnicodeCache* unicode_cache = isolate->unicode_cache();
-  if (trimLeft) {
-    while (left < length &&
-           unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
-      left++;
-    }
-  }
-
-  int right = length;
-  if (trimRight) {
-    while (right > left &&
-           unicode_cache->IsWhiteSpaceOrLineTerminator(
-               string->Get(right - 1))) {
-      right--;
-    }
-  }
-
-  return *isolate->factory()->NewSubString(string, left, right);
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringSplit) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
-  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
-  RUNTIME_ASSERT(limit > 0);
-
-  int subject_length = subject->length();
-  int pattern_length = pattern->length();
-  RUNTIME_ASSERT(pattern_length > 0);
-
-  if (limit == 0xffffffffu) {
-    Handle<Object> cached_answer(
-        RegExpResultsCache::Lookup(isolate->heap(),
-                                   *subject,
-                                   *pattern,
-                                   RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
-        isolate);
-    if (*cached_answer != Smi::FromInt(0)) {
-      // The cache FixedArray is a COW-array and can therefore be reused.
-      Handle<JSArray> result =
-          isolate->factory()->NewJSArrayWithElements(
-              Handle<FixedArray>::cast(cached_answer));
-      return *result;
-    }
-  }
-
-  // The limit can be very large (0xffffffffu), but since the pattern
-  // isn't empty, we can never create more parts than ~half the length
-  // of the subject.
-
-  subject = String::Flatten(subject);
-  pattern = String::Flatten(pattern);
-
-  static const int kMaxInitialListCapacity = 16;
-
-  ZoneScope zone_scope(isolate->runtime_zone());
-
-  // Find (up to limit) indices of separator and end-of-string in subject
-  int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
-  ZoneList<int> indices(initial_capacity, zone_scope.zone());
-
-  FindStringIndicesDispatch(isolate, *subject, *pattern,
-                            &indices, limit, zone_scope.zone());
-
-  if (static_cast<uint32_t>(indices.length()) < limit) {
-    indices.Add(subject_length, zone_scope.zone());
-  }
-
-  // The list indices now contains the end of each part to create.
-
-  // Create JSArray of substrings separated by separator.
-  int part_count = indices.length();
-
-  Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
-  JSObject::EnsureCanContainHeapObjectElements(result);
-  result->set_length(Smi::FromInt(part_count));
-
-  DCHECK(result->HasFastObjectElements());
-
-  if (part_count == 1 && indices.at(0) == subject_length) {
-    FixedArray::cast(result->elements())->set(0, *subject);
-    return *result;
-  }
-
-  Handle<FixedArray> elements(FixedArray::cast(result->elements()));
-  int part_start = 0;
-  for (int i = 0; i < part_count; i++) {
-    HandleScope local_loop_handle(isolate);
-    int part_end = indices.at(i);
-    Handle<String> substring =
-        isolate->factory()->NewProperSubString(subject, part_start, part_end);
-    elements->set(i, *substring);
-    part_start = part_end + pattern_length;
-  }
-
-  if (limit == 0xffffffffu) {
-    if (result->HasFastObjectElements()) {
-      RegExpResultsCache::Enter(isolate,
-                                subject,
-                                pattern,
-                                elements,
-                                RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
-    }
-  }
-
-  return *result;
-}
-
-
-// Copies Latin1 characters to the given fixed array looking up
-// one-char strings in the cache. Gives up on the first char that is
-// not in the cache and fills the remainder with smi zeros. Returns
-// the length of the successfully copied prefix.
-static int CopyCachedOneByteCharsToArray(Heap* heap, const uint8_t* chars,
-                                         FixedArray* elements, int length) {
-  DisallowHeapAllocation no_gc;
-  FixedArray* one_byte_cache = heap->single_character_string_cache();
-  Object* undefined = heap->undefined_value();
-  int i;
-  WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
-  for (i = 0; i < length; ++i) {
-    Object* value = one_byte_cache->get(chars[i]);
-    if (value == undefined) break;
-    elements->set(i, value, mode);
-  }
-  if (i < length) {
-    DCHECK(Smi::FromInt(0) == 0);
-    memset(elements->data_start() + i, 0, kPointerSize * (length - i));
-  }
-#ifdef DEBUG
-  for (int j = 0; j < length; ++j) {
-    Object* element = elements->get(j);
-    DCHECK(element == Smi::FromInt(0) ||
-           (element->IsString() && String::cast(element)->LooksValid()));
-  }
-#endif
-  return i;
-}
-
-
-// Converts a String to JSArray.
-// For example, "foo" => ["f", "o", "o"].
-RUNTIME_FUNCTION(Runtime_StringToArray) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
-  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
-
-  s = String::Flatten(s);
-  const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
-
-  Handle<FixedArray> elements;
-  int position = 0;
-  if (s->IsFlat() && s->IsOneByteRepresentation()) {
-    // Try using cached chars where possible.
-    elements = isolate->factory()->NewUninitializedFixedArray(length);
-
-    DisallowHeapAllocation no_gc;
-    String::FlatContent content = s->GetFlatContent();
-    if (content.IsOneByte()) {
-      Vector<const uint8_t> chars = content.ToOneByteVector();
-      // Note, this will initialize all elements (not only the prefix)
-      // to prevent GC from seeing partially initialized array.
-      position = CopyCachedOneByteCharsToArray(isolate->heap(), chars.start(),
-                                               *elements, length);
-    } else {
-      MemsetPointer(elements->data_start(),
-                    isolate->heap()->undefined_value(),
-                    length);
-    }
-  } else {
-    elements = isolate->factory()->NewFixedArray(length);
-  }
-  for (int i = position; i < length; ++i) {
-    Handle<Object> str =
-        isolate->factory()->LookupSingleCharacterStringFromCode(s->Get(i));
-    elements->set(i, *str);
-  }
-
-#ifdef DEBUG
-  for (int i = 0; i < length; ++i) {
-    DCHECK(String::cast(elements->get(i))->length() == 1);
-  }
-#endif
-
-  return *isolate->factory()->NewJSArrayWithElements(elements);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewStringWrapper) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
-  return *Object::ToObject(isolate, value).ToHandleChecked();
-}
-
-
-bool Runtime::IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch) {
-  unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
-  int char_length = runtime_state->to_upper_mapping()->get(ch, 0, chars);
-  return char_length == 0;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToStringRT) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
-
-  return *isolate->factory()->NumberToString(number);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToStringSkipCache) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
-
-  return *isolate->factory()->NumberToString(number, false);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToInteger) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
-  return *isolate->factory()->NewNumber(DoubleToInteger(number));
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
-  double double_value = DoubleToInteger(number);
-  // Map both -0 and +0 to +0.
-  if (double_value == 0) double_value = 0;
-
-  return *isolate->factory()->NewNumber(double_value);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
-  return *isolate->factory()->NewNumberFromUint(number);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
-  return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
-}
-
-
-// Converts a Number to a Smi, if possible. Returns NaN if the number is not
-// a small integer.
-RUNTIME_FUNCTION(Runtime_NumberToSmi) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  if (obj->IsSmi()) {
-    return obj;
-  }
-  if (obj->IsHeapNumber()) {
-    double value = HeapNumber::cast(obj)->value();
-    int int_value = FastD2I(value);
-    if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
-      return Smi::FromInt(int_value);
-    }
-  }
-  return isolate->heap()->nan_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  return *isolate->factory()->NewHeapNumber(0);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberAdd) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  return *isolate->factory()->NewNumber(x + y);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberSub) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  return *isolate->factory()->NewNumber(x - y);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberMul) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  return *isolate->factory()->NewNumber(x * y);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  return *isolate->factory()->NewNumber(-x);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberDiv) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  return *isolate->factory()->NewNumber(x / y);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberMod) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  return *isolate->factory()->NewNumber(modulo(x, y));
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberImul) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  // We rely on implementation-defined behavior below, but at least not on
-  // undefined behavior.
-  CONVERT_NUMBER_CHECKED(uint32_t, x, Int32, args[0]);
-  CONVERT_NUMBER_CHECKED(uint32_t, y, Int32, args[1]);
-  int32_t product = static_cast<int32_t>(x * y);
-  return *isolate->factory()->NewNumberFromInt(product);
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringAdd) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
-  isolate->counters()->string_add_runtime()->Increment();
-  Handle<String> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, isolate->factory()->NewConsString(str1, str2));
-  return *result;
-}
-
-
-template <typename sinkchar>
-static inline void StringBuilderConcatHelper(String* special,
-                                             sinkchar* sink,
-                                             FixedArray* fixed_array,
-                                             int array_length) {
-  DisallowHeapAllocation no_gc;
-  int position = 0;
-  for (int i = 0; i < array_length; i++) {
-    Object* element = fixed_array->get(i);
-    if (element->IsSmi()) {
-      // Smi encoding of position and length.
-      int encoded_slice = Smi::cast(element)->value();
-      int pos;
-      int len;
-      if (encoded_slice > 0) {
-        // Position and length encoded in one smi.
-        pos = StringBuilderSubstringPosition::decode(encoded_slice);
-        len = StringBuilderSubstringLength::decode(encoded_slice);
-      } else {
-        // Position and length encoded in two smis.
-        Object* obj = fixed_array->get(++i);
-        DCHECK(obj->IsSmi());
-        pos = Smi::cast(obj)->value();
-        len = -encoded_slice;
-      }
-      String::WriteToFlat(special,
-                          sink + position,
-                          pos,
-                          pos + len);
-      position += len;
-    } else {
-      String* string = String::cast(element);
-      int element_length = string->length();
-      String::WriteToFlat(string, sink + position, 0, element_length);
-      position += element_length;
-    }
-  }
-}
-
-
-// Returns the result length of the concatenation.
-// On illegal argument, -1 is returned.
-static inline int StringBuilderConcatLength(int special_length,
-                                            FixedArray* fixed_array,
-                                            int array_length,
-                                            bool* one_byte) {
-  DisallowHeapAllocation no_gc;
-  int position = 0;
-  for (int i = 0; i < array_length; i++) {
-    int increment = 0;
-    Object* elt = fixed_array->get(i);
-    if (elt->IsSmi()) {
-      // Smi encoding of position and length.
-      int smi_value = Smi::cast(elt)->value();
-      int pos;
-      int len;
-      if (smi_value > 0) {
-        // Position and length encoded in one smi.
-        pos = StringBuilderSubstringPosition::decode(smi_value);
-        len = StringBuilderSubstringLength::decode(smi_value);
-      } else {
-        // Position and length encoded in two smis.
-        len = -smi_value;
-        // Get the position and check that it is a positive smi.
-        i++;
-        if (i >= array_length) return -1;
-        Object* next_smi = fixed_array->get(i);
-        if (!next_smi->IsSmi()) return -1;
-        pos = Smi::cast(next_smi)->value();
-        if (pos < 0) return -1;
-      }
-      DCHECK(pos >= 0);
-      DCHECK(len >= 0);
-      if (pos > special_length || len > special_length - pos) return -1;
-      increment = len;
-    } else if (elt->IsString()) {
-      String* element = String::cast(elt);
-      int element_length = element->length();
-      increment = element_length;
-      if (*one_byte && !element->HasOnlyOneByteChars()) {
-        *one_byte = false;
-      }
-    } else {
-      return -1;
-    }
-    if (increment > String::kMaxLength - position) {
-      return kMaxInt;  // Provoke throw on allocation.
-    }
-    position += increment;
-  }
-  return position;
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
-  int32_t array_length;
-  if (!args[1]->ToInt32(&array_length)) {
-    THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
-  }
-  CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
-
-  size_t actual_array_length = 0;
-  RUNTIME_ASSERT(
-      TryNumberToSize(isolate, array->length(), &actual_array_length));
-  RUNTIME_ASSERT(array_length >= 0);
-  RUNTIME_ASSERT(static_cast<size_t>(array_length) <= actual_array_length);
-
-  // This assumption is used by the slice encoding in one or two smis.
-  DCHECK(Smi::kMaxValue >= String::kMaxLength);
-
-  RUNTIME_ASSERT(array->HasFastElements());
-  JSObject::EnsureCanContainHeapObjectElements(array);
-
-  int special_length = special->length();
-  if (!array->HasFastObjectElements()) {
-    return isolate->Throw(isolate->heap()->illegal_argument_string());
-  }
-
-  int length;
-  bool one_byte = special->HasOnlyOneByteChars();
-
-  { DisallowHeapAllocation no_gc;
-    FixedArray* fixed_array = FixedArray::cast(array->elements());
-    if (fixed_array->length() < array_length) {
-      array_length = fixed_array->length();
-    }
-
-    if (array_length == 0) {
-      return isolate->heap()->empty_string();
-    } else if (array_length == 1) {
-      Object* first = fixed_array->get(0);
-      if (first->IsString()) return first;
-    }
-    length = StringBuilderConcatLength(
-        special_length, fixed_array, array_length, &one_byte);
-  }
-
-  if (length == -1) {
-    return isolate->Throw(isolate->heap()->illegal_argument_string());
-  }
-
-  if (one_byte) {
-    Handle<SeqOneByteString> answer;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, answer,
-        isolate->factory()->NewRawOneByteString(length));
-    StringBuilderConcatHelper(*special,
-                              answer->GetChars(),
-                              FixedArray::cast(array->elements()),
-                              array_length);
-    return *answer;
-  } else {
-    Handle<SeqTwoByteString> answer;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, answer,
-        isolate->factory()->NewRawTwoByteString(length));
-    StringBuilderConcatHelper(*special,
-                              answer->GetChars(),
-                              FixedArray::cast(array->elements()),
-                              array_length);
-    return *answer;
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
-  int32_t array_length;
-  if (!args[1]->ToInt32(&array_length)) {
-    THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
-  }
-  CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
-  RUNTIME_ASSERT(array->HasFastObjectElements());
-  RUNTIME_ASSERT(array_length >= 0);
-
-  Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()));
-  if (fixed_array->length() < array_length) {
-    array_length = fixed_array->length();
-  }
-
-  if (array_length == 0) {
-    return isolate->heap()->empty_string();
-  } else if (array_length == 1) {
-    Object* first = fixed_array->get(0);
-    RUNTIME_ASSERT(first->IsString());
-    return first;
-  }
-
-  int separator_length = separator->length();
-  RUNTIME_ASSERT(separator_length > 0);
-  int max_nof_separators =
-      (String::kMaxLength + separator_length - 1) / separator_length;
-  if (max_nof_separators < (array_length - 1)) {
-    THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
-  }
-  int length = (array_length - 1) * separator_length;
-  for (int i = 0; i < array_length; i++) {
-    Object* element_obj = fixed_array->get(i);
-    RUNTIME_ASSERT(element_obj->IsString());
-    String* element = String::cast(element_obj);
-    int increment = element->length();
-    if (increment > String::kMaxLength - length) {
-      STATIC_ASSERT(String::kMaxLength < kMaxInt);
-      length = kMaxInt;  // Provoke exception;
-      break;
-    }
-    length += increment;
-  }
-
-  Handle<SeqTwoByteString> answer;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, answer,
-      isolate->factory()->NewRawTwoByteString(length));
-
-  DisallowHeapAllocation no_gc;
-
-  uc16* sink = answer->GetChars();
-#ifdef DEBUG
-  uc16* end = sink + length;
-#endif
-
-  RUNTIME_ASSERT(fixed_array->get(0)->IsString());
-  String* first = String::cast(fixed_array->get(0));
-  String* separator_raw = *separator;
-  int first_length = first->length();
-  String::WriteToFlat(first, sink, 0, first_length);
-  sink += first_length;
-
-  for (int i = 1; i < array_length; i++) {
-    DCHECK(sink + separator_length <= end);
-    String::WriteToFlat(separator_raw, sink, 0, separator_length);
-    sink += separator_length;
-
-    RUNTIME_ASSERT(fixed_array->get(i)->IsString());
-    String* element = String::cast(fixed_array->get(i));
-    int element_length = element->length();
-    DCHECK(sink + element_length <= end);
-    String::WriteToFlat(element, sink, 0, element_length);
-    sink += element_length;
-  }
-  DCHECK(sink == end);
-
-  // Use %_FastOneByteArrayJoin instead.
-  DCHECK(!answer->IsOneByteRepresentation());
-  return *answer;
-}
-
-template <typename Char>
-static void JoinSparseArrayWithSeparator(FixedArray* elements,
-                                         int elements_length,
-                                         uint32_t array_length,
-                                         String* separator,
-                                         Vector<Char> buffer) {
-  DisallowHeapAllocation no_gc;
-  int previous_separator_position = 0;
-  int separator_length = separator->length();
-  int cursor = 0;
-  for (int i = 0; i < elements_length; i += 2) {
-    int position = NumberToInt32(elements->get(i));
-    String* string = String::cast(elements->get(i + 1));
-    int string_length = string->length();
-    if (string->length() > 0) {
-      while (previous_separator_position < position) {
-        String::WriteToFlat<Char>(separator, &buffer[cursor],
-                                  0, separator_length);
-        cursor += separator_length;
-        previous_separator_position++;
-      }
-      String::WriteToFlat<Char>(string, &buffer[cursor],
-                                0, string_length);
-      cursor += string->length();
-    }
-  }
-  if (separator_length > 0) {
-    // Array length must be representable as a signed 32-bit number,
-    // otherwise the total string length would have been too large.
-    DCHECK(array_length <= 0x7fffffff);  // Is int32_t.
-    int last_array_index = static_cast<int>(array_length - 1);
-    while (previous_separator_position < last_array_index) {
-      String::WriteToFlat<Char>(separator, &buffer[cursor],
-                                0, separator_length);
-      cursor += separator_length;
-      previous_separator_position++;
-    }
-  }
-  DCHECK(cursor <= buffer.length());
-}
-
-
-RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
-  CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
-  CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
-  // elements_array is fast-mode JSarray of alternating positions
-  // (increasing order) and strings.
-  RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
-  // array_length is length of original array (used to add separators);
-  // separator is string to put between elements. Assumed to be non-empty.
-  RUNTIME_ASSERT(array_length > 0);
-
-  // Find total length of join result.
-  int string_length = 0;
-  bool is_one_byte = separator->IsOneByteRepresentation();
-  bool overflow = false;
-  CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length());
-  RUNTIME_ASSERT(elements_length <= elements_array->elements()->length());
-  RUNTIME_ASSERT((elements_length & 1) == 0);  // Even length.
-  FixedArray* elements = FixedArray::cast(elements_array->elements());
-  for (int i = 0; i < elements_length; i += 2) {
-    RUNTIME_ASSERT(elements->get(i)->IsNumber());
-    CONVERT_NUMBER_CHECKED(uint32_t, position, Uint32, elements->get(i));
-    RUNTIME_ASSERT(position < array_length);
-    RUNTIME_ASSERT(elements->get(i + 1)->IsString());
-  }
-
-  { DisallowHeapAllocation no_gc;
-    for (int i = 0; i < elements_length; i += 2) {
-      String* string = String::cast(elements->get(i + 1));
-      int length = string->length();
-      if (is_one_byte && !string->IsOneByteRepresentation()) {
-        is_one_byte = false;
-      }
-      if (length > String::kMaxLength ||
-          String::kMaxLength - length < string_length) {
-        overflow = true;
-        break;
-      }
-      string_length += length;
-    }
-  }
-
-  int separator_length = separator->length();
-  if (!overflow && separator_length > 0) {
-    if (array_length <= 0x7fffffffu) {
-      int separator_count = static_cast<int>(array_length) - 1;
-      int remaining_length = String::kMaxLength - string_length;
-      if ((remaining_length / separator_length) >= separator_count) {
-        string_length += separator_length * (array_length - 1);
-      } else {
-        // Not room for the separators within the maximal string length.
-        overflow = true;
-      }
-    } else {
-      // Nonempty separator and at least 2^31-1 separators necessary
-      // means that the string is too large to create.
-      STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
-      overflow = true;
-    }
-  }
-  if (overflow) {
-    // Throw an exception if the resulting string is too large. See
-    // https://code.google.com/p/chromium/issues/detail?id=336820
-    // for details.
-    THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
-  }
-
-  if (is_one_byte) {
-    Handle<SeqOneByteString> result = isolate->factory()->NewRawOneByteString(
-        string_length).ToHandleChecked();
-    JoinSparseArrayWithSeparator<uint8_t>(
-        FixedArray::cast(elements_array->elements()),
-        elements_length,
-        array_length,
-        *separator,
-        Vector<uint8_t>(result->GetChars(), string_length));
-    return *result;
-  } else {
-    Handle<SeqTwoByteString> result = isolate->factory()->NewRawTwoByteString(
-        string_length).ToHandleChecked();
-    JoinSparseArrayWithSeparator<uc16>(
-        FixedArray::cast(elements_array->elements()),
-        elements_length,
-        array_length,
-        *separator,
-        Vector<uc16>(result->GetChars(), string_length));
-    return *result;
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberOr) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
-  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
-  return *isolate->factory()->NewNumberFromInt(x | y);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberAnd) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
-  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
-  return *isolate->factory()->NewNumberFromInt(x & y);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberXor) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
-  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
-  return *isolate->factory()->NewNumberFromInt(x ^ y);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberShl) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
-  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
-  return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f));
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberShr) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
-  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
-  return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f));
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberSar) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
-  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
-  return *isolate->factory()->NewNumberFromInt(
-      ArithmeticShiftRight(x, y & 0x1f));
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberEquals) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
-  if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
-  if (x == y) return Smi::FromInt(EQUAL);
-  Object* result;
-  if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
-    result = Smi::FromInt(EQUAL);
-  } else {
-    result = Smi::FromInt(NOT_EQUAL);
-  }
-  return result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringEquals) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
-
-  bool not_equal = !String::Equals(x, y);
-  // This is slightly convoluted because the value that signifies
-  // equality is 0 and inequality is 1 so we have to negate the result
-  // from String::Equals.
-  DCHECK(not_equal == 0 || not_equal == 1);
-  STATIC_ASSERT(EQUAL == 0);
-  STATIC_ASSERT(NOT_EQUAL == 1);
-  return Smi::FromInt(not_equal);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NumberCompare) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 3);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
-  if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
-  if (x == y) return Smi::FromInt(EQUAL);
-  if (isless(x, y)) return Smi::FromInt(LESS);
-  return Smi::FromInt(GREATER);
-}
-
-
-// Compare two Smis as if they were converted to strings and then
-// compared lexicographically.
-RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_SMI_ARG_CHECKED(x_value, 0);
-  CONVERT_SMI_ARG_CHECKED(y_value, 1);
-
-  // If the integers are equal so are the string representations.
-  if (x_value == y_value) return Smi::FromInt(EQUAL);
-
-  // If one of the integers is zero the normal integer order is the
-  // same as the lexicographic order of the string representations.
-  if (x_value == 0 || y_value == 0)
-    return Smi::FromInt(x_value < y_value ? LESS : GREATER);
-
-  // If only one of the integers is negative the negative number is
-  // smallest because the char code of '-' is less than the char code
-  // of any digit.  Otherwise, we make both values positive.
-
-  // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
-  // architectures using 32-bit Smis.
-  uint32_t x_scaled = x_value;
-  uint32_t y_scaled = y_value;
-  if (x_value < 0 || y_value < 0) {
-    if (y_value >= 0) return Smi::FromInt(LESS);
-    if (x_value >= 0) return Smi::FromInt(GREATER);
-    x_scaled = -x_value;
-    y_scaled = -y_value;
-  }
-
-  static const uint32_t kPowersOf10[] = {
-    1, 10, 100, 1000, 10*1000, 100*1000,
-    1000*1000, 10*1000*1000, 100*1000*1000,
-    1000*1000*1000
-  };
-
-  // If the integers have the same number of decimal digits they can be
-  // compared directly as the numeric order is the same as the
-  // lexicographic order.  If one integer has fewer digits, it is scaled
-  // by some power of 10 to have the same number of digits as the longer
-  // integer.  If the scaled integers are equal it means the shorter
-  // integer comes first in the lexicographic order.
-
-  // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
-  int x_log2 = IntegerLog2(x_scaled);
-  int x_log10 = ((x_log2 + 1) * 1233) >> 12;
-  x_log10 -= x_scaled < kPowersOf10[x_log10];
-
-  int y_log2 = IntegerLog2(y_scaled);
-  int y_log10 = ((y_log2 + 1) * 1233) >> 12;
-  y_log10 -= y_scaled < kPowersOf10[y_log10];
-
-  int tie = EQUAL;
-
-  if (x_log10 < y_log10) {
-    // X has fewer digits.  We would like to simply scale up X but that
-    // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
-    // be scaled up to 9_000_000_000. So we scale up by the next
-    // smallest power and scale down Y to drop one digit. It is OK to
-    // drop one digit from the longer integer since the final digit is
-    // past the length of the shorter integer.
-    x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
-    y_scaled /= 10;
-    tie = LESS;
-  } else if (y_log10 < x_log10) {
-    y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
-    x_scaled /= 10;
-    tie = GREATER;
-  }
-
-  if (x_scaled < y_scaled) return Smi::FromInt(LESS);
-  if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
-  return Smi::FromInt(tie);
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringCompare) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
-
-  isolate->counters()->string_compare_runtime()->Increment();
-
-  // A few fast case tests before we flatten.
-  if (x.is_identical_to(y)) return Smi::FromInt(EQUAL);
-  if (y->length() == 0) {
-    if (x->length() == 0) return Smi::FromInt(EQUAL);
-    return Smi::FromInt(GREATER);
-  } else if (x->length() == 0) {
-    return Smi::FromInt(LESS);
-  }
-
-  int d = x->Get(0) - y->Get(0);
-  if (d < 0) return Smi::FromInt(LESS);
-  else if (d > 0) return Smi::FromInt(GREATER);
-
-  // Slow case.
-  x = String::Flatten(x);
-  y = String::Flatten(y);
-
-  DisallowHeapAllocation no_gc;
-  Object* equal_prefix_result = Smi::FromInt(EQUAL);
-  int prefix_length = x->length();
-  if (y->length() < prefix_length) {
-    prefix_length = y->length();
-    equal_prefix_result = Smi::FromInt(GREATER);
-  } else if (y->length() > prefix_length) {
-    equal_prefix_result = Smi::FromInt(LESS);
-  }
-  int r;
-  String::FlatContent x_content = x->GetFlatContent();
-  String::FlatContent y_content = y->GetFlatContent();
-  if (x_content.IsOneByte()) {
-    Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
-    if (y_content.IsOneByte()) {
-      Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
-      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
-    } else {
-      Vector<const uc16> y_chars = y_content.ToUC16Vector();
-      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
-    }
-  } else {
-    Vector<const uc16> x_chars = x_content.ToUC16Vector();
-    if (y_content.IsOneByte()) {
-      Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
-      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
-    } else {
-      Vector<const uc16> y_chars = y_content.ToUC16Vector();
-      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
-    }
-  }
-  Object* result;
-  if (r == 0) {
-    result = equal_prefix_result;
-  } else {
-    result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
-  }
-  return result;
-}
-
-
-#define RUNTIME_UNARY_MATH(Name, name)                                         \
-RUNTIME_FUNCTION(Runtime_Math##Name) {                           \
-  HandleScope scope(isolate);                                                  \
-  DCHECK(args.length() == 1);                                                  \
-  isolate->counters()->math_##name()->Increment();                             \
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);                                            \
-  return *isolate->factory()->NewHeapNumber(std::name(x));                     \
-}
-
-RUNTIME_UNARY_MATH(Acos, acos)
-RUNTIME_UNARY_MATH(Asin, asin)
-RUNTIME_UNARY_MATH(Atan, atan)
-RUNTIME_UNARY_MATH(LogRT, log)
-#undef RUNTIME_UNARY_MATH
-
-
-RUNTIME_FUNCTION(Runtime_DoubleHi) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  uint64_t integer = double_to_uint64(x);
-  integer = (integer >> 32) & 0xFFFFFFFFu;
-  return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
-}
-
-
-RUNTIME_FUNCTION(Runtime_DoubleLo) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  return *isolate->factory()->NewNumber(
-      static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
-}
-
-
-RUNTIME_FUNCTION(Runtime_ConstructDouble) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
-  CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
-  uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
-  return *isolate->factory()->NewNumber(uint64_to_double(result));
-}
-
-
-RUNTIME_FUNCTION(Runtime_RemPiO2) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  Factory* factory = isolate->factory();
-  double y[2] = {0.0, 0.0};
-  int n = fdlibm::rempio2(x, y);
-  Handle<FixedArray> array = factory->NewFixedArray(3);
-  Handle<HeapNumber> y0 = factory->NewHeapNumber(y[0]);
-  Handle<HeapNumber> y1 = factory->NewHeapNumber(y[1]);
-  array->set(0, Smi::FromInt(n));
-  array->set(1, *y0);
-  array->set(2, *y1);
-  return *factory->NewJSArrayWithElements(array);
-}
-
-
-static const double kPiDividedBy4 = 0.78539816339744830962;
-
-
-RUNTIME_FUNCTION(Runtime_MathAtan2) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  isolate->counters()->math_atan2()->Increment();
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  double result;
-  if (std::isinf(x) && std::isinf(y)) {
-    // Make sure that the result in case of two infinite arguments
-    // is a multiple of Pi / 4. The sign of the result is determined
-    // by the first argument (x) and the sign of the second argument
-    // determines the multiplier: one or three.
-    int multiplier = (x < 0) ? -1 : 1;
-    if (y < 0) multiplier *= 3;
-    result = multiplier * kPiDividedBy4;
-  } else {
-    result = std::atan2(x, y);
-  }
-  return *isolate->factory()->NewNumber(result);
-}
-
-
-RUNTIME_FUNCTION(Runtime_MathExpRT) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  isolate->counters()->math_exp()->Increment();
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  lazily_initialize_fast_exp();
-  return *isolate->factory()->NewNumber(fast_exp(x));
-}
-
-
-RUNTIME_FUNCTION(Runtime_MathFloorRT) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  isolate->counters()->math_floor()->Increment();
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  return *isolate->factory()->NewNumber(Floor(x));
-}
-
-
-// Slow version of Math.pow.  We check for fast paths for special cases.
-// Used if VFP3 is not available.
-RUNTIME_FUNCTION(Runtime_MathPowSlow) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  isolate->counters()->math_pow()->Increment();
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-
-  // If the second argument is a smi, it is much faster to call the
-  // custom powi() function than the generic pow().
-  if (args[1]->IsSmi()) {
-    int y = args.smi_at(1);
-    return *isolate->factory()->NewNumber(power_double_int(x, y));
-  }
-
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  double result = power_helper(x, y);
-  if (std::isnan(result)) return isolate->heap()->nan_value();
-  return *isolate->factory()->NewNumber(result);
-}
-
-
-// Fast version of Math.pow if we know that y is not an integer and y is not
-// -0.5 or 0.5.  Used as slow case from full codegen.
-RUNTIME_FUNCTION(Runtime_MathPowRT) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  isolate->counters()->math_pow()->Increment();
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
-  if (y == 0) {
-    return Smi::FromInt(1);
-  } else {
-    double result = power_double_double(x, y);
-    if (std::isnan(result)) return isolate->heap()->nan_value();
-    return *isolate->factory()->NewNumber(result);
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_RoundNumber) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
-  isolate->counters()->math_round()->Increment();
-
-  if (!input->IsHeapNumber()) {
-    DCHECK(input->IsSmi());
-    return *input;
-  }
-
-  Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
-
-  double value = number->value();
-  int exponent = number->get_exponent();
-  int sign = number->get_sign();
-
-  if (exponent < -1) {
-    // Number in range ]-0.5..0.5[. These always round to +/-zero.
-    if (sign) return isolate->heap()->minus_zero_value();
-    return Smi::FromInt(0);
-  }
-
-  // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
-  // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
-  // argument holds for 32-bit smis).
-  if (!sign && exponent < kSmiValueSize - 2) {
-    return Smi::FromInt(static_cast<int>(value + 0.5));
-  }
-
-  // If the magnitude is big enough, there's no place for fraction part. If we
-  // try to add 0.5 to this number, 1.0 will be added instead.
-  if (exponent >= 52) {
-    return *number;
-  }
-
-  if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
-
-  // Do not call NumberFromDouble() to avoid extra checks.
-  return *isolate->factory()->NewNumber(Floor(value + 0.5));
-}
-
-
-RUNTIME_FUNCTION(Runtime_MathSqrtRT) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  isolate->counters()->math_sqrt()->Increment();
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  return *isolate->factory()->NewNumber(fast_sqrt(x));
-}
-
-
-RUNTIME_FUNCTION(Runtime_MathFround) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  float xf = DoubleToFloat32(x);
-  return *isolate->factory()->NewNumber(xf);
-}
-
-
-RUNTIME_FUNCTION(Runtime_DateMakeDay) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_SMI_ARG_CHECKED(year, 0);
-  CONVERT_SMI_ARG_CHECKED(month, 1);
-
-  int days = isolate->date_cache()->DaysFromYearMonth(year, month);
-  RUNTIME_ASSERT(Smi::IsValid(days));
-  return Smi::FromInt(days);
-}
-
-
-RUNTIME_FUNCTION(Runtime_DateSetValue) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
-  CONVERT_DOUBLE_ARG_CHECKED(time, 1);
-  CONVERT_SMI_ARG_CHECKED(is_utc, 2);
-
-  DateCache* date_cache = isolate->date_cache();
-
-  Handle<Object> value;;
-  bool is_value_nan = false;
-  if (std::isnan(time)) {
-    value = isolate->factory()->nan_value();
-    is_value_nan = true;
-  } else if (!is_utc &&
-             (time < -DateCache::kMaxTimeBeforeUTCInMs ||
-              time > DateCache::kMaxTimeBeforeUTCInMs)) {
-    value = isolate->factory()->nan_value();
-    is_value_nan = true;
-  } else {
-    time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
-    if (time < -DateCache::kMaxTimeInMs ||
-        time > DateCache::kMaxTimeInMs) {
-      value = isolate->factory()->nan_value();
-      is_value_nan = true;
-    } else  {
-      value = isolate->factory()->NewNumber(DoubleToInteger(time));
-    }
-  }
-  date->SetValue(*value, is_value_nan);
-  return *value;
-}
-
-
-static Handle<JSObject> NewSloppyArguments(Isolate* isolate,
-                                           Handle<JSFunction> callee,
-                                           Object** parameters,
-                                           int argument_count) {
-  Handle<JSObject> result =
-      isolate->factory()->NewArgumentsObject(callee, argument_count);
-
-  // Allocate the elements if needed.
-  int parameter_count = callee->shared()->formal_parameter_count();
-  if (argument_count > 0) {
-    if (parameter_count > 0) {
-      int mapped_count = Min(argument_count, parameter_count);
-      Handle<FixedArray> parameter_map =
-          isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
-      parameter_map->set_map(
-          isolate->heap()->sloppy_arguments_elements_map());
-
-      Handle<Map> map = Map::Copy(handle(result->map()));
-      map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
-
-      result->set_map(*map);
-      result->set_elements(*parameter_map);
-
-      // Store the context and the arguments array at the beginning of the
-      // parameter map.
-      Handle<Context> context(isolate->context());
-      Handle<FixedArray> arguments =
-          isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
-      parameter_map->set(0, *context);
-      parameter_map->set(1, *arguments);
-
-      // Loop over the actual parameters backwards.
-      int index = argument_count - 1;
-      while (index >= mapped_count) {
-        // These go directly in the arguments array and have no
-        // corresponding slot in the parameter map.
-        arguments->set(index, *(parameters - index - 1));
-        --index;
-      }
-
-      Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
-      while (index >= 0) {
-        // Detect duplicate names to the right in the parameter list.
-        Handle<String> name(scope_info->ParameterName(index));
-        int context_local_count = scope_info->ContextLocalCount();
-        bool duplicate = false;
-        for (int j = index + 1; j < parameter_count; ++j) {
-          if (scope_info->ParameterName(j) == *name) {
-            duplicate = true;
-            break;
-          }
-        }
-
-        if (duplicate) {
-          // This goes directly in the arguments array with a hole in the
-          // parameter map.
-          arguments->set(index, *(parameters - index - 1));
-          parameter_map->set_the_hole(index + 2);
-        } else {
-          // The context index goes in the parameter map with a hole in the
-          // arguments array.
-          int context_index = -1;
-          for (int j = 0; j < context_local_count; ++j) {
-            if (scope_info->ContextLocalName(j) == *name) {
-              context_index = j;
-              break;
-            }
-          }
-          DCHECK(context_index >= 0);
-          arguments->set_the_hole(index);
-          parameter_map->set(index + 2, Smi::FromInt(
-              Context::MIN_CONTEXT_SLOTS + context_index));
-        }
-
-        --index;
-      }
-    } else {
-      // If there is no aliasing, the arguments object elements are not
-      // special in any way.
-      Handle<FixedArray> elements =
-          isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
-      result->set_elements(*elements);
-      for (int i = 0; i < argument_count; ++i) {
-        elements->set(i, *(parameters - i - 1));
-      }
-    }
-  }
-  return result;
-}
-
-
-static Handle<JSObject> NewStrictArguments(Isolate* isolate,
-                                           Handle<JSFunction> callee,
-                                           Object** parameters,
-                                           int argument_count) {
-  Handle<JSObject> result =
-      isolate->factory()->NewArgumentsObject(callee, argument_count);
-
-  if (argument_count > 0) {
-    Handle<FixedArray> array =
-        isolate->factory()->NewUninitializedFixedArray(argument_count);
-    DisallowHeapAllocation no_gc;
-    WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
-    for (int i = 0; i < argument_count; i++) {
-      array->set(i, *--parameters, mode);
-    }
-    result->set_elements(*array);
-  }
-  return result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewArguments) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
-  JavaScriptFrameIterator it(isolate);
-
-  // Find the frame that holds the actual arguments passed to the function.
-  it.AdvanceToArgumentsFrame();
-  JavaScriptFrame* frame = it.frame();
-
-  // Determine parameter location on the stack and dispatch on language mode.
-  int argument_count = frame->GetArgumentsLength();
-  Object** parameters = reinterpret_cast<Object**>(frame->GetParameterSlot(-1));
-  return callee->shared()->strict_mode() == STRICT
-             ? *NewStrictArguments(isolate, callee, parameters, argument_count)
-             : *NewSloppyArguments(isolate, callee, parameters, argument_count);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewSloppyArguments) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
-  Object** parameters = reinterpret_cast<Object**>(args[1]);
-  CONVERT_SMI_ARG_CHECKED(argument_count, 2);
-  return *NewSloppyArguments(isolate, callee, parameters, argument_count);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewStrictArguments) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
-  Object** parameters = reinterpret_cast<Object**>(args[1]);
-  CONVERT_SMI_ARG_CHECKED(argument_count, 2);
-  return *NewStrictArguments(isolate, callee, parameters, argument_count);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewClosureFromStubFailure) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
-  Handle<Context> context(isolate->context());
-  PretenureFlag pretenure_flag = NOT_TENURED;
-  return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
-                                                                pretenure_flag);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewClosure) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
-  CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
-  CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
-
-  // The caller ensures that we pretenure closures that are assigned
-  // directly to properties.
-  PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
-  return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
-      shared, context, pretenure_flag);
-}
-
-
-// Find the arguments of the JavaScript function invocation that called
-// into C++ code. Collect these in a newly allocated array of handles (possibly
-// prefixed by a number of empty handles).
-static SmartArrayPointer<Handle<Object> > GetCallerArguments(
-    Isolate* isolate,
-    int prefix_argc,
-    int* total_argc) {
-  // Find frame containing arguments passed to the caller.
-  JavaScriptFrameIterator it(isolate);
-  JavaScriptFrame* frame = it.frame();
-  List<JSFunction*> functions(2);
-  frame->GetFunctions(&functions);
-  if (functions.length() > 1) {
-    int inlined_jsframe_index = functions.length() - 1;
-    JSFunction* inlined_function = functions[inlined_jsframe_index];
-    SlotRefValueBuilder slot_refs(
-        frame,
-        inlined_jsframe_index,
-        inlined_function->shared()->formal_parameter_count());
-
-    int args_count = slot_refs.args_length();
-
-    *total_argc = prefix_argc + args_count;
-    SmartArrayPointer<Handle<Object> > param_data(
-        NewArray<Handle<Object> >(*total_argc));
-    slot_refs.Prepare(isolate);
-    for (int i = 0; i < args_count; i++) {
-      Handle<Object> val = slot_refs.GetNext(isolate, 0);
-      param_data[prefix_argc + i] = val;
-    }
-    slot_refs.Finish(isolate);
-
-    return param_data;
-  } else {
-    it.AdvanceToArgumentsFrame();
-    frame = it.frame();
-    int args_count = frame->ComputeParametersCount();
-
-    *total_argc = prefix_argc + args_count;
-    SmartArrayPointer<Handle<Object> > param_data(
-        NewArray<Handle<Object> >(*total_argc));
-    for (int i = 0; i < args_count; i++) {
-      Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
-      param_data[prefix_argc + i] = val;
-    }
-    return param_data;
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
-  CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
-
-  // TODO(lrn): Create bound function in C++ code from premade shared info.
-  bound_function->shared()->set_bound(true);
-  // Get all arguments of calling function (Function.prototype.bind).
-  int argc = 0;
-  SmartArrayPointer<Handle<Object> > arguments =
-      GetCallerArguments(isolate, 0, &argc);
-  // Don't count the this-arg.
-  if (argc > 0) {
-    RUNTIME_ASSERT(arguments[0].is_identical_to(this_object));
-    argc--;
-  } else {
-    RUNTIME_ASSERT(this_object->IsUndefined());
-  }
-  // Initialize array of bindings (function, this, and any existing arguments
-  // if the function was already bound).
-  Handle<FixedArray> new_bindings;
-  int i;
-  if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
-    Handle<FixedArray> old_bindings(
-        JSFunction::cast(*bindee)->function_bindings());
-    RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex);
-    new_bindings =
-        isolate->factory()->NewFixedArray(old_bindings->length() + argc);
-    bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
-                            isolate);
-    i = 0;
-    for (int n = old_bindings->length(); i < n; i++) {
-      new_bindings->set(i, old_bindings->get(i));
-    }
-  } else {
-    int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
-    new_bindings = isolate->factory()->NewFixedArray(array_size);
-    new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
-    new_bindings->set(JSFunction::kBoundThisIndex, *this_object);
-    i = 2;
-  }
-  // Copy arguments, skipping the first which is "this_arg".
-  for (int j = 0; j < argc; j++, i++) {
-    new_bindings->set(i, *arguments[j + 1]);
-  }
-  new_bindings->set_map_no_write_barrier(
-      isolate->heap()->fixed_cow_array_map());
-  bound_function->set_function_bindings(*new_bindings);
-
-  // Update length. Have to remove the prototype first so that map migration
-  // is happy about the number of fields.
-  RUNTIME_ASSERT(bound_function->RemovePrototype());
-  Handle<Map> bound_function_map(
-      isolate->native_context()->bound_function_map());
-  JSObject::MigrateToMap(bound_function, bound_function_map);
-  Handle<String> length_string = isolate->factory()->length_string();
-  PropertyAttributes attr =
-      static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
-  RETURN_FAILURE_ON_EXCEPTION(
-      isolate,
-      JSObject::SetOwnPropertyIgnoreAttributes(
-          bound_function, length_string, new_length, attr));
-  return *bound_function;
-}
-
-
-RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
-  HandleScope handles(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
-  if (callable->IsJSFunction()) {
-    Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
-    if (function->shared()->bound()) {
-      Handle<FixedArray> bindings(function->function_bindings());
-      RUNTIME_ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
-      return *isolate->factory()->NewJSArrayWithElements(bindings);
-    }
-  }
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  // First argument is a function to use as a constructor.
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  RUNTIME_ASSERT(function->shared()->bound());
-
-  // The argument is a bound function. Extract its bound arguments
-  // and callable.
-  Handle<FixedArray> bound_args =
-      Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
-  int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
-  Handle<Object> bound_function(
-      JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
-      isolate);
-  DCHECK(!bound_function->IsJSFunction() ||
-         !Handle<JSFunction>::cast(bound_function)->shared()->bound());
-
-  int total_argc = 0;
-  SmartArrayPointer<Handle<Object> > param_data =
-      GetCallerArguments(isolate, bound_argc, &total_argc);
-  for (int i = 0; i < bound_argc; i++) {
-    param_data[i] = Handle<Object>(bound_args->get(
-        JSFunction::kBoundArgumentsStartIndex + i), isolate);
-  }
-
-  if (!bound_function->IsJSFunction()) {
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, bound_function,
-        Execution::TryGetConstructorDelegate(isolate, bound_function));
-  }
-  DCHECK(bound_function->IsJSFunction());
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Execution::New(Handle<JSFunction>::cast(bound_function),
-                     total_argc, param_data.get()));
-  return *result;
-}
-
-
-static Object* Runtime_NewObjectHelper(Isolate* isolate,
-                                            Handle<Object> constructor,
-                                            Handle<AllocationSite> site) {
-  // If the constructor isn't a proper function we throw a type error.
-  if (!constructor->IsJSFunction()) {
-    Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
-    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
-                                   NewTypeError("not_constructor", arguments));
-  }
-
-  Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
-
-  // If function should not have prototype, construction is not allowed. In this
-  // case generated code bailouts here, since function has no initial_map.
-  if (!function->should_have_prototype() && !function->shared()->bound()) {
-    Vector< Handle<Object> > arguments = HandleVector(&constructor, 1);
-    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
-                                   NewTypeError("not_constructor", arguments));
-  }
-
-  Debug* debug = isolate->debug();
-  // Handle stepping into constructors if step into is active.
-  if (debug->StepInActive()) {
-    debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
-  }
-
-  if (function->has_initial_map()) {
-    if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
-      // The 'Function' function ignores the receiver object when
-      // called using 'new' and creates a new JSFunction object that
-      // is returned.  The receiver object is only used for error
-      // reporting if an error occurs when constructing the new
-      // JSFunction. Factory::NewJSObject() should not be used to
-      // allocate JSFunctions since it does not properly initialize
-      // the shared part of the function. Since the receiver is
-      // ignored anyway, we use the global object as the receiver
-      // instead of a new JSFunction object. This way, errors are
-      // reported the same way whether or not 'Function' is called
-      // using 'new'.
-      return isolate->global_proxy();
-    }
-  }
-
-  // The function should be compiled for the optimization hints to be
-  // available.
-  Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
-
-  Handle<JSObject> result;
-  if (site.is_null()) {
-    result = isolate->factory()->NewJSObject(function);
-  } else {
-    result = isolate->factory()->NewJSObjectWithMemento(function, site);
-  }
-
-  isolate->counters()->constructed_objects()->Increment();
-  isolate->counters()->constructed_objects_runtime()->Increment();
-
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewObject) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
-  return Runtime_NewObjectHelper(isolate,
-                                 constructor,
-                                 Handle<AllocationSite>::null());
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewObjectWithAllocationSite) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
-  Handle<AllocationSite> site;
-  if (feedback->IsAllocationSite()) {
-    // The feedback can be an AllocationSite or undefined.
-    site = Handle<AllocationSite>::cast(feedback);
-  }
-  return Runtime_NewObjectHelper(isolate, constructor, site);
-}
-
-
-RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  function->CompleteInobjectSlackTracking();
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_CompileLazy) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-#ifdef DEBUG
-  if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
-    PrintF("[unoptimized: ");
-    function->PrintName();
-    PrintF("]\n");
-  }
-#endif
-
-  // Compile the target function.
-  DCHECK(function->shared()->allows_lazy_compilation());
-
-  Handle<Code> code;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
-                                     Compiler::GetLazyCode(function));
-  DCHECK(code->kind() == Code::FUNCTION ||
-         code->kind() == Code::OPTIMIZED_FUNCTION);
-  function->ReplaceCode(*code);
-  return *code;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CompileOptimized) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
-
-  Handle<Code> unoptimized(function->shared()->code());
-  if (!isolate->use_crankshaft() ||
-      function->shared()->optimization_disabled() ||
-      isolate->DebuggerHasBreakPoints()) {
-    // If the function is not optimizable or debugger is active continue
-    // using the code from the full compiler.
-    if (FLAG_trace_opt) {
-      PrintF("[failed to optimize ");
-      function->PrintName();
-      PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
-          function->shared()->optimization_disabled() ? "F" : "T",
-          isolate->DebuggerHasBreakPoints() ? "T" : "F");
-    }
-    function->ReplaceCode(*unoptimized);
-    return function->code();
-  }
-
-  Compiler::ConcurrencyMode mode =
-      concurrent ? Compiler::CONCURRENT : Compiler::NOT_CONCURRENT;
-  Handle<Code> code;
-  if (Compiler::GetOptimizedCode(function, unoptimized, mode).ToHandle(&code)) {
-    function->ReplaceCode(*code);
-  } else {
-    function->ReplaceCode(function->shared()->code());
-  }
-
-  DCHECK(function->code()->kind() == Code::FUNCTION ||
-         function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
-         function->IsInOptimizationQueue());
-  return function->code();
-}
-
-
-class ActivationsFinder : public ThreadVisitor {
- public:
-  Code* code_;
-  bool has_code_activations_;
-
-  explicit ActivationsFinder(Code* code)
-    : code_(code),
-      has_code_activations_(false) { }
-
-  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
-    JavaScriptFrameIterator it(isolate, top);
-    VisitFrames(&it);
-  }
-
-  void VisitFrames(JavaScriptFrameIterator* it) {
-    for (; !it->done(); it->Advance()) {
-      JavaScriptFrame* frame = it->frame();
-      if (code_->contains(frame->pc())) has_code_activations_ = true;
-    }
-  }
-};
-
-
-RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
-  DCHECK(AllowHeapAllocation::IsAllowed());
-  delete deoptimizer;
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_SMI_ARG_CHECKED(type_arg, 0);
-  Deoptimizer::BailoutType type =
-      static_cast<Deoptimizer::BailoutType>(type_arg);
-  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
-  DCHECK(AllowHeapAllocation::IsAllowed());
-
-  Handle<JSFunction> function = deoptimizer->function();
-  Handle<Code> optimized_code = deoptimizer->compiled_code();
-
-  DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
-  DCHECK(type == deoptimizer->bailout_type());
-
-  // Make sure to materialize objects before causing any allocation.
-  JavaScriptFrameIterator it(isolate);
-  deoptimizer->MaterializeHeapObjects(&it);
-  delete deoptimizer;
-
-  JavaScriptFrame* frame = it.frame();
-  RUNTIME_ASSERT(frame->function()->IsJSFunction());
-  DCHECK(frame->function() == *function);
-
-  // Avoid doing too much work when running with --always-opt and keep
-  // the optimized code around.
-  if (FLAG_always_opt || type == Deoptimizer::LAZY) {
-    return isolate->heap()->undefined_value();
-  }
-
-  // Search for other activations of the same function and code.
-  ActivationsFinder activations_finder(*optimized_code);
-  activations_finder.VisitFrames(&it);
-  isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
-
-  if (!activations_finder.has_code_activations_) {
-    if (function->code() == *optimized_code) {
-      if (FLAG_trace_deopt) {
-        PrintF("[removing optimized code for: ");
-        function->PrintName();
-        PrintF("]\n");
-      }
-      function->ReplaceCode(function->shared()->code());
-      // Evict optimized code for this function from the cache so that it
-      // doesn't get used for new closures.
-      function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
-                                                    "notify deoptimized");
-    }
-  } else {
-    // TODO(titzer): we should probably do DeoptimizeCodeList(code)
-    // unconditionally if the code is not already marked for deoptimization.
-    // If there is an index by shared function info, all the better.
-    Deoptimizer::DeoptimizeFunction(*function);
-  }
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  if (!function->IsOptimized()) return isolate->heap()->undefined_value();
-
-  // TODO(turbofan): Deoptimization is not supported yet.
-  if (function->code()->is_turbofanned() && !FLAG_turbo_deoptimization) {
-    return isolate->heap()->undefined_value();
-  }
-
-  Deoptimizer::DeoptimizeFunction(*function);
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  function->shared()->ClearTypeFeedbackInfo();
-  Code* unoptimized = function->shared()->code();
-  if (unoptimized->kind() == Code::FUNCTION) {
-    unoptimized->ClearInlineCaches();
-  }
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-#if defined(USE_SIMULATOR)
-  return isolate->heap()->true_value();
-#else
-  return isolate->heap()->false_value();
-#endif
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  return isolate->heap()->ToBoolean(
-      isolate->concurrent_recompilation_enabled());
-}
-
-
-RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  // The following two assertions are lifted from the DCHECKs inside
-  // JSFunction::MarkForOptimization().
-  RUNTIME_ASSERT(!function->shared()->is_generator());
-  RUNTIME_ASSERT(function->shared()->allows_lazy_compilation() ||
-                 (function->code()->kind() == Code::FUNCTION &&
-                  function->code()->optimizable()));
-
-  // If the function is optimized, just return.
-  if (function->IsOptimized()) return isolate->heap()->undefined_value();
-
-  function->MarkForOptimization();
-
-  Code* unoptimized = function->shared()->code();
-  if (args.length() == 2 &&
-      unoptimized->kind() == Code::FUNCTION) {
-    CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
-    if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("osr")) && FLAG_use_osr) {
-      // Start patching from the currently patched loop nesting level.
-      DCHECK(BackEdgeTable::Verify(isolate, unoptimized));
-      isolate->runtime_profiler()->AttemptOnStackReplacement(
-          *function, Code::kMaxLoopNestingMarker);
-    } else if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) &&
-               isolate->concurrent_recompilation_enabled()) {
-      function->MarkForConcurrentOptimization();
-    }
-  }
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSFunction, function, 0);
-  function->shared()->set_optimization_disabled(true);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
-  HandleScope scope(isolate);
-  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
-  if (!isolate->use_crankshaft()) {
-    return Smi::FromInt(4);  // 4 == "never".
-  }
-  bool sync_with_compiler_thread = true;
-  if (args.length() == 2) {
-    CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
-    if (sync->IsOneByteEqualTo(STATIC_CHAR_VECTOR("no sync"))) {
-      sync_with_compiler_thread = false;
-    }
-  }
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  if (isolate->concurrent_recompilation_enabled() &&
-      sync_with_compiler_thread) {
-    while (function->IsInOptimizationQueue()) {
-      isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
-      base::OS::Sleep(50);
-    }
-  }
-  if (FLAG_always_opt) {
-    // We may have always opt, but that is more best-effort than a real
-    // promise, so we still say "no" if it is not optimized.
-    return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
-                                   : Smi::FromInt(2);  // 2 == "no".
-  }
-  if (FLAG_deopt_every_n_times) {
-    return Smi::FromInt(6);  // 6 == "maybe deopted".
-  }
-  if (function->IsOptimized() && function->code()->is_turbofanned()) {
-    return Smi::FromInt(7);  // 7 == "TurboFan compiler".
-  }
-  return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
-                                 : Smi::FromInt(2);  // 2 == "no".
-}
-
-
-RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
-  DCHECK(args.length() == 0);
-  RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
-  RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
-  isolate->optimizing_compiler_thread()->Unblock();
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  return Smi::FromInt(function->shared()->opt_count());
-}
-
-
-static bool IsSuitableForOnStackReplacement(Isolate* isolate,
-                                            Handle<JSFunction> function,
-                                            Handle<Code> current_code) {
-  // Keep track of whether we've succeeded in optimizing.
-  if (!isolate->use_crankshaft() || !current_code->optimizable()) return false;
-  // If we are trying to do OSR when there are already optimized
-  // activations of the function, it means (a) the function is directly or
-  // indirectly recursive and (b) an optimized invocation has been
-  // deoptimized so that we are currently in an unoptimized activation.
-  // Check for optimized activations of this function.
-  for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
-    JavaScriptFrame* frame = it.frame();
-    if (frame->is_optimized() && frame->function() == *function) return false;
-  }
-
-  return true;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  Handle<Code> caller_code(function->shared()->code());
-
-  // We're not prepared to handle a function with arguments object.
-  DCHECK(!function->shared()->uses_arguments());
-
-  RUNTIME_ASSERT(FLAG_use_osr);
-
-  // Passing the PC in the javascript frame from the caller directly is
-  // not GC safe, so we walk the stack to get it.
-  JavaScriptFrameIterator it(isolate);
-  JavaScriptFrame* frame = it.frame();
-  if (!caller_code->contains(frame->pc())) {
-    // Code on the stack may not be the code object referenced by the shared
-    // function info.  It may have been replaced to include deoptimization data.
-    caller_code = Handle<Code>(frame->LookupCode());
-  }
-
-  uint32_t pc_offset = static_cast<uint32_t>(
-      frame->pc() - caller_code->instruction_start());
-
-#ifdef DEBUG
-  DCHECK_EQ(frame->function(), *function);
-  DCHECK_EQ(frame->LookupCode(), *caller_code);
-  DCHECK(caller_code->contains(frame->pc()));
-#endif  // DEBUG
-
-
-  BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
-  DCHECK(!ast_id.IsNone());
-
-  Compiler::ConcurrencyMode mode =
-      isolate->concurrent_osr_enabled() &&
-      (function->shared()->ast_node_count() > 512) ? Compiler::CONCURRENT
-                                                   : Compiler::NOT_CONCURRENT;
-  Handle<Code> result = Handle<Code>::null();
-
-  OptimizedCompileJob* job = NULL;
-  if (mode == Compiler::CONCURRENT) {
-    // Gate the OSR entry with a stack check.
-    BackEdgeTable::AddStackCheck(caller_code, pc_offset);
-    // Poll already queued compilation jobs.
-    OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread();
-    if (thread->IsQueuedForOSR(function, ast_id)) {
-      if (FLAG_trace_osr) {
-        PrintF("[OSR - Still waiting for queued: ");
-        function->PrintName();
-        PrintF(" at AST id %d]\n", ast_id.ToInt());
-      }
-      return NULL;
-    }
-
-    job = thread->FindReadyOSRCandidate(function, ast_id);
-  }
-
-  if (job != NULL) {
-    if (FLAG_trace_osr) {
-      PrintF("[OSR - Found ready: ");
-      function->PrintName();
-      PrintF(" at AST id %d]\n", ast_id.ToInt());
-    }
-    result = Compiler::GetConcurrentlyOptimizedCode(job);
-  } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
-    if (FLAG_trace_osr) {
-      PrintF("[OSR - Compiling: ");
-      function->PrintName();
-      PrintF(" at AST id %d]\n", ast_id.ToInt());
-    }
-    MaybeHandle<Code> maybe_result = Compiler::GetOptimizedCode(
-        function, caller_code, mode, ast_id);
-    if (maybe_result.ToHandle(&result) &&
-        result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
-      // Optimization is queued.  Return to check later.
-      return NULL;
-    }
-  }
-
-  // Revert the patched back edge table, regardless of whether OSR succeeds.
-  BackEdgeTable::Revert(isolate, *caller_code);
-
-  // Check whether we ended up with usable optimized code.
-  if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
-    DeoptimizationInputData* data =
-        DeoptimizationInputData::cast(result->deoptimization_data());
-
-    if (data->OsrPcOffset()->value() >= 0) {
-      DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id);
-      if (FLAG_trace_osr) {
-        PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
-               ast_id.ToInt(), data->OsrPcOffset()->value());
-      }
-      // TODO(titzer): this is a massive hack to make the deopt counts
-      // match. Fix heuristics for reenabling optimizations!
-      function->shared()->increment_deopt_count();
-
-      // TODO(titzer): Do not install code into the function.
-      function->ReplaceCode(*result);
-      return *result;
-    }
-  }
-
-  // Failed.
-  if (FLAG_trace_osr) {
-    PrintF("[OSR - Failed: ");
-    function->PrintName();
-    PrintF(" at AST id %d]\n", ast_id.ToInt());
-  }
-
-  if (!function->IsOptimized()) {
-    function->ReplaceCode(function->shared()->code());
-  }
-  return NULL;
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2 || args.length() == 3);
-#ifdef DEBUG
-  CONVERT_SMI_ARG_CHECKED(interval, 0);
-  CONVERT_SMI_ARG_CHECKED(timeout, 1);
-  isolate->heap()->set_allocation_timeout(timeout);
-  FLAG_gc_interval = interval;
-  if (args.length() == 3) {
-    // Enable/disable inline allocation if requested.
-    CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
-    if (inline_allocation) {
-      isolate->heap()->EnableInlineAllocation();
-    } else {
-      isolate->heap()->DisableInlineAllocation();
-    }
-  }
-#endif
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetRootNaN) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
-  return isolate->heap()->nan_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_Call) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() >= 2);
-  int argc = args.length() - 2;
-  CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
-  Object* receiver = args[0];
-
-  // If there are too many arguments, allocate argv via malloc.
-  const int argv_small_size = 10;
-  Handle<Object> argv_small_buffer[argv_small_size];
-  SmartArrayPointer<Handle<Object> > argv_large_buffer;
-  Handle<Object>* argv = argv_small_buffer;
-  if (argc > argv_small_size) {
-    argv = new Handle<Object>[argc];
-    if (argv == NULL) return isolate->StackOverflow();
-    argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
-  }
-
-  for (int i = 0; i < argc; ++i) {
-     argv[i] = Handle<Object>(args[1 + i], isolate);
-  }
-
-  Handle<JSReceiver> hfun(fun);
-  Handle<Object> hreceiver(receiver, isolate);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_Apply) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 5);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
-  CONVERT_INT32_ARG_CHECKED(offset, 3);
-  CONVERT_INT32_ARG_CHECKED(argc, 4);
-  RUNTIME_ASSERT(offset >= 0);
-  // Loose upper bound to allow fuzzing. We'll most likely run out of
-  // stack space before hitting this limit.
-  static int kMaxArgc = 1000000;
-  RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
-
-  // If there are too many arguments, allocate argv via malloc.
-  const int argv_small_size = 10;
-  Handle<Object> argv_small_buffer[argv_small_size];
-  SmartArrayPointer<Handle<Object> > argv_large_buffer;
-  Handle<Object>* argv = argv_small_buffer;
-  if (argc > argv_small_size) {
-    argv = new Handle<Object>[argc];
-    if (argv == NULL) return isolate->StackOverflow();
-    argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
-  }
-
-  for (int i = 0; i < argc; ++i) {
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, argv[i],
-        Object::GetElement(isolate, arguments, offset + i));
-  }
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Execution::Call(isolate, fun, receiver, argc, argv, true));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-  RUNTIME_ASSERT(!object->IsJSFunction());
-  return *Execution::GetFunctionDelegate(isolate, object);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-  RUNTIME_ASSERT(!object->IsJSFunction());
-  return *Execution::GetConstructorDelegate(isolate, object);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewGlobalContext) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
-  Handle<Context> result =
-      isolate->factory()->NewGlobalContext(function, scope_info);
-
-  DCHECK(function->context() == isolate->context());
-  DCHECK(function->context()->global_object() == result->global_object());
-  result->global_object()->set_global_context(*result);
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_NewFunctionContext) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-
-  DCHECK(function->context() == isolate->context());
-  int length = function->shared()->scope_info()->ContextLength();
-  return *isolate->factory()->NewFunctionContext(length, function);
-}
-
-
-RUNTIME_FUNCTION(Runtime_PushWithContext) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  Handle<JSReceiver> extension_object;
-  if (args[0]->IsJSReceiver()) {
-    extension_object = args.at<JSReceiver>(0);
-  } else {
-    // Try to convert the object to a proper JavaScript object.
-    MaybeHandle<JSReceiver> maybe_object =
-        Object::ToObject(isolate, args.at<Object>(0));
-    if (!maybe_object.ToHandle(&extension_object)) {
-      Handle<Object> handle = args.at<Object>(0);
-      THROW_NEW_ERROR_RETURN_FAILURE(
-          isolate, NewTypeError("with_expression", HandleVector(&handle, 1)));
-    }
-  }
-
-  Handle<JSFunction> function;
-  if (args[1]->IsSmi()) {
-    // A smi sentinel indicates a context nested inside global code rather
-    // than some function.  There is a canonical empty function that can be
-    // gotten from the native context.
-    function = handle(isolate->native_context()->closure());
-  } else {
-    function = args.at<JSFunction>(1);
-  }
-
-  Handle<Context> current(isolate->context());
-  Handle<Context> context = isolate->factory()->NewWithContext(
-      function, current, extension_object);
-  isolate->set_context(*context);
-  return *context;
-}
-
-
-RUNTIME_FUNCTION(Runtime_PushCatchContext) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
-  Handle<JSFunction> function;
-  if (args[2]->IsSmi()) {
-    // A smi sentinel indicates a context nested inside global code rather
-    // than some function.  There is a canonical empty function that can be
-    // gotten from the native context.
-    function = handle(isolate->native_context()->closure());
-  } else {
-    function = args.at<JSFunction>(2);
-  }
-  Handle<Context> current(isolate->context());
-  Handle<Context> context = isolate->factory()->NewCatchContext(
-      function, current, name, thrown_object);
-  isolate->set_context(*context);
-  return *context;
-}
-
-
-RUNTIME_FUNCTION(Runtime_PushBlockContext) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
-  Handle<JSFunction> function;
-  if (args[1]->IsSmi()) {
-    // A smi sentinel indicates a context nested inside global code rather
-    // than some function.  There is a canonical empty function that can be
-    // gotten from the native context.
-    function = handle(isolate->native_context()->closure());
-  } else {
-    function = args.at<JSFunction>(1);
-  }
-  Handle<Context> current(isolate->context());
-  Handle<Context> context = isolate->factory()->NewBlockContext(
-      function, current, scope_info);
-  isolate->set_context(*context);
-  return *context;
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsJSModule) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  return isolate->heap()->ToBoolean(obj->IsJSModule());
-}
-
-
-RUNTIME_FUNCTION(Runtime_PushModuleContext) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_SMI_ARG_CHECKED(index, 0);
-
-  if (!args[1]->IsScopeInfo()) {
-    // Module already initialized. Find hosting context and retrieve context.
-    Context* host = Context::cast(isolate->context())->global_context();
-    Context* context = Context::cast(host->get(index));
-    DCHECK(context->previous() == isolate->context());
-    isolate->set_context(context);
-    return context;
-  }
-
-  CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
-
-  // Allocate module context.
-  HandleScope scope(isolate);
-  Factory* factory = isolate->factory();
-  Handle<Context> context = factory->NewModuleContext(scope_info);
-  Handle<JSModule> module = factory->NewJSModule(context, scope_info);
-  context->set_module(*module);
-  Context* previous = isolate->context();
-  context->set_previous(previous);
-  context->set_closure(previous->closure());
-  context->set_global_object(previous->global_object());
-  isolate->set_context(*context);
-
-  // Find hosting scope and initialize internal variable holding module there.
-  previous->global_context()->set(index, *context);
-
-  return *context;
-}
-
-
-RUNTIME_FUNCTION(Runtime_DeclareModules) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
-  Context* host_context = isolate->context();
-
-  for (int i = 0; i < descriptions->length(); ++i) {
-    Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i)));
-    int host_index = description->host_index();
-    Handle<Context> context(Context::cast(host_context->get(host_index)));
-    Handle<JSModule> module(context->module());
-
-    for (int j = 0; j < description->length(); ++j) {
-      Handle<String> name(description->name(j));
-      VariableMode mode = description->mode(j);
-      int index = description->index(j);
-      switch (mode) {
-        case VAR:
-        case LET:
-        case CONST:
-        case CONST_LEGACY: {
-          PropertyAttributes attr =
-              IsImmutableVariableMode(mode) ? FROZEN : SEALED;
-          Handle<AccessorInfo> info =
-              Accessors::MakeModuleExport(name, index, attr);
-          Handle<Object> result =
-              JSObject::SetAccessor(module, info).ToHandleChecked();
-          DCHECK(!result->IsUndefined());
-          USE(result);
-          break;
-        }
-        case MODULE: {
-          Object* referenced_context = Context::cast(host_context)->get(index);
-          Handle<JSModule> value(Context::cast(referenced_context)->module());
-          JSObject::SetOwnPropertyIgnoreAttributes(module, name, value, FROZEN)
-              .Assert();
-          break;
-        }
-        case INTERNAL:
-        case TEMPORARY:
-        case DYNAMIC:
-        case DYNAMIC_GLOBAL:
-        case DYNAMIC_LOCAL:
-          UNREACHABLE();
-      }
-    }
-
-    JSObject::PreventExtensions(module).Assert();
-  }
-
-  DCHECK(!isolate->has_pending_exception());
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
-
-  int index;
-  PropertyAttributes attributes;
-  ContextLookupFlags flags = FOLLOW_CHAINS;
-  BindingFlags binding_flags;
-  Handle<Object> holder = context->Lookup(name,
-                                          flags,
-                                          &index,
-                                          &attributes,
-                                          &binding_flags);
-
-  // If the slot was not found the result is true.
-  if (holder.is_null()) {
-    return isolate->heap()->true_value();
-  }
-
-  // If the slot was found in a context, it should be DONT_DELETE.
-  if (holder->IsContext()) {
-    return isolate->heap()->false_value();
-  }
-
-  // The slot was found in a JSObject, either a context extension object,
-  // the global object, or the subject of a with.  Try to delete it
-  // (respecting DONT_DELETE).
-  Handle<JSObject> object = Handle<JSObject>::cast(holder);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      JSReceiver::DeleteProperty(object, name));
-  return *result;
-}
-
-
-// A mechanism to return a pair of Object pointers in registers (if possible).
-// How this is achieved is calling convention-dependent.
-// All currently supported x86 compiles uses calling conventions that are cdecl
-// variants where a 64-bit value is returned in two 32-bit registers
-// (edx:eax on ia32, r1:r0 on ARM).
-// In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
-// In Win64 calling convention, a struct of two pointers is returned in memory,
-// allocated by the caller, and passed as a pointer in a hidden first parameter.
-#ifdef V8_HOST_ARCH_64_BIT
-struct ObjectPair {
-  Object* x;
-  Object* y;
-};
-
-
-static inline ObjectPair MakePair(Object* x, Object* y) {
-  ObjectPair result = {x, y};
-  // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
-  // In Win64 they are assigned to a hidden first argument.
-  return result;
-}
-#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
-// For x32 a 128-bit struct return is done as rax and rdx from the ObjectPair
-// are used in the full codegen and Crankshaft compiler. An alternative is
-// using uint64_t and modifying full codegen and Crankshaft compiler.
-struct ObjectPair {
-  Object* x;
-  uint32_t x_upper;
-  Object* y;
-  uint32_t y_upper;
-};
-
-
-static inline ObjectPair MakePair(Object* x, Object* y) {
-  ObjectPair result = {x, 0, y, 0};
-  // Pointers x and y returned in rax and rdx, in x32-abi.
-  return result;
-}
-#else
-typedef uint64_t ObjectPair;
-static inline ObjectPair MakePair(Object* x, Object* y) {
-#if defined(V8_TARGET_LITTLE_ENDIAN)
-  return reinterpret_cast<uint32_t>(x) |
-      (reinterpret_cast<ObjectPair>(y) << 32);
-#elif defined(V8_TARGET_BIG_ENDIAN)
-    return reinterpret_cast<uint32_t>(y) |
-        (reinterpret_cast<ObjectPair>(x) << 32);
-#else
-#error Unknown endianness
-#endif
-}
-#endif
-
-
-static Object* ComputeReceiverForNonGlobal(Isolate* isolate,
-                                           JSObject* holder) {
-  DCHECK(!holder->IsGlobalObject());
-  Context* top = isolate->context();
-  // Get the context extension function.
-  JSFunction* context_extension_function =
-      top->native_context()->context_extension_function();
-  // If the holder isn't a context extension object, we just return it
-  // as the receiver. This allows arguments objects to be used as
-  // receivers, but only if they are put in the context scope chain
-  // explicitly via a with-statement.
-  Object* constructor = holder->map()->constructor();
-  if (constructor != context_extension_function) return holder;
-  // Fall back to using the global object as the implicit receiver if
-  // the property turns out to be a local variable allocated in a
-  // context extension object - introduced via eval.
-  return isolate->heap()->undefined_value();
-}
-
-
-static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate,
-                                       bool throw_error) {
-  HandleScope scope(isolate);
-  DCHECK_EQ(2, args.length());
-
-  if (!args[0]->IsContext() || !args[1]->IsString()) {
-    return MakePair(isolate->ThrowIllegalOperation(), NULL);
-  }
-  Handle<Context> context = args.at<Context>(0);
-  Handle<String> name = args.at<String>(1);
-
-  int index;
-  PropertyAttributes attributes;
-  ContextLookupFlags flags = FOLLOW_CHAINS;
-  BindingFlags binding_flags;
-  Handle<Object> holder = context->Lookup(name,
-                                          flags,
-                                          &index,
-                                          &attributes,
-                                          &binding_flags);
-  if (isolate->has_pending_exception()) {
-    return MakePair(isolate->heap()->exception(), NULL);
-  }
-
-  // If the index is non-negative, the slot has been found in a context.
-  if (index >= 0) {
-    DCHECK(holder->IsContext());
-    // If the "property" we were looking for is a local variable, the
-    // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
-    Handle<Object> receiver = isolate->factory()->undefined_value();
-    Object* value = Context::cast(*holder)->get(index);
-    // Check for uninitialized bindings.
-    switch (binding_flags) {
-      case MUTABLE_CHECK_INITIALIZED:
-      case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
-        if (value->IsTheHole()) {
-          Handle<Object> error;
-          MaybeHandle<Object> maybe_error =
-              isolate->factory()->NewReferenceError("not_defined",
-                                                    HandleVector(&name, 1));
-          if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
-          return MakePair(isolate->heap()->exception(), NULL);
-        }
-        // FALLTHROUGH
-      case MUTABLE_IS_INITIALIZED:
-      case IMMUTABLE_IS_INITIALIZED:
-      case IMMUTABLE_IS_INITIALIZED_HARMONY:
-        DCHECK(!value->IsTheHole());
-        return MakePair(value, *receiver);
-      case IMMUTABLE_CHECK_INITIALIZED:
-        if (value->IsTheHole()) {
-          DCHECK((attributes & READ_ONLY) != 0);
-          value = isolate->heap()->undefined_value();
-        }
-        return MakePair(value, *receiver);
-      case MISSING_BINDING:
-        UNREACHABLE();
-        return MakePair(NULL, NULL);
-    }
-  }
-
-  // Otherwise, if the slot was found the holder is a context extension
-  // object, subject of a with, or a global object.  We read the named
-  // property from it.
-  if (!holder.is_null()) {
-    Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
-#ifdef DEBUG
-    if (!object->IsJSProxy()) {
-      Maybe<bool> maybe = JSReceiver::HasProperty(object, name);
-      DCHECK(maybe.has_value);
-      DCHECK(maybe.value);
-    }
-#endif
-    // GetProperty below can cause GC.
-    Handle<Object> receiver_handle(
-        object->IsGlobalObject()
-            ? Object::cast(isolate->heap()->undefined_value())
-            : object->IsJSProxy() ? static_cast<Object*>(*object)
-                : ComputeReceiverForNonGlobal(isolate, JSObject::cast(*object)),
-        isolate);
-
-    // No need to unhole the value here.  This is taken care of by the
-    // GetProperty function.
-    Handle<Object> value;
-    ASSIGN_RETURN_ON_EXCEPTION_VALUE(
-        isolate, value,
-        Object::GetProperty(object, name),
-        MakePair(isolate->heap()->exception(), NULL));
-    return MakePair(*value, *receiver_handle);
-  }
-
-  if (throw_error) {
-    // The property doesn't exist - throw exception.
-    Handle<Object> error;
-    MaybeHandle<Object> maybe_error = isolate->factory()->NewReferenceError(
-        "not_defined", HandleVector(&name, 1));
-    if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
-    return MakePair(isolate->heap()->exception(), NULL);
-  } else {
-    // The property doesn't exist - return undefined.
-    return MakePair(isolate->heap()->undefined_value(),
-                    isolate->heap()->undefined_value());
-  }
-}
-
-
-RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlot) {
-  return LoadLookupSlotHelper(args, isolate, true);
-}
-
-
-RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotNoReferenceError) {
-  return LoadLookupSlotHelper(args, isolate, false);
-}
-
-
-RUNTIME_FUNCTION(Runtime_StoreLookupSlot) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
-  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3);
-
-  int index;
-  PropertyAttributes attributes;
-  ContextLookupFlags flags = FOLLOW_CHAINS;
-  BindingFlags binding_flags;
-  Handle<Object> holder = context->Lookup(name,
-                                          flags,
-                                          &index,
-                                          &attributes,
-                                          &binding_flags);
-  // In case of JSProxy, an exception might have been thrown.
-  if (isolate->has_pending_exception()) return isolate->heap()->exception();
-
-  // The property was found in a context slot.
-  if (index >= 0) {
-    if ((attributes & READ_ONLY) == 0) {
-      Handle<Context>::cast(holder)->set(index, *value);
-    } else if (strict_mode == STRICT) {
-      // Setting read only property in strict mode.
-      THROW_NEW_ERROR_RETURN_FAILURE(
-          isolate,
-          NewTypeError("strict_cannot_assign", HandleVector(&name, 1)));
-    }
-    return *value;
-  }
-
-  // Slow case: The property is not in a context slot.  It is either in a
-  // context extension object, a property of the subject of a with, or a
-  // property of the global object.
-  Handle<JSReceiver> object;
-  if (attributes != ABSENT) {
-    // The property exists on the holder.
-    object = Handle<JSReceiver>::cast(holder);
-  } else if (strict_mode == STRICT) {
-    // If absent in strict mode: throw.
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewReferenceError("not_defined", HandleVector(&name, 1)));
-  } else {
-    // If absent in sloppy mode: add the property to the global object.
-    object = Handle<JSReceiver>(context->global_object());
-  }
-
-  RETURN_FAILURE_ON_EXCEPTION(
-      isolate, Object::SetProperty(object, name, value, strict_mode));
-
-  return *value;
-}
-
-
-RUNTIME_FUNCTION(Runtime_Throw) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  return isolate->Throw(args[0]);
-}
-
-
-RUNTIME_FUNCTION(Runtime_ReThrow) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  return isolate->ReThrow(args[0]);
-}
-
-
-RUNTIME_FUNCTION(Runtime_PromoteScheduledException) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  return isolate->PromoteScheduledException();
-}
-
-
-RUNTIME_FUNCTION(Runtime_ThrowReferenceError) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
-  THROW_NEW_ERROR_RETURN_FAILURE(
-      isolate, NewReferenceError("not_defined", HandleVector(&name, 1)));
-}
-
-
-RUNTIME_FUNCTION(Runtime_ThrowNonMethodError) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  THROW_NEW_ERROR_RETURN_FAILURE(
-      isolate, NewReferenceError("non_method", HandleVector<Object>(NULL, 0)));
-}
-
-
-RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  THROW_NEW_ERROR_RETURN_FAILURE(
-      isolate,
-      NewReferenceError("unsupported_super", HandleVector<Object>(NULL, 0)));
-}
-
-
-RUNTIME_FUNCTION(Runtime_ThrowNotDateError) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  THROW_NEW_ERROR_RETURN_FAILURE(
-      isolate, NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
-}
-
-
-RUNTIME_FUNCTION(Runtime_StackGuard) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-
-  // First check if this is a real stack overflow.
-  StackLimitCheck check(isolate);
-  if (check.JsHasOverflowed()) {
-    return isolate->StackOverflow();
-  }
-
-  return isolate->stack_guard()->HandleInterrupts();
-}
-
-
-RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-
-  // First check if this is a real stack overflow.
-  StackLimitCheck check(isolate);
-  if (check.JsHasOverflowed()) {
-    SealHandleScope shs(isolate);
-    return isolate->StackOverflow();
-  }
-
-  isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
-  return (function->IsOptimized()) ? function->code()
-                                   : function->shared()->code();
-}
-
-
-RUNTIME_FUNCTION(Runtime_Interrupt) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  return isolate->stack_guard()->HandleInterrupts();
-}
-
-
-static int StackSize(Isolate* isolate) {
-  int n = 0;
-  for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
-  return n;
-}
-
-
-static void PrintTransition(Isolate* isolate, Object* result) {
-  // indentation
-  { const int nmax = 80;
-    int n = StackSize(isolate);
-    if (n <= nmax)
-      PrintF("%4d:%*s", n, n, "");
-    else
-      PrintF("%4d:%*s", n, nmax, "...");
-  }
-
-  if (result == NULL) {
-    JavaScriptFrame::PrintTop(isolate, stdout, true, false);
-    PrintF(" {\n");
-  } else {
-    // function result
-    PrintF("} -> ");
-    result->ShortPrint();
-    PrintF("\n");
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_TraceEnter) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  PrintTransition(isolate, NULL);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_TraceExit) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  PrintTransition(isolate, obj);
-  return obj;  // return TOS
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugPrint) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  OFStream os(stdout);
-#ifdef DEBUG
-  if (args[0]->IsString()) {
-    // If we have a string, assume it's a code "marker"
-    // and print some interesting cpu debugging info.
-    JavaScriptFrameIterator it(isolate);
-    JavaScriptFrame* frame = it.frame();
-    os << "fp = " << frame->fp() << ", sp = " << frame->sp()
-       << ", caller_sp = " << frame->caller_sp() << ": ";
-  } else {
-    os << "DebugPrint: ";
-  }
-  args[0]->Print(os);
-  if (args[0]->IsHeapObject()) {
-    os << "\n";
-    HeapObject::cast(args[0])->map()->Print(os);
-  }
-#else
-  // ShortPrint is available in release mode. Print is not.
-  os << Brief(args[0]);
-#endif
-  os << endl;
-
-  return args[0];  // return TOS
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugTrace) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  isolate->PrintStack(stdout);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  if (FLAG_log_timer_events) LOG(isolate, CurrentTimeEvent());
-
-  // According to ECMA-262, section 15.9.1, page 117, the precision of
-  // the number in a Date object representing a particular instant in
-  // time is milliseconds. Therefore, we floor the result of getting
-  // the OS time.
-  double millis;
-  if (FLAG_verify_predictable) {
-    millis = 1388534400000.0;  // Jan 1 2014 00:00:00 GMT+0000
-    millis += Floor(isolate->heap()->synthetic_time());
-  } else {
-    millis = Floor(base::OS::TimeCurrentMillis());
-  }
-  return *isolate->factory()->NewNumber(millis);
-}
-
-
-RUNTIME_FUNCTION(Runtime_DateParseString) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
-
-  RUNTIME_ASSERT(output->HasFastElements());
-  JSObject::EnsureCanContainHeapObjectElements(output);
-  RUNTIME_ASSERT(output->HasFastObjectElements());
-  Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
-  RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
-
-  str = String::Flatten(str);
-  DisallowHeapAllocation no_gc;
-
-  bool result;
-  String::FlatContent str_content = str->GetFlatContent();
-  if (str_content.IsOneByte()) {
-    result = DateParser::Parse(str_content.ToOneByteVector(),
-                               *output_array,
-                               isolate->unicode_cache());
-  } else {
-    DCHECK(str_content.IsTwoByte());
-    result = DateParser::Parse(str_content.ToUC16Vector(),
-                               *output_array,
-                               isolate->unicode_cache());
-  }
-
-  if (result) {
-    return *output;
-  } else {
-    return isolate->heap()->null_value();
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
-                 x <= DateCache::kMaxTimeBeforeUTCInMs);
-  const char* zone =
-      isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
-  Handle<String> result = isolate->factory()->NewStringFromUtf8(
-      CStrVector(zone)).ToHandleChecked();
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_DateToUTC) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
-  RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
-                 x <= DateCache::kMaxTimeBeforeUTCInMs);
-  int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
-
-  return *isolate->factory()->NewNumber(static_cast<double>(time));
-}
-
-
-RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
-  HandleScope hs(isolate);
-  DCHECK(args.length() == 0);
-  if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
-    Handle<FixedArray> date_cache_version =
-        isolate->factory()->NewFixedArray(1, TENURED);
-    date_cache_version->set(0, Smi::FromInt(0));
-    isolate->eternal_handles()->CreateSingleton(
-        isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
-  }
-  Handle<FixedArray> date_cache_version =
-      Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
-          EternalHandles::DATE_CACHE_VERSION));
-  // Return result as a JS array.
-  Handle<JSObject> result =
-      isolate->factory()->NewJSObject(isolate->array_function());
-  JSArray::SetContent(Handle<JSArray>::cast(result), date_cache_version);
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_GlobalProxy) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, global, 0);
-  if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
-  return JSGlobalObject::cast(global)->global_proxy();
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsAttachedGlobal) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, global, 0);
-  if (!global->IsJSGlobalObject()) return isolate->heap()->false_value();
-  return isolate->heap()->ToBoolean(
-      !JSGlobalObject::cast(global)->IsDetached());
-}
-
-
-RUNTIME_FUNCTION(Runtime_ParseJson) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
-
-  source = String::Flatten(source);
-  // Optimized fast case where we only have Latin1 characters.
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      source->IsSeqOneByteString() ? JsonParser<true>::Parse(source)
-                                   : JsonParser<false>::Parse(source));
-  return *result;
-}
-
-
-bool CodeGenerationFromStringsAllowed(Isolate* isolate,
-                                      Handle<Context> context) {
-  DCHECK(context->allow_code_gen_from_strings()->IsFalse());
-  // Check with callback if set.
-  AllowCodeGenerationFromStringsCallback callback =
-      isolate->allow_code_gen_callback();
-  if (callback == NULL) {
-    // No callback set and code generation disallowed.
-    return false;
-  } else {
-    // Callback set. Let it decide if code generation is allowed.
-    VMState<EXTERNAL> state(isolate);
-    return callback(v8::Utils::ToLocal(context));
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_CompileString) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
-  CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
-
-  // Extract native context.
-  Handle<Context> context(isolate->native_context());
-
-  // Check if native context allows code generation from
-  // strings. Throw an exception if it doesn't.
-  if (context->allow_code_gen_from_strings()->IsFalse() &&
-      !CodeGenerationFromStringsAllowed(isolate, context)) {
-    Handle<Object> error_message =
-        context->ErrorMessageForCodeGenerationFromStrings();
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate, NewEvalError("code_gen_from_strings",
-                              HandleVector<Object>(&error_message, 1)));
-  }
-
-  // Compile source string in the native context.
-  ParseRestriction restriction = function_literal_only
-      ? ONLY_SINGLE_FUNCTION_LITERAL : NO_PARSE_RESTRICTION;
-  Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate);
-  Handle<JSFunction> fun;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, fun,
-      Compiler::GetFunctionFromEval(
-          source, outer_info,
-          context, SLOPPY, restriction, RelocInfo::kNoPosition));
-  return *fun;
-}
-
-
-static ObjectPair CompileGlobalEval(Isolate* isolate,
-                                    Handle<String> source,
-                                    Handle<SharedFunctionInfo> outer_info,
-                                    Handle<Object> receiver,
-                                    StrictMode strict_mode,
-                                    int scope_position) {
-  Handle<Context> context = Handle<Context>(isolate->context());
-  Handle<Context> native_context = Handle<Context>(context->native_context());
-
-  // Check if native context allows code generation from
-  // strings. Throw an exception if it doesn't.
-  if (native_context->allow_code_gen_from_strings()->IsFalse() &&
-      !CodeGenerationFromStringsAllowed(isolate, native_context)) {
-    Handle<Object> error_message =
-        native_context->ErrorMessageForCodeGenerationFromStrings();
-    Handle<Object> error;
-    MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError(
-        "code_gen_from_strings", HandleVector<Object>(&error_message, 1));
-    if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
-    return MakePair(isolate->heap()->exception(), NULL);
-  }
-
-  // Deal with a normal eval call with a string argument. Compile it
-  // and return the compiled function bound in the local context.
-  static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
-  Handle<JSFunction> compiled;
-  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
-      isolate, compiled,
-      Compiler::GetFunctionFromEval(
-          source, outer_info,
-          context, strict_mode, restriction, scope_position),
-      MakePair(isolate->heap()->exception(), NULL));
-  return MakePair(*compiled, *receiver);
-}
-
-
-RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 6);
-
-  Handle<Object> callee = args.at<Object>(0);
-
-  // If "eval" didn't refer to the original GlobalEval, it's not a
-  // direct call to eval.
-  // (And even if it is, but the first argument isn't a string, just let
-  // execution default to an indirect call to eval, which will also return
-  // the first argument without doing anything).
-  if (*callee != isolate->native_context()->global_eval_fun() ||
-      !args[1]->IsString()) {
-    return MakePair(*callee, isolate->heap()->undefined_value());
-  }
-
-  DCHECK(args[4]->IsSmi());
-  DCHECK(args.smi_at(4) == SLOPPY || args.smi_at(4) == STRICT);
-  StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(4));
-  DCHECK(args[5]->IsSmi());
-  Handle<SharedFunctionInfo> outer_info(args.at<JSFunction>(2)->shared(),
-                                        isolate);
-  return CompileGlobalEval(isolate,
-                           args.at<String>(1),
-                           outer_info,
-                           args.at<Object>(3),
-                           strict_mode,
-                           args.smi_at(5));
-}
-
-
-RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_SMI_ARG_CHECKED(size, 0);
-  RUNTIME_ASSERT(IsAligned(size, kPointerSize));
-  RUNTIME_ASSERT(size > 0);
-  RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
-  return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
-}
-
-
-RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_SMI_ARG_CHECKED(size, 0);
-  CONVERT_SMI_ARG_CHECKED(flags, 1);
-  RUNTIME_ASSERT(IsAligned(size, kPointerSize));
-  RUNTIME_ASSERT(size > 0);
-  RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
-  bool double_align = AllocateDoubleAlignFlag::decode(flags);
-  AllocationSpace space = AllocateTargetSpace::decode(flags);
-  return *isolate->factory()->NewFillerObject(size, double_align, space);
-}
-
-
-// Push an object unto an array of objects if it is not already in the
-// array.  Returns true if the element was pushed on the stack and
-// false otherwise.
-RUNTIME_FUNCTION(Runtime_PushIfAbsent) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
-  RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
-  int length = Smi::cast(array->length())->value();
-  FixedArray* elements = FixedArray::cast(array->elements());
-  for (int i = 0; i < length; i++) {
-    if (elements->get(i) == *element) return isolate->heap()->false_value();
-  }
-
-  // Strict not needed. Used for cycle detection in Array join implementation.
-  RETURN_FAILURE_ON_EXCEPTION(
-      isolate,
-      JSObject::SetFastElement(array, length, element, SLOPPY, true));
-  return isolate->heap()->true_value();
-}
-
-
-/**
- * A simple visitor visits every element of Array's.
- * The backend storage can be a fixed array for fast elements case,
- * or a dictionary for sparse array. Since Dictionary is a subtype
- * of FixedArray, the class can be used by both fast and slow cases.
- * The second parameter of the constructor, fast_elements, specifies
- * whether the storage is a FixedArray or Dictionary.
- *
- * An index limit is used to deal with the situation that a result array
- * length overflows 32-bit non-negative integer.
- */
-class ArrayConcatVisitor {
- public:
-  ArrayConcatVisitor(Isolate* isolate,
-                     Handle<FixedArray> storage,
-                     bool fast_elements) :
-      isolate_(isolate),
-      storage_(Handle<FixedArray>::cast(
-          isolate->global_handles()->Create(*storage))),
-      index_offset_(0u),
-      fast_elements_(fast_elements),
-      exceeds_array_limit_(false) { }
-
-  ~ArrayConcatVisitor() {
-    clear_storage();
-  }
-
-  void visit(uint32_t i, Handle<Object> elm) {
-    if (i > JSObject::kMaxElementCount - index_offset_) {
-      exceeds_array_limit_ = true;
-      return;
-    }
-    uint32_t index = index_offset_ + i;
-
-    if (fast_elements_) {
-      if (index < static_cast<uint32_t>(storage_->length())) {
-        storage_->set(index, *elm);
-        return;
-      }
-      // Our initial estimate of length was foiled, possibly by
-      // getters on the arrays increasing the length of later arrays
-      // during iteration.
-      // This shouldn't happen in anything but pathological cases.
-      SetDictionaryMode();
-      // Fall-through to dictionary mode.
-    }
-    DCHECK(!fast_elements_);
-    Handle<SeededNumberDictionary> dict(
-        SeededNumberDictionary::cast(*storage_));
-    Handle<SeededNumberDictionary> result =
-        SeededNumberDictionary::AtNumberPut(dict, index, elm);
-    if (!result.is_identical_to(dict)) {
-      // Dictionary needed to grow.
-      clear_storage();
-      set_storage(*result);
-    }
-  }
-
-  void increase_index_offset(uint32_t delta) {
-    if (JSObject::kMaxElementCount - index_offset_ < delta) {
-      index_offset_ = JSObject::kMaxElementCount;
-    } else {
-      index_offset_ += delta;
-    }
-    // If the initial length estimate was off (see special case in visit()),
-    // but the array blowing the limit didn't contain elements beyond the
-    // provided-for index range, go to dictionary mode now.
-    if (fast_elements_ &&
-        index_offset_ >
-            static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) {
-      SetDictionaryMode();
-    }
-  }
-
-  bool exceeds_array_limit() {
-    return exceeds_array_limit_;
-  }
-
-  Handle<JSArray> ToArray() {
-    Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
-    Handle<Object> length =
-        isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
-    Handle<Map> map = JSObject::GetElementsTransitionMap(
-        array,
-        fast_elements_ ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
-    array->set_map(*map);
-    array->set_length(*length);
-    array->set_elements(*storage_);
-    return array;
-  }
-
- private:
-  // Convert storage to dictionary mode.
-  void SetDictionaryMode() {
-    DCHECK(fast_elements_);
-    Handle<FixedArray> current_storage(*storage_);
-    Handle<SeededNumberDictionary> slow_storage(
-        SeededNumberDictionary::New(isolate_, current_storage->length()));
-    uint32_t current_length = static_cast<uint32_t>(current_storage->length());
-    for (uint32_t i = 0; i < current_length; i++) {
-      HandleScope loop_scope(isolate_);
-      Handle<Object> element(current_storage->get(i), isolate_);
-      if (!element->IsTheHole()) {
-        Handle<SeededNumberDictionary> new_storage =
-            SeededNumberDictionary::AtNumberPut(slow_storage, i, element);
-        if (!new_storage.is_identical_to(slow_storage)) {
-          slow_storage = loop_scope.CloseAndEscape(new_storage);
-        }
-      }
-    }
-    clear_storage();
-    set_storage(*slow_storage);
-    fast_elements_ = false;
-  }
-
-  inline void clear_storage() {
-    GlobalHandles::Destroy(Handle<Object>::cast(storage_).location());
-  }
-
-  inline void set_storage(FixedArray* storage) {
-    storage_ = Handle<FixedArray>::cast(
-        isolate_->global_handles()->Create(storage));
-  }
-
-  Isolate* isolate_;
-  Handle<FixedArray> storage_;  // Always a global handle.
-  // Index after last seen index. Always less than or equal to
-  // JSObject::kMaxElementCount.
-  uint32_t index_offset_;
-  bool fast_elements_ : 1;
-  bool exceeds_array_limit_ : 1;
-};
-
-
-static uint32_t EstimateElementCount(Handle<JSArray> array) {
-  uint32_t length = static_cast<uint32_t>(array->length()->Number());
-  int element_count = 0;
-  switch (array->GetElementsKind()) {
-    case FAST_SMI_ELEMENTS:
-    case FAST_HOLEY_SMI_ELEMENTS:
-    case FAST_ELEMENTS:
-    case FAST_HOLEY_ELEMENTS: {
-      // Fast elements can't have lengths that are not representable by
-      // a 32-bit signed integer.
-      DCHECK(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
-      int fast_length = static_cast<int>(length);
-      Handle<FixedArray> elements(FixedArray::cast(array->elements()));
-      for (int i = 0; i < fast_length; i++) {
-        if (!elements->get(i)->IsTheHole()) element_count++;
-      }
-      break;
-    }
-    case FAST_DOUBLE_ELEMENTS:
-    case FAST_HOLEY_DOUBLE_ELEMENTS: {
-      // Fast elements can't have lengths that are not representable by
-      // a 32-bit signed integer.
-      DCHECK(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
-      int fast_length = static_cast<int>(length);
-      if (array->elements()->IsFixedArray()) {
-        DCHECK(FixedArray::cast(array->elements())->length() == 0);
-        break;
-      }
-      Handle<FixedDoubleArray> elements(
-          FixedDoubleArray::cast(array->elements()));
-      for (int i = 0; i < fast_length; i++) {
-        if (!elements->is_the_hole(i)) element_count++;
-      }
-      break;
-    }
-    case DICTIONARY_ELEMENTS: {
-      Handle<SeededNumberDictionary> dictionary(
-          SeededNumberDictionary::cast(array->elements()));
-      int capacity = dictionary->Capacity();
-      for (int i = 0; i < capacity; i++) {
-        Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
-        if (dictionary->IsKey(*key)) {
-          element_count++;
-        }
-      }
-      break;
-    }
-    case SLOPPY_ARGUMENTS_ELEMENTS:
-#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size)                      \
-    case EXTERNAL_##TYPE##_ELEMENTS:                                         \
-    case TYPE##_ELEMENTS:                                                    \
-
-    TYPED_ARRAYS(TYPED_ARRAY_CASE)
-#undef TYPED_ARRAY_CASE
-      // External arrays are always dense.
-      return length;
-  }
-  // As an estimate, we assume that the prototype doesn't contain any
-  // inherited elements.
-  return element_count;
-}
-
-
-
-template<class ExternalArrayClass, class ElementType>
-static void IterateExternalArrayElements(Isolate* isolate,
-                                         Handle<JSObject> receiver,
-                                         bool elements_are_ints,
-                                         bool elements_are_guaranteed_smis,
-                                         ArrayConcatVisitor* visitor) {
-  Handle<ExternalArrayClass> array(
-      ExternalArrayClass::cast(receiver->elements()));
-  uint32_t len = static_cast<uint32_t>(array->length());
-
-  DCHECK(visitor != NULL);
-  if (elements_are_ints) {
-    if (elements_are_guaranteed_smis) {
-      for (uint32_t j = 0; j < len; j++) {
-        HandleScope loop_scope(isolate);
-        Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))),
-                      isolate);
-        visitor->visit(j, e);
-      }
-    } else {
-      for (uint32_t j = 0; j < len; j++) {
-        HandleScope loop_scope(isolate);
-        int64_t val = static_cast<int64_t>(array->get_scalar(j));
-        if (Smi::IsValid(static_cast<intptr_t>(val))) {
-          Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate);
-          visitor->visit(j, e);
-        } else {
-          Handle<Object> e =
-              isolate->factory()->NewNumber(static_cast<ElementType>(val));
-          visitor->visit(j, e);
-        }
-      }
-    }
-  } else {
-    for (uint32_t j = 0; j < len; j++) {
-      HandleScope loop_scope(isolate);
-      Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
-      visitor->visit(j, e);
-    }
-  }
-}
-
-
-// Used for sorting indices in a List<uint32_t>.
-static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
-  uint32_t a = *ap;
-  uint32_t b = *bp;
-  return (a == b) ? 0 : (a < b) ? -1 : 1;
-}
-
-
-static void CollectElementIndices(Handle<JSObject> object,
-                                  uint32_t range,
-                                  List<uint32_t>* indices) {
-  Isolate* isolate = object->GetIsolate();
-  ElementsKind kind = object->GetElementsKind();
-  switch (kind) {
-    case FAST_SMI_ELEMENTS:
-    case FAST_ELEMENTS:
-    case FAST_HOLEY_SMI_ELEMENTS:
-    case FAST_HOLEY_ELEMENTS: {
-      Handle<FixedArray> elements(FixedArray::cast(object->elements()));
-      uint32_t length = static_cast<uint32_t>(elements->length());
-      if (range < length) length = range;
-      for (uint32_t i = 0; i < length; i++) {
-        if (!elements->get(i)->IsTheHole()) {
-          indices->Add(i);
-        }
-      }
-      break;
-    }
-    case FAST_HOLEY_DOUBLE_ELEMENTS:
-    case FAST_DOUBLE_ELEMENTS: {
-      if (object->elements()->IsFixedArray()) {
-        DCHECK(object->elements()->length() == 0);
-        break;
-      }
-      Handle<FixedDoubleArray> elements(
-          FixedDoubleArray::cast(object->elements()));
-      uint32_t length = static_cast<uint32_t>(elements->length());
-      if (range < length) length = range;
-      for (uint32_t i = 0; i < length; i++) {
-        if (!elements->is_the_hole(i)) {
-          indices->Add(i);
-        }
-      }
-      break;
-    }
-    case DICTIONARY_ELEMENTS: {
-      Handle<SeededNumberDictionary> dict(
-          SeededNumberDictionary::cast(object->elements()));
-      uint32_t capacity = dict->Capacity();
-      for (uint32_t j = 0; j < capacity; j++) {
-        HandleScope loop_scope(isolate);
-        Handle<Object> k(dict->KeyAt(j), isolate);
-        if (dict->IsKey(*k)) {
-          DCHECK(k->IsNumber());
-          uint32_t index = static_cast<uint32_t>(k->Number());
-          if (index < range) {
-            indices->Add(index);
-          }
-        }
-      }
-      break;
-    }
-#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
-    case TYPE##_ELEMENTS:                               \
-    case EXTERNAL_##TYPE##_ELEMENTS:
-
-      TYPED_ARRAYS(TYPED_ARRAY_CASE)
-#undef TYPED_ARRAY_CASE
-    {
-      uint32_t length = static_cast<uint32_t>(
-          FixedArrayBase::cast(object->elements())->length());
-      if (range <= length) {
-        length = range;
-        // We will add all indices, so we might as well clear it first
-        // and avoid duplicates.
-        indices->Clear();
-      }
-      for (uint32_t i = 0; i < length; i++) {
-        indices->Add(i);
-      }
-      if (length == range) return;  // All indices accounted for already.
-      break;
-    }
-    case SLOPPY_ARGUMENTS_ELEMENTS: {
-      MaybeHandle<Object> length_obj =
-          Object::GetProperty(object, isolate->factory()->length_string());
-      double length_num = length_obj.ToHandleChecked()->Number();
-      uint32_t length = static_cast<uint32_t>(DoubleToInt32(length_num));
-      ElementsAccessor* accessor = object->GetElementsAccessor();
-      for (uint32_t i = 0; i < length; i++) {
-        if (accessor->HasElement(object, object, i)) {
-          indices->Add(i);
-        }
-      }
-      break;
-    }
-  }
-
-  PrototypeIterator iter(isolate, object);
-  if (!iter.IsAtEnd()) {
-    // The prototype will usually have no inherited element indices,
-    // but we have to check.
-    CollectElementIndices(
-        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range,
-        indices);
-  }
-}
-
-
-/**
- * A helper function that visits elements of a JSArray in numerical
- * order.
- *
- * The visitor argument called for each existing element in the array
- * with the element index and the element's value.
- * Afterwards it increments the base-index of the visitor by the array
- * length.
- * Returns false if any access threw an exception, otherwise true.
- */
-static bool IterateElements(Isolate* isolate,
-                            Handle<JSArray> receiver,
-                            ArrayConcatVisitor* visitor) {
-  uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
-  switch (receiver->GetElementsKind()) {
-    case FAST_SMI_ELEMENTS:
-    case FAST_ELEMENTS:
-    case FAST_HOLEY_SMI_ELEMENTS:
-    case FAST_HOLEY_ELEMENTS: {
-      // Run through the elements FixedArray and use HasElement and GetElement
-      // to check the prototype for missing elements.
-      Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
-      int fast_length = static_cast<int>(length);
-      DCHECK(fast_length <= elements->length());
-      for (int j = 0; j < fast_length; j++) {
-        HandleScope loop_scope(isolate);
-        Handle<Object> element_value(elements->get(j), isolate);
-        if (!element_value->IsTheHole()) {
-          visitor->visit(j, element_value);
-        } else {
-          Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
-          if (!maybe.has_value) return false;
-          if (maybe.value) {
-            // Call GetElement on receiver, not its prototype, or getters won't
-            // have the correct receiver.
-            ASSIGN_RETURN_ON_EXCEPTION_VALUE(
-                isolate, element_value,
-                Object::GetElement(isolate, receiver, j), false);
-            visitor->visit(j, element_value);
-          }
-        }
-      }
-      break;
-    }
-    case FAST_HOLEY_DOUBLE_ELEMENTS:
-    case FAST_DOUBLE_ELEMENTS: {
-      // Empty array is FixedArray but not FixedDoubleArray.
-      if (length == 0) break;
-      // Run through the elements FixedArray and use HasElement and GetElement
-      // to check the prototype for missing elements.
-      if (receiver->elements()->IsFixedArray()) {
-        DCHECK(receiver->elements()->length() == 0);
-        break;
-      }
-      Handle<FixedDoubleArray> elements(
-          FixedDoubleArray::cast(receiver->elements()));
-      int fast_length = static_cast<int>(length);
-      DCHECK(fast_length <= elements->length());
-      for (int j = 0; j < fast_length; j++) {
-        HandleScope loop_scope(isolate);
-        if (!elements->is_the_hole(j)) {
-          double double_value = elements->get_scalar(j);
-          Handle<Object> element_value =
-              isolate->factory()->NewNumber(double_value);
-          visitor->visit(j, element_value);
-        } else {
-          Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
-          if (!maybe.has_value) return false;
-          if (maybe.value) {
-            // Call GetElement on receiver, not its prototype, or getters won't
-            // have the correct receiver.
-            Handle<Object> element_value;
-            ASSIGN_RETURN_ON_EXCEPTION_VALUE(
-                isolate, element_value,
-                Object::GetElement(isolate, receiver, j), false);
-            visitor->visit(j, element_value);
-          }
-        }
-      }
-      break;
-    }
-    case DICTIONARY_ELEMENTS: {
-      Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
-      List<uint32_t> indices(dict->Capacity() / 2);
-      // Collect all indices in the object and the prototypes less
-      // than length. This might introduce duplicates in the indices list.
-      CollectElementIndices(receiver, length, &indices);
-      indices.Sort(&compareUInt32);
-      int j = 0;
-      int n = indices.length();
-      while (j < n) {
-        HandleScope loop_scope(isolate);
-        uint32_t index = indices[j];
-        Handle<Object> element;
-        ASSIGN_RETURN_ON_EXCEPTION_VALUE(
-            isolate, element,
-            Object::GetElement(isolate, receiver, index),
-            false);
-        visitor->visit(index, element);
-        // Skip to next different index (i.e., omit duplicates).
-        do {
-          j++;
-        } while (j < n && indices[j] == index);
-      }
-      break;
-    }
-    case EXTERNAL_UINT8_CLAMPED_ELEMENTS: {
-      Handle<ExternalUint8ClampedArray> pixels(ExternalUint8ClampedArray::cast(
-          receiver->elements()));
-      for (uint32_t j = 0; j < length; j++) {
-        Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
-        visitor->visit(j, e);
-      }
-      break;
-    }
-    case EXTERNAL_INT8_ELEMENTS: {
-      IterateExternalArrayElements<ExternalInt8Array, int8_t>(
-          isolate, receiver, true, true, visitor);
-      break;
-    }
-    case EXTERNAL_UINT8_ELEMENTS: {
-      IterateExternalArrayElements<ExternalUint8Array, uint8_t>(
-          isolate, receiver, true, true, visitor);
-      break;
-    }
-    case EXTERNAL_INT16_ELEMENTS: {
-      IterateExternalArrayElements<ExternalInt16Array, int16_t>(
-          isolate, receiver, true, true, visitor);
-      break;
-    }
-    case EXTERNAL_UINT16_ELEMENTS: {
-      IterateExternalArrayElements<ExternalUint16Array, uint16_t>(
-          isolate, receiver, true, true, visitor);
-      break;
-    }
-    case EXTERNAL_INT32_ELEMENTS: {
-      IterateExternalArrayElements<ExternalInt32Array, int32_t>(
-          isolate, receiver, true, false, visitor);
-      break;
-    }
-    case EXTERNAL_UINT32_ELEMENTS: {
-      IterateExternalArrayElements<ExternalUint32Array, uint32_t>(
-          isolate, receiver, true, false, visitor);
-      break;
-    }
-    case EXTERNAL_FLOAT32_ELEMENTS: {
-      IterateExternalArrayElements<ExternalFloat32Array, float>(
-          isolate, receiver, false, false, visitor);
-      break;
-    }
-    case EXTERNAL_FLOAT64_ELEMENTS: {
-      IterateExternalArrayElements<ExternalFloat64Array, double>(
-          isolate, receiver, false, false, visitor);
-      break;
-    }
-    default:
-      UNREACHABLE();
-      break;
-  }
-  visitor->increase_index_offset(length);
-  return true;
-}
-
-
-/**
- * Array::concat implementation.
- * See ECMAScript 262, 15.4.4.4.
- * TODO(581): Fix non-compliance for very large concatenations and update to
- * following the ECMAScript 5 specification.
- */
-RUNTIME_FUNCTION(Runtime_ArrayConcat) {
-  HandleScope handle_scope(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
-  int argument_count = static_cast<int>(arguments->length()->Number());
-  RUNTIME_ASSERT(arguments->HasFastObjectElements());
-  Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
-
-  // Pass 1: estimate the length and number of elements of the result.
-  // The actual length can be larger if any of the arguments have getters
-  // that mutate other arguments (but will otherwise be precise).
-  // The number of elements is precise if there are no inherited elements.
-
-  ElementsKind kind = FAST_SMI_ELEMENTS;
-
-  uint32_t estimate_result_length = 0;
-  uint32_t estimate_nof_elements = 0;
-  for (int i = 0; i < argument_count; i++) {
-    HandleScope loop_scope(isolate);
-    Handle<Object> obj(elements->get(i), isolate);
-    uint32_t length_estimate;
-    uint32_t element_estimate;
-    if (obj->IsJSArray()) {
-      Handle<JSArray> array(Handle<JSArray>::cast(obj));
-      length_estimate = static_cast<uint32_t>(array->length()->Number());
-      if (length_estimate != 0) {
-        ElementsKind array_kind =
-            GetPackedElementsKind(array->map()->elements_kind());
-        if (IsMoreGeneralElementsKindTransition(kind, array_kind)) {
-          kind = array_kind;
-        }
-      }
-      element_estimate = EstimateElementCount(array);
-    } else {
-      if (obj->IsHeapObject()) {
-        if (obj->IsNumber()) {
-          if (IsMoreGeneralElementsKindTransition(kind, FAST_DOUBLE_ELEMENTS)) {
-            kind = FAST_DOUBLE_ELEMENTS;
-          }
-        } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) {
-          kind = FAST_ELEMENTS;
-        }
-      }
-      length_estimate = 1;
-      element_estimate = 1;
-    }
-    // Avoid overflows by capping at kMaxElementCount.
-    if (JSObject::kMaxElementCount - estimate_result_length <
-        length_estimate) {
-      estimate_result_length = JSObject::kMaxElementCount;
-    } else {
-      estimate_result_length += length_estimate;
-    }
-    if (JSObject::kMaxElementCount - estimate_nof_elements <
-        element_estimate) {
-      estimate_nof_elements = JSObject::kMaxElementCount;
-    } else {
-      estimate_nof_elements += element_estimate;
-    }
-  }
-
-  // If estimated number of elements is more than half of length, a
-  // fixed array (fast case) is more time and space-efficient than a
-  // dictionary.
-  bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
-
-  if (fast_case && kind == FAST_DOUBLE_ELEMENTS) {
-    Handle<FixedArrayBase> storage =
-        isolate->factory()->NewFixedDoubleArray(estimate_result_length);
-    int j = 0;
-    bool failure = false;
-    if (estimate_result_length > 0) {
-      Handle<FixedDoubleArray> double_storage =
-          Handle<FixedDoubleArray>::cast(storage);
-      for (int i = 0; i < argument_count; i++) {
-        Handle<Object> obj(elements->get(i), isolate);
-        if (obj->IsSmi()) {
-          double_storage->set(j, Smi::cast(*obj)->value());
-          j++;
-        } else if (obj->IsNumber()) {
-          double_storage->set(j, obj->Number());
-          j++;
-        } else {
-          JSArray* array = JSArray::cast(*obj);
-          uint32_t length = static_cast<uint32_t>(array->length()->Number());
-          switch (array->map()->elements_kind()) {
-            case FAST_HOLEY_DOUBLE_ELEMENTS:
-            case FAST_DOUBLE_ELEMENTS: {
-              // Empty array is FixedArray but not FixedDoubleArray.
-              if (length == 0) break;
-              FixedDoubleArray* elements =
-                  FixedDoubleArray::cast(array->elements());
-              for (uint32_t i = 0; i < length; i++) {
-                if (elements->is_the_hole(i)) {
-                  // TODO(jkummerow/verwaest): We could be a bit more clever
-                  // here: Check if there are no elements/getters on the
-                  // prototype chain, and if so, allow creation of a holey
-                  // result array.
-                  // Same thing below (holey smi case).
-                  failure = true;
-                  break;
-                }
-                double double_value = elements->get_scalar(i);
-                double_storage->set(j, double_value);
-                j++;
-              }
-              break;
-            }
-            case FAST_HOLEY_SMI_ELEMENTS:
-            case FAST_SMI_ELEMENTS: {
-              FixedArray* elements(
-                  FixedArray::cast(array->elements()));
-              for (uint32_t i = 0; i < length; i++) {
-                Object* element = elements->get(i);
-                if (element->IsTheHole()) {
-                  failure = true;
-                  break;
-                }
-                int32_t int_value = Smi::cast(element)->value();
-                double_storage->set(j, int_value);
-                j++;
-              }
-              break;
-            }
-            case FAST_HOLEY_ELEMENTS:
-            case FAST_ELEMENTS:
-              DCHECK_EQ(0, length);
-              break;
-            default:
-              UNREACHABLE();
-          }
-        }
-        if (failure) break;
-      }
-    }
-    if (!failure) {
-      Handle<JSArray> array = isolate->factory()->NewJSArray(0);
-      Smi* length = Smi::FromInt(j);
-      Handle<Map> map;
-      map = JSObject::GetElementsTransitionMap(array, kind);
-      array->set_map(*map);
-      array->set_length(length);
-      array->set_elements(*storage);
-      return *array;
-    }
-    // In case of failure, fall through.
-  }
-
-  Handle<FixedArray> storage;
-  if (fast_case) {
-    // The backing storage array must have non-existing elements to preserve
-    // holes across concat operations.
-    storage = isolate->factory()->NewFixedArrayWithHoles(
-        estimate_result_length);
-  } else {
-    // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
-    uint32_t at_least_space_for = estimate_nof_elements +
-                                  (estimate_nof_elements >> 2);
-    storage = Handle<FixedArray>::cast(
-        SeededNumberDictionary::New(isolate, at_least_space_for));
-  }
-
-  ArrayConcatVisitor visitor(isolate, storage, fast_case);
-
-  for (int i = 0; i < argument_count; i++) {
-    Handle<Object> obj(elements->get(i), isolate);
-    if (obj->IsJSArray()) {
-      Handle<JSArray> array = Handle<JSArray>::cast(obj);
-      if (!IterateElements(isolate, array, &visitor)) {
-        return isolate->heap()->exception();
-      }
-    } else {
-      visitor.visit(0, obj);
-      visitor.increase_index_offset(1);
-    }
-  }
-
-  if (visitor.exceeds_array_limit()) {
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate,
-        NewRangeError("invalid_array_length", HandleVector<Object>(NULL, 0)));
-  }
-  return *visitor.ToArray();
-}
-
-
-// This will not allocate (flatten the string), but it may run
-// very slowly for very deeply nested ConsStrings.  For debugging use only.
-RUNTIME_FUNCTION(Runtime_GlobalPrint) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(String, string, 0);
-  ConsStringIteratorOp op;
-  StringCharacterStream stream(string, &op);
-  while (stream.HasMore()) {
-    uint16_t character = stream.GetNext();
-    PrintF("%c", character);
-  }
-  return string;
-}
-
-
-// Moves all own elements of an object, that are below a limit, to positions
-// starting at zero. All undefined values are placed after non-undefined values,
-// and are followed by non-existing element. Does not change the length
-// property.
-// Returns the number of non-undefined elements collected.
-// Returns -1 if hole removal is not supported by this method.
-RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
-  return *JSObject::PrepareElementsForSort(object, limit);
-}
-
-
-// Move contents of argument 0 (an array) to argument 1 (an array)
-RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1);
-  JSObject::ValidateElements(from);
-  JSObject::ValidateElements(to);
-
-  Handle<FixedArrayBase> new_elements(from->elements());
-  ElementsKind from_kind = from->GetElementsKind();
-  Handle<Map> new_map = JSObject::GetElementsTransitionMap(to, from_kind);
-  JSObject::SetMapAndElements(to, new_map, new_elements);
-  to->set_length(from->length());
-
-  JSObject::ResetElements(from);
-  from->set_length(Smi::FromInt(0));
-
-  JSObject::ValidateElements(to);
-  return *to;
-}
-
-
-// How many elements does this object/array have?
-RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
-  Handle<FixedArrayBase> elements(array->elements(), isolate);
-  SealHandleScope shs(isolate);
-  if (elements->IsDictionary()) {
-    int result =
-        Handle<SeededNumberDictionary>::cast(elements)->NumberOfElements();
-    return Smi::FromInt(result);
-  } else {
-    DCHECK(array->length()->IsSmi());
-    // For packed elements, we know the exact number of elements
-    int length = elements->length();
-    ElementsKind kind = array->GetElementsKind();
-    if (IsFastPackedElementsKind(kind)) {
-      return Smi::FromInt(length);
-    }
-    // For holey elements, take samples from the buffer checking for holes
-    // to generate the estimate.
-    const int kNumberOfHoleCheckSamples = 97;
-    int increment = (length < kNumberOfHoleCheckSamples)
-                        ? 1
-                        : static_cast<int>(length / kNumberOfHoleCheckSamples);
-    ElementsAccessor* accessor = array->GetElementsAccessor();
-    int holes = 0;
-    for (int i = 0; i < length; i += increment) {
-      if (!accessor->HasElement(array, array, i, elements)) {
-        ++holes;
-      }
-    }
-    int estimate = static_cast<int>((kNumberOfHoleCheckSamples - holes) /
-                                    kNumberOfHoleCheckSamples * length);
-    return Smi::FromInt(estimate);
-  }
-}
-
-
-// Returns an array that tells you where in the [0, length) interval an array
-// might have elements.  Can either return an array of keys (positive integers
-// or undefined) or a number representing the positive length of an interval
-// starting at index 0.
-// Intervals can span over some keys that are not in the object.
-RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
-  CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
-  if (array->elements()->IsDictionary()) {
-    Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
-    for (PrototypeIterator iter(isolate, array,
-                                PrototypeIterator::START_AT_RECEIVER);
-         !iter.IsAtEnd(); iter.Advance()) {
-      if (PrototypeIterator::GetCurrent(iter)->IsJSProxy() ||
-          JSObject::cast(*PrototypeIterator::GetCurrent(iter))
-              ->HasIndexedInterceptor()) {
-        // Bail out if we find a proxy or interceptor, likely not worth
-        // collecting keys in that case.
-        return *isolate->factory()->NewNumberFromUint(length);
-      }
-      Handle<JSObject> current =
-          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
-      Handle<FixedArray> current_keys =
-          isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
-      current->GetOwnElementKeys(*current_keys, NONE);
-      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-          isolate, keys, FixedArray::UnionOfKeys(keys, current_keys));
-    }
-    // Erase any keys >= length.
-    // TODO(adamk): Remove this step when the contract of %GetArrayKeys
-    // is changed to let this happen on the JS side.
-    for (int i = 0; i < keys->length(); i++) {
-      if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
-    }
-    return *isolate->factory()->NewJSArrayWithElements(keys);
-  } else {
-    RUNTIME_ASSERT(array->HasFastSmiOrObjectElements() ||
-                   array->HasFastDoubleElements());
-    uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
-    return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_LookupAccessor) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-  CONVERT_SMI_ARG_CHECKED(flag, 2);
-  AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
-  if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugBreak) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  isolate->debug()->HandleDebugBreak();
-  return isolate->heap()->undefined_value();
-}
-
-
-// Helper functions for wrapping and unwrapping stack frame ids.
-static Smi* WrapFrameId(StackFrame::Id id) {
-  DCHECK(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
-  return Smi::FromInt(id >> 2);
-}
-
-
-static StackFrame::Id UnwrapFrameId(int wrapped) {
-  return static_cast<StackFrame::Id>(wrapped << 2);
-}
-
-
-// Adds a JavaScript function as a debug event listener.
-// args[0]: debug event listener function to set or null or undefined for
-//          clearing the event listener function
-// args[1]: object supplied during callback
-RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  RUNTIME_ASSERT(args[0]->IsJSFunction() ||
-                 args[0]->IsUndefined() ||
-                 args[0]->IsNull());
-  CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
-  isolate->debug()->SetEventListener(callback, data);
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_Break) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  isolate->stack_guard()->RequestDebugBreak();
-  return isolate->heap()->undefined_value();
-}
-
-
-static Handle<Object> DebugGetProperty(LookupIterator* it,
-                                       bool* has_caught = NULL) {
-  for (; it->IsFound(); it->Next()) {
-    switch (it->state()) {
-      case LookupIterator::NOT_FOUND:
-      case LookupIterator::TRANSITION:
-        UNREACHABLE();
-      case LookupIterator::ACCESS_CHECK:
-        // Ignore access checks.
-        break;
-      case LookupIterator::INTERCEPTOR:
-      case LookupIterator::JSPROXY:
-        return it->isolate()->factory()->undefined_value();
-      case LookupIterator::ACCESSOR: {
-        Handle<Object> accessors = it->GetAccessors();
-        if (!accessors->IsAccessorInfo()) {
-          return it->isolate()->factory()->undefined_value();
-        }
-        MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithAccessor(
-            it->GetReceiver(), it->name(), it->GetHolder<JSObject>(),
-            accessors);
-        Handle<Object> result;
-        if (!maybe_result.ToHandle(&result)) {
-          result = handle(it->isolate()->pending_exception(), it->isolate());
-          it->isolate()->clear_pending_exception();
-          if (has_caught != NULL) *has_caught = true;
-        }
-        return result;
-      }
-
-      case LookupIterator::DATA:
-        return it->GetDataValue();
-    }
-  }
-
-  return it->isolate()->factory()->undefined_value();
-}
-
-
-// Get debugger related details for an object property, in the following format:
-// 0: Property value
-// 1: Property details
-// 2: Property value is exception
-// 3: Getter function if defined
-// 4: Setter function if defined
-// Items 2-4 are only filled if the property has either a getter or a setter.
-RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-
-  // Make sure to set the current context to the context before the debugger was
-  // entered (if the debugger is entered). The reason for switching context here
-  // is that for some property lookups (accessors and interceptors) callbacks
-  // into the embedding application can occour, and the embedding application
-  // could have the assumption that its own native context is the current
-  // context and not some internal debugger context.
-  SaveContext save(isolate);
-  if (isolate->debug()->in_debug_scope()) {
-    isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
-  }
-
-  // Check if the name is trivially convertible to an index and get the element
-  // if so.
-  uint32_t index;
-  if (name->AsArrayIndex(&index)) {
-    Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
-    Handle<Object> element_or_char;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, element_or_char,
-        Runtime::GetElementOrCharAt(isolate, obj, index));
-    details->set(0, *element_or_char);
-    details->set(
-        1, PropertyDetails(NONE, NORMAL, Representation::None()).AsSmi());
-    return *isolate->factory()->NewJSArrayWithElements(details);
-  }
-
-  LookupIterator it(obj, name, LookupIterator::HIDDEN);
-  bool has_caught = false;
-  Handle<Object> value = DebugGetProperty(&it, &has_caught);
-  if (!it.IsFound()) return isolate->heap()->undefined_value();
-
-  Handle<Object> maybe_pair;
-  if (it.state() == LookupIterator::ACCESSOR) {
-    maybe_pair = it.GetAccessors();
-  }
-
-  // If the callback object is a fixed array then it contains JavaScript
-  // getter and/or setter.
-  bool has_js_accessors = !maybe_pair.is_null() && maybe_pair->IsAccessorPair();
-  Handle<FixedArray> details =
-      isolate->factory()->NewFixedArray(has_js_accessors ? 6 : 3);
-  details->set(0, *value);
-  // TODO(verwaest): Get rid of this random way of handling interceptors.
-  PropertyDetails d = it.state() == LookupIterator::INTERCEPTOR
-                          ? PropertyDetails(NONE, NORMAL, 0)
-                          : it.property_details();
-  details->set(1, d.AsSmi());
-  details->set(
-      2, isolate->heap()->ToBoolean(it.state() == LookupIterator::INTERCEPTOR));
-  if (has_js_accessors) {
-    AccessorPair* accessors = AccessorPair::cast(*maybe_pair);
-    details->set(3, isolate->heap()->ToBoolean(has_caught));
-    details->set(4, accessors->GetComponent(ACCESSOR_GETTER));
-    details->set(5, accessors->GetComponent(ACCESSOR_SETTER));
-  }
-
-  return *isolate->factory()->NewJSArrayWithElements(details);
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-
-  LookupIterator it(obj, name);
-  return *DebugGetProperty(&it);
-}
-
-
-// Return the property type calculated from the property details.
-// args[0]: smi with property details.
-RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
-  return Smi::FromInt(static_cast<int>(details.type()));
-}
-
-
-// Return the property attribute calculated from the property details.
-// args[0]: smi with property details.
-RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
-  return Smi::FromInt(static_cast<int>(details.attributes()));
-}
-
-
-// Return the property insertion index calculated from the property details.
-// args[0]: smi with property details.
-RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
-  // TODO(verwaest): Depends on the type of details.
-  return Smi::FromInt(details.dictionary_index());
-}
-
-
-// Return property value from named interceptor.
-// args[0]: object
-// args[1]: property name
-RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  RUNTIME_ASSERT(obj->HasNamedInterceptor());
-  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, JSObject::GetProperty(obj, name));
-  return *result;
-}
-
-
-// Return element value from indexed interceptor.
-// args[0]: object
-// args[1]: index
-RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  RUNTIME_ASSERT(obj->HasIndexedInterceptor());
-  CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, JSObject::GetElementWithInterceptor(obj, obj, index));
-  return *result;
-}
-
-
-static bool CheckExecutionState(Isolate* isolate, int break_id) {
-  return !isolate->debug()->debug_context().is_null() &&
-         isolate->debug()->break_id() != 0 &&
-         isolate->debug()->break_id() == break_id;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-  return isolate->heap()->true_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetFrameCount) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-  // Count all frames which are relevant to debugging stack trace.
-  int n = 0;
-  StackFrame::Id id = isolate->debug()->break_frame_id();
-  if (id == StackFrame::NO_ID) {
-    // If there is no JavaScript stack frame count is 0.
-    return Smi::FromInt(0);
-  }
-
-  for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
-    List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
-    it.frame()->Summarize(&frames);
-    for (int i = frames.length() - 1; i >= 0; i--) {
-      // Omit functions from native scripts.
-      if (!frames[i].function()->IsFromNativeScript()) n++;
-    }
-  }
-  return Smi::FromInt(n);
-}
-
-
-class FrameInspector {
- public:
-  FrameInspector(JavaScriptFrame* frame,
-                 int inlined_jsframe_index,
-                 Isolate* isolate)
-      : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
-    // Calculate the deoptimized frame.
-    if (frame->is_optimized()) {
-      deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
-          frame, inlined_jsframe_index, isolate);
-    }
-    has_adapted_arguments_ = frame_->has_adapted_arguments();
-    is_bottommost_ = inlined_jsframe_index == 0;
-    is_optimized_ = frame_->is_optimized();
-  }
-
-  ~FrameInspector() {
-    // Get rid of the calculated deoptimized frame if any.
-    if (deoptimized_frame_ != NULL) {
-      Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
-                                                  isolate_);
-    }
-  }
-
-  int GetParametersCount() {
-    return is_optimized_
-        ? deoptimized_frame_->parameters_count()
-        : frame_->ComputeParametersCount();
-  }
-  int expression_count() { return deoptimized_frame_->expression_count(); }
-  Object* GetFunction() {
-    return is_optimized_
-        ? deoptimized_frame_->GetFunction()
-        : frame_->function();
-  }
-  Object* GetParameter(int index) {
-    return is_optimized_
-        ? deoptimized_frame_->GetParameter(index)
-        : frame_->GetParameter(index);
-  }
-  Object* GetExpression(int index) {
-    return is_optimized_
-        ? deoptimized_frame_->GetExpression(index)
-        : frame_->GetExpression(index);
-  }
-  int GetSourcePosition() {
-    return is_optimized_
-        ? deoptimized_frame_->GetSourcePosition()
-        : frame_->LookupCode()->SourcePosition(frame_->pc());
-  }
-  bool IsConstructor() {
-    return is_optimized_ && !is_bottommost_
-        ? deoptimized_frame_->HasConstructStub()
-        : frame_->IsConstructor();
-  }
-  Object* GetContext() {
-    return is_optimized_ ? deoptimized_frame_->GetContext() : frame_->context();
-  }
-
-  // To inspect all the provided arguments the frame might need to be
-  // replaced with the arguments frame.
-  void SetArgumentsFrame(JavaScriptFrame* frame) {
-    DCHECK(has_adapted_arguments_);
-    frame_ = frame;
-    is_optimized_ = frame_->is_optimized();
-    DCHECK(!is_optimized_);
-  }
-
- private:
-  JavaScriptFrame* frame_;
-  DeoptimizedFrameInfo* deoptimized_frame_;
-  Isolate* isolate_;
-  bool is_optimized_;
-  bool is_bottommost_;
-  bool has_adapted_arguments_;
-
-  DISALLOW_COPY_AND_ASSIGN(FrameInspector);
-};
-
-
-static const int kFrameDetailsFrameIdIndex = 0;
-static const int kFrameDetailsReceiverIndex = 1;
-static const int kFrameDetailsFunctionIndex = 2;
-static const int kFrameDetailsArgumentCountIndex = 3;
-static const int kFrameDetailsLocalCountIndex = 4;
-static const int kFrameDetailsSourcePositionIndex = 5;
-static const int kFrameDetailsConstructCallIndex = 6;
-static const int kFrameDetailsAtReturnIndex = 7;
-static const int kFrameDetailsFlagsIndex = 8;
-static const int kFrameDetailsFirstDynamicIndex = 9;
-
-
-static SaveContext* FindSavedContextForFrame(Isolate* isolate,
-                                             JavaScriptFrame* frame) {
-  SaveContext* save = isolate->save_context();
-  while (save != NULL && !save->IsBelowFrame(frame)) {
-    save = save->prev();
-  }
-  DCHECK(save != NULL);
-  return save;
-}
-
-
-// Advances the iterator to the frame that matches the index and returns the
-// inlined frame index, or -1 if not found.  Skips native JS functions.
-static int FindIndexedNonNativeFrame(JavaScriptFrameIterator* it, int index) {
-  int count = -1;
-  for (; !it->done(); it->Advance()) {
-    List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
-    it->frame()->Summarize(&frames);
-    for (int i = frames.length() - 1; i >= 0; i--) {
-      // Omit functions from native scripts.
-      if (frames[i].function()->IsFromNativeScript()) continue;
-      if (++count == index) return i;
-    }
-  }
-  return -1;
-}
-
-
-// Return an array with frame details
-// args[0]: number: break id
-// args[1]: number: frame index
-//
-// The array returned contains the following information:
-// 0: Frame id
-// 1: Receiver
-// 2: Function
-// 3: Argument count
-// 4: Local count
-// 5: Source position
-// 6: Constructor call
-// 7: Is at return
-// 8: Flags
-// Arguments name, value
-// Locals name, value
-// Return value if any
-RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
-  Heap* heap = isolate->heap();
-
-  // Find the relevant frame with the requested index.
-  StackFrame::Id id = isolate->debug()->break_frame_id();
-  if (id == StackFrame::NO_ID) {
-    // If there are no JavaScript stack frames return undefined.
-    return heap->undefined_value();
-  }
-
-  JavaScriptFrameIterator it(isolate, id);
-  // Inlined frame index in optimized frame, starting from outer function.
-  int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index);
-  if (inlined_jsframe_index == -1) return heap->undefined_value();
-
-  FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
-  bool is_optimized = it.frame()->is_optimized();
-
-  // Traverse the saved contexts chain to find the active context for the
-  // selected frame.
-  SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
-
-  // Get the frame id.
-  Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
-
-  // Find source position in unoptimized code.
-  int position = frame_inspector.GetSourcePosition();
-
-  // Check for constructor frame.
-  bool constructor = frame_inspector.IsConstructor();
-
-  // Get scope info and read from it for local variable information.
-  Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
-  Handle<SharedFunctionInfo> shared(function->shared());
-  Handle<ScopeInfo> scope_info(shared->scope_info());
-  DCHECK(*scope_info != ScopeInfo::Empty(isolate));
-
-  // Get the locals names and values into a temporary array.
-  int local_count = scope_info->LocalCount();
-  for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
-    // Hide compiler-introduced temporary variables, whether on the stack or on
-    // the context.
-    if (scope_info->LocalIsSynthetic(slot))
-      local_count--;
-  }
-
-  Handle<FixedArray> locals =
-      isolate->factory()->NewFixedArray(local_count * 2);
-
-  // Fill in the values of the locals.
-  int local = 0;
-  int i = 0;
-  for (; i < scope_info->StackLocalCount(); ++i) {
-    // Use the value from the stack.
-    if (scope_info->LocalIsSynthetic(i))
-      continue;
-    locals->set(local * 2, scope_info->LocalName(i));
-    locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
-    local++;
-  }
-  if (local < local_count) {
-    // Get the context containing declarations.
-    Handle<Context> context(
-        Context::cast(frame_inspector.GetContext())->declaration_context());
-    for (; i < scope_info->LocalCount(); ++i) {
-      if (scope_info->LocalIsSynthetic(i))
-        continue;
-      Handle<String> name(scope_info->LocalName(i));
-      VariableMode mode;
-      InitializationFlag init_flag;
-      MaybeAssignedFlag maybe_assigned_flag;
-      locals->set(local * 2, *name);
-      int context_slot_index = ScopeInfo::ContextSlotIndex(
-          scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
-      Object* value = context->get(context_slot_index);
-      locals->set(local * 2 + 1, value);
-      local++;
-    }
-  }
-
-  // Check whether this frame is positioned at return. If not top
-  // frame or if the frame is optimized it cannot be at a return.
-  bool at_return = false;
-  if (!is_optimized && index == 0) {
-    at_return = isolate->debug()->IsBreakAtReturn(it.frame());
-  }
-
-  // If positioned just before return find the value to be returned and add it
-  // to the frame information.
-  Handle<Object> return_value = isolate->factory()->undefined_value();
-  if (at_return) {
-    StackFrameIterator it2(isolate);
-    Address internal_frame_sp = NULL;
-    while (!it2.done()) {
-      if (it2.frame()->is_internal()) {
-        internal_frame_sp = it2.frame()->sp();
-      } else {
-        if (it2.frame()->is_java_script()) {
-          if (it2.frame()->id() == it.frame()->id()) {
-            // The internal frame just before the JavaScript frame contains the
-            // value to return on top. A debug break at return will create an
-            // internal frame to store the return value (eax/rax/r0) before
-            // entering the debug break exit frame.
-            if (internal_frame_sp != NULL) {
-              return_value =
-                  Handle<Object>(Memory::Object_at(internal_frame_sp),
-                                 isolate);
-              break;
-            }
-          }
-        }
-
-        // Indicate that the previous frame was not an internal frame.
-        internal_frame_sp = NULL;
-      }
-      it2.Advance();
-    }
-  }
-
-  // Now advance to the arguments adapter frame (if any). It contains all
-  // the provided parameters whereas the function frame always have the number
-  // of arguments matching the functions parameters. The rest of the
-  // information (except for what is collected above) is the same.
-  if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
-    it.AdvanceToArgumentsFrame();
-    frame_inspector.SetArgumentsFrame(it.frame());
-  }
-
-  // Find the number of arguments to fill. At least fill the number of
-  // parameters for the function and fill more if more parameters are provided.
-  int argument_count = scope_info->ParameterCount();
-  if (argument_count < frame_inspector.GetParametersCount()) {
-    argument_count = frame_inspector.GetParametersCount();
-  }
-
-  // Calculate the size of the result.
-  int details_size = kFrameDetailsFirstDynamicIndex +
-                     2 * (argument_count + local_count) +
-                     (at_return ? 1 : 0);
-  Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
-
-  // Add the frame id.
-  details->set(kFrameDetailsFrameIdIndex, *frame_id);
-
-  // Add the function (same as in function frame).
-  details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
-
-  // Add the arguments count.
-  details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
-
-  // Add the locals count
-  details->set(kFrameDetailsLocalCountIndex,
-               Smi::FromInt(local_count));
-
-  // Add the source position.
-  if (position != RelocInfo::kNoPosition) {
-    details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
-  } else {
-    details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
-  }
-
-  // Add the constructor information.
-  details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
-
-  // Add the at return information.
-  details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
-
-  // Add flags to indicate information on whether this frame is
-  //   bit 0: invoked in the debugger context.
-  //   bit 1: optimized frame.
-  //   bit 2: inlined in optimized frame
-  int flags = 0;
-  if (*save->context() == *isolate->debug()->debug_context()) {
-    flags |= 1 << 0;
-  }
-  if (is_optimized) {
-    flags |= 1 << 1;
-    flags |= inlined_jsframe_index << 2;
-  }
-  details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
-
-  // Fill the dynamic part.
-  int details_index = kFrameDetailsFirstDynamicIndex;
-
-  // Add arguments name and value.
-  for (int i = 0; i < argument_count; i++) {
-    // Name of the argument.
-    if (i < scope_info->ParameterCount()) {
-      details->set(details_index++, scope_info->ParameterName(i));
-    } else {
-      details->set(details_index++, heap->undefined_value());
-    }
-
-    // Parameter value.
-    if (i < frame_inspector.GetParametersCount()) {
-      // Get the value from the stack.
-      details->set(details_index++, frame_inspector.GetParameter(i));
-    } else {
-      details->set(details_index++, heap->undefined_value());
-    }
-  }
-
-  // Add locals name and value from the temporary copy from the function frame.
-  for (int i = 0; i < local_count * 2; i++) {
-    details->set(details_index++, locals->get(i));
-  }
-
-  // Add the value being returned.
-  if (at_return) {
-    details->set(details_index++, *return_value);
-  }
-
-  // Add the receiver (same as in function frame).
-  // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
-  // THE FRAME ITERATOR TO WRAP THE RECEIVER.
-  Handle<Object> receiver(it.frame()->receiver(), isolate);
-  if (!receiver->IsJSObject() &&
-      shared->strict_mode() == SLOPPY &&
-      !function->IsBuiltin()) {
-    // If the receiver is not a JSObject and the function is not a
-    // builtin or strict-mode we have hit an optimization where a
-    // value object is not converted into a wrapped JS objects. To
-    // hide this optimization from the debugger, we wrap the receiver
-    // by creating correct wrapper object based on the calling frame's
-    // native context.
-    it.Advance();
-    if (receiver->IsUndefined()) {
-      receiver = handle(function->global_proxy());
-    } else {
-      Context* context = Context::cast(it.frame()->context());
-      Handle<Context> native_context(Context::cast(context->native_context()));
-      if (!Object::ToObject(isolate, receiver, native_context)
-               .ToHandle(&receiver)) {
-        // This only happens if the receiver is forcibly set in %_CallFunction.
-        return heap->undefined_value();
-      }
-    }
-  }
-  details->set(kFrameDetailsReceiverIndex, *receiver);
-
-  DCHECK_EQ(details_size, details_index);
-  return *isolate->factory()->NewJSArrayWithElements(details);
-}
-
-
-static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
-                                              Handle<String> parameter_name) {
-  VariableMode mode;
-  InitializationFlag init_flag;
-  MaybeAssignedFlag maybe_assigned_flag;
-  return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag,
-                                     &maybe_assigned_flag) != -1;
-}
-
-
-// Create a plain JSObject which materializes the local scope for the specified
-// frame.
-MUST_USE_RESULT
-static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
-    Isolate* isolate,
-    Handle<JSObject> target,
-    Handle<JSFunction> function,
-    FrameInspector* frame_inspector) {
-  Handle<SharedFunctionInfo> shared(function->shared());
-  Handle<ScopeInfo> scope_info(shared->scope_info());
-
-  // First fill all parameters.
-  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
-    // Do not materialize the parameter if it is shadowed by a context local.
-    Handle<String> name(scope_info->ParameterName(i));
-    if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
-
-    HandleScope scope(isolate);
-    Handle<Object> value(i < frame_inspector->GetParametersCount()
-                             ? frame_inspector->GetParameter(i)
-                             : isolate->heap()->undefined_value(),
-                         isolate);
-    DCHECK(!value->IsTheHole());
-
-    RETURN_ON_EXCEPTION(
-        isolate,
-        Runtime::SetObjectProperty(isolate, target, name, value, SLOPPY),
-        JSObject);
-  }
-
-  // Second fill all stack locals.
-  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
-    if (scope_info->LocalIsSynthetic(i)) continue;
-    Handle<String> name(scope_info->StackLocalName(i));
-    Handle<Object> value(frame_inspector->GetExpression(i), isolate);
-    if (value->IsTheHole()) continue;
-
-    RETURN_ON_EXCEPTION(
-        isolate,
-        Runtime::SetObjectProperty(isolate, target, name, value, SLOPPY),
-        JSObject);
-  }
-
-  return target;
-}
-
-
-static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
-                                                    Handle<JSObject> target,
-                                                    Handle<JSFunction> function,
-                                                    JavaScriptFrame* frame,
-                                                    int inlined_jsframe_index) {
-  if (inlined_jsframe_index != 0 || frame->is_optimized()) {
-    // Optimized frames are not supported.
-    // TODO(yangguo): make sure all code deoptimized when debugger is active
-    //                and assert that this cannot happen.
-    return;
-  }
-
-  Handle<SharedFunctionInfo> shared(function->shared());
-  Handle<ScopeInfo> scope_info(shared->scope_info());
-
-  // Parameters.
-  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
-    // Shadowed parameters were not materialized.
-    Handle<String> name(scope_info->ParameterName(i));
-    if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
-
-    DCHECK(!frame->GetParameter(i)->IsTheHole());
-    HandleScope scope(isolate);
-    Handle<Object> value =
-        Object::GetPropertyOrElement(target, name).ToHandleChecked();
-    frame->SetParameterValue(i, *value);
-  }
-
-  // Stack locals.
-  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
-    if (scope_info->LocalIsSynthetic(i)) continue;
-    if (frame->GetExpression(i)->IsTheHole()) continue;
-    HandleScope scope(isolate);
-    Handle<Object> value = Object::GetPropertyOrElement(
-        target,
-        handle(scope_info->StackLocalName(i), isolate)).ToHandleChecked();
-    frame->SetExpression(i, *value);
-  }
-}
-
-
-MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
-    Isolate* isolate,
-    Handle<JSObject> target,
-    Handle<JSFunction> function,
-    JavaScriptFrame* frame) {
-  HandleScope scope(isolate);
-  Handle<SharedFunctionInfo> shared(function->shared());
-  Handle<ScopeInfo> scope_info(shared->scope_info());
-
-  if (!scope_info->HasContext()) return target;
-
-  // Third fill all context locals.
-  Handle<Context> frame_context(Context::cast(frame->context()));
-  Handle<Context> function_context(frame_context->declaration_context());
-  if (!ScopeInfo::CopyContextLocalsToScopeObject(
-          scope_info, function_context, target)) {
-    return MaybeHandle<JSObject>();
-  }
-
-  // Finally copy any properties from the function context extension.
-  // These will be variables introduced by eval.
-  if (function_context->closure() == *function) {
-    if (function_context->has_extension() &&
-        !function_context->IsNativeContext()) {
-      Handle<JSObject> ext(JSObject::cast(function_context->extension()));
-      Handle<FixedArray> keys;
-      ASSIGN_RETURN_ON_EXCEPTION(
-          isolate, keys,
-          JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
-          JSObject);
-
-      for (int i = 0; i < keys->length(); i++) {
-        // Names of variables introduced by eval are strings.
-        DCHECK(keys->get(i)->IsString());
-        Handle<String> key(String::cast(keys->get(i)));
-        Handle<Object> value;
-        ASSIGN_RETURN_ON_EXCEPTION(
-            isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
-        RETURN_ON_EXCEPTION(
-            isolate,
-            Runtime::SetObjectProperty(isolate, target, key, value, SLOPPY),
-            JSObject);
-      }
-    }
-  }
-
-  return target;
-}
-
-
-MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
-    Isolate* isolate,
-    JavaScriptFrame* frame,
-    int inlined_jsframe_index) {
-  FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
-  Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
-
-  Handle<JSObject> local_scope =
-      isolate->factory()->NewJSObject(isolate->object_function());
-  ASSIGN_RETURN_ON_EXCEPTION(
-      isolate, local_scope,
-      MaterializeStackLocalsWithFrameInspector(
-          isolate, local_scope, function, &frame_inspector),
-      JSObject);
-
-  return MaterializeLocalContext(isolate, local_scope, function, frame);
-}
-
-
-// Set the context local variable value.
-static bool SetContextLocalValue(Isolate* isolate,
-                                 Handle<ScopeInfo> scope_info,
-                                 Handle<Context> context,
-                                 Handle<String> variable_name,
-                                 Handle<Object> new_value) {
-  for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
-    Handle<String> next_name(scope_info->ContextLocalName(i));
-    if (String::Equals(variable_name, next_name)) {
-      VariableMode mode;
-      InitializationFlag init_flag;
-      MaybeAssignedFlag maybe_assigned_flag;
-      int context_index = ScopeInfo::ContextSlotIndex(
-          scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag);
-      context->set(context_index, *new_value);
-      return true;
-    }
-  }
-
-  return false;
-}
-
-
-static bool SetLocalVariableValue(Isolate* isolate,
-                                  JavaScriptFrame* frame,
-                                  int inlined_jsframe_index,
-                                  Handle<String> variable_name,
-                                  Handle<Object> new_value) {
-  if (inlined_jsframe_index != 0 || frame->is_optimized()) {
-    // Optimized frames are not supported.
-    return false;
-  }
-
-  Handle<JSFunction> function(frame->function());
-  Handle<SharedFunctionInfo> shared(function->shared());
-  Handle<ScopeInfo> scope_info(shared->scope_info());
-
-  bool default_result = false;
-
-  // Parameters.
-  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
-    HandleScope scope(isolate);
-    if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
-      frame->SetParameterValue(i, *new_value);
-      // Argument might be shadowed in heap context, don't stop here.
-      default_result = true;
-    }
-  }
-
-  // Stack locals.
-  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
-    HandleScope scope(isolate);
-    if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
-      frame->SetExpression(i, *new_value);
-      return true;
-    }
-  }
-
-  if (scope_info->HasContext()) {
-    // Context locals.
-    Handle<Context> frame_context(Context::cast(frame->context()));
-    Handle<Context> function_context(frame_context->declaration_context());
-    if (SetContextLocalValue(
-        isolate, scope_info, function_context, variable_name, new_value)) {
-      return true;
-    }
-
-    // Function context extension. These are variables introduced by eval.
-    if (function_context->closure() == *function) {
-      if (function_context->has_extension() &&
-          !function_context->IsNativeContext()) {
-        Handle<JSObject> ext(JSObject::cast(function_context->extension()));
-
-        Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
-        DCHECK(maybe.has_value);
-        if (maybe.value) {
-          // We don't expect this to do anything except replacing
-          // property value.
-          Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
-                                     SLOPPY).Assert();
-          return true;
-        }
-      }
-    }
-  }
-
-  return default_result;
-}
-
-
-// Create a plain JSObject which materializes the closure content for the
-// context.
-MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
-    Isolate* isolate,
-    Handle<Context> context) {
-  DCHECK(context->IsFunctionContext());
-
-  Handle<SharedFunctionInfo> shared(context->closure()->shared());
-  Handle<ScopeInfo> scope_info(shared->scope_info());
-
-  // Allocate and initialize a JSObject with all the content of this function
-  // closure.
-  Handle<JSObject> closure_scope =
-      isolate->factory()->NewJSObject(isolate->object_function());
-
-  // Fill all context locals to the context extension.
-  if (!ScopeInfo::CopyContextLocalsToScopeObject(
-          scope_info, context, closure_scope)) {
-    return MaybeHandle<JSObject>();
-  }
-
-  // Finally copy any properties from the function context extension. This will
-  // be variables introduced by eval.
-  if (context->has_extension()) {
-    Handle<JSObject> ext(JSObject::cast(context->extension()));
-    Handle<FixedArray> keys;
-    ASSIGN_RETURN_ON_EXCEPTION(
-        isolate, keys,
-        JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS), JSObject);
-
-    for (int i = 0; i < keys->length(); i++) {
-      HandleScope scope(isolate);
-      // Names of variables introduced by eval are strings.
-      DCHECK(keys->get(i)->IsString());
-      Handle<String> key(String::cast(keys->get(i)));
-      Handle<Object> value;
-      ASSIGN_RETURN_ON_EXCEPTION(
-          isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
-      RETURN_ON_EXCEPTION(
-          isolate,
-          Runtime::DefineObjectProperty(closure_scope, key, value, NONE),
-          JSObject);
-    }
-  }
-
-  return closure_scope;
-}
-
-
-// This method copies structure of MaterializeClosure method above.
-static bool SetClosureVariableValue(Isolate* isolate,
-                                    Handle<Context> context,
-                                    Handle<String> variable_name,
-                                    Handle<Object> new_value) {
-  DCHECK(context->IsFunctionContext());
-
-  Handle<SharedFunctionInfo> shared(context->closure()->shared());
-  Handle<ScopeInfo> scope_info(shared->scope_info());
-
-  // Context locals to the context extension.
-  if (SetContextLocalValue(
-          isolate, scope_info, context, variable_name, new_value)) {
-    return true;
-  }
-
-  // Properties from the function context extension. This will
-  // be variables introduced by eval.
-  if (context->has_extension()) {
-    Handle<JSObject> ext(JSObject::cast(context->extension()));
-    Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
-    DCHECK(maybe.has_value);
-    if (maybe.value) {
-      // We don't expect this to do anything except replacing property value.
-      Runtime::DefineObjectProperty(
-          ext, variable_name, new_value, NONE).Assert();
-      return true;
-    }
-  }
-
-  return false;
-}
-
-
-// Create a plain JSObject which materializes the scope for the specified
-// catch context.
-MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
-    Isolate* isolate,
-    Handle<Context> context) {
-  DCHECK(context->IsCatchContext());
-  Handle<String> name(String::cast(context->extension()));
-  Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
-                               isolate);
-  Handle<JSObject> catch_scope =
-      isolate->factory()->NewJSObject(isolate->object_function());
-  RETURN_ON_EXCEPTION(
-      isolate,
-      Runtime::DefineObjectProperty(catch_scope, name, thrown_object, NONE),
-      JSObject);
-  return catch_scope;
-}
-
-
-static bool SetCatchVariableValue(Isolate* isolate,
-                                  Handle<Context> context,
-                                  Handle<String> variable_name,
-                                  Handle<Object> new_value) {
-  DCHECK(context->IsCatchContext());
-  Handle<String> name(String::cast(context->extension()));
-  if (!String::Equals(name, variable_name)) {
-    return false;
-  }
-  context->set(Context::THROWN_OBJECT_INDEX, *new_value);
-  return true;
-}
-
-
-// Create a plain JSObject which materializes the block scope for the specified
-// block context.
-MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
-    Isolate* isolate,
-    Handle<Context> context) {
-  DCHECK(context->IsBlockContext());
-  Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
-
-  // Allocate and initialize a JSObject with all the arguments, stack locals
-  // heap locals and extension properties of the debugged function.
-  Handle<JSObject> block_scope =
-      isolate->factory()->NewJSObject(isolate->object_function());
-
-  // Fill all context locals.
-  if (!ScopeInfo::CopyContextLocalsToScopeObject(
-          scope_info, context, block_scope)) {
-    return MaybeHandle<JSObject>();
-  }
-
-  return block_scope;
-}
-
-
-// Create a plain JSObject which materializes the module scope for the specified
-// module context.
-MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
-    Isolate* isolate,
-    Handle<Context> context) {
-  DCHECK(context->IsModuleContext());
-  Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
-
-  // Allocate and initialize a JSObject with all the members of the debugged
-  // module.
-  Handle<JSObject> module_scope =
-      isolate->factory()->NewJSObject(isolate->object_function());
-
-  // Fill all context locals.
-  if (!ScopeInfo::CopyContextLocalsToScopeObject(
-          scope_info, context, module_scope)) {
-    return MaybeHandle<JSObject>();
-  }
-
-  return module_scope;
-}
-
-
-// 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 {
-    ScopeTypeGlobal = 0,
-    ScopeTypeLocal,
-    ScopeTypeWith,
-    ScopeTypeClosure,
-    ScopeTypeCatch,
-    ScopeTypeBlock,
-    ScopeTypeModule
-  };
-
-  ScopeIterator(Isolate* isolate,
-                JavaScriptFrame* frame,
-                int inlined_jsframe_index,
-                bool ignore_nested_scopes = false)
-    : isolate_(isolate),
-      frame_(frame),
-      inlined_jsframe_index_(inlined_jsframe_index),
-      function_(frame->function()),
-      context_(Context::cast(frame->context())),
-      nested_scope_chain_(4),
-      failed_(false) {
-
-    // Catch the case when the debugger stops in an internal function.
-    Handle<SharedFunctionInfo> shared_info(function_->shared());
-    Handle<ScopeInfo> scope_info(shared_info->scope_info());
-    if (shared_info->script() == isolate->heap()->undefined_value()) {
-      while (context_->closure() == *function_) {
-        context_ = Handle<Context>(context_->previous(), isolate_);
-      }
-      return;
-    }
-
-    // Get the debug info (create it if it does not exist).
-    if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
-      // Return if ensuring debug info failed.
-      return;
-    }
-
-    // Currently it takes too much time to find nested scopes due to script
-    // parsing. Sometimes we want to run the ScopeIterator as fast as possible
-    // (for example, while collecting async call stacks on every
-    // addEventListener call), even if we drop some nested scopes.
-    // Later we may optimize getting the nested scopes (cache the result?)
-    // and include nested scopes into the "fast" iteration case as well.
-    if (!ignore_nested_scopes) {
-      Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
-
-      // Find the break point where execution has stopped.
-      BreakLocationIterator break_location_iterator(debug_info,
-                                                    ALL_BREAK_LOCATIONS);
-      // pc points to the instruction after the current one, possibly a break
-      // location as well. So the "- 1" to exclude it from the search.
-      break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
-
-      // Within the return sequence at the moment it is not possible to
-      // get a source position which is consistent with the current scope chain.
-      // Thus all nested with, catch and block contexts are skipped and we only
-      // provide the function scope.
-      ignore_nested_scopes = break_location_iterator.IsExit();
-    }
-
-    if (ignore_nested_scopes) {
-      if (scope_info->HasContext()) {
-        context_ = Handle<Context>(context_->declaration_context(), isolate_);
-      } else {
-        while (context_->closure() == *function_) {
-          context_ = Handle<Context>(context_->previous(), isolate_);
-        }
-      }
-      if (scope_info->scope_type() == FUNCTION_SCOPE) {
-        nested_scope_chain_.Add(scope_info);
-      }
-    } else {
-      // Reparse the code and analyze the scopes.
-      Handle<Script> script(Script::cast(shared_info->script()));
-      Scope* scope = NULL;
-
-      // Check whether we are in global, eval or function code.
-      Handle<ScopeInfo> scope_info(shared_info->scope_info());
-      if (scope_info->scope_type() != FUNCTION_SCOPE) {
-        // Global or eval code.
-        CompilationInfoWithZone info(script);
-        if (scope_info->scope_type() == GLOBAL_SCOPE) {
-          info.MarkAsGlobal();
-        } else {
-          DCHECK(scope_info->scope_type() == EVAL_SCOPE);
-          info.MarkAsEval();
-          info.SetContext(Handle<Context>(function_->context()));
-        }
-        if (Parser::Parse(&info) && Scope::Analyze(&info)) {
-          scope = info.function()->scope();
-        }
-        RetrieveScopeChain(scope, shared_info);
-      } else {
-        // Function code
-        CompilationInfoWithZone info(shared_info);
-        if (Parser::Parse(&info) && Scope::Analyze(&info)) {
-          scope = info.function()->scope();
-        }
-        RetrieveScopeChain(scope, shared_info);
-      }
-    }
-  }
-
-  ScopeIterator(Isolate* isolate,
-                Handle<JSFunction> function)
-    : isolate_(isolate),
-      frame_(NULL),
-      inlined_jsframe_index_(0),
-      function_(function),
-      context_(function->context()),
-      failed_(false) {
-    if (function->IsBuiltin()) {
-      context_ = Handle<Context>();
-    }
-  }
-
-  // More scopes?
-  bool Done() {
-    DCHECK(!failed_);
-    return context_.is_null();
-  }
-
-  bool Failed() { return failed_; }
-
-  // Move to the next scope.
-  void Next() {
-    DCHECK(!failed_);
-    ScopeType scope_type = Type();
-    if (scope_type == ScopeTypeGlobal) {
-      // The global scope is always the last in the chain.
-      DCHECK(context_->IsNativeContext());
-      context_ = Handle<Context>();
-      return;
-    }
-    if (nested_scope_chain_.is_empty()) {
-      context_ = Handle<Context>(context_->previous(), isolate_);
-    } else {
-      if (nested_scope_chain_.last()->HasContext()) {
-        DCHECK(context_->previous() != NULL);
-        context_ = Handle<Context>(context_->previous(), isolate_);
-      }
-      nested_scope_chain_.RemoveLast();
-    }
-  }
-
-  // Return the type of the current scope.
-  ScopeType Type() {
-    DCHECK(!failed_);
-    if (!nested_scope_chain_.is_empty()) {
-      Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
-      switch (scope_info->scope_type()) {
-        case FUNCTION_SCOPE:
-          DCHECK(context_->IsFunctionContext() ||
-                 !scope_info->HasContext());
-          return ScopeTypeLocal;
-        case MODULE_SCOPE:
-          DCHECK(context_->IsModuleContext());
-          return ScopeTypeModule;
-        case GLOBAL_SCOPE:
-          DCHECK(context_->IsNativeContext());
-          return ScopeTypeGlobal;
-        case WITH_SCOPE:
-          DCHECK(context_->IsWithContext());
-          return ScopeTypeWith;
-        case CATCH_SCOPE:
-          DCHECK(context_->IsCatchContext());
-          return ScopeTypeCatch;
-        case BLOCK_SCOPE:
-          DCHECK(!scope_info->HasContext() ||
-                 context_->IsBlockContext());
-          return ScopeTypeBlock;
-        case EVAL_SCOPE:
-          UNREACHABLE();
-      }
-    }
-    if (context_->IsNativeContext()) {
-      DCHECK(context_->global_object()->IsGlobalObject());
-      return ScopeTypeGlobal;
-    }
-    if (context_->IsFunctionContext()) {
-      return ScopeTypeClosure;
-    }
-    if (context_->IsCatchContext()) {
-      return ScopeTypeCatch;
-    }
-    if (context_->IsBlockContext()) {
-      return ScopeTypeBlock;
-    }
-    if (context_->IsModuleContext()) {
-      return ScopeTypeModule;
-    }
-    DCHECK(context_->IsWithContext());
-    return ScopeTypeWith;
-  }
-
-  // Return the JavaScript object with the content of the current scope.
-  MaybeHandle<JSObject> ScopeObject() {
-    DCHECK(!failed_);
-    switch (Type()) {
-      case ScopeIterator::ScopeTypeGlobal:
-        return Handle<JSObject>(CurrentContext()->global_object());
-      case ScopeIterator::ScopeTypeLocal:
-        // Materialize the content of the local scope into a JSObject.
-        DCHECK(nested_scope_chain_.length() == 1);
-        return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
-      case ScopeIterator::ScopeTypeWith:
-        // Return the with object.
-        return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
-      case ScopeIterator::ScopeTypeCatch:
-        return MaterializeCatchScope(isolate_, CurrentContext());
-      case ScopeIterator::ScopeTypeClosure:
-        // Materialize the content of the closure scope into a JSObject.
-        return MaterializeClosure(isolate_, CurrentContext());
-      case ScopeIterator::ScopeTypeBlock:
-        return MaterializeBlockScope(isolate_, CurrentContext());
-      case ScopeIterator::ScopeTypeModule:
-        return MaterializeModuleScope(isolate_, CurrentContext());
-    }
-    UNREACHABLE();
-    return Handle<JSObject>();
-  }
-
-  bool SetVariableValue(Handle<String> variable_name,
-                        Handle<Object> new_value) {
-    DCHECK(!failed_);
-    switch (Type()) {
-      case ScopeIterator::ScopeTypeGlobal:
-        break;
-      case ScopeIterator::ScopeTypeLocal:
-        return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
-            variable_name, new_value);
-      case ScopeIterator::ScopeTypeWith:
-        break;
-      case ScopeIterator::ScopeTypeCatch:
-        return SetCatchVariableValue(isolate_, CurrentContext(),
-            variable_name, new_value);
-      case ScopeIterator::ScopeTypeClosure:
-        return SetClosureVariableValue(isolate_, CurrentContext(),
-            variable_name, new_value);
-      case ScopeIterator::ScopeTypeBlock:
-        // TODO(2399): should we implement it?
-        break;
-      case ScopeIterator::ScopeTypeModule:
-        // TODO(2399): should we implement it?
-        break;
-    }
-    return false;
-  }
-
-  Handle<ScopeInfo> CurrentScopeInfo() {
-    DCHECK(!failed_);
-    if (!nested_scope_chain_.is_empty()) {
-      return nested_scope_chain_.last();
-    } else if (context_->IsBlockContext()) {
-      return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
-    } else if (context_->IsFunctionContext()) {
-      return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
-    }
-    return Handle<ScopeInfo>::null();
-  }
-
-  // Return the context for this scope. For the local context there might not
-  // be an actual context.
-  Handle<Context> CurrentContext() {
-    DCHECK(!failed_);
-    if (Type() == ScopeTypeGlobal ||
-        nested_scope_chain_.is_empty()) {
-      return context_;
-    } else if (nested_scope_chain_.last()->HasContext()) {
-      return context_;
-    } else {
-      return Handle<Context>();
-    }
-  }
-
-#ifdef DEBUG
-  // Debug print of the content of the current scope.
-  void DebugPrint() {
-    OFStream os(stdout);
-    DCHECK(!failed_);
-    switch (Type()) {
-      case ScopeIterator::ScopeTypeGlobal:
-        os << "Global:\n";
-        CurrentContext()->Print(os);
-        break;
-
-      case ScopeIterator::ScopeTypeLocal: {
-        os << "Local:\n";
-        function_->shared()->scope_info()->Print();
-        if (!CurrentContext().is_null()) {
-          CurrentContext()->Print(os);
-          if (CurrentContext()->has_extension()) {
-            Handle<Object> extension(CurrentContext()->extension(), isolate_);
-            if (extension->IsJSContextExtensionObject()) {
-              extension->Print(os);
-            }
-          }
-        }
-        break;
-      }
-
-      case ScopeIterator::ScopeTypeWith:
-        os << "With:\n";
-        CurrentContext()->extension()->Print(os);
-        break;
-
-      case ScopeIterator::ScopeTypeCatch:
-        os << "Catch:\n";
-        CurrentContext()->extension()->Print(os);
-        CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print(os);
-        break;
-
-      case ScopeIterator::ScopeTypeClosure:
-        os << "Closure:\n";
-        CurrentContext()->Print(os);
-        if (CurrentContext()->has_extension()) {
-          Handle<Object> extension(CurrentContext()->extension(), isolate_);
-          if (extension->IsJSContextExtensionObject()) {
-            extension->Print(os);
-          }
-        }
-        break;
-
-      default:
-        UNREACHABLE();
-    }
-    PrintF("\n");
-  }
-#endif
-
- private:
-  Isolate* isolate_;
-  JavaScriptFrame* frame_;
-  int inlined_jsframe_index_;
-  Handle<JSFunction> function_;
-  Handle<Context> context_;
-  List<Handle<ScopeInfo> > nested_scope_chain_;
-  bool failed_;
-
-  void RetrieveScopeChain(Scope* scope,
-                          Handle<SharedFunctionInfo> shared_info) {
-    if (scope != NULL) {
-      int source_position = shared_info->code()->SourcePosition(frame_->pc());
-      scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
-    } else {
-      // A failed reparse indicates that the preparser has diverged from the
-      // parser or that the preparse data given to the initial parse has been
-      // faulty. We fail in debug mode but in release mode we only provide the
-      // information we get from the context chain but nothing about
-      // completely stack allocated scopes or stack allocated locals.
-      // Or it could be due to stack overflow.
-      DCHECK(isolate_->has_pending_exception());
-      failed_ = true;
-    }
-  }
-
-  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
-};
-
-
-RUNTIME_FUNCTION(Runtime_GetScopeCount) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
-
-  // Get the frame where the debugging is performed.
-  StackFrame::Id id = UnwrapFrameId(wrapped_id);
-  JavaScriptFrameIterator it(isolate, id);
-  JavaScriptFrame* frame = it.frame();
-
-  // Count the visible scopes.
-  int n = 0;
-  for (ScopeIterator it(isolate, frame, 0);
-       !it.Done();
-       it.Next()) {
-    n++;
-  }
-
-  return Smi::FromInt(n);
-}
-
-
-// Returns the list of step-in positions (text offset) in a function of the
-// stack frame in a range from the current debug break position to the end
-// of the corresponding statement.
-RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
-
-  // Get the frame where the debugging is performed.
-  StackFrame::Id id = UnwrapFrameId(wrapped_id);
-  JavaScriptFrameIterator frame_it(isolate, id);
-  RUNTIME_ASSERT(!frame_it.done());
-
-  JavaScriptFrame* frame = frame_it.frame();
-
-  Handle<JSFunction> fun =
-      Handle<JSFunction>(frame->function());
-  Handle<SharedFunctionInfo> shared =
-      Handle<SharedFunctionInfo>(fun->shared());
-
-  if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
-    return isolate->heap()->undefined_value();
-  }
-
-  Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
-
-  int len = 0;
-  Handle<JSArray> array(isolate->factory()->NewJSArray(10));
-  // Find the break point where execution has stopped.
-  BreakLocationIterator break_location_iterator(debug_info,
-                                                ALL_BREAK_LOCATIONS);
-
-  break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
-  int current_statement_pos = break_location_iterator.statement_position();
-
-  while (!break_location_iterator.Done()) {
-    bool accept;
-    if (break_location_iterator.pc() > frame->pc()) {
-      accept = true;
-    } else {
-      StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
-      // The break point is near our pc. Could be a step-in possibility,
-      // that is currently taken by active debugger call.
-      if (break_frame_id == StackFrame::NO_ID) {
-        // We are not stepping.
-        accept = false;
-      } else {
-        JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
-        // If our frame is a top frame and we are stepping, we can do step-in
-        // at this place.
-        accept = additional_frame_it.frame()->id() == id;
-      }
-    }
-    if (accept) {
-      if (break_location_iterator.IsStepInLocation(isolate)) {
-        Smi* position_value = Smi::FromInt(break_location_iterator.position());
-        RETURN_FAILURE_ON_EXCEPTION(
-            isolate,
-            JSObject::SetElement(array, len,
-                                 Handle<Object>(position_value, isolate),
-                                 NONE, SLOPPY));
-        len++;
-      }
-    }
-    // Advance iterator.
-    break_location_iterator.Next();
-    if (current_statement_pos !=
-        break_location_iterator.statement_position()) {
-      break;
-    }
-  }
-  return *array;
-}
-
-
-static const int kScopeDetailsTypeIndex = 0;
-static const int kScopeDetailsObjectIndex = 1;
-static const int kScopeDetailsSize = 2;
-
-
-MUST_USE_RESULT static MaybeHandle<JSObject> 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;
-  ASSIGN_RETURN_ON_EXCEPTION(
-      isolate, scope_object, it->ScopeObject(), JSObject);
-  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
-// args[2]: number: inlined frame index
-// args[3]: number: scope index
-//
-// The array returned contains the following information:
-// 0: Scope type
-// 1: Scope object
-RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
-  CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
-  CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
-
-  // Get the frame where the debugging is performed.
-  StackFrame::Id id = UnwrapFrameId(wrapped_id);
-  JavaScriptFrameIterator frame_it(isolate, id);
-  JavaScriptFrame* frame = frame_it.frame();
-
-  // Find the requested scope.
-  int n = 0;
-  ScopeIterator it(isolate, frame, inlined_jsframe_index);
-  for (; !it.Done() && n < index; it.Next()) {
-    n++;
-  }
-  if (it.Done()) {
-    return isolate->heap()->undefined_value();
-  }
-  Handle<JSObject> details;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, details, MaterializeScopeDetails(isolate, &it));
-  return *details;
-}
-
-
-// Return an array of scope details
-// args[0]: number: break id
-// args[1]: number: frame index
-// args[2]: number: inlined frame index
-// args[3]: boolean: ignore nested scopes
-//
-// The array returned contains arrays with the following information:
-// 0: Scope type
-// 1: Scope object
-RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3 || args.length() == 4);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
-  CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
-
-  bool ignore_nested_scopes = false;
-  if (args.length() == 4) {
-    CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
-    ignore_nested_scopes = flag;
-  }
-
-  // Get the frame where the debugging is performed.
-  StackFrame::Id id = UnwrapFrameId(wrapped_id);
-  JavaScriptFrameIterator frame_it(isolate, id);
-  JavaScriptFrame* frame = frame_it.frame();
-
-  List<Handle<JSObject> > result(4);
-  ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes);
-  for (; !it.Done(); it.Next()) {
-    Handle<JSObject> details;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, details, MaterializeScopeDetails(isolate, &it));
-    result.Add(details);
-  }
-
-  Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
-  for (int i = 0; i < result.length(); ++i) {
-    array->set(i, *result[i]);
-  }
-  return *isolate->factory()->NewJSArrayWithElements(array);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-
-  // Check arguments.
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
-
-  // Count the visible scopes.
-  int n = 0;
-  for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
-    n++;
-  }
-
-  return Smi::FromInt(n);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
-  HandleScope scope(isolate);
-  DCHECK(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();
-  }
-
-  Handle<JSObject> details;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, details, MaterializeScopeDetails(isolate, &it));
-  return *details;
-}
-
-
-static bool SetScopeVariableValue(ScopeIterator* it, int index,
-                                  Handle<String> variable_name,
-                                  Handle<Object> new_value) {
-  for (int n = 0; !it->Done() && n < index; it->Next()) {
-    n++;
-  }
-  if (it->Done()) {
-    return false;
-  }
-  return it->SetVariableValue(variable_name, new_value);
-}
-
-
-// Change variable value in closure or local scope
-// args[0]: number or JsFunction: break id or function
-// args[1]: number: frame index (when arg[0] is break id)
-// args[2]: number: inlined frame index (when arg[0] is break id)
-// args[3]: number: scope index
-// args[4]: string: variable name
-// args[5]: object: new value
-//
-// Return true if success and false otherwise
-RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 6);
-
-  // Check arguments.
-  CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
-  CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
-  CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
-
-  bool res;
-  if (args[0]->IsNumber()) {
-    CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-    RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-    CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
-    CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
-
-    // Get the frame where the debugging is performed.
-    StackFrame::Id id = UnwrapFrameId(wrapped_id);
-    JavaScriptFrameIterator frame_it(isolate, id);
-    JavaScriptFrame* frame = frame_it.frame();
-
-    ScopeIterator it(isolate, frame, inlined_jsframe_index);
-    res = SetScopeVariableValue(&it, index, variable_name, new_value);
-  } else {
-    CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
-    ScopeIterator it(isolate, fun);
-    res = SetScopeVariableValue(&it, index, variable_name, new_value);
-  }
-
-  return isolate->heap()->ToBoolean(res);
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-
-#ifdef DEBUG
-  // Print the scopes for the top frame.
-  StackFrameLocator locator(isolate);
-  JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
-  for (ScopeIterator it(isolate, frame, 0);
-       !it.Done();
-       it.Next()) {
-    it.DebugPrint();
-  }
-#endif
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetThreadCount) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-  // Count all archived V8 threads.
-  int n = 0;
-  for (ThreadState* thread =
-          isolate->thread_manager()->FirstThreadStateInUse();
-       thread != NULL;
-       thread = thread->Next()) {
-    n++;
-  }
-
-  // Total number of threads is current thread and archived threads.
-  return Smi::FromInt(n + 1);
-}
-
-
-static const int kThreadDetailsCurrentThreadIndex = 0;
-static const int kThreadDetailsThreadIdIndex = 1;
-static const int kThreadDetailsSize = 2;
-
-// Return an array with thread details
-// args[0]: number: break id
-// args[1]: number: thread index
-//
-// The array returned contains the following information:
-// 0: Is current thread?
-// 1: Thread id
-RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
-
-  // Allocate array for result.
-  Handle<FixedArray> details =
-      isolate->factory()->NewFixedArray(kThreadDetailsSize);
-
-  // Thread index 0 is current thread.
-  if (index == 0) {
-    // Fill the details.
-    details->set(kThreadDetailsCurrentThreadIndex,
-                 isolate->heap()->true_value());
-    details->set(kThreadDetailsThreadIdIndex,
-                 Smi::FromInt(ThreadId::Current().ToInteger()));
-  } else {
-    // Find the thread with the requested index.
-    int n = 1;
-    ThreadState* thread =
-        isolate->thread_manager()->FirstThreadStateInUse();
-    while (index != n && thread != NULL) {
-      thread = thread->Next();
-      n++;
-    }
-    if (thread == NULL) {
-      return isolate->heap()->undefined_value();
-    }
-
-    // Fill the details.
-    details->set(kThreadDetailsCurrentThreadIndex,
-                 isolate->heap()->false_value());
-    details->set(kThreadDetailsThreadIdIndex,
-                 Smi::FromInt(thread->id().ToInteger()));
-  }
-
-  // Convert to JS array and return.
-  return *isolate->factory()->NewJSArrayWithElements(details);
-}
-
-
-// Sets the disable break state
-// args[0]: disable break state
-RUNTIME_FUNCTION(Runtime_SetDisableBreak) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
-  isolate->debug()->set_disable_break(disable_break);
-  return  isolate->heap()->undefined_value();
-}
-
-
-static bool IsPositionAlignmentCodeCorrect(int alignment) {
-  return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
-  CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
-
-  if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
-    return isolate->ThrowIllegalOperation();
-  }
-  BreakPositionAlignment alignment =
-      static_cast<BreakPositionAlignment>(statement_aligned_code);
-
-  Handle<SharedFunctionInfo> shared(fun->shared());
-  // Find the number of break points
-  Handle<Object> break_locations =
-      Debug::GetSourceBreakLocations(shared, alignment);
-  if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
-  // Return array as JS array
-  return *isolate->factory()->NewJSArrayWithElements(
-      Handle<FixedArray>::cast(break_locations));
-}
-
-
-// Set a break point in a function.
-// args[0]: function
-// args[1]: number: break source position (within the function source)
-// args[2]: number: break point object
-RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
-  RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
-                 source_position <= function->shared()->end_position());
-  CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
-
-  // Set break point.
-  RUNTIME_ASSERT(isolate->debug()->SetBreakPoint(
-      function, break_point_object_arg, &source_position));
-
-  return Smi::FromInt(source_position);
-}
-
-
-// Changes the state of a break point in a script and returns source position
-// where break point was set. NOTE: Regarding performance see the NOTE for
-// GetScriptFromScriptData.
-// args[0]: script to set break point in
-// args[1]: number: break source position (within the script source)
-// args[2]: number, breakpoint position alignment
-// args[3]: number: break point object
-RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
-  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
-  RUNTIME_ASSERT(source_position >= 0);
-  CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
-  CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
-
-  if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
-    return isolate->ThrowIllegalOperation();
-  }
-  BreakPositionAlignment alignment =
-      static_cast<BreakPositionAlignment>(statement_aligned_code);
-
-  // Get the script from the script wrapper.
-  RUNTIME_ASSERT(wrapper->value()->IsScript());
-  Handle<Script> script(Script::cast(wrapper->value()));
-
-  // Set break point.
-  if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
-                                                &source_position,
-                                                alignment)) {
-    return isolate->heap()->undefined_value();
-  }
-
-  return Smi::FromInt(source_position);
-}
-
-
-// Clear a break point
-// args[0]: number: break point object
-RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
-
-  // Clear break point.
-  isolate->debug()->ClearBreakPoint(break_point_object_arg);
-
-  return isolate->heap()->undefined_value();
-}
-
-
-// Change the state of break on exceptions.
-// args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
-// args[1]: Boolean indicating on/off.
-RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
-  CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
-
-  // If the number doesn't match an enum value, the ChangeBreakOnException
-  // function will default to affecting caught exceptions.
-  ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
-  // Update break point state.
-  isolate->debug()->ChangeBreakOnException(type, enable);
-  return isolate->heap()->undefined_value();
-}
-
-
-// Returns the state of break on exceptions
-// args[0]: boolean indicating uncaught exceptions
-RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
-
-  ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
-  bool result = isolate->debug()->IsBreakOnException(type);
-  return Smi::FromInt(result);
-}
-
-
-// Prepare for stepping
-// args[0]: break id for checking execution state
-// args[1]: step action from the enumeration StepAction
-// args[2]: number of times to perform the step, for step out it is the number
-//          of frames to step down.
-RUNTIME_FUNCTION(Runtime_PrepareStep) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-  if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
-    return isolate->Throw(isolate->heap()->illegal_argument_string());
-  }
-
-  CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
-
-  StackFrame::Id frame_id;
-  if (wrapped_frame_id == 0) {
-    frame_id = StackFrame::NO_ID;
-  } else {
-    frame_id = UnwrapFrameId(wrapped_frame_id);
-  }
-
-  // Get the step action and check validity.
-  StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
-  if (step_action != StepIn &&
-      step_action != StepNext &&
-      step_action != StepOut &&
-      step_action != StepInMin &&
-      step_action != StepMin) {
-    return isolate->Throw(isolate->heap()->illegal_argument_string());
-  }
-
-  if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
-      step_action != StepMin && step_action != StepOut) {
-    return isolate->ThrowIllegalOperation();
-  }
-
-  // Get the number of steps.
-  int step_count = NumberToInt32(args[2]);
-  if (step_count < 1) {
-    return isolate->Throw(isolate->heap()->illegal_argument_string());
-  }
-
-  // Clear all current stepping setup.
-  isolate->debug()->ClearStepping();
-
-  // Prepare step.
-  isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
-                                step_count,
-                                frame_id);
-  return isolate->heap()->undefined_value();
-}
-
-
-// Clear all stepping set by PrepareStep.
-RUNTIME_FUNCTION(Runtime_ClearStepping) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  isolate->debug()->ClearStepping();
-  return isolate->heap()->undefined_value();
-}
-
-
-// Helper function to find or create the arguments object for
-// Runtime_DebugEvaluate.
-MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
-    Isolate* isolate,
-    Handle<JSObject> target,
-    Handle<JSFunction> function) {
-  // Do not materialize the arguments object for eval or top-level code.
-  // Skip if "arguments" is already taken.
-  if (!function->shared()->is_function()) return target;
-  Maybe<bool> maybe = JSReceiver::HasOwnProperty(
-      target, isolate->factory()->arguments_string());
-  if (!maybe.has_value) return MaybeHandle<JSObject>();
-  if (maybe.value) return target;
-
-  // FunctionGetArguments can't throw an exception.
-  Handle<JSObject> arguments = Handle<JSObject>::cast(
-      Accessors::FunctionGetArguments(function));
-  Handle<String> arguments_str = isolate->factory()->arguments_string();
-  RETURN_ON_EXCEPTION(
-      isolate,
-      Runtime::DefineObjectProperty(target, arguments_str, arguments, NONE),
-      JSObject);
-  return target;
-}
-
-
-// Compile and evaluate source for the given context.
-static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
-                                         Handle<SharedFunctionInfo> outer_info,
-                                         Handle<Context> context,
-                                         Handle<Object> context_extension,
-                                         Handle<Object> receiver,
-                                         Handle<String> source) {
-  if (context_extension->IsJSObject()) {
-    Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
-    Handle<JSFunction> closure(context->closure(), isolate);
-    context = isolate->factory()->NewWithContext(closure, context, extension);
-  }
-
-  Handle<JSFunction> eval_fun;
-  ASSIGN_RETURN_ON_EXCEPTION(
-      isolate, eval_fun,
-      Compiler::GetFunctionFromEval(source,
-                                    outer_info,
-                                    context,
-                                    SLOPPY,
-                                    NO_PARSE_RESTRICTION,
-                                    RelocInfo::kNoPosition),
-      Object);
-
-  Handle<Object> result;
-  ASSIGN_RETURN_ON_EXCEPTION(
-      isolate, result,
-      Execution::Call(isolate, eval_fun, receiver, 0, NULL),
-      Object);
-
-  // Skip the global proxy as it has no properties and always delegates to the
-  // real global object.
-  if (result->IsJSGlobalProxy()) {
-    PrototypeIterator iter(isolate, result);
-    // TODO(verwaest): This will crash when the global proxy is detached.
-    result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
-  }
-
-  // Clear the oneshot breakpoints so that the debugger does not step further.
-  isolate->debug()->ClearStepping();
-  return result;
-}
-
-
-static Handle<JSObject> NewJSObjectWithNullProto(Isolate* isolate) {
-  Handle<JSObject> result =
-      isolate->factory()->NewJSObject(isolate->object_function());
-  Handle<Map> new_map = Map::Copy(Handle<Map>(result->map()));
-  new_map->set_prototype(*isolate->factory()->null_value());
-  JSObject::MigrateToMap(result, new_map);
-  return result;
-}
-
-
-// Evaluate a piece of JavaScript in the context of a stack frame for
-// debugging.  Things that need special attention are:
-// - Parameters and stack-allocated locals need to be materialized.  Altered
-//   values need to be written back to the stack afterwards.
-// - The arguments object needs to materialized.
-RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
-  HandleScope scope(isolate);
-
-  // Check the execution state and decode arguments frame and source to be
-  // evaluated.
-  DCHECK(args.length() == 6);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
-  CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
-  CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
-  CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
-  CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
-
-  // Handle the processing of break.
-  DisableBreak disable_break_scope(isolate->debug(), disable_break);
-
-  // Get the frame where the debugging is performed.
-  StackFrame::Id id = UnwrapFrameId(wrapped_id);
-  JavaScriptFrameIterator it(isolate, id);
-  JavaScriptFrame* frame = it.frame();
-  FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
-  Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
-  Handle<SharedFunctionInfo> outer_info(function->shared());
-
-  // Traverse the saved contexts chain to find the active context for the
-  // selected frame.
-  SaveContext* save = FindSavedContextForFrame(isolate, frame);
-
-  SaveContext savex(isolate);
-  isolate->set_context(*(save->context()));
-
-  // Evaluate on the context of the frame.
-  Handle<Context> context(Context::cast(frame_inspector.GetContext()));
-  DCHECK(!context.is_null());
-
-  // Materialize stack locals and the arguments object.
-  Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate);
-
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, materialized,
-      MaterializeStackLocalsWithFrameInspector(
-          isolate, materialized, function, &frame_inspector));
-
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, materialized,
-      MaterializeArgumentsObject(isolate, materialized, function));
-
-  // Add the materialized object in a with-scope to shadow the stack locals.
-  context = isolate->factory()->NewWithContext(function, context, materialized);
-
-  Handle<Object> receiver(frame->receiver(), isolate);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      DebugEvaluate(isolate, outer_info,
-                    context, context_extension, receiver, source));
-
-  // Write back potential changes to materialized stack locals to the stack.
-  UpdateStackLocalsFromMaterializedObject(
-      isolate, materialized, function, frame, inlined_jsframe_index);
-
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
-  HandleScope scope(isolate);
-
-  // Check the execution state and decode arguments frame and source to be
-  // evaluated.
-  DCHECK(args.length() == 4);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
-  CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
-  CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
-
-  // Handle the processing of break.
-  DisableBreak disable_break_scope(isolate->debug(), disable_break);
-
-  // Enter the top context from before the debugger was invoked.
-  SaveContext save(isolate);
-  SaveContext* top = &save;
-  while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
-    top = top->prev();
-  }
-  if (top != NULL) {
-    isolate->set_context(*top->context());
-  }
-
-  // Get the native context now set to the top context from before the
-  // debugger was invoked.
-  Handle<Context> context = isolate->native_context();
-  Handle<JSObject> receiver(context->global_proxy());
-  Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate);
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      DebugEvaluate(isolate, outer_info,
-                    context, context_extension, receiver, source));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-
-  // Fill the script objects.
-  Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
-
-  // Convert the script objects to proper JS objects.
-  for (int i = 0; i < instances->length(); i++) {
-    Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
-    // Get the script wrapper in a local handle before calling GetScriptWrapper,
-    // because using
-    //   instances->set(i, *GetScriptWrapper(script))
-    // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
-    // already have dereferenced the instances handle.
-    Handle<JSObject> wrapper = Script::GetWrapper(script);
-    instances->set(i, *wrapper);
-  }
-
-  // Return result as a JS array.
-  Handle<JSObject> result =
-      isolate->factory()->NewJSObject(isolate->array_function());
-  JSArray::SetContent(Handle<JSArray>::cast(result), instances);
-  return *result;
-}
-
-
-// Helper function used by Runtime_DebugReferencedBy below.
-static int DebugReferencedBy(HeapIterator* iterator,
-                             JSObject* target,
-                             Object* instance_filter, int max_references,
-                             FixedArray* instances, int instances_size,
-                             JSFunction* arguments_function) {
-  Isolate* isolate = target->GetIsolate();
-  SealHandleScope shs(isolate);
-  DisallowHeapAllocation no_allocation;
-
-  // Iterate the heap.
-  int count = 0;
-  JSObject* last = NULL;
-  HeapObject* heap_obj = NULL;
-  while (((heap_obj = iterator->next()) != NULL) &&
-         (max_references == 0 || count < max_references)) {
-    // Only look at all JSObjects.
-    if (heap_obj->IsJSObject()) {
-      // Skip context extension objects and argument arrays as these are
-      // checked in the context of functions using them.
-      JSObject* obj = JSObject::cast(heap_obj);
-      if (obj->IsJSContextExtensionObject() ||
-          obj->map()->constructor() == arguments_function) {
-        continue;
-      }
-
-      // Check if the JS object has a reference to the object looked for.
-      if (obj->ReferencesObject(target)) {
-        // Check instance filter if supplied. This is normally used to avoid
-        // references from mirror objects (see Runtime_IsInPrototypeChain).
-        if (!instance_filter->IsUndefined()) {
-          for (PrototypeIterator iter(isolate, obj); !iter.IsAtEnd();
-               iter.Advance()) {
-            if (iter.GetCurrent() == instance_filter) {
-              obj = NULL;  // Don't add this object.
-              break;
-            }
-          }
-        }
-
-        if (obj != NULL) {
-          // Valid reference found add to instance array if supplied an update
-          // count.
-          if (instances != NULL && count < instances_size) {
-            instances->set(count, obj);
-          }
-          last = obj;
-          count++;
-        }
-      }
-    }
-  }
-
-  // Check for circular reference only. This can happen when the object is only
-  // referenced from mirrors and has a circular reference in which case the
-  // object is not really alive and would have been garbage collected if not
-  // referenced from the mirror.
-  if (count == 1 && last == target) {
-    count = 0;
-  }
-
-  // Return the number of referencing objects found.
-  return count;
-}
-
-
-// Scan the heap for objects with direct references to an object
-// args[0]: the object to find references to
-// args[1]: constructor function for instances to exclude (Mirror)
-// args[2]: the the maximum number of objects to return
-RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-
-  // Check parameters.
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
-  RUNTIME_ASSERT(instance_filter->IsUndefined() ||
-                 instance_filter->IsJSObject());
-  CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
-  RUNTIME_ASSERT(max_references >= 0);
-
-
-  // Get the constructor function for context extension and arguments array.
-  Handle<JSFunction> arguments_function(
-      JSFunction::cast(isolate->sloppy_arguments_map()->constructor()));
-
-  // Get the number of referencing objects.
-  int count;
-  // First perform a full GC in order to avoid dead objects and to make the heap
-  // iterable.
-  Heap* heap = isolate->heap();
-  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
-  {
-    HeapIterator heap_iterator(heap);
-    count = DebugReferencedBy(&heap_iterator,
-                              *target, *instance_filter, max_references,
-                              NULL, 0, *arguments_function);
-  }
-
-  // Allocate an array to hold the result.
-  Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
-
-  // Fill the referencing objects.
-  {
-    HeapIterator heap_iterator(heap);
-    count = DebugReferencedBy(&heap_iterator,
-                              *target, *instance_filter, max_references,
-                              *instances, count, *arguments_function);
-  }
-
-  // Return result as JS array.
-  Handle<JSFunction> constructor = isolate->array_function();
-
-  Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
-  JSArray::SetContent(Handle<JSArray>::cast(result), instances);
-  return *result;
-}
-
-
-// Helper function used by Runtime_DebugConstructedBy below.
-static int DebugConstructedBy(HeapIterator* iterator,
-                              JSFunction* constructor,
-                              int max_references,
-                              FixedArray* instances,
-                              int instances_size) {
-  DisallowHeapAllocation no_allocation;
-
-  // Iterate the heap.
-  int count = 0;
-  HeapObject* heap_obj = NULL;
-  while (((heap_obj = iterator->next()) != NULL) &&
-         (max_references == 0 || count < max_references)) {
-    // Only look at all JSObjects.
-    if (heap_obj->IsJSObject()) {
-      JSObject* obj = JSObject::cast(heap_obj);
-      if (obj->map()->constructor() == constructor) {
-        // Valid reference found add to instance array if supplied an update
-        // count.
-        if (instances != NULL && count < instances_size) {
-          instances->set(count, obj);
-        }
-        count++;
-      }
-    }
-  }
-
-  // Return the number of referencing objects found.
-  return count;
-}
-
-
-// Scan the heap for objects constructed by a specific function.
-// args[0]: the constructor to find instances of
-// args[1]: the the maximum number of objects to return
-RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-
-  // Check parameters.
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
-  CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
-  RUNTIME_ASSERT(max_references >= 0);
-
-  // Get the number of referencing objects.
-  int count;
-  // First perform a full GC in order to avoid dead objects and to make the heap
-  // iterable.
-  Heap* heap = isolate->heap();
-  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
-  {
-    HeapIterator heap_iterator(heap);
-    count = DebugConstructedBy(&heap_iterator,
-                               *constructor,
-                               max_references,
-                               NULL,
-                               0);
-  }
-
-  // Allocate an array to hold the result.
-  Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
-
-  // Fill the referencing objects.
-  {
-    HeapIterator heap_iterator2(heap);
-    count = DebugConstructedBy(&heap_iterator2,
-                               *constructor,
-                               max_references,
-                               *instances,
-                               count);
-  }
-
-  // Return result as JS array.
-  Handle<JSFunction> array_function = isolate->array_function();
-  Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
-  JSArray::SetContent(Handle<JSArray>::cast(result), instances);
-  return *result;
-}
-
-
-// Find the effective prototype object as returned by __proto__.
-// args[0]: the object to find the prototype for.
-RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
-  HandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
-  return *GetPrototypeSkipHiddenPrototypes(isolate, obj);
-}
-
-
-// Patches script source (should be called upon BeforeCompile event).
-RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
-
-  RUNTIME_ASSERT(script_wrapper->value()->IsScript());
-  Handle<Script> script(Script::cast(script_wrapper->value()));
-
-  int compilation_state = script->compilation_state();
-  RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
-  script->set_source(*source);
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_SystemBreak) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  base::OS::DebugBreak();
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
-  HandleScope scope(isolate);
-#ifdef DEBUG
-  DCHECK(args.length() == 1);
-  // Get the function and make sure it is compiled.
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
-  if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
-    return isolate->heap()->exception();
-  }
-  OFStream os(stdout);
-  func->code()->Print(os);
-  os << endl;
-#endif  // DEBUG
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
-  HandleScope scope(isolate);
-#ifdef DEBUG
-  DCHECK(args.length() == 1);
-  // Get the function and make sure it is compiled.
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
-  if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
-    return isolate->heap()->exception();
-  }
-  OFStream os(stdout);
-  func->shared()->construct_stub()->Print(os);
-  os << endl;
-#endif  // DEBUG
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(JSFunction, f, 0);
-  return f->shared()->inferred_name();
-}
-
-
-static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
-                                            Script* script,
-                                            FixedArray* buffer) {
-  DisallowHeapAllocation no_allocation;
-  int counter = 0;
-  int buffer_size = buffer->length();
-  for (HeapObject* obj = iterator->next();
-       obj != NULL;
-       obj = iterator->next()) {
-    DCHECK(obj != NULL);
-    if (!obj->IsSharedFunctionInfo()) {
-      continue;
-    }
-    SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
-    if (shared->script() != script) {
-      continue;
-    }
-    if (counter < buffer_size) {
-      buffer->set(counter, shared);
-    }
-    counter++;
-  }
-  return counter;
-}
-
-
-// For a script finds all SharedFunctionInfo's in the heap that points
-// to this script. Returns JSArray of SharedFunctionInfo wrapped
-// in OpaqueReferences.
-RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) {
-  HandleScope scope(isolate);
-  CHECK(isolate->debug()->live_edit_enabled());
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSValue, script_value, 0);
-
-  RUNTIME_ASSERT(script_value->value()->IsScript());
-  Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
-
-  const int kBufferSize = 32;
-
-  Handle<FixedArray> array;
-  array = isolate->factory()->NewFixedArray(kBufferSize);
-  int number;
-  Heap* heap = isolate->heap();
-  {
-    HeapIterator heap_iterator(heap);
-    Script* scr = *script;
-    FixedArray* arr = *array;
-    number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
-  }
-  if (number > kBufferSize) {
-    array = isolate->factory()->NewFixedArray(number);
-    HeapIterator heap_iterator(heap);
-    Script* scr = *script;
-    FixedArray* arr = *array;
-    FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
-  }
-
-  Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
-  result->set_length(Smi::FromInt(number));
-
-  LiveEdit::WrapSharedFunctionInfos(result);
-
-  return *result;
-}
-
-
-// For a script calculates compilation information about all its functions.
-// The script source is explicitly specified by the second argument.
-// The source of the actual script is not used, however it is important that
-// all generated code keeps references to this particular instance of script.
-// Returns a JSArray of compilation infos. The array is ordered so that
-// each function with all its descendant is always stored in a continues range
-// with the function itself going first. The root function is a script function.
-RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) {
-  HandleScope scope(isolate);
-  CHECK(isolate->debug()->live_edit_enabled());
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(JSValue, script, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
-
-  RUNTIME_ASSERT(script->value()->IsScript());
-  Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
-
-  Handle<JSArray> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result, LiveEdit::GatherCompileInfo(script_handle, source));
-  return *result;
-}
-
-
-// Changes the source of the script to a new_source.
-// If old_script_name is provided (i.e. is a String), also creates a copy of
-// the script with its original source and sends notification to debugger.
-RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
-  HandleScope scope(isolate);
-  CHECK(isolate->debug()->live_edit_enabled());
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
-
-  RUNTIME_ASSERT(original_script_value->value()->IsScript());
-  Handle<Script> original_script(Script::cast(original_script_value->value()));
-
-  Handle<Object> old_script = LiveEdit::ChangeScriptSource(
-      original_script,  new_source,  old_script_name);
-
-  if (old_script->IsScript()) {
-    Handle<Script> script_handle = Handle<Script>::cast(old_script);
-    return *Script::GetWrapper(script_handle);
-  } else {
-    return isolate->heap()->null_value();
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
-  HandleScope scope(isolate);
-  CHECK(isolate->debug()->live_edit_enabled());
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
-  RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
-
-  LiveEdit::FunctionSourceUpdated(shared_info);
-  return isolate->heap()->undefined_value();
-}
-
-
-// Replaces code of SharedFunctionInfo with a new one.
-RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
-  HandleScope scope(isolate);
-  CHECK(isolate->debug()->live_edit_enabled());
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
-  RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
-
-  LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
-  return isolate->heap()->undefined_value();
-}
-
-
-// Connects SharedFunctionInfo to another script.
-RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
-  HandleScope scope(isolate);
-  CHECK(isolate->debug()->live_edit_enabled());
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
-
-  if (function_object->IsJSValue()) {
-    Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
-    if (script_object->IsJSValue()) {
-      RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
-      Script* script = Script::cast(JSValue::cast(*script_object)->value());
-      script_object = Handle<Object>(script, isolate);
-    }
-    RUNTIME_ASSERT(function_wrapper->value()->IsSharedFunctionInfo());
-    LiveEdit::SetFunctionScript(function_wrapper, script_object);
-  } else {
-    // Just ignore this. We may not have a SharedFunctionInfo for some functions
-    // and we check it in this function.
-  }
-
-  return isolate->heap()->undefined_value();
-}
-
-
-// In a code of a parent function replaces original function as embedded object
-// with a substitution one.
-RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
-  HandleScope scope(isolate);
-  CHECK(isolate->debug()->live_edit_enabled());
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
-  RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo());
-  RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo());
-  RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo());
-
-  LiveEdit::ReplaceRefToNestedFunction(
-      parent_wrapper, orig_wrapper, subst_wrapper);
-  return isolate->heap()->undefined_value();
-}
-
-
-// Updates positions of a shared function info (first parameter) according
-// to script source change. Text change is described in second parameter as
-// array of groups of 3 numbers:
-// (change_begin, change_end, change_end_new_position).
-// Each group describes a change in text; groups are sorted by change_begin.
-RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
-  HandleScope scope(isolate);
-  CHECK(isolate->debug()->live_edit_enabled());
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
-  RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
-
-  LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
-  return isolate->heap()->undefined_value();
-}
-
-
-// For array of SharedFunctionInfo's (each wrapped in JSValue)
-// checks that none of them have activations on stacks (of any thread).
-// Returns array of the same length with corresponding results of
-// LiveEdit::FunctionPatchabilityStatus type.
-RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
-  HandleScope scope(isolate);
-  CHECK(isolate->debug()->live_edit_enabled());
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
-  CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
-  RUNTIME_ASSERT(shared_array->length()->IsSmi());
-  RUNTIME_ASSERT(shared_array->HasFastElements())
-  int array_length = Smi::cast(shared_array->length())->value();
-  for (int i = 0; i < array_length; i++) {
-    Handle<Object> element =
-        Object::GetElement(isolate, shared_array, i).ToHandleChecked();
-    RUNTIME_ASSERT(
-        element->IsJSValue() &&
-        Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo());
-  }
-
-  return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
-}
-
-
-// Compares 2 strings line-by-line, then token-wise and returns diff in form
-// of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
-// of diff chunks.
-RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) {
-  HandleScope scope(isolate);
-  CHECK(isolate->debug()->live_edit_enabled());
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
-
-  return *LiveEdit::CompareStrings(s1, s2);
-}
-
-
-// Restarts a call frame and completely drops all frames above.
-// Returns true if successful. Otherwise returns undefined or an error message.
-RUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) {
-  HandleScope scope(isolate);
-  CHECK(isolate->debug()->live_edit_enabled());
-  DCHECK(args.length() == 2);
-  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
-  RUNTIME_ASSERT(CheckExecutionState(isolate, break_id));
-
-  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
-  Heap* heap = isolate->heap();
-
-  // Find the relevant frame with the requested index.
-  StackFrame::Id id = isolate->debug()->break_frame_id();
-  if (id == StackFrame::NO_ID) {
-    // If there are no JavaScript stack frames return undefined.
-    return heap->undefined_value();
-  }
-
-  JavaScriptFrameIterator it(isolate, id);
-  int inlined_jsframe_index = FindIndexedNonNativeFrame(&it, index);
-  if (inlined_jsframe_index == -1) return heap->undefined_value();
-  // We don't really care what the inlined frame index is, since we are
-  // throwing away the entire frame anyways.
-  const char* error_message = LiveEdit::RestartFrame(it.frame());
-  if (error_message) {
-    return *(isolate->factory()->InternalizeUtf8String(error_message));
-  }
-  return heap->true_value();
-}
-
-
-// A testing entry. Returns statement position which is the closest to
-// source_position.
-RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
-  HandleScope scope(isolate);
-  CHECK(isolate->debug()->live_edit_enabled());
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
-
-  Handle<Code> code(function->code(), isolate);
-
-  if (code->kind() != Code::FUNCTION &&
-      code->kind() != Code::OPTIMIZED_FUNCTION) {
-    return isolate->heap()->undefined_value();
-  }
-
-  RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
-  int closest_pc = 0;
-  int distance = kMaxInt;
-  while (!it.done()) {
-    int statement_position = static_cast<int>(it.rinfo()->data());
-    // Check if this break point is closer that what was previously found.
-    if (source_position <= statement_position &&
-        statement_position - source_position < distance) {
-      closest_pc =
-          static_cast<int>(it.rinfo()->pc() - code->instruction_start());
-      distance = statement_position - source_position;
-      // Check whether we can't get any closer.
-      if (distance == 0) break;
-    }
-    it.next();
-  }
-
-  return Smi::FromInt(closest_pc);
-}
-
-
-// Calls specified function with or without entering the debugger.
-// This is used in unit tests to run code as if debugger is entered or simply
-// to have a stack with C++ frame in the middle.
-RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
-  CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
-
-  MaybeHandle<Object> maybe_result;
-  if (without_debugger) {
-    maybe_result = Execution::Call(isolate,
-                                   function,
-                                   handle(function->global_proxy()),
-                                   0,
-                                   NULL);
-  } else {
-    DebugScope debug_scope(isolate->debug());
-    maybe_result = Execution::Call(isolate,
-                                   function,
-                                   handle(function->global_proxy()),
-                                   0,
-                                   NULL);
-  }
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
-  return *result;
-}
-
-
-// Sets a v8 flag.
-RUNTIME_FUNCTION(Runtime_SetFlags) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(String, arg, 0);
-  SmartArrayPointer<char> flags =
-      arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
-  FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
-  return isolate->heap()->undefined_value();
-}
-
-
-// Performs a GC.
-// Presently, it only does a full GC.
-RUNTIME_FUNCTION(Runtime_CollectGarbage) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
-  return isolate->heap()->undefined_value();
-}
-
-
-// Gets the current heap usage.
-RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
-  if (!Smi::IsValid(usage)) {
-    return *isolate->factory()->NewNumberFromInt(usage);
-  }
-  return Smi::FromInt(usage);
-}
-
-
-#ifdef V8_I18N_SUPPORT
-RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) {
-  HandleScope scope(isolate);
-  Factory* factory = isolate->factory();
-
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
-
-  v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
-
-  // Return value which denotes invalid language tag.
-  const char* const kInvalidTag = "invalid-tag";
-
-  UErrorCode error = U_ZERO_ERROR;
-  char icu_result[ULOC_FULLNAME_CAPACITY];
-  int icu_length = 0;
-
-  uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
-                      &icu_length, &error);
-  if (U_FAILURE(error) || icu_length == 0) {
-    return *factory->NewStringFromAsciiChecked(kInvalidTag);
-  }
-
-  char result[ULOC_FULLNAME_CAPACITY];
-
-  // Force strict BCP47 rules.
-  uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
-
-  if (U_FAILURE(error)) {
-    return *factory->NewStringFromAsciiChecked(kInvalidTag);
-  }
-
-  return *factory->NewStringFromAsciiChecked(result);
-}
-
-
-RUNTIME_FUNCTION(Runtime_AvailableLocalesOf) {
-  HandleScope scope(isolate);
-  Factory* factory = isolate->factory();
-
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
-
-  const icu::Locale* available_locales = NULL;
-  int32_t count = 0;
-
-  if (service->IsUtf8EqualTo(CStrVector("collator"))) {
-    available_locales = icu::Collator::getAvailableLocales(count);
-  } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
-    available_locales = icu::NumberFormat::getAvailableLocales(count);
-  } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
-    available_locales = icu::DateFormat::getAvailableLocales(count);
-  } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
-    available_locales = icu::BreakIterator::getAvailableLocales(count);
-  }
-
-  UErrorCode error = U_ZERO_ERROR;
-  char result[ULOC_FULLNAME_CAPACITY];
-  Handle<JSObject> locales =
-      factory->NewJSObject(isolate->object_function());
-
-  for (int32_t i = 0; i < count; ++i) {
-    const char* icu_name = available_locales[i].getName();
-
-    error = U_ZERO_ERROR;
-    // No need to force strict BCP47 rules.
-    uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
-    if (U_FAILURE(error)) {
-      // This shouldn't happen, but lets not break the user.
-      continue;
-    }
-
-    RETURN_FAILURE_ON_EXCEPTION(isolate,
-        JSObject::SetOwnPropertyIgnoreAttributes(
-            locales,
-            factory->NewStringFromAsciiChecked(result),
-            factory->NewNumber(i),
-            NONE));
-  }
-
-  return *locales;
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) {
-  HandleScope scope(isolate);
-  Factory* factory = isolate->factory();
-
-  DCHECK(args.length() == 0);
-
-  icu::Locale default_locale;
-
-  // Set the locale
-  char result[ULOC_FULLNAME_CAPACITY];
-  UErrorCode status = U_ZERO_ERROR;
-  uloc_toLanguageTag(
-      default_locale.getName(), result, ULOC_FULLNAME_CAPACITY, FALSE, &status);
-  if (U_SUCCESS(status)) {
-    return *factory->NewStringFromAsciiChecked(result);
-  }
-
-  return *factory->NewStringFromStaticChars("und");
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) {
-  HandleScope scope(isolate);
-  Factory* factory = isolate->factory();
-
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
-
-  uint32_t length = static_cast<uint32_t>(input->length()->Number());
-  // Set some limit to prevent fuzz tests from going OOM.
-  // Can be bumped when callers' requirements change.
-  RUNTIME_ASSERT(length < 100);
-  Handle<FixedArray> output = factory->NewFixedArray(length);
-  Handle<Name> maximized = factory->NewStringFromStaticChars("maximized");
-  Handle<Name> base = factory->NewStringFromStaticChars("base");
-  for (unsigned int i = 0; i < length; ++i) {
-    Handle<Object> locale_id;
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, locale_id, Object::GetElement(isolate, input, i));
-    if (!locale_id->IsString()) {
-      return isolate->Throw(*factory->illegal_argument_string());
-    }
-
-    v8::String::Utf8Value utf8_locale_id(
-        v8::Utils::ToLocal(Handle<String>::cast(locale_id)));
-
-    UErrorCode error = U_ZERO_ERROR;
-
-    // Convert from BCP47 to ICU format.
-    // de-DE-u-co-phonebk -> de_DE@collation=phonebook
-    char icu_locale[ULOC_FULLNAME_CAPACITY];
-    int icu_locale_length = 0;
-    uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
-                        &icu_locale_length, &error);
-    if (U_FAILURE(error) || icu_locale_length == 0) {
-      return isolate->Throw(*factory->illegal_argument_string());
-    }
-
-    // Maximize the locale.
-    // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
-    char icu_max_locale[ULOC_FULLNAME_CAPACITY];
-    uloc_addLikelySubtags(
-        icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY, &error);
-
-    // Remove extensions from maximized locale.
-    // de_Latn_DE@collation=phonebook -> de_Latn_DE
-    char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
-    uloc_getBaseName(
-        icu_max_locale, icu_base_max_locale, ULOC_FULLNAME_CAPACITY, &error);
-
-    // Get original name without extensions.
-    // de_DE@collation=phonebook -> de_DE
-    char icu_base_locale[ULOC_FULLNAME_CAPACITY];
-    uloc_getBaseName(
-        icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY, &error);
-
-    // Convert from ICU locale format to BCP47 format.
-    // de_Latn_DE -> de-Latn-DE
-    char base_max_locale[ULOC_FULLNAME_CAPACITY];
-    uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
-                       ULOC_FULLNAME_CAPACITY, FALSE, &error);
-
-    // de_DE -> de-DE
-    char base_locale[ULOC_FULLNAME_CAPACITY];
-    uloc_toLanguageTag(
-        icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY, FALSE, &error);
-
-    if (U_FAILURE(error)) {
-      return isolate->Throw(*factory->illegal_argument_string());
-    }
-
-    Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
-    Handle<String> value = factory->NewStringFromAsciiChecked(base_max_locale);
-    JSObject::AddProperty(result, maximized, value, NONE);
-    value = factory->NewStringFromAsciiChecked(base_locale);
-    JSObject::AddProperty(result, base, value, NONE);
-    output->set(i, *result);
-  }
-
-  Handle<JSArray> result = factory->NewJSArrayWithElements(output);
-  result->set_length(Smi::FromInt(length));
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
-
-  if (!input->IsJSObject()) return isolate->heap()->false_value();
-  Handle<JSObject> obj = Handle<JSObject>::cast(input);
-
-  Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
-  Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
-  return isolate->heap()->ToBoolean(!tag->IsTheHole());
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
-
-  if (!input->IsJSObject()) return isolate->heap()->false_value();
-  Handle<JSObject> obj = Handle<JSObject>::cast(input);
-
-  Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
-  Handle<Object> tag(obj->GetHiddenProperty(marker), isolate);
-  return isolate->heap()->ToBoolean(
-      tag->IsString() && String::cast(*tag)->Equals(*expected_type));
-}
-
-
-RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2);
-
-  Handle<String> marker = isolate->factory()->intl_initialized_marker_string();
-  JSObject::SetHiddenProperty(input, marker, type);
-
-  marker = isolate->factory()->intl_impl_object_string();
-  JSObject::SetHiddenProperty(input, marker, impl);
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
-
-  if (!input->IsJSObject()) {
-    Vector< Handle<Object> > arguments = HandleVector(&input, 1);
-    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
-                                   NewTypeError("not_intl_object", arguments));
-  }
-
-  Handle<JSObject> obj = Handle<JSObject>::cast(input);
-
-  Handle<String> marker = isolate->factory()->intl_impl_object_string();
-  Handle<Object> impl(obj->GetHiddenProperty(marker), isolate);
-  if (impl->IsTheHole()) {
-    Vector< Handle<Object> > arguments = HandleVector(&obj, 1);
-    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
-                                   NewTypeError("not_intl_object", arguments));
-  }
-  return *impl;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
-
-  Handle<ObjectTemplateInfo> date_format_template =
-      I18N::GetTemplate(isolate);
-
-  // Create an empty object wrapper.
-  Handle<JSObject> local_object;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, local_object,
-      Execution::InstantiateObject(date_format_template));
-
-  // Set date time formatter as internal field of the resulting JS object.
-  icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat(
-      isolate, locale, options, resolved);
-
-  if (!date_format) return isolate->ThrowIllegalOperation();
-
-  local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
-
-  Factory* factory = isolate->factory();
-  Handle<String> key = factory->NewStringFromStaticChars("dateFormat");
-  Handle<String> value = factory->NewStringFromStaticChars("valid");
-  JSObject::AddProperty(local_object, key, value, NONE);
-
-  // Make object handle weak so we can delete the data format once GC kicks in.
-  Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
-  GlobalHandles::MakeWeak(wrapper.location(),
-                          reinterpret_cast<void*>(wrapper.location()),
-                          DateFormat::DeleteDateFormat);
-  return *local_object;
-}
-
-
-RUNTIME_FUNCTION(Runtime_InternalDateFormat) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
-
-  Handle<Object> value;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, value, Execution::ToNumber(isolate, date));
-
-  icu::SimpleDateFormat* date_format =
-      DateFormat::UnpackDateFormat(isolate, date_format_holder);
-  if (!date_format) return isolate->ThrowIllegalOperation();
-
-  icu::UnicodeString result;
-  date_format->format(value->Number(), result);
-
-  Handle<String> result_str;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result_str,
-      isolate->factory()->NewStringFromTwoByte(
-          Vector<const uint16_t>(
-              reinterpret_cast<const uint16_t*>(result.getBuffer()),
-              result.length())));
-  return *result_str;
-}
-
-
-RUNTIME_FUNCTION(Runtime_InternalDateParse) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
-
-  v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string));
-  icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date));
-  icu::SimpleDateFormat* date_format =
-      DateFormat::UnpackDateFormat(isolate, date_format_holder);
-  if (!date_format) return isolate->ThrowIllegalOperation();
-
-  UErrorCode status = U_ZERO_ERROR;
-  UDate date = date_format->parse(u_date, status);
-  if (U_FAILURE(status)) return isolate->heap()->undefined_value();
-
-  Handle<Object> result;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result,
-      Execution::NewDate(isolate, static_cast<double>(date)));
-  DCHECK(result->IsJSDate());
-  return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateNumberFormat) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
-
-  Handle<ObjectTemplateInfo> number_format_template =
-      I18N::GetTemplate(isolate);
-
-  // Create an empty object wrapper.
-  Handle<JSObject> local_object;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, local_object,
-      Execution::InstantiateObject(number_format_template));
-
-  // Set number formatter as internal field of the resulting JS object.
-  icu::DecimalFormat* number_format = NumberFormat::InitializeNumberFormat(
-      isolate, locale, options, resolved);
-
-  if (!number_format) return isolate->ThrowIllegalOperation();
-
-  local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
-
-  Factory* factory = isolate->factory();
-  Handle<String> key = factory->NewStringFromStaticChars("numberFormat");
-  Handle<String> value = factory->NewStringFromStaticChars("valid");
-  JSObject::AddProperty(local_object, key, value, NONE);
-
-  Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
-  GlobalHandles::MakeWeak(wrapper.location(),
-                          reinterpret_cast<void*>(wrapper.location()),
-                          NumberFormat::DeleteNumberFormat);
-  return *local_object;
-}
-
-
-RUNTIME_FUNCTION(Runtime_InternalNumberFormat) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
-
-  Handle<Object> value;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, value, Execution::ToNumber(isolate, number));
-
-  icu::DecimalFormat* number_format =
-      NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
-  if (!number_format) return isolate->ThrowIllegalOperation();
-
-  icu::UnicodeString result;
-  number_format->format(value->Number(), result);
-
-  Handle<String> result_str;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result_str,
-      isolate->factory()->NewStringFromTwoByte(
-          Vector<const uint16_t>(
-              reinterpret_cast<const uint16_t*>(result.getBuffer()),
-              result.length())));
-  return *result_str;
-}
-
-
-RUNTIME_FUNCTION(Runtime_InternalNumberParse) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
-
-  v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string));
-  icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number));
-  icu::DecimalFormat* number_format =
-      NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
-  if (!number_format) return isolate->ThrowIllegalOperation();
-
-  UErrorCode status = U_ZERO_ERROR;
-  icu::Formattable result;
-  // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49
-  // to be part of Chrome.
-  // TODO(cira): Include currency parsing code using parseCurrency call.
-  // We need to check if the formatter parses all currencies or only the
-  // one it was constructed with (it will impact the API - how to return ISO
-  // code and the value).
-  number_format->parse(u_number, result, status);
-  if (U_FAILURE(status)) return isolate->heap()->undefined_value();
-
-  switch (result.getType()) {
-  case icu::Formattable::kDouble:
-    return *isolate->factory()->NewNumber(result.getDouble());
-  case icu::Formattable::kLong:
-    return *isolate->factory()->NewNumberFromInt(result.getLong());
-  case icu::Formattable::kInt64:
-    return *isolate->factory()->NewNumber(
-        static_cast<double>(result.getInt64()));
-  default:
-    return isolate->heap()->undefined_value();
-  }
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateCollator) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
-
-  Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
-
-  // Create an empty object wrapper.
-  Handle<JSObject> local_object;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, local_object, Execution::InstantiateObject(collator_template));
-
-  // Set collator as internal field of the resulting JS object.
-  icu::Collator* collator = Collator::InitializeCollator(
-      isolate, locale, options, resolved);
-
-  if (!collator) return isolate->ThrowIllegalOperation();
-
-  local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
-
-  Factory* factory = isolate->factory();
-  Handle<String> key = factory->NewStringFromStaticChars("collator");
-  Handle<String> value = factory->NewStringFromStaticChars("valid");
-  JSObject::AddProperty(local_object, key, value, NONE);
-
-  Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
-  GlobalHandles::MakeWeak(wrapper.location(),
-                          reinterpret_cast<void*>(wrapper.location()),
-                          Collator::DeleteCollator);
-  return *local_object;
-}
-
-
-RUNTIME_FUNCTION(Runtime_InternalCompare) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, string2, 2);
-
-  icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder);
-  if (!collator) return isolate->ThrowIllegalOperation();
-
-  v8::String::Value string_value1(v8::Utils::ToLocal(string1));
-  v8::String::Value string_value2(v8::Utils::ToLocal(string2));
-  const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1);
-  const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2);
-  UErrorCode status = U_ZERO_ERROR;
-  UCollationResult result = collator->compare(u_string1,
-                                              string_value1.length(),
-                                              u_string2,
-                                              string_value2.length(),
-                                              status);
-  if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
-
-  return *isolate->factory()->NewNumberFromInt(result);
-}
-
-
-RUNTIME_FUNCTION(Runtime_StringNormalize) {
-  HandleScope scope(isolate);
-  static const UNormalizationMode normalizationForms[] =
-      { UNORM_NFC, UNORM_NFD, UNORM_NFKC, UNORM_NFKD };
-
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
-  CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
-  RUNTIME_ASSERT(form_id >= 0 &&
-                 static_cast<size_t>(form_id) < arraysize(normalizationForms));
-
-  v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
-  const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
-
-  // TODO(mnita): check Normalizer2 (not available in ICU 46)
-  UErrorCode status = U_ZERO_ERROR;
-  icu::UnicodeString result;
-  icu::Normalizer::normalize(u_value, normalizationForms[form_id], 0,
-      result, status);
-  if (U_FAILURE(status)) {
-    return isolate->heap()->undefined_value();
-  }
-
-  Handle<String> result_str;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, result_str,
-      isolate->factory()->NewStringFromTwoByte(
-          Vector<const uint16_t>(
-              reinterpret_cast<const uint16_t*>(result.getBuffer()),
-              result.length())));
-  return *result_str;
-}
-
-
-RUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 3);
-
-  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
-
-  Handle<ObjectTemplateInfo> break_iterator_template =
-      I18N::GetTemplate2(isolate);
-
-  // Create an empty object wrapper.
-  Handle<JSObject> local_object;
-  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-      isolate, local_object,
-      Execution::InstantiateObject(break_iterator_template));
-
-  // Set break iterator as internal field of the resulting JS object.
-  icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
-      isolate, locale, options, resolved);
-
-  if (!break_iterator) return isolate->ThrowIllegalOperation();
-
-  local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator));
-  // Make sure that the pointer to adopted text is NULL.
-  local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
-
-  Factory* factory = isolate->factory();
-  Handle<String> key = factory->NewStringFromStaticChars("breakIterator");
-  Handle<String> value = factory->NewStringFromStaticChars("valid");
-  JSObject::AddProperty(local_object, key, value, NONE);
-
-  // Make object handle weak so we can delete the break iterator once GC kicks
-  // in.
-  Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
-  GlobalHandles::MakeWeak(wrapper.location(),
-                          reinterpret_cast<void*>(wrapper.location()),
-                          BreakIterator::DeleteBreakIterator);
-  return *local_object;
-}
-
-
-RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 2);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
-  CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
-
-  icu::BreakIterator* break_iterator =
-      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
-  if (!break_iterator) return isolate->ThrowIllegalOperation();
-
-  icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
-      break_iterator_holder->GetInternalField(1));
-  delete u_text;
-
-  v8::String::Value text_value(v8::Utils::ToLocal(text));
-  u_text = new icu::UnicodeString(
-      reinterpret_cast<const UChar*>(*text_value), text_value.length());
-  break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text));
-
-  break_iterator->setText(*u_text);
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
-
-  icu::BreakIterator* break_iterator =
-      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
-  if (!break_iterator) return isolate->ThrowIllegalOperation();
-
-  return *isolate->factory()->NewNumberFromInt(break_iterator->first());
-}
-
-
-RUNTIME_FUNCTION(Runtime_BreakIteratorNext) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
-
-  icu::BreakIterator* break_iterator =
-      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
-  if (!break_iterator) return isolate->ThrowIllegalOperation();
-
-  return *isolate->factory()->NewNumberFromInt(break_iterator->next());
-}
-
-
-RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
-
-  icu::BreakIterator* break_iterator =
-      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
-  if (!break_iterator) return isolate->ThrowIllegalOperation();
-
-  return *isolate->factory()->NewNumberFromInt(break_iterator->current());
-}
-
-
-RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
-
-  icu::BreakIterator* break_iterator =
-      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
-  if (!break_iterator) return isolate->ThrowIllegalOperation();
-
-  // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
-  icu::RuleBasedBreakIterator* rule_based_iterator =
-      static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
-  int32_t status = rule_based_iterator->getRuleStatus();
-  // Keep return values in sync with JavaScript BreakType enum.
-  if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
-    return *isolate->factory()->NewStringFromStaticChars("none");
-  } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
-    return *isolate->factory()->number_string();
-  } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
-    return *isolate->factory()->NewStringFromStaticChars("letter");
-  } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
-    return *isolate->factory()->NewStringFromStaticChars("kana");
-  } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
-    return *isolate->factory()->NewStringFromStaticChars("ideo");
-  } else {
-    return *isolate->factory()->NewStringFromStaticChars("unknown");
-  }
-}
-#endif  // V8_I18N_SUPPORT
-
-
-// Finds the script object from the script data. NOTE: This operation uses
-// heap traversal to find the function generated for the source position
-// for the requested break point. For lazily compiled functions several heap
-// traversals might be required rendering this operation as a rather slow
-// operation. However for setting break points which is normally done through
-// some kind of user interaction the performance is not crucial.
-static Handle<Object> Runtime_GetScriptFromScriptName(
-    Handle<String> script_name) {
-  // Scan the heap for Script objects to find the script with the requested
-  // script data.
-  Handle<Script> script;
-  Factory* factory = script_name->GetIsolate()->factory();
-  Heap* heap = script_name->GetHeap();
-  HeapIterator iterator(heap);
-  HeapObject* obj = NULL;
-  while (script.is_null() && ((obj = iterator.next()) != NULL)) {
-    // If a script is found check if it has the script data requested.
-    if (obj->IsScript()) {
-      if (Script::cast(obj)->name()->IsString()) {
-        if (String::cast(Script::cast(obj)->name())->Equals(*script_name)) {
-          script = Handle<Script>(Script::cast(obj));
-        }
-      }
-    }
-  }
-
-  // If no script with the requested script data is found return undefined.
-  if (script.is_null()) return factory->undefined_value();
-
-  // Return the script found.
-  return Script::GetWrapper(script);
-}
-
-
-// Get the script object from script data. NOTE: Regarding performance
-// see the NOTE for GetScriptFromScriptData.
-// args[0]: script data for the script to find the source for
-RUNTIME_FUNCTION(Runtime_GetScript) {
-  HandleScope scope(isolate);
-
-  DCHECK(args.length() == 1);
-
-  CONVERT_ARG_CHECKED(String, script_name, 0);
-
-  // Find the requested script.
-  Handle<Object> result =
-      Runtime_GetScriptFromScriptName(Handle<String>(script_name));
-  return *result;
-}
-
-
-// Collect the raw data for a stack trace.  Returns an array of 4
-// element segments each containing a receiver, function, code and
-// native code offset.
-RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
-
-  if (!isolate->bootstrapper()->IsActive()) {
-    // Optionally capture a more detailed stack trace for the message.
-    isolate->CaptureAndSetDetailedStackTrace(error_object);
-    // Capture a simple stack trace for the stack property.
-    isolate->CaptureAndSetSimpleStackTrace(error_object, caller);
-  }
-  return isolate->heap()->undefined_value();
-}
-
-
-// Returns V8 version as a string.
-RUNTIME_FUNCTION(Runtime_GetV8Version) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-
-  const char* version_string = v8::V8::GetVersion();
-
-  return *isolate->factory()->NewStringFromAsciiChecked(version_string);
-}
-
-
-// Returns function of generator activation.
-RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
-
-  return generator->function();
-}
-
-
-// Returns context of generator activation.
-RUNTIME_FUNCTION(Runtime_GeneratorGetContext) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
-
-  return generator->context();
-}
-
-
-// Returns receiver of generator activation.
-RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
-
-  return generator->receiver();
-}
-
-
-// Returns generator continuation as a PC offset, or the magic -1 or 0 values.
-RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
-
-  return Smi::FromInt(generator->continuation());
-}
-
-
-RUNTIME_FUNCTION(Runtime_GeneratorGetSourcePosition) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
-
-  if (generator->is_suspended()) {
-    Handle<Code> code(generator->function()->code(), isolate);
-    int offset = generator->continuation();
-
-    RUNTIME_ASSERT(0 <= offset && offset < code->Size());
-    Address pc = code->address() + offset;
-
-    return Smi::FromInt(code->SourcePosition(pc));
-  }
-
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_Abort) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_SMI_ARG_CHECKED(message_id, 0);
-  const char* message = GetBailoutReason(
-      static_cast<BailoutReason>(message_id));
-  base::OS::PrintError("abort: %s\n", message);
-  isolate->PrintStack(stderr);
-  base::OS::Abort();
-  UNREACHABLE();
-  return NULL;
-}
-
-
-RUNTIME_FUNCTION(Runtime_AbortJS) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
-  base::OS::PrintError("abort: %s\n", message->ToCString().get());
-  isolate->PrintStack(stderr);
-  base::OS::Abort();
-  UNREACHABLE();
-  return NULL;
-}
-
-
-RUNTIME_FUNCTION(Runtime_FlattenString) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
-  return *String::Flatten(str);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  isolate->heap()->NotifyContextDisposed();
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-  CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
-  RUNTIME_ASSERT((index->value() & 1) == 1);
-  FieldIndex field_index =
-      FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
-  if (field_index.is_inobject()) {
-    RUNTIME_ASSERT(field_index.property_index() <
-                   object->map()->inobject_properties());
-  } else {
-    RUNTIME_ASSERT(field_index.outobject_array_index() <
-                   object->properties()->length());
-  }
-  Handle<Object> raw_value(object->RawFastPropertyAt(field_index), isolate);
-  RUNTIME_ASSERT(raw_value->IsMutableHeapNumber());
-  return *Object::WrapForRead(isolate, raw_value, Representation::Double());
-}
-
-
-RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
-  if (!object->IsJSObject()) return Smi::FromInt(0);
-  Handle<JSObject> js_object = Handle<JSObject>::cast(object);
-  if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
-  // This call must not cause lazy deopts, because it's called from deferred
-  // code where we can't handle lazy deopts for lack of a suitable bailout
-  // ID. So we just try migration and signal failure if necessary,
-  // which will also trigger a deopt.
-  if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
-  return *object;
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetFromCache) {
-  SealHandleScope shs(isolate);
-  // This is only called from codegen, so checks might be more lax.
-  CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
-  CONVERT_ARG_CHECKED(Object, key, 1);
-
-  {
-    DisallowHeapAllocation no_alloc;
-
-    int finger_index = cache->finger_index();
-    Object* o = cache->get(finger_index);
-    if (o == key) {
-      // The fastest case: hit the same place again.
-      return cache->get(finger_index + 1);
-    }
-
-    for (int i = finger_index - 2;
-         i >= JSFunctionResultCache::kEntriesIndex;
-         i -= 2) {
-      o = cache->get(i);
-      if (o == key) {
-        cache->set_finger_index(i);
-        return cache->get(i + 1);
-      }
-    }
-
-    int size = cache->size();
-    DCHECK(size <= cache->length());
-
-    for (int i = size - 2; i > finger_index; i -= 2) {
-      o = cache->get(i);
-      if (o == key) {
-        cache->set_finger_index(i);
-        return cache->get(i + 1);
-      }
-    }
-  }
-
-  // There is no value in the cache.  Invoke the function and cache result.
-  HandleScope scope(isolate);
-
-  Handle<JSFunctionResultCache> cache_handle(cache);
-  Handle<Object> key_handle(key, isolate);
-  Handle<Object> value;
-  {
-    Handle<JSFunction> factory(JSFunction::cast(
-          cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
-    // TODO(antonm): consider passing a receiver when constructing a cache.
-    Handle<JSObject> receiver(isolate->global_proxy());
-    // This handle is nor shared, nor used later, so it's safe.
-    Handle<Object> argv[] = { key_handle };
-    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
-        isolate, value,
-        Execution::Call(isolate, factory, receiver, arraysize(argv), argv));
-  }
-
-#ifdef VERIFY_HEAP
-  if (FLAG_verify_heap) {
-    cache_handle->JSFunctionResultCacheVerify();
-  }
-#endif
-
-  // Function invocation may have cleared the cache.  Reread all the data.
-  int finger_index = cache_handle->finger_index();
-  int size = cache_handle->size();
-
-  // If we have spare room, put new data into it, otherwise evict post finger
-  // entry which is likely to be the least recently used.
-  int index = -1;
-  if (size < cache_handle->length()) {
-    cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
-    index = size;
-  } else {
-    index = finger_index + JSFunctionResultCache::kEntrySize;
-    if (index == cache_handle->length()) {
-      index = JSFunctionResultCache::kEntriesIndex;
-    }
-  }
-
-  DCHECK(index % 2 == 0);
-  DCHECK(index >= JSFunctionResultCache::kEntriesIndex);
-  DCHECK(index < cache_handle->length());
-
-  cache_handle->set(index, *key_handle);
-  cache_handle->set(index + 1, *value);
-  cache_handle->set_finger_index(index);
-
-#ifdef VERIFY_HEAP
-  if (FLAG_verify_heap) {
-    cache_handle->JSFunctionResultCacheVerify();
-  }
-#endif
-
-  return *value;
-}
-
-
-RUNTIME_FUNCTION(Runtime_MessageGetStartPosition) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
-  return Smi::FromInt(message->start_position());
-}
-
-
-RUNTIME_FUNCTION(Runtime_MessageGetScript) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
-  return message->script();
-}
-
-
-#ifdef DEBUG
-// ListNatives is ONLY used by the fuzz-natives.js in debug mode
-// Exclude the code in release mode.
-RUNTIME_FUNCTION(Runtime_ListNatives) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-#define COUNT_ENTRY(Name, argc, ressize) + 1
-  int entry_count = 0
-      RUNTIME_FUNCTION_LIST(COUNT_ENTRY)
-      INLINE_FUNCTION_LIST(COUNT_ENTRY)
-      INLINE_OPTIMIZED_FUNCTION_LIST(COUNT_ENTRY);
-#undef COUNT_ENTRY
-  Factory* factory = isolate->factory();
-  Handle<FixedArray> elements = factory->NewFixedArray(entry_count);
-  int index = 0;
-  bool inline_runtime_functions = false;
-#define ADD_ENTRY(Name, argc, ressize)                                      \
-  {                                                                         \
-    HandleScope inner(isolate);                                             \
-    Handle<String> name;                                                    \
-    /* Inline runtime functions have an underscore in front of the name. */ \
-    if (inline_runtime_functions) {                                         \
-      name = factory->NewStringFromStaticChars("_" #Name);                  \
-    } else {                                                                \
-      name = factory->NewStringFromStaticChars(#Name);                      \
-    }                                                                       \
-    Handle<FixedArray> pair_elements = factory->NewFixedArray(2);           \
-    pair_elements->set(0, *name);                                           \
-    pair_elements->set(1, Smi::FromInt(argc));                              \
-    Handle<JSArray> pair = factory->NewJSArrayWithElements(pair_elements);  \
-    elements->set(index++, *pair);                                          \
-  }
-  inline_runtime_functions = false;
-  RUNTIME_FUNCTION_LIST(ADD_ENTRY)
-  INLINE_OPTIMIZED_FUNCTION_LIST(ADD_ENTRY)
-  inline_runtime_functions = true;
-  INLINE_FUNCTION_LIST(ADD_ENTRY)
-#undef ADD_ENTRY
-  DCHECK_EQ(index, entry_count);
-  Handle<JSArray> result = factory->NewJSArrayWithElements(elements);
-  return *result;
-}
-#endif
-
-
-RUNTIME_FUNCTION(Runtime_IS_VAR) {
-  UNREACHABLE();  // implemented as macro in the parser
-  return NULL;
-}
-
-
-#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)        \
-  RUNTIME_FUNCTION(Runtime_Has##Name) {          \
-    CONVERT_ARG_CHECKED(JSObject, obj, 0);                \
-    return isolate->heap()->ToBoolean(obj->Has##Name());  \
-  }
-
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
-// Properties test sitting with elements tests - not fooling anyone.
-ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
-
-#undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
-
-
-#define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size)     \
-  RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) {             \
-    CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
-    return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements());     \
-  }
-
-TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
-
-#undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
-
-
-#define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s)  \
-  RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) {                \
-    CONVERT_ARG_CHECKED(JSObject, obj, 0);                                     \
-    return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements());        \
-  }
-
-TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
-
-#undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
-
-
-RUNTIME_FUNCTION(Runtime_HaveSameMap) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(JSObject, obj1, 0);
-  CONVERT_ARG_CHECKED(JSObject, obj2, 1);
-  return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsObserved) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-
-  if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
-  CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
-  DCHECK(!obj->IsJSGlobalProxy() || !obj->map()->is_observed());
-  return isolate->heap()->ToBoolean(obj->map()->is_observed());
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetIsObserved) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
-  RUNTIME_ASSERT(!obj->IsJSGlobalProxy());
-  if (obj->IsJSProxy()) return isolate->heap()->undefined_value();
-  RUNTIME_ASSERT(!obj->map()->is_observed());
-
-  DCHECK(obj->IsJSObject());
-  JSObject::SetObserved(Handle<JSObject>::cast(obj));
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
-  isolate->EnqueueMicrotask(microtask);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  isolate->RunMicrotasks();
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetObservationState) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  return isolate->heap()->observation_state();
-}
-
-
-RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 0);
-  // TODO(adamk): Currently this runtime function is only called three times per
-  // isolate. If it's called more often, the map should be moved into the
-  // strong root list.
-  Handle<Map> map =
-      isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
-  Handle<JSWeakMap> weakmap =
-      Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
-  return *WeakCollectionInitialize(isolate, weakmap);
-}
-
-
-static bool ContextsHaveSameOrigin(Handle<Context> context1,
-                                   Handle<Context> context2) {
-  return context1->security_token() == context2->security_token();
-}
-
-
-RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2);
-
-  Handle<Context> observer_context(observer->context()->native_context());
-  Handle<Context> object_context(object->GetCreationContext());
-  Handle<Context> record_context(record->GetCreationContext());
-
-  return isolate->heap()->ToBoolean(
-      ContextsHaveSameOrigin(object_context, observer_context) &&
-      ContextsHaveSameOrigin(object_context, record_context));
-}
-
-
-RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-
-  Handle<Context> creation_context(object->GetCreationContext(), isolate);
-  return isolate->heap()->ToBoolean(
-      ContextsHaveSameOrigin(creation_context, isolate->native_context()));
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetObjectContextObjectObserve) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-
-  Handle<Context> context(object->GetCreationContext(), isolate);
-  return context->native_object_observe();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetObjectContextObjectGetNotifier) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-
-  Handle<Context> context(object->GetCreationContext(), isolate);
-  return context->native_object_get_notifier();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetObjectContextNotifierPerformChange) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0);
-
-  Handle<Context> context(object_info->GetCreationContext(), isolate);
-  return context->native_object_notifier_perform_change();
-}
-
-
-static Object* ArrayConstructorCommon(Isolate* isolate,
-                                           Handle<JSFunction> constructor,
-                                           Handle<AllocationSite> site,
-                                           Arguments* caller_args) {
-  Factory* factory = isolate->factory();
-
-  bool holey = false;
-  bool can_use_type_feedback = true;
-  if (caller_args->length() == 1) {
-    Handle<Object> argument_one = caller_args->at<Object>(0);
-    if (argument_one->IsSmi()) {
-      int value = Handle<Smi>::cast(argument_one)->value();
-      if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
-        // the array is a dictionary in this case.
-        can_use_type_feedback = false;
-      } else if (value != 0) {
-        holey = true;
-      }
-    } else {
-      // Non-smi length argument produces a dictionary
-      can_use_type_feedback = false;
-    }
-  }
-
-  Handle<JSArray> array;
-  if (!site.is_null() && can_use_type_feedback) {
-    ElementsKind to_kind = site->GetElementsKind();
-    if (holey && !IsFastHoleyElementsKind(to_kind)) {
-      to_kind = GetHoleyElementsKind(to_kind);
-      // Update the allocation site info to reflect the advice alteration.
-      site->SetElementsKind(to_kind);
-    }
-
-    // We should allocate with an initial map that reflects the allocation site
-    // advice. Therefore we use AllocateJSObjectFromMap instead of passing
-    // the constructor.
-    Handle<Map> initial_map(constructor->initial_map(), isolate);
-    if (to_kind != initial_map->elements_kind()) {
-      initial_map = Map::AsElementsKind(initial_map, to_kind);
-    }
-
-    // If we don't care to track arrays of to_kind ElementsKind, then
-    // don't emit a memento for them.
-    Handle<AllocationSite> allocation_site;
-    if (AllocationSite::GetMode(to_kind) == TRACK_ALLOCATION_SITE) {
-      allocation_site = site;
-    }
-
-    array = Handle<JSArray>::cast(factory->NewJSObjectFromMap(
-        initial_map, NOT_TENURED, true, allocation_site));
-  } else {
-    array = Handle<JSArray>::cast(factory->NewJSObject(constructor));
-
-    // We might need to transition to holey
-    ElementsKind kind = constructor->initial_map()->elements_kind();
-    if (holey && !IsFastHoleyElementsKind(kind)) {
-      kind = GetHoleyElementsKind(kind);
-      JSObject::TransitionElementsKind(array, kind);
-    }
-  }
-
-  factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS);
-
-  ElementsKind old_kind = array->GetElementsKind();
-  RETURN_FAILURE_ON_EXCEPTION(
-      isolate, ArrayConstructInitializeElements(array, caller_args));
-  if (!site.is_null() &&
-      (old_kind != array->GetElementsKind() ||
-       !can_use_type_feedback)) {
-    // The arguments passed in caused a transition. This kind of complexity
-    // can't be dealt with in the inlined hydrogen array constructor case.
-    // We must mark the allocationsite as un-inlinable.
-    site->SetDoNotInlineCall();
-  }
-  return *array;
-}
-
-
-RUNTIME_FUNCTION(Runtime_ArrayConstructor) {
-  HandleScope scope(isolate);
-  // If we get 2 arguments then they are the stub parameters (constructor, type
-  // info).  If we get 4, then the first one is a pointer to the arguments
-  // passed by the caller, and the last one is the length of the arguments
-  // passed to the caller (redundant, but useful to check on the deoptimizer
-  // with an assert).
-  Arguments empty_args(0, NULL);
-  bool no_caller_args = args.length() == 2;
-  DCHECK(no_caller_args || args.length() == 4);
-  int parameters_start = no_caller_args ? 0 : 1;
-  Arguments* caller_args = no_caller_args
-      ? &empty_args
-      : reinterpret_cast<Arguments*>(args[0]);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
-  CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
-#ifdef DEBUG
-  if (!no_caller_args) {
-    CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
-    DCHECK(arg_count == caller_args->length());
-  }
-#endif
-
-  Handle<AllocationSite> site;
-  if (!type_info.is_null() &&
-      *type_info != isolate->heap()->undefined_value()) {
-    site = Handle<AllocationSite>::cast(type_info);
-    DCHECK(!site->SitePointsToLiteral());
-  }
-
-  return ArrayConstructorCommon(isolate,
-                                constructor,
-                                site,
-                                caller_args);
-}
-
-
-RUNTIME_FUNCTION(Runtime_InternalArrayConstructor) {
-  HandleScope scope(isolate);
-  Arguments empty_args(0, NULL);
-  bool no_caller_args = args.length() == 1;
-  DCHECK(no_caller_args || args.length() == 3);
-  int parameters_start = no_caller_args ? 0 : 1;
-  Arguments* caller_args = no_caller_args
-      ? &empty_args
-      : reinterpret_cast<Arguments*>(args[0]);
-  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
-#ifdef DEBUG
-  if (!no_caller_args) {
-    CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
-    DCHECK(arg_count == caller_args->length());
-  }
-#endif
-  return ArrayConstructorCommon(isolate,
-                                constructor,
-                                Handle<AllocationSite>::null(),
-                                caller_args);
-}
-
-
-RUNTIME_FUNCTION(Runtime_NormalizeElements) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
-  RUNTIME_ASSERT(!array->HasExternalArrayElements() &&
-                 !array->HasFixedTypedArrayElements());
-  JSObject::NormalizeElements(array);
-  return *array;
-}
-
-
-RUNTIME_FUNCTION(Runtime_MaxSmi) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  return Smi::FromInt(Smi::kMaxValue);
-}
-
-
-// TODO(dcarney): remove this function when TurboFan supports it.
-// Takes the object to be iterated over and the result of GetPropertyNamesFast
-// Returns pair (cache_array, cache_type).
-RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInInit) {
-  SealHandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  // This simulates CONVERT_ARG_HANDLE_CHECKED for calls returning pairs.
-  // Not worth creating a macro atm as this function should be removed.
-  if (!args[0]->IsJSReceiver() || !args[1]->IsObject()) {
-    Object* error = isolate->ThrowIllegalOperation();
-    return MakePair(error, isolate->heap()->undefined_value());
-  }
-  Handle<JSReceiver> object = args.at<JSReceiver>(0);
-  Handle<Object> cache_type = args.at<Object>(1);
-  if (cache_type->IsMap()) {
-    // Enum cache case.
-    if (Map::EnumLengthBits::decode(Map::cast(*cache_type)->bit_field3()) ==
-        0) {
-      // 0 length enum.
-      // Can't handle this case in the graph builder,
-      // so transform it into the empty fixed array case.
-      return MakePair(isolate->heap()->empty_fixed_array(), Smi::FromInt(1));
-    }
-    return MakePair(object->map()->instance_descriptors()->GetEnumCache(),
-                    *cache_type);
-  } else {
-    // FixedArray case.
-    Smi* new_cache_type = Smi::FromInt(object->IsJSProxy() ? 0 : 1);
-    return MakePair(*Handle<FixedArray>::cast(cache_type), new_cache_type);
-  }
-}
-
-
-// TODO(dcarney): remove this function when TurboFan supports it.
-RUNTIME_FUNCTION(Runtime_ForInCacheArrayLength) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_HANDLE_CHECKED(Object, cache_type, 0);
-  CONVERT_ARG_HANDLE_CHECKED(FixedArray, array, 1);
-  int length = 0;
-  if (cache_type->IsMap()) {
-    length = Map::cast(*cache_type)->EnumLength();
-  } else {
-    DCHECK(cache_type->IsSmi());
-    length = array->length();
-  }
-  return Smi::FromInt(length);
-}
-
-
-// TODO(dcarney): remove this function when TurboFan supports it.
-// Takes (the object to be iterated over,
-//        cache_array from ForInInit,
-//        cache_type from ForInInit,
-//        the current index)
-// Returns pair (array[index], needs_filtering).
-RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInNext) {
-  SealHandleScope scope(isolate);
-  DCHECK(args.length() == 4);
-  int32_t index;
-  // This simulates CONVERT_ARG_HANDLE_CHECKED for calls returning pairs.
-  // Not worth creating a macro atm as this function should be removed.
-  if (!args[0]->IsJSReceiver() || !args[1]->IsFixedArray() ||
-      !args[2]->IsObject() || !args[3]->ToInt32(&index)) {
-    Object* error = isolate->ThrowIllegalOperation();
-    return MakePair(error, isolate->heap()->undefined_value());
-  }
-  Handle<JSReceiver> object = args.at<JSReceiver>(0);
-  Handle<FixedArray> array = args.at<FixedArray>(1);
-  Handle<Object> cache_type = args.at<Object>(2);
-  // Figure out first if a slow check is needed for this object.
-  bool slow_check_needed = false;
-  if (cache_type->IsMap()) {
-    if (object->map() != Map::cast(*cache_type)) {
-      // Object transitioned.  Need slow check.
-      slow_check_needed = true;
-    }
-  } else {
-    // No slow check needed for proxies.
-    slow_check_needed = Smi::cast(*cache_type)->value() == 1;
-  }
-  return MakePair(array->get(index),
-                  isolate->heap()->ToBoolean(slow_check_needed));
-}
-
-
-// ----------------------------------------------------------------------------
-// Reference implementation for inlined runtime functions.  Only used when the
-// compiler does not support a certain intrinsic.  Don't optimize these, but
-// implement the intrinsic in the respective compiler instead.
-
-// TODO(mstarzinger): These are place-holder stubs for TurboFan and will
-// eventually all have a C++ implementation and this macro will be gone.
-#define U(name)                               \
-  RUNTIME_FUNCTION(RuntimeReference_##name) { \
-    UNIMPLEMENTED();                          \
-    return NULL;                              \
-  }
-
-U(IsStringWrapperSafeForDefaultValueOf)
-U(DebugBreakInOptimizedCode)
-
-#undef U
-
-
-RUNTIME_FUNCTION(RuntimeReference_IsSmi) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  return isolate->heap()->ToBoolean(obj->IsSmi());
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_IsNonNegativeSmi) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  return isolate->heap()->ToBoolean(obj->IsSmi() &&
-                                    Smi::cast(obj)->value() >= 0);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_IsArray) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  return isolate->heap()->ToBoolean(obj->IsJSArray());
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_IsRegExp) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  return isolate->heap()->ToBoolean(obj->IsJSRegExp());
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_IsConstructCall) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  JavaScriptFrameIterator it(isolate);
-  JavaScriptFrame* frame = it.frame();
-  return isolate->heap()->ToBoolean(frame->IsConstructor());
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_CallFunction) {
-  SealHandleScope shs(isolate);
-  return __RT_impl_Runtime_Call(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_ArgumentsLength) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 0);
-  JavaScriptFrameIterator it(isolate);
-  JavaScriptFrame* frame = it.frame();
-  return Smi::FromInt(frame->GetArgumentsLength());
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_Arguments) {
-  SealHandleScope shs(isolate);
-  return __RT_impl_Runtime_GetArgumentsProperty(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_ValueOf) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  if (!obj->IsJSValue()) return obj;
-  return JSValue::cast(obj)->value();
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_SetValueOf) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  CONVERT_ARG_CHECKED(Object, value, 1);
-  if (!obj->IsJSValue()) return value;
-  JSValue::cast(obj)->set_value(value);
-  return value;
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_DateField) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  CONVERT_SMI_ARG_CHECKED(index, 1);
-  if (!obj->IsJSDate()) {
-    HandleScope scope(isolate);
-    THROW_NEW_ERROR_RETURN_FAILURE(
-        isolate,
-        NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
-  }
-  JSDate* date = JSDate::cast(obj);
-  if (index == 0) return date->value();
-  return JSDate::GetField(date, Smi::FromInt(index));
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_StringCharFromCode) {
-  SealHandleScope shs(isolate);
-  return __RT_impl_Runtime_CharFromCode(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_StringCharAt) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  if (!args[0]->IsString()) return Smi::FromInt(0);
-  if (!args[1]->IsNumber()) return Smi::FromInt(0);
-  if (std::isinf(args.number_at(1))) return isolate->heap()->empty_string();
-  Object* code = __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
-  if (code->IsNaN()) return isolate->heap()->empty_string();
-  return __RT_impl_Runtime_CharFromCode(Arguments(1, &code), isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_OneByteSeqStringSetChar) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_INT32_ARG_CHECKED(index, 0);
-  CONVERT_INT32_ARG_CHECKED(value, 1);
-  CONVERT_ARG_CHECKED(SeqOneByteString, string, 2);
-  string->SeqOneByteStringSet(index, value);
-  return string;
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_TwoByteSeqStringSetChar) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 3);
-  CONVERT_INT32_ARG_CHECKED(index, 0);
-  CONVERT_INT32_ARG_CHECKED(value, 1);
-  CONVERT_ARG_CHECKED(SeqTwoByteString, string, 2);
-  string->SeqTwoByteStringSet(index, value);
-  return string;
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_ObjectEquals) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_ARG_CHECKED(Object, obj1, 0);
-  CONVERT_ARG_CHECKED(Object, obj2, 1);
-  return isolate->heap()->ToBoolean(obj1 == obj2);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_IsObject) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  if (!obj->IsHeapObject()) return isolate->heap()->false_value();
-  if (obj->IsNull()) return isolate->heap()->true_value();
-  if (obj->IsUndetectableObject()) return isolate->heap()->false_value();
-  Map* map = HeapObject::cast(obj)->map();
-  bool is_non_callable_spec_object =
-      map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
-      map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE;
-  return isolate->heap()->ToBoolean(is_non_callable_spec_object);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_IsFunction) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  return isolate->heap()->ToBoolean(obj->IsJSFunction());
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_IsUndetectableObject) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  return isolate->heap()->ToBoolean(obj->IsUndetectableObject());
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  return isolate->heap()->ToBoolean(obj->IsSpecObject());
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_MathPow) {
-  SealHandleScope shs(isolate);
-  return __RT_impl_Runtime_MathPowSlow(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_IsMinusZero) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  if (!obj->IsHeapNumber()) return isolate->heap()->false_value();
-  HeapNumber* number = HeapNumber::cast(obj);
-  return isolate->heap()->ToBoolean(IsMinusZero(number->value()));
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_HasCachedArrayIndex) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  return isolate->heap()->false_value();
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_GetCachedArrayIndex) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_FastOneByteArrayJoin) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_GeneratorNext) {
-  UNREACHABLE();  // Optimization disabled in SetUpGenerators().
-  return NULL;
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_GeneratorThrow) {
-  UNREACHABLE();  // Optimization disabled in SetUpGenerators().
-  return NULL;
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_ClassOf) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 1);
-  CONVERT_ARG_CHECKED(Object, obj, 0);
-  if (!obj->IsJSReceiver()) return isolate->heap()->null_value();
-  return JSReceiver::cast(obj)->class_name();
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_StringCharCodeAt) {
-  SealHandleScope shs(isolate);
-  DCHECK(args.length() == 2);
-  if (!args[0]->IsString()) return isolate->heap()->undefined_value();
-  if (!args[1]->IsNumber()) return isolate->heap()->undefined_value();
-  if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value();
-  return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_StringAdd) {
-  SealHandleScope shs(isolate);
-  return __RT_impl_Runtime_StringAdd(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_SubString) {
-  SealHandleScope shs(isolate);
-  return __RT_impl_Runtime_SubString(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_StringCompare) {
-  SealHandleScope shs(isolate);
-  return __RT_impl_Runtime_StringCompare(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_RegExpExec) {
-  SealHandleScope shs(isolate);
-  return __RT_impl_Runtime_RegExpExecRT(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_RegExpConstructResult) {
-  SealHandleScope shs(isolate);
-  return __RT_impl_Runtime_RegExpConstructResult(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_GetFromCache) {
-  HandleScope scope(isolate);
-  DCHECK(args.length() == 2);
-  CONVERT_SMI_ARG_CHECKED(id, 0);
-  args[0] = isolate->native_context()->jsfunction_result_caches()->get(id);
-  return __RT_impl_Runtime_GetFromCache(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_NumberToString) {
-  SealHandleScope shs(isolate);
-  return __RT_impl_Runtime_NumberToStringRT(args, isolate);
-}
-
-
-RUNTIME_FUNCTION(RuntimeReference_DebugIsActive) {
-  SealHandleScope shs(isolate);
-  return Smi::FromInt(isolate->debug()->is_active());
-}
-
-
-// ----------------------------------------------------------------------------
-// Implementation of Runtime
-
-#define F(name, number_of_args, result_size)                                  \
-  {                                                                           \
-    Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \
-        number_of_args, result_size                                           \
-  }                                                                           \
-  ,
-
-
-#define I(name, number_of_args, result_size)                                \
-  {                                                                         \
-    Runtime::kInline##name, Runtime::INLINE, "_" #name,                     \
-        FUNCTION_ADDR(RuntimeReference_##name), number_of_args, result_size \
-  }                                                                         \
-  ,
-
-
-#define IO(name, number_of_args, result_size)                              \
-  {                                                                        \
-    Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, "_" #name, \
-        FUNCTION_ADDR(Runtime_##name), number_of_args, result_size         \
-  }                                                                        \
-  ,
-
-
-static const Runtime::Function kIntrinsicFunctions[] = {
-  RUNTIME_FUNCTION_LIST(F)
-  INLINE_OPTIMIZED_FUNCTION_LIST(F)
-  INLINE_FUNCTION_LIST(I)
-  INLINE_OPTIMIZED_FUNCTION_LIST(IO)
-};
-
-#undef IO
-#undef I
-#undef F
-
-
-void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
-                                               Handle<NameDictionary> dict) {
-  DCHECK(dict->NumberOfElements() == 0);
-  HandleScope scope(isolate);
-  for (int i = 0; i < kNumFunctions; ++i) {
-    const char* name = kIntrinsicFunctions[i].name;
-    if (name == NULL) continue;
-    Handle<NameDictionary> new_dict = NameDictionary::Add(
-        dict,
-        isolate->factory()->InternalizeUtf8String(name),
-        Handle<Smi>(Smi::FromInt(i), isolate),
-        PropertyDetails(NONE, NORMAL, Representation::None()));
-    // The dictionary does not need to grow.
-    CHECK(new_dict.is_identical_to(dict));
-  }
-}
-
-
-const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
-  Heap* heap = name->GetHeap();
-  int entry = heap->intrinsic_function_names()->FindEntry(name);
-  if (entry != kNotFound) {
-    Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
-    int function_index = Smi::cast(smi_index)->value();
-    return &(kIntrinsicFunctions[function_index]);
-  }
-  return NULL;
-}
-
-
-const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
-  for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
-    if (entry == kIntrinsicFunctions[i].entry) {
-      return &(kIntrinsicFunctions[i]);
-    }
-  }
-  return NULL;
-}
-
-
-const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
-  return &(kIntrinsicFunctions[static_cast<int>(id)]);
-}
-
-} }  // namespace v8::internal
diff --git a/src/runtime.h b/src/runtime.h
deleted file mode 100644
index e63cd90..0000000
--- a/src/runtime.h
+++ /dev/null
@@ -1,922 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_RUNTIME_H_
-#define V8_RUNTIME_H_
-
-#include "src/allocation.h"
-#include "src/zone.h"
-
-namespace v8 {
-namespace internal {
-
-// The interface to C++ runtime functions.
-
-// ----------------------------------------------------------------------------
-// RUNTIME_FUNCTION_LIST_ALWAYS defines runtime calls available in both
-// release and debug mode.
-// This macro should only be used by the macro RUNTIME_FUNCTION_LIST.
-
-// WARNING: RUNTIME_FUNCTION_LIST_ALWAYS_* is a very large macro that caused
-// MSVC Intellisense to crash.  It was broken into two macros to work around
-// this problem. Please avoid large recursive macros whenever possible.
-#define RUNTIME_FUNCTION_LIST_ALWAYS_1(F)                  \
-  /* Property access */                                    \
-  F(GetProperty, 2, 1)                                     \
-  F(KeyedGetProperty, 2, 1)                                \
-  F(DeleteProperty, 3, 1)                                  \
-  F(HasOwnProperty, 2, 1)                                  \
-  F(HasProperty, 2, 1)                                     \
-  F(HasElement, 2, 1)                                      \
-  F(IsPropertyEnumerable, 2, 1)                            \
-  F(GetPropertyNames, 1, 1)                                \
-  F(GetPropertyNamesFast, 1, 1)                            \
-  F(GetOwnPropertyNames, 2, 1)                             \
-  F(GetOwnElementNames, 1, 1)                              \
-  F(GetInterceptorInfo, 1, 1)                              \
-  F(GetNamedInterceptorPropertyNames, 1, 1)                \
-  F(GetIndexedInterceptorElementNames, 1, 1)               \
-  F(GetArgumentsProperty, 1, 1)                            \
-  F(ToFastProperties, 1, 1)                                \
-  F(FinishArrayPrototypeSetup, 1, 1)                       \
-  F(SpecialArrayFunctions, 0, 1)                           \
-  F(IsSloppyModeFunction, 1, 1)                            \
-  F(GetDefaultReceiver, 1, 1)                              \
-                                                           \
-  F(GetPrototype, 1, 1)                                    \
-  F(SetPrototype, 2, 1)                                    \
-  F(InternalSetPrototype, 2, 1)                            \
-  F(IsInPrototypeChain, 2, 1)                              \
-                                                           \
-  F(GetOwnProperty, 2, 1)                                  \
-                                                           \
-  F(IsExtensible, 1, 1)                                    \
-  F(PreventExtensions, 1, 1)                               \
-                                                           \
-  /* Utilities */                                          \
-  F(CheckIsBootstrapping, 0, 1)                            \
-  F(GetRootNaN, 0, 1)                                      \
-  F(Call, -1 /* >= 2 */, 1)                                \
-  F(Apply, 5, 1)                                           \
-  F(GetFunctionDelegate, 1, 1)                             \
-  F(GetConstructorDelegate, 1, 1)                          \
-  F(DeoptimizeFunction, 1, 1)                              \
-  F(ClearFunctionTypeFeedback, 1, 1)                       \
-  F(RunningInSimulator, 0, 1)                              \
-  F(IsConcurrentRecompilationSupported, 0, 1)              \
-  F(OptimizeFunctionOnNextCall, -1, 1)                     \
-  F(NeverOptimizeFunction, 1, 1)                           \
-  F(GetOptimizationStatus, -1, 1)                          \
-  F(GetOptimizationCount, 1, 1)                            \
-  F(UnblockConcurrentRecompilation, 0, 1)                  \
-  F(CompileForOnStackReplacement, 1, 1)                    \
-  F(SetAllocationTimeout, -1 /* 2 || 3 */, 1)              \
-  F(SetNativeFlag, 1, 1)                                   \
-  F(SetInlineBuiltinFlag, 1, 1)                            \
-  F(StoreArrayLiteralElement, 5, 1)                        \
-  F(DebugPrepareStepInIfStepping, 1, 1)                    \
-  F(DebugPushPromise, 1, 1)                                \
-  F(DebugPopPromise, 0, 1)                                 \
-  F(DebugPromiseEvent, 1, 1)                               \
-  F(DebugPromiseRejectEvent, 2, 1)                         \
-  F(DebugAsyncTaskEvent, 1, 1)                             \
-  F(FlattenString, 1, 1)                                   \
-  F(LoadMutableDouble, 2, 1)                               \
-  F(TryMigrateInstance, 1, 1)                              \
-  F(NotifyContextDisposed, 0, 1)                           \
-                                                           \
-  /* Array join support */                                 \
-  F(PushIfAbsent, 2, 1)                                    \
-  F(ArrayConcat, 1, 1)                                     \
-                                                           \
-  /* Conversions */                                        \
-  F(ToBool, 1, 1)                                          \
-  F(Typeof, 1, 1)                                          \
-                                                           \
-  F(Booleanize, 2, 1) /* TODO(turbofan): Only temporary */ \
-                                                           \
-  F(StringToNumber, 1, 1)                                  \
-  F(StringParseInt, 2, 1)                                  \
-  F(StringParseFloat, 1, 1)                                \
-  F(StringToLowerCase, 1, 1)                               \
-  F(StringToUpperCase, 1, 1)                               \
-  F(StringSplit, 3, 1)                                     \
-  F(CharFromCode, 1, 1)                                    \
-  F(URIEscape, 1, 1)                                       \
-  F(URIUnescape, 1, 1)                                     \
-                                                           \
-  F(NumberToInteger, 1, 1)                                 \
-  F(NumberToIntegerMapMinusZero, 1, 1)                     \
-  F(NumberToJSUint32, 1, 1)                                \
-  F(NumberToJSInt32, 1, 1)                                 \
-                                                           \
-  /* Arithmetic operations */                              \
-  F(NumberAdd, 2, 1)                                       \
-  F(NumberSub, 2, 1)                                       \
-  F(NumberMul, 2, 1)                                       \
-  F(NumberDiv, 2, 1)                                       \
-  F(NumberMod, 2, 1)                                       \
-  F(NumberUnaryMinus, 1, 1)                                \
-  F(NumberImul, 2, 1)                                      \
-                                                           \
-  F(StringBuilderConcat, 3, 1)                             \
-  F(StringBuilderJoin, 3, 1)                               \
-  F(SparseJoinWithSeparator, 3, 1)                         \
-                                                           \
-  /* Bit operations */                                     \
-  F(NumberOr, 2, 1)                                        \
-  F(NumberAnd, 2, 1)                                       \
-  F(NumberXor, 2, 1)                                       \
-                                                           \
-  F(NumberShl, 2, 1)                                       \
-  F(NumberShr, 2, 1)                                       \
-  F(NumberSar, 2, 1)                                       \
-                                                           \
-  /* Comparisons */                                        \
-  F(NumberEquals, 2, 1)                                    \
-  F(StringEquals, 2, 1)                                    \
-                                                           \
-  F(NumberCompare, 3, 1)                                   \
-  F(SmiLexicographicCompare, 2, 1)                         \
-                                                           \
-  /* Math */                                               \
-  F(MathAcos, 1, 1)                                        \
-  F(MathAsin, 1, 1)                                        \
-  F(MathAtan, 1, 1)                                        \
-  F(MathFloorRT, 1, 1)                                     \
-  F(MathAtan2, 2, 1)                                       \
-  F(MathExpRT, 1, 1)                                       \
-  F(RoundNumber, 1, 1)                                     \
-  F(MathFround, 1, 1)                                      \
-  F(RemPiO2, 1, 1)                                         \
-                                                           \
-  /* Regular expressions */                                \
-  F(RegExpCompile, 3, 1)                                   \
-  F(RegExpExecMultiple, 4, 1)                              \
-  F(RegExpInitializeObject, 6, 1)                          \
-                                                           \
-  /* JSON */                                               \
-  F(ParseJson, 1, 1)                                       \
-  F(BasicJSONStringify, 1, 1)                              \
-  F(QuoteJSONString, 1, 1)                                 \
-                                                           \
-  /* Strings */                                            \
-  F(StringIndexOf, 3, 1)                                   \
-  F(StringLastIndexOf, 3, 1)                               \
-  F(StringLocaleCompare, 2, 1)                             \
-  F(StringReplaceGlobalRegExpWithString, 4, 1)             \
-  F(StringReplaceOneCharWithString, 3, 1)                  \
-  F(StringMatch, 3, 1)                                     \
-  F(StringTrim, 3, 1)                                      \
-  F(StringToArray, 2, 1)                                   \
-  F(NewStringWrapper, 1, 1)                                \
-  F(NewString, 2, 1)                                       \
-  F(TruncateString, 2, 1)                                  \
-                                                           \
-  /* Numbers */                                            \
-  F(NumberToRadixString, 2, 1)                             \
-  F(NumberToFixed, 2, 1)                                   \
-  F(NumberToExponential, 2, 1)                             \
-  F(NumberToPrecision, 2, 1)                               \
-  F(IsValidSmi, 1, 1)                                      \
-                                                           \
-  /* Classes support */                                    \
-  F(ToMethod, 2, 1)                                        \
-  F(HomeObjectSymbol, 0, 1)                                \
-  F(ThrowNonMethodError, 0, 1)                             \
-  F(ThrowUnsupportedSuperError, 0, 1)                      \
-  F(LoadFromSuper, 3, 1)
-
-
-#define RUNTIME_FUNCTION_LIST_ALWAYS_2(F)                             \
-  /* Reflection */                                                    \
-  F(FunctionSetInstanceClassName, 2, 1)                               \
-  F(FunctionSetLength, 2, 1)                                          \
-  F(FunctionSetPrototype, 2, 1)                                       \
-  F(FunctionGetName, 1, 1)                                            \
-  F(FunctionSetName, 2, 1)                                            \
-  F(FunctionNameShouldPrintAsAnonymous, 1, 1)                         \
-  F(FunctionMarkNameShouldPrintAsAnonymous, 1, 1)                     \
-  F(FunctionIsGenerator, 1, 1)                                        \
-  F(FunctionIsArrow, 1, 1)                                            \
-  F(FunctionIsConciseMethod, 1, 1)                                    \
-  F(FunctionBindArguments, 4, 1)                                      \
-  F(BoundFunctionGetBindings, 1, 1)                                   \
-  F(FunctionRemovePrototype, 1, 1)                                    \
-  F(FunctionGetSourceCode, 1, 1)                                      \
-  F(FunctionGetScript, 1, 1)                                          \
-  F(FunctionGetScriptSourcePosition, 1, 1)                            \
-  F(FunctionGetPositionForOffset, 2, 1)                               \
-  F(FunctionIsAPIFunction, 1, 1)                                      \
-  F(FunctionIsBuiltin, 1, 1)                                          \
-  F(GetScript, 1, 1)                                                  \
-  F(CollectStackTrace, 2, 1)                                          \
-  F(GetV8Version, 0, 1)                                               \
-  F(GeneratorGetFunction, 1, 1)                                       \
-  F(GeneratorGetContext, 1, 1)                                        \
-  F(GeneratorGetReceiver, 1, 1)                                       \
-  F(GeneratorGetContinuation, 1, 1)                                   \
-  F(GeneratorGetSourcePosition, 1, 1)                                 \
-                                                                      \
-  F(SetCode, 2, 1)                                                    \
-                                                                      \
-  F(CreateApiFunction, 2, 1)                                          \
-  F(IsTemplate, 1, 1)                                                 \
-  F(GetTemplateField, 2, 1)                                           \
-  F(DisableAccessChecks, 1, 1)                                        \
-  F(EnableAccessChecks, 1, 1)                                         \
-                                                                      \
-  /* Dates */                                                         \
-  F(DateCurrentTime, 0, 1)                                            \
-  F(DateParseString, 2, 1)                                            \
-  F(DateLocalTimezone, 1, 1)                                          \
-  F(DateToUTC, 1, 1)                                                  \
-  F(DateMakeDay, 2, 1)                                                \
-  F(DateSetValue, 3, 1)                                               \
-  F(DateCacheVersion, 0, 1)                                           \
-                                                                      \
-  /* Globals */                                                       \
-  F(CompileString, 2, 1)                                              \
-                                                                      \
-  /* Eval */                                                          \
-  F(GlobalProxy, 1, 1)                                                \
-  F(IsAttachedGlobal, 1, 1)                                           \
-                                                                      \
-  F(AddNamedProperty, 4, 1)                                           \
-  F(AddPropertyForTemplate, 4, 1)                                     \
-  F(SetProperty, 4, 1)                                                \
-  F(AddElement, 4, 1)                                                 \
-  F(DefineApiAccessorProperty, 5, 1)                                  \
-  F(DefineDataPropertyUnchecked, 4, 1)                                \
-  F(DefineAccessorPropertyUnchecked, 5, 1)                            \
-  F(GetDataProperty, 2, 1)                                            \
-  F(SetHiddenProperty, 3, 1)                                          \
-                                                                      \
-  /* Arrays */                                                        \
-  F(RemoveArrayHoles, 2, 1)                                           \
-  F(GetArrayKeys, 2, 1)                                               \
-  F(MoveArrayContents, 2, 1)                                          \
-  F(EstimateNumberOfElements, 1, 1)                                   \
-  F(NormalizeElements, 1, 1)                                          \
-                                                                      \
-  /* Getters and Setters */                                           \
-  F(LookupAccessor, 3, 1)                                             \
-                                                                      \
-  /* ES5 */                                                           \
-  F(ObjectFreeze, 1, 1)                                               \
-                                                                      \
-  /* Harmony modules */                                               \
-  F(IsJSModule, 1, 1)                                                 \
-                                                                      \
-  /* Harmony symbols */                                               \
-  F(CreateSymbol, 1, 1)                                               \
-  F(CreatePrivateSymbol, 1, 1)                                        \
-  F(CreateGlobalPrivateOwnSymbol, 1, 1)                               \
-  F(CreatePrivateOwnSymbol, 1, 1)                                     \
-  F(NewSymbolWrapper, 1, 1)                                           \
-  F(SymbolDescription, 1, 1)                                          \
-  F(SymbolRegistry, 0, 1)                                             \
-  F(SymbolIsPrivate, 1, 1)                                            \
-                                                                      \
-  /* Harmony proxies */                                               \
-  F(CreateJSProxy, 2, 1)                                              \
-  F(CreateJSFunctionProxy, 4, 1)                                      \
-  F(IsJSProxy, 1, 1)                                                  \
-  F(IsJSFunctionProxy, 1, 1)                                          \
-  F(GetHandler, 1, 1)                                                 \
-  F(GetCallTrap, 1, 1)                                                \
-  F(GetConstructTrap, 1, 1)                                           \
-  F(Fix, 1, 1)                                                        \
-                                                                      \
-  /* Harmony sets */                                                  \
-  F(SetInitialize, 1, 1)                                              \
-  F(SetAdd, 2, 1)                                                     \
-  F(SetHas, 2, 1)                                                     \
-  F(SetDelete, 2, 1)                                                  \
-  F(SetClear, 1, 1)                                                   \
-  F(SetGetSize, 1, 1)                                                 \
-                                                                      \
-  F(SetIteratorInitialize, 3, 1)                                      \
-  F(SetIteratorNext, 2, 1)                                            \
-                                                                      \
-  /* Harmony maps */                                                  \
-  F(MapInitialize, 1, 1)                                              \
-  F(MapGet, 2, 1)                                                     \
-  F(MapHas, 2, 1)                                                     \
-  F(MapDelete, 2, 1)                                                  \
-  F(MapClear, 1, 1)                                                   \
-  F(MapSet, 3, 1)                                                     \
-  F(MapGetSize, 1, 1)                                                 \
-                                                                      \
-  F(MapIteratorInitialize, 3, 1)                                      \
-  F(MapIteratorNext, 2, 1)                                            \
-                                                                      \
-  /* Harmony weak maps and sets */                                    \
-  F(WeakCollectionInitialize, 1, 1)                                   \
-  F(WeakCollectionGet, 2, 1)                                          \
-  F(WeakCollectionHas, 2, 1)                                          \
-  F(WeakCollectionDelete, 2, 1)                                       \
-  F(WeakCollectionSet, 3, 1)                                          \
-                                                                      \
-  F(GetWeakMapEntries, 1, 1)                                          \
-  F(GetWeakSetValues, 1, 1)                                           \
-                                                                      \
-  /* Harmony events */                                                \
-  F(EnqueueMicrotask, 1, 1)                                           \
-  F(RunMicrotasks, 0, 1)                                              \
-                                                                      \
-  /* Harmony observe */                                               \
-  F(IsObserved, 1, 1)                                                 \
-  F(SetIsObserved, 1, 1)                                              \
-  F(GetObservationState, 0, 1)                                        \
-  F(ObservationWeakMapCreate, 0, 1)                                   \
-  F(ObserverObjectAndRecordHaveSameOrigin, 3, 1)                      \
-  F(ObjectWasCreatedInCurrentOrigin, 1, 1)                            \
-  F(GetObjectContextObjectObserve, 1, 1)                              \
-  F(GetObjectContextObjectGetNotifier, 1, 1)                          \
-  F(GetObjectContextNotifierPerformChange, 1, 1)                      \
-                                                                      \
-  /* Harmony typed arrays */                                          \
-  F(ArrayBufferInitialize, 2, 1)                                      \
-  F(ArrayBufferSliceImpl, 3, 1)                                       \
-  F(ArrayBufferIsView, 1, 1)                                          \
-  F(ArrayBufferNeuter, 1, 1)                                          \
-                                                                      \
-  F(TypedArrayInitializeFromArrayLike, 4, 1)                          \
-  F(TypedArrayGetBuffer, 1, 1)                                        \
-  F(TypedArraySetFastCases, 3, 1)                                     \
-                                                                      \
-  F(DataViewGetBuffer, 1, 1)                                          \
-  F(DataViewGetInt8, 3, 1)                                            \
-  F(DataViewGetUint8, 3, 1)                                           \
-  F(DataViewGetInt16, 3, 1)                                           \
-  F(DataViewGetUint16, 3, 1)                                          \
-  F(DataViewGetInt32, 3, 1)                                           \
-  F(DataViewGetUint32, 3, 1)                                          \
-  F(DataViewGetFloat32, 3, 1)                                         \
-  F(DataViewGetFloat64, 3, 1)                                         \
-                                                                      \
-  F(DataViewSetInt8, 4, 1)                                            \
-  F(DataViewSetUint8, 4, 1)                                           \
-  F(DataViewSetInt16, 4, 1)                                           \
-  F(DataViewSetUint16, 4, 1)                                          \
-  F(DataViewSetInt32, 4, 1)                                           \
-  F(DataViewSetUint32, 4, 1)                                          \
-  F(DataViewSetFloat32, 4, 1)                                         \
-  F(DataViewSetFloat64, 4, 1)                                         \
-                                                                      \
-  /* Statements */                                                    \
-  F(NewObjectFromBound, 1, 1)                                         \
-                                                                      \
-  /* Declarations and initialization */                               \
-  F(InitializeVarGlobal, 3, 1)                                        \
-  F(OptimizeObjectForAddingMultipleProperties, 2, 1)                  \
-                                                                      \
-  /* Debugging */                                                     \
-  F(DebugPrint, 1, 1)                                                 \
-  F(GlobalPrint, 1, 1)                                                \
-  F(DebugTrace, 0, 1)                                                 \
-  F(TraceEnter, 0, 1)                                                 \
-  F(TraceExit, 1, 1)                                                  \
-  F(Abort, 1, 1)                                                      \
-  F(AbortJS, 1, 1)                                                    \
-  /* ES5 */                                                           \
-  F(OwnKeys, 1, 1)                                                    \
-                                                                      \
-  /* Message objects */                                               \
-  F(MessageGetStartPosition, 1, 1)                                    \
-  F(MessageGetScript, 1, 1)                                           \
-                                                                      \
-  /* Pseudo functions - handled as macros by parser */                \
-  F(IS_VAR, 1, 1)                                                     \
-                                                                      \
-  /* expose boolean functions from objects-inl.h */                   \
-  F(HasFastSmiElements, 1, 1)                                         \
-  F(HasFastSmiOrObjectElements, 1, 1)                                 \
-  F(HasFastObjectElements, 1, 1)                                      \
-  F(HasFastDoubleElements, 1, 1)                                      \
-  F(HasFastHoleyElements, 1, 1)                                       \
-  F(HasDictionaryElements, 1, 1)                                      \
-  F(HasSloppyArgumentsElements, 1, 1)                                 \
-  F(HasExternalUint8ClampedElements, 1, 1)                            \
-  F(HasExternalArrayElements, 1, 1)                                   \
-  F(HasExternalInt8Elements, 1, 1)                                    \
-  F(HasExternalUint8Elements, 1, 1)                                   \
-  F(HasExternalInt16Elements, 1, 1)                                   \
-  F(HasExternalUint16Elements, 1, 1)                                  \
-  F(HasExternalInt32Elements, 1, 1)                                   \
-  F(HasExternalUint32Elements, 1, 1)                                  \
-  F(HasExternalFloat32Elements, 1, 1)                                 \
-  F(HasExternalFloat64Elements, 1, 1)                                 \
-  F(HasFixedUint8ClampedElements, 1, 1)                               \
-  F(HasFixedInt8Elements, 1, 1)                                       \
-  F(HasFixedUint8Elements, 1, 1)                                      \
-  F(HasFixedInt16Elements, 1, 1)                                      \
-  F(HasFixedUint16Elements, 1, 1)                                     \
-  F(HasFixedInt32Elements, 1, 1)                                      \
-  F(HasFixedUint32Elements, 1, 1)                                     \
-  F(HasFixedFloat32Elements, 1, 1)                                    \
-  F(HasFixedFloat64Elements, 1, 1)                                    \
-  F(HasFastProperties, 1, 1)                                          \
-  F(TransitionElementsKind, 2, 1)                                     \
-  F(HaveSameMap, 2, 1)                                                \
-  F(IsJSGlobalProxy, 1, 1)                                            \
-  F(ForInInit, 2, 2)             /* TODO(turbofan): Only temporary */ \
-  F(ForInNext, 4, 2)             /* TODO(turbofan): Only temporary */ \
-  F(ForInCacheArrayLength, 2, 1) /* TODO(turbofan): Only temporary */
-
-
-#define RUNTIME_FUNCTION_LIST_ALWAYS_3(F)                    \
-  /* String and Regexp */                                    \
-  F(NumberToStringRT, 1, 1)                                  \
-  F(RegExpConstructResult, 3, 1)                             \
-  F(RegExpExecRT, 4, 1)                                      \
-  F(StringAdd, 2, 1)                                         \
-  F(SubString, 3, 1)                                         \
-  F(InternalizeString, 1, 1)                                 \
-  F(StringCompare, 2, 1)                                     \
-  F(StringCharCodeAtRT, 2, 1)                                \
-  F(GetFromCache, 2, 1)                                      \
-                                                             \
-  /* Compilation */                                          \
-  F(CompileLazy, 1, 1)                                       \
-  F(CompileOptimized, 2, 1)                                  \
-  F(TryInstallOptimizedCode, 1, 1)                           \
-  F(NotifyDeoptimized, 1, 1)                                 \
-  F(NotifyStubFailure, 0, 1)                                 \
-                                                             \
-  /* Utilities */                                            \
-  F(AllocateInNewSpace, 1, 1)                                \
-  F(AllocateInTargetSpace, 2, 1)                             \
-  F(AllocateHeapNumber, 0, 1)                                \
-  F(NumberToSmi, 1, 1)                                       \
-  F(NumberToStringSkipCache, 1, 1)                           \
-                                                             \
-  F(NewArguments, 1, 1) /* TODO(turbofan): Only temporary */ \
-  F(NewSloppyArguments, 3, 1)                                \
-  F(NewStrictArguments, 3, 1)                                \
-                                                             \
-  /* Harmony generators */                                   \
-  F(CreateJSGeneratorObject, 0, 1)                           \
-  F(SuspendJSGeneratorObject, 1, 1)                          \
-  F(ResumeJSGeneratorObject, 3, 1)                           \
-  F(ThrowGeneratorStateError, 1, 1)                          \
-                                                             \
-  /* Arrays */                                               \
-  F(ArrayConstructor, -1, 1)                                 \
-  F(InternalArrayConstructor, -1, 1)                         \
-                                                             \
-  /* Literals */                                             \
-  F(MaterializeRegExpLiteral, 4, 1)                          \
-  F(CreateObjectLiteral, 4, 1)                               \
-  F(CreateArrayLiteral, 4, 1)                                \
-  F(CreateArrayLiteralStubBailout, 3, 1)                     \
-                                                             \
-  /* Statements */                                           \
-  F(NewClosure, 3, 1)                                        \
-  F(NewClosureFromStubFailure, 1, 1)                         \
-  F(NewObject, 1, 1)                                         \
-  F(NewObjectWithAllocationSite, 2, 1)                       \
-  F(FinalizeInstanceSize, 1, 1)                              \
-  F(Throw, 1, 1)                                             \
-  F(ReThrow, 1, 1)                                           \
-  F(ThrowReferenceError, 1, 1)                               \
-  F(ThrowNotDateError, 0, 1)                                 \
-  F(StackGuard, 0, 1)                                        \
-  F(Interrupt, 0, 1)                                         \
-  F(PromoteScheduledException, 0, 1)                         \
-                                                             \
-  /* Contexts */                                             \
-  F(NewGlobalContext, 2, 1)                                  \
-  F(NewFunctionContext, 1, 1)                                \
-  F(PushWithContext, 2, 1)                                   \
-  F(PushCatchContext, 3, 1)                                  \
-  F(PushBlockContext, 2, 1)                                  \
-  F(PushModuleContext, 2, 1)                                 \
-  F(DeleteLookupSlot, 2, 1)                                  \
-  F(LoadLookupSlot, 2, 2)                                    \
-  F(LoadLookupSlotNoReferenceError, 2, 2)                    \
-  F(StoreLookupSlot, 4, 1)                                   \
-                                                             \
-  /* Declarations and initialization */                      \
-  F(DeclareGlobals, 3, 1)                                    \
-  F(DeclareModules, 1, 1)                                    \
-  F(DeclareLookupSlot, 4, 1)                                 \
-  F(InitializeConstGlobal, 2, 1)                             \
-  F(InitializeLegacyConstLookupSlot, 3, 1)                   \
-                                                             \
-  /* Eval */                                                 \
-  F(ResolvePossiblyDirectEval, 6, 2)                         \
-                                                             \
-  /* Maths */                                                \
-  F(MathPowSlow, 2, 1)                                       \
-  F(MathPowRT, 2, 1)
-
-
-#define RUNTIME_FUNCTION_LIST_DEBUGGER(F) \
-  /* Debugger support*/ \
-  F(DebugBreak, 0, 1) \
-  F(SetDebugEventListener, 2, 1) \
-  F(Break, 0, 1) \
-  F(DebugGetPropertyDetails, 2, 1) \
-  F(DebugGetProperty, 2, 1) \
-  F(DebugPropertyTypeFromDetails, 1, 1) \
-  F(DebugPropertyAttributesFromDetails, 1, 1) \
-  F(DebugPropertyIndexFromDetails, 1, 1) \
-  F(DebugNamedInterceptorPropertyValue, 2, 1) \
-  F(DebugIndexedInterceptorElementValue, 2, 1) \
-  F(CheckExecutionState, 1, 1) \
-  F(GetFrameCount, 1, 1) \
-  F(GetFrameDetails, 2, 1) \
-  F(GetScopeCount, 2, 1) \
-  F(GetStepInPositions, 2, 1) \
-  F(GetScopeDetails, 4, 1) \
-  F(GetAllScopesDetails, 4, 1) \
-  F(GetFunctionScopeCount, 1, 1) \
-  F(GetFunctionScopeDetails, 2, 1) \
-  F(SetScopeVariableValue, 6, 1) \
-  F(DebugPrintScopes, 0, 1) \
-  F(GetThreadCount, 1, 1) \
-  F(GetThreadDetails, 2, 1) \
-  F(SetDisableBreak, 1, 1) \
-  F(GetBreakLocations, 2, 1) \
-  F(SetFunctionBreakPoint, 3, 1) \
-  F(SetScriptBreakPoint, 4, 1) \
-  F(ClearBreakPoint, 1, 1) \
-  F(ChangeBreakOnException, 2, 1) \
-  F(IsBreakOnException, 1, 1) \
-  F(PrepareStep, 4, 1) \
-  F(ClearStepping, 0, 1) \
-  F(DebugEvaluate, 6, 1) \
-  F(DebugEvaluateGlobal, 4, 1) \
-  F(DebugGetLoadedScripts, 0, 1) \
-  F(DebugReferencedBy, 3, 1) \
-  F(DebugConstructedBy, 2, 1) \
-  F(DebugGetPrototype, 1, 1) \
-  F(DebugSetScriptSource, 2, 1) \
-  F(DebugCallbackSupportsStepping, 1, 1) \
-  F(SystemBreak, 0, 1) \
-  F(DebugDisassembleFunction, 1, 1) \
-  F(DebugDisassembleConstructor, 1, 1) \
-  F(FunctionGetInferredName, 1, 1) \
-  F(LiveEditFindSharedFunctionInfosForScript, 1, 1) \
-  F(LiveEditGatherCompileInfo, 2, 1) \
-  F(LiveEditReplaceScript, 3, 1) \
-  F(LiveEditReplaceFunctionCode, 2, 1) \
-  F(LiveEditFunctionSourceUpdated, 1, 1) \
-  F(LiveEditFunctionSetScript, 2, 1) \
-  F(LiveEditReplaceRefToNestedFunction, 3, 1) \
-  F(LiveEditPatchFunctionPositions, 2, 1) \
-  F(LiveEditCheckAndDropActivations, 2, 1) \
-  F(LiveEditCompareStrings, 2, 1) \
-  F(LiveEditRestartFrame, 2, 1) \
-  F(GetFunctionCodePositionFromSource, 2, 1) \
-  F(ExecuteInDebugContext, 2, 1) \
-  \
-  F(SetFlags, 1, 1) \
-  F(CollectGarbage, 1, 1) \
-  F(GetHeapUsage, 0, 1) \
-
-
-#ifdef V8_I18N_SUPPORT
-#define RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F) \
-  /* i18n support */ \
-  /* Standalone, helper methods. */ \
-  F(CanonicalizeLanguageTag, 1, 1) \
-  F(AvailableLocalesOf, 1, 1) \
-  F(GetDefaultICULocale, 0, 1) \
-  F(GetLanguageTagVariants, 1, 1) \
-  F(IsInitializedIntlObject, 1, 1) \
-  F(IsInitializedIntlObjectOfType, 2, 1) \
-  F(MarkAsInitializedIntlObjectOfType, 3, 1) \
-  F(GetImplFromInitializedIntlObject, 1, 1) \
-  \
-  /* Date format and parse. */ \
-  F(CreateDateTimeFormat, 3, 1) \
-  F(InternalDateFormat, 2, 1) \
-  F(InternalDateParse, 2, 1) \
-  \
-  /* Number format and parse. */ \
-  F(CreateNumberFormat, 3, 1) \
-  F(InternalNumberFormat, 2, 1) \
-  F(InternalNumberParse, 2, 1) \
-  \
-  /* Collator. */ \
-  F(CreateCollator, 3, 1) \
-  F(InternalCompare, 3, 1) \
-  \
-  /* String.prototype.normalize. */ \
-  F(StringNormalize, 2, 1) \
-  \
-  /* Break iterator. */ \
-  F(CreateBreakIterator, 3, 1) \
-  F(BreakIteratorAdoptText, 2, 1) \
-  F(BreakIteratorFirst, 1, 1) \
-  F(BreakIteratorNext, 1, 1) \
-  F(BreakIteratorCurrent, 1, 1) \
-  F(BreakIteratorBreakType, 1, 1) \
-
-#else
-#define RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F)
-#endif
-
-
-#ifdef DEBUG
-#define RUNTIME_FUNCTION_LIST_DEBUG(F) \
-  /* Testing */ \
-  F(ListNatives, 0, 1)
-#else
-#define RUNTIME_FUNCTION_LIST_DEBUG(F)
-#endif
-
-// ----------------------------------------------------------------------------
-// RUNTIME_FUNCTION_LIST defines all runtime functions accessed
-// either directly by id (via the code generator), or indirectly
-// via a native call by name (from within JS code).
-// Entries have the form F(name, number of arguments, number of return values).
-
-#define RUNTIME_FUNCTION_LIST(F) \
-  RUNTIME_FUNCTION_LIST_ALWAYS_1(F) \
-  RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
-  RUNTIME_FUNCTION_LIST_ALWAYS_3(F) \
-  RUNTIME_FUNCTION_LIST_DEBUG(F) \
-  RUNTIME_FUNCTION_LIST_DEBUGGER(F) \
-  RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F)
-
-// ----------------------------------------------------------------------------
-// INLINE_FUNCTION_LIST defines all inlined functions accessed
-// with a native call of the form %_name from within JS code.
-// Entries have the form F(name, number of arguments, number of return values).
-#define INLINE_FUNCTION_LIST(F)                             \
-  F(IsSmi, 1, 1)                                            \
-  F(IsNonNegativeSmi, 1, 1)                                 \
-  F(IsArray, 1, 1)                                          \
-  F(IsRegExp, 1, 1)                                         \
-  F(IsConstructCall, 0, 1)                                  \
-  F(CallFunction, -1 /* receiver + n args + function */, 1) \
-  F(ArgumentsLength, 0, 1)                                  \
-  F(Arguments, 1, 1)                                        \
-  F(ValueOf, 1, 1)                                          \
-  F(SetValueOf, 2, 1)                                       \
-  F(DateField, 2 /* date object, field index */, 1)         \
-  F(StringCharFromCode, 1, 1)                               \
-  F(StringCharAt, 2, 1)                                     \
-  F(OneByteSeqStringSetChar, 3, 1)                          \
-  F(TwoByteSeqStringSetChar, 3, 1)                          \
-  F(ObjectEquals, 2, 1)                                     \
-  F(IsObject, 1, 1)                                         \
-  F(IsFunction, 1, 1)                                       \
-  F(IsUndetectableObject, 1, 1)                             \
-  F(IsSpecObject, 1, 1)                                     \
-  F(IsStringWrapperSafeForDefaultValueOf, 1, 1)             \
-  F(MathPow, 2, 1)                                          \
-  F(IsMinusZero, 1, 1)                                      \
-  F(HasCachedArrayIndex, 1, 1)                              \
-  F(GetCachedArrayIndex, 1, 1)                              \
-  F(FastOneByteArrayJoin, 2, 1)                             \
-  F(GeneratorNext, 2, 1)                                    \
-  F(GeneratorThrow, 2, 1)                                   \
-  F(DebugBreakInOptimizedCode, 0, 1)                        \
-  F(ClassOf, 1, 1)                                          \
-  F(StringCharCodeAt, 2, 1)                                 \
-  F(StringAdd, 2, 1)                                        \
-  F(SubString, 3, 1)                                        \
-  F(StringCompare, 2, 1)                                    \
-  F(RegExpExec, 4, 1)                                       \
-  F(RegExpConstructResult, 3, 1)                            \
-  F(GetFromCache, 2, 1)                                     \
-  F(NumberToString, 1, 1)                                   \
-  F(DebugIsActive, 0, 1)
-
-
-// ----------------------------------------------------------------------------
-// INLINE_OPTIMIZED_FUNCTION_LIST defines all inlined functions accessed
-// with a native call of the form %_name from within JS code that also have
-// a corresponding runtime function, that is called from non-optimized code.
-// For the benefit of (fuzz) tests, the runtime version can also be called
-// directly as %name (i.e. without the leading underscore).
-// Entries have the form F(name, number of arguments, number of return values).
-#define INLINE_OPTIMIZED_FUNCTION_LIST(F) \
-  /* Typed Arrays */                                                         \
-  F(TypedArrayInitialize, 5, 1)                                              \
-  F(DataViewInitialize, 4, 1)                                                \
-  F(MaxSmi, 0, 1)                                                            \
-  F(TypedArrayMaxSizeInHeap, 0, 1)                                           \
-  F(ArrayBufferViewGetByteLength, 1, 1)                                      \
-  F(ArrayBufferViewGetByteOffset, 1, 1)                                      \
-  F(TypedArrayGetLength, 1, 1)                                               \
-  /* ArrayBuffer */                                                          \
-  F(ArrayBufferGetByteLength, 1, 1)                                          \
-  /* Maths */                                                                \
-  F(ConstructDouble, 2, 1)                                                   \
-  F(DoubleHi, 1, 1)                                                          \
-  F(DoubleLo, 1, 1)                                                          \
-  F(MathSqrtRT, 1, 1)                                                        \
-  F(MathLogRT, 1, 1)
-
-
-//---------------------------------------------------------------------------
-// Runtime provides access to all C++ runtime functions.
-
-class RuntimeState {
- public:
-  StaticResource<ConsStringIteratorOp>* string_iterator() {
-    return &string_iterator_;
-  }
-  unibrow::Mapping<unibrow::ToUppercase, 128>* to_upper_mapping() {
-    return &to_upper_mapping_;
-  }
-  unibrow::Mapping<unibrow::ToLowercase, 128>* to_lower_mapping() {
-    return &to_lower_mapping_;
-  }
-  ConsStringIteratorOp* string_iterator_compare_x() {
-    return &string_iterator_compare_x_;
-  }
-  ConsStringIteratorOp* string_iterator_compare_y() {
-    return &string_iterator_compare_y_;
-  }
-  ConsStringIteratorOp* string_locale_compare_it1() {
-    return &string_locale_compare_it1_;
-  }
-  ConsStringIteratorOp* string_locale_compare_it2() {
-    return &string_locale_compare_it2_;
-  }
-
- private:
-  RuntimeState() {}
-  // Non-reentrant string buffer for efficient general use in the runtime.
-  StaticResource<ConsStringIteratorOp> string_iterator_;
-  unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping_;
-  unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping_;
-  ConsStringIteratorOp string_iterator_compare_x_;
-  ConsStringIteratorOp string_iterator_compare_y_;
-  ConsStringIteratorOp string_locale_compare_it1_;
-  ConsStringIteratorOp string_locale_compare_it2_;
-
-  friend class Isolate;
-  friend class Runtime;
-
-  DISALLOW_COPY_AND_ASSIGN(RuntimeState);
-};
-
-
-class Runtime : public AllStatic {
- public:
-  enum FunctionId {
-#define F(name, nargs, ressize) k##name,
-    RUNTIME_FUNCTION_LIST(F)
-    INLINE_OPTIMIZED_FUNCTION_LIST(F)
-#undef F
-#define F(name, nargs, ressize) kInline##name,
-    INLINE_FUNCTION_LIST(F)
-#undef F
-#define F(name, nargs, ressize) kInlineOptimized##name,
-    INLINE_OPTIMIZED_FUNCTION_LIST(F)
-#undef F
-    kNumFunctions,
-    kFirstInlineFunction = kInlineIsSmi
-  };
-
-  enum IntrinsicType {
-    RUNTIME,
-    INLINE,
-    INLINE_OPTIMIZED
-  };
-
-  // Intrinsic function descriptor.
-  struct Function {
-    FunctionId function_id;
-    IntrinsicType intrinsic_type;
-    // The JS name of the function.
-    const char* name;
-
-    // The C++ (native) entry point.  NULL if the function is inlined.
-    byte* entry;
-
-    // The number of arguments expected. nargs is -1 if the function takes
-    // a variable number of arguments.
-    int nargs;
-    // Size of result.  Most functions return a single pointer, size 1.
-    int result_size;
-  };
-
-  static const int kNotFound = -1;
-
-  // Add internalized strings for all the intrinsic function names to a
-  // StringDictionary.
-  static void InitializeIntrinsicFunctionNames(Isolate* isolate,
-                                               Handle<NameDictionary> dict);
-
-  // Get the intrinsic function with the given name, which must be internalized.
-  static const Function* FunctionForName(Handle<String> name);
-
-  // Get the intrinsic function with the given FunctionId.
-  static const Function* FunctionForId(FunctionId id);
-
-  // Get the intrinsic function with the given function entry address.
-  static const Function* FunctionForEntry(Address ref);
-
-  // General-purpose helper functions for runtime system.
-  static int StringMatch(Isolate* isolate,
-                         Handle<String> sub,
-                         Handle<String> pat,
-                         int index);
-
-  static bool IsUpperCaseChar(RuntimeState* runtime_state, uint16_t ch);
-
-  // TODO(1240886): Some of the following methods are *not* handle safe, but
-  // accept handle arguments. This seems fragile.
-
-  // Support getting the characters in a string using [] notation as
-  // in Firefox/SpiderMonkey, Safari and Opera.
-  MUST_USE_RESULT static MaybeHandle<Object> GetElementOrCharAt(
-      Isolate* isolate,
-      Handle<Object> object,
-      uint32_t index);
-
-  MUST_USE_RESULT static MaybeHandle<Object> SetObjectProperty(
-      Isolate* isolate, Handle<Object> object, Handle<Object> key,
-      Handle<Object> value, StrictMode strict_mode);
-
-  MUST_USE_RESULT static MaybeHandle<Object> DefineObjectProperty(
-      Handle<JSObject> object, Handle<Object> key, Handle<Object> value,
-      PropertyAttributes attr);
-
-  MUST_USE_RESULT static MaybeHandle<Object> DeleteObjectProperty(
-      Isolate* isolate,
-      Handle<JSReceiver> object,
-      Handle<Object> key,
-      JSReceiver::DeleteMode mode);
-
-  MUST_USE_RESULT static MaybeHandle<Object> HasObjectProperty(
-      Isolate* isolate,
-      Handle<JSReceiver> object,
-      Handle<Object> key);
-
-  MUST_USE_RESULT static MaybeHandle<Object> GetObjectProperty(
-      Isolate* isolate,
-      Handle<Object> object,
-      Handle<Object> key);
-
-  static void SetupArrayBuffer(Isolate* isolate,
-                               Handle<JSArrayBuffer> array_buffer,
-                               bool is_external,
-                               void* data,
-                               size_t allocated_length);
-
-  static bool SetupArrayBufferAllocatingData(
-      Isolate* isolate,
-      Handle<JSArrayBuffer> array_buffer,
-      size_t allocated_length,
-      bool initialize = true);
-
-  static void NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer);
-
-  static void FreeArrayBuffer(
-      Isolate* isolate,
-      JSArrayBuffer* phantom_array_buffer);
-
-  enum TypedArrayId {
-    // arrayIds below should be synchromized with typedarray.js natives.
-    ARRAY_ID_UINT8 = 1,
-    ARRAY_ID_INT8 = 2,
-    ARRAY_ID_UINT16 = 3,
-    ARRAY_ID_INT16 = 4,
-    ARRAY_ID_UINT32 = 5,
-    ARRAY_ID_INT32 = 6,
-    ARRAY_ID_FLOAT32 = 7,
-    ARRAY_ID_FLOAT64 = 8,
-    ARRAY_ID_UINT8_CLAMPED = 9,
-
-    ARRAY_ID_FIRST = ARRAY_ID_UINT8,
-    ARRAY_ID_LAST = ARRAY_ID_UINT8_CLAMPED
-  };
-
-  static void ArrayIdToTypeAndSize(int array_id,
-      ExternalArrayType *type,
-      ElementsKind* external_elements_kind,
-      ElementsKind* fixed_elements_kind,
-      size_t *element_size);
-
-  // Used in runtime.cc and hydrogen's VisitArrayLiteral.
-  MUST_USE_RESULT static MaybeHandle<Object> CreateArrayLiteralBoilerplate(
-      Isolate* isolate,
-      Handle<FixedArray> literals,
-      Handle<FixedArray> elements);
-};
-
-
-//---------------------------------------------------------------------------
-// Constants used by interface to runtime functions.
-
-class AllocateDoubleAlignFlag:  public BitField<bool,            0, 1> {};
-class AllocateTargetSpace:      public BitField<AllocationSpace, 1, 3> {};
-
-class DeclareGlobalsEvalFlag:   public BitField<bool,       0, 1> {};
-class DeclareGlobalsNativeFlag: public BitField<bool,       1, 1> {};
-class DeclareGlobalsStrictMode: public BitField<StrictMode, 2, 1> {};
-
-} }  // namespace v8::internal
-
-#endif  // V8_RUNTIME_H_
diff --git a/src/runtime.js b/src/runtime.js
index 4d15d20..978429e 100644
--- a/src/runtime.js
+++ b/src/runtime.js
@@ -6,9 +6,7 @@
 
 // CAUTION: Some of the functions specified in this file are called
 // directly from compiled code. These are the functions with names in
-// ALL CAPS. The compiled code passes the first argument in 'this' and
-// it does not push the function onto the stack. This means that you
-// cannot use contexts in all these functions.
+// ALL CAPS. The compiled code passes the first argument in 'this'.
 
 
 /* -----------------------------------
@@ -324,8 +322,13 @@
   if (!IS_SPEC_OBJECT(x)) {
     throw %MakeTypeError('invalid_in_operator_use', [this, x]);
   }
-  return %_IsNonNegativeSmi(this) ?
-    %HasElement(x, this) : %HasProperty(x, %ToName(this));
+  if (%_IsNonNegativeSmi(this)) {
+    if (IS_ARRAY(x) && %_HasFastPackedElements(x)) {
+      return this < x.length;
+    }
+    return %HasElement(x, this);
+  }
+  return %HasProperty(x, %ToName(this));
 }
 
 
@@ -598,6 +601,15 @@
   return x === y;
 }
 
+// ES6, section 7.2.4
+function SameValueZero(x, y) {
+  if (typeof x != typeof y) return false;
+  if (IS_NUMBER(x)) {
+    if (NUMBER_IS_NAN(x) && NUMBER_IS_NAN(y)) return true;
+  }
+  return x === y;
+}
+
 
 /* ---------------------------------
    - - -   U t i l i t i e s   - - -
@@ -614,6 +626,15 @@
 }
 
 
+// ES6, draft 10-14-14, section 22.1.3.1.1
+function IsConcatSpreadable(O) {
+  if (!IS_SPEC_OBJECT(O)) return false;
+  var spreadable = O[symbolIsConcatSpreadable];
+  if (IS_UNDEFINED(spreadable)) return IS_ARRAY(O);
+  return ToBoolean(spreadable);
+}
+
+
 // ECMA-262, section 8.6.2.6, page 28.
 function DefaultNumber(x) {
   if (!IS_SYMBOL_WRAPPER(x)) {
@@ -651,7 +672,7 @@
 }
 
 function ToPositiveInteger(x, rangeErrorName) {
-  var i = TO_INTEGER(x);
+  var i = TO_INTEGER_MAP_MINUS_ZERO(x);
   if (i < 0) throw MakeRangeError(rangeErrorName);
   return i;
 }
diff --git a/src/runtime/runtime-api.cc b/src/runtime/runtime-api.cc
new file mode 100644
index 0000000..740832e
--- /dev/null
+++ b/src/runtime/runtime-api.cc
@@ -0,0 +1,127 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/bootstrapper.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_CreateApiFunction) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(FunctionTemplateInfo, data, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+  return *isolate->factory()->CreateApiFunction(data, prototype);
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsTemplate) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, arg, 0);
+  bool result = arg->IsObjectTemplateInfo() || arg->IsFunctionTemplateInfo();
+  return isolate->heap()->ToBoolean(result);
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetTemplateField) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(HeapObject, templ, 0);
+  CONVERT_SMI_ARG_CHECKED(index, 1);
+  int offset = index * kPointerSize + HeapObject::kHeaderSize;
+  InstanceType type = templ->map()->instance_type();
+  RUNTIME_ASSERT(type == FUNCTION_TEMPLATE_INFO_TYPE ||
+                 type == OBJECT_TEMPLATE_INFO_TYPE);
+  RUNTIME_ASSERT(offset > 0);
+  if (type == FUNCTION_TEMPLATE_INFO_TYPE) {
+    RUNTIME_ASSERT(offset < FunctionTemplateInfo::kSize);
+  } else {
+    RUNTIME_ASSERT(offset < ObjectTemplateInfo::kSize);
+  }
+  return *HeapObject::RawField(templ, offset);
+}
+
+
+// Transform getter or setter into something DefineAccessor can handle.
+static Handle<Object> InstantiateAccessorComponent(Isolate* isolate,
+                                                   Handle<Object> component) {
+  if (component->IsUndefined()) return isolate->factory()->undefined_value();
+  Handle<FunctionTemplateInfo> info =
+      Handle<FunctionTemplateInfo>::cast(component);
+  return Utils::OpenHandle(*Utils::ToLocal(info)->GetFunction());
+}
+
+
+RUNTIME_FUNCTION(Runtime_DefineApiAccessorProperty) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 5);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
+  CONVERT_SMI_ARG_CHECKED(attribute, 4);
+  RUNTIME_ASSERT(getter->IsUndefined() || getter->IsFunctionTemplateInfo());
+  RUNTIME_ASSERT(setter->IsUndefined() || setter->IsFunctionTemplateInfo());
+  RUNTIME_ASSERT(PropertyDetails::AttributesField::is_valid(
+      static_cast<PropertyAttributes>(attribute)));
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, JSObject::DefineAccessor(
+                   object, name, InstantiateAccessorComponent(isolate, getter),
+                   InstantiateAccessorComponent(isolate, setter),
+                   static_cast<PropertyAttributes>(attribute)));
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_AddPropertyForTemplate) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 4);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
+  RUNTIME_ASSERT(
+      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+  // Compute attributes.
+  PropertyAttributes attributes =
+      static_cast<PropertyAttributes>(unchecked_attributes);
+
+#ifdef DEBUG
+  bool duplicate;
+  if (key->IsName()) {
+    LookupIterator it(object, Handle<Name>::cast(key),
+                      LookupIterator::OWN_SKIP_INTERCEPTOR);
+    Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+    DCHECK(maybe.has_value);
+    duplicate = it.IsFound();
+  } else {
+    uint32_t index = 0;
+    RUNTIME_ASSERT(key->ToArrayIndex(&index));
+    Maybe<bool> maybe = JSReceiver::HasOwnElement(object, index);
+    if (!maybe.has_value) return isolate->heap()->exception();
+    duplicate = maybe.value;
+  }
+  if (duplicate) {
+    Handle<Object> args[1] = {key};
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate,
+        NewTypeError("duplicate_template_property", HandleVector(args, 1)));
+  }
+#endif
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Runtime::DefineObjectProperty(object, key, value, attributes));
+  return *result;
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-array.cc b/src/runtime/runtime-array.cc
new file mode 100644
index 0000000..a017236
--- /dev/null
+++ b/src/runtime/runtime-array.cc
@@ -0,0 +1,1317 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_FinishArrayPrototypeSetup) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, prototype, 0);
+  Object* length = prototype->length();
+  RUNTIME_ASSERT(length->IsSmi() && Smi::cast(length)->value() == 0);
+  RUNTIME_ASSERT(prototype->HasFastSmiOrObjectElements());
+  // This is necessary to enable fast checks for absence of elements
+  // on Array.prototype and below.
+  prototype->set_elements(isolate->heap()->empty_fixed_array());
+  return Smi::FromInt(0);
+}
+
+
+static void InstallBuiltin(Isolate* isolate, Handle<JSObject> holder,
+                           const char* name, Builtins::Name builtin_name) {
+  Handle<String> key = isolate->factory()->InternalizeUtf8String(name);
+  Handle<Code> code(isolate->builtins()->builtin(builtin_name));
+  Handle<JSFunction> optimized =
+      isolate->factory()->NewFunctionWithoutPrototype(key, code);
+  optimized->shared()->DontAdaptArguments();
+  JSObject::AddProperty(holder, key, optimized, NONE);
+}
+
+
+RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  Handle<JSObject> holder =
+      isolate->factory()->NewJSObject(isolate->object_function());
+
+  InstallBuiltin(isolate, holder, "pop", Builtins::kArrayPop);
+  InstallBuiltin(isolate, holder, "push", Builtins::kArrayPush);
+  InstallBuiltin(isolate, holder, "shift", Builtins::kArrayShift);
+  InstallBuiltin(isolate, holder, "unshift", Builtins::kArrayUnshift);
+  InstallBuiltin(isolate, holder, "slice", Builtins::kArraySlice);
+  InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
+  InstallBuiltin(isolate, holder, "concat", Builtins::kArrayConcat);
+
+  return *holder;
+}
+
+
+RUNTIME_FUNCTION(Runtime_TransitionElementsKind) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Map, map, 1);
+  JSObject::TransitionElementsKind(array, map->elements_kind());
+  return *array;
+}
+
+
+// Push an object unto an array of objects if it is not already in the
+// array.  Returns true if the element was pushed on the stack and
+// false otherwise.
+RUNTIME_FUNCTION(Runtime_PushIfAbsent) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, element, 1);
+  RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
+  int length = Smi::cast(array->length())->value();
+  FixedArray* elements = FixedArray::cast(array->elements());
+  for (int i = 0; i < length; i++) {
+    if (elements->get(i) == *element) return isolate->heap()->false_value();
+  }
+
+  // Strict not needed. Used for cycle detection in Array join implementation.
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, JSObject::SetFastElement(array, length, element, SLOPPY, true));
+  return isolate->heap()->true_value();
+}
+
+
+/**
+ * A simple visitor visits every element of Array's.
+ * The backend storage can be a fixed array for fast elements case,
+ * or a dictionary for sparse array. Since Dictionary is a subtype
+ * of FixedArray, the class can be used by both fast and slow cases.
+ * The second parameter of the constructor, fast_elements, specifies
+ * whether the storage is a FixedArray or Dictionary.
+ *
+ * An index limit is used to deal with the situation that a result array
+ * length overflows 32-bit non-negative integer.
+ */
+class ArrayConcatVisitor {
+ public:
+  ArrayConcatVisitor(Isolate* isolate, Handle<FixedArray> storage,
+                     bool fast_elements)
+      : isolate_(isolate),
+        storage_(Handle<FixedArray>::cast(
+            isolate->global_handles()->Create(*storage))),
+        index_offset_(0u),
+        bit_field_(FastElementsField::encode(fast_elements) |
+                   ExceedsLimitField::encode(false)) {}
+
+  ~ArrayConcatVisitor() { clear_storage(); }
+
+  void visit(uint32_t i, Handle<Object> elm) {
+    if (i > JSObject::kMaxElementCount - index_offset_) {
+      set_exceeds_array_limit(true);
+      return;
+    }
+    uint32_t index = index_offset_ + i;
+
+    if (fast_elements()) {
+      if (index < static_cast<uint32_t>(storage_->length())) {
+        storage_->set(index, *elm);
+        return;
+      }
+      // Our initial estimate of length was foiled, possibly by
+      // getters on the arrays increasing the length of later arrays
+      // during iteration.
+      // This shouldn't happen in anything but pathological cases.
+      SetDictionaryMode();
+      // Fall-through to dictionary mode.
+    }
+    DCHECK(!fast_elements());
+    Handle<SeededNumberDictionary> dict(
+        SeededNumberDictionary::cast(*storage_));
+    Handle<SeededNumberDictionary> result =
+        SeededNumberDictionary::AtNumberPut(dict, index, elm);
+    if (!result.is_identical_to(dict)) {
+      // Dictionary needed to grow.
+      clear_storage();
+      set_storage(*result);
+    }
+  }
+
+  void increase_index_offset(uint32_t delta) {
+    if (JSObject::kMaxElementCount - index_offset_ < delta) {
+      index_offset_ = JSObject::kMaxElementCount;
+    } else {
+      index_offset_ += delta;
+    }
+    // If the initial length estimate was off (see special case in visit()),
+    // but the array blowing the limit didn't contain elements beyond the
+    // provided-for index range, go to dictionary mode now.
+    if (fast_elements() &&
+        index_offset_ >
+            static_cast<uint32_t>(FixedArrayBase::cast(*storage_)->length())) {
+      SetDictionaryMode();
+    }
+  }
+
+  bool exceeds_array_limit() const {
+    return ExceedsLimitField::decode(bit_field_);
+  }
+
+  Handle<JSArray> ToArray() {
+    Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
+    Handle<Object> length =
+        isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
+    Handle<Map> map = JSObject::GetElementsTransitionMap(
+        array, fast_elements() ? FAST_HOLEY_ELEMENTS : DICTIONARY_ELEMENTS);
+    array->set_map(*map);
+    array->set_length(*length);
+    array->set_elements(*storage_);
+    return array;
+  }
+
+ private:
+  // Convert storage to dictionary mode.
+  void SetDictionaryMode() {
+    DCHECK(fast_elements());
+    Handle<FixedArray> current_storage(*storage_);
+    Handle<SeededNumberDictionary> slow_storage(
+        SeededNumberDictionary::New(isolate_, current_storage->length()));
+    uint32_t current_length = static_cast<uint32_t>(current_storage->length());
+    for (uint32_t i = 0; i < current_length; i++) {
+      HandleScope loop_scope(isolate_);
+      Handle<Object> element(current_storage->get(i), isolate_);
+      if (!element->IsTheHole()) {
+        Handle<SeededNumberDictionary> new_storage =
+            SeededNumberDictionary::AtNumberPut(slow_storage, i, element);
+        if (!new_storage.is_identical_to(slow_storage)) {
+          slow_storage = loop_scope.CloseAndEscape(new_storage);
+        }
+      }
+    }
+    clear_storage();
+    set_storage(*slow_storage);
+    set_fast_elements(false);
+  }
+
+  inline void clear_storage() {
+    GlobalHandles::Destroy(Handle<Object>::cast(storage_).location());
+  }
+
+  inline void set_storage(FixedArray* storage) {
+    storage_ =
+        Handle<FixedArray>::cast(isolate_->global_handles()->Create(storage));
+  }
+
+  class FastElementsField : public BitField<bool, 0, 1> {};
+  class ExceedsLimitField : public BitField<bool, 1, 1> {};
+
+  bool fast_elements() const { return FastElementsField::decode(bit_field_); }
+  void set_fast_elements(bool fast) {
+    bit_field_ = FastElementsField::update(bit_field_, fast);
+  }
+  void set_exceeds_array_limit(bool exceeds) {
+    bit_field_ = ExceedsLimitField::update(bit_field_, exceeds);
+  }
+
+  Isolate* isolate_;
+  Handle<FixedArray> storage_;  // Always a global handle.
+  // Index after last seen index. Always less than or equal to
+  // JSObject::kMaxElementCount.
+  uint32_t index_offset_;
+  uint32_t bit_field_;
+};
+
+
+static uint32_t EstimateElementCount(Handle<JSArray> array) {
+  uint32_t length = static_cast<uint32_t>(array->length()->Number());
+  int element_count = 0;
+  switch (array->GetElementsKind()) {
+    case FAST_SMI_ELEMENTS:
+    case FAST_HOLEY_SMI_ELEMENTS:
+    case FAST_ELEMENTS:
+    case FAST_HOLEY_ELEMENTS: {
+      // Fast elements can't have lengths that are not representable by
+      // a 32-bit signed integer.
+      DCHECK(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
+      int fast_length = static_cast<int>(length);
+      Handle<FixedArray> elements(FixedArray::cast(array->elements()));
+      for (int i = 0; i < fast_length; i++) {
+        if (!elements->get(i)->IsTheHole()) element_count++;
+      }
+      break;
+    }
+    case FAST_DOUBLE_ELEMENTS:
+    case FAST_HOLEY_DOUBLE_ELEMENTS: {
+      // Fast elements can't have lengths that are not representable by
+      // a 32-bit signed integer.
+      DCHECK(static_cast<int32_t>(FixedDoubleArray::kMaxLength) >= 0);
+      int fast_length = static_cast<int>(length);
+      if (array->elements()->IsFixedArray()) {
+        DCHECK(FixedArray::cast(array->elements())->length() == 0);
+        break;
+      }
+      Handle<FixedDoubleArray> elements(
+          FixedDoubleArray::cast(array->elements()));
+      for (int i = 0; i < fast_length; i++) {
+        if (!elements->is_the_hole(i)) element_count++;
+      }
+      break;
+    }
+    case DICTIONARY_ELEMENTS: {
+      Handle<SeededNumberDictionary> dictionary(
+          SeededNumberDictionary::cast(array->elements()));
+      int capacity = dictionary->Capacity();
+      for (int i = 0; i < capacity; i++) {
+        Handle<Object> key(dictionary->KeyAt(i), array->GetIsolate());
+        if (dictionary->IsKey(*key)) {
+          element_count++;
+        }
+      }
+      break;
+    }
+    case SLOPPY_ARGUMENTS_ELEMENTS:
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+  case EXTERNAL_##TYPE##_ELEMENTS:                      \
+  case TYPE##_ELEMENTS:
+
+      TYPED_ARRAYS(TYPED_ARRAY_CASE)
+#undef TYPED_ARRAY_CASE
+      // External arrays are always dense.
+      return length;
+  }
+  // As an estimate, we assume that the prototype doesn't contain any
+  // inherited elements.
+  return element_count;
+}
+
+
+template <class ExternalArrayClass, class ElementType>
+static void IterateTypedArrayElements(Isolate* isolate,
+                                      Handle<JSObject> receiver,
+                                      bool elements_are_ints,
+                                      bool elements_are_guaranteed_smis,
+                                      ArrayConcatVisitor* visitor) {
+  Handle<ExternalArrayClass> array(
+      ExternalArrayClass::cast(receiver->elements()));
+  uint32_t len = static_cast<uint32_t>(array->length());
+
+  DCHECK(visitor != NULL);
+  if (elements_are_ints) {
+    if (elements_are_guaranteed_smis) {
+      for (uint32_t j = 0; j < len; j++) {
+        HandleScope loop_scope(isolate);
+        Handle<Smi> e(Smi::FromInt(static_cast<int>(array->get_scalar(j))),
+                      isolate);
+        visitor->visit(j, e);
+      }
+    } else {
+      for (uint32_t j = 0; j < len; j++) {
+        HandleScope loop_scope(isolate);
+        int64_t val = static_cast<int64_t>(array->get_scalar(j));
+        if (Smi::IsValid(static_cast<intptr_t>(val))) {
+          Handle<Smi> e(Smi::FromInt(static_cast<int>(val)), isolate);
+          visitor->visit(j, e);
+        } else {
+          Handle<Object> e =
+              isolate->factory()->NewNumber(static_cast<ElementType>(val));
+          visitor->visit(j, e);
+        }
+      }
+    }
+  } else {
+    for (uint32_t j = 0; j < len; j++) {
+      HandleScope loop_scope(isolate);
+      Handle<Object> e = isolate->factory()->NewNumber(array->get_scalar(j));
+      visitor->visit(j, e);
+    }
+  }
+}
+
+
+// Used for sorting indices in a List<uint32_t>.
+static int compareUInt32(const uint32_t* ap, const uint32_t* bp) {
+  uint32_t a = *ap;
+  uint32_t b = *bp;
+  return (a == b) ? 0 : (a < b) ? -1 : 1;
+}
+
+
+static void CollectElementIndices(Handle<JSObject> object, uint32_t range,
+                                  List<uint32_t>* indices) {
+  Isolate* isolate = object->GetIsolate();
+  ElementsKind kind = object->GetElementsKind();
+  switch (kind) {
+    case FAST_SMI_ELEMENTS:
+    case FAST_ELEMENTS:
+    case FAST_HOLEY_SMI_ELEMENTS:
+    case FAST_HOLEY_ELEMENTS: {
+      Handle<FixedArray> elements(FixedArray::cast(object->elements()));
+      uint32_t length = static_cast<uint32_t>(elements->length());
+      if (range < length) length = range;
+      for (uint32_t i = 0; i < length; i++) {
+        if (!elements->get(i)->IsTheHole()) {
+          indices->Add(i);
+        }
+      }
+      break;
+    }
+    case FAST_HOLEY_DOUBLE_ELEMENTS:
+    case FAST_DOUBLE_ELEMENTS: {
+      if (object->elements()->IsFixedArray()) {
+        DCHECK(object->elements()->length() == 0);
+        break;
+      }
+      Handle<FixedDoubleArray> elements(
+          FixedDoubleArray::cast(object->elements()));
+      uint32_t length = static_cast<uint32_t>(elements->length());
+      if (range < length) length = range;
+      for (uint32_t i = 0; i < length; i++) {
+        if (!elements->is_the_hole(i)) {
+          indices->Add(i);
+        }
+      }
+      break;
+    }
+    case DICTIONARY_ELEMENTS: {
+      Handle<SeededNumberDictionary> dict(
+          SeededNumberDictionary::cast(object->elements()));
+      uint32_t capacity = dict->Capacity();
+      for (uint32_t j = 0; j < capacity; j++) {
+        HandleScope loop_scope(isolate);
+        Handle<Object> k(dict->KeyAt(j), isolate);
+        if (dict->IsKey(*k)) {
+          DCHECK(k->IsNumber());
+          uint32_t index = static_cast<uint32_t>(k->Number());
+          if (index < range) {
+            indices->Add(index);
+          }
+        }
+      }
+      break;
+    }
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+  case TYPE##_ELEMENTS:                                 \
+  case EXTERNAL_##TYPE##_ELEMENTS:
+
+      TYPED_ARRAYS(TYPED_ARRAY_CASE)
+#undef TYPED_ARRAY_CASE
+      {
+        uint32_t length = static_cast<uint32_t>(
+            FixedArrayBase::cast(object->elements())->length());
+        if (range <= length) {
+          length = range;
+          // We will add all indices, so we might as well clear it first
+          // and avoid duplicates.
+          indices->Clear();
+        }
+        for (uint32_t i = 0; i < length; i++) {
+          indices->Add(i);
+        }
+        if (length == range) return;  // All indices accounted for already.
+        break;
+      }
+    case SLOPPY_ARGUMENTS_ELEMENTS: {
+      MaybeHandle<Object> length_obj =
+          Object::GetProperty(object, isolate->factory()->length_string());
+      double length_num = length_obj.ToHandleChecked()->Number();
+      uint32_t length = static_cast<uint32_t>(DoubleToInt32(length_num));
+      ElementsAccessor* accessor = object->GetElementsAccessor();
+      for (uint32_t i = 0; i < length; i++) {
+        if (accessor->HasElement(object, object, i)) {
+          indices->Add(i);
+        }
+      }
+      break;
+    }
+  }
+
+  PrototypeIterator iter(isolate, object);
+  if (!iter.IsAtEnd()) {
+    // The prototype will usually have no inherited element indices,
+    // but we have to check.
+    CollectElementIndices(
+        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), range,
+        indices);
+  }
+}
+
+
+static bool IterateElementsSlow(Isolate* isolate, Handle<JSObject> receiver,
+                                uint32_t length, ArrayConcatVisitor* visitor) {
+  for (uint32_t i = 0; i < length; ++i) {
+    HandleScope loop_scope(isolate);
+    Maybe<bool> maybe = JSReceiver::HasElement(receiver, i);
+    if (!maybe.has_value) return false;
+    if (maybe.value) {
+      Handle<Object> element_value;
+      ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+          isolate, element_value,
+          Runtime::GetElementOrCharAt(isolate, receiver, i), false);
+      visitor->visit(i, element_value);
+    }
+  }
+  visitor->increase_index_offset(length);
+  return true;
+}
+
+
+/**
+ * A helper function that visits elements of a JSObject in numerical
+ * order.
+ *
+ * The visitor argument called for each existing element in the array
+ * with the element index and the element's value.
+ * Afterwards it increments the base-index of the visitor by the array
+ * length.
+ * Returns false if any access threw an exception, otherwise true.
+ */
+static bool IterateElements(Isolate* isolate, Handle<JSObject> receiver,
+                            ArrayConcatVisitor* visitor) {
+  uint32_t length = 0;
+
+  if (receiver->IsJSArray()) {
+    Handle<JSArray> array(Handle<JSArray>::cast(receiver));
+    length = static_cast<uint32_t>(array->length()->Number());
+  } else {
+    Handle<Object> val;
+    Handle<Object> key(isolate->heap()->length_string(), isolate);
+    ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, val,
+        Runtime::GetObjectProperty(isolate, receiver, key), false);
+    // TODO(caitp): Support larger element indexes (up to 2^53-1).
+    if (!val->ToUint32(&length)) {
+      ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, val,
+          Execution::ToLength(isolate, val), false);
+      val->ToUint32(&length);
+    }
+  }
+
+  if (!(receiver->IsJSArray() || receiver->IsJSTypedArray())) {
+    // For classes which are not known to be safe to access via elements alone,
+    // use the slow case.
+    return IterateElementsSlow(isolate, receiver, length, visitor);
+  }
+
+  switch (receiver->GetElementsKind()) {
+    case FAST_SMI_ELEMENTS:
+    case FAST_ELEMENTS:
+    case FAST_HOLEY_SMI_ELEMENTS:
+    case FAST_HOLEY_ELEMENTS: {
+      // Run through the elements FixedArray and use HasElement and GetElement
+      // to check the prototype for missing elements.
+      Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
+      int fast_length = static_cast<int>(length);
+      DCHECK(fast_length <= elements->length());
+      for (int j = 0; j < fast_length; j++) {
+        HandleScope loop_scope(isolate);
+        Handle<Object> element_value(elements->get(j), isolate);
+        if (!element_value->IsTheHole()) {
+          visitor->visit(j, element_value);
+        } else {
+          Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
+          if (!maybe.has_value) return false;
+          if (maybe.value) {
+            // Call GetElement on receiver, not its prototype, or getters won't
+            // have the correct receiver.
+            ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+                isolate, element_value,
+                Object::GetElement(isolate, receiver, j), false);
+            visitor->visit(j, element_value);
+          }
+        }
+      }
+      break;
+    }
+    case FAST_HOLEY_DOUBLE_ELEMENTS:
+    case FAST_DOUBLE_ELEMENTS: {
+      // Empty array is FixedArray but not FixedDoubleArray.
+      if (length == 0) break;
+      // Run through the elements FixedArray and use HasElement and GetElement
+      // to check the prototype for missing elements.
+      if (receiver->elements()->IsFixedArray()) {
+        DCHECK(receiver->elements()->length() == 0);
+        break;
+      }
+      Handle<FixedDoubleArray> elements(
+          FixedDoubleArray::cast(receiver->elements()));
+      int fast_length = static_cast<int>(length);
+      DCHECK(fast_length <= elements->length());
+      for (int j = 0; j < fast_length; j++) {
+        HandleScope loop_scope(isolate);
+        if (!elements->is_the_hole(j)) {
+          double double_value = elements->get_scalar(j);
+          Handle<Object> element_value =
+              isolate->factory()->NewNumber(double_value);
+          visitor->visit(j, element_value);
+        } else {
+          Maybe<bool> maybe = JSReceiver::HasElement(receiver, j);
+          if (!maybe.has_value) return false;
+          if (maybe.value) {
+            // Call GetElement on receiver, not its prototype, or getters won't
+            // have the correct receiver.
+            Handle<Object> element_value;
+            ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+                isolate, element_value,
+                Object::GetElement(isolate, receiver, j), false);
+            visitor->visit(j, element_value);
+          }
+        }
+      }
+      break;
+    }
+    case DICTIONARY_ELEMENTS: {
+      Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
+      List<uint32_t> indices(dict->Capacity() / 2);
+      // Collect all indices in the object and the prototypes less
+      // than length. This might introduce duplicates in the indices list.
+      CollectElementIndices(receiver, length, &indices);
+      indices.Sort(&compareUInt32);
+      int j = 0;
+      int n = indices.length();
+      while (j < n) {
+        HandleScope loop_scope(isolate);
+        uint32_t index = indices[j];
+        Handle<Object> element;
+        ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+            isolate, element, Object::GetElement(isolate, receiver, index),
+            false);
+        visitor->visit(index, element);
+        // Skip to next different index (i.e., omit duplicates).
+        do {
+          j++;
+        } while (j < n && indices[j] == index);
+      }
+      break;
+    }
+    case EXTERNAL_UINT8_CLAMPED_ELEMENTS: {
+      Handle<ExternalUint8ClampedArray> pixels(
+          ExternalUint8ClampedArray::cast(receiver->elements()));
+      for (uint32_t j = 0; j < length; j++) {
+        Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
+        visitor->visit(j, e);
+      }
+      break;
+    }
+    case UINT8_CLAMPED_ELEMENTS: {
+      Handle<FixedUint8ClampedArray> pixels(
+      FixedUint8ClampedArray::cast(receiver->elements()));
+      for (uint32_t j = 0; j < length; j++) {
+        Handle<Smi> e(Smi::FromInt(pixels->get_scalar(j)), isolate);
+        visitor->visit(j, e);
+      }
+      break;
+    }
+    case EXTERNAL_INT8_ELEMENTS: {
+      IterateTypedArrayElements<ExternalInt8Array, int8_t>(
+          isolate, receiver, true, true, visitor);
+      break;
+    }
+    case INT8_ELEMENTS: {
+      IterateTypedArrayElements<FixedInt8Array, int8_t>(
+      isolate, receiver, true, true, visitor);
+      break;
+    }
+    case EXTERNAL_UINT8_ELEMENTS: {
+      IterateTypedArrayElements<ExternalUint8Array, uint8_t>(
+          isolate, receiver, true, true, visitor);
+      break;
+    }
+    case UINT8_ELEMENTS: {
+      IterateTypedArrayElements<FixedUint8Array, uint8_t>(
+      isolate, receiver, true, true, visitor);
+      break;
+    }
+    case EXTERNAL_INT16_ELEMENTS: {
+      IterateTypedArrayElements<ExternalInt16Array, int16_t>(
+          isolate, receiver, true, true, visitor);
+      break;
+    }
+    case INT16_ELEMENTS: {
+      IterateTypedArrayElements<FixedInt16Array, int16_t>(
+      isolate, receiver, true, true, visitor);
+      break;
+    }
+    case EXTERNAL_UINT16_ELEMENTS: {
+      IterateTypedArrayElements<ExternalUint16Array, uint16_t>(
+          isolate, receiver, true, true, visitor);
+      break;
+    }
+    case UINT16_ELEMENTS: {
+      IterateTypedArrayElements<FixedUint16Array, uint16_t>(
+      isolate, receiver, true, true, visitor);
+      break;
+    }
+    case EXTERNAL_INT32_ELEMENTS: {
+      IterateTypedArrayElements<ExternalInt32Array, int32_t>(
+          isolate, receiver, true, false, visitor);
+      break;
+    }
+    case INT32_ELEMENTS: {
+      IterateTypedArrayElements<FixedInt32Array, int32_t>(
+      isolate, receiver, true, false, visitor);
+      break;
+    }
+    case EXTERNAL_UINT32_ELEMENTS: {
+      IterateTypedArrayElements<ExternalUint32Array, uint32_t>(
+          isolate, receiver, true, false, visitor);
+      break;
+    }
+    case UINT32_ELEMENTS: {
+      IterateTypedArrayElements<FixedUint32Array, uint32_t>(
+      isolate, receiver, true, false, visitor);
+      break;
+    }
+    case EXTERNAL_FLOAT32_ELEMENTS: {
+      IterateTypedArrayElements<ExternalFloat32Array, float>(
+          isolate, receiver, false, false, visitor);
+      break;
+    }
+    case FLOAT32_ELEMENTS: {
+      IterateTypedArrayElements<FixedFloat32Array, float>(
+      isolate, receiver, false, false, visitor);
+      break;
+    }
+    case EXTERNAL_FLOAT64_ELEMENTS: {
+      IterateTypedArrayElements<ExternalFloat64Array, double>(
+          isolate, receiver, false, false, visitor);
+      break;
+    }
+    case FLOAT64_ELEMENTS: {
+      IterateTypedArrayElements<FixedFloat64Array, double>(
+      isolate, receiver, false, false, visitor);
+      break;
+    }
+    case SLOPPY_ARGUMENTS_ELEMENTS: {
+      ElementsAccessor* accessor = receiver->GetElementsAccessor();
+      for (uint32_t index = 0; index < length; index++) {
+        HandleScope loop_scope(isolate);
+        if (accessor->HasElement(receiver, receiver, index)) {
+          Handle<Object> element;
+          ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+              isolate, element, accessor->Get(receiver, receiver, index),
+              false);
+          visitor->visit(index, element);
+        }
+      }
+      break;
+    }
+  }
+  visitor->increase_index_offset(length);
+  return true;
+}
+
+
+static bool IsConcatSpreadable(Isolate* isolate, Handle<Object> obj) {
+  HandleScope handle_scope(isolate);
+  if (!obj->IsSpecObject()) return false;
+  if (obj->IsJSArray()) return true;
+  if (FLAG_harmony_arrays) {
+    Handle<Symbol> key(isolate->factory()->is_concat_spreadable_symbol());
+    Handle<Object> value;
+    MaybeHandle<Object> maybeValue =
+        i::Runtime::GetObjectProperty(isolate, obj, key);
+    if (maybeValue.ToHandle(&value)) {
+      return value->BooleanValue();
+    }
+  }
+  return false;
+}
+
+
+/**
+ * Array::concat implementation.
+ * See ECMAScript 262, 15.4.4.4.
+ * TODO(581): Fix non-compliance for very large concatenations and update to
+ * following the ECMAScript 5 specification.
+ */
+RUNTIME_FUNCTION(Runtime_ArrayConcat) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
+  int argument_count = static_cast<int>(arguments->length()->Number());
+  RUNTIME_ASSERT(arguments->HasFastObjectElements());
+  Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
+
+  // Pass 1: estimate the length and number of elements of the result.
+  // The actual length can be larger if any of the arguments have getters
+  // that mutate other arguments (but will otherwise be precise).
+  // The number of elements is precise if there are no inherited elements.
+
+  ElementsKind kind = FAST_SMI_ELEMENTS;
+
+  uint32_t estimate_result_length = 0;
+  uint32_t estimate_nof_elements = 0;
+  for (int i = 0; i < argument_count; i++) {
+    HandleScope loop_scope(isolate);
+    Handle<Object> obj(elements->get(i), isolate);
+    uint32_t length_estimate;
+    uint32_t element_estimate;
+    if (obj->IsJSArray()) {
+      Handle<JSArray> array(Handle<JSArray>::cast(obj));
+      length_estimate = static_cast<uint32_t>(array->length()->Number());
+      if (length_estimate != 0) {
+        ElementsKind array_kind =
+            GetPackedElementsKind(array->map()->elements_kind());
+        if (IsMoreGeneralElementsKindTransition(kind, array_kind)) {
+          kind = array_kind;
+        }
+      }
+      element_estimate = EstimateElementCount(array);
+    } else {
+      if (obj->IsHeapObject()) {
+        if (obj->IsNumber()) {
+          if (IsMoreGeneralElementsKindTransition(kind, FAST_DOUBLE_ELEMENTS)) {
+            kind = FAST_DOUBLE_ELEMENTS;
+          }
+        } else if (IsMoreGeneralElementsKindTransition(kind, FAST_ELEMENTS)) {
+          kind = FAST_ELEMENTS;
+        }
+      }
+      length_estimate = 1;
+      element_estimate = 1;
+    }
+    // Avoid overflows by capping at kMaxElementCount.
+    if (JSObject::kMaxElementCount - estimate_result_length < length_estimate) {
+      estimate_result_length = JSObject::kMaxElementCount;
+    } else {
+      estimate_result_length += length_estimate;
+    }
+    if (JSObject::kMaxElementCount - estimate_nof_elements < element_estimate) {
+      estimate_nof_elements = JSObject::kMaxElementCount;
+    } else {
+      estimate_nof_elements += element_estimate;
+    }
+  }
+
+  // If estimated number of elements is more than half of length, a
+  // fixed array (fast case) is more time and space-efficient than a
+  // dictionary.
+  bool fast_case = (estimate_nof_elements * 2) >= estimate_result_length;
+
+  if (fast_case && kind == FAST_DOUBLE_ELEMENTS) {
+    Handle<FixedArrayBase> storage =
+        isolate->factory()->NewFixedDoubleArray(estimate_result_length);
+    int j = 0;
+    bool failure = false;
+    if (estimate_result_length > 0) {
+      Handle<FixedDoubleArray> double_storage =
+          Handle<FixedDoubleArray>::cast(storage);
+      for (int i = 0; i < argument_count; i++) {
+        Handle<Object> obj(elements->get(i), isolate);
+        if (obj->IsSmi()) {
+          double_storage->set(j, Smi::cast(*obj)->value());
+          j++;
+        } else if (obj->IsNumber()) {
+          double_storage->set(j, obj->Number());
+          j++;
+        } else {
+          JSArray* array = JSArray::cast(*obj);
+          uint32_t length = static_cast<uint32_t>(array->length()->Number());
+          switch (array->map()->elements_kind()) {
+            case FAST_HOLEY_DOUBLE_ELEMENTS:
+            case FAST_DOUBLE_ELEMENTS: {
+              // Empty array is FixedArray but not FixedDoubleArray.
+              if (length == 0) break;
+              FixedDoubleArray* elements =
+                  FixedDoubleArray::cast(array->elements());
+              for (uint32_t i = 0; i < length; i++) {
+                if (elements->is_the_hole(i)) {
+                  // TODO(jkummerow/verwaest): We could be a bit more clever
+                  // here: Check if there are no elements/getters on the
+                  // prototype chain, and if so, allow creation of a holey
+                  // result array.
+                  // Same thing below (holey smi case).
+                  failure = true;
+                  break;
+                }
+                double double_value = elements->get_scalar(i);
+                double_storage->set(j, double_value);
+                j++;
+              }
+              break;
+            }
+            case FAST_HOLEY_SMI_ELEMENTS:
+            case FAST_SMI_ELEMENTS: {
+              FixedArray* elements(FixedArray::cast(array->elements()));
+              for (uint32_t i = 0; i < length; i++) {
+                Object* element = elements->get(i);
+                if (element->IsTheHole()) {
+                  failure = true;
+                  break;
+                }
+                int32_t int_value = Smi::cast(element)->value();
+                double_storage->set(j, int_value);
+                j++;
+              }
+              break;
+            }
+            case FAST_HOLEY_ELEMENTS:
+            case FAST_ELEMENTS:
+              DCHECK_EQ(0, length);
+              break;
+            default:
+              UNREACHABLE();
+          }
+        }
+        if (failure) break;
+      }
+    }
+    if (!failure) {
+      Handle<JSArray> array = isolate->factory()->NewJSArray(0);
+      Smi* length = Smi::FromInt(j);
+      Handle<Map> map;
+      map = JSObject::GetElementsTransitionMap(array, kind);
+      array->set_map(*map);
+      array->set_length(length);
+      array->set_elements(*storage);
+      return *array;
+    }
+    // In case of failure, fall through.
+  }
+
+  Handle<FixedArray> storage;
+  if (fast_case) {
+    // The backing storage array must have non-existing elements to preserve
+    // holes across concat operations.
+    storage =
+        isolate->factory()->NewFixedArrayWithHoles(estimate_result_length);
+  } else {
+    // TODO(126): move 25% pre-allocation logic into Dictionary::Allocate
+    uint32_t at_least_space_for =
+        estimate_nof_elements + (estimate_nof_elements >> 2);
+    storage = Handle<FixedArray>::cast(
+        SeededNumberDictionary::New(isolate, at_least_space_for));
+  }
+
+  ArrayConcatVisitor visitor(isolate, storage, fast_case);
+
+  for (int i = 0; i < argument_count; i++) {
+    Handle<Object> obj(elements->get(i), isolate);
+    bool spreadable = IsConcatSpreadable(isolate, obj);
+    if (isolate->has_pending_exception()) return isolate->heap()->exception();
+    if (spreadable) {
+      Handle<JSObject> object = Handle<JSObject>::cast(obj);
+      if (!IterateElements(isolate, object, &visitor)) {
+        return isolate->heap()->exception();
+      }
+    } else {
+      visitor.visit(0, obj);
+      visitor.increase_index_offset(1);
+    }
+  }
+
+  if (visitor.exceeds_array_limit()) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate,
+        NewRangeError("invalid_array_length", HandleVector<Object>(NULL, 0)));
+  }
+  return *visitor.ToArray();
+}
+
+
+// Moves all own elements of an object, that are below a limit, to positions
+// starting at zero. All undefined values are placed after non-undefined values,
+// and are followed by non-existing element. Does not change the length
+// property.
+// Returns the number of non-undefined elements collected.
+// Returns -1 if hole removal is not supported by this method.
+RUNTIME_FUNCTION(Runtime_RemoveArrayHoles) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
+  return *JSObject::PrepareElementsForSort(object, limit);
+}
+
+
+// Move contents of argument 0 (an array) to argument 1 (an array)
+RUNTIME_FUNCTION(Runtime_MoveArrayContents) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, from, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, to, 1);
+  JSObject::ValidateElements(from);
+  JSObject::ValidateElements(to);
+
+  Handle<FixedArrayBase> new_elements(from->elements());
+  ElementsKind from_kind = from->GetElementsKind();
+  Handle<Map> new_map = JSObject::GetElementsTransitionMap(to, from_kind);
+  JSObject::SetMapAndElements(to, new_map, new_elements);
+  to->set_length(from->length());
+
+  JSObject::ResetElements(from);
+  from->set_length(Smi::FromInt(0));
+
+  JSObject::ValidateElements(to);
+  return *to;
+}
+
+
+// How many elements does this object/array have?
+RUNTIME_FUNCTION(Runtime_EstimateNumberOfElements) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
+  Handle<FixedArrayBase> elements(array->elements(), isolate);
+  SealHandleScope shs(isolate);
+  if (elements->IsDictionary()) {
+    int result =
+        Handle<SeededNumberDictionary>::cast(elements)->NumberOfElements();
+    return Smi::FromInt(result);
+  } else {
+    DCHECK(array->length()->IsSmi());
+    // For packed elements, we know the exact number of elements
+    int length = elements->length();
+    ElementsKind kind = array->GetElementsKind();
+    if (IsFastPackedElementsKind(kind)) {
+      return Smi::FromInt(length);
+    }
+    // For holey elements, take samples from the buffer checking for holes
+    // to generate the estimate.
+    const int kNumberOfHoleCheckSamples = 97;
+    int increment = (length < kNumberOfHoleCheckSamples)
+                        ? 1
+                        : static_cast<int>(length / kNumberOfHoleCheckSamples);
+    ElementsAccessor* accessor = array->GetElementsAccessor();
+    int holes = 0;
+    for (int i = 0; i < length; i += increment) {
+      if (!accessor->HasElement(array, array, i, elements)) {
+        ++holes;
+      }
+    }
+    int estimate = static_cast<int>((kNumberOfHoleCheckSamples - holes) /
+                                    kNumberOfHoleCheckSamples * length);
+    return Smi::FromInt(estimate);
+  }
+}
+
+
+// Returns an array that tells you where in the [0, length) interval an array
+// might have elements.  Can either return an array of keys (positive integers
+// or undefined) or a number representing the positive length of an interval
+// starting at index 0.
+// Intervals can span over some keys that are not in the object.
+RUNTIME_FUNCTION(Runtime_GetArrayKeys) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
+  CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]);
+  if (array->elements()->IsDictionary()) {
+    Handle<FixedArray> keys = isolate->factory()->empty_fixed_array();
+    for (PrototypeIterator iter(isolate, array,
+                                PrototypeIterator::START_AT_RECEIVER);
+         !iter.IsAtEnd(); iter.Advance()) {
+      if (PrototypeIterator::GetCurrent(iter)->IsJSProxy() ||
+          JSObject::cast(*PrototypeIterator::GetCurrent(iter))
+              ->HasIndexedInterceptor()) {
+        // Bail out if we find a proxy or interceptor, likely not worth
+        // collecting keys in that case.
+        return *isolate->factory()->NewNumberFromUint(length);
+      }
+      Handle<JSObject> current =
+          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+      Handle<FixedArray> current_keys =
+          isolate->factory()->NewFixedArray(current->NumberOfOwnElements(NONE));
+      current->GetOwnElementKeys(*current_keys, NONE);
+      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+          isolate, keys, FixedArray::UnionOfKeys(keys, current_keys));
+    }
+    // Erase any keys >= length.
+    // TODO(adamk): Remove this step when the contract of %GetArrayKeys
+    // is changed to let this happen on the JS side.
+    for (int i = 0; i < keys->length(); i++) {
+      if (NumberToUint32(keys->get(i)) >= length) keys->set_undefined(i);
+    }
+    return *isolate->factory()->NewJSArrayWithElements(keys);
+  } else {
+    RUNTIME_ASSERT(array->HasFastSmiOrObjectElements() ||
+                   array->HasFastDoubleElements());
+    uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
+    return *isolate->factory()->NewNumberFromUint(Min(actual_length, length));
+  }
+}
+
+
+static Object* ArrayConstructorCommon(Isolate* isolate,
+                                      Handle<JSFunction> constructor,
+                                      Handle<AllocationSite> site,
+                                      Arguments* caller_args) {
+  Factory* factory = isolate->factory();
+
+  bool holey = false;
+  bool can_use_type_feedback = true;
+  if (caller_args->length() == 1) {
+    Handle<Object> argument_one = caller_args->at<Object>(0);
+    if (argument_one->IsSmi()) {
+      int value = Handle<Smi>::cast(argument_one)->value();
+      if (value < 0 || value >= JSObject::kInitialMaxFastElementArray) {
+        // the array is a dictionary in this case.
+        can_use_type_feedback = false;
+      } else if (value != 0) {
+        holey = true;
+      }
+    } else {
+      // Non-smi length argument produces a dictionary
+      can_use_type_feedback = false;
+    }
+  }
+
+  Handle<JSArray> array;
+  if (!site.is_null() && can_use_type_feedback) {
+    ElementsKind to_kind = site->GetElementsKind();
+    if (holey && !IsFastHoleyElementsKind(to_kind)) {
+      to_kind = GetHoleyElementsKind(to_kind);
+      // Update the allocation site info to reflect the advice alteration.
+      site->SetElementsKind(to_kind);
+    }
+
+    // We should allocate with an initial map that reflects the allocation site
+    // advice. Therefore we use AllocateJSObjectFromMap instead of passing
+    // the constructor.
+    Handle<Map> initial_map(constructor->initial_map(), isolate);
+    if (to_kind != initial_map->elements_kind()) {
+      initial_map = Map::AsElementsKind(initial_map, to_kind);
+    }
+
+    // If we don't care to track arrays of to_kind ElementsKind, then
+    // don't emit a memento for them.
+    Handle<AllocationSite> allocation_site;
+    if (AllocationSite::GetMode(to_kind) == TRACK_ALLOCATION_SITE) {
+      allocation_site = site;
+    }
+
+    array = Handle<JSArray>::cast(factory->NewJSObjectFromMap(
+        initial_map, NOT_TENURED, true, allocation_site));
+  } else {
+    array = Handle<JSArray>::cast(factory->NewJSObject(constructor));
+
+    // We might need to transition to holey
+    ElementsKind kind = constructor->initial_map()->elements_kind();
+    if (holey && !IsFastHoleyElementsKind(kind)) {
+      kind = GetHoleyElementsKind(kind);
+      JSObject::TransitionElementsKind(array, kind);
+    }
+  }
+
+  factory->NewJSArrayStorage(array, 0, 0, DONT_INITIALIZE_ARRAY_ELEMENTS);
+
+  ElementsKind old_kind = array->GetElementsKind();
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, ArrayConstructInitializeElements(array, caller_args));
+  if (!site.is_null() &&
+      (old_kind != array->GetElementsKind() || !can_use_type_feedback)) {
+    // The arguments passed in caused a transition. This kind of complexity
+    // can't be dealt with in the inlined hydrogen array constructor case.
+    // We must mark the allocationsite as un-inlinable.
+    site->SetDoNotInlineCall();
+  }
+  return *array;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ArrayConstructor) {
+  HandleScope scope(isolate);
+  // If we get 2 arguments then they are the stub parameters (constructor, type
+  // info).  If we get 4, then the first one is a pointer to the arguments
+  // passed by the caller, and the last one is the length of the arguments
+  // passed to the caller (redundant, but useful to check on the deoptimizer
+  // with an assert).
+  Arguments empty_args(0, NULL);
+  bool no_caller_args = args.length() == 2;
+  DCHECK(no_caller_args || args.length() == 4);
+  int parameters_start = no_caller_args ? 0 : 1;
+  Arguments* caller_args =
+      no_caller_args ? &empty_args : reinterpret_cast<Arguments*>(args[0]);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
+  CONVERT_ARG_HANDLE_CHECKED(Object, type_info, parameters_start + 1);
+#ifdef DEBUG
+  if (!no_caller_args) {
+    CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 2);
+    DCHECK(arg_count == caller_args->length());
+  }
+#endif
+
+  Handle<AllocationSite> site;
+  if (!type_info.is_null() &&
+      *type_info != isolate->heap()->undefined_value()) {
+    site = Handle<AllocationSite>::cast(type_info);
+    DCHECK(!site->SitePointsToLiteral());
+  }
+
+  return ArrayConstructorCommon(isolate, constructor, site, caller_args);
+}
+
+
+RUNTIME_FUNCTION(Runtime_InternalArrayConstructor) {
+  HandleScope scope(isolate);
+  Arguments empty_args(0, NULL);
+  bool no_caller_args = args.length() == 1;
+  DCHECK(no_caller_args || args.length() == 3);
+  int parameters_start = no_caller_args ? 0 : 1;
+  Arguments* caller_args =
+      no_caller_args ? &empty_args : reinterpret_cast<Arguments*>(args[0]);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, parameters_start);
+#ifdef DEBUG
+  if (!no_caller_args) {
+    CONVERT_SMI_ARG_CHECKED(arg_count, parameters_start + 1);
+    DCHECK(arg_count == caller_args->length());
+  }
+#endif
+  return ArrayConstructorCommon(isolate, constructor,
+                                Handle<AllocationSite>::null(), caller_args);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NormalizeElements) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
+  RUNTIME_ASSERT(!array->HasExternalArrayElements() &&
+                 !array->HasFixedTypedArrayElements());
+  JSObject::NormalizeElements(array);
+  return *array;
+}
+
+
+RUNTIME_FUNCTION(Runtime_HasComplexElements) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, array, 0);
+  for (PrototypeIterator iter(isolate, array,
+                              PrototypeIterator::START_AT_RECEIVER);
+       !iter.IsAtEnd(); iter.Advance()) {
+    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
+      return isolate->heap()->true_value();
+    }
+    Handle<JSObject> current =
+        Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+    if (current->HasIndexedInterceptor()) {
+      return isolate->heap()->true_value();
+    }
+    if (!current->HasDictionaryElements()) continue;
+    if (current->element_dictionary()->HasComplexElements()) {
+      return isolate->heap()->true_value();
+    }
+  }
+  return isolate->heap()->false_value();
+}
+
+
+// TODO(dcarney): remove this function when TurboFan supports it.
+// Takes the object to be iterated over and the result of GetPropertyNamesFast
+// Returns pair (cache_array, cache_type).
+RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInInit) {
+  SealHandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  // This simulates CONVERT_ARG_HANDLE_CHECKED for calls returning pairs.
+  // Not worth creating a macro atm as this function should be removed.
+  if (!args[0]->IsJSReceiver() || !args[1]->IsObject()) {
+    Object* error = isolate->ThrowIllegalOperation();
+    return MakePair(error, isolate->heap()->undefined_value());
+  }
+  Handle<JSReceiver> object = args.at<JSReceiver>(0);
+  Handle<Object> cache_type = args.at<Object>(1);
+  if (cache_type->IsMap()) {
+    // Enum cache case.
+    if (Map::EnumLengthBits::decode(Map::cast(*cache_type)->bit_field3()) ==
+        0) {
+      // 0 length enum.
+      // Can't handle this case in the graph builder,
+      // so transform it into the empty fixed array case.
+      return MakePair(isolate->heap()->empty_fixed_array(), Smi::FromInt(1));
+    }
+    return MakePair(object->map()->instance_descriptors()->GetEnumCache(),
+                    *cache_type);
+  } else {
+    // FixedArray case.
+    Smi* new_cache_type = Smi::FromInt(object->IsJSProxy() ? 0 : 1);
+    return MakePair(*Handle<FixedArray>::cast(cache_type), new_cache_type);
+  }
+}
+
+
+// TODO(dcarney): remove this function when TurboFan supports it.
+RUNTIME_FUNCTION(Runtime_ForInCacheArrayLength) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, cache_type, 0);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, array, 1);
+  int length = 0;
+  if (cache_type->IsMap()) {
+    length = Map::cast(*cache_type)->EnumLength();
+  } else {
+    DCHECK(cache_type->IsSmi());
+    length = array->length();
+  }
+  return Smi::FromInt(length);
+}
+
+
+// TODO(dcarney): remove this function when TurboFan supports it.
+// Takes (the object to be iterated over,
+//        cache_array from ForInInit,
+//        cache_type from ForInInit,
+//        the current index)
+// Returns pair (array[index], needs_filtering).
+RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInNext) {
+  SealHandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  int32_t index;
+  // This simulates CONVERT_ARG_HANDLE_CHECKED for calls returning pairs.
+  // Not worth creating a macro atm as this function should be removed.
+  if (!args[0]->IsJSReceiver() || !args[1]->IsFixedArray() ||
+      !args[2]->IsObject() || !args[3]->ToInt32(&index)) {
+    Object* error = isolate->ThrowIllegalOperation();
+    return MakePair(error, isolate->heap()->undefined_value());
+  }
+  Handle<JSReceiver> object = args.at<JSReceiver>(0);
+  Handle<FixedArray> array = args.at<FixedArray>(1);
+  Handle<Object> cache_type = args.at<Object>(2);
+  // Figure out first if a slow check is needed for this object.
+  bool slow_check_needed = false;
+  if (cache_type->IsMap()) {
+    if (object->map() != Map::cast(*cache_type)) {
+      // Object transitioned.  Need slow check.
+      slow_check_needed = true;
+    }
+  } else {
+    // No slow check needed for proxies.
+    slow_check_needed = Smi::cast(*cache_type)->value() == 1;
+  }
+  return MakePair(array->get(index),
+                  isolate->heap()->ToBoolean(slow_check_needed));
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsArray) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  return isolate->heap()->ToBoolean(obj->IsJSArray());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_HasCachedArrayIndex) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  return isolate->heap()->false_value();
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_GetCachedArrayIndex) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_FastOneByteArrayJoin) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  return isolate->heap()->undefined_value();
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-classes.cc b/src/runtime/runtime-classes.cc
new file mode 100644
index 0000000..7c827f0
--- /dev/null
+++ b/src/runtime/runtime-classes.cc
@@ -0,0 +1,488 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdlib.h>
+#include <limits>
+
+#include "src/v8.h"
+
+#include "src/isolate-inl.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+
+
+namespace v8 {
+namespace internal {
+
+
+RUNTIME_FUNCTION(Runtime_ThrowNonMethodError) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  THROW_NEW_ERROR_RETURN_FAILURE(
+      isolate, NewReferenceError("non_method", HandleVector<Object>(NULL, 0)));
+}
+
+
+static Object* ThrowUnsupportedSuper(Isolate* isolate) {
+  THROW_NEW_ERROR_RETURN_FAILURE(
+      isolate,
+      NewReferenceError("unsupported_super", HandleVector<Object>(NULL, 0)));
+}
+
+
+RUNTIME_FUNCTION(Runtime_ThrowUnsupportedSuperError) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  return ThrowUnsupportedSuper(isolate);
+}
+
+
+RUNTIME_FUNCTION(Runtime_ToMethod) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
+  Handle<JSFunction> clone = JSFunction::CloneClosure(fun);
+  Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol());
+  JSObject::SetOwnPropertyIgnoreAttributes(clone, home_object_symbol,
+                                           home_object, DONT_ENUM).Assert();
+  return *clone;
+}
+
+
+RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
+  DCHECK(args.length() == 0);
+  return isolate->heap()->home_object_symbol();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DefineClass) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 6);
+  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Script, script, 3);
+  CONVERT_SMI_ARG_CHECKED(start_position, 4);
+  CONVERT_SMI_ARG_CHECKED(end_position, 5);
+
+  Handle<Object> prototype_parent;
+  Handle<Object> constructor_parent;
+
+  if (super_class->IsTheHole()) {
+    prototype_parent = isolate->initial_object_prototype();
+  } else {
+    if (super_class->IsNull()) {
+      prototype_parent = isolate->factory()->null_value();
+    } else if (super_class->IsSpecFunction()) {
+      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+          isolate, prototype_parent,
+          Runtime::GetObjectProperty(isolate, super_class,
+                                     isolate->factory()->prototype_string()));
+      if (!prototype_parent->IsNull() && !prototype_parent->IsSpecObject()) {
+        Handle<Object> args[1] = {prototype_parent};
+        THROW_NEW_ERROR_RETURN_FAILURE(
+            isolate, NewTypeError("prototype_parent_not_an_object",
+                                  HandleVector(args, 1)));
+      }
+      constructor_parent = super_class;
+    } else {
+      // TODO(arv): Should be IsConstructor.
+      Handle<Object> args[1] = {super_class};
+      THROW_NEW_ERROR_RETURN_FAILURE(
+          isolate,
+          NewTypeError("extends_value_not_a_function", HandleVector(args, 1)));
+    }
+  }
+
+  Handle<Map> map =
+      isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+  map->SetPrototype(prototype_parent);
+  map->set_constructor(*constructor);
+  Handle<JSObject> prototype = isolate->factory()->NewJSObjectFromMap(map);
+
+  Handle<String> name_string = name->IsString()
+                                   ? Handle<String>::cast(name)
+                                   : isolate->factory()->empty_string();
+  constructor->shared()->set_name(*name_string);
+
+  JSFunction::SetPrototype(constructor, prototype);
+  PropertyAttributes attribs =
+      static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE | READ_ONLY);
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                   constructor, isolate->factory()->prototype_string(),
+                   prototype, attribs));
+
+  // TODO(arv): Only do this conditionally.
+  Handle<Symbol> home_object_symbol(isolate->heap()->home_object_symbol());
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                   constructor, home_object_symbol, prototype, DONT_ENUM));
+
+  if (!constructor_parent.is_null()) {
+    RETURN_FAILURE_ON_EXCEPTION(
+        isolate,
+        JSObject::SetPrototype(constructor, constructor_parent, false));
+  }
+
+  JSObject::AddProperty(prototype, isolate->factory()->constructor_string(),
+                        constructor, DONT_ENUM);
+
+  // Install private properties that are used to construct the FunctionToString.
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, Object::SetProperty(constructor,
+                                   isolate->factory()->class_script_symbol(),
+                                   script, STRICT));
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate,
+      Object::SetProperty(
+          constructor, isolate->factory()->class_start_position_symbol(),
+          handle(Smi::FromInt(start_position), isolate), STRICT));
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, Object::SetProperty(
+                   constructor, isolate->factory()->class_end_position_symbol(),
+                   handle(Smi::FromInt(end_position), isolate), STRICT));
+
+  return *constructor;
+}
+
+
+RUNTIME_FUNCTION(Runtime_DefineClassMethod) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 2);
+
+  uint32_t index;
+  if (key->ToArrayIndex(&index)) {
+    RETURN_FAILURE_ON_EXCEPTION(
+        isolate, JSObject::SetOwnElement(object, index, function, STRICT));
+  }
+
+  Handle<Name> name;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
+                                     Runtime::ToName(isolate, key));
+  if (name->AsArrayIndex(&index)) {
+    RETURN_FAILURE_ON_EXCEPTION(
+        isolate, JSObject::SetOwnElement(object, index, function, STRICT));
+  } else {
+    RETURN_FAILURE_ON_EXCEPTION(
+        isolate,
+        JSObject::SetOwnPropertyIgnoreAttributes(object, name, function, NONE));
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DefineClassGetter) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, getter, 2);
+
+  Handle<Name> name;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
+                                     Runtime::ToName(isolate, key));
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate,
+      JSObject::DefineAccessor(object, name, getter,
+                               isolate->factory()->null_value(), NONE));
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DefineClassSetter) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, setter, 2);
+
+  Handle<Name> name;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
+                                     Runtime::ToName(isolate, key));
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate,
+      JSObject::DefineAccessor(object, name, isolate->factory()->null_value(),
+                               setter, NONE));
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_ClassGetSourceCode) {
+  HandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+
+  Handle<Object> script;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, script,
+      Object::GetProperty(fun, isolate->factory()->class_script_symbol()));
+  if (!script->IsScript()) {
+    return isolate->heap()->undefined_value();
+  }
+
+  Handle<Symbol> start_position_symbol(
+      isolate->heap()->class_start_position_symbol());
+  Handle<Object> start_position;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, start_position, Object::GetProperty(fun, start_position_symbol));
+
+  Handle<Symbol> end_position_symbol(
+      isolate->heap()->class_end_position_symbol());
+  Handle<Object> end_position;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, end_position, Object::GetProperty(fun, end_position_symbol));
+
+  if (!start_position->IsSmi() || !end_position->IsSmi() ||
+      !Handle<Script>::cast(script)->HasValidSource()) {
+    return isolate->ThrowIllegalOperation();
+  }
+
+  Handle<String> source(String::cast(Handle<Script>::cast(script)->source()));
+  return *isolate->factory()->NewSubString(
+      source, Handle<Smi>::cast(start_position)->value(),
+      Handle<Smi>::cast(end_position)->value());
+}
+
+
+static Object* LoadFromSuper(Isolate* isolate, Handle<Object> receiver,
+                             Handle<JSObject> home_object, Handle<Name> name) {
+  if (home_object->IsAccessCheckNeeded() &&
+      !isolate->MayNamedAccess(home_object, name, v8::ACCESS_GET)) {
+    isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_GET);
+    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+  }
+
+  PrototypeIterator iter(isolate, home_object);
+  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
+  if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
+
+  LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, Object::GetProperty(&it));
+  return *result;
+}
+
+
+static Object* LoadElementFromSuper(Isolate* isolate, Handle<Object> receiver,
+                                    Handle<JSObject> home_object,
+                                    uint32_t index) {
+  if (home_object->IsAccessCheckNeeded() &&
+      !isolate->MayIndexedAccess(home_object, index, v8::ACCESS_GET)) {
+    isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_GET);
+    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+  }
+
+  PrototypeIterator iter(isolate, home_object);
+  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
+  if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Object::GetElementWithReceiver(isolate, proto, receiver, index));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
+
+  return LoadFromSuper(isolate, receiver, home_object, name);
+}
+
+
+RUNTIME_FUNCTION(Runtime_LoadKeyedFromSuper) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
+
+  uint32_t index;
+  if (key->ToArrayIndex(&index)) {
+    return LoadElementFromSuper(isolate, receiver, home_object, index);
+  }
+
+  Handle<Name> name;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
+                                     Runtime::ToName(isolate, key));
+  if (name->AsArrayIndex(&index)) {
+    return LoadElementFromSuper(isolate, receiver, home_object, index);
+  }
+  return LoadFromSuper(isolate, receiver, home_object, name);
+}
+
+
+static Object* StoreToSuper(Isolate* isolate, Handle<JSObject> home_object,
+                            Handle<Object> receiver, Handle<Name> name,
+                            Handle<Object> value, StrictMode strict_mode) {
+  if (home_object->IsAccessCheckNeeded() &&
+      !isolate->MayNamedAccess(home_object, name, v8::ACCESS_SET)) {
+    isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_SET);
+    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+  }
+
+  PrototypeIterator iter(isolate, home_object);
+  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
+  if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
+
+  LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Object::SetProperty(&it, value, strict_mode,
+                          Object::CERTAINLY_NOT_STORE_FROM_KEYED,
+                          Object::SUPER_PROPERTY));
+  return *result;
+}
+
+
+static Object* StoreElementToSuper(Isolate* isolate,
+                                   Handle<JSObject> home_object,
+                                   Handle<Object> receiver, uint32_t index,
+                                   Handle<Object> value,
+                                   StrictMode strict_mode) {
+  if (home_object->IsAccessCheckNeeded() &&
+      !isolate->MayIndexedAccess(home_object, index, v8::ACCESS_SET)) {
+    isolate->ReportFailedAccessCheck(home_object, v8::ACCESS_SET);
+    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+  }
+
+  PrototypeIterator iter(isolate, home_object);
+  Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
+  if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Object::SetElementWithReceiver(isolate, proto, receiver, index, value,
+                                     strict_mode));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
+
+  return StoreToSuper(isolate, home_object, receiver, name, value, STRICT);
+}
+
+
+RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
+
+  return StoreToSuper(isolate, home_object, receiver, name, value, SLOPPY);
+}
+
+
+static Object* StoreKeyedToSuper(Isolate* isolate, Handle<JSObject> home_object,
+                                 Handle<Object> receiver, Handle<Object> key,
+                                 Handle<Object> value, StrictMode strict_mode) {
+  uint32_t index;
+
+  if (key->ToArrayIndex(&index)) {
+    return StoreElementToSuper(isolate, home_object, receiver, index, value,
+                               strict_mode);
+  }
+  Handle<Name> name;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
+                                     Runtime::ToName(isolate, key));
+  if (name->AsArrayIndex(&index)) {
+    return StoreElementToSuper(isolate, home_object, receiver, index, value,
+                               strict_mode);
+  }
+  return StoreToSuper(isolate, home_object, receiver, name, value, strict_mode);
+}
+
+
+RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Strict) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
+
+  return StoreKeyedToSuper(isolate, home_object, receiver, key, value, STRICT);
+}
+
+
+RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
+
+  return StoreKeyedToSuper(isolate, home_object, receiver, key, value, SLOPPY);
+}
+
+
+RUNTIME_FUNCTION(Runtime_DefaultConstructorSuperCall) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+
+  // Compute the frame holding the arguments.
+  JavaScriptFrameIterator it(isolate);
+  it.AdvanceToArgumentsFrame();
+  JavaScriptFrame* frame = it.frame();
+
+  Handle<JSFunction> function(frame->function(), isolate);
+  Handle<Object> receiver(frame->receiver(), isolate);
+
+  Handle<Object> proto_function;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, proto_function,
+                                     Runtime::GetPrototype(isolate, function));
+
+  // Get the actual number of provided arguments.
+  const int argc = frame->ComputeParametersCount();
+
+  // Loose upper bound to allow fuzzing. We'll most likely run out of
+  // stack space before hitting this limit.
+  static int kMaxArgc = 1000000;
+  RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
+
+  // If there are too many arguments, allocate argv via malloc.
+  const int argv_small_size = 10;
+  Handle<Object> argv_small_buffer[argv_small_size];
+  SmartArrayPointer<Handle<Object> > argv_large_buffer;
+  Handle<Object>* argv = argv_small_buffer;
+  if (argc > argv_small_size) {
+    argv = new Handle<Object>[argc];
+    if (argv == NULL) return isolate->StackOverflow();
+    argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
+  }
+
+  for (int i = 0; i < argc; ++i) {
+    argv[i] = handle(frame->GetParameter(i), isolate);
+  }
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Execution::Call(isolate, proto_function, receiver, argc, argv, false));
+  return *result;
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-collections.cc b/src/runtime/runtime-collections.cc
new file mode 100644
index 0000000..abdd056
--- /dev/null
+++ b/src/runtime/runtime-collections.cc
@@ -0,0 +1,427 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/runtime/runtime-utils.h"
+
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_SetInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  Handle<OrderedHashSet> table = isolate->factory()->NewOrderedHashSet();
+  holder->set_table(*table);
+  return *holder;
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetAdd) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+  table = OrderedHashSet::Add(table, key);
+  holder->set_table(*table);
+  return *holder;
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetHas) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+  return isolate->heap()->ToBoolean(table->Contains(key));
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetDelete) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+  bool was_present = false;
+  table = OrderedHashSet::Remove(table, key, &was_present);
+  holder->set_table(*table);
+  return isolate->heap()->ToBoolean(was_present);
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetClear) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+  table = OrderedHashSet::Clear(table);
+  holder->set_table(*table);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetGetSize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()));
+  return Smi::FromInt(table->NumberOfElements());
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetIteratorInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSSet, set, 1);
+  CONVERT_SMI_ARG_CHECKED(kind, 2)
+  RUNTIME_ASSERT(kind == JSSetIterator::kKindValues ||
+                 kind == JSSetIterator::kKindEntries);
+  Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()));
+  holder->set_table(*table);
+  holder->set_index(Smi::FromInt(0));
+  holder->set_kind(Smi::FromInt(kind));
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetIteratorClone) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
+
+  Handle<JSSetIterator> result = isolate->factory()->NewJSSetIterator();
+  result->set_table(holder->table());
+  result->set_index(Smi::FromInt(Smi::cast(holder->index())->value()));
+  result->set_kind(Smi::FromInt(Smi::cast(holder->kind())->value()));
+
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetIteratorNext) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(JSSetIterator, holder, 0);
+  CONVERT_ARG_CHECKED(JSArray, value_array, 1);
+  return holder->Next(value_array);
+}
+
+
+// The array returned contains the following information:
+// 0: HasMore flag
+// 1: Iteration index
+// 2: Iteration kind
+RUNTIME_FUNCTION(Runtime_SetIteratorDetails) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
+  Handle<FixedArray> details = isolate->factory()->NewFixedArray(4);
+  details->set(0, isolate->heap()->ToBoolean(holder->HasMore()));
+  details->set(1, holder->index());
+  details->set(2, holder->kind());
+  return *isolate->factory()->NewJSArrayWithElements(details);
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  Handle<OrderedHashMap> table = isolate->factory()->NewOrderedHashMap();
+  holder->set_table(*table);
+  return *holder;
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapGet) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+  Handle<Object> lookup(table->Lookup(key), isolate);
+  return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapHas) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+  Handle<Object> lookup(table->Lookup(key), isolate);
+  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapDelete) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+  bool was_present = false;
+  Handle<OrderedHashMap> new_table =
+      OrderedHashMap::Remove(table, key, &was_present);
+  holder->set_table(*new_table);
+  return isolate->heap()->ToBoolean(was_present);
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapClear) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+  table = OrderedHashMap::Clear(table);
+  holder->set_table(*table);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapSet) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+  Handle<OrderedHashMap> new_table = OrderedHashMap::Put(table, key, value);
+  holder->set_table(*new_table);
+  return *holder;
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapGetSize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()));
+  return Smi::FromInt(table->NumberOfElements());
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapIteratorInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSMap, map, 1);
+  CONVERT_SMI_ARG_CHECKED(kind, 2)
+  RUNTIME_ASSERT(kind == JSMapIterator::kKindKeys ||
+                 kind == JSMapIterator::kKindValues ||
+                 kind == JSMapIterator::kKindEntries);
+  Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()));
+  holder->set_table(*table);
+  holder->set_index(Smi::FromInt(0));
+  holder->set_kind(Smi::FromInt(kind));
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapIteratorClone) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
+
+  Handle<JSMapIterator> result = isolate->factory()->NewJSMapIterator();
+  result->set_table(holder->table());
+  result->set_index(Smi::FromInt(Smi::cast(holder->index())->value()));
+  result->set_kind(Smi::FromInt(Smi::cast(holder->kind())->value()));
+
+  return *result;
+}
+
+
+// The array returned contains the following information:
+// 0: HasMore flag
+// 1: Iteration index
+// 2: Iteration kind
+RUNTIME_FUNCTION(Runtime_MapIteratorDetails) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
+  Handle<FixedArray> details = isolate->factory()->NewFixedArray(4);
+  details->set(0, isolate->heap()->ToBoolean(holder->HasMore()));
+  details->set(1, holder->index());
+  details->set(2, holder->kind());
+  return *isolate->factory()->NewJSArrayWithElements(details);
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
+  CONVERT_NUMBER_CHECKED(int, max_entries, Int32, args[1]);
+  RUNTIME_ASSERT(max_entries >= 0);
+
+  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+  if (max_entries == 0 || max_entries > table->NumberOfElements()) {
+    max_entries = table->NumberOfElements();
+  }
+  Handle<FixedArray> entries =
+      isolate->factory()->NewFixedArray(max_entries * 2);
+  {
+    DisallowHeapAllocation no_gc;
+    int count = 0;
+    for (int i = 0; count / 2 < max_entries && i < table->Capacity(); i++) {
+      Handle<Object> key(table->KeyAt(i), isolate);
+      if (table->IsKey(*key)) {
+        entries->set(count++, *key);
+        Object* value = table->Lookup(key);
+        entries->set(count++, value);
+      }
+    }
+    DCHECK_EQ(max_entries * 2, count);
+  }
+  return *isolate->factory()->NewJSArrayWithElements(entries);
+}
+
+
+RUNTIME_FUNCTION(Runtime_MapIteratorNext) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(JSMapIterator, holder, 0);
+  CONVERT_ARG_CHECKED(JSArray, value_array, 1);
+  return holder->Next(value_array);
+}
+
+
+static Handle<JSWeakCollection> WeakCollectionInitialize(
+    Isolate* isolate, Handle<JSWeakCollection> weak_collection) {
+  DCHECK(weak_collection->map()->inobject_properties() == 0);
+  Handle<ObjectHashTable> table = ObjectHashTable::New(isolate, 0);
+  weak_collection->set_table(*table);
+  return weak_collection;
+}
+
+
+RUNTIME_FUNCTION(Runtime_WeakCollectionInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
+  return *WeakCollectionInitialize(isolate, weak_collection);
+}
+
+
+RUNTIME_FUNCTION(Runtime_WeakCollectionGet) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
+  Handle<ObjectHashTable> table(
+      ObjectHashTable::cast(weak_collection->table()));
+  RUNTIME_ASSERT(table->IsKey(*key));
+  Handle<Object> lookup(table->Lookup(key), isolate);
+  return lookup->IsTheHole() ? isolate->heap()->undefined_value() : *lookup;
+}
+
+
+RUNTIME_FUNCTION(Runtime_WeakCollectionHas) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
+  Handle<ObjectHashTable> table(
+      ObjectHashTable::cast(weak_collection->table()));
+  RUNTIME_ASSERT(table->IsKey(*key));
+  Handle<Object> lookup(table->Lookup(key), isolate);
+  return isolate->heap()->ToBoolean(!lookup->IsTheHole());
+}
+
+
+RUNTIME_FUNCTION(Runtime_WeakCollectionDelete) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
+  Handle<ObjectHashTable> table(
+      ObjectHashTable::cast(weak_collection->table()));
+  RUNTIME_ASSERT(table->IsKey(*key));
+  bool was_present = false;
+  Handle<ObjectHashTable> new_table =
+      ObjectHashTable::Remove(table, key, &was_present);
+  weak_collection->set_table(*new_table);
+  if (*table != *new_table) {
+    // Zap the old table since we didn't record slots for its elements.
+    table->FillWithHoles(0, table->length());
+  }
+  return isolate->heap()->ToBoolean(was_present);
+}
+
+
+RUNTIME_FUNCTION(Runtime_WeakCollectionSet) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, weak_collection, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  RUNTIME_ASSERT(key->IsJSReceiver() || key->IsSymbol());
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  Handle<ObjectHashTable> table(
+      ObjectHashTable::cast(weak_collection->table()));
+  RUNTIME_ASSERT(table->IsKey(*key));
+  Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
+  weak_collection->set_table(*new_table);
+  if (*table != *new_table) {
+    // Zap the old table since we didn't record slots for its elements.
+    table->FillWithHoles(0, table->length());
+  }
+  return *weak_collection;
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetWeakSetValues) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSWeakCollection, holder, 0);
+  CONVERT_NUMBER_CHECKED(int, max_values, Int32, args[1]);
+  RUNTIME_ASSERT(max_values >= 0);
+
+  Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
+  if (max_values == 0 || max_values > table->NumberOfElements()) {
+    max_values = table->NumberOfElements();
+  }
+  Handle<FixedArray> values = isolate->factory()->NewFixedArray(max_values);
+  // Recompute max_values because GC could have removed elements from the table.
+  if (max_values > table->NumberOfElements()) {
+    max_values = table->NumberOfElements();
+  }
+  {
+    DisallowHeapAllocation no_gc;
+    int count = 0;
+    for (int i = 0; count < max_values && i < table->Capacity(); i++) {
+      Handle<Object> key(table->KeyAt(i), isolate);
+      if (table->IsKey(*key)) values->set(count++, *key);
+    }
+    DCHECK_EQ(max_values, count);
+  }
+  return *isolate->factory()->NewJSArrayWithElements(values);
+}
+
+
+RUNTIME_FUNCTION(Runtime_ObservationWeakMapCreate) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  // TODO(adamk): Currently this runtime function is only called three times per
+  // isolate. If it's called more often, the map should be moved into the
+  // strong root list.
+  Handle<Map> map =
+      isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
+  Handle<JSWeakMap> weakmap =
+      Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
+  return *WeakCollectionInitialize(isolate, weakmap);
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-compiler.cc b/src/runtime/runtime-compiler.cc
new file mode 100644
index 0000000..ebd0c13
--- /dev/null
+++ b/src/runtime/runtime-compiler.cc
@@ -0,0 +1,451 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/compiler.h"
+#include "src/deoptimizer.h"
+#include "src/frames.h"
+#include "src/full-codegen.h"
+#include "src/isolate-inl.h"
+#include "src/runtime/runtime-utils.h"
+#include "src/v8threads.h"
+#include "src/vm-state-inl.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_CompileLazy) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+#ifdef DEBUG
+  if (FLAG_trace_lazy && !function->shared()->is_compiled()) {
+    PrintF("[unoptimized: ");
+    function->PrintName();
+    PrintF("]\n");
+  }
+#endif
+
+  // Compile the target function.
+  DCHECK(function->shared()->allows_lazy_compilation());
+
+  Handle<Code> code;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, code,
+                                     Compiler::GetLazyCode(function));
+  DCHECK(code->kind() == Code::FUNCTION ||
+         code->kind() == Code::OPTIMIZED_FUNCTION);
+  function->ReplaceCode(*code);
+  return *code;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CompileOptimized) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  CONVERT_BOOLEAN_ARG_CHECKED(concurrent, 1);
+  DCHECK(isolate->use_crankshaft());
+
+  Handle<Code> unoptimized(function->shared()->code());
+  if (function->shared()->optimization_disabled() ||
+      isolate->DebuggerHasBreakPoints()) {
+    // If the function is not optimizable or debugger is active continue
+    // using the code from the full compiler.
+    if (FLAG_trace_opt) {
+      PrintF("[failed to optimize ");
+      function->PrintName();
+      PrintF(": is code optimizable: %s, is debugger enabled: %s]\n",
+             function->shared()->optimization_disabled() ? "F" : "T",
+             isolate->DebuggerHasBreakPoints() ? "T" : "F");
+    }
+    function->ReplaceCode(*unoptimized);
+    return function->code();
+  }
+
+  Compiler::ConcurrencyMode mode =
+      concurrent ? Compiler::CONCURRENT : Compiler::NOT_CONCURRENT;
+  Handle<Code> code;
+  if (Compiler::GetOptimizedCode(function, unoptimized, mode).ToHandle(&code)) {
+    function->ReplaceCode(*code);
+  } else {
+    function->ReplaceCode(function->shared()->code());
+  }
+
+  DCHECK(function->code()->kind() == Code::FUNCTION ||
+         function->code()->kind() == Code::OPTIMIZED_FUNCTION ||
+         function->IsInOptimizationQueue());
+  return function->code();
+}
+
+
+RUNTIME_FUNCTION(Runtime_NotifyStubFailure) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
+  DCHECK(AllowHeapAllocation::IsAllowed());
+  delete deoptimizer;
+  return isolate->heap()->undefined_value();
+}
+
+
+class ActivationsFinder : public ThreadVisitor {
+ public:
+  Code* code_;
+  bool has_code_activations_;
+
+  explicit ActivationsFinder(Code* code)
+      : code_(code), has_code_activations_(false) {}
+
+  void VisitThread(Isolate* isolate, ThreadLocalTop* top) {
+    JavaScriptFrameIterator it(isolate, top);
+    VisitFrames(&it);
+  }
+
+  void VisitFrames(JavaScriptFrameIterator* it) {
+    for (; !it->done(); it->Advance()) {
+      JavaScriptFrame* frame = it->frame();
+      if (code_->contains(frame->pc())) has_code_activations_ = true;
+    }
+  }
+};
+
+
+RUNTIME_FUNCTION(Runtime_NotifyDeoptimized) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_SMI_ARG_CHECKED(type_arg, 0);
+  Deoptimizer::BailoutType type =
+      static_cast<Deoptimizer::BailoutType>(type_arg);
+  Deoptimizer* deoptimizer = Deoptimizer::Grab(isolate);
+  DCHECK(AllowHeapAllocation::IsAllowed());
+
+  Handle<JSFunction> function = deoptimizer->function();
+  Handle<Code> optimized_code = deoptimizer->compiled_code();
+
+  DCHECK(optimized_code->kind() == Code::OPTIMIZED_FUNCTION);
+  DCHECK(type == deoptimizer->bailout_type());
+
+  // Make sure to materialize objects before causing any allocation.
+  JavaScriptFrameIterator it(isolate);
+  deoptimizer->MaterializeHeapObjects(&it);
+  delete deoptimizer;
+
+  JavaScriptFrame* frame = it.frame();
+  RUNTIME_ASSERT(frame->function()->IsJSFunction());
+  DCHECK(frame->function() == *function);
+
+  // Avoid doing too much work when running with --always-opt and keep
+  // the optimized code around.
+  if (FLAG_always_opt || type == Deoptimizer::LAZY) {
+    return isolate->heap()->undefined_value();
+  }
+
+  // Search for other activations of the same function and code.
+  ActivationsFinder activations_finder(*optimized_code);
+  activations_finder.VisitFrames(&it);
+  isolate->thread_manager()->IterateArchivedThreads(&activations_finder);
+
+  if (!activations_finder.has_code_activations_) {
+    if (function->code() == *optimized_code) {
+      if (FLAG_trace_deopt) {
+        PrintF("[removing optimized code for: ");
+        function->PrintName();
+        PrintF("]\n");
+      }
+      function->ReplaceCode(function->shared()->code());
+      // Evict optimized code for this function from the cache so that it
+      // doesn't get used for new closures.
+      function->shared()->EvictFromOptimizedCodeMap(*optimized_code,
+                                                    "notify deoptimized");
+    }
+  } else {
+    // TODO(titzer): we should probably do DeoptimizeCodeList(code)
+    // unconditionally if the code is not already marked for deoptimization.
+    // If there is an index by shared function info, all the better.
+    Deoptimizer::DeoptimizeFunction(*function);
+  }
+
+  return isolate->heap()->undefined_value();
+}
+
+
+static bool IsSuitableForOnStackReplacement(Isolate* isolate,
+                                            Handle<JSFunction> function,
+                                            Handle<Code> current_code) {
+  // Keep track of whether we've succeeded in optimizing.
+  if (!current_code->optimizable()) return false;
+  // If we are trying to do OSR when there are already optimized
+  // activations of the function, it means (a) the function is directly or
+  // indirectly recursive and (b) an optimized invocation has been
+  // deoptimized so that we are currently in an unoptimized activation.
+  // Check for optimized activations of this function.
+  for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
+    JavaScriptFrame* frame = it.frame();
+    if (frame->is_optimized() && frame->function() == *function) return false;
+  }
+
+  return true;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CompileForOnStackReplacement) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  Handle<Code> caller_code(function->shared()->code());
+
+  // We're not prepared to handle a function with arguments object.
+  DCHECK(!function->shared()->uses_arguments());
+
+  RUNTIME_ASSERT(FLAG_use_osr);
+
+  // Passing the PC in the javascript frame from the caller directly is
+  // not GC safe, so we walk the stack to get it.
+  JavaScriptFrameIterator it(isolate);
+  JavaScriptFrame* frame = it.frame();
+  if (!caller_code->contains(frame->pc())) {
+    // Code on the stack may not be the code object referenced by the shared
+    // function info.  It may have been replaced to include deoptimization data.
+    caller_code = Handle<Code>(frame->LookupCode());
+  }
+
+  uint32_t pc_offset =
+      static_cast<uint32_t>(frame->pc() - caller_code->instruction_start());
+
+#ifdef DEBUG
+  DCHECK_EQ(frame->function(), *function);
+  DCHECK_EQ(frame->LookupCode(), *caller_code);
+  DCHECK(caller_code->contains(frame->pc()));
+#endif  // DEBUG
+
+
+  BailoutId ast_id = caller_code->TranslatePcOffsetToAstId(pc_offset);
+  DCHECK(!ast_id.IsNone());
+
+  Compiler::ConcurrencyMode mode =
+      isolate->concurrent_osr_enabled() &&
+              (function->shared()->ast_node_count() > 512)
+          ? Compiler::CONCURRENT
+          : Compiler::NOT_CONCURRENT;
+  Handle<Code> result = Handle<Code>::null();
+
+  OptimizedCompileJob* job = NULL;
+  if (mode == Compiler::CONCURRENT) {
+    // Gate the OSR entry with a stack check.
+    BackEdgeTable::AddStackCheck(caller_code, pc_offset);
+    // Poll already queued compilation jobs.
+    OptimizingCompilerThread* thread = isolate->optimizing_compiler_thread();
+    if (thread->IsQueuedForOSR(function, ast_id)) {
+      if (FLAG_trace_osr) {
+        PrintF("[OSR - Still waiting for queued: ");
+        function->PrintName();
+        PrintF(" at AST id %d]\n", ast_id.ToInt());
+      }
+      return NULL;
+    }
+
+    job = thread->FindReadyOSRCandidate(function, ast_id);
+  }
+
+  if (job != NULL) {
+    if (FLAG_trace_osr) {
+      PrintF("[OSR - Found ready: ");
+      function->PrintName();
+      PrintF(" at AST id %d]\n", ast_id.ToInt());
+    }
+    result = Compiler::GetConcurrentlyOptimizedCode(job);
+  } else if (IsSuitableForOnStackReplacement(isolate, function, caller_code)) {
+    if (FLAG_trace_osr) {
+      PrintF("[OSR - Compiling: ");
+      function->PrintName();
+      PrintF(" at AST id %d]\n", ast_id.ToInt());
+    }
+    MaybeHandle<Code> maybe_result =
+        Compiler::GetOptimizedCode(function, caller_code, mode, ast_id);
+    if (maybe_result.ToHandle(&result) &&
+        result.is_identical_to(isolate->builtins()->InOptimizationQueue())) {
+      // Optimization is queued.  Return to check later.
+      return NULL;
+    }
+  }
+
+  // Revert the patched back edge table, regardless of whether OSR succeeds.
+  BackEdgeTable::Revert(isolate, *caller_code);
+
+  // Check whether we ended up with usable optimized code.
+  if (!result.is_null() && result->kind() == Code::OPTIMIZED_FUNCTION) {
+    DeoptimizationInputData* data =
+        DeoptimizationInputData::cast(result->deoptimization_data());
+
+    if (data->OsrPcOffset()->value() >= 0) {
+      DCHECK(BailoutId(data->OsrAstId()->value()) == ast_id);
+      if (FLAG_trace_osr) {
+        PrintF("[OSR - Entry at AST id %d, offset %d in optimized code]\n",
+               ast_id.ToInt(), data->OsrPcOffset()->value());
+      }
+      // TODO(titzer): this is a massive hack to make the deopt counts
+      // match. Fix heuristics for reenabling optimizations!
+      function->shared()->increment_deopt_count();
+
+      // TODO(titzer): Do not install code into the function.
+      function->ReplaceCode(*result);
+      return *result;
+    }
+  }
+
+  // Failed.
+  if (FLAG_trace_osr) {
+    PrintF("[OSR - Failed: ");
+    function->PrintName();
+    PrintF(" at AST id %d]\n", ast_id.ToInt());
+  }
+
+  if (!function->IsOptimized()) {
+    function->ReplaceCode(function->shared()->code());
+  }
+  return NULL;
+}
+
+
+RUNTIME_FUNCTION(Runtime_TryInstallOptimizedCode) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+
+  // First check if this is a real stack overflow.
+  StackLimitCheck check(isolate);
+  if (check.JsHasOverflowed()) {
+    SealHandleScope shs(isolate);
+    return isolate->StackOverflow();
+  }
+
+  isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
+  return (function->IsOptimized()) ? function->code()
+                                   : function->shared()->code();
+}
+
+
+bool CodeGenerationFromStringsAllowed(Isolate* isolate,
+                                      Handle<Context> context) {
+  DCHECK(context->allow_code_gen_from_strings()->IsFalse());
+  // Check with callback if set.
+  AllowCodeGenerationFromStringsCallback callback =
+      isolate->allow_code_gen_callback();
+  if (callback == NULL) {
+    // No callback set and code generation disallowed.
+    return false;
+  } else {
+    // Callback set. Let it decide if code generation is allowed.
+    VMState<EXTERNAL> state(isolate);
+    return callback(v8::Utils::ToLocal(context));
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_CompileString) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
+  CONVERT_BOOLEAN_ARG_CHECKED(function_literal_only, 1);
+  CONVERT_SMI_ARG_CHECKED(source_offset, 2);
+
+  // Extract native context.
+  Handle<Context> context(isolate->native_context());
+
+  // Check if native context allows code generation from
+  // strings. Throw an exception if it doesn't.
+  if (context->allow_code_gen_from_strings()->IsFalse() &&
+      !CodeGenerationFromStringsAllowed(isolate, context)) {
+    Handle<Object> error_message =
+        context->ErrorMessageForCodeGenerationFromStrings();
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewEvalError("code_gen_from_strings",
+                              HandleVector<Object>(&error_message, 1)));
+  }
+
+  // Compile source string in the native context.
+  ParseRestriction restriction = function_literal_only
+                                     ? ONLY_SINGLE_FUNCTION_LITERAL
+                                     : NO_PARSE_RESTRICTION;
+  Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate);
+  Handle<JSFunction> fun;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, fun,
+      Compiler::GetFunctionFromEval(source, outer_info, context, SLOPPY,
+                                    restriction, RelocInfo::kNoPosition));
+  if (function_literal_only) {
+    // The actual body is wrapped, which shifts line numbers.
+    Handle<Script> script(Script::cast(fun->shared()->script()), isolate);
+    if (script->line_offset() == 0) {
+      int line_num = Script::GetLineNumber(script, source_offset);
+      script->set_line_offset(Smi::FromInt(-line_num));
+    }
+  }
+  return *fun;
+}
+
+
+static ObjectPair CompileGlobalEval(Isolate* isolate, Handle<String> source,
+                                    Handle<SharedFunctionInfo> outer_info,
+                                    Handle<Object> receiver,
+                                    StrictMode strict_mode,
+                                    int scope_position) {
+  Handle<Context> context = Handle<Context>(isolate->context());
+  Handle<Context> native_context = Handle<Context>(context->native_context());
+
+  // Check if native context allows code generation from
+  // strings. Throw an exception if it doesn't.
+  if (native_context->allow_code_gen_from_strings()->IsFalse() &&
+      !CodeGenerationFromStringsAllowed(isolate, native_context)) {
+    Handle<Object> error_message =
+        native_context->ErrorMessageForCodeGenerationFromStrings();
+    Handle<Object> error;
+    MaybeHandle<Object> maybe_error = isolate->factory()->NewEvalError(
+        "code_gen_from_strings", HandleVector<Object>(&error_message, 1));
+    if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
+    return MakePair(isolate->heap()->exception(), NULL);
+  }
+
+  // Deal with a normal eval call with a string argument. Compile it
+  // and return the compiled function bound in the local context.
+  static const ParseRestriction restriction = NO_PARSE_RESTRICTION;
+  Handle<JSFunction> compiled;
+  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+      isolate, compiled,
+      Compiler::GetFunctionFromEval(source, outer_info, context, strict_mode,
+                                    restriction, scope_position),
+      MakePair(isolate->heap()->exception(), NULL));
+  return MakePair(*compiled, *receiver);
+}
+
+
+RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 6);
+
+  Handle<Object> callee = args.at<Object>(0);
+
+  // If "eval" didn't refer to the original GlobalEval, it's not a
+  // direct call to eval.
+  // (And even if it is, but the first argument isn't a string, just let
+  // execution default to an indirect call to eval, which will also return
+  // the first argument without doing anything).
+  if (*callee != isolate->native_context()->global_eval_fun() ||
+      !args[1]->IsString()) {
+    return MakePair(*callee, isolate->heap()->undefined_value());
+  }
+
+  DCHECK(args[4]->IsSmi());
+  DCHECK(args.smi_at(4) == SLOPPY || args.smi_at(4) == STRICT);
+  StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(4));
+  DCHECK(args[5]->IsSmi());
+  Handle<SharedFunctionInfo> outer_info(args.at<JSFunction>(2)->shared(),
+                                        isolate);
+  return CompileGlobalEval(isolate, args.at<String>(1), outer_info,
+                           args.at<Object>(3), strict_mode, args.smi_at(5));
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-date.cc b/src/runtime/runtime-date.cc
new file mode 100644
index 0000000..65d8fc6
--- /dev/null
+++ b/src/runtime/runtime-date.cc
@@ -0,0 +1,189 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/date.h"
+#include "src/dateparser-inl.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_DateMakeDay) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_SMI_ARG_CHECKED(year, 0);
+  CONVERT_SMI_ARG_CHECKED(month, 1);
+
+  int days = isolate->date_cache()->DaysFromYearMonth(year, month);
+  RUNTIME_ASSERT(Smi::IsValid(days));
+  return Smi::FromInt(days);
+}
+
+
+RUNTIME_FUNCTION(Runtime_DateSetValue) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(time, 1);
+  CONVERT_SMI_ARG_CHECKED(is_utc, 2);
+
+  DateCache* date_cache = isolate->date_cache();
+
+  Handle<Object> value;
+  ;
+  bool is_value_nan = false;
+  if (std::isnan(time)) {
+    value = isolate->factory()->nan_value();
+    is_value_nan = true;
+  } else if (!is_utc && (time < -DateCache::kMaxTimeBeforeUTCInMs ||
+                         time > DateCache::kMaxTimeBeforeUTCInMs)) {
+    value = isolate->factory()->nan_value();
+    is_value_nan = true;
+  } else {
+    time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
+    if (time < -DateCache::kMaxTimeInMs || time > DateCache::kMaxTimeInMs) {
+      value = isolate->factory()->nan_value();
+      is_value_nan = true;
+    } else {
+      value = isolate->factory()->NewNumber(DoubleToInteger(time));
+    }
+  }
+  date->SetValue(*value, is_value_nan);
+  return *value;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ThrowNotDateError) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  THROW_NEW_ERROR_RETURN_FAILURE(
+      isolate, NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
+}
+
+
+RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  if (FLAG_log_timer_events) LOG(isolate, CurrentTimeEvent());
+
+  // According to ECMA-262, section 15.9.1, page 117, the precision of
+  // the number in a Date object representing a particular instant in
+  // time is milliseconds. Therefore, we floor the result of getting
+  // the OS time.
+  double millis;
+  if (FLAG_verify_predictable) {
+    millis = 1388534400000.0;  // Jan 1 2014 00:00:00 GMT+0000
+    millis += Floor(isolate->heap()->synthetic_time());
+  } else {
+    millis = Floor(base::OS::TimeCurrentMillis());
+  }
+  return *isolate->factory()->NewNumber(millis);
+}
+
+
+RUNTIME_FUNCTION(Runtime_DateParseString) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
+
+  RUNTIME_ASSERT(output->HasFastElements());
+  JSObject::EnsureCanContainHeapObjectElements(output);
+  RUNTIME_ASSERT(output->HasFastObjectElements());
+  Handle<FixedArray> output_array(FixedArray::cast(output->elements()));
+  RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
+
+  str = String::Flatten(str);
+  DisallowHeapAllocation no_gc;
+
+  bool result;
+  String::FlatContent str_content = str->GetFlatContent();
+  if (str_content.IsOneByte()) {
+    result = DateParser::Parse(str_content.ToOneByteVector(), *output_array,
+                               isolate->unicode_cache());
+  } else {
+    DCHECK(str_content.IsTwoByte());
+    result = DateParser::Parse(str_content.ToUC16Vector(), *output_array,
+                               isolate->unicode_cache());
+  }
+
+  if (result) {
+    return *output;
+  } else {
+    return isolate->heap()->null_value();
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
+                 x <= DateCache::kMaxTimeBeforeUTCInMs);
+  const char* zone =
+      isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
+  Handle<String> result =
+      isolate->factory()->NewStringFromUtf8(CStrVector(zone)).ToHandleChecked();
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_DateToUTC) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
+                 x <= DateCache::kMaxTimeBeforeUTCInMs);
+  int64_t time = isolate->date_cache()->ToUTC(static_cast<int64_t>(x));
+
+  return *isolate->factory()->NewNumber(static_cast<double>(time));
+}
+
+
+RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
+  HandleScope hs(isolate);
+  DCHECK(args.length() == 0);
+  if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
+    Handle<FixedArray> date_cache_version =
+        isolate->factory()->NewFixedArray(1, TENURED);
+    date_cache_version->set(0, Smi::FromInt(0));
+    isolate->eternal_handles()->CreateSingleton(
+        isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
+  }
+  Handle<FixedArray> date_cache_version =
+      Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
+          EternalHandles::DATE_CACHE_VERSION));
+  // Return result as a JS array.
+  Handle<JSObject> result =
+      isolate->factory()->NewJSObject(isolate->array_function());
+  JSArray::SetContent(Handle<JSArray>::cast(result), date_cache_version);
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_DateField) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  CONVERT_SMI_ARG_CHECKED(index, 1);
+  if (!obj->IsJSDate()) {
+    HandleScope scope(isolate);
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate,
+        NewTypeError("not_date_object", HandleVector<Object>(NULL, 0)));
+  }
+  JSDate* date = JSDate::cast(obj);
+  if (index == 0) return date->value();
+  return JSDate::GetField(date, Smi::FromInt(index));
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-debug.cc b/src/runtime/runtime-debug.cc
new file mode 100644
index 0000000..9b71a4f
--- /dev/null
+++ b/src/runtime/runtime-debug.cc
@@ -0,0 +1,2819 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/accessors.h"
+#include "src/arguments.h"
+#include "src/debug.h"
+#include "src/deoptimizer.h"
+#include "src/isolate-inl.h"
+#include "src/parser.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_DebugBreak) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  isolate->debug()->HandleDebugBreak();
+  return isolate->heap()->undefined_value();
+}
+
+
+// Helper functions for wrapping and unwrapping stack frame ids.
+static Smi* WrapFrameId(StackFrame::Id id) {
+  DCHECK(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
+  return Smi::FromInt(id >> 2);
+}
+
+
+static StackFrame::Id UnwrapFrameId(int wrapped) {
+  return static_cast<StackFrame::Id>(wrapped << 2);
+}
+
+
+// Adds a JavaScript function as a debug event listener.
+// args[0]: debug event listener function to set or null or undefined for
+//          clearing the event listener function
+// args[1]: object supplied during callback
+RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  RUNTIME_ASSERT(args[0]->IsJSFunction() || args[0]->IsUndefined() ||
+                 args[0]->IsNull());
+  CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
+  isolate->debug()->SetEventListener(callback, data);
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_Break) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  isolate->stack_guard()->RequestDebugBreak();
+  return isolate->heap()->undefined_value();
+}
+
+
+static Handle<Object> DebugGetProperty(LookupIterator* it,
+                                       bool* has_caught = NULL) {
+  for (; it->IsFound(); it->Next()) {
+    switch (it->state()) {
+      case LookupIterator::NOT_FOUND:
+      case LookupIterator::TRANSITION:
+        UNREACHABLE();
+      case LookupIterator::ACCESS_CHECK:
+        // Ignore access checks.
+        break;
+      case LookupIterator::INTERCEPTOR:
+      case LookupIterator::JSPROXY:
+        return it->isolate()->factory()->undefined_value();
+      case LookupIterator::ACCESSOR: {
+        Handle<Object> accessors = it->GetAccessors();
+        if (!accessors->IsAccessorInfo()) {
+          return it->isolate()->factory()->undefined_value();
+        }
+        MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithAccessor(
+            it->GetReceiver(), it->name(), it->GetHolder<JSObject>(),
+            accessors);
+        Handle<Object> result;
+        if (!maybe_result.ToHandle(&result)) {
+          result = handle(it->isolate()->pending_exception(), it->isolate());
+          it->isolate()->clear_pending_exception();
+          if (has_caught != NULL) *has_caught = true;
+        }
+        return result;
+      }
+
+      case LookupIterator::DATA:
+        return it->GetDataValue();
+    }
+  }
+
+  return it->isolate()->factory()->undefined_value();
+}
+
+
+// Get debugger related details for an object property, in the following format:
+// 0: Property value
+// 1: Property details
+// 2: Property value is exception
+// 3: Getter function if defined
+// 4: Setter function if defined
+// Items 2-4 are only filled if the property has either a getter or a setter.
+RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+
+  // Make sure to set the current context to the context before the debugger was
+  // entered (if the debugger is entered). The reason for switching context here
+  // is that for some property lookups (accessors and interceptors) callbacks
+  // into the embedding application can occour, and the embedding application
+  // could have the assumption that its own native context is the current
+  // context and not some internal debugger context.
+  SaveContext save(isolate);
+  if (isolate->debug()->in_debug_scope()) {
+    isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
+  }
+
+  // Check if the name is trivially convertible to an index and get the element
+  // if so.
+  uint32_t index;
+  if (name->AsArrayIndex(&index)) {
+    Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
+    Handle<Object> element_or_char;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, element_or_char,
+        Runtime::GetElementOrCharAt(isolate, obj, index));
+    details->set(0, *element_or_char);
+    details->set(1, PropertyDetails(NONE, FIELD, 0).AsSmi());
+    return *isolate->factory()->NewJSArrayWithElements(details);
+  }
+
+  LookupIterator it(obj, name, LookupIterator::HIDDEN);
+  bool has_caught = false;
+  Handle<Object> value = DebugGetProperty(&it, &has_caught);
+  if (!it.IsFound()) return isolate->heap()->undefined_value();
+
+  Handle<Object> maybe_pair;
+  if (it.state() == LookupIterator::ACCESSOR) {
+    maybe_pair = it.GetAccessors();
+  }
+
+  // If the callback object is a fixed array then it contains JavaScript
+  // getter and/or setter.
+  bool has_js_accessors = !maybe_pair.is_null() && maybe_pair->IsAccessorPair();
+  Handle<FixedArray> details =
+      isolate->factory()->NewFixedArray(has_js_accessors ? 6 : 3);
+  details->set(0, *value);
+  // TODO(verwaest): Get rid of this random way of handling interceptors.
+  PropertyDetails d = it.state() == LookupIterator::INTERCEPTOR
+                          ? PropertyDetails(NONE, FIELD, 0)
+                          : it.property_details();
+  details->set(1, d.AsSmi());
+  details->set(
+      2, isolate->heap()->ToBoolean(it.state() == LookupIterator::INTERCEPTOR));
+  if (has_js_accessors) {
+    AccessorPair* accessors = AccessorPair::cast(*maybe_pair);
+    details->set(3, isolate->heap()->ToBoolean(has_caught));
+    details->set(4, accessors->GetComponent(ACCESSOR_GETTER));
+    details->set(5, accessors->GetComponent(ACCESSOR_SETTER));
+  }
+
+  return *isolate->factory()->NewJSArrayWithElements(details);
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+
+  LookupIterator it(obj, name);
+  return *DebugGetProperty(&it);
+}
+
+
+// Return the property type calculated from the property details.
+// args[0]: smi with property details.
+RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
+  return Smi::FromInt(static_cast<int>(details.type()));
+}
+
+
+// Return the property attribute calculated from the property details.
+// args[0]: smi with property details.
+RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
+  return Smi::FromInt(static_cast<int>(details.attributes()));
+}
+
+
+// Return the property insertion index calculated from the property details.
+// args[0]: smi with property details.
+RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
+  // TODO(verwaest): Works only for dictionary mode holders.
+  return Smi::FromInt(details.dictionary_index());
+}
+
+
+// Return property value from named interceptor.
+// args[0]: object
+// args[1]: property name
+RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  RUNTIME_ASSERT(obj->HasNamedInterceptor());
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                     JSObject::GetProperty(obj, name));
+  return *result;
+}
+
+
+// Return element value from indexed interceptor.
+// args[0]: object
+// args[1]: index
+RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  RUNTIME_ASSERT(obj->HasIndexedInterceptor());
+  CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      JSObject::GetElementWithInterceptor(obj, obj, index, true));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+  return isolate->heap()->true_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetFrameCount) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+  // Count all frames which are relevant to debugging stack trace.
+  int n = 0;
+  StackFrame::Id id = isolate->debug()->break_frame_id();
+  if (id == StackFrame::NO_ID) {
+    // If there is no JavaScript stack frame count is 0.
+    return Smi::FromInt(0);
+  }
+
+  for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
+    List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
+    it.frame()->Summarize(&frames);
+    for (int i = frames.length() - 1; i >= 0; i--) {
+      // Omit functions from native scripts.
+      if (!frames[i].function()->IsFromNativeScript()) n++;
+    }
+  }
+  return Smi::FromInt(n);
+}
+
+
+class FrameInspector {
+ public:
+  FrameInspector(JavaScriptFrame* frame, int inlined_jsframe_index,
+                 Isolate* isolate)
+      : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
+    // Calculate the deoptimized frame.
+    if (frame->is_optimized()) {
+      deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
+          frame, inlined_jsframe_index, isolate);
+    }
+    has_adapted_arguments_ = frame_->has_adapted_arguments();
+    is_bottommost_ = inlined_jsframe_index == 0;
+    is_optimized_ = frame_->is_optimized();
+  }
+
+  ~FrameInspector() {
+    // Get rid of the calculated deoptimized frame if any.
+    if (deoptimized_frame_ != NULL) {
+      Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_, isolate_);
+    }
+  }
+
+  int GetParametersCount() {
+    return is_optimized_ ? deoptimized_frame_->parameters_count()
+                         : frame_->ComputeParametersCount();
+  }
+  int expression_count() { return deoptimized_frame_->expression_count(); }
+  Object* GetFunction() {
+    return is_optimized_ ? deoptimized_frame_->GetFunction()
+                         : frame_->function();
+  }
+  Object* GetParameter(int index) {
+    return is_optimized_ ? deoptimized_frame_->GetParameter(index)
+                         : frame_->GetParameter(index);
+  }
+  Object* GetExpression(int index) {
+    return is_optimized_ ? deoptimized_frame_->GetExpression(index)
+                         : frame_->GetExpression(index);
+  }
+  int GetSourcePosition() {
+    return is_optimized_ ? deoptimized_frame_->GetSourcePosition()
+                         : frame_->LookupCode()->SourcePosition(frame_->pc());
+  }
+  bool IsConstructor() {
+    return is_optimized_ && !is_bottommost_
+               ? deoptimized_frame_->HasConstructStub()
+               : frame_->IsConstructor();
+  }
+  Object* GetContext() {
+    return is_optimized_ ? deoptimized_frame_->GetContext() : frame_->context();
+  }
+
+  // To inspect all the provided arguments the frame might need to be
+  // replaced with the arguments frame.
+  void SetArgumentsFrame(JavaScriptFrame* frame) {
+    DCHECK(has_adapted_arguments_);
+    frame_ = frame;
+    is_optimized_ = frame_->is_optimized();
+    DCHECK(!is_optimized_);
+  }
+
+ private:
+  JavaScriptFrame* frame_;
+  DeoptimizedFrameInfo* deoptimized_frame_;
+  Isolate* isolate_;
+  bool is_optimized_;
+  bool is_bottommost_;
+  bool has_adapted_arguments_;
+
+  DISALLOW_COPY_AND_ASSIGN(FrameInspector);
+};
+
+
+static const int kFrameDetailsFrameIdIndex = 0;
+static const int kFrameDetailsReceiverIndex = 1;
+static const int kFrameDetailsFunctionIndex = 2;
+static const int kFrameDetailsArgumentCountIndex = 3;
+static const int kFrameDetailsLocalCountIndex = 4;
+static const int kFrameDetailsSourcePositionIndex = 5;
+static const int kFrameDetailsConstructCallIndex = 6;
+static const int kFrameDetailsAtReturnIndex = 7;
+static const int kFrameDetailsFlagsIndex = 8;
+static const int kFrameDetailsFirstDynamicIndex = 9;
+
+
+static SaveContext* FindSavedContextForFrame(Isolate* isolate,
+                                             JavaScriptFrame* frame) {
+  SaveContext* save = isolate->save_context();
+  while (save != NULL && !save->IsBelowFrame(frame)) {
+    save = save->prev();
+  }
+  DCHECK(save != NULL);
+  return save;
+}
+
+
+// Advances the iterator to the frame that matches the index and returns the
+// inlined frame index, or -1 if not found.  Skips native JS functions.
+int Runtime::FindIndexedNonNativeFrame(JavaScriptFrameIterator* it, int index) {
+  int count = -1;
+  for (; !it->done(); it->Advance()) {
+    List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
+    it->frame()->Summarize(&frames);
+    for (int i = frames.length() - 1; i >= 0; i--) {
+      // Omit functions from native scripts.
+      if (frames[i].function()->IsFromNativeScript()) continue;
+      if (++count == index) return i;
+    }
+  }
+  return -1;
+}
+
+
+// Return an array with frame details
+// args[0]: number: break id
+// args[1]: number: frame index
+//
+// The array returned contains the following information:
+// 0: Frame id
+// 1: Receiver
+// 2: Function
+// 3: Argument count
+// 4: Local count
+// 5: Source position
+// 6: Constructor call
+// 7: Is at return
+// 8: Flags
+// Arguments name, value
+// Locals name, value
+// Return value if any
+RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
+  Heap* heap = isolate->heap();
+
+  // Find the relevant frame with the requested index.
+  StackFrame::Id id = isolate->debug()->break_frame_id();
+  if (id == StackFrame::NO_ID) {
+    // If there are no JavaScript stack frames return undefined.
+    return heap->undefined_value();
+  }
+
+  JavaScriptFrameIterator it(isolate, id);
+  // Inlined frame index in optimized frame, starting from outer function.
+  int inlined_jsframe_index = Runtime::FindIndexedNonNativeFrame(&it, index);
+  if (inlined_jsframe_index == -1) return heap->undefined_value();
+
+  FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
+  bool is_optimized = it.frame()->is_optimized();
+
+  // Traverse the saved contexts chain to find the active context for the
+  // selected frame.
+  SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
+
+  // Get the frame id.
+  Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
+
+  // Find source position in unoptimized code.
+  int position = frame_inspector.GetSourcePosition();
+
+  // Check for constructor frame.
+  bool constructor = frame_inspector.IsConstructor();
+
+  // Get scope info and read from it for local variable information.
+  Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
+  Handle<SharedFunctionInfo> shared(function->shared());
+  Handle<ScopeInfo> scope_info(shared->scope_info());
+  DCHECK(*scope_info != ScopeInfo::Empty(isolate));
+
+  // Get the locals names and values into a temporary array.
+  int local_count = scope_info->LocalCount();
+  for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
+    // Hide compiler-introduced temporary variables, whether on the stack or on
+    // the context.
+    if (scope_info->LocalIsSynthetic(slot)) local_count--;
+  }
+
+  Handle<FixedArray> locals =
+      isolate->factory()->NewFixedArray(local_count * 2);
+
+  // Fill in the values of the locals.
+  int local = 0;
+  int i = 0;
+  for (; i < scope_info->StackLocalCount(); ++i) {
+    // Use the value from the stack.
+    if (scope_info->LocalIsSynthetic(i)) continue;
+    locals->set(local * 2, scope_info->LocalName(i));
+    locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
+    local++;
+  }
+  if (local < local_count) {
+    // Get the context containing declarations.
+    Handle<Context> context(
+        Context::cast(frame_inspector.GetContext())->declaration_context());
+    for (; i < scope_info->LocalCount(); ++i) {
+      if (scope_info->LocalIsSynthetic(i)) continue;
+      Handle<String> name(scope_info->LocalName(i));
+      VariableMode mode;
+      InitializationFlag init_flag;
+      MaybeAssignedFlag maybe_assigned_flag;
+      locals->set(local * 2, *name);
+      int context_slot_index = ScopeInfo::ContextSlotIndex(
+          scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
+      Object* value = context->get(context_slot_index);
+      locals->set(local * 2 + 1, value);
+      local++;
+    }
+  }
+
+  // Check whether this frame is positioned at return. If not top
+  // frame or if the frame is optimized it cannot be at a return.
+  bool at_return = false;
+  if (!is_optimized && index == 0) {
+    at_return = isolate->debug()->IsBreakAtReturn(it.frame());
+  }
+
+  // If positioned just before return find the value to be returned and add it
+  // to the frame information.
+  Handle<Object> return_value = isolate->factory()->undefined_value();
+  if (at_return) {
+    StackFrameIterator it2(isolate);
+    Address internal_frame_sp = NULL;
+    while (!it2.done()) {
+      if (it2.frame()->is_internal()) {
+        internal_frame_sp = it2.frame()->sp();
+      } else {
+        if (it2.frame()->is_java_script()) {
+          if (it2.frame()->id() == it.frame()->id()) {
+            // The internal frame just before the JavaScript frame contains the
+            // value to return on top. A debug break at return will create an
+            // internal frame to store the return value (eax/rax/r0) before
+            // entering the debug break exit frame.
+            if (internal_frame_sp != NULL) {
+              return_value =
+                  Handle<Object>(Memory::Object_at(internal_frame_sp), isolate);
+              break;
+            }
+          }
+        }
+
+        // Indicate that the previous frame was not an internal frame.
+        internal_frame_sp = NULL;
+      }
+      it2.Advance();
+    }
+  }
+
+  // Now advance to the arguments adapter frame (if any). It contains all
+  // the provided parameters whereas the function frame always have the number
+  // of arguments matching the functions parameters. The rest of the
+  // information (except for what is collected above) is the same.
+  if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
+    it.AdvanceToArgumentsFrame();
+    frame_inspector.SetArgumentsFrame(it.frame());
+  }
+
+  // Find the number of arguments to fill. At least fill the number of
+  // parameters for the function and fill more if more parameters are provided.
+  int argument_count = scope_info->ParameterCount();
+  if (argument_count < frame_inspector.GetParametersCount()) {
+    argument_count = frame_inspector.GetParametersCount();
+  }
+
+  // Calculate the size of the result.
+  int details_size = kFrameDetailsFirstDynamicIndex +
+                     2 * (argument_count + local_count) + (at_return ? 1 : 0);
+  Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
+
+  // Add the frame id.
+  details->set(kFrameDetailsFrameIdIndex, *frame_id);
+
+  // Add the function (same as in function frame).
+  details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
+
+  // Add the arguments count.
+  details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
+
+  // Add the locals count
+  details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(local_count));
+
+  // Add the source position.
+  if (position != RelocInfo::kNoPosition) {
+    details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
+  } else {
+    details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
+  }
+
+  // Add the constructor information.
+  details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
+
+  // Add the at return information.
+  details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
+
+  // Add flags to indicate information on whether this frame is
+  //   bit 0: invoked in the debugger context.
+  //   bit 1: optimized frame.
+  //   bit 2: inlined in optimized frame
+  int flags = 0;
+  if (*save->context() == *isolate->debug()->debug_context()) {
+    flags |= 1 << 0;
+  }
+  if (is_optimized) {
+    flags |= 1 << 1;
+    flags |= inlined_jsframe_index << 2;
+  }
+  details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
+
+  // Fill the dynamic part.
+  int details_index = kFrameDetailsFirstDynamicIndex;
+
+  // Add arguments name and value.
+  for (int i = 0; i < argument_count; i++) {
+    // Name of the argument.
+    if (i < scope_info->ParameterCount()) {
+      details->set(details_index++, scope_info->ParameterName(i));
+    } else {
+      details->set(details_index++, heap->undefined_value());
+    }
+
+    // Parameter value.
+    if (i < frame_inspector.GetParametersCount()) {
+      // Get the value from the stack.
+      details->set(details_index++, frame_inspector.GetParameter(i));
+    } else {
+      details->set(details_index++, heap->undefined_value());
+    }
+  }
+
+  // Add locals name and value from the temporary copy from the function frame.
+  for (int i = 0; i < local_count * 2; i++) {
+    details->set(details_index++, locals->get(i));
+  }
+
+  // Add the value being returned.
+  if (at_return) {
+    details->set(details_index++, *return_value);
+  }
+
+  // Add the receiver (same as in function frame).
+  // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
+  // THE FRAME ITERATOR TO WRAP THE RECEIVER.
+  Handle<Object> receiver(it.frame()->receiver(), isolate);
+  if (!receiver->IsJSObject() && shared->strict_mode() == SLOPPY &&
+      !function->IsBuiltin()) {
+    // If the receiver is not a JSObject and the function is not a
+    // builtin or strict-mode we have hit an optimization where a
+    // value object is not converted into a wrapped JS objects. To
+    // hide this optimization from the debugger, we wrap the receiver
+    // by creating correct wrapper object based on the calling frame's
+    // native context.
+    it.Advance();
+    if (receiver->IsUndefined()) {
+      receiver = handle(function->global_proxy());
+    } else {
+      Context* context = Context::cast(it.frame()->context());
+      Handle<Context> native_context(Context::cast(context->native_context()));
+      if (!Object::ToObject(isolate, receiver, native_context)
+               .ToHandle(&receiver)) {
+        // This only happens if the receiver is forcibly set in %_CallFunction.
+        return heap->undefined_value();
+      }
+    }
+  }
+  details->set(kFrameDetailsReceiverIndex, *receiver);
+
+  DCHECK_EQ(details_size, details_index);
+  return *isolate->factory()->NewJSArrayWithElements(details);
+}
+
+
+static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
+                                              Handle<String> parameter_name) {
+  VariableMode mode;
+  InitializationFlag init_flag;
+  MaybeAssignedFlag maybe_assigned_flag;
+  return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag,
+                                     &maybe_assigned_flag) != -1;
+}
+
+
+// Create a plain JSObject which materializes the local scope for the specified
+// frame.
+MUST_USE_RESULT
+static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
+    Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function,
+    FrameInspector* frame_inspector) {
+  Handle<SharedFunctionInfo> shared(function->shared());
+  Handle<ScopeInfo> scope_info(shared->scope_info());
+
+  // First fill all parameters.
+  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
+    // Do not materialize the parameter if it is shadowed by a context local.
+    Handle<String> name(scope_info->ParameterName(i));
+    if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
+
+    HandleScope scope(isolate);
+    Handle<Object> value(i < frame_inspector->GetParametersCount()
+                             ? frame_inspector->GetParameter(i)
+                             : isolate->heap()->undefined_value(),
+                         isolate);
+    DCHECK(!value->IsTheHole());
+
+    RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty(
+                                     isolate, target, name, value, SLOPPY),
+                        JSObject);
+  }
+
+  // Second fill all stack locals.
+  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
+    if (scope_info->LocalIsSynthetic(i)) continue;
+    Handle<String> name(scope_info->StackLocalName(i));
+    Handle<Object> value(frame_inspector->GetExpression(i), isolate);
+    if (value->IsTheHole()) continue;
+
+    RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty(
+                                     isolate, target, name, value, SLOPPY),
+                        JSObject);
+  }
+
+  return target;
+}
+
+
+static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
+                                                    Handle<JSObject> target,
+                                                    Handle<JSFunction> function,
+                                                    JavaScriptFrame* frame,
+                                                    int inlined_jsframe_index) {
+  if (inlined_jsframe_index != 0 || frame->is_optimized()) {
+    // Optimized frames are not supported.
+    // TODO(yangguo): make sure all code deoptimized when debugger is active
+    //                and assert that this cannot happen.
+    return;
+  }
+
+  Handle<SharedFunctionInfo> shared(function->shared());
+  Handle<ScopeInfo> scope_info(shared->scope_info());
+
+  // Parameters.
+  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
+    // Shadowed parameters were not materialized.
+    Handle<String> name(scope_info->ParameterName(i));
+    if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
+
+    DCHECK(!frame->GetParameter(i)->IsTheHole());
+    HandleScope scope(isolate);
+    Handle<Object> value =
+        Object::GetPropertyOrElement(target, name).ToHandleChecked();
+    frame->SetParameterValue(i, *value);
+  }
+
+  // Stack locals.
+  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
+    if (scope_info->LocalIsSynthetic(i)) continue;
+    if (frame->GetExpression(i)->IsTheHole()) continue;
+    HandleScope scope(isolate);
+    Handle<Object> value = Object::GetPropertyOrElement(
+                               target, handle(scope_info->StackLocalName(i),
+                                              isolate)).ToHandleChecked();
+    frame->SetExpression(i, *value);
+  }
+}
+
+
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
+    Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function,
+    JavaScriptFrame* frame) {
+  HandleScope scope(isolate);
+  Handle<SharedFunctionInfo> shared(function->shared());
+  Handle<ScopeInfo> scope_info(shared->scope_info());
+
+  if (!scope_info->HasContext()) return target;
+
+  // Third fill all context locals.
+  Handle<Context> frame_context(Context::cast(frame->context()));
+  Handle<Context> function_context(frame_context->declaration_context());
+  if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, function_context,
+                                                 target)) {
+    return MaybeHandle<JSObject>();
+  }
+
+  // Finally copy any properties from the function context extension.
+  // These will be variables introduced by eval.
+  if (function_context->closure() == *function) {
+    if (function_context->has_extension() &&
+        !function_context->IsNativeContext()) {
+      Handle<JSObject> ext(JSObject::cast(function_context->extension()));
+      Handle<FixedArray> keys;
+      ASSIGN_RETURN_ON_EXCEPTION(
+          isolate, keys, JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
+          JSObject);
+
+      for (int i = 0; i < keys->length(); i++) {
+        // Names of variables introduced by eval are strings.
+        DCHECK(keys->get(i)->IsString());
+        Handle<String> key(String::cast(keys->get(i)));
+        Handle<Object> value;
+        ASSIGN_RETURN_ON_EXCEPTION(
+            isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
+        RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty(
+                                         isolate, target, key, value, SLOPPY),
+                            JSObject);
+      }
+    }
+  }
+
+  return target;
+}
+
+
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScriptScope(
+    Handle<GlobalObject> global) {
+  Isolate* isolate = global->GetIsolate();
+  Handle<ScriptContextTable> script_contexts(
+      global->native_context()->script_context_table());
+
+  Handle<JSObject> script_scope =
+      isolate->factory()->NewJSObject(isolate->object_function());
+
+  for (int context_index = 0; context_index < script_contexts->used();
+       context_index++) {
+    Handle<Context> context =
+        ScriptContextTable::GetContext(script_contexts, context_index);
+    Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
+    if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
+                                                   script_scope)) {
+      return MaybeHandle<JSObject>();
+    }
+  }
+  return script_scope;
+}
+
+
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
+    Isolate* isolate, JavaScriptFrame* frame, int inlined_jsframe_index) {
+  FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
+  Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
+
+  Handle<JSObject> local_scope =
+      isolate->factory()->NewJSObject(isolate->object_function());
+  ASSIGN_RETURN_ON_EXCEPTION(
+      isolate, local_scope,
+      MaterializeStackLocalsWithFrameInspector(isolate, local_scope, function,
+                                               &frame_inspector),
+      JSObject);
+
+  return MaterializeLocalContext(isolate, local_scope, function, frame);
+}
+
+
+// Set the context local variable value.
+static bool SetContextLocalValue(Isolate* isolate, Handle<ScopeInfo> scope_info,
+                                 Handle<Context> context,
+                                 Handle<String> variable_name,
+                                 Handle<Object> new_value) {
+  for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
+    Handle<String> next_name(scope_info->ContextLocalName(i));
+    if (String::Equals(variable_name, next_name)) {
+      VariableMode mode;
+      InitializationFlag init_flag;
+      MaybeAssignedFlag maybe_assigned_flag;
+      int context_index = ScopeInfo::ContextSlotIndex(
+          scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag);
+      context->set(context_index, *new_value);
+      return true;
+    }
+  }
+
+  return false;
+}
+
+
+static bool SetLocalVariableValue(Isolate* isolate, JavaScriptFrame* frame,
+                                  int inlined_jsframe_index,
+                                  Handle<String> variable_name,
+                                  Handle<Object> new_value) {
+  if (inlined_jsframe_index != 0 || frame->is_optimized()) {
+    // Optimized frames are not supported.
+    return false;
+  }
+
+  Handle<JSFunction> function(frame->function());
+  Handle<SharedFunctionInfo> shared(function->shared());
+  Handle<ScopeInfo> scope_info(shared->scope_info());
+
+  bool default_result = false;
+
+  // Parameters.
+  for (int i = 0; i < scope_info->ParameterCount(); ++i) {
+    HandleScope scope(isolate);
+    if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
+      frame->SetParameterValue(i, *new_value);
+      // Argument might be shadowed in heap context, don't stop here.
+      default_result = true;
+    }
+  }
+
+  // Stack locals.
+  for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
+    HandleScope scope(isolate);
+    if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
+      frame->SetExpression(i, *new_value);
+      return true;
+    }
+  }
+
+  if (scope_info->HasContext()) {
+    // Context locals.
+    Handle<Context> frame_context(Context::cast(frame->context()));
+    Handle<Context> function_context(frame_context->declaration_context());
+    if (SetContextLocalValue(isolate, scope_info, function_context,
+                             variable_name, new_value)) {
+      return true;
+    }
+
+    // Function context extension. These are variables introduced by eval.
+    if (function_context->closure() == *function) {
+      if (function_context->has_extension() &&
+          !function_context->IsNativeContext()) {
+        Handle<JSObject> ext(JSObject::cast(function_context->extension()));
+
+        Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
+        DCHECK(maybe.has_value);
+        if (maybe.value) {
+          // We don't expect this to do anything except replacing
+          // property value.
+          Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
+                                     SLOPPY).Assert();
+          return true;
+        }
+      }
+    }
+  }
+
+  return default_result;
+}
+
+
+// Create a plain JSObject which materializes the closure content for the
+// context.
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
+    Isolate* isolate, Handle<Context> context) {
+  DCHECK(context->IsFunctionContext());
+
+  Handle<SharedFunctionInfo> shared(context->closure()->shared());
+  Handle<ScopeInfo> scope_info(shared->scope_info());
+
+  // Allocate and initialize a JSObject with all the content of this function
+  // closure.
+  Handle<JSObject> closure_scope =
+      isolate->factory()->NewJSObject(isolate->object_function());
+
+  // Fill all context locals to the context extension.
+  if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
+                                                 closure_scope)) {
+    return MaybeHandle<JSObject>();
+  }
+
+  // Finally copy any properties from the function context extension. This will
+  // be variables introduced by eval.
+  if (context->has_extension()) {
+    Handle<JSObject> ext(JSObject::cast(context->extension()));
+    Handle<FixedArray> keys;
+    ASSIGN_RETURN_ON_EXCEPTION(
+        isolate, keys, JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
+        JSObject);
+
+    for (int i = 0; i < keys->length(); i++) {
+      HandleScope scope(isolate);
+      // Names of variables introduced by eval are strings.
+      DCHECK(keys->get(i)->IsString());
+      Handle<String> key(String::cast(keys->get(i)));
+      Handle<Object> value;
+      ASSIGN_RETURN_ON_EXCEPTION(
+          isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
+      RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty(
+                                       closure_scope, key, value, NONE),
+                          JSObject);
+    }
+  }
+
+  return closure_scope;
+}
+
+
+// This method copies structure of MaterializeClosure method above.
+static bool SetClosureVariableValue(Isolate* isolate, Handle<Context> context,
+                                    Handle<String> variable_name,
+                                    Handle<Object> new_value) {
+  DCHECK(context->IsFunctionContext());
+
+  Handle<SharedFunctionInfo> shared(context->closure()->shared());
+  Handle<ScopeInfo> scope_info(shared->scope_info());
+
+  // Context locals to the context extension.
+  if (SetContextLocalValue(isolate, scope_info, context, variable_name,
+                           new_value)) {
+    return true;
+  }
+
+  // Properties from the function context extension. This will
+  // be variables introduced by eval.
+  if (context->has_extension()) {
+    Handle<JSObject> ext(JSObject::cast(context->extension()));
+    Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
+    DCHECK(maybe.has_value);
+    if (maybe.value) {
+      // We don't expect this to do anything except replacing property value.
+      Runtime::DefineObjectProperty(ext, variable_name, new_value, NONE)
+          .Assert();
+      return true;
+    }
+  }
+
+  return false;
+}
+
+
+static bool SetBlockContextVariableValue(Handle<Context> block_context,
+                                         Handle<String> variable_name,
+                                         Handle<Object> new_value) {
+  DCHECK(block_context->IsBlockContext());
+  Handle<ScopeInfo> scope_info(ScopeInfo::cast(block_context->extension()));
+
+  return SetContextLocalValue(block_context->GetIsolate(), scope_info,
+                              block_context, variable_name, new_value);
+}
+
+
+static bool SetScriptVariableValue(Handle<Context> context,
+                                   Handle<String> variable_name,
+                                   Handle<Object> new_value) {
+  Handle<ScriptContextTable> script_contexts(
+      context->global_object()->native_context()->script_context_table());
+  ScriptContextTable::LookupResult lookup_result;
+  if (ScriptContextTable::Lookup(script_contexts, variable_name,
+                                 &lookup_result)) {
+    Handle<Context> script_context = ScriptContextTable::GetContext(
+        script_contexts, lookup_result.context_index);
+    script_context->set(lookup_result.slot_index, *new_value);
+    return true;
+  }
+
+  return false;
+}
+
+
+// Create a plain JSObject which materializes the scope for the specified
+// catch context.
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
+    Isolate* isolate, Handle<Context> context) {
+  DCHECK(context->IsCatchContext());
+  Handle<String> name(String::cast(context->extension()));
+  Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
+                               isolate);
+  Handle<JSObject> catch_scope =
+      isolate->factory()->NewJSObject(isolate->object_function());
+  RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty(
+                                   catch_scope, name, thrown_object, NONE),
+                      JSObject);
+  return catch_scope;
+}
+
+
+static bool SetCatchVariableValue(Isolate* isolate, Handle<Context> context,
+                                  Handle<String> variable_name,
+                                  Handle<Object> new_value) {
+  DCHECK(context->IsCatchContext());
+  Handle<String> name(String::cast(context->extension()));
+  if (!String::Equals(name, variable_name)) {
+    return false;
+  }
+  context->set(Context::THROWN_OBJECT_INDEX, *new_value);
+  return true;
+}
+
+
+// Create a plain JSObject which materializes the block scope for the specified
+// block context.
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
+    Isolate* isolate, Handle<Context> context) {
+  DCHECK(context->IsBlockContext());
+  Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
+
+  // Allocate and initialize a JSObject with all the arguments, stack locals
+  // heap locals and extension properties of the debugged function.
+  Handle<JSObject> block_scope =
+      isolate->factory()->NewJSObject(isolate->object_function());
+
+  // Fill all context locals.
+  if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
+                                                 block_scope)) {
+    return MaybeHandle<JSObject>();
+  }
+
+  return block_scope;
+}
+
+
+// Create a plain JSObject which materializes the module scope for the specified
+// module context.
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
+    Isolate* isolate, Handle<Context> context) {
+  DCHECK(context->IsModuleContext());
+  Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
+
+  // Allocate and initialize a JSObject with all the members of the debugged
+  // module.
+  Handle<JSObject> module_scope =
+      isolate->factory()->NewJSObject(isolate->object_function());
+
+  // Fill all context locals.
+  if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
+                                                 module_scope)) {
+    return MaybeHandle<JSObject>();
+  }
+
+  return module_scope;
+}
+
+
+// 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 {
+    ScopeTypeGlobal = 0,
+    ScopeTypeLocal,
+    ScopeTypeWith,
+    ScopeTypeClosure,
+    ScopeTypeCatch,
+    ScopeTypeBlock,
+    ScopeTypeScript,
+    ScopeTypeModule
+  };
+
+  ScopeIterator(Isolate* isolate, JavaScriptFrame* frame,
+                int inlined_jsframe_index, bool ignore_nested_scopes = false)
+      : isolate_(isolate),
+        frame_(frame),
+        inlined_jsframe_index_(inlined_jsframe_index),
+        function_(frame->function()),
+        context_(Context::cast(frame->context())),
+        nested_scope_chain_(4),
+        seen_script_scope_(false),
+        failed_(false) {
+    // Catch the case when the debugger stops in an internal function.
+    Handle<SharedFunctionInfo> shared_info(function_->shared());
+    Handle<ScopeInfo> scope_info(shared_info->scope_info());
+    if (shared_info->script() == isolate->heap()->undefined_value()) {
+      while (context_->closure() == *function_) {
+        context_ = Handle<Context>(context_->previous(), isolate_);
+      }
+      return;
+    }
+
+    // Get the debug info (create it if it does not exist).
+    if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
+      // Return if ensuring debug info failed.
+      return;
+    }
+
+    // Currently it takes too much time to find nested scopes due to script
+    // parsing. Sometimes we want to run the ScopeIterator as fast as possible
+    // (for example, while collecting async call stacks on every
+    // addEventListener call), even if we drop some nested scopes.
+    // Later we may optimize getting the nested scopes (cache the result?)
+    // and include nested scopes into the "fast" iteration case as well.
+    if (!ignore_nested_scopes) {
+      Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
+
+      // Find the break point where execution has stopped.
+      BreakLocationIterator break_location_iterator(debug_info,
+                                                    ALL_BREAK_LOCATIONS);
+      // pc points to the instruction after the current one, possibly a break
+      // location as well. So the "- 1" to exclude it from the search.
+      break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
+
+      // Within the return sequence at the moment it is not possible to
+      // get a source position which is consistent with the current scope chain.
+      // Thus all nested with, catch and block contexts are skipped and we only
+      // provide the function scope.
+      ignore_nested_scopes = break_location_iterator.IsExit();
+    }
+
+    if (ignore_nested_scopes) {
+      if (scope_info->HasContext()) {
+        context_ = Handle<Context>(context_->declaration_context(), isolate_);
+      } else {
+        while (context_->closure() == *function_) {
+          context_ = Handle<Context>(context_->previous(), isolate_);
+        }
+      }
+      if (scope_info->scope_type() == FUNCTION_SCOPE ||
+          scope_info->scope_type() == ARROW_SCOPE) {
+        nested_scope_chain_.Add(scope_info);
+      }
+    } else {
+      // Reparse the code and analyze the scopes.
+      Handle<Script> script(Script::cast(shared_info->script()));
+      Scope* scope = NULL;
+
+      // Check whether we are in global, eval or function code.
+      Handle<ScopeInfo> scope_info(shared_info->scope_info());
+      if (scope_info->scope_type() != FUNCTION_SCOPE &&
+          scope_info->scope_type() != ARROW_SCOPE) {
+        // Global or eval code.
+        CompilationInfoWithZone info(script);
+        if (scope_info->scope_type() == SCRIPT_SCOPE) {
+          info.MarkAsGlobal();
+        } else {
+          DCHECK(scope_info->scope_type() == EVAL_SCOPE);
+          info.MarkAsEval();
+          info.SetContext(Handle<Context>(function_->context()));
+        }
+        if (Parser::Parse(&info) && Scope::Analyze(&info)) {
+          scope = info.function()->scope();
+        }
+        RetrieveScopeChain(scope, shared_info);
+      } else {
+        // Function code
+        CompilationInfoWithZone info(shared_info);
+        if (Parser::Parse(&info) && Scope::Analyze(&info)) {
+          scope = info.function()->scope();
+        }
+        RetrieveScopeChain(scope, shared_info);
+      }
+    }
+  }
+
+  ScopeIterator(Isolate* isolate, Handle<JSFunction> function)
+      : isolate_(isolate),
+        frame_(NULL),
+        inlined_jsframe_index_(0),
+        function_(function),
+        context_(function->context()),
+        seen_script_scope_(false),
+        failed_(false) {
+    if (function->IsBuiltin()) {
+      context_ = Handle<Context>();
+    }
+  }
+
+  // More scopes?
+  bool Done() {
+    DCHECK(!failed_);
+    return context_.is_null();
+  }
+
+  bool Failed() { return failed_; }
+
+  // Move to the next scope.
+  void Next() {
+    DCHECK(!failed_);
+    ScopeType scope_type = Type();
+    if (scope_type == ScopeTypeGlobal) {
+      // The global scope is always the last in the chain.
+      DCHECK(context_->IsNativeContext());
+      context_ = Handle<Context>();
+      return;
+    }
+    if (scope_type == ScopeTypeScript) seen_script_scope_ = true;
+    if (nested_scope_chain_.is_empty()) {
+      if (scope_type == ScopeTypeScript) {
+        if (context_->IsScriptContext()) {
+          context_ = Handle<Context>(context_->previous(), isolate_);
+        }
+        CHECK(context_->IsNativeContext());
+      } else {
+        context_ = Handle<Context>(context_->previous(), isolate_);
+      }
+    } else {
+      if (nested_scope_chain_.last()->HasContext()) {
+        DCHECK(context_->previous() != NULL);
+        context_ = Handle<Context>(context_->previous(), isolate_);
+      }
+      nested_scope_chain_.RemoveLast();
+    }
+  }
+
+  // Return the type of the current scope.
+  ScopeType Type() {
+    DCHECK(!failed_);
+    if (!nested_scope_chain_.is_empty()) {
+      Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
+      switch (scope_info->scope_type()) {
+        case FUNCTION_SCOPE:
+        case ARROW_SCOPE:
+          DCHECK(context_->IsFunctionContext() || !scope_info->HasContext());
+          return ScopeTypeLocal;
+        case MODULE_SCOPE:
+          DCHECK(context_->IsModuleContext());
+          return ScopeTypeModule;
+        case SCRIPT_SCOPE:
+          DCHECK(context_->IsScriptContext() || context_->IsNativeContext());
+          return ScopeTypeScript;
+        case WITH_SCOPE:
+          DCHECK(context_->IsWithContext());
+          return ScopeTypeWith;
+        case CATCH_SCOPE:
+          DCHECK(context_->IsCatchContext());
+          return ScopeTypeCatch;
+        case BLOCK_SCOPE:
+          DCHECK(!scope_info->HasContext() || context_->IsBlockContext());
+          return ScopeTypeBlock;
+        case EVAL_SCOPE:
+          UNREACHABLE();
+      }
+    }
+    if (context_->IsNativeContext()) {
+      DCHECK(context_->global_object()->IsGlobalObject());
+      // If we are at the native context and have not yet seen script scope,
+      // fake it.
+      return seen_script_scope_ ? ScopeTypeGlobal : ScopeTypeScript;
+    }
+    if (context_->IsFunctionContext()) {
+      return ScopeTypeClosure;
+    }
+    if (context_->IsCatchContext()) {
+      return ScopeTypeCatch;
+    }
+    if (context_->IsBlockContext()) {
+      return ScopeTypeBlock;
+    }
+    if (context_->IsModuleContext()) {
+      return ScopeTypeModule;
+    }
+    if (context_->IsScriptContext()) {
+      return ScopeTypeScript;
+    }
+    DCHECK(context_->IsWithContext());
+    return ScopeTypeWith;
+  }
+
+  // Return the JavaScript object with the content of the current scope.
+  MaybeHandle<JSObject> ScopeObject() {
+    DCHECK(!failed_);
+    switch (Type()) {
+      case ScopeIterator::ScopeTypeGlobal:
+        return Handle<JSObject>(CurrentContext()->global_object());
+      case ScopeIterator::ScopeTypeScript:
+        return MaterializeScriptScope(
+            Handle<GlobalObject>(CurrentContext()->global_object()));
+      case ScopeIterator::ScopeTypeLocal:
+        // Materialize the content of the local scope into a JSObject.
+        DCHECK(nested_scope_chain_.length() == 1);
+        return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
+      case ScopeIterator::ScopeTypeWith:
+        // Return the with object.
+        return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
+      case ScopeIterator::ScopeTypeCatch:
+        return MaterializeCatchScope(isolate_, CurrentContext());
+      case ScopeIterator::ScopeTypeClosure:
+        // Materialize the content of the closure scope into a JSObject.
+        return MaterializeClosure(isolate_, CurrentContext());
+      case ScopeIterator::ScopeTypeBlock:
+        return MaterializeBlockScope(isolate_, CurrentContext());
+      case ScopeIterator::ScopeTypeModule:
+        return MaterializeModuleScope(isolate_, CurrentContext());
+    }
+    UNREACHABLE();
+    return Handle<JSObject>();
+  }
+
+  bool SetVariableValue(Handle<String> variable_name,
+                        Handle<Object> new_value) {
+    DCHECK(!failed_);
+    switch (Type()) {
+      case ScopeIterator::ScopeTypeGlobal:
+        break;
+      case ScopeIterator::ScopeTypeLocal:
+        return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
+                                     variable_name, new_value);
+      case ScopeIterator::ScopeTypeWith:
+        break;
+      case ScopeIterator::ScopeTypeCatch:
+        return SetCatchVariableValue(isolate_, CurrentContext(), variable_name,
+                                     new_value);
+      case ScopeIterator::ScopeTypeClosure:
+        return SetClosureVariableValue(isolate_, CurrentContext(),
+                                       variable_name, new_value);
+      case ScopeIterator::ScopeTypeScript:
+        return SetScriptVariableValue(CurrentContext(), variable_name,
+                                      new_value);
+      case ScopeIterator::ScopeTypeBlock:
+        return SetBlockContextVariableValue(CurrentContext(), variable_name,
+                                            new_value);
+      case ScopeIterator::ScopeTypeModule:
+        // TODO(2399): should we implement it?
+        break;
+    }
+    return false;
+  }
+
+  Handle<ScopeInfo> CurrentScopeInfo() {
+    DCHECK(!failed_);
+    if (!nested_scope_chain_.is_empty()) {
+      return nested_scope_chain_.last();
+    } else if (context_->IsBlockContext()) {
+      return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
+    } else if (context_->IsFunctionContext()) {
+      return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
+    }
+    return Handle<ScopeInfo>::null();
+  }
+
+  // Return the context for this scope. For the local context there might not
+  // be an actual context.
+  Handle<Context> CurrentContext() {
+    DCHECK(!failed_);
+    if (Type() == ScopeTypeGlobal || Type() == ScopeTypeScript ||
+        nested_scope_chain_.is_empty()) {
+      return context_;
+    } else if (nested_scope_chain_.last()->HasContext()) {
+      return context_;
+    } else {
+      return Handle<Context>();
+    }
+  }
+
+#ifdef DEBUG
+  // Debug print of the content of the current scope.
+  void DebugPrint() {
+    OFStream os(stdout);
+    DCHECK(!failed_);
+    switch (Type()) {
+      case ScopeIterator::ScopeTypeGlobal:
+        os << "Global:\n";
+        CurrentContext()->Print(os);
+        break;
+
+      case ScopeIterator::ScopeTypeLocal: {
+        os << "Local:\n";
+        function_->shared()->scope_info()->Print();
+        if (!CurrentContext().is_null()) {
+          CurrentContext()->Print(os);
+          if (CurrentContext()->has_extension()) {
+            Handle<Object> extension(CurrentContext()->extension(), isolate_);
+            if (extension->IsJSContextExtensionObject()) {
+              extension->Print(os);
+            }
+          }
+        }
+        break;
+      }
+
+      case ScopeIterator::ScopeTypeWith:
+        os << "With:\n";
+        CurrentContext()->extension()->Print(os);
+        break;
+
+      case ScopeIterator::ScopeTypeCatch:
+        os << "Catch:\n";
+        CurrentContext()->extension()->Print(os);
+        CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print(os);
+        break;
+
+      case ScopeIterator::ScopeTypeClosure:
+        os << "Closure:\n";
+        CurrentContext()->Print(os);
+        if (CurrentContext()->has_extension()) {
+          Handle<Object> extension(CurrentContext()->extension(), isolate_);
+          if (extension->IsJSContextExtensionObject()) {
+            extension->Print(os);
+          }
+        }
+        break;
+
+      case ScopeIterator::ScopeTypeScript:
+        os << "Script:\n";
+        CurrentContext()
+            ->global_object()
+            ->native_context()
+            ->script_context_table()
+            ->Print(os);
+        break;
+
+      default:
+        UNREACHABLE();
+    }
+    PrintF("\n");
+  }
+#endif
+
+ private:
+  Isolate* isolate_;
+  JavaScriptFrame* frame_;
+  int inlined_jsframe_index_;
+  Handle<JSFunction> function_;
+  Handle<Context> context_;
+  List<Handle<ScopeInfo> > nested_scope_chain_;
+  bool seen_script_scope_;
+  bool failed_;
+
+  void RetrieveScopeChain(Scope* scope,
+                          Handle<SharedFunctionInfo> shared_info) {
+    if (scope != NULL) {
+      int source_position = shared_info->code()->SourcePosition(frame_->pc());
+      scope->GetNestedScopeChain(&nested_scope_chain_, source_position);
+    } else {
+      // A failed reparse indicates that the preparser has diverged from the
+      // parser or that the preparse data given to the initial parse has been
+      // faulty. We fail in debug mode but in release mode we only provide the
+      // information we get from the context chain but nothing about
+      // completely stack allocated scopes or stack allocated locals.
+      // Or it could be due to stack overflow.
+      DCHECK(isolate_->has_pending_exception());
+      failed_ = true;
+    }
+  }
+
+  DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
+};
+
+
+RUNTIME_FUNCTION(Runtime_GetScopeCount) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
+
+  // Get the frame where the debugging is performed.
+  StackFrame::Id id = UnwrapFrameId(wrapped_id);
+  JavaScriptFrameIterator it(isolate, id);
+  JavaScriptFrame* frame = it.frame();
+
+  // Count the visible scopes.
+  int n = 0;
+  for (ScopeIterator it(isolate, frame, 0); !it.Done(); it.Next()) {
+    n++;
+  }
+
+  return Smi::FromInt(n);
+}
+
+
+// Returns the list of step-in positions (text offset) in a function of the
+// stack frame in a range from the current debug break position to the end
+// of the corresponding statement.
+RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
+
+  // Get the frame where the debugging is performed.
+  StackFrame::Id id = UnwrapFrameId(wrapped_id);
+  JavaScriptFrameIterator frame_it(isolate, id);
+  RUNTIME_ASSERT(!frame_it.done());
+
+  JavaScriptFrame* frame = frame_it.frame();
+
+  Handle<JSFunction> fun = Handle<JSFunction>(frame->function());
+  Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(fun->shared());
+
+  if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
+    return isolate->heap()->undefined_value();
+  }
+
+  Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
+
+  int len = 0;
+  Handle<JSArray> array(isolate->factory()->NewJSArray(10));
+  // Find the break point where execution has stopped.
+  BreakLocationIterator break_location_iterator(debug_info,
+                                                ALL_BREAK_LOCATIONS);
+
+  break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
+  int current_statement_pos = break_location_iterator.statement_position();
+
+  while (!break_location_iterator.Done()) {
+    bool accept;
+    if (break_location_iterator.pc() > frame->pc()) {
+      accept = true;
+    } else {
+      StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
+      // The break point is near our pc. Could be a step-in possibility,
+      // that is currently taken by active debugger call.
+      if (break_frame_id == StackFrame::NO_ID) {
+        // We are not stepping.
+        accept = false;
+      } else {
+        JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
+        // If our frame is a top frame and we are stepping, we can do step-in
+        // at this place.
+        accept = additional_frame_it.frame()->id() == id;
+      }
+    }
+    if (accept) {
+      if (break_location_iterator.IsStepInLocation(isolate)) {
+        Smi* position_value = Smi::FromInt(break_location_iterator.position());
+        RETURN_FAILURE_ON_EXCEPTION(
+            isolate, JSObject::SetElement(
+                         array, len, Handle<Object>(position_value, isolate),
+                         NONE, SLOPPY));
+        len++;
+      }
+    }
+    // Advance iterator.
+    break_location_iterator.Next();
+    if (current_statement_pos != break_location_iterator.statement_position()) {
+      break;
+    }
+  }
+  return *array;
+}
+
+
+static const int kScopeDetailsTypeIndex = 0;
+static const int kScopeDetailsObjectIndex = 1;
+static const int kScopeDetailsSize = 2;
+
+
+MUST_USE_RESULT static MaybeHandle<JSObject> 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;
+  ASSIGN_RETURN_ON_EXCEPTION(isolate, scope_object, it->ScopeObject(),
+                             JSObject);
+  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
+// args[2]: number: inlined frame index
+// args[3]: number: scope index
+//
+// The array returned contains the following information:
+// 0: Scope type
+// 1: Scope object
+RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
+  CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
+  CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
+
+  // Get the frame where the debugging is performed.
+  StackFrame::Id id = UnwrapFrameId(wrapped_id);
+  JavaScriptFrameIterator frame_it(isolate, id);
+  JavaScriptFrame* frame = frame_it.frame();
+
+  // Find the requested scope.
+  int n = 0;
+  ScopeIterator it(isolate, frame, inlined_jsframe_index);
+  for (; !it.Done() && n < index; it.Next()) {
+    n++;
+  }
+  if (it.Done()) {
+    return isolate->heap()->undefined_value();
+  }
+  Handle<JSObject> details;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
+                                     MaterializeScopeDetails(isolate, &it));
+  return *details;
+}
+
+
+// Return an array of scope details
+// args[0]: number: break id
+// args[1]: number: frame index
+// args[2]: number: inlined frame index
+// args[3]: boolean: ignore nested scopes
+//
+// The array returned contains arrays with the following information:
+// 0: Scope type
+// 1: Scope object
+RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3 || args.length() == 4);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
+  CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
+
+  bool ignore_nested_scopes = false;
+  if (args.length() == 4) {
+    CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
+    ignore_nested_scopes = flag;
+  }
+
+  // Get the frame where the debugging is performed.
+  StackFrame::Id id = UnwrapFrameId(wrapped_id);
+  JavaScriptFrameIterator frame_it(isolate, id);
+  JavaScriptFrame* frame = frame_it.frame();
+
+  List<Handle<JSObject> > result(4);
+  ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes);
+  for (; !it.Done(); it.Next()) {
+    Handle<JSObject> details;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
+                                       MaterializeScopeDetails(isolate, &it));
+    result.Add(details);
+  }
+
+  Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
+  for (int i = 0; i < result.length(); ++i) {
+    array->set(i, *result[i]);
+  }
+  return *isolate->factory()->NewJSArrayWithElements(array);
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  // Check arguments.
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+
+  // Count the visible scopes.
+  int n = 0;
+  for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
+    n++;
+  }
+
+  return Smi::FromInt(n);
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
+  HandleScope scope(isolate);
+  DCHECK(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();
+  }
+
+  Handle<JSObject> details;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
+                                     MaterializeScopeDetails(isolate, &it));
+  return *details;
+}
+
+
+static bool SetScopeVariableValue(ScopeIterator* it, int index,
+                                  Handle<String> variable_name,
+                                  Handle<Object> new_value) {
+  for (int n = 0; !it->Done() && n < index; it->Next()) {
+    n++;
+  }
+  if (it->Done()) {
+    return false;
+  }
+  return it->SetVariableValue(variable_name, new_value);
+}
+
+
+// Change variable value in closure or local scope
+// args[0]: number or JsFunction: break id or function
+// args[1]: number: frame index (when arg[0] is break id)
+// args[2]: number: inlined frame index (when arg[0] is break id)
+// args[3]: number: scope index
+// args[4]: string: variable name
+// args[5]: object: new value
+//
+// Return true if success and false otherwise
+RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 6);
+
+  // Check arguments.
+  CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
+  CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
+  CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
+
+  bool res;
+  if (args[0]->IsNumber()) {
+    CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+    RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+    CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
+    CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
+
+    // Get the frame where the debugging is performed.
+    StackFrame::Id id = UnwrapFrameId(wrapped_id);
+    JavaScriptFrameIterator frame_it(isolate, id);
+    JavaScriptFrame* frame = frame_it.frame();
+
+    ScopeIterator it(isolate, frame, inlined_jsframe_index);
+    res = SetScopeVariableValue(&it, index, variable_name, new_value);
+  } else {
+    CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+    ScopeIterator it(isolate, fun);
+    res = SetScopeVariableValue(&it, index, variable_name, new_value);
+  }
+
+  return isolate->heap()->ToBoolean(res);
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+
+#ifdef DEBUG
+  // Print the scopes for the top frame.
+  StackFrameLocator locator(isolate);
+  JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
+  for (ScopeIterator it(isolate, frame, 0); !it.Done(); it.Next()) {
+    it.DebugPrint();
+  }
+#endif
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetThreadCount) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+  // Count all archived V8 threads.
+  int n = 0;
+  for (ThreadState* thread = isolate->thread_manager()->FirstThreadStateInUse();
+       thread != NULL; thread = thread->Next()) {
+    n++;
+  }
+
+  // Total number of threads is current thread and archived threads.
+  return Smi::FromInt(n + 1);
+}
+
+
+static const int kThreadDetailsCurrentThreadIndex = 0;
+static const int kThreadDetailsThreadIdIndex = 1;
+static const int kThreadDetailsSize = 2;
+
+// Return an array with thread details
+// args[0]: number: break id
+// args[1]: number: thread index
+//
+// The array returned contains the following information:
+// 0: Is current thread?
+// 1: Thread id
+RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
+
+  // Allocate array for result.
+  Handle<FixedArray> details =
+      isolate->factory()->NewFixedArray(kThreadDetailsSize);
+
+  // Thread index 0 is current thread.
+  if (index == 0) {
+    // Fill the details.
+    details->set(kThreadDetailsCurrentThreadIndex,
+                 isolate->heap()->true_value());
+    details->set(kThreadDetailsThreadIdIndex,
+                 Smi::FromInt(ThreadId::Current().ToInteger()));
+  } else {
+    // Find the thread with the requested index.
+    int n = 1;
+    ThreadState* thread = isolate->thread_manager()->FirstThreadStateInUse();
+    while (index != n && thread != NULL) {
+      thread = thread->Next();
+      n++;
+    }
+    if (thread == NULL) {
+      return isolate->heap()->undefined_value();
+    }
+
+    // Fill the details.
+    details->set(kThreadDetailsCurrentThreadIndex,
+                 isolate->heap()->false_value());
+    details->set(kThreadDetailsThreadIdIndex,
+                 Smi::FromInt(thread->id().ToInteger()));
+  }
+
+  // Convert to JS array and return.
+  return *isolate->factory()->NewJSArrayWithElements(details);
+}
+
+
+// Sets the disable break state
+// args[0]: disable break state
+RUNTIME_FUNCTION(Runtime_SetDisableBreak) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
+  isolate->debug()->set_disable_break(disable_break);
+  return isolate->heap()->undefined_value();
+}
+
+
+static bool IsPositionAlignmentCodeCorrect(int alignment) {
+  return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+  CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
+
+  if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
+    return isolate->ThrowIllegalOperation();
+  }
+  BreakPositionAlignment alignment =
+      static_cast<BreakPositionAlignment>(statement_aligned_code);
+
+  Handle<SharedFunctionInfo> shared(fun->shared());
+  // Find the number of break points
+  Handle<Object> break_locations =
+      Debug::GetSourceBreakLocations(shared, alignment);
+  if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
+  // Return array as JS array
+  return *isolate->factory()->NewJSArrayWithElements(
+      Handle<FixedArray>::cast(break_locations));
+}
+
+
+// Set a break point in a function.
+// args[0]: function
+// args[1]: number: break source position (within the function source)
+// args[2]: number: break point object
+RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
+  RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
+                 source_position <= function->shared()->end_position());
+  CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
+
+  // Set break point.
+  RUNTIME_ASSERT(isolate->debug()->SetBreakPoint(
+      function, break_point_object_arg, &source_position));
+
+  return Smi::FromInt(source_position);
+}
+
+
+// Changes the state of a break point in a script and returns source position
+// where break point was set. NOTE: Regarding performance see the NOTE for
+// GetScriptFromScriptData.
+// args[0]: script to set break point in
+// args[1]: number: break source position (within the script source)
+// args[2]: number, breakpoint position alignment
+// args[3]: number: break point object
+RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
+  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
+  RUNTIME_ASSERT(source_position >= 0);
+  CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
+  CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
+
+  if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
+    return isolate->ThrowIllegalOperation();
+  }
+  BreakPositionAlignment alignment =
+      static_cast<BreakPositionAlignment>(statement_aligned_code);
+
+  // Get the script from the script wrapper.
+  RUNTIME_ASSERT(wrapper->value()->IsScript());
+  Handle<Script> script(Script::cast(wrapper->value()));
+
+  // Set break point.
+  if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
+                                                &source_position, alignment)) {
+    return isolate->heap()->undefined_value();
+  }
+
+  return Smi::FromInt(source_position);
+}
+
+
+// Clear a break point
+// args[0]: number: break point object
+RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
+
+  // Clear break point.
+  isolate->debug()->ClearBreakPoint(break_point_object_arg);
+
+  return isolate->heap()->undefined_value();
+}
+
+
+// Change the state of break on exceptions.
+// args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
+// args[1]: Boolean indicating on/off.
+RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
+  CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
+
+  // If the number doesn't match an enum value, the ChangeBreakOnException
+  // function will default to affecting caught exceptions.
+  ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
+  // Update break point state.
+  isolate->debug()->ChangeBreakOnException(type, enable);
+  return isolate->heap()->undefined_value();
+}
+
+
+// Returns the state of break on exceptions
+// args[0]: boolean indicating uncaught exceptions
+RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
+
+  ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
+  bool result = isolate->debug()->IsBreakOnException(type);
+  return Smi::FromInt(result);
+}
+
+
+// Prepare for stepping
+// args[0]: break id for checking execution state
+// args[1]: step action from the enumeration StepAction
+// args[2]: number of times to perform the step, for step out it is the number
+//          of frames to step down.
+RUNTIME_FUNCTION(Runtime_PrepareStep) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+  if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
+    return isolate->Throw(isolate->heap()->illegal_argument_string());
+  }
+
+  CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
+
+  StackFrame::Id frame_id;
+  if (wrapped_frame_id == 0) {
+    frame_id = StackFrame::NO_ID;
+  } else {
+    frame_id = UnwrapFrameId(wrapped_frame_id);
+  }
+
+  // Get the step action and check validity.
+  StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
+  if (step_action != StepIn && step_action != StepNext &&
+      step_action != StepOut && step_action != StepInMin &&
+      step_action != StepMin && step_action != StepFrame) {
+    return isolate->Throw(isolate->heap()->illegal_argument_string());
+  }
+
+  if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
+      step_action != StepMin && step_action != StepOut) {
+    return isolate->ThrowIllegalOperation();
+  }
+
+  // Get the number of steps.
+  int step_count = NumberToInt32(args[2]);
+  if (step_count < 1) {
+    return isolate->Throw(isolate->heap()->illegal_argument_string());
+  }
+
+  // Clear all current stepping setup.
+  isolate->debug()->ClearStepping();
+
+  // Prepare step.
+  isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
+                                step_count, frame_id);
+  return isolate->heap()->undefined_value();
+}
+
+
+// Clear all stepping set by PrepareStep.
+RUNTIME_FUNCTION(Runtime_ClearStepping) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  isolate->debug()->ClearStepping();
+  return isolate->heap()->undefined_value();
+}
+
+
+// Helper function to find or create the arguments object for
+// Runtime_DebugEvaluate.
+MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
+    Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function) {
+  // Do not materialize the arguments object for eval or top-level code.
+  // Skip if "arguments" is already taken.
+  if (!function->shared()->is_function()) return target;
+  Maybe<bool> maybe = JSReceiver::HasOwnProperty(
+      target, isolate->factory()->arguments_string());
+  if (!maybe.has_value) return MaybeHandle<JSObject>();
+  if (maybe.value) return target;
+
+  // FunctionGetArguments can't throw an exception.
+  Handle<JSObject> arguments =
+      Handle<JSObject>::cast(Accessors::FunctionGetArguments(function));
+  Handle<String> arguments_str = isolate->factory()->arguments_string();
+  RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty(
+                                   target, arguments_str, arguments, NONE),
+                      JSObject);
+  return target;
+}
+
+
+// Compile and evaluate source for the given context.
+static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
+                                         Handle<SharedFunctionInfo> outer_info,
+                                         Handle<Context> context,
+                                         Handle<Object> context_extension,
+                                         Handle<Object> receiver,
+                                         Handle<String> source) {
+  if (context_extension->IsJSObject()) {
+    Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
+    Handle<JSFunction> closure(context->closure(), isolate);
+    context = isolate->factory()->NewWithContext(closure, context, extension);
+  }
+
+  Handle<JSFunction> eval_fun;
+  ASSIGN_RETURN_ON_EXCEPTION(isolate, eval_fun,
+                             Compiler::GetFunctionFromEval(
+                                 source, outer_info, context, SLOPPY,
+                                 NO_PARSE_RESTRICTION, RelocInfo::kNoPosition),
+                             Object);
+
+  Handle<Object> result;
+  ASSIGN_RETURN_ON_EXCEPTION(
+      isolate, result, Execution::Call(isolate, eval_fun, receiver, 0, NULL),
+      Object);
+
+  // Skip the global proxy as it has no properties and always delegates to the
+  // real global object.
+  if (result->IsJSGlobalProxy()) {
+    PrototypeIterator iter(isolate, result);
+    // TODO(verwaest): This will crash when the global proxy is detached.
+    result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+  }
+
+  // Clear the oneshot breakpoints so that the debugger does not step further.
+  isolate->debug()->ClearStepping();
+  return result;
+}
+
+
+static Handle<JSObject> NewJSObjectWithNullProto(Isolate* isolate) {
+  Handle<JSObject> result =
+      isolate->factory()->NewJSObject(isolate->object_function());
+  Handle<Map> new_map =
+      Map::Copy(Handle<Map>(result->map()), "ObjectWithNullProto");
+  new_map->SetPrototype(isolate->factory()->null_value());
+  JSObject::MigrateToMap(result, new_map);
+  return result;
+}
+
+
+// Evaluate a piece of JavaScript in the context of a stack frame for
+// debugging.  Things that need special attention are:
+// - Parameters and stack-allocated locals need to be materialized.  Altered
+//   values need to be written back to the stack afterwards.
+// - The arguments object needs to materialized.
+RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
+  HandleScope scope(isolate);
+
+  // Check the execution state and decode arguments frame and source to be
+  // evaluated.
+  DCHECK(args.length() == 6);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+  CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
+  CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
+  CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
+  CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
+  CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
+
+  // Handle the processing of break.
+  DisableBreak disable_break_scope(isolate->debug(), disable_break);
+
+  // Get the frame where the debugging is performed.
+  StackFrame::Id id = UnwrapFrameId(wrapped_id);
+  JavaScriptFrameIterator it(isolate, id);
+  JavaScriptFrame* frame = it.frame();
+  FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
+  Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
+  Handle<SharedFunctionInfo> outer_info(function->shared());
+
+  // Traverse the saved contexts chain to find the active context for the
+  // selected frame.
+  SaveContext* save = FindSavedContextForFrame(isolate, frame);
+
+  SaveContext savex(isolate);
+  isolate->set_context(*(save->context()));
+
+  // Materialize stack locals and the arguments object.
+  Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate);
+
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, materialized,
+      MaterializeStackLocalsWithFrameInspector(isolate, materialized, function,
+                                               &frame_inspector));
+
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, materialized,
+      MaterializeArgumentsObject(isolate, materialized, function));
+
+  // At this point, the lookup chain may look like this:
+  // [inner context] -> [function stack]+[function context] -> [outer context]
+  // The function stack is not an actual context, it complements the function
+  // context. In order to have the same lookup chain when debug-evaluating,
+  // we materialize the stack and insert it into the context chain as a
+  // with-context before the function context.
+  // [inner context] -> [with context] -> [function context] -> [outer context]
+  // Ordering the with-context before the function context forces a dynamic
+  // lookup instead of a static lookup that could fail as the scope info is
+  // outdated and may expect variables to still be stack-allocated.
+  // Afterwards, we write changes to the with-context back to the stack
+  // and remove it from the context chain.
+  // This could cause lookup failures if debug-evaluate creates a closure that
+  // uses this temporary context chain.
+
+  Handle<Context> eval_context(Context::cast(frame_inspector.GetContext()));
+  DCHECK(!eval_context.is_null());
+  Handle<Context> function_context = eval_context;
+  Handle<Context> outer_context(function->context(), isolate);
+  Handle<Context> inner_context;
+  // We iterate to find the function's context. If the function has no
+  // context-allocated variables, we iterate until we hit the outer context.
+  while (!function_context->IsFunctionContext() &&
+         !function_context->IsScriptContext() &&
+         !function_context.is_identical_to(outer_context)) {
+    inner_context = function_context;
+    function_context = Handle<Context>(function_context->previous(), isolate);
+  }
+
+  Handle<Context> materialized_context = isolate->factory()->NewWithContext(
+      function, function_context, materialized);
+
+  if (inner_context.is_null()) {
+    // No inner context. The with-context is now inner-most.
+    eval_context = materialized_context;
+  } else {
+    inner_context->set_previous(*materialized_context);
+  }
+
+  Handle<Object> receiver(frame->receiver(), isolate);
+  MaybeHandle<Object> maybe_result = DebugEvaluate(
+      isolate, outer_info, eval_context, context_extension, receiver, source);
+
+  // Remove with-context if it was inserted in between.
+  if (!inner_context.is_null()) inner_context->set_previous(*function_context);
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
+
+  // Write back potential changes to materialized stack locals to the stack.
+  UpdateStackLocalsFromMaterializedObject(isolate, materialized, function,
+                                          frame, inlined_jsframe_index);
+
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
+  HandleScope scope(isolate);
+
+  // Check the execution state and decode arguments frame and source to be
+  // evaluated.
+  DCHECK(args.length() == 4);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
+  CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
+
+  // Handle the processing of break.
+  DisableBreak disable_break_scope(isolate->debug(), disable_break);
+
+  // Enter the top context from before the debugger was invoked.
+  SaveContext save(isolate);
+  SaveContext* top = &save;
+  while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
+    top = top->prev();
+  }
+  if (top != NULL) {
+    isolate->set_context(*top->context());
+  }
+
+  // Get the native context now set to the top context from before the
+  // debugger was invoked.
+  Handle<Context> context = isolate->native_context();
+  Handle<JSObject> receiver(context->global_proxy());
+  Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, DebugEvaluate(isolate, outer_info, context,
+                                     context_extension, receiver, source));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+
+  // Fill the script objects.
+  Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
+
+  // Convert the script objects to proper JS objects.
+  for (int i = 0; i < instances->length(); i++) {
+    Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
+    // Get the script wrapper in a local handle before calling GetScriptWrapper,
+    // because using
+    //   instances->set(i, *GetScriptWrapper(script))
+    // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
+    // already have dereferenced the instances handle.
+    Handle<JSObject> wrapper = Script::GetWrapper(script);
+    instances->set(i, *wrapper);
+  }
+
+  // Return result as a JS array.
+  Handle<JSObject> result =
+      isolate->factory()->NewJSObject(isolate->array_function());
+  JSArray::SetContent(Handle<JSArray>::cast(result), instances);
+  return *result;
+}
+
+
+// Helper function used by Runtime_DebugReferencedBy below.
+static int DebugReferencedBy(HeapIterator* iterator, JSObject* target,
+                             Object* instance_filter, int max_references,
+                             FixedArray* instances, int instances_size,
+                             JSFunction* arguments_function) {
+  Isolate* isolate = target->GetIsolate();
+  SealHandleScope shs(isolate);
+  DisallowHeapAllocation no_allocation;
+
+  // Iterate the heap.
+  int count = 0;
+  JSObject* last = NULL;
+  HeapObject* heap_obj = NULL;
+  while (((heap_obj = iterator->next()) != NULL) &&
+         (max_references == 0 || count < max_references)) {
+    // Only look at all JSObjects.
+    if (heap_obj->IsJSObject()) {
+      // Skip context extension objects and argument arrays as these are
+      // checked in the context of functions using them.
+      JSObject* obj = JSObject::cast(heap_obj);
+      if (obj->IsJSContextExtensionObject() ||
+          obj->map()->constructor() == arguments_function) {
+        continue;
+      }
+
+      // Check if the JS object has a reference to the object looked for.
+      if (obj->ReferencesObject(target)) {
+        // Check instance filter if supplied. This is normally used to avoid
+        // references from mirror objects (see Runtime_IsInPrototypeChain).
+        if (!instance_filter->IsUndefined()) {
+          for (PrototypeIterator iter(isolate, obj); !iter.IsAtEnd();
+               iter.Advance()) {
+            if (iter.GetCurrent() == instance_filter) {
+              obj = NULL;  // Don't add this object.
+              break;
+            }
+          }
+        }
+
+        if (obj != NULL) {
+          // Valid reference found add to instance array if supplied an update
+          // count.
+          if (instances != NULL && count < instances_size) {
+            instances->set(count, obj);
+          }
+          last = obj;
+          count++;
+        }
+      }
+    }
+  }
+
+  // Check for circular reference only. This can happen when the object is only
+  // referenced from mirrors and has a circular reference in which case the
+  // object is not really alive and would have been garbage collected if not
+  // referenced from the mirror.
+  if (count == 1 && last == target) {
+    count = 0;
+  }
+
+  // Return the number of referencing objects found.
+  return count;
+}
+
+
+// Scan the heap for objects with direct references to an object
+// args[0]: the object to find references to
+// args[1]: constructor function for instances to exclude (Mirror)
+// args[2]: the the maximum number of objects to return
+RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+
+  // Check parameters.
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
+  RUNTIME_ASSERT(instance_filter->IsUndefined() ||
+                 instance_filter->IsJSObject());
+  CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
+  RUNTIME_ASSERT(max_references >= 0);
+
+
+  // Get the constructor function for context extension and arguments array.
+  Handle<JSFunction> arguments_function(
+      JSFunction::cast(isolate->sloppy_arguments_map()->constructor()));
+
+  // Get the number of referencing objects.
+  int count;
+  // First perform a full GC in order to avoid dead objects and to make the heap
+  // iterable.
+  Heap* heap = isolate->heap();
+  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
+  {
+    HeapIterator heap_iterator(heap);
+    count = DebugReferencedBy(&heap_iterator, *target, *instance_filter,
+                              max_references, NULL, 0, *arguments_function);
+  }
+
+  // Allocate an array to hold the result.
+  Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
+
+  // Fill the referencing objects.
+  {
+    HeapIterator heap_iterator(heap);
+    count = DebugReferencedBy(&heap_iterator, *target, *instance_filter,
+                              max_references, *instances, count,
+                              *arguments_function);
+  }
+
+  // Return result as JS array.
+  Handle<JSFunction> constructor = isolate->array_function();
+
+  Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
+  JSArray::SetContent(Handle<JSArray>::cast(result), instances);
+  return *result;
+}
+
+
+// Helper function used by Runtime_DebugConstructedBy below.
+static int DebugConstructedBy(HeapIterator* iterator, JSFunction* constructor,
+                              int max_references, FixedArray* instances,
+                              int instances_size) {
+  DisallowHeapAllocation no_allocation;
+
+  // Iterate the heap.
+  int count = 0;
+  HeapObject* heap_obj = NULL;
+  while (((heap_obj = iterator->next()) != NULL) &&
+         (max_references == 0 || count < max_references)) {
+    // Only look at all JSObjects.
+    if (heap_obj->IsJSObject()) {
+      JSObject* obj = JSObject::cast(heap_obj);
+      if (obj->map()->constructor() == constructor) {
+        // Valid reference found add to instance array if supplied an update
+        // count.
+        if (instances != NULL && count < instances_size) {
+          instances->set(count, obj);
+        }
+        count++;
+      }
+    }
+  }
+
+  // Return the number of referencing objects found.
+  return count;
+}
+
+
+// Scan the heap for objects constructed by a specific function.
+// args[0]: the constructor to find instances of
+// args[1]: the the maximum number of objects to return
+RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+
+  // Check parameters.
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
+  CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
+  RUNTIME_ASSERT(max_references >= 0);
+
+  // Get the number of referencing objects.
+  int count;
+  // First perform a full GC in order to avoid dead objects and to make the heap
+  // iterable.
+  Heap* heap = isolate->heap();
+  heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
+  {
+    HeapIterator heap_iterator(heap);
+    count = DebugConstructedBy(&heap_iterator, *constructor, max_references,
+                               NULL, 0);
+  }
+
+  // Allocate an array to hold the result.
+  Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
+
+  // Fill the referencing objects.
+  {
+    HeapIterator heap_iterator2(heap);
+    count = DebugConstructedBy(&heap_iterator2, *constructor, max_references,
+                               *instances, count);
+  }
+
+  // Return result as JS array.
+  Handle<JSFunction> array_function = isolate->array_function();
+  Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
+  JSArray::SetContent(Handle<JSArray>::cast(result), instances);
+  return *result;
+}
+
+
+// Find the effective prototype object as returned by __proto__.
+// args[0]: the object to find the prototype for.
+RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
+  HandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  return *Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
+}
+
+
+// Patches script source (should be called upon BeforeCompile event).
+RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
+
+  RUNTIME_ASSERT(script_wrapper->value()->IsScript());
+  Handle<Script> script(Script::cast(script_wrapper->value()));
+
+  int compilation_state = script->compilation_state();
+  RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
+  script->set_source(*source);
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
+  HandleScope scope(isolate);
+#ifdef DEBUG
+  DCHECK(args.length() == 1);
+  // Get the function and make sure it is compiled.
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
+  if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
+    return isolate->heap()->exception();
+  }
+  OFStream os(stdout);
+  func->code()->Print(os);
+  os << std::endl;
+#endif  // DEBUG
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
+  HandleScope scope(isolate);
+#ifdef DEBUG
+  DCHECK(args.length() == 1);
+  // Get the function and make sure it is compiled.
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
+  if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
+    return isolate->heap()->exception();
+  }
+  OFStream os(stdout);
+  func->shared()->construct_stub()->Print(os);
+  os << std::endl;
+#endif  // DEBUG
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return f->shared()->inferred_name();
+}
+
+
+// A testing entry. Returns statement position which is the closest to
+// source_position.
+RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
+  HandleScope scope(isolate);
+  CHECK(isolate->debug()->live_edit_enabled());
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
+
+  Handle<Code> code(function->code(), isolate);
+
+  if (code->kind() != Code::FUNCTION &&
+      code->kind() != Code::OPTIMIZED_FUNCTION) {
+    return isolate->heap()->undefined_value();
+  }
+
+  RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
+  int closest_pc = 0;
+  int distance = kMaxInt;
+  while (!it.done()) {
+    int statement_position = static_cast<int>(it.rinfo()->data());
+    // Check if this break point is closer that what was previously found.
+    if (source_position <= statement_position &&
+        statement_position - source_position < distance) {
+      closest_pc =
+          static_cast<int>(it.rinfo()->pc() - code->instruction_start());
+      distance = statement_position - source_position;
+      // Check whether we can't get any closer.
+      if (distance == 0) break;
+    }
+    it.next();
+  }
+
+  return Smi::FromInt(closest_pc);
+}
+
+
+// Calls specified function with or without entering the debugger.
+// This is used in unit tests to run code as if debugger is entered or simply
+// to have a stack with C++ frame in the middle.
+RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
+
+  MaybeHandle<Object> maybe_result;
+  if (without_debugger) {
+    maybe_result = Execution::Call(isolate, function,
+                                   handle(function->global_proxy()), 0, NULL);
+  } else {
+    DebugScope debug_scope(isolate->debug());
+    maybe_result = Execution::Call(isolate, function,
+                                   handle(function->global_proxy()), 0, NULL);
+  }
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
+  return *result;
+}
+
+
+// Performs a GC.
+// Presently, it only does a full GC.
+RUNTIME_FUNCTION(Runtime_CollectGarbage) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
+  return isolate->heap()->undefined_value();
+}
+
+
+// Gets the current heap usage.
+RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
+  if (!Smi::IsValid(usage)) {
+    return *isolate->factory()->NewNumberFromInt(usage);
+  }
+  return Smi::FromInt(usage);
+}
+
+
+// Finds the script object from the script data. NOTE: This operation uses
+// heap traversal to find the function generated for the source position
+// for the requested break point. For lazily compiled functions several heap
+// traversals might be required rendering this operation as a rather slow
+// operation. However for setting break points which is normally done through
+// some kind of user interaction the performance is not crucial.
+RUNTIME_FUNCTION(Runtime_GetScript) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, script_name, 0);
+
+  Handle<Script> found;
+  Heap* heap = isolate->heap();
+  {
+    HeapIterator iterator(heap);
+    HeapObject* obj = NULL;
+    while ((obj = iterator.next()) != NULL) {
+      if (!obj->IsScript()) continue;
+      Script* script = Script::cast(obj);
+      if (!script->name()->IsString()) continue;
+      String* name = String::cast(script->name());
+      if (name->Equals(*script_name)) {
+        found = Handle<Script>(script, isolate);
+        break;
+      }
+    }
+  }
+
+  if (found.is_null()) return heap->undefined_value();
+  return *Script::GetWrapper(found);
+}
+
+
+// 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(Runtime_DebugCallbackSupportsStepping) {
+  DCHECK(args.length() == 1);
+  Debug* debug = isolate->debug();
+  if (!debug->is_active() || !debug->IsStepping() ||
+      debug->last_step_action() != StepIn) {
+    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.
+  return isolate->heap()->ToBoolean(callback->IsJSFunction() &&
+                                    !JSFunction::cast(callback)->IsBuiltin());
+}
+
+
+// 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(Runtime_DebugPrepareStepInIfStepping) {
+  DCHECK(args.length() == 1);
+  Debug* debug = isolate->debug();
+  if (!debug->IsStepping()) return isolate->heap()->undefined_value();
+
+  HandleScope scope(isolate);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject());
+  Handle<JSFunction> fun;
+  if (object->IsJSFunction()) {
+    fun = Handle<JSFunction>::cast(object);
+  } else {
+    fun = Handle<JSFunction>(
+        Handle<JSGeneratorObject>::cast(object)->function(), isolate);
+  }
+  // When leaving the function, step out has been activated, but not performed
+  // if we do not leave the builtin.  To be able to step into the function
+  // again, we need to clear the step out at this point.
+  debug->ClearStepOut();
+  debug->FloodWithOneShot(fun);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
+  DCHECK(args.length() == 1);
+  HandleScope scope(isolate);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
+  isolate->PushPromise(promise);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
+  DCHECK(args.length() == 0);
+  SealHandleScope shs(isolate);
+  isolate->PopPromise();
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
+  DCHECK(args.length() == 1);
+  HandleScope scope(isolate);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
+  isolate->debug()->OnPromiseEvent(data);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
+  DCHECK(args.length() == 1);
+  HandleScope scope(isolate);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
+  isolate->debug()->OnAsyncTaskEvent(data);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_DebugIsActive) {
+  SealHandleScope shs(isolate);
+  return Smi::FromInt(isolate->debug()->is_active());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_DebugBreakInOptimizedCode) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-function.cc b/src/runtime/runtime-function.cc
new file mode 100644
index 0000000..e25b659
--- /dev/null
+++ b/src/runtime/runtime-function.cc
@@ -0,0 +1,625 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/accessors.h"
+#include "src/arguments.h"
+#include "src/compiler.h"
+#include "src/deoptimizer.h"
+#include "src/frames.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_IsSloppyModeFunction) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
+  if (!callable->IsJSFunction()) {
+    HandleScope scope(isolate);
+    Handle<Object> delegate;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, delegate, Execution::TryGetFunctionDelegate(
+                               isolate, Handle<JSReceiver>(callable)));
+    callable = JSFunction::cast(*delegate);
+  }
+  JSFunction* function = JSFunction::cast(callable);
+  SharedFunctionInfo* shared = function->shared();
+  return isolate->heap()->ToBoolean(shared->strict_mode() == SLOPPY);
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetDefaultReceiver) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSReceiver, callable, 0);
+
+  if (!callable->IsJSFunction()) {
+    HandleScope scope(isolate);
+    Handle<Object> delegate;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, delegate, Execution::TryGetFunctionDelegate(
+                               isolate, Handle<JSReceiver>(callable)));
+    callable = JSFunction::cast(*delegate);
+  }
+  JSFunction* function = JSFunction::cast(callable);
+
+  SharedFunctionInfo* shared = function->shared();
+  if (shared->native() || shared->strict_mode() == STRICT) {
+    return isolate->heap()->undefined_value();
+  }
+  // Returns undefined for strict or native functions, or
+  // the associated global receiver for "normal" functions.
+
+  return function->global_proxy();
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionGetName) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return f->shared()->name();
+}
+
+
+static Handle<String> NameToFunctionName(Handle<Name> name) {
+  Handle<String> stringName(name->GetHeap()->empty_string());
+
+  // TODO(caitp): Follow proper rules in section 9.2.11 (SetFunctionName)
+  if (name->IsSymbol()) {
+    Handle<Object> description(Handle<Symbol>::cast(name)->name(),
+                               name->GetIsolate());
+    if (description->IsString()) {
+      stringName = Handle<String>::cast(description);
+    }
+  } else {
+    stringName = Handle<String>::cast(name);
+  }
+
+  return stringName;
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionSetName) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+
+  f->shared()->set_name(*NameToFunctionName(name));
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return isolate->heap()->ToBoolean(
+      f->shared()->name_should_print_as_anonymous());
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  f->shared()->set_name_should_print_as_anonymous(true);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionIsArrow) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return isolate->heap()->ToBoolean(f->shared()->is_arrow());
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionIsConciseMethod) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return isolate->heap()->ToBoolean(f->shared()->is_concise_method());
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionRemovePrototype) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  RUNTIME_ASSERT(f->RemovePrototype());
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionGetScript) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+  Handle<Object> script = Handle<Object>(fun->shared()->script(), isolate);
+  if (!script->IsScript()) return isolate->heap()->undefined_value();
+
+  return *Script::GetWrapper(Handle<Script>::cast(script));
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionGetSourceCode) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
+  Handle<SharedFunctionInfo> shared(f->shared());
+  return *shared->GetSourceCode();
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionGetScriptSourcePosition) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+  int pos = fun->shared()->start_position();
+  return Smi::FromInt(pos);
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionGetPositionForOffset) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_CHECKED(Code, code, 0);
+  CONVERT_NUMBER_CHECKED(int, offset, Int32, args[1]);
+
+  RUNTIME_ASSERT(0 <= offset && offset < code->Size());
+
+  Address pc = code->address() + offset;
+  return Smi::FromInt(code->SourcePosition(pc));
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionSetInstanceClassName) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+  CONVERT_ARG_CHECKED(String, name, 1);
+  fun->SetInstanceClassName(name);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionSetLength) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_CHECKED(JSFunction, fun, 0);
+  CONVERT_SMI_ARG_CHECKED(length, 1);
+  RUNTIME_ASSERT((length & 0xC0000000) == 0xC0000000 ||
+                 (length & 0xC0000000) == 0x0);
+  fun->shared()->set_length(length);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionSetPrototype) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
+  RUNTIME_ASSERT(fun->should_have_prototype());
+  RETURN_FAILURE_ON_EXCEPTION(isolate,
+                              Accessors::FunctionSetPrototype(fun, value));
+  return args[0];  // return TOS
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionIsAPIFunction) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return isolate->heap()->ToBoolean(f->shared()->IsApiFunction());
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionIsBuiltin) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return isolate->heap()->ToBoolean(f->IsBuiltin());
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetCode) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, target, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, source, 1);
+
+  Handle<SharedFunctionInfo> target_shared(target->shared());
+  Handle<SharedFunctionInfo> source_shared(source->shared());
+  RUNTIME_ASSERT(!source_shared->bound());
+
+  if (!Compiler::EnsureCompiled(source, KEEP_EXCEPTION)) {
+    return isolate->heap()->exception();
+  }
+
+  // Mark both, the source and the target, as un-flushable because the
+  // shared unoptimized code makes them impossible to enqueue in a list.
+  DCHECK(target_shared->code()->gc_metadata() == NULL);
+  DCHECK(source_shared->code()->gc_metadata() == NULL);
+  target_shared->set_dont_flush(true);
+  source_shared->set_dont_flush(true);
+
+  // Set the code, scope info, formal parameter count, and the length
+  // of the target shared function info.
+  target_shared->ReplaceCode(source_shared->code());
+  target_shared->set_scope_info(source_shared->scope_info());
+  target_shared->set_length(source_shared->length());
+  target_shared->set_feedback_vector(source_shared->feedback_vector());
+  target_shared->set_formal_parameter_count(
+      source_shared->formal_parameter_count());
+  target_shared->set_script(source_shared->script());
+  target_shared->set_start_position_and_type(
+      source_shared->start_position_and_type());
+  target_shared->set_end_position(source_shared->end_position());
+  bool was_native = target_shared->native();
+  target_shared->set_compiler_hints(source_shared->compiler_hints());
+  target_shared->set_native(was_native);
+  target_shared->set_profiler_ticks(source_shared->profiler_ticks());
+
+  // Set the code of the target function.
+  target->ReplaceCode(source_shared->code());
+  DCHECK(target->next_function_link()->IsUndefined());
+
+  // Make sure we get a fresh copy of the literal vector to avoid cross
+  // context contamination.
+  Handle<Context> context(source->context());
+  int number_of_literals = source->NumberOfLiterals();
+  Handle<FixedArray> literals =
+      isolate->factory()->NewFixedArray(number_of_literals, TENURED);
+  if (number_of_literals > 0) {
+    literals->set(JSFunction::kLiteralNativeContextIndex,
+                  context->native_context());
+  }
+  target->set_context(*context);
+  target->set_literals(*literals);
+
+  if (isolate->logger()->is_logging_code_events() ||
+      isolate->cpu_profiler()->is_profiling()) {
+    isolate->logger()->LogExistingFunction(source_shared,
+                                           Handle<Code>(source_shared->code()));
+  }
+
+  return *target;
+}
+
+
+// Set the native flag on the function.
+// This is used to decide if we should transform null and undefined
+// into the global object when doing call and apply.
+RUNTIME_FUNCTION(Runtime_SetNativeFlag) {
+  SealHandleScope shs(isolate);
+  RUNTIME_ASSERT(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(Object, object, 0);
+
+  if (object->IsJSFunction()) {
+    JSFunction* func = JSFunction::cast(object);
+    func->shared()->set_native(true);
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetInlineBuiltinFlag) {
+  SealHandleScope shs(isolate);
+  RUNTIME_ASSERT(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+
+  if (object->IsJSFunction()) {
+    JSFunction* func = JSFunction::cast(*object);
+    func->shared()->set_inline_builtin(true);
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+// Find the arguments of the JavaScript function invocation that called
+// into C++ code. Collect these in a newly allocated array of handles (possibly
+// prefixed by a number of empty handles).
+static SmartArrayPointer<Handle<Object> > GetCallerArguments(Isolate* isolate,
+                                                             int prefix_argc,
+                                                             int* total_argc) {
+  // Find frame containing arguments passed to the caller.
+  JavaScriptFrameIterator it(isolate);
+  JavaScriptFrame* frame = it.frame();
+  List<JSFunction*> functions(2);
+  frame->GetFunctions(&functions);
+  if (functions.length() > 1) {
+    int inlined_jsframe_index = functions.length() - 1;
+    JSFunction* inlined_function = functions[inlined_jsframe_index];
+    SlotRefValueBuilder slot_refs(
+        frame, inlined_jsframe_index,
+        inlined_function->shared()->formal_parameter_count());
+
+    int args_count = slot_refs.args_length();
+
+    *total_argc = prefix_argc + args_count;
+    SmartArrayPointer<Handle<Object> > param_data(
+        NewArray<Handle<Object> >(*total_argc));
+    slot_refs.Prepare(isolate);
+    for (int i = 0; i < args_count; i++) {
+      Handle<Object> val = slot_refs.GetNext(isolate, 0);
+      param_data[prefix_argc + i] = val;
+    }
+    slot_refs.Finish(isolate);
+
+    return param_data;
+  } else {
+    it.AdvanceToArgumentsFrame();
+    frame = it.frame();
+    int args_count = frame->ComputeParametersCount();
+
+    *total_argc = prefix_argc + args_count;
+    SmartArrayPointer<Handle<Object> > param_data(
+        NewArray<Handle<Object> >(*total_argc));
+    for (int i = 0; i < args_count; i++) {
+      Handle<Object> val = Handle<Object>(frame->GetParameter(i), isolate);
+      param_data[prefix_argc + i] = val;
+    }
+    return param_data;
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionBindArguments) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, bound_function, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, bindee, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, this_object, 2);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(new_length, 3);
+
+  // TODO(lrn): Create bound function in C++ code from premade shared info.
+  bound_function->shared()->set_bound(true);
+  // Get all arguments of calling function (Function.prototype.bind).
+  int argc = 0;
+  SmartArrayPointer<Handle<Object> > arguments =
+      GetCallerArguments(isolate, 0, &argc);
+  // Don't count the this-arg.
+  if (argc > 0) {
+    RUNTIME_ASSERT(arguments[0].is_identical_to(this_object));
+    argc--;
+  } else {
+    RUNTIME_ASSERT(this_object->IsUndefined());
+  }
+  // Initialize array of bindings (function, this, and any existing arguments
+  // if the function was already bound).
+  Handle<FixedArray> new_bindings;
+  int i;
+  if (bindee->IsJSFunction() && JSFunction::cast(*bindee)->shared()->bound()) {
+    Handle<FixedArray> old_bindings(
+        JSFunction::cast(*bindee)->function_bindings());
+    RUNTIME_ASSERT(old_bindings->length() > JSFunction::kBoundFunctionIndex);
+    new_bindings =
+        isolate->factory()->NewFixedArray(old_bindings->length() + argc);
+    bindee = Handle<Object>(old_bindings->get(JSFunction::kBoundFunctionIndex),
+                            isolate);
+    i = 0;
+    for (int n = old_bindings->length(); i < n; i++) {
+      new_bindings->set(i, old_bindings->get(i));
+    }
+  } else {
+    int array_size = JSFunction::kBoundArgumentsStartIndex + argc;
+    new_bindings = isolate->factory()->NewFixedArray(array_size);
+    new_bindings->set(JSFunction::kBoundFunctionIndex, *bindee);
+    new_bindings->set(JSFunction::kBoundThisIndex, *this_object);
+    i = 2;
+  }
+  // Copy arguments, skipping the first which is "this_arg".
+  for (int j = 0; j < argc; j++, i++) {
+    new_bindings->set(i, *arguments[j + 1]);
+  }
+  new_bindings->set_map_no_write_barrier(
+      isolate->heap()->fixed_cow_array_map());
+  bound_function->set_function_bindings(*new_bindings);
+
+  // Update length. Have to remove the prototype first so that map migration
+  // is happy about the number of fields.
+  RUNTIME_ASSERT(bound_function->RemovePrototype());
+  Handle<Map> bound_function_map(
+      isolate->native_context()->bound_function_map());
+  JSObject::MigrateToMap(bound_function, bound_function_map);
+  Handle<String> length_string = isolate->factory()->length_string();
+  PropertyAttributes attr =
+      static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM | READ_ONLY);
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                   bound_function, length_string, new_length, attr));
+  return *bound_function;
+}
+
+
+RUNTIME_FUNCTION(Runtime_BoundFunctionGetBindings) {
+  HandleScope handles(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, callable, 0);
+  if (callable->IsJSFunction()) {
+    Handle<JSFunction> function = Handle<JSFunction>::cast(callable);
+    if (function->shared()->bound()) {
+      Handle<FixedArray> bindings(function->function_bindings());
+      RUNTIME_ASSERT(bindings->map() == isolate->heap()->fixed_cow_array_map());
+      return *isolate->factory()->NewJSArrayWithElements(bindings);
+    }
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewObjectFromBound) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  // First argument is a function to use as a constructor.
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  RUNTIME_ASSERT(function->shared()->bound());
+
+  // The argument is a bound function. Extract its bound arguments
+  // and callable.
+  Handle<FixedArray> bound_args =
+      Handle<FixedArray>(FixedArray::cast(function->function_bindings()));
+  int bound_argc = bound_args->length() - JSFunction::kBoundArgumentsStartIndex;
+  Handle<Object> bound_function(
+      JSReceiver::cast(bound_args->get(JSFunction::kBoundFunctionIndex)),
+      isolate);
+  DCHECK(!bound_function->IsJSFunction() ||
+         !Handle<JSFunction>::cast(bound_function)->shared()->bound());
+
+  int total_argc = 0;
+  SmartArrayPointer<Handle<Object> > param_data =
+      GetCallerArguments(isolate, bound_argc, &total_argc);
+  for (int i = 0; i < bound_argc; i++) {
+    param_data[i] = Handle<Object>(
+        bound_args->get(JSFunction::kBoundArgumentsStartIndex + i), isolate);
+  }
+
+  if (!bound_function->IsJSFunction()) {
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, bound_function,
+        Execution::TryGetConstructorDelegate(isolate, bound_function));
+  }
+  DCHECK(bound_function->IsJSFunction());
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, Execution::New(Handle<JSFunction>::cast(bound_function),
+                                      total_argc, param_data.get()));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_Call) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() >= 2);
+  int argc = args.length() - 2;
+  CONVERT_ARG_CHECKED(JSReceiver, fun, argc + 1);
+  Object* receiver = args[0];
+
+  // If there are too many arguments, allocate argv via malloc.
+  const int argv_small_size = 10;
+  Handle<Object> argv_small_buffer[argv_small_size];
+  SmartArrayPointer<Handle<Object> > argv_large_buffer;
+  Handle<Object>* argv = argv_small_buffer;
+  if (argc > argv_small_size) {
+    argv = new Handle<Object>[argc];
+    if (argv == NULL) return isolate->StackOverflow();
+    argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
+  }
+
+  for (int i = 0; i < argc; ++i) {
+    argv[i] = Handle<Object>(args[1 + i], isolate);
+  }
+
+  Handle<JSReceiver> hfun(fun);
+  Handle<Object> hreceiver(receiver, isolate);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Execution::Call(isolate, hfun, hreceiver, argc, argv, true));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_Apply) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 5);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, fun, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, arguments, 2);
+  CONVERT_INT32_ARG_CHECKED(offset, 3);
+  CONVERT_INT32_ARG_CHECKED(argc, 4);
+  RUNTIME_ASSERT(offset >= 0);
+  // Loose upper bound to allow fuzzing. We'll most likely run out of
+  // stack space before hitting this limit.
+  static int kMaxArgc = 1000000;
+  RUNTIME_ASSERT(argc >= 0 && argc <= kMaxArgc);
+
+  // If there are too many arguments, allocate argv via malloc.
+  const int argv_small_size = 10;
+  Handle<Object> argv_small_buffer[argv_small_size];
+  SmartArrayPointer<Handle<Object> > argv_large_buffer;
+  Handle<Object>* argv = argv_small_buffer;
+  if (argc > argv_small_size) {
+    argv = new Handle<Object>[argc];
+    if (argv == NULL) return isolate->StackOverflow();
+    argv_large_buffer = SmartArrayPointer<Handle<Object> >(argv);
+  }
+
+  for (int i = 0; i < argc; ++i) {
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, argv[i], Object::GetElement(isolate, arguments, offset + i));
+  }
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Execution::Call(isolate, fun, receiver, argc, argv, true));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetFunctionDelegate) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  RUNTIME_ASSERT(!object->IsJSFunction());
+  return *Execution::GetFunctionDelegate(isolate, object);
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetConstructorDelegate) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  RUNTIME_ASSERT(!object->IsJSFunction());
+  return *Execution::GetConstructorDelegate(isolate, object);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_CallFunction) {
+  SealHandleScope shs(isolate);
+  return __RT_impl_Runtime_Call(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsConstructCall) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  JavaScriptFrameIterator it(isolate);
+  JavaScriptFrame* frame = it.frame();
+  return isolate->heap()->ToBoolean(frame->IsConstructor());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsFunction) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  return isolate->heap()->ToBoolean(obj->IsJSFunction());
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-generator.cc b/src/runtime/runtime-generator.cc
new file mode 100644
index 0000000..ff07acd
--- /dev/null
+++ b/src/runtime/runtime-generator.cc
@@ -0,0 +1,227 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/frames-inl.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_CreateJSGeneratorObject) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+
+  JavaScriptFrameIterator it(isolate);
+  JavaScriptFrame* frame = it.frame();
+  Handle<JSFunction> function(frame->function());
+  RUNTIME_ASSERT(function->shared()->is_generator());
+
+  Handle<JSGeneratorObject> generator;
+  if (frame->IsConstructor()) {
+    generator = handle(JSGeneratorObject::cast(frame->receiver()));
+  } else {
+    generator = isolate->factory()->NewJSGeneratorObject(function);
+  }
+  generator->set_function(*function);
+  generator->set_context(Context::cast(frame->context()));
+  generator->set_receiver(frame->receiver());
+  generator->set_continuation(0);
+  generator->set_operand_stack(isolate->heap()->empty_fixed_array());
+  generator->set_stack_handler_index(-1);
+
+  return *generator;
+}
+
+
+RUNTIME_FUNCTION(Runtime_SuspendJSGeneratorObject) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator_object, 0);
+
+  JavaScriptFrameIterator stack_iterator(isolate);
+  JavaScriptFrame* frame = stack_iterator.frame();
+  RUNTIME_ASSERT(frame->function()->shared()->is_generator());
+  DCHECK_EQ(frame->function(), generator_object->function());
+
+  // The caller should have saved the context and continuation already.
+  DCHECK_EQ(generator_object->context(), Context::cast(frame->context()));
+  DCHECK_LT(0, generator_object->continuation());
+
+  // We expect there to be at least two values on the operand stack: the return
+  // value of the yield expression, and the argument to this runtime call.
+  // Neither of those should be saved.
+  int operands_count = frame->ComputeOperandsCount();
+  DCHECK_GE(operands_count, 2);
+  operands_count -= 2;
+
+  if (operands_count == 0) {
+    // Although it's semantically harmless to call this function with an
+    // operands_count of zero, it is also unnecessary.
+    DCHECK_EQ(generator_object->operand_stack(),
+              isolate->heap()->empty_fixed_array());
+    DCHECK_EQ(generator_object->stack_handler_index(), -1);
+    // If there are no operands on the stack, there shouldn't be a handler
+    // active either.
+    DCHECK(!frame->HasHandler());
+  } else {
+    int stack_handler_index = -1;
+    Handle<FixedArray> operand_stack =
+        isolate->factory()->NewFixedArray(operands_count);
+    frame->SaveOperandStack(*operand_stack, &stack_handler_index);
+    generator_object->set_operand_stack(*operand_stack);
+    generator_object->set_stack_handler_index(stack_handler_index);
+  }
+
+  return isolate->heap()->undefined_value();
+}
+
+
+// Note that this function is the slow path for resuming generators.  It is only
+// called if the suspended activation had operands on the stack, stack handlers
+// needing rewinding, or if the resume should throw an exception.  The fast path
+// is handled directly in FullCodeGenerator::EmitGeneratorResume(), which is
+// inlined into GeneratorNext and GeneratorThrow.  EmitGeneratorResumeResume is
+// called in any case, as it needs to reconstruct the stack frame and make space
+// for arguments and operands.
+RUNTIME_FUNCTION(Runtime_ResumeJSGeneratorObject) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_CHECKED(JSGeneratorObject, generator_object, 0);
+  CONVERT_ARG_CHECKED(Object, value, 1);
+  CONVERT_SMI_ARG_CHECKED(resume_mode_int, 2);
+  JavaScriptFrameIterator stack_iterator(isolate);
+  JavaScriptFrame* frame = stack_iterator.frame();
+
+  DCHECK_EQ(frame->function(), generator_object->function());
+  DCHECK(frame->function()->is_compiled());
+
+  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
+  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
+
+  Address pc = generator_object->function()->code()->instruction_start();
+  int offset = generator_object->continuation();
+  DCHECK(offset > 0);
+  frame->set_pc(pc + offset);
+  if (FLAG_enable_ool_constant_pool) {
+    frame->set_constant_pool(
+        generator_object->function()->code()->constant_pool());
+  }
+  generator_object->set_continuation(JSGeneratorObject::kGeneratorExecuting);
+
+  FixedArray* operand_stack = generator_object->operand_stack();
+  int operands_count = operand_stack->length();
+  if (operands_count != 0) {
+    frame->RestoreOperandStack(operand_stack,
+                               generator_object->stack_handler_index());
+    generator_object->set_operand_stack(isolate->heap()->empty_fixed_array());
+    generator_object->set_stack_handler_index(-1);
+  }
+
+  JSGeneratorObject::ResumeMode resume_mode =
+      static_cast<JSGeneratorObject::ResumeMode>(resume_mode_int);
+  switch (resume_mode) {
+    case JSGeneratorObject::NEXT:
+      return value;
+    case JSGeneratorObject::THROW:
+      return isolate->Throw(value);
+  }
+
+  UNREACHABLE();
+  return isolate->ThrowIllegalOperation();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GeneratorClose) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+  generator->set_continuation(JSGeneratorObject::kGeneratorClosed);
+
+  return isolate->heap()->undefined_value();
+}
+
+
+// Returns function of generator activation.
+RUNTIME_FUNCTION(Runtime_GeneratorGetFunction) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+  return generator->function();
+}
+
+
+// Returns context of generator activation.
+RUNTIME_FUNCTION(Runtime_GeneratorGetContext) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+  return generator->context();
+}
+
+
+// Returns receiver of generator activation.
+RUNTIME_FUNCTION(Runtime_GeneratorGetReceiver) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+  return generator->receiver();
+}
+
+
+// Returns generator continuation as a PC offset, or the magic -1 or 0 values.
+RUNTIME_FUNCTION(Runtime_GeneratorGetContinuation) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+  return Smi::FromInt(generator->continuation());
+}
+
+
+RUNTIME_FUNCTION(Runtime_GeneratorGetSourcePosition) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, generator, 0);
+
+  if (generator->is_suspended()) {
+    Handle<Code> code(generator->function()->code(), isolate);
+    int offset = generator->continuation();
+
+    RUNTIME_ASSERT(0 <= offset && offset < code->Size());
+    Address pc = code->address() + offset;
+
+    return Smi::FromInt(code->SourcePosition(pc));
+  }
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_FunctionIsGenerator) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, f, 0);
+  return isolate->heap()->ToBoolean(f->shared()->is_generator());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_GeneratorNext) {
+  UNREACHABLE();  // Optimization disabled in SetUpGenerators().
+  return NULL;
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_GeneratorThrow) {
+  UNREACHABLE();  // Optimization disabled in SetUpGenerators().
+  return NULL;
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-i18n.cc b/src/runtime/runtime-i18n.cc
new file mode 100644
index 0000000..94d9f42
--- /dev/null
+++ b/src/runtime/runtime-i18n.cc
@@ -0,0 +1,751 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+#ifdef V8_I18N_SUPPORT
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/i18n.h"
+#include "src/runtime/runtime-utils.h"
+
+#include "unicode/brkiter.h"
+#include "unicode/calendar.h"
+#include "unicode/coll.h"
+#include "unicode/curramt.h"
+#include "unicode/datefmt.h"
+#include "unicode/dcfmtsym.h"
+#include "unicode/decimfmt.h"
+#include "unicode/dtfmtsym.h"
+#include "unicode/dtptngen.h"
+#include "unicode/locid.h"
+#include "unicode/numfmt.h"
+#include "unicode/numsys.h"
+#include "unicode/rbbi.h"
+#include "unicode/smpdtfmt.h"
+#include "unicode/timezone.h"
+#include "unicode/uchar.h"
+#include "unicode/ucol.h"
+#include "unicode/ucurr.h"
+#include "unicode/uloc.h"
+#include "unicode/unum.h"
+#include "unicode/uversion.h"
+
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_CanonicalizeLanguageTag) {
+  HandleScope scope(isolate);
+  Factory* factory = isolate->factory();
+
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, locale_id_str, 0);
+
+  v8::String::Utf8Value locale_id(v8::Utils::ToLocal(locale_id_str));
+
+  // Return value which denotes invalid language tag.
+  const char* const kInvalidTag = "invalid-tag";
+
+  UErrorCode error = U_ZERO_ERROR;
+  char icu_result[ULOC_FULLNAME_CAPACITY];
+  int icu_length = 0;
+
+  uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
+                      &icu_length, &error);
+  if (U_FAILURE(error) || icu_length == 0) {
+    return *factory->NewStringFromAsciiChecked(kInvalidTag);
+  }
+
+  char result[ULOC_FULLNAME_CAPACITY];
+
+  // Force strict BCP47 rules.
+  uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
+
+  if (U_FAILURE(error)) {
+    return *factory->NewStringFromAsciiChecked(kInvalidTag);
+  }
+
+  return *factory->NewStringFromAsciiChecked(result);
+}
+
+
+RUNTIME_FUNCTION(Runtime_AvailableLocalesOf) {
+  HandleScope scope(isolate);
+  Factory* factory = isolate->factory();
+
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, service, 0);
+
+  const icu::Locale* available_locales = NULL;
+  int32_t count = 0;
+
+  if (service->IsUtf8EqualTo(CStrVector("collator"))) {
+    available_locales = icu::Collator::getAvailableLocales(count);
+  } else if (service->IsUtf8EqualTo(CStrVector("numberformat"))) {
+    available_locales = icu::NumberFormat::getAvailableLocales(count);
+  } else if (service->IsUtf8EqualTo(CStrVector("dateformat"))) {
+    available_locales = icu::DateFormat::getAvailableLocales(count);
+  } else if (service->IsUtf8EqualTo(CStrVector("breakiterator"))) {
+    available_locales = icu::BreakIterator::getAvailableLocales(count);
+  }
+
+  UErrorCode error = U_ZERO_ERROR;
+  char result[ULOC_FULLNAME_CAPACITY];
+  Handle<JSObject> locales = factory->NewJSObject(isolate->object_function());
+
+  for (int32_t i = 0; i < count; ++i) {
+    const char* icu_name = available_locales[i].getName();
+
+    error = U_ZERO_ERROR;
+    // No need to force strict BCP47 rules.
+    uloc_toLanguageTag(icu_name, result, ULOC_FULLNAME_CAPACITY, FALSE, &error);
+    if (U_FAILURE(error)) {
+      // This shouldn't happen, but lets not break the user.
+      continue;
+    }
+
+    RETURN_FAILURE_ON_EXCEPTION(
+        isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                     locales, factory->NewStringFromAsciiChecked(result),
+                     factory->NewNumber(i), NONE));
+  }
+
+  return *locales;
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetDefaultICULocale) {
+  HandleScope scope(isolate);
+  Factory* factory = isolate->factory();
+
+  DCHECK(args.length() == 0);
+
+  icu::Locale default_locale;
+
+  // Set the locale
+  char result[ULOC_FULLNAME_CAPACITY];
+  UErrorCode status = U_ZERO_ERROR;
+  uloc_toLanguageTag(default_locale.getName(), result, ULOC_FULLNAME_CAPACITY,
+                     FALSE, &status);
+  if (U_SUCCESS(status)) {
+    return *factory->NewStringFromAsciiChecked(result);
+  }
+
+  return *factory->NewStringFromStaticChars("und");
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetLanguageTagVariants) {
+  HandleScope scope(isolate);
+  Factory* factory = isolate->factory();
+
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, input, 0);
+
+  uint32_t length = static_cast<uint32_t>(input->length()->Number());
+  // Set some limit to prevent fuzz tests from going OOM.
+  // Can be bumped when callers' requirements change.
+  RUNTIME_ASSERT(length < 100);
+  Handle<FixedArray> output = factory->NewFixedArray(length);
+  Handle<Name> maximized = factory->NewStringFromStaticChars("maximized");
+  Handle<Name> base = factory->NewStringFromStaticChars("base");
+  for (unsigned int i = 0; i < length; ++i) {
+    Handle<Object> locale_id;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, locale_id,
+                                       Object::GetElement(isolate, input, i));
+    if (!locale_id->IsString()) {
+      return isolate->Throw(*factory->illegal_argument_string());
+    }
+
+    v8::String::Utf8Value utf8_locale_id(
+        v8::Utils::ToLocal(Handle<String>::cast(locale_id)));
+
+    UErrorCode error = U_ZERO_ERROR;
+
+    // Convert from BCP47 to ICU format.
+    // de-DE-u-co-phonebk -> de_DE@collation=phonebook
+    char icu_locale[ULOC_FULLNAME_CAPACITY];
+    int icu_locale_length = 0;
+    uloc_forLanguageTag(*utf8_locale_id, icu_locale, ULOC_FULLNAME_CAPACITY,
+                        &icu_locale_length, &error);
+    if (U_FAILURE(error) || icu_locale_length == 0) {
+      return isolate->Throw(*factory->illegal_argument_string());
+    }
+
+    // Maximize the locale.
+    // de_DE@collation=phonebook -> de_Latn_DE@collation=phonebook
+    char icu_max_locale[ULOC_FULLNAME_CAPACITY];
+    uloc_addLikelySubtags(icu_locale, icu_max_locale, ULOC_FULLNAME_CAPACITY,
+                          &error);
+
+    // Remove extensions from maximized locale.
+    // de_Latn_DE@collation=phonebook -> de_Latn_DE
+    char icu_base_max_locale[ULOC_FULLNAME_CAPACITY];
+    uloc_getBaseName(icu_max_locale, icu_base_max_locale,
+                     ULOC_FULLNAME_CAPACITY, &error);
+
+    // Get original name without extensions.
+    // de_DE@collation=phonebook -> de_DE
+    char icu_base_locale[ULOC_FULLNAME_CAPACITY];
+    uloc_getBaseName(icu_locale, icu_base_locale, ULOC_FULLNAME_CAPACITY,
+                     &error);
+
+    // Convert from ICU locale format to BCP47 format.
+    // de_Latn_DE -> de-Latn-DE
+    char base_max_locale[ULOC_FULLNAME_CAPACITY];
+    uloc_toLanguageTag(icu_base_max_locale, base_max_locale,
+                       ULOC_FULLNAME_CAPACITY, FALSE, &error);
+
+    // de_DE -> de-DE
+    char base_locale[ULOC_FULLNAME_CAPACITY];
+    uloc_toLanguageTag(icu_base_locale, base_locale, ULOC_FULLNAME_CAPACITY,
+                       FALSE, &error);
+
+    if (U_FAILURE(error)) {
+      return isolate->Throw(*factory->illegal_argument_string());
+    }
+
+    Handle<JSObject> result = factory->NewJSObject(isolate->object_function());
+    Handle<String> value = factory->NewStringFromAsciiChecked(base_max_locale);
+    JSObject::AddProperty(result, maximized, value, NONE);
+    value = factory->NewStringFromAsciiChecked(base_locale);
+    JSObject::AddProperty(result, base, value, NONE);
+    output->set(i, *result);
+  }
+
+  Handle<JSArray> result = factory->NewJSArrayWithElements(output);
+  result->set_length(Smi::FromInt(length));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsInitializedIntlObject) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
+
+  if (!input->IsJSObject()) return isolate->heap()->false_value();
+  Handle<JSObject> obj = Handle<JSObject>::cast(input);
+
+  Handle<Symbol> marker = isolate->factory()->intl_initialized_marker_symbol();
+  Handle<Object> tag = JSObject::GetDataProperty(obj, marker);
+  return isolate->heap()->ToBoolean(!tag->IsUndefined());
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsInitializedIntlObjectOfType) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, expected_type, 1);
+
+  if (!input->IsJSObject()) return isolate->heap()->false_value();
+  Handle<JSObject> obj = Handle<JSObject>::cast(input);
+
+  Handle<Symbol> marker = isolate->factory()->intl_initialized_marker_symbol();
+  Handle<Object> tag = JSObject::GetDataProperty(obj, marker);
+  return isolate->heap()->ToBoolean(tag->IsString() &&
+                                    String::cast(*tag)->Equals(*expected_type));
+}
+
+
+RUNTIME_FUNCTION(Runtime_MarkAsInitializedIntlObjectOfType) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, input, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, impl, 2);
+
+  Handle<Symbol> marker = isolate->factory()->intl_initialized_marker_symbol();
+  JSObject::SetProperty(input, marker, type, STRICT).Assert();
+
+  marker = isolate->factory()->intl_impl_object_symbol();
+  JSObject::SetProperty(input, marker, impl, STRICT).Assert();
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetImplFromInitializedIntlObject) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(Object, input, 0);
+
+  if (!input->IsJSObject()) {
+    Vector<Handle<Object> > arguments = HandleVector(&input, 1);
+    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+                                   NewTypeError("not_intl_object", arguments));
+  }
+
+  Handle<JSObject> obj = Handle<JSObject>::cast(input);
+
+  Handle<Symbol> marker = isolate->factory()->intl_impl_object_symbol();
+
+  Handle<Object> impl = JSObject::GetDataProperty(obj, marker);
+  if (impl->IsTheHole()) {
+    Vector<Handle<Object> > arguments = HandleVector(&obj, 1);
+    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+                                   NewTypeError("not_intl_object", arguments));
+  }
+  return *impl;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreateDateTimeFormat) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
+
+  Handle<ObjectTemplateInfo> date_format_template = I18N::GetTemplate(isolate);
+
+  // Create an empty object wrapper.
+  Handle<JSObject> local_object;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, local_object,
+      Execution::InstantiateObject(date_format_template));
+
+  // Set date time formatter as internal field of the resulting JS object.
+  icu::SimpleDateFormat* date_format =
+      DateFormat::InitializeDateTimeFormat(isolate, locale, options, resolved);
+
+  if (!date_format) return isolate->ThrowIllegalOperation();
+
+  local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format));
+
+  Factory* factory = isolate->factory();
+  Handle<String> key = factory->NewStringFromStaticChars("dateFormat");
+  Handle<String> value = factory->NewStringFromStaticChars("valid");
+  JSObject::AddProperty(local_object, key, value, NONE);
+
+  // Make object handle weak so we can delete the data format once GC kicks in.
+  Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
+  GlobalHandles::MakeWeak(wrapper.location(),
+                          reinterpret_cast<void*>(wrapper.location()),
+                          DateFormat::DeleteDateFormat);
+  return *local_object;
+}
+
+
+RUNTIME_FUNCTION(Runtime_InternalDateFormat) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1);
+
+  Handle<Object> value;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
+                                     Execution::ToNumber(isolate, date));
+
+  icu::SimpleDateFormat* date_format =
+      DateFormat::UnpackDateFormat(isolate, date_format_holder);
+  if (!date_format) return isolate->ThrowIllegalOperation();
+
+  icu::UnicodeString result;
+  date_format->format(value->Number(), result);
+
+  Handle<String> result_str;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result_str,
+      isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>(
+          reinterpret_cast<const uint16_t*>(result.getBuffer()),
+          result.length())));
+  return *result_str;
+}
+
+
+RUNTIME_FUNCTION(Runtime_InternalDateParse) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1);
+
+  v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string));
+  icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date));
+  icu::SimpleDateFormat* date_format =
+      DateFormat::UnpackDateFormat(isolate, date_format_holder);
+  if (!date_format) return isolate->ThrowIllegalOperation();
+
+  UErrorCode status = U_ZERO_ERROR;
+  UDate date = date_format->parse(u_date, status);
+  if (U_FAILURE(status)) return isolate->heap()->undefined_value();
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, Execution::NewDate(isolate, static_cast<double>(date)));
+  DCHECK(result->IsJSDate());
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreateNumberFormat) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
+
+  Handle<ObjectTemplateInfo> number_format_template =
+      I18N::GetTemplate(isolate);
+
+  // Create an empty object wrapper.
+  Handle<JSObject> local_object;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, local_object,
+      Execution::InstantiateObject(number_format_template));
+
+  // Set number formatter as internal field of the resulting JS object.
+  icu::DecimalFormat* number_format =
+      NumberFormat::InitializeNumberFormat(isolate, locale, options, resolved);
+
+  if (!number_format) return isolate->ThrowIllegalOperation();
+
+  local_object->SetInternalField(0, reinterpret_cast<Smi*>(number_format));
+
+  Factory* factory = isolate->factory();
+  Handle<String> key = factory->NewStringFromStaticChars("numberFormat");
+  Handle<String> value = factory->NewStringFromStaticChars("valid");
+  JSObject::AddProperty(local_object, key, value, NONE);
+
+  Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
+  GlobalHandles::MakeWeak(wrapper.location(),
+                          reinterpret_cast<void*>(wrapper.location()),
+                          NumberFormat::DeleteNumberFormat);
+  return *local_object;
+}
+
+
+RUNTIME_FUNCTION(Runtime_InternalNumberFormat) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, number, 1);
+
+  Handle<Object> value;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
+                                     Execution::ToNumber(isolate, number));
+
+  icu::DecimalFormat* number_format =
+      NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
+  if (!number_format) return isolate->ThrowIllegalOperation();
+
+  icu::UnicodeString result;
+  number_format->format(value->Number(), result);
+
+  Handle<String> result_str;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result_str,
+      isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>(
+          reinterpret_cast<const uint16_t*>(result.getBuffer()),
+          result.length())));
+  return *result_str;
+}
+
+
+RUNTIME_FUNCTION(Runtime_InternalNumberParse) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, number_format_holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, number_string, 1);
+
+  v8::String::Utf8Value utf8_number(v8::Utils::ToLocal(number_string));
+  icu::UnicodeString u_number(icu::UnicodeString::fromUTF8(*utf8_number));
+  icu::DecimalFormat* number_format =
+      NumberFormat::UnpackNumberFormat(isolate, number_format_holder);
+  if (!number_format) return isolate->ThrowIllegalOperation();
+
+  UErrorCode status = U_ZERO_ERROR;
+  icu::Formattable result;
+  // ICU 4.6 doesn't support parseCurrency call. We need to wait for ICU49
+  // to be part of Chrome.
+  // TODO(cira): Include currency parsing code using parseCurrency call.
+  // We need to check if the formatter parses all currencies or only the
+  // one it was constructed with (it will impact the API - how to return ISO
+  // code and the value).
+  number_format->parse(u_number, result, status);
+  if (U_FAILURE(status)) return isolate->heap()->undefined_value();
+
+  switch (result.getType()) {
+    case icu::Formattable::kDouble:
+      return *isolate->factory()->NewNumber(result.getDouble());
+    case icu::Formattable::kLong:
+      return *isolate->factory()->NewNumberFromInt(result.getLong());
+    case icu::Formattable::kInt64:
+      return *isolate->factory()->NewNumber(
+          static_cast<double>(result.getInt64()));
+    default:
+      return isolate->heap()->undefined_value();
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreateCollator) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
+
+  Handle<ObjectTemplateInfo> collator_template = I18N::GetTemplate(isolate);
+
+  // Create an empty object wrapper.
+  Handle<JSObject> local_object;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, local_object, Execution::InstantiateObject(collator_template));
+
+  // Set collator as internal field of the resulting JS object.
+  icu::Collator* collator =
+      Collator::InitializeCollator(isolate, locale, options, resolved);
+
+  if (!collator) return isolate->ThrowIllegalOperation();
+
+  local_object->SetInternalField(0, reinterpret_cast<Smi*>(collator));
+
+  Factory* factory = isolate->factory();
+  Handle<String> key = factory->NewStringFromStaticChars("collator");
+  Handle<String> value = factory->NewStringFromStaticChars("valid");
+  JSObject::AddProperty(local_object, key, value, NONE);
+
+  Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
+  GlobalHandles::MakeWeak(wrapper.location(),
+                          reinterpret_cast<void*>(wrapper.location()),
+                          Collator::DeleteCollator);
+  return *local_object;
+}
+
+
+RUNTIME_FUNCTION(Runtime_InternalCompare) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, collator_holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, string1, 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, string2, 2);
+
+  icu::Collator* collator = Collator::UnpackCollator(isolate, collator_holder);
+  if (!collator) return isolate->ThrowIllegalOperation();
+
+  v8::String::Value string_value1(v8::Utils::ToLocal(string1));
+  v8::String::Value string_value2(v8::Utils::ToLocal(string2));
+  const UChar* u_string1 = reinterpret_cast<const UChar*>(*string_value1);
+  const UChar* u_string2 = reinterpret_cast<const UChar*>(*string_value2);
+  UErrorCode status = U_ZERO_ERROR;
+  UCollationResult result =
+      collator->compare(u_string1, string_value1.length(), u_string2,
+                        string_value2.length(), status);
+  if (U_FAILURE(status)) return isolate->ThrowIllegalOperation();
+
+  return *isolate->factory()->NewNumberFromInt(result);
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringNormalize) {
+  HandleScope scope(isolate);
+  static const UNormalizationMode normalizationForms[] = {
+      UNORM_NFC, UNORM_NFD, UNORM_NFKC, UNORM_NFKD};
+
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, stringValue, 0);
+  CONVERT_NUMBER_CHECKED(int, form_id, Int32, args[1]);
+  RUNTIME_ASSERT(form_id >= 0 &&
+                 static_cast<size_t>(form_id) < arraysize(normalizationForms));
+
+  v8::String::Value string_value(v8::Utils::ToLocal(stringValue));
+  const UChar* u_value = reinterpret_cast<const UChar*>(*string_value);
+
+  // TODO(mnita): check Normalizer2 (not available in ICU 46)
+  UErrorCode status = U_ZERO_ERROR;
+  icu::UnicodeString result;
+  icu::Normalizer::normalize(u_value, normalizationForms[form_id], 0, result,
+                             status);
+  if (U_FAILURE(status)) {
+    return isolate->heap()->undefined_value();
+  }
+
+  Handle<String> result_str;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result_str,
+      isolate->factory()->NewStringFromTwoByte(Vector<const uint16_t>(
+          reinterpret_cast<const uint16_t*>(result.getBuffer()),
+          result.length())));
+  return *result_str;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreateBreakIterator) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, locale, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2);
+
+  Handle<ObjectTemplateInfo> break_iterator_template =
+      I18N::GetTemplate2(isolate);
+
+  // Create an empty object wrapper.
+  Handle<JSObject> local_object;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, local_object,
+      Execution::InstantiateObject(break_iterator_template));
+
+  // Set break iterator as internal field of the resulting JS object.
+  icu::BreakIterator* break_iterator = BreakIterator::InitializeBreakIterator(
+      isolate, locale, options, resolved);
+
+  if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+  local_object->SetInternalField(0, reinterpret_cast<Smi*>(break_iterator));
+  // Make sure that the pointer to adopted text is NULL.
+  local_object->SetInternalField(1, reinterpret_cast<Smi*>(NULL));
+
+  Factory* factory = isolate->factory();
+  Handle<String> key = factory->NewStringFromStaticChars("breakIterator");
+  Handle<String> value = factory->NewStringFromStaticChars("valid");
+  JSObject::AddProperty(local_object, key, value, NONE);
+
+  // Make object handle weak so we can delete the break iterator once GC kicks
+  // in.
+  Handle<Object> wrapper = isolate->global_handles()->Create(*local_object);
+  GlobalHandles::MakeWeak(wrapper.location(),
+                          reinterpret_cast<void*>(wrapper.location()),
+                          BreakIterator::DeleteBreakIterator);
+  return *local_object;
+}
+
+
+RUNTIME_FUNCTION(Runtime_BreakIteratorAdoptText) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, text, 1);
+
+  icu::BreakIterator* break_iterator =
+      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+  if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+  icu::UnicodeString* u_text = reinterpret_cast<icu::UnicodeString*>(
+      break_iterator_holder->GetInternalField(1));
+  delete u_text;
+
+  v8::String::Value text_value(v8::Utils::ToLocal(text));
+  u_text = new icu::UnicodeString(reinterpret_cast<const UChar*>(*text_value),
+                                  text_value.length());
+  break_iterator_holder->SetInternalField(1, reinterpret_cast<Smi*>(u_text));
+
+  break_iterator->setText(*u_text);
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_BreakIteratorFirst) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+
+  icu::BreakIterator* break_iterator =
+      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+  if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+  return *isolate->factory()->NewNumberFromInt(break_iterator->first());
+}
+
+
+RUNTIME_FUNCTION(Runtime_BreakIteratorNext) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+
+  icu::BreakIterator* break_iterator =
+      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+  if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+  return *isolate->factory()->NewNumberFromInt(break_iterator->next());
+}
+
+
+RUNTIME_FUNCTION(Runtime_BreakIteratorCurrent) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+
+  icu::BreakIterator* break_iterator =
+      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+  if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+  return *isolate->factory()->NewNumberFromInt(break_iterator->current());
+}
+
+
+RUNTIME_FUNCTION(Runtime_BreakIteratorBreakType) {
+  HandleScope scope(isolate);
+
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, break_iterator_holder, 0);
+
+  icu::BreakIterator* break_iterator =
+      BreakIterator::UnpackBreakIterator(isolate, break_iterator_holder);
+  if (!break_iterator) return isolate->ThrowIllegalOperation();
+
+  // TODO(cira): Remove cast once ICU fixes base BreakIterator class.
+  icu::RuleBasedBreakIterator* rule_based_iterator =
+      static_cast<icu::RuleBasedBreakIterator*>(break_iterator);
+  int32_t status = rule_based_iterator->getRuleStatus();
+  // Keep return values in sync with JavaScript BreakType enum.
+  if (status >= UBRK_WORD_NONE && status < UBRK_WORD_NONE_LIMIT) {
+    return *isolate->factory()->NewStringFromStaticChars("none");
+  } else if (status >= UBRK_WORD_NUMBER && status < UBRK_WORD_NUMBER_LIMIT) {
+    return *isolate->factory()->number_string();
+  } else if (status >= UBRK_WORD_LETTER && status < UBRK_WORD_LETTER_LIMIT) {
+    return *isolate->factory()->NewStringFromStaticChars("letter");
+  } else if (status >= UBRK_WORD_KANA && status < UBRK_WORD_KANA_LIMIT) {
+    return *isolate->factory()->NewStringFromStaticChars("kana");
+  } else if (status >= UBRK_WORD_IDEO && status < UBRK_WORD_IDEO_LIMIT) {
+    return *isolate->factory()->NewStringFromStaticChars("ideo");
+  } else {
+    return *isolate->factory()->NewStringFromStaticChars("unknown");
+  }
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_I18N_SUPPORT
diff --git a/src/runtime/runtime-internal.cc b/src/runtime/runtime-internal.cc
new file mode 100644
index 0000000..79dface
--- /dev/null
+++ b/src/runtime/runtime-internal.cc
@@ -0,0 +1,282 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/bootstrapper.h"
+#include "src/debug.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_CheckIsBootstrapping) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_Throw) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  return isolate->Throw(args[0]);
+}
+
+
+RUNTIME_FUNCTION(Runtime_ReThrow) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  return isolate->ReThrow(args[0]);
+}
+
+
+RUNTIME_FUNCTION(Runtime_PromoteScheduledException) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  return isolate->PromoteScheduledException();
+}
+
+
+RUNTIME_FUNCTION(Runtime_ThrowReferenceError) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
+  THROW_NEW_ERROR_RETURN_FAILURE(
+      isolate, NewReferenceError("not_defined", HandleVector(&name, 1)));
+}
+
+
+RUNTIME_FUNCTION(Runtime_PromiseRejectEvent) {
+  DCHECK(args.length() == 3);
+  HandleScope scope(isolate);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
+  CONVERT_BOOLEAN_ARG_CHECKED(debug_event, 2);
+  if (debug_event) isolate->debug()->OnPromiseReject(promise, value);
+  Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol();
+  // Do not report if we actually have a handler.
+  if (JSObject::GetDataProperty(promise, key)->IsUndefined()) {
+    isolate->ReportPromiseReject(promise, value,
+                                 v8::kPromiseRejectWithNoHandler);
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_PromiseRevokeReject) {
+  DCHECK(args.length() == 1);
+  HandleScope scope(isolate);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
+  Handle<Symbol> key = isolate->factory()->promise_has_handler_symbol();
+  // At this point, no revocation has been issued before
+  RUNTIME_ASSERT(JSObject::GetDataProperty(promise, key)->IsUndefined());
+  isolate->ReportPromiseReject(promise, Handle<Object>(),
+                               v8::kPromiseHandlerAddedAfterReject);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_PromiseHasHandlerSymbol) {
+  DCHECK(args.length() == 0);
+  return isolate->heap()->promise_has_handler_symbol();
+}
+
+
+RUNTIME_FUNCTION(Runtime_StackGuard) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+
+  // First check if this is a real stack overflow.
+  StackLimitCheck check(isolate);
+  if (check.JsHasOverflowed()) {
+    return isolate->StackOverflow();
+  }
+
+  return isolate->stack_guard()->HandleInterrupts();
+}
+
+
+RUNTIME_FUNCTION(Runtime_Interrupt) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  return isolate->stack_guard()->HandleInterrupts();
+}
+
+
+RUNTIME_FUNCTION(Runtime_AllocateInNewSpace) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_SMI_ARG_CHECKED(size, 0);
+  RUNTIME_ASSERT(IsAligned(size, kPointerSize));
+  RUNTIME_ASSERT(size > 0);
+  RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
+  return *isolate->factory()->NewFillerObject(size, false, NEW_SPACE);
+}
+
+
+RUNTIME_FUNCTION(Runtime_AllocateInTargetSpace) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_SMI_ARG_CHECKED(size, 0);
+  CONVERT_SMI_ARG_CHECKED(flags, 1);
+  RUNTIME_ASSERT(IsAligned(size, kPointerSize));
+  RUNTIME_ASSERT(size > 0);
+  RUNTIME_ASSERT(size <= Page::kMaxRegularHeapObjectSize);
+  bool double_align = AllocateDoubleAlignFlag::decode(flags);
+  AllocationSpace space = AllocateTargetSpace::decode(flags);
+  return *isolate->factory()->NewFillerObject(size, double_align, space);
+}
+
+
+// Collect the raw data for a stack trace.  Returns an array of 4
+// element segments each containing a receiver, function, code and
+// native code offset.
+RUNTIME_FUNCTION(Runtime_CollectStackTrace) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, error_object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, caller, 1);
+
+  if (!isolate->bootstrapper()->IsActive()) {
+    // Optionally capture a more detailed stack trace for the message.
+    isolate->CaptureAndSetDetailedStackTrace(error_object);
+    // Capture a simple stack trace for the stack property.
+    isolate->CaptureAndSetSimpleStackTrace(error_object, caller);
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetFromCache) {
+  SealHandleScope shs(isolate);
+  // This is only called from codegen, so checks might be more lax.
+  CONVERT_ARG_CHECKED(JSFunctionResultCache, cache, 0);
+  CONVERT_ARG_CHECKED(Object, key, 1);
+
+  {
+    DisallowHeapAllocation no_alloc;
+
+    int finger_index = cache->finger_index();
+    Object* o = cache->get(finger_index);
+    if (o == key) {
+      // The fastest case: hit the same place again.
+      return cache->get(finger_index + 1);
+    }
+
+    for (int i = finger_index - 2; i >= JSFunctionResultCache::kEntriesIndex;
+         i -= 2) {
+      o = cache->get(i);
+      if (o == key) {
+        cache->set_finger_index(i);
+        return cache->get(i + 1);
+      }
+    }
+
+    int size = cache->size();
+    DCHECK(size <= cache->length());
+
+    for (int i = size - 2; i > finger_index; i -= 2) {
+      o = cache->get(i);
+      if (o == key) {
+        cache->set_finger_index(i);
+        return cache->get(i + 1);
+      }
+    }
+  }
+
+  // There is no value in the cache.  Invoke the function and cache result.
+  HandleScope scope(isolate);
+
+  Handle<JSFunctionResultCache> cache_handle(cache);
+  Handle<Object> key_handle(key, isolate);
+  Handle<Object> value;
+  {
+    Handle<JSFunction> factory(JSFunction::cast(
+        cache_handle->get(JSFunctionResultCache::kFactoryIndex)));
+    // TODO(antonm): consider passing a receiver when constructing a cache.
+    Handle<JSObject> receiver(isolate->global_proxy());
+    // This handle is nor shared, nor used later, so it's safe.
+    Handle<Object> argv[] = {key_handle};
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, value,
+        Execution::Call(isolate, factory, receiver, arraysize(argv), argv));
+  }
+
+#ifdef VERIFY_HEAP
+  if (FLAG_verify_heap) {
+    cache_handle->JSFunctionResultCacheVerify();
+  }
+#endif
+
+  // Function invocation may have cleared the cache.  Reread all the data.
+  int finger_index = cache_handle->finger_index();
+  int size = cache_handle->size();
+
+  // If we have spare room, put new data into it, otherwise evict post finger
+  // entry which is likely to be the least recently used.
+  int index = -1;
+  if (size < cache_handle->length()) {
+    cache_handle->set_size(size + JSFunctionResultCache::kEntrySize);
+    index = size;
+  } else {
+    index = finger_index + JSFunctionResultCache::kEntrySize;
+    if (index == cache_handle->length()) {
+      index = JSFunctionResultCache::kEntriesIndex;
+    }
+  }
+
+  DCHECK(index % 2 == 0);
+  DCHECK(index >= JSFunctionResultCache::kEntriesIndex);
+  DCHECK(index < cache_handle->length());
+
+  cache_handle->set(index, *key_handle);
+  cache_handle->set(index + 1, *value);
+  cache_handle->set_finger_index(index);
+
+#ifdef VERIFY_HEAP
+  if (FLAG_verify_heap) {
+    cache_handle->JSFunctionResultCacheVerify();
+  }
+#endif
+
+  return *value;
+}
+
+
+RUNTIME_FUNCTION(Runtime_MessageGetStartPosition) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
+  return Smi::FromInt(message->start_position());
+}
+
+
+RUNTIME_FUNCTION(Runtime_MessageGetScript) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSMessageObject, message, 0);
+  return message->script();
+}
+
+
+RUNTIME_FUNCTION(Runtime_IS_VAR) {
+  UNREACHABLE();  // implemented as macro in the parser
+  return NULL;
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_GetFromCache) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_SMI_ARG_CHECKED(id, 0);
+  args[0] = isolate->native_context()->jsfunction_result_caches()->get(id);
+  return __RT_impl_Runtime_GetFromCache(args, isolate);
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-json.cc b/src/runtime/runtime-json.cc
new file mode 100644
index 0000000..647f48b
--- /dev/null
+++ b/src/runtime/runtime-json.cc
@@ -0,0 +1,53 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/json-parser.h"
+#include "src/json-stringifier.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_QuoteJSONString) {
+  HandleScope scope(isolate);
+  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
+  DCHECK(args.length() == 1);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, BasicJsonStringifier::StringifyString(isolate, string));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_BasicJSONStringify) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  BasicJsonStringifier stringifier(isolate);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                     stringifier.Stringify(object));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ParseJson) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
+
+  source = String::Flatten(source);
+  // Optimized fast case where we only have Latin1 characters.
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                     source->IsSeqOneByteString()
+                                         ? JsonParser<true>::Parse(source)
+                                         : JsonParser<false>::Parse(source));
+  return *result;
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-literals.cc b/src/runtime/runtime-literals.cc
new file mode 100644
index 0000000..8bbe0ee
--- /dev/null
+++ b/src/runtime/runtime-literals.cc
@@ -0,0 +1,435 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/allocation-site-scopes.h"
+#include "src/arguments.h"
+#include "src/ast.h"
+#include "src/parser.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+static Handle<Map> ComputeObjectLiteralMap(
+    Handle<Context> context, Handle<FixedArray> constant_properties,
+    bool* is_result_from_cache) {
+  int properties_length = constant_properties->length();
+  int number_of_properties = properties_length / 2;
+
+  for (int p = 0; p != properties_length; p += 2) {
+    Object* key = constant_properties->get(p);
+    uint32_t element_index = 0;
+    if (key->ToArrayIndex(&element_index)) {
+      // An index key does not require space in the property backing store.
+      number_of_properties--;
+    }
+  }
+  Isolate* isolate = context->GetIsolate();
+  return isolate->factory()->ObjectLiteralMapFromCache(
+      context, number_of_properties, is_result_from_cache);
+}
+
+MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
+    Isolate* isolate, Handle<FixedArray> literals,
+    Handle<FixedArray> constant_properties);
+
+
+MUST_USE_RESULT static MaybeHandle<Object> CreateObjectLiteralBoilerplate(
+    Isolate* isolate, Handle<FixedArray> literals,
+    Handle<FixedArray> constant_properties, bool should_have_fast_elements,
+    bool has_function_literal) {
+  // Get the native context from the literals array.  This is the
+  // context in which the function was created and we use the object
+  // function from this context to create the object literal.  We do
+  // not use the object function from the current native context
+  // because this might be the object function from another context
+  // which we should not have access to.
+  Handle<Context> context =
+      Handle<Context>(JSFunction::NativeContextFromLiterals(*literals));
+
+  // In case we have function literals, we want the object to be in
+  // slow properties mode for now. We don't go in the map cache because
+  // maps with constant functions can't be shared if the functions are
+  // not the same (which is the common case).
+  bool is_result_from_cache = false;
+  Handle<Map> map = has_function_literal
+                        ? Handle<Map>(context->object_function()->initial_map())
+                        : ComputeObjectLiteralMap(context, constant_properties,
+                                                  &is_result_from_cache);
+
+  PretenureFlag pretenure_flag =
+      isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
+
+  Handle<JSObject> boilerplate =
+      isolate->factory()->NewJSObjectFromMap(map, pretenure_flag);
+
+  // Normalize the elements of the boilerplate to save space if needed.
+  if (!should_have_fast_elements) JSObject::NormalizeElements(boilerplate);
+
+  // Add the constant properties to the boilerplate.
+  int length = constant_properties->length();
+  bool should_transform =
+      !is_result_from_cache && boilerplate->HasFastProperties();
+  bool should_normalize = should_transform || has_function_literal;
+  if (should_normalize) {
+    // TODO(verwaest): We might not want to ever normalize here.
+    JSObject::NormalizeProperties(boilerplate, KEEP_INOBJECT_PROPERTIES,
+                                  length / 2, "Boilerplate");
+  }
+  // TODO(verwaest): Support tracking representations in the boilerplate.
+  for (int index = 0; index < length; index += 2) {
+    Handle<Object> key(constant_properties->get(index + 0), isolate);
+    Handle<Object> value(constant_properties->get(index + 1), isolate);
+    if (value->IsFixedArray()) {
+      // The value contains the constant_properties of a
+      // simple object or array literal.
+      Handle<FixedArray> array = Handle<FixedArray>::cast(value);
+      ASSIGN_RETURN_ON_EXCEPTION(
+          isolate, value, CreateLiteralBoilerplate(isolate, literals, array),
+          Object);
+    }
+    MaybeHandle<Object> maybe_result;
+    uint32_t element_index = 0;
+    if (key->IsInternalizedString()) {
+      if (Handle<String>::cast(key)->AsArrayIndex(&element_index)) {
+        // Array index as string (uint32).
+        if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
+        maybe_result =
+            JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY);
+      } else {
+        Handle<String> name(String::cast(*key));
+        DCHECK(!name->AsArrayIndex(&element_index));
+        maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(
+            boilerplate, name, value, NONE);
+      }
+    } else if (key->ToArrayIndex(&element_index)) {
+      // Array index (uint32).
+      if (value->IsUninitialized()) value = handle(Smi::FromInt(0), isolate);
+      maybe_result =
+          JSObject::SetOwnElement(boilerplate, element_index, value, SLOPPY);
+    } else {
+      // Non-uint32 number.
+      DCHECK(key->IsNumber());
+      double num = key->Number();
+      char arr[100];
+      Vector<char> buffer(arr, arraysize(arr));
+      const char* str = DoubleToCString(num, buffer);
+      Handle<String> name = isolate->factory()->NewStringFromAsciiChecked(str);
+      maybe_result = JSObject::SetOwnPropertyIgnoreAttributes(boilerplate, name,
+                                                              value, NONE);
+    }
+    // If setting the property on the boilerplate throws an
+    // exception, the exception is converted to an empty handle in
+    // the handle based operations.  In that case, we need to
+    // convert back to an exception.
+    RETURN_ON_EXCEPTION(isolate, maybe_result, Object);
+  }
+
+  // Transform to fast properties if necessary. For object literals with
+  // containing function literals we defer this operation until after all
+  // computed properties have been assigned so that we can generate
+  // constant function properties.
+  if (should_transform && !has_function_literal) {
+    JSObject::MigrateSlowToFast(boilerplate,
+                                boilerplate->map()->unused_property_fields(),
+                                "FastLiteral");
+  }
+  return boilerplate;
+}
+
+
+MaybeHandle<Object> Runtime::CreateArrayLiteralBoilerplate(
+    Isolate* isolate, Handle<FixedArray> literals,
+    Handle<FixedArray> elements) {
+  // Create the JSArray.
+  Handle<JSFunction> constructor(
+      JSFunction::NativeContextFromLiterals(*literals)->array_function());
+
+  PretenureFlag pretenure_flag =
+      isolate->heap()->InNewSpace(*literals) ? NOT_TENURED : TENURED;
+
+  Handle<JSArray> object = Handle<JSArray>::cast(
+      isolate->factory()->NewJSObject(constructor, pretenure_flag));
+
+  ElementsKind constant_elements_kind =
+      static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
+  Handle<FixedArrayBase> constant_elements_values(
+      FixedArrayBase::cast(elements->get(1)));
+
+  {
+    DisallowHeapAllocation no_gc;
+    DCHECK(IsFastElementsKind(constant_elements_kind));
+    Context* native_context = isolate->context()->native_context();
+    Object* maps_array = native_context->js_array_maps();
+    DCHECK(!maps_array->IsUndefined());
+    Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind);
+    object->set_map(Map::cast(map));
+  }
+
+  Handle<FixedArrayBase> copied_elements_values;
+  if (IsFastDoubleElementsKind(constant_elements_kind)) {
+    copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
+        Handle<FixedDoubleArray>::cast(constant_elements_values));
+  } else {
+    DCHECK(IsFastSmiOrObjectElementsKind(constant_elements_kind));
+    const bool is_cow = (constant_elements_values->map() ==
+                         isolate->heap()->fixed_cow_array_map());
+    if (is_cow) {
+      copied_elements_values = constant_elements_values;
+#if DEBUG
+      Handle<FixedArray> fixed_array_values =
+          Handle<FixedArray>::cast(copied_elements_values);
+      for (int i = 0; i < fixed_array_values->length(); i++) {
+        DCHECK(!fixed_array_values->get(i)->IsFixedArray());
+      }
+#endif
+    } else {
+      Handle<FixedArray> fixed_array_values =
+          Handle<FixedArray>::cast(constant_elements_values);
+      Handle<FixedArray> fixed_array_values_copy =
+          isolate->factory()->CopyFixedArray(fixed_array_values);
+      copied_elements_values = fixed_array_values_copy;
+      for (int i = 0; i < fixed_array_values->length(); i++) {
+        if (fixed_array_values->get(i)->IsFixedArray()) {
+          // The value contains the constant_properties of a
+          // simple object or array literal.
+          Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
+          Handle<Object> result;
+          ASSIGN_RETURN_ON_EXCEPTION(
+              isolate, result, CreateLiteralBoilerplate(isolate, literals, fa),
+              Object);
+          fixed_array_values_copy->set(i, *result);
+        }
+      }
+    }
+  }
+  object->set_elements(*copied_elements_values);
+  object->set_length(Smi::FromInt(copied_elements_values->length()));
+
+  JSObject::ValidateElements(object);
+  return object;
+}
+
+
+MUST_USE_RESULT static MaybeHandle<Object> CreateLiteralBoilerplate(
+    Isolate* isolate, Handle<FixedArray> literals, Handle<FixedArray> array) {
+  Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
+  const bool kHasNoFunctionLiteral = false;
+  switch (CompileTimeValue::GetLiteralType(array)) {
+    case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS:
+      return CreateObjectLiteralBoilerplate(isolate, literals, elements, true,
+                                            kHasNoFunctionLiteral);
+    case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS:
+      return CreateObjectLiteralBoilerplate(isolate, literals, elements, false,
+                                            kHasNoFunctionLiteral);
+    case CompileTimeValue::ARRAY_LITERAL:
+      return Runtime::CreateArrayLiteralBoilerplate(isolate, literals,
+                                                    elements);
+    default:
+      UNREACHABLE();
+      return MaybeHandle<Object>();
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
+  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, constant_properties, 2);
+  CONVERT_SMI_ARG_CHECKED(flags, 3);
+  bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0;
+  bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0;
+
+  RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length());
+
+  // Check if boilerplate exists. If not, create it first.
+  Handle<Object> literal_site(literals->get(literals_index), isolate);
+  Handle<AllocationSite> site;
+  Handle<JSObject> boilerplate;
+  if (*literal_site == isolate->heap()->undefined_value()) {
+    Handle<Object> raw_boilerplate;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, raw_boilerplate,
+        CreateObjectLiteralBoilerplate(isolate, literals, constant_properties,
+                                       should_have_fast_elements,
+                                       has_function_literal));
+    boilerplate = Handle<JSObject>::cast(raw_boilerplate);
+
+    AllocationSiteCreationContext creation_context(isolate);
+    site = creation_context.EnterNewScope();
+    RETURN_FAILURE_ON_EXCEPTION(
+        isolate, JSObject::DeepWalk(boilerplate, &creation_context));
+    creation_context.ExitScope(site, boilerplate);
+
+    // Update the functions literal and return the boilerplate.
+    literals->set(literals_index, *site);
+  } else {
+    site = Handle<AllocationSite>::cast(literal_site);
+    boilerplate =
+        Handle<JSObject>(JSObject::cast(site->transition_info()), isolate);
+  }
+
+  AllocationSiteUsageContext usage_context(isolate, site, true);
+  usage_context.EnterNewScope();
+  MaybeHandle<Object> maybe_copy =
+      JSObject::DeepCopy(boilerplate, &usage_context);
+  usage_context.ExitScope(site, boilerplate);
+  Handle<Object> copy;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, copy, maybe_copy);
+  return *copy;
+}
+
+
+MUST_USE_RESULT static MaybeHandle<AllocationSite> GetLiteralAllocationSite(
+    Isolate* isolate, Handle<FixedArray> literals, int literals_index,
+    Handle<FixedArray> elements) {
+  // Check if boilerplate exists. If not, create it first.
+  Handle<Object> literal_site(literals->get(literals_index), isolate);
+  Handle<AllocationSite> site;
+  if (*literal_site == isolate->heap()->undefined_value()) {
+    DCHECK(*elements != isolate->heap()->empty_fixed_array());
+    Handle<Object> boilerplate;
+    ASSIGN_RETURN_ON_EXCEPTION(
+        isolate, boilerplate,
+        Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements),
+        AllocationSite);
+
+    AllocationSiteCreationContext creation_context(isolate);
+    site = creation_context.EnterNewScope();
+    if (JSObject::DeepWalk(Handle<JSObject>::cast(boilerplate),
+                           &creation_context).is_null()) {
+      return Handle<AllocationSite>::null();
+    }
+    creation_context.ExitScope(site, Handle<JSObject>::cast(boilerplate));
+
+    literals->set(literals_index, *site);
+  } else {
+    site = Handle<AllocationSite>::cast(literal_site);
+  }
+
+  return site;
+}
+
+
+static MaybeHandle<JSObject> CreateArrayLiteralImpl(Isolate* isolate,
+                                                    Handle<FixedArray> literals,
+                                                    int literals_index,
+                                                    Handle<FixedArray> elements,
+                                                    int flags) {
+  RUNTIME_ASSERT_HANDLIFIED(
+      literals_index >= 0 && literals_index < literals->length(), JSObject);
+  Handle<AllocationSite> site;
+  ASSIGN_RETURN_ON_EXCEPTION(
+      isolate, site,
+      GetLiteralAllocationSite(isolate, literals, literals_index, elements),
+      JSObject);
+
+  bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0;
+  Handle<JSObject> boilerplate(JSObject::cast(site->transition_info()));
+  AllocationSiteUsageContext usage_context(isolate, site, enable_mementos);
+  usage_context.EnterNewScope();
+  JSObject::DeepCopyHints hints = (flags & ArrayLiteral::kShallowElements) == 0
+                                      ? JSObject::kNoHints
+                                      : JSObject::kObjectIsShallow;
+  MaybeHandle<JSObject> copy =
+      JSObject::DeepCopy(boilerplate, &usage_context, hints);
+  usage_context.ExitScope(site, boilerplate);
+  return copy;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreateArrayLiteral) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
+  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
+  CONVERT_SMI_ARG_CHECKED(flags, 3);
+
+  Handle<JSObject> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, CreateArrayLiteralImpl(isolate, literals, literals_index,
+                                              elements, flags));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreateArrayLiteralStubBailout) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
+  CONVERT_SMI_ARG_CHECKED(literals_index, 1);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
+
+  Handle<JSObject> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      CreateArrayLiteralImpl(isolate, literals, literals_index, elements,
+                             ArrayLiteral::kShallowElements));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_StoreArrayLiteralElement) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 5);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_SMI_ARG_CHECKED(store_index, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
+  CONVERT_SMI_ARG_CHECKED(literal_index, 4);
+
+  Object* raw_literal_cell = literals->get(literal_index);
+  JSArray* boilerplate = NULL;
+  if (raw_literal_cell->IsAllocationSite()) {
+    AllocationSite* site = AllocationSite::cast(raw_literal_cell);
+    boilerplate = JSArray::cast(site->transition_info());
+  } else {
+    boilerplate = JSArray::cast(raw_literal_cell);
+  }
+  Handle<JSArray> boilerplate_object(boilerplate);
+  ElementsKind elements_kind = object->GetElementsKind();
+  DCHECK(IsFastElementsKind(elements_kind));
+  // Smis should never trigger transitions.
+  DCHECK(!value->IsSmi());
+
+  if (value->IsNumber()) {
+    DCHECK(IsFastSmiElementsKind(elements_kind));
+    ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
+                                         ? FAST_HOLEY_DOUBLE_ELEMENTS
+                                         : FAST_DOUBLE_ELEMENTS;
+    if (IsMoreGeneralElementsKindTransition(
+            boilerplate_object->GetElementsKind(), transitioned_kind)) {
+      JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
+    }
+    JSObject::TransitionElementsKind(object, transitioned_kind);
+    DCHECK(IsFastDoubleElementsKind(object->GetElementsKind()));
+    FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
+    HeapNumber* number = HeapNumber::cast(*value);
+    double_array->set(store_index, number->Number());
+  } else {
+    if (!IsFastObjectElementsKind(elements_kind)) {
+      ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
+                                           ? FAST_HOLEY_ELEMENTS
+                                           : FAST_ELEMENTS;
+      JSObject::TransitionElementsKind(object, transitioned_kind);
+      ElementsKind boilerplate_elements_kind =
+          boilerplate_object->GetElementsKind();
+      if (IsMoreGeneralElementsKindTransition(boilerplate_elements_kind,
+                                              transitioned_kind)) {
+        JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
+      }
+    }
+    FixedArray* object_array = FixedArray::cast(object->elements());
+    object_array->set(store_index, *value);
+  }
+  return *object;
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-liveedit.cc b/src/runtime/runtime-liveedit.cc
new file mode 100644
index 0000000..b453d15
--- /dev/null
+++ b/src/runtime/runtime-liveedit.cc
@@ -0,0 +1,293 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/debug.h"
+#include "src/liveedit.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+
+static int FindSharedFunctionInfosForScript(HeapIterator* iterator,
+                                            Script* script,
+                                            FixedArray* buffer) {
+  DisallowHeapAllocation no_allocation;
+  int counter = 0;
+  int buffer_size = buffer->length();
+  for (HeapObject* obj = iterator->next(); obj != NULL;
+       obj = iterator->next()) {
+    DCHECK(obj != NULL);
+    if (!obj->IsSharedFunctionInfo()) {
+      continue;
+    }
+    SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
+    if (shared->script() != script) {
+      continue;
+    }
+    if (counter < buffer_size) {
+      buffer->set(counter, shared);
+    }
+    counter++;
+  }
+  return counter;
+}
+
+
+// For a script finds all SharedFunctionInfo's in the heap that points
+// to this script. Returns JSArray of SharedFunctionInfo wrapped
+// in OpaqueReferences.
+RUNTIME_FUNCTION(Runtime_LiveEditFindSharedFunctionInfosForScript) {
+  HandleScope scope(isolate);
+  CHECK(isolate->debug()->live_edit_enabled());
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSValue, script_value, 0);
+
+  RUNTIME_ASSERT(script_value->value()->IsScript());
+  Handle<Script> script = Handle<Script>(Script::cast(script_value->value()));
+
+  const int kBufferSize = 32;
+
+  Handle<FixedArray> array;
+  array = isolate->factory()->NewFixedArray(kBufferSize);
+  int number;
+  Heap* heap = isolate->heap();
+  {
+    HeapIterator heap_iterator(heap);
+    Script* scr = *script;
+    FixedArray* arr = *array;
+    number = FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
+  }
+  if (number > kBufferSize) {
+    array = isolate->factory()->NewFixedArray(number);
+    HeapIterator heap_iterator(heap);
+    Script* scr = *script;
+    FixedArray* arr = *array;
+    FindSharedFunctionInfosForScript(&heap_iterator, scr, arr);
+  }
+
+  Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(array);
+  result->set_length(Smi::FromInt(number));
+
+  LiveEdit::WrapSharedFunctionInfos(result);
+
+  return *result;
+}
+
+
+// For a script calculates compilation information about all its functions.
+// The script source is explicitly specified by the second argument.
+// The source of the actual script is not used, however it is important that
+// all generated code keeps references to this particular instance of script.
+// Returns a JSArray of compilation infos. The array is ordered so that
+// each function with all its descendant is always stored in a continues range
+// with the function itself going first. The root function is a script function.
+RUNTIME_FUNCTION(Runtime_LiveEditGatherCompileInfo) {
+  HandleScope scope(isolate);
+  CHECK(isolate->debug()->live_edit_enabled());
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(JSValue, script, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
+
+  RUNTIME_ASSERT(script->value()->IsScript());
+  Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
+
+  Handle<JSArray> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, LiveEdit::GatherCompileInfo(script_handle, source));
+  return *result;
+}
+
+
+// Changes the source of the script to a new_source.
+// If old_script_name is provided (i.e. is a String), also creates a copy of
+// the script with its original source and sends notification to debugger.
+RUNTIME_FUNCTION(Runtime_LiveEditReplaceScript) {
+  HandleScope scope(isolate);
+  CHECK(isolate->debug()->live_edit_enabled());
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_CHECKED(JSValue, original_script_value, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, old_script_name, 2);
+
+  RUNTIME_ASSERT(original_script_value->value()->IsScript());
+  Handle<Script> original_script(Script::cast(original_script_value->value()));
+
+  Handle<Object> old_script = LiveEdit::ChangeScriptSource(
+      original_script, new_source, old_script_name);
+
+  if (old_script->IsScript()) {
+    Handle<Script> script_handle = Handle<Script>::cast(old_script);
+    return *Script::GetWrapper(script_handle);
+  } else {
+    return isolate->heap()->null_value();
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_LiveEditFunctionSourceUpdated) {
+  HandleScope scope(isolate);
+  CHECK(isolate->debug()->live_edit_enabled());
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 0);
+  RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
+
+  LiveEdit::FunctionSourceUpdated(shared_info);
+  return isolate->heap()->undefined_value();
+}
+
+
+// Replaces code of SharedFunctionInfo with a new one.
+RUNTIME_FUNCTION(Runtime_LiveEditReplaceFunctionCode) {
+  HandleScope scope(isolate);
+  CHECK(isolate->debug()->live_edit_enabled());
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, new_compile_info, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_info, 1);
+  RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_info));
+
+  LiveEdit::ReplaceFunctionCode(new_compile_info, shared_info);
+  return isolate->heap()->undefined_value();
+}
+
+
+// Connects SharedFunctionInfo to another script.
+RUNTIME_FUNCTION(Runtime_LiveEditFunctionSetScript) {
+  HandleScope scope(isolate);
+  CHECK(isolate->debug()->live_edit_enabled());
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, script_object, 1);
+
+  if (function_object->IsJSValue()) {
+    Handle<JSValue> function_wrapper = Handle<JSValue>::cast(function_object);
+    if (script_object->IsJSValue()) {
+      RUNTIME_ASSERT(JSValue::cast(*script_object)->value()->IsScript());
+      Script* script = Script::cast(JSValue::cast(*script_object)->value());
+      script_object = Handle<Object>(script, isolate);
+    }
+    RUNTIME_ASSERT(function_wrapper->value()->IsSharedFunctionInfo());
+    LiveEdit::SetFunctionScript(function_wrapper, script_object);
+  } else {
+    // Just ignore this. We may not have a SharedFunctionInfo for some functions
+    // and we check it in this function.
+  }
+
+  return isolate->heap()->undefined_value();
+}
+
+
+// In a code of a parent function replaces original function as embedded object
+// with a substitution one.
+RUNTIME_FUNCTION(Runtime_LiveEditReplaceRefToNestedFunction) {
+  HandleScope scope(isolate);
+  CHECK(isolate->debug()->live_edit_enabled());
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSValue, parent_wrapper, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSValue, orig_wrapper, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSValue, subst_wrapper, 2);
+  RUNTIME_ASSERT(parent_wrapper->value()->IsSharedFunctionInfo());
+  RUNTIME_ASSERT(orig_wrapper->value()->IsSharedFunctionInfo());
+  RUNTIME_ASSERT(subst_wrapper->value()->IsSharedFunctionInfo());
+
+  LiveEdit::ReplaceRefToNestedFunction(parent_wrapper, orig_wrapper,
+                                       subst_wrapper);
+  return isolate->heap()->undefined_value();
+}
+
+
+// Updates positions of a shared function info (first parameter) according
+// to script source change. Text change is described in second parameter as
+// array of groups of 3 numbers:
+// (change_begin, change_end, change_end_new_position).
+// Each group describes a change in text; groups are sorted by change_begin.
+RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
+  HandleScope scope(isolate);
+  CHECK(isolate->debug()->live_edit_enabled());
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
+  RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
+
+  LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
+  return isolate->heap()->undefined_value();
+}
+
+
+// For array of SharedFunctionInfo's (each wrapped in JSValue)
+// checks that none of them have activations on stacks (of any thread).
+// Returns array of the same length with corresponding results of
+// LiveEdit::FunctionPatchabilityStatus type.
+RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
+  HandleScope scope(isolate);
+  CHECK(isolate->debug()->live_edit_enabled());
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
+  CONVERT_BOOLEAN_ARG_CHECKED(do_drop, 1);
+  RUNTIME_ASSERT(shared_array->length()->IsSmi());
+  RUNTIME_ASSERT(shared_array->HasFastElements())
+  int array_length = Smi::cast(shared_array->length())->value();
+  for (int i = 0; i < array_length; i++) {
+    Handle<Object> element =
+        Object::GetElement(isolate, shared_array, i).ToHandleChecked();
+    RUNTIME_ASSERT(
+        element->IsJSValue() &&
+        Handle<JSValue>::cast(element)->value()->IsSharedFunctionInfo());
+  }
+
+  return *LiveEdit::CheckAndDropActivations(shared_array, do_drop);
+}
+
+
+// Compares 2 strings line-by-line, then token-wise and returns diff in form
+// of JSArray of triplets (pos1, pos1_end, pos2_end) describing list
+// of diff chunks.
+RUNTIME_FUNCTION(Runtime_LiveEditCompareStrings) {
+  HandleScope scope(isolate);
+  CHECK(isolate->debug()->live_edit_enabled());
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(String, s1, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, s2, 1);
+
+  return *LiveEdit::CompareStrings(s1, s2);
+}
+
+
+// Restarts a call frame and completely drops all frames above.
+// Returns true if successful. Otherwise returns undefined or an error message.
+RUNTIME_FUNCTION(Runtime_LiveEditRestartFrame) {
+  HandleScope scope(isolate);
+  CHECK(isolate->debug()->live_edit_enabled());
+  DCHECK(args.length() == 2);
+  CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
+  RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
+
+  CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
+  Heap* heap = isolate->heap();
+
+  // Find the relevant frame with the requested index.
+  StackFrame::Id id = isolate->debug()->break_frame_id();
+  if (id == StackFrame::NO_ID) {
+    // If there are no JavaScript stack frames return undefined.
+    return heap->undefined_value();
+  }
+
+  JavaScriptFrameIterator it(isolate, id);
+  int inlined_jsframe_index = Runtime::FindIndexedNonNativeFrame(&it, index);
+  if (inlined_jsframe_index == -1) return heap->undefined_value();
+  // We don't really care what the inlined frame index is, since we are
+  // throwing away the entire frame anyways.
+  const char* error_message = LiveEdit::RestartFrame(it.frame());
+  if (error_message) {
+    return *(isolate->factory()->InternalizeUtf8String(error_message));
+  }
+  return heap->true_value();
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-maths.cc b/src/runtime/runtime-maths.cc
new file mode 100644
index 0000000..6397ad1
--- /dev/null
+++ b/src/runtime/runtime-maths.cc
@@ -0,0 +1,246 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/assembler.h"
+#include "src/codegen.h"
+#include "src/runtime/runtime-utils.h"
+#include "src/third_party/fdlibm/fdlibm.h"
+
+
+namespace v8 {
+namespace internal {
+
+#define RUNTIME_UNARY_MATH(Name, name)                       \
+  RUNTIME_FUNCTION(Runtime_Math##Name) {                     \
+    HandleScope scope(isolate);                              \
+    DCHECK(args.length() == 1);                              \
+    isolate->counters()->math_##name()->Increment();         \
+    CONVERT_DOUBLE_ARG_CHECKED(x, 0);                        \
+    return *isolate->factory()->NewHeapNumber(std::name(x)); \
+  }
+
+RUNTIME_UNARY_MATH(Acos, acos)
+RUNTIME_UNARY_MATH(Asin, asin)
+RUNTIME_UNARY_MATH(Atan, atan)
+RUNTIME_UNARY_MATH(LogRT, log)
+#undef RUNTIME_UNARY_MATH
+
+
+RUNTIME_FUNCTION(Runtime_DoubleHi) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  uint64_t integer = double_to_uint64(x);
+  integer = (integer >> 32) & 0xFFFFFFFFu;
+  return *isolate->factory()->NewNumber(static_cast<int32_t>(integer));
+}
+
+
+RUNTIME_FUNCTION(Runtime_DoubleLo) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  return *isolate->factory()->NewNumber(
+      static_cast<int32_t>(double_to_uint64(x) & 0xFFFFFFFFu));
+}
+
+
+RUNTIME_FUNCTION(Runtime_ConstructDouble) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_NUMBER_CHECKED(uint32_t, hi, Uint32, args[0]);
+  CONVERT_NUMBER_CHECKED(uint32_t, lo, Uint32, args[1]);
+  uint64_t result = (static_cast<uint64_t>(hi) << 32) | lo;
+  return *isolate->factory()->NewNumber(uint64_to_double(result));
+}
+
+
+RUNTIME_FUNCTION(Runtime_RemPiO2) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  Factory* factory = isolate->factory();
+  double y[2] = {0.0, 0.0};
+  int n = fdlibm::rempio2(x, y);
+  Handle<FixedArray> array = factory->NewFixedArray(3);
+  Handle<HeapNumber> y0 = factory->NewHeapNumber(y[0]);
+  Handle<HeapNumber> y1 = factory->NewHeapNumber(y[1]);
+  array->set(0, Smi::FromInt(n));
+  array->set(1, *y0);
+  array->set(2, *y1);
+  return *factory->NewJSArrayWithElements(array);
+}
+
+
+static const double kPiDividedBy4 = 0.78539816339744830962;
+
+
+RUNTIME_FUNCTION(Runtime_MathAtan2) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  isolate->counters()->math_atan2()->Increment();
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  double result;
+  if (std::isinf(x) && std::isinf(y)) {
+    // Make sure that the result in case of two infinite arguments
+    // is a multiple of Pi / 4. The sign of the result is determined
+    // by the first argument (x) and the sign of the second argument
+    // determines the multiplier: one or three.
+    int multiplier = (x < 0) ? -1 : 1;
+    if (y < 0) multiplier *= 3;
+    result = multiplier * kPiDividedBy4;
+  } else {
+    result = std::atan2(x, y);
+  }
+  return *isolate->factory()->NewNumber(result);
+}
+
+
+RUNTIME_FUNCTION(Runtime_MathExpRT) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  isolate->counters()->math_exp()->Increment();
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  lazily_initialize_fast_exp();
+  return *isolate->factory()->NewNumber(fast_exp(x));
+}
+
+
+RUNTIME_FUNCTION(Runtime_MathFloorRT) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  isolate->counters()->math_floor()->Increment();
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  return *isolate->factory()->NewNumber(Floor(x));
+}
+
+
+// Slow version of Math.pow.  We check for fast paths for special cases.
+// Used if VFP3 is not available.
+RUNTIME_FUNCTION(Runtime_MathPowSlow) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  isolate->counters()->math_pow()->Increment();
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+
+  // If the second argument is a smi, it is much faster to call the
+  // custom powi() function than the generic pow().
+  if (args[1]->IsSmi()) {
+    int y = args.smi_at(1);
+    return *isolate->factory()->NewNumber(power_double_int(x, y));
+  }
+
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  double result = power_helper(x, y);
+  if (std::isnan(result)) return isolate->heap()->nan_value();
+  return *isolate->factory()->NewNumber(result);
+}
+
+
+// Fast version of Math.pow if we know that y is not an integer and y is not
+// -0.5 or 0.5.  Used as slow case from full codegen.
+RUNTIME_FUNCTION(Runtime_MathPowRT) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  isolate->counters()->math_pow()->Increment();
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  if (y == 0) {
+    return Smi::FromInt(1);
+  } else {
+    double result = power_double_double(x, y);
+    if (std::isnan(result)) return isolate->heap()->nan_value();
+    return *isolate->factory()->NewNumber(result);
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_RoundNumber) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(input, 0);
+  isolate->counters()->math_round()->Increment();
+
+  if (!input->IsHeapNumber()) {
+    DCHECK(input->IsSmi());
+    return *input;
+  }
+
+  Handle<HeapNumber> number = Handle<HeapNumber>::cast(input);
+
+  double value = number->value();
+  int exponent = number->get_exponent();
+  int sign = number->get_sign();
+
+  if (exponent < -1) {
+    // Number in range ]-0.5..0.5[. These always round to +/-zero.
+    if (sign) return isolate->heap()->minus_zero_value();
+    return Smi::FromInt(0);
+  }
+
+  // We compare with kSmiValueSize - 2 because (2^30 - 0.1) has exponent 29 and
+  // should be rounded to 2^30, which is not smi (for 31-bit smis, similar
+  // argument holds for 32-bit smis).
+  if (!sign && exponent < kSmiValueSize - 2) {
+    return Smi::FromInt(static_cast<int>(value + 0.5));
+  }
+
+  // If the magnitude is big enough, there's no place for fraction part. If we
+  // try to add 0.5 to this number, 1.0 will be added instead.
+  if (exponent >= 52) {
+    return *number;
+  }
+
+  if (sign && value >= -0.5) return isolate->heap()->minus_zero_value();
+
+  // Do not call NumberFromDouble() to avoid extra checks.
+  return *isolate->factory()->NewNumber(Floor(value + 0.5));
+}
+
+
+RUNTIME_FUNCTION(Runtime_MathSqrtRT) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  isolate->counters()->math_sqrt()->Increment();
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  return *isolate->factory()->NewNumber(fast_sqrt(x));
+}
+
+
+RUNTIME_FUNCTION(Runtime_MathFround) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  float xf = DoubleToFloat32(x);
+  return *isolate->factory()->NewNumber(xf);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_MathPow) {
+  SealHandleScope shs(isolate);
+  return __RT_impl_Runtime_MathPowSlow(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsMinusZero) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  if (!obj->IsHeapNumber()) return isolate->heap()->false_value();
+  HeapNumber* number = HeapNumber::cast(obj);
+  return isolate->heap()->ToBoolean(IsMinusZero(number->value()));
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-numbers.cc b/src/runtime/runtime-numbers.cc
new file mode 100644
index 0000000..bc0bb36
--- /dev/null
+++ b/src/runtime/runtime-numbers.cc
@@ -0,0 +1,596 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/base/bits.h"
+#include "src/bootstrapper.h"
+#include "src/codegen.h"
+#include "src/runtime/runtime-utils.h"
+
+
+#ifndef _STLP_VENDOR_CSTD
+// STLPort doesn't import fpclassify and isless into the std namespace.
+using std::fpclassify;
+using std::isless;
+#endif
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_NumberToRadixString) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_SMI_ARG_CHECKED(radix, 1);
+  RUNTIME_ASSERT(2 <= radix && radix <= 36);
+
+  // Fast case where the result is a one character string.
+  if (args[0]->IsSmi()) {
+    int value = args.smi_at(0);
+    if (value >= 0 && value < radix) {
+      // Character array used for conversion.
+      static const char kCharTable[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+      return *isolate->factory()->LookupSingleCharacterStringFromCode(
+          kCharTable[value]);
+    }
+  }
+
+  // Slow case.
+  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
+  if (std::isnan(value)) {
+    return isolate->heap()->nan_string();
+  }
+  if (std::isinf(value)) {
+    if (value < 0) {
+      return isolate->heap()->minus_infinity_string();
+    }
+    return isolate->heap()->infinity_string();
+  }
+  char* str = DoubleToRadixCString(value, radix);
+  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
+  DeleteArray(str);
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToFixed) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
+  int f = FastD2IChecked(f_number);
+  // See DoubleToFixedCString for these constants:
+  RUNTIME_ASSERT(f >= 0 && f <= 20);
+  RUNTIME_ASSERT(!Double(value).IsSpecial());
+  char* str = DoubleToFixedCString(value, f);
+  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
+  DeleteArray(str);
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToExponential) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
+  int f = FastD2IChecked(f_number);
+  RUNTIME_ASSERT(f >= -1 && f <= 20);
+  RUNTIME_ASSERT(!Double(value).IsSpecial());
+  char* str = DoubleToExponentialCString(value, f);
+  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
+  DeleteArray(str);
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToPrecision) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(value, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(f_number, 1);
+  int f = FastD2IChecked(f_number);
+  RUNTIME_ASSERT(f >= 1 && f <= 21);
+  RUNTIME_ASSERT(!Double(value).IsSpecial());
+  char* str = DoubleToPrecisionCString(value, f);
+  Handle<String> result = isolate->factory()->NewStringFromAsciiChecked(str);
+  DeleteArray(str);
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsValidSmi) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
+  return isolate->heap()->ToBoolean(Smi::IsValid(number));
+}
+
+
+static bool AreDigits(const uint8_t* s, int from, int to) {
+  for (int i = from; i < to; i++) {
+    if (s[i] < '0' || s[i] > '9') return false;
+  }
+
+  return true;
+}
+
+
+static int ParseDecimalInteger(const uint8_t* s, int from, int to) {
+  DCHECK(to - from < 10);  // Overflow is not possible.
+  DCHECK(from < to);
+  int d = s[from] - '0';
+
+  for (int i = from + 1; i < to; i++) {
+    d = 10 * d + (s[i] - '0');
+  }
+
+  return d;
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringToNumber) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+  subject = String::Flatten(subject);
+
+  // Fast case: short integer or some sorts of junk values.
+  if (subject->IsSeqOneByteString()) {
+    int len = subject->length();
+    if (len == 0) return Smi::FromInt(0);
+
+    DisallowHeapAllocation no_gc;
+    uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
+    bool minus = (data[0] == '-');
+    int start_pos = (minus ? 1 : 0);
+
+    if (start_pos == len) {
+      return isolate->heap()->nan_value();
+    } else if (data[start_pos] > '9') {
+      // Fast check for a junk value. A valid string may start from a
+      // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
+      // or the 'I' character ('Infinity'). All of that have codes not greater
+      // than '9' except 'I' and &nbsp;.
+      if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
+        return isolate->heap()->nan_value();
+      }
+    } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
+      // The maximal/minimal smi has 10 digits. If the string has less digits
+      // we know it will fit into the smi-data type.
+      int d = ParseDecimalInteger(data, start_pos, len);
+      if (minus) {
+        if (d == 0) return isolate->heap()->minus_zero_value();
+        d = -d;
+      } else if (!subject->HasHashCode() && len <= String::kMaxArrayIndexSize &&
+                 (len == 1 || data[0] != '0')) {
+        // String hash is not calculated yet but all the data are present.
+        // Update the hash field to speed up sequential convertions.
+        uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
+#ifdef DEBUG
+        subject->Hash();  // Force hash calculation.
+        DCHECK_EQ(static_cast<int>(subject->hash_field()),
+                  static_cast<int>(hash));
+#endif
+        subject->set_hash_field(hash);
+      }
+      return Smi::FromInt(d);
+    }
+  }
+
+  // Slower case.
+  int flags = ALLOW_HEX;
+  if (FLAG_harmony_numeric_literals) {
+    // The current spec draft has not updated "ToNumber Applied to the String
+    // Type", https://bugs.ecmascript.org/show_bug.cgi?id=1584
+    flags |= ALLOW_OCTAL | ALLOW_BINARY;
+  }
+
+  return *isolate->factory()->NewNumber(
+      StringToDouble(isolate->unicode_cache(), subject, flags));
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringParseInt) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+  CONVERT_NUMBER_CHECKED(int, radix, Int32, args[1]);
+  RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
+
+  subject = String::Flatten(subject);
+  double value;
+
+  {
+    DisallowHeapAllocation no_gc;
+    String::FlatContent flat = subject->GetFlatContent();
+
+    // ECMA-262 section 15.1.2.3, empty string is NaN
+    if (flat.IsOneByte()) {
+      value =
+          StringToInt(isolate->unicode_cache(), flat.ToOneByteVector(), radix);
+    } else {
+      value = StringToInt(isolate->unicode_cache(), flat.ToUC16Vector(), radix);
+    }
+  }
+
+  return *isolate->factory()->NewNumber(value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringParseFloat) {
+  HandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+
+  double value = StringToDouble(isolate->unicode_cache(), subject,
+                                ALLOW_TRAILING_JUNK, base::OS::nan_value());
+
+  return *isolate->factory()->NewNumber(value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToStringRT) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
+
+  return *isolate->factory()->NumberToString(number);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToStringSkipCache) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(number, 0);
+
+  return *isolate->factory()->NumberToString(number, false);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToInteger) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
+  return *isolate->factory()->NewNumber(DoubleToInteger(number));
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToIntegerMapMinusZero) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
+  double double_value = DoubleToInteger(number);
+  // Map both -0 and +0 to +0.
+  if (double_value == 0) double_value = 0;
+
+  return *isolate->factory()->NewNumber(double_value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToJSUint32) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_NUMBER_CHECKED(int32_t, number, Uint32, args[0]);
+  return *isolate->factory()->NewNumberFromUint(number);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberToJSInt32) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(number, 0);
+  return *isolate->factory()->NewNumberFromInt(DoubleToInt32(number));
+}
+
+
+// Converts a Number to a Smi, if possible. Returns NaN if the number is not
+// a small integer.
+RUNTIME_FUNCTION(Runtime_NumberToSmi) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  if (obj->IsSmi()) {
+    return obj;
+  }
+  if (obj->IsHeapNumber()) {
+    double value = HeapNumber::cast(obj)->value();
+    int int_value = FastD2I(value);
+    if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
+      return Smi::FromInt(int_value);
+    }
+  }
+  return isolate->heap()->nan_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberAdd) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  return *isolate->factory()->NewNumber(x + y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberSub) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  return *isolate->factory()->NewNumber(x - y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberMul) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  return *isolate->factory()->NewNumber(x * y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberUnaryMinus) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  return *isolate->factory()->NewNumber(-x);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberDiv) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  return *isolate->factory()->NewNumber(x / y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberMod) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  return *isolate->factory()->NewNumber(modulo(x, y));
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberImul) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  // We rely on implementation-defined behavior below, but at least not on
+  // undefined behavior.
+  CONVERT_NUMBER_CHECKED(uint32_t, x, Int32, args[0]);
+  CONVERT_NUMBER_CHECKED(uint32_t, y, Int32, args[1]);
+  int32_t product = static_cast<int32_t>(x * y);
+  return *isolate->factory()->NewNumberFromInt(product);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberOr) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
+  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
+  return *isolate->factory()->NewNumberFromInt(x | y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberAnd) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
+  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
+  return *isolate->factory()->NewNumberFromInt(x & y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberXor) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
+  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
+  return *isolate->factory()->NewNumberFromInt(x ^ y);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberShl) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
+  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
+  return *isolate->factory()->NewNumberFromInt(x << (y & 0x1f));
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberShr) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_NUMBER_CHECKED(uint32_t, x, Uint32, args[0]);
+  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
+  return *isolate->factory()->NewNumberFromUint(x >> (y & 0x1f));
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberSar) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_NUMBER_CHECKED(int32_t, x, Int32, args[0]);
+  CONVERT_NUMBER_CHECKED(int32_t, y, Int32, args[1]);
+  return *isolate->factory()->NewNumberFromInt(
+      ArithmeticShiftRight(x, y & 0x1f));
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberEquals) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  if (std::isnan(x)) return Smi::FromInt(NOT_EQUAL);
+  if (std::isnan(y)) return Smi::FromInt(NOT_EQUAL);
+  if (x == y) return Smi::FromInt(EQUAL);
+  Object* result;
+  if ((fpclassify(x) == FP_ZERO) && (fpclassify(y) == FP_ZERO)) {
+    result = Smi::FromInt(EQUAL);
+  } else {
+    result = Smi::FromInt(NOT_EQUAL);
+  }
+  return result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NumberCompare) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 3);
+
+  CONVERT_DOUBLE_ARG_CHECKED(x, 0);
+  CONVERT_DOUBLE_ARG_CHECKED(y, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, uncomparable_result, 2)
+  if (std::isnan(x) || std::isnan(y)) return *uncomparable_result;
+  if (x == y) return Smi::FromInt(EQUAL);
+  if (isless(x, y)) return Smi::FromInt(LESS);
+  return Smi::FromInt(GREATER);
+}
+
+
+// Compare two Smis as if they were converted to strings and then
+// compared lexicographically.
+RUNTIME_FUNCTION(Runtime_SmiLexicographicCompare) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_SMI_ARG_CHECKED(x_value, 0);
+  CONVERT_SMI_ARG_CHECKED(y_value, 1);
+
+  // If the integers are equal so are the string representations.
+  if (x_value == y_value) return Smi::FromInt(EQUAL);
+
+  // If one of the integers is zero the normal integer order is the
+  // same as the lexicographic order of the string representations.
+  if (x_value == 0 || y_value == 0)
+    return Smi::FromInt(x_value < y_value ? LESS : GREATER);
+
+  // If only one of the integers is negative the negative number is
+  // smallest because the char code of '-' is less than the char code
+  // of any digit.  Otherwise, we make both values positive.
+
+  // Use unsigned values otherwise the logic is incorrect for -MIN_INT on
+  // architectures using 32-bit Smis.
+  uint32_t x_scaled = x_value;
+  uint32_t y_scaled = y_value;
+  if (x_value < 0 || y_value < 0) {
+    if (y_value >= 0) return Smi::FromInt(LESS);
+    if (x_value >= 0) return Smi::FromInt(GREATER);
+    x_scaled = -x_value;
+    y_scaled = -y_value;
+  }
+
+  static const uint32_t kPowersOf10[] = {
+      1,                 10,                100,         1000,
+      10 * 1000,         100 * 1000,        1000 * 1000, 10 * 1000 * 1000,
+      100 * 1000 * 1000, 1000 * 1000 * 1000};
+
+  // If the integers have the same number of decimal digits they can be
+  // compared directly as the numeric order is the same as the
+  // lexicographic order.  If one integer has fewer digits, it is scaled
+  // by some power of 10 to have the same number of digits as the longer
+  // integer.  If the scaled integers are equal it means the shorter
+  // integer comes first in the lexicographic order.
+
+  // From http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+  int x_log2 = 31 - base::bits::CountLeadingZeros32(x_scaled);
+  int x_log10 = ((x_log2 + 1) * 1233) >> 12;
+  x_log10 -= x_scaled < kPowersOf10[x_log10];
+
+  int y_log2 = 31 - base::bits::CountLeadingZeros32(y_scaled);
+  int y_log10 = ((y_log2 + 1) * 1233) >> 12;
+  y_log10 -= y_scaled < kPowersOf10[y_log10];
+
+  int tie = EQUAL;
+
+  if (x_log10 < y_log10) {
+    // X has fewer digits.  We would like to simply scale up X but that
+    // might overflow, e.g when comparing 9 with 1_000_000_000, 9 would
+    // be scaled up to 9_000_000_000. So we scale up by the next
+    // smallest power and scale down Y to drop one digit. It is OK to
+    // drop one digit from the longer integer since the final digit is
+    // past the length of the shorter integer.
+    x_scaled *= kPowersOf10[y_log10 - x_log10 - 1];
+    y_scaled /= 10;
+    tie = LESS;
+  } else if (y_log10 < x_log10) {
+    y_scaled *= kPowersOf10[x_log10 - y_log10 - 1];
+    x_scaled /= 10;
+    tie = GREATER;
+  }
+
+  if (x_scaled < y_scaled) return Smi::FromInt(LESS);
+  if (x_scaled > y_scaled) return Smi::FromInt(GREATER);
+  return Smi::FromInt(tie);
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetRootNaN) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  RUNTIME_ASSERT(isolate->bootstrapper()->IsActive());
+  return isolate->heap()->nan_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_MaxSmi) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  return Smi::FromInt(Smi::kMaxValue);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_NumberToString) {
+  SealHandleScope shs(isolate);
+  return __RT_impl_Runtime_NumberToStringRT(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsSmi) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  return isolate->heap()->ToBoolean(obj->IsSmi());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsNonNegativeSmi) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  return isolate->heap()->ToBoolean(obj->IsSmi() &&
+                                    Smi::cast(obj)->value() >= 0);
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc
new file mode 100644
index 0000000..407f237
--- /dev/null
+++ b/src/runtime/runtime-object.cc
@@ -0,0 +1,1610 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/bootstrapper.h"
+#include "src/debug.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+// Returns a single character string where first character equals
+// string->Get(index).
+static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
+  if (index < static_cast<uint32_t>(string->length())) {
+    Factory* factory = string->GetIsolate()->factory();
+    return factory->LookupSingleCharacterStringFromCode(
+        String::Flatten(string)->Get(index));
+  }
+  return Execution::CharAt(string, index);
+}
+
+
+MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
+                                                Handle<Object> object,
+                                                uint32_t index) {
+  // Handle [] indexing on Strings
+  if (object->IsString()) {
+    Handle<Object> result = GetCharAt(Handle<String>::cast(object), index);
+    if (!result->IsUndefined()) return result;
+  }
+
+  // Handle [] indexing on String objects
+  if (object->IsStringObjectWithCharacterAt(index)) {
+    Handle<JSValue> js_value = Handle<JSValue>::cast(object);
+    Handle<Object> result =
+        GetCharAt(Handle<String>(String::cast(js_value->value())), index);
+    if (!result->IsUndefined()) return result;
+  }
+
+  Handle<Object> result;
+  if (object->IsString() || object->IsNumber() || object->IsBoolean()) {
+    PrototypeIterator iter(isolate, object);
+    return Object::GetElement(isolate, PrototypeIterator::GetCurrent(iter),
+                              index);
+  } else {
+    return Object::GetElement(isolate, object, index);
+  }
+}
+
+
+MaybeHandle<Name> Runtime::ToName(Isolate* isolate, Handle<Object> key) {
+  if (key->IsName()) {
+    return Handle<Name>::cast(key);
+  } else {
+    Handle<Object> converted;
+    ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
+                               Execution::ToString(isolate, key), Name);
+    return Handle<Name>::cast(converted);
+  }
+}
+
+
+MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
+                                               Handle<Object> object,
+                                               Handle<Object> key) {
+  if (object->IsUndefined() || object->IsNull()) {
+    Handle<Object> args[2] = {key, object};
+    THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_load",
+                                          HandleVector(args, 2)),
+                    Object);
+  }
+
+  // Check if the given key is an array index.
+  uint32_t index;
+  if (key->ToArrayIndex(&index)) {
+    return GetElementOrCharAt(isolate, object, index);
+  }
+
+  // Convert the key to a name - possibly by calling back into JavaScript.
+  Handle<Name> name;
+  ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
+
+  // Check if the name is trivially convertible to an index and get
+  // the element if so.
+  if (name->AsArrayIndex(&index)) {
+    return GetElementOrCharAt(isolate, object, index);
+  } else {
+    return Object::GetProperty(object, name);
+  }
+}
+
+
+MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
+                                               Handle<Object> object,
+                                               Handle<Object> key,
+                                               Handle<Object> value,
+                                               StrictMode strict_mode) {
+  if (object->IsUndefined() || object->IsNull()) {
+    Handle<Object> args[2] = {key, object};
+    THROW_NEW_ERROR(isolate, NewTypeError("non_object_property_store",
+                                          HandleVector(args, 2)),
+                    Object);
+  }
+
+  if (object->IsJSProxy()) {
+    Handle<Object> name_object;
+    if (key->IsSymbol()) {
+      name_object = key;
+    } else {
+      ASSIGN_RETURN_ON_EXCEPTION(isolate, name_object,
+                                 Execution::ToString(isolate, key), Object);
+    }
+    Handle<Name> name = Handle<Name>::cast(name_object);
+    return Object::SetProperty(Handle<JSProxy>::cast(object), name, value,
+                               strict_mode);
+  }
+
+  // Check if the given key is an array index.
+  uint32_t index;
+  if (key->ToArrayIndex(&index)) {
+    // TODO(verwaest): Support non-JSObject receivers.
+    if (!object->IsJSObject()) return value;
+    Handle<JSObject> js_object = Handle<JSObject>::cast(object);
+
+    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
+    // of a string using [] notation.  We need to support this too in
+    // JavaScript.
+    // In the case of a String object we just need to redirect the assignment to
+    // the underlying string if the index is in range.  Since the underlying
+    // string does nothing with the assignment then we can ignore such
+    // assignments.
+    if (js_object->IsStringObjectWithCharacterAt(index)) {
+      return value;
+    }
+
+    JSObject::ValidateElements(js_object);
+    if (js_object->HasExternalArrayElements() ||
+        js_object->HasFixedTypedArrayElements()) {
+      if (!value->IsNumber() && !value->IsUndefined()) {
+        ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
+                                   Execution::ToNumber(isolate, value), Object);
+      }
+    }
+
+    MaybeHandle<Object> result = JSObject::SetElement(
+        js_object, index, value, NONE, strict_mode, true, SET_PROPERTY);
+    JSObject::ValidateElements(js_object);
+
+    return result.is_null() ? result : value;
+  }
+
+  if (key->IsName()) {
+    Handle<Name> name = Handle<Name>::cast(key);
+    if (name->AsArrayIndex(&index)) {
+      // TODO(verwaest): Support non-JSObject receivers.
+      if (!object->IsJSObject()) return value;
+      Handle<JSObject> js_object = Handle<JSObject>::cast(object);
+      if (js_object->HasExternalArrayElements()) {
+        if (!value->IsNumber() && !value->IsUndefined()) {
+          ASSIGN_RETURN_ON_EXCEPTION(
+              isolate, value, Execution::ToNumber(isolate, value), Object);
+        }
+      }
+      return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
+                                  true, SET_PROPERTY);
+    } else {
+      if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
+      return Object::SetProperty(object, name, value, strict_mode);
+    }
+  }
+
+  // Call-back into JavaScript to convert the key to a string.
+  Handle<Object> converted;
+  ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
+                             Execution::ToString(isolate, key), Object);
+  Handle<String> name = Handle<String>::cast(converted);
+
+  if (name->AsArrayIndex(&index)) {
+    // TODO(verwaest): Support non-JSObject receivers.
+    if (!object->IsJSObject()) return value;
+    Handle<JSObject> js_object = Handle<JSObject>::cast(object);
+    return JSObject::SetElement(js_object, index, value, NONE, strict_mode,
+                                true, SET_PROPERTY);
+  }
+  return Object::SetProperty(object, name, value, strict_mode);
+}
+
+
+MaybeHandle<Object> Runtime::DefineObjectProperty(Handle<JSObject> js_object,
+                                                  Handle<Object> key,
+                                                  Handle<Object> value,
+                                                  PropertyAttributes attr) {
+  Isolate* isolate = js_object->GetIsolate();
+  // Check if the given key is an array index.
+  uint32_t index;
+  if (key->ToArrayIndex(&index)) {
+    // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
+    // of a string using [] notation.  We need to support this too in
+    // JavaScript.
+    // In the case of a String object we just need to redirect the assignment to
+    // the underlying string if the index is in range.  Since the underlying
+    // string does nothing with the assignment then we can ignore such
+    // assignments.
+    if (js_object->IsStringObjectWithCharacterAt(index)) {
+      return value;
+    }
+
+    return JSObject::SetElement(js_object, index, value, attr, SLOPPY, false,
+                                DEFINE_PROPERTY);
+  }
+
+  if (key->IsName()) {
+    Handle<Name> name = Handle<Name>::cast(key);
+    if (name->AsArrayIndex(&index)) {
+      return JSObject::SetElement(js_object, index, value, attr, SLOPPY, false,
+                                  DEFINE_PROPERTY);
+    } else {
+      if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
+      return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
+                                                      attr);
+    }
+  }
+
+  // Call-back into JavaScript to convert the key to a string.
+  Handle<Object> converted;
+  ASSIGN_RETURN_ON_EXCEPTION(isolate, converted,
+                             Execution::ToString(isolate, key), Object);
+  Handle<String> name = Handle<String>::cast(converted);
+
+  if (name->AsArrayIndex(&index)) {
+    return JSObject::SetElement(js_object, index, value, attr, SLOPPY, false,
+                                DEFINE_PROPERTY);
+  } else {
+    return JSObject::SetOwnPropertyIgnoreAttributes(js_object, name, value,
+                                                    attr);
+  }
+}
+
+
+MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate,
+                                          Handle<Object> obj) {
+  // We don't expect access checks to be needed on JSProxy objects.
+  DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
+  PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
+  do {
+    if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
+        !isolate->MayNamedAccess(
+            Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
+            isolate->factory()->proto_string(), v8::ACCESS_GET)) {
+      isolate->ReportFailedAccessCheck(
+          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
+          v8::ACCESS_GET);
+      RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+      return isolate->factory()->undefined_value();
+    }
+    iter.AdvanceIgnoringProxies();
+    if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
+      return PrototypeIterator::GetCurrent(iter);
+    }
+  } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
+  return PrototypeIterator::GetCurrent(iter);
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetPrototype) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                     Runtime::GetPrototype(isolate, obj));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+  DCHECK(!obj->IsAccessCheckNeeded());
+  DCHECK(!obj->map()->is_observed());
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, JSObject::SetPrototype(obj, prototype, false));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetPrototype) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+  if (obj->IsAccessCheckNeeded() &&
+      !isolate->MayNamedAccess(obj, isolate->factory()->proto_string(),
+                               v8::ACCESS_SET)) {
+    isolate->ReportFailedAccessCheck(obj, v8::ACCESS_SET);
+    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+    return isolate->heap()->undefined_value();
+  }
+  if (obj->map()->is_observed()) {
+    Handle<Object> old_value =
+        Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
+    Handle<Object> result;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, result, JSObject::SetPrototype(obj, prototype, true));
+
+    Handle<Object> new_value =
+        Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
+    if (!new_value->SameValue(*old_value)) {
+      RETURN_FAILURE_ON_EXCEPTION(
+          isolate, JSObject::EnqueueChangeRecord(
+                       obj, "setPrototype", isolate->factory()->proto_string(),
+                       old_value));
+    }
+    return *result;
+  }
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, JSObject::SetPrototype(obj, prototype, true));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
+  HandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
+  CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
+  PrototypeIterator iter(isolate, V, PrototypeIterator::START_AT_RECEIVER);
+  while (true) {
+    iter.AdvanceIgnoringProxies();
+    if (iter.IsAtEnd()) return isolate->heap()->false_value();
+    if (iter.IsAtEnd(O)) return isolate->heap()->true_value();
+  }
+}
+
+
+// Enumerator used as indices into the array returned from GetOwnProperty
+enum PropertyDescriptorIndices {
+  IS_ACCESSOR_INDEX,
+  VALUE_INDEX,
+  GETTER_INDEX,
+  SETTER_INDEX,
+  WRITABLE_INDEX,
+  ENUMERABLE_INDEX,
+  CONFIGURABLE_INDEX,
+  DESCRIPTOR_SIZE
+};
+
+
+MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
+                                                          Handle<JSObject> obj,
+                                                          Handle<Name> name) {
+  Heap* heap = isolate->heap();
+  Factory* factory = isolate->factory();
+
+  PropertyAttributes attrs;
+  uint32_t index = 0;
+  Handle<Object> value;
+  MaybeHandle<AccessorPair> maybe_accessors;
+  // TODO(verwaest): Unify once indexed properties can be handled by the
+  // LookupIterator.
+  if (name->AsArrayIndex(&index)) {
+    // Get attributes.
+    Maybe<PropertyAttributes> maybe =
+        JSReceiver::GetOwnElementAttribute(obj, index);
+    if (!maybe.has_value) return MaybeHandle<Object>();
+    attrs = maybe.value;
+    if (attrs == ABSENT) return factory->undefined_value();
+
+    // Get AccessorPair if present.
+    maybe_accessors = JSObject::GetOwnElementAccessorPair(obj, index);
+
+    // Get value if not an AccessorPair.
+    if (maybe_accessors.is_null()) {
+      ASSIGN_RETURN_ON_EXCEPTION(
+          isolate, value, Runtime::GetElementOrCharAt(isolate, obj, index),
+          Object);
+    }
+  } else {
+    // Get attributes.
+    LookupIterator it(obj, name, LookupIterator::HIDDEN);
+    Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
+    if (!maybe.has_value) return MaybeHandle<Object>();
+    attrs = maybe.value;
+    if (attrs == ABSENT) return factory->undefined_value();
+
+    // Get AccessorPair if present.
+    if (it.state() == LookupIterator::ACCESSOR &&
+        it.GetAccessors()->IsAccessorPair()) {
+      maybe_accessors = Handle<AccessorPair>::cast(it.GetAccessors());
+    }
+
+    // Get value if not an AccessorPair.
+    if (maybe_accessors.is_null()) {
+      ASSIGN_RETURN_ON_EXCEPTION(isolate, value, Object::GetProperty(&it),
+                                 Object);
+    }
+  }
+  DCHECK(!isolate->has_pending_exception());
+  Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
+  elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
+  elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
+  elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(!maybe_accessors.is_null()));
+
+  Handle<AccessorPair> accessors;
+  if (maybe_accessors.ToHandle(&accessors)) {
+    Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
+    Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
+    elms->set(GETTER_INDEX, *getter);
+    elms->set(SETTER_INDEX, *setter);
+  } else {
+    elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
+    elms->set(VALUE_INDEX, *value);
+  }
+
+  return factory->NewJSArrayWithElements(elms);
+}
+
+
+// Returns an array with the property description:
+//  if args[1] is not a property on args[0]
+//          returns undefined
+//  if args[1] is a data property on args[0]
+//         [false, value, Writeable, Enumerable, Configurable]
+//  if args[1] is an accessor on args[0]
+//         [true, GetFunction, SetFunction, Enumerable, Configurable]
+RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                     GetOwnProperty(isolate, obj, name));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_PreventExtensions) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                     JSObject::PreventExtensions(obj));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsExtensible) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSObject, obj, 0);
+  if (obj->IsJSGlobalProxy()) {
+    PrototypeIterator iter(isolate, obj);
+    if (iter.IsAtEnd()) return isolate->heap()->false_value();
+    DCHECK(iter.GetCurrent()->IsJSGlobalObject());
+    obj = JSObject::cast(iter.GetCurrent());
+  }
+  return isolate->heap()->ToBoolean(obj->map()->is_extensible());
+}
+
+
+RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
+  Handle<Map> old_map(object->map());
+  bool needs_access_checks = old_map->is_access_check_needed();
+  if (needs_access_checks) {
+    // Copy map so it won't interfere constructor's initial map.
+    Handle<Map> new_map = Map::Copy(old_map, "DisableAccessChecks");
+    new_map->set_is_access_check_needed(false);
+    JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
+  }
+  return isolate->heap()->ToBoolean(needs_access_checks);
+}
+
+
+RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  Handle<Map> old_map(object->map());
+  RUNTIME_ASSERT(!old_map->is_access_check_needed());
+  // Copy map so it won't interfere constructor's initial map.
+  Handle<Map> new_map = Map::Copy(old_map, "EnableAccessChecks");
+  new_map->set_is_access_check_needed(true);
+  JSObject::MigrateToMap(object, new_map);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_SMI_ARG_CHECKED(properties, 1);
+  // Conservative upper limit to prevent fuzz tests from going OOM.
+  RUNTIME_ASSERT(properties <= 100000);
+  if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
+    JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties,
+                                  "OptimizeForAdding");
+  }
+  return *object;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+
+  // %ObjectFreeze is a fast path and these cases are handled elsewhere.
+  RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
+                 !object->map()->is_observed() && !object->IsJSProxy());
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ObjectSeal) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+
+  // %ObjectSeal is a fast path and these cases are handled elsewhere.
+  RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
+                 !object->map()->is_observed() && !object->IsJSProxy());
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Seal(object));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetProperty) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, Runtime::GetObjectProperty(isolate, object, key));
+  return *result;
+}
+
+
+MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
+    Handle<Object> object, ElementsKind to_kind, Isolate* isolate) {
+  HandleScope scope(isolate);
+  if (!object->IsJSObject()) {
+    isolate->ThrowIllegalOperation();
+    return MaybeHandle<Object>();
+  }
+  ElementsKind from_kind =
+      Handle<JSObject>::cast(object)->map()->elements_kind();
+  if (Map::IsValidElementsTransition(from_kind, to_kind)) {
+    JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
+    return object;
+  }
+  isolate->ThrowIllegalOperation();
+  return MaybeHandle<Object>();
+}
+
+
+// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
+RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
+
+  // Fast cases for getting named properties of the receiver JSObject
+  // itself.
+  //
+  // The global proxy objects has to be excluded since LookupOwn on
+  // the global proxy object can return a valid result even though the
+  // global proxy object never has properties.  This is the case
+  // because the global proxy object forwards everything to its hidden
+  // prototype including own lookups.
+  //
+  // Additionally, we need to make sure that we do not cache results
+  // for objects that require access checks.
+  if (receiver_obj->IsJSObject()) {
+    if (!receiver_obj->IsJSGlobalProxy() &&
+        !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
+      DisallowHeapAllocation no_allocation;
+      Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
+      Handle<Name> key = Handle<Name>::cast(key_obj);
+      if (receiver->HasFastProperties()) {
+        // Attempt to use lookup cache.
+        Handle<Map> receiver_map(receiver->map(), isolate);
+        KeyedLookupCache* keyed_lookup_cache = isolate->keyed_lookup_cache();
+        int index = keyed_lookup_cache->Lookup(receiver_map, key);
+        if (index != -1) {
+          // Doubles are not cached, so raw read the value.
+          return receiver->RawFastPropertyAt(
+              FieldIndex::ForKeyedLookupCacheIndex(*receiver_map, index));
+        }
+        // Lookup cache miss.  Perform lookup and update the cache if
+        // appropriate.
+        LookupIterator it(receiver, key, LookupIterator::OWN);
+        if (it.state() == LookupIterator::DATA &&
+            it.property_details().type() == FIELD) {
+          FieldIndex field_index = it.GetFieldIndex();
+          // Do not track double fields in the keyed lookup cache. Reading
+          // double values requires boxing.
+          if (!it.representation().IsDouble()) {
+            keyed_lookup_cache->Update(receiver_map, key,
+                                       field_index.GetKeyedLookupCacheIndex());
+          }
+          AllowHeapAllocation allow_allocation;
+          return *JSObject::FastPropertyAt(receiver, it.representation(),
+                                           field_index);
+        }
+      } else {
+        // Attempt dictionary lookup.
+        NameDictionary* dictionary = receiver->property_dictionary();
+        int entry = dictionary->FindEntry(key);
+        if ((entry != NameDictionary::kNotFound) &&
+            (dictionary->DetailsAt(entry).type() == FIELD)) {
+          Object* value = dictionary->ValueAt(entry);
+          if (!receiver->IsGlobalObject()) return value;
+          value = PropertyCell::cast(value)->value();
+          if (!value->IsTheHole()) return value;
+          // If value is the hole (meaning, absent) do the general lookup.
+        }
+      }
+    } else if (key_obj->IsSmi()) {
+      // JSObject without a name key. If the key is a Smi, check for a
+      // definite out-of-bounds access to elements, which is a strong indicator
+      // that subsequent accesses will also call the runtime. Proactively
+      // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
+      // doubles for those future calls in the case that the elements would
+      // become FAST_DOUBLE_ELEMENTS.
+      Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
+      ElementsKind elements_kind = js_object->GetElementsKind();
+      if (IsFastDoubleElementsKind(elements_kind)) {
+        Handle<Smi> key = Handle<Smi>::cast(key_obj);
+        if (key->value() >= js_object->elements()->length()) {
+          if (IsFastHoleyElementsKind(elements_kind)) {
+            elements_kind = FAST_HOLEY_ELEMENTS;
+          } else {
+            elements_kind = FAST_ELEMENTS;
+          }
+          RETURN_FAILURE_ON_EXCEPTION(
+              isolate, TransitionElements(js_object, elements_kind, isolate));
+        }
+      } else {
+        DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
+               !IsFastElementsKind(elements_kind));
+      }
+    }
+  } else if (receiver_obj->IsString() && key_obj->IsSmi()) {
+    // Fast case for string indexing using [] with a smi index.
+    Handle<String> str = Handle<String>::cast(receiver_obj);
+    int index = args.smi_at(1);
+    if (index >= 0 && index < str->length()) {
+      return *GetCharAt(str, index);
+    }
+  }
+
+  // Fall back to GetObjectProperty.
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_AddNamedProperty) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 4);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
+  RUNTIME_ASSERT(
+      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+  // Compute attributes.
+  PropertyAttributes attributes =
+      static_cast<PropertyAttributes>(unchecked_attributes);
+
+#ifdef DEBUG
+  uint32_t index = 0;
+  DCHECK(!key->ToArrayIndex(&index));
+  LookupIterator it(object, key, LookupIterator::OWN_SKIP_INTERCEPTOR);
+  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+  if (!maybe.has_value) return isolate->heap()->exception();
+  RUNTIME_ASSERT(!it.IsFound());
+#endif
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      JSObject::SetOwnPropertyIgnoreAttributes(object, key, value, attributes));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetProperty) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 4);
+
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode_arg, 3);
+  StrictMode strict_mode = strict_mode_arg;
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Runtime::SetObjectProperty(isolate, object, key, value, strict_mode));
+  return *result;
+}
+
+
+// Adds an element to an array.
+// This is used to create an indexed data property into an array.
+RUNTIME_FUNCTION(Runtime_AddElement) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 4);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+  CONVERT_SMI_ARG_CHECKED(unchecked_attributes, 3);
+  RUNTIME_ASSERT(
+      (unchecked_attributes & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+  // Compute attributes.
+  PropertyAttributes attributes =
+      static_cast<PropertyAttributes>(unchecked_attributes);
+
+  uint32_t index = 0;
+  key->ToArrayIndex(&index);
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, JSObject::SetElement(object, index, value, attributes,
+                                            SLOPPY, false, DEFINE_PROPERTY));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_DeleteProperty) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 2);
+  JSReceiver::DeleteMode delete_mode = strict_mode == STRICT
+                                           ? JSReceiver::STRICT_DELETION
+                                           : JSReceiver::NORMAL_DELETION;
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, JSReceiver::DeleteProperty(object, key, delete_mode));
+  return *result;
+}
+
+
+static Object* HasOwnPropertyImplementation(Isolate* isolate,
+                                            Handle<JSObject> object,
+                                            Handle<Name> key) {
+  Maybe<bool> maybe = JSReceiver::HasOwnProperty(object, key);
+  if (!maybe.has_value) return isolate->heap()->exception();
+  if (maybe.value) return isolate->heap()->true_value();
+  // Handle hidden prototypes.  If there's a hidden prototype above this thing
+  // then we have to check it for properties, because they are supposed to
+  // look like they are on this object.
+  PrototypeIterator iter(isolate, object);
+  if (!iter.IsAtEnd() &&
+      Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))
+          ->map()
+          ->is_hidden_prototype()) {
+    // TODO(verwaest): The recursion is not necessary for keys that are array
+    // indices. Removing this.
+    return HasOwnPropertyImplementation(
+        isolate, Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)),
+        key);
+  }
+  RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+  return isolate->heap()->false_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_HasOwnProperty) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0)
+  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+
+  uint32_t index;
+  const bool key_is_array_index = key->AsArrayIndex(&index);
+
+  // Only JS objects can have properties.
+  if (object->IsJSObject()) {
+    Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
+    // Fast case: either the key is a real named property or it is not
+    // an array index and there are no interceptors or hidden
+    // prototypes.
+    Maybe<bool> maybe;
+    if (key_is_array_index) {
+      maybe = JSObject::HasOwnElement(js_obj, index);
+    } else {
+      maybe = JSObject::HasRealNamedProperty(js_obj, key);
+    }
+    if (!maybe.has_value) return isolate->heap()->exception();
+    DCHECK(!isolate->has_pending_exception());
+    if (maybe.value) {
+      return isolate->heap()->true_value();
+    }
+    Map* map = js_obj->map();
+    if (!key_is_array_index && !map->has_named_interceptor() &&
+        !HeapObject::cast(map->prototype())->map()->is_hidden_prototype()) {
+      return isolate->heap()->false_value();
+    }
+    // Slow case.
+    return HasOwnPropertyImplementation(isolate, Handle<JSObject>(js_obj),
+                                        Handle<Name>(key));
+  } else if (object->IsString() && key_is_array_index) {
+    // Well, there is one exception:  Handle [] on strings.
+    Handle<String> string = Handle<String>::cast(object);
+    if (index < static_cast<uint32_t>(string->length())) {
+      return isolate->heap()->true_value();
+    }
+  }
+  return isolate->heap()->false_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_HasProperty) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+
+  Maybe<bool> maybe = JSReceiver::HasProperty(receiver, key);
+  if (!maybe.has_value) return isolate->heap()->exception();
+  return isolate->heap()->ToBoolean(maybe.value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_HasElement) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
+  CONVERT_SMI_ARG_CHECKED(index, 1);
+
+  Maybe<bool> maybe = JSReceiver::HasElement(receiver, index);
+  if (!maybe.has_value) return isolate->heap()->exception();
+  return isolate->heap()->ToBoolean(maybe.value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsPropertyEnumerable) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+
+  Maybe<PropertyAttributes> maybe =
+      JSReceiver::GetOwnPropertyAttributes(object, key);
+  if (!maybe.has_value) return isolate->heap()->exception();
+  if (maybe.value == ABSENT) maybe.value = DONT_ENUM;
+  return isolate->heap()->ToBoolean((maybe.value & DONT_ENUM) == 0);
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetPropertyNames) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, object, 0);
+  Handle<JSArray> result;
+
+  isolate->counters()->for_in()->Increment();
+  Handle<FixedArray> elements;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, elements,
+      JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
+  return *isolate->factory()->NewJSArrayWithElements(elements);
+}
+
+
+// Returns either a FixedArray as Runtime_GetPropertyNames,
+// or, if the given object has an enum cache that contains
+// all enumerable properties of the object and its prototypes
+// have none, the map of the object. This is used to speed up
+// the check for deletions during a for-in.
+RUNTIME_FUNCTION(Runtime_GetPropertyNamesFast) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(JSReceiver, raw_object, 0);
+
+  if (raw_object->IsSimpleEnum()) return raw_object->map();
+
+  HandleScope scope(isolate);
+  Handle<JSReceiver> object(raw_object);
+  Handle<FixedArray> content;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, content,
+      JSReceiver::GetKeys(object, JSReceiver::INCLUDE_PROTOS));
+
+  // Test again, since cache may have been built by preceding call.
+  if (object->IsSimpleEnum()) return object->map();
+
+  return *content;
+}
+
+
+// Find the length of the prototype chain that is to be handled as one. If a
+// prototype object is hidden it is to be viewed as part of the the object it
+// is prototype for.
+static int OwnPrototypeChainLength(JSObject* obj) {
+  int count = 1;
+  for (PrototypeIterator iter(obj->GetIsolate(), obj);
+       !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
+    count++;
+  }
+  return count;
+}
+
+
+// Return the names of the own named properties.
+// args[0]: object
+// args[1]: PropertyAttributes as int
+RUNTIME_FUNCTION(Runtime_GetOwnPropertyNames) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  if (!args[0]->IsJSObject()) {
+    return isolate->heap()->undefined_value();
+  }
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  CONVERT_SMI_ARG_CHECKED(filter_value, 1);
+  PropertyAttributes filter = static_cast<PropertyAttributes>(filter_value);
+
+  // Skip the global proxy as it has no properties and always delegates to the
+  // real global object.
+  if (obj->IsJSGlobalProxy()) {
+    // Only collect names if access is permitted.
+    if (obj->IsAccessCheckNeeded() &&
+        !isolate->MayNamedAccess(obj, isolate->factory()->undefined_value(),
+                                 v8::ACCESS_KEYS)) {
+      isolate->ReportFailedAccessCheck(obj, v8::ACCESS_KEYS);
+      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+      return *isolate->factory()->NewJSArray(0);
+    }
+    PrototypeIterator iter(isolate, obj);
+    obj = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+  }
+
+  // Find the number of objects making up this.
+  int length = OwnPrototypeChainLength(*obj);
+
+  // Find the number of own properties for each of the objects.
+  ScopedVector<int> own_property_count(length);
+  int total_property_count = 0;
+  {
+    PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
+    for (int i = 0; i < length; i++) {
+      DCHECK(!iter.IsAtEnd());
+      Handle<JSObject> jsproto =
+          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+      // Only collect names if access is permitted.
+      if (jsproto->IsAccessCheckNeeded() &&
+          !isolate->MayNamedAccess(jsproto,
+                                   isolate->factory()->undefined_value(),
+                                   v8::ACCESS_KEYS)) {
+        isolate->ReportFailedAccessCheck(jsproto, v8::ACCESS_KEYS);
+        RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+        return *isolate->factory()->NewJSArray(0);
+      }
+      int n;
+      n = jsproto->NumberOfOwnProperties(filter);
+      own_property_count[i] = n;
+      total_property_count += n;
+      iter.Advance();
+    }
+  }
+
+  // Allocate an array with storage for all the property names.
+  Handle<FixedArray> names =
+      isolate->factory()->NewFixedArray(total_property_count);
+
+  // Get the property names.
+  int next_copy_index = 0;
+  int hidden_strings = 0;
+  {
+    PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
+    for (int i = 0; i < length; i++) {
+      DCHECK(!iter.IsAtEnd());
+      Handle<JSObject> jsproto =
+          Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+      jsproto->GetOwnPropertyNames(*names, next_copy_index, filter);
+      // Names from hidden prototypes may already have been added
+      // for inherited function template instances. Count the duplicates
+      // and stub them out; the final copy pass at the end ignores holes.
+      for (int j = next_copy_index; j < next_copy_index + own_property_count[i];
+           j++) {
+        Object* name_from_hidden_proto = names->get(j);
+        if (isolate->IsInternallyUsedPropertyName(name_from_hidden_proto)) {
+          hidden_strings++;
+        } else {
+          for (int k = 0; k < next_copy_index; k++) {
+            Object* name = names->get(k);
+            if (name_from_hidden_proto == name) {
+              names->set(j, isolate->heap()->hidden_string());
+              hidden_strings++;
+              break;
+            }
+          }
+        }
+      }
+      next_copy_index += own_property_count[i];
+
+      iter.Advance();
+    }
+  }
+
+  // Filter out name of hidden properties object and
+  // hidden prototype duplicates.
+  if (hidden_strings > 0) {
+    Handle<FixedArray> old_names = names;
+    names = isolate->factory()->NewFixedArray(names->length() - hidden_strings);
+    int dest_pos = 0;
+    for (int i = 0; i < total_property_count; i++) {
+      Object* name = old_names->get(i);
+      if (isolate->IsInternallyUsedPropertyName(name)) {
+        hidden_strings--;
+        continue;
+      }
+      names->set(dest_pos++, name);
+    }
+    DCHECK_EQ(0, hidden_strings);
+  }
+
+  return *isolate->factory()->NewJSArrayWithElements(names);
+}
+
+
+// Return the names of the own indexed properties.
+// args[0]: object
+RUNTIME_FUNCTION(Runtime_GetOwnElementNames) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  if (!args[0]->IsJSObject()) {
+    return isolate->heap()->undefined_value();
+  }
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+
+  int n = obj->NumberOfOwnElements(static_cast<PropertyAttributes>(NONE));
+  Handle<FixedArray> names = isolate->factory()->NewFixedArray(n);
+  obj->GetOwnElementKeys(*names, static_cast<PropertyAttributes>(NONE));
+  return *isolate->factory()->NewJSArrayWithElements(names);
+}
+
+
+// Return information on whether an object has a named or indexed interceptor.
+// args[0]: object
+RUNTIME_FUNCTION(Runtime_GetInterceptorInfo) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  if (!args[0]->IsJSObject()) {
+    return Smi::FromInt(0);
+  }
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+
+  int result = 0;
+  if (obj->HasNamedInterceptor()) result |= 2;
+  if (obj->HasIndexedInterceptor()) result |= 1;
+
+  return Smi::FromInt(result);
+}
+
+
+// Return property names from named interceptor.
+// args[0]: object
+RUNTIME_FUNCTION(Runtime_GetNamedInterceptorPropertyNames) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+
+  if (obj->HasNamedInterceptor()) {
+    Handle<JSObject> result;
+    if (JSObject::GetKeysForNamedInterceptor(obj, obj).ToHandle(&result)) {
+      return *result;
+    }
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+// Return element names from indexed interceptor.
+// args[0]: object
+RUNTIME_FUNCTION(Runtime_GetIndexedInterceptorElementNames) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+
+  if (obj->HasIndexedInterceptor()) {
+    Handle<JSObject> result;
+    if (JSObject::GetKeysForIndexedInterceptor(obj, obj).ToHandle(&result)) {
+      return *result;
+    }
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_OwnKeys) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSObject, raw_object, 0);
+  Handle<JSObject> object(raw_object);
+
+  if (object->IsJSGlobalProxy()) {
+    // Do access checks before going to the global object.
+    if (object->IsAccessCheckNeeded() &&
+        !isolate->MayNamedAccess(object, isolate->factory()->undefined_value(),
+                                 v8::ACCESS_KEYS)) {
+      isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS);
+      RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+      return *isolate->factory()->NewJSArray(0);
+    }
+
+    PrototypeIterator iter(isolate, object);
+    // If proxy is detached we simply return an empty array.
+    if (iter.IsAtEnd()) return *isolate->factory()->NewJSArray(0);
+    object = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
+  }
+
+  Handle<FixedArray> contents;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, contents, JSReceiver::GetKeys(object, JSReceiver::OWN_ONLY));
+
+  // Some fast paths through GetKeysInFixedArrayFor reuse a cached
+  // property array and since the result is mutable we have to create
+  // a fresh clone on each invocation.
+  int length = contents->length();
+  Handle<FixedArray> copy = isolate->factory()->NewFixedArray(length);
+  for (int i = 0; i < length; i++) {
+    Object* entry = contents->get(i);
+    if (entry->IsString()) {
+      copy->set(i, entry);
+    } else {
+      DCHECK(entry->IsNumber());
+      HandleScope scope(isolate);
+      Handle<Object> entry_handle(entry, isolate);
+      Handle<Object> entry_str =
+          isolate->factory()->NumberToString(entry_handle);
+      copy->set(i, *entry_str);
+    }
+  }
+  return *isolate->factory()->NewJSArrayWithElements(copy);
+}
+
+
+RUNTIME_FUNCTION(Runtime_ToFastProperties) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  if (object->IsJSObject() && !object->IsGlobalObject()) {
+    JSObject::MigrateSlowToFast(Handle<JSObject>::cast(object), 0,
+                                "RuntimeToFastProperties");
+  }
+  return *object;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ToBool) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, object, 0);
+
+  return isolate->heap()->ToBoolean(object->BooleanValue());
+}
+
+
+// Returns the type string of a value; see ECMA-262, 11.4.3 (p 47).
+// Possible optimizations: put the type string into the oddballs.
+RUNTIME_FUNCTION(Runtime_Typeof) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  if (obj->IsNumber()) return isolate->heap()->number_string();
+  HeapObject* heap_obj = HeapObject::cast(obj);
+
+  // typeof an undetectable object is 'undefined'
+  if (heap_obj->map()->is_undetectable()) {
+    return isolate->heap()->undefined_string();
+  }
+
+  InstanceType instance_type = heap_obj->map()->instance_type();
+  if (instance_type < FIRST_NONSTRING_TYPE) {
+    return isolate->heap()->string_string();
+  }
+
+  switch (instance_type) {
+    case ODDBALL_TYPE:
+      if (heap_obj->IsTrue() || heap_obj->IsFalse()) {
+        return isolate->heap()->boolean_string();
+      }
+      if (heap_obj->IsNull()) {
+        return isolate->heap()->object_string();
+      }
+      DCHECK(heap_obj->IsUndefined());
+      return isolate->heap()->undefined_string();
+    case SYMBOL_TYPE:
+      return isolate->heap()->symbol_string();
+    case JS_FUNCTION_TYPE:
+    case JS_FUNCTION_PROXY_TYPE:
+      return isolate->heap()->function_string();
+    default:
+      // For any kind of object not handled above, the spec rule for
+      // host objects gives that it is okay to return "object"
+      return isolate->heap()->object_string();
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_Booleanize) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(Object, value_raw, 0);
+  CONVERT_SMI_ARG_CHECKED(token_raw, 1);
+  intptr_t value = reinterpret_cast<intptr_t>(value_raw);
+  Token::Value token = static_cast<Token::Value>(token_raw);
+  switch (token) {
+    case Token::EQ:
+    case Token::EQ_STRICT:
+      return isolate->heap()->ToBoolean(value == 0);
+    case Token::NE:
+    case Token::NE_STRICT:
+      return isolate->heap()->ToBoolean(value != 0);
+    case Token::LT:
+      return isolate->heap()->ToBoolean(value < 0);
+    case Token::GT:
+      return isolate->heap()->ToBoolean(value > 0);
+    case Token::LTE:
+      return isolate->heap()->ToBoolean(value <= 0);
+    case Token::GTE:
+      return isolate->heap()->ToBoolean(value >= 0);
+    default:
+      // This should only happen during natives fuzzing.
+      return isolate->heap()->undefined_value();
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewStringWrapper) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, value, 0);
+  return *Object::ToObject(isolate, value).ToHandleChecked();
+}
+
+
+RUNTIME_FUNCTION(Runtime_AllocateHeapNumber) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  return *isolate->factory()->NewHeapNumber(0);
+}
+
+
+static Object* Runtime_NewObjectHelper(Isolate* isolate,
+                                       Handle<Object> constructor,
+                                       Handle<AllocationSite> site) {
+  // If the constructor isn't a proper function we throw a type error.
+  if (!constructor->IsJSFunction()) {
+    Vector<Handle<Object> > arguments = HandleVector(&constructor, 1);
+    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+                                   NewTypeError("not_constructor", arguments));
+  }
+
+  Handle<JSFunction> function = Handle<JSFunction>::cast(constructor);
+
+  // If function should not have prototype, construction is not allowed. In this
+  // case generated code bailouts here, since function has no initial_map.
+  if (!function->should_have_prototype() && !function->shared()->bound()) {
+    Vector<Handle<Object> > arguments = HandleVector(&constructor, 1);
+    THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+                                   NewTypeError("not_constructor", arguments));
+  }
+
+  Debug* debug = isolate->debug();
+  // Handle stepping into constructors if step into is active.
+  if (debug->StepInActive()) {
+    debug->HandleStepIn(function, Handle<Object>::null(), 0, true);
+  }
+
+  if (function->has_initial_map()) {
+    if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
+      // The 'Function' function ignores the receiver object when
+      // called using 'new' and creates a new JSFunction object that
+      // is returned.  The receiver object is only used for error
+      // reporting if an error occurs when constructing the new
+      // JSFunction. Factory::NewJSObject() should not be used to
+      // allocate JSFunctions since it does not properly initialize
+      // the shared part of the function. Since the receiver is
+      // ignored anyway, we use the global object as the receiver
+      // instead of a new JSFunction object. This way, errors are
+      // reported the same way whether or not 'Function' is called
+      // using 'new'.
+      return isolate->global_proxy();
+    }
+  }
+
+  // The function should be compiled for the optimization hints to be
+  // available.
+  Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
+
+  Handle<JSObject> result;
+  if (site.is_null()) {
+    result = isolate->factory()->NewJSObject(function);
+  } else {
+    result = isolate->factory()->NewJSObjectWithMemento(function, site);
+  }
+
+  isolate->counters()->constructed_objects()->Increment();
+  isolate->counters()->constructed_objects_runtime()->Increment();
+
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewObject) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 0);
+  return Runtime_NewObjectHelper(isolate, constructor,
+                                 Handle<AllocationSite>::null());
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewObjectWithAllocationSite) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, constructor, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, feedback, 0);
+  Handle<AllocationSite> site;
+  if (feedback->IsAllocationSite()) {
+    // The feedback can be an AllocationSite or undefined.
+    site = Handle<AllocationSite>::cast(feedback);
+  }
+  return Runtime_NewObjectHelper(isolate, constructor, site);
+}
+
+
+RUNTIME_FUNCTION(Runtime_FinalizeInstanceSize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  function->CompleteInobjectSlackTracking();
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GlobalProxy) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, global, 0);
+  if (!global->IsJSGlobalObject()) return isolate->heap()->null_value();
+  return JSGlobalObject::cast(global)->global_proxy();
+}
+
+
+RUNTIME_FUNCTION(Runtime_LookupAccessor) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+  CONVERT_SMI_ARG_CHECKED(flag, 2);
+  AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
+  if (!receiver->IsJSObject()) return isolate->heap()->undefined_value();
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      JSObject::GetAccessor(Handle<JSObject>::cast(receiver), name, component));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_LoadMutableDouble) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Smi, index, 1);
+  RUNTIME_ASSERT((index->value() & 1) == 1);
+  FieldIndex field_index =
+      FieldIndex::ForLoadByFieldIndex(object->map(), index->value());
+  if (field_index.is_inobject()) {
+    RUNTIME_ASSERT(field_index.property_index() <
+                   object->map()->inobject_properties());
+  } else {
+    RUNTIME_ASSERT(field_index.outobject_array_index() <
+                   object->properties()->length());
+  }
+  return *JSObject::FastPropertyAt(object, Representation::Double(),
+                                   field_index);
+}
+
+
+RUNTIME_FUNCTION(Runtime_TryMigrateInstance) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+  if (!object->IsJSObject()) return Smi::FromInt(0);
+  Handle<JSObject> js_object = Handle<JSObject>::cast(object);
+  if (!js_object->map()->is_deprecated()) return Smi::FromInt(0);
+  // This call must not cause lazy deopts, because it's called from deferred
+  // code where we can't handle lazy deopts for lack of a suitable bailout
+  // ID. So we just try migration and signal failure if necessary,
+  // which will also trigger a deopt.
+  if (!JSObject::TryMigrateInstance(js_object)) return Smi::FromInt(0);
+  return *object;
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsJSGlobalProxy) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  return isolate->heap()->ToBoolean(obj->IsJSGlobalProxy());
+}
+
+
+static bool IsValidAccessor(Handle<Object> obj) {
+  return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
+}
+
+
+// Implements part of 8.12.9 DefineOwnProperty.
+// There are 3 cases that lead here:
+// Step 4b - define a new accessor property.
+// Steps 9c & 12 - replace an existing data property with an accessor property.
+// Step 12 - update an existing accessor property with an accessor or generic
+//           descriptor.
+RUNTIME_FUNCTION(Runtime_DefineAccessorPropertyUnchecked) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 5);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+  RUNTIME_ASSERT(!obj->IsNull());
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
+  RUNTIME_ASSERT(IsValidAccessor(getter));
+  CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
+  RUNTIME_ASSERT(IsValidAccessor(setter));
+  CONVERT_SMI_ARG_CHECKED(unchecked, 4);
+  RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+  PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
+
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, JSObject::DefineAccessor(obj, name, getter, setter, attr));
+  return isolate->heap()->undefined_value();
+}
+
+
+// Implements part of 8.12.9 DefineOwnProperty.
+// There are 3 cases that lead here:
+// Step 4a - define a new data property.
+// Steps 9b & 12 - replace an existing accessor property with a data property.
+// Step 12 - update an existing data property with a data or generic
+//           descriptor.
+RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
+  CONVERT_SMI_ARG_CHECKED(unchecked, 3);
+  RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
+  PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
+
+  LookupIterator it(js_object, name, LookupIterator::OWN_SKIP_INTERCEPTOR);
+  if (it.IsFound() && it.state() == LookupIterator::ACCESS_CHECK) {
+    if (!isolate->MayNamedAccess(js_object, name, v8::ACCESS_SET)) {
+      return isolate->heap()->undefined_value();
+    }
+    it.Next();
+  }
+
+  // Take special care when attributes are different and there is already
+  // a property.
+  if (it.state() == LookupIterator::ACCESSOR) {
+    // Use IgnoreAttributes version since a readonly property may be
+    // overridden and SetProperty does not allow this.
+    Handle<Object> result;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, result,
+        JSObject::SetOwnPropertyIgnoreAttributes(
+            js_object, name, obj_value, attr, JSObject::DONT_FORCE_FIELD));
+    return *result;
+  }
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Runtime::DefineObjectProperty(js_object, name, obj_value, attr));
+  return *result;
+}
+
+
+// Return property without being observable by accessors or interceptors.
+RUNTIME_FUNCTION(Runtime_GetDataProperty) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
+  return *JSObject::GetDataProperty(object, key);
+}
+
+
+RUNTIME_FUNCTION(Runtime_HasFastPackedElements) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(HeapObject, obj, 0);
+  return isolate->heap()->ToBoolean(
+      IsFastPackedElementsKind(obj->map()->elements_kind()));
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_ValueOf) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  if (!obj->IsJSValue()) return obj;
+  return JSValue::cast(obj)->value();
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_SetValueOf) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  CONVERT_ARG_CHECKED(Object, value, 1);
+  if (!obj->IsJSValue()) return value;
+  JSValue::cast(obj)->set_value(value);
+  return value;
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_ObjectEquals) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(Object, obj1, 0);
+  CONVERT_ARG_CHECKED(Object, obj2, 1);
+  return isolate->heap()->ToBoolean(obj1 == obj2);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsObject) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  if (!obj->IsHeapObject()) return isolate->heap()->false_value();
+  if (obj->IsNull()) return isolate->heap()->true_value();
+  if (obj->IsUndetectableObject()) return isolate->heap()->false_value();
+  Map* map = HeapObject::cast(obj)->map();
+  bool is_non_callable_spec_object =
+      map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
+      map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE;
+  return isolate->heap()->ToBoolean(is_non_callable_spec_object);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsUndetectableObject) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  return isolate->heap()->ToBoolean(obj->IsUndetectableObject());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsSpecObject) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  return isolate->heap()->ToBoolean(obj->IsSpecObject());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_ClassOf) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  if (!obj->IsJSReceiver()) return isolate->heap()->null_value();
+  return JSReceiver::cast(obj)->class_name();
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-observe.cc b/src/runtime/runtime-observe.cc
new file mode 100644
index 0000000..211922c
--- /dev/null
+++ b/src/runtime/runtime-observe.cc
@@ -0,0 +1,160 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/debug.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_IsObserved) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  if (!args[0]->IsJSReceiver()) return isolate->heap()->false_value();
+  CONVERT_ARG_CHECKED(JSReceiver, obj, 0);
+  DCHECK(!obj->IsJSGlobalProxy() || !obj->map()->is_observed());
+  return isolate->heap()->ToBoolean(obj->map()->is_observed());
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetIsObserved) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, obj, 0);
+  RUNTIME_ASSERT(!obj->IsJSGlobalProxy());
+  if (obj->IsJSProxy()) return isolate->heap()->undefined_value();
+  RUNTIME_ASSERT(!obj->map()->is_observed());
+
+  DCHECK(obj->IsJSObject());
+  JSObject::SetObserved(Handle<JSObject>::cast(obj));
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_EnqueueMicrotask) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, microtask, 0);
+  isolate->EnqueueMicrotask(microtask);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_RunMicrotasks) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  isolate->RunMicrotasks();
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DeliverObservationChangeRecords) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, callback, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, argument, 1);
+  v8::TryCatch catcher;
+  // We should send a message on uncaught exception thrown during
+  // Object.observe delivery while not interrupting further delivery, thus
+  // we make a call inside a verbose TryCatch.
+  catcher.SetVerbose(true);
+  Handle<Object> argv[] = {argument};
+
+  // Allow stepping into the observer callback.
+  Debug* debug = isolate->debug();
+  if (debug->is_active() && debug->IsStepping() &&
+      debug->last_step_action() == StepIn) {
+    // Previous StepIn may have activated a StepOut if it was at the frame exit.
+    // In this case to be able to step into the callback again, we need to clear
+    // the step out first.
+    debug->ClearStepOut();
+    debug->FloodWithOneShot(callback);
+  }
+
+  USE(Execution::Call(isolate, callback, isolate->factory()->undefined_value(),
+                      arraysize(argv), argv));
+  if (isolate->has_pending_exception()) {
+    isolate->ReportPendingMessages();
+    isolate->clear_pending_exception();
+    isolate->set_external_caught_exception(false);
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetObservationState) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  return isolate->heap()->observation_state();
+}
+
+
+static bool ContextsHaveSameOrigin(Handle<Context> context1,
+                                   Handle<Context> context2) {
+  return context1->security_token() == context2->security_token();
+}
+
+
+RUNTIME_FUNCTION(Runtime_ObserverObjectAndRecordHaveSameOrigin) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, observer, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, record, 2);
+
+  Handle<Context> observer_context(observer->context()->native_context());
+  Handle<Context> object_context(object->GetCreationContext());
+  Handle<Context> record_context(record->GetCreationContext());
+
+  return isolate->heap()->ToBoolean(
+      ContextsHaveSameOrigin(object_context, observer_context) &&
+      ContextsHaveSameOrigin(object_context, record_context));
+}
+
+
+RUNTIME_FUNCTION(Runtime_ObjectWasCreatedInCurrentOrigin) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+
+  Handle<Context> creation_context(object->GetCreationContext(), isolate);
+  return isolate->heap()->ToBoolean(
+      ContextsHaveSameOrigin(creation_context, isolate->native_context()));
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetObjectContextObjectObserve) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+
+  Handle<Context> context(object->GetCreationContext(), isolate);
+  return context->native_object_observe();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetObjectContextObjectGetNotifier) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+
+  Handle<Context> context(object->GetCreationContext(), isolate);
+  return context->native_object_get_notifier();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetObjectContextNotifierPerformChange) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSObject, object_info, 0);
+
+  Handle<Context> context(object_info->GetCreationContext(), isolate);
+  return context->native_object_notifier_perform_change();
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-proxy.cc b/src/runtime/runtime-proxy.cc
new file mode 100644
index 0000000..baf7cdb
--- /dev/null
+++ b/src/runtime/runtime-proxy.cc
@@ -0,0 +1,85 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_CreateJSProxy) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+  if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
+  return *isolate->factory()->NewJSProxy(handler, prototype);
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, call_trap, 1);
+  RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2);
+  CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3);
+  if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
+  return *isolate->factory()->NewJSFunctionProxy(handler, call_trap,
+                                                 construct_trap, prototype);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsJSProxy) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  return isolate->heap()->ToBoolean(obj->IsJSProxy());
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsJSFunctionProxy) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
+  return isolate->heap()->ToBoolean(obj->IsJSFunctionProxy());
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetHandler) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
+  return proxy->handler();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetCallTrap) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
+  return proxy->call_trap();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetConstructTrap) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunctionProxy, proxy, 0);
+  return proxy->construct_trap();
+}
+
+
+RUNTIME_FUNCTION(Runtime_Fix) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
+  JSProxy::Fix(proxy);
+  return isolate->heap()->undefined_value();
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-regexp.cc b/src/runtime/runtime-regexp.cc
new file mode 100644
index 0000000..9296a4b
--- /dev/null
+++ b/src/runtime/runtime-regexp.cc
@@ -0,0 +1,1122 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/jsregexp-inl.h"
+#include "src/jsregexp.h"
+#include "src/runtime/runtime-utils.h"
+#include "src/string-builder.h"
+#include "src/string-search.h"
+
+namespace v8 {
+namespace internal {
+
+class CompiledReplacement {
+ public:
+  explicit CompiledReplacement(Zone* zone)
+      : parts_(1, zone), replacement_substrings_(0, zone), zone_(zone) {}
+
+  // Return whether the replacement is simple.
+  bool Compile(Handle<String> replacement, int capture_count,
+               int subject_length);
+
+  // Use Apply only if Compile returned false.
+  void Apply(ReplacementStringBuilder* builder, int match_from, int match_to,
+             int32_t* match);
+
+  // Number of distinct parts of the replacement pattern.
+  int parts() { return parts_.length(); }
+
+  Zone* zone() const { return zone_; }
+
+ private:
+  enum PartType {
+    SUBJECT_PREFIX = 1,
+    SUBJECT_SUFFIX,
+    SUBJECT_CAPTURE,
+    REPLACEMENT_SUBSTRING,
+    REPLACEMENT_STRING,
+    NUMBER_OF_PART_TYPES
+  };
+
+  struct ReplacementPart {
+    static inline ReplacementPart SubjectMatch() {
+      return ReplacementPart(SUBJECT_CAPTURE, 0);
+    }
+    static inline ReplacementPart SubjectCapture(int capture_index) {
+      return ReplacementPart(SUBJECT_CAPTURE, capture_index);
+    }
+    static inline ReplacementPart SubjectPrefix() {
+      return ReplacementPart(SUBJECT_PREFIX, 0);
+    }
+    static inline ReplacementPart SubjectSuffix(int subject_length) {
+      return ReplacementPart(SUBJECT_SUFFIX, subject_length);
+    }
+    static inline ReplacementPart ReplacementString() {
+      return ReplacementPart(REPLACEMENT_STRING, 0);
+    }
+    static inline ReplacementPart ReplacementSubString(int from, int to) {
+      DCHECK(from >= 0);
+      DCHECK(to > from);
+      return ReplacementPart(-from, to);
+    }
+
+    // If tag <= 0 then it is the negation of a start index of a substring of
+    // the replacement pattern, otherwise it's a value from PartType.
+    ReplacementPart(int tag, int data) : tag(tag), data(data) {
+      // Must be non-positive or a PartType value.
+      DCHECK(tag < NUMBER_OF_PART_TYPES);
+    }
+    // Either a value of PartType or a non-positive number that is
+    // the negation of an index into the replacement string.
+    int tag;
+    // The data value's interpretation depends on the value of tag:
+    // tag == SUBJECT_PREFIX ||
+    // tag == SUBJECT_SUFFIX:  data is unused.
+    // tag == SUBJECT_CAPTURE: data is the number of the capture.
+    // tag == REPLACEMENT_SUBSTRING ||
+    // tag == REPLACEMENT_STRING:    data is index into array of substrings
+    //                               of the replacement string.
+    // tag <= 0: Temporary representation of the substring of the replacement
+    //           string ranging over -tag .. data.
+    //           Is replaced by REPLACEMENT_{SUB,}STRING when we create the
+    //           substring objects.
+    int data;
+  };
+
+  template <typename Char>
+  bool ParseReplacementPattern(ZoneList<ReplacementPart>* parts,
+                               Vector<Char> characters, int capture_count,
+                               int subject_length, Zone* zone) {
+    int length = characters.length();
+    int last = 0;
+    for (int i = 0; i < length; i++) {
+      Char c = characters[i];
+      if (c == '$') {
+        int next_index = i + 1;
+        if (next_index == length) {  // No next character!
+          break;
+        }
+        Char c2 = characters[next_index];
+        switch (c2) {
+          case '$':
+            if (i > last) {
+              // There is a substring before. Include the first "$".
+              parts->Add(
+                  ReplacementPart::ReplacementSubString(last, next_index),
+                  zone);
+              last = next_index + 1;  // Continue after the second "$".
+            } else {
+              // Let the next substring start with the second "$".
+              last = next_index;
+            }
+            i = next_index;
+            break;
+          case '`':
+            if (i > last) {
+              parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
+            }
+            parts->Add(ReplacementPart::SubjectPrefix(), zone);
+            i = next_index;
+            last = i + 1;
+            break;
+          case '\'':
+            if (i > last) {
+              parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
+            }
+            parts->Add(ReplacementPart::SubjectSuffix(subject_length), zone);
+            i = next_index;
+            last = i + 1;
+            break;
+          case '&':
+            if (i > last) {
+              parts->Add(ReplacementPart::ReplacementSubString(last, i), zone);
+            }
+            parts->Add(ReplacementPart::SubjectMatch(), zone);
+            i = next_index;
+            last = i + 1;
+            break;
+          case '0':
+          case '1':
+          case '2':
+          case '3':
+          case '4':
+          case '5':
+          case '6':
+          case '7':
+          case '8':
+          case '9': {
+            int capture_ref = c2 - '0';
+            if (capture_ref > capture_count) {
+              i = next_index;
+              continue;
+            }
+            int second_digit_index = next_index + 1;
+            if (second_digit_index < length) {
+              // Peek ahead to see if we have two digits.
+              Char c3 = characters[second_digit_index];
+              if ('0' <= c3 && c3 <= '9') {  // Double digits.
+                int double_digit_ref = capture_ref * 10 + c3 - '0';
+                if (double_digit_ref <= capture_count) {
+                  next_index = second_digit_index;
+                  capture_ref = double_digit_ref;
+                }
+              }
+            }
+            if (capture_ref > 0) {
+              if (i > last) {
+                parts->Add(ReplacementPart::ReplacementSubString(last, i),
+                           zone);
+              }
+              DCHECK(capture_ref <= capture_count);
+              parts->Add(ReplacementPart::SubjectCapture(capture_ref), zone);
+              last = next_index + 1;
+            }
+            i = next_index;
+            break;
+          }
+          default:
+            i = next_index;
+            break;
+        }
+      }
+    }
+    if (length > last) {
+      if (last == 0) {
+        // Replacement is simple.  Do not use Apply to do the replacement.
+        return true;
+      } else {
+        parts->Add(ReplacementPart::ReplacementSubString(last, length), zone);
+      }
+    }
+    return false;
+  }
+
+  ZoneList<ReplacementPart> parts_;
+  ZoneList<Handle<String> > replacement_substrings_;
+  Zone* zone_;
+};
+
+
+bool CompiledReplacement::Compile(Handle<String> replacement, int capture_count,
+                                  int subject_length) {
+  {
+    DisallowHeapAllocation no_gc;
+    String::FlatContent content = replacement->GetFlatContent();
+    DCHECK(content.IsFlat());
+    bool simple = false;
+    if (content.IsOneByte()) {
+      simple = ParseReplacementPattern(&parts_, content.ToOneByteVector(),
+                                       capture_count, subject_length, zone());
+    } else {
+      DCHECK(content.IsTwoByte());
+      simple = ParseReplacementPattern(&parts_, content.ToUC16Vector(),
+                                       capture_count, subject_length, zone());
+    }
+    if (simple) return true;
+  }
+
+  Isolate* isolate = replacement->GetIsolate();
+  // Find substrings of replacement string and create them as String objects.
+  int substring_index = 0;
+  for (int i = 0, n = parts_.length(); i < n; i++) {
+    int tag = parts_[i].tag;
+    if (tag <= 0) {  // A replacement string slice.
+      int from = -tag;
+      int to = parts_[i].data;
+      replacement_substrings_.Add(
+          isolate->factory()->NewSubString(replacement, from, to), zone());
+      parts_[i].tag = REPLACEMENT_SUBSTRING;
+      parts_[i].data = substring_index;
+      substring_index++;
+    } else if (tag == REPLACEMENT_STRING) {
+      replacement_substrings_.Add(replacement, zone());
+      parts_[i].data = substring_index;
+      substring_index++;
+    }
+  }
+  return false;
+}
+
+
+void CompiledReplacement::Apply(ReplacementStringBuilder* builder,
+                                int match_from, int match_to, int32_t* match) {
+  DCHECK_LT(0, parts_.length());
+  for (int i = 0, n = parts_.length(); i < n; i++) {
+    ReplacementPart part = parts_[i];
+    switch (part.tag) {
+      case SUBJECT_PREFIX:
+        if (match_from > 0) builder->AddSubjectSlice(0, match_from);
+        break;
+      case SUBJECT_SUFFIX: {
+        int subject_length = part.data;
+        if (match_to < subject_length) {
+          builder->AddSubjectSlice(match_to, subject_length);
+        }
+        break;
+      }
+      case SUBJECT_CAPTURE: {
+        int capture = part.data;
+        int from = match[capture * 2];
+        int to = match[capture * 2 + 1];
+        if (from >= 0 && to > from) {
+          builder->AddSubjectSlice(from, to);
+        }
+        break;
+      }
+      case REPLACEMENT_SUBSTRING:
+      case REPLACEMENT_STRING:
+        builder->AddString(replacement_substrings_[part.data]);
+        break;
+      default:
+        UNREACHABLE();
+    }
+  }
+}
+
+
+void FindOneByteStringIndices(Vector<const uint8_t> subject, uint8_t pattern,
+                              ZoneList<int>* indices, unsigned int limit,
+                              Zone* zone) {
+  DCHECK(limit > 0);
+  // Collect indices of pattern in subject using memchr.
+  // Stop after finding at most limit values.
+  const uint8_t* subject_start = subject.start();
+  const uint8_t* subject_end = subject_start + subject.length();
+  const uint8_t* pos = subject_start;
+  while (limit > 0) {
+    pos = reinterpret_cast<const uint8_t*>(
+        memchr(pos, pattern, subject_end - pos));
+    if (pos == NULL) return;
+    indices->Add(static_cast<int>(pos - subject_start), zone);
+    pos++;
+    limit--;
+  }
+}
+
+
+void FindTwoByteStringIndices(const Vector<const uc16> subject, uc16 pattern,
+                              ZoneList<int>* indices, unsigned int limit,
+                              Zone* zone) {
+  DCHECK(limit > 0);
+  const uc16* subject_start = subject.start();
+  const uc16* subject_end = subject_start + subject.length();
+  for (const uc16* pos = subject_start; pos < subject_end && limit > 0; pos++) {
+    if (*pos == pattern) {
+      indices->Add(static_cast<int>(pos - subject_start), zone);
+      limit--;
+    }
+  }
+}
+
+
+template <typename SubjectChar, typename PatternChar>
+void FindStringIndices(Isolate* isolate, Vector<const SubjectChar> subject,
+                       Vector<const PatternChar> pattern,
+                       ZoneList<int>* indices, unsigned int limit, Zone* zone) {
+  DCHECK(limit > 0);
+  // Collect indices of pattern in subject.
+  // Stop after finding at most limit values.
+  int pattern_length = pattern.length();
+  int index = 0;
+  StringSearch<PatternChar, SubjectChar> search(isolate, pattern);
+  while (limit > 0) {
+    index = search.Search(subject, index);
+    if (index < 0) return;
+    indices->Add(index, zone);
+    index += pattern_length;
+    limit--;
+  }
+}
+
+
+void FindStringIndicesDispatch(Isolate* isolate, String* subject,
+                               String* pattern, ZoneList<int>* indices,
+                               unsigned int limit, Zone* zone) {
+  {
+    DisallowHeapAllocation no_gc;
+    String::FlatContent subject_content = subject->GetFlatContent();
+    String::FlatContent pattern_content = pattern->GetFlatContent();
+    DCHECK(subject_content.IsFlat());
+    DCHECK(pattern_content.IsFlat());
+    if (subject_content.IsOneByte()) {
+      Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
+      if (pattern_content.IsOneByte()) {
+        Vector<const uint8_t> pattern_vector =
+            pattern_content.ToOneByteVector();
+        if (pattern_vector.length() == 1) {
+          FindOneByteStringIndices(subject_vector, pattern_vector[0], indices,
+                                   limit, zone);
+        } else {
+          FindStringIndices(isolate, subject_vector, pattern_vector, indices,
+                            limit, zone);
+        }
+      } else {
+        FindStringIndices(isolate, subject_vector,
+                          pattern_content.ToUC16Vector(), indices, limit, zone);
+      }
+    } else {
+      Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
+      if (pattern_content.IsOneByte()) {
+        Vector<const uint8_t> pattern_vector =
+            pattern_content.ToOneByteVector();
+        if (pattern_vector.length() == 1) {
+          FindTwoByteStringIndices(subject_vector, pattern_vector[0], indices,
+                                   limit, zone);
+        } else {
+          FindStringIndices(isolate, subject_vector, pattern_vector, indices,
+                            limit, zone);
+        }
+      } else {
+        Vector<const uc16> pattern_vector = pattern_content.ToUC16Vector();
+        if (pattern_vector.length() == 1) {
+          FindTwoByteStringIndices(subject_vector, pattern_vector[0], indices,
+                                   limit, zone);
+        } else {
+          FindStringIndices(isolate, subject_vector, pattern_vector, indices,
+                            limit, zone);
+        }
+      }
+    }
+  }
+}
+
+
+template <typename ResultSeqString>
+MUST_USE_RESULT static Object* StringReplaceGlobalAtomRegExpWithString(
+    Isolate* isolate, Handle<String> subject, Handle<JSRegExp> pattern_regexp,
+    Handle<String> replacement, Handle<JSArray> last_match_info) {
+  DCHECK(subject->IsFlat());
+  DCHECK(replacement->IsFlat());
+
+  ZoneScope zone_scope(isolate->runtime_zone());
+  ZoneList<int> indices(8, zone_scope.zone());
+  DCHECK_EQ(JSRegExp::ATOM, pattern_regexp->TypeTag());
+  String* pattern =
+      String::cast(pattern_regexp->DataAt(JSRegExp::kAtomPatternIndex));
+  int subject_len = subject->length();
+  int pattern_len = pattern->length();
+  int replacement_len = replacement->length();
+
+  FindStringIndicesDispatch(isolate, *subject, pattern, &indices, 0xffffffff,
+                            zone_scope.zone());
+
+  int matches = indices.length();
+  if (matches == 0) return *subject;
+
+  // Detect integer overflow.
+  int64_t result_len_64 = (static_cast<int64_t>(replacement_len) -
+                           static_cast<int64_t>(pattern_len)) *
+                              static_cast<int64_t>(matches) +
+                          static_cast<int64_t>(subject_len);
+  int result_len;
+  if (result_len_64 > static_cast<int64_t>(String::kMaxLength)) {
+    STATIC_ASSERT(String::kMaxLength < kMaxInt);
+    result_len = kMaxInt;  // Provoke exception.
+  } else {
+    result_len = static_cast<int>(result_len_64);
+  }
+
+  int subject_pos = 0;
+  int result_pos = 0;
+
+  MaybeHandle<SeqString> maybe_res;
+  if (ResultSeqString::kHasOneByteEncoding) {
+    maybe_res = isolate->factory()->NewRawOneByteString(result_len);
+  } else {
+    maybe_res = isolate->factory()->NewRawTwoByteString(result_len);
+  }
+  Handle<SeqString> untyped_res;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, untyped_res, maybe_res);
+  Handle<ResultSeqString> result = Handle<ResultSeqString>::cast(untyped_res);
+
+  for (int i = 0; i < matches; i++) {
+    // Copy non-matched subject content.
+    if (subject_pos < indices.at(i)) {
+      String::WriteToFlat(*subject, result->GetChars() + result_pos,
+                          subject_pos, indices.at(i));
+      result_pos += indices.at(i) - subject_pos;
+    }
+
+    // Replace match.
+    if (replacement_len > 0) {
+      String::WriteToFlat(*replacement, result->GetChars() + result_pos, 0,
+                          replacement_len);
+      result_pos += replacement_len;
+    }
+
+    subject_pos = indices.at(i) + pattern_len;
+  }
+  // Add remaining subject content at the end.
+  if (subject_pos < subject_len) {
+    String::WriteToFlat(*subject, result->GetChars() + result_pos, subject_pos,
+                        subject_len);
+  }
+
+  int32_t match_indices[] = {indices.at(matches - 1),
+                             indices.at(matches - 1) + pattern_len};
+  RegExpImpl::SetLastMatchInfo(last_match_info, subject, 0, match_indices);
+
+  return *result;
+}
+
+
+MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithString(
+    Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp,
+    Handle<String> replacement, Handle<JSArray> last_match_info) {
+  DCHECK(subject->IsFlat());
+  DCHECK(replacement->IsFlat());
+
+  int capture_count = regexp->CaptureCount();
+  int subject_length = subject->length();
+
+  // CompiledReplacement uses zone allocation.
+  ZoneScope zone_scope(isolate->runtime_zone());
+  CompiledReplacement compiled_replacement(zone_scope.zone());
+  bool simple_replace =
+      compiled_replacement.Compile(replacement, capture_count, subject_length);
+
+  // Shortcut for simple non-regexp global replacements
+  if (regexp->TypeTag() == JSRegExp::ATOM && simple_replace) {
+    if (subject->HasOnlyOneByteChars() && replacement->HasOnlyOneByteChars()) {
+      return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
+          isolate, subject, regexp, replacement, last_match_info);
+    } else {
+      return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
+          isolate, subject, regexp, replacement, last_match_info);
+    }
+  }
+
+  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
+  if (global_cache.HasException()) return isolate->heap()->exception();
+
+  int32_t* current_match = global_cache.FetchNext();
+  if (current_match == NULL) {
+    if (global_cache.HasException()) return isolate->heap()->exception();
+    return *subject;
+  }
+
+  // Guessing the number of parts that the final result string is built
+  // from. Global regexps can match any number of times, so we guess
+  // conservatively.
+  int expected_parts = (compiled_replacement.parts() + 1) * 4 + 1;
+  ReplacementStringBuilder builder(isolate->heap(), subject, expected_parts);
+
+  // Number of parts added by compiled replacement plus preceeding
+  // string and possibly suffix after last match.  It is possible for
+  // all components to use two elements when encoded as two smis.
+  const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
+
+  int prev = 0;
+
+  do {
+    builder.EnsureCapacity(parts_added_per_loop);
+
+    int start = current_match[0];
+    int end = current_match[1];
+
+    if (prev < start) {
+      builder.AddSubjectSlice(prev, start);
+    }
+
+    if (simple_replace) {
+      builder.AddString(replacement);
+    } else {
+      compiled_replacement.Apply(&builder, start, end, current_match);
+    }
+    prev = end;
+
+    current_match = global_cache.FetchNext();
+  } while (current_match != NULL);
+
+  if (global_cache.HasException()) return isolate->heap()->exception();
+
+  if (prev < subject_length) {
+    builder.EnsureCapacity(2);
+    builder.AddSubjectSlice(prev, subject_length);
+  }
+
+  RegExpImpl::SetLastMatchInfo(last_match_info, subject, capture_count,
+                               global_cache.LastSuccessfulMatch());
+
+  Handle<String> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, builder.ToString());
+  return *result;
+}
+
+
+template <typename ResultSeqString>
+MUST_USE_RESULT static Object* StringReplaceGlobalRegExpWithEmptyString(
+    Isolate* isolate, Handle<String> subject, Handle<JSRegExp> regexp,
+    Handle<JSArray> last_match_info) {
+  DCHECK(subject->IsFlat());
+
+  // Shortcut for simple non-regexp global replacements
+  if (regexp->TypeTag() == JSRegExp::ATOM) {
+    Handle<String> empty_string = isolate->factory()->empty_string();
+    if (subject->IsOneByteRepresentation()) {
+      return StringReplaceGlobalAtomRegExpWithString<SeqOneByteString>(
+          isolate, subject, regexp, empty_string, last_match_info);
+    } else {
+      return StringReplaceGlobalAtomRegExpWithString<SeqTwoByteString>(
+          isolate, subject, regexp, empty_string, last_match_info);
+    }
+  }
+
+  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
+  if (global_cache.HasException()) return isolate->heap()->exception();
+
+  int32_t* current_match = global_cache.FetchNext();
+  if (current_match == NULL) {
+    if (global_cache.HasException()) return isolate->heap()->exception();
+    return *subject;
+  }
+
+  int start = current_match[0];
+  int end = current_match[1];
+  int capture_count = regexp->CaptureCount();
+  int subject_length = subject->length();
+
+  int new_length = subject_length - (end - start);
+  if (new_length == 0) return isolate->heap()->empty_string();
+
+  Handle<ResultSeqString> answer;
+  if (ResultSeqString::kHasOneByteEncoding) {
+    answer = Handle<ResultSeqString>::cast(
+        isolate->factory()->NewRawOneByteString(new_length).ToHandleChecked());
+  } else {
+    answer = Handle<ResultSeqString>::cast(
+        isolate->factory()->NewRawTwoByteString(new_length).ToHandleChecked());
+  }
+
+  int prev = 0;
+  int position = 0;
+
+  do {
+    start = current_match[0];
+    end = current_match[1];
+    if (prev < start) {
+      // Add substring subject[prev;start] to answer string.
+      String::WriteToFlat(*subject, answer->GetChars() + position, prev, start);
+      position += start - prev;
+    }
+    prev = end;
+
+    current_match = global_cache.FetchNext();
+  } while (current_match != NULL);
+
+  if (global_cache.HasException()) return isolate->heap()->exception();
+
+  RegExpImpl::SetLastMatchInfo(last_match_info, subject, capture_count,
+                               global_cache.LastSuccessfulMatch());
+
+  if (prev < subject_length) {
+    // Add substring subject[prev;length] to answer string.
+    String::WriteToFlat(*subject, answer->GetChars() + position, prev,
+                        subject_length);
+    position += subject_length - prev;
+  }
+
+  if (position == 0) return isolate->heap()->empty_string();
+
+  // Shorten string and fill
+  int string_size = ResultSeqString::SizeFor(position);
+  int allocated_string_size = ResultSeqString::SizeFor(new_length);
+  int delta = allocated_string_size - string_size;
+
+  answer->set_length(position);
+  if (delta == 0) return *answer;
+
+  Address end_of_string = answer->address() + string_size;
+  Heap* heap = isolate->heap();
+
+  // The trimming is performed on a newly allocated object, which is on a
+  // fresly allocated page or on an already swept page. Hence, the sweeper
+  // thread can not get confused with the filler creation. No synchronization
+  // needed.
+  heap->CreateFillerObjectAt(end_of_string, delta);
+  heap->AdjustLiveBytes(answer->address(), -delta, Heap::FROM_MUTATOR);
+  return *answer;
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringReplaceGlobalRegExpWithString) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, replacement, 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
+
+  RUNTIME_ASSERT(regexp->GetFlags().is_global());
+  RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
+
+  subject = String::Flatten(subject);
+
+  if (replacement->length() == 0) {
+    if (subject->HasOnlyOneByteChars()) {
+      return StringReplaceGlobalRegExpWithEmptyString<SeqOneByteString>(
+          isolate, subject, regexp, last_match_info);
+    } else {
+      return StringReplaceGlobalRegExpWithEmptyString<SeqTwoByteString>(
+          isolate, subject, regexp, last_match_info);
+    }
+  }
+
+  replacement = String::Flatten(replacement);
+
+  return StringReplaceGlobalRegExpWithString(isolate, subject, regexp,
+                                             replacement, last_match_info);
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringSplit) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, pattern, 1);
+  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[2]);
+  RUNTIME_ASSERT(limit > 0);
+
+  int subject_length = subject->length();
+  int pattern_length = pattern->length();
+  RUNTIME_ASSERT(pattern_length > 0);
+
+  if (limit == 0xffffffffu) {
+    Handle<Object> cached_answer(
+        RegExpResultsCache::Lookup(isolate->heap(), *subject, *pattern,
+                                   RegExpResultsCache::STRING_SPLIT_SUBSTRINGS),
+        isolate);
+    if (*cached_answer != Smi::FromInt(0)) {
+      // The cache FixedArray is a COW-array and can therefore be reused.
+      Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(
+          Handle<FixedArray>::cast(cached_answer));
+      return *result;
+    }
+  }
+
+  // The limit can be very large (0xffffffffu), but since the pattern
+  // isn't empty, we can never create more parts than ~half the length
+  // of the subject.
+
+  subject = String::Flatten(subject);
+  pattern = String::Flatten(pattern);
+
+  static const int kMaxInitialListCapacity = 16;
+
+  ZoneScope zone_scope(isolate->runtime_zone());
+
+  // Find (up to limit) indices of separator and end-of-string in subject
+  int initial_capacity = Min<uint32_t>(kMaxInitialListCapacity, limit);
+  ZoneList<int> indices(initial_capacity, zone_scope.zone());
+
+  FindStringIndicesDispatch(isolate, *subject, *pattern, &indices, limit,
+                            zone_scope.zone());
+
+  if (static_cast<uint32_t>(indices.length()) < limit) {
+    indices.Add(subject_length, zone_scope.zone());
+  }
+
+  // The list indices now contains the end of each part to create.
+
+  // Create JSArray of substrings separated by separator.
+  int part_count = indices.length();
+
+  Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
+  JSObject::EnsureCanContainHeapObjectElements(result);
+  result->set_length(Smi::FromInt(part_count));
+
+  DCHECK(result->HasFastObjectElements());
+
+  if (part_count == 1 && indices.at(0) == subject_length) {
+    FixedArray::cast(result->elements())->set(0, *subject);
+    return *result;
+  }
+
+  Handle<FixedArray> elements(FixedArray::cast(result->elements()));
+  int part_start = 0;
+  for (int i = 0; i < part_count; i++) {
+    HandleScope local_loop_handle(isolate);
+    int part_end = indices.at(i);
+    Handle<String> substring =
+        isolate->factory()->NewProperSubString(subject, part_start, part_end);
+    elements->set(i, *substring);
+    part_start = part_end + pattern_length;
+  }
+
+  if (limit == 0xffffffffu) {
+    if (result->HasFastObjectElements()) {
+      RegExpResultsCache::Enter(isolate, subject, pattern, elements,
+                                RegExpResultsCache::STRING_SPLIT_SUBSTRINGS);
+    }
+  }
+
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_RegExpExecRT) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
+  CONVERT_INT32_ARG_CHECKED(index, 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
+  // Due to the way the JS calls are constructed this must be less than the
+  // length of a string, i.e. it is always a Smi.  We check anyway for security.
+  RUNTIME_ASSERT(index >= 0);
+  RUNTIME_ASSERT(index <= subject->length());
+  isolate->counters()->regexp_entry_runtime()->Increment();
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      RegExpImpl::Exec(regexp, subject, index, last_match_info));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_RegExpConstructResult) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_SMI_ARG_CHECKED(size, 0);
+  RUNTIME_ASSERT(size >= 0 && size <= FixedArray::kMaxLength);
+  CONVERT_ARG_HANDLE_CHECKED(Object, index, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, input, 2);
+  Handle<FixedArray> elements = isolate->factory()->NewFixedArray(size);
+  Handle<Map> regexp_map(isolate->native_context()->regexp_result_map());
+  Handle<JSObject> object =
+      isolate->factory()->NewJSObjectFromMap(regexp_map, NOT_TENURED, false);
+  Handle<JSArray> array = Handle<JSArray>::cast(object);
+  array->set_elements(*elements);
+  array->set_length(Smi::FromInt(size));
+  // Write in-object properties after the length of the array.
+  array->InObjectPropertyAtPut(JSRegExpResult::kIndexIndex, *index);
+  array->InObjectPropertyAtPut(JSRegExpResult::kInputIndex, *input);
+  return *array;
+}
+
+
+static JSRegExp::Flags RegExpFlagsFromString(Handle<String> flags,
+                                             bool* success) {
+  uint32_t value = JSRegExp::NONE;
+  int length = flags->length();
+  // A longer flags string cannot be valid.
+  if (length > 4) return JSRegExp::Flags(0);
+  for (int i = 0; i < length; i++) {
+    uint32_t flag = JSRegExp::NONE;
+    switch (flags->Get(i)) {
+      case 'g':
+        flag = JSRegExp::GLOBAL;
+        break;
+      case 'i':
+        flag = JSRegExp::IGNORE_CASE;
+        break;
+      case 'm':
+        flag = JSRegExp::MULTILINE;
+        break;
+      case 'y':
+        if (!FLAG_harmony_regexps) return JSRegExp::Flags(0);
+        flag = JSRegExp::STICKY;
+        break;
+      default:
+        return JSRegExp::Flags(0);
+    }
+    // Duplicate flag.
+    if (value & flag) return JSRegExp::Flags(0);
+    value |= flag;
+  }
+  *success = true;
+  return JSRegExp::Flags(value);
+}
+
+
+RUNTIME_FUNCTION(Runtime_RegExpInitializeAndCompile) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, flags_string, 2);
+  Factory* factory = isolate->factory();
+  // 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 = factory->query_colon_string();
+
+  bool success = false;
+  JSRegExp::Flags flags = RegExpFlagsFromString(flags_string, &success);
+  if (!success) {
+    Handle<FixedArray> element = factory->NewFixedArray(1);
+    element->set(0, *flags_string);
+    Handle<JSArray> args = factory->NewJSArrayWithElements(element);
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewSyntaxError("invalid_regexp_flags", args));
+  }
+
+  Handle<Object> global = factory->ToBoolean(flags.is_global());
+  Handle<Object> ignore_case = factory->ToBoolean(flags.is_ignore_case());
+  Handle<Object> multiline = factory->ToBoolean(flags.is_multiline());
+  Handle<Object> sticky = factory->ToBoolean(flags.is_sticky());
+
+  Map* map = regexp->map();
+  Object* constructor = map->constructor();
+  if (!FLAG_harmony_regexps && constructor->IsJSFunction() &&
+      JSFunction::cast(constructor)->initial_map() == map) {
+    // If we still have the original map, set in-object properties directly.
+    // Both true and false are immovable immortal objects so no need for write
+    // barrier.
+    regexp->InObjectPropertyAtPut(JSRegExp::kGlobalFieldIndex, *global,
+                                  SKIP_WRITE_BARRIER);
+    regexp->InObjectPropertyAtPut(JSRegExp::kIgnoreCaseFieldIndex, *ignore_case,
+                                  SKIP_WRITE_BARRIER);
+    regexp->InObjectPropertyAtPut(JSRegExp::kMultilineFieldIndex, *multiline,
+                                  SKIP_WRITE_BARRIER);
+    regexp->InObjectPropertyAtPut(JSRegExp::kLastIndexFieldIndex,
+                                  Smi::FromInt(0), SKIP_WRITE_BARRIER);
+  } else {
+    // Map has changed, so use generic, but slower, method.  We also end here if
+    // the --harmony-regexp flag is set, because the initial map does not have
+    // space for the 'sticky' flag, since it is from the snapshot, but must work
+    // both with and without --harmony-regexp.  When sticky comes out from under
+    // the flag, we will be able to use the fast initial map.
+    PropertyAttributes final =
+        static_cast<PropertyAttributes>(READ_ONLY | DONT_ENUM | DONT_DELETE);
+    PropertyAttributes writable =
+        static_cast<PropertyAttributes>(DONT_ENUM | DONT_DELETE);
+    Handle<Object> zero(Smi::FromInt(0), isolate);
+    JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->global_string(),
+                                             global, final).Check();
+    JSObject::SetOwnPropertyIgnoreAttributes(
+        regexp, factory->ignore_case_string(), ignore_case, final).Check();
+    JSObject::SetOwnPropertyIgnoreAttributes(
+        regexp, factory->multiline_string(), multiline, final).Check();
+    if (FLAG_harmony_regexps) {
+      JSObject::SetOwnPropertyIgnoreAttributes(regexp, factory->sticky_string(),
+                                               sticky, final).Check();
+    }
+    JSObject::SetOwnPropertyIgnoreAttributes(
+        regexp, factory->last_index_string(), zero, writable).Check();
+  }
+
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, RegExpImpl::Compile(regexp, source, flags));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_MaterializeRegExpLiteral) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
+  CONVERT_SMI_ARG_CHECKED(index, 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, pattern, 2);
+  CONVERT_ARG_HANDLE_CHECKED(String, flags, 3);
+
+  // Get the RegExp function from the context in the literals array.
+  // This is the RegExp function from the context in which the
+  // function was created.  We do not use the RegExp function from the
+  // current native context because this might be the RegExp function
+  // from another context which we should not have access to.
+  Handle<JSFunction> constructor = Handle<JSFunction>(
+      JSFunction::NativeContextFromLiterals(*literals)->regexp_function());
+  // Compute the regular expression literal.
+  Handle<Object> regexp;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, regexp,
+      RegExpImpl::CreateRegExpLiteral(constructor, pattern, flags));
+  literals->set(index, *regexp);
+  return *regexp;
+}
+
+
+// Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
+// separate last match info.  See comment on that function.
+template <bool has_capture>
+static Object* SearchRegExpMultiple(Isolate* isolate, Handle<String> subject,
+                                    Handle<JSRegExp> regexp,
+                                    Handle<JSArray> last_match_array,
+                                    Handle<JSArray> result_array) {
+  DCHECK(subject->IsFlat());
+  DCHECK_NE(has_capture, regexp->CaptureCount() == 0);
+
+  int capture_count = regexp->CaptureCount();
+  int subject_length = subject->length();
+
+  static const int kMinLengthToCache = 0x1000;
+
+  if (subject_length > kMinLengthToCache) {
+    Handle<Object> cached_answer(
+        RegExpResultsCache::Lookup(isolate->heap(), *subject, regexp->data(),
+                                   RegExpResultsCache::REGEXP_MULTIPLE_INDICES),
+        isolate);
+    if (*cached_answer != Smi::FromInt(0)) {
+      Handle<FixedArray> cached_fixed_array =
+          Handle<FixedArray>(FixedArray::cast(*cached_answer));
+      // The cache FixedArray is a COW-array and can therefore be reused.
+      JSArray::SetContent(result_array, cached_fixed_array);
+      // The actual length of the result array is stored in the last element of
+      // the backing store (the backing FixedArray may have a larger capacity).
+      Object* cached_fixed_array_last_element =
+          cached_fixed_array->get(cached_fixed_array->length() - 1);
+      Smi* js_array_length = Smi::cast(cached_fixed_array_last_element);
+      result_array->set_length(js_array_length);
+      RegExpImpl::SetLastMatchInfo(last_match_array, subject, capture_count,
+                                   NULL);
+      return *result_array;
+    }
+  }
+
+  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
+  if (global_cache.HasException()) return isolate->heap()->exception();
+
+  // Ensured in Runtime_RegExpExecMultiple.
+  DCHECK(result_array->HasFastObjectElements());
+  Handle<FixedArray> result_elements(
+      FixedArray::cast(result_array->elements()));
+  if (result_elements->length() < 16) {
+    result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
+  }
+
+  FixedArrayBuilder builder(result_elements);
+
+  // Position to search from.
+  int match_start = -1;
+  int match_end = 0;
+  bool first = true;
+
+  // Two smis before and after the match, for very long strings.
+  static const int kMaxBuilderEntriesPerRegExpMatch = 5;
+
+  while (true) {
+    int32_t* current_match = global_cache.FetchNext();
+    if (current_match == NULL) break;
+    match_start = current_match[0];
+    builder.EnsureCapacity(kMaxBuilderEntriesPerRegExpMatch);
+    if (match_end < match_start) {
+      ReplacementStringBuilder::AddSubjectSlice(&builder, match_end,
+                                                match_start);
+    }
+    match_end = current_match[1];
+    {
+      // Avoid accumulating new handles inside loop.
+      HandleScope temp_scope(isolate);
+      Handle<String> match;
+      if (!first) {
+        match = isolate->factory()->NewProperSubString(subject, match_start,
+                                                       match_end);
+      } else {
+        match =
+            isolate->factory()->NewSubString(subject, match_start, match_end);
+        first = false;
+      }
+
+      if (has_capture) {
+        // Arguments array to replace function is match, captures, index and
+        // subject, i.e., 3 + capture count in total.
+        Handle<FixedArray> elements =
+            isolate->factory()->NewFixedArray(3 + capture_count);
+
+        elements->set(0, *match);
+        for (int i = 1; i <= capture_count; i++) {
+          int start = current_match[i * 2];
+          if (start >= 0) {
+            int end = current_match[i * 2 + 1];
+            DCHECK(start <= end);
+            Handle<String> substring =
+                isolate->factory()->NewSubString(subject, start, end);
+            elements->set(i, *substring);
+          } else {
+            DCHECK(current_match[i * 2 + 1] < 0);
+            elements->set(i, isolate->heap()->undefined_value());
+          }
+        }
+        elements->set(capture_count + 1, Smi::FromInt(match_start));
+        elements->set(capture_count + 2, *subject);
+        builder.Add(*isolate->factory()->NewJSArrayWithElements(elements));
+      } else {
+        builder.Add(*match);
+      }
+    }
+  }
+
+  if (global_cache.HasException()) return isolate->heap()->exception();
+
+  if (match_start >= 0) {
+    // Finished matching, with at least one match.
+    if (match_end < subject_length) {
+      ReplacementStringBuilder::AddSubjectSlice(&builder, match_end,
+                                                subject_length);
+    }
+
+    RegExpImpl::SetLastMatchInfo(last_match_array, subject, capture_count,
+                                 NULL);
+
+    if (subject_length > kMinLengthToCache) {
+      // Store the length of the result array into the last element of the
+      // backing FixedArray.
+      builder.EnsureCapacity(1);
+      Handle<FixedArray> fixed_array = builder.array();
+      fixed_array->set(fixed_array->length() - 1,
+                       Smi::FromInt(builder.length()));
+      // Cache the result and turn the FixedArray into a COW array.
+      RegExpResultsCache::Enter(isolate, subject,
+                                handle(regexp->data(), isolate), fixed_array,
+                                RegExpResultsCache::REGEXP_MULTIPLE_INDICES);
+    }
+    return *builder.ToJSArray(result_array);
+  } else {
+    return isolate->heap()->null_value();  // No matches at all.
+  }
+}
+
+
+// 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(Runtime_RegExpExecMultiple) {
+  HandleScope handles(isolate);
+  DCHECK(args.length() == 4);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
+  RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
+  RUNTIME_ASSERT(result_array->HasFastObjectElements());
+
+  subject = String::Flatten(subject);
+  RUNTIME_ASSERT(regexp->GetFlags().is_global());
+
+  if (regexp->CaptureCount() == 0) {
+    return SearchRegExpMultiple<false>(isolate, subject, regexp,
+                                       last_match_info, result_array);
+  } else {
+    return SearchRegExpMultiple<true>(isolate, subject, regexp, last_match_info,
+                                      result_array);
+  }
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_RegExpConstructResult) {
+  SealHandleScope shs(isolate);
+  return __RT_impl_Runtime_RegExpConstructResult(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_RegExpExec) {
+  SealHandleScope shs(isolate);
+  return __RT_impl_Runtime_RegExpExecRT(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsRegExp) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  return isolate->heap()->ToBoolean(obj->IsJSRegExp());
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-scopes.cc b/src/runtime/runtime-scopes.cc
new file mode 100644
index 0000000..2a0b435
--- /dev/null
+++ b/src/runtime/runtime-scopes.cc
@@ -0,0 +1,1088 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/accessors.h"
+#include "src/arguments.h"
+#include "src/frames-inl.h"
+#include "src/runtime/runtime-utils.h"
+#include "src/scopeinfo.h"
+#include "src/scopes.h"
+
+namespace v8 {
+namespace internal {
+
+static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) {
+  HandleScope scope(isolate);
+  Handle<Object> args[1] = {name};
+  THROW_NEW_ERROR_RETURN_FAILURE(
+      isolate, NewTypeError("var_redeclaration", HandleVector(args, 1)));
+}
+
+
+RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) {
+  HandleScope scope(isolate);
+  THROW_NEW_ERROR_RETURN_FAILURE(
+      isolate,
+      NewTypeError("harmony_const_assign", HandleVector<Object>(NULL, 0)));
+}
+
+
+// May throw a RedeclarationError.
+static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global,
+                              Handle<String> name, Handle<Object> value,
+                              PropertyAttributes attr, bool is_var,
+                              bool is_const, bool is_function) {
+  Handle<ScriptContextTable> script_contexts(
+      global->native_context()->script_context_table());
+  ScriptContextTable::LookupResult lookup;
+  if (ScriptContextTable::Lookup(script_contexts, name, &lookup) &&
+      IsLexicalVariableMode(lookup.mode)) {
+    return ThrowRedeclarationError(isolate, name);
+  }
+
+  // Do the lookup own properties only, see ES5 erratum.
+  LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+  if (!maybe.has_value) return isolate->heap()->exception();
+
+  if (it.IsFound()) {
+    PropertyAttributes old_attributes = maybe.value;
+    // The name was declared before; check for conflicting re-declarations.
+    if (is_const) return ThrowRedeclarationError(isolate, name);
+
+    // Skip var re-declarations.
+    if (is_var) return isolate->heap()->undefined_value();
+
+    DCHECK(is_function);
+    if ((old_attributes & DONT_DELETE) != 0) {
+      // Only allow reconfiguring globals to functions in user code (no
+      // natives, which are marked as read-only).
+      DCHECK((attr & READ_ONLY) == 0);
+
+      // Check whether we can reconfigure the existing property into a
+      // function.
+      PropertyDetails old_details = it.property_details();
+      // TODO(verwaest): CALLBACKS invalidly includes ExecutableAccessInfo,
+      // which are actually data properties, not accessor properties.
+      if (old_details.IsReadOnly() || old_details.IsDontEnum() ||
+          old_details.type() == CALLBACKS) {
+        return ThrowRedeclarationError(isolate, name);
+      }
+      // If the existing property is not configurable, keep its attributes. Do
+      attr = old_attributes;
+    }
+  }
+
+  // Define or redefine own property.
+  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                                           global, name, value, attr));
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  Handle<GlobalObject> global(isolate->global_object());
+
+  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 1);
+  CONVERT_SMI_ARG_CHECKED(flags, 2);
+
+  // Traverse the name/value pairs and set the properties.
+  int length = pairs->length();
+  for (int i = 0; i < length; i += 2) {
+    HandleScope scope(isolate);
+    Handle<String> name(String::cast(pairs->get(i)));
+    Handle<Object> initial_value(pairs->get(i + 1), isolate);
+
+    // We have to declare a global const property. To capture we only
+    // assign to it when evaluating the assignment for "const x =
+    // <expr>" the initial value is the hole.
+    bool is_var = initial_value->IsUndefined();
+    bool is_const = initial_value->IsTheHole();
+    bool is_function = initial_value->IsSharedFunctionInfo();
+    DCHECK(is_var + is_const + is_function == 1);
+
+    Handle<Object> value;
+    if (is_function) {
+      // Copy the function and update its context. Use it as value.
+      Handle<SharedFunctionInfo> shared =
+          Handle<SharedFunctionInfo>::cast(initial_value);
+      Handle<JSFunction> function =
+          isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
+                                                                TENURED);
+      value = function;
+    } else {
+      value = isolate->factory()->undefined_value();
+    }
+
+    // Compute the property attributes. According to ECMA-262,
+    // the property must be non-configurable except in eval.
+    bool is_native = DeclareGlobalsNativeFlag::decode(flags);
+    bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
+    int attr = NONE;
+    if (is_const) attr |= READ_ONLY;
+    if (is_function && is_native) attr |= READ_ONLY;
+    if (!is_const && !is_eval) attr |= DONT_DELETE;
+
+    Object* result = DeclareGlobals(isolate, global, name, value,
+                                    static_cast<PropertyAttributes>(attr),
+                                    is_var, is_const, is_function);
+    if (isolate->has_pending_exception()) return result;
+  }
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
+  HandleScope scope(isolate);
+  // args[0] == name
+  // args[1] == language_mode
+  // args[2] == value (optional)
+
+  // Determine if we need to assign to the variable if it already
+  // exists (based on the number of arguments).
+  RUNTIME_ASSERT(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
+  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
+
+  Handle<GlobalObject> global(isolate->context()->global_object());
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, Object::SetProperty(global, name, value, strict_mode));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) {
+  HandleScope handle_scope(isolate);
+  // All constants are declared with an initial value. The name
+  // of the constant is the first argument and the initial value
+  // is the second.
+  RUNTIME_ASSERT(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
+
+  Handle<GlobalObject> global = isolate->global_object();
+
+  // Lookup the property as own on the global object.
+  LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+  Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+  DCHECK(maybe.has_value);
+  PropertyAttributes old_attributes = maybe.value;
+
+  PropertyAttributes attr =
+      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
+  // Set the value if the property is either missing, or the property attributes
+  // allow setting the value without invoking an accessor.
+  if (it.IsFound()) {
+    // Ignore if we can't reconfigure the value.
+    if ((old_attributes & DONT_DELETE) != 0) {
+      if ((old_attributes & READ_ONLY) != 0 ||
+          it.state() == LookupIterator::ACCESSOR) {
+        return *value;
+      }
+      attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
+    }
+  }
+
+  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                                           global, name, value, attr));
+
+  return *value;
+}
+
+
+RUNTIME_FUNCTION(Runtime_DeclareLookupSlot) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+
+  // Declarations are always made in a function, eval or script context. In
+  // the case of eval code, the context passed is the context of the caller,
+  // which may be some nested context and not the declaration context.
+  CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 0);
+  Handle<Context> context(context_arg->declaration_context());
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
+  CONVERT_SMI_ARG_CHECKED(attr_arg, 2);
+  PropertyAttributes attr = static_cast<PropertyAttributes>(attr_arg);
+  RUNTIME_ASSERT(attr == READ_ONLY || attr == NONE);
+  CONVERT_ARG_HANDLE_CHECKED(Object, initial_value, 3);
+
+  // TODO(verwaest): Unify the encoding indicating "var" with DeclareGlobals.
+  bool is_var = *initial_value == NULL;
+  bool is_const = initial_value->IsTheHole();
+  bool is_function = initial_value->IsJSFunction();
+  DCHECK(is_var + is_const + is_function == 1);
+
+  int index;
+  PropertyAttributes attributes;
+  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
+  BindingFlags binding_flags;
+  Handle<Object> holder =
+      context->Lookup(name, flags, &index, &attributes, &binding_flags);
+
+  Handle<JSObject> object;
+  Handle<Object> value =
+      is_function ? initial_value
+                  : Handle<Object>::cast(isolate->factory()->undefined_value());
+
+  // TODO(verwaest): This case should probably not be covered by this function,
+  // but by DeclareGlobals instead.
+  if ((attributes != ABSENT && holder->IsJSGlobalObject()) ||
+      (context_arg->has_extension() &&
+       context_arg->extension()->IsJSGlobalObject())) {
+    return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name,
+                          value, attr, is_var, is_const, is_function);
+  }
+
+  if (attributes != ABSENT) {
+    // The name was declared before; check for conflicting re-declarations.
+    if (is_const || (attributes & READ_ONLY) != 0) {
+      return ThrowRedeclarationError(isolate, name);
+    }
+
+    // Skip var re-declarations.
+    if (is_var) return isolate->heap()->undefined_value();
+
+    DCHECK(is_function);
+    if (index >= 0) {
+      DCHECK(holder.is_identical_to(context));
+      context->set(index, *initial_value);
+      return isolate->heap()->undefined_value();
+    }
+
+    object = Handle<JSObject>::cast(holder);
+
+  } else if (context->has_extension()) {
+    object = handle(JSObject::cast(context->extension()));
+    DCHECK(object->IsJSContextExtensionObject() || object->IsJSGlobalObject());
+  } else {
+    DCHECK(context->IsFunctionContext());
+    object =
+        isolate->factory()->NewJSObject(isolate->context_extension_function());
+    context->set_extension(*object);
+  }
+
+  RETURN_FAILURE_ON_EXCEPTION(isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                                           object, name, value, attr));
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_InitializeLegacyConstLookupSlot) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
+  DCHECK(!value->IsTheHole());
+  // Initializations are always done in a function or native context.
+  CONVERT_ARG_HANDLE_CHECKED(Context, context_arg, 1);
+  Handle<Context> context(context_arg->declaration_context());
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
+
+  int index;
+  PropertyAttributes attributes;
+  ContextLookupFlags flags = DONT_FOLLOW_CHAINS;
+  BindingFlags binding_flags;
+  Handle<Object> holder =
+      context->Lookup(name, flags, &index, &attributes, &binding_flags);
+
+  if (index >= 0) {
+    DCHECK(holder->IsContext());
+    // Property was found in a context.  Perform the assignment if the constant
+    // was uninitialized.
+    Handle<Context> context = Handle<Context>::cast(holder);
+    DCHECK((attributes & READ_ONLY) != 0);
+    if (context->get(index)->IsTheHole()) context->set(index, *value);
+    return *value;
+  }
+
+  PropertyAttributes attr =
+      static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
+
+  // Strict mode handling not needed (legacy const is disallowed in strict
+  // mode).
+
+  // The declared const was configurable, and may have been deleted in the
+  // meanwhile. If so, re-introduce the variable in the context extension.
+  if (attributes == ABSENT) {
+    Handle<Context> declaration_context(context_arg->declaration_context());
+    DCHECK(declaration_context->has_extension());
+    holder = handle(declaration_context->extension(), isolate);
+    CHECK(holder->IsJSObject());
+  } else {
+    // For JSContextExtensionObjects, the initializer can be run multiple times
+    // if in a for loop: for (var i = 0; i < 2; i++) { const x = i; }. Only the
+    // first assignment should go through. For JSGlobalObjects, additionally any
+    // code can run in between that modifies the declared property.
+    DCHECK(holder->IsJSGlobalObject() || holder->IsJSContextExtensionObject());
+
+    LookupIterator it(holder, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+    Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+    if (!maybe.has_value) return isolate->heap()->exception();
+    PropertyAttributes old_attributes = maybe.value;
+
+    // Ignore if we can't reconfigure the value.
+    if ((old_attributes & DONT_DELETE) != 0) {
+      if ((old_attributes & READ_ONLY) != 0 ||
+          it.state() == LookupIterator::ACCESSOR) {
+        return *value;
+      }
+      attr = static_cast<PropertyAttributes>(old_attributes | READ_ONLY);
+    }
+  }
+
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, JSObject::SetOwnPropertyIgnoreAttributes(
+                   Handle<JSObject>::cast(holder), name, value, attr));
+
+  return *value;
+}
+
+
+static Handle<JSObject> NewSloppyArguments(Isolate* isolate,
+                                           Handle<JSFunction> callee,
+                                           Object** parameters,
+                                           int argument_count) {
+  Handle<JSObject> result =
+      isolate->factory()->NewArgumentsObject(callee, argument_count);
+
+  // Allocate the elements if needed.
+  int parameter_count = callee->shared()->formal_parameter_count();
+  if (argument_count > 0) {
+    if (parameter_count > 0) {
+      int mapped_count = Min(argument_count, parameter_count);
+      Handle<FixedArray> parameter_map =
+          isolate->factory()->NewFixedArray(mapped_count + 2, NOT_TENURED);
+      parameter_map->set_map(isolate->heap()->sloppy_arguments_elements_map());
+
+      Handle<Map> map = Map::Copy(handle(result->map()), "NewSloppyArguments");
+      map->set_elements_kind(SLOPPY_ARGUMENTS_ELEMENTS);
+
+      result->set_map(*map);
+      result->set_elements(*parameter_map);
+
+      // Store the context and the arguments array at the beginning of the
+      // parameter map.
+      Handle<Context> context(isolate->context());
+      Handle<FixedArray> arguments =
+          isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
+      parameter_map->set(0, *context);
+      parameter_map->set(1, *arguments);
+
+      // Loop over the actual parameters backwards.
+      int index = argument_count - 1;
+      while (index >= mapped_count) {
+        // These go directly in the arguments array and have no
+        // corresponding slot in the parameter map.
+        arguments->set(index, *(parameters - index - 1));
+        --index;
+      }
+
+      Handle<ScopeInfo> scope_info(callee->shared()->scope_info());
+      while (index >= 0) {
+        // Detect duplicate names to the right in the parameter list.
+        Handle<String> name(scope_info->ParameterName(index));
+        int context_local_count = scope_info->ContextLocalCount();
+        bool duplicate = false;
+        for (int j = index + 1; j < parameter_count; ++j) {
+          if (scope_info->ParameterName(j) == *name) {
+            duplicate = true;
+            break;
+          }
+        }
+
+        if (duplicate) {
+          // This goes directly in the arguments array with a hole in the
+          // parameter map.
+          arguments->set(index, *(parameters - index - 1));
+          parameter_map->set_the_hole(index + 2);
+        } else {
+          // The context index goes in the parameter map with a hole in the
+          // arguments array.
+          int context_index = -1;
+          for (int j = 0; j < context_local_count; ++j) {
+            if (scope_info->ContextLocalName(j) == *name) {
+              context_index = j;
+              break;
+            }
+          }
+          DCHECK(context_index >= 0);
+          arguments->set_the_hole(index);
+          parameter_map->set(
+              index + 2,
+              Smi::FromInt(Context::MIN_CONTEXT_SLOTS + context_index));
+        }
+
+        --index;
+      }
+    } else {
+      // If there is no aliasing, the arguments object elements are not
+      // special in any way.
+      Handle<FixedArray> elements =
+          isolate->factory()->NewFixedArray(argument_count, NOT_TENURED);
+      result->set_elements(*elements);
+      for (int i = 0; i < argument_count; ++i) {
+        elements->set(i, *(parameters - i - 1));
+      }
+    }
+  }
+  return result;
+}
+
+
+static Handle<JSObject> NewStrictArguments(Isolate* isolate,
+                                           Handle<JSFunction> callee,
+                                           Object** parameters,
+                                           int argument_count) {
+  Handle<JSObject> result =
+      isolate->factory()->NewArgumentsObject(callee, argument_count);
+
+  if (argument_count > 0) {
+    Handle<FixedArray> array =
+        isolate->factory()->NewUninitializedFixedArray(argument_count);
+    DisallowHeapAllocation no_gc;
+    WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
+    for (int i = 0; i < argument_count; i++) {
+      array->set(i, *--parameters, mode);
+    }
+    result->set_elements(*array);
+  }
+  return result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewArguments) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
+  JavaScriptFrameIterator it(isolate);
+
+  // Find the frame that holds the actual arguments passed to the function.
+  it.AdvanceToArgumentsFrame();
+  JavaScriptFrame* frame = it.frame();
+
+  // Determine parameter location on the stack and dispatch on language mode.
+  int argument_count = frame->GetArgumentsLength();
+  Object** parameters = reinterpret_cast<Object**>(frame->GetParameterSlot(-1));
+  return callee->shared()->strict_mode() == STRICT
+             ? *NewStrictArguments(isolate, callee, parameters, argument_count)
+             : *NewSloppyArguments(isolate, callee, parameters, argument_count);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewSloppyArguments) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0);
+  Object** parameters = reinterpret_cast<Object**>(args[1]);
+  CONVERT_SMI_ARG_CHECKED(argument_count, 2);
+  return *NewSloppyArguments(isolate, callee, parameters, argument_count);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewStrictArguments) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, callee, 0)
+  Object** parameters = reinterpret_cast<Object**>(args[1]);
+  CONVERT_SMI_ARG_CHECKED(argument_count, 2);
+  return *NewStrictArguments(isolate, callee, parameters, argument_count);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewClosureFromStubFailure) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
+  Handle<Context> context(isolate->context());
+  PretenureFlag pretenure_flag = NOT_TENURED;
+  return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
+                                                                pretenure_flag);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewClosure) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
+  CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 1);
+  CONVERT_BOOLEAN_ARG_CHECKED(pretenure, 2);
+
+  // The caller ensures that we pretenure closures that are assigned
+  // directly to properties.
+  PretenureFlag pretenure_flag = pretenure ? TENURED : NOT_TENURED;
+  return *isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context,
+                                                                pretenure_flag);
+}
+
+static Object* FindNameClash(Handle<ScopeInfo> scope_info,
+                             Handle<GlobalObject> global_object,
+                             Handle<ScriptContextTable> script_context) {
+  Isolate* isolate = scope_info->GetIsolate();
+  for (int var = 0; var < scope_info->ContextLocalCount(); var++) {
+    Handle<String> name(scope_info->ContextLocalName(var));
+    VariableMode mode = scope_info->ContextLocalMode(var);
+    ScriptContextTable::LookupResult lookup;
+    if (ScriptContextTable::Lookup(script_context, name, &lookup)) {
+      if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) {
+        return ThrowRedeclarationError(isolate, name);
+      }
+    }
+
+    if (IsLexicalVariableMode(mode)) {
+      LookupIterator it(global_object, name,
+                        LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
+      Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
+      if (!maybe.has_value) return isolate->heap()->exception();
+      if ((maybe.value & DONT_DELETE) != 0) {
+        return ThrowRedeclarationError(isolate, name);
+      }
+
+      GlobalObject::InvalidatePropertyCell(global_object, name);
+    }
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewScriptContext) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
+  Handle<GlobalObject> global_object(function->context()->global_object());
+  Handle<Context> native_context(global_object->native_context());
+  Handle<ScriptContextTable> script_context_table(
+      native_context->script_context_table());
+
+  Handle<String> clashed_name;
+  Object* name_clash_result =
+      FindNameClash(scope_info, global_object, script_context_table);
+  if (isolate->has_pending_exception()) return name_clash_result;
+
+  Handle<Context> result =
+      isolate->factory()->NewScriptContext(function, scope_info);
+
+  DCHECK(function->context() == isolate->context());
+  DCHECK(function->context()->global_object() == result->global_object());
+
+  Handle<ScriptContextTable> new_script_context_table =
+      ScriptContextTable::Extend(script_context_table, result);
+  native_context->set_script_context_table(*new_script_context_table);
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewFunctionContext) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+
+  DCHECK(function->context() == isolate->context());
+  int length = function->shared()->scope_info()->ContextLength();
+  return *isolate->factory()->NewFunctionContext(length, function);
+}
+
+
+RUNTIME_FUNCTION(Runtime_PushWithContext) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  Handle<JSReceiver> extension_object;
+  if (args[0]->IsJSReceiver()) {
+    extension_object = args.at<JSReceiver>(0);
+  } else {
+    // Try to convert the object to a proper JavaScript object.
+    MaybeHandle<JSReceiver> maybe_object =
+        Object::ToObject(isolate, args.at<Object>(0));
+    if (!maybe_object.ToHandle(&extension_object)) {
+      Handle<Object> handle = args.at<Object>(0);
+      THROW_NEW_ERROR_RETURN_FAILURE(
+          isolate, NewTypeError("with_expression", HandleVector(&handle, 1)));
+    }
+  }
+
+  Handle<JSFunction> function;
+  if (args[1]->IsSmi()) {
+    // A smi sentinel indicates a context nested inside global code rather
+    // than some function.  There is a canonical empty function that can be
+    // gotten from the native context.
+    function = handle(isolate->native_context()->closure());
+  } else {
+    function = args.at<JSFunction>(1);
+  }
+
+  Handle<Context> current(isolate->context());
+  Handle<Context> context =
+      isolate->factory()->NewWithContext(function, current, extension_object);
+  isolate->set_context(*context);
+  return *context;
+}
+
+
+RUNTIME_FUNCTION(Runtime_PushCatchContext) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Object, thrown_object, 1);
+  Handle<JSFunction> function;
+  if (args[2]->IsSmi()) {
+    // A smi sentinel indicates a context nested inside global code rather
+    // than some function.  There is a canonical empty function that can be
+    // gotten from the native context.
+    function = handle(isolate->native_context()->closure());
+  } else {
+    function = args.at<JSFunction>(2);
+  }
+  Handle<Context> current(isolate->context());
+  Handle<Context> context = isolate->factory()->NewCatchContext(
+      function, current, name, thrown_object);
+  isolate->set_context(*context);
+  return *context;
+}
+
+
+RUNTIME_FUNCTION(Runtime_PushBlockContext) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 0);
+  Handle<JSFunction> function;
+  if (args[1]->IsSmi()) {
+    // A smi sentinel indicates a context nested inside global code rather
+    // than some function.  There is a canonical empty function that can be
+    // gotten from the native context.
+    function = handle(isolate->native_context()->closure());
+  } else {
+    function = args.at<JSFunction>(1);
+  }
+  Handle<Context> current(isolate->context());
+  Handle<Context> context =
+      isolate->factory()->NewBlockContext(function, current, scope_info);
+  isolate->set_context(*context);
+  return *context;
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsJSModule) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  return isolate->heap()->ToBoolean(obj->IsJSModule());
+}
+
+
+RUNTIME_FUNCTION(Runtime_PushModuleContext) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_SMI_ARG_CHECKED(index, 0);
+
+  if (!args[1]->IsScopeInfo()) {
+    // Module already initialized. Find hosting context and retrieve context.
+    Context* host = Context::cast(isolate->context())->script_context();
+    Context* context = Context::cast(host->get(index));
+    DCHECK(context->previous() == isolate->context());
+    isolate->set_context(context);
+    return context;
+  }
+
+  CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
+
+  // Allocate module context.
+  HandleScope scope(isolate);
+  Factory* factory = isolate->factory();
+  Handle<Context> context = factory->NewModuleContext(scope_info);
+  Handle<JSModule> module = factory->NewJSModule(context, scope_info);
+  context->set_module(*module);
+  Context* previous = isolate->context();
+  context->set_previous(previous);
+  context->set_closure(previous->closure());
+  context->set_global_object(previous->global_object());
+  isolate->set_context(*context);
+
+  // Find hosting scope and initialize internal variable holding module there.
+  previous->script_context()->set(index, *context);
+
+  return *context;
+}
+
+
+RUNTIME_FUNCTION(Runtime_DeclareModules) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(FixedArray, descriptions, 0);
+  Context* host_context = isolate->context();
+
+  for (int i = 0; i < descriptions->length(); ++i) {
+    Handle<ModuleInfo> description(ModuleInfo::cast(descriptions->get(i)));
+    int host_index = description->host_index();
+    Handle<Context> context(Context::cast(host_context->get(host_index)));
+    Handle<JSModule> module(context->module());
+
+    for (int j = 0; j < description->length(); ++j) {
+      Handle<String> name(description->name(j));
+      VariableMode mode = description->mode(j);
+      int index = description->index(j);
+      switch (mode) {
+        case VAR:
+        case LET:
+        case CONST:
+        case CONST_LEGACY: {
+          PropertyAttributes attr =
+              IsImmutableVariableMode(mode) ? FROZEN : SEALED;
+          Handle<AccessorInfo> info =
+              Accessors::MakeModuleExport(name, index, attr);
+          Handle<Object> result =
+              JSObject::SetAccessor(module, info).ToHandleChecked();
+          DCHECK(!result->IsUndefined());
+          USE(result);
+          break;
+        }
+        case MODULE: {
+          Object* referenced_context = Context::cast(host_context)->get(index);
+          Handle<JSModule> value(Context::cast(referenced_context)->module());
+          JSObject::SetOwnPropertyIgnoreAttributes(module, name, value, FROZEN)
+              .Assert();
+          break;
+        }
+        case INTERNAL:
+        case TEMPORARY:
+        case DYNAMIC:
+        case DYNAMIC_GLOBAL:
+        case DYNAMIC_LOCAL:
+          UNREACHABLE();
+      }
+    }
+
+    JSObject::PreventExtensions(module).Assert();
+  }
+
+  DCHECK(!isolate->has_pending_exception());
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(Context, context, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
+
+  int index;
+  PropertyAttributes attributes;
+  ContextLookupFlags flags = FOLLOW_CHAINS;
+  BindingFlags binding_flags;
+  Handle<Object> holder =
+      context->Lookup(name, flags, &index, &attributes, &binding_flags);
+
+  // If the slot was not found the result is true.
+  if (holder.is_null()) {
+    return isolate->heap()->true_value();
+  }
+
+  // If the slot was found in a context, it should be DONT_DELETE.
+  if (holder->IsContext()) {
+    return isolate->heap()->false_value();
+  }
+
+  // The slot was found in a JSObject, either a context extension object,
+  // the global object, or the subject of a with.  Try to delete it
+  // (respecting DONT_DELETE).
+  Handle<JSObject> object = Handle<JSObject>::cast(holder);
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+                                     JSReceiver::DeleteProperty(object, name));
+  return *result;
+}
+
+
+static Object* ComputeReceiverForNonGlobal(Isolate* isolate, JSObject* holder) {
+  DCHECK(!holder->IsGlobalObject());
+  Context* top = isolate->context();
+  // Get the context extension function.
+  JSFunction* context_extension_function =
+      top->native_context()->context_extension_function();
+  // If the holder isn't a context extension object, we just return it
+  // as the receiver. This allows arguments objects to be used as
+  // receivers, but only if they are put in the context scope chain
+  // explicitly via a with-statement.
+  Object* constructor = holder->map()->constructor();
+  if (constructor != context_extension_function) return holder;
+  // Fall back to using the global object as the implicit receiver if
+  // the property turns out to be a local variable allocated in a
+  // context extension object - introduced via eval.
+  return isolate->heap()->undefined_value();
+}
+
+
+static ObjectPair LoadLookupSlotHelper(Arguments args, Isolate* isolate,
+                                       bool throw_error) {
+  HandleScope scope(isolate);
+  DCHECK_EQ(2, args.length());
+
+  if (!args[0]->IsContext() || !args[1]->IsString()) {
+    return MakePair(isolate->ThrowIllegalOperation(), NULL);
+  }
+  Handle<Context> context = args.at<Context>(0);
+  Handle<String> name = args.at<String>(1);
+
+  int index;
+  PropertyAttributes attributes;
+  ContextLookupFlags flags = FOLLOW_CHAINS;
+  BindingFlags binding_flags;
+  Handle<Object> holder =
+      context->Lookup(name, flags, &index, &attributes, &binding_flags);
+  if (isolate->has_pending_exception()) {
+    return MakePair(isolate->heap()->exception(), NULL);
+  }
+
+  // If the index is non-negative, the slot has been found in a context.
+  if (index >= 0) {
+    DCHECK(holder->IsContext());
+    // If the "property" we were looking for is a local variable, the
+    // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3.
+    Handle<Object> receiver = isolate->factory()->undefined_value();
+    Object* value = Context::cast(*holder)->get(index);
+    // Check for uninitialized bindings.
+    switch (binding_flags) {
+      case MUTABLE_CHECK_INITIALIZED:
+      case IMMUTABLE_CHECK_INITIALIZED_HARMONY:
+        if (value->IsTheHole()) {
+          Handle<Object> error;
+          MaybeHandle<Object> maybe_error =
+              isolate->factory()->NewReferenceError("not_defined",
+                                                    HandleVector(&name, 1));
+          if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
+          return MakePair(isolate->heap()->exception(), NULL);
+        }
+      // FALLTHROUGH
+      case MUTABLE_IS_INITIALIZED:
+      case IMMUTABLE_IS_INITIALIZED:
+      case IMMUTABLE_IS_INITIALIZED_HARMONY:
+        DCHECK(!value->IsTheHole());
+        return MakePair(value, *receiver);
+      case IMMUTABLE_CHECK_INITIALIZED:
+        if (value->IsTheHole()) {
+          DCHECK((attributes & READ_ONLY) != 0);
+          value = isolate->heap()->undefined_value();
+        }
+        return MakePair(value, *receiver);
+      case MISSING_BINDING:
+        UNREACHABLE();
+        return MakePair(NULL, NULL);
+    }
+  }
+
+  // Otherwise, if the slot was found the holder is a context extension
+  // object, subject of a with, or a global object.  We read the named
+  // property from it.
+  if (!holder.is_null()) {
+    Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder);
+#ifdef DEBUG
+    if (!object->IsJSProxy()) {
+      Maybe<bool> maybe = JSReceiver::HasProperty(object, name);
+      DCHECK(maybe.has_value);
+      DCHECK(maybe.value);
+    }
+#endif
+    // GetProperty below can cause GC.
+    Handle<Object> receiver_handle(
+        object->IsGlobalObject()
+            ? Object::cast(isolate->heap()->undefined_value())
+            : object->IsJSProxy() ? static_cast<Object*>(*object)
+                                  : ComputeReceiverForNonGlobal(
+                                        isolate, JSObject::cast(*object)),
+        isolate);
+
+    // No need to unhole the value here.  This is taken care of by the
+    // GetProperty function.
+    Handle<Object> value;
+    ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+        isolate, value, Object::GetProperty(object, name),
+        MakePair(isolate->heap()->exception(), NULL));
+    return MakePair(*value, *receiver_handle);
+  }
+
+  if (throw_error) {
+    // The property doesn't exist - throw exception.
+    Handle<Object> error;
+    MaybeHandle<Object> maybe_error = isolate->factory()->NewReferenceError(
+        "not_defined", HandleVector(&name, 1));
+    if (maybe_error.ToHandle(&error)) isolate->Throw(*error);
+    return MakePair(isolate->heap()->exception(), NULL);
+  } else {
+    // The property doesn't exist - return undefined.
+    return MakePair(isolate->heap()->undefined_value(),
+                    isolate->heap()->undefined_value());
+  }
+}
+
+
+RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlot) {
+  return LoadLookupSlotHelper(args, isolate, true);
+}
+
+
+RUNTIME_FUNCTION_RETURN_PAIR(Runtime_LoadLookupSlotNoReferenceError) {
+  return LoadLookupSlotHelper(args, isolate, false);
+}
+
+
+RUNTIME_FUNCTION(Runtime_StoreLookupSlot) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+
+  CONVERT_ARG_HANDLE_CHECKED(Object, value, 0);
+  CONVERT_ARG_HANDLE_CHECKED(Context, context, 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 2);
+  CONVERT_STRICT_MODE_ARG_CHECKED(strict_mode, 3);
+
+  int index;
+  PropertyAttributes attributes;
+  ContextLookupFlags flags = FOLLOW_CHAINS;
+  BindingFlags binding_flags;
+  Handle<Object> holder =
+      context->Lookup(name, flags, &index, &attributes, &binding_flags);
+  // In case of JSProxy, an exception might have been thrown.
+  if (isolate->has_pending_exception()) return isolate->heap()->exception();
+
+  // The property was found in a context slot.
+  if (index >= 0) {
+    if ((attributes & READ_ONLY) == 0) {
+      Handle<Context>::cast(holder)->set(index, *value);
+    } else if (strict_mode == STRICT) {
+      // Setting read only property in strict mode.
+      THROW_NEW_ERROR_RETURN_FAILURE(
+          isolate,
+          NewTypeError("strict_cannot_assign", HandleVector(&name, 1)));
+    }
+    return *value;
+  }
+
+  // Slow case: The property is not in a context slot.  It is either in a
+  // context extension object, a property of the subject of a with, or a
+  // property of the global object.
+  Handle<JSReceiver> object;
+  if (attributes != ABSENT) {
+    // The property exists on the holder.
+    object = Handle<JSReceiver>::cast(holder);
+  } else if (strict_mode == STRICT) {
+    // If absent in strict mode: throw.
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewReferenceError("not_defined", HandleVector(&name, 1)));
+  } else {
+    // If absent in sloppy mode: add the property to the global object.
+    object = Handle<JSReceiver>(context->global_object());
+  }
+
+  RETURN_FAILURE_ON_EXCEPTION(
+      isolate, Object::SetProperty(object, name, value, strict_mode));
+
+  return *value;
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetArgumentsProperty) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, raw_key, 0);
+
+  // Compute the frame holding the arguments.
+  JavaScriptFrameIterator it(isolate);
+  it.AdvanceToArgumentsFrame();
+  JavaScriptFrame* frame = it.frame();
+
+  // Get the actual number of provided arguments.
+  const uint32_t n = frame->ComputeParametersCount();
+
+  // Try to convert the key to an index. If successful and within
+  // index return the the argument from the frame.
+  uint32_t index;
+  if (raw_key->ToArrayIndex(&index) && index < n) {
+    return frame->GetParameter(index);
+  }
+
+  HandleScope scope(isolate);
+  if (raw_key->IsSymbol()) {
+    Handle<Symbol> symbol = Handle<Symbol>::cast(raw_key);
+    if (Name::Equals(symbol, isolate->factory()->iterator_symbol())) {
+      return isolate->native_context()->array_values_iterator();
+    }
+    // Lookup in the initial Object.prototype object.
+    Handle<Object> result;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, result,
+        Object::GetProperty(isolate->initial_object_prototype(),
+                            Handle<Symbol>::cast(raw_key)));
+    return *result;
+  }
+
+  // Convert the key to a string.
+  Handle<Object> converted;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, converted,
+                                     Execution::ToString(isolate, raw_key));
+  Handle<String> key = Handle<String>::cast(converted);
+
+  // Try to convert the string key into an array index.
+  if (key->AsArrayIndex(&index)) {
+    if (index < n) {
+      return frame->GetParameter(index);
+    } else {
+      Handle<Object> initial_prototype(isolate->initial_object_prototype());
+      Handle<Object> result;
+      ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+          isolate, result,
+          Object::GetElement(isolate, initial_prototype, index));
+      return *result;
+    }
+  }
+
+  // Handle special arguments properties.
+  if (String::Equals(isolate->factory()->length_string(), key)) {
+    return Smi::FromInt(n);
+  }
+  if (String::Equals(isolate->factory()->callee_string(), key)) {
+    JSFunction* function = frame->function();
+    if (function->shared()->strict_mode() == STRICT) {
+      THROW_NEW_ERROR_RETURN_FAILURE(
+          isolate, NewTypeError("strict_arguments_callee",
+                                HandleVector<Object>(NULL, 0)));
+    }
+    return function;
+  }
+
+  // Lookup in the initial Object.prototype object.
+  Handle<Object> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      Object::GetProperty(isolate->initial_object_prototype(), key));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_ArgumentsLength) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  JavaScriptFrameIterator it(isolate);
+  JavaScriptFrame* frame = it.frame();
+  return Smi::FromInt(frame->GetArgumentsLength());
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_Arguments) {
+  SealHandleScope shs(isolate);
+  return __RT_impl_Runtime_GetArgumentsProperty(args, isolate);
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-strings.cc b/src/runtime/runtime-strings.cc
new file mode 100644
index 0000000..df2210c
--- /dev/null
+++ b/src/runtime/runtime-strings.cc
@@ -0,0 +1,1305 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/jsregexp-inl.h"
+#include "src/jsregexp.h"
+#include "src/runtime/runtime-utils.h"
+#include "src/string-builder.h"
+#include "src/string-search.h"
+
+namespace v8 {
+namespace internal {
+
+
+// Perform string match of pattern on subject, starting at start index.
+// Caller must ensure that 0 <= start_index <= sub->length(),
+// and should check that pat->length() + start_index <= sub->length().
+int StringMatch(Isolate* isolate, Handle<String> sub, Handle<String> pat,
+                int start_index) {
+  DCHECK(0 <= start_index);
+  DCHECK(start_index <= sub->length());
+
+  int pattern_length = pat->length();
+  if (pattern_length == 0) return start_index;
+
+  int subject_length = sub->length();
+  if (start_index + pattern_length > subject_length) return -1;
+
+  sub = String::Flatten(sub);
+  pat = String::Flatten(pat);
+
+  DisallowHeapAllocation no_gc;  // ensure vectors stay valid
+  // Extract flattened substrings of cons strings before getting encoding.
+  String::FlatContent seq_sub = sub->GetFlatContent();
+  String::FlatContent seq_pat = pat->GetFlatContent();
+
+  // dispatch on type of strings
+  if (seq_pat.IsOneByte()) {
+    Vector<const uint8_t> pat_vector = seq_pat.ToOneByteVector();
+    if (seq_sub.IsOneByte()) {
+      return SearchString(isolate, seq_sub.ToOneByteVector(), pat_vector,
+                          start_index);
+    }
+    return SearchString(isolate, seq_sub.ToUC16Vector(), pat_vector,
+                        start_index);
+  }
+  Vector<const uc16> pat_vector = seq_pat.ToUC16Vector();
+  if (seq_sub.IsOneByte()) {
+    return SearchString(isolate, seq_sub.ToOneByteVector(), pat_vector,
+                        start_index);
+  }
+  return SearchString(isolate, seq_sub.ToUC16Vector(), pat_vector, start_index);
+}
+
+
+// This may return an empty MaybeHandle if an exception is thrown or
+// we abort due to reaching the recursion limit.
+MaybeHandle<String> StringReplaceOneCharWithString(
+    Isolate* isolate, Handle<String> subject, Handle<String> search,
+    Handle<String> replace, bool* found, int recursion_limit) {
+  StackLimitCheck stackLimitCheck(isolate);
+  if (stackLimitCheck.HasOverflowed() || (recursion_limit == 0)) {
+    return MaybeHandle<String>();
+  }
+  recursion_limit--;
+  if (subject->IsConsString()) {
+    ConsString* cons = ConsString::cast(*subject);
+    Handle<String> first = Handle<String>(cons->first());
+    Handle<String> second = Handle<String>(cons->second());
+    Handle<String> new_first;
+    if (!StringReplaceOneCharWithString(isolate, first, search, replace, found,
+                                        recursion_limit).ToHandle(&new_first)) {
+      return MaybeHandle<String>();
+    }
+    if (*found) return isolate->factory()->NewConsString(new_first, second);
+
+    Handle<String> new_second;
+    if (!StringReplaceOneCharWithString(isolate, second, search, replace, found,
+                                        recursion_limit)
+             .ToHandle(&new_second)) {
+      return MaybeHandle<String>();
+    }
+    if (*found) return isolate->factory()->NewConsString(first, new_second);
+
+    return subject;
+  } else {
+    int index = StringMatch(isolate, subject, search, 0);
+    if (index == -1) return subject;
+    *found = true;
+    Handle<String> first = isolate->factory()->NewSubString(subject, 0, index);
+    Handle<String> cons1;
+    ASSIGN_RETURN_ON_EXCEPTION(
+        isolate, cons1, isolate->factory()->NewConsString(first, replace),
+        String);
+    Handle<String> second =
+        isolate->factory()->NewSubString(subject, index + 1, subject->length());
+    return isolate->factory()->NewConsString(cons1, second);
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringReplaceOneCharWithString) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, search, 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, replace, 2);
+
+  // If the cons string tree is too deep, we simply abort the recursion and
+  // retry with a flattened subject string.
+  const int kRecursionLimit = 0x1000;
+  bool found = false;
+  Handle<String> result;
+  if (StringReplaceOneCharWithString(isolate, subject, search, replace, &found,
+                                     kRecursionLimit).ToHandle(&result)) {
+    return *result;
+  }
+  if (isolate->has_pending_exception()) return isolate->heap()->exception();
+
+  subject = String::Flatten(subject);
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result,
+      StringReplaceOneCharWithString(isolate, subject, search, replace, &found,
+                                     kRecursionLimit));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringIndexOf) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
+
+  uint32_t start_index;
+  if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
+
+  RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length()));
+  int position = StringMatch(isolate, sub, pat, start_index);
+  return Smi::FromInt(position);
+}
+
+
+template <typename schar, typename pchar>
+static int StringMatchBackwards(Vector<const schar> subject,
+                                Vector<const pchar> pattern, int idx) {
+  int pattern_length = pattern.length();
+  DCHECK(pattern_length >= 1);
+  DCHECK(idx + pattern_length <= subject.length());
+
+  if (sizeof(schar) == 1 && sizeof(pchar) > 1) {
+    for (int i = 0; i < pattern_length; i++) {
+      uc16 c = pattern[i];
+      if (c > String::kMaxOneByteCharCode) {
+        return -1;
+      }
+    }
+  }
+
+  pchar pattern_first_char = pattern[0];
+  for (int i = idx; i >= 0; i--) {
+    if (subject[i] != pattern_first_char) continue;
+    int j = 1;
+    while (j < pattern_length) {
+      if (pattern[j] != subject[i + j]) {
+        break;
+      }
+      j++;
+    }
+    if (j == pattern_length) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringLastIndexOf) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, sub, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, pat, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, index, 2);
+
+  uint32_t start_index;
+  if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1);
+
+  uint32_t pat_length = pat->length();
+  uint32_t sub_length = sub->length();
+
+  if (start_index + pat_length > sub_length) {
+    start_index = sub_length - pat_length;
+  }
+
+  if (pat_length == 0) {
+    return Smi::FromInt(start_index);
+  }
+
+  sub = String::Flatten(sub);
+  pat = String::Flatten(pat);
+
+  int position = -1;
+  DisallowHeapAllocation no_gc;  // ensure vectors stay valid
+
+  String::FlatContent sub_content = sub->GetFlatContent();
+  String::FlatContent pat_content = pat->GetFlatContent();
+
+  if (pat_content.IsOneByte()) {
+    Vector<const uint8_t> pat_vector = pat_content.ToOneByteVector();
+    if (sub_content.IsOneByte()) {
+      position = StringMatchBackwards(sub_content.ToOneByteVector(), pat_vector,
+                                      start_index);
+    } else {
+      position = StringMatchBackwards(sub_content.ToUC16Vector(), pat_vector,
+                                      start_index);
+    }
+  } else {
+    Vector<const uc16> pat_vector = pat_content.ToUC16Vector();
+    if (sub_content.IsOneByte()) {
+      position = StringMatchBackwards(sub_content.ToOneByteVector(), pat_vector,
+                                      start_index);
+    } else {
+      position = StringMatchBackwards(sub_content.ToUC16Vector(), pat_vector,
+                                      start_index);
+    }
+  }
+
+  return Smi::FromInt(position);
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringLocaleCompare) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
+
+  if (str1.is_identical_to(str2)) return Smi::FromInt(0);  // Equal.
+  int str1_length = str1->length();
+  int str2_length = str2->length();
+
+  // Decide trivial cases without flattening.
+  if (str1_length == 0) {
+    if (str2_length == 0) return Smi::FromInt(0);  // Equal.
+    return Smi::FromInt(-str2_length);
+  } else {
+    if (str2_length == 0) return Smi::FromInt(str1_length);
+  }
+
+  int end = str1_length < str2_length ? str1_length : str2_length;
+
+  // No need to flatten if we are going to find the answer on the first
+  // character.  At this point we know there is at least one character
+  // in each string, due to the trivial case handling above.
+  int d = str1->Get(0) - str2->Get(0);
+  if (d != 0) return Smi::FromInt(d);
+
+  str1 = String::Flatten(str1);
+  str2 = String::Flatten(str2);
+
+  DisallowHeapAllocation no_gc;
+  String::FlatContent flat1 = str1->GetFlatContent();
+  String::FlatContent flat2 = str2->GetFlatContent();
+
+  for (int i = 0; i < end; i++) {
+    if (flat1.Get(i) != flat2.Get(i)) {
+      return Smi::FromInt(flat1.Get(i) - flat2.Get(i));
+    }
+  }
+
+  return Smi::FromInt(str1_length - str2_length);
+}
+
+
+RUNTIME_FUNCTION(Runtime_SubString) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
+  int start, end;
+  // We have a fast integer-only case here to avoid a conversion to double in
+  // the common case where from and to are Smis.
+  if (args[1]->IsSmi() && args[2]->IsSmi()) {
+    CONVERT_SMI_ARG_CHECKED(from_number, 1);
+    CONVERT_SMI_ARG_CHECKED(to_number, 2);
+    start = from_number;
+    end = to_number;
+  } else {
+    CONVERT_DOUBLE_ARG_CHECKED(from_number, 1);
+    CONVERT_DOUBLE_ARG_CHECKED(to_number, 2);
+    start = FastD2IChecked(from_number);
+    end = FastD2IChecked(to_number);
+  }
+  RUNTIME_ASSERT(end >= start);
+  RUNTIME_ASSERT(start >= 0);
+  RUNTIME_ASSERT(end <= string->length());
+  isolate->counters()->sub_string_runtime()->Increment();
+
+  return *isolate->factory()->NewSubString(string, start, end);
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringAdd) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(String, str1, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, str2, 1);
+  isolate->counters()->string_add_runtime()->Increment();
+  Handle<String> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, isolate->factory()->NewConsString(str1, str2));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_InternalizeString) {
+  HandleScope handles(isolate);
+  RUNTIME_ASSERT(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
+  return *isolate->factory()->InternalizeString(string);
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringMatch) {
+  HandleScope handles(isolate);
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, regexp_info, 2);
+
+  RUNTIME_ASSERT(regexp_info->HasFastObjectElements());
+
+  RegExpImpl::GlobalCache global_cache(regexp, subject, true, isolate);
+  if (global_cache.HasException()) return isolate->heap()->exception();
+
+  int capture_count = regexp->CaptureCount();
+
+  ZoneScope zone_scope(isolate->runtime_zone());
+  ZoneList<int> offsets(8, zone_scope.zone());
+
+  while (true) {
+    int32_t* match = global_cache.FetchNext();
+    if (match == NULL) break;
+    offsets.Add(match[0], zone_scope.zone());  // start
+    offsets.Add(match[1], zone_scope.zone());  // end
+  }
+
+  if (global_cache.HasException()) return isolate->heap()->exception();
+
+  if (offsets.length() == 0) {
+    // Not a single match.
+    return isolate->heap()->null_value();
+  }
+
+  RegExpImpl::SetLastMatchInfo(regexp_info, subject, capture_count,
+                               global_cache.LastSuccessfulMatch());
+
+  int matches = offsets.length() / 2;
+  Handle<FixedArray> elements = isolate->factory()->NewFixedArray(matches);
+  Handle<String> substring =
+      isolate->factory()->NewSubString(subject, offsets.at(0), offsets.at(1));
+  elements->set(0, *substring);
+  for (int i = 1; i < matches; i++) {
+    HandleScope temp_scope(isolate);
+    int from = offsets.at(i * 2);
+    int to = offsets.at(i * 2 + 1);
+    Handle<String> substring =
+        isolate->factory()->NewProperSubString(subject, from, to);
+    elements->set(i, *substring);
+  }
+  Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(elements);
+  result->set_length(Smi::FromInt(matches));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringCharCodeAtRT) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, subject, 0);
+  CONVERT_NUMBER_CHECKED(uint32_t, i, Uint32, args[1]);
+
+  // Flatten the string.  If someone wants to get a char at an index
+  // in a cons string, it is likely that more indices will be
+  // accessed.
+  subject = String::Flatten(subject);
+
+  if (i >= static_cast<uint32_t>(subject->length())) {
+    return isolate->heap()->nan_value();
+  }
+
+  return Smi::FromInt(subject->Get(i));
+}
+
+
+RUNTIME_FUNCTION(Runtime_CharFromCode) {
+  HandleScope handlescope(isolate);
+  DCHECK(args.length() == 1);
+  if (args[0]->IsNumber()) {
+    CONVERT_NUMBER_CHECKED(uint32_t, code, Uint32, args[0]);
+    code &= 0xffff;
+    return *isolate->factory()->LookupSingleCharacterStringFromCode(code);
+  }
+  return isolate->heap()->empty_string();
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringCompare) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
+
+  isolate->counters()->string_compare_runtime()->Increment();
+
+  // A few fast case tests before we flatten.
+  if (x.is_identical_to(y)) return Smi::FromInt(EQUAL);
+  if (y->length() == 0) {
+    if (x->length() == 0) return Smi::FromInt(EQUAL);
+    return Smi::FromInt(GREATER);
+  } else if (x->length() == 0) {
+    return Smi::FromInt(LESS);
+  }
+
+  int d = x->Get(0) - y->Get(0);
+  if (d < 0)
+    return Smi::FromInt(LESS);
+  else if (d > 0)
+    return Smi::FromInt(GREATER);
+
+  // Slow case.
+  x = String::Flatten(x);
+  y = String::Flatten(y);
+
+  DisallowHeapAllocation no_gc;
+  Object* equal_prefix_result = Smi::FromInt(EQUAL);
+  int prefix_length = x->length();
+  if (y->length() < prefix_length) {
+    prefix_length = y->length();
+    equal_prefix_result = Smi::FromInt(GREATER);
+  } else if (y->length() > prefix_length) {
+    equal_prefix_result = Smi::FromInt(LESS);
+  }
+  int r;
+  String::FlatContent x_content = x->GetFlatContent();
+  String::FlatContent y_content = y->GetFlatContent();
+  if (x_content.IsOneByte()) {
+    Vector<const uint8_t> x_chars = x_content.ToOneByteVector();
+    if (y_content.IsOneByte()) {
+      Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
+      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
+    } else {
+      Vector<const uc16> y_chars = y_content.ToUC16Vector();
+      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
+    }
+  } else {
+    Vector<const uc16> x_chars = x_content.ToUC16Vector();
+    if (y_content.IsOneByte()) {
+      Vector<const uint8_t> y_chars = y_content.ToOneByteVector();
+      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
+    } else {
+      Vector<const uc16> y_chars = y_content.ToUC16Vector();
+      r = CompareChars(x_chars.start(), y_chars.start(), prefix_length);
+    }
+  }
+  Object* result;
+  if (r == 0) {
+    result = equal_prefix_result;
+  } else {
+    result = (r < 0) ? Smi::FromInt(LESS) : Smi::FromInt(GREATER);
+  }
+  return result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringBuilderConcat) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
+  int32_t array_length;
+  if (!args[1]->ToInt32(&array_length)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
+  }
+  CONVERT_ARG_HANDLE_CHECKED(String, special, 2);
+
+  size_t actual_array_length = 0;
+  RUNTIME_ASSERT(
+      TryNumberToSize(isolate, array->length(), &actual_array_length));
+  RUNTIME_ASSERT(array_length >= 0);
+  RUNTIME_ASSERT(static_cast<size_t>(array_length) <= actual_array_length);
+
+  // This assumption is used by the slice encoding in one or two smis.
+  DCHECK(Smi::kMaxValue >= String::kMaxLength);
+
+  RUNTIME_ASSERT(array->HasFastElements());
+  JSObject::EnsureCanContainHeapObjectElements(array);
+
+  int special_length = special->length();
+  if (!array->HasFastObjectElements()) {
+    return isolate->Throw(isolate->heap()->illegal_argument_string());
+  }
+
+  int length;
+  bool one_byte = special->HasOnlyOneByteChars();
+
+  {
+    DisallowHeapAllocation no_gc;
+    FixedArray* fixed_array = FixedArray::cast(array->elements());
+    if (fixed_array->length() < array_length) {
+      array_length = fixed_array->length();
+    }
+
+    if (array_length == 0) {
+      return isolate->heap()->empty_string();
+    } else if (array_length == 1) {
+      Object* first = fixed_array->get(0);
+      if (first->IsString()) return first;
+    }
+    length = StringBuilderConcatLength(special_length, fixed_array,
+                                       array_length, &one_byte);
+  }
+
+  if (length == -1) {
+    return isolate->Throw(isolate->heap()->illegal_argument_string());
+  }
+
+  if (one_byte) {
+    Handle<SeqOneByteString> answer;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, answer, isolate->factory()->NewRawOneByteString(length));
+    StringBuilderConcatHelper(*special, answer->GetChars(),
+                              FixedArray::cast(array->elements()),
+                              array_length);
+    return *answer;
+  } else {
+    Handle<SeqTwoByteString> answer;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, answer, isolate->factory()->NewRawTwoByteString(length));
+    StringBuilderConcatHelper(*special, answer->GetChars(),
+                              FixedArray::cast(array->elements()),
+                              array_length);
+    return *answer;
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringBuilderJoin) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, array, 0);
+  int32_t array_length;
+  if (!args[1]->ToInt32(&array_length)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
+  }
+  CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
+  RUNTIME_ASSERT(array->HasFastObjectElements());
+  RUNTIME_ASSERT(array_length >= 0);
+
+  Handle<FixedArray> fixed_array(FixedArray::cast(array->elements()));
+  if (fixed_array->length() < array_length) {
+    array_length = fixed_array->length();
+  }
+
+  if (array_length == 0) {
+    return isolate->heap()->empty_string();
+  } else if (array_length == 1) {
+    Object* first = fixed_array->get(0);
+    RUNTIME_ASSERT(first->IsString());
+    return first;
+  }
+
+  int separator_length = separator->length();
+  RUNTIME_ASSERT(separator_length > 0);
+  int max_nof_separators =
+      (String::kMaxLength + separator_length - 1) / separator_length;
+  if (max_nof_separators < (array_length - 1)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
+  }
+  int length = (array_length - 1) * separator_length;
+  for (int i = 0; i < array_length; i++) {
+    Object* element_obj = fixed_array->get(i);
+    RUNTIME_ASSERT(element_obj->IsString());
+    String* element = String::cast(element_obj);
+    int increment = element->length();
+    if (increment > String::kMaxLength - length) {
+      STATIC_ASSERT(String::kMaxLength < kMaxInt);
+      length = kMaxInt;  // Provoke exception;
+      break;
+    }
+    length += increment;
+  }
+
+  Handle<SeqTwoByteString> answer;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, answer, isolate->factory()->NewRawTwoByteString(length));
+
+  DisallowHeapAllocation no_gc;
+
+  uc16* sink = answer->GetChars();
+#ifdef DEBUG
+  uc16* end = sink + length;
+#endif
+
+  RUNTIME_ASSERT(fixed_array->get(0)->IsString());
+  String* first = String::cast(fixed_array->get(0));
+  String* separator_raw = *separator;
+  int first_length = first->length();
+  String::WriteToFlat(first, sink, 0, first_length);
+  sink += first_length;
+
+  for (int i = 1; i < array_length; i++) {
+    DCHECK(sink + separator_length <= end);
+    String::WriteToFlat(separator_raw, sink, 0, separator_length);
+    sink += separator_length;
+
+    RUNTIME_ASSERT(fixed_array->get(i)->IsString());
+    String* element = String::cast(fixed_array->get(i));
+    int element_length = element->length();
+    DCHECK(sink + element_length <= end);
+    String::WriteToFlat(element, sink, 0, element_length);
+    sink += element_length;
+  }
+  DCHECK(sink == end);
+
+  // Use %_FastOneByteArrayJoin instead.
+  DCHECK(!answer->IsOneByteRepresentation());
+  return *answer;
+}
+
+template <typename Char>
+static void JoinSparseArrayWithSeparator(FixedArray* elements,
+                                         int elements_length,
+                                         uint32_t array_length,
+                                         String* separator,
+                                         Vector<Char> buffer) {
+  DisallowHeapAllocation no_gc;
+  int previous_separator_position = 0;
+  int separator_length = separator->length();
+  int cursor = 0;
+  for (int i = 0; i < elements_length; i += 2) {
+    int position = NumberToInt32(elements->get(i));
+    String* string = String::cast(elements->get(i + 1));
+    int string_length = string->length();
+    if (string->length() > 0) {
+      while (previous_separator_position < position) {
+        String::WriteToFlat<Char>(separator, &buffer[cursor], 0,
+                                  separator_length);
+        cursor += separator_length;
+        previous_separator_position++;
+      }
+      String::WriteToFlat<Char>(string, &buffer[cursor], 0, string_length);
+      cursor += string->length();
+    }
+  }
+  if (separator_length > 0) {
+    // Array length must be representable as a signed 32-bit number,
+    // otherwise the total string length would have been too large.
+    DCHECK(array_length <= 0x7fffffff);  // Is int32_t.
+    int last_array_index = static_cast<int>(array_length - 1);
+    while (previous_separator_position < last_array_index) {
+      String::WriteToFlat<Char>(separator, &buffer[cursor], 0,
+                                separator_length);
+      cursor += separator_length;
+      previous_separator_position++;
+    }
+  }
+  DCHECK(cursor <= buffer.length());
+}
+
+
+RUNTIME_FUNCTION(Runtime_SparseJoinWithSeparator) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSArray, elements_array, 0);
+  CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
+  CONVERT_ARG_HANDLE_CHECKED(String, separator, 2);
+  // elements_array is fast-mode JSarray of alternating positions
+  // (increasing order) and strings.
+  RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
+  // array_length is length of original array (used to add separators);
+  // separator is string to put between elements. Assumed to be non-empty.
+  RUNTIME_ASSERT(array_length > 0);
+
+  // Find total length of join result.
+  int string_length = 0;
+  bool is_one_byte = separator->IsOneByteRepresentation();
+  bool overflow = false;
+  CONVERT_NUMBER_CHECKED(int, elements_length, Int32, elements_array->length());
+  RUNTIME_ASSERT(elements_length <= elements_array->elements()->length());
+  RUNTIME_ASSERT((elements_length & 1) == 0);  // Even length.
+  FixedArray* elements = FixedArray::cast(elements_array->elements());
+  for (int i = 0; i < elements_length; i += 2) {
+    RUNTIME_ASSERT(elements->get(i)->IsNumber());
+    CONVERT_NUMBER_CHECKED(uint32_t, position, Uint32, elements->get(i));
+    RUNTIME_ASSERT(position < array_length);
+    RUNTIME_ASSERT(elements->get(i + 1)->IsString());
+  }
+
+  {
+    DisallowHeapAllocation no_gc;
+    for (int i = 0; i < elements_length; i += 2) {
+      String* string = String::cast(elements->get(i + 1));
+      int length = string->length();
+      if (is_one_byte && !string->IsOneByteRepresentation()) {
+        is_one_byte = false;
+      }
+      if (length > String::kMaxLength ||
+          String::kMaxLength - length < string_length) {
+        overflow = true;
+        break;
+      }
+      string_length += length;
+    }
+  }
+
+  int separator_length = separator->length();
+  if (!overflow && separator_length > 0) {
+    if (array_length <= 0x7fffffffu) {
+      int separator_count = static_cast<int>(array_length) - 1;
+      int remaining_length = String::kMaxLength - string_length;
+      if ((remaining_length / separator_length) >= separator_count) {
+        string_length += separator_length * (array_length - 1);
+      } else {
+        // Not room for the separators within the maximal string length.
+        overflow = true;
+      }
+    } else {
+      // Nonempty separator and at least 2^31-1 separators necessary
+      // means that the string is too large to create.
+      STATIC_ASSERT(String::kMaxLength < 0x7fffffff);
+      overflow = true;
+    }
+  }
+  if (overflow) {
+    // Throw an exception if the resulting string is too large. See
+    // https://code.google.com/p/chromium/issues/detail?id=336820
+    // for details.
+    THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewInvalidStringLengthError());
+  }
+
+  if (is_one_byte) {
+    Handle<SeqOneByteString> result = isolate->factory()
+                                          ->NewRawOneByteString(string_length)
+                                          .ToHandleChecked();
+    JoinSparseArrayWithSeparator<uint8_t>(
+        FixedArray::cast(elements_array->elements()), elements_length,
+        array_length, *separator,
+        Vector<uint8_t>(result->GetChars(), string_length));
+    return *result;
+  } else {
+    Handle<SeqTwoByteString> result = isolate->factory()
+                                          ->NewRawTwoByteString(string_length)
+                                          .ToHandleChecked();
+    JoinSparseArrayWithSeparator<uc16>(
+        FixedArray::cast(elements_array->elements()), elements_length,
+        array_length, *separator,
+        Vector<uc16>(result->GetChars(), string_length));
+    return *result;
+  }
+}
+
+
+// Copies Latin1 characters to the given fixed array looking up
+// one-char strings in the cache. Gives up on the first char that is
+// not in the cache and fills the remainder with smi zeros. Returns
+// the length of the successfully copied prefix.
+static int CopyCachedOneByteCharsToArray(Heap* heap, const uint8_t* chars,
+                                         FixedArray* elements, int length) {
+  DisallowHeapAllocation no_gc;
+  FixedArray* one_byte_cache = heap->single_character_string_cache();
+  Object* undefined = heap->undefined_value();
+  int i;
+  WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
+  for (i = 0; i < length; ++i) {
+    Object* value = one_byte_cache->get(chars[i]);
+    if (value == undefined) break;
+    elements->set(i, value, mode);
+  }
+  if (i < length) {
+    DCHECK(Smi::FromInt(0) == 0);
+    memset(elements->data_start() + i, 0, kPointerSize * (length - i));
+  }
+#ifdef DEBUG
+  for (int j = 0; j < length; ++j) {
+    Object* element = elements->get(j);
+    DCHECK(element == Smi::FromInt(0) ||
+           (element->IsString() && String::cast(element)->LooksValid()));
+  }
+#endif
+  return i;
+}
+
+
+// Converts a String to JSArray.
+// For example, "foo" => ["f", "o", "o"].
+RUNTIME_FUNCTION(Runtime_StringToArray) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
+  CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
+
+  s = String::Flatten(s);
+  const int length = static_cast<int>(Min<uint32_t>(s->length(), limit));
+
+  Handle<FixedArray> elements;
+  int position = 0;
+  if (s->IsFlat() && s->IsOneByteRepresentation()) {
+    // Try using cached chars where possible.
+    elements = isolate->factory()->NewUninitializedFixedArray(length);
+
+    DisallowHeapAllocation no_gc;
+    String::FlatContent content = s->GetFlatContent();
+    if (content.IsOneByte()) {
+      Vector<const uint8_t> chars = content.ToOneByteVector();
+      // Note, this will initialize all elements (not only the prefix)
+      // to prevent GC from seeing partially initialized array.
+      position = CopyCachedOneByteCharsToArray(isolate->heap(), chars.start(),
+                                               *elements, length);
+    } else {
+      MemsetPointer(elements->data_start(), isolate->heap()->undefined_value(),
+                    length);
+    }
+  } else {
+    elements = isolate->factory()->NewFixedArray(length);
+  }
+  for (int i = position; i < length; ++i) {
+    Handle<Object> str =
+        isolate->factory()->LookupSingleCharacterStringFromCode(s->Get(i));
+    elements->set(i, *str);
+  }
+
+#ifdef DEBUG
+  for (int i = 0; i < length; ++i) {
+    DCHECK(String::cast(elements->get(i))->length() == 1);
+  }
+#endif
+
+  return *isolate->factory()->NewJSArrayWithElements(elements);
+}
+
+
+static inline bool ToUpperOverflows(uc32 character) {
+  // y with umlauts and the micro sign are the only characters that stop
+  // fitting into one-byte when converting to uppercase.
+  static const uc32 yuml_code = 0xff;
+  static const uc32 micro_code = 0xb5;
+  return (character == yuml_code || character == micro_code);
+}
+
+
+template <class Converter>
+MUST_USE_RESULT static Object* ConvertCaseHelper(
+    Isolate* isolate, String* string, SeqString* result, int result_length,
+    unibrow::Mapping<Converter, 128>* mapping) {
+  DisallowHeapAllocation no_gc;
+  // We try this twice, once with the assumption that the result is no longer
+  // than the input and, if that assumption breaks, again with the exact
+  // length.  This may not be pretty, but it is nicer than what was here before
+  // and I hereby claim my vaffel-is.
+  //
+  // NOTE: This assumes that the upper/lower case of an ASCII
+  // character is also ASCII.  This is currently the case, but it
+  // might break in the future if we implement more context and locale
+  // dependent upper/lower conversions.
+  bool has_changed_character = false;
+
+  // Convert all characters to upper case, assuming that they will fit
+  // in the buffer
+  StringCharacterStream stream(string);
+  unibrow::uchar chars[Converter::kMaxWidth];
+  // We can assume that the string is not empty
+  uc32 current = stream.GetNext();
+  bool ignore_overflow = Converter::kIsToLower || result->IsSeqTwoByteString();
+  for (int i = 0; i < result_length;) {
+    bool has_next = stream.HasMore();
+    uc32 next = has_next ? stream.GetNext() : 0;
+    int char_length = mapping->get(current, next, chars);
+    if (char_length == 0) {
+      // The case conversion of this character is the character itself.
+      result->Set(i, current);
+      i++;
+    } else if (char_length == 1 &&
+               (ignore_overflow || !ToUpperOverflows(current))) {
+      // Common case: converting the letter resulted in one character.
+      DCHECK(static_cast<uc32>(chars[0]) != current);
+      result->Set(i, chars[0]);
+      has_changed_character = true;
+      i++;
+    } else if (result_length == string->length()) {
+      bool overflows = ToUpperOverflows(current);
+      // We've assumed that the result would be as long as the
+      // input but here is a character that converts to several
+      // characters.  No matter, we calculate the exact length
+      // of the result and try the whole thing again.
+      //
+      // Note that this leaves room for optimization.  We could just
+      // memcpy what we already have to the result string.  Also,
+      // the result string is the last object allocated we could
+      // "realloc" it and probably, in the vast majority of cases,
+      // extend the existing string to be able to hold the full
+      // result.
+      int next_length = 0;
+      if (has_next) {
+        next_length = mapping->get(next, 0, chars);
+        if (next_length == 0) next_length = 1;
+      }
+      int current_length = i + char_length + next_length;
+      while (stream.HasMore()) {
+        current = stream.GetNext();
+        overflows |= ToUpperOverflows(current);
+        // NOTE: we use 0 as the next character here because, while
+        // the next character may affect what a character converts to,
+        // it does not in any case affect the length of what it convert
+        // to.
+        int char_length = mapping->get(current, 0, chars);
+        if (char_length == 0) char_length = 1;
+        current_length += char_length;
+        if (current_length > String::kMaxLength) {
+          AllowHeapAllocation allocate_error_and_return;
+          THROW_NEW_ERROR_RETURN_FAILURE(isolate,
+                                         NewInvalidStringLengthError());
+        }
+      }
+      // Try again with the real length.  Return signed if we need
+      // to allocate a two-byte string for to uppercase.
+      return (overflows && !ignore_overflow) ? Smi::FromInt(-current_length)
+                                             : Smi::FromInt(current_length);
+    } else {
+      for (int j = 0; j < char_length; j++) {
+        result->Set(i, chars[j]);
+        i++;
+      }
+      has_changed_character = true;
+    }
+    current = next;
+  }
+  if (has_changed_character) {
+    return result;
+  } else {
+    // If we didn't actually change anything in doing the conversion
+    // we simple return the result and let the converted string
+    // become garbage; there is no reason to keep two identical strings
+    // alive.
+    return string;
+  }
+}
+
+
+static const uintptr_t kOneInEveryByte = kUintptrAllBitsSet / 0xFF;
+static const uintptr_t kAsciiMask = kOneInEveryByte << 7;
+
+// Given a word and two range boundaries returns a word with high bit
+// set in every byte iff the corresponding input byte was strictly in
+// the range (m, n). All the other bits in the result are cleared.
+// This function is only useful when it can be inlined and the
+// boundaries are statically known.
+// Requires: all bytes in the input word and the boundaries must be
+// ASCII (less than 0x7F).
+static inline uintptr_t AsciiRangeMask(uintptr_t w, char m, char n) {
+  // Use strict inequalities since in edge cases the function could be
+  // further simplified.
+  DCHECK(0 < m && m < n);
+  // Has high bit set in every w byte less than n.
+  uintptr_t tmp1 = kOneInEveryByte * (0x7F + n) - w;
+  // Has high bit set in every w byte greater than m.
+  uintptr_t tmp2 = w + kOneInEveryByte * (0x7F - m);
+  return (tmp1 & tmp2 & (kOneInEveryByte * 0x80));
+}
+
+
+#ifdef DEBUG
+static bool CheckFastAsciiConvert(char* dst, const char* src, int length,
+                                  bool changed, bool is_to_lower) {
+  bool expected_changed = false;
+  for (int i = 0; i < length; i++) {
+    if (dst[i] == src[i]) continue;
+    expected_changed = true;
+    if (is_to_lower) {
+      DCHECK('A' <= src[i] && src[i] <= 'Z');
+      DCHECK(dst[i] == src[i] + ('a' - 'A'));
+    } else {
+      DCHECK('a' <= src[i] && src[i] <= 'z');
+      DCHECK(dst[i] == src[i] - ('a' - 'A'));
+    }
+  }
+  return (expected_changed == changed);
+}
+#endif
+
+
+template <class Converter>
+static bool FastAsciiConvert(char* dst, const char* src, int length,
+                             bool* changed_out) {
+#ifdef DEBUG
+  char* saved_dst = dst;
+  const char* saved_src = src;
+#endif
+  DisallowHeapAllocation no_gc;
+  // We rely on the distance between upper and lower case letters
+  // being a known power of 2.
+  DCHECK('a' - 'A' == (1 << 5));
+  // Boundaries for the range of input characters than require conversion.
+  static const char lo = Converter::kIsToLower ? 'A' - 1 : 'a' - 1;
+  static const char hi = Converter::kIsToLower ? 'Z' + 1 : 'z' + 1;
+  bool changed = false;
+  uintptr_t or_acc = 0;
+  const char* const limit = src + length;
+
+  // dst is newly allocated and always aligned.
+  DCHECK(IsAligned(reinterpret_cast<intptr_t>(dst), sizeof(uintptr_t)));
+  // Only attempt processing one word at a time if src is also aligned.
+  if (IsAligned(reinterpret_cast<intptr_t>(src), sizeof(uintptr_t))) {
+    // Process the prefix of the input that requires no conversion one aligned
+    // (machine) word at a time.
+    while (src <= limit - sizeof(uintptr_t)) {
+      const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
+      or_acc |= w;
+      if (AsciiRangeMask(w, lo, hi) != 0) {
+        changed = true;
+        break;
+      }
+      *reinterpret_cast<uintptr_t*>(dst) = w;
+      src += sizeof(uintptr_t);
+      dst += sizeof(uintptr_t);
+    }
+    // Process the remainder of the input performing conversion when
+    // required one word at a time.
+    while (src <= limit - sizeof(uintptr_t)) {
+      const uintptr_t w = *reinterpret_cast<const uintptr_t*>(src);
+      or_acc |= w;
+      uintptr_t m = AsciiRangeMask(w, lo, hi);
+      // The mask has high (7th) bit set in every byte that needs
+      // conversion and we know that the distance between cases is
+      // 1 << 5.
+      *reinterpret_cast<uintptr_t*>(dst) = w ^ (m >> 2);
+      src += sizeof(uintptr_t);
+      dst += sizeof(uintptr_t);
+    }
+  }
+  // Process the last few bytes of the input (or the whole input if
+  // unaligned access is not supported).
+  while (src < limit) {
+    char c = *src;
+    or_acc |= c;
+    if (lo < c && c < hi) {
+      c ^= (1 << 5);
+      changed = true;
+    }
+    *dst = c;
+    ++src;
+    ++dst;
+  }
+
+  if ((or_acc & kAsciiMask) != 0) return false;
+
+  DCHECK(CheckFastAsciiConvert(saved_dst, saved_src, length, changed,
+                               Converter::kIsToLower));
+
+  *changed_out = changed;
+  return true;
+}
+
+
+template <class Converter>
+MUST_USE_RESULT static Object* ConvertCase(
+    Handle<String> s, Isolate* isolate,
+    unibrow::Mapping<Converter, 128>* mapping) {
+  s = String::Flatten(s);
+  int length = s->length();
+  // Assume that the string is not empty; we need this assumption later
+  if (length == 0) return *s;
+
+  // Simpler handling of ASCII strings.
+  //
+  // NOTE: This assumes that the upper/lower case of an ASCII
+  // character is also ASCII.  This is currently the case, but it
+  // might break in the future if we implement more context and locale
+  // dependent upper/lower conversions.
+  if (s->IsOneByteRepresentationUnderneath()) {
+    // Same length as input.
+    Handle<SeqOneByteString> result =
+        isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
+    DisallowHeapAllocation no_gc;
+    String::FlatContent flat_content = s->GetFlatContent();
+    DCHECK(flat_content.IsFlat());
+    bool has_changed_character = false;
+    bool is_ascii = FastAsciiConvert<Converter>(
+        reinterpret_cast<char*>(result->GetChars()),
+        reinterpret_cast<const char*>(flat_content.ToOneByteVector().start()),
+        length, &has_changed_character);
+    // If not ASCII, we discard the result and take the 2 byte path.
+    if (is_ascii) return has_changed_character ? *result : *s;
+  }
+
+  Handle<SeqString> result;  // Same length as input.
+  if (s->IsOneByteRepresentation()) {
+    result = isolate->factory()->NewRawOneByteString(length).ToHandleChecked();
+  } else {
+    result = isolate->factory()->NewRawTwoByteString(length).ToHandleChecked();
+  }
+
+  Object* answer = ConvertCaseHelper(isolate, *s, *result, length, mapping);
+  if (answer->IsException() || answer->IsString()) return answer;
+
+  DCHECK(answer->IsSmi());
+  length = Smi::cast(answer)->value();
+  if (s->IsOneByteRepresentation() && length > 0) {
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, result, isolate->factory()->NewRawOneByteString(length));
+  } else {
+    if (length < 0) length = -length;
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, result, isolate->factory()->NewRawTwoByteString(length));
+  }
+  return ConvertCaseHelper(isolate, *s, *result, length, mapping);
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringToLowerCase) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
+  return ConvertCase(s, isolate, isolate->runtime_state()->to_lower_mapping());
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringToUpperCase) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, s, 0);
+  return ConvertCase(s, isolate, isolate->runtime_state()->to_upper_mapping());
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringTrim) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, string, 0);
+  CONVERT_BOOLEAN_ARG_CHECKED(trimLeft, 1);
+  CONVERT_BOOLEAN_ARG_CHECKED(trimRight, 2);
+
+  string = String::Flatten(string);
+  int length = string->length();
+
+  int left = 0;
+  UnicodeCache* unicode_cache = isolate->unicode_cache();
+  if (trimLeft) {
+    while (left < length &&
+           unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(left))) {
+      left++;
+    }
+  }
+
+  int right = length;
+  if (trimRight) {
+    while (
+        right > left &&
+        unicode_cache->IsWhiteSpaceOrLineTerminator(string->Get(right - 1))) {
+      right--;
+    }
+  }
+
+  return *isolate->factory()->NewSubString(string, left, right);
+}
+
+
+RUNTIME_FUNCTION(Runtime_TruncateString) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(SeqString, string, 0);
+  CONVERT_INT32_ARG_CHECKED(new_length, 1);
+  RUNTIME_ASSERT(new_length >= 0);
+  return *SeqString::Truncate(string, new_length);
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewString) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_INT32_ARG_CHECKED(length, 0);
+  CONVERT_BOOLEAN_ARG_CHECKED(is_one_byte, 1);
+  if (length == 0) return isolate->heap()->empty_string();
+  Handle<String> result;
+  if (is_one_byte) {
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, result, isolate->factory()->NewRawOneByteString(length));
+  } else {
+    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+        isolate, result, isolate->factory()->NewRawTwoByteString(length));
+  }
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_StringEquals) {
+  HandleScope handle_scope(isolate);
+  DCHECK(args.length() == 2);
+
+  CONVERT_ARG_HANDLE_CHECKED(String, x, 0);
+  CONVERT_ARG_HANDLE_CHECKED(String, y, 1);
+
+  bool not_equal = !String::Equals(x, y);
+  // This is slightly convoluted because the value that signifies
+  // equality is 0 and inequality is 1 so we have to negate the result
+  // from String::Equals.
+  DCHECK(not_equal == 0 || not_equal == 1);
+  STATIC_ASSERT(EQUAL == 0);
+  STATIC_ASSERT(NOT_EQUAL == 1);
+  return Smi::FromInt(not_equal);
+}
+
+
+RUNTIME_FUNCTION(Runtime_FlattenString) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
+  return *String::Flatten(str);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_StringCharFromCode) {
+  SealHandleScope shs(isolate);
+  return __RT_impl_Runtime_CharFromCode(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_StringCharAt) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  if (!args[0]->IsString()) return Smi::FromInt(0);
+  if (!args[1]->IsNumber()) return Smi::FromInt(0);
+  if (std::isinf(args.number_at(1))) return isolate->heap()->empty_string();
+  Object* code = __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
+  if (code->IsNaN()) return isolate->heap()->empty_string();
+  return __RT_impl_Runtime_CharFromCode(Arguments(1, &code), isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_OneByteSeqStringSetChar) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_INT32_ARG_CHECKED(index, 0);
+  CONVERT_INT32_ARG_CHECKED(value, 1);
+  CONVERT_ARG_CHECKED(SeqOneByteString, string, 2);
+  string->SeqOneByteStringSet(index, value);
+  return string;
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_TwoByteSeqStringSetChar) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_INT32_ARG_CHECKED(index, 0);
+  CONVERT_INT32_ARG_CHECKED(value, 1);
+  CONVERT_ARG_CHECKED(SeqTwoByteString, string, 2);
+  string->SeqTwoByteStringSet(index, value);
+  return string;
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_StringCompare) {
+  SealHandleScope shs(isolate);
+  return __RT_impl_Runtime_StringCompare(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_StringCharCodeAt) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  if (!args[0]->IsString()) return isolate->heap()->undefined_value();
+  if (!args[1]->IsNumber()) return isolate->heap()->undefined_value();
+  if (std::isinf(args.number_at(1))) return isolate->heap()->nan_value();
+  return __RT_impl_Runtime_StringCharCodeAtRT(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_SubString) {
+  SealHandleScope shs(isolate);
+  return __RT_impl_Runtime_SubString(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_StringAdd) {
+  SealHandleScope shs(isolate);
+  return __RT_impl_Runtime_StringAdd(args, isolate);
+}
+
+
+RUNTIME_FUNCTION(RuntimeReference_IsStringWrapperSafeForDefaultValueOf) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-symbol.cc b/src/runtime/runtime-symbol.cc
new file mode 100644
index 0000000..31b6bed
--- /dev/null
+++ b/src/runtime/runtime-symbol.cc
@@ -0,0 +1,100 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_CreateSymbol) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
+  RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
+  Handle<Symbol> symbol = isolate->factory()->NewSymbol();
+  if (name->IsString()) symbol->set_name(*name);
+  return *symbol;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreatePrivateSymbol) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
+  RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
+  Handle<Symbol> symbol = isolate->factory()->NewPrivateSymbol();
+  if (name->IsString()) symbol->set_name(*name);
+  return *symbol;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreatePrivateOwnSymbol) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, name, 0);
+  RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
+  Handle<Symbol> symbol = isolate->factory()->NewPrivateOwnSymbol();
+  if (name->IsString()) symbol->set_name(*name);
+  return *symbol;
+}
+
+
+RUNTIME_FUNCTION(Runtime_CreateGlobalPrivateOwnSymbol) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
+  Handle<JSObject> registry = isolate->GetSymbolRegistry();
+  Handle<String> part = isolate->factory()->private_intern_string();
+  Handle<Object> privates;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, privates, Object::GetPropertyOrElement(registry, part));
+  Handle<Object> symbol;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, symbol, Object::GetPropertyOrElement(privates, name));
+  if (!symbol->IsSymbol()) {
+    DCHECK(symbol->IsUndefined());
+    symbol = isolate->factory()->NewPrivateSymbol();
+    Handle<Symbol>::cast(symbol)->set_name(*name);
+    Handle<Symbol>::cast(symbol)->set_is_own(true);
+    JSObject::SetProperty(Handle<JSObject>::cast(privates), name, symbol,
+                          STRICT).Assert();
+  }
+  return *symbol;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NewSymbolWrapper) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(Symbol, symbol, 0);
+  return *Object::ToObject(isolate, symbol).ToHandleChecked();
+}
+
+
+RUNTIME_FUNCTION(Runtime_SymbolDescription) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Symbol, symbol, 0);
+  return symbol->name();
+}
+
+
+RUNTIME_FUNCTION(Runtime_SymbolRegistry) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  return *isolate->GetSymbolRegistry();
+}
+
+
+RUNTIME_FUNCTION(Runtime_SymbolIsPrivate) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Symbol, symbol, 0);
+  return isolate->heap()->ToBoolean(symbol->is_private());
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-test.cc b/src/runtime/runtime-test.cc
new file mode 100644
index 0000000..b4b90e2
--- /dev/null
+++ b/src/runtime/runtime-test.cc
@@ -0,0 +1,418 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/deoptimizer.h"
+#include "src/full-codegen.h"
+#include "src/natives.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  if (!function->IsOptimized()) return isolate->heap()->undefined_value();
+
+  // TODO(turbofan): Deoptimization is not supported yet.
+  if (function->code()->is_turbofanned() && !FLAG_turbo_deoptimization) {
+    return isolate->heap()->undefined_value();
+  }
+
+  Deoptimizer::DeoptimizeFunction(*function);
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_RunningInSimulator) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+#if defined(USE_SIMULATOR)
+  return isolate->heap()->true_value();
+#else
+  return isolate->heap()->false_value();
+#endif
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsConcurrentRecompilationSupported) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  return isolate->heap()->ToBoolean(
+      isolate->concurrent_recompilation_enabled());
+}
+
+
+RUNTIME_FUNCTION(Runtime_OptimizeFunctionOnNextCall) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  // The following two assertions are lifted from the DCHECKs inside
+  // JSFunction::MarkForOptimization().
+  RUNTIME_ASSERT(!function->shared()->is_generator());
+  RUNTIME_ASSERT(function->shared()->allows_lazy_compilation() ||
+                 (function->code()->kind() == Code::FUNCTION &&
+                  function->code()->optimizable()));
+
+  if (!isolate->use_crankshaft()) return isolate->heap()->undefined_value();
+
+  // If the function is already optimized, just return.
+  if (function->IsOptimized()) return isolate->heap()->undefined_value();
+
+  // If the function cannot optimized, just return.
+  if (function->shared()->optimization_disabled()) {
+    return isolate->heap()->undefined_value();
+  }
+
+  function->MarkForOptimization();
+
+  Code* unoptimized = function->shared()->code();
+  if (args.length() == 2 && unoptimized->kind() == Code::FUNCTION) {
+    CONVERT_ARG_HANDLE_CHECKED(String, type, 1);
+    if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("osr")) && FLAG_use_osr) {
+      // Start patching from the currently patched loop nesting level.
+      DCHECK(BackEdgeTable::Verify(isolate, unoptimized));
+      isolate->runtime_profiler()->AttemptOnStackReplacement(
+          *function, Code::kMaxLoopNestingMarker);
+    } else if (type->IsOneByteEqualTo(STATIC_CHAR_VECTOR("concurrent")) &&
+               isolate->concurrent_recompilation_enabled()) {
+      function->AttemptConcurrentOptimization();
+    }
+  }
+
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_NeverOptimizeFunction) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSFunction, function, 0);
+  function->shared()->set_disable_optimization_reason(kOptimizationDisabled);
+  function->shared()->set_optimization_disabled(true);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
+  HandleScope scope(isolate);
+  RUNTIME_ASSERT(args.length() == 1 || args.length() == 2);
+  if (!isolate->use_crankshaft()) {
+    return Smi::FromInt(4);  // 4 == "never".
+  }
+  bool sync_with_compiler_thread = true;
+  if (args.length() == 2) {
+    CONVERT_ARG_HANDLE_CHECKED(String, sync, 1);
+    if (sync->IsOneByteEqualTo(STATIC_CHAR_VECTOR("no sync"))) {
+      sync_with_compiler_thread = false;
+    }
+  }
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  if (isolate->concurrent_recompilation_enabled() &&
+      sync_with_compiler_thread) {
+    while (function->IsInOptimizationQueue()) {
+      isolate->optimizing_compiler_thread()->InstallOptimizedFunctions();
+      base::OS::Sleep(50);
+    }
+  }
+  if (FLAG_always_opt) {
+    // We may have always opt, but that is more best-effort than a real
+    // promise, so we still say "no" if it is not optimized.
+    return function->IsOptimized() ? Smi::FromInt(3)   // 3 == "always".
+                                   : Smi::FromInt(2);  // 2 == "no".
+  }
+  if (FLAG_deopt_every_n_times) {
+    return Smi::FromInt(6);  // 6 == "maybe deopted".
+  }
+  if (function->IsOptimized() && function->code()->is_turbofanned()) {
+    return Smi::FromInt(7);  // 7 == "TurboFan compiler".
+  }
+  return function->IsOptimized() ? Smi::FromInt(1)   // 1 == "yes".
+                                 : Smi::FromInt(2);  // 2 == "no".
+}
+
+
+RUNTIME_FUNCTION(Runtime_UnblockConcurrentRecompilation) {
+  DCHECK(args.length() == 0);
+  RUNTIME_ASSERT(FLAG_block_concurrent_recompilation);
+  RUNTIME_ASSERT(isolate->concurrent_recompilation_enabled());
+  isolate->optimizing_compiler_thread()->Unblock();
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetOptimizationCount) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  return Smi::FromInt(function->shared()->opt_count());
+}
+
+
+RUNTIME_FUNCTION(Runtime_ClearFunctionTypeFeedback) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
+  function->shared()->ClearTypeFeedbackInfo();
+  Code* unoptimized = function->shared()->code();
+  if (unoptimized->kind() == Code::FUNCTION) {
+    unoptimized->ClearInlineCaches();
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  isolate->heap()->NotifyContextDisposed(true);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetAllocationTimeout) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2 || args.length() == 3);
+#ifdef DEBUG
+  CONVERT_SMI_ARG_CHECKED(interval, 0);
+  CONVERT_SMI_ARG_CHECKED(timeout, 1);
+  isolate->heap()->set_allocation_timeout(timeout);
+  FLAG_gc_interval = interval;
+  if (args.length() == 3) {
+    // Enable/disable inline allocation if requested.
+    CONVERT_BOOLEAN_ARG_CHECKED(inline_allocation, 2);
+    if (inline_allocation) {
+      isolate->heap()->EnableInlineAllocation();
+    } else {
+      isolate->heap()->DisableInlineAllocation();
+    }
+  }
+#endif
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugPrint) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  OFStream os(stdout);
+#ifdef DEBUG
+  if (args[0]->IsString()) {
+    // If we have a string, assume it's a code "marker"
+    // and print some interesting cpu debugging info.
+    JavaScriptFrameIterator it(isolate);
+    JavaScriptFrame* frame = it.frame();
+    os << "fp = " << frame->fp() << ", sp = " << frame->sp()
+       << ", caller_sp = " << frame->caller_sp() << ": ";
+  } else {
+    os << "DebugPrint: ";
+  }
+  args[0]->Print(os);
+  if (args[0]->IsHeapObject()) {
+    os << "\n";
+    HeapObject::cast(args[0])->map()->Print(os);
+  }
+#else
+  // ShortPrint is available in release mode. Print is not.
+  os << Brief(args[0]);
+#endif
+  os << std::endl;
+
+  return args[0];  // return TOS
+}
+
+
+RUNTIME_FUNCTION(Runtime_DebugTrace) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  isolate->PrintStack(stdout);
+  return isolate->heap()->undefined_value();
+}
+
+
+// This will not allocate (flatten the string), but it may run
+// very slowly for very deeply nested ConsStrings.  For debugging use only.
+RUNTIME_FUNCTION(Runtime_GlobalPrint) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+
+  CONVERT_ARG_CHECKED(String, string, 0);
+  StringCharacterStream stream(string);
+  while (stream.HasMore()) {
+    uint16_t character = stream.GetNext();
+    PrintF("%c", character);
+  }
+  return string;
+}
+
+
+RUNTIME_FUNCTION(Runtime_SystemBreak) {
+  // The code below doesn't create handles, but when breaking here in GDB
+  // having a handle scope might be useful.
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+  base::OS::DebugBreak();
+  return isolate->heap()->undefined_value();
+}
+
+
+// Sets a v8 flag.
+RUNTIME_FUNCTION(Runtime_SetFlags) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(String, arg, 0);
+  SmartArrayPointer<char> flags =
+      arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+  FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_Abort) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_SMI_ARG_CHECKED(message_id, 0);
+  const char* message =
+      GetBailoutReason(static_cast<BailoutReason>(message_id));
+  base::OS::PrintError("abort: %s\n", message);
+  isolate->PrintStack(stderr);
+  base::OS::Abort();
+  UNREACHABLE();
+  return NULL;
+}
+
+
+RUNTIME_FUNCTION(Runtime_AbortJS) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
+  base::OS::PrintError("abort: %s\n", message->ToCString().get());
+  isolate->PrintStack(stderr);
+  base::OS::Abort();
+  UNREACHABLE();
+  return NULL;
+}
+
+
+RUNTIME_FUNCTION(Runtime_NativeScriptsCount) {
+  DCHECK(args.length() == 0);
+  return Smi::FromInt(Natives::GetBuiltinsCount());
+}
+
+
+// Returns V8 version as a string.
+RUNTIME_FUNCTION(Runtime_GetV8Version) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 0);
+
+  const char* version_string = v8::V8::GetVersion();
+
+  return *isolate->factory()->NewStringFromAsciiChecked(version_string);
+}
+
+
+static int StackSize(Isolate* isolate) {
+  int n = 0;
+  for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) n++;
+  return n;
+}
+
+
+static void PrintTransition(Isolate* isolate, Object* result) {
+  // indentation
+  {
+    const int nmax = 80;
+    int n = StackSize(isolate);
+    if (n <= nmax)
+      PrintF("%4d:%*s", n, n, "");
+    else
+      PrintF("%4d:%*s", n, nmax, "...");
+  }
+
+  if (result == NULL) {
+    JavaScriptFrame::PrintTop(isolate, stdout, true, false);
+    PrintF(" {\n");
+  } else {
+    // function result
+    PrintF("} -> ");
+    result->ShortPrint();
+    PrintF("\n");
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_TraceEnter) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 0);
+  PrintTransition(isolate, NULL);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_TraceExit) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, obj, 0);
+  PrintTransition(isolate, obj);
+  return obj;  // return TOS
+}
+
+
+RUNTIME_FUNCTION(Runtime_HaveSameMap) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_CHECKED(JSObject, obj1, 0);
+  CONVERT_ARG_CHECKED(JSObject, obj2, 1);
+  return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
+}
+
+
+#define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name)       \
+  RUNTIME_FUNCTION(Runtime_Has##Name) {                  \
+    CONVERT_ARG_CHECKED(JSObject, obj, 0);               \
+    return isolate->heap()->ToBoolean(obj->Has##Name()); \
+  }
+
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(SloppyArgumentsElements)
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
+// Properties test sitting with elements tests - not fooling anyone.
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastProperties)
+
+#undef ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION
+
+
+#define TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, size) \
+  RUNTIME_FUNCTION(Runtime_HasExternal##Type##Elements) {                  \
+    CONVERT_ARG_CHECKED(JSObject, obj, 0);                                 \
+    return isolate->heap()->ToBoolean(obj->HasExternal##Type##Elements()); \
+  }
+
+TYPED_ARRAYS(TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
+
+#undef TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
+
+
+#define FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION(Type, type, TYPE, ctype, s) \
+  RUNTIME_FUNCTION(Runtime_HasFixed##Type##Elements) {                        \
+    CONVERT_ARG_CHECKED(JSObject, obj, 0);                                    \
+    return isolate->heap()->ToBoolean(obj->HasFixed##Type##Elements());       \
+  }
+
+TYPED_ARRAYS(FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION)
+
+#undef FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-typedarray.cc b/src/runtime/runtime-typedarray.cc
new file mode 100644
index 0000000..cd2c0eb
--- /dev/null
+++ b/src/runtime/runtime-typedarray.cc
@@ -0,0 +1,768 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+
+
+namespace v8 {
+namespace internal {
+
+void Runtime::FreeArrayBuffer(Isolate* isolate,
+                              JSArrayBuffer* phantom_array_buffer) {
+  if (phantom_array_buffer->should_be_freed()) {
+    DCHECK(phantom_array_buffer->is_external());
+    free(phantom_array_buffer->backing_store());
+  }
+  if (phantom_array_buffer->is_external()) return;
+
+  size_t allocated_length =
+      NumberToSize(isolate, phantom_array_buffer->byte_length());
+
+  reinterpret_cast<v8::Isolate*>(isolate)
+      ->AdjustAmountOfExternalAllocatedMemory(
+          -static_cast<int64_t>(allocated_length));
+  CHECK(V8::ArrayBufferAllocator() != NULL);
+  V8::ArrayBufferAllocator()->Free(phantom_array_buffer->backing_store(),
+                                   allocated_length);
+}
+
+
+void Runtime::SetupArrayBuffer(Isolate* isolate,
+                               Handle<JSArrayBuffer> array_buffer,
+                               bool is_external, void* data,
+                               size_t allocated_length) {
+  DCHECK(array_buffer->GetInternalFieldCount() ==
+         v8::ArrayBuffer::kInternalFieldCount);
+  for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
+    array_buffer->SetInternalField(i, Smi::FromInt(0));
+  }
+  array_buffer->set_backing_store(data);
+  array_buffer->set_flag(Smi::FromInt(0));
+  array_buffer->set_is_external(is_external);
+  array_buffer->set_is_neuterable(true);
+
+  Handle<Object> byte_length =
+      isolate->factory()->NewNumberFromSize(allocated_length);
+  CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber());
+  array_buffer->set_byte_length(*byte_length);
+
+  array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
+  isolate->heap()->set_array_buffers_list(*array_buffer);
+  array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
+}
+
+
+bool Runtime::SetupArrayBufferAllocatingData(Isolate* isolate,
+                                             Handle<JSArrayBuffer> array_buffer,
+                                             size_t allocated_length,
+                                             bool initialize) {
+  void* data;
+  CHECK(V8::ArrayBufferAllocator() != NULL);
+  if (allocated_length != 0) {
+    if (initialize) {
+      data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
+    } else {
+      data =
+          V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
+    }
+    if (data == NULL) return false;
+  } else {
+    data = NULL;
+  }
+
+  SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
+
+  reinterpret_cast<v8::Isolate*>(isolate)
+      ->AdjustAmountOfExternalAllocatedMemory(allocated_length);
+
+  return true;
+}
+
+
+void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
+  Isolate* isolate = array_buffer->GetIsolate();
+  for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate);
+       !view_obj->IsUndefined();) {
+    Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj));
+    if (view->IsJSTypedArray()) {
+      JSTypedArray::cast(*view)->Neuter();
+    } else if (view->IsJSDataView()) {
+      JSDataView::cast(*view)->Neuter();
+    } else {
+      UNREACHABLE();
+    }
+    view_obj = handle(view->weak_next(), isolate);
+  }
+  array_buffer->Neuter();
+}
+
+
+RUNTIME_FUNCTION(Runtime_ArrayBufferInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 2);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byteLength, 1);
+  if (!holder->byte_length()->IsUndefined()) {
+    // ArrayBuffer is already initialized; probably a fuzz test.
+    return *holder;
+  }
+  size_t allocated_length = 0;
+  if (!TryNumberToSize(isolate, *byteLength, &allocated_length)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_array_buffer_length",
+                               HandleVector<Object>(NULL, 0)));
+  }
+  if (!Runtime::SetupArrayBufferAllocatingData(isolate, holder,
+                                               allocated_length)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_array_buffer_length",
+                               HandleVector<Object>(NULL, 0)));
+  }
+  return *holder;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ArrayBufferGetByteLength) {
+  SealHandleScope shs(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
+  return holder->byte_length();
+}
+
+
+RUNTIME_FUNCTION(Runtime_ArrayBufferSliceImpl) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(first, 2);
+  RUNTIME_ASSERT(!source.is_identical_to(target));
+  size_t start = 0;
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *first, &start));
+  size_t target_length = NumberToSize(isolate, target->byte_length());
+
+  if (target_length == 0) return isolate->heap()->undefined_value();
+
+  size_t source_byte_length = NumberToSize(isolate, source->byte_length());
+  RUNTIME_ASSERT(start <= source_byte_length);
+  RUNTIME_ASSERT(source_byte_length - start >= target_length);
+  uint8_t* source_data = reinterpret_cast<uint8_t*>(source->backing_store());
+  uint8_t* target_data = reinterpret_cast<uint8_t*>(target->backing_store());
+  CopyBytes(target_data, source_data + start, target_length);
+  return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_ArrayBufferIsView) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_CHECKED(Object, object, 0);
+  return isolate->heap()->ToBoolean(object->IsJSArrayBufferView());
+}
+
+
+RUNTIME_FUNCTION(Runtime_ArrayBufferNeuter) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0);
+  if (array_buffer->backing_store() == NULL) {
+    CHECK(Smi::FromInt(0) == array_buffer->byte_length());
+    return isolate->heap()->undefined_value();
+  }
+  DCHECK(!array_buffer->is_external());
+  void* backing_store = array_buffer->backing_store();
+  size_t byte_length = NumberToSize(isolate, array_buffer->byte_length());
+  array_buffer->set_is_external(true);
+  Runtime::NeuterArrayBuffer(array_buffer);
+  V8::ArrayBufferAllocator()->Free(backing_store, byte_length);
+  return isolate->heap()->undefined_value();
+}
+
+
+void Runtime::ArrayIdToTypeAndSize(int arrayId, ExternalArrayType* array_type,
+                                   ElementsKind* external_elements_kind,
+                                   ElementsKind* fixed_elements_kind,
+                                   size_t* element_size) {
+  switch (arrayId) {
+#define ARRAY_ID_CASE(Type, type, TYPE, ctype, size)      \
+  case ARRAY_ID_##TYPE:                                   \
+    *array_type = kExternal##Type##Array;                 \
+    *external_elements_kind = EXTERNAL_##TYPE##_ELEMENTS; \
+    *fixed_elements_kind = TYPE##_ELEMENTS;               \
+    *element_size = size;                                 \
+    break;
+
+    TYPED_ARRAYS(ARRAY_ID_CASE)
+#undef ARRAY_ID_CASE
+
+    default:
+      UNREACHABLE();
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 5);
+  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
+  CONVERT_SMI_ARG_CHECKED(arrayId, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, maybe_buffer, 2);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset_object, 3);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length_object, 4);
+
+  RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
+                 arrayId <= Runtime::ARRAY_ID_LAST);
+
+  ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
+  size_t element_size = 1;                            // Bogus initialization.
+  ElementsKind external_elements_kind =
+      EXTERNAL_INT8_ELEMENTS;                        // Bogus initialization.
+  ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
+  Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &external_elements_kind,
+                                &fixed_elements_kind, &element_size);
+  RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
+
+  size_t byte_offset = 0;
+  size_t byte_length = 0;
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset_object, &byte_offset));
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length_object, &byte_length));
+
+  if (maybe_buffer->IsJSArrayBuffer()) {
+    Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
+    size_t array_buffer_byte_length =
+        NumberToSize(isolate, buffer->byte_length());
+    RUNTIME_ASSERT(byte_offset <= array_buffer_byte_length);
+    RUNTIME_ASSERT(array_buffer_byte_length - byte_offset >= byte_length);
+  } else {
+    RUNTIME_ASSERT(maybe_buffer->IsNull());
+  }
+
+  RUNTIME_ASSERT(byte_length % element_size == 0);
+  size_t length = byte_length / element_size;
+
+  if (length > static_cast<unsigned>(Smi::kMaxValue)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_typed_array_length",
+                               HandleVector<Object>(NULL, 0)));
+  }
+
+  // All checks are done, now we can modify objects.
+
+  DCHECK(holder->GetInternalFieldCount() ==
+         v8::ArrayBufferView::kInternalFieldCount);
+  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
+    holder->SetInternalField(i, Smi::FromInt(0));
+  }
+  Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
+  holder->set_length(*length_obj);
+  holder->set_byte_offset(*byte_offset_object);
+  holder->set_byte_length(*byte_length_object);
+
+  if (!maybe_buffer->IsNull()) {
+    Handle<JSArrayBuffer> buffer = Handle<JSArrayBuffer>::cast(maybe_buffer);
+    holder->set_buffer(*buffer);
+    holder->set_weak_next(buffer->weak_first_view());
+    buffer->set_weak_first_view(*holder);
+
+    Handle<ExternalArray> elements = isolate->factory()->NewExternalArray(
+        static_cast<int>(length), array_type,
+        static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
+    Handle<Map> map =
+        JSObject::GetElementsTransitionMap(holder, external_elements_kind);
+    JSObject::SetMapAndElements(holder, map, elements);
+    DCHECK(IsExternalArrayElementsKind(holder->map()->elements_kind()));
+  } else {
+    holder->set_buffer(Smi::FromInt(0));
+    holder->set_weak_next(isolate->heap()->undefined_value());
+    Handle<FixedTypedArrayBase> elements =
+        isolate->factory()->NewFixedTypedArray(static_cast<int>(length),
+                                               array_type);
+    holder->set_elements(*elements);
+  }
+  return isolate->heap()->undefined_value();
+}
+
+
+// Initializes a typed array from an array-like object.
+// If an array-like object happens to be a typed array of the same type,
+// initializes backing store using memove.
+//
+// Returns true if backing store was initialized or false otherwise.
+RUNTIME_FUNCTION(Runtime_TypedArrayInitializeFromArrayLike) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
+  CONVERT_SMI_ARG_CHECKED(arrayId, 1);
+  CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(length_obj, 3);
+
+  RUNTIME_ASSERT(arrayId >= Runtime::ARRAY_ID_FIRST &&
+                 arrayId <= Runtime::ARRAY_ID_LAST);
+
+  ExternalArrayType array_type = kExternalInt8Array;  // Bogus initialization.
+  size_t element_size = 1;                            // Bogus initialization.
+  ElementsKind external_elements_kind =
+      EXTERNAL_INT8_ELEMENTS;                        // Bogus intialization.
+  ElementsKind fixed_elements_kind = INT8_ELEMENTS;  // Bogus initialization.
+  Runtime::ArrayIdToTypeAndSize(arrayId, &array_type, &external_elements_kind,
+                                &fixed_elements_kind, &element_size);
+
+  RUNTIME_ASSERT(holder->map()->elements_kind() == fixed_elements_kind);
+
+  Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
+  if (source->IsJSTypedArray() &&
+      JSTypedArray::cast(*source)->type() == array_type) {
+    length_obj = Handle<Object>(JSTypedArray::cast(*source)->length(), isolate);
+  }
+  size_t length = 0;
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *length_obj, &length));
+
+  if ((length > static_cast<unsigned>(Smi::kMaxValue)) ||
+      (length > (kMaxInt / element_size))) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_typed_array_length",
+                               HandleVector<Object>(NULL, 0)));
+  }
+  size_t byte_length = length * element_size;
+
+  DCHECK(holder->GetInternalFieldCount() ==
+         v8::ArrayBufferView::kInternalFieldCount);
+  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
+    holder->SetInternalField(i, Smi::FromInt(0));
+  }
+
+  // NOTE: not initializing backing store.
+  // We assume that the caller of this function will initialize holder
+  // with the loop
+  //      for(i = 0; i < length; i++) { holder[i] = source[i]; }
+  // We assume that the caller of this function is always a typed array
+  // constructor.
+  // If source is a typed array, this loop will always run to completion,
+  // so we are sure that the backing store will be initialized.
+  // Otherwise, the indexing operation might throw, so the loop will not
+  // run to completion and the typed array might remain partly initialized.
+  // However we further assume that the caller of this function is a typed array
+  // constructor, and the exception will propagate out of the constructor,
+  // therefore uninitialized memory will not be accessible by a user program.
+  //
+  // TODO(dslomov): revise this once we support subclassing.
+
+  if (!Runtime::SetupArrayBufferAllocatingData(isolate, buffer, byte_length,
+                                               false)) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("invalid_array_buffer_length",
+                               HandleVector<Object>(NULL, 0)));
+  }
+
+  holder->set_buffer(*buffer);
+  holder->set_byte_offset(Smi::FromInt(0));
+  Handle<Object> byte_length_obj(
+      isolate->factory()->NewNumberFromSize(byte_length));
+  holder->set_byte_length(*byte_length_obj);
+  holder->set_length(*length_obj);
+  holder->set_weak_next(buffer->weak_first_view());
+  buffer->set_weak_first_view(*holder);
+
+  Handle<ExternalArray> elements = isolate->factory()->NewExternalArray(
+      static_cast<int>(length), array_type,
+      static_cast<uint8_t*>(buffer->backing_store()));
+  Handle<Map> map =
+      JSObject::GetElementsTransitionMap(holder, external_elements_kind);
+  JSObject::SetMapAndElements(holder, map, elements);
+
+  if (source->IsJSTypedArray()) {
+    Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
+
+    if (typed_array->type() == holder->type()) {
+      uint8_t* backing_store =
+          static_cast<uint8_t*>(typed_array->GetBuffer()->backing_store());
+      size_t source_byte_offset =
+          NumberToSize(isolate, typed_array->byte_offset());
+      memcpy(buffer->backing_store(), backing_store + source_byte_offset,
+             byte_length);
+      return isolate->heap()->true_value();
+    }
+  }
+
+  return isolate->heap()->false_value();
+}
+
+
+#define BUFFER_VIEW_GETTER(Type, getter, accessor)   \
+  RUNTIME_FUNCTION(Runtime_##Type##Get##getter) {    \
+    HandleScope scope(isolate);                      \
+    DCHECK(args.length() == 1);                      \
+    CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \
+    return holder->accessor();                       \
+  }
+
+BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
+BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
+BUFFER_VIEW_GETTER(TypedArray, Length, length)
+BUFFER_VIEW_GETTER(DataView, Buffer, buffer)
+
+#undef BUFFER_VIEW_GETTER
+
+RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
+  return *holder->GetBuffer();
+}
+
+
+// Return codes for Runtime_TypedArraySetFastCases.
+// Should be synchronized with typedarray.js natives.
+enum TypedArraySetResultCodes {
+  // Set from typed array of the same type.
+  // This is processed by TypedArraySetFastCases
+  TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0,
+  // Set from typed array of the different type, overlapping in memory.
+  TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1,
+  // Set from typed array of the different type, non-overlapping.
+  TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2,
+  // Set from non-typed array.
+  TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3
+};
+
+
+RUNTIME_FUNCTION(Runtime_TypedArraySetFastCases) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 3);
+  if (!args[0]->IsJSTypedArray()) {
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate,
+        NewTypeError("not_typed_array", HandleVector<Object>(NULL, 0)));
+  }
+
+  if (!args[1]->IsJSTypedArray())
+    return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY);
+
+  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, target_obj, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, source_obj, 1);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset_obj, 2);
+
+  Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
+  Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
+  size_t offset = 0;
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *offset_obj, &offset));
+  size_t target_length = NumberToSize(isolate, target->length());
+  size_t source_length = NumberToSize(isolate, source->length());
+  size_t target_byte_length = NumberToSize(isolate, target->byte_length());
+  size_t source_byte_length = NumberToSize(isolate, source->byte_length());
+  if (offset > target_length || offset + source_length > target_length ||
+      offset + source_length < offset) {  // overflow
+    THROW_NEW_ERROR_RETURN_FAILURE(
+        isolate, NewRangeError("typed_array_set_source_too_large",
+                               HandleVector<Object>(NULL, 0)));
+  }
+
+  size_t target_offset = NumberToSize(isolate, target->byte_offset());
+  size_t source_offset = NumberToSize(isolate, source->byte_offset());
+  uint8_t* target_base =
+      static_cast<uint8_t*>(target->GetBuffer()->backing_store()) +
+      target_offset;
+  uint8_t* source_base =
+      static_cast<uint8_t*>(source->GetBuffer()->backing_store()) +
+      source_offset;
+
+  // Typed arrays of the same type: use memmove.
+  if (target->type() == source->type()) {
+    memmove(target_base + offset * target->element_size(), source_base,
+            source_byte_length);
+    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE);
+  }
+
+  // Typed arrays of different types over the same backing store
+  if ((source_base <= target_base &&
+       source_base + source_byte_length > target_base) ||
+      (target_base <= source_base &&
+       target_base + target_byte_length > source_base)) {
+    // We do not support overlapping ArrayBuffers
+    DCHECK(target->GetBuffer()->backing_store() ==
+           source->GetBuffer()->backing_store());
+    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING);
+  } else {  // Non-overlapping typed arrays
+    return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING);
+  }
+}
+
+
+RUNTIME_FUNCTION(Runtime_TypedArrayMaxSizeInHeap) {
+  DCHECK(args.length() == 0);
+  DCHECK_OBJECT_SIZE(FLAG_typed_array_max_size_in_heap +
+                     FixedTypedArrayBase::kDataOffset);
+  return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsTypedArray) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  return isolate->heap()->ToBoolean(args[0]->IsJSTypedArray());
+}
+
+
+RUNTIME_FUNCTION(Runtime_DataViewInitialize) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 4);
+  CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);
+  CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_offset, 2);
+  CONVERT_NUMBER_ARG_HANDLE_CHECKED(byte_length, 3);
+
+  DCHECK(holder->GetInternalFieldCount() ==
+         v8::ArrayBufferView::kInternalFieldCount);
+  for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
+    holder->SetInternalField(i, Smi::FromInt(0));
+  }
+  size_t buffer_length = 0;
+  size_t offset = 0;
+  size_t length = 0;
+  RUNTIME_ASSERT(
+      TryNumberToSize(isolate, buffer->byte_length(), &buffer_length));
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_offset, &offset));
+  RUNTIME_ASSERT(TryNumberToSize(isolate, *byte_length, &length));
+
+  // TODO(jkummerow): When we have a "safe numerics" helper class, use it here.
+  // Entire range [offset, offset + length] must be in bounds.
+  RUNTIME_ASSERT(offset <= buffer_length);
+  RUNTIME_ASSERT(offset + length <= buffer_length);
+  // No overflow.
+  RUNTIME_ASSERT(offset + length >= offset);
+
+  holder->set_buffer(*buffer);
+  holder->set_byte_offset(*byte_offset);
+  holder->set_byte_length(*byte_length);
+
+  holder->set_weak_next(buffer->weak_first_view());
+  buffer->set_weak_first_view(*holder);
+
+  return isolate->heap()->undefined_value();
+}
+
+
+inline static bool NeedToFlipBytes(bool is_little_endian) {
+#ifdef V8_TARGET_LITTLE_ENDIAN
+  return !is_little_endian;
+#else
+  return is_little_endian;
+#endif
+}
+
+
+template <int n>
+inline void CopyBytes(uint8_t* target, uint8_t* source) {
+  for (int i = 0; i < n; i++) {
+    *(target++) = *(source++);
+  }
+}
+
+
+template <int n>
+inline void FlipBytes(uint8_t* target, uint8_t* source) {
+  source = source + (n - 1);
+  for (int i = 0; i < n; i++) {
+    *(target++) = *(source--);
+  }
+}
+
+
+template <typename T>
+inline static bool DataViewGetValue(Isolate* isolate,
+                                    Handle<JSDataView> data_view,
+                                    Handle<Object> byte_offset_obj,
+                                    bool is_little_endian, T* result) {
+  size_t byte_offset = 0;
+  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
+    return false;
+  }
+  Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
+
+  size_t data_view_byte_offset =
+      NumberToSize(isolate, data_view->byte_offset());
+  size_t data_view_byte_length =
+      NumberToSize(isolate, data_view->byte_length());
+  if (byte_offset + sizeof(T) > data_view_byte_length ||
+      byte_offset + sizeof(T) < byte_offset) {  // overflow
+    return false;
+  }
+
+  union Value {
+    T data;
+    uint8_t bytes[sizeof(T)];
+  };
+
+  Value value;
+  size_t buffer_offset = data_view_byte_offset + byte_offset;
+  DCHECK(NumberToSize(isolate, buffer->byte_length()) >=
+         buffer_offset + sizeof(T));
+  uint8_t* source =
+      static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
+  if (NeedToFlipBytes(is_little_endian)) {
+    FlipBytes<sizeof(T)>(value.bytes, source);
+  } else {
+    CopyBytes<sizeof(T)>(value.bytes, source);
+  }
+  *result = value.data;
+  return true;
+}
+
+
+template <typename T>
+static bool DataViewSetValue(Isolate* isolate, Handle<JSDataView> data_view,
+                             Handle<Object> byte_offset_obj,
+                             bool is_little_endian, T data) {
+  size_t byte_offset = 0;
+  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
+    return false;
+  }
+  Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
+
+  size_t data_view_byte_offset =
+      NumberToSize(isolate, data_view->byte_offset());
+  size_t data_view_byte_length =
+      NumberToSize(isolate, data_view->byte_length());
+  if (byte_offset + sizeof(T) > data_view_byte_length ||
+      byte_offset + sizeof(T) < byte_offset) {  // overflow
+    return false;
+  }
+
+  union Value {
+    T data;
+    uint8_t bytes[sizeof(T)];
+  };
+
+  Value value;
+  value.data = data;
+  size_t buffer_offset = data_view_byte_offset + byte_offset;
+  DCHECK(NumberToSize(isolate, buffer->byte_length()) >=
+         buffer_offset + sizeof(T));
+  uint8_t* target =
+      static_cast<uint8_t*>(buffer->backing_store()) + buffer_offset;
+  if (NeedToFlipBytes(is_little_endian)) {
+    FlipBytes<sizeof(T)>(target, value.bytes);
+  } else {
+    CopyBytes<sizeof(T)>(target, value.bytes);
+  }
+  return true;
+}
+
+
+#define DATA_VIEW_GETTER(TypeName, Type, Converter)                   \
+  RUNTIME_FUNCTION(Runtime_DataViewGet##TypeName) {                   \
+    HandleScope scope(isolate);                                       \
+    DCHECK(args.length() == 3);                                       \
+    CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                \
+    CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                     \
+    CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 2);                 \
+    Type result;                                                      \
+    if (DataViewGetValue(isolate, holder, offset, is_little_endian,   \
+                         &result)) {                                  \
+      return *isolate->factory()->Converter(result);                  \
+    } else {                                                          \
+      THROW_NEW_ERROR_RETURN_FAILURE(                                 \
+          isolate, NewRangeError("invalid_data_view_accessor_offset", \
+                                 HandleVector<Object>(NULL, 0)));     \
+    }                                                                 \
+  }
+
+DATA_VIEW_GETTER(Uint8, uint8_t, NewNumberFromUint)
+DATA_VIEW_GETTER(Int8, int8_t, NewNumberFromInt)
+DATA_VIEW_GETTER(Uint16, uint16_t, NewNumberFromUint)
+DATA_VIEW_GETTER(Int16, int16_t, NewNumberFromInt)
+DATA_VIEW_GETTER(Uint32, uint32_t, NewNumberFromUint)
+DATA_VIEW_GETTER(Int32, int32_t, NewNumberFromInt)
+DATA_VIEW_GETTER(Float32, float, NewNumber)
+DATA_VIEW_GETTER(Float64, double, NewNumber)
+
+#undef DATA_VIEW_GETTER
+
+
+template <typename T>
+static T DataViewConvertValue(double value);
+
+
+template <>
+int8_t DataViewConvertValue<int8_t>(double value) {
+  return static_cast<int8_t>(DoubleToInt32(value));
+}
+
+
+template <>
+int16_t DataViewConvertValue<int16_t>(double value) {
+  return static_cast<int16_t>(DoubleToInt32(value));
+}
+
+
+template <>
+int32_t DataViewConvertValue<int32_t>(double value) {
+  return DoubleToInt32(value);
+}
+
+
+template <>
+uint8_t DataViewConvertValue<uint8_t>(double value) {
+  return static_cast<uint8_t>(DoubleToUint32(value));
+}
+
+
+template <>
+uint16_t DataViewConvertValue<uint16_t>(double value) {
+  return static_cast<uint16_t>(DoubleToUint32(value));
+}
+
+
+template <>
+uint32_t DataViewConvertValue<uint32_t>(double value) {
+  return DoubleToUint32(value);
+}
+
+
+template <>
+float DataViewConvertValue<float>(double value) {
+  return static_cast<float>(value);
+}
+
+
+template <>
+double DataViewConvertValue<double>(double value) {
+  return value;
+}
+
+
+#define DATA_VIEW_SETTER(TypeName, Type)                                  \
+  RUNTIME_FUNCTION(Runtime_DataViewSet##TypeName) {                       \
+    HandleScope scope(isolate);                                           \
+    DCHECK(args.length() == 4);                                           \
+    CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0);                    \
+    CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1);                         \
+    CONVERT_NUMBER_ARG_HANDLE_CHECKED(value, 2);                          \
+    CONVERT_BOOLEAN_ARG_CHECKED(is_little_endian, 3);                     \
+    Type v = DataViewConvertValue<Type>(value->Number());                 \
+    if (DataViewSetValue(isolate, holder, offset, is_little_endian, v)) { \
+      return isolate->heap()->undefined_value();                          \
+    } else {                                                              \
+      THROW_NEW_ERROR_RETURN_FAILURE(                                     \
+          isolate, NewRangeError("invalid_data_view_accessor_offset",     \
+                                 HandleVector<Object>(NULL, 0)));         \
+    }                                                                     \
+  }
+
+DATA_VIEW_SETTER(Uint8, uint8_t)
+DATA_VIEW_SETTER(Int8, int8_t)
+DATA_VIEW_SETTER(Uint16, uint16_t)
+DATA_VIEW_SETTER(Int16, int16_t)
+DATA_VIEW_SETTER(Uint32, uint32_t)
+DATA_VIEW_SETTER(Int32, int32_t)
+DATA_VIEW_SETTER(Float32, float)
+DATA_VIEW_SETTER(Float64, double)
+
+#undef DATA_VIEW_SETTER
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-uri.cc b/src/runtime/runtime-uri.cc
new file mode 100644
index 0000000..477071a
--- /dev/null
+++ b/src/runtime/runtime-uri.cc
@@ -0,0 +1,288 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/arguments.h"
+#include "src/conversions.h"
+#include "src/runtime/runtime-utils.h"
+#include "src/string-search.h"
+#include "src/utils.h"
+
+
+namespace v8 {
+namespace internal {
+
+class URIUnescape : public AllStatic {
+ public:
+  template <typename Char>
+  MUST_USE_RESULT static MaybeHandle<String> Unescape(Isolate* isolate,
+                                                      Handle<String> source);
+
+ private:
+  static const signed char kHexValue['g'];
+
+  template <typename Char>
+  MUST_USE_RESULT static MaybeHandle<String> UnescapeSlow(Isolate* isolate,
+                                                          Handle<String> string,
+                                                          int start_index);
+
+  static INLINE(int TwoDigitHex(uint16_t character1, uint16_t character2));
+
+  template <typename Char>
+  static INLINE(int UnescapeChar(Vector<const Char> vector, int i, int length,
+                                 int* step));
+};
+
+
+const signed char URIUnescape::kHexValue[] = {
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -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, 1,  2,  3,  4,  5,
+    6,  7,  8,  9,  -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15};
+
+
+template <typename Char>
+MaybeHandle<String> URIUnescape::Unescape(Isolate* isolate,
+                                          Handle<String> source) {
+  int index;
+  {
+    DisallowHeapAllocation no_allocation;
+    StringSearch<uint8_t, Char> search(isolate, STATIC_CHAR_VECTOR("%"));
+    index = search.Search(source->GetCharVector<Char>(), 0);
+    if (index < 0) return source;
+  }
+  return UnescapeSlow<Char>(isolate, source, index);
+}
+
+
+template <typename Char>
+MaybeHandle<String> URIUnescape::UnescapeSlow(Isolate* isolate,
+                                              Handle<String> string,
+                                              int start_index) {
+  bool one_byte = true;
+  int length = string->length();
+
+  int unescaped_length = 0;
+  {
+    DisallowHeapAllocation no_allocation;
+    Vector<const Char> vector = string->GetCharVector<Char>();
+    for (int i = start_index; i < length; unescaped_length++) {
+      int step;
+      if (UnescapeChar(vector, i, length, &step) >
+          String::kMaxOneByteCharCode) {
+        one_byte = false;
+      }
+      i += step;
+    }
+  }
+
+  DCHECK(start_index < length);
+  Handle<String> first_part =
+      isolate->factory()->NewProperSubString(string, 0, start_index);
+
+  int dest_position = 0;
+  Handle<String> second_part;
+  DCHECK(unescaped_length <= String::kMaxLength);
+  if (one_byte) {
+    Handle<SeqOneByteString> dest = isolate->factory()
+                                        ->NewRawOneByteString(unescaped_length)
+                                        .ToHandleChecked();
+    DisallowHeapAllocation no_allocation;
+    Vector<const Char> vector = string->GetCharVector<Char>();
+    for (int i = start_index; i < length; dest_position++) {
+      int step;
+      dest->SeqOneByteStringSet(dest_position,
+                                UnescapeChar(vector, i, length, &step));
+      i += step;
+    }
+    second_part = dest;
+  } else {
+    Handle<SeqTwoByteString> dest = isolate->factory()
+                                        ->NewRawTwoByteString(unescaped_length)
+                                        .ToHandleChecked();
+    DisallowHeapAllocation no_allocation;
+    Vector<const Char> vector = string->GetCharVector<Char>();
+    for (int i = start_index; i < length; dest_position++) {
+      int step;
+      dest->SeqTwoByteStringSet(dest_position,
+                                UnescapeChar(vector, i, length, &step));
+      i += step;
+    }
+    second_part = dest;
+  }
+  return isolate->factory()->NewConsString(first_part, second_part);
+}
+
+
+int URIUnescape::TwoDigitHex(uint16_t character1, uint16_t character2) {
+  if (character1 > 'f') return -1;
+  int hi = kHexValue[character1];
+  if (hi == -1) return -1;
+  if (character2 > 'f') return -1;
+  int lo = kHexValue[character2];
+  if (lo == -1) return -1;
+  return (hi << 4) + lo;
+}
+
+
+template <typename Char>
+int URIUnescape::UnescapeChar(Vector<const Char> vector, int i, int length,
+                              int* step) {
+  uint16_t character = vector[i];
+  int32_t hi = 0;
+  int32_t lo = 0;
+  if (character == '%' && i <= length - 6 && vector[i + 1] == 'u' &&
+      (hi = TwoDigitHex(vector[i + 2], vector[i + 3])) != -1 &&
+      (lo = TwoDigitHex(vector[i + 4], vector[i + 5])) != -1) {
+    *step = 6;
+    return (hi << 8) + lo;
+  } else if (character == '%' && i <= length - 3 &&
+             (lo = TwoDigitHex(vector[i + 1], vector[i + 2])) != -1) {
+    *step = 3;
+    return lo;
+  } else {
+    *step = 1;
+    return character;
+  }
+}
+
+
+class URIEscape : public AllStatic {
+ public:
+  template <typename Char>
+  MUST_USE_RESULT static MaybeHandle<String> Escape(Isolate* isolate,
+                                                    Handle<String> string);
+
+ private:
+  static const char kHexChars[17];
+  static const char kNotEscaped[256];
+
+  static bool IsNotEscaped(uint16_t c) { return kNotEscaped[c] != 0; }
+};
+
+
+const char URIEscape::kHexChars[] = "0123456789ABCDEF";
+
+
+// kNotEscaped is generated by the following:
+//
+// #!/bin/perl
+// for (my $i = 0; $i < 256; $i++) {
+//   print "\n" if $i % 16 == 0;
+//   my $c = chr($i);
+//   my $escaped = 1;
+//   $escaped = 0 if $c =~ m#[A-Za-z0-9@*_+./-]#;
+//   print $escaped ? "0, " : "1, ";
+// }
+
+const char URIEscape::kNotEscaped[] = {
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 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, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+
+template <typename Char>
+MaybeHandle<String> URIEscape::Escape(Isolate* isolate, Handle<String> string) {
+  DCHECK(string->IsFlat());
+  int escaped_length = 0;
+  int length = string->length();
+
+  {
+    DisallowHeapAllocation no_allocation;
+    Vector<const Char> vector = string->GetCharVector<Char>();
+    for (int i = 0; i < length; i++) {
+      uint16_t c = vector[i];
+      if (c >= 256) {
+        escaped_length += 6;
+      } else if (IsNotEscaped(c)) {
+        escaped_length++;
+      } else {
+        escaped_length += 3;
+      }
+
+      // We don't allow strings that are longer than a maximal length.
+      DCHECK(String::kMaxLength < 0x7fffffff - 6);     // Cannot overflow.
+      if (escaped_length > String::kMaxLength) break;  // Provoke exception.
+    }
+  }
+
+  // No length change implies no change.  Return original string if no change.
+  if (escaped_length == length) return string;
+
+  Handle<SeqOneByteString> dest;
+  ASSIGN_RETURN_ON_EXCEPTION(
+      isolate, dest, isolate->factory()->NewRawOneByteString(escaped_length),
+      String);
+  int dest_position = 0;
+
+  {
+    DisallowHeapAllocation no_allocation;
+    Vector<const Char> vector = string->GetCharVector<Char>();
+    for (int i = 0; i < length; i++) {
+      uint16_t c = vector[i];
+      if (c >= 256) {
+        dest->SeqOneByteStringSet(dest_position, '%');
+        dest->SeqOneByteStringSet(dest_position + 1, 'u');
+        dest->SeqOneByteStringSet(dest_position + 2, kHexChars[c >> 12]);
+        dest->SeqOneByteStringSet(dest_position + 3, kHexChars[(c >> 8) & 0xf]);
+        dest->SeqOneByteStringSet(dest_position + 4, kHexChars[(c >> 4) & 0xf]);
+        dest->SeqOneByteStringSet(dest_position + 5, kHexChars[c & 0xf]);
+        dest_position += 6;
+      } else if (IsNotEscaped(c)) {
+        dest->SeqOneByteStringSet(dest_position, c);
+        dest_position++;
+      } else {
+        dest->SeqOneByteStringSet(dest_position, '%');
+        dest->SeqOneByteStringSet(dest_position + 1, kHexChars[c >> 4]);
+        dest->SeqOneByteStringSet(dest_position + 2, kHexChars[c & 0xf]);
+        dest_position += 3;
+      }
+    }
+  }
+
+  return dest;
+}
+
+
+RUNTIME_FUNCTION(Runtime_URIEscape) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
+  Handle<String> string = String::Flatten(source);
+  DCHECK(string->IsFlat());
+  Handle<String> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, string->IsOneByteRepresentationUnderneath()
+                           ? URIEscape::Escape<uint8_t>(isolate, source)
+                           : URIEscape::Escape<uc16>(isolate, source));
+  return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_URIUnescape) {
+  HandleScope scope(isolate);
+  DCHECK(args.length() == 1);
+  CONVERT_ARG_HANDLE_CHECKED(String, source, 0);
+  Handle<String> string = String::Flatten(source);
+  DCHECK(string->IsFlat());
+  Handle<String> result;
+  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+      isolate, result, string->IsOneByteRepresentationUnderneath()
+                           ? URIUnescape::Unescape<uint8_t>(isolate, source)
+                           : URIUnescape::Unescape<uc16>(isolate, source));
+  return *result;
+}
+}
+}  // namespace v8::internal
diff --git a/src/runtime/runtime-utils.h b/src/runtime/runtime-utils.h
new file mode 100644
index 0000000..95d75f5
--- /dev/null
+++ b/src/runtime/runtime-utils.h
@@ -0,0 +1,147 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_RUNTIME_RUNTIME_UTILS_H_
+#define V8_RUNTIME_RUNTIME_UTILS_H_
+
+
+namespace v8 {
+namespace internal {
+
+#define RUNTIME_ASSERT(value) \
+  if (!(value)) return isolate->ThrowIllegalOperation();
+
+#define RUNTIME_ASSERT_HANDLIFIED(value, T) \
+  if (!(value)) {                           \
+    isolate->ThrowIllegalOperation();       \
+    return MaybeHandle<T>();                \
+  }
+
+// Cast the given object to a value of the specified type and store
+// it in a variable with the given name.  If the object is not of the
+// expected type call IllegalOperation and return.
+#define CONVERT_ARG_CHECKED(Type, name, index) \
+  RUNTIME_ASSERT(args[index]->Is##Type());     \
+  Type* name = Type::cast(args[index]);
+
+#define CONVERT_ARG_HANDLE_CHECKED(Type, name, index) \
+  RUNTIME_ASSERT(args[index]->Is##Type());            \
+  Handle<Type> name = args.at<Type>(index);
+
+#define CONVERT_NUMBER_ARG_HANDLE_CHECKED(name, index) \
+  RUNTIME_ASSERT(args[index]->IsNumber());             \
+  Handle<Object> name = args.at<Object>(index);
+
+// Cast the given object to a boolean and store it in a variable with
+// the given name.  If the object is not a boolean call IllegalOperation
+// and return.
+#define CONVERT_BOOLEAN_ARG_CHECKED(name, index) \
+  RUNTIME_ASSERT(args[index]->IsBoolean());      \
+  bool name = args[index]->IsTrue();
+
+// Cast the given argument to a Smi and store its value in an int variable
+// with the given name.  If the argument is not a Smi call IllegalOperation
+// and return.
+#define CONVERT_SMI_ARG_CHECKED(name, index) \
+  RUNTIME_ASSERT(args[index]->IsSmi());      \
+  int name = args.smi_at(index);
+
+// Cast the given argument to a double and store it in a variable with
+// the given name.  If the argument is not a number (as opposed to
+// the number not-a-number) call IllegalOperation and return.
+#define CONVERT_DOUBLE_ARG_CHECKED(name, index) \
+  RUNTIME_ASSERT(args[index]->IsNumber());      \
+  double name = args.number_at(index);
+
+// Call the specified converter on the object *comand store the result in
+// a variable of the specified type with the given name.  If the
+// object is not a Number call IllegalOperation and return.
+#define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \
+  RUNTIME_ASSERT(obj->IsNumber());                    \
+  type name = NumberTo##Type(obj);
+
+
+// Cast the given argument to PropertyDetails and store its value in a
+// variable with the given name.  If the argument is not a Smi call
+// IllegalOperation and return.
+#define CONVERT_PROPERTY_DETAILS_CHECKED(name, index) \
+  RUNTIME_ASSERT(args[index]->IsSmi());               \
+  PropertyDetails name = PropertyDetails(Smi::cast(args[index]));
+
+
+// Assert that the given argument has a valid value for a StrictMode
+// and store it in a StrictMode variable with the given name.
+#define CONVERT_STRICT_MODE_ARG_CHECKED(name, index) \
+  RUNTIME_ASSERT(args[index]->IsSmi());              \
+  RUNTIME_ASSERT(args.smi_at(index) == STRICT ||     \
+                 args.smi_at(index) == SLOPPY);      \
+  StrictMode name = static_cast<StrictMode>(args.smi_at(index));
+
+
+// Assert that the given argument is a number within the Int32 range
+// and convert it to int32_t.  If the argument is not an Int32 call
+// IllegalOperation and return.
+#define CONVERT_INT32_ARG_CHECKED(name, index) \
+  RUNTIME_ASSERT(args[index]->IsNumber());     \
+  int32_t name = 0;                            \
+  RUNTIME_ASSERT(args[index]->ToInt32(&name));
+
+
+// A mechanism to return a pair of Object pointers in registers (if possible).
+// How this is achieved is calling convention-dependent.
+// All currently supported x86 compiles uses calling conventions that are cdecl
+// variants where a 64-bit value is returned in two 32-bit registers
+// (edx:eax on ia32, r1:r0 on ARM).
+// In AMD-64 calling convention a struct of two pointers is returned in rdx:rax.
+// In Win64 calling convention, a struct of two pointers is returned in memory,
+// allocated by the caller, and passed as a pointer in a hidden first parameter.
+#ifdef V8_HOST_ARCH_64_BIT
+struct ObjectPair {
+  Object* x;
+  Object* y;
+};
+
+
+static inline ObjectPair MakePair(Object* x, Object* y) {
+  ObjectPair result = {x, y};
+  // Pointers x and y returned in rax and rdx, in AMD-x64-abi.
+  // In Win64 they are assigned to a hidden first argument.
+  return result;
+}
+#elif V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
+// For x32 a 128-bit struct return is done as rax and rdx from the ObjectPair
+// are used in the full codegen and Crankshaft compiler. An alternative is
+// using uint64_t and modifying full codegen and Crankshaft compiler.
+struct ObjectPair {
+  Object* x;
+  uint32_t x_upper;
+  Object* y;
+  uint32_t y_upper;
+};
+
+
+static inline ObjectPair MakePair(Object* x, Object* y) {
+  ObjectPair result = {x, 0, y, 0};
+  // Pointers x and y returned in rax and rdx, in x32-abi.
+  return result;
+}
+#else
+typedef uint64_t ObjectPair;
+static inline ObjectPair MakePair(Object* x, Object* y) {
+#if defined(V8_TARGET_LITTLE_ENDIAN)
+  return reinterpret_cast<uint32_t>(x) |
+         (reinterpret_cast<ObjectPair>(y) << 32);
+#elif defined(V8_TARGET_BIG_ENDIAN)
+  return reinterpret_cast<uint32_t>(y) |
+         (reinterpret_cast<ObjectPair>(x) << 32);
+#else
+#error Unknown endianness
+#endif
+}
+#endif
+
+}
+}  // namespace v8::internal
+
+#endif  // V8_RUNTIME_RUNTIME_UTILS_H_
diff --git a/src/runtime/runtime.cc b/src/runtime/runtime.cc
new file mode 100644
index 0000000..459ca50
--- /dev/null
+++ b/src/runtime/runtime.cc
@@ -0,0 +1,122 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/runtime/runtime.h"
+#include "src/runtime/runtime-utils.h"
+
+namespace v8 {
+namespace internal {
+
+// Header of runtime functions.
+#define F(name, number_of_args, result_size)                    \
+  Object* Runtime_##name(int args_length, Object** args_object, \
+                         Isolate* isolate);
+
+#define P(name, number_of_args, result_size)                       \
+  ObjectPair Runtime_##name(int args_length, Object** args_object, \
+                            Isolate* isolate);
+
+// Reference implementation for inlined runtime functions.  Only used when the
+// compiler does not support a certain intrinsic.  Don't optimize these, but
+// implement the intrinsic in the respective compiler instead.
+// TODO(mstarzinger): These are place-holder stubs for TurboFan and will
+// eventually all have a C++ implementation and this macro will be gone.
+#define I(name, number_of_args, result_size)                             \
+  Object* RuntimeReference_##name(int args_length, Object** args_object, \
+                                  Isolate* isolate);
+
+RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F)
+RUNTIME_FUNCTION_LIST_RETURN_PAIR(P)
+INLINE_OPTIMIZED_FUNCTION_LIST(F)
+INLINE_FUNCTION_LIST(I)
+
+#undef I
+#undef F
+#undef P
+
+
+#define F(name, number_of_args, result_size)                                  \
+  {                                                                           \
+    Runtime::k##name, Runtime::RUNTIME, #name, FUNCTION_ADDR(Runtime_##name), \
+        number_of_args, result_size                                           \
+  }                                                                           \
+  ,
+
+
+#define I(name, number_of_args, result_size)                                \
+  {                                                                         \
+    Runtime::kInline##name, Runtime::INLINE, "_" #name,                     \
+        FUNCTION_ADDR(RuntimeReference_##name), number_of_args, result_size \
+  }                                                                         \
+  ,
+
+
+#define IO(name, number_of_args, result_size)                              \
+  {                                                                        \
+    Runtime::kInlineOptimized##name, Runtime::INLINE_OPTIMIZED, "_" #name, \
+        FUNCTION_ADDR(Runtime_##name), number_of_args, result_size         \
+  }                                                                        \
+  ,
+
+
+static const Runtime::Function kIntrinsicFunctions[] = {
+    RUNTIME_FUNCTION_LIST(F) INLINE_OPTIMIZED_FUNCTION_LIST(F)
+    INLINE_FUNCTION_LIST(I) INLINE_OPTIMIZED_FUNCTION_LIST(IO)};
+
+#undef IO
+#undef I
+#undef F
+
+
+void Runtime::InitializeIntrinsicFunctionNames(Isolate* isolate,
+                                               Handle<NameDictionary> dict) {
+  DCHECK(dict->NumberOfElements() == 0);
+  HandleScope scope(isolate);
+  for (int i = 0; i < kNumFunctions; ++i) {
+    const char* name = kIntrinsicFunctions[i].name;
+    if (name == NULL) continue;
+    Handle<NameDictionary> new_dict = NameDictionary::Add(
+        dict, isolate->factory()->InternalizeUtf8String(name),
+        Handle<Smi>(Smi::FromInt(i), isolate), PropertyDetails(NONE, FIELD, 0));
+    // The dictionary does not need to grow.
+    CHECK(new_dict.is_identical_to(dict));
+  }
+}
+
+
+const Runtime::Function* Runtime::FunctionForName(Handle<String> name) {
+  Heap* heap = name->GetHeap();
+  int entry = heap->intrinsic_function_names()->FindEntry(name);
+  if (entry != kNotFound) {
+    Object* smi_index = heap->intrinsic_function_names()->ValueAt(entry);
+    int function_index = Smi::cast(smi_index)->value();
+    return &(kIntrinsicFunctions[function_index]);
+  }
+  return NULL;
+}
+
+
+const Runtime::Function* Runtime::FunctionForEntry(Address entry) {
+  for (size_t i = 0; i < arraysize(kIntrinsicFunctions); ++i) {
+    if (entry == kIntrinsicFunctions[i].entry) {
+      return &(kIntrinsicFunctions[i]);
+    }
+  }
+  return NULL;
+}
+
+
+const Runtime::Function* Runtime::FunctionForId(Runtime::FunctionId id) {
+  return &(kIntrinsicFunctions[static_cast<int>(id)]);
+}
+
+
+std::ostream& operator<<(std::ostream& os, Runtime::FunctionId id) {
+  return os << Runtime::FunctionForId(id)->name;
+}
+
+}  // namespace internal
+}  // namespace v8
diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h
new file mode 100644
index 0000000..9e6c495
--- /dev/null
+++ b/src/runtime/runtime.h
@@ -0,0 +1,898 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_RUNTIME_RUNTIME_H_
+#define V8_RUNTIME_RUNTIME_H_
+
+#include "src/allocation.h"
+#include "src/objects.h"
+#include "src/zone.h"
+
+namespace v8 {
+namespace internal {
+
+// The interface to C++ runtime functions.
+
+// ----------------------------------------------------------------------------
+// RUNTIME_FUNCTION_LIST_ALWAYS defines runtime calls available in both
+// release and debug mode.
+// This macro should only be used by the macro RUNTIME_FUNCTION_LIST.
+
+// WARNING: RUNTIME_FUNCTION_LIST_ALWAYS_* is a very large macro that caused
+// MSVC Intellisense to crash.  It was broken into two macros to work around
+// this problem. Please avoid large recursive macros whenever possible.
+#define RUNTIME_FUNCTION_LIST_ALWAYS_1(F)                  \
+  /* Property access */                                    \
+  F(GetProperty, 2, 1)                                     \
+  F(KeyedGetProperty, 2, 1)                                \
+  F(DeleteProperty, 3, 1)                                  \
+  F(HasOwnProperty, 2, 1)                                  \
+  F(HasProperty, 2, 1)                                     \
+  F(HasElement, 2, 1)                                      \
+  F(IsPropertyEnumerable, 2, 1)                            \
+  F(GetPropertyNames, 1, 1)                                \
+  F(GetPropertyNamesFast, 1, 1)                            \
+  F(GetOwnPropertyNames, 2, 1)                             \
+  F(GetOwnElementNames, 1, 1)                              \
+  F(GetInterceptorInfo, 1, 1)                              \
+  F(GetNamedInterceptorPropertyNames, 1, 1)                \
+  F(GetIndexedInterceptorElementNames, 1, 1)               \
+  F(GetArgumentsProperty, 1, 1)                            \
+  F(ToFastProperties, 1, 1)                                \
+  F(FinishArrayPrototypeSetup, 1, 1)                       \
+  F(SpecialArrayFunctions, 0, 1)                           \
+  F(IsSloppyModeFunction, 1, 1)                            \
+  F(GetDefaultReceiver, 1, 1)                              \
+                                                           \
+  F(SetPrototype, 2, 1)                                    \
+  F(InternalSetPrototype, 2, 1)                            \
+  F(IsInPrototypeChain, 2, 1)                              \
+                                                           \
+  F(GetOwnProperty, 2, 1)                                  \
+                                                           \
+  F(IsExtensible, 1, 1)                                    \
+  F(PreventExtensions, 1, 1)                               \
+                                                           \
+  /* Utilities */                                          \
+  F(CheckIsBootstrapping, 0, 1)                            \
+  F(GetRootNaN, 0, 1)                                      \
+  F(Call, -1 /* >= 2 */, 1)                                \
+  F(Apply, 5, 1)                                           \
+  F(GetFunctionDelegate, 1, 1)                             \
+  F(GetConstructorDelegate, 1, 1)                          \
+  F(DeoptimizeFunction, 1, 1)                              \
+  F(ClearFunctionTypeFeedback, 1, 1)                       \
+  F(RunningInSimulator, 0, 1)                              \
+  F(IsConcurrentRecompilationSupported, 0, 1)              \
+  F(OptimizeFunctionOnNextCall, -1, 1)                     \
+  F(NeverOptimizeFunction, 1, 1)                           \
+  F(GetOptimizationStatus, -1, 1)                          \
+  F(GetOptimizationCount, 1, 1)                            \
+  F(UnblockConcurrentRecompilation, 0, 1)                  \
+  F(CompileForOnStackReplacement, 1, 1)                    \
+  F(SetAllocationTimeout, -1 /* 2 || 3 */, 1)              \
+  F(SetNativeFlag, 1, 1)                                   \
+  F(SetInlineBuiltinFlag, 1, 1)                            \
+  F(StoreArrayLiteralElement, 5, 1)                        \
+  F(DebugPrepareStepInIfStepping, 1, 1)                    \
+  F(DebugPushPromise, 1, 1)                                \
+  F(DebugPopPromise, 0, 1)                                 \
+  F(DebugPromiseEvent, 1, 1)                               \
+  F(DebugAsyncTaskEvent, 1, 1)                             \
+  F(PromiseRejectEvent, 3, 1)                              \
+  F(PromiseRevokeReject, 1, 1)                             \
+  F(PromiseHasHandlerSymbol, 0, 1)                         \
+  F(FlattenString, 1, 1)                                   \
+  F(LoadMutableDouble, 2, 1)                               \
+  F(TryMigrateInstance, 1, 1)                              \
+  F(NotifyContextDisposed, 0, 1)                           \
+                                                           \
+  /* Array join support */                                 \
+  F(PushIfAbsent, 2, 1)                                    \
+  F(ArrayConcat, 1, 1)                                     \
+                                                           \
+  /* Conversions */                                        \
+  F(ToBool, 1, 1)                                          \
+  F(Typeof, 1, 1)                                          \
+                                                           \
+  F(Booleanize, 2, 1) /* TODO(turbofan): Only temporary */ \
+                                                           \
+  F(StringToNumber, 1, 1)                                  \
+  F(StringParseInt, 2, 1)                                  \
+  F(StringParseFloat, 1, 1)                                \
+  F(StringToLowerCase, 1, 1)                               \
+  F(StringToUpperCase, 1, 1)                               \
+  F(StringSplit, 3, 1)                                     \
+  F(CharFromCode, 1, 1)                                    \
+  F(URIEscape, 1, 1)                                       \
+  F(URIUnescape, 1, 1)                                     \
+                                                           \
+  F(NumberToInteger, 1, 1)                                 \
+  F(NumberToIntegerMapMinusZero, 1, 1)                     \
+  F(NumberToJSUint32, 1, 1)                                \
+  F(NumberToJSInt32, 1, 1)                                 \
+                                                           \
+  /* Arithmetic operations */                              \
+  F(NumberAdd, 2, 1)                                       \
+  F(NumberSub, 2, 1)                                       \
+  F(NumberMul, 2, 1)                                       \
+  F(NumberDiv, 2, 1)                                       \
+  F(NumberMod, 2, 1)                                       \
+  F(NumberUnaryMinus, 1, 1)                                \
+  F(NumberImul, 2, 1)                                      \
+                                                           \
+  F(StringBuilderConcat, 3, 1)                             \
+  F(StringBuilderJoin, 3, 1)                               \
+  F(SparseJoinWithSeparator, 3, 1)                         \
+                                                           \
+  /* Bit operations */                                     \
+  F(NumberOr, 2, 1)                                        \
+  F(NumberAnd, 2, 1)                                       \
+  F(NumberXor, 2, 1)                                       \
+                                                           \
+  F(NumberShl, 2, 1)                                       \
+  F(NumberShr, 2, 1)                                       \
+  F(NumberSar, 2, 1)                                       \
+                                                           \
+  /* Comparisons */                                        \
+  F(NumberEquals, 2, 1)                                    \
+  F(StringEquals, 2, 1)                                    \
+                                                           \
+  F(NumberCompare, 3, 1)                                   \
+  F(SmiLexicographicCompare, 2, 1)                         \
+                                                           \
+  /* Math */                                               \
+  F(MathAcos, 1, 1)                                        \
+  F(MathAsin, 1, 1)                                        \
+  F(MathAtan, 1, 1)                                        \
+  F(MathFloorRT, 1, 1)                                     \
+  F(MathAtan2, 2, 1)                                       \
+  F(MathExpRT, 1, 1)                                       \
+  F(RoundNumber, 1, 1)                                     \
+  F(MathFround, 1, 1)                                      \
+  F(RemPiO2, 1, 1)                                         \
+                                                           \
+  /* Regular expressions */                                \
+  F(RegExpInitializeAndCompile, 3, 1)                      \
+  F(RegExpExecMultiple, 4, 1)                              \
+                                                           \
+  /* JSON */                                               \
+  F(ParseJson, 1, 1)                                       \
+  F(BasicJSONStringify, 1, 1)                              \
+  F(QuoteJSONString, 1, 1)                                 \
+                                                           \
+  /* Strings */                                            \
+  F(StringIndexOf, 3, 1)                                   \
+  F(StringLastIndexOf, 3, 1)                               \
+  F(StringLocaleCompare, 2, 1)                             \
+  F(StringReplaceGlobalRegExpWithString, 4, 1)             \
+  F(StringReplaceOneCharWithString, 3, 1)                  \
+  F(StringMatch, 3, 1)                                     \
+  F(StringTrim, 3, 1)                                      \
+  F(StringToArray, 2, 1)                                   \
+  F(NewStringWrapper, 1, 1)                                \
+  F(NewString, 2, 1)                                       \
+  F(TruncateString, 2, 1)                                  \
+                                                           \
+  /* Numbers */                                            \
+  F(NumberToRadixString, 2, 1)                             \
+  F(NumberToFixed, 2, 1)                                   \
+  F(NumberToExponential, 2, 1)                             \
+  F(NumberToPrecision, 2, 1)                               \
+  F(IsValidSmi, 1, 1)                                      \
+                                                           \
+  /* Classes support */                                    \
+  F(ToMethod, 2, 1)                                        \
+  F(HomeObjectSymbol, 0, 1)                                \
+  F(DefineClass, 6, 1)                                     \
+  F(DefineClassMethod, 3, 1)                               \
+  F(DefineClassGetter, 3, 1)                               \
+  F(DefineClassSetter, 3, 1)                               \
+  F(ClassGetSourceCode, 1, 1)                              \
+  F(ThrowNonMethodError, 0, 1)                             \
+  F(ThrowUnsupportedSuperError, 0, 1)                      \
+  F(LoadFromSuper, 3, 1)                                   \
+  F(LoadKeyedFromSuper, 3, 1)                              \
+  F(StoreToSuper_Strict, 4, 1)                             \
+  F(StoreToSuper_Sloppy, 4, 1)                             \
+  F(StoreKeyedToSuper_Strict, 4, 1)                        \
+  F(StoreKeyedToSuper_Sloppy, 4, 1)                        \
+  F(DefaultConstructorSuperCall, 0, 1)
+
+
+#define RUNTIME_FUNCTION_LIST_ALWAYS_2(F)              \
+  /* Reflection */                                     \
+  F(FunctionSetInstanceClassName, 2, 1)                \
+  F(FunctionSetLength, 2, 1)                           \
+  F(FunctionSetPrototype, 2, 1)                        \
+  F(FunctionGetName, 1, 1)                             \
+  F(FunctionSetName, 2, 1)                             \
+  F(FunctionNameShouldPrintAsAnonymous, 1, 1)          \
+  F(FunctionMarkNameShouldPrintAsAnonymous, 1, 1)      \
+  F(FunctionIsGenerator, 1, 1)                         \
+  F(FunctionIsArrow, 1, 1)                             \
+  F(FunctionIsConciseMethod, 1, 1)                     \
+  F(FunctionBindArguments, 4, 1)                       \
+  F(BoundFunctionGetBindings, 1, 1)                    \
+  F(FunctionRemovePrototype, 1, 1)                     \
+  F(FunctionGetSourceCode, 1, 1)                       \
+  F(FunctionGetScript, 1, 1)                           \
+  F(FunctionGetScriptSourcePosition, 1, 1)             \
+  F(FunctionGetPositionForOffset, 2, 1)                \
+  F(FunctionIsAPIFunction, 1, 1)                       \
+  F(FunctionIsBuiltin, 1, 1)                           \
+  F(GetScript, 1, 1)                                   \
+  F(CollectStackTrace, 2, 1)                           \
+  F(GetV8Version, 0, 1)                                \
+  F(GeneratorGetFunction, 1, 1)                        \
+  F(GeneratorGetContext, 1, 1)                         \
+  F(GeneratorGetReceiver, 1, 1)                        \
+  F(GeneratorGetContinuation, 1, 1)                    \
+  F(GeneratorGetSourcePosition, 1, 1)                  \
+                                                       \
+  F(SetCode, 2, 1)                                     \
+                                                       \
+  F(CreateApiFunction, 2, 1)                           \
+  F(IsTemplate, 1, 1)                                  \
+  F(GetTemplateField, 2, 1)                            \
+  F(DisableAccessChecks, 1, 1)                         \
+  F(EnableAccessChecks, 1, 1)                          \
+                                                       \
+  /* Dates */                                          \
+  F(DateCurrentTime, 0, 1)                             \
+  F(DateParseString, 2, 1)                             \
+  F(DateLocalTimezone, 1, 1)                           \
+  F(DateToUTC, 1, 1)                                   \
+  F(DateMakeDay, 2, 1)                                 \
+  F(DateSetValue, 3, 1)                                \
+  F(DateCacheVersion, 0, 1)                            \
+                                                       \
+  /* Globals */                                        \
+  F(CompileString, 3, 1)                               \
+                                                       \
+  /* Eval */                                           \
+  F(GlobalProxy, 1, 1)                                 \
+                                                       \
+  F(AddNamedProperty, 4, 1)                            \
+  F(AddPropertyForTemplate, 4, 1)                      \
+  F(SetProperty, 4, 1)                                 \
+  F(AddElement, 4, 1)                                  \
+  F(DefineApiAccessorProperty, 5, 1)                   \
+  F(DefineDataPropertyUnchecked, 4, 1)                 \
+  F(DefineAccessorPropertyUnchecked, 5, 1)             \
+  F(GetDataProperty, 2, 1)                             \
+                                                       \
+  /* Arrays */                                         \
+  F(RemoveArrayHoles, 2, 1)                            \
+  F(GetArrayKeys, 2, 1)                                \
+  F(MoveArrayContents, 2, 1)                           \
+  F(EstimateNumberOfElements, 1, 1)                    \
+  F(NormalizeElements, 1, 1)                           \
+  F(HasComplexElements, 1, 1)                          \
+                                                       \
+  /* Getters and Setters */                            \
+  F(LookupAccessor, 3, 1)                              \
+                                                       \
+  /* ES5 */                                            \
+  F(ObjectSeal, 1, 1)                                  \
+  F(ObjectFreeze, 1, 1)                                \
+                                                       \
+  /* Harmony modules */                                \
+  F(IsJSModule, 1, 1)                                  \
+                                                       \
+  /* Harmony symbols */                                \
+  F(CreateSymbol, 1, 1)                                \
+  F(CreatePrivateSymbol, 1, 1)                         \
+  F(CreateGlobalPrivateOwnSymbol, 1, 1)                \
+  F(CreatePrivateOwnSymbol, 1, 1)                      \
+  F(NewSymbolWrapper, 1, 1)                            \
+  F(SymbolDescription, 1, 1)                           \
+  F(SymbolRegistry, 0, 1)                              \
+  F(SymbolIsPrivate, 1, 1)                             \
+                                                       \
+  /* Harmony proxies */                                \
+  F(CreateJSProxy, 2, 1)                               \
+  F(CreateJSFunctionProxy, 4, 1)                       \
+  F(IsJSFunctionProxy, 1, 1)                           \
+  F(GetHandler, 1, 1)                                  \
+  F(GetCallTrap, 1, 1)                                 \
+  F(GetConstructTrap, 1, 1)                            \
+  F(Fix, 1, 1)                                         \
+                                                       \
+  /* ES6 collection iterators */                       \
+  F(SetIteratorInitialize, 3, 1)                       \
+  F(SetIteratorClone, 1, 1)                            \
+  F(SetIteratorNext, 2, 1)                             \
+  F(SetIteratorDetails, 1, 1)                          \
+  F(MapIteratorInitialize, 3, 1)                       \
+  F(MapIteratorClone, 1, 1)                            \
+  F(MapIteratorNext, 2, 1)                             \
+  F(MapIteratorDetails, 1, 1)                          \
+                                                       \
+  /* Harmony weak maps and sets */                     \
+  F(WeakCollectionInitialize, 1, 1)                    \
+  F(WeakCollectionGet, 2, 1)                           \
+  F(WeakCollectionHas, 2, 1)                           \
+  F(WeakCollectionDelete, 2, 1)                        \
+  F(WeakCollectionSet, 3, 1)                           \
+                                                       \
+  F(GetWeakMapEntries, 2, 1)                           \
+  F(GetWeakSetValues, 2, 1)                            \
+                                                       \
+  /* Harmony events */                                 \
+  F(EnqueueMicrotask, 1, 1)                            \
+  F(RunMicrotasks, 0, 1)                               \
+                                                       \
+  /* Harmony observe */                                \
+  F(IsObserved, 1, 1)                                  \
+  F(SetIsObserved, 1, 1)                               \
+  F(GetObservationState, 0, 1)                         \
+  F(ObservationWeakMapCreate, 0, 1)                    \
+  F(ObserverObjectAndRecordHaveSameOrigin, 3, 1)       \
+  F(ObjectWasCreatedInCurrentOrigin, 1, 1)             \
+  F(GetObjectContextObjectObserve, 1, 1)               \
+  F(GetObjectContextObjectGetNotifier, 1, 1)           \
+  F(GetObjectContextNotifierPerformChange, 1, 1)       \
+  F(DeliverObservationChangeRecords, 2, 1)             \
+                                                       \
+  /* Harmony typed arrays */                           \
+  F(ArrayBufferInitialize, 2, 1)                       \
+  F(ArrayBufferSliceImpl, 3, 1)                        \
+  F(ArrayBufferIsView, 1, 1)                           \
+  F(ArrayBufferNeuter, 1, 1)                           \
+                                                       \
+  F(IsTypedArray, 1, 1)                                \
+  F(TypedArrayInitializeFromArrayLike, 4, 1)           \
+  F(TypedArrayGetBuffer, 1, 1)                         \
+  F(TypedArraySetFastCases, 3, 1)                      \
+                                                       \
+  F(DataViewGetBuffer, 1, 1)                           \
+  F(DataViewGetInt8, 3, 1)                             \
+  F(DataViewGetUint8, 3, 1)                            \
+  F(DataViewGetInt16, 3, 1)                            \
+  F(DataViewGetUint16, 3, 1)                           \
+  F(DataViewGetInt32, 3, 1)                            \
+  F(DataViewGetUint32, 3, 1)                           \
+  F(DataViewGetFloat32, 3, 1)                          \
+  F(DataViewGetFloat64, 3, 1)                          \
+                                                       \
+  F(DataViewSetInt8, 4, 1)                             \
+  F(DataViewSetUint8, 4, 1)                            \
+  F(DataViewSetInt16, 4, 1)                            \
+  F(DataViewSetUint16, 4, 1)                           \
+  F(DataViewSetInt32, 4, 1)                            \
+  F(DataViewSetUint32, 4, 1)                           \
+  F(DataViewSetFloat32, 4, 1)                          \
+  F(DataViewSetFloat64, 4, 1)                          \
+                                                       \
+  /* Statements */                                     \
+  F(NewObjectFromBound, 1, 1)                          \
+                                                       \
+  /* Declarations and initialization */                \
+  F(InitializeVarGlobal, 3, 1)                         \
+  F(OptimizeObjectForAddingMultipleProperties, 2, 1)   \
+                                                       \
+  /* Debugging */                                      \
+  F(DebugPrint, 1, 1)                                  \
+  F(GlobalPrint, 1, 1)                                 \
+  F(DebugTrace, 0, 1)                                  \
+  F(TraceEnter, 0, 1)                                  \
+  F(TraceExit, 1, 1)                                   \
+  F(Abort, 1, 1)                                       \
+  F(AbortJS, 1, 1)                                     \
+  F(NativeScriptsCount, 0, 1)                          \
+  /* ES5 */                                            \
+  F(OwnKeys, 1, 1)                                     \
+                                                       \
+  /* Message objects */                                \
+  F(MessageGetStartPosition, 1, 1)                     \
+  F(MessageGetScript, 1, 1)                            \
+                                                       \
+  /* Pseudo functions - handled as macros by parser */ \
+  F(IS_VAR, 1, 1)                                      \
+                                                       \
+  /* expose boolean functions from objects-inl.h */    \
+  F(HasFastSmiElements, 1, 1)                          \
+  F(HasFastSmiOrObjectElements, 1, 1)                  \
+  F(HasFastObjectElements, 1, 1)                       \
+  F(HasFastDoubleElements, 1, 1)                       \
+  F(HasFastHoleyElements, 1, 1)                        \
+  F(HasDictionaryElements, 1, 1)                       \
+  F(HasSloppyArgumentsElements, 1, 1)                  \
+  F(HasExternalUint8ClampedElements, 1, 1)             \
+  F(HasExternalArrayElements, 1, 1)                    \
+  F(HasExternalInt8Elements, 1, 1)                     \
+  F(HasExternalUint8Elements, 1, 1)                    \
+  F(HasExternalInt16Elements, 1, 1)                    \
+  F(HasExternalUint16Elements, 1, 1)                   \
+  F(HasExternalInt32Elements, 1, 1)                    \
+  F(HasExternalUint32Elements, 1, 1)                   \
+  F(HasExternalFloat32Elements, 1, 1)                  \
+  F(HasExternalFloat64Elements, 1, 1)                  \
+  F(HasFixedUint8ClampedElements, 1, 1)                \
+  F(HasFixedInt8Elements, 1, 1)                        \
+  F(HasFixedUint8Elements, 1, 1)                       \
+  F(HasFixedInt16Elements, 1, 1)                       \
+  F(HasFixedUint16Elements, 1, 1)                      \
+  F(HasFixedInt32Elements, 1, 1)                       \
+  F(HasFixedUint32Elements, 1, 1)                      \
+  F(HasFixedFloat32Elements, 1, 1)                     \
+  F(HasFixedFloat64Elements, 1, 1)                     \
+  F(HasFastProperties, 1, 1)                           \
+  F(TransitionElementsKind, 2, 1)                      \
+  F(HaveSameMap, 2, 1)                                 \
+  F(IsJSGlobalProxy, 1, 1)                             \
+  F(ForInCacheArrayLength, 2, 1) /* TODO(turbofan): Only temporary */
+
+
+#define RUNTIME_FUNCTION_LIST_ALWAYS_3(F)                    \
+  /* String and Regexp */                                    \
+  F(NumberToStringRT, 1, 1)                                  \
+  F(RegExpConstructResult, 3, 1)                             \
+  F(RegExpExecRT, 4, 1)                                      \
+  F(StringAdd, 2, 1)                                         \
+  F(SubString, 3, 1)                                         \
+  F(InternalizeString, 1, 1)                                 \
+  F(StringCompare, 2, 1)                                     \
+  F(StringCharCodeAtRT, 2, 1)                                \
+  F(GetFromCache, 2, 1)                                      \
+                                                             \
+  /* Compilation */                                          \
+  F(CompileLazy, 1, 1)                                       \
+  F(CompileOptimized, 2, 1)                                  \
+  F(TryInstallOptimizedCode, 1, 1)                           \
+  F(NotifyDeoptimized, 1, 1)                                 \
+  F(NotifyStubFailure, 0, 1)                                 \
+                                                             \
+  /* Utilities */                                            \
+  F(AllocateInNewSpace, 1, 1)                                \
+  F(AllocateInTargetSpace, 2, 1)                             \
+  F(AllocateHeapNumber, 0, 1)                                \
+  F(NumberToSmi, 1, 1)                                       \
+  F(NumberToStringSkipCache, 1, 1)                           \
+                                                             \
+  F(NewArguments, 1, 1) /* TODO(turbofan): Only temporary */ \
+  F(NewSloppyArguments, 3, 1)                                \
+  F(NewStrictArguments, 3, 1)                                \
+                                                             \
+  /* Harmony generators */                                   \
+  F(CreateJSGeneratorObject, 0, 1)                           \
+  F(SuspendJSGeneratorObject, 1, 1)                          \
+  F(ResumeJSGeneratorObject, 3, 1)                           \
+  F(GeneratorClose, 1, 1)                                    \
+                                                             \
+  /* Arrays */                                               \
+  F(ArrayConstructor, -1, 1)                                 \
+  F(InternalArrayConstructor, -1, 1)                         \
+                                                             \
+  /* Literals */                                             \
+  F(MaterializeRegExpLiteral, 4, 1)                          \
+  F(CreateObjectLiteral, 4, 1)                               \
+  F(CreateArrayLiteral, 4, 1)                                \
+  F(CreateArrayLiteralStubBailout, 3, 1)                     \
+                                                             \
+  /* Statements */                                           \
+  F(NewClosure, 3, 1)                                        \
+  F(NewClosureFromStubFailure, 1, 1)                         \
+  F(NewObject, 1, 1)                                         \
+  F(NewObjectWithAllocationSite, 2, 1)                       \
+  F(FinalizeInstanceSize, 1, 1)                              \
+  F(Throw, 1, 1)                                             \
+  F(ReThrow, 1, 1)                                           \
+  F(ThrowReferenceError, 1, 1)                               \
+  F(ThrowNotDateError, 0, 1)                                 \
+  F(ThrowConstAssignError, 0, 1)                             \
+  F(StackGuard, 0, 1)                                        \
+  F(Interrupt, 0, 1)                                         \
+  F(PromoteScheduledException, 0, 1)                         \
+                                                             \
+  /* Contexts */                                             \
+  F(NewScriptContext, 2, 1)                                  \
+  F(NewFunctionContext, 1, 1)                                \
+  F(PushWithContext, 2, 1)                                   \
+  F(PushCatchContext, 3, 1)                                  \
+  F(PushBlockContext, 2, 1)                                  \
+  F(PushModuleContext, 2, 1)                                 \
+  F(DeleteLookupSlot, 2, 1)                                  \
+  F(StoreLookupSlot, 4, 1)                                   \
+                                                             \
+  /* Declarations and initialization */                      \
+  F(DeclareGlobals, 3, 1)                                    \
+  F(DeclareModules, 1, 1)                                    \
+  F(DeclareLookupSlot, 4, 1)                                 \
+  F(InitializeConstGlobal, 2, 1)                             \
+  F(InitializeLegacyConstLookupSlot, 3, 1)                   \
+                                                             \
+  /* Maths */                                                \
+  F(MathPowSlow, 2, 1)                                       \
+  F(MathPowRT, 2, 1)
+
+
+#define RUNTIME_FUNCTION_LIST_RETURN_PAIR(F)              \
+  F(LoadLookupSlot, 2, 2)                                 \
+  F(LoadLookupSlotNoReferenceError, 2, 2)                 \
+  F(ResolvePossiblyDirectEval, 6, 2)                      \
+  F(ForInInit, 2, 2) /* TODO(turbofan): Only temporary */ \
+  F(ForInNext, 4, 2) /* TODO(turbofan): Only temporary */
+
+
+#define RUNTIME_FUNCTION_LIST_DEBUGGER(F)           \
+  /* Debugger support*/                             \
+  F(DebugBreak, 0, 1)                               \
+  F(SetDebugEventListener, 2, 1)                    \
+  F(Break, 0, 1)                                    \
+  F(DebugGetPropertyDetails, 2, 1)                  \
+  F(DebugGetProperty, 2, 1)                         \
+  F(DebugPropertyTypeFromDetails, 1, 1)             \
+  F(DebugPropertyAttributesFromDetails, 1, 1)       \
+  F(DebugPropertyIndexFromDetails, 1, 1)            \
+  F(DebugNamedInterceptorPropertyValue, 2, 1)       \
+  F(DebugIndexedInterceptorElementValue, 2, 1)      \
+  F(CheckExecutionState, 1, 1)                      \
+  F(GetFrameCount, 1, 1)                            \
+  F(GetFrameDetails, 2, 1)                          \
+  F(GetScopeCount, 2, 1)                            \
+  F(GetStepInPositions, 2, 1)                       \
+  F(GetScopeDetails, 4, 1)                          \
+  F(GetAllScopesDetails, 4, 1)                      \
+  F(GetFunctionScopeCount, 1, 1)                    \
+  F(GetFunctionScopeDetails, 2, 1)                  \
+  F(SetScopeVariableValue, 6, 1)                    \
+  F(DebugPrintScopes, 0, 1)                         \
+  F(GetThreadCount, 1, 1)                           \
+  F(GetThreadDetails, 2, 1)                         \
+  F(SetDisableBreak, 1, 1)                          \
+  F(GetBreakLocations, 2, 1)                        \
+  F(SetFunctionBreakPoint, 3, 1)                    \
+  F(SetScriptBreakPoint, 4, 1)                      \
+  F(ClearBreakPoint, 1, 1)                          \
+  F(ChangeBreakOnException, 2, 1)                   \
+  F(IsBreakOnException, 1, 1)                       \
+  F(PrepareStep, 4, 1)                              \
+  F(ClearStepping, 0, 1)                            \
+  F(DebugEvaluate, 6, 1)                            \
+  F(DebugEvaluateGlobal, 4, 1)                      \
+  F(DebugGetLoadedScripts, 0, 1)                    \
+  F(DebugReferencedBy, 3, 1)                        \
+  F(DebugConstructedBy, 2, 1)                       \
+  F(DebugGetPrototype, 1, 1)                        \
+  F(DebugSetScriptSource, 2, 1)                     \
+  F(DebugCallbackSupportsStepping, 1, 1)            \
+  F(SystemBreak, 0, 1)                              \
+  F(DebugDisassembleFunction, 1, 1)                 \
+  F(DebugDisassembleConstructor, 1, 1)              \
+  F(FunctionGetInferredName, 1, 1)                  \
+  F(LiveEditFindSharedFunctionInfosForScript, 1, 1) \
+  F(LiveEditGatherCompileInfo, 2, 1)                \
+  F(LiveEditReplaceScript, 3, 1)                    \
+  F(LiveEditReplaceFunctionCode, 2, 1)              \
+  F(LiveEditFunctionSourceUpdated, 1, 1)            \
+  F(LiveEditFunctionSetScript, 2, 1)                \
+  F(LiveEditReplaceRefToNestedFunction, 3, 1)       \
+  F(LiveEditPatchFunctionPositions, 2, 1)           \
+  F(LiveEditCheckAndDropActivations, 2, 1)          \
+  F(LiveEditCompareStrings, 2, 1)                   \
+  F(LiveEditRestartFrame, 2, 1)                     \
+  F(GetFunctionCodePositionFromSource, 2, 1)        \
+  F(ExecuteInDebugContext, 2, 1)                    \
+                                                    \
+  F(SetFlags, 1, 1)                                 \
+  F(CollectGarbage, 1, 1)                           \
+  F(GetHeapUsage, 0, 1)
+
+
+#ifdef V8_I18N_SUPPORT
+#define RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F) \
+  /* i18n support */                          \
+  /* Standalone, helper methods. */           \
+  F(CanonicalizeLanguageTag, 1, 1)            \
+  F(AvailableLocalesOf, 1, 1)                 \
+  F(GetDefaultICULocale, 0, 1)                \
+  F(GetLanguageTagVariants, 1, 1)             \
+  F(IsInitializedIntlObject, 1, 1)            \
+  F(IsInitializedIntlObjectOfType, 2, 1)      \
+  F(MarkAsInitializedIntlObjectOfType, 3, 1)  \
+  F(GetImplFromInitializedIntlObject, 1, 1)   \
+                                              \
+  /* Date format and parse. */                \
+  F(CreateDateTimeFormat, 3, 1)               \
+  F(InternalDateFormat, 2, 1)                 \
+  F(InternalDateParse, 2, 1)                  \
+                                              \
+  /* Number format and parse. */              \
+  F(CreateNumberFormat, 3, 1)                 \
+  F(InternalNumberFormat, 2, 1)               \
+  F(InternalNumberParse, 2, 1)                \
+                                              \
+  /* Collator. */                             \
+  F(CreateCollator, 3, 1)                     \
+  F(InternalCompare, 3, 1)                    \
+                                              \
+  /* String.prototype.normalize. */           \
+  F(StringNormalize, 2, 1)                    \
+                                              \
+  /* Break iterator. */                       \
+  F(CreateBreakIterator, 3, 1)                \
+  F(BreakIteratorAdoptText, 2, 1)             \
+  F(BreakIteratorFirst, 1, 1)                 \
+  F(BreakIteratorNext, 1, 1)                  \
+  F(BreakIteratorCurrent, 1, 1)               \
+  F(BreakIteratorBreakType, 1, 1)
+
+#else
+#define RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F)
+#endif
+
+
+// ----------------------------------------------------------------------------
+// RUNTIME_FUNCTION_LIST defines all runtime functions accessed
+// either directly by id (via the code generator), or indirectly
+// via a native call by name (from within JS code).
+// Entries have the form F(name, number of arguments, number of return values).
+
+#define RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F) \
+  RUNTIME_FUNCTION_LIST_ALWAYS_1(F)            \
+  RUNTIME_FUNCTION_LIST_ALWAYS_2(F)            \
+  RUNTIME_FUNCTION_LIST_ALWAYS_3(F)            \
+  RUNTIME_FUNCTION_LIST_DEBUGGER(F)            \
+  RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F)
+
+
+#define RUNTIME_FUNCTION_LIST(F)         \
+  RUNTIME_FUNCTION_LIST_RETURN_OBJECT(F) \
+  RUNTIME_FUNCTION_LIST_RETURN_PAIR(F)
+
+// ----------------------------------------------------------------------------
+// INLINE_FUNCTION_LIST defines all inlined functions accessed
+// with a native call of the form %_name from within JS code.
+// Entries have the form F(name, number of arguments, number of return values).
+#define INLINE_FUNCTION_LIST(F)                             \
+  F(IsSmi, 1, 1)                                            \
+  F(IsNonNegativeSmi, 1, 1)                                 \
+  F(IsArray, 1, 1)                                          \
+  F(IsRegExp, 1, 1)                                         \
+  F(IsJSProxy, 1, 1)                                        \
+  F(IsConstructCall, 0, 1)                                  \
+  F(CallFunction, -1 /* receiver + n args + function */, 1) \
+  F(ArgumentsLength, 0, 1)                                  \
+  F(Arguments, 1, 1)                                        \
+  F(ValueOf, 1, 1)                                          \
+  F(SetValueOf, 2, 1)                                       \
+  F(DateField, 2 /* date object, field index */, 1)         \
+  F(StringCharFromCode, 1, 1)                               \
+  F(StringCharAt, 2, 1)                                     \
+  F(OneByteSeqStringSetChar, 3, 1)                          \
+  F(TwoByteSeqStringSetChar, 3, 1)                          \
+  F(ObjectEquals, 2, 1)                                     \
+  F(IsObject, 1, 1)                                         \
+  F(IsFunction, 1, 1)                                       \
+  F(IsUndetectableObject, 1, 1)                             \
+  F(IsSpecObject, 1, 1)                                     \
+  F(IsStringWrapperSafeForDefaultValueOf, 1, 1)             \
+  F(MathPow, 2, 1)                                          \
+  F(IsMinusZero, 1, 1)                                      \
+  F(HasCachedArrayIndex, 1, 1)                              \
+  F(GetCachedArrayIndex, 1, 1)                              \
+  F(FastOneByteArrayJoin, 2, 1)                             \
+  F(GeneratorNext, 2, 1)                                    \
+  F(GeneratorThrow, 2, 1)                                   \
+  F(DebugBreakInOptimizedCode, 0, 1)                        \
+  F(ClassOf, 1, 1)                                          \
+  F(StringCharCodeAt, 2, 1)                                 \
+  F(StringAdd, 2, 1)                                        \
+  F(SubString, 3, 1)                                        \
+  F(StringCompare, 2, 1)                                    \
+  F(RegExpExec, 4, 1)                                       \
+  F(RegExpConstructResult, 3, 1)                            \
+  F(GetFromCache, 2, 1)                                     \
+  F(NumberToString, 1, 1)                                   \
+  F(DebugIsActive, 0, 1)
+
+
+// ----------------------------------------------------------------------------
+// INLINE_OPTIMIZED_FUNCTION_LIST defines all inlined functions accessed
+// with a native call of the form %_name from within JS code that also have
+// a corresponding runtime function, that is called from non-optimized code.
+// For the benefit of (fuzz) tests, the runtime version can also be called
+// directly as %name (i.e. without the leading underscore).
+// Entries have the form F(name, number of arguments, number of return values).
+#define INLINE_OPTIMIZED_FUNCTION_LIST(F) \
+  /* Typed Arrays */                      \
+  F(TypedArrayInitialize, 5, 1)           \
+  F(DataViewInitialize, 4, 1)             \
+  F(MaxSmi, 0, 1)                         \
+  F(TypedArrayMaxSizeInHeap, 0, 1)        \
+  F(ArrayBufferViewGetByteLength, 1, 1)   \
+  F(ArrayBufferViewGetByteOffset, 1, 1)   \
+  F(TypedArrayGetLength, 1, 1)            \
+  /* ArrayBuffer */                       \
+  F(ArrayBufferGetByteLength, 1, 1)       \
+  /* Maths */                             \
+  F(ConstructDouble, 2, 1)                \
+  F(DoubleHi, 1, 1)                       \
+  F(DoubleLo, 1, 1)                       \
+  F(MathSqrtRT, 1, 1)                     \
+  F(MathLogRT, 1, 1)                      \
+  /* ES6 Collections */                   \
+  F(MapClear, 1, 1)                       \
+  F(MapDelete, 2, 1)                      \
+  F(MapGet, 2, 1)                         \
+  F(MapGetSize, 1, 1)                     \
+  F(MapHas, 2, 1)                         \
+  F(MapInitialize, 1, 1)                  \
+  F(MapSet, 3, 1)                         \
+  F(SetAdd, 2, 1)                         \
+  F(SetClear, 1, 1)                       \
+  F(SetDelete, 2, 1)                      \
+  F(SetGetSize, 1, 1)                     \
+  F(SetHas, 2, 1)                         \
+  F(SetInitialize, 1, 1)                  \
+  /* Arrays */                            \
+  F(HasFastPackedElements, 1, 1)          \
+  F(GetPrototype, 1, 1)
+
+
+//---------------------------------------------------------------------------
+// Runtime provides access to all C++ runtime functions.
+
+class RuntimeState {
+ public:
+  unibrow::Mapping<unibrow::ToUppercase, 128>* to_upper_mapping() {
+    return &to_upper_mapping_;
+  }
+  unibrow::Mapping<unibrow::ToLowercase, 128>* to_lower_mapping() {
+    return &to_lower_mapping_;
+  }
+
+ private:
+  RuntimeState() {}
+  unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping_;
+  unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping_;
+
+  friend class Isolate;
+  friend class Runtime;
+
+  DISALLOW_COPY_AND_ASSIGN(RuntimeState);
+};
+
+
+class JavaScriptFrameIterator;  // Forward declaration.
+
+
+class Runtime : public AllStatic {
+ public:
+  enum FunctionId {
+#define F(name, nargs, ressize) k##name,
+    RUNTIME_FUNCTION_LIST(F) INLINE_OPTIMIZED_FUNCTION_LIST(F)
+#undef F
+#define F(name, nargs, ressize) kInline##name,
+    INLINE_FUNCTION_LIST(F)
+#undef F
+#define F(name, nargs, ressize) kInlineOptimized##name,
+    INLINE_OPTIMIZED_FUNCTION_LIST(F)
+#undef F
+    kNumFunctions,
+    kFirstInlineFunction = kInlineIsSmi
+  };
+
+  enum IntrinsicType { RUNTIME, INLINE, INLINE_OPTIMIZED };
+
+  // Intrinsic function descriptor.
+  struct Function {
+    FunctionId function_id;
+    IntrinsicType intrinsic_type;
+    // The JS name of the function.
+    const char* name;
+
+    // The C++ (native) entry point.  NULL if the function is inlined.
+    byte* entry;
+
+    // The number of arguments expected. nargs is -1 if the function takes
+    // a variable number of arguments.
+    int nargs;
+    // Size of result.  Most functions return a single pointer, size 1.
+    int result_size;
+  };
+
+  static const int kNotFound = -1;
+
+  // Add internalized strings for all the intrinsic function names to a
+  // StringDictionary.
+  static void InitializeIntrinsicFunctionNames(Isolate* isolate,
+                                               Handle<NameDictionary> dict);
+
+  // Get the intrinsic function with the given name, which must be internalized.
+  static const Function* FunctionForName(Handle<String> name);
+
+  // Get the intrinsic function with the given FunctionId.
+  static const Function* FunctionForId(FunctionId id);
+
+  // Get the intrinsic function with the given function entry address.
+  static const Function* FunctionForEntry(Address ref);
+
+  // TODO(1240886): Some of the following methods are *not* handle safe, but
+  // accept handle arguments. This seems fragile.
+
+  // Support getting the characters in a string using [] notation as
+  // in Firefox/SpiderMonkey, Safari and Opera.
+  MUST_USE_RESULT static MaybeHandle<Object> GetElementOrCharAt(
+      Isolate* isolate, Handle<Object> object, uint32_t index);
+
+  MUST_USE_RESULT static MaybeHandle<Object> SetObjectProperty(
+      Isolate* isolate, Handle<Object> object, Handle<Object> key,
+      Handle<Object> value, StrictMode strict_mode);
+
+  MUST_USE_RESULT static MaybeHandle<Object> DefineObjectProperty(
+      Handle<JSObject> object, Handle<Object> key, Handle<Object> value,
+      PropertyAttributes attr);
+
+  MUST_USE_RESULT static MaybeHandle<Object> GetObjectProperty(
+      Isolate* isolate, Handle<Object> object, Handle<Object> key);
+
+  MUST_USE_RESULT static MaybeHandle<Object> GetPrototype(
+      Isolate* isolate, Handle<Object> object);
+
+  MUST_USE_RESULT static MaybeHandle<Name> ToName(Isolate* isolate,
+                                                  Handle<Object> key);
+
+  static void SetupArrayBuffer(Isolate* isolate,
+                               Handle<JSArrayBuffer> array_buffer,
+                               bool is_external, void* data,
+                               size_t allocated_length);
+
+  static bool SetupArrayBufferAllocatingData(Isolate* isolate,
+                                             Handle<JSArrayBuffer> array_buffer,
+                                             size_t allocated_length,
+                                             bool initialize = true);
+
+  static void NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer);
+
+  static void FreeArrayBuffer(Isolate* isolate,
+                              JSArrayBuffer* phantom_array_buffer);
+
+  static int FindIndexedNonNativeFrame(JavaScriptFrameIterator* it, int index);
+
+  enum TypedArrayId {
+    // arrayIds below should be synchromized with typedarray.js natives.
+    ARRAY_ID_UINT8 = 1,
+    ARRAY_ID_INT8 = 2,
+    ARRAY_ID_UINT16 = 3,
+    ARRAY_ID_INT16 = 4,
+    ARRAY_ID_UINT32 = 5,
+    ARRAY_ID_INT32 = 6,
+    ARRAY_ID_FLOAT32 = 7,
+    ARRAY_ID_FLOAT64 = 8,
+    ARRAY_ID_UINT8_CLAMPED = 9,
+    ARRAY_ID_FIRST = ARRAY_ID_UINT8,
+    ARRAY_ID_LAST = ARRAY_ID_UINT8_CLAMPED
+  };
+
+  static void ArrayIdToTypeAndSize(int array_id, ExternalArrayType* type,
+                                   ElementsKind* external_elements_kind,
+                                   ElementsKind* fixed_elements_kind,
+                                   size_t* element_size);
+
+  // Used in runtime.cc and hydrogen's VisitArrayLiteral.
+  MUST_USE_RESULT static MaybeHandle<Object> CreateArrayLiteralBoilerplate(
+      Isolate* isolate, Handle<FixedArray> literals,
+      Handle<FixedArray> elements);
+};
+
+
+std::ostream& operator<<(std::ostream&, Runtime::FunctionId);
+
+//---------------------------------------------------------------------------
+// Constants used by interface to runtime functions.
+
+class AllocateDoubleAlignFlag : public BitField<bool, 0, 1> {};
+class AllocateTargetSpace : public BitField<AllocationSpace, 1, 3> {};
+
+class DeclareGlobalsEvalFlag : public BitField<bool, 0, 1> {};
+class DeclareGlobalsNativeFlag : public BitField<bool, 1, 1> {};
+class DeclareGlobalsStrictMode : public BitField<StrictMode, 2, 1> {};
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_RUNTIME_RUNTIME_H_
diff --git a/src/safepoint-table.cc b/src/safepoint-table.cc
index 89500e2..aaa32b9 100644
--- a/src/safepoint-table.cc
+++ b/src/safepoint-table.cc
@@ -61,7 +61,8 @@
 }
 
 
-void SafepointTable::PrintEntry(unsigned index, OStream& os) const {  // NOLINT
+void SafepointTable::PrintEntry(unsigned index,
+                                std::ostream& os) const {  // NOLINT
   disasm::NameConverter converter;
   SafepointEntry entry = GetEntry(index);
   uint8_t* bits = entry.bits();
@@ -86,7 +87,7 @@
 }
 
 
-void SafepointTable::PrintBits(OStream& os,  // NOLINT
+void SafepointTable::PrintBits(std::ostream& os,  // NOLINT
                                uint8_t byte, int digits) {
   DCHECK(digits >= 0 && digits <= kBitsPerByte);
   for (int i = 0; i < digits; i++) {
diff --git a/src/safepoint-table.h b/src/safepoint-table.h
index 5fbfe41..a7719e0 100644
--- a/src/safepoint-table.h
+++ b/src/safepoint-table.h
@@ -104,7 +104,7 @@
   // Returns the entry for the given pc.
   SafepointEntry FindEntry(Address pc) const;
 
-  void PrintEntry(unsigned index, OStream& os) const;  // NOLINT
+  void PrintEntry(unsigned index, std::ostream& os) const;  // NOLINT
 
  private:
   static const uint8_t kNoRegisters = 0xFF;
@@ -127,7 +127,7 @@
     return GetPcOffsetLocation(index) + kPcSize;
   }
 
-  static void PrintBits(OStream& os,  // NOLINT
+  static void PrintBits(std::ostream& os,  // NOLINT
                         uint8_t byte, int digits);
 
   DisallowHeapAllocation no_allocation_;
diff --git a/src/sampler.cc b/src/sampler.cc
index 394efeb..760df80 100644
--- a/src/sampler.cc
+++ b/src/sampler.cc
@@ -226,13 +226,13 @@
 #if defined(USE_SIMULATOR)
 class SimulatorHelper {
  public:
-  inline bool Init(Sampler* sampler, Isolate* isolate) {
+  inline bool Init(Isolate* isolate) {
     simulator_ = isolate->thread_local_top()->simulator_;
     // Check if there is active simulator.
     return simulator_ != NULL;
   }
 
-  inline void FillRegisters(RegisterState* state) {
+  inline void FillRegisters(v8::RegisterState* state) {
 #if V8_TARGET_ARCH_ARM
     state->pc = reinterpret_cast<Address>(simulator_->get_pc());
     state->sp = reinterpret_cast<Address>(simulator_->get_register(
@@ -241,22 +241,16 @@
         Simulator::r11));
 #elif V8_TARGET_ARCH_ARM64
     if (simulator_->sp() == 0 || simulator_->fp() == 0) {
-      // It possible that the simulator is interrupted while it is updating
+      // It's possible that the simulator is interrupted while it is updating
       // the sp or fp register. ARM64 simulator does this in two steps:
-      // first setting it to zero and then setting it to the new value.
+      // first setting it to zero and then setting it to a new value.
       // Bailout if sp/fp doesn't contain the new value.
       return;
     }
     state->pc = reinterpret_cast<Address>(simulator_->pc());
     state->sp = reinterpret_cast<Address>(simulator_->sp());
     state->fp = reinterpret_cast<Address>(simulator_->fp());
-#elif V8_TARGET_ARCH_MIPS
-    state->pc = reinterpret_cast<Address>(simulator_->get_pc());
-    state->sp = reinterpret_cast<Address>(simulator_->get_register(
-        Simulator::sp));
-    state->fp = reinterpret_cast<Address>(simulator_->get_register(
-        Simulator::fp));
-#elif V8_TARGET_ARCH_MIPS64
+#elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
     state->pc = reinterpret_cast<Address>(simulator_->get_pc());
     state->sp = reinterpret_cast<Address>(simulator_->get_register(
         Simulator::sp));
@@ -341,7 +335,7 @@
   USE(info);
   if (signal != SIGPROF) return;
   Isolate* isolate = Isolate::UnsafeCurrent();
-  if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) {
+  if (isolate == NULL || !isolate->IsInUse()) {
     // We require a fully initialized and entered isolate.
     return;
   }
@@ -353,11 +347,11 @@
   Sampler* sampler = isolate->logger()->sampler();
   if (sampler == NULL) return;
 
-  RegisterState state;
+  v8::RegisterState state;
 
 #if defined(USE_SIMULATOR)
   SimulatorHelper helper;
-  if (!helper.Init(sampler, isolate)) return;
+  if (!helper.Init(isolate)) return;
   helper.FillRegisters(&state);
   // It possible that the simulator is interrupted while it is updating
   // the sp or fp register. ARM64 simulator does this in two steps:
@@ -380,8 +374,7 @@
   state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
   state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
 #elif V8_HOST_ARCH_ARM
-#if defined(__GLIBC__) && !defined(__UCLIBC__) && \
-    (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
+#if V8_LIBC_GLIBC && !V8_GLIBC_PREREQ(2, 4)
   // Old GLibc ARM versions used a gregs[] array to access the register
   // values from mcontext_t.
   state.pc = reinterpret_cast<Address>(mcontext.gregs[R15]);
@@ -391,8 +384,7 @@
   state.pc = reinterpret_cast<Address>(mcontext.arm_pc);
   state.sp = reinterpret_cast<Address>(mcontext.arm_sp);
   state.fp = reinterpret_cast<Address>(mcontext.arm_fp);
-#endif  // defined(__GLIBC__) && !defined(__UCLIBC__) &&
-        // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
+#endif  // V8_LIBC_GLIBC && !V8_GLIBC_PREREQ(2, 4)
 #elif V8_HOST_ARCH_ARM64
   state.pc = reinterpret_cast<Address>(mcontext.pc);
   state.sp = reinterpret_cast<Address>(mcontext.sp);
@@ -548,7 +540,6 @@
         // profiled. We must not suspend.
         for (int i = 0; i < active_samplers_.length(); ++i) {
           Sampler* sampler = active_samplers_.at(i);
-          if (!sampler->isolate()->IsInitialized()) continue;
           if (!sampler->IsProfiling()) continue;
           sampler->DoSample();
         }
@@ -577,20 +568,17 @@
 // StackTracer implementation
 //
 DISABLE_ASAN void TickSample::Init(Isolate* isolate,
-                                   const RegisterState& regs) {
-  DCHECK(isolate->IsInitialized());
+                                   const v8::RegisterState& regs,
+                                   RecordCEntryFrame record_c_entry_frame) {
   timestamp = base::TimeTicks::HighResolutionNow();
-  pc = regs.pc;
+  pc = reinterpret_cast<Address>(regs.pc);
   state = isolate->current_vm_state();
 
   // Avoid collecting traces while doing GC.
   if (state == GC) return;
 
   Address js_entry_sp = isolate->js_entry_sp();
-  if (js_entry_sp == 0) {
-    // Not executing JS now.
-    return;
-  }
+  if (js_entry_sp == 0) return;  // Not executing JS now.
 
   ExternalCallbackScope* scope = isolate->external_callback_scope();
   Address handler = Isolate::handler(isolate->thread_local_top());
@@ -603,18 +591,44 @@
   } else {
     // Sample potential return address value for frameless invocation of
     // stubs (we'll figure out later, if this value makes sense).
-    tos = Memory::Address_at(regs.sp);
+    tos = Memory::Address_at(reinterpret_cast<Address>(regs.sp));
     has_external_callback = false;
   }
 
-  SafeStackFrameIterator it(isolate, regs.fp, regs.sp, js_entry_sp);
+  SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp),
+                            reinterpret_cast<Address>(regs.sp), js_entry_sp);
   top_frame_type = it.top_frame_type();
-  unsigned i = 0;
-  while (!it.done() && i < TickSample::kMaxFramesCount) {
-    stack[i++] = it.frame()->pc();
+
+  SampleInfo info;
+  GetStackSample(isolate, regs, record_c_entry_frame,
+                 reinterpret_cast<void**>(&stack[0]), kMaxFramesCount, &info);
+  frames_count = static_cast<unsigned>(info.frames_count);
+}
+
+
+void TickSample::GetStackSample(Isolate* isolate, const v8::RegisterState& regs,
+                                RecordCEntryFrame record_c_entry_frame,
+                                void** frames, size_t frames_limit,
+                                v8::SampleInfo* sample_info) {
+  sample_info->frames_count = 0;
+  sample_info->vm_state = isolate->current_vm_state();
+  if (sample_info->vm_state == GC) return;
+
+  Address js_entry_sp = isolate->js_entry_sp();
+  if (js_entry_sp == 0) return;  // Not executing JS now.
+
+  SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp),
+                            reinterpret_cast<Address>(regs.sp), js_entry_sp);
+  size_t i = 0;
+  if (record_c_entry_frame == kIncludeCEntryFrame && !it.done() &&
+      it.top_frame_type() == StackFrame::EXIT) {
+    frames[i++] = isolate->c_function();
+  }
+  while (!it.done() && i < frames_limit) {
+    frames[i++] = it.frame()->pc();
     it.Advance();
   }
-  frames_count = i;
+  sample_info->frames_count = i;
 }
 
 
@@ -682,11 +696,11 @@
 }
 
 
-void Sampler::SampleStack(const RegisterState& state) {
+void Sampler::SampleStack(const v8::RegisterState& state) {
   TickSample* sample = isolate_->cpu_profiler()->StartTickSample();
   TickSample sample_obj;
   if (sample == NULL) sample = &sample_obj;
-  sample->Init(isolate_, state);
+  sample->Init(isolate_, state, TickSample::kIncludeCEntryFrame);
   if (is_counting_samples_) {
     if (sample->state == JS || sample->state == EXTERNAL) {
       ++js_and_external_sample_count_;
@@ -714,7 +728,7 @@
 
 #if defined(USE_SIMULATOR)
   SimulatorHelper helper;
-  if (!helper.Init(this, isolate())) return;
+  if (!helper.Init(isolate())) return;
 #endif
 
   const DWORD kSuspendFailed = static_cast<DWORD>(-1);
@@ -725,7 +739,7 @@
   memset(&context, 0, sizeof(context));
   context.ContextFlags = CONTEXT_FULL;
   if (GetThreadContext(profiled_thread, &context) != 0) {
-    RegisterState state;
+    v8::RegisterState state;
 #if defined(USE_SIMULATOR)
     helper.FillRegisters(&state);
 #else
diff --git a/src/sampler.h b/src/sampler.h
index c3dce4e..120260d 100644
--- a/src/sampler.h
+++ b/src/sampler.h
@@ -5,6 +5,8 @@
 #ifndef V8_SAMPLER_H_
 #define V8_SAMPLER_H_
 
+#include "include/v8.h"
+
 #include "src/base/atomicops.h"
 #include "src/frames.h"
 #include "src/globals.h"
@@ -21,15 +23,13 @@
 // (if used for profiling) the program counter and stack pointer for
 // the thread that created it.
 
-struct RegisterState {
-  RegisterState() : pc(NULL), sp(NULL), fp(NULL) {}
-  Address pc;      // Instruction pointer.
-  Address sp;      // Stack pointer.
-  Address fp;      // Frame pointer.
-};
-
 // TickSample captures the information collected for each sample.
 struct TickSample {
+  // Internal profiling (with --prof + tools/$OS-tick-processor) wants to
+  // include the runtime function we're calling. Externally exposed tick
+  // samples don't care.
+  enum RecordCEntryFrame { kIncludeCEntryFrame, kSkipCEntryFrame };
+
   TickSample()
       : state(OTHER),
         pc(NULL),
@@ -37,7 +37,12 @@
         frames_count(0),
         has_external_callback(false),
         top_frame_type(StackFrame::NONE) {}
-  void Init(Isolate* isolate, const RegisterState& state);
+  void Init(Isolate* isolate, const v8::RegisterState& state,
+            RecordCEntryFrame record_c_entry_frame);
+  static void GetStackSample(Isolate* isolate, const v8::RegisterState& state,
+                             RecordCEntryFrame record_c_entry_frame,
+                             void** frames, size_t frames_limit,
+                             v8::SampleInfo* sample_info);
   StateTag state;  // The state of the VM.
   Address pc;      // Instruction pointer.
   union {
@@ -67,7 +72,7 @@
   int interval() const { return interval_; }
 
   // Performs stack sampling.
-  void SampleStack(const RegisterState& regs);
+  void SampleStack(const v8::RegisterState& regs);
 
   // Start and stop sampler.
   void Start();
diff --git a/src/scanner-character-streams.cc b/src/scanner-character-streams.cc
index d06f479..50c3955 100644
--- a/src/scanner-character-streams.cc
+++ b/src/scanner-character-streams.cc
@@ -18,6 +18,10 @@
 unsigned CopyCharsHelper(uint16_t* dest, unsigned length, const uint8_t* src,
                          unsigned* src_pos, unsigned src_length,
                          ScriptCompiler::StreamedSource::Encoding encoding) {
+  // It's possible that this will be called with length 0, but don't assume that
+  // the functions this calls handle it gracefully.
+  if (length == 0) return 0;
+
   if (encoding == ScriptCompiler::StreamedSource::UTF8) {
     return v8::internal::Utf8ToUtf16CharacterStream::CopyChars(
         dest, length, src, src_pos, src_length);
@@ -381,15 +385,22 @@
 
 void ExternalStreamingStream::HandleUtf8SplitCharacters(
     unsigned* data_in_buffer) {
+  // Note the following property of UTF-8 which makes this function possible:
+  // Given any byte, we can always read its local environment (in both
+  // directions) to find out the (possibly multi-byte) character it belongs
+  // to. Single byte characters are of the form 0b0XXXXXXX. The first byte of a
+  // multi-byte character is of the form 0b110XXXXX, 0b1110XXXX or
+  // 0b11110XXX. The continuation bytes are of the form 0b10XXXXXX.
+
   // First check if we have leftover data from the last chunk.
   unibrow::uchar c;
   if (utf8_split_char_buffer_length_ > 0) {
     // Move the bytes which are part of the split character (which started in
-    // the previous chunk) into utf8_split_char_buffer_.
+    // the previous chunk) into utf8_split_char_buffer_. Note that the
+    // continuation bytes are of the form 0b10XXXXXX, thus c >> 6 == 2.
     while (current_data_offset_ < current_data_length_ &&
            utf8_split_char_buffer_length_ < 4 &&
-           (c = current_data_[current_data_offset_]) >
-               unibrow::Utf8::kMaxOneByteChar) {
+           (c = current_data_[current_data_offset_]) >> 6 == 2) {
       utf8_split_char_buffer_[utf8_split_char_buffer_length_] = c;
       ++utf8_split_char_buffer_length_;
       ++current_data_offset_;
@@ -420,6 +431,12 @@
          utf8_split_char_buffer_length_ < 4) {
     --current_data_length_;
     ++utf8_split_char_buffer_length_;
+    if (c >= (3 << 6)) {
+      // 3 << 6 = 0b11000000; this is the first byte of the multi-byte
+      // character. No need to copy the previous characters into the conversion
+      // buffer (even if they're multi-byte).
+      break;
+    }
   }
   CHECK(utf8_split_char_buffer_length_ <= 4);
   for (unsigned i = 0; i < utf8_split_char_buffer_length_; ++i) {
diff --git a/src/scanner-character-streams.h b/src/scanner-character-streams.h
index afca13f..3c1cccc 100644
--- a/src/scanner-character-streams.h
+++ b/src/scanner-character-streams.h
@@ -91,7 +91,7 @@
 
   virtual ~ExternalStreamingStream() { delete[] current_data_; }
 
-  virtual unsigned BufferSeekForward(unsigned delta) OVERRIDE {
+  unsigned BufferSeekForward(unsigned delta) OVERRIDE {
     // We never need to seek forward when streaming scripts. We only seek
     // forward when we want to parse a function whose location we already know,
     // and when streaming, we don't know the locations of anything we haven't
@@ -100,7 +100,7 @@
     return 0;
   }
 
-  virtual unsigned FillBuffer(unsigned position);
+  unsigned FillBuffer(unsigned position) OVERRIDE;
 
  private:
   void HandleUtf8SplitCharacters(unsigned* data_in_buffer);
diff --git a/src/scanner.cc b/src/scanner.cc
index 72874aa..d499e9b 100644
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -4,11 +4,12 @@
 
 // Features shared by parsing and pre-parsing scanners.
 
+#include <stdint.h>
+
 #include <cmath>
 
 #include "src/v8.h"
 
-#include "include/v8stdint.h"
 #include "src/ast-value-factory.h"
 #include "src/char-predicates-inl.h"
 #include "src/conversions-inl.h"
@@ -37,7 +38,9 @@
       harmony_scoping_(false),
       harmony_modules_(false),
       harmony_numeric_literals_(false),
-      harmony_classes_(false) { }
+      harmony_classes_(false),
+      harmony_templates_(false),
+      harmony_unicode_(false) {}
 
 
 void Scanner::Initialize(Utf16CharacterStream* source) {
@@ -53,33 +56,41 @@
 }
 
 
+template <bool capture_raw>
 uc32 Scanner::ScanHexNumber(int expected_length) {
   DCHECK(expected_length <= 4);  // prevent overflow
 
-  uc32 digits[4] = { 0, 0, 0, 0 };
   uc32 x = 0;
   for (int i = 0; i < expected_length; i++) {
-    digits[i] = c0_;
     int d = HexValue(c0_);
     if (d < 0) {
-      // According to ECMA-262, 3rd, 7.8.4, page 18, these hex escapes
-      // should be illegal, but other JS VMs just return the
-      // non-escaped version of the original character.
-
-      // Push back digits that we have advanced past.
-      for (int j = i-1; j >= 0; j--) {
-        PushBack(digits[j]);
-      }
       return -1;
     }
     x = x * 16 + d;
-    Advance();
+    Advance<capture_raw>();
   }
 
   return x;
 }
 
 
+template <bool capture_raw>
+uc32 Scanner::ScanUnlimitedLengthHexNumber(int max_value) {
+  uc32 x = 0;
+  int d = HexValue(c0_);
+  if (d < 0) {
+    return -1;
+  }
+  while (d >= 0) {
+    x = x * 16 + d;
+    if (x > max_value) return -1;
+    Advance<capture_raw>();
+    d = HexValue(c0_);
+  }
+  return x;
+}
+
+
 // Ensure that tokens can be stored in a byte.
 STATIC_ASSERT(Token::NUM_TOKENS <= 0x100);
 
@@ -254,6 +265,8 @@
 
   while (true) {
     while (true) {
+      // The unicode cache accepts unsigned inputs.
+      if (c0_ < 0) break;
       // Advance as long as character is a WhiteSpace or LineTerminator.
       // Remember if the latter is the case.
       if (unicode_cache_->IsLineTerminator(c0_)) {
@@ -318,8 +331,7 @@
 void Scanner::TryToParseSourceURLComment() {
   // Magic comments are of the form: //[#@]\s<name>=\s*<value>\s*.* and this
   // function will just return if it cannot parse a magic comment.
-  if (!unicode_cache_->IsWhiteSpace(c0_))
-    return;
+  if (c0_ < 0 || !unicode_cache_->IsWhiteSpace(c0_)) return;
   Advance();
   LiteralBuffer name;
   while (c0_ >= 0 && !unicode_cache_->IsWhiteSpaceOrLineTerminator(c0_) &&
@@ -374,7 +386,7 @@
   while (c0_ >= 0) {
     uc32 ch = c0_;
     Advance();
-    if (unicode_cache_->IsLineTerminator(ch)) {
+    if (c0_ >= 0 && unicode_cache_->IsLineTerminator(ch)) {
       // Following ECMA-262, section 7.4, a comment containing
       // a newline will make the comment count as a line-terminator.
       has_multiline_comment_before_next_ = true;
@@ -410,6 +422,7 @@
 
 void Scanner::Scan() {
   next_.literal_chars = NULL;
+  next_.raw_literal_chars = NULL;
   Token::Value token;
   do {
     // Remember the position of the next token
@@ -633,15 +646,21 @@
         token = Select(Token::BIT_NOT);
         break;
 
+      case '`':
+        if (HarmonyTemplates()) {
+          token = ScanTemplateStart();
+          break;
+        }
+
       default:
-        if (unicode_cache_->IsIdentifierStart(c0_)) {
+        if (c0_ < 0) {
+          token = Token::EOS;
+        } else if (unicode_cache_->IsIdentifierStart(c0_)) {
           token = ScanIdentifierOrKeyword();
         } else if (IsDecimalDigit(c0_)) {
           token = ScanNumber(false);
         } else if (SkipWhiteSpace()) {
           token = Token::WHITESPACE;
-        } else if (c0_ < 0) {
-          token = Token::EOS;
         } else {
           token = Select(Token::ILLEGAL);
         }
@@ -678,16 +697,17 @@
 }
 
 
+template <bool capture_raw, bool in_template_literal>
 bool Scanner::ScanEscape() {
   uc32 c = c0_;
-  Advance();
+  Advance<capture_raw>();
 
   // Skip escaped newlines.
-  if (unicode_cache_->IsLineTerminator(c)) {
+  if (!in_template_literal && c0_ >= 0 && unicode_cache_->IsLineTerminator(c)) {
     // Allow CR+LF newlines in multiline string literals.
-    if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance();
+    if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance<capture_raw>();
     // Allow LF+CR newlines in multiline string literals.
-    if (IsLineFeed(c) && IsCarriageReturn(c0_)) Advance();
+    if (IsLineFeed(c) && IsCarriageReturn(c0_)) Advance<capture_raw>();
     return true;
   }
 
@@ -701,24 +721,28 @@
     case 'r' : c = '\r'; break;
     case 't' : c = '\t'; break;
     case 'u' : {
-      c = ScanHexNumber(4);
+      c = ScanUnicodeEscape<capture_raw>();
       if (c < 0) return false;
       break;
     }
-    case 'v' : c = '\v'; break;
-    case 'x' : {
-      c = ScanHexNumber(2);
+    case 'v':
+      c = '\v';
+      break;
+    case 'x': {
+      c = ScanHexNumber<capture_raw>(2);
       if (c < 0) return false;
       break;
     }
-    case '0' :  // fall through
-    case '1' :  // fall through
-    case '2' :  // fall through
-    case '3' :  // fall through
-    case '4' :  // fall through
-    case '5' :  // fall through
-    case '6' :  // fall through
-    case '7' : c = ScanOctalEscape(c, 2); break;
+    case '0':  // Fall through.
+    case '1':  // fall through
+    case '2':  // fall through
+    case '3':  // fall through
+    case '4':  // fall through
+    case '5':  // fall through
+    case '6':  // fall through
+    case '7':
+      c = ScanOctalEscape<capture_raw>(c, 2);
+      break;
   }
 
   // According to ECMA-262, section 7.8.4, characters not covered by the
@@ -731,6 +755,7 @@
 
 // Octal escapes of the forms '\0xx' and '\xxx' are not a part of
 // ECMA-262. Other JS VMs support them.
+template <bool capture_raw>
 uc32 Scanner::ScanOctalEscape(uc32 c, int length) {
   uc32 x = c - '0';
   int i = 0;
@@ -740,7 +765,7 @@
     int nx = x * 8 + d;
     if (nx >= 256) break;
     x = nx;
-    Advance();
+    Advance<capture_raw>();
   }
   // Anything except '\0' is an octal escape sequence, illegal in strict mode.
   // Remember the position of octal escape sequences so that an error
@@ -764,7 +789,7 @@
     uc32 c = c0_;
     Advance();
     if (c == '\\') {
-      if (c0_ < 0 || !ScanEscape()) return Token::ILLEGAL;
+      if (c0_ < 0 || !ScanEscape<false, false>()) return Token::ILLEGAL;
     } else {
       AddLiteralChar(c);
     }
@@ -777,6 +802,96 @@
 }
 
 
+Token::Value Scanner::ScanTemplateSpan() {
+  // When scanning a TemplateSpan, we are looking for the following construct:
+  // TEMPLATE_SPAN ::
+  //     ` LiteralChars* ${
+  //   | } LiteralChars* ${
+  //
+  // TEMPLATE_TAIL ::
+  //     ` LiteralChars* `
+  //   | } LiteralChar* `
+  //
+  // A TEMPLATE_SPAN should always be followed by an Expression, while a
+  // TEMPLATE_TAIL terminates a TemplateLiteral and does not need to be
+  // followed by an Expression.
+
+  Token::Value result = Token::TEMPLATE_SPAN;
+  LiteralScope literal(this);
+  StartRawLiteral();
+  const bool capture_raw = true;
+  const bool in_template_literal = true;
+
+  while (true) {
+    uc32 c = c0_;
+    Advance<capture_raw>();
+    if (c == '`') {
+      result = Token::TEMPLATE_TAIL;
+      ReduceRawLiteralLength(1);
+      break;
+    } else if (c == '$' && c0_ == '{') {
+      Advance<capture_raw>();  // Consume '{'
+      ReduceRawLiteralLength(2);
+      break;
+    } else if (c == '\\') {
+      if (unicode_cache_->IsLineTerminator(c0_)) {
+        // The TV of LineContinuation :: \ LineTerminatorSequence is the empty
+        // code unit sequence.
+        uc32 lastChar = c0_;
+        Advance<capture_raw>();
+        if (lastChar == '\r') {
+          ReduceRawLiteralLength(1);  // Remove \r
+          if (c0_ == '\n') {
+            Advance<capture_raw>();  // Adds \n
+          } else {
+            AddRawLiteralChar('\n');
+          }
+        }
+      } else if (!ScanEscape<capture_raw, in_template_literal>()) {
+        return Token::ILLEGAL;
+      }
+    } else if (c < 0) {
+      // Unterminated template literal
+      PushBack(c);
+      break;
+    } else {
+      // The TRV of LineTerminatorSequence :: <CR> is the CV 0x000A.
+      // The TRV of LineTerminatorSequence :: <CR><LF> is the sequence
+      // consisting of the CV 0x000A.
+      if (c == '\r') {
+        ReduceRawLiteralLength(1);  // Remove \r
+        if (c0_ == '\n') {
+          Advance<capture_raw>();  // Adds \n
+        } else {
+          AddRawLiteralChar('\n');
+        }
+        c = '\n';
+      }
+      AddLiteralChar(c);
+    }
+  }
+  literal.Complete();
+  next_.location.end_pos = source_pos();
+  next_.token = result;
+  return result;
+}
+
+
+Token::Value Scanner::ScanTemplateStart() {
+  DCHECK(c0_ == '`');
+  next_.location.beg_pos = source_pos();
+  Advance();  // Consume `
+  return ScanTemplateSpan();
+}
+
+
+Token::Value Scanner::ScanTemplateContinuation() {
+  DCHECK_EQ(next_.token, Token::RBRACE);
+  next_.location.beg_pos = source_pos() - 1;  // We already consumed }
+  return ScanTemplateSpan();
+}
+
+
 void Scanner::ScanDecimalDigits() {
   while (IsDecimalDigit(c0_))
     AddLiteralCharAdvance();
@@ -880,7 +995,8 @@
   // not be an identifier start or a decimal digit; see ECMA-262
   // section 7.8.3, page 17 (note that we read only one decimal digit
   // if the value is 0).
-  if (IsDecimalDigit(c0_) || unicode_cache_->IsIdentifierStart(c0_))
+  if (IsDecimalDigit(c0_) ||
+      (c0_ >= 0 && unicode_cache_->IsIdentifierStart(c0_)))
     return Token::ILLEGAL;
 
   literal.Complete();
@@ -893,9 +1009,28 @@
   Advance();
   if (c0_ != 'u') return -1;
   Advance();
-  uc32 result = ScanHexNumber(4);
-  if (result < 0) PushBack('u');
-  return result;
+  return ScanUnicodeEscape<false>();
+}
+
+
+template <bool capture_raw>
+uc32 Scanner::ScanUnicodeEscape() {
+  // Accept both \uxxxx and \u{xxxxxx} (if harmony unicode escapes are
+  // allowed). In the latter case, the number of hex digits between { } is
+  // arbitrary. \ and u have already been read.
+  if (c0_ == '{' && HarmonyUnicode()) {
+    Advance<capture_raw>();
+    uc32 cp = ScanUnlimitedLengthHexNumber<capture_raw>(0x10ffff);
+    if (cp < 0) {
+      return -1;
+    }
+    if (c0_ != '}') {
+      return -1;
+    }
+    Advance<capture_raw>();
+    return cp;
+  }
+  return ScanHexNumber<capture_raw>(4);
 }
 
 
@@ -1017,11 +1152,15 @@
 bool Scanner::IdentifierIsFutureStrictReserved(
     const AstRawString* string) const {
   // Keywords are always 1-byte strings.
-  return string->is_one_byte() &&
-         Token::FUTURE_STRICT_RESERVED_WORD ==
-             KeywordOrIdentifierToken(string->raw_data(), string->length(),
-                                      harmony_scoping_, harmony_modules_,
-                                      harmony_classes_);
+  if (!string->is_one_byte()) return false;
+  if (string->IsOneByteEqualTo("let") || string->IsOneByteEqualTo("static") ||
+      string->IsOneByteEqualTo("yield")) {
+    return true;
+  }
+  return Token::FUTURE_STRICT_RESERVED_WORD ==
+         KeywordOrIdentifierToken(string->raw_data(), string->length(),
+                                  harmony_scoping_, harmony_modules_,
+                                  harmony_classes_);
 }
 
 
@@ -1046,7 +1185,7 @@
   AddLiteralChar(first_char);
 
   // Scan the rest of the identifier characters.
-  while (unicode_cache_->IsIdentifierPart(c0_)) {
+  while (c0_ >= 0 && unicode_cache_->IsIdentifierPart(c0_)) {
     if (c0_ != '\\') {
       uc32 next_char = c0_;
       Advance();
@@ -1074,7 +1213,7 @@
 
 Token::Value Scanner::ScanIdentifierSuffix(LiteralScope* literal) {
   // Scan the rest of the identifier characters.
-  while (unicode_cache_->IsIdentifierPart(c0_)) {
+  while (c0_ >= 0 && unicode_cache_->IsIdentifierPart(c0_)) {
     if (c0_ == '\\') {
       uc32 c = ScanIdentifierUnicodeEscape();
       // Only allow legal identifier part characters.
@@ -1113,10 +1252,10 @@
   }
 
   while (c0_ != '/' || in_character_class) {
-    if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
+    if (c0_ < 0 || unicode_cache_->IsLineTerminator(c0_)) return false;
     if (c0_ == '\\') {  // Escape sequence.
       AddLiteralCharAdvance();
-      if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
+      if (c0_ < 0 || unicode_cache_->IsLineTerminator(c0_)) return false;
       AddLiteralCharAdvance();
       // If the escape allows more characters, i.e., \x??, \u????, or \c?,
       // only "safe" characters are allowed (letters, digits, underscore),
@@ -1142,47 +1281,14 @@
 }
 
 
-bool Scanner::ScanLiteralUnicodeEscape() {
-  DCHECK(c0_ == '\\');
-  uc32 chars_read[6] = {'\\', 'u', 0, 0, 0, 0};
-  Advance();
-  int i = 1;
-  if (c0_ == 'u') {
-    i++;
-    while (i < 6) {
-      Advance();
-      if (!IsHexDigit(c0_)) break;
-      chars_read[i] = c0_;
-      i++;
-    }
-  }
-  if (i < 6) {
-    // Incomplete escape. Undo all advances and return false.
-    while (i > 0) {
-      i--;
-      PushBack(chars_read[i]);
-    }
-    return false;
-  }
-  // Complete escape. Add all chars to current literal buffer.
-  for (int i = 0; i < 6; i++) {
-    AddLiteralChar(chars_read[i]);
-  }
-  return true;
-}
-
-
 bool Scanner::ScanRegExpFlags() {
   // Scan regular expression flags.
   LiteralScope literal(this);
-  while (unicode_cache_->IsIdentifierPart(c0_)) {
+  while (c0_ >= 0 && unicode_cache_->IsIdentifierPart(c0_)) {
     if (c0_ != '\\') {
       AddLiteralCharAdvance();
     } else {
-      if (!ScanLiteralUnicodeEscape()) {
-        break;
-      }
-      Advance();
+      return false;
     }
   }
   literal.Complete();
@@ -1208,6 +1314,15 @@
 }
 
 
+const AstRawString* Scanner::CurrentRawSymbol(
+    AstValueFactory* ast_value_factory) {
+  if (is_raw_literal_one_byte()) {
+    return ast_value_factory->GetOneByteString(raw_literal_one_byte_string());
+  }
+  return ast_value_factory->GetTwoByteString(raw_literal_two_byte_string());
+}
+
+
 double Scanner::DoubleValue() {
   DCHECK(is_literal_one_byte());
   return StringToDouble(
diff --git a/src/scanner.h b/src/scanner.h
index 356c8e4..6e668fd 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -15,6 +15,7 @@
 #include "src/list.h"
 #include "src/token.h"
 #include "src/unicode-inl.h"
+#include "src/unicode-decoder.h"
 #include "src/utils.h"
 
 namespace v8 {
@@ -211,9 +212,18 @@
       }
       ConvertToTwoByte();
     }
-    DCHECK(code_unit < 0x10000u);
-    *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = code_unit;
-    position_ += kUC16Size;
+    if (code_unit <= unibrow::Utf16::kMaxNonSurrogateCharCode) {
+      *reinterpret_cast<uint16_t*>(&backing_store_[position_]) = code_unit;
+      position_ += kUC16Size;
+    } else {
+      *reinterpret_cast<uint16_t*>(&backing_store_[position_]) =
+          unibrow::Utf16::LeadSurrogate(code_unit);
+      position_ += kUC16Size;
+      if (position_ >= backing_store_.length()) ExpandBuffer();
+      *reinterpret_cast<uint16_t*>(&backing_store_[position_]) =
+          unibrow::Utf16::TrailSurrogate(code_unit);
+      position_ += kUC16Size;
+    }
   }
 
   bool is_one_byte() const { return is_one_byte_; }
@@ -242,6 +252,10 @@
     return is_one_byte_ ? position_ : (position_ >> 1);
   }
 
+  void ReduceLength(int delta) {
+    position_ -= delta * (is_one_byte_ ? kOneByteSize : kUC16Size);
+  }
+
   void Reset() {
     position_ = 0;
     is_one_byte_ = true;
@@ -308,15 +322,13 @@
   // if aborting the scanning before it's complete.
   class LiteralScope {
    public:
-    explicit LiteralScope(Scanner* self)
-        : scanner_(self), complete_(false) {
+    explicit LiteralScope(Scanner* self) : scanner_(self), complete_(false) {
       scanner_->StartLiteral();
     }
      ~LiteralScope() {
        if (!complete_) scanner_->DropLiteral();
      }
     void Complete() {
-      scanner_->TerminateLiteral();
       complete_ = true;
     }
 
@@ -382,18 +394,23 @@
 
   const AstRawString* CurrentSymbol(AstValueFactory* ast_value_factory);
   const AstRawString* NextSymbol(AstValueFactory* ast_value_factory);
+  const AstRawString* CurrentRawSymbol(AstValueFactory* ast_value_factory);
 
   double DoubleValue();
-  bool UnescapedLiteralMatches(const char* data, int length) {
+  bool LiteralMatches(const char* data, int length, bool allow_escapes = true) {
     if (is_literal_one_byte() &&
         literal_length() == length &&
-        !literal_contains_escapes()) {
+        (allow_escapes || !literal_contains_escapes())) {
       const char* token =
           reinterpret_cast<const char*>(literal_one_byte_string().start());
       return !strncmp(token, data, length);
     }
     return false;
   }
+  inline bool UnescapedLiteralMatches(const char* data, int length) {
+    return LiteralMatches(data, length, false);
+  }
+
   void IsGetOrSet(bool* is_get, bool* is_set) {
     if (is_literal_one_byte() &&
         literal_length() == 3 &&
@@ -444,6 +461,10 @@
   void SetHarmonyClasses(bool classes) {
     harmony_classes_ = classes;
   }
+  bool HarmonyTemplates() const { return harmony_templates_; }
+  void SetHarmonyTemplates(bool templates) { harmony_templates_ = templates; }
+  bool HarmonyUnicode() const { return harmony_unicode_; }
+  void SetHarmonyUnicode(bool unicode) { harmony_unicode_ = unicode; }
 
   // Returns true if there was a line terminator before the peek'ed token,
   // possibly inside a multi-line comment.
@@ -459,6 +480,10 @@
   // be empty).
   bool ScanRegExpFlags();
 
+  // Scans the input as a template literal
+  Token::Value ScanTemplateStart();
+  Token::Value ScanTemplateContinuation();
+
   const LiteralBuffer* source_url() const { return &source_url_; }
   const LiteralBuffer* source_mapping_url() const {
     return &source_mapping_url_;
@@ -472,11 +497,13 @@
     Token::Value token;
     Location location;
     LiteralBuffer* literal_chars;
+    LiteralBuffer* raw_literal_chars;
   };
 
   static const int kCharacterLookaheadBufferSize = 1;
 
   // Scans octal escape sequence. Also accepts "\0" decimal escape sequence.
+  template <bool capture_raw>
   uc32 ScanOctalEscape(uc32 c, int length);
 
   // Call this after setting source_ to the input.
@@ -486,6 +513,7 @@
     Advance();
     // Initialize current_ to not refer to a literal.
     current_.literal_chars = NULL;
+    current_.raw_literal_chars = NULL;
   }
 
   // Literal buffer support
@@ -496,20 +524,31 @@
     next_.literal_chars = free_buffer;
   }
 
+  inline void StartRawLiteral() {
+    raw_literal_buffer_.Reset();
+    next_.raw_literal_chars = &raw_literal_buffer_;
+  }
+
   INLINE(void AddLiteralChar(uc32 c)) {
     DCHECK_NOT_NULL(next_.literal_chars);
     next_.literal_chars->AddChar(c);
   }
 
-  // Complete scanning of a literal.
-  inline void TerminateLiteral() {
-    // Does nothing in the current implementation.
+  INLINE(void AddRawLiteralChar(uc32 c)) {
+    DCHECK_NOT_NULL(next_.raw_literal_chars);
+    next_.raw_literal_chars->AddChar(c);
+  }
+
+  INLINE(void ReduceRawLiteralLength(int delta)) {
+    DCHECK_NOT_NULL(next_.raw_literal_chars);
+    next_.raw_literal_chars->ReduceLength(delta);
   }
 
   // Stops scanning of a literal and drop the collected characters,
   // e.g., due to an encountered error.
   inline void DropLiteral() {
     next_.literal_chars = NULL;
+    next_.raw_literal_chars = NULL;
   }
 
   inline void AddLiteralCharAdvance() {
@@ -518,9 +557,29 @@
   }
 
   // Low-level scanning support.
-  void Advance() { c0_ = source_->Advance(); }
+  template <bool capture_raw = false>
+  void Advance() {
+    if (capture_raw) {
+      AddRawLiteralChar(c0_);
+    }
+    c0_ = source_->Advance();
+    if (unibrow::Utf16::IsLeadSurrogate(c0_)) {
+      uc32 c1 = source_->Advance();
+      if (!unibrow::Utf16::IsTrailSurrogate(c1)) {
+        source_->PushBack(c1);
+      } else {
+        c0_ = unibrow::Utf16::CombineSurrogatePair(c0_, c1);
+      }
+    }
+  }
+
   void PushBack(uc32 ch) {
-    source_->PushBack(c0_);
+    if (ch > static_cast<uc32>(unibrow::Utf16::kMaxNonSurrogateCharCode)) {
+      source_->PushBack(unibrow::Utf16::TrailSurrogate(c0_));
+      source_->PushBack(unibrow::Utf16::LeadSurrogate(c0_));
+    } else {
+      source_->PushBack(c0_);
+    }
     c0_ = ch;
   }
 
@@ -541,10 +600,11 @@
 
   // Returns the literal string, if any, for the current token (the
   // token last returned by Next()). The string is 0-terminated.
-  // Literal strings are collected for identifiers, strings, and
-  // numbers.
-  // These functions only give the correct result if the literal
-  // was scanned between calls to StartLiteral() and TerminateLiteral().
+  // Literal strings are collected for identifiers, strings, numbers as well
+  // as for template literals. For template literals we also collect the raw
+  // form.
+  // These functions only give the correct result if the literal was scanned
+  // when a LiteralScope object is alive.
   Vector<const uint8_t> literal_one_byte_string() {
     DCHECK_NOT_NULL(current_.literal_chars);
     return current_.literal_chars->one_byte_literal();
@@ -575,12 +635,26 @@
     DCHECK_NOT_NULL(next_.literal_chars);
     return next_.literal_chars->is_one_byte();
   }
-  int next_literal_length() const {
-    DCHECK_NOT_NULL(next_.literal_chars);
-    return next_.literal_chars->length();
+  Vector<const uint8_t> raw_literal_one_byte_string() {
+    DCHECK_NOT_NULL(current_.raw_literal_chars);
+    return current_.raw_literal_chars->one_byte_literal();
+  }
+  Vector<const uint16_t> raw_literal_two_byte_string() {
+    DCHECK_NOT_NULL(current_.raw_literal_chars);
+    return current_.raw_literal_chars->two_byte_literal();
+  }
+  bool is_raw_literal_one_byte() {
+    DCHECK_NOT_NULL(current_.raw_literal_chars);
+    return current_.raw_literal_chars->is_one_byte();
   }
 
+  template <bool capture_raw>
   uc32 ScanHexNumber(int expected_length);
+  // Scan a number of any length but not bigger than max_value. For example, the
+  // number can be 000000001, so it's very long in characters but its value is
+  // small.
+  template <bool capture_raw>
+  uc32 ScanUnlimitedLengthHexNumber(int max_value);
 
   // Scans a single JavaScript token.
   void Scan();
@@ -603,14 +677,17 @@
   // 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.
+  template <bool capture_raw, bool in_template_literal>
   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();
-  // Scans a Unicode escape-sequence and adds its characters,
-  // uninterpreted, to the current literal. Used for parsing RegExp
-  // flags.
-  bool ScanLiteralUnicodeEscape();
+  // Helper for the above functions.
+  template <bool capture_raw>
+  uc32 ScanUnicodeEscape();
+
+  Token::Value ScanTemplateSpan();
 
   // Return the current source position.
   int source_pos() {
@@ -627,6 +704,9 @@
   LiteralBuffer source_url_;
   LiteralBuffer source_mapping_url_;
 
+  // Buffer to store raw string values
+  LiteralBuffer raw_literal_buffer_;
+
   TokenDesc current_;  // desc for current token (as returned by Next())
   TokenDesc next_;     // desc for next token (one token look-ahead)
 
@@ -655,6 +735,10 @@
   bool harmony_numeric_literals_;
   // Whether we scan 'class', 'extends', 'static' and 'super' as keywords.
   bool harmony_classes_;
+  // Whether we scan TEMPLATE_SPAN and TEMPLATE_TAIL
+  bool harmony_templates_;
+  // Whether we allow \u{xxxxx}.
+  bool harmony_unicode_;
 };
 
 } }  // namespace v8::internal
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index 75bf014..b9cb6f3 100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -170,11 +170,11 @@
     int context_locals = ContextLocalCount();
     bool function_name_context_slot =
         FunctionVariableField::decode(Flags()) == CONTEXT;
-    bool has_context = context_locals > 0 ||
-        function_name_context_slot ||
-        scope_type() == WITH_SCOPE ||
-        (scope_type() == FUNCTION_SCOPE && CallsEval()) ||
-        scope_type() == MODULE_SCOPE;
+    bool has_context = context_locals > 0 || function_name_context_slot ||
+                       scope_type() == WITH_SCOPE ||
+                       (scope_type() == ARROW_SCOPE && CallsEval()) ||
+                       (scope_type() == FUNCTION_SCOPE && CallsEval()) ||
+                       scope_type() == MODULE_SCOPE;
     if (has_context) {
       return Context::MIN_CONTEXT_SLOTS + context_locals +
           (function_name_context_slot ? 1 : 0);
@@ -380,13 +380,14 @@
   for (int i = 0; i < local_count; ++i) {
     if (scope_info->LocalIsSynthetic(first_context_var + i)) continue;
     int context_index = Context::MIN_CONTEXT_SLOTS + i;
+    Handle<Object> value = Handle<Object>(context->get(context_index), isolate);
+    // Do not reflect variables under TDZ in scope object.
+    if (value->IsTheHole()) continue;
     RETURN_ON_EXCEPTION_VALUE(
-        isolate,
-        Runtime::DefineObjectProperty(
-            scope_object,
-            Handle<String>(String::cast(scope_info->get(i + start))),
-            Handle<Object>(context->get(context_index), isolate),
-            ::NONE),
+        isolate, Runtime::DefineObjectProperty(
+                     scope_object,
+                     Handle<String>(String::cast(scope_info->get(i + start))),
+                     value, ::NONE),
         false);
   }
   return true;
diff --git a/src/scopes.cc b/src/scopes.cc
index 440c7f2..39b67a8 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -78,14 +78,14 @@
       unresolved_(16, zone),
       decls_(4, zone),
       interface_(FLAG_harmony_modules &&
-                 (scope_type == MODULE_SCOPE || scope_type == GLOBAL_SCOPE)
+                 (scope_type == MODULE_SCOPE || scope_type == SCRIPT_SCOPE)
                      ? Interface::NewModule(zone) : NULL),
       already_resolved_(false),
       ast_value_factory_(ast_value_factory),
       zone_(zone) {
   SetDefaults(scope_type, outer_scope, Handle<ScopeInfo>::null());
-  // The outermost scope must be a global scope.
-  DCHECK(scope_type == GLOBAL_SCOPE || outer_scope != NULL);
+  // The outermost scope must be a script scope.
+  DCHECK(scope_type == SCRIPT_SCOPE || outer_scope != NULL);
   DCHECK(!HasIllegalRedeclaration());
 }
 
@@ -160,12 +160,20 @@
   scope_inside_with_ = false;
   scope_contains_with_ = false;
   scope_calls_eval_ = false;
+  scope_uses_arguments_ = false;
+  scope_uses_super_property_ = false;
+  scope_uses_super_constructor_call_ = false;
+  scope_uses_this_ = false;
   asm_module_ = false;
   asm_function_ = outer_scope != NULL && outer_scope->asm_module_;
   // Inherit the strict mode from the parent scope.
   strict_mode_ = outer_scope != NULL ? outer_scope->strict_mode_ : SLOPPY;
   outer_scope_calls_sloppy_eval_ = false;
   inner_scope_calls_eval_ = false;
+  inner_scope_uses_arguments_ = false;
+  inner_scope_uses_this_ = false;
+  inner_scope_uses_super_property_ = false;
+  inner_scope_uses_super_constructor_call_ = false;
   force_eager_compilation_ = false;
   force_context_allocation_ = (outer_scope != NULL && !is_function_scope())
       ? outer_scope->has_forced_context_allocation() : false;
@@ -184,7 +192,7 @@
 }
 
 
-Scope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope,
+Scope* Scope::DeserializeScopeChain(Context* context, Scope* script_scope,
                                     Zone* zone) {
   // Reconstruct the outer scope chain from a closure's context chain.
   Scope* current_scope = NULL;
@@ -195,7 +203,7 @@
       Scope* with_scope = new(zone) Scope(current_scope,
                                           WITH_SCOPE,
                                           Handle<ScopeInfo>::null(),
-                                          global_scope->ast_value_factory_,
+                                          script_scope->ast_value_factory_,
                                           zone);
       current_scope = with_scope;
       // All the inner scopes are inside a with.
@@ -203,26 +211,26 @@
       for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) {
         s->scope_inside_with_ = true;
       }
-    } else if (context->IsGlobalContext()) {
+    } else if (context->IsScriptContext()) {
       ScopeInfo* scope_info = ScopeInfo::cast(context->extension());
       current_scope = new(zone) Scope(current_scope,
-                                      GLOBAL_SCOPE,
+                                      SCRIPT_SCOPE,
                                       Handle<ScopeInfo>(scope_info),
-                                      global_scope->ast_value_factory_,
+                                      script_scope->ast_value_factory_,
                                       zone);
     } else if (context->IsModuleContext()) {
       ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info());
       current_scope = new(zone) Scope(current_scope,
                                       MODULE_SCOPE,
                                       Handle<ScopeInfo>(scope_info),
-                                      global_scope->ast_value_factory_,
+                                      script_scope->ast_value_factory_,
                                       zone);
     } else if (context->IsFunctionContext()) {
       ScopeInfo* scope_info = context->closure()->shared()->scope_info();
       current_scope = new(zone) Scope(current_scope,
                                       FUNCTION_SCOPE,
                                       Handle<ScopeInfo>(scope_info),
-                                      global_scope->ast_value_factory_,
+                                      script_scope->ast_value_factory_,
                                       zone);
       if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true;
       if (scope_info->IsAsmModule()) current_scope->asm_module_ = true;
@@ -231,15 +239,15 @@
       current_scope = new(zone) Scope(current_scope,
                                       BLOCK_SCOPE,
                                       Handle<ScopeInfo>(scope_info),
-                                      global_scope->ast_value_factory_,
+                                      script_scope->ast_value_factory_,
                                       zone);
     } else {
       DCHECK(context->IsCatchContext());
       String* name = String::cast(context->extension());
       current_scope = new (zone) Scope(
           current_scope,
-          global_scope->ast_value_factory_->GetString(Handle<String>(name)),
-          global_scope->ast_value_factory_, zone);
+          script_scope->ast_value_factory_->GetString(Handle<String>(name)),
+          script_scope->ast_value_factory_, zone);
     }
     if (contains_with) current_scope->RecordWithStatement();
     if (innermost_scope == NULL) innermost_scope = current_scope;
@@ -251,9 +259,9 @@
     context = context->previous();
   }
 
-  global_scope->AddInnerScope(current_scope);
-  global_scope->PropagateScopeInfo(false);
-  return (innermost_scope == NULL) ? global_scope : innermost_scope;
+  script_scope->AddInnerScope(current_scope);
+  script_scope->PropagateScopeInfo(false);
+  return (innermost_scope == NULL) ? script_scope : innermost_scope;
 }
 
 
@@ -264,15 +272,14 @@
 
   // Traverse the scope tree up to the first unresolved scope or the global
   // scope and start scope resolution and variable allocation from that scope.
-  while (!top->is_global_scope() &&
+  while (!top->is_script_scope() &&
          !top->outer_scope()->already_resolved()) {
     top = top->outer_scope();
   }
 
   // Allocate the variables.
   {
-    AstNodeFactory<AstNullVisitor> ast_node_factory(
-        info->zone(), info->ast_value_factory(), info->ast_node_id_gen());
+    AstNodeFactory ast_node_factory(info->ast_value_factory());
     if (!top->AllocateVariables(info, &ast_node_factory)) return false;
   }
 
@@ -283,7 +290,7 @@
     scope->Print();
   }
 
-  if (FLAG_harmony_modules && FLAG_print_interfaces && top->is_global_scope()) {
+  if (FLAG_harmony_modules && FLAG_print_interfaces && top->is_script_scope()) {
     PrintF("global : ");
     top->interface()->Print();
   }
@@ -306,9 +313,9 @@
   }
 
   // Declare convenience variables.
-  // Declare and allocate receiver (even for the global scope, and even
+  // Declare and allocate receiver (even for the script scope, and even
   // if naccesses_ == 0).
-  // NOTE: When loading parameters in the global scope, we must take
+  // NOTE: When loading parameters in the script scope, we must take
   // care not to access them as properties of the global object, but
   // instead load them directly from the stack. Currently, the only
   // such parameter is 'this' which is passed on the stack when
@@ -368,6 +375,13 @@
     outer_scope()->unresolved_.Add(unresolved_[i], zone());
   }
 
+  // Propagate usage flags to outer scope.
+  if (uses_arguments()) outer_scope_->RecordArgumentsUsage();
+  if (uses_super_property()) outer_scope_->RecordSuperPropertyUsage();
+  if (uses_super_constructor_call())
+    outer_scope_->RecordSuperConstructorCallUsage();
+  if (uses_this()) outer_scope_->RecordThisUsage();
+
   return NULL;
 }
 
@@ -414,7 +428,7 @@
 
 
 Variable* Scope::LookupFunctionVar(const AstRawString* name,
-                                   AstNodeFactory<AstNullVisitor>* factory) {
+                                   AstNodeFactory* factory) {
   if (function_ != NULL && function_->proxy()->raw_name() == name) {
     return function_->proxy()->var();
   } else if (!scope_info_.is_null()) {
@@ -474,7 +488,7 @@
 
 
 Variable* Scope::DeclareDynamicGlobal(const AstRawString* name) {
-  DCHECK(is_global_scope());
+  DCHECK(is_script_scope());
   return variables_.Declare(this,
                             name,
                             DYNAMIC_GLOBAL,
@@ -633,8 +647,7 @@
 }
 
 
-bool Scope::AllocateVariables(CompilationInfo* info,
-                              AstNodeFactory<AstNullVisitor>* factory) {
+bool Scope::AllocateVariables(CompilationInfo* info, AstNodeFactory* factory) {
   // 1) Propagate scope information.
   bool outer_scope_calls_sloppy_eval = false;
   if (outer_scope_ != NULL) {
@@ -645,7 +658,7 @@
   PropagateScopeInfo(outer_scope_calls_sloppy_eval);
 
   // 2) Allocate module instances.
-  if (FLAG_harmony_modules && (is_global_scope() || is_module_scope())) {
+  if (FLAG_harmony_modules && (is_script_scope() || is_module_scope())) {
     DCHECK(num_modules_ == 0);
     AllocateModulesRecursively(this);
   }
@@ -725,9 +738,9 @@
 }
 
 
-Scope* Scope::GlobalScope() {
+Scope* Scope::ScriptScope() {
   Scope* scope = this;
-  while (!scope->is_global_scope()) {
+  while (!scope->is_script_scope()) {
     scope = scope->outer_scope();
   }
   return scope;
@@ -775,10 +788,11 @@
     case EVAL_SCOPE: return "eval";
     case FUNCTION_SCOPE: return "function";
     case MODULE_SCOPE: return "module";
-    case GLOBAL_SCOPE: return "global";
+    case SCRIPT_SCOPE: return "global";
     case CATCH_SCOPE: return "catch";
     case BLOCK_SCOPE: return "block";
     case WITH_SCOPE: return "with";
+    case ARROW_SCOPE: return "arrow";
   }
   UNREACHABLE();
   return NULL;
@@ -885,6 +899,21 @@
   if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n");
   if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n");
   if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
+  if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n");
+  if (scope_uses_super_property_)
+    Indent(n1, "// scope uses 'super' property\n");
+  if (scope_uses_super_constructor_call_)
+    Indent(n1, "// scope uses 'super' constructor\n");
+  if (scope_uses_this_) Indent(n1, "// scope uses 'this'\n");
+  if (inner_scope_uses_arguments_) {
+    Indent(n1, "// inner scope uses 'arguments'\n");
+  }
+  if (inner_scope_uses_super_property_)
+    Indent(n1, "// inner scope uses 'super' property\n");
+  if (inner_scope_uses_super_constructor_call_) {
+    Indent(n1, "// inner scope uses 'super' constructor\n");
+  }
+  if (inner_scope_uses_this_) Indent(n1, "// inner scope uses 'this'\n");
   if (outer_scope_calls_sloppy_eval_) {
     Indent(n1, "// outer scope calls 'eval' in sloppy context\n");
   }
@@ -962,7 +991,7 @@
 
 Variable* Scope::LookupRecursive(VariableProxy* proxy,
                                  BindingKind* binding_kind,
-                                 AstNodeFactory<AstNullVisitor>* factory) {
+                                 AstNodeFactory* factory) {
   DCHECK(binding_kind != NULL);
   if (already_resolved() && is_with_scope()) {
     // Short-cut: if the scope is deserialized from a scope info, variable
@@ -995,7 +1024,7 @@
       var->ForceContextAllocation();
     }
   } else {
-    DCHECK(is_global_scope());
+    DCHECK(is_script_scope());
   }
 
   if (is_with_scope()) {
@@ -1024,14 +1053,13 @@
 }
 
 
-bool Scope::ResolveVariable(CompilationInfo* info,
-                            VariableProxy* proxy,
-                            AstNodeFactory<AstNullVisitor>* factory) {
-  DCHECK(info->global_scope()->is_global_scope());
+bool Scope::ResolveVariable(CompilationInfo* info, VariableProxy* proxy,
+                            AstNodeFactory* factory) {
+  DCHECK(info->script_scope()->is_script_scope());
 
   // If the proxy is already resolved there's nothing to do
   // (functions and consts may be resolved by the parser).
-  if (proxy->var() != NULL) return true;
+  if (proxy->is_resolved()) return true;
 
   // Otherwise, try to resolve the variable.
   BindingKind binding_kind;
@@ -1059,7 +1087,7 @@
 
     case UNBOUND:
       // No binding has been found. Declare a variable on the global object.
-      var = info->global_scope()->DeclareDynamicGlobal(proxy->raw_name());
+      var = info->script_scope()->DeclareDynamicGlobal(proxy->raw_name());
       break;
 
     case UNBOUND_EVAL_SHADOWED:
@@ -1076,21 +1104,6 @@
   DCHECK(var != NULL);
   if (proxy->is_assigned()) var->set_maybe_assigned();
 
-  if (FLAG_harmony_scoping && strict_mode() == STRICT &&
-      var->is_const_mode() && proxy->is_assigned()) {
-    // Assignment to const. Throw a syntax error.
-    MessageLocation location(
-        info->script(), proxy->position(), proxy->position());
-    Isolate* isolate = info->isolate();
-    Factory* factory = isolate->factory();
-    Handle<JSArray> array = factory->NewJSArray(0);
-    Handle<Object> error;
-    MaybeHandle<Object> maybe_error =
-        factory->NewSyntaxError("harmony_const_assign", array);
-    if (maybe_error.ToHandle(&error)) isolate->Throw(*error, &location);
-    return false;
-  }
-
   if (FLAG_harmony_modules) {
     bool ok;
 #ifdef DEBUG
@@ -1133,10 +1146,9 @@
 }
 
 
-bool Scope::ResolveVariablesRecursively(
-    CompilationInfo* info,
-    AstNodeFactory<AstNullVisitor>* factory) {
-  DCHECK(info->global_scope()->is_global_scope());
+bool Scope::ResolveVariablesRecursively(CompilationInfo* info,
+                                        AstNodeFactory* factory) {
+  DCHECK(info->script_scope()->is_script_scope());
 
   // Resolve unresolved variables for this scope.
   for (int i = 0; i < unresolved_.length(); i++) {
@@ -1166,6 +1178,25 @@
     if (inner->scope_calls_eval_ || inner->inner_scope_calls_eval_) {
       inner_scope_calls_eval_ = true;
     }
+    // If the inner scope is an arrow function, propagate the flags tracking
+    // usage of arguments/super/this, but do not propagate them out from normal
+    // functions.
+    if (!inner->is_function_scope() || inner->is_arrow_scope()) {
+      if (inner->scope_uses_arguments_ || inner->inner_scope_uses_arguments_) {
+        inner_scope_uses_arguments_ = true;
+      }
+      if (inner->scope_uses_super_property_ ||
+          inner->inner_scope_uses_super_property_) {
+        inner_scope_uses_super_property_ = true;
+      }
+      if (inner->uses_super_constructor_call() ||
+          inner->inner_scope_uses_super_constructor_call_) {
+        inner_scope_uses_super_constructor_call_ = true;
+      }
+      if (inner->scope_uses_this_ || inner->inner_scope_uses_this_) {
+        inner_scope_uses_this_ = true;
+      }
+    }
     if (inner->force_eager_compilation_) {
       force_eager_compilation_ = true;
     }
@@ -1188,7 +1219,7 @@
        is_catch_scope() ||
        is_block_scope() ||
        is_module_scope() ||
-       is_global_scope())) {
+       is_script_scope())) {
     var->set_is_used();
     if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned();
   }
@@ -1211,7 +1242,7 @@
   if (var->mode() == TEMPORARY) return false;
   if (var->mode() == INTERNAL) return true;
   if (is_catch_scope() || is_block_scope() || is_module_scope()) return true;
-  if (is_global_scope() && IsLexicalVariableMode(var->mode())) return true;
+  if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true;
   return var->has_forced_context_allocation() ||
       scope_calls_eval_ ||
       inner_scope_calls_eval_ ||
diff --git a/src/scopes.h b/src/scopes.h
index 06c6c99..8d79006 100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -80,7 +80,7 @@
   // doesn't re-allocate variables repeatedly.
   static bool Analyze(CompilationInfo* info);
 
-  static Scope* DeserializeScopeChain(Context* context, Scope* global_scope,
+  static Scope* DeserializeScopeChain(Context* context, Scope* script_scope,
                                       Zone* zone);
 
   // The scope name is only used for printing/debugging.
@@ -108,7 +108,7 @@
   // the name of named function literal is kept in an intermediate scope
   // in between this scope and the next outer scope.)
   Variable* LookupFunctionVar(const AstRawString* name,
-                              AstNodeFactory<AstNullVisitor>* factory);
+                              AstNodeFactory* factory);
 
   // Lookup a variable in this scope or outer scopes.
   // Returns the variable or NULL if not found.
@@ -135,14 +135,13 @@
                          Interface* interface = Interface::NewValue());
 
   // Declare an implicit global variable in this scope which must be a
-  // global scope.  The variable was introduced (possibly from an inner
+  // script scope.  The variable was introduced (possibly from an inner
   // scope) by a reference to an unresolved variable with no intervening
   // with statements or eval calls.
   Variable* DeclareDynamicGlobal(const AstRawString* name);
 
   // Create a new unresolved variable.
-  template<class Visitor>
-  VariableProxy* NewUnresolved(AstNodeFactory<Visitor>* factory,
+  VariableProxy* NewUnresolved(AstNodeFactory* factory,
                                const AstRawString* name,
                                Interface* interface = Interface::NewValue(),
                                int position = RelocInfo::kNoPosition) {
@@ -209,7 +208,21 @@
   void RecordWithStatement() { scope_contains_with_ = true; }
 
   // Inform the scope that the corresponding code contains an eval call.
-  void RecordEvalCall() { if (!is_global_scope()) scope_calls_eval_ = true; }
+  void RecordEvalCall() { if (!is_script_scope()) scope_calls_eval_ = true; }
+
+  // Inform the scope that the corresponding code uses "arguments".
+  void RecordArgumentsUsage() { scope_uses_arguments_ = true; }
+
+  // Inform the scope that the corresponding code uses "super".
+  void RecordSuperPropertyUsage() { scope_uses_super_property_ = true; }
+
+  // Inform the scope that the corresponding code invokes "super" constructor.
+  void RecordSuperConstructorCallUsage() {
+    scope_uses_super_constructor_call_ = true;
+  }
+
+  // Inform the scope that the corresponding code uses "this".
+  void RecordThisUsage() { scope_uses_this_ = true; }
 
   // Set the strict mode flag (unless disabled by a global flag).
   void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
@@ -262,15 +275,18 @@
 
   // Specific scope types.
   bool is_eval_scope() const { return scope_type_ == EVAL_SCOPE; }
-  bool is_function_scope() const { return scope_type_ == FUNCTION_SCOPE; }
+  bool is_function_scope() const {
+    return scope_type_ == FUNCTION_SCOPE || scope_type_ == ARROW_SCOPE;
+  }
   bool is_module_scope() const { return scope_type_ == MODULE_SCOPE; }
-  bool is_global_scope() const { return scope_type_ == GLOBAL_SCOPE; }
+  bool is_script_scope() const { return scope_type_ == SCRIPT_SCOPE; }
   bool is_catch_scope() const { return scope_type_ == CATCH_SCOPE; }
   bool is_block_scope() const { return scope_type_ == BLOCK_SCOPE; }
   bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
+  bool is_arrow_scope() const { return scope_type_ == ARROW_SCOPE; }
   bool is_declaration_scope() const {
     return is_eval_scope() || is_function_scope() ||
-        is_module_scope() || is_global_scope();
+        is_module_scope() || is_script_scope();
   }
   bool is_strict_eval_scope() const {
     return is_eval_scope() && strict_mode_ == STRICT;
@@ -292,6 +308,29 @@
   // Does this scope contain a with statement.
   bool contains_with() const { return scope_contains_with_; }
 
+  // Does this scope access "arguments".
+  bool uses_arguments() const { return scope_uses_arguments_; }
+  // Does any inner scope access "arguments".
+  bool inner_uses_arguments() const { return inner_scope_uses_arguments_; }
+  // Does this scope access "super" property (super.foo).
+  bool uses_super_property() const { return scope_uses_super_property_; }
+  // Does any inner scope access "super" property.
+  bool inner_uses_super_property() const {
+    return inner_scope_uses_super_property_;
+  }
+  // Does this scope calls "super" constructor.
+  bool uses_super_constructor_call() const {
+    return scope_uses_super_constructor_call_;
+  }
+  // Does  any inner scope calls "super" constructor.
+  bool inner_uses_super_constructor_call() const {
+    return inner_scope_uses_super_constructor_call_;
+  }
+  // Does this scope access "this".
+  bool uses_this() const { return scope_uses_this_; }
+  // Does any inner scope access "this".
+  bool inner_uses_this() const { return inner_scope_uses_this_; }
+
   // ---------------------------------------------------------------------------
   // Accessors.
 
@@ -354,7 +393,7 @@
   int StackLocalCount() const;
   int ContextLocalCount() const;
 
-  // For global scopes, the number of module literals (including nested ones).
+  // For script scopes, the number of module literals (including nested ones).
   int num_modules() const { return num_modules_; }
 
   // For module scopes, the host scope's internal variable binding this module.
@@ -378,8 +417,10 @@
   // The number of contexts between this and scope; zero if this == scope.
   int ContextChainLength(Scope* scope);
 
-  // Find the innermost global scope.
-  Scope* GlobalScope();
+  // Find the script scope.
+  // Used in modules implemenetation to find hosting scope.
+  // TODO(rossberg): is this needed?
+  Scope* ScriptScope();
 
   // Find the first function, global, or eval scope.  This is the scope
   // where var declarations will be hoisted to in the implementation.
@@ -431,7 +472,7 @@
 
   // The variables declared in this scope:
   //
-  // All user-declared variables (incl. parameters).  For global scopes
+  // All user-declared variables (incl. parameters).  For script scopes
   // variables may be implicitly 'declared' by being used (possibly in
   // an inner scope) with no intervening with statements or eval calls.
   VariableMap variables_;
@@ -468,6 +509,14 @@
   // This scope or a nested catch scope or with scope contain an 'eval' call. At
   // the 'eval' call site this scope is the declaration scope.
   bool scope_calls_eval_;
+  // This scope uses "arguments".
+  bool scope_uses_arguments_;
+  // This scope uses "super" property ('super.foo').
+  bool scope_uses_super_property_;
+  // This scope uses "super" constructor ('super(..)').
+  bool scope_uses_super_constructor_call_;
+  // This scope uses "this".
+  bool scope_uses_this_;
   // This scope contains an "use asm" annotation.
   bool asm_module_;
   // This scope's outer context is an asm module.
@@ -481,6 +530,10 @@
   // Computed via PropagateScopeInfo.
   bool outer_scope_calls_sloppy_eval_;
   bool inner_scope_calls_eval_;
+  bool inner_scope_uses_arguments_;
+  bool inner_scope_uses_super_property_;
+  bool inner_scope_uses_super_constructor_call_;
+  bool inner_scope_uses_this_;
   bool force_eager_compilation_;
   bool force_context_allocation_;
 
@@ -531,14 +584,14 @@
     // The variable reference could not be statically resolved to any binding
     // and thus should be considered referencing a global variable. NULL is
     // returned. The variable reference is not inside any 'with' statement and
-    // no scope between the reference scope (inclusive) and global scope
+    // no scope between the reference scope (inclusive) and script scope
     // (exclusive) makes a sloppy 'eval' call.
     UNBOUND,
 
     // The variable reference could not be statically resolved to any binding
     // NULL is returned. The variable reference is not inside any 'with'
     // statement, but some scope between the reference scope (inclusive) and
-    // global scope (exclusive) makes a sloppy 'eval' call, that might
+    // script scope (exclusive) makes a sloppy 'eval' call, that might
     // possibly introduce a variable binding. Thus the reference should be
     // considered referencing a global variable unless it is shadowed by an
     // 'eval' introduced binding.
@@ -558,16 +611,14 @@
   // Lookup a variable reference given by name recursively starting with this
   // scope. If the code is executed because of a call to 'eval', the context
   // parameter should be set to the calling context of 'eval'.
-  Variable* LookupRecursive(VariableProxy* proxy,
-                            BindingKind* binding_kind,
-                            AstNodeFactory<AstNullVisitor>* factory);
+  Variable* LookupRecursive(VariableProxy* proxy, BindingKind* binding_kind,
+                            AstNodeFactory* factory);
   MUST_USE_RESULT
-  bool ResolveVariable(CompilationInfo* info,
-                       VariableProxy* proxy,
-                       AstNodeFactory<AstNullVisitor>* factory);
+  bool ResolveVariable(CompilationInfo* info, VariableProxy* proxy,
+                       AstNodeFactory* factory);
   MUST_USE_RESULT
   bool ResolveVariablesRecursively(CompilationInfo* info,
-                                   AstNodeFactory<AstNullVisitor>* factory);
+                                   AstNodeFactory* factory);
 
   // Scope analysis.
   void PropagateScopeInfo(bool outer_scope_calls_sloppy_eval);
@@ -596,8 +647,7 @@
   // parameter is the context in which eval was called.  In all other
   // cases the context parameter is an empty handle.
   MUST_USE_RESULT
-  bool AllocateVariables(CompilationInfo* info,
-                         AstNodeFactory<AstNullVisitor>* factory);
+  bool AllocateVariables(CompilationInfo* info, AstNodeFactory* factory);
 
  private:
   // Construct a scope based on the scope info.
diff --git a/src/serialize.cc b/src/serialize.cc
index dce62fe..c5f8b63 100644
--- a/src/serialize.cc
+++ b/src/serialize.cc
@@ -16,7 +16,7 @@
 #include "src/ic/stub-cache.h"
 #include "src/natives.h"
 #include "src/objects.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 #include "src/serialize.h"
 #include "src/snapshot.h"
 #include "src/snapshot-source-sink.h"
@@ -365,15 +365,11 @@
   }
 
   // Accessors
-#define ACCESSOR_INFO_DECLARATION(name) \
-  Add(FUNCTION_ADDR(&Accessors::name##Getter), \
-      ACCESSOR, \
-      Accessors::k##name##Getter, \
-      "Accessors::" #name "Getter"); \
-  Add(FUNCTION_ADDR(&Accessors::name##Setter), \
-      ACCESSOR, \
-      Accessors::k##name##Setter, \
-      "Accessors::" #name "Setter");
+#define ACCESSOR_INFO_DECLARATION(name)                          \
+  Add(FUNCTION_ADDR(&Accessors::name##Getter), ACCESSOR_CODE,    \
+      Accessors::k##name##Getter, "Accessors::" #name "Getter"); \
+  Add(FUNCTION_ADDR(&Accessors::name##Setter), ACCESSOR_CODE,    \
+      Accessors::k##name##Setter, "Accessors::" #name "Setter");
   ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION)
 #undef ACCESSOR_INFO_DECLARATION
 
@@ -481,6 +477,27 @@
 }
 
 
+RootIndexMap::RootIndexMap(Isolate* isolate) {
+  map_ = new HashMap(HashMap::PointersMatch);
+  Object** root_array = isolate->heap()->roots_array_start();
+  for (int i = 0; i < Heap::kStrongRootListLength; i++) {
+    Object* root = root_array[i];
+    if (root->IsHeapObject() && !isolate->heap()->InNewSpace(root)) {
+      HeapObject* heap_object = HeapObject::cast(root);
+      if (LookupEntry(map_, heap_object, false) != NULL) {
+        // Some root values are initialized to the empty FixedArray();
+        // Do not add them to the map.
+        // TODO(yangguo): This assert is not true. Some roots like
+        // instanceof_cache_answer can be e.g. null.
+        // DCHECK_EQ(isolate->heap()->empty_fixed_array(), heap_object);
+      } else {
+        SetValue(LookupEntry(map_, heap_object, true), i);
+      }
+    }
+  }
+}
+
+
 class CodeAddressMap: public CodeEventLogger {
  public:
   explicit CodeAddressMap(Isolate* isolate)
@@ -592,14 +609,17 @@
 };
 
 
-Deserializer::Deserializer(SnapshotByteSource* source)
-    : isolate_(NULL),
-      attached_objects_(NULL),
-      source_(source),
-      external_reference_decoder_(NULL) {
-  for (int i = 0; i < LAST_SPACE + 1; i++) {
-    reservations_[i] = kUninitializedReservation;
+void Deserializer::DecodeReservation(
+    Vector<const SerializedData::Reservation> res) {
+  DCHECK_EQ(0, reservations_[NEW_SPACE].length());
+  STATIC_ASSERT(NEW_SPACE == 0);
+  int current_space = NEW_SPACE;
+  for (const auto& r : res) {
+    reservations_[current_space].Add({r.chunk_size(), NULL, NULL});
+    if (r.is_last()) current_space++;
   }
+  DCHECK_EQ(kNumberOfSpaces, current_space);
+  for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) current_chunk_[i] = 0;
 }
 
 
@@ -612,10 +632,19 @@
 }
 
 
+bool Deserializer::ReserveSpace() {
+  if (!isolate_->heap()->ReserveSpace(reservations_)) return false;
+  for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
+    high_water_[i] = reservations_[i][0].start;
+  }
+  return true;
+}
+
+
 void Deserializer::Deserialize(Isolate* isolate) {
   isolate_ = isolate;
   DCHECK(isolate_ != NULL);
-  isolate_->heap()->ReserveSpace(reservations_, &high_water_[0]);
+  if (!ReserveSpace()) FatalProcessOutOfMemory("deserializing context");
   // No active threads.
   DCHECK_EQ(NULL, isolate_->thread_manager()->FirstThreadStateInUse());
   // No active handles.
@@ -657,12 +686,17 @@
 }
 
 
-void Deserializer::DeserializePartial(Isolate* isolate, Object** root) {
+void Deserializer::DeserializePartial(Isolate* isolate, Object** root,
+                                      OnOOM on_oom) {
   isolate_ = isolate;
   for (int i = NEW_SPACE; i < kNumberOfSpaces; i++) {
-    DCHECK(reservations_[i] != kUninitializedReservation);
+    DCHECK(reservations_[i].length() > 0);
   }
-  isolate_->heap()->ReserveSpace(reservations_, &high_water_[0]);
+  if (!ReserveSpace()) {
+    if (on_oom == FATAL_ON_OOM) FatalProcessOutOfMemory("deserialize context");
+    *root = NULL;
+    return;
+  }
   if (external_reference_decoder_ == NULL) {
     external_reference_decoder_ = new ExternalReferenceDecoder(isolate);
   }
@@ -684,7 +718,7 @@
 
 Deserializer::~Deserializer() {
   // TODO(svenpanne) Re-enable this assertion when v8 initialization is fixed.
-  // DCHECK(source_->AtEOF());
+  // DCHECK(source_.AtEOF());
   if (external_reference_decoder_) {
     delete external_reference_decoder_;
     external_reference_decoder_ = NULL;
@@ -698,7 +732,7 @@
 void Deserializer::VisitPointers(Object** start, Object** end) {
   // The space must be new space.  Any other space would cause ReadChunk to try
   // to update the remembered using NULL as the address.
-  ReadChunk(start, end, NEW_SPACE, NULL);
+  ReadData(start, end, NEW_SPACE, NULL);
 }
 
 
@@ -720,7 +754,7 @@
     DCHECK(string->IsInternalizedString());
   }
 
-  virtual bool IsMatch(Object* string) {
+  bool IsMatch(Object* string) OVERRIDE {
     // We know that all entries in a hash table had their hash keys created.
     // Use that knowledge to have fast failure.
     if (hash_ != HashForObject(string)) return false;
@@ -728,9 +762,9 @@
     return string_->SlowEquals(String::cast(string));
   }
 
-  virtual uint32_t Hash() OVERRIDE { return hash_; }
+  uint32_t Hash() OVERRIDE { return hash_; }
 
-  virtual uint32_t HashForObject(Object* key) OVERRIDE {
+  uint32_t HashForObject(Object* key) OVERRIDE {
     return String::cast(key)->Hash();
   }
 
@@ -762,10 +796,24 @@
 }
 
 
-Object* Deserializer::ProcessBackRefInSerializedCode(Object* obj) {
-  if (obj->IsInternalizedString()) {
-    return String::cast(obj)->GetForwardedInternalizedString();
+HeapObject* Deserializer::GetBackReferencedObject(int space) {
+  HeapObject* obj;
+  if (space == LO_SPACE) {
+    uint32_t index = source_.GetInt();
+    obj = deserialized_large_objects_[index];
+  } else {
+    BackReference back_reference(source_.GetInt());
+    DCHECK(space < kNumberOfPreallocatedSpaces);
+    uint32_t chunk_index = back_reference.chunk_index();
+    DCHECK_LE(chunk_index, current_chunk_[space]);
+    uint32_t chunk_offset = back_reference.chunk_offset();
+    obj = HeapObject::FromAddress(reservations_[space][chunk_index].start +
+                                  chunk_offset);
   }
+  if (deserializing_user_code() && obj->IsInternalizedString()) {
+    obj = String::cast(obj)->GetForwardedInternalizedString();
+  }
+  hot_objects_.Add(obj);
   return obj;
 }
 
@@ -775,18 +823,34 @@
 // The reason for this strange interface is that otherwise the object is
 // written very late, which means the FreeSpace map is not set up by the
 // time we need to use it to mark the space at the end of a page free.
-void Deserializer::ReadObject(int space_number,
-                              Object** write_back) {
-  int size = source_->GetInt() << kObjectAlignmentBits;
-  Address address = Allocate(space_number, size);
-  HeapObject* obj = HeapObject::FromAddress(address);
+void Deserializer::ReadObject(int space_number, Object** write_back) {
+  Address address;
+  HeapObject* obj;
+  int next_int = source_.GetInt();
+
+  bool double_align = false;
+#ifndef V8_HOST_ARCH_64_BIT
+  double_align = next_int == kDoubleAlignmentSentinel;
+  if (double_align) next_int = source_.GetInt();
+#endif
+
+  DCHECK_NE(kDoubleAlignmentSentinel, next_int);
+  int size = next_int << kObjectAlignmentBits;
+  int reserved_size = size + (double_align ? kPointerSize : 0);
+  address = Allocate(space_number, reserved_size);
+  obj = HeapObject::FromAddress(address);
+  if (double_align) {
+    obj = isolate_->heap()->DoubleAlignForDeserialization(obj, reserved_size);
+    address = obj->address();
+  }
+
   isolate_->heap()->OnAllocationEvent(obj, size);
   Object** current = reinterpret_cast<Object**>(address);
   Object** limit = current + (size >> kPointerSizeLog2);
   if (FLAG_log_snapshot_positions) {
-    LOG(isolate_, SnapshotPositionEvent(address, source_->position()));
+    LOG(isolate_, SnapshotPositionEvent(address, source_.position()));
   }
-  ReadChunk(current, limit, space_number, address);
+  ReadData(current, limit, space_number, address);
 
   // TODO(mvstanton): consider treating the heap()->allocation_sites_list()
   // as a (weak) root. If this root is relocated correctly,
@@ -798,15 +862,53 @@
 
   *write_back = obj;
 #ifdef DEBUG
-  bool is_codespace = (space_number == CODE_SPACE);
-  DCHECK(obj->IsCode() == is_codespace);
+  if (obj->IsCode()) {
+    DCHECK(space_number == CODE_SPACE || space_number == LO_SPACE);
+  } else {
+    DCHECK(space_number != CODE_SPACE);
+  }
 #endif
 }
 
-void Deserializer::ReadChunk(Object** current,
-                             Object** limit,
-                             int source_space,
-                             Address current_object_address) {
+
+// We know the space requirements before deserialization and can
+// pre-allocate that reserved space. During deserialization, all we need
+// to do is to bump up the pointer for each space in the reserved
+// space. This is also used for fixing back references.
+// We may have to split up the pre-allocation into several chunks
+// because it would not fit onto a single page. We do not have to keep
+// track of when to move to the next chunk. An opcode will signal this.
+// Since multiple large objects cannot be folded into one large object
+// space allocation, we have to do an actual allocation when deserializing
+// each large object. Instead of tracking offset for back references, we
+// reference large objects by index.
+Address Deserializer::Allocate(int space_index, int size) {
+  if (space_index == LO_SPACE) {
+    AlwaysAllocateScope scope(isolate_);
+    LargeObjectSpace* lo_space = isolate_->heap()->lo_space();
+    Executability exec = static_cast<Executability>(source_.Get());
+    AllocationResult result = lo_space->AllocateRaw(size, exec);
+    HeapObject* obj = HeapObject::cast(result.ToObjectChecked());
+    deserialized_large_objects_.Add(obj);
+    return obj->address();
+  } else {
+    DCHECK(space_index < kNumberOfPreallocatedSpaces);
+    Address address = high_water_[space_index];
+    DCHECK_NE(NULL, address);
+    high_water_[space_index] += size;
+#ifdef DEBUG
+    // Assert that the current reserved chunk is still big enough.
+    const Heap::Reservation& reservation = reservations_[space_index];
+    int chunk_index = current_chunk_[space_index];
+    CHECK_LE(high_water_[space_index], reservation[chunk_index].end);
+#endif
+    return address;
+  }
+}
+
+
+void Deserializer::ReadData(Object** current, Object** limit, int source_space,
+                            Address current_object_address) {
   Isolate* const isolate = isolate_;
   // Write barrier support costs around 1% in startup time.  In fact there
   // are no new space objects in current boot snapshots, so it's not needed,
@@ -818,7 +920,7 @@
                                source_space != CODE_SPACE &&
                                source_space != OLD_DATA_SPACE);
   while (current < limit) {
-    int data = source_->Get();
+    byte data = source_.Get();
     switch (data) {
 #define CASE_STATEMENT(where, how, within, space_number) \
   case where + how + within + space_number:              \
@@ -842,29 +944,26 @@
       if (where == kNewObject) {                                               \
         ReadObject(space_number, &new_object);                                 \
       } else if (where == kRootArray) {                                        \
-        int root_id = source_->GetInt();                                       \
+        int root_id = source_.GetInt();                                        \
         new_object = isolate->heap()->roots_array_start()[root_id];            \
         emit_write_barrier = isolate->heap()->InNewSpace(new_object);          \
       } else if (where == kPartialSnapshotCache) {                             \
-        int cache_index = source_->GetInt();                                   \
+        int cache_index = source_.GetInt();                                    \
         new_object = isolate->serialize_partial_snapshot_cache()[cache_index]; \
         emit_write_barrier = isolate->heap()->InNewSpace(new_object);          \
       } else if (where == kExternalReference) {                                \
-        int skip = source_->GetInt();                                          \
+        int skip = source_.GetInt();                                           \
         current = reinterpret_cast<Object**>(                                  \
             reinterpret_cast<Address>(current) + skip);                        \
-        int reference_id = source_->GetInt();                                  \
+        int reference_id = source_.GetInt();                                   \
         Address address = external_reference_decoder_->Decode(reference_id);   \
         new_object = reinterpret_cast<Object*>(address);                       \
       } else if (where == kBackref) {                                          \
         emit_write_barrier = (space_number == NEW_SPACE);                      \
-        new_object = GetAddressFromEnd(data & kSpaceMask);                     \
-        if (deserializing_user_code()) {                                       \
-          new_object = ProcessBackRefInSerializedCode(new_object);             \
-        }                                                                      \
+        new_object = GetBackReferencedObject(data & kSpaceMask);               \
       } else if (where == kBuiltin) {                                          \
         DCHECK(deserializing_user_code());                                     \
-        int builtin_id = source_->GetInt();                                    \
+        int builtin_id = source_.GetInt();                                     \
         DCHECK_LE(0, builtin_id);                                              \
         DCHECK_LT(builtin_id, Builtins::builtin_count);                        \
         Builtins::Name name = static_cast<Builtins::Name>(builtin_id);         \
@@ -872,19 +971,16 @@
         emit_write_barrier = false;                                            \
       } else if (where == kAttachedReference) {                                \
         DCHECK(deserializing_user_code());                                     \
-        int index = source_->GetInt();                                         \
+        int index = source_.GetInt();                                          \
         new_object = *attached_objects_->at(index);                            \
         emit_write_barrier = isolate->heap()->InNewSpace(new_object);          \
       } else {                                                                 \
         DCHECK(where == kBackrefWithSkip);                                     \
-        int skip = source_->GetInt();                                          \
+        int skip = source_.GetInt();                                           \
         current = reinterpret_cast<Object**>(                                  \
             reinterpret_cast<Address>(current) + skip);                        \
         emit_write_barrier = (space_number == NEW_SPACE);                      \
-        new_object = GetAddressFromEnd(data & kSpaceMask);                     \
-        if (deserializing_user_code()) {                                       \
-          new_object = ProcessBackRefInSerializedCode(new_object);             \
-        }                                                                      \
+        new_object = GetBackReferencedObject(data & kSpaceMask);               \
       }                                                                        \
       if (within == kInnerPointer) {                                           \
         if (space_number != CODE_SPACE || new_object->IsCode()) {              \
@@ -925,15 +1021,16 @@
 // This generates a case and a body for the new space (which has to do extra
 // write barrier handling) and handles the other spaces with 8 fall-through
 // cases and one body.
-#define ALL_SPACES(where, how, within)                                         \
-  CASE_STATEMENT(where, how, within, NEW_SPACE)                                \
-  CASE_BODY(where, how, within, NEW_SPACE)                                     \
-  CASE_STATEMENT(where, how, within, OLD_DATA_SPACE)                           \
-  CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE)                        \
-  CASE_STATEMENT(where, how, within, CODE_SPACE)                               \
-  CASE_STATEMENT(where, how, within, CELL_SPACE)                               \
-  CASE_STATEMENT(where, how, within, PROPERTY_CELL_SPACE)                      \
-  CASE_STATEMENT(where, how, within, MAP_SPACE)                                \
+#define ALL_SPACES(where, how, within)                    \
+  CASE_STATEMENT(where, how, within, NEW_SPACE)           \
+  CASE_BODY(where, how, within, NEW_SPACE)                \
+  CASE_STATEMENT(where, how, within, OLD_DATA_SPACE)      \
+  CASE_STATEMENT(where, how, within, OLD_POINTER_SPACE)   \
+  CASE_STATEMENT(where, how, within, CODE_SPACE)          \
+  CASE_STATEMENT(where, how, within, MAP_SPACE)           \
+  CASE_STATEMENT(where, how, within, CELL_SPACE)          \
+  CASE_STATEMENT(where, how, within, PROPERTY_CELL_SPACE) \
+  CASE_STATEMENT(where, how, within, LO_SPACE)            \
   CASE_BODY(where, how, within, kAnyOldSpace)
 
 #define FOUR_CASES(byte_code)             \
@@ -983,23 +1080,22 @@
 
       // We generate 15 cases and bodies that process special tags that combine
       // the raw data tag and the length into one byte.
-#define RAW_CASE(index)                                                      \
-      case kRawData + index: {                                               \
-        byte* raw_data_out = reinterpret_cast<byte*>(current);               \
-        source_->CopyRaw(raw_data_out, index * kPointerSize);                \
-        current =                                                            \
-            reinterpret_cast<Object**>(raw_data_out + index * kPointerSize); \
-        break;                                                               \
-      }
+#define RAW_CASE(index)                                                        \
+  case kRawData + index: {                                                     \
+    byte* raw_data_out = reinterpret_cast<byte*>(current);                     \
+    source_.CopyRaw(raw_data_out, index* kPointerSize);                        \
+    current = reinterpret_cast<Object**>(raw_data_out + index * kPointerSize); \
+    break;                                                                     \
+  }
       COMMON_RAW_LENGTHS(RAW_CASE)
 #undef RAW_CASE
 
       // Deserialize a chunk of raw data that doesn't have one of the popular
       // lengths.
       case kRawData: {
-        int size = source_->GetInt();
+        int size = source_.GetInt();
         byte* raw_data_out = reinterpret_cast<byte*>(current);
-        source_->CopyRaw(raw_data_out, size);
+        source_.CopyRaw(raw_data_out, size);
         break;
       }
 
@@ -1015,7 +1111,7 @@
       SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance)
       SIXTEEN_CASES(kRootArrayConstants + kHasSkipDistance + 16) {
         int root_id = RootArrayConstantFromByteCode(data);
-        int skip = source_->GetInt();
+        int skip = source_.GetInt();
         current = reinterpret_cast<Object**>(
             reinterpret_cast<intptr_t>(current) + skip);
         Object* object = isolate->heap()->roots_array_start()[root_id];
@@ -1024,8 +1120,8 @@
         break;
       }
 
-      case kRepeat: {
-        int repeats = source_->GetInt();
+      case kVariableRepeat: {
+        int repeats = source_.GetInt();
         Object* object = current[-1];
         DCHECK(!isolate->heap()->InNewSpace(object));
         for (int i = 0; i < repeats; i++) current[i] = object;
@@ -1035,11 +1131,13 @@
 
       STATIC_ASSERT(kRootArrayNumberOfConstantEncodings ==
                     Heap::kOldSpaceRoots);
-      STATIC_ASSERT(kMaxRepeats == 13);
-      case kConstantRepeat:
-      FOUR_CASES(kConstantRepeat + 1)
-      FOUR_CASES(kConstantRepeat + 5)
-      FOUR_CASES(kConstantRepeat + 9) {
+      STATIC_ASSERT(kMaxFixedRepeats == 15);
+      FOUR_CASES(kFixedRepeat)
+      FOUR_CASES(kFixedRepeat + 4)
+      FOUR_CASES(kFixedRepeat + 8)
+      case kFixedRepeat + 12:
+      case kFixedRepeat + 13:
+      case kFixedRepeat + 14: {
         int repeats = RepeatsForCode(data);
         Object* object = current[-1];
         DCHECK(!isolate->heap()->InNewSpace(object));
@@ -1125,13 +1223,8 @@
       // Find a builtin and write a pointer to it to the current object.
       CASE_STATEMENT(kBuiltin, kPlain, kStartOfObject, 0)
       CASE_BODY(kBuiltin, kPlain, kStartOfObject, 0)
-#if V8_OOL_CONSTANT_POOL
-      // Find a builtin code entry and write a pointer to it to the current
-      // object.
       CASE_STATEMENT(kBuiltin, kPlain, kInnerPointer, 0)
       CASE_BODY(kBuiltin, kPlain, kInnerPointer, 0)
-#endif
-      // Find a builtin and write a pointer to it in the current code object.
       CASE_STATEMENT(kBuiltin, kFromCode, kInnerPointer, 0)
       CASE_BODY(kBuiltin, kFromCode, kInnerPointer, 0)
       // Find an object in the attached references and write a pointer to it to
@@ -1148,15 +1241,15 @@
 #undef ALL_SPACES
 
       case kSkip: {
-        int size = source_->GetInt();
+        int size = source_.GetInt();
         current = reinterpret_cast<Object**>(
             reinterpret_cast<intptr_t>(current) + size);
         break;
       }
 
       case kNativesStringResource: {
-        int index = source_->Get();
-        Vector<const char> source_vector = Natives::GetRawScriptSource(index);
+        int index = source_.Get();
+        Vector<const char> source_vector = Natives::GetScriptSource(index);
         NativesExternalStringResource* resource =
             new NativesExternalStringResource(isolate->bootstrapper(),
                                               source_vector.start(),
@@ -1165,6 +1258,41 @@
         break;
       }
 
+      case kNextChunk: {
+        int space = source_.Get();
+        DCHECK(space < kNumberOfPreallocatedSpaces);
+        int chunk_index = current_chunk_[space];
+        const Heap::Reservation& reservation = reservations_[space];
+        // Make sure the current chunk is indeed exhausted.
+        CHECK_EQ(reservation[chunk_index].end, high_water_[space]);
+        // Move to next reserved chunk.
+        chunk_index = ++current_chunk_[space];
+        DCHECK_LT(chunk_index, reservation.length());
+        high_water_[space] = reservation[chunk_index].start;
+        break;
+      }
+
+      FOUR_CASES(kHotObjectWithSkip)
+      FOUR_CASES(kHotObjectWithSkip + 4) {
+        int skip = source_.GetInt();
+        current = reinterpret_cast<Object**>(
+            reinterpret_cast<Address>(current) + skip);
+        // Fall through.
+      }
+      FOUR_CASES(kHotObject)
+      FOUR_CASES(kHotObject + 4) {
+        int index = data & kHotObjectIndexMask;
+        *current = hot_objects_.Get(index);
+        if (write_barrier_needed && isolate->heap()->InNewSpace(*current)) {
+          Address current_address = reinterpret_cast<Address>(current);
+          isolate->heap()->RecordWrite(
+              current_object_address,
+              static_cast<int>(current_address - current_object_address));
+        }
+        current++;
+        break;
+      }
+
       case kSynchronize: {
         // If we get here then that indicates that you have a mismatch between
         // the number of GC roots when serializing and deserializing.
@@ -1183,12 +1311,16 @@
     : isolate_(isolate),
       sink_(sink),
       external_reference_encoder_(new ExternalReferenceEncoder(isolate)),
-      root_index_wave_front_(0),
-      code_address_map_(NULL) {
+      root_index_map_(isolate),
+      code_address_map_(NULL),
+      large_objects_total_size_(0),
+      seen_large_objects_index_(0) {
   // The serializer is meant to be used only to generate initial heap images
   // from a context in which there is only one isolate.
-  for (int i = 0; i <= LAST_SPACE; i++) {
-    fullness_[i] = 0;
+  for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
+    pending_chunk_[i] = 0;
+    max_chunk_size_[i] = static_cast<uint32_t>(
+        MemoryAllocator::PageAreaSize(static_cast<AllocationSpace>(i)));
   }
 }
 
@@ -1214,6 +1346,27 @@
 }
 
 
+void StartupSerializer::VisitPointers(Object** start, Object** end) {
+  for (Object** current = start; current < end; current++) {
+    if (start == isolate()->heap()->roots_array_start()) {
+      root_index_wave_front_ =
+          Max(root_index_wave_front_, static_cast<intptr_t>(current - start));
+    }
+    if (ShouldBeSkipped(current)) {
+      sink_->Put(kSkip, "Skip");
+      sink_->PutInt(kPointerSize, "SkipOneWord");
+    } else if ((*current)->IsSmi()) {
+      sink_->Put(kOnePointerRawData, "Smi");
+      for (int i = 0; i < kPointerSize; i++) {
+        sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
+      }
+    } else {
+      SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0);
+    }
+  }
+}
+
+
 void PartialSerializer::Serialize(Object** object) {
   this->VisitPointer(object);
   Pad();
@@ -1229,28 +1382,37 @@
 
 
 void Serializer::VisitPointers(Object** start, Object** end) {
-  Isolate* isolate = this->isolate();;
-
   for (Object** current = start; current < end; current++) {
-    if (start == isolate->heap()->roots_array_start()) {
-      root_index_wave_front_ =
-          Max(root_index_wave_front_, static_cast<intptr_t>(current - start));
-    }
-    if (ShouldBeSkipped(current)) {
-      sink_->Put(kSkip, "Skip");
-      sink_->PutInt(kPointerSize, "SkipOneWord");
-    } else if ((*current)->IsSmi()) {
-      sink_->Put(kRawData + 1, "Smi");
+    if ((*current)->IsSmi()) {
+      sink_->Put(kOnePointerRawData, "Smi");
       for (int i = 0; i < kPointerSize; i++) {
         sink_->Put(reinterpret_cast<byte*>(current)[i], "Byte");
       }
     } else {
-      SerializeObject(*current, kPlain, kStartOfObject, 0);
+      SerializeObject(HeapObject::cast(*current), kPlain, kStartOfObject, 0);
     }
   }
 }
 
 
+void Serializer::EncodeReservations(
+    List<SerializedData::Reservation>* out) const {
+  for (int i = 0; i < kNumberOfPreallocatedSpaces; i++) {
+    for (int j = 0; j < completed_chunks_[i].length(); j++) {
+      out->Add(SerializedData::Reservation(completed_chunks_[i][j]));
+    }
+
+    if (pending_chunk_[i] > 0 || completed_chunks_[i].length() == 0) {
+      out->Add(SerializedData::Reservation(pending_chunk_[i]));
+    }
+    out->last().mark_as_last();
+  }
+
+  out->Add(SerializedData::Reservation(large_objects_total_size_));
+  out->last().mark_as_last();
+}
+
+
 // This ensures that the partial snapshot cache keeps things alive during GC and
 // tracks their movement.  When it is called during serialization of the startup
 // snapshot nothing happens.  When the partial (context) snapshot is created,
@@ -1302,80 +1464,90 @@
 }
 
 
-int Serializer::RootIndex(HeapObject* heap_object, HowToCode from) {
-  Heap* heap = isolate()->heap();
-  if (heap->InNewSpace(heap_object)) return kInvalidRootIndex;
-  for (int i = 0; i < root_index_wave_front_; i++) {
-    Object* root = heap->roots_array_start()[i];
-    if (!root->IsSmi() && root == heap_object) {
-      return i;
+bool Serializer::SerializeKnownObject(HeapObject* obj, HowToCode how_to_code,
+                                      WhereToPoint where_to_point, int skip) {
+  if (how_to_code == kPlain && where_to_point == kStartOfObject) {
+    // Encode a reference to a hot object by its index in the working set.
+    int index = hot_objects_.Find(obj);
+    if (index != HotObjectsList::kNotFound) {
+      DCHECK(index >= 0 && index <= kMaxHotObjectIndex);
+      if (FLAG_trace_serializer) {
+        PrintF(" Encoding hot object %d:", index);
+        obj->ShortPrint();
+        PrintF("\n");
+      }
+      if (skip != 0) {
+        sink_->Put(kHotObjectWithSkip + index, "HotObjectWithSkip");
+        sink_->PutInt(skip, "HotObjectSkipDistance");
+      } else {
+        sink_->Put(kHotObject + index, "HotObject");
+      }
+      return true;
     }
   }
-  return kInvalidRootIndex;
-}
+  BackReference back_reference = back_reference_map_.Lookup(obj);
+  if (back_reference.is_valid()) {
+    // Encode the location of an already deserialized object in order to write
+    // its location into a later object.  We can encode the location as an
+    // offset fromthe start of the deserialized objects or as an offset
+    // backwards from thecurrent allocation pointer.
+    if (back_reference.is_source()) {
+      FlushSkip(skip);
+      if (FLAG_trace_serializer) PrintF(" Encoding source object\n");
+      DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject);
+      sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
+      sink_->PutInt(kSourceObjectReference, "kSourceObjectIndex");
+    } else {
+      if (FLAG_trace_serializer) {
+        PrintF(" Encoding back reference to: ");
+        obj->ShortPrint();
+        PrintF("\n");
+      }
 
+      AllocationSpace space = back_reference.space();
+      if (skip == 0) {
+        sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRef");
+      } else {
+        sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space,
+                   "BackRefWithSkip");
+        sink_->PutInt(skip, "BackRefSkipDistance");
+      }
+      sink_->PutInt(back_reference.reference(), "BackRefValue");
 
-// Encode the location of an already deserialized object in order to write its
-// location into a later object.  We can encode the location as an offset from
-// the start of the deserialized objects or as an offset backwards from the
-// current allocation pointer.
-void Serializer::SerializeReferenceToPreviousObject(HeapObject* heap_object,
-                                                    HowToCode how_to_code,
-                                                    WhereToPoint where_to_point,
-                                                    int skip) {
-  int space = SpaceOfObject(heap_object);
-  int address = address_mapper_.MappedTo(heap_object);
-  int offset = CurrentAllocationAddress(space) - address;
-  // Shift out the bits that are always 0.
-  offset >>= kObjectAlignmentBits;
-  if (skip == 0) {
-    sink_->Put(kBackref + how_to_code + where_to_point + space, "BackRefSer");
-  } else {
-    sink_->Put(kBackrefWithSkip + how_to_code + where_to_point + space,
-               "BackRefSerWithSkip");
-    sink_->PutInt(skip, "BackRefSkipDistance");
+      hot_objects_.Add(obj);
+    }
+    return true;
   }
-  sink_->PutInt(offset, "offset");
+  return false;
 }
 
 
-void StartupSerializer::SerializeObject(
-    Object* o,
-    HowToCode how_to_code,
-    WhereToPoint where_to_point,
-    int skip) {
-  CHECK(o->IsHeapObject());
-  HeapObject* heap_object = HeapObject::cast(o);
-  DCHECK(!heap_object->IsJSFunction());
+void StartupSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
+                                        WhereToPoint where_to_point, int skip) {
+  DCHECK(!obj->IsJSFunction());
 
-  int root_index;
-  if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) {
-    PutRoot(root_index, heap_object, how_to_code, where_to_point, skip);
+  int root_index = root_index_map_.Lookup(obj);
+  // We can only encode roots as such if it has already been serialized.
+  // That applies to root indices below the wave front.
+  if (root_index != RootIndexMap::kInvalidRootIndex &&
+      root_index < root_index_wave_front_) {
+    PutRoot(root_index, obj, how_to_code, where_to_point, skip);
     return;
   }
 
-  if (address_mapper_.IsMapped(heap_object)) {
-    SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point,
-                                       skip);
-  } else {
-    if (skip != 0) {
-      sink_->Put(kSkip, "FlushPendingSkip");
-      sink_->PutInt(skip, "SkipDistance");
-    }
+  if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return;
 
-    // Object has not yet been serialized.  Serialize it here.
-    ObjectSerializer object_serializer(this,
-                                       heap_object,
-                                       sink_,
-                                       how_to_code,
-                                       where_to_point);
-    object_serializer.Serialize();
-  }
+  FlushSkip(skip);
+
+  // Object has not yet been serialized.  Serialize it here.
+  ObjectSerializer object_serializer(this, obj, sink_, how_to_code,
+                                     where_to_point);
+  object_serializer.Serialize();
 }
 
 
 void StartupSerializer::SerializeWeakReferences() {
-  // This phase comes right after the partial serialization (of the snapshot).
+  // This phase comes right after the serialization (of the snapshot).
   // After we have done the partial serialization the partial snapshot cache
   // will contain some references needed to decode the partial snapshot.  We
   // add one entry with 'undefined' which is the sentinel that the deserializer
@@ -1392,6 +1564,12 @@
                          SerializerDeserializer::HowToCode how_to_code,
                          SerializerDeserializer::WhereToPoint where_to_point,
                          int skip) {
+  if (FLAG_trace_serializer) {
+    PrintF(" Encoding root %d:", root_index);
+    object->ShortPrint();
+    PrintF("\n");
+  }
+
   if (how_to_code == kPlain &&
       where_to_point == kStartOfObject &&
       root_index < kRootArrayNumberOfConstantEncodings &&
@@ -1405,44 +1583,31 @@
       sink_->PutInt(skip, "SkipInPutRoot");
     }
   } else {
-    if (skip != 0) {
-      sink_->Put(kSkip, "SkipFromPutRoot");
-      sink_->PutInt(skip, "SkipFromPutRootDistance");
-    }
+    FlushSkip(skip);
     sink_->Put(kRootArray + how_to_code + where_to_point, "RootSerialization");
     sink_->PutInt(root_index, "root_index");
   }
 }
 
 
-void PartialSerializer::SerializeObject(
-    Object* o,
-    HowToCode how_to_code,
-    WhereToPoint where_to_point,
-    int skip) {
-  CHECK(o->IsHeapObject());
-  HeapObject* heap_object = HeapObject::cast(o);
-
-  if (heap_object->IsMap()) {
+void PartialSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
+                                        WhereToPoint where_to_point, int skip) {
+  if (obj->IsMap()) {
     // The code-caches link to context-specific code objects, which
     // the startup and context serializes cannot currently handle.
-    DCHECK(Map::cast(heap_object)->code_cache() ==
-           heap_object->GetHeap()->empty_fixed_array());
+    DCHECK(Map::cast(obj)->code_cache() == obj->GetHeap()->empty_fixed_array());
   }
 
-  int root_index;
-  if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) {
-    PutRoot(root_index, heap_object, how_to_code, where_to_point, skip);
+  int root_index = root_index_map_.Lookup(obj);
+  if (root_index != RootIndexMap::kInvalidRootIndex) {
+    PutRoot(root_index, obj, how_to_code, where_to_point, skip);
     return;
   }
 
-  if (ShouldBeInThePartialSnapshotCache(heap_object)) {
-    if (skip != 0) {
-      sink_->Put(kSkip, "SkipFromSerializeObject");
-      sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
-    }
+  if (ShouldBeInThePartialSnapshotCache(obj)) {
+    FlushSkip(skip);
 
-    int cache_index = PartialSnapshotCacheIndex(heap_object);
+    int cache_index = PartialSnapshotCacheIndex(obj);
     sink_->Put(kPartialSnapshotCache + how_to_code + where_to_point,
                "PartialSnapshotCache");
     sink_->PutInt(cache_index, "partial_snapshot_cache_index");
@@ -1452,38 +1617,23 @@
   // Pointers from the partial snapshot to the objects in the startup snapshot
   // should go through the root array or through the partial snapshot cache.
   // If this is not the case you may have to add something to the root array.
-  DCHECK(!startup_serializer_->address_mapper()->IsMapped(heap_object));
+  DCHECK(!startup_serializer_->back_reference_map()->Lookup(obj).is_valid());
   // All the internalized strings that the partial snapshot needs should be
   // either in the root table or in the partial snapshot cache.
-  DCHECK(!heap_object->IsInternalizedString());
+  DCHECK(!obj->IsInternalizedString());
 
-  if (address_mapper_.IsMapped(heap_object)) {
-    SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point,
-                                       skip);
-  } else {
-    if (skip != 0) {
-      sink_->Put(kSkip, "SkipFromSerializeObject");
-      sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
-    }
-    // Object has not yet been serialized.  Serialize it here.
-    ObjectSerializer serializer(this,
-                                heap_object,
-                                sink_,
-                                how_to_code,
-                                where_to_point);
-    serializer.Serialize();
-  }
+  if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return;
+
+  FlushSkip(skip);
+
+  // Object has not yet been serialized.  Serialize it here.
+  ObjectSerializer serializer(this, obj, sink_, how_to_code, where_to_point);
+  serializer.Serialize();
 }
 
 
-void Serializer::ObjectSerializer::Serialize() {
-  int space = Serializer::SpaceOfObject(object_);
-  int size = object_->Size();
-
-  sink_->Put(kNewObject + reference_representation_ + space,
-             "ObjectSerialization");
-  sink_->PutInt(size >> kObjectAlignmentBits, "Size in words");
-
+void Serializer::ObjectSerializer::SerializePrologue(AllocationSpace space,
+                                                     int size, Map* map) {
   if (serializer_->code_address_map_) {
     const char* code_name =
         serializer_->code_address_map_->Lookup(object_->address());
@@ -1493,17 +1643,140 @@
         SnapshotPositionEvent(object_->address(), sink_->Position()));
   }
 
+  BackReference back_reference;
+  if (space == LO_SPACE) {
+    sink_->Put(kNewObject + reference_representation_ + space,
+               "NewLargeObject");
+    sink_->PutInt(size >> kObjectAlignmentBits, "ObjectSizeInWords");
+    if (object_->IsCode()) {
+      sink_->Put(EXECUTABLE, "executable large object");
+    } else {
+      sink_->Put(NOT_EXECUTABLE, "not executable large object");
+    }
+    back_reference = serializer_->AllocateLargeObject(size);
+  } else {
+    bool needs_double_align = false;
+    if (object_->NeedsToEnsureDoubleAlignment()) {
+      // Add wriggle room for double alignment padding.
+      back_reference = serializer_->Allocate(space, size + kPointerSize);
+      needs_double_align = true;
+    } else {
+      back_reference = serializer_->Allocate(space, size);
+    }
+    sink_->Put(kNewObject + reference_representation_ + space, "NewObject");
+    if (needs_double_align)
+      sink_->PutInt(kDoubleAlignmentSentinel, "DoubleAlignSentinel");
+    int encoded_size = size >> kObjectAlignmentBits;
+    DCHECK_NE(kDoubleAlignmentSentinel, encoded_size);
+    sink_->PutInt(encoded_size, "ObjectSizeInWords");
+  }
+
   // Mark this object as already serialized.
-  int offset = serializer_->Allocate(space, size);
-  serializer_->address_mapper()->AddMapping(object_, offset);
+  serializer_->back_reference_map()->Add(object_, back_reference);
 
   // Serialize the map (first word of the object).
-  serializer_->SerializeObject(object_->map(), kPlain, kStartOfObject, 0);
+  serializer_->SerializeObject(map, kPlain, kStartOfObject, 0);
+}
+
+
+void Serializer::ObjectSerializer::SerializeExternalString() {
+  // Instead of serializing this as an external string, we serialize
+  // an imaginary sequential string with the same content.
+  Isolate* isolate = serializer_->isolate();
+  DCHECK(object_->IsExternalString());
+  DCHECK(object_->map() != isolate->heap()->native_source_string_map());
+  ExternalString* string = ExternalString::cast(object_);
+  int length = string->length();
+  Map* map;
+  int content_size;
+  int allocation_size;
+  const byte* resource;
+  // Find the map and size for the imaginary sequential string.
+  bool internalized = object_->IsInternalizedString();
+  if (object_->IsExternalOneByteString()) {
+    map = internalized ? isolate->heap()->one_byte_internalized_string_map()
+                       : isolate->heap()->one_byte_string_map();
+    allocation_size = SeqOneByteString::SizeFor(length);
+    content_size = length * kCharSize;
+    resource = reinterpret_cast<const byte*>(
+        ExternalOneByteString::cast(string)->resource()->data());
+  } else {
+    map = internalized ? isolate->heap()->internalized_string_map()
+                       : isolate->heap()->string_map();
+    allocation_size = SeqTwoByteString::SizeFor(length);
+    content_size = length * kShortSize;
+    resource = reinterpret_cast<const byte*>(
+        ExternalTwoByteString::cast(string)->resource()->data());
+  }
+
+  AllocationSpace space = (allocation_size > Page::kMaxRegularHeapObjectSize)
+                              ? LO_SPACE
+                              : OLD_DATA_SPACE;
+  SerializePrologue(space, allocation_size, map);
+
+  // Output the rest of the imaginary string.
+  int bytes_to_output = allocation_size - HeapObject::kHeaderSize;
+
+  // Output raw data header. Do not bother with common raw length cases here.
+  sink_->Put(kRawData, "RawDataForString");
+  sink_->PutInt(bytes_to_output, "length");
+
+  // Serialize string header (except for map).
+  Address string_start = string->address();
+  for (int i = HeapObject::kHeaderSize; i < SeqString::kHeaderSize; i++) {
+    sink_->PutSection(string_start[i], "StringHeader");
+  }
+
+  // Serialize string content.
+  sink_->PutRaw(resource, content_size, "StringContent");
+
+  // Since the allocation size is rounded up to object alignment, there
+  // maybe left-over bytes that need to be padded.
+  int padding_size = allocation_size - SeqString::kHeaderSize - content_size;
+  DCHECK(0 <= padding_size && padding_size < kObjectAlignment);
+  for (int i = 0; i < padding_size; i++) sink_->PutSection(0, "StringPadding");
+
+  sink_->Put(kSkip, "SkipAfterString");
+  sink_->PutInt(bytes_to_output, "SkipDistance");
+}
+
+
+void Serializer::ObjectSerializer::Serialize() {
+  if (FLAG_trace_serializer) {
+    PrintF(" Encoding heap object: ");
+    object_->ShortPrint();
+    PrintF("\n");
+  }
+
+  if (object_->IsScript()) {
+    // Clear cached line ends.
+    Object* undefined = serializer_->isolate()->heap()->undefined_value();
+    Script::cast(object_)->set_line_ends(undefined);
+  }
+
+  if (object_->IsExternalString()) {
+    Heap* heap = serializer_->isolate()->heap();
+    if (object_->map() != heap->native_source_string_map()) {
+      // Usually we cannot recreate resources for external strings. To work
+      // around this, external strings are serialized to look like ordinary
+      // sequential strings.
+      // The exception are native source code strings, since we can recreate
+      // their resources. In that case we fall through and leave it to
+      // VisitExternalOneByteString further down.
+      SerializeExternalString();
+      return;
+    }
+  }
+
+  int size = object_->Size();
+  Map* map = object_->map();
+  SerializePrologue(Serializer::SpaceOfObject(object_), size, map);
 
   // Serialize the rest of the object.
   CHECK_EQ(0, bytes_processed_so_far_);
   bytes_processed_so_far_ = kPointerSize;
-  object_->IterateBody(object_->map()->instance_type(), size, this);
+
+  object_->IterateBody(map->instance_type(), size, this);
   OutputRawData(object_->address() + size);
 }
 
@@ -1517,13 +1790,11 @@
 
     while (current < end && !(*current)->IsSmi()) {
       HeapObject* current_contents = HeapObject::cast(*current);
-      int root_index = serializer_->RootIndex(current_contents, kPlain);
-      // Repeats are not subject to the write barrier so there are only some
-      // objects that can be used in a repeat encoding.  These are the early
-      // ones in the root array that are never in new space.
-      if (current != start &&
-          root_index != kInvalidRootIndex &&
-          root_index < kRootArrayNumberOfConstantEncodings &&
+      int root_index = serializer_->root_index_map()->Lookup(current_contents);
+      // Repeats are not subject to the write barrier so we can only use
+      // immortal immovable root members. They are never in new space.
+      if (current != start && root_index != RootIndexMap::kInvalidRootIndex &&
+          Heap::RootIsImmortalImmovable(root_index) &&
           current_contents == current[-1]) {
         DCHECK(!serializer_->isolate()->heap()->InNewSpace(current_contents));
         int repeat_count = 1;
@@ -1533,8 +1804,8 @@
         }
         current += repeat_count;
         bytes_processed_so_far_ += repeat_count * kPointerSize;
-        if (repeat_count > kMaxRepeats) {
-          sink_->Put(kRepeat, "SerializeRepeats");
+        if (repeat_count > kMaxFixedRepeats) {
+          sink_->Put(kVariableRepeat, "SerializeRepeats");
           sink_->PutInt(repeat_count, "SerializeRepeats");
         } else {
           sink_->Put(CodeForRepeats(repeat_count), "SerializeRepeats");
@@ -1558,7 +1829,8 @@
                            kCanReturnSkipInsteadOfSkipping);
   HowToCode how_to_code = rinfo->IsCodedSpecially() ? kFromCode : kPlain;
   Object* object = rinfo->target_object();
-  serializer_->SerializeObject(object, how_to_code, kStartOfObject, skip);
+  serializer_->SerializeObject(HeapObject::cast(object), how_to_code,
+                               kStartOfObject, skip);
   bytes_processed_so_far_ += rinfo->target_address_size();
 }
 
@@ -1649,7 +1921,7 @@
     }
   }
   // One of the strings in the natives cache should match the resource.  We
-  // can't serialize any other kinds of external strings.
+  // don't expect any other kinds of external strings here.
   UNREACHABLE();
 }
 
@@ -1712,6 +1984,8 @@
     // To make snapshots reproducible, we need to wipe out all pointers in code.
     if (code_object_) {
       Code* code = CloneCodeObject(object_);
+      // Code age headers are not serializable.
+      code->MakeYoung(serializer_->isolate());
       WipeOutRelocations(code);
       // We need to wipe out the header fields *after* wiping out the
       // relocations, because some of these fields are needed for the latter.
@@ -1720,9 +1994,7 @@
     }
 
     const char* description = code_object_ ? "Code" : "Byte";
-    for (int i = 0; i < bytes_to_output; i++) {
-      sink_->PutSection(object_start[base + i], description);
-    }
+    sink_->PutRaw(object_start + base, bytes_to_output, description);
     if (code_object_) delete[] object_start;
   }
   if (to_skip != 0 && return_skip == kIgnoringReturn) {
@@ -1734,33 +2006,45 @@
 }
 
 
-int Serializer::SpaceOfObject(HeapObject* object) {
+AllocationSpace Serializer::SpaceOfObject(HeapObject* object) {
   for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) {
     AllocationSpace s = static_cast<AllocationSpace>(i);
     if (object->GetHeap()->InSpace(object, s)) {
       DCHECK(i < kNumberOfSpaces);
-      return i;
+      return s;
     }
   }
   UNREACHABLE();
-  return 0;
+  return FIRST_SPACE;
 }
 
 
-int Serializer::Allocate(int space, int size) {
-  CHECK(space >= 0 && space < kNumberOfSpaces);
-  int allocation_address = fullness_[space];
-  fullness_[space] = allocation_address + size;
-  return allocation_address;
+BackReference Serializer::AllocateLargeObject(int size) {
+  // Large objects are allocated one-by-one when deserializing. We do not
+  // have to keep track of multiple chunks.
+  large_objects_total_size_ += size;
+  return BackReference::LargeObjectReference(seen_large_objects_index_++);
 }
 
 
-int Serializer::SpaceAreaSize(int space) {
-  if (space == CODE_SPACE) {
-    return isolate_->memory_allocator()->CodePageAreaSize();
-  } else {
-    return Page::kPageSize - Page::kObjectStartOffset;
+BackReference Serializer::Allocate(AllocationSpace space, int size) {
+  DCHECK(space >= 0 && space < kNumberOfPreallocatedSpaces);
+  DCHECK(size > 0 && size <= static_cast<int>(max_chunk_size(space)));
+  uint32_t new_chunk_size = pending_chunk_[space] + size;
+  if (new_chunk_size > max_chunk_size(space)) {
+    // The new chunk size would not fit onto a single page. Complete the
+    // current chunk and start a new one.
+    sink_->Put(kNextChunk, "NextChunk");
+    sink_->Put(space, "NextChunkSpace");
+    completed_chunks_[space].Add(pending_chunk_[space]);
+    DCHECK_LE(completed_chunks_[space].length(), BackReference::kMaxChunkIndex);
+    pending_chunk_[space] = 0;
+    new_chunk_size = size;
   }
+  uint32_t offset = pending_chunk_[space];
+  pending_chunk_[space] = new_chunk_size;
+  return BackReference::Reference(space, completed_chunks_[space].length(),
+                                  offset);
 }
 
 
@@ -1770,6 +2054,10 @@
   for (unsigned i = 0; i < sizeof(int32_t) - 1; i++) {
     sink_->Put(kNop, "Padding");
   }
+  // Pad up to pointer size for checksum.
+  while (!IsAligned(sink_->Position(), kPointerAlignment)) {
+    sink_->Put(kNop, "Padding");
+  }
 }
 
 
@@ -1784,21 +2072,22 @@
                                       Handle<String> source) {
   base::ElapsedTimer timer;
   if (FLAG_profile_deserialization) timer.Start();
+  if (FLAG_trace_serializer) {
+    PrintF("[Serializing from");
+    Object* script = info->script();
+    if (script->IsScript()) Script::cast(script)->name()->ShortPrint();
+    PrintF("]\n");
+  }
 
   // Serialize code object.
-  List<byte> payload;
-  ListSnapshotSink list_sink(&payload);
-  DebugSnapshotSink debug_sink(&list_sink);
-  SnapshotByteSink* sink = FLAG_trace_code_serializer
-                               ? static_cast<SnapshotByteSink*>(&debug_sink)
-                               : static_cast<SnapshotByteSink*>(&list_sink);
-  CodeSerializer cs(isolate, sink, *source);
+  SnapshotByteSink sink(info->code()->CodeSize() * 2);
+  CodeSerializer cs(isolate, &sink, *source, info->code());
   DisallowHeapAllocation no_gc;
   Object** location = Handle<Object>::cast(info).location();
   cs.VisitPointer(location);
   cs.Pad();
 
-  SerializedCodeData data(&payload, &cs);
+  SerializedCodeData data(sink.data(), cs);
   ScriptData* script_data = data.GetScriptData();
 
   if (FLAG_profile_deserialization) {
@@ -1811,76 +2100,70 @@
 }
 
 
-void CodeSerializer::SerializeObject(Object* o, HowToCode how_to_code,
+void CodeSerializer::SerializeObject(HeapObject* obj, HowToCode how_to_code,
                                      WhereToPoint where_to_point, int skip) {
-  CHECK(o->IsHeapObject());
-  HeapObject* heap_object = HeapObject::cast(o);
-
-  // The code-caches link to context-specific code objects, which
-  // the startup and context serializes cannot currently handle.
-  DCHECK(!heap_object->IsMap() ||
-         Map::cast(heap_object)->code_cache() ==
-             heap_object->GetHeap()->empty_fixed_array());
-
-  int root_index;
-  if ((root_index = RootIndex(heap_object, how_to_code)) != kInvalidRootIndex) {
-    PutRoot(root_index, heap_object, how_to_code, where_to_point, skip);
+  int root_index = root_index_map_.Lookup(obj);
+  if (root_index != RootIndexMap::kInvalidRootIndex) {
+    PutRoot(root_index, obj, how_to_code, where_to_point, skip);
     return;
   }
 
-  // TODO(yangguo) wire up global object.
-  // TODO(yangguo) We cannot deal with different hash seeds yet.
-  DCHECK(!heap_object->IsHashTable());
+  if (SerializeKnownObject(obj, how_to_code, where_to_point, skip)) return;
 
-  if (address_mapper_.IsMapped(heap_object)) {
-    SerializeReferenceToPreviousObject(heap_object, how_to_code, where_to_point,
-                                       skip);
-    return;
-  }
+  FlushSkip(skip);
 
-  if (heap_object->IsCode()) {
-    Code* code_object = Code::cast(heap_object);
-    if (code_object->kind() == Code::BUILTIN) {
-      SerializeBuiltin(code_object, how_to_code, where_to_point, skip);
-      return;
+  if (obj->IsCode()) {
+    Code* code_object = Code::cast(obj);
+    switch (code_object->kind()) {
+      case Code::OPTIMIZED_FUNCTION:  // No optimized code compiled yet.
+      case Code::HANDLER:             // No handlers patched in yet.
+      case Code::REGEXP:              // No regexp literals initialized yet.
+      case Code::NUMBER_OF_KINDS:     // Pseudo enum value.
+        CHECK(false);
+      case Code::BUILTIN:
+        SerializeBuiltin(code_object->builtin_index(), how_to_code,
+                         where_to_point);
+        return;
+      case Code::STUB:
+        SerializeCodeStub(code_object->stub_key(), how_to_code, where_to_point);
+        return;
+#define IC_KIND_CASE(KIND) case Code::KIND:
+        IC_KIND_LIST(IC_KIND_CASE)
+#undef IC_KIND_CASE
+        SerializeIC(code_object, how_to_code, where_to_point);
+        return;
+      case Code::FUNCTION:
+        DCHECK(code_object->has_reloc_info_for_serialization());
+        // Only serialize the code for the toplevel function unless specified
+        // by flag. Replace code of inner functions by the lazy compile builtin.
+        // This is safe, as checked in Compiler::BuildFunctionInfo.
+        if (code_object != main_code_ && !FLAG_serialize_inner) {
+          SerializeBuiltin(Builtins::kCompileLazy, how_to_code, where_to_point);
+        } else {
+          SerializeGeneric(code_object, how_to_code, where_to_point);
+        }
+        return;
     }
-    if (code_object->IsCodeStubOrIC()) {
-      SerializeCodeStub(code_object, how_to_code, where_to_point, skip);
-      return;
-    }
-    code_object->ClearInlineCaches();
+    UNREACHABLE();
   }
 
-  if (heap_object == source_) {
-    SerializeSourceObject(how_to_code, where_to_point, skip);
-    return;
-  }
+  // Past this point we should not see any (context-specific) maps anymore.
+  CHECK(!obj->IsMap());
+  // There should be no references to the global object embedded.
+  CHECK(!obj->IsJSGlobalProxy() && !obj->IsGlobalObject());
+  // There should be no hash table embedded. They would require rehashing.
+  CHECK(!obj->IsHashTable());
+  // We expect no instantiated function objects or contexts.
+  CHECK(!obj->IsJSFunction() && !obj->IsContext());
 
-  SerializeHeapObject(heap_object, how_to_code, where_to_point, skip);
+  SerializeGeneric(obj, how_to_code, where_to_point);
 }
 
 
-void CodeSerializer::SerializeHeapObject(HeapObject* heap_object,
-                                         HowToCode how_to_code,
-                                         WhereToPoint where_to_point,
-                                         int skip) {
-  if (heap_object->IsScript()) {
-    // The wrapper cache uses a Foreign object to point to a global handle.
-    // However, the object visitor expects foreign objects to point to external
-    // references.  Clear the cache to avoid this issue.
-    Script::cast(heap_object)->ClearWrapperCache();
-  }
-
-  if (skip != 0) {
-    sink_->Put(kSkip, "SkipFromSerializeObject");
-    sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
-  }
-
-  if (FLAG_trace_code_serializer) {
-    PrintF("Encoding heap object: ");
-    heap_object->ShortPrint();
-    PrintF("\n");
-  }
+void CodeSerializer::SerializeGeneric(HeapObject* heap_object,
+                                      HowToCode how_to_code,
+                                      WhereToPoint where_to_point) {
+  if (heap_object->IsInternalizedString()) num_internalized_strings_++;
 
   // Object has not yet been serialized.  Serialize it here.
   ObjectSerializer serializer(this, heap_object, sink_, how_to_code,
@@ -1889,22 +2172,16 @@
 }
 
 
-void CodeSerializer::SerializeBuiltin(Code* builtin, HowToCode how_to_code,
-                                      WhereToPoint where_to_point, int skip) {
-  if (skip != 0) {
-    sink_->Put(kSkip, "SkipFromSerializeBuiltin");
-    sink_->PutInt(skip, "SkipDistanceFromSerializeBuiltin");
-  }
-
+void CodeSerializer::SerializeBuiltin(int builtin_index, HowToCode how_to_code,
+                                      WhereToPoint where_to_point) {
   DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
          (how_to_code == kPlain && where_to_point == kInnerPointer) ||
          (how_to_code == kFromCode && where_to_point == kInnerPointer));
-  int builtin_index = builtin->builtin_index();
   DCHECK_LT(builtin_index, Builtins::builtin_count);
   DCHECK_LE(0, builtin_index);
 
-  if (FLAG_trace_code_serializer) {
-    PrintF("Encoding builtin: %s\n",
+  if (FLAG_trace_serializer) {
+    PrintF(" Encoding builtin: %s\n",
            isolate()->builtins()->name(builtin_index));
   }
 
@@ -1913,30 +2190,18 @@
 }
 
 
-void CodeSerializer::SerializeCodeStub(Code* code, HowToCode how_to_code,
-                                       WhereToPoint where_to_point, int skip) {
+void CodeSerializer::SerializeCodeStub(uint32_t stub_key, HowToCode how_to_code,
+                                       WhereToPoint where_to_point) {
   DCHECK((how_to_code == kPlain && where_to_point == kStartOfObject) ||
          (how_to_code == kPlain && where_to_point == kInnerPointer) ||
          (how_to_code == kFromCode && where_to_point == kInnerPointer));
-  uint32_t stub_key = code->stub_key();
-
-  if (stub_key == CodeStub::NoCacheKey()) {
-    if (FLAG_trace_code_serializer) {
-      PrintF("Encoding uncacheable code stub as heap object\n");
-    }
-    SerializeHeapObject(code, how_to_code, where_to_point, skip);
-    return;
-  }
-
-  if (skip != 0) {
-    sink_->Put(kSkip, "SkipFromSerializeCodeStub");
-    sink_->PutInt(skip, "SkipDistanceFromSerializeCodeStub");
-  }
+  DCHECK(CodeStub::MajorKeyFromKey(stub_key) != CodeStub::NoCache);
+  DCHECK(!CodeStub::GetCode(isolate(), stub_key).is_null());
 
   int index = AddCodeStubKey(stub_key) + kCodeStubsBaseIndex;
 
-  if (FLAG_trace_code_serializer) {
-    PrintF("Encoding code stub %s as %d\n",
+  if (FLAG_trace_serializer) {
+    PrintF(" Encoding code stub %s as %d\n",
            CodeStub::MajorName(CodeStub::MajorKeyFromKey(stub_key), false),
            index);
   }
@@ -1946,6 +2211,44 @@
 }
 
 
+void CodeSerializer::SerializeIC(Code* ic, HowToCode how_to_code,
+                                 WhereToPoint where_to_point) {
+  // The IC may be implemented as a stub.
+  uint32_t stub_key = ic->stub_key();
+  if (stub_key != CodeStub::NoCacheKey()) {
+    if (FLAG_trace_serializer) {
+      PrintF(" %s is a code stub\n", Code::Kind2String(ic->kind()));
+    }
+    SerializeCodeStub(stub_key, how_to_code, where_to_point);
+    return;
+  }
+  // The IC may be implemented as builtin. Only real builtins have an
+  // actual builtin_index value attached (otherwise it's just garbage).
+  // Compare to make sure we are really dealing with a builtin.
+  int builtin_index = ic->builtin_index();
+  if (builtin_index < Builtins::builtin_count) {
+    Builtins::Name name = static_cast<Builtins::Name>(builtin_index);
+    Code* builtin = isolate()->builtins()->builtin(name);
+    if (builtin == ic) {
+      if (FLAG_trace_serializer) {
+        PrintF(" %s is a builtin\n", Code::Kind2String(ic->kind()));
+      }
+      DCHECK(ic->kind() == Code::KEYED_LOAD_IC ||
+             ic->kind() == Code::KEYED_STORE_IC);
+      SerializeBuiltin(builtin_index, how_to_code, where_to_point);
+      return;
+    }
+  }
+  // The IC may also just be a piece of code kept in the non_monomorphic_cache.
+  // In that case, just serialize as a normal code object.
+  if (FLAG_trace_serializer) {
+    PrintF(" %s has no special handling\n", Code::Kind2String(ic->kind()));
+  }
+  DCHECK(ic->kind() == Code::LOAD_IC || ic->kind() == Code::STORE_IC);
+  SerializeGeneric(ic, how_to_code, where_to_point);
+}
+
+
 int CodeSerializer::AddCodeStubKey(uint32_t stub_key) {
   // TODO(yangguo) Maybe we need a hash table for a faster lookup than O(n^2).
   int index = 0;
@@ -1959,16 +2262,8 @@
 
 
 void CodeSerializer::SerializeSourceObject(HowToCode how_to_code,
-                                           WhereToPoint where_to_point,
-                                           int skip) {
-  if (skip != 0) {
-    sink_->Put(kSkip, "SkipFromSerializeSourceObject");
-    sink_->PutInt(skip, "SkipDistanceFromSerializeSourceObject");
-  }
-
-  if (FLAG_trace_code_serializer) {
-    PrintF("Encoding source object\n");
-  }
+                                           WhereToPoint where_to_point) {
+  if (FLAG_trace_serializer) PrintF(" Encoding source object\n");
 
   DCHECK(how_to_code == kPlain && where_to_point == kStartOfObject);
   sink_->Put(kAttachedReference + how_to_code + where_to_point, "Source");
@@ -1976,9 +2271,8 @@
 }
 
 
-Handle<SharedFunctionInfo> CodeSerializer::Deserialize(Isolate* isolate,
-                                                       ScriptData* data,
-                                                       Handle<String> source) {
+MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
+    Isolate* isolate, ScriptData* cached_data, Handle<String> source) {
   base::ElapsedTimer timer;
   if (FLAG_profile_deserialization) timer.Start();
 
@@ -1987,16 +2281,20 @@
   {
     HandleScope scope(isolate);
 
-    SerializedCodeData scd(data, *source);
-    SnapshotByteSource payload(scd.Payload(), scd.PayloadLength());
-    Deserializer deserializer(&payload);
-    STATIC_ASSERT(NEW_SPACE == 0);
-    for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) {
-      deserializer.set_reservation(i, scd.GetReservation(i));
+    SmartPointer<SerializedCodeData> scd(
+        SerializedCodeData::FromCachedData(cached_data, *source));
+    if (scd.is_empty()) {
+      if (FLAG_profile_deserialization) PrintF("[Cached code failed check]\n");
+      DCHECK(cached_data->rejected());
+      return MaybeHandle<SharedFunctionInfo>();
     }
 
+    // Eagerly expand string table to avoid allocations during deserialization.
+    StringTable::EnsureCapacityForDeserialization(
+        isolate, scd->NumInternalizedStrings());
+
     // Prepare and register list of attached objects.
-    Vector<const uint32_t> code_stub_keys = scd.CodeStubKeys();
+    Vector<const uint32_t> code_stub_keys = scd->CodeStubKeys();
     Vector<Handle<Object> > attached_objects = Vector<Handle<Object> >::New(
         code_stub_keys.length() + kCodeStubsBaseIndex);
     attached_objects[kSourceObjectIndex] = source;
@@ -2004,69 +2302,232 @@
       attached_objects[i + kCodeStubsBaseIndex] =
           CodeStub::GetCode(isolate, code_stub_keys[i]).ToHandleChecked();
     }
+
+    Deserializer deserializer(scd.get());
     deserializer.SetAttachedObjects(&attached_objects);
 
     // Deserialize.
-    deserializer.DeserializePartial(isolate, &root);
+    deserializer.DeserializePartial(isolate, &root, Deserializer::NULL_ON_OOM);
+    if (root == NULL) {
+      // Deserializing may fail if the reservations cannot be fulfilled.
+      if (FLAG_profile_deserialization) PrintF("[Deserializing failed]\n");
+      return MaybeHandle<SharedFunctionInfo>();
+    }
     deserializer.FlushICacheForNewCodeObjects();
   }
 
   if (FLAG_profile_deserialization) {
     double ms = timer.Elapsed().InMillisecondsF();
-    int length = data->length();
+    int length = cached_data->length();
     PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms);
   }
-  return Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(root), isolate);
-}
+  Handle<SharedFunctionInfo> result(SharedFunctionInfo::cast(root), isolate);
+  result->set_deserialized(true);
 
-
-SerializedCodeData::SerializedCodeData(List<byte>* payload, CodeSerializer* cs)
-    : owns_script_data_(true) {
-  DisallowHeapAllocation no_gc;
-  List<uint32_t>* stub_keys = cs->stub_keys();
-
-  // Calculate sizes.
-  int num_stub_keys = stub_keys->length();
-  int stub_keys_size = stub_keys->length() * kInt32Size;
-  int data_length = kHeaderSize + stub_keys_size + payload->length();
-
-  // Allocate backing store and create result data.
-  byte* data = NewArray<byte>(data_length);
-  DCHECK(IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment));
-  script_data_ = new ScriptData(data, data_length);
-  script_data_->AcquireDataOwnership();
-
-  // Set header values.
-  SetHeaderValue(kCheckSumOffset, CheckSum(cs->source()));
-  SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys);
-  SetHeaderValue(kPayloadLengthOffset, payload->length());
-  STATIC_ASSERT(NEW_SPACE == 0);
-  for (int i = NEW_SPACE; i <= PROPERTY_CELL_SPACE; i++) {
-    SetHeaderValue(kReservationsOffset + i, cs->CurrentAllocationAddress(i));
+  if (isolate->logger()->is_logging_code_events() ||
+      isolate->cpu_profiler()->is_profiling()) {
+    String* name = isolate->heap()->empty_string();
+    if (result->script()->IsScript()) {
+      Script* script = Script::cast(result->script());
+      if (script->name()->IsString()) name = String::cast(script->name());
+    }
+    isolate->logger()->CodeCreateEvent(Logger::SCRIPT_TAG, result->code(),
+                                       *result, NULL, name);
   }
 
-  // Copy code stub keys.
-  CopyBytes(data + kHeaderSize, reinterpret_cast<byte*>(stub_keys->begin()),
-            stub_keys_size);
+  return result;
+}
+
+
+void SerializedData::AllocateData(int size) {
+  DCHECK(!owns_data_);
+  data_ = NewArray<byte>(size);
+  size_ = size;
+  owns_data_ = true;
+  DCHECK(IsAligned(reinterpret_cast<intptr_t>(data_), kPointerAlignment));
+}
+
+
+SnapshotData::SnapshotData(const SnapshotByteSink& sink,
+                           const Serializer& ser) {
+  DisallowHeapAllocation no_gc;
+  List<Reservation> reservations;
+  ser.EncodeReservations(&reservations);
+  const List<byte>& payload = sink.data();
+
+  // Calculate sizes.
+  int reservation_size = reservations.length() * kInt32Size;
+  int size = kHeaderSize + reservation_size + payload.length();
+
+  // Allocate backing store and create result data.
+  AllocateData(size);
+
+  // Set header values.
+  SetHeaderValue(kCheckSumOffset, Version::Hash());
+  SetHeaderValue(kReservationsOffset, reservations.length());
+  SetHeaderValue(kPayloadLengthOffset, payload.length());
+
+  // Copy reservation chunk sizes.
+  CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
+            reservation_size);
 
   // Copy serialized data.
-  CopyBytes(data + kHeaderSize + stub_keys_size, payload->begin(),
-            static_cast<size_t>(payload->length()));
+  CopyBytes(data_ + kHeaderSize + reservation_size, payload.begin(),
+            static_cast<size_t>(payload.length()));
 }
 
 
-bool SerializedCodeData::IsSane(String* source) {
-  return GetHeaderValue(kCheckSumOffset) == CheckSum(source) &&
-         PayloadLength() >= SharedFunctionInfo::kSize;
+bool SnapshotData::IsSane() {
+  return GetHeaderValue(kCheckSumOffset) == Version::Hash();
 }
 
 
-int SerializedCodeData::CheckSum(String* string) {
-  int checksum = Version::Hash();
-#ifdef DEBUG
-  uint32_t seed = static_cast<uint32_t>(checksum);
-  checksum = static_cast<int>(IteratingStringHasher::Hash(string, seed));
-#endif  // DEBUG
-  return checksum;
+Vector<const SerializedData::Reservation> SnapshotData::Reservations() const {
+  return Vector<const Reservation>(
+      reinterpret_cast<const Reservation*>(data_ + kHeaderSize),
+      GetHeaderValue(kReservationsOffset));
+}
+
+
+Vector<const byte> SnapshotData::Payload() const {
+  int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
+  const byte* payload = data_ + kHeaderSize + reservations_size;
+  int length = GetHeaderValue(kPayloadLengthOffset);
+  DCHECK_EQ(data_ + size_, payload + length);
+  return Vector<const byte>(payload, length);
+}
+
+
+class Checksum {
+ public:
+  explicit Checksum(Vector<const byte> payload) {
+    // Fletcher's checksum. Modified to reduce 64-bit sums to 32-bit.
+    uintptr_t a = 1;
+    uintptr_t b = 0;
+    const uintptr_t* cur = reinterpret_cast<const uintptr_t*>(payload.start());
+    DCHECK(IsAligned(payload.length(), kIntptrSize));
+    const uintptr_t* end = cur + payload.length() / kIntptrSize;
+    while (cur < end) {
+      // Unsigned overflow expected and intended.
+      a += *cur++;
+      b += a;
+    }
+#if V8_HOST_ARCH_64_BIT
+    a ^= a >> 32;
+    b ^= b >> 32;
+#endif  // V8_HOST_ARCH_64_BIT
+    a_ = static_cast<uint32_t>(a);
+    b_ = static_cast<uint32_t>(b);
+  }
+
+  bool Check(uint32_t a, uint32_t b) const { return a == a_ && b == b_; }
+
+  uint32_t a() const { return a_; }
+  uint32_t b() const { return b_; }
+
+ private:
+  uint32_t a_;
+  uint32_t b_;
+
+  DISALLOW_COPY_AND_ASSIGN(Checksum);
+};
+
+
+SerializedCodeData::SerializedCodeData(const List<byte>& payload,
+                                       const CodeSerializer& cs) {
+  DisallowHeapAllocation no_gc;
+  const List<uint32_t>* stub_keys = cs.stub_keys();
+
+  List<Reservation> reservations;
+  cs.EncodeReservations(&reservations);
+
+  // Calculate sizes.
+  int reservation_size = reservations.length() * kInt32Size;
+  int num_stub_keys = stub_keys->length();
+  int stub_keys_size = stub_keys->length() * kInt32Size;
+  int size = kHeaderSize + reservation_size + stub_keys_size + payload.length();
+
+  // Allocate backing store and create result data.
+  AllocateData(size);
+
+  // Set header values.
+  SetHeaderValue(kVersionHashOffset, Version::Hash());
+  SetHeaderValue(kSourceHashOffset, SourceHash(cs.source()));
+  SetHeaderValue(kCpuFeaturesOffset,
+                 static_cast<uint32_t>(CpuFeatures::SupportedFeatures()));
+  SetHeaderValue(kFlagHashOffset, FlagList::Hash());
+  SetHeaderValue(kNumInternalizedStringsOffset, cs.num_internalized_strings());
+  SetHeaderValue(kReservationsOffset, reservations.length());
+  SetHeaderValue(kNumCodeStubKeysOffset, num_stub_keys);
+  SetHeaderValue(kPayloadLengthOffset, payload.length());
+
+  Checksum checksum(payload.ToConstVector());
+  SetHeaderValue(kChecksum1Offset, checksum.a());
+  SetHeaderValue(kChecksum2Offset, checksum.b());
+
+  // Copy reservation chunk sizes.
+  CopyBytes(data_ + kHeaderSize, reinterpret_cast<byte*>(reservations.begin()),
+            reservation_size);
+
+  // Copy code stub keys.
+  CopyBytes(data_ + kHeaderSize + reservation_size,
+            reinterpret_cast<byte*>(stub_keys->begin()), stub_keys_size);
+
+  // Copy serialized data.
+  CopyBytes(data_ + kHeaderSize + reservation_size + stub_keys_size,
+            payload.begin(), static_cast<size_t>(payload.length()));
+}
+
+
+bool SerializedCodeData::IsSane(String* source) const {
+  return GetHeaderValue(kVersionHashOffset) == Version::Hash() &&
+         GetHeaderValue(kSourceHashOffset) == SourceHash(source) &&
+         GetHeaderValue(kCpuFeaturesOffset) ==
+             static_cast<uint32_t>(CpuFeatures::SupportedFeatures()) &&
+         GetHeaderValue(kFlagHashOffset) == FlagList::Hash() &&
+         Checksum(Payload()).Check(GetHeaderValue(kChecksum1Offset),
+                                   GetHeaderValue(kChecksum2Offset));
+}
+
+
+// Return ScriptData object and relinquish ownership over it to the caller.
+ScriptData* SerializedCodeData::GetScriptData() {
+  DCHECK(owns_data_);
+  ScriptData* result = new ScriptData(data_, size_);
+  result->AcquireDataOwnership();
+  owns_data_ = false;
+  data_ = NULL;
+  return result;
+}
+
+
+Vector<const SerializedData::Reservation> SerializedCodeData::Reservations()
+    const {
+  return Vector<const Reservation>(
+      reinterpret_cast<const Reservation*>(data_ + kHeaderSize),
+      GetHeaderValue(kReservationsOffset));
+}
+
+
+Vector<const byte> SerializedCodeData::Payload() const {
+  int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
+  int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size;
+  const byte* payload =
+      data_ + kHeaderSize + reservations_size + code_stubs_size;
+  int length = GetHeaderValue(kPayloadLengthOffset);
+  DCHECK_EQ(data_ + size_, payload + length);
+  return Vector<const byte>(payload, length);
+}
+
+
+int SerializedCodeData::NumInternalizedStrings() const {
+  return GetHeaderValue(kNumInternalizedStringsOffset);
+}
+
+Vector<const uint32_t> SerializedCodeData::CodeStubKeys() const {
+  int reservations_size = GetHeaderValue(kReservationsOffset) * kInt32Size;
+  const byte* start = data_ + kHeaderSize + reservations_size;
+  return Vector<const uint32_t>(reinterpret_cast<const uint32_t*>(start),
+                                GetHeaderValue(kNumCodeStubKeysOffset));
 }
 } }  // namespace v8::internal
diff --git a/src/serialize.h b/src/serialize.h
index 71b274b..da750cb 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -24,7 +24,7 @@
   IC_UTILITY,
   STATS_COUNTER,
   TOP_ADDRESS,
-  ACCESSOR,
+  ACCESSOR_CODE,
   STUB_CACHE_TABLE,
   RUNTIME_ENTRY,
   LAZY_DEOPTIMIZATION
@@ -139,6 +139,189 @@
 };
 
 
+class AddressMapBase {
+ protected:
+  static void SetValue(HashMap::Entry* entry, uint32_t v) {
+    entry->value = reinterpret_cast<void*>(v);
+  }
+
+  static uint32_t GetValue(HashMap::Entry* entry) {
+    return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry->value));
+  }
+
+  static HashMap::Entry* LookupEntry(HashMap* map, HeapObject* obj,
+                                     bool insert) {
+    return map->Lookup(Key(obj), Hash(obj), insert);
+  }
+
+ private:
+  static uint32_t Hash(HeapObject* obj) {
+    return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address()));
+  }
+
+  static void* Key(HeapObject* obj) {
+    return reinterpret_cast<void*>(obj->address());
+  }
+};
+
+
+class RootIndexMap : public AddressMapBase {
+ public:
+  explicit RootIndexMap(Isolate* isolate);
+
+  ~RootIndexMap() { delete map_; }
+
+  static const int kInvalidRootIndex = -1;
+  int Lookup(HeapObject* obj) {
+    HashMap::Entry* entry = LookupEntry(map_, obj, false);
+    if (entry) return GetValue(entry);
+    return kInvalidRootIndex;
+  }
+
+ private:
+  HashMap* map_;
+
+  DISALLOW_COPY_AND_ASSIGN(RootIndexMap);
+};
+
+
+class BackReference {
+ public:
+  explicit BackReference(uint32_t bitfield) : bitfield_(bitfield) {}
+
+  BackReference() : bitfield_(kInvalidValue) {}
+
+  static BackReference SourceReference() { return BackReference(kSourceValue); }
+
+  static BackReference LargeObjectReference(uint32_t index) {
+    return BackReference(SpaceBits::encode(LO_SPACE) |
+                         ChunkOffsetBits::encode(index));
+  }
+
+  static BackReference Reference(AllocationSpace space, uint32_t chunk_index,
+                                 uint32_t chunk_offset) {
+    DCHECK(IsAligned(chunk_offset, kObjectAlignment));
+    DCHECK_NE(LO_SPACE, space);
+    return BackReference(
+        SpaceBits::encode(space) | ChunkIndexBits::encode(chunk_index) |
+        ChunkOffsetBits::encode(chunk_offset >> kObjectAlignmentBits));
+  }
+
+  bool is_valid() const { return bitfield_ != kInvalidValue; }
+  bool is_source() const { return bitfield_ == kSourceValue; }
+
+  AllocationSpace space() const {
+    DCHECK(is_valid());
+    return SpaceBits::decode(bitfield_);
+  }
+
+  uint32_t chunk_offset() const {
+    DCHECK(is_valid());
+    return ChunkOffsetBits::decode(bitfield_) << kObjectAlignmentBits;
+  }
+
+  uint32_t chunk_index() const {
+    DCHECK(is_valid());
+    return ChunkIndexBits::decode(bitfield_);
+  }
+
+  uint32_t reference() const {
+    DCHECK(is_valid());
+    return bitfield_ & (ChunkOffsetBits::kMask | ChunkIndexBits::kMask);
+  }
+
+  uint32_t bitfield() const { return bitfield_; }
+
+ private:
+  static const uint32_t kInvalidValue = 0xFFFFFFFF;
+  static const uint32_t kSourceValue = 0xFFFFFFFE;
+  static const int kChunkOffsetSize = kPageSizeBits - kObjectAlignmentBits;
+  static const int kChunkIndexSize = 32 - kChunkOffsetSize - kSpaceTagSize;
+
+ public:
+  static const int kMaxChunkIndex = (1 << kChunkIndexSize) - 1;
+
+ private:
+  class ChunkOffsetBits : public BitField<uint32_t, 0, kChunkOffsetSize> {};
+  class ChunkIndexBits
+      : public BitField<uint32_t, ChunkOffsetBits::kNext, kChunkIndexSize> {};
+  class SpaceBits
+      : public BitField<AllocationSpace, ChunkIndexBits::kNext, kSpaceTagSize> {
+  };
+
+  uint32_t bitfield_;
+};
+
+
+// Mapping objects to their location after deserialization.
+// This is used during building, but not at runtime by V8.
+class BackReferenceMap : public AddressMapBase {
+ public:
+  BackReferenceMap()
+      : no_allocation_(), map_(new HashMap(HashMap::PointersMatch)) {}
+
+  ~BackReferenceMap() { delete map_; }
+
+  BackReference Lookup(HeapObject* obj) {
+    HashMap::Entry* entry = LookupEntry(map_, obj, false);
+    return entry ? BackReference(GetValue(entry)) : BackReference();
+  }
+
+  void Add(HeapObject* obj, BackReference b) {
+    DCHECK(b.is_valid());
+    DCHECK_EQ(NULL, LookupEntry(map_, obj, false));
+    HashMap::Entry* entry = LookupEntry(map_, obj, true);
+    SetValue(entry, b.bitfield());
+  }
+
+  void AddSourceString(String* string) {
+    Add(string, BackReference::SourceReference());
+  }
+
+ private:
+  DisallowHeapAllocation no_allocation_;
+  HashMap* map_;
+  DISALLOW_COPY_AND_ASSIGN(BackReferenceMap);
+};
+
+
+class HotObjectsList {
+ public:
+  HotObjectsList() : index_(0) {
+    for (int i = 0; i < kSize; i++) circular_queue_[i] = NULL;
+  }
+
+  void Add(HeapObject* object) {
+    circular_queue_[index_] = object;
+    index_ = (index_ + 1) & kSizeMask;
+  }
+
+  HeapObject* Get(int index) {
+    DCHECK_NE(NULL, circular_queue_[index]);
+    return circular_queue_[index];
+  }
+
+  static const int kNotFound = -1;
+
+  int Find(HeapObject* object) {
+    for (int i = 0; i < kSize; i++) {
+      if (circular_queue_[i] == object) return i;
+    }
+    return kNotFound;
+  }
+
+  static const int kSize = 8;
+
+ private:
+  STATIC_ASSERT(IS_POWER_OF_TWO(kSize));
+  static const int kSizeMask = kSize - 1;
+  HeapObject* circular_queue_[kSize];
+  int index_;
+
+  DISALLOW_COPY_AND_ASSIGN(HotObjectsList);
+};
+
+
 // The Serializer/Deserializer class is a common superclass for Serializer and
 // Deserializer which is used to store common constants and methods used by
 // both.
@@ -148,23 +331,28 @@
 
   static int nop() { return kNop; }
 
+  // No reservation for large object space necessary.
+  static const int kNumberOfPreallocatedSpaces = LO_SPACE;
+  static const int kNumberOfSpaces = LAST_SPACE + 1;
+
  protected:
   // Where the pointed-to object can be found:
   enum Where {
-    kNewObject = 0,  // Object is next in snapshot.
-    // 1-6                             One per space.
+    kNewObject = 0,  //              Object is next in snapshot.
+    // 1-7                           One per space.
+    // 0x8                           Unused.
     kRootArray = 0x9,             // Object is found in root array.
     kPartialSnapshotCache = 0xa,  // Object is in the cache.
     kExternalReference = 0xb,     // Pointer to an external reference.
     kSkip = 0xc,                  // Skip n bytes.
     kBuiltin = 0xd,               // Builtin code object.
     kAttachedReference = 0xe,     // Object is described in an attached list.
-    kNop = 0xf,                   // Does nothing, used to pad.
-    kBackref = 0x10,              // Object is described relative to end.
-    // 0x11-0x16                       One per space.
-    kBackrefWithSkip = 0x18,  // Object is described relative to end.
-    // 0x19-0x1e                       One per space.
-    // 0x20-0x3f                       Used by misc. tags below.
+    // 0xf                           Used by misc. See below.
+    kBackref = 0x10,  //             Object is described relative to end.
+    // 0x11-0x17                     One per space.
+    kBackrefWithSkip = 0x18,  //     Object is described relative to end.
+    // 0x19-0x1f                     One per space.
+    // 0x20-0x3f                     Used by misc. See below.
     kPointedToMask = 0x3f
   };
 
@@ -196,40 +384,118 @@
   // entire code in one memcpy, then fix up stuff with kSkip and other byte
   // codes that overwrite data.
   static const int kRawData = 0x20;
-  // Some common raw lengths: 0x21-0x3f.  These autoadvance the current pointer.
-  // A tag emitted at strategic points in the snapshot to delineate sections.
-  // If the deserializer does not find these at the expected moments then it
-  // is an indication that the snapshot and the VM do not fit together.
-  // Examine the build process for architecture, version or configuration
-  // mismatches.
-  static const int kSynchronize = 0x70;
-  // Used for the source code of the natives, which is in the executable, but
-  // is referred to from external strings in the snapshot.
-  static const int kNativesStringResource = 0x71;
-  static const int kRepeat = 0x72;
-  static const int kConstantRepeat = 0x73;
-  // 0x73-0x7f            Repeat last word (subtract 0x72 to get the count).
-  static const int kMaxRepeats = 0x7f - 0x72;
+  // Some common raw lengths: 0x21-0x3f.
+  // These autoadvance the current pointer.
+  static const int kOnePointerRawData = 0x21;
+
+  static const int kVariableRepeat = 0x60;
+  // 0x61-0x6f   Repeat last word
+  static const int kFixedRepeat = 0x61;
+  static const int kFixedRepeatBase = kFixedRepeat - 1;
+  static const int kLastFixedRepeat = 0x6f;
+  static const int kMaxFixedRepeats = kLastFixedRepeat - kFixedRepeatBase;
   static int CodeForRepeats(int repeats) {
-    DCHECK(repeats >= 1 && repeats <= kMaxRepeats);
-    return 0x72 + repeats;
+    DCHECK(repeats >= 1 && repeats <= kMaxFixedRepeats);
+    return kFixedRepeatBase + repeats;
   }
   static int RepeatsForCode(int byte_code) {
-    DCHECK(byte_code >= kConstantRepeat && byte_code <= 0x7f);
-    return byte_code - 0x72;
+    DCHECK(byte_code > kFixedRepeatBase && byte_code <= kLastFixedRepeat);
+    return byte_code - kFixedRepeatBase;
   }
+
+  // Hot objects are a small set of recently seen or back-referenced objects.
+  // They are represented by a single opcode to save space.
+  // We use 0x70..0x77 for 8 hot objects, and 0x78..0x7f to add skip.
+  static const int kHotObject = 0x70;
+  static const int kMaxHotObjectIndex = 0x77 - kHotObject;
+  static const int kHotObjectWithSkip = 0x78;
+  STATIC_ASSERT(HotObjectsList::kSize == kMaxHotObjectIndex + 1);
+  STATIC_ASSERT(0x7f - kHotObjectWithSkip == kMaxHotObjectIndex);
+  static const int kHotObjectIndexMask = 0x7;
+
   static const int kRootArrayConstants = 0xa0;
-  // 0xa0-0xbf            Things from the first 32 elements of the root array.
+  // 0xa0-0xbf  Things from the first 32 elements of the root array.
   static const int kRootArrayNumberOfConstantEncodings = 0x20;
   static int RootArrayConstantFromByteCode(int byte_code) {
     return byte_code & 0x1f;
   }
 
-  static const int kNumberOfSpaces = LO_SPACE;
+  // Do nothing, used for padding.
+  static const int kNop = 0xf;
+
+  // Move to next reserved chunk.
+  static const int kNextChunk = 0x4f;
+
+  // A tag emitted at strategic points in the snapshot to delineate sections.
+  // If the deserializer does not find these at the expected moments then it
+  // is an indication that the snapshot and the VM do not fit together.
+  // Examine the build process for architecture, version or configuration
+  // mismatches.
+  static const int kSynchronize = 0x8f;
+
+  // Used for the source code of the natives, which is in the executable, but
+  // is referred to from external strings in the snapshot.
+  static const int kNativesStringResource = 0xcf;
+
   static const int kAnyOldSpace = -1;
 
   // A bitmask for getting the space out of an instruction.
   static const int kSpaceMask = 7;
+  STATIC_ASSERT(kNumberOfSpaces <= kSpaceMask + 1);
+
+  // Sentinel after a new object to indicate that double alignment is needed.
+  static const int kDoubleAlignmentSentinel = 0;
+
+  // Used as index for the attached reference representing the source object.
+  static const int kSourceObjectReference = 0;
+
+  HotObjectsList hot_objects_;
+};
+
+
+class SerializedData {
+ public:
+  class Reservation {
+   public:
+    explicit Reservation(uint32_t size)
+        : reservation_(ChunkSizeBits::encode(size)) {}
+
+    uint32_t chunk_size() const { return ChunkSizeBits::decode(reservation_); }
+    bool is_last() const { return IsLastChunkBits::decode(reservation_); }
+
+    void mark_as_last() { reservation_ |= IsLastChunkBits::encode(true); }
+
+   private:
+    uint32_t reservation_;
+  };
+
+  SerializedData(byte* data, int size)
+      : data_(data), size_(size), owns_data_(false) {}
+  SerializedData() : data_(NULL), size_(0), owns_data_(false) {}
+
+  ~SerializedData() {
+    if (owns_data_) DeleteArray<byte>(data_);
+  }
+
+  class ChunkSizeBits : public BitField<uint32_t, 0, 31> {};
+  class IsLastChunkBits : public BitField<bool, 31, 1> {};
+
+ protected:
+  void SetHeaderValue(int offset, uint32_t value) {
+    memcpy(reinterpret_cast<uint32_t*>(data_) + offset, &value, sizeof(value));
+  }
+
+  uint32_t GetHeaderValue(int offset) const {
+    uint32_t value;
+    memcpy(&value, reinterpret_cast<int*>(data_) + offset, sizeof(value));
+    return value;
+  }
+
+  void AllocateData(int size);
+
+  byte* data_;
+  int size_;
+  bool owns_data_;
 };
 
 
@@ -237,21 +503,27 @@
 class Deserializer: public SerializerDeserializer {
  public:
   // Create a deserializer from a snapshot byte source.
-  explicit Deserializer(SnapshotByteSource* source);
+  template <class Data>
+  explicit Deserializer(Data* data)
+      : isolate_(NULL),
+        attached_objects_(NULL),
+        source_(data->Payload()),
+        external_reference_decoder_(NULL),
+        deserialized_large_objects_(0) {
+    DecodeReservation(data->Reservations());
+  }
 
   virtual ~Deserializer();
 
   // Deserialize the snapshot into an empty heap.
   void Deserialize(Isolate* isolate);
 
-  // Deserialize a single object and the objects reachable from it.
-  void DeserializePartial(Isolate* isolate, Object** root);
+  enum OnOOM { FATAL_ON_OOM, NULL_ON_OOM };
 
-  void set_reservation(int space_number, int reservation) {
-    DCHECK(space_number >= 0);
-    DCHECK(space_number <= LAST_SPACE);
-    reservations_[space_number] = reservation;
-  }
+  // Deserialize a single object and the objects reachable from it.
+  // We may want to abort gracefully even if deserialization fails.
+  void DeserializePartial(Isolate* isolate, Object** root,
+                          OnOOM on_oom = FATAL_ON_OOM);
 
   void FlushICacheForNewCodeObjects();
 
@@ -270,6 +542,10 @@
     UNREACHABLE();
   }
 
+  void DecodeReservation(Vector<const SerializedData::Reservation> res);
+
+  bool ReserveSpace();
+
   // Allocation sites are present in the snapshot, and must be linked into
   // a list at deserialization time.
   void RelinkAllocationSite(AllocationSite* site);
@@ -279,30 +555,17 @@
   // of the object we are writing into, or NULL if we are not writing into an
   // object, i.e. if we are writing a series of tagged values that are not on
   // the heap.
-  void ReadChunk(
-      Object** start, Object** end, int space, Address object_address);
+  void ReadData(Object** start, Object** end, int space,
+                Address object_address);
   void ReadObject(int space_number, Object** write_back);
+  Address Allocate(int space_index, int size);
 
   // Special handling for serialized code like hooking up internalized strings.
   HeapObject* ProcessNewObjectFromSerializedCode(HeapObject* obj);
-  Object* ProcessBackRefInSerializedCode(Object* obj);
-
-  // This routine both allocates a new object, and also keeps
-  // track of where objects have been allocated so that we can
-  // fix back references when deserializing.
-  Address Allocate(int space_index, int size) {
-    Address address = high_water_[space_index];
-    high_water_[space_index] = address + size;
-    return address;
-  }
 
   // This returns the address of an object that has been described in the
-  // snapshot as being offset bytes back in a particular space.
-  HeapObject* GetAddressFromEnd(int space) {
-    int offset = source_->GetInt();
-    offset <<= kObjectAlignmentBits;
-    return HeapObject::FromAddress(high_water_[space] - offset);
-  }
+  // snapshot by chunk index and offset.
+  HeapObject* GetBackReferencedObject(int space);
 
   // Cached current isolate.
   Isolate* isolate_;
@@ -310,68 +573,23 @@
   // Objects from the attached object descriptions in the serialized user code.
   Vector<Handle<Object> >* attached_objects_;
 
-  SnapshotByteSource* source_;
-  // This is the address of the next object that will be allocated in each
-  // space.  It is used to calculate the addresses of back-references.
-  Address high_water_[LAST_SPACE + 1];
-
-  int reservations_[LAST_SPACE + 1];
-  static const intptr_t kUninitializedReservation = -1;
+  SnapshotByteSource source_;
+  // The address of the next object that will be allocated in each space.
+  // Each space has a number of chunks reserved by the GC, with each chunk
+  // fitting into a page. Deserialized objects are allocated into the
+  // current chunk of the target space by bumping up high water mark.
+  Heap::Reservation reservations_[kNumberOfSpaces];
+  uint32_t current_chunk_[kNumberOfPreallocatedSpaces];
+  Address high_water_[kNumberOfPreallocatedSpaces];
 
   ExternalReferenceDecoder* external_reference_decoder_;
 
+  List<HeapObject*> deserialized_large_objects_;
+
   DISALLOW_COPY_AND_ASSIGN(Deserializer);
 };
 
 
-// Mapping objects to their location after deserialization.
-// This is used during building, but not at runtime by V8.
-class SerializationAddressMapper {
- public:
-  SerializationAddressMapper()
-      : no_allocation_(),
-        serialization_map_(new HashMap(HashMap::PointersMatch)) { }
-
-  ~SerializationAddressMapper() {
-    delete serialization_map_;
-  }
-
-  bool IsMapped(HeapObject* obj) {
-    return serialization_map_->Lookup(Key(obj), Hash(obj), false) != NULL;
-  }
-
-  int MappedTo(HeapObject* obj) {
-    DCHECK(IsMapped(obj));
-    return static_cast<int>(reinterpret_cast<intptr_t>(
-        serialization_map_->Lookup(Key(obj), Hash(obj), false)->value));
-  }
-
-  void AddMapping(HeapObject* obj, int to) {
-    DCHECK(!IsMapped(obj));
-    HashMap::Entry* entry =
-        serialization_map_->Lookup(Key(obj), Hash(obj), true);
-    entry->value = Value(to);
-  }
-
- private:
-  static uint32_t Hash(HeapObject* obj) {
-    return static_cast<int32_t>(reinterpret_cast<intptr_t>(obj->address()));
-  }
-
-  static void* Key(HeapObject* obj) {
-    return reinterpret_cast<void*>(obj->address());
-  }
-
-  static void* Value(int v) {
-    return reinterpret_cast<void*>(v);
-  }
-
-  DisallowHeapAllocation no_allocation_;
-  HashMap* serialization_map_;
-  DISALLOW_COPY_AND_ASSIGN(SerializationAddressMapper);
-};
-
-
 class CodeAddressMap;
 
 // There can be only one serializer per V8 process.
@@ -379,33 +597,16 @@
  public:
   Serializer(Isolate* isolate, SnapshotByteSink* sink);
   ~Serializer();
-  void VisitPointers(Object** start, Object** end);
-  // You can call this after serialization to find out how much space was used
-  // in each space.
-  int CurrentAllocationAddress(int space) const {
-    DCHECK(space < kNumberOfSpaces);
-    return fullness_[space];
-  }
+  void VisitPointers(Object** start, Object** end) OVERRIDE;
+
+  void EncodeReservations(List<SerializedData::Reservation>* out) const;
 
   Isolate* isolate() const { return isolate_; }
 
-  SerializationAddressMapper* address_mapper() { return &address_mapper_; }
-  void PutRoot(int index,
-               HeapObject* object,
-               HowToCode how,
-               WhereToPoint where,
-               int skip);
+  BackReferenceMap* back_reference_map() { return &back_reference_map_; }
+  RootIndexMap* root_index_map() { return &root_index_map_; }
 
  protected:
-  static const int kInvalidRootIndex = -1;
-
-  int RootIndex(HeapObject* heap_object, HowToCode from);
-  intptr_t root_index_wave_front() { return root_index_wave_front_; }
-  void set_root_index_wave_front(intptr_t value) {
-    DCHECK(value >= root_index_wave_front_);
-    root_index_wave_front_ = value;
-  }
-
   class ObjectSerializer : public ObjectVisitor {
    public:
     ObjectSerializer(Serializer* serializer,
@@ -439,12 +640,16 @@
     }
 
    private:
+    void SerializePrologue(AllocationSpace space, int size, Map* map);
+
     enum ReturnSkip { kCanReturnSkipInsteadOfSkipping, kIgnoringReturn };
     // This function outputs or skips the raw data between the last pointer and
     // up to the current position.  It optionally can just return the number of
     // bytes to skip instead of performing a skip instruction, in case the skip
     // can be merged into the next instruction.
     int OutputRawData(Address up_to, ReturnSkip return_skip = kIgnoringReturn);
+    // External strings are serialized in a way to resemble sequential strings.
+    void SerializeExternalString();
 
     Serializer* serializer_;
     HeapObject* object_;
@@ -455,48 +660,74 @@
     bool code_has_been_output_;
   };
 
-  virtual void SerializeObject(Object* o,
-                               HowToCode how_to_code,
-                               WhereToPoint where_to_point,
-                               int skip) = 0;
-  void SerializeReferenceToPreviousObject(HeapObject* heap_object,
-                                          HowToCode how_to_code,
-                                          WhereToPoint where_to_point,
-                                          int skip);
+  virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
+                               WhereToPoint where_to_point, int skip) = 0;
+
+  void PutRoot(int index, HeapObject* object, HowToCode how, WhereToPoint where,
+               int skip);
+
+  // Returns true if the object was successfully serialized.
+  bool SerializeKnownObject(HeapObject* obj, HowToCode how_to_code,
+                            WhereToPoint where_to_point, int skip);
+
+  inline void FlushSkip(int skip) {
+    if (skip != 0) {
+      sink_->Put(kSkip, "SkipFromSerializeObject");
+      sink_->PutInt(skip, "SkipDistanceFromSerializeObject");
+    }
+  }
+
   void InitializeAllocators();
   // This will return the space for an object.
-  static int SpaceOfObject(HeapObject* object);
-  int Allocate(int space, int size);
+  static AllocationSpace SpaceOfObject(HeapObject* object);
+  BackReference AllocateLargeObject(int size);
+  BackReference Allocate(AllocationSpace space, int size);
   int EncodeExternalReference(Address addr) {
     return external_reference_encoder_->Encode(addr);
   }
 
-  int SpaceAreaSize(int space);
+  // GetInt reads 4 bytes at once, requiring padding at the end.
+  void Pad();
 
   // Some roots should not be serialized, because their actual value depends on
   // absolute addresses and they are reset after deserialization, anyway.
   bool ShouldBeSkipped(Object** current);
 
-  Isolate* isolate_;
-  // Keep track of the fullness of each space in order to generate
-  // relative addresses for back references.
-  int fullness_[LAST_SPACE + 1];
-  SnapshotByteSink* sink_;
-  ExternalReferenceEncoder* external_reference_encoder_;
-
-  SerializationAddressMapper address_mapper_;
-  intptr_t root_index_wave_front_;
-  void Pad();
-
-  friend class ObjectSerializer;
-  friend class Deserializer;
-
   // We may not need the code address map for logging for every instance
   // of the serializer.  Initialize it on demand.
   void InitializeCodeAddressMap();
 
+  inline uint32_t max_chunk_size(int space) const {
+    DCHECK_LE(0, space);
+    DCHECK_LT(space, kNumberOfSpaces);
+    return max_chunk_size_[space];
+  }
+
+  Isolate* isolate_;
+
+  SnapshotByteSink* sink_;
+  ExternalReferenceEncoder* external_reference_encoder_;
+
+  BackReferenceMap back_reference_map_;
+  RootIndexMap root_index_map_;
+
+  friend class ObjectSerializer;
+  friend class Deserializer;
+
  private:
   CodeAddressMap* code_address_map_;
+  // Objects from the same space are put into chunks for bulk-allocation
+  // when deserializing. We have to make sure that each chunk fits into a
+  // page. So we track the chunk size in pending_chunk_ of a space, but
+  // when it exceeds a page, we complete the current chunk and start a new one.
+  uint32_t pending_chunk_[kNumberOfPreallocatedSpaces];
+  List<uint32_t> completed_chunks_[kNumberOfPreallocatedSpaces];
+  uint32_t max_chunk_size_[kNumberOfPreallocatedSpaces];
+
+  // We map serialized large objects to indexes for back-referencing.
+  uint32_t large_objects_total_size_;
+  uint32_t seen_large_objects_index_;
+
   DISALLOW_COPY_AND_ASSIGN(Serializer);
 };
 
@@ -508,16 +739,13 @@
                     SnapshotByteSink* sink)
     : Serializer(isolate, sink),
       startup_serializer_(startup_snapshot_serializer) {
-    set_root_index_wave_front(Heap::kStrongRootListLength);
     InitializeCodeAddressMap();
   }
 
   // Serialize the objects reachable from a single object pointer.
   void Serialize(Object** o);
-  virtual void SerializeObject(Object* o,
-                               HowToCode how_to_code,
-                               WhereToPoint where_to_point,
-                               int skip);
+  virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
+                               WhereToPoint where_to_point, int skip) OVERRIDE;
 
  private:
   int PartialSnapshotCacheIndex(HeapObject* o);
@@ -543,7 +771,7 @@
 class StartupSerializer : public Serializer {
  public:
   StartupSerializer(Isolate* isolate, SnapshotByteSink* sink)
-    : Serializer(isolate, sink) {
+      : Serializer(isolate, sink), root_index_wave_front_(0) {
     // Clear the cache of objects used by the partial snapshot.  After the
     // strong roots have been serialized we can create a partial snapshot
     // which will repopulate the cache with objects needed by that partial
@@ -551,15 +779,18 @@
     isolate->set_serialize_partial_snapshot_cache_length(0);
     InitializeCodeAddressMap();
   }
+
+  // The StartupSerializer has to serialize the root array, which is slightly
+  // different.
+  void VisitPointers(Object** start, Object** end) OVERRIDE;
+
   // Serialize the current state of the heap.  The order is:
   // 1) Strong references.
   // 2) Partial snapshot cache.
   // 3) Weak references (e.g. the string table).
   virtual void SerializeStrongReferences();
-  virtual void SerializeObject(Object* o,
-                               HowToCode how_to_code,
-                               WhereToPoint where_to_point,
-                               int skip);
+  virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
+                               WhereToPoint where_to_point, int skip) OVERRIDE;
   void SerializeWeakReferences();
   void Serialize() {
     SerializeStrongReferences();
@@ -568,139 +799,155 @@
   }
 
  private:
+  intptr_t root_index_wave_front_;
   DISALLOW_COPY_AND_ASSIGN(StartupSerializer);
 };
 
 
 class CodeSerializer : public Serializer {
  public:
-  CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source)
-      : Serializer(isolate, sink), source_(source) {
-    set_root_index_wave_front(Heap::kStrongRootListLength);
-    InitializeCodeAddressMap();
-  }
-
   static ScriptData* Serialize(Isolate* isolate,
                                Handle<SharedFunctionInfo> info,
                                Handle<String> source);
 
-  virtual void SerializeObject(Object* o, HowToCode how_to_code,
-                               WhereToPoint where_to_point, int skip);
-
-  static Handle<SharedFunctionInfo> Deserialize(Isolate* isolate,
-                                                ScriptData* data,
-                                                Handle<String> source);
+  MUST_USE_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize(
+      Isolate* isolate, ScriptData* cached_data, Handle<String> source);
 
   static const int kSourceObjectIndex = 0;
+  STATIC_ASSERT(kSourceObjectReference == kSourceObjectIndex);
+
   static const int kCodeStubsBaseIndex = 1;
 
-  String* source() {
+  String* source() const {
     DCHECK(!AllowHeapAllocation::IsAllowed());
     return source_;
   }
 
-  List<uint32_t>* stub_keys() { return &stub_keys_; }
+  const List<uint32_t>* stub_keys() const { return &stub_keys_; }
+  int num_internalized_strings() const { return num_internalized_strings_; }
 
  private:
-  void SerializeBuiltin(Code* builtin, HowToCode how_to_code,
-                        WhereToPoint where_to_point, int skip);
-  void SerializeCodeStub(Code* code, HowToCode how_to_code,
-                         WhereToPoint where_to_point, int skip);
-  void SerializeSourceObject(HowToCode how_to_code, WhereToPoint where_to_point,
-                             int skip);
-  void SerializeHeapObject(HeapObject* heap_object, HowToCode how_to_code,
-                           WhereToPoint where_to_point, int skip);
+  CodeSerializer(Isolate* isolate, SnapshotByteSink* sink, String* source,
+                 Code* main_code)
+      : Serializer(isolate, sink),
+        source_(source),
+        main_code_(main_code),
+        num_internalized_strings_(0) {
+    back_reference_map_.AddSourceString(source);
+  }
+
+  virtual void SerializeObject(HeapObject* o, HowToCode how_to_code,
+                               WhereToPoint where_to_point, int skip) OVERRIDE;
+
+  void SerializeBuiltin(int builtin_index, HowToCode how_to_code,
+                        WhereToPoint where_to_point);
+  void SerializeIC(Code* ic, HowToCode how_to_code,
+                   WhereToPoint where_to_point);
+  void SerializeCodeStub(uint32_t stub_key, HowToCode how_to_code,
+                         WhereToPoint where_to_point);
+  void SerializeSourceObject(HowToCode how_to_code,
+                             WhereToPoint where_to_point);
+  void SerializeGeneric(HeapObject* heap_object, HowToCode how_to_code,
+                        WhereToPoint where_to_point);
   int AddCodeStubKey(uint32_t stub_key);
 
   DisallowHeapAllocation no_gc_;
   String* source_;
+  Code* main_code_;
+  int num_internalized_strings_;
   List<uint32_t> stub_keys_;
   DISALLOW_COPY_AND_ASSIGN(CodeSerializer);
 };
 
 
-// Wrapper around ScriptData to provide code-serializer-specific functionality.
-class SerializedCodeData {
+// Wrapper around reservation sizes and the serialization payload.
+class SnapshotData : public SerializedData {
  public:
-  // Used by when consuming.
-  explicit SerializedCodeData(ScriptData* data, String* source)
-      : script_data_(data), owns_script_data_(false) {
-    DisallowHeapAllocation no_gc;
-    CHECK(IsSane(source));
-  }
-
   // Used when producing.
-  SerializedCodeData(List<byte>* payload, CodeSerializer* cs);
+  SnapshotData(const SnapshotByteSink& sink, const Serializer& ser);
 
-  ~SerializedCodeData() {
-    if (owns_script_data_) delete script_data_;
+  // Used when consuming.
+  explicit SnapshotData(const Vector<const byte> snapshot)
+      : SerializedData(const_cast<byte*>(snapshot.begin()), snapshot.length()) {
+    CHECK(IsSane());
   }
 
-  // Return ScriptData object and relinquish ownership over it to the caller.
-  ScriptData* GetScriptData() {
-    ScriptData* result = script_data_;
-    script_data_ = NULL;
-    DCHECK(owns_script_data_);
-    owns_script_data_ = false;
-    return result;
-  }
+  Vector<const Reservation> Reservations() const;
+  Vector<const byte> Payload() const;
 
-  Vector<const uint32_t> CodeStubKeys() const {
-    return Vector<const uint32_t>(
-        reinterpret_cast<const uint32_t*>(script_data_->data() + kHeaderSize),
-        GetHeaderValue(kNumCodeStubKeysOffset));
-  }
-
-  const byte* Payload() const {
-    int code_stubs_size = GetHeaderValue(kNumCodeStubKeysOffset) * kInt32Size;
-    return script_data_->data() + kHeaderSize + code_stubs_size;
-  }
-
-  int PayloadLength() const {
-    int payload_length = GetHeaderValue(kPayloadLengthOffset);
-    DCHECK_EQ(script_data_->data() + script_data_->length(),
-              Payload() + payload_length);
-    return payload_length;
-  }
-
-  int GetReservation(int space) const {
-    return GetHeaderValue(kReservationsOffset + space);
+  Vector<const byte> RawData() const {
+    return Vector<const byte>(data_, size_);
   }
 
  private:
-  void SetHeaderValue(int offset, int value) {
-    reinterpret_cast<int*>(const_cast<byte*>(script_data_->data()))[offset] =
-        value;
+  bool IsSane();
+  // The data header consists of int-sized entries:
+  // [0] version hash
+  // [1] number of reservation size entries
+  // [2] payload length
+  static const int kCheckSumOffset = 0;
+  static const int kReservationsOffset = 1;
+  static const int kPayloadLengthOffset = 2;
+  static const int kHeaderSize = (kPayloadLengthOffset + 1) * kIntSize;
+};
+
+
+// Wrapper around ScriptData to provide code-serializer-specific functionality.
+class SerializedCodeData : public SerializedData {
+ public:
+  // Used when consuming.
+  static SerializedCodeData* FromCachedData(ScriptData* cached_data,
+                                            String* source) {
+    DisallowHeapAllocation no_gc;
+    SerializedCodeData* scd = new SerializedCodeData(cached_data);
+    if (scd->IsSane(source)) return scd;
+    cached_data->Reject();
+    delete scd;
+    return NULL;
   }
 
-  int GetHeaderValue(int offset) const {
-    return reinterpret_cast<const int*>(script_data_->data())[offset];
-  }
+  // Used when producing.
+  SerializedCodeData(const List<byte>& payload, const CodeSerializer& cs);
 
-  bool IsSane(String* source);
+  // Return ScriptData object and relinquish ownership over it to the caller.
+  ScriptData* GetScriptData();
 
-  int CheckSum(String* source);
+  Vector<const Reservation> Reservations() const;
+  Vector<const byte> Payload() const;
+
+  int NumInternalizedStrings() const;
+  Vector<const uint32_t> CodeStubKeys() const;
+
+ private:
+  explicit SerializedCodeData(ScriptData* data)
+      : SerializedData(const_cast<byte*>(data->data()), data->length()) {}
+
+  bool IsSane(String* source) const;
+
+  static uint32_t SourceHash(String* source) { return source->length(); }
 
   // The data header consists of int-sized entries:
   // [0] version hash
-  // [1] number of code stub keys
-  // [2] payload length
-  // [3..9] reservation sizes for spaces from NEW_SPACE to PROPERTY_CELL_SPACE.
-  static const int kCheckSumOffset = 0;
-  static const int kNumCodeStubKeysOffset = 1;
-  static const int kPayloadLengthOffset = 2;
-  static const int kReservationsOffset = 3;
-
-  static const int kNumSpaces = PROPERTY_CELL_SPACE - NEW_SPACE + 1;
-  static const int kHeaderEntries = kReservationsOffset + kNumSpaces;
-  static const int kHeaderSize = kHeaderEntries * kIntSize;
-
-  // Following the header, we store, in sequential order
-  // - code stub keys
-  // - serialization payload
-
-  ScriptData* script_data_;
-  bool owns_script_data_;
+  // [1] source hash
+  // [2] cpu features
+  // [3] flag hash
+  // [4] number of internalized strings
+  // [5] number of code stub keys
+  // [6] number of reservation size entries
+  // [7] payload length
+  // [8] checksum 1
+  // [9] checksum 2
+  static const int kVersionHashOffset = 0;
+  static const int kSourceHashOffset = 1;
+  static const int kCpuFeaturesOffset = 2;
+  static const int kFlagHashOffset = 3;
+  static const int kNumInternalizedStringsOffset = 4;
+  static const int kReservationsOffset = 5;
+  static const int kNumCodeStubKeysOffset = 6;
+  static const int kPayloadLengthOffset = 7;
+  static const int kChecksum1Offset = 8;
+  static const int kChecksum2Offset = 9;
+  static const int kHeaderSize = (kChecksum2Offset + 1) * kIntSize;
 };
 } }  // namespace v8::internal
 
diff --git a/src/snapshot-common.cc b/src/snapshot-common.cc
index a2d5213..dc7f655 100644
--- a/src/snapshot-common.cc
+++ b/src/snapshot-common.cc
@@ -14,73 +14,78 @@
 namespace v8 {
 namespace internal {
 
-void Snapshot::ReserveSpaceForLinkedInSnapshot(Deserializer* deserializer) {
-  deserializer->set_reservation(NEW_SPACE, new_space_used_);
-  deserializer->set_reservation(OLD_POINTER_SPACE, pointer_space_used_);
-  deserializer->set_reservation(OLD_DATA_SPACE, data_space_used_);
-  deserializer->set_reservation(CODE_SPACE, code_space_used_);
-  deserializer->set_reservation(MAP_SPACE, map_space_used_);
-  deserializer->set_reservation(CELL_SPACE, cell_space_used_);
-  deserializer->set_reservation(PROPERTY_CELL_SPACE,
-                                property_cell_space_used_);
+bool Snapshot::HaveASnapshotToStartFrom() {
+  return SnapshotBlob().data != NULL;
 }
 
 
 bool Snapshot::Initialize(Isolate* isolate) {
-  if (size_ > 0) {
-    base::ElapsedTimer timer;
-    if (FLAG_profile_deserialization) {
-      timer.Start();
-    }
-    SnapshotByteSource source(raw_data_, raw_size_);
-    Deserializer deserializer(&source);
-    ReserveSpaceForLinkedInSnapshot(&deserializer);
-    bool success = isolate->Init(&deserializer);
-    if (FLAG_profile_deserialization) {
-      double ms = timer.Elapsed().InMillisecondsF();
-      PrintF("[Snapshot loading and deserialization took %0.3f ms]\n", ms);
-    }
-    return success;
+  if (!HaveASnapshotToStartFrom()) return false;
+  base::ElapsedTimer timer;
+  if (FLAG_profile_deserialization) timer.Start();
+
+  const v8::StartupData blob = SnapshotBlob();
+  SnapshotData snapshot_data(ExtractStartupData(&blob));
+  Deserializer deserializer(&snapshot_data);
+  bool success = isolate->Init(&deserializer);
+  if (FLAG_profile_deserialization) {
+    double ms = timer.Elapsed().InMillisecondsF();
+    PrintF("[Snapshot loading and deserialization took %0.3f ms]\n", ms);
   }
-  return false;
-}
-
-
-bool Snapshot::HaveASnapshotToStartFrom() {
-  return size_ != 0;
+  return success;
 }
 
 
 Handle<Context> Snapshot::NewContextFromSnapshot(Isolate* isolate) {
-  if (context_size_ == 0) {
-    return Handle<Context>();
-  }
-  SnapshotByteSource source(context_raw_data_,
-                            context_raw_size_);
-  Deserializer deserializer(&source);
+  if (!HaveASnapshotToStartFrom()) return Handle<Context>();
+
+  const v8::StartupData blob = SnapshotBlob();
+  SnapshotData snapshot_data(ExtractContextData(&blob));
+  Deserializer deserializer(&snapshot_data);
   Object* root;
-  deserializer.set_reservation(NEW_SPACE, context_new_space_used_);
-  deserializer.set_reservation(OLD_POINTER_SPACE, context_pointer_space_used_);
-  deserializer.set_reservation(OLD_DATA_SPACE, context_data_space_used_);
-  deserializer.set_reservation(CODE_SPACE, context_code_space_used_);
-  deserializer.set_reservation(MAP_SPACE, context_map_space_used_);
-  deserializer.set_reservation(CELL_SPACE, context_cell_space_used_);
-  deserializer.set_reservation(PROPERTY_CELL_SPACE,
-                               context_property_cell_space_used_);
   deserializer.DeserializePartial(isolate, &root);
   CHECK(root->IsContext());
   return Handle<Context>(Context::cast(root));
 }
 
 
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
-// Dummy implementations of Set*FromFile(..) APIs.
-//
-// These are meant for use with snapshot-external.cc. Should this file
-// be compiled with those options we just supply these dummy implementations
-// below. This happens when compiling the mksnapshot utility.
-void SetNativesFromFile(StartupData* data) { CHECK(false); }
-void SetSnapshotFromFile(StartupData* data) { CHECK(false); }
-#endif  // V8_USE_EXTERNAL_STARTUP_DATA
+v8::StartupData Snapshot::CreateSnapshotBlob(
+    const Vector<const byte> startup_data,
+    const Vector<const byte> context_data) {
+  int startup_length = startup_data.length();
+  int context_length = context_data.length();
+  int context_offset = kIntSize + startup_length;
+  int length = context_offset + context_length;
+  char* data = new char[length];
 
+  memcpy(data, &startup_length, kIntSize);
+  memcpy(data + kIntSize, startup_data.begin(), startup_length);
+  memcpy(data + context_offset, context_data.begin(), context_length);
+  v8::StartupData result = {data, length};
+  return result;
+}
+
+
+Vector<const byte> Snapshot::ExtractStartupData(const v8::StartupData* data) {
+  DCHECK_LT(kIntSize, data->raw_size);
+  int startup_length;
+  memcpy(&startup_length, data->data, kIntSize);
+  DCHECK_LT(startup_length, data->raw_size);
+  const byte* startup_data =
+      reinterpret_cast<const byte*>(data->data + kIntSize);
+  return Vector<const byte>(startup_data, startup_length);
+}
+
+
+Vector<const byte> Snapshot::ExtractContextData(const v8::StartupData* data) {
+  DCHECK_LT(kIntSize, data->raw_size);
+  int startup_length;
+  memcpy(&startup_length, data->data, kIntSize);
+  int context_offset = kIntSize + startup_length;
+  const byte* context_data =
+      reinterpret_cast<const byte*>(data->data + context_offset);
+  DCHECK_LT(context_offset, data->raw_size);
+  int context_length = data->raw_size - context_offset;
+  return Vector<const byte>(context_data, context_length);
+}
 } }  // namespace v8::internal
diff --git a/src/snapshot-empty.cc b/src/snapshot-empty.cc
index 65207bf..020d1cb 100644
--- a/src/snapshot-empty.cc
+++ b/src/snapshot-empty.cc
@@ -11,29 +11,18 @@
 namespace v8 {
 namespace internal {
 
-const byte Snapshot::data_[] = { 0 };
-const byte* Snapshot::raw_data_ = NULL;
-const int Snapshot::size_ = 0;
-const int Snapshot::raw_size_ = 0;
-const byte Snapshot::context_data_[] = { 0 };
-const byte* Snapshot::context_raw_data_ = NULL;
-const int Snapshot::context_size_ = 0;
-const int Snapshot::context_raw_size_ = 0;
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+// Dummy implementations of Set*FromFile(..) APIs.
+//
+// These are meant for use with snapshot-external.cc. Should this file
+// be compiled with those options we just supply these dummy implementations
+// below. This happens when compiling the mksnapshot utility.
+void SetNativesFromFile(StartupData* data) { CHECK(false); }
+void SetSnapshotFromFile(StartupData* data) { CHECK(false); }
+#endif  // V8_USE_EXTERNAL_STARTUP_DATA
 
-const int Snapshot::new_space_used_ = 0;
-const int Snapshot::pointer_space_used_ = 0;
-const int Snapshot::data_space_used_ = 0;
-const int Snapshot::code_space_used_ = 0;
-const int Snapshot::map_space_used_ = 0;
-const int Snapshot::cell_space_used_ = 0;
-const int Snapshot::property_cell_space_used_ = 0;
 
-const int Snapshot::context_new_space_used_ = 0;
-const int Snapshot::context_pointer_space_used_ = 0;
-const int Snapshot::context_data_space_used_ = 0;
-const int Snapshot::context_code_space_used_ = 0;
-const int Snapshot::context_map_space_used_ = 0;
-const int Snapshot::context_cell_space_used_ = 0;
-const int Snapshot::context_property_cell_space_used_ = 0;
-
+const v8::StartupData Snapshot::SnapshotBlob() {
+  return {NULL, 0};
+}
 } }  // namespace v8::internal
diff --git a/src/snapshot-external.cc b/src/snapshot-external.cc
index ee1a8f4..2fda571 100644
--- a/src/snapshot-external.cc
+++ b/src/snapshot-external.cc
@@ -10,131 +10,28 @@
 #include "src/snapshot-source-sink.h"
 #include "src/v8.h"  // for V8::Initialize
 
+
+#ifndef V8_USE_EXTERNAL_STARTUP_DATA
+#error snapshot-external.cc is used only for the external snapshot build.
+#endif  // V8_USE_EXTERNAL_STARTUP_DATA
+
+
 namespace v8 {
 namespace internal {
 
-
-struct SnapshotImpl {
- public:
-  const byte* data;
-  int size;
-  int new_space_used;
-  int pointer_space_used;
-  int data_space_used;
-  int code_space_used;
-  int map_space_used;
-  int cell_space_used;
-  int property_cell_space_used;
-
-  const byte* context_data;
-  int context_size;
-  int context_new_space_used;
-  int context_pointer_space_used;
-  int context_data_space_used;
-  int context_code_space_used;
-  int context_map_space_used;
-  int context_cell_space_used;
-  int context_property_cell_space_used;
-};
-
-
-static SnapshotImpl* snapshot_impl_ = NULL;
-
-
-bool Snapshot::HaveASnapshotToStartFrom() {
-  return snapshot_impl_ != NULL;
-}
-
-
-bool Snapshot::Initialize(Isolate* isolate) {
-  if (!HaveASnapshotToStartFrom())
-    return false;
-
-  base::ElapsedTimer timer;
-  if (FLAG_profile_deserialization) {
-    timer.Start();
-  }
-  SnapshotByteSource source(snapshot_impl_->data, snapshot_impl_->size);
-  Deserializer deserializer(&source);
-  deserializer.set_reservation(NEW_SPACE, snapshot_impl_->new_space_used);
-  deserializer.set_reservation(OLD_POINTER_SPACE,
-                               snapshot_impl_->pointer_space_used);
-  deserializer.set_reservation(OLD_DATA_SPACE,
-                               snapshot_impl_->data_space_used);
-  deserializer.set_reservation(CODE_SPACE, snapshot_impl_->code_space_used);
-  deserializer.set_reservation(MAP_SPACE, snapshot_impl_->map_space_used);
-  deserializer.set_reservation(CELL_SPACE, snapshot_impl_->cell_space_used);
-  deserializer.set_reservation(PROPERTY_CELL_SPACE,
-                               snapshot_impl_->property_cell_space_used);
-  bool success = isolate->Init(&deserializer);
-  if (FLAG_profile_deserialization) {
-    double ms = timer.Elapsed().InMillisecondsF();
-    PrintF("[Snapshot loading and deserialization took %0.3f ms]\n", ms);
-  }
-  return success;
-}
-
-
-Handle<Context> Snapshot::NewContextFromSnapshot(Isolate* isolate) {
-  if (!HaveASnapshotToStartFrom())
-    return Handle<Context>();
-
-  SnapshotByteSource source(snapshot_impl_->context_data,
-                            snapshot_impl_->context_size);
-  Deserializer deserializer(&source);
-  deserializer.set_reservation(NEW_SPACE,
-                               snapshot_impl_->context_new_space_used);
-  deserializer.set_reservation(OLD_POINTER_SPACE,
-                               snapshot_impl_->context_pointer_space_used);
-  deserializer.set_reservation(OLD_DATA_SPACE,
-                               snapshot_impl_->context_data_space_used);
-  deserializer.set_reservation(CODE_SPACE,
-                               snapshot_impl_->context_code_space_used);
-  deserializer.set_reservation(MAP_SPACE,
-                               snapshot_impl_->context_map_space_used);
-  deserializer.set_reservation(CELL_SPACE,
-                               snapshot_impl_->context_cell_space_used);
-  deserializer.set_reservation(PROPERTY_CELL_SPACE,
-                               snapshot_impl_->
-                                   context_property_cell_space_used);
-  Object* root;
-  deserializer.DeserializePartial(isolate, &root);
-  CHECK(root->IsContext());
-  return Handle<Context>(Context::cast(root));
-}
-
+static v8::StartupData external_startup_blob = {NULL, 0};
 
 void SetSnapshotFromFile(StartupData* snapshot_blob) {
   DCHECK(snapshot_blob);
   DCHECK(snapshot_blob->data);
   DCHECK(snapshot_blob->raw_size > 0);
-  DCHECK(!snapshot_impl_);
-
-  snapshot_impl_ = new SnapshotImpl;
-  SnapshotByteSource source(reinterpret_cast<const byte*>(snapshot_blob->data),
-                            snapshot_blob->raw_size);
-
-  bool success = source.GetBlob(&snapshot_impl_->data,
-                                &snapshot_impl_->size);
-  snapshot_impl_->new_space_used = source.GetInt();
-  snapshot_impl_->pointer_space_used = source.GetInt();
-  snapshot_impl_->data_space_used = source.GetInt();
-  snapshot_impl_->code_space_used = source.GetInt();
-  snapshot_impl_->map_space_used = source.GetInt();
-  snapshot_impl_->cell_space_used = source.GetInt();
-  snapshot_impl_->property_cell_space_used = source.GetInt();
-
-  success &= source.GetBlob(&snapshot_impl_->context_data,
-                            &snapshot_impl_->context_size);
-  snapshot_impl_->context_new_space_used = source.GetInt();
-  snapshot_impl_->context_pointer_space_used = source.GetInt();
-  snapshot_impl_->context_data_space_used = source.GetInt();
-  snapshot_impl_->context_code_space_used = source.GetInt();
-  snapshot_impl_->context_map_space_used = source.GetInt();
-  snapshot_impl_->context_cell_space_used = source.GetInt();
-  snapshot_impl_->context_property_cell_space_used = source.GetInt();
-
-  DCHECK(success);
+  DCHECK(!external_startup_blob.data);
+  // Validate snapshot blob.
+  DCHECK(!Snapshot::ExtractStartupData(snapshot_blob).is_empty());
+  DCHECK(!Snapshot::ExtractContextData(snapshot_blob).is_empty());
+  external_startup_blob = *snapshot_blob;
 }
 
+
+const v8::StartupData Snapshot::SnapshotBlob() { return external_startup_blob; }
 } }  // namespace v8::internal
diff --git a/src/snapshot-source-sink.cc b/src/snapshot-source-sink.cc
index 44f8706..fd94724 100644
--- a/src/snapshot-source-sink.cc
+++ b/src/snapshot-source-sink.cc
@@ -13,15 +13,6 @@
 namespace v8 {
 namespace internal {
 
-
-SnapshotByteSource::SnapshotByteSource(const byte* array, int length)
-    : data_(array), length_(length), position_(0) {
-}
-
-
-SnapshotByteSource::~SnapshotByteSource() { }
-
-
 int32_t SnapshotByteSource::GetUnalignedInt() {
   DCHECK(position_ < length_);  // Require at least one byte left.
   int32_t answer = data_[position_];
@@ -39,28 +30,23 @@
 
 
 void SnapshotByteSink::PutInt(uintptr_t integer, const char* description) {
-  DCHECK(integer < 1 << 22);
+  DCHECK(integer < 1 << 30);
   integer <<= 2;
   int bytes = 1;
   if (integer > 0xff) bytes = 2;
   if (integer > 0xffff) bytes = 3;
-  integer |= bytes;
+  if (integer > 0xffffff) bytes = 4;
+  integer |= (bytes - 1);
   Put(static_cast<int>(integer & 0xff), "IntPart1");
   if (bytes > 1) Put(static_cast<int>((integer >> 8) & 0xff), "IntPart2");
   if (bytes > 2) Put(static_cast<int>((integer >> 16) & 0xff), "IntPart3");
+  if (bytes > 3) Put(static_cast<int>((integer >> 24) & 0xff), "IntPart4");
 }
 
-void SnapshotByteSink::PutRaw(byte* data, int number_of_bytes,
+
+void SnapshotByteSink::PutRaw(const byte* data, int number_of_bytes,
                               const char* description) {
-  for (int i = 0; i < number_of_bytes; ++i) {
-    Put(data[i], description);
-  }
-}
-
-void SnapshotByteSink::PutBlob(byte* data, int number_of_bytes,
-                               const char* description) {
-  PutInt(number_of_bytes, description);
-  PutRaw(data, number_of_bytes, description);
+  data_.AddAll(Vector<byte>(const_cast<byte*>(data), number_of_bytes));
 }
 
 
@@ -77,7 +63,7 @@
   int size = GetInt();
   *number_of_bytes = size;
 
-  if (position_ + size < length_) {
+  if (position_ + size <= length_) {
     *data = &data_[position_];
     Advance(size);
     return true;
@@ -87,11 +73,5 @@
   }
 }
 
-
-void DebugSnapshotSink::Put(byte b, const char* description) {
-  PrintF("%24s: %x\n", description, b);
-  sink_->Put(b, description);
-}
-
 }  // namespace v8::internal
 }  // namespace v8
diff --git a/src/snapshot-source-sink.h b/src/snapshot-source-sink.h
index 3c64bca..66feaec 100644
--- a/src/snapshot-source-sink.h
+++ b/src/snapshot-source-sink.h
@@ -19,12 +19,19 @@
  */
 class SnapshotByteSource FINAL {
  public:
-  SnapshotByteSource(const byte* array, int length);
-  ~SnapshotByteSource();
+  SnapshotByteSource(const char* data, int length)
+      : data_(reinterpret_cast<const byte*>(data)),
+        length_(length),
+        position_(0) {}
+
+  explicit SnapshotByteSource(Vector<const byte> payload)
+      : data_(payload.start()), length_(payload.length()), position_(0) {}
+
+  ~SnapshotByteSource() {}
 
   bool HasMore() { return position_ < length_; }
 
-  int Get() {
+  byte Get() {
     DCHECK(position_ < length_);
     return data_[position_++];
   }
@@ -39,7 +46,7 @@
     // This way of variable-length encoding integers does not suffer from branch
     // mispredictions.
     uint32_t answer = GetUnalignedInt();
-    int bytes = answer & 3;
+    int bytes = (answer & 3) + 1;
     Advance(bytes);
     uint32_t mask = 0xffffffffu;
     mask >>= 32 - (bytes << 3);
@@ -70,53 +77,26 @@
  */
 class SnapshotByteSink {
  public:
-  virtual ~SnapshotByteSink() { }
-  virtual void Put(byte b, const char* description) = 0;
-  virtual void PutSection(int b, const char* description) {
+  SnapshotByteSink() {}
+  explicit SnapshotByteSink(int initial_size) : data_(initial_size) {}
+
+  ~SnapshotByteSink() {}
+
+  void Put(byte b, const char* description) { data_.Add(b); }
+
+  void PutSection(int b, const char* description) {
     DCHECK_LE(b, kMaxUInt8);
     Put(static_cast<byte>(b), description);
   }
+
   void PutInt(uintptr_t integer, const char* description);
-  void PutRaw(byte* data, int number_of_bytes, const char* description);
-  void PutBlob(byte* data, int number_of_bytes, const char* description);
-  virtual int Position() = 0;
-};
+  void PutRaw(const byte* data, int number_of_bytes, const char* description);
+  int Position() { return data_.length(); }
 
-
-class DummySnapshotSink : public SnapshotByteSink {
- public:
-  DummySnapshotSink() : length_(0) {}
-  virtual ~DummySnapshotSink() {}
-  virtual void Put(byte b, const char* description) { length_++; }
-  virtual int Position() { return length_; }
+  const List<byte>& data() const { return data_; }
 
  private:
-  int length_;
-};
-
-
-// Wrap a SnapshotByteSink into a DebugSnapshotSink to get debugging output.
-class DebugSnapshotSink : public SnapshotByteSink {
- public:
-  explicit DebugSnapshotSink(SnapshotByteSink* chained) : sink_(chained) {}
-  virtual void Put(byte b, const char* description) OVERRIDE;
-  virtual int Position() OVERRIDE { return sink_->Position(); }
-
- private:
-  SnapshotByteSink* sink_;
-};
-
-
-class ListSnapshotSink : public i::SnapshotByteSink {
- public:
-  explicit ListSnapshotSink(i::List<byte>* data) : data_(data) {}
-  virtual void Put(byte b, const char* description) OVERRIDE {
-    data_->Add(b);
-  }
-  virtual int Position() OVERRIDE { return data_->length(); }
-
- private:
-  i::List<byte>* data_;
+  List<byte> data_;
 };
 
 }  // namespace v8::internal
diff --git a/src/snapshot.h b/src/snapshot.h
index 3d752a7..25a07cd 100644
--- a/src/snapshot.h
+++ b/src/snapshot.h
@@ -10,58 +10,27 @@
 namespace v8 {
 namespace internal {
 
-class Snapshot {
+class Snapshot : public AllStatic {
  public:
   // Initialize the Isolate from the internal snapshot. Returns false if no
   // snapshot could be found.
   static bool Initialize(Isolate* isolate);
-
-  static bool HaveASnapshotToStartFrom();
-
   // Create a new context using the internal partial snapshot.
   static Handle<Context> NewContextFromSnapshot(Isolate* isolate);
 
-  // These methods support COMPRESS_STARTUP_DATA_BZ2.
-  static const byte* data() { return data_; }
-  static int size() { return size_; }
-  static int raw_size() { return raw_size_; }
-  static void set_raw_data(const byte* raw_data) {
-    raw_data_ = raw_data;
-  }
-  static const byte* context_data() { return context_data_; }
-  static int context_size() { return context_size_; }
-  static int context_raw_size() { return context_raw_size_; }
-  static void set_context_raw_data(
-      const byte* context_raw_data) {
-    context_raw_data_ = context_raw_data;
-  }
+  static bool HaveASnapshotToStartFrom();
+
+  // To be implemented by the snapshot source.
+  static const v8::StartupData SnapshotBlob();
+
+  static v8::StartupData CreateSnapshotBlob(
+      const Vector<const byte> startup_data,
+      const Vector<const byte> context_data);
+
+  static Vector<const byte> ExtractStartupData(const v8::StartupData* data);
+  static Vector<const byte> ExtractContextData(const v8::StartupData* data);
 
  private:
-  static const byte data_[];
-  static const byte* raw_data_;
-  static const byte context_data_[];
-  static const byte* context_raw_data_;
-  static const int new_space_used_;
-  static const int pointer_space_used_;
-  static const int data_space_used_;
-  static const int code_space_used_;
-  static const int map_space_used_;
-  static const int cell_space_used_;
-  static const int property_cell_space_used_;
-  static const int context_new_space_used_;
-  static const int context_pointer_space_used_;
-  static const int context_data_space_used_;
-  static const int context_code_space_used_;
-  static const int context_map_space_used_;
-  static const int context_cell_space_used_;
-  static const int context_property_cell_space_used_;
-  static const int size_;
-  static const int raw_size_;
-  static const int context_size_;
-  static const int context_raw_size_;
-
-  static void ReserveSpaceForLinkedInSnapshot(Deserializer* deserializer);
-
   DISALLOW_IMPLICIT_CONSTRUCTORS(Snapshot);
 };
 
diff --git a/src/string-builder.cc b/src/string-builder.cc
new file mode 100644
index 0000000..38c3188
--- /dev/null
+++ b/src/string-builder.cc
@@ -0,0 +1,111 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/string-builder.h"
+
+namespace v8 {
+namespace internal {
+
+MaybeHandle<String> ReplacementStringBuilder::ToString() {
+  Isolate* isolate = heap_->isolate();
+  if (array_builder_.length() == 0) {
+    return isolate->factory()->empty_string();
+  }
+
+  Handle<String> joined_string;
+  if (is_one_byte_) {
+    Handle<SeqOneByteString> seq;
+    ASSIGN_RETURN_ON_EXCEPTION(
+        isolate, seq, isolate->factory()->NewRawOneByteString(character_count_),
+        String);
+
+    DisallowHeapAllocation no_gc;
+    uint8_t* char_buffer = seq->GetChars();
+    StringBuilderConcatHelper(*subject_, char_buffer, *array_builder_.array(),
+                              array_builder_.length());
+    joined_string = Handle<String>::cast(seq);
+  } else {
+    // Two-byte.
+    Handle<SeqTwoByteString> seq;
+    ASSIGN_RETURN_ON_EXCEPTION(
+        isolate, seq, isolate->factory()->NewRawTwoByteString(character_count_),
+        String);
+
+    DisallowHeapAllocation no_gc;
+    uc16* char_buffer = seq->GetChars();
+    StringBuilderConcatHelper(*subject_, char_buffer, *array_builder_.array(),
+                              array_builder_.length());
+    joined_string = Handle<String>::cast(seq);
+  }
+  return joined_string;
+}
+
+
+IncrementalStringBuilder::IncrementalStringBuilder(Isolate* isolate)
+    : isolate_(isolate),
+      encoding_(String::ONE_BYTE_ENCODING),
+      overflowed_(false),
+      part_length_(kInitialPartLength),
+      current_index_(0) {
+  // Create an accumulator handle starting with the empty string.
+  accumulator_ = Handle<String>(isolate->heap()->empty_string(), isolate);
+  current_part_ =
+      factory()->NewRawOneByteString(part_length_).ToHandleChecked();
+}
+
+
+void IncrementalStringBuilder::Accumulate() {
+  // Only accumulate fully written strings. Shrink first if necessary.
+  DCHECK_EQ(current_index_, current_part()->length());
+  Handle<String> new_accumulator;
+  if (accumulator()->length() + current_part()->length() > String::kMaxLength) {
+    // Set the flag and carry on. Delay throwing the exception till the end.
+    new_accumulator = factory()->empty_string();
+    overflowed_ = true;
+  } else {
+    new_accumulator = factory()
+                          ->NewConsString(accumulator(), current_part())
+                          .ToHandleChecked();
+  }
+  set_accumulator(new_accumulator);
+}
+
+
+void IncrementalStringBuilder::Extend() {
+  Accumulate();
+  if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) {
+    part_length_ *= kPartLengthGrowthFactor;
+  }
+  Handle<String> new_part;
+  if (encoding_ == String::ONE_BYTE_ENCODING) {
+    new_part = factory()->NewRawOneByteString(part_length_).ToHandleChecked();
+  } else {
+    new_part = factory()->NewRawTwoByteString(part_length_).ToHandleChecked();
+  }
+  // Reuse the same handle to avoid being invalidated when exiting handle scope.
+  set_current_part(new_part);
+  current_index_ = 0;
+}
+
+
+MaybeHandle<String> IncrementalStringBuilder::Finish() {
+  ShrinkCurrentPart();
+  Accumulate();
+  if (overflowed_) {
+    THROW_NEW_ERROR(isolate_, NewInvalidStringLengthError(), String);
+  }
+  return accumulator();
+}
+
+
+void IncrementalStringBuilder::AppendString(Handle<String> string) {
+  ShrinkCurrentPart();
+  part_length_ = kInitialPartLength;  // Allocate conservatively.
+  Extend();  // Attach current part and allocate new part.
+  Handle<String> concat =
+      factory()->NewConsString(accumulator(), string).ToHandleChecked();
+  set_accumulator(concat);
+}
+}
+}  // namespace v8::internal
diff --git a/src/string-builder.h b/src/string-builder.h
new file mode 100644
index 0000000..43b690d
--- /dev/null
+++ b/src/string-builder.h
@@ -0,0 +1,430 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_STRING_BUILDER_H_
+#define V8_STRING_BUILDER_H_
+
+#include "src/v8.h"
+
+namespace v8 {
+namespace internal {
+
+const int kStringBuilderConcatHelperLengthBits = 11;
+const int kStringBuilderConcatHelperPositionBits = 19;
+
+typedef BitField<int, 0, kStringBuilderConcatHelperLengthBits>
+    StringBuilderSubstringLength;
+typedef BitField<int, kStringBuilderConcatHelperLengthBits,
+                 kStringBuilderConcatHelperPositionBits>
+    StringBuilderSubstringPosition;
+
+
+template <typename sinkchar>
+static inline void StringBuilderConcatHelper(String* special, sinkchar* sink,
+                                             FixedArray* fixed_array,
+                                             int array_length) {
+  DisallowHeapAllocation no_gc;
+  int position = 0;
+  for (int i = 0; i < array_length; i++) {
+    Object* element = fixed_array->get(i);
+    if (element->IsSmi()) {
+      // Smi encoding of position and length.
+      int encoded_slice = Smi::cast(element)->value();
+      int pos;
+      int len;
+      if (encoded_slice > 0) {
+        // Position and length encoded in one smi.
+        pos = StringBuilderSubstringPosition::decode(encoded_slice);
+        len = StringBuilderSubstringLength::decode(encoded_slice);
+      } else {
+        // Position and length encoded in two smis.
+        Object* obj = fixed_array->get(++i);
+        DCHECK(obj->IsSmi());
+        pos = Smi::cast(obj)->value();
+        len = -encoded_slice;
+      }
+      String::WriteToFlat(special, sink + position, pos, pos + len);
+      position += len;
+    } else {
+      String* string = String::cast(element);
+      int element_length = string->length();
+      String::WriteToFlat(string, sink + position, 0, element_length);
+      position += element_length;
+    }
+  }
+}
+
+
+// Returns the result length of the concatenation.
+// On illegal argument, -1 is returned.
+static inline int StringBuilderConcatLength(int special_length,
+                                            FixedArray* fixed_array,
+                                            int array_length, bool* one_byte) {
+  DisallowHeapAllocation no_gc;
+  int position = 0;
+  for (int i = 0; i < array_length; i++) {
+    int increment = 0;
+    Object* elt = fixed_array->get(i);
+    if (elt->IsSmi()) {
+      // Smi encoding of position and length.
+      int smi_value = Smi::cast(elt)->value();
+      int pos;
+      int len;
+      if (smi_value > 0) {
+        // Position and length encoded in one smi.
+        pos = StringBuilderSubstringPosition::decode(smi_value);
+        len = StringBuilderSubstringLength::decode(smi_value);
+      } else {
+        // Position and length encoded in two smis.
+        len = -smi_value;
+        // Get the position and check that it is a positive smi.
+        i++;
+        if (i >= array_length) return -1;
+        Object* next_smi = fixed_array->get(i);
+        if (!next_smi->IsSmi()) return -1;
+        pos = Smi::cast(next_smi)->value();
+        if (pos < 0) return -1;
+      }
+      DCHECK(pos >= 0);
+      DCHECK(len >= 0);
+      if (pos > special_length || len > special_length - pos) return -1;
+      increment = len;
+    } else if (elt->IsString()) {
+      String* element = String::cast(elt);
+      int element_length = element->length();
+      increment = element_length;
+      if (*one_byte && !element->HasOnlyOneByteChars()) {
+        *one_byte = false;
+      }
+    } else {
+      return -1;
+    }
+    if (increment > String::kMaxLength - position) {
+      return kMaxInt;  // Provoke throw on allocation.
+    }
+    position += increment;
+  }
+  return position;
+}
+
+
+class FixedArrayBuilder {
+ public:
+  explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity)
+      : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)),
+        length_(0),
+        has_non_smi_elements_(false) {
+    // Require a non-zero initial size. Ensures that doubling the size to
+    // extend the array will work.
+    DCHECK(initial_capacity > 0);
+  }
+
+  explicit FixedArrayBuilder(Handle<FixedArray> backing_store)
+      : array_(backing_store), length_(0), has_non_smi_elements_(false) {
+    // Require a non-zero initial size. Ensures that doubling the size to
+    // extend the array will work.
+    DCHECK(backing_store->length() > 0);
+  }
+
+  bool HasCapacity(int elements) {
+    int length = array_->length();
+    int required_length = length_ + elements;
+    return (length >= required_length);
+  }
+
+  void EnsureCapacity(int elements) {
+    int length = array_->length();
+    int required_length = length_ + elements;
+    if (length < required_length) {
+      int new_length = length;
+      do {
+        new_length *= 2;
+      } while (new_length < required_length);
+      Handle<FixedArray> extended_array =
+          array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length);
+      array_->CopyTo(0, *extended_array, 0, length_);
+      array_ = extended_array;
+    }
+  }
+
+  void Add(Object* value) {
+    DCHECK(!value->IsSmi());
+    DCHECK(length_ < capacity());
+    array_->set(length_, value);
+    length_++;
+    has_non_smi_elements_ = true;
+  }
+
+  void Add(Smi* value) {
+    DCHECK(value->IsSmi());
+    DCHECK(length_ < capacity());
+    array_->set(length_, value);
+    length_++;
+  }
+
+  Handle<FixedArray> array() { return array_; }
+
+  int length() { return length_; }
+
+  int capacity() { return array_->length(); }
+
+  Handle<JSArray> ToJSArray(Handle<JSArray> target_array) {
+    JSArray::SetContent(target_array, array_);
+    target_array->set_length(Smi::FromInt(length_));
+    return target_array;
+  }
+
+
+ private:
+  Handle<FixedArray> array_;
+  int length_;
+  bool has_non_smi_elements_;
+};
+
+
+class ReplacementStringBuilder {
+ public:
+  ReplacementStringBuilder(Heap* heap, Handle<String> subject,
+                           int estimated_part_count)
+      : heap_(heap),
+        array_builder_(heap->isolate(), estimated_part_count),
+        subject_(subject),
+        character_count_(0),
+        is_one_byte_(subject->IsOneByteRepresentation()) {
+    // Require a non-zero initial size. Ensures that doubling the size to
+    // extend the array will work.
+    DCHECK(estimated_part_count > 0);
+  }
+
+  static inline void AddSubjectSlice(FixedArrayBuilder* builder, int from,
+                                     int to) {
+    DCHECK(from >= 0);
+    int length = to - from;
+    DCHECK(length > 0);
+    if (StringBuilderSubstringLength::is_valid(length) &&
+        StringBuilderSubstringPosition::is_valid(from)) {
+      int encoded_slice = StringBuilderSubstringLength::encode(length) |
+                          StringBuilderSubstringPosition::encode(from);
+      builder->Add(Smi::FromInt(encoded_slice));
+    } else {
+      // Otherwise encode as two smis.
+      builder->Add(Smi::FromInt(-length));
+      builder->Add(Smi::FromInt(from));
+    }
+  }
+
+
+  void EnsureCapacity(int elements) { array_builder_.EnsureCapacity(elements); }
+
+
+  void AddSubjectSlice(int from, int to) {
+    AddSubjectSlice(&array_builder_, from, to);
+    IncrementCharacterCount(to - from);
+  }
+
+
+  void AddString(Handle<String> string) {
+    int length = string->length();
+    DCHECK(length > 0);
+    AddElement(*string);
+    if (!string->IsOneByteRepresentation()) {
+      is_one_byte_ = false;
+    }
+    IncrementCharacterCount(length);
+  }
+
+
+  MaybeHandle<String> ToString();
+
+
+  void IncrementCharacterCount(int by) {
+    if (character_count_ > String::kMaxLength - by) {
+      STATIC_ASSERT(String::kMaxLength < kMaxInt);
+      character_count_ = kMaxInt;
+    } else {
+      character_count_ += by;
+    }
+  }
+
+ private:
+  void AddElement(Object* element) {
+    DCHECK(element->IsSmi() || element->IsString());
+    DCHECK(array_builder_.capacity() > array_builder_.length());
+    array_builder_.Add(element);
+  }
+
+  Heap* heap_;
+  FixedArrayBuilder array_builder_;
+  Handle<String> subject_;
+  int character_count_;
+  bool is_one_byte_;
+};
+
+
+class IncrementalStringBuilder {
+ public:
+  explicit IncrementalStringBuilder(Isolate* isolate);
+
+  INLINE(String::Encoding CurrentEncoding()) { return encoding_; }
+
+  template <typename SrcChar, typename DestChar>
+  INLINE(void Append(SrcChar c));
+
+  INLINE(void AppendCharacter(uint8_t c)) {
+    if (encoding_ == String::ONE_BYTE_ENCODING) {
+      Append<uint8_t, uint8_t>(c);
+    } else {
+      Append<uint8_t, uc16>(c);
+    }
+  }
+
+  INLINE(void AppendCString(const char* s)) {
+    const uint8_t* u = reinterpret_cast<const uint8_t*>(s);
+    if (encoding_ == String::ONE_BYTE_ENCODING) {
+      while (*u != '\0') Append<uint8_t, uint8_t>(*(u++));
+    } else {
+      while (*u != '\0') Append<uint8_t, uc16>(*(u++));
+    }
+  }
+
+  INLINE(bool CurrentPartCanFit(int length)) {
+    return part_length_ - current_index_ > length;
+  }
+
+  void AppendString(Handle<String> string);
+
+  MaybeHandle<String> Finish();
+
+  // Change encoding to two-byte.
+  void ChangeEncoding() {
+    DCHECK_EQ(String::ONE_BYTE_ENCODING, encoding_);
+    ShrinkCurrentPart();
+    encoding_ = String::TWO_BYTE_ENCODING;
+    Extend();
+  }
+
+  template <typename DestChar>
+  class NoExtend {
+   public:
+    explicit NoExtend(Handle<String> string, int offset) {
+      DCHECK(string->IsSeqOneByteString() || string->IsSeqTwoByteString());
+      if (sizeof(DestChar) == 1) {
+        start_ = reinterpret_cast<DestChar*>(
+            Handle<SeqOneByteString>::cast(string)->GetChars() + offset);
+      } else {
+        start_ = reinterpret_cast<DestChar*>(
+            Handle<SeqTwoByteString>::cast(string)->GetChars() + offset);
+      }
+      cursor_ = start_;
+    }
+
+    INLINE(void Append(DestChar c)) { *(cursor_++) = c; }
+    INLINE(void AppendCString(const char* s)) {
+      const uint8_t* u = reinterpret_cast<const uint8_t*>(s);
+      while (*u != '\0') Append(*(u++));
+    }
+
+    int written() { return static_cast<int>(cursor_ - start_); }
+
+   private:
+    DestChar* start_;
+    DestChar* cursor_;
+    DisallowHeapAllocation no_gc_;
+  };
+
+  template <typename DestChar>
+  class NoExtendString : public NoExtend<DestChar> {
+   public:
+    NoExtendString(Handle<String> string, int required_length)
+        : NoExtend<DestChar>(string, 0), string_(string) {
+      DCHECK(string->length() >= required_length);
+    }
+
+    ~NoExtendString() {
+      Handle<SeqString> string = Handle<SeqString>::cast(string_);
+      int length = NoExtend<DestChar>::written();
+      *string_.location() = *SeqString::Truncate(string, length);
+    }
+
+   private:
+    Handle<String> string_;
+  };
+
+  template <typename DestChar>
+  class NoExtendBuilder : public NoExtend<DestChar> {
+   public:
+    NoExtendBuilder(IncrementalStringBuilder* builder, int required_length)
+        : NoExtend<DestChar>(builder->current_part(), builder->current_index_),
+          builder_(builder) {
+      DCHECK(builder->CurrentPartCanFit(required_length));
+    }
+
+    ~NoExtendBuilder() {
+      builder_->current_index_ += NoExtend<DestChar>::written();
+    }
+
+   private:
+    IncrementalStringBuilder* builder_;
+  };
+
+ private:
+  Factory* factory() { return isolate_->factory(); }
+
+  INLINE(Handle<String> accumulator()) { return accumulator_; }
+
+  INLINE(void set_accumulator(Handle<String> string)) {
+    *accumulator_.location() = *string;
+  }
+
+  INLINE(Handle<String> current_part()) { return current_part_; }
+
+  INLINE(void set_current_part(Handle<String> string)) {
+    *current_part_.location() = *string;
+  }
+
+  // Add the current part to the accumulator.
+  void Accumulate();
+
+  // Finish the current part and allocate a new part.
+  void Extend();
+
+  // Shrink current part to the right size.
+  void ShrinkCurrentPart() {
+    DCHECK(current_index_ < part_length_);
+    set_current_part(SeqString::Truncate(
+        Handle<SeqString>::cast(current_part()), current_index_));
+  }
+
+  static const int kInitialPartLength = 32;
+  static const int kMaxPartLength = 16 * 1024;
+  static const int kPartLengthGrowthFactor = 2;
+
+  Isolate* isolate_;
+  String::Encoding encoding_;
+  bool overflowed_;
+  int part_length_;
+  int current_index_;
+  Handle<String> accumulator_;
+  Handle<String> current_part_;
+};
+
+
+template <typename SrcChar, typename DestChar>
+void IncrementalStringBuilder::Append(SrcChar c) {
+  DCHECK_EQ(encoding_ == String::ONE_BYTE_ENCODING, sizeof(DestChar) == 1);
+  if (sizeof(DestChar) == 1) {
+    DCHECK_EQ(String::ONE_BYTE_ENCODING, encoding_);
+    SeqOneByteString::cast(*current_part_)
+        ->SeqOneByteStringSet(current_index_++, c);
+  } else {
+    DCHECK_EQ(String::TWO_BYTE_ENCODING, encoding_);
+    SeqTwoByteString::cast(*current_part_)
+        ->SeqTwoByteStringSet(current_index_++, c);
+  }
+  if (current_index_ == part_length_) Extend();
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_STRING_BUILDER_H_
diff --git a/src/string-iterator.js b/src/string-iterator.js
index cb578e7..f5eef37 100644
--- a/src/string-iterator.js
+++ b/src/string-iterator.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-'use strict';
+"use strict";
 
 
 // This file relies on the fact that the following declaration has been made
@@ -87,6 +87,8 @@
   %FunctionSetName(StringIteratorIterator, '[Symbol.iterator]');
   %AddNamedProperty(StringIterator.prototype, symbolIterator,
                     StringIteratorIterator, DONT_ENUM);
+  %AddNamedProperty(StringIterator.prototype, symbolToStringTag,
+                    "String Iterator", READ_ONLY | DONT_ENUM);
 }
 SetUpStringIterator();
 
diff --git a/src/string-stream.cc b/src/string-stream.cc
index 42c2af7..21f66a6 100644
--- a/src/string-stream.cc
+++ b/src/string-stream.cc
@@ -295,8 +295,7 @@
 
 
 bool StringStream::Put(String* str, int start, int end) {
-  ConsStringIteratorOp op;
-  StringCharacterStream stream(str, &op, start);
+  StringCharacterStream stream(str, start);
   for (int i = start; i < end && stream.HasMore(); i++) {
     uint16_t c = stream.GetNext();
     if (c >= 127 || c < 32) {
@@ -352,8 +351,13 @@
         }
         Add(": ");
         FieldIndex index = FieldIndex::ForDescriptor(map, i);
-        Object* value = js_object->RawFastPropertyAt(index);
-        Add("%o\n", value);
+        if (js_object->IsUnboxedDoubleField(index)) {
+          double value = js_object->RawFastDoublePropertyAt(index);
+          Add("<unboxed double> %.16g\n", FmtElm(value));
+        } else {
+          Object* value = js_object->RawFastPropertyAt(index);
+          Add("%o\n", value);
+        }
       }
     }
   }
diff --git a/src/string-stream.h b/src/string-stream.h
index fca1d4b..3b820cd 100644
--- a/src/string-stream.h
+++ b/src/string-stream.h
@@ -27,8 +27,8 @@
 class HeapStringAllocator FINAL : public StringAllocator {
  public:
   ~HeapStringAllocator() { DeleteArray(space_); }
-  virtual char* allocate(unsigned bytes) OVERRIDE;
-  virtual char* grow(unsigned* bytes) OVERRIDE;
+  char* allocate(unsigned bytes) OVERRIDE;
+  char* grow(unsigned* bytes) OVERRIDE;
 
  private:
   char* space_;
diff --git a/src/symbol.js b/src/symbol.js
index ce3327b..d9cf792 100644
--- a/src/symbol.js
+++ b/src/symbol.js
@@ -8,6 +8,14 @@
 // in runtime.js:
 // var $Array = global.Array;
 
+// And requires following symbols to be set in the bootstrapper during genesis:
+// - symbolHasInstance
+// - symbolIsConcatSpreadable
+// - symbolIsRegExp
+// - symbolIterator
+// - symbolToStringTag
+// - symbolUnscopables
+
 var $Symbol = global.Symbol;
 
 // -------------------------------------------------------------------
@@ -40,15 +48,6 @@
 }
 
 
-function InternalSymbol(key) {
-  var internal_registry = %SymbolRegistry().for_intern;
-  if (IS_UNDEFINED(internal_registry[key])) {
-    internal_registry[key] = %CreateSymbol(key);
-  }
-  return internal_registry[key];
-}
-
-
 function SymbolFor(key) {
   key = TO_STRING_INLINE(key);
   var registry = %SymbolRegistry();
@@ -69,27 +68,13 @@
 
 // ES6 19.1.2.8
 function ObjectGetOwnPropertySymbols(obj) {
-  if (!IS_SPEC_OBJECT(obj)) {
-    throw MakeTypeError("called_on_non_object",
-                        ["Object.getOwnPropertySymbols"]);
-  }
+  obj = ToObject(obj);
 
   // TODO(arv): Proxies use a shared trap for String and Symbol keys.
 
-  return ObjectGetOwnPropertyKeys(obj, true);
+  return ObjectGetOwnPropertyKeys(obj, PROPERTY_ATTRIBUTES_STRING);
 }
 
-
-//-------------------------------------------------------------------
-
-var symbolHasInstance = InternalSymbol("Symbol.hasInstance");
-var symbolIsConcatSpreadable = InternalSymbol("Symbol.isConcatSpreadable");
-var symbolIsRegExp = InternalSymbol("Symbol.isRegExp");
-var symbolIterator = InternalSymbol("Symbol.iterator");
-var symbolToStringTag = InternalSymbol("Symbol.toStringTag");
-var symbolUnscopables = InternalSymbol("Symbol.unscopables");
-
-
 //-------------------------------------------------------------------
 
 function SetUpSymbol() {
@@ -104,6 +89,8 @@
     // "isConcatSpreadable", symbolIsConcatSpreadable,
     // "isRegExp", symbolIsRegExp,
     "iterator", symbolIterator,
+    // TODO(dslomov, caitp): Currently defined in harmony-tostring.js ---
+    // Move here when shipping
     // "toStringTag", symbolToStringTag,
     "unscopables", symbolUnscopables
   ));
@@ -113,6 +100,8 @@
   ));
 
   %AddNamedProperty($Symbol.prototype, "constructor", $Symbol, DONT_ENUM);
+  %AddNamedProperty(
+      $Symbol.prototype, symbolToStringTag, "Symbol", DONT_ENUM | READ_ONLY);
   InstallFunctions($Symbol.prototype, DONT_ENUM, $Array(
     "toString", SymbolToString,
     "valueOf", SymbolValueOf
diff --git a/src/test/DEPS b/src/test/DEPS
deleted file mode 100644
index 13855ec..0000000
--- a/src/test/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
-  "+include/libplatform/libplatform.h"
-]
diff --git a/src/test/test-utils.cc b/src/test/test-utils.cc
deleted file mode 100644
index 1041465..0000000
--- a/src/test/test-utils.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/test/test-utils.h"
-
-#include "src/isolate-inl.h"
-
-namespace v8 {
-
-// static
-Isolate* TestWithIsolate::isolate_ = NULL;
-
-
-TestWithIsolate::TestWithIsolate()
-    : isolate_scope_(isolate()), handle_scope_(isolate()) {}
-
-
-TestWithIsolate::~TestWithIsolate() {}
-
-
-// static
-void TestWithIsolate::SetUpTestCase() {
-  Test::SetUpTestCase();
-  EXPECT_EQ(NULL, isolate_);
-  isolate_ = v8::Isolate::New();
-  EXPECT_TRUE(isolate_ != NULL);
-}
-
-
-// static
-void TestWithIsolate::TearDownTestCase() {
-  ASSERT_TRUE(isolate_ != NULL);
-  isolate_->Dispose();
-  isolate_ = NULL;
-  Test::TearDownTestCase();
-}
-
-
-TestWithContext::TestWithContext()
-    : context_(Context::New(isolate())), context_scope_(context_) {}
-
-
-TestWithContext::~TestWithContext() {}
-
-
-namespace internal {
-
-TestWithIsolate::~TestWithIsolate() {}
-
-
-Factory* TestWithIsolate::factory() const { return isolate()->factory(); }
-
-
-TestWithZone::~TestWithZone() {}
-
-}  // namespace internal
-}  // namespace v8
diff --git a/src/test/test-utils.h b/src/test/test-utils.h
deleted file mode 100644
index 05d1ea6..0000000
--- a/src/test/test-utils.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_TEST_TEST_UTILS_H_
-#define V8_TEST_TEST_UTILS_H_
-
-#include "include/v8.h"
-#include "src/base/macros.h"
-#include "src/zone.h"
-#include "testing/gtest-support.h"
-
-namespace v8 {
-
-class TestWithIsolate : public ::testing::Test {
- public:
-  TestWithIsolate();
-  virtual ~TestWithIsolate();
-
-  Isolate* isolate() const { return isolate_; }
-
-  static void SetUpTestCase();
-  static void TearDownTestCase();
-
- private:
-  static Isolate* isolate_;
-  Isolate::Scope isolate_scope_;
-  HandleScope handle_scope_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestWithIsolate);
-};
-
-
-class TestWithContext : public virtual TestWithIsolate {
- public:
-  TestWithContext();
-  virtual ~TestWithContext();
-
-  const Local<Context>& context() const { return context_; }
-
- private:
-  Local<Context> context_;
-  Context::Scope context_scope_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestWithContext);
-};
-
-
-namespace internal {
-
-// Forward declarations.
-class Factory;
-
-
-class TestWithIsolate : public virtual ::v8::TestWithIsolate {
- public:
-  TestWithIsolate() {}
-  virtual ~TestWithIsolate();
-
-  Factory* factory() const;
-  Isolate* isolate() const {
-    return reinterpret_cast<Isolate*>(::v8::TestWithIsolate::isolate());
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestWithIsolate);
-};
-
-
-class TestWithZone : public TestWithIsolate {
- public:
-  TestWithZone() : zone_(isolate()) {}
-  virtual ~TestWithZone();
-
-  Zone* zone() { return &zone_; }
-
- private:
-  Zone zone_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestWithZone);
-};
-
-}  // namespace internal
-}  // namespace v8
-
-#endif  // V8_TEST_TEST_UTILS_H_
diff --git a/src/test/test.gyp b/src/test/test.gyp
deleted file mode 100644
index f4c6a5e..0000000
--- a/src/test/test.gyp
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2014 the V8 project authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
-  'variables': {
-    'v8_code': 1,
-  },
-  'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
-  'targets': [
-    {
-      'target_name': 'run-all-unittests',
-      'type': 'static_library',
-      'variables': {
-        'optimize': 'max',
-      },
-      'dependencies': [
-        '../../testing/gmock.gyp:gmock',
-        '../../testing/gtest.gyp:gtest',
-        '../../tools/gyp/v8.gyp:v8_libplatform',
-      ],
-      'include_dirs': [
-        '../..',
-      ],
-      'sources': [  ### gcmole(all) ###
-        'run-all-unittests.cc',
-        'test-utils.h',
-        'test-utils.cc',
-      ],
-      'export_dependent_settings': [
-        '../../testing/gmock.gyp:gmock',
-        '../../testing/gtest.gyp:gtest',
-      ],
-      'conditions': [
-        ['component=="shared_library"', {
-          # compiler-unittests can't be built against a shared library, so we
-          # need to depend on the underlying static target in that case.
-          'conditions': [
-            ['v8_use_snapshot=="true"', {
-              'dependencies': ['../../tools/gyp/v8.gyp:v8_snapshot'],
-            },
-            {
-              'dependencies': [
-                '../../tools/gyp/v8.gyp:v8_nosnapshot',
-              ],
-            }],
-          ],
-        }, {
-          'dependencies': ['../../tools/gyp/v8.gyp:v8'],
-        }],
-        ['os_posix == 1', {
-          # TODO(svenpanne): This is a temporary work-around to fix the warnings
-          # that show up because we use -std=gnu++0x instead of -std=c++11.
-          'cflags!': [
-            '-pedantic',
-          ],
-          'direct_dependent_settings': {
-            'cflags!': [
-              '-pedantic',
-            ],
-          },
-        }],
-        ['want_separate_host_toolset==1', {
-          'toolsets': ['host', 'target'],
-        }, {
-          'toolsets': ['target'],
-        }],
-      ],
-    },
-  ],
-}
diff --git a/third_party/fdlibm/LICENSE b/src/third_party/fdlibm/LICENSE
similarity index 100%
rename from third_party/fdlibm/LICENSE
rename to src/third_party/fdlibm/LICENSE
diff --git a/third_party/fdlibm/README.v8 b/src/third_party/fdlibm/README.v8
similarity index 100%
rename from third_party/fdlibm/README.v8
rename to src/third_party/fdlibm/README.v8
diff --git a/src/third_party/fdlibm/fdlibm.cc b/src/third_party/fdlibm/fdlibm.cc
new file mode 100644
index 0000000..cc5dbc2
--- /dev/null
+++ b/src/third_party/fdlibm/fdlibm.cc
@@ -0,0 +1,294 @@
+// The following is adapted from fdlibm (http://www.netlib.org/fdlibm).
+//
+// ====================================================
+// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+//
+// Developed at SunSoft, a Sun Microsystems, Inc. business.
+// Permission to use, copy, modify, and distribute this
+// software is freely granted, provided that this notice
+// is preserved.
+// ====================================================
+//
+// The original source code covered by the above license above has been
+// modified significantly by Google Inc.
+// Copyright 2014 the V8 project authors. All rights reserved.
+
+#include "src/v8.h"
+
+#include "src/double.h"
+#include "src/third_party/fdlibm/fdlibm.h"
+
+
+namespace v8 {
+namespace fdlibm {
+
+#ifdef _MSC_VER
+inline double scalbn(double x, int y) { return _scalb(x, y); }
+#endif  // _MSC_VER
+
+const double MathConstants::constants[] = {
+    6.36619772367581382433e-01,   // invpio2    0
+    1.57079632673412561417e+00,   // pio2_1     1
+    6.07710050650619224932e-11,   // pio2_1t    2
+    6.07710050630396597660e-11,   // pio2_2     3
+    2.02226624879595063154e-21,   // pio2_2t    4
+    2.02226624871116645580e-21,   // pio2_3     5
+    8.47842766036889956997e-32,   // pio2_3t    6
+    -1.66666666666666324348e-01,  // S1         7  coefficients for sin
+    8.33333333332248946124e-03,   //            8
+    -1.98412698298579493134e-04,  //            9
+    2.75573137070700676789e-06,   //           10
+    -2.50507602534068634195e-08,  //           11
+    1.58969099521155010221e-10,   // S6        12
+    4.16666666666666019037e-02,   // C1        13  coefficients for cos
+    -1.38888888888741095749e-03,  //           14
+    2.48015872894767294178e-05,   //           15
+    -2.75573143513906633035e-07,  //           16
+    2.08757232129817482790e-09,   //           17
+    -1.13596475577881948265e-11,  // C6        18
+    3.33333333333334091986e-01,   // T0        19  coefficients for tan
+    1.33333333333201242699e-01,   //           20
+    5.39682539762260521377e-02,   //           21
+    2.18694882948595424599e-02,   //           22
+    8.86323982359930005737e-03,   //           23
+    3.59207910759131235356e-03,   //           24
+    1.45620945432529025516e-03,   //           25
+    5.88041240820264096874e-04,   //           26
+    2.46463134818469906812e-04,   //           27
+    7.81794442939557092300e-05,   //           28
+    7.14072491382608190305e-05,   //           29
+    -1.85586374855275456654e-05,  //           30
+    2.59073051863633712884e-05,   // T12       31
+    7.85398163397448278999e-01,   // pio4      32
+    3.06161699786838301793e-17,   // pio4lo    33
+    6.93147180369123816490e-01,   // ln2_hi    34
+    1.90821492927058770002e-10,   // ln2_lo    35
+    6.666666666666666666e-01,     // 2/3       36
+    6.666666666666735130e-01,     // LP1       37  coefficients for log1p
+    3.999999999940941908e-01,     //           38
+    2.857142874366239149e-01,     //           39
+    2.222219843214978396e-01,     //           40
+    1.818357216161805012e-01,     //           41
+    1.531383769920937332e-01,     //           42
+    1.479819860511658591e-01,     // LP7       43
+    7.09782712893383973096e+02,   //           44  overflow threshold for expm1
+    1.44269504088896338700e+00,   // 1/ln2     45
+    -3.33333333333331316428e-02,  // Q1        46  coefficients for expm1
+    1.58730158725481460165e-03,   //           47
+    -7.93650757867487942473e-05,  //           48
+    4.00821782732936239552e-06,   //           49
+    -2.01099218183624371326e-07,  // Q5        50
+    710.4758600739439,            //           51  overflow threshold sinh, cosh
+    4.34294481903251816668e-01,   // ivln10    52  coefficients for log10
+    3.01029995663611771306e-01,   // log10_2hi 53
+    3.69423907715893078616e-13,   // log10_2lo 54
+    5.99999999999994648725e-01,   // L1        55  coefficients for log2
+    4.28571428578550184252e-01,   //           56
+    3.33333329818377432918e-01,   //           57
+    2.72728123808534006489e-01,   //           58
+    2.30660745775561754067e-01,   //           59
+    2.06975017800338417784e-01,   // L6        60
+    9.61796693925975554329e-01,   // cp        61  2/(3*ln(2))
+    9.61796700954437255859e-01,   // cp_h      62
+    -7.02846165095275826516e-09,  // cp_l      63
+    5.84962487220764160156e-01,   // dp_h      64
+    1.35003920212974897128e-08    // dp_l      65
+};
+
+
+// Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
+static const int two_over_pi[] = {
+    0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 0x95993C,
+    0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, 0x424DD2, 0xE00649,
+    0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 0xA73EE8, 0x8235F5, 0x2EBB44,
+    0x84E99C, 0x7026B4, 0x5F7E41, 0x3991D6, 0x398353, 0x39F49C, 0x845F8B,
+    0xBDF928, 0x3B1FF8, 0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D,
+    0x367ECF, 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
+    0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, 0x560330,
+    0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, 0x91615E, 0xE61B08,
+    0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 0x4D7327, 0x310606, 0x1556CA,
+    0x73A8C9, 0x60E27B, 0xC08C6B};
+
+static const double zero = 0.0;
+static const double two24 = 1.6777216e+07;
+static const double one = 1.0;
+static const double twon24 = 5.9604644775390625e-08;
+
+static const double PIo2[] = {
+    1.57079625129699707031e+00,  // 0x3FF921FB, 0x40000000
+    7.54978941586159635335e-08,  // 0x3E74442D, 0x00000000
+    5.39030252995776476554e-15,  // 0x3CF84698, 0x80000000
+    3.28200341580791294123e-22,  // 0x3B78CC51, 0x60000000
+    1.27065575308067607349e-29,  // 0x39F01B83, 0x80000000
+    1.22933308981111328932e-36,  // 0x387A2520, 0x40000000
+    2.73370053816464559624e-44,  // 0x36E38222, 0x80000000
+    2.16741683877804819444e-51   // 0x3569F31D, 0x00000000
+};
+
+
+int __kernel_rem_pio2(double* x, double* y, int e0, int nx) {
+  static const int32_t jk = 3;
+  double fw;
+  int32_t jx = nx - 1;
+  int32_t jv = (e0 - 3) / 24;
+  if (jv < 0) jv = 0;
+  int32_t q0 = e0 - 24 * (jv + 1);
+  int32_t m = jx + jk;
+
+  double f[10];
+  for (int i = 0, j = jv - jx; i <= m; i++, j++) {
+    f[i] = (j < 0) ? zero : static_cast<double>(two_over_pi[j]);
+  }
+
+  double q[10];
+  for (int i = 0; i <= jk; i++) {
+    fw = 0.0;
+    for (int j = 0; j <= jx; j++) fw += x[j] * f[jx + i - j];
+    q[i] = fw;
+  }
+
+  int32_t jz = jk;
+
+recompute:
+
+  int32_t iq[10];
+  double z = q[jz];
+  for (int i = 0, j = jz; j > 0; i++, j--) {
+    fw = static_cast<double>(static_cast<int32_t>(twon24 * z));
+    iq[i] = static_cast<int32_t>(z - two24 * fw);
+    z = q[j - 1] + fw;
+  }
+
+  z = scalbn(z, q0);
+  z -= 8.0 * std::floor(z * 0.125);
+  int32_t n = static_cast<int32_t>(z);
+  z -= static_cast<double>(n);
+  int32_t ih = 0;
+  if (q0 > 0) {
+    int32_t i = (iq[jz - 1] >> (24 - q0));
+    n += i;
+    iq[jz - 1] -= i << (24 - q0);
+    ih = iq[jz - 1] >> (23 - q0);
+  } else if (q0 == 0) {
+    ih = iq[jz - 1] >> 23;
+  } else if (z >= 0.5) {
+    ih = 2;
+  }
+
+  if (ih > 0) {
+    n += 1;
+    int32_t carry = 0;
+    for (int i = 0; i < jz; i++) {
+      int32_t j = iq[i];
+      if (carry == 0) {
+        if (j != 0) {
+          carry = 1;
+          iq[i] = 0x1000000 - j;
+        }
+      } else {
+        iq[i] = 0xffffff - j;
+      }
+    }
+    if (q0 == 1) {
+      iq[jz - 1] &= 0x7fffff;
+    } else if (q0 == 2) {
+      iq[jz - 1] &= 0x3fffff;
+    }
+    if (ih == 2) {
+      z = one - z;
+      if (carry != 0) z -= scalbn(one, q0);
+    }
+  }
+
+  if (z == zero) {
+    int32_t j = 0;
+    for (int i = jz - 1; i >= jk; i--) j |= iq[i];
+    if (j == 0) {
+      int32_t k = 1;
+      while (iq[jk - k] == 0) k++;
+      for (int i = jz + 1; i <= jz + k; i++) {
+        f[jx + i] = static_cast<double>(two_over_pi[jv + i]);
+        for (j = 0, fw = 0.0; j <= jx; j++) fw += x[j] * f[jx + i - j];
+        q[i] = fw;
+      }
+      jz += k;
+      goto recompute;
+    }
+  }
+
+  if (z == 0.0) {
+    jz -= 1;
+    q0 -= 24;
+    while (iq[jz] == 0) {
+      jz--;
+      q0 -= 24;
+    }
+  } else {
+    z = scalbn(z, -q0);
+    if (z >= two24) {
+      fw = static_cast<double>(static_cast<int32_t>(twon24 * z));
+      iq[jz] = static_cast<int32_t>(z - two24 * fw);
+      jz += 1;
+      q0 += 24;
+      iq[jz] = static_cast<int32_t>(fw);
+    } else {
+      iq[jz] = static_cast<int32_t>(z);
+    }
+  }
+
+  fw = scalbn(one, q0);
+  for (int i = jz; i >= 0; i--) {
+    q[i] = fw * static_cast<double>(iq[i]);
+    fw *= twon24;
+  }
+
+  double fq[10];
+  for (int i = jz; i >= 0; i--) {
+    fw = 0.0;
+    for (int k = 0; k <= jk && k <= jz - i; k++) fw += PIo2[k] * q[i + k];
+    fq[jz - i] = fw;
+  }
+
+  fw = 0.0;
+  for (int i = jz; i >= 0; i--) fw += fq[i];
+  y[0] = (ih == 0) ? fw : -fw;
+  fw = fq[0] - fw;
+  for (int i = 1; i <= jz; i++) fw += fq[i];
+  y[1] = (ih == 0) ? fw : -fw;
+  return n & 7;
+}
+
+
+int rempio2(double x, double* y) {
+  int32_t hx = static_cast<int32_t>(internal::double_to_uint64(x) >> 32);
+  int32_t ix = hx & 0x7fffffff;
+
+  if (ix >= 0x7ff00000) {
+    *y = base::OS::nan_value();
+    return 0;
+  }
+
+  int32_t e0 = (ix >> 20) - 1046;
+  uint64_t zi = internal::double_to_uint64(x) & 0xFFFFFFFFu;
+  zi |= static_cast<uint64_t>(ix - (e0 << 20)) << 32;
+  double z = internal::uint64_to_double(zi);
+
+  double tx[3];
+  for (int i = 0; i < 2; i++) {
+    tx[i] = static_cast<double>(static_cast<int32_t>(z));
+    z = (z - tx[i]) * two24;
+  }
+  tx[2] = z;
+
+  int nx = 3;
+  while (tx[nx - 1] == zero) nx--;
+  int n = __kernel_rem_pio2(tx, y, e0, nx);
+  if (hx < 0) {
+    y[0] = -y[0];
+    y[1] = -y[1];
+    return -n;
+  }
+  return n;
+}
+}
+}  // namespace v8::internal
diff --git a/src/third_party/fdlibm/fdlibm.h b/src/third_party/fdlibm/fdlibm.h
new file mode 100644
index 0000000..c7bc09a
--- /dev/null
+++ b/src/third_party/fdlibm/fdlibm.h
@@ -0,0 +1,31 @@
+// The following is adapted from fdlibm (http://www.netlib.org/fdlibm).
+//
+// ====================================================
+// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+//
+// Developed at SunSoft, a Sun Microsystems, Inc. business.
+// Permission to use, copy, modify, and distribute this
+// software is freely granted, provided that this notice
+// is preserved.
+// ====================================================
+//
+// The original source code covered by the above license above has been
+// modified significantly by Google Inc.
+// Copyright 2014 the V8 project authors. All rights reserved.
+
+#ifndef V8_FDLIBM_H_
+#define V8_FDLIBM_H_
+
+namespace v8 {
+namespace fdlibm {
+
+int rempio2(double x, double* y);
+
+// Constants to be exposed to builtins via Float64Array.
+struct MathConstants {
+  static const double constants[66];
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_FDLIBM_H_
diff --git a/src/third_party/fdlibm/fdlibm.js b/src/third_party/fdlibm/fdlibm.js
new file mode 100644
index 0000000..ceeacc5
--- /dev/null
+++ b/src/third_party/fdlibm/fdlibm.js
@@ -0,0 +1,996 @@
+// The following is adapted from fdlibm (http://www.netlib.org/fdlibm),
+//
+// ====================================================
+// Copyright (C) 1993-2004 by Sun Microsystems, Inc. All rights reserved.
+//
+// Developed at SunSoft, a Sun Microsystems, Inc. business.
+// Permission to use, copy, modify, and distribute this
+// software is freely granted, provided that this notice
+// is preserved.
+// ====================================================
+//
+// The original source code covered by the above license above has been
+// modified significantly by Google Inc.
+// Copyright 2014 the V8 project authors. All rights reserved.
+//
+// The following is a straightforward translation of fdlibm routines
+// by Raymond Toy (rtoy@google.com).
+
+// Double constants that do not have empty lower 32 bits are found in fdlibm.cc
+// and exposed through kMath as typed array. We assume the compiler to convert
+// from decimal to binary accurately enough to produce the intended values.
+// kMath is initialized to a Float64Array during genesis and not writable.
+
+"use strict";
+
+var kMath;
+
+const INVPIO2 = kMath[0];
+const PIO2_1  = kMath[1];
+const PIO2_1T = kMath[2];
+const PIO2_2  = kMath[3];
+const PIO2_2T = kMath[4];
+const PIO2_3  = kMath[5];
+const PIO2_3T = kMath[6];
+const PIO4    = kMath[32];
+const PIO4LO  = kMath[33];
+
+// Compute k and r such that x - k*pi/2 = r where |r| < pi/4. For
+// precision, r is returned as two values y0 and y1 such that r = y0 + y1
+// to more than double precision.
+macro REMPIO2(X)
+  var n, y0, y1;
+  var hx = %_DoubleHi(X);
+  var ix = hx & 0x7fffffff;
+
+  if (ix < 0x4002d97c) {
+    // |X| ~< 3*pi/4, special case with n = +/- 1
+    if (hx > 0) {
+      var z = X - PIO2_1;
+      if (ix != 0x3ff921fb) {
+        // 33+53 bit pi is good enough
+        y0 = z - PIO2_1T;
+        y1 = (z - y0) - PIO2_1T;
+      } else {
+        // near pi/2, use 33+33+53 bit pi
+        z -= PIO2_2;
+        y0 = z - PIO2_2T;
+        y1 = (z - y0) - PIO2_2T;
+      }
+      n = 1;
+    } else {
+      // Negative X
+      var z = X + PIO2_1;
+      if (ix != 0x3ff921fb) {
+        // 33+53 bit pi is good enough
+        y0 = z + PIO2_1T;
+        y1 = (z - y0) + PIO2_1T;
+      } else {
+        // near pi/2, use 33+33+53 bit pi
+        z += PIO2_2;
+        y0 = z + PIO2_2T;
+        y1 = (z - y0) + PIO2_2T;
+      }
+      n = -1;
+    }
+  } else if (ix <= 0x413921fb) {
+    // |X| ~<= 2^19*(pi/2), medium size
+    var t = MathAbs(X);
+    n = (t * INVPIO2 + 0.5) | 0;
+    var r = t - n * PIO2_1;
+    var w = n * PIO2_1T;
+    // First round good to 85 bit
+    y0 = r - w;
+    if (ix - (%_DoubleHi(y0) & 0x7ff00000) > 0x1000000) {
+      // 2nd iteration needed, good to 118
+      t = r;
+      w = n * PIO2_2;
+      r = t - w;
+      w = n * PIO2_2T - ((t - r) - w);
+      y0 = r - w;
+      if (ix - (%_DoubleHi(y0) & 0x7ff00000) > 0x3100000) {
+        // 3rd iteration needed. 151 bits accuracy
+        t = r;
+        w = n * PIO2_3;
+        r = t - w;
+        w = n * PIO2_3T - ((t - r) - w);
+        y0 = r - w;
+      }
+    }
+    y1 = (r - y0) - w;
+    if (hx < 0) {
+      n = -n;
+      y0 = -y0;
+      y1 = -y1;
+    }
+  } else {
+    // Need to do full Payne-Hanek reduction here.
+    var r = %RemPiO2(X);
+    n = r[0];
+    y0 = r[1];
+    y1 = r[2];
+  }
+endmacro
+
+
+// __kernel_sin(X, Y, IY)
+// kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854
+// Input X is assumed to be bounded by ~pi/4 in magnitude.
+// Input Y is the tail of X so that x = X + Y.
+//
+// Algorithm
+//  1. Since ieee_sin(-x) = -ieee_sin(x), we need only to consider positive x.
+//  2. ieee_sin(x) is approximated by a polynomial of degree 13 on
+//     [0,pi/4]
+//                           3            13
+//          sin(x) ~ x + S1*x + ... + S6*x
+//     where
+//
+//    |ieee_sin(x)    2     4     6     8     10     12  |     -58
+//    |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x  +S6*x   )| <= 2
+//    |  x                                               |
+//
+//  3. ieee_sin(X+Y) = ieee_sin(X) + sin'(X')*Y
+//              ~ ieee_sin(X) + (1-X*X/2)*Y
+//     For better accuracy, let
+//               3      2      2      2      2
+//          r = X *(S2+X *(S3+X *(S4+X *(S5+X *S6))))
+//     then                   3    2
+//          sin(x) = X + (S1*X + (X *(r-Y/2)+Y))
+//
+macro KSIN(x)
+kMath[7+x]
+endmacro
+
+macro RETURN_KERNELSIN(X, Y, SIGN)
+  var z = X * X;
+  var v = z * X;
+  var r = KSIN(1) + z * (KSIN(2) + z * (KSIN(3) +
+                    z * (KSIN(4) + z * KSIN(5))));
+  return (X - ((z * (0.5 * Y - v * r) - Y) - v * KSIN(0))) SIGN;
+endmacro
+
+// __kernel_cos(X, Y)
+// kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
+// Input X is assumed to be bounded by ~pi/4 in magnitude.
+// Input Y is the tail of X so that x = X + Y.
+//
+// Algorithm
+//  1. Since ieee_cos(-x) = ieee_cos(x), we need only to consider positive x.
+//  2. ieee_cos(x) is approximated by a polynomial of degree 14 on
+//     [0,pi/4]
+//                                   4            14
+//          cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
+//     where the remez error is
+//
+//  |                   2     4     6     8     10    12     14 |     -58
+//  |ieee_cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  )| <= 2
+//  |                                                           |
+//
+//                 4     6     8     10    12     14
+//  3. let r = C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  , then
+//         ieee_cos(x) = 1 - x*x/2 + r
+//     since ieee_cos(X+Y) ~ ieee_cos(X) - ieee_sin(X)*Y
+//                    ~ ieee_cos(X) - X*Y,
+//     a correction term is necessary in ieee_cos(x) and hence
+//         cos(X+Y) = 1 - (X*X/2 - (r - X*Y))
+//     For better accuracy when x > 0.3, let qx = |x|/4 with
+//     the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
+//     Then
+//         cos(X+Y) = (1-qx) - ((X*X/2-qx) - (r-X*Y)).
+//     Note that 1-qx and (X*X/2-qx) is EXACT here, and the
+//     magnitude of the latter is at least a quarter of X*X/2,
+//     thus, reducing the rounding error in the subtraction.
+//
+macro KCOS(x)
+kMath[13+x]
+endmacro
+
+macro RETURN_KERNELCOS(X, Y, SIGN)
+  var ix = %_DoubleHi(X) & 0x7fffffff;
+  var z = X * X;
+  var r = z * (KCOS(0) + z * (KCOS(1) + z * (KCOS(2)+
+          z * (KCOS(3) + z * (KCOS(4) + z * KCOS(5))))));
+  if (ix < 0x3fd33333) {  // |x| ~< 0.3
+    return (1 - (0.5 * z - (z * r - X * Y))) SIGN;
+  } else {
+    var qx;
+    if (ix > 0x3fe90000) {  // |x| > 0.78125
+      qx = 0.28125;
+    } else {
+      qx = %_ConstructDouble(%_DoubleHi(0.25 * X), 0);
+    }
+    var hz = 0.5 * z - qx;
+    return (1 - qx - (hz - (z * r - X * Y))) SIGN;
+  }
+endmacro
+
+
+// kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
+// Input x is assumed to be bounded by ~pi/4 in magnitude.
+// Input y is the tail of x.
+// Input k indicates whether ieee_tan (if k = 1) or -1/tan (if k = -1)
+// is returned.
+//
+// Algorithm
+//  1. Since ieee_tan(-x) = -ieee_tan(x), we need only to consider positive x.
+//  2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0.
+//  3. ieee_tan(x) is approximated by a odd polynomial of degree 27 on
+//     [0,0.67434]
+//                           3             27
+//          tan(x) ~ x + T1*x + ... + T13*x
+//     where
+//
+//     |ieee_tan(x)    2     4            26   |     -59.2
+//     |----- - (1+T1*x +T2*x +.... +T13*x    )| <= 2
+//     |  x                                    |
+//
+//     Note: ieee_tan(x+y) = ieee_tan(x) + tan'(x)*y
+//                    ~ ieee_tan(x) + (1+x*x)*y
+//     Therefore, for better accuracy in computing ieee_tan(x+y), let
+//               3      2      2       2       2
+//          r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
+//     then
+//                              3    2
+//          tan(x+y) = x + (T1*x + (x *(r+y)+y))
+//
+//  4. For x in [0.67434,pi/4],  let y = pi/4 - x, then
+//          tan(x) = ieee_tan(pi/4-y) = (1-ieee_tan(y))/(1+ieee_tan(y))
+//                 = 1 - 2*(ieee_tan(y) - (ieee_tan(y)^2)/(1+ieee_tan(y)))
+//
+// Set returnTan to 1 for tan; -1 for cot.  Anything else is illegal
+// and will cause incorrect results.
+//
+macro KTAN(x)
+kMath[19+x]
+endmacro
+
+function KernelTan(x, y, returnTan) {
+  var z;
+  var w;
+  var hx = %_DoubleHi(x);
+  var ix = hx & 0x7fffffff;
+
+  if (ix < 0x3e300000) {  // |x| < 2^-28
+    if (((ix | %_DoubleLo(x)) | (returnTan + 1)) == 0) {
+      // x == 0 && returnTan = -1
+      return 1 / MathAbs(x);
+    } else {
+      if (returnTan == 1) {
+        return x;
+      } else {
+        // Compute -1/(x + y) carefully
+        var w = x + y;
+        var z = %_ConstructDouble(%_DoubleHi(w), 0);
+        var v = y - (z - x);
+        var a = -1 / w;
+        var t = %_ConstructDouble(%_DoubleHi(a), 0);
+        var s = 1 + t * z;
+        return t + a * (s + t * v);
+      }
+    }
+  }
+  if (ix >= 0x3fe59428) {  // |x| > .6744
+    if (x < 0) {
+      x = -x;
+      y = -y;
+    }
+    z = PIO4 - x;
+    w = PIO4LO - y;
+    x = z + w;
+    y = 0;
+  }
+  z = x * x;
+  w = z * z;
+
+  // Break x^5 * (T1 + x^2*T2 + ...) into
+  // x^5 * (T1 + x^4*T3 + ... + x^20*T11) +
+  // x^5 * (x^2 * (T2 + x^4*T4 + ... + x^22*T12))
+  var r = KTAN(1) + w * (KTAN(3) + w * (KTAN(5) +
+                    w * (KTAN(7) + w * (KTAN(9) + w * KTAN(11)))));
+  var v = z * (KTAN(2) + w * (KTAN(4) + w * (KTAN(6) +
+                         w * (KTAN(8) + w * (KTAN(10) + w * KTAN(12))))));
+  var s = z * x;
+  r = y + z * (s * (r + v) + y);
+  r = r + KTAN(0) * s;
+  w = x + r;
+  if (ix >= 0x3fe59428) {
+    return (1 - ((hx >> 30) & 2)) *
+      (returnTan - 2.0 * (x - (w * w / (w + returnTan) - r)));
+  }
+  if (returnTan == 1) {
+    return w;
+  } else {
+    z = %_ConstructDouble(%_DoubleHi(w), 0);
+    v = r - (z - x);
+    var a = -1 / w;
+    var t = %_ConstructDouble(%_DoubleHi(a), 0);
+    s = 1 + t * z;
+    return t + a * (s + t * v);
+  }
+}
+
+function MathSinSlow(x) {
+  REMPIO2(x);
+  var sign = 1 - (n & 2);
+  if (n & 1) {
+    RETURN_KERNELCOS(y0, y1, * sign);
+  } else {
+    RETURN_KERNELSIN(y0, y1, * sign);
+  }
+}
+
+function MathCosSlow(x) {
+  REMPIO2(x);
+  if (n & 1) {
+    var sign = (n & 2) - 1;
+    RETURN_KERNELSIN(y0, y1, * sign);
+  } else {
+    var sign = 1 - (n & 2);
+    RETURN_KERNELCOS(y0, y1, * sign);
+  }
+}
+
+// ECMA 262 - 15.8.2.16
+function MathSin(x) {
+  x = x * 1;  // Convert to number.
+  if ((%_DoubleHi(x) & 0x7fffffff) <= 0x3fe921fb) {
+    // |x| < pi/4, approximately.  No reduction needed.
+    RETURN_KERNELSIN(x, 0, /* empty */);
+  }
+  return MathSinSlow(x);
+}
+
+// ECMA 262 - 15.8.2.7
+function MathCos(x) {
+  x = x * 1;  // Convert to number.
+  if ((%_DoubleHi(x) & 0x7fffffff) <= 0x3fe921fb) {
+    // |x| < pi/4, approximately.  No reduction needed.
+    RETURN_KERNELCOS(x, 0, /* empty */);
+  }
+  return MathCosSlow(x);
+}
+
+// ECMA 262 - 15.8.2.18
+function MathTan(x) {
+  x = x * 1;  // Convert to number.
+  if ((%_DoubleHi(x) & 0x7fffffff) <= 0x3fe921fb) {
+    // |x| < pi/4, approximately.  No reduction needed.
+    return KernelTan(x, 0, 1);
+  }
+  REMPIO2(x);
+  return KernelTan(y0, y1, (n & 1) ? -1 : 1);
+}
+
+// ES6 draft 09-27-13, section 20.2.2.20.
+// Math.log1p
+//
+// Method :                  
+//   1. Argument Reduction: find k and f such that 
+//                      1+x = 2^k * (1+f), 
+//         where  sqrt(2)/2 < 1+f < sqrt(2) .
+//
+//      Note. If k=0, then f=x is exact. However, if k!=0, then f
+//      may not be representable exactly. In that case, a correction
+//      term is need. Let u=1+x rounded. Let c = (1+x)-u, then
+//      log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),
+//      and add back the correction term c/u.
+//      (Note: when x > 2**53, one can simply return log(x))
+//
+//   2. Approximation of log1p(f).
+//      Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
+//            = 2s + 2/3 s**3 + 2/5 s**5 + .....,
+//            = 2s + s*R
+//      We use a special Reme algorithm on [0,0.1716] to generate 
+//      a polynomial of degree 14 to approximate R The maximum error 
+//      of this polynomial approximation is bounded by 2**-58.45. In
+//      other words,
+//                      2      4      6      8      10      12      14
+//          R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s  +Lp6*s  +Lp7*s
+//      (the values of Lp1 to Lp7 are listed in the program)
+//      and
+//          |      2          14          |     -58.45
+//          | Lp1*s +...+Lp7*s    -  R(z) | <= 2 
+//          |                             |
+//      Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
+//      In order to guarantee error in log below 1ulp, we compute log
+//      by
+//              log1p(f) = f - (hfsq - s*(hfsq+R)).
+//
+//      3. Finally, log1p(x) = k*ln2 + log1p(f).  
+//                           = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
+//         Here ln2 is split into two floating point number: 
+//                      ln2_hi + ln2_lo,
+//         where n*ln2_hi is always exact for |n| < 2000.
+//
+// Special cases:
+//      log1p(x) is NaN with signal if x < -1 (including -INF) ; 
+//      log1p(+INF) is +INF; log1p(-1) is -INF with signal;
+//      log1p(NaN) is that NaN with no signal.
+//
+// Accuracy:
+//      according to an error analysis, the error is always less than
+//      1 ulp (unit in the last place).
+//
+// Constants:
+//      Constants are found in fdlibm.cc. We assume the C++ compiler to convert
+//      from decimal to binary accurately enough to produce the intended values.
+//
+// Note: Assuming log() return accurate answer, the following
+//       algorithm can be used to compute log1p(x) to within a few ULP:
+//
+//              u = 1+x;
+//              if (u==1.0) return x ; else
+//                          return log(u)*(x/(u-1.0));
+//
+//       See HP-15C Advanced Functions Handbook, p.193.
+//
+const LN2_HI    = kMath[34];
+const LN2_LO    = kMath[35];
+const TWO_THIRD = kMath[36];
+macro KLOG1P(x)
+(kMath[37+x])
+endmacro
+// 2^54
+const TWO54 = 18014398509481984;
+
+function MathLog1p(x) {
+  x = x * 1;  // Convert to number.
+  var hx = %_DoubleHi(x);
+  var ax = hx & 0x7fffffff;
+  var k = 1;
+  var f = x;
+  var hu = 1;
+  var c = 0;
+  var u = x;
+
+  if (hx < 0x3fda827a) {
+    // x < 0.41422
+    if (ax >= 0x3ff00000) {  // |x| >= 1
+      if (x === -1) {
+        return -INFINITY;  // log1p(-1) = -inf
+      } else {
+        return NAN;  // log1p(x<-1) = NaN
+      }
+    } else if (ax < 0x3c900000)  {
+      // For |x| < 2^-54 we can return x.
+      return x;
+    } else if (ax < 0x3e200000) {
+      // For |x| < 2^-29 we can use a simple two-term Taylor series.
+      return x - x * x * 0.5;
+    }
+
+    if ((hx > 0) || (hx <= -0x402D413D)) {  // (int) 0xbfd2bec3 = -0x402d413d
+      // -.2929 < x < 0.41422
+      k = 0;
+    }
+  }
+
+  // Handle Infinity and NAN
+  if (hx >= 0x7ff00000) return x;
+
+  if (k !== 0) {
+    if (hx < 0x43400000) {
+      // x < 2^53
+      u = 1 + x;
+      hu = %_DoubleHi(u);
+      k = (hu >> 20) - 1023;
+      c = (k > 0) ? 1 - (u - x) : x - (u - 1);
+      c = c / u;
+    } else {
+      hu = %_DoubleHi(u);
+      k = (hu >> 20) - 1023;
+    }
+    hu = hu & 0xfffff;
+    if (hu < 0x6a09e) {
+      u = %_ConstructDouble(hu | 0x3ff00000, %_DoubleLo(u));  // Normalize u.
+    } else {
+      ++k;
+      u = %_ConstructDouble(hu | 0x3fe00000, %_DoubleLo(u));  // Normalize u/2.
+      hu = (0x00100000 - hu) >> 2;
+    }
+    f = u - 1;
+  }
+
+  var hfsq = 0.5 * f * f;
+  if (hu === 0) {
+    // |f| < 2^-20;
+    if (f === 0) {
+      if (k === 0) {
+        return 0.0;
+      } else {
+        return k * LN2_HI + (c + k * LN2_LO);
+      }
+    }
+    var R = hfsq * (1 - TWO_THIRD * f);
+    if (k === 0) {
+      return f - R;
+    } else {
+      return k * LN2_HI - ((R - (k * LN2_LO + c)) - f);
+    }
+  }
+
+  var s = f / (2 + f); 
+  var z = s * s;
+  var R = z * (KLOG1P(0) + z * (KLOG1P(1) + z *
+              (KLOG1P(2) + z * (KLOG1P(3) + z *
+              (KLOG1P(4) + z * (KLOG1P(5) + z * KLOG1P(6)))))));
+  if (k === 0) {
+    return f - (hfsq - s * (hfsq + R));
+  } else {
+    return k * LN2_HI - ((hfsq - (s * (hfsq + R) + (k * LN2_LO + c))) - f);
+  }
+}
+
+// ES6 draft 09-27-13, section 20.2.2.14.
+// Math.expm1
+// Returns exp(x)-1, the exponential of x minus 1.
+//
+// Method
+//   1. Argument reduction:
+//      Given x, find r and integer k such that
+//
+//               x = k*ln2 + r,  |r| <= 0.5*ln2 ~ 0.34658  
+//
+//      Here a correction term c will be computed to compensate 
+//      the error in r when rounded to a floating-point number.
+//
+//   2. Approximating expm1(r) by a special rational function on
+//      the interval [0,0.34658]:
+//      Since
+//          r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
+//      we define R1(r*r) by
+//          r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
+//      That is,
+//          R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
+//                   = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
+//                   = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
+//      We use a special Remes algorithm on [0,0.347] to generate 
+//      a polynomial of degree 5 in r*r to approximate R1. The 
+//      maximum error of this polynomial approximation is bounded 
+//      by 2**-61. In other words,
+//          R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
+//      where   Q1  =  -1.6666666666666567384E-2,
+//              Q2  =   3.9682539681370365873E-4,
+//              Q3  =  -9.9206344733435987357E-6,
+//              Q4  =   2.5051361420808517002E-7,
+//              Q5  =  -6.2843505682382617102E-9;
+//      (where z=r*r, and the values of Q1 to Q5 are listed below)
+//      with error bounded by
+//          |                  5           |     -61
+//          | 1.0+Q1*z+...+Q5*z   -  R1(z) | <= 2 
+//          |                              |
+//
+//      expm1(r) = exp(r)-1 is then computed by the following 
+//      specific way which minimize the accumulation rounding error: 
+//                             2     3
+//                            r     r    [ 3 - (R1 + R1*r/2)  ]
+//            expm1(r) = r + --- + --- * [--------------------]
+//                            2     2    [ 6 - r*(3 - R1*r/2) ]
+//
+//      To compensate the error in the argument reduction, we use
+//              expm1(r+c) = expm1(r) + c + expm1(r)*c 
+//                         ~ expm1(r) + c + r*c 
+//      Thus c+r*c will be added in as the correction terms for
+//      expm1(r+c). Now rearrange the term to avoid optimization 
+//      screw up:
+//                      (      2                                    2 )
+//                      ({  ( r    [ R1 -  (3 - R1*r/2) ]  )  }    r  )
+//       expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
+//                      ({  ( 2    [ 6 - r*(3 - R1*r/2) ]  )  }    2  )
+//                      (                                             )
+//
+//                 = r - E
+//   3. Scale back to obtain expm1(x):
+//      From step 1, we have
+//         expm1(x) = either 2^k*[expm1(r)+1] - 1
+//                  = or     2^k*[expm1(r) + (1-2^-k)]
+//   4. Implementation notes:
+//      (A). To save one multiplication, we scale the coefficient Qi
+//           to Qi*2^i, and replace z by (x^2)/2.
+//      (B). To achieve maximum accuracy, we compute expm1(x) by
+//        (i)   if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
+//        (ii)  if k=0, return r-E
+//        (iii) if k=-1, return 0.5*(r-E)-0.5
+//        (iv)  if k=1 if r < -0.25, return 2*((r+0.5)- E)
+//                     else          return  1.0+2.0*(r-E);
+//        (v)   if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
+//        (vi)  if k <= 20, return 2^k((1-2^-k)-(E-r)), else
+//        (vii) return 2^k(1-((E+2^-k)-r)) 
+//
+// Special cases:
+//      expm1(INF) is INF, expm1(NaN) is NaN;
+//      expm1(-INF) is -1, and
+//      for finite argument, only expm1(0)=0 is exact.
+//
+// Accuracy:
+//      according to an error analysis, the error is always less than
+//      1 ulp (unit in the last place).
+//
+// Misc. info.
+//      For IEEE double 
+//          if x > 7.09782712893383973096e+02 then expm1(x) overflow
+//
+const KEXPM1_OVERFLOW = kMath[44];
+const INVLN2          = kMath[45];
+macro KEXPM1(x)
+(kMath[46+x])
+endmacro
+
+function MathExpm1(x) {
+  x = x * 1;  // Convert to number.
+  var y;
+  var hi;
+  var lo;
+  var k;
+  var t;
+  var c;
+    
+  var hx = %_DoubleHi(x);
+  var xsb = hx & 0x80000000;     // Sign bit of x
+  var y = (xsb === 0) ? x : -x;  // y = |x|
+  hx &= 0x7fffffff;              // High word of |x|
+
+  // Filter out huge and non-finite argument
+  if (hx >= 0x4043687a) {     // if |x| ~=> 56 * ln2
+    if (hx >= 0x40862e42) {   // if |x| >= 709.78
+      if (hx >= 0x7ff00000) {
+        // expm1(inf) = inf; expm1(-inf) = -1; expm1(nan) = nan;
+        return (x === -INFINITY) ? -1 : x;
+      }
+      if (x > KEXPM1_OVERFLOW) return INFINITY;  // Overflow
+    }
+    if (xsb != 0) return -1;  // x < -56 * ln2, return -1.
+  }
+
+  // Argument reduction
+  if (hx > 0x3fd62e42) {    // if |x| > 0.5 * ln2
+    if (hx < 0x3ff0a2b2) {  // and |x| < 1.5 * ln2
+      if (xsb === 0) {
+        hi = x - LN2_HI;
+        lo = LN2_LO;
+        k = 1;
+      } else {
+        hi = x + LN2_HI;
+        lo = -LN2_LO;
+        k = -1;
+      }
+    } else {
+      k = (INVLN2 * x + ((xsb === 0) ? 0.5 : -0.5)) | 0;
+      t = k;
+      // t * ln2_hi is exact here.
+      hi = x - t * LN2_HI;
+      lo = t * LN2_LO;
+    }
+    x = hi - lo;
+    c = (hi - x) - lo;
+  } else if (hx < 0x3c900000)	{
+    // When |x| < 2^-54, we can return x.
+    return x;
+  } else {
+    // Fall through.
+    k = 0;
+  }
+
+  // x is now in primary range
+  var hfx = 0.5 * x;
+  var hxs = x * hfx;
+  var r1 = 1 + hxs * (KEXPM1(0) + hxs * (KEXPM1(1) + hxs *
+                     (KEXPM1(2) + hxs * (KEXPM1(3) + hxs * KEXPM1(4)))));
+  t = 3 - r1 * hfx;
+  var e = hxs * ((r1 - t) / (6 - x * t));
+  if (k === 0) {  // c is 0
+    return x - (x*e - hxs);
+  } else {
+    e = (x * (e - c) - c);
+    e -= hxs;
+    if (k === -1) return 0.5 * (x - e) - 0.5;
+    if (k === 1) {
+      if (x < -0.25) return -2 * (e - (x + 0.5));
+      return 1 + 2 * (x - e);
+    }
+
+    if (k <= -2 || k > 56) {
+      // suffice to return exp(x) + 1
+      y = 1 - (e - x);
+      // Add k to y's exponent
+      y = %_ConstructDouble(%_DoubleHi(y) + (k << 20), %_DoubleLo(y));
+      return y - 1;
+    }
+    if (k < 20) {
+      // t = 1 - 2^k
+      t = %_ConstructDouble(0x3ff00000 - (0x200000 >> k), 0);
+      y = t - (e - x);
+      // Add k to y's exponent
+      y = %_ConstructDouble(%_DoubleHi(y) + (k << 20), %_DoubleLo(y));
+    } else {
+      // t = 2^-k
+      t = %_ConstructDouble((0x3ff - k) << 20, 0);
+      y = x - (e + t);
+      y += 1;
+      // Add k to y's exponent
+      y = %_ConstructDouble(%_DoubleHi(y) + (k << 20), %_DoubleLo(y));
+    }
+  }
+  return y;
+}
+
+
+// ES6 draft 09-27-13, section 20.2.2.30.
+// Math.sinh
+// Method :
+// mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
+//      1. Replace x by |x| (sinh(-x) = -sinh(x)).
+//      2.
+//                                                  E + E/(E+1)
+//          0        <= x <= 22     :  sinh(x) := --------------, E=expm1(x)
+//                                                      2
+//
+//          22       <= x <= lnovft :  sinh(x) := exp(x)/2 
+//          lnovft   <= x <= ln2ovft:  sinh(x) := exp(x/2)/2 * exp(x/2)
+//          ln2ovft  <  x           :  sinh(x) := x*shuge (overflow)
+//
+// Special cases:
+//      sinh(x) is |x| if x is +Infinity, -Infinity, or NaN.
+//      only sinh(0)=0 is exact for finite x.
+//
+const KSINH_OVERFLOW = kMath[51];
+const TWO_M28 = 3.725290298461914e-9;  // 2^-28, empty lower half
+const LOG_MAXD = 709.7822265625;  // 0x40862e42 00000000, empty lower half
+
+function MathSinh(x) {
+  x = x * 1;  // Convert to number.
+  var h = (x < 0) ? -0.5 : 0.5;
+  // |x| in [0, 22]. return sign(x)*0.5*(E+E/(E+1))
+  var ax = MathAbs(x);
+  if (ax < 22) {
+    // For |x| < 2^-28, sinh(x) = x
+    if (ax < TWO_M28) return x;
+    var t = MathExpm1(ax);
+    if (ax < 1) return h * (2 * t - t * t / (t + 1));
+    return h * (t + t / (t + 1));
+  }
+  // |x| in [22, log(maxdouble)], return 0.5 * exp(|x|)
+  if (ax < LOG_MAXD) return h * MathExp(ax);
+  // |x| in [log(maxdouble), overflowthreshold]
+  // overflowthreshold = 710.4758600739426
+  if (ax <= KSINH_OVERFLOW) {
+    var w = MathExp(0.5 * ax);
+    var t = h * w;
+    return t * w;
+  }
+  // |x| > overflowthreshold or is NaN.
+  // Return Infinity of the appropriate sign or NaN.
+  return x * INFINITY;
+}
+
+
+// ES6 draft 09-27-13, section 20.2.2.12.
+// Math.cosh
+// Method : 
+// mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
+//      1. Replace x by |x| (cosh(x) = cosh(-x)). 
+//      2.
+//                                                      [ exp(x) - 1 ]^2 
+//          0        <= x <= ln2/2  :  cosh(x) := 1 + -------------------
+//                                                         2*exp(x)
+//
+//                                                 exp(x) + 1/exp(x)
+//          ln2/2    <= x <= 22     :  cosh(x) := -------------------
+//                                                        2
+//          22       <= x <= lnovft :  cosh(x) := exp(x)/2 
+//          lnovft   <= x <= ln2ovft:  cosh(x) := exp(x/2)/2 * exp(x/2)
+//          ln2ovft  <  x           :  cosh(x) := huge*huge (overflow)
+//
+// Special cases:
+//      cosh(x) is |x| if x is +INF, -INF, or NaN.
+//      only cosh(0)=1 is exact for finite x.
+//
+const KCOSH_OVERFLOW = kMath[51];
+
+function MathCosh(x) {
+  x = x * 1;  // Convert to number.
+  var ix = %_DoubleHi(x) & 0x7fffffff;
+  // |x| in [0,0.5*log2], return 1+expm1(|x|)^2/(2*exp(|x|))
+  if (ix < 0x3fd62e43) {
+    var t = MathExpm1(MathAbs(x));
+    var w = 1 + t;
+    // For |x| < 2^-55, cosh(x) = 1
+    if (ix < 0x3c800000) return w;
+    return 1 + (t * t) / (w + w);
+  }
+  // |x| in [0.5*log2, 22], return (exp(|x|)+1/exp(|x|)/2
+  if (ix < 0x40360000) {
+    var t = MathExp(MathAbs(x));
+    return 0.5 * t + 0.5 / t;
+  }
+  // |x| in [22, log(maxdouble)], return half*exp(|x|)
+  if (ix < 0x40862e42) return 0.5 * MathExp(MathAbs(x));
+  // |x| in [log(maxdouble), overflowthreshold]
+  if (MathAbs(x) <= KCOSH_OVERFLOW) {
+    var w = MathExp(0.5 * MathAbs(x));
+    var t = 0.5 * w;
+    return t * w;
+  }
+  if (NUMBER_IS_NAN(x)) return x;
+  // |x| > overflowthreshold.
+  return INFINITY;
+}
+
+// ES6 draft 09-27-13, section 20.2.2.21.
+// Return the base 10 logarithm of x
+//
+// Method :
+//      Let log10_2hi = leading 40 bits of log10(2) and
+//          log10_2lo = log10(2) - log10_2hi,
+//          ivln10   = 1/log(10) rounded.
+//      Then
+//              n = ilogb(x),
+//              if(n<0)  n = n+1;
+//              x = scalbn(x,-n);
+//              log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x))
+//
+// Note 1:
+//      To guarantee log10(10**n)=n, where 10**n is normal, the rounding
+//      mode must set to Round-to-Nearest.
+// Note 2:
+//      [1/log(10)] rounded to 53 bits has error .198 ulps;
+//      log10 is monotonic at all binary break points.
+//
+// Special cases:
+//      log10(x) is NaN if x < 0;
+//      log10(+INF) is +INF; log10(0) is -INF;
+//      log10(NaN) is that NaN;
+//      log10(10**N) = N  for N=0,1,...,22.
+//
+
+const IVLN10 = kMath[52];
+const LOG10_2HI = kMath[53];
+const LOG10_2LO = kMath[54];
+
+function MathLog10(x) {
+  x = x * 1;  // Convert to number.
+  var hx = %_DoubleHi(x);
+  var lx = %_DoubleLo(x);
+  var k = 0;
+
+  if (hx < 0x00100000) {
+    // x < 2^-1022
+    // log10(+/- 0) = -Infinity.
+    if (((hx & 0x7fffffff) | lx) === 0) return -INFINITY;
+    // log10 of negative number is NaN.
+    if (hx < 0) return NAN;
+    // Subnormal number. Scale up x.
+    k -= 54;
+    x *= TWO54;
+    hx = %_DoubleHi(x);
+    lx = %_DoubleLo(x);
+  }
+
+  // Infinity or NaN.
+  if (hx >= 0x7ff00000) return x;
+
+  k += (hx >> 20) - 1023;
+  i = (k & 0x80000000) >> 31;
+  hx = (hx & 0x000fffff) | ((0x3ff - i) << 20);
+  y = k + i;
+  x = %_ConstructDouble(hx, lx);
+
+  z = y * LOG10_2LO + IVLN10 * MathLog(x);
+  return z + y * LOG10_2HI;
+}
+
+
+// ES6 draft 09-27-13, section 20.2.2.22.
+// Return the base 2 logarithm of x
+//
+// fdlibm does not have an explicit log2 function, but fdlibm's pow
+// function does implement an accurate log2 function as part of the
+// pow implementation.  This extracts the core parts of that as a
+// separate log2 function.
+
+// Method:
+// Compute log2(x) in two pieces:
+// log2(x) = w1 + w2
+// where w1 has 53-24 = 29 bits of trailing zeroes.
+
+const DP_H = kMath[64];
+const DP_L = kMath[65];
+
+// Polynomial coefficients for (3/2)*(log2(x) - 2*s - 2/3*s^3)
+macro KLOG2(x)
+(kMath[55+x])
+endmacro
+
+// cp = 2/(3*ln(2)). Note that cp_h + cp_l is cp, but with more accuracy.
+const CP = kMath[61];
+const CP_H = kMath[62];
+const CP_L = kMath[63];
+// 2^53
+const TWO53 = 9007199254740992; 
+
+function MathLog2(x) {
+  x = x * 1;  // Convert to number.
+  var ax = MathAbs(x);
+  var hx = %_DoubleHi(x);
+  var lx = %_DoubleLo(x);
+  var ix = hx & 0x7fffffff;
+
+  // Handle special cases.
+  // log2(+/- 0) = -Infinity
+  if ((ix | lx) == 0) return -INFINITY;
+
+  // log(x) = NaN, if x < 0
+  if (hx < 0) return NAN;
+
+  // log2(Infinity) = Infinity, log2(NaN) = NaN
+  if (ix >= 0x7ff00000) return x;
+
+  var n = 0;
+
+  // Take care of subnormal number.
+  if (ix < 0x00100000) {
+    ax *= TWO53;
+    n -= 53;
+    ix = %_DoubleHi(ax);
+  }
+
+  n += (ix >> 20) - 0x3ff;
+  var j = ix & 0x000fffff;
+
+  // Determine interval.
+  ix = j | 0x3ff00000;  // normalize ix.
+
+  var bp = 1;
+  var dp_h = 0;
+  var dp_l = 0;
+  if (j > 0x3988e) {  // |x| > sqrt(3/2)
+    if (j < 0xbb67a) {  // |x| < sqrt(3)
+      bp = 1.5;
+      dp_h = DP_H;
+      dp_l = DP_L;
+    } else {
+      n += 1;
+      ix -= 0x00100000;
+    }
+  }
+ 
+  ax = %_ConstructDouble(ix, %_DoubleLo(ax));
+
+  // Compute ss = s_h + s_l = (x - 1)/(x+1) or (x - 1.5)/(x + 1.5)
+  var u = ax - bp;
+  var v = 1 / (ax + bp);
+  var ss = u * v;
+  var s_h = %_ConstructDouble(%_DoubleHi(ss), 0);
+
+  // t_h = ax + bp[k] High
+  var t_h = %_ConstructDouble(%_DoubleHi(ax + bp), 0)
+  var t_l = ax - (t_h - bp);
+  var s_l = v * ((u - s_h * t_h) - s_h * t_l);
+
+  // Compute log2(ax)
+  var s2 = ss * ss;
+  var r = s2 * s2 * (KLOG2(0) + s2 * (KLOG2(1) + s2 * (KLOG2(2) + s2 * (
+                     KLOG2(3) + s2 * (KLOG2(4) + s2 * KLOG2(5))))));
+  r += s_l * (s_h + ss);
+  s2  = s_h * s_h;
+  t_h = %_ConstructDouble(%_DoubleHi(3.0 + s2 + r), 0);
+  t_l = r - ((t_h - 3.0) - s2);
+  // u + v = ss * (1 + ...)
+  u = s_h * t_h;
+  v = s_l * t_h + t_l * ss;
+
+  // 2 / (3 * log(2)) * (ss + ...)
+  p_h = %_ConstructDouble(%_DoubleHi(u + v), 0);
+  p_l = v - (p_h - u);
+  z_h = CP_H * p_h;
+  z_l = CP_L * p_h + p_l * CP + dp_l;
+
+  // log2(ax) = (ss + ...) * 2 / (3 * log(2)) = n + dp_h + z_h + z_l
+  var t = n;
+  var t1 = %_ConstructDouble(%_DoubleHi(((z_h + z_l) + dp_h) + t), 0);
+  var t2 = z_l - (((t1 - t) - dp_h) - z_h);
+
+  // t1 + t2 = log2(ax), sum up because we do not care about extra precision.
+  return t1 + t2;
+}
diff --git a/src/third_party/vtune/v8-vtune.h b/src/third_party/vtune/v8-vtune.h
index a7e5116..34da9cb 100644
--- a/src/third_party/vtune/v8-vtune.h
+++ b/src/third_party/vtune/v8-vtune.h
@@ -62,7 +62,7 @@
 
 namespace vTune {
 
-void InitializeVtuneForV8(v8::Isolate::CreateParams& params);
+v8::JitCodeEventHandler GetVtuneCodeEventHandler();
 
 }  // namespace vTune
 
diff --git a/src/third_party/vtune/vtune-jit.cc b/src/third_party/vtune/vtune-jit.cc
index e489d6e..b621cbc 100644
--- a/src/third_party/vtune/vtune-jit.cc
+++ b/src/third_party/vtune/vtune-jit.cc
@@ -271,10 +271,10 @@
 
 }  // namespace internal
 
-void InitializeVtuneForV8(v8::Isolate::CreateParams& params) {
+v8::JitCodeEventHandler GetVtuneCodeEventHandler() {
   v8::V8::SetFlagsFromString("--nocompact_code_space",
                              (int)strlen("--nocompact_code_space"));
-  params.code_event_handler = vTune::internal::VTUNEJITInterface::event_handler;
+  return vTune::internal::VTUNEJITInterface::event_handler;
 }
 
 }  // namespace vTune
diff --git a/src/token.cc b/src/token.cc
index 5dc67bb..db88271 100644
--- a/src/token.cc
+++ b/src/token.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "include/v8stdint.h"
+#include <stdint.h>
 #include "src/token.h"
 
 namespace v8 {
diff --git a/src/token.h b/src/token.h
index 9c719b8..de8ede9 100644
--- a/src/token.h
+++ b/src/token.h
@@ -6,6 +6,7 @@
 #define V8_TOKEN_H_
 
 #include "src/base/logging.h"
+#include "src/globals.h"
 
 namespace v8 {
 namespace internal {
@@ -162,7 +163,11 @@
   T(ILLEGAL, "ILLEGAL", 0)                                           \
                                                                      \
   /* Scanner-internal use only. */                                   \
-  T(WHITESPACE, NULL, 0)
+  T(WHITESPACE, NULL, 0)                                             \
+                                                                     \
+  /* ES6 Template Literals */                                        \
+  T(TEMPLATE_SPAN, NULL, 0)                                          \
+  T(TEMPLATE_TAIL, NULL, 0)
 
 
 class Token {
@@ -187,6 +192,24 @@
     return token_type[tok] == 'K';
   }
 
+  static bool IsIdentifier(Value tok, StrictMode strict_mode,
+                           bool is_generator) {
+    switch (tok) {
+      case IDENTIFIER:
+        return true;
+      case FUTURE_STRICT_RESERVED_WORD:
+      case LET:
+      case STATIC:
+        return strict_mode == SLOPPY;
+      case YIELD:
+        return !is_generator && strict_mode == SLOPPY;
+      default:
+        return false;
+    }
+    UNREACHABLE();
+    return false;
+  }
+
   static bool IsAssignmentOp(Value tok) {
     return INIT_VAR <= tok && tok <= ASSIGN_MOD;
   }
diff --git a/src/transitions-inl.h b/src/transitions-inl.h
index a16eb44..fd8eb8b 100644
--- a/src/transitions-inl.h
+++ b/src/transitions-inl.h
@@ -34,7 +34,7 @@
 
 
 bool TransitionArray::HasElementsTransition() {
-  return Search(GetHeap()->elements_transition_symbol()) != kNotFound;
+  return SearchSpecial(GetHeap()->elements_transition_symbol()) != kNotFound;
 }
 
 
@@ -134,13 +134,83 @@
 }
 
 
-int TransitionArray::Search(Name* name) {
+Object* TransitionArray::GetTargetValue(int transition_number) {
+  Map* map = GetTarget(transition_number);
+  return map->instance_descriptors()->GetValue(map->LastAdded());
+}
+
+
+int TransitionArray::SearchName(Name* name, int* out_insertion_index) {
   if (IsSimpleTransition()) {
     Name* key = GetKey(kSimpleTransitionIndex);
     if (key->Equals(name)) return kSimpleTransitionIndex;
+    if (out_insertion_index != NULL) {
+      *out_insertion_index = key->Hash() > name->Hash() ? 0 : 1;
+    }
     return kNotFound;
   }
-  return internal::Search<ALL_ENTRIES>(this, name);
+  return internal::Search<ALL_ENTRIES>(this, name, 0, out_insertion_index);
+}
+
+
+#ifdef DEBUG
+bool TransitionArray::IsSpecialTransition(Name* name) {
+  if (!name->IsSymbol()) return false;
+  Heap* heap = name->GetHeap();
+  return name == heap->nonextensible_symbol() ||
+         name == heap->sealed_symbol() || name == heap->frozen_symbol() ||
+         name == heap->elements_transition_symbol() ||
+         name == heap->observed_symbol();
+}
+#endif
+
+
+int TransitionArray::CompareKeys(Name* key1, uint32_t hash1, PropertyKind kind1,
+                                 PropertyAttributes attributes1, Name* key2,
+                                 uint32_t hash2, PropertyKind kind2,
+                                 PropertyAttributes attributes2) {
+  int cmp = CompareNames(key1, hash1, key2, hash2);
+  if (cmp != 0) return cmp;
+
+  return CompareDetails(kind1, attributes1, kind2, attributes2);
+}
+
+
+int TransitionArray::CompareNames(Name* key1, uint32_t hash1, Name* key2,
+                                  uint32_t hash2) {
+  if (key1 != key2) {
+    // In case of hash collisions key1 is always "less" than key2.
+    return hash1 <= hash2 ? -1 : 1;
+  }
+
+  return 0;
+}
+
+
+int TransitionArray::CompareDetails(PropertyKind kind1,
+                                    PropertyAttributes attributes1,
+                                    PropertyKind kind2,
+                                    PropertyAttributes attributes2) {
+  if (kind1 != kind2) {
+    return static_cast<int>(kind1) < static_cast<int>(kind2) ? -1 : 1;
+  }
+
+  if (attributes1 != attributes2) {
+    return static_cast<int>(attributes1) < static_cast<int>(attributes2) ? -1
+                                                                         : 1;
+  }
+
+  return 0;
+}
+
+
+PropertyDetails TransitionArray::GetTargetDetails(Name* name, Map* target) {
+  DCHECK(!IsSpecialTransition(name));
+  int descriptor = target->LastAdded();
+  DescriptorArray* descriptors = target->instance_descriptors();
+  // Transitions are allowed only for the last added property.
+  DCHECK(descriptors->GetKey(descriptor)->Equals(name));
+  return descriptors->GetDetails(descriptor);
 }
 
 
@@ -154,6 +224,15 @@
 }
 
 
+void TransitionArray::SetNumberOfTransitions(int number_of_transitions) {
+  if (IsFullTransitionArray()) {
+    DCHECK(number_of_transitions <= number_of_transitions_storage());
+    WRITE_FIELD(this, kTransitionLengthOffset,
+                Smi::FromInt(number_of_transitions));
+  }
+}
+
+
 #undef FIELD_ADDR
 #undef WRITE_FIELD
 #undef CONDITIONAL_WRITE_BARRIER
diff --git a/src/transitions.cc b/src/transitions.cc
index 96ed870..c8c63d7 100644
--- a/src/transitions.cc
+++ b/src/transitions.cc
@@ -13,10 +13,12 @@
 
 
 Handle<TransitionArray> TransitionArray::Allocate(Isolate* isolate,
-                                                  int number_of_transitions) {
-  Handle<FixedArray> array =
-      isolate->factory()->NewFixedArray(ToKeyIndex(number_of_transitions));
+                                                  int number_of_transitions,
+                                                  int slack) {
+  Handle<FixedArray> array = isolate->factory()->NewFixedArray(
+      LengthFor(number_of_transitions + slack));
   array->set(kPrototypeTransitionsIndex, Smi::FromInt(0));
+  array->set(kTransitionLengthIndex, Smi::FromInt(number_of_transitions));
   return Handle<TransitionArray>::cast(array);
 }
 
@@ -39,11 +41,6 @@
 }
 
 
-static bool InsertionPointFound(Name* key1, Name* key2) {
-  return key1->Hash() > key2->Hash();
-}
-
-
 Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map,
                                                  Handle<Name> name,
                                                  Handle<Map> target,
@@ -51,7 +48,7 @@
   Handle<TransitionArray> result;
   Isolate* isolate = name->GetIsolate();
 
-  if (flag == SIMPLE_TRANSITION) {
+  if (flag == SIMPLE_PROPERTY_TRANSITION) {
     result = AllocateSimple(isolate, target);
   } else {
     result = Allocate(isolate, 1);
@@ -74,6 +71,7 @@
   if (new_nof != nof) {
     DCHECK(new_nof == 0);
     result->Shrink(ToKeyIndex(0));
+    result->SetNumberOfTransitions(0);
   } else if (nof == 1) {
     result->NoIncrementalWriteBarrierCopyFrom(
         containing_map->transitions(), kSimpleTransitionIndex, 0);
@@ -85,21 +83,63 @@
 }
 
 
-Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map,
-                                                    Handle<Name> name,
-                                                    Handle<Map> target,
-                                                    SimpleTransitionFlag flag) {
+Handle<TransitionArray> TransitionArray::Insert(Handle<Map> map,
+                                                Handle<Name> name,
+                                                Handle<Map> target,
+                                                SimpleTransitionFlag flag) {
   if (!map->HasTransitionArray()) {
     return TransitionArray::NewWith(map, name, target, flag);
   }
 
   int number_of_transitions = map->transitions()->number_of_transitions();
-  int new_size = number_of_transitions;
+  int new_nof = number_of_transitions;
 
-  int insertion_index = map->transitions()->Search(*name);
-  if (insertion_index == kNotFound) ++new_size;
+  bool is_special_transition = flag == SPECIAL_TRANSITION;
+  DCHECK_EQ(is_special_transition, IsSpecialTransition(*name));
+  PropertyDetails details = is_special_transition
+                                ? PropertyDetails(NONE, FIELD, 0)
+                                : GetTargetDetails(*name, *target);
 
-  Handle<TransitionArray> result = Allocate(map->GetIsolate(), new_size);
+  int insertion_index = kNotFound;
+  int index =
+      is_special_transition
+          ? map->transitions()->SearchSpecial(Symbol::cast(*name),
+                                              &insertion_index)
+          : map->transitions()->Search(details.kind(), *name,
+                                       details.attributes(), &insertion_index);
+  if (index == kNotFound) {
+    ++new_nof;
+  } else {
+    insertion_index = index;
+  }
+  DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions);
+
+  CHECK(new_nof <= kMaxNumberOfTransitions);
+
+  if (new_nof <= map->transitions()->number_of_transitions_storage()) {
+    DisallowHeapAllocation no_gc;
+    TransitionArray* array = map->transitions();
+
+    if (index != kNotFound) {
+      array->SetTarget(index, *target);
+      return handle(array);
+    }
+
+    array->SetNumberOfTransitions(new_nof);
+    for (index = number_of_transitions; index > insertion_index; --index) {
+      Name* key = array->GetKey(index - 1);
+      array->SetKey(index, key);
+      array->SetTarget(index, array->GetTarget(index - 1));
+    }
+    array->SetKey(index, *name);
+    array->SetTarget(index, *target);
+    SLOW_DCHECK(array->IsSortedNoDuplicates());
+    return handle(array);
+  }
+
+  Handle<TransitionArray> result = Allocate(
+      map->GetIsolate(), new_nof,
+      Map::SlackForArraySize(number_of_transitions, kMaxNumberOfTransitions));
 
   // The map's transition array may grown smaller during the allocation above as
   // it was weakly traversed, though it is guaranteed not to disappear. Trim the
@@ -111,46 +151,75 @@
     DCHECK(array->number_of_transitions() < number_of_transitions);
 
     number_of_transitions = array->number_of_transitions();
-    new_size = number_of_transitions;
+    new_nof = number_of_transitions;
 
-    insertion_index = array->Search(*name);
-    if (insertion_index == kNotFound) ++new_size;
+    insertion_index = kNotFound;
+    index = is_special_transition ? map->transitions()->SearchSpecial(
+                                        Symbol::cast(*name), &insertion_index)
+                                  : map->transitions()->Search(
+                                        details.kind(), *name,
+                                        details.attributes(), &insertion_index);
+    if (index == kNotFound) {
+      ++new_nof;
+    } else {
+      insertion_index = index;
+    }
+    DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions);
 
-    result->Shrink(ToKeyIndex(new_size));
+    result->Shrink(ToKeyIndex(new_nof));
+    result->SetNumberOfTransitions(new_nof);
   }
 
   if (array->HasPrototypeTransitions()) {
     result->SetPrototypeTransitions(array->GetPrototypeTransitions());
   }
 
-  if (insertion_index != kNotFound) {
-    for (int i = 0; i < number_of_transitions; ++i) {
-      if (i != insertion_index) {
-        result->NoIncrementalWriteBarrierCopyFrom(array, i, i);
-      }
-    }
-    result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
-    result->set_back_pointer_storage(array->back_pointer_storage());
-    return result;
+  DCHECK_NE(kNotFound, insertion_index);
+  for (int i = 0; i < insertion_index; ++i) {
+    result->NoIncrementalWriteBarrierCopyFrom(array, i, i);
   }
-
-  insertion_index = 0;
-  for (; insertion_index < number_of_transitions; ++insertion_index) {
-    if (InsertionPointFound(array->GetKey(insertion_index), *name)) break;
-    result->NoIncrementalWriteBarrierCopyFrom(
-        array, insertion_index, insertion_index);
-  }
-
   result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
-
-  for (; insertion_index < number_of_transitions; ++insertion_index) {
-    result->NoIncrementalWriteBarrierCopyFrom(
-        array, insertion_index, insertion_index + 1);
+  for (int i = insertion_index; i < number_of_transitions; ++i) {
+    result->NoIncrementalWriteBarrierCopyFrom(array, i, i + 1);
   }
 
   result->set_back_pointer_storage(array->back_pointer_storage());
+  SLOW_DCHECK(result->IsSortedNoDuplicates());
   return result;
 }
 
 
+int TransitionArray::SearchDetails(int transition, PropertyKind kind,
+                                   PropertyAttributes attributes,
+                                   int* out_insertion_index) {
+  int nof_transitions = number_of_transitions();
+  DCHECK(transition < nof_transitions);
+  Name* key = GetKey(transition);
+  for (; transition < nof_transitions && GetKey(transition) == key;
+       transition++) {
+    Map* target = GetTarget(transition);
+    PropertyDetails target_details = GetTargetDetails(key, target);
+
+    int cmp = CompareDetails(kind, attributes, target_details.kind(),
+                             target_details.attributes());
+    if (cmp == 0) {
+      return transition;
+    } else if (cmp < 0) {
+      break;
+    }
+  }
+  if (out_insertion_index != NULL) *out_insertion_index = transition;
+  return kNotFound;
+}
+
+
+int TransitionArray::Search(PropertyKind kind, Name* name,
+                            PropertyAttributes attributes,
+                            int* out_insertion_index) {
+  int transition = SearchName(name, out_insertion_index);
+  if (transition == kNotFound) {
+    return kNotFound;
+  }
+  return SearchDetails(transition, kind, attributes, out_insertion_index);
+}
 } }  // namespace v8::internal
diff --git a/src/transitions.h b/src/transitions.h
index 21c02ac..999ad86 100644
--- a/src/transitions.h
+++ b/src/transitions.h
@@ -30,8 +30,9 @@
 // The full format is:
 // [0] Undefined or back pointer map
 // [1] Smi(0) or fixed array of prototype transitions
-// [2] First transition
-// [length() - kTransitionSize] Last transition
+// [2] Number of transitions
+// [3] First transition
+// [3 + number of transitions * kTransitionSize]: start of slack
 class TransitionArray: public FixedArray {
  public:
   // Accessors for fetching instance transition at transition number.
@@ -48,6 +49,7 @@
   inline void SetTarget(int transition_number, Map* target);
 
   inline PropertyDetails GetTargetDetails(int transition_number);
+  inline Object* GetTargetValue(int transition_number);
 
   inline bool HasElementsTransition();
 
@@ -66,10 +68,21 @@
   // Returns the number of transitions in the array.
   int number_of_transitions() {
     if (IsSimpleTransition()) return 1;
-    int len = length();
-    return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kTransitionSize;
+    if (length() <= kFirstIndex) return 0;
+    return Smi::cast(get(kTransitionLengthIndex))->value();
   }
 
+  int number_of_transitions_storage() {
+    if (IsSimpleTransition()) return 1;
+    if (length() <= kFirstIndex) return 0;
+    return (length() - kFirstIndex) / kTransitionSize;
+  }
+
+  int NumberOfSlackTransitions() {
+    return number_of_transitions_storage() - number_of_transitions();
+  }
+
+  inline void SetNumberOfTransitions(int number_of_transitions);
   inline int number_of_entries() { return number_of_transitions(); }
 
   // Creates a FullTransitionArray from a SimpleTransitionArray in
@@ -77,21 +90,30 @@
   static Handle<TransitionArray> ExtendToFullTransitionArray(
       Handle<Map> containing_map);
 
-  // Create a transition array, copying from the owning map if it already has
-  // one, otherwise creating a new one according to flag.
+  // Return a transition array, using the array from the owning map if it
+  // already has one (copying into a larger array if necessary), otherwise
+  // creating a new one according to flag.
   // TODO(verwaest): This should not cause an existing transition to be
   // overwritten.
-  static Handle<TransitionArray> CopyInsert(Handle<Map> map,
-                                            Handle<Name> name,
-                                            Handle<Map> target,
-                                            SimpleTransitionFlag flag);
+  static Handle<TransitionArray> Insert(Handle<Map> map, Handle<Name> name,
+                                        Handle<Map> target,
+                                        SimpleTransitionFlag flag);
+  // Search a  transition for a given kind, property name and attributes.
+  int Search(PropertyKind kind, Name* name, PropertyAttributes attributes,
+             int* out_insertion_index = NULL);
 
-  // Search a transition for a given property name.
-  inline int Search(Name* name);
+  // Search a non-property transition (like elements kind, observe or frozen
+  // transitions).
+  inline int SearchSpecial(Symbol* symbol, int* out_insertion_index = NULL) {
+    return SearchName(symbol, out_insertion_index);
+  }
+
+  static inline PropertyDetails GetTargetDetails(Name* name, Map* target);
 
   // Allocates a TransitionArray.
-  static Handle<TransitionArray> Allocate(
-      Isolate* isolate, int number_of_transitions);
+  static Handle<TransitionArray> Allocate(Isolate* isolate,
+                                          int number_of_transitions,
+                                          int slack = 0);
 
   bool IsSimpleTransition() {
     return length() == kSimpleTransitionSize &&
@@ -119,7 +141,8 @@
 
   // Layout for full transition arrays.
   static const int kPrototypeTransitionsIndex = 1;
-  static const int kFirstIndex = 2;
+  static const int kTransitionLengthIndex = 2;
+  static const int kFirstIndex = 3;
 
   // Layout for simple transition arrays.
   static const int kSimpleTransitionTarget = 1;
@@ -132,27 +155,42 @@
   // Layout for the full transition array header.
   static const int kPrototypeTransitionsOffset = kBackPointerStorageOffset +
                                                  kPointerSize;
+  static const int kTransitionLengthOffset =
+      kPrototypeTransitionsOffset + kPointerSize;
 
   // Layout of map transition entries in full transition arrays.
   static const int kTransitionKey = 0;
   static const int kTransitionTarget = 1;
   static const int kTransitionSize = 2;
 
-#ifdef OBJECT_PRINT
+#if defined(DEBUG) || defined(OBJECT_PRINT)
+  // For our gdb macros, we should perhaps change these in the future.
+  void Print();
+
   // Print all the transitions.
-  void PrintTransitions(OStream& os);  // NOLINT
+  void PrintTransitions(std::ostream& os, bool print_header = true);  // NOLINT
 #endif
 
 #ifdef DEBUG
   bool IsSortedNoDuplicates(int valid_entries = -1);
   bool IsConsistentWithBackPointers(Map* current_map);
   bool IsEqualTo(TransitionArray* other);
+
+  // Returns true for a non-property transitions like elements kind, observed
+  // or frozen transitions.
+  static inline bool IsSpecialTransition(Name* name);
 #endif
 
   // The maximum number of transitions we want in a transition array (should
   // fit in a page).
   static const int kMaxNumberOfTransitions = 1024 + 512;
 
+  // Returns the fixed array length required to hold number_of_transitions
+  // transitions.
+  static int LengthFor(int number_of_transitions) {
+    return ToKeyIndex(number_of_transitions);
+  }
+
  private:
   // Conversion from transition number to array indices.
   static int ToKeyIndex(int transition_number) {
@@ -176,6 +214,30 @@
                                          Handle<Map> target,
                                          SimpleTransitionFlag flag);
 
+  // Search a first transition for a given property name.
+  inline int SearchName(Name* name, int* out_insertion_index = NULL);
+  int SearchDetails(int transition, PropertyKind kind,
+                    PropertyAttributes attributes, int* out_insertion_index);
+
+  // Compares two tuples <key, kind, attributes>, returns -1 if
+  // tuple1 is "less" than tuple2, 0 if tuple1 equal to tuple2 and 1 otherwise.
+  static inline int CompareKeys(Name* key1, uint32_t hash1, PropertyKind kind1,
+                                PropertyAttributes attributes1, Name* key2,
+                                uint32_t hash2, PropertyKind kind2,
+                                PropertyAttributes attributes2);
+
+  // Compares keys, returns -1 if key1 is "less" than key2,
+  // 0 if key1 equal to key2 and 1 otherwise.
+  static inline int CompareNames(Name* key1, uint32_t hash1, Name* key2,
+                                 uint32_t hash2);
+
+  // Compares two details, returns -1 if details1 is "less" than details2,
+  // 0 if details1 equal to details2 and 1 otherwise.
+  static inline int CompareDetails(PropertyKind kind1,
+                                   PropertyAttributes attributes1,
+                                   PropertyKind kind2,
+                                   PropertyAttributes attributes2);
+
   inline void NoIncrementalWriteBarrierSet(int transition_number,
                                            Name* key,
                                            Map* target);
diff --git a/src/type-feedback-vector-inl.h b/src/type-feedback-vector-inl.h
index 43e768e..612004e 100644
--- a/src/type-feedback-vector-inl.h
+++ b/src/type-feedback-vector-inl.h
@@ -10,6 +10,11 @@
 namespace v8 {
 namespace internal {
 
+int TypeFeedbackVector::ic_metadata_length() const {
+  return FLAG_vector_ics ? VectorICComputer::word_count(ICSlots()) : 0;
+}
+
+
 Handle<Object> TypeFeedbackVector::UninitializedSentinel(Isolate* isolate) {
   return isolate->factory()->uninitialized_symbol();
 }
@@ -21,7 +26,7 @@
 
 
 Handle<Object> TypeFeedbackVector::PremonomorphicSentinel(Isolate* isolate) {
-  return isolate->factory()->megamorphic_symbol();
+  return isolate->factory()->premonomorphic_symbol();
 }
 
 
diff --git a/src/type-feedback-vector.cc b/src/type-feedback-vector.cc
index a3fe070..c51d987 100644
--- a/src/type-feedback-vector.cc
+++ b/src/type-feedback-vector.cc
@@ -4,6 +4,8 @@
 
 #include "src/v8.h"
 
+#include "src/ic/ic.h"
+#include "src/ic/ic-state.h"
 #include "src/objects.h"
 #include "src/type-feedback-vector-inl.h"
 
@@ -11,6 +13,114 @@
 namespace internal {
 
 // static
+TypeFeedbackVector::VectorICKind TypeFeedbackVector::FromCodeKind(
+    Code::Kind kind) {
+  switch (kind) {
+    case Code::CALL_IC:
+      return KindCallIC;
+    case Code::LOAD_IC:
+      return KindLoadIC;
+    case Code::KEYED_LOAD_IC:
+      return KindKeyedLoadIC;
+    default:
+      // Shouldn't get here.
+      UNREACHABLE();
+  }
+
+  return KindUnused;
+}
+
+
+// static
+Code::Kind TypeFeedbackVector::FromVectorICKind(VectorICKind kind) {
+  switch (kind) {
+    case KindCallIC:
+      return Code::CALL_IC;
+    case KindLoadIC:
+      return Code::LOAD_IC;
+    case KindKeyedLoadIC:
+      return Code::KEYED_LOAD_IC;
+    case KindUnused:
+      break;
+  }
+  // Sentinel for no information.
+  return Code::NUMBER_OF_KINDS;
+}
+
+
+Code::Kind TypeFeedbackVector::GetKind(FeedbackVectorICSlot slot) const {
+  if (!FLAG_vector_ics) {
+    // We only have CALL_ICs
+    return Code::CALL_IC;
+  }
+
+  int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
+  int data = Smi::cast(get(index))->value();
+  VectorICKind b = VectorICComputer::decode(data, slot.ToInt());
+  return FromVectorICKind(b);
+}
+
+
+void TypeFeedbackVector::SetKind(FeedbackVectorICSlot slot, Code::Kind kind) {
+  if (!FLAG_vector_ics) {
+    // Nothing to do if we only have CALL_ICs
+    return;
+  }
+
+  VectorICKind b = FromCodeKind(kind);
+  int index = VectorICComputer::index(kReservedIndexCount, slot.ToInt());
+  int data = Smi::cast(get(index))->value();
+  int new_data = VectorICComputer::encode(data, slot.ToInt(), b);
+  set(index, Smi::FromInt(new_data));
+}
+
+
+// static
+Handle<TypeFeedbackVector> TypeFeedbackVector::Allocate(
+    Isolate* isolate, const FeedbackVectorSpec& spec) {
+  const int slot_count = spec.slots();
+  const int ic_slot_count = spec.ic_slots();
+  const int index_count =
+      FLAG_vector_ics ? VectorICComputer::word_count(ic_slot_count) : 0;
+  const int length =
+      slot_count + ic_slot_count + index_count + kReservedIndexCount;
+  if (length == kReservedIndexCount) {
+    return Handle<TypeFeedbackVector>::cast(
+        isolate->factory()->empty_fixed_array());
+  }
+
+  Handle<FixedArray> array = isolate->factory()->NewFixedArray(length, TENURED);
+  if (ic_slot_count > 0) {
+    array->set(kFirstICSlotIndex,
+               Smi::FromInt(slot_count + index_count + kReservedIndexCount));
+  } else {
+    array->set(kFirstICSlotIndex, Smi::FromInt(length));
+  }
+  array->set(kWithTypesIndex, Smi::FromInt(0));
+  array->set(kGenericCountIndex, Smi::FromInt(0));
+  // Fill the indexes with zeros.
+  for (int i = 0; i < index_count; i++) {
+    array->set(kReservedIndexCount + i, Smi::FromInt(0));
+  }
+
+  // Ensure we can skip the write barrier
+  Handle<Object> uninitialized_sentinel = UninitializedSentinel(isolate);
+  DCHECK_EQ(isolate->heap()->uninitialized_symbol(), *uninitialized_sentinel);
+  for (int i = kReservedIndexCount + index_count; i < length; i++) {
+    array->set(i, *uninitialized_sentinel, SKIP_WRITE_BARRIER);
+  }
+
+  Handle<TypeFeedbackVector> vector = Handle<TypeFeedbackVector>::cast(array);
+  if (FLAG_vector_ics) {
+    for (int i = 0; i < ic_slot_count; i++) {
+      vector->SetKind(FeedbackVectorICSlot(i), spec.GetKind(i));
+    }
+  }
+  return vector;
+}
+
+
+// static
 Handle<TypeFeedbackVector> TypeFeedbackVector::Copy(
     Isolate* isolate, Handle<TypeFeedbackVector> vector) {
   Handle<TypeFeedbackVector> result;
@@ -18,5 +128,389 @@
       isolate->factory()->CopyFixedArray(Handle<FixedArray>::cast(vector)));
   return result;
 }
+
+
+// This logic is copied from
+// StaticMarkingVisitor<StaticVisitor>::VisitCodeTarget.
+// TODO(mvstanton): with weak handling of all vector ics, this logic should
+// actually be completely eliminated and we no longer need to clear the
+// vector ICs.
+static bool ClearLogic(Heap* heap, int ic_age, Code::Kind kind,
+                       InlineCacheState state) {
+  if (FLAG_cleanup_code_caches_at_gc &&
+      (kind == Code::CALL_IC || heap->flush_monomorphic_ics() ||
+       // TODO(mvstanton): is this ic_age granular enough? it comes from
+       // the SharedFunctionInfo which may change on a different schedule
+       // than ic targets.
+       // ic_age != heap->global_ic_age() ||
+       // is_invalidated_weak_stub ||
+       heap->isolate()->serializer_enabled())) {
+    return true;
+  }
+  return false;
+}
+
+
+void TypeFeedbackVector::ClearSlots(SharedFunctionInfo* shared) {
+  int slots = Slots();
+  Isolate* isolate = GetIsolate();
+  Object* uninitialized_sentinel =
+      TypeFeedbackVector::RawUninitializedSentinel(isolate->heap());
+
+  for (int i = 0; i < slots; i++) {
+    FeedbackVectorSlot slot(i);
+    Object* obj = Get(slot);
+    if (obj->IsHeapObject()) {
+      InstanceType instance_type =
+          HeapObject::cast(obj)->map()->instance_type();
+      // AllocationSites are exempt from clearing. They don't store Maps
+      // or Code pointers which can cause memory leaks if not cleared
+      // regularly.
+      if (instance_type != ALLOCATION_SITE_TYPE) {
+        Set(slot, uninitialized_sentinel, SKIP_WRITE_BARRIER);
+      }
+    }
+  }
+
+  slots = ICSlots();
+  if (slots == 0) return;
+
+  // Now clear vector-based ICs.
+  // Try and pass the containing code (the "host").
+  Heap* heap = isolate->heap();
+  Code* host = shared->code();
+  // I'm not sure yet if this ic age is the correct one.
+  int ic_age = shared->ic_age();
+  for (int i = 0; i < slots; i++) {
+    FeedbackVectorICSlot slot(i);
+    Object* obj = Get(slot);
+    if (obj != uninitialized_sentinel) {
+      Code::Kind kind = GetKind(slot);
+      if (kind == Code::CALL_IC) {
+        CallICNexus nexus(this, slot);
+        if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) {
+          nexus.Clear(host);
+        }
+      } else if (kind == Code::LOAD_IC) {
+        LoadICNexus nexus(this, slot);
+        if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) {
+          nexus.Clear(host);
+        }
+      } else if (kind == Code::KEYED_LOAD_IC) {
+        KeyedLoadICNexus nexus(this, slot);
+        if (ClearLogic(heap, ic_age, kind, nexus.StateFromFeedback())) {
+          nexus.Clear(host);
+        }
+      }
+    }
+  }
+}
+
+
+Handle<FixedArray> FeedbackNexus::EnsureArrayOfSize(int length) {
+  Isolate* isolate = GetIsolate();
+  Handle<Object> feedback = handle(GetFeedback(), isolate);
+  if (!feedback->IsFixedArray() ||
+      FixedArray::cast(*feedback)->length() != length) {
+    Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
+    SetFeedback(*array);
+    return array;
+  }
+  return Handle<FixedArray>::cast(feedback);
+}
+
+
+void FeedbackNexus::InstallHandlers(int start_index, TypeHandleList* types,
+                                    CodeHandleList* handlers) {
+  Isolate* isolate = GetIsolate();
+  Handle<FixedArray> array = handle(FixedArray::cast(GetFeedback()), isolate);
+  int receiver_count = types->length();
+  for (int current = 0; current < receiver_count; ++current) {
+    Handle<HeapType> type = types->at(current);
+    Handle<Map> map = IC::TypeToMap(*type, isolate);
+    Handle<WeakCell> cell = Map::WeakCellForMap(map);
+    array->set(start_index + (current * 2), *cell);
+    array->set(start_index + (current * 2 + 1), *handlers->at(current));
+  }
+}
+
+
+InlineCacheState LoadICNexus::StateFromFeedback() const {
+  Isolate* isolate = GetIsolate();
+  Object* feedback = GetFeedback();
+  if (feedback == *vector()->UninitializedSentinel(isolate)) {
+    return UNINITIALIZED;
+  } else if (feedback == *vector()->MegamorphicSentinel(isolate)) {
+    return MEGAMORPHIC;
+  } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) {
+    return PREMONOMORPHIC;
+  } else if (feedback->IsFixedArray()) {
+    // Determine state purely by our structure, don't check if the maps are
+    // cleared.
+    FixedArray* array = FixedArray::cast(feedback);
+    int length = array->length();
+    DCHECK(length >= 2);
+    return length == 2 ? MONOMORPHIC : POLYMORPHIC;
+  }
+
+  return UNINITIALIZED;
+}
+
+
+InlineCacheState KeyedLoadICNexus::StateFromFeedback() const {
+  Isolate* isolate = GetIsolate();
+  Object* feedback = GetFeedback();
+  if (feedback == *vector()->UninitializedSentinel(isolate)) {
+    return UNINITIALIZED;
+  } else if (feedback == *vector()->PremonomorphicSentinel(isolate)) {
+    return PREMONOMORPHIC;
+  } else if (feedback == *vector()->GenericSentinel(isolate)) {
+    return GENERIC;
+  } else if (feedback->IsFixedArray()) {
+    // Determine state purely by our structure, don't check if the maps are
+    // cleared.
+    FixedArray* array = FixedArray::cast(feedback);
+    int length = array->length();
+    DCHECK(length >= 3);
+    return length == 3 ? MONOMORPHIC : POLYMORPHIC;
+  }
+
+  return UNINITIALIZED;
+}
+
+
+InlineCacheState CallICNexus::StateFromFeedback() const {
+  Isolate* isolate = GetIsolate();
+  Object* feedback = GetFeedback();
+
+  if (feedback == *vector()->MegamorphicSentinel(isolate)) {
+    return GENERIC;
+  } else if (feedback->IsAllocationSite() || feedback->IsJSFunction()) {
+    return MONOMORPHIC;
+  }
+
+  CHECK(feedback == *vector()->UninitializedSentinel(isolate));
+  return UNINITIALIZED;
+}
+
+
+void CallICNexus::Clear(Code* host) { CallIC::Clear(GetIsolate(), host, this); }
+
+
+void CallICNexus::ConfigureGeneric() {
+  SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
+}
+
+
+void CallICNexus::ConfigureMonomorphicArray() {
+  Object* feedback = GetFeedback();
+  if (!feedback->IsAllocationSite()) {
+    Handle<AllocationSite> new_site =
+        GetIsolate()->factory()->NewAllocationSite();
+    SetFeedback(*new_site);
+  }
+}
+
+
+void CallICNexus::ConfigureUninitialized() {
+  SetFeedback(*vector()->UninitializedSentinel(GetIsolate()),
+              SKIP_WRITE_BARRIER);
+}
+
+
+void CallICNexus::ConfigureMonomorphic(Handle<JSFunction> function) {
+  SetFeedback(*function);
+}
+
+
+void KeyedLoadICNexus::ConfigureGeneric() {
+  SetFeedback(*vector()->GenericSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
+}
+
+
+void LoadICNexus::ConfigureMegamorphic() {
+  SetFeedback(*vector()->MegamorphicSentinel(GetIsolate()), SKIP_WRITE_BARRIER);
+}
+
+
+void LoadICNexus::ConfigurePremonomorphic() {
+  SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()),
+              SKIP_WRITE_BARRIER);
+}
+
+
+void KeyedLoadICNexus::ConfigurePremonomorphic() {
+  SetFeedback(*vector()->PremonomorphicSentinel(GetIsolate()),
+              SKIP_WRITE_BARRIER);
+}
+
+
+void LoadICNexus::ConfigureMonomorphic(Handle<HeapType> type,
+                                       Handle<Code> handler) {
+  Handle<FixedArray> array = EnsureArrayOfSize(2);
+  Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate());
+  Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
+  array->set(0, *cell);
+  array->set(1, *handler);
+}
+
+
+void KeyedLoadICNexus::ConfigureMonomorphic(Handle<Name> name,
+                                            Handle<HeapType> type,
+                                            Handle<Code> handler) {
+  Handle<FixedArray> array = EnsureArrayOfSize(3);
+  Handle<Map> receiver_map = IC::TypeToMap(*type, GetIsolate());
+  if (name.is_null()) {
+    array->set(0, Smi::FromInt(0));
+  } else {
+    array->set(0, *name);
+  }
+  Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
+  array->set(1, *cell);
+  array->set(2, *handler);
+}
+
+
+void LoadICNexus::ConfigurePolymorphic(TypeHandleList* types,
+                                       CodeHandleList* handlers) {
+  int receiver_count = types->length();
+  EnsureArrayOfSize(receiver_count * 2);
+  InstallHandlers(0, types, handlers);
+}
+
+
+void KeyedLoadICNexus::ConfigurePolymorphic(Handle<Name> name,
+                                            TypeHandleList* types,
+                                            CodeHandleList* handlers) {
+  int receiver_count = types->length();
+  Handle<FixedArray> array = EnsureArrayOfSize(1 + receiver_count * 2);
+  if (name.is_null()) {
+    array->set(0, Smi::FromInt(0));
+  } else {
+    array->set(0, *name);
+  }
+  InstallHandlers(1, types, handlers);
+}
+
+
+int FeedbackNexus::ExtractMaps(int start_index, MapHandleList* maps) const {
+  Isolate* isolate = GetIsolate();
+  Object* feedback = GetFeedback();
+  if (feedback->IsFixedArray()) {
+    int found = 0;
+    FixedArray* array = FixedArray::cast(feedback);
+    // The array should be of the form [<optional name>], then
+    // [map, handler, map, handler, ... ]
+    DCHECK(array->length() >= (2 + start_index));
+    for (int i = start_index; i < array->length(); i += 2) {
+      WeakCell* cell = WeakCell::cast(array->get(i));
+      if (!cell->cleared()) {
+        Map* map = Map::cast(cell->value());
+        maps->Add(handle(map, isolate));
+        found++;
+      }
+    }
+    return found;
+  }
+
+  return 0;
+}
+
+
+MaybeHandle<Code> FeedbackNexus::FindHandlerForMap(int start_index,
+                                                   Handle<Map> map) const {
+  Object* feedback = GetFeedback();
+  if (feedback->IsFixedArray()) {
+    FixedArray* array = FixedArray::cast(feedback);
+    for (int i = start_index; i < array->length(); i += 2) {
+      WeakCell* cell = WeakCell::cast(array->get(i));
+      if (!cell->cleared()) {
+        Map* array_map = Map::cast(cell->value());
+        if (array_map == *map) {
+          Code* code = Code::cast(array->get(i + 1));
+          DCHECK(code->kind() == Code::HANDLER);
+          return handle(code);
+        }
+      }
+    }
+  }
+
+  return MaybeHandle<Code>();
+}
+
+
+bool FeedbackNexus::FindHandlers(int start_index, CodeHandleList* code_list,
+                                 int length) const {
+  Object* feedback = GetFeedback();
+  int count = 0;
+  if (feedback->IsFixedArray()) {
+    FixedArray* array = FixedArray::cast(feedback);
+    // The array should be of the form [<optional name>], then
+    // [map, handler, map, handler, ... ]. Be sure to skip handlers whose maps
+    // have been cleared.
+    DCHECK(array->length() >= (2 + start_index));
+    for (int i = start_index; i < array->length(); i += 2) {
+      WeakCell* cell = WeakCell::cast(array->get(i));
+      if (!cell->cleared()) {
+        Code* code = Code::cast(array->get(i + 1));
+        DCHECK(code->kind() == Code::HANDLER);
+        code_list->Add(handle(code));
+        count++;
+      }
+    }
+  }
+  return count == length;
+}
+
+
+int LoadICNexus::ExtractMaps(MapHandleList* maps) const {
+  return FeedbackNexus::ExtractMaps(0, maps);
+}
+
+
+void LoadICNexus::Clear(Code* host) { LoadIC::Clear(GetIsolate(), host, this); }
+
+
+void KeyedLoadICNexus::Clear(Code* host) {
+  KeyedLoadIC::Clear(GetIsolate(), host, this);
+}
+
+
+int KeyedLoadICNexus::ExtractMaps(MapHandleList* maps) const {
+  return FeedbackNexus::ExtractMaps(1, maps);
+}
+
+
+MaybeHandle<Code> LoadICNexus::FindHandlerForMap(Handle<Map> map) const {
+  return FeedbackNexus::FindHandlerForMap(0, map);
+}
+
+
+MaybeHandle<Code> KeyedLoadICNexus::FindHandlerForMap(Handle<Map> map) const {
+  return FeedbackNexus::FindHandlerForMap(1, map);
+}
+
+
+bool LoadICNexus::FindHandlers(CodeHandleList* code_list, int length) const {
+  return FeedbackNexus::FindHandlers(0, code_list, length);
+}
+
+
+bool KeyedLoadICNexus::FindHandlers(CodeHandleList* code_list,
+                                    int length) const {
+  return FeedbackNexus::FindHandlers(1, code_list, length);
+}
+
+
+Name* KeyedLoadICNexus::FindFirstName() const {
+  Object* feedback = GetFeedback();
+  if (feedback->IsFixedArray()) {
+    FixedArray* array = FixedArray::cast(feedback);
+    DCHECK(array->length() >= 3);
+    Object* name = array->get(0);
+    if (name->IsName()) return Name::cast(name);
+  }
+  return NULL;
+}
 }
 }  // namespace v8::internal
diff --git a/src/type-feedback-vector.h b/src/type-feedback-vector.h
index b6fadba..864f336 100644
--- a/src/type-feedback-vector.h
+++ b/src/type-feedback-vector.h
@@ -5,6 +5,8 @@
 #ifndef V8_TYPE_FEEDBACK_VECTOR_H_
 #define V8_TYPE_FEEDBACK_VECTOR_H_
 
+#include <vector>
+
 #include "src/checks.h"
 #include "src/elements-kind.h"
 #include "src/heap/heap.h"
@@ -14,6 +16,51 @@
 namespace v8 {
 namespace internal {
 
+class FeedbackVectorSpec {
+ public:
+  FeedbackVectorSpec() : slots_(0), ic_slots_(0) {}
+  FeedbackVectorSpec(int slots, int ic_slots)
+      : slots_(slots), ic_slots_(ic_slots) {
+    if (FLAG_vector_ics) ic_slot_kinds_.resize(ic_slots);
+  }
+
+  int slots() const { return slots_; }
+  void increase_slots(int count) { slots_ += count; }
+
+  int ic_slots() const { return ic_slots_; }
+  void increase_ic_slots(int count) {
+    ic_slots_ += count;
+    if (FLAG_vector_ics) ic_slot_kinds_.resize(ic_slots_);
+  }
+
+  void SetKind(int ic_slot, Code::Kind kind) {
+    DCHECK(FLAG_vector_ics);
+    ic_slot_kinds_[ic_slot] = kind;
+  }
+
+  Code::Kind GetKind(int ic_slot) const {
+    DCHECK(FLAG_vector_ics);
+    return static_cast<Code::Kind>(ic_slot_kinds_.at(ic_slot));
+  }
+
+ private:
+  int slots_;
+  int ic_slots_;
+  std::vector<unsigned char> ic_slot_kinds_;
+};
+
+
+// The shape of the TypeFeedbackVector is an array with:
+// 0: first_ic_slot_index (== length() if no ic slots are present)
+// 1: ics_with_types
+// 2: ics_with_generic_info
+// 3: type information for ic slots, if any
+// ...
+// N: first feedback slot (N >= 3)
+// ...
+// [<first_ic_slot_index>: feedback slot]
+// ...to length() - 1
+//
 class TypeFeedbackVector : public FixedArray {
  public:
   // Casting.
@@ -22,9 +69,103 @@
     return reinterpret_cast<TypeFeedbackVector*>(obj);
   }
 
+  static const int kReservedIndexCount = 3;
+  static const int kFirstICSlotIndex = 0;
+  static const int kWithTypesIndex = 1;
+  static const int kGenericCountIndex = 2;
+
+  int first_ic_slot_index() const {
+    DCHECK(length() >= kReservedIndexCount);
+    return Smi::cast(get(kFirstICSlotIndex))->value();
+  }
+
+  int ic_with_type_info_count() {
+    return length() > 0 ? Smi::cast(get(kWithTypesIndex))->value() : 0;
+  }
+
+  void change_ic_with_type_info_count(int delta) {
+    if (delta == 0) return;
+    int value = ic_with_type_info_count() + delta;
+    // Could go negative because of the debugger.
+    if (value >= 0) {
+      set(kWithTypesIndex, Smi::FromInt(value));
+    }
+  }
+
+  int ic_generic_count() {
+    return length() > 0 ? Smi::cast(get(kGenericCountIndex))->value() : 0;
+  }
+
+  void change_ic_generic_count(int delta) {
+    if (delta == 0) return;
+    int value = ic_generic_count() + delta;
+    if (value >= 0) {
+      set(kGenericCountIndex, Smi::FromInt(value));
+    }
+  }
+
+  inline int ic_metadata_length() const;
+
+  int Slots() const {
+    if (length() == 0) return 0;
+    return Max(
+        0, first_ic_slot_index() - ic_metadata_length() - kReservedIndexCount);
+  }
+
+  int ICSlots() const {
+    if (length() == 0) return 0;
+    return length() - first_ic_slot_index();
+  }
+
+  // Conversion from a slot or ic slot to an integer index to the underlying
+  // array.
+  int GetIndex(FeedbackVectorSlot slot) const {
+    return kReservedIndexCount + ic_metadata_length() + slot.ToInt();
+  }
+
+  int GetIndex(FeedbackVectorICSlot slot) const {
+    int first_ic_slot = first_ic_slot_index();
+    DCHECK(slot.ToInt() < ICSlots());
+    return first_ic_slot + slot.ToInt();
+  }
+
+  // Conversion from an integer index to either a slot or an ic slot. The caller
+  // should know what kind she expects.
+  FeedbackVectorSlot ToSlot(int index) const {
+    DCHECK(index >= kReservedIndexCount && index < first_ic_slot_index());
+    return FeedbackVectorSlot(index - ic_metadata_length() -
+                              kReservedIndexCount);
+  }
+
+  FeedbackVectorICSlot ToICSlot(int index) const {
+    DCHECK(index >= first_ic_slot_index() && index < length());
+    return FeedbackVectorICSlot(index - first_ic_slot_index());
+  }
+
+  Object* Get(FeedbackVectorSlot slot) const { return get(GetIndex(slot)); }
+  void Set(FeedbackVectorSlot slot, Object* value,
+           WriteBarrierMode mode = UPDATE_WRITE_BARRIER) {
+    set(GetIndex(slot), value, mode);
+  }
+
+  Object* Get(FeedbackVectorICSlot slot) const { return get(GetIndex(slot)); }
+  void Set(FeedbackVectorICSlot slot, Object* value,
+           WriteBarrierMode mode = UPDATE_WRITE_BARRIER) {
+    set(GetIndex(slot), value, mode);
+  }
+
+  // IC slots need metadata to recognize the type of IC.
+  Code::Kind GetKind(FeedbackVectorICSlot slot) const;
+
+  static Handle<TypeFeedbackVector> Allocate(Isolate* isolate,
+                                             const FeedbackVectorSpec& spec);
+
   static Handle<TypeFeedbackVector> Copy(Isolate* isolate,
                                          Handle<TypeFeedbackVector> vector);
 
+  // Clears the vector slots and the vector ic slots.
+  void ClearSlots(SharedFunctionInfo* shared);
+
   // The object that indicates an uninitialized cache.
   static inline Handle<Object> UninitializedSentinel(Isolate* isolate);
 
@@ -47,8 +188,182 @@
   static inline Object* RawUninitializedSentinel(Heap* heap);
 
  private:
+  enum VectorICKind {
+    KindUnused = 0x0,
+    KindCallIC = 0x1,
+    KindLoadIC = 0x2,
+    KindKeyedLoadIC = 0x3
+  };
+
+  static const int kVectorICKindBits = 2;
+  static VectorICKind FromCodeKind(Code::Kind kind);
+  static Code::Kind FromVectorICKind(VectorICKind kind);
+  void SetKind(FeedbackVectorICSlot slot, Code::Kind kind);
+
+  typedef BitSetComputer<VectorICKind, kVectorICKindBits, kSmiValueSize,
+                         uint32_t> VectorICComputer;
+
   DISALLOW_IMPLICIT_CONSTRUCTORS(TypeFeedbackVector);
 };
+
+
+// A FeedbackNexus is the combination of a TypeFeedbackVector and a slot.
+// Derived classes customize the update and retrieval of feedback.
+class FeedbackNexus {
+ public:
+  FeedbackNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
+      : vector_handle_(vector), vector_(NULL), slot_(slot) {}
+  FeedbackNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
+      : vector_(vector), slot_(slot) {}
+  virtual ~FeedbackNexus() {}
+
+  Handle<TypeFeedbackVector> vector_handle() const {
+    DCHECK(vector_ == NULL);
+    return vector_handle_;
+  }
+  TypeFeedbackVector* vector() const {
+    return vector_handle_.is_null() ? vector_ : *vector_handle_;
+  }
+  FeedbackVectorICSlot slot() const { return slot_; }
+
+  InlineCacheState ic_state() const { return StateFromFeedback(); }
+  Map* FindFirstMap() const {
+    MapHandleList maps;
+    ExtractMaps(&maps);
+    if (maps.length() > 0) return *maps.at(0);
+    return NULL;
+  }
+
+  // TODO(mvstanton): remove FindAllMaps, it didn't survive a code review.
+  void FindAllMaps(MapHandleList* maps) const { ExtractMaps(maps); }
+
+  virtual InlineCacheState StateFromFeedback() const = 0;
+  virtual int ExtractMaps(MapHandleList* maps) const = 0;
+  virtual MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const = 0;
+  virtual bool FindHandlers(CodeHandleList* code_list, int length = -1) const {
+    return length == 0;
+  }
+  virtual Name* FindFirstName() const { return NULL; }
+
+  Object* GetFeedback() const { return vector()->Get(slot()); }
+
+ protected:
+  Isolate* GetIsolate() const { return vector()->GetIsolate(); }
+
+  void SetFeedback(Object* feedback,
+                   WriteBarrierMode mode = UPDATE_WRITE_BARRIER) {
+    vector()->Set(slot(), feedback, mode);
+  }
+
+  Handle<FixedArray> EnsureArrayOfSize(int length);
+  void InstallHandlers(int start_index, TypeHandleList* types,
+                       CodeHandleList* handlers);
+  int ExtractMaps(int start_index, MapHandleList* maps) const;
+  MaybeHandle<Code> FindHandlerForMap(int start_index, Handle<Map> map) const;
+  bool FindHandlers(int start_index, CodeHandleList* code_list,
+                    int length) const;
+
+ private:
+  // The reason for having a vector handle and a raw pointer is that we can and
+  // should use handles during IC miss, but not during GC when we clear ICs. If
+  // you have a handle to the vector that is better because more operations can
+  // be done, like allocation.
+  Handle<TypeFeedbackVector> vector_handle_;
+  TypeFeedbackVector* vector_;
+  FeedbackVectorICSlot slot_;
+};
+
+
+class CallICNexus : public FeedbackNexus {
+ public:
+  CallICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
+      : FeedbackNexus(vector, slot) {
+    DCHECK(vector->GetKind(slot) == Code::CALL_IC);
+  }
+  CallICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
+      : FeedbackNexus(vector, slot) {
+    DCHECK(vector->GetKind(slot) == Code::CALL_IC);
+  }
+
+  void Clear(Code* host);
+
+  void ConfigureUninitialized();
+  void ConfigureGeneric();
+  void ConfigureMonomorphicArray();
+  void ConfigureMonomorphic(Handle<JSFunction> function);
+
+  InlineCacheState StateFromFeedback() const OVERRIDE;
+
+  int ExtractMaps(MapHandleList* maps) const OVERRIDE {
+    // CallICs don't record map feedback.
+    return 0;
+  }
+  MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE {
+    return MaybeHandle<Code>();
+  }
+  virtual bool FindHandlers(CodeHandleList* code_list,
+                            int length = -1) const OVERRIDE {
+    return length == 0;
+  }
+};
+
+
+class LoadICNexus : public FeedbackNexus {
+ public:
+  LoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
+      : FeedbackNexus(vector, slot) {
+    DCHECK(vector->GetKind(slot) == Code::LOAD_IC);
+  }
+  LoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
+      : FeedbackNexus(vector, slot) {
+    DCHECK(vector->GetKind(slot) == Code::LOAD_IC);
+  }
+
+  void Clear(Code* host);
+
+  void ConfigureMegamorphic();
+  void ConfigurePremonomorphic();
+  void ConfigureMonomorphic(Handle<HeapType> type, Handle<Code> handler);
+
+  void ConfigurePolymorphic(TypeHandleList* types, CodeHandleList* handlers);
+
+  InlineCacheState StateFromFeedback() const OVERRIDE;
+  int ExtractMaps(MapHandleList* maps) const OVERRIDE;
+  MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE;
+  virtual bool FindHandlers(CodeHandleList* code_list,
+                            int length = -1) const OVERRIDE;
+};
+
+
+class KeyedLoadICNexus : public FeedbackNexus {
+ public:
+  KeyedLoadICNexus(Handle<TypeFeedbackVector> vector, FeedbackVectorICSlot slot)
+      : FeedbackNexus(vector, slot) {
+    DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC);
+  }
+  KeyedLoadICNexus(TypeFeedbackVector* vector, FeedbackVectorICSlot slot)
+      : FeedbackNexus(vector, slot) {
+    DCHECK(vector->GetKind(slot) == Code::KEYED_LOAD_IC);
+  }
+
+  void Clear(Code* host);
+
+  void ConfigureGeneric();
+  void ConfigurePremonomorphic();
+  // name can be a null handle for element loads.
+  void ConfigureMonomorphic(Handle<Name> name, Handle<HeapType> type,
+                            Handle<Code> handler);
+  // name can be null.
+  void ConfigurePolymorphic(Handle<Name> name, TypeHandleList* types,
+                            CodeHandleList* handlers);
+
+  InlineCacheState StateFromFeedback() const OVERRIDE;
+  int ExtractMaps(MapHandleList* maps) const OVERRIDE;
+  MaybeHandle<Code> FindHandlerForMap(Handle<Map> map) const OVERRIDE;
+  virtual bool FindHandlers(CodeHandleList* code_list,
+                            int length = -1) const OVERRIDE;
+  Name* FindFirstName() const OVERRIDE;
+};
 }
 }  // namespace v8::internal
 
diff --git a/src/type-info.cc b/src/type-info.cc
index cf3950f..611373f 100644
--- a/src/type-info.cc
+++ b/src/type-info.cc
@@ -9,11 +9,8 @@
 #include "src/compiler.h"
 #include "src/ic/ic.h"
 #include "src/ic/stub-cache.h"
-#include "src/macro-assembler.h"
 #include "src/type-info.h"
 
-#include "src/objects-inl.h"
-
 namespace v8 {
 namespace internal {
 
@@ -52,9 +49,20 @@
 }
 
 
-Handle<Object> TypeFeedbackOracle::GetInfo(int slot) {
-  DCHECK(slot >= 0 && slot < feedback_vector_->length());
-  Object* obj = feedback_vector_->get(slot);
+Handle<Object> TypeFeedbackOracle::GetInfo(FeedbackVectorSlot slot) {
+  DCHECK(slot.ToInt() >= 0 && slot.ToInt() < feedback_vector_->length());
+  Object* obj = feedback_vector_->Get(slot);
+  if (!obj->IsJSFunction() ||
+      !CanRetainOtherContext(JSFunction::cast(obj), *native_context_)) {
+    return Handle<Object>(obj, isolate());
+  }
+  return Handle<Object>::cast(isolate()->factory()->undefined_value());
+}
+
+
+Handle<Object> TypeFeedbackOracle::GetInfo(FeedbackVectorICSlot slot) {
+  DCHECK(slot.ToInt() >= 0 && slot.ToInt() < feedback_vector_->length());
+  Object* obj = feedback_vector_->Get(slot);
   if (!obj->IsJSFunction() ||
       !CanRetainOtherContext(JSFunction::cast(obj), *native_context_)) {
     return Handle<Object>(obj, isolate());
@@ -73,6 +81,24 @@
 }
 
 
+bool TypeFeedbackOracle::LoadIsUninitialized(FeedbackVectorICSlot slot) {
+  Code::Kind kind = feedback_vector_->GetKind(slot);
+  if (kind == Code::LOAD_IC) {
+    LoadICNexus nexus(feedback_vector_, slot);
+    return nexus.StateFromFeedback() == UNINITIALIZED;
+  } else if (kind == Code::KEYED_LOAD_IC) {
+    KeyedLoadICNexus nexus(feedback_vector_, slot);
+    return nexus.StateFromFeedback() == UNINITIALIZED;
+  } else if (kind == Code::NUMBER_OF_KINDS) {
+    // Code::NUMBER_OF_KINDS indicates a slot that was never even compiled
+    // in full code.
+    return true;
+  }
+
+  return false;
+}
+
+
 bool TypeFeedbackOracle::StoreIsUninitialized(TypeFeedbackId ast_id) {
   Handle<Object> maybe_code = GetInfo(ast_id);
   if (!maybe_code->IsCode()) return false;
@@ -81,24 +107,21 @@
 }
 
 
-bool TypeFeedbackOracle::StoreIsKeyedPolymorphic(TypeFeedbackId ast_id) {
-  Handle<Object> maybe_code = GetInfo(ast_id);
-  if (maybe_code->IsCode()) {
-    Handle<Code> code = Handle<Code>::cast(maybe_code);
-    return code->is_keyed_store_stub() &&
-        code->ic_state() == POLYMORPHIC;
-  }
-  return false;
+bool TypeFeedbackOracle::CallIsUninitialized(FeedbackVectorICSlot slot) {
+  Handle<Object> value = GetInfo(slot);
+  return value->IsUndefined() ||
+         value.is_identical_to(
+             TypeFeedbackVector::UninitializedSentinel(isolate()));
 }
 
 
-bool TypeFeedbackOracle::CallIsMonomorphic(int slot) {
+bool TypeFeedbackOracle::CallIsMonomorphic(FeedbackVectorICSlot slot) {
   Handle<Object> value = GetInfo(slot);
   return value->IsAllocationSite() || value->IsJSFunction();
 }
 
 
-bool TypeFeedbackOracle::CallNewIsMonomorphic(int slot) {
+bool TypeFeedbackOracle::CallNewIsMonomorphic(FeedbackVectorSlot slot) {
   Handle<Object> info = GetInfo(slot);
   return FLAG_pretenuring_call_new
       ? info->IsJSFunction()
@@ -106,7 +129,7 @@
 }
 
 
-byte TypeFeedbackOracle::ForInType(int feedback_vector_slot) {
+byte TypeFeedbackOracle::ForInType(FeedbackVectorSlot feedback_vector_slot) {
   Handle<Object> value = GetInfo(feedback_vector_slot);
   return value.is_identical_to(
              TypeFeedbackVector::UninitializedSentinel(isolate()))
@@ -115,20 +138,41 @@
 }
 
 
-KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode(
-    TypeFeedbackId ast_id) {
+void TypeFeedbackOracle::GetStoreModeAndKeyType(
+    TypeFeedbackId ast_id, KeyedAccessStoreMode* store_mode,
+    IcCheckType* key_type) {
   Handle<Object> maybe_code = GetInfo(ast_id);
   if (maybe_code->IsCode()) {
     Handle<Code> code = Handle<Code>::cast(maybe_code);
     if (code->kind() == Code::KEYED_STORE_IC) {
-      return KeyedStoreIC::GetKeyedAccessStoreMode(code->extra_ic_state());
+      ExtraICState extra_ic_state = code->extra_ic_state();
+      *store_mode = KeyedStoreIC::GetKeyedAccessStoreMode(extra_ic_state);
+      *key_type = KeyedStoreIC::GetKeyType(extra_ic_state);
+      return;
     }
   }
-  return STANDARD_STORE;
+  *store_mode = STANDARD_STORE;
+  *key_type = ELEMENT;
 }
 
 
-Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(int slot) {
+void TypeFeedbackOracle::GetLoadKeyType(
+    TypeFeedbackId ast_id, IcCheckType* key_type) {
+  Handle<Object> maybe_code = GetInfo(ast_id);
+  if (maybe_code->IsCode()) {
+    Handle<Code> code = Handle<Code>::cast(maybe_code);
+    if (code->kind() == Code::KEYED_LOAD_IC) {
+      ExtraICState extra_ic_state = code->extra_ic_state();
+      *key_type = KeyedLoadIC::GetKeyType(extra_ic_state);
+      return;
+    }
+  }
+  *key_type = ELEMENT;
+}
+
+
+Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(
+    FeedbackVectorICSlot slot) {
   Handle<Object> info = GetInfo(slot);
   if (info->IsAllocationSite()) {
     return Handle<JSFunction>(isolate()->native_context()->array_function());
@@ -138,7 +182,8 @@
 }
 
 
-Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(int slot) {
+Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(
+    FeedbackVectorSlot slot) {
   Handle<Object> info = GetInfo(slot);
   if (FLAG_pretenuring_call_new || info->IsJSFunction()) {
     return Handle<JSFunction>::cast(info);
@@ -149,7 +194,8 @@
 }
 
 
-Handle<AllocationSite> TypeFeedbackOracle::GetCallAllocationSite(int slot) {
+Handle<AllocationSite> TypeFeedbackOracle::GetCallAllocationSite(
+    FeedbackVectorICSlot slot) {
   Handle<Object> info = GetInfo(slot);
   if (info->IsAllocationSite()) {
     return Handle<AllocationSite>::cast(info);
@@ -158,7 +204,8 @@
 }
 
 
-Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite(int slot) {
+Handle<AllocationSite> TypeFeedbackOracle::GetCallNewAllocationSite(
+    FeedbackVectorSlot slot) {
   Handle<Object> info = GetInfo(slot);
   if (FLAG_pretenuring_call_new || info->IsAllocationSite()) {
     return Handle<AllocationSite>::cast(info);
@@ -263,15 +310,45 @@
 }
 
 
-void TypeFeedbackOracle::KeyedPropertyReceiverTypes(
-    TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) {
-  receiver_types->Clear();
-  *is_string = false;
-  if (LoadIsBuiltin(id, Builtins::kKeyedLoadIC_String)) {
-    *is_string = true;
-  } else {
-    CollectReceiverTypes(id, receiver_types);
+bool TypeFeedbackOracle::HasOnlyStringMaps(SmallMapList* receiver_types) {
+  bool all_strings = receiver_types->length() > 0;
+  for (int i = 0; i < receiver_types->length(); i++) {
+    all_strings &= receiver_types->at(i)->IsStringMap();
   }
+  return all_strings;
+}
+
+
+void TypeFeedbackOracle::KeyedPropertyReceiverTypes(
+    TypeFeedbackId id,
+    SmallMapList* receiver_types,
+    bool* is_string,
+    IcCheckType* key_type) {
+  receiver_types->Clear();
+  CollectReceiverTypes(id, receiver_types);
+  *is_string = HasOnlyStringMaps(receiver_types);
+  GetLoadKeyType(id, key_type);
+}
+
+
+void TypeFeedbackOracle::PropertyReceiverTypes(FeedbackVectorICSlot slot,
+                                               Handle<String> name,
+                                               SmallMapList* receiver_types) {
+  receiver_types->Clear();
+  LoadICNexus nexus(feedback_vector_, slot);
+  Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
+  CollectReceiverTypes(&nexus, name, flags, receiver_types);
+}
+
+
+void TypeFeedbackOracle::KeyedPropertyReceiverTypes(
+    FeedbackVectorICSlot slot, SmallMapList* receiver_types, bool* is_string,
+    IcCheckType* key_type) {
+  receiver_types->Clear();
+  KeyedLoadICNexus nexus(feedback_vector_, slot);
+  CollectReceiverTypes<FeedbackNexus>(&nexus, receiver_types);
+  *is_string = HasOnlyStringMaps(receiver_types);
+  *key_type = nexus.FindFirstName() != NULL ? PROPERTY : ELEMENT;
 }
 
 
@@ -285,10 +362,10 @@
 
 void TypeFeedbackOracle::KeyedAssignmentReceiverTypes(
     TypeFeedbackId id, SmallMapList* receiver_types,
-    KeyedAccessStoreMode* store_mode) {
+    KeyedAccessStoreMode* store_mode, IcCheckType* key_type) {
   receiver_types->Clear();
   CollectReceiverTypes(id, receiver_types);
-  *store_mode = GetStoreMode(id);
+  GetStoreModeAndKeyType(id, store_mode, key_type);
 }
 
 
@@ -308,14 +385,21 @@
 
   DCHECK(object->IsCode());
   Handle<Code> code(Handle<Code>::cast(object));
+  CollectReceiverTypes<Code>(*code, name, flags, types);
+}
 
+
+template <class T>
+void TypeFeedbackOracle::CollectReceiverTypes(T* obj, Handle<String> name,
+                                              Code::Flags flags,
+                                              SmallMapList* types) {
   if (FLAG_collect_megamorphic_maps_from_stub_cache &&
-      code->ic_state() == MEGAMORPHIC) {
+      obj->ic_state() == MEGAMORPHIC) {
     types->Reserve(4, zone());
     isolate()->stub_cache()->CollectMatchingMaps(
         types, name, flags, native_context_, zone());
   } else {
-    CollectReceiverTypes(ast_id, types);
+    CollectReceiverTypes<T>(obj, types);
   }
 }
 
@@ -359,12 +443,18 @@
   Handle<Object> object = GetInfo(ast_id);
   if (!object->IsCode()) return;
   Handle<Code> code = Handle<Code>::cast(object);
+  CollectReceiverTypes<Code>(*code, types);
+}
+
+
+template <class T>
+void TypeFeedbackOracle::CollectReceiverTypes(T* obj, SmallMapList* types) {
   MapHandleList maps;
-  if (code->ic_state() == MONOMORPHIC) {
-    Map* map = code->FindFirstMap();
+  if (obj->ic_state() == MONOMORPHIC) {
+    Map* map = obj->FindFirstMap();
     if (map != NULL) maps.Add(handle(map));
-  } else if (code->ic_state() == POLYMORPHIC) {
-    code->FindAllMaps(&maps);
+  } else if (obj->ic_state() == POLYMORPHIC) {
+    obj->FindAllMaps(&maps);
   } else {
     return;
   }
diff --git a/src/type-info.h b/src/type-info.h
index 434ddd6..60f156f 100644
--- a/src/type-info.h
+++ b/src/type-info.h
@@ -24,46 +24,58 @@
                      Handle<Context> native_context, Zone* zone);
 
   bool LoadIsUninitialized(TypeFeedbackId id);
+  bool LoadIsUninitialized(FeedbackVectorICSlot slot);
   bool StoreIsUninitialized(TypeFeedbackId id);
-  bool StoreIsKeyedPolymorphic(TypeFeedbackId id);
-  bool CallIsMonomorphic(int slot);
-  bool CallIsMonomorphic(TypeFeedbackId aid);
+  bool CallIsUninitialized(FeedbackVectorICSlot slot);
+  bool CallIsMonomorphic(FeedbackVectorICSlot slot);
   bool KeyedArrayCallIsHoley(TypeFeedbackId id);
-  bool CallNewIsMonomorphic(int slot);
+  bool CallNewIsMonomorphic(FeedbackVectorSlot slot);
 
   // TODO(1571) We can't use ForInStatement::ForInType as the return value due
   // to various cycles in our headers.
   // TODO(rossberg): once all oracle access is removed from ast.cc, it should
   // be possible.
-  byte ForInType(int feedback_vector_slot);
+  byte ForInType(FeedbackVectorSlot feedback_vector_slot);
 
-  KeyedAccessStoreMode GetStoreMode(TypeFeedbackId id);
+  void GetStoreModeAndKeyType(TypeFeedbackId id,
+                              KeyedAccessStoreMode* store_mode,
+                              IcCheckType* key_type);
+  void GetLoadKeyType(TypeFeedbackId id, IcCheckType* key_type);
 
   void PropertyReceiverTypes(TypeFeedbackId id, Handle<String> name,
                              SmallMapList* receiver_types);
+  void PropertyReceiverTypes(FeedbackVectorICSlot slot, Handle<String> name,
+                             SmallMapList* receiver_types);
   void KeyedPropertyReceiverTypes(TypeFeedbackId id,
                                   SmallMapList* receiver_types,
-                                  bool* is_string);
+                                  bool* is_string,
+                                  IcCheckType* key_type);
+  void KeyedPropertyReceiverTypes(FeedbackVectorICSlot slot,
+                                  SmallMapList* receiver_types, bool* is_string,
+                                  IcCheckType* key_type);
   void AssignmentReceiverTypes(TypeFeedbackId id,
                                Handle<String> name,
                                SmallMapList* receiver_types);
   void KeyedAssignmentReceiverTypes(TypeFeedbackId id,
                                     SmallMapList* receiver_types,
-                                    KeyedAccessStoreMode* store_mode);
+                                    KeyedAccessStoreMode* store_mode,
+                                    IcCheckType* key_type);
   void CountReceiverTypes(TypeFeedbackId id,
                           SmallMapList* receiver_types);
 
   void CollectReceiverTypes(TypeFeedbackId id,
                             SmallMapList* types);
+  template <class T>
+  void CollectReceiverTypes(T* obj, SmallMapList* types);
 
   static bool CanRetainOtherContext(Map* map, Context* native_context);
   static bool CanRetainOtherContext(JSFunction* function,
                                     Context* native_context);
 
-  Handle<JSFunction> GetCallTarget(int slot);
-  Handle<AllocationSite> GetCallAllocationSite(int slot);
-  Handle<JSFunction> GetCallNewTarget(int slot);
-  Handle<AllocationSite> GetCallNewAllocationSite(int slot);
+  Handle<JSFunction> GetCallTarget(FeedbackVectorICSlot slot);
+  Handle<AllocationSite> GetCallAllocationSite(FeedbackVectorICSlot slot);
+  Handle<JSFunction> GetCallNewTarget(FeedbackVectorSlot slot);
+  Handle<AllocationSite> GetCallNewAllocationSite(FeedbackVectorSlot slot);
 
   bool LoadIsBuiltin(TypeFeedbackId id, Builtins::Name builtin_id);
 
@@ -96,6 +108,13 @@
                             Handle<String> name,
                             Code::Flags flags,
                             SmallMapList* types);
+  template <class T>
+  void CollectReceiverTypes(T* obj, Handle<String> name, Code::Flags flags,
+                            SmallMapList* types);
+
+  // Returns true if there is at least one string map and if
+  // all maps are string maps.
+  bool HasOnlyStringMaps(SmallMapList* receiver_types);
 
   void SetInfo(TypeFeedbackId id, Object* target);
 
@@ -113,7 +132,8 @@
 
   // Returns an element from the type feedback vector. Returns undefined
   // if there is no information.
-  Handle<Object> GetInfo(int slot);
+  Handle<Object> GetInfo(FeedbackVectorSlot slot);
+  Handle<Object> GetInfo(FeedbackVectorICSlot slot);
 
  private:
   Handle<Context> native_context_;
diff --git a/src/typedarray.js b/src/typedarray.js
index c149b35..4420bce 100644
--- a/src/typedarray.js
+++ b/src/typedarray.js
@@ -291,6 +291,13 @@
   }
 }
 
+function TypedArrayGetToStringTag() {
+  if (!%IsTypedArray(this)) return;
+  var name = %_ClassOf(this);
+  if (IS_UNDEFINED(name)) return;
+  return name;
+}
+
 // -------------------------------------------------------------------
 
 function SetupTypedArrays() {
@@ -310,7 +317,8 @@
   InstallGetter(global.NAME.prototype, "byteOffset", NAME_GetByteOffset);
   InstallGetter(global.NAME.prototype, "byteLength", NAME_GetByteLength);
   InstallGetter(global.NAME.prototype, "length", NAME_GetLength);
-
+  InstallGetter(global.NAME.prototype, symbolToStringTag,
+                TypedArrayGetToStringTag);
   InstallFunctions(global.NAME.prototype, DONT_ENUM, $Array(
         "subarray", NAMESubArray,
         "set", TypedArraySet
@@ -437,6 +445,8 @@
 
   // Set up constructor property on the DataView prototype.
   %AddNamedProperty($DataView.prototype, "constructor", $DataView, DONT_ENUM);
+  %AddNamedProperty(
+      $DataView.prototype, symbolToStringTag, "DataView", READ_ONLY|DONT_ENUM);
 
   InstallGetter($DataView.prototype, "buffer", DataViewGetBufferJS);
   InstallGetter($DataView.prototype, "byteOffset", DataViewGetByteOffset);
diff --git a/src/types-inl.h b/src/types-inl.h
index 162e658..2e7f8a3 100644
--- a/src/types-inl.h
+++ b/src/types-inl.h
@@ -56,6 +56,13 @@
 
 // static
 template<class T>
+T* ZoneTypeConfig::null_handle() {
+  return NULL;
+}
+
+
+// static
+template<class T>
 T* ZoneTypeConfig::handle(T* type) {
   return type;
 }
@@ -199,6 +206,13 @@
 
 // static
 template<class T>
+i::Handle<T> HeapTypeConfig::null_handle() {
+  return i::Handle<T>();
+}
+
+
+// static
+template<class T>
 i::Handle<T> HeapTypeConfig::handle(T* type) {
   return i::handle(type, i::HeapObject::cast(type)->GetIsolate());
 }
diff --git a/src/types.cc b/src/types.cc
index 8e96d86..c4f1bae 100644
--- a/src/types.cc
+++ b/src/types.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <iomanip>
+
 #include "src/types.h"
 
 #include "src/ostreams.h"
@@ -80,7 +82,7 @@
   if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
   if (this->IsUnion()) {
     double min = +V8_INFINITY;
-    for (int i = 0; i < this->AsUnion()->Length(); ++i) {
+    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
       min = std::min(min, this->AsUnion()->Get(i)->Min());
     }
     return min;
@@ -98,7 +100,7 @@
   if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
   if (this->IsUnion()) {
     double max = -V8_INFINITY;
-    for (int i = 0; i < this->AsUnion()->Length(); ++i) {
+    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
       max = std::max(max, this->AsUnion()->Get(i)->Max());
     }
     return max;
@@ -139,7 +141,7 @@
   if (type->IsBitset()) return type->AsBitset();
   if (type->IsUnion()) {
     int bitset = kNone;
-    for (int i = 0; i < type->AsUnion()->Length(); ++i) {
+    for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
       bitset |= type->AsUnion()->Get(i)->BitsetLub();
     }
     return bitset;
@@ -151,9 +153,9 @@
   }
   if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset();
   if (type->IsRange()) return type->AsRange()->BitsetLub();
-  if (type->IsContext()) return kInternal & kTaggedPtr;
+  if (type->IsContext()) return kInternal & kTaggedPointer;
   if (type->IsArray()) return kArray;
-  if (type->IsFunction()) return kFunction;
+  if (type->IsFunction()) return kOtherObject;  // TODO(rossberg): kFunction
   UNREACHABLE();
   return kNone;
 }
@@ -198,10 +200,10 @@
              map == heap->no_interceptor_result_sentinel_map() ||
              map == heap->termination_exception_map() ||
              map == heap->arguments_marker_map());
-      return kInternal & kTaggedPtr;
+      return kInternal & kTaggedPointer;
     }
     case HEAP_NUMBER_TYPE:
-      return kNumber & kTaggedPtr;
+      return kNumber & kTaggedPointer;
     case JS_VALUE_TYPE:
     case JS_DATE_TYPE:
     case JS_OBJECT_TYPE:
@@ -225,9 +227,9 @@
     case JS_ARRAY_TYPE:
       return kArray;
     case JS_FUNCTION_TYPE:
-      return kFunction;
+      return kOtherObject;  // TODO(rossberg): there should be a Function type.
     case JS_REGEXP_TYPE:
-      return kRegExp;
+      return kOtherObject;  // TODO(rossberg): there should be a RegExp type.
     case JS_PROXY_TYPE:
     case JS_FUNCTION_PROXY_TYPE:
       return kProxy;
@@ -247,9 +249,10 @@
     case SHARED_FUNCTION_INFO_TYPE:
     case ACCESSOR_PAIR_TYPE:
     case FIXED_ARRAY_TYPE:
+    case BYTE_ARRAY_TYPE:
     case FOREIGN_TYPE:
     case CODE_TYPE:
-      return kInternal & kTaggedPtr;
+      return kInternal & kTaggedPointer;
     default:
       UNREACHABLE();
       return kNone;
@@ -262,7 +265,8 @@
 TypeImpl<Config>::BitsetType::Lub(i::Object* value) {
   DisallowHeapAllocation no_allocation;
   if (value->IsNumber()) {
-    return Lub(value->Number()) & (value->IsSmi() ? kTaggedInt : kTaggedPtr);
+    return Lub(value->Number()) &
+        (value->IsSmi() ? kTaggedSigned : kTaggedPointer);
   }
   return Lub(i::HeapObject::cast(value)->map());
 }
@@ -274,73 +278,48 @@
   DisallowHeapAllocation no_allocation;
   if (i::IsMinusZero(value)) return kMinusZero;
   if (std::isnan(value)) return kNaN;
-  if (IsUint32Double(value)) return Lub(FastD2UI(value));
-  if (IsInt32Double(value)) return Lub(FastD2I(value));
-  return kOtherNumber;
-}
-
-
-template<class Config>
-typename TypeImpl<Config>::bitset
-TypeImpl<Config>::BitsetType::Lub(int32_t value) {
-  DisallowHeapAllocation no_allocation;
-  if (value >= 0x40000000) {
-    return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall;
-  }
-  if (value >= 0) return kUnsignedSmall;
-  if (value >= -0x40000000) return kOtherSignedSmall;
-  return i::SmiValuesAre31Bits() ? kOtherSigned32 : kOtherSignedSmall;
-}
-
-
-template<class Config>
-typename TypeImpl<Config>::bitset
-TypeImpl<Config>::BitsetType::Lub(uint32_t value) {
-  DisallowHeapAllocation no_allocation;
-  if (value >= 0x80000000u) return kOtherUnsigned32;
-  if (value >= 0x40000000u) {
-    return i::SmiValuesAre31Bits() ? kOtherUnsigned31 : kUnsignedSmall;
-  }
-  return kUnsignedSmall;
+  if (IsUint32Double(value) || IsInt32Double(value)) return Lub(value, value);
+  return kPlainNumber;
 }
 
 
 // Minimum values of regular numeric bitsets when SmiValuesAre31Bits.
-template<class Config>
+template <class Config>
 const typename TypeImpl<Config>::BitsetType::BitsetMin
-TypeImpl<Config>::BitsetType::BitsetMins31[] = {
-    {kOtherNumber, -V8_INFINITY},
-    {kOtherSigned32, kMinInt},
-    {kOtherSignedSmall, -0x40000000},
-    {kUnsignedSmall, 0},
-    {kOtherUnsigned31, 0x40000000},
-    {kOtherUnsigned32, 0x80000000},
-    {kOtherNumber, static_cast<double>(kMaxUInt32) + 1}
-};
+    TypeImpl<Config>::BitsetType::BitsetMins31[] = {
+        {kOtherNumber, -V8_INFINITY},
+        {kOtherSigned32, kMinInt},
+        {kNegativeSignedSmall, -0x40000000},
+        {kUnsignedSmall, 0},
+        {kOtherUnsigned31, 0x40000000},
+        {kOtherUnsigned32, 0x80000000},
+        {kOtherNumber, static_cast<double>(kMaxUInt32) + 1}};
 
 
 // Minimum values of regular numeric bitsets when SmiValuesAre32Bits.
 // OtherSigned32 and OtherUnsigned31 are empty (see the diagrams in types.h).
-template<class Config>
+template <class Config>
 const typename TypeImpl<Config>::BitsetType::BitsetMin
-TypeImpl<Config>::BitsetType::BitsetMins32[] = {
-    {kOtherNumber, -V8_INFINITY},
-    {kOtherSignedSmall, kMinInt},
-    {kUnsignedSmall, 0},
-    {kOtherUnsigned32, 0x80000000},
-    {kOtherNumber, static_cast<double>(kMaxUInt32) + 1}
-};
+    TypeImpl<Config>::BitsetType::BitsetMins32[] = {
+        {kOtherNumber, -V8_INFINITY},
+        {kNegativeSignedSmall, kMinInt},
+        {kUnsignedSmall, 0},
+        {kOtherUnsigned32, 0x80000000},
+        {kOtherNumber, static_cast<double>(kMaxUInt32) + 1}};
 
 
 template<class Config>
 typename TypeImpl<Config>::bitset
-TypeImpl<Config>::BitsetType::Lub(Limits lim) {
+TypeImpl<Config>::BitsetType::Lub(double min, double max) {
   DisallowHeapAllocation no_allocation;
-  double min = lim.min->Number();
-  double max = lim.max->Number();
   int lub = kNone;
   const BitsetMin* mins = BitsetMins();
 
+  // Make sure the min-max range touches 0, so we are guaranteed no holes
+  // in unions of valid bitsets.
+  if (max < -1) max = -1;
+  if (min > 0) min = 0;
+
   for (size_t i = 1; i < BitsetMinsSize(); ++i) {
     if (min < mins[i].min) {
       lub |= mins[i-1].bits;
@@ -372,7 +351,7 @@
   DisallowHeapAllocation no_allocation;
   DCHECK(Is(bits, kNumber));
   const BitsetMin* mins = BitsetMins();
-  bool mz = bits & kMinusZero;
+  bool mz = SEMANTIC(bits & kMinusZero);
   if (BitsetType::Is(mins[BitsetMinsSize()-1].bits, bits)) {
     return +V8_INFINITY;
   }
@@ -419,7 +398,7 @@
         !this_fun->Receiver()->Equals(that_fun->Receiver())) {
       return false;
     }
-    for (int i = 0; i < this_fun->Arity(); ++i) {
+    for (int i = 0, n = this_fun->Arity(); i < n; ++i) {
       if (!this_fun->Parameter(i)->Equals(that_fun->Parameter(i))) return false;
     }
     return true;
@@ -443,16 +422,15 @@
 
   // (T1 \/ ... \/ Tn) <= T  if  (T1 <= T) /\ ... /\ (Tn <= T)
   if (this->IsUnion()) {
-    UnionHandle unioned = handle(this->AsUnion());
-    for (int i = 0; i < unioned->Length(); ++i) {
-      if (!unioned->Get(i)->Is(that)) return false;
+    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
+      if (!this->AsUnion()->Get(i)->Is(that)) return false;
     }
     return true;
   }
 
   // T <= (T1 \/ ... \/ Tn)  if  (T <= T1) \/ ... \/ (T <= Tn)
   if (that->IsUnion()) {
-    for (int i = 0; i < that->AsUnion()->Length(); ++i) {
+    for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
       if (this->Is(that->AsUnion()->Get(i))) return true;
       if (i > 1 && this->IsRange()) return false;  // Shortcut.
     }
@@ -465,6 +443,7 @@
             Contains(that->AsRange(), *this->AsConstant()->Value()));
   }
   if (this->IsRange()) return false;
+
   return this->SimplyEquals(that);
 }
 
@@ -507,16 +486,15 @@
 
   // (T1 \/ ... \/ Tn) overlaps T  if  (T1 overlaps T) \/ ... \/ (Tn overlaps T)
   if (this->IsUnion()) {
-    UnionHandle unioned = handle(this->AsUnion());
-    for (int i = 0; i < unioned->Length(); ++i) {
-      if (unioned->Get(i)->Maybe(that)) return true;
+    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
+      if (this->AsUnion()->Get(i)->Maybe(that)) return true;
     }
     return false;
   }
 
   // T overlaps (T1 \/ ... \/ Tn)  if  (T overlaps T1) \/ ... \/ (T overlaps Tn)
   if (that->IsUnion()) {
-    for (int i = 0; i < that->AsUnion()->Length(); ++i) {
+    for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
       if (this->Maybe(that->AsUnion()->Get(i))) return true;
     }
     return false;
@@ -683,13 +661,13 @@
     TypeHandle lhs, TypeHandle rhs,
     UnionHandle result, int size, Region* region) {
   if (lhs->IsUnion()) {
-    for (int i = 0; i < lhs->AsUnion()->Length(); ++i) {
+    for (int i = 0, n = lhs->AsUnion()->Length(); i < n; ++i) {
       size = IntersectAux(lhs->AsUnion()->Get(i), rhs, result, size, region);
     }
     return size;
   }
   if (rhs->IsUnion()) {
-    for (int i = 0; i < rhs->AsUnion()->Length(); ++i) {
+    for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) {
       size = IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, region);
     }
     return size;
@@ -793,7 +771,7 @@
     TypeHandle type, UnionHandle result, int size, Region* region) {
   if (type->IsBitset() || type->IsRange()) return size;
   if (type->IsUnion()) {
-    for (int i = 0; i < type->AsUnion()->Length(); ++i) {
+    for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
       size = AddToUnion(type->AsUnion()->Get(i), result, size, region);
     }
     return size;
@@ -834,10 +812,9 @@
   if (this->IsClass()) {
     return 1;
   } else if (this->IsUnion()) {
-    UnionHandle unioned = handle(this->AsUnion());
     int result = 0;
-    for (int i = 0; i < unioned->Length(); ++i) {
-      if (unioned->Get(i)->IsClass()) ++result;
+    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
+      if (this->AsUnion()->Get(i)->IsClass()) ++result;
     }
     return result;
   } else {
@@ -852,10 +829,9 @@
   if (this->IsConstant()) {
     return 1;
   } else if (this->IsUnion()) {
-    UnionHandle unioned = handle(this->AsUnion());
     int result = 0;
-    for (int i = 0; i < unioned->Length(); ++i) {
-      if (unioned->Get(i)->IsConstant()) ++result;
+    for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
+      if (this->AsUnion()->Get(i)->IsConstant()) ++result;
     }
     return result;
   } else {
@@ -917,9 +893,8 @@
   DisallowHeapAllocation no_allocation;
   ++index_;
   if (type_->IsUnion()) {
-    UnionHandle unioned = Config::template cast<UnionType>(type_);
-    for (; index_ < unioned->Length(); ++index_) {
-      if (matches(unioned->Get(index_))) return;
+    for (int n = type_->AsUnion()->Length(); index_ < n; ++index_) {
+      if (matches(type_->AsUnion()->Get(index_))) return;
     }
   } else if (index_ == 0 && matches(type_)) {
     return;
@@ -1000,7 +975,7 @@
 
 
 template <class Config>
-void TypeImpl<Config>::BitsetType::Print(OStream& os,  // NOLINT
+void TypeImpl<Config>::BitsetType::Print(std::ostream& os,  // NOLINT
                                          bitset bits) {
   DisallowHeapAllocation no_allocation;
   const char* name = Name(bits);
@@ -1015,6 +990,7 @@
 #undef BITSET_CONSTANT
 
 #define BITSET_CONSTANT(type, value) SEMANTIC(k##type),
+      INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT)
       SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT)
 #undef BITSET_CONSTANT
   };
@@ -1036,7 +1012,7 @@
 
 
 template <class Config>
-void TypeImpl<Config>::PrintTo(OStream& os, PrintDimension dim) {  // NOLINT
+void TypeImpl<Config>::PrintTo(std::ostream& os, PrintDimension dim) {
   DisallowHeapAllocation no_allocation;
   if (dim != REPRESENTATION_DIM) {
     if (this->IsBitset()) {
@@ -1046,20 +1022,22 @@
       BitsetType::New(BitsetType::Lub(this))->PrintTo(os, dim);
       os << ")";
     } else if (this->IsConstant()) {
-      os << "Constant(" << static_cast<void*>(*this->AsConstant()->Value())
-         << ")";
+      os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")";
     } else if (this->IsRange()) {
-      os << "Range(" << this->AsRange()->Min()->Number()
-         << ", " << this->AsRange()->Max()->Number() << ")";
+      std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed);
+      std::streamsize saved_precision = os.precision(0);
+      os << "Range(" << this->AsRange()->Min()->Number() << ", "
+         << this->AsRange()->Max()->Number() << ")";
+      os.flags(saved_flags);
+      os.precision(saved_precision);
     } else if (this->IsContext()) {
       os << "Context(";
       this->AsContext()->Outer()->PrintTo(os, dim);
       os << ")";
     } else if (this->IsUnion()) {
       os << "(";
-      UnionHandle unioned = handle(this->AsUnion());
-      for (int i = 0; i < unioned->Length(); ++i) {
-        TypeHandle type_i = unioned->Get(i);
+      for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
+        TypeHandle type_i = this->AsUnion()->Get(i);
         if (i > 0) os << " | ";
         type_i->PrintTo(os, dim);
       }
@@ -1096,13 +1074,13 @@
 void TypeImpl<Config>::Print() {
   OFStream os(stdout);
   PrintTo(os);
-  os << endl;
+  os << std::endl;
 }
 template <class Config>
 void TypeImpl<Config>::BitsetType::Print(bitset bits) {
   OFStream os(stdout);
   Print(os, bits);
-  os << endl;
+  os << std::endl;
 }
 #endif
 
diff --git a/src/types.h b/src/types.h
index e7815ed..4b7d8ba 100644
--- a/src/types.h
+++ b/src/types.h
@@ -154,75 +154,90 @@
 // Values for bitset types
 
 #define MASK_BITSET_TYPE_LIST(V) \
-  V(Representation, 0xff800000u) \
-  V(Semantic,       0x007ffffeu)
+  V(Representation, 0xfff00000u) \
+  V(Semantic,       0x000ffffeu)
 
 #define REPRESENTATION(k) ((k) & BitsetType::kRepresentation)
 #define SEMANTIC(k)       ((k) & BitsetType::kSemantic)
 
-#define REPRESENTATION_BITSET_TYPE_LIST(V) \
-  V(None,             0)                   \
-  V(UntaggedInt1,     1u << 23 | kSemantic) \
-  V(UntaggedInt8,     1u << 24 | kSemantic) \
-  V(UntaggedInt16,    1u << 25 | kSemantic) \
-  V(UntaggedInt32,    1u << 26 | kSemantic) \
-  V(UntaggedFloat32,  1u << 27 | kSemantic) \
-  V(UntaggedFloat64,  1u << 28 | kSemantic) \
-  V(UntaggedPtr,      1u << 29 | kSemantic) \
-  V(TaggedInt,        1u << 30 | kSemantic) \
-  V(TaggedPtr,        1u << 31 | kSemantic) \
+#define REPRESENTATION_BITSET_TYPE_LIST(V)    \
+  V(None,               0)                    \
+  V(UntaggedBit,        1u << 20 | kSemantic) \
+  V(UntaggedSigned8,    1u << 21 | kSemantic) \
+  V(UntaggedSigned16,   1u << 22 | kSemantic) \
+  V(UntaggedSigned32,   1u << 23 | kSemantic) \
+  V(UntaggedUnsigned8,  1u << 24 | kSemantic) \
+  V(UntaggedUnsigned16, 1u << 25 | kSemantic) \
+  V(UntaggedUnsigned32, 1u << 26 | kSemantic) \
+  V(UntaggedFloat32,    1u << 27 | kSemantic) \
+  V(UntaggedFloat64,    1u << 28 | kSemantic) \
+  V(UntaggedPointer,    1u << 29 | kSemantic) \
+  V(TaggedSigned,       1u << 30 | kSemantic) \
+  V(TaggedPointer,      1u << 31 | kSemantic) \
   \
-  V(UntaggedInt,      kUntaggedInt1 | kUntaggedInt8 |      \
-                      kUntaggedInt16 | kUntaggedInt32)     \
-  V(UntaggedFloat,    kUntaggedFloat32 | kUntaggedFloat64) \
-  V(UntaggedNumber,   kUntaggedInt | kUntaggedFloat)       \
-  V(Untagged,         kUntaggedNumber | kUntaggedPtr)      \
-  V(Tagged,           kTaggedInt | kTaggedPtr)
+  V(UntaggedSigned,     kUntaggedSigned8 | kUntaggedSigned16 |              \
+                        kUntaggedSigned32)                                  \
+  V(UntaggedUnsigned,   kUntaggedUnsigned8 | kUntaggedUnsigned16 |          \
+                        kUntaggedUnsigned32)                                \
+  V(UntaggedIntegral8,  kUntaggedSigned8 | kUntaggedUnsigned8)              \
+  V(UntaggedIntegral16, kUntaggedSigned16 | kUntaggedUnsigned16)            \
+  V(UntaggedIntegral32, kUntaggedSigned32 | kUntaggedUnsigned32)            \
+  V(UntaggedIntegral,   kUntaggedBit | kUntaggedSigned | kUntaggedUnsigned) \
+  V(UntaggedFloat,      kUntaggedFloat32 | kUntaggedFloat64)                \
+  V(UntaggedNumber,     kUntaggedIntegral | kUntaggedFloat)                 \
+  V(Untagged,           kUntaggedNumber | kUntaggedPointer)                 \
+  V(Tagged,             kTaggedSigned | kTaggedPointer)
+
+#define INTERNAL_BITSET_TYPE_LIST(V)                                      \
+  V(OtherUnsigned31, 1u << 1 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+  V(OtherUnsigned32, 1u << 2 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+  V(OtherSigned32,   1u << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+  V(OtherNumber,     1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber))
 
 #define SEMANTIC_BITSET_TYPE_LIST(V) \
-  V(Null,                1u << 1  | REPRESENTATION(kTaggedPtr)) \
-  V(Undefined,           1u << 2  | REPRESENTATION(kTaggedPtr)) \
-  V(Boolean,             1u << 3  | REPRESENTATION(kTaggedPtr)) \
-  V(UnsignedSmall,       1u << 4  | REPRESENTATION(kTagged | kUntaggedNumber)) \
-  V(OtherSignedSmall,    1u << 5  | REPRESENTATION(kTagged | kUntaggedNumber)) \
-  V(OtherUnsigned31,     1u << 6  | REPRESENTATION(kTagged | kUntaggedNumber)) \
-  V(OtherUnsigned32,     1u << 7  | REPRESENTATION(kTagged | kUntaggedNumber)) \
-  V(OtherSigned32,       1u << 8  | REPRESENTATION(kTagged | kUntaggedNumber)) \
-  V(MinusZero,           1u << 9  | REPRESENTATION(kTagged | kUntaggedNumber)) \
-  V(NaN,                 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
-  V(OtherNumber,         1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \
-  V(Symbol,              1u << 12 | REPRESENTATION(kTaggedPtr)) \
-  V(InternalizedString,  1u << 13 | REPRESENTATION(kTaggedPtr)) \
-  V(OtherString,         1u << 14 | REPRESENTATION(kTaggedPtr)) \
-  V(Undetectable,        1u << 15 | REPRESENTATION(kTaggedPtr)) \
-  V(Array,               1u << 16 | REPRESENTATION(kTaggedPtr)) \
-  V(Buffer,              1u << 17 | REPRESENTATION(kTaggedPtr)) \
-  V(Function,            1u << 18 | REPRESENTATION(kTaggedPtr)) \
-  V(RegExp,              1u << 19 | REPRESENTATION(kTaggedPtr)) \
-  V(OtherObject,         1u << 20 | REPRESENTATION(kTaggedPtr)) \
-  V(Proxy,               1u << 21 | REPRESENTATION(kTaggedPtr)) \
-  V(Internal,            1u << 22 | REPRESENTATION(kTagged | kUntagged)) \
+  V(NegativeSignedSmall, 1u << 5  | REPRESENTATION(kTagged | kUntaggedNumber)) \
+  V(Null,                1u << 6  | REPRESENTATION(kTaggedPointer)) \
+  V(Undefined,           1u << 7  | REPRESENTATION(kTaggedPointer)) \
+  V(Boolean,             1u << 8  | REPRESENTATION(kTaggedPointer)) \
+  V(UnsignedSmall,       1u << 9  | REPRESENTATION(kTagged | kUntaggedNumber)) \
+  V(MinusZero,           1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+  V(NaN,                 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \
+  V(Symbol,              1u << 12 | REPRESENTATION(kTaggedPointer)) \
+  V(InternalizedString,  1u << 13 | REPRESENTATION(kTaggedPointer)) \
+  V(OtherString,         1u << 14 | REPRESENTATION(kTaggedPointer)) \
+  V(Undetectable,        1u << 15 | REPRESENTATION(kTaggedPointer)) \
+  V(Array,               1u << 16 | REPRESENTATION(kTaggedPointer)) \
+  V(OtherObject,         1u << 17 | REPRESENTATION(kTaggedPointer)) \
+  V(Proxy,               1u << 18 | REPRESENTATION(kTaggedPointer)) \
+  V(Internal,            1u << 19 | REPRESENTATION(kTagged | kUntagged)) \
   \
-  V(SignedSmall,         kUnsignedSmall | kOtherSignedSmall) \
+  V(SignedSmall,         kUnsignedSmall | kNegativeSignedSmall) \
   V(Signed32,            kSignedSmall | kOtherUnsigned31 | kOtherSigned32) \
+  V(NegativeSigned32,    kNegativeSignedSmall | kOtherSigned32) \
+  V(NonNegativeSigned32, kUnsignedSmall | kOtherUnsigned31) \
   V(Unsigned32,          kUnsignedSmall | kOtherUnsigned31 | kOtherUnsigned32) \
   V(Integral32,          kSigned32 | kUnsigned32) \
-  V(OrderedNumber,       kIntegral32 | kMinusZero | kOtherNumber) \
+  V(PlainNumber,         kIntegral32 | kOtherNumber) \
+  V(OrderedNumber,       kPlainNumber | kMinusZero) \
   V(Number,              kOrderedNumber | kNaN) \
   V(String,              kInternalizedString | kOtherString) \
   V(UniqueName,          kSymbol | kInternalizedString) \
   V(Name,                kSymbol | kString) \
   V(NumberOrString,      kNumber | kString) \
-  V(Primitive,           kNumber | kName | kBoolean | kNull | kUndefined) \
-  V(DetectableObject,    kArray | kFunction | kRegExp | kOtherObject) \
+  V(PlainPrimitive,      kNumberOrString | kBoolean | kNull | kUndefined) \
+  V(Primitive,           kSymbol | kPlainPrimitive) \
+  V(DetectableObject,    kArray | kOtherObject) \
   V(DetectableReceiver,  kDetectableObject | kProxy) \
   V(Detectable,          kDetectableReceiver | kNumber | kName) \
   V(Object,              kDetectableObject | kUndetectable) \
   V(Receiver,            kObject | kProxy) \
-  V(NonNumber,           kBoolean | kName | kNull | kReceiver | \
-                         kUndefined | kInternal) \
+  V(StringOrReceiver,    kString | kReceiver) \
+  V(Unique,              kBoolean | kUniqueName | kNull | kUndefined | \
+                         kReceiver) \
+  V(NonNumber,           kUnique | kString | kInternal) \
   V(Any,                 0xfffffffeu)
 
+
 /*
  * The following diagrams show how integers (in the mathematical sense) are
  * divided among the different atomic numerical types.
@@ -242,15 +257,20 @@
  *
  * E.g., OtherUnsigned32 (OU32) covers all integers from 2^31 to 2^32-1.
  *
+ * NOTE: OtherSigned32 (OS32) and OU31 (OtherUnsigned31) are empty if Smis are
+ *       32-bit wide.  They should thus never be used directly, only indirectly
+ *       via e.g. Number.
  */
 
 #define PROPER_BITSET_TYPE_LIST(V) \
   REPRESENTATION_BITSET_TYPE_LIST(V) \
   SEMANTIC_BITSET_TYPE_LIST(V)
 
-#define BITSET_TYPE_LIST(V) \
-  MASK_BITSET_TYPE_LIST(V) \
-  PROPER_BITSET_TYPE_LIST(V)
+#define BITSET_TYPE_LIST(V)          \
+  MASK_BITSET_TYPE_LIST(V)           \
+  REPRESENTATION_BITSET_TYPE_LIST(V) \
+  INTERNAL_BITSET_TYPE_LIST(V)       \
+  SEMANTIC_BITSET_TYPE_LIST(V)
 
 
 // -----------------------------------------------------------------------------
@@ -262,6 +282,7 @@
 //   typedef Struct;
 //   typedef Region;
 //   template<class> struct Handle { typedef type; }  // No template typedefs...
+//   template<class T> static Handle<T>::type null_handle();
 //   template<class T> static Handle<T>::type handle(T* t);  // !is_bitset(t)
 //   template<class T> static Handle<T>::type cast(Handle<Type>::type);
 //   static bool is_bitset(Type*);
@@ -372,6 +393,12 @@
 
   static TypeHandle Union(TypeHandle type1, TypeHandle type2, Region* reg);
   static TypeHandle Intersect(TypeHandle type1, TypeHandle type2, Region* reg);
+  static TypeImpl* Union(TypeImpl* type1, TypeImpl* type2) {
+    return BitsetType::New(type1->AsBitset() | type2->AsBitset());
+  }
+  static TypeImpl* Intersect(TypeImpl* type1, TypeImpl* type2) {
+    return BitsetType::New(type1->AsBitset() & type2->AsBitset());
+  }
 
   static TypeHandle Of(double value, Region* region) {
     return Config::from_bitset(BitsetType::Lub(value), region);
@@ -453,6 +480,11 @@
   double Min();
   double Max();
 
+  // Extracts a range from the type. If the type is a range, it just
+  // returns it; if it is a union, it returns the range component.
+  // Note that it does not contain range for constants.
+  RangeType* GetRange();
+
   int NumClasses();
   int NumConstants();
 
@@ -478,7 +510,7 @@
 
   enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
 
-  void PrintTo(OStream& os, PrintDimension dim = BOTH_DIMS);  // NOLINT
+  void PrintTo(std::ostream& os, PrintDimension dim = BOTH_DIMS);  // NOLINT
 
 #ifdef DEBUG
   void Print();
@@ -540,7 +572,6 @@
   static bool Contains(RangeType* lhs, RangeType* rhs);
   static bool Contains(RangeType* range, i::Object* val);
 
-  RangeType* GetRange();
   static int UpdateRange(
       RangeHandle type, UnionHandle result, int size, Region* region);
 
@@ -576,6 +607,20 @@
 
   static TypeImpl* New(bitset bits) {
     DCHECK(bits == kNone || IsInhabited(bits));
+
+    if (FLAG_enable_slow_asserts) {
+      // Check that the bitset does not contain any holes in number ranges.
+      bitset mask = kSemantic;
+      if (!i::SmiValuesAre31Bits()) {
+        mask &= ~(kOtherUnsigned31 | kOtherSigned32);
+      }
+      bitset number_bits = bits & kPlainNumber & mask;
+      if (number_bits != 0) {
+        bitset lub = Lub(Min(number_bits), Max(number_bits)) & mask;
+        CHECK(lub == number_bits);
+      }
+    }
+
     return Config::from_bitset(bits);
   }
   static TypeHandle New(bitset bits, Region* region) {
@@ -598,15 +643,13 @@
 
   static bitset Glb(TypeImpl* type);  // greatest lower bound that's a bitset
   static bitset Lub(TypeImpl* type);  // least upper bound that's a bitset
+  static bitset Lub(i::Map* map);
   static bitset Lub(i::Object* value);
   static bitset Lub(double value);
-  static bitset Lub(int32_t value);
-  static bitset Lub(uint32_t value);
-  static bitset Lub(i::Map* map);
-  static bitset Lub(Limits lim);
+  static bitset Lub(double min, double max);
 
   static const char* Name(bitset);
-  static void Print(OStream& os, bitset);  // NOLINT
+  static void Print(std::ostream& os, bitset);  // NOLINT
 #ifdef DEBUG
   static void Print(bitset);
 #endif
@@ -778,10 +821,12 @@
 
   static RangeHandle New(
       i::Handle<i::Object> min, i::Handle<i::Object> max, Region* region) {
+    DCHECK(IsInteger(min->Number()) && IsInteger(max->Number()));
     DCHECK(min->Number() <= max->Number());
     RangeHandle type = Config::template cast<RangeType>(
         StructuralType::New(StructuralType::kRangeTag, 3, region));
-    type->Set(0, BitsetType::New(BitsetType::Lub(Limits(min, max)), region));
+    type->Set(0, BitsetType::New(
+        BitsetType::Lub(min->Number(), max->Number()), region));
     type->SetValue(1, min);
     type->SetValue(2, max);
     return type;
@@ -910,6 +955,7 @@
   typedef i::Zone Region;
   template<class T> struct Handle { typedef T* type; };
 
+  template<class T> static inline T* null_handle();
   template<class T> static inline T* handle(T* type);
   template<class T> static inline T* cast(Type* type);
 
@@ -952,6 +998,7 @@
   typedef i::Isolate Region;
   template<class T> struct Handle { typedef i::Handle<T> type; };
 
+  template<class T> static inline i::Handle<T> null_handle();
   template<class T> static inline i::Handle<T> handle(T* type);
   template<class T> static inline i::Handle<T> cast(i::Handle<Type> type);
 
@@ -1000,7 +1047,9 @@
   TypeHandle lower;
   TypeHandle upper;
 
-  BoundsImpl() {}
+  BoundsImpl() :  // Make sure accessing uninitialized bounds crashes big-time.
+    lower(Config::template null_handle<Type>()),
+    upper(Config::template null_handle<Type>()) {}
   explicit BoundsImpl(TypeHandle t) : lower(t), upper(t) {}
   BoundsImpl(TypeHandle l, TypeHandle u) : lower(l), upper(u) {
     DCHECK(lower->Is(upper));
@@ -1016,7 +1065,7 @@
     TypeHandle lower = Type::Union(b1.lower, b2.lower, region);
     TypeHandle upper = Type::Intersect(b1.upper, b2.upper, region);
     // Lower bounds are considered approximate, correct as necessary.
-    lower = Type::Intersect(lower, upper, region);
+    if (!lower->Is(upper)) lower = upper;
     return BoundsImpl(lower, upper);
   }
 
@@ -1028,14 +1077,16 @@
   }
 
   static BoundsImpl NarrowLower(BoundsImpl b, TypeHandle t, Region* region) {
-    // Lower bounds are considered approximate, correct as necessary.
-    t = Type::Intersect(t, b.upper, region);
     TypeHandle lower = Type::Union(b.lower, t, region);
+    // Lower bounds are considered approximate, correct as necessary.
+    if (!lower->Is(b.upper)) lower = b.upper;
     return BoundsImpl(lower, b.upper);
   }
   static BoundsImpl NarrowUpper(BoundsImpl b, TypeHandle t, Region* region) {
-    TypeHandle lower = Type::Intersect(b.lower, t, region);
+    TypeHandle lower = b.lower;
     TypeHandle upper = Type::Intersect(b.upper, t, region);
+    // Lower bounds are considered approximate, correct as necessary.
+    if (!lower->Is(upper)) lower = upper;
     return BoundsImpl(lower, upper);
   }
 
diff --git a/src/typing.cc b/src/typing.cc
index 02c9603..17deb6d 100644
--- a/src/typing.cc
+++ b/src/typing.cc
@@ -56,7 +56,7 @@
     var->name()->Print(os);
     os << " : " << Brief(value) << " -> ";
     type->PrintTo(os);
-    os << endl;
+    os << std::endl;
   }
 #endif  // OBJECT_PRINT
 
@@ -394,7 +394,8 @@
 
 
 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
-  NarrowType(expr, Bounds(Type::RegExp(zone())));
+  // TODO(rossberg): Reintroduce RegExp type.
+  NarrowType(expr, Bounds(Type::Object(zone())));
 }
 
 
@@ -444,9 +445,11 @@
         oracle()->AssignmentReceiverTypes(id, name, expr->GetReceiverTypes());
       } else {
         KeyedAccessStoreMode store_mode;
-        oracle()->KeyedAssignmentReceiverTypes(
-            id, expr->GetReceiverTypes(), &store_mode);
+        IcCheckType key_type;
+        oracle()->KeyedAssignmentReceiverTypes(id, expr->GetReceiverTypes(),
+                                               &store_mode, &key_type);
         expr->set_store_mode(store_mode);
+        expr->set_key_type(key_type);
       }
     }
   }
@@ -482,19 +485,38 @@
 
 void AstTyper::VisitProperty(Property* expr) {
   // Collect type feedback.
-  TypeFeedbackId id = expr->PropertyFeedbackId();
-  expr->set_is_uninitialized(oracle()->LoadIsUninitialized(id));
+  FeedbackVectorICSlot slot(FeedbackVectorICSlot::Invalid());
+  TypeFeedbackId id(TypeFeedbackId::None());
+  if (FLAG_vector_ics) {
+    slot = expr->PropertyFeedbackSlot();
+    expr->set_is_uninitialized(oracle()->LoadIsUninitialized(slot));
+  } else {
+    id = expr->PropertyFeedbackId();
+    expr->set_is_uninitialized(oracle()->LoadIsUninitialized(id));
+  }
+
   if (!expr->IsUninitialized()) {
     if (expr->key()->IsPropertyName()) {
       Literal* lit_key = expr->key()->AsLiteral();
       DCHECK(lit_key != NULL && lit_key->value()->IsString());
       Handle<String> name = Handle<String>::cast(lit_key->value());
-      oracle()->PropertyReceiverTypes(id, name, expr->GetReceiverTypes());
+      if (FLAG_vector_ics) {
+        oracle()->PropertyReceiverTypes(slot, name, expr->GetReceiverTypes());
+      } else {
+        oracle()->PropertyReceiverTypes(id, name, expr->GetReceiverTypes());
+      }
     } else {
       bool is_string;
-      oracle()->KeyedPropertyReceiverTypes(
-          id, expr->GetReceiverTypes(), &is_string);
+      IcCheckType key_type;
+      if (FLAG_vector_ics) {
+        oracle()->KeyedPropertyReceiverTypes(slot, expr->GetReceiverTypes(),
+                                             &is_string, &key_type);
+      } else {
+        oracle()->KeyedPropertyReceiverTypes(id, expr->GetReceiverTypes(),
+                                             &is_string, &key_type);
+      }
       expr->set_is_string_access(is_string);
+      expr->set_key_type(key_type);
     }
   }
 
@@ -508,15 +530,20 @@
 void AstTyper::VisitCall(Call* expr) {
   // Collect type feedback.
   RECURSE(Visit(expr->expression()));
-  if (!expr->expression()->IsProperty() &&
-      expr->IsUsingCallFeedbackSlot(isolate()) &&
-      oracle()->CallIsMonomorphic(expr->CallFeedbackSlot())) {
-    expr->set_target(oracle()->GetCallTarget(expr->CallFeedbackSlot()));
-    Handle<AllocationSite> site =
-        oracle()->GetCallAllocationSite(expr->CallFeedbackSlot());
-    expr->set_allocation_site(site);
+  bool is_uninitialized = true;
+  if (expr->IsUsingCallFeedbackSlot(isolate())) {
+    FeedbackVectorICSlot slot = expr->CallFeedbackSlot();
+    is_uninitialized = oracle()->CallIsUninitialized(slot);
+    if (!expr->expression()->IsProperty() &&
+        oracle()->CallIsMonomorphic(slot)) {
+      expr->set_target(oracle()->GetCallTarget(slot));
+      Handle<AllocationSite> site = oracle()->GetCallAllocationSite(slot);
+      expr->set_allocation_site(site);
+    }
   }
 
+  expr->set_is_uninitialized(is_uninitialized);
+
   ZoneList<Expression*>* args = expr->arguments();
   for (int i = 0; i < args->length(); ++i) {
     Expression* arg = args->at(i);
@@ -587,7 +614,11 @@
 void AstTyper::VisitCountOperation(CountOperation* expr) {
   // Collect type feedback.
   TypeFeedbackId store_id = expr->CountStoreFeedbackId();
-  expr->set_store_mode(oracle()->GetStoreMode(store_id));
+  KeyedAccessStoreMode store_mode;
+  IcCheckType key_type;
+  oracle()->GetStoreModeAndKeyType(store_id, &store_mode, &key_type);
+  expr->set_store_mode(store_mode);
+  expr->set_key_type(key_type);
   oracle()->CountReceiverTypes(store_id, expr->GetReceiverTypes());
   expr->set_type(oracle()->CountType(expr->CountBinOpFeedbackId()));
   // TODO(rossberg): merge the count type with the generic expression type.
diff --git a/src/typing.h b/src/typing.h
index 6f6b0dc..b56c878 100644
--- a/src/typing.h
+++ b/src/typing.h
@@ -72,10 +72,10 @@
            var->IsParameter() ? parameter_index(var->index()) : kNoVar;
   }
 
-  void VisitDeclarations(ZoneList<Declaration*>* declarations);
-  void VisitStatements(ZoneList<Statement*>* statements);
+  void VisitDeclarations(ZoneList<Declaration*>* declarations) OVERRIDE;
+  void VisitStatements(ZoneList<Statement*>* statements) OVERRIDE;
 
-#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
+#define DECLARE_VISIT(type) virtual void Visit##type(type* node) OVERRIDE;
   AST_NODE_LIST(DECLARE_VISIT)
 #undef DECLARE_VISIT
 
diff --git a/src/unicode-decoder.cc b/src/unicode-decoder.cc
new file mode 100644
index 0000000..88eff3a
--- /dev/null
+++ b/src/unicode-decoder.cc
@@ -0,0 +1,78 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+#include "src/unicode-inl.h"
+#include "src/unicode-decoder.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+namespace unibrow {
+
+void Utf8DecoderBase::Reset(uint16_t* buffer, unsigned buffer_length,
+                            const uint8_t* stream, unsigned stream_length) {
+  // Assume everything will fit in the buffer and stream won't be needed.
+  last_byte_of_buffer_unused_ = false;
+  unbuffered_start_ = NULL;
+  bool writing_to_buffer = true;
+  // Loop until stream is read, writing to buffer as long as buffer has space.
+  unsigned utf16_length = 0;
+  while (stream_length != 0) {
+    unsigned cursor = 0;
+    uint32_t character = Utf8::ValueOf(stream, stream_length, &cursor);
+    DCHECK(cursor > 0 && cursor <= stream_length);
+    stream += cursor;
+    stream_length -= cursor;
+    bool is_two_characters = character > Utf16::kMaxNonSurrogateCharCode;
+    utf16_length += is_two_characters ? 2 : 1;
+    // Don't need to write to the buffer, but still need utf16_length.
+    if (!writing_to_buffer) continue;
+    // Write out the characters to the buffer.
+    // Must check for equality with buffer_length as we've already updated it.
+    if (utf16_length <= buffer_length) {
+      if (is_two_characters) {
+        *buffer++ = Utf16::LeadSurrogate(character);
+        *buffer++ = Utf16::TrailSurrogate(character);
+      } else {
+        *buffer++ = character;
+      }
+      if (utf16_length == buffer_length) {
+        // Just wrote last character of buffer
+        writing_to_buffer = false;
+        unbuffered_start_ = stream;
+      }
+      continue;
+    }
+    // Have gone over buffer.
+    // Last char of buffer is unused, set cursor back.
+    DCHECK(is_two_characters);
+    writing_to_buffer = false;
+    last_byte_of_buffer_unused_ = true;
+    unbuffered_start_ = stream - cursor;
+  }
+  utf16_length_ = utf16_length;
+}
+
+
+void Utf8DecoderBase::WriteUtf16Slow(const uint8_t* stream, uint16_t* data,
+                                     unsigned data_length) {
+  while (data_length != 0) {
+    unsigned cursor = 0;
+    uint32_t character = Utf8::ValueOf(stream, Utf8::kMaxEncodedSize, &cursor);
+    // There's a total lack of bounds checking for stream
+    // as it was already done in Reset.
+    stream += cursor;
+    if (character > unibrow::Utf16::kMaxNonSurrogateCharCode) {
+      *data++ = Utf16::LeadSurrogate(character);
+      *data++ = Utf16::TrailSurrogate(character);
+      DCHECK(data_length > 1);
+      data_length -= 2;
+    } else {
+      *data++ = character;
+      data_length -= 1;
+    }
+  }
+}
+
+}  // namespace unibrow
diff --git a/src/unicode-decoder.h b/src/unicode-decoder.h
new file mode 100644
index 0000000..35ea30c
--- /dev/null
+++ b/src/unicode-decoder.h
@@ -0,0 +1,121 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_UNICODE_DECODER_H_
+#define V8_UNICODE_DECODER_H_
+
+#include <sys/types.h>
+#include "src/globals.h"
+
+namespace unibrow {
+
+class Utf8DecoderBase {
+ public:
+  // Initialization done in subclass.
+  inline Utf8DecoderBase();
+  inline Utf8DecoderBase(uint16_t* buffer, unsigned buffer_length,
+                         const uint8_t* stream, unsigned stream_length);
+  inline unsigned Utf16Length() const { return utf16_length_; }
+
+ protected:
+  // This reads all characters and sets the utf16_length_.
+  // The first buffer_length utf16 chars are cached in the buffer.
+  void Reset(uint16_t* buffer, unsigned buffer_length, const uint8_t* stream,
+             unsigned stream_length);
+  static void WriteUtf16Slow(const uint8_t* stream, uint16_t* data,
+                             unsigned length);
+  const uint8_t* unbuffered_start_;
+  unsigned utf16_length_;
+  bool last_byte_of_buffer_unused_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Utf8DecoderBase);
+};
+
+template <unsigned kBufferSize>
+class Utf8Decoder : public Utf8DecoderBase {
+ public:
+  inline Utf8Decoder() {}
+  inline Utf8Decoder(const char* stream, unsigned length);
+  inline void Reset(const char* stream, unsigned length);
+  inline unsigned WriteUtf16(uint16_t* data, unsigned length) const;
+
+ private:
+  uint16_t buffer_[kBufferSize];
+};
+
+
+Utf8DecoderBase::Utf8DecoderBase()
+    : unbuffered_start_(NULL),
+      utf16_length_(0),
+      last_byte_of_buffer_unused_(false) {}
+
+
+Utf8DecoderBase::Utf8DecoderBase(uint16_t* buffer, unsigned buffer_length,
+                                 const uint8_t* stream,
+                                 unsigned stream_length) {
+  Reset(buffer, buffer_length, stream, stream_length);
+}
+
+
+template <unsigned kBufferSize>
+Utf8Decoder<kBufferSize>::Utf8Decoder(const char* stream, unsigned length)
+    : Utf8DecoderBase(buffer_, kBufferSize,
+                      reinterpret_cast<const uint8_t*>(stream), length) {}
+
+
+template <unsigned kBufferSize>
+void Utf8Decoder<kBufferSize>::Reset(const char* stream, unsigned length) {
+  Utf8DecoderBase::Reset(buffer_, kBufferSize,
+                         reinterpret_cast<const uint8_t*>(stream), length);
+}
+
+
+template <unsigned kBufferSize>
+unsigned Utf8Decoder<kBufferSize>::WriteUtf16(uint16_t* data,
+                                              unsigned length) const {
+  DCHECK(length > 0);
+  if (length > utf16_length_) length = utf16_length_;
+  // memcpy everything in buffer.
+  unsigned buffer_length =
+      last_byte_of_buffer_unused_ ? kBufferSize - 1 : kBufferSize;
+  unsigned memcpy_length = length <= buffer_length ? length : buffer_length;
+  v8::internal::MemCopy(data, buffer_, memcpy_length * sizeof(uint16_t));
+  if (length <= buffer_length) return length;
+  DCHECK(unbuffered_start_ != NULL);
+  // Copy the rest the slow way.
+  WriteUtf16Slow(unbuffered_start_, data + buffer_length,
+                 length - buffer_length);
+  return length;
+}
+
+class Latin1 {
+ public:
+  static const unsigned kMaxChar = 0xff;
+  // Returns 0 if character does not convert to single latin-1 character
+  // or if the character doesn't not convert back to latin-1 via inverse
+  // operation (upper to lower, etc).
+  static inline uint16_t ConvertNonLatin1ToLatin1(uint16_t);
+};
+
+
+uint16_t Latin1::ConvertNonLatin1ToLatin1(uint16_t c) {
+  DCHECK(c > Latin1::kMaxChar);
+  switch (c) {
+    // This are equivalent characters in unicode.
+    case 0x39c:
+    case 0x3bc:
+      return 0xb5;
+    // This is an uppercase of a Latin-1 character
+    // outside of Latin-1.
+    case 0x178:
+      return 0xff;
+  }
+  return 0;
+}
+
+
+}  // namespace unibrow
+
+#endif  // V8_UNICODE_DECODER_H_
diff --git a/src/unicode-inl.h b/src/unicode-inl.h
index 81327d7..0f78d39 100644
--- a/src/unicode-inl.h
+++ b/src/unicode-inl.h
@@ -13,7 +13,7 @@
 
 template <class T, int s> bool Predicate<T, s>::get(uchar code_point) {
   CacheEntry entry = entries_[code_point & kMask];
-  if (entry.code_point_ == code_point) return entry.value_;
+  if (entry.code_point() == code_point) return entry.value();
   return CalculateValue(code_point);
 }
 
@@ -57,22 +57,6 @@
 }
 
 
-uint16_t Latin1::ConvertNonLatin1ToLatin1(uint16_t c) {
-  DCHECK(c > Latin1::kMaxChar);
-  switch (c) {
-    // This are equivalent characters in unicode.
-    case 0x39c:
-    case 0x3bc:
-      return 0xb5;
-    // This is an uppercase of a Latin-1 character
-    // outside of Latin-1.
-    case 0x178:
-      return 0xff;
-  }
-  return 0;
-}
-
-
 unsigned Utf8::EncodeOneByte(char* str, uint8_t c) {
   static const int kMask = ~(1 << 6);
   if (c <= kMaxOneByteChar) {
@@ -153,53 +137,6 @@
   }
 }
 
-Utf8DecoderBase::Utf8DecoderBase()
-  : unbuffered_start_(NULL),
-    utf16_length_(0),
-    last_byte_of_buffer_unused_(false) {}
-
-Utf8DecoderBase::Utf8DecoderBase(uint16_t* buffer,
-                                 unsigned buffer_length,
-                                 const uint8_t* stream,
-                                 unsigned stream_length) {
-  Reset(buffer, buffer_length, stream, stream_length);
-}
-
-template<unsigned kBufferSize>
-Utf8Decoder<kBufferSize>::Utf8Decoder(const char* stream, unsigned length)
-  : Utf8DecoderBase(buffer_,
-                    kBufferSize,
-                    reinterpret_cast<const uint8_t*>(stream),
-                    length) {
-}
-
-template<unsigned kBufferSize>
-void Utf8Decoder<kBufferSize>::Reset(const char* stream, unsigned length) {
-  Utf8DecoderBase::Reset(buffer_,
-                         kBufferSize,
-                         reinterpret_cast<const uint8_t*>(stream),
-                         length);
-}
-
-template <unsigned kBufferSize>
-unsigned Utf8Decoder<kBufferSize>::WriteUtf16(uint16_t* data,
-                                              unsigned length) const {
-  DCHECK(length > 0);
-  if (length > utf16_length_) length = utf16_length_;
-  // memcpy everything in buffer.
-  unsigned buffer_length =
-      last_byte_of_buffer_unused_ ? kBufferSize - 1 : kBufferSize;
-  unsigned memcpy_length = length <= buffer_length ? length : buffer_length;
-  v8::internal::MemCopy(data, buffer_, memcpy_length * sizeof(uint16_t));
-  if (length <= buffer_length) return length;
-  DCHECK(unbuffered_start_ != NULL);
-  // Copy the rest the slow way.
-  WriteUtf16Slow(unbuffered_start_,
-                 data + buffer_length,
-                 length - buffer_length);
-  return length;
-}
-
 }  // namespace unibrow
 
 #endif  // V8_UNICODE_INL_H_
diff --git a/src/unicode.cc b/src/unicode.cc
index a128a6f..26a336a 100644
--- a/src/unicode.cc
+++ b/src/unicode.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
-// This file was generated at 2014-02-07 15:31:16.733174
+// This file was generated at 2014-10-08 15:25:47.940335
 
 #include "src/unicode-inl.h"
 #include <stdio.h>
@@ -23,6 +23,7 @@
 typedef unsigned short uint16_t;  // NOLINT
 typedef int int32_t;  // NOLINT
 
+
 // All access to the character table should go through this function.
 template <int D>
 static inline uchar TableGet(const int32_t* table, int index) {
@@ -188,6 +189,7 @@
   }
 }
 
+
 uchar Utf8::CalculateValue(const byte* str,
                            unsigned length,
                            unsigned* cursor) {
@@ -258,136 +260,124 @@
 }
 
 
-void Utf8DecoderBase::Reset(uint16_t* buffer,
-                            unsigned buffer_length,
-                            const uint8_t* stream,
-                            unsigned stream_length) {
-  // Assume everything will fit in the buffer and stream won't be needed.
-  last_byte_of_buffer_unused_ = false;
-  unbuffered_start_ = NULL;
-  bool writing_to_buffer = true;
-  // Loop until stream is read, writing to buffer as long as buffer has space.
-  unsigned utf16_length = 0;
-  while (stream_length != 0) {
-    unsigned cursor = 0;
-    uint32_t character = Utf8::ValueOf(stream, stream_length, &cursor);
-    DCHECK(cursor > 0 && cursor <= stream_length);
-    stream += cursor;
-    stream_length -= cursor;
-    bool is_two_characters = character > Utf16::kMaxNonSurrogateCharCode;
-    utf16_length += is_two_characters ? 2 : 1;
-    // Don't need to write to the buffer, but still need utf16_length.
-    if (!writing_to_buffer) continue;
-    // Write out the characters to the buffer.
-    // Must check for equality with buffer_length as we've already updated it.
-    if (utf16_length <= buffer_length) {
-      if (is_two_characters) {
-        *buffer++ = Utf16::LeadSurrogate(character);
-        *buffer++ = Utf16::TrailSurrogate(character);
-      } else {
-        *buffer++ = character;
-      }
-      if (utf16_length == buffer_length) {
-        // Just wrote last character of buffer
-        writing_to_buffer = false;
-        unbuffered_start_ = stream;
-      }
-      continue;
-    }
-    // Have gone over buffer.
-    // Last char of buffer is unused, set cursor back.
-    DCHECK(is_two_characters);
-    writing_to_buffer = false;
-    last_byte_of_buffer_unused_ = true;
-    unbuffered_start_ = stream - cursor;
-  }
-  utf16_length_ = utf16_length;
-}
-
-
-void Utf8DecoderBase::WriteUtf16Slow(const uint8_t* stream,
-                                     uint16_t* data,
-                                     unsigned data_length) {
-  while (data_length != 0) {
-    unsigned cursor = 0;
-    uint32_t character = Utf8::ValueOf(stream, Utf8::kMaxEncodedSize, &cursor);
-    // There's a total lack of bounds checking for stream
-    // as it was already done in Reset.
-    stream += cursor;
-    if (character > unibrow::Utf16::kMaxNonSurrogateCharCode) {
-      *data++ = Utf16::LeadSurrogate(character);
-      *data++ = Utf16::TrailSurrogate(character);
-      DCHECK(data_length > 1);
-      data_length -= 2;
-    } else {
-      *data++ = character;
-      data_length -= 1;
-    }
-  }
-}
-
-
 // Uppercase:            point.category == 'Lu'
 
-static const uint16_t kUppercaseTable0Size = 450;
-static const int32_t kUppercaseTable0[450] = {
-  1073741889, 90, 1073742016, 214, 1073742040, 222, 256, 258,  // NOLINT
-  260, 262, 264, 266, 268, 270, 272, 274,  // NOLINT
-  276, 278, 280, 282, 284, 286, 288, 290,  // NOLINT
-  292, 294, 296, 298, 300, 302, 304, 306,  // NOLINT
-  308, 310, 313, 315, 317, 319, 321, 323,  // NOLINT
-  325, 327, 330, 332, 334, 336, 338, 340,  // NOLINT
-  342, 344, 346, 348, 350, 352, 354, 356,  // NOLINT
-  358, 360, 362, 364, 366, 368, 370, 372,  // NOLINT
-  374, 1073742200, 377, 379, 381, 1073742209, 386, 388,  // NOLINT
-  1073742214, 391, 1073742217, 395, 1073742222, 401, 1073742227, 404,  // NOLINT
-  1073742230, 408, 1073742236, 413, 1073742239, 416, 418, 420,  // NOLINT
-  1073742246, 423, 425, 428, 1073742254, 431, 1073742257, 435,  // NOLINT
-  437, 1073742263, 440, 444, 452, 455, 458, 461,  // NOLINT
-  463, 465, 467, 469, 471, 473, 475, 478,  // NOLINT
-  480, 482, 484, 486, 488, 490, 492, 494,  // NOLINT
-  497, 500, 1073742326, 504, 506, 508, 510, 512,  // NOLINT
-  514, 516, 518, 520, 522, 524, 526, 528,  // NOLINT
-  530, 532, 534, 536, 538, 540, 542, 544,  // NOLINT
-  546, 548, 550, 552, 554, 556, 558, 560,  // NOLINT
-  562, 1073742394, 571, 1073742397, 574, 577, 1073742403, 582,  // NOLINT
-  584, 586, 588, 590, 880, 882, 886, 902,  // NOLINT
-  1073742728, 906, 908, 1073742734, 911, 1073742737, 929, 1073742755,  // NOLINT
-  939, 975, 1073742802, 980, 984, 986, 988, 990,  // NOLINT
-  992, 994, 996, 998, 1000, 1002, 1004, 1006,  // NOLINT
-  1012, 1015, 1073742841, 1018, 1073742845, 1071, 1120, 1122,  // NOLINT
-  1124, 1126, 1128, 1130, 1132, 1134, 1136, 1138,  // NOLINT
-  1140, 1142, 1144, 1146, 1148, 1150, 1152, 1162,  // NOLINT
-  1164, 1166, 1168, 1170, 1172, 1174, 1176, 1178,  // NOLINT
-  1180, 1182, 1184, 1186, 1188, 1190, 1192, 1194,  // NOLINT
-  1196, 1198, 1200, 1202, 1204, 1206, 1208, 1210,  // NOLINT
-  1212, 1214, 1073743040, 1217, 1219, 1221, 1223, 1225,  // NOLINT
-  1227, 1229, 1232, 1234, 1236, 1238, 1240, 1242,  // NOLINT
-  1244, 1246, 1248, 1250, 1252, 1254, 1256, 1258,  // NOLINT
-  1260, 1262, 1264, 1266, 1268, 1270, 1272, 1274,  // NOLINT
-  1276, 1278, 1280, 1282, 1284, 1286, 1288, 1290,  // NOLINT
-  1292, 1294, 1296, 1298, 1300, 1302, 1304, 1306,  // NOLINT
-  1308, 1310, 1312, 1314, 1316, 1318, 1073743153, 1366,  // NOLINT
-  1073746080, 4293, 4295, 4301, 7680, 7682, 7684, 7686,  // NOLINT
-  7688, 7690, 7692, 7694, 7696, 7698, 7700, 7702,  // NOLINT
-  7704, 7706, 7708, 7710, 7712, 7714, 7716, 7718,  // NOLINT
-  7720, 7722, 7724, 7726, 7728, 7730, 7732, 7734,  // NOLINT
-  7736, 7738, 7740, 7742, 7744, 7746, 7748, 7750,  // NOLINT
-  7752, 7754, 7756, 7758, 7760, 7762, 7764, 7766,  // NOLINT
-  7768, 7770, 7772, 7774, 7776, 7778, 7780, 7782,  // NOLINT
-  7784, 7786, 7788, 7790, 7792, 7794, 7796, 7798,  // NOLINT
-  7800, 7802, 7804, 7806, 7808, 7810, 7812, 7814,  // NOLINT
-  7816, 7818, 7820, 7822, 7824, 7826, 7828, 7838,  // NOLINT
-  7840, 7842, 7844, 7846, 7848, 7850, 7852, 7854,  // NOLINT
-  7856, 7858, 7860, 7862, 7864, 7866, 7868, 7870,  // NOLINT
-  7872, 7874, 7876, 7878, 7880, 7882, 7884, 7886,  // NOLINT
-  7888, 7890, 7892, 7894, 7896, 7898, 7900, 7902,  // NOLINT
-  7904, 7906, 7908, 7910, 7912, 7914, 7916, 7918,  // NOLINT
-  7920, 7922, 7924, 7926, 7928, 7930, 7932, 7934,  // NOLINT
-  1073749768, 7951, 1073749784, 7965, 1073749800, 7983, 1073749816, 7999,  // NOLINT
-  1073749832, 8013, 8025, 8027, 8029, 8031, 1073749864, 8047,  // NOLINT
-  1073749944, 8123, 1073749960, 8139, 1073749976, 8155, 1073749992, 8172,  // NOLINT
-  1073750008, 8187 };  // NOLINT
+static const uint16_t kUppercaseTable0Size = 455;
+static const int32_t kUppercaseTable0[455] = {
+    1073741889, 90,         1073742016, 214,
+    1073742040, 222,        256,        258,  // NOLINT
+    260,        262,        264,        266,
+    268,        270,        272,        274,  // NOLINT
+    276,        278,        280,        282,
+    284,        286,        288,        290,  // NOLINT
+    292,        294,        296,        298,
+    300,        302,        304,        306,  // NOLINT
+    308,        310,        313,        315,
+    317,        319,        321,        323,  // NOLINT
+    325,        327,        330,        332,
+    334,        336,        338,        340,  // NOLINT
+    342,        344,        346,        348,
+    350,        352,        354,        356,  // NOLINT
+    358,        360,        362,        364,
+    366,        368,        370,        372,  // NOLINT
+    374,        1073742200, 377,        379,
+    381,        1073742209, 386,        388,  // NOLINT
+    1073742214, 391,        1073742217, 395,
+    1073742222, 401,        1073742227, 404,  // NOLINT
+    1073742230, 408,        1073742236, 413,
+    1073742239, 416,        418,        420,  // NOLINT
+    1073742246, 423,        425,        428,
+    1073742254, 431,        1073742257, 435,  // NOLINT
+    437,        1073742263, 440,        444,
+    452,        455,        458,        461,  // NOLINT
+    463,        465,        467,        469,
+    471,        473,        475,        478,  // NOLINT
+    480,        482,        484,        486,
+    488,        490,        492,        494,  // NOLINT
+    497,        500,        1073742326, 504,
+    506,        508,        510,        512,  // NOLINT
+    514,        516,        518,        520,
+    522,        524,        526,        528,  // NOLINT
+    530,        532,        534,        536,
+    538,        540,        542,        544,  // NOLINT
+    546,        548,        550,        552,
+    554,        556,        558,        560,  // NOLINT
+    562,        1073742394, 571,        1073742397,
+    574,        577,        1073742403, 582,  // NOLINT
+    584,        586,        588,        590,
+    880,        882,        886,        895,  // NOLINT
+    902,        1073742728, 906,        908,
+    1073742734, 911,        1073742737, 929,  // NOLINT
+    1073742755, 939,        975,        1073742802,
+    980,        984,        986,        988,  // NOLINT
+    990,        992,        994,        996,
+    998,        1000,       1002,       1004,  // NOLINT
+    1006,       1012,       1015,       1073742841,
+    1018,       1073742845, 1071,       1120,  // NOLINT
+    1122,       1124,       1126,       1128,
+    1130,       1132,       1134,       1136,  // NOLINT
+    1138,       1140,       1142,       1144,
+    1146,       1148,       1150,       1152,  // NOLINT
+    1162,       1164,       1166,       1168,
+    1170,       1172,       1174,       1176,  // NOLINT
+    1178,       1180,       1182,       1184,
+    1186,       1188,       1190,       1192,  // NOLINT
+    1194,       1196,       1198,       1200,
+    1202,       1204,       1206,       1208,  // NOLINT
+    1210,       1212,       1214,       1073743040,
+    1217,       1219,       1221,       1223,  // NOLINT
+    1225,       1227,       1229,       1232,
+    1234,       1236,       1238,       1240,  // NOLINT
+    1242,       1244,       1246,       1248,
+    1250,       1252,       1254,       1256,  // NOLINT
+    1258,       1260,       1262,       1264,
+    1266,       1268,       1270,       1272,  // NOLINT
+    1274,       1276,       1278,       1280,
+    1282,       1284,       1286,       1288,  // NOLINT
+    1290,       1292,       1294,       1296,
+    1298,       1300,       1302,       1304,  // NOLINT
+    1306,       1308,       1310,       1312,
+    1314,       1316,       1318,       1320,  // NOLINT
+    1322,       1324,       1326,       1073743153,
+    1366,       1073746080, 4293,       4295,  // NOLINT
+    4301,       7680,       7682,       7684,
+    7686,       7688,       7690,       7692,  // NOLINT
+    7694,       7696,       7698,       7700,
+    7702,       7704,       7706,       7708,  // NOLINT
+    7710,       7712,       7714,       7716,
+    7718,       7720,       7722,       7724,  // NOLINT
+    7726,       7728,       7730,       7732,
+    7734,       7736,       7738,       7740,  // NOLINT
+    7742,       7744,       7746,       7748,
+    7750,       7752,       7754,       7756,  // NOLINT
+    7758,       7760,       7762,       7764,
+    7766,       7768,       7770,       7772,  // NOLINT
+    7774,       7776,       7778,       7780,
+    7782,       7784,       7786,       7788,  // NOLINT
+    7790,       7792,       7794,       7796,
+    7798,       7800,       7802,       7804,  // NOLINT
+    7806,       7808,       7810,       7812,
+    7814,       7816,       7818,       7820,  // NOLINT
+    7822,       7824,       7826,       7828,
+    7838,       7840,       7842,       7844,  // NOLINT
+    7846,       7848,       7850,       7852,
+    7854,       7856,       7858,       7860,  // NOLINT
+    7862,       7864,       7866,       7868,
+    7870,       7872,       7874,       7876,  // NOLINT
+    7878,       7880,       7882,       7884,
+    7886,       7888,       7890,       7892,  // NOLINT
+    7894,       7896,       7898,       7900,
+    7902,       7904,       7906,       7908,  // NOLINT
+    7910,       7912,       7914,       7916,
+    7918,       7920,       7922,       7924,  // NOLINT
+    7926,       7928,       7930,       7932,
+    7934,       1073749768, 7951,       1073749784,  // NOLINT
+    7965,       1073749800, 7983,       1073749816,
+    7999,       1073749832, 8013,       8025,  // NOLINT
+    8027,       8029,       8031,       1073749864,
+    8047,       1073749944, 8123,       1073749960,  // NOLINT
+    8139,       1073749976, 8155,       1073749992,
+    8172,       1073750008, 8187};  // NOLINT
 static const uint16_t kUppercaseTable1Size = 86;
 static const int32_t kUppercaseTable1[86] = {
   258, 263, 1073742091, 269, 1073742096, 274, 277, 1073742105,  // NOLINT
@@ -401,20 +391,21 @@
   3262, 3264, 3266, 3268, 3270, 3272, 3274, 3276,  // NOLINT
   3278, 3280, 3282, 3284, 3286, 3288, 3290, 3292,  // NOLINT
   3294, 3296, 3298, 3307, 3309, 3314 };  // NOLINT
-static const uint16_t kUppercaseTable5Size = 91;
-static const int32_t kUppercaseTable5[91] = {
-  1600, 1602, 1604, 1606, 1608, 1610, 1612, 1614,  // NOLINT
-  1616, 1618, 1620, 1622, 1624, 1626, 1628, 1630,  // NOLINT
-  1632, 1634, 1636, 1638, 1640, 1642, 1644, 1664,  // NOLINT
-  1666, 1668, 1670, 1672, 1674, 1676, 1678, 1680,  // NOLINT
-  1682, 1684, 1686, 1826, 1828, 1830, 1832, 1834,  // NOLINT
-  1836, 1838, 1842, 1844, 1846, 1848, 1850, 1852,  // NOLINT
-  1854, 1856, 1858, 1860, 1862, 1864, 1866, 1868,  // NOLINT
-  1870, 1872, 1874, 1876, 1878, 1880, 1882, 1884,  // NOLINT
-  1886, 1888, 1890, 1892, 1894, 1896, 1898, 1900,  // NOLINT
-  1902, 1913, 1915, 1073743741, 1918, 1920, 1922, 1924,  // NOLINT
-  1926, 1931, 1933, 1936, 1938, 1952, 1954, 1956,  // NOLINT
-  1958, 1960, 1962 };  // NOLINT
+static const uint16_t kUppercaseTable5Size = 101;
+static const int32_t kUppercaseTable5[101] = {
+    1600, 1602,       1604, 1606,       1608, 1610,       1612, 1614,  // NOLINT
+    1616, 1618,       1620, 1622,       1624, 1626,       1628, 1630,  // NOLINT
+    1632, 1634,       1636, 1638,       1640, 1642,       1644, 1664,  // NOLINT
+    1666, 1668,       1670, 1672,       1674, 1676,       1678, 1680,  // NOLINT
+    1682, 1684,       1686, 1688,       1690, 1826,       1828, 1830,  // NOLINT
+    1832, 1834,       1836, 1838,       1842, 1844,       1846, 1848,  // NOLINT
+    1850, 1852,       1854, 1856,       1858, 1860,       1862, 1864,  // NOLINT
+    1866, 1868,       1870, 1872,       1874, 1876,       1878, 1880,  // NOLINT
+    1882, 1884,       1886, 1888,       1890, 1892,       1894, 1896,  // NOLINT
+    1898, 1900,       1902, 1913,       1915, 1073743741, 1918, 1920,  // NOLINT
+    1922, 1924,       1926, 1931,       1933, 1936,       1938, 1942,  // NOLINT
+    1944, 1946,       1948, 1950,       1952, 1954,       1956, 1958,  // NOLINT
+    1960, 1073743786, 1965, 1073743792, 1969};                         // NOLINT
 static const uint16_t kUppercaseTable7Size = 2;
 static const int32_t kUppercaseTable7[2] = {
   1073749793, 7994 };  // NOLINT
@@ -440,66 +431,125 @@
 
 // Lowercase:            point.category == 'Ll'
 
-static const uint16_t kLowercaseTable0Size = 463;
-static const int32_t kLowercaseTable0[463] = {
-  1073741921, 122, 181, 1073742047, 246, 1073742072, 255, 257,  // NOLINT
-  259, 261, 263, 265, 267, 269, 271, 273,  // NOLINT
-  275, 277, 279, 281, 283, 285, 287, 289,  // NOLINT
-  291, 293, 295, 297, 299, 301, 303, 305,  // NOLINT
-  307, 309, 1073742135, 312, 314, 316, 318, 320,  // NOLINT
-  322, 324, 326, 1073742152, 329, 331, 333, 335,  // NOLINT
-  337, 339, 341, 343, 345, 347, 349, 351,  // NOLINT
-  353, 355, 357, 359, 361, 363, 365, 367,  // NOLINT
-  369, 371, 373, 375, 378, 380, 1073742206, 384,  // NOLINT
-  387, 389, 392, 1073742220, 397, 402, 405, 1073742233,  // NOLINT
-  411, 414, 417, 419, 421, 424, 1073742250, 427,  // NOLINT
-  429, 432, 436, 438, 1073742265, 442, 1073742269, 447,  // NOLINT
-  454, 457, 460, 462, 464, 466, 468, 470,  // NOLINT
-  472, 474, 1073742300, 477, 479, 481, 483, 485,  // NOLINT
-  487, 489, 491, 493, 1073742319, 496, 499, 501,  // NOLINT
-  505, 507, 509, 511, 513, 515, 517, 519,  // NOLINT
-  521, 523, 525, 527, 529, 531, 533, 535,  // NOLINT
-  537, 539, 541, 543, 545, 547, 549, 551,  // NOLINT
-  553, 555, 557, 559, 561, 1073742387, 569, 572,  // NOLINT
-  1073742399, 576, 578, 583, 585, 587, 589, 1073742415,  // NOLINT
-  659, 1073742485, 687, 881, 883, 887, 1073742715, 893,  // NOLINT
-  912, 1073742764, 974, 1073742800, 977, 1073742805, 983, 985,  // NOLINT
-  987, 989, 991, 993, 995, 997, 999, 1001,  // NOLINT
-  1003, 1005, 1073742831, 1011, 1013, 1016, 1073742843, 1020,  // NOLINT
-  1073742896, 1119, 1121, 1123, 1125, 1127, 1129, 1131,  // NOLINT
-  1133, 1135, 1137, 1139, 1141, 1143, 1145, 1147,  // NOLINT
-  1149, 1151, 1153, 1163, 1165, 1167, 1169, 1171,  // NOLINT
-  1173, 1175, 1177, 1179, 1181, 1183, 1185, 1187,  // NOLINT
-  1189, 1191, 1193, 1195, 1197, 1199, 1201, 1203,  // NOLINT
-  1205, 1207, 1209, 1211, 1213, 1215, 1218, 1220,  // NOLINT
-  1222, 1224, 1226, 1228, 1073743054, 1231, 1233, 1235,  // NOLINT
-  1237, 1239, 1241, 1243, 1245, 1247, 1249, 1251,  // NOLINT
-  1253, 1255, 1257, 1259, 1261, 1263, 1265, 1267,  // NOLINT
-  1269, 1271, 1273, 1275, 1277, 1279, 1281, 1283,  // NOLINT
-  1285, 1287, 1289, 1291, 1293, 1295, 1297, 1299,  // NOLINT
-  1301, 1303, 1305, 1307, 1309, 1311, 1313, 1315,  // NOLINT
-  1317, 1319, 1073743201, 1415, 1073749248, 7467, 1073749355, 7543,  // NOLINT
-  1073749369, 7578, 7681, 7683, 7685, 7687, 7689, 7691,  // NOLINT
-  7693, 7695, 7697, 7699, 7701, 7703, 7705, 7707,  // NOLINT
-  7709, 7711, 7713, 7715, 7717, 7719, 7721, 7723,  // NOLINT
-  7725, 7727, 7729, 7731, 7733, 7735, 7737, 7739,  // NOLINT
-  7741, 7743, 7745, 7747, 7749, 7751, 7753, 7755,  // NOLINT
-  7757, 7759, 7761, 7763, 7765, 7767, 7769, 7771,  // NOLINT
-  7773, 7775, 7777, 7779, 7781, 7783, 7785, 7787,  // NOLINT
-  7789, 7791, 7793, 7795, 7797, 7799, 7801, 7803,  // NOLINT
-  7805, 7807, 7809, 7811, 7813, 7815, 7817, 7819,  // NOLINT
-  7821, 7823, 7825, 7827, 1073749653, 7837, 7839, 7841,  // NOLINT
-  7843, 7845, 7847, 7849, 7851, 7853, 7855, 7857,  // NOLINT
-  7859, 7861, 7863, 7865, 7867, 7869, 7871, 7873,  // NOLINT
-  7875, 7877, 7879, 7881, 7883, 7885, 7887, 7889,  // NOLINT
-  7891, 7893, 7895, 7897, 7899, 7901, 7903, 7905,  // NOLINT
-  7907, 7909, 7911, 7913, 7915, 7917, 7919, 7921,  // NOLINT
-  7923, 7925, 7927, 7929, 7931, 7933, 1073749759, 7943,  // NOLINT
-  1073749776, 7957, 1073749792, 7975, 1073749808, 7991, 1073749824, 8005,  // NOLINT
-  1073749840, 8023, 1073749856, 8039, 1073749872, 8061, 1073749888, 8071,  // NOLINT
-  1073749904, 8087, 1073749920, 8103, 1073749936, 8116, 1073749942, 8119,  // NOLINT
-  8126, 1073749954, 8132, 1073749958, 8135, 1073749968, 8147, 1073749974,  // NOLINT
-  8151, 1073749984, 8167, 1073750002, 8180, 1073750006, 8183 };  // NOLINT
+static const uint16_t kLowercaseTable0Size = 467;
+static const int32_t kLowercaseTable0[467] = {
+    1073741921, 122,        181,        1073742047,
+    246,        1073742072, 255,        257,  // NOLINT
+    259,        261,        263,        265,
+    267,        269,        271,        273,  // NOLINT
+    275,        277,        279,        281,
+    283,        285,        287,        289,  // NOLINT
+    291,        293,        295,        297,
+    299,        301,        303,        305,  // NOLINT
+    307,        309,        1073742135, 312,
+    314,        316,        318,        320,  // NOLINT
+    322,        324,        326,        1073742152,
+    329,        331,        333,        335,  // NOLINT
+    337,        339,        341,        343,
+    345,        347,        349,        351,  // NOLINT
+    353,        355,        357,        359,
+    361,        363,        365,        367,  // NOLINT
+    369,        371,        373,        375,
+    378,        380,        1073742206, 384,  // NOLINT
+    387,        389,        392,        1073742220,
+    397,        402,        405,        1073742233,  // NOLINT
+    411,        414,        417,        419,
+    421,        424,        1073742250, 427,  // NOLINT
+    429,        432,        436,        438,
+    1073742265, 442,        1073742269, 447,  // NOLINT
+    454,        457,        460,        462,
+    464,        466,        468,        470,  // NOLINT
+    472,        474,        1073742300, 477,
+    479,        481,        483,        485,  // NOLINT
+    487,        489,        491,        493,
+    1073742319, 496,        499,        501,  // NOLINT
+    505,        507,        509,        511,
+    513,        515,        517,        519,  // NOLINT
+    521,        523,        525,        527,
+    529,        531,        533,        535,  // NOLINT
+    537,        539,        541,        543,
+    545,        547,        549,        551,  // NOLINT
+    553,        555,        557,        559,
+    561,        1073742387, 569,        572,  // NOLINT
+    1073742399, 576,        578,        583,
+    585,        587,        589,        1073742415,  // NOLINT
+    659,        1073742485, 687,        881,
+    883,        887,        1073742715, 893,  // NOLINT
+    912,        1073742764, 974,        1073742800,
+    977,        1073742805, 983,        985,  // NOLINT
+    987,        989,        991,        993,
+    995,        997,        999,        1001,  // NOLINT
+    1003,       1005,       1073742831, 1011,
+    1013,       1016,       1073742843, 1020,  // NOLINT
+    1073742896, 1119,       1121,       1123,
+    1125,       1127,       1129,       1131,  // NOLINT
+    1133,       1135,       1137,       1139,
+    1141,       1143,       1145,       1147,  // NOLINT
+    1149,       1151,       1153,       1163,
+    1165,       1167,       1169,       1171,  // NOLINT
+    1173,       1175,       1177,       1179,
+    1181,       1183,       1185,       1187,  // NOLINT
+    1189,       1191,       1193,       1195,
+    1197,       1199,       1201,       1203,  // NOLINT
+    1205,       1207,       1209,       1211,
+    1213,       1215,       1218,       1220,  // NOLINT
+    1222,       1224,       1226,       1228,
+    1073743054, 1231,       1233,       1235,  // NOLINT
+    1237,       1239,       1241,       1243,
+    1245,       1247,       1249,       1251,  // NOLINT
+    1253,       1255,       1257,       1259,
+    1261,       1263,       1265,       1267,  // NOLINT
+    1269,       1271,       1273,       1275,
+    1277,       1279,       1281,       1283,  // NOLINT
+    1285,       1287,       1289,       1291,
+    1293,       1295,       1297,       1299,  // NOLINT
+    1301,       1303,       1305,       1307,
+    1309,       1311,       1313,       1315,  // NOLINT
+    1317,       1319,       1321,       1323,
+    1325,       1327,       1073743201, 1415,  // NOLINT
+    1073749248, 7467,       1073749355, 7543,
+    1073749369, 7578,       7681,       7683,  // NOLINT
+    7685,       7687,       7689,       7691,
+    7693,       7695,       7697,       7699,  // NOLINT
+    7701,       7703,       7705,       7707,
+    7709,       7711,       7713,       7715,  // NOLINT
+    7717,       7719,       7721,       7723,
+    7725,       7727,       7729,       7731,  // NOLINT
+    7733,       7735,       7737,       7739,
+    7741,       7743,       7745,       7747,  // NOLINT
+    7749,       7751,       7753,       7755,
+    7757,       7759,       7761,       7763,  // NOLINT
+    7765,       7767,       7769,       7771,
+    7773,       7775,       7777,       7779,  // NOLINT
+    7781,       7783,       7785,       7787,
+    7789,       7791,       7793,       7795,  // NOLINT
+    7797,       7799,       7801,       7803,
+    7805,       7807,       7809,       7811,  // NOLINT
+    7813,       7815,       7817,       7819,
+    7821,       7823,       7825,       7827,  // NOLINT
+    1073749653, 7837,       7839,       7841,
+    7843,       7845,       7847,       7849,  // NOLINT
+    7851,       7853,       7855,       7857,
+    7859,       7861,       7863,       7865,  // NOLINT
+    7867,       7869,       7871,       7873,
+    7875,       7877,       7879,       7881,  // NOLINT
+    7883,       7885,       7887,       7889,
+    7891,       7893,       7895,       7897,  // NOLINT
+    7899,       7901,       7903,       7905,
+    7907,       7909,       7911,       7913,  // NOLINT
+    7915,       7917,       7919,       7921,
+    7923,       7925,       7927,       7929,  // NOLINT
+    7931,       7933,       1073749759, 7943,
+    1073749776, 7957,       1073749792, 7975,  // NOLINT
+    1073749808, 7991,       1073749824, 8005,
+    1073749840, 8023,       1073749856, 8039,  // NOLINT
+    1073749872, 8061,       1073749888, 8071,
+    1073749904, 8087,       1073749920, 8103,  // NOLINT
+    1073749936, 8116,       1073749942, 8119,
+    8126,       1073749954, 8132,       1073749958,  // NOLINT
+    8135,       1073749968, 8147,       1073749974,
+    8151,       1073749984, 8167,       1073750002,  // NOLINT
+    8180,       1073750006, 8183};                   // NOLINT
 static const uint16_t kLowercaseTable1Size = 84;
 static const int32_t kLowercaseTable1[84] = {
   266, 1073742094, 271, 275, 303, 308, 313, 1073742140,  // NOLINT
@@ -513,20 +563,35 @@
   3277, 3279, 3281, 3283, 3285, 3287, 3289, 3291,  // NOLINT
   3293, 3295, 3297, 1073745123, 3300, 3308, 3310, 3315,  // NOLINT
   1073745152, 3365, 3367, 3373 };  // NOLINT
-static const uint16_t kLowercaseTable5Size = 93;
-static const int32_t kLowercaseTable5[93] = {
-  1601, 1603, 1605, 1607, 1609, 1611, 1613, 1615,  // NOLINT
-  1617, 1619, 1621, 1623, 1625, 1627, 1629, 1631,  // NOLINT
-  1633, 1635, 1637, 1639, 1641, 1643, 1645, 1665,  // NOLINT
-  1667, 1669, 1671, 1673, 1675, 1677, 1679, 1681,  // NOLINT
-  1683, 1685, 1687, 1827, 1829, 1831, 1833, 1835,  // NOLINT
-  1837, 1073743663, 1841, 1843, 1845, 1847, 1849, 1851,  // NOLINT
-  1853, 1855, 1857, 1859, 1861, 1863, 1865, 1867,  // NOLINT
-  1869, 1871, 1873, 1875, 1877, 1879, 1881, 1883,  // NOLINT
-  1885, 1887, 1889, 1891, 1893, 1895, 1897, 1899,  // NOLINT
-  1901, 1903, 1073743729, 1912, 1914, 1916, 1919, 1921,  // NOLINT
-  1923, 1925, 1927, 1932, 1934, 1937, 1939, 1953,  // NOLINT
-  1955, 1957, 1959, 1961, 2042 };  // NOLINT
+static const uint16_t kLowercaseTable5Size = 105;
+static const int32_t kLowercaseTable5[105] = {
+    1601,       1603,       1605, 1607,
+    1609,       1611,       1613, 1615,  // NOLINT
+    1617,       1619,       1621, 1623,
+    1625,       1627,       1629, 1631,  // NOLINT
+    1633,       1635,       1637, 1639,
+    1641,       1643,       1645, 1665,  // NOLINT
+    1667,       1669,       1671, 1673,
+    1675,       1677,       1679, 1681,  // NOLINT
+    1683,       1685,       1687, 1689,
+    1691,       1827,       1829, 1831,  // NOLINT
+    1833,       1835,       1837, 1073743663,
+    1841,       1843,       1845, 1847,  // NOLINT
+    1849,       1851,       1853, 1855,
+    1857,       1859,       1861, 1863,  // NOLINT
+    1865,       1867,       1869, 1871,
+    1873,       1875,       1877, 1879,  // NOLINT
+    1881,       1883,       1885, 1887,
+    1889,       1891,       1893, 1895,  // NOLINT
+    1897,       1899,       1901, 1903,
+    1073743729, 1912,       1914, 1916,  // NOLINT
+    1919,       1921,       1923, 1925,
+    1927,       1932,       1934, 1937,  // NOLINT
+    1073743763, 1941,       1943, 1945,
+    1947,       1949,       1951, 1953,  // NOLINT
+    1955,       1957,       1959, 1961,
+    2042,       1073744688, 2906, 1073744740,  // NOLINT
+    2917};                                     // NOLINT
 static const uint16_t kLowercaseTable7Size = 6;
 static const int32_t kLowercaseTable7[6] = {
   1073748736, 6918, 1073748755, 6935, 1073749825, 8026 };  // NOLINT
@@ -550,65 +615,118 @@
 }
 
 
-// Letter:               point.category in ['Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl' ]
+// Letter:               point.category in ['Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl']
 
-static const uint16_t kLetterTable0Size = 435;
-static const int32_t kLetterTable0[435] = {
-  1073741889, 90, 1073741921, 122, 170, 181, 186, 1073742016,  // NOLINT
-  214, 1073742040, 246, 1073742072, 705, 1073742534, 721, 1073742560,  // NOLINT
-  740, 748, 750, 1073742704, 884, 1073742710, 887, 1073742714,  // NOLINT
-  893, 902, 1073742728, 906, 908, 1073742734, 929, 1073742755,  // NOLINT
-  1013, 1073742839, 1153, 1073742986, 1319, 1073743153, 1366, 1369,  // NOLINT
-  1073743201, 1415, 1073743312, 1514, 1073743344, 1522, 1073743392, 1610,  // NOLINT
-  1073743470, 1647, 1073743473, 1747, 1749, 1073743589, 1766, 1073743598,  // NOLINT
-  1775, 1073743610, 1788, 1791, 1808, 1073743634, 1839, 1073743693,  // NOLINT
-  1957, 1969, 1073743818, 2026, 1073743860, 2037, 2042, 1073743872,  // NOLINT
-  2069, 2074, 2084, 2088, 1073743936, 2136, 2208, 1073744034,  // NOLINT
-  2220, 1073744132, 2361, 2365, 2384, 1073744216, 2401, 1073744241,  // NOLINT
-  2423, 1073744249, 2431, 1073744261, 2444, 1073744271, 2448, 1073744275,  // NOLINT
-  2472, 1073744298, 2480, 2482, 1073744310, 2489, 2493, 2510,  // NOLINT
-  1073744348, 2525, 1073744351, 2529, 1073744368, 2545, 1073744389, 2570,  // NOLINT
-  1073744399, 2576, 1073744403, 2600, 1073744426, 2608, 1073744434, 2611,  // NOLINT
-  1073744437, 2614, 1073744440, 2617, 1073744473, 2652, 2654, 1073744498,  // NOLINT
-  2676, 1073744517, 2701, 1073744527, 2705, 1073744531, 2728, 1073744554,  // NOLINT
-  2736, 1073744562, 2739, 1073744565, 2745, 2749, 2768, 1073744608,  // NOLINT
-  2785, 1073744645, 2828, 1073744655, 2832, 1073744659, 2856, 1073744682,  // NOLINT
-  2864, 1073744690, 2867, 1073744693, 2873, 2877, 1073744732, 2909,  // NOLINT
-  1073744735, 2913, 2929, 2947, 1073744773, 2954, 1073744782, 2960,  // NOLINT
-  1073744786, 2965, 1073744793, 2970, 2972, 1073744798, 2975, 1073744803,  // NOLINT
-  2980, 1073744808, 2986, 1073744814, 3001, 3024, 1073744901, 3084,  // NOLINT
-  1073744910, 3088, 1073744914, 3112, 1073744938, 3123, 1073744949, 3129,  // NOLINT
-  3133, 1073744984, 3161, 1073744992, 3169, 1073745029, 3212, 1073745038,  // NOLINT
-  3216, 1073745042, 3240, 1073745066, 3251, 1073745077, 3257, 3261,  // NOLINT
-  3294, 1073745120, 3297, 1073745137, 3314, 1073745157, 3340, 1073745166,  // NOLINT
-  3344, 1073745170, 3386, 3389, 3406, 1073745248, 3425, 1073745274,  // NOLINT
-  3455, 1073745285, 3478, 1073745306, 3505, 1073745331, 3515, 3517,  // NOLINT
-  1073745344, 3526, 1073745409, 3632, 1073745458, 3635, 1073745472, 3654,  // NOLINT
-  1073745537, 3714, 3716, 1073745543, 3720, 3722, 3725, 1073745556,  // NOLINT
-  3735, 1073745561, 3743, 1073745569, 3747, 3749, 3751, 1073745578,  // NOLINT
-  3755, 1073745581, 3760, 1073745586, 3763, 3773, 1073745600, 3780,  // NOLINT
-  3782, 1073745628, 3807, 3840, 1073745728, 3911, 1073745737, 3948,  // NOLINT
-  1073745800, 3980, 1073745920, 4138, 4159, 1073746000, 4181, 1073746010,  // NOLINT
-  4189, 4193, 1073746021, 4198, 1073746030, 4208, 1073746037, 4225,  // NOLINT
-  4238, 1073746080, 4293, 4295, 4301, 1073746128, 4346, 1073746172,  // NOLINT
-  4680, 1073746506, 4685, 1073746512, 4694, 4696, 1073746522, 4701,  // NOLINT
-  1073746528, 4744, 1073746570, 4749, 1073746576, 4784, 1073746610, 4789,  // NOLINT
-  1073746616, 4798, 4800, 1073746626, 4805, 1073746632, 4822, 1073746648,  // NOLINT
-  4880, 1073746706, 4885, 1073746712, 4954, 1073746816, 5007, 1073746848,  // NOLINT
-  5108, 1073746945, 5740, 1073747567, 5759, 1073747585, 5786, 1073747616,  // NOLINT
-  5866, 1073747694, 5872, 1073747712, 5900, 1073747726, 5905, 1073747744,  // NOLINT
-  5937, 1073747776, 5969, 1073747808, 5996, 1073747822, 6000, 1073747840,  // NOLINT
-  6067, 6103, 6108, 1073748000, 6263, 1073748096, 6312, 6314,  // NOLINT
-  1073748144, 6389, 1073748224, 6428, 1073748304, 6509, 1073748336, 6516,  // NOLINT
-  1073748352, 6571, 1073748417, 6599, 1073748480, 6678, 1073748512, 6740,  // NOLINT
-  6823, 1073748741, 6963, 1073748805, 6987, 1073748867, 7072, 1073748910,  // NOLINT
-  7087, 1073748922, 7141, 1073748992, 7203, 1073749069, 7247, 1073749082,  // NOLINT
-  7293, 1073749225, 7404, 1073749230, 7409, 1073749237, 7414, 1073749248,  // NOLINT
-  7615, 1073749504, 7957, 1073749784, 7965, 1073749792, 8005, 1073749832,  // NOLINT
-  8013, 1073749840, 8023, 8025, 8027, 8029, 1073749855, 8061,  // NOLINT
-  1073749888, 8116, 1073749942, 8124, 8126, 1073749954, 8132, 1073749958,  // NOLINT
-  8140, 1073749968, 8147, 1073749974, 8155, 1073749984, 8172, 1073750002,  // NOLINT
-  8180, 1073750006, 8188 };  // NOLINT
+static const uint16_t kLetterTable0Size = 431;
+static const int32_t kLetterTable0[431] = {
+    1073741889, 90,         1073741921, 122,
+    170,        181,        186,        1073742016,  // NOLINT
+    214,        1073742040, 246,        1073742072,
+    705,        1073742534, 721,        1073742560,  // NOLINT
+    740,        748,        750,        1073742704,
+    884,        1073742710, 887,        1073742714,  // NOLINT
+    893,        895,        902,        1073742728,
+    906,        908,        1073742734, 929,  // NOLINT
+    1073742755, 1013,       1073742839, 1153,
+    1073742986, 1327,       1073743153, 1366,  // NOLINT
+    1369,       1073743201, 1415,       1073743312,
+    1514,       1073743344, 1522,       1073743392,  // NOLINT
+    1610,       1073743470, 1647,       1073743473,
+    1747,       1749,       1073743589, 1766,  // NOLINT
+    1073743598, 1775,       1073743610, 1788,
+    1791,       1808,       1073743634, 1839,  // NOLINT
+    1073743693, 1957,       1969,       1073743818,
+    2026,       1073743860, 2037,       2042,  // NOLINT
+    1073743872, 2069,       2074,       2084,
+    2088,       1073743936, 2136,       1073744032,  // NOLINT
+    2226,       1073744132, 2361,       2365,
+    2384,       1073744216, 2401,       1073744241,  // NOLINT
+    2432,       1073744261, 2444,       1073744271,
+    2448,       1073744275, 2472,       1073744298,  // NOLINT
+    2480,       2482,       1073744310, 2489,
+    2493,       2510,       1073744348, 2525,  // NOLINT
+    1073744351, 2529,       1073744368, 2545,
+    1073744389, 2570,       1073744399, 2576,  // NOLINT
+    1073744403, 2600,       1073744426, 2608,
+    1073744434, 2611,       1073744437, 2614,  // NOLINT
+    1073744440, 2617,       1073744473, 2652,
+    2654,       1073744498, 2676,       1073744517,  // NOLINT
+    2701,       1073744527, 2705,       1073744531,
+    2728,       1073744554, 2736,       1073744562,  // NOLINT
+    2739,       1073744565, 2745,       2749,
+    2768,       1073744608, 2785,       1073744645,  // NOLINT
+    2828,       1073744655, 2832,       1073744659,
+    2856,       1073744682, 2864,       1073744690,  // NOLINT
+    2867,       1073744693, 2873,       2877,
+    1073744732, 2909,       1073744735, 2913,  // NOLINT
+    2929,       2947,       1073744773, 2954,
+    1073744782, 2960,       1073744786, 2965,  // NOLINT
+    1073744793, 2970,       2972,       1073744798,
+    2975,       1073744803, 2980,       1073744808,  // NOLINT
+    2986,       1073744814, 3001,       3024,
+    1073744901, 3084,       1073744910, 3088,  // NOLINT
+    1073744914, 3112,       1073744938, 3129,
+    3133,       1073744984, 3161,       1073744992,  // NOLINT
+    3169,       1073745029, 3212,       1073745038,
+    3216,       1073745042, 3240,       1073745066,  // NOLINT
+    3251,       1073745077, 3257,       3261,
+    3294,       1073745120, 3297,       1073745137,  // NOLINT
+    3314,       1073745157, 3340,       1073745166,
+    3344,       1073745170, 3386,       3389,  // NOLINT
+    3406,       1073745248, 3425,       1073745274,
+    3455,       1073745285, 3478,       1073745306,  // NOLINT
+    3505,       1073745331, 3515,       3517,
+    1073745344, 3526,       1073745409, 3632,  // NOLINT
+    1073745458, 3635,       1073745472, 3654,
+    1073745537, 3714,       3716,       1073745543,  // NOLINT
+    3720,       3722,       3725,       1073745556,
+    3735,       1073745561, 3743,       1073745569,  // NOLINT
+    3747,       3749,       3751,       1073745578,
+    3755,       1073745581, 3760,       1073745586,  // NOLINT
+    3763,       3773,       1073745600, 3780,
+    3782,       1073745628, 3807,       3840,  // NOLINT
+    1073745728, 3911,       1073745737, 3948,
+    1073745800, 3980,       1073745920, 4138,  // NOLINT
+    4159,       1073746000, 4181,       1073746010,
+    4189,       4193,       1073746021, 4198,  // NOLINT
+    1073746030, 4208,       1073746037, 4225,
+    4238,       1073746080, 4293,       4295,  // NOLINT
+    4301,       1073746128, 4346,       1073746172,
+    4680,       1073746506, 4685,       1073746512,  // NOLINT
+    4694,       4696,       1073746522, 4701,
+    1073746528, 4744,       1073746570, 4749,  // NOLINT
+    1073746576, 4784,       1073746610, 4789,
+    1073746616, 4798,       4800,       1073746626,  // NOLINT
+    4805,       1073746632, 4822,       1073746648,
+    4880,       1073746706, 4885,       1073746712,  // NOLINT
+    4954,       1073746816, 5007,       1073746848,
+    5108,       1073746945, 5740,       1073747567,  // NOLINT
+    5759,       1073747585, 5786,       1073747616,
+    5866,       1073747694, 5880,       1073747712,  // NOLINT
+    5900,       1073747726, 5905,       1073747744,
+    5937,       1073747776, 5969,       1073747808,  // NOLINT
+    5996,       1073747822, 6000,       1073747840,
+    6067,       6103,       6108,       1073748000,  // NOLINT
+    6263,       1073748096, 6312,       6314,
+    1073748144, 6389,       1073748224, 6430,  // NOLINT
+    1073748304, 6509,       1073748336, 6516,
+    1073748352, 6571,       1073748417, 6599,  // NOLINT
+    1073748480, 6678,       1073748512, 6740,
+    6823,       1073748741, 6963,       1073748805,  // NOLINT
+    6987,       1073748867, 7072,       1073748910,
+    7087,       1073748922, 7141,       1073748992,  // NOLINT
+    7203,       1073749069, 7247,       1073749082,
+    7293,       1073749225, 7404,       1073749230,  // NOLINT
+    7409,       1073749237, 7414,       1073749248,
+    7615,       1073749504, 7957,       1073749784,  // NOLINT
+    7965,       1073749792, 8005,       1073749832,
+    8013,       1073749840, 8023,       8025,  // NOLINT
+    8027,       8029,       1073749855, 8061,
+    1073749888, 8116,       1073749942, 8124,  // NOLINT
+    8126,       1073749954, 8132,       1073749958,
+    8140,       1073749968, 8147,       1073749974,  // NOLINT
+    8155,       1073749984, 8172,       1073750002,
+    8180,       1073750006, 8188};  // NOLINT
 static const uint16_t kLetterTable1Size = 87;
 static const int32_t kLetterTable1[87] = {
   113, 127, 1073741968, 156, 258, 263, 1073742090, 275,  // NOLINT
@@ -631,19 +749,33 @@
 static const uint16_t kLetterTable4Size = 2;
 static const int32_t kLetterTable4[2] = {
   1073741824, 8140 };  // NOLINT
-static const uint16_t kLetterTable5Size = 88;
-static const int32_t kLetterTable5[88] = {
-  1073741824, 1164, 1073743056, 1277, 1073743104, 1548, 1073743376, 1567,  // NOLINT
-  1073743402, 1579, 1073743424, 1646, 1073743487, 1687, 1073743520, 1775,  // NOLINT
-  1073743639, 1823, 1073743650, 1928, 1073743755, 1934, 1073743760, 1939,  // NOLINT
-  1073743776, 1962, 1073743864, 2049, 1073743875, 2053, 1073743879, 2058,  // NOLINT
-  1073743884, 2082, 1073743936, 2163, 1073744002, 2227, 1073744114, 2295,  // NOLINT
-  2299, 1073744138, 2341, 1073744176, 2374, 1073744224, 2428, 1073744260,  // NOLINT
-  2482, 2511, 1073744384, 2600, 1073744448, 2626, 1073744452, 2635,  // NOLINT
-  1073744480, 2678, 2682, 1073744512, 2735, 2737, 1073744565, 2742,  // NOLINT
-  1073744569, 2749, 2752, 2754, 1073744603, 2781, 1073744608, 2794,  // NOLINT
-  1073744626, 2804, 1073744641, 2822, 1073744649, 2830, 1073744657, 2838,  // NOLINT
-  1073744672, 2854, 1073744680, 2862, 1073744832, 3042, 1073744896, 8191 };  // NOLINT
+static const uint16_t kLetterTable5Size = 100;
+static const int32_t kLetterTable5[100] = {
+    1073741824, 1164,       1073743056, 1277,
+    1073743104, 1548,       1073743376, 1567,  // NOLINT
+    1073743402, 1579,       1073743424, 1646,
+    1073743487, 1693,       1073743520, 1775,  // NOLINT
+    1073743639, 1823,       1073743650, 1928,
+    1073743755, 1934,       1073743760, 1965,  // NOLINT
+    1073743792, 1969,       1073743863, 2049,
+    1073743875, 2053,       1073743879, 2058,  // NOLINT
+    1073743884, 2082,       1073743936, 2163,
+    1073744002, 2227,       1073744114, 2295,  // NOLINT
+    2299,       1073744138, 2341,       1073744176,
+    2374,       1073744224, 2428,       1073744260,  // NOLINT
+    2482,       2511,       1073744352, 2532,
+    1073744358, 2543,       1073744378, 2558,  // NOLINT
+    1073744384, 2600,       1073744448, 2626,
+    1073744452, 2635,       1073744480, 2678,  // NOLINT
+    2682,       1073744510, 2735,       2737,
+    1073744565, 2742,       1073744569, 2749,  // NOLINT
+    2752,       2754,       1073744603, 2781,
+    1073744608, 2794,       1073744626, 2804,  // NOLINT
+    1073744641, 2822,       1073744649, 2830,
+    1073744657, 2838,       1073744672, 2854,  // NOLINT
+    1073744680, 2862,       1073744688, 2906,
+    1073744732, 2911,       1073744740, 2917,   // NOLINT
+    1073744832, 3042,       1073744896, 8191};  // NOLINT
 static const uint16_t kLetterTable6Size = 6;
 static const int32_t kLetterTable6[6] = {
   1073741824, 6051, 1073747888, 6086, 1073747915, 6139 };  // NOLINT
@@ -687,49 +819,363 @@
 }
 
 
-// Number:               point.category == 'Nd'
+// ID_Start:             ((point.category in ['Lu', 'Ll', 'Lt', 'Lm', 'Lo',
+// 'Nl'] or 'Other_ID_Start' in point.properties) and ('Pattern_Syntax' not in
+// point.properties) and ('Pattern_White_Space' not in point.properties)) or
+// ('JS_ID_Start' in point.properties)
 
-static const uint16_t kNumberTable0Size = 56;
-static const int32_t kNumberTable0[56] = {
-  1073741872, 57, 1073743456, 1641, 1073743600, 1785, 1073743808, 1993,  // NOLINT
-  1073744230, 2415, 1073744358, 2543, 1073744486, 2671, 1073744614, 2799,  // NOLINT
-  1073744742, 2927, 1073744870, 3055, 1073744998, 3183, 1073745126, 3311,  // NOLINT
-  1073745254, 3439, 1073745488, 3673, 1073745616, 3801, 1073745696, 3881,  // NOLINT
-  1073745984, 4169, 1073746064, 4249, 1073747936, 6121, 1073747984, 6169,  // NOLINT
-  1073748294, 6479, 1073748432, 6617, 1073748608, 6793, 1073748624, 6809,  // NOLINT
-  1073748816, 7001, 1073748912, 7097, 1073749056, 7241, 1073749072, 7257 };  // NOLINT
-static const uint16_t kNumberTable5Size = 12;
-static const int32_t kNumberTable5[12] = {
-  1073743392, 1577, 1073744080, 2265, 1073744128, 2313, 1073744336, 2521,  // NOLINT
-  1073744464, 2649, 1073744880, 3065 };  // NOLINT
-static const uint16_t kNumberTable7Size = 2;
-static const int32_t kNumberTable7[2] = {
-  1073749776, 7961 };  // NOLINT
-bool Number::Is(uchar c) {
+static const uint16_t kID_StartTable0Size = 434;
+static const int32_t kID_StartTable0[434] = {
+    36,         1073741889, 90,         92,
+    95,         1073741921, 122,        170,  // NOLINT
+    181,        186,        1073742016, 214,
+    1073742040, 246,        1073742072, 705,  // NOLINT
+    1073742534, 721,        1073742560, 740,
+    748,        750,        1073742704, 884,  // NOLINT
+    1073742710, 887,        1073742714, 893,
+    895,        902,        1073742728, 906,  // NOLINT
+    908,        1073742734, 929,        1073742755,
+    1013,       1073742839, 1153,       1073742986,  // NOLINT
+    1327,       1073743153, 1366,       1369,
+    1073743201, 1415,       1073743312, 1514,  // NOLINT
+    1073743344, 1522,       1073743392, 1610,
+    1073743470, 1647,       1073743473, 1747,  // NOLINT
+    1749,       1073743589, 1766,       1073743598,
+    1775,       1073743610, 1788,       1791,  // NOLINT
+    1808,       1073743634, 1839,       1073743693,
+    1957,       1969,       1073743818, 2026,  // NOLINT
+    1073743860, 2037,       2042,       1073743872,
+    2069,       2074,       2084,       2088,  // NOLINT
+    1073743936, 2136,       1073744032, 2226,
+    1073744132, 2361,       2365,       2384,  // NOLINT
+    1073744216, 2401,       1073744241, 2432,
+    1073744261, 2444,       1073744271, 2448,  // NOLINT
+    1073744275, 2472,       1073744298, 2480,
+    2482,       1073744310, 2489,       2493,  // NOLINT
+    2510,       1073744348, 2525,       1073744351,
+    2529,       1073744368, 2545,       1073744389,  // NOLINT
+    2570,       1073744399, 2576,       1073744403,
+    2600,       1073744426, 2608,       1073744434,  // NOLINT
+    2611,       1073744437, 2614,       1073744440,
+    2617,       1073744473, 2652,       2654,  // NOLINT
+    1073744498, 2676,       1073744517, 2701,
+    1073744527, 2705,       1073744531, 2728,  // NOLINT
+    1073744554, 2736,       1073744562, 2739,
+    1073744565, 2745,       2749,       2768,  // NOLINT
+    1073744608, 2785,       1073744645, 2828,
+    1073744655, 2832,       1073744659, 2856,  // NOLINT
+    1073744682, 2864,       1073744690, 2867,
+    1073744693, 2873,       2877,       1073744732,  // NOLINT
+    2909,       1073744735, 2913,       2929,
+    2947,       1073744773, 2954,       1073744782,  // NOLINT
+    2960,       1073744786, 2965,       1073744793,
+    2970,       2972,       1073744798, 2975,  // NOLINT
+    1073744803, 2980,       1073744808, 2986,
+    1073744814, 3001,       3024,       1073744901,  // NOLINT
+    3084,       1073744910, 3088,       1073744914,
+    3112,       1073744938, 3129,       3133,  // NOLINT
+    1073744984, 3161,       1073744992, 3169,
+    1073745029, 3212,       1073745038, 3216,  // NOLINT
+    1073745042, 3240,       1073745066, 3251,
+    1073745077, 3257,       3261,       3294,  // NOLINT
+    1073745120, 3297,       1073745137, 3314,
+    1073745157, 3340,       1073745166, 3344,  // NOLINT
+    1073745170, 3386,       3389,       3406,
+    1073745248, 3425,       1073745274, 3455,  // NOLINT
+    1073745285, 3478,       1073745306, 3505,
+    1073745331, 3515,       3517,       1073745344,  // NOLINT
+    3526,       1073745409, 3632,       1073745458,
+    3635,       1073745472, 3654,       1073745537,  // NOLINT
+    3714,       3716,       1073745543, 3720,
+    3722,       3725,       1073745556, 3735,  // NOLINT
+    1073745561, 3743,       1073745569, 3747,
+    3749,       3751,       1073745578, 3755,  // NOLINT
+    1073745581, 3760,       1073745586, 3763,
+    3773,       1073745600, 3780,       3782,  // NOLINT
+    1073745628, 3807,       3840,       1073745728,
+    3911,       1073745737, 3948,       1073745800,  // NOLINT
+    3980,       1073745920, 4138,       4159,
+    1073746000, 4181,       1073746010, 4189,  // NOLINT
+    4193,       1073746021, 4198,       1073746030,
+    4208,       1073746037, 4225,       4238,  // NOLINT
+    1073746080, 4293,       4295,       4301,
+    1073746128, 4346,       1073746172, 4680,  // NOLINT
+    1073746506, 4685,       1073746512, 4694,
+    4696,       1073746522, 4701,       1073746528,  // NOLINT
+    4744,       1073746570, 4749,       1073746576,
+    4784,       1073746610, 4789,       1073746616,  // NOLINT
+    4798,       4800,       1073746626, 4805,
+    1073746632, 4822,       1073746648, 4880,  // NOLINT
+    1073746706, 4885,       1073746712, 4954,
+    1073746816, 5007,       1073746848, 5108,  // NOLINT
+    1073746945, 5740,       1073747567, 5759,
+    1073747585, 5786,       1073747616, 5866,  // NOLINT
+    1073747694, 5880,       1073747712, 5900,
+    1073747726, 5905,       1073747744, 5937,  // NOLINT
+    1073747776, 5969,       1073747808, 5996,
+    1073747822, 6000,       1073747840, 6067,  // NOLINT
+    6103,       6108,       1073748000, 6263,
+    1073748096, 6312,       6314,       1073748144,  // NOLINT
+    6389,       1073748224, 6430,       1073748304,
+    6509,       1073748336, 6516,       1073748352,  // NOLINT
+    6571,       1073748417, 6599,       1073748480,
+    6678,       1073748512, 6740,       6823,  // NOLINT
+    1073748741, 6963,       1073748805, 6987,
+    1073748867, 7072,       1073748910, 7087,  // NOLINT
+    1073748922, 7141,       1073748992, 7203,
+    1073749069, 7247,       1073749082, 7293,  // NOLINT
+    1073749225, 7404,       1073749230, 7409,
+    1073749237, 7414,       1073749248, 7615,  // NOLINT
+    1073749504, 7957,       1073749784, 7965,
+    1073749792, 8005,       1073749832, 8013,  // NOLINT
+    1073749840, 8023,       8025,       8027,
+    8029,       1073749855, 8061,       1073749888,  // NOLINT
+    8116,       1073749942, 8124,       8126,
+    1073749954, 8132,       1073749958, 8140,  // NOLINT
+    1073749968, 8147,       1073749974, 8155,
+    1073749984, 8172,       1073750002, 8180,  // NOLINT
+    1073750006, 8188};                         // NOLINT
+static const uint16_t kID_StartTable1Size = 84;
+static const int32_t kID_StartTable1[84] = {
+    113,        127,        1073741968, 156,
+    258,        263,        1073742090, 275,  // NOLINT
+    277,        1073742104, 285,        292,
+    294,        296,        1073742122, 313,  // NOLINT
+    1073742140, 319,        1073742149, 329,
+    334,        1073742176, 392,        1073744896,  // NOLINT
+    3118,       1073744944, 3166,       1073744992,
+    3300,       1073745131, 3310,       1073745138,  // NOLINT
+    3315,       1073745152, 3365,       3367,
+    3373,       1073745200, 3431,       3439,  // NOLINT
+    1073745280, 3478,       1073745312, 3494,
+    1073745320, 3502,       1073745328, 3510,  // NOLINT
+    1073745336, 3518,       1073745344, 3526,
+    1073745352, 3534,       1073745360, 3542,  // NOLINT
+    1073745368, 3550,       1073745925, 4103,
+    1073745953, 4137,       1073745969, 4149,  // NOLINT
+    1073745976, 4156,       1073745985, 4246,
+    1073746075, 4255,       1073746081, 4346,  // NOLINT
+    1073746172, 4351,       1073746181, 4397,
+    1073746225, 4494,       1073746336, 4538,   // NOLINT
+    1073746416, 4607,       1073746944, 8191};  // NOLINT
+static const uint16_t kID_StartTable2Size = 4;
+static const int32_t kID_StartTable2[4] = {1073741824, 3509, 1073745408,
+                                           8191};  // NOLINT
+static const uint16_t kID_StartTable3Size = 2;
+static const int32_t kID_StartTable3[2] = {1073741824, 8191};  // NOLINT
+static const uint16_t kID_StartTable4Size = 2;
+static const int32_t kID_StartTable4[2] = {1073741824, 8140};  // NOLINT
+static const uint16_t kID_StartTable5Size = 100;
+static const int32_t kID_StartTable5[100] = {
+    1073741824, 1164,       1073743056, 1277,
+    1073743104, 1548,       1073743376, 1567,  // NOLINT
+    1073743402, 1579,       1073743424, 1646,
+    1073743487, 1693,       1073743520, 1775,  // NOLINT
+    1073743639, 1823,       1073743650, 1928,
+    1073743755, 1934,       1073743760, 1965,  // NOLINT
+    1073743792, 1969,       1073743863, 2049,
+    1073743875, 2053,       1073743879, 2058,  // NOLINT
+    1073743884, 2082,       1073743936, 2163,
+    1073744002, 2227,       1073744114, 2295,  // NOLINT
+    2299,       1073744138, 2341,       1073744176,
+    2374,       1073744224, 2428,       1073744260,  // NOLINT
+    2482,       2511,       1073744352, 2532,
+    1073744358, 2543,       1073744378, 2558,  // NOLINT
+    1073744384, 2600,       1073744448, 2626,
+    1073744452, 2635,       1073744480, 2678,  // NOLINT
+    2682,       1073744510, 2735,       2737,
+    1073744565, 2742,       1073744569, 2749,  // NOLINT
+    2752,       2754,       1073744603, 2781,
+    1073744608, 2794,       1073744626, 2804,  // NOLINT
+    1073744641, 2822,       1073744649, 2830,
+    1073744657, 2838,       1073744672, 2854,  // NOLINT
+    1073744680, 2862,       1073744688, 2906,
+    1073744732, 2911,       1073744740, 2917,   // NOLINT
+    1073744832, 3042,       1073744896, 8191};  // NOLINT
+static const uint16_t kID_StartTable6Size = 6;
+static const int32_t kID_StartTable6[6] = {1073741824, 6051, 1073747888, 6086,
+                                           1073747915, 6139};  // NOLINT
+static const uint16_t kID_StartTable7Size = 48;
+static const int32_t kID_StartTable7[48] = {
+    1073748224, 6765,       1073748592, 6873,
+    1073748736, 6918,       1073748755, 6935,  // NOLINT
+    6941,       1073748767, 6952,       1073748778,
+    6966,       1073748792, 6972,       6974,  // NOLINT
+    1073748800, 6977,       1073748803, 6980,
+    1073748806, 7089,       1073748947, 7485,  // NOLINT
+    1073749328, 7567,       1073749394, 7623,
+    1073749488, 7675,       1073749616, 7796,  // NOLINT
+    1073749622, 7932,       1073749793, 7994,
+    1073749825, 8026,       1073749862, 8126,  // NOLINT
+    1073749954, 8135,       1073749962, 8143,
+    1073749970, 8151,       1073749978, 8156};  // NOLINT
+bool ID_Start::Is(uchar c) {
   int chunk_index = c >> 13;
   switch (chunk_index) {
-    case 0: return LookupPredicate(kNumberTable0,
-                                       kNumberTable0Size,
-                                       c);
-    case 5: return LookupPredicate(kNumberTable5,
-                                       kNumberTable5Size,
-                                       c);
-    case 7: return LookupPredicate(kNumberTable7,
-                                       kNumberTable7Size,
-                                       c);
+    case 0:
+      return LookupPredicate(kID_StartTable0, kID_StartTable0Size, c);
+    case 1:
+      return LookupPredicate(kID_StartTable1, kID_StartTable1Size, c);
+    case 2:
+      return LookupPredicate(kID_StartTable2, kID_StartTable2Size, c);
+    case 3:
+      return LookupPredicate(kID_StartTable3, kID_StartTable3Size, c);
+    case 4:
+      return LookupPredicate(kID_StartTable4, kID_StartTable4Size, c);
+    case 5:
+      return LookupPredicate(kID_StartTable5, kID_StartTable5Size, c);
+    case 6:
+      return LookupPredicate(kID_StartTable6, kID_StartTable6Size, c);
+    case 7:
+      return LookupPredicate(kID_StartTable7, kID_StartTable7Size, c);
+    default:
+      return false;
+  }
+}
+
+
+// ID_Continue:          point.category in ['Nd', 'Mn', 'Mc', 'Pc'] or
+// 'Other_ID_Continue' in point.properties or 'JS_ID_Continue' in
+// point.properties
+
+static const uint16_t kID_ContinueTable0Size = 315;
+static const int32_t kID_ContinueTable0[315] = {
+    1073741872, 57,         95,         183,
+    1073742592, 879,        903,        1073742979,  // NOLINT
+    1159,       1073743249, 1469,       1471,
+    1073743297, 1474,       1073743300, 1477,  // NOLINT
+    1479,       1073743376, 1562,       1073743435,
+    1641,       1648,       1073743574, 1756,  // NOLINT
+    1073743583, 1764,       1073743591, 1768,
+    1073743594, 1773,       1073743600, 1785,  // NOLINT
+    1809,       1073743664, 1866,       1073743782,
+    1968,       1073743808, 1993,       1073743851,  // NOLINT
+    2035,       1073743894, 2073,       1073743899,
+    2083,       1073743909, 2087,       1073743913,  // NOLINT
+    2093,       1073743961, 2139,       1073744100,
+    2307,       1073744186, 2364,       1073744190,  // NOLINT
+    2383,       1073744209, 2391,       1073744226,
+    2403,       1073744230, 2415,       1073744257,  // NOLINT
+    2435,       2492,       1073744318, 2500,
+    1073744327, 2504,       1073744331, 2509,  // NOLINT
+    2519,       1073744354, 2531,       1073744358,
+    2543,       1073744385, 2563,       2620,  // NOLINT
+    1073744446, 2626,       1073744455, 2632,
+    1073744459, 2637,       2641,       1073744486,  // NOLINT
+    2673,       2677,       1073744513, 2691,
+    2748,       1073744574, 2757,       1073744583,  // NOLINT
+    2761,       1073744587, 2765,       1073744610,
+    2787,       1073744614, 2799,       1073744641,  // NOLINT
+    2819,       2876,       1073744702, 2884,
+    1073744711, 2888,       1073744715, 2893,  // NOLINT
+    1073744726, 2903,       1073744738, 2915,
+    1073744742, 2927,       2946,       1073744830,  // NOLINT
+    3010,       1073744838, 3016,       1073744842,
+    3021,       3031,       1073744870, 3055,  // NOLINT
+    1073744896, 3075,       1073744958, 3140,
+    1073744966, 3144,       1073744970, 3149,  // NOLINT
+    1073744981, 3158,       1073744994, 3171,
+    1073744998, 3183,       1073745025, 3203,  // NOLINT
+    3260,       1073745086, 3268,       1073745094,
+    3272,       1073745098, 3277,       1073745109,  // NOLINT
+    3286,       1073745122, 3299,       1073745126,
+    3311,       1073745153, 3331,       1073745214,  // NOLINT
+    3396,       1073745222, 3400,       1073745226,
+    3405,       3415,       1073745250, 3427,  // NOLINT
+    1073745254, 3439,       1073745282, 3459,
+    3530,       1073745359, 3540,       3542,  // NOLINT
+    1073745368, 3551,       1073745382, 3567,
+    1073745394, 3571,       3633,       1073745460,  // NOLINT
+    3642,       1073745479, 3662,       1073745488,
+    3673,       3761,       1073745588, 3769,  // NOLINT
+    1073745595, 3772,       1073745608, 3789,
+    1073745616, 3801,       1073745688, 3865,  // NOLINT
+    1073745696, 3881,       3893,       3895,
+    3897,       1073745726, 3903,       1073745777,  // NOLINT
+    3972,       1073745798, 3975,       1073745805,
+    3991,       1073745817, 4028,       4038,  // NOLINT
+    1073745963, 4158,       1073745984, 4169,
+    1073746006, 4185,       1073746014, 4192,  // NOLINT
+    1073746018, 4196,       1073746023, 4205,
+    1073746033, 4212,       1073746050, 4237,  // NOLINT
+    1073746063, 4253,       1073746781, 4959,
+    1073746793, 4977,       1073747730, 5908,  // NOLINT
+    1073747762, 5940,       1073747794, 5971,
+    1073747826, 6003,       1073747892, 6099,  // NOLINT
+    6109,       1073747936, 6121,       1073747979,
+    6157,       1073747984, 6169,       6313,  // NOLINT
+    1073748256, 6443,       1073748272, 6459,
+    1073748294, 6479,       1073748400, 6592,  // NOLINT
+    1073748424, 6601,       1073748432, 6618,
+    1073748503, 6683,       1073748565, 6750,  // NOLINT
+    1073748576, 6780,       1073748607, 6793,
+    1073748624, 6809,       1073748656, 6845,  // NOLINT
+    1073748736, 6916,       1073748788, 6980,
+    1073748816, 7001,       1073748843, 7027,  // NOLINT
+    1073748864, 7042,       1073748897, 7085,
+    1073748912, 7097,       1073748966, 7155,  // NOLINT
+    1073749028, 7223,       1073749056, 7241,
+    1073749072, 7257,       1073749200, 7378,  // NOLINT
+    1073749204, 7400,       7405,       1073749234,
+    7412,       1073749240, 7417,       1073749440,  // NOLINT
+    7669,       1073749500, 7679};                   // NOLINT
+static const uint16_t kID_ContinueTable1Size = 19;
+static const int32_t kID_ContinueTable1[19] = {
+    1073741836, 13,         1073741887, 64,
+    84,         1073742032, 220,        225,  // NOLINT
+    1073742053, 240,        1073745135, 3313,
+    3455,       1073745376, 3583,       1073745962,  // NOLINT
+    4143,       1073746073, 4250};                   // NOLINT
+static const uint16_t kID_ContinueTable5Size = 63;
+static const int32_t kID_ContinueTable5[63] = {
+    1073743392, 1577,       1647,       1073743476,
+    1661,       1695,       1073743600, 1777,  // NOLINT
+    2050,       2054,       2059,       1073743907,
+    2087,       1073744000, 2177,       1073744052,  // NOLINT
+    2244,       1073744080, 2265,       1073744096,
+    2289,       1073744128, 2313,       1073744166,  // NOLINT
+    2349,       1073744199, 2387,       1073744256,
+    2435,       1073744307, 2496,       1073744336,  // NOLINT
+    2521,       2533,       1073744368, 2553,
+    1073744425, 2614,       2627,       1073744460,  // NOLINT
+    2637,       1073744464, 2649,       1073744507,
+    2685,       2736,       1073744562, 2740,  // NOLINT
+    1073744567, 2744,       1073744574, 2751,
+    2753,       1073744619, 2799,       1073744629,  // NOLINT
+    2806,       1073744867, 3050,       1073744876,
+    3053,       1073744880, 3065};  // NOLINT
+static const uint16_t kID_ContinueTable7Size = 12;
+static const int32_t kID_ContinueTable7[12] = {
+    6942, 1073749504, 7695, 1073749536,
+    7725, 1073749555, 7732, 1073749581,  // NOLINT
+    7759, 1073749776, 7961, 7999};       // NOLINT
+bool ID_Continue::Is(uchar c) {
+  int chunk_index = c >> 13;
+  switch (chunk_index) {
+    case 0:
+      return LookupPredicate(kID_ContinueTable0, kID_ContinueTable0Size, c);
+    case 1:
+      return LookupPredicate(kID_ContinueTable1, kID_ContinueTable1Size, c);
+    case 5:
+      return LookupPredicate(kID_ContinueTable5, kID_ContinueTable5Size, c);
+    case 7:
+      return LookupPredicate(kID_ContinueTable7, kID_ContinueTable7Size, c);
     default: return false;
   }
 }
 
 
-// WhiteSpace:           point.category == 'Zs'
+// WhiteSpace:           (point.category == 'Zs') or ('JS_White_Space' in
+// point.properties)
 
-static const uint16_t kWhiteSpaceTable0Size = 4;
-static const int32_t kWhiteSpaceTable0[4] = {
-  32, 160, 5760, 6158 };  // NOLINT
+static const uint16_t kWhiteSpaceTable0Size = 7;
+static const int32_t kWhiteSpaceTable0[7] = {9,   1073741835, 12,  32,
+                                             160, 5760,       6158};  // NOLINT
 static const uint16_t kWhiteSpaceTable1Size = 5;
 static const int32_t kWhiteSpaceTable1[5] = {
   1073741824, 10, 47, 95, 4096 };  // NOLINT
+static const uint16_t kWhiteSpaceTable7Size = 1;
+static const int32_t kWhiteSpaceTable7[1] = {7935};  // NOLINT
 bool WhiteSpace::Is(uchar c) {
   int chunk_index = c >> 13;
   switch (chunk_index) {
@@ -739,12 +1185,14 @@
     case 1: return LookupPredicate(kWhiteSpaceTable1,
                                        kWhiteSpaceTable1Size,
                                        c);
+    case 7:
+      return LookupPredicate(kWhiteSpaceTable7, kWhiteSpaceTable7Size, c);
     default: return false;
   }
 }
 
 
-// LineTerminator:       'Lt' in point.properties
+// LineTerminator:       'JS_Line_Terminator' in point.properties
 
 static const uint16_t kLineTerminatorTable0Size = 2;
 static const int32_t kLineTerminatorTable0[2] = {
@@ -765,171 +1213,193 @@
   }
 }
 
-
-// CombiningMark:        point.category in ['Mn', 'Mc']
-
-static const uint16_t kCombiningMarkTable0Size = 258;
-static const int32_t kCombiningMarkTable0[258] = {
-  1073742592, 879, 1073742979, 1159, 1073743249, 1469, 1471, 1073743297,  // NOLINT
-  1474, 1073743300, 1477, 1479, 1073743376, 1562, 1073743435, 1631,  // NOLINT
-  1648, 1073743574, 1756, 1073743583, 1764, 1073743591, 1768, 1073743594,  // NOLINT
-  1773, 1809, 1073743664, 1866, 1073743782, 1968, 1073743851, 2035,  // NOLINT
-  1073743894, 2073, 1073743899, 2083, 1073743909, 2087, 1073743913, 2093,  // NOLINT
-  1073743961, 2139, 1073744100, 2302, 1073744128, 2307, 1073744186, 2364,  // NOLINT
-  1073744190, 2383, 1073744209, 2391, 1073744226, 2403, 1073744257, 2435,  // NOLINT
-  2492, 1073744318, 2500, 1073744327, 2504, 1073744331, 2509, 2519,  // NOLINT
-  1073744354, 2531, 1073744385, 2563, 2620, 1073744446, 2626, 1073744455,  // NOLINT
-  2632, 1073744459, 2637, 2641, 1073744496, 2673, 2677, 1073744513,  // NOLINT
-  2691, 2748, 1073744574, 2757, 1073744583, 2761, 1073744587, 2765,  // NOLINT
-  1073744610, 2787, 1073744641, 2819, 2876, 1073744702, 2884, 1073744711,  // NOLINT
-  2888, 1073744715, 2893, 1073744726, 2903, 1073744738, 2915, 2946,  // NOLINT
-  1073744830, 3010, 1073744838, 3016, 1073744842, 3021, 3031, 1073744897,  // NOLINT
-  3075, 1073744958, 3140, 1073744966, 3144, 1073744970, 3149, 1073744981,  // NOLINT
-  3158, 1073744994, 3171, 1073745026, 3203, 3260, 1073745086, 3268,  // NOLINT
-  1073745094, 3272, 1073745098, 3277, 1073745109, 3286, 1073745122, 3299,  // NOLINT
-  1073745154, 3331, 1073745214, 3396, 1073745222, 3400, 1073745226, 3405,  // NOLINT
-  3415, 1073745250, 3427, 1073745282, 3459, 3530, 1073745359, 3540,  // NOLINT
-  3542, 1073745368, 3551, 1073745394, 3571, 3633, 1073745460, 3642,  // NOLINT
-  1073745479, 3662, 3761, 1073745588, 3769, 1073745595, 3772, 1073745608,  // NOLINT
-  3789, 1073745688, 3865, 3893, 3895, 3897, 1073745726, 3903,  // NOLINT
-  1073745777, 3972, 1073745798, 3975, 1073745805, 3991, 1073745817, 4028,  // NOLINT
-  4038, 1073745963, 4158, 1073746006, 4185, 1073746014, 4192, 1073746018,  // NOLINT
-  4196, 1073746023, 4205, 1073746033, 4212, 1073746050, 4237, 4239,  // NOLINT
-  1073746074, 4253, 1073746781, 4959, 1073747730, 5908, 1073747762, 5940,  // NOLINT
-  1073747794, 5971, 1073747826, 6003, 1073747892, 6099, 6109, 1073747979,  // NOLINT
-  6157, 6313, 1073748256, 6443, 1073748272, 6459, 1073748400, 6592,  // NOLINT
-  1073748424, 6601, 1073748503, 6683, 1073748565, 6750, 1073748576, 6780,  // NOLINT
-  6783, 1073748736, 6916, 1073748788, 6980, 1073748843, 7027, 1073748864,  // NOLINT
-  7042, 1073748897, 7085, 1073748966, 7155, 1073749028, 7223, 1073749200,  // NOLINT
-  7378, 1073749204, 7400, 7405, 1073749234, 7412, 1073749440, 7654,  // NOLINT
-  1073749500, 7679 };  // NOLINT
-static const uint16_t kCombiningMarkTable1Size = 14;
-static const int32_t kCombiningMarkTable1[14] = {
-  1073742032, 220, 225, 1073742053, 240, 1073745135, 3313, 3455,  // NOLINT
-  1073745376, 3583, 1073745962, 4143, 1073746073, 4250 };  // NOLINT
-static const uint16_t kCombiningMarkTable5Size = 47;
-static const int32_t kCombiningMarkTable5[47] = {
-  1647, 1073743476, 1661, 1695, 1073743600, 1777, 2050, 2054,  // NOLINT
-  2059, 1073743907, 2087, 1073744000, 2177, 1073744052, 2244, 1073744096,  // NOLINT
-  2289, 1073744166, 2349, 1073744199, 2387, 1073744256, 2435, 1073744307,  // NOLINT
-  2496, 1073744425, 2614, 2627, 1073744460, 2637, 2683, 2736,  // NOLINT
-  1073744562, 2740, 1073744567, 2744, 1073744574, 2751, 2753, 1073744619,  // NOLINT
-  2799, 1073744629, 2806, 1073744867, 3050, 1073744876, 3053 };  // NOLINT
-static const uint16_t kCombiningMarkTable7Size = 5;
-static const int32_t kCombiningMarkTable7[5] = {
-  6942, 1073749504, 7695, 1073749536, 7718 };  // NOLINT
-bool CombiningMark::Is(uchar c) {
-  int chunk_index = c >> 13;
-  switch (chunk_index) {
-    case 0: return LookupPredicate(kCombiningMarkTable0,
-                                       kCombiningMarkTable0Size,
-                                       c);
-    case 1: return LookupPredicate(kCombiningMarkTable1,
-                                       kCombiningMarkTable1Size,
-                                       c);
-    case 5: return LookupPredicate(kCombiningMarkTable5,
-                                       kCombiningMarkTable5Size,
-                                       c);
-    case 7: return LookupPredicate(kCombiningMarkTable7,
-                                       kCombiningMarkTable7Size,
-                                       c);
-    default: return false;
-  }
-}
-
-
-// ConnectorPunctuation: point.category == 'Pc'
-
-static const uint16_t kConnectorPunctuationTable0Size = 1;
-static const int32_t kConnectorPunctuationTable0[1] = {
-  95 };  // NOLINT
-static const uint16_t kConnectorPunctuationTable1Size = 3;
-static const int32_t kConnectorPunctuationTable1[3] = {
-  1073741887, 64, 84 };  // NOLINT
-static const uint16_t kConnectorPunctuationTable7Size = 5;
-static const int32_t kConnectorPunctuationTable7[5] = {
-  1073749555, 7732, 1073749581, 7759, 7999 };  // NOLINT
-bool ConnectorPunctuation::Is(uchar c) {
-  int chunk_index = c >> 13;
-  switch (chunk_index) {
-    case 0: return LookupPredicate(kConnectorPunctuationTable0,
-                                       kConnectorPunctuationTable0Size,
-                                       c);
-    case 1: return LookupPredicate(kConnectorPunctuationTable1,
-                                       kConnectorPunctuationTable1Size,
-                                       c);
-    case 7: return LookupPredicate(kConnectorPunctuationTable7,
-                                       kConnectorPunctuationTable7Size,
-                                       c);
-    default: return false;
-  }
-}
-
 static const MultiCharacterSpecialCase<2> kToLowercaseMultiStrings0[2] = {  // NOLINT
   {{105, 775}}, {{kSentinel}} }; // NOLINT
-static const uint16_t kToLowercaseTable0Size = 483;  // NOLINT
-static const int32_t kToLowercaseTable0[966] = {
-  1073741889, 128, 90, 128, 1073742016, 128, 214, 128, 1073742040, 128, 222, 128, 256, 4, 258, 4,  // NOLINT
-  260, 4, 262, 4, 264, 4, 266, 4, 268, 4, 270, 4, 272, 4, 274, 4,  // NOLINT
-  276, 4, 278, 4, 280, 4, 282, 4, 284, 4, 286, 4, 288, 4, 290, 4,  // NOLINT
-  292, 4, 294, 4, 296, 4, 298, 4, 300, 4, 302, 4, 304, 1, 306, 4,  // NOLINT
-  308, 4, 310, 4, 313, 4, 315, 4, 317, 4, 319, 4, 321, 4, 323, 4,  // NOLINT
-  325, 4, 327, 4, 330, 4, 332, 4, 334, 4, 336, 4, 338, 4, 340, 4,  // NOLINT
-  342, 4, 344, 4, 346, 4, 348, 4, 350, 4, 352, 4, 354, 4, 356, 4,  // NOLINT
-  358, 4, 360, 4, 362, 4, 364, 4, 366, 4, 368, 4, 370, 4, 372, 4,  // NOLINT
-  374, 4, 376, -484, 377, 4, 379, 4, 381, 4, 385, 840, 386, 4, 388, 4,  // NOLINT
-  390, 824, 391, 4, 1073742217, 820, 394, 820, 395, 4, 398, 316, 399, 808, 400, 812,  // NOLINT
-  401, 4, 403, 820, 404, 828, 406, 844, 407, 836, 408, 4, 412, 844, 413, 852,  // NOLINT
-  415, 856, 416, 4, 418, 4, 420, 4, 422, 872, 423, 4, 425, 872, 428, 4,  // NOLINT
-  430, 872, 431, 4, 1073742257, 868, 434, 868, 435, 4, 437, 4, 439, 876, 440, 4,  // NOLINT
-  444, 4, 452, 8, 453, 4, 455, 8, 456, 4, 458, 8, 459, 4, 461, 4,  // NOLINT
-  463, 4, 465, 4, 467, 4, 469, 4, 471, 4, 473, 4, 475, 4, 478, 4,  // NOLINT
-  480, 4, 482, 4, 484, 4, 486, 4, 488, 4, 490, 4, 492, 4, 494, 4,  // NOLINT
-  497, 8, 498, 4, 500, 4, 502, -388, 503, -224, 504, 4, 506, 4, 508, 4,  // NOLINT
-  510, 4, 512, 4, 514, 4, 516, 4, 518, 4, 520, 4, 522, 4, 524, 4,  // NOLINT
-  526, 4, 528, 4, 530, 4, 532, 4, 534, 4, 536, 4, 538, 4, 540, 4,  // NOLINT
-  542, 4, 544, -520, 546, 4, 548, 4, 550, 4, 552, 4, 554, 4, 556, 4,  // NOLINT
-  558, 4, 560, 4, 562, 4, 570, 43180, 571, 4, 573, -652, 574, 43168, 577, 4,  // NOLINT
-  579, -780, 580, 276, 581, 284, 582, 4, 584, 4, 586, 4, 588, 4, 590, 4,  // NOLINT
-  880, 4, 882, 4, 886, 4, 902, 152, 1073742728, 148, 906, 148, 908, 256, 1073742734, 252,  // NOLINT
-  911, 252, 1073742737, 128, 929, 128, 931, 6, 1073742756, 128, 939, 128, 975, 32, 984, 4,  // NOLINT
-  986, 4, 988, 4, 990, 4, 992, 4, 994, 4, 996, 4, 998, 4, 1000, 4,  // NOLINT
-  1002, 4, 1004, 4, 1006, 4, 1012, -240, 1015, 4, 1017, -28, 1018, 4, 1073742845, -520,  // NOLINT
-  1023, -520, 1073742848, 320, 1039, 320, 1073742864, 128, 1071, 128, 1120, 4, 1122, 4, 1124, 4,  // NOLINT
-  1126, 4, 1128, 4, 1130, 4, 1132, 4, 1134, 4, 1136, 4, 1138, 4, 1140, 4,  // NOLINT
-  1142, 4, 1144, 4, 1146, 4, 1148, 4, 1150, 4, 1152, 4, 1162, 4, 1164, 4,  // NOLINT
-  1166, 4, 1168, 4, 1170, 4, 1172, 4, 1174, 4, 1176, 4, 1178, 4, 1180, 4,  // NOLINT
-  1182, 4, 1184, 4, 1186, 4, 1188, 4, 1190, 4, 1192, 4, 1194, 4, 1196, 4,  // NOLINT
-  1198, 4, 1200, 4, 1202, 4, 1204, 4, 1206, 4, 1208, 4, 1210, 4, 1212, 4,  // NOLINT
-  1214, 4, 1216, 60, 1217, 4, 1219, 4, 1221, 4, 1223, 4, 1225, 4, 1227, 4,  // NOLINT
-  1229, 4, 1232, 4, 1234, 4, 1236, 4, 1238, 4, 1240, 4, 1242, 4, 1244, 4,  // NOLINT
-  1246, 4, 1248, 4, 1250, 4, 1252, 4, 1254, 4, 1256, 4, 1258, 4, 1260, 4,  // NOLINT
-  1262, 4, 1264, 4, 1266, 4, 1268, 4, 1270, 4, 1272, 4, 1274, 4, 1276, 4,  // NOLINT
-  1278, 4, 1280, 4, 1282, 4, 1284, 4, 1286, 4, 1288, 4, 1290, 4, 1292, 4,  // NOLINT
-  1294, 4, 1296, 4, 1298, 4, 1300, 4, 1302, 4, 1304, 4, 1306, 4, 1308, 4,  // NOLINT
-  1310, 4, 1312, 4, 1314, 4, 1316, 4, 1318, 4, 1073743153, 192, 1366, 192, 1073746080, 29056,  // NOLINT
-  4293, 29056, 4295, 29056, 4301, 29056, 7680, 4, 7682, 4, 7684, 4, 7686, 4, 7688, 4,  // NOLINT
-  7690, 4, 7692, 4, 7694, 4, 7696, 4, 7698, 4, 7700, 4, 7702, 4, 7704, 4,  // NOLINT
-  7706, 4, 7708, 4, 7710, 4, 7712, 4, 7714, 4, 7716, 4, 7718, 4, 7720, 4,  // NOLINT
-  7722, 4, 7724, 4, 7726, 4, 7728, 4, 7730, 4, 7732, 4, 7734, 4, 7736, 4,  // NOLINT
-  7738, 4, 7740, 4, 7742, 4, 7744, 4, 7746, 4, 7748, 4, 7750, 4, 7752, 4,  // NOLINT
-  7754, 4, 7756, 4, 7758, 4, 7760, 4, 7762, 4, 7764, 4, 7766, 4, 7768, 4,  // NOLINT
-  7770, 4, 7772, 4, 7774, 4, 7776, 4, 7778, 4, 7780, 4, 7782, 4, 7784, 4,  // NOLINT
-  7786, 4, 7788, 4, 7790, 4, 7792, 4, 7794, 4, 7796, 4, 7798, 4, 7800, 4,  // NOLINT
-  7802, 4, 7804, 4, 7806, 4, 7808, 4, 7810, 4, 7812, 4, 7814, 4, 7816, 4,  // NOLINT
-  7818, 4, 7820, 4, 7822, 4, 7824, 4, 7826, 4, 7828, 4, 7838, -30460, 7840, 4,  // NOLINT
-  7842, 4, 7844, 4, 7846, 4, 7848, 4, 7850, 4, 7852, 4, 7854, 4, 7856, 4,  // NOLINT
-  7858, 4, 7860, 4, 7862, 4, 7864, 4, 7866, 4, 7868, 4, 7870, 4, 7872, 4,  // NOLINT
-  7874, 4, 7876, 4, 7878, 4, 7880, 4, 7882, 4, 7884, 4, 7886, 4, 7888, 4,  // NOLINT
-  7890, 4, 7892, 4, 7894, 4, 7896, 4, 7898, 4, 7900, 4, 7902, 4, 7904, 4,  // NOLINT
-  7906, 4, 7908, 4, 7910, 4, 7912, 4, 7914, 4, 7916, 4, 7918, 4, 7920, 4,  // NOLINT
-  7922, 4, 7924, 4, 7926, 4, 7928, 4, 7930, 4, 7932, 4, 7934, 4, 1073749768, -32,  // NOLINT
-  7951, -32, 1073749784, -32, 7965, -32, 1073749800, -32, 7983, -32, 1073749816, -32, 7999, -32, 1073749832, -32,  // NOLINT
-  8013, -32, 8025, -32, 8027, -32, 8029, -32, 8031, -32, 1073749864, -32, 8047, -32, 1073749896, -32,  // NOLINT
-  8079, -32, 1073749912, -32, 8095, -32, 1073749928, -32, 8111, -32, 1073749944, -32, 8121, -32, 1073749946, -296,  // NOLINT
-  8123, -296, 8124, -36, 1073749960, -344, 8139, -344, 8140, -36, 1073749976, -32, 8153, -32, 1073749978, -400,  // NOLINT
-  8155, -400, 1073749992, -32, 8169, -32, 1073749994, -448, 8171, -448, 8172, -28, 1073750008, -512, 8185, -512,  // NOLINT
-  1073750010, -504, 8187, -504, 8188, -36 };  // NOLINT
+static const uint16_t kToLowercaseTable0Size = 488;  // NOLINT
+static const int32_t kToLowercaseTable0[976] = {
+    1073741889, 128,    90,         128,   1073742016, 128,
+    214,        128,    1073742040, 128,   222,        128,
+    256,        4,      258,        4,  // NOLINT
+    260,        4,      262,        4,     264,        4,
+    266,        4,      268,        4,     270,        4,
+    272,        4,      274,        4,  // NOLINT
+    276,        4,      278,        4,     280,        4,
+    282,        4,      284,        4,     286,        4,
+    288,        4,      290,        4,  // NOLINT
+    292,        4,      294,        4,     296,        4,
+    298,        4,      300,        4,     302,        4,
+    304,        1,      306,        4,  // NOLINT
+    308,        4,      310,        4,     313,        4,
+    315,        4,      317,        4,     319,        4,
+    321,        4,      323,        4,  // NOLINT
+    325,        4,      327,        4,     330,        4,
+    332,        4,      334,        4,     336,        4,
+    338,        4,      340,        4,  // NOLINT
+    342,        4,      344,        4,     346,        4,
+    348,        4,      350,        4,     352,        4,
+    354,        4,      356,        4,  // NOLINT
+    358,        4,      360,        4,     362,        4,
+    364,        4,      366,        4,     368,        4,
+    370,        4,      372,        4,  // NOLINT
+    374,        4,      376,        -484,  377,        4,
+    379,        4,      381,        4,     385,        840,
+    386,        4,      388,        4,  // NOLINT
+    390,        824,    391,        4,     1073742217, 820,
+    394,        820,    395,        4,     398,        316,
+    399,        808,    400,        812,  // NOLINT
+    401,        4,      403,        820,   404,        828,
+    406,        844,    407,        836,   408,        4,
+    412,        844,    413,        852,  // NOLINT
+    415,        856,    416,        4,     418,        4,
+    420,        4,      422,        872,   423,        4,
+    425,        872,    428,        4,  // NOLINT
+    430,        872,    431,        4,     1073742257, 868,
+    434,        868,    435,        4,     437,        4,
+    439,        876,    440,        4,  // NOLINT
+    444,        4,      452,        8,     453,        4,
+    455,        8,      456,        4,     458,        8,
+    459,        4,      461,        4,  // NOLINT
+    463,        4,      465,        4,     467,        4,
+    469,        4,      471,        4,     473,        4,
+    475,        4,      478,        4,  // NOLINT
+    480,        4,      482,        4,     484,        4,
+    486,        4,      488,        4,     490,        4,
+    492,        4,      494,        4,  // NOLINT
+    497,        8,      498,        4,     500,        4,
+    502,        -388,   503,        -224,  504,        4,
+    506,        4,      508,        4,  // NOLINT
+    510,        4,      512,        4,     514,        4,
+    516,        4,      518,        4,     520,        4,
+    522,        4,      524,        4,  // NOLINT
+    526,        4,      528,        4,     530,        4,
+    532,        4,      534,        4,     536,        4,
+    538,        4,      540,        4,  // NOLINT
+    542,        4,      544,        -520,  546,        4,
+    548,        4,      550,        4,     552,        4,
+    554,        4,      556,        4,  // NOLINT
+    558,        4,      560,        4,     562,        4,
+    570,        43180,  571,        4,     573,        -652,
+    574,        43168,  577,        4,  // NOLINT
+    579,        -780,   580,        276,   581,        284,
+    582,        4,      584,        4,     586,        4,
+    588,        4,      590,        4,  // NOLINT
+    880,        4,      882,        4,     886,        4,
+    895,        464,    902,        152,   1073742728, 148,
+    906,        148,    908,        256,  // NOLINT
+    1073742734, 252,    911,        252,   1073742737, 128,
+    929,        128,    931,        6,     1073742756, 128,
+    939,        128,    975,        32,  // NOLINT
+    984,        4,      986,        4,     988,        4,
+    990,        4,      992,        4,     994,        4,
+    996,        4,      998,        4,  // NOLINT
+    1000,       4,      1002,       4,     1004,       4,
+    1006,       4,      1012,       -240,  1015,       4,
+    1017,       -28,    1018,       4,  // NOLINT
+    1073742845, -520,   1023,       -520,  1073742848, 320,
+    1039,       320,    1073742864, 128,   1071,       128,
+    1120,       4,      1122,       4,  // NOLINT
+    1124,       4,      1126,       4,     1128,       4,
+    1130,       4,      1132,       4,     1134,       4,
+    1136,       4,      1138,       4,  // NOLINT
+    1140,       4,      1142,       4,     1144,       4,
+    1146,       4,      1148,       4,     1150,       4,
+    1152,       4,      1162,       4,  // NOLINT
+    1164,       4,      1166,       4,     1168,       4,
+    1170,       4,      1172,       4,     1174,       4,
+    1176,       4,      1178,       4,  // NOLINT
+    1180,       4,      1182,       4,     1184,       4,
+    1186,       4,      1188,       4,     1190,       4,
+    1192,       4,      1194,       4,  // NOLINT
+    1196,       4,      1198,       4,     1200,       4,
+    1202,       4,      1204,       4,     1206,       4,
+    1208,       4,      1210,       4,  // NOLINT
+    1212,       4,      1214,       4,     1216,       60,
+    1217,       4,      1219,       4,     1221,       4,
+    1223,       4,      1225,       4,  // NOLINT
+    1227,       4,      1229,       4,     1232,       4,
+    1234,       4,      1236,       4,     1238,       4,
+    1240,       4,      1242,       4,  // NOLINT
+    1244,       4,      1246,       4,     1248,       4,
+    1250,       4,      1252,       4,     1254,       4,
+    1256,       4,      1258,       4,  // NOLINT
+    1260,       4,      1262,       4,     1264,       4,
+    1266,       4,      1268,       4,     1270,       4,
+    1272,       4,      1274,       4,  // NOLINT
+    1276,       4,      1278,       4,     1280,       4,
+    1282,       4,      1284,       4,     1286,       4,
+    1288,       4,      1290,       4,  // NOLINT
+    1292,       4,      1294,       4,     1296,       4,
+    1298,       4,      1300,       4,     1302,       4,
+    1304,       4,      1306,       4,  // NOLINT
+    1308,       4,      1310,       4,     1312,       4,
+    1314,       4,      1316,       4,     1318,       4,
+    1320,       4,      1322,       4,  // NOLINT
+    1324,       4,      1326,       4,     1073743153, 192,
+    1366,       192,    1073746080, 29056, 4293,       29056,
+    4295,       29056,  4301,       29056,  // NOLINT
+    7680,       4,      7682,       4,     7684,       4,
+    7686,       4,      7688,       4,     7690,       4,
+    7692,       4,      7694,       4,  // NOLINT
+    7696,       4,      7698,       4,     7700,       4,
+    7702,       4,      7704,       4,     7706,       4,
+    7708,       4,      7710,       4,  // NOLINT
+    7712,       4,      7714,       4,     7716,       4,
+    7718,       4,      7720,       4,     7722,       4,
+    7724,       4,      7726,       4,  // NOLINT
+    7728,       4,      7730,       4,     7732,       4,
+    7734,       4,      7736,       4,     7738,       4,
+    7740,       4,      7742,       4,  // NOLINT
+    7744,       4,      7746,       4,     7748,       4,
+    7750,       4,      7752,       4,     7754,       4,
+    7756,       4,      7758,       4,  // NOLINT
+    7760,       4,      7762,       4,     7764,       4,
+    7766,       4,      7768,       4,     7770,       4,
+    7772,       4,      7774,       4,  // NOLINT
+    7776,       4,      7778,       4,     7780,       4,
+    7782,       4,      7784,       4,     7786,       4,
+    7788,       4,      7790,       4,  // NOLINT
+    7792,       4,      7794,       4,     7796,       4,
+    7798,       4,      7800,       4,     7802,       4,
+    7804,       4,      7806,       4,  // NOLINT
+    7808,       4,      7810,       4,     7812,       4,
+    7814,       4,      7816,       4,     7818,       4,
+    7820,       4,      7822,       4,  // NOLINT
+    7824,       4,      7826,       4,     7828,       4,
+    7838,       -30460, 7840,       4,     7842,       4,
+    7844,       4,      7846,       4,  // NOLINT
+    7848,       4,      7850,       4,     7852,       4,
+    7854,       4,      7856,       4,     7858,       4,
+    7860,       4,      7862,       4,  // NOLINT
+    7864,       4,      7866,       4,     7868,       4,
+    7870,       4,      7872,       4,     7874,       4,
+    7876,       4,      7878,       4,  // NOLINT
+    7880,       4,      7882,       4,     7884,       4,
+    7886,       4,      7888,       4,     7890,       4,
+    7892,       4,      7894,       4,  // NOLINT
+    7896,       4,      7898,       4,     7900,       4,
+    7902,       4,      7904,       4,     7906,       4,
+    7908,       4,      7910,       4,  // NOLINT
+    7912,       4,      7914,       4,     7916,       4,
+    7918,       4,      7920,       4,     7922,       4,
+    7924,       4,      7926,       4,  // NOLINT
+    7928,       4,      7930,       4,     7932,       4,
+    7934,       4,      1073749768, -32,   7951,       -32,
+    1073749784, -32,    7965,       -32,  // NOLINT
+    1073749800, -32,    7983,       -32,   1073749816, -32,
+    7999,       -32,    1073749832, -32,   8013,       -32,
+    8025,       -32,    8027,       -32,  // NOLINT
+    8029,       -32,    8031,       -32,   1073749864, -32,
+    8047,       -32,    1073749896, -32,   8079,       -32,
+    1073749912, -32,    8095,       -32,  // NOLINT
+    1073749928, -32,    8111,       -32,   1073749944, -32,
+    8121,       -32,    1073749946, -296,  8123,       -296,
+    8124,       -36,    1073749960, -344,  // NOLINT
+    8139,       -344,   8140,       -36,   1073749976, -32,
+    8153,       -32,    1073749978, -400,  8155,       -400,
+    1073749992, -32,    8169,       -32,  // NOLINT
+    1073749994, -448,   8171,       -448,  8172,       -28,
+    1073750008, -512,   8185,       -512,  1073750010, -504,
+    8187,       -504,   8188,       -36};                 // NOLINT
 static const uint16_t kToLowercaseMultiStrings0Size = 2;  // NOLINT
 static const MultiCharacterSpecialCase<1> kToLowercaseMultiStrings1[1] = {  // NOLINT
   {{kSentinel}} }; // NOLINT
@@ -948,20 +1418,34 @@
 static const uint16_t kToLowercaseMultiStrings1Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<1> kToLowercaseMultiStrings5[1] = {  // NOLINT
   {{kSentinel}} }; // NOLINT
-static const uint16_t kToLowercaseTable5Size = 91;  // NOLINT
-static const int32_t kToLowercaseTable5[182] = {
-  1600, 4, 1602, 4, 1604, 4, 1606, 4, 1608, 4, 1610, 4, 1612, 4, 1614, 4,  // NOLINT
-  1616, 4, 1618, 4, 1620, 4, 1622, 4, 1624, 4, 1626, 4, 1628, 4, 1630, 4,  // NOLINT
-  1632, 4, 1634, 4, 1636, 4, 1638, 4, 1640, 4, 1642, 4, 1644, 4, 1664, 4,  // NOLINT
-  1666, 4, 1668, 4, 1670, 4, 1672, 4, 1674, 4, 1676, 4, 1678, 4, 1680, 4,  // NOLINT
-  1682, 4, 1684, 4, 1686, 4, 1826, 4, 1828, 4, 1830, 4, 1832, 4, 1834, 4,  // NOLINT
-  1836, 4, 1838, 4, 1842, 4, 1844, 4, 1846, 4, 1848, 4, 1850, 4, 1852, 4,  // NOLINT
-  1854, 4, 1856, 4, 1858, 4, 1860, 4, 1862, 4, 1864, 4, 1866, 4, 1868, 4,  // NOLINT
-  1870, 4, 1872, 4, 1874, 4, 1876, 4, 1878, 4, 1880, 4, 1882, 4, 1884, 4,  // NOLINT
-  1886, 4, 1888, 4, 1890, 4, 1892, 4, 1894, 4, 1896, 4, 1898, 4, 1900, 4,  // NOLINT
-  1902, 4, 1913, 4, 1915, 4, 1917, -141328, 1918, 4, 1920, 4, 1922, 4, 1924, 4,  // NOLINT
-  1926, 4, 1931, 4, 1933, -169120, 1936, 4, 1938, 4, 1952, 4, 1954, 4, 1956, 4,  // NOLINT
-  1958, 4, 1960, 4, 1962, -169232 };  // NOLINT
+static const uint16_t kToLowercaseTable5Size = 103;  // NOLINT
+static const int32_t kToLowercaseTable5[206] = {
+    1600, 4,       1602, 4,       1604, 4,       1606, 4,
+    1608, 4,       1610, 4,       1612, 4,       1614, 4,  // NOLINT
+    1616, 4,       1618, 4,       1620, 4,       1622, 4,
+    1624, 4,       1626, 4,       1628, 4,       1630, 4,  // NOLINT
+    1632, 4,       1634, 4,       1636, 4,       1638, 4,
+    1640, 4,       1642, 4,       1644, 4,       1664, 4,  // NOLINT
+    1666, 4,       1668, 4,       1670, 4,       1672, 4,
+    1674, 4,       1676, 4,       1678, 4,       1680, 4,  // NOLINT
+    1682, 4,       1684, 4,       1686, 4,       1688, 4,
+    1690, 4,       1826, 4,       1828, 4,       1830, 4,  // NOLINT
+    1832, 4,       1834, 4,       1836, 4,       1838, 4,
+    1842, 4,       1844, 4,       1846, 4,       1848, 4,  // NOLINT
+    1850, 4,       1852, 4,       1854, 4,       1856, 4,
+    1858, 4,       1860, 4,       1862, 4,       1864, 4,  // NOLINT
+    1866, 4,       1868, 4,       1870, 4,       1872, 4,
+    1874, 4,       1876, 4,       1878, 4,       1880, 4,  // NOLINT
+    1882, 4,       1884, 4,       1886, 4,       1888, 4,
+    1890, 4,       1892, 4,       1894, 4,       1896, 4,  // NOLINT
+    1898, 4,       1900, 4,       1902, 4,       1913, 4,
+    1915, 4,       1917, -141328, 1918, 4,       1920, 4,  // NOLINT
+    1922, 4,       1924, 4,       1926, 4,       1931, 4,
+    1933, -169120, 1936, 4,       1938, 4,       1942, 4,  // NOLINT
+    1944, 4,       1946, 4,       1948, 4,       1950, 4,
+    1952, 4,       1954, 4,       1956, 4,       1958, 4,  // NOLINT
+    1960, 4,       1962, -169232, 1963, -169276, 1964, -169260,
+    1965, -169220, 1968, -169032, 1969, -169128};         // NOLINT
 static const uint16_t kToLowercaseMultiStrings5Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<1> kToLowercaseMultiStrings7[1] = {  // NOLINT
   {{kSentinel}} }; // NOLINT
@@ -1024,81 +1508,229 @@
   {{933, 776, 768}}, {{929, 787, kSentinel}}, {{933, 834, kSentinel}}, {{933, 776, 834}},  // NOLINT
   {{8186, 921, kSentinel}}, {{937, 921, kSentinel}}, {{911, 921, kSentinel}}, {{937, 834, kSentinel}},  // NOLINT
   {{937, 834, 921}}, {{kSentinel}} }; // NOLINT
-static const uint16_t kToUppercaseTable0Size = 580;  // NOLINT
-static const int32_t kToUppercaseTable0[1160] = {
-  1073741921, -128, 122, -128, 181, 2972, 223, 1, 1073742048, -128, 246, -128, 1073742072, -128, 254, -128,  // NOLINT
-  255, 484, 257, -4, 259, -4, 261, -4, 263, -4, 265, -4, 267, -4, 269, -4,  // NOLINT
-  271, -4, 273, -4, 275, -4, 277, -4, 279, -4, 281, -4, 283, -4, 285, -4,  // NOLINT
-  287, -4, 289, -4, 291, -4, 293, -4, 295, -4, 297, -4, 299, -4, 301, -4,  // NOLINT
-  303, -4, 305, -928, 307, -4, 309, -4, 311, -4, 314, -4, 316, -4, 318, -4,  // NOLINT
-  320, -4, 322, -4, 324, -4, 326, -4, 328, -4, 329, 5, 331, -4, 333, -4,  // NOLINT
-  335, -4, 337, -4, 339, -4, 341, -4, 343, -4, 345, -4, 347, -4, 349, -4,  // NOLINT
-  351, -4, 353, -4, 355, -4, 357, -4, 359, -4, 361, -4, 363, -4, 365, -4,  // NOLINT
-  367, -4, 369, -4, 371, -4, 373, -4, 375, -4, 378, -4, 380, -4, 382, -4,  // NOLINT
-  383, -1200, 384, 780, 387, -4, 389, -4, 392, -4, 396, -4, 402, -4, 405, 388,  // NOLINT
-  409, -4, 410, 652, 414, 520, 417, -4, 419, -4, 421, -4, 424, -4, 429, -4,  // NOLINT
-  432, -4, 436, -4, 438, -4, 441, -4, 445, -4, 447, 224, 453, -4, 454, -8,  // NOLINT
-  456, -4, 457, -8, 459, -4, 460, -8, 462, -4, 464, -4, 466, -4, 468, -4,  // NOLINT
-  470, -4, 472, -4, 474, -4, 476, -4, 477, -316, 479, -4, 481, -4, 483, -4,  // NOLINT
-  485, -4, 487, -4, 489, -4, 491, -4, 493, -4, 495, -4, 496, 9, 498, -4,  // NOLINT
-  499, -8, 501, -4, 505, -4, 507, -4, 509, -4, 511, -4, 513, -4, 515, -4,  // NOLINT
-  517, -4, 519, -4, 521, -4, 523, -4, 525, -4, 527, -4, 529, -4, 531, -4,  // NOLINT
-  533, -4, 535, -4, 537, -4, 539, -4, 541, -4, 543, -4, 547, -4, 549, -4,  // NOLINT
-  551, -4, 553, -4, 555, -4, 557, -4, 559, -4, 561, -4, 563, -4, 572, -4,  // NOLINT
-  1073742399, 43260, 576, 43260, 578, -4, 583, -4, 585, -4, 587, -4, 589, -4, 591, -4,  // NOLINT
-  592, 43132, 593, 43120, 594, 43128, 595, -840, 596, -824, 1073742422, -820, 599, -820, 601, -808,  // NOLINT
-  603, -812, 608, -820, 611, -828, 613, 169120, 614, 169232, 616, -836, 617, -844, 619, 42972,  // NOLINT
-  623, -844, 625, 42996, 626, -852, 629, -856, 637, 42908, 640, -872, 643, -872, 648, -872,  // NOLINT
-  649, -276, 1073742474, -868, 651, -868, 652, -284, 658, -876, 837, 336, 881, -4, 883, -4,  // NOLINT
-  887, -4, 1073742715, 520, 893, 520, 912, 13, 940, -152, 1073742765, -148, 943, -148, 944, 17,  // NOLINT
-  1073742769, -128, 961, -128, 962, -124, 1073742787, -128, 971, -128, 972, -256, 1073742797, -252, 974, -252,  // NOLINT
-  976, -248, 977, -228, 981, -188, 982, -216, 983, -32, 985, -4, 987, -4, 989, -4,  // NOLINT
-  991, -4, 993, -4, 995, -4, 997, -4, 999, -4, 1001, -4, 1003, -4, 1005, -4,  // NOLINT
-  1007, -4, 1008, -344, 1009, -320, 1010, 28, 1013, -384, 1016, -4, 1019, -4, 1073742896, -128,  // NOLINT
-  1103, -128, 1073742928, -320, 1119, -320, 1121, -4, 1123, -4, 1125, -4, 1127, -4, 1129, -4,  // NOLINT
-  1131, -4, 1133, -4, 1135, -4, 1137, -4, 1139, -4, 1141, -4, 1143, -4, 1145, -4,  // NOLINT
-  1147, -4, 1149, -4, 1151, -4, 1153, -4, 1163, -4, 1165, -4, 1167, -4, 1169, -4,  // NOLINT
-  1171, -4, 1173, -4, 1175, -4, 1177, -4, 1179, -4, 1181, -4, 1183, -4, 1185, -4,  // NOLINT
-  1187, -4, 1189, -4, 1191, -4, 1193, -4, 1195, -4, 1197, -4, 1199, -4, 1201, -4,  // NOLINT
-  1203, -4, 1205, -4, 1207, -4, 1209, -4, 1211, -4, 1213, -4, 1215, -4, 1218, -4,  // NOLINT
-  1220, -4, 1222, -4, 1224, -4, 1226, -4, 1228, -4, 1230, -4, 1231, -60, 1233, -4,  // NOLINT
-  1235, -4, 1237, -4, 1239, -4, 1241, -4, 1243, -4, 1245, -4, 1247, -4, 1249, -4,  // NOLINT
-  1251, -4, 1253, -4, 1255, -4, 1257, -4, 1259, -4, 1261, -4, 1263, -4, 1265, -4,  // NOLINT
-  1267, -4, 1269, -4, 1271, -4, 1273, -4, 1275, -4, 1277, -4, 1279, -4, 1281, -4,  // NOLINT
-  1283, -4, 1285, -4, 1287, -4, 1289, -4, 1291, -4, 1293, -4, 1295, -4, 1297, -4,  // NOLINT
-  1299, -4, 1301, -4, 1303, -4, 1305, -4, 1307, -4, 1309, -4, 1311, -4, 1313, -4,  // NOLINT
-  1315, -4, 1317, -4, 1319, -4, 1073743201, -192, 1414, -192, 1415, 21, 7545, 141328, 7549, 15256,  // NOLINT
-  7681, -4, 7683, -4, 7685, -4, 7687, -4, 7689, -4, 7691, -4, 7693, -4, 7695, -4,  // NOLINT
-  7697, -4, 7699, -4, 7701, -4, 7703, -4, 7705, -4, 7707, -4, 7709, -4, 7711, -4,  // NOLINT
-  7713, -4, 7715, -4, 7717, -4, 7719, -4, 7721, -4, 7723, -4, 7725, -4, 7727, -4,  // NOLINT
-  7729, -4, 7731, -4, 7733, -4, 7735, -4, 7737, -4, 7739, -4, 7741, -4, 7743, -4,  // NOLINT
-  7745, -4, 7747, -4, 7749, -4, 7751, -4, 7753, -4, 7755, -4, 7757, -4, 7759, -4,  // NOLINT
-  7761, -4, 7763, -4, 7765, -4, 7767, -4, 7769, -4, 7771, -4, 7773, -4, 7775, -4,  // NOLINT
-  7777, -4, 7779, -4, 7781, -4, 7783, -4, 7785, -4, 7787, -4, 7789, -4, 7791, -4,  // NOLINT
-  7793, -4, 7795, -4, 7797, -4, 7799, -4, 7801, -4, 7803, -4, 7805, -4, 7807, -4,  // NOLINT
-  7809, -4, 7811, -4, 7813, -4, 7815, -4, 7817, -4, 7819, -4, 7821, -4, 7823, -4,  // NOLINT
-  7825, -4, 7827, -4, 7829, -4, 7830, 25, 7831, 29, 7832, 33, 7833, 37, 7834, 41,  // NOLINT
-  7835, -236, 7841, -4, 7843, -4, 7845, -4, 7847, -4, 7849, -4, 7851, -4, 7853, -4,  // NOLINT
-  7855, -4, 7857, -4, 7859, -4, 7861, -4, 7863, -4, 7865, -4, 7867, -4, 7869, -4,  // NOLINT
-  7871, -4, 7873, -4, 7875, -4, 7877, -4, 7879, -4, 7881, -4, 7883, -4, 7885, -4,  // NOLINT
-  7887, -4, 7889, -4, 7891, -4, 7893, -4, 7895, -4, 7897, -4, 7899, -4, 7901, -4,  // NOLINT
-  7903, -4, 7905, -4, 7907, -4, 7909, -4, 7911, -4, 7913, -4, 7915, -4, 7917, -4,  // NOLINT
-  7919, -4, 7921, -4, 7923, -4, 7925, -4, 7927, -4, 7929, -4, 7931, -4, 7933, -4,  // NOLINT
-  7935, -4, 1073749760, 32, 7943, 32, 1073749776, 32, 7957, 32, 1073749792, 32, 7975, 32, 1073749808, 32,  // NOLINT
-  7991, 32, 1073749824, 32, 8005, 32, 8016, 45, 8017, 32, 8018, 49, 8019, 32, 8020, 53,  // NOLINT
-  8021, 32, 8022, 57, 8023, 32, 1073749856, 32, 8039, 32, 1073749872, 296, 8049, 296, 1073749874, 344,  // NOLINT
-  8053, 344, 1073749878, 400, 8055, 400, 1073749880, 512, 8057, 512, 1073749882, 448, 8059, 448, 1073749884, 504,  // NOLINT
-  8061, 504, 8064, 61, 8065, 65, 8066, 69, 8067, 73, 8068, 77, 8069, 81, 8070, 85,  // NOLINT
-  8071, 89, 8072, 61, 8073, 65, 8074, 69, 8075, 73, 8076, 77, 8077, 81, 8078, 85,  // NOLINT
-  8079, 89, 8080, 93, 8081, 97, 8082, 101, 8083, 105, 8084, 109, 8085, 113, 8086, 117,  // NOLINT
-  8087, 121, 8088, 93, 8089, 97, 8090, 101, 8091, 105, 8092, 109, 8093, 113, 8094, 117,  // NOLINT
-  8095, 121, 8096, 125, 8097, 129, 8098, 133, 8099, 137, 8100, 141, 8101, 145, 8102, 149,  // NOLINT
-  8103, 153, 8104, 125, 8105, 129, 8106, 133, 8107, 137, 8108, 141, 8109, 145, 8110, 149,  // NOLINT
-  8111, 153, 1073749936, 32, 8113, 32, 8114, 157, 8115, 161, 8116, 165, 8118, 169, 8119, 173,  // NOLINT
-  8124, 161, 8126, -28820, 8130, 177, 8131, 181, 8132, 185, 8134, 189, 8135, 193, 8140, 181,  // NOLINT
-  1073749968, 32, 8145, 32, 8146, 197, 8147, 13, 8150, 201, 8151, 205, 1073749984, 32, 8161, 32,  // NOLINT
-  8162, 209, 8163, 17, 8164, 213, 8165, 28, 8166, 217, 8167, 221, 8178, 225, 8179, 229,  // NOLINT
-  8180, 233, 8182, 237, 8183, 241, 8188, 229 };  // NOLINT
+static const uint16_t kToUppercaseTable0Size = 590;  // NOLINT
+static const int32_t kToUppercaseTable0[1180] = {
+    1073741921, -128,   122,        -128,   181,        2972,
+    223,        1,      1073742048, -128,   246,        -128,
+    1073742072, -128,   254,        -128,  // NOLINT
+    255,        484,    257,        -4,     259,        -4,
+    261,        -4,     263,        -4,     265,        -4,
+    267,        -4,     269,        -4,  // NOLINT
+    271,        -4,     273,        -4,     275,        -4,
+    277,        -4,     279,        -4,     281,        -4,
+    283,        -4,     285,        -4,  // NOLINT
+    287,        -4,     289,        -4,     291,        -4,
+    293,        -4,     295,        -4,     297,        -4,
+    299,        -4,     301,        -4,  // NOLINT
+    303,        -4,     305,        -928,   307,        -4,
+    309,        -4,     311,        -4,     314,        -4,
+    316,        -4,     318,        -4,  // NOLINT
+    320,        -4,     322,        -4,     324,        -4,
+    326,        -4,     328,        -4,     329,        5,
+    331,        -4,     333,        -4,  // NOLINT
+    335,        -4,     337,        -4,     339,        -4,
+    341,        -4,     343,        -4,     345,        -4,
+    347,        -4,     349,        -4,  // NOLINT
+    351,        -4,     353,        -4,     355,        -4,
+    357,        -4,     359,        -4,     361,        -4,
+    363,        -4,     365,        -4,  // NOLINT
+    367,        -4,     369,        -4,     371,        -4,
+    373,        -4,     375,        -4,     378,        -4,
+    380,        -4,     382,        -4,  // NOLINT
+    383,        -1200,  384,        780,    387,        -4,
+    389,        -4,     392,        -4,     396,        -4,
+    402,        -4,     405,        388,  // NOLINT
+    409,        -4,     410,        652,    414,        520,
+    417,        -4,     419,        -4,     421,        -4,
+    424,        -4,     429,        -4,  // NOLINT
+    432,        -4,     436,        -4,     438,        -4,
+    441,        -4,     445,        -4,     447,        224,
+    453,        -4,     454,        -8,  // NOLINT
+    456,        -4,     457,        -8,     459,        -4,
+    460,        -8,     462,        -4,     464,        -4,
+    466,        -4,     468,        -4,  // NOLINT
+    470,        -4,     472,        -4,     474,        -4,
+    476,        -4,     477,        -316,   479,        -4,
+    481,        -4,     483,        -4,  // NOLINT
+    485,        -4,     487,        -4,     489,        -4,
+    491,        -4,     493,        -4,     495,        -4,
+    496,        9,      498,        -4,  // NOLINT
+    499,        -8,     501,        -4,     505,        -4,
+    507,        -4,     509,        -4,     511,        -4,
+    513,        -4,     515,        -4,  // NOLINT
+    517,        -4,     519,        -4,     521,        -4,
+    523,        -4,     525,        -4,     527,        -4,
+    529,        -4,     531,        -4,  // NOLINT
+    533,        -4,     535,        -4,     537,        -4,
+    539,        -4,     541,        -4,     543,        -4,
+    547,        -4,     549,        -4,  // NOLINT
+    551,        -4,     553,        -4,     555,        -4,
+    557,        -4,     559,        -4,     561,        -4,
+    563,        -4,     572,        -4,  // NOLINT
+    1073742399, 43260,  576,        43260,  578,        -4,
+    583,        -4,     585,        -4,     587,        -4,
+    589,        -4,     591,        -4,  // NOLINT
+    592,        43132,  593,        43120,  594,        43128,
+    595,        -840,   596,        -824,   1073742422, -820,
+    599,        -820,   601,        -808,  // NOLINT
+    603,        -812,   604,        169276, 608,        -820,
+    609,        169260, 611,        -828,   613,        169120,
+    614,        169232, 616,        -836,  // NOLINT
+    617,        -844,   619,        42972,  620,        169220,
+    623,        -844,   625,        42996,  626,        -852,
+    629,        -856,   637,        42908,  // NOLINT
+    640,        -872,   643,        -872,   647,        169128,
+    648,        -872,   649,        -276,   1073742474, -868,
+    651,        -868,   652,        -284,  // NOLINT
+    658,        -876,   670,        169032, 837,        336,
+    881,        -4,     883,        -4,     887,        -4,
+    1073742715, 520,    893,        520,  // NOLINT
+    912,        13,     940,        -152,   1073742765, -148,
+    943,        -148,   944,        17,     1073742769, -128,
+    961,        -128,   962,        -124,  // NOLINT
+    1073742787, -128,   971,        -128,   972,        -256,
+    1073742797, -252,   974,        -252,   976,        -248,
+    977,        -228,   981,        -188,  // NOLINT
+    982,        -216,   983,        -32,    985,        -4,
+    987,        -4,     989,        -4,     991,        -4,
+    993,        -4,     995,        -4,  // NOLINT
+    997,        -4,     999,        -4,     1001,       -4,
+    1003,       -4,     1005,       -4,     1007,       -4,
+    1008,       -344,   1009,       -320,  // NOLINT
+    1010,       28,     1011,       -464,   1013,       -384,
+    1016,       -4,     1019,       -4,     1073742896, -128,
+    1103,       -128,   1073742928, -320,  // NOLINT
+    1119,       -320,   1121,       -4,     1123,       -4,
+    1125,       -4,     1127,       -4,     1129,       -4,
+    1131,       -4,     1133,       -4,  // NOLINT
+    1135,       -4,     1137,       -4,     1139,       -4,
+    1141,       -4,     1143,       -4,     1145,       -4,
+    1147,       -4,     1149,       -4,  // NOLINT
+    1151,       -4,     1153,       -4,     1163,       -4,
+    1165,       -4,     1167,       -4,     1169,       -4,
+    1171,       -4,     1173,       -4,  // NOLINT
+    1175,       -4,     1177,       -4,     1179,       -4,
+    1181,       -4,     1183,       -4,     1185,       -4,
+    1187,       -4,     1189,       -4,  // NOLINT
+    1191,       -4,     1193,       -4,     1195,       -4,
+    1197,       -4,     1199,       -4,     1201,       -4,
+    1203,       -4,     1205,       -4,  // NOLINT
+    1207,       -4,     1209,       -4,     1211,       -4,
+    1213,       -4,     1215,       -4,     1218,       -4,
+    1220,       -4,     1222,       -4,  // NOLINT
+    1224,       -4,     1226,       -4,     1228,       -4,
+    1230,       -4,     1231,       -60,    1233,       -4,
+    1235,       -4,     1237,       -4,  // NOLINT
+    1239,       -4,     1241,       -4,     1243,       -4,
+    1245,       -4,     1247,       -4,     1249,       -4,
+    1251,       -4,     1253,       -4,  // NOLINT
+    1255,       -4,     1257,       -4,     1259,       -4,
+    1261,       -4,     1263,       -4,     1265,       -4,
+    1267,       -4,     1269,       -4,  // NOLINT
+    1271,       -4,     1273,       -4,     1275,       -4,
+    1277,       -4,     1279,       -4,     1281,       -4,
+    1283,       -4,     1285,       -4,  // NOLINT
+    1287,       -4,     1289,       -4,     1291,       -4,
+    1293,       -4,     1295,       -4,     1297,       -4,
+    1299,       -4,     1301,       -4,  // NOLINT
+    1303,       -4,     1305,       -4,     1307,       -4,
+    1309,       -4,     1311,       -4,     1313,       -4,
+    1315,       -4,     1317,       -4,  // NOLINT
+    1319,       -4,     1321,       -4,     1323,       -4,
+    1325,       -4,     1327,       -4,     1073743201, -192,
+    1414,       -192,   1415,       21,  // NOLINT
+    7545,       141328, 7549,       15256,  7681,       -4,
+    7683,       -4,     7685,       -4,     7687,       -4,
+    7689,       -4,     7691,       -4,  // NOLINT
+    7693,       -4,     7695,       -4,     7697,       -4,
+    7699,       -4,     7701,       -4,     7703,       -4,
+    7705,       -4,     7707,       -4,  // NOLINT
+    7709,       -4,     7711,       -4,     7713,       -4,
+    7715,       -4,     7717,       -4,     7719,       -4,
+    7721,       -4,     7723,       -4,  // NOLINT
+    7725,       -4,     7727,       -4,     7729,       -4,
+    7731,       -4,     7733,       -4,     7735,       -4,
+    7737,       -4,     7739,       -4,  // NOLINT
+    7741,       -4,     7743,       -4,     7745,       -4,
+    7747,       -4,     7749,       -4,     7751,       -4,
+    7753,       -4,     7755,       -4,  // NOLINT
+    7757,       -4,     7759,       -4,     7761,       -4,
+    7763,       -4,     7765,       -4,     7767,       -4,
+    7769,       -4,     7771,       -4,  // NOLINT
+    7773,       -4,     7775,       -4,     7777,       -4,
+    7779,       -4,     7781,       -4,     7783,       -4,
+    7785,       -4,     7787,       -4,  // NOLINT
+    7789,       -4,     7791,       -4,     7793,       -4,
+    7795,       -4,     7797,       -4,     7799,       -4,
+    7801,       -4,     7803,       -4,  // NOLINT
+    7805,       -4,     7807,       -4,     7809,       -4,
+    7811,       -4,     7813,       -4,     7815,       -4,
+    7817,       -4,     7819,       -4,  // NOLINT
+    7821,       -4,     7823,       -4,     7825,       -4,
+    7827,       -4,     7829,       -4,     7830,       25,
+    7831,       29,     7832,       33,  // NOLINT
+    7833,       37,     7834,       41,     7835,       -236,
+    7841,       -4,     7843,       -4,     7845,       -4,
+    7847,       -4,     7849,       -4,  // NOLINT
+    7851,       -4,     7853,       -4,     7855,       -4,
+    7857,       -4,     7859,       -4,     7861,       -4,
+    7863,       -4,     7865,       -4,  // NOLINT
+    7867,       -4,     7869,       -4,     7871,       -4,
+    7873,       -4,     7875,       -4,     7877,       -4,
+    7879,       -4,     7881,       -4,  // NOLINT
+    7883,       -4,     7885,       -4,     7887,       -4,
+    7889,       -4,     7891,       -4,     7893,       -4,
+    7895,       -4,     7897,       -4,  // NOLINT
+    7899,       -4,     7901,       -4,     7903,       -4,
+    7905,       -4,     7907,       -4,     7909,       -4,
+    7911,       -4,     7913,       -4,  // NOLINT
+    7915,       -4,     7917,       -4,     7919,       -4,
+    7921,       -4,     7923,       -4,     7925,       -4,
+    7927,       -4,     7929,       -4,  // NOLINT
+    7931,       -4,     7933,       -4,     7935,       -4,
+    1073749760, 32,     7943,       32,     1073749776, 32,
+    7957,       32,     1073749792, 32,  // NOLINT
+    7975,       32,     1073749808, 32,     7991,       32,
+    1073749824, 32,     8005,       32,     8016,       45,
+    8017,       32,     8018,       49,  // NOLINT
+    8019,       32,     8020,       53,     8021,       32,
+    8022,       57,     8023,       32,     1073749856, 32,
+    8039,       32,     1073749872, 296,  // NOLINT
+    8049,       296,    1073749874, 344,    8053,       344,
+    1073749878, 400,    8055,       400,    1073749880, 512,
+    8057,       512,    1073749882, 448,  // NOLINT
+    8059,       448,    1073749884, 504,    8061,       504,
+    8064,       61,     8065,       65,     8066,       69,
+    8067,       73,     8068,       77,  // NOLINT
+    8069,       81,     8070,       85,     8071,       89,
+    8072,       61,     8073,       65,     8074,       69,
+    8075,       73,     8076,       77,  // NOLINT
+    8077,       81,     8078,       85,     8079,       89,
+    8080,       93,     8081,       97,     8082,       101,
+    8083,       105,    8084,       109,  // NOLINT
+    8085,       113,    8086,       117,    8087,       121,
+    8088,       93,     8089,       97,     8090,       101,
+    8091,       105,    8092,       109,  // NOLINT
+    8093,       113,    8094,       117,    8095,       121,
+    8096,       125,    8097,       129,    8098,       133,
+    8099,       137,    8100,       141,  // NOLINT
+    8101,       145,    8102,       149,    8103,       153,
+    8104,       125,    8105,       129,    8106,       133,
+    8107,       137,    8108,       141,  // NOLINT
+    8109,       145,    8110,       149,    8111,       153,
+    1073749936, 32,     8113,       32,     8114,       157,
+    8115,       161,    8116,       165,  // NOLINT
+    8118,       169,    8119,       173,    8124,       161,
+    8126,       -28820, 8130,       177,    8131,       181,
+    8132,       185,    8134,       189,  // NOLINT
+    8135,       193,    8140,       181,    1073749968, 32,
+    8145,       32,     8146,       197,    8147,       13,
+    8150,       201,    8151,       205,  // NOLINT
+    1073749984, 32,     8161,       32,     8162,       209,
+    8163,       17,     8164,       213,    8165,       28,
+    8166,       217,    8167,       221,  // NOLINT
+    8178,       225,    8179,       229,    8180,       233,
+    8182,       237,    8183,       241,    8188,       229};  // NOLINT
 static const uint16_t kToUppercaseMultiStrings0Size = 62;  // NOLINT
 static const MultiCharacterSpecialCase<1> kToUppercaseMultiStrings1[1] = {  // NOLINT
   {{kSentinel}} }; // NOLINT
@@ -1117,19 +1749,32 @@
 static const uint16_t kToUppercaseMultiStrings1Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<1> kToUppercaseMultiStrings5[1] = {  // NOLINT
   {{kSentinel}} }; // NOLINT
-static const uint16_t kToUppercaseTable5Size = 88;  // NOLINT
-static const int32_t kToUppercaseTable5[176] = {
-  1601, -4, 1603, -4, 1605, -4, 1607, -4, 1609, -4, 1611, -4, 1613, -4, 1615, -4,  // NOLINT
-  1617, -4, 1619, -4, 1621, -4, 1623, -4, 1625, -4, 1627, -4, 1629, -4, 1631, -4,  // NOLINT
-  1633, -4, 1635, -4, 1637, -4, 1639, -4, 1641, -4, 1643, -4, 1645, -4, 1665, -4,  // NOLINT
-  1667, -4, 1669, -4, 1671, -4, 1673, -4, 1675, -4, 1677, -4, 1679, -4, 1681, -4,  // NOLINT
-  1683, -4, 1685, -4, 1687, -4, 1827, -4, 1829, -4, 1831, -4, 1833, -4, 1835, -4,  // NOLINT
-  1837, -4, 1839, -4, 1843, -4, 1845, -4, 1847, -4, 1849, -4, 1851, -4, 1853, -4,  // NOLINT
-  1855, -4, 1857, -4, 1859, -4, 1861, -4, 1863, -4, 1865, -4, 1867, -4, 1869, -4,  // NOLINT
-  1871, -4, 1873, -4, 1875, -4, 1877, -4, 1879, -4, 1881, -4, 1883, -4, 1885, -4,  // NOLINT
-  1887, -4, 1889, -4, 1891, -4, 1893, -4, 1895, -4, 1897, -4, 1899, -4, 1901, -4,  // NOLINT
-  1903, -4, 1914, -4, 1916, -4, 1919, -4, 1921, -4, 1923, -4, 1925, -4, 1927, -4,  // NOLINT
-  1932, -4, 1937, -4, 1939, -4, 1953, -4, 1955, -4, 1957, -4, 1959, -4, 1961, -4 };  // NOLINT
+static const uint16_t kToUppercaseTable5Size = 95;  // NOLINT
+static const int32_t
+    kToUppercaseTable5[190] = {1601, -4, 1603, -4, 1605, -4, 1607, -4, 1609, -4,
+                               1611, -4, 1613, -4, 1615, -4,  // NOLINT
+                               1617, -4, 1619, -4, 1621, -4, 1623, -4, 1625, -4,
+                               1627, -4, 1629, -4, 1631, -4,  // NOLINT
+                               1633, -4, 1635, -4, 1637, -4, 1639, -4, 1641, -4,
+                               1643, -4, 1645, -4, 1665, -4,  // NOLINT
+                               1667, -4, 1669, -4, 1671, -4, 1673, -4, 1675, -4,
+                               1677, -4, 1679, -4, 1681, -4,  // NOLINT
+                               1683, -4, 1685, -4, 1687, -4, 1689, -4, 1691, -4,
+                               1827, -4, 1829, -4, 1831, -4,  // NOLINT
+                               1833, -4, 1835, -4, 1837, -4, 1839, -4, 1843, -4,
+                               1845, -4, 1847, -4, 1849, -4,  // NOLINT
+                               1851, -4, 1853, -4, 1855, -4, 1857, -4, 1859, -4,
+                               1861, -4, 1863, -4, 1865, -4,  // NOLINT
+                               1867, -4, 1869, -4, 1871, -4, 1873, -4, 1875, -4,
+                               1877, -4, 1879, -4, 1881, -4,  // NOLINT
+                               1883, -4, 1885, -4, 1887, -4, 1889, -4, 1891, -4,
+                               1893, -4, 1895, -4, 1897, -4,  // NOLINT
+                               1899, -4, 1901, -4, 1903, -4, 1914, -4, 1916, -4,
+                               1919, -4, 1921, -4, 1923, -4,  // NOLINT
+                               1925, -4, 1927, -4, 1932, -4, 1937, -4, 1939, -4,
+                               1943, -4, 1945, -4, 1947, -4,  // NOLINT
+                               1949, -4, 1951, -4, 1953, -4, 1955, -4, 1957, -4,
+                               1959, -4, 1961, -4};       // NOLINT
 static const uint16_t kToUppercaseMultiStrings5Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<3> kToUppercaseMultiStrings7[12] = {  // NOLINT
   {{70, 70, kSentinel}}, {{70, 73, kSentinel}}, {{70, 76, kSentinel}}, {{70, 70, 73}},  // NOLINT
@@ -1180,69 +1825,195 @@
 
 static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings0[1] = {  // NOLINT
   {{kSentinel}} }; // NOLINT
-static const uint16_t kEcma262CanonicalizeTable0Size = 488;  // NOLINT
-static const int32_t kEcma262CanonicalizeTable0[976] = {
-  1073741921, -128, 122, -128, 181, 2972, 1073742048, -128, 246, -128, 1073742072, -128, 254, -128, 255, 484,  // NOLINT
-  257, -4, 259, -4, 261, -4, 263, -4, 265, -4, 267, -4, 269, -4, 271, -4,  // NOLINT
-  273, -4, 275, -4, 277, -4, 279, -4, 281, -4, 283, -4, 285, -4, 287, -4,  // NOLINT
-  289, -4, 291, -4, 293, -4, 295, -4, 297, -4, 299, -4, 301, -4, 303, -4,  // NOLINT
-  307, -4, 309, -4, 311, -4, 314, -4, 316, -4, 318, -4, 320, -4, 322, -4,  // NOLINT
-  324, -4, 326, -4, 328, -4, 331, -4, 333, -4, 335, -4, 337, -4, 339, -4,  // NOLINT
-  341, -4, 343, -4, 345, -4, 347, -4, 349, -4, 351, -4, 353, -4, 355, -4,  // NOLINT
-  357, -4, 359, -4, 361, -4, 363, -4, 365, -4, 367, -4, 369, -4, 371, -4,  // NOLINT
-  373, -4, 375, -4, 378, -4, 380, -4, 382, -4, 384, 780, 387, -4, 389, -4,  // NOLINT
-  392, -4, 396, -4, 402, -4, 405, 388, 409, -4, 410, 652, 414, 520, 417, -4,  // NOLINT
-  419, -4, 421, -4, 424, -4, 429, -4, 432, -4, 436, -4, 438, -4, 441, -4,  // NOLINT
-  445, -4, 447, 224, 453, -4, 454, -8, 456, -4, 457, -8, 459, -4, 460, -8,  // NOLINT
-  462, -4, 464, -4, 466, -4, 468, -4, 470, -4, 472, -4, 474, -4, 476, -4,  // NOLINT
-  477, -316, 479, -4, 481, -4, 483, -4, 485, -4, 487, -4, 489, -4, 491, -4,  // NOLINT
-  493, -4, 495, -4, 498, -4, 499, -8, 501, -4, 505, -4, 507, -4, 509, -4,  // NOLINT
-  511, -4, 513, -4, 515, -4, 517, -4, 519, -4, 521, -4, 523, -4, 525, -4,  // NOLINT
-  527, -4, 529, -4, 531, -4, 533, -4, 535, -4, 537, -4, 539, -4, 541, -4,  // NOLINT
-  543, -4, 547, -4, 549, -4, 551, -4, 553, -4, 555, -4, 557, -4, 559, -4,  // NOLINT
-  561, -4, 563, -4, 572, -4, 1073742399, 43260, 576, 43260, 578, -4, 583, -4, 585, -4,  // NOLINT
-  587, -4, 589, -4, 591, -4, 592, 43132, 593, 43120, 594, 43128, 595, -840, 596, -824,  // NOLINT
-  1073742422, -820, 599, -820, 601, -808, 603, -812, 608, -820, 611, -828, 613, 169120, 614, 169232,  // NOLINT
-  616, -836, 617, -844, 619, 42972, 623, -844, 625, 42996, 626, -852, 629, -856, 637, 42908,  // NOLINT
-  640, -872, 643, -872, 648, -872, 649, -276, 1073742474, -868, 651, -868, 652, -284, 658, -876,  // NOLINT
-  837, 336, 881, -4, 883, -4, 887, -4, 1073742715, 520, 893, 520, 940, -152, 1073742765, -148,  // NOLINT
-  943, -148, 1073742769, -128, 961, -128, 962, -124, 1073742787, -128, 971, -128, 972, -256, 1073742797, -252,  // NOLINT
-  974, -252, 976, -248, 977, -228, 981, -188, 982, -216, 983, -32, 985, -4, 987, -4,  // NOLINT
-  989, -4, 991, -4, 993, -4, 995, -4, 997, -4, 999, -4, 1001, -4, 1003, -4,  // NOLINT
-  1005, -4, 1007, -4, 1008, -344, 1009, -320, 1010, 28, 1013, -384, 1016, -4, 1019, -4,  // NOLINT
-  1073742896, -128, 1103, -128, 1073742928, -320, 1119, -320, 1121, -4, 1123, -4, 1125, -4, 1127, -4,  // NOLINT
-  1129, -4, 1131, -4, 1133, -4, 1135, -4, 1137, -4, 1139, -4, 1141, -4, 1143, -4,  // NOLINT
-  1145, -4, 1147, -4, 1149, -4, 1151, -4, 1153, -4, 1163, -4, 1165, -4, 1167, -4,  // NOLINT
-  1169, -4, 1171, -4, 1173, -4, 1175, -4, 1177, -4, 1179, -4, 1181, -4, 1183, -4,  // NOLINT
-  1185, -4, 1187, -4, 1189, -4, 1191, -4, 1193, -4, 1195, -4, 1197, -4, 1199, -4,  // NOLINT
-  1201, -4, 1203, -4, 1205, -4, 1207, -4, 1209, -4, 1211, -4, 1213, -4, 1215, -4,  // NOLINT
-  1218, -4, 1220, -4, 1222, -4, 1224, -4, 1226, -4, 1228, -4, 1230, -4, 1231, -60,  // NOLINT
-  1233, -4, 1235, -4, 1237, -4, 1239, -4, 1241, -4, 1243, -4, 1245, -4, 1247, -4,  // NOLINT
-  1249, -4, 1251, -4, 1253, -4, 1255, -4, 1257, -4, 1259, -4, 1261, -4, 1263, -4,  // NOLINT
-  1265, -4, 1267, -4, 1269, -4, 1271, -4, 1273, -4, 1275, -4, 1277, -4, 1279, -4,  // NOLINT
-  1281, -4, 1283, -4, 1285, -4, 1287, -4, 1289, -4, 1291, -4, 1293, -4, 1295, -4,  // NOLINT
-  1297, -4, 1299, -4, 1301, -4, 1303, -4, 1305, -4, 1307, -4, 1309, -4, 1311, -4,  // NOLINT
-  1313, -4, 1315, -4, 1317, -4, 1319, -4, 1073743201, -192, 1414, -192, 7545, 141328, 7549, 15256,  // NOLINT
-  7681, -4, 7683, -4, 7685, -4, 7687, -4, 7689, -4, 7691, -4, 7693, -4, 7695, -4,  // NOLINT
-  7697, -4, 7699, -4, 7701, -4, 7703, -4, 7705, -4, 7707, -4, 7709, -4, 7711, -4,  // NOLINT
-  7713, -4, 7715, -4, 7717, -4, 7719, -4, 7721, -4, 7723, -4, 7725, -4, 7727, -4,  // NOLINT
-  7729, -4, 7731, -4, 7733, -4, 7735, -4, 7737, -4, 7739, -4, 7741, -4, 7743, -4,  // NOLINT
-  7745, -4, 7747, -4, 7749, -4, 7751, -4, 7753, -4, 7755, -4, 7757, -4, 7759, -4,  // NOLINT
-  7761, -4, 7763, -4, 7765, -4, 7767, -4, 7769, -4, 7771, -4, 7773, -4, 7775, -4,  // NOLINT
-  7777, -4, 7779, -4, 7781, -4, 7783, -4, 7785, -4, 7787, -4, 7789, -4, 7791, -4,  // NOLINT
-  7793, -4, 7795, -4, 7797, -4, 7799, -4, 7801, -4, 7803, -4, 7805, -4, 7807, -4,  // NOLINT
-  7809, -4, 7811, -4, 7813, -4, 7815, -4, 7817, -4, 7819, -4, 7821, -4, 7823, -4,  // NOLINT
-  7825, -4, 7827, -4, 7829, -4, 7835, -236, 7841, -4, 7843, -4, 7845, -4, 7847, -4,  // NOLINT
-  7849, -4, 7851, -4, 7853, -4, 7855, -4, 7857, -4, 7859, -4, 7861, -4, 7863, -4,  // NOLINT
-  7865, -4, 7867, -4, 7869, -4, 7871, -4, 7873, -4, 7875, -4, 7877, -4, 7879, -4,  // NOLINT
-  7881, -4, 7883, -4, 7885, -4, 7887, -4, 7889, -4, 7891, -4, 7893, -4, 7895, -4,  // NOLINT
-  7897, -4, 7899, -4, 7901, -4, 7903, -4, 7905, -4, 7907, -4, 7909, -4, 7911, -4,  // NOLINT
-  7913, -4, 7915, -4, 7917, -4, 7919, -4, 7921, -4, 7923, -4, 7925, -4, 7927, -4,  // NOLINT
-  7929, -4, 7931, -4, 7933, -4, 7935, -4, 1073749760, 32, 7943, 32, 1073749776, 32, 7957, 32,  // NOLINT
-  1073749792, 32, 7975, 32, 1073749808, 32, 7991, 32, 1073749824, 32, 8005, 32, 8017, 32, 8019, 32,  // NOLINT
-  8021, 32, 8023, 32, 1073749856, 32, 8039, 32, 1073749872, 296, 8049, 296, 1073749874, 344, 8053, 344,  // NOLINT
-  1073749878, 400, 8055, 400, 1073749880, 512, 8057, 512, 1073749882, 448, 8059, 448, 1073749884, 504, 8061, 504,  // NOLINT
-  1073749936, 32, 8113, 32, 8126, -28820, 1073749968, 32, 8145, 32, 1073749984, 32, 8161, 32, 8165, 28 };  // NOLINT
+static const uint16_t kEcma262CanonicalizeTable0Size = 498;  // NOLINT
+static const int32_t kEcma262CanonicalizeTable0[996] = {
+    1073741921, -128,   122,        -128,   181,        2972,
+    1073742048, -128,   246,        -128,   1073742072, -128,
+    254,        -128,   255,        484,  // NOLINT
+    257,        -4,     259,        -4,     261,        -4,
+    263,        -4,     265,        -4,     267,        -4,
+    269,        -4,     271,        -4,  // NOLINT
+    273,        -4,     275,        -4,     277,        -4,
+    279,        -4,     281,        -4,     283,        -4,
+    285,        -4,     287,        -4,  // NOLINT
+    289,        -4,     291,        -4,     293,        -4,
+    295,        -4,     297,        -4,     299,        -4,
+    301,        -4,     303,        -4,  // NOLINT
+    307,        -4,     309,        -4,     311,        -4,
+    314,        -4,     316,        -4,     318,        -4,
+    320,        -4,     322,        -4,  // NOLINT
+    324,        -4,     326,        -4,     328,        -4,
+    331,        -4,     333,        -4,     335,        -4,
+    337,        -4,     339,        -4,  // NOLINT
+    341,        -4,     343,        -4,     345,        -4,
+    347,        -4,     349,        -4,     351,        -4,
+    353,        -4,     355,        -4,  // NOLINT
+    357,        -4,     359,        -4,     361,        -4,
+    363,        -4,     365,        -4,     367,        -4,
+    369,        -4,     371,        -4,  // NOLINT
+    373,        -4,     375,        -4,     378,        -4,
+    380,        -4,     382,        -4,     384,        780,
+    387,        -4,     389,        -4,  // NOLINT
+    392,        -4,     396,        -4,     402,        -4,
+    405,        388,    409,        -4,     410,        652,
+    414,        520,    417,        -4,  // NOLINT
+    419,        -4,     421,        -4,     424,        -4,
+    429,        -4,     432,        -4,     436,        -4,
+    438,        -4,     441,        -4,  // NOLINT
+    445,        -4,     447,        224,    453,        -4,
+    454,        -8,     456,        -4,     457,        -8,
+    459,        -4,     460,        -8,  // NOLINT
+    462,        -4,     464,        -4,     466,        -4,
+    468,        -4,     470,        -4,     472,        -4,
+    474,        -4,     476,        -4,  // NOLINT
+    477,        -316,   479,        -4,     481,        -4,
+    483,        -4,     485,        -4,     487,        -4,
+    489,        -4,     491,        -4,  // NOLINT
+    493,        -4,     495,        -4,     498,        -4,
+    499,        -8,     501,        -4,     505,        -4,
+    507,        -4,     509,        -4,  // NOLINT
+    511,        -4,     513,        -4,     515,        -4,
+    517,        -4,     519,        -4,     521,        -4,
+    523,        -4,     525,        -4,  // NOLINT
+    527,        -4,     529,        -4,     531,        -4,
+    533,        -4,     535,        -4,     537,        -4,
+    539,        -4,     541,        -4,  // NOLINT
+    543,        -4,     547,        -4,     549,        -4,
+    551,        -4,     553,        -4,     555,        -4,
+    557,        -4,     559,        -4,  // NOLINT
+    561,        -4,     563,        -4,     572,        -4,
+    1073742399, 43260,  576,        43260,  578,        -4,
+    583,        -4,     585,        -4,  // NOLINT
+    587,        -4,     589,        -4,     591,        -4,
+    592,        43132,  593,        43120,  594,        43128,
+    595,        -840,   596,        -824,  // NOLINT
+    1073742422, -820,   599,        -820,   601,        -808,
+    603,        -812,   604,        169276, 608,        -820,
+    609,        169260, 611,        -828,  // NOLINT
+    613,        169120, 614,        169232, 616,        -836,
+    617,        -844,   619,        42972,  620,        169220,
+    623,        -844,   625,        42996,  // NOLINT
+    626,        -852,   629,        -856,   637,        42908,
+    640,        -872,   643,        -872,   647,        169128,
+    648,        -872,   649,        -276,  // NOLINT
+    1073742474, -868,   651,        -868,   652,        -284,
+    658,        -876,   670,        169032, 837,        336,
+    881,        -4,     883,        -4,  // NOLINT
+    887,        -4,     1073742715, 520,    893,        520,
+    940,        -152,   1073742765, -148,   943,        -148,
+    1073742769, -128,   961,        -128,  // NOLINT
+    962,        -124,   1073742787, -128,   971,        -128,
+    972,        -256,   1073742797, -252,   974,        -252,
+    976,        -248,   977,        -228,  // NOLINT
+    981,        -188,   982,        -216,   983,        -32,
+    985,        -4,     987,        -4,     989,        -4,
+    991,        -4,     993,        -4,  // NOLINT
+    995,        -4,     997,        -4,     999,        -4,
+    1001,       -4,     1003,       -4,     1005,       -4,
+    1007,       -4,     1008,       -344,  // NOLINT
+    1009,       -320,   1010,       28,     1011,       -464,
+    1013,       -384,   1016,       -4,     1019,       -4,
+    1073742896, -128,   1103,       -128,  // NOLINT
+    1073742928, -320,   1119,       -320,   1121,       -4,
+    1123,       -4,     1125,       -4,     1127,       -4,
+    1129,       -4,     1131,       -4,  // NOLINT
+    1133,       -4,     1135,       -4,     1137,       -4,
+    1139,       -4,     1141,       -4,     1143,       -4,
+    1145,       -4,     1147,       -4,  // NOLINT
+    1149,       -4,     1151,       -4,     1153,       -4,
+    1163,       -4,     1165,       -4,     1167,       -4,
+    1169,       -4,     1171,       -4,  // NOLINT
+    1173,       -4,     1175,       -4,     1177,       -4,
+    1179,       -4,     1181,       -4,     1183,       -4,
+    1185,       -4,     1187,       -4,  // NOLINT
+    1189,       -4,     1191,       -4,     1193,       -4,
+    1195,       -4,     1197,       -4,     1199,       -4,
+    1201,       -4,     1203,       -4,  // NOLINT
+    1205,       -4,     1207,       -4,     1209,       -4,
+    1211,       -4,     1213,       -4,     1215,       -4,
+    1218,       -4,     1220,       -4,  // NOLINT
+    1222,       -4,     1224,       -4,     1226,       -4,
+    1228,       -4,     1230,       -4,     1231,       -60,
+    1233,       -4,     1235,       -4,  // NOLINT
+    1237,       -4,     1239,       -4,     1241,       -4,
+    1243,       -4,     1245,       -4,     1247,       -4,
+    1249,       -4,     1251,       -4,  // NOLINT
+    1253,       -4,     1255,       -4,     1257,       -4,
+    1259,       -4,     1261,       -4,     1263,       -4,
+    1265,       -4,     1267,       -4,  // NOLINT
+    1269,       -4,     1271,       -4,     1273,       -4,
+    1275,       -4,     1277,       -4,     1279,       -4,
+    1281,       -4,     1283,       -4,  // NOLINT
+    1285,       -4,     1287,       -4,     1289,       -4,
+    1291,       -4,     1293,       -4,     1295,       -4,
+    1297,       -4,     1299,       -4,  // NOLINT
+    1301,       -4,     1303,       -4,     1305,       -4,
+    1307,       -4,     1309,       -4,     1311,       -4,
+    1313,       -4,     1315,       -4,  // NOLINT
+    1317,       -4,     1319,       -4,     1321,       -4,
+    1323,       -4,     1325,       -4,     1327,       -4,
+    1073743201, -192,   1414,       -192,  // NOLINT
+    7545,       141328, 7549,       15256,  7681,       -4,
+    7683,       -4,     7685,       -4,     7687,       -4,
+    7689,       -4,     7691,       -4,  // NOLINT
+    7693,       -4,     7695,       -4,     7697,       -4,
+    7699,       -4,     7701,       -4,     7703,       -4,
+    7705,       -4,     7707,       -4,  // NOLINT
+    7709,       -4,     7711,       -4,     7713,       -4,
+    7715,       -4,     7717,       -4,     7719,       -4,
+    7721,       -4,     7723,       -4,  // NOLINT
+    7725,       -4,     7727,       -4,     7729,       -4,
+    7731,       -4,     7733,       -4,     7735,       -4,
+    7737,       -4,     7739,       -4,  // NOLINT
+    7741,       -4,     7743,       -4,     7745,       -4,
+    7747,       -4,     7749,       -4,     7751,       -4,
+    7753,       -4,     7755,       -4,  // NOLINT
+    7757,       -4,     7759,       -4,     7761,       -4,
+    7763,       -4,     7765,       -4,     7767,       -4,
+    7769,       -4,     7771,       -4,  // NOLINT
+    7773,       -4,     7775,       -4,     7777,       -4,
+    7779,       -4,     7781,       -4,     7783,       -4,
+    7785,       -4,     7787,       -4,  // NOLINT
+    7789,       -4,     7791,       -4,     7793,       -4,
+    7795,       -4,     7797,       -4,     7799,       -4,
+    7801,       -4,     7803,       -4,  // NOLINT
+    7805,       -4,     7807,       -4,     7809,       -4,
+    7811,       -4,     7813,       -4,     7815,       -4,
+    7817,       -4,     7819,       -4,  // NOLINT
+    7821,       -4,     7823,       -4,     7825,       -4,
+    7827,       -4,     7829,       -4,     7835,       -236,
+    7841,       -4,     7843,       -4,  // NOLINT
+    7845,       -4,     7847,       -4,     7849,       -4,
+    7851,       -4,     7853,       -4,     7855,       -4,
+    7857,       -4,     7859,       -4,  // NOLINT
+    7861,       -4,     7863,       -4,     7865,       -4,
+    7867,       -4,     7869,       -4,     7871,       -4,
+    7873,       -4,     7875,       -4,  // NOLINT
+    7877,       -4,     7879,       -4,     7881,       -4,
+    7883,       -4,     7885,       -4,     7887,       -4,
+    7889,       -4,     7891,       -4,  // NOLINT
+    7893,       -4,     7895,       -4,     7897,       -4,
+    7899,       -4,     7901,       -4,     7903,       -4,
+    7905,       -4,     7907,       -4,  // NOLINT
+    7909,       -4,     7911,       -4,     7913,       -4,
+    7915,       -4,     7917,       -4,     7919,       -4,
+    7921,       -4,     7923,       -4,  // NOLINT
+    7925,       -4,     7927,       -4,     7929,       -4,
+    7931,       -4,     7933,       -4,     7935,       -4,
+    1073749760, 32,     7943,       32,  // NOLINT
+    1073749776, 32,     7957,       32,     1073749792, 32,
+    7975,       32,     1073749808, 32,     7991,       32,
+    1073749824, 32,     8005,       32,  // NOLINT
+    8017,       32,     8019,       32,     8021,       32,
+    8023,       32,     1073749856, 32,     8039,       32,
+    1073749872, 296,    8049,       296,  // NOLINT
+    1073749874, 344,    8053,       344,    1073749878, 400,
+    8055,       400,    1073749880, 512,    8057,       512,
+    1073749882, 448,    8059,       448,  // NOLINT
+    1073749884, 504,    8061,       504,    1073749936, 32,
+    8113,       32,     8126,       -28820, 1073749968, 32,
+    8145,       32,     1073749984, 32,                           // NOLINT
+    8161,       32,     8165,       28};                          // NOLINT
 static const uint16_t kEcma262CanonicalizeMultiStrings0Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings1[1] = {  // NOLINT
   {{kSentinel}} }; // NOLINT
@@ -1261,19 +2032,32 @@
 static const uint16_t kEcma262CanonicalizeMultiStrings1Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings5[1] = {  // NOLINT
   {{kSentinel}} }; // NOLINT
-static const uint16_t kEcma262CanonicalizeTable5Size = 88;  // NOLINT
-static const int32_t kEcma262CanonicalizeTable5[176] = {
-  1601, -4, 1603, -4, 1605, -4, 1607, -4, 1609, -4, 1611, -4, 1613, -4, 1615, -4,  // NOLINT
-  1617, -4, 1619, -4, 1621, -4, 1623, -4, 1625, -4, 1627, -4, 1629, -4, 1631, -4,  // NOLINT
-  1633, -4, 1635, -4, 1637, -4, 1639, -4, 1641, -4, 1643, -4, 1645, -4, 1665, -4,  // NOLINT
-  1667, -4, 1669, -4, 1671, -4, 1673, -4, 1675, -4, 1677, -4, 1679, -4, 1681, -4,  // NOLINT
-  1683, -4, 1685, -4, 1687, -4, 1827, -4, 1829, -4, 1831, -4, 1833, -4, 1835, -4,  // NOLINT
-  1837, -4, 1839, -4, 1843, -4, 1845, -4, 1847, -4, 1849, -4, 1851, -4, 1853, -4,  // NOLINT
-  1855, -4, 1857, -4, 1859, -4, 1861, -4, 1863, -4, 1865, -4, 1867, -4, 1869, -4,  // NOLINT
-  1871, -4, 1873, -4, 1875, -4, 1877, -4, 1879, -4, 1881, -4, 1883, -4, 1885, -4,  // NOLINT
-  1887, -4, 1889, -4, 1891, -4, 1893, -4, 1895, -4, 1897, -4, 1899, -4, 1901, -4,  // NOLINT
-  1903, -4, 1914, -4, 1916, -4, 1919, -4, 1921, -4, 1923, -4, 1925, -4, 1927, -4,  // NOLINT
-  1932, -4, 1937, -4, 1939, -4, 1953, -4, 1955, -4, 1957, -4, 1959, -4, 1961, -4 };  // NOLINT
+static const uint16_t kEcma262CanonicalizeTable5Size = 95;  // NOLINT
+static const int32_t kEcma262CanonicalizeTable5
+    [190] = {1601, -4, 1603, -4, 1605, -4, 1607, -4,
+             1609, -4, 1611, -4, 1613, -4, 1615, -4,  // NOLINT
+             1617, -4, 1619, -4, 1621, -4, 1623, -4,
+             1625, -4, 1627, -4, 1629, -4, 1631, -4,  // NOLINT
+             1633, -4, 1635, -4, 1637, -4, 1639, -4,
+             1641, -4, 1643, -4, 1645, -4, 1665, -4,  // NOLINT
+             1667, -4, 1669, -4, 1671, -4, 1673, -4,
+             1675, -4, 1677, -4, 1679, -4, 1681, -4,  // NOLINT
+             1683, -4, 1685, -4, 1687, -4, 1689, -4,
+             1691, -4, 1827, -4, 1829, -4, 1831, -4,  // NOLINT
+             1833, -4, 1835, -4, 1837, -4, 1839, -4,
+             1843, -4, 1845, -4, 1847, -4, 1849, -4,  // NOLINT
+             1851, -4, 1853, -4, 1855, -4, 1857, -4,
+             1859, -4, 1861, -4, 1863, -4, 1865, -4,  // NOLINT
+             1867, -4, 1869, -4, 1871, -4, 1873, -4,
+             1875, -4, 1877, -4, 1879, -4, 1881, -4,  // NOLINT
+             1883, -4, 1885, -4, 1887, -4, 1889, -4,
+             1891, -4, 1893, -4, 1895, -4, 1897, -4,  // NOLINT
+             1899, -4, 1901, -4, 1903, -4, 1914, -4,
+             1916, -4, 1919, -4, 1921, -4, 1923, -4,  // NOLINT
+             1925, -4, 1927, -4, 1932, -4, 1937, -4,
+             1939, -4, 1943, -4, 1945, -4, 1947, -4,  // NOLINT
+             1949, -4, 1951, -4, 1953, -4, 1955, -4,
+             1957, -4, 1959, -4, 1961, -4};                       // NOLINT
 static const uint16_t kEcma262CanonicalizeMultiStrings5Size = 1;  // NOLINT
 static const MultiCharacterSpecialCase<1> kEcma262CanonicalizeMultiStrings7[1] = {  // NOLINT
   {{kSentinel}} }; // NOLINT
@@ -1319,259 +2103,895 @@
   }
 }
 
-static const MultiCharacterSpecialCase<4> kEcma262UnCanonicalizeMultiStrings0[497] = {  // NOLINT
-  {{65, 97, kSentinel}}, {{90, 122, kSentinel}}, {{181, 924, 956, kSentinel}}, {{192, 224, kSentinel}},  // NOLINT
-  {{214, 246, kSentinel}}, {{216, 248, kSentinel}}, {{222, 254, kSentinel}}, {{255, 376, kSentinel}},  // NOLINT
-  {{256, 257, kSentinel}}, {{258, 259, kSentinel}}, {{260, 261, kSentinel}}, {{262, 263, kSentinel}},  // NOLINT
-  {{264, 265, kSentinel}}, {{266, 267, kSentinel}}, {{268, 269, kSentinel}}, {{270, 271, kSentinel}},  // NOLINT
-  {{272, 273, kSentinel}}, {{274, 275, kSentinel}}, {{276, 277, kSentinel}}, {{278, 279, kSentinel}},  // NOLINT
-  {{280, 281, kSentinel}}, {{282, 283, kSentinel}}, {{284, 285, kSentinel}}, {{286, 287, kSentinel}},  // NOLINT
-  {{288, 289, kSentinel}}, {{290, 291, kSentinel}}, {{292, 293, kSentinel}}, {{294, 295, kSentinel}},  // NOLINT
-  {{296, 297, kSentinel}}, {{298, 299, kSentinel}}, {{300, 301, kSentinel}}, {{302, 303, kSentinel}},  // NOLINT
-  {{306, 307, kSentinel}}, {{308, 309, kSentinel}}, {{310, 311, kSentinel}}, {{313, 314, kSentinel}},  // NOLINT
-  {{315, 316, kSentinel}}, {{317, 318, kSentinel}}, {{319, 320, kSentinel}}, {{321, 322, kSentinel}},  // NOLINT
-  {{323, 324, kSentinel}}, {{325, 326, kSentinel}}, {{327, 328, kSentinel}}, {{330, 331, kSentinel}},  // NOLINT
-  {{332, 333, kSentinel}}, {{334, 335, kSentinel}}, {{336, 337, kSentinel}}, {{338, 339, kSentinel}},  // NOLINT
-  {{340, 341, kSentinel}}, {{342, 343, kSentinel}}, {{344, 345, kSentinel}}, {{346, 347, kSentinel}},  // NOLINT
-  {{348, 349, kSentinel}}, {{350, 351, kSentinel}}, {{352, 353, kSentinel}}, {{354, 355, kSentinel}},  // NOLINT
-  {{356, 357, kSentinel}}, {{358, 359, kSentinel}}, {{360, 361, kSentinel}}, {{362, 363, kSentinel}},  // NOLINT
-  {{364, 365, kSentinel}}, {{366, 367, kSentinel}}, {{368, 369, kSentinel}}, {{370, 371, kSentinel}},  // NOLINT
-  {{372, 373, kSentinel}}, {{374, 375, kSentinel}}, {{377, 378, kSentinel}}, {{379, 380, kSentinel}},  // NOLINT
-  {{381, 382, kSentinel}}, {{384, 579, kSentinel}}, {{385, 595, kSentinel}}, {{386, 387, kSentinel}},  // NOLINT
-  {{388, 389, kSentinel}}, {{390, 596, kSentinel}}, {{391, 392, kSentinel}}, {{393, 598, kSentinel}},  // NOLINT
-  {{394, 599, kSentinel}}, {{395, 396, kSentinel}}, {{398, 477, kSentinel}}, {{399, 601, kSentinel}},  // NOLINT
-  {{400, 603, kSentinel}}, {{401, 402, kSentinel}}, {{403, 608, kSentinel}}, {{404, 611, kSentinel}},  // NOLINT
-  {{405, 502, kSentinel}}, {{406, 617, kSentinel}}, {{407, 616, kSentinel}}, {{408, 409, kSentinel}},  // NOLINT
-  {{410, 573, kSentinel}}, {{412, 623, kSentinel}}, {{413, 626, kSentinel}}, {{414, 544, kSentinel}},  // NOLINT
-  {{415, 629, kSentinel}}, {{416, 417, kSentinel}}, {{418, 419, kSentinel}}, {{420, 421, kSentinel}},  // NOLINT
-  {{422, 640, kSentinel}}, {{423, 424, kSentinel}}, {{425, 643, kSentinel}}, {{428, 429, kSentinel}},  // NOLINT
-  {{430, 648, kSentinel}}, {{431, 432, kSentinel}}, {{433, 650, kSentinel}}, {{434, 651, kSentinel}},  // NOLINT
-  {{435, 436, kSentinel}}, {{437, 438, kSentinel}}, {{439, 658, kSentinel}}, {{440, 441, kSentinel}},  // NOLINT
-  {{444, 445, kSentinel}}, {{447, 503, kSentinel}}, {{452, 453, 454, kSentinel}}, {{455, 456, 457, kSentinel}},  // NOLINT
-  {{458, 459, 460, kSentinel}}, {{461, 462, kSentinel}}, {{463, 464, kSentinel}}, {{465, 466, kSentinel}},  // NOLINT
-  {{467, 468, kSentinel}}, {{469, 470, kSentinel}}, {{471, 472, kSentinel}}, {{473, 474, kSentinel}},  // NOLINT
-  {{475, 476, kSentinel}}, {{478, 479, kSentinel}}, {{480, 481, kSentinel}}, {{482, 483, kSentinel}},  // NOLINT
-  {{484, 485, kSentinel}}, {{486, 487, kSentinel}}, {{488, 489, kSentinel}}, {{490, 491, kSentinel}},  // NOLINT
-  {{492, 493, kSentinel}}, {{494, 495, kSentinel}}, {{497, 498, 499, kSentinel}}, {{500, 501, kSentinel}},  // NOLINT
-  {{504, 505, kSentinel}}, {{506, 507, kSentinel}}, {{508, 509, kSentinel}}, {{510, 511, kSentinel}},  // NOLINT
-  {{512, 513, kSentinel}}, {{514, 515, kSentinel}}, {{516, 517, kSentinel}}, {{518, 519, kSentinel}},  // NOLINT
-  {{520, 521, kSentinel}}, {{522, 523, kSentinel}}, {{524, 525, kSentinel}}, {{526, 527, kSentinel}},  // NOLINT
-  {{528, 529, kSentinel}}, {{530, 531, kSentinel}}, {{532, 533, kSentinel}}, {{534, 535, kSentinel}},  // NOLINT
-  {{536, 537, kSentinel}}, {{538, 539, kSentinel}}, {{540, 541, kSentinel}}, {{542, 543, kSentinel}},  // NOLINT
-  {{546, 547, kSentinel}}, {{548, 549, kSentinel}}, {{550, 551, kSentinel}}, {{552, 553, kSentinel}},  // NOLINT
-  {{554, 555, kSentinel}}, {{556, 557, kSentinel}}, {{558, 559, kSentinel}}, {{560, 561, kSentinel}},  // NOLINT
-  {{562, 563, kSentinel}}, {{570, 11365, kSentinel}}, {{571, 572, kSentinel}}, {{574, 11366, kSentinel}},  // NOLINT
-  {{575, 11390, kSentinel}}, {{576, 11391, kSentinel}}, {{577, 578, kSentinel}}, {{580, 649, kSentinel}},  // NOLINT
-  {{581, 652, kSentinel}}, {{582, 583, kSentinel}}, {{584, 585, kSentinel}}, {{586, 587, kSentinel}},  // NOLINT
-  {{588, 589, kSentinel}}, {{590, 591, kSentinel}}, {{592, 11375, kSentinel}}, {{593, 11373, kSentinel}},  // NOLINT
-  {{594, 11376, kSentinel}}, {{613, 42893, kSentinel}}, {{614, 42922, kSentinel}}, {{619, 11362, kSentinel}},  // NOLINT
-  {{625, 11374, kSentinel}}, {{637, 11364, kSentinel}}, {{837, 921, 953, 8126}}, {{880, 881, kSentinel}},  // NOLINT
-  {{882, 883, kSentinel}}, {{886, 887, kSentinel}}, {{891, 1021, kSentinel}}, {{893, 1023, kSentinel}},  // NOLINT
-  {{902, 940, kSentinel}}, {{904, 941, kSentinel}}, {{906, 943, kSentinel}}, {{908, 972, kSentinel}},  // NOLINT
-  {{910, 973, kSentinel}}, {{911, 974, kSentinel}}, {{913, 945, kSentinel}}, {{914, 946, 976, kSentinel}},  // NOLINT
-  {{915, 947, kSentinel}}, {{916, 948, kSentinel}}, {{917, 949, 1013, kSentinel}}, {{918, 950, kSentinel}},  // NOLINT
-  {{919, 951, kSentinel}}, {{920, 952, 977, kSentinel}}, {{922, 954, 1008, kSentinel}}, {{923, 955, kSentinel}},  // NOLINT
-  {{925, 957, kSentinel}}, {{927, 959, kSentinel}}, {{928, 960, 982, kSentinel}}, {{929, 961, 1009, kSentinel}},  // NOLINT
-  {{931, 962, 963, kSentinel}}, {{932, 964, kSentinel}}, {{933, 965, kSentinel}}, {{934, 966, 981, kSentinel}},  // NOLINT
-  {{935, 967, kSentinel}}, {{939, 971, kSentinel}}, {{975, 983, kSentinel}}, {{984, 985, kSentinel}},  // NOLINT
-  {{986, 987, kSentinel}}, {{988, 989, kSentinel}}, {{990, 991, kSentinel}}, {{992, 993, kSentinel}},  // NOLINT
-  {{994, 995, kSentinel}}, {{996, 997, kSentinel}}, {{998, 999, kSentinel}}, {{1000, 1001, kSentinel}},  // NOLINT
-  {{1002, 1003, kSentinel}}, {{1004, 1005, kSentinel}}, {{1006, 1007, kSentinel}}, {{1010, 1017, kSentinel}},  // NOLINT
-  {{1015, 1016, kSentinel}}, {{1018, 1019, kSentinel}}, {{1024, 1104, kSentinel}}, {{1039, 1119, kSentinel}},  // NOLINT
-  {{1040, 1072, kSentinel}}, {{1071, 1103, kSentinel}}, {{1120, 1121, kSentinel}}, {{1122, 1123, kSentinel}},  // NOLINT
-  {{1124, 1125, kSentinel}}, {{1126, 1127, kSentinel}}, {{1128, 1129, kSentinel}}, {{1130, 1131, kSentinel}},  // NOLINT
-  {{1132, 1133, kSentinel}}, {{1134, 1135, kSentinel}}, {{1136, 1137, kSentinel}}, {{1138, 1139, kSentinel}},  // NOLINT
-  {{1140, 1141, kSentinel}}, {{1142, 1143, kSentinel}}, {{1144, 1145, kSentinel}}, {{1146, 1147, kSentinel}},  // NOLINT
-  {{1148, 1149, kSentinel}}, {{1150, 1151, kSentinel}}, {{1152, 1153, kSentinel}}, {{1162, 1163, kSentinel}},  // NOLINT
-  {{1164, 1165, kSentinel}}, {{1166, 1167, kSentinel}}, {{1168, 1169, kSentinel}}, {{1170, 1171, kSentinel}},  // NOLINT
-  {{1172, 1173, kSentinel}}, {{1174, 1175, kSentinel}}, {{1176, 1177, kSentinel}}, {{1178, 1179, kSentinel}},  // NOLINT
-  {{1180, 1181, kSentinel}}, {{1182, 1183, kSentinel}}, {{1184, 1185, kSentinel}}, {{1186, 1187, kSentinel}},  // NOLINT
-  {{1188, 1189, kSentinel}}, {{1190, 1191, kSentinel}}, {{1192, 1193, kSentinel}}, {{1194, 1195, kSentinel}},  // NOLINT
-  {{1196, 1197, kSentinel}}, {{1198, 1199, kSentinel}}, {{1200, 1201, kSentinel}}, {{1202, 1203, kSentinel}},  // NOLINT
-  {{1204, 1205, kSentinel}}, {{1206, 1207, kSentinel}}, {{1208, 1209, kSentinel}}, {{1210, 1211, kSentinel}},  // NOLINT
-  {{1212, 1213, kSentinel}}, {{1214, 1215, kSentinel}}, {{1216, 1231, kSentinel}}, {{1217, 1218, kSentinel}},  // NOLINT
-  {{1219, 1220, kSentinel}}, {{1221, 1222, kSentinel}}, {{1223, 1224, kSentinel}}, {{1225, 1226, kSentinel}},  // NOLINT
-  {{1227, 1228, kSentinel}}, {{1229, 1230, kSentinel}}, {{1232, 1233, kSentinel}}, {{1234, 1235, kSentinel}},  // NOLINT
-  {{1236, 1237, kSentinel}}, {{1238, 1239, kSentinel}}, {{1240, 1241, kSentinel}}, {{1242, 1243, kSentinel}},  // NOLINT
-  {{1244, 1245, kSentinel}}, {{1246, 1247, kSentinel}}, {{1248, 1249, kSentinel}}, {{1250, 1251, kSentinel}},  // NOLINT
-  {{1252, 1253, kSentinel}}, {{1254, 1255, kSentinel}}, {{1256, 1257, kSentinel}}, {{1258, 1259, kSentinel}},  // NOLINT
-  {{1260, 1261, kSentinel}}, {{1262, 1263, kSentinel}}, {{1264, 1265, kSentinel}}, {{1266, 1267, kSentinel}},  // NOLINT
-  {{1268, 1269, kSentinel}}, {{1270, 1271, kSentinel}}, {{1272, 1273, kSentinel}}, {{1274, 1275, kSentinel}},  // NOLINT
-  {{1276, 1277, kSentinel}}, {{1278, 1279, kSentinel}}, {{1280, 1281, kSentinel}}, {{1282, 1283, kSentinel}},  // NOLINT
-  {{1284, 1285, kSentinel}}, {{1286, 1287, kSentinel}}, {{1288, 1289, kSentinel}}, {{1290, 1291, kSentinel}},  // NOLINT
-  {{1292, 1293, kSentinel}}, {{1294, 1295, kSentinel}}, {{1296, 1297, kSentinel}}, {{1298, 1299, kSentinel}},  // NOLINT
-  {{1300, 1301, kSentinel}}, {{1302, 1303, kSentinel}}, {{1304, 1305, kSentinel}}, {{1306, 1307, kSentinel}},  // NOLINT
-  {{1308, 1309, kSentinel}}, {{1310, 1311, kSentinel}}, {{1312, 1313, kSentinel}}, {{1314, 1315, kSentinel}},  // NOLINT
-  {{1316, 1317, kSentinel}}, {{1318, 1319, kSentinel}}, {{1329, 1377, kSentinel}}, {{1366, 1414, kSentinel}},  // NOLINT
-  {{4256, 11520, kSentinel}}, {{4293, 11557, kSentinel}}, {{4295, 11559, kSentinel}}, {{4301, 11565, kSentinel}},  // NOLINT
-  {{7545, 42877, kSentinel}}, {{7549, 11363, kSentinel}}, {{7680, 7681, kSentinel}}, {{7682, 7683, kSentinel}},  // NOLINT
-  {{7684, 7685, kSentinel}}, {{7686, 7687, kSentinel}}, {{7688, 7689, kSentinel}}, {{7690, 7691, kSentinel}},  // NOLINT
-  {{7692, 7693, kSentinel}}, {{7694, 7695, kSentinel}}, {{7696, 7697, kSentinel}}, {{7698, 7699, kSentinel}},  // NOLINT
-  {{7700, 7701, kSentinel}}, {{7702, 7703, kSentinel}}, {{7704, 7705, kSentinel}}, {{7706, 7707, kSentinel}},  // NOLINT
-  {{7708, 7709, kSentinel}}, {{7710, 7711, kSentinel}}, {{7712, 7713, kSentinel}}, {{7714, 7715, kSentinel}},  // NOLINT
-  {{7716, 7717, kSentinel}}, {{7718, 7719, kSentinel}}, {{7720, 7721, kSentinel}}, {{7722, 7723, kSentinel}},  // NOLINT
-  {{7724, 7725, kSentinel}}, {{7726, 7727, kSentinel}}, {{7728, 7729, kSentinel}}, {{7730, 7731, kSentinel}},  // NOLINT
-  {{7732, 7733, kSentinel}}, {{7734, 7735, kSentinel}}, {{7736, 7737, kSentinel}}, {{7738, 7739, kSentinel}},  // NOLINT
-  {{7740, 7741, kSentinel}}, {{7742, 7743, kSentinel}}, {{7744, 7745, kSentinel}}, {{7746, 7747, kSentinel}},  // NOLINT
-  {{7748, 7749, kSentinel}}, {{7750, 7751, kSentinel}}, {{7752, 7753, kSentinel}}, {{7754, 7755, kSentinel}},  // NOLINT
-  {{7756, 7757, kSentinel}}, {{7758, 7759, kSentinel}}, {{7760, 7761, kSentinel}}, {{7762, 7763, kSentinel}},  // NOLINT
-  {{7764, 7765, kSentinel}}, {{7766, 7767, kSentinel}}, {{7768, 7769, kSentinel}}, {{7770, 7771, kSentinel}},  // NOLINT
-  {{7772, 7773, kSentinel}}, {{7774, 7775, kSentinel}}, {{7776, 7777, 7835, kSentinel}}, {{7778, 7779, kSentinel}},  // NOLINT
-  {{7780, 7781, kSentinel}}, {{7782, 7783, kSentinel}}, {{7784, 7785, kSentinel}}, {{7786, 7787, kSentinel}},  // NOLINT
-  {{7788, 7789, kSentinel}}, {{7790, 7791, kSentinel}}, {{7792, 7793, kSentinel}}, {{7794, 7795, kSentinel}},  // NOLINT
-  {{7796, 7797, kSentinel}}, {{7798, 7799, kSentinel}}, {{7800, 7801, kSentinel}}, {{7802, 7803, kSentinel}},  // NOLINT
-  {{7804, 7805, kSentinel}}, {{7806, 7807, kSentinel}}, {{7808, 7809, kSentinel}}, {{7810, 7811, kSentinel}},  // NOLINT
-  {{7812, 7813, kSentinel}}, {{7814, 7815, kSentinel}}, {{7816, 7817, kSentinel}}, {{7818, 7819, kSentinel}},  // NOLINT
-  {{7820, 7821, kSentinel}}, {{7822, 7823, kSentinel}}, {{7824, 7825, kSentinel}}, {{7826, 7827, kSentinel}},  // NOLINT
-  {{7828, 7829, kSentinel}}, {{7840, 7841, kSentinel}}, {{7842, 7843, kSentinel}}, {{7844, 7845, kSentinel}},  // NOLINT
-  {{7846, 7847, kSentinel}}, {{7848, 7849, kSentinel}}, {{7850, 7851, kSentinel}}, {{7852, 7853, kSentinel}},  // NOLINT
-  {{7854, 7855, kSentinel}}, {{7856, 7857, kSentinel}}, {{7858, 7859, kSentinel}}, {{7860, 7861, kSentinel}},  // NOLINT
-  {{7862, 7863, kSentinel}}, {{7864, 7865, kSentinel}}, {{7866, 7867, kSentinel}}, {{7868, 7869, kSentinel}},  // NOLINT
-  {{7870, 7871, kSentinel}}, {{7872, 7873, kSentinel}}, {{7874, 7875, kSentinel}}, {{7876, 7877, kSentinel}},  // NOLINT
-  {{7878, 7879, kSentinel}}, {{7880, 7881, kSentinel}}, {{7882, 7883, kSentinel}}, {{7884, 7885, kSentinel}},  // NOLINT
-  {{7886, 7887, kSentinel}}, {{7888, 7889, kSentinel}}, {{7890, 7891, kSentinel}}, {{7892, 7893, kSentinel}},  // NOLINT
-  {{7894, 7895, kSentinel}}, {{7896, 7897, kSentinel}}, {{7898, 7899, kSentinel}}, {{7900, 7901, kSentinel}},  // NOLINT
-  {{7902, 7903, kSentinel}}, {{7904, 7905, kSentinel}}, {{7906, 7907, kSentinel}}, {{7908, 7909, kSentinel}},  // NOLINT
-  {{7910, 7911, kSentinel}}, {{7912, 7913, kSentinel}}, {{7914, 7915, kSentinel}}, {{7916, 7917, kSentinel}},  // NOLINT
-  {{7918, 7919, kSentinel}}, {{7920, 7921, kSentinel}}, {{7922, 7923, kSentinel}}, {{7924, 7925, kSentinel}},  // NOLINT
-  {{7926, 7927, kSentinel}}, {{7928, 7929, kSentinel}}, {{7930, 7931, kSentinel}}, {{7932, 7933, kSentinel}},  // NOLINT
-  {{7934, 7935, kSentinel}}, {{7936, 7944, kSentinel}}, {{7943, 7951, kSentinel}}, {{7952, 7960, kSentinel}},  // NOLINT
-  {{7957, 7965, kSentinel}}, {{7968, 7976, kSentinel}}, {{7975, 7983, kSentinel}}, {{7984, 7992, kSentinel}},  // NOLINT
-  {{7991, 7999, kSentinel}}, {{8000, 8008, kSentinel}}, {{8005, 8013, kSentinel}}, {{8017, 8025, kSentinel}},  // NOLINT
-  {{8019, 8027, kSentinel}}, {{8021, 8029, kSentinel}}, {{8023, 8031, kSentinel}}, {{8032, 8040, kSentinel}},  // NOLINT
-  {{8039, 8047, kSentinel}}, {{8048, 8122, kSentinel}}, {{8049, 8123, kSentinel}}, {{8050, 8136, kSentinel}},  // NOLINT
-  {{8053, 8139, kSentinel}}, {{8054, 8154, kSentinel}}, {{8055, 8155, kSentinel}}, {{8056, 8184, kSentinel}},  // NOLINT
-  {{8057, 8185, kSentinel}}, {{8058, 8170, kSentinel}}, {{8059, 8171, kSentinel}}, {{8060, 8186, kSentinel}},  // NOLINT
-  {{8061, 8187, kSentinel}}, {{8112, 8120, kSentinel}}, {{8113, 8121, kSentinel}}, {{8144, 8152, kSentinel}},  // NOLINT
-  {{8145, 8153, kSentinel}}, {{8160, 8168, kSentinel}}, {{8161, 8169, kSentinel}}, {{8165, 8172, kSentinel}},  // NOLINT
-  {{kSentinel}} }; // NOLINT
-static const uint16_t kEcma262UnCanonicalizeTable0Size = 990;  // NOLINT
-static const int32_t kEcma262UnCanonicalizeTable0[1980] = {
-  1073741889, 1, 90, 5, 1073741921, 1, 122, 5, 181, 9, 1073742016, 13, 214, 17, 1073742040, 21,  // NOLINT
-  222, 25, 1073742048, 13, 246, 17, 1073742072, 21, 254, 25, 255, 29, 256, 33, 257, 33,  // NOLINT
-  258, 37, 259, 37, 260, 41, 261, 41, 262, 45, 263, 45, 264, 49, 265, 49,  // NOLINT
-  266, 53, 267, 53, 268, 57, 269, 57, 270, 61, 271, 61, 272, 65, 273, 65,  // NOLINT
-  274, 69, 275, 69, 276, 73, 277, 73, 278, 77, 279, 77, 280, 81, 281, 81,  // NOLINT
-  282, 85, 283, 85, 284, 89, 285, 89, 286, 93, 287, 93, 288, 97, 289, 97,  // NOLINT
-  290, 101, 291, 101, 292, 105, 293, 105, 294, 109, 295, 109, 296, 113, 297, 113,  // NOLINT
-  298, 117, 299, 117, 300, 121, 301, 121, 302, 125, 303, 125, 306, 129, 307, 129,  // NOLINT
-  308, 133, 309, 133, 310, 137, 311, 137, 313, 141, 314, 141, 315, 145, 316, 145,  // NOLINT
-  317, 149, 318, 149, 319, 153, 320, 153, 321, 157, 322, 157, 323, 161, 324, 161,  // NOLINT
-  325, 165, 326, 165, 327, 169, 328, 169, 330, 173, 331, 173, 332, 177, 333, 177,  // NOLINT
-  334, 181, 335, 181, 336, 185, 337, 185, 338, 189, 339, 189, 340, 193, 341, 193,  // NOLINT
-  342, 197, 343, 197, 344, 201, 345, 201, 346, 205, 347, 205, 348, 209, 349, 209,  // NOLINT
-  350, 213, 351, 213, 352, 217, 353, 217, 354, 221, 355, 221, 356, 225, 357, 225,  // NOLINT
-  358, 229, 359, 229, 360, 233, 361, 233, 362, 237, 363, 237, 364, 241, 365, 241,  // NOLINT
-  366, 245, 367, 245, 368, 249, 369, 249, 370, 253, 371, 253, 372, 257, 373, 257,  // NOLINT
-  374, 261, 375, 261, 376, 29, 377, 265, 378, 265, 379, 269, 380, 269, 381, 273,  // NOLINT
-  382, 273, 384, 277, 385, 281, 386, 285, 387, 285, 388, 289, 389, 289, 390, 293,  // NOLINT
-  391, 297, 392, 297, 1073742217, 301, 394, 305, 395, 309, 396, 309, 398, 313, 399, 317,  // NOLINT
-  400, 321, 401, 325, 402, 325, 403, 329, 404, 333, 405, 337, 406, 341, 407, 345,  // NOLINT
-  408, 349, 409, 349, 410, 353, 412, 357, 413, 361, 414, 365, 415, 369, 416, 373,  // NOLINT
-  417, 373, 418, 377, 419, 377, 420, 381, 421, 381, 422, 385, 423, 389, 424, 389,  // NOLINT
-  425, 393, 428, 397, 429, 397, 430, 401, 431, 405, 432, 405, 1073742257, 409, 434, 413,  // NOLINT
-  435, 417, 436, 417, 437, 421, 438, 421, 439, 425, 440, 429, 441, 429, 444, 433,  // NOLINT
-  445, 433, 447, 437, 452, 441, 453, 441, 454, 441, 455, 445, 456, 445, 457, 445,  // NOLINT
-  458, 449, 459, 449, 460, 449, 461, 453, 462, 453, 463, 457, 464, 457, 465, 461,  // NOLINT
-  466, 461, 467, 465, 468, 465, 469, 469, 470, 469, 471, 473, 472, 473, 473, 477,  // NOLINT
-  474, 477, 475, 481, 476, 481, 477, 313, 478, 485, 479, 485, 480, 489, 481, 489,  // NOLINT
-  482, 493, 483, 493, 484, 497, 485, 497, 486, 501, 487, 501, 488, 505, 489, 505,  // NOLINT
-  490, 509, 491, 509, 492, 513, 493, 513, 494, 517, 495, 517, 497, 521, 498, 521,  // NOLINT
-  499, 521, 500, 525, 501, 525, 502, 337, 503, 437, 504, 529, 505, 529, 506, 533,  // NOLINT
-  507, 533, 508, 537, 509, 537, 510, 541, 511, 541, 512, 545, 513, 545, 514, 549,  // NOLINT
-  515, 549, 516, 553, 517, 553, 518, 557, 519, 557, 520, 561, 521, 561, 522, 565,  // NOLINT
-  523, 565, 524, 569, 525, 569, 526, 573, 527, 573, 528, 577, 529, 577, 530, 581,  // NOLINT
-  531, 581, 532, 585, 533, 585, 534, 589, 535, 589, 536, 593, 537, 593, 538, 597,  // NOLINT
-  539, 597, 540, 601, 541, 601, 542, 605, 543, 605, 544, 365, 546, 609, 547, 609,  // NOLINT
-  548, 613, 549, 613, 550, 617, 551, 617, 552, 621, 553, 621, 554, 625, 555, 625,  // NOLINT
-  556, 629, 557, 629, 558, 633, 559, 633, 560, 637, 561, 637, 562, 641, 563, 641,  // NOLINT
-  570, 645, 571, 649, 572, 649, 573, 353, 574, 653, 1073742399, 657, 576, 661, 577, 665,  // NOLINT
-  578, 665, 579, 277, 580, 669, 581, 673, 582, 677, 583, 677, 584, 681, 585, 681,  // NOLINT
-  586, 685, 587, 685, 588, 689, 589, 689, 590, 693, 591, 693, 592, 697, 593, 701,  // NOLINT
-  594, 705, 595, 281, 596, 293, 1073742422, 301, 599, 305, 601, 317, 603, 321, 608, 329,  // NOLINT
-  611, 333, 613, 709, 614, 713, 616, 345, 617, 341, 619, 717, 623, 357, 625, 721,  // NOLINT
-  626, 361, 629, 369, 637, 725, 640, 385, 643, 393, 648, 401, 649, 669, 1073742474, 409,  // NOLINT
-  651, 413, 652, 673, 658, 425, 837, 729, 880, 733, 881, 733, 882, 737, 883, 737,  // NOLINT
-  886, 741, 887, 741, 1073742715, 745, 893, 749, 902, 753, 1073742728, 757, 906, 761, 908, 765,  // NOLINT
-  1073742734, 769, 911, 773, 913, 777, 914, 781, 1073742739, 785, 916, 789, 917, 793, 1073742742, 797,  // NOLINT
-  919, 801, 920, 805, 921, 729, 922, 809, 923, 813, 924, 9, 1073742749, 817, 927, 821,  // NOLINT
-  928, 825, 929, 829, 931, 833, 1073742756, 837, 933, 841, 934, 845, 1073742759, 849, 939, 853,  // NOLINT
-  940, 753, 1073742765, 757, 943, 761, 945, 777, 946, 781, 1073742771, 785, 948, 789, 949, 793,  // NOLINT
-  1073742774, 797, 951, 801, 952, 805, 953, 729, 954, 809, 955, 813, 956, 9, 1073742781, 817,  // NOLINT
-  959, 821, 960, 825, 961, 829, 962, 833, 963, 833, 1073742788, 837, 965, 841, 966, 845,  // NOLINT
-  1073742791, 849, 971, 853, 972, 765, 1073742797, 769, 974, 773, 975, 857, 976, 781, 977, 805,  // NOLINT
-  981, 845, 982, 825, 983, 857, 984, 861, 985, 861, 986, 865, 987, 865, 988, 869,  // NOLINT
-  989, 869, 990, 873, 991, 873, 992, 877, 993, 877, 994, 881, 995, 881, 996, 885,  // NOLINT
-  997, 885, 998, 889, 999, 889, 1000, 893, 1001, 893, 1002, 897, 1003, 897, 1004, 901,  // NOLINT
-  1005, 901, 1006, 905, 1007, 905, 1008, 809, 1009, 829, 1010, 909, 1013, 793, 1015, 913,  // NOLINT
-  1016, 913, 1017, 909, 1018, 917, 1019, 917, 1073742845, 745, 1023, 749, 1073742848, 921, 1039, 925,  // NOLINT
-  1073742864, 929, 1071, 933, 1073742896, 929, 1103, 933, 1073742928, 921, 1119, 925, 1120, 937, 1121, 937,  // NOLINT
-  1122, 941, 1123, 941, 1124, 945, 1125, 945, 1126, 949, 1127, 949, 1128, 953, 1129, 953,  // NOLINT
-  1130, 957, 1131, 957, 1132, 961, 1133, 961, 1134, 965, 1135, 965, 1136, 969, 1137, 969,  // NOLINT
-  1138, 973, 1139, 973, 1140, 977, 1141, 977, 1142, 981, 1143, 981, 1144, 985, 1145, 985,  // NOLINT
-  1146, 989, 1147, 989, 1148, 993, 1149, 993, 1150, 997, 1151, 997, 1152, 1001, 1153, 1001,  // NOLINT
-  1162, 1005, 1163, 1005, 1164, 1009, 1165, 1009, 1166, 1013, 1167, 1013, 1168, 1017, 1169, 1017,  // NOLINT
-  1170, 1021, 1171, 1021, 1172, 1025, 1173, 1025, 1174, 1029, 1175, 1029, 1176, 1033, 1177, 1033,  // NOLINT
-  1178, 1037, 1179, 1037, 1180, 1041, 1181, 1041, 1182, 1045, 1183, 1045, 1184, 1049, 1185, 1049,  // NOLINT
-  1186, 1053, 1187, 1053, 1188, 1057, 1189, 1057, 1190, 1061, 1191, 1061, 1192, 1065, 1193, 1065,  // NOLINT
-  1194, 1069, 1195, 1069, 1196, 1073, 1197, 1073, 1198, 1077, 1199, 1077, 1200, 1081, 1201, 1081,  // NOLINT
-  1202, 1085, 1203, 1085, 1204, 1089, 1205, 1089, 1206, 1093, 1207, 1093, 1208, 1097, 1209, 1097,  // NOLINT
-  1210, 1101, 1211, 1101, 1212, 1105, 1213, 1105, 1214, 1109, 1215, 1109, 1216, 1113, 1217, 1117,  // NOLINT
-  1218, 1117, 1219, 1121, 1220, 1121, 1221, 1125, 1222, 1125, 1223, 1129, 1224, 1129, 1225, 1133,  // NOLINT
-  1226, 1133, 1227, 1137, 1228, 1137, 1229, 1141, 1230, 1141, 1231, 1113, 1232, 1145, 1233, 1145,  // NOLINT
-  1234, 1149, 1235, 1149, 1236, 1153, 1237, 1153, 1238, 1157, 1239, 1157, 1240, 1161, 1241, 1161,  // NOLINT
-  1242, 1165, 1243, 1165, 1244, 1169, 1245, 1169, 1246, 1173, 1247, 1173, 1248, 1177, 1249, 1177,  // NOLINT
-  1250, 1181, 1251, 1181, 1252, 1185, 1253, 1185, 1254, 1189, 1255, 1189, 1256, 1193, 1257, 1193,  // NOLINT
-  1258, 1197, 1259, 1197, 1260, 1201, 1261, 1201, 1262, 1205, 1263, 1205, 1264, 1209, 1265, 1209,  // NOLINT
-  1266, 1213, 1267, 1213, 1268, 1217, 1269, 1217, 1270, 1221, 1271, 1221, 1272, 1225, 1273, 1225,  // NOLINT
-  1274, 1229, 1275, 1229, 1276, 1233, 1277, 1233, 1278, 1237, 1279, 1237, 1280, 1241, 1281, 1241,  // NOLINT
-  1282, 1245, 1283, 1245, 1284, 1249, 1285, 1249, 1286, 1253, 1287, 1253, 1288, 1257, 1289, 1257,  // NOLINT
-  1290, 1261, 1291, 1261, 1292, 1265, 1293, 1265, 1294, 1269, 1295, 1269, 1296, 1273, 1297, 1273,  // NOLINT
-  1298, 1277, 1299, 1277, 1300, 1281, 1301, 1281, 1302, 1285, 1303, 1285, 1304, 1289, 1305, 1289,  // NOLINT
-  1306, 1293, 1307, 1293, 1308, 1297, 1309, 1297, 1310, 1301, 1311, 1301, 1312, 1305, 1313, 1305,  // NOLINT
-  1314, 1309, 1315, 1309, 1316, 1313, 1317, 1313, 1318, 1317, 1319, 1317, 1073743153, 1321, 1366, 1325,  // NOLINT
-  1073743201, 1321, 1414, 1325, 1073746080, 1329, 4293, 1333, 4295, 1337, 4301, 1341, 7545, 1345, 7549, 1349,  // NOLINT
-  7680, 1353, 7681, 1353, 7682, 1357, 7683, 1357, 7684, 1361, 7685, 1361, 7686, 1365, 7687, 1365,  // NOLINT
-  7688, 1369, 7689, 1369, 7690, 1373, 7691, 1373, 7692, 1377, 7693, 1377, 7694, 1381, 7695, 1381,  // NOLINT
-  7696, 1385, 7697, 1385, 7698, 1389, 7699, 1389, 7700, 1393, 7701, 1393, 7702, 1397, 7703, 1397,  // NOLINT
-  7704, 1401, 7705, 1401, 7706, 1405, 7707, 1405, 7708, 1409, 7709, 1409, 7710, 1413, 7711, 1413,  // NOLINT
-  7712, 1417, 7713, 1417, 7714, 1421, 7715, 1421, 7716, 1425, 7717, 1425, 7718, 1429, 7719, 1429,  // NOLINT
-  7720, 1433, 7721, 1433, 7722, 1437, 7723, 1437, 7724, 1441, 7725, 1441, 7726, 1445, 7727, 1445,  // NOLINT
-  7728, 1449, 7729, 1449, 7730, 1453, 7731, 1453, 7732, 1457, 7733, 1457, 7734, 1461, 7735, 1461,  // NOLINT
-  7736, 1465, 7737, 1465, 7738, 1469, 7739, 1469, 7740, 1473, 7741, 1473, 7742, 1477, 7743, 1477,  // NOLINT
-  7744, 1481, 7745, 1481, 7746, 1485, 7747, 1485, 7748, 1489, 7749, 1489, 7750, 1493, 7751, 1493,  // NOLINT
-  7752, 1497, 7753, 1497, 7754, 1501, 7755, 1501, 7756, 1505, 7757, 1505, 7758, 1509, 7759, 1509,  // NOLINT
-  7760, 1513, 7761, 1513, 7762, 1517, 7763, 1517, 7764, 1521, 7765, 1521, 7766, 1525, 7767, 1525,  // NOLINT
-  7768, 1529, 7769, 1529, 7770, 1533, 7771, 1533, 7772, 1537, 7773, 1537, 7774, 1541, 7775, 1541,  // NOLINT
-  7776, 1545, 7777, 1545, 7778, 1549, 7779, 1549, 7780, 1553, 7781, 1553, 7782, 1557, 7783, 1557,  // NOLINT
-  7784, 1561, 7785, 1561, 7786, 1565, 7787, 1565, 7788, 1569, 7789, 1569, 7790, 1573, 7791, 1573,  // NOLINT
-  7792, 1577, 7793, 1577, 7794, 1581, 7795, 1581, 7796, 1585, 7797, 1585, 7798, 1589, 7799, 1589,  // NOLINT
-  7800, 1593, 7801, 1593, 7802, 1597, 7803, 1597, 7804, 1601, 7805, 1601, 7806, 1605, 7807, 1605,  // NOLINT
-  7808, 1609, 7809, 1609, 7810, 1613, 7811, 1613, 7812, 1617, 7813, 1617, 7814, 1621, 7815, 1621,  // NOLINT
-  7816, 1625, 7817, 1625, 7818, 1629, 7819, 1629, 7820, 1633, 7821, 1633, 7822, 1637, 7823, 1637,  // NOLINT
-  7824, 1641, 7825, 1641, 7826, 1645, 7827, 1645, 7828, 1649, 7829, 1649, 7835, 1545, 7840, 1653,  // NOLINT
-  7841, 1653, 7842, 1657, 7843, 1657, 7844, 1661, 7845, 1661, 7846, 1665, 7847, 1665, 7848, 1669,  // NOLINT
-  7849, 1669, 7850, 1673, 7851, 1673, 7852, 1677, 7853, 1677, 7854, 1681, 7855, 1681, 7856, 1685,  // NOLINT
-  7857, 1685, 7858, 1689, 7859, 1689, 7860, 1693, 7861, 1693, 7862, 1697, 7863, 1697, 7864, 1701,  // NOLINT
-  7865, 1701, 7866, 1705, 7867, 1705, 7868, 1709, 7869, 1709, 7870, 1713, 7871, 1713, 7872, 1717,  // NOLINT
-  7873, 1717, 7874, 1721, 7875, 1721, 7876, 1725, 7877, 1725, 7878, 1729, 7879, 1729, 7880, 1733,  // NOLINT
-  7881, 1733, 7882, 1737, 7883, 1737, 7884, 1741, 7885, 1741, 7886, 1745, 7887, 1745, 7888, 1749,  // NOLINT
-  7889, 1749, 7890, 1753, 7891, 1753, 7892, 1757, 7893, 1757, 7894, 1761, 7895, 1761, 7896, 1765,  // NOLINT
-  7897, 1765, 7898, 1769, 7899, 1769, 7900, 1773, 7901, 1773, 7902, 1777, 7903, 1777, 7904, 1781,  // NOLINT
-  7905, 1781, 7906, 1785, 7907, 1785, 7908, 1789, 7909, 1789, 7910, 1793, 7911, 1793, 7912, 1797,  // NOLINT
-  7913, 1797, 7914, 1801, 7915, 1801, 7916, 1805, 7917, 1805, 7918, 1809, 7919, 1809, 7920, 1813,  // NOLINT
-  7921, 1813, 7922, 1817, 7923, 1817, 7924, 1821, 7925, 1821, 7926, 1825, 7927, 1825, 7928, 1829,  // NOLINT
-  7929, 1829, 7930, 1833, 7931, 1833, 7932, 1837, 7933, 1837, 7934, 1841, 7935, 1841, 1073749760, 1845,  // NOLINT
-  7943, 1849, 1073749768, 1845, 7951, 1849, 1073749776, 1853, 7957, 1857, 1073749784, 1853, 7965, 1857, 1073749792, 1861,  // NOLINT
-  7975, 1865, 1073749800, 1861, 7983, 1865, 1073749808, 1869, 7991, 1873, 1073749816, 1869, 7999, 1873, 1073749824, 1877,  // NOLINT
-  8005, 1881, 1073749832, 1877, 8013, 1881, 8017, 1885, 8019, 1889, 8021, 1893, 8023, 1897, 8025, 1885,  // NOLINT
-  8027, 1889, 8029, 1893, 8031, 1897, 1073749856, 1901, 8039, 1905, 1073749864, 1901, 8047, 1905, 1073749872, 1909,  // NOLINT
-  8049, 1913, 1073749874, 1917, 8053, 1921, 1073749878, 1925, 8055, 1929, 1073749880, 1933, 8057, 1937, 1073749882, 1941,  // NOLINT
-  8059, 1945, 1073749884, 1949, 8061, 1953, 1073749936, 1957, 8113, 1961, 1073749944, 1957, 8121, 1961, 1073749946, 1909,  // NOLINT
-  8123, 1913, 8126, 729, 1073749960, 1917, 8139, 1921, 1073749968, 1965, 8145, 1969, 1073749976, 1965, 8153, 1969,  // NOLINT
-  1073749978, 1925, 8155, 1929, 1073749984, 1973, 8161, 1977, 8165, 1981, 1073749992, 1973, 8169, 1977, 1073749994, 1941,  // NOLINT
-  8171, 1945, 8172, 1981, 1073750008, 1933, 8185, 1937, 1073750010, 1949, 8187, 1953 };  // NOLINT
-static const uint16_t kEcma262UnCanonicalizeMultiStrings0Size = 497;  // NOLINT
+static const MultiCharacterSpecialCase<4>
+    kEcma262UnCanonicalizeMultiStrings0[507] = {  // NOLINT
+        {{65, 97, kSentinel}},
+        {{90, 122, kSentinel}},
+        {{181, 924, 956, kSentinel}},
+        {{192, 224, kSentinel}},  // NOLINT
+        {{214, 246, kSentinel}},
+        {{216, 248, kSentinel}},
+        {{222, 254, kSentinel}},
+        {{255, 376, kSentinel}},  // NOLINT
+        {{256, 257, kSentinel}},
+        {{258, 259, kSentinel}},
+        {{260, 261, kSentinel}},
+        {{262, 263, kSentinel}},  // NOLINT
+        {{264, 265, kSentinel}},
+        {{266, 267, kSentinel}},
+        {{268, 269, kSentinel}},
+        {{270, 271, kSentinel}},  // NOLINT
+        {{272, 273, kSentinel}},
+        {{274, 275, kSentinel}},
+        {{276, 277, kSentinel}},
+        {{278, 279, kSentinel}},  // NOLINT
+        {{280, 281, kSentinel}},
+        {{282, 283, kSentinel}},
+        {{284, 285, kSentinel}},
+        {{286, 287, kSentinel}},  // NOLINT
+        {{288, 289, kSentinel}},
+        {{290, 291, kSentinel}},
+        {{292, 293, kSentinel}},
+        {{294, 295, kSentinel}},  // NOLINT
+        {{296, 297, kSentinel}},
+        {{298, 299, kSentinel}},
+        {{300, 301, kSentinel}},
+        {{302, 303, kSentinel}},  // NOLINT
+        {{306, 307, kSentinel}},
+        {{308, 309, kSentinel}},
+        {{310, 311, kSentinel}},
+        {{313, 314, kSentinel}},  // NOLINT
+        {{315, 316, kSentinel}},
+        {{317, 318, kSentinel}},
+        {{319, 320, kSentinel}},
+        {{321, 322, kSentinel}},  // NOLINT
+        {{323, 324, kSentinel}},
+        {{325, 326, kSentinel}},
+        {{327, 328, kSentinel}},
+        {{330, 331, kSentinel}},  // NOLINT
+        {{332, 333, kSentinel}},
+        {{334, 335, kSentinel}},
+        {{336, 337, kSentinel}},
+        {{338, 339, kSentinel}},  // NOLINT
+        {{340, 341, kSentinel}},
+        {{342, 343, kSentinel}},
+        {{344, 345, kSentinel}},
+        {{346, 347, kSentinel}},  // NOLINT
+        {{348, 349, kSentinel}},
+        {{350, 351, kSentinel}},
+        {{352, 353, kSentinel}},
+        {{354, 355, kSentinel}},  // NOLINT
+        {{356, 357, kSentinel}},
+        {{358, 359, kSentinel}},
+        {{360, 361, kSentinel}},
+        {{362, 363, kSentinel}},  // NOLINT
+        {{364, 365, kSentinel}},
+        {{366, 367, kSentinel}},
+        {{368, 369, kSentinel}},
+        {{370, 371, kSentinel}},  // NOLINT
+        {{372, 373, kSentinel}},
+        {{374, 375, kSentinel}},
+        {{377, 378, kSentinel}},
+        {{379, 380, kSentinel}},  // NOLINT
+        {{381, 382, kSentinel}},
+        {{384, 579, kSentinel}},
+        {{385, 595, kSentinel}},
+        {{386, 387, kSentinel}},  // NOLINT
+        {{388, 389, kSentinel}},
+        {{390, 596, kSentinel}},
+        {{391, 392, kSentinel}},
+        {{393, 598, kSentinel}},  // NOLINT
+        {{394, 599, kSentinel}},
+        {{395, 396, kSentinel}},
+        {{398, 477, kSentinel}},
+        {{399, 601, kSentinel}},  // NOLINT
+        {{400, 603, kSentinel}},
+        {{401, 402, kSentinel}},
+        {{403, 608, kSentinel}},
+        {{404, 611, kSentinel}},  // NOLINT
+        {{405, 502, kSentinel}},
+        {{406, 617, kSentinel}},
+        {{407, 616, kSentinel}},
+        {{408, 409, kSentinel}},  // NOLINT
+        {{410, 573, kSentinel}},
+        {{412, 623, kSentinel}},
+        {{413, 626, kSentinel}},
+        {{414, 544, kSentinel}},  // NOLINT
+        {{415, 629, kSentinel}},
+        {{416, 417, kSentinel}},
+        {{418, 419, kSentinel}},
+        {{420, 421, kSentinel}},  // NOLINT
+        {{422, 640, kSentinel}},
+        {{423, 424, kSentinel}},
+        {{425, 643, kSentinel}},
+        {{428, 429, kSentinel}},  // NOLINT
+        {{430, 648, kSentinel}},
+        {{431, 432, kSentinel}},
+        {{433, 650, kSentinel}},
+        {{434, 651, kSentinel}},  // NOLINT
+        {{435, 436, kSentinel}},
+        {{437, 438, kSentinel}},
+        {{439, 658, kSentinel}},
+        {{440, 441, kSentinel}},  // NOLINT
+        {{444, 445, kSentinel}},
+        {{447, 503, kSentinel}},
+        {{452, 453, 454, kSentinel}},
+        {{455, 456, 457, kSentinel}},  // NOLINT
+        {{458, 459, 460, kSentinel}},
+        {{461, 462, kSentinel}},
+        {{463, 464, kSentinel}},
+        {{465, 466, kSentinel}},  // NOLINT
+        {{467, 468, kSentinel}},
+        {{469, 470, kSentinel}},
+        {{471, 472, kSentinel}},
+        {{473, 474, kSentinel}},  // NOLINT
+        {{475, 476, kSentinel}},
+        {{478, 479, kSentinel}},
+        {{480, 481, kSentinel}},
+        {{482, 483, kSentinel}},  // NOLINT
+        {{484, 485, kSentinel}},
+        {{486, 487, kSentinel}},
+        {{488, 489, kSentinel}},
+        {{490, 491, kSentinel}},  // NOLINT
+        {{492, 493, kSentinel}},
+        {{494, 495, kSentinel}},
+        {{497, 498, 499, kSentinel}},
+        {{500, 501, kSentinel}},  // NOLINT
+        {{504, 505, kSentinel}},
+        {{506, 507, kSentinel}},
+        {{508, 509, kSentinel}},
+        {{510, 511, kSentinel}},  // NOLINT
+        {{512, 513, kSentinel}},
+        {{514, 515, kSentinel}},
+        {{516, 517, kSentinel}},
+        {{518, 519, kSentinel}},  // NOLINT
+        {{520, 521, kSentinel}},
+        {{522, 523, kSentinel}},
+        {{524, 525, kSentinel}},
+        {{526, 527, kSentinel}},  // NOLINT
+        {{528, 529, kSentinel}},
+        {{530, 531, kSentinel}},
+        {{532, 533, kSentinel}},
+        {{534, 535, kSentinel}},  // NOLINT
+        {{536, 537, kSentinel}},
+        {{538, 539, kSentinel}},
+        {{540, 541, kSentinel}},
+        {{542, 543, kSentinel}},  // NOLINT
+        {{546, 547, kSentinel}},
+        {{548, 549, kSentinel}},
+        {{550, 551, kSentinel}},
+        {{552, 553, kSentinel}},  // NOLINT
+        {{554, 555, kSentinel}},
+        {{556, 557, kSentinel}},
+        {{558, 559, kSentinel}},
+        {{560, 561, kSentinel}},  // NOLINT
+        {{562, 563, kSentinel}},
+        {{570, 11365, kSentinel}},
+        {{571, 572, kSentinel}},
+        {{574, 11366, kSentinel}},  // NOLINT
+        {{575, 11390, kSentinel}},
+        {{576, 11391, kSentinel}},
+        {{577, 578, kSentinel}},
+        {{580, 649, kSentinel}},  // NOLINT
+        {{581, 652, kSentinel}},
+        {{582, 583, kSentinel}},
+        {{584, 585, kSentinel}},
+        {{586, 587, kSentinel}},  // NOLINT
+        {{588, 589, kSentinel}},
+        {{590, 591, kSentinel}},
+        {{592, 11375, kSentinel}},
+        {{593, 11373, kSentinel}},  // NOLINT
+        {{594, 11376, kSentinel}},
+        {{604, 42923, kSentinel}},
+        {{609, 42924, kSentinel}},
+        {{613, 42893, kSentinel}},  // NOLINT
+        {{614, 42922, kSentinel}},
+        {{619, 11362, kSentinel}},
+        {{620, 42925, kSentinel}},
+        {{625, 11374, kSentinel}},  // NOLINT
+        {{637, 11364, kSentinel}},
+        {{647, 42929, kSentinel}},
+        {{670, 42928, kSentinel}},
+        {{837, 921, 953, 8126}},  // NOLINT
+        {{880, 881, kSentinel}},
+        {{882, 883, kSentinel}},
+        {{886, 887, kSentinel}},
+        {{891, 1021, kSentinel}},  // NOLINT
+        {{893, 1023, kSentinel}},
+        {{895, 1011, kSentinel}},
+        {{902, 940, kSentinel}},
+        {{904, 941, kSentinel}},  // NOLINT
+        {{906, 943, kSentinel}},
+        {{908, 972, kSentinel}},
+        {{910, 973, kSentinel}},
+        {{911, 974, kSentinel}},  // NOLINT
+        {{913, 945, kSentinel}},
+        {{914, 946, 976, kSentinel}},
+        {{915, 947, kSentinel}},
+        {{916, 948, kSentinel}},  // NOLINT
+        {{917, 949, 1013, kSentinel}},
+        {{918, 950, kSentinel}},
+        {{919, 951, kSentinel}},
+        {{920, 952, 977, kSentinel}},  // NOLINT
+        {{922, 954, 1008, kSentinel}},
+        {{923, 955, kSentinel}},
+        {{925, 957, kSentinel}},
+        {{927, 959, kSentinel}},  // NOLINT
+        {{928, 960, 982, kSentinel}},
+        {{929, 961, 1009, kSentinel}},
+        {{931, 962, 963, kSentinel}},
+        {{932, 964, kSentinel}},  // NOLINT
+        {{933, 965, kSentinel}},
+        {{934, 966, 981, kSentinel}},
+        {{935, 967, kSentinel}},
+        {{939, 971, kSentinel}},  // NOLINT
+        {{975, 983, kSentinel}},
+        {{984, 985, kSentinel}},
+        {{986, 987, kSentinel}},
+        {{988, 989, kSentinel}},  // NOLINT
+        {{990, 991, kSentinel}},
+        {{992, 993, kSentinel}},
+        {{994, 995, kSentinel}},
+        {{996, 997, kSentinel}},  // NOLINT
+        {{998, 999, kSentinel}},
+        {{1000, 1001, kSentinel}},
+        {{1002, 1003, kSentinel}},
+        {{1004, 1005, kSentinel}},  // NOLINT
+        {{1006, 1007, kSentinel}},
+        {{1010, 1017, kSentinel}},
+        {{1015, 1016, kSentinel}},
+        {{1018, 1019, kSentinel}},  // NOLINT
+        {{1024, 1104, kSentinel}},
+        {{1039, 1119, kSentinel}},
+        {{1040, 1072, kSentinel}},
+        {{1071, 1103, kSentinel}},  // NOLINT
+        {{1120, 1121, kSentinel}},
+        {{1122, 1123, kSentinel}},
+        {{1124, 1125, kSentinel}},
+        {{1126, 1127, kSentinel}},  // NOLINT
+        {{1128, 1129, kSentinel}},
+        {{1130, 1131, kSentinel}},
+        {{1132, 1133, kSentinel}},
+        {{1134, 1135, kSentinel}},  // NOLINT
+        {{1136, 1137, kSentinel}},
+        {{1138, 1139, kSentinel}},
+        {{1140, 1141, kSentinel}},
+        {{1142, 1143, kSentinel}},  // NOLINT
+        {{1144, 1145, kSentinel}},
+        {{1146, 1147, kSentinel}},
+        {{1148, 1149, kSentinel}},
+        {{1150, 1151, kSentinel}},  // NOLINT
+        {{1152, 1153, kSentinel}},
+        {{1162, 1163, kSentinel}},
+        {{1164, 1165, kSentinel}},
+        {{1166, 1167, kSentinel}},  // NOLINT
+        {{1168, 1169, kSentinel}},
+        {{1170, 1171, kSentinel}},
+        {{1172, 1173, kSentinel}},
+        {{1174, 1175, kSentinel}},  // NOLINT
+        {{1176, 1177, kSentinel}},
+        {{1178, 1179, kSentinel}},
+        {{1180, 1181, kSentinel}},
+        {{1182, 1183, kSentinel}},  // NOLINT
+        {{1184, 1185, kSentinel}},
+        {{1186, 1187, kSentinel}},
+        {{1188, 1189, kSentinel}},
+        {{1190, 1191, kSentinel}},  // NOLINT
+        {{1192, 1193, kSentinel}},
+        {{1194, 1195, kSentinel}},
+        {{1196, 1197, kSentinel}},
+        {{1198, 1199, kSentinel}},  // NOLINT
+        {{1200, 1201, kSentinel}},
+        {{1202, 1203, kSentinel}},
+        {{1204, 1205, kSentinel}},
+        {{1206, 1207, kSentinel}},  // NOLINT
+        {{1208, 1209, kSentinel}},
+        {{1210, 1211, kSentinel}},
+        {{1212, 1213, kSentinel}},
+        {{1214, 1215, kSentinel}},  // NOLINT
+        {{1216, 1231, kSentinel}},
+        {{1217, 1218, kSentinel}},
+        {{1219, 1220, kSentinel}},
+        {{1221, 1222, kSentinel}},  // NOLINT
+        {{1223, 1224, kSentinel}},
+        {{1225, 1226, kSentinel}},
+        {{1227, 1228, kSentinel}},
+        {{1229, 1230, kSentinel}},  // NOLINT
+        {{1232, 1233, kSentinel}},
+        {{1234, 1235, kSentinel}},
+        {{1236, 1237, kSentinel}},
+        {{1238, 1239, kSentinel}},  // NOLINT
+        {{1240, 1241, kSentinel}},
+        {{1242, 1243, kSentinel}},
+        {{1244, 1245, kSentinel}},
+        {{1246, 1247, kSentinel}},  // NOLINT
+        {{1248, 1249, kSentinel}},
+        {{1250, 1251, kSentinel}},
+        {{1252, 1253, kSentinel}},
+        {{1254, 1255, kSentinel}},  // NOLINT
+        {{1256, 1257, kSentinel}},
+        {{1258, 1259, kSentinel}},
+        {{1260, 1261, kSentinel}},
+        {{1262, 1263, kSentinel}},  // NOLINT
+        {{1264, 1265, kSentinel}},
+        {{1266, 1267, kSentinel}},
+        {{1268, 1269, kSentinel}},
+        {{1270, 1271, kSentinel}},  // NOLINT
+        {{1272, 1273, kSentinel}},
+        {{1274, 1275, kSentinel}},
+        {{1276, 1277, kSentinel}},
+        {{1278, 1279, kSentinel}},  // NOLINT
+        {{1280, 1281, kSentinel}},
+        {{1282, 1283, kSentinel}},
+        {{1284, 1285, kSentinel}},
+        {{1286, 1287, kSentinel}},  // NOLINT
+        {{1288, 1289, kSentinel}},
+        {{1290, 1291, kSentinel}},
+        {{1292, 1293, kSentinel}},
+        {{1294, 1295, kSentinel}},  // NOLINT
+        {{1296, 1297, kSentinel}},
+        {{1298, 1299, kSentinel}},
+        {{1300, 1301, kSentinel}},
+        {{1302, 1303, kSentinel}},  // NOLINT
+        {{1304, 1305, kSentinel}},
+        {{1306, 1307, kSentinel}},
+        {{1308, 1309, kSentinel}},
+        {{1310, 1311, kSentinel}},  // NOLINT
+        {{1312, 1313, kSentinel}},
+        {{1314, 1315, kSentinel}},
+        {{1316, 1317, kSentinel}},
+        {{1318, 1319, kSentinel}},  // NOLINT
+        {{1320, 1321, kSentinel}},
+        {{1322, 1323, kSentinel}},
+        {{1324, 1325, kSentinel}},
+        {{1326, 1327, kSentinel}},  // NOLINT
+        {{1329, 1377, kSentinel}},
+        {{1366, 1414, kSentinel}},
+        {{4256, 11520, kSentinel}},
+        {{4293, 11557, kSentinel}},  // NOLINT
+        {{4295, 11559, kSentinel}},
+        {{4301, 11565, kSentinel}},
+        {{7545, 42877, kSentinel}},
+        {{7549, 11363, kSentinel}},  // NOLINT
+        {{7680, 7681, kSentinel}},
+        {{7682, 7683, kSentinel}},
+        {{7684, 7685, kSentinel}},
+        {{7686, 7687, kSentinel}},  // NOLINT
+        {{7688, 7689, kSentinel}},
+        {{7690, 7691, kSentinel}},
+        {{7692, 7693, kSentinel}},
+        {{7694, 7695, kSentinel}},  // NOLINT
+        {{7696, 7697, kSentinel}},
+        {{7698, 7699, kSentinel}},
+        {{7700, 7701, kSentinel}},
+        {{7702, 7703, kSentinel}},  // NOLINT
+        {{7704, 7705, kSentinel}},
+        {{7706, 7707, kSentinel}},
+        {{7708, 7709, kSentinel}},
+        {{7710, 7711, kSentinel}},  // NOLINT
+        {{7712, 7713, kSentinel}},
+        {{7714, 7715, kSentinel}},
+        {{7716, 7717, kSentinel}},
+        {{7718, 7719, kSentinel}},  // NOLINT
+        {{7720, 7721, kSentinel}},
+        {{7722, 7723, kSentinel}},
+        {{7724, 7725, kSentinel}},
+        {{7726, 7727, kSentinel}},  // NOLINT
+        {{7728, 7729, kSentinel}},
+        {{7730, 7731, kSentinel}},
+        {{7732, 7733, kSentinel}},
+        {{7734, 7735, kSentinel}},  // NOLINT
+        {{7736, 7737, kSentinel}},
+        {{7738, 7739, kSentinel}},
+        {{7740, 7741, kSentinel}},
+        {{7742, 7743, kSentinel}},  // NOLINT
+        {{7744, 7745, kSentinel}},
+        {{7746, 7747, kSentinel}},
+        {{7748, 7749, kSentinel}},
+        {{7750, 7751, kSentinel}},  // NOLINT
+        {{7752, 7753, kSentinel}},
+        {{7754, 7755, kSentinel}},
+        {{7756, 7757, kSentinel}},
+        {{7758, 7759, kSentinel}},  // NOLINT
+        {{7760, 7761, kSentinel}},
+        {{7762, 7763, kSentinel}},
+        {{7764, 7765, kSentinel}},
+        {{7766, 7767, kSentinel}},  // NOLINT
+        {{7768, 7769, kSentinel}},
+        {{7770, 7771, kSentinel}},
+        {{7772, 7773, kSentinel}},
+        {{7774, 7775, kSentinel}},  // NOLINT
+        {{7776, 7777, 7835, kSentinel}},
+        {{7778, 7779, kSentinel}},
+        {{7780, 7781, kSentinel}},
+        {{7782, 7783, kSentinel}},  // NOLINT
+        {{7784, 7785, kSentinel}},
+        {{7786, 7787, kSentinel}},
+        {{7788, 7789, kSentinel}},
+        {{7790, 7791, kSentinel}},  // NOLINT
+        {{7792, 7793, kSentinel}},
+        {{7794, 7795, kSentinel}},
+        {{7796, 7797, kSentinel}},
+        {{7798, 7799, kSentinel}},  // NOLINT
+        {{7800, 7801, kSentinel}},
+        {{7802, 7803, kSentinel}},
+        {{7804, 7805, kSentinel}},
+        {{7806, 7807, kSentinel}},  // NOLINT
+        {{7808, 7809, kSentinel}},
+        {{7810, 7811, kSentinel}},
+        {{7812, 7813, kSentinel}},
+        {{7814, 7815, kSentinel}},  // NOLINT
+        {{7816, 7817, kSentinel}},
+        {{7818, 7819, kSentinel}},
+        {{7820, 7821, kSentinel}},
+        {{7822, 7823, kSentinel}},  // NOLINT
+        {{7824, 7825, kSentinel}},
+        {{7826, 7827, kSentinel}},
+        {{7828, 7829, kSentinel}},
+        {{7840, 7841, kSentinel}},  // NOLINT
+        {{7842, 7843, kSentinel}},
+        {{7844, 7845, kSentinel}},
+        {{7846, 7847, kSentinel}},
+        {{7848, 7849, kSentinel}},  // NOLINT
+        {{7850, 7851, kSentinel}},
+        {{7852, 7853, kSentinel}},
+        {{7854, 7855, kSentinel}},
+        {{7856, 7857, kSentinel}},  // NOLINT
+        {{7858, 7859, kSentinel}},
+        {{7860, 7861, kSentinel}},
+        {{7862, 7863, kSentinel}},
+        {{7864, 7865, kSentinel}},  // NOLINT
+        {{7866, 7867, kSentinel}},
+        {{7868, 7869, kSentinel}},
+        {{7870, 7871, kSentinel}},
+        {{7872, 7873, kSentinel}},  // NOLINT
+        {{7874, 7875, kSentinel}},
+        {{7876, 7877, kSentinel}},
+        {{7878, 7879, kSentinel}},
+        {{7880, 7881, kSentinel}},  // NOLINT
+        {{7882, 7883, kSentinel}},
+        {{7884, 7885, kSentinel}},
+        {{7886, 7887, kSentinel}},
+        {{7888, 7889, kSentinel}},  // NOLINT
+        {{7890, 7891, kSentinel}},
+        {{7892, 7893, kSentinel}},
+        {{7894, 7895, kSentinel}},
+        {{7896, 7897, kSentinel}},  // NOLINT
+        {{7898, 7899, kSentinel}},
+        {{7900, 7901, kSentinel}},
+        {{7902, 7903, kSentinel}},
+        {{7904, 7905, kSentinel}},  // NOLINT
+        {{7906, 7907, kSentinel}},
+        {{7908, 7909, kSentinel}},
+        {{7910, 7911, kSentinel}},
+        {{7912, 7913, kSentinel}},  // NOLINT
+        {{7914, 7915, kSentinel}},
+        {{7916, 7917, kSentinel}},
+        {{7918, 7919, kSentinel}},
+        {{7920, 7921, kSentinel}},  // NOLINT
+        {{7922, 7923, kSentinel}},
+        {{7924, 7925, kSentinel}},
+        {{7926, 7927, kSentinel}},
+        {{7928, 7929, kSentinel}},  // NOLINT
+        {{7930, 7931, kSentinel}},
+        {{7932, 7933, kSentinel}},
+        {{7934, 7935, kSentinel}},
+        {{7936, 7944, kSentinel}},  // NOLINT
+        {{7943, 7951, kSentinel}},
+        {{7952, 7960, kSentinel}},
+        {{7957, 7965, kSentinel}},
+        {{7968, 7976, kSentinel}},  // NOLINT
+        {{7975, 7983, kSentinel}},
+        {{7984, 7992, kSentinel}},
+        {{7991, 7999, kSentinel}},
+        {{8000, 8008, kSentinel}},  // NOLINT
+        {{8005, 8013, kSentinel}},
+        {{8017, 8025, kSentinel}},
+        {{8019, 8027, kSentinel}},
+        {{8021, 8029, kSentinel}},  // NOLINT
+        {{8023, 8031, kSentinel}},
+        {{8032, 8040, kSentinel}},
+        {{8039, 8047, kSentinel}},
+        {{8048, 8122, kSentinel}},  // NOLINT
+        {{8049, 8123, kSentinel}},
+        {{8050, 8136, kSentinel}},
+        {{8053, 8139, kSentinel}},
+        {{8054, 8154, kSentinel}},  // NOLINT
+        {{8055, 8155, kSentinel}},
+        {{8056, 8184, kSentinel}},
+        {{8057, 8185, kSentinel}},
+        {{8058, 8170, kSentinel}},  // NOLINT
+        {{8059, 8171, kSentinel}},
+        {{8060, 8186, kSentinel}},
+        {{8061, 8187, kSentinel}},
+        {{8112, 8120, kSentinel}},  // NOLINT
+        {{8113, 8121, kSentinel}},
+        {{8144, 8152, kSentinel}},
+        {{8145, 8153, kSentinel}},
+        {{8160, 8168, kSentinel}},  // NOLINT
+        {{8161, 8169, kSentinel}},
+        {{8165, 8172, kSentinel}},
+        {{kSentinel}}};                                         // NOLINT
+static const uint16_t kEcma262UnCanonicalizeTable0Size = 1005;  // NOLINT
+static const int32_t kEcma262UnCanonicalizeTable0[2010] = {
+    1073741889, 1,    90,         5,    1073741921, 1,
+    122,        5,    181,        9,    1073742016, 13,
+    214,        17,   1073742040, 21,  // NOLINT
+    222,        25,   1073742048, 13,   246,        17,
+    1073742072, 21,   254,        25,   255,        29,
+    256,        33,   257,        33,  // NOLINT
+    258,        37,   259,        37,   260,        41,
+    261,        41,   262,        45,   263,        45,
+    264,        49,   265,        49,  // NOLINT
+    266,        53,   267,        53,   268,        57,
+    269,        57,   270,        61,   271,        61,
+    272,        65,   273,        65,  // NOLINT
+    274,        69,   275,        69,   276,        73,
+    277,        73,   278,        77,   279,        77,
+    280,        81,   281,        81,  // NOLINT
+    282,        85,   283,        85,   284,        89,
+    285,        89,   286,        93,   287,        93,
+    288,        97,   289,        97,  // NOLINT
+    290,        101,  291,        101,  292,        105,
+    293,        105,  294,        109,  295,        109,
+    296,        113,  297,        113,  // NOLINT
+    298,        117,  299,        117,  300,        121,
+    301,        121,  302,        125,  303,        125,
+    306,        129,  307,        129,  // NOLINT
+    308,        133,  309,        133,  310,        137,
+    311,        137,  313,        141,  314,        141,
+    315,        145,  316,        145,  // NOLINT
+    317,        149,  318,        149,  319,        153,
+    320,        153,  321,        157,  322,        157,
+    323,        161,  324,        161,  // NOLINT
+    325,        165,  326,        165,  327,        169,
+    328,        169,  330,        173,  331,        173,
+    332,        177,  333,        177,  // NOLINT
+    334,        181,  335,        181,  336,        185,
+    337,        185,  338,        189,  339,        189,
+    340,        193,  341,        193,  // NOLINT
+    342,        197,  343,        197,  344,        201,
+    345,        201,  346,        205,  347,        205,
+    348,        209,  349,        209,  // NOLINT
+    350,        213,  351,        213,  352,        217,
+    353,        217,  354,        221,  355,        221,
+    356,        225,  357,        225,  // NOLINT
+    358,        229,  359,        229,  360,        233,
+    361,        233,  362,        237,  363,        237,
+    364,        241,  365,        241,  // NOLINT
+    366,        245,  367,        245,  368,        249,
+    369,        249,  370,        253,  371,        253,
+    372,        257,  373,        257,  // NOLINT
+    374,        261,  375,        261,  376,        29,
+    377,        265,  378,        265,  379,        269,
+    380,        269,  381,        273,  // NOLINT
+    382,        273,  384,        277,  385,        281,
+    386,        285,  387,        285,  388,        289,
+    389,        289,  390,        293,  // NOLINT
+    391,        297,  392,        297,  1073742217, 301,
+    394,        305,  395,        309,  396,        309,
+    398,        313,  399,        317,  // NOLINT
+    400,        321,  401,        325,  402,        325,
+    403,        329,  404,        333,  405,        337,
+    406,        341,  407,        345,  // NOLINT
+    408,        349,  409,        349,  410,        353,
+    412,        357,  413,        361,  414,        365,
+    415,        369,  416,        373,  // NOLINT
+    417,        373,  418,        377,  419,        377,
+    420,        381,  421,        381,  422,        385,
+    423,        389,  424,        389,  // NOLINT
+    425,        393,  428,        397,  429,        397,
+    430,        401,  431,        405,  432,        405,
+    1073742257, 409,  434,        413,  // NOLINT
+    435,        417,  436,        417,  437,        421,
+    438,        421,  439,        425,  440,        429,
+    441,        429,  444,        433,  // NOLINT
+    445,        433,  447,        437,  452,        441,
+    453,        441,  454,        441,  455,        445,
+    456,        445,  457,        445,  // NOLINT
+    458,        449,  459,        449,  460,        449,
+    461,        453,  462,        453,  463,        457,
+    464,        457,  465,        461,  // NOLINT
+    466,        461,  467,        465,  468,        465,
+    469,        469,  470,        469,  471,        473,
+    472,        473,  473,        477,  // NOLINT
+    474,        477,  475,        481,  476,        481,
+    477,        313,  478,        485,  479,        485,
+    480,        489,  481,        489,  // NOLINT
+    482,        493,  483,        493,  484,        497,
+    485,        497,  486,        501,  487,        501,
+    488,        505,  489,        505,  // NOLINT
+    490,        509,  491,        509,  492,        513,
+    493,        513,  494,        517,  495,        517,
+    497,        521,  498,        521,  // NOLINT
+    499,        521,  500,        525,  501,        525,
+    502,        337,  503,        437,  504,        529,
+    505,        529,  506,        533,  // NOLINT
+    507,        533,  508,        537,  509,        537,
+    510,        541,  511,        541,  512,        545,
+    513,        545,  514,        549,  // NOLINT
+    515,        549,  516,        553,  517,        553,
+    518,        557,  519,        557,  520,        561,
+    521,        561,  522,        565,  // NOLINT
+    523,        565,  524,        569,  525,        569,
+    526,        573,  527,        573,  528,        577,
+    529,        577,  530,        581,  // NOLINT
+    531,        581,  532,        585,  533,        585,
+    534,        589,  535,        589,  536,        593,
+    537,        593,  538,        597,  // NOLINT
+    539,        597,  540,        601,  541,        601,
+    542,        605,  543,        605,  544,        365,
+    546,        609,  547,        609,  // NOLINT
+    548,        613,  549,        613,  550,        617,
+    551,        617,  552,        621,  553,        621,
+    554,        625,  555,        625,  // NOLINT
+    556,        629,  557,        629,  558,        633,
+    559,        633,  560,        637,  561,        637,
+    562,        641,  563,        641,  // NOLINT
+    570,        645,  571,        649,  572,        649,
+    573,        353,  574,        653,  1073742399, 657,
+    576,        661,  577,        665,  // NOLINT
+    578,        665,  579,        277,  580,        669,
+    581,        673,  582,        677,  583,        677,
+    584,        681,  585,        681,  // NOLINT
+    586,        685,  587,        685,  588,        689,
+    589,        689,  590,        693,  591,        693,
+    592,        697,  593,        701,  // NOLINT
+    594,        705,  595,        281,  596,        293,
+    1073742422, 301,  599,        305,  601,        317,
+    603,        321,  604,        709,  // NOLINT
+    608,        329,  609,        713,  611,        333,
+    613,        717,  614,        721,  616,        345,
+    617,        341,  619,        725,  // NOLINT
+    620,        729,  623,        357,  625,        733,
+    626,        361,  629,        369,  637,        737,
+    640,        385,  643,        393,  // NOLINT
+    647,        741,  648,        401,  649,        669,
+    1073742474, 409,  651,        413,  652,        673,
+    658,        425,  670,        745,  // NOLINT
+    837,        749,  880,        753,  881,        753,
+    882,        757,  883,        757,  886,        761,
+    887,        761,  1073742715, 765,  // NOLINT
+    893,        769,  895,        773,  902,        777,
+    1073742728, 781,  906,        785,  908,        789,
+    1073742734, 793,  911,        797,  // NOLINT
+    913,        801,  914,        805,  1073742739, 809,
+    916,        813,  917,        817,  1073742742, 821,
+    919,        825,  920,        829,  // NOLINT
+    921,        749,  922,        833,  923,        837,
+    924,        9,    1073742749, 841,  927,        845,
+    928,        849,  929,        853,  // NOLINT
+    931,        857,  1073742756, 861,  933,        865,
+    934,        869,  1073742759, 873,  939,        877,
+    940,        777,  1073742765, 781,  // NOLINT
+    943,        785,  945,        801,  946,        805,
+    1073742771, 809,  948,        813,  949,        817,
+    1073742774, 821,  951,        825,  // NOLINT
+    952,        829,  953,        749,  954,        833,
+    955,        837,  956,        9,    1073742781, 841,
+    959,        845,  960,        849,  // NOLINT
+    961,        853,  962,        857,  963,        857,
+    1073742788, 861,  965,        865,  966,        869,
+    1073742791, 873,  971,        877,  // NOLINT
+    972,        789,  1073742797, 793,  974,        797,
+    975,        881,  976,        805,  977,        829,
+    981,        869,  982,        849,  // NOLINT
+    983,        881,  984,        885,  985,        885,
+    986,        889,  987,        889,  988,        893,
+    989,        893,  990,        897,  // NOLINT
+    991,        897,  992,        901,  993,        901,
+    994,        905,  995,        905,  996,        909,
+    997,        909,  998,        913,  // NOLINT
+    999,        913,  1000,       917,  1001,       917,
+    1002,       921,  1003,       921,  1004,       925,
+    1005,       925,  1006,       929,  // NOLINT
+    1007,       929,  1008,       833,  1009,       853,
+    1010,       933,  1011,       773,  1013,       817,
+    1015,       937,  1016,       937,  // NOLINT
+    1017,       933,  1018,       941,  1019,       941,
+    1073742845, 765,  1023,       769,  1073742848, 945,
+    1039,       949,  1073742864, 953,  // NOLINT
+    1071,       957,  1073742896, 953,  1103,       957,
+    1073742928, 945,  1119,       949,  1120,       961,
+    1121,       961,  1122,       965,  // NOLINT
+    1123,       965,  1124,       969,  1125,       969,
+    1126,       973,  1127,       973,  1128,       977,
+    1129,       977,  1130,       981,  // NOLINT
+    1131,       981,  1132,       985,  1133,       985,
+    1134,       989,  1135,       989,  1136,       993,
+    1137,       993,  1138,       997,  // NOLINT
+    1139,       997,  1140,       1001, 1141,       1001,
+    1142,       1005, 1143,       1005, 1144,       1009,
+    1145,       1009, 1146,       1013,  // NOLINT
+    1147,       1013, 1148,       1017, 1149,       1017,
+    1150,       1021, 1151,       1021, 1152,       1025,
+    1153,       1025, 1162,       1029,  // NOLINT
+    1163,       1029, 1164,       1033, 1165,       1033,
+    1166,       1037, 1167,       1037, 1168,       1041,
+    1169,       1041, 1170,       1045,  // NOLINT
+    1171,       1045, 1172,       1049, 1173,       1049,
+    1174,       1053, 1175,       1053, 1176,       1057,
+    1177,       1057, 1178,       1061,  // NOLINT
+    1179,       1061, 1180,       1065, 1181,       1065,
+    1182,       1069, 1183,       1069, 1184,       1073,
+    1185,       1073, 1186,       1077,  // NOLINT
+    1187,       1077, 1188,       1081, 1189,       1081,
+    1190,       1085, 1191,       1085, 1192,       1089,
+    1193,       1089, 1194,       1093,  // NOLINT
+    1195,       1093, 1196,       1097, 1197,       1097,
+    1198,       1101, 1199,       1101, 1200,       1105,
+    1201,       1105, 1202,       1109,  // NOLINT
+    1203,       1109, 1204,       1113, 1205,       1113,
+    1206,       1117, 1207,       1117, 1208,       1121,
+    1209,       1121, 1210,       1125,  // NOLINT
+    1211,       1125, 1212,       1129, 1213,       1129,
+    1214,       1133, 1215,       1133, 1216,       1137,
+    1217,       1141, 1218,       1141,  // NOLINT
+    1219,       1145, 1220,       1145, 1221,       1149,
+    1222,       1149, 1223,       1153, 1224,       1153,
+    1225,       1157, 1226,       1157,  // NOLINT
+    1227,       1161, 1228,       1161, 1229,       1165,
+    1230,       1165, 1231,       1137, 1232,       1169,
+    1233,       1169, 1234,       1173,  // NOLINT
+    1235,       1173, 1236,       1177, 1237,       1177,
+    1238,       1181, 1239,       1181, 1240,       1185,
+    1241,       1185, 1242,       1189,  // NOLINT
+    1243,       1189, 1244,       1193, 1245,       1193,
+    1246,       1197, 1247,       1197, 1248,       1201,
+    1249,       1201, 1250,       1205,  // NOLINT
+    1251,       1205, 1252,       1209, 1253,       1209,
+    1254,       1213, 1255,       1213, 1256,       1217,
+    1257,       1217, 1258,       1221,  // NOLINT
+    1259,       1221, 1260,       1225, 1261,       1225,
+    1262,       1229, 1263,       1229, 1264,       1233,
+    1265,       1233, 1266,       1237,  // NOLINT
+    1267,       1237, 1268,       1241, 1269,       1241,
+    1270,       1245, 1271,       1245, 1272,       1249,
+    1273,       1249, 1274,       1253,  // NOLINT
+    1275,       1253, 1276,       1257, 1277,       1257,
+    1278,       1261, 1279,       1261, 1280,       1265,
+    1281,       1265, 1282,       1269,  // NOLINT
+    1283,       1269, 1284,       1273, 1285,       1273,
+    1286,       1277, 1287,       1277, 1288,       1281,
+    1289,       1281, 1290,       1285,  // NOLINT
+    1291,       1285, 1292,       1289, 1293,       1289,
+    1294,       1293, 1295,       1293, 1296,       1297,
+    1297,       1297, 1298,       1301,  // NOLINT
+    1299,       1301, 1300,       1305, 1301,       1305,
+    1302,       1309, 1303,       1309, 1304,       1313,
+    1305,       1313, 1306,       1317,  // NOLINT
+    1307,       1317, 1308,       1321, 1309,       1321,
+    1310,       1325, 1311,       1325, 1312,       1329,
+    1313,       1329, 1314,       1333,  // NOLINT
+    1315,       1333, 1316,       1337, 1317,       1337,
+    1318,       1341, 1319,       1341, 1320,       1345,
+    1321,       1345, 1322,       1349,  // NOLINT
+    1323,       1349, 1324,       1353, 1325,       1353,
+    1326,       1357, 1327,       1357, 1073743153, 1361,
+    1366,       1365, 1073743201, 1361,  // NOLINT
+    1414,       1365, 1073746080, 1369, 4293,       1373,
+    4295,       1377, 4301,       1381, 7545,       1385,
+    7549,       1389, 7680,       1393,  // NOLINT
+    7681,       1393, 7682,       1397, 7683,       1397,
+    7684,       1401, 7685,       1401, 7686,       1405,
+    7687,       1405, 7688,       1409,  // NOLINT
+    7689,       1409, 7690,       1413, 7691,       1413,
+    7692,       1417, 7693,       1417, 7694,       1421,
+    7695,       1421, 7696,       1425,  // NOLINT
+    7697,       1425, 7698,       1429, 7699,       1429,
+    7700,       1433, 7701,       1433, 7702,       1437,
+    7703,       1437, 7704,       1441,  // NOLINT
+    7705,       1441, 7706,       1445, 7707,       1445,
+    7708,       1449, 7709,       1449, 7710,       1453,
+    7711,       1453, 7712,       1457,  // NOLINT
+    7713,       1457, 7714,       1461, 7715,       1461,
+    7716,       1465, 7717,       1465, 7718,       1469,
+    7719,       1469, 7720,       1473,  // NOLINT
+    7721,       1473, 7722,       1477, 7723,       1477,
+    7724,       1481, 7725,       1481, 7726,       1485,
+    7727,       1485, 7728,       1489,  // NOLINT
+    7729,       1489, 7730,       1493, 7731,       1493,
+    7732,       1497, 7733,       1497, 7734,       1501,
+    7735,       1501, 7736,       1505,  // NOLINT
+    7737,       1505, 7738,       1509, 7739,       1509,
+    7740,       1513, 7741,       1513, 7742,       1517,
+    7743,       1517, 7744,       1521,  // NOLINT
+    7745,       1521, 7746,       1525, 7747,       1525,
+    7748,       1529, 7749,       1529, 7750,       1533,
+    7751,       1533, 7752,       1537,  // NOLINT
+    7753,       1537, 7754,       1541, 7755,       1541,
+    7756,       1545, 7757,       1545, 7758,       1549,
+    7759,       1549, 7760,       1553,  // NOLINT
+    7761,       1553, 7762,       1557, 7763,       1557,
+    7764,       1561, 7765,       1561, 7766,       1565,
+    7767,       1565, 7768,       1569,  // NOLINT
+    7769,       1569, 7770,       1573, 7771,       1573,
+    7772,       1577, 7773,       1577, 7774,       1581,
+    7775,       1581, 7776,       1585,  // NOLINT
+    7777,       1585, 7778,       1589, 7779,       1589,
+    7780,       1593, 7781,       1593, 7782,       1597,
+    7783,       1597, 7784,       1601,  // NOLINT
+    7785,       1601, 7786,       1605, 7787,       1605,
+    7788,       1609, 7789,       1609, 7790,       1613,
+    7791,       1613, 7792,       1617,  // NOLINT
+    7793,       1617, 7794,       1621, 7795,       1621,
+    7796,       1625, 7797,       1625, 7798,       1629,
+    7799,       1629, 7800,       1633,  // NOLINT
+    7801,       1633, 7802,       1637, 7803,       1637,
+    7804,       1641, 7805,       1641, 7806,       1645,
+    7807,       1645, 7808,       1649,  // NOLINT
+    7809,       1649, 7810,       1653, 7811,       1653,
+    7812,       1657, 7813,       1657, 7814,       1661,
+    7815,       1661, 7816,       1665,  // NOLINT
+    7817,       1665, 7818,       1669, 7819,       1669,
+    7820,       1673, 7821,       1673, 7822,       1677,
+    7823,       1677, 7824,       1681,  // NOLINT
+    7825,       1681, 7826,       1685, 7827,       1685,
+    7828,       1689, 7829,       1689, 7835,       1585,
+    7840,       1693, 7841,       1693,  // NOLINT
+    7842,       1697, 7843,       1697, 7844,       1701,
+    7845,       1701, 7846,       1705, 7847,       1705,
+    7848,       1709, 7849,       1709,  // NOLINT
+    7850,       1713, 7851,       1713, 7852,       1717,
+    7853,       1717, 7854,       1721, 7855,       1721,
+    7856,       1725, 7857,       1725,  // NOLINT
+    7858,       1729, 7859,       1729, 7860,       1733,
+    7861,       1733, 7862,       1737, 7863,       1737,
+    7864,       1741, 7865,       1741,  // NOLINT
+    7866,       1745, 7867,       1745, 7868,       1749,
+    7869,       1749, 7870,       1753, 7871,       1753,
+    7872,       1757, 7873,       1757,  // NOLINT
+    7874,       1761, 7875,       1761, 7876,       1765,
+    7877,       1765, 7878,       1769, 7879,       1769,
+    7880,       1773, 7881,       1773,  // NOLINT
+    7882,       1777, 7883,       1777, 7884,       1781,
+    7885,       1781, 7886,       1785, 7887,       1785,
+    7888,       1789, 7889,       1789,  // NOLINT
+    7890,       1793, 7891,       1793, 7892,       1797,
+    7893,       1797, 7894,       1801, 7895,       1801,
+    7896,       1805, 7897,       1805,  // NOLINT
+    7898,       1809, 7899,       1809, 7900,       1813,
+    7901,       1813, 7902,       1817, 7903,       1817,
+    7904,       1821, 7905,       1821,  // NOLINT
+    7906,       1825, 7907,       1825, 7908,       1829,
+    7909,       1829, 7910,       1833, 7911,       1833,
+    7912,       1837, 7913,       1837,  // NOLINT
+    7914,       1841, 7915,       1841, 7916,       1845,
+    7917,       1845, 7918,       1849, 7919,       1849,
+    7920,       1853, 7921,       1853,  // NOLINT
+    7922,       1857, 7923,       1857, 7924,       1861,
+    7925,       1861, 7926,       1865, 7927,       1865,
+    7928,       1869, 7929,       1869,  // NOLINT
+    7930,       1873, 7931,       1873, 7932,       1877,
+    7933,       1877, 7934,       1881, 7935,       1881,
+    1073749760, 1885, 7943,       1889,  // NOLINT
+    1073749768, 1885, 7951,       1889, 1073749776, 1893,
+    7957,       1897, 1073749784, 1893, 7965,       1897,
+    1073749792, 1901, 7975,       1905,  // NOLINT
+    1073749800, 1901, 7983,       1905, 1073749808, 1909,
+    7991,       1913, 1073749816, 1909, 7999,       1913,
+    1073749824, 1917, 8005,       1921,  // NOLINT
+    1073749832, 1917, 8013,       1921, 8017,       1925,
+    8019,       1929, 8021,       1933, 8023,       1937,
+    8025,       1925, 8027,       1929,  // NOLINT
+    8029,       1933, 8031,       1937, 1073749856, 1941,
+    8039,       1945, 1073749864, 1941, 8047,       1945,
+    1073749872, 1949, 8049,       1953,  // NOLINT
+    1073749874, 1957, 8053,       1961, 1073749878, 1965,
+    8055,       1969, 1073749880, 1973, 8057,       1977,
+    1073749882, 1981, 8059,       1985,  // NOLINT
+    1073749884, 1989, 8061,       1993, 1073749936, 1997,
+    8113,       2001, 1073749944, 1997, 8121,       2001,
+    1073749946, 1949, 8123,       1953,  // NOLINT
+    8126,       749,  1073749960, 1957, 8139,       1961,
+    1073749968, 2005, 8145,       2009, 1073749976, 2005,
+    8153,       2009, 1073749978, 1965,  // NOLINT
+    8155,       1969, 1073749984, 2013, 8161,       2017,
+    8165,       2021, 1073749992, 2013, 8169,       2017,
+    1073749994, 1981, 8171,       1985,  // NOLINT
+    8172,       2021, 1073750008, 1973, 8185,       1977,
+    1073750010, 1989, 8187,       1993};                              // NOLINT
+static const uint16_t kEcma262UnCanonicalizeMultiStrings0Size = 507;  // NOLINT
 static const MultiCharacterSpecialCase<2> kEcma262UnCanonicalizeMultiStrings1[83] = {  // NOLINT
   {{8498, 8526}}, {{8544, 8560}}, {{8559, 8575}}, {{8579, 8580}},  // NOLINT
   {{9398, 9424}}, {{9423, 9449}}, {{11264, 11312}}, {{11310, 11358}},  // NOLINT
@@ -1616,56 +3036,165 @@
   3297, 293, 3298, 297, 3299, 297, 3307, 301, 3308, 301, 3309, 305, 3310, 305, 3314, 309,  // NOLINT
   3315, 309, 1073745152, 313, 3365, 317, 3367, 321, 3373, 325 };  // NOLINT
 static const uint16_t kEcma262UnCanonicalizeMultiStrings1Size = 83;  // NOLINT
-static const MultiCharacterSpecialCase<2> kEcma262UnCanonicalizeMultiStrings5[92] = {  // NOLINT
-  {{42560, 42561}}, {{42562, 42563}}, {{42564, 42565}}, {{42566, 42567}},  // NOLINT
-  {{42568, 42569}}, {{42570, 42571}}, {{42572, 42573}}, {{42574, 42575}},  // NOLINT
-  {{42576, 42577}}, {{42578, 42579}}, {{42580, 42581}}, {{42582, 42583}},  // NOLINT
-  {{42584, 42585}}, {{42586, 42587}}, {{42588, 42589}}, {{42590, 42591}},  // NOLINT
-  {{42592, 42593}}, {{42594, 42595}}, {{42596, 42597}}, {{42598, 42599}},  // NOLINT
-  {{42600, 42601}}, {{42602, 42603}}, {{42604, 42605}}, {{42624, 42625}},  // NOLINT
-  {{42626, 42627}}, {{42628, 42629}}, {{42630, 42631}}, {{42632, 42633}},  // NOLINT
-  {{42634, 42635}}, {{42636, 42637}}, {{42638, 42639}}, {{42640, 42641}},  // NOLINT
-  {{42642, 42643}}, {{42644, 42645}}, {{42646, 42647}}, {{42786, 42787}},  // NOLINT
-  {{42788, 42789}}, {{42790, 42791}}, {{42792, 42793}}, {{42794, 42795}},  // NOLINT
-  {{42796, 42797}}, {{42798, 42799}}, {{42802, 42803}}, {{42804, 42805}},  // NOLINT
-  {{42806, 42807}}, {{42808, 42809}}, {{42810, 42811}}, {{42812, 42813}},  // NOLINT
-  {{42814, 42815}}, {{42816, 42817}}, {{42818, 42819}}, {{42820, 42821}},  // NOLINT
-  {{42822, 42823}}, {{42824, 42825}}, {{42826, 42827}}, {{42828, 42829}},  // NOLINT
-  {{42830, 42831}}, {{42832, 42833}}, {{42834, 42835}}, {{42836, 42837}},  // NOLINT
-  {{42838, 42839}}, {{42840, 42841}}, {{42842, 42843}}, {{42844, 42845}},  // NOLINT
-  {{42846, 42847}}, {{42848, 42849}}, {{42850, 42851}}, {{42852, 42853}},  // NOLINT
-  {{42854, 42855}}, {{42856, 42857}}, {{42858, 42859}}, {{42860, 42861}},  // NOLINT
-  {{42862, 42863}}, {{42873, 42874}}, {{42875, 42876}}, {{7545, 42877}},  // NOLINT
-  {{42878, 42879}}, {{42880, 42881}}, {{42882, 42883}}, {{42884, 42885}},  // NOLINT
-  {{42886, 42887}}, {{42891, 42892}}, {{613, 42893}}, {{42896, 42897}},  // NOLINT
-  {{42898, 42899}}, {{42912, 42913}}, {{42914, 42915}}, {{42916, 42917}},  // NOLINT
-  {{42918, 42919}}, {{42920, 42921}}, {{614, 42922}}, {{kSentinel}} }; // NOLINT
-static const uint16_t kEcma262UnCanonicalizeTable5Size = 179;  // NOLINT
-static const int32_t kEcma262UnCanonicalizeTable5[358] = {
-  1600, 1, 1601, 1, 1602, 5, 1603, 5, 1604, 9, 1605, 9, 1606, 13, 1607, 13,  // NOLINT
-  1608, 17, 1609, 17, 1610, 21, 1611, 21, 1612, 25, 1613, 25, 1614, 29, 1615, 29,  // NOLINT
-  1616, 33, 1617, 33, 1618, 37, 1619, 37, 1620, 41, 1621, 41, 1622, 45, 1623, 45,  // NOLINT
-  1624, 49, 1625, 49, 1626, 53, 1627, 53, 1628, 57, 1629, 57, 1630, 61, 1631, 61,  // NOLINT
-  1632, 65, 1633, 65, 1634, 69, 1635, 69, 1636, 73, 1637, 73, 1638, 77, 1639, 77,  // NOLINT
-  1640, 81, 1641, 81, 1642, 85, 1643, 85, 1644, 89, 1645, 89, 1664, 93, 1665, 93,  // NOLINT
-  1666, 97, 1667, 97, 1668, 101, 1669, 101, 1670, 105, 1671, 105, 1672, 109, 1673, 109,  // NOLINT
-  1674, 113, 1675, 113, 1676, 117, 1677, 117, 1678, 121, 1679, 121, 1680, 125, 1681, 125,  // NOLINT
-  1682, 129, 1683, 129, 1684, 133, 1685, 133, 1686, 137, 1687, 137, 1826, 141, 1827, 141,  // NOLINT
-  1828, 145, 1829, 145, 1830, 149, 1831, 149, 1832, 153, 1833, 153, 1834, 157, 1835, 157,  // NOLINT
-  1836, 161, 1837, 161, 1838, 165, 1839, 165, 1842, 169, 1843, 169, 1844, 173, 1845, 173,  // NOLINT
-  1846, 177, 1847, 177, 1848, 181, 1849, 181, 1850, 185, 1851, 185, 1852, 189, 1853, 189,  // NOLINT
-  1854, 193, 1855, 193, 1856, 197, 1857, 197, 1858, 201, 1859, 201, 1860, 205, 1861, 205,  // NOLINT
-  1862, 209, 1863, 209, 1864, 213, 1865, 213, 1866, 217, 1867, 217, 1868, 221, 1869, 221,  // NOLINT
-  1870, 225, 1871, 225, 1872, 229, 1873, 229, 1874, 233, 1875, 233, 1876, 237, 1877, 237,  // NOLINT
-  1878, 241, 1879, 241, 1880, 245, 1881, 245, 1882, 249, 1883, 249, 1884, 253, 1885, 253,  // NOLINT
-  1886, 257, 1887, 257, 1888, 261, 1889, 261, 1890, 265, 1891, 265, 1892, 269, 1893, 269,  // NOLINT
-  1894, 273, 1895, 273, 1896, 277, 1897, 277, 1898, 281, 1899, 281, 1900, 285, 1901, 285,  // NOLINT
-  1902, 289, 1903, 289, 1913, 293, 1914, 293, 1915, 297, 1916, 297, 1917, 301, 1918, 305,  // NOLINT
-  1919, 305, 1920, 309, 1921, 309, 1922, 313, 1923, 313, 1924, 317, 1925, 317, 1926, 321,  // NOLINT
-  1927, 321, 1931, 325, 1932, 325, 1933, 329, 1936, 333, 1937, 333, 1938, 337, 1939, 337,  // NOLINT
-  1952, 341, 1953, 341, 1954, 345, 1955, 345, 1956, 349, 1957, 349, 1958, 353, 1959, 353,  // NOLINT
-  1960, 357, 1961, 357, 1962, 361 };  // NOLINT
-static const uint16_t kEcma262UnCanonicalizeMultiStrings5Size = 92;  // NOLINT
+static const MultiCharacterSpecialCase<2>
+    kEcma262UnCanonicalizeMultiStrings5[104] = {  // NOLINT
+        {{42560, 42561}},
+        {{42562, 42563}},
+        {{42564, 42565}},
+        {{42566, 42567}},  // NOLINT
+        {{42568, 42569}},
+        {{42570, 42571}},
+        {{42572, 42573}},
+        {{42574, 42575}},  // NOLINT
+        {{42576, 42577}},
+        {{42578, 42579}},
+        {{42580, 42581}},
+        {{42582, 42583}},  // NOLINT
+        {{42584, 42585}},
+        {{42586, 42587}},
+        {{42588, 42589}},
+        {{42590, 42591}},  // NOLINT
+        {{42592, 42593}},
+        {{42594, 42595}},
+        {{42596, 42597}},
+        {{42598, 42599}},  // NOLINT
+        {{42600, 42601}},
+        {{42602, 42603}},
+        {{42604, 42605}},
+        {{42624, 42625}},  // NOLINT
+        {{42626, 42627}},
+        {{42628, 42629}},
+        {{42630, 42631}},
+        {{42632, 42633}},  // NOLINT
+        {{42634, 42635}},
+        {{42636, 42637}},
+        {{42638, 42639}},
+        {{42640, 42641}},  // NOLINT
+        {{42642, 42643}},
+        {{42644, 42645}},
+        {{42646, 42647}},
+        {{42648, 42649}},  // NOLINT
+        {{42650, 42651}},
+        {{42786, 42787}},
+        {{42788, 42789}},
+        {{42790, 42791}},  // NOLINT
+        {{42792, 42793}},
+        {{42794, 42795}},
+        {{42796, 42797}},
+        {{42798, 42799}},  // NOLINT
+        {{42802, 42803}},
+        {{42804, 42805}},
+        {{42806, 42807}},
+        {{42808, 42809}},  // NOLINT
+        {{42810, 42811}},
+        {{42812, 42813}},
+        {{42814, 42815}},
+        {{42816, 42817}},  // NOLINT
+        {{42818, 42819}},
+        {{42820, 42821}},
+        {{42822, 42823}},
+        {{42824, 42825}},  // NOLINT
+        {{42826, 42827}},
+        {{42828, 42829}},
+        {{42830, 42831}},
+        {{42832, 42833}},  // NOLINT
+        {{42834, 42835}},
+        {{42836, 42837}},
+        {{42838, 42839}},
+        {{42840, 42841}},  // NOLINT
+        {{42842, 42843}},
+        {{42844, 42845}},
+        {{42846, 42847}},
+        {{42848, 42849}},  // NOLINT
+        {{42850, 42851}},
+        {{42852, 42853}},
+        {{42854, 42855}},
+        {{42856, 42857}},  // NOLINT
+        {{42858, 42859}},
+        {{42860, 42861}},
+        {{42862, 42863}},
+        {{42873, 42874}},  // NOLINT
+        {{42875, 42876}},
+        {{7545, 42877}},
+        {{42878, 42879}},
+        {{42880, 42881}},  // NOLINT
+        {{42882, 42883}},
+        {{42884, 42885}},
+        {{42886, 42887}},
+        {{42891, 42892}},  // NOLINT
+        {{613, 42893}},
+        {{42896, 42897}},
+        {{42898, 42899}},
+        {{42902, 42903}},  // NOLINT
+        {{42904, 42905}},
+        {{42906, 42907}},
+        {{42908, 42909}},
+        {{42910, 42911}},  // NOLINT
+        {{42912, 42913}},
+        {{42914, 42915}},
+        {{42916, 42917}},
+        {{42918, 42919}},  // NOLINT
+        {{42920, 42921}},
+        {{614, 42922}},
+        {{604, 42923}},
+        {{609, 42924}},  // NOLINT
+        {{620, 42925}},
+        {{670, 42928}},
+        {{647, 42929}},
+        {{kSentinel}}};                                        // NOLINT
+static const uint16_t kEcma262UnCanonicalizeTable5Size = 198;  // NOLINT
+static const int32_t kEcma262UnCanonicalizeTable5
+    [396] = {1600, 1,   1601, 1,   1602, 5,   1603, 5,
+             1604, 9,   1605, 9,   1606, 13,  1607, 13,  // NOLINT
+             1608, 17,  1609, 17,  1610, 21,  1611, 21,
+             1612, 25,  1613, 25,  1614, 29,  1615, 29,  // NOLINT
+             1616, 33,  1617, 33,  1618, 37,  1619, 37,
+             1620, 41,  1621, 41,  1622, 45,  1623, 45,  // NOLINT
+             1624, 49,  1625, 49,  1626, 53,  1627, 53,
+             1628, 57,  1629, 57,  1630, 61,  1631, 61,  // NOLINT
+             1632, 65,  1633, 65,  1634, 69,  1635, 69,
+             1636, 73,  1637, 73,  1638, 77,  1639, 77,  // NOLINT
+             1640, 81,  1641, 81,  1642, 85,  1643, 85,
+             1644, 89,  1645, 89,  1664, 93,  1665, 93,  // NOLINT
+             1666, 97,  1667, 97,  1668, 101, 1669, 101,
+             1670, 105, 1671, 105, 1672, 109, 1673, 109,  // NOLINT
+             1674, 113, 1675, 113, 1676, 117, 1677, 117,
+             1678, 121, 1679, 121, 1680, 125, 1681, 125,  // NOLINT
+             1682, 129, 1683, 129, 1684, 133, 1685, 133,
+             1686, 137, 1687, 137, 1688, 141, 1689, 141,  // NOLINT
+             1690, 145, 1691, 145, 1826, 149, 1827, 149,
+             1828, 153, 1829, 153, 1830, 157, 1831, 157,  // NOLINT
+             1832, 161, 1833, 161, 1834, 165, 1835, 165,
+             1836, 169, 1837, 169, 1838, 173, 1839, 173,  // NOLINT
+             1842, 177, 1843, 177, 1844, 181, 1845, 181,
+             1846, 185, 1847, 185, 1848, 189, 1849, 189,  // NOLINT
+             1850, 193, 1851, 193, 1852, 197, 1853, 197,
+             1854, 201, 1855, 201, 1856, 205, 1857, 205,  // NOLINT
+             1858, 209, 1859, 209, 1860, 213, 1861, 213,
+             1862, 217, 1863, 217, 1864, 221, 1865, 221,  // NOLINT
+             1866, 225, 1867, 225, 1868, 229, 1869, 229,
+             1870, 233, 1871, 233, 1872, 237, 1873, 237,  // NOLINT
+             1874, 241, 1875, 241, 1876, 245, 1877, 245,
+             1878, 249, 1879, 249, 1880, 253, 1881, 253,  // NOLINT
+             1882, 257, 1883, 257, 1884, 261, 1885, 261,
+             1886, 265, 1887, 265, 1888, 269, 1889, 269,  // NOLINT
+             1890, 273, 1891, 273, 1892, 277, 1893, 277,
+             1894, 281, 1895, 281, 1896, 285, 1897, 285,  // NOLINT
+             1898, 289, 1899, 289, 1900, 293, 1901, 293,
+             1902, 297, 1903, 297, 1913, 301, 1914, 301,  // NOLINT
+             1915, 305, 1916, 305, 1917, 309, 1918, 313,
+             1919, 313, 1920, 317, 1921, 317, 1922, 321,  // NOLINT
+             1923, 321, 1924, 325, 1925, 325, 1926, 329,
+             1927, 329, 1931, 333, 1932, 333, 1933, 337,  // NOLINT
+             1936, 341, 1937, 341, 1938, 345, 1939, 345,
+             1942, 349, 1943, 349, 1944, 353, 1945, 353,  // NOLINT
+             1946, 357, 1947, 357, 1948, 361, 1949, 361,
+             1950, 365, 1951, 365, 1952, 369, 1953, 369,  // NOLINT
+             1954, 373, 1955, 373, 1956, 377, 1957, 377,
+             1958, 381, 1959, 381, 1960, 385, 1961, 385,  // NOLINT
+             1962, 389, 1963, 393, 1964, 397, 1965, 401,
+             1968, 405, 1969, 409};                                   // NOLINT
+static const uint16_t kEcma262UnCanonicalizeMultiStrings5Size = 104;  // NOLINT
 static const MultiCharacterSpecialCase<2> kEcma262UnCanonicalizeMultiStrings7[3] = {  // NOLINT
   {{65313, 65345}}, {{65338, 65370}}, {{kSentinel}} }; // NOLINT
 static const uint16_t kEcma262UnCanonicalizeTable7Size = 4;  // NOLINT
@@ -1772,55 +3301,96 @@
 const uchar UnicodeData::kMaxCodePoint = 65533;
 
 int UnicodeData::GetByteCount() {
-  return kUppercaseTable0Size * sizeof(int32_t)  // NOLINT
-      + kUppercaseTable1Size * sizeof(int32_t)  // NOLINT
-      + kUppercaseTable5Size * sizeof(int32_t)  // NOLINT
-      + kUppercaseTable7Size * sizeof(int32_t)  // NOLINT
-      + kLowercaseTable0Size * sizeof(int32_t)  // NOLINT
-      + kLowercaseTable1Size * sizeof(int32_t)  // NOLINT
-      + kLowercaseTable5Size * sizeof(int32_t)  // NOLINT
-      + kLowercaseTable7Size * sizeof(int32_t)  // NOLINT
-      + kLetterTable0Size * sizeof(int32_t)  // NOLINT
-      + kLetterTable1Size * sizeof(int32_t)  // NOLINT
-      + kLetterTable2Size * sizeof(int32_t)  // NOLINT
-      + kLetterTable3Size * sizeof(int32_t)  // NOLINT
-      + kLetterTable4Size * sizeof(int32_t)  // NOLINT
-      + kLetterTable5Size * sizeof(int32_t)  // NOLINT
-      + kLetterTable6Size * sizeof(int32_t)  // NOLINT
-      + kLetterTable7Size * sizeof(int32_t)  // NOLINT
-      + kNumberTable0Size * sizeof(int32_t)  // NOLINT
-      + kNumberTable5Size * sizeof(int32_t)  // NOLINT
-      + kNumberTable7Size * sizeof(int32_t)  // NOLINT
-      + kWhiteSpaceTable0Size * sizeof(int32_t)  // NOLINT
-      + kWhiteSpaceTable1Size * sizeof(int32_t)  // NOLINT
-      + kLineTerminatorTable0Size * sizeof(int32_t)  // NOLINT
-      + kLineTerminatorTable1Size * sizeof(int32_t)  // NOLINT
-      + kCombiningMarkTable0Size * sizeof(int32_t)  // NOLINT
-      + kCombiningMarkTable1Size * sizeof(int32_t)  // NOLINT
-      + kCombiningMarkTable5Size * sizeof(int32_t)  // NOLINT
-      + kCombiningMarkTable7Size * sizeof(int32_t)  // NOLINT
-      + kConnectorPunctuationTable0Size * sizeof(int32_t)  // NOLINT
-      + kConnectorPunctuationTable1Size * sizeof(int32_t)  // NOLINT
-      + kConnectorPunctuationTable7Size * sizeof(int32_t)  // NOLINT
-      + kToLowercaseMultiStrings0Size * sizeof(MultiCharacterSpecialCase<2>)  // NOLINT
-      + kToLowercaseMultiStrings1Size * sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
-      + kToLowercaseMultiStrings5Size * sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
-      + kToLowercaseMultiStrings7Size * sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
-      + kToUppercaseMultiStrings0Size * sizeof(MultiCharacterSpecialCase<3>)  // NOLINT
-      + kToUppercaseMultiStrings1Size * sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
-      + kToUppercaseMultiStrings5Size * sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
-      + kToUppercaseMultiStrings7Size * sizeof(MultiCharacterSpecialCase<3>)  // NOLINT
-      + kEcma262CanonicalizeMultiStrings0Size * sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
-      + kEcma262CanonicalizeMultiStrings1Size * sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
-      + kEcma262CanonicalizeMultiStrings5Size * sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
-      + kEcma262CanonicalizeMultiStrings7Size * sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
-      + kEcma262UnCanonicalizeMultiStrings0Size * sizeof(MultiCharacterSpecialCase<4>)  // NOLINT
-      + kEcma262UnCanonicalizeMultiStrings1Size * sizeof(MultiCharacterSpecialCase<2>)  // NOLINT
-      + kEcma262UnCanonicalizeMultiStrings5Size * sizeof(MultiCharacterSpecialCase<2>)  // NOLINT
-      + kEcma262UnCanonicalizeMultiStrings7Size * sizeof(MultiCharacterSpecialCase<2>)  // NOLINT
-      + kCanonicalizationRangeMultiStrings0Size * sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
-      + kCanonicalizationRangeMultiStrings1Size * sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
-      + kCanonicalizationRangeMultiStrings7Size * sizeof(MultiCharacterSpecialCase<1>); // NOLINT
+  return kUppercaseTable0Size * sizeof(int32_t)         // NOLINT
+         + kUppercaseTable1Size * sizeof(int32_t)       // NOLINT
+         + kUppercaseTable5Size * sizeof(int32_t)       // NOLINT
+         + kUppercaseTable7Size * sizeof(int32_t)       // NOLINT
+         + kLowercaseTable0Size * sizeof(int32_t)       // NOLINT
+         + kLowercaseTable1Size * sizeof(int32_t)       // NOLINT
+         + kLowercaseTable5Size * sizeof(int32_t)       // NOLINT
+         + kLowercaseTable7Size * sizeof(int32_t)       // NOLINT
+         + kLetterTable0Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable1Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable2Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable3Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable4Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable5Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable6Size * sizeof(int32_t)          // NOLINT
+         + kLetterTable7Size * sizeof(int32_t)          // NOLINT
+         + kID_StartTable0Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable1Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable2Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable3Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable4Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable5Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable6Size * sizeof(int32_t)        // NOLINT
+         + kID_StartTable7Size * sizeof(int32_t)        // NOLINT
+         + kID_ContinueTable0Size * sizeof(int32_t)     // NOLINT
+         + kID_ContinueTable1Size * sizeof(int32_t)     // NOLINT
+         + kID_ContinueTable5Size * sizeof(int32_t)     // NOLINT
+         + kID_ContinueTable7Size * sizeof(int32_t)     // NOLINT
+         + kWhiteSpaceTable0Size * sizeof(int32_t)      // NOLINT
+         + kWhiteSpaceTable1Size * sizeof(int32_t)      // NOLINT
+         + kWhiteSpaceTable7Size * sizeof(int32_t)      // NOLINT
+         + kLineTerminatorTable0Size * sizeof(int32_t)  // NOLINT
+         + kLineTerminatorTable1Size * sizeof(int32_t)  // NOLINT
+         +
+         kToLowercaseMultiStrings0Size *
+             sizeof(MultiCharacterSpecialCase<2>)  // NOLINT
+         +
+         kToLowercaseMultiStrings1Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kToLowercaseMultiStrings5Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kToLowercaseMultiStrings7Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kToUppercaseMultiStrings0Size *
+             sizeof(MultiCharacterSpecialCase<3>)  // NOLINT
+         +
+         kToUppercaseMultiStrings1Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kToUppercaseMultiStrings5Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kToUppercaseMultiStrings7Size *
+             sizeof(MultiCharacterSpecialCase<3>)  // NOLINT
+         +
+         kEcma262CanonicalizeMultiStrings0Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kEcma262CanonicalizeMultiStrings1Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kEcma262CanonicalizeMultiStrings5Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kEcma262CanonicalizeMultiStrings7Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kEcma262UnCanonicalizeMultiStrings0Size *
+             sizeof(MultiCharacterSpecialCase<4>)  // NOLINT
+         +
+         kEcma262UnCanonicalizeMultiStrings1Size *
+             sizeof(MultiCharacterSpecialCase<2>)  // NOLINT
+         +
+         kEcma262UnCanonicalizeMultiStrings5Size *
+             sizeof(MultiCharacterSpecialCase<2>)  // NOLINT
+         +
+         kEcma262UnCanonicalizeMultiStrings7Size *
+             sizeof(MultiCharacterSpecialCase<2>)  // NOLINT
+         +
+         kCanonicalizationRangeMultiStrings0Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kCanonicalizationRangeMultiStrings1Size *
+             sizeof(MultiCharacterSpecialCase<1>)  // NOLINT
+         +
+         kCanonicalizationRangeMultiStrings7Size *
+             sizeof(MultiCharacterSpecialCase<1>);  // NOLINT
 }
 
-}  // namespace unicode
+}  // namespace unibrow
diff --git a/src/unicode.h b/src/unicode.h
index e2d6b96..1666814 100644
--- a/src/unicode.h
+++ b/src/unicode.h
@@ -7,6 +7,7 @@
 
 #include <sys/types.h>
 #include "src/globals.h"
+#include "src/utils.h"
 /**
  * \file
  * Definitions and convenience functions for working with unicode.
@@ -28,22 +29,33 @@
  public:
   inline Predicate() { }
   inline bool get(uchar c);
+
  private:
   friend class Test;
   bool CalculateValue(uchar c);
-  struct CacheEntry {
-    inline CacheEntry() : code_point_(0), value_(0) { }
+  class CacheEntry {
+   public:
+    inline CacheEntry()
+        : bit_field_(CodePointField::encode(0) | ValueField::encode(0)) {}
     inline CacheEntry(uchar code_point, bool value)
-      : code_point_(code_point),
-        value_(value) { }
-    uchar code_point_ : 21;
-    bool value_ : 1;
+        : bit_field_(CodePointField::encode(code_point) |
+                     ValueField::encode(value)) {}
+
+    uchar code_point() const { return CodePointField::decode(bit_field_); }
+    bool value() const { return ValueField::decode(bit_field_); }
+
+   private:
+    class CodePointField : public v8::internal::BitField<uchar, 0, 21> {};
+    class ValueField : public v8::internal::BitField<bool, 21, 1> {};
+
+    uint32_t bit_field_;
   };
   static const int kSize = size;
   static const int kMask = kSize - 1;
   CacheEntry entries_[kSize];
 };
 
+
 // A cache used in case conversion.  It caches the value for characters
 // that either have no mapping or map to a single character independent
 // of context.  Characters that map to more than one character or that
@@ -70,6 +82,7 @@
   CacheEntry entries_[kSize];
 };
 
+
 class UnicodeData {
  private:
   friend class Test;
@@ -77,6 +90,7 @@
   static const uchar kMaxCodePoint;
 };
 
+
 class Utf16 {
  public:
   static inline bool IsSurrogatePair(int lead, int trail) {
@@ -113,14 +127,6 @@
   }
 };
 
-class Latin1 {
- public:
-  static const unsigned kMaxChar = 0xff;
-  // Returns 0 if character does not convert to single latin-1 character
-  // or if the character doesn't not convert back to latin-1 via inverse
-  // operation (upper to lower, etc).
-  static inline uint16_t ConvertNonLatin1ToLatin1(uint16_t);
-};
 
 class Utf8 {
  public:
@@ -155,45 +161,6 @@
                               unsigned* cursor);
 };
 
-
-class Utf8DecoderBase {
- public:
-  // Initialization done in subclass.
-  inline Utf8DecoderBase();
-  inline Utf8DecoderBase(uint16_t* buffer,
-                         unsigned buffer_length,
-                         const uint8_t* stream,
-                         unsigned stream_length);
-  inline unsigned Utf16Length() const { return utf16_length_; }
- protected:
-  // This reads all characters and sets the utf16_length_.
-  // The first buffer_length utf16 chars are cached in the buffer.
-  void Reset(uint16_t* buffer,
-             unsigned buffer_length,
-             const uint8_t* stream,
-             unsigned stream_length);
-  static void WriteUtf16Slow(const uint8_t* stream,
-                             uint16_t* data,
-                             unsigned length);
-  const uint8_t* unbuffered_start_;
-  unsigned utf16_length_;
-  bool last_byte_of_buffer_unused_;
- private:
-  DISALLOW_COPY_AND_ASSIGN(Utf8DecoderBase);
-};
-
-template <unsigned kBufferSize>
-class Utf8Decoder : public Utf8DecoderBase {
- public:
-  inline Utf8Decoder() {}
-  inline Utf8Decoder(const char* stream, unsigned length);
-  inline void Reset(const char* stream, unsigned length);
-  inline unsigned WriteUtf16(uint16_t* data, unsigned length) const;
- private:
-  uint16_t buffer_[kBufferSize];
-};
-
-
 struct Uppercase {
   static bool Is(uchar c);
 };
@@ -203,7 +170,10 @@
 struct Letter {
   static bool Is(uchar c);
 };
-struct Number {
+struct ID_Start {
+  static bool Is(uchar c);
+};
+struct ID_Continue {
   static bool Is(uchar c);
 };
 struct WhiteSpace {
@@ -212,12 +182,6 @@
 struct LineTerminator {
   static bool Is(uchar c);
 };
-struct CombiningMark {
-  static bool Is(uchar c);
-};
-struct ConnectorPunctuation {
-  static bool Is(uchar c);
-};
 struct ToLowercase {
   static const int kMaxWidth = 3;
   static const bool kIsToLower = true;
diff --git a/src/unique.h b/src/unique.h
index 619c3c9..321eb36 100644
--- a/src/unique.h
+++ b/src/unique.h
@@ -5,9 +5,11 @@
 #ifndef V8_HYDROGEN_UNIQUE_H_
 #define V8_HYDROGEN_UNIQUE_H_
 
+#include <ostream>  // NOLINT(readability/streams)
+
+#include "src/base/functional.h"
 #include "src/handles-inl.h"  // TODO(everyone): Fix our inl.h crap
 #include "src/objects-inl.h"  // TODO(everyone): Fix our inl.h crap
-#include "src/string-stream.h"
 #include "src/utils.h"
 #include "src/zone.h"
 
@@ -81,6 +83,11 @@
     return raw_address_ != other.raw_address_;
   }
 
+  friend inline size_t hash_value(Unique<T> const& unique) {
+    DCHECK(unique.IsInitialized());
+    return base::hash<void*>()(unique.raw_address_);
+  }
+
   inline intptr_t Hashcode() const {
     DCHECK(IsInitialized());
     return reinterpret_cast<intptr_t>(raw_address_);
@@ -110,7 +117,7 @@
 
   // TODO(titzer): this is a hack to migrate to Unique<T> incrementally.
   static Unique<T> CreateUninitialized(Handle<T> handle) {
-    return Unique<T>(reinterpret_cast<Address>(NULL), handle);
+    return Unique<T>(NULL, handle);
   }
 
   static Unique<T> CreateImmovable(Handle<T> handle) {
@@ -128,6 +135,11 @@
   friend class SideEffectsTracker;
 };
 
+template <typename T>
+inline std::ostream& operator<<(std::ostream& os, Unique<T> uniq) {
+  return os << Brief(*uniq.handle());
+}
+
 
 template <typename T>
 class UniqueSet FINAL : public ZoneObject {
diff --git a/src/uri.h b/src/uri.h
deleted file mode 100644
index 75f2605..0000000
--- a/src/uri.h
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_URI_H_
-#define V8_URI_H_
-
-#include "src/v8.h"
-
-#include "src/conversions.h"
-#include "src/string-search.h"
-#include "src/utils.h"
-
-namespace v8 {
-namespace internal {
-
-
-template <typename Char>
-static INLINE(Vector<const Char> GetCharVector(Handle<String> string));
-
-
-template <>
-Vector<const uint8_t> GetCharVector(Handle<String> string) {
-  String::FlatContent flat = string->GetFlatContent();
-  DCHECK(flat.IsOneByte());
-  return flat.ToOneByteVector();
-}
-
-
-template <>
-Vector<const uc16> GetCharVector(Handle<String> string) {
-  String::FlatContent flat = string->GetFlatContent();
-  DCHECK(flat.IsTwoByte());
-  return flat.ToUC16Vector();
-}
-
-
-class URIUnescape : public AllStatic {
- public:
-  template<typename Char>
-  MUST_USE_RESULT static MaybeHandle<String> Unescape(Isolate* isolate,
-                                                      Handle<String> source);
-
- private:
-  static const signed char kHexValue['g'];
-
-  template<typename Char>
-  MUST_USE_RESULT static MaybeHandle<String> UnescapeSlow(
-      Isolate* isolate, Handle<String> string, int start_index);
-
-  static INLINE(int TwoDigitHex(uint16_t character1, uint16_t character2));
-
-  template <typename Char>
-  static INLINE(int UnescapeChar(Vector<const Char> vector,
-                                 int i,
-                                 int length,
-                                 int* step));
-};
-
-
-const signed char URIUnescape::kHexValue[] = {
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -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,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,
-    -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-    -1, 10, 11, 12, 13, 14, 15 };
-
-
-template<typename Char>
-MaybeHandle<String> URIUnescape::Unescape(Isolate* isolate,
-                                          Handle<String> source) {
-  int index;
-  { DisallowHeapAllocation no_allocation;
-    StringSearch<uint8_t, Char> search(isolate, STATIC_CHAR_VECTOR("%"));
-    index = search.Search(GetCharVector<Char>(source), 0);
-    if (index < 0) return source;
-  }
-  return UnescapeSlow<Char>(isolate, source, index);
-}
-
-
-template <typename Char>
-MaybeHandle<String> URIUnescape::UnescapeSlow(
-    Isolate* isolate, Handle<String> string, int start_index) {
-  bool one_byte = true;
-  int length = string->length();
-
-  int unescaped_length = 0;
-  { DisallowHeapAllocation no_allocation;
-    Vector<const Char> vector = GetCharVector<Char>(string);
-    for (int i = start_index; i < length; unescaped_length++) {
-      int step;
-      if (UnescapeChar(vector, i, length, &step) >
-              String::kMaxOneByteCharCode) {
-        one_byte = false;
-      }
-      i += step;
-    }
-  }
-
-  DCHECK(start_index < length);
-  Handle<String> first_part =
-      isolate->factory()->NewProperSubString(string, 0, start_index);
-
-  int dest_position = 0;
-  Handle<String> second_part;
-  DCHECK(unescaped_length <= String::kMaxLength);
-  if (one_byte) {
-    Handle<SeqOneByteString> dest = isolate->factory()->NewRawOneByteString(
-        unescaped_length).ToHandleChecked();
-    DisallowHeapAllocation no_allocation;
-    Vector<const Char> vector = GetCharVector<Char>(string);
-    for (int i = start_index; i < length; dest_position++) {
-      int step;
-      dest->SeqOneByteStringSet(dest_position,
-                                UnescapeChar(vector, i, length, &step));
-      i += step;
-    }
-    second_part = dest;
-  } else {
-    Handle<SeqTwoByteString> dest = isolate->factory()->NewRawTwoByteString(
-        unescaped_length).ToHandleChecked();
-    DisallowHeapAllocation no_allocation;
-    Vector<const Char> vector = GetCharVector<Char>(string);
-    for (int i = start_index; i < length; dest_position++) {
-      int step;
-      dest->SeqTwoByteStringSet(dest_position,
-                                UnescapeChar(vector, i, length, &step));
-      i += step;
-    }
-    second_part = dest;
-  }
-  return isolate->factory()->NewConsString(first_part, second_part);
-}
-
-
-int URIUnescape::TwoDigitHex(uint16_t character1, uint16_t character2) {
-  if (character1 > 'f') return -1;
-  int hi = kHexValue[character1];
-  if (hi == -1) return -1;
-  if (character2 > 'f') return -1;
-  int lo = kHexValue[character2];
-  if (lo == -1) return -1;
-  return (hi << 4) + lo;
-}
-
-
-template <typename Char>
-int URIUnescape::UnescapeChar(Vector<const Char> vector,
-                              int i,
-                              int length,
-                              int* step) {
-  uint16_t character = vector[i];
-  int32_t hi = 0;
-  int32_t lo = 0;
-  if (character == '%' &&
-      i <= length - 6 &&
-      vector[i + 1] == 'u' &&
-      (hi = TwoDigitHex(vector[i + 2],
-                        vector[i + 3])) != -1 &&
-      (lo = TwoDigitHex(vector[i + 4],
-                        vector[i + 5])) != -1) {
-    *step = 6;
-    return (hi << 8) + lo;
-  } else if (character == '%' &&
-      i <= length - 3 &&
-      (lo = TwoDigitHex(vector[i + 1],
-                        vector[i + 2])) != -1) {
-    *step = 3;
-    return lo;
-  } else {
-    *step = 1;
-    return character;
-  }
-}
-
-
-class URIEscape : public AllStatic {
- public:
-  template<typename Char>
-  MUST_USE_RESULT static MaybeHandle<String> Escape(Isolate* isolate,
-                                                    Handle<String> string);
-
- private:
-  static const char kHexChars[17];
-  static const char kNotEscaped[256];
-
-  static bool IsNotEscaped(uint16_t c) { return kNotEscaped[c] != 0; }
-};
-
-
-const char URIEscape::kHexChars[] = "0123456789ABCDEF";
-
-
-// kNotEscaped is generated by the following:
-//
-// #!/bin/perl
-// for (my $i = 0; $i < 256; $i++) {
-//   print "\n" if $i % 16 == 0;
-//   my $c = chr($i);
-//   my $escaped = 1;
-//   $escaped = 0 if $c =~ m#[A-Za-z0-9@*_+./-]#;
-//   print $escaped ? "0, " : "1, ";
-// }
-
-const char URIEscape::kNotEscaped[] = {
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1,
-    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 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, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-
-template<typename Char>
-MaybeHandle<String> URIEscape::Escape(Isolate* isolate, Handle<String> string) {
-  DCHECK(string->IsFlat());
-  int escaped_length = 0;
-  int length = string->length();
-
-  { DisallowHeapAllocation no_allocation;
-    Vector<const Char> vector = GetCharVector<Char>(string);
-    for (int i = 0; i < length; i++) {
-      uint16_t c = vector[i];
-      if (c >= 256) {
-        escaped_length += 6;
-      } else if (IsNotEscaped(c)) {
-        escaped_length++;
-      } else {
-        escaped_length += 3;
-      }
-
-      // We don't allow strings that are longer than a maximal length.
-      DCHECK(String::kMaxLength < 0x7fffffff - 6);  // Cannot overflow.
-      if (escaped_length > String::kMaxLength) break;  // Provoke exception.
-    }
-  }
-
-  // No length change implies no change.  Return original string if no change.
-  if (escaped_length == length) return string;
-
-  Handle<SeqOneByteString> dest;
-  ASSIGN_RETURN_ON_EXCEPTION(
-      isolate, dest,
-      isolate->factory()->NewRawOneByteString(escaped_length),
-      String);
-  int dest_position = 0;
-
-  { DisallowHeapAllocation no_allocation;
-    Vector<const Char> vector = GetCharVector<Char>(string);
-    for (int i = 0; i < length; i++) {
-      uint16_t c = vector[i];
-      if (c >= 256) {
-        dest->SeqOneByteStringSet(dest_position, '%');
-        dest->SeqOneByteStringSet(dest_position+1, 'u');
-        dest->SeqOneByteStringSet(dest_position+2, kHexChars[c >> 12]);
-        dest->SeqOneByteStringSet(dest_position+3, kHexChars[(c >> 8) & 0xf]);
-        dest->SeqOneByteStringSet(dest_position+4, kHexChars[(c >> 4) & 0xf]);
-        dest->SeqOneByteStringSet(dest_position+5, kHexChars[c & 0xf]);
-        dest_position += 6;
-      } else if (IsNotEscaped(c)) {
-        dest->SeqOneByteStringSet(dest_position, c);
-        dest_position++;
-      } else {
-        dest->SeqOneByteStringSet(dest_position, '%');
-        dest->SeqOneByteStringSet(dest_position+1, kHexChars[c >> 4]);
-        dest->SeqOneByteStringSet(dest_position+2, kHexChars[c & 0xf]);
-        dest_position += 3;
-      }
-    }
-  }
-
-  return dest;
-}
-
-} }  // namespace v8::internal
-
-#endif  // V8_URI_H_
diff --git a/src/utils.cc b/src/utils.cc
index 165855a..40c8b40 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -7,6 +7,7 @@
 
 #include "src/v8.h"
 
+#include "src/base/functional.h"
 #include "src/base/logging.h"
 #include "src/base/platform/platform.h"
 #include "src/utils.h"
@@ -77,6 +78,17 @@
 }
 
 
+size_t hash_value(BailoutId id) {
+  base::hash<int> h;
+  return h(id.id_);
+}
+
+
+std::ostream& operator<<(std::ostream& os, BailoutId id) {
+  return os << id.id_;
+}
+
+
 void PrintF(const char* format, ...) {
   va_list arguments;
   va_start(arguments, format);
diff --git a/src/utils.h b/src/utils.h
index 2991815..525c6f8 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -61,7 +61,6 @@
   }
   DCHECK_EQ(1 << bits, original_x);
   return bits;
-  return 0;
 }
 
 
@@ -157,7 +156,7 @@
 
 // Floor(-0.0) == 0.0
 inline double Floor(double x) {
-#ifdef _MSC_VER
+#if V8_CC_MSVC
   if (x == 0) return x;  // Fix for issue 3477.
 #endif
   return std::floor(x);
@@ -231,6 +230,14 @@
 };
 
 
+template <class T, int shift, int size>
+class BitField8 : public BitFieldBase<T, shift, size, uint8_t> {};
+
+
+template <class T, int shift, int size>
+class BitField16 : public BitFieldBase<T, shift, size, uint16_t> {};
+
+
 template<class T, int shift, int size>
 class BitField : public BitFieldBase<T, shift, size, uint32_t> { };
 
@@ -240,6 +247,46 @@
 
 
 // ----------------------------------------------------------------------------
+// BitSetComputer is a help template for encoding and decoding information for
+// a variable number of items in an array.
+//
+// To encode boolean data in a smi array you would use:
+// typedef BitSetComputer<bool, 1, kSmiValueSize, uint32_t> BoolComputer;
+//
+template <class T, int kBitsPerItem, int kBitsPerWord, class U>
+class BitSetComputer {
+ public:
+  static const int kItemsPerWord = kBitsPerWord / kBitsPerItem;
+  static const int kMask = (1 << kBitsPerItem) - 1;
+
+  // The number of array elements required to embed T information for each item.
+  static int word_count(int items) {
+    if (items == 0) return 0;
+    return (items - 1) / kItemsPerWord + 1;
+  }
+
+  // The array index to look at for item.
+  static int index(int base_index, int item) {
+    return base_index + item / kItemsPerWord;
+  }
+
+  // Extract T data for a given item from data.
+  static T decode(U data, int item) {
+    return static_cast<T>((data >> shift(item)) & kMask);
+  }
+
+  // Return the encoding for a store of value for item in previous.
+  static U encode(U previous, int item, T value) {
+    int shift_value = shift(item);
+    int set_bits = (static_cast<int>(value) << shift_value);
+    return (previous & ~(kMask << shift_value)) | set_bits;
+  }
+
+  static int shift(int item) { return (item % kItemsPerWord) * kBitsPerItem; }
+};
+
+
+// ----------------------------------------------------------------------------
 // Hash function.
 
 static const uint32_t kZeroHashSeed = 0;
@@ -816,7 +863,7 @@
   // compute the length of the input string.
   void AddString(const char* s);
 
-  // Add the first 'n' characters of the given string 's' to the
+  // Add the first 'n' characters of the given 0-terminated string 's' to the
   // builder. The input string must have enough characters.
   void AddSubstring(const char* s, int n);
 
@@ -952,6 +999,33 @@
 };
 
 
+template <int dummy_parameter>
+class VectorSlot {
+ public:
+  explicit VectorSlot(int id) : id_(id) {}
+  int ToInt() const { return id_; }
+
+  static VectorSlot Invalid() { return VectorSlot(kInvalidSlot); }
+  bool IsInvalid() const { return id_ == kInvalidSlot; }
+
+  VectorSlot next() const {
+    DCHECK(id_ != kInvalidSlot);
+    return VectorSlot(id_ + 1);
+  }
+
+  bool operator==(const VectorSlot& other) const { return id_ == other.id_; }
+
+ private:
+  static const int kInvalidSlot = -1;
+
+  int id_;
+};
+
+
+typedef VectorSlot<0> FeedbackVectorSlot;
+typedef VectorSlot<1> FeedbackVectorICSlot;
+
+
 class BailoutId {
  public:
   explicit BailoutId(int id) : id_(id) { }
@@ -966,6 +1040,8 @@
   bool IsNone() const { return id_ == kNoneId; }
   bool operator==(const BailoutId& other) const { return id_ == other.id_; }
   bool operator!=(const BailoutId& other) const { return id_ != other.id_; }
+  friend size_t hash_value(BailoutId);
+  friend std::ostream& operator<<(std::ostream&, BailoutId);
 
  private:
   static const int kNoneId = -1;
diff --git a/src/v8.cc b/src/v8.cc
index 62c3da4..b04ccc0 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -18,10 +18,12 @@
 #include "src/hydrogen.h"
 #include "src/isolate.h"
 #include "src/lithium-allocator.h"
+#include "src/natives.h"
 #include "src/objects.h"
 #include "src/runtime-profiler.h"
 #include "src/sampler.h"
 #include "src/serialize.h"
+#include "src/snapshot.h"
 
 
 namespace v8 {
@@ -29,6 +31,11 @@
 
 V8_DECLARE_ONCE(init_once);
 
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+V8_DECLARE_ONCE(init_natives_once);
+V8_DECLARE_ONCE(init_snapshot_once);
+#endif
+
 v8::ArrayBuffer::Allocator* V8::array_buffer_allocator_ = NULL;
 v8::Platform* V8::platform_ = NULL;
 
@@ -117,4 +124,21 @@
   return platform_;
 }
 
+
+void V8::SetNativesBlob(StartupData* natives_blob) {
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+  base::CallOnce(&init_natives_once, &SetNativesFromFile, natives_blob);
+#else
+  CHECK(false);
+#endif
+}
+
+
+void V8::SetSnapshotBlob(StartupData* snapshot_blob) {
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+  base::CallOnce(&init_snapshot_once, &SetSnapshotFromFile, snapshot_blob);
+#else
+  CHECK(false);
+#endif
+}
 } }  // namespace v8::internal
diff --git a/src/v8.h b/src/v8.h
index 13c33e1..4267434 100644
--- a/src/v8.h
+++ b/src/v8.h
@@ -9,8 +9,8 @@
 #ifndef V8_V8_H_
 #define V8_V8_H_
 
-#if defined(GOOGLE3)
-// Google3 special flag handling.
+#if defined(GOOGLE3) || defined(DCHECK_ALWAYS_ON)
+// Google3 and Chromium special flag handling.
 #if defined(DEBUG) && defined(NDEBUG)
 // V8 only uses DEBUG and whenever it is set we are building a debug
 // version of V8. We do not use NDEBUG and simply undef it here for
@@ -82,6 +82,9 @@
   static void ShutdownPlatform();
   static v8::Platform* GetCurrentPlatform();
 
+  static void SetNativesBlob(StartupData* natives_blob);
+  static void SetSnapshotBlob(StartupData* snapshot_blob);
+
  private:
   static void InitializeOncePerProcessImpl();
   static void InitializeOncePerProcess();
diff --git a/src/v8natives.js b/src/v8natives.js
index 782b953..ac96f63 100644
--- a/src/v8natives.js
+++ b/src/v8natives.js
@@ -163,19 +163,9 @@
 function GlobalEval(x) {
   if (!IS_STRING(x)) return x;
 
-  // For consistency with JSC we require the global object passed to
-  // eval to be the global object from which 'eval' originated. This
-  // is not mandated by the spec.
-  // We only throw if the global has been detached, since we need the
-  // receiver as this-value for the call.
-  if (!%IsAttachedGlobal(global)) {
-    throw new $EvalError('The "this" value passed to eval must ' +
-                         'be the global object from which eval originated');
-  }
-
   var global_proxy = %GlobalProxy(global);
 
-  var f = %CompileString(x, false);
+  var f = %CompileString(x, false, 0);
   if (!IS_FUNCTION(f)) return f;
 
   return %_CallFunction(global_proxy, f);
@@ -215,8 +205,9 @@
 // ----------------------------------------------------------------------------
 // Object
 
+var DefaultObjectToString = NoSideEffectsObjectToString;
 // ECMA-262 - 15.2.4.2
-function ObjectToString() {
+function NoSideEffectsObjectToString() {
   if (IS_UNDEFINED(this) && !IS_UNDETECTABLE(this)) return "[object Undefined]";
   if (IS_NULL(this)) return "[object Null]";
   return "[object " + %_ClassOf(ToObject(this)) + "]";
@@ -238,7 +229,7 @@
 
 // ECMA-262 - 15.2.4.5
 function ObjectHasOwnProperty(V) {
-  if (%IsJSProxy(this)) {
+  if (%_IsJSProxy(this)) {
     // TODO(rossberg): adjust once there is a story for symbols vs proxies.
     if (IS_SYMBOL(V)) return false;
 
@@ -251,8 +242,8 @@
 
 // ECMA-262 - 15.2.4.6
 function ObjectIsPrototypeOf(V) {
-  CHECK_OBJECT_COERCIBLE(this, "Object.prototype.isPrototypeOf");
   if (!IS_SPEC_OBJECT(V)) return false;
+  CHECK_OBJECT_COERCIBLE(this, "Object.prototype.isPrototypeOf");
   return %IsInPrototypeChain(this, V);
 }
 
@@ -260,7 +251,7 @@
 // ECMA-262 - 15.2.4.6
 function ObjectPropertyIsEnumerable(V) {
   var P = ToName(V);
-  if (%IsJSProxy(this)) {
+  if (%_IsJSProxy(this)) {
     // TODO(rossberg): adjust once there is a story for symbols vs proxies.
     if (IS_SYMBOL(V)) return false;
 
@@ -325,10 +316,8 @@
 
 
 function ObjectKeys(obj) {
-  if (!IS_SPEC_OBJECT(obj)) {
-    throw MakeTypeError("called_on_non_object", ["Object.keys"]);
-  }
-  if (%IsJSProxy(obj)) {
+  obj = ToObject(obj);
+  if (%_IsJSProxy(obj)) {
     var handler = %GetHandler(obj);
     var names = CallTrap0(handler, "keys", DerivedKeysTrap);
     return ToNameArray(names, "keys", false);
@@ -502,67 +491,68 @@
     "set_",
     "hasSetter_"
   ), $Array(
-    "toString", function() {
+    "toString", function PropertyDescriptor_ToString() {
       return "[object PropertyDescriptor]";
     },
-    "setValue", function(value) {
+    "setValue", function PropertyDescriptor_SetValue(value) {
       this.value_ = value;
       this.hasValue_ = true;
     },
-    "getValue", function() {
+    "getValue", function PropertyDescriptor_GetValue() {
       return this.value_;
     },
-    "hasValue", function() {
+    "hasValue", function PropertyDescriptor_HasValue() {
       return this.hasValue_;
     },
-    "setEnumerable", function(enumerable) {
+    "setEnumerable", function PropertyDescriptor_SetEnumerable(enumerable) {
       this.enumerable_ = enumerable;
         this.hasEnumerable_ = true;
     },
-    "isEnumerable", function () {
+    "isEnumerable", function PropertyDescriptor_IsEnumerable() {
       return this.enumerable_;
     },
-    "hasEnumerable", function() {
+    "hasEnumerable", function PropertyDescriptor_HasEnumerable() {
       return this.hasEnumerable_;
     },
-    "setWritable", function(writable) {
+    "setWritable", function PropertyDescriptor_SetWritable(writable) {
       this.writable_ = writable;
       this.hasWritable_ = true;
     },
-    "isWritable", function() {
+    "isWritable", function PropertyDescriptor_IsWritable() {
       return this.writable_;
     },
-    "hasWritable", function() {
+    "hasWritable", function PropertyDescriptor_HasWritable() {
       return this.hasWritable_;
     },
-    "setConfigurable", function(configurable) {
+    "setConfigurable",
+    function PropertyDescriptor_SetConfigurable(configurable) {
       this.configurable_ = configurable;
       this.hasConfigurable_ = true;
     },
-    "hasConfigurable", function() {
+    "hasConfigurable", function PropertyDescriptor_HasConfigurable() {
       return this.hasConfigurable_;
     },
-    "isConfigurable", function() {
+    "isConfigurable", function PropertyDescriptor_IsConfigurable() {
       return this.configurable_;
     },
-    "setGet", function(get) {
+    "setGet", function PropertyDescriptor_SetGetter(get) {
       this.get_ = get;
-        this.hasGetter_ = true;
+      this.hasGetter_ = true;
     },
-    "getGet", function() {
+    "getGet", function PropertyDescriptor_GetGetter() {
       return this.get_;
     },
-    "hasGetter", function() {
+    "hasGetter", function PropertyDescriptor_HasGetter() {
       return this.hasGetter_;
     },
-    "setSet", function(set) {
+    "setSet", function PropertyDescriptor_SetSetter(set) {
       this.set_ = set;
       this.hasSetter_ = true;
     },
-    "getSet", function() {
+    "getSet", function PropertyDescriptor_GetSetter() {
       return this.set_;
     },
-    "hasSetter", function() {
+    "hasSetter", function PropertyDescriptor_HasSetter() {
       return this.hasSetter_;
   }));
 
@@ -624,7 +614,7 @@
 // ES5 section 8.12.1.
 function GetOwnPropertyJS(obj, v) {
   var p = ToName(v);
-  if (%IsJSProxy(obj)) {
+  if (%_IsJSProxy(obj)) {
     // TODO(rossberg): adjust once there is a story for symbols vs proxies.
     if (IS_SYMBOL(v)) return UNDEFINED;
 
@@ -897,15 +887,6 @@
         break;
       }
     }
-    // Make sure the below call to DefineObjectProperty() doesn't overwrite
-    // any magic "length" property by removing the value.
-    // TODO(mstarzinger): This hack should be removed once we have addressed the
-    // respective TODO in Runtime_DefineDataPropertyUnchecked.
-    // For the time being, we need a hack to prevent Object.observe from
-    // generating two change records.
-    obj.length = new_length;
-    desc.value_ = UNDEFINED;
-    desc.hasValue_ = false;
     threw = !DefineObjectProperty(obj, "length", desc, should_throw) || threw;
     if (emit_splice) {
       EndPerformSplice(obj);
@@ -964,7 +945,7 @@
 
 // ES5 section 8.12.9, ES5 section 15.4.5.1 and Harmony proxies.
 function DefineOwnProperty(obj, p, desc, should_throw) {
-  if (%IsJSProxy(obj)) {
+  if (%_IsJSProxy(obj)) {
     // TODO(rossberg): adjust once there is a story for symbols vs proxies.
     if (IS_SYMBOL(p)) return false;
 
@@ -983,7 +964,7 @@
   if (!IS_SPEC_OBJECT(obj)) {
     throw MakeTypeError("called_on_non_object", ["Object.getPrototypeOf"]);
   }
-  return %GetPrototype(obj);
+  return %_GetPrototype(obj);
 }
 
 // ES6 section 19.1.2.19.
@@ -1038,24 +1019,21 @@
 }
 
 
-function ObjectGetOwnPropertyKeys(obj, symbolsOnly) {
+function ObjectGetOwnPropertyKeys(obj, filter) {
   var nameArrays = new InternalArray();
-  var filter = symbolsOnly ?
-      PROPERTY_ATTRIBUTES_STRING | PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL :
-      PROPERTY_ATTRIBUTES_SYMBOLIC;
+  filter |= PROPERTY_ATTRIBUTES_PRIVATE_SYMBOL;
+  var interceptorInfo = %GetInterceptorInfo(obj);
 
   // Find all the indexed properties.
 
   // Only get own element names if we want to include string keys.
-  if (!symbolsOnly) {
+  if ((filter & PROPERTY_ATTRIBUTES_STRING) === 0) {
     var ownElementNames = %GetOwnElementNames(obj);
     for (var i = 0; i < ownElementNames.length; ++i) {
       ownElementNames[i] = %_NumberToString(ownElementNames[i]);
     }
     nameArrays.push(ownElementNames);
-
     // Get names for indexed interceptor properties.
-    var interceptorInfo = %GetInterceptorInfo(obj);
     if ((interceptorInfo & 1) != 0) {
       var indexedInterceptorNames = %GetIndexedInterceptorElementNames(obj);
       if (!IS_UNDEFINED(indexedInterceptorNames)) {
@@ -1089,10 +1067,12 @@
     var j = 0;
     for (var i = 0; i < propertyNames.length; ++i) {
       var name = propertyNames[i];
-      if (symbolsOnly) {
-        if (!IS_SYMBOL(name) || IS_PRIVATE(name)) continue;
+      if (IS_SYMBOL(name)) {
+        if ((filter & PROPERTY_ATTRIBUTES_SYMBOLIC) || IS_PRIVATE(name)) {
+          continue;
+        }
       } else {
-        if (IS_SYMBOL(name)) continue;
+        if (filter & PROPERTY_ATTRIBUTES_STRING) continue;
         name = ToString(name);
       }
       if (seenKeys[name]) continue;
@@ -1108,17 +1088,15 @@
 
 // ES5 section 15.2.3.4.
 function ObjectGetOwnPropertyNames(obj) {
-  if (!IS_SPEC_OBJECT(obj)) {
-    throw MakeTypeError("called_on_non_object", ["Object.getOwnPropertyNames"]);
-  }
+  obj = ToObject(obj);
   // Special handling for proxies.
-  if (%IsJSProxy(obj)) {
+  if (%_IsJSProxy(obj)) {
     var handler = %GetHandler(obj);
     var names = CallTrap0(handler, "getOwnPropertyNames", UNDEFINED);
     return ToNameArray(names, "getOwnPropertyNames", false);
   }
 
-  return ObjectGetOwnPropertyKeys(obj, false);
+  return ObjectGetOwnPropertyKeys(obj, PROPERTY_ATTRIBUTES_SYMBOLIC);
 }
 
 
@@ -1140,7 +1118,7 @@
     throw MakeTypeError("called_on_non_object", ["Object.defineProperty"]);
   }
   var name = ToName(p);
-  if (%IsJSProxy(obj)) {
+  if (%_IsJSProxy(obj)) {
     // Clone the attributes object for protection.
     // TODO(rossberg): not spec'ed yet, so not sure if this should involve
     // non-own properties as it does (or non-enumerable ones, as it doesn't?).
@@ -1245,23 +1223,30 @@
 
 
 // ES5 section 15.2.3.8.
-function ObjectSeal(obj) {
+function ObjectSealJS(obj) {
   if (!IS_SPEC_OBJECT(obj)) {
     throw MakeTypeError("called_on_non_object", ["Object.seal"]);
   }
-  if (%IsJSProxy(obj)) {
-    ProxyFix(obj);
-  }
-  var names = ObjectGetOwnPropertyNames(obj);
-  for (var i = 0; i < names.length; i++) {
-    var name = names[i];
-    var desc = GetOwnPropertyJS(obj, name);
-    if (desc.isConfigurable()) {
-      desc.setConfigurable(false);
-      DefineOwnProperty(obj, name, desc, true);
+  var isProxy = %_IsJSProxy(obj);
+  if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) {
+    if (isProxy) {
+      ProxyFix(obj);
     }
+    var names = ObjectGetOwnPropertyNames(obj);
+    for (var i = 0; i < names.length; i++) {
+      var name = names[i];
+      var desc = GetOwnPropertyJS(obj, name);
+      if (desc.isConfigurable()) {
+        desc.setConfigurable(false);
+        DefineOwnProperty(obj, name, desc, true);
+      }
+    }
+    %PreventExtensions(obj);
+  } else {
+    // TODO(adamk): Is it worth going to this fast path if the
+    // object's properties are already in dictionary mode?
+    %ObjectSeal(obj);
   }
-  %PreventExtensions(obj);
   return obj;
 }
 
@@ -1271,7 +1256,7 @@
   if (!IS_SPEC_OBJECT(obj)) {
     throw MakeTypeError("called_on_non_object", ["Object.freeze"]);
   }
-  var isProxy = %IsJSProxy(obj);
+  var isProxy = %_IsJSProxy(obj);
   if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) {
     if (isProxy) {
       ProxyFix(obj);
@@ -1301,7 +1286,7 @@
   if (!IS_SPEC_OBJECT(obj)) {
     throw MakeTypeError("called_on_non_object", ["Object.preventExtension"]);
   }
-  if (%IsJSProxy(obj)) {
+  if (%_IsJSProxy(obj)) {
     ProxyFix(obj);
   }
   %PreventExtensions(obj);
@@ -1314,7 +1299,7 @@
   if (!IS_SPEC_OBJECT(obj)) {
     throw MakeTypeError("called_on_non_object", ["Object.isSealed"]);
   }
-  if (%IsJSProxy(obj)) {
+  if (%_IsJSProxy(obj)) {
     return false;
   }
   if (%IsExtensible(obj)) {
@@ -1337,7 +1322,7 @@
   if (!IS_SPEC_OBJECT(obj)) {
     throw MakeTypeError("called_on_non_object", ["Object.isFrozen"]);
   }
-  if (%IsJSProxy(obj)) {
+  if (%_IsJSProxy(obj)) {
     return false;
   }
   if (%IsExtensible(obj)) {
@@ -1359,26 +1344,22 @@
   if (!IS_SPEC_OBJECT(obj)) {
     throw MakeTypeError("called_on_non_object", ["Object.isExtensible"]);
   }
-  if (%IsJSProxy(obj)) {
+  if (%_IsJSProxy(obj)) {
     return true;
   }
   return %IsExtensible(obj);
 }
 
 
-// Harmony egal.
+// ECMA-262, Edition 6, section 19.1.2.10
 function ObjectIs(obj1, obj2) {
-  if (obj1 === obj2) {
-    return (obj1 !== 0) || (1 / obj1 === 1 / obj2);
-  } else {
-    return (obj1 !== obj1) && (obj2 !== obj2);
-  }
+  return SameValue(obj1, obj2);
 }
 
 
 // ECMA-262, Edition 6, section B.2.2.1.1
 function ObjectGetProto() {
-  return %GetPrototype(ToObject(this));
+  return %_GetPrototype(ToObject(this));
 }
 
 
@@ -1416,7 +1397,7 @@
 
   // Set up non-enumerable functions on the Object.prototype object.
   InstallFunctions($Object.prototype, DONT_ENUM, $Array(
-    "toString", ObjectToString,
+    "toString", NoSideEffectsObjectToString,
     "toLocaleString", ObjectToLocaleString,
     "valueOf", ObjectValueOf,
     "hasOwnProperty", ObjectHasOwnProperty,
@@ -1447,7 +1428,7 @@
     "isFrozen", ObjectIsFrozen,
     "isSealed", ObjectIsSealed,
     "preventExtensions", ObjectPreventExtension,
-    "seal", ObjectSeal
+    "seal", ObjectSealJS
     // deliverChangeRecords, getNotifier, observe and unobserve are added
     // in object-observe.js.
   ));
@@ -1739,6 +1720,11 @@
     throw new $TypeError('Function.prototype.toString is not generic');
   }
 
+  var classSource = %ClassGetSourceCode(func);
+  if (IS_STRING(classSource)) {
+    return classSource;
+  }
+
   var source = %FunctionGetSourceCode(func);
   if (!IS_STRING(source) || %FunctionIsBuiltin(func)) {
     var name = %FunctionGetName(func);
@@ -1830,7 +1816,7 @@
 }
 
 
-function NewFunctionString(arguments, function_token) {
+function NewFunctionFromString(arguments, function_token) {
   var n = arguments.length;
   var p = '';
   if (n > 1) {
@@ -1847,21 +1833,20 @@
     // If the formal parameters include an unbalanced block comment, the
     // function must be rejected. Since JavaScript does not allow nested
     // comments we can include a trailing block comment to catch this.
-    p += '\n/' + '**/';
+    p += '\n\x2f**\x2f';
   }
   var body = (n > 0) ? ToString(arguments[n - 1]) : '';
-  return '(' + function_token + '(' + p + ') {\n' + body + '\n})';
+  var head = '(' + function_token + '(' + p + ') {\n';
+  var src = head + body + '\n})';
+  var global_proxy = %GlobalProxy(global);
+  var f = %_CallFunction(global_proxy, %CompileString(src, true, head.length));
+  %FunctionMarkNameShouldPrintAsAnonymous(f);
+  return f;
 }
 
 
 function FunctionConstructor(arg1) {  // length == 1
-  var source = NewFunctionString(arguments, 'function');
-  var global_proxy = %GlobalProxy(global);
-  // Compile the string in the constructor and not a helper so that errors
-  // appear to come from here.
-  var f = %_CallFunction(global_proxy, %CompileString(source, true));
-  %FunctionMarkNameShouldPrintAsAnonymous(f);
-  return f;
+  return NewFunctionFromString(arguments, 'function');
 }
 
 
diff --git a/src/v8threads.cc b/src/v8threads.cc
index a46b289..e2d9d49 100644
--- a/src/v8threads.cc
+++ b/src/v8threads.cc
@@ -14,34 +14,29 @@
 namespace v8 {
 
 
+namespace {
+
 // Track whether this V8 instance has ever called v8::Locker. This allows the
 // API code to verify that the lock is always held when V8 is being entered.
-bool Locker::active_ = false;
+base::Atomic32 g_locker_was_ever_used_ = 0;
+
+}  // namespace
 
 
 // Once the Locker is initialized, the current thread will be guaranteed to have
 // the lock for a given isolate.
 void Locker::Initialize(v8::Isolate* isolate) {
   DCHECK(isolate != NULL);
-  has_lock_= false;
+  has_lock_ = false;
   top_level_ = true;
   isolate_ = reinterpret_cast<i::Isolate*>(isolate);
   // Record that the Locker has been used at least once.
-  active_ = true;
+  base::NoBarrier_Store(&g_locker_was_ever_used_, 1);
   // Get the big lock if necessary.
   if (!isolate_->thread_manager()->IsLockedByCurrentThread()) {
     isolate_->thread_manager()->Lock();
     has_lock_ = true;
 
-    // Make sure that V8 is initialized.  Archiving of threads interferes
-    // with deserialization by adding additional root pointers, so we must
-    // initialize here, before anyone can call ~Locker() or Unlocker().
-    if (!isolate_->IsInitialized()) {
-      isolate_->Enter();
-      V8::Initialize();
-      isolate_->Exit();
-    }
-
     // This may be a locker within an unlocker in which case we have to
     // get the saved state for this thread and restore it.
     if (isolate_->thread_manager()->RestoreThread()) {
@@ -64,7 +59,7 @@
 
 
 bool Locker::IsActive() {
-  return active_;
+  return !!base::NoBarrier_Load(&g_locker_was_ever_used_);
 }
 
 
diff --git a/src/variables.cc b/src/variables.cc
index 6588312..3b1559d 100644
--- a/src/variables.cc
+++ b/src/variables.cc
@@ -60,7 +60,7 @@
   // activation frame.
   return (IsDynamicVariableMode(mode_) ||
           (IsDeclaredVariableMode(mode_) && !IsLexicalVariableMode(mode_)))
-      && scope_ != NULL && scope_->is_global_scope();
+      && scope_ != NULL && scope_->is_script_scope();
 }
 
 
diff --git a/src/variables.h b/src/variables.h
index a8cf5e3..93bfb4a 100644
--- a/src/variables.h
+++ b/src/variables.h
@@ -64,7 +64,7 @@
 
   // The source code for an eval() call may refer to a variable that is
   // in an outer scope about which we don't know anything (it may not
-  // be the global scope). scope() is NULL in that case. Currently the
+  // be the script scope). scope() is NULL in that case. Currently the
   // scope is only used to follow the context chain length.
   Scope* scope() const { return scope_; }
 
diff --git a/src/vector.h b/src/vector.h
index d3ba775..a4fdb10 100644
--- a/src/vector.h
+++ b/src/vector.h
@@ -58,6 +58,10 @@
 
   T& last() { return start_[length_ - 1]; }
 
+  typedef T* iterator;
+  inline iterator begin() const { return &start_[0]; }
+  inline iterator end() const { return &start_[length_]; }
+
   // Returns a clone of this vector with a new backing store.
   Vector<T> Clone() const {
     T* result = NewArray<T>(length_);
diff --git a/src/version.cc b/src/version.cc
index 0502ba1..edcf2be 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -32,10 +32,10 @@
 // These macros define the version number for the current version.
 // NOTE these macros are used by some of the tool scripts and the build
 // system so their names cannot be changed without changing the scripts.
-#define MAJOR_VERSION     3
-#define MINOR_VERSION     29
-#define BUILD_NUMBER      88
-#define PATCH_LEVEL       18
+#define MAJOR_VERSION     4
+#define MINOR_VERSION     1
+#define BUILD_NUMBER      0
+#define PATCH_LEVEL       21
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
diff --git a/src/version.h b/src/version.h
index 4f60005..dbcec1b 100644
--- a/src/version.h
+++ b/src/version.h
@@ -5,6 +5,8 @@
 #ifndef V8_VERSION_H_
 #define V8_VERSION_H_
 
+#include "src/base/functional.h"
+
 namespace v8 {
 namespace internal {
 
@@ -16,7 +18,10 @@
   static int GetBuild() { return build_; }
   static int GetPatch() { return patch_; }
   static bool IsCandidate() { return candidate_; }
-  static int Hash() { return (major_ << 20) ^ (minor_ << 10) ^ patch_; }
+  static uint32_t Hash() {
+    return static_cast<uint32_t>(
+        base::hash_combine(major_, minor_, build_, patch_));
+  }
 
   // Calculate the V8 version string.
   static void GetString(Vector<char> str);
diff --git a/src/vm-state.h b/src/vm-state.h
index a72180c..9838b87 100644
--- a/src/vm-state.h
+++ b/src/vm-state.h
@@ -11,6 +11,11 @@
 namespace v8 {
 namespace internal {
 
+// Logging and profiling.  A StateTag represents a possible state of
+// the VM. The logger maintains a stack of these. Creating a VMState
+// object enters a state by pushing on the stack, and destroying a
+// VMState object leaves a state by popping the current state from the
+// stack.
 template <StateTag Tag>
 class VMState BASE_EMBEDDED {
  public:
diff --git a/src/weak-collection.js b/src/weak-collection.js
index 1160176..a44c3d7 100644
--- a/src/weak-collection.js
+++ b/src/weak-collection.js
@@ -96,16 +96,6 @@
 }
 
 
-function WeakMapClear() {
-  if (!IS_WEAKMAP(this)) {
-    throw MakeTypeError('incompatible_method_receiver',
-                        ['WeakMap.prototype.clear', this]);
-  }
-  // Replace the internal table with a new empty table.
-  %WeakCollectionInitialize(this);
-}
-
-
 // -------------------------------------------------------------------
 
 function SetUpWeakMap() {
@@ -114,14 +104,15 @@
   %SetCode($WeakMap, WeakMapConstructor);
   %FunctionSetPrototype($WeakMap, new $Object());
   %AddNamedProperty($WeakMap.prototype, "constructor", $WeakMap, DONT_ENUM);
+  %AddNamedProperty(
+      $WeakMap.prototype, symbolToStringTag, "WeakMap", DONT_ENUM | READ_ONLY);
 
   // Set up the non-enumerable functions on the WeakMap prototype object.
   InstallFunctions($WeakMap.prototype, DONT_ENUM, $Array(
     "get", WeakMapGet,
     "set", WeakMapSet,
     "has", WeakMapHas,
-    "delete", WeakMapDelete,
-    "clear", WeakMapClear
+    "delete", WeakMapDelete
   ));
 }
 
@@ -196,16 +187,6 @@
 }
 
 
-function WeakSetClear() {
-  if (!IS_WEAKSET(this)) {
-    throw MakeTypeError('incompatible_method_receiver',
-                        ['WeakSet.prototype.clear', this]);
-  }
-  // Replace the internal table with a new empty table.
-  %WeakCollectionInitialize(this);
-}
-
-
 // -------------------------------------------------------------------
 
 function SetUpWeakSet() {
@@ -214,13 +195,14 @@
   %SetCode($WeakSet, WeakSetConstructor);
   %FunctionSetPrototype($WeakSet, new $Object());
   %AddNamedProperty($WeakSet.prototype, "constructor", $WeakSet, DONT_ENUM);
+  %AddNamedProperty(
+      $WeakSet.prototype, symbolToStringTag, "WeakSet", DONT_ENUM | READ_ONLY);
 
   // Set up the non-enumerable functions on the WeakSet prototype object.
   InstallFunctions($WeakSet.prototype, DONT_ENUM, $Array(
     "add", WeakSetAdd,
     "has", WeakSetHas,
-    "delete", WeakSetDelete,
-    "clear", WeakSetClear
+    "delete", WeakSetDelete
   ));
 }
 
diff --git a/src/x64/assembler-x64-inl.h b/src/x64/assembler-x64-inl.h
index b64bbfb..caf7af6 100644
--- a/src/x64/assembler-x64-inl.h
+++ b/src/x64/assembler-x64-inl.h
@@ -179,11 +179,75 @@
 }
 
 
+void Assembler::emit_optional_rex_32(XMMRegister rm_reg) {
+  if (rm_reg.high_bit()) emit(0x41);
+}
+
+
 void Assembler::emit_optional_rex_32(const Operand& op) {
   if (op.rex_ != 0) emit(0x40 | op.rex_);
 }
 
 
+// byte 1 of 3-byte VEX
+void Assembler::emit_vex3_byte1(XMMRegister reg, XMMRegister rm,
+                                LeadingOpcode m) {
+  byte rxb = ~((reg.high_bit() << 2) | rm.high_bit()) << 5;
+  emit(rxb | m);
+}
+
+
+// byte 1 of 3-byte VEX
+void Assembler::emit_vex3_byte1(XMMRegister reg, const Operand& rm,
+                                LeadingOpcode m) {
+  byte rxb = ~((reg.high_bit() << 2) | rm.rex_) << 5;
+  emit(rxb | m);
+}
+
+
+// byte 1 of 2-byte VEX
+void Assembler::emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l,
+                                SIMDPrefix pp) {
+  byte rv = ~((reg.high_bit() << 4) | v.code()) << 3;
+  emit(rv | l | pp);
+}
+
+
+// byte 2 of 3-byte VEX
+void Assembler::emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l,
+                                SIMDPrefix pp) {
+  emit(w | ((~v.code() & 0xf) << 3) | l | pp);
+}
+
+
+void Assembler::emit_vex_prefix(XMMRegister reg, XMMRegister vreg,
+                                XMMRegister rm, VectorLength l, SIMDPrefix pp,
+                                LeadingOpcode mm, VexW w) {
+  if (rm.high_bit() || mm != k0F || w != kW0) {
+    emit_vex3_byte0();
+    emit_vex3_byte1(reg, rm, mm);
+    emit_vex3_byte2(w, vreg, l, pp);
+  } else {
+    emit_vex2_byte0();
+    emit_vex2_byte1(reg, vreg, l, pp);
+  }
+}
+
+
+void Assembler::emit_vex_prefix(XMMRegister reg, XMMRegister vreg,
+                                const Operand& rm, VectorLength l,
+                                SIMDPrefix pp, LeadingOpcode mm, VexW w) {
+  if (rm.rex_ || mm != k0F || w != kW0) {
+    emit_vex3_byte0();
+    emit_vex3_byte1(reg, rm, mm);
+    emit_vex3_byte2(w, vreg, l, pp);
+  } else {
+    emit_vex2_byte0();
+    emit_vex2_byte1(reg, vreg, l, pp);
+  }
+}
+
+
 Address Assembler::target_address_at(Address pc,
                                      ConstantPoolArray* constant_pool) {
   return Memory::int32_at(pc) + pc + 4;
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 4f8d5b1..fd722b2 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -2,13 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
+#include "src/x64/assembler-x64.h"
+
+#if V8_OS_MACOSX
+#include <sys/sysctl.h>
+#endif
 
 #if V8_TARGET_ARCH_X64
 
 #include "src/base/bits.h"
 #include "src/macro-assembler.h"
-#include "src/serialize.h"
+#include "src/v8.h"
 
 namespace v8 {
 namespace internal {
@@ -16,6 +20,29 @@
 // -----------------------------------------------------------------------------
 // Implementation of CpuFeatures
 
+namespace {
+
+bool EnableAVX() {
+#if V8_OS_MACOSX
+  // Mac OS X 10.9 has a bug where AVX transitions were indeed being caused by
+  // ISRs, so we detect Mac OS X 10.9 here and disable AVX in that case.
+  char buffer[128];
+  size_t buffer_size = arraysize(buffer);
+  int ctl_name[] = { CTL_KERN , KERN_OSRELEASE };
+  if (sysctl(ctl_name, 2, buffer, &buffer_size, nullptr, 0) != 0) {
+    V8_Fatal(__FILE__, __LINE__, "V8 failed to get kernel version");
+  }
+  // The buffer now contains a string of the form XX.YY.ZZ, where
+  // XX is the major kernel version component. 13.x.x (Mavericks) is
+  // affected by this bug, so disable AVX there.
+  if (memcmp(buffer, "13.", 3) == 0) return false;
+#endif  // V8_OS_MACOSX
+  return FLAG_enable_avx;
+}
+
+}  // namespace
+
+
 void CpuFeatures::ProbeImpl(bool cross_compile) {
   base::CPU cpu;
   CHECK(cpu.has_sse2());  // SSE2 support is mandatory.
@@ -27,12 +54,19 @@
   if (cpu.has_sse41() && FLAG_enable_sse4_1) supported_ |= 1u << SSE4_1;
   if (cpu.has_sse3() && FLAG_enable_sse3) supported_ |= 1u << SSE3;
   // SAHF is not generally available in long mode.
-  if (cpu.has_sahf() && FLAG_enable_sahf) supported_|= 1u << SAHF;
+  if (cpu.has_sahf() && FLAG_enable_sahf) supported_ |= 1u << SAHF;
+  if (cpu.has_avx() && EnableAVX()) supported_ |= 1u << AVX;
+  if (cpu.has_fma3() && FLAG_enable_fma3) supported_ |= 1u << FMA3;
 }
 
 
 void CpuFeatures::PrintTarget() { }
-void CpuFeatures::PrintFeatures() { }
+void CpuFeatures::PrintFeatures() {
+  printf("SSE3=%d SSE4_1=%d SAHF=%d AVX=%d FMA3=%d\n",
+         CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSE4_1),
+         CpuFeatures::IsSupported(SAHF), CpuFeatures::IsSupported(AVX),
+         CpuFeatures::IsSupported(FMA3));
+}
 
 
 // -----------------------------------------------------------------------------
@@ -617,6 +651,24 @@
 }
 
 
+void Assembler::shift(Operand dst, Immediate shift_amount, int subcode,
+                      int size) {
+  EnsureSpace ensure_space(this);
+  DCHECK(size == kInt64Size ? is_uint6(shift_amount.value_)
+                            : is_uint5(shift_amount.value_));
+  if (shift_amount.value_ == 1) {
+    emit_rex(dst, size);
+    emit(0xD1);
+    emit_operand(subcode, dst);
+  } else {
+    emit_rex(dst, size);
+    emit(0xC1);
+    emit_operand(subcode, dst);
+    emit(shift_amount.value_);
+  }
+}
+
+
 void Assembler::shift(Register dst, int subcode, int size) {
   EnsureSpace ensure_space(this);
   emit_rex(dst, size);
@@ -625,6 +677,14 @@
 }
 
 
+void Assembler::shift(Operand dst, int subcode, int size) {
+  EnsureSpace ensure_space(this);
+  emit_rex(dst, size);
+  emit(0xD3);
+  emit_operand(subcode, dst);
+}
+
+
 void Assembler::bt(const Operand& dst, Register src) {
   EnsureSpace ensure_space(this);
   emit_rex_64(src, dst);
@@ -909,6 +969,14 @@
 }
 
 
+void Assembler::emit_imul(const Operand& src, int size) {
+  EnsureSpace ensure_space(this);
+  emit_rex(src, size);
+  emit(0xF7);
+  emit_operand(0x5, src);
+}
+
+
 void Assembler::emit_imul(Register dst, Register src, int size) {
   EnsureSpace ensure_space(this);
   emit_rex(dst, src, size);
@@ -942,6 +1010,22 @@
 }
 
 
+void Assembler::emit_imul(Register dst, const Operand& src, Immediate imm,
+                          int size) {
+  EnsureSpace ensure_space(this);
+  emit_rex(dst, src, size);
+  if (is_int8(imm.value_)) {
+    emit(0x6B);
+    emit_operand(dst, src);
+    emit(imm.value_);
+  } else {
+    emit(0x69);
+    emit_operand(dst, src);
+    emitl(imm.value_);
+  }
+}
+
+
 void Assembler::emit_inc(Register dst, int size) {
   EnsureSpace ensure_space(this);
   emit_rex(dst, size);
@@ -1333,6 +1417,20 @@
 }
 
 
+void Assembler::movsxbl(Register dst, Register src) {
+  EnsureSpace ensure_space(this);
+  if (!src.is_byte_register()) {
+    // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
+    emit_rex_32(dst, src);
+  } else {
+    emit_optional_rex_32(dst, src);
+  }
+  emit(0x0F);
+  emit(0xBE);
+  emit_modrm(dst, src);
+}
+
+
 void Assembler::movsxbl(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   emit_optional_rex_32(dst, src);
@@ -1351,6 +1449,15 @@
 }
 
 
+void Assembler::movsxwl(Register dst, Register src) {
+  EnsureSpace ensure_space(this);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0xBF);
+  emit_modrm(dst, src);
+}
+
+
 void Assembler::movsxwl(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   emit_optional_rex_32(dst, src);
@@ -1457,7 +1564,23 @@
 }
 
 
-void Assembler::mul(Register src) {
+void Assembler::mull(Register src) {
+  EnsureSpace ensure_space(this);
+  emit_optional_rex_32(src);
+  emit(0xF7);
+  emit_modrm(0x4, src);
+}
+
+
+void Assembler::mull(const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit_optional_rex_32(src);
+  emit(0xF7);
+  emit_operand(0x4, src);
+}
+
+
+void Assembler::mulq(Register src) {
   EnsureSpace ensure_space(this);
   emit_rex_64(src);
   emit(0xF7);
@@ -2549,6 +2672,104 @@
 }
 
 
+void Assembler::addss(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF3);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x58);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::addss(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF3);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x58);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::subss(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF3);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5C);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::subss(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF3);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5C);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::mulss(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF3);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x59);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::mulss(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF3);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x59);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::divss(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF3);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5E);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::divss(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF3);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5E);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::ucomiss(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit_optional_rex_32(dst, src);
+  emit(0x0f);
+  emit(0x2e);
+  emit_sse_operand(dst, src);
+}
+
+
+void Assembler::ucomiss(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit_optional_rex_32(dst, src);
+  emit(0x0f);
+  emit(0x2e);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::movss(XMMRegister dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   emit(0xF3);  // single
@@ -2572,6 +2793,7 @@
 void Assembler::psllq(XMMRegister reg, byte imm8) {
   EnsureSpace ensure_space(this);
   emit(0x66);
+  emit_optional_rex_32(reg);
   emit(0x0F);
   emit(0x73);
   emit_sse_operand(rsi, reg);  // rsi == 6
@@ -2579,6 +2801,39 @@
 }
 
 
+void Assembler::psrlq(XMMRegister reg, byte imm8) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(reg);
+  emit(0x0F);
+  emit(0x73);
+  emit_sse_operand(rdx, reg);  // rdx == 2
+  emit(imm8);
+}
+
+
+void Assembler::pslld(XMMRegister reg, byte imm8) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(reg);
+  emit(0x0F);
+  emit(0x72);
+  emit_sse_operand(rsi, reg);  // rsi == 6
+  emit(imm8);
+}
+
+
+void Assembler::psrld(XMMRegister reg, byte imm8) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(reg);
+  emit(0x0F);
+  emit(0x72);
+  emit_sse_operand(rdx, reg);  // rdx == 2
+  emit(imm8);
+}
+
+
 void Assembler::cvttss2si(Register dst, const Operand& src) {
   EnsureSpace ensure_space(this);
   emit(0xF3);
@@ -2669,6 +2924,16 @@
 }
 
 
+void Assembler::cvtqsi2sd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF2);
+  emit_rex_64(dst, src);
+  emit(0x0F);
+  emit(0x2A);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::cvtqsi2sd(XMMRegister dst, Register src) {
   EnsureSpace ensure_space(this);
   emit(0xF2);
@@ -2709,6 +2974,16 @@
 }
 
 
+void Assembler::cvtsd2ss(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF2);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5A);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::cvtsd2si(Register dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
   emit(0xF2);
@@ -2779,6 +3054,16 @@
 }
 
 
+void Assembler::subsd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF2);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5C);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
   emit(0xF2);
@@ -2789,6 +3074,16 @@
 }
 
 
+void Assembler::divsd(XMMRegister dst, const Operand& src) {
+  EnsureSpace ensure_space(this);
+  emit(0xF2);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x5E);
+  emit_sse_operand(dst, src);
+}
+
+
 void Assembler::andpd(XMMRegister dst, XMMRegister src) {
   EnsureSpace ensure_space(this);
   emit(0x66);
@@ -2904,6 +3199,77 @@
 }
 
 
+void Assembler::pcmpeqd(XMMRegister dst, XMMRegister src) {
+  EnsureSpace ensure_space(this);
+  emit(0x66);
+  emit_optional_rex_32(dst, src);
+  emit(0x0F);
+  emit(0x76);
+  emit_sse_operand(dst, src);
+}
+
+
+// AVX instructions
+void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
+                       XMMRegister src2) {
+  DCHECK(IsEnabled(FMA3));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW1);
+  emit(op);
+  emit_sse_operand(dst, src2);
+}
+
+
+void Assembler::vfmasd(byte op, XMMRegister dst, XMMRegister src1,
+                       const Operand& src2) {
+  DCHECK(IsEnabled(FMA3));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW1);
+  emit(op);
+  emit_sse_operand(dst, src2);
+}
+
+
+void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
+                       XMMRegister src2) {
+  DCHECK(IsEnabled(FMA3));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW0);
+  emit(op);
+  emit_sse_operand(dst, src2);
+}
+
+
+void Assembler::vfmass(byte op, XMMRegister dst, XMMRegister src1,
+                       const Operand& src2) {
+  DCHECK(IsEnabled(FMA3));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(dst, src1, src2, kLIG, k66, k0F38, kW0);
+  emit(op);
+  emit_sse_operand(dst, src2);
+}
+
+
+void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1,
+                    XMMRegister src2) {
+  DCHECK(IsEnabled(AVX));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(dst, src1, src2, kLIG, kF2, k0F, kWIG);
+  emit(op);
+  emit_sse_operand(dst, src2);
+}
+
+
+void Assembler::vsd(byte op, XMMRegister dst, XMMRegister src1,
+                    const Operand& src2) {
+  DCHECK(IsEnabled(AVX));
+  EnsureSpace ensure_space(this);
+  emit_vex_prefix(dst, src1, src2, kLIG, kF2, k0F, kWIG);
+  emit(op);
+  emit_sse_operand(dst, src2);
+}
+
+
 void Assembler::emit_sse_operand(XMMRegister reg, const Operand& adr) {
   Register ireg = { reg.code() };
   emit_operand(ireg, adr);
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index b2a97cc..2ebae3b 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -200,6 +200,11 @@
     return kMaxNumAllocatableRegisters;
   }
 
+  // TODO(turbofan): Proper support for float32.
+  static int NumAllocatableAliasedRegisters() {
+    return NumAllocatableRegisters();
+  }
+
   static int ToAllocationIndex(XMMRegister reg) {
     DCHECK(reg.code() != 0);
     return reg.code() - 1;
@@ -726,8 +731,10 @@
   void movq(Register dst, int64_t value);
   void movq(Register dst, uint64_t value);
 
+  void movsxbl(Register dst, Register src);
   void movsxbl(Register dst, const Operand& src);
   void movsxbq(Register dst, const Operand& src);
+  void movsxwl(Register dst, Register src);
   void movsxwl(Register dst, const Operand& src);
   void movsxwq(Register dst, const Operand& src);
   void movsxlq(Register dst, Register src);
@@ -805,33 +812,48 @@
   // Sign-extends eax into edx:eax.
   void cdq();
 
+  // Multiply eax by src, put the result in edx:eax.
+  void mull(Register src);
+  void mull(const Operand& src);
   // Multiply rax by src, put the result in rdx:rax.
-  void mul(Register src);
+  void mulq(Register src);
 
-#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode)     \
-  void instruction##p(Register dst, Immediate imm8) {       \
-    shift(dst, imm8, subcode, kPointerSize);                \
-  }                                                         \
-                                                            \
-  void instruction##l(Register dst, Immediate imm8) {       \
-    shift(dst, imm8, subcode, kInt32Size);                  \
-  }                                                         \
-                                                            \
-  void instruction##q(Register dst, Immediate imm8) {       \
-    shift(dst, imm8, subcode, kInt64Size);                  \
-  }                                                         \
-                                                            \
-  void instruction##p_cl(Register dst) {                    \
-    shift(dst, subcode, kPointerSize);                      \
-  }                                                         \
-                                                            \
-  void instruction##l_cl(Register dst) {                    \
-    shift(dst, subcode, kInt32Size);                        \
-  }                                                         \
-                                                            \
-  void instruction##q_cl(Register dst) {                    \
-    shift(dst, subcode, kInt64Size);                        \
-  }
+#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode)                       \
+  void instruction##p(Register dst, Immediate imm8) {                         \
+    shift(dst, imm8, subcode, kPointerSize);                                  \
+  }                                                                           \
+                                                                              \
+  void instruction##l(Register dst, Immediate imm8) {                         \
+    shift(dst, imm8, subcode, kInt32Size);                                    \
+  }                                                                           \
+                                                                              \
+  void instruction##q(Register dst, Immediate imm8) {                         \
+    shift(dst, imm8, subcode, kInt64Size);                                    \
+  }                                                                           \
+                                                                              \
+  void instruction##p(Operand dst, Immediate imm8) {                          \
+    shift(dst, imm8, subcode, kPointerSize);                                  \
+  }                                                                           \
+                                                                              \
+  void instruction##l(Operand dst, Immediate imm8) {                          \
+    shift(dst, imm8, subcode, kInt32Size);                                    \
+  }                                                                           \
+                                                                              \
+  void instruction##q(Operand dst, Immediate imm8) {                          \
+    shift(dst, imm8, subcode, kInt64Size);                                    \
+  }                                                                           \
+                                                                              \
+  void instruction##p_cl(Register dst) { shift(dst, subcode, kPointerSize); } \
+                                                                              \
+  void instruction##l_cl(Register dst) { shift(dst, subcode, kInt32Size); }   \
+                                                                              \
+  void instruction##q_cl(Register dst) { shift(dst, subcode, kInt64Size); }   \
+                                                                              \
+  void instruction##p_cl(Operand dst) { shift(dst, subcode, kPointerSize); }  \
+                                                                              \
+  void instruction##l_cl(Operand dst) { shift(dst, subcode, kInt32Size); }    \
+                                                                              \
+  void instruction##q_cl(Operand dst) { shift(dst, subcode, kInt64Size); }
   SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION)
 #undef DECLARE_SHIFT_INSTRUCTION
 
@@ -992,6 +1014,17 @@
   void sahf();
 
   // SSE instructions
+  void addss(XMMRegister dst, XMMRegister src);
+  void addss(XMMRegister dst, const Operand& src);
+  void subss(XMMRegister dst, XMMRegister src);
+  void subss(XMMRegister dst, const Operand& src);
+  void mulss(XMMRegister dst, XMMRegister src);
+  void mulss(XMMRegister dst, const Operand& src);
+  void divss(XMMRegister dst, XMMRegister src);
+  void divss(XMMRegister dst, const Operand& src);
+
+  void ucomiss(XMMRegister dst, XMMRegister src);
+  void ucomiss(XMMRegister dst, const Operand& src);
   void movaps(XMMRegister dst, XMMRegister src);
   void movss(XMMRegister dst, const Operand& src);
   void movss(const Operand& dst, XMMRegister src);
@@ -1044,6 +1077,9 @@
   void movapd(XMMRegister dst, XMMRegister src);
 
   void psllq(XMMRegister reg, byte imm8);
+  void psrlq(XMMRegister reg, byte imm8);
+  void pslld(XMMRegister reg, byte imm8);
+  void psrld(XMMRegister reg, byte imm8);
 
   void cvttsd2si(Register dst, const Operand& src);
   void cvttsd2si(Register dst, XMMRegister src);
@@ -1059,6 +1095,7 @@
   void cvtss2sd(XMMRegister dst, XMMRegister src);
   void cvtss2sd(XMMRegister dst, const Operand& src);
   void cvtsd2ss(XMMRegister dst, XMMRegister src);
+  void cvtsd2ss(XMMRegister dst, const Operand& src);
 
   void cvtsd2si(Register dst, XMMRegister src);
   void cvtsd2siq(Register dst, XMMRegister src);
@@ -1066,9 +1103,11 @@
   void addsd(XMMRegister dst, XMMRegister src);
   void addsd(XMMRegister dst, const Operand& src);
   void subsd(XMMRegister dst, XMMRegister src);
+  void subsd(XMMRegister dst, const Operand& src);
   void mulsd(XMMRegister dst, XMMRegister src);
   void mulsd(XMMRegister dst, const Operand& src);
   void divsd(XMMRegister dst, XMMRegister src);
+  void divsd(XMMRegister dst, const Operand& src);
 
   void andpd(XMMRegister dst, XMMRegister src);
   void orpd(XMMRegister dst, XMMRegister src);
@@ -1079,6 +1118,7 @@
   void ucomisd(XMMRegister dst, XMMRegister src);
   void ucomisd(XMMRegister dst, const Operand& src);
   void cmpltsd(XMMRegister dst, XMMRegister src);
+  void pcmpeqd(XMMRegister dst, XMMRegister src);
 
   void movmskpd(Register dst, XMMRegister src);
 
@@ -1094,6 +1134,184 @@
 
   void roundsd(XMMRegister dst, XMMRegister src, RoundingMode mode);
 
+  // AVX instruction
+  void vfmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmasd(0x99, dst, src1, src2);
+  }
+  void vfmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmasd(0xa9, dst, src1, src2);
+  }
+  void vfmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmasd(0xb9, dst, src1, src2);
+  }
+  void vfmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0x99, dst, src1, src2);
+  }
+  void vfmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xa9, dst, src1, src2);
+  }
+  void vfmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xb9, dst, src1, src2);
+  }
+  void vfmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmasd(0x9b, dst, src1, src2);
+  }
+  void vfmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmasd(0xab, dst, src1, src2);
+  }
+  void vfmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmasd(0xbb, dst, src1, src2);
+  }
+  void vfmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0x9b, dst, src1, src2);
+  }
+  void vfmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xab, dst, src1, src2);
+  }
+  void vfmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xbb, dst, src1, src2);
+  }
+  void vfnmadd132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmasd(0x9d, dst, src1, src2);
+  }
+  void vfnmadd213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmasd(0xad, dst, src1, src2);
+  }
+  void vfnmadd231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmasd(0xbd, dst, src1, src2);
+  }
+  void vfnmadd132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0x9d, dst, src1, src2);
+  }
+  void vfnmadd213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xad, dst, src1, src2);
+  }
+  void vfnmadd231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xbd, dst, src1, src2);
+  }
+  void vfnmsub132sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmasd(0x9f, dst, src1, src2);
+  }
+  void vfnmsub213sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmasd(0xaf, dst, src1, src2);
+  }
+  void vfnmsub231sd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmasd(0xbf, dst, src1, src2);
+  }
+  void vfnmsub132sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0x9f, dst, src1, src2);
+  }
+  void vfnmsub213sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xaf, dst, src1, src2);
+  }
+  void vfnmsub231sd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmasd(0xbf, dst, src1, src2);
+  }
+  void vfmasd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
+  void vfmasd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
+
+  void vfmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmass(0x99, dst, src1, src2);
+  }
+  void vfmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmass(0xa9, dst, src1, src2);
+  }
+  void vfmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmass(0xb9, dst, src1, src2);
+  }
+  void vfmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0x99, dst, src1, src2);
+  }
+  void vfmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xa9, dst, src1, src2);
+  }
+  void vfmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xb9, dst, src1, src2);
+  }
+  void vfmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmass(0x9b, dst, src1, src2);
+  }
+  void vfmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmass(0xab, dst, src1, src2);
+  }
+  void vfmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmass(0xbb, dst, src1, src2);
+  }
+  void vfmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0x9b, dst, src1, src2);
+  }
+  void vfmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xab, dst, src1, src2);
+  }
+  void vfmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xbb, dst, src1, src2);
+  }
+  void vfnmadd132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmass(0x9d, dst, src1, src2);
+  }
+  void vfnmadd213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmass(0xad, dst, src1, src2);
+  }
+  void vfnmadd231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmass(0xbd, dst, src1, src2);
+  }
+  void vfnmadd132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0x9d, dst, src1, src2);
+  }
+  void vfnmadd213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xad, dst, src1, src2);
+  }
+  void vfnmadd231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xbd, dst, src1, src2);
+  }
+  void vfnmsub132ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmass(0x9f, dst, src1, src2);
+  }
+  void vfnmsub213ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmass(0xaf, dst, src1, src2);
+  }
+  void vfnmsub231ss(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vfmass(0xbf, dst, src1, src2);
+  }
+  void vfnmsub132ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0x9f, dst, src1, src2);
+  }
+  void vfnmsub213ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xaf, dst, src1, src2);
+  }
+  void vfnmsub231ss(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vfmass(0xbf, dst, src1, src2);
+  }
+  void vfmass(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
+  void vfmass(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
+
+  void vaddsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vsd(0x58, dst, src1, src2);
+  }
+  void vaddsd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vsd(0x58, dst, src1, src2);
+  }
+  void vsubsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vsd(0x5c, dst, src1, src2);
+  }
+  void vsubsd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vsd(0x5c, dst, src1, src2);
+  }
+  void vmulsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vsd(0x59, dst, src1, src2);
+  }
+  void vmulsd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vsd(0x59, dst, src1, src2);
+  }
+  void vdivsd(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+    vsd(0x5e, dst, src1, src2);
+  }
+  void vdivsd(XMMRegister dst, XMMRegister src1, const Operand& src2) {
+    vsd(0x5e, dst, src1, src2);
+  }
+  void vsd(byte op, XMMRegister dst, XMMRegister src1, XMMRegister src2);
+  void vsd(byte op, XMMRegister dst, XMMRegister src1, const Operand& src2);
+
   // Debugging
   void Print();
 
@@ -1253,6 +1471,7 @@
   // Optionally do as emit_rex_32(Register) if the register number has
   // the high bit set.
   inline void emit_optional_rex_32(Register rm_reg);
+  inline void emit_optional_rex_32(XMMRegister rm_reg);
 
   // Optionally do as emit_rex_32(const Operand&) if the operand register
   // numbers have a high bit set.
@@ -1286,6 +1505,28 @@
     }
   }
 
+  // Emit vex prefix
+  enum SIMDPrefix { kNone = 0x0, k66 = 0x1, kF3 = 0x2, kF2 = 0x3 };
+  enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128 };
+  enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 };
+  enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x2 };
+
+  void emit_vex2_byte0() { emit(0xc5); }
+  inline void emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l,
+                              SIMDPrefix pp);
+  void emit_vex3_byte0() { emit(0xc4); }
+  inline void emit_vex3_byte1(XMMRegister reg, XMMRegister rm, LeadingOpcode m);
+  inline void emit_vex3_byte1(XMMRegister reg, const Operand& rm,
+                              LeadingOpcode m);
+  inline void emit_vex3_byte2(VexW w, XMMRegister v, VectorLength l,
+                              SIMDPrefix pp);
+  inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, XMMRegister rm,
+                              VectorLength l, SIMDPrefix pp, LeadingOpcode m,
+                              VexW w);
+  inline void emit_vex_prefix(XMMRegister reg, XMMRegister v, const Operand& rm,
+                              VectorLength l, SIMDPrefix pp, LeadingOpcode m,
+                              VexW w);
+
   // Emit the ModR/M byte, and optionally the SIB byte and
   // 1- or 4-byte offset for a memory operand.  Also encodes
   // the second operand of the operation, a register or operation
@@ -1360,9 +1601,11 @@
                                int size);
 
   // Emit machine code for a shift operation.
+  void shift(Operand dst, Immediate shift_amount, int subcode, int size);
   void shift(Register dst, Immediate shift_amount, int subcode, int size);
   // Shift dst by cl % 64 bits.
   void shift(Register dst, int subcode, int size);
+  void shift(Operand dst, int subcode, int size);
 
   void emit_farith(int b1, int b2, int i);
 
@@ -1446,9 +1689,11 @@
   // Signed multiply instructions.
   // rdx:rax = rax * src when size is 64 or edx:eax = eax * src when size is 32.
   void emit_imul(Register src, int size);
+  void emit_imul(const Operand& src, int size);
   void emit_imul(Register dst, Register src, int size);
   void emit_imul(Register dst, const Operand& src, int size);
   void emit_imul(Register dst, Register src, Immediate imm, int size);
+  void emit_imul(Register dst, const Operand& src, Immediate imm, int size);
 
   void emit_inc(Register dst, int size);
   void emit_inc(const Operand& dst, int size);
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index 194d8a6..ef3df65 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -158,22 +158,20 @@
       // rax: initial map
       __ CmpInstanceType(rax, JS_FUNCTION_TYPE);
       __ j(equal, &rt_call);
-
       if (!is_api_function) {
         Label allocate;
         // The code below relies on these assumptions.
-        STATIC_ASSERT(JSFunction::kNoSlackTracking == 0);
-        STATIC_ASSERT(Map::ConstructionCount::kShift +
-                      Map::ConstructionCount::kSize == 32);
+        STATIC_ASSERT(Map::Counter::kShift + Map::Counter::kSize == 32);
         // Check if slack tracking is enabled.
         __ movl(rsi, FieldOperand(rax, Map::kBitField3Offset));
-        __ shrl(rsi, Immediate(Map::ConstructionCount::kShift));
-        __ j(zero, &allocate);  // JSFunction::kNoSlackTracking
+        __ shrl(rsi, Immediate(Map::Counter::kShift));
+        __ cmpl(rsi, Immediate(Map::kSlackTrackingCounterEnd));
+        __ j(less, &allocate);
         // Decrease generous allocation count.
         __ subl(FieldOperand(rax, Map::kBitField3Offset),
-                Immediate(1 << Map::ConstructionCount::kShift));
+                Immediate(1 << Map::Counter::kShift));
 
-        __ cmpl(rsi, Immediate(JSFunction::kFinishSlackTracking));
+        __ cmpl(rsi, Immediate(Map::kSlackTrackingCounterEnd));
         __ j(not_equal, &allocate);
 
         __ Push(rax);
@@ -184,7 +182,7 @@
 
         __ Pop(rdi);
         __ Pop(rax);
-        __ xorl(rsi, rsi);  // JSFunction::kNoSlackTracking
+        __ movl(rsi, Immediate(Map::kSlackTrackingCounterEnd - 1));
 
         __ bind(&allocate);
       }
@@ -222,8 +220,8 @@
         Label no_inobject_slack_tracking;
 
         // Check if slack tracking is enabled.
-        __ cmpl(rsi, Immediate(JSFunction::kNoSlackTracking));
-        __ j(equal, &no_inobject_slack_tracking);
+        __ cmpl(rsi, Immediate(Map::kSlackTrackingCounterEnd));
+        __ j(less, &no_inobject_slack_tracking);
 
         // Allocate object with a slack.
         __ movzxbp(rsi,
@@ -1075,14 +1073,19 @@
 
     // Use inline caching to speed up access to arguments.
     if (FLAG_vector_ics) {
-      __ Move(VectorLoadICDescriptor::SlotRegister(), Smi::FromInt(0));
+      // TODO(mvstanton): Vector-based ics need additional infrastructure to
+      // be embedded here. For now, just call the runtime.
+      __ Push(receiver);
+      __ Push(key);
+      __ CallRuntime(Runtime::kGetProperty, 2);
+    } else {
+      Handle<Code> ic = CodeFactory::KeyedLoadIC(masm->isolate()).code();
+      __ Call(ic, RelocInfo::CODE_TARGET);
+      // It is important that we do not have a test instruction after the
+      // call.  A test instruction after the call is used to indicate that
+      // we have generated an inline version of the keyed load.  In this
+      // case, we know that we are not generating a test instruction next.
     }
-    Handle<Code> ic = CodeFactory::KeyedLoadIC(masm->isolate()).code();
-    __ Call(ic, RelocInfo::CODE_TARGET);
-    // It is important that we do not have a test instruction after the
-    // call.  A test instruction after the call is used to indicate that
-    // we have generated an inline version of the keyed load.  In this
-    // case, we know that we are not generating a test instruction next.
 
     // Push the nth argument.
     __ Push(rax);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index a625269..f327b50 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -14,7 +14,7 @@
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -524,6 +524,11 @@
 void FunctionPrototypeStub::Generate(MacroAssembler* masm) {
   Label miss;
   Register receiver = LoadDescriptor::ReceiverRegister();
+  // Ensure that the vector and slot registers won't be clobbered before
+  // calling the miss handler.
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(r8, r9, VectorLoadICDescriptor::VectorRegister(),
+                     VectorLoadICDescriptor::SlotRegister()));
 
   NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, r8,
                                                           r9, &miss);
@@ -867,6 +872,40 @@
 }
 
 
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+  // Return address is on the stack.
+  Label miss;
+
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register index = LoadDescriptor::NameRegister();
+  Register scratch = rdi;
+  Register result = rax;
+  DCHECK(!scratch.is(receiver) && !scratch.is(index));
+  DCHECK(!FLAG_vector_ics ||
+         (!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
+          result.is(VectorLoadICDescriptor::SlotRegister())));
+
+  // StringCharAtGenerator doesn't use the result register until it's passed
+  // the different miss possibilities. If it did, we would have a conflict
+  // when FLAG_vector_ics is true.
+  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+                                          &miss,  // When not a string.
+                                          &miss,  // When not a number.
+                                          &miss,  // When index out of range.
+                                          STRING_INDEX_IS_ARRAY_INDEX,
+                                          RECEIVER_IS_STRING);
+  char_at_generator.GenerateFast(masm);
+  __ ret(0);
+
+  StubRuntimeCallHelper call_helper;
+  char_at_generator.GenerateSlow(masm, call_helper);
+
+  __ bind(&miss);
+  PropertyAccessCompiler::TailCallBuiltin(
+      masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
+
+
 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
   // rsp[0]  : return address
   // rsp[8]  : number of parameters
@@ -2059,6 +2098,10 @@
   // rdi - function
   // rdx - slot id
   Isolate* isolate = masm->isolate();
+  const int with_types_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
+  const int generic_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
   Label extra_checks_or_miss, slow_start;
   Label slow, non_function, wrap, cont;
   Label have_js_function;
@@ -2100,27 +2143,64 @@
   }
 
   __ bind(&extra_checks_or_miss);
-  Label miss;
+  Label uninitialized, miss;
 
   __ movp(rcx, FieldOperand(rbx, rdx, times_pointer_size,
                             FixedArray::kHeaderSize));
   __ Cmp(rcx, TypeFeedbackVector::MegamorphicSentinel(isolate));
   __ j(equal, &slow_start);
-  __ Cmp(rcx, TypeFeedbackVector::UninitializedSentinel(isolate));
-  __ j(equal, &miss);
 
-  if (!FLAG_trace_ic) {
-    // We are going megamorphic. If the feedback is a JSFunction, it is fine
-    // to handle it here. More complex cases are dealt with in the runtime.
-    __ AssertNotSmi(rcx);
-    __ CmpObjectType(rcx, JS_FUNCTION_TYPE, rcx);
-    __ j(not_equal, &miss);
-    __ Move(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize),
-            TypeFeedbackVector::MegamorphicSentinel(isolate));
-    __ jmp(&slow_start);
+  // The following cases attempt to handle MISS cases without going to the
+  // runtime.
+  if (FLAG_trace_ic) {
+    __ jmp(&miss);
   }
 
-  // We are here because tracing is on or we are going monomorphic.
+  __ Cmp(rcx, TypeFeedbackVector::UninitializedSentinel(isolate));
+  __ j(equal, &uninitialized);
+
+  // We are going megamorphic. If the feedback is a JSFunction, it is fine
+  // to handle it here. More complex cases are dealt with in the runtime.
+  __ AssertNotSmi(rcx);
+  __ CmpObjectType(rcx, JS_FUNCTION_TYPE, rcx);
+  __ j(not_equal, &miss);
+  __ Move(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize),
+          TypeFeedbackVector::MegamorphicSentinel(isolate));
+  // We have to update statistics for runtime profiling.
+  __ SmiAddConstant(FieldOperand(rbx, with_types_offset), Smi::FromInt(-1));
+  __ SmiAddConstant(FieldOperand(rbx, generic_offset), Smi::FromInt(1));
+  __ jmp(&slow_start);
+
+  __ bind(&uninitialized);
+
+  // We are going monomorphic, provided we actually have a JSFunction.
+  __ JumpIfSmi(rdi, &miss);
+
+  // Goto miss case if we do not have a function.
+  __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
+  __ j(not_equal, &miss);
+
+  // Make sure the function is not the Array() function, which requires special
+  // behavior on MISS.
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, rcx);
+  __ cmpp(rdi, rcx);
+  __ j(equal, &miss);
+
+  // Update stats.
+  __ SmiAddConstant(FieldOperand(rbx, with_types_offset), Smi::FromInt(1));
+
+  // Store the function.
+  __ movp(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize),
+          rdi);
+
+  // Update the write barrier.
+  __ movp(rax, rdi);
+  __ RecordWriteArray(rbx, rax, rdx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
+                      OMIT_SMI_CHECK);
+  __ jmp(&have_js_function);
+
+  // We are here because tracing is on or we encountered a MISS case we can't
+  // handle here.
   __ bind(&miss);
   GenerateMiss(masm);
 
@@ -2711,14 +2791,16 @@
 
 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
   // If the receiver is a smi trigger the non-string case.
-  __ JumpIfSmi(object_, receiver_not_string_);
+  if (check_mode_ == RECEIVER_IS_UNKNOWN) {
+    __ JumpIfSmi(object_, receiver_not_string_);
 
-  // Fetch the instance type of the receiver into result register.
-  __ movp(result_, FieldOperand(object_, HeapObject::kMapOffset));
-  __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
-  // If the receiver is not a string trigger the non-string case.
-  __ testb(result_, Immediate(kIsNotStringMask));
-  __ j(not_zero, receiver_not_string_);
+    // Fetch the instance type of the receiver into result register.
+    __ movp(result_, FieldOperand(object_, HeapObject::kMapOffset));
+    __ movzxbl(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
+    // If the receiver is not a string trigger the non-string case.
+    __ testb(result_, Immediate(kIsNotStringMask));
+    __ j(not_zero, receiver_not_string_);
+  }
 
   // If the index is non-smi trigger the non-smi case.
   __ JumpIfNotSmi(index_, &index_not_smi_);
@@ -3076,14 +3158,62 @@
   // rbx: instance type
   // rcx: sub string length (smi)
   // rdx: from index (smi)
-  StringCharAtGenerator generator(
-      rax, rdx, rcx, rax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
+  StringCharAtGenerator generator(rax, rdx, rcx, rax, &runtime, &runtime,
+                                  &runtime, STRING_INDEX_IS_NUMBER,
+                                  RECEIVER_IS_STRING);
   generator.GenerateFast(masm);
   __ ret(SUB_STRING_ARGUMENT_COUNT * kPointerSize);
   generator.SkipSlow(masm, &runtime);
 }
 
 
+void ToNumberStub::Generate(MacroAssembler* masm) {
+  // The ToNumber stub takes one argument in rax.
+  Label not_smi;
+  __ JumpIfNotSmi(rax, &not_smi, Label::kNear);
+  __ Ret();
+  __ bind(&not_smi);
+
+  Label not_heap_number;
+  __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
+                 Heap::kHeapNumberMapRootIndex);
+  __ j(not_equal, &not_heap_number, Label::kNear);
+  __ Ret();
+  __ bind(&not_heap_number);
+
+  Label not_string, slow_string;
+  __ CmpObjectType(rax, FIRST_NONSTRING_TYPE, rdi);
+  // rax: object
+  // rdi: object map
+  __ j(above_equal, &not_string, Label::kNear);
+  // Check if string has a cached array index.
+  __ testl(FieldOperand(rax, String::kHashFieldOffset),
+           Immediate(String::kContainsCachedArrayIndexMask));
+  __ j(not_zero, &slow_string, Label::kNear);
+  __ movl(rax, FieldOperand(rax, String::kHashFieldOffset));
+  __ IndexFromHash(rax, rax);
+  __ Ret();
+  __ bind(&slow_string);
+  __ PopReturnAddressTo(rcx);     // Pop return address.
+  __ Push(rax);                   // Push argument.
+  __ PushReturnAddressFrom(rcx);  // Push return address.
+  __ TailCallRuntime(Runtime::kStringToNumber, 1, 1);
+  __ bind(&not_string);
+
+  Label not_oddball;
+  __ CmpInstanceType(rdi, ODDBALL_TYPE);
+  __ j(not_equal, &not_oddball, Label::kNear);
+  __ movp(rax, FieldOperand(rax, Oddball::kToNumberOffset));
+  __ Ret();
+  __ bind(&not_oddball);
+
+  __ PopReturnAddressTo(rcx);     // Pop return address.
+  __ Push(rax);                   // Push argument.
+  __ PushReturnAddressFrom(rcx);  // Push return address.
+  __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
+}
+
+
 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm,
                                                    Register left,
                                                    Register right,
diff --git a/src/x64/code-stubs-x64.h b/src/x64/code-stubs-x64.h
index d17fa1b..0efcf7f 100644
--- a/src/x64/code-stubs-x64.h
+++ b/src/x64/code-stubs-x64.h
@@ -71,7 +71,7 @@
                                      Register r0,
                                      Register r1);
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
  private:
   static const int kInlinedProbes = 4;
@@ -134,7 +134,7 @@
     INCREMENTAL_COMPACTION
   };
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
   static const byte kTwoByteNopInstruction = 0x3c;  // Cmpb al, #imm8.
   static const byte kTwoByteJumpInstruction = 0xeb;  // Jmp #imm8.
@@ -313,9 +313,9 @@
     kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
   };
 
-  virtual Major MajorKey() const FINAL OVERRIDE { return RecordWrite; }
+  Major MajorKey() const FINAL { return RecordWrite; }
 
-  virtual void Generate(MacroAssembler* masm) OVERRIDE;
+  void Generate(MacroAssembler* masm) OVERRIDE;
   void GenerateIncremental(MacroAssembler* masm, Mode mode);
   void CheckNeedsToInformIncrementalMarker(
       MacroAssembler* masm,
@@ -323,7 +323,7 @@
       Mode mode);
   void InformIncrementalMarker(MacroAssembler* masm);
 
-  void Activate(Code* code) {
+  void Activate(Code* code) OVERRIDE {
     code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
   }
 
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 44e1618..ceee954 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -397,6 +397,20 @@
   __ LoadRoot(rdi, Heap::kTheHoleValueRootIndex);
   // rsi: the-hole NaN
   // rdi: pointer to the-hole
+
+  // Allocating heap numbers in the loop below can fail and cause a jump to
+  // gc_required. We can't leave a partly initialized FixedArray behind,
+  // so pessimistically fill it with holes now.
+  Label initialization_loop, initialization_loop_entry;
+  __ jmp(&initialization_loop_entry, Label::kNear);
+  __ bind(&initialization_loop);
+  __ movp(FieldOperand(r11, r9, times_pointer_size, FixedArray::kHeaderSize),
+          rdi);
+  __ bind(&initialization_loop_entry);
+  __ decp(r9);
+  __ j(not_sign, &initialization_loop);
+
+  __ SmiToInteger32(r9, FieldOperand(r8, FixedDoubleArray::kLengthOffset));
   __ jmp(&entry);
 
   // Call into runtime if GC is required.
diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc
index c8b7c22..c8f9456 100644
--- a/src/x64/debug-x64.cc
+++ b/src/x64/debug-x64.cc
@@ -164,7 +164,11 @@
   // Register state for IC load call (from ic-x64.cc).
   Register receiver = LoadDescriptor::ReceiverRegister();
   Register name = LoadDescriptor::NameRegister();
-  Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false);
+  RegList regs = receiver.bit() | name.bit();
+  if (FLAG_vector_ics) {
+    regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit();
+  }
+  Generate_DebugBreakCallHelper(masm, regs, 0, false);
 }
 
 
diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc
index 16b0cdc..54fe9b0 100644
--- a/src/x64/deoptimizer-x64.cc
+++ b/src/x64/deoptimizer-x64.cc
@@ -23,6 +23,12 @@
 }
 
 
+void Deoptimizer::EnsureRelocSpaceForLazyDeoptimization(Handle<Code> code) {
+  // Empty because there is no need for relocation information for the code
+  // patching in Deoptimizer::PatchCodeForDeoptimization below.
+}
+
+
 void Deoptimizer::PatchCodeForDeoptimization(Isolate* isolate, Code* code) {
   // Invalidate the relocation information, as it will become invalid by the
   // code patching below, and is not needed any more.
diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc
index 2b8fc2d..75adc89 100644
--- a/src/x64/disasm-x64.cc
+++ b/src/x64/disasm-x64.cc
@@ -148,6 +148,8 @@
   ESCAPE_PREFIX = 0x0F,
   OPERAND_SIZE_OVERRIDE_PREFIX = 0x66,
   ADDRESS_SIZE_OVERRIDE_PREFIX = 0x67,
+  VEX3_PREFIX = 0xC4,
+  VEX2_PREFIX = 0xC5,
   REPNE_PREFIX = 0xF2,
   REP_PREFIX = 0xF3,
   REPEQ_PREFIX = REP_PREFIX
@@ -252,7 +254,7 @@
     LAZY_INSTANCE_INITIALIZER;
 
 
-static InstructionDesc cmov_instructions[16] = {
+static const InstructionDesc cmov_instructions[16] = {
   {"cmovo", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
   {"cmovno", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
   {"cmovc", TWO_OPERANDS_INSTR, REG_OPER_OP_ORDER, false},
@@ -290,11 +292,14 @@
                       ABORT_ON_UNIMPLEMENTED_OPCODE)
       : converter_(converter),
         tmp_buffer_pos_(0),
-        abort_on_unimplemented_(
-            unimplemented_action == ABORT_ON_UNIMPLEMENTED_OPCODE),
+        abort_on_unimplemented_(unimplemented_action ==
+                                ABORT_ON_UNIMPLEMENTED_OPCODE),
         rex_(0),
         operand_size_(0),
         group_1_prefix_(0),
+        vex_byte0_(0),
+        vex_byte1_(0),
+        vex_byte2_(0),
         byte_size_operand_(false),
         instruction_table_(instruction_table.Pointer()) {
     tmp_buffer_[0] = '\0';
@@ -323,6 +328,9 @@
   byte rex_;
   byte operand_size_;  // 0x66 or (if no group 3 prefix is present) 0x0.
   byte group_1_prefix_;  // 0xF2, 0xF3, or (if no group 1 prefix is present) 0.
+  byte vex_byte0_;       // 0xc4 or 0xc5
+  byte vex_byte1_;
+  byte vex_byte2_;  // only for 3 bytes vex prefix
   // Byte size operand override.
   bool byte_size_operand_;
   const InstructionTable* const instruction_table_;
@@ -345,6 +353,51 @@
 
   bool rex_w() { return (rex_ & 0x08) != 0; }
 
+  bool vex_128() {
+    DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
+    byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
+    return (checked & 4) != 1;
+  }
+
+  bool vex_66() {
+    DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
+    byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
+    return (checked & 3) == 1;
+  }
+
+  bool vex_f3() {
+    DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
+    byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
+    return (checked & 3) == 2;
+  }
+
+  bool vex_f2() {
+    DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
+    byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
+    return (checked & 3) == 3;
+  }
+
+  bool vex_0f() {
+    if (vex_byte0_ == VEX2_PREFIX) return true;
+    return (vex_byte1_ & 3) == 1;
+  }
+
+  bool vex_0f38() {
+    if (vex_byte0_ == VEX2_PREFIX) return false;
+    return (vex_byte1_ & 3) == 2;
+  }
+
+  bool vex_0f3a() {
+    if (vex_byte0_ == VEX2_PREFIX) return false;
+    return (vex_byte1_ & 3) == 3;
+  }
+
+  int vex_vreg() {
+    DCHECK(vex_byte0_ == VEX3_PREFIX || vex_byte0_ == VEX2_PREFIX);
+    byte checked = vex_byte0_ == VEX3_PREFIX ? vex_byte2_ : vex_byte1_;
+    return ~(checked >> 3) & 0xf;
+  }
+
   OperandSize operand_size() {
     if (byte_size_operand_) return OPERAND_BYTE_SIZE;
     if (rex_w()) return OPERAND_QUADWORD_SIZE;
@@ -356,6 +409,8 @@
     return "bwlq"[operand_size()];
   }
 
+  char float_size_code() { return "sd"[rex_w()]; }
+
   const char* NameOfCPURegister(int reg) const {
     return converter_.NameOfCPURegister(reg);
   }
@@ -414,6 +469,7 @@
   int FPUInstruction(byte* data);
   int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start);
   int RegisterFPUInstruction(int escape_opcode, byte modrm_byte);
+  int AVXInstruction(byte* data);
   void AppendToBuffer(const char* format, ...);
 
   void UnimplementedInstruction() {
@@ -709,65 +765,62 @@
 
 int DisassemblerX64::ShiftInstruction(byte* data) {
   byte op = *data & (~1);
+  int count = 1;
   if (op != 0xD0 && op != 0xD2 && op != 0xC0) {
     UnimplementedInstruction();
-    return 1;
+    return count;
   }
-  byte modrm = *(data + 1);
-  int mod, regop, rm;
-  get_modrm(modrm, &mod, &regop, &rm);
-  regop &= 0x7;  // The REX.R bit does not affect the operation.
-  int imm8 = -1;
-  int num_bytes = 2;
-  if (mod != 3) {
-    UnimplementedInstruction();
-    return num_bytes;
+  // Print mneumonic.
+  {
+    byte modrm = *(data + count);
+    int mod, regop, rm;
+    get_modrm(modrm, &mod, &regop, &rm);
+    regop &= 0x7;  // The REX.R bit does not affect the operation.
+    const char* mnem = NULL;
+    switch (regop) {
+      case 0:
+        mnem = "rol";
+        break;
+      case 1:
+        mnem = "ror";
+        break;
+      case 2:
+        mnem = "rcl";
+        break;
+      case 3:
+        mnem = "rcr";
+        break;
+      case 4:
+        mnem = "shl";
+        break;
+      case 5:
+        mnem = "shr";
+        break;
+      case 7:
+        mnem = "sar";
+        break;
+      default:
+        UnimplementedInstruction();
+        return count + 1;
+    }
+    DCHECK_NE(NULL, mnem);
+    AppendToBuffer("%s%c ", mnem, operand_size_code());
   }
-  const char* mnem = NULL;
-  switch (regop) {
-    case 0:
-      mnem = "rol";
-      break;
-    case 1:
-      mnem = "ror";
-      break;
-    case 2:
-      mnem = "rcl";
-      break;
-    case 3:
-      mnem = "rcr";
-      break;
-    case 4:
-      mnem = "shl";
-      break;
-    case 5:
-      mnem = "shr";
-      break;
-    case 7:
-      mnem = "sar";
-      break;
-    default:
-      UnimplementedInstruction();
-      return num_bytes;
-  }
-  DCHECK_NE(NULL, mnem);
-  if (op == 0xD0) {
-    imm8 = 1;
-  } else if (op == 0xC0) {
-    imm8 = *(data + 2);
-    num_bytes = 3;
-  }
-  AppendToBuffer("%s%c %s,",
-                 mnem,
-                 operand_size_code(),
-                 byte_size_operand_ ? NameOfByteCPURegister(rm)
-                                    : NameOfCPURegister(rm));
+  count += PrintRightOperand(data + count);
   if (op == 0xD2) {
-    AppendToBuffer("cl");
+    AppendToBuffer(", cl");
   } else {
-    AppendToBuffer("%d", imm8);
+    int imm8 = -1;
+    if (op == 0xD0) {
+      imm8 = 1;
+    } else {
+      DCHECK_EQ(0xC0, op);
+      imm8 = *(data + count);
+      count++;
+    }
+    AppendToBuffer(", %d", imm8);
   }
-  return num_bytes;
+  return count;
 }
 
 
@@ -814,6 +867,111 @@
 }
 
 
+int DisassemblerX64::AVXInstruction(byte* data) {
+  byte opcode = *data;
+  byte* current = data + 1;
+  if (vex_66() && vex_0f38()) {
+    int mod, regop, rm, vvvv = vex_vreg();
+    get_modrm(*current, &mod, &regop, &rm);
+    switch (opcode) {
+      case 0x99:
+        AppendToBuffer("vfmadd132s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xa9:
+        AppendToBuffer("vfmadd213s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xb9:
+        AppendToBuffer("vfmadd231s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x9b:
+        AppendToBuffer("vfmsub132s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xab:
+        AppendToBuffer("vfmsub213s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xbb:
+        AppendToBuffer("vfmsub231s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x9d:
+        AppendToBuffer("vfnmadd132s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xad:
+        AppendToBuffer("vfnmadd213s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xbd:
+        AppendToBuffer("vfnmadd231s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x9f:
+        AppendToBuffer("vfnmsub132s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xaf:
+        AppendToBuffer("vfnmsub213s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0xbf:
+        AppendToBuffer("vfnmsub231s%c %s,%s,", float_size_code(),
+                       NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      default:
+        UnimplementedInstruction();
+    }
+  } else if (vex_f2() && vex_0f()) {
+    int mod, regop, rm, vvvv = vex_vreg();
+    get_modrm(*current, &mod, &regop, &rm);
+    switch (opcode) {
+      case 0x58:
+        AppendToBuffer("vaddsd %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x59:
+        AppendToBuffer("vmulsd %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x5c:
+        AppendToBuffer("vsubsd %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      case 0x5e:
+        AppendToBuffer("vdivsd %s,%s,", NameOfXMMRegister(regop),
+                       NameOfXMMRegister(vvvv));
+        current += PrintRightXMMOperand(current);
+        break;
+      default:
+        UnimplementedInstruction();
+    }
+  } else {
+    UnimplementedInstruction();
+  }
+
+  return static_cast<int>(current - data);
+}
+
+
 // Returns number of bytes used, including *data.
 int DisassemblerX64::FPUInstruction(byte* data) {
   byte escape_opcode = *data;
@@ -1069,10 +1227,15 @@
       } else if (opcode == 0x50) {
         AppendToBuffer("movmskpd %s,", NameOfCPURegister(regop));
         current += PrintRightXMMOperand(current);
+      } else if (opcode == 0x72) {
+        current += 1;
+        AppendToBuffer("%s,%s,%d", (regop == 6) ? "pslld" : "psrld",
+                       NameOfXMMRegister(rm), *current & 0x7f);
+        current += 1;
       } else if (opcode == 0x73) {
         current += 1;
-        DCHECK(regop == 6);
-        AppendToBuffer("psllq,%s,%d", NameOfXMMRegister(rm), *current & 0x7f);
+        AppendToBuffer("%s,%s,%d", (regop == 6) ? "psllq" : "psrlq",
+                       NameOfXMMRegister(rm), *current & 0x7f);
         current += 1;
       } else {
         const char* mnemonic = "?";
@@ -1086,6 +1249,8 @@
           mnemonic = "ucomisd";
         } else if (opcode == 0x2F) {
           mnemonic = "comisd";
+        } else if (opcode == 0x76) {
+          mnemonic = "pcmpeqd";
         } else {
           UnimplementedInstruction();
         }
@@ -1185,6 +1350,16 @@
       AppendToBuffer("cvttss2si%c %s,",
           operand_size_code(), NameOfCPURegister(regop));
       current += PrintRightXMMOperand(current);
+    } else if (opcode == 0x58) {
+      int mod, regop, rm;
+      get_modrm(*current, &mod, &regop, &rm);
+      AppendToBuffer("addss %s,", NameOfXMMRegister(regop));
+      current += PrintRightXMMOperand(current);
+    } else if (opcode == 0x59) {
+      int mod, regop, rm;
+      get_modrm(*current, &mod, &regop, &rm);
+      AppendToBuffer("mulss %s,", NameOfXMMRegister(regop));
+      current += PrintRightXMMOperand(current);
     } else if (opcode == 0x5A) {
       // CVTSS2SD:
       // Convert scalar single-precision FP to scalar double-precision FP.
@@ -1192,6 +1367,16 @@
       get_modrm(*current, &mod, &regop, &rm);
       AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop));
       current += PrintRightXMMOperand(current);
+    } else if (opcode == 0x5c) {
+      int mod, regop, rm;
+      get_modrm(*current, &mod, &regop, &rm);
+      AppendToBuffer("subss %s,", NameOfXMMRegister(regop));
+      current += PrintRightXMMOperand(current);
+    } else if (opcode == 0x5e) {
+      int mod, regop, rm;
+      get_modrm(*current, &mod, &regop, &rm);
+      AppendToBuffer("divss %s,", NameOfXMMRegister(regop));
+      current += PrintRightXMMOperand(current);
     } else if (opcode == 0x7E) {
       int mod, regop, rm;
       get_modrm(*current, &mod, &regop, &rm);
@@ -1230,6 +1415,11 @@
     current += PrintRightXMMOperand(current);
     AppendToBuffer(",%s", NameOfXMMRegister(regop));
 
+  } else if (opcode == 0x2e) {
+    int mod, regop, rm;
+    get_modrm(*current, &mod, &regop, &rm);
+    AppendToBuffer("ucomiss %s,", NameOfXMMRegister(regop));
+    current += PrintRightXMMOperand(current);
   } else if (opcode == 0xA2) {
     // CPUID
     AppendToBuffer("%s", mnemonic);
@@ -1383,99 +1573,114 @@
       if (rex_w()) AppendToBuffer("REX.W ");
     } else if ((current & 0xFE) == 0xF2) {  // Group 1 prefix (0xF2 or 0xF3).
       group_1_prefix_ = current;
+    } else if (current == VEX3_PREFIX) {
+      vex_byte0_ = current;
+      vex_byte1_ = *(data + 1);
+      vex_byte2_ = *(data + 2);
+      setRex(0x40 | (~(vex_byte1_ >> 5) & 7) | ((vex_byte2_ >> 4) & 8));
+      data += 2;
+    } else if (current == VEX2_PREFIX) {
+      vex_byte0_ = current;
+      vex_byte1_ = *(data + 1);
+      setRex(0x40 | (~(vex_byte1_ >> 5) & 4));
+      data++;
     } else {  // Not a prefix - an opcode.
       break;
     }
     data++;
   }
 
-  const InstructionDesc& idesc = instruction_table_->Get(current);
-  byte_size_operand_ = idesc.byte_size_operation;
-  switch (idesc.type) {
-    case ZERO_OPERANDS_INSTR:
-      if (current >= 0xA4 && current <= 0xA7) {
-        // String move or compare operations.
-        if (group_1_prefix_ == REP_PREFIX) {
-          // REP.
-          AppendToBuffer("rep ");
+  // Decode AVX instructions.
+  if (vex_byte0_ != 0) {
+    processed = true;
+    data += AVXInstruction(data);
+  } else {
+    const InstructionDesc& idesc = instruction_table_->Get(current);
+    byte_size_operand_ = idesc.byte_size_operation;
+    switch (idesc.type) {
+      case ZERO_OPERANDS_INSTR:
+        if (current >= 0xA4 && current <= 0xA7) {
+          // String move or compare operations.
+          if (group_1_prefix_ == REP_PREFIX) {
+            // REP.
+            AppendToBuffer("rep ");
+          }
+          if (rex_w()) AppendToBuffer("REX.W ");
+          AppendToBuffer("%s%c", idesc.mnem, operand_size_code());
+        } else {
+          AppendToBuffer("%s", idesc.mnem, operand_size_code());
         }
-        if (rex_w()) AppendToBuffer("REX.W ");
-        AppendToBuffer("%s%c", idesc.mnem, operand_size_code());
-      } else {
-        AppendToBuffer("%s", idesc.mnem, operand_size_code());
+        data++;
+        break;
+
+      case TWO_OPERANDS_INSTR:
+        data++;
+        data += PrintOperands(idesc.mnem, idesc.op_order_, data);
+        break;
+
+      case JUMP_CONDITIONAL_SHORT_INSTR:
+        data += JumpConditionalShort(data);
+        break;
+
+      case REGISTER_INSTR:
+        AppendToBuffer("%s%c %s", idesc.mnem, operand_size_code(),
+                       NameOfCPURegister(base_reg(current & 0x07)));
+        data++;
+        break;
+      case PUSHPOP_INSTR:
+        AppendToBuffer("%s %s", idesc.mnem,
+                       NameOfCPURegister(base_reg(current & 0x07)));
+        data++;
+        break;
+      case MOVE_REG_INSTR: {
+        byte* addr = NULL;
+        switch (operand_size()) {
+          case OPERAND_WORD_SIZE:
+            addr =
+                reinterpret_cast<byte*>(*reinterpret_cast<int16_t*>(data + 1));
+            data += 3;
+            break;
+          case OPERAND_DOUBLEWORD_SIZE:
+            addr =
+                reinterpret_cast<byte*>(*reinterpret_cast<uint32_t*>(data + 1));
+            data += 5;
+            break;
+          case OPERAND_QUADWORD_SIZE:
+            addr =
+                reinterpret_cast<byte*>(*reinterpret_cast<int64_t*>(data + 1));
+            data += 9;
+            break;
+          default:
+            UNREACHABLE();
+        }
+        AppendToBuffer("mov%c %s,%s", operand_size_code(),
+                       NameOfCPURegister(base_reg(current & 0x07)),
+                       NameOfAddress(addr));
+        break;
       }
-      data++;
-      break;
 
-    case TWO_OPERANDS_INSTR:
-      data++;
-      data += PrintOperands(idesc.mnem, idesc.op_order_, data);
-      break;
-
-    case JUMP_CONDITIONAL_SHORT_INSTR:
-      data += JumpConditionalShort(data);
-      break;
-
-    case REGISTER_INSTR:
-      AppendToBuffer("%s%c %s",
-                     idesc.mnem,
-                     operand_size_code(),
-                     NameOfCPURegister(base_reg(current & 0x07)));
-      data++;
-      break;
-    case PUSHPOP_INSTR:
-      AppendToBuffer("%s %s",
-                     idesc.mnem,
-                     NameOfCPURegister(base_reg(current & 0x07)));
-      data++;
-      break;
-    case MOVE_REG_INSTR: {
-      byte* addr = NULL;
-      switch (operand_size()) {
-        case OPERAND_WORD_SIZE:
-          addr = reinterpret_cast<byte*>(*reinterpret_cast<int16_t*>(data + 1));
-          data += 3;
-          break;
-        case OPERAND_DOUBLEWORD_SIZE:
-          addr =
-              reinterpret_cast<byte*>(*reinterpret_cast<uint32_t*>(data + 1));
-          data += 5;
-          break;
-        case OPERAND_QUADWORD_SIZE:
-          addr = reinterpret_cast<byte*>(*reinterpret_cast<int64_t*>(data + 1));
-          data += 9;
-          break;
-        default:
-          UNREACHABLE();
+      case CALL_JUMP_INSTR: {
+        byte* addr = data + *reinterpret_cast<int32_t*>(data + 1) + 5;
+        AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr));
+        data += 5;
+        break;
       }
-      AppendToBuffer("mov%c %s,%s",
-                     operand_size_code(),
-                     NameOfCPURegister(base_reg(current & 0x07)),
-                     NameOfAddress(addr));
-      break;
+
+      case SHORT_IMMEDIATE_INSTR: {
+        byte* addr =
+            reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
+        AppendToBuffer("%s rax,%s", idesc.mnem, NameOfAddress(addr));
+        data += 5;
+        break;
+      }
+
+      case NO_INSTR:
+        processed = false;
+        break;
+
+      default:
+        UNIMPLEMENTED();  // This type is not implemented.
     }
-
-    case CALL_JUMP_INSTR: {
-      byte* addr = data + *reinterpret_cast<int32_t*>(data + 1) + 5;
-      AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr));
-      data += 5;
-      break;
-    }
-
-    case SHORT_IMMEDIATE_INSTR: {
-      byte* addr =
-          reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
-      AppendToBuffer("%s rax,%s", idesc.mnem, NameOfAddress(addr));
-      data += 5;
-      break;
-    }
-
-    case NO_INSTR:
-      processed = false;
-      break;
-
-    default:
-      UNIMPLEMENTED();  // This type is not implemented.
   }
 
   // The first byte didn't match any of the simple opcodes, so we
@@ -1489,15 +1694,15 @@
 
       case 0x69:  // fall through
       case 0x6B: {
-        int mod, regop, rm;
-        get_modrm(*(data + 1), &mod, &regop, &rm);
-        int32_t imm = *data == 0x6B ? *(data + 2)
-            : *reinterpret_cast<int32_t*>(data + 2);
-        AppendToBuffer("imul%c %s,%s,0x%x",
-                       operand_size_code(),
-                       NameOfCPURegister(regop),
-                       NameOfCPURegister(rm), imm);
-        data += 2 + (*data == 0x6B ? 1 : 4);
+        int count = 1;
+        count += PrintOperands("imul", REG_OPER_OP_ORDER, data + count);
+        AppendToBuffer(",0x");
+        if (*data == 0x69) {
+          count += PrintImmediate(data + count, operand_size());
+        } else {
+          count += PrintImmediate(data + count, OPERAND_BYTE_SIZE);
+        }
+        data += count;
         break;
       }
 
@@ -1811,19 +2016,19 @@
 //------------------------------------------------------------------------------
 
 
-static const char* cpu_regs[16] = {
+static const char* const cpu_regs[16] = {
   "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
 };
 
 
-static const char* byte_cpu_regs[16] = {
+static const char* const byte_cpu_regs[16] = {
   "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
   "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l"
 };
 
 
-static const char* xmm_regs[16] = {
+static const char* const xmm_regs[16] = {
   "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
   "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
 };
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 0f787b2..24747ee 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -187,10 +187,10 @@
     Comment cmnt(masm_, "[ Allocate context");
     bool need_write_barrier = true;
     // Argument to NewContext is the function, which is still in rdi.
-    if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
+    if (FLAG_harmony_scoping && info->scope()->is_script_scope()) {
       __ Push(rdi);
       __ Push(info->scope()->GetScopeInfo());
-      __ CallRuntime(Runtime::kNewGlobalContext, 2);
+      __ CallRuntime(Runtime::kNewScriptContext, 2);
     } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
       FastNewContextStub stub(isolate(), heap_slots);
       __ CallStub(&stub);
@@ -895,7 +895,7 @@
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
-  __ LoadContext(rax, scope_->ContextChainLength(scope_->GlobalScope()));
+  __ LoadContext(rax, scope_->ContextChainLength(scope_->ScriptScope()));
   __ movp(rax, ContextOperand(rax, variable->interface()->Index()));
   __ movp(rax, ContextOperand(rax, Context::EXTENSION_INDEX));
 
@@ -1058,7 +1058,7 @@
 
 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   Comment cmnt(masm_, "[ ForInStatement");
-  int slot = stmt->ForInFeedbackSlot();
+  FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
   SetStatementPosition(stmt);
 
   Label loop, exit;
@@ -1067,6 +1067,7 @@
 
   // Get the object to enumerate over. If the object is null or undefined, skip
   // over the loop.  See ECMA-262 version 5, section 12.6.4.
+  SetExpressionPosition(stmt->enumerable());
   VisitForAccumulatorValue(stmt->enumerable());
   __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
   __ j(equal, &exit);
@@ -1086,6 +1087,7 @@
   __ Push(rax);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ Push(rax);
 
   // Check for proxies.
@@ -1110,6 +1112,7 @@
   __ bind(&call_runtime);
   __ Push(rax);  // Duplicate the enumerable object on the stack.
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
 
   // If we got a map from the runtime call, we can do a fast
   // modification check. Otherwise, we got a fixed array, and we have
@@ -1149,7 +1152,8 @@
 
   // No need for a write barrier, we are storing a Smi in the feedback vector.
   __ Move(rbx, FeedbackVector());
-  __ Move(FieldOperand(rbx, FixedArray::OffsetOfElementAt(slot)),
+  int vector_index = FeedbackVector()->GetIndex(slot);
+  __ Move(FieldOperand(rbx, FixedArray::OffsetOfElementAt(vector_index)),
           TypeFeedbackVector::MegamorphicSentinel(isolate()));
   __ Move(rbx, Smi::FromInt(1));  // Smi indicates slow check
   __ movp(rcx, Operand(rsp, 0 * kPointerSize));  // Get enumerated object
@@ -1167,6 +1171,8 @@
   // Generate code for doing the condition check.
   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
   __ bind(&loop);
+  SetExpressionPosition(stmt->each());
+
   __ movp(rax, Operand(rsp, 0 * kPointerSize));  // Get the current index.
   __ cmpp(rax, Operand(rsp, 1 * kPointerSize));  // Compare to the array length.
   __ j(above_equal, loop_statement.break_label());
@@ -1236,48 +1242,6 @@
 }
 
 
-void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
-  Comment cmnt(masm_, "[ ForOfStatement");
-  SetStatementPosition(stmt);
-
-  Iteration loop_statement(this, stmt);
-  increment_loop_depth();
-
-  // var iterator = iterable[Symbol.iterator]();
-  VisitForEffect(stmt->assign_iterator());
-
-  // Loop entry.
-  __ bind(loop_statement.continue_label());
-
-  // result = iterator.next()
-  VisitForEffect(stmt->next_result());
-
-  // if (result.done) break;
-  Label result_not_done;
-  VisitForControl(stmt->result_done(),
-                  loop_statement.break_label(),
-                  &result_not_done,
-                  &result_not_done);
-  __ bind(&result_not_done);
-
-  // each = result.value
-  VisitForEffect(stmt->assign_each());
-
-  // Generate code for the body of the loop.
-  Visit(stmt->body());
-
-  // Check stack before looping.
-  PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
-  EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
-  __ jmp(loop_statement.continue_label());
-
-  // Exit and decrement the loop depth.
-  PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
-  __ bind(loop_statement.break_label());
-  decrement_loop_depth();
-}
-
-
 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
                                        bool pretenure) {
   // Use the fast case closure allocation code that allocates in new
@@ -1321,7 +1285,14 @@
   Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
   __ Move(LoadDescriptor::NameRegister(), home_object_symbol);
 
-  CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  if (FLAG_vector_ics) {
+    __ Move(VectorLoadICDescriptor::SlotRegister(),
+            SmiFromSlot(expr->HomeObjectFeedbackSlot()));
+    CallLoadIC(NOT_CONTEXTUAL);
+  } else {
+    CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  }
+
 
   __ Cmp(rax, isolate()->factory()->undefined_value());
   Label done;
@@ -1331,6 +1302,19 @@
 }
 
 
+void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
+                                                  int offset) {
+  if (NeedsHomeObject(initializer)) {
+    __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0));
+    __ Move(StoreDescriptor::NameRegister(),
+            isolate()->factory()->home_object_symbol());
+    __ movp(StoreDescriptor::ValueRegister(),
+            Operand(rsp, offset * kPointerSize));
+    CallStoreIC();
+  }
+}
+
+
 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
                                                       TypeofState typeof_state,
                                                       Label* slow) {
@@ -1386,7 +1370,7 @@
   __ Move(LoadDescriptor::NameRegister(), proxy->var()->name());
   if (FLAG_vector_ics) {
     __ Move(VectorLoadICDescriptor::SlotRegister(),
-            Smi::FromInt(proxy->VariableFeedbackSlot()));
+            SmiFromSlot(proxy->VariableFeedbackSlot()));
   }
 
   ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
@@ -1472,7 +1456,7 @@
       __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
       if (FLAG_vector_ics) {
         __ Move(VectorLoadICDescriptor::SlotRegister(),
-                Smi::FromInt(proxy->VariableFeedbackSlot()));
+                SmiFromSlot(proxy->VariableFeedbackSlot()));
       }
       CallLoadIC(CONTEXTUAL);
       context()->Plug(rax);
@@ -1655,6 +1639,7 @@
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in rax.
@@ -1683,6 +1668,8 @@
         DCHECK(!CompileTimeValue::IsCompileTimeValue(value));
         // Fall through.
       case ObjectLiteral::Property::COMPUTED:
+        // It is safe to use [[Put]] here because the boilerplate already
+        // contains computed properties with an uninitialized value.
         if (key->value()->IsInternalizedString()) {
           if (property->emit_store()) {
             VisitForAccumulatorValue(value);
@@ -1691,6 +1678,14 @@
             __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0));
             CallStoreIC(key->LiteralFeedbackId());
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
+
+            if (NeedsHomeObject(value)) {
+              __ movp(StoreDescriptor::ReceiverRegister(), rax);
+              __ Move(StoreDescriptor::NameRegister(),
+                      isolate()->factory()->home_object_symbol());
+              __ movp(StoreDescriptor::ValueRegister(), Operand(rsp, 0));
+              CallStoreIC();
+            }
           } else {
             VisitForEffect(value);
           }
@@ -1700,6 +1695,7 @@
         VisitForStackValue(key);
         VisitForStackValue(value);
         if (property->emit_store()) {
+          EmitSetHomeObjectIfNeeded(value, 2);
           __ Push(Smi::FromInt(SLOPPY));  // Strict mode
           __ CallRuntime(Runtime::kSetProperty, 4);
         } else {
@@ -1710,7 +1706,7 @@
         __ Push(Operand(rsp, 0));  // Duplicate receiver.
         VisitForStackValue(value);
         if (property->emit_store()) {
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           __ Drop(2);
         }
@@ -1732,7 +1728,9 @@
     __ Push(Operand(rsp, 0));  // Duplicate receiver.
     VisitForStackValue(it->first);
     EmitAccessor(it->second->getter);
+    EmitSetHomeObjectIfNeeded(it->second->getter, 2);
     EmitAccessor(it->second->setter);
+    EmitSetHomeObjectIfNeeded(it->second->setter, 3);
     __ Push(Smi::FromInt(NONE));
     __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
   }
@@ -1847,16 +1845,8 @@
 
   Comment cmnt(masm_, "[ Assignment");
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
-  if (property != NULL) {
-    assign_type = (property->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(property);
 
   // Evaluate LHS expression.
   switch (assign_type) {
@@ -1872,6 +1862,27 @@
         VisitForStackValue(property->obj());
       }
       break;
+    case NAMED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        __ Push(MemOperand(rsp, kPointerSize));
+        __ Push(result_register());
+      }
+      break;
+    case KEYED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(property->key());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        __ Push(MemOperand(rsp, 2 * kPointerSize));
+        __ Push(MemOperand(rsp, 2 * kPointerSize));
+        __ Push(result_register());
+      }
+      break;
     case KEYED_PROPERTY: {
       if (expr->is_compound()) {
         VisitForStackValue(property->obj());
@@ -1899,6 +1910,14 @@
           EmitNamedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
           break;
+        case NAMED_SUPER_PROPERTY:
+          EmitNamedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
+        case KEYED_SUPER_PROPERTY:
+          EmitKeyedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
         case KEYED_PROPERTY:
           EmitKeyedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
@@ -1944,6 +1963,14 @@
     case NAMED_PROPERTY:
       EmitNamedPropertyAssignment(expr);
       break;
+    case NAMED_SUPER_PROPERTY:
+      EmitNamedSuperPropertyStore(property);
+      context()->Plug(rax);
+      break;
+    case KEYED_SUPER_PROPERTY:
+      EmitKeyedSuperPropertyStore(property);
+      context()->Plug(rax);
+      break;
     case KEYED_PROPERTY:
       EmitKeyedPropertyAssignment(expr);
       break;
@@ -2077,7 +2104,7 @@
       __ movp(load_receiver, Operand(rsp, kPointerSize));
       if (FLAG_vector_ics) {
         __ Move(VectorLoadICDescriptor::SlotRegister(),
-                Smi::FromInt(expr->KeyedLoadFeedbackSlot()));
+                SmiFromSlot(expr->KeyedLoadFeedbackSlot()));
       }
       Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
       CallIC(ic, TypeFeedbackId::None());
@@ -2096,7 +2123,7 @@
       __ LoadRoot(load_name, Heap::kdone_stringRootIndex);  // "done"
       if (FLAG_vector_ics) {
         __ Move(VectorLoadICDescriptor::SlotRegister(),
-                Smi::FromInt(expr->DoneFeedbackSlot()));
+                SmiFromSlot(expr->DoneFeedbackSlot()));
       }
       CallLoadIC(NOT_CONTEXTUAL);                           // rax=result.done
       Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
@@ -2109,7 +2136,7 @@
       __ LoadRoot(load_name, Heap::kvalue_stringRootIndex);  // "value"
       if (FLAG_vector_ics) {
         __ Move(VectorLoadICDescriptor::SlotRegister(),
-                Smi::FromInt(expr->ValueFeedbackSlot()));
+                SmiFromSlot(expr->ValueFeedbackSlot()));
       }
       CallLoadIC(NOT_CONTEXTUAL);                        // result.value in rax
       context()->DropAndPlug(2, rax);                    // drop iter and g
@@ -2130,15 +2157,6 @@
   VisitForAccumulatorValue(value);
   __ Pop(rbx);
 
-  // Check generator state.
-  Label wrong_state, closed_state, done;
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
-  __ SmiCompare(FieldOperand(rbx, JSGeneratorObject::kContinuationOffset),
-                Smi::FromInt(0));
-  __ j(equal, &closed_state);
-  __ j(less, &wrong_state);
-
   // Load suspended function and context.
   __ movp(rsi, FieldOperand(rbx, JSGeneratorObject::kContextOffset));
   __ movp(rdi, FieldOperand(rbx, JSGeneratorObject::kFunctionOffset));
@@ -2160,7 +2178,7 @@
 
   // Enter a new JavaScript frame, and initialize its slots as they were when
   // the generator was suspended.
-  Label resume_frame;
+  Label resume_frame, done;
   __ bind(&push_frame);
   __ call(&resume_frame);
   __ jmp(&done);
@@ -2207,25 +2225,6 @@
   // Not reached: the runtime call returns elsewhere.
   __ Abort(kGeneratorFailedToResume);
 
-  // Reach here when generator is closed.
-  __ bind(&closed_state);
-  if (resume_mode == JSGeneratorObject::NEXT) {
-    // Return completed iterator result when generator is closed.
-    __ PushRoot(Heap::kUndefinedValueRootIndex);
-    // Pop value from top-of-stack slot; box result into result register.
-    EmitCreateIteratorResult(true);
-  } else {
-    // Throw the provided value.
-    __ Push(rax);
-    __ CallRuntime(Runtime::kThrow, 1);
-  }
-  __ jmp(&done);
-
-  // Throw error if we attempt to operate on a running generator.
-  __ bind(&wrong_state);
-  __ Push(rbx);
-  __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
-
   __ bind(&done);
   context()->Plug(result_register());
 }
@@ -2235,22 +2234,25 @@
   Label gc_required;
   Label allocated;
 
-  Handle<Map> map(isolate()->native_context()->iterator_result_map());
+  const int instance_size = 5 * kPointerSize;
+  DCHECK_EQ(isolate()->native_context()->iterator_result_map()->instance_size(),
+            instance_size);
 
-  __ Allocate(map->instance_size(), rax, rcx, rdx, &gc_required, TAG_OBJECT);
+  __ Allocate(instance_size, rax, rcx, rdx, &gc_required, TAG_OBJECT);
   __ jmp(&allocated);
 
   __ bind(&gc_required);
-  __ Push(Smi::FromInt(map->instance_size()));
+  __ Push(Smi::FromInt(instance_size));
   __ CallRuntime(Runtime::kAllocateInNewSpace, 1);
   __ movp(context_register(),
           Operand(rbp, StandardFrameConstants::kContextOffset));
 
   __ bind(&allocated);
-  __ Move(rbx, map);
+  __ movp(rbx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
+  __ movp(rbx, FieldOperand(rbx, GlobalObject::kNativeContextOffset));
+  __ movp(rbx, ContextOperand(rbx, Context::ITERATOR_RESULT_MAP_INDEX));
   __ Pop(rcx);
   __ Move(rdx, isolate()->factory()->ToBoolean(done));
-  DCHECK_EQ(map->instance_size(), 5 * kPointerSize);
   __ movp(FieldOperand(rax, HeapObject::kMapOffset), rbx);
   __ Move(FieldOperand(rax, JSObject::kPropertiesOffset),
           isolate()->factory()->empty_fixed_array());
@@ -2271,10 +2273,12 @@
 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
+  DCHECK(!prop->IsSuperAccess());
+
   __ Move(LoadDescriptor::NameRegister(), key->value());
   if (FLAG_vector_ics) {
     __ Move(VectorLoadICDescriptor::SlotRegister(),
-            Smi::FromInt(prop->PropertyFeedbackSlot()));
+            SmiFromSlot(prop->PropertyFeedbackSlot()));
     CallLoadIC(NOT_CONTEXTUAL);
   } else {
     CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
@@ -2283,15 +2287,12 @@
 
 
 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
   DCHECK(!key->value()->IsSmi());
   DCHECK(prop->IsSuperAccess());
 
-  SuperReference* super_ref = prop->obj()->AsSuperReference();
-  EmitLoadHomeObject(super_ref);
-  __ Push(rax);
-  VisitForStackValue(super_ref->this_var());
   __ Push(key->value());
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 }
@@ -2302,7 +2303,7 @@
   Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
   if (FLAG_vector_ics) {
     __ Move(VectorLoadICDescriptor::SlotRegister(),
-            Smi::FromInt(prop->PropertyFeedbackSlot()));
+            SmiFromSlot(prop->PropertyFeedbackSlot()));
     CallIC(ic);
   } else {
     CallIC(ic, prop->PropertyFeedbackId());
@@ -2310,6 +2311,14 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object, key.
+  SetSourcePosition(prop->position());
+
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+}
+
+
 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
                                               Token::Value op,
                                               OverwriteMode mode,
@@ -2371,6 +2380,61 @@
 }
 
 
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
+  // Constructor is in rax.
+  DCHECK(lit != NULL);
+  __ Push(rax);
+
+  // No access check is needed here since the constructor is created by the
+  // class literal.
+  Register scratch = rbx;
+  __ movp(scratch, FieldOperand(rax, JSFunction::kPrototypeOrInitialMapOffset));
+  __ Push(scratch);
+
+  for (int i = 0; i < lit->properties()->length(); i++) {
+    ObjectLiteral::Property* property = lit->properties()->at(i);
+    Literal* key = property->key()->AsLiteral();
+    Expression* value = property->value();
+    DCHECK(key != NULL);
+
+    if (property->is_static()) {
+      __ Push(Operand(rsp, kPointerSize));  // constructor
+    } else {
+      __ Push(Operand(rsp, 0));  // prototype
+    }
+    VisitForStackValue(key);
+    VisitForStackValue(value);
+    EmitSetHomeObjectIfNeeded(value, 2);
+
+    switch (property->kind()) {
+      case ObjectLiteral::Property::CONSTANT:
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+      case ObjectLiteral::Property::COMPUTED:
+      case ObjectLiteral::Property::PROTOTYPE:
+        __ CallRuntime(Runtime::kDefineClassMethod, 3);
+        break;
+
+      case ObjectLiteral::Property::GETTER:
+        __ CallRuntime(Runtime::kDefineClassGetter, 3);
+        break;
+
+      case ObjectLiteral::Property::SETTER:
+        __ CallRuntime(Runtime::kDefineClassSetter, 3);
+        break;
+
+      default:
+        UNREACHABLE();
+    }
+  }
+
+  // prototype
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+
+  // constructor
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+}
+
+
 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
                                      Token::Value op,
                                      OverwriteMode mode) {
@@ -2386,16 +2450,8 @@
 void FullCodeGenerator::EmitAssignment(Expression* expr) {
   DCHECK(expr->IsValidReferenceExpression());
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->AsProperty();
-  if (prop != NULL) {
-    assign_type = (prop->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   switch (assign_type) {
     case VARIABLE: {
@@ -2414,6 +2470,42 @@
       CallStoreIC();
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      __ Push(rax);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      // stack: value, this; rax: home_object
+      Register scratch = rcx;
+      Register scratch2 = rdx;
+      __ Move(scratch, result_register());               // home_object
+      __ movp(rax, MemOperand(rsp, kPointerSize));       // value
+      __ movp(scratch2, MemOperand(rsp, 0));             // this
+      __ movp(MemOperand(rsp, kPointerSize), scratch2);  // this
+      __ movp(MemOperand(rsp, 0), scratch);              // home_object
+      // stack: this, home_object; rax: value
+      EmitNamedSuperPropertyStore(prop);
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      __ Push(rax);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(prop->key());
+      Register scratch = rcx;
+      Register scratch2 = rdx;
+      __ movp(scratch2, MemOperand(rsp, 2 * kPointerSize));  // value
+      // stack: value, this, home_object; rax: key, rdx: value
+      __ movp(scratch, MemOperand(rsp, kPointerSize));  // this
+      __ movp(MemOperand(rsp, 2 * kPointerSize), scratch);
+      __ movp(scratch, MemOperand(rsp, 0));  // home_object
+      __ movp(MemOperand(rsp, kPointerSize), scratch);
+      __ movp(MemOperand(rsp, 0), rax);
+      __ Move(rax, scratch2);
+      // stack: this, home_object, key; rax: value.
+      EmitKeyedSuperPropertyStore(prop);
+      break;
+    }
     case KEYED_PROPERTY: {
       __ Push(rax);  // Preserve value.
       VisitForStackValue(prop->obj());
@@ -2504,8 +2596,9 @@
       }
       EmitStoreToStackLocalOrContextSlot(var, location);
     }
+  } else if (IsSignallingAssignmentToConst(var, op, strict_mode())) {
+    __ CallRuntime(Runtime::kThrowConstAssignError, 0);
   }
-  // Non-initializing assignments to consts are ignored.
 }
 
 
@@ -2526,6 +2619,35 @@
 }
 
 
+void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // rax : value
+  // stack : receiver ('this'), home_object
+  DCHECK(prop != NULL);
+  Literal* key = prop->key()->AsLiteral();
+  DCHECK(key != NULL);
+
+  __ Push(key->value());
+  __ Push(rax);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
+                                          : Runtime::kStoreToSuper_Sloppy),
+                 4);
+}
+
+
+void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // rax : value
+  // stack : receiver ('this'), home_object, key
+  DCHECK(prop != NULL);
+
+  __ Push(rax);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict
+                                          : Runtime::kStoreKeyedToSuper_Sloppy),
+                 4);
+}
+
+
 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
   // Assignment to a property, using a keyed store IC.
 
@@ -2553,16 +2675,27 @@
       __ movp(LoadDescriptor::ReceiverRegister(), rax);
       EmitNamedPropertyLoad(expr);
     } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ Push(result_register());
       EmitNamedSuperPropertyLoad(expr);
     }
     PrepareForBailoutForId(expr->LoadId(), TOS_REG);
     context()->Plug(rax);
   } else {
-    VisitForStackValue(expr->obj());
-    VisitForAccumulatorValue(expr->key());
-    __ Move(LoadDescriptor::NameRegister(), rax);
-    __ Pop(LoadDescriptor::ReceiverRegister());
-    EmitKeyedPropertyLoad(expr);
+    if (!expr->IsSuperAccess()) {
+      VisitForStackValue(expr->obj());
+      VisitForAccumulatorValue(expr->key());
+      __ Move(LoadDescriptor::NameRegister(), rax);
+      __ Pop(LoadDescriptor::ReceiverRegister());
+      EmitKeyedPropertyLoad(expr);
+    } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForStackValue(expr->key());
+      EmitKeyedSuperPropertyLoad(expr);
+    }
     context()->Plug(rax);
   }
 }
@@ -2621,15 +2754,15 @@
   __ Push(rax);
   VisitForAccumulatorValue(super_ref->this_var());
   __ Push(rax);
-  __ Push(Operand(rsp, kPointerSize));
   __ Push(rax);
+  __ Push(Operand(rsp, kPointerSize * 2));
   __ Push(key->value());
 
   // Stack here:
   //  - home_object
   //  - this (receiver)
-  //  - home_object <-- LoadFromSuper will pop here and below.
-  //  - this (receiver)
+  //  - this (receiver) <-- LoadFromSuper will pop here and below.
+  //  - home_object
   //  - key
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 
@@ -2666,6 +2799,41 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
+  Expression* callee = expr->expression();
+  DCHECK(callee->IsProperty());
+  Property* prop = callee->AsProperty();
+  DCHECK(prop->IsSuperAccess());
+
+  SetSourcePosition(prop->position());
+  // Load the function from the receiver.
+  SuperReference* super_ref = prop->obj()->AsSuperReference();
+  EmitLoadHomeObject(super_ref);
+  __ Push(rax);
+  VisitForAccumulatorValue(super_ref->this_var());
+  __ Push(rax);
+  __ Push(rax);
+  __ Push(Operand(rsp, kPointerSize * 2));
+  VisitForStackValue(prop->key());
+
+  // Stack here:
+  //  - home_object
+  //  - this (receiver)
+  //  - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
+  //  - home_object
+  //  - key
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+
+  // Replace home_object with target function.
+  __ movp(Operand(rsp, kPointerSize), rax);
+
+  // Stack here:
+  // - target function
+  // - this (receiver)
+  EmitCall(expr, CallICState::METHOD);
+}
+
+
 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Load the arguments.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2680,7 +2848,7 @@
   SetSourcePosition(expr->position());
   Handle<Code> ic = CallIC::initialize_stub(
       isolate(), arg_count, call_type);
-  __ Move(rdx, Smi::FromInt(expr->CallFeedbackSlot()));
+  __ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot()));
   __ movp(rdi, Operand(rsp, (arg_count + 1) * kPointerSize));
   // Don't assign a type feedback id to the IC, since type feedback is provided
   // by the vector above.
@@ -2721,6 +2889,13 @@
 }
 
 
+void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
+  DCHECK(super_ref != NULL);
+  __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
+  __ CallRuntime(Runtime::kGetPrototype, 1);
+}
+
+
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -2756,6 +2931,8 @@
       // rdx (receiver). Touch up the stack with the right values.
       __ movp(Operand(rsp, (arg_count + 0) * kPointerSize), rdx);
       __ movp(Operand(rsp, (arg_count + 1) * kPointerSize), rax);
+
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
     // Record source position for debugger.
     SetSourcePosition(expr->position());
@@ -2787,6 +2964,7 @@
     __ CallRuntime(Runtime::kLoadLookupSlot, 2);
     __ Push(rax);  // Function.
     __ Push(rdx);  // Receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
 
     // If fast case code has been generated, emit code to push the function
     // and receiver and have the slow path jump around this code.
@@ -2808,9 +2986,12 @@
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
     bool is_named_call = property->key()->IsPropertyName();
-    // super.x() is handled in EmitCallWithLoadIC.
-    if (property->IsSuperAccess() && is_named_call) {
-      EmitSuperCallWithLoadIC(expr);
+    if (property->IsSuperAccess()) {
+      if (is_named_call) {
+        EmitSuperCallWithLoadIC(expr);
+      } else {
+        EmitKeyedSuperCallWithLoadIC(expr);
+      }
     } else {
       {
         PreservePositionScope scope(masm()->positions_recorder());
@@ -2822,6 +3003,12 @@
         EmitKeyedCallWithLoadIC(expr, property->key());
       }
     }
+  } else if (call_type == Call::SUPER_CALL) {
+    SuperReference* super_ref = callee->AsSuperReference();
+    EmitLoadSuperConstructor(super_ref);
+    __ Push(result_register());
+    VisitForStackValue(super_ref->this_var());
+    EmitCall(expr, CallICState::METHOD);
   } else {
     DCHECK(call_type == Call::OTHER_CALL);
     // Call to an arbitrary expression not handled specially above.
@@ -2849,7 +3036,12 @@
   // Push constructor on the stack.  If it's not a function it's used as
   // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
   // ignored.
-  VisitForStackValue(expr->expression());
+  if (expr->expression()->IsSuperReference()) {
+    EmitLoadSuperConstructor(expr->expression()->AsSuperReference());
+    __ Push(result_register());
+  } else {
+    VisitForStackValue(expr->expression());
+  }
 
   // Push the arguments ("left-to-right") on the stack.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2869,12 +3061,12 @@
   // Record call targets in unoptimized code, but not in the snapshot.
   if (FLAG_pretenuring_call_new) {
     EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
-    DCHECK(expr->AllocationSiteFeedbackSlot() ==
-           expr->CallNewFeedbackSlot() + 1);
+    DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
+           expr->CallNewFeedbackSlot().ToInt() + 1);
   }
 
   __ Move(rbx, FeedbackVector());
-  __ Move(rdx, Smi::FromInt(expr->CallNewFeedbackSlot()));
+  __ Move(rdx, SmiFromSlot(expr->CallNewFeedbackSlot()));
 
   CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
   __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
@@ -3181,6 +3373,31 @@
 }
 
 
+void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(rax, if_false);
+  Register map = rbx;
+  __ movp(map, FieldOperand(rax, HeapObject::kMapOffset));
+  __ CmpInstanceType(map, FIRST_JS_PROXY_TYPE);
+  __ j(less, if_false);
+  __ CmpInstanceType(map, LAST_JS_PROXY_TYPE);
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(less_equal, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
 
 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
   DCHECK(expr->arguments()->length() == 0);
@@ -4146,7 +4363,7 @@
     __ Move(LoadDescriptor::NameRegister(), expr->name());
     if (FLAG_vector_ics) {
       __ Move(VectorLoadICDescriptor::SlotRegister(),
-              Smi::FromInt(expr->CallRuntimeFeedbackSlot()));
+              SmiFromSlot(expr->CallRuntimeFeedbackSlot()));
       CallLoadIC(NOT_CONTEXTUAL);
     } else {
       CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
@@ -4304,17 +4521,8 @@
   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());
 
-  // Expression can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
-  // In case of a property we use the uninitialized expression context
-  // of the key to detect a named property.
-  if (prop != NULL) {
-    assign_type =
-        (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   // Evaluate expression and get value.
   if (assign_type == VARIABLE) {
@@ -4326,18 +4534,50 @@
     if (expr->is_postfix() && !context()->IsEffect()) {
       __ Push(Smi::FromInt(0));
     }
-    if (assign_type == NAMED_PROPERTY) {
-      VisitForStackValue(prop->obj());
-      __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
-      EmitNamedPropertyLoad(prop);
-    } else {
-      VisitForStackValue(prop->obj());
-      VisitForStackValue(prop->key());
-      // Leave receiver on stack
-      __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize));
-      // Copy of key, needed for later store.
-      __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0));
-      EmitKeyedPropertyLoad(prop);
+    switch (assign_type) {
+      case NAMED_PROPERTY: {
+        VisitForStackValue(prop->obj());
+        __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0));
+        EmitNamedPropertyLoad(prop);
+        break;
+      }
+
+      case NAMED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        __ Push(MemOperand(rsp, kPointerSize));
+        __ Push(result_register());
+        EmitNamedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ Push(result_register());
+        VisitForAccumulatorValue(prop->key());
+        __ Push(result_register());
+        __ Push(MemOperand(rsp, 2 * kPointerSize));
+        __ Push(MemOperand(rsp, 2 * kPointerSize));
+        __ Push(result_register());
+        EmitKeyedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_PROPERTY: {
+        VisitForStackValue(prop->obj());
+        VisitForStackValue(prop->key());
+        // Leave receiver on stack
+        __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize));
+        // Copy of key, needed for later store.
+        __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0));
+        EmitKeyedPropertyLoad(prop);
+        break;
+      }
+
+      case VARIABLE:
+        UNREACHABLE();
     }
   }
 
@@ -4369,9 +4609,15 @@
           case NAMED_PROPERTY:
             __ movp(Operand(rsp, kPointerSize), rax);
             break;
+          case NAMED_SUPER_PROPERTY:
+            __ movp(Operand(rsp, 2 * kPointerSize), rax);
+            break;
           case KEYED_PROPERTY:
             __ movp(Operand(rsp, 2 * kPointerSize), rax);
             break;
+          case KEYED_SUPER_PROPERTY:
+            __ movp(Operand(rsp, 3 * kPointerSize), rax);
+            break;
         }
       }
     }
@@ -4404,9 +4650,15 @@
         case NAMED_PROPERTY:
           __ movp(Operand(rsp, kPointerSize), rax);
           break;
+        case NAMED_SUPER_PROPERTY:
+          __ movp(Operand(rsp, 2 * kPointerSize), rax);
+          break;
         case KEYED_PROPERTY:
           __ movp(Operand(rsp, 2 * kPointerSize), rax);
           break;
+        case KEYED_SUPER_PROPERTY:
+          __ movp(Operand(rsp, 3 * kPointerSize), rax);
+          break;
       }
     }
   }
@@ -4463,6 +4715,28 @@
       }
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      EmitNamedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(rax);
+      }
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      EmitKeyedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(rax);
+      }
+      break;
+    }
     case KEYED_PROPERTY: {
       __ Pop(StoreDescriptor::NameRegister());
       __ Pop(StoreDescriptor::ReceiverRegister());
@@ -4494,7 +4768,7 @@
     __ movp(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand());
     if (FLAG_vector_ics) {
       __ Move(VectorLoadICDescriptor::SlotRegister(),
-              Smi::FromInt(proxy->VariableFeedbackSlot()));
+              SmiFromSlot(proxy->VariableFeedbackSlot()));
     }
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
@@ -4728,7 +5002,7 @@
 
 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
   Scope* declaration_scope = scope()->DeclarationScope();
-  if (declaration_scope->is_global_scope() ||
+  if (declaration_scope->is_script_scope() ||
       declaration_scope->is_module_scope()) {
     // Contexts nested in the native context have a canonical empty function
     // as their closure, not the anonymous closure containing the global
diff --git a/src/x64/interface-descriptors-x64.cc b/src/x64/interface-descriptors-x64.cc
index 84fdca4..f19979d 100644
--- a/src/x64/interface-descriptors-x64.cc
+++ b/src/x64/interface-descriptors-x64.cc
@@ -29,6 +29,9 @@
 const Register StoreDescriptor::ValueRegister() { return rax; }
 
 
+const Register StoreTransitionDescriptor::MapRegister() { return rbx; }
+
+
 const Register ElementTransitionAndStoreDescriptor::MapRegister() {
   return rbx;
 }
@@ -152,6 +155,15 @@
 }
 
 
+void AllocateHeapNumberDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  // register state
+  // rsi -- context
+  Register registers[] = {rsi};
+  data->Initialize(arraysize(registers), registers, nullptr);
+}
+
+
 void ArrayConstructorConstantArgCountDescriptor::Initialize(
     CallInterfaceDescriptorData* data) {
   // register state
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 1981d55..10f2bb8 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -30,9 +30,9 @@
         deopt_mode_(mode) { }
   virtual ~SafepointGenerator() {}
 
-  virtual void BeforeCall(int call_size) const OVERRIDE {}
+  void BeforeCall(int call_size) const OVERRIDE {}
 
-  virtual void AfterCall() const OVERRIDE {
+  void AfterCall() const OVERRIDE {
     codegen_->RecordSafepoint(pointers_, deopt_mode_);
   }
 
@@ -2676,10 +2676,10 @@
     DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
                                   LInstanceOfKnownGlobal* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
     Label* map_check() { return &map_check_; }
    private:
     LInstanceOfKnownGlobal* instr_;
@@ -2822,6 +2822,7 @@
     __ Ret((ToInteger32(instr->constant_parameter_count()) + 1) * kPointerSize,
            rcx);
   } else {
+    DCHECK(info()->IsStub());  // Functions would need to drop one more value.
     Register reg = ToRegister(instr->parameter_count());
     // The argument count parameter is a smi
     __ SmiToInteger32(reg, reg);
@@ -2850,13 +2851,18 @@
 template <class T>
 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
   DCHECK(FLAG_vector_ics);
-  Register vector = ToRegister(instr->temp_vector());
-  DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister()));
-  __ Move(vector, instr->hydrogen()->feedback_vector());
+  Register vector_register = ToRegister(instr->temp_vector());
+  Register slot_register = VectorLoadICDescriptor::SlotRegister();
+  DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
+  DCHECK(slot_register.is(rax));
+
+  AllowDeferredHandleDereference vector_structure_check;
+  Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
+  __ Move(vector_register, vector);
   // No need to allocate this register.
-  DCHECK(VectorLoadICDescriptor::SlotRegister().is(rax));
-  __ Move(VectorLoadICDescriptor::SlotRegister(),
-          Smi::FromInt(instr->hydrogen()->slot()));
+  FeedbackVectorICSlot slot = instr->hydrogen()->slot();
+  int index = vector->GetIndex(slot);
+  __ Move(slot_register, Smi::FromInt(index));
 }
 
 
@@ -2871,7 +2877,7 @@
     EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
+  Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -2974,6 +2980,7 @@
 
   Register object = ToRegister(instr->object());
   if (instr->hydrogen()->representation().IsDouble()) {
+    DCHECK(access.IsInobject());
     XMMRegister result = ToDoubleRegister(instr->result());
     __ movsd(result, FieldOperand(object, offset));
     return;
@@ -3013,7 +3020,8 @@
   if (FLAG_vector_ics) {
     EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
+  Handle<Code> ic =
+      CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3272,11 +3280,9 @@
     return Operand(elements_pointer_reg,
                    (constant_value << shift_size) + offset);
   } else {
-    // Take the tag bit into account while computing the shift size.
-    if (key_representation.IsSmi() && (shift_size >= 1)) {
-      DCHECK(SmiValuesAre31Bits());
-      shift_size -= kSmiTagSize;
-    }
+    // Guaranteed by ArrayInstructionInterface::KeyedAccessIndexRequirement().
+    DCHECK(key_representation.IsInteger32());
+
     ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
     return Operand(elements_pointer_reg,
                    ToRegister(key),
@@ -3295,7 +3301,7 @@
     EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
-  Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
+  Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3535,43 +3541,67 @@
   Register name = ToRegister(instr->name());
   DCHECK(receiver.is(LoadDescriptor::ReceiverRegister()));
   DCHECK(name.is(LoadDescriptor::NameRegister()));
-
-  Register scratch = rbx;
+  Register scratch = rdi;
   DCHECK(!scratch.is(receiver) && !scratch.is(name));
+  DCHECK(!FLAG_vector_ics ||
+         !AreAliased(ToRegister(instr->slot()), ToRegister(instr->vector()),
+                     scratch));
 
   // Important for the tail-call.
   bool must_teardown_frame = NeedsEagerFrame();
 
-  // The probe will tail call to a handler if found.
-  isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
-                                         must_teardown_frame, receiver, name,
-                                         scratch, no_reg);
+  if (!instr->hydrogen()->is_just_miss()) {
+    // The probe will tail call to a handler if found.
+    DCHECK(!instr->hydrogen()->is_keyed_load());
+    isolate()->stub_cache()->GenerateProbe(
+        masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
+        receiver, name, scratch, no_reg);
+  }
 
   // Tail call to miss if we ended up here.
   if (must_teardown_frame) __ leave();
-  LoadIC::GenerateMiss(masm());
+  if (instr->hydrogen()->is_keyed_load()) {
+    KeyedLoadIC::GenerateMiss(masm());
+  } else {
+    LoadIC::GenerateMiss(masm());
+  }
 }
 
 
 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
   DCHECK(ToRegister(instr->result()).is(rax));
 
-  LPointerMap* pointers = instr->pointer_map();
-  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+  if (instr->hydrogen()->IsTailCall()) {
+    if (NeedsEagerFrame()) __ leave();
 
-  if (instr->target()->IsConstantOperand()) {
-    LConstantOperand* target = LConstantOperand::cast(instr->target());
-    Handle<Code> code = Handle<Code>::cast(ToHandle(target));
-    generator.BeforeCall(__ CallSize(code));
-    __ call(code, RelocInfo::CODE_TARGET);
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      __ jmp(code, RelocInfo::CODE_TARGET);
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      __ addp(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
+      __ jmp(target);
+    }
   } else {
-    DCHECK(instr->target()->IsRegister());
-    Register target = ToRegister(instr->target());
-    generator.BeforeCall(__ CallSize(target));
-    __ addp(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
-    __ call(target);
+    LPointerMap* pointers = instr->pointer_map();
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      generator.BeforeCall(__ CallSize(code));
+      __ call(code, RelocInfo::CODE_TARGET);
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      generator.BeforeCall(__ CallSize(target));
+      __ addp(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
+      __ call(target);
+    }
+    generator.AfterCall();
   }
-  generator.AfterCall();
 }
 
 
@@ -3680,10 +3710,11 @@
    public:
     DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LMathAbs* instr_;
   };
@@ -4119,7 +4150,7 @@
   DCHECK(!representation.IsSmi() ||
          !instr->value()->IsConstantOperand() ||
          IsInteger32Constant(LConstantOperand::cast(instr->value())));
-  if (representation.IsDouble()) {
+  if (!FLAG_unbox_double_fields && representation.IsDouble()) {
     DCHECK(access.IsInobject());
     DCHECK(!hinstr->has_transition());
     DCHECK(!hinstr->NeedsWriteBarrier());
@@ -4169,7 +4200,12 @@
 
   Operand operand = FieldOperand(write_register, offset);
 
-  if (instr->value()->IsRegister()) {
+  if (FLAG_unbox_double_fields && representation.IsDouble()) {
+    DCHECK(access.IsInobject());
+    XMMRegister value = ToDoubleRegister(instr->value());
+    __ movsd(operand, value);
+
+  } else if (instr->value()->IsRegister()) {
     Register value = ToRegister(instr->value());
     __ Store(operand, value, representation);
   } else {
@@ -4543,10 +4579,9 @@
    public:
     DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredStringCharCodeAt(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredStringCharCodeAt(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStringCharCodeAt* instr_;
   };
@@ -4598,10 +4633,11 @@
    public:
     DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredStringCharFromCode(instr_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStringCharFromCode* instr_;
   };
@@ -4670,11 +4706,12 @@
    public:
     DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(),
                                        instr_->temp2(), SIGNED_INT32);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagI* instr_;
   };
@@ -4700,11 +4737,12 @@
    public:
     DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(),
                                        instr_->temp2(), UNSIGNED_INT32);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagU* instr_;
   };
@@ -4787,10 +4825,9 @@
    public:
     DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredNumberTagD(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredNumberTagD(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagD* instr_;
   };
@@ -4983,10 +5020,9 @@
    public:
     DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredTaggedToI(instr_, done());
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredTaggedToI(instr_, done()); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LTaggedToI* instr_;
   };
@@ -5173,11 +5209,12 @@
         : LDeferredCode(codegen), instr_(instr), object_(object) {
       SetExit(check_maps());
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredInstanceMigration(instr_, object_);
     }
     Label* check_maps() { return &check_maps_; }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LCheckMaps* instr_;
     Label check_maps_;
@@ -5302,10 +5339,9 @@
    public:
     DeferredAllocate(LCodeGen* codegen, LAllocate* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredAllocate(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredAllocate(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LAllocate* instr_;
   };
@@ -5675,10 +5711,9 @@
    public:
     DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr)
         : LDeferredCode(codegen), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredStackCheck(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredStackCheck(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStackCheck* instr_;
   };
@@ -5822,10 +5857,11 @@
           object_(object),
           index_(index) {
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredLoadMutableDouble(instr_, object_, index_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LLoadFieldByIndex* instr_;
     Register object_;
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 69f50b1..c1831af 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <sstream>
+
 #include "src/v8.h"
 
 #if V8_TARGET_ARCH_X64
@@ -360,9 +362,9 @@
 
 void LStoreNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
-  OStringStream os;
+  std::ostringstream os;
   os << hydrogen()->access() << " <- ";
-  stream->Add(os.c_str());
+  stream->Add(os.str().c_str());
   value()->PrintTo(stream);
 }
 
@@ -720,11 +722,7 @@
     // Shift operations can only deoptimize if we do a logical shift by 0 and
     // the result cannot be truncated to int32.
     if (op == Token::SHR && constant_value == 0) {
-      if (FLAG_opt_safe_uint32_operations) {
-        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-      } else {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
-      }
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
     }
 
     LInstruction* result =
@@ -1120,9 +1118,17 @@
       UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
   LOperand* name_register =
       UseFixed(instr->name(), LoadDescriptor::NameRegister());
+  LOperand* slot = NULL;
+  LOperand* vector = NULL;
+  if (FLAG_vector_ics) {
+    slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
+    vector =
+        UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
+  }
+
   // Not marked as call. It can't deoptimize, and it never returns.
   return new (zone()) LTailCallThroughMegamorphicCache(
-      context, receiver_register, name_register);
+      context, receiver_register, name_register, slot, vector);
 }
 
 
@@ -2069,7 +2075,7 @@
   LOperand* global_object =
       UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
@@ -2142,7 +2148,7 @@
   LOperand* object =
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
   LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(
@@ -2235,7 +2241,7 @@
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 30b994e..8b7a5bc 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -163,17 +163,13 @@
   V(WrapReceiver)
 
 
-#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)                        \
-  virtual Opcode opcode() const FINAL OVERRIDE {                      \
-    return LInstruction::k##type;                                           \
-  }                                                                         \
-  virtual void CompileToNative(LCodeGen* generator) FINAL OVERRIDE;   \
-  virtual const char* Mnemonic() const FINAL OVERRIDE {               \
-    return mnemonic;                                                        \
-  }                                                                         \
-  static L##type* cast(LInstruction* instr) {                               \
-    DCHECK(instr->Is##type());                                              \
-    return reinterpret_cast<L##type*>(instr);                               \
+#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)            \
+  Opcode opcode() const FINAL { return LInstruction::k##type; } \
+  void CompileToNative(LCodeGen* generator) FINAL;              \
+  const char* Mnemonic() const FINAL { return mnemonic; }       \
+  static L##type* cast(LInstruction* instr) {                   \
+    DCHECK(instr->Is##type());                                  \
+    return reinterpret_cast<L##type*>(instr);                   \
   }
 
 
@@ -292,14 +288,11 @@
  public:
   // Allow 0 or 1 output operands.
   STATIC_ASSERT(R == 0 || R == 1);
-  virtual bool HasResult() const FINAL OVERRIDE {
-    return R != 0 && result() != NULL;
-  }
+  bool HasResult() const FINAL { return R != 0 && result() != NULL; }
   void set_result(LOperand* operand) { results_[0] = operand; }
-  LOperand* result() const { return results_[0]; }
+  LOperand* result() const OVERRIDE { return results_[0]; }
 
-  virtual bool MustSignExtendResult(
-      LPlatformChunk* chunk) const FINAL OVERRIDE;
+  bool MustSignExtendResult(LPlatformChunk* chunk) const FINAL;
 
  protected:
   EmbeddedContainer<LOperand*, R> results_;
@@ -317,11 +310,11 @@
 
  private:
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return I; }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return I; }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return T; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return temps_[i]; }
+  int TempCount() FINAL { return T; }
+  LOperand* TempAt(int i) FINAL { return temps_[i]; }
 };
 
 
@@ -336,8 +329,8 @@
   }
 
   // Can't use the DECLARE-macro here because of sub-classes.
-  virtual bool IsGap() const FINAL OVERRIDE { return true; }
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsGap() const FINAL { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   static LGap* cast(LInstruction* instr) {
     DCHECK(instr->IsGap());
     return reinterpret_cast<LGap*>(instr);
@@ -378,7 +371,7 @@
  public:
   explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
     return !IsRedundant();
   }
 
@@ -390,10 +383,10 @@
  public:
   explicit LGoto(HBasicBlock* block) : block_(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
-  virtual bool IsControl() const OVERRIDE { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsControl() const OVERRIDE { return true; }
 
   int block_id() const { return block_->block_id(); }
 
@@ -436,7 +429,7 @@
 
 class LDeoptimize FINAL : public LTemplateInstruction<0, 0, 0> {
  public:
-  virtual bool IsControl() const OVERRIDE { return true; }
+  bool IsControl() const OVERRIDE { return true; }
   DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
   DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
 };
@@ -447,12 +440,10 @@
   explicit LLabel(HBasicBlock* block)
       : LGap(block), replacement_(NULL) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Label, "label")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int block_id() const { return block()->block_id(); }
   bool is_loop_header() const { return block()->IsLoopHeader(); }
@@ -470,9 +461,7 @@
 
 class LParameter FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
 };
 
@@ -491,19 +480,23 @@
 
 
 class LTailCallThroughMegamorphicCache FINAL
-    : public LTemplateInstruction<0, 3, 0> {
+    : public LTemplateInstruction<0, 5, 0> {
  public:
   explicit LTailCallThroughMegamorphicCache(LOperand* context,
-                                            LOperand* receiver,
-                                            LOperand* name) {
+                                            LOperand* receiver, LOperand* name,
+                                            LOperand* slot, LOperand* vector) {
     inputs_[0] = context;
     inputs_[1] = receiver;
     inputs_[2] = name;
+    inputs_[3] = slot;
+    inputs_[4] = vector;
   }
 
   LOperand* context() { return inputs_[0]; }
   LOperand* receiver() { return inputs_[1]; }
   LOperand* name() { return inputs_[2]; }
+  LOperand* slot() { return inputs_[3]; }
+  LOperand* vector() { return inputs_[4]; }
 
   DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
                                "tail-call-through-megamorphic-cache")
@@ -513,9 +506,7 @@
 
 class LUnknownOSRValue FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
 };
 
@@ -525,7 +516,7 @@
  public:
   LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
 
-  virtual bool IsControl() const FINAL OVERRIDE { return true; }
+  bool IsControl() const FINAL { return true; }
 
   int SuccessorCount() { return hydrogen()->SuccessorCount(); }
   HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
@@ -614,7 +605,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -855,7 +846,7 @@
     return hydrogen()->representation().IsDouble();
   }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1030,7 +1021,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsObjectAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1047,7 +1038,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1062,7 +1053,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1080,7 +1071,7 @@
                                "is-undetectable-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1102,7 +1093,7 @@
                                "string-compare-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Token::Value op() const { return hydrogen()->token(); }
 };
@@ -1120,7 +1111,7 @@
                                "has-instance-type-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1150,7 +1141,7 @@
                                "has-cached-array-index-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndexAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1170,7 +1161,7 @@
                                "class-of-test-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1376,7 +1367,7 @@
   DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
   DECLARE_HYDROGEN_ACCESSOR(Branch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1528,11 +1519,9 @@
   LOperand* left() { return inputs_[0]; }
   LOperand* right() { return inputs_[1]; }
 
-  virtual Opcode opcode() const OVERRIDE {
-    return LInstruction::kArithmeticD;
-  }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticD; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
  private:
   Token::Value op_;
@@ -1556,11 +1545,9 @@
   LOperand* left() { return inputs_[1]; }
   LOperand* right() { return inputs_[2]; }
 
-  virtual Opcode opcode() const OVERRIDE {
-    return LInstruction::kArithmeticT;
-  }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticT; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
  private:
   Token::Value op_;
@@ -1686,7 +1673,7 @@
   }
   LOperand* elements() { return inputs_[0]; }
   LOperand* key() { return inputs_[1]; }
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   uint32_t base_offset() const { return hydrogen()->base_offset(); }
   ElementsKind elements_kind() const {
     return hydrogen()->elements_kind();
@@ -1770,7 +1757,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1791,7 +1778,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1830,7 +1817,7 @@
   LOperand* function() { return inputs_[0]; }
   LOperand* code_object() { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
   DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
@@ -1847,7 +1834,7 @@
   LOperand* base_object() const { return inputs_[0]; }
   LOperand* offset() const { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
 };
@@ -1891,7 +1878,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
   DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1913,18 +1900,18 @@
  private:
   DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 
   ZoneList<LOperand*> inputs_;
 
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return inputs_.length(); }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return inputs_.length(); }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return 0; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return NULL; }
+  int TempCount() FINAL { return 0; }
+  LOperand* TempAt(int i) FINAL { return NULL; }
 };
 
 
@@ -1941,7 +1928,7 @@
   DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
   DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1976,7 +1963,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
   DECLARE_HYDROGEN_ACCESSOR(CallNew)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1995,7 +1982,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
   DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -2012,7 +1999,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
   DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
 
-  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
+  bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
     return save_doubles() == kDontSaveFPRegs;
   }
 
@@ -2198,7 +2185,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Representation representation() const {
     return hydrogen()->field_representation();
@@ -2221,7 +2208,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Handle<Object> name() const { return hydrogen()->name(); }
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
@@ -2251,7 +2238,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
   uint32_t base_offset() const { return hydrogen()->base_offset(); }
 };
@@ -2277,7 +2264,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
@@ -2304,7 +2291,7 @@
                                "transition-elements-kind")
   DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
   Handle<Map> transitioned_map() {
@@ -2593,7 +2580,7 @@
 
   Handle<String> type_literal() { return hydrogen()->type_literal(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -2615,9 +2602,7 @@
  public:
   LOsrEntry() {}
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
 };
 
@@ -2827,7 +2812,7 @@
 
   // An input operand in register, stack slot or a constant operand.
   // Will not be moved to a register even if one is freely available.
-  virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
+  MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
 
   // Temporary operand that must be in a register.
   MUST_USE_RESULT LUnallocated* TempRegister();
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 5033303..5b897de 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -2743,6 +2743,57 @@
 }
 
 
+void MacroAssembler::Move(XMMRegister dst, uint32_t src) {
+  if (src == 0) {
+    xorps(dst, dst);
+  } else {
+    unsigned cnt = base::bits::CountPopulation32(src);
+    unsigned nlz = base::bits::CountLeadingZeros32(src);
+    unsigned ntz = base::bits::CountTrailingZeros32(src);
+    if (nlz + cnt + ntz == 32) {
+      pcmpeqd(dst, dst);
+      if (ntz == 0) {
+        psrld(dst, 32 - cnt);
+      } else {
+        pslld(dst, 32 - cnt);
+        if (nlz != 0) psrld(dst, nlz);
+      }
+    } else {
+      movl(kScratchRegister, Immediate(src));
+      movq(dst, kScratchRegister);
+    }
+  }
+}
+
+
+void MacroAssembler::Move(XMMRegister dst, uint64_t src) {
+  uint32_t lower = static_cast<uint32_t>(src);
+  uint32_t upper = static_cast<uint32_t>(src >> 32);
+  if (upper == 0) {
+    Move(dst, lower);
+  } else {
+    unsigned cnt = base::bits::CountPopulation64(src);
+    unsigned nlz = base::bits::CountLeadingZeros64(src);
+    unsigned ntz = base::bits::CountTrailingZeros64(src);
+    if (nlz + cnt + ntz == 64) {
+      pcmpeqd(dst, dst);
+      if (ntz == 0) {
+        psrlq(dst, 64 - cnt);
+      } else {
+        psllq(dst, 64 - cnt);
+        if (nlz != 0) psrlq(dst, nlz);
+      }
+    } else if (lower == 0) {
+      Move(dst, upper);
+      psllq(dst, 32);
+    } else {
+      movq(kScratchRegister, src);
+      movq(dst, kScratchRegister);
+    }
+  }
+}
+
+
 void MacroAssembler::Cmp(Register dst, Handle<Object> source) {
   AllowDeferredHandleDereference smi_check;
   if (source->IsSmi()) {
@@ -2801,6 +2852,21 @@
 }
 
 
+void MacroAssembler::CmpWeakValue(Register value, Handle<WeakCell> cell,
+                                  Register scratch) {
+  Move(scratch, cell, RelocInfo::EMBEDDED_OBJECT);
+  cmpp(value, FieldOperand(scratch, WeakCell::kValueOffset));
+}
+
+
+void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell,
+                                   Label* miss) {
+  Move(value, cell, RelocInfo::EMBEDDED_OBJECT);
+  movp(value, FieldOperand(value, WeakCell::kValueOffset));
+  JumpIfSmi(value, miss);
+}
+
+
 void MacroAssembler::Drop(int stack_elements) {
   if (stack_elements > 0) {
     addp(rsp, Immediate(stack_elements * kPointerSize));
@@ -3564,18 +3630,17 @@
 }
 
 
-void MacroAssembler::DispatchMap(Register obj,
-                                 Register unused,
-                                 Handle<Map> map,
-                                 Handle<Code> success,
-                                 SmiCheckType smi_check_type) {
+void MacroAssembler::DispatchWeakMap(Register obj, Register scratch1,
+                                     Register scratch2, Handle<WeakCell> cell,
+                                     Handle<Code> success,
+                                     SmiCheckType smi_check_type) {
   Label fail;
   if (smi_check_type == DO_SMI_CHECK) {
     JumpIfSmi(obj, &fail);
   }
-  Cmp(FieldOperand(obj, HeapObject::kMapOffset), map);
+  movq(scratch1, FieldOperand(obj, HeapObject::kMapOffset));
+  CmpWeakValue(scratch1, cell, scratch2);
   j(equal, success, RelocInfo::CODE_TARGET);
-
   bind(&fail);
 }
 
@@ -3984,6 +4049,13 @@
 }
 
 
+void MacroAssembler::EnterFrame(StackFrame::Type type,
+                                bool load_constant_pool_pointer_reg) {
+  // Out-of-line constant pool not implemented on x64.
+  UNREACHABLE();
+}
+
+
 void MacroAssembler::EnterFrame(StackFrame::Type type) {
   pushq(rbp);
   movp(rbp, rsp);
@@ -4035,6 +4107,7 @@
 
   Store(ExternalReference(Isolate::kCEntryFPAddress, isolate()), rbp);
   Store(ExternalReference(Isolate::kContextAddress, isolate()), rsi);
+  Store(ExternalReference(Isolate::kCFunctionAddress, isolate()), rbx);
 }
 
 
@@ -4308,10 +4381,10 @@
   }
 
   bind(&done);
-  // Check that the value is a normal propety.
+  // Check that the value is a field property.
   const int kDetailsOffset =
       SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
-  DCHECK_EQ(NORMAL, 0);
+  DCHECK_EQ(FIELD, 0);
   Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
        Smi::FromInt(PropertyDetails::TypeField::kMask));
   j(not_zero, miss);
@@ -5054,18 +5127,6 @@
 }
 
 
-void MacroAssembler::CheckMapDeprecated(Handle<Map> map,
-                                        Register scratch,
-                                        Label* if_deprecated) {
-  if (map->CanBeDeprecated()) {
-    Move(scratch, map);
-    movl(scratch, FieldOperand(scratch, Map::kBitField3Offset));
-    andl(scratch, Immediate(Map::Deprecated::kMask));
-    j(not_zero, if_deprecated);
-  }
-}
-
-
 void MacroAssembler::JumpIfBlack(Register object,
                                  Register bitmap_scratch,
                                  Register mask_scratch,
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index d051773..4656665 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -175,10 +175,6 @@
                      Label* condition_met,
                      Label::Distance condition_met_distance = Label::kFar);
 
-  void CheckMapDeprecated(Handle<Map> map,
-                          Register scratch,
-                          Label* if_deprecated);
-
   // Check if object is in new space.  Jumps if the object is not in new space.
   // The register scratch can be object itself, but scratch will be clobbered.
   void JumpIfNotInNewSpace(Register object,
@@ -847,6 +843,13 @@
   // Load a global cell into a register.
   void LoadGlobalCell(Register dst, Handle<Cell> cell);
 
+  // Compare the given value and the value of weak cell.
+  void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch);
+
+  // Load the value of the weak cell in the value register. Branch to the given
+  // miss label if the weak cell was cleared.
+  void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss);
+
   // Emit code to discard a non-negative number of pointer-sized elements
   // from the stack, clobbering only the rsp register.
   void Drop(int stack_elements);
@@ -888,6 +891,9 @@
     movp(dst, reinterpret_cast<void*>(value.location()), rmode);
   }
 
+  void Move(XMMRegister dst, uint32_t src);
+  void Move(XMMRegister dst, uint64_t src);
+
   // Control Flow
   void Jump(Address destination, RelocInfo::Mode rmode);
   void Jump(ExternalReference ext);
@@ -986,14 +992,12 @@
                 Label* fail,
                 SmiCheckType smi_check_type);
 
-  // Check if the map of an object is equal to a specified map and branch to a
-  // specified target if equal. Skip the smi check if not required (object is
-  // known to be a heap object)
-  void DispatchMap(Register obj,
-                   Register unused,
-                   Handle<Map> map,
-                   Handle<Code> success,
-                   SmiCheckType smi_check_type);
+  // Check if the map of an object is equal to a specified weak map and branch
+  // to a specified target if equal. Skip the smi check if not required
+  // (object is known to be a heap object)
+  void DispatchWeakMap(Register obj, Register scratch1, Register scratch2,
+                       Handle<WeakCell> cell, Handle<Code> success,
+                       SmiCheckType smi_check_type);
 
   // Check if the object in register heap_object is a string. Afterwards the
   // register map contains the object map and the register instance_type
@@ -1438,6 +1442,7 @@
 
   // Activation support.
   void EnterFrame(StackFrame::Type type);
+  void EnterFrame(StackFrame::Type type, bool load_constant_pool_pointer_reg);
   void LeaveFrame(StackFrame::Type type);
 
   // Expects object in rax and returns map with validated enum cache
diff --git a/src/x87/assembler-x87.cc b/src/x87/assembler-x87.cc
index 9e1c883..4177156 100644
--- a/src/x87/assembler-x87.cc
+++ b/src/x87/assembler-x87.cc
@@ -915,24 +915,24 @@
 }
 
 
-void Assembler::ror(Register dst, uint8_t imm8) {
+void Assembler::ror(const Operand& dst, uint8_t imm8) {
   EnsureSpace ensure_space(this);
   DCHECK(is_uint5(imm8));  // illegal shift count
   if (imm8 == 1) {
     EMIT(0xD1);
-    EMIT(0xC8 | dst.code());
+    emit_operand(ecx, dst);
   } else {
     EMIT(0xC1);
-    EMIT(0xC8 | dst.code());
+    emit_operand(ecx, dst);
     EMIT(imm8);
   }
 }
 
 
-void Assembler::ror_cl(Register dst) {
+void Assembler::ror_cl(const Operand& dst) {
   EnsureSpace ensure_space(this);
   EMIT(0xD3);
-  EMIT(0xC8 | dst.code());
+  emit_operand(ecx, dst);
 }
 
 
@@ -1897,11 +1897,6 @@
 }
 
 
-void Assembler::Print() {
-  Disassembler::Decode(isolate(), stdout, buffer_, pc_);
-}
-
-
 void Assembler::RecordJSReturn() {
   positions_recorder()->WriteRecordedPositions();
   EnsureSpace ensure_space(this);
diff --git a/src/x87/assembler-x87.h b/src/x87/assembler-x87.h
index d37c9d7..1da632f 100644
--- a/src/x87/assembler-x87.h
+++ b/src/x87/assembler-x87.h
@@ -148,6 +148,13 @@
     return kMaxNumAllocatableRegisters;
   }
 
+
+  // TODO(turbofan): Proper support for float32.
+  static int NumAllocatableAliasedRegisters() {
+    return NumAllocatableRegisters();
+  }
+
+
   static int ToAllocationIndex(X87Register reg) {
     return reg.code_;
   }
@@ -718,8 +725,11 @@
 
   void rcl(Register dst, uint8_t imm8);
   void rcr(Register dst, uint8_t imm8);
-  void ror(Register dst, uint8_t imm8);
-  void ror_cl(Register dst);
+
+  void ror(Register dst, uint8_t imm8) { ror(Operand(dst), imm8); }
+  void ror(const Operand& dst, uint8_t imm8);
+  void ror_cl(Register dst) { ror_cl(Operand(dst)); }
+  void ror_cl(const Operand& dst);
 
   void sar(Register dst, uint8_t imm8) { sar(Operand(dst), imm8); }
   void sar(const Operand& dst, uint8_t imm8);
@@ -909,9 +919,6 @@
 
   // TODO(lrn): Need SFENCE for movnt?
 
-  // Debugging
-  void Print();
-
   // Check the code size generated from label to here.
   int SizeOfCodeGeneratedSince(Label* label) {
     return pc_offset() - label->pos();
diff --git a/src/x87/builtins-x87.cc b/src/x87/builtins-x87.cc
index d631175..51bb3a7 100644
--- a/src/x87/builtins-x87.cc
+++ b/src/x87/builtins-x87.cc
@@ -160,18 +160,17 @@
       if (!is_api_function) {
         Label allocate;
         // The code below relies on these assumptions.
-        STATIC_ASSERT(JSFunction::kNoSlackTracking == 0);
-        STATIC_ASSERT(Map::ConstructionCount::kShift +
-                      Map::ConstructionCount::kSize == 32);
+        STATIC_ASSERT(Map::Counter::kShift + Map::Counter::kSize == 32);
         // Check if slack tracking is enabled.
         __ mov(esi, FieldOperand(eax, Map::kBitField3Offset));
-        __ shr(esi, Map::ConstructionCount::kShift);
-        __ j(zero, &allocate);  // JSFunction::kNoSlackTracking
+        __ shr(esi, Map::Counter::kShift);
+        __ cmp(esi, Map::kSlackTrackingCounterEnd);
+        __ j(less, &allocate);
         // Decrease generous allocation count.
         __ sub(FieldOperand(eax, Map::kBitField3Offset),
-               Immediate(1 << Map::ConstructionCount::kShift));
+               Immediate(1 << Map::Counter::kShift));
 
-        __ cmp(esi, JSFunction::kFinishSlackTracking);
+        __ cmp(esi, Map::kSlackTrackingCounterEnd);
         __ j(not_equal, &allocate);
 
         __ push(eax);
@@ -182,7 +181,7 @@
 
         __ pop(edi);
         __ pop(eax);
-        __ xor_(esi, esi);  // JSFunction::kNoSlackTracking
+        __ mov(esi, Map::kSlackTrackingCounterEnd - 1);
 
         __ bind(&allocate);
       }
@@ -219,8 +218,8 @@
         Label no_inobject_slack_tracking;
 
         // Check if slack tracking is enabled.
-        __ cmp(esi, JSFunction::kNoSlackTracking);
-        __ j(equal, &no_inobject_slack_tracking);
+        __ cmp(esi, Map::kSlackTrackingCounterEnd);
+        __ j(less, &no_inobject_slack_tracking);
 
         // Allocate object with a slack.
         __ movzx_b(esi,
@@ -1002,17 +1001,21 @@
     __ bind(&loop);
     __ mov(receiver, Operand(ebp, kArgumentsOffset));  // load arguments
 
-    // Use inline caching to speed up access to arguments.
     if (FLAG_vector_ics) {
-      __ mov(VectorLoadICDescriptor::SlotRegister(),
-             Immediate(Smi::FromInt(0)));
+      // TODO(mvstanton): Vector-based ics need additional infrastructure to
+      // be embedded here. For now, just call the runtime.
+      __ push(receiver);
+      __ push(key);
+      __ CallRuntime(Runtime::kGetProperty, 2);
+    } else {
+      // Use inline caching to speed up access to arguments.
+      Handle<Code> ic = CodeFactory::KeyedLoadIC(masm->isolate()).code();
+      __ call(ic, RelocInfo::CODE_TARGET);
+      // It is important that we do not have a test instruction after the
+      // call.  A test instruction after the call is used to indicate that
+      // we have generated an inline version of the keyed load.  In this
+      // case, we know that we are not generating a test instruction next.
     }
-    Handle<Code> ic = CodeFactory::KeyedLoadIC(masm->isolate()).code();
-    __ call(ic, RelocInfo::CODE_TARGET);
-    // It is important that we do not have a test instruction after the
-    // call.  A test instruction after the call is used to indicate that
-    // we have generated an inline version of the keyed load.  In this
-    // case, we know that we are not generating a test instruction next.
 
     // Push the nth argument.
     __ push(eax);
diff --git a/src/x87/code-stubs-x87.cc b/src/x87/code-stubs-x87.cc
index d4c383b..1264dd9 100644
--- a/src/x87/code-stubs-x87.cc
+++ b/src/x87/code-stubs-x87.cc
@@ -15,7 +15,7 @@
 #include "src/isolate.h"
 #include "src/jsregexp.h"
 #include "src/regexp-macro-assembler.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 
 namespace v8 {
 namespace internal {
@@ -333,8 +333,19 @@
   Label miss;
   Register receiver = LoadDescriptor::ReceiverRegister();
 
-  NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, eax,
-                                                          ebx, &miss);
+  if (FLAG_vector_ics) {
+    // With careful management, we won't have to save slot and vector on
+    // the stack. Simply handle the possibly missing case first.
+    // TODO(mvstanton): this code can be more efficient.
+    __ cmp(FieldOperand(receiver, JSFunction::kPrototypeOrInitialMapOffset),
+           Immediate(isolate()->factory()->the_hole_value()));
+    __ j(equal, &miss);
+    __ TryGetFunctionPrototype(receiver, eax, ebx, &miss);
+    __ ret(0);
+  } else {
+    NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(masm, receiver, eax,
+                                                            ebx, &miss);
+  }
   __ bind(&miss);
   PropertyAccessCompiler::TailCallBuiltin(
       masm, PropertyAccessCompiler::MissBuiltin(Code::LOAD_IC));
@@ -371,6 +382,42 @@
 }
 
 
+void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
+  // Return address is on the stack.
+  Label miss;
+
+  Register receiver = LoadDescriptor::ReceiverRegister();
+  Register index = LoadDescriptor::NameRegister();
+  Register scratch = edi;
+  DCHECK(!scratch.is(receiver) && !scratch.is(index));
+  Register result = eax;
+  DCHECK(!result.is(scratch));
+  DCHECK(!FLAG_vector_ics ||
+         (!scratch.is(VectorLoadICDescriptor::VectorRegister()) &&
+          result.is(VectorLoadICDescriptor::SlotRegister())));
+
+  // StringCharAtGenerator doesn't use the result register until it's passed
+  // the different miss possibilities. If it did, we would have a conflict
+  // when FLAG_vector_ics is true.
+
+  StringCharAtGenerator char_at_generator(receiver, index, scratch, result,
+                                          &miss,  // When not a string.
+                                          &miss,  // When not a number.
+                                          &miss,  // When index out of range.
+                                          STRING_INDEX_IS_ARRAY_INDEX,
+                                          RECEIVER_IS_STRING);
+  char_at_generator.GenerateFast(masm);
+  __ ret(0);
+
+  StubRuntimeCallHelper call_helper;
+  char_at_generator.GenerateSlow(masm, call_helper);
+
+  __ bind(&miss);
+  PropertyAccessCompiler::TailCallBuiltin(
+      masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC));
+}
+
+
 void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
   // The key is in edx and the parameter count is in eax.
   DCHECK(edx.is(ArgumentsAccessReadDescriptor::index()));
@@ -1871,6 +1918,10 @@
   // edi - function
   // edx - slot id
   Isolate* isolate = masm->isolate();
+  const int with_types_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
+  const int generic_offset =
+      FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
   Label extra_checks_or_miss, slow_start;
   Label slow, non_function, wrap, cont;
   Label have_js_function;
@@ -1910,28 +1961,66 @@
   }
 
   __ bind(&extra_checks_or_miss);
-  Label miss;
+  Label uninitialized, miss;
 
   __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
                            FixedArray::kHeaderSize));
   __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
   __ j(equal, &slow_start);
-  __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate)));
-  __ j(equal, &miss);
 
-  if (!FLAG_trace_ic) {
-    // We are going megamorphic. If the feedback is a JSFunction, it is fine
-    // to handle it here. More complex cases are dealt with in the runtime.
-    __ AssertNotSmi(ecx);
-    __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
-    __ j(not_equal, &miss);
-    __ mov(FieldOperand(ebx, edx, times_half_pointer_size,
-                        FixedArray::kHeaderSize),
-           Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
-    __ jmp(&slow_start);
+  // The following cases attempt to handle MISS cases without going to the
+  // runtime.
+  if (FLAG_trace_ic) {
+    __ jmp(&miss);
   }
 
-  // We are here because tracing is on or we are going monomorphic.
+  __ cmp(ecx, Immediate(TypeFeedbackVector::UninitializedSentinel(isolate)));
+  __ j(equal, &uninitialized);
+
+  // We are going megamorphic. If the feedback is a JSFunction, it is fine
+  // to handle it here. More complex cases are dealt with in the runtime.
+  __ AssertNotSmi(ecx);
+  __ CmpObjectType(ecx, JS_FUNCTION_TYPE, ecx);
+  __ j(not_equal, &miss);
+  __ mov(
+      FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize),
+      Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
+  // We have to update statistics for runtime profiling.
+  __ sub(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1)));
+  __ add(FieldOperand(ebx, generic_offset), Immediate(Smi::FromInt(1)));
+  __ jmp(&slow_start);
+
+  __ bind(&uninitialized);
+
+  // We are going monomorphic, provided we actually have a JSFunction.
+  __ JumpIfSmi(edi, &miss);
+
+  // Goto miss case if we do not have a function.
+  __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
+  __ j(not_equal, &miss);
+
+  // Make sure the function is not the Array() function, which requires special
+  // behavior on MISS.
+  __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx);
+  __ cmp(edi, ecx);
+  __ j(equal, &miss);
+
+  // Update stats.
+  __ add(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1)));
+
+  // Store the function.
+  __ mov(
+      FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize),
+      edi);
+
+  // Update the write barrier.
+  __ mov(eax, edi);
+  __ RecordWriteArray(ebx, eax, edx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
+                      OMIT_SMI_CHECK);
+  __ jmp(&have_js_function);
+
+  // We are here because tracing is on or we encountered a MISS case we can't
+  // handle here.
   __ bind(&miss);
   GenerateMiss(masm);
 
@@ -2437,18 +2526,18 @@
 
 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
   // If the receiver is a smi trigger the non-string case.
-  STATIC_ASSERT(kSmiTag == 0);
-  __ JumpIfSmi(object_, receiver_not_string_);
+  if (check_mode_ == RECEIVER_IS_UNKNOWN) {
+    __ JumpIfSmi(object_, receiver_not_string_);
 
-  // Fetch the instance type of the receiver into result register.
-  __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
-  __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
-  // If the receiver is not a string trigger the non-string case.
-  __ test(result_, Immediate(kIsNotStringMask));
-  __ j(not_zero, receiver_not_string_);
+    // Fetch the instance type of the receiver into result register.
+    __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset));
+    __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset));
+    // If the receiver is not a string trigger the non-string case.
+    __ test(result_, Immediate(kIsNotStringMask));
+    __ j(not_zero, receiver_not_string_);
+  }
 
   // If the index is non-smi trigger the non-smi case.
-  STATIC_ASSERT(kSmiTag == 0);
   __ JumpIfNotSmi(index_, &index_not_smi_);
   __ bind(&got_smi_index_);
 
@@ -2817,14 +2906,61 @@
   // ebx: instance type
   // ecx: sub string length (smi)
   // edx: from index (smi)
-  StringCharAtGenerator generator(
-      eax, edx, ecx, eax, &runtime, &runtime, &runtime, STRING_INDEX_IS_NUMBER);
+  StringCharAtGenerator generator(eax, edx, ecx, eax, &runtime, &runtime,
+                                  &runtime, STRING_INDEX_IS_NUMBER,
+                                  RECEIVER_IS_STRING);
   generator.GenerateFast(masm);
   __ ret(3 * kPointerSize);
   generator.SkipSlow(masm, &runtime);
 }
 
 
+void ToNumberStub::Generate(MacroAssembler* masm) {
+  // The ToNumber stub takes one argument in eax.
+  Label not_smi;
+  __ JumpIfNotSmi(eax, &not_smi, Label::kNear);
+  __ Ret();
+  __ bind(&not_smi);
+
+  Label not_heap_number;
+  __ CompareMap(eax, masm->isolate()->factory()->heap_number_map());
+  __ j(not_equal, &not_heap_number, Label::kNear);
+  __ Ret();
+  __ bind(&not_heap_number);
+
+  Label not_string, slow_string;
+  __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, edi);
+  // eax: object
+  // edi: object map
+  __ j(above_equal, &not_string, Label::kNear);
+  // Check if string has a cached array index.
+  __ test(FieldOperand(eax, String::kHashFieldOffset),
+          Immediate(String::kContainsCachedArrayIndexMask));
+  __ j(not_zero, &slow_string, Label::kNear);
+  __ mov(eax, FieldOperand(eax, String::kHashFieldOffset));
+  __ IndexFromHash(eax, eax);
+  __ Ret();
+  __ bind(&slow_string);
+  __ pop(ecx);   // Pop return address.
+  __ push(eax);  // Push argument.
+  __ push(ecx);  // Push return address.
+  __ TailCallRuntime(Runtime::kStringToNumber, 1, 1);
+  __ bind(&not_string);
+
+  Label not_oddball;
+  __ CmpInstanceType(edi, ODDBALL_TYPE);
+  __ j(not_equal, &not_oddball, Label::kNear);
+  __ mov(eax, FieldOperand(eax, Oddball::kToNumberOffset));
+  __ Ret();
+  __ bind(&not_oddball);
+
+  __ pop(ecx);   // Pop return address.
+  __ push(eax);  // Push argument.
+  __ push(ecx);  // Push return address.
+  __ InvokeBuiltin(Builtins::TO_NUMBER, JUMP_FUNCTION);
+}
+
+
 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm,
                                                    Register left,
                                                    Register right,
diff --git a/src/x87/code-stubs-x87.h b/src/x87/code-stubs-x87.h
index 03ff477..a079b6f 100644
--- a/src/x87/code-stubs-x87.h
+++ b/src/x87/code-stubs-x87.h
@@ -76,7 +76,7 @@
                                      Register r0,
                                      Register r1);
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
  private:
   static const int kInlinedProbes = 4;
@@ -139,7 +139,7 @@
     INCREMENTAL_COMPACTION
   };
 
-  virtual bool SometimesSetsUpAFrame() { return false; }
+  bool SometimesSetsUpAFrame() OVERRIDE { return false; }
 
   static const byte kTwoByteNopInstruction = 0x3c;  // Cmpb al, #imm8.
   static const byte kTwoByteJumpInstruction = 0xeb;  // Jmp #imm8.
@@ -328,9 +328,9 @@
     kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
   };
 
-  virtual inline Major MajorKey() const FINAL OVERRIDE { return RecordWrite; }
+  inline Major MajorKey() const FINAL { return RecordWrite; }
 
-  virtual void Generate(MacroAssembler* masm) OVERRIDE;
+  void Generate(MacroAssembler* masm) OVERRIDE;
   void GenerateIncremental(MacroAssembler* masm, Mode mode);
   void CheckNeedsToInformIncrementalMarker(
       MacroAssembler* masm,
@@ -338,7 +338,7 @@
       Mode mode);
   void InformIncrementalMarker(MacroAssembler* masm);
 
-  void Activate(Code* code) {
+  void Activate(Code* code) OVERRIDE {
     code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
   }
 
diff --git a/src/x87/codegen-x87.cc b/src/x87/codegen-x87.cc
index e33959e..1321461 100644
--- a/src/x87/codegen-x87.cc
+++ b/src/x87/codegen-x87.cc
@@ -380,6 +380,19 @@
   __ mov(FieldOperand(eax, FixedArray::kLengthOffset), ebx);
   __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
 
+  // Allocating heap numbers in the loop below can fail and cause a jump to
+  // gc_required. We can't leave a partly initialized FixedArray behind,
+  // so pessimistically fill it with holes now.
+  Label initialization_loop, initialization_loop_entry;
+  __ jmp(&initialization_loop_entry, Label::kNear);
+  __ bind(&initialization_loop);
+  __ mov(FieldOperand(eax, ebx, times_2, FixedArray::kHeaderSize),
+         masm->isolate()->factory()->the_hole_value());
+  __ bind(&initialization_loop_entry);
+  __ sub(ebx, Immediate(Smi::FromInt(1)));
+  __ j(not_sign, &initialization_loop);
+
+  __ mov(ebx, FieldOperand(edi, FixedDoubleArray::kLengthOffset));
   __ jmp(&entry);
 
   // ebx: target map
diff --git a/src/x87/debug-x87.cc b/src/x87/debug-x87.cc
index 92c23ab..cdbcbad 100644
--- a/src/x87/debug-x87.cc
+++ b/src/x87/debug-x87.cc
@@ -182,7 +182,11 @@
   // Register state for IC load call (from ic-x87.cc).
   Register receiver = LoadDescriptor::ReceiverRegister();
   Register name = LoadDescriptor::NameRegister();
-  Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false);
+  RegList regs = receiver.bit() | name.bit();
+  if (FLAG_vector_ics) {
+    regs |= VectorLoadICTrampolineDescriptor::SlotRegister().bit();
+  }
+  Generate_DebugBreakCallHelper(masm, regs, 0, false);
 }
 
 
diff --git a/src/x87/deoptimizer-x87.cc b/src/x87/deoptimizer-x87.cc
index a76c7a7..0e53a0e 100644
--- a/src/x87/deoptimizer-x87.cc
+++ b/src/x87/deoptimizer-x87.cc
@@ -27,7 +27,7 @@
   HandleScope scope(isolate);
 
   // Compute the size of relocation information needed for the code
-  // patching in Deoptimizer::DeoptimizeFunction.
+  // patching in Deoptimizer::PatchCodeForDeoptimization below.
   int min_reloc_size = 0;
   int prev_pc_offset = 0;
   DeoptimizationInputData* deopt_data =
diff --git a/src/x87/disasm-x87.cc b/src/x87/disasm-x87.cc
index 908e8b0..8c77d77 100644
--- a/src/x87/disasm-x87.cc
+++ b/src/x87/disasm-x87.cc
@@ -1698,17 +1698,17 @@
 //------------------------------------------------------------------------------
 
 
-static const char* cpu_regs[8] = {
+static const char* const cpu_regs[8] = {
   "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
 };
 
 
-static const char* byte_cpu_regs[8] = {
+static const char* const byte_cpu_regs[8] = {
   "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
 };
 
 
-static const char* xmm_regs[8] = {
+static const char* const xmm_regs[8] = {
   "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
 };
 
diff --git a/src/x87/full-codegen-x87.cc b/src/x87/full-codegen-x87.cc
index c159edd..0f292cc 100644
--- a/src/x87/full-codegen-x87.cc
+++ b/src/x87/full-codegen-x87.cc
@@ -188,10 +188,10 @@
     Comment cmnt(masm_, "[ Allocate context");
     bool need_write_barrier = true;
     // Argument to NewContext is the function, which is still in edi.
-    if (FLAG_harmony_scoping && info->scope()->is_global_scope()) {
+    if (FLAG_harmony_scoping && info->scope()->is_script_scope()) {
       __ push(edi);
       __ Push(info->scope()->GetScopeInfo());
-      __ CallRuntime(Runtime::kNewGlobalContext, 2);
+      __ CallRuntime(Runtime::kNewScriptContext, 2);
     } else if (heap_slots <= FastNewContextStub::kMaximumSlots) {
       FastNewContextStub stub(isolate(), heap_slots);
       __ CallStub(&stub);
@@ -865,7 +865,7 @@
   EmitDebugCheckDeclarationContext(variable);
 
   // Load instance object.
-  __ LoadContext(eax, scope_->ContextChainLength(scope_->GlobalScope()));
+  __ LoadContext(eax, scope_->ContextChainLength(scope_->ScriptScope()));
   __ mov(eax, ContextOperand(eax, variable->interface()->Index()));
   __ mov(eax, ContextOperand(eax, Context::EXTENSION_INDEX));
 
@@ -1024,7 +1024,7 @@
 
 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
   Comment cmnt(masm_, "[ ForInStatement");
-  int slot = stmt->ForInFeedbackSlot();
+  FeedbackVectorSlot slot = stmt->ForInFeedbackSlot();
 
   SetStatementPosition(stmt);
 
@@ -1034,6 +1034,7 @@
 
   // Get the object to enumerate over. If the object is null or undefined, skip
   // over the loop.  See ECMA-262 version 5, section 12.6.4.
+  SetExpressionPosition(stmt->enumerable());
   VisitForAccumulatorValue(stmt->enumerable());
   __ cmp(eax, isolate()->factory()->undefined_value());
   __ j(equal, &exit);
@@ -1051,6 +1052,7 @@
   __ push(eax);
   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
   __ bind(&done_convert);
+  PrepareForBailoutForId(stmt->ToObjectId(), TOS_REG);
   __ push(eax);
 
   // Check for proxies.
@@ -1072,6 +1074,7 @@
   __ bind(&call_runtime);
   __ push(eax);
   __ CallRuntime(Runtime::kGetPropertyNamesFast, 1);
+  PrepareForBailoutForId(stmt->EnumId(), TOS_REG);
   __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
          isolate()->factory()->meta_map());
   __ j(not_equal, &fixed_array);
@@ -1106,7 +1109,8 @@
 
   // No need for a write barrier, we are storing a Smi in the feedback vector.
   __ LoadHeapObject(ebx, FeedbackVector());
-  __ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(slot)),
+  int vector_index = FeedbackVector()->GetIndex(slot);
+  __ mov(FieldOperand(ebx, FixedArray::OffsetOfElementAt(vector_index)),
          Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate())));
 
   __ mov(ebx, Immediate(Smi::FromInt(1)));  // Smi indicates slow check
@@ -1125,6 +1129,8 @@
   // Generate code for doing the condition check.
   PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
   __ bind(&loop);
+  SetExpressionPosition(stmt->each());
+
   __ mov(eax, Operand(esp, 0 * kPointerSize));  // Get the current index.
   __ cmp(eax, Operand(esp, 1 * kPointerSize));  // Compare to the array length.
   __ j(above_equal, loop_statement.break_label());
@@ -1191,48 +1197,6 @@
 }
 
 
-void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
-  Comment cmnt(masm_, "[ ForOfStatement");
-  SetStatementPosition(stmt);
-
-  Iteration loop_statement(this, stmt);
-  increment_loop_depth();
-
-  // var iterator = iterable[Symbol.iterator]();
-  VisitForEffect(stmt->assign_iterator());
-
-  // Loop entry.
-  __ bind(loop_statement.continue_label());
-
-  // result = iterator.next()
-  VisitForEffect(stmt->next_result());
-
-  // if (result.done) break;
-  Label result_not_done;
-  VisitForControl(stmt->result_done(),
-                  loop_statement.break_label(),
-                  &result_not_done,
-                  &result_not_done);
-  __ bind(&result_not_done);
-
-  // each = result.value
-  VisitForEffect(stmt->assign_each());
-
-  // Generate code for the body of the loop.
-  Visit(stmt->body());
-
-  // Check stack before looping.
-  PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
-  EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
-  __ jmp(loop_statement.continue_label());
-
-  // Exit and decrement the loop depth.
-  PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
-  __ bind(loop_statement.break_label());
-  decrement_loop_depth();
-}
-
-
 void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
                                        bool pretenure) {
   // Use the fast case closure allocation code that allocates in new
@@ -1276,7 +1240,13 @@
   Handle<Symbol> home_object_symbol(isolate()->heap()->home_object_symbol());
   __ mov(LoadDescriptor::NameRegister(), home_object_symbol);
 
-  CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  if (FLAG_vector_ics) {
+    __ mov(VectorLoadICDescriptor::SlotRegister(),
+           Immediate(SmiFromSlot(expr->HomeObjectFeedbackSlot())));
+    CallLoadIC(NOT_CONTEXTUAL);
+  } else {
+    CallLoadIC(NOT_CONTEXTUAL, expr->HomeObjectFeedbackId());
+  }
 
   __ cmp(eax, isolate()->factory()->undefined_value());
   Label done;
@@ -1286,6 +1256,19 @@
 }
 
 
+void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
+                                                  int offset) {
+  if (NeedsHomeObject(initializer)) {
+    __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
+    __ mov(StoreDescriptor::NameRegister(),
+           Immediate(isolate()->factory()->home_object_symbol()));
+    __ mov(StoreDescriptor::ValueRegister(),
+           Operand(esp, offset * kPointerSize));
+    CallStoreIC();
+  }
+}
+
+
 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
                                                       TypeofState typeof_state,
                                                       Label* slow) {
@@ -1340,7 +1323,7 @@
   __ mov(LoadDescriptor::NameRegister(), proxy->var()->name());
   if (FLAG_vector_ics) {
     __ mov(VectorLoadICDescriptor::SlotRegister(),
-           Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
+           Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
   }
 
   ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
@@ -1427,7 +1410,7 @@
       __ mov(LoadDescriptor::NameRegister(), var->name());
       if (FLAG_vector_ics) {
         __ mov(VectorLoadICDescriptor::SlotRegister(),
-               Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
+               Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
       }
       CallLoadIC(CONTEXTUAL);
       context()->Plug(eax);
@@ -1611,6 +1594,7 @@
     FastCloneShallowObjectStub stub(isolate(), properties_count);
     __ CallStub(&stub);
   }
+  PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
 
   // If result_saved is true the result is on top of the stack.  If
   // result_saved is false the result is in eax.
@@ -1639,6 +1623,8 @@
         DCHECK(!CompileTimeValue::IsCompileTimeValue(value));
         // Fall through.
       case ObjectLiteral::Property::COMPUTED:
+        // It is safe to use [[Put]] here because the boilerplate already
+        // contains computed properties with an uninitialized value.
         if (key->value()->IsInternalizedString()) {
           if (property->emit_store()) {
             VisitForAccumulatorValue(value);
@@ -1647,6 +1633,14 @@
             __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0));
             CallStoreIC(key->LiteralFeedbackId());
             PrepareForBailoutForId(key->id(), NO_REGISTERS);
+
+            if (NeedsHomeObject(value)) {
+              __ mov(StoreDescriptor::ReceiverRegister(), eax);
+              __ mov(StoreDescriptor::NameRegister(),
+                     Immediate(isolate()->factory()->home_object_symbol()));
+              __ mov(StoreDescriptor::ValueRegister(), Operand(esp, 0));
+              CallStoreIC();
+            }
           } else {
             VisitForEffect(value);
           }
@@ -1656,6 +1650,7 @@
         VisitForStackValue(key);
         VisitForStackValue(value);
         if (property->emit_store()) {
+          EmitSetHomeObjectIfNeeded(value, 2);
           __ push(Immediate(Smi::FromInt(SLOPPY)));  // Strict mode
           __ CallRuntime(Runtime::kSetProperty, 4);
         } else {
@@ -1666,7 +1661,7 @@
         __ push(Operand(esp, 0));  // Duplicate receiver.
         VisitForStackValue(value);
         if (property->emit_store()) {
-          __ CallRuntime(Runtime::kSetPrototype, 2);
+          __ CallRuntime(Runtime::kInternalSetPrototype, 2);
         } else {
           __ Drop(2);
         }
@@ -1688,7 +1683,9 @@
     __ push(Operand(esp, 0));  // Duplicate receiver.
     VisitForStackValue(it->first);
     EmitAccessor(it->second->getter);
+    EmitSetHomeObjectIfNeeded(it->second->getter, 2);
     EmitAccessor(it->second->setter);
+    EmitSetHomeObjectIfNeeded(it->second->setter, 3);
     __ push(Immediate(Smi::FromInt(NONE)));
     __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
   }
@@ -1801,22 +1798,23 @@
 
   Comment cmnt(masm_, "[ Assignment");
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* property = expr->target()->AsProperty();
-  if (property != NULL) {
-    assign_type = (property->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(property);
 
   // Evaluate LHS expression.
   switch (assign_type) {
     case VARIABLE:
       // Nothing to do here.
       break;
+    case NAMED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ push(result_register());
+      if (expr->is_compound()) {
+        __ push(MemOperand(esp, kPointerSize));
+        __ push(result_register());
+      }
+      break;
     case NAMED_PROPERTY:
       if (expr->is_compound()) {
         // We need the receiver both on the stack and in the register.
@@ -1826,6 +1824,18 @@
         VisitForStackValue(property->obj());
       }
       break;
+    case KEYED_SUPER_PROPERTY:
+      VisitForStackValue(property->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(property->obj()->AsSuperReference());
+      __ Push(result_register());
+      VisitForAccumulatorValue(property->key());
+      __ Push(result_register());
+      if (expr->is_compound()) {
+        __ push(MemOperand(esp, 2 * kPointerSize));
+        __ push(MemOperand(esp, 2 * kPointerSize));
+        __ push(result_register());
+      }
+      break;
     case KEYED_PROPERTY: {
       if (expr->is_compound()) {
         VisitForStackValue(property->obj());
@@ -1850,10 +1860,18 @@
           EmitVariableLoad(expr->target()->AsVariableProxy());
           PrepareForBailout(expr->target(), TOS_REG);
           break;
+        case NAMED_SUPER_PROPERTY:
+          EmitNamedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
         case NAMED_PROPERTY:
           EmitNamedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
           break;
+        case KEYED_SUPER_PROPERTY:
+          EmitKeyedSuperPropertyLoad(property);
+          PrepareForBailoutForId(property->LoadId(), TOS_REG);
+          break;
         case KEYED_PROPERTY:
           EmitKeyedPropertyLoad(property);
           PrepareForBailoutForId(property->LoadId(), TOS_REG);
@@ -1899,6 +1917,14 @@
     case NAMED_PROPERTY:
       EmitNamedPropertyAssignment(expr);
       break;
+    case NAMED_SUPER_PROPERTY:
+      EmitNamedSuperPropertyStore(property);
+      context()->Plug(result_register());
+      break;
+    case KEYED_SUPER_PROPERTY:
+      EmitKeyedSuperPropertyStore(property);
+      context()->Plug(result_register());
+      break;
     case KEYED_PROPERTY:
       EmitKeyedPropertyAssignment(expr);
       break;
@@ -2031,7 +2057,7 @@
       __ mov(load_receiver, Operand(esp, kPointerSize));
       if (FLAG_vector_ics) {
         __ mov(VectorLoadICDescriptor::SlotRegister(),
-               Immediate(Smi::FromInt(expr->KeyedLoadFeedbackSlot())));
+               Immediate(SmiFromSlot(expr->KeyedLoadFeedbackSlot())));
       }
       Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
       CallIC(ic, TypeFeedbackId::None());
@@ -2051,7 +2077,7 @@
              isolate()->factory()->done_string());       // "done"
       if (FLAG_vector_ics) {
         __ mov(VectorLoadICDescriptor::SlotRegister(),
-               Immediate(Smi::FromInt(expr->DoneFeedbackSlot())));
+               Immediate(SmiFromSlot(expr->DoneFeedbackSlot())));
       }
       CallLoadIC(NOT_CONTEXTUAL);                        // result.done in eax
       Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
@@ -2065,7 +2091,7 @@
              isolate()->factory()->value_string());       // "value"
       if (FLAG_vector_ics) {
         __ mov(VectorLoadICDescriptor::SlotRegister(),
-               Immediate(Smi::FromInt(expr->ValueFeedbackSlot())));
+               Immediate(SmiFromSlot(expr->ValueFeedbackSlot())));
       }
       CallLoadIC(NOT_CONTEXTUAL);                         // result.value in eax
       context()->DropAndPlug(2, eax);                     // drop iter and g
@@ -2086,15 +2112,6 @@
   VisitForAccumulatorValue(value);
   __ pop(ebx);
 
-  // Check generator state.
-  Label wrong_state, closed_state, done;
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
-  STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
-  __ cmp(FieldOperand(ebx, JSGeneratorObject::kContinuationOffset),
-         Immediate(Smi::FromInt(0)));
-  __ j(equal, &closed_state);
-  __ j(less, &wrong_state);
-
   // Load suspended function and context.
   __ mov(esi, FieldOperand(ebx, JSGeneratorObject::kContextOffset));
   __ mov(edi, FieldOperand(ebx, JSGeneratorObject::kFunctionOffset));
@@ -2116,7 +2133,7 @@
 
   // Enter a new JavaScript frame, and initialize its slots as they were when
   // the generator was suspended.
-  Label resume_frame;
+  Label resume_frame, done;
   __ bind(&push_frame);
   __ call(&resume_frame);
   __ jmp(&done);
@@ -2163,25 +2180,6 @@
   // Not reached: the runtime call returns elsewhere.
   __ Abort(kGeneratorFailedToResume);
 
-  // Reach here when generator is closed.
-  __ bind(&closed_state);
-  if (resume_mode == JSGeneratorObject::NEXT) {
-    // Return completed iterator result when generator is closed.
-    __ push(Immediate(isolate()->factory()->undefined_value()));
-    // Pop value from top-of-stack slot; box result into result register.
-    EmitCreateIteratorResult(true);
-  } else {
-    // Throw the provided value.
-    __ push(eax);
-    __ CallRuntime(Runtime::kThrow, 1);
-  }
-  __ jmp(&done);
-
-  // Throw error if we attempt to operate on a running generator.
-  __ bind(&wrong_state);
-  __ push(ebx);
-  __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
-
   __ bind(&done);
   context()->Plug(result_register());
 }
@@ -2229,10 +2227,12 @@
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
   DCHECK(!key->value()->IsSmi());
+  DCHECK(!prop->IsSuperAccess());
+
   __ mov(LoadDescriptor::NameRegister(), Immediate(key->value()));
   if (FLAG_vector_ics) {
     __ mov(VectorLoadICDescriptor::SlotRegister(),
-           Immediate(Smi::FromInt(prop->PropertyFeedbackSlot())));
+           Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
     CallLoadIC(NOT_CONTEXTUAL);
   } else {
     CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
@@ -2241,15 +2241,12 @@
 
 
 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object.
   SetSourcePosition(prop->position());
   Literal* key = prop->key()->AsLiteral();
   DCHECK(!key->value()->IsSmi());
   DCHECK(prop->IsSuperAccess());
 
-  SuperReference* super_ref = prop->obj()->AsSuperReference();
-  EmitLoadHomeObject(super_ref);
-  __ push(eax);
-  VisitForStackValue(super_ref->this_var());
   __ push(Immediate(key->value()));
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 }
@@ -2260,7 +2257,7 @@
   Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
   if (FLAG_vector_ics) {
     __ mov(VectorLoadICDescriptor::SlotRegister(),
-           Immediate(Smi::FromInt(prop->PropertyFeedbackSlot())));
+           Immediate(SmiFromSlot(prop->PropertyFeedbackSlot())));
     CallIC(ic);
   } else {
     CallIC(ic, prop->PropertyFeedbackId());
@@ -2268,6 +2265,14 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
+  // Stack: receiver, home_object, key.
+  SetSourcePosition(prop->position());
+
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+}
+
+
 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
                                               Token::Value op,
                                               OverwriteMode mode,
@@ -2363,6 +2368,61 @@
 }
 
 
+void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
+  // Constructor is in eax.
+  DCHECK(lit != NULL);
+  __ push(eax);
+
+  // No access check is needed here since the constructor is created by the
+  // class literal.
+  Register scratch = ebx;
+  __ mov(scratch, FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset));
+  __ Push(scratch);
+
+  for (int i = 0; i < lit->properties()->length(); i++) {
+    ObjectLiteral::Property* property = lit->properties()->at(i);
+    Literal* key = property->key()->AsLiteral();
+    Expression* value = property->value();
+    DCHECK(key != NULL);
+
+    if (property->is_static()) {
+      __ push(Operand(esp, kPointerSize));  // constructor
+    } else {
+      __ push(Operand(esp, 0));  // prototype
+    }
+    VisitForStackValue(key);
+    VisitForStackValue(value);
+    EmitSetHomeObjectIfNeeded(value, 2);
+
+    switch (property->kind()) {
+      case ObjectLiteral::Property::CONSTANT:
+      case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+      case ObjectLiteral::Property::COMPUTED:
+      case ObjectLiteral::Property::PROTOTYPE:
+        __ CallRuntime(Runtime::kDefineClassMethod, 3);
+        break;
+
+      case ObjectLiteral::Property::GETTER:
+        __ CallRuntime(Runtime::kDefineClassGetter, 3);
+        break;
+
+      case ObjectLiteral::Property::SETTER:
+        __ CallRuntime(Runtime::kDefineClassSetter, 3);
+        break;
+
+      default:
+        UNREACHABLE();
+    }
+  }
+
+  // prototype
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+
+  // constructor
+  __ CallRuntime(Runtime::kToFastProperties, 1);
+}
+
+
 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
                                      Token::Value op,
                                      OverwriteMode mode) {
@@ -2378,16 +2438,8 @@
 void FullCodeGenerator::EmitAssignment(Expression* expr) {
   DCHECK(expr->IsValidReferenceExpression());
 
-  // Left-hand side can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->AsProperty();
-  if (prop != NULL) {
-    assign_type = (prop->key()->IsPropertyName())
-        ? NAMED_PROPERTY
-        : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   switch (assign_type) {
     case VARIABLE: {
@@ -2406,6 +2458,42 @@
       CallStoreIC();
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      __ push(eax);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      // stack: value, this; eax: home_object
+      Register scratch = ecx;
+      Register scratch2 = edx;
+      __ mov(scratch, result_register());               // home_object
+      __ mov(eax, MemOperand(esp, kPointerSize));       // value
+      __ mov(scratch2, MemOperand(esp, 0));             // this
+      __ mov(MemOperand(esp, kPointerSize), scratch2);  // this
+      __ mov(MemOperand(esp, 0), scratch);              // home_object
+      // stack: this, home_object. eax: value
+      EmitNamedSuperPropertyStore(prop);
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      __ push(eax);
+      VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(prop->obj()->AsSuperReference());
+      __ push(result_register());
+      VisitForAccumulatorValue(prop->key());
+      Register scratch = ecx;
+      Register scratch2 = edx;
+      __ mov(scratch2, MemOperand(esp, 2 * kPointerSize));  // value
+      // stack: value, this, home_object; eax: key, edx: value
+      __ mov(scratch, MemOperand(esp, kPointerSize));  // this
+      __ mov(MemOperand(esp, 2 * kPointerSize), scratch);
+      __ mov(scratch, MemOperand(esp, 0));  // home_object
+      __ mov(MemOperand(esp, kPointerSize), scratch);
+      __ mov(MemOperand(esp, 0), eax);
+      __ mov(eax, scratch2);
+      // stack: this, home_object, key; eax: value.
+      EmitKeyedSuperPropertyStore(prop);
+      break;
+    }
     case KEYED_PROPERTY: {
       __ push(eax);  // Preserve value.
       VisitForStackValue(prop->obj());
@@ -2474,7 +2562,6 @@
     __ CallRuntime(Runtime::kThrowReferenceError, 1);
     __ bind(&assign);
     EmitStoreToStackLocalOrContextSlot(var, location);
-
   } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
     if (var->IsLookupSlot()) {
       // Assignment to var.
@@ -2496,8 +2583,9 @@
       }
       EmitStoreToStackLocalOrContextSlot(var, location);
     }
+  } else if (IsSignallingAssignmentToConst(var, op, strict_mode())) {
+    __ CallRuntime(Runtime::kThrowConstAssignError, 0);
   }
-  // Non-initializing assignments to consts are ignored.
 }
 
 
@@ -2520,6 +2608,34 @@
 }
 
 
+void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // eax : value
+  // stack : receiver ('this'), home_object
+  DCHECK(prop != NULL);
+  Literal* key = prop->key()->AsLiteral();
+  DCHECK(key != NULL);
+
+  __ push(Immediate(key->value()));
+  __ push(eax);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
+                                          : Runtime::kStoreToSuper_Sloppy),
+                 4);
+}
+
+
+void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
+  // Assignment to named property of super.
+  // eax : value
+  // stack : receiver ('this'), home_object, key
+
+  __ push(eax);
+  __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict
+                                          : Runtime::kStoreKeyedToSuper_Sloppy),
+                 4);
+}
+
+
 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
   // Assignment to a property, using a keyed store IC.
   // eax               : value
@@ -2549,16 +2665,27 @@
       __ Move(LoadDescriptor::ReceiverRegister(), result_register());
       EmitNamedPropertyLoad(expr);
     } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ push(result_register());
       EmitNamedSuperPropertyLoad(expr);
     }
     PrepareForBailoutForId(expr->LoadId(), TOS_REG);
     context()->Plug(eax);
   } else {
-    VisitForStackValue(expr->obj());
-    VisitForAccumulatorValue(expr->key());
-    __ pop(LoadDescriptor::ReceiverRegister());                  // Object.
-    __ Move(LoadDescriptor::NameRegister(), result_register());  // Key.
-    EmitKeyedPropertyLoad(expr);
+    if (!expr->IsSuperAccess()) {
+      VisitForStackValue(expr->obj());
+      VisitForAccumulatorValue(expr->key());
+      __ pop(LoadDescriptor::ReceiverRegister());                  // Object.
+      __ Move(LoadDescriptor::NameRegister(), result_register());  // Key.
+      EmitKeyedPropertyLoad(expr);
+    } else {
+      VisitForStackValue(expr->obj()->AsSuperReference()->this_var());
+      EmitLoadHomeObject(expr->obj()->AsSuperReference());
+      __ push(result_register());
+      VisitForStackValue(expr->key());
+      EmitKeyedSuperPropertyLoad(expr);
+    }
     context()->Plug(eax);
   }
 }
@@ -2617,14 +2744,14 @@
   __ push(eax);
   VisitForAccumulatorValue(super_ref->this_var());
   __ push(eax);
-  __ push(Operand(esp, kPointerSize));
   __ push(eax);
+  __ push(Operand(esp, kPointerSize * 2));
   __ push(Immediate(key->value()));
   // Stack here:
   //  - home_object
   //  - this (receiver)
-  //  - home_object <-- LoadFromSuper will pop here and below.
-  //  - this (receiver)
+  //  - this (receiver) <-- LoadFromSuper will pop here and below.
+  //  - home_object
   //  - key
   __ CallRuntime(Runtime::kLoadFromSuper, 3);
 
@@ -2661,6 +2788,40 @@
 }
 
 
+void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
+  Expression* callee = expr->expression();
+  DCHECK(callee->IsProperty());
+  Property* prop = callee->AsProperty();
+  DCHECK(prop->IsSuperAccess());
+
+  SetSourcePosition(prop->position());
+  // Load the function from the receiver.
+  SuperReference* super_ref = callee->AsProperty()->obj()->AsSuperReference();
+  EmitLoadHomeObject(super_ref);
+  __ push(eax);
+  VisitForAccumulatorValue(super_ref->this_var());
+  __ push(eax);
+  __ push(eax);
+  __ push(Operand(esp, kPointerSize * 2));
+  VisitForStackValue(prop->key());
+  // Stack here:
+  //  - home_object
+  //  - this (receiver)
+  //  - this (receiver) <-- LoadKeyedFromSuper will pop here and below.
+  //  - home_object
+  //  - key
+  __ CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
+
+  // Replace home_object with target function.
+  __ mov(Operand(esp, kPointerSize), eax);
+
+  // Stack here:
+  // - target function
+  // - this (receiver)
+  EmitCall(expr, CallICState::METHOD);
+}
+
+
 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
   // Load the arguments.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2675,7 +2836,7 @@
   SetSourcePosition(expr->position());
   Handle<Code> ic = CallIC::initialize_stub(
       isolate(), arg_count, call_type);
-  __ Move(edx, Immediate(Smi::FromInt(expr->CallFeedbackSlot())));
+  __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot())));
   __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize));
   // Don't assign a type feedback id to the IC, since type feedback is provided
   // by the vector above.
@@ -2713,6 +2874,13 @@
 }
 
 
+void FullCodeGenerator::EmitLoadSuperConstructor(SuperReference* super_ref) {
+  DCHECK(super_ref != NULL);
+  __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
+  __ CallRuntime(Runtime::kGetPrototype, 1);
+}
+
+
 void FullCodeGenerator::VisitCall(Call* expr) {
 #ifdef DEBUG
   // We want to verify that RecordJSReturnSite gets called on all paths
@@ -2748,6 +2916,8 @@
       // edx (receiver). Touch up the stack with the right values.
       __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx);
       __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax);
+
+      PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
     }
     // Record source position for debugger.
     SetSourcePosition(expr->position());
@@ -2779,6 +2949,7 @@
     __ CallRuntime(Runtime::kLoadLookupSlot, 2);
     __ push(eax);  // Function.
     __ push(edx);  // Receiver.
+    PrepareForBailoutForId(expr->EvalOrLookupId(), NO_REGISTERS);
 
     // If fast case code has been generated, emit code to push the function
     // and receiver and have the slow path jump around this code.
@@ -2801,9 +2972,12 @@
   } else if (call_type == Call::PROPERTY_CALL) {
     Property* property = callee->AsProperty();
     bool is_named_call = property->key()->IsPropertyName();
-    // super.x() is handled in EmitCallWithLoadIC.
-    if (property->IsSuperAccess() && is_named_call) {
-      EmitSuperCallWithLoadIC(expr);
+    if (property->IsSuperAccess()) {
+      if (is_named_call) {
+        EmitSuperCallWithLoadIC(expr);
+      } else {
+        EmitKeyedSuperCallWithLoadIC(expr);
+      }
     } else {
       {
         PreservePositionScope scope(masm()->positions_recorder());
@@ -2815,6 +2989,12 @@
         EmitKeyedCallWithLoadIC(expr, property->key());
       }
     }
+  } else if (call_type == Call::SUPER_CALL) {
+    SuperReference* super_ref = callee->AsSuperReference();
+    EmitLoadSuperConstructor(super_ref);
+    __ push(result_register());
+    VisitForStackValue(super_ref->this_var());
+    EmitCall(expr, CallICState::METHOD);
   } else {
     DCHECK(call_type == Call::OTHER_CALL);
     // Call to an arbitrary expression not handled specially above.
@@ -2842,7 +3022,12 @@
   // Push constructor on the stack.  If it's not a function it's used as
   // receiver for CALL_NON_FUNCTION, otherwise the value on the stack is
   // ignored.
-  VisitForStackValue(expr->expression());
+  if (expr->expression()->IsSuperReference()) {
+    EmitLoadSuperConstructor(expr->expression()->AsSuperReference());
+    __ push(result_register());
+  } else {
+    VisitForStackValue(expr->expression());
+  }
 
   // Push the arguments ("left-to-right") on the stack.
   ZoneList<Expression*>* args = expr->arguments();
@@ -2862,12 +3047,12 @@
   // Record call targets in unoptimized code.
   if (FLAG_pretenuring_call_new) {
     EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
-    DCHECK(expr->AllocationSiteFeedbackSlot() ==
-           expr->CallNewFeedbackSlot() + 1);
+    DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
+           expr->CallNewFeedbackSlot().ToInt() + 1);
   }
 
   __ LoadHeapObject(ebx, FeedbackVector());
-  __ mov(edx, Immediate(Smi::FromInt(expr->CallNewFeedbackSlot())));
+  __ mov(edx, Immediate(SmiFromSlot(expr->CallNewFeedbackSlot())));
 
   CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
   __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
@@ -3181,6 +3366,31 @@
 }
 
 
+void FullCodeGenerator::EmitIsJSProxy(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  DCHECK(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false, &if_true,
+                         &if_false, &fall_through);
+
+  __ JumpIfSmi(eax, if_false);
+  Register map = ebx;
+  __ mov(map, FieldOperand(eax, HeapObject::kMapOffset));
+  __ CmpInstanceType(map, FIRST_JS_PROXY_TYPE);
+  __ j(less, if_false);
+  __ CmpInstanceType(map, LAST_JS_PROXY_TYPE);
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(less_equal, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
 
 void FullCodeGenerator::EmitIsConstructCall(CallRuntime* expr) {
   DCHECK(expr->arguments()->length() == 0);
@@ -4118,7 +4328,7 @@
     __ mov(LoadDescriptor::NameRegister(), Immediate(expr->name()));
     if (FLAG_vector_ics) {
       __ mov(VectorLoadICDescriptor::SlotRegister(),
-             Immediate(Smi::FromInt(expr->CallRuntimeFeedbackSlot())));
+             Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot())));
       CallLoadIC(NOT_CONTEXTUAL);
     } else {
       CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
@@ -4279,17 +4489,8 @@
   Comment cmnt(masm_, "[ CountOperation");
   SetSourcePosition(expr->position());
 
-  // Expression can only be a property, a global or a (parameter or local)
-  // slot.
-  enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
-  LhsKind assign_type = VARIABLE;
   Property* prop = expr->expression()->AsProperty();
-  // In case of a property we use the uninitialized expression context
-  // of the key to detect a named property.
-  if (prop != NULL) {
-    assign_type =
-        (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
-  }
+  LhsKind assign_type = GetAssignType(prop);
 
   // Evaluate expression and get value.
   if (assign_type == VARIABLE) {
@@ -4301,18 +4502,50 @@
     if (expr->is_postfix() && !context()->IsEffect()) {
       __ push(Immediate(Smi::FromInt(0)));
     }
-    if (assign_type == NAMED_PROPERTY) {
-      // Put the object both on the stack and in the register.
-      VisitForStackValue(prop->obj());
-      __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
-      EmitNamedPropertyLoad(prop);
-    } else {
-      VisitForStackValue(prop->obj());
-      VisitForStackValue(prop->key());
-      __ mov(LoadDescriptor::ReceiverRegister(),
-             Operand(esp, kPointerSize));                       // Object.
-      __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0));  // Key.
-      EmitKeyedPropertyLoad(prop);
+    switch (assign_type) {
+      case NAMED_PROPERTY: {
+        // Put the object both on the stack and in the register.
+        VisitForStackValue(prop->obj());
+        __ mov(LoadDescriptor::ReceiverRegister(), Operand(esp, 0));
+        EmitNamedPropertyLoad(prop);
+        break;
+      }
+
+      case NAMED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ push(result_register());
+        __ push(MemOperand(esp, kPointerSize));
+        __ push(result_register());
+        EmitNamedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_SUPER_PROPERTY: {
+        VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
+        EmitLoadHomeObject(prop->obj()->AsSuperReference());
+        __ push(result_register());
+        VisitForAccumulatorValue(prop->key());
+        __ push(result_register());
+        __ push(MemOperand(esp, 2 * kPointerSize));
+        __ push(MemOperand(esp, 2 * kPointerSize));
+        __ push(result_register());
+        EmitKeyedSuperPropertyLoad(prop);
+        break;
+      }
+
+      case KEYED_PROPERTY: {
+        VisitForStackValue(prop->obj());
+        VisitForStackValue(prop->key());
+        __ mov(LoadDescriptor::ReceiverRegister(),
+               Operand(esp, kPointerSize));                       // Object.
+        __ mov(LoadDescriptor::NameRegister(), Operand(esp, 0));  // Key.
+        EmitKeyedPropertyLoad(prop);
+        break;
+      }
+
+      case VARIABLE:
+        UNREACHABLE();
     }
   }
 
@@ -4344,9 +4577,15 @@
           case NAMED_PROPERTY:
             __ mov(Operand(esp, kPointerSize), eax);
             break;
+          case NAMED_SUPER_PROPERTY:
+            __ mov(Operand(esp, 2 * kPointerSize), eax);
+            break;
           case KEYED_PROPERTY:
             __ mov(Operand(esp, 2 * kPointerSize), eax);
             break;
+          case KEYED_SUPER_PROPERTY:
+            __ mov(Operand(esp, 3 * kPointerSize), eax);
+            break;
         }
       }
     }
@@ -4382,9 +4621,15 @@
         case NAMED_PROPERTY:
           __ mov(Operand(esp, kPointerSize), eax);
           break;
+        case NAMED_SUPER_PROPERTY:
+          __ mov(Operand(esp, 2 * kPointerSize), eax);
+          break;
         case KEYED_PROPERTY:
           __ mov(Operand(esp, 2 * kPointerSize), eax);
           break;
+        case KEYED_SUPER_PROPERTY:
+          __ mov(Operand(esp, 3 * kPointerSize), eax);
+          break;
       }
     }
   }
@@ -4441,6 +4686,28 @@
       }
       break;
     }
+    case NAMED_SUPER_PROPERTY: {
+      EmitNamedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(eax);
+      }
+      break;
+    }
+    case KEYED_SUPER_PROPERTY: {
+      EmitKeyedSuperPropertyStore(prop);
+      if (expr->is_postfix()) {
+        if (!context()->IsEffect()) {
+          context()->PlugTOS();
+        }
+      } else {
+        context()->Plug(eax);
+      }
+      break;
+    }
     case KEYED_PROPERTY: {
       __ pop(StoreDescriptor::NameRegister());
       __ pop(StoreDescriptor::ReceiverRegister());
@@ -4473,7 +4740,7 @@
     __ mov(LoadDescriptor::NameRegister(), Immediate(proxy->name()));
     if (FLAG_vector_ics) {
       __ mov(VectorLoadICDescriptor::SlotRegister(),
-             Immediate(Smi::FromInt(proxy->VariableFeedbackSlot())));
+             Immediate(SmiFromSlot(proxy->VariableFeedbackSlot())));
     }
     // Use a regular load, not a contextual load, to avoid a reference
     // error.
@@ -4708,7 +4975,7 @@
 
 void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
   Scope* declaration_scope = scope()->DeclarationScope();
-  if (declaration_scope->is_global_scope() ||
+  if (declaration_scope->is_script_scope() ||
       declaration_scope->is_module_scope()) {
     // Contexts nested in the native context have a canonical empty function
     // as their closure, not the anonymous closure containing the global
diff --git a/src/x87/interface-descriptors-x87.cc b/src/x87/interface-descriptors-x87.cc
index 8dfad36..26ce4dc 100644
--- a/src/x87/interface-descriptors-x87.cc
+++ b/src/x87/interface-descriptors-x87.cc
@@ -29,6 +29,9 @@
 const Register StoreDescriptor::ValueRegister() { return eax; }
 
 
+const Register StoreTransitionDescriptor::MapRegister() { return ebx; }
+
+
 const Register ElementTransitionAndStoreDescriptor::MapRegister() {
   return ebx;
 }
@@ -152,6 +155,15 @@
 }
 
 
+void AllocateHeapNumberDescriptor::Initialize(
+    CallInterfaceDescriptorData* data) {
+  // register state
+  // esi -- context
+  Register registers[] = {esi};
+  data->Initialize(arraysize(registers), registers, nullptr);
+}
+
+
 void ArrayConstructorConstantArgCountDescriptor::Initialize(
     CallInterfaceDescriptorData* data) {
   // register state
diff --git a/src/x87/lithium-codegen-x87.cc b/src/x87/lithium-codegen-x87.cc
index a5bc5ea..c292bb9 100644
--- a/src/x87/lithium-codegen-x87.cc
+++ b/src/x87/lithium-codegen-x87.cc
@@ -32,9 +32,9 @@
         deopt_mode_(mode) {}
   virtual ~SafepointGenerator() {}
 
-  virtual void BeforeCall(int call_size) const OVERRIDE {}
+  void BeforeCall(int call_size) const OVERRIDE {}
 
-  virtual void AfterCall() const OVERRIDE {
+  void AfterCall() const OVERRIDE {
     codegen_->RecordSafepoint(pointers_, deopt_mode_);
   }
 
@@ -2924,10 +2924,10 @@
                                   LInstanceOfKnownGlobal* instr,
                                   const X87Stack& x87_stack)
         : LDeferredCode(codegen, x87_stack), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
     Label* map_check() { return &map_check_; }
    private:
     LInstanceOfKnownGlobal* instr_;
@@ -3050,6 +3050,7 @@
     }
     __ Ret((parameter_count + extra_value_count) * kPointerSize, ecx);
   } else {
+    DCHECK(info()->IsStub());  // Functions would need to drop one more value.
     Register reg = ToRegister(instr->parameter_count());
     // The argument count parameter is a smi
     __ SmiUntag(reg);
@@ -3124,13 +3125,18 @@
 template <class T>
 void LCodeGen::EmitVectorLoadICRegisters(T* instr) {
   DCHECK(FLAG_vector_ics);
-  Register vector = ToRegister(instr->temp_vector());
-  DCHECK(vector.is(VectorLoadICDescriptor::VectorRegister()));
-  __ mov(vector, instr->hydrogen()->feedback_vector());
+  Register vector_register = ToRegister(instr->temp_vector());
+  Register slot_register = VectorLoadICDescriptor::SlotRegister();
+  DCHECK(vector_register.is(VectorLoadICDescriptor::VectorRegister()));
+  DCHECK(slot_register.is(eax));
+
+  AllowDeferredHandleDereference vector_structure_check;
+  Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
+  __ mov(vector_register, vector);
   // No need to allocate this register.
-  DCHECK(VectorLoadICDescriptor::SlotRegister().is(eax));
-  __ mov(VectorLoadICDescriptor::SlotRegister(),
-         Immediate(Smi::FromInt(instr->hydrogen()->slot())));
+  FeedbackVectorICSlot slot = instr->hydrogen()->slot();
+  int index = vector->GetIndex(slot);
+  __ mov(slot_register, Immediate(Smi::FromInt(index)));
 }
 
 
@@ -3145,7 +3151,7 @@
     EmitVectorLoadICRegisters<LLoadGlobalGeneric>(instr);
   }
   ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), mode).code();
+  Handle<Code> ic = CodeFactory::LoadICInOptimizedCode(isolate(), mode).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3275,7 +3281,8 @@
   if (FLAG_vector_ics) {
     EmitVectorLoadICRegisters<LLoadNamedGeneric>(instr);
   }
-  Handle<Code> ic = CodeFactory::LoadIC(isolate(), NOT_CONTEXTUAL).code();
+  Handle<Code> ic =
+      CodeFactory::LoadICInOptimizedCode(isolate(), NOT_CONTEXTUAL).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3498,7 +3505,7 @@
     EmitVectorLoadICRegisters<LLoadKeyedGeneric>(instr);
   }
 
-  Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
+  Handle<Code> ic = CodeFactory::KeyedLoadICInOptimizedCode(isolate()).code();
   CallCode(ic, RelocInfo::CODE_TARGET, instr);
 }
 
@@ -3734,45 +3741,81 @@
   Register name = ToRegister(instr->name());
   DCHECK(receiver.is(LoadDescriptor::ReceiverRegister()));
   DCHECK(name.is(LoadDescriptor::NameRegister()));
+  Register slot = FLAG_vector_ics ? ToRegister(instr->slot()) : no_reg;
+  Register vector = FLAG_vector_ics ? ToRegister(instr->vector()) : no_reg;
 
   Register scratch = ebx;
-  Register extra = eax;
+  Register extra = edi;
+  DCHECK(!extra.is(slot) && !extra.is(vector));
   DCHECK(!scratch.is(receiver) && !scratch.is(name));
   DCHECK(!extra.is(receiver) && !extra.is(name));
 
   // Important for the tail-call.
   bool must_teardown_frame = NeedsEagerFrame();
 
-  // The probe will tail call to a handler if found.
-  isolate()->stub_cache()->GenerateProbe(masm(), instr->hydrogen()->flags(),
-                                         must_teardown_frame, receiver, name,
-                                         scratch, extra);
+  if (!instr->hydrogen()->is_just_miss()) {
+    if (FLAG_vector_ics) {
+      __ push(slot);
+      __ push(vector);
+    }
+
+    // The probe will tail call to a handler if found.
+    // If --vector-ics is on, then it knows to pop the two args first.
+    DCHECK(!instr->hydrogen()->is_keyed_load());
+    isolate()->stub_cache()->GenerateProbe(
+        masm(), Code::LOAD_IC, instr->hydrogen()->flags(), must_teardown_frame,
+        receiver, name, scratch, extra);
+
+    if (FLAG_vector_ics) {
+      __ pop(vector);
+      __ pop(slot);
+    }
+  }
 
   // Tail call to miss if we ended up here.
   if (must_teardown_frame) __ leave();
-  LoadIC::GenerateMiss(masm());
+  if (instr->hydrogen()->is_keyed_load()) {
+    KeyedLoadIC::GenerateMiss(masm());
+  } else {
+    LoadIC::GenerateMiss(masm());
+  }
 }
 
 
 void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
   DCHECK(ToRegister(instr->result()).is(eax));
 
-  LPointerMap* pointers = instr->pointer_map();
-  SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+  if (instr->hydrogen()->IsTailCall()) {
+    if (NeedsEagerFrame()) __ leave();
 
-  if (instr->target()->IsConstantOperand()) {
-    LConstantOperand* target = LConstantOperand::cast(instr->target());
-    Handle<Code> code = Handle<Code>::cast(ToHandle(target));
-    generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
-    __ call(code, RelocInfo::CODE_TARGET);
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      __ jmp(code, RelocInfo::CODE_TARGET);
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
+      __ jmp(target);
+    }
   } else {
-    DCHECK(instr->target()->IsRegister());
-    Register target = ToRegister(instr->target());
-    generator.BeforeCall(__ CallSize(Operand(target)));
-    __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
-    __ call(target);
+    LPointerMap* pointers = instr->pointer_map();
+    SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
+
+    if (instr->target()->IsConstantOperand()) {
+      LConstantOperand* target = LConstantOperand::cast(instr->target());
+      Handle<Code> code = Handle<Code>::cast(ToHandle(target));
+      generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
+      __ call(code, RelocInfo::CODE_TARGET);
+    } else {
+      DCHECK(instr->target()->IsRegister());
+      Register target = ToRegister(instr->target());
+      generator.BeforeCall(__ CallSize(Operand(target)));
+      __ add(target, Immediate(Code::kHeaderSize - kHeapObjectTag));
+      __ call(target);
+    }
+    generator.AfterCall();
   }
-  generator.AfterCall();
 }
 
 
@@ -3869,10 +3912,11 @@
                                     LMathAbs* instr,
                                     const X87Stack& x87_stack)
         : LDeferredCode(codegen, x87_stack), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LMathAbs* instr_;
   };
@@ -4777,10 +4821,9 @@
                              LStringCharCodeAt* instr,
                              const X87Stack& x87_stack)
         : LDeferredCode(codegen, x87_stack), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredStringCharCodeAt(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredStringCharCodeAt(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStringCharCodeAt* instr_;
   };
@@ -4836,10 +4879,11 @@
                                LStringCharFromCode* instr,
                                const X87Stack& x87_stack)
         : LDeferredCode(codegen, x87_stack), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredStringCharFromCode(instr_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStringCharFromCode* instr_;
   };
@@ -4925,11 +4969,12 @@
                        LNumberTagI* instr,
                        const X87Stack& x87_stack)
         : LDeferredCode(codegen, x87_stack), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp(),
                                        SIGNED_INT32);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagI* instr_;
   };
@@ -4953,11 +4998,12 @@
                        LNumberTagU* instr,
                        const X87Stack& x87_stack)
         : LDeferredCode(codegen, x87_stack), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp(),
                                        UNSIGNED_INT32);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagU* instr_;
   };
@@ -5042,10 +5088,9 @@
                        LNumberTagD* instr,
                        const X87Stack& x87_stack)
         : LDeferredCode(codegen, x87_stack), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredNumberTagD(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredNumberTagD(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LNumberTagD* instr_;
   };
@@ -5288,10 +5333,9 @@
                       LTaggedToI* instr,
                       const X87Stack& x87_stack)
         : LDeferredCode(codegen, x87_stack), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredTaggedToI(instr_, done());
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredTaggedToI(instr_, done()); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LTaggedToI* instr_;
   };
@@ -5353,9 +5397,8 @@
     Label lost_precision, is_nan, minus_zero, done;
     X87Register input_reg = ToX87Register(input);
     X87Fxch(input_reg);
-    Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear;
     __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
-                 &lost_precision, &is_nan, &minus_zero, dist);
+                 &lost_precision, &is_nan, &minus_zero);
     __ jmp(&done);
     __ bind(&lost_precision);
     DeoptimizeIf(no_condition, instr, "lost precision");
@@ -5378,9 +5421,8 @@
   Label lost_precision, is_nan, minus_zero, done;
   X87Register input_reg = ToX87Register(input);
   X87Fxch(input_reg);
-  Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear;
   __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(),
-               &lost_precision, &is_nan, &minus_zero, dist);
+               &lost_precision, &is_nan, &minus_zero);
   __ jmp(&done);
   __ bind(&lost_precision);
   DeoptimizeIf(no_condition, instr, "lost precision");
@@ -5494,11 +5536,12 @@
         : LDeferredCode(codegen, x87_stack), instr_(instr), object_(object) {
       SetExit(check_maps());
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredInstanceMigration(instr_, object_);
     }
     Label* check_maps() { return &check_maps_; }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LCheckMaps* instr_;
     Label check_maps_;
@@ -5717,10 +5760,9 @@
                      LAllocate* instr,
                      const X87Stack& x87_stack)
         : LDeferredCode(codegen, x87_stack), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredAllocate(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredAllocate(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LAllocate* instr_;
   };
@@ -6086,10 +6128,9 @@
                        LStackCheck* instr,
                        const X87Stack& x87_stack)
         : LDeferredCode(codegen, x87_stack), instr_(instr) { }
-    virtual void Generate() OVERRIDE {
-      codegen()->DoDeferredStackCheck(instr_);
-    }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    void Generate() OVERRIDE { codegen()->DoDeferredStackCheck(instr_); }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LStackCheck* instr_;
   };
@@ -6237,10 +6278,11 @@
           object_(object),
           index_(index) {
     }
-    virtual void Generate() OVERRIDE {
+    void Generate() OVERRIDE {
       codegen()->DoDeferredLoadMutableDouble(instr_, object_, index_);
     }
-    virtual LInstruction* instr() OVERRIDE { return instr_; }
+    LInstruction* instr() OVERRIDE { return instr_; }
+
    private:
     LLoadFieldByIndex* instr_;
     Register object_;
diff --git a/src/x87/lithium-x87.cc b/src/x87/lithium-x87.cc
index 9304b89..3a52dc4 100644
--- a/src/x87/lithium-x87.cc
+++ b/src/x87/lithium-x87.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <sstream>
+
 #include "src/v8.h"
 
 #if V8_TARGET_ARCH_X87
@@ -376,9 +378,9 @@
 
 void LStoreNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintTo(stream);
-  OStringStream os;
+  std::ostringstream os;
   os << hydrogen()->access() << " <- ";
-  stream->Add(os.c_str());
+  stream->Add(os.str().c_str());
   value()->PrintTo(stream);
 }
 
@@ -736,11 +738,7 @@
     // Shift operations can only deoptimize if we do a logical shift by 0 and
     // the result cannot be truncated to int32.
     if (op == Token::SHR && constant_value == 0) {
-      if (FLAG_opt_safe_uint32_operations) {
-        does_deopt = !instr->CheckFlag(HInstruction::kUint32);
-      } else {
-        does_deopt = !instr->CheckUsesForFlag(HValue::kTruncatingToInt32);
-      }
+      does_deopt = !instr->CheckFlag(HInstruction::kUint32);
     }
 
     LInstruction* result =
@@ -1159,9 +1157,17 @@
       UseFixed(instr->receiver(), LoadDescriptor::ReceiverRegister());
   LOperand* name_register =
       UseFixed(instr->name(), LoadDescriptor::NameRegister());
+  LOperand* slot = NULL;
+  LOperand* vector = NULL;
+  if (FLAG_vector_ics) {
+    slot = UseFixed(instr->slot(), VectorLoadICDescriptor::SlotRegister());
+    vector =
+        UseFixed(instr->vector(), VectorLoadICDescriptor::VectorRegister());
+  }
+
   // Not marked as call. It can't deoptimize, and it never returns.
   return new (zone()) LTailCallThroughMegamorphicCache(
-      context, receiver_register, name_register);
+      context, receiver_register, name_register, slot, vector);
 }
 
 
@@ -2115,7 +2121,7 @@
   LOperand* global_object =
       UseFixed(instr->global_object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
 
@@ -2176,7 +2182,7 @@
   LOperand* object =
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
   LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(
@@ -2241,7 +2247,7 @@
       UseFixed(instr->object(), LoadDescriptor::ReceiverRegister());
   LOperand* key = UseFixed(instr->key(), LoadDescriptor::NameRegister());
   LOperand* vector = NULL;
-  if (FLAG_vector_ics) {
+  if (instr->HasVectorAndSlot()) {
     vector = FixedTemp(VectorLoadICDescriptor::VectorRegister());
   }
   LLoadKeyedGeneric* result =
diff --git a/src/x87/lithium-x87.h b/src/x87/lithium-x87.h
index dbb18ec..5d27fcb 100644
--- a/src/x87/lithium-x87.h
+++ b/src/x87/lithium-x87.h
@@ -168,17 +168,13 @@
   V(WrapReceiver)
 
 
-#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)                        \
-  virtual Opcode opcode() const FINAL OVERRIDE {                      \
-    return LInstruction::k##type;                                           \
-  }                                                                         \
-  virtual void CompileToNative(LCodeGen* generator) FINAL OVERRIDE;   \
-  virtual const char* Mnemonic() const FINAL OVERRIDE {               \
-    return mnemonic;                                                        \
-  }                                                                         \
-  static L##type* cast(LInstruction* instr) {                               \
-    DCHECK(instr->Is##type());                                              \
-    return reinterpret_cast<L##type*>(instr);                               \
+#define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic)            \
+  Opcode opcode() const FINAL { return LInstruction::k##type; } \
+  void CompileToNative(LCodeGen* generator) FINAL;              \
+  const char* Mnemonic() const FINAL { return mnemonic; }       \
+  static L##type* cast(LInstruction* instr) {                   \
+    DCHECK(instr->Is##type());                                  \
+    return reinterpret_cast<L##type*>(instr);                   \
   }
 
 
@@ -297,11 +293,9 @@
  public:
   // Allow 0 or 1 output operands.
   STATIC_ASSERT(R == 0 || R == 1);
-  virtual bool HasResult() const FINAL OVERRIDE {
-    return R != 0 && result() != NULL;
-  }
+  bool HasResult() const FINAL { return R != 0 && result() != NULL; }
   void set_result(LOperand* operand) { results_[0] = operand; }
-  LOperand* result() const { return results_[0]; }
+  LOperand* result() const OVERRIDE { return results_[0]; }
 
  protected:
   EmbeddedContainer<LOperand*, R> results_;
@@ -319,11 +313,11 @@
 
  private:
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return I; }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return I; }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return T; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return temps_[i]; }
+  int TempCount() FINAL { return T; }
+  LOperand* TempAt(int i) FINAL { return temps_[i]; }
 };
 
 
@@ -337,8 +331,8 @@
   }
 
   // Can't use the DECLARE-macro here because of sub-classes.
-  virtual bool IsGap() const FINAL OVERRIDE { return true; }
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsGap() const FINAL { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   static LGap* cast(LInstruction* instr) {
     DCHECK(instr->IsGap());
     return reinterpret_cast<LGap*>(instr);
@@ -378,7 +372,7 @@
  public:
   explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
     return !IsRedundant();
   }
 
@@ -390,9 +384,7 @@
  public:
   explicit LClobberDoubles(Isolate* isolate) { }
 
-  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
-    return true;
-  }
+  bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE { return true; }
 
   DECLARE_CONCRETE_INSTRUCTION(ClobberDoubles, "clobber-d")
 };
@@ -402,13 +394,13 @@
  public:
   explicit LGoto(HBasicBlock* block) : block_(block) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE;
   DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
-  virtual bool IsControl() const OVERRIDE { return true; }
+  void PrintDataTo(StringStream* stream) OVERRIDE;
+  bool IsControl() const OVERRIDE { return true; }
 
   int block_id() const { return block_->block_id(); }
-  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
+  bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
     return false;
   }
 
@@ -444,7 +436,7 @@
 
 class LDeoptimize FINAL : public LTemplateInstruction<0, 0, 0> {
  public:
-  virtual bool IsControl() const OVERRIDE { return true; }
+  bool IsControl() const OVERRIDE { return true; }
   DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
   DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
 };
@@ -455,12 +447,10 @@
   explicit LLabel(HBasicBlock* block)
       : LGap(block), replacement_(NULL) { }
 
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Label, "label")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int block_id() const { return block()->block_id(); }
   bool is_loop_header() const { return block()->IsLoopHeader(); }
@@ -478,9 +468,7 @@
 
 class LParameter FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
 };
 
@@ -499,19 +487,23 @@
 
 
 class LTailCallThroughMegamorphicCache FINAL
-    : public LTemplateInstruction<0, 3, 0> {
+    : public LTemplateInstruction<0, 5, 0> {
  public:
-  explicit LTailCallThroughMegamorphicCache(LOperand* context,
-                                            LOperand* receiver,
-                                            LOperand* name) {
+  LTailCallThroughMegamorphicCache(LOperand* context, LOperand* receiver,
+                                   LOperand* name, LOperand* slot,
+                                   LOperand* vector) {
     inputs_[0] = context;
     inputs_[1] = receiver;
     inputs_[2] = name;
+    inputs_[3] = slot;
+    inputs_[4] = vector;
   }
 
   LOperand* context() { return inputs_[0]; }
   LOperand* receiver() { return inputs_[1]; }
   LOperand* name() { return inputs_[2]; }
+  LOperand* slot() { return inputs_[3]; }
+  LOperand* vector() { return inputs_[4]; }
 
   DECLARE_CONCRETE_INSTRUCTION(TailCallThroughMegamorphicCache,
                                "tail-call-through-megamorphic-cache")
@@ -521,9 +513,7 @@
 
 class LUnknownOSRValue FINAL : public LTemplateInstruction<1, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
 };
 
@@ -533,7 +523,7 @@
  public:
   LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
 
-  virtual bool IsControl() const FINAL OVERRIDE { return true; }
+  bool IsControl() const FINAL { return true; }
 
   int SuccessorCount() { return hydrogen()->SuccessorCount(); }
   HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
@@ -626,7 +616,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -875,7 +865,7 @@
     return hydrogen()->representation().IsDouble();
   }
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1052,7 +1042,7 @@
 
   DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1069,7 +1059,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1084,7 +1074,7 @@
   DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1102,7 +1092,7 @@
                                "is-undetectable-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1122,7 +1112,7 @@
                                "string-compare-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Token::Value op() const { return hydrogen()->token(); }
 };
@@ -1142,7 +1132,7 @@
                                "has-instance-type-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1171,7 +1161,7 @@
   DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch,
                                "has-cached-array-index-and-branch")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1204,7 +1194,7 @@
                                "class-of-test-and-branch")
   DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1399,7 +1389,7 @@
   DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
   DECLARE_HYDROGEN_ACCESSOR(Branch)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1552,11 +1542,9 @@
 
   Token::Value op() const { return op_; }
 
-  virtual Opcode opcode() const OVERRIDE {
-    return LInstruction::kArithmeticD;
-  }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticD; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
  private:
   Token::Value op_;
@@ -1579,11 +1567,9 @@
   LOperand* left() { return inputs_[1]; }
   LOperand* right() { return inputs_[2]; }
 
-  virtual Opcode opcode() const OVERRIDE {
-    return LInstruction::kArithmeticT;
-  }
-  virtual void CompileToNative(LCodeGen* generator) OVERRIDE;
-  virtual const char* Mnemonic() const OVERRIDE;
+  Opcode opcode() const OVERRIDE { return LInstruction::kArithmeticT; }
+  void CompileToNative(LCodeGen* generator) OVERRIDE;
+  const char* Mnemonic() const OVERRIDE;
 
   Token::Value op() const { return op_; }
 
@@ -1696,7 +1682,7 @@
   DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
   DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   uint32_t base_offset() const { return hydrogen()->base_offset(); }
   bool key_is_smi() {
     return hydrogen()->key()->representation().IsTagged();
@@ -1794,7 +1780,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1815,7 +1801,7 @@
 
   int slot_index() { return hydrogen()->slot_index(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -1854,7 +1840,7 @@
   LOperand* function() { return inputs_[0]; }
   LOperand* code_object() { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
   DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
@@ -1871,7 +1857,7 @@
   LOperand* base_object() const { return inputs_[0]; }
   LOperand* offset() const { return inputs_[1]; }
 
-  virtual void PrintDataTo(StringStream* stream);
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
 };
@@ -1915,7 +1901,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallJSFunction, "call-js-function")
   DECLARE_HYDROGEN_ACCESSOR(CallJSFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -1937,18 +1923,18 @@
  private:
   DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 
   ZoneList<LOperand*> inputs_;
 
   // Iterator support.
-  virtual int InputCount() FINAL OVERRIDE { return inputs_.length(); }
-  virtual LOperand* InputAt(int i) FINAL OVERRIDE { return inputs_[i]; }
+  int InputCount() FINAL { return inputs_.length(); }
+  LOperand* InputAt(int i) FINAL { return inputs_[i]; }
 
-  virtual int TempCount() FINAL OVERRIDE { return 0; }
-  virtual LOperand* TempAt(int i) FINAL OVERRIDE { return NULL; }
+  int TempCount() FINAL { return 0; }
+  LOperand* TempAt(int i) FINAL { return NULL; }
 };
 
 
@@ -1965,7 +1951,7 @@
   DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
   DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -2001,7 +1987,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new")
   DECLARE_HYDROGEN_ACCESSOR(CallNew)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -2020,7 +2006,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
   DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   int arity() const { return hydrogen()->argument_count() - 1; }
 };
@@ -2037,7 +2023,7 @@
   DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
   DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
 
-  virtual bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
+  bool ClobbersDoubleRegisters(Isolate* isolate) const OVERRIDE {
     return save_doubles() == kDontSaveFPRegs;
   }
 
@@ -2225,7 +2211,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
@@ -2244,7 +2230,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreNamedGeneric, "store-named-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreNamedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   Handle<Object> name() const { return hydrogen()->name(); }
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
@@ -2275,7 +2261,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
   uint32_t base_offset() const { return hydrogen()->base_offset(); }
   bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
 };
@@ -2301,7 +2287,7 @@
   DECLARE_CONCRETE_INSTRUCTION(StoreKeyedGeneric, "store-keyed-generic")
   DECLARE_HYDROGEN_ACCESSOR(StoreKeyedGeneric)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   StrictMode strict_mode() { return hydrogen()->strict_mode(); }
 };
@@ -2328,7 +2314,7 @@
                                "transition-elements-kind")
   DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 
   Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
   Handle<Map> transitioned_map() {
@@ -2628,15 +2614,13 @@
 
   Handle<String> type_literal() { return hydrogen()->type_literal(); }
 
-  virtual void PrintDataTo(StringStream* stream) OVERRIDE;
+  void PrintDataTo(StringStream* stream) OVERRIDE;
 };
 
 
 class LOsrEntry FINAL : public LTemplateInstruction<0, 0, 0> {
  public:
-  virtual bool HasInterestingComment(LCodeGen* gen) const OVERRIDE {
-    return false;
-  }
+  bool HasInterestingComment(LCodeGen* gen) const OVERRIDE { return false; }
   DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
 };
 
@@ -2843,7 +2827,7 @@
 
   // An input operand in register, stack slot or a constant operand.
   // Will not be moved to a register even if one is freely available.
-  virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
+  MUST_USE_RESULT LOperand* UseAny(HValue* value) OVERRIDE;
 
   // Temporary operand that must be in a register.
   MUST_USE_RESULT LUnallocated* TempRegister();
diff --git a/src/x87/macro-assembler-x87.cc b/src/x87/macro-assembler-x87.cc
index a1fa331..008b2af 100644
--- a/src/x87/macro-assembler-x87.cc
+++ b/src/x87/macro-assembler-x87.cc
@@ -13,7 +13,7 @@
 #include "src/cpu-profiler.h"
 #include "src/debug.h"
 #include "src/isolate-inl.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 #include "src/serialize.h"
 
 namespace v8 {
@@ -278,7 +278,7 @@
 }
 
 
-void MacroAssembler::LoadUint32NoSSE2(Register src) {
+void MacroAssembler::LoadUint32NoSSE2(const Operand& src) {
   Label done;
   push(src);
   fild_s(Operand(esp, 0));
@@ -654,16 +654,16 @@
 }
 
 
-void MacroAssembler::DispatchMap(Register obj,
-                                 Register unused,
-                                 Handle<Map> map,
-                                 Handle<Code> success,
-                                 SmiCheckType smi_check_type) {
+void MacroAssembler::DispatchWeakMap(Register obj, Register scratch1,
+                                     Register scratch2, Handle<WeakCell> cell,
+                                     Handle<Code> success,
+                                     SmiCheckType smi_check_type) {
   Label fail;
   if (smi_check_type == DO_SMI_CHECK) {
     JumpIfSmi(obj, &fail);
   }
-  cmp(FieldOperand(obj, HeapObject::kMapOffset), Immediate(map));
+  mov(scratch1, FieldOperand(obj, HeapObject::kMapOffset));
+  CmpWeakValue(scratch1, cell, scratch2);
   j(equal, success);
 
   bind(&fail);
@@ -867,6 +867,13 @@
 }
 
 
+void MacroAssembler::EnterFrame(StackFrame::Type type,
+                                bool load_constant_pool_pointer_reg) {
+  // Out-of-line constant pool not implemented on x87.
+  UNREACHABLE();
+}
+
+
 void MacroAssembler::EnterFrame(StackFrame::Type type) {
   push(ebp);
   mov(ebp, esp);
@@ -906,8 +913,10 @@
   // Save the frame pointer and the context in top.
   ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate());
   ExternalReference context_address(Isolate::kContextAddress, isolate());
+  ExternalReference c_function_address(Isolate::kCFunctionAddress, isolate());
   mov(Operand::StaticVariable(c_entry_fp_address), ebp);
   mov(Operand::StaticVariable(context_address), esi);
+  mov(Operand::StaticVariable(c_function_address), ebx);
 }
 
 
@@ -1312,10 +1321,10 @@
   }
 
   bind(&done);
-  // Check that the value is a normal propety.
+  // Check that the value is a field property.
   const int kDetailsOffset =
       SeededNumberDictionary::kElementsStartOffset + 2 * kPointerSize;
-  DCHECK_EQ(NORMAL, 0);
+  DCHECK_EQ(FIELD, 0);
   test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
        Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize));
   j(not_zero, miss);
@@ -2535,6 +2544,21 @@
 }
 
 
+void MacroAssembler::CmpWeakValue(Register value, Handle<WeakCell> cell,
+                                  Register scratch) {
+  mov(scratch, cell);
+  cmp(value, FieldOperand(scratch, WeakCell::kValueOffset));
+}
+
+
+void MacroAssembler::LoadWeakValue(Register value, Handle<WeakCell> cell,
+                                   Label* miss) {
+  mov(value, cell);
+  mov(value, FieldOperand(value, WeakCell::kValueOffset));
+  JumpIfSmi(value, miss);
+}
+
+
 void MacroAssembler::Ret() {
   ret(0);
 }
@@ -3063,18 +3087,6 @@
 }
 
 
-void MacroAssembler::CheckMapDeprecated(Handle<Map> map,
-                                        Register scratch,
-                                        Label* if_deprecated) {
-  if (map->CanBeDeprecated()) {
-    mov(scratch, map);
-    mov(scratch, FieldOperand(scratch, Map::kBitField3Offset));
-    and_(scratch, Immediate(Map::Deprecated::kMask));
-    j(not_zero, if_deprecated);
-  }
-}
-
-
 void MacroAssembler::JumpIfBlack(Register object,
                                  Register scratch0,
                                  Register scratch1,
diff --git a/src/x87/macro-assembler-x87.h b/src/x87/macro-assembler-x87.h
index c9e9087..b797265 100644
--- a/src/x87/macro-assembler-x87.h
+++ b/src/x87/macro-assembler-x87.h
@@ -93,10 +93,6 @@
       Label* condition_met,
       Label::Distance condition_met_distance = Label::kFar);
 
-  void CheckMapDeprecated(Handle<Map> map,
-                          Register scratch,
-                          Label* if_deprecated);
-
   // Check if object is in new space.  Jumps if the object is not in new space.
   // The register scratch can be object itself, but scratch will be clobbered.
   void JumpIfNotInNewSpace(Register object,
@@ -277,6 +273,9 @@
     }
   }
 
+  void CmpWeakValue(Register value, Handle<WeakCell> cell, Register scratch);
+  void LoadWeakValue(Register value, Handle<WeakCell> cell, Label* miss);
+
   // ---------------------------------------------------------------------------
   // JavaScript invokes
 
@@ -379,14 +378,12 @@
                 Label* fail,
                 SmiCheckType smi_check_type);
 
-  // Check if the map of an object is equal to a specified map and branch to a
-  // specified target if equal. Skip the smi check if not required (object is
-  // known to be a heap object)
-  void DispatchMap(Register obj,
-                   Register unused,
-                   Handle<Map> map,
-                   Handle<Code> success,
-                   SmiCheckType smi_check_type);
+  // Check if the map of an object is equal to a specified weak map and branch
+  // to a specified target if equal. Skip the smi check if not required
+  // (object is known to be a heap object)
+  void DispatchWeakMap(Register obj, Register scratch1, Register scratch2,
+                       Handle<WeakCell> cell, Handle<Code> success,
+                       SmiCheckType smi_check_type);
 
   // Check if the object in register heap_object is a string. Afterwards the
   // register map contains the object map and the register instance_type
@@ -458,7 +455,10 @@
     j(not_carry, is_smi);
   }
 
-  void LoadUint32NoSSE2(Register src);
+  void LoadUint32NoSSE2(Register src) {
+    LoadUint32NoSSE2(Operand(src));
+  }
+  void LoadUint32NoSSE2(const Operand& src);
 
   // Jump the register contains a smi.
   inline void JumpIfSmi(Register value,
@@ -904,6 +904,7 @@
 
   // Activation support.
   void EnterFrame(StackFrame::Type type);
+  void EnterFrame(StackFrame::Type type, bool load_constant_pool_pointer_reg);
   void LeaveFrame(StackFrame::Type type);
 
   // Expects object in eax and returns map with validated enum cache
diff --git a/src/zone-allocator.h b/src/zone-allocator.h
index ab0ae9c..1eb69b8 100644
--- a/src/zone-allocator.h
+++ b/src/zone-allocator.h
@@ -50,10 +50,10 @@
   }
   void destroy(pointer p) { p->~T(); }
 
-  bool operator==(zone_allocator const& other) {
+  bool operator==(zone_allocator const& other) const {
     return zone_ == other.zone_;
   }
-  bool operator!=(zone_allocator const& other) {
+  bool operator!=(zone_allocator const& other) const {
     return zone_ != other.zone_;
   }
 
diff --git a/src/zone-containers.h b/src/zone-containers.h
index 2ee1780..b0ff7b6 100644
--- a/src/zone-containers.h
+++ b/src/zone-containers.h
@@ -6,7 +6,9 @@
 #define V8_ZONE_CONTAINERS_H_
 
 #include <deque>
+#include <list>
 #include <queue>
+#include <stack>
 #include <vector>
 
 #include "src/zone-allocator.h"
@@ -17,42 +19,75 @@
 // A wrapper subclass for std::vector to make it easy to construct one
 // that uses a zone allocator.
 template <typename T>
-class ZoneVector : public std::vector<T, zone_allocator<T> > {
+class ZoneVector : public std::vector<T, zone_allocator<T>> {
  public:
   // Constructs an empty vector.
   explicit ZoneVector(Zone* zone)
-      : std::vector<T, zone_allocator<T> >(zone_allocator<T>(zone)) {}
+      : std::vector<T, zone_allocator<T>>(zone_allocator<T>(zone)) {}
+
+  // Constructs a new vector and fills it with {size} elements, each
+  // constructed via the default constructor.
+  ZoneVector(int size, Zone* zone)
+      : std::vector<T, zone_allocator<T>>(size, T(), zone_allocator<T>(zone)) {}
 
   // Constructs a new vector and fills it with {size} elements, each
   // having the value {def}.
   ZoneVector(int size, T def, Zone* zone)
-      : std::vector<T, zone_allocator<T> >(size, def, zone_allocator<T>(zone)) {
-  }
+      : std::vector<T, zone_allocator<T>>(size, def, zone_allocator<T>(zone)) {}
 };
 
+
 // A wrapper subclass std::deque to make it easy to construct one
 // that uses a zone allocator.
 template <typename T>
-class ZoneDeque : public std::deque<T, zone_allocator<T> > {
+class ZoneDeque : public std::deque<T, zone_allocator<T>> {
  public:
+  // Constructs an empty deque.
   explicit ZoneDeque(Zone* zone)
-      : std::deque<T, zone_allocator<T> >(zone_allocator<T>(zone)) {}
+      : std::deque<T, zone_allocator<T>>(zone_allocator<T>(zone)) {}
 };
 
+
+// A wrapper subclass std::list to make it easy to construct one
+// that uses a zone allocator.
+// TODO(mstarzinger): This should be renamed to ZoneList once we got rid of our
+// own home-grown ZoneList that actually is a ZoneVector.
+template <typename T>
+class ZoneLinkedList : public std::list<T, zone_allocator<T>> {
+ public:
+  // Constructs an empty list.
+  explicit ZoneLinkedList(Zone* zone)
+      : std::list<T, zone_allocator<T>>(zone_allocator<T>(zone)) {}
+};
+
+
 // A wrapper subclass for std::queue to make it easy to construct one
 // that uses a zone allocator.
 template <typename T>
-class ZoneQueue : public std::queue<T, std::deque<T, zone_allocator<T> > > {
+class ZoneQueue : public std::queue<T, ZoneDeque<T>> {
  public:
   // Constructs an empty queue.
   explicit ZoneQueue(Zone* zone)
-      : std::queue<T, std::deque<T, zone_allocator<T> > >(
-            std::deque<T, zone_allocator<T> >(zone_allocator<T>(zone))) {}
+      : std::queue<T, ZoneDeque<T>>(ZoneDeque<T>(zone)) {}
 };
 
+
+// A wrapper subclass for std::stack to make it easy to construct one that uses
+// a zone allocator.
+template <typename T>
+class ZoneStack : public std::stack<T, ZoneDeque<T>> {
+ public:
+  // Constructs an empty stack.
+  explicit ZoneStack(Zone* zone)
+      : std::stack<T, ZoneDeque<T>>(ZoneDeque<T>(zone)) {}
+};
+
+
 // Typedefs to shorten commonly used vectors.
 typedef ZoneVector<bool> BoolVector;
 typedef ZoneVector<int> IntVector;
-} }  // namespace v8::internal
+
+}  // namespace internal
+}  // namespace v8
 
 #endif  // V8_ZONE_CONTAINERS_H_
diff --git a/src/zone-inl.h b/src/zone-inl.h
index cf037b5..63efe16 100644
--- a/src/zone-inl.h
+++ b/src/zone-inl.h
@@ -31,7 +31,6 @@
 
 void Zone::adjust_segment_bytes_allocated(int delta) {
   segment_bytes_allocated_ += delta;
-  isolate_->counters()->zone_segment_bytes()->Set(segment_bytes_allocated_);
 }
 
 
diff --git a/src/zone.cc b/src/zone.cc
index 48d8c7b..eb2e532 100644
--- a/src/zone.cc
+++ b/src/zone.cc
@@ -150,6 +150,7 @@
     position_ = limit_ = 0;
   }
 
+  allocation_size_ = 0;
   // Update the head segment to be the kept segment (if any).
   segment_head_ = keep;
 }
diff --git a/test/benchmarks/testcfg.py b/test/benchmarks/testcfg.py
index 6607bef..29e0c37 100644
--- a/test/benchmarks/testcfg.py
+++ b/test/benchmarks/testcfg.py
@@ -186,7 +186,7 @@
     # Both --nocrankshaft and --stressopt are very slow. Add TF but without
     # always opt to match the way the benchmarks are run for performance
     # testing.
-    return [[], ["--turbo-filter=*"]]
+    return [[], ["--turbo-asm", "--turbo-filter=*"]]
 
 
 def GetSuite(name, root):
diff --git a/test/cctest/cctest.cc b/test/cctest/cctest.cc
index f03710a..170aa5a 100644
--- a/test/cctest/cctest.cc
+++ b/test/cctest/cctest.cc
@@ -34,12 +34,12 @@
 #include "test/cctest/profiler-extension.h"
 #include "test/cctest/trace-extension.h"
 
-#if (defined(_WIN32) || defined(_WIN64))
+#if V8_OS_WIN
 #include <windows.h>  // NOLINT
-#if defined(_MSC_VER)
+#if V8_CC_MSVC
 #include <crtdbg.h>
-#endif  // defined(_MSC_VER)
-#endif  // defined(_WIN32) || defined(_WIN64)
+#endif
+#endif
 
 enum InitializationState {kUnset, kUnintialized, kInitialized};
 static InitializationState initialization_state_  = kUnset;
@@ -47,7 +47,7 @@
 
 CcTest* CcTest::last_ = NULL;
 bool CcTest::initialize_called_ = false;
-bool CcTest::isolate_used_ = false;
+v8::base::Atomic32 CcTest::isolate_used_ = 0;
 v8::Isolate* CcTest::isolate_ = NULL;
 
 
@@ -145,12 +145,12 @@
 
 
 int main(int argc, char* argv[]) {
-#if (defined(_WIN32) || defined(_WIN64))
+#if V8_OS_WIN
   UINT new_flags =
       SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX;
   UINT existing_flags = SetErrorMode(new_flags);
   SetErrorMode(existing_flags | new_flags);
-#if defined(_MSC_VER)
+#if V8_CC_MSVC
   _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
   _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
   _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
@@ -158,8 +158,8 @@
   _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
   _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
   _set_error_mode(_OUT_TO_STDERR);
-#endif  // _MSC_VER
-#endif  // defined(_WIN32) || defined(_WIN64)
+#endif  // V8_CC_MSVC
+#endif  // V8_OS_WIN
 
   v8::V8::InitializeICU();
   v8::Platform* platform = v8::platform::CreateDefaultPlatform();
diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp
index 6a57763..4d1c467 100644
--- a/test/cctest/cctest.gyp
+++ b/test/cctest/cctest.gyp
@@ -53,22 +53,27 @@
         'compiler/graph-tester.h',
         'compiler/simplified-graph-builder.cc',
         'compiler/simplified-graph-builder.h',
+        'compiler/test-basic-block-profiler.cc',
         'compiler/test-branch-combine.cc',
         'compiler/test-changes-lowering.cc',
         'compiler/test-codegen-deopt.cc',
+        'compiler/test-control-reducer.cc',
         'compiler/test-gap-resolver.cc',
         'compiler/test-graph-reducer.cc',
+        'compiler/test-graph-visualizer.cc',
         'compiler/test-instruction.cc',
         'compiler/test-js-context-specialization.cc',
         'compiler/test-js-constant-cache.cc',
         'compiler/test-js-typed-lowering.cc',
+        'compiler/test-jump-threading.cc',
         'compiler/test-linkage.cc',
+        'compiler/test-loop-assignment-analysis.cc',
+        'compiler/test-loop-analysis.cc',
         'compiler/test-machine-operator-reducer.cc',
         'compiler/test-node-algorithm.cc',
         'compiler/test-node-cache.cc',
         'compiler/test-node.cc',
         'compiler/test-operator.cc',
-        'compiler/test-phi-reducer.cc',
         'compiler/test-pipeline.cc',
         'compiler/test-representation-change.cc',
         'compiler/test-run-deopt.cc',
@@ -80,10 +85,12 @@
         'compiler/test-run-jsops.cc',
         'compiler/test-run-machops.cc',
         'compiler/test-run-properties.cc',
+        'compiler/test-run-stackcheck.cc',
         'compiler/test-run-variables.cc',
         'compiler/test-schedule.cc',
         'compiler/test-scheduler.cc',
         'compiler/test-simplified-lowering.cc',
+        'compiler/test-typer.cc',
         'cctest.cc',
         'gay-fixed.cc',
         'gay-precision.cc',
@@ -97,13 +104,13 @@
         'test-atomicops.cc',
         'test-bignum.cc',
         'test-bignum-dtoa.cc',
+        'test-bit-vector.cc',
         'test-checks.cc',
         'test-circular-queue.cc',
         'test-compiler.cc',
         'test-constantpool.cc',
         'test-conversions.cc',
         'test-cpu-profiler.cc',
-        'test-dataflow.cc',
         'test-date.cc',
         'test-debug.cc',
         'test-declarative-accessors.cc',
@@ -114,6 +121,7 @@
         'test-double.cc',
         'test-dtoa.cc',
         'test-fast-dtoa.cc',
+        'test-feedback-vector.cc',
         'test-fixed-dtoa.cc',
         'test-flags.cc',
         'test-func-name-inference.cc',
@@ -134,7 +142,6 @@
         'test-mementos.cc',
         'test-object-observe.cc',
         'test-ordered-hash-table.cc',
-        'test-ostreams.cc',
         'test-parsing.cc',
         'test-platform.cc',
         'test-profile-generator.cc',
@@ -142,6 +149,7 @@
         'test-regexp.cc',
         'test-reloc-info.cc',
         'test-representation.cc',
+        'test-sampler-api.cc',
         'test-serialize.cc',
         'test-spaces.cc',
         'test-strings.cc',
@@ -149,8 +157,10 @@
         'test-strtod.cc',
         'test-thread-termination.cc',
         'test-threads.cc',
+        'test-transitions.cc',
         'test-types.cc',
         'test-unbound-queue.cc',
+        'test-unboxed-doubles.cc',
         'test-unique.cc',
         'test-unscopables-hidden-prototype.cc',
         'test-utils.cc',
@@ -250,13 +260,14 @@
           # cctest can't be built against a shared library, so we need to
           # depend on the underlying static target in that case.
           'conditions': [
-            ['v8_use_snapshot=="true"', {
+            ['v8_use_snapshot=="true" and v8_use_external_startup_data==0', {
               'dependencies': ['../../tools/gyp/v8.gyp:v8_snapshot'],
-            },
-            {
-              'dependencies': [
-                '../../tools/gyp/v8.gyp:v8_nosnapshot',
-              ],
+            }],
+            ['v8_use_snapshot=="true" and v8_use_external_startup_data==1', {
+              'dependencies': ['../../tools/gyp/v8.gyp:v8_external_snapshot'],
+            }],
+            ['v8_use_snapshot!="true"', {
+              'dependencies': ['../../tools/gyp/v8.gyp:v8_nosnapshot'],
             }],
           ],
         }, {
@@ -294,7 +305,6 @@
             '../../tools/js2c.py',
             '<@(_outputs)',
             'TEST',  # type
-            'off',  # compression
             '<@(file_list)',
           ],
         }
diff --git a/test/cctest/cctest.h b/test/cctest/cctest.h
index 6d27074..a8239d2 100644
--- a/test/cctest/cctest.h
+++ b/test/cctest/cctest.h
@@ -117,7 +117,7 @@
 
   static v8::Isolate* isolate() {
     CHECK(isolate_ != NULL);
-    isolate_used_ = true;
+    v8::base::NoBarrier_Store(&isolate_used_, 1);
     return isolate_;
   }
 
@@ -149,7 +149,7 @@
   // TODO(dcarney): Remove.
   // This must be called first in a test.
   static void InitializeVM() {
-    CHECK(!isolate_used_);
+    CHECK(!v8::base::NoBarrier_Load(&isolate_used_));
     CHECK(!initialize_called_);
     initialize_called_ = true;
     v8::HandleScope handle_scope(CcTest::isolate());
@@ -181,7 +181,7 @@
   static CcTest* last_;
   static v8::Isolate* isolate_;
   static bool initialize_called_;
-  static bool isolate_used_;
+  static v8::base::Atomic32 isolate_used_;
 };
 
 // Switches between all the Api tests using the threading support.
@@ -481,15 +481,31 @@
 
 
 // Helper function that simulates a full new-space in the heap.
-static inline void SimulateFullSpace(v8::internal::NewSpace* space) {
-  int new_linear_size = static_cast<int>(
-      *space->allocation_limit_address() - *space->allocation_top_address());
-  if (new_linear_size == 0) return;
+static inline bool FillUpOnePage(v8::internal::NewSpace* space) {
   v8::internal::AllocationResult allocation =
-      space->AllocateRaw(new_linear_size);
+      space->AllocateRaw(v8::internal::Page::kMaxRegularHeapObjectSize);
+  if (allocation.IsRetry()) return false;
   v8::internal::FreeListNode* node =
       v8::internal::FreeListNode::cast(allocation.ToObjectChecked());
-  node->set_size(space->heap(), new_linear_size);
+  node->set_size(space->heap(), v8::internal::Page::kMaxRegularHeapObjectSize);
+  return true;
+}
+
+
+static inline void SimulateFullSpace(v8::internal::NewSpace* space) {
+  int new_linear_size = static_cast<int>(*space->allocation_limit_address() -
+                                         *space->allocation_top_address());
+  if (new_linear_size > 0) {
+    // Fill up the current page.
+    v8::internal::AllocationResult allocation =
+        space->AllocateRaw(new_linear_size);
+    v8::internal::FreeListNode* node =
+        v8::internal::FreeListNode::cast(allocation.ToObjectChecked());
+    node->set_size(space->heap(), new_linear_size);
+  }
+  // Fill up all remaining pages.
+  while (FillUpOnePage(space))
+    ;
 }
 
 
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 5198af6..cc5414d 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -29,6 +29,7 @@
 [ALWAYS, {
   # All tests prefixed with 'Bug' are expected to fail.
   'test-api/Bug*': [FAIL],
+  'test-serialize/Bug*': [FAIL],
 
   ##############################################################################
 
@@ -80,58 +81,14 @@
   ##############################################################################
   # TurboFan compiler failures.
 
-  # TODO(sigurds): The schedule is borked with multiple inlinees,
-  # and cannot handle free-floating loops yet
-  'test-run-inlining/InlineTwiceDependentDiamond': [SKIP],
-  'test-run-inlining/InlineTwiceDependentDiamondDifferent': [SKIP],
-  'test-run-inlining/InlineLoop': [SKIP],
-
   # Some tests are just too slow to run for now.
   'test-api/Threading*': [PASS, NO_VARIANTS],
   'test-heap/IncrementalMarkingStepMakesBigProgressWithLargeObjects': [PASS, NO_VARIANTS],
   'test-heap-profiler/ManyLocalsInSharedContext': [PASS, NO_VARIANTS],
   'test-debug/ThreadedDebugging': [PASS, NO_VARIANTS],
   'test-debug/DebugBreakLoop': [PASS, NO_VARIANTS],
-
-  # Support for breakpoints requires using LoadICs and StoreICs.
-  'test-debug/BreakPointICStore': [PASS, NO_VARIANTS],
-  'test-debug/BreakPointICLoad': [PASS, NO_VARIANTS],
-  'test-debug/BreakPointICCall': [PASS, NO_VARIANTS],
-  'test-debug/BreakPointICCallWithGC': [PASS, NO_VARIANTS],
-  'test-debug/BreakPointConstructCallWithGC': [PASS, NO_VARIANTS],
-  'test-debug/BreakPointReturn': [PASS, NO_VARIANTS],
-  'test-debug/BreakPointThroughJavaScript': [PASS, NO_VARIANTS],
-  'test-debug/ScriptBreakPointByNameThroughJavaScript': [PASS, NO_VARIANTS],
-  'test-debug/ScriptBreakPointByIdThroughJavaScript': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepLinear': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepKeyedLoadLoop': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepKeyedStoreLoop': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepNamedLoadLoop': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepNamedStoreLoop': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepLinearMixedICs': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepDeclarations': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepLocals': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepIf': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepSwitch': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepWhile': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepDoWhile': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepFor': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepForContinue': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepForBreak': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepForIn': [PASS, NO_VARIANTS],
-  'test-debug/DebugStepWith': [PASS, NO_VARIANTS],
-  'test-debug/DebugConditional': [PASS, NO_VARIANTS],
-  'test-debug/StepInOutSimple': [PASS, NO_VARIANTS],
-  'test-debug/StepInOutTree': [PASS, NO_VARIANTS],
-  'test-debug/StepInOutBranch': [PASS, NO_VARIANTS],
-  'test-debug/DebugBreak': [PASS, NO_VARIANTS],
-  'test-debug/DebugBreakStackInspection': [PASS, NO_VARIANTS],
-  'test-debug/BreakMessageWhenMessageHandlerIsReset': [PASS, NO_VARIANTS],
-  'test-debug/NoDebugBreakInAfterCompileMessageHandler': [PASS, NO_VARIANTS],
-  'test-debug/DisableBreak': [PASS, NO_VARIANTS],
-  'test-debug/RegExpDebugBreak': [PASS, NO_VARIANTS],
-  'test-debug/DebugBreakFunctionApply': [PASS, NO_VARIANTS],
-  'test-debug/DeoptimizeDuringDebugBreak': [PASS, NO_VARIANTS],
+  # BUG(3742).
+  'test-mark-compact/MarkCompactCollector': [PASS, ['arch==arm', NO_VARIANTS]],
 
   # Support for %GetFrameDetails is missing and requires checkpoints.
   'test-api/Regress385349': [PASS, NO_VARIANTS],
@@ -148,6 +105,17 @@
   'test-debug/CallingContextIsNotDebugContext': [PASS, NO_VARIANTS],
   'test-debug/DebugEventContext': [PASS, NO_VARIANTS],
   'test-debug/DebugBreakInline': [PASS, NO_VARIANTS],
+  'test-debug/BreakMessageWhenMessageHandlerIsReset': [PASS, NO_VARIANTS],
+  'test-debug/DebugBreak': [PASS, NO_VARIANTS],
+  'test-debug/DebugBreakFunctionApply': [PASS, NO_VARIANTS],
+  'test-debug/DebugBreakStackInspection': [PASS, NO_VARIANTS],
+  'test-debug/DeoptimizeDuringDebugBreak': [PASS, NO_VARIANTS],
+  'test-debug/DisableBreak': [PASS, NO_VARIANTS],
+  'test-debug/NoDebugBreakInAfterCompileMessageHandler': [PASS, NO_VARIANTS],
+  'test-debug/RegExpDebugBreak': [PASS, NO_VARIANTS],
+
+  # TODO(titzer): Triggers bug in late control reduction.
+  'test-run-inlining/InlineLoopGuardedEmpty': [SKIP],
 
   ############################################################################
   # Slow tests.
@@ -298,6 +266,19 @@
 }],  # 'arch == mipsel or arch == mips'
 
 ##############################################################################
+['arch == mips', {
+  # Too slow with TF.
+  'test-api/ExternalArrays': [PASS, NO_VARIANTS],
+
+  # TODO(mips-team): Currently fails on mips board.
+  'test-simplified-lowering/RunNumberMultiply_TruncatingToUint32': [SKIP],
+  'test-parsing/TooManyArguments': [SKIP],
+  'test-api/Threading3': [SKIP],
+  'test-api/RequestInterruptTestWithNativeAccessor': [SKIP],
+  'test-api/RequestInterruptTestWithAccessor': [SKIP],
+}],  # 'arch == mips'
+
+##############################################################################
 ['arch == mips64el', {
 
   # BUG(2657): Test sometimes times out on MIPS simulator.
@@ -334,12 +315,6 @@
   'test-log/LogAccessorCallbacks': [SKIP],
   'test-log/LogCallbacks': [SKIP],
   'test-log/ProfLazyMode': [SKIP],
-
-  # platform-tls.h does not contain an ANDROID-related header.
-  'test-platform-tls/FastTLS': [SKIP],
-
-  # This test times out.
-  'test-threads/ThreadJoinSelf': [SKIP],
 }],  # 'arch == android_arm or arch == android_ia32'
 
 ##############################################################################
diff --git a/test/cctest/compiler/call-tester.h b/test/cctest/compiler/call-tester.h
index e864160..cad171e 100644
--- a/test/cctest/compiler/call-tester.h
+++ b/test/cctest/compiler/call-tester.h
@@ -207,7 +207,43 @@
         Simulator::CallArgument::End()};
     return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f), args));
   }
-#elif USE_SIMULATOR && V8_TARGET_ARCH_ARM
+#elif USE_SIMULATOR && V8_TARGET_ARCH_MIPS64
+  uintptr_t CallSimulator(byte* f, int64_t p1 = 0, int64_t p2 = 0,
+                          int64_t p3 = 0, int64_t p4 = 0) {
+    Simulator* simulator = Simulator::current(isolate_);
+    return static_cast<uintptr_t>(simulator->Call(f, 4, p1, p2, p3, p4));
+  }
+
+  template <typename R, typename F>
+  R DoCall(F* f) {
+    return ReturnValueTraits<R>::Cast(CallSimulator(FUNCTION_ADDR(f)));
+  }
+  template <typename R, typename F, typename P1>
+  R DoCall(F* f, P1 p1) {
+    return ReturnValueTraits<R>::Cast(
+        CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1)));
+  }
+  template <typename R, typename F, typename P1, typename P2>
+  R DoCall(F* f, P1 p1, P2 p2) {
+    return ReturnValueTraits<R>::Cast(
+        CallSimulator(FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
+                      ParameterTraits<P2>::Cast(p2)));
+  }
+  template <typename R, typename F, typename P1, typename P2, typename P3>
+  R DoCall(F* f, P1 p1, P2 p2, P3 p3) {
+    return ReturnValueTraits<R>::Cast(CallSimulator(
+        FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
+        ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3)));
+  }
+  template <typename R, typename F, typename P1, typename P2, typename P3,
+            typename P4>
+  R DoCall(F* f, P1 p1, P2 p2, P3 p3, P4 p4) {
+    return ReturnValueTraits<R>::Cast(CallSimulator(
+        FUNCTION_ADDR(f), ParameterTraits<P1>::Cast(p1),
+        ParameterTraits<P2>::Cast(p2), ParameterTraits<P3>::Cast(p3),
+        ParameterTraits<P4>::Cast(p4)));
+  }
+#elif USE_SIMULATOR && (V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS)
   uintptr_t CallSimulator(byte* f, int32_t p1 = 0, int32_t p2 = 0,
                           int32_t p3 = 0, int32_t p4 = 0) {
     Simulator* simulator = Simulator::current(isolate_);
diff --git a/test/cctest/compiler/codegen-tester.cc b/test/cctest/compiler/codegen-tester.cc
index b1874f5..5311001 100644
--- a/test/cctest/compiler/codegen-tester.cc
+++ b/test/cctest/compiler/codegen-tester.cc
@@ -14,7 +14,6 @@
 TEST(CompareWrapper) {
   // Who tests the testers?
   // If CompareWrapper is broken, then test expectations will be broken.
-  RawMachineAssemblerTester<int32_t> m;
   CompareWrapper wWord32Equal(IrOpcode::kWord32Equal);
   CompareWrapper wInt32LessThan(IrOpcode::kInt32LessThan);
   CompareWrapper wInt32LessThanOrEqual(IrOpcode::kInt32LessThanOrEqual);
@@ -477,10 +476,10 @@
 
 
 TEST(RunHeapNumberConstant) {
-  RawMachineAssemblerTester<Object*> m;
-  Handle<Object> number = m.isolate()->factory()->NewHeapNumber(100.5);
+  RawMachineAssemblerTester<HeapObject*> m;
+  Handle<HeapObject> number = m.isolate()->factory()->NewHeapNumber(100.5);
   m.Return(m.HeapConstant(number));
-  Object* result = m.Call();
+  HeapObject* result = m.Call();
   CHECK_EQ(result, *number);
 }
 
diff --git a/test/cctest/compiler/codegen-tester.h b/test/cctest/compiler/codegen-tester.h
index 6aa5bae..283d533 100644
--- a/test/cctest/compiler/codegen-tester.h
+++ b/test/cctest/compiler/codegen-tester.h
@@ -7,6 +7,7 @@
 
 #include "src/v8.h"
 
+#include "src/compiler/instruction-selector.h"
 #include "src/compiler/pipeline.h"
 #include "src/compiler/raw-machine-assembler.h"
 #include "src/simulator.h"
@@ -23,7 +24,9 @@
  public:
   MachineAssemblerTester(MachineType return_type, MachineType p0,
                          MachineType p1, MachineType p2, MachineType p3,
-                         MachineType p4)
+                         MachineType p4,
+                         MachineOperatorBuilder::Flags flags =
+                             MachineOperatorBuilder::Flag::kNoFlags)
       : HandleAndZoneScope(),
         CallHelper(
             main_isolate(),
@@ -31,7 +34,7 @@
         MachineAssembler(
             new (main_zone()) Graph(main_zone()),
             MakeMachineSignature(main_zone(), return_type, p0, p1, p2, p3, p4),
-            kMachPtr) {}
+            kMachPtr, flags) {}
 
   Node* LoadFromPointer(void* address, MachineType rep, int32_t offset = 0) {
     return this->Load(rep, this->PointerConstant(address),
@@ -65,10 +68,8 @@
       Schedule* schedule = this->Export();
       CallDescriptor* call_descriptor = this->call_descriptor();
       Graph* graph = this->graph();
-      CompilationInfo info(graph->zone()->isolate(), graph->zone());
-      Linkage linkage(&info, call_descriptor);
-      Pipeline pipeline(&info);
-      code_ = pipeline.GenerateCodeForMachineGraph(&linkage, graph, schedule);
+      code_ =
+          Pipeline::GenerateCodeForTesting(call_descriptor, graph, schedule);
     }
     return this->code_.ToHandleChecked()->entry();
   }
@@ -89,8 +90,8 @@
                             MachineType p3 = kMachNone,
                             MachineType p4 = kMachNone)
       : MachineAssemblerTester<RawMachineAssembler>(
-            ReturnValueTraits<ReturnType>::Representation(), p0, p1, p2, p3,
-            p4) {}
+            ReturnValueTraits<ReturnType>::Representation(), p0, p1, p2, p3, p4,
+            InstructionSelector::SupportedMachineOperatorFlags()) {}
 
   template <typename Ci, typename Fn>
   void Run(const Ci& ci, const Fn& fn) {
diff --git a/test/cctest/compiler/function-tester.h b/test/cctest/compiler/function-tester.h
index c869f00..7e16eea 100644
--- a/test/cctest/compiler/function-tester.h
+++ b/test/cctest/compiler/function-tester.h
@@ -8,7 +8,9 @@
 #include "src/v8.h"
 #include "test/cctest/cctest.h"
 
+#include "src/ast-numbering.h"
 #include "src/compiler.h"
+#include "src/compiler/linkage.h"
 #include "src/compiler/pipeline.h"
 #include "src/execution.h"
 #include "src/full-codegen.h"
@@ -37,52 +39,16 @@
     CHECK_EQ(0, flags_ & ~supported_flags);
   }
 
+  explicit FunctionTester(Graph* graph)
+      : isolate(main_isolate()),
+        function(NewFunction("(function(a,b){})")),
+        flags_(0) {
+    CompileGraph(graph);
+  }
+
   Isolate* isolate;
   Handle<JSFunction> function;
 
-  Handle<JSFunction> Compile(Handle<JSFunction> function) {
-#if V8_TURBOFAN_TARGET
-    CompilationInfoWithZone info(function);
-
-    CHECK(Parser::Parse(&info));
-    info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
-    if (flags_ & CompilationInfo::kContextSpecializing) {
-      info.MarkAsContextSpecializing();
-    }
-    if (flags_ & CompilationInfo::kInliningEnabled) {
-      info.MarkAsInliningEnabled();
-    }
-    if (flags_ & CompilationInfo::kTypingEnabled) {
-      info.MarkAsTypingEnabled();
-    }
-    CHECK(Rewriter::Rewrite(&info));
-    CHECK(Scope::Analyze(&info));
-    CHECK(Compiler::EnsureDeoptimizationSupport(&info));
-
-    Pipeline pipeline(&info);
-    Handle<Code> code = pipeline.GenerateCode();
-    if (FLAG_turbo_deoptimization) {
-      info.context()->native_context()->AddOptimizedCode(*code);
-    }
-
-    CHECK(!code.is_null());
-    function->ReplaceCode(*code);
-#elif USE_CRANKSHAFT
-    Handle<Code> unoptimized = Handle<Code>(function->code());
-    Handle<Code> code = Compiler::GetOptimizedCode(function, unoptimized,
-                                                   Compiler::NOT_CONCURRENT);
-    CHECK(!code.is_null());
-#if ENABLE_DISASSEMBLER
-    if (FLAG_print_opt_code) {
-      CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
-      code->Disassemble("test code", tracing_scope.file());
-    }
-#endif
-    function->ReplaceCode(*code);
-#endif
-    return function;
-  }
-
   MaybeHandle<Object> Call(Handle<Object> a, Handle<Object> b) {
     Handle<Object> args[] = {a, b};
     return Execution::Call(isolate, function, undefined(), 2, args, false);
@@ -183,8 +149,78 @@
 
   Handle<Object> false_value() { return isolate->factory()->false_value(); }
 
+  Handle<JSFunction> Compile(Handle<JSFunction> function) {
+// TODO(titzer): make this method private.
+#if V8_TURBOFAN_TARGET
+    CompilationInfoWithZone info(function);
+
+    CHECK(Parser::Parse(&info));
+    info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
+    if (flags_ & CompilationInfo::kContextSpecializing) {
+      info.MarkAsContextSpecializing();
+    }
+    if (flags_ & CompilationInfo::kInliningEnabled) {
+      info.MarkAsInliningEnabled();
+    }
+    if (flags_ & CompilationInfo::kTypingEnabled) {
+      info.MarkAsTypingEnabled();
+    }
+    CHECK(Compiler::Analyze(&info));
+    CHECK(Compiler::EnsureDeoptimizationSupport(&info));
+
+    Pipeline pipeline(&info);
+    Handle<Code> code = pipeline.GenerateCode();
+    if (FLAG_turbo_deoptimization) {
+      info.context()->native_context()->AddOptimizedCode(*code);
+    }
+
+    CHECK(!code.is_null());
+    function->ReplaceCode(*code);
+#elif USE_CRANKSHAFT
+    Handle<Code> unoptimized = Handle<Code>(function->code());
+    Handle<Code> code = Compiler::GetOptimizedCode(function, unoptimized,
+                                                   Compiler::NOT_CONCURRENT);
+    CHECK(!code.is_null());
+#if ENABLE_DISASSEMBLER
+    if (FLAG_print_opt_code) {
+      CodeTracer::Scope tracing_scope(isolate->GetCodeTracer());
+      code->Disassemble("test code", tracing_scope.file());
+    }
+#endif
+    function->ReplaceCode(*code);
+#endif
+    return function;
+  }
+
+  static Handle<JSFunction> ForMachineGraph(Graph* graph) {
+    JSFunction* p = NULL;
+    {  // because of the implicit handle scope of FunctionTester.
+      FunctionTester f(graph);
+      p = *f.function;
+    }
+    return Handle<JSFunction>(p);  // allocated in outer handle scope.
+  }
+
  private:
   uint32_t flags_;
+
+  // Compile the given machine graph instead of the source of the function
+  // and replace the JSFunction's code with the result.
+  Handle<JSFunction> CompileGraph(Graph* graph) {
+    CHECK(Pipeline::SupportedTarget());
+    CompilationInfoWithZone info(function);
+
+    CHECK(Parser::Parse(&info));
+    info.SetOptimizing(BailoutId::None(),
+                       Handle<Code>(function->shared()->code()));
+    CHECK(Compiler::Analyze(&info));
+    CHECK(Compiler::EnsureDeoptimizationSupport(&info));
+
+    Handle<Code> code = Pipeline::GenerateCodeForTesting(&info, graph);
+    CHECK(!code.is_null());
+    function->ReplaceCode(*code);
+    return function;
+  }
 };
 }
 }
diff --git a/test/cctest/compiler/graph-builder-tester.cc b/test/cctest/compiler/graph-builder-tester.cc
index bfa8226..b0f470b 100644
--- a/test/cctest/compiler/graph-builder-tester.cc
+++ b/test/cctest/compiler/graph-builder-tester.cc
@@ -35,11 +35,9 @@
   if (!Pipeline::SupportedBackend()) return NULL;
   if (code_.is_null()) {
     Zone* zone = graph_->zone();
-    CompilationInfo info(zone->isolate(), zone);
-    Linkage linkage(&info,
-                    Linkage::GetSimplifiedCDescriptor(zone, machine_sig_));
-    Pipeline pipeline(&info);
-    code_ = pipeline.GenerateCodeForMachineGraph(&linkage, graph_);
+    CallDescriptor* desc =
+        Linkage::GetSimplifiedCDescriptor(zone, machine_sig_);
+    code_ = Pipeline::GenerateCodeForTesting(desc, graph_);
   }
   return code_.ToHandleChecked()->entry();
 }
diff --git a/test/cctest/compiler/graph-builder-tester.h b/test/cctest/compiler/graph-builder-tester.h
index df79250..772de4d 100644
--- a/test/cctest/compiler/graph-builder-tester.h
+++ b/test/cctest/compiler/graph-builder-tester.h
@@ -27,8 +27,8 @@
 
  protected:
   virtual Node* MakeNode(const Operator* op, int value_input_count,
-                         Node** value_inputs) FINAL {
-    return graph()->NewNode(op, value_input_count, value_inputs);
+                         Node** value_inputs, bool incomplete) FINAL {
+    return graph()->NewNode(op, value_input_count, value_inputs, incomplete);
   }
 };
 
@@ -61,6 +61,7 @@
   explicit GraphAndBuilders(Zone* zone)
       : main_graph_(new (zone) Graph(zone)),
         main_common_(zone),
+        main_machine_(zone),
         main_simplified_(zone) {}
 
  protected:
diff --git a/test/cctest/compiler/simplified-graph-builder.cc b/test/cctest/compiler/simplified-graph-builder.cc
index c44d5ed..baa03fb 100644
--- a/test/cctest/compiler/simplified-graph-builder.cc
+++ b/test/cctest/compiler/simplified-graph-builder.cc
@@ -5,7 +5,6 @@
 #include "test/cctest/compiler/simplified-graph-builder.h"
 
 #include "src/compiler/operator-properties.h"
-#include "src/compiler/operator-properties-inl.h"
 
 namespace v8 {
 namespace internal {
@@ -45,20 +44,20 @@
 
 Node* SimplifiedGraphBuilder::MakeNode(const Operator* op,
                                        int value_input_count,
-                                       Node** value_inputs) {
-  DCHECK(op->InputCount() == value_input_count);
+                                       Node** value_inputs, bool incomplete) {
+  DCHECK(op->ValueInputCount() == value_input_count);
 
   DCHECK(!OperatorProperties::HasContextInput(op));
   DCHECK(!OperatorProperties::HasFrameStateInput(op));
-  bool has_control = OperatorProperties::GetControlInputCount(op) == 1;
-  bool has_effect = OperatorProperties::GetEffectInputCount(op) == 1;
+  bool has_control = op->ControlInputCount() == 1;
+  bool has_effect = op->EffectInputCount() == 1;
 
-  DCHECK(OperatorProperties::GetControlInputCount(op) < 2);
-  DCHECK(OperatorProperties::GetEffectInputCount(op) < 2);
+  DCHECK(op->ControlInputCount() < 2);
+  DCHECK(op->EffectInputCount() < 2);
 
   Node* result = NULL;
   if (!has_control && !has_effect) {
-    result = graph()->NewNode(op, value_input_count, value_inputs);
+    result = graph()->NewNode(op, value_input_count, value_inputs, incomplete);
   } else {
     int input_count_with_deps = value_input_count;
     if (has_control) ++input_count_with_deps;
@@ -72,14 +71,12 @@
     if (has_control) {
       *current_input++ = graph()->start();
     }
-    result = graph()->NewNode(op, input_count_with_deps, buffer);
+    result = graph()->NewNode(op, input_count_with_deps, buffer, incomplete);
     if (has_effect) {
       effect_ = result;
     }
-    if (OperatorProperties::HasControlOutput(result->op())) {
-      // This graph builder does not support control flow.
-      UNREACHABLE();
-    }
+    // This graph builder does not support control flow.
+    CHECK_EQ(0, op->ControlOutputCount());
   }
 
   return result;
diff --git a/test/cctest/compiler/simplified-graph-builder.h b/test/cctest/compiler/simplified-graph-builder.h
index 1b637b7..537094a 100644
--- a/test/cctest/compiler/simplified-graph-builder.h
+++ b/test/cctest/compiler/simplified-graph-builder.h
@@ -45,8 +45,8 @@
   Node* Int32Constant(int32_t value) {
     return NewNode(common()->Int32Constant(value));
   }
-  Node* HeapConstant(Handle<Object> object) {
-    Unique<Object> val = Unique<Object>::CreateUninitialized(object);
+  Node* HeapConstant(Handle<HeapObject> object) {
+    Unique<HeapObject> val = Unique<HeapObject>::CreateUninitialized(object);
     return NewNode(common()->HeapConstant(val));
   }
 
@@ -127,19 +127,17 @@
   Node* StoreField(const FieldAccess& access, Node* object, Node* value) {
     return NewNode(simplified()->StoreField(access), object, value);
   }
-  Node* LoadElement(const ElementAccess& access, Node* object, Node* index,
-                    Node* length) {
-    return NewNode(simplified()->LoadElement(access), object, index, length);
+  Node* LoadElement(const ElementAccess& access, Node* object, Node* index) {
+    return NewNode(simplified()->LoadElement(access), object, index);
   }
   Node* StoreElement(const ElementAccess& access, Node* object, Node* index,
-                     Node* length, Node* value) {
-    return NewNode(simplified()->StoreElement(access), object, index, length,
-                   value);
+                     Node* value) {
+    return NewNode(simplified()->StoreElement(access), object, index, value);
   }
 
  protected:
   virtual Node* MakeNode(const Operator* op, int value_input_count,
-                         Node** value_inputs) FINAL;
+                         Node** value_inputs, bool incomplete) FINAL;
 
  private:
   Node* effect_;
diff --git a/test/cctest/compiler/test-basic-block-profiler.cc b/test/cctest/compiler/test-basic-block-profiler.cc
new file mode 100644
index 0000000..703fc17
--- /dev/null
+++ b/test/cctest/compiler/test-basic-block-profiler.cc
@@ -0,0 +1,114 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/basic-block-profiler.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/codegen-tester.h"
+
+#if V8_TURBOFAN_TARGET
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+typedef RawMachineAssembler::Label MLabel;
+
+class BasicBlockProfilerTest : public RawMachineAssemblerTester<int32_t> {
+ public:
+  BasicBlockProfilerTest() : RawMachineAssemblerTester<int32_t>(kMachInt32) {
+    FLAG_turbo_profiling = true;
+  }
+
+  void ResetCounts() { isolate()->basic_block_profiler()->ResetCounts(); }
+
+  void Expect(size_t size, uint32_t* expected) {
+    CHECK_NE(NULL, isolate()->basic_block_profiler());
+    const BasicBlockProfiler::DataList* l =
+        isolate()->basic_block_profiler()->data_list();
+    CHECK_NE(0, static_cast<int>(l->size()));
+    const BasicBlockProfiler::Data* data = l->back();
+    CHECK_EQ(static_cast<int>(size), static_cast<int>(data->n_blocks()));
+    const uint32_t* counts = data->counts();
+    for (size_t i = 0; i < size; ++i) {
+      CHECK_EQ(static_cast<int>(expected[i]), static_cast<int>(counts[i]));
+    }
+  }
+};
+
+
+TEST(ProfileDiamond) {
+  BasicBlockProfilerTest m;
+
+  MLabel blocka, blockb, end;
+  m.Branch(m.Parameter(0), &blocka, &blockb);
+  m.Bind(&blocka);
+  m.Goto(&end);
+  m.Bind(&blockb);
+  m.Goto(&end);
+  m.Bind(&end);
+  m.Return(m.Int32Constant(0));
+
+  m.GenerateCode();
+  {
+    uint32_t expected[] = {0, 0, 0, 0};
+    m.Expect(arraysize(expected), expected);
+  }
+
+  m.Call(0);
+  {
+    uint32_t expected[] = {1, 1, 0, 1};
+    m.Expect(arraysize(expected), expected);
+  }
+
+  m.ResetCounts();
+
+  m.Call(1);
+  {
+    uint32_t expected[] = {1, 0, 1, 1};
+    m.Expect(arraysize(expected), expected);
+  }
+
+  m.Call(0);
+  {
+    uint32_t expected[] = {2, 1, 1, 2};
+    m.Expect(arraysize(expected), expected);
+  }
+}
+
+
+TEST(ProfileLoop) {
+  BasicBlockProfilerTest m;
+
+  MLabel header, body, end;
+  Node* one = m.Int32Constant(1);
+  m.Goto(&header);
+
+  m.Bind(&header);
+  Node* count = m.Phi(kMachInt32, m.Parameter(0), one);
+  m.Branch(count, &body, &end);
+
+  m.Bind(&body);
+  count->ReplaceInput(1, m.Int32Sub(count, one));
+  m.Goto(&header);
+
+  m.Bind(&end);
+  m.Return(one);
+
+  m.GenerateCode();
+  {
+    uint32_t expected[] = {0, 0, 0, 0};
+    m.Expect(arraysize(expected), expected);
+  }
+
+  uint32_t runs[] = {0, 1, 500, 10000};
+  for (size_t i = 0; i < arraysize(runs); i++) {
+    m.ResetCounts();
+    CHECK_EQ(1, m.Call(static_cast<int>(runs[i])));
+    uint32_t expected[] = {1, runs[i] + 1, runs[i], 1};
+    m.Expect(arraysize(expected), expected);
+  }
+}
+
+#endif  // V8_TURBOFAN_TARGET
diff --git a/test/cctest/compiler/test-changes-lowering.cc b/test/cctest/compiler/test-changes-lowering.cc
index 06308a0..5795754 100644
--- a/test/cctest/compiler/test-changes-lowering.cc
+++ b/test/cctest/compiler/test-changes-lowering.cc
@@ -6,10 +6,11 @@
 
 #include "src/compiler/change-lowering.h"
 #include "src/compiler/control-builders.h"
-#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/compiler/pipeline.h"
+#include "src/compiler/select-lowering.h"
+#include "src/compiler/simplified-lowering.h"
 #include "src/compiler/typer.h"
 #include "src/compiler/verifier.h"
 #include "src/execution.h"
@@ -19,6 +20,7 @@
 #include "src/scopes.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/codegen-tester.h"
+#include "test/cctest/compiler/function-tester.h"
 #include "test/cctest/compiler/graph-builder-tester.h"
 #include "test/cctest/compiler/value-helper.h"
 
@@ -30,13 +32,10 @@
  public:
   explicit ChangesLoweringTester(MachineType p0 = kMachNone)
       : GraphBuilderTester<ReturnType>(p0),
-        typer(this->zone()),
         javascript(this->zone()),
-        jsgraph(this->graph(), this->common(), &javascript, &typer,
-                this->machine()),
+        jsgraph(this->graph(), this->common(), &javascript, this->machine()),
         function(Handle<JSFunction>::null()) {}
 
-  Typer typer;
   JSOperatorBuilder javascript;
   JSGraph jsgraph;
   Handle<JSFunction> function;
@@ -45,29 +44,10 @@
 
   template <typename T>
   T* CallWithPotentialGC() {
-    // TODO(titzer): we need to wrap the code in a JSFunction and call it via
-    // Execution::Call() so that the GC knows about the frame, can walk it,
-    // relocate the code object if necessary, etc.
-    // This is pretty ugly and at the least should be moved up to helpers.
+    // TODO(titzer): we wrap the code in a JSFunction here to reuse the
+    // JSEntryStub; that could be done with a special prologue or other stub.
     if (function.is_null()) {
-      function =
-          v8::Utils::OpenHandle(*v8::Handle<v8::Function>::Cast(CompileRun(
-              "(function() { 'use strict'; return 2.7123; })")));
-      CompilationInfoWithZone info(function);
-      CHECK(Parser::Parse(&info));
-      info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
-      CHECK(Rewriter::Rewrite(&info));
-      CHECK(Scope::Analyze(&info));
-      CHECK_NE(NULL, info.scope());
-      Handle<ScopeInfo> scope_info =
-          ScopeInfo::Create(info.scope(), info.zone());
-      info.shared_info()->set_scope_info(*scope_info);
-      Pipeline pipeline(&info);
-      Linkage linkage(&info);
-      Handle<Code> code =
-          pipeline.GenerateCodeForMachineGraph(&linkage, this->graph());
-      CHECK(!code.is_null());
-      function->ReplaceCode(*code);
+      function = FunctionTester::ForMachineGraph(this->graph());
     }
     Handle<Object>* args = NULL;
     MaybeHandle<Object> result =
@@ -132,9 +112,9 @@
                          void* location) {
     // We build a graph by hand here, because the raw machine assembler
     // does not add the correct control and effect nodes.
-    Node* load =
-        this->graph()->NewNode(load_op, this->PointerConstant(location),
-                               this->Int32Constant(0), this->start());
+    Node* load = this->graph()->NewNode(
+        load_op, this->PointerConstant(location), this->Int32Constant(0),
+        this->start(), this->start());
     Node* change = this->graph()->NewNode(op, load);
     Node* ret = this->graph()->NewNode(this->common()->Return(), change,
                                        this->start(), this->start());
@@ -146,12 +126,16 @@
   void LowerChange(Node* change) {
     // Run the graph reducer with changes lowering on a single node.
     CompilationInfo info(this->isolate(), this->zone());
-    Linkage linkage(&info);
-    ChangeLowering lowering(&jsgraph, &linkage);
-    GraphReducer reducer(this->graph());
-    reducer.AddReducer(&lowering);
+    Linkage linkage(this->zone(), &info);
+    Typer typer(this->graph(), info.context());
+    typer.Run();
+    ChangeLowering change_lowering(&jsgraph, &linkage);
+    SelectLowering select_lowering(this->graph(), this->common());
+    GraphReducer reducer(this->graph(), this->zone());
+    reducer.AddReducer(&change_lowering);
+    reducer.AddReducer(&select_lowering);
     reducer.ReduceNode(change);
-    Verifier::Run(this->graph());
+    Verifier::Run(this->graph(), Verifier::UNTYPED);
   }
 
   Factory* factory() { return this->isolate()->factory(); }
diff --git a/test/cctest/compiler/test-codegen-deopt.cc b/test/cctest/compiler/test-codegen-deopt.cc
index 8217229..56afe7b 100644
--- a/test/cctest/compiler/test-codegen-deopt.cc
+++ b/test/cctest/compiler/test-codegen-deopt.cc
@@ -16,6 +16,7 @@
 #include "src/compiler/register-allocator.h"
 #include "src/compiler/schedule.h"
 
+#include "src/ast-numbering.h"
 #include "src/full-codegen.h"
 #include "src/parser.h"
 #include "src/rewriter.h"
@@ -30,6 +31,7 @@
 #if V8_TURBOFAN_TARGET
 
 typedef RawMachineAssembler::Label MLabel;
+typedef v8::internal::compiler::InstructionSequence TestInstrSeq;
 
 static Handle<JSFunction> NewFunction(const char* source) {
   return v8::Utils::OpenHandle(
@@ -46,8 +48,7 @@
         bailout_id(-1) {
     CHECK(Parser::Parse(&info));
     info.SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
-    CHECK(Rewriter::Rewrite(&info));
-    CHECK(Scope::Analyze(&info));
+    CHECK(Compiler::Analyze(&info));
     CHECK(Compiler::EnsureDeoptimizationSupport(&info));
 
     DCHECK(info.shared_info()->has_deoptimization_support());
@@ -55,38 +56,14 @@
     graph = new (scope_->main_zone()) Graph(scope_->main_zone());
   }
 
-  virtual ~DeoptCodegenTester() { delete code; }
+  virtual ~DeoptCodegenTester() {}
 
   void GenerateCodeFromSchedule(Schedule* schedule) {
     OFStream os(stdout);
     if (FLAG_trace_turbo) {
       os << *schedule;
     }
-
-    // Initialize the codegen and generate code.
-    Linkage* linkage = new (scope_->main_zone()) Linkage(&info);
-    code = new v8::internal::compiler::InstructionSequence(linkage, graph,
-                                                           schedule);
-    SourcePositionTable source_positions(graph);
-    InstructionSelector selector(code, &source_positions);
-    selector.SelectInstructions();
-
-    if (FLAG_trace_turbo) {
-      os << "----- Instruction sequence before register allocation -----\n"
-         << *code;
-    }
-
-    RegisterAllocator allocator(code);
-    CHECK(allocator.Allocate());
-
-    if (FLAG_trace_turbo) {
-      os << "----- Instruction sequence after register allocation -----\n"
-         << *code;
-    }
-
-    compiler::CodeGenerator generator(code);
-    result_code = generator.GenerateCode();
-
+    result_code = Pipeline::GenerateCodeForTesting(&info, graph, schedule);
 #ifdef OBJECT_PRINT
     if (FLAG_print_opt_code || FLAG_trace_turbo) {
       result_code->Print();
@@ -101,7 +78,7 @@
   CompilationInfo info;
   BailoutId bailout_id;
   Handle<Code> result_code;
-  v8::internal::compiler::InstructionSequence* code;
+  TestInstrSeq* code;
   Graph* graph;
 };
 
@@ -129,13 +106,13 @@
 
     Handle<JSFunction> deopt_function =
         NewFunction("function deopt() { %DeoptimizeFunction(foo); }; deopt");
-    Unique<Object> deopt_fun_constant =
-        Unique<Object>::CreateUninitialized(deopt_function);
+    Unique<JSFunction> deopt_fun_constant =
+        Unique<JSFunction>::CreateUninitialized(deopt_function);
     Node* deopt_fun_node = m.NewNode(common.HeapConstant(deopt_fun_constant));
 
     Handle<Context> caller_context(function->context(), CcTest::i_isolate());
-    Unique<Object> caller_context_constant =
-        Unique<Object>::CreateUninitialized(caller_context);
+    Unique<Context> caller_context_constant =
+        Unique<Context>::CreateUninitialized(caller_context);
     Node* caller_context_node =
         m.NewNode(common.HeapConstant(caller_context_constant));
 
@@ -145,12 +122,13 @@
     Node* stack = m.NewNode(common.StateValues(0));
 
     Node* state_node = m.NewNode(
-        common.FrameState(JS_FRAME, bailout_id, kIgnoreOutput), parameters,
-        locals, stack, caller_context_node, m.UndefinedConstant());
+        common.FrameState(JS_FRAME, bailout_id,
+                          OutputFrameStateCombine::Ignore()),
+        parameters, locals, stack, caller_context_node, m.UndefinedConstant());
 
     Handle<Context> context(deopt_function->context(), CcTest::i_isolate());
-    Unique<Object> context_constant =
-        Unique<Object>::CreateUninitialized(context);
+    Unique<Context> context_constant =
+        Unique<Context>::CreateUninitialized(context);
     Node* context_node = m.NewNode(common.HeapConstant(context_constant));
 
     m.CallJS0(deopt_fun_node, m.UndefinedConstant(), context_node, state_node);
@@ -244,13 +222,13 @@
     CSignature1<Object*, Object*> sig;
     RawMachineAssembler m(graph, &sig);
 
-    Unique<Object> this_fun_constant =
-        Unique<Object>::CreateUninitialized(function);
+    Unique<HeapObject> this_fun_constant =
+        Unique<HeapObject>::CreateUninitialized(function);
     Node* this_fun_node = m.NewNode(common.HeapConstant(this_fun_constant));
 
     Handle<Context> context(function->context(), CcTest::i_isolate());
-    Unique<Object> context_constant =
-        Unique<Object>::CreateUninitialized(context);
+    Unique<HeapObject> context_constant =
+        Unique<HeapObject>::CreateUninitialized(context);
     Node* context_node = m.NewNode(common.HeapConstant(context_constant));
 
     bailout_id = GetCallBailoutId();
@@ -259,8 +237,9 @@
     Node* stack = m.NewNode(common.StateValues(0));
 
     Node* state_node = m.NewNode(
-        common.FrameState(JS_FRAME, bailout_id, kIgnoreOutput), parameters,
-        locals, stack, context_node, m.UndefinedConstant());
+        common.FrameState(JS_FRAME, bailout_id,
+                          OutputFrameStateCombine::Ignore()),
+        parameters, locals, stack, context_node, m.UndefinedConstant());
 
     m.CallRuntime1(Runtime::kDeoptimizeFunction, this_fun_node, context_node,
                    state_node);
diff --git a/test/cctest/compiler/test-control-reducer.cc b/test/cctest/compiler/test-control-reducer.cc
new file mode 100644
index 0000000..03aa50b
--- /dev/null
+++ b/test/cctest/compiler/test-control-reducer.cc
@@ -0,0 +1,1678 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/base/bits.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/control-reducer.h"
+#include "src/compiler/graph-inl.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/node-properties-inl.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+static const size_t kNumLeafs = 4;
+
+// TODO(titzer): convert this whole file into unit tests.
+
+static int CheckInputs(Node* node, Node* i0 = NULL, Node* i1 = NULL,
+                       Node* i2 = NULL) {
+  int count = 3;
+  if (i2 == NULL) count = 2;
+  if (i1 == NULL) count = 1;
+  if (i0 == NULL) count = 0;
+  CHECK_EQ(count, node->InputCount());
+  if (i0 != NULL) CHECK_EQ(i0, node->InputAt(0));
+  if (i1 != NULL) CHECK_EQ(i1, node->InputAt(1));
+  if (i2 != NULL) CHECK_EQ(i2, node->InputAt(2));
+  return count;
+}
+
+
+static int CheckMerge(Node* node, Node* i0 = NULL, Node* i1 = NULL,
+                      Node* i2 = NULL) {
+  CHECK_EQ(IrOpcode::kMerge, node->opcode());
+  int count = CheckInputs(node, i0, i1, i2);
+  CHECK_EQ(count, node->op()->ControlInputCount());
+  return count;
+}
+
+
+static int CheckLoop(Node* node, Node* i0 = NULL, Node* i1 = NULL,
+                     Node* i2 = NULL) {
+  CHECK_EQ(IrOpcode::kLoop, node->opcode());
+  int count = CheckInputs(node, i0, i1, i2);
+  CHECK_EQ(count, node->op()->ControlInputCount());
+  return count;
+}
+
+
+bool IsUsedBy(Node* a, Node* b) {
+  for (UseIter i = a->uses().begin(); i != a->uses().end(); ++i) {
+    if (b == *i) return true;
+  }
+  return false;
+}
+
+
+// A helper for all tests dealing with ControlTester.
+class ControlReducerTester : HandleAndZoneScope {
+ public:
+  ControlReducerTester()
+      : isolate(main_isolate()),
+        common(main_zone()),
+        graph(main_zone()),
+        jsgraph(&graph, &common, NULL, NULL),
+        start(graph.NewNode(common.Start(1))),
+        end(graph.NewNode(common.End(), start)),
+        p0(graph.NewNode(common.Parameter(0), start)),
+        zero(jsgraph.Int32Constant(0)),
+        one(jsgraph.OneConstant()),
+        half(jsgraph.Constant(0.5)),
+        self(graph.NewNode(common.Int32Constant(0xaabbccdd))),
+        dead(graph.NewNode(common.Dead())) {
+    graph.SetEnd(end);
+    graph.SetStart(start);
+    leaf[0] = zero;
+    leaf[1] = one;
+    leaf[2] = half;
+    leaf[3] = p0;
+  }
+
+  Isolate* isolate;
+  CommonOperatorBuilder common;
+  Graph graph;
+  JSGraph jsgraph;
+  Node* start;
+  Node* end;
+  Node* p0;
+  Node* zero;
+  Node* one;
+  Node* half;
+  Node* self;
+  Node* dead;
+  Node* leaf[kNumLeafs];
+
+  Node* Phi(Node* a) {
+    return SetSelfReferences(graph.NewNode(op(1, false), a, start));
+  }
+
+  Node* Phi(Node* a, Node* b) {
+    return SetSelfReferences(graph.NewNode(op(2, false), a, b, start));
+  }
+
+  Node* Phi(Node* a, Node* b, Node* c) {
+    return SetSelfReferences(graph.NewNode(op(3, false), a, b, c, start));
+  }
+
+  Node* Phi(Node* a, Node* b, Node* c, Node* d) {
+    return SetSelfReferences(graph.NewNode(op(4, false), a, b, c, d, start));
+  }
+
+  Node* EffectPhi(Node* a) {
+    return SetSelfReferences(graph.NewNode(op(1, true), a, start));
+  }
+
+  Node* EffectPhi(Node* a, Node* b) {
+    return SetSelfReferences(graph.NewNode(op(2, true), a, b, start));
+  }
+
+  Node* EffectPhi(Node* a, Node* b, Node* c) {
+    return SetSelfReferences(graph.NewNode(op(3, true), a, b, c, start));
+  }
+
+  Node* EffectPhi(Node* a, Node* b, Node* c, Node* d) {
+    return SetSelfReferences(graph.NewNode(op(4, true), a, b, c, d, start));
+  }
+
+  Node* SetSelfReferences(Node* node) {
+    for (Edge edge : node->input_edges()) {
+      if (edge.to() == self) node->ReplaceInput(edge.index(), node);
+    }
+    return node;
+  }
+
+  const Operator* op(int count, bool effect) {
+    return effect ? common.EffectPhi(count) : common.Phi(kMachAnyTagged, count);
+  }
+
+  void Trim() { ControlReducer::TrimGraph(main_zone(), &jsgraph); }
+
+  void ReduceGraph() {
+    ControlReducer::ReduceGraph(main_zone(), &jsgraph, &common);
+  }
+
+  // Checks one-step reduction of a phi.
+  void ReducePhi(Node* expect, Node* phi) {
+    Node* result = ControlReducer::ReducePhiForTesting(&jsgraph, &common, phi);
+    CHECK_EQ(expect, result);
+    ReducePhiIterative(expect, phi);  // iterative should give the same result.
+  }
+
+  void ReducePhiIterative(Node* expect, Node* phi) {
+    p0->ReplaceInput(0, start);  // hack: parameters may be trimmed.
+    Node* ret = graph.NewNode(common.Return(), phi, start, start);
+    Node* end = graph.NewNode(common.End(), ret);
+    graph.SetEnd(end);
+    ControlReducer::ReduceGraph(main_zone(), &jsgraph, &common);
+    CheckInputs(end, ret);
+    CheckInputs(ret, expect, start, start);
+  }
+
+  void ReduceMerge(Node* expect, Node* merge) {
+    Node* result =
+        ControlReducer::ReduceMergeForTesting(&jsgraph, &common, merge);
+    CHECK_EQ(expect, result);
+  }
+
+  void ReduceMergeIterative(Node* expect, Node* merge) {
+    p0->ReplaceInput(0, start);  // hack: parameters may be trimmed.
+    Node* end = graph.NewNode(common.End(), merge);
+    graph.SetEnd(end);
+    ReduceGraph();
+    CheckInputs(end, expect);
+  }
+
+  void ReduceBranch(Node* expect, Node* branch) {
+    Node* result =
+        ControlReducer::ReduceBranchForTesting(&jsgraph, &common, branch);
+    CHECK_EQ(expect, result);
+  }
+
+  Node* Return(Node* val, Node* effect, Node* control) {
+    Node* ret = graph.NewNode(common.Return(), val, effect, control);
+    end->ReplaceInput(0, ret);
+    return ret;
+  }
+};
+
+
+TEST(Trim1_live) {
+  ControlReducerTester T;
+  CHECK(IsUsedBy(T.start, T.p0));
+  T.graph.SetEnd(T.p0);
+  T.Trim();
+  CHECK(IsUsedBy(T.start, T.p0));
+  CheckInputs(T.p0, T.start);
+}
+
+
+TEST(Trim1_dead) {
+  ControlReducerTester T;
+  CHECK(IsUsedBy(T.start, T.p0));
+  T.Trim();
+  CHECK(!IsUsedBy(T.start, T.p0));
+  CHECK_EQ(NULL, T.p0->InputAt(0));
+}
+
+
+TEST(Trim2_live) {
+  ControlReducerTester T;
+  Node* phi =
+      T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, T.start);
+  CHECK(IsUsedBy(T.one, phi));
+  CHECK(IsUsedBy(T.half, phi));
+  CHECK(IsUsedBy(T.start, phi));
+  T.graph.SetEnd(phi);
+  T.Trim();
+  CHECK(IsUsedBy(T.one, phi));
+  CHECK(IsUsedBy(T.half, phi));
+  CHECK(IsUsedBy(T.start, phi));
+  CheckInputs(phi, T.one, T.half, T.start);
+}
+
+
+TEST(Trim2_dead) {
+  ControlReducerTester T;
+  Node* phi =
+      T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, T.start);
+  CHECK(IsUsedBy(T.one, phi));
+  CHECK(IsUsedBy(T.half, phi));
+  CHECK(IsUsedBy(T.start, phi));
+  T.Trim();
+  CHECK(!IsUsedBy(T.one, phi));
+  CHECK(!IsUsedBy(T.half, phi));
+  CHECK(!IsUsedBy(T.start, phi));
+  CHECK_EQ(NULL, phi->InputAt(0));
+  CHECK_EQ(NULL, phi->InputAt(1));
+  CHECK_EQ(NULL, phi->InputAt(2));
+}
+
+
+TEST(Trim_chain1) {
+  ControlReducerTester T;
+  const int kDepth = 15;
+  Node* live[kDepth];
+  Node* dead[kDepth];
+  Node* end = T.start;
+  for (int i = 0; i < kDepth; i++) {
+    live[i] = end = T.graph.NewNode(T.common.Merge(1), end);
+    dead[i] = T.graph.NewNode(T.common.Merge(1), end);
+  }
+  // end         -> live[last] ->  live[last-1] -> ... -> start
+  //     dead[last] ^ dead[last-1] ^ ...                  ^
+  T.graph.SetEnd(end);
+  T.Trim();
+  for (int i = 0; i < kDepth; i++) {
+    CHECK(!IsUsedBy(live[i], dead[i]));
+    CHECK_EQ(NULL, dead[i]->InputAt(0));
+    CHECK_EQ(i == 0 ? T.start : live[i - 1], live[i]->InputAt(0));
+  }
+}
+
+
+TEST(Trim_chain2) {
+  ControlReducerTester T;
+  const int kDepth = 15;
+  Node* live[kDepth];
+  Node* dead[kDepth];
+  Node* l = T.start;
+  Node* d = T.start;
+  for (int i = 0; i < kDepth; i++) {
+    live[i] = l = T.graph.NewNode(T.common.Merge(1), l);
+    dead[i] = d = T.graph.NewNode(T.common.Merge(1), d);
+  }
+  // end -> live[last] -> live[last-1] -> ... -> start
+  //        dead[last] -> dead[last-1] -> ... -> start
+  T.graph.SetEnd(l);
+  T.Trim();
+  CHECK(!IsUsedBy(T.start, dead[0]));
+  for (int i = 0; i < kDepth; i++) {
+    CHECK_EQ(i == 0 ? NULL : dead[i - 1], dead[i]->InputAt(0));
+    CHECK_EQ(i == 0 ? T.start : live[i - 1], live[i]->InputAt(0));
+  }
+}
+
+
+TEST(Trim_cycle1) {
+  ControlReducerTester T;
+  Node* loop = T.graph.NewNode(T.common.Loop(1), T.start, T.start);
+  loop->ReplaceInput(1, loop);
+  Node* end = T.graph.NewNode(T.common.End(), loop);
+  T.graph.SetEnd(end);
+
+  CHECK(IsUsedBy(T.start, loop));
+  CHECK(IsUsedBy(loop, end));
+  CHECK(IsUsedBy(loop, loop));
+
+  T.Trim();
+
+  // nothing should have happened to the loop itself.
+  CHECK(IsUsedBy(T.start, loop));
+  CHECK(IsUsedBy(loop, end));
+  CHECK(IsUsedBy(loop, loop));
+  CheckInputs(loop, T.start, loop);
+  CheckInputs(end, loop);
+}
+
+
+TEST(Trim_cycle2) {
+  ControlReducerTester T;
+  Node* loop = T.graph.NewNode(T.common.Loop(2), T.start, T.start);
+  loop->ReplaceInput(1, loop);
+  Node* end = T.graph.NewNode(T.common.End(), loop);
+  Node* phi =
+      T.graph.NewNode(T.common.Phi(kMachAnyTagged, 2), T.one, T.half, loop);
+  T.graph.SetEnd(end);
+
+  CHECK(IsUsedBy(T.start, loop));
+  CHECK(IsUsedBy(loop, end));
+  CHECK(IsUsedBy(loop, loop));
+  CHECK(IsUsedBy(loop, phi));
+  CHECK(IsUsedBy(T.one, phi));
+  CHECK(IsUsedBy(T.half, phi));
+
+  T.Trim();
+
+  // nothing should have happened to the loop itself.
+  CHECK(IsUsedBy(T.start, loop));
+  CHECK(IsUsedBy(loop, end));
+  CHECK(IsUsedBy(loop, loop));
+  CheckInputs(loop, T.start, loop);
+  CheckInputs(end, loop);
+
+  // phi should have been trimmed away.
+  CHECK(!IsUsedBy(loop, phi));
+  CHECK(!IsUsedBy(T.one, phi));
+  CHECK(!IsUsedBy(T.half, phi));
+  CHECK_EQ(NULL, phi->InputAt(0));
+  CHECK_EQ(NULL, phi->InputAt(1));
+  CHECK_EQ(NULL, phi->InputAt(2));
+}
+
+
+void CheckTrimConstant(ControlReducerTester* T, Node* k) {
+  Node* phi = T->graph.NewNode(T->common.Phi(kMachInt32, 1), k, T->start);
+  CHECK(IsUsedBy(k, phi));
+  T->Trim();
+  CHECK(!IsUsedBy(k, phi));
+  CHECK_EQ(NULL, phi->InputAt(0));
+  CHECK_EQ(NULL, phi->InputAt(1));
+}
+
+
+TEST(Trim_constants) {
+  ControlReducerTester T;
+  int32_t int32_constants[] = {
+      0, -1,  -2,  2,  2,  3,  3,  4,  4,  5,  5,  4,  5,  6, 6, 7, 8, 7, 8, 9,
+      0, -11, -12, 12, 12, 13, 13, 14, 14, 15, 15, 14, 15, 6, 6, 7, 8, 7, 8, 9};
+
+  for (size_t i = 0; i < arraysize(int32_constants); i++) {
+    CheckTrimConstant(&T, T.jsgraph.Int32Constant(int32_constants[i]));
+    CheckTrimConstant(&T, T.jsgraph.Float64Constant(int32_constants[i]));
+    CheckTrimConstant(&T, T.jsgraph.Constant(int32_constants[i]));
+  }
+
+  Node* other_constants[] = {
+      T.jsgraph.UndefinedConstant(), T.jsgraph.TheHoleConstant(),
+      T.jsgraph.TrueConstant(),      T.jsgraph.FalseConstant(),
+      T.jsgraph.NullConstant(),      T.jsgraph.ZeroConstant(),
+      T.jsgraph.OneConstant(),       T.jsgraph.NaNConstant(),
+      T.jsgraph.Constant(21),        T.jsgraph.Constant(22.2)};
+
+  for (size_t i = 0; i < arraysize(other_constants); i++) {
+    CheckTrimConstant(&T, other_constants[i]);
+  }
+}
+
+
+TEST(CReducePhi1) {
+  ControlReducerTester R;
+
+  R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0]));
+  R.ReducePhi(R.leaf[1], R.Phi(R.leaf[1]));
+  R.ReducePhi(R.leaf[2], R.Phi(R.leaf[2]));
+  R.ReducePhi(R.leaf[3], R.Phi(R.leaf[3]));
+}
+
+
+TEST(CReducePhi1_dead) {
+  ControlReducerTester R;
+
+  R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0], R.dead));
+  R.ReducePhi(R.leaf[1], R.Phi(R.leaf[1], R.dead));
+  R.ReducePhi(R.leaf[2], R.Phi(R.leaf[2], R.dead));
+  R.ReducePhi(R.leaf[3], R.Phi(R.leaf[3], R.dead));
+
+  R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.leaf[0]));
+  R.ReducePhi(R.leaf[1], R.Phi(R.dead, R.leaf[1]));
+  R.ReducePhi(R.leaf[2], R.Phi(R.dead, R.leaf[2]));
+  R.ReducePhi(R.leaf[3], R.Phi(R.dead, R.leaf[3]));
+}
+
+
+TEST(CReducePhi1_dead2) {
+  ControlReducerTester R;
+
+  R.ReducePhi(R.leaf[0], R.Phi(R.leaf[0], R.dead, R.dead));
+  R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.leaf[0], R.dead));
+  R.ReducePhi(R.leaf[0], R.Phi(R.dead, R.dead, R.leaf[0]));
+}
+
+
+TEST(CReducePhi2a) {
+  ControlReducerTester R;
+
+  for (size_t i = 0; i < kNumLeafs; i++) {
+    Node* a = R.leaf[i];
+    R.ReducePhi(a, R.Phi(a, a));
+  }
+}
+
+
+TEST(CReducePhi2b) {
+  ControlReducerTester R;
+
+  for (size_t i = 0; i < kNumLeafs; i++) {
+    Node* a = R.leaf[i];
+    R.ReducePhi(a, R.Phi(R.self, a));
+    R.ReducePhi(a, R.Phi(a, R.self));
+  }
+}
+
+
+TEST(CReducePhi2c) {
+  ControlReducerTester R;
+
+  for (size_t i = 1; i < kNumLeafs; i++) {
+    Node* a = R.leaf[i], *b = R.leaf[0];
+    Node* phi1 = R.Phi(b, a);
+    R.ReducePhi(phi1, phi1);
+
+    Node* phi2 = R.Phi(a, b);
+    R.ReducePhi(phi2, phi2);
+  }
+}
+
+
+TEST(CReducePhi2_dead) {
+  ControlReducerTester R;
+
+  for (size_t i = 0; i < kNumLeafs; i++) {
+    Node* a = R.leaf[i];
+    R.ReducePhi(a, R.Phi(a, a, R.dead));
+    R.ReducePhi(a, R.Phi(a, R.dead, a));
+    R.ReducePhi(a, R.Phi(R.dead, a, a));
+  }
+
+  for (size_t i = 0; i < kNumLeafs; i++) {
+    Node* a = R.leaf[i];
+    R.ReducePhi(a, R.Phi(R.self, a));
+    R.ReducePhi(a, R.Phi(a, R.self));
+    R.ReducePhi(a, R.Phi(R.self, a, R.dead));
+    R.ReducePhi(a, R.Phi(a, R.self, R.dead));
+  }
+
+  for (size_t i = 1; i < kNumLeafs; i++) {
+    Node* a = R.leaf[i], *b = R.leaf[0];
+    Node* phi1 = R.Phi(b, a, R.dead);
+    R.ReducePhi(phi1, phi1);
+
+    Node* phi2 = R.Phi(a, b, R.dead);
+    R.ReducePhi(phi2, phi2);
+  }
+}
+
+
+TEST(CReducePhi3) {
+  ControlReducerTester R;
+
+  for (size_t i = 0; i < kNumLeafs; i++) {
+    Node* a = R.leaf[i];
+    R.ReducePhi(a, R.Phi(a, a, a));
+  }
+
+  for (size_t i = 0; i < kNumLeafs; i++) {
+    Node* a = R.leaf[i];
+    R.ReducePhi(a, R.Phi(R.self, a, a));
+    R.ReducePhi(a, R.Phi(a, R.self, a));
+    R.ReducePhi(a, R.Phi(a, a, R.self));
+  }
+
+  for (size_t i = 1; i < kNumLeafs; i++) {
+    Node* a = R.leaf[i], *b = R.leaf[0];
+    Node* phi1 = R.Phi(b, a, a);
+    R.ReducePhi(phi1, phi1);
+
+    Node* phi2 = R.Phi(a, b, a);
+    R.ReducePhi(phi2, phi2);
+
+    Node* phi3 = R.Phi(a, a, b);
+    R.ReducePhi(phi3, phi3);
+  }
+}
+
+
+TEST(CReducePhi4) {
+  ControlReducerTester R;
+
+  for (size_t i = 0; i < kNumLeafs; i++) {
+    Node* a = R.leaf[i];
+    R.ReducePhi(a, R.Phi(a, a, a, a));
+  }
+
+  for (size_t i = 0; i < kNumLeafs; i++) {
+    Node* a = R.leaf[i];
+    R.ReducePhi(a, R.Phi(R.self, a, a, a));
+    R.ReducePhi(a, R.Phi(a, R.self, a, a));
+    R.ReducePhi(a, R.Phi(a, a, R.self, a));
+    R.ReducePhi(a, R.Phi(a, a, a, R.self));
+
+    R.ReducePhi(a, R.Phi(R.self, R.self, a, a));
+    R.ReducePhi(a, R.Phi(a, R.self, R.self, a));
+    R.ReducePhi(a, R.Phi(a, a, R.self, R.self));
+    R.ReducePhi(a, R.Phi(R.self, a, a, R.self));
+  }
+
+  for (size_t i = 1; i < kNumLeafs; i++) {
+    Node* a = R.leaf[i], *b = R.leaf[0];
+    Node* phi1 = R.Phi(b, a, a, a);
+    R.ReducePhi(phi1, phi1);
+
+    Node* phi2 = R.Phi(a, b, a, a);
+    R.ReducePhi(phi2, phi2);
+
+    Node* phi3 = R.Phi(a, a, b, a);
+    R.ReducePhi(phi3, phi3);
+
+    Node* phi4 = R.Phi(a, a, a, b);
+    R.ReducePhi(phi4, phi4);
+  }
+}
+
+
+TEST(CReducePhi_iterative1) {
+  ControlReducerTester R;
+
+  R.ReducePhiIterative(R.leaf[0], R.Phi(R.leaf[0], R.Phi(R.leaf[0])));
+  R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0]), R.leaf[0]));
+}
+
+
+TEST(CReducePhi_iterative2) {
+  ControlReducerTester R;
+
+  R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0]), R.Phi(R.leaf[0])));
+}
+
+
+TEST(CReducePhi_iterative3) {
+  ControlReducerTester R;
+
+  R.ReducePhiIterative(R.leaf[0],
+                       R.Phi(R.leaf[0], R.Phi(R.leaf[0], R.leaf[0])));
+  R.ReducePhiIterative(R.leaf[0],
+                       R.Phi(R.Phi(R.leaf[0], R.leaf[0]), R.leaf[0]));
+}
+
+
+TEST(CReducePhi_iterative4) {
+  ControlReducerTester R;
+
+  R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.leaf[0]),
+                                        R.Phi(R.leaf[0], R.leaf[0])));
+
+  Node* p1 = R.Phi(R.leaf[0], R.leaf[0]);
+  R.ReducePhiIterative(R.leaf[0], R.Phi(p1, p1));
+
+  Node* p2 = R.Phi(R.leaf[0], R.leaf[0], R.leaf[0]);
+  R.ReducePhiIterative(R.leaf[0], R.Phi(p2, p2, p2));
+
+  Node* p3 = R.Phi(R.leaf[0], R.leaf[0], R.leaf[0]);
+  R.ReducePhiIterative(R.leaf[0], R.Phi(p3, p3, R.leaf[0]));
+}
+
+
+TEST(CReducePhi_iterative_self1) {
+  ControlReducerTester R;
+
+  R.ReducePhiIterative(R.leaf[0], R.Phi(R.leaf[0], R.Phi(R.leaf[0], R.self)));
+  R.ReducePhiIterative(R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.self), R.leaf[0]));
+}
+
+
+TEST(CReducePhi_iterative_self2) {
+  ControlReducerTester R;
+
+  R.ReducePhiIterative(
+      R.leaf[0], R.Phi(R.Phi(R.leaf[0], R.self), R.Phi(R.leaf[0], R.self)));
+  R.ReducePhiIterative(
+      R.leaf[0], R.Phi(R.Phi(R.self, R.leaf[0]), R.Phi(R.self, R.leaf[0])));
+
+  Node* p1 = R.Phi(R.leaf[0], R.self);
+  R.ReducePhiIterative(R.leaf[0], R.Phi(p1, p1));
+
+  Node* p2 = R.Phi(R.self, R.leaf[0]);
+  R.ReducePhiIterative(R.leaf[0], R.Phi(p2, p2));
+}
+
+
+TEST(EReducePhi1) {
+  ControlReducerTester R;
+
+  R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0]));
+  R.ReducePhi(R.leaf[1], R.EffectPhi(R.leaf[1]));
+  R.ReducePhi(R.leaf[2], R.EffectPhi(R.leaf[2]));
+  R.ReducePhi(R.leaf[3], R.EffectPhi(R.leaf[3]));
+}
+
+
+TEST(EReducePhi1_dead) {
+  ControlReducerTester R;
+
+  R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0], R.dead));
+  R.ReducePhi(R.leaf[1], R.EffectPhi(R.leaf[1], R.dead));
+  R.ReducePhi(R.leaf[2], R.EffectPhi(R.leaf[2], R.dead));
+  R.ReducePhi(R.leaf[3], R.EffectPhi(R.leaf[3], R.dead));
+
+  R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.leaf[0]));
+  R.ReducePhi(R.leaf[1], R.EffectPhi(R.dead, R.leaf[1]));
+  R.ReducePhi(R.leaf[2], R.EffectPhi(R.dead, R.leaf[2]));
+  R.ReducePhi(R.leaf[3], R.EffectPhi(R.dead, R.leaf[3]));
+}
+
+
+TEST(EReducePhi1_dead2) {
+  ControlReducerTester R;
+
+  R.ReducePhi(R.leaf[0], R.EffectPhi(R.leaf[0], R.dead, R.dead));
+  R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.leaf[0], R.dead));
+  R.ReducePhi(R.leaf[0], R.EffectPhi(R.dead, R.dead, R.leaf[0]));
+}
+
+
+TEST(CMergeReduce_simple1) {
+  ControlReducerTester R;
+
+  Node* merge = R.graph.NewNode(R.common.Merge(1), R.start);
+  R.ReduceMerge(R.start, merge);
+}
+
+
+TEST(CMergeReduce_simple2) {
+  ControlReducerTester R;
+
+  Node* merge1 = R.graph.NewNode(R.common.Merge(1), R.start);
+  Node* merge2 = R.graph.NewNode(R.common.Merge(1), merge1);
+  R.ReduceMerge(merge1, merge2);
+  R.ReduceMergeIterative(R.start, merge2);
+}
+
+
+TEST(CMergeReduce_none1) {
+  ControlReducerTester R;
+
+  Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, R.start);
+  R.ReduceMerge(merge, merge);
+}
+
+
+TEST(CMergeReduce_none2) {
+  ControlReducerTester R;
+
+  Node* t = R.graph.NewNode(R.common.IfTrue(), R.start);
+  Node* f = R.graph.NewNode(R.common.IfFalse(), R.start);
+  Node* merge = R.graph.NewNode(R.common.Merge(2), t, f);
+  R.ReduceMerge(merge, merge);
+}
+
+
+TEST(CMergeReduce_self3) {
+  ControlReducerTester R;
+
+  Node* merge =
+      R.SetSelfReferences(R.graph.NewNode(R.common.Merge(2), R.start, R.self));
+  R.ReduceMerge(merge, merge);
+}
+
+
+TEST(CMergeReduce_dead1) {
+  ControlReducerTester R;
+
+  Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, R.dead);
+  R.ReduceMerge(R.start, merge);
+}
+
+
+TEST(CMergeReduce_dead2) {
+  ControlReducerTester R;
+
+  Node* merge1 = R.graph.NewNode(R.common.Merge(1), R.start);
+  Node* merge2 = R.graph.NewNode(R.common.Merge(2), merge1, R.dead);
+  R.ReduceMerge(merge1, merge2);
+  R.ReduceMergeIterative(R.start, merge2);
+}
+
+
+TEST(CMergeReduce_dead_rm1a) {
+  ControlReducerTester R;
+
+  for (int i = 0; i < 3; i++) {
+    Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
+    merge->ReplaceInput(i, R.dead);
+    R.ReduceMerge(merge, merge);
+    CheckMerge(merge, R.start, R.start);
+  }
+}
+
+
+TEST(CMergeReduce_dead_rm1b) {
+  ControlReducerTester R;
+
+  Node* t = R.graph.NewNode(R.common.IfTrue(), R.start);
+  Node* f = R.graph.NewNode(R.common.IfFalse(), R.start);
+  for (int i = 0; i < 2; i++) {
+    Node* merge = R.graph.NewNode(R.common.Merge(3), R.dead, R.dead, R.dead);
+    for (int j = i + 1; j < 3; j++) {
+      merge->ReplaceInput(i, t);
+      merge->ReplaceInput(j, f);
+      R.ReduceMerge(merge, merge);
+      CheckMerge(merge, t, f);
+    }
+  }
+}
+
+
+TEST(CMergeReduce_dead_rm2) {
+  ControlReducerTester R;
+
+  for (int i = 0; i < 3; i++) {
+    Node* merge = R.graph.NewNode(R.common.Merge(3), R.dead, R.dead, R.dead);
+    merge->ReplaceInput(i, R.start);
+    R.ReduceMerge(R.start, merge);
+  }
+}
+
+
+TEST(CLoopReduce_dead_rm1) {
+  ControlReducerTester R;
+
+  for (int i = 0; i < 3; i++) {
+    Node* loop = R.graph.NewNode(R.common.Loop(3), R.dead, R.start, R.start);
+    R.ReduceMerge(loop, loop);
+    CheckLoop(loop, R.start, R.start);
+  }
+}
+
+
+TEST(CMergeReduce_edit_phi1) {
+  ControlReducerTester R;
+
+  for (int i = 0; i < 3; i++) {
+    Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
+    merge->ReplaceInput(i, R.dead);
+    Node* phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 3), R.leaf[0],
+                                R.leaf[1], R.leaf[2], merge);
+    R.ReduceMerge(merge, merge);
+    CHECK_EQ(IrOpcode::kPhi, phi->opcode());
+    CHECK_EQ(2, phi->op()->ValueInputCount());
+    CHECK_EQ(3, phi->InputCount());
+    CHECK_EQ(R.leaf[i < 1 ? 1 : 0], phi->InputAt(0));
+    CHECK_EQ(R.leaf[i < 2 ? 2 : 1], phi->InputAt(1));
+    CHECK_EQ(merge, phi->InputAt(2));
+  }
+}
+
+
+TEST(CMergeReduce_edit_effect_phi1) {
+  ControlReducerTester R;
+
+  for (int i = 0; i < 3; i++) {
+    Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
+    merge->ReplaceInput(i, R.dead);
+    Node* phi = R.graph.NewNode(R.common.EffectPhi(3), R.leaf[0], R.leaf[1],
+                                R.leaf[2], merge);
+    R.ReduceMerge(merge, merge);
+    CHECK_EQ(IrOpcode::kEffectPhi, phi->opcode());
+    CHECK_EQ(0, phi->op()->ValueInputCount());
+    CHECK_EQ(2, phi->op()->EffectInputCount());
+    CHECK_EQ(3, phi->InputCount());
+    CHECK_EQ(R.leaf[i < 1 ? 1 : 0], phi->InputAt(0));
+    CHECK_EQ(R.leaf[i < 2 ? 2 : 1], phi->InputAt(1));
+    CHECK_EQ(merge, phi->InputAt(2));
+  }
+}
+
+
+static const int kSelectorSize = 4;
+
+// Helper to select K of N nodes according to a mask, useful for the test below.
+struct Selector {
+  int mask;
+  int count;
+  explicit Selector(int m) {
+    mask = m;
+    count = v8::base::bits::CountPopulation32(m);
+  }
+  bool is_selected(int i) { return (mask & (1 << i)) != 0; }
+  void CheckNode(Node* node, IrOpcode::Value opcode, Node** inputs,
+                 Node* control) {
+    CHECK_EQ(opcode, node->opcode());
+    CHECK_EQ(count + (control != NULL ? 1 : 0), node->InputCount());
+    int index = 0;
+    for (int i = 0; i < kSelectorSize; i++) {
+      if (mask & (1 << i)) {
+        CHECK_EQ(inputs[i], node->InputAt(index++));
+      }
+    }
+    CHECK_EQ(count, index);
+    if (control != NULL) CHECK_EQ(control, node->InputAt(index++));
+  }
+  int single_index() {
+    CHECK_EQ(1, count);
+    return WhichPowerOf2(mask);
+  }
+};
+
+
+TEST(CMergeReduce_exhaustive_4) {
+  ControlReducerTester R;
+  Node* controls[] = {
+      R.graph.NewNode(R.common.Start(1)), R.graph.NewNode(R.common.Start(2)),
+      R.graph.NewNode(R.common.Start(3)), R.graph.NewNode(R.common.Start(4))};
+  Node* values[] = {R.jsgraph.Int32Constant(11), R.jsgraph.Int32Constant(22),
+                    R.jsgraph.Int32Constant(33), R.jsgraph.Int32Constant(44)};
+  Node* effects[] = {
+      R.jsgraph.Float64Constant(123.4), R.jsgraph.Float64Constant(223.4),
+      R.jsgraph.Float64Constant(323.4), R.jsgraph.Float64Constant(423.4)};
+
+  for (int mask = 0; mask < (1 << (kSelectorSize - 1)); mask++) {
+    // Reduce a single merge with a given mask.
+    Node* merge = R.graph.NewNode(R.common.Merge(4), controls[0], controls[1],
+                                  controls[2], controls[3]);
+    Node* phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 4), values[0],
+                                values[1], values[2], values[3], merge);
+    Node* ephi = R.graph.NewNode(R.common.EffectPhi(4), effects[0], effects[1],
+                                 effects[2], effects[3], merge);
+
+    Node* phi_use =
+        R.graph.NewNode(R.common.Phi(kMachAnyTagged, 1), phi, R.start);
+    Node* ephi_use = R.graph.NewNode(R.common.EffectPhi(1), ephi, R.start);
+
+    Selector selector(mask);
+
+    for (int i = 0; i < kSelectorSize; i++) {  // set up dead merge inputs.
+      if (!selector.is_selected(i)) merge->ReplaceInput(i, R.dead);
+    }
+
+    Node* result =
+        ControlReducer::ReduceMergeForTesting(&R.jsgraph, &R.common, merge);
+
+    int count = selector.count;
+    if (count == 0) {
+      // result should be dead.
+      CHECK_EQ(IrOpcode::kDead, result->opcode());
+    } else if (count == 1) {
+      // merge should be replaced with one of the controls.
+      CHECK_EQ(controls[selector.single_index()], result);
+      // Phis should have been directly replaced.
+      CHECK_EQ(values[selector.single_index()], phi_use->InputAt(0));
+      CHECK_EQ(effects[selector.single_index()], ephi_use->InputAt(0));
+    } else {
+      // Otherwise, nodes should be edited in place.
+      CHECK_EQ(merge, result);
+      selector.CheckNode(merge, IrOpcode::kMerge, controls, NULL);
+      selector.CheckNode(phi, IrOpcode::kPhi, values, merge);
+      selector.CheckNode(ephi, IrOpcode::kEffectPhi, effects, merge);
+      CHECK_EQ(phi, phi_use->InputAt(0));
+      CHECK_EQ(ephi, ephi_use->InputAt(0));
+      CHECK_EQ(count, phi->op()->ValueInputCount());
+      CHECK_EQ(count + 1, phi->InputCount());
+      CHECK_EQ(count, ephi->op()->EffectInputCount());
+      CHECK_EQ(count + 1, ephi->InputCount());
+    }
+  }
+}
+
+
+TEST(CMergeReduce_edit_many_phis1) {
+  ControlReducerTester R;
+
+  const int kPhiCount = 10;
+  Node* phis[kPhiCount];
+
+  for (int i = 0; i < 3; i++) {
+    Node* merge = R.graph.NewNode(R.common.Merge(3), R.start, R.start, R.start);
+    merge->ReplaceInput(i, R.dead);
+    for (int j = 0; j < kPhiCount; j++) {
+      phis[j] = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 3), R.leaf[0],
+                                R.leaf[1], R.leaf[2], merge);
+    }
+    R.ReduceMerge(merge, merge);
+    for (int j = 0; j < kPhiCount; j++) {
+      Node* phi = phis[j];
+      CHECK_EQ(IrOpcode::kPhi, phi->opcode());
+      CHECK_EQ(2, phi->op()->ValueInputCount());
+      CHECK_EQ(3, phi->InputCount());
+      CHECK_EQ(R.leaf[i < 1 ? 1 : 0], phi->InputAt(0));
+      CHECK_EQ(R.leaf[i < 2 ? 2 : 1], phi->InputAt(1));
+      CHECK_EQ(merge, phi->InputAt(2));
+    }
+  }
+}
+
+
+TEST(CMergeReduce_simple_chain1) {
+  ControlReducerTester R;
+  for (int i = 0; i < 5; i++) {
+    Node* merge = R.graph.NewNode(R.common.Merge(1), R.start);
+    for (int j = 0; j < i; j++) {
+      merge = R.graph.NewNode(R.common.Merge(1), merge);
+    }
+    R.ReduceMergeIterative(R.start, merge);
+  }
+}
+
+
+TEST(CMergeReduce_dead_chain1) {
+  ControlReducerTester R;
+  for (int i = 0; i < 5; i++) {
+    Node* merge = R.graph.NewNode(R.common.Merge(1), R.dead);
+    for (int j = 0; j < i; j++) {
+      merge = R.graph.NewNode(R.common.Merge(1), merge);
+    }
+    Node* end = R.graph.NewNode(R.common.End(), merge);
+    R.graph.SetEnd(end);
+    R.ReduceGraph();
+    CHECK(merge->IsDead());
+    CHECK_EQ(NULL, end->InputAt(0));  // end dies.
+  }
+}
+
+
+TEST(CMergeReduce_dead_chain2) {
+  ControlReducerTester R;
+  for (int i = 0; i < 5; i++) {
+    Node* merge = R.graph.NewNode(R.common.Merge(1), R.start);
+    for (int j = 0; j < i; j++) {
+      merge = R.graph.NewNode(R.common.Merge(2), merge, R.dead);
+    }
+    R.ReduceMergeIterative(R.start, merge);
+  }
+}
+
+
+struct Branch {
+  Node* branch;
+  Node* if_true;
+  Node* if_false;
+
+  Branch(ControlReducerTester& R, Node* cond, Node* control = NULL) {
+    if (control == NULL) control = R.start;
+    branch = R.graph.NewNode(R.common.Branch(), cond, control);
+    if_true = R.graph.NewNode(R.common.IfTrue(), branch);
+    if_false = R.graph.NewNode(R.common.IfFalse(), branch);
+  }
+};
+
+
+// TODO(titzer): use the diamonds from src/compiler/diamond.h here.
+struct Diamond {
+  Node* branch;
+  Node* if_true;
+  Node* if_false;
+  Node* merge;
+  Node* phi;
+
+  Diamond(ControlReducerTester& R, Node* cond) {
+    branch = R.graph.NewNode(R.common.Branch(), cond, R.start);
+    if_true = R.graph.NewNode(R.common.IfTrue(), branch);
+    if_false = R.graph.NewNode(R.common.IfFalse(), branch);
+    merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false);
+    phi = NULL;
+  }
+
+  Diamond(ControlReducerTester& R, Node* cond, Node* tv, Node* fv) {
+    branch = R.graph.NewNode(R.common.Branch(), cond, R.start);
+    if_true = R.graph.NewNode(R.common.IfTrue(), branch);
+    if_false = R.graph.NewNode(R.common.IfFalse(), branch);
+    merge = R.graph.NewNode(R.common.Merge(2), if_true, if_false);
+    phi = R.graph.NewNode(R.common.Phi(kMachAnyTagged, 2), tv, fv, merge);
+  }
+
+  void chain(Diamond& that) { branch->ReplaceInput(1, that.merge); }
+
+  // Nest {this} into either the if_true or if_false branch of {that}.
+  void nest(Diamond& that, bool if_true) {
+    if (if_true) {
+      branch->ReplaceInput(1, that.if_true);
+      that.merge->ReplaceInput(0, merge);
+    } else {
+      branch->ReplaceInput(1, that.if_false);
+      that.merge->ReplaceInput(1, merge);
+    }
+  }
+};
+
+
+struct While {
+  Node* branch;
+  Node* if_true;
+  Node* exit;
+  Node* loop;
+
+  While(ControlReducerTester& R, Node* cond) {
+    loop = R.graph.NewNode(R.common.Loop(2), R.start, R.start);
+    branch = R.graph.NewNode(R.common.Branch(), cond, loop);
+    if_true = R.graph.NewNode(R.common.IfTrue(), branch);
+    exit = R.graph.NewNode(R.common.IfFalse(), branch);
+    loop->ReplaceInput(1, if_true);
+  }
+
+  void chain(Node* control) { loop->ReplaceInput(0, control); }
+};
+
+
+TEST(CBranchReduce_none1) {
+  ControlReducerTester R;
+  Diamond d(R, R.p0);
+  R.ReduceBranch(d.branch, d.branch);
+}
+
+
+TEST(CBranchReduce_none2) {
+  ControlReducerTester R;
+  Diamond d1(R, R.p0);
+  Diamond d2(R, R.p0);
+  d2.chain(d1);
+  R.ReduceBranch(d2.branch, d2.branch);
+}
+
+
+TEST(CBranchReduce_true) {
+  ControlReducerTester R;
+  Node* true_values[] = {
+      R.one,                               R.jsgraph.Int32Constant(2),
+      R.jsgraph.Int32Constant(0x7fffffff), R.jsgraph.Constant(1.0),
+      R.jsgraph.Constant(22.1),            R.jsgraph.TrueConstant()};
+
+  for (size_t i = 0; i < arraysize(true_values); i++) {
+    Diamond d(R, true_values[i]);
+    Node* true_use = R.graph.NewNode(R.common.Merge(1), d.if_true);
+    Node* false_use = R.graph.NewNode(R.common.Merge(1), d.if_false);
+    R.ReduceBranch(R.start, d.branch);
+    CHECK_EQ(R.start, true_use->InputAt(0));
+    CHECK_EQ(IrOpcode::kDead, false_use->InputAt(0)->opcode());
+    CHECK(d.if_true->IsDead());   // replaced
+    CHECK(d.if_false->IsDead());  // replaced
+  }
+}
+
+
+TEST(CBranchReduce_false) {
+  ControlReducerTester R;
+  Node* false_values[] = {R.zero, R.jsgraph.Constant(0.0),
+                          R.jsgraph.Constant(-0.0), R.jsgraph.FalseConstant()};
+
+  for (size_t i = 0; i < arraysize(false_values); i++) {
+    Diamond d(R, false_values[i]);
+    Node* true_use = R.graph.NewNode(R.common.Merge(1), d.if_true);
+    Node* false_use = R.graph.NewNode(R.common.Merge(1), d.if_false);
+    R.ReduceBranch(R.start, d.branch);
+    CHECK_EQ(R.start, false_use->InputAt(0));
+    CHECK_EQ(IrOpcode::kDead, true_use->InputAt(0)->opcode());
+    CHECK(d.if_true->IsDead());   // replaced
+    CHECK(d.if_false->IsDead());  // replaced
+  }
+}
+
+
+TEST(CDiamondReduce_true) {
+  ControlReducerTester R;
+  Diamond d1(R, R.one);
+  R.ReduceMergeIterative(R.start, d1.merge);
+}
+
+
+TEST(CDiamondReduce_false) {
+  ControlReducerTester R;
+  Diamond d2(R, R.zero);
+  R.ReduceMergeIterative(R.start, d2.merge);
+}
+
+
+TEST(CChainedDiamondsReduce_true_false) {
+  ControlReducerTester R;
+  Diamond d1(R, R.one);
+  Diamond d2(R, R.zero);
+  d2.chain(d1);
+
+  R.ReduceMergeIterative(R.start, d2.merge);
+}
+
+
+TEST(CChainedDiamondsReduce_x_false) {
+  ControlReducerTester R;
+  Diamond d1(R, R.p0);
+  Diamond d2(R, R.zero);
+  d2.chain(d1);
+
+  R.ReduceMergeIterative(d1.merge, d2.merge);
+}
+
+
+TEST(CChainedDiamondsReduce_false_x) {
+  ControlReducerTester R;
+  Diamond d1(R, R.zero);
+  Diamond d2(R, R.p0);
+  d2.chain(d1);
+
+  R.ReduceMergeIterative(d2.merge, d2.merge);
+  CheckInputs(d2.branch, R.p0, R.start);
+}
+
+
+TEST(CChainedDiamondsReduce_phi1) {
+  ControlReducerTester R;
+  Diamond d1(R, R.zero, R.one, R.zero);  // foldable branch, phi.
+  Diamond d2(R, d1.phi);
+  d2.chain(d1);
+
+  R.ReduceMergeIterative(R.start, d2.merge);
+}
+
+
+TEST(CChainedDiamondsReduce_phi2) {
+  ControlReducerTester R;
+  Diamond d1(R, R.p0, R.one, R.one);  // redundant phi.
+  Diamond d2(R, d1.phi);
+  d2.chain(d1);
+
+  R.ReduceMergeIterative(d1.merge, d2.merge);
+}
+
+
+TEST(CNestedDiamondsReduce_true_true_false) {
+  ControlReducerTester R;
+  Diamond d1(R, R.one);
+  Diamond d2(R, R.zero);
+  d2.nest(d1, true);
+
+  R.ReduceMergeIterative(R.start, d1.merge);
+}
+
+
+TEST(CNestedDiamondsReduce_false_true_false) {
+  ControlReducerTester R;
+  Diamond d1(R, R.one);
+  Diamond d2(R, R.zero);
+  d2.nest(d1, false);
+
+  R.ReduceMergeIterative(R.start, d1.merge);
+}
+
+
+TEST(CNestedDiamonds_xyz) {
+  ControlReducerTester R;
+
+  for (int a = 0; a < 2; a++) {
+    for (int b = 0; b < 2; b++) {
+      for (int c = 0; c < 2; c++) {
+        Diamond d1(R, R.jsgraph.Int32Constant(a));
+        Diamond d2(R, R.jsgraph.Int32Constant(b));
+        d2.nest(d1, c);
+
+        R.ReduceMergeIterative(R.start, d1.merge);
+      }
+    }
+  }
+}
+
+
+TEST(CDeadLoop1) {
+  ControlReducerTester R;
+
+  Node* loop = R.graph.NewNode(R.common.Loop(1), R.start);
+  Branch b(R, R.p0, loop);
+  loop->ReplaceInput(0, b.if_true);  // loop is not connected to start.
+  Node* merge = R.graph.NewNode(R.common.Merge(2), R.start, b.if_false);
+  R.ReduceMergeIterative(R.start, merge);
+  CHECK(b.if_true->IsDead());
+  CHECK(b.if_false->IsDead());
+}
+
+
+TEST(CDeadLoop2) {
+  ControlReducerTester R;
+
+  While w(R, R.p0);
+  Diamond d(R, R.zero);
+  // if (0) { while (p0) ; } else { }
+  w.branch->ReplaceInput(1, d.if_true);
+  d.merge->ReplaceInput(0, w.exit);
+
+  R.ReduceMergeIterative(R.start, d.merge);
+  CHECK(d.if_true->IsDead());
+  CHECK(d.if_false->IsDead());
+}
+
+
+TEST(CNonTermLoop1) {
+  ControlReducerTester R;
+  Node* loop =
+      R.SetSelfReferences(R.graph.NewNode(R.common.Loop(2), R.start, R.self));
+  R.ReduceGraph();
+  Node* end = R.graph.end();
+  CheckLoop(loop, R.start, loop);
+  Node* merge = end->InputAt(0);
+  CheckMerge(merge, R.start, loop);
+}
+
+
+TEST(CNonTermLoop2) {
+  ControlReducerTester R;
+  Diamond d(R, R.p0);
+  Node* loop = R.SetSelfReferences(
+      R.graph.NewNode(R.common.Loop(2), d.if_false, R.self));
+  d.merge->ReplaceInput(1, R.dead);
+  Node* end = R.graph.end();
+  end->ReplaceInput(0, d.merge);
+  R.ReduceGraph();
+  CHECK_EQ(end, R.graph.end());
+  CheckLoop(loop, d.if_false, loop);
+  Node* merge = end->InputAt(0);
+  CheckMerge(merge, d.if_true, loop);
+}
+
+
+TEST(NonTermLoop3) {
+  ControlReducerTester R;
+  Node* loop = R.graph.NewNode(R.common.Loop(2), R.start, R.start);
+  Branch b(R, R.one, loop);
+  loop->ReplaceInput(1, b.if_true);
+  Node* end = R.graph.end();
+  end->ReplaceInput(0, b.if_false);
+
+  R.ReduceGraph();
+
+  CHECK_EQ(end, R.graph.end());
+  CheckInputs(end, loop);
+  CheckInputs(loop, R.start, loop);
+}
+
+
+TEST(CNonTermLoop_terminate1) {
+  ControlReducerTester R;
+  Node* loop = R.graph.NewNode(R.common.Loop(2), R.start, R.start);
+  Node* effect = R.SetSelfReferences(
+      R.graph.NewNode(R.common.EffectPhi(2), R.start, R.self, loop));
+  Branch b(R, R.one, loop);
+  loop->ReplaceInput(1, b.if_true);
+  Node* end = R.graph.end();
+  end->ReplaceInput(0, b.if_false);
+
+  R.ReduceGraph();
+
+  CHECK_EQ(end, R.graph.end());
+  CheckLoop(loop, R.start, loop);
+  Node* terminate = end->InputAt(0);
+  CHECK_EQ(IrOpcode::kTerminate, terminate->opcode());
+  CHECK_EQ(2, terminate->InputCount());
+  CHECK_EQ(1, terminate->op()->EffectInputCount());
+  CHECK_EQ(1, terminate->op()->ControlInputCount());
+  CheckInputs(terminate, effect, loop);
+}
+
+
+TEST(CNonTermLoop_terminate2) {
+  ControlReducerTester R;
+  Node* loop = R.graph.NewNode(R.common.Loop(2), R.start, R.start);
+  Node* effect1 = R.SetSelfReferences(
+      R.graph.NewNode(R.common.EffectPhi(2), R.start, R.self, loop));
+  Node* effect2 = R.SetSelfReferences(
+      R.graph.NewNode(R.common.EffectPhi(2), R.start, R.self, loop));
+  Branch b(R, R.one, loop);
+  loop->ReplaceInput(1, b.if_true);
+  Node* end = R.graph.end();
+  end->ReplaceInput(0, b.if_false);
+
+  R.ReduceGraph();
+
+  CheckLoop(loop, R.start, loop);
+  CHECK_EQ(end, R.graph.end());
+  Node* terminate = end->InputAt(0);
+  CHECK_EQ(IrOpcode::kTerminate, terminate->opcode());
+  CHECK_EQ(3, terminate->InputCount());
+  CHECK_EQ(2, terminate->op()->EffectInputCount());
+  CHECK_EQ(1, terminate->op()->ControlInputCount());
+  Node* e0 = terminate->InputAt(0);
+  Node* e1 = terminate->InputAt(1);
+  CHECK(e0 == effect1 || e1 == effect1);
+  CHECK(e0 == effect2 || e1 == effect2);
+  CHECK_EQ(loop, terminate->InputAt(2));
+}
+
+
+TEST(CNonTermLoop_terminate_m1) {
+  ControlReducerTester R;
+  Node* loop =
+      R.SetSelfReferences(R.graph.NewNode(R.common.Loop(2), R.start, R.self));
+  Node* effect = R.SetSelfReferences(
+      R.graph.NewNode(R.common.EffectPhi(2), R.start, R.self, loop));
+  R.ReduceGraph();
+  Node* end = R.graph.end();
+  CHECK_EQ(R.start, loop->InputAt(0));
+  CHECK_EQ(loop, loop->InputAt(1));
+  Node* merge = end->InputAt(0);
+  CHECK_EQ(IrOpcode::kMerge, merge->opcode());
+  CHECK_EQ(2, merge->InputCount());
+  CHECK_EQ(2, merge->op()->ControlInputCount());
+  CHECK_EQ(R.start, merge->InputAt(0));
+
+  Node* terminate = merge->InputAt(1);
+  CHECK_EQ(IrOpcode::kTerminate, terminate->opcode());
+  CHECK_EQ(2, terminate->InputCount());
+  CHECK_EQ(1, terminate->op()->EffectInputCount());
+  CHECK_EQ(1, terminate->op()->ControlInputCount());
+  CHECK_EQ(effect, terminate->InputAt(0));
+  CHECK_EQ(loop, terminate->InputAt(1));
+}
+
+
+TEST(CNonTermLoop_big1) {
+  ControlReducerTester R;
+  Branch b1(R, R.p0);
+  Node* rt = R.graph.NewNode(R.common.Return(), R.one, R.start, b1.if_true);
+
+  Branch b2(R, R.p0, b1.if_false);
+  Node* rf = R.graph.NewNode(R.common.Return(), R.zero, R.start, b2.if_true);
+  Node* loop = R.SetSelfReferences(
+      R.graph.NewNode(R.common.Loop(2), b2.if_false, R.self));
+  Node* merge = R.graph.NewNode(R.common.Merge(2), rt, rf);
+  R.end->ReplaceInput(0, merge);
+
+  R.ReduceGraph();
+
+  CheckInputs(R.end, merge);
+  CheckInputs(merge, rt, rf, loop);
+  CheckInputs(loop, b2.if_false, loop);
+}
+
+
+TEST(CNonTermLoop_big2) {
+  ControlReducerTester R;
+  Branch b1(R, R.p0);
+  Node* rt = R.graph.NewNode(R.common.Return(), R.one, R.start, b1.if_true);
+
+  Branch b2(R, R.zero, b1.if_false);
+  Node* rf = R.graph.NewNode(R.common.Return(), R.zero, R.start, b2.if_true);
+  Node* loop = R.SetSelfReferences(
+      R.graph.NewNode(R.common.Loop(2), b2.if_false, R.self));
+  Node* merge = R.graph.NewNode(R.common.Merge(2), rt, rf);
+  R.end->ReplaceInput(0, merge);
+
+  R.ReduceGraph();
+
+  Node* new_merge = R.end->InputAt(0);  // old merge was reduced.
+  CHECK_NE(merge, new_merge);
+  CheckInputs(new_merge, rt, loop);
+  CheckInputs(loop, b1.if_false, loop);
+  CHECK(merge->IsDead());
+  CHECK(rf->IsDead());
+  CHECK(b2.if_true->IsDead());
+}
+
+
+TEST(Return1) {
+  ControlReducerTester R;
+  Node* ret = R.Return(R.one, R.start, R.start);
+  R.ReduceGraph();
+  CheckInputs(R.graph.end(), ret);
+  CheckInputs(ret, R.one, R.start, R.start);
+}
+
+
+TEST(Return2) {
+  ControlReducerTester R;
+  Diamond d(R, R.one);
+  Node* ret = R.Return(R.half, R.start, d.merge);
+  R.ReduceGraph();
+  CHECK(d.branch->IsDead());
+  CHECK(d.if_true->IsDead());
+  CHECK(d.if_false->IsDead());
+  CHECK(d.merge->IsDead());
+
+  CheckInputs(R.graph.end(), ret);
+  CheckInputs(ret, R.half, R.start, R.start);
+}
+
+
+TEST(Return_true1) {
+  ControlReducerTester R;
+  Diamond d(R, R.one, R.half, R.zero);
+  Node* ret = R.Return(d.phi, R.start, d.merge);
+  R.ReduceGraph();
+  CHECK(d.branch->IsDead());
+  CHECK(d.if_true->IsDead());
+  CHECK(d.if_false->IsDead());
+  CHECK(d.merge->IsDead());
+  CHECK(d.phi->IsDead());
+
+  CheckInputs(R.graph.end(), ret);
+  CheckInputs(ret, R.half, R.start, R.start);
+}
+
+
+TEST(Return_false1) {
+  ControlReducerTester R;
+  Diamond d(R, R.zero, R.one, R.half);
+  Node* ret = R.Return(d.phi, R.start, d.merge);
+  R.ReduceGraph();
+  CHECK(d.branch->IsDead());
+  CHECK(d.if_true->IsDead());
+  CHECK(d.if_false->IsDead());
+  CHECK(d.merge->IsDead());
+  CHECK(d.phi->IsDead());
+
+  CheckInputs(R.graph.end(), ret);
+  CheckInputs(ret, R.half, R.start, R.start);
+}
+
+
+void CheckDeadDiamond(Diamond& d) {
+  CHECK(d.branch->IsDead());
+  CHECK(d.if_true->IsDead());
+  CHECK(d.if_false->IsDead());
+  CHECK(d.merge->IsDead());
+  if (d.phi != NULL) CHECK(d.phi->IsDead());
+}
+
+
+void CheckLiveDiamond(Diamond& d, bool live_phi = true) {
+  CheckInputs(d.merge, d.if_true, d.if_false);
+  CheckInputs(d.if_true, d.branch);
+  CheckInputs(d.if_false, d.branch);
+  if (d.phi != NULL) {
+    if (live_phi) {
+      CHECK_EQ(3, d.phi->InputCount());
+      CHECK_EQ(d.merge, d.phi->InputAt(2));
+    } else {
+      CHECK(d.phi->IsDead());
+    }
+  }
+}
+
+
+TEST(Return_effect1) {
+  ControlReducerTester R;
+  Diamond d(R, R.one);
+  Node* e1 = R.jsgraph.Float64Constant(-100.1);
+  Node* e2 = R.jsgraph.Float64Constant(+100.1);
+  Node* effect = R.graph.NewNode(R.common.EffectPhi(2), e1, e2, d.merge);
+  Node* ret = R.Return(R.p0, effect, d.merge);
+  R.ReduceGraph();
+  CheckDeadDiamond(d);
+  CHECK(effect->IsDead());
+
+  CheckInputs(R.graph.end(), ret);
+  CheckInputs(ret, R.p0, e1, R.start);
+}
+
+
+TEST(Return_nested_diamonds1) {
+  ControlReducerTester R;
+  Diamond d1(R, R.p0, R.one, R.zero);
+  Diamond d2(R, R.p0);
+  Diamond d3(R, R.p0);
+
+  d2.nest(d1, true);
+  d3.nest(d1, false);
+
+  Node* ret = R.Return(d1.phi, R.start, d1.merge);
+
+  R.ReduceGraph();  // nothing should happen.
+
+  CheckInputs(ret, d1.phi, R.start, d1.merge);
+  CheckInputs(d1.phi, R.one, R.zero, d1.merge);
+  CheckInputs(d1.merge, d2.merge, d3.merge);
+  CheckLiveDiamond(d2);
+  CheckLiveDiamond(d3);
+}
+
+
+TEST(Return_nested_diamonds_true1) {
+  ControlReducerTester R;
+  Diamond d1(R, R.one, R.one, R.zero);
+  Diamond d2(R, R.p0);
+  Diamond d3(R, R.p0);
+
+  d2.nest(d1, true);
+  d3.nest(d1, false);
+
+  Node* ret = R.Return(d1.phi, R.start, d1.merge);
+
+  R.ReduceGraph();  // d1 gets folded true.
+
+  CheckInputs(ret, R.one, R.start, d2.merge);
+  CheckInputs(d2.branch, R.p0, R.start);
+  CheckDeadDiamond(d1);
+  CheckLiveDiamond(d2);
+  CheckDeadDiamond(d3);
+}
+
+
+TEST(Return_nested_diamonds_false1) {
+  ControlReducerTester R;
+  Diamond d1(R, R.zero, R.one, R.zero);
+  Diamond d2(R, R.p0);
+  Diamond d3(R, R.p0);
+
+  d2.nest(d1, true);
+  d3.nest(d1, false);
+
+  Node* ret = R.Return(d1.phi, R.start, d1.merge);
+
+  R.ReduceGraph();  // d1 gets folded false.
+
+  CheckInputs(ret, R.zero, R.start, d3.merge);
+  CheckInputs(d3.branch, R.p0, R.start);
+  CheckDeadDiamond(d1);
+  CheckDeadDiamond(d2);
+  CheckLiveDiamond(d3);
+}
+
+
+TEST(Return_nested_diamonds_true_true1) {
+  ControlReducerTester R;
+  Diamond d1(R, R.one, R.one, R.zero);
+  Diamond d2(R, R.one);
+  Diamond d3(R, R.p0);
+
+  d2.nest(d1, true);
+  d3.nest(d1, false);
+
+  Node* ret = R.Return(d1.phi, R.start, d1.merge);
+
+  R.ReduceGraph();  // d1 and d2 both get folded true.
+
+  CheckInputs(ret, R.one, R.start, R.start);
+  CheckDeadDiamond(d1);
+  CheckDeadDiamond(d2);
+  CheckDeadDiamond(d3);
+}
+
+
+TEST(Return_nested_diamonds_true_false1) {
+  ControlReducerTester R;
+  Diamond d1(R, R.one, R.one, R.zero);
+  Diamond d2(R, R.zero);
+  Diamond d3(R, R.p0);
+
+  d2.nest(d1, true);
+  d3.nest(d1, false);
+
+  Node* ret = R.Return(d1.phi, R.start, d1.merge);
+
+  R.ReduceGraph();  // d1 gets folded true and d2 gets folded false.
+
+  CheckInputs(ret, R.one, R.start, R.start);
+  CheckDeadDiamond(d1);
+  CheckDeadDiamond(d2);
+  CheckDeadDiamond(d3);
+}
+
+
+TEST(Return_nested_diamonds2) {
+  ControlReducerTester R;
+  Node* x2 = R.jsgraph.Float64Constant(11.1);
+  Node* y2 = R.jsgraph.Float64Constant(22.2);
+  Node* x3 = R.jsgraph.Float64Constant(33.3);
+  Node* y3 = R.jsgraph.Float64Constant(44.4);
+
+  Diamond d2(R, R.p0, x2, y2);
+  Diamond d3(R, R.p0, x3, y3);
+  Diamond d1(R, R.p0, d2.phi, d3.phi);
+
+  d2.nest(d1, true);
+  d3.nest(d1, false);
+
+  Node* ret = R.Return(d1.phi, R.start, d1.merge);
+
+  R.ReduceGraph();  // nothing should happen.
+
+  CheckInputs(ret, d1.phi, R.start, d1.merge);
+  CheckInputs(d1.phi, d2.phi, d3.phi, d1.merge);
+  CheckInputs(d1.merge, d2.merge, d3.merge);
+  CheckLiveDiamond(d2);
+  CheckLiveDiamond(d3);
+}
+
+
+TEST(Return_nested_diamonds_true2) {
+  ControlReducerTester R;
+  Node* x2 = R.jsgraph.Float64Constant(11.1);
+  Node* y2 = R.jsgraph.Float64Constant(22.2);
+  Node* x3 = R.jsgraph.Float64Constant(33.3);
+  Node* y3 = R.jsgraph.Float64Constant(44.4);
+
+  Diamond d2(R, R.p0, x2, y2);
+  Diamond d3(R, R.p0, x3, y3);
+  Diamond d1(R, R.one, d2.phi, d3.phi);
+
+  d2.nest(d1, true);
+  d3.nest(d1, false);
+
+  Node* ret = R.Return(d1.phi, R.start, d1.merge);
+
+  R.ReduceGraph();  // d1 gets folded true.
+
+  CheckInputs(ret, d2.phi, R.start, d2.merge);
+  CheckInputs(d2.branch, R.p0, R.start);
+  CheckDeadDiamond(d1);
+  CheckLiveDiamond(d2);
+  CheckDeadDiamond(d3);
+}
+
+
+TEST(Return_nested_diamonds_true_true2) {
+  ControlReducerTester R;
+  Node* x2 = R.jsgraph.Float64Constant(11.1);
+  Node* y2 = R.jsgraph.Float64Constant(22.2);
+  Node* x3 = R.jsgraph.Float64Constant(33.3);
+  Node* y3 = R.jsgraph.Float64Constant(44.4);
+
+  Diamond d2(R, R.one, x2, y2);
+  Diamond d3(R, R.p0, x3, y3);
+  Diamond d1(R, R.one, d2.phi, d3.phi);
+
+  d2.nest(d1, true);
+  d3.nest(d1, false);
+
+  Node* ret = R.Return(d1.phi, R.start, d1.merge);
+
+  R.ReduceGraph();  // d1 gets folded true.
+
+  CheckInputs(ret, x2, R.start, R.start);
+  CheckDeadDiamond(d1);
+  CheckDeadDiamond(d2);
+  CheckDeadDiamond(d3);
+}
+
+
+TEST(Return_nested_diamonds_true_false2) {
+  ControlReducerTester R;
+  Node* x2 = R.jsgraph.Float64Constant(11.1);
+  Node* y2 = R.jsgraph.Float64Constant(22.2);
+  Node* x3 = R.jsgraph.Float64Constant(33.3);
+  Node* y3 = R.jsgraph.Float64Constant(44.4);
+
+  Diamond d2(R, R.zero, x2, y2);
+  Diamond d3(R, R.p0, x3, y3);
+  Diamond d1(R, R.one, d2.phi, d3.phi);
+
+  d2.nest(d1, true);
+  d3.nest(d1, false);
+
+  Node* ret = R.Return(d1.phi, R.start, d1.merge);
+
+  R.ReduceGraph();  // d1 gets folded true.
+
+  CheckInputs(ret, y2, R.start, R.start);
+  CheckDeadDiamond(d1);
+  CheckDeadDiamond(d2);
+  CheckDeadDiamond(d3);
+}
diff --git a/test/cctest/compiler/test-gap-resolver.cc b/test/cctest/compiler/test-gap-resolver.cc
index 6239f2a..ea6f4ee 100644
--- a/test/cctest/compiler/test-gap-resolver.cc
+++ b/test/cctest/compiler/test-gap-resolver.cc
@@ -58,13 +58,16 @@
     return Value(op->kind(), op->index());
   }
 
-  friend OStream& operator<<(OStream& os, const InterpreterState& is) {
+  friend std::ostream& operator<<(std::ostream& os,
+                                  const InterpreterState& is) {
     for (OperandMap::const_iterator it = is.values_.begin();
          it != is.values_.end(); ++it) {
       if (it != is.values_.begin()) os << " ";
       InstructionOperand source(it->first.first, it->first.second);
       InstructionOperand destination(it->second.first, it->second.second);
-      os << MoveOperands(&source, &destination);
+      MoveOperands mo(&source, &destination);
+      PrintableMoveOperands pmo = {RegisterConfiguration::ArchDefault(), &mo};
+      os << pmo;
     }
     return os;
   }
diff --git a/test/cctest/compiler/test-graph-reducer.cc b/test/cctest/compiler/test-graph-reducer.cc
index eabfd22..70b57b9 100644
--- a/test/cctest/compiler/test-graph-reducer.cc
+++ b/test/cctest/compiler/test-graph-reducer.cc
@@ -5,7 +5,6 @@
 #include "src/v8.h"
 
 #include "graph-tester.h"
-#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/graph-reducer.h"
 
 using namespace v8::internal;
@@ -21,15 +20,15 @@
 const uint8_t OPCODE_C1 = 31;
 const uint8_t OPCODE_C2 = 32;
 
-static SimpleOperator OPA0(OPCODE_A0, Operator::kNoWrite, 0, 0, "opa0");
-static SimpleOperator OPA1(OPCODE_A1, Operator::kNoWrite, 1, 0, "opa1");
-static SimpleOperator OPA2(OPCODE_A2, Operator::kNoWrite, 2, 0, "opa2");
-static SimpleOperator OPB0(OPCODE_B0, Operator::kNoWrite, 0, 0, "opa0");
-static SimpleOperator OPB1(OPCODE_B1, Operator::kNoWrite, 1, 0, "opa1");
-static SimpleOperator OPB2(OPCODE_B2, Operator::kNoWrite, 2, 0, "opa2");
-static SimpleOperator OPC0(OPCODE_C0, Operator::kNoWrite, 0, 0, "opc0");
-static SimpleOperator OPC1(OPCODE_C1, Operator::kNoWrite, 1, 0, "opc1");
-static SimpleOperator OPC2(OPCODE_C2, Operator::kNoWrite, 2, 0, "opc2");
+static Operator OPA0(OPCODE_A0, Operator::kNoWrite, "opa0", 0, 0, 0, 0, 0, 0);
+static Operator OPA1(OPCODE_A1, Operator::kNoWrite, "opa1", 1, 0, 0, 0, 0, 0);
+static Operator OPA2(OPCODE_A2, Operator::kNoWrite, "opa2", 2, 0, 0, 0, 0, 0);
+static Operator OPB0(OPCODE_B0, Operator::kNoWrite, "opa0", 0, 0, 0, 0, 0, 0);
+static Operator OPB1(OPCODE_B1, Operator::kNoWrite, "opa1", 1, 0, 0, 0, 0, 0);
+static Operator OPB2(OPCODE_B2, Operator::kNoWrite, "opa2", 2, 0, 0, 0, 0, 0);
+static Operator OPC0(OPCODE_C0, Operator::kNoWrite, "opc0", 0, 0, 0, 0, 0, 0);
+static Operator OPC1(OPCODE_C1, Operator::kNoWrite, "opc1", 1, 0, 0, 0, 0, 0);
+static Operator OPC2(OPCODE_C2, Operator::kNoWrite, "opc2", 2, 0, 0, 0, 0, 0);
 
 
 // Replaces all "A" operators with "B" operators without creating new nodes.
@@ -202,7 +201,7 @@
   Node* end = graph.NewNode(&OPA1, n1);
   graph.SetEnd(end);
 
-  GraphReducer reducer(&graph);
+  GraphReducer reducer(&graph, graph.zone());
   ReducerRecorder recorder(graph.zone());
   reducer.AddReducer(&recorder);
   reducer.ReduceGraph();
@@ -220,7 +219,7 @@
   Node* end = graph.NewNode(&OPA2, n2, n3);
   graph.SetEnd(end);
 
-  GraphReducer reducer(&graph);
+  GraphReducer reducer(&graph, graph.zone());
   ReducerRecorder recorder(graph.zone());
   reducer.AddReducer(&recorder);
   reducer.ReduceGraph();
@@ -238,7 +237,7 @@
   Node* end = graph.NewNode(&OPA1, n1);
   graph.SetEnd(end);
 
-  GraphReducer reducer(&graph);
+  GraphReducer reducer(&graph, graph.zone());
   InPlaceABReducer r;
   reducer.AddReducer(&r);
 
@@ -263,7 +262,7 @@
   Node* end = graph.NewNode(&OPA2, n2, n3);
   graph.SetEnd(end);
 
-  GraphReducer reducer(&graph);
+  GraphReducer reducer(&graph, graph.zone());
   InPlaceABReducer r;
   reducer.AddReducer(&r);
 
@@ -293,7 +292,7 @@
   Node* end = graph.NewNode(&OPA2, n2, n3);
   graph.SetEnd(end);
 
-  GraphReducer reducer(&graph);
+  GraphReducer reducer(&graph, graph.zone());
   NewABReducer r(&graph);
   reducer.AddReducer(&r);
 
@@ -330,7 +329,7 @@
   graph.SetEnd(end);
   CHECK_EQ(1, graph.NodeCount());
 
-  GraphReducer reducer(&graph);
+  GraphReducer reducer(&graph, graph.zone());
   A0Wrapper r(&graph);
   reducer.AddReducer(&r);
 
@@ -352,7 +351,7 @@
   graph.SetEnd(end);
   CHECK_EQ(1, graph.NodeCount());
 
-  GraphReducer reducer(&graph);
+  GraphReducer reducer(&graph, graph.zone());
   B0Wrapper r(&graph);
   reducer.AddReducer(&r);
 
@@ -379,7 +378,7 @@
   Node* end = graph.NewNode(&OPA1, n1);
   graph.SetEnd(end);
 
-  GraphReducer reducer(&graph);
+  GraphReducer reducer(&graph, graph.zone());
   A1Forwarder r;
   reducer.AddReducer(&r);
 
@@ -403,7 +402,7 @@
   Node* end = graph.NewNode(&OPA2, n2, n3);
   graph.SetEnd(end);
 
-  GraphReducer reducer(&graph);
+  GraphReducer reducer(&graph, graph.zone());
   A1Forwarder r;
   reducer.AddReducer(&r);
 
@@ -434,7 +433,7 @@
     }
     graph.SetEnd(end);
 
-    GraphReducer reducer(&graph);
+    GraphReducer reducer(&graph, graph.zone());
     A1Forwarder r;
     reducer.AddReducer(&r);
 
@@ -458,7 +457,7 @@
   Node* end = graph.NewNode(&OPA2, n2, n3);
   graph.SetEnd(end);
 
-  GraphReducer reducer(&graph);
+  GraphReducer reducer(&graph, graph.zone());
   InPlaceABReducer r;
   B1Forwarder f;
   reducer.AddReducer(&r);
@@ -501,7 +500,7 @@
 
     graph.SetEnd(end);
 
-    GraphReducer reducer(&graph);
+    GraphReducer reducer(&graph, graph.zone());
     reducer.AddReducer(&r);
 
     int before = graph.NodeCount();
@@ -560,7 +559,7 @@
 
         GenDAG(&graph, p3, p2, p1);
 
-        GraphReducer reducer(&graph);
+        GraphReducer reducer(&graph, graph.zone());
         AB2Sorter r1;
         A1Forwarder r2;
         InPlaceABReducer r3;
@@ -599,7 +598,7 @@
     Node* end = graph.NewNode(&OPA1, n1);
     graph.SetEnd(end);
 
-    GraphReducer reducer(&graph);
+    GraphReducer reducer(&graph, graph.zone());
     InPlaceABReducer abr;
     InPlaceBCReducer bcr;
     if (i == 0) {
@@ -621,41 +620,3 @@
     }
   }
 }
-
-
-// Tests that a reducer is only applied once.
-class OneTimeReducer : public Reducer {
- public:
-  OneTimeReducer(Reducer* reducer, Zone* zone)
-      : reducer_(reducer),
-        nodes_(NodeSet::key_compare(), NodeSet::allocator_type(zone)) {}
-  virtual Reduction Reduce(Node* node) {
-    CHECK_EQ(0, static_cast<int>(nodes_.count(node)));
-    nodes_.insert(node);
-    return reducer_->Reduce(node);
-  }
-  Reducer* reducer_;
-  NodeSet nodes_;
-};
-
-
-TEST(OneTimeReduce1) {
-  GraphTester graph;
-
-  Node* n1 = graph.NewNode(&OPA0);
-  Node* end = graph.NewNode(&OPA1, n1);
-  graph.SetEnd(end);
-
-  GraphReducer reducer(&graph);
-  InPlaceABReducer r;
-  OneTimeReducer once(&r, graph.zone());
-  reducer.AddReducer(&once);
-
-  // Tests A* => B* with in-place updates. Should only be applied once.
-  int before = graph.NodeCount();
-  reducer.ReduceGraph();
-  CHECK_EQ(before, graph.NodeCount());
-  CHECK_EQ(&OPB0, n1->op());
-  CHECK_EQ(&OPB1, end->op());
-  CHECK_EQ(n1, end->InputAt(0));
-}
diff --git a/test/cctest/compiler/test-graph-visualizer.cc b/test/cctest/compiler/test-graph-visualizer.cc
new file mode 100644
index 0000000..ce3e6b7
--- /dev/null
+++ b/test/cctest/compiler/test-graph-visualizer.cc
@@ -0,0 +1,90 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/graph-visualizer.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/node.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/schedule.h"
+#include "src/compiler/scheduler.h"
+#include "src/compiler/verifier.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+TEST(NodeWithNullInputReachableFromEnd) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(0));
+  graph.SetStart(start);
+  Node* k = graph.NewNode(common.Int32Constant(0));
+  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 1), k, start);
+  phi->ReplaceInput(0, NULL);
+  graph.SetEnd(phi);
+
+  OFStream os(stdout);
+  os << AsDOT(graph);
+  os << AsJSON(graph);
+}
+
+
+TEST(NodeWithNullControlReachableFromEnd) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(0));
+  graph.SetStart(start);
+  Node* k = graph.NewNode(common.Int32Constant(0));
+  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 1), k, start);
+  phi->ReplaceInput(1, NULL);
+  graph.SetEnd(phi);
+
+  OFStream os(stdout);
+  os << AsDOT(graph);
+  os << AsJSON(graph);
+}
+
+
+TEST(NodeWithNullInputReachableFromStart) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(0));
+  graph.SetStart(start);
+  Node* k = graph.NewNode(common.Int32Constant(0));
+  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 1), k, start);
+  phi->ReplaceInput(0, NULL);
+  graph.SetEnd(start);
+
+  OFStream os(stdout);
+  os << AsDOT(graph);
+  os << AsJSON(graph);
+}
+
+
+TEST(NodeWithNullControlReachableFromStart) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(0));
+  graph.SetStart(start);
+  Node* merge = graph.NewNode(common.Merge(2), start, start);
+  merge->ReplaceInput(1, NULL);
+  graph.SetEnd(merge);
+
+  OFStream os(stdout);
+  os << AsDOT(graph);
+  os << AsJSON(graph);
+}
diff --git a/test/cctest/compiler/test-instruction.cc b/test/cctest/compiler/test-instruction.cc
index a9feaac..294812f 100644
--- a/test/cctest/compiler/test-instruction.cc
+++ b/test/cctest/compiler/test-instruction.cc
@@ -31,12 +31,11 @@
         graph(zone()),
         schedule(zone()),
         info(static_cast<HydrogenCodeStub*>(NULL), main_isolate()),
-        linkage(&info),
+        linkage(zone(), &info),
         common(zone()),
+        machine(zone()),
         code(NULL) {}
 
-  ~InstructionTester() { delete code; }
-
   Isolate* isolate;
   Graph graph;
   Schedule schedule;
@@ -51,10 +50,12 @@
   void allocCode() {
     if (schedule.rpo_order()->size() == 0) {
       // Compute the RPO order.
-      Scheduler::ComputeSpecialRPO(&schedule);
+      Scheduler::ComputeSpecialRPO(main_zone(), &schedule);
       DCHECK(schedule.rpo_order()->size() > 0);
     }
-    code = new TestInstrSeq(&linkage, &graph, &schedule);
+    InstructionBlocks* instruction_blocks =
+        TestInstrSeq::InstructionBlocksFor(main_zone(), &schedule);
+    code = new (main_zone()) TestInstrSeq(main_zone(), instruction_blocks);
   }
 
   Node* Int32Constant(int32_t val) {
@@ -81,10 +82,10 @@
     return node;
   }
 
-  int NewInstr(BasicBlock* block) {
+  int NewInstr() {
     InstructionCode opcode = static_cast<InstructionCode>(110);
     TestInstr* instr = TestInstr::New(zone(), opcode);
-    return code->AddInstruction(instr, block);
+    return code->AddInstruction(instr);
   }
 
   UnallocatedOperand* NewUnallocated(int vreg) {
@@ -93,6 +94,21 @@
     unallocated->set_virtual_register(vreg);
     return unallocated;
   }
+
+  InstructionBlock* BlockAt(BasicBlock* block) {
+    return code->InstructionBlockAt(block->GetRpoNumber());
+  }
+  BasicBlock* GetBasicBlock(int instruction_index) {
+    const InstructionBlock* block =
+        code->GetInstructionBlock(instruction_index);
+    return schedule.rpo_order()->at(block->rpo_number().ToSize());
+  }
+  int first_instruction_index(BasicBlock* block) {
+    return BlockAt(block)->first_instruction_index();
+  }
+  int last_instruction_index(BasicBlock* block) {
+    return BlockAt(block)->last_instruction_index();
+  }
 };
 
 
@@ -112,17 +128,16 @@
 
   R.allocCode();
 
-  CHECK_EQ(R.graph.NodeCount(), R.code->ValueCount());
-
   BasicBlockVector* blocks = R.schedule.rpo_order();
-  CHECK_EQ(static_cast<int>(blocks->size()), R.code->BasicBlockCount());
+  CHECK_EQ(static_cast<int>(blocks->size()), R.code->InstructionBlockCount());
 
   int index = 0;
   for (BasicBlockVectorIter i = blocks->begin(); i != blocks->end();
        i++, index++) {
     BasicBlock* block = *i;
-    CHECK_EQ(block, R.code->BlockAt(index));
-    CHECK_EQ(-1, R.code->GetLoopEnd(block));
+    CHECK_EQ(block->rpo_number(), R.BlockAt(block)->rpo_number().ToInt());
+    CHECK_EQ(block->id().ToInt(), R.BlockAt(block)->id().ToInt());
+    CHECK_EQ(NULL, block->loop_end());
   }
 }
 
@@ -141,47 +156,47 @@
 
   R.allocCode();
 
-  R.code->StartBlock(b0);
-  int i0 = R.NewInstr(b0);
-  int i1 = R.NewInstr(b0);
-  R.code->EndBlock(b0);
-  R.code->StartBlock(b1);
-  int i2 = R.NewInstr(b1);
-  int i3 = R.NewInstr(b1);
-  int i4 = R.NewInstr(b1);
-  int i5 = R.NewInstr(b1);
-  R.code->EndBlock(b1);
-  R.code->StartBlock(b2);
-  int i6 = R.NewInstr(b2);
-  int i7 = R.NewInstr(b2);
-  int i8 = R.NewInstr(b2);
-  R.code->EndBlock(b2);
-  R.code->StartBlock(b3);
-  R.code->EndBlock(b3);
+  R.code->StartBlock(b0->GetRpoNumber());
+  int i0 = R.NewInstr();
+  int i1 = R.NewInstr();
+  R.code->EndBlock(b0->GetRpoNumber());
+  R.code->StartBlock(b1->GetRpoNumber());
+  int i2 = R.NewInstr();
+  int i3 = R.NewInstr();
+  int i4 = R.NewInstr();
+  int i5 = R.NewInstr();
+  R.code->EndBlock(b1->GetRpoNumber());
+  R.code->StartBlock(b2->GetRpoNumber());
+  int i6 = R.NewInstr();
+  int i7 = R.NewInstr();
+  int i8 = R.NewInstr();
+  R.code->EndBlock(b2->GetRpoNumber());
+  R.code->StartBlock(b3->GetRpoNumber());
+  R.code->EndBlock(b3->GetRpoNumber());
 
-  CHECK_EQ(b0, R.code->GetBasicBlock(i0));
-  CHECK_EQ(b0, R.code->GetBasicBlock(i1));
+  CHECK_EQ(b0, R.GetBasicBlock(i0));
+  CHECK_EQ(b0, R.GetBasicBlock(i1));
 
-  CHECK_EQ(b1, R.code->GetBasicBlock(i2));
-  CHECK_EQ(b1, R.code->GetBasicBlock(i3));
-  CHECK_EQ(b1, R.code->GetBasicBlock(i4));
-  CHECK_EQ(b1, R.code->GetBasicBlock(i5));
+  CHECK_EQ(b1, R.GetBasicBlock(i2));
+  CHECK_EQ(b1, R.GetBasicBlock(i3));
+  CHECK_EQ(b1, R.GetBasicBlock(i4));
+  CHECK_EQ(b1, R.GetBasicBlock(i5));
 
-  CHECK_EQ(b2, R.code->GetBasicBlock(i6));
-  CHECK_EQ(b2, R.code->GetBasicBlock(i7));
-  CHECK_EQ(b2, R.code->GetBasicBlock(i8));
+  CHECK_EQ(b2, R.GetBasicBlock(i6));
+  CHECK_EQ(b2, R.GetBasicBlock(i7));
+  CHECK_EQ(b2, R.GetBasicBlock(i8));
 
-  CHECK_EQ(b0, R.code->GetBasicBlock(b0->first_instruction_index()));
-  CHECK_EQ(b0, R.code->GetBasicBlock(b0->last_instruction_index()));
+  CHECK_EQ(b0, R.GetBasicBlock(R.first_instruction_index(b0)));
+  CHECK_EQ(b0, R.GetBasicBlock(R.last_instruction_index(b0)));
 
-  CHECK_EQ(b1, R.code->GetBasicBlock(b1->first_instruction_index()));
-  CHECK_EQ(b1, R.code->GetBasicBlock(b1->last_instruction_index()));
+  CHECK_EQ(b1, R.GetBasicBlock(R.first_instruction_index(b1)));
+  CHECK_EQ(b1, R.GetBasicBlock(R.last_instruction_index(b1)));
 
-  CHECK_EQ(b2, R.code->GetBasicBlock(b2->first_instruction_index()));
-  CHECK_EQ(b2, R.code->GetBasicBlock(b2->last_instruction_index()));
+  CHECK_EQ(b2, R.GetBasicBlock(R.first_instruction_index(b2)));
+  CHECK_EQ(b2, R.GetBasicBlock(R.last_instruction_index(b2)));
 
-  CHECK_EQ(b3, R.code->GetBasicBlock(b3->first_instruction_index()));
-  CHECK_EQ(b3, R.code->GetBasicBlock(b3->last_instruction_index()));
+  CHECK_EQ(b3, R.GetBasicBlock(R.first_instruction_index(b3)));
+  CHECK_EQ(b3, R.GetBasicBlock(R.last_instruction_index(b3)));
 }
 
 
@@ -194,10 +209,10 @@
   R.allocCode();
   TestInstr* i0 = TestInstr::New(R.zone(), 100);
   TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
-  R.code->StartBlock(b0);
-  R.code->AddInstruction(i0, b0);
-  R.code->AddInstruction(g, b0);
-  R.code->EndBlock(b0);
+  R.code->StartBlock(b0->GetRpoNumber());
+  R.code->AddInstruction(i0);
+  R.code->AddInstruction(g);
+  R.code->EndBlock(b0->GetRpoNumber());
 
   CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
 
@@ -221,17 +236,17 @@
   R.allocCode();
   TestInstr* i0 = TestInstr::New(R.zone(), 100);
   TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
-  R.code->StartBlock(b0);
-  R.code->AddInstruction(i0, b0);
-  R.code->AddInstruction(g, b0);
-  R.code->EndBlock(b0);
+  R.code->StartBlock(b0->GetRpoNumber());
+  R.code->AddInstruction(i0);
+  R.code->AddInstruction(g);
+  R.code->EndBlock(b0->GetRpoNumber());
 
   TestInstr* i1 = TestInstr::New(R.zone(), 102);
   TestInstr* g1 = TestInstr::New(R.zone(), 104)->MarkAsControl();
-  R.code->StartBlock(b1);
-  R.code->AddInstruction(i1, b1);
-  R.code->AddInstruction(g1, b1);
-  R.code->EndBlock(b1);
+  R.code->StartBlock(b1->GetRpoNumber());
+  R.code->AddInstruction(i1);
+  R.code->AddInstruction(g1);
+  R.code->EndBlock(b1->GetRpoNumber());
 
   CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
 
@@ -262,10 +277,10 @@
   R.allocCode();
   TestInstr* i0 = TestInstr::New(R.zone(), 100);
   TestInstr* g = TestInstr::New(R.zone(), 103)->MarkAsControl();
-  R.code->StartBlock(b0);
-  R.code->AddInstruction(i0, b0);
-  R.code->AddInstruction(g, b0);
-  R.code->EndBlock(b0);
+  R.code->StartBlock(b0->GetRpoNumber());
+  R.code->AddInstruction(i0);
+  R.code->AddInstruction(g);
+  R.code->EndBlock(b0->GetRpoNumber());
 
   CHECK_EQ(true, R.code->InstructionAt(0)->IsBlockStart());
 
diff --git a/test/cctest/compiler/test-js-constant-cache.cc b/test/cctest/compiler/test-js-constant-cache.cc
index eb0975e..8588f66 100644
--- a/test/cctest/compiler/test-js-constant-cache.cc
+++ b/test/cctest/compiler/test-js-constant-cache.cc
@@ -4,6 +4,7 @@
 
 #include "src/v8.h"
 
+#include "src/assembler.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/compiler/typer.h"
@@ -20,8 +21,8 @@
       : main_graph_(zone),
         main_common_(zone),
         main_javascript_(zone),
-        main_typer_(zone),
-        main_machine_() {}
+        main_typer_(&main_graph_, MaybeHandle<Context>()),
+        main_machine_(zone) {}
   Graph main_graph_;
   CommonOperatorBuilder main_common_;
   JSOperatorBuilder main_javascript_;
@@ -30,14 +31,19 @@
 };
 
 
+// TODO(dcarney): JSConstantCacheTester inherits from JSGraph???
 class JSConstantCacheTester : public HandleAndZoneScope,
                               public JSCacheTesterHelper,
                               public JSGraph {
  public:
   JSConstantCacheTester()
       : JSCacheTesterHelper(main_zone()),
-        JSGraph(&main_graph_, &main_common_, &main_javascript_, &main_typer_,
-                &main_machine_) {}
+        JSGraph(&main_graph_, &main_common_, &main_javascript_,
+                &main_machine_) {
+    main_graph_.SetStart(main_graph_.NewNode(common()->Start(0)));
+    main_graph_.SetEnd(main_graph_.NewNode(common()->End()));
+    main_typer_.Run();
+  }
 
   Type* upper(Node* node) { return NodeProperties::GetBounds(node).upper; }
 
@@ -227,7 +233,7 @@
   FOR_FLOAT64_INPUTS(i) {
     double value = *i;
     Node* node = T.Constant(value);
-    CHECK(T.upper(node)->Equals(Type::Of(value, T.main_zone())));
+    CHECK(T.upper(node)->Is(Type::Of(value, T.main_zone())));
   }
 }
 
@@ -289,3 +295,180 @@
 TEST(ExternalReferences) {
   // TODO(titzer): test canonicalization of external references.
 }
+
+
+static bool Contains(NodeVector* nodes, Node* n) {
+  for (size_t i = 0; i < nodes->size(); i++) {
+    if (nodes->at(i) == n) return true;
+  }
+  return false;
+}
+
+
+static void CheckGetCachedNodesContains(JSConstantCacheTester* T, Node* n) {
+  NodeVector nodes(T->main_zone());
+  T->GetCachedNodes(&nodes);
+  CHECK(Contains(&nodes, n));
+}
+
+
+TEST(JSGraph_GetCachedNodes1) {
+  JSConstantCacheTester T;
+  CheckGetCachedNodesContains(&T, T.TrueConstant());
+  CheckGetCachedNodesContains(&T, T.UndefinedConstant());
+  CheckGetCachedNodesContains(&T, T.TheHoleConstant());
+  CheckGetCachedNodesContains(&T, T.TrueConstant());
+  CheckGetCachedNodesContains(&T, T.FalseConstant());
+  CheckGetCachedNodesContains(&T, T.NullConstant());
+  CheckGetCachedNodesContains(&T, T.ZeroConstant());
+  CheckGetCachedNodesContains(&T, T.OneConstant());
+  CheckGetCachedNodesContains(&T, T.NaNConstant());
+}
+
+
+TEST(JSGraph_GetCachedNodes_int32) {
+  JSConstantCacheTester T;
+
+  int32_t constants[] = {0,  1,  1,   1,   1,   2,   3,   4,  11, 12, 13,
+                         14, 55, -55, -44, -33, -22, -11, 16, 16, 17, 17,
+                         18, 18, 19,  19,  20,  20,  21,  21, 22, 23, 24,
+                         25, 15, 30,  31,  45,  46,  47,  48};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    int count_before = T.graph()->NodeCount();
+    NodeVector nodes_before(T.main_zone());
+    T.GetCachedNodes(&nodes_before);
+    Node* n = T.Int32Constant(constants[i]);
+    if (n->id() < count_before) {
+      // An old ID indicates a cached node. It should have been in the set.
+      CHECK(Contains(&nodes_before, n));
+    }
+    // Old or new, it should be in the cached set afterwards.
+    CheckGetCachedNodesContains(&T, n);
+  }
+}
+
+
+TEST(JSGraph_GetCachedNodes_float64) {
+  JSConstantCacheTester T;
+
+  double constants[] = {0,   11.1, 12.2,  13,    14,   55.5, -55.5, -44.4,
+                        -33, -22,  -11,   0,     11.1, 11.1, 12.3,  12.3,
+                        11,  11,   -33.3, -33.3, -22,  -11};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    int count_before = T.graph()->NodeCount();
+    NodeVector nodes_before(T.main_zone());
+    T.GetCachedNodes(&nodes_before);
+    Node* n = T.Float64Constant(constants[i]);
+    if (n->id() < count_before) {
+      // An old ID indicates a cached node. It should have been in the set.
+      CHECK(Contains(&nodes_before, n));
+    }
+    // Old or new, it should be in the cached set afterwards.
+    CheckGetCachedNodesContains(&T, n);
+  }
+}
+
+
+TEST(JSGraph_GetCachedNodes_int64) {
+  JSConstantCacheTester T;
+
+  int32_t constants[] = {0,   11,  12, 13, 14, 55, -55, -44, -33,
+                         -22, -11, 16, 16, 17, 17, 18,  18,  19,
+                         19,  20,  20, 21, 21, 22, 23,  24,  25};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    int count_before = T.graph()->NodeCount();
+    NodeVector nodes_before(T.main_zone());
+    T.GetCachedNodes(&nodes_before);
+    Node* n = T.Int64Constant(constants[i]);
+    if (n->id() < count_before) {
+      // An old ID indicates a cached node. It should have been in the set.
+      CHECK(Contains(&nodes_before, n));
+    }
+    // Old or new, it should be in the cached set afterwards.
+    CheckGetCachedNodesContains(&T, n);
+  }
+}
+
+
+TEST(JSGraph_GetCachedNodes_number) {
+  JSConstantCacheTester T;
+
+  double constants[] = {0,   11.1, 12.2,  13,    14,   55.5, -55.5, -44.4,
+                        -33, -22,  -11,   0,     11.1, 11.1, 12.3,  12.3,
+                        11,  11,   -33.3, -33.3, -22,  -11};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    int count_before = T.graph()->NodeCount();
+    NodeVector nodes_before(T.main_zone());
+    T.GetCachedNodes(&nodes_before);
+    Node* n = T.Constant(constants[i]);
+    if (n->id() < count_before) {
+      // An old ID indicates a cached node. It should have been in the set.
+      CHECK(Contains(&nodes_before, n));
+    }
+    // Old or new, it should be in the cached set afterwards.
+    CheckGetCachedNodesContains(&T, n);
+  }
+}
+
+
+TEST(JSGraph_GetCachedNodes_external) {
+  JSConstantCacheTester T;
+
+  ExternalReference constants[] = {ExternalReference::address_of_min_int(),
+                                   ExternalReference::address_of_min_int(),
+                                   ExternalReference::address_of_min_int(),
+                                   ExternalReference::address_of_one_half(),
+                                   ExternalReference::address_of_one_half(),
+                                   ExternalReference::address_of_min_int(),
+                                   ExternalReference::address_of_the_hole_nan(),
+                                   ExternalReference::address_of_one_half()};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    int count_before = T.graph()->NodeCount();
+    NodeVector nodes_before(T.main_zone());
+    T.GetCachedNodes(&nodes_before);
+    Node* n = T.ExternalConstant(constants[i]);
+    if (n->id() < count_before) {
+      // An old ID indicates a cached node. It should have been in the set.
+      CHECK(Contains(&nodes_before, n));
+    }
+    // Old or new, it should be in the cached set afterwards.
+    CheckGetCachedNodesContains(&T, n);
+  }
+}
+
+
+TEST(JSGraph_GetCachedNodes_together) {
+  JSConstantCacheTester T;
+
+  Node* constants[] = {
+      T.TrueConstant(),
+      T.UndefinedConstant(),
+      T.TheHoleConstant(),
+      T.TrueConstant(),
+      T.FalseConstant(),
+      T.NullConstant(),
+      T.ZeroConstant(),
+      T.OneConstant(),
+      T.NaNConstant(),
+      T.Int32Constant(0),
+      T.Int32Constant(1),
+      T.Int64Constant(-2),
+      T.Int64Constant(-4),
+      T.Float64Constant(0.9),
+      T.Float64Constant(V8_INFINITY),
+      T.Constant(0.99),
+      T.Constant(1.11),
+      T.ExternalConstant(ExternalReference::address_of_one_half())};
+
+  NodeVector nodes(T.main_zone());
+  T.GetCachedNodes(&nodes);
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    CHECK(Contains(&nodes, constants[i]));
+  }
+}
diff --git a/test/cctest/compiler/test-js-context-specialization.cc b/test/cctest/compiler/test-js-context-specialization.cc
index 47c660a..fb7bd94 100644
--- a/test/cctest/compiler/test-js-context-specialization.cc
+++ b/test/cctest/compiler/test-js-context-specialization.cc
@@ -7,7 +7,6 @@
 #include "src/compiler/node-matchers.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/compiler/source-position.h"
-#include "src/compiler/typer.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/function-tester.h"
 #include "test/cctest/compiler/graph-builder-tester.h"
@@ -22,10 +21,9 @@
       : DirectGraphBuilder(new (main_zone()) Graph(main_zone())),
         common_(main_zone()),
         javascript_(main_zone()),
-        machine_(),
+        machine_(main_zone()),
         simplified_(main_zone()),
-        typer_(main_zone()),
-        jsgraph_(graph(), common(), &javascript_, &typer_, &machine_),
+        jsgraph_(graph(), common(), &javascript_, &machine_),
         info_(main_isolate(), main_zone()) {}
 
   Factory* factory() { return main_isolate()->factory(); }
@@ -40,7 +38,6 @@
   JSOperatorBuilder javascript_;
   MachineOperatorBuilder machine_;
   SimplifiedOperatorBuilder simplified_;
-  Typer typer_;
   JSGraph jsgraph_;
   CompilationInfo info_;
 };
@@ -95,8 +92,8 @@
     HeapObjectMatcher<Context> match(new_context_input);
     CHECK_EQ(*native, *match.Value().handle());
     ContextAccess access = OpParameter<ContextAccess>(r.replacement());
-    CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, access.index());
-    CHECK_EQ(0, access.depth());
+    CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
+    CHECK_EQ(0, static_cast<int>(access.depth()));
     CHECK_EQ(false, access.immutable());
   }
 
@@ -175,8 +172,8 @@
     HeapObjectMatcher<Context> match(new_context_input);
     CHECK_EQ(*native, *match.Value().handle());
     ContextAccess access = OpParameter<ContextAccess>(r.replacement());
-    CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, access.index());
-    CHECK_EQ(0, access.depth());
+    CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index()));
+    CHECK_EQ(0, static_cast<int>(access.depth()));
     CHECK_EQ(false, access.immutable());
   }
 }
@@ -206,7 +203,7 @@
   JSContextSpecializer spec(t.info(), t.jsgraph(), const_context);
 
   {
-    // Check that SpecializeToContext() replaces values and forwards effects
+    // Check that specialization replaces values and forwards effects
     // correctly, and folds values from constant and non-constant contexts
     Node* effect_in = start;
     Node* load = t.NewNode(t.javascript()->LoadContext(0, slot, true),
@@ -232,8 +229,10 @@
     CheckEffectInput(effect_in, load);
     CheckEffectInput(load, effect_use);
 
-    // Perform the substitution on the entire graph.
-    spec.SpecializeToContext();
+    // Perform the reduction on the entire graph.
+    GraphReducer graph_reducer(t.graph(), t.main_zone());
+    graph_reducer.AddReducer(&spec);
+    graph_reducer.ReduceGraph();
 
     // Effects should have been forwarded (not replaced with a value).
     CheckEffectInput(effect_in, effect_use);
diff --git a/test/cctest/compiler/test-js-typed-lowering.cc b/test/cctest/compiler/test-js-typed-lowering.cc
index cf126c2..3023837 100644
--- a/test/cctest/compiler/test-js-typed-lowering.cc
+++ b/test/cctest/compiler/test-js-typed-lowering.cc
@@ -2,14 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
 #include "src/compiler/graph-inl.h"
+#include "src/compiler/js-graph.h"
 #include "src/compiler/js-typed-lowering.h"
+#include "src/compiler/machine-operator.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/compiler/opcodes.h"
 #include "src/compiler/typer.h"
+#include "test/cctest/cctest.h"
 
 using namespace v8::internal;
 using namespace v8::internal::compiler;
@@ -21,14 +21,15 @@
         binop(NULL),
         unop(NULL),
         javascript(main_zone()),
+        machine(main_zone()),
         simplified(main_zone()),
         common(main_zone()),
         graph(main_zone()),
-        typer(main_zone()),
+        typer(&graph, MaybeHandle<Context>()),
         context_node(NULL) {
-    typer.DecorateGraph(&graph);
-    Node* s = graph.NewNode(common.Start(num_parameters));
-    graph.SetStart(s);
+    graph.SetStart(graph.NewNode(common.Start(num_parameters)));
+    graph.SetEnd(graph.NewNode(common.End()));
+    typer.Run();
   }
 
   Isolate* isolate;
@@ -49,13 +50,14 @@
   }
 
   Node* UndefinedConstant() {
-    Unique<Object> unique =
-        Unique<Object>::CreateImmovable(isolate->factory()->undefined_value());
+    Unique<HeapObject> unique = Unique<HeapObject>::CreateImmovable(
+        isolate->factory()->undefined_value());
     return graph.NewNode(common.HeapConstant(unique));
   }
 
-  Node* HeapConstant(Handle<Object> constant) {
-    Unique<Object> unique = Unique<Object>::CreateUninitialized(constant);
+  Node* HeapConstant(Handle<HeapObject> constant) {
+    Unique<HeapObject> unique =
+        Unique<HeapObject>::CreateUninitialized(constant);
     return graph.NewNode(common.HeapConstant(unique));
   }
 
@@ -65,15 +67,16 @@
     Node* stack = graph.NewNode(common.StateValues(0));
 
     Node* state_node =
-        graph.NewNode(common.FrameState(JS_FRAME, BailoutId(0), kIgnoreOutput),
+        graph.NewNode(common.FrameState(JS_FRAME, BailoutId(0),
+                                        OutputFrameStateCombine::Ignore()),
                       parameters, locals, stack, context, UndefinedConstant());
 
     return state_node;
   }
 
   Node* reduce(Node* node) {
-    JSGraph jsgraph(&graph, &common, &javascript, &typer, &machine);
-    JSTypedLowering reducer(&jsgraph);
+    JSGraph jsgraph(&graph, &common, &javascript, &machine);
+    JSTypedLowering reducer(&jsgraph, main_zone());
     Reduction reduction = reducer.Reduce(node);
     if (reduction.Changed()) return reduction.replacement();
     return node;
@@ -164,17 +167,19 @@
 
 
 static Type* kInt32Types[] = {
-    Type::UnsignedSmall(),   Type::OtherSignedSmall(), Type::OtherUnsigned31(),
-    Type::OtherUnsigned32(), Type::OtherSigned32(),    Type::SignedSmall(),
-    Type::Signed32(),        Type::Unsigned32(),       Type::Integral32()};
+    Type::UnsignedSmall(),       Type::NegativeSigned32(),
+    Type::NonNegativeSigned32(), Type::SignedSmall(),
+    Type::Signed32(),            Type::Unsigned32(),
+    Type::Integral32()};
 
 
 static Type* kNumberTypes[] = {
-    Type::UnsignedSmall(),   Type::OtherSignedSmall(), Type::OtherUnsigned31(),
-    Type::OtherUnsigned32(), Type::OtherSigned32(),    Type::SignedSmall(),
-    Type::Signed32(),        Type::Unsigned32(),       Type::Integral32(),
-    Type::MinusZero(),       Type::NaN(),              Type::OtherNumber(),
-    Type::OrderedNumber(),   Type::Number()};
+    Type::UnsignedSmall(),       Type::NegativeSigned32(),
+    Type::NonNegativeSigned32(), Type::SignedSmall(),
+    Type::Signed32(),            Type::Unsigned32(),
+    Type::Integral32(),          Type::MinusZero(),
+    Type::NaN(),                 Type::OrderedNumber(),
+    Type::PlainNumber(),         Type::Number()};
 
 
 static Type* kJSTypes[] = {Type::Undefined(), Type::Null(),   Type::Boolean(),
@@ -260,16 +265,15 @@
 
 static void CheckToI32(Node* old_input, Node* new_input, bool is_signed) {
   Type* old_type = NodeProperties::GetBounds(old_input).upper;
+  Type* new_type = NodeProperties::GetBounds(new_input).upper;
   Type* expected_type = I32Type(is_signed);
+  CHECK(new_type->Is(expected_type));
   if (old_type->Is(expected_type)) {
     CHECK_EQ(old_input, new_input);
   } else if (new_input->opcode() == IrOpcode::kNumberConstant) {
-    CHECK(NodeProperties::GetBounds(new_input).upper->Is(expected_type));
     double v = OpParameter<double>(new_input);
     double e = static_cast<double>(is_signed ? FastD2I(v) : FastD2UI(v));
     CHECK_EQ(e, v);
-  } else {
-    CHECK_EQ(NumberToI32(is_signed), new_input->opcode());
   }
 }
 
@@ -302,12 +306,13 @@
 TEST(Int32BitwiseShifts) {
   JSBitwiseShiftTypedLoweringTester R;
 
-  Type* types[] = {
-      Type::SignedSmall(), Type::UnsignedSmall(), Type::OtherSigned32(),
-      Type::Unsigned32(),  Type::Signed32(),      Type::MinusZero(),
-      Type::NaN(),         Type::OtherNumber(),   Type::Undefined(),
-      Type::Null(),        Type::Boolean(),       Type::Number(),
-      Type::String(),      Type::Object()};
+  Type* types[] = {Type::SignedSmall(),      Type::UnsignedSmall(),
+                   Type::NegativeSigned32(), Type::NonNegativeSigned32(),
+                   Type::Unsigned32(),       Type::Signed32(),
+                   Type::MinusZero(),        Type::NaN(),
+                   Type::Undefined(),        Type::Null(),
+                   Type::Boolean(),          Type::Number(),
+                   Type::PlainNumber(),      Type::String()};
 
   for (size_t i = 0; i < arraysize(types); ++i) {
     Node* p0 = R.Parameter(types[i], 0);
@@ -325,9 +330,13 @@
 
         CheckToI32(p0, r0, R.signedness[k]);
 
-        R.CheckPureBinop(IrOpcode::kWord32And, r1);
-        CheckToI32(p1, r1->InputAt(0), R.signedness[k + 1]);
-        R.CheckInt32Constant(0x1F, r1->InputAt(1));
+        if (r1->opcode() == IrOpcode::kWord32And) {
+          R.CheckPureBinop(IrOpcode::kWord32And, r1);
+          CheckToI32(p1, r1->InputAt(0), R.signedness[k + 1]);
+          R.CheckInt32Constant(0x1F, r1->InputAt(1));
+        } else {
+          CheckToI32(p1, r1, R.signedness[k]);
+        }
       }
     }
   }
@@ -363,11 +372,11 @@
   JSBitwiseTypedLoweringTester R;
 
   Type* types[] = {
-      Type::SignedSmall(), Type::UnsignedSmall(), Type::OtherSigned32(),
-      Type::Unsigned32(),  Type::Signed32(),      Type::MinusZero(),
-      Type::NaN(),         Type::OtherNumber(),   Type::Undefined(),
-      Type::Null(),        Type::Boolean(),       Type::Number(),
-      Type::String(),      Type::Object()};
+      Type::SignedSmall(),   Type::UnsignedSmall(), Type::Unsigned32(),
+      Type::Signed32(),      Type::MinusZero(),     Type::NaN(),
+      Type::OrderedNumber(), Type::PlainNumber(),   Type::Undefined(),
+      Type::Null(),          Type::Boolean(),       Type::Number(),
+      Type::String()};
 
   for (size_t i = 0; i < arraysize(types); ++i) {
     Node* p0 = R.Parameter(types[i], 0);
@@ -498,20 +507,6 @@
     CHECK_EQ(IrOpcode::kParameter, r->opcode());
   }
 
-  {  // ToBoolean(ordered-number)
-    Node* r = R.ReduceUnop(op, Type::OrderedNumber());
-    CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
-    Node* i = r->InputAt(0);
-    CHECK_EQ(IrOpcode::kNumberEqual, i->opcode());
-    // ToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x, #0))
-  }
-
-  {  // ToBoolean(string)
-    Node* r = R.ReduceUnop(op, Type::String());
-    // TODO(titzer): test will break with better js-typed-lowering
-    CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
-  }
-
   {  // ToBoolean(object)
     Node* r = R.ReduceUnop(op, Type::DetectableObject());
     R.CheckTrue(r);
@@ -524,39 +519,7 @@
 
   {  // ToBoolean(object)
     Node* r = R.ReduceUnop(op, Type::Object());
-    CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
-  }
-}
-
-
-TEST(JSToBoolean_replacement) {
-  JSTypedLoweringTester R;
-
-  Type* types[] = {Type::Null(),             Type::Undefined(),
-                   Type::Boolean(),          Type::OrderedNumber(),
-                   Type::DetectableObject(), Type::Undetectable()};
-
-  for (size_t i = 0; i < arraysize(types); i++) {
-    Node* n = R.Parameter(types[i]);
-    Node* c = R.graph.NewNode(R.javascript.ToBoolean(), n, R.context(),
-                              R.start(), R.start());
-    Node* effect_use = R.UseForEffect(c);
-    Node* add = R.graph.NewNode(R.simplified.ReferenceEqual(Type::Any()), n, c);
-
-    R.CheckEffectInput(c, effect_use);
-    Node* r = R.reduce(c);
-
-    if (types[i]->Is(Type::Boolean())) {
-      CHECK_EQ(n, r);
-    } else if (types[i]->Is(Type::OrderedNumber())) {
-      CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
-    } else {
-      CHECK_EQ(IrOpcode::kHeapConstant, r->opcode());
-    }
-
-    CHECK_EQ(n, add->InputAt(0));
-    CHECK_EQ(r, add->InputAt(1));
-    R.CheckEffectInput(R.start(), effect_use);
+    CHECK_EQ(IrOpcode::kAnyToBoolean, r->opcode());
   }
 }
 
@@ -690,33 +653,22 @@
       R.javascript.GreaterThan(),        R.simplified.NumberLessThan(),
       R.javascript.GreaterThanOrEqual(), R.simplified.NumberLessThanOrEqual()};
 
-  for (size_t i = 0; i < arraysize(kJSTypes); i++) {
-    Type* t0 = kJSTypes[i];
-    // Skip Type::String and Type::Receiver which might coerce into a string.
-    if (t0->Is(Type::String()) || t0->Is(Type::Receiver())) continue;
-    Node* p0 = R.Parameter(t0, 0);
+  Node* const p0 = R.Parameter(Type::Number(), 0);
+  Node* const p1 = R.Parameter(Type::Number(), 1);
 
-    for (size_t j = 0; j < arraysize(kJSTypes); j++) {
-      Type* t1 = kJSTypes[j];
-      // Skip Type::String and Type::Receiver which might coerce into a string.
-      if (t1->Is(Type::String()) || t0->Is(Type::Receiver())) continue;
-      Node* p1 = R.Parameter(t1, 1);
+  for (size_t k = 0; k < arraysize(ops); k += 2) {
+    Node* cmp = R.Binop(ops[k], p0, p1);
+    Node* r = R.reduce(cmp);
 
-      for (size_t k = 0; k < arraysize(ops); k += 2) {
-        Node* cmp = R.Binop(ops[k], p0, p1);
-        Node* r = R.reduce(cmp);
-
-        R.CheckPureBinop(ops[k + 1], r);
-        if (k >= 4) {
-          // GreaterThan and GreaterThanOrEqual commute the inputs
-          // and use the LessThan and LessThanOrEqual operators.
-          CheckIsConvertedToNumber(p1, r->InputAt(0));
-          CheckIsConvertedToNumber(p0, r->InputAt(1));
-        } else {
-          CheckIsConvertedToNumber(p0, r->InputAt(0));
-          CheckIsConvertedToNumber(p1, r->InputAt(1));
-        }
-      }
+    R.CheckPureBinop(ops[k + 1], r);
+    if (k >= 4) {
+      // GreaterThan and GreaterThanOrEqual commute the inputs
+      // and use the LessThan and LessThanOrEqual operators.
+      CheckIsConvertedToNumber(p1, r->InputAt(0));
+      CheckIsConvertedToNumber(p0, r->InputAt(1));
+    } else {
+      CheckIsConvertedToNumber(p0, r->InputAt(0));
+      CheckIsConvertedToNumber(p1, r->InputAt(1));
     }
   }
 }
@@ -753,51 +705,18 @@
 }
 
 
-TEST(ObjectComparison) {
-  JSTypedLoweringTester R;
-
-  Node* p0 = R.Parameter(Type::Number(), 0);
-  Node* p1 = R.Parameter(Type::Object(), 1);
-
-  Node* cmp = R.Binop(R.javascript.LessThan(), p0, p1);
-  Node* effect_use = R.UseForEffect(cmp);
-
-  R.CheckEffectInput(R.start(), cmp);
-  R.CheckEffectInput(cmp, effect_use);
-
-  Node* r = R.reduce(cmp);
-
-  R.CheckPureBinop(R.simplified.NumberLessThan(), r);
-
-  Node* i0 = r->InputAt(0);
-  Node* i1 = r->InputAt(1);
-
-  CHECK_EQ(p0, i0);
-  CHECK_NE(p1, i1);
-  CHECK_EQ(IrOpcode::kParameter, i0->opcode());
-  CHECK_EQ(IrOpcode::kJSToNumber, i1->opcode());
-
-  // Check effect chain is correct.
-  R.CheckEffectInput(R.start(), i1);
-  R.CheckEffectInput(i1, effect_use);
-}
-
-
 TEST(UnaryNot) {
   JSTypedLoweringTester R;
   const Operator* opnot = R.javascript.UnaryNot();
 
   for (size_t i = 0; i < arraysize(kJSTypes); i++) {
     Node* orig = R.Unop(opnot, R.Parameter(kJSTypes[i]));
-    Node* use = R.graph.NewNode(R.common.Return(), orig);
     Node* r = R.reduce(orig);
-    // TODO(titzer): test will break if/when js-typed-lowering constant folds.
-    CHECK_EQ(IrOpcode::kBooleanNot, use->InputAt(0)->opcode());
 
     if (r == orig && orig->opcode() == IrOpcode::kJSToBoolean) {
       // The original node was turned into a ToBoolean.
       CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
-    } else {
+    } else if (r->opcode() != IrOpcode::kHeapConstant) {
       CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
     }
   }
@@ -852,7 +771,7 @@
     if (effect_use != NULL) {
       R.CheckEffectInput(R.start(), effect_use);
       // Check that value uses of ToNumber() do not go to start().
-      for (int i = 0; i < effect_use->op()->InputCount(); i++) {
+      for (int i = 0; i < effect_use->op()->ValueInputCount(); i++) {
         CHECK_NE(R.start(), effect_use->InputAt(i));
       }
     }
@@ -904,9 +823,9 @@
   Node* CheckConverted(IrOpcode::Value opcode, Node* node, bool effects) {
     CHECK_EQ(opcode, node->opcode());
     if (effects) {
-      CHECK_LT(0, OperatorProperties::GetEffectInputCount(node->op()));
+      CHECK_LT(0, node->op()->EffectInputCount());
     } else {
-      CHECK_EQ(0, OperatorProperties::GetEffectInputCount(node->op()));
+      CHECK_EQ(0, node->op()->EffectInputCount());
     }
     return node;
   }
@@ -1030,7 +949,7 @@
   };
 
   for (size_t j = 0; j < arraysize(ops); j += 2) {
-    BinopEffectsTester B(ops[j], Type::Object(), Type::String());
+    BinopEffectsTester B(ops[j], Type::Symbol(), Type::Symbol());
     CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());
 
     Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
@@ -1103,8 +1022,8 @@
     CHECK_EQ(B.p1, i0->InputAt(0));
     CHECK_EQ(B.p0, i1->InputAt(0));
 
-    // But effects should be ordered start -> i1 -> i0 -> effect_use
-    B.CheckEffectOrdering(i1, i0);
+    // But effects should be ordered start -> i1 -> effect_use
+    B.CheckEffectOrdering(i1);
   }
 
   for (size_t j = 0; j < arraysize(ops); j += 2) {
@@ -1166,7 +1085,7 @@
 
   for (int j = 0; j < R.kNumberOps; j += 2) {
     bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
-    BinopEffectsTester B(R.ops[j], Type::Number(), Type::Object());
+    BinopEffectsTester B(R.ops[j], Type::Number(), Type::Primitive());
 
     B.R.CheckPureBinop(B.result->opcode(), B.result);
 
@@ -1183,7 +1102,7 @@
 
   for (int j = 0; j < R.kNumberOps; j += 2) {
     bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
-    BinopEffectsTester B(R.ops[j], Type::Object(), Type::Number());
+    BinopEffectsTester B(R.ops[j], Type::Primitive(), Type::Number());
 
     B.R.CheckPureBinop(B.result->opcode(), B.result);
 
@@ -1200,7 +1119,7 @@
 
   for (int j = 0; j < R.kNumberOps; j += 2) {
     bool signed_left = R.signedness[j], signed_right = R.signedness[j + 1];
-    BinopEffectsTester B(R.ops[j], Type::Object(), Type::Object());
+    BinopEffectsTester B(R.ops[j], Type::Primitive(), Type::Primitive());
 
     B.R.CheckPureBinop(B.result->opcode(), B.result);
 
@@ -1218,33 +1137,6 @@
 }
 
 
-TEST(UnaryNotEffects) {
-  JSTypedLoweringTester R;
-  const Operator* opnot = R.javascript.UnaryNot();
-
-  for (size_t i = 0; i < arraysize(kJSTypes); i++) {
-    Node* p0 = R.Parameter(kJSTypes[i], 0);
-    Node* orig = R.Unop(opnot, p0);
-    Node* effect_use = R.UseForEffect(orig);
-    Node* value_use = R.graph.NewNode(R.common.Return(), orig);
-    Node* r = R.reduce(orig);
-    // TODO(titzer): test will break if/when js-typed-lowering constant folds.
-    CHECK_EQ(IrOpcode::kBooleanNot, value_use->InputAt(0)->opcode());
-
-    if (r == orig && orig->opcode() == IrOpcode::kJSToBoolean) {
-      // The original node was turned into a ToBoolean, which has an effect.
-      CHECK_EQ(IrOpcode::kJSToBoolean, r->opcode());
-      R.CheckEffectInput(R.start(), orig);
-      R.CheckEffectInput(orig, effect_use);
-    } else {
-      // effect should have been removed from this node.
-      CHECK_EQ(IrOpcode::kBooleanNot, r->opcode());
-      R.CheckEffectInput(R.start(), effect_use);
-    }
-  }
-}
-
-
 TEST(Int32AddNarrowing) {
   {
     JSBitwiseTypedLoweringTester R;
@@ -1263,11 +1155,7 @@
             Node* r = R.reduce(or_node);
 
             CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode());
-            CHECK_EQ(IrOpcode::kInt32Add, add_node->opcode());
-            bool is_signed = l ? R.signedness[o] : R.signedness[o + 1];
-
-            Type* add_type = NodeProperties::GetBounds(add_node).upper;
-            CHECK(add_type->Is(I32Type(is_signed)));
+            CHECK_EQ(IrOpcode::kNumberAdd, add_node->opcode());
           }
         }
       }
@@ -1290,40 +1178,33 @@
             Node* r = R.reduce(or_node);
 
             CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode());
-            CHECK_EQ(IrOpcode::kInt32Add, add_node->opcode());
-            bool is_signed = l ? R.signedness[o] : R.signedness[o + 1];
-
-            Type* add_type = NodeProperties::GetBounds(add_node).upper;
-            CHECK(add_type->Is(I32Type(is_signed)));
+            CHECK_EQ(IrOpcode::kNumberAdd, add_node->opcode());
           }
         }
       }
     }
   }
-}
+  {
+    JSBitwiseTypedLoweringTester R;
 
+    for (int o = 0; o < R.kNumberOps; o += 2) {
+      Node* n0 = R.Parameter(I32Type(R.signedness[o]));
+      Node* n1 = R.Parameter(I32Type(R.signedness[o + 1]));
+      Node* one = R.graph.NewNode(R.common.NumberConstant(1));
 
-TEST(Int32AddNarrowingNotOwned) {
-  JSBitwiseTypedLoweringTester R;
-
-  for (int o = 0; o < R.kNumberOps; o += 2) {
-    Node* n0 = R.Parameter(I32Type(R.signedness[o]));
-    Node* n1 = R.Parameter(I32Type(R.signedness[o + 1]));
-    Node* one = R.graph.NewNode(R.common.NumberConstant(1));
-
-    Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1);
-    Node* or_node = R.Binop(R.ops[o], add_node, one);
-    Node* other_use = R.Binop(R.simplified.NumberAdd(), add_node, one);
-    Node* r = R.reduce(or_node);
-    CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode());
-    // Should not be reduced to Int32Add because of the other number add.
-    CHECK_EQ(IrOpcode::kNumberAdd, add_node->opcode());
-    // Conversion to int32 should be done.
-    CheckToI32(add_node, r->InputAt(0), R.signedness[o]);
-    CheckToI32(one, r->InputAt(1), R.signedness[o + 1]);
-    // The other use should also not be touched.
-    CHECK_EQ(add_node, other_use->InputAt(0));
-    CHECK_EQ(one, other_use->InputAt(1));
+      Node* add_node = R.Binop(R.simplified.NumberAdd(), n0, n1);
+      Node* or_node = R.Binop(R.ops[o], add_node, one);
+      Node* other_use = R.Binop(R.simplified.NumberAdd(), add_node, one);
+      Node* r = R.reduce(or_node);
+      CHECK_EQ(R.ops[o + 1]->opcode(), r->op()->opcode());
+      CHECK_EQ(IrOpcode::kNumberAdd, add_node->opcode());
+      // Conversion to int32 should be done.
+      CheckToI32(add_node, r->InputAt(0), R.signedness[o]);
+      CheckToI32(one, r->InputAt(1), R.signedness[o + 1]);
+      // The other use should also not be touched.
+      CHECK_EQ(add_node, other_use->InputAt(0));
+      CHECK_EQ(one, other_use->InputAt(1));
+    }
   }
 }
 
diff --git a/test/cctest/compiler/test-jump-threading.cc b/test/cctest/compiler/test-jump-threading.cc
new file mode 100644
index 0000000..74bf43d
--- /dev/null
+++ b/test/cctest/compiler/test-jump-threading.cc
@@ -0,0 +1,764 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/compiler/instruction.h"
+#include "src/compiler/instruction-codes.h"
+#include "src/compiler/jump-threading.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+typedef BasicBlock::RpoNumber RpoNumber;
+
+class TestCode : public HandleAndZoneScope {
+ public:
+  TestCode()
+      : HandleAndZoneScope(),
+        blocks_(main_zone()),
+        sequence_(main_zone(), &blocks_),
+        rpo_number_(RpoNumber::FromInt(0)),
+        current_(NULL) {}
+
+  ZoneVector<InstructionBlock*> blocks_;
+  InstructionSequence sequence_;
+  RpoNumber rpo_number_;
+  InstructionBlock* current_;
+
+  int Jump(int target) {
+    Start();
+    InstructionOperand* ops[] = {UseRpo(target)};
+    sequence_.AddInstruction(Instruction::New(main_zone(), kArchJmp, 0, NULL, 1,
+                                              ops, 0, NULL)->MarkAsControl());
+    int pos = static_cast<int>(sequence_.instructions().size() - 1);
+    End();
+    return pos;
+  }
+  void Fallthru() {
+    Start();
+    End();
+  }
+  int Branch(int ttarget, int ftarget) {
+    Start();
+    InstructionOperand* ops[] = {UseRpo(ttarget), UseRpo(ftarget)};
+    InstructionCode code = 119 | FlagsModeField::encode(kFlags_branch) |
+                           FlagsConditionField::encode(kEqual);
+    sequence_.AddInstruction(Instruction::New(main_zone(), code, 0, NULL, 2,
+                                              ops, 0, NULL)->MarkAsControl());
+    int pos = static_cast<int>(sequence_.instructions().size() - 1);
+    End();
+    return pos;
+  }
+  void Nop() {
+    Start();
+    sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop));
+  }
+  void RedundantMoves() {
+    Start();
+    sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop));
+    int index = static_cast<int>(sequence_.instructions().size()) - 1;
+    sequence_.AddGapMove(index, RegisterOperand::Create(13, main_zone()),
+                         RegisterOperand::Create(13, main_zone()));
+  }
+  void NonRedundantMoves() {
+    Start();
+    sequence_.AddInstruction(Instruction::New(main_zone(), kArchNop));
+    int index = static_cast<int>(sequence_.instructions().size()) - 1;
+    sequence_.AddGapMove(index, ImmediateOperand::Create(11, main_zone()),
+                         RegisterOperand::Create(11, main_zone()));
+  }
+  void Other() {
+    Start();
+    sequence_.AddInstruction(Instruction::New(main_zone(), 155));
+  }
+  void End() {
+    Start();
+    sequence_.EndBlock(current_->rpo_number());
+    current_ = NULL;
+    rpo_number_ = RpoNumber::FromInt(rpo_number_.ToInt() + 1);
+  }
+  InstructionOperand* UseRpo(int num) {
+    int index = sequence_.AddImmediate(Constant(RpoNumber::FromInt(num)));
+    return ImmediateOperand::Create(index, main_zone());
+  }
+  void Start(bool deferred = false) {
+    if (current_ == NULL) {
+      current_ = new (main_zone()) InstructionBlock(
+          main_zone(), BasicBlock::Id::FromInt(rpo_number_.ToInt()),
+          rpo_number_, RpoNumber::Invalid(), RpoNumber::Invalid(), deferred);
+      blocks_.push_back(current_);
+      sequence_.StartBlock(rpo_number_);
+    }
+  }
+  void Defer() {
+    CHECK(current_ == NULL);
+    Start(true);
+  }
+};
+
+
+void VerifyForwarding(TestCode& code, int count, int* expected) {
+  Zone local_zone(code.main_isolate());
+  ZoneVector<RpoNumber> result(&local_zone);
+  JumpThreading::ComputeForwarding(&local_zone, result, &code.sequence_);
+
+  CHECK(count == static_cast<int>(result.size()));
+  for (int i = 0; i < count; i++) {
+    CHECK(expected[i] == result[i].ToInt());
+  }
+}
+
+
+TEST(FwEmpty1) {
+  TestCode code;
+
+  // B0
+  code.Jump(1);
+  // B1
+  code.Jump(2);
+  // B2
+  code.End();
+
+  static int expected[] = {2, 2, 2};
+  VerifyForwarding(code, 3, expected);
+}
+
+
+TEST(FwEmptyN) {
+  for (int i = 0; i < 9; i++) {
+    TestCode code;
+
+    // B0
+    code.Jump(1);
+    // B1
+    for (int j = 0; j < i; j++) code.Nop();
+    code.Jump(2);
+    // B2
+    code.End();
+
+    static int expected[] = {2, 2, 2};
+    VerifyForwarding(code, 3, expected);
+  }
+}
+
+
+TEST(FwNone1) {
+  TestCode code;
+
+  // B0
+  code.End();
+
+  static int expected[] = {0};
+  VerifyForwarding(code, 1, expected);
+}
+
+
+TEST(FwMoves1) {
+  TestCode code;
+
+  // B0
+  code.RedundantMoves();
+  code.End();
+
+  static int expected[] = {0};
+  VerifyForwarding(code, 1, expected);
+}
+
+
+TEST(FwMoves2) {
+  TestCode code;
+
+  // B0
+  code.RedundantMoves();
+  code.Fallthru();
+  // B1
+  code.End();
+
+  static int expected[] = {1, 1};
+  VerifyForwarding(code, 2, expected);
+}
+
+
+TEST(FwMoves2b) {
+  TestCode code;
+
+  // B0
+  code.NonRedundantMoves();
+  code.Fallthru();
+  // B1
+  code.End();
+
+  static int expected[] = {0, 1};
+  VerifyForwarding(code, 2, expected);
+}
+
+
+TEST(FwOther2) {
+  TestCode code;
+
+  // B0
+  code.Other();
+  code.Fallthru();
+  // B1
+  code.End();
+
+  static int expected[] = {0, 1};
+  VerifyForwarding(code, 2, expected);
+}
+
+
+TEST(FwNone2a) {
+  TestCode code;
+
+  // B0
+  code.Fallthru();
+  // B1
+  code.End();
+
+  static int expected[] = {1, 1};
+  VerifyForwarding(code, 2, expected);
+}
+
+
+TEST(FwNone2b) {
+  TestCode code;
+
+  // B0
+  code.Jump(1);
+  // B1
+  code.End();
+
+  static int expected[] = {1, 1};
+  VerifyForwarding(code, 2, expected);
+}
+
+
+TEST(FwLoop1) {
+  TestCode code;
+
+  // B0
+  code.Jump(0);
+
+  static int expected[] = {0};
+  VerifyForwarding(code, 1, expected);
+}
+
+
+TEST(FwLoop2) {
+  TestCode code;
+
+  // B0
+  code.Fallthru();
+  // B1
+  code.Jump(0);
+
+  static int expected[] = {0, 0};
+  VerifyForwarding(code, 2, expected);
+}
+
+
+TEST(FwLoop3) {
+  TestCode code;
+
+  // B0
+  code.Fallthru();
+  // B1
+  code.Fallthru();
+  // B2
+  code.Jump(0);
+
+  static int expected[] = {0, 0, 0};
+  VerifyForwarding(code, 3, expected);
+}
+
+
+TEST(FwLoop1b) {
+  TestCode code;
+
+  // B0
+  code.Fallthru();
+  // B1
+  code.Jump(1);
+
+  static int expected[] = {1, 1};
+  VerifyForwarding(code, 2, expected);
+}
+
+
+TEST(FwLoop2b) {
+  TestCode code;
+
+  // B0
+  code.Fallthru();
+  // B1
+  code.Fallthru();
+  // B2
+  code.Jump(1);
+
+  static int expected[] = {1, 1, 1};
+  VerifyForwarding(code, 3, expected);
+}
+
+
+TEST(FwLoop3b) {
+  TestCode code;
+
+  // B0
+  code.Fallthru();
+  // B1
+  code.Fallthru();
+  // B2
+  code.Fallthru();
+  // B3
+  code.Jump(1);
+
+  static int expected[] = {1, 1, 1, 1};
+  VerifyForwarding(code, 4, expected);
+}
+
+
+TEST(FwLoop2_1a) {
+  TestCode code;
+
+  // B0
+  code.Fallthru();
+  // B1
+  code.Fallthru();
+  // B2
+  code.Fallthru();
+  // B3
+  code.Jump(1);
+  // B4
+  code.Jump(2);
+
+  static int expected[] = {1, 1, 1, 1, 1};
+  VerifyForwarding(code, 5, expected);
+}
+
+
+TEST(FwLoop2_1b) {
+  TestCode code;
+
+  // B0
+  code.Fallthru();
+  // B1
+  code.Fallthru();
+  // B2
+  code.Jump(4);
+  // B3
+  code.Jump(1);
+  // B4
+  code.Jump(2);
+
+  static int expected[] = {2, 2, 2, 2, 2};
+  VerifyForwarding(code, 5, expected);
+}
+
+
+TEST(FwLoop2_1c) {
+  TestCode code;
+
+  // B0
+  code.Fallthru();
+  // B1
+  code.Fallthru();
+  // B2
+  code.Jump(4);
+  // B3
+  code.Jump(2);
+  // B4
+  code.Jump(1);
+
+  static int expected[] = {1, 1, 1, 1, 1};
+  VerifyForwarding(code, 5, expected);
+}
+
+
+TEST(FwLoop2_1d) {
+  TestCode code;
+
+  // B0
+  code.Fallthru();
+  // B1
+  code.Fallthru();
+  // B2
+  code.Jump(1);
+  // B3
+  code.Jump(1);
+  // B4
+  code.Jump(1);
+
+  static int expected[] = {1, 1, 1, 1, 1};
+  VerifyForwarding(code, 5, expected);
+}
+
+
+TEST(FwLoop3_1a) {
+  TestCode code;
+
+  // B0
+  code.Fallthru();
+  // B1
+  code.Fallthru();
+  // B2
+  code.Fallthru();
+  // B3
+  code.Jump(2);
+  // B4
+  code.Jump(1);
+  // B5
+  code.Jump(0);
+
+  static int expected[] = {2, 2, 2, 2, 2, 2};
+  VerifyForwarding(code, 6, expected);
+}
+
+
+TEST(FwDiamonds) {
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      TestCode code;
+      // B0
+      code.Branch(1, 2);
+      // B1
+      if (i) code.Other();
+      code.Jump(3);
+      // B2
+      if (j) code.Other();
+      code.Jump(3);
+      // B3
+      code.End();
+
+      int expected[] = {0, i ? 1 : 3, j ? 2 : 3, 3};
+      VerifyForwarding(code, 4, expected);
+    }
+  }
+}
+
+
+TEST(FwDiamonds2) {
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int k = 0; k < 2; k++) {
+        TestCode code;
+        // B0
+        code.Branch(1, 2);
+        // B1
+        if (i) code.Other();
+        code.Jump(3);
+        // B2
+        if (j) code.Other();
+        code.Jump(3);
+        // B3
+        if (k) code.NonRedundantMoves();
+        code.Jump(4);
+        // B4
+        code.End();
+
+        int merge = k ? 3 : 4;
+        int expected[] = {0, i ? 1 : merge, j ? 2 : merge, merge, 4};
+        VerifyForwarding(code, 5, expected);
+      }
+    }
+  }
+}
+
+
+TEST(FwDoubleDiamonds) {
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      for (int x = 0; x < 2; x++) {
+        for (int y = 0; y < 2; y++) {
+          TestCode code;
+          // B0
+          code.Branch(1, 2);
+          // B1
+          if (i) code.Other();
+          code.Jump(3);
+          // B2
+          if (j) code.Other();
+          code.Jump(3);
+          // B3
+          code.Branch(4, 5);
+          // B4
+          if (x) code.Other();
+          code.Jump(6);
+          // B5
+          if (y) code.Other();
+          code.Jump(6);
+          // B6
+          code.End();
+
+          int expected[] = {0,         i ? 1 : 3, j ? 2 : 3, 3,
+                            x ? 4 : 6, y ? 5 : 6, 6};
+          VerifyForwarding(code, 7, expected);
+        }
+      }
+    }
+  }
+}
+
+template <int kSize>
+void RunPermutationsRecursive(int outer[kSize], int start,
+                              void (*run)(int*, int)) {
+  int permutation[kSize];
+
+  for (int i = 0; i < kSize; i++) permutation[i] = outer[i];
+
+  int count = kSize - start;
+  if (count == 0) return run(permutation, kSize);
+  for (int i = start; i < kSize; i++) {
+    permutation[start] = outer[i];
+    permutation[i] = outer[start];
+    RunPermutationsRecursive<kSize>(permutation, start + 1, run);
+    permutation[i] = outer[i];
+    permutation[start] = outer[start];
+  }
+}
+
+
+template <int kSize>
+void RunAllPermutations(void (*run)(int*, int)) {
+  int permutation[kSize];
+  for (int i = 0; i < kSize; i++) permutation[i] = i;
+  RunPermutationsRecursive<kSize>(permutation, 0, run);
+}
+
+
+void PrintPermutation(int* permutation, int size) {
+  printf("{ ");
+  for (int i = 0; i < size; i++) {
+    if (i > 0) printf(", ");
+    printf("%d", permutation[i]);
+  }
+  printf(" }\n");
+}
+
+
+int find(int x, int* permutation, int size) {
+  for (int i = 0; i < size; i++) {
+    if (permutation[i] == x) return i;
+  }
+  return size;
+}
+
+
+void RunPermutedChain(int* permutation, int size) {
+  TestCode code;
+  int cur = -1;
+  for (int i = 0; i < size; i++) {
+    code.Jump(find(cur + 1, permutation, size) + 1);
+    cur = permutation[i];
+  }
+  code.Jump(find(cur + 1, permutation, size) + 1);
+  code.End();
+
+  int expected[] = {size + 1, size + 1, size + 1, size + 1,
+                    size + 1, size + 1, size + 1};
+  VerifyForwarding(code, size + 2, expected);
+}
+
+
+TEST(FwPermuted_chain) {
+  RunAllPermutations<3>(RunPermutedChain);
+  RunAllPermutations<4>(RunPermutedChain);
+  RunAllPermutations<5>(RunPermutedChain);
+}
+
+
+void RunPermutedDiamond(int* permutation, int size) {
+  TestCode code;
+  int br = 1 + find(0, permutation, size);
+  code.Jump(br);
+  for (int i = 0; i < size; i++) {
+    switch (permutation[i]) {
+      case 0:
+        code.Branch(1 + find(1, permutation, size),
+                    1 + find(2, permutation, size));
+        break;
+      case 1:
+        code.Jump(1 + find(3, permutation, size));
+        break;
+      case 2:
+        code.Jump(1 + find(3, permutation, size));
+        break;
+      case 3:
+        code.Jump(5);
+        break;
+    }
+  }
+  code.End();
+
+  int expected[] = {br, 5, 5, 5, 5, 5};
+  expected[br] = br;
+  VerifyForwarding(code, 6, expected);
+}
+
+
+TEST(FwPermuted_diamond) { RunAllPermutations<4>(RunPermutedDiamond); }
+
+
+void ApplyForwarding(TestCode& code, int size, int* forward) {
+  ZoneVector<RpoNumber> vector(code.main_zone());
+  for (int i = 0; i < size; i++) {
+    vector.push_back(RpoNumber::FromInt(forward[i]));
+  }
+  JumpThreading::ApplyForwarding(vector, &code.sequence_);
+}
+
+
+void CheckJump(TestCode& code, int pos, int target) {
+  Instruction* instr = code.sequence_.InstructionAt(pos);
+  CHECK_EQ(kArchJmp, instr->arch_opcode());
+  CHECK_EQ(1, static_cast<int>(instr->InputCount()));
+  CHECK_EQ(0, static_cast<int>(instr->OutputCount()));
+  CHECK_EQ(0, static_cast<int>(instr->TempCount()));
+  CHECK_EQ(target, code.sequence_.InputRpo(instr, 0).ToInt());
+}
+
+
+void CheckNop(TestCode& code, int pos) {
+  Instruction* instr = code.sequence_.InstructionAt(pos);
+  CHECK_EQ(kArchNop, instr->arch_opcode());
+  CHECK_EQ(0, static_cast<int>(instr->InputCount()));
+  CHECK_EQ(0, static_cast<int>(instr->OutputCount()));
+  CHECK_EQ(0, static_cast<int>(instr->TempCount()));
+}
+
+
+void CheckBranch(TestCode& code, int pos, int t1, int t2) {
+  Instruction* instr = code.sequence_.InstructionAt(pos);
+  CHECK_EQ(2, static_cast<int>(instr->InputCount()));
+  CHECK_EQ(0, static_cast<int>(instr->OutputCount()));
+  CHECK_EQ(0, static_cast<int>(instr->TempCount()));
+  CHECK_EQ(t1, code.sequence_.InputRpo(instr, 0).ToInt());
+  CHECK_EQ(t2, code.sequence_.InputRpo(instr, 1).ToInt());
+}
+
+
+void CheckAssemblyOrder(TestCode& code, int size, int* expected) {
+  int i = 0;
+  for (auto const block : code.sequence_.instruction_blocks()) {
+    CHECK_EQ(expected[i++], block->ao_number().ToInt());
+  }
+}
+
+
+TEST(Rewire1) {
+  TestCode code;
+
+  // B0
+  int j1 = code.Jump(1);
+  // B1
+  int j2 = code.Jump(2);
+  // B2
+  code.End();
+
+  static int forward[] = {2, 2, 2};
+  ApplyForwarding(code, 3, forward);
+  CheckJump(code, j1, 2);
+  CheckNop(code, j2);
+
+  static int assembly[] = {0, 1, 1};
+  CheckAssemblyOrder(code, 3, assembly);
+}
+
+
+TEST(Rewire1_deferred) {
+  TestCode code;
+
+  // B0
+  int j1 = code.Jump(1);
+  // B1
+  int j2 = code.Jump(2);
+  // B2
+  code.Defer();
+  int j3 = code.Jump(3);
+  // B3
+  code.End();
+
+  static int forward[] = {3, 3, 3, 3};
+  ApplyForwarding(code, 4, forward);
+  CheckJump(code, j1, 3);
+  CheckNop(code, j2);
+  CheckNop(code, j3);
+
+  static int assembly[] = {0, 1, 2, 1};
+  CheckAssemblyOrder(code, 4, assembly);
+}
+
+
+TEST(Rewire2_deferred) {
+  TestCode code;
+
+  // B0
+  code.Other();
+  int j1 = code.Jump(1);
+  // B1
+  code.Defer();
+  code.Fallthru();
+  // B2
+  code.Defer();
+  int j2 = code.Jump(3);
+  // B3
+  code.End();
+
+  static int forward[] = {0, 1, 2, 3};
+  ApplyForwarding(code, 4, forward);
+  CheckJump(code, j1, 1);
+  CheckJump(code, j2, 3);
+
+  static int assembly[] = {0, 2, 3, 1};
+  CheckAssemblyOrder(code, 4, assembly);
+}
+
+
+TEST(Rewire_diamond) {
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 2; j++) {
+      TestCode code;
+      // B0
+      int j1 = code.Jump(1);
+      // B1
+      int b1 = code.Branch(2, 3);
+      // B2
+      int j2 = code.Jump(4);
+      // B3
+      int j3 = code.Jump(4);
+      // B5
+      code.End();
+
+      int forward[] = {0, 1, i ? 4 : 2, j ? 4 : 3, 4};
+      ApplyForwarding(code, 5, forward);
+      CheckJump(code, j1, 1);
+      CheckBranch(code, b1, i ? 4 : 2, j ? 4 : 3);
+      if (i) {
+        CheckNop(code, j2);
+      } else {
+        CheckJump(code, j2, 4);
+      }
+      if (j) {
+        CheckNop(code, j3);
+      } else {
+        CheckJump(code, j3, 4);
+      }
+
+      int assembly[] = {0, 1, 2, 3, 4};
+      if (i) {
+        for (int k = 3; k < 5; k++) assembly[k]--;
+      }
+      if (j) {
+        for (int k = 4; k < 5; k++) assembly[k]--;
+      }
+      CheckAssemblyOrder(code, 5, assembly);
+    }
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/cctest/compiler/test-linkage.cc b/test/cctest/compiler/test-linkage.cc
index ff65d6e..117caf2 100644
--- a/test/cctest/compiler/test-linkage.cc
+++ b/test/cctest/compiler/test-linkage.cc
@@ -8,7 +8,6 @@
 #include "src/zone.h"
 
 #include "src/compiler/common-operator.h"
-#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/linkage.h"
 #include "src/compiler/machine-operator.h"
@@ -23,8 +22,8 @@
 using namespace v8::internal;
 using namespace v8::internal::compiler;
 
-static SimpleOperator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
-                                     0, 0, "dummy");
+static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
+                               "dummy", 0, 0, 0, 0, 0, 0);
 
 // So we can get a real JS function.
 static Handle<JSFunction> Compile(const char* source) {
@@ -45,7 +44,7 @@
   InitializedHandleScope handles;
   Handle<JSFunction> function = Compile("a + b");
   CompilationInfoWithZone info(function);
-  Linkage linkage(&info);
+  Linkage linkage(info.zone(), &info);
 }
 
 
@@ -60,13 +59,13 @@
     Handle<JSFunction> function = v8::Utils::OpenHandle(
         *v8::Handle<v8::Function>::Cast(CompileRun(sources[i])));
     CompilationInfoWithZone info(function);
-    Linkage linkage(&info);
+    Linkage linkage(info.zone(), &info);
 
     CallDescriptor* descriptor = linkage.GetIncomingDescriptor();
     CHECK_NE(NULL, descriptor);
 
-    CHECK_EQ(1 + i, descriptor->JSParameterCount());
-    CHECK_EQ(1, descriptor->ReturnCount());
+    CHECK_EQ(1 + i, static_cast<int>(descriptor->JSParameterCount()));
+    CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount()));
     CHECK_EQ(Operator::kNoProperties, descriptor->properties());
     CHECK_EQ(true, descriptor->IsJSFunctionCall());
   }
@@ -76,7 +75,7 @@
 TEST(TestLinkageCodeStubIncoming) {
   Isolate* isolate = CcTest::InitIsolateOnce();
   CompilationInfoWithZone info(static_cast<HydrogenCodeStub*>(NULL), isolate);
-  Linkage linkage(&info);
+  Linkage linkage(info.zone(), &info);
   // TODO(titzer): test linkage creation with a bonafide code stub.
   // this just checks current behavior.
   CHECK_EQ(NULL, linkage.GetIncomingDescriptor());
@@ -87,13 +86,14 @@
   HandleAndZoneScope handles;
   Handle<JSFunction> function = Compile("a + c");
   CompilationInfoWithZone info(function);
-  Linkage linkage(&info);
+  Linkage linkage(info.zone(), &info);
 
   for (int i = 0; i < 32; i++) {
-    CallDescriptor* descriptor = linkage.GetJSCallDescriptor(i);
+    CallDescriptor* descriptor =
+        linkage.GetJSCallDescriptor(i, CallDescriptor::kNoFlags);
     CHECK_NE(NULL, descriptor);
-    CHECK_EQ(i, descriptor->JSParameterCount());
-    CHECK_EQ(1, descriptor->ReturnCount());
+    CHECK_EQ(i, static_cast<int>(descriptor->JSParameterCount()));
+    CHECK_EQ(1, static_cast<int>(descriptor->ReturnCount()));
     CHECK_EQ(Operator::kNoProperties, descriptor->properties());
     CHECK_EQ(true, descriptor->IsJSFunctionCall());
   }
diff --git a/test/cctest/compiler/test-loop-analysis.cc b/test/cctest/compiler/test-loop-analysis.cc
new file mode 100644
index 0000000..9c11268
--- /dev/null
+++ b/test/cctest/compiler/test-loop-analysis.cc
@@ -0,0 +1,862 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "src/compiler/access-builder.h"
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/graph-visualizer.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/loop-analysis.h"
+#include "src/compiler/node.h"
+#include "src/compiler/opcodes.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/schedule.h"
+#include "src/compiler/scheduler.h"
+#include "src/compiler/simplified-operator.h"
+#include "src/compiler/verifier.h"
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+static Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0,
+                        0, 1, 0, 0);
+static Operator kIntLt(IrOpcode::kInt32LessThan, Operator::kPure,
+                       "Int32LessThan", 2, 0, 0, 1, 0, 0);
+static Operator kStore(IrOpcode::kStore, Operator::kNoProperties, "Store", 0, 2,
+                       1, 0, 1, 0);
+
+static const int kNumLeafs = 4;
+
+// A helper for all tests dealing with LoopFinder.
+class LoopFinderTester : HandleAndZoneScope {
+ public:
+  LoopFinderTester()
+      : isolate(main_isolate()),
+        common(main_zone()),
+        graph(main_zone()),
+        jsgraph(&graph, &common, NULL, NULL),
+        start(graph.NewNode(common.Start(1))),
+        end(graph.NewNode(common.End(), start)),
+        p0(graph.NewNode(common.Parameter(0), start)),
+        zero(jsgraph.Int32Constant(0)),
+        one(jsgraph.OneConstant()),
+        half(jsgraph.Constant(0.5)),
+        self(graph.NewNode(common.Int32Constant(0xaabbccdd))),
+        dead(graph.NewNode(common.Dead())),
+        loop_tree(NULL) {
+    graph.SetEnd(end);
+    graph.SetStart(start);
+    leaf[0] = zero;
+    leaf[1] = one;
+    leaf[2] = half;
+    leaf[3] = p0;
+  }
+
+  Isolate* isolate;
+  CommonOperatorBuilder common;
+  Graph graph;
+  JSGraph jsgraph;
+  Node* start;
+  Node* end;
+  Node* p0;
+  Node* zero;
+  Node* one;
+  Node* half;
+  Node* self;
+  Node* dead;
+  Node* leaf[kNumLeafs];
+  LoopTree* loop_tree;
+
+  Node* Phi(Node* a) {
+    return SetSelfReferences(graph.NewNode(op(1, false), a, start));
+  }
+
+  Node* Phi(Node* a, Node* b) {
+    return SetSelfReferences(graph.NewNode(op(2, false), a, b, start));
+  }
+
+  Node* Phi(Node* a, Node* b, Node* c) {
+    return SetSelfReferences(graph.NewNode(op(3, false), a, b, c, start));
+  }
+
+  Node* Phi(Node* a, Node* b, Node* c, Node* d) {
+    return SetSelfReferences(graph.NewNode(op(4, false), a, b, c, d, start));
+  }
+
+  Node* EffectPhi(Node* a) {
+    return SetSelfReferences(graph.NewNode(op(1, true), a, start));
+  }
+
+  Node* EffectPhi(Node* a, Node* b) {
+    return SetSelfReferences(graph.NewNode(op(2, true), a, b, start));
+  }
+
+  Node* EffectPhi(Node* a, Node* b, Node* c) {
+    return SetSelfReferences(graph.NewNode(op(3, true), a, b, c, start));
+  }
+
+  Node* EffectPhi(Node* a, Node* b, Node* c, Node* d) {
+    return SetSelfReferences(graph.NewNode(op(4, true), a, b, c, d, start));
+  }
+
+  Node* SetSelfReferences(Node* node) {
+    for (Edge edge : node->input_edges()) {
+      if (edge.to() == self) node->ReplaceInput(edge.index(), node);
+    }
+    return node;
+  }
+
+  const Operator* op(int count, bool effect) {
+    return effect ? common.EffectPhi(count) : common.Phi(kMachAnyTagged, count);
+  }
+
+  Node* Return(Node* val, Node* effect, Node* control) {
+    Node* ret = graph.NewNode(common.Return(), val, effect, control);
+    end->ReplaceInput(0, ret);
+    return ret;
+  }
+
+  LoopTree* GetLoopTree() {
+    if (loop_tree == NULL) {
+      if (FLAG_trace_turbo_graph) {
+        OFStream os(stdout);
+        os << AsRPO(graph);
+      }
+      Zone zone(isolate);
+      loop_tree = LoopFinder::BuildLoopTree(&graph, &zone);
+    }
+    return loop_tree;
+  }
+
+  void CheckLoop(Node** header, int header_count, Node** body, int body_count) {
+    LoopTree* tree = GetLoopTree();
+    LoopTree::Loop* loop = tree->ContainingLoop(header[0]);
+    CHECK_NE(NULL, loop);
+
+    CHECK(header_count == static_cast<int>(loop->HeaderSize()));
+    for (int i = 0; i < header_count; i++) {
+      // Each header node should be in the loop.
+      CHECK_EQ(loop, tree->ContainingLoop(header[i]));
+      CheckRangeContains(tree->HeaderNodes(loop), header[i]);
+    }
+
+    CHECK_EQ(body_count, static_cast<int>(loop->BodySize()));
+    for (int i = 0; i < body_count; i++) {
+      // Each body node should be contained in the loop.
+      CHECK(tree->Contains(loop, body[i]));
+      CheckRangeContains(tree->BodyNodes(loop), body[i]);
+    }
+  }
+
+  void CheckRangeContains(NodeRange range, Node* node) {
+    // O(n) ftw.
+    CHECK_NE(range.end(), std::find(range.begin(), range.end(), node));
+  }
+
+  void CheckNestedLoops(Node** chain, int chain_count) {
+    LoopTree* tree = GetLoopTree();
+    for (int i = 0; i < chain_count; i++) {
+      Node* header = chain[i];
+      // Each header should be in a loop.
+      LoopTree::Loop* loop = tree->ContainingLoop(header);
+      CHECK_NE(NULL, loop);
+      // Check parentage.
+      LoopTree::Loop* parent =
+          i == 0 ? NULL : tree->ContainingLoop(chain[i - 1]);
+      CHECK_EQ(parent, loop->parent());
+      for (int j = i - 1; j >= 0; j--) {
+        // This loop should be nested inside all the outer loops.
+        Node* outer_header = chain[j];
+        LoopTree::Loop* outer = tree->ContainingLoop(outer_header);
+        CHECK(tree->Contains(outer, header));
+        CHECK(!tree->Contains(loop, outer_header));
+      }
+    }
+  }
+};
+
+
+struct While {
+  LoopFinderTester& t;
+  Node* branch;
+  Node* if_true;
+  Node* exit;
+  Node* loop;
+
+  While(LoopFinderTester& R, Node* cond) : t(R) {
+    loop = t.graph.NewNode(t.common.Loop(2), t.start, t.start);
+    branch = t.graph.NewNode(t.common.Branch(), cond, loop);
+    if_true = t.graph.NewNode(t.common.IfTrue(), branch);
+    exit = t.graph.NewNode(t.common.IfFalse(), branch);
+    loop->ReplaceInput(1, if_true);
+  }
+
+  void chain(Node* control) { loop->ReplaceInput(0, control); }
+  void nest(While& that) {
+    that.loop->ReplaceInput(1, exit);
+    this->loop->ReplaceInput(0, that.if_true);
+  }
+};
+
+
+struct Counter {
+  Node* base;
+  Node* inc;
+  Node* phi;
+  Node* add;
+
+  Counter(While& w, int32_t b, int32_t k)
+      : base(w.t.jsgraph.Int32Constant(b)), inc(w.t.jsgraph.Int32Constant(k)) {
+    Build(w);
+  }
+
+  Counter(While& w, Node* b, Node* k) : base(b), inc(k) { Build(w); }
+
+  void Build(While& w) {
+    phi = w.t.graph.NewNode(w.t.op(2, false), base, base, w.loop);
+    add = w.t.graph.NewNode(&kIntAdd, phi, inc);
+    phi->ReplaceInput(1, add);
+  }
+};
+
+
+struct StoreLoop {
+  Node* base;
+  Node* val;
+  Node* phi;
+  Node* store;
+
+  explicit StoreLoop(While& w)
+      : base(w.t.jsgraph.Int32Constant(12)),
+        val(w.t.jsgraph.Int32Constant(13)) {
+    Build(w);
+  }
+
+  StoreLoop(While& w, Node* b, Node* v) : base(b), val(v) { Build(w); }
+
+  void Build(While& w) {
+    phi = w.t.graph.NewNode(w.t.op(2, true), base, base, w.loop);
+    store = w.t.graph.NewNode(&kStore, phi, val, w.loop);
+    phi->ReplaceInput(1, store);
+  }
+};
+
+
+TEST(LaLoop1) {
+  // One loop.
+  LoopFinderTester t;
+  While w(t, t.p0);
+  t.Return(t.p0, t.start, w.exit);
+
+  Node* chain[] = {w.loop};
+  t.CheckNestedLoops(chain, 1);
+
+  Node* header[] = {w.loop};
+  Node* body[] = {w.branch, w.if_true};
+  t.CheckLoop(header, 1, body, 2);
+}
+
+
+TEST(LaLoop1c) {
+  // One loop with a counter.
+  LoopFinderTester t;
+  While w(t, t.p0);
+  Counter c(w, 0, 1);
+  t.Return(c.phi, t.start, w.exit);
+
+  Node* chain[] = {w.loop};
+  t.CheckNestedLoops(chain, 1);
+
+  Node* header[] = {w.loop, c.phi};
+  Node* body[] = {w.branch, w.if_true, c.add};
+  t.CheckLoop(header, 2, body, 3);
+}
+
+
+TEST(LaLoop1e) {
+  // One loop with an effect phi.
+  LoopFinderTester t;
+  While w(t, t.p0);
+  StoreLoop c(w);
+  t.Return(t.p0, c.phi, w.exit);
+
+  Node* chain[] = {w.loop};
+  t.CheckNestedLoops(chain, 1);
+
+  Node* header[] = {w.loop, c.phi};
+  Node* body[] = {w.branch, w.if_true, c.store};
+  t.CheckLoop(header, 2, body, 3);
+}
+
+
+TEST(LaLoop1d) {
+  // One loop with two counters.
+  LoopFinderTester t;
+  While w(t, t.p0);
+  Counter c1(w, 0, 1);
+  Counter c2(w, 1, 1);
+  t.Return(t.graph.NewNode(&kIntAdd, c1.phi, c2.phi), t.start, w.exit);
+
+  Node* chain[] = {w.loop};
+  t.CheckNestedLoops(chain, 1);
+
+  Node* header[] = {w.loop, c1.phi, c2.phi};
+  Node* body[] = {w.branch, w.if_true, c1.add, c2.add};
+  t.CheckLoop(header, 3, body, 4);
+}
+
+
+TEST(LaLoop2) {
+  // One loop following another.
+  LoopFinderTester t;
+  While w1(t, t.p0);
+  While w2(t, t.p0);
+  w2.chain(w1.exit);
+  t.Return(t.p0, t.start, w2.exit);
+
+  {
+    Node* chain[] = {w1.loop};
+    t.CheckNestedLoops(chain, 1);
+
+    Node* header[] = {w1.loop};
+    Node* body[] = {w1.branch, w1.if_true};
+    t.CheckLoop(header, 1, body, 2);
+  }
+
+  {
+    Node* chain[] = {w2.loop};
+    t.CheckNestedLoops(chain, 1);
+
+    Node* header[] = {w2.loop};
+    Node* body[] = {w2.branch, w2.if_true};
+    t.CheckLoop(header, 1, body, 2);
+  }
+}
+
+
+TEST(LaLoop2c) {
+  // One loop following another, each with counters.
+  LoopFinderTester t;
+  While w1(t, t.p0);
+  While w2(t, t.p0);
+  Counter c1(w1, 0, 1);
+  Counter c2(w2, 0, 1);
+  w2.chain(w1.exit);
+  t.Return(t.graph.NewNode(&kIntAdd, c1.phi, c2.phi), t.start, w2.exit);
+
+  {
+    Node* chain[] = {w1.loop};
+    t.CheckNestedLoops(chain, 1);
+
+    Node* header[] = {w1.loop, c1.phi};
+    Node* body[] = {w1.branch, w1.if_true, c1.add};
+    t.CheckLoop(header, 2, body, 3);
+  }
+
+  {
+    Node* chain[] = {w2.loop};
+    t.CheckNestedLoops(chain, 1);
+
+    Node* header[] = {w2.loop, c2.phi};
+    Node* body[] = {w2.branch, w2.if_true, c2.add};
+    t.CheckLoop(header, 2, body, 3);
+  }
+}
+
+
+TEST(LaLoop2cc) {
+  // One loop following another; second loop uses phi from first.
+  for (int i = 0; i < 8; i++) {
+    LoopFinderTester t;
+    While w1(t, t.p0);
+    While w2(t, t.p0);
+    Counter c1(w1, 0, 1);
+
+    // various usage scenarios for the second loop.
+    Counter c2(w2, i & 1 ? t.p0 : c1.phi, i & 2 ? t.p0 : c1.phi);
+    if (i & 3) w2.branch->ReplaceInput(0, c1.phi);
+
+    w2.chain(w1.exit);
+    t.Return(t.graph.NewNode(&kIntAdd, c1.phi, c2.phi), t.start, w2.exit);
+
+    {
+      Node* chain[] = {w1.loop};
+      t.CheckNestedLoops(chain, 1);
+
+      Node* header[] = {w1.loop, c1.phi};
+      Node* body[] = {w1.branch, w1.if_true, c1.add};
+      t.CheckLoop(header, 2, body, 3);
+    }
+
+    {
+      Node* chain[] = {w2.loop};
+      t.CheckNestedLoops(chain, 1);
+
+      Node* header[] = {w2.loop, c2.phi};
+      Node* body[] = {w2.branch, w2.if_true, c2.add};
+      t.CheckLoop(header, 2, body, 3);
+    }
+  }
+}
+
+
+TEST(LaNestedLoop1) {
+  // One loop nested in another.
+  LoopFinderTester t;
+  While w1(t, t.p0);
+  While w2(t, t.p0);
+  w2.nest(w1);
+  t.Return(t.p0, t.start, w1.exit);
+
+  Node* chain[] = {w1.loop, w2.loop};
+  t.CheckNestedLoops(chain, 2);
+
+  Node* h1[] = {w1.loop};
+  Node* b1[] = {w1.branch, w1.if_true, w2.loop, w2.branch, w2.if_true, w2.exit};
+  t.CheckLoop(h1, 1, b1, 6);
+
+  Node* h2[] = {w2.loop};
+  Node* b2[] = {w2.branch, w2.if_true};
+  t.CheckLoop(h2, 1, b2, 2);
+}
+
+
+TEST(LaNestedLoop1c) {
+  // One loop nested in another, each with a counter.
+  LoopFinderTester t;
+  While w1(t, t.p0);
+  While w2(t, t.p0);
+  Counter c1(w1, 0, 1);
+  Counter c2(w2, 0, 1);
+  w2.branch->ReplaceInput(0, c2.phi);
+  w2.nest(w1);
+  t.Return(c1.phi, t.start, w1.exit);
+
+  Node* chain[] = {w1.loop, w2.loop};
+  t.CheckNestedLoops(chain, 2);
+
+  Node* h1[] = {w1.loop, c1.phi};
+  Node* b1[] = {w1.branch, w1.if_true, w2.loop, w2.branch, w2.if_true,
+                w2.exit,   c2.phi,     c1.add,  c2.add};
+  t.CheckLoop(h1, 2, b1, 9);
+
+  Node* h2[] = {w2.loop, c2.phi};
+  Node* b2[] = {w2.branch, w2.if_true, c2.add};
+  t.CheckLoop(h2, 2, b2, 3);
+}
+
+
+TEST(LaNestedLoop2) {
+  // Two loops nested in an outer loop.
+  LoopFinderTester t;
+  While w1(t, t.p0);
+  While w2(t, t.p0);
+  While w3(t, t.p0);
+  w2.nest(w1);
+  w3.nest(w1);
+  w3.chain(w2.exit);
+  t.Return(t.p0, t.start, w1.exit);
+
+  Node* chain1[] = {w1.loop, w2.loop};
+  t.CheckNestedLoops(chain1, 2);
+
+  Node* chain2[] = {w1.loop, w3.loop};
+  t.CheckNestedLoops(chain2, 2);
+
+  Node* h1[] = {w1.loop};
+  Node* b1[] = {w1.branch, w1.if_true, w2.loop,   w2.branch,  w2.if_true,
+                w2.exit,   w3.loop,    w3.branch, w3.if_true, w3.exit};
+  t.CheckLoop(h1, 1, b1, 10);
+
+  Node* h2[] = {w2.loop};
+  Node* b2[] = {w2.branch, w2.if_true};
+  t.CheckLoop(h2, 1, b2, 2);
+
+  Node* h3[] = {w3.loop};
+  Node* b3[] = {w3.branch, w3.if_true};
+  t.CheckLoop(h3, 1, b3, 2);
+}
+
+
+TEST(LaNestedLoop3) {
+  // Three nested loops.
+  LoopFinderTester t;
+  While w1(t, t.p0);
+  While w2(t, t.p0);
+  While w3(t, t.p0);
+  w2.loop->ReplaceInput(0, w1.if_true);
+  w3.loop->ReplaceInput(0, w2.if_true);
+  w2.loop->ReplaceInput(1, w3.exit);
+  w1.loop->ReplaceInput(1, w2.exit);
+  t.Return(t.p0, t.start, w1.exit);
+
+  Node* chain[] = {w1.loop, w2.loop, w3.loop};
+  t.CheckNestedLoops(chain, 3);
+
+  Node* h1[] = {w1.loop};
+  Node* b1[] = {w1.branch, w1.if_true, w2.loop,   w2.branch,  w2.if_true,
+                w2.exit,   w3.loop,    w3.branch, w3.if_true, w3.exit};
+  t.CheckLoop(h1, 1, b1, 10);
+
+  Node* h2[] = {w2.loop};
+  Node* b2[] = {w2.branch, w2.if_true, w3.loop, w3.branch, w3.if_true, w3.exit};
+  t.CheckLoop(h2, 1, b2, 6);
+
+  Node* h3[] = {w3.loop};
+  Node* b3[] = {w3.branch, w3.if_true};
+  t.CheckLoop(h3, 1, b3, 2);
+}
+
+
+TEST(LaNestedLoop3c) {
+  // Three nested loops with counters.
+  LoopFinderTester t;
+  While w1(t, t.p0);
+  Counter c1(w1, 0, 1);
+  While w2(t, t.p0);
+  Counter c2(w2, 0, 1);
+  While w3(t, t.p0);
+  Counter c3(w3, 0, 1);
+  w2.loop->ReplaceInput(0, w1.if_true);
+  w3.loop->ReplaceInput(0, w2.if_true);
+  w2.loop->ReplaceInput(1, w3.exit);
+  w1.loop->ReplaceInput(1, w2.exit);
+  w1.branch->ReplaceInput(0, c1.phi);
+  w2.branch->ReplaceInput(0, c2.phi);
+  w3.branch->ReplaceInput(0, c3.phi);
+  t.Return(c1.phi, t.start, w1.exit);
+
+  Node* chain[] = {w1.loop, w2.loop, w3.loop};
+  t.CheckNestedLoops(chain, 3);
+
+  Node* h1[] = {w1.loop, c1.phi};
+  Node* b1[] = {w1.branch, w1.if_true, c1.add,    c2.add,     c2.add,
+                c2.phi,    c3.phi,     w2.loop,   w2.branch,  w2.if_true,
+                w2.exit,   w3.loop,    w3.branch, w3.if_true, w3.exit};
+  t.CheckLoop(h1, 2, b1, 15);
+
+  Node* h2[] = {w2.loop, c2.phi};
+  Node* b2[] = {w2.branch, w2.if_true, c2.add,     c3.add, c3.phi,
+                w3.loop,   w3.branch,  w3.if_true, w3.exit};
+  t.CheckLoop(h2, 2, b2, 9);
+
+  Node* h3[] = {w3.loop, c3.phi};
+  Node* b3[] = {w3.branch, w3.if_true, c3.add};
+  t.CheckLoop(h3, 2, b3, 3);
+}
+
+
+TEST(LaMultipleExit1) {
+  const int kMaxExits = 10;
+  Node* merge[1 + kMaxExits];
+  Node* body[2 * kMaxExits];
+
+  // A single loop with {i} exits.
+  for (int i = 1; i < kMaxExits; i++) {
+    LoopFinderTester t;
+    Node* cond = t.p0;
+
+    int merge_count = 0;
+    int body_count = 0;
+    Node* loop = t.graph.NewNode(t.common.Loop(2), t.start, t.start);
+    Node* last = loop;
+
+    for (int e = 0; e < i; e++) {
+      Node* branch = t.graph.NewNode(t.common.Branch(), cond, last);
+      Node* if_true = t.graph.NewNode(t.common.IfTrue(), branch);
+      Node* exit = t.graph.NewNode(t.common.IfFalse(), branch);
+      last = if_true;
+
+      body[body_count++] = branch;
+      body[body_count++] = if_true;
+      merge[merge_count++] = exit;
+    }
+
+    loop->ReplaceInput(1, last);  // form loop backedge.
+    Node* end = t.graph.NewNode(t.common.Merge(i), i, merge);  // form exit.
+    t.graph.SetEnd(end);
+
+    Node* h[] = {loop};
+    t.CheckLoop(h, 1, body, body_count);
+  }
+}
+
+
+TEST(LaMultipleBackedge1) {
+  const int kMaxBackedges = 10;
+  Node* loop_inputs[1 + kMaxBackedges];
+  Node* body[3 * kMaxBackedges];
+
+  // A single loop with {i} backedges.
+  for (int i = 1; i < kMaxBackedges; i++) {
+    LoopFinderTester t;
+
+    for (int j = 0; j <= i; j++) loop_inputs[j] = t.start;
+    Node* loop = t.graph.NewNode(t.common.Loop(1 + i), 1 + i, loop_inputs);
+
+    Node* cond = t.p0;
+    int body_count = 0;
+    Node* exit = loop;
+
+    for (int b = 0; b < i; b++) {
+      Node* branch = t.graph.NewNode(t.common.Branch(), cond, exit);
+      Node* if_true = t.graph.NewNode(t.common.IfTrue(), branch);
+      Node* if_false = t.graph.NewNode(t.common.IfFalse(), branch);
+      exit = if_false;
+
+      body[body_count++] = branch;
+      body[body_count++] = if_true;
+      if (b != (i - 1)) body[body_count++] = if_false;
+
+      loop->ReplaceInput(1 + b, if_true);
+    }
+
+    t.graph.SetEnd(exit);
+
+    Node* h[] = {loop};
+    t.CheckLoop(h, 1, body, body_count);
+  }
+}
+
+
+TEST(LaEdgeMatrix1) {
+  // Test various kinds of extra edges added to a simple loop.
+  for (int i = 0; i < 3; i++) {
+    for (int j = 0; j < 3; j++) {
+      for (int k = 0; k < 3; k++) {
+        LoopFinderTester t;
+
+        Node* p1 = t.jsgraph.Int32Constant(11);
+        Node* p2 = t.jsgraph.Int32Constant(22);
+        Node* p3 = t.jsgraph.Int32Constant(33);
+
+        Node* loop = t.graph.NewNode(t.common.Loop(2), t.start, t.start);
+        Node* phi =
+            t.graph.NewNode(t.common.Phi(kMachInt32, 2), t.one, p1, loop);
+        Node* cond = t.graph.NewNode(&kIntAdd, phi, p2);
+        Node* branch = t.graph.NewNode(t.common.Branch(), cond, loop);
+        Node* if_true = t.graph.NewNode(t.common.IfTrue(), branch);
+        Node* exit = t.graph.NewNode(t.common.IfFalse(), branch);
+        loop->ReplaceInput(1, if_true);
+        Node* ret = t.graph.NewNode(t.common.Return(), p3, t.start, exit);
+        t.graph.SetEnd(ret);
+
+        Node* choices[] = {p1, phi, cond};
+        p1->ReplaceUses(choices[i]);
+        p2->ReplaceUses(choices[j]);
+        p3->ReplaceUses(choices[k]);
+
+        Node* header[] = {loop, phi};
+        Node* body[] = {cond, branch, if_true};
+        t.CheckLoop(header, 2, body, 3);
+      }
+    }
+  }
+}
+
+
+void RunEdgeMatrix2(int i) {
+  DCHECK(i >= 0 && i < 5);
+  for (int j = 0; j < 5; j++) {
+    for (int k = 0; k < 5; k++) {
+      LoopFinderTester t;
+
+      Node* p1 = t.jsgraph.Int32Constant(11);
+      Node* p2 = t.jsgraph.Int32Constant(22);
+      Node* p3 = t.jsgraph.Int32Constant(33);
+
+      // outer loop.
+      Node* loop1 = t.graph.NewNode(t.common.Loop(2), t.start, t.start);
+      Node* phi1 =
+          t.graph.NewNode(t.common.Phi(kMachInt32, 2), t.one, p1, loop1);
+      Node* cond1 = t.graph.NewNode(&kIntAdd, phi1, t.one);
+      Node* branch1 = t.graph.NewNode(t.common.Branch(), cond1, loop1);
+      Node* if_true1 = t.graph.NewNode(t.common.IfTrue(), branch1);
+      Node* exit1 = t.graph.NewNode(t.common.IfFalse(), branch1);
+
+      // inner loop.
+      Node* loop2 = t.graph.NewNode(t.common.Loop(2), if_true1, t.start);
+      Node* phi2 =
+          t.graph.NewNode(t.common.Phi(kMachInt32, 2), t.one, p2, loop2);
+      Node* cond2 = t.graph.NewNode(&kIntAdd, phi2, p3);
+      Node* branch2 = t.graph.NewNode(t.common.Branch(), cond2, loop2);
+      Node* if_true2 = t.graph.NewNode(t.common.IfTrue(), branch2);
+      Node* exit2 = t.graph.NewNode(t.common.IfFalse(), branch2);
+      loop2->ReplaceInput(1, if_true2);
+      loop1->ReplaceInput(1, exit2);
+
+      Node* ret = t.graph.NewNode(t.common.Return(), phi1, t.start, exit1);
+      t.graph.SetEnd(ret);
+
+      Node* choices[] = {p1, phi1, cond1, phi2, cond2};
+      p1->ReplaceUses(choices[i]);
+      p2->ReplaceUses(choices[j]);
+      p3->ReplaceUses(choices[k]);
+
+      Node* header1[] = {loop1, phi1};
+      Node* body1[] = {cond1, branch1, if_true1, exit2,   loop2,
+                       phi2,  cond2,   branch2,  if_true2};
+      t.CheckLoop(header1, 2, body1, 9);
+
+      Node* header2[] = {loop2, phi2};
+      Node* body2[] = {cond2, branch2, if_true2};
+      t.CheckLoop(header2, 2, body2, 3);
+
+      Node* chain[] = {loop1, loop2};
+      t.CheckNestedLoops(chain, 2);
+    }
+  }
+}
+
+
+TEST(LaEdgeMatrix2_0) { RunEdgeMatrix2(0); }
+
+
+TEST(LaEdgeMatrix2_1) { RunEdgeMatrix2(1); }
+
+
+TEST(LaEdgeMatrix2_2) { RunEdgeMatrix2(2); }
+
+
+TEST(LaEdgeMatrix2_3) { RunEdgeMatrix2(3); }
+
+
+TEST(LaEdgeMatrix2_4) { RunEdgeMatrix2(4); }
+
+
+// Generates a triply-nested loop with extra edges between the phis and
+// conditions according to the edge choice parameters.
+void RunEdgeMatrix3(int c1a, int c1b, int c1c,    // line break
+                    int c2a, int c2b, int c2c,    // line break
+                    int c3a, int c3b, int c3c) {  // line break
+  LoopFinderTester t;
+
+  Node* p1a = t.jsgraph.Int32Constant(11);
+  Node* p1b = t.jsgraph.Int32Constant(22);
+  Node* p1c = t.jsgraph.Int32Constant(33);
+  Node* p2a = t.jsgraph.Int32Constant(44);
+  Node* p2b = t.jsgraph.Int32Constant(55);
+  Node* p2c = t.jsgraph.Int32Constant(66);
+  Node* p3a = t.jsgraph.Int32Constant(77);
+  Node* p3b = t.jsgraph.Int32Constant(88);
+  Node* p3c = t.jsgraph.Int32Constant(99);
+
+  // L1 depth = 0
+  Node* loop1 = t.graph.NewNode(t.common.Loop(2), t.start, t.start);
+  Node* phi1 = t.graph.NewNode(t.common.Phi(kMachInt32, 2), p1a, p1c, loop1);
+  Node* cond1 = t.graph.NewNode(&kIntAdd, phi1, p1b);
+  Node* branch1 = t.graph.NewNode(t.common.Branch(), cond1, loop1);
+  Node* if_true1 = t.graph.NewNode(t.common.IfTrue(), branch1);
+  Node* exit1 = t.graph.NewNode(t.common.IfFalse(), branch1);
+
+  // L2 depth = 1
+  Node* loop2 = t.graph.NewNode(t.common.Loop(2), if_true1, t.start);
+  Node* phi2 = t.graph.NewNode(t.common.Phi(kMachInt32, 2), p2a, p2c, loop2);
+  Node* cond2 = t.graph.NewNode(&kIntAdd, phi2, p2b);
+  Node* branch2 = t.graph.NewNode(t.common.Branch(), cond2, loop2);
+  Node* if_true2 = t.graph.NewNode(t.common.IfTrue(), branch2);
+  Node* exit2 = t.graph.NewNode(t.common.IfFalse(), branch2);
+
+  // L3 depth = 2
+  Node* loop3 = t.graph.NewNode(t.common.Loop(2), if_true2, t.start);
+  Node* phi3 = t.graph.NewNode(t.common.Phi(kMachInt32, 2), p3a, p3c, loop3);
+  Node* cond3 = t.graph.NewNode(&kIntAdd, phi3, p3b);
+  Node* branch3 = t.graph.NewNode(t.common.Branch(), cond3, loop3);
+  Node* if_true3 = t.graph.NewNode(t.common.IfTrue(), branch3);
+  Node* exit3 = t.graph.NewNode(t.common.IfFalse(), branch3);
+
+  loop3->ReplaceInput(1, if_true3);
+  loop2->ReplaceInput(1, exit3);
+  loop1->ReplaceInput(1, exit2);
+
+  Node* ret = t.graph.NewNode(t.common.Return(), phi1, t.start, exit1);
+  t.graph.SetEnd(ret);
+
+  // Mutate the graph according to the edge choices.
+
+  Node* o1[] = {t.one};
+  Node* o2[] = {t.one, phi1, cond1};
+  Node* o3[] = {t.one, phi1, cond1, phi2, cond2};
+
+  p1a->ReplaceUses(o1[c1a]);
+  p1b->ReplaceUses(o1[c1b]);
+
+  p2a->ReplaceUses(o2[c2a]);
+  p2b->ReplaceUses(o2[c2b]);
+
+  p3a->ReplaceUses(o3[c3a]);
+  p3b->ReplaceUses(o3[c3b]);
+
+  Node* l2[] = {phi1, cond1, phi2, cond2};
+  Node* l3[] = {phi1, cond1, phi2, cond2, phi3, cond3};
+
+  p1c->ReplaceUses(l2[c1c]);
+  p2c->ReplaceUses(l3[c2c]);
+  p3c->ReplaceUses(l3[c3c]);
+
+  // Run the tests and verify loop structure.
+
+  Node* chain[] = {loop1, loop2, loop3};
+  t.CheckNestedLoops(chain, 3);
+
+  Node* header1[] = {loop1, phi1};
+  Node* body1[] = {cond1, branch1, if_true1, exit2,    loop2,
+                   phi2,  cond2,   branch2,  if_true2, exit3,
+                   loop3, phi3,    cond3,    branch3,  if_true3};
+  t.CheckLoop(header1, 2, body1, 15);
+
+  Node* header2[] = {loop2, phi2};
+  Node* body2[] = {cond2, branch2, if_true2, exit3,   loop3,
+                   phi3,  cond3,   branch3,  if_true3};
+  t.CheckLoop(header2, 2, body2, 9);
+
+  Node* header3[] = {loop3, phi3};
+  Node* body3[] = {cond3, branch3, if_true3};
+  t.CheckLoop(header3, 2, body3, 3);
+}
+
+
+// Runs all combinations with a fixed {i}.
+void RunEdgeMatrix3_i(int i) {
+  for (int a = 0; a < 1; a++) {
+    for (int b = 0; b < 1; b++) {
+      for (int c = 0; c < 4; c++) {
+        for (int d = 0; d < 3; d++) {
+          for (int e = 0; e < 3; e++) {
+            for (int f = 0; f < 6; f++) {
+              for (int g = 0; g < 5; g++) {
+                for (int h = 0; h < 5; h++) {
+                  RunEdgeMatrix3(a, b, c, d, e, f, g, h, i);
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+
+// Test all possible legal triply-nested loops with conditions and phis.
+TEST(LaEdgeMatrix3_0) { RunEdgeMatrix3_i(0); }
+
+
+TEST(LaEdgeMatrix3_1) { RunEdgeMatrix3_i(1); }
+
+
+TEST(LaEdgeMatrix3_2) { RunEdgeMatrix3_i(2); }
+
+
+TEST(LaEdgeMatrix3_3) { RunEdgeMatrix3_i(3); }
+
+
+TEST(LaEdgeMatrix3_4) { RunEdgeMatrix3_i(4); }
+
+
+TEST(LaEdgeMatrix3_5) { RunEdgeMatrix3_i(5); }
diff --git a/test/cctest/compiler/test-loop-assignment-analysis.cc b/test/cctest/compiler/test-loop-assignment-analysis.cc
new file mode 100644
index 0000000..aabd95b
--- /dev/null
+++ b/test/cctest/compiler/test-loop-assignment-analysis.cc
@@ -0,0 +1,294 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/ast-loop-assignment-analyzer.h"
+#include "src/parser.h"
+#include "src/rewriter.h"
+#include "src/scopes.h"
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+namespace {
+const int kBufferSize = 1024;
+
+struct TestHelper : public HandleAndZoneScope {
+  Handle<JSFunction> function;
+  LoopAssignmentAnalysis* result;
+
+  explicit TestHelper(const char* body)
+      : function(Handle<JSFunction>::null()), result(NULL) {
+    ScopedVector<char> program(kBufferSize);
+    SNPrintF(program, "function f(a,b,c) { %s; } f;", body);
+    v8::Local<v8::Value> v = CompileRun(program.start());
+    Handle<Object> obj = v8::Utils::OpenHandle(*v);
+    function = Handle<JSFunction>::cast(obj);
+  }
+
+  void CheckLoopAssignedCount(int expected, const char* var_name) {
+    // TODO(titzer): don't scope analyze every single time.
+    CompilationInfo info(function, main_zone());
+
+    CHECK(Parser::Parse(&info));
+    CHECK(Rewriter::Rewrite(&info));
+    CHECK(Scope::Analyze(&info));
+
+    Scope* scope = info.function()->scope();
+    AstValueFactory* factory = info.ast_value_factory();
+    CHECK_NE(NULL, scope);
+
+    if (result == NULL) {
+      AstLoopAssignmentAnalyzer analyzer(main_zone(), &info);
+      result = analyzer.Analyze();
+      CHECK_NE(NULL, result);
+    }
+
+    const i::AstRawString* name = factory->GetOneByteString(var_name);
+
+    i::Variable* var = scope->Lookup(name);
+    CHECK_NE(NULL, var);
+
+    if (var->location() == Variable::UNALLOCATED) {
+      CHECK_EQ(0, expected);
+    } else {
+      CHECK(var->IsStackAllocated());
+      CHECK_EQ(expected, result->GetAssignmentCountForTesting(scope, var));
+    }
+  }
+};
+}
+
+
+TEST(SimpleLoop1) {
+  TestHelper f("var x = 0; while (x) ;");
+
+  f.CheckLoopAssignedCount(0, "x");
+}
+
+
+TEST(SimpleLoop2) {
+  const char* loops[] = {
+      "while (x) { var x = 0; }",            "for(;;) { var x = 0; }",
+      "for(;x;) { var x = 0; }",             "for(;x;x) { var x = 0; }",
+      "for(var i = x; x; x) { var x = 0; }", "for(y in 0) { var x = 0; }",
+      "for(y of 0) { var x = 0; }",          "for(var x = 0; x; x++) { }",
+      "for(var x = 0; x++;) { }",            "var x; for(;x;x++) { }",
+      "var x; do { x = 1; } while (0);",     "do { var x = 1; } while (0);"};
+
+  for (size_t i = 0; i < arraysize(loops); i++) {
+    TestHelper f(loops[i]);
+    f.CheckLoopAssignedCount(1, "x");
+  }
+}
+
+
+TEST(ForInOf1) {
+  const char* loops[] = {
+      "for(x in 0) { }", "for(x of 0) { }",
+  };
+
+  for (size_t i = 0; i < arraysize(loops); i++) {
+    TestHelper f(loops[i]);
+    f.CheckLoopAssignedCount(0, "x");
+  }
+}
+
+
+TEST(Param1) {
+  TestHelper f("while (1) a = 0;");
+
+  f.CheckLoopAssignedCount(1, "a");
+  f.CheckLoopAssignedCount(0, "b");
+  f.CheckLoopAssignedCount(0, "c");
+}
+
+
+TEST(Param2) {
+  TestHelper f("for (;;) b = 0;");
+
+  f.CheckLoopAssignedCount(0, "a");
+  f.CheckLoopAssignedCount(1, "b");
+  f.CheckLoopAssignedCount(0, "c");
+}
+
+
+TEST(Param2b) {
+  TestHelper f("a; b; c; for (;;) b = 0;");
+
+  f.CheckLoopAssignedCount(0, "a");
+  f.CheckLoopAssignedCount(1, "b");
+  f.CheckLoopAssignedCount(0, "c");
+}
+
+
+TEST(Param3) {
+  TestHelper f("for(x in 0) c = 0;");
+
+  f.CheckLoopAssignedCount(0, "a");
+  f.CheckLoopAssignedCount(0, "b");
+  f.CheckLoopAssignedCount(1, "c");
+}
+
+
+TEST(Param3b) {
+  TestHelper f("a; b; c; for(x in 0) c = 0;");
+
+  f.CheckLoopAssignedCount(0, "a");
+  f.CheckLoopAssignedCount(0, "b");
+  f.CheckLoopAssignedCount(1, "c");
+}
+
+
+TEST(NestedLoop1) {
+  TestHelper f("while (x) { while (x) { var x = 0; } }");
+
+  f.CheckLoopAssignedCount(2, "x");
+}
+
+
+TEST(NestedLoop2) {
+  TestHelper f("while (0) { while (0) { var x = 0; } }");
+
+  f.CheckLoopAssignedCount(2, "x");
+}
+
+
+TEST(NestedLoop3) {
+  TestHelper f("while (0) { var y = 1; while (0) { var x = 0; } }");
+
+  f.CheckLoopAssignedCount(2, "x");
+  f.CheckLoopAssignedCount(1, "y");
+}
+
+
+TEST(NestedInc1) {
+  const char* loops[] = {
+      "while (1) a(b++);",
+      "while (1) a(0, b++);",
+      "while (1) a(0, 0, b++);",
+      "while (1) a(b++, 1, 1);",
+      "while (1) a(++b);",
+      "while (1) a + (b++);",
+      "while (1) (b++) + a;",
+      "while (1) a + c(b++);",
+      "while (1) throw b++;",
+      "while (1) switch (b++) {} ;",
+      "while (1) switch (a) {case (b++): 0; } ;",
+      "while (1) switch (a) {case b: b++; } ;",
+      "while (1) a == (b++);",
+      "while (1) a === (b++);",
+      "while (1) +(b++);",
+      "while (1) ~(b++);",
+      "while (1) new a(b++);",
+      "while (1) (b++).f;",
+      "while (1) a[b++];",
+      "while (1) (b++)();",
+      "while (1) [b++];",
+      "while (1) [0,b++];",
+      "while (1) var y = [11,b++,12];",
+      "while (1) var y = {f:11,g:(b++),h:12};",
+      "while (1) try {b++;} finally {};",
+      "while (1) try {} finally {b++};",
+      "while (1) try {b++;} catch (e) {};",
+      "while (1) try {} catch (e) {b++};",
+      "while (1) return b++;",
+      "while (1) (b++) ? b : b;",
+      "while (1) b ? (b++) : b;",
+      "while (1) b ? b : (b++);",
+  };
+
+  for (size_t i = 0; i < arraysize(loops); i++) {
+    TestHelper f(loops[i]);
+    f.CheckLoopAssignedCount(1, "b");
+  }
+}
+
+
+TEST(NestedAssign1) {
+  const char* loops[] = {
+      "while (1) a(b=1);",
+      "while (1) a(0, b=1);",
+      "while (1) a(0, 0, b=1);",
+      "while (1) a(b=1, 1, 1);",
+      "while (1) a + (b=1);",
+      "while (1) (b=1) + a;",
+      "while (1) a + c(b=1);",
+      "while (1) throw b=1;",
+      "while (1) switch (b=1) {} ;",
+      "while (1) switch (a) {case b=1: 0; } ;",
+      "while (1) switch (a) {case b: b=1; } ;",
+      "while (1) a == (b=1);",
+      "while (1) a === (b=1);",
+      "while (1) +(b=1);",
+      "while (1) ~(b=1);",
+      "while (1) new a(b=1);",
+      "while (1) (b=1).f;",
+      "while (1) a[b=1];",
+      "while (1) (b=1)();",
+      "while (1) [b=1];",
+      "while (1) [0,b=1];",
+      "while (1) var z = [11,b=1,12];",
+      "while (1) var y = {f:11,g:(b=1),h:12};",
+      "while (1) try {b=1;} finally {};",
+      "while (1) try {} finally {b=1};",
+      "while (1) try {b=1;} catch (e) {};",
+      "while (1) try {} catch (e) {b=1};",
+      "while (1) return b=1;",
+      "while (1) (b=1) ? b : b;",
+      "while (1) b ? (b=1) : b;",
+      "while (1) b ? b : (b=1);",
+  };
+
+  for (size_t i = 0; i < arraysize(loops); i++) {
+    TestHelper f(loops[i]);
+    f.CheckLoopAssignedCount(1, "b");
+  }
+}
+
+
+TEST(NestedLoops3) {
+  TestHelper f("var x, y, z, w; while (x++) while (y++) while (z++) ; w;");
+
+  f.CheckLoopAssignedCount(1, "x");
+  f.CheckLoopAssignedCount(2, "y");
+  f.CheckLoopAssignedCount(3, "z");
+  f.CheckLoopAssignedCount(0, "w");
+}
+
+
+TEST(NestedLoops3b) {
+  TestHelper f(
+      "var x, y, z, w;"
+      "while (1) { x=1; while (1) { y=1; while (1) z=1; } }"
+      "w;");
+
+  f.CheckLoopAssignedCount(1, "x");
+  f.CheckLoopAssignedCount(2, "y");
+  f.CheckLoopAssignedCount(3, "z");
+  f.CheckLoopAssignedCount(0, "w");
+}
+
+
+TEST(NestedLoops3c) {
+  TestHelper f(
+      "var x, y, z, w;"
+      "while (1) {"
+      "  x++;"
+      "  while (1) {"
+      "    y++;"
+      "    while (1) z++;"
+      "  }"
+      "  while (1) {"
+      "    y++;"
+      "    while (1) z++;"
+      "  }"
+      "}"
+      "w;");
+
+  f.CheckLoopAssignedCount(1, "x");
+  f.CheckLoopAssignedCount(3, "y");
+  f.CheckLoopAssignedCount(5, "z");
+  f.CheckLoopAssignedCount(0, "w");
+}
diff --git a/test/cctest/compiler/test-machine-operator-reducer.cc b/test/cctest/compiler/test-machine-operator-reducer.cc
index eca1f3c..648e1b9 100644
--- a/test/cctest/compiler/test-machine-operator-reducer.cc
+++ b/test/cctest/compiler/test-machine-operator-reducer.cc
@@ -5,9 +5,11 @@
 #include "test/cctest/cctest.h"
 
 #include "src/base/utils/random-number-generator.h"
+#include "src/codegen.h"
 #include "src/compiler/graph-inl.h"
 #include "src/compiler/js-graph.h"
 #include "src/compiler/machine-operator-reducer.h"
+#include "src/compiler/operator-properties.h"
 #include "src/compiler/typer.h"
 #include "test/cctest/compiler/value-helper.h"
 
@@ -49,15 +51,18 @@
 
 class ReducerTester : public HandleAndZoneScope {
  public:
-  explicit ReducerTester(int num_parameters = 0)
+  explicit ReducerTester(
+      int num_parameters = 0,
+      MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags)
       : isolate(main_isolate()),
         binop(NULL),
         unop(NULL),
+        machine(main_zone(), kMachPtr, flags),
         common(main_zone()),
         graph(main_zone()),
         javascript(main_zone()),
-        typer(main_zone()),
-        jsgraph(&graph, &common, &javascript, &typer, &machine),
+        typer(&graph, MaybeHandle<Context>()),
+        jsgraph(&graph, &common, &javascript, &machine),
         maxuint32(Constant<int32_t>(kMaxUInt32)) {
     Node* s = graph.NewNode(common.Start(num_parameters));
     graph.SetStart(s);
@@ -96,7 +101,7 @@
   template <typename T>
   void CheckFoldBinop(volatile T expect, Node* a, Node* b) {
     CHECK_NE(NULL, binop);
-    Node* n = graph.NewNode(binop, a, b);
+    Node* n = CreateBinopNode(a, b);
     MachineOperatorReducer reducer(&jsgraph);
     Reduction reduction = reducer.Reduce(n);
     CHECK(reduction.Changed());
@@ -108,7 +113,7 @@
   // the {expect} node.
   void CheckBinop(Node* expect, Node* a, Node* b) {
     CHECK_NE(NULL, binop);
-    Node* n = graph.NewNode(binop, a, b);
+    Node* n = CreateBinopNode(a, b);
     MachineOperatorReducer reducer(&jsgraph);
     Reduction reduction = reducer.Reduce(n);
     CHECK(reduction.Changed());
@@ -120,7 +125,7 @@
   void CheckFoldBinop(Node* left_expect, Node* right_expect, Node* left,
                       Node* right) {
     CHECK_NE(NULL, binop);
-    Node* n = graph.NewNode(binop, left, right);
+    Node* n = CreateBinopNode(left, right);
     MachineOperatorReducer reducer(&jsgraph);
     Reduction reduction = reducer.Reduce(n);
     CHECK(reduction.Changed());
@@ -135,7 +140,7 @@
   void CheckFoldBinop(volatile T left_expect, const Operator* op_expect,
                       Node* right_expect, Node* left, Node* right) {
     CHECK_NE(NULL, binop);
-    Node* n = graph.NewNode(binop, left, right);
+    Node* n = CreateBinopNode(left, right);
     MachineOperatorReducer reducer(&jsgraph);
     Reduction r = reducer.Reduce(n);
     CHECK(r.Changed());
@@ -150,11 +155,13 @@
   void CheckFoldBinop(Node* left_expect, const Operator* op_expect,
                       volatile T right_expect, Node* left, Node* right) {
     CHECK_NE(NULL, binop);
-    Node* n = graph.NewNode(binop, left, right);
+    Node* n = CreateBinopNode(left, right);
     MachineOperatorReducer reducer(&jsgraph);
     Reduction r = reducer.Reduce(n);
     CHECK(r.Changed());
     CHECK_EQ(op_expect->opcode(), r.replacement()->op()->opcode());
+    CHECK_EQ(OperatorProperties::GetTotalInputCount(op_expect),
+             r.replacement()->InputCount());
     CHECK_EQ(left_expect, r.replacement()->InputAt(0));
     CHECK_EQ(right_expect, ValueOf<T>(r.replacement()->InputAt(1)->op()));
   }
@@ -167,7 +174,7 @@
     Node* p = Parameter();
     Node* k = Constant<T>(constant);
     {
-      Node* n = graph.NewNode(binop, k, p);
+      Node* n = CreateBinopNode(k, p);
       MachineOperatorReducer reducer(&jsgraph);
       Reduction reduction = reducer.Reduce(n);
       CHECK(!reduction.Changed() || reduction.replacement() == n);
@@ -175,7 +182,7 @@
       CHECK_EQ(k, n->InputAt(1));
     }
     {
-      Node* n = graph.NewNode(binop, p, k);
+      Node* n = CreateBinopNode(p, k);
       MachineOperatorReducer reducer(&jsgraph);
       Reduction reduction = reducer.Reduce(n);
       CHECK(!reduction.Changed());
@@ -191,7 +198,7 @@
     CHECK(!binop->HasProperty(Operator::kCommutative));
     Node* p = Parameter();
     Node* k = Constant<T>(constant);
-    Node* n = graph.NewNode(binop, k, p);
+    Node* n = CreateBinopNode(k, p);
     MachineOperatorReducer reducer(&jsgraph);
     Reduction reduction = reducer.Reduce(n);
     CHECK(!reduction.Changed());
@@ -202,6 +209,15 @@
   Node* Parameter(int32_t index = 0) {
     return graph.NewNode(common.Parameter(index), graph.start());
   }
+
+ private:
+  Node* CreateBinopNode(Node* left, Node* right) {
+    if (binop->ControlInputCount() > 0) {
+      return graph.NewNode(binop, left, right, graph.start());
+    } else {
+      return graph.NewNode(binop, left, right);
+    }
+  }
 };
 
 
@@ -343,7 +359,36 @@
 }
 
 
-TEST(ReduceWord32Equal) {
+static void CheckJsShift(ReducerTester* R) {
+  DCHECK(R->machine.Word32ShiftIsSafe());
+
+  Node* x = R->Parameter(0);
+  Node* y = R->Parameter(1);
+  Node* thirty_one = R->Constant<int32_t>(0x1f);
+  Node* y_and_thirty_one =
+      R->graph.NewNode(R->machine.Word32And(), y, thirty_one);
+
+  // If the underlying machine shift instructions 'and' their right operand
+  // with 0x1f then:  x << (y & 0x1f) => x << y
+  R->CheckFoldBinop(x, y, x, y_and_thirty_one);
+}
+
+
+TEST(ReduceJsShifts) {
+  ReducerTester R(0, MachineOperatorBuilder::kWord32ShiftIsSafe);
+
+  R.binop = R.machine.Word32Shl();
+  CheckJsShift(&R);
+
+  R.binop = R.machine.Word32Shr();
+  CheckJsShift(&R);
+
+  R.binop = R.machine.Word32Sar();
+  CheckJsShift(&R);
+}
+
+
+TEST(Word32Equal) {
   ReducerTester R;
   R.binop = R.machine.Word32Equal();
 
@@ -476,9 +521,9 @@
 }
 
 
-TEST(ReduceInt32UDiv) {
+TEST(ReduceUint32Div) {
   ReducerTester R;
-  R.binop = R.machine.Int32UDiv();
+  R.binop = R.machine.Uint32Div();
 
   FOR_UINT32_INPUTS(pl) {
     FOR_UINT32_INPUTS(pr) {
@@ -529,9 +574,9 @@
 }
 
 
-TEST(ReduceInt32UMod) {
+TEST(ReduceUint32Mod) {
   ReducerTester R;
-  R.binop = R.machine.Int32UMod();
+  R.binop = R.machine.Uint32Mod();
 
   FOR_INT32_INPUTS(pl) {
     FOR_INT32_INPUTS(pr) {
@@ -687,9 +732,9 @@
          pr != nans.end(); ++pr) {
       Node* nan1 = R->Constant<double>(*pl);
       Node* nan2 = R->Constant<double>(*pr);
-      R->CheckBinop(nan1, x, nan1);     // x % NaN => NaN
-      R->CheckBinop(nan1, nan1, x);     // NaN % x => NaN
-      R->CheckBinop(nan1, nan2, nan1);  // NaN % NaN => NaN
+      R->CheckBinop(nan1, x, nan1);     // x op NaN => NaN
+      R->CheckBinop(nan1, nan1, x);     // NaN op x => NaN
+      R->CheckBinop(nan1, nan2, nan1);  // NaN op NaN => NaN
     }
   }
 }
@@ -706,8 +751,15 @@
     }
   }
 
-  FOR_FLOAT64_INPUTS(i) { R.CheckPutConstantOnRight(*i); }
-  // TODO(titzer): CheckNans(&R);
+  FOR_FLOAT64_INPUTS(i) {
+    Double tmp(*i);
+    if (!tmp.IsSpecial() || tmp.IsInfinite()) {
+      // Don't check NaNs as they are reduced more.
+      R.CheckPutConstantOnRight(*i);
+    }
+  }
+
+  CheckNans(&R);
 }
 
 
@@ -721,7 +773,13 @@
       R.CheckFoldBinop<double>(x - y, x, y);
     }
   }
-  // TODO(titzer): CheckNans(&R);
+
+  Node* zero = R.Constant<double>(0.0);
+  Node* x = R.Parameter();
+
+  R.CheckBinop(x, x, zero);  // x - 0.0 => x
+
+  CheckNans(&R);
 }
 
 
@@ -783,6 +841,11 @@
     }
   }
 
+  Node* x = R.Parameter();
+  Node* zero = R.Constant<double>(0.0);
+
+  R.CheckFoldBinop<double>(v8::base::OS::nan_value(), x, zero);
+
   CheckNans(&R);
 }
 
@@ -800,9 +863,9 @@
 // TODO(titzer): test MachineOperatorReducer for Int64Mul
 // TODO(titzer): test MachineOperatorReducer for Int64UMul
 // TODO(titzer): test MachineOperatorReducer for Int64Div
-// TODO(titzer): test MachineOperatorReducer for Int64UDiv
+// TODO(titzer): test MachineOperatorReducer for Uint64Div
 // TODO(titzer): test MachineOperatorReducer for Int64Mod
-// TODO(titzer): test MachineOperatorReducer for Int64UMod
+// TODO(titzer): test MachineOperatorReducer for Uint64Mod
 // TODO(titzer): test MachineOperatorReducer for Int64Neg
 // TODO(titzer): test MachineOperatorReducer for ChangeInt32ToFloat64
 // TODO(titzer): test MachineOperatorReducer for ChangeFloat64ToInt32
diff --git a/test/cctest/compiler/test-node-algorithm.cc b/test/cctest/compiler/test-node-algorithm.cc
index 10f98a6..842d182 100644
--- a/test/cctest/compiler/test-node-algorithm.cc
+++ b/test/cctest/compiler/test-node-algorithm.cc
@@ -8,25 +8,23 @@
 
 #include "graph-tester.h"
 #include "src/compiler/common-operator.h"
-#include "src/compiler/generic-node.h"
-#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/graph-inl.h"
 #include "src/compiler/graph-visualizer.h"
+#include "src/compiler/node.h"
 #include "src/compiler/operator.h"
 
 using namespace v8::internal;
 using namespace v8::internal::compiler;
 
-static SimpleOperator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
-                                     0, 0, "dummy");
+static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
+                               "dummy", 0, 0, 0, 1, 0, 0);
 
 class PreNodeVisitor : public NullNodeVisitor {
  public:
-  GenericGraphVisit::Control Pre(Node* node) {
+  void Pre(Node* node) {
     printf("NODE ID: %d\n", node->id());
     nodes_.push_back(node);
-    return GenericGraphVisit::CONTINUE;
   }
   std::vector<Node*> nodes_;
 };
@@ -34,45 +32,14 @@
 
 class PostNodeVisitor : public NullNodeVisitor {
  public:
-  GenericGraphVisit::Control Post(Node* node) {
+  void Post(Node* node) {
     printf("NODE ID: %d\n", node->id());
     nodes_.push_back(node);
-    return GenericGraphVisit::CONTINUE;
   }
   std::vector<Node*> nodes_;
 };
 
 
-TEST(TestUseNodeVisitEmpty) {
-  GraphWithStartNodeTester graph;
-
-  PreNodeVisitor node_visitor;
-  graph.VisitNodeUsesFromStart(&node_visitor);
-
-  CHECK_EQ(1, static_cast<int>(node_visitor.nodes_.size()));
-}
-
-
-TEST(TestUseNodePreOrderVisitSimple) {
-  GraphWithStartNodeTester graph;
-  Node* n2 = graph.NewNode(&dummy_operator, graph.start());
-  Node* n3 = graph.NewNode(&dummy_operator, n2);
-  Node* n4 = graph.NewNode(&dummy_operator, n2, n3);
-  Node* n5 = graph.NewNode(&dummy_operator, n4, n2);
-  graph.SetEnd(n5);
-
-  PreNodeVisitor node_visitor;
-  graph.VisitNodeUsesFromStart(&node_visitor);
-
-  CHECK_EQ(5, static_cast<int>(node_visitor.nodes_.size()));
-  CHECK(graph.start()->id() == node_visitor.nodes_[0]->id());
-  CHECK(n2->id() == node_visitor.nodes_[1]->id());
-  CHECK(n3->id() == node_visitor.nodes_[2]->id());
-  CHECK(n4->id() == node_visitor.nodes_[3]->id());
-  CHECK(n5->id() == node_visitor.nodes_[4]->id());
-}
-
-
 TEST(TestInputNodePreOrderVisitSimple) {
   GraphWithStartNodeTester graph;
   Node* n2 = graph.NewNode(&dummy_operator, graph.start());
@@ -92,223 +59,6 @@
 }
 
 
-TEST(TestUseNodePostOrderVisitSimple) {
-  GraphWithStartNodeTester graph;
-  Node* n2 = graph.NewNode(&dummy_operator, graph.start());
-  Node* n3 = graph.NewNode(&dummy_operator, graph.start());
-  Node* n4 = graph.NewNode(&dummy_operator, n2);
-  Node* n5 = graph.NewNode(&dummy_operator, n2);
-  Node* n6 = graph.NewNode(&dummy_operator, n2);
-  Node* n7 = graph.NewNode(&dummy_operator, n3);
-  Node* end_dependencies[4] = {n4, n5, n6, n7};
-  Node* n8 = graph.NewNode(&dummy_operator, 4, end_dependencies);
-  graph.SetEnd(n8);
-
-  PostNodeVisitor node_visitor;
-  graph.VisitNodeUsesFromStart(&node_visitor);
-
-  CHECK_EQ(8, static_cast<int>(node_visitor.nodes_.size()));
-  CHECK(graph.end()->id() == node_visitor.nodes_[0]->id());
-  CHECK(n4->id() == node_visitor.nodes_[1]->id());
-  CHECK(n5->id() == node_visitor.nodes_[2]->id());
-  CHECK(n6->id() == node_visitor.nodes_[3]->id());
-  CHECK(n2->id() == node_visitor.nodes_[4]->id());
-  CHECK(n7->id() == node_visitor.nodes_[5]->id());
-  CHECK(n3->id() == node_visitor.nodes_[6]->id());
-  CHECK(graph.start()->id() == node_visitor.nodes_[7]->id());
-}
-
-
-TEST(TestUseNodePostOrderVisitLong) {
-  GraphWithStartNodeTester graph;
-  Node* n2 = graph.NewNode(&dummy_operator, graph.start());
-  Node* n3 = graph.NewNode(&dummy_operator, graph.start());
-  Node* n4 = graph.NewNode(&dummy_operator, n2);
-  Node* n5 = graph.NewNode(&dummy_operator, n2);
-  Node* n6 = graph.NewNode(&dummy_operator, n3);
-  Node* n7 = graph.NewNode(&dummy_operator, n3);
-  Node* n8 = graph.NewNode(&dummy_operator, n5);
-  Node* n9 = graph.NewNode(&dummy_operator, n5);
-  Node* n10 = graph.NewNode(&dummy_operator, n9);
-  Node* n11 = graph.NewNode(&dummy_operator, n9);
-  Node* end_dependencies[6] = {n4, n8, n10, n11, n6, n7};
-  Node* n12 = graph.NewNode(&dummy_operator, 6, end_dependencies);
-  graph.SetEnd(n12);
-
-  PostNodeVisitor node_visitor;
-  graph.VisitNodeUsesFromStart(&node_visitor);
-
-  CHECK_EQ(12, static_cast<int>(node_visitor.nodes_.size()));
-  CHECK(graph.end()->id() == node_visitor.nodes_[0]->id());
-  CHECK(n4->id() == node_visitor.nodes_[1]->id());
-  CHECK(n8->id() == node_visitor.nodes_[2]->id());
-  CHECK(n10->id() == node_visitor.nodes_[3]->id());
-  CHECK(n11->id() == node_visitor.nodes_[4]->id());
-  CHECK(n9->id() == node_visitor.nodes_[5]->id());
-  CHECK(n5->id() == node_visitor.nodes_[6]->id());
-  CHECK(n2->id() == node_visitor.nodes_[7]->id());
-  CHECK(n6->id() == node_visitor.nodes_[8]->id());
-  CHECK(n7->id() == node_visitor.nodes_[9]->id());
-  CHECK(n3->id() == node_visitor.nodes_[10]->id());
-  CHECK(graph.start()->id() == node_visitor.nodes_[11]->id());
-}
-
-
-TEST(TestUseNodePreOrderVisitCycle) {
-  GraphWithStartNodeTester graph;
-  Node* n0 = graph.start_node();
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n2 = graph.NewNode(&dummy_operator, n1);
-  n0->AppendInput(graph.main_zone(), n2);
-  graph.SetStart(n0);
-  graph.SetEnd(n2);
-
-  PreNodeVisitor node_visitor;
-  graph.VisitNodeUsesFromStart(&node_visitor);
-
-  CHECK_EQ(3, static_cast<int>(node_visitor.nodes_.size()));
-  CHECK(n0->id() == node_visitor.nodes_[0]->id());
-  CHECK(n1->id() == node_visitor.nodes_[1]->id());
-  CHECK(n2->id() == node_visitor.nodes_[2]->id());
-}
-
-
-struct ReenterNodeVisitor : NullNodeVisitor {
-  GenericGraphVisit::Control Pre(Node* node) {
-    printf("[%d] PRE NODE: %d\n", static_cast<int>(nodes_.size()), node->id());
-    nodes_.push_back(node->id());
-    int size = static_cast<int>(nodes_.size());
-    switch (node->id()) {
-      case 0:
-        return size < 6 ? GenericGraphVisit::REENTER : GenericGraphVisit::SKIP;
-      case 1:
-        return size < 4 ? GenericGraphVisit::DEFER
-                        : GenericGraphVisit::CONTINUE;
-      default:
-        return GenericGraphVisit::REENTER;
-    }
-  }
-
-  GenericGraphVisit::Control Post(Node* node) {
-    printf("[%d] POST NODE: %d\n", static_cast<int>(nodes_.size()), node->id());
-    nodes_.push_back(-node->id());
-    return node->id() == 4 ? GenericGraphVisit::REENTER
-                           : GenericGraphVisit::CONTINUE;
-  }
-
-  void PreEdge(Node* from, int index, Node* to) {
-    printf("[%d] PRE EDGE: %d-%d\n", static_cast<int>(edges_.size()),
-           from->id(), to->id());
-    edges_.push_back(std::make_pair(from->id(), to->id()));
-  }
-
-  void PostEdge(Node* from, int index, Node* to) {
-    printf("[%d] POST EDGE: %d-%d\n", static_cast<int>(edges_.size()),
-           from->id(), to->id());
-    edges_.push_back(std::make_pair(-from->id(), -to->id()));
-  }
-
-  std::vector<int> nodes_;
-  std::vector<std::pair<int, int> > edges_;
-};
-
-
-TEST(TestUseNodeReenterVisit) {
-  GraphWithStartNodeTester graph;
-  Node* n0 = graph.start_node();
-  Node* n1 = graph.NewNode(&dummy_operator, n0);
-  Node* n2 = graph.NewNode(&dummy_operator, n0);
-  Node* n3 = graph.NewNode(&dummy_operator, n2);
-  Node* n4 = graph.NewNode(&dummy_operator, n0);
-  Node* n5 = graph.NewNode(&dummy_operator, n4);
-  n0->AppendInput(graph.main_zone(), n3);
-  graph.SetStart(n0);
-  graph.SetEnd(n5);
-
-  ReenterNodeVisitor visitor;
-  graph.VisitNodeUsesFromStart(&visitor);
-
-  CHECK_EQ(22, static_cast<int>(visitor.nodes_.size()));
-  CHECK_EQ(24, static_cast<int>(visitor.edges_.size()));
-
-  CHECK(n0->id() == visitor.nodes_[0]);
-  CHECK(n0->id() == visitor.edges_[0].first);
-  CHECK(n1->id() == visitor.edges_[0].second);
-  CHECK(n1->id() == visitor.nodes_[1]);
-  // N1 is deferred.
-  CHECK(-n1->id() == visitor.edges_[1].second);
-  CHECK(-n0->id() == visitor.edges_[1].first);
-  CHECK(n0->id() == visitor.edges_[2].first);
-  CHECK(n2->id() == visitor.edges_[2].second);
-  CHECK(n2->id() == visitor.nodes_[2]);
-  CHECK(n2->id() == visitor.edges_[3].first);
-  CHECK(n3->id() == visitor.edges_[3].second);
-  CHECK(n3->id() == visitor.nodes_[3]);
-  // Circle back to N0, which we may reenter for now.
-  CHECK(n3->id() == visitor.edges_[4].first);
-  CHECK(n0->id() == visitor.edges_[4].second);
-  CHECK(n0->id() == visitor.nodes_[4]);
-  CHECK(n0->id() == visitor.edges_[5].first);
-  CHECK(n1->id() == visitor.edges_[5].second);
-  CHECK(n1->id() == visitor.nodes_[5]);
-  // This time N1 is no longer deferred.
-  CHECK(-n1->id() == visitor.nodes_[6]);
-  CHECK(-n1->id() == visitor.edges_[6].second);
-  CHECK(-n0->id() == visitor.edges_[6].first);
-  CHECK(n0->id() == visitor.edges_[7].first);
-  CHECK(n2->id() == visitor.edges_[7].second);
-  CHECK(n2->id() == visitor.nodes_[7]);
-  CHECK(n2->id() == visitor.edges_[8].first);
-  CHECK(n3->id() == visitor.edges_[8].second);
-  CHECK(n3->id() == visitor.nodes_[8]);
-  CHECK(n3->id() == visitor.edges_[9].first);
-  CHECK(n0->id() == visitor.edges_[9].second);
-  CHECK(n0->id() == visitor.nodes_[9]);
-  // This time we break at N0 and skip it.
-  CHECK(-n0->id() == visitor.edges_[10].second);
-  CHECK(-n3->id() == visitor.edges_[10].first);
-  CHECK(-n3->id() == visitor.nodes_[10]);
-  CHECK(-n3->id() == visitor.edges_[11].second);
-  CHECK(-n2->id() == visitor.edges_[11].first);
-  CHECK(-n2->id() == visitor.nodes_[11]);
-  CHECK(-n2->id() == visitor.edges_[12].second);
-  CHECK(-n0->id() == visitor.edges_[12].first);
-  CHECK(n0->id() == visitor.edges_[13].first);
-  CHECK(n4->id() == visitor.edges_[13].second);
-  CHECK(n4->id() == visitor.nodes_[12]);
-  CHECK(n4->id() == visitor.edges_[14].first);
-  CHECK(n5->id() == visitor.edges_[14].second);
-  CHECK(n5->id() == visitor.nodes_[13]);
-  CHECK(-n5->id() == visitor.nodes_[14]);
-  CHECK(-n5->id() == visitor.edges_[15].second);
-  CHECK(-n4->id() == visitor.edges_[15].first);
-  CHECK(-n4->id() == visitor.nodes_[15]);
-  CHECK(-n4->id() == visitor.edges_[16].second);
-  CHECK(-n0->id() == visitor.edges_[16].first);
-  CHECK(-n0->id() == visitor.nodes_[16]);
-  CHECK(-n0->id() == visitor.edges_[17].second);
-  CHECK(-n3->id() == visitor.edges_[17].first);
-  CHECK(-n3->id() == visitor.nodes_[17]);
-  CHECK(-n3->id() == visitor.edges_[18].second);
-  CHECK(-n2->id() == visitor.edges_[18].first);
-  CHECK(-n2->id() == visitor.nodes_[18]);
-  CHECK(-n2->id() == visitor.edges_[19].second);
-  CHECK(-n0->id() == visitor.edges_[19].first);
-  // N4 may be reentered.
-  CHECK(n0->id() == visitor.edges_[20].first);
-  CHECK(n4->id() == visitor.edges_[20].second);
-  CHECK(n4->id() == visitor.nodes_[19]);
-  CHECK(n4->id() == visitor.edges_[21].first);
-  CHECK(n5->id() == visitor.edges_[21].second);
-  CHECK(-n5->id() == visitor.edges_[22].second);
-  CHECK(-n4->id() == visitor.edges_[22].first);
-  CHECK(-n4->id() == visitor.nodes_[20]);
-  CHECK(-n4->id() == visitor.edges_[23].second);
-  CHECK(-n0->id() == visitor.edges_[23].first);
-  CHECK(-n0->id() == visitor.nodes_[21]);
-}
-
-
 TEST(TestPrintNodeGraphToNodeGraphviz) {
   GraphWithStartNodeTester graph;
   Node* n2 = graph.NewNode(&dummy_operator, graph.start());
diff --git a/test/cctest/compiler/test-node-cache.cc b/test/cctest/compiler/test-node-cache.cc
index 3569386..a48adb9 100644
--- a/test/cctest/compiler/test-node-cache.cc
+++ b/test/cctest/compiler/test-node-cache.cc
@@ -115,46 +115,61 @@
 }
 
 
-TEST(PtrConstant_back_to_back) {
-  GraphTester graph;
-  PtrNodeCache cache;
-  int32_t buffer[50];
+static bool Contains(NodeVector* nodes, Node* n) {
+  for (size_t i = 0; i < nodes->size(); i++) {
+    if (nodes->at(i) == n) return true;
+  }
+  return false;
+}
 
-  for (int32_t* p = buffer;
-       (p - buffer) < static_cast<ptrdiff_t>(arraysize(buffer)); p++) {
-    Node** pos = cache.Find(graph.zone(), p);
-    CHECK_NE(NULL, pos);
-    for (int j = 0; j < 3; j++) {
-      Node** npos = cache.Find(graph.zone(), p);
-      CHECK_EQ(pos, npos);
+
+TEST(NodeCache_GetCachedNodes_int32) {
+  GraphTester graph;
+  Int32NodeCache cache;
+  CommonOperatorBuilder common(graph.zone());
+
+  int32_t constants[] = {0, 311, 12,  13,  14,  555, -555, -44, -33, -22, -11,
+                         0, 311, 311, 412, 412, 11,  11,   -33, -33, -22, -11};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    int32_t k = constants[i];
+    Node** pos = cache.Find(graph.zone(), k);
+    if (*pos != NULL) {
+      NodeVector nodes(graph.zone());
+      cache.GetCachedNodes(&nodes);
+      CHECK(Contains(&nodes, *pos));
+    } else {
+      NodeVector nodes(graph.zone());
+      Node* n = graph.NewNode(common.Int32Constant(k));
+      *pos = n;
+      cache.GetCachedNodes(&nodes);
+      CHECK(Contains(&nodes, n));
     }
   }
 }
 
 
-TEST(PtrConstant_hits) {
+TEST(NodeCache_GetCachedNodes_int64) {
   GraphTester graph;
-  PtrNodeCache cache;
-  const int32_t kSize = 50;
-  int32_t buffer[kSize];
-  Node* nodes[kSize];
+  Int64NodeCache cache;
   CommonOperatorBuilder common(graph.zone());
 
-  for (size_t i = 0; i < arraysize(buffer); i++) {
-    int k = static_cast<int>(i);
-    int32_t* p = &buffer[i];
-    nodes[i] = graph.NewNode(common.Int32Constant(k));
-    *cache.Find(graph.zone(), p) = nodes[i];
-  }
+  int64_t constants[] = {0, 311, 12,  13,  14,  555, -555, -44, -33, -22, -11,
+                         0, 311, 311, 412, 412, 11,  11,   -33, -33, -22, -11};
 
-  int hits = 0;
-  for (size_t i = 0; i < arraysize(buffer); i++) {
-    int32_t* p = &buffer[i];
-    Node** pos = cache.Find(graph.zone(), p);
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    int64_t k = constants[i];
+    Node** pos = cache.Find(graph.zone(), k);
     if (*pos != NULL) {
-      CHECK_EQ(nodes[i], *pos);
-      hits++;
+      NodeVector nodes(graph.zone());
+      cache.GetCachedNodes(&nodes);
+      CHECK(Contains(&nodes, *pos));
+    } else {
+      NodeVector nodes(graph.zone());
+      Node* n = graph.NewNode(common.Int64Constant(k));
+      *pos = n;
+      cache.GetCachedNodes(&nodes);
+      CHECK(Contains(&nodes, n));
     }
   }
-  CHECK_LT(4, hits);
 }
diff --git a/test/cctest/compiler/test-node.cc b/test/cctest/compiler/test-node.cc
index 28d807e..eafabd3 100644
--- a/test/cctest/compiler/test-node.cc
+++ b/test/cctest/compiler/test-node.cc
@@ -7,15 +7,14 @@
 #include "src/v8.h"
 
 #include "graph-tester.h"
-#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/node.h"
 #include "src/compiler/operator.h"
 
 using namespace v8::internal;
 using namespace v8::internal::compiler;
 
-static SimpleOperator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
-                                     0, 0, "dummy");
+static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
+                               "dummy", 0, 0, 0, 1, 0, 0);
 
 TEST(NodeAllocation) {
   GraphTester graph;
@@ -93,10 +92,8 @@
 TEST(NodeUseIteratorEmpty) {
   GraphTester graph;
   Node* n1 = graph.NewNode(&dummy_operator);
-  Node::Uses::iterator i(n1->uses().begin());
   int use_count = 0;
-  for (; i != n1->uses().end(); ++i) {
-    Node::Edge edge(i.edge());
+  for (Edge const edge : n1->use_edges()) {
     USE(edge);
     use_count++;
   }
@@ -366,31 +363,31 @@
   Node* n1 = graph.NewNode(&dummy_operator, n0);
   Node* n2 = graph.NewNode(&dummy_operator, n0, n1);
 
-  Node::Inputs inputs(n2->inputs());
-  Node::Inputs::iterator current = inputs.begin();
+  Node::InputEdges inputs(n2->input_edges());
+  Node::InputEdges::iterator current = inputs.begin();
   CHECK(current != inputs.end());
-  CHECK(*current == n0);
+  CHECK((*current).to() == n0);
   ++current;
   CHECK(current != inputs.end());
-  CHECK(*current == n1);
+  CHECK((*current).to() == n1);
   ++current;
   CHECK(current == inputs.end());
 
   Node* n3 = graph.NewNode(&dummy_operator);
   n2->AppendInput(graph.zone(), n3);
-  inputs = n2->inputs();
+  inputs = n2->input_edges();
   current = inputs.begin();
   CHECK(current != inputs.end());
-  CHECK(*current == n0);
-  CHECK_EQ(0, current.index());
+  CHECK((*current).to() == n0);
+  CHECK_EQ(0, (*current).index());
   ++current;
   CHECK(current != inputs.end());
-  CHECK(*current == n1);
-  CHECK_EQ(1, current.index());
+  CHECK((*current).to() == n1);
+  CHECK_EQ(1, (*current).index());
   ++current;
   CHECK(current != inputs.end());
-  CHECK(*current == n3);
-  CHECK_EQ(2, current.index());
+  CHECK((*current).to() == n3);
+  CHECK_EQ(2, (*current).index());
   ++current;
   CHECK(current == inputs.end());
 }
diff --git a/test/cctest/compiler/test-operator.cc b/test/cctest/compiler/test-operator.cc
index af75d67..39f660f 100644
--- a/test/cctest/compiler/test-operator.cc
+++ b/test/cctest/compiler/test-operator.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <sstream>
+
 #include "src/v8.h"
 
 #include "src/compiler/operator.h"
@@ -10,44 +12,45 @@
 using namespace v8::internal;
 using namespace v8::internal::compiler;
 
-#define NaN (v8::base::OS::nan_value())
-#define Infinity (std::numeric_limits<double>::infinity())
+#define NONE Operator::kNoProperties
+#define FOLD Operator::kFoldable
 
-TEST(TestOperatorMnemonic) {
-  SimpleOperator op1(10, Operator::kNoProperties, 0, 0, "ThisOne");
+
+TEST(TestOperator_Mnemonic) {
+  Operator op1(10, NONE, "ThisOne", 0, 0, 0, 0, 0, 0);
   CHECK_EQ(0, strcmp(op1.mnemonic(), "ThisOne"));
 
-  SimpleOperator op2(11, Operator::kNoProperties, 0, 0, "ThatOne");
+  Operator op2(11, NONE, "ThatOne", 0, 0, 0, 0, 0, 0);
   CHECK_EQ(0, strcmp(op2.mnemonic(), "ThatOne"));
 
-  Operator1<int> op3(12, Operator::kNoProperties, 0, 1, "Mnemonic1", 12333);
+  Operator1<int> op3(12, NONE, "Mnemonic1", 0, 0, 0, 1, 0, 0, 12333);
   CHECK_EQ(0, strcmp(op3.mnemonic(), "Mnemonic1"));
 
-  Operator1<double> op4(13, Operator::kNoProperties, 0, 1, "TheOther", 99.9);
+  Operator1<double> op4(13, NONE, "TheOther", 0, 0, 0, 1, 0, 0, 99.9);
   CHECK_EQ(0, strcmp(op4.mnemonic(), "TheOther"));
 }
 
 
-TEST(TestSimpleOperatorHash) {
-  SimpleOperator op1(17, Operator::kNoProperties, 0, 0, "Another");
-  CHECK_EQ(17, op1.HashCode());
+TEST(TestOperator_Hash) {
+  Operator op1(17, NONE, "Another", 0, 0, 0, 0, 0, 0);
+  CHECK_EQ(17, static_cast<int>(op1.HashCode()));
 
-  SimpleOperator op2(18, Operator::kNoProperties, 0, 0, "Falsch");
-  CHECK_EQ(18, op2.HashCode());
+  Operator op2(18, NONE, "Falsch", 0, 0, 0, 0, 0, 0);
+  CHECK_EQ(18, static_cast<int>(op2.HashCode()));
 }
 
 
-TEST(TestSimpleOperatorEquals) {
-  SimpleOperator op1a(19, Operator::kNoProperties, 0, 0, "Another1");
-  SimpleOperator op1b(19, Operator::kFoldable, 2, 2, "Another2");
+TEST(TestOperator_Equals) {
+  Operator op1a(19, NONE, "Another1", 0, 0, 0, 0, 0, 0);
+  Operator op1b(19, FOLD, "Another2", 2, 0, 0, 2, 0, 0);
 
   CHECK(op1a.Equals(&op1a));
   CHECK(op1a.Equals(&op1b));
   CHECK(op1b.Equals(&op1a));
   CHECK(op1b.Equals(&op1b));
 
-  SimpleOperator op2a(20, Operator::kNoProperties, 0, 0, "Falsch1");
-  SimpleOperator op2b(20, Operator::kFoldable, 1, 1, "Falsch2");
+  Operator op2a(20, NONE, "Falsch1", 0, 0, 0, 0, 0, 0);
+  Operator op2b(20, FOLD, "Falsch2", 1, 0, 0, 1, 0, 0);
 
   CHECK(op2a.Equals(&op2a));
   CHECK(op2a.Equals(&op2b));
@@ -67,52 +70,52 @@
 
 
 static SmartArrayPointer<const char> OperatorToString(Operator* op) {
-  OStringStream os;
+  std::ostringstream os;
   os << *op;
-  return SmartArrayPointer<const char>(StrDup(os.c_str()));
+  return SmartArrayPointer<const char>(StrDup(os.str().c_str()));
 }
 
 
-TEST(TestSimpleOperatorPrint) {
-  SimpleOperator op1a(19, Operator::kNoProperties, 0, 0, "Another1");
-  SimpleOperator op1b(19, Operator::kFoldable, 2, 2, "Another2");
+TEST(TestOperator_Print) {
+  Operator op1a(19, NONE, "Another1", 0, 0, 0, 0, 0, 0);
+  Operator op1b(19, FOLD, "Another2", 2, 0, 0, 2, 0, 0);
 
   CHECK_EQ("Another1", OperatorToString(&op1a).get());
   CHECK_EQ("Another2", OperatorToString(&op1b).get());
 
-  SimpleOperator op2a(20, Operator::kNoProperties, 0, 0, "Flog1");
-  SimpleOperator op2b(20, Operator::kFoldable, 1, 1, "Flog2");
+  Operator op2a(20, NONE, "Flog1", 0, 0, 0, 0, 0, 0);
+  Operator op2b(20, FOLD, "Flog2", 1, 0, 0, 1, 0, 0);
 
   CHECK_EQ("Flog1", OperatorToString(&op2a).get());
   CHECK_EQ("Flog2", OperatorToString(&op2b).get());
 }
 
 
-TEST(TestOperator1intHash) {
-  Operator1<int> op1a(23, Operator::kNoProperties, 0, 0, "Wolfie", 11);
-  Operator1<int> op1b(23, Operator::kFoldable, 2, 2, "Doggie", 11);
+TEST(TestOperator1int_Hash) {
+  Operator1<int> op1a(23, NONE, "Wolfie", 0, 0, 0, 0, 0, 0, 11);
+  Operator1<int> op1b(23, FOLD, "Doggie", 2, 0, 0, 2, 0, 0, 11);
 
-  CHECK_EQ(op1a.HashCode(), op1b.HashCode());
+  CHECK(op1a.HashCode() == op1b.HashCode());
 
-  Operator1<int> op2a(24, Operator::kNoProperties, 0, 0, "Arfie", 3);
-  Operator1<int> op2b(24, Operator::kNoProperties, 0, 0, "Arfie", 4);
+  Operator1<int> op2a(24, NONE, "Arfie", 0, 0, 0, 0, 0, 0, 3);
+  Operator1<int> op2b(24, NONE, "Arfie", 0, 0, 0, 0, 0, 0, 4);
 
-  CHECK_NE(op1a.HashCode(), op2a.HashCode());
-  CHECK_NE(op2a.HashCode(), op2b.HashCode());
+  CHECK(op1a.HashCode() != op2a.HashCode());
+  CHECK(op2a.HashCode() != op2b.HashCode());
 }
 
 
-TEST(TestOperator1intEquals) {
-  Operator1<int> op1a(23, Operator::kNoProperties, 0, 0, "Scratchy", 11);
-  Operator1<int> op1b(23, Operator::kFoldable, 2, 2, "Scratchy", 11);
+TEST(TestOperator1int_Equals) {
+  Operator1<int> op1a(23, NONE, "Scratchy", 0, 0, 0, 0, 0, 0, 11);
+  Operator1<int> op1b(23, FOLD, "Scratchy", 2, 0, 0, 2, 0, 0, 11);
 
   CHECK(op1a.Equals(&op1a));
   CHECK(op1a.Equals(&op1b));
   CHECK(op1b.Equals(&op1a));
   CHECK(op1b.Equals(&op1b));
 
-  Operator1<int> op2a(24, Operator::kNoProperties, 0, 0, "Im", 3);
-  Operator1<int> op2b(24, Operator::kNoProperties, 0, 0, "Im", 4);
+  Operator1<int> op2a(24, NONE, "Im", 0, 0, 0, 0, 0, 0, 3);
+  Operator1<int> op2b(24, NONE, "Im", 0, 0, 0, 0, 0, 0, 4);
 
   CHECK(op2a.Equals(&op2a));
   CHECK(!op2a.Equals(&op2b));
@@ -129,7 +132,7 @@
   CHECK(!op2b.Equals(&op1a));
   CHECK(!op2b.Equals(&op1b));
 
-  SimpleOperator op3(25, Operator::kNoProperties, 0, 0, "Weepy");
+  Operator op3(25, NONE, "Weepy", 0, 0, 0, 0, 0, 0);
 
   CHECK(!op1a.Equals(&op3));
   CHECK(!op1b.Equals(&op3));
@@ -143,46 +146,55 @@
 }
 
 
-TEST(TestOperator1intPrint) {
-  Operator1<int> op1(12, Operator::kNoProperties, 0, 1, "Op1Test", 0);
+TEST(TestOperator1int_Print) {
+  Operator1<int> op1(12, NONE, "Op1Test", 0, 0, 0, 1, 0, 0, 0);
   CHECK_EQ("Op1Test[0]", OperatorToString(&op1).get());
 
-  Operator1<int> op2(12, Operator::kNoProperties, 0, 1, "Op1Test", 66666666);
+  Operator1<int> op2(12, NONE, "Op1Test", 0, 0, 0, 1, 0, 0, 66666666);
   CHECK_EQ("Op1Test[66666666]", OperatorToString(&op2).get());
 
-  Operator1<int> op3(12, Operator::kNoProperties, 0, 1, "FooBar", 2347);
+  Operator1<int> op3(12, NONE, "FooBar", 0, 0, 0, 1, 0, 0, 2347);
   CHECK_EQ("FooBar[2347]", OperatorToString(&op3).get());
 
-  Operator1<int> op4(12, Operator::kNoProperties, 0, 1, "BarFoo", -879);
+  Operator1<int> op4(12, NONE, "BarFoo", 0, 0, 0, 1, 0, 0, -879);
   CHECK_EQ("BarFoo[-879]", OperatorToString(&op4).get());
 }
 
 
-TEST(TestOperator1doubleHash) {
-  Operator1<double> op1a(23, Operator::kNoProperties, 0, 0, "Wolfie", 11.77);
-  Operator1<double> op1b(23, Operator::kFoldable, 2, 2, "Doggie", 11.77);
+TEST(TestOperator1double_Hash) {
+  Operator1<double> op1a(23, NONE, "Wolfie", 0, 0, 0, 0, 0, 0, 11.77);
+  Operator1<double> op1b(23, FOLD, "Doggie", 2, 0, 0, 2, 0, 0, 11.77);
 
-  CHECK_EQ(op1a.HashCode(), op1b.HashCode());
+  CHECK(op1a.HashCode() == op1b.HashCode());
 
-  Operator1<double> op2a(24, Operator::kNoProperties, 0, 0, "Arfie", -6.7);
-  Operator1<double> op2b(24, Operator::kNoProperties, 0, 0, "Arfie", -6.8);
+  Operator1<double> op2a(24, NONE, "Arfie", 0, 0, 0, 0, 0, 0, -6.7);
+  Operator1<double> op2b(24, NONE, "Arfie", 0, 0, 0, 0, 0, 0, -6.8);
 
-  CHECK_NE(op1a.HashCode(), op2a.HashCode());
-  CHECK_NE(op2a.HashCode(), op2b.HashCode());
+  CHECK(op1a.HashCode() != op2a.HashCode());
+  CHECK(op2a.HashCode() != op2b.HashCode());
 }
 
 
-TEST(TestOperator1doubleEquals) {
-  Operator1<double> op1a(23, Operator::kNoProperties, 0, 0, "Scratchy", 11.77);
-  Operator1<double> op1b(23, Operator::kFoldable, 2, 2, "Scratchy", 11.77);
+TEST(TestOperator1doublePrint) {
+  Operator1<double> op1a(23, NONE, "Canary", 0, 0, 0, 0, 0, 0, 0.5);
+  Operator1<double> op1b(23, FOLD, "Finch", 2, 0, 0, 2, 0, 0, -1.5);
+
+  CHECK_EQ("Canary[0.5]", OperatorToString(&op1a).get());
+  CHECK_EQ("Finch[-1.5]", OperatorToString(&op1b).get());
+}
+
+
+TEST(TestOperator1double_Equals) {
+  Operator1<double> op1a(23, NONE, "Scratchy", 0, 0, 0, 0, 0, 0, 11.77);
+  Operator1<double> op1b(23, FOLD, "Scratchy", 2, 0, 0, 2, 0, 0, 11.77);
 
   CHECK(op1a.Equals(&op1a));
   CHECK(op1a.Equals(&op1b));
   CHECK(op1b.Equals(&op1a));
   CHECK(op1b.Equals(&op1b));
 
-  Operator1<double> op2a(24, Operator::kNoProperties, 0, 0, "Im", 3.1);
-  Operator1<double> op2b(24, Operator::kNoProperties, 0, 0, "Im", 3.2);
+  Operator1<double> op2a(24, NONE, "Im", 0, 0, 0, 0, 0, 0, 3.1);
+  Operator1<double> op2b(24, NONE, "Im", 0, 0, 0, 0, 0, 0, 3.2);
 
   CHECK(op2a.Equals(&op2a));
   CHECK(!op2a.Equals(&op2b));
@@ -199,7 +211,7 @@
   CHECK(!op2b.Equals(&op1a));
   CHECK(!op2b.Equals(&op1b));
 
-  SimpleOperator op3(25, Operator::kNoProperties, 0, 0, "Weepy");
+  Operator op3(25, NONE, "Weepy", 0, 0, 0, 0, 0, 0);
 
   CHECK(!op1a.Equals(&op3));
   CHECK(!op1b.Equals(&op3));
@@ -211,8 +223,8 @@
   CHECK(!op3.Equals(&op2a));
   CHECK(!op3.Equals(&op2b));
 
-  Operator1<double> op4a(24, Operator::kNoProperties, 0, 0, "Bashful", NaN);
-  Operator1<double> op4b(24, Operator::kNoProperties, 0, 0, "Bashful", NaN);
+  Operator1<double> op4a(24, NONE, "Bashful", 0, 0, 0, 0, 0, 0, 1.0);
+  Operator1<double> op4b(24, NONE, "Bashful", 0, 0, 0, 0, 0, 0, 1.0);
 
   CHECK(op4a.Equals(&op4a));
   CHECK(op4a.Equals(&op4b));
@@ -226,19 +238,46 @@
 }
 
 
-TEST(TestOperator1doublePrint) {
-  Operator1<double> op1(12, Operator::kNoProperties, 0, 1, "Op1Test", 0);
-  CHECK_EQ("Op1Test[0]", OperatorToString(&op1).get());
+TEST(TestOpParameter_Operator1double) {
+  double values[] = {7777.5, -66, 0, 11, 0.1};
 
-  Operator1<double> op2(12, Operator::kNoProperties, 0, 1, "Op1Test", 7.3);
-  CHECK_EQ("Op1Test[7.3]", OperatorToString(&op2).get());
+  for (size_t i = 0; i < arraysize(values); i++) {
+    Operator1<double> op(33, NONE, "Scurvy", 0, 0, 0, 0, 0, 0, values[i]);
+    CHECK_EQ(values[i], OpParameter<double>(&op));
+  }
+}
 
-  Operator1<double> op3(12, Operator::kNoProperties, 0, 1, "FooBar", 2e+123);
-  CHECK_EQ("FooBar[2e+123]", OperatorToString(&op3).get());
 
-  Operator1<double> op4(12, Operator::kNoProperties, 0, 1, "BarFoo", Infinity);
-  CHECK_EQ("BarFoo[inf]", OperatorToString(&op4).get());
+TEST(TestOpParameter_Operator1float) {
+  float values[] = {// thanks C++.
+                    static_cast<float>(7777.5), static_cast<float>(-66),
+                    static_cast<float>(0), static_cast<float>(11),
+                    static_cast<float>(0.1)};
 
-  Operator1<double> op5(12, Operator::kNoProperties, 0, 1, "BarFoo", NaN);
-  CHECK_EQ("BarFoo[nan]", OperatorToString(&op5).get());
+  for (size_t i = 0; i < arraysize(values); i++) {
+    Operator1<float> op(33, NONE, "Scurvy", 0, 0, 0, 0, 0, 0, values[i]);
+    CHECK_EQ(values[i], OpParameter<float>(&op));
+  }
+}
+
+
+TEST(TestOpParameter_Operator1int) {
+  int values[] = {7777, -66, 0, 11, 1, 0x666aff};
+
+  for (size_t i = 0; i < arraysize(values); i++) {
+    Operator1<int> op(33, NONE, "Scurvy", 0, 0, 0, 0, 0, 0, values[i]);
+    CHECK_EQ(values[i], OpParameter<int>(&op));
+  }
+}
+
+
+TEST(Operator_CountsOrder) {
+  Operator op(29, NONE, "Flashy", 11, 22, 33, 44, 55, 66);
+  CHECK_EQ(11, op.ValueInputCount());
+  CHECK_EQ(22, op.EffectInputCount());
+  CHECK_EQ(33, op.ControlInputCount());
+
+  CHECK_EQ(44, op.ValueOutputCount());
+  CHECK_EQ(55, op.EffectOutputCount());
+  CHECK_EQ(66, op.ControlOutputCount());
 }
diff --git a/test/cctest/compiler/test-phi-reducer.cc b/test/cctest/compiler/test-phi-reducer.cc
deleted file mode 100644
index 7d2fab6..0000000
--- a/test/cctest/compiler/test-phi-reducer.cc
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/v8.h"
-#include "test/cctest/cctest.h"
-
-#include "src/compiler/common-operator.h"
-#include "src/compiler/graph-inl.h"
-#include "src/compiler/phi-reducer.h"
-
-using namespace v8::internal;
-using namespace v8::internal::compiler;
-
-class PhiReducerTester : HandleAndZoneScope {
- public:
-  explicit PhiReducerTester(int num_parameters = 0)
-      : isolate(main_isolate()),
-        common(main_zone()),
-        graph(main_zone()),
-        self(graph.NewNode(common.Start(num_parameters))),
-        dead(graph.NewNode(common.Dead())) {
-    graph.SetStart(self);
-  }
-
-  Isolate* isolate;
-  CommonOperatorBuilder common;
-  Graph graph;
-  Node* self;
-  Node* dead;
-
-  void CheckReduce(Node* expect, Node* phi) {
-    PhiReducer reducer;
-    Reduction reduction = reducer.Reduce(phi);
-    if (expect == phi) {
-      CHECK(!reduction.Changed());
-    } else {
-      CHECK(reduction.Changed());
-      CHECK_EQ(expect, reduction.replacement());
-    }
-  }
-
-  Node* Int32Constant(int32_t val) {
-    return graph.NewNode(common.Int32Constant(val));
-  }
-
-  Node* Float64Constant(double val) {
-    return graph.NewNode(common.Float64Constant(val));
-  }
-
-  Node* Parameter(int32_t index = 0) {
-    return graph.NewNode(common.Parameter(index), graph.start());
-  }
-
-  Node* Phi(Node* a) {
-    return SetSelfReferences(graph.NewNode(common.Phi(kMachAnyTagged, 1), a));
-  }
-
-  Node* Phi(Node* a, Node* b) {
-    return SetSelfReferences(
-        graph.NewNode(common.Phi(kMachAnyTagged, 2), a, b));
-  }
-
-  Node* Phi(Node* a, Node* b, Node* c) {
-    return SetSelfReferences(
-        graph.NewNode(common.Phi(kMachAnyTagged, 3), a, b, c));
-  }
-
-  Node* Phi(Node* a, Node* b, Node* c, Node* d) {
-    return SetSelfReferences(
-        graph.NewNode(common.Phi(kMachAnyTagged, 4), a, b, c, d));
-  }
-
-  Node* PhiWithControl(Node* a, Node* control) {
-    return SetSelfReferences(
-        graph.NewNode(common.Phi(kMachAnyTagged, 1), a, control));
-  }
-
-  Node* PhiWithControl(Node* a, Node* b, Node* control) {
-    return SetSelfReferences(
-        graph.NewNode(common.Phi(kMachAnyTagged, 2), a, b, control));
-  }
-
-  Node* SetSelfReferences(Node* node) {
-    Node::Inputs inputs = node->inputs();
-    for (Node::Inputs::iterator iter(inputs.begin()); iter != inputs.end();
-         ++iter) {
-      Node* input = *iter;
-      if (input == self) node->ReplaceInput(iter.index(), node);
-    }
-    return node;
-  }
-};
-
-
-TEST(PhiReduce1) {
-  PhiReducerTester R;
-  Node* zero = R.Int32Constant(0);
-  Node* one = R.Int32Constant(1);
-  Node* oneish = R.Float64Constant(1.1);
-  Node* param = R.Parameter();
-
-  Node* singles[] = {zero, one, oneish, param};
-  for (size_t i = 0; i < arraysize(singles); i++) {
-    R.CheckReduce(singles[i], R.Phi(singles[i]));
-  }
-}
-
-
-TEST(PhiReduce2) {
-  PhiReducerTester R;
-  Node* zero = R.Int32Constant(0);
-  Node* one = R.Int32Constant(1);
-  Node* oneish = R.Float64Constant(1.1);
-  Node* param = R.Parameter();
-
-  Node* singles[] = {zero, one, oneish, param};
-  for (size_t i = 0; i < arraysize(singles); i++) {
-    Node* a = singles[i];
-    R.CheckReduce(a, R.Phi(a, a));
-  }
-
-  for (size_t i = 0; i < arraysize(singles); i++) {
-    Node* a = singles[i];
-    R.CheckReduce(a, R.Phi(R.self, a));
-    R.CheckReduce(a, R.Phi(a, R.self));
-  }
-
-  for (size_t i = 1; i < arraysize(singles); i++) {
-    Node* a = singles[i], *b = singles[0];
-    Node* phi1 = R.Phi(b, a);
-    R.CheckReduce(phi1, phi1);
-
-    Node* phi2 = R.Phi(a, b);
-    R.CheckReduce(phi2, phi2);
-  }
-}
-
-
-TEST(PhiReduce3) {
-  PhiReducerTester R;
-  Node* zero = R.Int32Constant(0);
-  Node* one = R.Int32Constant(1);
-  Node* oneish = R.Float64Constant(1.1);
-  Node* param = R.Parameter();
-
-  Node* singles[] = {zero, one, oneish, param};
-  for (size_t i = 0; i < arraysize(singles); i++) {
-    Node* a = singles[i];
-    R.CheckReduce(a, R.Phi(a, a, a));
-  }
-
-  for (size_t i = 0; i < arraysize(singles); i++) {
-    Node* a = singles[i];
-    R.CheckReduce(a, R.Phi(R.self, a, a));
-    R.CheckReduce(a, R.Phi(a, R.self, a));
-    R.CheckReduce(a, R.Phi(a, a, R.self));
-  }
-
-  for (size_t i = 1; i < arraysize(singles); i++) {
-    Node* a = singles[i], *b = singles[0];
-    Node* phi1 = R.Phi(b, a, a);
-    R.CheckReduce(phi1, phi1);
-
-    Node* phi2 = R.Phi(a, b, a);
-    R.CheckReduce(phi2, phi2);
-
-    Node* phi3 = R.Phi(a, a, b);
-    R.CheckReduce(phi3, phi3);
-  }
-}
-
-
-TEST(PhiReduce4) {
-  PhiReducerTester R;
-  Node* zero = R.Int32Constant(0);
-  Node* one = R.Int32Constant(1);
-  Node* oneish = R.Float64Constant(1.1);
-  Node* param = R.Parameter();
-
-  Node* singles[] = {zero, one, oneish, param};
-  for (size_t i = 0; i < arraysize(singles); i++) {
-    Node* a = singles[i];
-    R.CheckReduce(a, R.Phi(a, a, a, a));
-  }
-
-  for (size_t i = 0; i < arraysize(singles); i++) {
-    Node* a = singles[i];
-    R.CheckReduce(a, R.Phi(R.self, a, a, a));
-    R.CheckReduce(a, R.Phi(a, R.self, a, a));
-    R.CheckReduce(a, R.Phi(a, a, R.self, a));
-    R.CheckReduce(a, R.Phi(a, a, a, R.self));
-
-    R.CheckReduce(a, R.Phi(R.self, R.self, a, a));
-    R.CheckReduce(a, R.Phi(a, R.self, R.self, a));
-    R.CheckReduce(a, R.Phi(a, a, R.self, R.self));
-    R.CheckReduce(a, R.Phi(R.self, a, a, R.self));
-  }
-
-  for (size_t i = 1; i < arraysize(singles); i++) {
-    Node* a = singles[i], *b = singles[0];
-    Node* phi1 = R.Phi(b, a, a, a);
-    R.CheckReduce(phi1, phi1);
-
-    Node* phi2 = R.Phi(a, b, a, a);
-    R.CheckReduce(phi2, phi2);
-
-    Node* phi3 = R.Phi(a, a, b, a);
-    R.CheckReduce(phi3, phi3);
-
-    Node* phi4 = R.Phi(a, a, a, b);
-    R.CheckReduce(phi4, phi4);
-  }
-}
-
-
-TEST(PhiReduceShouldIgnoreControlNodes) {
-  PhiReducerTester R;
-  Node* zero = R.Int32Constant(0);
-  Node* one = R.Int32Constant(1);
-  Node* oneish = R.Float64Constant(1.1);
-  Node* param = R.Parameter();
-
-  Node* singles[] = {zero, one, oneish, param};
-  for (size_t i = 0; i < arraysize(singles); ++i) {
-    R.CheckReduce(singles[i], R.PhiWithControl(singles[i], R.dead));
-    R.CheckReduce(singles[i], R.PhiWithControl(R.self, singles[i], R.dead));
-    R.CheckReduce(singles[i], R.PhiWithControl(singles[i], R.self, R.dead));
-  }
-}
diff --git a/test/cctest/compiler/test-pipeline.cc b/test/cctest/compiler/test-pipeline.cc
index f0b750a..98b0bae 100644
--- a/test/cctest/compiler/test-pipeline.cc
+++ b/test/cctest/compiler/test-pipeline.cc
@@ -5,6 +5,7 @@
 #include "src/v8.h"
 #include "test/cctest/cctest.h"
 
+#include "src/ast-numbering.h"
 #include "src/compiler.h"
 #include "src/compiler/pipeline.h"
 #include "src/handles.h"
@@ -22,10 +23,7 @@
       *v8::Handle<v8::Function>::Cast(CompileRun(source)));
   CompilationInfoWithZone info(function);
 
-  CHECK(Parser::Parse(&info));
-  CHECK(Rewriter::Rewrite(&info));
-  CHECK(Scope::Analyze(&info));
-  CHECK_NE(NULL, info.scope());
+  CHECK(Compiler::ParseAndAnalyze(&info));
 
   Pipeline pipeline(&info);
 #if V8_TURBOFAN_TARGET
diff --git a/test/cctest/compiler/test-representation-change.cc b/test/cctest/compiler/test-representation-change.cc
index 6c9026b..2dc3029 100644
--- a/test/cctest/compiler/test-representation-change.cc
+++ b/test/cctest/compiler/test-representation-change.cc
@@ -7,10 +7,10 @@
 #include "src/v8.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/graph-builder-tester.h"
+#include "test/cctest/compiler/value-helper.h"
 
 #include "src/compiler/node-matchers.h"
 #include "src/compiler/representation-change.h"
-#include "src/compiler/typer.h"
 
 using namespace v8::internal;
 using namespace v8::internal::compiler;
@@ -24,16 +24,13 @@
  public:
   explicit RepresentationChangerTester(int num_parameters = 0)
       : GraphAndBuilders(main_zone()),
-        typer_(main_zone()),
         javascript_(main_zone()),
-        jsgraph_(main_graph_, &main_common_, &javascript_, &typer_,
-                 &main_machine_),
+        jsgraph_(main_graph_, &main_common_, &javascript_, &main_machine_),
         changer_(&jsgraph_, &main_simplified_, main_isolate()) {
     Node* s = graph()->NewNode(common()->Start(num_parameters));
     graph()->SetStart(s);
   }
 
-  Typer typer_;
   JSOperatorBuilder javascript_;
   JSGraph jsgraph_;
   RepresentationChanger changer_;
@@ -51,6 +48,24 @@
     CHECK_EQ(expected, m.Value());
   }
 
+  void CheckUint32Constant(Node* n, uint32_t expected) {
+    Uint32Matcher m(n);
+    CHECK(m.HasValue());
+    CHECK_EQ(static_cast<int>(expected), static_cast<int>(m.Value()));
+  }
+
+  void CheckFloat64Constant(Node* n, double expected) {
+    Float64Matcher m(n);
+    CHECK(m.HasValue());
+    CHECK_EQ(expected, m.Value());
+  }
+
+  void CheckFloat32Constant(Node* n, float expected) {
+    CHECK_EQ(IrOpcode::kFloat32Constant, n->opcode());
+    float fval = OpParameter<float>(n->op());
+    CHECK_EQ(expected, fval);
+  }
+
   void CheckHeapConstant(Node* n, HeapObject* expected) {
     HeapObjectMatcher<HeapObject> m(n);
     CHECK(m.HasValue());
@@ -88,28 +103,8 @@
 }  // namespace v8::internal::compiler
 
 
-// TODO(titzer): add kRepFloat32 when fully supported.
-static const MachineType all_reps[] = {kRepBit, kRepWord32, kRepWord64,
-                                       kRepFloat64, kRepTagged};
-
-
-// TODO(titzer): lift this to ValueHelper
-static const double double_inputs[] = {
-    0.0,   -0.0,    1.0,    -1.0,        0.1,         1.4,    -1.7,
-    2,     5,       6,      982983,      888,         -999.8, 3.1e7,
-    -2e66, 2.3e124, -12e73, V8_INFINITY, -V8_INFINITY};
-
-
-static const int32_t int32_inputs[] = {
-    0,      1,                                -1,
-    2,      5,                                6,
-    982983, 888,                              -999,
-    65535,  static_cast<int32_t>(0xFFFFFFFF), static_cast<int32_t>(0x80000000)};
-
-
-static const uint32_t uint32_inputs[] = {
-    0,      1,   static_cast<uint32_t>(-1),   2,     5,          6,
-    982983, 888, static_cast<uint32_t>(-999), 65535, 0xFFFFFFFF, 0x80000000};
+static const MachineType all_reps[] = {kRepBit,     kRepWord32,  kRepWord64,
+                                       kRepFloat32, kRepFloat64, kRepTagged};
 
 
 TEST(BoolToBit_constant) {
@@ -142,24 +137,234 @@
 TEST(ToTagged_constant) {
   RepresentationChangerTester r;
 
-  for (size_t i = 0; i < arraysize(double_inputs); i++) {
-    Node* n = r.jsgraph()->Float64Constant(double_inputs[i]);
-    Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged);
-    r.CheckNumberConstant(c, double_inputs[i]);
+  {
+    FOR_FLOAT64_INPUTS(i) {
+      Node* n = r.jsgraph()->Float64Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged);
+      r.CheckNumberConstant(c, *i);
+    }
   }
 
-  for (size_t i = 0; i < arraysize(int32_inputs); i++) {
-    Node* n = r.jsgraph()->Int32Constant(int32_inputs[i]);
-    Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32,
-                                                kRepTagged);
-    r.CheckNumberConstant(c, static_cast<double>(int32_inputs[i]));
+  {
+    FOR_FLOAT64_INPUTS(i) {
+      Node* n = r.jsgraph()->Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepTagged);
+      r.CheckNumberConstant(c, *i);
+    }
   }
 
-  for (size_t i = 0; i < arraysize(uint32_inputs); i++) {
-    Node* n = r.jsgraph()->Int32Constant(uint32_inputs[i]);
-    Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32,
-                                                kRepTagged);
-    r.CheckNumberConstant(c, static_cast<double>(uint32_inputs[i]));
+  {
+    FOR_FLOAT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Float32Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepTagged);
+      r.CheckNumberConstant(c, *i);
+    }
+  }
+
+  {
+    FOR_INT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Int32Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32,
+                                                  kRepTagged);
+      r.CheckNumberConstant(c, *i);
+    }
+  }
+
+  {
+    FOR_UINT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Int32Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32,
+                                                  kRepTagged);
+      r.CheckNumberConstant(c, *i);
+    }
+  }
+}
+
+
+TEST(ToFloat64_constant) {
+  RepresentationChangerTester r;
+
+  {
+    FOR_FLOAT64_INPUTS(i) {
+      Node* n = r.jsgraph()->Float64Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepFloat64);
+      CHECK_EQ(n, c);
+    }
+  }
+
+  {
+    FOR_FLOAT64_INPUTS(i) {
+      Node* n = r.jsgraph()->Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepTagged, kRepFloat64);
+      r.CheckFloat64Constant(c, *i);
+    }
+  }
+
+  {
+    FOR_FLOAT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Float32Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepFloat64);
+      r.CheckFloat64Constant(c, *i);
+    }
+  }
+
+  {
+    FOR_INT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Int32Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32,
+                                                  kRepFloat64);
+      r.CheckFloat64Constant(c, *i);
+    }
+  }
+
+  {
+    FOR_UINT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Int32Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32,
+                                                  kRepFloat64);
+      r.CheckFloat64Constant(c, *i);
+    }
+  }
+}
+
+
+static bool IsFloat32Int32(int32_t val) {
+  return val >= -(1 << 23) && val <= (1 << 23);
+}
+
+
+static bool IsFloat32Uint32(uint32_t val) { return val <= (1 << 23); }
+
+
+TEST(ToFloat32_constant) {
+  RepresentationChangerTester r;
+
+  {
+    FOR_FLOAT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Float32Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32, kRepFloat32);
+      CHECK_EQ(n, c);
+    }
+  }
+
+  {
+    FOR_FLOAT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepTagged, kRepFloat32);
+      r.CheckFloat32Constant(c, *i);
+    }
+  }
+
+  {
+    FOR_FLOAT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Float64Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64, kRepFloat32);
+      r.CheckFloat32Constant(c, *i);
+    }
+  }
+
+  {
+    FOR_INT32_INPUTS(i) {
+      if (!IsFloat32Int32(*i)) continue;
+      Node* n = r.jsgraph()->Int32Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32,
+                                                  kRepFloat32);
+      r.CheckFloat32Constant(c, static_cast<float>(*i));
+    }
+  }
+
+  {
+    FOR_UINT32_INPUTS(i) {
+      if (!IsFloat32Uint32(*i)) continue;
+      Node* n = r.jsgraph()->Int32Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32,
+                                                  kRepFloat32);
+      r.CheckFloat32Constant(c, static_cast<float>(*i));
+    }
+  }
+}
+
+
+TEST(ToInt32_constant) {
+  RepresentationChangerTester r;
+
+  {
+    FOR_INT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Int32Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeInt32,
+                                                  kRepWord32);
+      r.CheckInt32Constant(c, *i);
+    }
+  }
+
+  {
+    FOR_INT32_INPUTS(i) {
+      if (!IsFloat32Int32(*i)) continue;
+      Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i));
+      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32 | kTypeInt32,
+                                                  kRepWord32);
+      r.CheckInt32Constant(c, *i);
+    }
+  }
+
+  {
+    FOR_INT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Float64Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64 | kTypeInt32,
+                                                  kRepWord32);
+      r.CheckInt32Constant(c, *i);
+    }
+  }
+
+  {
+    FOR_INT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeInt32,
+                                                  kRepWord32);
+      r.CheckInt32Constant(c, *i);
+    }
+  }
+}
+
+
+TEST(ToUint32_constant) {
+  RepresentationChangerTester r;
+
+  {
+    FOR_UINT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Int32Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepWord32 | kTypeUint32,
+                                                  kRepWord32);
+      r.CheckUint32Constant(c, *i);
+    }
+  }
+
+  {
+    FOR_UINT32_INPUTS(i) {
+      if (!IsFloat32Uint32(*i)) continue;
+      Node* n = r.jsgraph()->Float32Constant(static_cast<float>(*i));
+      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat32 | kTypeUint32,
+                                                  kRepWord32);
+      r.CheckUint32Constant(c, *i);
+    }
+  }
+
+  {
+    FOR_UINT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Float64Constant(*i);
+      Node* c = r.changer()->GetRepresentationFor(n, kRepFloat64 | kTypeUint32,
+                                                  kRepWord32);
+      r.CheckUint32Constant(c, *i);
+    }
+  }
+
+  {
+    FOR_UINT32_INPUTS(i) {
+      Node* n = r.jsgraph()->Constant(static_cast<double>(*i));
+      Node* c = r.changer()->GetRepresentationFor(n, kRepTagged | kTypeUint32,
+                                                  kRepWord32);
+      r.CheckUint32Constant(c, *i);
+    }
   }
 }
 
@@ -177,6 +382,23 @@
 }
 
 
+static void CheckTwoChanges(IrOpcode::Value expected2,
+                            IrOpcode::Value expected1, MachineTypeUnion from,
+                            MachineTypeUnion to) {
+  RepresentationChangerTester r;
+
+  Node* n = r.Parameter();
+  Node* c1 = r.changer()->GetRepresentationFor(n, from, to);
+
+  CHECK_NE(c1, n);
+  CHECK_EQ(expected1, c1->opcode());
+  Node* c2 = c1->InputAt(0);
+  CHECK_NE(c2, n);
+  CHECK_EQ(expected2, c2->opcode());
+  CHECK_EQ(n, c2->InputAt(0));
+}
+
+
 TEST(SingleChanges) {
   CheckChange(IrOpcode::kChangeBoolToBit, kRepTagged, kRepBit);
   CheckChange(IrOpcode::kChangeBitToBool, kRepBit, kRepTagged);
@@ -202,6 +424,28 @@
               kRepWord32);
   CheckChange(IrOpcode::kChangeFloat64ToUint32, kRepFloat64 | kTypeUint32,
               kRepWord32);
+
+  CheckChange(IrOpcode::kTruncateFloat64ToFloat32, kRepFloat64, kRepFloat32);
+
+  // Int32,Uint32 <-> Float32 require two changes.
+  CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
+                  IrOpcode::kTruncateFloat64ToFloat32, kRepWord32 | kTypeInt32,
+                  kRepFloat32);
+  CheckTwoChanges(IrOpcode::kChangeUint32ToFloat64,
+                  IrOpcode::kTruncateFloat64ToFloat32, kRepWord32 | kTypeUint32,
+                  kRepFloat32);
+  CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
+                  IrOpcode::kChangeFloat64ToInt32, kRepFloat32 | kTypeInt32,
+                  kRepWord32);
+  CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
+                  IrOpcode::kChangeFloat64ToUint32, kRepFloat32 | kTypeUint32,
+                  kRepWord32);
+
+  // Float32 <-> Tagged require two changes.
+  CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
+                  IrOpcode::kChangeFloat64ToTagged, kRepFloat32, kRepTagged);
+  CheckTwoChanges(IrOpcode::kChangeTaggedToFloat64,
+                  IrOpcode::kTruncateFloat64ToFloat32, kRepTagged, kRepFloat32);
 }
 
 
@@ -215,6 +459,11 @@
               kRepWord32 | kTypeUint32);
   CheckChange(IrOpcode::kChangeInt32ToFloat64, kRepWord32, kRepFloat64);
   CheckChange(IrOpcode::kChangeFloat64ToInt32, kRepFloat64, kRepWord32);
+
+  CheckTwoChanges(IrOpcode::kChangeInt32ToFloat64,
+                  IrOpcode::kTruncateFloat64ToFloat32, kRepWord32, kRepFloat32);
+  CheckTwoChanges(IrOpcode::kChangeFloat32ToFloat64,
+                  IrOpcode::kChangeFloat64ToInt32, kRepFloat32, kRepWord32);
 }
 
 
@@ -295,11 +544,4 @@
       r.CheckTypeError(all_reps[i] | all_reps[j], kRepTagged);
     }
   }
-
-  // TODO(titzer): Float32 representation changes trigger type errors now.
-  // Enforce current behavior to test all paths through representation changer.
-  for (size_t i = 0; i < arraysize(all_reps); i++) {
-    r.CheckTypeError(all_reps[i], kRepFloat32);
-    r.CheckTypeError(kRepFloat32, all_reps[i]);
-  }
 }
diff --git a/test/cctest/compiler/test-run-inlining.cc b/test/cctest/compiler/test-run-inlining.cc
index ad82fec..19b96ba 100644
--- a/test/cctest/compiler/test-run-inlining.cc
+++ b/test/cctest/compiler/test-run-inlining.cc
@@ -25,7 +25,8 @@
     frames_seen++;
     it.Advance();
   }
-  CHECK_EQ(args[0]->ToInt32()->Value(), topmost->GetInlineCount());
+  CHECK_EQ(args[0]->ToInt32(args.GetIsolate())->Value(),
+           topmost->GetInlineCount());
 }
 
 
@@ -37,16 +38,20 @@
 }
 
 
+static uint32_t kInlineFlags = CompilationInfo::kInliningEnabled |
+                               CompilationInfo::kContextSpecializing |
+                               CompilationInfo::kTypingEnabled;
+
+
 TEST(SimpleInlining) {
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function(){"
-      "function foo(s) { AssertInlineCount(2); return s; };"
-      "function bar(s, t) { return foo(s); };"
-      "return bar;})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      "  function foo(s) { AssertInlineCount(2); return s; };"
+      "  function bar(s, t) { return foo(s); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
@@ -57,13 +62,11 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function(){"
-      "function foo(s) { %DeoptimizeFunction(bar); return "
-      "s; };"
-      "function bar(s, t) { return foo(s); };"
-      "return bar;})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      "  function foo(s) { %DeoptimizeFunction(bar); return s; };"
+      "  function bar(s, t) { return foo(s); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(1), T.Val(1), T.Val(2));
@@ -74,13 +77,11 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "function foo(s) { AssertInlineCount(2); var x = 12; return s + x; };"
-      "function bar(s, t) { return foo(s); };"
-      "return bar;"
+      "  function foo(s) { AssertInlineCount(2); var x = 12; return s + x; };"
+      "  function bar(s, t) { return foo(s); };"
+      "  return bar;"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(13), T.Val(1), T.Val(2));
@@ -91,16 +92,14 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "function foo(s) { "
-      "  AssertInlineCount(2); %DeoptimizeFunction(bar); var x = 12;"
-      "  return s + x;"
-      "};"
-      "function bar(s, t) { return foo(s); };"
-      "return bar;"
+      "  function foo(s) {"
+      "    AssertInlineCount(2); %DeoptimizeFunction(bar); var x = 12;"
+      "    return s + x;"
+      "  };"
+      "  function bar(s, t) { return foo(s); };"
+      "  return bar;"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(13), T.Val(1), T.Val(2));
@@ -111,14 +110,12 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "var f = (function () {"
-      "var x = 42;"
-      "function bar(s) { return x + s; };"
-      "return (function (s) { return bar(s); });"
+      "  var x = 42;"
+      "  function bar(s) { return x + s; };"
+      "  return (function (s) { return bar(s); });"
       "})();"
-      "(function (s) { return f(s)})",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      "(function (s) { return f(s) })",
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(42 + 12), T.Val(12), T.undefined());
@@ -132,12 +129,10 @@
   FunctionTester T(
       "var x = 42;"
       "(function () {"
-      "function bar(s, t) { return eval(\"AssertInlineCount(1); x\") };"
-      "return bar;"
+      "  function bar(s, t) { return eval(\"AssertInlineCount(1); x\") };"
+      "  return bar;"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(42), T.Val("x"), T.undefined());
@@ -148,13 +143,11 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "var x = 42;"
-      "function bar(s, t, u, v) { AssertInlineCount(2); return x + s; };"
-      "return (function (s,t) { return bar(s); });"
+      "  var x = 42;"
+      "  function bar(s, t, u, v) { AssertInlineCount(2); return x + s; };"
+      "  return (function (s,t) { return bar(s); });"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(42 + 12), T.Val(12), T.undefined());
@@ -165,16 +158,14 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "function foo(s,t,u,v) { AssertInlineCount(2); %DeoptimizeFunction(bar); "
-      "return baz(); };"
-      "function bar() { return foo(11); };"
-      "function baz() { return foo.arguments.length == 1 && "
-      "                        foo.arguments[0] == 11 ; }"
-      "return bar;"
+      "  function foo(s,t,u,v) { AssertInlineCount(2);"
+      "                          %DeoptimizeFunction(bar); return baz(); };"
+      "  function bar() { return foo(11); };"
+      "  function baz() { return foo.arguments.length == 1 &&"
+      "                          foo.arguments[0] == 11; }"
+      "  return bar;"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.true_value(), T.Val(12), T.Val(14));
@@ -185,14 +176,12 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "var x = 42;"
-      "function foo(s) { AssertInlineCount(2); return x + s; };"
-      "function bar(s,t) { return foo(s,t,13); };"
-      "return bar;"
+      "  var x = 42;"
+      "  function foo(s) { AssertInlineCount(2); return x + s; };"
+      "  function bar(s,t) { return foo(s,t,13); };"
+      "  return bar;"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(42 + 12), T.Val(12), T.undefined());
@@ -203,18 +192,16 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "function foo(s) { AssertInlineCount(2); %DeoptimizeFunction(bar); "
-      "return baz(); };"
-      "function bar() { return foo(13, 14, 15); };"
-      "function baz() { return foo.arguments.length == 3 && "
-      "                        foo.arguments[0] == 13 && "
-      "                        foo.arguments[1] == 14 && "
-      "                        foo.arguments[2] == 15; }"
-      "return bar;"
+      "  function foo(s) { AssertInlineCount(2); %DeoptimizeFunction(bar);"
+      "                    return baz(); };"
+      "  function bar() { return foo(13, 14, 15); };"
+      "  function baz() { return foo.arguments.length == 3 &&"
+      "                          foo.arguments[0] == 13 &&"
+      "                          foo.arguments[1] == 14 &&"
+      "                          foo.arguments[2] == 15; }"
+      "  return bar;"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.true_value(), T.Val(12), T.Val(14));
@@ -225,13 +212,11 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "var x = 42;"
-      "function bar(s) { AssertInlineCount(2); return x + s; };"
-      "return (function (s,t) { return bar(s) + bar(t); });"
+      "  var x = 42;"
+      "  function bar(s) { AssertInlineCount(2); return x + s; };"
+      "  return (function (s,t) { return bar(s) + bar(t); });"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(2 * 42 + 12 + 4), T.Val(12), T.Val(4));
@@ -242,14 +227,12 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "var x = 42;"
-      "function foo(s) { AssertInlineCount(2); return x + s; };"
-      "function bar(s,t) { return foo(foo(s)); };"
-      "return bar;"
+      "  var x = 42;"
+      "  function foo(s) { AssertInlineCount(2); return x + s; };"
+      "  function bar(s,t) { return foo(foo(s)); };"
+      "  return bar;"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(42 + 42 + 12), T.Val(12), T.Val(4));
@@ -260,15 +243,13 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "var x = 41;"
-      "function foo(s) { AssertInlineCount(2); if (s % 2 == 0) {"
-      "                  return x - s } else { return x + s; } };"
-      "function bar(s,t) { return foo(foo(s)); };"
-      "return bar;"
+      "  var x = 41;"
+      "  function foo(s) { AssertInlineCount(2); if (s % 2 == 0) {"
+      "                    return x - s } else { return x + s; } };"
+      "  function bar(s,t) { return foo(foo(s)); };"
+      "  return bar;"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(-11), T.Val(11), T.Val(4));
@@ -279,34 +260,60 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "var x = 41;"
-      "function foo(s,t) { AssertInlineCount(2); if (s % 2 == 0) {"
-      "                    return x - s * t } else { return x + s * t; } };"
-      "function bar(s,t) { return foo(foo(s, 3), 5); };"
-      "return bar;"
+      "  var x = 41;"
+      "  function foo(s,t) { AssertInlineCount(2); if (s % 2 == 0) {"
+      "                      return x - s * t } else { return x + s * t; } };"
+      "  function bar(s,t) { return foo(foo(s, 3), 5); };"
+      "  return bar;"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(-329), T.Val(11), T.Val(4));
 }
 
 
-TEST(InlineLoop) {
+TEST(InlineLoopGuardedEmpty) {
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "var x = 41;"
-      "function foo(s) { AssertInlineCount(2); while (s > 0) {"
-      "                  s = s - 1; }; return s; };"
-      "function bar(s,t) { return foo(foo(s)); };"
-      "return bar;"
+      "  function foo(s) { AssertInlineCount(2); if (s) while (s); return s; };"
+      "  function bar(s,t) { return foo(s); };"
+      "  return bar;"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.Val(0.0), T.Val(0.0), T.Val(4));
+}
+
+
+TEST(InlineLoopGuardedOnce) {
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T(
+      "(function () {"
+      "  function foo(s,t) { AssertInlineCount(2); if (t > 0) while (s > 0) {"
+      "                      s = s - 1; }; return s; };"
+      "  function bar(s,t) { return foo(s,t); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.Val(0.0), T.Val(11), T.Val(4));
+}
+
+
+TEST(InlineLoopGuardedTwice) {
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T(
+      "(function () {"
+      "  function foo(s,t) { AssertInlineCount(2); if (t > 0) while (s > 0) {"
+      "                      s = s - 1; }; return s; };"
+      "  function bar(s,t) { return foo(foo(s,t),t); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(0.0), T.Val(11), T.Val(4));
@@ -317,15 +324,13 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "var x = Object.create({}, { y: { value:42, writable:false } });"
-      "function foo(s) { 'use strict';"
-      "                   x.y = 9; };"
-      "function bar(s,t) { return foo(s); };"
-      "return bar;"
+      "  var x = Object.create({}, { y: { value:42, writable:false } });"
+      "  function foo(s) { 'use strict';"
+      "                     x.y = 9; };"
+      "  function bar(s,t) { return foo(s); };"
+      "  return bar;"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckThrows(T.undefined(), T.undefined());
@@ -336,18 +341,100 @@
   FLAG_turbo_deoptimization = true;
   FunctionTester T(
       "(function () {"
-      "var x = Object.create({}, { y: { value:42, writable:false } });"
-      "function foo(s) { x.y = 9; return x.y; };"
-      "function bar(s,t) { \'use strict\'; return foo(s); };"
-      "return bar;"
+      "  var x = Object.create({}, { y: { value:42, writable:false } });"
+      "  function foo(s) { x.y = 9; return x.y; };"
+      "  function bar(s,t) { \'use strict\'; return foo(s); };"
+      "  return bar;"
       "})();",
-      CompilationInfo::kInliningEnabled |
-          CompilationInfo::kContextSpecializing |
-          CompilationInfo::kTypingEnabled);
+      kInlineFlags);
 
   InstallAssertInlineCountHelper(CcTest::isolate());
   T.CheckCall(T.Val(42), T.undefined(), T.undefined());
 }
 
 
+TEST(InlineIntrinsicIsSmi) {
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T(
+      "(function () {"
+      "  var x = 42;"
+      "  function bar(s,t) { return %_IsSmi(x); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.true_value(), T.Val(12), T.Val(4));
+}
+
+
+TEST(InlineIntrinsicIsNonNegativeSmi) {
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T(
+      "(function () {"
+      "  var x = 42;"
+      "  function bar(s,t) { return %_IsNonNegativeSmi(x); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.true_value(), T.Val(12), T.Val(4));
+}
+
+
+TEST(InlineIntrinsicIsArray) {
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T(
+      "(function () {"
+      "  var x = [1,2,3];"
+      "  function bar(s,t) { return %_IsArray(x); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.true_value(), T.Val(12), T.Val(4));
+
+  FunctionTester T2(
+      "(function () {"
+      "  var x = 32;"
+      "  function bar(s,t) { return %_IsArray(x); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  T2.CheckCall(T.false_value(), T.Val(12), T.Val(4));
+
+  FunctionTester T3(
+      "(function () {"
+      "  var x = bar;"
+      "  function bar(s,t) { return %_IsArray(x); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  T3.CheckCall(T.false_value(), T.Val(12), T.Val(4));
+}
+
+
+TEST(InlineWithArguments) {
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T(
+      "(function () {"
+      "  function foo(s,t,u) { AssertInlineCount(2);"
+      "    return foo.arguments.length == 3 &&"
+      "           foo.arguments[0] == 13 &&"
+      "           foo.arguments[1] == 14 &&"
+      "           foo.arguments[2] == 15;"
+      "  }"
+      "  function bar() { return foo(13, 14, 15); };"
+      "  return bar;"
+      "})();",
+      kInlineFlags);
+
+  InstallAssertInlineCountHelper(CcTest::isolate());
+  T.CheckCall(T.true_value(), T.Val(12), T.Val(14));
+}
+
 #endif  // V8_TURBOFAN_TARGET
diff --git a/test/cctest/compiler/test-run-intrinsics.cc b/test/cctest/compiler/test-run-intrinsics.cc
index a1b5676..76cbb8f 100644
--- a/test/cctest/compiler/test-run-intrinsics.cc
+++ b/test/cctest/compiler/test-run-intrinsics.cc
@@ -8,10 +8,12 @@
 
 using namespace v8::internal;
 using namespace v8::internal::compiler;
-
+uint32_t flags = CompilationInfo::kInliningEnabled;
 
 TEST(IsSmi) {
-  FunctionTester T("(function(a) { return %_IsSmi(a); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a) { return %_IsSmi(a); })", flags);
 
   T.CheckTrue(T.Val(1));
   T.CheckFalse(T.Val(1.1));
@@ -23,7 +25,9 @@
 
 
 TEST(IsNonNegativeSmi) {
-  FunctionTester T("(function(a) { return %_IsNonNegativeSmi(a); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a) { return %_IsNonNegativeSmi(a); })", flags);
 
   T.CheckTrue(T.Val(1));
   T.CheckFalse(T.Val(1.1));
@@ -35,7 +39,9 @@
 
 
 TEST(IsMinusZero) {
-  FunctionTester T("(function(a) { return %_IsMinusZero(a); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a) { return %_IsMinusZero(a); })", flags);
 
   T.CheckFalse(T.Val(1));
   T.CheckFalse(T.Val(1.1));
@@ -47,7 +53,9 @@
 
 
 TEST(IsArray) {
-  FunctionTester T("(function(a) { return %_IsArray(a); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a) { return %_IsArray(a); })", flags);
 
   T.CheckFalse(T.NewObject("(function() {})"));
   T.CheckTrue(T.NewObject("([1])"));
@@ -61,7 +69,9 @@
 
 
 TEST(IsObject) {
-  FunctionTester T("(function(a) { return %_IsObject(a); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a) { return %_IsObject(a); })", flags);
 
   T.CheckFalse(T.NewObject("(function() {})"));
   T.CheckTrue(T.NewObject("([1])"));
@@ -75,7 +85,9 @@
 
 
 TEST(IsFunction) {
-  FunctionTester T("(function(a) { return %_IsFunction(a); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a) { return %_IsFunction(a); })", flags);
 
   T.CheckTrue(T.NewObject("(function() {})"));
   T.CheckFalse(T.NewObject("([1])"));
@@ -89,7 +101,9 @@
 
 
 TEST(IsRegExp) {
-  FunctionTester T("(function(a) { return %_IsRegExp(a); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a) { return %_IsRegExp(a); })", flags);
 
   T.CheckFalse(T.NewObject("(function() {})"));
   T.CheckFalse(T.NewObject("([1])"));
@@ -103,7 +117,9 @@
 
 
 TEST(ClassOf) {
-  FunctionTester T("(function(a) { return %_ClassOf(a); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a) { return %_ClassOf(a); })", flags);
 
   T.CheckCall(T.Val("Function"), T.NewObject("(function() {})"));
   T.CheckCall(T.Val("Array"), T.NewObject("([1])"));
@@ -117,7 +133,9 @@
 
 
 TEST(ObjectEquals) {
-  FunctionTester T("(function(a,b) { return %_ObjectEquals(a,b); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a,b) { return %_ObjectEquals(a,b); })", flags);
   CompileRun("var o = {}");
 
   T.CheckTrue(T.NewObject("(o)"), T.NewObject("(o)"));
@@ -130,7 +148,9 @@
 
 
 TEST(ValueOf) {
-  FunctionTester T("(function(a) { return %_ValueOf(a); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a) { return %_ValueOf(a); })", flags);
 
   T.CheckCall(T.Val("a"), T.Val("a"));
   T.CheckCall(T.Val("b"), T.NewObject("(new String('b'))"));
@@ -140,7 +160,9 @@
 
 
 TEST(SetValueOf) {
-  FunctionTester T("(function(a,b) { return %_SetValueOf(a,b); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a,b) { return %_SetValueOf(a,b); })", flags);
 
   T.CheckCall(T.Val("a"), T.NewObject("(new String)"), T.Val("a"));
   T.CheckCall(T.Val(123), T.NewObject("(new Number)"), T.Val(123));
@@ -149,7 +171,9 @@
 
 
 TEST(StringCharFromCode) {
-  FunctionTester T("(function(a) { return %_StringCharFromCode(a); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a) { return %_StringCharFromCode(a); })", flags);
 
   T.CheckCall(T.Val("a"), T.Val(97));
   T.CheckCall(T.Val("\xE2\x9D\x8A"), T.Val(0x274A));
@@ -158,7 +182,9 @@
 
 
 TEST(StringCharAt) {
-  FunctionTester T("(function(a,b) { return %_StringCharAt(a,b); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a,b) { return %_StringCharAt(a,b); })", flags);
 
   T.CheckCall(T.Val("e"), T.Val("huge fan!"), T.Val(3));
   T.CheckCall(T.Val("f"), T.Val("\xE2\x9D\x8A fan!"), T.Val(2));
@@ -167,7 +193,10 @@
 
 
 TEST(StringCharCodeAt) {
-  FunctionTester T("(function(a,b) { return %_StringCharCodeAt(a,b); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a,b) { return %_StringCharCodeAt(a,b); })",
+                   flags);
 
   T.CheckCall(T.Val('e'), T.Val("huge fan!"), T.Val(3));
   T.CheckCall(T.Val('f'), T.Val("\xE2\x9D\x8A fan!"), T.Val(2));
@@ -176,7 +205,9 @@
 
 
 TEST(StringAdd) {
-  FunctionTester T("(function(a,b) { return %_StringAdd(a,b); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a,b) { return %_StringAdd(a,b); })", flags);
 
   T.CheckCall(T.Val("aaabbb"), T.Val("aaa"), T.Val("bbb"));
   T.CheckCall(T.Val("aaa"), T.Val("aaa"), T.Val(""));
@@ -185,7 +216,9 @@
 
 
 TEST(StringSubString) {
-  FunctionTester T("(function(a,b) { return %_SubString(a,b,b+3); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a,b) { return %_SubString(a,b,b+3); })", flags);
 
   T.CheckCall(T.Val("aaa"), T.Val("aaabbb"), T.Val(0.0));
   T.CheckCall(T.Val("abb"), T.Val("aaabbb"), T.Val(2));
@@ -194,7 +227,9 @@
 
 
 TEST(StringCompare) {
-  FunctionTester T("(function(a,b) { return %_StringCompare(a,b); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a,b) { return %_StringCompare(a,b); })", flags);
 
   T.CheckCall(T.Val(-1), T.Val("aaa"), T.Val("bbb"));
   T.CheckCall(T.Val(0.0), T.Val("bbb"), T.Val("bbb"));
@@ -203,7 +238,10 @@
 
 
 TEST(CallFunction) {
-  FunctionTester T("(function(a,b) { return %_CallFunction(a, 1, 2, 3, b); })");
+  FLAG_turbo_inlining_intrinsics = true;
+  FLAG_turbo_deoptimization = true;
+  FunctionTester T("(function(a,b) { return %_CallFunction(a, 1, 2, 3, b); })",
+                   flags);
   CompileRun("function f(a,b,c) { return a + b + c + this.d; }");
 
   T.CheckCall(T.Val(129), T.NewObject("({d:123})"), T.NewObject("f"));
diff --git a/test/cctest/compiler/test-run-jsbranches.cc b/test/cctest/compiler/test-run-jsbranches.cc
index df2fcdc..7a4a0b3 100644
--- a/test/cctest/compiler/test-run-jsbranches.cc
+++ b/test/cctest/compiler/test-run-jsbranches.cc
@@ -280,3 +280,78 @@
   T.CheckCall(T.Val(2), T.Val(2), T.false_value());
   T.CheckCall(T.undefined(), T.Val(1), T.null());
 }
+
+
+TEST(IfTrue) {
+  FunctionTester T("(function(a,b) { if (true) return a; return b; })");
+
+  T.CheckCall(T.Val(55), T.Val(55), T.Val(11));
+  T.CheckCall(T.Val(666), T.Val(666), T.Val(-444));
+}
+
+
+TEST(TernaryTrue) {
+  FunctionTester T("(function(a,b) { return true ? a : b; })");
+
+  T.CheckCall(T.Val(77), T.Val(77), T.Val(11));
+  T.CheckCall(T.Val(111), T.Val(111), T.Val(-444));
+}
+
+
+TEST(IfFalse) {
+  FunctionTester T("(function(a,b) { if (false) return a; return b; })");
+
+  T.CheckCall(T.Val(11), T.Val(22), T.Val(11));
+  T.CheckCall(T.Val(-555), T.Val(333), T.Val(-555));
+}
+
+
+TEST(TernaryFalse) {
+  FunctionTester T("(function(a,b) { return false ? a : b; })");
+
+  T.CheckCall(T.Val(99), T.Val(33), T.Val(99));
+  T.CheckCall(T.Val(-99), T.Val(-33), T.Val(-99));
+}
+
+
+TEST(WhileTrue) {
+  FunctionTester T("(function(a,b) { while (true) return a; return b; })");
+
+  T.CheckCall(T.Val(551), T.Val(551), T.Val(111));
+  T.CheckCall(T.Val(661), T.Val(661), T.Val(-444));
+}
+
+
+TEST(WhileFalse) {
+  FunctionTester T("(function(a,b) { while (false) return a; return b; })");
+
+  T.CheckCall(T.Val(115), T.Val(551), T.Val(115));
+  T.CheckCall(T.Val(-445), T.Val(661), T.Val(-445));
+}
+
+
+TEST(DoWhileTrue) {
+  FunctionTester T(
+      "(function(a,b) { do { return a; } while (true); return b; })");
+
+  T.CheckCall(T.Val(7551), T.Val(7551), T.Val(7111));
+  T.CheckCall(T.Val(7661), T.Val(7661), T.Val(-7444));
+}
+
+
+TEST(DoWhileFalse) {
+  FunctionTester T(
+      "(function(a,b) { do { "
+      "; } while (false); return b; })");
+
+  T.CheckCall(T.Val(8115), T.Val(8551), T.Val(8115));
+  T.CheckCall(T.Val(-8445), T.Val(8661), T.Val(-8445));
+}
+
+
+TEST(EmptyFor) {
+  FunctionTester T("(function(a,b) { if (a) for(;;) ; return b; })");
+
+  T.CheckCall(T.Val(8126.1), T.Val(0.0), T.Val(8126.1));
+  T.CheckCall(T.Val(1123.1), T.Val(0.0), T.Val(1123.1));
+}
diff --git a/test/cctest/compiler/test-run-machops.cc b/test/cctest/compiler/test-run-machops.cc
index 985e0f8..974d4ce 100644
--- a/test/cctest/compiler/test-run-machops.cc
+++ b/test/cctest/compiler/test-run-machops.cc
@@ -2,11 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <cmath>
 #include <functional>
 #include <limits>
 
 #include "src/base/bits.h"
-#include "src/compiler/generic-node-inl.h"
+#include "src/codegen.h"
 #include "test/cctest/cctest.h"
 #include "test/cctest/compiler/codegen-tester.h"
 #include "test/cctest/compiler/value-helper.h"
@@ -58,25 +59,25 @@
 TEST(CodeGenInt32Binop) {
   RawMachineAssemblerTester<void> m;
 
-  const Operator* ops[] = {
+  const Operator* kOps[] = {
       m.machine()->Word32And(),      m.machine()->Word32Or(),
       m.machine()->Word32Xor(),      m.machine()->Word32Shl(),
       m.machine()->Word32Shr(),      m.machine()->Word32Sar(),
       m.machine()->Word32Equal(),    m.machine()->Int32Add(),
       m.machine()->Int32Sub(),       m.machine()->Int32Mul(),
-      m.machine()->Int32Div(),       m.machine()->Int32UDiv(),
-      m.machine()->Int32Mod(),       m.machine()->Int32UMod(),
+      m.machine()->Int32MulHigh(),   m.machine()->Int32Div(),
+      m.machine()->Uint32Div(),      m.machine()->Int32Mod(),
+      m.machine()->Uint32Mod(),      m.machine()->Uint32MulHigh(),
       m.machine()->Int32LessThan(),  m.machine()->Int32LessThanOrEqual(),
-      m.machine()->Uint32LessThan(), m.machine()->Uint32LessThanOrEqual(),
-      NULL};
+      m.machine()->Uint32LessThan(), m.machine()->Uint32LessThanOrEqual()};
 
-  for (int i = 0; ops[i] != NULL; i++) {
+  for (size_t i = 0; i < arraysize(kOps); ++i) {
     for (int j = 0; j < 8; j++) {
       for (int k = 0; k < 8; k++) {
         RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
         Node* a = Int32Input(&m, j);
         Node* b = Int32Input(&m, k);
-        m.Return(m.NewNode(ops[i], a, b));
+        m.Return(m.NewNode(kOps[i], a, b));
         m.GenerateCode();
       }
     }
@@ -127,51 +128,6 @@
 }
 
 
-TEST(RunRedundantBranch1) {
-  RawMachineAssemblerTester<int32_t> m;
-  int constant = 944777;
-
-  MLabel blocka;
-  m.Branch(m.Int32Constant(0), &blocka, &blocka);
-  m.Bind(&blocka);
-  m.Return(m.Int32Constant(constant));
-
-  CHECK_EQ(constant, m.Call());
-}
-
-
-TEST(RunRedundantBranch2) {
-  RawMachineAssemblerTester<int32_t> m;
-  int constant = 955777;
-
-  MLabel blocka, blockb;
-  m.Branch(m.Int32Constant(0), &blocka, &blocka);
-  m.Bind(&blockb);
-  m.Goto(&blocka);
-  m.Bind(&blocka);
-  m.Return(m.Int32Constant(constant));
-
-  CHECK_EQ(constant, m.Call());
-}
-
-
-TEST(RunRedundantBranch3) {
-  RawMachineAssemblerTester<int32_t> m;
-  int constant = 966777;
-
-  MLabel blocka, blockb, blockc;
-  m.Branch(m.Int32Constant(0), &blocka, &blockc);
-  m.Bind(&blocka);
-  m.Branch(m.Int32Constant(0), &blockb, &blockb);
-  m.Bind(&blockc);
-  m.Goto(&blockb);
-  m.Bind(&blockb);
-  m.Return(m.Int32Constant(constant));
-
-  CHECK_EQ(constant, m.Call());
-}
-
-
 TEST(RunDiamond2) {
   RawMachineAssemblerTester<int32_t> m;
 
@@ -571,6 +527,142 @@
 }
 
 
+TEST(RunInt32AddAndWord32EqualP) {
+  {
+    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Int32Add(m.Parameter(0),
+                        m.Word32Equal(m.Parameter(1), m.Parameter(2))));
+    FOR_INT32_INPUTS(i) {
+      FOR_INT32_INPUTS(j) {
+        FOR_INT32_INPUTS(k) {
+          // Use uint32_t because signed overflow is UB in C.
+          int32_t const expected =
+              bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k));
+          CHECK_EQ(expected, m.Call(*i, *j, *k));
+        }
+      }
+    }
+  }
+  {
+    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Int32Add(m.Word32Equal(m.Parameter(0), m.Parameter(1)),
+                        m.Parameter(2)));
+    FOR_INT32_INPUTS(i) {
+      FOR_INT32_INPUTS(j) {
+        FOR_INT32_INPUTS(k) {
+          // Use uint32_t because signed overflow is UB in C.
+          int32_t const expected =
+              bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k));
+          CHECK_EQ(expected, m.Call(*i, *j, *k));
+        }
+      }
+    }
+  }
+}
+
+
+TEST(RunInt32AddAndWord32EqualImm) {
+  {
+    FOR_INT32_INPUTS(i) {
+      RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+      m.Return(m.Int32Add(m.Int32Constant(*i),
+                          m.Word32Equal(m.Parameter(0), m.Parameter(1))));
+      FOR_INT32_INPUTS(j) {
+        FOR_INT32_INPUTS(k) {
+          // Use uint32_t because signed overflow is UB in C.
+          int32_t const expected =
+              bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k));
+          CHECK_EQ(expected, m.Call(*j, *k));
+        }
+      }
+    }
+  }
+  {
+    FOR_INT32_INPUTS(i) {
+      RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+      m.Return(m.Int32Add(m.Word32Equal(m.Int32Constant(*i), m.Parameter(0)),
+                          m.Parameter(1)));
+      FOR_INT32_INPUTS(j) {
+        FOR_INT32_INPUTS(k) {
+          // Use uint32_t because signed overflow is UB in C.
+          int32_t const expected =
+              bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k));
+          CHECK_EQ(expected, m.Call(*j, *k));
+        }
+      }
+    }
+  }
+}
+
+
+TEST(RunInt32AddAndWord32NotEqualP) {
+  {
+    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Int32Add(m.Parameter(0),
+                        m.Word32NotEqual(m.Parameter(1), m.Parameter(2))));
+    FOR_INT32_INPUTS(i) {
+      FOR_INT32_INPUTS(j) {
+        FOR_INT32_INPUTS(k) {
+          // Use uint32_t because signed overflow is UB in C.
+          int32_t const expected =
+              bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k));
+          CHECK_EQ(expected, m.Call(*i, *j, *k));
+        }
+      }
+    }
+  }
+  {
+    RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Int32Add(m.Word32NotEqual(m.Parameter(0), m.Parameter(1)),
+                        m.Parameter(2)));
+    FOR_INT32_INPUTS(i) {
+      FOR_INT32_INPUTS(j) {
+        FOR_INT32_INPUTS(k) {
+          // Use uint32_t because signed overflow is UB in C.
+          int32_t const expected =
+              bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k));
+          CHECK_EQ(expected, m.Call(*i, *j, *k));
+        }
+      }
+    }
+  }
+}
+
+
+TEST(RunInt32AddAndWord32NotEqualImm) {
+  {
+    FOR_INT32_INPUTS(i) {
+      RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+      m.Return(m.Int32Add(m.Int32Constant(*i),
+                          m.Word32NotEqual(m.Parameter(0), m.Parameter(1))));
+      FOR_INT32_INPUTS(j) {
+        FOR_INT32_INPUTS(k) {
+          // Use uint32_t because signed overflow is UB in C.
+          int32_t const expected =
+              bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k));
+          CHECK_EQ(expected, m.Call(*j, *k));
+        }
+      }
+    }
+  }
+  {
+    FOR_INT32_INPUTS(i) {
+      RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
+      m.Return(m.Int32Add(m.Word32NotEqual(m.Int32Constant(*i), m.Parameter(0)),
+                          m.Parameter(1)));
+      FOR_INT32_INPUTS(j) {
+        FOR_INT32_INPUTS(k) {
+          // Use uint32_t because signed overflow is UB in C.
+          int32_t const expected =
+              bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k));
+          CHECK_EQ(expected, m.Call(*j, *k));
+        }
+      }
+    }
+  }
+}
+
+
 TEST(RunInt32AddAndWord32SarP) {
   {
     RawMachineAssemblerTester<int32_t> m(kMachUint32, kMachInt32, kMachUint32);
@@ -1233,6 +1325,20 @@
 }
 
 
+TEST(RunInt32MulHighP) {
+  RawMachineAssemblerTester<int32_t> m;
+  Int32BinopTester bt(&m);
+  bt.AddReturn(m.Int32MulHigh(bt.param0, bt.param1));
+  FOR_INT32_INPUTS(i) {
+    FOR_INT32_INPUTS(j) {
+      int32_t expected = static_cast<int32_t>(
+          (static_cast<int64_t>(*i) * static_cast<int64_t>(*j)) >> 32);
+      CHECK_EQ(expected, bt.call(*i, *j));
+    }
+  }
+}
+
+
 TEST(RunInt32MulImm) {
   {
     FOR_UINT32_INPUTS(i) {
@@ -1259,6 +1365,22 @@
 
 TEST(RunInt32MulAndInt32AddP) {
   {
+    FOR_INT32_INPUTS(i) {
+      FOR_INT32_INPUTS(j) {
+        RawMachineAssemblerTester<int32_t> m(kMachInt32);
+        int32_t p0 = *i;
+        int32_t p1 = *j;
+        m.Return(m.Int32Add(m.Int32Constant(p0),
+                            m.Int32Mul(m.Parameter(0), m.Int32Constant(p1))));
+        FOR_INT32_INPUTS(k) {
+          int32_t p2 = *k;
+          int expected = p0 + static_cast<int32_t>(p1 * p2);
+          CHECK_EQ(expected, m.Call(p2));
+        }
+      }
+    }
+  }
+  {
     RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32, kMachInt32);
     m.Return(
         m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
@@ -1347,6 +1469,20 @@
 }
 
 
+TEST(RunUint32MulHighP) {
+  RawMachineAssemblerTester<int32_t> m;
+  Int32BinopTester bt(&m);
+  bt.AddReturn(m.Uint32MulHigh(bt.param0, bt.param1));
+  FOR_UINT32_INPUTS(i) {
+    FOR_UINT32_INPUTS(j) {
+      int32_t expected = bit_cast<int32_t>(static_cast<uint32_t>(
+          (static_cast<uint64_t>(*i) * static_cast<uint64_t>(*j)) >> 32));
+      CHECK_EQ(expected, bt.call(bit_cast<int32_t>(*i), bit_cast<int32_t>(*j)));
+    }
+  }
+}
+
+
 TEST(RunInt32DivP) {
   {
     RawMachineAssemblerTester<int32_t> m;
@@ -1381,11 +1517,11 @@
 }
 
 
-TEST(RunInt32UDivP) {
+TEST(RunUint32DivP) {
   {
     RawMachineAssemblerTester<int32_t> m;
     Int32BinopTester bt(&m);
-    bt.AddReturn(m.Int32UDiv(bt.param0, bt.param1));
+    bt.AddReturn(m.Uint32Div(bt.param0, bt.param1));
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t p0 = *i;
@@ -1400,7 +1536,7 @@
   {
     RawMachineAssemblerTester<int32_t> m;
     Int32BinopTester bt(&m);
-    bt.AddReturn(m.Int32Add(bt.param0, m.Int32UDiv(bt.param0, bt.param1)));
+    bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Div(bt.param0, bt.param1)));
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t p0 = *i;
@@ -1449,11 +1585,11 @@
 }
 
 
-TEST(RunInt32UModP) {
+TEST(RunUint32ModP) {
   {
     RawMachineAssemblerTester<int32_t> m;
     Int32BinopTester bt(&m);
-    bt.AddReturn(m.Int32UMod(bt.param0, bt.param1));
+    bt.AddReturn(m.Uint32Mod(bt.param0, bt.param1));
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t p0 = *i;
@@ -1468,7 +1604,7 @@
   {
     RawMachineAssemblerTester<int32_t> m;
     Int32BinopTester bt(&m);
-    bt.AddReturn(m.Int32Add(bt.param0, m.Int32UMod(bt.param0, bt.param1)));
+    bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Mod(bt.param0, bt.param1)));
     FOR_UINT32_INPUTS(i) {
       FOR_UINT32_INPUTS(j) {
         uint32_t p0 = *i;
@@ -2658,22 +2794,23 @@
 TEST(RunDeadInt32Binops) {
   RawMachineAssemblerTester<int32_t> m;
 
-  const Operator* ops[] = {
-      m.machine()->Word32And(),             m.machine()->Word32Or(),
-      m.machine()->Word32Xor(),             m.machine()->Word32Shl(),
-      m.machine()->Word32Shr(),             m.machine()->Word32Sar(),
-      m.machine()->Word32Ror(),             m.machine()->Word32Equal(),
-      m.machine()->Int32Add(),              m.machine()->Int32Sub(),
-      m.machine()->Int32Mul(),              m.machine()->Int32Div(),
-      m.machine()->Int32UDiv(),             m.machine()->Int32Mod(),
-      m.machine()->Int32UMod(),             m.machine()->Int32LessThan(),
-      m.machine()->Int32LessThanOrEqual(),  m.machine()->Uint32LessThan(),
-      m.machine()->Uint32LessThanOrEqual(), NULL};
+  const Operator* kOps[] = {
+      m.machine()->Word32And(),            m.machine()->Word32Or(),
+      m.machine()->Word32Xor(),            m.machine()->Word32Shl(),
+      m.machine()->Word32Shr(),            m.machine()->Word32Sar(),
+      m.machine()->Word32Ror(),            m.machine()->Word32Equal(),
+      m.machine()->Int32Add(),             m.machine()->Int32Sub(),
+      m.machine()->Int32Mul(),             m.machine()->Int32MulHigh(),
+      m.machine()->Int32Div(),             m.machine()->Uint32Div(),
+      m.machine()->Int32Mod(),             m.machine()->Uint32Mod(),
+      m.machine()->Uint32MulHigh(),        m.machine()->Int32LessThan(),
+      m.machine()->Int32LessThanOrEqual(), m.machine()->Uint32LessThan(),
+      m.machine()->Uint32LessThanOrEqual()};
 
-  for (int i = 0; ops[i] != NULL; i++) {
+  for (size_t i = 0; i < arraysize(kOps); ++i) {
     RawMachineAssemblerTester<int32_t> m(kMachInt32, kMachInt32);
-    int constant = 0x55555 + i;
-    m.NewNode(ops[i], m.Parameter(0), m.Parameter(1));
+    int32_t constant = static_cast<int32_t>(0x55555 + i);
+    m.NewNode(kOps[i], m.Parameter(0), m.Parameter(1));
     m.Return(m.Int32Constant(constant));
 
     CHECK_EQ(constant, m.Call(1, 1));
@@ -3102,6 +3239,38 @@
 }
 
 
+TEST(RunChangeUint32ToFloat64_spilled) {
+  RawMachineAssemblerTester<int32_t> m;
+  const int kNumInputs = 32;
+  int32_t magic = 0x786234;
+  uint32_t input[kNumInputs];
+  double result[kNumInputs];
+  Node* input_node[kNumInputs];
+
+  for (int i = 0; i < kNumInputs; i++) {
+    input_node[i] =
+        m.Load(kMachUint32, m.PointerConstant(&input), m.Int32Constant(i * 4));
+  }
+
+  for (int i = 0; i < kNumInputs; i++) {
+    m.Store(kMachFloat64, m.PointerConstant(&result), m.Int32Constant(i * 8),
+            m.ChangeUint32ToFloat64(input_node[i]));
+  }
+
+  m.Return(m.Int32Constant(magic));
+
+  for (int i = 0; i < kNumInputs; i++) {
+    input[i] = 100 + i;
+  }
+
+  CHECK_EQ(magic, m.Call());
+
+  for (int i = 0; i < kNumInputs; i++) {
+    CHECK_EQ(result[i], static_cast<double>(100 + i));
+  }
+}
+
+
 TEST(RunChangeFloat64ToInt32_A) {
   RawMachineAssemblerTester<int32_t> m;
   int32_t magic = 0x786234;
@@ -3272,6 +3441,38 @@
 }
 
 
+TEST(RunTruncateFloat64ToFloat32_spilled) {
+  RawMachineAssemblerTester<uint32_t> m;
+  const int kNumInputs = 32;
+  int32_t magic = 0x786234;
+  double input[kNumInputs];
+  float result[kNumInputs];
+  Node* input_node[kNumInputs];
+
+  for (int i = 0; i < kNumInputs; i++) {
+    input_node[i] =
+        m.Load(kMachFloat64, m.PointerConstant(&input), m.Int32Constant(i * 8));
+  }
+
+  for (int i = 0; i < kNumInputs; i++) {
+    m.Store(kMachFloat32, m.PointerConstant(&result), m.Int32Constant(i * 4),
+            m.TruncateFloat64ToFloat32(input_node[i]));
+  }
+
+  m.Return(m.Int32Constant(magic));
+
+  for (int i = 0; i < kNumInputs; i++) {
+    input[i] = 0.1 + i;
+  }
+
+  CHECK_EQ(magic, m.Call());
+
+  for (int i = 0; i < kNumInputs; i++) {
+    CHECK_EQ(result[i], DoubleToFloat32(input[i]));
+  }
+}
+
+
 TEST(RunDeadChangeFloat64ToInt32) {
   RawMachineAssemblerTester<int32_t> m;
   const int magic = 0x88abcda4;
@@ -4242,4 +4443,249 @@
   }
 }
 
+
+TEST(RunChangeFloat32ToFloat64) {
+  double actual = 0.0f;
+  float expected = 0.0;
+  RawMachineAssemblerTester<int32_t> m;
+  m.StoreToPointer(
+      &actual, kMachFloat64,
+      m.ChangeFloat32ToFloat64(m.LoadFromPointer(&expected, kMachFloat32)));
+  m.Return(m.Int32Constant(0));
+  FOR_FLOAT32_INPUTS(i) {
+    expected = *i;
+    CHECK_EQ(0, m.Call());
+    CHECK_EQ(expected, actual);
+  }
+}
+
+
+TEST(RunChangeFloat32ToFloat64_spilled) {
+  RawMachineAssemblerTester<int32_t> m;
+  const int kNumInputs = 32;
+  int32_t magic = 0x786234;
+  float input[kNumInputs];
+  double result[kNumInputs];
+  Node* input_node[kNumInputs];
+
+  for (int i = 0; i < kNumInputs; i++) {
+    input_node[i] =
+        m.Load(kMachFloat32, m.PointerConstant(&input), m.Int32Constant(i * 4));
+  }
+
+  for (int i = 0; i < kNumInputs; i++) {
+    m.Store(kMachFloat64, m.PointerConstant(&result), m.Int32Constant(i * 8),
+            m.ChangeFloat32ToFloat64(input_node[i]));
+  }
+
+  m.Return(m.Int32Constant(magic));
+
+  for (int i = 0; i < kNumInputs; i++) {
+    input[i] = 100.9f + i;
+  }
+
+  CHECK_EQ(magic, m.Call());
+
+  for (int i = 0; i < kNumInputs; i++) {
+    CHECK_EQ(result[i], static_cast<double>(input[i]));
+  }
+}
+
+
+TEST(RunTruncateFloat64ToFloat32) {
+  float actual = 0.0f;
+  double input = 0.0;
+  RawMachineAssemblerTester<int32_t> m;
+  m.StoreToPointer(
+      &actual, kMachFloat32,
+      m.TruncateFloat64ToFloat32(m.LoadFromPointer(&input, kMachFloat64)));
+  m.Return(m.Int32Constant(0));
+  FOR_FLOAT64_INPUTS(i) {
+    input = *i;
+    volatile double expected = DoubleToFloat32(input);
+    CHECK_EQ(0, m.Call());
+    CHECK_EQ(expected, actual);
+  }
+}
+
+
+TEST(RunFloat32Constant) {
+  FOR_FLOAT32_INPUTS(i) {
+    float expected = *i;
+    float actual = *i;
+    RawMachineAssemblerTester<int32_t> m;
+    m.StoreToPointer(&actual, kMachFloat32, m.Float32Constant(expected));
+    m.Return(m.Int32Constant(0));
+    CHECK_EQ(0, m.Call());
+    CHECK_EQ(expected, actual);
+  }
+}
+
+
+static double two_30 = 1 << 30;             // 2^30 is a smi boundary.
+static double two_52 = two_30 * (1 << 22);  // 2^52 is a precision boundary.
+static double kValues[] = {0.1,
+                           0.2,
+                           0.49999999999999994,
+                           0.5,
+                           0.7,
+                           1.0 - std::numeric_limits<double>::epsilon(),
+                           -0.1,
+                           -0.49999999999999994,
+                           -0.5,
+                           -0.7,
+                           1.1,
+                           1.0 + std::numeric_limits<double>::epsilon(),
+                           1.5,
+                           1.7,
+                           -1,
+                           -1 + std::numeric_limits<double>::epsilon(),
+                           -1 - std::numeric_limits<double>::epsilon(),
+                           -1.1,
+                           -1.5,
+                           -1.7,
+                           std::numeric_limits<double>::min(),
+                           -std::numeric_limits<double>::min(),
+                           std::numeric_limits<double>::max(),
+                           -std::numeric_limits<double>::max(),
+                           std::numeric_limits<double>::infinity(),
+                           -std::numeric_limits<double>::infinity(),
+                           two_30,
+                           two_30 + 0.1,
+                           two_30 + 0.5,
+                           two_30 + 0.7,
+                           two_30 - 1,
+                           two_30 - 1 + 0.1,
+                           two_30 - 1 + 0.5,
+                           two_30 - 1 + 0.7,
+                           -two_30,
+                           -two_30 + 0.1,
+                           -two_30 + 0.5,
+                           -two_30 + 0.7,
+                           -two_30 + 1,
+                           -two_30 + 1 + 0.1,
+                           -two_30 + 1 + 0.5,
+                           -two_30 + 1 + 0.7,
+                           two_52,
+                           two_52 + 0.1,
+                           two_52 + 0.5,
+                           two_52 + 0.5,
+                           two_52 + 0.7,
+                           two_52 + 0.7,
+                           two_52 - 1,
+                           two_52 - 1 + 0.1,
+                           two_52 - 1 + 0.5,
+                           two_52 - 1 + 0.7,
+                           -two_52,
+                           -two_52 + 0.1,
+                           -two_52 + 0.5,
+                           -two_52 + 0.7,
+                           -two_52 + 1,
+                           -two_52 + 1 + 0.1,
+                           -two_52 + 1 + 0.5,
+                           -two_52 + 1 + 0.7,
+                           two_30,
+                           two_30 - 0.1,
+                           two_30 - 0.5,
+                           two_30 - 0.7,
+                           two_30 - 1,
+                           two_30 - 1 - 0.1,
+                           two_30 - 1 - 0.5,
+                           two_30 - 1 - 0.7,
+                           -two_30,
+                           -two_30 - 0.1,
+                           -two_30 - 0.5,
+                           -two_30 - 0.7,
+                           -two_30 + 1,
+                           -two_30 + 1 - 0.1,
+                           -two_30 + 1 - 0.5,
+                           -two_30 + 1 - 0.7,
+                           two_52,
+                           two_52 - 0.1,
+                           two_52 - 0.5,
+                           two_52 - 0.5,
+                           two_52 - 0.7,
+                           two_52 - 0.7,
+                           two_52 - 1,
+                           two_52 - 1 - 0.1,
+                           two_52 - 1 - 0.5,
+                           two_52 - 1 - 0.7,
+                           -two_52,
+                           -two_52 - 0.1,
+                           -two_52 - 0.5,
+                           -two_52 - 0.7,
+                           -two_52 + 1,
+                           -two_52 + 1 - 0.1,
+                           -two_52 + 1 - 0.5,
+                           -two_52 + 1 - 0.7};
+
+
+TEST(RunFloat64Floor) {
+  double input = -1.0;
+  double result = 0.0;
+  RawMachineAssemblerTester<int32_t> m;
+  if (!m.machine()->HasFloat64Floor()) return;
+  m.StoreToPointer(&result, kMachFloat64,
+                   m.Float64Floor(m.LoadFromPointer(&input, kMachFloat64)));
+  m.Return(m.Int32Constant(0));
+  for (size_t i = 0; i < arraysize(kValues); ++i) {
+    input = kValues[i];
+    CHECK_EQ(0, m.Call());
+    double expected = std::floor(kValues[i]);
+    CHECK_EQ(expected, result);
+  }
+}
+
+
+TEST(RunFloat64Ceil) {
+  double input = -1.0;
+  double result = 0.0;
+  RawMachineAssemblerTester<int32_t> m;
+  if (!m.machine()->HasFloat64Ceil()) return;
+  m.StoreToPointer(&result, kMachFloat64,
+                   m.Float64Ceil(m.LoadFromPointer(&input, kMachFloat64)));
+  m.Return(m.Int32Constant(0));
+  for (size_t i = 0; i < arraysize(kValues); ++i) {
+    input = kValues[i];
+    CHECK_EQ(0, m.Call());
+    double expected = std::ceil(kValues[i]);
+    CHECK_EQ(expected, result);
+  }
+}
+
+
+TEST(RunFloat64RoundTruncate) {
+  double input = -1.0;
+  double result = 0.0;
+  RawMachineAssemblerTester<int32_t> m;
+  if (!m.machine()->HasFloat64Ceil()) return;
+  m.StoreToPointer(
+      &result, kMachFloat64,
+      m.Float64RoundTruncate(m.LoadFromPointer(&input, kMachFloat64)));
+  m.Return(m.Int32Constant(0));
+  for (size_t i = 0; i < arraysize(kValues); ++i) {
+    input = kValues[i];
+    CHECK_EQ(0, m.Call());
+    double expected = trunc(kValues[i]);
+    CHECK_EQ(expected, result);
+  }
+}
+
+
+TEST(RunFloat64RoundTiesAway) {
+  double input = -1.0;
+  double result = 0.0;
+  RawMachineAssemblerTester<int32_t> m;
+  if (!m.machine()->HasFloat64RoundTiesAway()) return;
+  m.StoreToPointer(
+      &result, kMachFloat64,
+      m.Float64RoundTiesAway(m.LoadFromPointer(&input, kMachFloat64)));
+  m.Return(m.Int32Constant(0));
+  for (size_t i = 0; i < arraysize(kValues); ++i) {
+    input = kValues[i];
+    CHECK_EQ(0, m.Call());
+    double expected = round(kValues[i]);
+    CHECK_EQ(expected, result);
+  }
+}
 #endif  // V8_TURBOFAN_TARGET
diff --git a/test/cctest/compiler/test-run-stackcheck.cc b/test/cctest/compiler/test-run-stackcheck.cc
new file mode 100644
index 0000000..8c1664b
--- /dev/null
+++ b/test/cctest/compiler/test-run-stackcheck.cc
@@ -0,0 +1,18 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+
+#include "test/cctest/compiler/function-tester.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+TEST(TerminateAtMethodEntry) {
+  FunctionTester T("(function(a,b) { return 23; })");
+
+  T.CheckCall(T.Val(23));
+  T.isolate->stack_guard()->RequestTerminateExecution();
+  T.CheckThrows(T.undefined(), T.undefined());
+}
diff --git a/test/cctest/compiler/test-schedule.cc b/test/cctest/compiler/test-schedule.cc
index 6c05c05..1eb3547 100644
--- a/test/cctest/compiler/test-schedule.cc
+++ b/test/cctest/compiler/test-schedule.cc
@@ -5,7 +5,6 @@
 #include "src/v8.h"
 
 #include "src/compiler/common-operator.h"
-#include "src/compiler/generic-node-inl.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/machine-operator.h"
 #include "src/compiler/node.h"
@@ -16,26 +15,25 @@
 using namespace v8::internal;
 using namespace v8::internal::compiler;
 
-static SimpleOperator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
-                                     0, 0, "dummy");
+static Operator dummy_operator(IrOpcode::kParameter, Operator::kNoWrite,
+                               "dummy", 0, 0, 0, 0, 0, 0);
 
 TEST(TestScheduleAllocation) {
   HandleAndZoneScope scope;
   Schedule schedule(scope.main_zone());
 
   CHECK_NE(NULL, schedule.start());
-  CHECK_EQ(schedule.start(), *(schedule.all_blocks().begin()));
+  CHECK_EQ(schedule.start(), schedule.GetBlockById(BasicBlock::Id::FromInt(0)));
 }
 
 
 TEST(TestScheduleAddNode) {
   HandleAndZoneScope scope;
+  Schedule schedule(scope.main_zone());
   Graph graph(scope.main_zone());
   Node* n0 = graph.NewNode(&dummy_operator);
   Node* n1 = graph.NewNode(&dummy_operator);
 
-  Schedule schedule(scope.main_zone());
-
   BasicBlock* entry = schedule.start();
   schedule.AddNode(entry, n0);
   schedule.AddNode(entry, n1);
@@ -51,50 +49,49 @@
 
 TEST(TestScheduleAddGoto) {
   HandleAndZoneScope scope;
-
   Schedule schedule(scope.main_zone());
+
   BasicBlock* entry = schedule.start();
   BasicBlock* next = schedule.NewBasicBlock();
 
   schedule.AddGoto(entry, next);
 
-  CHECK_EQ(0, entry->PredecessorCount());
-  CHECK_EQ(1, entry->SuccessorCount());
+  CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
+  CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
   CHECK_EQ(next, entry->SuccessorAt(0));
 
-  CHECK_EQ(1, next->PredecessorCount());
+  CHECK_EQ(1, static_cast<int>(next->PredecessorCount()));
   CHECK_EQ(entry, next->PredecessorAt(0));
-  CHECK_EQ(0, next->SuccessorCount());
+  CHECK_EQ(0, static_cast<int>(next->SuccessorCount()));
 }
 
 
 TEST(TestScheduleAddBranch) {
   HandleAndZoneScope scope;
   Schedule schedule(scope.main_zone());
-
-  BasicBlock* entry = schedule.start();
-  BasicBlock* tblock = schedule.NewBasicBlock();
-  BasicBlock* fblock = schedule.NewBasicBlock();
-
   Graph graph(scope.main_zone());
   CommonOperatorBuilder common(scope.main_zone());
   Node* n0 = graph.NewNode(&dummy_operator);
   Node* b = graph.NewNode(common.Branch(), n0);
 
+  BasicBlock* entry = schedule.start();
+  BasicBlock* tblock = schedule.NewBasicBlock();
+  BasicBlock* fblock = schedule.NewBasicBlock();
+
   schedule.AddBranch(entry, b, tblock, fblock);
 
-  CHECK_EQ(0, entry->PredecessorCount());
-  CHECK_EQ(2, entry->SuccessorCount());
+  CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
+  CHECK_EQ(2, static_cast<int>(entry->SuccessorCount()));
   CHECK_EQ(tblock, entry->SuccessorAt(0));
   CHECK_EQ(fblock, entry->SuccessorAt(1));
 
-  CHECK_EQ(1, tblock->PredecessorCount());
+  CHECK_EQ(1, static_cast<int>(tblock->PredecessorCount()));
   CHECK_EQ(entry, tblock->PredecessorAt(0));
-  CHECK_EQ(0, tblock->SuccessorCount());
+  CHECK_EQ(0, static_cast<int>(tblock->SuccessorCount()));
 
-  CHECK_EQ(1, fblock->PredecessorCount());
+  CHECK_EQ(1, static_cast<int>(fblock->PredecessorCount()));
   CHECK_EQ(entry, fblock->PredecessorAt(0));
-  CHECK_EQ(0, fblock->SuccessorCount());
+  CHECK_EQ(0, static_cast<int>(fblock->SuccessorCount()));
 }
 
 
@@ -106,8 +103,8 @@
   BasicBlock* entry = schedule.start();
   schedule.AddReturn(entry, n0);
 
-  CHECK_EQ(0, entry->PredecessorCount());
-  CHECK_EQ(1, entry->SuccessorCount());
+  CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
+  CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
   CHECK_EQ(schedule.end(), entry->SuccessorAt(0));
 }
 
@@ -120,18 +117,53 @@
   BasicBlock* entry = schedule.start();
   schedule.AddThrow(entry, n0);
 
-  CHECK_EQ(0, entry->PredecessorCount());
-  CHECK_EQ(1, entry->SuccessorCount());
+  CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
+  CHECK_EQ(1, static_cast<int>(entry->SuccessorCount()));
   CHECK_EQ(schedule.end(), entry->SuccessorAt(0));
 }
 
 
+TEST(TestScheduleInsertBranch) {
+  HandleAndZoneScope scope;
+  Schedule schedule(scope.main_zone());
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+  Node* n0 = graph.NewNode(&dummy_operator);
+  Node* n1 = graph.NewNode(&dummy_operator);
+  Node* b = graph.NewNode(common.Branch(), n1);
+
+  BasicBlock* entry = schedule.start();
+  BasicBlock* tblock = schedule.NewBasicBlock();
+  BasicBlock* fblock = schedule.NewBasicBlock();
+  BasicBlock* merge = schedule.NewBasicBlock();
+  schedule.AddReturn(entry, n0);
+  schedule.AddGoto(tblock, merge);
+  schedule.AddGoto(fblock, merge);
+
+  schedule.InsertBranch(entry, merge, b, tblock, fblock);
+
+  CHECK_EQ(0, static_cast<int>(entry->PredecessorCount()));
+  CHECK_EQ(2, static_cast<int>(entry->SuccessorCount()));
+  CHECK_EQ(tblock, entry->SuccessorAt(0));
+  CHECK_EQ(fblock, entry->SuccessorAt(1));
+
+  CHECK_EQ(2, static_cast<int>(merge->PredecessorCount()));
+  CHECK_EQ(1, static_cast<int>(merge->SuccessorCount()));
+  CHECK_EQ(schedule.end(), merge->SuccessorAt(0));
+
+  CHECK_EQ(1, static_cast<int>(schedule.end()->PredecessorCount()));
+  CHECK_EQ(0, static_cast<int>(schedule.end()->SuccessorCount()));
+  CHECK_EQ(merge, schedule.end()->PredecessorAt(0));
+}
+
+
 TEST(BuildMulNodeGraph) {
   HandleAndZoneScope scope;
   Schedule schedule(scope.main_zone());
   Graph graph(scope.main_zone());
   CommonOperatorBuilder common(scope.main_zone());
-  MachineOperatorBuilder machine;
+  // TODO(titzer): use test operators.
+  MachineOperatorBuilder machine(scope.main_zone());
 
   Node* start = graph.NewNode(common.Start(0));
   graph.SetStart(start);
diff --git a/test/cctest/compiler/test-scheduler.cc b/test/cctest/compiler/test-scheduler.cc
index cf33123..1b79ed5 100644
--- a/test/cctest/compiler/test-scheduler.cc
+++ b/test/cctest/compiler/test-scheduler.cc
@@ -3,31 +3,71 @@
 // found in the LICENSE file.
 
 #include "src/v8.h"
-#include "test/cctest/cctest.h"
 
+#include "src/compiler/access-builder.h"
 #include "src/compiler/common-operator.h"
-#include "src/compiler/generic-node-inl.h"
-#include "src/compiler/generic-node.h"
 #include "src/compiler/graph.h"
 #include "src/compiler/graph-visualizer.h"
 #include "src/compiler/js-operator.h"
-#include "src/compiler/machine-operator.h"
 #include "src/compiler/node.h"
+#include "src/compiler/opcodes.h"
 #include "src/compiler/operator.h"
 #include "src/compiler/schedule.h"
 #include "src/compiler/scheduler.h"
+#include "src/compiler/simplified-operator.h"
 #include "src/compiler/verifier.h"
+#include "test/cctest/cctest.h"
 
 using namespace v8::internal;
 using namespace v8::internal::compiler;
 
+Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0, 0, 1,
+                 0, 0);
+
 // TODO(titzer): pull RPO tests out to their own file.
+static void CheckRPONumbers(BasicBlockVector* order, size_t expected,
+                            bool loops_allowed) {
+  CHECK(expected == order->size());
+  for (int i = 0; i < static_cast<int>(order->size()); i++) {
+    CHECK(order->at(i)->rpo_number() == i);
+    if (!loops_allowed) {
+      CHECK_EQ(NULL, order->at(i)->loop_end());
+      CHECK_EQ(NULL, order->at(i)->loop_header());
+    }
+  }
+}
+
+
+static void CheckLoop(BasicBlockVector* order, BasicBlock** blocks,
+                      int body_size) {
+  BasicBlock* header = blocks[0];
+  BasicBlock* end = header->loop_end();
+  CHECK_NE(NULL, end);
+  CHECK_GT(end->rpo_number(), 0);
+  CHECK_EQ(body_size, end->rpo_number() - header->rpo_number());
+  for (int i = 0; i < body_size; i++) {
+    CHECK_GE(blocks[i]->rpo_number(), header->rpo_number());
+    CHECK_LT(blocks[i]->rpo_number(), end->rpo_number());
+    CHECK(header->LoopContains(blocks[i]));
+    CHECK(header->IsLoopHeader() || blocks[i]->loop_header() == header);
+  }
+  if (header->rpo_number() > 0) {
+    CHECK_NE(order->at(header->rpo_number() - 1)->loop_header(), header);
+  }
+  if (end->rpo_number() < static_cast<int>(order->size())) {
+    CHECK_NE(order->at(end->rpo_number())->loop_header(), header);
+  }
+}
+
+
 struct TestLoop {
   int count;
   BasicBlock** nodes;
   BasicBlock* header() { return nodes[0]; }
   BasicBlock* last() { return nodes[count - 1]; }
   ~TestLoop() { delete[] nodes; }
+
+  void Check(BasicBlockVector* order) { CheckLoop(order, nodes, count); }
 };
 
 
@@ -37,36 +77,15 @@
   loop->nodes = new BasicBlock* [count];
   for (int i = 0; i < count; i++) {
     loop->nodes[i] = schedule->NewBasicBlock();
-    if (i > 0) schedule->AddSuccessor(loop->nodes[i - 1], loop->nodes[i]);
+    if (i > 0) {
+      schedule->AddSuccessorForTesting(loop->nodes[i - 1], loop->nodes[i]);
+    }
   }
-  schedule->AddSuccessor(loop->nodes[count - 1], loop->nodes[0]);
+  schedule->AddSuccessorForTesting(loop->nodes[count - 1], loop->nodes[0]);
   return loop;
 }
 
 
-static void CheckRPONumbers(BasicBlockVector* order, int expected,
-                            bool loops_allowed) {
-  CHECK_EQ(expected, static_cast<int>(order->size()));
-  for (int i = 0; i < static_cast<int>(order->size()); i++) {
-    CHECK(order->at(i)->rpo_number_ == i);
-    if (!loops_allowed) CHECK_LT(order->at(i)->loop_end_, 0);
-  }
-}
-
-
-static void CheckLoopContains(BasicBlock** blocks, int body_size) {
-  BasicBlock* header = blocks[0];
-  CHECK_GT(header->loop_end_, 0);
-  CHECK_EQ(body_size, (header->loop_end_ - header->rpo_number_));
-  for (int i = 0; i < body_size; i++) {
-    int num = blocks[i]->rpo_number_;
-    CHECK(num >= header->rpo_number_ && num < header->loop_end_);
-    CHECK(header->LoopContains(blocks[i]));
-    CHECK(header->IsLoopHeader() || blocks[i]->loop_header_ == header);
-  }
-}
-
-
 static int GetScheduledNodeCount(Schedule* schedule) {
   int node_count = 0;
   for (BasicBlockVectorIter i = schedule->rpo_order()->begin();
@@ -76,7 +95,7 @@
          ++j) {
       ++node_count;
     }
-    BasicBlock::Control control = block->control_;
+    BasicBlock::Control control = block->control();
     if (control != BasicBlock::kNone) {
       ++node_count;
     }
@@ -91,11 +110,11 @@
     os << AsDOT(*graph);
   }
 
-  Schedule* schedule = Scheduler::ComputeSchedule(graph);
+  Schedule* schedule = Scheduler::ComputeSchedule(graph->zone(), graph);
 
   if (FLAG_trace_turbo_scheduler) {
     OFStream os(stdout);
-    os << *schedule << endl;
+    os << *schedule << std::endl;
   }
   ScheduleVerifier::Run(schedule);
   CHECK_EQ(expected, GetScheduledNodeCount(schedule));
@@ -107,7 +126,8 @@
   HandleAndZoneScope scope;
   Schedule schedule(scope.main_zone());
 
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
   CheckRPONumbers(order, 1, false);
   CHECK_EQ(schedule.start(), order->at(0));
 }
@@ -118,7 +138,8 @@
   Schedule schedule(scope.main_zone());
 
   schedule.AddGoto(schedule.start(), schedule.end());
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
   CheckRPONumbers(order, 2, false);
   CHECK_EQ(schedule.start(), order->at(0));
   CHECK_EQ(schedule.end(), order->at(1));
@@ -134,18 +155,18 @@
     BasicBlock* last = schedule.start();
     for (int j = 0; j < i; j++) {
       BasicBlock* block = schedule.NewBasicBlock();
+      block->set_deferred(i & 1);
       schedule.AddGoto(last, block);
       last = block;
     }
-    BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+    BasicBlockVector* order =
+        Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
     CheckRPONumbers(order, 1 + i, false);
 
-    Schedule::BasicBlocks blocks(schedule.all_blocks());
-    for (Schedule::BasicBlocks::iterator iter = blocks.begin();
-         iter != blocks.end(); ++iter) {
-      BasicBlock* block = *iter;
-      if (block->rpo_number_ >= 0 && block->SuccessorCount() == 1) {
-        CHECK(block->rpo_number_ + 1 == block->SuccessorAt(0)->rpo_number_);
+    for (size_t i = 0; i < schedule.BasicBlockCount(); i++) {
+      BasicBlock* block = schedule.GetBlockById(BasicBlock::Id::FromSize(i));
+      if (block->rpo_number() >= 0 && block->SuccessorCount() == 1) {
+        CHECK(block->rpo_number() + 1 == block->SuccessorAt(0)->rpo_number());
       }
     }
   }
@@ -155,23 +176,26 @@
 TEST(RPOSelfLoop) {
   HandleAndZoneScope scope;
   Schedule schedule(scope.main_zone());
-  schedule.AddSuccessor(schedule.start(), schedule.start());
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  schedule.AddSuccessorForTesting(schedule.start(), schedule.start());
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
   CheckRPONumbers(order, 1, true);
   BasicBlock* loop[] = {schedule.start()};
-  CheckLoopContains(loop, 1);
+  CheckLoop(order, loop, 1);
 }
 
 
 TEST(RPOEntryLoop) {
   HandleAndZoneScope scope;
   Schedule schedule(scope.main_zone());
-  schedule.AddSuccessor(schedule.start(), schedule.end());
-  schedule.AddSuccessor(schedule.end(), schedule.start());
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  BasicBlock* body = schedule.NewBasicBlock();
+  schedule.AddSuccessorForTesting(schedule.start(), body);
+  schedule.AddSuccessorForTesting(body, schedule.start());
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
   CheckRPONumbers(order, 2, true);
-  BasicBlock* loop[] = {schedule.start(), schedule.end()};
-  CheckLoopContains(loop, 2);
+  BasicBlock* loop[] = {schedule.start(), body};
+  CheckLoop(order, loop, 2);
 }
 
 
@@ -179,10 +203,11 @@
   HandleAndZoneScope scope;
   Schedule schedule(scope.main_zone());
   SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2));
-  schedule.AddSuccessor(schedule.start(), loop1->header());
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  schedule.AddSuccessorForTesting(schedule.start(), loop1->header());
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
   CheckRPONumbers(order, 3, true);
-  CheckLoopContains(loop1->nodes, loop1->count);
+  loop1->Check(order);
 }
 
 
@@ -190,11 +215,12 @@
   HandleAndZoneScope scope;
   Schedule schedule(scope.main_zone());
   SmartPointer<TestLoop> loop1(CreateLoop(&schedule, 2));
-  schedule.AddSuccessor(schedule.start(), loop1->header());
-  schedule.AddSuccessor(loop1->last(), schedule.start());
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  schedule.AddSuccessorForTesting(schedule.start(), loop1->header());
+  schedule.AddSuccessorForTesting(loop1->last(), schedule.start());
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
   CheckRPONumbers(order, 3, true);
-  CheckLoopContains(loop1->nodes, loop1->count);
+  loop1->Check(order);
 }
 
 
@@ -207,18 +233,19 @@
   BasicBlock* C = schedule.NewBasicBlock();
   BasicBlock* D = schedule.end();
 
-  schedule.AddSuccessor(A, B);
-  schedule.AddSuccessor(A, C);
-  schedule.AddSuccessor(B, D);
-  schedule.AddSuccessor(C, D);
+  schedule.AddSuccessorForTesting(A, B);
+  schedule.AddSuccessorForTesting(A, C);
+  schedule.AddSuccessorForTesting(B, D);
+  schedule.AddSuccessorForTesting(C, D);
 
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
   CheckRPONumbers(order, 4, false);
 
-  CHECK_EQ(0, A->rpo_number_);
-  CHECK((B->rpo_number_ == 1 && C->rpo_number_ == 2) ||
-        (B->rpo_number_ == 2 && C->rpo_number_ == 1));
-  CHECK_EQ(3, D->rpo_number_);
+  CHECK_EQ(0, A->rpo_number());
+  CHECK((B->rpo_number() == 1 && C->rpo_number() == 2) ||
+        (B->rpo_number() == 2 && C->rpo_number() == 1));
+  CHECK_EQ(3, D->rpo_number());
 }
 
 
@@ -231,15 +258,16 @@
   BasicBlock* C = schedule.NewBasicBlock();
   BasicBlock* D = schedule.end();
 
-  schedule.AddSuccessor(A, B);
-  schedule.AddSuccessor(B, C);
-  schedule.AddSuccessor(C, B);
-  schedule.AddSuccessor(C, D);
+  schedule.AddSuccessorForTesting(A, B);
+  schedule.AddSuccessorForTesting(B, C);
+  schedule.AddSuccessorForTesting(C, B);
+  schedule.AddSuccessorForTesting(C, D);
 
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
   CheckRPONumbers(order, 4, true);
   BasicBlock* loop[] = {B, C};
-  CheckLoopContains(loop, 2);
+  CheckLoop(order, loop, 2);
 }
 
 
@@ -252,15 +280,16 @@
   BasicBlock* C = schedule.NewBasicBlock();
   BasicBlock* D = schedule.end();
 
-  schedule.AddSuccessor(A, B);
-  schedule.AddSuccessor(B, C);
-  schedule.AddSuccessor(C, B);
-  schedule.AddSuccessor(B, D);
+  schedule.AddSuccessorForTesting(A, B);
+  schedule.AddSuccessorForTesting(B, C);
+  schedule.AddSuccessorForTesting(C, B);
+  schedule.AddSuccessorForTesting(B, D);
 
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
   CheckRPONumbers(order, 4, true);
   BasicBlock* loop[] = {B, C};
-  CheckLoopContains(loop, 2);
+  CheckLoop(order, loop, 2);
 }
 
 
@@ -277,32 +306,33 @@
     BasicBlock* F = schedule.NewBasicBlock();
     BasicBlock* G = schedule.end();
 
-    schedule.AddSuccessor(A, B);
-    schedule.AddSuccessor(B, C);
-    schedule.AddSuccessor(C, D);
-    schedule.AddSuccessor(D, E);
-    schedule.AddSuccessor(E, F);
-    schedule.AddSuccessor(F, B);
-    schedule.AddSuccessor(B, G);
+    schedule.AddSuccessorForTesting(A, B);
+    schedule.AddSuccessorForTesting(B, C);
+    schedule.AddSuccessorForTesting(C, D);
+    schedule.AddSuccessorForTesting(D, E);
+    schedule.AddSuccessorForTesting(E, F);
+    schedule.AddSuccessorForTesting(F, B);
+    schedule.AddSuccessorForTesting(B, G);
 
     // Throw in extra backedges from time to time.
-    if (i == 1) schedule.AddSuccessor(B, B);
-    if (i == 2) schedule.AddSuccessor(C, B);
-    if (i == 3) schedule.AddSuccessor(D, B);
-    if (i == 4) schedule.AddSuccessor(E, B);
-    if (i == 5) schedule.AddSuccessor(F, B);
+    if (i == 1) schedule.AddSuccessorForTesting(B, B);
+    if (i == 2) schedule.AddSuccessorForTesting(C, B);
+    if (i == 3) schedule.AddSuccessorForTesting(D, B);
+    if (i == 4) schedule.AddSuccessorForTesting(E, B);
+    if (i == 5) schedule.AddSuccessorForTesting(F, B);
 
     // Throw in extra loop exits from time to time.
-    if (i == 6) schedule.AddSuccessor(B, G);
-    if (i == 7) schedule.AddSuccessor(C, G);
-    if (i == 8) schedule.AddSuccessor(D, G);
-    if (i == 9) schedule.AddSuccessor(E, G);
-    if (i == 10) schedule.AddSuccessor(F, G);
+    if (i == 6) schedule.AddSuccessorForTesting(B, G);
+    if (i == 7) schedule.AddSuccessorForTesting(C, G);
+    if (i == 8) schedule.AddSuccessorForTesting(D, G);
+    if (i == 9) schedule.AddSuccessorForTesting(E, G);
+    if (i == 10) schedule.AddSuccessorForTesting(F, G);
 
-    BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+    BasicBlockVector* order =
+        Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
     CheckRPONumbers(order, 7, true);
     BasicBlock* loop[] = {B, C, D, E, F};
-    CheckLoopContains(loop, 5);
+    CheckLoop(order, loop, 5);
   }
 }
 
@@ -318,21 +348,22 @@
   BasicBlock* E = schedule.NewBasicBlock();
   BasicBlock* F = schedule.end();
 
-  schedule.AddSuccessor(A, B);
-  schedule.AddSuccessor(B, C);
-  schedule.AddSuccessor(C, D);
-  schedule.AddSuccessor(D, C);
-  schedule.AddSuccessor(D, E);
-  schedule.AddSuccessor(E, B);
-  schedule.AddSuccessor(E, F);
+  schedule.AddSuccessorForTesting(A, B);
+  schedule.AddSuccessorForTesting(B, C);
+  schedule.AddSuccessorForTesting(C, D);
+  schedule.AddSuccessorForTesting(D, C);
+  schedule.AddSuccessorForTesting(D, E);
+  schedule.AddSuccessorForTesting(E, B);
+  schedule.AddSuccessorForTesting(E, F);
 
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
   CheckRPONumbers(order, 6, true);
   BasicBlock* loop1[] = {B, C, D, E};
-  CheckLoopContains(loop1, 4);
+  CheckLoop(order, loop1, 4);
 
   BasicBlock* loop2[] = {C, D};
-  CheckLoopContains(loop2, 2);
+  CheckLoop(order, loop2, 2);
 }
 
 
@@ -349,28 +380,29 @@
   BasicBlock* G = schedule.NewBasicBlock();
   BasicBlock* H = schedule.end();
 
-  schedule.AddSuccessor(A, B);
-  schedule.AddSuccessor(B, C);
-  schedule.AddSuccessor(C, D);
-  schedule.AddSuccessor(D, E);
-  schedule.AddSuccessor(E, F);
-  schedule.AddSuccessor(F, G);
-  schedule.AddSuccessor(G, H);
+  schedule.AddSuccessorForTesting(A, B);
+  schedule.AddSuccessorForTesting(B, C);
+  schedule.AddSuccessorForTesting(C, D);
+  schedule.AddSuccessorForTesting(D, E);
+  schedule.AddSuccessorForTesting(E, F);
+  schedule.AddSuccessorForTesting(F, G);
+  schedule.AddSuccessorForTesting(G, H);
 
-  schedule.AddSuccessor(E, D);
-  schedule.AddSuccessor(F, C);
-  schedule.AddSuccessor(G, B);
+  schedule.AddSuccessorForTesting(E, D);
+  schedule.AddSuccessorForTesting(F, C);
+  schedule.AddSuccessorForTesting(G, B);
 
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
   CheckRPONumbers(order, 8, true);
   BasicBlock* loop1[] = {B, C, D, E, F, G};
-  CheckLoopContains(loop1, 6);
+  CheckLoop(order, loop1, 6);
 
   BasicBlock* loop2[] = {C, D, E, F};
-  CheckLoopContains(loop2, 4);
+  CheckLoop(order, loop2, 4);
 
   BasicBlock* loop3[] = {D, E};
-  CheckLoopContains(loop3, 2);
+  CheckLoop(order, loop3, 2);
 }
 
 
@@ -384,17 +416,18 @@
   BasicBlock* A = schedule.start();
   BasicBlock* E = schedule.end();
 
-  schedule.AddSuccessor(A, loop1->header());
-  schedule.AddSuccessor(loop1->header(), loop2->header());
-  schedule.AddSuccessor(loop2->last(), E);
+  schedule.AddSuccessorForTesting(A, loop1->header());
+  schedule.AddSuccessorForTesting(loop1->header(), loop2->header());
+  schedule.AddSuccessorForTesting(loop2->last(), E);
 
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
 
-  CheckLoopContains(loop1->nodes, loop1->count);
+  CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
+           static_cast<int>(order->size()));
 
-  CHECK_EQ(schedule.BasicBlockCount(), static_cast<int>(order->size()));
-  CheckLoopContains(loop1->nodes, loop1->count);
-  CheckLoopContains(loop2->nodes, loop2->count);
+  loop1->Check(order);
+  loop2->Check(order);
 }
 
 
@@ -409,18 +442,18 @@
   BasicBlock* S = schedule.NewBasicBlock();
   BasicBlock* E = schedule.end();
 
-  schedule.AddSuccessor(A, loop1->header());
-  schedule.AddSuccessor(loop1->header(), S);
-  schedule.AddSuccessor(S, loop2->header());
-  schedule.AddSuccessor(loop2->last(), E);
+  schedule.AddSuccessorForTesting(A, loop1->header());
+  schedule.AddSuccessorForTesting(loop1->header(), S);
+  schedule.AddSuccessorForTesting(S, loop2->header());
+  schedule.AddSuccessorForTesting(loop2->last(), E);
 
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
 
-  CheckLoopContains(loop1->nodes, loop1->count);
-
-  CHECK_EQ(schedule.BasicBlockCount(), static_cast<int>(order->size()));
-  CheckLoopContains(loop1->nodes, loop1->count);
-  CheckLoopContains(loop2->nodes, loop2->count);
+  CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
+           static_cast<int>(order->size()));
+  loop1->Check(order);
+  loop2->Check(order);
 }
 
 
@@ -435,15 +468,16 @@
       BasicBlock* A = schedule.start();
       BasicBlock* E = schedule.end();
 
-      schedule.AddSuccessor(A, loop1->header());
-      schedule.AddSuccessor(loop1->nodes[exit], loop2->header());
-      schedule.AddSuccessor(loop2->nodes[exit], E);
-      BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
-      CheckLoopContains(loop1->nodes, loop1->count);
+      schedule.AddSuccessorForTesting(A, loop1->header());
+      schedule.AddSuccessorForTesting(loop1->nodes[exit], loop2->header());
+      schedule.AddSuccessorForTesting(loop2->nodes[exit], E);
+      BasicBlockVector* order =
+          Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
 
-      CHECK_EQ(schedule.BasicBlockCount(), static_cast<int>(order->size()));
-      CheckLoopContains(loop1->nodes, loop1->count);
-      CheckLoopContains(loop2->nodes, loop2->count);
+      CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
+               static_cast<int>(order->size()));
+      loop1->Check(order);
+      loop2->Check(order);
     }
   }
 }
@@ -461,23 +495,23 @@
   BasicBlock* C = schedule.NewBasicBlock();
   BasicBlock* E = schedule.end();
 
-  schedule.AddSuccessor(A, B);
-  schedule.AddSuccessor(B, loop1->header());
-  schedule.AddSuccessor(loop1->header(), loop2->header());
-  schedule.AddSuccessor(loop2->last(), C);
-  schedule.AddSuccessor(C, E);
-  schedule.AddSuccessor(C, B);
+  schedule.AddSuccessorForTesting(A, B);
+  schedule.AddSuccessorForTesting(B, loop1->header());
+  schedule.AddSuccessorForTesting(loop1->header(), loop2->header());
+  schedule.AddSuccessorForTesting(loop2->last(), C);
+  schedule.AddSuccessorForTesting(C, E);
+  schedule.AddSuccessorForTesting(C, B);
 
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
 
-  CheckLoopContains(loop1->nodes, loop1->count);
-
-  CHECK_EQ(schedule.BasicBlockCount(), static_cast<int>(order->size()));
-  CheckLoopContains(loop1->nodes, loop1->count);
-  CheckLoopContains(loop2->nodes, loop2->count);
+  CHECK_EQ(static_cast<int>(schedule.BasicBlockCount()),
+           static_cast<int>(order->size()));
+  loop1->Check(order);
+  loop2->Check(order);
 
   BasicBlock* loop3[] = {B, loop1->nodes[0], loop2->nodes[0], C};
-  CheckLoopContains(loop3, 4);
+  CheckLoop(order, loop3, 4);
 }
 
 
@@ -492,15 +526,16 @@
       BasicBlock* E = schedule.end();
 
       SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
-      schedule.AddSuccessor(A, loop1->header());
-      schedule.AddSuccessor(loop1->last(), E);
+      schedule.AddSuccessorForTesting(A, loop1->header());
+      schedule.AddSuccessorForTesting(loop1->last(), E);
 
-      schedule.AddSuccessor(loop1->nodes[i], loop1->header());
-      schedule.AddSuccessor(loop1->nodes[j], E);
+      schedule.AddSuccessorForTesting(loop1->nodes[i], loop1->header());
+      schedule.AddSuccessorForTesting(loop1->nodes[j], E);
 
-      BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+      BasicBlockVector* order =
+          Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
       CheckRPONumbers(order, schedule.BasicBlockCount(), true);
-      CheckLoopContains(loop1->nodes, loop1->count);
+      loop1->Check(order);
     }
   }
 }
@@ -518,16 +553,17 @@
       BasicBlock* E = schedule.end();
 
       SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
-      schedule.AddSuccessor(A, loop1->header());
-      schedule.AddSuccessor(loop1->last(), E);
+      schedule.AddSuccessorForTesting(A, loop1->header());
+      schedule.AddSuccessorForTesting(loop1->last(), E);
 
-      schedule.AddSuccessor(loop1->nodes[i], loop1->header());
-      schedule.AddSuccessor(loop1->nodes[j], D);
-      schedule.AddSuccessor(D, E);
+      schedule.AddSuccessorForTesting(loop1->nodes[i], loop1->header());
+      schedule.AddSuccessorForTesting(loop1->nodes[j], D);
+      schedule.AddSuccessorForTesting(D, E);
 
-      BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+      BasicBlockVector* order =
+          Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
       CheckRPONumbers(order, schedule.BasicBlockCount(), true);
-      CheckLoopContains(loop1->nodes, loop1->count);
+      loop1->Check(order);
     }
   }
 }
@@ -543,18 +579,19 @@
     BasicBlock* E = schedule.end();
 
     SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
-    schedule.AddSuccessor(A, loop1->header());
-    schedule.AddSuccessor(loop1->last(), E);
+    schedule.AddSuccessorForTesting(A, loop1->header());
+    schedule.AddSuccessorForTesting(loop1->last(), E);
 
     for (int j = 0; j < size; j++) {
       BasicBlock* O = schedule.NewBasicBlock();
-      schedule.AddSuccessor(loop1->nodes[j], O);
-      schedule.AddSuccessor(O, E);
+      schedule.AddSuccessorForTesting(loop1->nodes[j], O);
+      schedule.AddSuccessorForTesting(O, E);
     }
 
-    BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+    BasicBlockVector* order =
+        Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
     CheckRPONumbers(order, schedule.BasicBlockCount(), true);
-    CheckLoopContains(loop1->nodes, loop1->count);
+    loop1->Check(order);
   }
 }
 
@@ -568,22 +605,23 @@
     BasicBlock* A = schedule.start();
     BasicBlock* E = schedule.end();
     SmartPointer<TestLoop> loop1(CreateLoop(&schedule, size));
-    schedule.AddSuccessor(A, loop1->header());
-    schedule.AddSuccessor(loop1->last(), E);
+    schedule.AddSuccessorForTesting(A, loop1->header());
+    schedule.AddSuccessorForTesting(loop1->last(), E);
 
     TestLoop** loopN = new TestLoop* [size];
     for (int j = 0; j < size; j++) {
       loopN[j] = CreateLoop(&schedule, 2);
-      schedule.AddSuccessor(loop1->nodes[j], loopN[j]->header());
-      schedule.AddSuccessor(loopN[j]->last(), E);
+      schedule.AddSuccessorForTesting(loop1->nodes[j], loopN[j]->header());
+      schedule.AddSuccessorForTesting(loopN[j]->last(), E);
     }
 
-    BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+    BasicBlockVector* order =
+        Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
     CheckRPONumbers(order, schedule.BasicBlockCount(), true);
-    CheckLoopContains(loop1->nodes, loop1->count);
+    loop1->Check(order);
 
     for (int j = 0; j < size; j++) {
-      CheckLoopContains(loopN[j]->nodes, loopN[j]->count);
+      loopN[j]->Check(order);
       delete loopN[j];
     }
     delete[] loopN;
@@ -598,22 +636,23 @@
   BasicBlock* A = schedule.start();
   BasicBlock* B = schedule.NewBasicBlock();
   BasicBlock* C = schedule.NewBasicBlock();
-  BasicBlock* D = schedule.end();
+  BasicBlock* D = schedule.NewBasicBlock();
   BasicBlock* E = schedule.NewBasicBlock();
 
-  schedule.AddSuccessor(A, B);
-  schedule.AddSuccessor(B, C);
-  schedule.AddSuccessor(B, D);
-  schedule.AddSuccessor(B, E);
-  schedule.AddSuccessor(C, B);
-  schedule.AddSuccessor(D, B);
-  schedule.AddSuccessor(E, B);
+  schedule.AddSuccessorForTesting(A, B);
+  schedule.AddSuccessorForTesting(B, C);
+  schedule.AddSuccessorForTesting(B, D);
+  schedule.AddSuccessorForTesting(B, E);
+  schedule.AddSuccessorForTesting(C, B);
+  schedule.AddSuccessorForTesting(D, B);
+  schedule.AddSuccessorForTesting(E, B);
 
-  BasicBlockVector* order = Scheduler::ComputeSpecialRPO(&schedule);
+  BasicBlockVector* order =
+      Scheduler::ComputeSpecialRPO(scope.main_zone(), &schedule);
   CheckRPONumbers(order, 5, true);
 
   BasicBlock* loop1[] = {B, C, D, E};
-  CheckLoopContains(loop1, 4);
+  CheckLoop(order, loop1, 4);
 }
 
 
@@ -624,7 +663,7 @@
   graph.SetStart(graph.NewNode(builder.Start(0)));
   graph.SetEnd(graph.NewNode(builder.End(), graph.start()));
 
-  USE(Scheduler::ComputeSchedule(&graph));
+  USE(Scheduler::ComputeSchedule(scope.main_zone(), &graph));
 }
 
 
@@ -639,7 +678,7 @@
 
   graph.SetEnd(graph.NewNode(builder.End(), ret));
 
-  USE(Scheduler::ComputeSchedule(&graph));
+  USE(Scheduler::ComputeSchedule(scope.main_zone(), &graph));
 }
 
 
@@ -678,9 +717,10 @@
   JSOperatorBuilder js_builder(scope.main_zone());
   const Operator* op;
 
-  Handle<Object> object =
-      Handle<Object>(isolate->heap()->undefined_value(), isolate);
-  Unique<Object> unique_constant = Unique<Object>::CreateUninitialized(object);
+  Handle<HeapObject> object =
+      Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
+  Unique<HeapObject> unique_constant =
+      Unique<HeapObject>::CreateUninitialized(object);
 
   // Manually transcripted code for:
   // function turbo_fan_test(a, b, c, y) {
@@ -823,9 +863,10 @@
   JSOperatorBuilder js_builder(scope.main_zone());
   const Operator* op;
 
-  Handle<Object> object =
-      Handle<Object>(isolate->heap()->undefined_value(), isolate);
-  Unique<Object> unique_constant = Unique<Object>::CreateUninitialized(object);
+  Handle<HeapObject> object =
+      Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
+  Unique<HeapObject> unique_constant =
+      Unique<HeapObject>::CreateUninitialized(object);
 
   // Manually transcripted code for:
   // function turbo_fan_test(a, b) {
@@ -935,9 +976,10 @@
   JSOperatorBuilder js_builder(scope.main_zone());
   const Operator* op;
 
-  Handle<Object> object =
-      Handle<Object>(isolate->heap()->undefined_value(), isolate);
-  Unique<Object> unique_constant = Unique<Object>::CreateUninitialized(object);
+  Handle<HeapObject> object =
+      Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
+  Unique<HeapObject> unique_constant =
+      Unique<HeapObject>::CreateUninitialized(object);
 
   // Manually transcripted code for:
   // function turbo_fan_test(a, b, c) {
@@ -1182,9 +1224,10 @@
   JSOperatorBuilder js_builder(scope.main_zone());
   const Operator* op;
 
-  Handle<Object> object =
-      Handle<Object>(isolate->heap()->undefined_value(), isolate);
-  Unique<Object> unique_constant = Unique<Object>::CreateUninitialized(object);
+  Handle<HeapObject> object =
+      Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
+  Unique<HeapObject> unique_constant =
+      Unique<HeapObject>::CreateUninitialized(object);
 
   // Manually transcripted code for:
   // function turbo_fan_test(a, b, c) {
@@ -1509,12 +1552,12 @@
   Graph graph(scope.main_zone());
   CommonOperatorBuilder common_builder(scope.main_zone());
   JSOperatorBuilder js_builder(scope.main_zone());
-  MachineOperatorBuilder machine_builder;
   const Operator* op;
 
-  Handle<Object> object =
-      Handle<Object>(isolate->heap()->undefined_value(), isolate);
-  Unique<Object> unique_constant = Unique<Object>::CreateUninitialized(object);
+  Handle<HeapObject> object =
+      Handle<HeapObject>(isolate->heap()->undefined_value(), isolate);
+  Unique<HeapObject> unique_constant =
+      Unique<HeapObject>::CreateUninitialized(object);
 
   // Manually transcripted code for:
   // function turbo_fan_test(a, b, c) {
@@ -1544,7 +1587,7 @@
   Node* n20 = graph.NewNode(op, nil, nil, nil, nil, nil);
   USE(n20);
   n20->ReplaceInput(0, n9);
-  op = machine_builder.Int32Add();
+  op = &kIntAdd;
   Node* n19 = graph.NewNode(op, nil, nil);
   USE(n19);
   op = common_builder.Phi(kMachAnyTagged, 2);
@@ -1668,7 +1711,6 @@
   HandleAndZoneScope scope;
   Graph graph(scope.main_zone());
   CommonOperatorBuilder common(scope.main_zone());
-  MachineOperatorBuilder machine;
 
   Node* start = graph.NewNode(common.Start(2));
   graph.SetStart(start);
@@ -1677,7 +1719,7 @@
   Node* p1 = graph.NewNode(common.Parameter(1), start);
   Node* d1 = CreateDiamond(&graph, &common, p0);
   Node* d2 = CreateDiamond(&graph, &common, p1);
-  Node* add = graph.NewNode(machine.Int32Add(), d1, d2);
+  Node* add = graph.NewNode(&kIntAdd, d1, d2);
   Node* ret = graph.NewNode(common.Return(), add, start, start);
   Node* end = graph.NewNode(common.End(), ret, start);
 
@@ -1691,7 +1733,6 @@
   HandleAndZoneScope scope;
   Graph graph(scope.main_zone());
   CommonOperatorBuilder common(scope.main_zone());
-  MachineOperatorBuilder machine;
 
   Node* start = graph.NewNode(common.Start(2));
   graph.SetStart(start);
@@ -1700,7 +1741,7 @@
   Node* p1 = graph.NewNode(common.Parameter(1), start);
   Node* d1 = CreateDiamond(&graph, &common, p0);
   Node* d2 = CreateDiamond(&graph, &common, p1);
-  Node* add = graph.NewNode(machine.Int32Add(), d1, d2);
+  Node* add = graph.NewNode(&kIntAdd, d1, d2);
   Node* d3 = CreateDiamond(&graph, &common, add);
   Node* ret = graph.NewNode(common.Return(), d3, start, start);
   Node* end = graph.NewNode(common.End(), ret, start);
@@ -1710,4 +1751,374 @@
   ComputeAndVerifySchedule(33, &graph);
 }
 
+
+TEST(NestedFloatingDiamonds) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+  SimplifiedOperatorBuilder simplified(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(2));
+  graph.SetStart(start);
+
+  Node* p0 = graph.NewNode(common.Parameter(0), start);
+
+  Node* fv = graph.NewNode(common.Int32Constant(7));
+  Node* br = graph.NewNode(common.Branch(), p0, graph.start());
+  Node* t = graph.NewNode(common.IfTrue(), br);
+  Node* f = graph.NewNode(common.IfFalse(), br);
+
+  Node* map = graph.NewNode(
+      simplified.LoadElement(AccessBuilder::ForFixedArrayElement()), p0, p0, p0,
+      start, f);
+  Node* br1 = graph.NewNode(common.Branch(), map, graph.start());
+  Node* t1 = graph.NewNode(common.IfTrue(), br1);
+  Node* f1 = graph.NewNode(common.IfFalse(), br1);
+  Node* m1 = graph.NewNode(common.Merge(2), t1, f1);
+  Node* ttrue = graph.NewNode(common.Int32Constant(1));
+  Node* ffalse = graph.NewNode(common.Int32Constant(0));
+  Node* phi1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), ttrue, ffalse, m1);
+
+
+  Node* m = graph.NewNode(common.Merge(2), t, f);
+  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 2), fv, phi1, m);
+  Node* ephi1 = graph.NewNode(common.EffectPhi(2), start, map, m);
+
+  Node* ret = graph.NewNode(common.Return(), phi, ephi1, start);
+  Node* end = graph.NewNode(common.End(), ret, start);
+
+  graph.SetEnd(end);
+
+  ComputeAndVerifySchedule(23, &graph);
+}
+
+
+TEST(NestedFloatingDiamondWithChain) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(2));
+  graph.SetStart(start);
+
+  Node* p0 = graph.NewNode(common.Parameter(0), start);
+  Node* p1 = graph.NewNode(common.Parameter(1), start);
+  Node* c = graph.NewNode(common.Int32Constant(7));
+
+  Node* brA1 = graph.NewNode(common.Branch(), p0, graph.start());
+  Node* tA1 = graph.NewNode(common.IfTrue(), brA1);
+  Node* fA1 = graph.NewNode(common.IfFalse(), brA1);
+  Node* mA1 = graph.NewNode(common.Merge(2), tA1, fA1);
+  Node* phiA1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p1, mA1);
+
+  Node* brB1 = graph.NewNode(common.Branch(), p1, graph.start());
+  Node* tB1 = graph.NewNode(common.IfTrue(), brB1);
+  Node* fB1 = graph.NewNode(common.IfFalse(), brB1);
+  Node* mB1 = graph.NewNode(common.Merge(2), tB1, fB1);
+  Node* phiB1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p1, mB1);
+
+  Node* brA2 = graph.NewNode(common.Branch(), phiB1, mA1);
+  Node* tA2 = graph.NewNode(common.IfTrue(), brA2);
+  Node* fA2 = graph.NewNode(common.IfFalse(), brA2);
+  Node* mA2 = graph.NewNode(common.Merge(2), tA2, fA2);
+  Node* phiA2 = graph.NewNode(common.Phi(kMachAnyTagged, 2), phiB1, c, mA2);
+
+  Node* brB2 = graph.NewNode(common.Branch(), phiA1, mB1);
+  Node* tB2 = graph.NewNode(common.IfTrue(), brB2);
+  Node* fB2 = graph.NewNode(common.IfFalse(), brB2);
+  Node* mB2 = graph.NewNode(common.Merge(2), tB2, fB2);
+  Node* phiB2 = graph.NewNode(common.Phi(kMachAnyTagged, 2), phiA1, c, mB2);
+
+  Node* add = graph.NewNode(&kIntAdd, phiA2, phiB2);
+  Node* ret = graph.NewNode(common.Return(), add, start, start);
+  Node* end = graph.NewNode(common.End(), ret, start);
+
+  graph.SetEnd(end);
+
+  ComputeAndVerifySchedule(35, &graph);
+}
+
+
+TEST(NestedFloatingDiamondWithLoop) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(2));
+  graph.SetStart(start);
+
+  Node* p0 = graph.NewNode(common.Parameter(0), start);
+
+  Node* fv = graph.NewNode(common.Int32Constant(7));
+  Node* br = graph.NewNode(common.Branch(), p0, graph.start());
+  Node* t = graph.NewNode(common.IfTrue(), br);
+  Node* f = graph.NewNode(common.IfFalse(), br);
+
+  Node* loop = graph.NewNode(common.Loop(2), f, start);
+  Node* ind = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop);
+
+  Node* add = graph.NewNode(&kIntAdd, ind, fv);
+  Node* br1 = graph.NewNode(common.Branch(), add, loop);
+  Node* t1 = graph.NewNode(common.IfTrue(), br1);
+  Node* f1 = graph.NewNode(common.IfFalse(), br1);
+
+  loop->ReplaceInput(1, t1);  // close loop.
+  ind->ReplaceInput(1, ind);  // close induction variable.
+
+  Node* m = graph.NewNode(common.Merge(2), t, f1);
+  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 2), fv, ind, m);
+
+  Node* ret = graph.NewNode(common.Return(), phi, start, start);
+  Node* end = graph.NewNode(common.End(), ret, start);
+
+  graph.SetEnd(end);
+
+  ComputeAndVerifySchedule(20, &graph);
+}
+
+
+TEST(LoopedFloatingDiamond1) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(2));
+  graph.SetStart(start);
+
+  Node* p0 = graph.NewNode(common.Parameter(0), start);
+
+  Node* c = graph.NewNode(common.Int32Constant(7));
+  Node* loop = graph.NewNode(common.Loop(2), start, start);
+  Node* ind = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop);
+  Node* add = graph.NewNode(&kIntAdd, ind, c);
+
+  Node* br = graph.NewNode(common.Branch(), add, loop);
+  Node* t = graph.NewNode(common.IfTrue(), br);
+  Node* f = graph.NewNode(common.IfFalse(), br);
+
+  Node* br1 = graph.NewNode(common.Branch(), p0, graph.start());
+  Node* t1 = graph.NewNode(common.IfTrue(), br1);
+  Node* f1 = graph.NewNode(common.IfFalse(), br1);
+  Node* m1 = graph.NewNode(common.Merge(2), t1, f1);
+  Node* phi1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), add, p0, m1);
+
+  loop->ReplaceInput(1, t);    // close loop.
+  ind->ReplaceInput(1, phi1);  // close induction variable.
+
+  Node* ret = graph.NewNode(common.Return(), ind, start, f);
+  Node* end = graph.NewNode(common.End(), ret, f);
+
+  graph.SetEnd(end);
+
+  ComputeAndVerifySchedule(20, &graph);
+}
+
+
+TEST(LoopedFloatingDiamond2) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(2));
+  graph.SetStart(start);
+
+  Node* p0 = graph.NewNode(common.Parameter(0), start);
+
+  Node* c = graph.NewNode(common.Int32Constant(7));
+  Node* loop = graph.NewNode(common.Loop(2), start, start);
+  Node* ind = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop);
+
+  Node* br1 = graph.NewNode(common.Branch(), p0, graph.start());
+  Node* t1 = graph.NewNode(common.IfTrue(), br1);
+  Node* f1 = graph.NewNode(common.IfFalse(), br1);
+  Node* m1 = graph.NewNode(common.Merge(2), t1, f1);
+  Node* phi1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), c, ind, m1);
+
+  Node* add = graph.NewNode(&kIntAdd, ind, phi1);
+
+  Node* br = graph.NewNode(common.Branch(), add, loop);
+  Node* t = graph.NewNode(common.IfTrue(), br);
+  Node* f = graph.NewNode(common.IfFalse(), br);
+
+  loop->ReplaceInput(1, t);   // close loop.
+  ind->ReplaceInput(1, add);  // close induction variable.
+
+  Node* ret = graph.NewNode(common.Return(), ind, start, f);
+  Node* end = graph.NewNode(common.End(), ret, f);
+
+  graph.SetEnd(end);
+
+  ComputeAndVerifySchedule(20, &graph);
+}
+
+
+TEST(LoopedFloatingDiamond3) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(2));
+  graph.SetStart(start);
+
+  Node* p0 = graph.NewNode(common.Parameter(0), start);
+
+  Node* c = graph.NewNode(common.Int32Constant(7));
+  Node* loop = graph.NewNode(common.Loop(2), start, start);
+  Node* ind = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop);
+
+  Node* br1 = graph.NewNode(common.Branch(), p0, graph.start());
+  Node* t1 = graph.NewNode(common.IfTrue(), br1);
+  Node* f1 = graph.NewNode(common.IfFalse(), br1);
+
+  Node* loop1 = graph.NewNode(common.Loop(2), t1, start);
+  Node* ind1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), p0, p0, loop);
+
+  Node* add1 = graph.NewNode(&kIntAdd, ind1, c);
+  Node* br2 = graph.NewNode(common.Branch(), add1, loop1);
+  Node* t2 = graph.NewNode(common.IfTrue(), br2);
+  Node* f2 = graph.NewNode(common.IfFalse(), br2);
+
+  loop1->ReplaceInput(1, t2);   // close inner loop.
+  ind1->ReplaceInput(1, ind1);  // close inner induction variable.
+
+  Node* m1 = graph.NewNode(common.Merge(2), f1, f2);
+  Node* phi1 = graph.NewNode(common.Phi(kMachAnyTagged, 2), c, ind1, m1);
+
+  Node* add = graph.NewNode(&kIntAdd, ind, phi1);
+
+  Node* br = graph.NewNode(common.Branch(), add, loop);
+  Node* t = graph.NewNode(common.IfTrue(), br);
+  Node* f = graph.NewNode(common.IfFalse(), br);
+
+  loop->ReplaceInput(1, t);   // close loop.
+  ind->ReplaceInput(1, add);  // close induction variable.
+
+  Node* ret = graph.NewNode(common.Return(), ind, start, f);
+  Node* end = graph.NewNode(common.End(), ret, f);
+
+  graph.SetEnd(end);
+
+  ComputeAndVerifySchedule(28, &graph);
+}
+
+
+TEST(PhisPushedDownToDifferentBranches) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(2));
+  graph.SetStart(start);
+
+  Node* p0 = graph.NewNode(common.Parameter(0), start);
+  Node* p1 = graph.NewNode(common.Parameter(1), start);
+
+  Node* v1 = graph.NewNode(common.Int32Constant(1));
+  Node* v2 = graph.NewNode(common.Int32Constant(2));
+  Node* v3 = graph.NewNode(common.Int32Constant(3));
+  Node* v4 = graph.NewNode(common.Int32Constant(4));
+  Node* br = graph.NewNode(common.Branch(), p0, graph.start());
+  Node* t = graph.NewNode(common.IfTrue(), br);
+  Node* f = graph.NewNode(common.IfFalse(), br);
+  Node* m = graph.NewNode(common.Merge(2), t, f);
+  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 2), v1, v2, m);
+  Node* phi2 = graph.NewNode(common.Phi(kMachAnyTagged, 2), v3, v4, m);
+
+  Node* br2 = graph.NewNode(common.Branch(), p1, graph.start());
+  Node* t2 = graph.NewNode(common.IfTrue(), br2);
+  Node* f2 = graph.NewNode(common.IfFalse(), br2);
+  Node* m2 = graph.NewNode(common.Merge(2), t2, f2);
+  Node* phi3 = graph.NewNode(common.Phi(kMachAnyTagged, 2), phi, phi2, m2);
+
+  Node* ret = graph.NewNode(common.Return(), phi3, start, start);
+  Node* end = graph.NewNode(common.End(), ret, start);
+
+  graph.SetEnd(end);
+
+  ComputeAndVerifySchedule(24, &graph);
+}
+
+
+TEST(BranchHintTrue) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(1));
+  graph.SetStart(start);
+
+  Node* p0 = graph.NewNode(common.Parameter(0), start);
+  Node* tv = graph.NewNode(common.Int32Constant(6));
+  Node* fv = graph.NewNode(common.Int32Constant(7));
+  Node* br = graph.NewNode(common.Branch(BranchHint::kTrue), p0, start);
+  Node* t = graph.NewNode(common.IfTrue(), br);
+  Node* f = graph.NewNode(common.IfFalse(), br);
+  Node* m = graph.NewNode(common.Merge(2), t, f);
+  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 2), tv, fv, m);
+  Node* ret = graph.NewNode(common.Return(), phi, start, start);
+  Node* end = graph.NewNode(common.End(), ret, start);
+
+  graph.SetEnd(end);
+
+  Schedule* schedule = ComputeAndVerifySchedule(13, &graph);
+  // Make sure the false block is marked as deferred.
+  CHECK(!schedule->block(t)->deferred());
+  CHECK(schedule->block(f)->deferred());
+}
+
+
+TEST(BranchHintFalse) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(1));
+  graph.SetStart(start);
+
+  Node* p0 = graph.NewNode(common.Parameter(0), start);
+  Node* tv = graph.NewNode(common.Int32Constant(6));
+  Node* fv = graph.NewNode(common.Int32Constant(7));
+  Node* br = graph.NewNode(common.Branch(BranchHint::kFalse), p0, start);
+  Node* t = graph.NewNode(common.IfTrue(), br);
+  Node* f = graph.NewNode(common.IfFalse(), br);
+  Node* m = graph.NewNode(common.Merge(2), t, f);
+  Node* phi = graph.NewNode(common.Phi(kMachAnyTagged, 2), tv, fv, m);
+  Node* ret = graph.NewNode(common.Return(), phi, start, start);
+  Node* end = graph.NewNode(common.End(), ret, start);
+
+  graph.SetEnd(end);
+
+  Schedule* schedule = ComputeAndVerifySchedule(13, &graph);
+  // Make sure the true block is marked as deferred.
+  CHECK(schedule->block(t)->deferred());
+  CHECK(!schedule->block(f)->deferred());
+}
+
+
+TEST(ScheduleTerminate) {
+  HandleAndZoneScope scope;
+  Graph graph(scope.main_zone());
+  CommonOperatorBuilder common(scope.main_zone());
+
+  Node* start = graph.NewNode(common.Start(1));
+  graph.SetStart(start);
+
+  Node* loop = graph.NewNode(common.Loop(2), start, start);
+  loop->ReplaceInput(1, loop);  // self loop, NTL.
+
+  Node* effect = graph.NewNode(common.EffectPhi(1), start, loop);
+  effect->ReplaceInput(0, effect);
+
+  Node* terminate = graph.NewNode(common.Terminate(1), effect, loop);
+  Node* end = graph.NewNode(common.End(), terminate);
+
+  graph.SetEnd(end);
+
+  Schedule* schedule = ComputeAndVerifySchedule(6, &graph);
+  BasicBlock* block = schedule->block(loop);
+  CHECK_NE(NULL, loop);
+  CHECK_EQ(block, schedule->block(effect));
+  CHECK_GE(block->rpo_number(), 0);
+}
+
 #endif
diff --git a/test/cctest/compiler/test-simplified-lowering.cc b/test/cctest/compiler/test-simplified-lowering.cc
index 96fb965..147aa32 100644
--- a/test/cctest/compiler/test-simplified-lowering.cc
+++ b/test/cctest/compiler/test-simplified-lowering.cc
@@ -5,8 +5,9 @@
 #include <limits>
 
 #include "src/compiler/access-builder.h"
+#include "src/compiler/change-lowering.h"
 #include "src/compiler/control-builders.h"
-#include "src/compiler/generic-node-inl.h"
+#include "src/compiler/graph-reducer.h"
 #include "src/compiler/graph-visualizer.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/compiler/pipeline.h"
@@ -35,11 +36,10 @@
                            MachineType p3 = kMachNone,
                            MachineType p4 = kMachNone)
       : GraphBuilderTester<ReturnType>(p0, p1, p2, p3, p4),
-        typer(this->zone()),
+        typer(this->graph(), MaybeHandle<Context>()),
         javascript(this->zone()),
-        jsgraph(this->graph(), this->common(), &javascript, &typer,
-                this->machine()),
-        lowering(&jsgraph) {}
+        jsgraph(this->graph(), this->common(), &javascript, this->machine()),
+        lowering(&jsgraph, this->zone()) {}
 
   Typer typer;
   JSOperatorBuilder javascript;
@@ -48,16 +48,40 @@
 
   void LowerAllNodes() {
     this->End();
+    typer.Run();
     lowering.LowerAllNodes();
   }
 
+  void LowerAllNodesAndLowerChanges() {
+    this->End();
+    typer.Run();
+    lowering.LowerAllNodes();
+
+    Zone* zone = this->zone();
+    CompilationInfo info(zone->isolate(), zone);
+    Linkage linkage(
+        zone, Linkage::GetSimplifiedCDescriptor(zone, this->machine_sig_));
+    ChangeLowering lowering(&jsgraph, &linkage);
+    GraphReducer reducer(this->graph(), this->zone());
+    reducer.AddReducer(&lowering);
+    reducer.ReduceGraph();
+    Verifier::Run(this->graph());
+  }
+
+  void CheckNumberCall(double expected, double input) {
+    // TODO(titzer): make calls to NewNumber work in cctests.
+    if (expected <= Smi::kMinValue) return;
+    if (expected >= Smi::kMaxValue) return;
+    Handle<Object> num = factory()->NewNumber(input);
+    Object* result = this->Call(*num);
+    CHECK(factory()->NewNumber(expected)->SameValue(result));
+  }
+
   Factory* factory() { return this->isolate()->factory(); }
   Heap* heap() { return this->isolate()->heap(); }
 };
 
 
-#ifndef V8_TARGET_ARCH_ARM64
-// TODO(titzer): these result in a stub call that doesn't work on ARM64.
 // TODO(titzer): factor these tests out to test-run-simplifiedops.cc.
 // TODO(titzer): test tagged representation for input to NumberToInt32.
 TEST(RunNumberToInt32_float64) {
@@ -68,6 +92,7 @@
   FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(),
                       kMachFloat64};
   Node* loaded = t.LoadField(load, t.PointerConstant(&input));
+  NodeProperties::SetBounds(loaded, Bounds(Type::Number()));
   Node* convert = t.NumberToInt32(loaded);
   FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Signed32(),
                        kMachInt32};
@@ -96,6 +121,7 @@
   FieldAccess load = {kUntaggedBase, 0, Handle<Name>(), Type::Number(),
                       kMachFloat64};
   Node* loaded = t.LoadField(load, t.PointerConstant(&input));
+  NodeProperties::SetBounds(loaded, Bounds(Type::Number()));
   Node* convert = t.NumberToUint32(loaded);
   FieldAccess store = {kUntaggedBase, 0, Handle<Name>(), Type::Unsigned32(),
                        kMachUint32};
@@ -113,7 +139,6 @@
     }
   }
 }
-#endif
 
 
 // Create a simple JSObject with a unique map.
@@ -207,10 +232,8 @@
 TEST(RunLoadStoreFixedArrayIndex) {
   SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
   ElementAccess access = AccessBuilder::ForFixedArrayElement();
-  Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0),
-                             t.Int32Constant(2));
-  t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), t.Int32Constant(2),
-                 load);
+  Node* load = t.LoadElement(access, t.Parameter(0), t.Int32Constant(0));
+  t.StoreElement(access, t.Parameter(0), t.Int32Constant(1), load);
   t.Return(load);
 
   t.LowerAllNodes();
@@ -235,14 +258,13 @@
   const int index = 12;
   const int array_length = 2 * index;
   ElementAccess buffer_access =
-      AccessBuilder::ForBackingStoreElement(kMachInt8);
+      AccessBuilder::ForTypedArrayElement(v8::kExternalInt8Array, true);
   Node* backing_store = t.LoadField(
       AccessBuilder::ForJSArrayBufferBackingStore(), t.Parameter(0));
   Node* load =
-      t.LoadElement(buffer_access, backing_store, t.Int32Constant(index),
-                    t.Int32Constant(array_length));
+      t.LoadElement(buffer_access, backing_store, t.Int32Constant(index));
   t.StoreElement(buffer_access, backing_store, t.Int32Constant(index + 1),
-                 t.Int32Constant(array_length), load);
+                 load);
   t.Return(t.jsgraph.TrueConstant());
 
   t.LowerAllNodes();
@@ -329,9 +351,8 @@
                               kMachAnyTagged};
 
       SimplifiedLoweringTester<Object*> t;
-      Node* load = t.LoadElement(
-          access, t.PointerConstant(smis), t.Int32Constant(static_cast<int>(j)),
-          t.Int32Constant(static_cast<int>(arraysize(smis))));
+      Node* load = t.LoadElement(access, t.PointerConstant(smis),
+                                 t.Int32Constant(static_cast<int>(j)));
       t.Return(load);
       t.LowerAllNodes();
 
@@ -360,8 +381,7 @@
       SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
       Node* p0 = t.Parameter(0);
       t.StoreElement(access, t.PointerConstant(smis),
-                     t.Int32Constant(static_cast<int>(j)),
-                     t.Int32Constant(static_cast<int>(arraysize(smis))), p0);
+                     t.Int32Constant(static_cast<int>(j)), p0);
       t.Return(p0);
       t.LowerAllNodes();
 
@@ -427,10 +447,8 @@
 
     SimplifiedLoweringTester<Object*> t;
     Node* ptr = GetBaseNode(&t);
-    Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index),
-                               t.Int32Constant(static_cast<int>(num_elements)));
-    t.StoreElement(access, ptr, t.Int32Constant(to_index),
-                   t.Int32Constant(static_cast<int>(num_elements)), load);
+    Node* load = t.LoadElement(access, ptr, t.Int32Constant(from_index));
+    t.StoreElement(access, ptr, t.Int32Constant(to_index), load);
     t.Return(t.jsgraph.TrueConstant());
     t.LowerAllNodes();
     t.GenerateCode();
@@ -648,9 +666,9 @@
   explicit TestingGraph(Type* p0_type, Type* p1_type = Type::None(),
                         Type* p2_type = Type::None())
       : GraphAndBuilders(main_zone()),
-        typer(main_zone()),
+        typer(graph(), MaybeHandle<Context>()),
         javascript(main_zone()),
-        jsgraph(graph(), common(), &javascript, &typer, machine()) {
+        jsgraph(graph(), common(), &javascript, machine()) {
     start = graph()->NewNode(common()->Start(2));
     graph()->SetStart(start);
     ret =
@@ -660,6 +678,7 @@
     p0 = graph()->NewNode(common()->Parameter(0), start);
     p1 = graph()->NewNode(common()->Parameter(1), start);
     p2 = graph()->NewNode(common()->Parameter(2), start);
+    typer.Run();
     NodeProperties::SetBounds(p0, Bounds(p0_type));
     NodeProperties::SetBounds(p1, Bounds(p1_type));
     NodeProperties::SetBounds(p2, Bounds(p2_type));
@@ -679,10 +698,7 @@
     CHECK_EQ(expected, node->opcode());
   }
 
-  void Lower() {
-    SimplifiedLowering lowering(&jsgraph);
-    lowering.LowerAllNodes();
-  }
+  void Lower() { SimplifiedLowering(&jsgraph, jsgraph.zone()).LowerAllNodes(); }
 
   // Inserts the node as the return value of the graph.
   Node* Return(Node* node) {
@@ -718,6 +734,17 @@
     }
   }
 
+  Node* ExampleWithTypeAndRep(Type* type, MachineType mach_type) {
+    FieldAccess access = {kUntaggedBase, 0, Handle<Name>::null(), type,
+                          mach_type};
+    // TODO(titzer): using loads here just to force the representation is ugly.
+    Node* node = graph()->NewNode(simplified()->LoadField(access),
+                                  jsgraph.IntPtrConstant(0), graph()->start(),
+                                  graph()->start());
+    NodeProperties::SetBounds(node, Bounds(type));
+    return node;
+  }
+
   Node* Use(Node* node, MachineType type) {
     if (type & kTypeInt32) {
       return graph()->NewNode(machine()->Int32LessThan(), node,
@@ -731,6 +758,9 @@
     } else if (type & kRepWord64) {
       return graph()->NewNode(machine()->Int64LessThan(), node,
                               Int64Constant(1));
+    } else if (type & kRepWord32) {
+      return graph()->NewNode(machine()->Word32Equal(), node,
+                              jsgraph.Int32Constant(1));
     } else {
       return graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), node,
                               jsgraph.TrueConstant());
@@ -757,6 +787,50 @@
 };
 
 
+TEST(LowerAnyToBoolean_bit_bit) {
+  // AnyToBoolean(x: kRepBit) used as kRepBit
+  HandleAndZoneScope scope;
+  Factory* f = scope.main_zone()->isolate()->factory();
+  Handle<Object> zero = f->NewNumber(0);
+  Handle<Object> one = f->NewNumber(1);
+  Type* singleton_zero = Type::Constant(zero, scope.main_zone());
+  Type* singleton_one = Type::Constant(one, scope.main_zone());
+  Type* zero_one_range = Type::Range(zero, one, scope.main_zone());
+  static Type* kTypes[] = {
+      singleton_zero, singleton_one, zero_one_range, Type::Boolean(),
+      Type::Union(Type::Boolean(), singleton_zero, scope.main_zone()),
+      Type::Union(Type::Boolean(), singleton_one, scope.main_zone()),
+      Type::Union(Type::Boolean(), zero_one_range, scope.main_zone())};
+  for (Type* type : kTypes) {
+    TestingGraph t(type);
+    Node* x = t.ExampleWithTypeAndRep(type, kRepBit);
+    Node* cnv = t.graph()->NewNode(t.simplified()->AnyToBoolean(), x);
+    Node* use = t.Branch(cnv);
+    t.Lower();
+    CHECK_EQ(x, use->InputAt(0));
+  }
+}
+
+
+#if V8_TURBOFAN_TARGET
+
+TEST(LowerAnyToBoolean_tagged_tagged) {
+  // AnyToBoolean(x: kRepTagged) used as kRepTagged
+  TestingGraph t(Type::Any());
+  Node* x = t.p0;
+  Node* cnv = t.graph()->NewNode(t.simplified()->AnyToBoolean(), x);
+  Node* use = t.Use(cnv, kRepTagged);
+  t.Return(use);
+  t.Lower();
+  CHECK_EQ(IrOpcode::kCall, cnv->opcode());
+  CHECK_EQ(IrOpcode::kHeapConstant, cnv->InputAt(0)->opcode());
+  CHECK_EQ(x, cnv->InputAt(1));
+  CHECK_EQ(t.jsgraph.NoContextConstant(), cnv->InputAt(2));
+}
+
+#endif
+
+
 TEST(LowerBooleanNot_bit_bit) {
   // BooleanNot(x: kRepBit) used as kRepBit
   TestingGraph t(Type::Boolean());
@@ -765,7 +839,7 @@
   Node* use = t.Branch(inv);
   t.Lower();
   Node* cmp = use->InputAt(0);
-  CHECK_EQ(t.machine()->WordEqual()->opcode(), cmp->opcode());
+  CHECK_EQ(t.machine()->Word32Equal()->opcode(), cmp->opcode());
   CHECK(b == cmp->InputAt(0) || b == cmp->InputAt(1));
   Node* f = t.jsgraph.Int32Constant(0);
   CHECK(f == cmp->InputAt(0) || f == cmp->InputAt(1));
@@ -782,7 +856,7 @@
   t.Lower();
   CHECK_EQ(IrOpcode::kChangeBitToBool, use->InputAt(0)->opcode());
   Node* cmp = use->InputAt(0)->InputAt(0);
-  CHECK_EQ(t.machine()->WordEqual()->opcode(), cmp->opcode());
+  CHECK_EQ(t.machine()->Word32Equal()->opcode(), cmp->opcode());
   CHECK(b == cmp->InputAt(0) || b == cmp->InputAt(1));
   Node* f = t.jsgraph.Int32Constant(0);
   CHECK(f == cmp->InputAt(0) || f == cmp->InputAt(1));
@@ -921,24 +995,50 @@
 
 
 TEST(LowerNumberAddSub_to_int32) {
-  TestingGraph t(Type::Signed32(), Type::Signed32());
-  t.CheckLoweringTruncatedBinop(IrOpcode::kInt32Add,
-                                t.simplified()->NumberAdd(),
-                                t.simplified()->NumberToInt32());
-  t.CheckLoweringTruncatedBinop(IrOpcode::kInt32Sub,
-                                t.simplified()->NumberSubtract(),
-                                t.simplified()->NumberToInt32());
+  HandleAndZoneScope scope;
+  Factory* f = scope.main_zone()->isolate()->factory();
+  Type* small_range =
+      Type::Range(f->NewNumber(1), f->NewNumber(10), scope.main_zone());
+  Type* large_range =
+      Type::Range(f->NewNumber(-1e+13), f->NewNumber(1e+14), scope.main_zone());
+  static Type* types[] = {Type::Signed32(), Type::Integral32(), small_range,
+                          large_range};
+
+  for (size_t i = 0; i < arraysize(types); i++) {
+    for (size_t j = 0; j < arraysize(types); j++) {
+      TestingGraph t(types[i], types[j]);
+      t.CheckLoweringTruncatedBinop(IrOpcode::kInt32Add,
+                                    t.simplified()->NumberAdd(),
+                                    t.simplified()->NumberToInt32());
+      t.CheckLoweringTruncatedBinop(IrOpcode::kInt32Sub,
+                                    t.simplified()->NumberSubtract(),
+                                    t.simplified()->NumberToInt32());
+    }
+  }
 }
 
 
 TEST(LowerNumberAddSub_to_uint32) {
-  TestingGraph t(Type::Unsigned32(), Type::Unsigned32());
-  t.CheckLoweringTruncatedBinop(IrOpcode::kInt32Add,
-                                t.simplified()->NumberAdd(),
-                                t.simplified()->NumberToUint32());
-  t.CheckLoweringTruncatedBinop(IrOpcode::kInt32Sub,
-                                t.simplified()->NumberSubtract(),
-                                t.simplified()->NumberToUint32());
+  HandleAndZoneScope scope;
+  Factory* f = scope.main_zone()->isolate()->factory();
+  Type* small_range =
+      Type::Range(f->NewNumber(1), f->NewNumber(10), scope.main_zone());
+  Type* large_range =
+      Type::Range(f->NewNumber(-1e+13), f->NewNumber(1e+14), scope.main_zone());
+  static Type* types[] = {Type::Signed32(), Type::Integral32(), small_range,
+                          large_range};
+
+  for (size_t i = 0; i < arraysize(types); i++) {
+    for (size_t j = 0; j < arraysize(types); j++) {
+      TestingGraph t(types[i], types[j]);
+      t.CheckLoweringTruncatedBinop(IrOpcode::kInt32Add,
+                                    t.simplified()->NumberAdd(),
+                                    t.simplified()->NumberToUint32());
+      t.CheckLoweringTruncatedBinop(IrOpcode::kInt32Sub,
+                                    t.simplified()->NumberSubtract(),
+                                    t.simplified()->NumberToUint32());
+    }
+  }
 }
 
 
@@ -958,8 +1058,10 @@
     TestingGraph t(test_types[i], test_types[i]);
 
     t.CheckLoweringBinop(IrOpcode::kFloat64Div, t.simplified()->NumberDivide());
-    t.CheckLoweringBinop(IrOpcode::kFloat64Mod,
-                         t.simplified()->NumberModulus());
+    if (!test_types[i]->Is(Type::Unsigned32())) {
+      t.CheckLoweringBinop(IrOpcode::kFloat64Mod,
+                           t.simplified()->NumberModulus());
+    }
   }
 }
 
@@ -1006,7 +1108,7 @@
 TEST(LowerNumberToInt32_to_TruncateFloat64ToInt32) {
   // NumberToInt32(x: kRepFloat64) used as kMachInt32
   TestingGraph t(Type::Number());
-  Node* p0 = t.ExampleWithOutput(kMachFloat64);
+  Node* p0 = t.ExampleWithTypeAndRep(Type::Number(), kMachFloat64);
   Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), p0);
   Node* use = t.Use(trunc, kMachInt32);
   t.Return(use);
@@ -1030,17 +1132,6 @@
 }
 
 
-TEST(LowerNumberToInt32_to_ChangeFloat64ToTagged) {
-  // TODO(titzer): NumberToInt32(x: kRepFloat64 | kTypeInt32) used as kRepTagged
-}
-
-
-TEST(LowerNumberToInt32_to_ChangeFloat64ToInt32) {
-  // TODO(titzer): NumberToInt32(x: kRepFloat64 | kTypeInt32) used as kRepWord32
-  // | kTypeInt32
-}
-
-
 TEST(LowerNumberToUint32_to_nop) {
   // NumberToUint32(x: kRepTagged | kTypeUint32) used as kRepTagged
   TestingGraph t(Type::Unsigned32());
@@ -1078,6 +1169,8 @@
   // NumberToUint32(x: kRepFloat64) used as kMachUint32
   TestingGraph t(Type::Number());
   Node* p0 = t.ExampleWithOutput(kMachFloat64);
+  // TODO(titzer): run the typer here, or attach machine type to param.
+  NodeProperties::SetBounds(p0, Bounds(Type::Number()));
   Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), p0);
   Node* use = t.Use(trunc, kMachUint32);
   t.Return(use);
@@ -1101,20 +1194,67 @@
 }
 
 
-TEST(LowerNumberToUint32_to_ChangeFloat64ToTagged) {
-  // TODO(titzer): NumberToUint32(x: kRepFloat64 | kTypeUint32) used as
-  // kRepTagged
+TEST(LowerNumberToUint32_to_TruncateFloat64ToInt32_uint32) {
+  // NumberToUint32(x: kRepFloat64) used as kRepWord32
+  TestingGraph t(Type::Unsigned32());
+  Node* input = t.ExampleWithTypeAndRep(Type::Number(), kMachFloat64);
+  Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), input);
+  Node* use = t.Use(trunc, kRepWord32);
+  t.Return(use);
+  t.Lower();
+  CheckChangeOf(IrOpcode::kTruncateFloat64ToInt32, input, use->InputAt(0));
 }
 
 
-TEST(LowerNumberToUint32_to_ChangeFloat64ToUint32) {
-  // TODO(titzer): NumberToUint32(x: kRepFloat64 | kTypeUint32) used as
-  // kRepWord32
+TEST(LowerNumberToUI32_of_Float64_used_as_word32) {
+  // NumberTo(Int,Uint)32(x: kRepFloat64 | kType(Int,Uint)32) used as
+  // kType(Int,Uint)32 | kRepWord32
+  Type* types[] = {Type::Signed32(), Type::Unsigned32()};
+  MachineType mach[] = {kTypeInt32, kTypeUint32, kMachNone};
+
+  for (int i = 0; i < 2; i++) {
+    for (int u = 0; u < 3; u++) {
+      TestingGraph t(types[i]);
+      Node* input = t.ExampleWithTypeAndRep(
+          types[i], static_cast<MachineType>(kRepFloat64 | mach[i]));
+      const Operator* op = i == 0 ? t.simplified()->NumberToInt32()
+                                  : t.simplified()->NumberToUint32();
+      Node* trunc = t.graph()->NewNode(op, input);
+      Node* use = t.Use(trunc, static_cast<MachineType>(kRepWord32 | mach[u]));
+      t.Return(use);
+      t.Lower();
+      IrOpcode::Value opcode = i == 0 ? IrOpcode::kChangeFloat64ToInt32
+                                      : IrOpcode::kChangeFloat64ToUint32;
+      CheckChangeOf(opcode, input, use->InputAt(0));
+    }
+  }
 }
 
 
-TEST(LowerNumberToUint32_to_TruncateFloat64ToUint32) {
-  // TODO(titzer): NumberToUint32(x: kRepFloat64) used as kRepWord32
+TEST(LowerNumberToUI32_of_Float64_used_as_tagged) {
+  // NumberTo(Int,Uint)32(x: kRepFloat64 | kType(Int,Uint)32) used as
+  // kType(Int,Uint)32 | kRepTagged
+  Type* types[] = {Type::Signed32(), Type::Unsigned32(), Type::Any()};
+  MachineType mach[] = {kTypeInt32, kTypeUint32, kMachNone};
+
+  for (int i = 0; i < 2; i++) {
+    for (int u = 0; u < 3; u++) {
+      TestingGraph t(types[i]);
+      Node* input = t.ExampleWithTypeAndRep(
+          types[i], static_cast<MachineType>(kRepFloat64 | mach[i]));
+      const Operator* op = i == 0 ? t.simplified()->NumberToInt32()
+                                  : t.simplified()->NumberToUint32();
+      Node* trunc = t.graph()->NewNode(op, input);
+      // TODO(titzer): we use the store here to force the representation.
+      FieldAccess access = {kTaggedBase, 0, Handle<Name>(), types[u],
+                            static_cast<MachineType>(mach[u] | kRepTagged)};
+      Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
+                                       trunc, t.start, t.start);
+      t.Effect(store);
+      t.Lower();
+      CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, input, store->InputAt(2));
+    }
+  }
 }
 
 
@@ -1268,45 +1408,54 @@
 }
 
 
+namespace {
+
 void CheckFieldAccessArithmetic(FieldAccess access, Node* load_or_store) {
-  Int32Matcher index = Int32Matcher(load_or_store->InputAt(1));
-  CHECK(index.Is(access.offset - access.tag()));
+  IntPtrMatcher mindex(load_or_store->InputAt(1));
+  CHECK(mindex.Is(access.offset - access.tag()));
 }
 
 
 Node* CheckElementAccessArithmetic(ElementAccess access, Node* load_or_store) {
-  Int32BinopMatcher index(load_or_store->InputAt(1));
-  CHECK_EQ(IrOpcode::kInt32Add, index.node()->opcode());
-  CHECK(index.right().Is(access.header_size - access.tag()));
+  Node* index = load_or_store->InputAt(1);
+  if (kPointerSize == 8) {
+    CHECK_EQ(IrOpcode::kChangeUint32ToUint64, index->opcode());
+    index = index->InputAt(0);
+  }
 
-  int element_size = ElementSizeOf(access.machine_type);
+  Int32BinopMatcher mindex(index);
+  CHECK_EQ(IrOpcode::kInt32Add, mindex.node()->opcode());
+  CHECK(mindex.right().Is(access.header_size - access.tag()));
 
-  if (element_size != 1) {
-    Int32BinopMatcher mul(index.left().node());
-    CHECK_EQ(IrOpcode::kInt32Mul, mul.node()->opcode());
-    CHECK(mul.right().Is(element_size));
-    return mul.left().node();
+  const int element_size_shift = ElementSizeLog2Of(access.machine_type);
+  if (element_size_shift) {
+    Int32BinopMatcher shl(mindex.left().node());
+    CHECK_EQ(IrOpcode::kWord32Shl, shl.node()->opcode());
+    CHECK(shl.right().Is(element_size_shift));
+    return shl.left().node();
   } else {
-    return index.left().node();
+    return mindex.left().node();
   }
 }
 
 
-static const MachineType machine_reps[] = {
-    kRepBit,    kMachInt8,    kMachInt16,    kMachInt32,
-    kMachInt64, kMachFloat64, kMachAnyTagged};
+const MachineType kMachineReps[] = {kRepBit,       kMachInt8,  kMachInt16,
+                                    kMachInt32,    kMachInt64, kMachFloat64,
+                                    kMachAnyTagged};
+
+}  // namespace
 
 
 TEST(LowerLoadField_to_load) {
   TestingGraph t(Type::Any(), Type::Signed32());
 
-  for (size_t i = 0; i < arraysize(machine_reps); i++) {
+  for (size_t i = 0; i < arraysize(kMachineReps); i++) {
     FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
-                          Handle<Name>::null(), Type::Any(), machine_reps[i]};
+                          Handle<Name>::null(), Type::Any(), kMachineReps[i]};
 
     Node* load =
         t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
-    Node* use = t.Use(load, machine_reps[i]);
+    Node* use = t.Use(load, kMachineReps[i]);
     t.Return(use);
     t.Lower();
     CHECK_EQ(IrOpcode::kLoad, load->opcode());
@@ -1314,7 +1463,7 @@
     CheckFieldAccessArithmetic(access, load);
 
     MachineType rep = OpParameter<MachineType>(load);
-    CHECK_EQ(machine_reps[i], rep);
+    CHECK_EQ(kMachineReps[i], rep);
   }
 }
 
@@ -1322,12 +1471,12 @@
 TEST(LowerStoreField_to_store) {
   TestingGraph t(Type::Any(), Type::Signed32());
 
-  for (size_t i = 0; i < arraysize(machine_reps); i++) {
+  for (size_t i = 0; i < arraysize(kMachineReps); i++) {
     FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
-                          Handle<Name>::null(), Type::Any(), machine_reps[i]};
+                          Handle<Name>::null(), Type::Any(), kMachineReps[i]};
 
 
-    Node* val = t.ExampleWithOutput(machine_reps[i]);
+    Node* val = t.ExampleWithOutput(kMachineReps[i]);
     Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
                                      val, t.start, t.start);
     t.Effect(store);
@@ -1337,10 +1486,10 @@
     CheckFieldAccessArithmetic(access, store);
 
     StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
-    if (machine_reps[i] & kRepTagged) {
+    if (kMachineReps[i] & kRepTagged) {
       CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
     }
-    CHECK_EQ(machine_reps[i], rep.machine_type());
+    CHECK_EQ(kMachineReps[i], rep.machine_type());
   }
 }
 
@@ -1348,14 +1497,13 @@
 TEST(LowerLoadElement_to_load) {
   TestingGraph t(Type::Any(), Type::Signed32());
 
-  for (size_t i = 0; i < arraysize(machine_reps); i++) {
+  for (size_t i = 0; i < arraysize(kMachineReps); i++) {
     ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
-                            Type::Any(), machine_reps[i]};
+                            Type::Any(), kMachineReps[i]};
 
-    Node* load =
-        t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0, t.p1,
-                           t.jsgraph.Int32Constant(1024), t.start);
-    Node* use = t.Use(load, machine_reps[i]);
+    Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
+                                    t.p1, t.start, t.start);
+    Node* use = t.Use(load, kMachineReps[i]);
     t.Return(use);
     t.Lower();
     CHECK_EQ(IrOpcode::kLoad, load->opcode());
@@ -1363,7 +1511,7 @@
     CheckElementAccessArithmetic(access, load);
 
     MachineType rep = OpParameter<MachineType>(load);
-    CHECK_EQ(machine_reps[i], rep);
+    CHECK_EQ(kMachineReps[i], rep);
   }
 }
 
@@ -1371,14 +1519,13 @@
 TEST(LowerStoreElement_to_store) {
   TestingGraph t(Type::Any(), Type::Signed32());
 
-  for (size_t i = 0; i < arraysize(machine_reps); i++) {
+  for (size_t i = 0; i < arraysize(kMachineReps); i++) {
     ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
-                            Type::Any(), machine_reps[i]};
+                            Type::Any(), kMachineReps[i]};
 
-    Node* val = t.ExampleWithOutput(machine_reps[i]);
+    Node* val = t.ExampleWithOutput(kMachineReps[i]);
     Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0,
-                                     t.p1, t.jsgraph.Int32Constant(1024), val,
-                                     t.start, t.start);
+                                     t.p1, val, t.start, t.start);
     t.Effect(store);
     t.Lower();
     CHECK_EQ(IrOpcode::kStore, store->opcode());
@@ -1386,10 +1533,10 @@
     CheckElementAccessArithmetic(access, store);
 
     StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
-    if (machine_reps[i] & kRepTagged) {
+    if (kMachineReps[i] & kRepTagged) {
       CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
     }
-    CHECK_EQ(machine_reps[i], rep.machine_type());
+    CHECK_EQ(kMachineReps[i], rep.machine_type());
   }
 }
 
@@ -1397,12 +1544,12 @@
 TEST(InsertChangeForLoadElementIndex) {
   // LoadElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length) =>
   //   Load(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k))
-  TestingGraph t(Type::Any(), Type::Signed32(), Type::Any());
+  TestingGraph t(Type::Any(), Type::Signed32());
   ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
                           kMachAnyTagged};
 
   Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
-                                  t.p1, t.p2, t.start);
+                                  t.p1, t.start, t.start);
   t.Return(load);
   t.Lower();
   CHECK_EQ(IrOpcode::kLoad, load->opcode());
@@ -1416,12 +1563,12 @@
 TEST(InsertChangeForStoreElementIndex) {
   // StoreElement(obj: Tagged, index: kTypeInt32 | kRepTagged, length, val) =>
   //   Store(obj, Int32Add(Int32Mul(ChangeTaggedToInt32(index), #k), #k), val)
-  TestingGraph t(Type::Any(), Type::Signed32(), Type::Any());
+  TestingGraph t(Type::Any(), Type::Signed32());
   ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
                           kMachAnyTagged};
 
   Node* store =
-      t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1, t.p2,
+      t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, t.p1,
                          t.jsgraph.TrueConstant(), t.start, t.start);
   t.Effect(store);
   t.Lower();
@@ -1440,7 +1587,7 @@
                           kMachFloat64};
 
   Node* load = t.graph()->NewNode(t.simplified()->LoadElement(access), t.p0,
-                                  t.p1, t.p1, t.start);
+                                  t.p1, t.start, t.start);
   t.Return(load);
   t.Lower();
   CHECK_EQ(IrOpcode::kLoad, load->opcode());
@@ -1467,13 +1614,13 @@
 
 TEST(InsertChangeForStoreElement) {
   // TODO(titzer): test all load/store representation change insertions.
-  TestingGraph t(Type::Any(), Type::Signed32(), Type::Any());
+  TestingGraph t(Type::Any(), Type::Signed32());
   ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, Type::Any(),
                           kMachFloat64};
 
-  Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0,
-                                   t.jsgraph.Int32Constant(0), t.p2, t.p1,
-                                   t.start, t.start);
+  Node* store =
+      t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0,
+                         t.jsgraph.Int32Constant(0), t.p1, t.start, t.start);
   t.Effect(store);
   t.Lower();
 
@@ -1504,10 +1651,11 @@
   TestingGraph t(Type::Any(), Type::Signed32());
   static const MachineType kMachineTypes[] = {kMachInt32, kMachUint32,
                                               kMachFloat64};
+  Type* kTypes[] = {Type::Signed32(), Type::Unsigned32(), Type::Number()};
 
   for (size_t i = 0; i < arraysize(kMachineTypes); i++) {
     FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
-                          Handle<Name>::null(), Type::Any(), kMachineTypes[i]};
+                          Handle<Name>::null(), kTypes[i], kMachineTypes[i]};
 
     Node* load0 =
         t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
@@ -1525,36 +1673,405 @@
 }
 
 
-// TODO(titzer): this tests current behavior of assuming an implicit
-// representation change in loading float32s. Fix when float32 is fully
-// supported.
-TEST(ImplicitFloat32ToFloat64InLoads) {
-  TestingGraph t(Type::Any());
+TEST(RunNumberDivide_minus_1_TruncatingToInt32) {
+  SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+  Node* num = t.NumberToInt32(t.Parameter(0));
+  Node* div = t.NumberDivide(num, t.jsgraph.Constant(-1));
+  Node* trunc = t.NumberToInt32(div);
+  t.Return(trunc);
 
-  FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
-                        Handle<Name>::null(), Type::Any(), kMachFloat32};
+  if (Pipeline::SupportedTarget()) {
+    t.LowerAllNodesAndLowerChanges();
+    t.GenerateCode();
 
-  Node* load =
-      t.graph()->NewNode(t.simplified()->LoadField(access), t.p0, t.start);
-  t.Return(load);
-  t.Lower();
-  CHECK_EQ(IrOpcode::kLoad, load->opcode());
-  CHECK_EQ(t.p0, load->InputAt(0));
-  CheckChangeOf(IrOpcode::kChangeFloat64ToTagged, load, t.ret->InputAt(0));
+    FOR_INT32_INPUTS(i) {
+      int32_t x = 0 - *i;
+      t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
+    }
+  }
 }
 
 
-TEST(ImplicitFloat64ToFloat32InStores) {
-  TestingGraph t(Type::Any(), Type::Signed32());
-  FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
-                        Handle<Name>::null(), Type::Any(), kMachFloat32};
+TEST(NumberMultiply_TruncatingToInt32) {
+  int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000};
 
-  Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
-                                   t.p1, t.start, t.start);
-  t.Effect(store);
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    TestingGraph t(Type::Signed32());
+    Node* k = t.jsgraph.Constant(constants[i]);
+    Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
+    Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mul);
+    t.Return(trunc);
+    t.Lower();
+
+    CHECK_EQ(IrOpcode::kInt32Mul, mul->opcode());
+  }
+}
+
+
+TEST(RunNumberMultiply_TruncatingToInt32) {
+  int32_t constants[] = {-100, -10, -1, 0, 1, 100, 1000, 3000999};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    double k = static_cast<double>(constants[i]);
+    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    Node* num = t.NumberToInt32(t.Parameter(0));
+    Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k));
+    Node* trunc = t.NumberToInt32(mul);
+    t.Return(trunc);
+
+    if (Pipeline::SupportedTarget()) {
+      t.LowerAllNodesAndLowerChanges();
+      t.GenerateCode();
+
+      FOR_INT32_INPUTS(i) {
+        int32_t x = DoubleToInt32(static_cast<double>(*i) * k);
+        t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
+      }
+    }
+  }
+}
+
+
+TEST(RunNumberMultiply_TruncatingToUint32) {
+  uint32_t constants[] = {0, 1, 2, 3, 4, 100, 1000, 1024, 2048, 3000999};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    double k = static_cast<double>(constants[i]);
+    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    Node* num = t.NumberToUint32(t.Parameter(0));
+    Node* mul = t.NumberMultiply(num, t.jsgraph.Constant(k));
+    Node* trunc = t.NumberToUint32(mul);
+    t.Return(trunc);
+
+    if (Pipeline::SupportedTarget()) {
+      t.LowerAllNodesAndLowerChanges();
+      t.GenerateCode();
+
+      FOR_UINT32_INPUTS(i) {
+        uint32_t x = DoubleToUint32(static_cast<double>(*i) * k);
+        t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
+      }
+    }
+  }
+}
+
+
+TEST(RunNumberDivide_2_TruncatingToUint32) {
+  SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+  Node* num = t.NumberToUint32(t.Parameter(0));
+  Node* div = t.NumberDivide(num, t.jsgraph.Constant(2));
+  Node* trunc = t.NumberToUint32(div);
+  t.Return(trunc);
+
+  if (Pipeline::SupportedTarget()) {
+    t.LowerAllNodesAndLowerChanges();
+    t.GenerateCode();
+
+    FOR_UINT32_INPUTS(i) {
+      uint32_t x = DoubleToUint32(static_cast<double>(*i / 2.0));
+      t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
+    }
+  }
+}
+
+
+TEST(NumberMultiply_ConstantOutOfRange) {
+  TestingGraph t(Type::Signed32());
+  Node* k = t.jsgraph.Constant(1000000023);
+  Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
+  Node* trunc = t.graph()->NewNode(t.simplified()->NumberToInt32(), mul);
+  t.Return(trunc);
   t.Lower();
 
-  CHECK_EQ(IrOpcode::kStore, store->opcode());
-  CHECK_EQ(t.p0, store->InputAt(0));
-  CheckChangeOf(IrOpcode::kChangeTaggedToFloat64, t.p1, store->InputAt(2));
+  CHECK_EQ(IrOpcode::kFloat64Mul, mul->opcode());
+}
+
+
+TEST(NumberMultiply_NonTruncating) {
+  TestingGraph t(Type::Signed32());
+  Node* k = t.jsgraph.Constant(111);
+  Node* mul = t.graph()->NewNode(t.simplified()->NumberMultiply(), t.p0, k);
+  t.Return(mul);
+  t.Lower();
+
+  CHECK_EQ(IrOpcode::kFloat64Mul, mul->opcode());
+}
+
+
+TEST(NumberDivide_TruncatingToInt32) {
+  int32_t constants[] = {-100, -10, 1, 4, 100, 1000};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    TestingGraph t(Type::Signed32());
+    Node* k = t.jsgraph.Constant(constants[i]);
+    Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
+    Node* use = t.Use(div, kMachInt32);
+    t.Return(use);
+    t.Lower();
+
+    CHECK_EQ(IrOpcode::kInt32Div, use->InputAt(0)->opcode());
+  }
+}
+
+
+TEST(RunNumberDivide_TruncatingToInt32) {
+  int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    int32_t k = constants[i];
+    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    Node* num = t.NumberToInt32(t.Parameter(0));
+    Node* div = t.NumberDivide(num, t.jsgraph.Constant(k));
+    Node* trunc = t.NumberToInt32(div);
+    t.Return(trunc);
+
+    if (Pipeline::SupportedTarget()) {
+      t.LowerAllNodesAndLowerChanges();
+      t.GenerateCode();
+
+      FOR_INT32_INPUTS(i) {
+        if (*i == INT_MAX) continue;  // exclude max int.
+        int32_t x = DoubleToInt32(static_cast<double>(*i) / k);
+        t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
+      }
+    }
+  }
+}
+
+
+TEST(NumberDivide_TruncatingToUint32) {
+  double constants[] = {1, 3, 100, 1000, 100998348};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    TestingGraph t(Type::Unsigned32());
+    Node* k = t.jsgraph.Constant(constants[i]);
+    Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
+    Node* use = t.Use(div, kMachUint32);
+    t.Return(use);
+    t.Lower();
+
+    CHECK_EQ(IrOpcode::kUint32Div, use->InputAt(0)->opcode());
+  }
+}
+
+
+TEST(RunNumberDivide_TruncatingToUint32) {
+  uint32_t constants[] = {100, 10, 1, 1, 2, 4, 1000, 1024, 2048};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    uint32_t k = constants[i];
+    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    Node* num = t.NumberToUint32(t.Parameter(0));
+    Node* div = t.NumberDivide(num, t.jsgraph.Constant(static_cast<double>(k)));
+    Node* trunc = t.NumberToUint32(div);
+    t.Return(trunc);
+
+    if (Pipeline::SupportedTarget()) {
+      t.LowerAllNodesAndLowerChanges();
+      t.GenerateCode();
+
+      FOR_UINT32_INPUTS(i) {
+        uint32_t x = *i / k;
+        t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
+      }
+    }
+  }
+}
+
+
+TEST(NumberDivide_BadConstants) {
+  {
+    TestingGraph t(Type::Signed32());
+    Node* k = t.jsgraph.Constant(-1);
+    Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
+    Node* use = t.Use(div, kMachInt32);
+    t.Return(use);
+    t.Lower();
+
+    CHECK_EQ(IrOpcode::kInt32Sub, use->InputAt(0)->opcode());
+  }
+
+  {
+    TestingGraph t(Type::Signed32());
+    Node* k = t.jsgraph.Constant(0);
+    Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
+    Node* use = t.Use(div, kMachInt32);
+    t.Return(use);
+    t.Lower();
+
+    CHECK_EQ(IrOpcode::kInt32Constant, use->InputAt(0)->opcode());
+    CHECK_EQ(0, OpParameter<int32_t>(use->InputAt(0)));
+  }
+
+  {
+    TestingGraph t(Type::Unsigned32());
+    Node* k = t.jsgraph.Constant(0);
+    Node* div = t.graph()->NewNode(t.simplified()->NumberDivide(), t.p0, k);
+    Node* use = t.Use(div, kMachUint32);
+    t.Return(use);
+    t.Lower();
+
+    CHECK_EQ(IrOpcode::kInt32Constant, use->InputAt(0)->opcode());
+    CHECK_EQ(0, OpParameter<int32_t>(use->InputAt(0)));
+  }
+}
+
+
+TEST(NumberModulus_TruncatingToInt32) {
+  int32_t constants[] = {-100, -10, 1, 4, 100, 1000};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    TestingGraph t(Type::Signed32());
+    Node* k = t.jsgraph.Constant(constants[i]);
+    Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
+    Node* use = t.Use(mod, kMachInt32);
+    t.Return(use);
+    t.Lower();
+
+    CHECK_EQ(IrOpcode::kInt32Mod, use->InputAt(0)->opcode());
+  }
+}
+
+
+TEST(RunNumberModulus_TruncatingToInt32) {
+  int32_t constants[] = {-100, -10, -1, 1, 2, 100, 1000, 1024, 2048};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    int32_t k = constants[i];
+    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    Node* num = t.NumberToInt32(t.Parameter(0));
+    Node* mod = t.NumberModulus(num, t.jsgraph.Constant(k));
+    Node* trunc = t.NumberToInt32(mod);
+    t.Return(trunc);
+
+    if (Pipeline::SupportedTarget()) {
+      t.LowerAllNodesAndLowerChanges();
+      t.GenerateCode();
+
+      FOR_INT32_INPUTS(i) {
+        if (*i == INT_MAX) continue;  // exclude max int.
+        int32_t x = DoubleToInt32(std::fmod(static_cast<double>(*i), k));
+        t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
+      }
+    }
+  }
+}
+
+
+TEST(NumberModulus_TruncatingToUint32) {
+  double constants[] = {1, 3, 100, 1000, 100998348};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    TestingGraph t(Type::Unsigned32());
+    Node* k = t.jsgraph.Constant(constants[i]);
+    Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
+    Node* trunc = t.graph()->NewNode(t.simplified()->NumberToUint32(), mod);
+    Node* ret = t.Return(trunc);
+    t.Lower();
+
+    CHECK_EQ(IrOpcode::kUint32Mod, ret->InputAt(0)->opcode());
+  }
+}
+
+
+TEST(RunNumberModulus_TruncatingToUint32) {
+  uint32_t constants[] = {1, 2, 100, 1000, 1024, 2048};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    uint32_t k = constants[i];
+    SimplifiedLoweringTester<Object*> t(kMachAnyTagged);
+    Node* num = t.NumberToUint32(t.Parameter(0));
+    Node* mod =
+        t.NumberModulus(num, t.jsgraph.Constant(static_cast<double>(k)));
+    Node* trunc = t.NumberToUint32(mod);
+    t.Return(trunc);
+
+    if (Pipeline::SupportedTarget()) {
+      t.LowerAllNodesAndLowerChanges();
+      t.GenerateCode();
+
+      FOR_UINT32_INPUTS(i) {
+        uint32_t x = *i % k;
+        t.CheckNumberCall(static_cast<double>(x), static_cast<double>(*i));
+      }
+    }
+  }
+}
+
+
+TEST(NumberModulus_Int32) {
+  int32_t constants[] = {-100, -10, 1, 4, 100, 1000};
+
+  for (size_t i = 0; i < arraysize(constants); i++) {
+    TestingGraph t(Type::Signed32());
+    Node* k = t.jsgraph.Constant(constants[i]);
+    Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
+    t.Return(mod);
+    t.Lower();
+
+    CHECK_EQ(IrOpcode::kFloat64Mod, mod->opcode());  // Pesky -0 behavior.
+  }
+}
+
+
+TEST(NumberModulus_Uint32) {
+  const double kConstants[] = {2, 100, 1000, 1024, 2048};
+  const MachineType kTypes[] = {kMachInt32, kMachUint32};
+
+  for (auto const type : kTypes) {
+    for (auto const c : kConstants) {
+      TestingGraph t(Type::Unsigned32());
+      Node* k = t.jsgraph.Constant(c);
+      Node* mod = t.graph()->NewNode(t.simplified()->NumberModulus(), t.p0, k);
+      Node* use = t.Use(mod, type);
+      t.Return(use);
+      t.Lower();
+
+      CHECK_EQ(IrOpcode::kUint32Mod, use->InputAt(0)->opcode());
+    }
+  }
+}
+
+
+TEST(PhiRepresentation) {
+  HandleAndZoneScope scope;
+  Zone* z = scope.main_zone();
+
+  struct TestData {
+    Type* arg1;
+    Type* arg2;
+    MachineType use;
+    MachineTypeUnion expected;
+  };
+
+  TestData test_data[] = {
+      {Type::Signed32(), Type::Unsigned32(), kMachInt32,
+       kRepWord32 | kTypeNumber},
+      {Type::Signed32(), Type::Unsigned32(), kMachUint32,
+       kRepWord32 | kTypeNumber},
+      {Type::Signed32(), Type::Signed32(), kMachInt32, kMachInt32},
+      {Type::Unsigned32(), Type::Unsigned32(), kMachInt32, kMachUint32},
+      {Type::Number(), Type::Signed32(), kMachInt32, kMachFloat64},
+      {Type::Signed32(), Type::String(), kMachInt32, kMachAnyTagged}};
+
+  for (auto const d : test_data) {
+    TestingGraph t(d.arg1, d.arg2, Type::Boolean());
+
+    Node* br = t.graph()->NewNode(t.common()->Branch(), t.p2, t.start);
+    Node* tb = t.graph()->NewNode(t.common()->IfTrue(), br);
+    Node* fb = t.graph()->NewNode(t.common()->IfFalse(), br);
+    Node* m = t.graph()->NewNode(t.common()->Merge(2), tb, fb);
+
+    Node* phi =
+        t.graph()->NewNode(t.common()->Phi(kMachAnyTagged, 2), t.p0, t.p1, m);
+
+    Bounds phi_bounds = Bounds::Either(Bounds(d.arg1), Bounds(d.arg2), z);
+    NodeProperties::SetBounds(phi, phi_bounds);
+
+    Node* use = t.Use(phi, d.use);
+    t.Return(use);
+    t.Lower();
+
+    CHECK_EQ(d.expected, OpParameter<MachineType>(phi));
+  }
 }
diff --git a/test/cctest/compiler/test-typer.cc b/test/cctest/compiler/test-typer.cc
new file mode 100644
index 0000000..5f7f55a
--- /dev/null
+++ b/test/cctest/compiler/test-typer.cc
@@ -0,0 +1,380 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <functional>
+
+#include "src/codegen.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/typer.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/graph-builder-tester.h"
+#include "test/cctest/types-fuzz.h"
+
+using namespace v8::internal;
+using namespace v8::internal::compiler;
+
+
+// TODO(titzer): generate a large set of deterministic inputs for these tests.
+class TyperTester : public HandleAndZoneScope, public GraphAndBuilders {
+ public:
+  TyperTester()
+      : GraphAndBuilders(main_zone()),
+        types_(main_zone(), isolate()),
+        typer_(graph(), MaybeHandle<Context>()),
+        javascript_(main_zone()) {
+    Node* s = graph()->NewNode(common()->Start(3));
+    graph()->SetStart(s);
+    context_node_ = graph()->NewNode(common()->Parameter(2), graph()->start());
+    rng_ = isolate()->random_number_generator();
+
+    integers.push_back(0);
+    integers.push_back(0);
+    integers.push_back(-1);
+    integers.push_back(+1);
+    integers.push_back(-V8_INFINITY);
+    integers.push_back(+V8_INFINITY);
+    for (int i = 0; i < 5; ++i) {
+      double x = rng_->NextInt();
+      integers.push_back(x);
+      x *= rng_->NextInt();
+      if (!IsMinusZero(x)) integers.push_back(x);
+    }
+
+    int32s.push_back(0);
+    int32s.push_back(0);
+    int32s.push_back(-1);
+    int32s.push_back(+1);
+    int32s.push_back(kMinInt);
+    int32s.push_back(kMaxInt);
+    for (int i = 0; i < 10; ++i) {
+      int32s.push_back(rng_->NextInt());
+    }
+  }
+
+  Types<Type, Type*, Zone> types_;
+  Typer typer_;
+  JSOperatorBuilder javascript_;
+  Node* context_node_;
+  v8::base::RandomNumberGenerator* rng_;
+  std::vector<double> integers;
+  std::vector<double> int32s;
+
+  Isolate* isolate() { return main_isolate(); }
+  Graph* graph() { return main_graph_; }
+  CommonOperatorBuilder* common() { return &main_common_; }
+
+  Node* Parameter(int index = 0) {
+    return graph()->NewNode(common()->Parameter(index), graph()->start());
+  }
+
+  Type* TypeBinaryOp(const Operator* op, Type* lhs, Type* rhs) {
+    Node* p0 = Parameter(0);
+    Node* p1 = Parameter(1);
+    NodeProperties::SetBounds(p0, Bounds(lhs));
+    NodeProperties::SetBounds(p1, Bounds(rhs));
+    Node* n = graph()->NewNode(
+        op, p0, p1, context_node_, graph()->start(), graph()->start());
+    return NodeProperties::GetBounds(n).upper;
+  }
+
+  Type* RandomRange(bool int32 = false) {
+    std::vector<double>& numbers = int32 ? int32s : integers;
+    double i = numbers[rng_->NextInt(static_cast<int>(numbers.size()))];
+    double j = numbers[rng_->NextInt(static_cast<int>(numbers.size()))];
+    return NewRange(i, j);
+  }
+
+  Type* NewRange(double i, double j) {
+    Factory* f = isolate()->factory();
+    i::Handle<i::Object> min = f->NewNumber(i);
+    i::Handle<i::Object> max = f->NewNumber(j);
+    if (min->Number() > max->Number()) std::swap(min, max);
+    return Type::Range(min, max, main_zone());
+  }
+
+  double RandomInt(double min, double max) {
+    switch (rng_->NextInt(4)) {
+      case 0: return min;
+      case 1: return max;
+      default: break;
+    }
+    if (min == +V8_INFINITY) return +V8_INFINITY;
+    if (max == -V8_INFINITY) return -V8_INFINITY;
+    if (min == -V8_INFINITY && max == +V8_INFINITY) {
+      return rng_->NextInt() * static_cast<double>(rng_->NextInt());
+    }
+    double result = nearbyint(min + (max - min) * rng_->NextDouble());
+    if (IsMinusZero(result)) return 0;
+    if (std::isnan(result)) return rng_->NextInt(2) ? min : max;
+    DCHECK(min <= result && result <= max);
+    return result;
+  }
+
+  double RandomInt(Type::RangeType* range) {
+    return RandomInt(range->Min()->Number(), range->Max()->Number());
+  }
+
+  // Careful, this function runs O(max_width^5) trials.
+  template <class BinaryFunction>
+  void TestBinaryArithOpCloseToZero(const Operator* op, BinaryFunction opfun,
+                                    int max_width) {
+    const int min_min = -2 - max_width / 2;
+    const int max_min = 2 + max_width / 2;
+    for (int width = 0; width < max_width; width++) {
+      for (int lmin = min_min; lmin <= max_min; lmin++) {
+        for (int rmin = min_min; rmin <= max_min; rmin++) {
+          Type* r1 = NewRange(lmin, lmin + width);
+          Type* r2 = NewRange(rmin, rmin + width);
+          Type* expected_type = TypeBinaryOp(op, r1, r2);
+
+          for (int x1 = lmin; x1 < lmin + width; x1++) {
+            for (int x2 = rmin; x2 < rmin + width; x2++) {
+              double result_value = opfun(x1, x2);
+              Type* result_type = Type::Constant(
+                  isolate()->factory()->NewNumber(result_value), main_zone());
+              CHECK(result_type->Is(expected_type));
+            }
+          }
+        }
+      }
+    }
+  }
+
+  template <class BinaryFunction>
+  void TestBinaryArithOp(const Operator* op, BinaryFunction opfun) {
+    TestBinaryArithOpCloseToZero(op, opfun, 8);
+    for (int i = 0; i < 100; ++i) {
+      Type::RangeType* r1 = RandomRange()->AsRange();
+      Type::RangeType* r2 = RandomRange()->AsRange();
+      Type* expected_type = TypeBinaryOp(op, r1, r2);
+      for (int i = 0; i < 10; i++) {
+        double x1 = RandomInt(r1);
+        double x2 = RandomInt(r2);
+        double result_value = opfun(x1, x2);
+        Type* result_type = Type::Constant(
+            isolate()->factory()->NewNumber(result_value), main_zone());
+        CHECK(result_type->Is(expected_type));
+      }
+    }
+  }
+
+  template <class BinaryFunction>
+  void TestBinaryCompareOp(const Operator* op, BinaryFunction opfun) {
+    for (int i = 0; i < 100; ++i) {
+      Type::RangeType* r1 = RandomRange()->AsRange();
+      Type::RangeType* r2 = RandomRange()->AsRange();
+      Type* expected_type = TypeBinaryOp(op, r1, r2);
+      for (int i = 0; i < 10; i++) {
+        double x1 = RandomInt(r1);
+        double x2 = RandomInt(r2);
+        bool result_value = opfun(x1, x2);
+        Type* result_type =
+            Type::Constant(result_value ? isolate()->factory()->true_value()
+                                        : isolate()->factory()->false_value(),
+                           main_zone());
+        CHECK(result_type->Is(expected_type));
+      }
+    }
+  }
+
+  template <class BinaryFunction>
+  void TestBinaryBitOp(const Operator* op, BinaryFunction opfun) {
+    for (int i = 0; i < 100; ++i) {
+      Type::RangeType* r1 = RandomRange(true)->AsRange();
+      Type::RangeType* r2 = RandomRange(true)->AsRange();
+      Type* expected_type = TypeBinaryOp(op, r1, r2);
+      for (int i = 0; i < 10; i++) {
+        int32_t x1 = static_cast<int32_t>(RandomInt(r1));
+        int32_t x2 = static_cast<int32_t>(RandomInt(r2));
+        double result_value = opfun(x1, x2);
+        Type* result_type = Type::Constant(
+            isolate()->factory()->NewNumber(result_value), main_zone());
+        CHECK(result_type->Is(expected_type));
+      }
+    }
+  }
+
+  Type* RandomSubtype(Type* type) {
+    Type* subtype;
+    do {
+      subtype = types_.Fuzz();
+    } while (!subtype->Is(type));
+    return subtype;
+  }
+
+  void TestBinaryMonotonicity(const Operator* op) {
+    for (int i = 0; i < 50; ++i) {
+      Type* type1 = types_.Fuzz();
+      Type* type2 = types_.Fuzz();
+      Type* type = TypeBinaryOp(op, type1, type2);
+      Type* subtype1 = RandomSubtype(type1);;
+      Type* subtype2 = RandomSubtype(type2);;
+      Type* subtype = TypeBinaryOp(op, subtype1, subtype2);
+      CHECK(subtype->Is(type));
+    }
+  }
+};
+
+
+static int32_t shift_left(int32_t x, int32_t y) { return x << y; }
+static int32_t shift_right(int32_t x, int32_t y) { return x >> y; }
+static int32_t bit_or(int32_t x, int32_t y) { return x | y; }
+static int32_t bit_and(int32_t x, int32_t y) { return x & y; }
+static int32_t bit_xor(int32_t x, int32_t y) { return x ^ y; }
+
+
+//------------------------------------------------------------------------------
+// Soundness
+//   For simplicity, we currently only test soundness on expression operators
+//   that have a direct equivalent in C++.  Also, testing is currently limited
+//   to ranges as input types.
+
+
+TEST(TypeJSAdd) {
+  TyperTester t;
+  t.TestBinaryArithOp(t.javascript_.Add(), std::plus<double>());
+}
+
+
+TEST(TypeJSSubtract) {
+  TyperTester t;
+  t.TestBinaryArithOp(t.javascript_.Subtract(), std::minus<double>());
+}
+
+
+TEST(TypeJSMultiply) {
+  TyperTester t;
+  t.TestBinaryArithOp(t.javascript_.Multiply(), std::multiplies<double>());
+}
+
+
+TEST(TypeJSDivide) {
+  TyperTester t;
+  t.TestBinaryArithOp(t.javascript_.Divide(), std::divides<double>());
+}
+
+
+TEST(TypeJSModulus) {
+  TyperTester t;
+  t.TestBinaryArithOp(t.javascript_.Modulus(), modulo);
+}
+
+
+TEST(TypeJSBitwiseOr) {
+  TyperTester t;
+  t.TestBinaryBitOp(t.javascript_.BitwiseOr(), bit_or);
+}
+
+
+TEST(TypeJSBitwiseAnd) {
+  TyperTester t;
+  t.TestBinaryBitOp(t.javascript_.BitwiseAnd(), bit_and);
+}
+
+
+TEST(TypeJSBitwiseXor) {
+  TyperTester t;
+  t.TestBinaryBitOp(t.javascript_.BitwiseXor(), bit_xor);
+}
+
+
+TEST(TypeJSShiftLeft) {
+  TyperTester t;
+  t.TestBinaryBitOp(t.javascript_.ShiftLeft(), shift_left);
+}
+
+
+TEST(TypeJSShiftRight) {
+  TyperTester t;
+  t.TestBinaryBitOp(t.javascript_.ShiftRight(), shift_right);
+}
+
+
+TEST(TypeJSLessThan) {
+  TyperTester t;
+  t.TestBinaryCompareOp(t.javascript_.LessThan(), std::less<double>());
+}
+
+
+TEST(TypeJSLessThanOrEqual) {
+  TyperTester t;
+  t.TestBinaryCompareOp(
+      t.javascript_.LessThanOrEqual(), std::less_equal<double>());
+}
+
+
+TEST(TypeJSGreaterThan) {
+  TyperTester t;
+  t.TestBinaryCompareOp(t.javascript_.GreaterThan(), std::greater<double>());
+}
+
+
+TEST(TypeJSGreaterThanOrEqual) {
+  TyperTester t;
+  t.TestBinaryCompareOp(
+      t.javascript_.GreaterThanOrEqual(), std::greater_equal<double>());
+}
+
+
+TEST(TypeJSEqual) {
+  TyperTester t;
+  t.TestBinaryCompareOp(t.javascript_.Equal(), std::equal_to<double>());
+}
+
+
+TEST(TypeJSNotEqual) {
+  TyperTester t;
+  t.TestBinaryCompareOp(t.javascript_.NotEqual(), std::not_equal_to<double>());
+}
+
+
+// For numbers there's no difference between strict and non-strict equality.
+TEST(TypeJSStrictEqual) {
+  TyperTester t;
+  t.TestBinaryCompareOp(t.javascript_.StrictEqual(), std::equal_to<double>());
+}
+
+
+TEST(TypeJSStrictNotEqual) {
+  TyperTester t;
+  t.TestBinaryCompareOp(
+      t.javascript_.StrictNotEqual(), std::not_equal_to<double>());
+}
+
+
+//------------------------------------------------------------------------------
+// Monotonicity
+
+
+// List should be in sync with JS_SIMPLE_BINOP_LIST.
+#define JSBINOP_LIST(V) \
+  V(Equal) \
+  V(NotEqual) \
+  V(StrictEqual) \
+  V(StrictNotEqual) \
+  V(LessThan) \
+  V(GreaterThan) \
+  V(LessThanOrEqual) \
+  V(GreaterThanOrEqual) \
+  V(BitwiseOr) \
+  V(BitwiseXor) \
+  V(BitwiseAnd) \
+  V(ShiftLeft) \
+  V(ShiftRight) \
+  V(ShiftRightLogical) \
+  V(Add) \
+  V(Subtract) \
+  V(Multiply) \
+  V(Divide) \
+  V(Modulus)
+
+
+#define TEST_FUNC(name)                             \
+  TEST(Monotonicity_##name) {                       \
+    TyperTester t;                                  \
+    t.TestBinaryMonotonicity(t.javascript_.name()); \
+  }
+JSBINOP_LIST(TEST_FUNC)
+#undef TEST_FUNC
diff --git a/test/cctest/compiler/value-helper.h b/test/cctest/compiler/value-helper.h
index b5da982..218a773 100644
--- a/test/cctest/compiler/value-helper.h
+++ b/test/cctest/compiler/value-helper.h
@@ -60,6 +60,45 @@
     CheckHeapConstant(isolate_->heap()->false_value(), node);
   }
 
+  static std::vector<float> float32_vector() {
+    static const float kValues[] = {
+        -std::numeric_limits<float>::infinity(), -2.70497e+38f, -1.4698e+37f,
+        -1.22813e+35f,                           -1.20555e+35f, -1.34584e+34f,
+        -1.0079e+32f,                            -6.49364e+26f, -3.06077e+25f,
+        -1.46821e+25f,                           -1.17658e+23f, -1.9617e+22f,
+        -2.7357e+20f,                            -1.48708e+13f, -1.89633e+12f,
+        -4.66622e+11f,                           -2.22581e+11f, -1.45381e+10f,
+        -1.3956e+09f,                            -1.32951e+09f, -1.30721e+09f,
+        -1.19756e+09f,                           -9.26822e+08f, -6.35647e+08f,
+        -4.00037e+08f,                           -1.81227e+08f, -5.09256e+07f,
+        -964300.0f,                              -192446.0f,    -28455.0f,
+        -27194.0f,                               -26401.0f,     -20575.0f,
+        -17069.0f,                               -9167.0f,      -960.178f,
+        -113.0f,                                 -62.0f,        -15.0f,
+        -7.0f,                                   -0.0256635f,   -4.60374e-07f,
+        -3.63759e-10f,                           -4.30175e-14f, -5.27385e-15f,
+        -1.48084e-15f,                           -1.05755e-19f, -3.2995e-21f,
+        -1.67354e-23f,                           -1.11885e-23f, -1.78506e-30f,
+        -5.07594e-31f,                           -3.65799e-31f, -1.43718e-34f,
+        -1.27126e-38f,                           -0.0f,         0.0f,
+        1.17549e-38f,                            1.56657e-37f,  4.08512e-29f,
+        3.31357e-28f,                            6.25073e-22f,  4.1723e-13f,
+        1.44343e-09f,                            5.27004e-08f,  9.48298e-08f,
+        5.57888e-07f,                            4.89988e-05f,  0.244326f,
+        12.4895f,                                19.0f,         47.0f,
+        106.0f,                                  538.324f,      564.536f,
+        819.124f,                                7048.0f,       12611.0f,
+        19878.0f,                                20309.0f,      797056.0f,
+        1.77219e+09f,                            1.51116e+11f,  4.18193e+13f,
+        3.59167e+16f,                            3.38211e+19f,  2.67488e+20f,
+        1.78831e+21f,                            9.20914e+21f,  8.35654e+23f,
+        1.4495e+24f,                             5.94015e+25f,  4.43608e+30f,
+        2.44502e+33f,                            2.61152e+33f,  1.38178e+37f,
+        1.71306e+37f,                            3.31899e+38f,  3.40282e+38f,
+        std::numeric_limits<float>::infinity()};
+    return std::vector<float>(&kValues[0], &kValues[arraysize(kValues)]);
+  }
+
   static std::vector<double> float64_vector() {
     static const double nan = v8::base::OS::nan_value();
     static const double values[] = {
@@ -82,6 +121,8 @@
   static const std::vector<uint32_t> uint32_vector() {
     static const uint32_t kValues[] = {
         0x00000000, 0x00000001, 0xffffffff, 0x1b09788b, 0x04c5fce8, 0xcc0de5bf,
+        // This row is useful for testing lea optimizations on intel.
+        0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000008, 0x00000009,
         0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344,
         0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c,
         0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00,
@@ -117,6 +158,7 @@
 
 #define FOR_INT32_INPUTS(var) FOR_INPUTS(int32_t, int32, var)
 #define FOR_UINT32_INPUTS(var) FOR_INPUTS(uint32_t, uint32, var)
+#define FOR_FLOAT32_INPUTS(var) FOR_INPUTS(float, float32, var)
 #define FOR_FLOAT64_INPUTS(var) FOR_INPUTS(double, float64, var)
 
 #define FOR_INT32_SHIFTS(var) for (int32_t var = 0; var < 32; var++)
diff --git a/test/cctest/test-accessors.cc b/test/cctest/test-accessors.cc
index 5bf61c8..5f452ea 100644
--- a/test/cctest/test-accessors.cc
+++ b/test/cctest/test-accessors.cc
@@ -38,6 +38,7 @@
 using ::v8::Value;
 using ::v8::Context;
 using ::v8::Local;
+using ::v8::Name;
 using ::v8::String;
 using ::v8::Script;
 using ::v8::Function;
@@ -513,7 +514,7 @@
 }
 
 
-void JSONStringifyGetter(Local<String> name,
+void JSONStringifyGetter(Local<Name> name,
                          const v8::PropertyCallbackInfo<v8::Value>& info) {
   info.GetReturnValue().Set(v8_str("crbug-161028"));
 }
@@ -525,8 +526,8 @@
   v8::HandleScope scope(isolate);
 
   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
-  obj->SetNamedPropertyHandler(
-      JSONStringifyGetter, NULL, NULL, NULL, JSONStringifyEnumerator);
+  obj->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      JSONStringifyGetter, NULL, NULL, NULL, JSONStringifyEnumerator));
   env->Global()->Set(v8_str("obj"), obj->NewInstance());
   v8::Handle<v8::String> expected = v8_str("{\"regress\":\"crbug-161028\"}");
   CHECK(CompileRun("JSON.stringify(obj)")->Equals(expected));
@@ -577,3 +578,30 @@
   CHECK(v8::Utils::OpenHandle(*CompileRun("getter()"))->IsJSGlobalProxy());
   CHECK(v8::Utils::OpenHandle(*CompileRun("set_value"))->IsJSGlobalProxy());
 }
+
+
+static void EmptyGetter(Local<Name> name,
+                        const v8::PropertyCallbackInfo<v8::Value>& info) {
+  ApiTestFuzzer::Fuzz();
+}
+
+
+static void OneProperty(Local<String> name,
+                        const v8::PropertyCallbackInfo<v8::Value>& info) {
+  ApiTestFuzzer::Fuzz();
+  info.GetReturnValue().Set(v8_num(1));
+}
+
+
+THREADED_TEST(Regress433458) {
+  LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
+  obj->SetHandler(v8::NamedPropertyHandlerConfiguration(EmptyGetter));
+  obj->SetNativeDataProperty(v8_str("prop"), OneProperty);
+  env->Global()->Set(v8_str("obj"), obj->NewInstance());
+  CompileRun(
+      "Object.defineProperty(obj, 'prop', { writable: false });"
+      "Object.defineProperty(obj, 'prop', { writable: true });");
+}
diff --git a/test/cctest/test-alloc.cc b/test/cctest/test-alloc.cc
index d647a31..2e071ac 100644
--- a/test/cctest/test-alloc.cc
+++ b/test/cctest/test-alloc.cc
@@ -86,7 +86,7 @@
       Builtins::kIllegal)).ToObjectChecked();
 
   // Return success.
-  return Smi::FromInt(42);
+  return heap->true_value();
 }
 
 
@@ -100,7 +100,7 @@
   v8::Handle<v8::Context> env = v8::Context::New(CcTest::isolate());
   env->Enter();
   Handle<Object> o = Test();
-  CHECK(o->IsSmi() && Smi::cast(*o)->value() == 42);
+  CHECK(o->IsTrue());
   env->Exit();
 }
 
@@ -162,7 +162,7 @@
   // Call the accessor through JavaScript.
   v8::Handle<v8::Value> result = v8::Script::Compile(
       v8::String::NewFromUtf8(CcTest::isolate(), "(new Foo).get"))->Run();
-  CHECK_EQ(42, result->Int32Value());
+  CHECK_EQ(true, result->BooleanValue());
   env->Exit();
 }
 
@@ -198,7 +198,8 @@
   const size_t code_range_size = 32*MB;
   CcTest::InitializeVM();
   CodeRange code_range(reinterpret_cast<Isolate*>(CcTest::isolate()));
-  code_range.SetUp(code_range_size);
+  code_range.SetUp(code_range_size +
+                   kReservedCodeRangePages * v8::base::OS::CommitPageSize());
   size_t current_allocated = 0;
   size_t total_allocated = 0;
   List< ::Block> blocks(1000);
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 0e80384..06cf553 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -185,7 +185,8 @@
 }
 
 
-static void TestSignature(const char* loop_js, Local<Value> receiver) {
+static void TestSignature(const char* loop_js, Local<Value> receiver,
+                          v8::Isolate* isolate) {
   i::ScopedVector<char> source(200);
   i::SNPrintF(source,
               "for (var i = 0; i < 10; i++) {"
@@ -202,7 +203,7 @@
     CHECK_EQ(10, signature_callback_count);
   } else {
     CHECK_EQ(v8_str("TypeError: Illegal invocation"),
-             try_catch.Exception()->ToString());
+             try_catch.Exception()->ToString(isolate));
   }
 }
 
@@ -267,17 +268,17 @@
     i::SNPrintF(
         source, "var test_object = %s; test_object", test_objects[i]);
     Local<Value> test_object = CompileRun(source.start());
-    TestSignature("test_object.prop();", test_object);
-    TestSignature("test_object.accessor;", test_object);
-    TestSignature("test_object[accessor_key];", test_object);
-    TestSignature("test_object.accessor = 1;", test_object);
-    TestSignature("test_object[accessor_key] = 1;", test_object);
+    TestSignature("test_object.prop();", test_object, isolate);
+    TestSignature("test_object.accessor;", test_object, isolate);
+    TestSignature("test_object[accessor_key];", test_object, isolate);
+    TestSignature("test_object.accessor = 1;", test_object, isolate);
+    TestSignature("test_object[accessor_key] = 1;", test_object, isolate);
     if (i >= bad_signature_start_offset) test_object = Local<Value>();
-    TestSignature("test_object.prop_sig();", test_object);
-    TestSignature("test_object.accessor_sig;", test_object);
-    TestSignature("test_object[accessor_sig_key];", test_object);
-    TestSignature("test_object.accessor_sig = 1;", test_object);
-    TestSignature("test_object[accessor_sig_key] = 1;", test_object);
+    TestSignature("test_object.prop_sig();", test_object, isolate);
+    TestSignature("test_object.accessor_sig;", test_object, isolate);
+    TestSignature("test_object[accessor_sig_key];", test_object, isolate);
+    TestSignature("test_object.accessor_sig = 1;", test_object, isolate);
+    TestSignature("test_object[accessor_sig_key] = 1;", test_object, isolate);
   }
 }
 
@@ -356,7 +357,7 @@
   v8::Isolate* isolate = env->GetIsolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::Primitive> undef = v8::Undefined(isolate);
-  Local<String> undef_str = undef->ToString();
+  Local<String> undef_str = undef->ToString(isolate);
   char* value = i::NewArray<char>(undef_str->Utf8Length() + 1);
   undef_str->WriteUtf8(value);
   CHECK_EQ(0, strcmp(value, "undefined"));
@@ -742,6 +743,58 @@
 }
 
 
+class RandomLengthResource : public v8::String::ExternalStringResource {
+ public:
+  explicit RandomLengthResource(int length) : length_(length) {}
+  virtual const uint16_t* data() const { return string_; }
+  virtual size_t length() const { return length_; }
+
+ private:
+  uint16_t string_[10];
+  int length_;
+};
+
+
+class RandomLengthOneByteResource
+    : public v8::String::ExternalOneByteStringResource {
+ public:
+  explicit RandomLengthOneByteResource(int length) : length_(length) {}
+  virtual const char* data() const { return string_; }
+  virtual size_t length() const { return length_; }
+
+ private:
+  char string_[10];
+  int length_;
+};
+
+
+THREADED_TEST(NewExternalForVeryLongString) {
+  {
+    LocalContext env;
+    v8::HandleScope scope(env->GetIsolate());
+    v8::TryCatch try_catch;
+    RandomLengthOneByteResource r(1 << 30);
+    v8::Local<v8::String> str = v8::String::NewExternal(CcTest::isolate(), &r);
+    CHECK(str.IsEmpty());
+    CHECK(try_catch.HasCaught());
+    String::Utf8Value exception_value(try_catch.Exception());
+    CHECK_EQ("RangeError: Invalid string length", *exception_value);
+  }
+
+  {
+    LocalContext env;
+    v8::HandleScope scope(env->GetIsolate());
+    v8::TryCatch try_catch;
+    RandomLengthResource r(1 << 30);
+    v8::Local<v8::String> str = v8::String::NewExternal(CcTest::isolate(), &r);
+    CHECK(str.IsEmpty());
+    CHECK(try_catch.HasCaught());
+    String::Utf8Value exception_value(try_catch.Exception());
+    CHECK_EQ("RangeError: Invalid string length", *exception_value);
+  }
+}
+
+
 THREADED_TEST(ScavengeExternalString) {
   i::FLAG_stress_compaction = false;
   i::FLAG_gc_global = false;
@@ -934,7 +987,7 @@
   // If CPU profiler is active check that when API callback is invoked
   // VMState is set to EXTERNAL.
   if (isolate->cpu_profiler()->is_profiling()) {
-    CHECK_EQ(i::EXTERNAL, isolate->current_vm_state());
+    CHECK_EQ(v8::EXTERNAL, isolate->current_vm_state());
     CHECK(isolate->external_callback_scope());
     CHECK_EQ(callback, isolate->external_callback_scope()->callback());
   }
@@ -1181,7 +1234,8 @@
 
 THREADED_PROFILED_TEST(FastReturnValues) {
   LocalContext env;
-  v8::HandleScope scope(CcTest::isolate());
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
   v8::Handle<v8::Value> value;
   // check int32_t and uint32_t
   int32_t int_values[] = {
@@ -1206,13 +1260,13 @@
   // check double
   value = TestFastReturnValues<double>();
   CHECK(value->IsNumber());
-  CHECK_EQ(kFastReturnValueDouble, value->ToNumber()->Value());
+  CHECK_EQ(kFastReturnValueDouble, value->ToNumber(isolate)->Value());
   // check bool values
   for (int i = 0; i < 2; i++) {
     fast_return_value_bool = i == 0;
     value = TestFastReturnValues<bool>();
     CHECK(value->IsBoolean());
-    CHECK_EQ(fast_return_value_bool, value->ToBoolean()->Value());
+    CHECK_EQ(fast_return_value_bool, value->ToBoolean(isolate)->Value());
   }
   // check oddballs
   ReturnValueOddball oddballs[] = {
@@ -1542,6 +1596,34 @@
 }
 
 
+THREADED_TEST(IsGeneratorFunctionOrObject) {
+  LocalContext env;
+  v8::HandleScope scope(env->GetIsolate());
+
+  CompileRun("function *gen() { yield 1; }\nfunction func() {}");
+  v8::Handle<Value> gen = CompileRun("gen");
+  v8::Handle<Value> genObj = CompileRun("gen()");
+  v8::Handle<Value> object = CompileRun("{a:42}");
+  v8::Handle<Value> func = CompileRun("func");
+
+  CHECK(gen->IsGeneratorFunction());
+  CHECK(gen->IsFunction());
+  CHECK(!gen->IsGeneratorObject());
+
+  CHECK(!genObj->IsGeneratorFunction());
+  CHECK(!genObj->IsFunction());
+  CHECK(genObj->IsGeneratorObject());
+
+  CHECK(!object->IsGeneratorFunction());
+  CHECK(!object->IsFunction());
+  CHECK(!object->IsGeneratorObject());
+
+  CHECK(!func->IsGeneratorFunction());
+  CHECK(func->IsFunction());
+  CHECK(!func->IsGeneratorObject());
+}
+
+
 THREADED_TEST(ArgumentsObject) {
   LocalContext env;
   v8::HandleScope scope(env->GetIsolate());
@@ -1904,7 +1986,7 @@
 int echo_named_call_count;
 
 
-static void EchoNamedProperty(Local<String> name,
+static void EchoNamedProperty(Local<Name> name,
                               const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   CHECK_EQ(v8_str("data"), info.Data());
@@ -1946,18 +2028,41 @@
   SimpleAccessorSetter(Local<String>::Cast(sym->Name()), value, info);
 }
 
-void EmptyInterceptorGetter(Local<String> name,
-                            const v8::PropertyCallbackInfo<v8::Value>& info) {
+void SymbolAccessorGetterReturnsDefault(
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+  CHECK(name->IsSymbol());
+  Local<Symbol> sym = Local<Symbol>::Cast(name);
+  if (sym->Name()->IsUndefined()) return;
+  info.GetReturnValue().Set(info.Data());
 }
 
-void EmptyInterceptorSetter(Local<String> name,
-                            Local<Value> value,
-                            const v8::PropertyCallbackInfo<v8::Value>& info) {
+static void ThrowingSymbolAccessorGetter(
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+  info.GetReturnValue().Set(info.GetIsolate()->ThrowException(name));
 }
 
-void InterceptorGetter(Local<String> name,
-                       const v8::PropertyCallbackInfo<v8::Value>& info) {
-  // Intercept names that start with 'interceptor_'.
+
+void EmptyInterceptorGetter(Local<Name> name,
+                            const v8::PropertyCallbackInfo<v8::Value>& info) {}
+
+
+void EmptyInterceptorSetter(Local<Name> name, Local<Value> value,
+                            const v8::PropertyCallbackInfo<v8::Value>& info) {}
+
+
+void EmptyGenericInterceptorGetter(
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {}
+
+
+void EmptyGenericInterceptorSetter(
+    Local<Name> name, Local<Value> value,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {}
+
+
+void StringInterceptorGetter(
+    Local<String> name,
+    const v8::PropertyCallbackInfo<v8::Value>&
+        info) {  // Intercept names that start with 'interceptor_'.
   String::Utf8Value utf8(name);
   char* name_str = *utf8;
   char prefix[] = "interceptor_";
@@ -1969,9 +2074,9 @@
   info.GetReturnValue().Set(self->GetHiddenValue(v8_str(name_str + i)));
 }
 
-void InterceptorSetter(Local<String> name,
-                       Local<Value> value,
-                       const v8::PropertyCallbackInfo<v8::Value>& info) {
+
+void StringInterceptorSetter(Local<String> name, Local<Value> value,
+                             const v8::PropertyCallbackInfo<v8::Value>& info) {
   // Intercept accesses that set certain integer values, for which the name does
   // not start with 'accessor_'.
   String::Utf8Value utf8(name);
@@ -1990,6 +2095,57 @@
   }
 }
 
+void InterceptorGetter(Local<Name> generic_name,
+                       const v8::PropertyCallbackInfo<v8::Value>& info) {
+  if (generic_name->IsSymbol()) return;
+  StringInterceptorGetter(Local<String>::Cast(generic_name), info);
+}
+
+void InterceptorSetter(Local<Name> generic_name, Local<Value> value,
+                       const v8::PropertyCallbackInfo<v8::Value>& info) {
+  if (generic_name->IsSymbol()) return;
+  StringInterceptorSetter(Local<String>::Cast(generic_name), value, info);
+}
+
+void GenericInterceptorGetter(Local<Name> generic_name,
+                              const v8::PropertyCallbackInfo<v8::Value>& info) {
+  Local<String> str;
+  if (generic_name->IsSymbol()) {
+    Local<Value> name = Local<Symbol>::Cast(generic_name)->Name();
+    if (name->IsUndefined()) return;
+    str = String::Concat(v8_str("_sym_"), Local<String>::Cast(name));
+  } else {
+    Local<String> name = Local<String>::Cast(generic_name);
+    String::Utf8Value utf8(name);
+    char* name_str = *utf8;
+    if (*name_str == '_') return;
+    str = String::Concat(v8_str("_str_"), name);
+  }
+
+  Handle<Object> self = Handle<Object>::Cast(info.This());
+  info.GetReturnValue().Set(self->Get(str));
+}
+
+void GenericInterceptorSetter(Local<Name> generic_name, Local<Value> value,
+                              const v8::PropertyCallbackInfo<v8::Value>& info) {
+  Local<String> str;
+  if (generic_name->IsSymbol()) {
+    Local<Value> name = Local<Symbol>::Cast(generic_name)->Name();
+    if (name->IsUndefined()) return;
+    str = String::Concat(v8_str("_sym_"), Local<String>::Cast(name));
+  } else {
+    Local<String> name = Local<String>::Cast(generic_name);
+    String::Utf8Value utf8(name);
+    char* name_str = *utf8;
+    if (*name_str == '_') return;
+    str = String::Concat(v8_str("_str_"), name);
+  }
+
+  Handle<Object> self = Handle<Object>::Cast(info.This());
+  self->Set(str, value);
+  info.GetReturnValue().Set(value);
+}
+
 void AddAccessor(Handle<FunctionTemplate> templ,
                  Handle<String> name,
                  v8::AccessorGetterCallback getter,
@@ -2011,6 +2167,13 @@
   templ->PrototypeTemplate()->SetAccessor(name, getter, setter);
 }
 
+void AddInterceptor(Handle<FunctionTemplate> templ,
+                    v8::GenericNamedPropertyGetterCallback getter,
+                    v8::GenericNamedPropertySetterCallback setter) {
+  templ->InstanceTemplate()->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(getter, setter));
+}
+
 
 THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) {
   v8::HandleScope scope(CcTest::isolate());
@@ -2030,6 +2193,62 @@
 }
 
 
+THREADED_TEST(LegacyInterceptorDoesNotSeeSymbols) {
+  LocalContext env;
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
+  Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate);
+  Handle<FunctionTemplate> child = FunctionTemplate::New(isolate);
+  v8::Local<v8::Symbol> age = v8::Symbol::New(isolate, v8_str("age"));
+
+  child->Inherit(parent);
+  AddAccessor(parent, age, SymbolAccessorGetter, SymbolAccessorSetter);
+  AddInterceptor(child, StringInterceptorGetter, StringInterceptorSetter);
+
+  env->Global()->Set(v8_str("Child"), child->GetFunction());
+  env->Global()->Set(v8_str("age"), age);
+  CompileRun(
+      "var child = new Child;"
+      "child[age] = 10;");
+  ExpectInt32("child[age]", 10);
+  ExpectBoolean("child.hasOwnProperty('age')", false);
+  ExpectBoolean("child.hasOwnProperty('accessor_age')", true);
+}
+
+
+THREADED_TEST(GenericInterceptorDoesSeeSymbols) {
+  LocalContext env;
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
+  Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate);
+  Handle<FunctionTemplate> child = FunctionTemplate::New(isolate);
+  v8::Local<v8::Symbol> age = v8::Symbol::New(isolate, v8_str("age"));
+  v8::Local<v8::Symbol> anon = v8::Symbol::New(isolate);
+
+  child->Inherit(parent);
+  AddAccessor(parent, age, SymbolAccessorGetter, SymbolAccessorSetter);
+  AddInterceptor(child, GenericInterceptorGetter, GenericInterceptorSetter);
+
+  env->Global()->Set(v8_str("Child"), child->GetFunction());
+  env->Global()->Set(v8_str("age"), age);
+  env->Global()->Set(v8_str("anon"), anon);
+  CompileRun(
+      "var child = new Child;"
+      "child[age] = 10;");
+  ExpectInt32("child[age]", 10);
+  ExpectInt32("child._sym_age", 10);
+
+  // Check that it also sees strings.
+  CompileRun("child.foo = 47");
+  ExpectInt32("child.foo", 47);
+  ExpectInt32("child._str_foo", 47);
+
+  // Check that the interceptor can punt (in this case, on anonymous symbols).
+  CompileRun("child[anon] = 31337");
+  ExpectInt32("child[anon]", 31337);
+}
+
+
 THREADED_TEST(ExecutableAccessorIsPreservedOnAttributeChange) {
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
@@ -2275,9 +2494,8 @@
   v8::HandleScope scope(CcTest::isolate());
   v8::Handle<v8::FunctionTemplate> templ =
       v8::FunctionTemplate::New(CcTest::isolate());
-  templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty,
-                                                     0, 0, 0, 0,
-                                                     v8_str("data"));
+  templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      EchoNamedProperty, 0, 0, 0, 0, v8_str("data")));
   LocalContext env;
   env->Global()->Set(v8_str("obj"),
                      templ->GetFunction()->NewInstance());
@@ -2312,9 +2530,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
-  templ->InstanceTemplate()->SetIndexedPropertyHandler(EchoIndexedProperty,
-                                                       0, 0, 0, 0,
-                                                       v8_num(637));
+  templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      EchoIndexedProperty, 0, 0, 0, 0, v8_num(637)));
   LocalContext env;
   env->Global()->Set(v8_str("obj"),
                      templ->GetFunction()->NewInstance());
@@ -2334,8 +2551,7 @@
 }
 
 static void CheckThisNamedPropertyHandler(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyHandler));
   ApiTestFuzzer::Fuzz();
   CHECK(info.This()->Equals(bottom));
@@ -2352,8 +2568,7 @@
 
 
 void CheckThisNamedPropertySetter(
-    Local<String> property,
-    Local<Value> value,
+    Local<Name> property, Local<Value> value,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertySetter));
   ApiTestFuzzer::Fuzz();
@@ -2370,8 +2585,7 @@
 
 
 void CheckThisNamedPropertyQuery(
-    Local<String> property,
-    const v8::PropertyCallbackInfo<v8::Integer>& info) {
+    Local<Name> property, const v8::PropertyCallbackInfo<v8::Integer>& info) {
   CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyQuery));
   ApiTestFuzzer::Fuzz();
   CHECK(info.This()->Equals(bottom));
@@ -2388,8 +2602,7 @@
 
 
 void CheckThisNamedPropertyDeleter(
-    Local<String> property,
-    const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+    Local<Name> property, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
   CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyDeleter));
   ApiTestFuzzer::Fuzz();
   CHECK(info.This()->Equals(bottom));
@@ -2419,19 +2632,15 @@
 
   // Set up a prototype chain with three interceptors.
   v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
-  templ->InstanceTemplate()->SetIndexedPropertyHandler(
-      CheckThisIndexedPropertyHandler,
-      CheckThisIndexedPropertySetter,
-      CheckThisIndexedPropertyQuery,
-      CheckThisIndexedPropertyDeleter,
-      CheckThisIndexedPropertyEnumerator);
+  templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter,
+      CheckThisIndexedPropertyQuery, CheckThisIndexedPropertyDeleter,
+      CheckThisIndexedPropertyEnumerator));
 
-  templ->InstanceTemplate()->SetNamedPropertyHandler(
-      CheckThisNamedPropertyHandler,
-      CheckThisNamedPropertySetter,
-      CheckThisNamedPropertyQuery,
-      CheckThisNamedPropertyDeleter,
-      CheckThisNamedPropertyEnumerator);
+  templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter,
+      CheckThisNamedPropertyQuery, CheckThisNamedPropertyDeleter,
+      CheckThisNamedPropertyEnumerator));
 
   bottom = templ->GetFunction()->NewInstance();
   Local<v8::Object> top = templ->GetFunction()->NewInstance();
@@ -2463,8 +2672,7 @@
 
 
 static void PrePropertyHandlerGet(
-    Local<String> key,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   if (v8_str("pre")->Equals(key)) {
     info.GetReturnValue().Set(v8_str("PrePropertyHandler: pre"));
@@ -2473,8 +2681,7 @@
 
 
 static void PrePropertyHandlerQuery(
-    Local<String> key,
-    const v8::PropertyCallbackInfo<v8::Integer>& info) {
+    Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) {
   if (v8_str("pre")->Equals(key)) {
     info.GetReturnValue().Set(static_cast<int32_t>(v8::None));
   }
@@ -2485,9 +2692,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate);
-  desc->InstanceTemplate()->SetNamedPropertyHandler(PrePropertyHandlerGet,
-                                                    0,
-                                                    PrePropertyHandlerQuery);
+  desc->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      PrePropertyHandlerGet, 0, PrePropertyHandlerQuery));
   LocalContext env(NULL, desc->InstanceTemplate());
   CompileRun("var pre = 'Object: pre'; var on = 'Object: on';");
   v8::Handle<Value> result_pre = CompileRun("pre");
@@ -2560,16 +2766,17 @@
 
 
 static void ThrowingPropertyHandlerGet(
-    Local<String> key,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
+  // Since this interceptor is used on "with" objects, the runtime will look up
+  // @@unscopables.  Punt.
+  if (key->IsSymbol()) return;
   ApiTestFuzzer::Fuzz();
   info.GetReturnValue().Set(info.GetIsolate()->ThrowException(key));
 }
 
 
 static void ThrowingPropertyHandlerSet(
-    Local<String> key,
-    Local<Value>,
+    Local<Name> key, Local<Value>,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   info.GetIsolate()->ThrowException(key);
   info.GetReturnValue().SetUndefined();  // not the same as empty handle
@@ -2580,8 +2787,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
-  obj->SetNamedPropertyHandler(ThrowingPropertyHandlerGet,
-                               ThrowingPropertyHandlerSet);
+  obj->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      ThrowingPropertyHandlerGet, ThrowingPropertyHandlerSet));
   LocalContext env;
   env->Global()->Set(v8_str("obj"), obj->NewInstance());
   v8::Handle<Value> otto = CompileRun(
@@ -2749,6 +2956,16 @@
 }
 
 
+THREADED_TEST(GetIsolate) {
+  LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+  Local<v8::Object> obj = v8::Object::New(isolate);
+  CHECK_EQ(isolate, obj->GetIsolate());
+  CHECK_EQ(isolate, CcTest::global()->GetIsolate());
+}
+
+
 THREADED_TEST(IdentityHash) {
   LocalContext env;
   v8::Isolate* isolate = env->GetIsolate();
@@ -2813,6 +3030,53 @@
 }
 
 
+TEST(SymbolIdentityHash) {
+  LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+
+  {
+    Local<v8::Symbol> symbol = v8::Symbol::New(isolate);
+    int hash = symbol->GetIdentityHash();
+    int hash1 = symbol->GetIdentityHash();
+    CHECK_EQ(hash, hash1);
+    CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+    int hash3 = symbol->GetIdentityHash();
+    CHECK_EQ(hash, hash3);
+  }
+
+  {
+    v8::Handle<v8::Symbol> js_symbol =
+        CompileRun("Symbol('foo')").As<v8::Symbol>();
+    int hash = js_symbol->GetIdentityHash();
+    int hash1 = js_symbol->GetIdentityHash();
+    CHECK_EQ(hash, hash1);
+    CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+    int hash3 = js_symbol->GetIdentityHash();
+    CHECK_EQ(hash, hash3);
+  }
+}
+
+
+TEST(StringIdentityHash) {
+  LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+
+  Local<v8::String> str = v8::String::NewFromUtf8(isolate, "str1");
+  int hash = str->GetIdentityHash();
+  int hash1 = str->GetIdentityHash();
+  CHECK_EQ(hash, hash1);
+  CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+  int hash3 = str->GetIdentityHash();
+  CHECK_EQ(hash, hash3);
+
+  Local<v8::String> str2 = v8::String::NewFromUtf8(isolate, "str1");
+  int hash4 = str2->GetIdentityHash();
+  CHECK_EQ(hash, hash4);
+}
+
+
 THREADED_TEST(SymbolProperties) {
   LocalContext env;
   v8::Isolate* isolate = env->GetIsolate();
@@ -3195,6 +3459,24 @@
 }
 
 
+THREADED_TEST(ArrayBuffer_DisableNeuter) {
+  LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope handle_scope(isolate);
+
+  i::ScopedVector<uint8_t> my_data(100);
+  memset(my_data.start(), 0, 100);
+  Local<v8::ArrayBuffer> ab =
+      v8::ArrayBuffer::New(isolate, my_data.start(), 100);
+  CHECK(ab->IsNeuterable());
+
+  i::Handle<i::JSArrayBuffer> buf = v8::Utils::OpenHandle(*ab);
+  buf->set_is_neuterable(false);
+
+  CHECK(!ab->IsNeuterable());
+}
+
+
 static void CheckDataViewIsNeutered(v8::Handle<v8::DataView> dv) {
   CHECK_EQ(0, static_cast<int>(dv->ByteLength()));
   CHECK_EQ(0, static_cast<int>(dv->ByteOffset()));
@@ -3411,7 +3693,7 @@
 
 static bool interceptor_for_hidden_properties_called;
 static void InterceptorForHiddenProperties(
-    Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   interceptor_for_hidden_properties_called = true;
 }
 
@@ -3428,7 +3710,8 @@
   // Associate an interceptor with an object and start setting hidden values.
   Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate);
   Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate();
-  instance_templ->SetNamedPropertyHandler(InterceptorForHiddenProperties);
+  instance_templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorForHiddenProperties));
   Local<v8::Function> function = fun_templ->GetFunction();
   Local<v8::Object> obj = function->NewInstance();
   CHECK(obj->SetHiddenValue(key, v8::Integer::New(isolate, 2302)));
@@ -4144,6 +4427,45 @@
 }
 
 
+THREADED_TEST(WeakRootsSurviveTwoRoundsOfGC) {
+  LocalContext env;
+  v8::Isolate* iso = env->GetIsolate();
+  HandleScope scope(iso);
+
+  WeakCallCounter counter(1234);
+
+  WeakCallCounterAndPersistent<Value> weak_obj(&counter);
+
+  // Create a weak object that references a internalized string.
+  {
+    HandleScope scope(iso);
+    weak_obj.handle.Reset(iso, Object::New(iso));
+    weak_obj.handle.SetWeak(&weak_obj, &WeakPointerCallback);
+    CHECK(weak_obj.handle.IsWeak());
+    Local<Object>::New(iso, weak_obj.handle.As<Object>())->Set(
+        v8_str("x"),
+        String::NewFromUtf8(iso, "magic cookie", String::kInternalizedString));
+  }
+  // Do a single full GC
+  i::Isolate* i_iso = reinterpret_cast<v8::internal::Isolate*>(iso);
+  i::Heap* heap = i_iso->heap();
+  heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
+
+  // We should have received the weak callback.
+  CHECK_EQ(1, counter.NumberOfWeakCalls());
+
+  // Check that the string is still alive.
+  {
+    HandleScope scope(iso);
+    i::MaybeHandle<i::String> magic_string =
+        i::StringTable::LookupStringIfExists(
+            i_iso,
+            v8::Utils::OpenHandle(*String::NewFromUtf8(iso, "magic cookie")));
+    magic_string.Check();
+  }
+}
+
+
 // TODO(mstarzinger): This should be a THREADED_TEST but causes failures
 // on the buildbots, so was made non-threaded for the time being.
 TEST(ApiObjectGroupsCycleForScavenger) {
@@ -4266,13 +4588,14 @@
 
 TEST(TryCatchCustomException) {
   LocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
   v8::TryCatch try_catch;
   CompileRun("function CustomError() { this.a = 'b'; }"
              "(function f() { throw new CustomError(); })();");
   CHECK(try_catch.HasCaught());
-  CHECK(try_catch.Exception()->ToObject()->
-            Get(v8_str("a"))->Equals(v8_str("b")));
+  CHECK(try_catch.Exception()->ToObject(isolate)->Get(v8_str("a"))->Equals(
+      v8_str("b")));
 }
 
 
@@ -4766,49 +5089,51 @@
 
 THREADED_TEST(ConversionNumber) {
   LocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
   // Very large number.
   CompileRun("var obj = Math.pow(2,32) * 1237;");
   Local<Value> obj = env->Global()->Get(v8_str("obj"));
-  CHECK_EQ(5312874545152.0, obj->ToNumber()->Value());
-  CHECK_EQ(0, obj->ToInt32()->Value());
-  CHECK(0u == obj->ToUint32()->Value());  // NOLINT - no CHECK_EQ for unsigned.
+  CHECK_EQ(5312874545152.0, obj->ToNumber(isolate)->Value());
+  CHECK_EQ(0, obj->ToInt32(isolate)->Value());
+  CHECK(0u ==
+        obj->ToUint32(isolate)->Value());  // NOLINT - no CHECK_EQ for unsigned.
   // Large number.
   CompileRun("var obj = -1234567890123;");
   obj = env->Global()->Get(v8_str("obj"));
-  CHECK_EQ(-1234567890123.0, obj->ToNumber()->Value());
-  CHECK_EQ(-1912276171, obj->ToInt32()->Value());
-  CHECK(2382691125u == obj->ToUint32()->Value());  // NOLINT
+  CHECK_EQ(-1234567890123.0, obj->ToNumber(isolate)->Value());
+  CHECK_EQ(-1912276171, obj->ToInt32(isolate)->Value());
+  CHECK(2382691125u == obj->ToUint32(isolate)->Value());  // NOLINT
   // Small positive integer.
   CompileRun("var obj = 42;");
   obj = env->Global()->Get(v8_str("obj"));
-  CHECK_EQ(42.0, obj->ToNumber()->Value());
-  CHECK_EQ(42, obj->ToInt32()->Value());
-  CHECK(42u == obj->ToUint32()->Value());  // NOLINT
+  CHECK_EQ(42.0, obj->ToNumber(isolate)->Value());
+  CHECK_EQ(42, obj->ToInt32(isolate)->Value());
+  CHECK(42u == obj->ToUint32(isolate)->Value());  // NOLINT
   // Negative integer.
   CompileRun("var obj = -37;");
   obj = env->Global()->Get(v8_str("obj"));
-  CHECK_EQ(-37.0, obj->ToNumber()->Value());
-  CHECK_EQ(-37, obj->ToInt32()->Value());
-  CHECK(4294967259u == obj->ToUint32()->Value());  // NOLINT
+  CHECK_EQ(-37.0, obj->ToNumber(isolate)->Value());
+  CHECK_EQ(-37, obj->ToInt32(isolate)->Value());
+  CHECK(4294967259u == obj->ToUint32(isolate)->Value());  // NOLINT
   // Positive non-int32 integer.
   CompileRun("var obj = 0x81234567;");
   obj = env->Global()->Get(v8_str("obj"));
-  CHECK_EQ(2166572391.0, obj->ToNumber()->Value());
-  CHECK_EQ(-2128394905, obj->ToInt32()->Value());
-  CHECK(2166572391u == obj->ToUint32()->Value());  // NOLINT
+  CHECK_EQ(2166572391.0, obj->ToNumber(isolate)->Value());
+  CHECK_EQ(-2128394905, obj->ToInt32(isolate)->Value());
+  CHECK(2166572391u == obj->ToUint32(isolate)->Value());  // NOLINT
   // Fraction.
   CompileRun("var obj = 42.3;");
   obj = env->Global()->Get(v8_str("obj"));
-  CHECK_EQ(42.3, obj->ToNumber()->Value());
-  CHECK_EQ(42, obj->ToInt32()->Value());
-  CHECK(42u == obj->ToUint32()->Value());  // NOLINT
+  CHECK_EQ(42.3, obj->ToNumber(isolate)->Value());
+  CHECK_EQ(42, obj->ToInt32(isolate)->Value());
+  CHECK(42u == obj->ToUint32(isolate)->Value());  // NOLINT
   // Large negative fraction.
   CompileRun("var obj = -5726623061.75;");
   obj = env->Global()->Get(v8_str("obj"));
-  CHECK_EQ(-5726623061.75, obj->ToNumber()->Value());
-  CHECK_EQ(-1431655765, obj->ToInt32()->Value());
-  CHECK(2863311531u == obj->ToUint32()->Value());  // NOLINT
+  CHECK_EQ(-5726623061.75, obj->ToNumber(isolate)->Value());
+  CHECK_EQ(-1431655765, obj->ToInt32(isolate)->Value());
+  CHECK(2863311531u == obj->ToUint32(isolate)->Value());  // NOLINT
 }
 
 
@@ -4873,29 +5198,29 @@
     "var obj = new TestClass();");
   Local<Value> obj = env->Global()->Get(v8_str("obj"));
 
-  v8::TryCatch try_catch;
+  v8::TryCatch try_catch(isolate);
 
-  Local<Value> to_string_result = obj->ToString();
+  Local<Value> to_string_result = obj->ToString(isolate);
   CHECK(to_string_result.IsEmpty());
   CheckUncle(&try_catch);
 
-  Local<Value> to_number_result = obj->ToNumber();
+  Local<Value> to_number_result = obj->ToNumber(isolate);
   CHECK(to_number_result.IsEmpty());
   CheckUncle(&try_catch);
 
-  Local<Value> to_integer_result = obj->ToInteger();
+  Local<Value> to_integer_result = obj->ToInteger(isolate);
   CHECK(to_integer_result.IsEmpty());
   CheckUncle(&try_catch);
 
-  Local<Value> to_uint32_result = obj->ToUint32();
+  Local<Value> to_uint32_result = obj->ToUint32(isolate);
   CHECK(to_uint32_result.IsEmpty());
   CheckUncle(&try_catch);
 
-  Local<Value> to_int32_result = obj->ToInt32();
+  Local<Value> to_int32_result = obj->ToInt32(isolate);
   CHECK(to_int32_result.IsEmpty());
   CheckUncle(&try_catch);
 
-  Local<Value> to_object_result = v8::Undefined(isolate)->ToObject();
+  Local<Value> to_object_result = v8::Undefined(isolate)->ToObject(isolate);
   CHECK(to_object_result.IsEmpty());
   CHECK(try_catch.HasCaught());
   try_catch.Reset();
@@ -4931,7 +5256,7 @@
   }
   v8::HandleScope scope(args.GetIsolate());
   v8::TryCatch try_catch;
-  Local<Value> result = CompileRun(args[0]->ToString());
+  Local<Value> result = CompileRun(args[0]->ToString(args.GetIsolate()));
   CHECK(!try_catch.HasCaught() || result.IsEmpty());
   args.GetReturnValue().Set(try_catch.HasCaught());
 }
@@ -5980,7 +6305,7 @@
 }
 
 
-static void XPropertyGetter(Local<String> property,
+static void XPropertyGetter(Local<Name> property,
                             const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   CHECK(info.Data()->IsUndefined());
@@ -5992,7 +6317,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(XPropertyGetter);
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter));
   LocalContext context;
   context->Global()->Set(v8_str("obj"), templ->NewInstance());
   Local<Script> script = v8_compile("obj.x");
@@ -6007,7 +6332,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(XPropertyGetter);
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter));
   LocalContext context;
   // Create an object with a named interceptor.
   context->Global()->Set(v8_str("interceptor_obj"), templ->NewInstance());
@@ -6041,7 +6366,7 @@
 
   context1->Enter();
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(XPropertyGetter);
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter));
   // Create an object with a named interceptor.
   v8::Local<v8::Object> object = templ->NewInstance();
   context1->Global()->Set(v8_str("interceptor_obj"), object);
@@ -6076,8 +6401,7 @@
 
 
 static void SetXOnPrototypeGetter(
-    Local<String> property,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
   // Set x on the prototype object and do not handle the get request.
   v8::Handle<v8::Value> proto = info.Holder()->GetPrototype();
   proto.As<v8::Object>()->Set(v8_str("x"),
@@ -6094,7 +6418,8 @@
       v8::FunctionTemplate::New(isolate);
   Local<v8::ObjectTemplate> instance_template
       = function_template->InstanceTemplate();
-  instance_template->SetNamedPropertyHandler(SetXOnPrototypeGetter);
+  instance_template->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(SetXOnPrototypeGetter));
   LocalContext context;
   context->Global()->Set(v8_str("F"), function_template->GetFunction());
   // Create an instance of F and introduce a map transition for x.
@@ -6130,8 +6455,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(IndexedPropertyGetter,
-                                   IndexedPropertySetter);
+  templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      IndexedPropertyGetter, IndexedPropertySetter));
   LocalContext context;
   context->Global()->Set(v8_str("obj"), templ->NewInstance());
   Local<Script> getter_script = v8_compile(
@@ -6196,11 +6521,9 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(UnboxedDoubleIndexedPropertyGetter,
-                                   UnboxedDoubleIndexedPropertySetter,
-                                   0,
-                                   0,
-                                   UnboxedDoubleIndexedPropertyEnumerator);
+  templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      UnboxedDoubleIndexedPropertyGetter, UnboxedDoubleIndexedPropertySetter, 0,
+      0, UnboxedDoubleIndexedPropertyEnumerator));
   LocalContext context;
   context->Global()->Set(v8_str("obj"), templ->NewInstance());
   // When obj is created, force it to be Stored in a FastDoubleArray.
@@ -6210,7 +6533,7 @@
       "for (x in obj) {key_count++;};"
       "obj;");
   Local<Value> result = create_unboxed_double_script->Run();
-  CHECK(result->ToObject()->HasRealIndexedProperty(2000));
+  CHECK(result->ToObject(isolate)->HasRealIndexedProperty(2000));
   Local<Script> key_count_check = v8_compile("key_count;");
   result = key_count_check->Run();
   CHECK_EQ(v8_num(40013), result);
@@ -6252,11 +6575,9 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(SloppyIndexedPropertyGetter,
-                                   0,
-                                   0,
-                                   0,
-                                   SloppyArgsIndexedPropertyEnumerator);
+  templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      SloppyIndexedPropertyGetter, 0, 0, 0,
+      SloppyArgsIndexedPropertyEnumerator));
   LocalContext context;
   context->Global()->Set(v8_str("obj"), templ->NewInstance());
   Local<Script> create_args_script = v8_compile(
@@ -6278,7 +6599,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+  templ->SetHandler(
+      v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
 
   LocalContext context;
   context->Global()->Set(v8_str("obj"), templ->NewInstance());
@@ -6300,7 +6622,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+  templ->SetHandler(
+      v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
 
   LocalContext context;
   context->Global()->Set(v8_str("obj"), templ->NewInstance());
@@ -6324,7 +6647,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+  templ->SetHandler(
+      v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
 
   LocalContext context;
   Local<v8::Object> obj = templ->NewInstance();
@@ -6352,7 +6676,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+  templ->SetHandler(
+      v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
 
   LocalContext context;
   Local<v8::Object> obj = templ->NewInstance();
@@ -6390,7 +6715,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+  templ->SetHandler(
+      v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
 
   LocalContext context;
   Local<v8::Object> obj = templ->NewInstance();
@@ -6414,7 +6740,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+  templ->SetHandler(
+      v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
 
   LocalContext context;
   Local<v8::Object> obj = templ->NewInstance();
@@ -6454,7 +6781,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+  templ->SetHandler(
+      v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
 
   LocalContext context;
   Local<v8::Object> obj = templ->NewInstance();
@@ -6484,7 +6812,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+  templ->SetHandler(
+      v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
 
   LocalContext context;
   Local<v8::Object> obj = templ->NewInstance();
@@ -6515,7 +6844,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+  templ->SetHandler(
+      v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
 
   LocalContext context;
   Local<v8::Object> obj = templ->NewInstance();
@@ -6546,7 +6876,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+  templ->SetHandler(
+      v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
 
   LocalContext context;
   Local<v8::Object> obj = templ->NewInstance();
@@ -7371,14 +7702,175 @@
 };
 
 
-static void DisposeAndSetFlag(
-    const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
-  data.GetParameter()->handle.Reset();
+static void SetFlag(const v8::PhantomCallbackData<FlagAndPersistent>& data) {
   data.GetParameter()->flag = true;
 }
 
 
+static void IndependentWeakHandle(bool global_gc, bool interlinked) {
+  v8::Isolate* iso = CcTest::isolate();
+  v8::HandleScope scope(iso);
+  v8::Handle<Context> context = Context::New(iso);
+  Context::Scope context_scope(context);
+
+  FlagAndPersistent object_a, object_b;
+
+  intptr_t big_heap_size;
+
+  {
+    v8::HandleScope handle_scope(iso);
+    Local<Object> a(v8::Object::New(iso));
+    Local<Object> b(v8::Object::New(iso));
+    object_a.handle.Reset(iso, a);
+    object_b.handle.Reset(iso, b);
+    if (interlinked) {
+      a->Set(v8_str("x"), b);
+      b->Set(v8_str("x"), a);
+    }
+    if (global_gc) {
+      CcTest::heap()->CollectAllGarbage(TestHeap::Heap::kNoGCFlags);
+    } else {
+      CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+    }
+    // We are relying on this creating a big flag array and reserving the space
+    // up front.
+    v8::Handle<Value> big_array = CompileRun("new Array(50000)");
+    a->Set(v8_str("y"), big_array);
+    big_heap_size = CcTest::heap()->SizeOfObjects();
+  }
+
+  object_a.flag = false;
+  object_b.flag = false;
+  object_a.handle.SetPhantom(&object_a, &SetFlag);
+  object_b.handle.SetPhantom(&object_b, &SetFlag);
+  CHECK(!object_b.handle.IsIndependent());
+  object_a.handle.MarkIndependent();
+  object_b.handle.MarkIndependent();
+  CHECK(object_b.handle.IsIndependent());
+  if (global_gc) {
+    CcTest::heap()->CollectAllGarbage(TestHeap::Heap::kNoGCFlags);
+  } else {
+    CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+  }
+  // A single GC should be enough to reclaim the memory, since we are using
+  // phantom handles.
+  CHECK_LT(CcTest::heap()->SizeOfObjects(), big_heap_size - 200000);
+  CHECK(object_a.flag);
+  CHECK(object_b.flag);
+}
+
+
 THREADED_TEST(IndependentWeakHandle) {
+  IndependentWeakHandle(false, false);
+  IndependentWeakHandle(false, true);
+  IndependentWeakHandle(true, false);
+  IndependentWeakHandle(true, true);
+}
+
+
+class Trivial {
+ public:
+  explicit Trivial(int x) : x_(x) {}
+
+  int x() { return x_; }
+  void set_x(int x) { x_ = x; }
+
+ private:
+  int x_;
+};
+
+
+class Trivial2 {
+ public:
+  Trivial2(int x, int y) : y_(y), x_(x) {}
+
+  int x() { return x_; }
+  void set_x(int x) { x_ = x; }
+
+  int y() { return y_; }
+  void set_y(int y) { y_ = y; }
+
+ private:
+  int y_;
+  int x_;
+};
+
+
+void CheckInternalFields(
+    const v8::InternalFieldsCallbackData<Trivial, Trivial2>& data) {
+  Trivial* t1 = data.GetInternalField1();
+  Trivial2* t2 = data.GetInternalField2();
+  CHECK_EQ(42, t1->x());
+  CHECK_EQ(103, t2->x());
+  t1->set_x(1729);
+  t2->set_x(33550336);
+}
+
+
+void InternalFieldCallback(bool global_gc) {
+  LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+
+  Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
+  Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate();
+  Trivial* t1;
+  Trivial2* t2;
+  instance_templ->SetInternalFieldCount(2);
+  {
+    v8::HandleScope scope(isolate);
+    Local<v8::Object> obj = templ->GetFunction()->NewInstance();
+    v8::Persistent<v8::Object> handle(isolate, obj);
+    CHECK_EQ(2, obj->InternalFieldCount());
+    CHECK(obj->GetInternalField(0)->IsUndefined());
+    t1 = new Trivial(42);
+    t2 = new Trivial2(103, 9);
+
+    obj->SetAlignedPointerInInternalField(0, t1);
+    t1 = reinterpret_cast<Trivial*>(obj->GetAlignedPointerFromInternalField(0));
+    CHECK_EQ(42, t1->x());
+
+    obj->SetAlignedPointerInInternalField(1, t2);
+    t2 =
+        reinterpret_cast<Trivial2*>(obj->GetAlignedPointerFromInternalField(1));
+    CHECK_EQ(103, t2->x());
+
+    handle.SetPhantom(CheckInternalFields, 0, 1);
+    if (!global_gc) {
+      handle.MarkIndependent();
+    }
+  }
+  if (global_gc) {
+    CcTest::heap()->CollectAllGarbage(TestHeap::Heap::kNoGCFlags);
+  } else {
+    CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+  }
+
+  CHECK_EQ(1729, t1->x());
+  CHECK_EQ(33550336, t2->x());
+
+  delete t1;
+  delete t2;
+}
+
+
+THREADED_TEST(InternalFieldCallback) {
+  InternalFieldCallback(false);
+  InternalFieldCallback(true);
+}
+
+
+static void ResetUseValueAndSetFlag(
+    const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
+  // Blink will reset the handle, and then use the other handle, so they
+  // can't use the same backing slot.
+  data.GetParameter()->handle.Reset();
+  data.GetValue()->IsBoolean();  // Make sure the handle still works.
+  data.GetParameter()->flag = true;
+}
+
+
+static void ResetWeakHandle(bool global_gc) {
   v8::Isolate* iso = CcTest::isolate();
   v8::HandleScope scope(iso);
   v8::Handle<Context> context = Context::New(iso);
@@ -7388,24 +7880,44 @@
 
   {
     v8::HandleScope handle_scope(iso);
-    object_a.handle.Reset(iso, v8::Object::New(iso));
-    object_b.handle.Reset(iso, v8::Object::New(iso));
+    Local<Object> a(v8::Object::New(iso));
+    Local<Object> b(v8::Object::New(iso));
+    object_a.handle.Reset(iso, a);
+    object_b.handle.Reset(iso, b);
+    if (global_gc) {
+      CcTest::heap()->CollectAllGarbage(
+          TestHeap::Heap::kAbortIncrementalMarkingMask);
+    } else {
+      CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+    }
   }
 
   object_a.flag = false;
   object_b.flag = false;
-  object_a.handle.SetWeak(&object_a, &DisposeAndSetFlag);
-  object_b.handle.SetWeak(&object_b, &DisposeAndSetFlag);
-  CHECK(!object_b.handle.IsIndependent());
-  object_a.handle.MarkIndependent();
-  object_b.handle.MarkIndependent();
-  CHECK(object_b.handle.IsIndependent());
-  CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+  object_a.handle.SetWeak(&object_a, &ResetUseValueAndSetFlag);
+  object_b.handle.SetWeak(&object_b, &ResetUseValueAndSetFlag);
+  if (!global_gc) {
+    object_a.handle.MarkIndependent();
+    object_b.handle.MarkIndependent();
+    CHECK(object_b.handle.IsIndependent());
+  }
+  if (global_gc) {
+    CcTest::heap()->CollectAllGarbage(
+        TestHeap::Heap::kAbortIncrementalMarkingMask);
+  } else {
+    CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+  }
   CHECK(object_a.flag);
   CHECK(object_b.flag);
 }
 
 
+THREADED_TEST(ResetWeakHandle) {
+  ResetWeakHandle(false);
+  ResetWeakHandle(true);
+}
+
+
 static void InvokeScavenge() {
   CcTest::heap()->CollectGarbage(i::NEW_SPACE);
 }
@@ -7533,9 +8045,8 @@
 }
 
 
-static void NoBlockGetterX(Local<String> name,
-                           const v8::PropertyCallbackInfo<v8::Value>&) {
-}
+static void NoBlockGetterX(Local<Name> name,
+                           const v8::PropertyCallbackInfo<v8::Value>&) {}
 
 
 static void NoBlockGetterI(uint32_t index,
@@ -7543,7 +8054,7 @@
 }
 
 
-static void PDeleter(Local<String> name,
+static void PDeleter(Local<Name> name,
                      const v8::PropertyCallbackInfo<v8::Boolean>& info) {
   if (!name->Equals(v8_str("foo"))) {
     return;  // not intercepted
@@ -7567,8 +8078,10 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
-  obj->SetNamedPropertyHandler(NoBlockGetterX, NULL, NULL, PDeleter, NULL);
-  obj->SetIndexedPropertyHandler(NoBlockGetterI, NULL, NULL, IDeleter, NULL);
+  obj->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX, NULL,
+                                                        NULL, PDeleter, NULL));
+  obj->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      NoBlockGetterI, NULL, NULL, IDeleter, NULL));
   LocalContext context;
   context->Global()->Set(v8_str("k"), obj->NewInstance());
   CompileRun(
@@ -7590,7 +8103,7 @@
 }
 
 
-static void GetK(Local<String> name,
+static void GetK(Local<Name> name,
                  const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   if (name->Equals(v8_str("foo")) ||
@@ -7631,8 +8144,10 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
-  obj->SetNamedPropertyHandler(GetK, NULL, NULL, NULL, NamedEnum);
-  obj->SetIndexedPropertyHandler(IndexedGetK, NULL, NULL, NULL, IndexedEnum);
+  obj->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(GetK, NULL, NULL, NULL, NamedEnum));
+  obj->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      IndexedGetK, NULL, NULL, NULL, IndexedEnum));
   LocalContext context;
   context->Global()->Set(v8_str("k"), obj->NewInstance());
   v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun(
@@ -7724,7 +8239,7 @@
 }
 
 
-static void PGetter2(Local<String> name,
+static void PGetter2(Local<Name> name,
                      const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   p_getter_count2++;
@@ -7761,7 +8276,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
-  obj->SetNamedPropertyHandler(PGetter2);
+  obj->SetHandler(v8::NamedPropertyHandlerConfiguration(PGetter2));
   p_getter_count2 = 0;
   RunHolderTest(obj);
   CHECK_EQ(40, p_getter_count2);
@@ -8419,6 +8934,85 @@
 }
 
 
+static void ThrowV8Exception(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  ApiTestFuzzer::Fuzz();
+  v8::Handle<String> foo = v8_str("foo");
+  v8::Handle<String> message = v8_str("message");
+  v8::Handle<Value> error = v8::Exception::Error(foo);
+  CHECK(error->IsObject());
+  CHECK(error.As<v8::Object>()->Get(message)->Equals(foo));
+  info.GetIsolate()->ThrowException(error);
+  info.GetReturnValue().SetUndefined();
+}
+
+
+THREADED_TEST(ExceptionCreateMessage) {
+  LocalContext context;
+  v8::HandleScope scope(context->GetIsolate());
+  v8::Handle<String> foo_str = v8_str("foo");
+  v8::Handle<String> message_str = v8_str("message");
+
+  v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
+
+  Local<v8::FunctionTemplate> fun =
+      v8::FunctionTemplate::New(context->GetIsolate(), ThrowV8Exception);
+  v8::Local<v8::Object> global = context->Global();
+  global->Set(v8_str("throwV8Exception"), fun->GetFunction());
+
+  TryCatch try_catch;
+  CompileRun(
+      "function f1() {\n"
+      "  throwV8Exception();\n"
+      "};\n"
+      "f1();");
+  CHECK(try_catch.HasCaught());
+
+  v8::Handle<v8::Value> error = try_catch.Exception();
+  CHECK(error->IsObject());
+  CHECK(error.As<v8::Object>()->Get(message_str)->Equals(foo_str));
+
+  v8::Handle<v8::Message> message = v8::Exception::CreateMessage(error);
+  CHECK(!message.IsEmpty());
+  CHECK_EQ(2, message->GetLineNumber());
+  CHECK_EQ(2, message->GetStartColumn());
+
+  v8::Handle<v8::StackTrace> stackTrace = message->GetStackTrace();
+  CHECK(!stackTrace.IsEmpty());
+  CHECK_EQ(2, stackTrace->GetFrameCount());
+
+  stackTrace = v8::Exception::GetStackTrace(error);
+  CHECK(!stackTrace.IsEmpty());
+  CHECK_EQ(2, stackTrace->GetFrameCount());
+
+  v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
+
+  // Now check message location when SetCaptureStackTraceForUncaughtExceptions
+  // is false.
+  try_catch.Reset();
+
+  CompileRun(
+      "function f2() {\n"
+      "  return throwV8Exception();\n"
+      "};\n"
+      "f2();");
+  CHECK(try_catch.HasCaught());
+
+  error = try_catch.Exception();
+  CHECK(error->IsObject());
+  CHECK(error.As<v8::Object>()->Get(message_str)->Equals(foo_str));
+
+  message = v8::Exception::CreateMessage(error);
+  CHECK(!message.IsEmpty());
+  CHECK_EQ(2, message->GetLineNumber());
+  CHECK_EQ(9, message->GetStartColumn());
+
+  // Should be empty stack trace.
+  stackTrace = message->GetStackTrace();
+  CHECK(stackTrace.IsEmpty());
+  CHECK(v8::Exception::GetStackTrace(error).IsEmpty());
+}
+
+
 static void YGetter(Local<String> name,
                     const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
@@ -8532,6 +9126,33 @@
   v8::V8::RemoveMessageListeners(ApiUncaughtExceptionTestListener);
 }
 
+
+TEST(ApiUncaughtExceptionInObjectObserve) {
+  v8::internal::FLAG_stack_size = 150;
+  report_count = 0;
+  LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+  v8::V8::AddMessageListener(ApiUncaughtExceptionTestListener);
+  CompileRun(
+      "var obj = {};"
+      "var observe_count = 0;"
+      "function observer1() { ++observe_count; };"
+      "function observer2() { ++observe_count; };"
+      "function observer_throws() { throw new Error(); };"
+      "function stack_overflow() { return (function f(x) { f(x+1); })(0); };"
+      "Object.observe(obj, observer_throws.bind());"
+      "Object.observe(obj, observer1);"
+      "Object.observe(obj, stack_overflow);"
+      "Object.observe(obj, observer2);"
+      "Object.observe(obj, observer_throws.bind());"
+      "obj.foo = 'bar';");
+  CHECK_EQ(3, report_count);
+  ExpectInt32("observe_count", 2);
+  v8::V8::RemoveMessageListeners(ApiUncaughtExceptionTestListener);
+}
+
+
 static const char* script_resource_name = "ExceptionInNativeScript.js";
 static void ExceptionInNativeScriptTestListener(v8::Handle<v8::Message> message,
                                                 v8::Handle<Value>) {
@@ -8603,7 +9224,7 @@
 
 void CEvaluate(const v8::FunctionCallbackInfo<v8::Value>& args) {
   v8::HandleScope scope(args.GetIsolate());
-  CompileRun(args[0]->ToString());
+  CompileRun(args[0]->ToString(args.GetIsolate()));
 }
 
 
@@ -8877,11 +9498,11 @@
   CHECK(indexed_security_check_with_gc_called);
 
   named_security_check_with_gc_called = false;
-  CHECK(CompileRun("obj.foo")->ToString()->Equals(v8_str("1001")));
+  CHECK(CompileRun("obj.foo")->ToString(isolate)->Equals(v8_str("1001")));
   CHECK(named_security_check_with_gc_called);
 
   indexed_security_check_with_gc_called = false;
-  CHECK(CompileRun("obj[0]")->ToString()->Equals(v8_str("1002")));
+  CHECK(CompileRun("obj[0]")->ToString(isolate)->Equals(v8_str("1002")));
   CHECK(indexed_security_check_with_gc_called);
 }
 
@@ -9609,20 +10230,52 @@
   LocalContext env;
   env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance());
 
-  v8::TryCatch try_catch;
-  CompileRun(
-      "function f() { return super.hasOwnProperty; };"
-      "var m = f.toMethod(prohibited);"
-      "m();");
-  CHECK(try_catch.HasCaught());
+  {
+    v8::TryCatch try_catch;
+    CompileRun(
+        "function f() { return super.hasOwnProperty; };"
+        "var m = f.toMethod(prohibited);"
+        "m();");
+    CHECK(try_catch.HasCaught());
+  }
+
+  {
+    v8::TryCatch try_catch;
+    CompileRun(
+        "function f() { return super[42]; };"
+        "var m = f.toMethod(prohibited);"
+        "m();");
+    CHECK(try_catch.HasCaught());
+  }
+
+  {
+    v8::TryCatch try_catch;
+    CompileRun(
+        "function f() { super.hasOwnProperty = function () {}; };"
+        "var m = f.toMethod(prohibited);"
+        "m();");
+    CHECK(try_catch.HasCaught());
+  }
+
+  {
+    v8::TryCatch try_catch;
+    CompileRun(
+        "Object.defineProperty(Object.prototype, 'x', { set : function(){}});"
+        "function f() { "
+        "     'use strict';"
+        "     super.x = function () {}; "
+        "};"
+        "var m = f.toMethod(prohibited);"
+        "m();");
+    CHECK(try_catch.HasCaught());
+  }
 }
 
 
 static void IndexedPropertyEnumerator(
     const v8::PropertyCallbackInfo<v8::Array>& info) {
-  v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2);
+  v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 1);
   result->Set(0, v8::Integer::New(info.GetIsolate(), 7));
-  result->Set(1, v8::Object::New(info.GetIsolate()));
   info.GetReturnValue().Set(result);
 }
 
@@ -9631,7 +10284,7 @@
     const v8::PropertyCallbackInfo<v8::Array>& info) {
   v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2);
   result->Set(0, v8_str("x"));
-  result->Set(1, v8::Object::New(info.GetIsolate()));
+  result->Set(1, v8::Symbol::GetIterator(info.GetIsolate()));
   info.GetReturnValue().Set(result);
 }
 
@@ -9644,10 +10297,10 @@
 
   obj_template->Set(v8_str("7"), v8::Integer::New(CcTest::isolate(), 7));
   obj_template->Set(v8_str("x"), v8::Integer::New(CcTest::isolate(), 42));
-  obj_template->SetIndexedPropertyHandler(NULL, NULL, NULL, NULL,
-                                          IndexedPropertyEnumerator);
-  obj_template->SetNamedPropertyHandler(NULL, NULL, NULL, NULL,
-                                        NamedPropertyEnumerator);
+  obj_template->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      NULL, NULL, NULL, NULL, IndexedPropertyEnumerator));
+  obj_template->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      NULL, NULL, NULL, NULL, NamedPropertyEnumerator));
 
   LocalContext context;
   v8::Handle<v8::Object> global = context->Global();
@@ -9657,13 +10310,26 @@
       CompileRun("Object.getOwnPropertyNames(object)");
   CHECK(result->IsArray());
   v8::Handle<v8::Array> result_array = v8::Handle<v8::Array>::Cast(result);
-  CHECK_EQ(3, result_array->Length());
+  CHECK_EQ(2, result_array->Length());
   CHECK(result_array->Get(0)->IsString());
   CHECK(result_array->Get(1)->IsString());
-  CHECK(result_array->Get(2)->IsString());
   CHECK_EQ(v8_str("7"), result_array->Get(0));
-  CHECK_EQ(v8_str("[object Object]"), result_array->Get(1));
-  CHECK_EQ(v8_str("x"), result_array->Get(2));
+  CHECK_EQ(v8_str("x"), result_array->Get(1));
+
+  result = CompileRun("var ret = []; for (var k in object) ret.push(k); ret");
+  CHECK(result->IsArray());
+  result_array = v8::Handle<v8::Array>::Cast(result);
+  CHECK_EQ(2, result_array->Length());
+  CHECK(result_array->Get(0)->IsString());
+  CHECK(result_array->Get(1)->IsString());
+  CHECK_EQ(v8_str("7"), result_array->Get(0));
+  CHECK_EQ(v8_str("x"), result_array->Get(1));
+
+  result = CompileRun("Object.getOwnPropertySymbols(object)");
+  CHECK(result->IsArray());
+  result_array = v8::Handle<v8::Array>::Cast(result);
+  CHECK_EQ(1, result_array->Length());
+  CHECK_EQ(result_array->Get(0), v8::Symbol::GetIterator(isolate));
 }
 
 
@@ -9937,15 +10603,13 @@
 
 
 static void AccessControlNamedGetter(
-    Local<String>,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name>, const v8::PropertyCallbackInfo<v8::Value>& info) {
   info.GetReturnValue().Set(42);
 }
 
 
 static void AccessControlNamedSetter(
-    Local<String>,
-    Local<Value> value,
+    Local<Name>, Local<Value> value,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   info.GetReturnValue().Set(value);
 }
@@ -9984,10 +10648,10 @@
       v8::ObjectTemplate::New(isolate);
   object_template->SetAccessCheckCallbacks(NamedAccessCounter,
                                            IndexedAccessCounter);
-  object_template->SetNamedPropertyHandler(AccessControlNamedGetter,
-                                           AccessControlNamedSetter);
-  object_template->SetIndexedPropertyHandler(AccessControlIndexedGetter,
-                                             AccessControlIndexedSetter);
+  object_template->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      AccessControlNamedGetter, AccessControlNamedSetter));
+  object_template->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      AccessControlIndexedGetter, AccessControlIndexedSetter));
   Local<v8::Object> object = object_template->NewInstance();
 
   v8::HandleScope scope1(isolate);
@@ -10069,8 +10733,7 @@
 
 
 static void GlobalObjectInstancePropertiesGet(
-    Local<String> key,
-    const v8::PropertyCallbackInfo<v8::Value>&) {
+    Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>&) {
   ApiTestFuzzer::Fuzz();
 }
 
@@ -10082,8 +10745,8 @@
   Local<Value> global_object;
 
   Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
-  t->InstanceTemplate()->SetNamedPropertyHandler(
-      GlobalObjectInstancePropertiesGet);
+  t->InstanceTemplate()->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(GlobalObjectInstancePropertiesGet));
   Local<ObjectTemplate> instance_template = t->InstanceTemplate();
   instance_template->Set(v8_str("x"), v8_num(42));
   instance_template->Set(v8_str("f"),
@@ -10207,9 +10870,8 @@
 }
 
 
-static void ShadowNamedGet(Local<String> key,
-                           const v8::PropertyCallbackInfo<v8::Value>&) {
-}
+static void ShadowNamedGet(Local<Name> key,
+                           const v8::PropertyCallbackInfo<v8::Value>&) {}
 
 
 THREADED_TEST(ShadowObject) {
@@ -10221,8 +10883,10 @@
   LocalContext context(NULL, global_template);
 
   Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
-  t->InstanceTemplate()->SetNamedPropertyHandler(ShadowNamedGet);
-  t->InstanceTemplate()->SetIndexedPropertyHandler(ShadowIndexedGet);
+  t->InstanceTemplate()->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(ShadowNamedGet));
+  t->InstanceTemplate()->SetHandler(
+      v8::IndexedPropertyHandlerConfiguration(ShadowIndexedGet));
   Local<ObjectTemplate> proto = t->PrototypeTemplate();
   Local<ObjectTemplate> instance = t->InstanceTemplate();
 
@@ -10709,7 +11373,7 @@
         "(function() { var o = new obj('tipli'); return o.a; })()");
     CHECK(!try_catch.HasCaught());
     CHECK(value->IsString());
-    String::Utf8Value string_value1(value->ToString());
+    String::Utf8Value string_value1(value->ToString(isolate));
     CHECK_EQ("tipli", *string_value1);
 
     Local<Value> args2[] = { v8_str("tipli") };
@@ -10719,7 +11383,7 @@
     value = object2->Get(v8_str("a"));
     CHECK(!try_catch.HasCaught());
     CHECK(value->IsString());
-    String::Utf8Value string_value2(value->ToString());
+    String::Utf8Value string_value2(value->ToString(isolate));
     CHECK_EQ("tipli", *string_value2);
 
     // Call the Object's constructor with a Boolean.
@@ -10982,8 +11646,7 @@
 
 
 // Test that calling eval in a context which has been detached from
-// its global throws an exception.  This behavior is consistent with
-// other JavaScript implementations.
+// its global proxy works.
 THREADED_TEST(EvalInDetachedGlobal) {
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
@@ -11011,8 +11674,7 @@
   context0->DetachGlobal();
   v8::TryCatch catcher;
   x_value = CompileRun("fun('x')");
-  CHECK(x_value.IsEmpty());
-  CHECK(catcher.HasCaught());
+  CHECK_EQ(42, x_value->Int32Value());
   context1->Exit();
 }
 
@@ -11330,8 +11992,7 @@
 
 
 static void InterceptorHasOwnPropertyGetter(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
 }
 
@@ -11342,7 +12003,8 @@
   v8::HandleScope scope(isolate);
   Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate);
   Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate();
-  instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetter);
+  instance_templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorHasOwnPropertyGetter));
   Local<Function> function = fun_templ->GetFunction();
   context->Global()->Set(v8_str("constructor"), function);
   v8::Handle<Value> value = CompileRun(
@@ -11361,8 +12023,7 @@
 
 
 static void InterceptorHasOwnPropertyGetterGC(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
 }
@@ -11374,7 +12035,8 @@
   v8::HandleScope scope(isolate);
   Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate);
   Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate();
-  instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC);
+  instance_templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorHasOwnPropertyGetterGC));
   Local<Function> function = fun_templ->GetFunction();
   context->Global()->Set(v8_str("constructor"), function);
   // Let's first make some stuff so we can be sure to get a good GC.
@@ -11398,18 +12060,14 @@
 }
 
 
-typedef void (*NamedPropertyGetter)(
-    Local<String> property,
-    const v8::PropertyCallbackInfo<v8::Value>& info);
-
-
-static void CheckInterceptorLoadIC(NamedPropertyGetter getter,
-                                   const char* source,
-                                   int expected) {
+static void CheckInterceptorLoadIC(
+    v8::GenericNamedPropertyGetterCallback getter, const char* source,
+    int expected) {
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(getter, 0, 0, 0, 0, v8_str("data"));
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(getter, 0, 0, 0, 0,
+                                                          v8_str("data")));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   v8::Handle<Value> value = CompileRun(source);
@@ -11418,8 +12076,7 @@
 
 
 static void InterceptorLoadICGetter(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   v8::Isolate* isolate = CcTest::isolate();
   CHECK_EQ(isolate, info.GetIsolate());
@@ -11445,8 +12102,7 @@
 // (those cases are special cased to get better performance).
 
 static void InterceptorLoadXICGetter(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   info.GetReturnValue().Set(
       v8_str("x")->Equals(name) ?
@@ -11561,8 +12217,7 @@
 
 static int interceptor_load_not_handled_calls = 0;
 static void InterceptorLoadNotHandled(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ++interceptor_load_not_handled_calls;
 }
 
@@ -11623,7 +12278,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+  templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
   templ->SetAccessor(v8_str("y"), Return239Callback);
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
@@ -11653,7 +12309,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
-  templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+  templ_o->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
   v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate);
   templ_p->SetAccessor(v8_str("y"), Return239Callback);
 
@@ -11687,7 +12344,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+  templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
   templ->SetAccessor(v8_str("y"), Return239Callback);
 
   LocalContext context;
@@ -11716,7 +12374,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
-  templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+  templ_o->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
   v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate);
   templ_p->SetAccessor(v8_str("y"), Return239Callback);
 
@@ -11745,7 +12404,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
-  templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+  templ_o->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
   v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate);
   templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis);
 
@@ -11778,7 +12438,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
-  templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+  templ_o->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
   v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate);
   templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis);
 
@@ -11804,8 +12465,7 @@
 
 
 static void InterceptorLoadICGetter0(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   CHECK(v8_str("x")->Equals(name));
   info.GetReturnValue().Set(v8::Integer::New(info.GetIsolate(), 0));
@@ -11820,8 +12480,7 @@
 
 
 static void InterceptorStoreICSetter(
-    Local<String> key,
-    Local<Value> value,
+    Local<Name> key, Local<Value> value,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   CHECK(v8_str("x")->Equals(key));
   CHECK_EQ(42, value->Int32Value());
@@ -11834,9 +12493,9 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(InterceptorLoadICGetter,
-                                 InterceptorStoreICSetter,
-                                 0, 0, 0, v8_str("data"));
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      InterceptorLoadICGetter, InterceptorStoreICSetter, 0, 0, 0,
+      v8_str("data")));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   CompileRun(
@@ -11850,7 +12509,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+  templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   v8::Handle<Value> value = CompileRun(
@@ -11869,8 +12529,7 @@
 v8::Handle<Value> call_ic_function3;
 
 static void InterceptorCallICGetter(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   CHECK(v8_str("x")->Equals(name));
   info.GetReturnValue().Set(call_ic_function);
@@ -11882,7 +12541,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(InterceptorCallICGetter);
+  templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   call_ic_function =
@@ -11902,7 +12562,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(NoBlockGetterX);
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   v8::Handle<Value> value = CompileRun(
@@ -11917,8 +12577,7 @@
 
 static v8::Handle<Value> call_ic_function4;
 static void InterceptorCallICGetter4(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   CHECK(v8_str("x")->Equals(name));
   info.GetReturnValue().Set(call_ic_function4);
@@ -11932,7 +12591,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(InterceptorCallICGetter4);
+  templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter4));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   call_ic_function4 =
@@ -11953,7 +12613,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(NoBlockGetterX);
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   v8::Handle<Value> value = CompileRun(
@@ -11981,7 +12641,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(NoBlockGetterX);
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   v8::Handle<Value> value = CompileRun(
@@ -11998,8 +12658,7 @@
 
 static v8::Handle<Value> call_ic_function5;
 static void InterceptorCallICGetter5(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   if (v8_str("x")->Equals(name))
     info.GetReturnValue().Set(call_ic_function5);
@@ -12013,7 +12672,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(InterceptorCallICGetter5);
+  templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter5));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   call_ic_function5 =
@@ -12032,8 +12692,7 @@
 
 static v8::Handle<Value> call_ic_function6;
 static void InterceptorCallICGetter6(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   if (v8_str("x")->Equals(name))
     info.GetReturnValue().Set(call_ic_function6);
@@ -12047,7 +12706,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(InterceptorCallICGetter6);
+  templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter6));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   call_ic_function6 =
@@ -12078,7 +12738,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(NoBlockGetterX);
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   v8::Handle<Value> value = CompileRun(
@@ -12109,7 +12769,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(NoBlockGetterX);
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   v8::Handle<Value> value = CompileRun(
@@ -12135,7 +12795,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
-  templ_o->SetNamedPropertyHandler(NoBlockGetterX);
+  templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
 
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ_o->NewInstance());
@@ -12160,8 +12820,7 @@
 }
 
 static void InterceptorCallICFastApi(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   CheckReturnValue(info, FUNCTION_ADDR(InterceptorCallICFastApi));
   int* call_count =
@@ -12350,9 +13009,9 @@
   v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
   proto_templ->Set(v8_str("method"), method_templ);
   v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
-  templ->SetNamedPropertyHandler(
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
       InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
-      v8::External::New(isolate, &interceptor_call_count));
+      v8::External::New(isolate, &interceptor_call_count)));
   LocalContext context;
   v8::Handle<v8::Function> fun = fun_templ->GetFunction();
   GenerateSomeGarbage();
@@ -12380,9 +13039,9 @@
   proto_templ->Set(v8_str("method"), method_templ);
   fun_templ->SetHiddenPrototype(true);
   v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
-  templ->SetNamedPropertyHandler(
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
       InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
-      v8::External::New(isolate, &interceptor_call_count));
+      v8::External::New(isolate, &interceptor_call_count)));
   LocalContext context;
   v8::Handle<v8::Function> fun = fun_templ->GetFunction();
   GenerateSomeGarbage();
@@ -12413,9 +13072,9 @@
   proto_templ->Set(v8_str("method"), method_templ);
   fun_templ->SetHiddenPrototype(true);
   v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
-  templ->SetNamedPropertyHandler(
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
       InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
-      v8::External::New(isolate, &interceptor_call_count));
+      v8::External::New(isolate, &interceptor_call_count)));
   LocalContext context;
   v8::Handle<v8::Function> fun = fun_templ->GetFunction();
   GenerateSomeGarbage();
@@ -12452,9 +13111,9 @@
   proto_templ->Set(v8_str("method"), method_templ);
   fun_templ->SetHiddenPrototype(true);
   v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
-  templ->SetNamedPropertyHandler(
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
       InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
-      v8::External::New(isolate, &interceptor_call_count));
+      v8::External::New(isolate, &interceptor_call_count)));
   LocalContext context;
   v8::Handle<v8::Function> fun = fun_templ->GetFunction();
   GenerateSomeGarbage();
@@ -12491,9 +13150,9 @@
   proto_templ->Set(v8_str("method"), method_templ);
   fun_templ->SetHiddenPrototype(true);
   v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
-  templ->SetNamedPropertyHandler(
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
       InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
-      v8::External::New(isolate, &interceptor_call_count));
+      v8::External::New(isolate, &interceptor_call_count)));
   LocalContext context;
   v8::Handle<v8::Function> fun = fun_templ->GetFunction();
   GenerateSomeGarbage();
@@ -12515,7 +13174,7 @@
   CHECK(try_catch.HasCaught());
   // TODO(verwaest): Adjust message.
   CHECK_EQ(v8_str("TypeError: undefined is not a function"),
-           try_catch.Exception()->ToString());
+           try_catch.Exception()->ToString(isolate));
   CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
   CHECK_GE(interceptor_call_count, 50);
 }
@@ -12534,9 +13193,9 @@
   proto_templ->Set(v8_str("method"), method_templ);
   fun_templ->SetHiddenPrototype(true);
   v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
-  templ->SetNamedPropertyHandler(
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
       InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
-      v8::External::New(isolate, &interceptor_call_count));
+      v8::External::New(isolate, &interceptor_call_count)));
   LocalContext context;
   v8::Handle<v8::Function> fun = fun_templ->GetFunction();
   GenerateSomeGarbage();
@@ -12557,7 +13216,7 @@
       "}");
   CHECK(try_catch.HasCaught());
   CHECK_EQ(v8_str("TypeError: Illegal invocation"),
-           try_catch.Exception()->ToString());
+           try_catch.Exception()->ToString(isolate));
   CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
   CHECK_GE(interceptor_call_count, 50);
 }
@@ -12690,7 +13349,7 @@
   CHECK(try_catch.HasCaught());
   // TODO(verwaest): Adjust message.
   CHECK_EQ(v8_str("TypeError: undefined is not a function"),
-           try_catch.Exception()->ToString());
+           try_catch.Exception()->ToString(isolate));
   CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
 }
 
@@ -12728,7 +13387,7 @@
       "}");
   CHECK(try_catch.HasCaught());
   CHECK_EQ(v8_str("TypeError: Illegal invocation"),
-           try_catch.Exception()->ToString());
+           try_catch.Exception()->ToString(isolate));
   CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
 }
 
@@ -12736,8 +13395,7 @@
 v8::Handle<Value> keyed_call_ic_function;
 
 static void InterceptorKeyedCallICGetter(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   if (v8_str("x")->Equals(name)) {
     info.GetReturnValue().Set(keyed_call_ic_function);
@@ -12751,7 +13409,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(NoBlockGetterX);
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   CompileRun(
@@ -12776,7 +13434,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(InterceptorKeyedCallICGetter);
+  templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorKeyedCallICGetter));
   LocalContext context;
   context->Global()->Set(v8_str("proto1"), templ->NewInstance());
   keyed_call_ic_function =
@@ -12804,7 +13463,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(NoBlockGetterX);
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ->NewInstance());
   CompileRun(
@@ -12830,7 +13489,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
-  templ_o->SetNamedPropertyHandler(NoBlockGetterX);
+  templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ_o->NewInstance());
 
@@ -12856,7 +13515,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
-  templ_o->SetNamedPropertyHandler(NoBlockGetterX);
+  templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
   LocalContext context;
   context->Global()->Set(v8_str("proto"), templ_o->NewInstance());
 
@@ -12879,7 +13538,7 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
-  templ_o->SetNamedPropertyHandler(NoBlockGetterX);
+  templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
   LocalContext context;
   context->Global()->Set(v8_str("o"), templ_o->NewInstance());
 
@@ -12900,8 +13559,7 @@
 static int interceptor_call_count = 0;
 
 static void InterceptorICRefErrorGetter(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   if (v8_str("x")->Equals(name) && interceptor_call_count++ < 20) {
     info.GetReturnValue().Set(call_ic_function2);
@@ -12916,7 +13574,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(InterceptorICRefErrorGetter);
+  templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorICRefErrorGetter));
   LocalContext context(0, templ, v8::Handle<Value>());
   call_ic_function2 = v8_compile("function h(x) { return x; }; h")->Run();
   v8::Handle<Value> value = CompileRun(
@@ -12944,8 +13603,7 @@
 static int interceptor_ic_exception_get_count = 0;
 
 static void InterceptorICExceptionGetter(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   if (v8_str("x")->Equals(name) && ++interceptor_ic_exception_get_count < 20) {
     info.GetReturnValue().Set(call_ic_function3);
@@ -12964,7 +13622,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(InterceptorICExceptionGetter);
+  templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorICExceptionGetter));
   LocalContext context(0, templ, v8::Handle<Value>());
   call_ic_function3 = v8_compile("function h(x) { return x; }; h")->Run();
   v8::Handle<Value> value = CompileRun(
@@ -12992,9 +13651,8 @@
 static int interceptor_ic_exception_set_count = 0;
 
 static void InterceptorICExceptionSetter(
-      Local<String> key,
-      Local<Value> value,
-      const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> key, Local<Value> value,
+    const v8::PropertyCallbackInfo<v8::Value>& info) {
   ApiTestFuzzer::Fuzz();
   if (++interceptor_ic_exception_set_count > 20) {
     info.GetIsolate()->ThrowException(v8_num(42));
@@ -13009,7 +13667,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(0, InterceptorICExceptionSetter);
+  templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(0, InterceptorICExceptionSetter));
   LocalContext context(0, templ, v8::Handle<Value>());
   v8::Handle<Value> value = CompileRun(
     "function f() {"
@@ -13028,8 +13687,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(
-      static_cast<v8::NamedPropertyGetterCallback>(0));
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      static_cast<v8::GenericNamedPropertyGetterCallback>(0)));
   LocalContext context;
   templ->Set(CcTest::isolate(), "x", v8_num(42));
   v8::Handle<v8::Object> obj = templ->NewInstance();
@@ -13045,8 +13704,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(
-      static_cast<v8::IndexedPropertyGetterCallback>(0));
+  templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      static_cast<v8::IndexedPropertyGetterCallback>(0)));
   LocalContext context;
   templ->Set(CcTest::isolate(), "42", v8_num(42));
   v8::Handle<v8::Object> obj = templ->NewInstance();
@@ -13061,7 +13720,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
-  templ->InstanceTemplate()->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+  templ->InstanceTemplate()->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
   LocalContext env;
   env->Global()->Set(v8_str("obj"),
                      templ->GetFunction()->NewInstance());
@@ -13315,7 +13975,7 @@
 
   // Normal ToString call should call replaced Object.prototype.toString
   Local<v8::Object> instance = templ->GetFunction()->NewInstance();
-  Local<String> value = instance->ToString();
+  Local<String> value = instance->ToString(isolate);
   CHECK(value->IsString() && value->Equals(customized_tostring));
 
   // ObjectProtoToString should not call replace toString function.
@@ -13333,9 +13993,127 @@
 }
 
 
-THREADED_TEST(ObjectGetConstructorName) {
+TEST(ObjectProtoToStringES6) {
+  // TODO(dslomov, caitp): merge into ObjectProtoToString test once shipped.
+  i::FLAG_harmony_tostring = true;
   LocalContext context;
-  v8::HandleScope scope(context->GetIsolate());
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope scope(isolate);
+  Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
+  templ->SetClassName(v8_str("MyClass"));
+
+  Local<String> customized_tostring = v8_str("customized toString");
+
+  // Replace Object.prototype.toString
+  CompileRun(
+      "Object.prototype.toString = function() {"
+      "  return 'customized toString';"
+      "}");
+
+  // Normal ToString call should call replaced Object.prototype.toString
+  Local<v8::Object> instance = templ->GetFunction()->NewInstance();
+  Local<String> value = instance->ToString(isolate);
+  CHECK(value->IsString() && value->Equals(customized_tostring));
+
+  // ObjectProtoToString should not call replace toString function.
+  value = instance->ObjectProtoToString();
+  CHECK(value->IsString() && value->Equals(v8_str("[object MyClass]")));
+
+  // Check global
+  value = context->Global()->ObjectProtoToString();
+  CHECK(value->IsString() && value->Equals(v8_str("[object global]")));
+
+  // Check ordinary object
+  Local<Value> object = CompileRun("new Object()");
+  value = object.As<v8::Object>()->ObjectProtoToString();
+  CHECK(value->IsString() && value->Equals(v8_str("[object Object]")));
+
+  // Check that ES6 semantics using @@toStringTag work
+  Local<v8::Symbol> toStringTag = v8::Symbol::GetToStringTag(isolate);
+
+#define TEST_TOSTRINGTAG(type, tag, expected)                \
+  do {                                                       \
+    object = CompileRun("new " #type "()");                  \
+    object.As<v8::Object>()->Set(toStringTag, v8_str(#tag)); \
+    value = object.As<v8::Object>()->ObjectProtoToString();  \
+    CHECK(value->IsString() &&                               \
+          value->Equals(v8_str("[object " #expected "]")));  \
+  } while (0)
+
+  TEST_TOSTRINGTAG(Array, Object, Object);
+  TEST_TOSTRINGTAG(Object, Arguments, ~Arguments);
+  TEST_TOSTRINGTAG(Object, Array, ~Array);
+  TEST_TOSTRINGTAG(Object, Boolean, ~Boolean);
+  TEST_TOSTRINGTAG(Object, Date, ~Date);
+  TEST_TOSTRINGTAG(Object, Error, ~Error);
+  TEST_TOSTRINGTAG(Object, Function, ~Function);
+  TEST_TOSTRINGTAG(Object, Number, ~Number);
+  TEST_TOSTRINGTAG(Object, RegExp, ~RegExp);
+  TEST_TOSTRINGTAG(Object, String, ~String);
+  TEST_TOSTRINGTAG(Object, Foo, Foo);
+
+#undef TEST_TOSTRINGTAG
+
+  // @@toStringTag getter throws
+  Local<Value> obj = v8::Object::New(isolate);
+  obj.As<v8::Object>()->SetAccessor(toStringTag, ThrowingSymbolAccessorGetter);
+  {
+    TryCatch try_catch;
+    value = obj.As<v8::Object>()->ObjectProtoToString();
+    CHECK(value.IsEmpty());
+    CHECK(try_catch.HasCaught());
+  }
+
+  // @@toStringTag getter does not throw
+  obj = v8::Object::New(isolate);
+  obj.As<v8::Object>()->SetAccessor(
+      toStringTag, SymbolAccessorGetterReturnsDefault, 0, v8_str("Test"));
+  {
+    TryCatch try_catch;
+    value = obj.As<v8::Object>()->ObjectProtoToString();
+    CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
+    CHECK(!try_catch.HasCaught());
+  }
+
+  // JS @@toStringTag value
+  obj = CompileRun("obj = {}; obj[Symbol.toStringTag] = 'Test'; obj");
+  {
+    TryCatch try_catch;
+    value = obj.As<v8::Object>()->ObjectProtoToString();
+    CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
+    CHECK(!try_catch.HasCaught());
+  }
+
+  // JS @@toStringTag getter throws
+  obj = CompileRun(
+      "obj = {}; Object.defineProperty(obj, Symbol.toStringTag, {"
+      "  get: function() { throw 'Test'; }"
+      "}); obj");
+  {
+    TryCatch try_catch;
+    value = obj.As<v8::Object>()->ObjectProtoToString();
+    CHECK(value.IsEmpty());
+    CHECK(try_catch.HasCaught());
+  }
+
+  // JS @@toStringTag getter does not throw
+  obj = CompileRun(
+      "obj = {}; Object.defineProperty(obj, Symbol.toStringTag, {"
+      "  get: function() { return 'Test'; }"
+      "}); obj");
+  {
+    TryCatch try_catch;
+    value = obj.As<v8::Object>()->ObjectProtoToString();
+    CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
+    CHECK(!try_catch.HasCaught());
+  }
+}
+
+
+THREADED_TEST(ObjectGetConstructorName) {
+  v8::Isolate* isolate = CcTest::isolate();
+  LocalContext context;
+  v8::HandleScope scope(isolate);
   v8_compile("function Parent() {};"
              "function Child() {};"
              "Child.prototype = new Parent();"
@@ -13345,16 +14123,17 @@
              "var x = new outer.inner();")->Run();
 
   Local<v8::Value> p = context->Global()->Get(v8_str("p"));
-  CHECK(p->IsObject() && p->ToObject()->GetConstructorName()->Equals(
-      v8_str("Parent")));
+  CHECK(p->IsObject() &&
+        p->ToObject(isolate)->GetConstructorName()->Equals(v8_str("Parent")));
 
   Local<v8::Value> c = context->Global()->Get(v8_str("c"));
-  CHECK(c->IsObject() && c->ToObject()->GetConstructorName()->Equals(
-      v8_str("Child")));
+  CHECK(c->IsObject() &&
+        c->ToObject(isolate)->GetConstructorName()->Equals(v8_str("Child")));
 
   Local<v8::Value> x = context->Global()->Get(v8_str("x"));
-  CHECK(x->IsObject() && x->ToObject()->GetConstructorName()->Equals(
-      v8_str("outer.inner")));
+  CHECK(x->IsObject() &&
+        x->ToObject(isolate)->GetConstructorName()->Equals(
+            v8_str("outer.inner")));
 }
 
 
@@ -13902,7 +14681,7 @@
   v8::Local<Context> env = Context::New(isolate);
   env->Enter();
   v8::Handle<Value> value = NestedScope(env);
-  v8::Handle<String> str(value->ToString());
+  v8::Handle<String> str(value->ToString(isolate));
   CHECK(!str.IsEmpty());
   env->Exit();
 }
@@ -14744,7 +15523,7 @@
   v8::Handle<v8::Array> props = val.As<v8::Object>()->GetPropertyNames();
   CHECK_EQ(0, props->Length());
   for (uint32_t i = 0; i < props->Length(); i++) {
-    printf("p[%d]\n", i);
+    printf("p[%u]\n", i);
   }
 }
 
@@ -15291,7 +16070,7 @@
 #ifndef V8_INTERPRETED_REGEXP
 
 struct RegExpInterruptionData {
-  int loop_count;
+  v8::base::Atomic32 loop_count;
   UC16VectorResource* string_resource;
   v8::Persistent<v8::String> string;
 } regexp_interruption_data;
@@ -15303,9 +16082,10 @@
       : Thread(Options("TimeoutThread")), isolate_(isolate) {}
 
   virtual void Run() {
-    for (regexp_interruption_data.loop_count = 0;
-         regexp_interruption_data.loop_count < 7;
-         regexp_interruption_data.loop_count++) {
+    for (v8::base::NoBarrier_Store(&regexp_interruption_data.loop_count, 0);
+         v8::base::NoBarrier_Load(&regexp_interruption_data.loop_count) < 7;
+         v8::base::NoBarrier_AtomicIncrement(
+             &regexp_interruption_data.loop_count, 1)) {
       v8::base::OS::Sleep(50);  // Wait a bit before requesting GC.
       reinterpret_cast<i::Isolate*>(isolate_)->stack_guard()->RequestGC();
     }
@@ -15319,7 +16099,9 @@
 
 
 void RunBeforeGC(v8::GCType type, v8::GCCallbackFlags flags) {
-  if (regexp_interruption_data.loop_count != 2) return;
+  if (v8::base::NoBarrier_Load(&regexp_interruption_data.loop_count) != 2) {
+    return;
+  }
   v8::HandleScope scope(CcTest::isolate());
   v8::Local<v8::String> string = v8::Local<v8::String>::New(
       CcTest::isolate(), regexp_interruption_data.string);
@@ -15407,9 +16189,14 @@
   force_set_set_count++;
 }
 
+static void ForceSetInterceptGetter(
+    v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+  CHECK(name->IsString());
+  ForceSetGetter(Local<String>::Cast(name), info);
+}
+
 static void ForceSetInterceptSetter(
-    v8::Local<v8::String> name,
-    v8::Local<v8::Value> value,
+    v8::Local<v8::Name> name, v8::Local<v8::Value> value,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   force_set_set_count++;
   info.GetReturnValue().SetUndefined();
@@ -15469,7 +16256,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(ForceSetGetter, ForceSetInterceptSetter);
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      ForceSetInterceptGetter, ForceSetInterceptSetter));
   LocalContext context(NULL, templ);
   v8::Handle<v8::Object> global = context->Global();
 
@@ -15537,7 +16325,7 @@
 
 
 static void ForceDeleteDeleter(
-    v8::Local<v8::String> name,
+    v8::Local<v8::Name> name,
     const v8::PropertyCallbackInfo<v8::Boolean>& info) {
   force_delete_interceptor_count++;
   if (pass_on_delete) return;
@@ -15552,7 +16340,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(0, 0, 0, ForceDeleteDeleter);
+  templ->SetHandler(
+      v8::NamedPropertyHandlerConfiguration(0, 0, 0, ForceDeleteDeleter));
   LocalContext context(NULL, templ);
   v8::Handle<v8::Object> global = context->Global();
 
@@ -16195,8 +16984,8 @@
   }
   v8::Handle<v8::ObjectTemplate> templ =
       v8::ObjectTemplate::New(context->GetIsolate());
-  templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter,
-                                   NotHandledIndexedPropertySetter);
+  templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      NotHandledIndexedPropertyGetter, NotHandledIndexedPropertySetter));
   v8::Handle<v8::Object> obj = templ->NewInstance();
   obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount);
   context->Global()->Set(v8_str("pixels"), obj);
@@ -17335,6 +18124,7 @@
 static void StackTraceForUncaughtExceptionListener(
     v8::Handle<v8::Message> message,
     v8::Handle<Value>) {
+  report_count++;
   v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace();
   CHECK_EQ(2, stack_trace->GetFrameCount());
   checkStackFrame("origin", "foo", 2, 3, false, false,
@@ -17365,6 +18155,38 @@
   Function::Cast(*trouble)->Call(global, 0, NULL);
   v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
   v8::V8::RemoveMessageListeners(StackTraceForUncaughtExceptionListener);
+  CHECK_EQ(1, report_count);
+}
+
+
+TEST(GetStackTraceForUncaughtExceptionFromSimpleStackTrace) {
+  report_count = 0;
+  LocalContext env;
+  v8::HandleScope scope(env->GetIsolate());
+
+  // Create an Error object first.
+  CompileRunWithOrigin(
+      "function foo() {\n"
+      "e=new Error('err');\n"
+      "};\n"
+      "function bar() {\n"
+      "  foo();\n"
+      "};\n"
+      "var e;",
+      "origin");
+  v8::Local<v8::Object> global = env->Global();
+  Local<Value> trouble = global->Get(v8_str("bar"));
+  CHECK(trouble->IsFunction());
+  Function::Cast(*trouble)->Call(global, 0, NULL);
+
+  // Enable capturing detailed stack trace late, and throw the exception.
+  // The detailed stack trace should be extracted from the simple stack.
+  v8::V8::AddMessageListener(StackTraceForUncaughtExceptionListener);
+  v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
+  CompileRunWithOrigin("throw e", "origin");
+  v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
+  v8::V8::RemoveMessageListeners(StackTraceForUncaughtExceptionListener);
+  CHECK_EQ(1, report_count);
 }
 
 
@@ -17519,6 +18341,343 @@
 }
 
 
+v8::PromiseRejectEvent reject_event = v8::kPromiseRejectWithNoHandler;
+int promise_reject_counter = 0;
+int promise_revoke_counter = 0;
+int promise_reject_line_number = -1;
+int promise_reject_frame_count = -1;
+
+void PromiseRejectCallback(v8::PromiseRejectMessage message) {
+  if (message.GetEvent() == v8::kPromiseRejectWithNoHandler) {
+    promise_reject_counter++;
+    CcTest::global()->Set(v8_str("rejected"), message.GetPromise());
+    CcTest::global()->Set(v8_str("value"), message.GetValue());
+    v8::Handle<v8::StackTrace> stack_trace =
+        v8::Exception::CreateMessage(message.GetValue())->GetStackTrace();
+    if (!stack_trace.IsEmpty()) {
+      promise_reject_frame_count = stack_trace->GetFrameCount();
+      if (promise_reject_frame_count > 0) {
+        CHECK(stack_trace->GetFrame(0)->GetScriptName()->Equals(v8_str("pro")));
+        promise_reject_line_number = stack_trace->GetFrame(0)->GetLineNumber();
+      } else {
+        promise_reject_line_number = -1;
+      }
+    }
+  } else {
+    promise_revoke_counter++;
+    CcTest::global()->Set(v8_str("revoked"), message.GetPromise());
+    CHECK(message.GetValue().IsEmpty());
+  }
+}
+
+
+v8::Handle<v8::Promise> GetPromise(const char* name) {
+  return v8::Handle<v8::Promise>::Cast(CcTest::global()->Get(v8_str(name)));
+}
+
+
+v8::Handle<v8::Value> RejectValue() {
+  return CcTest::global()->Get(v8_str("value"));
+}
+
+
+void ResetPromiseStates() {
+  promise_reject_counter = 0;
+  promise_revoke_counter = 0;
+  promise_reject_line_number = -1;
+  promise_reject_frame_count = -1;
+  CcTest::global()->Set(v8_str("rejected"), v8_str(""));
+  CcTest::global()->Set(v8_str("value"), v8_str(""));
+  CcTest::global()->Set(v8_str("revoked"), v8_str(""));
+}
+
+
+TEST(PromiseRejectCallback) {
+  LocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+
+  isolate->SetPromiseRejectCallback(PromiseRejectCallback);
+
+  ResetPromiseStates();
+
+  // Create promise p0.
+  CompileRun(
+      "var reject;            \n"
+      "var p0 = new Promise(  \n"
+      "  function(res, rej) { \n"
+      "    reject = rej;      \n"
+      "  }                    \n"
+      ");                     \n");
+  CHECK(!GetPromise("p0")->HasHandler());
+  CHECK_EQ(0, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+
+  // Add resolve handler (and default reject handler) to p0.
+  CompileRun("var p1 = p0.then(function(){});");
+  CHECK(GetPromise("p0")->HasHandler());
+  CHECK(!GetPromise("p1")->HasHandler());
+  CHECK_EQ(0, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+
+  // Reject p0.
+  CompileRun("reject('ppp');");
+  CHECK(GetPromise("p0")->HasHandler());
+  CHECK(!GetPromise("p1")->HasHandler());
+  CHECK_EQ(1, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+  CHECK_EQ(v8::kPromiseRejectWithNoHandler, reject_event);
+  CHECK(GetPromise("rejected")->Equals(GetPromise("p1")));
+  CHECK(RejectValue()->Equals(v8_str("ppp")));
+
+  // Reject p0 again. Callback is not triggered again.
+  CompileRun("reject();");
+  CHECK(GetPromise("p0")->HasHandler());
+  CHECK(!GetPromise("p1")->HasHandler());
+  CHECK_EQ(1, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+
+  // Add resolve handler to p1.
+  CompileRun("var p2 = p1.then(function(){});");
+  CHECK(GetPromise("p0")->HasHandler());
+  CHECK(GetPromise("p1")->HasHandler());
+  CHECK(!GetPromise("p2")->HasHandler());
+  CHECK_EQ(2, promise_reject_counter);
+  CHECK_EQ(1, promise_revoke_counter);
+  CHECK(GetPromise("rejected")->Equals(GetPromise("p2")));
+  CHECK(RejectValue()->Equals(v8_str("ppp")));
+  CHECK(GetPromise("revoked")->Equals(GetPromise("p1")));
+
+  ResetPromiseStates();
+
+  // Create promise q0.
+  CompileRun(
+      "var q0 = new Promise(  \n"
+      "  function(res, rej) { \n"
+      "    reject = rej;      \n"
+      "  }                    \n"
+      ");                     \n");
+  CHECK(!GetPromise("q0")->HasHandler());
+  CHECK_EQ(0, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+
+  // Add reject handler to q0.
+  CompileRun("var q1 = q0.catch(function() {});");
+  CHECK(GetPromise("q0")->HasHandler());
+  CHECK(!GetPromise("q1")->HasHandler());
+  CHECK_EQ(0, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+
+  // Reject q0.
+  CompileRun("reject('qq')");
+  CHECK(GetPromise("q0")->HasHandler());
+  CHECK(!GetPromise("q1")->HasHandler());
+  CHECK_EQ(0, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+
+  // Add a new reject handler, which rejects by returning Promise.reject().
+  // The returned promise q_ triggers a reject callback at first, only to
+  // revoke it when returning it causes q2 to be rejected.
+  CompileRun(
+      "var q_;"
+      "var q2 = q0.catch(               \n"
+      "   function() {                  \n"
+      "     q_ = Promise.reject('qqq'); \n"
+      "     return q_;                  \n"
+      "   }                             \n"
+      ");                               \n");
+  CHECK(GetPromise("q0")->HasHandler());
+  CHECK(!GetPromise("q1")->HasHandler());
+  CHECK(!GetPromise("q2")->HasHandler());
+  CHECK(GetPromise("q_")->HasHandler());
+  CHECK_EQ(2, promise_reject_counter);
+  CHECK_EQ(1, promise_revoke_counter);
+  CHECK(GetPromise("rejected")->Equals(GetPromise("q2")));
+  CHECK(GetPromise("revoked")->Equals(GetPromise("q_")));
+  CHECK(RejectValue()->Equals(v8_str("qqq")));
+
+  // Add a reject handler to the resolved q1, which rejects by throwing.
+  CompileRun(
+      "var q3 = q1.then(  \n"
+      "   function() {    \n"
+      "     throw 'qqqq'; \n"
+      "   }               \n"
+      ");                 \n");
+  CHECK(GetPromise("q0")->HasHandler());
+  CHECK(GetPromise("q1")->HasHandler());
+  CHECK(!GetPromise("q2")->HasHandler());
+  CHECK(!GetPromise("q3")->HasHandler());
+  CHECK_EQ(3, promise_reject_counter);
+  CHECK_EQ(1, promise_revoke_counter);
+  CHECK(GetPromise("rejected")->Equals(GetPromise("q3")));
+  CHECK(RejectValue()->Equals(v8_str("qqqq")));
+
+  ResetPromiseStates();
+
+  // Create promise r0, which has three handlers, two of which handle rejects.
+  CompileRun(
+      "var r0 = new Promise(             \n"
+      "  function(res, rej) {            \n"
+      "    reject = rej;                 \n"
+      "  }                               \n"
+      ");                                \n"
+      "var r1 = r0.catch(function() {}); \n"
+      "var r2 = r0.then(function() {});  \n"
+      "var r3 = r0.then(function() {},   \n"
+      "                 function() {});  \n");
+  CHECK(GetPromise("r0")->HasHandler());
+  CHECK(!GetPromise("r1")->HasHandler());
+  CHECK(!GetPromise("r2")->HasHandler());
+  CHECK(!GetPromise("r3")->HasHandler());
+  CHECK_EQ(0, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+
+  // Reject r0.
+  CompileRun("reject('rrr')");
+  CHECK(GetPromise("r0")->HasHandler());
+  CHECK(!GetPromise("r1")->HasHandler());
+  CHECK(!GetPromise("r2")->HasHandler());
+  CHECK(!GetPromise("r3")->HasHandler());
+  CHECK_EQ(1, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+  CHECK(GetPromise("rejected")->Equals(GetPromise("r2")));
+  CHECK(RejectValue()->Equals(v8_str("rrr")));
+
+  // Add reject handler to r2.
+  CompileRun("var r4 = r2.catch(function() {});");
+  CHECK(GetPromise("r0")->HasHandler());
+  CHECK(!GetPromise("r1")->HasHandler());
+  CHECK(GetPromise("r2")->HasHandler());
+  CHECK(!GetPromise("r3")->HasHandler());
+  CHECK(!GetPromise("r4")->HasHandler());
+  CHECK_EQ(1, promise_reject_counter);
+  CHECK_EQ(1, promise_revoke_counter);
+  CHECK(GetPromise("revoked")->Equals(GetPromise("r2")));
+  CHECK(RejectValue()->Equals(v8_str("rrr")));
+
+  // Add reject handlers to r4.
+  CompileRun("var r5 = r4.then(function() {}, function() {});");
+  CHECK(GetPromise("r0")->HasHandler());
+  CHECK(!GetPromise("r1")->HasHandler());
+  CHECK(GetPromise("r2")->HasHandler());
+  CHECK(!GetPromise("r3")->HasHandler());
+  CHECK(GetPromise("r4")->HasHandler());
+  CHECK(!GetPromise("r5")->HasHandler());
+  CHECK_EQ(1, promise_reject_counter);
+  CHECK_EQ(1, promise_revoke_counter);
+
+  ResetPromiseStates();
+
+  // Create promise s0, which has three handlers, none of which handle rejects.
+  CompileRun(
+      "var s0 = new Promise(            \n"
+      "  function(res, rej) {           \n"
+      "    reject = rej;                \n"
+      "  }                              \n"
+      ");                               \n"
+      "var s1 = s0.then(function() {}); \n"
+      "var s2 = s0.then(function() {}); \n"
+      "var s3 = s0.then(function() {}); \n");
+  CHECK(GetPromise("s0")->HasHandler());
+  CHECK(!GetPromise("s1")->HasHandler());
+  CHECK(!GetPromise("s2")->HasHandler());
+  CHECK(!GetPromise("s3")->HasHandler());
+  CHECK_EQ(0, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+
+  // Reject s0.
+  CompileRun("reject('sss')");
+  CHECK(GetPromise("s0")->HasHandler());
+  CHECK(!GetPromise("s1")->HasHandler());
+  CHECK(!GetPromise("s2")->HasHandler());
+  CHECK(!GetPromise("s3")->HasHandler());
+  CHECK_EQ(3, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+  CHECK(RejectValue()->Equals(v8_str("sss")));
+
+  // Test stack frames.
+  V8::SetCaptureStackTraceForUncaughtExceptions(true);
+
+  ResetPromiseStates();
+
+  // Create promise t0, which is rejected in the constructor with an error.
+  CompileRunWithOrigin(
+      "var t0 = new Promise(  \n"
+      "  function(res, rej) { \n"
+      "    reference_error;   \n"
+      "  }                    \n"
+      ");                     \n",
+      "pro", 0, 0);
+  CHECK(!GetPromise("t0")->HasHandler());
+  CHECK_EQ(1, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+  CHECK_EQ(2, promise_reject_frame_count);
+  CHECK_EQ(3, promise_reject_line_number);
+
+  ResetPromiseStates();
+
+  // Create promise u0 and chain u1 to it, which is rejected via throw.
+  CompileRunWithOrigin(
+      "var u0 = Promise.resolve();        \n"
+      "var u1 = u0.then(                  \n"
+      "           function() {            \n"
+      "             (function() {         \n"
+      "                throw new Error(); \n"
+      "              })();                \n"
+      "           }                       \n"
+      "         );                        \n",
+      "pro", 0, 0);
+  CHECK(GetPromise("u0")->HasHandler());
+  CHECK(!GetPromise("u1")->HasHandler());
+  CHECK_EQ(1, promise_reject_counter);
+  CHECK_EQ(0, promise_revoke_counter);
+  CHECK_EQ(2, promise_reject_frame_count);
+  CHECK_EQ(5, promise_reject_line_number);
+
+  // Throw in u3, which handles u1's rejection.
+  CompileRunWithOrigin(
+      "function f() {                \n"
+      "  return (function() {        \n"
+      "    return new Error();       \n"
+      "  })();                       \n"
+      "}                             \n"
+      "var u2 = Promise.reject(f()); \n"
+      "var u3 = u1.catch(            \n"
+      "           function() {       \n"
+      "             return u2;       \n"
+      "           }                  \n"
+      "         );                   \n",
+      "pro", 0, 0);
+  CHECK(GetPromise("u0")->HasHandler());
+  CHECK(GetPromise("u1")->HasHandler());
+  CHECK(GetPromise("u2")->HasHandler());
+  CHECK(!GetPromise("u3")->HasHandler());
+  CHECK_EQ(3, promise_reject_counter);
+  CHECK_EQ(2, promise_revoke_counter);
+  CHECK_EQ(3, promise_reject_frame_count);
+  CHECK_EQ(3, promise_reject_line_number);
+
+  ResetPromiseStates();
+
+  // Create promise rejected promise v0, which is incorrectly handled by v1
+  // via chaining cycle.
+  CompileRunWithOrigin(
+      "var v0 = Promise.reject(); \n"
+      "var v1 = v0.catch(         \n"
+      "           function() {    \n"
+      "             return v1;    \n"
+      "           }               \n"
+      "         );                \n",
+      "pro", 0, 0);
+  CHECK(GetPromise("v0")->HasHandler());
+  CHECK(!GetPromise("v1")->HasHandler());
+  CHECK_EQ(2, promise_reject_counter);
+  CHECK_EQ(1, promise_revoke_counter);
+  CHECK_EQ(0, promise_reject_frame_count);
+  CHECK_EQ(-1, promise_reject_line_number);
+}
+
+
 void AnalyzeStackOfEvalWithSourceURL(
     const v8::FunctionCallbackInfo<v8::Value>& args) {
   v8::HandleScope scope(args.GetIsolate());
@@ -17835,40 +18994,6 @@
 }
 
 
-TEST(Regress2107) {
-  const intptr_t MB = 1024 * 1024;
-  const int kIdlePauseInMs = 1000;
-  LocalContext env;
-  v8::Isolate* isolate = env->GetIsolate();
-  v8::HandleScope scope(env->GetIsolate());
-  intptr_t initial_size = CcTest::heap()->SizeOfObjects();
-  // Send idle notification to start a round of incremental GCs.
-  env->GetIsolate()->IdleNotification(kIdlePauseInMs);
-  // Emulate 7 page reloads.
-  for (int i = 0; i < 7; i++) {
-    {
-      v8::HandleScope inner_scope(env->GetIsolate());
-      v8::Local<v8::Context> ctx = v8::Context::New(isolate);
-      ctx->Enter();
-      CreateGarbageInOldSpace();
-      ctx->Exit();
-    }
-    env->GetIsolate()->ContextDisposedNotification();
-    env->GetIsolate()->IdleNotification(kIdlePauseInMs);
-  }
-  // Create garbage and check that idle notification still collects it.
-  CreateGarbageInOldSpace();
-  intptr_t size_with_garbage = CcTest::heap()->SizeOfObjects();
-  CHECK_GT(size_with_garbage, initial_size + MB);
-  bool finished = false;
-  for (int i = 0; i < 200 && !finished; i++) {
-    finished = env->GetIsolate()->IdleNotification(kIdlePauseInMs);
-  }
-  intptr_t final_size = CcTest::heap()->SizeOfObjects();
-  CHECK_LT(final_size, initial_size + 1);
-}
-
-
 TEST(Regress2333) {
   LocalContext env;
   for (int i = 0; i < 3; i++) {
@@ -17998,10 +19123,11 @@
 
 
 TEST(ExternalizeOldSpaceTwoByteCons) {
+  v8::Isolate* isolate = CcTest::isolate();
   LocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
+  v8::HandleScope scope(isolate);
   v8::Local<v8::String> cons =
-      CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString();
+      CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString(isolate);
   CHECK(v8::Utils::OpenHandle(*cons)->IsConsString());
   CcTest::heap()->CollectAllAvailableGarbage();
   CHECK(CcTest::heap()->old_pointer_space()->Contains(
@@ -18020,10 +19146,11 @@
 
 
 TEST(ExternalizeOldSpaceOneByteCons) {
+  v8::Isolate* isolate = CcTest::isolate();
   LocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
+  v8::HandleScope scope(isolate);
   v8::Local<v8::String> cons =
-      CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString();
+      CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString(isolate);
   CHECK(v8::Utils::OpenHandle(*cons)->IsConsString());
   CcTest::heap()->CollectAllAvailableGarbage();
   CHECK(CcTest::heap()->old_pointer_space()->Contains(
@@ -18042,8 +19169,9 @@
 
 
 TEST(VisitExternalStrings) {
+  v8::Isolate* isolate = CcTest::isolate();
   LocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
+  v8::HandleScope scope(isolate);
   const char* string = "Some string";
   uint16_t* two_byte_string = AsciiToTwoByteString(string);
   TestResource* resource[4];
@@ -18113,7 +19241,7 @@
     const char* s = "One string to test them all";
     TestOneByteResource* inscription =
         new TestOneByteResource(i::StrDup(s), &destroyed);
-    v8::Local<v8::String> ring = CompileRun("ring")->ToString();
+    v8::Local<v8::String> ring = CompileRun("ring")->ToString(isolate);
     CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString());
     ring->MakeExternal(inscription);
     // Ring is still alive.  Orcs are roaming freely across our lands.
@@ -18128,6 +19256,9 @@
 
 
 TEST(ExternalInternalizedStringCollectedAtGC) {
+  // TODO(mvstanton): vector ics need weak support.
+  if (i::FLAG_vector_ics) return;
+
   int destroyed = 0;
   { LocalContext env;
     v8::HandleScope handle_scope(env->GetIsolate());
@@ -18135,7 +19266,7 @@
     const char* s = "One string to test them all";
     TestOneByteResource* inscription =
         new TestOneByteResource(i::StrDup(s), &destroyed);
-    v8::Local<v8::String> ring = CompileRun("ring")->ToString();
+    v8::Local<v8::String> ring = CompileRun("ring").As<v8::String>();
     CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString());
     ring->MakeExternal(inscription);
     // Ring is still alive.  Orcs are roaming freely across our lands.
@@ -18274,7 +19405,7 @@
     const v8::FunctionCallbackInfo<v8::Value>& args) {
   v8::HandleScope scope(args.GetIsolate());
   v8::TryCatch tc;
-  v8::Handle<v8::String> str(args[0]->ToString());
+  v8::Handle<v8::String> str(args[0]->ToString(args.GetIsolate()));
   USE(str);
   if (tc.HasCaught())
     tc.ReThrow();
@@ -18625,7 +19756,7 @@
 }
 
 
-void FooGetInterceptor(Local<String> name,
+void FooGetInterceptor(Local<Name> name,
                        const v8::PropertyCallbackInfo<v8::Value>& info) {
   CHECK(v8::Utils::OpenHandle(*info.This())->IsJSObject());
   CHECK(v8::Utils::OpenHandle(*info.Holder())->IsJSObject());
@@ -18634,8 +19765,7 @@
 }
 
 
-void FooSetInterceptor(Local<String> name,
-                       Local<Value> value,
+void FooSetInterceptor(Local<Name> name, Local<Value> value,
                        const v8::PropertyCallbackInfo<v8::Value>& info) {
   CHECK(v8::Utils::OpenHandle(*info.This())->IsJSObject());
   CHECK(v8::Utils::OpenHandle(*info.Holder())->IsJSObject());
@@ -18681,15 +19811,13 @@
 
 
 static void NamedPropertyGetterWhichReturns42(
-    Local<String> name,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
   info.GetReturnValue().Set(v8_num(42));
 }
 
 
 static void NamedPropertySetterWhichSetsYOnThisTo23(
-    Local<String> name,
-    Local<Value> value,
+    Local<Name> name, Local<Value> value,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   if (name->Equals(v8_str("x"))) {
     Local<Object>::Cast(info.This())->Set(v8_str("y"), v8_num(23));
@@ -18701,8 +19829,9 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetNamedPropertyHandler(NamedPropertyGetterWhichReturns42,
-                                 NamedPropertySetterWhichSetsYOnThisTo23);
+  templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      NamedPropertyGetterWhichReturns42,
+      NamedPropertySetterWhichSetsYOnThisTo23));
   LocalContext context;
   context->Global()->Set(v8_str("P"), templ->NewInstance());
   CompileRun("function C1() {"
@@ -19860,7 +20989,7 @@
   CHECK_EQ(42, object.WrapperClassId());
 
   Visitor42 visitor(&object);
-  v8::V8::VisitHandlesWithClassIds(&visitor);
+  v8::V8::VisitHandlesWithClassIds(isolate, &visitor);
   CHECK_EQ(1, visitor.counter_);
 
   object.Reset();
@@ -19994,8 +21123,8 @@
 }
 
 
-static void Getter(v8::Local<v8::String> property,
-                   const v8::PropertyCallbackInfo<v8::Value>& info ) {
+static void Getter(v8::Local<v8::Name> property,
+                   const v8::PropertyCallbackInfo<v8::Value>& info) {
   info.GetReturnValue().Set(v8_str("42!"));
 }
 
@@ -20014,7 +21143,8 @@
   v8::Context::Scope context_scope(context.local());
 
   v8::Handle<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(isolate);
-  tmpl->SetNamedPropertyHandler(Getter, NULL, NULL, NULL, Enumerator);
+  tmpl->SetHandler(v8::NamedPropertyHandlerConfiguration(Getter, NULL, NULL,
+                                                         NULL, Enumerator));
   context->Global()->Set(v8_str("o"), tmpl->NewInstance());
   v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun(
         "var result = []; for (var k in o) result.push(k); result"));
@@ -20159,8 +21289,7 @@
 
 
 void HasOwnPropertyNamedPropertyGetter(
-    Local<String> property,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
   if (property->Equals(v8_str("foo"))) info.GetReturnValue().Set(v8_str("yes"));
 }
 
@@ -20172,15 +21301,13 @@
 
 
 void HasOwnPropertyNamedPropertyQuery(
-    Local<String> property,
-    const v8::PropertyCallbackInfo<v8::Integer>& info) {
+    Local<Name> property, const v8::PropertyCallbackInfo<v8::Integer>& info) {
   if (property->Equals(v8_str("foo"))) info.GetReturnValue().Set(1);
 }
 
 
 void HasOwnPropertyNamedPropertyQuery2(
-    Local<String> property,
-    const v8::PropertyCallbackInfo<v8::Integer>& info) {
+    Local<Name> property, const v8::PropertyCallbackInfo<v8::Integer>& info) {
   if (property->Equals(v8_str("bar"))) info.GetReturnValue().Set(1);
 }
 
@@ -20209,7 +21336,7 @@
         "Bar.prototype = new Foo();"
         "new Bar();");
     CHECK(value->IsObject());
-    Handle<Object> object = value->ToObject();
+    Handle<Object> object = value->ToObject(isolate);
     CHECK(object->Has(v8_str("foo")));
     CHECK(!object->HasOwnProperty(v8_str("foo")));
     CHECK(object->HasOwnProperty(v8_str("bar")));
@@ -20219,7 +21346,8 @@
   }
   { // Check named getter interceptors.
     Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-    templ->SetNamedPropertyHandler(HasOwnPropertyNamedPropertyGetter);
+    templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+        HasOwnPropertyNamedPropertyGetter));
     Handle<Object> instance = templ->NewInstance();
     CHECK(!instance->HasOwnProperty(v8_str("42")));
     CHECK(instance->HasOwnProperty(v8_str("foo")));
@@ -20227,7 +21355,8 @@
   }
   { // Check indexed getter interceptors.
     Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-    templ->SetIndexedPropertyHandler(HasOwnPropertyIndexedPropertyGetter);
+    templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+        HasOwnPropertyIndexedPropertyGetter));
     Handle<Object> instance = templ->NewInstance();
     CHECK(instance->HasOwnProperty(v8_str("42")));
     CHECK(!instance->HasOwnProperty(v8_str("43")));
@@ -20235,14 +21364,16 @@
   }
   { // Check named query interceptors.
     Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-    templ->SetNamedPropertyHandler(0, 0, HasOwnPropertyNamedPropertyQuery);
+    templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+        0, 0, HasOwnPropertyNamedPropertyQuery));
     Handle<Object> instance = templ->NewInstance();
     CHECK(instance->HasOwnProperty(v8_str("foo")));
     CHECK(!instance->HasOwnProperty(v8_str("bar")));
   }
   { // Check indexed query interceptors.
     Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-    templ->SetIndexedPropertyHandler(0, 0, HasOwnPropertyIndexedPropertyQuery);
+    templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+        0, 0, HasOwnPropertyIndexedPropertyQuery));
     Handle<Object> instance = templ->NewInstance();
     CHECK(instance->HasOwnProperty(v8_str("42")));
     CHECK(!instance->HasOwnProperty(v8_str("41")));
@@ -20256,9 +21387,9 @@
   }
   { // Check that query wins on disagreement.
     Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-    templ->SetNamedPropertyHandler(HasOwnPropertyNamedPropertyGetter,
-                                   0,
-                                   HasOwnPropertyNamedPropertyQuery2);
+    templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+        HasOwnPropertyNamedPropertyGetter, 0,
+        HasOwnPropertyNamedPropertyQuery2));
     Handle<Object> instance = templ->NewInstance();
     CHECK(!instance->HasOwnProperty(v8_str("foo")));
     CHECK(instance->HasOwnProperty(v8_str("bar")));
@@ -20270,9 +21401,8 @@
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope scope(isolate);
   Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
-  templ->SetIndexedPropertyHandler(NULL,
-                                   NULL,
-                                   HasOwnPropertyIndexedPropertyQuery);
+  templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      NULL, NULL, HasOwnPropertyIndexedPropertyQuery));
   LocalContext context;
   context->Global()->Set(v8_str("obj"), templ->NewInstance());
   CompileRun("var s = new String('foobar'); obj.__proto__ = s;");
@@ -20417,29 +21547,40 @@
 }
 
 
+static int CountLiveMapsInMapCache(i::Context* context) {
+  i::FixedArray* map_cache = i::FixedArray::cast(context->map_cache());
+  int length = map_cache->length();
+  int count = 0;
+  for (int i = 0; i < length; i++) {
+    i::Object* value = map_cache->get(i);
+    if (value->IsWeakCell() && !i::WeakCell::cast(value)->cleared()) count++;
+  }
+  return count;
+}
+
+
 THREADED_TEST(Regress1516) {
   LocalContext context;
   v8::HandleScope scope(context->GetIsolate());
 
+  // Object with 20 properties is not a common case, so it should be removed
+  // from the cache after GC.
   { v8::HandleScope temp_scope(context->GetIsolate());
-    CompileRun("({'a': 0})");
+    CompileRun(
+        "({"
+        "'a00': 0, 'a01': 0, 'a02': 0, 'a03': 0, 'a04': 0, "
+        "'a05': 0, 'a06': 0, 'a07': 0, 'a08': 0, 'a09': 0, "
+        "'a10': 0, 'a11': 0, 'a12': 0, 'a13': 0, 'a14': 0, "
+        "'a15': 0, 'a16': 0, 'a17': 0, 'a18': 0, 'a19': 0, "
+        "})");
   }
 
-  int elements;
-  { i::MapCache* map_cache =
-        i::MapCache::cast(CcTest::i_isolate()->context()->map_cache());
-    elements = map_cache->NumberOfElements();
-    CHECK_LE(1, elements);
-  }
+  int elements = CountLiveMapsInMapCache(CcTest::i_isolate()->context());
+  CHECK_LE(1, elements);
 
-  CcTest::heap()->CollectAllGarbage(
-      i::Heap::kAbortIncrementalMarkingMask);
-  { i::Object* raw_map_cache = CcTest::i_isolate()->context()->map_cache();
-    if (raw_map_cache != CcTest::heap()->undefined_value()) {
-      i::MapCache* map_cache = i::MapCache::cast(raw_map_cache);
-      CHECK_GT(elements, map_cache->NumberOfElements());
-    }
-  }
+  CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
+
+  CHECK_GT(elements, CountLiveMapsInMapCache(CcTest::i_isolate()->context()));
 }
 
 
@@ -20448,12 +21589,11 @@
                                                 v8::AccessType type,
                                                 Local<Value> data) {
   // Only block read access to __proto__.
-  if (type == v8::ACCESS_GET &&
-      name->IsString() &&
-      name->ToString()->Length() == 9 &&
-      name->ToString()->Utf8Length() == 9) {
+  if (type == v8::ACCESS_GET && name->IsString() &&
+      name.As<v8::String>()->Length() == 9 &&
+      name.As<v8::String>()->Utf8Length() == 9) {
     char buffer[10];
-    CHECK_EQ(10, name->ToString()->WriteUtf8(buffer));
+    CHECK_EQ(10, name.As<v8::String>()->WriteUtf8(buffer));
     return strncmp(buffer, "__proto__", 9) != 0;
   }
 
@@ -20500,8 +21640,7 @@
       context->Global();
 
   // Global object, the  prototype of proxy_object. No security checks.
-  Local<Object> global_object =
-      proxy_object->GetPrototype()->ToObject();
+  Local<Object> global_object = proxy_object->GetPrototype()->ToObject(isolate);
 
   // Hidden prototype without security check.
   Local<Object> hidden_prototype =
@@ -20545,7 +21684,7 @@
 
   Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)");
   CHECK(result5->Equals(
-      object_with_hidden->GetPrototype()->ToObject()->GetPrototype()));
+      object_with_hidden->GetPrototype()->ToObject(isolate)->GetPrototype()));
 
   Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)");
   CHECK(result6.IsEmpty());
@@ -20581,8 +21720,8 @@
                          const char* code) {
   Local<Value> result = CompileRun(code);
   CHECK(result->IsObject());
-  CHECK(expected_receiver->Equals(result->ToObject()->Get(1)));
-  CHECK(expected_result->Equals(result->ToObject()->Get(0)));
+  CHECK(expected_receiver->Equals(result.As<v8::Object>()->Get(1)));
+  CHECK(expected_result->Equals(result.As<v8::Object>()->Get(0)));
 }
 
 
@@ -20970,8 +22109,8 @@
   Handle<Object> exec_state = event_details.GetExecutionState();
   Handle<Value> break_id = exec_state->Get(v8_str("break_id"));
   CompileRun("function f(id) { new FrameDetails(id, 0); }");
-  Handle<Function> fun = Handle<Function>::Cast(
-      CcTest::global()->Get(v8_str("f"))->ToObject());
+  Handle<Function> fun =
+      Handle<Function>::Cast(CcTest::global()->Get(v8_str("f")));
   fun->Call(CcTest::global(), 1, &break_id);
 }
 
@@ -20995,7 +22134,7 @@
 }
 
 
-#ifdef DEBUG
+#ifdef ENABLE_DISASSEMBLER
 static int probes_counter = 0;
 static int misses_counter = 0;
 static int updates_counter = 0;
@@ -21029,7 +22168,7 @@
 
 
 static void StubCacheHelper(bool primary) {
-#ifdef DEBUG
+#ifdef ENABLE_DISASSEMBLER
   i::FLAG_native_code_counters = true;
   if (primary) {
     i::FLAG_test_primary_stub_cache = true;
@@ -21376,7 +22515,8 @@
   LocalContext context;
   Local<ObjectTemplate> templ = ObjectTemplate::New(context->GetIsolate());
   if (interceptor) {
-    templ->SetNamedPropertyHandler(FooGetInterceptor, FooSetInterceptor);
+    templ->SetHandler(v8::NamedPropertyHandlerConfiguration(FooGetInterceptor,
+                                                            FooSetInterceptor));
   } else {
     templ->SetAccessor(v8_str("foo"),
                        GetterWhichReturns42,
@@ -21782,7 +22922,8 @@
 
 
 void HasOwnPropertyCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
-  args[0]->ToObject()->HasOwnProperty(args[1]->ToString());
+  args[0]->ToObject(args.GetIsolate())->HasOwnProperty(
+      args[1]->ToString(args.GetIsolate()));
 }
 
 
@@ -21998,8 +23139,6 @@
 
     TestBody();
 
-    isolate_->ClearInterrupt();
-
     // Verify we arrived here because interruptor was called
     // not due to a bug causing us to exit the loop too early.
     CHECK(!should_continue());
@@ -22149,7 +23288,8 @@
     proto->Set(v8_str("shouldContinue"), Function::New(
         isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)));
     v8::Local<v8::ObjectTemplate> instance_template = t->InstanceTemplate();
-    instance_template->SetNamedPropertyHandler(EmptyInterceptor);
+    instance_template->SetHandler(
+        v8::NamedPropertyHandlerConfiguration(EmptyInterceptor));
 
     env_->Global()->Set(v8_str("Klass"), t->GetFunction());
 
@@ -22158,9 +23298,7 @@
 
  private:
   static void EmptyInterceptor(
-      Local<String> property,
-      const v8::PropertyCallbackInfo<v8::Value>& info) {
-  }
+      Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {}
 };
 
 
@@ -22249,10 +23387,9 @@
 }
 
 
-class ClearInterruptFromAnotherThread
-    : public RequestInterruptTestBase {
+class RequestMultipleInterrupts : public RequestInterruptTestBase {
  public:
-  ClearInterruptFromAnotherThread() : i_thread(this), sem2_(0) { }
+  RequestMultipleInterrupts() : i_thread(this), counter_(0) {}
 
   virtual void StartInterruptThread() {
     i_thread.Start();
@@ -22269,39 +23406,33 @@
  private:
   class InterruptThread : public v8::base::Thread {
    public:
-    explicit InterruptThread(ClearInterruptFromAnotherThread* test)
+    enum { NUM_INTERRUPTS = 10 };
+    explicit InterruptThread(RequestMultipleInterrupts* test)
         : Thread(Options("RequestInterruptTest")), test_(test) {}
 
     virtual void Run() {
       test_->sem_.Wait();
-      test_->isolate_->RequestInterrupt(&OnInterrupt, test_);
-      test_->sem_.Wait();
-      test_->isolate_->ClearInterrupt();
-      test_->sem2_.Signal();
+      for (int i = 0; i < NUM_INTERRUPTS; i++) {
+        test_->isolate_->RequestInterrupt(&OnInterrupt, test_);
+      }
     }
 
     static void OnInterrupt(v8::Isolate* isolate, void* data) {
-      ClearInterruptFromAnotherThread* test =
-          reinterpret_cast<ClearInterruptFromAnotherThread*>(data);
-      test->sem_.Signal();
-      bool success = test->sem2_.WaitFor(v8::base::TimeDelta::FromSeconds(2));
-      // Crash instead of timeout to make this failure more prominent.
-      CHECK(success);
-      test->should_continue_ = false;
+      RequestMultipleInterrupts* test =
+          reinterpret_cast<RequestMultipleInterrupts*>(data);
+      test->should_continue_ = ++test->counter_ < NUM_INTERRUPTS;
     }
 
    private:
-     ClearInterruptFromAnotherThread* test_;
+    RequestMultipleInterrupts* test_;
   };
 
   InterruptThread i_thread;
-  v8::base::Semaphore sem2_;
+  int counter_;
 };
 
 
-TEST(ClearInterruptFromAnotherThread) {
-  ClearInterruptFromAnotherThread().RunTest();
-}
+TEST(RequestMultipleInterrupts) { RequestMultipleInterrupts().RunTest(); }
 
 
 static Local<Value> function_new_expected_env;
@@ -22606,6 +23737,7 @@
   Handle<v8::Promise::Resolver> rr = v8::Promise::Resolver::New(isolate);
   Handle<v8::Promise> p = pr->GetPromise();
   Handle<v8::Promise> r = rr->GetPromise();
+  CHECK_EQ(isolate, p->GetIsolate());
 
   // IsPromise predicate.
   CHECK(p->IsPromise());
@@ -22867,10 +23999,8 @@
   CHECK_EQ(13, line_number);
 }
 
-
-void SourceURLHelper(const char* source, const char* expected_source_url,
-                     const char* expected_source_mapping_url) {
-  Local<Script> script = v8_compile(source);
+void CheckMagicComments(Handle<Script> script, const char* expected_source_url,
+                        const char* expected_source_mapping_url) {
   if (expected_source_url != NULL) {
     v8::String::Utf8Value url(script->GetUnboundScript()->GetSourceURL());
     CHECK_EQ(expected_source_url, *url);
@@ -22886,6 +24016,12 @@
   }
 }
 
+void SourceURLHelper(const char* source, const char* expected_source_url,
+                     const char* expected_source_mapping_url) {
+  Local<Script> script = v8_compile(source);
+  CheckMagicComments(script, expected_source_url, expected_source_mapping_url);
+}
+
 
 TEST(ScriptSourceURLAndSourceMappingURL) {
   LocalContext env;
@@ -23077,7 +24213,9 @@
 void RunStreamingTest(const char** chunks,
                       v8::ScriptCompiler::StreamedSource::Encoding encoding =
                           v8::ScriptCompiler::StreamedSource::ONE_BYTE,
-                      bool expected_success = true) {
+                      bool expected_success = true,
+                      const char* expected_source_url = NULL,
+                      const char* expected_source_mapping_url = NULL) {
   LocalContext env;
   v8::Isolate* isolate = env->GetIsolate();
   v8::HandleScope scope(isolate);
@@ -23106,6 +24244,8 @@
     v8::Handle<Value> result(script->Run());
     // All scripts are supposed to return the fixed value 13 when ran.
     CHECK_EQ(13, result->Int32Value());
+    CheckMagicComments(script, expected_source_url,
+                       expected_source_mapping_url);
   } else {
     CHECK(script.IsEmpty());
     CHECK(try_catch.HasCaught());
@@ -23170,14 +24310,14 @@
 
 
 TEST(StreamingUtf8Script) {
-  // We'd want to write \uc481 instead of \xeb\x91\x80, but Windows compilers
+  // We'd want to write \uc481 instead of \xec\x92\x81, but Windows compilers
   // don't like it.
   const char* chunk1 =
       "function foo() {\n"
       "  // This function will contain an UTF-8 character which is not in\n"
       "  // ASCII.\n"
-      "  var foob\xeb\x91\x80r = 13;\n"
-      "  return foob\xeb\x91\x80r;\n"
+      "  var foob\xec\x92\x81r = 13;\n"
+      "  return foob\xec\x92\x81r;\n"
       "}\n";
   const char* chunks[] = {chunk1, "foo(); ", NULL};
   RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
@@ -23188,7 +24328,7 @@
   // A sanity check to prove that the approach of splitting UTF-8
   // characters is correct. Here is an UTF-8 character which will take three
   // bytes.
-  const char* reference = "\xeb\x91\x80";
+  const char* reference = "\xec\x92\x81";
   CHECK(3u == strlen(reference));  // NOLINT - no CHECK_EQ for unsigned.
 
   char chunk1[] =
@@ -23198,7 +24338,7 @@
       "  var foob";
   char chunk2[] =
       "XXXr = 13;\n"
-      "  return foob\xeb\x91\x80r;\n"
+      "  return foob\xec\x92\x81r;\n"
       "}\n";
   for (int i = 0; i < 3; ++i) {
     chunk2[i] = reference[i];
@@ -23211,7 +24351,7 @@
 TEST(StreamingUtf8ScriptWithSplitCharacters) {
   // Stream data where a multi-byte UTF-8 character is split between two data
   // chunks.
-  const char* reference = "\xeb\x91\x80";
+  const char* reference = "\xec\x92\x81";
   char chunk1[] =
       "function foo() {\n"
       "  // This function will contain an UTF-8 character which is not in\n"
@@ -23219,7 +24359,7 @@
       "  var foobX";
   char chunk2[] =
       "XXr = 13;\n"
-      "  return foob\xeb\x91\x80r;\n"
+      "  return foob\xec\x92\x81r;\n"
       "}\n";
   chunk1[strlen(chunk1) - 1] = reference[0];
   chunk2[0] = reference[1];
@@ -23235,7 +24375,7 @@
   // Case 1: a chunk contains only bytes for a split character (and no other
   // data). This kind of a chunk would be exceptionally small, but we should
   // still decode it correctly.
-  const char* reference = "\xeb\x91\x80";
+  const char* reference = "\xec\x92\x81";
   // The small chunk is at the beginning of the split character
   {
     char chunk1[] =
@@ -23246,7 +24386,7 @@
     char chunk2[] = "XX";
     char chunk3[] =
         "Xr = 13;\n"
-        "  return foob\xeb\x91\x80r;\n"
+        "  return foob\xec\x92\x81r;\n"
         "}\n";
     chunk2[0] = reference[0];
     chunk2[1] = reference[1];
@@ -23264,7 +24404,7 @@
     char chunk2[] = "XX";
     char chunk3[] =
         "r = 13;\n"
-        "  return foob\xeb\x91\x80r;\n"
+        "  return foob\xec\x92\x81r;\n"
         "}\n";
     chunk1[strlen(chunk1) - 1] = reference[0];
     chunk2[0] = reference[1];
@@ -23276,8 +24416,8 @@
   // decoded correctly and not just ignored.
   {
     char chunk1[] =
-        "var foob\xeb\x91\x80 = 13;\n"
-        "foob\xeb\x91\x80";
+        "var foob\xec\x92\x81 = 13;\n"
+        "foob\xec\x92\x81";
     const char* chunks[] = {chunk1, NULL};
     RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
   }
@@ -23288,7 +24428,7 @@
   // Test cases where a UTF-8 character is split over several chunks. Those
   // cases are not supported (the embedder should give the data in big enough
   // chunks), but we shouldn't crash, just produce a parse error.
-  const char* reference = "\xeb\x91\x80";
+  const char* reference = "\xec\x92\x81";
   char chunk1[] =
       "function foo() {\n"
       "  // This function will contain an UTF-8 character which is not in\n"
@@ -23297,7 +24437,7 @@
   char chunk2[] = "X";
   char chunk3[] =
       "Xr = 13;\n"
-      "  return foob\xeb\x91\x80r;\n"
+      "  return foob\xec\x92\x81r;\n"
       "}\n";
   chunk1[strlen(chunk1) - 1] = reference[0];
   chunk2[0] = reference[1];
@@ -23332,6 +24472,7 @@
   const v8::ScriptCompiler::CachedData* cached_data = source.GetCachedData();
   CHECK(cached_data != NULL);
   CHECK(cached_data->data != NULL);
+  CHECK(!cached_data->rejected);
   CHECK_GT(cached_data->length, 0);
 }
 
@@ -23339,7 +24480,7 @@
 TEST(StreamingScriptWithInvalidUtf8) {
   // Regression test for a crash: test that invalid UTF-8 bytes in the end of a
   // chunk don't produce a crash.
-  const char* reference = "\xeb\x91\x80\x80\x80";
+  const char* reference = "\xec\x92\x81\x80\x80";
   char chunk1[] =
       "function foo() {\n"
       "  // This function will contain an UTF-8 character which is not in\n"
@@ -23347,10 +24488,274 @@
       "  var foobXXXXX";  // Too many bytes which look like incomplete chars!
   char chunk2[] =
       "r = 13;\n"
-      "  return foob\xeb\x91\x80\x80\x80r;\n"
+      "  return foob\xec\x92\x81\x80\x80r;\n"
       "}\n";
   for (int i = 0; i < 5; ++i) chunk1[strlen(chunk1) - 5 + i] = reference[i];
 
   const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
   RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, false);
 }
+
+
+TEST(StreamingUtf8ScriptWithMultipleMultibyteCharactersSomeSplit) {
+  // Regression test: Stream data where there are several multi-byte UTF-8
+  // characters in a sequence and one of them is split between two data chunks.
+  const char* reference = "\xec\x92\x81";
+  char chunk1[] =
+      "function foo() {\n"
+      "  // This function will contain an UTF-8 character which is not in\n"
+      "  // ASCII.\n"
+      "  var foob\xec\x92\x81X";
+  char chunk2[] =
+      "XXr = 13;\n"
+      "  return foob\xec\x92\x81\xec\x92\x81r;\n"
+      "}\n";
+  chunk1[strlen(chunk1) - 1] = reference[0];
+  chunk2[0] = reference[1];
+  chunk2[1] = reference[2];
+  const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
+  RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
+}
+
+
+TEST(StreamingUtf8ScriptWithMultipleMultibyteCharactersSomeSplit2) {
+  // Another regression test, similar to the previous one. The difference is
+  // that the split character is not the last one in the sequence.
+  const char* reference = "\xec\x92\x81";
+  char chunk1[] =
+      "function foo() {\n"
+      "  // This function will contain an UTF-8 character which is not in\n"
+      "  // ASCII.\n"
+      "  var foobX";
+  char chunk2[] =
+      "XX\xec\x92\x81r = 13;\n"
+      "  return foob\xec\x92\x81\xec\x92\x81r;\n"
+      "}\n";
+  chunk1[strlen(chunk1) - 1] = reference[0];
+  chunk2[0] = reference[1];
+  chunk2[1] = reference[2];
+  const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
+  RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
+}
+
+
+void TestInvalidCacheData(v8::ScriptCompiler::CompileOptions option) {
+  const char* garbage = "garbage garbage garbage garbage garbage garbage";
+  const uint8_t* data = reinterpret_cast<const uint8_t*>(garbage);
+  int length = 16;
+  v8::ScriptCompiler::CachedData* cached_data =
+      new v8::ScriptCompiler::CachedData(data, length);
+  DCHECK(!cached_data->rejected);
+  v8::ScriptOrigin origin(v8_str("origin"));
+  v8::ScriptCompiler::Source source(v8_str("42"), origin, cached_data);
+  v8::Handle<v8::Script> script =
+      v8::ScriptCompiler::Compile(CcTest::isolate(), &source, option);
+  CHECK(cached_data->rejected);
+  CHECK_EQ(42, script->Run()->Int32Value());
+}
+
+
+TEST(InvalidCacheData) {
+  v8::V8::Initialize();
+  v8::HandleScope scope(CcTest::isolate());
+  LocalContext context;
+  TestInvalidCacheData(v8::ScriptCompiler::kConsumeParserCache);
+  TestInvalidCacheData(v8::ScriptCompiler::kConsumeCodeCache);
+}
+
+
+TEST(ParserCacheRejectedGracefully) {
+  i::FLAG_min_preparse_length = 0;
+  v8::V8::Initialize();
+  v8::HandleScope scope(CcTest::isolate());
+  LocalContext context;
+  // Produce valid cached data.
+  v8::ScriptOrigin origin(v8_str("origin"));
+  v8::Local<v8::String> source_str = v8_str("function foo() {}");
+  v8::ScriptCompiler::Source source(source_str, origin);
+  v8::Handle<v8::Script> script = v8::ScriptCompiler::Compile(
+      CcTest::isolate(), &source, v8::ScriptCompiler::kProduceParserCache);
+  CHECK(!script.IsEmpty());
+  const v8::ScriptCompiler::CachedData* original_cached_data =
+      source.GetCachedData();
+  CHECK(original_cached_data != NULL);
+  CHECK(original_cached_data->data != NULL);
+  CHECK(!original_cached_data->rejected);
+  CHECK_GT(original_cached_data->length, 0);
+  // Recompiling the same script with it won't reject the data.
+  {
+    v8::ScriptCompiler::Source source_with_cached_data(
+        source_str, origin,
+        new v8::ScriptCompiler::CachedData(original_cached_data->data,
+                                           original_cached_data->length));
+    v8::Handle<v8::Script> script =
+        v8::ScriptCompiler::Compile(CcTest::isolate(), &source_with_cached_data,
+                                    v8::ScriptCompiler::kConsumeParserCache);
+    CHECK(!script.IsEmpty());
+    const v8::ScriptCompiler::CachedData* new_cached_data =
+        source_with_cached_data.GetCachedData();
+    CHECK(new_cached_data != NULL);
+    CHECK(!new_cached_data->rejected);
+  }
+  // Compile an incompatible script with the cached data. The new script doesn't
+  // have the same starting position for the function as the old one, so the old
+  // cached data will be incompatible with it and will be rejected.
+  {
+    v8::Local<v8::String> incompatible_source_str =
+        v8_str("   function foo() {}");
+    v8::ScriptCompiler::Source source_with_cached_data(
+        incompatible_source_str, origin,
+        new v8::ScriptCompiler::CachedData(original_cached_data->data,
+                                           original_cached_data->length));
+    v8::Handle<v8::Script> script =
+        v8::ScriptCompiler::Compile(CcTest::isolate(), &source_with_cached_data,
+                                    v8::ScriptCompiler::kConsumeParserCache);
+    CHECK(!script.IsEmpty());
+    const v8::ScriptCompiler::CachedData* new_cached_data =
+        source_with_cached_data.GetCachedData();
+    CHECK(new_cached_data != NULL);
+    CHECK(new_cached_data->rejected);
+  }
+}
+
+
+TEST(StringConcatOverflow) {
+  v8::V8::Initialize();
+  v8::HandleScope scope(CcTest::isolate());
+  RandomLengthOneByteResource* r =
+      new RandomLengthOneByteResource(i::String::kMaxLength);
+  v8::Local<v8::String> str = v8::String::NewExternal(CcTest::isolate(), r);
+  CHECK(!str.IsEmpty());
+  v8::TryCatch try_catch;
+  v8::Local<v8::String> result = v8::String::Concat(str, str);
+  CHECK(result.IsEmpty());
+  CHECK(!try_catch.HasCaught());
+}
+
+
+TEST(TurboAsmDisablesNeuter) {
+  v8::V8::Initialize();
+  v8::HandleScope scope(CcTest::isolate());
+  LocalContext context;
+#if V8_TURBOFAN_TARGET
+  bool should_be_neuterable = !i::FLAG_turbo_asm;
+#else
+  bool should_be_neuterable = true;
+#endif
+  const char* load =
+      "function Module(stdlib, foreign, heap) {"
+      "  'use asm';"
+      "  var MEM32 = new stdlib.Int32Array(heap);"
+      "  function load() { return MEM32[0]; }"
+      "  return { load: load };"
+      "}"
+      "var buffer = new ArrayBuffer(4);"
+      "Module(this, {}, buffer).load();"
+      "buffer";
+
+  v8::Local<v8::ArrayBuffer> result = CompileRun(load).As<v8::ArrayBuffer>();
+  CHECK_EQ(should_be_neuterable, result->IsNeuterable());
+
+  const char* store =
+      "function Module(stdlib, foreign, heap) {"
+      "  'use asm';"
+      "  var MEM32 = new stdlib.Int32Array(heap);"
+      "  function store() { MEM32[0] = 0; }"
+      "  return { store: store };"
+      "}"
+      "var buffer = new ArrayBuffer(4);"
+      "Module(this, {}, buffer).store();"
+      "buffer";
+
+  result = CompileRun(store).As<v8::ArrayBuffer>();
+  CHECK_EQ(should_be_neuterable, result->IsNeuterable());
+}
+
+
+TEST(GetPrototypeAccessControl) {
+  i::FLAG_allow_natives_syntax = true;
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope handle_scope(isolate);
+  LocalContext env;
+
+  v8::Handle<v8::ObjectTemplate> obj_template =
+      v8::ObjectTemplate::New(isolate);
+  obj_template->SetAccessCheckCallbacks(BlockEverythingNamed,
+                                        BlockEverythingIndexed);
+
+  env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance());
+
+  {
+    v8::TryCatch try_catch;
+    CompileRun(
+        "function f() { %_GetPrototype(prohibited); }"
+        "%OptimizeFunctionOnNextCall(f);"
+        "f();");
+    CHECK(try_catch.HasCaught());
+  }
+}
+
+
+TEST(GetPrototypeHidden) {
+  i::FLAG_allow_natives_syntax = true;
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope handle_scope(isolate);
+  LocalContext env;
+
+  Handle<FunctionTemplate> t = FunctionTemplate::New(isolate);
+  t->SetHiddenPrototype(true);
+  Handle<Object> proto = t->GetFunction()->NewInstance();
+  Handle<Object> object = Object::New(isolate);
+  Handle<Object> proto2 = Object::New(isolate);
+  object->SetPrototype(proto);
+  proto->SetPrototype(proto2);
+
+  env->Global()->Set(v8_str("object"), object);
+  env->Global()->Set(v8_str("proto"), proto);
+  env->Global()->Set(v8_str("proto2"), proto2);
+
+  v8::Handle<v8::Value> result = CompileRun("%_GetPrototype(object)");
+  CHECK(result->Equals(proto2));
+
+  result = CompileRun(
+      "function f() { return %_GetPrototype(object); }"
+      "%OptimizeFunctionOnNextCall(f);"
+      "f()");
+  CHECK(result->Equals(proto2));
+}
+
+
+TEST(ClassPrototypeCreationContext) {
+  i::FLAG_harmony_classes = true;
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope handle_scope(isolate);
+  LocalContext env;
+
+  Handle<Object> result = Handle<Object>::Cast(
+      CompileRun("'use strict'; class Example { }; Example.prototype"));
+  CHECK(env.local() == result->CreationContext());
+}
+
+
+TEST(SimpleStreamingScriptWithSourceURL) {
+  const char* chunks[] = {"function foo() { ret", "urn 13; } f", "oo();\n",
+                          "//# sourceURL=bar2.js\n", NULL};
+  RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true,
+                   "bar2.js");
+}
+
+
+TEST(StreamingScriptWithSplitSourceURL) {
+  const char* chunks[] = {"function foo() { ret", "urn 13; } f",
+                          "oo();\n//# sourceURL=b", "ar2.js\n", NULL};
+  RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true,
+                   "bar2.js");
+}
+
+
+TEST(StreamingScriptWithSourceMappingURLInTheMiddle) {
+  const char* chunks[] = {"function foo() { ret", "urn 13; }\n//#",
+                          " sourceMappingURL=bar2.js\n", "foo();", NULL};
+  RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true, NULL,
+                   "bar2.js");
+}
diff --git a/test/cctest/test-assembler-arm.cc b/test/cctest/test-assembler-arm.cc
index ed9563d..2bcf022 100644
--- a/test/cctest/test-assembler-arm.cc
+++ b/test/cctest/test-assembler-arm.cc
@@ -25,6 +25,8 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+#include <iostream>  // NOLINT(readability/streams)
+
 #include "src/v8.h"
 #include "test/cctest/cctest.h"
 
@@ -34,6 +36,7 @@
 #include "src/factory.h"
 #include "src/ostreams.h"
 
+using namespace v8::base;
 using namespace v8::internal;
 
 
@@ -1372,14 +1375,14 @@
   __ pkhtb(r2, r0, Operand(r1, ASR, 8));
   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst1)));
 
-  __ uxtb16(r2, Operand(r0, ROR, 8));
+  __ uxtb16(r2, r0, 8);
   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst2)));
 
-  __ uxtb(r2, Operand(r0, ROR, 8));
+  __ uxtb(r2, r0, 8);
   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst3)));
 
   __ ldr(r0, MemOperand(r4, OFFSET_OF(T, src2)));
-  __ uxtab(r2, r0, Operand(r1, ROR, 8));
+  __ uxtab(r2, r0, r1, 8);
   __ str(r2, MemOperand(r4, OFFSET_OF(T, dst4)));
 
   __ ldm(ia_w, sp, r4.bit() | pc.bit());
@@ -1439,21 +1442,19 @@
     CHECK_EQ(expected_, t.result);
 
 
-TEST(18) {
+TEST(sdiv) {
   // Test the sdiv.
   CcTest::InitializeVM();
   Isolate* isolate = CcTest::i_isolate();
   HandleScope scope(isolate);
-
-  typedef struct {
-    uint32_t dividend;
-    uint32_t divisor;
-    uint32_t result;
-  } T;
-  T t;
-
   Assembler assm(isolate, NULL, 0);
 
+  struct T {
+    int32_t dividend;
+    int32_t divisor;
+    int32_t result;
+  } t;
+
   if (CpuFeatures::IsSupported(SUDIV)) {
     CpuFeatureScope scope(&assm, SUDIV);
 
@@ -1477,6 +1478,8 @@
 #endif
     F3 f = FUNCTION_CAST<F3>(code->entry());
     Object* dummy;
+    TEST_SDIV(0, kMinInt, 0);
+    TEST_SDIV(0, 1024, 0);
     TEST_SDIV(1073741824, kMinInt, -2);
     TEST_SDIV(kMinInt, kMinInt, -1);
     TEST_SDIV(5, 10, 2);
@@ -1495,6 +1498,322 @@
 #undef TEST_SDIV
 
 
+#define TEST_UDIV(expected_, dividend_, divisor_) \
+  t.dividend = dividend_;                         \
+  t.divisor = divisor_;                           \
+  t.result = 0;                                   \
+  dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0); \
+  CHECK_EQ(expected_, t.result);
+
+
+TEST(udiv) {
+  // Test the udiv.
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+  Assembler assm(isolate, NULL, 0);
+
+  struct T {
+    uint32_t dividend;
+    uint32_t divisor;
+    uint32_t result;
+  } t;
+
+  if (CpuFeatures::IsSupported(SUDIV)) {
+    CpuFeatureScope scope(&assm, SUDIV);
+
+    __ mov(r3, Operand(r0));
+
+    __ ldr(r0, MemOperand(r3, OFFSET_OF(T, dividend)));
+    __ ldr(r1, MemOperand(r3, OFFSET_OF(T, divisor)));
+
+    __ sdiv(r2, r0, r1);
+    __ str(r2, MemOperand(r3, OFFSET_OF(T, result)));
+
+    __ bx(lr);
+
+    CodeDesc desc;
+    assm.GetCode(&desc);
+    Handle<Code> code = isolate->factory()->NewCode(
+        desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef DEBUG
+    OFStream os(stdout);
+    code->Print(os);
+#endif
+    F3 f = FUNCTION_CAST<F3>(code->entry());
+    Object* dummy;
+    TEST_UDIV(0, 0, 0);
+    TEST_UDIV(0, 1024, 0);
+    TEST_UDIV(5, 10, 2);
+    TEST_UDIV(3, 10, 3);
+    USE(dummy);
+  }
+}
+
+
+#undef TEST_UDIV
+
+
+TEST(smmla) {
+  CcTest::InitializeVM();
+  Isolate* const isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+  RandomNumberGenerator* const rng = isolate->random_number_generator();
+  Assembler assm(isolate, nullptr, 0);
+  __ smmla(r1, r1, r2, r3);
+  __ str(r1, MemOperand(r0));
+  __ bx(lr);
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  code->Print(std::cout);
+#endif
+  F3 f = FUNCTION_CAST<F3>(code->entry());
+  for (size_t i = 0; i < 128; ++i) {
+    int32_t r, x = rng->NextInt(), y = rng->NextInt(), z = rng->NextInt();
+    Object* dummy = CALL_GENERATED_CODE(f, &r, x, y, z, 0);
+    CHECK_EQ(bits::SignedMulHighAndAdd32(x, y, z), r);
+    USE(dummy);
+  }
+}
+
+
+TEST(smmul) {
+  CcTest::InitializeVM();
+  Isolate* const isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+  RandomNumberGenerator* const rng = isolate->random_number_generator();
+  Assembler assm(isolate, nullptr, 0);
+  __ smmul(r1, r1, r2);
+  __ str(r1, MemOperand(r0));
+  __ bx(lr);
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  code->Print(std::cout);
+#endif
+  F3 f = FUNCTION_CAST<F3>(code->entry());
+  for (size_t i = 0; i < 128; ++i) {
+    int32_t r, x = rng->NextInt(), y = rng->NextInt();
+    Object* dummy = CALL_GENERATED_CODE(f, &r, x, y, 0, 0);
+    CHECK_EQ(bits::SignedMulHigh32(x, y), r);
+    USE(dummy);
+  }
+}
+
+
+TEST(sxtb) {
+  CcTest::InitializeVM();
+  Isolate* const isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+  RandomNumberGenerator* const rng = isolate->random_number_generator();
+  Assembler assm(isolate, nullptr, 0);
+  __ sxtb(r1, r1);
+  __ str(r1, MemOperand(r0));
+  __ bx(lr);
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  code->Print(std::cout);
+#endif
+  F3 f = FUNCTION_CAST<F3>(code->entry());
+  for (size_t i = 0; i < 128; ++i) {
+    int32_t r, x = rng->NextInt();
+    Object* dummy = CALL_GENERATED_CODE(f, &r, x, 0, 0, 0);
+    CHECK_EQ(static_cast<int32_t>(static_cast<int8_t>(x)), r);
+    USE(dummy);
+  }
+}
+
+
+TEST(sxtab) {
+  CcTest::InitializeVM();
+  Isolate* const isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+  RandomNumberGenerator* const rng = isolate->random_number_generator();
+  Assembler assm(isolate, nullptr, 0);
+  __ sxtab(r1, r2, r1);
+  __ str(r1, MemOperand(r0));
+  __ bx(lr);
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  code->Print(std::cout);
+#endif
+  F3 f = FUNCTION_CAST<F3>(code->entry());
+  for (size_t i = 0; i < 128; ++i) {
+    int32_t r, x = rng->NextInt(), y = rng->NextInt();
+    Object* dummy = CALL_GENERATED_CODE(f, &r, x, y, 0, 0);
+    CHECK_EQ(static_cast<int32_t>(static_cast<int8_t>(x)) + y, r);
+    USE(dummy);
+  }
+}
+
+
+TEST(sxth) {
+  CcTest::InitializeVM();
+  Isolate* const isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+  RandomNumberGenerator* const rng = isolate->random_number_generator();
+  Assembler assm(isolate, nullptr, 0);
+  __ sxth(r1, r1);
+  __ str(r1, MemOperand(r0));
+  __ bx(lr);
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  code->Print(std::cout);
+#endif
+  F3 f = FUNCTION_CAST<F3>(code->entry());
+  for (size_t i = 0; i < 128; ++i) {
+    int32_t r, x = rng->NextInt();
+    Object* dummy = CALL_GENERATED_CODE(f, &r, x, 0, 0, 0);
+    CHECK_EQ(static_cast<int32_t>(static_cast<int16_t>(x)), r);
+    USE(dummy);
+  }
+}
+
+
+TEST(sxtah) {
+  CcTest::InitializeVM();
+  Isolate* const isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+  RandomNumberGenerator* const rng = isolate->random_number_generator();
+  Assembler assm(isolate, nullptr, 0);
+  __ sxtah(r1, r2, r1);
+  __ str(r1, MemOperand(r0));
+  __ bx(lr);
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  code->Print(std::cout);
+#endif
+  F3 f = FUNCTION_CAST<F3>(code->entry());
+  for (size_t i = 0; i < 128; ++i) {
+    int32_t r, x = rng->NextInt(), y = rng->NextInt();
+    Object* dummy = CALL_GENERATED_CODE(f, &r, x, y, 0, 0);
+    CHECK_EQ(static_cast<int32_t>(static_cast<int16_t>(x)) + y, r);
+    USE(dummy);
+  }
+}
+
+
+TEST(uxtb) {
+  CcTest::InitializeVM();
+  Isolate* const isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+  RandomNumberGenerator* const rng = isolate->random_number_generator();
+  Assembler assm(isolate, nullptr, 0);
+  __ uxtb(r1, r1);
+  __ str(r1, MemOperand(r0));
+  __ bx(lr);
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  code->Print(std::cout);
+#endif
+  F3 f = FUNCTION_CAST<F3>(code->entry());
+  for (size_t i = 0; i < 128; ++i) {
+    int32_t r, x = rng->NextInt();
+    Object* dummy = CALL_GENERATED_CODE(f, &r, x, 0, 0, 0);
+    CHECK_EQ(static_cast<int32_t>(static_cast<uint8_t>(x)), r);
+    USE(dummy);
+  }
+}
+
+
+TEST(uxtab) {
+  CcTest::InitializeVM();
+  Isolate* const isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+  RandomNumberGenerator* const rng = isolate->random_number_generator();
+  Assembler assm(isolate, nullptr, 0);
+  __ uxtab(r1, r2, r1);
+  __ str(r1, MemOperand(r0));
+  __ bx(lr);
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  code->Print(std::cout);
+#endif
+  F3 f = FUNCTION_CAST<F3>(code->entry());
+  for (size_t i = 0; i < 128; ++i) {
+    int32_t r, x = rng->NextInt(), y = rng->NextInt();
+    Object* dummy = CALL_GENERATED_CODE(f, &r, x, y, 0, 0);
+    CHECK_EQ(static_cast<int32_t>(static_cast<uint8_t>(x)) + y, r);
+    USE(dummy);
+  }
+}
+
+
+TEST(uxth) {
+  CcTest::InitializeVM();
+  Isolate* const isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+  RandomNumberGenerator* const rng = isolate->random_number_generator();
+  Assembler assm(isolate, nullptr, 0);
+  __ uxth(r1, r1);
+  __ str(r1, MemOperand(r0));
+  __ bx(lr);
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  code->Print(std::cout);
+#endif
+  F3 f = FUNCTION_CAST<F3>(code->entry());
+  for (size_t i = 0; i < 128; ++i) {
+    int32_t r, x = rng->NextInt();
+    Object* dummy = CALL_GENERATED_CODE(f, &r, x, 0, 0, 0);
+    CHECK_EQ(static_cast<int32_t>(static_cast<uint16_t>(x)), r);
+    USE(dummy);
+  }
+}
+
+
+TEST(uxtah) {
+  CcTest::InitializeVM();
+  Isolate* const isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+  RandomNumberGenerator* const rng = isolate->random_number_generator();
+  Assembler assm(isolate, nullptr, 0);
+  __ uxtah(r1, r2, r1);
+  __ str(r1, MemOperand(r0));
+  __ bx(lr);
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  code->Print(std::cout);
+#endif
+  F3 f = FUNCTION_CAST<F3>(code->entry());
+  for (size_t i = 0; i < 128; ++i) {
+    int32_t r, x = rng->NextInt(), y = rng->NextInt();
+    Object* dummy = CALL_GENERATED_CODE(f, &r, x, y, 0, 0);
+    CHECK_EQ(static_cast<int32_t>(static_cast<uint16_t>(x)) + y, r);
+    USE(dummy);
+  }
+}
+
+
 TEST(code_relative_offset) {
   // Test extracting the offset of a label from the beginning of the code
   // in a register.
@@ -1565,4 +1884,100 @@
   CHECK_EQ(42, res);
 }
 
+
+TEST(ARMv8_vrintX) {
+  // Test the vrintX floating point instructions.
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+
+  typedef struct {
+    double input;
+    double ar;
+    double nr;
+    double mr;
+    double pr;
+    double zr;
+  } T;
+  T t;
+
+  // Create a function that accepts &t, and loads, manipulates, and stores
+  // the doubles and floats.
+  Assembler assm(isolate, NULL, 0);
+  Label L, C;
+
+
+  if (CpuFeatures::IsSupported(ARMv8)) {
+    CpuFeatureScope scope(&assm, ARMv8);
+
+    __ mov(ip, Operand(sp));
+    __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());
+
+    __ mov(r4, Operand(r0));
+
+    // Test vrinta
+    __ vldr(d6, r4, OFFSET_OF(T, input));
+    __ vrinta(d5, d6);
+    __ vstr(d5, r4, OFFSET_OF(T, ar));
+
+    // Test vrintn
+    __ vldr(d6, r4, OFFSET_OF(T, input));
+    __ vrintn(d5, d6);
+    __ vstr(d5, r4, OFFSET_OF(T, nr));
+
+    // Test vrintp
+    __ vldr(d6, r4, OFFSET_OF(T, input));
+    __ vrintp(d5, d6);
+    __ vstr(d5, r4, OFFSET_OF(T, pr));
+
+    // Test vrintm
+    __ vldr(d6, r4, OFFSET_OF(T, input));
+    __ vrintm(d5, d6);
+    __ vstr(d5, r4, OFFSET_OF(T, mr));
+
+    // Test vrintz
+    __ vldr(d6, r4, OFFSET_OF(T, input));
+    __ vrintz(d5, d6);
+    __ vstr(d5, r4, OFFSET_OF(T, zr));
+
+    __ ldm(ia_w, sp, r4.bit() | fp.bit() | pc.bit());
+
+    CodeDesc desc;
+    assm.GetCode(&desc);
+    Handle<Code> code = isolate->factory()->NewCode(
+        desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef DEBUG
+    OFStream os(stdout);
+    code->Print(os);
+#endif
+    F3 f = FUNCTION_CAST<F3>(code->entry());
+
+    Object* dummy = nullptr;
+    USE(dummy);
+
+#define CHECK_VRINT(input_val, ares, nres, mres, pres, zres) \
+  t.input = input_val;                                       \
+  dummy = CALL_GENERATED_CODE(f, &t, 0, 0, 0, 0);            \
+  CHECK_EQ(ares, t.ar);                                      \
+  CHECK_EQ(nres, t.nr);                                      \
+  CHECK_EQ(mres, t.mr);                                      \
+  CHECK_EQ(pres, t.pr);                                      \
+  CHECK_EQ(zres, t.zr);
+
+    CHECK_VRINT(-0.5, -1.0, -0.0, -1.0, -0.0, -0.0)
+    CHECK_VRINT(-0.6, -1.0, -1.0, -1.0, -0.0, -0.0)
+    CHECK_VRINT(-1.1, -1.0, -1.0, -2.0, -1.0, -1.0)
+    CHECK_VRINT(0.5, 1.0, 0.0, 0.0, 1.0, 0.0)
+    CHECK_VRINT(0.6, 1.0, 1.0, 0.0, 1.0, 0.0)
+    CHECK_VRINT(1.1, 1.0, 1.0, 1.0, 2.0, 1.0)
+    double inf = std::numeric_limits<double>::infinity();
+    CHECK_VRINT(inf, inf, inf, inf, inf, inf)
+    CHECK_VRINT(-inf, -inf, -inf, -inf, -inf, -inf)
+    CHECK_VRINT(-0.0, -0.0, -0.0, -0.0, -0.0, -0.0)
+    double nan = std::numeric_limits<double>::quiet_NaN();
+    CHECK_VRINT(nan, nan, nan, nan, nan, nan)
+
+#undef CHECK_VRINT
+  }
+}
 #undef __
diff --git a/test/cctest/test-assembler-arm64.cc b/test/cctest/test-assembler-arm64.cc
index 587a4ce..108152e 100644
--- a/test/cctest/test-assembler-arm64.cc
+++ b/test/cctest/test-assembler-arm64.cc
@@ -6554,6 +6554,95 @@
 }
 
 
+TEST(frintp) {
+  INIT_V8();
+  SETUP();
+
+  START();
+  __ Fmov(s16, 1.0);
+  __ Fmov(s17, 1.1);
+  __ Fmov(s18, 1.5);
+  __ Fmov(s19, 1.9);
+  __ Fmov(s20, 2.5);
+  __ Fmov(s21, -1.5);
+  __ Fmov(s22, -2.5);
+  __ Fmov(s23, kFP32PositiveInfinity);
+  __ Fmov(s24, kFP32NegativeInfinity);
+  __ Fmov(s25, 0.0);
+  __ Fmov(s26, -0.0);
+  __ Fmov(s27, -0.2);
+
+  __ Frintp(s0, s16);
+  __ Frintp(s1, s17);
+  __ Frintp(s2, s18);
+  __ Frintp(s3, s19);
+  __ Frintp(s4, s20);
+  __ Frintp(s5, s21);
+  __ Frintp(s6, s22);
+  __ Frintp(s7, s23);
+  __ Frintp(s8, s24);
+  __ Frintp(s9, s25);
+  __ Frintp(s10, s26);
+  __ Frintp(s11, s27);
+
+  __ Fmov(d16, -0.5);
+  __ Fmov(d17, -0.8);
+  __ Fmov(d18, 1.5);
+  __ Fmov(d19, 1.9);
+  __ Fmov(d20, 2.5);
+  __ Fmov(d21, -1.5);
+  __ Fmov(d22, -2.5);
+  __ Fmov(d23, kFP32PositiveInfinity);
+  __ Fmov(d24, kFP32NegativeInfinity);
+  __ Fmov(d25, 0.0);
+  __ Fmov(d26, -0.0);
+  __ Fmov(d27, -0.2);
+
+  __ Frintp(d12, d16);
+  __ Frintp(d13, d17);
+  __ Frintp(d14, d18);
+  __ Frintp(d15, d19);
+  __ Frintp(d16, d20);
+  __ Frintp(d17, d21);
+  __ Frintp(d18, d22);
+  __ Frintp(d19, d23);
+  __ Frintp(d20, d24);
+  __ Frintp(d21, d25);
+  __ Frintp(d22, d26);
+  __ Frintp(d23, d27);
+  END();
+
+  RUN();
+
+  CHECK_EQUAL_FP32(1.0, s0);
+  CHECK_EQUAL_FP32(2.0, s1);
+  CHECK_EQUAL_FP32(2.0, s2);
+  CHECK_EQUAL_FP32(2.0, s3);
+  CHECK_EQUAL_FP32(3.0, s4);
+  CHECK_EQUAL_FP32(-1.0, s5);
+  CHECK_EQUAL_FP32(-2.0, s6);
+  CHECK_EQUAL_FP32(kFP32PositiveInfinity, s7);
+  CHECK_EQUAL_FP32(kFP32NegativeInfinity, s8);
+  CHECK_EQUAL_FP32(0.0, s9);
+  CHECK_EQUAL_FP32(-0.0, s10);
+  CHECK_EQUAL_FP32(-0.0, s11);
+  CHECK_EQUAL_FP64(-0.0, d12);
+  CHECK_EQUAL_FP64(-0.0, d13);
+  CHECK_EQUAL_FP64(2.0, d14);
+  CHECK_EQUAL_FP64(2.0, d15);
+  CHECK_EQUAL_FP64(3.0, d16);
+  CHECK_EQUAL_FP64(-1.0, d17);
+  CHECK_EQUAL_FP64(-2.0, d18);
+  CHECK_EQUAL_FP64(kFP64PositiveInfinity, d19);
+  CHECK_EQUAL_FP64(kFP64NegativeInfinity, d20);
+  CHECK_EQUAL_FP64(0.0, d21);
+  CHECK_EQUAL_FP64(-0.0, d22);
+  CHECK_EQUAL_FP64(-0.0, d23);
+
+  TEARDOWN();
+}
+
+
 TEST(frintz) {
   INIT_V8();
   SETUP();
diff --git a/test/cctest/test-assembler-ia32.cc b/test/cctest/test-assembler-ia32.cc
index e8c7f95..f59c3c4 100644
--- a/test/cctest/test-assembler-ia32.cc
+++ b/test/cctest/test-assembler-ia32.cc
@@ -170,11 +170,10 @@
   assm.GetCode(&desc);
   Handle<Code> code = isolate->factory()->NewCode(
       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
-  // don't print the code - our disassembler can't handle cvttss2si
-  // instead print bytes
-  Disassembler::Dump(stdout,
-                     code->instruction_start(),
-                     code->instruction_start() + code->instruction_size());
+#ifdef OBJECT_PRINT
+  OFStream os(stdout);
+  code->Print(os);
+#endif
   F3 f = FUNCTION_CAST<F3>(code->entry());
   int res = f(static_cast<float>(-3.1415));
   ::printf("f() = %d\n", res);
@@ -200,11 +199,10 @@
   assm.GetCode(&desc);
   Handle<Code> code = isolate->factory()->NewCode(
       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
-  // don't print the code - our disassembler can't handle cvttsd2si
-  // instead print bytes
-  Disassembler::Dump(stdout,
-                     code->instruction_start(),
-                     code->instruction_start() + code->instruction_size());
+#ifdef OBJECT_PRINT
+  OFStream os(stdout);
+  code->Print(os);
+#endif
   F4 f = FUNCTION_CAST<F4>(code->entry());
   int res = f(2.718281828);
   ::printf("f() = %d\n", res);
@@ -261,13 +259,9 @@
   assm.GetCode(&desc);
   Handle<Code> code = isolate->factory()->NewCode(
       desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
-#ifdef DEBUG
-  ::printf("\n---\n");
-  // don't print the code - our disassembler can't handle SSE instructions
-  // instead print bytes
-  Disassembler::Dump(stdout,
-                     code->instruction_start(),
-                     code->instruction_start() + code->instruction_size());
+#ifdef OBJECT_PRINT
+  OFStream os(stdout);
+  code->Print(os);
 #endif
   F5 f = FUNCTION_CAST<F5>(code->entry());
   double res = f(2.2, 1.1);
@@ -595,4 +589,458 @@
 }
 
 
+typedef int (*F9)(double x, double y, double z);
+TEST(AssemblerX64FMA_sd) {
+  CcTest::InitializeVM();
+  if (!CpuFeatures::IsSupported(FMA3)) return;
+
+  Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
+  HandleScope scope(isolate);
+  v8::internal::byte buffer[1024];
+  MacroAssembler assm(isolate, buffer, sizeof buffer);
+  {
+    CpuFeatureScope fscope(&assm, FMA3);
+    Label exit;
+    __ movsd(xmm0, Operand(esp, 1 * kPointerSize));
+    __ movsd(xmm1, Operand(esp, 3 * kPointerSize));
+    __ movsd(xmm2, Operand(esp, 5 * kPointerSize));
+    // argument in xmm0, xmm1 and xmm2
+    // xmm0 * xmm1 + xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulsd(xmm3, xmm1);
+    __ addsd(xmm3, xmm2);  // Expected result in xmm3
+
+    __ sub(esp, Immediate(kDoubleSize));  // For memory operand
+    // vfmadd132sd
+    __ mov(eax, Immediate(1));  // Test number
+    __ movaps(xmm4, xmm0);
+    __ vfmadd132sd(xmm4, xmm2, xmm1);
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ vfmadd213sd(xmm4, xmm0, xmm2);
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd231sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ vfmadd231sd(xmm4, xmm0, xmm1);
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfmadd132sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ movsd(Operand(esp, 0), xmm1);
+    __ vfmadd132sd(xmm4, xmm2, Operand(esp, 0));
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ movsd(Operand(esp, 0), xmm2);
+    __ vfmadd213sd(xmm4, xmm0, Operand(esp, 0));
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd231sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ movsd(Operand(esp, 0), xmm1);
+    __ vfmadd231sd(xmm4, xmm0, Operand(esp, 0));
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+    // xmm0 * xmm1 - xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulsd(xmm3, xmm1);
+    __ subsd(xmm3, xmm2);  // Expected result in xmm3
+
+    // vfmsub132sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ vfmsub132sd(xmm4, xmm2, xmm1);
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ vfmsub213sd(xmm4, xmm0, xmm2);
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub231sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ vfmsub231sd(xmm4, xmm0, xmm1);
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfmsub132sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ movsd(Operand(esp, 0), xmm1);
+    __ vfmsub132sd(xmm4, xmm2, Operand(esp, 0));
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub213sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ movsd(Operand(esp, 0), xmm2);
+    __ vfmsub213sd(xmm4, xmm0, Operand(esp, 0));
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub231sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ movsd(Operand(esp, 0), xmm1);
+    __ vfmsub231sd(xmm4, xmm0, Operand(esp, 0));
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+
+    // - xmm0 * xmm1 + xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulsd(xmm3, xmm1);
+    __ Move(xmm4, (uint64_t)1 << 63);
+    __ xorpd(xmm3, xmm4);
+    __ addsd(xmm3, xmm2);  // Expected result in xmm3
+
+    // vfnmadd132sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ vfnmadd132sd(xmm4, xmm2, xmm1);
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ vfnmadd213sd(xmm4, xmm0, xmm2);
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmadd231sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ vfnmadd231sd(xmm4, xmm0, xmm1);
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfnmadd132sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ movsd(Operand(esp, 0), xmm1);
+    __ vfnmadd132sd(xmm4, xmm2, Operand(esp, 0));
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmadd213sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ movsd(Operand(esp, 0), xmm2);
+    __ vfnmadd213sd(xmm4, xmm0, Operand(esp, 0));
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmadd231sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ movsd(Operand(esp, 0), xmm1);
+    __ vfnmadd231sd(xmm4, xmm0, Operand(esp, 0));
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+
+    // - xmm0 * xmm1 - xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulsd(xmm3, xmm1);
+    __ Move(xmm4, (uint64_t)1 << 63);
+    __ xorpd(xmm3, xmm4);
+    __ subsd(xmm3, xmm2);  // Expected result in xmm3
+
+    // vfnmsub132sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ vfnmsub132sd(xmm4, xmm2, xmm1);
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub213sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ vfnmsub213sd(xmm4, xmm0, xmm2);
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmsub231sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ vfnmsub231sd(xmm4, xmm0, xmm1);
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfnmsub132sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ movsd(Operand(esp, 0), xmm1);
+    __ vfnmsub132sd(xmm4, xmm2, Operand(esp, 0));
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmsub213sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ movsd(Operand(esp, 0), xmm2);
+    __ vfnmsub213sd(xmm4, xmm0, Operand(esp, 0));
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmsub231sd
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ movsd(Operand(esp, 0), xmm1);
+    __ vfnmsub231sd(xmm4, xmm0, Operand(esp, 0));
+    __ ucomisd(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+
+    __ xor_(eax, eax);
+    __ bind(&exit);
+    __ add(esp, Immediate(kDoubleSize));
+    __ ret(0);
+  }
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  OFStream os(stdout);
+  code->Print(os);
+#endif
+
+  F9 f = FUNCTION_CAST<F9>(code->entry());
+  CHECK_EQ(0, f(0.000092662107262076, -2.460774966188315, -1.0958787393627414));
+}
+
+
+typedef int (*F10)(float x, float y, float z);
+TEST(AssemblerX64FMA_ss) {
+  CcTest::InitializeVM();
+  if (!CpuFeatures::IsSupported(FMA3)) return;
+
+  Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
+  HandleScope scope(isolate);
+  v8::internal::byte buffer[1024];
+  MacroAssembler assm(isolate, buffer, sizeof buffer);
+  {
+    CpuFeatureScope fscope(&assm, FMA3);
+    Label exit;
+    __ movss(xmm0, Operand(esp, 1 * kPointerSize));
+    __ movss(xmm1, Operand(esp, 2 * kPointerSize));
+    __ movss(xmm2, Operand(esp, 3 * kPointerSize));
+    // arguments in xmm0, xmm1 and xmm2
+    // xmm0 * xmm1 + xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulss(xmm3, xmm1);
+    __ addss(xmm3, xmm2);  // Expected result in xmm3
+
+    __ sub(esp, Immediate(kDoubleSize));  // For memory operand
+    // vfmadd132ss
+    __ mov(eax, Immediate(1));  // Test number
+    __ movaps(xmm4, xmm0);
+    __ vfmadd132ss(xmm4, xmm2, xmm1);
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ vfmadd213ss(xmm4, xmm0, xmm2);
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd231ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ vfmadd231ss(xmm4, xmm0, xmm1);
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfmadd132ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ movss(Operand(esp, 0), xmm1);
+    __ vfmadd132ss(xmm4, xmm2, Operand(esp, 0));
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ movss(Operand(esp, 0), xmm2);
+    __ vfmadd213ss(xmm4, xmm0, Operand(esp, 0));
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd231ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ movss(Operand(esp, 0), xmm1);
+    __ vfmadd231ss(xmm4, xmm0, Operand(esp, 0));
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+    // xmm0 * xmm1 - xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulss(xmm3, xmm1);
+    __ subss(xmm3, xmm2);  // Expected result in xmm3
+
+    // vfmsub132ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ vfmsub132ss(xmm4, xmm2, xmm1);
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ vfmsub213ss(xmm4, xmm0, xmm2);
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub231ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ vfmsub231ss(xmm4, xmm0, xmm1);
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfmsub132ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ movss(Operand(esp, 0), xmm1);
+    __ vfmsub132ss(xmm4, xmm2, Operand(esp, 0));
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub213ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ movss(Operand(esp, 0), xmm2);
+    __ vfmsub213ss(xmm4, xmm0, Operand(esp, 0));
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub231ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ movss(Operand(esp, 0), xmm1);
+    __ vfmsub231ss(xmm4, xmm0, Operand(esp, 0));
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+
+    // - xmm0 * xmm1 + xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulss(xmm3, xmm1);
+    __ Move(xmm4, (uint32_t)1 << 31);
+    __ xorps(xmm3, xmm4);
+    __ addss(xmm3, xmm2);  // Expected result in xmm3
+
+    // vfnmadd132ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ vfnmadd132ss(xmm4, xmm2, xmm1);
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ vfnmadd213ss(xmm4, xmm0, xmm2);
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmadd231ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ vfnmadd231ss(xmm4, xmm0, xmm1);
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfnmadd132ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ movss(Operand(esp, 0), xmm1);
+    __ vfnmadd132ss(xmm4, xmm2, Operand(esp, 0));
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmadd213ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ movss(Operand(esp, 0), xmm2);
+    __ vfnmadd213ss(xmm4, xmm0, Operand(esp, 0));
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmadd231ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ movss(Operand(esp, 0), xmm1);
+    __ vfnmadd231ss(xmm4, xmm0, Operand(esp, 0));
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+
+    // - xmm0 * xmm1 - xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulss(xmm3, xmm1);
+    __ Move(xmm4, (uint32_t)1 << 31);
+    __ xorps(xmm3, xmm4);
+    __ subss(xmm3, xmm2);  // Expected result in xmm3
+
+    // vfnmsub132ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ vfnmsub132ss(xmm4, xmm2, xmm1);
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub213ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ vfnmsub213ss(xmm4, xmm0, xmm2);
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmsub231ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ vfnmsub231ss(xmm4, xmm0, xmm1);
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfnmsub132ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm0);
+    __ movss(Operand(esp, 0), xmm1);
+    __ vfnmsub132ss(xmm4, xmm2, Operand(esp, 0));
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmsub213ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm1);
+    __ movss(Operand(esp, 0), xmm2);
+    __ vfnmsub213ss(xmm4, xmm0, Operand(esp, 0));
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmsub231ss
+    __ inc(eax);
+    __ movaps(xmm4, xmm2);
+    __ movss(Operand(esp, 0), xmm1);
+    __ vfnmsub231ss(xmm4, xmm0, Operand(esp, 0));
+    __ ucomiss(xmm4, xmm3);
+    __ j(not_equal, &exit);
+
+
+    __ xor_(eax, eax);
+    __ bind(&exit);
+    __ add(esp, Immediate(kDoubleSize));
+    __ ret(0);
+  }
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  OFStream os(stdout);
+  code->Print(os);
+#endif
+
+  F10 f = FUNCTION_CAST<F10>(code->entry());
+  CHECK_EQ(0, f(9.26621069e-05f, -2.4607749f, -1.09587872f));
+}
 #undef __
diff --git a/test/cctest/test-assembler-x64.cc b/test/cctest/test-assembler-x64.cc
index 3d305b6..23d0be6 100644
--- a/test/cctest/test-assembler-x64.cc
+++ b/test/cctest/test-assembler-x64.cc
@@ -736,4 +736,454 @@
   F6 f = FUNCTION_CAST<F6>(code->entry());
   CHECK_EQ(2, f(1.0, 2.0));
 }
+
+
+typedef int (*F7)(double x, double y, double z);
+TEST(AssemblerX64FMA_sd) {
+  CcTest::InitializeVM();
+  if (!CpuFeatures::IsSupported(FMA3)) return;
+
+  Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
+  HandleScope scope(isolate);
+  v8::internal::byte buffer[1024];
+  MacroAssembler assm(isolate, buffer, sizeof buffer);
+  {
+    CpuFeatureScope fscope(&assm, FMA3);
+    Label exit;
+    // argument in xmm0, xmm1 and xmm2
+    // xmm0 * xmm1 + xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulsd(xmm3, xmm1);
+    __ addsd(xmm3, xmm2);  // Expected result in xmm3
+
+    __ subq(rsp, Immediate(kDoubleSize));  // For memory operand
+    // vfmadd132sd
+    __ movl(rax, Immediate(1));  // Test number
+    __ movaps(xmm8, xmm0);
+    __ vfmadd132sd(xmm8, xmm2, xmm1);
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ vfmadd213sd(xmm8, xmm0, xmm2);
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd231sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ vfmadd231sd(xmm8, xmm0, xmm1);
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfmadd132sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ movsd(Operand(rsp, 0), xmm1);
+    __ vfmadd132sd(xmm8, xmm2, Operand(rsp, 0));
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ movsd(Operand(rsp, 0), xmm2);
+    __ vfmadd213sd(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd231sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ movsd(Operand(rsp, 0), xmm1);
+    __ vfmadd231sd(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+    // xmm0 * xmm1 - xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulsd(xmm3, xmm1);
+    __ subsd(xmm3, xmm2);  // Expected result in xmm3
+
+    // vfmsub132sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ vfmsub132sd(xmm8, xmm2, xmm1);
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ vfmsub213sd(xmm8, xmm0, xmm2);
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub231sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ vfmsub231sd(xmm8, xmm0, xmm1);
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfmsub132sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ movsd(Operand(rsp, 0), xmm1);
+    __ vfmsub132sd(xmm8, xmm2, Operand(rsp, 0));
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub213sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ movsd(Operand(rsp, 0), xmm2);
+    __ vfmsub213sd(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub231sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ movsd(Operand(rsp, 0), xmm1);
+    __ vfmsub231sd(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+
+    // - xmm0 * xmm1 + xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulsd(xmm3, xmm1);
+    __ Move(xmm4, (uint64_t)1 << 63);
+    __ xorpd(xmm3, xmm4);
+    __ addsd(xmm3, xmm2);  // Expected result in xmm3
+
+    // vfnmadd132sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ vfnmadd132sd(xmm8, xmm2, xmm1);
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ vfnmadd213sd(xmm8, xmm0, xmm2);
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmadd231sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ vfnmadd231sd(xmm8, xmm0, xmm1);
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfnmadd132sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ movsd(Operand(rsp, 0), xmm1);
+    __ vfnmadd132sd(xmm8, xmm2, Operand(rsp, 0));
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmadd213sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ movsd(Operand(rsp, 0), xmm2);
+    __ vfnmadd213sd(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmadd231sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ movsd(Operand(rsp, 0), xmm1);
+    __ vfnmadd231sd(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+
+    // - xmm0 * xmm1 - xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulsd(xmm3, xmm1);
+    __ Move(xmm4, (uint64_t)1 << 63);
+    __ xorpd(xmm3, xmm4);
+    __ subsd(xmm3, xmm2);  // Expected result in xmm3
+
+    // vfnmsub132sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ vfnmsub132sd(xmm8, xmm2, xmm1);
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub213sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ vfnmsub213sd(xmm8, xmm0, xmm2);
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmsub231sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ vfnmsub231sd(xmm8, xmm0, xmm1);
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfnmsub132sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ movsd(Operand(rsp, 0), xmm1);
+    __ vfnmsub132sd(xmm8, xmm2, Operand(rsp, 0));
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmsub213sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ movsd(Operand(rsp, 0), xmm2);
+    __ vfnmsub213sd(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmsub231sd
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ movsd(Operand(rsp, 0), xmm1);
+    __ vfnmsub231sd(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomisd(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+
+    __ xorl(rax, rax);
+    __ bind(&exit);
+    __ addq(rsp, Immediate(kDoubleSize));
+    __ ret(0);
+  }
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  OFStream os(stdout);
+  code->Print(os);
+#endif
+
+  F7 f = FUNCTION_CAST<F7>(code->entry());
+  CHECK_EQ(0, f(0.000092662107262076, -2.460774966188315, -1.0958787393627414));
+}
+
+
+typedef int (*F8)(float x, float y, float z);
+TEST(AssemblerX64FMA_ss) {
+  CcTest::InitializeVM();
+  if (!CpuFeatures::IsSupported(FMA3)) return;
+
+  Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
+  HandleScope scope(isolate);
+  v8::internal::byte buffer[1024];
+  MacroAssembler assm(isolate, buffer, sizeof buffer);
+  {
+    CpuFeatureScope fscope(&assm, FMA3);
+    Label exit;
+    // arguments in xmm0, xmm1 and xmm2
+    // xmm0 * xmm1 + xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulss(xmm3, xmm1);
+    __ addss(xmm3, xmm2);  // Expected result in xmm3
+
+    __ subq(rsp, Immediate(kDoubleSize));  // For memory operand
+    // vfmadd132ss
+    __ movl(rax, Immediate(1));  // Test number
+    __ movaps(xmm8, xmm0);
+    __ vfmadd132ss(xmm8, xmm2, xmm1);
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ vfmadd213ss(xmm8, xmm0, xmm2);
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd231ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ vfmadd231ss(xmm8, xmm0, xmm1);
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfmadd132ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ movss(Operand(rsp, 0), xmm1);
+    __ vfmadd132ss(xmm8, xmm2, Operand(rsp, 0));
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ movss(Operand(rsp, 0), xmm2);
+    __ vfmadd213ss(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd231ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ movss(Operand(rsp, 0), xmm1);
+    __ vfmadd231ss(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+    // xmm0 * xmm1 - xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulss(xmm3, xmm1);
+    __ subss(xmm3, xmm2);  // Expected result in xmm3
+
+    // vfmsub132ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ vfmsub132ss(xmm8, xmm2, xmm1);
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ vfmsub213ss(xmm8, xmm0, xmm2);
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub231ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ vfmsub231ss(xmm8, xmm0, xmm1);
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfmsub132ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ movss(Operand(rsp, 0), xmm1);
+    __ vfmsub132ss(xmm8, xmm2, Operand(rsp, 0));
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub213ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ movss(Operand(rsp, 0), xmm2);
+    __ vfmsub213ss(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub231ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ movss(Operand(rsp, 0), xmm1);
+    __ vfmsub231ss(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+
+    // - xmm0 * xmm1 + xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulss(xmm3, xmm1);
+    __ Move(xmm4, (uint32_t)1 << 31);
+    __ xorps(xmm3, xmm4);
+    __ addss(xmm3, xmm2);  // Expected result in xmm3
+
+    // vfnmadd132ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ vfnmadd132ss(xmm8, xmm2, xmm1);
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmadd213ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ vfnmadd213ss(xmm8, xmm0, xmm2);
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmadd231ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ vfnmadd231ss(xmm8, xmm0, xmm1);
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfnmadd132ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ movss(Operand(rsp, 0), xmm1);
+    __ vfnmadd132ss(xmm8, xmm2, Operand(rsp, 0));
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmadd213ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ movss(Operand(rsp, 0), xmm2);
+    __ vfnmadd213ss(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmadd231ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ movss(Operand(rsp, 0), xmm1);
+    __ vfnmadd231ss(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+
+    // - xmm0 * xmm1 - xmm2
+    __ movaps(xmm3, xmm0);
+    __ mulss(xmm3, xmm1);
+    __ Move(xmm4, (uint32_t)1 << 31);
+    __ xorps(xmm3, xmm4);
+    __ subss(xmm3, xmm2);  // Expected result in xmm3
+
+    // vfnmsub132ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ vfnmsub132ss(xmm8, xmm2, xmm1);
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfmsub213ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ vfnmsub213ss(xmm8, xmm0, xmm2);
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmsub231ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ vfnmsub231ss(xmm8, xmm0, xmm1);
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+    // vfnmsub132ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm0);
+    __ movss(Operand(rsp, 0), xmm1);
+    __ vfnmsub132ss(xmm8, xmm2, Operand(rsp, 0));
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmsub213ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm1);
+    __ movss(Operand(rsp, 0), xmm2);
+    __ vfnmsub213ss(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+    // vfnmsub231ss
+    __ incq(rax);
+    __ movaps(xmm8, xmm2);
+    __ movss(Operand(rsp, 0), xmm1);
+    __ vfnmsub231ss(xmm8, xmm0, Operand(rsp, 0));
+    __ ucomiss(xmm8, xmm3);
+    __ j(not_equal, &exit);
+
+
+    __ xorl(rax, rax);
+    __ bind(&exit);
+    __ addq(rsp, Immediate(kDoubleSize));
+    __ ret(0);
+  }
+
+  CodeDesc desc;
+  assm.GetCode(&desc);
+  Handle<Code> code = isolate->factory()->NewCode(
+      desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+  OFStream os(stdout);
+  code->Print(os);
+#endif
+
+  F8 f = FUNCTION_CAST<F8>(code->entry());
+  CHECK_EQ(0, f(9.26621069e-05f, -2.4607749f, -1.09587872f));
+}
 #undef __
diff --git a/test/cctest/test-ast.cc b/test/cctest/test-ast.cc
index 24819df..096d5c7 100644
--- a/test/cctest/test-ast.cc
+++ b/test/cctest/test-ast.cc
@@ -40,8 +40,8 @@
 
   Isolate* isolate = CcTest::i_isolate();
   Zone zone(isolate);
-  AstNode::IdGen id_gen;
-  AstNodeFactory<AstNullVisitor> factory(&zone, NULL, &id_gen);
+  AstValueFactory value_factory(&zone, 0);
+  AstNodeFactory factory(&value_factory);
   AstNode* node = factory.NewEmptyStatement(RelocInfo::kNoPosition);
   list->Add(node);
   CHECK_EQ(1, list->length());
diff --git a/test/cctest/test-bit-vector.cc b/test/cctest/test-bit-vector.cc
new file mode 100644
index 0000000..ac00fab
--- /dev/null
+++ b/test/cctest/test-bit-vector.cc
@@ -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.
+
+#include <stdlib.h>
+
+#include "src/v8.h"
+
+#include "src/bit-vector.h"
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+
+TEST(BitVector) {
+  Zone zone(CcTest::i_isolate());
+  {
+    BitVector v(15, &zone);
+    v.Add(1);
+    CHECK(v.Contains(1));
+    v.Remove(0);
+    CHECK(!v.Contains(0));
+    v.Add(0);
+    v.Add(1);
+    BitVector w(15, &zone);
+    w.Add(1);
+    v.Intersect(w);
+    CHECK(!v.Contains(0));
+    CHECK(v.Contains(1));
+  }
+
+  {
+    BitVector v(64, &zone);
+    v.Add(27);
+    v.Add(30);
+    v.Add(31);
+    v.Add(33);
+    BitVector::Iterator iter(&v);
+    CHECK_EQ(27, iter.Current());
+    iter.Advance();
+    CHECK_EQ(30, iter.Current());
+    iter.Advance();
+    CHECK_EQ(31, iter.Current());
+    iter.Advance();
+    CHECK_EQ(33, iter.Current());
+    iter.Advance();
+    CHECK(iter.Done());
+  }
+
+  {
+    BitVector v(15, &zone);
+    v.Add(0);
+    BitVector w(15, &zone);
+    w.Add(1);
+    v.Union(w);
+    CHECK(v.Contains(0));
+    CHECK(v.Contains(1));
+  }
+
+  {
+    BitVector v(15, &zone);
+    v.Add(0);
+    BitVector w(15, &zone);
+    w.CopyFrom(v);
+    CHECK(w.Contains(0));
+    w.Add(1);
+    BitVector u(w, &zone);
+    CHECK(u.Contains(0));
+    CHECK(u.Contains(1));
+    v.Union(w);
+    CHECK(v.Contains(0));
+    CHECK(v.Contains(1));
+  }
+
+  {
+    BitVector v(35, &zone);
+    v.Add(0);
+    BitVector w(35, &zone);
+    w.Add(33);
+    v.Union(w);
+    CHECK(v.Contains(0));
+    CHECK(v.Contains(33));
+  }
+
+  {
+    BitVector v(35, &zone);
+    v.Add(32);
+    v.Add(33);
+    BitVector w(35, &zone);
+    w.Add(33);
+    v.Intersect(w);
+    CHECK(!v.Contains(32));
+    CHECK(v.Contains(33));
+    BitVector r(35, &zone);
+    r.CopyFrom(v);
+    CHECK(!r.Contains(32));
+    CHECK(r.Contains(33));
+  }
+}
diff --git a/test/cctest/test-code-stubs-mips64.cc b/test/cctest/test-code-stubs-mips64.cc
index 025a8ba..1f7df38 100644
--- a/test/cctest/test-code-stubs-mips64.cc
+++ b/test/cctest/test-code-stubs-mips64.cc
@@ -104,7 +104,7 @@
   for (--reg_num; reg_num >= 2; --reg_num) {
     Register reg = Register::from_code(reg_num);
     if (!reg.is(destination_reg)) {
-      __ lw(at, MemOperand(sp, 0));
+      __ ld(at, MemOperand(sp, 0));
       __ Assert(eq, kRegisterWasClobbered, reg, Operand(at));
       __ Daddu(sp, sp, Operand(kPointerSize));
     }
diff --git a/test/cctest/test-compiler.cc b/test/cctest/test-compiler.cc
index 4d6e005..a05231e 100644
--- a/test/cctest/test-compiler.cc
+++ b/test/cctest/test-compiler.cc
@@ -306,12 +306,15 @@
   // We shouldn't have deoptimization support. We want to recompile and
   // verify that our feedback vector preserves information.
   CHECK(!f->shared()->has_deoptimization_support());
-  Handle<FixedArray> feedback_vector(f->shared()->feedback_vector());
+  Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector());
 
   // Verify that we gathered feedback.
-  int expected_count = FLAG_vector_ics ? 2 : 1;
-  CHECK_EQ(expected_count, feedback_vector->length());
-  CHECK(feedback_vector->get(expected_count - 1)->IsJSFunction());
+  int expected_slots = 0;
+  int expected_ic_slots = 1;
+  CHECK_EQ(expected_slots, feedback_vector->Slots());
+  CHECK_EQ(expected_ic_slots, feedback_vector->ICSlots());
+  FeedbackVectorICSlot slot_for_a(0);
+  CHECK(feedback_vector->Get(slot_for_a)->IsJSFunction());
 
   CompileRun("%OptimizeFunctionOnNextCall(f); f(fun1);");
 
@@ -319,8 +322,7 @@
   // of the full code.
   CHECK(f->IsOptimized());
   CHECK(f->shared()->has_deoptimization_support());
-  CHECK(f->shared()->feedback_vector()->
-        get(expected_count - 1)->IsJSFunction());
+  CHECK(f->shared()->feedback_vector()->Get(slot_for_a)->IsJSFunction());
 }
 
 
@@ -346,16 +348,19 @@
           *v8::Handle<v8::Function>::Cast(
               CcTest::global()->Get(v8_str("morphing_call"))));
 
-  int expected_count = FLAG_vector_ics ? 2 : 1;
-  CHECK_EQ(expected_count, f->shared()->feedback_vector()->length());
-  // And yet it's not compiled.
+  // Not compiled, and so no feedback vector allocated yet.
   CHECK(!f->shared()->is_compiled());
+  CHECK_EQ(0, f->shared()->feedback_vector()->Slots());
+  CHECK_EQ(0, f->shared()->feedback_vector()->ICSlots());
 
   CompileRun("morphing_call();");
 
-  // The vector should have the same size despite the new scoping.
-  CHECK_EQ(expected_count, f->shared()->feedback_vector()->length());
+  // Now a feedback vector is allocated.
   CHECK(f->shared()->is_compiled());
+  int expected_slots = 0;
+  int expected_ic_slots = FLAG_vector_ics ? 2 : 1;
+  CHECK_EQ(expected_slots, f->shared()->feedback_vector()->Slots());
+  CHECK_EQ(expected_ic_slots, f->shared()->feedback_vector()->ICSlots());
 }
 
 
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index 8d429d2..0e2dd91 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -1064,6 +1064,104 @@
 }
 
 
+// This tests checks distribution of the samples through the source lines.
+TEST(TickLines) {
+  CcTest::InitializeVM();
+  LocalContext env;
+  i::FLAG_turbo_source_positions = true;
+  i::Isolate* isolate = CcTest::i_isolate();
+  i::Factory* factory = isolate->factory();
+  i::HandleScope scope(isolate);
+
+  i::EmbeddedVector<char, 512> script;
+
+  const char* func_name = "func";
+  i::SNPrintF(script,
+              "function %s() {\n"
+              "  var n = 0;\n"
+              "  var m = 100*100;\n"
+              "  while (m > 1) {\n"
+              "    m--;\n"
+              "    n += m * m * m;\n"
+              "  }\n"
+              "}\n"
+              "%s();\n",
+              func_name, func_name);
+
+  CompileRun(script.start());
+
+  i::Handle<i::JSFunction> func = v8::Utils::OpenHandle(
+      *v8::Local<v8::Function>::Cast((*env)->Global()->Get(v8_str(func_name))));
+  CHECK_NE(NULL, func->shared());
+  CHECK_NE(NULL, func->shared()->code());
+  i::Code* code = NULL;
+  if (func->code()->is_optimized_code()) {
+    code = func->code();
+  } else {
+    CHECK(func->shared()->code() == func->code() || !i::FLAG_crankshaft);
+    code = func->shared()->code();
+  }
+  CHECK_NE(NULL, code);
+  i::Address code_address = code->instruction_start();
+  CHECK_NE(NULL, code_address);
+
+  CpuProfilesCollection* profiles = new CpuProfilesCollection(isolate->heap());
+  profiles->StartProfiling("", false);
+  ProfileGenerator generator(profiles);
+  ProfilerEventsProcessor* processor = new ProfilerEventsProcessor(
+      &generator, NULL, v8::base::TimeDelta::FromMicroseconds(100));
+  processor->Start();
+  CpuProfiler profiler(isolate, profiles, &generator, processor);
+
+  // Enqueue code creation events.
+  i::Handle<i::String> str = factory->NewStringFromAsciiChecked(func_name);
+  int line = 1;
+  int column = 1;
+  profiler.CodeCreateEvent(i::Logger::FUNCTION_TAG, code, func->shared(), NULL,
+                           *str, line, column);
+
+  // Enqueue a tick event to enable code events processing.
+  EnqueueTickSampleEvent(processor, code_address);
+
+  processor->StopSynchronously();
+
+  CpuProfile* profile = profiles->StopProfiling("");
+  CHECK_NE(NULL, profile);
+
+  // Check the state of profile generator.
+  CodeEntry* func_entry = generator.code_map()->FindEntry(code_address);
+  CHECK_NE(NULL, func_entry);
+  CHECK_EQ(func_name, func_entry->name());
+  const i::JITLineInfoTable* line_info = func_entry->line_info();
+  CHECK_NE(NULL, line_info);
+  CHECK(!line_info->empty());
+
+  // Check the hit source lines using V8 Public APIs.
+  const i::ProfileTree* tree = profile->top_down();
+  ProfileNode* root = tree->root();
+  CHECK_NE(NULL, root);
+  ProfileNode* func_node = root->FindChild(func_entry);
+  CHECK_NE(NULL, func_node);
+
+  // Add 10 faked ticks to source line #5.
+  int hit_line = 5;
+  int hit_count = 10;
+  for (int i = 0; i < hit_count; i++) func_node->IncrementLineTicks(hit_line);
+
+  unsigned int line_count = func_node->GetHitLineCount();
+  CHECK_EQ(2, line_count);  // Expect two hit source lines - #1 and #5.
+  ScopedVector<v8::CpuProfileNode::LineTick> entries(line_count);
+  CHECK(func_node->GetLineTicks(&entries[0], line_count));
+  int value = 0;
+  for (int i = 0; i < entries.length(); i++)
+    if (entries[i].line == hit_line) {
+      value = entries[i].hit_count;
+      break;
+    }
+  CHECK_EQ(hit_count, value);
+}
+
+
 static const char* call_function_test_source = "function bar(iterations) {\n"
 "}\n"
 "function start(duration) {\n"
diff --git a/test/cctest/test-dataflow.cc b/test/cctest/test-dataflow.cc
deleted file mode 100644
index 43d950d..0000000
--- a/test/cctest/test-dataflow.cc
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <stdlib.h>
-
-#include "src/v8.h"
-
-#include "src/data-flow.h"
-#include "test/cctest/cctest.h"
-
-using namespace v8::internal;
-
-TEST(BitVector) {
-  Zone zone(CcTest::i_isolate());
-  {
-    BitVector v(15, &zone);
-    v.Add(1);
-    CHECK(v.Contains(1));
-    v.Remove(0);
-    CHECK(!v.Contains(0));
-    v.Add(0);
-    v.Add(1);
-    BitVector w(15, &zone);
-    w.Add(1);
-    v.Intersect(w);
-    CHECK(!v.Contains(0));
-    CHECK(v.Contains(1));
-  }
-
-  {
-    BitVector v(64, &zone);
-    v.Add(27);
-    v.Add(30);
-    v.Add(31);
-    v.Add(33);
-    BitVector::Iterator iter(&v);
-    CHECK_EQ(27, iter.Current());
-    iter.Advance();
-    CHECK_EQ(30, iter.Current());
-    iter.Advance();
-    CHECK_EQ(31, iter.Current());
-    iter.Advance();
-    CHECK_EQ(33, iter.Current());
-    iter.Advance();
-    CHECK(iter.Done());
-  }
-
-  {
-    BitVector v(15, &zone);
-    v.Add(0);
-    BitVector w(15, &zone);
-    w.Add(1);
-    v.Union(w);
-    CHECK(v.Contains(0));
-    CHECK(v.Contains(1));
-  }
-
-  {
-    BitVector v(15, &zone);
-    v.Add(0);
-    BitVector w(15, &zone);
-    w = v;
-    CHECK(w.Contains(0));
-    w.Add(1);
-    BitVector u(w, &zone);
-    CHECK(u.Contains(0));
-    CHECK(u.Contains(1));
-    v.Union(w);
-    CHECK(v.Contains(0));
-    CHECK(v.Contains(1));
-  }
-
-  {
-    BitVector v(35, &zone);
-    v.Add(0);
-    BitVector w(35, &zone);
-    w.Add(33);
-    v.Union(w);
-    CHECK(v.Contains(0));
-    CHECK(v.Contains(33));
-  }
-
-  {
-    BitVector v(35, &zone);
-    v.Add(32);
-    v.Add(33);
-    BitVector w(35, &zone);
-    w.Add(33);
-    v.Intersect(w);
-    CHECK(!v.Contains(32));
-    CHECK(v.Contains(33));
-    BitVector r(35, &zone);
-    r.CopyFrom(v);
-    CHECK(!r.Contains(32));
-    CHECK(r.Contains(33));
-  }
-}
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 2f0674a..c3c65fd 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -621,7 +621,7 @@
         last_function_hit[0] = '\0';
       } else {
         CHECK(result->IsString());
-        v8::Handle<v8::String> function_name(result->ToString());
+        v8::Handle<v8::String> function_name(result.As<v8::String>());
         function_name->WriteUtf8(last_function_hit);
       }
     }
@@ -656,7 +656,7 @@
         last_script_name_hit[0] = '\0';
       } else {
         CHECK(result->IsString());
-        v8::Handle<v8::String> script_name(result->ToString());
+        v8::Handle<v8::String> script_name(result.As<v8::String>());
         script_name->WriteUtf8(last_script_name_hit);
       }
     }
@@ -775,7 +775,7 @@
       v8::Handle<v8::Value> result =
           evaluate_check_function->Call(exec_state, argc, argv);
       if (!result->IsTrue()) {
-        v8::String::Utf8Value utf8(checks[i].expected->ToString());
+        v8::String::Utf8Value utf8(checks[i].expected);
         V8_Fatal(__FILE__, __LINE__, "%s != %s", checks[i].expr, *utf8);
       }
     }
@@ -849,7 +849,7 @@
     v8::Handle<v8::Value> result = frame_function_name->Call(exec_state,
                                                              argc, argv);
     CHECK(result->IsString());
-    v8::String::Utf8Value function_name(result->ToString());
+    v8::String::Utf8Value function_name(result->ToString(CcTest::isolate()));
     CHECK_EQ(1, StrLength(*function_name));
     CHECK_EQ((*function_name)[0],
               expected_step_sequence[break_point_hit_count]);
@@ -2860,7 +2860,7 @@
   foo->Call(env->Global(), kArgc, args);
 
   // With stepping all break locations are hit.
-  CHECK_EQ(35, break_point_hit_count);
+  CHECK_EQ(45, break_point_hit_count);
 
   v8::Debug::SetDebugEventListener(NULL);
   CheckDebuggerUnloaded();
@@ -2908,7 +2908,7 @@
   foo->Call(env->Global(), kArgc, args);
 
   // With stepping all break locations are hit.
-  CHECK_EQ(34, break_point_hit_count);
+  CHECK_EQ(44, break_point_hit_count);
 
   v8::Debug::SetDebugEventListener(NULL);
   CheckDebuggerUnloaded();
@@ -2952,7 +2952,7 @@
   foo->Call(env->Global(), 0, NULL);
 
   // With stepping all break locations are hit.
-  CHECK_EQ(55, break_point_hit_count);
+  CHECK_EQ(65, break_point_hit_count);
 
   v8::Debug::SetDebugEventListener(NULL);
   CheckDebuggerUnloaded();
@@ -2995,9 +2995,7 @@
 
 
 // Test of the stepping mechanism for named load in a loop.
-TEST(DebugStepNamedStoreLoop) {
-  DoDebugStepNamedStoreLoop(24);
-}
+TEST(DebugStepNamedStoreLoop) { DoDebugStepNamedStoreLoop(34); }
 
 
 // Test the stepping mechanism with different ICs.
@@ -3330,14 +3328,14 @@
   break_point_hit_count = 0;
   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) };
   foo->Call(env->Global(), argc, argv_10);
-  CHECK_EQ(23, break_point_hit_count);
+  CHECK_EQ(45, break_point_hit_count);
 
   // Looping 100 times.
   step_action = StepIn;
   break_point_hit_count = 0;
   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) };
   foo->Call(env->Global(), argc, argv_100);
-  CHECK_EQ(203, break_point_hit_count);
+  CHECK_EQ(405, break_point_hit_count);
 
   // Get rid of the debug event listener.
   v8::Debug::SetDebugEventListener(NULL);
@@ -3381,7 +3379,7 @@
   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) };
   result = foo->Call(env->Global(), argc, argv_10);
   CHECK_EQ(5, result->Int32Value());
-  CHECK_EQ(52, break_point_hit_count);
+  CHECK_EQ(62, break_point_hit_count);
 
   // Looping 100 times.
   step_action = StepIn;
@@ -3389,7 +3387,7 @@
   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) };
   result = foo->Call(env->Global(), argc, argv_100);
   CHECK_EQ(50, result->Int32Value());
-  CHECK_EQ(457, break_point_hit_count);
+  CHECK_EQ(557, break_point_hit_count);
 
   // Get rid of the debug event listener.
   v8::Debug::SetDebugEventListener(NULL);
@@ -3434,7 +3432,7 @@
   v8::Handle<v8::Value> argv_10[argc] = { v8::Number::New(isolate, 10) };
   result = foo->Call(env->Global(), argc, argv_10);
   CHECK_EQ(9, result->Int32Value());
-  CHECK_EQ(55, break_point_hit_count);
+  CHECK_EQ(64, break_point_hit_count);
 
   // Looping 100 times.
   step_action = StepIn;
@@ -3442,7 +3440,7 @@
   v8::Handle<v8::Value> argv_100[argc] = { v8::Number::New(isolate, 100) };
   result = foo->Call(env->Global(), argc, argv_100);
   CHECK_EQ(99, result->Int32Value());
-  CHECK_EQ(505, break_point_hit_count);
+  CHECK_EQ(604, break_point_hit_count);
 
   // Get rid of the debug event listener.
   v8::Debug::SetDebugEventListener(NULL);
@@ -3473,7 +3471,7 @@
   step_action = StepIn;
   break_point_hit_count = 0;
   foo->Call(env->Global(), 0, NULL);
-  CHECK_EQ(6, break_point_hit_count);
+  CHECK_EQ(8, break_point_hit_count);
 
   // Create a function for testing stepping. Run it to allow it to get
   // optimized.
@@ -3490,7 +3488,7 @@
   step_action = StepIn;
   break_point_hit_count = 0;
   foo->Call(env->Global(), 0, NULL);
-  CHECK_EQ(8, break_point_hit_count);
+  CHECK_EQ(10, break_point_hit_count);
 
   // Get rid of the debug event listener.
   v8::Debug::SetDebugEventListener(NULL);
@@ -4352,9 +4350,10 @@
 }
 
 
-static void NamedGetter(v8::Local<v8::String> name,
+static void NamedGetter(v8::Local<v8::Name> name,
                         const v8::PropertyCallbackInfo<v8::Value>& info) {
-  v8::String::Utf8Value n(name);
+  if (name->IsSymbol()) return;
+  v8::String::Utf8Value n(v8::Local<v8::String>::Cast(name));
   if (strcmp(*n, "a") == 0) {
     info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "AA"));
     return;
@@ -4387,26 +4386,26 @@
 
   // Create object with named interceptor.
   v8::Handle<v8::ObjectTemplate> named = v8::ObjectTemplate::New(isolate);
-  named->SetNamedPropertyHandler(NamedGetter, NULL, NULL, NULL, NamedEnum);
+  named->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      NamedGetter, NULL, NULL, NULL, NamedEnum));
   env->Global()->Set(
       v8::String::NewFromUtf8(isolate, "intercepted_named"),
       named->NewInstance());
 
   // Create object with indexed interceptor.
   v8::Handle<v8::ObjectTemplate> indexed = v8::ObjectTemplate::New(isolate);
-  indexed->SetIndexedPropertyHandler(IndexedGetter,
-                                     NULL,
-                                     NULL,
-                                     NULL,
-                                     IndexedEnum);
+  indexed->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      IndexedGetter, NULL, NULL, NULL, IndexedEnum));
   env->Global()->Set(
       v8::String::NewFromUtf8(isolate, "intercepted_indexed"),
       indexed->NewInstance());
 
   // Create object with both named and indexed interceptor.
   v8::Handle<v8::ObjectTemplate> both = v8::ObjectTemplate::New(isolate);
-  both->SetNamedPropertyHandler(NamedGetter, NULL, NULL, NULL, NamedEnum);
-  both->SetIndexedPropertyHandler(IndexedGetter, NULL, NULL, NULL, IndexedEnum);
+  both->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      NamedGetter, NULL, NULL, NULL, NamedEnum));
+  both->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+      IndexedGetter, NULL, NULL, NULL, IndexedEnum));
   env->Global()->Set(
       v8::String::NewFromUtf8(isolate, "intercepted_both"),
       both->NewInstance());
@@ -5264,6 +5263,7 @@
 
     CompileRun(source);
   }
+  threaded_debugging_barriers.barrier_4.Wait();
   isolate_->Dispose();
 }
 
@@ -5285,6 +5285,7 @@
   threaded_debugging_barriers.barrier_2.Wait();
   v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_1, buffer));
   v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_2, buffer));
+  threaded_debugging_barriers.barrier_4.Wait();
 }
 
 
@@ -5388,6 +5389,7 @@
     breakpoints_barriers->barrier_2.Wait();
     CompileRun(source_2);
   }
+  breakpoints_barriers->barrier_4.Wait();
   isolate_->Dispose();
 }
 
@@ -5503,6 +5505,7 @@
   CHECK_EQ(116, evaluate_int_result);
   // 9: Continue evaluation of source2, reach end.
   v8::Debug::SendCommand(isolate_, buffer, AsciiToUtf16(command_8, buffer));
+  breakpoints_barriers->barrier_4.Wait();
 }
 
 
@@ -6157,7 +6160,8 @@
         last_function_hit[0] = '\0';
       } else {
         CHECK(result->IsString());
-        v8::Handle<v8::String> function_name(result->ToString());
+        v8::Handle<v8::String> function_name(
+            result->ToString(CcTest::isolate()));
         function_name->WriteUtf8(last_function_hit);
       }
     }
@@ -7040,7 +7044,8 @@
       if (!result->IsUndefined()) {
         char fn[80];
         CHECK(result->IsString());
-        v8::Handle<v8::String> function_name(result->ToString());
+        v8::Handle<v8::String> function_name(
+            result->ToString(CcTest::isolate()));
         function_name->WriteUtf8(fn);
         if (strcmp(fn, "bar") == 0) {
           i::Deoptimizer::DeoptimizeAll(CcTest::i_isolate());
@@ -7105,12 +7110,12 @@
         v8::Handle<v8::Value> result =
             frame_function_name->Call(exec_state, argc, argv);
         CHECK(result->IsString());
-        v8::Handle<v8::String> function_name(result->ToString());
+        v8::Handle<v8::String> function_name(result->ToString(isolate));
         CHECK(function_name->Equals(v8::String::NewFromUtf8(isolate, "loop")));
         // Get the name of the first argument in frame i.
         result = frame_argument_name->Call(exec_state, argc, argv);
         CHECK(result->IsString());
-        v8::Handle<v8::String> argument_name(result->ToString());
+        v8::Handle<v8::String> argument_name(result->ToString(isolate));
         CHECK(argument_name->Equals(v8::String::NewFromUtf8(isolate, "count")));
         // Get the value of the first argument in frame i. If the
         // funtion is optimized the value will be undefined, otherwise
@@ -7123,7 +7128,7 @@
         // Get the name of the first local variable.
         result = frame_local_name->Call(exec_state, argc, argv);
         CHECK(result->IsString());
-        v8::Handle<v8::String> local_name(result->ToString());
+        v8::Handle<v8::String> local_name(result->ToString(isolate));
         CHECK(local_name->Equals(v8::String::NewFromUtf8(isolate, "local")));
         // Get the value of the first local variable. If the function
         // is optimized the value will be undefined, otherwise it will
@@ -7518,3 +7523,159 @@
   CompileRun("while (true);");
   CHECK(try_catch.HasTerminated());
 }
+
+
+static void DebugEventExpectNoException(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  CHECK_NE(v8::Exception, event);
+}
+
+
+static void TryCatchWrappedThrowCallback(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  v8::TryCatch try_catch;
+  CompileRun("throw 'rejection';");
+  CHECK(try_catch.HasCaught());
+}
+
+
+TEST(DebugPromiseInterceptedByTryCatch) {
+  DebugLocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+  v8::Debug::SetDebugEventListener(&DebugEventExpectNoException);
+  ChangeBreakOnException(false, true);
+
+  v8::Handle<v8::FunctionTemplate> fun =
+      v8::FunctionTemplate::New(isolate, TryCatchWrappedThrowCallback);
+  env->Global()->Set(v8_str("fun"), fun->GetFunction());
+
+  CompileRun("var p = new Promise(function(res, rej) { fun(); res(); });");
+  CompileRun(
+      "var r;"
+      "p.chain(function() { r = 'resolved'; },"
+      "        function() { r = 'rejected'; });");
+  CHECK(CompileRun("r")->Equals(v8_str("resolved")));
+}
+
+
+static int exception_event_counter = 0;
+
+
+static void DebugEventCountException(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  if (event == v8::Exception) exception_event_counter++;
+}
+
+
+static void ThrowCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
+  CompileRun("throw 'rejection';");
+}
+
+
+TEST(DebugPromiseRejectedByCallback) {
+  DebugLocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+  v8::Debug::SetDebugEventListener(&DebugEventCountException);
+  ChangeBreakOnException(false, true);
+  exception_event_counter = 0;
+
+  v8::Handle<v8::FunctionTemplate> fun =
+      v8::FunctionTemplate::New(isolate, ThrowCallback);
+  env->Global()->Set(v8_str("fun"), fun->GetFunction());
+
+  CompileRun("var p = new Promise(function(res, rej) { fun(); res(); });");
+  CompileRun(
+      "var r;"
+      "p.chain(function() { r = 'resolved'; },"
+      "        function(e) { r = 'rejected' + e; });");
+  CHECK(CompileRun("r")->Equals(v8_str("rejectedrejection")));
+  CHECK_EQ(1, exception_event_counter);
+}
+
+
+TEST(DebugBreakOnExceptionInObserveCallback) {
+  DebugLocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+  v8::Debug::SetDebugEventListener(&DebugEventCountException);
+  // Break on uncaught exception
+  ChangeBreakOnException(false, true);
+  exception_event_counter = 0;
+
+  v8::Handle<v8::FunctionTemplate> fun =
+      v8::FunctionTemplate::New(isolate, ThrowCallback);
+  env->Global()->Set(v8_str("fun"), fun->GetFunction());
+
+  CompileRun(
+      "var obj = {};"
+      "var callbackRan = false;"
+      "Object.observe(obj, function() {"
+      "   callbackRan = true;"
+      "   throw Error('foo');"
+      "});"
+      "obj.prop = 1");
+  CHECK(CompileRun("callbackRan")->BooleanValue());
+  CHECK_EQ(1, exception_event_counter);
+}
+
+
+static void DebugHarmonyScopingListener(
+    const v8::Debug::EventDetails& event_details) {
+  v8::DebugEvent event = event_details.GetEvent();
+  if (event != v8::Break) return;
+
+  int break_id = CcTest::i_isolate()->debug()->break_id();
+
+  char script[128];
+  i::Vector<char> script_vector(script, sizeof(script));
+  SNPrintF(script_vector, "%%GetFrameCount(%d)", break_id);
+  ExpectInt32(script, 1);
+
+  SNPrintF(script_vector, "var frame = new FrameMirror(%d, 0);", break_id);
+  CompileRun(script);
+  ExpectInt32("frame.evaluate('x').value_", 1);
+  ExpectInt32("frame.evaluate('y').value_", 2);
+
+  CompileRun("var allScopes = frame.allScopes()");
+  ExpectInt32("allScopes.length", 2);
+
+  ExpectBoolean("allScopes[0].scopeType() === ScopeType.Script", true);
+
+  ExpectInt32("allScopes[0].scopeObject().value_.x", 1);
+
+  ExpectInt32("allScopes[0].scopeObject().value_.y", 2);
+
+  CompileRun("allScopes[0].setVariableValue('x', 5);");
+  CompileRun("allScopes[0].setVariableValue('y', 6);");
+  ExpectInt32("frame.evaluate('x + y').value_", 11);
+}
+
+
+TEST(DebugBreakInLexicalScopes) {
+  i::FLAG_harmony_scoping = true;
+  i::FLAG_allow_natives_syntax = true;
+
+  DebugLocalContext env;
+  v8::Isolate* isolate = env->GetIsolate();
+  v8::HandleScope scope(isolate);
+  v8::Debug::SetDebugEventListener(DebugHarmonyScopingListener);
+
+  CompileRun(
+      "'use strict';            \n"
+      "let x = 1;               \n");
+  ExpectInt32(
+      "'use strict';            \n"
+      "let y = 2;               \n"
+      "debugger;                \n"
+      "x * y",
+      30);
+  ExpectInt32(
+      "x = 1; y = 2; \n"
+      "debugger;"
+      "x * y",
+      30);
+}
diff --git a/test/cctest/test-decls.cc b/test/cctest/test-decls.cc
index 34f0b69..06afdd2 100644
--- a/test/cctest/test-decls.cc
+++ b/test/cctest/test-decls.cc
@@ -70,9 +70,9 @@
   int query_count() const { return query_count_; }
 
  protected:
-  virtual v8::Handle<Value> Get(Local<String> key);
-  virtual v8::Handle<Value> Set(Local<String> key, Local<Value> value);
-  virtual v8::Handle<Integer> Query(Local<String> key);
+  virtual v8::Handle<Value> Get(Local<Name> key);
+  virtual v8::Handle<Value> Set(Local<Name> key, Local<Value> value);
+  virtual v8::Handle<Integer> Query(Local<Name> key);
 
   void InitializeIfNeeded();
 
@@ -88,12 +88,11 @@
 
   // The handlers are called as static functions that forward
   // to the instance specific virtual methods.
-  static void HandleGet(Local<String> key,
+  static void HandleGet(Local<Name> key,
                         const v8::PropertyCallbackInfo<v8::Value>& info);
-  static void HandleSet(Local<String> key,
-                        Local<Value> value,
+  static void HandleSet(Local<Name> key, Local<Value> value,
                         const v8::PropertyCallbackInfo<v8::Value>& info);
-  static void HandleQuery(Local<String> key,
+  static void HandleQuery(Local<Name> key,
                           const v8::PropertyCallbackInfo<v8::Integer>& info);
 
   v8::Isolate* isolate() const { return CcTest::isolate(); }
@@ -122,11 +121,8 @@
   HandleScope scope(isolate);
   Local<FunctionTemplate> function = FunctionTemplate::New(isolate);
   Local<Value> data = External::New(CcTest::isolate(), this);
-  GetHolder(function)->SetNamedPropertyHandler(&HandleGet,
-                                               &HandleSet,
-                                               &HandleQuery,
-                                               0, 0,
-                                               data);
+  GetHolder(function)->SetHandler(v8::NamedPropertyHandlerConfiguration(
+      &HandleGet, &HandleSet, &HandleQuery, 0, 0, data));
   Local<Context> context = Context::New(isolate,
                                         0,
                                         function->InstanceTemplate(),
@@ -178,8 +174,7 @@
 
 
 void DeclarationContext::HandleGet(
-    Local<String> key,
-    const v8::PropertyCallbackInfo<v8::Value>& info) {
+    Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
   DeclarationContext* context = GetInstance(info.Data());
   context->get_count_++;
   info.GetReturnValue().Set(context->Get(key));
@@ -187,8 +182,7 @@
 
 
 void DeclarationContext::HandleSet(
-    Local<String> key,
-    Local<Value> value,
+    Local<Name> key, Local<Value> value,
     const v8::PropertyCallbackInfo<v8::Value>& info) {
   DeclarationContext* context = GetInstance(info.Data());
   context->set_count_++;
@@ -197,8 +191,7 @@
 
 
 void DeclarationContext::HandleQuery(
-    Local<String> key,
-    const v8::PropertyCallbackInfo<v8::Integer>& info) {
+    Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) {
   DeclarationContext* context = GetInstance(info.Data());
   context->query_count_++;
   info.GetReturnValue().Set(context->Query(key));
@@ -211,18 +204,17 @@
 }
 
 
-v8::Handle<Value> DeclarationContext::Get(Local<String> key) {
+v8::Handle<Value> DeclarationContext::Get(Local<Name> key) {
   return v8::Handle<Value>();
 }
 
 
-v8::Handle<Value> DeclarationContext::Set(Local<String> key,
-                                          Local<Value> value) {
+v8::Handle<Value> DeclarationContext::Set(Local<Name> key, Local<Value> value) {
   return v8::Handle<Value>();
 }
 
 
-v8::Handle<Integer> DeclarationContext::Query(Local<String> key) {
+v8::Handle<Integer> DeclarationContext::Query(Local<Name> key) {
   return v8::Handle<Integer>();
 }
 
@@ -272,7 +264,7 @@
 
 class AbsentPropertyContext: public DeclarationContext {
  protected:
-  virtual v8::Handle<Integer> Query(Local<String> key) {
+  virtual v8::Handle<Integer> Query(Local<Name> key) {
     return v8::Handle<Integer>();
   }
 };
@@ -336,7 +328,7 @@
   AppearingPropertyContext() : state_(DECLARE) { }
 
  protected:
-  virtual v8::Handle<Integer> Query(Local<String> key) {
+  virtual v8::Handle<Integer> Query(Local<Name> key) {
     switch (state_) {
       case DECLARE:
         // Force declaration by returning that the
@@ -405,7 +397,7 @@
  public:
   ExistsInPrototypeContext() { InitializeIfNeeded(); }
  protected:
-  virtual v8::Handle<Integer> Query(Local<String> key) {
+  virtual v8::Handle<Integer> Query(Local<Name> key) {
     // Let it seem that the property exists in the prototype object.
     return Integer::New(isolate(), v8::None);
   }
@@ -464,7 +456,7 @@
 
 class AbsentInPrototypeContext: public DeclarationContext {
  protected:
-  virtual v8::Handle<Integer> Query(Local<String> key) {
+  virtual v8::Handle<Integer> Query(Local<Name> key) {
     // Let it seem that the property is absent in the prototype object.
     return Handle<Integer>();
   }
@@ -499,7 +491,7 @@
   }
 
  protected:
-  virtual v8::Handle<Integer> Query(Local<String> key) {
+  virtual v8::Handle<Integer> Query(Local<Name> key) {
     // Let it seem that the property exists in the hidden prototype object.
     return Integer::New(isolate(), v8::None);
   }
@@ -644,34 +636,212 @@
 }
 
 
-TEST(CrossScriptReferencesHarmony) {
+TEST(CrossScriptReferences_Simple) {
+  i::FLAG_harmony_scoping = true;
   i::FLAG_use_strict = true;
+
+  v8::Isolate* isolate = CcTest::isolate();
+  HandleScope scope(isolate);
+
+  {
+    SimpleContext context;
+    context.Check("let x = 1; x", EXPECT_RESULT, Number::New(isolate, 1));
+    context.Check("let x = 5; x", EXPECT_EXCEPTION);
+  }
+}
+
+
+TEST(CrossScriptReferences_Simple2) {
+  i::FLAG_harmony_scoping = true;
+  i::FLAG_use_strict = true;
+
+  v8::Isolate* isolate = CcTest::isolate();
+  HandleScope scope(isolate);
+
+  for (int k = 0; k < 100; k++) {
+    SimpleContext context;
+    bool cond = (k % 2) == 0;
+    if (cond) {
+      context.Check("let x = 1; x", EXPECT_RESULT, Number::New(isolate, 1));
+      context.Check("let z = 4; z", EXPECT_RESULT, Number::New(isolate, 4));
+    } else {
+      context.Check("let z = 1; z", EXPECT_RESULT, Number::New(isolate, 1));
+      context.Check("let x = 4; x", EXPECT_RESULT, Number::New(isolate, 4));
+    }
+    context.Check("let y = 2; x", EXPECT_RESULT,
+                  Number::New(isolate, cond ? 1 : 4));
+  }
+}
+
+
+TEST(CrossScriptReferencesHarmony) {
   i::FLAG_harmony_scoping = true;
   i::FLAG_harmony_modules = true;
 
   v8::Isolate* isolate = CcTest::isolate();
   HandleScope scope(isolate);
 
+  // Check that simple cross-script global scope access works.
   const char* decs[] = {
-    "var x = 1; x", "x", "this.x",
-    "function x() { return 1 }; x()", "x()", "this.x()",
-    "let x = 1; x", "x", "this.x",
-    "const x = 1; x", "x", "this.x",
-    "module x { export let a = 1 }; x.a", "x.a", "this.x.a",
+    "'use strict'; var x = 1; x", "x",
+    "'use strict'; function x() { return 1 }; x()", "x()",
+    "'use strict'; let x = 1; x", "x",
+    "'use strict'; const x = 1; x", "x",
+    "'use strict'; module x { export let a = 1 }; x.a", "x.a",
     NULL
   };
 
-  for (int i = 0; decs[i] != NULL; i += 3) {
+  for (int i = 0; decs[i] != NULL; i += 2) {
     SimpleContext context;
     context.Check(decs[i], EXPECT_RESULT, Number::New(isolate, 1));
     context.Check(decs[i+1], EXPECT_RESULT, Number::New(isolate, 1));
-    // TODO(rossberg): The current ES6 draft spec does not reflect lexical
-    // bindings on the global object. However, this will probably change, in
-    // which case we reactivate the following test.
-    if (i/3 < 2) {
-      context.Check(decs[i+2], EXPECT_RESULT, Number::New(isolate, 1));
-    }
   }
+
+  // Check that cross-script global scope access works with late declarations.
+  {
+    SimpleContext context;
+    context.Check("function d0() { return x0 }",  // dynamic lookup
+                  EXPECT_RESULT, Undefined(isolate));
+    context.Check("this.x0 = -1;"
+                  "d0()",
+                  EXPECT_RESULT, Number::New(isolate, -1));
+    context.Check("'use strict';"
+                  "function f0() { let y = 10; return x0 + y }"
+                  "function g0() { let y = 10; return eval('x0 + y') }"
+                  "function h0() { let y = 10; return (1,eval)('x0') + y }"
+                  "x0 + f0() + g0() + h0()",
+                  EXPECT_RESULT, Number::New(isolate, 26));
+
+    context.Check("'use strict';"
+                  "let x1 = 1;"
+                  "function f1() { let y = 10; return x1 + y }"
+                  "function g1() { let y = 10; return eval('x1 + y') }"
+                  "function h1() { let y = 10; return (1,eval)('x1') + y }"
+                  "function i1() { "
+                  "  let y = 10; return (typeof x2 === 'undefined' ? 0 : 2) + y"
+                  "}"
+                  "function j1() { let y = 10; return eval('x2 + y') }"
+                  "function k1() { let y = 10; return (1,eval)('x2') + y }"
+                  "function cl() { "
+                  "  let y = 10; "
+                  "  return { "
+                  "    f: function(){ return x1 + y },"
+                  "    g: function(){ return eval('x1 + y') },"
+                  "    h: function(){ return (1,eval)('x1') + y },"
+                  "    i: function(){"
+                  "      return (typeof x2 == 'undefined' ? 0 : 2) + y"
+                  "    },"
+                  "    j: function(){ return eval('x2 + y') },"
+                  "    k: function(){ return (1,eval)('x2') + y },"
+                  "  }"
+                  "}"
+                  "let o = cl();"
+                  "x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
+                  EXPECT_RESULT, Number::New(isolate, 36));
+    context.Check("x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
+                  EXPECT_RESULT, Number::New(isolate, 36));
+    context.Check("o.f() + o.g() + o.h();",
+                  EXPECT_RESULT, Number::New(isolate, 33));
+    context.Check("i1() + o.i();",
+                  EXPECT_RESULT, Number::New(isolate, 20));
+
+    context.Check("'use strict';"
+                  "let x2 = 2;"
+                  "function f2() { let y = 20; return x2 + y }"
+                  "function g2() { let y = 20; return eval('x2 + y') }"
+                  "function h2() { let y = 20; return (1,eval)('x2') + y }"
+                  "function i2() { let y = 20; return x1 + y }"
+                  "function j2() { let y = 20; return eval('x1 + y') }"
+                  "function k2() { let y = 20; return (1,eval)('x1') + y }"
+                  "x2 + eval('x2') + (1,eval)('x2') + f2() + g2() + h2();",
+                  EXPECT_RESULT, Number::New(isolate, 72));
+    context.Check("x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
+                  EXPECT_RESULT, Number::New(isolate, 36));
+    context.Check("i1() + j1() + k1();",
+                  EXPECT_RESULT, Number::New(isolate, 36));
+    context.Check("i2() + j2() + k2();",
+                  EXPECT_RESULT, Number::New(isolate, 63));
+    context.Check("o.f() + o.g() + o.h();",
+                  EXPECT_RESULT, Number::New(isolate, 33));
+    context.Check("o.i() + o.j() + o.k();",
+                  EXPECT_RESULT, Number::New(isolate, 36));
+    context.Check("i1() + o.i();",
+                  EXPECT_RESULT, Number::New(isolate, 24));
+
+    context.Check("'use strict';"
+                  "let x0 = 100;"
+                  "x0 + eval('x0') + (1,eval)('x0') + "
+                  "    d0() + f0() + g0() + h0();",
+                  EXPECT_RESULT, Number::New(isolate, 730));
+    context.Check("x0 + eval('x0') + (1,eval)('x0') + "
+                  "    d0() + f0() + g0() + h0();",
+                  EXPECT_RESULT, Number::New(isolate, 730));
+    context.Check("delete this.x0;"
+                  "x0 + eval('x0') + (1,eval)('x0') + "
+                  "    d0() + f0() + g0() + h0();",
+                  EXPECT_RESULT, Number::New(isolate, 730));
+    context.Check("this.x1 = 666;"
+                  "x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
+                  EXPECT_RESULT, Number::New(isolate, 36));
+    context.Check("delete this.x1;"
+                  "x1 + eval('x1') + (1,eval)('x1') + f1() + g1() + h1();",
+                  EXPECT_RESULT, Number::New(isolate, 36));
+  }
+
+  // Check that caching does respect scopes.
+  {
+    SimpleContext context;
+    const char* script1 = "(function(){ return y1 })()";
+    const char* script2 = "(function(){ return y2 })()";
+
+    context.Check(script1, EXPECT_EXCEPTION);
+    context.Check("this.y1 = 1; this.y2 = 2; 0;",
+                  EXPECT_RESULT, Number::New(isolate, 0));
+    context.Check(script1,
+                  EXPECT_RESULT, Number::New(isolate, 1));
+    context.Check("'use strict'; let y1 = 3; 0;",
+                  EXPECT_RESULT, Number::New(isolate, 0));
+    context.Check(script1,
+                  EXPECT_RESULT, Number::New(isolate, 3));
+    context.Check("y1 = 4;",
+                  EXPECT_RESULT, Number::New(isolate, 4));
+    context.Check(script1,
+                  EXPECT_RESULT, Number::New(isolate, 4));
+
+    context.Check(script2,
+                  EXPECT_RESULT, Number::New(isolate, 2));
+    context.Check("'use strict'; let y2 = 5; 0;",
+                  EXPECT_RESULT, Number::New(isolate, 0));
+    context.Check(script1,
+                  EXPECT_RESULT, Number::New(isolate, 4));
+    context.Check(script2,
+                  EXPECT_RESULT, Number::New(isolate, 5));
+  }
+}
+
+
+TEST(GlobalLexicalOSR) {
+  i::FLAG_use_strict = true;
+  i::FLAG_harmony_scoping = true;
+  i::FLAG_harmony_modules = true;
+
+  v8::Isolate* isolate = CcTest::isolate();
+  HandleScope scope(isolate);
+  SimpleContext context;
+
+  context.Check("'use strict';"
+                "let x = 1; x;",
+                EXPECT_RESULT, Number::New(isolate, 1));
+  context.Check("'use strict';"
+                "let y = 2*x;"
+                "++x;"
+                "let z = 0;"
+                "const limit = 100000;"
+                "for (var i = 0; i < limit; ++i) {"
+                "  z += x + y;"
+                "}"
+                "z;",
+                EXPECT_RESULT, Number::New(isolate, 400000));
 }
 
 
@@ -704,12 +874,280 @@
       SimpleContext context;
       context.Check(firsts[i], EXPECT_RESULT,
                     Number::New(CcTest::isolate(), 1));
-      // TODO(rossberg): All tests should actually be errors in Harmony,
-      // but we currently do not detect the cases where the first declaration
-      // is not lexical.
-      context.Check(seconds[j],
-                    i < 2 ? EXPECT_RESULT : EXPECT_ERROR,
-                    Number::New(CcTest::isolate(), 2));
+      bool success_case = i < 2 && j < 2;
+      Local<Value> success_result;
+      if (success_case) success_result = Number::New(CcTest::isolate(), 2);
+
+      context.Check(seconds[j], success_case ? EXPECT_RESULT : EXPECT_EXCEPTION,
+                    success_result);
     }
   }
 }
+
+
+TEST(CrossScriptDynamicLookup) {
+  i::FLAG_harmony_scoping = true;
+
+  HandleScope handle_scope(CcTest::isolate());
+
+  {
+    SimpleContext context;
+    Local<String> undefined_string = String::NewFromUtf8(
+        CcTest::isolate(), "undefined", String::kInternalizedString);
+    Local<String> number_string = String::NewFromUtf8(
+        CcTest::isolate(), "number", String::kInternalizedString);
+
+    context.Check(
+        "function f(o) { with(o) { return x; } }"
+        "function g(o) { with(o) { x = 15; } }"
+        "function h(o) { with(o) { return typeof x; } }",
+        EXPECT_RESULT, Undefined(CcTest::isolate()));
+    context.Check("h({})", EXPECT_RESULT, undefined_string);
+    context.Check(
+        "'use strict';"
+        "let x = 1;"
+        "f({})",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
+    context.Check(
+        "'use strict';"
+        "g({});0",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 0));
+    context.Check("f({})", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
+    context.Check("h({})", EXPECT_RESULT, number_string);
+  }
+}
+
+
+TEST(CrossScriptGlobal) {
+  i::FLAG_harmony_scoping = true;
+
+  HandleScope handle_scope(CcTest::isolate());
+  {
+    SimpleContext context;
+
+    context.Check(
+        "var global = this;"
+        "global.x = 255;"
+        "x",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 255));
+    context.Check(
+        "'use strict';"
+        "let x = 1;"
+        "global.x",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 255));
+    context.Check("global.x = 15; x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 1));
+    context.Check("x = 221; global.x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 15));
+    context.Check(
+        "z = 15;"
+        "function f() { return z; };"
+        "for (var k = 0; k < 3; k++) { f(); }"
+        "f()",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
+    context.Check(
+        "'use strict';"
+        "let z = 5; f()",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
+    context.Check(
+        "function f() { konst = 10; return konst; };"
+        "f()",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 10));
+    context.Check(
+        "'use strict';"
+        "const konst = 255;"
+        "f()",
+        EXPECT_EXCEPTION);
+  }
+}
+
+
+TEST(CrossScriptStaticLookupUndeclared) {
+  i::FLAG_harmony_scoping = true;
+
+  HandleScope handle_scope(CcTest::isolate());
+
+  {
+    SimpleContext context;
+    Local<String> undefined_string = String::NewFromUtf8(
+        CcTest::isolate(), "undefined", String::kInternalizedString);
+    Local<String> number_string = String::NewFromUtf8(
+        CcTest::isolate(), "number", String::kInternalizedString);
+
+    context.Check(
+        "function f(o) { return x; }"
+        "function g(v) { x = v; }"
+        "function h(o) { return typeof x; }",
+        EXPECT_RESULT, Undefined(CcTest::isolate()));
+    context.Check("h({})", EXPECT_RESULT, undefined_string);
+    context.Check(
+        "'use strict';"
+        "let x = 1;"
+        "f({})",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
+    context.Check(
+        "'use strict';"
+        "g(15);x",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
+    context.Check("h({})", EXPECT_RESULT, number_string);
+    context.Check("f({})", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
+    context.Check("h({})", EXPECT_RESULT, number_string);
+  }
+}
+
+
+TEST(CrossScriptLoadICs) {
+  i::FLAG_harmony_scoping = true;
+  i::FLAG_allow_natives_syntax = true;
+
+  HandleScope handle_scope(CcTest::isolate());
+
+  {
+    SimpleContext context;
+    context.Check(
+        "x = 15;"
+        "function f() { return x; }"
+        "function g() { return x; }"
+        "f()",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
+    context.Check(
+        "'use strict';"
+        "let x = 5;"
+        "f()",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
+    for (int k = 0; k < 3; k++) {
+      context.Check("g()", EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
+    }
+    for (int k = 0; k < 3; k++) {
+      context.Check("f()", EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
+    }
+    context.Check("%OptimizeFunctionOnNextCall(g); g()", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 5));
+    context.Check("%OptimizeFunctionOnNextCall(f); f()", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 5));
+  }
+  {
+    SimpleContext context;
+    context.Check(
+        "x = 15;"
+        "function f() { return x; }"
+        "f()",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
+    for (int k = 0; k < 3; k++) {
+      context.Check("f()", EXPECT_RESULT, Number::New(CcTest::isolate(), 15));
+    }
+    context.Check("%OptimizeFunctionOnNextCall(f); f()", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 15));
+    context.Check(
+        "'use strict';"
+        "let x = 5;"
+        "f()",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
+    for (int k = 0; k < 3; k++) {
+      context.Check("f()", EXPECT_RESULT, Number::New(CcTest::isolate(), 5));
+    }
+    context.Check("%OptimizeFunctionOnNextCall(f); f()", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 5));
+  }
+}
+
+
+TEST(CrossScriptStoreICs) {
+  i::FLAG_harmony_scoping = true;
+  i::FLAG_allow_natives_syntax = true;
+
+  HandleScope handle_scope(CcTest::isolate());
+
+  {
+    SimpleContext context;
+    context.Check(
+        "var global = this;"
+        "x = 15;"
+        "function f(v) { x = v; }"
+        "function g(v) { x = v; }"
+        "f(10); x",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 10));
+    context.Check(
+        "'use strict';"
+        "let x = 5;"
+        "f(7); x",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 7));
+    context.Check("global.x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 10));
+    for (int k = 0; k < 3; k++) {
+      context.Check("g(31); x", EXPECT_RESULT,
+                    Number::New(CcTest::isolate(), 31));
+    }
+    context.Check("global.x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 10));
+    for (int k = 0; k < 3; k++) {
+      context.Check("f(32); x", EXPECT_RESULT,
+                    Number::New(CcTest::isolate(), 32));
+    }
+    context.Check("global.x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 10));
+    context.Check("%OptimizeFunctionOnNextCall(g); g(18); x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 18));
+    context.Check("global.x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 10));
+    context.Check("%OptimizeFunctionOnNextCall(f); f(33); x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 33));
+    context.Check("global.x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 10));
+  }
+  {
+    SimpleContext context;
+    context.Check(
+        "var global = this;"
+        "x = 15;"
+        "function f(v) { x = v; }"
+        "f(10); x",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 10));
+    for (int k = 0; k < 3; k++) {
+      context.Check("f(18); x", EXPECT_RESULT,
+                    Number::New(CcTest::isolate(), 18));
+    }
+    context.Check("%OptimizeFunctionOnNextCall(f); f(20); x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 20));
+    context.Check(
+        "'use strict';"
+        "let x = 5;"
+        "f(8); x",
+        EXPECT_RESULT, Number::New(CcTest::isolate(), 8));
+    context.Check("global.x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 20));
+    for (int k = 0; k < 3; k++) {
+      context.Check("f(13); x", EXPECT_RESULT,
+                    Number::New(CcTest::isolate(), 13));
+    }
+    context.Check("global.x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 20));
+    context.Check("%OptimizeFunctionOnNextCall(f); f(41); x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 41));
+    context.Check("global.x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 20));
+  }
+}
+
+
+TEST(CrossScriptAssignmentToConst) {
+  i::FLAG_harmony_scoping = true;
+  i::FLAG_allow_natives_syntax = true;
+
+  HandleScope handle_scope(CcTest::isolate());
+
+  {
+    SimpleContext context;
+
+    context.Check("function f() { x = 27; }", EXPECT_RESULT,
+                  Undefined(CcTest::isolate()));
+    context.Check("'use strict';const x = 1; x", EXPECT_RESULT,
+                  Number::New(CcTest::isolate(), 1));
+    context.Check("f();", EXPECT_EXCEPTION);
+    context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
+    context.Check("f();", EXPECT_EXCEPTION);
+    context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
+    context.Check("%OptimizeFunctionOnNextCall(f);f();", EXPECT_EXCEPTION);
+    context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1));
+  }
+}
diff --git a/test/cctest/test-disasm-arm.cc b/test/cctest/test-disasm-arm.cc
index c1f6ce2..095c636 100644
--- a/test/cctest/test-disasm-arm.cc
+++ b/test/cctest/test-disasm-arm.cc
@@ -410,16 +410,40 @@
             "e6843895       pkhbt r3, r4, r5, lsl #17");
     COMPARE(pkhtb(r3, r4, Operand(r5, ASR, 17)),
             "e68438d5       pkhtb r3, r4, r5, asr #17");
-    COMPARE(uxtb(r9, Operand(r10, ROR, 0)),
-            "e6ef907a       uxtb r9, r10");
-    COMPARE(uxtb(r3, Operand(r4, ROR, 8)),
-            "e6ef3474       uxtb r3, r4, ror #8");
-    COMPARE(uxtab(r3, r4, Operand(r5, ROR, 8)),
-            "e6e43475       uxtab r3, r4, r5, ror #8");
-    COMPARE(uxtb16(r3, Operand(r4, ROR, 8)),
-            "e6cf3474       uxtb16 r3, r4, ror #8");
+
+    COMPARE(sxtb(r1, r7, 0, eq), "06af1077       sxtbeq r1, r7");
+    COMPARE(sxtb(r0, r0, 8, ne), "16af0470       sxtbne r0, r0, ror #8");
+    COMPARE(sxtb(r9, r10, 16), "e6af987a       sxtb r9, r10, ror #16");
+    COMPARE(sxtb(r4, r3, 24), "e6af4c73       sxtb r4, r3, ror #24");
+
+    COMPARE(sxtab(r3, r4, r5), "e6a43075       sxtab r3, r4, r5");
+
+    COMPARE(sxth(r5, r0), "e6bf5070       sxth r5, r0");
+    COMPARE(sxth(r5, r9, 8), "e6bf5479       sxth r5, r9, ror #8");
+    COMPARE(sxth(r5, r9, 16, hi), "86bf5879       sxthhi r5, r9, ror #16");
+    COMPARE(sxth(r8, r9, 24, cc), "36bf8c79       sxthcc r8, r9, ror #24");
+
+    COMPARE(sxtah(r3, r4, r5, 16), "e6b43875       sxtah r3, r4, r5, ror #16");
+
+    COMPARE(uxtb(r9, r10), "e6ef907a       uxtb r9, r10");
+    COMPARE(uxtb(r3, r4, 8), "e6ef3474       uxtb r3, r4, ror #8");
+
+    COMPARE(uxtab(r3, r4, r5, 8), "e6e43475       uxtab r3, r4, r5, ror #8");
+
+    COMPARE(uxtb16(r3, r4, 8), "e6cf3474       uxtb16 r3, r4, ror #8");
+
+    COMPARE(uxth(r9, r10), "e6ff907a       uxth r9, r10");
+    COMPARE(uxth(r3, r4, 8), "e6ff3474       uxth r3, r4, ror #8");
+
+    COMPARE(uxtah(r3, r4, r5, 24), "e6f43c75       uxtah r3, r4, r5, ror #24");
   }
 
+  COMPARE(smmla(r0, r1, r2, r3), "e7503211       smmla r0, r1, r2, r3");
+  COMPARE(smmla(r10, r9, r8, r7), "e75a7819       smmla r10, r9, r8, r7");
+
+  COMPARE(smmul(r0, r1, r2), "e750f211       smmul r0, r1, r2");
+  COMPARE(smmul(r8, r9, r10), "e758fa19       smmul r8, r9, r10");
+
   VERIFY_RUN();
 }
 
@@ -680,6 +704,30 @@
 }
 
 
+TEST(ARMv8_vrintX_disasm) {
+  SET_UP();
+
+  if (CpuFeatures::IsSupported(ARMv8)) {
+    COMPARE(vrinta(d0, d0), "feb80b40       vrinta.f64.f64 d0, d0");
+    COMPARE(vrinta(d2, d3), "feb82b43       vrinta.f64.f64 d2, d3");
+
+    COMPARE(vrintp(d0, d0), "feba0b40       vrintp.f64.f64 d0, d0");
+    COMPARE(vrintp(d2, d3), "feba2b43       vrintp.f64.f64 d2, d3");
+
+    COMPARE(vrintn(d0, d0), "feb90b40       vrintn.f64.f64 d0, d0");
+    COMPARE(vrintn(d2, d3), "feb92b43       vrintn.f64.f64 d2, d3");
+
+    COMPARE(vrintm(d0, d0), "febb0b40       vrintm.f64.f64 d0, d0");
+    COMPARE(vrintm(d2, d3), "febb2b43       vrintm.f64.f64 d2, d3");
+
+    COMPARE(vrintz(d0, d0), "eeb60bc0       vrintz.f64.f64 d0, d0");
+    COMPARE(vrintz(d2, d3, ne), "1eb62bc3       vrintzne.f64.f64 d2, d3");
+  }
+
+  VERIFY_RUN();
+}
+
+
 TEST(Neon) {
   SET_UP();
 
diff --git a/test/cctest/test-disasm-arm64.cc b/test/cctest/test-disasm-arm64.cc
index fb01347..208f1f5 100644
--- a/test/cctest/test-disasm-arm64.cc
+++ b/test/cctest/test-disasm-arm64.cc
@@ -1408,6 +1408,10 @@
   COMPARE(frintn(s31, s30), "frintn s31, s30");
   COMPARE(frintn(d12, d13), "frintn d12, d13");
   COMPARE(frintn(d31, d30), "frintn d31, d30");
+  COMPARE(frintp(s10, s11), "frintp s10, s11");
+  COMPARE(frintp(s31, s30), "frintp s31, s30");
+  COMPARE(frintp(d12, d13), "frintp d12, d13");
+  COMPARE(frintp(d31, d30), "frintp d31, d30");
   COMPARE(frintz(s10, s11), "frintz s10, s11");
   COMPARE(frintz(s31, s30), "frintz s31, s30");
   COMPARE(frintz(d12, d13), "frintz d12, d13");
diff --git a/test/cctest/test-disasm-ia32.cc b/test/cctest/test-disasm-ia32.cc
index 49088f6..a2eaa15 100644
--- a/test/cctest/test-disasm-ia32.cc
+++ b/test/cctest/test-disasm-ia32.cc
@@ -51,7 +51,7 @@
   CcTest::InitializeVM();
   Isolate* isolate = CcTest::i_isolate();
   HandleScope scope(isolate);
-  v8::internal::byte buffer[2048];
+  v8::internal::byte buffer[4096];
   Assembler assm(isolate, buffer, sizeof buffer);
   DummyStaticFunction(NULL);  // just bloody use it (DELETE; debugging)
 
@@ -201,6 +201,12 @@
   __ rcl(edx, 7);
   __ rcr(edx, 1);
   __ rcr(edx, 7);
+  __ ror(edx, 1);
+  __ ror(edx, 6);
+  __ ror_cl(edx);
+  __ ror(Operand(ebx, ecx, times_4, 10000), 1);
+  __ ror(Operand(ebx, ecx, times_4, 10000), 6);
+  __ ror_cl(Operand(ebx, ecx, times_4, 10000));
   __ sar(edx, 1);
   __ sar(edx, 6);
   __ sar_cl(edx);
@@ -383,6 +389,8 @@
     // Move operation
     __ movaps(xmm0, xmm1);
     __ shufps(xmm0, xmm0, 0x0);
+    __ cvtsd2ss(xmm0, xmm1);
+    __ cvtsd2ss(xmm0, Operand(ebx, ecx, times_4, 10000));
 
     // logic operation
     __ andps(xmm0, xmm1);
@@ -393,6 +401,14 @@
     __ xorps(xmm0, Operand(ebx, ecx, times_4, 10000));
 
     // Arithmetic operation
+    __ addss(xmm1, xmm0);
+    __ addss(xmm1, Operand(ebx, ecx, times_4, 10000));
+    __ mulss(xmm1, xmm0);
+    __ mulss(xmm1, Operand(ebx, ecx, times_4, 10000));
+    __ subss(xmm1, xmm0);
+    __ subss(xmm1, Operand(ebx, ecx, times_4, 10000));
+    __ divss(xmm1, xmm0);
+    __ divss(xmm1, Operand(ebx, ecx, times_4, 10000));
     __ addps(xmm1, xmm0);
     __ addps(xmm1, Operand(ebx, ecx, times_4, 10000));
     __ subps(xmm1, xmm0);
@@ -401,10 +417,15 @@
     __ mulps(xmm1, Operand(ebx, ecx, times_4, 10000));
     __ divps(xmm1, xmm0);
     __ divps(xmm1, Operand(ebx, ecx, times_4, 10000));
+
+    __ ucomiss(xmm0, xmm1);
+    __ ucomiss(xmm0, Operand(ebx, ecx, times_4, 10000));
   }
   {
     __ cvttss2si(edx, Operand(ebx, ecx, times_4, 10000));
     __ cvtsi2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
+    __ cvtss2sd(xmm1, Operand(ebx, ecx, times_4, 10000));
+    __ cvtss2sd(xmm1, xmm0);
     __ movsd(xmm1, Operand(ebx, ecx, times_4, 10000));
     __ movsd(Operand(ebx, ecx, times_4, 10000), xmm1);
     // 128 bit move instructions.
@@ -414,10 +435,13 @@
     __ movdqu(Operand(ebx, ecx, times_4, 10000), xmm0);
 
     __ addsd(xmm1, xmm0);
+    __ addsd(xmm1, Operand(ebx, ecx, times_4, 10000));
     __ mulsd(xmm1, xmm0);
+    __ mulsd(xmm1, Operand(ebx, ecx, times_4, 10000));
     __ subsd(xmm1, xmm0);
     __ subsd(xmm1, Operand(ebx, ecx, times_4, 10000));
     __ divsd(xmm1, xmm0);
+    __ divsd(xmm1, Operand(ebx, ecx, times_4, 10000));
     __ ucomisd(xmm0, xmm1);
     __ cmpltsd(xmm0, xmm1);
 
@@ -458,6 +482,83 @@
     }
   }
 
+  // AVX instruction
+  {
+    if (CpuFeatures::IsSupported(AVX)) {
+      CpuFeatureScope scope(&assm, AVX);
+      __ vaddsd(xmm0, xmm1, xmm2);
+      __ vaddsd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vmulsd(xmm0, xmm1, xmm2);
+      __ vmulsd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vsubsd(xmm0, xmm1, xmm2);
+      __ vsubsd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vdivsd(xmm0, xmm1, xmm2);
+      __ vdivsd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+    }
+  }
+
+  // FMA3 instruction
+  {
+    if (CpuFeatures::IsSupported(FMA3)) {
+      CpuFeatureScope scope(&assm, FMA3);
+      __ vfmadd132sd(xmm0, xmm1, xmm2);
+      __ vfmadd132sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfmadd213sd(xmm0, xmm1, xmm2);
+      __ vfmadd213sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfmadd231sd(xmm0, xmm1, xmm2);
+      __ vfmadd231sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+
+      __ vfmsub132sd(xmm0, xmm1, xmm2);
+      __ vfmsub132sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfmsub213sd(xmm0, xmm1, xmm2);
+      __ vfmsub213sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfmsub231sd(xmm0, xmm1, xmm2);
+      __ vfmsub231sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+
+      __ vfnmadd132sd(xmm0, xmm1, xmm2);
+      __ vfnmadd132sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfnmadd213sd(xmm0, xmm1, xmm2);
+      __ vfnmadd213sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfnmadd231sd(xmm0, xmm1, xmm2);
+      __ vfnmadd231sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+
+      __ vfnmsub132sd(xmm0, xmm1, xmm2);
+      __ vfnmsub132sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfnmsub213sd(xmm0, xmm1, xmm2);
+      __ vfnmsub213sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfnmsub231sd(xmm0, xmm1, xmm2);
+      __ vfnmsub231sd(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+
+      __ vfmadd132ss(xmm0, xmm1, xmm2);
+      __ vfmadd132ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfmadd213ss(xmm0, xmm1, xmm2);
+      __ vfmadd213ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfmadd231ss(xmm0, xmm1, xmm2);
+      __ vfmadd231ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+
+      __ vfmsub132ss(xmm0, xmm1, xmm2);
+      __ vfmsub132ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfmsub213ss(xmm0, xmm1, xmm2);
+      __ vfmsub213ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfmsub231ss(xmm0, xmm1, xmm2);
+      __ vfmsub231ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+
+      __ vfnmadd132ss(xmm0, xmm1, xmm2);
+      __ vfnmadd132ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfnmadd213ss(xmm0, xmm1, xmm2);
+      __ vfnmadd213ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfnmadd231ss(xmm0, xmm1, xmm2);
+      __ vfnmadd231ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+
+      __ vfnmsub132ss(xmm0, xmm1, xmm2);
+      __ vfnmsub132ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfnmsub213ss(xmm0, xmm1, xmm2);
+      __ vfnmsub213ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+      __ vfnmsub231ss(xmm0, xmm1, xmm2);
+      __ vfnmsub231ss(xmm0, xmm1, Operand(ebx, ecx, times_4, 10000));
+    }
+  }
+
   // xchg.
   {
     __ xchg(eax, eax);
diff --git a/test/cctest/test-disasm-x64.cc b/test/cctest/test-disasm-x64.cc
index e756ce2..6cd58ec 100644
--- a/test/cctest/test-disasm-x64.cc
+++ b/test/cctest/test-disasm-x64.cc
@@ -51,7 +51,7 @@
   CcTest::InitializeVM();
   Isolate* isolate = CcTest::i_isolate();
   HandleScope scope(isolate);
-  v8::internal::byte buffer[2048];
+  v8::internal::byte buffer[4096];
   Assembler assm(isolate, buffer, sizeof buffer);
   DummyStaticFunction(NULL);  // just bloody use it (DELETE; debugging)
 
@@ -117,6 +117,26 @@
   __ imulq(rdx, rcx);
   __ shld(rdx, rcx);
   __ shrd(rdx, rcx);
+  __ shlq(Operand(rdi, rax, times_4, 100), Immediate(1));
+  __ shlq(Operand(rdi, rax, times_4, 100), Immediate(6));
+  __ shlq(Operand(r15, 0), Immediate(1));
+  __ shlq(Operand(r15, 0), Immediate(6));
+  __ shlq_cl(Operand(r15, 0));
+  __ shlq_cl(Operand(r15, 0));
+  __ shlq_cl(Operand(rdi, rax, times_4, 100));
+  __ shlq_cl(Operand(rdi, rax, times_4, 100));
+  __ shlq(rdx, Immediate(1));
+  __ shlq(rdx, Immediate(6));
+  __ shll(Operand(rdi, rax, times_4, 100), Immediate(1));
+  __ shll(Operand(rdi, rax, times_4, 100), Immediate(6));
+  __ shll(Operand(r15, 0), Immediate(1));
+  __ shll(Operand(r15, 0), Immediate(6));
+  __ shll_cl(Operand(r15, 0));
+  __ shll_cl(Operand(r15, 0));
+  __ shll_cl(Operand(rdi, rax, times_4, 100));
+  __ shll_cl(Operand(rdi, rax, times_4, 100));
+  __ shll(rdx, Immediate(1));
+  __ shll(rdx, Immediate(6));
   __ bts(Operand(rdx, 0), rcx);
   __ bts(Operand(rbx, rcx, times_4, 0), rcx);
   __ nop();
@@ -159,14 +179,22 @@
 
   __ nop();
   __ idivq(rdx);
-  __ mul(rdx);
+  __ mull(rdx);
+  __ mulq(rdx);
   __ negq(rdx);
   __ notq(rdx);
   __ testq(Operand(rbx, rcx, times_4, 10000), rdx);
 
-  __ imulq(rdx, Operand(rbx, rcx, times_4, 10000));
   __ imulq(rdx, rcx, Immediate(12));
   __ imulq(rdx, rcx, Immediate(1000));
+  __ imulq(rdx, Operand(rbx, rcx, times_4, 10000));
+  __ imulq(rdx, Operand(rbx, rcx, times_4, 10000), Immediate(12));
+  __ imulq(rdx, Operand(rbx, rcx, times_4, 10000), Immediate(1000));
+  __ imull(r15, rcx, Immediate(12));
+  __ imull(r15, rcx, Immediate(1000));
+  __ imull(r15, Operand(rbx, rcx, times_4, 10000));
+  __ imull(r15, Operand(rbx, rcx, times_4, 10000), Immediate(12));
+  __ imull(r15, Operand(rbx, rcx, times_4, 10000), Immediate(1000));
 
   __ incq(rdx);
   __ incq(Operand(rbx, rcx, times_4, 10000));
@@ -353,6 +381,8 @@
     // Move operation
     __ cvttss2si(rdx, Operand(rbx, rcx, times_4, 10000));
     __ cvttss2si(rdx, xmm1);
+    __ cvtsd2ss(xmm0, xmm1);
+    __ cvtsd2ss(xmm0, Operand(rbx, rcx, times_4, 10000));
     __ movaps(xmm0, xmm1);
 
     // logic operation
@@ -364,6 +394,14 @@
     __ xorps(xmm0, Operand(rbx, rcx, times_4, 10000));
 
     // Arithmetic operation
+    __ addss(xmm1, xmm0);
+    __ addss(xmm1, Operand(rbx, rcx, times_4, 10000));
+    __ mulss(xmm1, xmm0);
+    __ mulss(xmm1, Operand(rbx, rcx, times_4, 10000));
+    __ subss(xmm1, xmm0);
+    __ subss(xmm1, Operand(rbx, rcx, times_4, 10000));
+    __ divss(xmm1, xmm0);
+    __ divss(xmm1, Operand(rbx, rcx, times_4, 10000));
     __ addps(xmm1, xmm0);
     __ addps(xmm1, Operand(rbx, rcx, times_4, 10000));
     __ subps(xmm1, xmm0);
@@ -372,6 +410,9 @@
     __ mulps(xmm1, Operand(rbx, rcx, times_4, 10000));
     __ divps(xmm1, xmm0);
     __ divps(xmm1, Operand(rbx, rcx, times_4, 10000));
+
+    __ ucomiss(xmm0, xmm1);
+    __ ucomiss(xmm0, Operand(rbx, rcx, times_4, 10000));
   }
   // SSE 2 instructions
   {
@@ -379,6 +420,8 @@
     __ cvttsd2si(rdx, xmm1);
     __ cvttsd2siq(rdx, xmm1);
     __ cvttsd2siq(rdx, Operand(rbx, rcx, times_4, 10000));
+    __ cvtqsi2sd(xmm1, Operand(rbx, rcx, times_4, 10000));
+    __ cvtqsi2sd(xmm1, rdx);
     __ movsd(xmm1, Operand(rbx, rcx, times_4, 10000));
     __ movsd(Operand(rbx, rcx, times_4, 10000), xmm1);
     // 128 bit move instructions.
@@ -386,12 +429,23 @@
     __ movdqa(Operand(rbx, rcx, times_4, 10000), xmm0);
 
     __ addsd(xmm1, xmm0);
+    __ addsd(xmm1, Operand(rbx, rcx, times_4, 10000));
     __ mulsd(xmm1, xmm0);
+    __ mulsd(xmm1, Operand(rbx, rcx, times_4, 10000));
     __ subsd(xmm1, xmm0);
+    __ subsd(xmm1, Operand(rbx, rcx, times_4, 10000));
     __ divsd(xmm1, xmm0);
+    __ divsd(xmm1, Operand(rbx, rcx, times_4, 10000));
     __ ucomisd(xmm0, xmm1);
 
     __ andpd(xmm0, xmm1);
+
+    __ pslld(xmm0, 6);
+    __ psrld(xmm0, 6);
+    __ psllq(xmm0, 6);
+    __ psrlq(xmm0, 6);
+
+    __ pcmpeqd(xmm1, xmm0);
   }
 
   // cmov.
@@ -421,6 +475,89 @@
     }
   }
 
+  // AVX instruction
+  {
+    if (CpuFeatures::IsSupported(AVX)) {
+      CpuFeatureScope scope(&assm, AVX);
+      __ vaddsd(xmm0, xmm1, xmm2);
+      __ vaddsd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vmulsd(xmm0, xmm1, xmm2);
+      __ vmulsd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vsubsd(xmm0, xmm1, xmm2);
+      __ vsubsd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vdivsd(xmm0, xmm1, xmm2);
+      __ vdivsd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+    }
+  }
+
+  // FMA3 instruction
+  {
+    if (CpuFeatures::IsSupported(FMA3)) {
+      CpuFeatureScope scope(&assm, FMA3);
+      __ vfmadd132sd(xmm0, xmm1, xmm2);
+      __ vfmadd132sd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfmadd213sd(xmm0, xmm1, xmm2);
+      __ vfmadd213sd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfmadd231sd(xmm0, xmm1, xmm2);
+      __ vfmadd231sd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+
+      __ vfmadd132sd(xmm9, xmm10, xmm11);
+      __ vfmadd132sd(xmm9, xmm10, Operand(r9, r11, times_4, 10000));
+      __ vfmadd213sd(xmm9, xmm10, xmm11);
+      __ vfmadd213sd(xmm9, xmm10, Operand(r9, r11, times_4, 10000));
+      __ vfmadd231sd(xmm9, xmm10, xmm11);
+      __ vfmadd231sd(xmm9, xmm10, Operand(r9, r11, times_4, 10000));
+
+      __ vfmsub132sd(xmm0, xmm1, xmm2);
+      __ vfmsub132sd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfmsub213sd(xmm0, xmm1, xmm2);
+      __ vfmsub213sd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfmsub231sd(xmm0, xmm1, xmm2);
+      __ vfmsub231sd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+
+      __ vfnmadd132sd(xmm0, xmm1, xmm2);
+      __ vfnmadd132sd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfnmadd213sd(xmm0, xmm1, xmm2);
+      __ vfnmadd213sd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfnmadd231sd(xmm0, xmm1, xmm2);
+      __ vfnmadd231sd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+
+      __ vfnmsub132sd(xmm0, xmm1, xmm2);
+      __ vfnmsub132sd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfnmsub213sd(xmm0, xmm1, xmm2);
+      __ vfnmsub213sd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfnmsub231sd(xmm0, xmm1, xmm2);
+      __ vfnmsub231sd(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+
+      __ vfmadd132ss(xmm0, xmm1, xmm2);
+      __ vfmadd132ss(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfmadd213ss(xmm0, xmm1, xmm2);
+      __ vfmadd213ss(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfmadd231ss(xmm0, xmm1, xmm2);
+      __ vfmadd231ss(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+
+      __ vfmsub132ss(xmm0, xmm1, xmm2);
+      __ vfmsub132ss(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfmsub213ss(xmm0, xmm1, xmm2);
+      __ vfmsub213ss(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfmsub231ss(xmm0, xmm1, xmm2);
+      __ vfmsub231ss(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+
+      __ vfnmadd132ss(xmm0, xmm1, xmm2);
+      __ vfnmadd132ss(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfnmadd213ss(xmm0, xmm1, xmm2);
+      __ vfnmadd213ss(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfnmadd231ss(xmm0, xmm1, xmm2);
+      __ vfnmadd231ss(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+
+      __ vfnmsub132ss(xmm0, xmm1, xmm2);
+      __ vfnmsub132ss(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfnmsub213ss(xmm0, xmm1, xmm2);
+      __ vfnmsub213ss(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+      __ vfnmsub231ss(xmm0, xmm1, xmm2);
+      __ vfnmsub231ss(xmm0, xmm1, Operand(rbx, rcx, times_4, 10000));
+    }
+  }
   // xchg.
   {
     __ xchgq(rax, rax);
diff --git a/test/cctest/test-disasm-x87.cc b/test/cctest/test-disasm-x87.cc
index 6cd33e5..e9b0dc5 100644
--- a/test/cctest/test-disasm-x87.cc
+++ b/test/cctest/test-disasm-x87.cc
@@ -201,6 +201,12 @@
   __ rcl(edx, 7);
   __ rcr(edx, 1);
   __ rcr(edx, 7);
+  __ ror(edx, 1);
+  __ ror(edx, 6);
+  __ ror_cl(edx);
+  __ ror(Operand(ebx, ecx, times_4, 10000), 1);
+  __ ror(Operand(ebx, ecx, times_4, 10000), 6);
+  __ ror_cl(Operand(ebx, ecx, times_4, 10000));
   __ sar(edx, 1);
   __ sar(edx, 6);
   __ sar_cl(edx);
diff --git a/test/cctest/test-feedback-vector.cc b/test/cctest/test-feedback-vector.cc
new file mode 100644
index 0000000..fa2f195
--- /dev/null
+++ b/test/cctest/test-feedback-vector.cc
@@ -0,0 +1,308 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/v8.h"
+#include "test/cctest/cctest.h"
+
+#include "src/api.h"
+#include "src/debug.h"
+#include "src/execution.h"
+#include "src/factory.h"
+#include "src/global-handles.h"
+#include "src/macro-assembler.h"
+#include "src/objects.h"
+
+using namespace v8::internal;
+
+namespace {
+
+TEST(VectorStructure) {
+  LocalContext context;
+  v8::HandleScope scope(context->GetIsolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* factory = isolate->factory();
+
+  // Empty vectors are the empty fixed array.
+  FeedbackVectorSpec empty;
+  Handle<TypeFeedbackVector> vector = factory->NewTypeFeedbackVector(empty);
+  CHECK(Handle<FixedArray>::cast(vector)
+            .is_identical_to(factory->empty_fixed_array()));
+  // Which can nonetheless be queried.
+  CHECK_EQ(0, vector->ic_with_type_info_count());
+  CHECK_EQ(0, vector->ic_generic_count());
+  CHECK_EQ(0, vector->Slots());
+  CHECK_EQ(0, vector->ICSlots());
+
+  FeedbackVectorSpec one_slot(1, 0);
+  vector = factory->NewTypeFeedbackVector(one_slot);
+  CHECK_EQ(1, vector->Slots());
+  CHECK_EQ(0, vector->ICSlots());
+
+  FeedbackVectorSpec one_icslot(0, 1);
+  if (FLAG_vector_ics) {
+    one_icslot.SetKind(0, Code::CALL_IC);
+  }
+  vector = factory->NewTypeFeedbackVector(one_icslot);
+  CHECK_EQ(0, vector->Slots());
+  CHECK_EQ(1, vector->ICSlots());
+
+  FeedbackVectorSpec spec(3, 5);
+  if (FLAG_vector_ics) {
+    for (int i = 0; i < 5; i++) spec.SetKind(i, Code::CALL_IC);
+  }
+  vector = factory->NewTypeFeedbackVector(spec);
+  CHECK_EQ(3, vector->Slots());
+  CHECK_EQ(5, vector->ICSlots());
+
+  int metadata_length = vector->ic_metadata_length();
+  if (!FLAG_vector_ics) {
+    CHECK_EQ(0, metadata_length);
+  } else {
+    CHECK(metadata_length > 0);
+  }
+
+  int index = vector->GetIndex(FeedbackVectorSlot(0));
+
+  CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + metadata_length, index);
+  CHECK(FeedbackVectorSlot(0) == vector->ToSlot(index));
+
+  index = vector->GetIndex(FeedbackVectorICSlot(0));
+  CHECK_EQ(index,
+           TypeFeedbackVector::kReservedIndexCount + metadata_length + 3);
+  CHECK(FeedbackVectorICSlot(0) == vector->ToICSlot(index));
+
+  CHECK_EQ(TypeFeedbackVector::kReservedIndexCount + metadata_length + 3 + 5,
+           vector->length());
+}
+
+
+// IC slots need an encoding to recognize what is in there.
+TEST(VectorICMetadata) {
+  LocalContext context;
+  v8::HandleScope scope(context->GetIsolate());
+  if (!FLAG_vector_ics) {
+    // If FLAG_vector_ics is false, we only store CALL_ICs in the vector, so
+    // there is no need for metadata to describe the slots.
+    return;
+  }
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* factory = isolate->factory();
+
+  FeedbackVectorSpec spec(10, 3 * 10);
+  // Set metadata.
+  for (int i = 0; i < 30; i++) {
+    Code::Kind kind;
+    if (i % 3 == 0) {
+      kind = Code::CALL_IC;
+    } else if (i % 3 == 1) {
+      kind = Code::LOAD_IC;
+    } else {
+      kind = Code::KEYED_LOAD_IC;
+    }
+    spec.SetKind(i, kind);
+  }
+
+  Handle<TypeFeedbackVector> vector = factory->NewTypeFeedbackVector(spec);
+  CHECK_EQ(10, vector->Slots());
+  CHECK_EQ(3 * 10, vector->ICSlots());
+
+  // Meanwhile set some feedback values and type feedback values to
+  // verify the data structure remains intact.
+  vector->change_ic_with_type_info_count(100);
+  vector->change_ic_generic_count(3333);
+  vector->Set(FeedbackVectorSlot(0), *vector);
+
+  // Verify the metadata is correctly set up from the spec.
+  for (int i = 0; i < 30; i++) {
+    Code::Kind kind = vector->GetKind(FeedbackVectorICSlot(i));
+    if (i % 3 == 0) {
+      CHECK_EQ(Code::CALL_IC, kind);
+    } else if (i % 3 == 1) {
+      CHECK_EQ(Code::LOAD_IC, kind);
+    } else {
+      CHECK_EQ(Code::KEYED_LOAD_IC, kind);
+    }
+  }
+}
+
+
+TEST(VectorSlotClearing) {
+  LocalContext context;
+  v8::HandleScope scope(context->GetIsolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* factory = isolate->factory();
+
+  // We only test clearing FeedbackVectorSlots, not FeedbackVectorICSlots.
+  // The reason is that FeedbackVectorICSlots need a full code environment
+  // to fully test (See VectorICProfilerStatistics test below).
+  FeedbackVectorSpec spec(5, 0);
+  Handle<TypeFeedbackVector> vector = factory->NewTypeFeedbackVector(spec);
+
+  // Fill with information
+  vector->Set(FeedbackVectorSlot(0), Smi::FromInt(1));
+  vector->Set(FeedbackVectorSlot(1), *factory->fixed_array_map());
+  Handle<AllocationSite> site = factory->NewAllocationSite();
+  vector->Set(FeedbackVectorSlot(2), *site);
+
+  vector->ClearSlots(NULL);
+
+  // The feedback vector slots are cleared. AllocationSites are granted
+  // an exemption from clearing, as are smis.
+  CHECK_EQ(Smi::FromInt(1), vector->Get(FeedbackVectorSlot(0)));
+  CHECK_EQ(*TypeFeedbackVector::UninitializedSentinel(isolate),
+           vector->Get(FeedbackVectorSlot(1)));
+  CHECK(vector->Get(FeedbackVectorSlot(2))->IsAllocationSite());
+}
+
+
+TEST(VectorICProfilerStatistics) {
+  if (i::FLAG_always_opt) return;
+  CcTest::InitializeVM();
+  LocalContext context;
+  v8::HandleScope scope(context->GetIsolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Heap* heap = isolate->heap();
+
+  // Make sure function f has a call that uses a type feedback slot.
+  CompileRun(
+      "function fun() {};"
+      "function f(a) { a(); } f(fun);");
+  Handle<JSFunction> f = v8::Utils::OpenHandle(
+      *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
+  // There should be one IC.
+  Code* code = f->shared()->code();
+  TypeFeedbackInfo* feedback_info =
+      TypeFeedbackInfo::cast(code->type_feedback_info());
+  CHECK_EQ(1, feedback_info->ic_total_count());
+  CHECK_EQ(0, feedback_info->ic_with_type_info_count());
+  CHECK_EQ(0, feedback_info->ic_generic_count());
+  TypeFeedbackVector* feedback_vector = f->shared()->feedback_vector();
+  CHECK_EQ(1, feedback_vector->ic_with_type_info_count());
+  CHECK_EQ(0, feedback_vector->ic_generic_count());
+
+  // Now send the information generic.
+  CompileRun("f(Object);");
+  feedback_vector = f->shared()->feedback_vector();
+  CHECK_EQ(0, feedback_vector->ic_with_type_info_count());
+  CHECK_EQ(1, feedback_vector->ic_generic_count());
+
+  // A collection will make the site uninitialized again.
+  heap->CollectAllGarbage(i::Heap::kNoGCFlags);
+  feedback_vector = f->shared()->feedback_vector();
+  CHECK_EQ(0, feedback_vector->ic_with_type_info_count());
+  CHECK_EQ(0, feedback_vector->ic_generic_count());
+
+  // The Array function is special. A call to array remains monomorphic
+  // and isn't cleared by gc because an AllocationSite is being held.
+  CompileRun("f(Array);");
+  feedback_vector = f->shared()->feedback_vector();
+  CHECK_EQ(1, feedback_vector->ic_with_type_info_count());
+  CHECK_EQ(0, feedback_vector->ic_generic_count());
+
+  int ic_slot = 0;
+  CHECK(
+      feedback_vector->Get(FeedbackVectorICSlot(ic_slot))->IsAllocationSite());
+  heap->CollectAllGarbage(i::Heap::kNoGCFlags);
+  feedback_vector = f->shared()->feedback_vector();
+  CHECK_EQ(1, feedback_vector->ic_with_type_info_count());
+  CHECK_EQ(0, feedback_vector->ic_generic_count());
+  CHECK(
+      feedback_vector->Get(FeedbackVectorICSlot(ic_slot))->IsAllocationSite());
+}
+
+
+TEST(VectorCallICStates) {
+  if (i::FLAG_always_opt) return;
+  CcTest::InitializeVM();
+  LocalContext context;
+  v8::HandleScope scope(context->GetIsolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Heap* heap = isolate->heap();
+
+  // Make sure function f has a call that uses a type feedback slot.
+  CompileRun(
+      "function foo() { return 17; }"
+      "function f(a) { a(); } f(foo);");
+  Handle<JSFunction> f = v8::Utils::OpenHandle(
+      *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
+  // There should be one IC.
+  Handle<TypeFeedbackVector> feedback_vector =
+      Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate);
+  FeedbackVectorICSlot slot(0);
+  CallICNexus nexus(feedback_vector, slot);
+  CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
+  // CallIC doesn't return map feedback.
+  CHECK_EQ(NULL, nexus.FindFirstMap());
+
+  CompileRun("f(function() { return 16; })");
+  CHECK_EQ(GENERIC, nexus.StateFromFeedback());
+
+  // After a collection, state should be reset to UNINITIALIZED.
+  heap->CollectAllGarbage(i::Heap::kNoGCFlags);
+  CHECK_EQ(UNINITIALIZED, nexus.StateFromFeedback());
+
+  // Array is special. It will remain monomorphic across gcs and it contains an
+  // AllocationSite.
+  CompileRun("f(Array)");
+  CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
+  CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot))->IsAllocationSite());
+
+  heap->CollectAllGarbage(i::Heap::kNoGCFlags);
+  CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
+}
+
+
+TEST(VectorLoadICStates) {
+  if (i::FLAG_always_opt || !i::FLAG_vector_ics) return;
+  CcTest::InitializeVM();
+  LocalContext context;
+  v8::HandleScope scope(context->GetIsolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Heap* heap = isolate->heap();
+
+  // Make sure function f has a call that uses a type feedback slot.
+  CompileRun(
+      "var o = { foo: 3 };"
+      "function f(a) { return a.foo; } f(o);");
+  Handle<JSFunction> f = v8::Utils::OpenHandle(
+      *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
+  // There should be one IC.
+  Handle<TypeFeedbackVector> feedback_vector =
+      Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate);
+  FeedbackVectorICSlot slot(0);
+  LoadICNexus nexus(feedback_vector, slot);
+  CHECK_EQ(PREMONOMORPHIC, nexus.StateFromFeedback());
+
+  CompileRun("f(o)");
+  CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
+  // Verify that the monomorphic map is the one we expect.
+  Handle<JSObject> o = v8::Utils::OpenHandle(
+      *v8::Handle<v8::Object>::Cast(CcTest::global()->Get(v8_str("o"))));
+  CHECK_EQ(o->map(), nexus.FindFirstMap());
+
+  // Now go polymorphic.
+  CompileRun("f({ blarg: 3, foo: 2 })");
+  CHECK_EQ(POLYMORPHIC, nexus.StateFromFeedback());
+
+  CompileRun(
+      "delete o.foo;"
+      "f(o)");
+  CHECK_EQ(POLYMORPHIC, nexus.StateFromFeedback());
+
+  CompileRun("f({ blarg: 3, torino: 10, foo: 2 })");
+  CHECK_EQ(POLYMORPHIC, nexus.StateFromFeedback());
+  MapHandleList maps;
+  nexus.FindAllMaps(&maps);
+  CHECK_EQ(4, maps.length());
+
+  // Finally driven megamorphic.
+  CompileRun("f({ blarg: 3, gran: 3, torino: 10, foo: 2 })");
+  CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback());
+  CHECK_EQ(NULL, nexus.FindFirstMap());
+
+  // After a collection, state should not be reset to PREMONOMORPHIC.
+  heap->CollectAllGarbage(i::Heap::kNoGCFlags);
+  CHECK_EQ(MEGAMORPHIC, nexus.StateFromFeedback());
+}
+}
diff --git a/test/cctest/test-func-name-inference.cc b/test/cctest/test-func-name-inference.cc
index bc503b5..7f3dafc 100644
--- a/test/cctest/test-func-name-inference.cc
+++ b/test/cctest/test-func-name-inference.cc
@@ -30,7 +30,7 @@
 
 #include "src/api.h"
 #include "src/debug.h"
-#include "src/runtime.h"
+#include "src/string-search.h"
 #include "test/cctest/cctest.h"
 
 
@@ -46,13 +46,13 @@
 using ::v8::internal::SmartArrayPointer;
 using ::v8::internal::SharedFunctionInfo;
 using ::v8::internal::String;
+using ::v8::internal::Vector;
 
 
 static void CheckFunctionName(v8::Handle<v8::Script> script,
                               const char* func_pos_src,
                               const char* ref_inferred_name) {
   Isolate* isolate = CcTest::i_isolate();
-  Factory* factory = isolate->factory();
 
   // Get script source.
   Handle<Object> obj = v8::Utils::OpenHandle(*script);
@@ -69,12 +69,14 @@
   Handle<String> script_src(String::cast(i_script->source()));
 
   // Find the position of a given func source substring in the source.
-  Handle<String> func_pos_str =
-      factory->NewStringFromAsciiChecked(func_pos_src);
-  int func_pos = Runtime::StringMatch(isolate,
-                                      script_src,
-                                      func_pos_str,
-                                      0);
+  int func_pos;
+  {
+    i::DisallowHeapAllocation no_gc;
+    Vector<const uint8_t> func_pos_str = i::OneByteVector(func_pos_src);
+    String::FlatContent script_content = script_src->GetFlatContent();
+    func_pos = SearchString(isolate, script_content.ToOneByteVector(),
+                            func_pos_str, 0);
+  }
   CHECK_NE(0, func_pos);
 
   // Obtain SharedFunctionInfo for the function.
diff --git a/test/cctest/test-heap-profiler.cc b/test/cctest/test-heap-profiler.cc
index 8f9b484..94a5be4 100644
--- a/test/cctest/test-heap-profiler.cc
+++ b/test/cctest/test-heap-profiler.cc
@@ -890,9 +890,10 @@
 }  // namespace
 
 TEST(HeapSnapshotJSONSerialization) {
+  v8::Isolate* isolate = CcTest::isolate();
   LocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
-  v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
+  v8::HandleScope scope(isolate);
+  v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler();
 
 #define STRING_LITERAL_FOR_TEST \
   "\"String \\n\\r\\u0008\\u0081\\u0101\\u0801\\u8001\""
@@ -923,7 +924,7 @@
 
   // Verify that snapshot object has required fields.
   v8::Local<v8::Object> parsed_snapshot =
-      env->Global()->Get(v8_str("parsed"))->ToObject();
+      env->Global()->Get(v8_str("parsed"))->ToObject(isolate);
   CHECK(parsed_snapshot->Has(v8_str("snapshot")));
   CHECK(parsed_snapshot->Has(v8_str("nodes")));
   CHECK(parsed_snapshot->Has(v8_str("edges")));
@@ -979,17 +980,18 @@
       "  \"s\", property_type)");
   CHECK(!string_obj_pos_val.IsEmpty());
   int string_obj_pos =
-      static_cast<int>(string_obj_pos_val->ToNumber()->Value());
+      static_cast<int>(string_obj_pos_val->ToNumber(isolate)->Value());
   v8::Local<v8::Object> nodes_array =
-      parsed_snapshot->Get(v8_str("nodes"))->ToObject();
+      parsed_snapshot->Get(v8_str("nodes"))->ToObject(isolate);
   int string_index = static_cast<int>(
-      nodes_array->Get(string_obj_pos + 1)->ToNumber()->Value());
+      nodes_array->Get(string_obj_pos + 1)->ToNumber(isolate)->Value());
   CHECK_GT(string_index, 0);
   v8::Local<v8::Object> strings_array =
-      parsed_snapshot->Get(v8_str("strings"))->ToObject();
-  v8::Local<v8::String> string = strings_array->Get(string_index)->ToString();
+      parsed_snapshot->Get(v8_str("strings"))->ToObject(isolate);
+  v8::Local<v8::String> string =
+      strings_array->Get(string_index)->ToString(isolate);
   v8::Local<v8::String> ref_string =
-      CompileRun(STRING_LITERAL_FOR_TEST)->ToString();
+      CompileRun(STRING_LITERAL_FOR_TEST)->ToString(isolate);
 #undef STRING_LITERAL_FOR_TEST
   CHECK_EQ(*v8::String::Utf8Value(ref_string),
            *v8::String::Utf8Value(string));
@@ -1719,9 +1721,6 @@
   const v8::HeapGraphNode* native_context =
       GetProperty(global, v8::HeapGraphEdge::kInternal, "native_context");
   CHECK_NE(NULL, native_context);
-  const v8::HeapGraphNode* global_context =
-      GetProperty(global, v8::HeapGraphEdge::kInternal, "global_context");
-  CHECK_NE(NULL, global_context);
   const v8::HeapGraphNode* global_proxy =
       GetProperty(global, v8::HeapGraphEdge::kInternal, "global_proxy");
   CHECK_NE(NULL, global_proxy);
@@ -1917,6 +1916,47 @@
 }
 
 
+TEST(FastCaseRedefinedAccessors) {
+  LocalContext env;
+  v8::HandleScope scope(env->GetIsolate());
+  v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
+
+  CompileRun(
+      "var obj1 = {};\n"
+      "Object.defineProperty(obj1, 'prop', { "
+      "  get: function() { return 42; },\n"
+      "  set: function(value) { return this.prop_ = value; },\n"
+      "  configurable: true,\n"
+      "  enumerable: true,\n"
+      "});\n"
+      "Object.defineProperty(obj1, 'prop', { "
+      "  get: function() { return 153; },\n"
+      "  set: function(value) { return this.prop_ = value; },\n"
+      "  configurable: true,\n"
+      "  enumerable: true,\n"
+      "});\n");
+  v8::Local<v8::Object> js_global =
+      env->Global()->GetPrototype().As<v8::Object>();
+  i::Handle<i::JSObject> js_obj1 =
+      v8::Utils::OpenHandle(*js_global->Get(v8_str("obj1")).As<v8::Object>());
+  USE(js_obj1);
+
+  const v8::HeapSnapshot* snapshot =
+      heap_profiler->TakeHeapSnapshot(v8_str("fastCaseAccessors"));
+  CHECK(ValidateSnapshot(snapshot));
+  const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
+  CHECK_NE(NULL, global);
+  const v8::HeapGraphNode* obj1 =
+      GetProperty(global, v8::HeapGraphEdge::kProperty, "obj1");
+  CHECK_NE(NULL, obj1);
+  const v8::HeapGraphNode* func;
+  func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get prop");
+  CHECK_NE(NULL, func);
+  func = GetProperty(obj1, v8::HeapGraphEdge::kProperty, "set prop");
+  CHECK_NE(NULL, func);
+}
+
+
 TEST(SlowCaseAccessors) {
   LocalContext env;
   v8::HandleScope scope(env->GetIsolate());
@@ -1952,9 +1992,10 @@
 
 
 TEST(HiddenPropertiesFastCase) {
+  v8::Isolate* isolate = CcTest::isolate();
   LocalContext env;
-  v8::HandleScope scope(env->GetIsolate());
-  v8::HeapProfiler* heap_profiler = env->GetIsolate()->GetHeapProfiler();
+  v8::HandleScope scope(isolate);
+  v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler();
 
   CompileRun(
       "function C(x) { this.a = this; this.b = x; }\n"
@@ -1973,7 +2014,7 @@
   v8::Handle<v8::Value> cHandle =
       env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "c"));
   CHECK(!cHandle.IsEmpty() && cHandle->IsObject());
-  cHandle->ToObject()->SetHiddenValue(v8_str("key"), v8_str("val"));
+  cHandle->ToObject(isolate)->SetHiddenValue(v8_str("key"), v8_str("val"));
 
   snapshot = heap_profiler->TakeHeapSnapshot(
       v8_str("HiddenPropertiesFastCase2"));
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index e526761..f8a7df2 100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -1375,6 +1375,98 @@
 }
 
 
+TEST(CompilationCacheCachingBehavior) {
+  // If we do not flush code, or have the compilation cache turned off, this
+  // test is invalid.
+  if (!FLAG_flush_code || !FLAG_flush_code_incrementally ||
+      !FLAG_compilation_cache) {
+    return;
+  }
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* factory = isolate->factory();
+  Heap* heap = isolate->heap();
+  CompilationCache* compilation_cache = isolate->compilation_cache();
+
+  v8::HandleScope scope(CcTest::isolate());
+  const char* raw_source =
+      "function foo() {"
+      "  var x = 42;"
+      "  var y = 42;"
+      "  var z = x + y;"
+      "};"
+      "foo()";
+  Handle<String> source = factory->InternalizeUtf8String(raw_source);
+  Handle<Context> native_context = isolate->native_context();
+
+  {
+    v8::HandleScope scope(CcTest::isolate());
+    CompileRun(raw_source);
+  }
+
+  // On first compilation, only a hash is inserted in the code cache. We can't
+  // find that value.
+  MaybeHandle<SharedFunctionInfo> info = compilation_cache->LookupScript(
+      source, Handle<Object>(), 0, 0, true, native_context);
+  CHECK(info.is_null());
+
+  {
+    v8::HandleScope scope(CcTest::isolate());
+    CompileRun(raw_source);
+  }
+
+  // On second compilation, the hash is replaced by a real cache entry mapping
+  // the source to the shared function info containing the code.
+  info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, true,
+                                         native_context);
+  CHECK(!info.is_null());
+
+  heap->CollectAllGarbage(Heap::kNoGCFlags);
+
+  // On second compilation, the hash is replaced by a real cache entry mapping
+  // the source to the shared function info containing the code.
+  info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, true,
+                                         native_context);
+  CHECK(!info.is_null());
+
+  while (!info.ToHandleChecked()->code()->IsOld()) {
+    info.ToHandleChecked()->code()->MakeOlder(NO_MARKING_PARITY);
+  }
+
+  heap->CollectAllGarbage(Heap::kNoGCFlags);
+  // Ensure code aging cleared the entry from the cache.
+  info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, true,
+                                         native_context);
+  CHECK(info.is_null());
+
+  {
+    v8::HandleScope scope(CcTest::isolate());
+    CompileRun(raw_source);
+  }
+
+  // On first compilation, only a hash is inserted in the code cache. We can't
+  // find that value.
+  info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, true,
+                                         native_context);
+  CHECK(info.is_null());
+
+  for (int i = 0; i < CompilationCacheTable::kHashGenerations; i++) {
+    compilation_cache->MarkCompactPrologue();
+  }
+
+  {
+    v8::HandleScope scope(CcTest::isolate());
+    CompileRun(raw_source);
+  }
+
+  // If we aged the cache before caching the script, ensure that we didn't cache
+  // on next compilation.
+  info = compilation_cache->LookupScript(source, Handle<Object>(), 0, 0, true,
+                                         native_context);
+  CHECK(info.is_null());
+}
+
+
 // Count the number of native contexts in the weak list of native contexts.
 int CountNativeContexts() {
   int count = 0;
@@ -1487,7 +1579,7 @@
   }
 
   // Force compilation cache cleanup.
-  CcTest::heap()->NotifyContextDisposed();
+  CcTest::heap()->NotifyContextDisposed(true);
   CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
 
   // Dispose the native contexts one by one.
@@ -1602,6 +1694,64 @@
 }
 
 
+TEST(TestSizeOfRegExpCode) {
+  if (!FLAG_regexp_optimization) return;
+
+  v8::V8::Initialize();
+
+  Isolate* isolate = CcTest::i_isolate();
+  HandleScope scope(isolate);
+
+  LocalContext context;
+
+  // Adjust source below and this check to match
+  // RegExpImple::kRegExpTooLargeToOptimize.
+  DCHECK_EQ(i::RegExpImpl::kRegExpTooLargeToOptimize, 10 * KB);
+
+  // Compile a regexp that is much larger if we are using regexp optimizations.
+  CompileRun(
+      "var reg_exp_source = '(?:a|bc|def|ghij|klmno|pqrstu)';"
+      "var half_size_reg_exp;"
+      "while (reg_exp_source.length < 10 * 1024) {"
+      "  half_size_reg_exp = reg_exp_source;"
+      "  reg_exp_source = reg_exp_source + reg_exp_source;"
+      "}"
+      // Flatten string.
+      "reg_exp_source.match(/f/);");
+
+  // Get initial heap size after several full GCs, which will stabilize
+  // the heap size and return with sweeping finished completely.
+  CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
+  CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
+  CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
+  CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
+  CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
+  MarkCompactCollector* collector = CcTest::heap()->mark_compact_collector();
+  if (collector->sweeping_in_progress()) {
+    collector->EnsureSweepingCompleted();
+  }
+  int initial_size = static_cast<int>(CcTest::heap()->SizeOfObjects());
+
+  CompileRun("'foo'.match(reg_exp_source);");
+  CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
+  int size_with_regexp = static_cast<int>(CcTest::heap()->SizeOfObjects());
+
+  CompileRun("'foo'.match(half_size_reg_exp);");
+  CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
+  int size_with_optimized_regexp =
+      static_cast<int>(CcTest::heap()->SizeOfObjects());
+
+  int size_of_regexp_code = size_with_regexp - initial_size;
+
+  CHECK_LE(size_of_regexp_code, 1 * MB);
+
+  // Small regexp is half the size, but compiles to more than twice the code
+  // due to the optimization steps.
+  CHECK_GE(size_with_optimized_regexp,
+           size_with_regexp + size_of_regexp_code * 2);
+}
+
+
 TEST(TestSizeOfObjects) {
   v8::V8::Initialize();
 
@@ -2183,6 +2333,48 @@
 }
 
 
+TEST(IdleNotificationFinishMarking) {
+  i::FLAG_allow_natives_syntax = true;
+  CcTest::InitializeVM();
+  SimulateFullSpace(CcTest::heap()->old_pointer_space());
+  IncrementalMarking* marking = CcTest::heap()->incremental_marking();
+  marking->Abort();
+  marking->Start();
+
+  CHECK_EQ(CcTest::heap()->gc_count(), 0);
+
+  // TODO(hpayer): We cannot write proper unit test right now for heap.
+  // The ideal test would call kMaxIdleMarkingDelayCounter to test the
+  // marking delay counter.
+
+  // Perform a huge incremental marking step but don't complete marking.
+  intptr_t bytes_processed = 0;
+  do {
+    bytes_processed =
+        marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD,
+                      IncrementalMarking::FORCE_MARKING,
+                      IncrementalMarking::DO_NOT_FORCE_COMPLETION);
+    CHECK(!marking->IsIdleMarkingDelayCounterLimitReached());
+  } while (bytes_processed);
+
+  // The next invocations of incremental marking are not going to complete
+  // marking
+  // since the completion threshold is not reached
+  for (size_t i = 0; i < IncrementalMarking::kMaxIdleMarkingDelayCounter - 2;
+       i++) {
+    marking->Step(1 * MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD,
+                  IncrementalMarking::FORCE_MARKING,
+                  IncrementalMarking::DO_NOT_FORCE_COMPLETION);
+    CHECK(!marking->IsIdleMarkingDelayCounterLimitReached());
+  }
+
+  // The next idle notification has to finish incremental marking.
+  const int kLongIdleTime = 1000000;
+  CcTest::isolate()->IdleNotification(kLongIdleTime);
+  CHECK_EQ(CcTest::heap()->gc_count(), 1);
+}
+
+
 // Test that HAllocateObject will always return an object in new-space.
 TEST(OptimizedAllocationAlwaysInNewSpace) {
   i::FLAG_allow_natives_syntax = true;
@@ -2204,7 +2396,8 @@
       "f(1); f(2); f(3);"
       "%OptimizeFunctionOnNextCall(f);"
       "f(4);");
-  CHECK_EQ(4, res->ToObject()->GetRealNamedProperty(v8_str("x"))->Int32Value());
+  CHECK_EQ(
+      4, res.As<v8::Object>()->GetRealNamedProperty(v8_str("x"))->Int32Value());
 
   Handle<JSObject> o =
       v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(res));
@@ -2342,12 +2535,21 @@
   FieldIndex idx1 = FieldIndex::ForPropertyIndex(o->map(), 0);
   FieldIndex idx2 = FieldIndex::ForPropertyIndex(o->map(), 1);
   CHECK(CcTest::heap()->InOldPointerSpace(o->RawFastPropertyAt(idx1)));
-  CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(idx2)));
+  if (!o->IsUnboxedDoubleField(idx2)) {
+    CHECK(CcTest::heap()->InOldDataSpace(o->RawFastPropertyAt(idx2)));
+  } else {
+    CHECK_EQ(1.1, o->RawFastDoublePropertyAt(idx2));
+  }
 
   JSObject* inner_object =
       reinterpret_cast<JSObject*>(o->RawFastPropertyAt(idx1));
   CHECK(CcTest::heap()->InOldPointerSpace(inner_object));
-  CHECK(CcTest::heap()->InOldDataSpace(inner_object->RawFastPropertyAt(idx1)));
+  if (!inner_object->IsUnboxedDoubleField(idx1)) {
+    CHECK(
+        CcTest::heap()->InOldDataSpace(inner_object->RawFastPropertyAt(idx1)));
+  } else {
+    CHECK_EQ(2.2, inner_object->RawFastDoublePropertyAt(idx1));
+  }
   CHECK(CcTest::heap()->InOldPointerSpace(
       inner_object->RawFastPropertyAt(idx2)));
 }
@@ -2806,6 +3008,7 @@
              "root = new F");
   root = GetByName("root");
   AddPropertyTo(2, root, "funny");
+  CcTest::heap()->CollectGarbage(NEW_SPACE);
 
   // Count number of live transitions after marking.  Note that one transition
   // is left, because 'o' still holds an instance of one transition target.
@@ -2832,6 +3035,7 @@
 
   root = GetByName("root");
   AddPropertyTo(2, root, "funny");
+  CcTest::heap()->CollectGarbage(NEW_SPACE);
 
   // Count number of live transitions after marking.  Note that one transition
   // is left, because 'o' still holds an instance of one transition target.
@@ -3076,7 +3280,7 @@
 
   OFStream os(stdout);
   g->shared()->Print(os);
-  os << endl;
+  os << std::endl;
 }
 #endif  // OBJECT_PRINT
 
@@ -3147,22 +3351,20 @@
 
   Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector());
 
-  int expected_length = FLAG_vector_ics ? 4 : 2;
-  CHECK_EQ(expected_length, feedback_vector->length());
-  for (int i = 0; i < expected_length; i++) {
-    if ((i % 2) == 1) {
-      CHECK(feedback_vector->get(i)->IsJSFunction());
-    }
-  }
+  int expected_slots = 2;
+  CHECK_EQ(expected_slots, feedback_vector->ICSlots());
+  int slot1 = 0;
+  int slot2 = 1;
+  CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot1))->IsJSFunction());
+  CHECK(feedback_vector->Get(FeedbackVectorICSlot(slot2))->IsJSFunction());
 
   SimulateIncrementalMarking(CcTest::heap());
   CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
 
-  CHECK_EQ(expected_length, feedback_vector->length());
-  for (int i = 0; i < expected_length; i++) {
-    CHECK_EQ(feedback_vector->get(i),
-             *TypeFeedbackVector::UninitializedSentinel(CcTest::i_isolate()));
-  }
+  CHECK_EQ(feedback_vector->Get(FeedbackVectorICSlot(slot1)),
+           *TypeFeedbackVector::UninitializedSentinel(CcTest::i_isolate()));
+  CHECK_EQ(feedback_vector->Get(FeedbackVectorICSlot(slot2)),
+           *TypeFeedbackVector::UninitializedSentinel(CcTest::i_isolate()));
 }
 
 
@@ -3181,6 +3383,25 @@
 }
 
 
+static void CheckVectorIC(Handle<JSFunction> f, int ic_slot_index,
+                          InlineCacheState desired_state) {
+  Handle<TypeFeedbackVector> vector =
+      Handle<TypeFeedbackVector>(f->shared()->feedback_vector());
+  FeedbackVectorICSlot slot(ic_slot_index);
+  LoadICNexus nexus(vector, slot);
+  CHECK(nexus.StateFromFeedback() == desired_state);
+}
+
+
+static void CheckVectorICCleared(Handle<JSFunction> f, int ic_slot_index) {
+  Handle<TypeFeedbackVector> vector =
+      Handle<TypeFeedbackVector>(f->shared()->feedback_vector());
+  FeedbackVectorICSlot slot(ic_slot_index);
+  LoadICNexus nexus(vector, slot);
+  CHECK(IC::IsCleared(&nexus));
+}
+
+
 TEST(IncrementalMarkingPreservesMonomorphicIC) {
   if (i::FLAG_always_opt) return;
   CcTest::InitializeVM();
@@ -3196,13 +3417,23 @@
               CcTest::global()->Get(v8_str("f"))));
 
   Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
-  CHECK(ic_before->ic_state() == MONOMORPHIC);
+  if (FLAG_vector_ics) {
+    CheckVectorIC(f, 0, MONOMORPHIC);
+    CHECK(ic_before->ic_state() == DEFAULT);
+  } else {
+    CHECK(ic_before->ic_state() == MONOMORPHIC);
+  }
 
   SimulateIncrementalMarking(CcTest::heap());
   CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
 
   Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
-  CHECK(ic_after->ic_state() == MONOMORPHIC);
+  if (FLAG_vector_ics) {
+    CheckVectorIC(f, 0, MONOMORPHIC);
+    CHECK(ic_after->ic_state() == DEFAULT);
+  } else {
+    CHECK(ic_after->ic_state() == MONOMORPHIC);
+  }
 }
 
 
@@ -3228,7 +3459,12 @@
               CcTest::global()->Get(v8_str("f"))));
 
   Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
-  CHECK(ic_before->ic_state() == MONOMORPHIC);
+  if (FLAG_vector_ics) {
+    CheckVectorIC(f, 0, MONOMORPHIC);
+    CHECK(ic_before->ic_state() == DEFAULT);
+  } else {
+    CHECK(ic_before->ic_state() == MONOMORPHIC);
+  }
 
   // Fire context dispose notification.
   CcTest::isolate()->ContextDisposedNotification();
@@ -3236,7 +3472,60 @@
   CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
 
   Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
-  CHECK(IC::IsCleared(ic_after));
+  if (FLAG_vector_ics) {
+    CheckVectorICCleared(f, 0);
+    CHECK(ic_after->ic_state() == DEFAULT);
+  } else {
+    CHECK(IC::IsCleared(ic_after));
+  }
+}
+
+
+TEST(IncrementalMarkingPreservesPolymorphicIC) {
+  if (i::FLAG_always_opt) return;
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+  v8::Local<v8::Value> obj1, obj2;
+
+  {
+    LocalContext env;
+    CompileRun("function fun() { this.x = 1; }; var obj = new fun();");
+    obj1 = env->Global()->Get(v8_str("obj"));
+  }
+
+  {
+    LocalContext env;
+    CompileRun("function fun() { this.x = 2; }; var obj = new fun();");
+    obj2 = env->Global()->Get(v8_str("obj"));
+  }
+
+  // Prepare function f that contains a polymorphic IC for objects
+  // originating from two different native contexts.
+  CcTest::global()->Set(v8_str("obj1"), obj1);
+  CcTest::global()->Set(v8_str("obj2"), obj2);
+  CompileRun("function f(o) { return o.x; } f(obj1); f(obj1); f(obj2);");
+  Handle<JSFunction> f = v8::Utils::OpenHandle(
+      *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))));
+
+  Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
+  if (FLAG_vector_ics) {
+    CheckVectorIC(f, 0, POLYMORPHIC);
+    CHECK(ic_before->ic_state() == DEFAULT);
+  } else {
+    CHECK(ic_before->ic_state() == POLYMORPHIC);
+  }
+
+  // Fire context dispose notification.
+  SimulateIncrementalMarking(CcTest::heap());
+  CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
+
+  Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
+  if (FLAG_vector_ics) {
+    CheckVectorIC(f, 0, POLYMORPHIC);
+    CHECK(ic_after->ic_state() == DEFAULT);
+  } else {
+    CHECK(ic_after->ic_state() == POLYMORPHIC);
+  }
 }
 
 
@@ -3269,7 +3558,12 @@
               CcTest::global()->Get(v8_str("f"))));
 
   Code* ic_before = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
-  CHECK(ic_before->ic_state() == POLYMORPHIC);
+  if (FLAG_vector_ics) {
+    CheckVectorIC(f, 0, POLYMORPHIC);
+    CHECK(ic_before->ic_state() == DEFAULT);
+  } else {
+    CHECK(ic_before->ic_state() == POLYMORPHIC);
+  }
 
   // Fire context dispose notification.
   CcTest::isolate()->ContextDisposedNotification();
@@ -3277,7 +3571,12 @@
   CcTest::heap()->CollectAllGarbage(Heap::kNoGCFlags);
 
   Code* ic_after = FindFirstIC(f->shared()->code(), Code::LOAD_IC);
-  CHECK(IC::IsCleared(ic_after));
+  if (FLAG_vector_ics) {
+    CheckVectorICCleared(f, 0);
+    CHECK(ic_before->ic_state() == DEFAULT);
+  } else {
+    CHECK(IC::IsCleared(ic_after));
+  }
 }
 
 
@@ -4021,8 +4320,9 @@
                "bar%d();"
                "bar%d();"
                "bar%d();"
-               "%%OptimizeFunctionOnNextCall(bar%d);"
-               "bar%d();", i, i, i, i, i, i, i, i);
+               "%%OptimizeFwunctionOnNextCall(bar%d);"
+               "bar%d();",
+               i, i, i, i, i, i, i, i);
       CompileRun(source.start());
     }
     heap->CollectAllGarbage(i::Heap::kNoGCFlags);
@@ -4154,7 +4454,7 @@
   v8::Persistent<v8::Object> garbage;
   {
     v8::HandleScope scope(isolate);
-    garbage.Reset(isolate, CompileRun(source)->ToObject());
+    garbage.Reset(isolate, CompileRun(source)->ToObject(isolate));
   }
   weak_ic_cleared = false;
   garbage.SetWeak(static_cast<void*>(&garbage), &ClearWeakIC);
@@ -4181,6 +4481,25 @@
 }
 
 
+TEST(WeakMapInPolymorphicLoadIC) {
+  CheckWeakness(
+      "function loadIC(obj) {"
+      "  return obj.name;"
+      "}"
+      " (function() {"
+      "   var proto = {'name' : 'weak'};"
+      "   var obj = Object.create(proto);"
+      "   loadIC(obj);"
+      "   loadIC(obj);"
+      "   loadIC(obj);"
+      "   var poly = Object.create(proto);"
+      "   poly.x = true;"
+      "   loadIC(poly);"
+      "   return proto;"
+      " })();");
+}
+
+
 TEST(WeakMapInMonomorphicKeyedLoadIC) {
   CheckWeakness("function keyedLoadIC(obj, field) {"
                 "  return obj[field];"
@@ -4196,6 +4515,25 @@
 }
 
 
+TEST(WeakMapInPolymorphicKeyedLoadIC) {
+  CheckWeakness(
+      "function keyedLoadIC(obj, field) {"
+      "  return obj[field];"
+      "}"
+      " (function() {"
+      "   var proto = {'name' : 'weak'};"
+      "   var obj = Object.create(proto);"
+      "   keyedLoadIC(obj, 'name');"
+      "   keyedLoadIC(obj, 'name');"
+      "   keyedLoadIC(obj, 'name');"
+      "   var poly = Object.create(proto);"
+      "   poly.x = true;"
+      "   keyedLoadIC(poly, 'name');"
+      "   return proto;"
+      " })();");
+}
+
+
 TEST(WeakMapInMonomorphicStoreIC) {
   CheckWeakness("function storeIC(obj, value) {"
                 "  obj.name = value;"
@@ -4211,6 +4549,25 @@
 }
 
 
+TEST(WeakMapInPolymorphicStoreIC) {
+  CheckWeakness(
+      "function storeIC(obj, value) {"
+      "  obj.name = value;"
+      "}"
+      " (function() {"
+      "   var proto = {'name' : 'weak'};"
+      "   var obj = Object.create(proto);"
+      "   storeIC(obj, 'x');"
+      "   storeIC(obj, 'x');"
+      "   storeIC(obj, 'x');"
+      "   var poly = Object.create(proto);"
+      "   poly.x = true;"
+      "   storeIC(poly, 'x');"
+      "   return proto;"
+      " })();");
+}
+
+
 TEST(WeakMapInMonomorphicKeyedStoreIC) {
   CheckWeakness("function keyedStoreIC(obj, field, value) {"
                 "  obj[field] = value;"
@@ -4226,6 +4583,25 @@
 }
 
 
+TEST(WeakMapInPolymorphicKeyedStoreIC) {
+  CheckWeakness(
+      "function keyedStoreIC(obj, field, value) {"
+      "  obj[field] = value;"
+      "}"
+      " (function() {"
+      "   var proto = {'name' : 'weak'};"
+      "   var obj = Object.create(proto);"
+      "   keyedStoreIC(obj, 'x');"
+      "   keyedStoreIC(obj, 'x');"
+      "   keyedStoreIC(obj, 'x');"
+      "   var poly = Object.create(proto);"
+      "   poly.x = true;"
+      "   keyedStoreIC(poly, 'x');"
+      "   return proto;"
+      " })();");
+}
+
+
 TEST(WeakMapInMonomorphicCompareNilIC) {
   CheckWeakness("function compareNilIC(obj) {"
                 "  return obj == null;"
@@ -4241,6 +4617,160 @@
 }
 
 
+Handle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) {
+  Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
+  Handle<Object> obj =
+      Object::GetProperty(isolate->global_object(), str).ToHandleChecked();
+  return Handle<JSFunction>::cast(obj);
+}
+
+
+void CheckIC(Code* code, Code::Kind kind, InlineCacheState state) {
+  Code* ic = FindFirstIC(code, kind);
+  CHECK(ic->is_inline_cache_stub());
+  CHECK(ic->ic_state() == state);
+}
+
+
+TEST(MonomorphicStaysMonomorphicAfterGC) {
+  if (FLAG_always_opt) return;
+  // TODO(mvstanton): vector ics need weak support!
+  if (FLAG_vector_ics) return;
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  Heap* heap = isolate->heap();
+  v8::HandleScope scope(CcTest::isolate());
+  CompileRun(
+      "function loadIC(obj) {"
+      "  return obj.name;"
+      "}"
+      "function testIC() {"
+      "  var proto = {'name' : 'weak'};"
+      "  var obj = Object.create(proto);"
+      "  loadIC(obj);"
+      "  loadIC(obj);"
+      "  loadIC(obj);"
+      "  return proto;"
+      "};");
+  Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC");
+  {
+    v8::HandleScope scope(CcTest::isolate());
+    CompileRun("(testIC())");
+  }
+  heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+  CheckIC(loadIC->code(), Code::LOAD_IC, MONOMORPHIC);
+  {
+    v8::HandleScope scope(CcTest::isolate());
+    CompileRun("(testIC())");
+  }
+  CheckIC(loadIC->code(), Code::LOAD_IC, MONOMORPHIC);
+}
+
+
+TEST(PolymorphicStaysPolymorphicAfterGC) {
+  if (FLAG_always_opt) return;
+  // TODO(mvstanton): vector ics need weak support!
+  if (FLAG_vector_ics) return;
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  Heap* heap = isolate->heap();
+  v8::HandleScope scope(CcTest::isolate());
+  CompileRun(
+      "function loadIC(obj) {"
+      "  return obj.name;"
+      "}"
+      "function testIC() {"
+      "  var proto = {'name' : 'weak'};"
+      "  var obj = Object.create(proto);"
+      "  loadIC(obj);"
+      "  loadIC(obj);"
+      "  loadIC(obj);"
+      "  var poly = Object.create(proto);"
+      "  poly.x = true;"
+      "  loadIC(poly);"
+      "  return proto;"
+      "};");
+  Handle<JSFunction> loadIC = GetFunctionByName(isolate, "loadIC");
+  {
+    v8::HandleScope scope(CcTest::isolate());
+    CompileRun("(testIC())");
+  }
+  heap->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
+  CheckIC(loadIC->code(), Code::LOAD_IC, POLYMORPHIC);
+  {
+    v8::HandleScope scope(CcTest::isolate());
+    CompileRun("(testIC())");
+  }
+  CheckIC(loadIC->code(), Code::LOAD_IC, POLYMORPHIC);
+}
+
+
+TEST(WeakCell) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::internal::Heap* heap = CcTest::heap();
+  v8::internal::Factory* factory = isolate->factory();
+
+  HandleScope outer_scope(isolate);
+  Handle<WeakCell> weak_cell1;
+  {
+    HandleScope inner_scope(isolate);
+    Handle<HeapObject> value = factory->NewFixedArray(1, NOT_TENURED);
+    weak_cell1 = inner_scope.CloseAndEscape(factory->NewWeakCell(value));
+  }
+
+  Handle<FixedArray> survivor = factory->NewFixedArray(1, NOT_TENURED);
+  Handle<WeakCell> weak_cell2;
+  {
+    HandleScope inner_scope(isolate);
+    weak_cell2 = inner_scope.CloseAndEscape(factory->NewWeakCell(survivor));
+  }
+  CHECK(weak_cell1->value()->IsFixedArray());
+  CHECK_EQ(*survivor, weak_cell2->value());
+  heap->CollectGarbage(NEW_SPACE);
+  CHECK(weak_cell1->value()->IsFixedArray());
+  CHECK_EQ(*survivor, weak_cell2->value());
+  heap->CollectGarbage(NEW_SPACE);
+  CHECK(weak_cell1->value()->IsFixedArray());
+  CHECK_EQ(*survivor, weak_cell2->value());
+  heap->CollectAllAvailableGarbage();
+  CHECK(weak_cell1->cleared());
+  CHECK_EQ(*survivor, weak_cell2->value());
+}
+
+
+TEST(WeakCellsWithIncrementalMarking) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::internal::Heap* heap = CcTest::heap();
+  v8::internal::Factory* factory = isolate->factory();
+
+  const int N = 16;
+  HandleScope outer_scope(isolate);
+  Handle<FixedArray> survivor = factory->NewFixedArray(1, NOT_TENURED);
+  Handle<WeakCell> weak_cells[N];
+
+  for (int i = 0; i < N; i++) {
+    HandleScope inner_scope(isolate);
+    Handle<HeapObject> value =
+        i == 0 ? survivor : factory->NewFixedArray(1, NOT_TENURED);
+    Handle<WeakCell> weak_cell = factory->NewWeakCell(value);
+    CHECK(weak_cell->value()->IsFixedArray());
+    IncrementalMarking* marking = heap->incremental_marking();
+    if (marking->IsStopped()) marking->Start();
+    marking->Step(128, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
+    heap->CollectGarbage(NEW_SPACE);
+    CHECK(weak_cell->value()->IsFixedArray());
+    weak_cells[i] = inner_scope.CloseAndEscape(weak_cell);
+  }
+  heap->CollectAllGarbage(Heap::kNoGCFlags);
+  CHECK_EQ(*survivor, weak_cells[0]->value());
+  for (int i = 1; i < N; i++) {
+    CHECK(weak_cells[i]->cleared());
+  }
+}
+
+
 #ifdef DEBUG
 TEST(AddInstructionChangesNewSpacePromotion) {
   i::FLAG_allow_natives_syntax = true;
@@ -4320,7 +4850,7 @@
   CcTest::InitializeVM();
   v8::Isolate* isolate = CcTest::isolate();
   v8::HandleScope hscope(isolate);
-  v8::Handle<v8::ObjectTemplate> global =v8::ObjectTemplate::New(isolate);
+  v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
   global->Set(v8::String::NewFromUtf8(isolate, "interrupt"),
               v8::FunctionTemplate::New(isolate, RequestInterrupt));
   v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global);
@@ -4333,7 +4863,7 @@
       "eval('function f() {' + locals + 'return function() { return v0; }; }');"
       "interrupt();"  // This triggers a fake stack overflow in f.
       "f()()");
-  CHECK_EQ(42.0, result->ToNumber()->Value());
+  CHECK_EQ(42.0, result->ToNumber(isolate)->Value());
 }
 
 
@@ -4502,6 +5032,63 @@
 }
 
 
+TEST(Regress3631) {
+  i::FLAG_expose_gc = true;
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Heap* heap = isolate->heap();
+  IncrementalMarking* marking = CcTest::heap()->incremental_marking();
+  v8::Local<v8::Value> result = CompileRun(
+      "var weak_map = new WeakMap();"
+      "var future_keys = [];"
+      "for (var i = 0; i < 50; i++) {"
+      "  var key = {'k' : i + 0.1};"
+      "  weak_map.set(key, 1);"
+      "  future_keys.push({'x' : i + 0.2});"
+      "}"
+      "weak_map");
+  if (marking->IsStopped()) {
+    marking->Start();
+  }
+  // Incrementally mark the backing store.
+  Handle<JSObject> obj =
+      v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result));
+  Handle<JSWeakCollection> weak_map(reinterpret_cast<JSWeakCollection*>(*obj));
+  while (!Marking::IsBlack(
+             Marking::MarkBitFrom(HeapObject::cast(weak_map->table()))) &&
+         !marking->IsStopped()) {
+    marking->Step(MB, IncrementalMarking::NO_GC_VIA_STACK_GUARD);
+  }
+  // Stash the backing store in a handle.
+  Handle<Object> save(weak_map->table(), isolate);
+  // The following line will update the backing store.
+  CompileRun(
+      "for (var i = 0; i < 50; i++) {"
+      "  weak_map.set(future_keys[i], i);"
+      "}");
+  heap->incremental_marking()->set_should_hurry(true);
+  heap->CollectGarbage(OLD_POINTER_SPACE);
+}
+
+
+TEST(Regress442710) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  Heap* heap = isolate->heap();
+  Factory* factory = isolate->factory();
+
+  HandleScope sc(isolate);
+  Handle<GlobalObject> global(CcTest::i_isolate()->context()->global_object());
+  Handle<JSArray> array = factory->NewJSArray(2);
+
+  Handle<String> name = factory->InternalizeUtf8String("testArray");
+  JSReceiver::SetProperty(global, name, array, SLOPPY).Check();
+  CompileRun("testArray[0] = 1; testArray[1] = 2; testArray.shift();");
+  heap->CollectGarbage(OLD_POINTER_SPACE);
+}
+
+
 #ifdef DEBUG
 TEST(PathTracer) {
   CcTest::InitializeVM();
diff --git a/test/cctest/test-lockers.cc b/test/cctest/test-lockers.cc
index ed315ce..dc5404e 100644
--- a/test/cctest/test-lockers.cc
+++ b/test/cctest/test-lockers.cc
@@ -141,6 +141,7 @@
 
   void Join() {
     semaphore_.Wait();
+    thread_.Join();
   }
 
   virtual void Run() = 0;
diff --git a/test/cctest/test-log-stack-tracer.cc b/test/cctest/test-log-stack-tracer.cc
index 334a201..714ad69 100644
--- a/test/cctest/test-log-stack-tracer.cc
+++ b/test/cctest/test-log-stack-tracer.cc
@@ -235,9 +235,9 @@
 
 static void CFuncDoTrace(byte dummy_parameter) {
   Address fp;
-#ifdef __GNUC__
+#if V8_HAS_BUILTIN_FRAME_ADDRESS
   fp = reinterpret_cast<Address>(__builtin_frame_address(0));
-#elif defined _MSC_VER
+#elif V8_CC_MSVC
   // Approximate a frame pointer address. We compile without base pointers,
   // so we can't trust ebp/rbp.
   fp = &dummy_parameter - 2 * sizeof(void*);  // NOLINT
diff --git a/test/cctest/test-log.cc b/test/cctest/test-log.cc
index 482f89f..eee3e13 100644
--- a/test/cctest/test-log.cc
+++ b/test/cctest/test-log.cc
@@ -42,6 +42,7 @@
 #include "src/natives.h"
 #include "src/utils.h"
 #include "src/v8threads.h"
+#include "src/version.h"
 #include "src/vm-state-inl.h"
 #include "test/cctest/cctest.h"
 
@@ -477,10 +478,9 @@
         isolate, log.start(), v8::String::kNormalString, log.length());
     initialize_logger.env()->Global()->Set(v8_str("_log"), log_str);
 
-    i::Vector<const unsigned char> source = TestSources::GetScriptsSource();
+    i::Vector<const char> source = TestSources::GetScriptsSource();
     v8::Handle<v8::String> source_str = v8::String::NewFromUtf8(
-        isolate, reinterpret_cast<const char*>(source.start()),
-        v8::String::kNormalString, source.length());
+        isolate, source.start(), v8::String::kNormalString, source.length());
     v8::TryCatch try_catch;
     v8::Handle<v8::Script> script = CompileWithOrigin(source_str, "");
     if (script.IsEmpty()) {
@@ -496,7 +496,7 @@
     }
     // The result either be a "true" literal or problem description.
     if (!result->IsTrue()) {
-      v8::Local<v8::String> s = result->ToString();
+      v8::Local<v8::String> s = result->ToString(isolate);
       i::ScopedVector<char> data(s->Utf8Length() + 1);
       CHECK_NE(NULL, data.start());
       s->WriteUtf8(data.start());
@@ -508,3 +508,23 @@
   }
   isolate->Dispose();
 }
+
+
+TEST(LogVersion) {
+  v8::Isolate* isolate;
+  {
+    ScopedLoggerInitializer initialize_logger;
+    isolate = initialize_logger.isolate();
+    bool exists = false;
+    i::Vector<const char> log(
+        i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists, true));
+    CHECK(exists);
+    i::EmbeddedVector<char, 100> ref_data;
+    i::SNPrintF(ref_data, "v8-version,%d,%d,%d,%d,%d", i::Version::GetMajor(),
+                i::Version::GetMinor(), i::Version::GetBuild(),
+                i::Version::GetPatch(), i::Version::IsCandidate());
+    CHECK_NE(NULL, StrNStr(log.start(), ref_data.start(), log.length()));
+    log.Dispose();
+  }
+  isolate->Dispose();
+}
diff --git a/test/cctest/test-mark-compact.cc b/test/cctest/test-mark-compact.cc
index c7d6531..64d995d 100644
--- a/test/cctest/test-mark-compact.cc
+++ b/test/cctest/test-mark-compact.cc
@@ -446,7 +446,7 @@
     bool write_permission = (buffer[position++] == 'w');
     CHECK(buffer[position] == '-' || buffer[position] == 'x');
     bool execute_permission = (buffer[position++] == 'x');
-    CHECK(buffer[position] == '-' || buffer[position] == 'p');
+    CHECK(buffer[position] == 's' || buffer[position] == 'p');
     bool private_mapping = (buffer[position++] == 'p');
     CHECK_EQ(buffer[position++], ' ');
     uintptr_t offset = ReadLong(buffer, &position, 16);
diff --git a/test/cctest/test-object-observe.cc b/test/cctest/test-object-observe.cc
index d208a26..2766a4f 100644
--- a/test/cctest/test-object-observe.cc
+++ b/test/cctest/test-object-observe.cc
@@ -130,6 +130,59 @@
 }
 
 
+TEST(DeliveryCallbackThrows) {
+  HandleScope scope(CcTest::isolate());
+  LocalContext context(CcTest::isolate());
+  CompileRun(
+      "var obj = {};"
+      "var ordering = [];"
+      "function observer1() { ordering.push(1); };"
+      "function observer2() { ordering.push(2); };"
+      "function observer_throws() {"
+      "  ordering.push(0);"
+      "  throw new Error();"
+      "  ordering.push(-1);"
+      "};"
+      "Object.observe(obj, observer_throws.bind());"
+      "Object.observe(obj, observer1);"
+      "Object.observe(obj, observer_throws.bind());"
+      "Object.observe(obj, observer2);"
+      "Object.observe(obj, observer_throws.bind());"
+      "obj.foo = 'bar';");
+  CHECK_EQ(5, CompileRun("ordering.length")->Int32Value());
+  CHECK_EQ(0, CompileRun("ordering[0]")->Int32Value());
+  CHECK_EQ(1, CompileRun("ordering[1]")->Int32Value());
+  CHECK_EQ(0, CompileRun("ordering[2]")->Int32Value());
+  CHECK_EQ(2, CompileRun("ordering[3]")->Int32Value());
+  CHECK_EQ(0, CompileRun("ordering[4]")->Int32Value());
+}
+
+
+TEST(DeliveryChangesMutationInCallback) {
+  HandleScope scope(CcTest::isolate());
+  LocalContext context(CcTest::isolate());
+  CompileRun(
+      "var obj = {};"
+      "var ordering = [];"
+      "function observer1(records) {"
+      "  ordering.push(100 + records.length);"
+      "  records.push(11);"
+      "  records.push(22);"
+      "};"
+      "function observer2(records) {"
+      "  ordering.push(200 + records.length);"
+      "  records.push(33);"
+      "  records.push(44);"
+      "};"
+      "Object.observe(obj, observer1);"
+      "Object.observe(obj, observer2);"
+      "obj.foo = 'bar';");
+  CHECK_EQ(2, CompileRun("ordering.length")->Int32Value());
+  CHECK_EQ(101, CompileRun("ordering[0]")->Int32Value());
+  CHECK_EQ(201, CompileRun("ordering[1]")->Int32Value());
+}
+
+
 TEST(DeliveryOrderingReentrant) {
   HandleScope scope(CcTest::isolate());
   LocalContext context(CcTest::isolate());
@@ -709,3 +762,76 @@
   CcTest::isolate()->ContextDisposedNotification();
   CheckSurvivingGlobalObjectsCount(1);
 }
+
+
+static void ObserverCallback(const FunctionCallbackInfo<Value>& args) {
+  *static_cast<int*>(Handle<External>::Cast(args.Data())->Value()) =
+      Handle<Array>::Cast(args[0])->Length();
+}
+
+
+TEST(ObjectObserveCallsCppFunction) {
+  Isolate* isolate = CcTest::isolate();
+  HandleScope scope(isolate);
+  LocalContext context(isolate);
+  int numRecordsSent = 0;
+  Handle<Function> observer =
+      Function::New(CcTest::isolate(), ObserverCallback,
+                    External::New(isolate, &numRecordsSent));
+  context->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "observer"),
+                         observer);
+  CompileRun(
+      "var obj = {};"
+      "Object.observe(obj, observer);"
+      "obj.foo = 1;"
+      "obj.bar = 2;");
+  CHECK_EQ(2, numRecordsSent);
+}
+
+
+TEST(ObjectObserveCallsFunctionTemplateInstance) {
+  Isolate* isolate = CcTest::isolate();
+  HandleScope scope(isolate);
+  LocalContext context(isolate);
+  int numRecordsSent = 0;
+  Handle<FunctionTemplate> tmpl = FunctionTemplate::New(
+      isolate, ObserverCallback, External::New(isolate, &numRecordsSent));
+  context->Global()->Set(String::NewFromUtf8(CcTest::isolate(), "observer"),
+                         tmpl->GetFunction());
+  CompileRun(
+      "var obj = {};"
+      "Object.observe(obj, observer);"
+      "obj.foo = 1;"
+      "obj.bar = 2;");
+  CHECK_EQ(2, numRecordsSent);
+}
+
+
+static void AccessorGetter(Local<String> property,
+                           const PropertyCallbackInfo<Value>& info) {
+  info.GetReturnValue().Set(Integer::New(info.GetIsolate(), 42));
+}
+
+
+static void AccessorSetter(Local<String> property, Local<Value> value,
+                           const PropertyCallbackInfo<void>& info) {
+  info.GetReturnValue().SetUndefined();
+}
+
+
+TEST(APIAccessorsShouldNotNotify) {
+  Isolate* isolate = CcTest::isolate();
+  HandleScope handle_scope(isolate);
+  LocalContext context(isolate);
+  Handle<Object> object = Object::New(isolate);
+  object->SetAccessor(String::NewFromUtf8(isolate, "accessor"), &AccessorGetter,
+                      &AccessorSetter);
+  context->Global()->Set(String::NewFromUtf8(isolate, "obj"), object);
+  CompileRun(
+      "var records = null;"
+      "Object.observe(obj, function(r) { records = r });"
+      "obj.accessor = 43;");
+  CHECK(CompileRun("records")->IsNull());
+  CompileRun("Object.defineProperty(obj, 'accessor', { value: 44 });");
+  CHECK(CompileRun("records")->IsNull());
+}
diff --git a/test/cctest/test-ostreams.cc b/test/cctest/test-ostreams.cc
deleted file mode 100644
index c83f96d..0000000
--- a/test/cctest/test-ostreams.cc
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <string.h>
-#include <limits>
-
-#include "include/v8stdint.h"
-#include "src/ostreams.h"
-#include "test/cctest/cctest.h"
-
-using namespace v8::internal;
-
-
-TEST(OStringStreamConstructor) {
-  OStringStream oss;
-  const size_t expected_size = 0;
-  CHECK(expected_size == oss.size());
-  CHECK_GT(oss.capacity(), 0);
-  CHECK_NE(NULL, oss.data());
-  CHECK_EQ("", oss.c_str());
-}
-
-
-#define TEST_STRING            \
-  "Ash nazg durbatuluk, "      \
-  "ash nazg gimbatul, "        \
-  "ash nazg thrakatuluk, "     \
-  "agh burzum-ishi krimpatul."
-
-TEST(OStringStreamGrow) {
-  OStringStream oss;
-  const int repeat = 30;
-  size_t len = strlen(TEST_STRING);
-  for (int i = 0; i < repeat; ++i) {
-    oss.write(TEST_STRING, len);
-  }
-  const char* expected =
-      TEST_STRING TEST_STRING TEST_STRING TEST_STRING TEST_STRING
-      TEST_STRING TEST_STRING TEST_STRING TEST_STRING TEST_STRING
-      TEST_STRING TEST_STRING TEST_STRING TEST_STRING TEST_STRING
-      TEST_STRING TEST_STRING TEST_STRING TEST_STRING TEST_STRING
-      TEST_STRING TEST_STRING TEST_STRING TEST_STRING TEST_STRING
-      TEST_STRING TEST_STRING TEST_STRING TEST_STRING TEST_STRING;
-  const size_t expected_len = len * repeat;
-  CHECK(expected_len == oss.size());
-  CHECK_GT(oss.capacity(), 0);
-  CHECK_EQ(0, strncmp(expected, oss.data(), expected_len));
-  CHECK_EQ(expected, oss.c_str());
-}
-
-
-template <class T>
-static void check(const char* expected, T value) {
-  OStringStream oss;
-  oss << value << " " << hex << value;
-  CHECK_EQ(expected, oss.c_str());
-}
-
-
-TEST(NumericFormatting) {
-  check<bool>("0 0", false);
-  check<bool>("1 1", true);
-
-  check<int16_t>("-12345 cfc7", -12345);
-  check<int16_t>("-32768 8000", std::numeric_limits<int16_t>::min());
-  check<int16_t>("32767 7fff", std::numeric_limits<int16_t>::max());
-
-  check<uint16_t>("34567 8707", 34567);
-  check<uint16_t>("0 0", std::numeric_limits<uint16_t>::min());
-  check<uint16_t>("65535 ffff", std::numeric_limits<uint16_t>::max());
-
-  check<int32_t>("-1234567 ffed2979", -1234567);
-  check<int32_t>("-2147483648 80000000", std::numeric_limits<int32_t>::min());
-  check<int32_t>("2147483647 7fffffff", std::numeric_limits<int32_t>::max());
-
-  check<uint32_t>("3456789 34bf15", 3456789);
-  check<uint32_t>("0 0", std::numeric_limits<uint32_t>::min());
-  check<uint32_t>("4294967295 ffffffff", std::numeric_limits<uint32_t>::max());
-
-  check<int64_t>("-1234567 ffffffffffed2979", -1234567);
-  check<int64_t>("-9223372036854775808 8000000000000000",
-                 std::numeric_limits<int64_t>::min());
-  check<int64_t>("9223372036854775807 7fffffffffffffff",
-                 std::numeric_limits<int64_t>::max());
-
-  check<uint64_t>("3456789 34bf15", 3456789);
-  check<uint64_t>("0 0", std::numeric_limits<uint64_t>::min());
-  check<uint64_t>("18446744073709551615 ffffffffffffffff",
-                  std::numeric_limits<uint64_t>::max());
-
-  check<float>("0 0", 0.0f);
-  check<float>("123 123", 123.0f);
-  check<float>("-0.5 -0.5", -0.5f);
-  check<float>("1.25 1.25", 1.25f);
-  check<float>("0.0625 0.0625", 6.25e-2f);
-
-  check<double>("0 0", 0.0);
-  check<double>("123 123", 123.0);
-  check<double>("-0.5 -0.5", -0.5);
-  check<double>("1.25 1.25", 1.25);
-  check<double>("0.0625 0.0625", 6.25e-2);
-}
-
-
-TEST(CharacterOutput) {
-  check<char>("a a", 'a');
-  check<signed char>("B B", 'B');
-  check<unsigned char>("9 9", '9');
-  check<const char*>("bye bye", "bye");
-
-  OStringStream os;
-  os.put('H').write("ello", 4);
-  CHECK_EQ("Hello", os.c_str());
-}
-
-
-TEST(Manipulators) {
-  OStringStream os;
-  os << 123 << hex << 123 << endl << 123 << dec << 123 << 123;
-  CHECK_EQ("1237b\n7b123123", os.c_str());
-}
-
-
-class MiscStuff {
- public:
-  MiscStuff(int i, double d, const char* s) : i_(i), d_(d), s_(s) { }
-
- private:
-  friend OStream& operator<<(OStream& os, const MiscStuff& m);
-
-  int i_;
-  double d_;
-  const char* s_;
-};
-
-
-OStream& operator<<(OStream& os, const MiscStuff& m) {
-  return os << "{i:" << m.i_ << ", d:" << m.d_ << ", s:'" << m.s_ << "'}";
-}
-
-
-TEST(CustomOutput) {
-  OStringStream os;
-  MiscStuff m(123, 4.5, "Hurz!");
-  os << m;
-  CHECK_EQ("{i:123, d:4.5, s:'Hurz!'}", os.c_str());
-}
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc
index 72f2298..08caeab 100644
--- a/test/cctest/test-parsing.cc
+++ b/test/cctest/test-parsing.cc
@@ -31,6 +31,8 @@
 
 #include "src/v8.h"
 
+#include "src/ast.h"
+#include "src/ast-numbering.h"
 #include "src/ast-value-factory.h"
 #include "src/compiler.h"
 #include "src/execution.h"
@@ -317,8 +319,8 @@
 
     i::PreParser preparser(&scanner, &log, stack_limit);
     preparser.set_allow_lazy(true);
-    preparser.set_allow_natives_syntax(true);
-    preparser.set_allow_arrow_functions(true);
+    preparser.set_allow_natives(true);
+    preparser.set_allow_harmony_arrow_functions(true);
     i::PreParser::PreParseResult result = preparser.PreParseProgram();
     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
     CHECK(!log.HasError());
@@ -452,14 +454,14 @@
   i::PreParser::PreParseResult result = preparser.PreParseProgram();
   CHECK_EQ(i::PreParser::kPreParseSuccess, result);
   i::ScriptData* sd = log.GetScriptData();
-  i::ParseData pd(sd);
-  pd.Initialize();
+  i::ParseData* pd = i::ParseData::FromCachedData(sd);
+  pd->Initialize();
 
   int first_function =
       static_cast<int>(strstr(program, "function") - program);
   int first_lbrace = first_function + i::StrLength("function () ");
   CHECK_EQ('{', program[first_lbrace]);
-  i::FunctionEntry entry1 = pd.GetFunctionEntry(first_lbrace);
+  i::FunctionEntry entry1 = pd->GetFunctionEntry(first_lbrace);
   CHECK(!entry1.is_valid());
 
   int second_function =
@@ -467,10 +469,11 @@
   int second_lbrace =
       second_function + i::StrLength("function () ");
   CHECK_EQ('{', program[second_lbrace]);
-  i::FunctionEntry entry2 = pd.GetFunctionEntry(second_lbrace);
+  i::FunctionEntry entry2 = pd->GetFunctionEntry(second_lbrace);
   CHECK(entry2.is_valid());
   CHECK_EQ('}', program[entry2.end_pos() - 1]);
   delete sd;
+  delete pd;
 }
 
 
@@ -496,7 +499,7 @@
 
   i::PreParser preparser(&scanner, &log, stack_limit);
   preparser.set_allow_lazy(true);
-  preparser.set_allow_arrow_functions(true);
+  preparser.set_allow_harmony_arrow_functions(true);
   i::PreParser::PreParseResult result = preparser.PreParseProgram();
   CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
 }
@@ -917,6 +920,142 @@
 }
 
 
+TEST(ScopeUsesArgumentsSuperThis) {
+  static const struct {
+    const char* prefix;
+    const char* suffix;
+  } surroundings[] = {
+    { "function f() {", "}" },
+    { "var f = () => {", "}" },
+  };
+
+  enum Expected {
+    NONE = 0,
+    ARGUMENTS = 1,
+    SUPER_PROPERTY = 2,
+    SUPER_CONSTRUCTOR_CALL = 4,
+    THIS = 8,
+    INNER_ARGUMENTS = 16,
+    INNER_SUPER_PROPERTY = 32,
+    INNER_SUPER_CONSTRUCTOR_CALL = 64,
+    INNER_THIS = 128
+  };
+
+  static const struct {
+    const char* body;
+    int expected;
+  } source_data[] = {
+        {"", NONE},
+        {"return this", THIS},
+        {"return arguments", ARGUMENTS},
+        {"return super()", SUPER_CONSTRUCTOR_CALL},
+        {"return super.x", SUPER_PROPERTY},
+        {"return arguments[0]", ARGUMENTS},
+        {"return this + arguments[0]", ARGUMENTS | THIS},
+        {"return this + arguments[0] + super.x",
+         ARGUMENTS | SUPER_PROPERTY | THIS},
+        {"return x => this + x", INNER_THIS},
+        {"return x => super() + x", INNER_SUPER_CONSTRUCTOR_CALL},
+        {"this.foo = 42;", THIS},
+        {"this.foo();", THIS},
+        {"if (foo()) { this.f() }", THIS},
+        {"if (foo()) { super.f() }", SUPER_PROPERTY},
+        {"if (arguments.length) { this.f() }", ARGUMENTS | THIS},
+        {"while (true) { this.f() }", THIS},
+        {"while (true) { super.f() }", SUPER_PROPERTY},
+        {"if (true) { while (true) this.foo(arguments) }", ARGUMENTS | THIS},
+        // Multiple nesting levels must work as well.
+        {"while (true) { while (true) { while (true) return this } }", THIS},
+        {"while (true) { while (true) { while (true) return super() } }",
+         SUPER_CONSTRUCTOR_CALL},
+        {"if (1) { return () => { while (true) new this() } }", INNER_THIS},
+        {"if (1) { return () => { while (true) new super() } }", NONE},
+        {"if (1) { return () => { while (true) new new super() } }", NONE},
+        // Note that propagation of the inner_uses_this() value does not
+        // cross boundaries of normal functions onto parent scopes.
+        {"return function (x) { return this + x }", NONE},
+        {"return function (x) { return super() + x }", NONE},
+        {"var x = function () { this.foo = 42 };", NONE},
+        {"var x = function () { super.foo = 42 };", NONE},
+        {"if (1) { return function () { while (true) new this() } }", NONE},
+        {"if (1) { return function () { while (true) new super() } }", NONE},
+        {"return function (x) { return () => this }", NONE},
+        {"return function (x) { return () => super() }", NONE},
+        // Flags must be correctly set when using block scoping.
+        {"\"use strict\"; while (true) { let x; this, arguments; }",
+         INNER_ARGUMENTS | INNER_THIS},
+        {"\"use strict\"; while (true) { let x; this, super(), arguments; }",
+         INNER_ARGUMENTS | INNER_SUPER_CONSTRUCTOR_CALL | INNER_THIS},
+        {"\"use strict\"; if (foo()) { let x; this.f() }", INNER_THIS},
+        {"\"use strict\"; if (foo()) { let x; super.f() }",
+         INNER_SUPER_PROPERTY},
+        {"\"use strict\"; if (1) {"
+         "  let x; return function () { return this + super() + arguments }"
+         "}",
+         NONE},
+    };
+
+  i::Isolate* isolate = CcTest::i_isolate();
+  i::Factory* factory = isolate->factory();
+
+  v8::HandleScope handles(CcTest::isolate());
+  v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
+  v8::Context::Scope context_scope(context);
+
+  isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
+                                        128 * 1024);
+
+  for (unsigned j = 0; j < arraysize(surroundings); ++j) {
+    for (unsigned i = 0; i < arraysize(source_data); ++i) {
+      int kProgramByteSize = i::StrLength(surroundings[j].prefix) +
+                             i::StrLength(surroundings[j].suffix) +
+                             i::StrLength(source_data[i].body);
+      i::ScopedVector<char> program(kProgramByteSize + 1);
+      i::SNPrintF(program, "%s%s%s", surroundings[j].prefix,
+                  source_data[i].body, surroundings[j].suffix);
+      i::Handle<i::String> source =
+          factory->NewStringFromUtf8(i::CStrVector(program.start()))
+              .ToHandleChecked();
+      i::Handle<i::Script> script = factory->NewScript(source);
+      i::CompilationInfoWithZone info(script);
+      i::Parser::ParseInfo parse_info = {isolate->stack_guard()->real_climit(),
+                                         isolate->heap()->HashSeed(),
+                                         isolate->unicode_cache()};
+      i::Parser parser(&info, &parse_info);
+      parser.set_allow_harmony_arrow_functions(true);
+      parser.set_allow_harmony_classes(true);
+      parser.set_allow_harmony_scoping(true);
+      info.MarkAsGlobal();
+      parser.Parse();
+      CHECK(i::Rewriter::Rewrite(&info));
+      CHECK(i::Scope::Analyze(&info));
+      CHECK(info.function() != NULL);
+
+      i::Scope* script_scope = info.function()->scope();
+      CHECK(script_scope->is_script_scope());
+      CHECK_EQ(1, script_scope->inner_scopes()->length());
+
+      i::Scope* scope = script_scope->inner_scopes()->at(0);
+      CHECK_EQ((source_data[i].expected & ARGUMENTS) != 0,
+               scope->uses_arguments());
+      CHECK_EQ((source_data[i].expected & SUPER_PROPERTY) != 0,
+               scope->uses_super_property());
+      CHECK_EQ((source_data[i].expected & SUPER_CONSTRUCTOR_CALL) != 0,
+               scope->uses_super_constructor_call());
+      CHECK_EQ((source_data[i].expected & THIS) != 0, scope->uses_this());
+      CHECK_EQ((source_data[i].expected & INNER_ARGUMENTS) != 0,
+               scope->inner_uses_arguments());
+      CHECK_EQ((source_data[i].expected & INNER_SUPER_PROPERTY) != 0,
+               scope->inner_uses_super_property());
+      CHECK_EQ((source_data[i].expected & INNER_SUPER_CONSTRUCTOR_CALL) != 0,
+               scope->inner_uses_super_constructor_call());
+      CHECK_EQ((source_data[i].expected & INNER_THIS) != 0,
+               scope->inner_uses_this());
+    }
+  }
+}
+
+
 TEST(ScopePositions) {
   v8::internal::FLAG_harmony_scoping = true;
 
@@ -974,11 +1113,10 @@
       "    infunction;\n"
       "  }", "\n"
       "  more;", i::FUNCTION_SCOPE, i::SLOPPY },
-    // TODO(aperez): Change to use i::ARROW_SCOPE when implemented
     { "  start;\n", "(a,b) => a + b", "; more;",
-      i::FUNCTION_SCOPE, i::SLOPPY },
+      i::ARROW_SCOPE, i::SLOPPY },
     { "  start;\n", "(a,b) => { return a+b; }", "\nmore;",
-      i::FUNCTION_SCOPE, i::SLOPPY },
+      i::ARROW_SCOPE, i::SLOPPY },
     { "  start;\n"
       "  (function fun", "(a,b) { infunction; }", ")();",
       i::FUNCTION_SCOPE, i::SLOPPY },
@@ -1137,7 +1275,7 @@
     i::Parser parser(&info, &parse_info);
     parser.set_allow_lazy(true);
     parser.set_allow_harmony_scoping(true);
-    parser.set_allow_arrow_functions(true);
+    parser.set_allow_harmony_arrow_functions(true);
     info.MarkAsGlobal();
     info.SetStrictMode(source_data[i].strict_mode);
     parser.Parse();
@@ -1145,7 +1283,7 @@
 
     // Check scope types and positions.
     i::Scope* scope = info.function()->scope();
-    CHECK(scope->is_global_scope());
+    CHECK(scope->is_script_scope());
     CHECK_EQ(scope->start_position(), 0);
     CHECK_EQ(scope->end_position(), kProgramSize);
     CHECK_EQ(scope->inner_scopes()->length(), 1);
@@ -1211,13 +1349,16 @@
 
 enum ParserFlag {
   kAllowLazy,
-  kAllowNativesSyntax,
+  kAllowNatives,
   kAllowHarmonyScoping,
-  kAllowModules,
+  kAllowHarmonyModules,
   kAllowHarmonyNumericLiterals,
-  kAllowArrowFunctions,
-  kAllowClasses,
-  kAllowHarmonyObjectLiterals
+  kAllowHarmonyArrowFunctions,
+  kAllowHarmonyClasses,
+  kAllowHarmonyObjectLiterals,
+  kAllowHarmonyTemplates,
+  kAllowHarmonySloppy,
+  kAllowHarmonyUnicode
 };
 
 
@@ -1231,15 +1372,19 @@
 void SetParserFlags(i::ParserBase<Traits>* parser,
                     i::EnumSet<ParserFlag> flags) {
   parser->set_allow_lazy(flags.Contains(kAllowLazy));
-  parser->set_allow_natives_syntax(flags.Contains(kAllowNativesSyntax));
+  parser->set_allow_natives(flags.Contains(kAllowNatives));
   parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping));
-  parser->set_allow_modules(flags.Contains(kAllowModules));
+  parser->set_allow_harmony_modules(flags.Contains(kAllowHarmonyModules));
   parser->set_allow_harmony_numeric_literals(
       flags.Contains(kAllowHarmonyNumericLiterals));
   parser->set_allow_harmony_object_literals(
       flags.Contains(kAllowHarmonyObjectLiterals));
-  parser->set_allow_arrow_functions(flags.Contains(kAllowArrowFunctions));
-  parser->set_allow_classes(flags.Contains(kAllowClasses));
+  parser->set_allow_harmony_arrow_functions(
+      flags.Contains(kAllowHarmonyArrowFunctions));
+  parser->set_allow_harmony_classes(flags.Contains(kAllowHarmonyClasses));
+  parser->set_allow_harmony_templates(flags.Contains(kAllowHarmonyTemplates));
+  parser->set_allow_harmony_sloppy(flags.Contains(kAllowHarmonySloppy));
+  parser->set_allow_harmony_unicode(flags.Contains(kAllowHarmonyUnicode));
 }
 
 
@@ -1250,6 +1395,8 @@
   i::Factory* factory = isolate->factory();
 
   uintptr_t stack_limit = isolate->stack_guard()->real_climit();
+  int preparser_materialized_literals = -1;
+  int parser_materialized_literals = -2;
 
   // Preparse the data.
   i::CompleteParserRecorder log;
@@ -1259,7 +1406,8 @@
     i::PreParser preparser(&scanner, &log, stack_limit);
     SetParserFlags(&preparser, flags);
     scanner.Initialize(&stream);
-    i::PreParser::PreParseResult result = preparser.PreParseProgram();
+    i::PreParser::PreParseResult result = preparser.PreParseProgram(
+        &preparser_materialized_literals);
     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
   }
 
@@ -1278,6 +1426,9 @@
     info.MarkAsGlobal();
     parser.Parse();
     function = info.function();
+    if (function) {
+      parser_materialized_literals = function->materialized_literal_count();
+    }
   }
 
   // Check that preparsing fails iff parsing fails.
@@ -1343,6 +1494,15 @@
         "However, parser and preparser succeeded",
         source->ToCString().get());
     CHECK(false);
+  } else if (preparser_materialized_literals != parser_materialized_literals) {
+    v8::base::OS::Print(
+        "Preparser materialized literals (%d) differ from Parser materialized "
+        "literals (%d) on:\n"
+        "\t%s\n"
+        "However, parser and preparser succeeded",
+        preparser_materialized_literals, parser_materialized_literals,
+        source->ToCString().get());
+    CHECK(false);
   }
 }
 
@@ -1352,7 +1512,9 @@
                     size_t varying_flags_length,
                     ParserSyncTestResult result = kSuccessOrError,
                     const ParserFlag* always_true_flags = NULL,
-                    size_t always_true_flags_length = 0) {
+                    size_t always_true_flags_length = 0,
+                    const ParserFlag* always_false_flags = NULL,
+                    size_t always_false_flags_length = 0) {
   i::Handle<i::String> str =
       CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source);
   for (int bits = 0; bits < (1 << varying_flags_length); bits++) {
@@ -1365,6 +1527,10 @@
          ++flag_index) {
       flags.Add(always_true_flags[flag_index]);
     }
+    for (size_t flag_index = 0; flag_index < always_false_flags_length;
+         ++flag_index) {
+      flags.Remove(always_false_flags[flag_index]);
+    }
     TestParserSyncWithFlags(str, flags, result);
   }
 }
@@ -1399,7 +1565,7 @@
     "if (false) {} else ;",
     "if (false) {} else {}",
     "if (false) {} else 12",
-    "if (false) ;"
+    "if (false) ;",
     "if (false) {}",
     "if (false) 12",
     "do {} while (false)",
@@ -1419,8 +1585,8 @@
     "with ({}) ;",
     "with ({}) {}",
     "with ({}) 12",
-    "switch ({}) { default: }"
-    "label3: "
+    "switch ({}) { default: }",
+    "label3: ",
     "throw",
     "throw  12",
     "throw\n12",
@@ -1447,16 +1613,6 @@
   CcTest::i_isolate()->stack_guard()->SetStackLimit(
       i::GetCurrentStackPosition() - 128 * 1024);
 
-  static const ParserFlag flags1[] = {
-    kAllowArrowFunctions,
-    kAllowClasses,
-    kAllowHarmonyNumericLiterals,
-    kAllowHarmonyObjectLiterals,
-    kAllowHarmonyScoping,
-    kAllowLazy,
-    kAllowModules,
-  };
-
   for (int i = 0; context_data[i][0] != NULL; ++i) {
     for (int j = 0; statement_data[j] != NULL; ++j) {
       for (int k = 0; termination_data[k] != NULL; ++k) {
@@ -1476,7 +1632,7 @@
             termination_data[k],
             context_data[i][1]);
         CHECK(length == kProgramSize);
-        TestParserSync(program.start(), flags1, arraysize(flags1));
+        TestParserSync(program.start(), NULL, 0);
       }
     }
   }
@@ -1488,7 +1644,7 @@
   TestParserSync("0o1234", flags2, arraysize(flags2));
   TestParserSync("0b1011", flags2, arraysize(flags2));
 
-  static const ParserFlag flags3[] = { kAllowNativesSyntax };
+  static const ParserFlag flags3[] = { kAllowNatives };
   TestParserSync("%DebugPrint(123)", flags3, arraysize(flags3));
 }
 
@@ -1522,7 +1678,9 @@
                        const ParserFlag* flags = NULL,
                        int flags_len = 0,
                        const ParserFlag* always_true_flags = NULL,
-                       int always_true_flags_len = 0) {
+                       int always_true_len = 0,
+                       const ParserFlag* always_false_flags = NULL,
+                       int always_false_len = 0) {
   v8::HandleScope handles(CcTest::isolate());
   v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
   v8::Context::Scope context_scope(context);
@@ -1530,36 +1688,32 @@
   CcTest::i_isolate()->stack_guard()->SetStackLimit(
       i::GetCurrentStackPosition() - 128 * 1024);
 
+  // Experimental feature flags should not go here; pass the flags as
+  // always_true_flags if the test needs them.
   static const ParserFlag default_flags[] = {
-    kAllowArrowFunctions,
-    kAllowClasses,
-    kAllowHarmonyNumericLiterals,
-    kAllowHarmonyObjectLiterals,
-    kAllowHarmonyScoping,
     kAllowLazy,
-    kAllowModules,
-    kAllowNativesSyntax,
+    kAllowNatives,
   };
   ParserFlag* generated_flags = NULL;
   if (flags == NULL) {
     flags = default_flags;
     flags_len = arraysize(default_flags);
-    if (always_true_flags != NULL) {
-      // Remove always_true_flags from default_flags.
-      CHECK(always_true_flags_len < flags_len);
-      generated_flags = new ParserFlag[flags_len - always_true_flags_len];
+    if (always_true_flags != NULL || always_false_flags != NULL) {
+      // Remove always_true/false_flags from default_flags (if present).
+      CHECK((always_true_flags != NULL) == (always_true_len > 0));
+      CHECK((always_false_flags != NULL) == (always_false_len > 0));
+      generated_flags = new ParserFlag[flags_len + always_true_len];
       int flag_index = 0;
       for (int i = 0; i < flags_len; ++i) {
         bool use_flag = true;
-        for (int j = 0; j < always_true_flags_len; ++j) {
-          if (flags[i] == always_true_flags[j]) {
-            use_flag = false;
-            break;
-          }
+        for (int j = 0; use_flag && j < always_true_len; ++j) {
+          if (flags[i] == always_true_flags[j]) use_flag = false;
+        }
+        for (int j = 0; use_flag && j < always_false_len; ++j) {
+          if (flags[i] == always_false_flags[j]) use_flag = false;
         }
         if (use_flag) generated_flags[flag_index++] = flags[i];
       }
-      CHECK(flag_index == flags_len - always_true_flags_len);
       flags_len = flag_index;
       flags = generated_flags;
     }
@@ -1584,7 +1738,9 @@
                      flags_len,
                      result,
                      always_true_flags,
-                     always_true_flags_len);
+                     always_true_len,
+                     always_false_flags,
+                     always_false_len);
     }
   }
   delete[] generated_flags;
@@ -1691,45 +1847,70 @@
     NULL
   };
 
-  static const ParserFlag always_flags[] = {kAllowArrowFunctions};
+  static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions};
   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
 }
 
 
+#define FUTURE_STRICT_RESERVED_WORDS(V) \
+  V(implements)                         \
+  V(interface)                          \
+  V(let)                                \
+  V(package)                            \
+  V(private)                            \
+  V(protected)                          \
+  V(public)                             \
+  V(static)                             \
+  V(yield)
+
+
+#define LIMITED_FUTURE_STRICT_RESERVED_WORDS(V) \
+  V(implements)                                 \
+  V(let)                                        \
+  V(static)                                     \
+  V(yield)
+
+
+#define FUTURE_STRICT_RESERVED_STATEMENTS(NAME) \
+  "var " #NAME ";",                             \
+  "var foo, " #NAME ";",                        \
+  "try { } catch (" #NAME ") { }",              \
+  "function " #NAME "() { }",                   \
+  "(function " #NAME "() { })",                 \
+  "function foo(" #NAME ") { }",                \
+  "function foo(bar, " #NAME ") { }",           \
+  #NAME " = 1;",                                \
+  #NAME " += 1;",                               \
+  "var foo = " #NAME " = 1;",                   \
+  "++" #NAME ";",                               \
+  #NAME " ++;",
+
+
 TEST(ErrorsFutureStrictReservedWords) {
   // Tests that both preparsing and parsing produce the right kind of errors for
   // using future strict reserved words as identifiers. Without the strict mode,
   // it's ok to use future strict reserved words as identifiers. With the strict
   // mode, it isn't.
   const char* context_data[][2] = {
-    { "\"use strict\";", "" },
     { "function test_func() {\"use strict\"; ", "}"},
     { "() => { \"use strict\"; ", "}" },
     { NULL, NULL }
   };
 
-  const char* statement_data[] = {
-    "var interface;",
-    "var foo, interface;",
-    "try { } catch (interface) { }",
-    "function interface() { }",
-    "function foo(interface) { }",
-    "function foo(bar, interface) { }",
-    "interface = 1;",
-    "var foo = interface = 1;",
-    "++interface;",
-    "interface++;",
-    "var yield = 13;",
+  const char* statement_data[] {
+    LIMITED_FUTURE_STRICT_RESERVED_WORDS(FUTURE_STRICT_RESERVED_STATEMENTS)
     NULL
   };
 
-  static const ParserFlag always_flags[] = {kAllowArrowFunctions};
-  RunParserSyncTest(context_data, statement_data, kError, NULL, 0, always_flags,
-                    arraysize(always_flags));
+  RunParserSyncTest(context_data, statement_data, kError);
+  RunParserSyncTest(context_data, statement_data, kError);
 }
 
 
+#undef LIMITED_FUTURE_STRICT_RESERVED_WORDS
+
+
 TEST(NoErrorsFutureStrictReservedWords) {
   const char* context_data[][2] = {
     { "", "" },
@@ -1739,23 +1920,18 @@
   };
 
   const char* statement_data[] = {
-    "var interface;",
-    "var foo, interface;",
-    "try { } catch (interface) { }",
-    "function interface() { }",
-    "function foo(interface) { }",
-    "function foo(bar, interface) { }",
-    "interface = 1;",
-    "var foo = interface = 1;",
-    "++interface;",
-    "interface++;",
-    "var yield = 13;",
+    FUTURE_STRICT_RESERVED_WORDS(FUTURE_STRICT_RESERVED_STATEMENTS)
     NULL
   };
 
-  static const ParserFlag always_flags[] = {kAllowArrowFunctions};
+  static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions};
   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
+
+  static const ParserFlag classes_flags[] = {
+      kAllowHarmonyArrowFunctions, kAllowHarmonyClasses, kAllowHarmonyScoping};
+  RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+                    classes_flags, arraysize(classes_flags));
 }
 
 
@@ -2135,12 +2311,13 @@
     { NULL, NULL }
   };
 
+#define LABELLED_WHILE(NAME) #NAME ": while (true) { break " #NAME "; }",
   const char* statement_data[] = {
     "super: while(true) { break super; }",
-    "interface: while(true) { break interface; }",
-    "yield: while(true) { break yield; }",
+    FUTURE_STRICT_RESERVED_WORDS(LABELLED_WHILE)
     NULL
   };
+#undef LABELLED_WHILE
 
   RunParserSyncTest(context_data, statement_data, kError);
 }
@@ -2165,7 +2342,28 @@
     NULL
   };
 
-  static const ParserFlag always_flags[] = {kAllowArrowFunctions};
+  static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions};
+  RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
+                    always_flags, arraysize(always_flags));
+}
+
+
+TEST(NoErrorsFutureStrictReservedAsLabelsSloppy) {
+  const char* context_data[][2] = {
+    { "", ""},
+    { "function test_func() {", "}" },
+    { "() => {", "}" },
+    { NULL, NULL }
+  };
+
+#define LABELLED_WHILE(NAME) #NAME ": while (true) { break " #NAME "; }",
+  const char* statement_data[] {
+    FUTURE_STRICT_RESERVED_WORDS(LABELLED_WHILE)
+    NULL
+  };
+#undef LABELLED_WHILE
+
+  static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions};
   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
 }
@@ -2285,17 +2483,18 @@
     i::ScriptData* sd = NULL;
     info.SetCachedData(&sd, v8::ScriptCompiler::kProduceParserCache);
     i::Parser::Parse(&info, true);
-    i::ParseData pd(sd);
+    i::ParseData* pd = i::ParseData::FromCachedData(sd);
 
-    if (pd.FunctionCount() != test_cases[i].functions) {
+    if (pd->FunctionCount() != test_cases[i].functions) {
       v8::base::OS::Print(
           "Expected preparse data for program:\n"
           "\t%s\n"
           "to contain %d functions, however, received %d functions.\n",
-          program, test_cases[i].functions, pd.FunctionCount());
+          program, test_cases[i].functions, pd->FunctionCount());
       CHECK(false);
     }
     delete sd;
+    delete pd;
   }
 }
 
@@ -2416,9 +2615,9 @@
     NULL
   };
 
-  // This test requires kAllowNativesSyntax to succeed.
+  // This test requires kAllowNatives to succeed.
   static const ParserFlag always_true_flags[] = {
-    kAllowNativesSyntax
+    kAllowNatives
   };
 
   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
@@ -2904,11 +3103,11 @@
   const i::AstRawString* name = avf.GetOneByteString("result");
   i::Handle<i::String> str = name->string();
   CHECK(str->IsInternalizedString());
-  i::Scope* global_scope =
-      new (&zone) i::Scope(NULL, i::GLOBAL_SCOPE, &avf, &zone);
-  global_scope->Initialize();
-  i::Scope* s = i::Scope::DeserializeScopeChain(context, global_scope, &zone);
-  DCHECK(s != global_scope);
+  i::Scope* script_scope =
+      new (&zone) i::Scope(NULL, i::SCRIPT_SCOPE, &avf, &zone);
+  script_scope->Initialize();
+  i::Scope* s = i::Scope::DeserializeScopeChain(context, script_scope, &zone);
+  DCHECK(s != script_scope);
   DCHECK(name != NULL);
 
   // Get result from h's function context (that is f's context)
@@ -2951,11 +3150,11 @@
   i::AstValueFactory avf(&zone, isolate->heap()->HashSeed());
   avf.Internalize(isolate);
 
-  i::Scope* global_scope =
-      new (&zone) i::Scope(NULL, i::GLOBAL_SCOPE, &avf, &zone);
-  global_scope->Initialize();
-  i::Scope* s = i::Scope::DeserializeScopeChain(context, global_scope, &zone);
-  DCHECK(s != global_scope);
+  i::Scope* script_scope =
+      new (&zone) i::Scope(NULL, i::SCRIPT_SCOPE, &avf, &zone);
+  script_scope->Initialize();
+  i::Scope* s = i::Scope::DeserializeScopeChain(context, script_scope, &zone);
+  DCHECK(s != script_scope);
   const i::AstRawString* name_x = avf.GetOneByteString("x");
 
   // Get result from f's function context (that is g's outer context)
@@ -2998,11 +3197,11 @@
   i::AstValueFactory avf(&zone, isolate->heap()->HashSeed());
   avf.Internalize(isolate);
 
-  i::Scope* global_scope =
-      new (&zone) i::Scope(NULL, i::GLOBAL_SCOPE, &avf, &zone);
-  global_scope->Initialize();
-  i::Scope* s = i::Scope::DeserializeScopeChain(context, global_scope, &zone);
-  DCHECK(s != global_scope);
+  i::Scope* script_scope =
+      new (&zone) i::Scope(NULL, i::SCRIPT_SCOPE, &avf, &zone);
+  script_scope->Initialize();
+  i::Scope* s = i::Scope::DeserializeScopeChain(context, script_scope, &zone);
+  DCHECK(s != script_scope);
   const i::AstRawString* name_x = avf.GetOneByteString("x");
   const i::AstRawString* name_f = avf.GetOneByteString("f");
   const i::AstRawString* name_y = avf.GetOneByteString("y");
@@ -3156,8 +3355,7 @@
           i::Parser parser(&info, &parse_info);
           parser.set_allow_harmony_scoping(true);
           CHECK(parser.Parse());
-          CHECK(i::Rewriter::Rewrite(&info));
-          CHECK(i::Scope::Analyze(&info));
+          CHECK(i::Compiler::Analyze(&info));
           CHECK(info.function() != NULL);
 
           i::Scope* scope = info.function()->scope();
@@ -3304,7 +3502,7 @@
 
   // The test is quite slow, so run it with a reduced set of flags.
   static const ParserFlag flags[] = {kAllowLazy, kAllowHarmonyScoping};
-  static const ParserFlag always_flags[] = { kAllowArrowFunctions };
+  static const ParserFlag always_flags[] = { kAllowHarmonyArrowFunctions };
   RunParserSyncTest(context_data, statement_data, kError, flags,
                     arraysize(flags), always_flags, arraysize(always_flags));
 }
@@ -3358,7 +3556,7 @@
     NULL
   };
 
-  static const ParserFlag always_flags[] = {kAllowArrowFunctions};
+  static const ParserFlag always_flags[] = {kAllowHarmonyArrowFunctions};
   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
 }
@@ -3383,7 +3581,7 @@
     "z.super",  // Ok, property lookup.
     NULL};
 
-  static const ParserFlag always_flags[] = {kAllowClasses};
+  static const ParserFlag always_flags[] = {kAllowHarmonyClasses};
   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
 }
@@ -3402,7 +3600,7 @@
     "f(super)",
     NULL};
 
-  static const ParserFlag always_flags[] = {kAllowClasses};
+  static const ParserFlag always_flags[] = {kAllowHarmonyClasses};
   RunParserSyncTest(context_data, statement_data, kError, NULL, 0,
                     always_flags, arraysize(always_flags));
 }
@@ -3585,7 +3783,8 @@
     "class name extends class base {} {}",
     NULL};
 
-  static const ParserFlag always_flags[] = {kAllowClasses};
+  static const ParserFlag always_flags[] = {
+      kAllowHarmonyClasses, kAllowHarmonySloppy};
   RunParserSyncTest(context_data, class_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
 }
@@ -3604,7 +3803,8 @@
     "class name extends class base {} {}",
     NULL};
 
-  static const ParserFlag always_flags[] = {kAllowClasses};
+  static const ParserFlag always_flags[] = {
+      kAllowHarmonyClasses, kAllowHarmonySloppy};
   RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
 }
@@ -3648,8 +3848,9 @@
     NULL};
 
   static const ParserFlag always_flags[] = {
-    kAllowClasses,
-    kAllowHarmonyObjectLiterals
+    kAllowHarmonyClasses,
+    kAllowHarmonyObjectLiterals,
+    kAllowHarmonySloppy
   };
   RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
@@ -3706,8 +3907,9 @@
     NULL};
 
   static const ParserFlag always_flags[] = {
-    kAllowClasses,
-    kAllowHarmonyObjectLiterals
+    kAllowHarmonyClasses,
+    kAllowHarmonyObjectLiterals,
+    kAllowHarmonySloppy
   };
   RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
@@ -3737,8 +3939,9 @@
     NULL};
 
   static const ParserFlag always_flags[] = {
-    kAllowClasses,
-    kAllowHarmonyObjectLiterals
+    kAllowHarmonyClasses,
+    kAllowHarmonyObjectLiterals,
+    kAllowHarmonySloppy
   };
   RunParserSyncTest(context_data, class_data, kError, NULL, 0,
                     always_flags, arraysize(always_flags));
@@ -3774,8 +3977,9 @@
     NULL};
 
   static const ParserFlag always_flags[] = {
-    kAllowClasses,
-    kAllowHarmonyNumericLiterals
+    kAllowHarmonyClasses,
+    kAllowHarmonyNumericLiterals,
+    kAllowHarmonySloppy
   };
   RunParserSyncTest(context_data, class_data, kError, NULL, 0,
                     always_flags, arraysize(always_flags));
@@ -3804,8 +4008,9 @@
     NULL};
 
   static const ParserFlag always_flags[] = {
-    kAllowClasses,
-    kAllowHarmonyObjectLiterals
+    kAllowHarmonyClasses,
+    kAllowHarmonyObjectLiterals,
+    kAllowHarmonySloppy
   };
   RunParserSyncTest(context_data, class_name, kError, NULL, 0,
                     always_flags, arraysize(always_flags));
@@ -3837,8 +4042,9 @@
     NULL};
 
   static const ParserFlag always_flags[] = {
-    kAllowClasses,
-    kAllowHarmonyObjectLiterals
+    kAllowHarmonyClasses,
+    kAllowHarmonyObjectLiterals,
+    kAllowHarmonySloppy
   };
   RunParserSyncTest(context_data, class_name, kError, NULL, 0,
                     always_flags, arraysize(always_flags));
@@ -3855,11 +4061,19 @@
     "static get prototype() {}",
     "static set prototype(_) {}",
     "static *prototype() {}",
+    "static 'prototype'() {}",
+    "static *'prototype'() {}",
+    "static prot\\u006ftype() {}",
+    "static 'prot\\u006ftype'() {}",
+    "static get 'prot\\u006ftype'() {}",
+    "static set 'prot\\u006ftype'(_) {}",
+    "static *'prot\\u006ftype'() {}",
     NULL};
 
   static const ParserFlag always_flags[] = {
-    kAllowClasses,
-    kAllowHarmonyObjectLiterals
+    kAllowHarmonyClasses,
+    kAllowHarmonyObjectLiterals,
+    kAllowHarmonySloppy
   };
   RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
                     always_flags, arraysize(always_flags));
@@ -3875,11 +4089,19 @@
     "get constructor() {}",
     "get constructor(_) {}",
     "*constructor() {}",
+    "get 'constructor'() {}",
+    "*'constructor'() {}",
+    "get c\\u006fnstructor() {}",
+    "*c\\u006fnstructor() {}",
+    "get 'c\\u006fnstructor'() {}",
+    "get 'c\\u006fnstructor'(_) {}",
+    "*'c\\u006fnstructor'() {}",
     NULL};
 
   static const ParserFlag always_flags[] = {
-    kAllowClasses,
-    kAllowHarmonyObjectLiterals
+    kAllowHarmonyClasses,
+    kAllowHarmonyObjectLiterals,
+    kAllowHarmonySloppy
   };
   RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
                     always_flags, arraysize(always_flags));
@@ -3900,8 +4122,9 @@
     NULL};
 
   static const ParserFlag always_flags[] = {
-    kAllowClasses,
-    kAllowHarmonyObjectLiterals
+    kAllowHarmonyClasses,
+    kAllowHarmonyObjectLiterals,
+    kAllowHarmonySloppy
   };
   RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
@@ -3909,9 +4132,6 @@
 
 
 TEST(ClassMultipleConstructorErrors) {
-  // We currently do not allow any duplicate properties in class bodies. This
-  // test ensures that when we change that we still throw on duplicate
-  // constructors.
   const char* context_data[][2] = {{"class C {", "}"},
                                    {"(class {", "});"},
                                    {NULL, NULL}};
@@ -3921,17 +4141,16 @@
     NULL};
 
   static const ParserFlag always_flags[] = {
-    kAllowClasses,
-    kAllowHarmonyObjectLiterals
+    kAllowHarmonyClasses,
+    kAllowHarmonyObjectLiterals,
+    kAllowHarmonySloppy
   };
   RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
                     always_flags, arraysize(always_flags));
 }
 
 
-// TODO(arv): We should allow duplicate property names.
-// https://code.google.com/p/v8/issues/detail?id=3570
-DISABLED_TEST(ClassMultiplePropertyNamesNoErrors) {
+TEST(ClassMultiplePropertyNamesNoErrors) {
   const char* context_data[][2] = {{"class C {", "}"},
                                    {"(class {", "});"},
                                    {NULL, NULL}};
@@ -3940,11 +4159,14 @@
     "constructor() {}; static constructor() {}",
     "m() {}; static m() {}",
     "m() {}; m() {}",
+    "static m() {}; static m() {}",
+    "get m() {}; set m(_) {}; get m() {}; set m(_) {};",
     NULL};
 
   static const ParserFlag always_flags[] = {
-    kAllowClasses,
-    kAllowHarmonyObjectLiterals
+    kAllowHarmonyClasses,
+    kAllowHarmonyObjectLiterals,
+    kAllowHarmonySloppy
   };
   RunParserSyncTest(context_data, class_body_data, kSuccess, NULL, 0,
                     always_flags, arraysize(always_flags));
@@ -3963,9 +4185,422 @@
     NULL};
 
   static const ParserFlag always_flags[] = {
-    kAllowClasses,
-    kAllowHarmonyObjectLiterals
+    kAllowHarmonyClasses,
+    kAllowHarmonyObjectLiterals,
+    kAllowHarmonySloppy
   };
   RunParserSyncTest(context_data, class_body_data, kError, NULL, 0,
                     always_flags, arraysize(always_flags));
 }
+
+
+TEST(ObjectLiteralPropertyShorthandKeywordsError) {
+  const char* context_data[][2] = {{"({", "});"},
+                                   {"'use strict'; ({", "});"},
+                                   {NULL, NULL}};
+
+  const char* name_data[] = {
+    "break",
+    "case",
+    "catch",
+    "class",
+    "const",
+    "continue",
+    "debugger",
+    "default",
+    "delete",
+    "do",
+    "else",
+    "enum",
+    "export",
+    "extends",
+    "false",
+    "finally",
+    "for",
+    "function",
+    "if",
+    "import",
+    "in",
+    "instanceof",
+    "new",
+    "null",
+    "return",
+    "super",
+    "switch",
+    "this",
+    "throw",
+    "true",
+    "try",
+    "typeof",
+    "var",
+    "void",
+    "while",
+    "with",
+    NULL
+  };
+
+  static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
+  RunParserSyncTest(context_data, name_data, kError, NULL, 0,
+                    always_flags, arraysize(always_flags));
+}
+
+
+TEST(ObjectLiteralPropertyShorthandStrictKeywords) {
+  const char* context_data[][2] = {{"({", "});"},
+                                   {NULL, NULL}};
+
+  const char* name_data[] = {
+    "implements",
+    "interface",
+    "let",
+    "package",
+    "private",
+    "protected",
+    "public",
+    "static",
+    "yield",
+    NULL
+  };
+
+  static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
+  RunParserSyncTest(context_data, name_data, kSuccess, NULL, 0,
+                    always_flags, arraysize(always_flags));
+
+  const char* context_strict_data[][2] = {{"'use strict'; ({", "});"},
+                                          {NULL, NULL}};
+  RunParserSyncTest(context_strict_data, name_data, kError, NULL, 0,
+                    always_flags, arraysize(always_flags));
+}
+
+
+TEST(ObjectLiteralPropertyShorthandError) {
+  const char* context_data[][2] = {{"({", "});"},
+                                   {"'use strict'; ({", "});"},
+                                   {NULL, NULL}};
+
+  const char* name_data[] = {
+    "1",
+    "1.2",
+    "0",
+    "0.1",
+    "1.0",
+    "1e1",
+    "0x1",
+    "\"s\"",
+    "'s'",
+    NULL
+  };
+
+  static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
+  RunParserSyncTest(context_data, name_data, kError, NULL, 0,
+                    always_flags, arraysize(always_flags));
+}
+
+
+TEST(ObjectLiteralPropertyShorthandYieldInGeneratorError) {
+  const char* context_data[][2] = {{"", ""},
+                                   {NULL, NULL}};
+
+  const char* name_data[] = {
+    "function* g() { ({yield}); }",
+    NULL
+  };
+
+  static const ParserFlag always_flags[] = {kAllowHarmonyObjectLiterals};
+  RunParserSyncTest(context_data, name_data, kError, NULL, 0,
+                    always_flags, arraysize(always_flags));
+}
+
+
+TEST(ConstParsingInForIn) {
+  const char* context_data[][2] = {{"'use strict';", ""},
+                                   {"function foo(){ 'use strict';", "}"},
+                                   {NULL, NULL}};
+
+  const char* data[] = {
+      "for(const x = 1; ; ) {}",
+      "for(const x = 1, y = 2;;){}",
+      "for(const x in [1,2,3]) {}",
+      "for(const x of [1,2,3]) {}",
+      NULL};
+  static const ParserFlag always_flags[] = {kAllowHarmonyScoping};
+  RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
+                    arraysize(always_flags));
+}
+
+
+TEST(ConstParsingInForInError) {
+  const char* context_data[][2] = {{"'use strict';", ""},
+                                   {"function foo(){ 'use strict';", "}"},
+                                   {NULL, NULL}};
+
+  const char* data[] = {
+      "for(const x,y = 1; ; ) {}",
+      "for(const x = 4 in [1,2,3]) {}",
+      "for(const x = 4, y in [1,2,3]) {}",
+      "for(const x = 4 of [1,2,3]) {}",
+      "for(const x = 4, y of [1,2,3]) {}",
+      "for(const x = 1, y = 2 in []) {}",
+      "for(const x,y in []) {}",
+      "for(const x = 1, y = 2 of []) {}",
+      "for(const x,y of []) {}",
+      NULL};
+  static const ParserFlag always_flags[] = {kAllowHarmonyScoping};
+  RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
+                    arraysize(always_flags));
+}
+
+
+TEST(InvalidUnicodeEscapes) {
+  const char* context_data[][2] = {{"", ""},
+                                   {"'use strict';", ""},
+                                   {NULL, NULL}};
+  const char* data[] = {
+    "var foob\\u123r = 0;",
+    "var \\u123roo = 0;",
+    "\"foob\\u123rr\"",
+    // No escapes allowed in regexp flags
+    "/regex/\\u0069g",
+    "/regex/\\u006g",
+    // Braces gone wrong
+    "var foob\\u{c481r = 0;",
+    "var foob\\uc481}r = 0;",
+    "var \\u{0052oo = 0;",
+    "var \\u0052}oo = 0;",
+    "\"foob\\u{c481r\"",
+    "var foob\\u{}ar = 0;",
+    // Too high value for the unicode escape
+    "\"\\u{110000}\"",
+    // Not an unicode escape
+    "var foob\\v1234r = 0;",
+    "var foob\\U1234r = 0;",
+    "var foob\\v{1234}r = 0;",
+    "var foob\\U{1234}r = 0;",
+    NULL};
+  static const ParserFlag always_flags[] = {kAllowHarmonyUnicode};
+  RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
+                    arraysize(always_flags));
+}
+
+
+TEST(UnicodeEscapes) {
+  const char* context_data[][2] = {{"", ""},
+                                   {"'use strict';", ""},
+                                   {NULL, NULL}};
+  const char* data[] = {
+    // Identifier starting with escape
+    "var \\u0052oo = 0;",
+    "var \\u{0052}oo = 0;",
+    "var \\u{52}oo = 0;",
+    "var \\u{00000000052}oo = 0;",
+    // Identifier with an escape but not starting with an escape
+    "var foob\\uc481r = 0;",
+    "var foob\\u{c481}r = 0;",
+    // String with an escape
+    "\"foob\\uc481r\"",
+    "\"foob\\{uc481}r\"",
+    // This character is a valid unicode character, representable as a surrogate
+    // pair, not representable as 4 hex digits.
+    "\"foo\\u{10e6d}\"",
+    // Max value for the unicode escape
+    "\"\\u{10ffff}\"",
+    NULL};
+  static const ParserFlag always_flags[] = {kAllowHarmonyUnicode};
+  RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
+                    arraysize(always_flags));
+}
+
+
+TEST(ScanTemplateLiterals) {
+  const char* context_data[][2] = {{"'use strict';", ""},
+                                   {"function foo(){ 'use strict';"
+                                    "  var a, b, c; return ", "}"},
+                                   {NULL, NULL}};
+
+  const char* data[] = {
+      "``",
+      "`no-subst-template`",
+      "`template-head${a}`",
+      "`${a}`",
+      "`${a}template-tail`",
+      "`template-head${a}template-tail`",
+      "`${a}${b}${c}`",
+      "`a${a}b${b}c${c}`",
+      "`${a}a${b}b${c}c`",
+      "`foo\n\nbar\r\nbaz`",
+      "`foo\n\n${  bar  }\r\nbaz`",
+      "`foo${a /* comment */}`",
+      "`foo${a // comment\n}`",
+      "`foo${a \n}`",
+      "`foo${a \r\n}`",
+      "`foo${a \r}`",
+      "`foo${/* comment */ a}`",
+      "`foo${// comment\na}`",
+      "`foo${\n a}`",
+      "`foo${\r\n a}`",
+      "`foo${\r a}`",
+      "`foo${'a' in a}`",
+      NULL};
+  static const ParserFlag always_flags[] = {kAllowHarmonyTemplates};
+  RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
+                    arraysize(always_flags));
+}
+
+
+TEST(ScanTaggedTemplateLiterals) {
+  const char* context_data[][2] = {{"'use strict';", ""},
+                                   {"function foo(){ 'use strict';"
+                                    "  function tag() {}"
+                                    "  var a, b, c; return ", "}"},
+                                   {NULL, NULL}};
+
+  const char* data[] = {
+      "tag ``",
+      "tag `no-subst-template`",
+      "tag`template-head${a}`",
+      "tag `${a}`",
+      "tag `${a}template-tail`",
+      "tag   `template-head${a}template-tail`",
+      "tag\n`${a}${b}${c}`",
+      "tag\r\n`a${a}b${b}c${c}`",
+      "tag    `${a}a${b}b${c}c`",
+      "tag\t`foo\n\nbar\r\nbaz`",
+      "tag\r`foo\n\n${  bar  }\r\nbaz`",
+      "tag`foo${a /* comment */}`",
+      "tag`foo${a // comment\n}`",
+      "tag`foo${a \n}`",
+      "tag`foo${a \r\n}`",
+      "tag`foo${a \r}`",
+      "tag`foo${/* comment */ a}`",
+      "tag`foo${// comment\na}`",
+      "tag`foo${\n a}`",
+      "tag`foo${\r\n a}`",
+      "tag`foo${\r a}`",
+      "tag`foo${'a' in a}`",
+      NULL};
+  static const ParserFlag always_flags[] = {kAllowHarmonyTemplates};
+  RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
+                    arraysize(always_flags));
+}
+
+
+TEST(TemplateMaterializedLiterals) {
+  const char* context_data[][2] = {
+    {
+      "'use strict';\n"
+      "function tag() {}\n"
+      "var a, b, c;\n"
+      "(", ")"
+    },
+    {NULL, NULL}
+  };
+
+  const char* data[] = {
+    "tag``",
+    "tag`a`",
+    "tag`a${1}b`",
+    "tag`a${1}b${2}c`",
+    "``",
+    "`a`",
+    "`a${1}b`",
+    "`a${1}b${2}c`",
+    NULL
+  };
+
+  static const ParserFlag always_flags[] = {kAllowHarmonyTemplates};
+  RunParserSyncTest(context_data, data, kSuccess, NULL, 0, always_flags,
+                    arraysize(always_flags));
+}
+
+
+TEST(ScanUnterminatedTemplateLiterals) {
+  const char* context_data[][2] = {{"'use strict';", ""},
+                                   {"function foo(){ 'use strict';"
+                                    "  var a, b, c; return ", "}"},
+                                   {NULL, NULL}};
+
+  const char* data[] = {
+      "`no-subst-template",
+      "`template-head${a}",
+      "`${a}template-tail",
+      "`template-head${a}template-tail",
+      "`${a}${b}${c}",
+      "`a${a}b${b}c${c}",
+      "`${a}a${b}b${c}c",
+      "`foo\n\nbar\r\nbaz",
+      "`foo\n\n${  bar  }\r\nbaz",
+      "`foo${a /* comment } */`",
+      "`foo${a /* comment } `*/",
+      "`foo${a // comment}`",
+      "`foo${a \n`",
+      "`foo${a \r\n`",
+      "`foo${a \r`",
+      "`foo${/* comment */ a`",
+      "`foo${// commenta}`",
+      "`foo${\n a`",
+      "`foo${\r\n a`",
+      "`foo${\r a`",
+      "`foo${fn(}`",
+      "`foo${1 if}`",
+      NULL};
+  static const ParserFlag always_flags[] = {kAllowHarmonyTemplates};
+  RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
+                    arraysize(always_flags));
+}
+
+
+TEST(TemplateLiteralsIllegalTokens) {
+  const char* context_data[][2] = {{"'use strict';", ""},
+                                   {"function foo(){ 'use strict';"
+                                    "  var a, b, c; return ", "}"},
+                                   {NULL, NULL}};
+  const char* data[] = {
+      "`hello\\x`",
+      "`hello\\x${1}`",
+      "`hello${1}\\x`",
+      "`hello${1}\\x${2}`",
+      "`hello\\x\n`",
+      "`hello\\x\n${1}`",
+      "`hello${1}\\x\n`",
+      "`hello${1}\\x\n${2}`",
+      NULL};
+
+  static const ParserFlag always_flags[] = {kAllowHarmonyTemplates};
+  RunParserSyncTest(context_data, data, kError, NULL, 0, always_flags,
+                    arraysize(always_flags));
+}
+
+
+TEST(LexicalScopingSloppyMode) {
+  const char* context_data[][2] = {
+      {"", ""},
+      {"function f() {", "}"},
+      {"{", "}"},
+      {NULL, NULL}};
+  const char* bad_data[] = {
+    "let x = 1;",
+    "for(let x = 1;;){}",
+    "for(let x of []){}",
+    "for(let x in []){}",
+    "class C {}",
+    "class C extends D {}",
+    "(class {})",
+    "(class extends D {})",
+    "(class C {})",
+    "(class C extends D {})",
+    NULL};
+  static const ParserFlag always_true_flags[] = {
+      kAllowHarmonyScoping, kAllowHarmonyClasses};
+  static const ParserFlag always_false_flags[] = {kAllowHarmonySloppy};
+  RunParserSyncTest(context_data, bad_data, kError, NULL, 0,
+                    always_true_flags, arraysize(always_true_flags),
+                    always_false_flags, arraysize(always_false_flags));
+
+  const char* good_data[] = {
+    "let = 1;",
+    "for(let = 1;;){}",
+    NULL};
+  RunParserSyncTest(context_data, good_data, kSuccess, NULL, 0,
+                    always_true_flags, arraysize(always_true_flags),
+                    always_false_flags, arraysize(always_false_flags));
+}
diff --git a/test/cctest/test-platform.cc b/test/cctest/test-platform.cc
index 100a5a7..90926d1 100644
--- a/test/cctest/test-platform.cc
+++ b/test/cctest/test-platform.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "include/v8stdint.h"
+#include <stdint.h>
 #include "src/base/build_config.h"
 #include "src/base/platform/platform.h"
 #include "test/cctest/cctest.h"
diff --git a/test/cctest/test-regexp.cc b/test/cctest/test-regexp.cc
index 9d1d52e..4a572c8 100644
--- a/test/cctest/test-regexp.cc
+++ b/test/cctest/test-regexp.cc
@@ -25,8 +25,8 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-
-#include <stdlib.h>
+#include <cstdlib>
+#include <sstream>
 
 #include "src/v8.h"
 
@@ -103,9 +103,9 @@
       &reader, false, &result, &zone));
   CHECK(result.tree != NULL);
   CHECK(result.error.is_null());
-  OStringStream os;
+  std::ostringstream os;
   result.tree->Print(os, &zone);
-  CHECK_EQ(expected, os.c_str());
+  CHECK_EQ(expected, os.str().c_str());
 }
 
 
@@ -435,11 +435,11 @@
   // Check that we don't allow more than kMaxCapture captures
   const int kMaxCaptures = 1 << 16;  // Must match RegExpParser::kMaxCaptures.
   const char* kTooManyCaptures = "Too many captures";
-  OStringStream os;
+  std::ostringstream os;
   for (int i = 0; i <= kMaxCaptures; i++) {
     os << "()";
   }
-  ExpectError(os.c_str(), kTooManyCaptures);
+  ExpectError(os.str().c_str(), kTooManyCaptures);
 }
 
 
diff --git a/test/cctest/test-sampler-api.cc b/test/cctest/test-sampler-api.cc
new file mode 100644
index 0000000..2f6f92e
--- /dev/null
+++ b/test/cctest/test-sampler-api.cc
@@ -0,0 +1,245 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Tests the sampling API in include/v8.h
+
+#include <map>
+#include <string>
+#include "include/v8.h"
+#include "src/simulator.h"
+#include "test/cctest/cctest.h"
+
+namespace {
+
+class Sample {
+ public:
+  enum { kFramesLimit = 255 };
+
+  Sample() {}
+
+  typedef const void* const* const_iterator;
+  const_iterator begin() const { return data_.start(); }
+  const_iterator end() const { return &data_[data_.length()]; }
+
+  int size() const { return data_.length(); }
+  v8::internal::Vector<void*>& data() { return data_; }
+
+ private:
+  v8::internal::EmbeddedVector<void*, kFramesLimit> data_;
+};
+
+
+#if defined(USE_SIMULATOR)
+class SimulatorHelper {
+ public:
+  inline bool Init(v8::Isolate* isolate) {
+    simulator_ = reinterpret_cast<v8::internal::Isolate*>(isolate)
+                     ->thread_local_top()
+                     ->simulator_;
+    // Check if there is active simulator.
+    return simulator_ != NULL;
+  }
+
+  inline void FillRegisters(v8::RegisterState* state) {
+#if V8_TARGET_ARCH_ARM
+    state->pc = reinterpret_cast<void*>(simulator_->get_pc());
+    state->sp = reinterpret_cast<void*>(
+        simulator_->get_register(v8::internal::Simulator::sp));
+    state->fp = reinterpret_cast<void*>(
+        simulator_->get_register(v8::internal::Simulator::r11));
+#elif V8_TARGET_ARCH_ARM64
+    if (simulator_->sp() == 0 || simulator_->fp() == 0) {
+      // It's possible that the simulator is interrupted while it is updating
+      // the sp or fp register. ARM64 simulator does this in two steps:
+      // first setting it to zero and then setting it to a new value.
+      // Bailout if sp/fp doesn't contain the new value.
+      return;
+    }
+    state->pc = reinterpret_cast<void*>(simulator_->pc());
+    state->sp = reinterpret_cast<void*>(simulator_->sp());
+    state->fp = reinterpret_cast<void*>(simulator_->fp());
+#elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
+    state->pc = reinterpret_cast<void*>(simulator_->get_pc());
+    state->sp = reinterpret_cast<void*>(
+        simulator_->get_register(v8::internal::Simulator::sp));
+    state->fp = reinterpret_cast<void*>(
+        simulator_->get_register(v8::internal::Simulator::fp));
+#endif
+  }
+
+ private:
+  v8::internal::Simulator* simulator_;
+};
+#endif  // USE_SIMULATOR
+
+
+class SamplingTestHelper {
+ public:
+  struct CodeEventEntry {
+    std::string name;
+    const void* code_start;
+    size_t code_len;
+  };
+  typedef std::map<const void*, CodeEventEntry> CodeEntries;
+
+  explicit SamplingTestHelper(const std::string& test_function)
+      : sample_is_taken_(false), isolate_(CcTest::isolate()) {
+    DCHECK_EQ(NULL, instance_);
+    instance_ = this;
+    v8::HandleScope scope(isolate_);
+    v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate_);
+    global->Set(v8::String::NewFromUtf8(isolate_, "CollectSample"),
+                v8::FunctionTemplate::New(isolate_, CollectSample));
+    LocalContext env(isolate_, NULL, global);
+    isolate_->SetJitCodeEventHandler(v8::kJitCodeEventDefault,
+                                     JitCodeEventHandler);
+    v8::Script::Compile(
+        v8::String::NewFromUtf8(isolate_, test_function.c_str()))->Run();
+  }
+
+  ~SamplingTestHelper() {
+    isolate_->SetJitCodeEventHandler(v8::kJitCodeEventDefault, NULL);
+    instance_ = NULL;
+  }
+
+  Sample& sample() { return sample_; }
+
+  const CodeEventEntry* FindEventEntry(const void* address) {
+    CodeEntries::const_iterator it = code_entries_.upper_bound(address);
+    if (it == code_entries_.begin()) return NULL;
+    const CodeEventEntry& entry = (--it)->second;
+    const void* code_end =
+        static_cast<const uint8_t*>(entry.code_start) + entry.code_len;
+    return address < code_end ? &entry : NULL;
+  }
+
+ private:
+  static void CollectSample(const v8::FunctionCallbackInfo<v8::Value>& args) {
+    instance_->DoCollectSample();
+  }
+
+  static void JitCodeEventHandler(const v8::JitCodeEvent* event) {
+    instance_->DoJitCodeEventHandler(event);
+  }
+
+  // The JavaScript calls this function when on full stack depth.
+  void DoCollectSample() {
+    v8::RegisterState state;
+#if defined(USE_SIMULATOR)
+    SimulatorHelper simulator_helper;
+    if (!simulator_helper.Init(isolate_)) return;
+    simulator_helper.FillRegisters(&state);
+#else
+    state.pc = NULL;
+    state.fp = &state;
+    state.sp = &state;
+#endif
+    v8::SampleInfo info;
+    isolate_->GetStackSample(state, sample_.data().start(),
+                             static_cast<size_t>(sample_.size()), &info);
+    size_t frames_count = info.frames_count;
+    CHECK_LE(frames_count, static_cast<size_t>(sample_.size()));
+    sample_.data().Truncate(static_cast<int>(frames_count));
+    sample_is_taken_ = true;
+  }
+
+  void DoJitCodeEventHandler(const v8::JitCodeEvent* event) {
+    if (sample_is_taken_) return;
+    switch (event->type) {
+      case v8::JitCodeEvent::CODE_ADDED: {
+        CodeEventEntry entry;
+        entry.name = std::string(event->name.str, event->name.len);
+        entry.code_start = event->code_start;
+        entry.code_len = event->code_len;
+        code_entries_.insert(std::make_pair(entry.code_start, entry));
+        break;
+      }
+      case v8::JitCodeEvent::CODE_MOVED: {
+        CodeEntries::iterator it = code_entries_.find(event->code_start);
+        CHECK(it != code_entries_.end());
+        code_entries_.erase(it);
+        CodeEventEntry entry;
+        entry.name = std::string(event->name.str, event->name.len);
+        entry.code_start = event->new_code_start;
+        entry.code_len = event->code_len;
+        code_entries_.insert(std::make_pair(entry.code_start, entry));
+        break;
+      }
+      case v8::JitCodeEvent::CODE_REMOVED:
+        code_entries_.erase(event->code_start);
+        break;
+      default:
+        break;
+    }
+  }
+
+  Sample sample_;
+  bool sample_is_taken_;
+  v8::Isolate* isolate_;
+  CodeEntries code_entries_;
+
+  static SamplingTestHelper* instance_;
+};
+
+SamplingTestHelper* SamplingTestHelper::instance_;
+
+}  // namespace
+
+
+// A JavaScript function which takes stack depth
+// (minimum value 2) as an argument.
+// When at the bottom of the recursion,
+// the JavaScript code calls into C++ test code,
+// waiting for the sampler to take a sample.
+static const char* test_function =
+    "function func(depth) {"
+    "  if (depth == 2) CollectSample();"
+    "  else return func(depth - 1);"
+    "}";
+
+
+TEST(StackDepthIsConsistent) {
+  SamplingTestHelper helper(std::string(test_function) + "func(8);");
+  CHECK_EQ(8, helper.sample().size());
+}
+
+
+TEST(StackDepthDoesNotExceedMaxValue) {
+  SamplingTestHelper helper(std::string(test_function) + "func(300);");
+  CHECK_EQ(Sample::kFramesLimit, helper.sample().size());
+}
+
+
+// The captured sample should have three pc values.
+// They should fall in the range where the compiled code resides.
+// The expected stack is:
+// bottom of stack [{anon script}, outer, inner] top of stack
+//                              ^      ^       ^
+// sample.stack indices         2      1       0
+TEST(StackFramesConsistent) {
+  // Note: The arguments.callee stuff is there so that the
+  //       functions are not optimized away.
+  const char* test_script =
+      "function test_sampler_api_inner() {"
+      "  CollectSample();"
+      "  return arguments.callee.toString();"
+      "}"
+      "function test_sampler_api_outer() {"
+      "  return test_sampler_api_inner() + arguments.callee.toString();"
+      "}"
+      "test_sampler_api_outer();";
+
+  SamplingTestHelper helper(test_script);
+  Sample& sample = helper.sample();
+  CHECK_EQ(3, sample.size());
+
+  const SamplingTestHelper::CodeEventEntry* entry;
+  entry = helper.FindEventEntry(sample.begin()[0]);
+  CHECK_NE(NULL, entry);
+  CHECK(std::string::npos != entry->name.find("test_sampler_api_inner"));
+
+  entry = helper.FindEventEntry(sample.begin()[1]);
+  CHECK_NE(NULL, entry);
+  CHECK(std::string::npos != entry->name.find("test_sampler_api_outer"));
+}
diff --git a/test/cctest/test-serialize.cc b/test/cctest/test-serialize.cc
index 94b400e..45da250 100644
--- a/test/cctest/test-serialize.cc
+++ b/test/cctest/test-serialize.cc
@@ -37,7 +37,7 @@
 #include "src/heap/spaces.h"
 #include "src/natives.h"
 #include "src/objects.h"
-#include "src/runtime.h"
+#include "src/runtime/runtime.h"
 #include "src/scopeinfo.h"
 #include "src/serialize.h"
 #include "src/snapshot.h"
@@ -114,82 +114,27 @@
 }
 
 
-class FileByteSink : public SnapshotByteSink {
- public:
-  explicit FileByteSink(const char* snapshot_file) {
-    fp_ = v8::base::OS::FOpen(snapshot_file, "wb");
-    file_name_ = snapshot_file;
-    if (fp_ == NULL) {
-      PrintF("Unable to write to snapshot file \"%s\"\n", snapshot_file);
-      exit(1);
-    }
+void WritePayload(const Vector<const byte>& payload, const char* file_name) {
+  FILE* file = v8::base::OS::FOpen(file_name, "wb");
+  if (file == NULL) {
+    PrintF("Unable to write to snapshot file \"%s\"\n", file_name);
+    exit(1);
   }
-  virtual ~FileByteSink() {
-    if (fp_ != NULL) {
-      fclose(fp_);
-    }
+  size_t written = fwrite(payload.begin(), 1, payload.length(), file);
+  if (written != static_cast<size_t>(payload.length())) {
+    i::PrintF("Writing snapshot file failed.. Aborting.\n");
+    exit(1);
   }
-  virtual void Put(byte b, const char* description) {
-    if (fp_ != NULL) {
-      fputc(b, fp_);
-    }
-  }
-  virtual int Position() {
-    return ftell(fp_);
-  }
-  void WriteSpaceUsed(
-      int new_space_used,
-      int pointer_space_used,
-      int data_space_used,
-      int code_space_used,
-      int map_space_used,
-      int cell_space_used,
-      int property_cell_space_used);
-
- private:
-  FILE* fp_;
-  const char* file_name_;
-};
-
-
-void FileByteSink::WriteSpaceUsed(
-      int new_space_used,
-      int pointer_space_used,
-      int data_space_used,
-      int code_space_used,
-      int map_space_used,
-      int cell_space_used,
-      int property_cell_space_used) {
-  int file_name_length = StrLength(file_name_) + 10;
-  Vector<char> name = Vector<char>::New(file_name_length + 1);
-  SNPrintF(name, "%s.size", file_name_);
-  FILE* fp = v8::base::OS::FOpen(name.start(), "w");
-  name.Dispose();
-  fprintf(fp, "new %d\n", new_space_used);
-  fprintf(fp, "pointer %d\n", pointer_space_used);
-  fprintf(fp, "data %d\n", data_space_used);
-  fprintf(fp, "code %d\n", code_space_used);
-  fprintf(fp, "map %d\n", map_space_used);
-  fprintf(fp, "cell %d\n", cell_space_used);
-  fprintf(fp, "property cell %d\n", property_cell_space_used);
-  fclose(fp);
+  fclose(file);
 }
 
 
 static bool WriteToFile(Isolate* isolate, const char* snapshot_file) {
-  FileByteSink file(snapshot_file);
-  StartupSerializer ser(isolate, &file);
+  SnapshotByteSink sink;
+  StartupSerializer ser(isolate, &sink);
   ser.Serialize();
-
-  file.WriteSpaceUsed(
-      ser.CurrentAllocationAddress(NEW_SPACE),
-      ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
-      ser.CurrentAllocationAddress(OLD_DATA_SPACE),
-      ser.CurrentAllocationAddress(CODE_SPACE),
-      ser.CurrentAllocationAddress(MAP_SPACE),
-      ser.CurrentAllocationAddress(CELL_SPACE),
-      ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
-
+  SnapshotData snapshot_data(sink, ser);
+  WritePayload(snapshot_data.RawData(), snapshot_file);
   return true;
 }
 
@@ -206,7 +151,7 @@
   }
 
   Isolate* internal_isolate = reinterpret_cast<Isolate*>(isolate);
-  internal_isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "serialize");
+  internal_isolate->heap()->CollectAllAvailableGarbage("serialize");
   WriteToFile(internal_isolate, FLAG_testing_serialization_file);
 }
 
@@ -237,51 +182,14 @@
 //----------------------------------------------------------------------------
 // Tests that the heap can be deserialized.
 
-
-static void ReserveSpaceForSnapshot(Deserializer* deserializer,
-                                    const char* file_name) {
-  int file_name_length = StrLength(file_name) + 10;
-  Vector<char> name = Vector<char>::New(file_name_length + 1);
-  SNPrintF(name, "%s.size", file_name);
-  FILE* fp = v8::base::OS::FOpen(name.start(), "r");
-  name.Dispose();
-  int new_size, pointer_size, data_size, code_size, map_size, cell_size,
-      property_cell_size;
-#ifdef _MSC_VER
-  // Avoid warning about unsafe fscanf from MSVC.
-  // Please note that this is only fine if %c and %s are not being used.
-#define fscanf fscanf_s
-#endif
-  CHECK_EQ(1, fscanf(fp, "new %d\n", &new_size));
-  CHECK_EQ(1, fscanf(fp, "pointer %d\n", &pointer_size));
-  CHECK_EQ(1, fscanf(fp, "data %d\n", &data_size));
-  CHECK_EQ(1, fscanf(fp, "code %d\n", &code_size));
-  CHECK_EQ(1, fscanf(fp, "map %d\n", &map_size));
-  CHECK_EQ(1, fscanf(fp, "cell %d\n", &cell_size));
-  CHECK_EQ(1, fscanf(fp, "property cell %d\n", &property_cell_size));
-#ifdef _MSC_VER
-#undef fscanf
-#endif
-  fclose(fp);
-  deserializer->set_reservation(NEW_SPACE, new_size);
-  deserializer->set_reservation(OLD_POINTER_SPACE, pointer_size);
-  deserializer->set_reservation(OLD_DATA_SPACE, data_size);
-  deserializer->set_reservation(CODE_SPACE, code_size);
-  deserializer->set_reservation(MAP_SPACE, map_size);
-  deserializer->set_reservation(CELL_SPACE, cell_size);
-  deserializer->set_reservation(PROPERTY_CELL_SPACE, property_cell_size);
-}
-
-
 v8::Isolate* InitializeFromFile(const char* snapshot_file) {
   int len;
   byte* str = ReadBytes(snapshot_file, &len);
   if (!str) return NULL;
   v8::Isolate* v8_isolate = NULL;
   {
-    SnapshotByteSource source(str, len);
-    Deserializer deserializer(&source);
-    ReserveSpaceForSnapshot(&deserializer, snapshot_file);
+    SnapshotData snapshot_data(Vector<const byte>(str, len));
+    Deserializer deserializer(&snapshot_data);
     Isolate* isolate = Isolate::NewForTesting();
     v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
     v8::Isolate::Scope isolate_scope(v8_isolate);
@@ -440,32 +348,23 @@
       }
       env.Reset();
 
-      FileByteSink startup_sink(startup_name.start());
+      SnapshotByteSink startup_sink;
       StartupSerializer startup_serializer(isolate, &startup_sink);
       startup_serializer.SerializeStrongReferences();
 
-      FileByteSink partial_sink(FLAG_testing_serialization_file);
-      PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink);
-      p_ser.Serialize(&raw_foo);
+      SnapshotByteSink partial_sink;
+      PartialSerializer partial_serializer(isolate, &startup_serializer,
+                                           &partial_sink);
+      partial_serializer.Serialize(&raw_foo);
+
       startup_serializer.SerializeWeakReferences();
 
-      partial_sink.WriteSpaceUsed(
-          p_ser.CurrentAllocationAddress(NEW_SPACE),
-          p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
-          p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
-          p_ser.CurrentAllocationAddress(CODE_SPACE),
-          p_ser.CurrentAllocationAddress(MAP_SPACE),
-          p_ser.CurrentAllocationAddress(CELL_SPACE),
-          p_ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
+      SnapshotData startup_snapshot(startup_sink, startup_serializer);
+      SnapshotData partial_snapshot(partial_sink, partial_serializer);
 
-      startup_sink.WriteSpaceUsed(
-          startup_serializer.CurrentAllocationAddress(NEW_SPACE),
-          startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE),
-          startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE),
-          startup_serializer.CurrentAllocationAddress(CODE_SPACE),
-          startup_serializer.CurrentAllocationAddress(MAP_SPACE),
-          startup_serializer.CurrentAllocationAddress(CELL_SPACE),
-          startup_serializer.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
+      WritePayload(partial_snapshot.RawData(), FLAG_testing_serialization_file);
+      WritePayload(startup_snapshot.RawData(), startup_name.start());
+
       startup_name.Dispose();
     }
     v8_isolate->Exit();
@@ -494,9 +393,8 @@
       Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
       Object* root;
       {
-        SnapshotByteSource source(snapshot, snapshot_size);
-        Deserializer deserializer(&source);
-        ReserveSpaceForSnapshot(&deserializer, file_name);
+        SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
+        Deserializer deserializer(&snapshot_data);
         deserializer.DeserializePartial(isolate, &root);
         CHECK(root->IsString());
       }
@@ -506,9 +404,8 @@
 
       Object* root2;
       {
-        SnapshotByteSource source(snapshot, snapshot_size);
-        Deserializer deserializer(&source);
-        ReserveSpaceForSnapshot(&deserializer, file_name);
+        SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
+        Deserializer deserializer(&snapshot_data);
         deserializer.DeserializePartial(isolate, &root2);
         CHECK(root2->IsString());
         CHECK(*root_handle == root2);
@@ -563,32 +460,22 @@
 
       env.Reset();
 
-      FileByteSink startup_sink(startup_name.start());
+      SnapshotByteSink startup_sink;
       StartupSerializer startup_serializer(isolate, &startup_sink);
       startup_serializer.SerializeStrongReferences();
 
-      FileByteSink partial_sink(FLAG_testing_serialization_file);
-      PartialSerializer p_ser(isolate, &startup_serializer, &partial_sink);
-      p_ser.Serialize(&raw_context);
+      SnapshotByteSink partial_sink;
+      PartialSerializer partial_serializer(isolate, &startup_serializer,
+                                           &partial_sink);
+      partial_serializer.Serialize(&raw_context);
       startup_serializer.SerializeWeakReferences();
 
-      partial_sink.WriteSpaceUsed(
-          p_ser.CurrentAllocationAddress(NEW_SPACE),
-          p_ser.CurrentAllocationAddress(OLD_POINTER_SPACE),
-          p_ser.CurrentAllocationAddress(OLD_DATA_SPACE),
-          p_ser.CurrentAllocationAddress(CODE_SPACE),
-          p_ser.CurrentAllocationAddress(MAP_SPACE),
-          p_ser.CurrentAllocationAddress(CELL_SPACE),
-          p_ser.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
+      SnapshotData startup_snapshot(startup_sink, startup_serializer);
+      SnapshotData partial_snapshot(partial_sink, partial_serializer);
 
-      startup_sink.WriteSpaceUsed(
-          startup_serializer.CurrentAllocationAddress(NEW_SPACE),
-          startup_serializer.CurrentAllocationAddress(OLD_POINTER_SPACE),
-          startup_serializer.CurrentAllocationAddress(OLD_DATA_SPACE),
-          startup_serializer.CurrentAllocationAddress(CODE_SPACE),
-          startup_serializer.CurrentAllocationAddress(MAP_SPACE),
-          startup_serializer.CurrentAllocationAddress(CELL_SPACE),
-          startup_serializer.CurrentAllocationAddress(PROPERTY_CELL_SPACE));
+      WritePayload(partial_snapshot.RawData(), FLAG_testing_serialization_file);
+      WritePayload(startup_snapshot.RawData(), startup_name.start());
+
       startup_name.Dispose();
     }
     v8_isolate->Dispose();
@@ -616,9 +503,8 @@
       Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
       Object* root;
       {
-        SnapshotByteSource source(snapshot, snapshot_size);
-        Deserializer deserializer(&source);
-        ReserveSpaceForSnapshot(&deserializer, file_name);
+        SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
+        Deserializer deserializer(&snapshot_data);
         deserializer.DeserializePartial(isolate, &root);
         CHECK(root->IsContext());
       }
@@ -628,9 +514,8 @@
 
       Object* root2;
       {
-        SnapshotByteSource source(snapshot, snapshot_size);
-        Deserializer deserializer(&source);
-        ReserveSpaceForSnapshot(&deserializer, file_name);
+        SnapshotData snapshot_data(Vector<const byte>(snapshot, snapshot_size));
+        Deserializer deserializer(&snapshot_data);
         deserializer.DeserializePartial(isolate, &root2);
         CHECK(root2->IsContext());
         CHECK(*root_handle != root2);
@@ -786,6 +671,432 @@
 }
 
 
+Vector<const uint8_t> ConstructSource(Vector<const uint8_t> head,
+                                      Vector<const uint8_t> body,
+                                      Vector<const uint8_t> tail, int repeats) {
+  int source_length = head.length() + body.length() * repeats + tail.length();
+  uint8_t* source = NewArray<uint8_t>(static_cast<size_t>(source_length));
+  CopyChars(source, head.start(), head.length());
+  for (int i = 0; i < repeats; i++) {
+    CopyChars(source + head.length() + i * body.length(), body.start(),
+              body.length());
+  }
+  CopyChars(source + head.length() + repeats * body.length(), tail.start(),
+            tail.length());
+  return Vector<const uint8_t>(const_cast<const uint8_t*>(source),
+                               source_length);
+}
+
+
+TEST(SerializeToplevelLargeCodeObject) {
+  FLAG_serialize_toplevel = true;
+  LocalContext context;
+  Isolate* isolate = CcTest::i_isolate();
+  isolate->compilation_cache()->Disable();  // Disable same-isolate code cache.
+
+  v8::HandleScope scope(CcTest::isolate());
+
+  Vector<const uint8_t> source =
+      ConstructSource(STATIC_CHAR_VECTOR("var j=1; try { if (j) throw 1;"),
+                      STATIC_CHAR_VECTOR("for(var i=0;i<1;i++)j++;"),
+                      STATIC_CHAR_VECTOR("} catch (e) { j=7; } j"), 10000);
+  Handle<String> source_str =
+      isolate->factory()->NewStringFromOneByte(source).ToHandleChecked();
+
+  Handle<JSObject> global(isolate->context()->global_object());
+  ScriptData* cache = NULL;
+
+  Handle<SharedFunctionInfo> orig = Compiler::CompileScript(
+      source_str, Handle<String>(), 0, 0, false,
+      Handle<Context>(isolate->native_context()), NULL, &cache,
+      v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE);
+
+  CHECK(isolate->heap()->InSpace(orig->code(), LO_SPACE));
+
+  Handle<SharedFunctionInfo> copy;
+  {
+    DisallowCompilation no_compile_expected(isolate);
+    copy = Compiler::CompileScript(
+        source_str, Handle<String>(), 0, 0, false,
+        Handle<Context>(isolate->native_context()), NULL, &cache,
+        v8::ScriptCompiler::kConsumeCodeCache, NOT_NATIVES_CODE);
+  }
+  CHECK_NE(*orig, *copy);
+
+  Handle<JSFunction> copy_fun =
+      isolate->factory()->NewFunctionFromSharedFunctionInfo(
+          copy, isolate->native_context());
+
+  Handle<Object> copy_result =
+      Execution::Call(isolate, copy_fun, global, 0, NULL).ToHandleChecked();
+
+  int result_int;
+  CHECK(copy_result->ToInt32(&result_int));
+  CHECK_EQ(7, result_int);
+
+  delete cache;
+  source.Dispose();
+}
+
+
+TEST(SerializeToplevelLargeStrings) {
+  FLAG_serialize_toplevel = true;
+  LocalContext context;
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* f = isolate->factory();
+  isolate->compilation_cache()->Disable();  // Disable same-isolate code cache.
+
+  v8::HandleScope scope(CcTest::isolate());
+
+  Vector<const uint8_t> source_s = ConstructSource(
+      STATIC_CHAR_VECTOR("var s = \""), STATIC_CHAR_VECTOR("abcdef"),
+      STATIC_CHAR_VECTOR("\";"), 1000000);
+  Vector<const uint8_t> source_t = ConstructSource(
+      STATIC_CHAR_VECTOR("var t = \""), STATIC_CHAR_VECTOR("uvwxyz"),
+      STATIC_CHAR_VECTOR("\"; s + t"), 999999);
+  Handle<String> source_str =
+      f->NewConsString(f->NewStringFromOneByte(source_s).ToHandleChecked(),
+                       f->NewStringFromOneByte(source_t).ToHandleChecked())
+          .ToHandleChecked();
+
+  Handle<JSObject> global(isolate->context()->global_object());
+  ScriptData* cache = NULL;
+
+  Handle<SharedFunctionInfo> orig = Compiler::CompileScript(
+      source_str, Handle<String>(), 0, 0, false,
+      Handle<Context>(isolate->native_context()), NULL, &cache,
+      v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE);
+
+  Handle<SharedFunctionInfo> copy;
+  {
+    DisallowCompilation no_compile_expected(isolate);
+    copy = Compiler::CompileScript(
+        source_str, Handle<String>(), 0, 0, false,
+        Handle<Context>(isolate->native_context()), NULL, &cache,
+        v8::ScriptCompiler::kConsumeCodeCache, NOT_NATIVES_CODE);
+  }
+  CHECK_NE(*orig, *copy);
+
+  Handle<JSFunction> copy_fun =
+      isolate->factory()->NewFunctionFromSharedFunctionInfo(
+          copy, isolate->native_context());
+
+  Handle<Object> copy_result =
+      Execution::Call(isolate, copy_fun, global, 0, NULL).ToHandleChecked();
+
+  CHECK_EQ(6 * 1999999, Handle<String>::cast(copy_result)->length());
+  Handle<Object> property = JSObject::GetDataProperty(
+      isolate->global_object(), f->NewStringFromAsciiChecked("s"));
+  CHECK(isolate->heap()->InSpace(HeapObject::cast(*property), LO_SPACE));
+  property = JSObject::GetDataProperty(isolate->global_object(),
+                                       f->NewStringFromAsciiChecked("t"));
+  CHECK(isolate->heap()->InSpace(HeapObject::cast(*property), LO_SPACE));
+  // Make sure we do not serialize too much, e.g. include the source string.
+  CHECK_LT(cache->length(), 13000000);
+
+  delete cache;
+  source_s.Dispose();
+  source_t.Dispose();
+}
+
+
+TEST(SerializeToplevelThreeBigStrings) {
+  FLAG_serialize_toplevel = true;
+  LocalContext context;
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* f = isolate->factory();
+  isolate->compilation_cache()->Disable();  // Disable same-isolate code cache.
+
+  v8::HandleScope scope(CcTest::isolate());
+
+  Vector<const uint8_t> source_a =
+      ConstructSource(STATIC_CHAR_VECTOR("var a = \""), STATIC_CHAR_VECTOR("a"),
+                      STATIC_CHAR_VECTOR("\";"), 700000);
+  Handle<String> source_a_str =
+      f->NewStringFromOneByte(source_a).ToHandleChecked();
+
+  Vector<const uint8_t> source_b =
+      ConstructSource(STATIC_CHAR_VECTOR("var b = \""), STATIC_CHAR_VECTOR("b"),
+                      STATIC_CHAR_VECTOR("\";"), 600000);
+  Handle<String> source_b_str =
+      f->NewStringFromOneByte(source_b).ToHandleChecked();
+
+  Vector<const uint8_t> source_c =
+      ConstructSource(STATIC_CHAR_VECTOR("var c = \""), STATIC_CHAR_VECTOR("c"),
+                      STATIC_CHAR_VECTOR("\";"), 500000);
+  Handle<String> source_c_str =
+      f->NewStringFromOneByte(source_c).ToHandleChecked();
+
+  Handle<String> source_str =
+      f->NewConsString(
+             f->NewConsString(source_a_str, source_b_str).ToHandleChecked(),
+             source_c_str).ToHandleChecked();
+
+  Handle<JSObject> global(isolate->context()->global_object());
+  ScriptData* cache = NULL;
+
+  Handle<SharedFunctionInfo> orig = Compiler::CompileScript(
+      source_str, Handle<String>(), 0, 0, false,
+      Handle<Context>(isolate->native_context()), NULL, &cache,
+      v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE);
+
+  Handle<SharedFunctionInfo> copy;
+  {
+    DisallowCompilation no_compile_expected(isolate);
+    copy = Compiler::CompileScript(
+        source_str, Handle<String>(), 0, 0, false,
+        Handle<Context>(isolate->native_context()), NULL, &cache,
+        v8::ScriptCompiler::kConsumeCodeCache, NOT_NATIVES_CODE);
+  }
+  CHECK_NE(*orig, *copy);
+
+  Handle<JSFunction> copy_fun =
+      isolate->factory()->NewFunctionFromSharedFunctionInfo(
+          copy, isolate->native_context());
+
+  USE(Execution::Call(isolate, copy_fun, global, 0, NULL));
+
+  CHECK_EQ(600000 + 700000, CompileRun("(a + b).length")->Int32Value());
+  CHECK_EQ(500000 + 600000, CompileRun("(b + c).length")->Int32Value());
+  Heap* heap = isolate->heap();
+  CHECK(heap->InSpace(
+      *v8::Utils::OpenHandle(*CompileRun("a")->ToString(CcTest::isolate())),
+      OLD_DATA_SPACE));
+  CHECK(heap->InSpace(
+      *v8::Utils::OpenHandle(*CompileRun("b")->ToString(CcTest::isolate())),
+      OLD_DATA_SPACE));
+  CHECK(heap->InSpace(
+      *v8::Utils::OpenHandle(*CompileRun("c")->ToString(CcTest::isolate())),
+      OLD_DATA_SPACE));
+
+  delete cache;
+  source_a.Dispose();
+  source_b.Dispose();
+  source_c.Dispose();
+}
+
+
+class SerializerOneByteResource
+    : public v8::String::ExternalOneByteStringResource {
+ public:
+  SerializerOneByteResource(const char* data, size_t length)
+      : data_(data), length_(length) {}
+  virtual const char* data() const { return data_; }
+  virtual size_t length() const { return length_; }
+
+ private:
+  const char* data_;
+  size_t length_;
+};
+
+
+class SerializerTwoByteResource : public v8::String::ExternalStringResource {
+ public:
+  SerializerTwoByteResource(const char* data, size_t length)
+      : data_(AsciiToTwoByteString(data)), length_(length) {}
+  ~SerializerTwoByteResource() { DeleteArray<const uint16_t>(data_); }
+
+  virtual const uint16_t* data() const { return data_; }
+  virtual size_t length() const { return length_; }
+
+ private:
+  const uint16_t* data_;
+  size_t length_;
+};
+
+
+TEST(SerializeToplevelExternalString) {
+  FLAG_serialize_toplevel = true;
+  LocalContext context;
+  Isolate* isolate = CcTest::i_isolate();
+  isolate->compilation_cache()->Disable();  // Disable same-isolate code cache.
+
+  v8::HandleScope scope(CcTest::isolate());
+
+  // Obtain external internalized one-byte string.
+  SerializerOneByteResource one_byte_resource("one_byte", 8);
+  Handle<String> one_byte_string =
+      isolate->factory()->NewStringFromAsciiChecked("one_byte");
+  one_byte_string = isolate->factory()->InternalizeString(one_byte_string);
+  one_byte_string->MakeExternal(&one_byte_resource);
+  CHECK(one_byte_string->IsExternalOneByteString());
+  CHECK(one_byte_string->IsInternalizedString());
+
+  // Obtain external internalized two-byte string.
+  SerializerTwoByteResource two_byte_resource("two_byte", 8);
+  Handle<String> two_byte_string =
+      isolate->factory()->NewStringFromAsciiChecked("two_byte");
+  two_byte_string = isolate->factory()->InternalizeString(two_byte_string);
+  two_byte_string->MakeExternal(&two_byte_resource);
+  CHECK(two_byte_string->IsExternalTwoByteString());
+  CHECK(two_byte_string->IsInternalizedString());
+
+  const char* source =
+      "var o = {}               \n"
+      "o.one_byte = 7;          \n"
+      "o.two_byte = 8;          \n"
+      "o.one_byte + o.two_byte; \n";
+  Handle<String> source_string = isolate->factory()
+                                     ->NewStringFromUtf8(CStrVector(source))
+                                     .ToHandleChecked();
+
+  Handle<JSObject> global(isolate->context()->global_object());
+  ScriptData* cache = NULL;
+
+  Handle<SharedFunctionInfo> orig = Compiler::CompileScript(
+      source_string, Handle<String>(), 0, 0, false,
+      Handle<Context>(isolate->native_context()), NULL, &cache,
+      v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE);
+
+  Handle<SharedFunctionInfo> copy;
+  {
+    DisallowCompilation no_compile_expected(isolate);
+    copy = Compiler::CompileScript(
+        source_string, Handle<String>(), 0, 0, false,
+        Handle<Context>(isolate->native_context()), NULL, &cache,
+        v8::ScriptCompiler::kConsumeCodeCache, NOT_NATIVES_CODE);
+  }
+  CHECK_NE(*orig, *copy);
+
+  Handle<JSFunction> copy_fun =
+      isolate->factory()->NewFunctionFromSharedFunctionInfo(
+          copy, isolate->native_context());
+
+  Handle<Object> copy_result =
+      Execution::Call(isolate, copy_fun, global, 0, NULL).ToHandleChecked();
+
+  CHECK_EQ(15.0f, copy_result->Number());
+
+  delete cache;
+}
+
+
+TEST(SerializeToplevelLargeExternalString) {
+  FLAG_serialize_toplevel = true;
+  LocalContext context;
+  Isolate* isolate = CcTest::i_isolate();
+  isolate->compilation_cache()->Disable();  // Disable same-isolate code cache.
+
+  Factory* f = isolate->factory();
+
+  v8::HandleScope scope(CcTest::isolate());
+
+  // Create a huge external internalized string to use as variable name.
+  Vector<const uint8_t> string =
+      ConstructSource(STATIC_CHAR_VECTOR(""), STATIC_CHAR_VECTOR("abcdef"),
+                      STATIC_CHAR_VECTOR(""), 999999);
+  Handle<String> name = f->NewStringFromOneByte(string).ToHandleChecked();
+  SerializerOneByteResource one_byte_resource(
+      reinterpret_cast<const char*>(string.start()), string.length());
+  name = f->InternalizeString(name);
+  name->MakeExternal(&one_byte_resource);
+  CHECK(name->IsExternalOneByteString());
+  CHECK(name->IsInternalizedString());
+  CHECK(isolate->heap()->InSpace(*name, LO_SPACE));
+
+  // Create the source, which is "var <literal> = 42; <literal>".
+  Handle<String> source_str =
+      f->NewConsString(
+             f->NewConsString(f->NewStringFromAsciiChecked("var "), name)
+                 .ToHandleChecked(),
+             f->NewConsString(f->NewStringFromAsciiChecked(" = 42; "), name)
+                 .ToHandleChecked()).ToHandleChecked();
+
+  Handle<JSObject> global(isolate->context()->global_object());
+  ScriptData* cache = NULL;
+
+  Handle<SharedFunctionInfo> orig = Compiler::CompileScript(
+      source_str, Handle<String>(), 0, 0, false,
+      Handle<Context>(isolate->native_context()), NULL, &cache,
+      v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE);
+
+  Handle<SharedFunctionInfo> copy;
+  {
+    DisallowCompilation no_compile_expected(isolate);
+    copy = Compiler::CompileScript(
+        source_str, Handle<String>(), 0, 0, false,
+        Handle<Context>(isolate->native_context()), NULL, &cache,
+        v8::ScriptCompiler::kConsumeCodeCache, NOT_NATIVES_CODE);
+  }
+  CHECK_NE(*orig, *copy);
+
+  Handle<JSFunction> copy_fun =
+      f->NewFunctionFromSharedFunctionInfo(copy, isolate->native_context());
+
+  Handle<Object> copy_result =
+      Execution::Call(isolate, copy_fun, global, 0, NULL).ToHandleChecked();
+
+  CHECK_EQ(42.0f, copy_result->Number());
+
+  delete cache;
+  string.Dispose();
+}
+
+
+TEST(SerializeToplevelExternalScriptName) {
+  FLAG_serialize_toplevel = true;
+  LocalContext context;
+  Isolate* isolate = CcTest::i_isolate();
+  isolate->compilation_cache()->Disable();  // Disable same-isolate code cache.
+
+  Factory* f = isolate->factory();
+
+  v8::HandleScope scope(CcTest::isolate());
+
+  const char* source =
+      "var a = [1, 2, 3, 4];"
+      "a.reduce(function(x, y) { return x + y }, 0)";
+
+  Handle<String> source_string =
+      f->NewStringFromUtf8(CStrVector(source)).ToHandleChecked();
+
+  const SerializerOneByteResource one_byte_resource("one_byte", 8);
+  Handle<String> name =
+      f->NewExternalStringFromOneByte(&one_byte_resource).ToHandleChecked();
+  CHECK(name->IsExternalOneByteString());
+  CHECK(!name->IsInternalizedString());
+
+  Handle<JSObject> global(isolate->context()->global_object());
+  ScriptData* cache = NULL;
+
+  Handle<SharedFunctionInfo> orig = Compiler::CompileScript(
+      source_string, name, 0, 0, false,
+      Handle<Context>(isolate->native_context()), NULL, &cache,
+      v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE);
+
+  Handle<SharedFunctionInfo> copy;
+  {
+    DisallowCompilation no_compile_expected(isolate);
+    copy = Compiler::CompileScript(
+        source_string, name, 0, 0, false,
+        Handle<Context>(isolate->native_context()), NULL, &cache,
+        v8::ScriptCompiler::kConsumeCodeCache, NOT_NATIVES_CODE);
+  }
+  CHECK_NE(*orig, *copy);
+
+  Handle<JSFunction> copy_fun =
+      f->NewFunctionFromSharedFunctionInfo(copy, isolate->native_context());
+
+  Handle<Object> copy_result =
+      Execution::Call(isolate, copy_fun, global, 0, NULL).ToHandleChecked();
+
+  CHECK_EQ(10.0f, copy_result->Number());
+
+  delete cache;
+}
+
+
+static bool toplevel_test_code_event_found = false;
+
+
+static void SerializerCodeEventListener(const v8::JitCodeEvent* event) {
+  if (event->type == v8::JitCodeEvent::CODE_ADDED &&
+      memcmp(event->name.str, "Script:~test", 12) == 0) {
+    toplevel_test_code_event_found = true;
+  }
+}
+
+
 TEST(SerializeToplevelIsolates) {
   FLAG_serialize_toplevel = true;
 
@@ -805,6 +1116,7 @@
     v8::Local<v8::UnboundScript> script = v8::ScriptCompiler::CompileUnbound(
         isolate1, &source, v8::ScriptCompiler::kProduceCodeCache);
     const v8::ScriptCompiler::CachedData* data = source.GetCachedData();
+    CHECK(data);
     // Persist cached data.
     uint8_t* buffer = NewArray<uint8_t>(data->length);
     MemCopy(buffer, data->data, data->length);
@@ -812,11 +1124,14 @@
         buffer, data->length, v8::ScriptCompiler::CachedData::BufferOwned);
 
     v8::Local<v8::Value> result = script->BindToCurrentContext()->Run();
-    CHECK(result->ToString()->Equals(v8_str("abcdef")));
+    CHECK(result->ToString(isolate1)->Equals(v8_str("abcdef")));
   }
   isolate1->Dispose();
 
   v8::Isolate* isolate2 = v8::Isolate::New();
+  isolate2->SetJitCodeEventHandler(v8::kJitCodeEventDefault,
+                                   SerializerCodeEventListener);
+  toplevel_test_code_event_found = false;
   {
     v8::Isolate::Scope iscope(isolate2);
     v8::HandleScope scope(isolate2);
@@ -832,8 +1147,125 @@
       script = v8::ScriptCompiler::CompileUnbound(
           isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache);
     }
+    CHECK(!cache->rejected);
     v8::Local<v8::Value> result = script->BindToCurrentContext()->Run();
-    CHECK(result->ToString()->Equals(v8_str("abcdef")));
+    CHECK(result->ToString(isolate2)->Equals(v8_str("abcdef")));
+  }
+  DCHECK(toplevel_test_code_event_found);
+  isolate2->Dispose();
+}
+
+
+TEST(SerializeToplevelFlagChange) {
+  FLAG_serialize_toplevel = true;
+
+  const char* source = "function f() { return 'abc'; }; f() + 'def'";
+  v8::ScriptCompiler::CachedData* cache;
+
+  v8::Isolate* isolate1 = v8::Isolate::New();
+  {
+    v8::Isolate::Scope iscope(isolate1);
+    v8::HandleScope scope(isolate1);
+    v8::Local<v8::Context> context = v8::Context::New(isolate1);
+    v8::Context::Scope context_scope(context);
+
+    v8::Local<v8::String> source_str = v8_str(source);
+    v8::ScriptOrigin origin(v8_str("test"));
+    v8::ScriptCompiler::Source source(source_str, origin);
+    v8::Local<v8::UnboundScript> script = v8::ScriptCompiler::CompileUnbound(
+        isolate1, &source, v8::ScriptCompiler::kProduceCodeCache);
+    const v8::ScriptCompiler::CachedData* data = source.GetCachedData();
+    CHECK(data);
+    // Persist cached data.
+    uint8_t* buffer = NewArray<uint8_t>(data->length);
+    MemCopy(buffer, data->data, data->length);
+    cache = new v8::ScriptCompiler::CachedData(
+        buffer, data->length, v8::ScriptCompiler::CachedData::BufferOwned);
+
+    v8::Local<v8::Value> result = script->BindToCurrentContext()->Run();
+    CHECK(result->ToString(isolate1)->Equals(v8_str("abcdef")));
+  }
+  isolate1->Dispose();
+
+  v8::Isolate* isolate2 = v8::Isolate::New();
+  FLAG_allow_natives_syntax = true;  // Flag change should trigger cache reject.
+  {
+    v8::Isolate::Scope iscope(isolate2);
+    v8::HandleScope scope(isolate2);
+    v8::Local<v8::Context> context = v8::Context::New(isolate2);
+    v8::Context::Scope context_scope(context);
+
+    v8::Local<v8::String> source_str = v8_str(source);
+    v8::ScriptOrigin origin(v8_str("test"));
+    v8::ScriptCompiler::Source source(source_str, origin, cache);
+    v8::ScriptCompiler::CompileUnbound(isolate2, &source,
+                                       v8::ScriptCompiler::kConsumeCodeCache);
+    CHECK(cache->rejected);
+  }
+  isolate2->Dispose();
+}
+
+
+TEST(SerializeWithHarmonyScoping) {
+  FLAG_serialize_toplevel = true;
+  FLAG_harmony_scoping = true;
+
+  const char* source1 = "'use strict'; let x = 'X'";
+  const char* source2 = "'use strict'; let y = 'Y'";
+  const char* source3 = "'use strict'; x + y";
+
+  v8::ScriptCompiler::CachedData* cache;
+
+  v8::Isolate* isolate1 = v8::Isolate::New();
+  {
+    v8::Isolate::Scope iscope(isolate1);
+    v8::HandleScope scope(isolate1);
+    v8::Local<v8::Context> context = v8::Context::New(isolate1);
+    v8::Context::Scope context_scope(context);
+
+    CompileRun(source1);
+    CompileRun(source2);
+
+    v8::Local<v8::String> source_str = v8_str(source3);
+    v8::ScriptOrigin origin(v8_str("test"));
+    v8::ScriptCompiler::Source source(source_str, origin);
+    v8::Local<v8::UnboundScript> script = v8::ScriptCompiler::CompileUnbound(
+        isolate1, &source, v8::ScriptCompiler::kProduceCodeCache);
+    const v8::ScriptCompiler::CachedData* data = source.GetCachedData();
+    CHECK(data);
+    // Persist cached data.
+    uint8_t* buffer = NewArray<uint8_t>(data->length);
+    MemCopy(buffer, data->data, data->length);
+    cache = new v8::ScriptCompiler::CachedData(
+        buffer, data->length, v8::ScriptCompiler::CachedData::BufferOwned);
+
+    v8::Local<v8::Value> result = script->BindToCurrentContext()->Run();
+    CHECK(result->ToString(isolate1)->Equals(v8_str("XY")));
+  }
+  isolate1->Dispose();
+
+  v8::Isolate* isolate2 = v8::Isolate::New();
+  {
+    v8::Isolate::Scope iscope(isolate2);
+    v8::HandleScope scope(isolate2);
+    v8::Local<v8::Context> context = v8::Context::New(isolate2);
+    v8::Context::Scope context_scope(context);
+
+    // Reverse order of prior running scripts.
+    CompileRun(source2);
+    CompileRun(source1);
+
+    v8::Local<v8::String> source_str = v8_str(source3);
+    v8::ScriptOrigin origin(v8_str("test"));
+    v8::ScriptCompiler::Source source(source_str, origin, cache);
+    v8::Local<v8::UnboundScript> script;
+    {
+      DisallowCompilation no_compile(reinterpret_cast<Isolate*>(isolate2));
+      script = v8::ScriptCompiler::CompileUnbound(
+          isolate2, &source, v8::ScriptCompiler::kConsumeCodeCache);
+    }
+    v8::Local<v8::Value> result = script->BindToCurrentContext()->Run();
+    CHECK(result->ToString(isolate2)->Equals(v8_str("XY")));
   }
   isolate2->Dispose();
 }
diff --git a/test/cctest/test-spaces.cc b/test/cctest/test-spaces.cc
index d09c128..a84b867 100644
--- a/test/cctest/test-spaces.cc
+++ b/test/cctest/test-spaces.cc
@@ -27,6 +27,7 @@
 
 #include <stdlib.h>
 
+#include "src/base/platform/platform.h"
 #include "src/snapshot.h"
 #include "src/v8.h"
 #include "test/cctest/cctest.h"
@@ -212,11 +213,17 @@
   TestMemoryAllocatorScope test_allocator_scope(isolate, memory_allocator);
   CodeRange* code_range = new CodeRange(isolate);
   const size_t code_range_size = 4 * MB;
-  if (!code_range->SetUp(code_range_size)) return;
+  if (!code_range->SetUp(
+          code_range_size +
+          RoundUp(v8::base::OS::CommitPageSize() * kReservedCodeRangePages,
+                  MemoryChunk::kAlignment) +
+          v8::internal::MemoryAllocator::CodePageAreaSize())) {
+    return;
+  }
   Address address;
   size_t size;
-  address = code_range->AllocateRawMemory(code_range_size - MB,
-                                          code_range_size - MB, &size);
+  address = code_range->AllocateRawMemory(code_range_size - 2 * MB,
+                                          code_range_size - 2 * MB, &size);
   CHECK(address != NULL);
   Address null_address;
   size_t null_size;
@@ -450,3 +457,55 @@
   // No large objects required to perform the above steps.
   CHECK(isolate->heap()->lo_space()->IsEmpty());
 }
+
+
+static inline void FillCurrentPage(v8::internal::NewSpace* space) {
+  int new_linear_size = static_cast<int>(*space->allocation_limit_address() -
+                                         *space->allocation_top_address());
+  if (new_linear_size == 0) return;
+  v8::internal::AllocationResult allocation =
+      space->AllocateRaw(new_linear_size);
+  v8::internal::FreeListNode* node =
+      v8::internal::FreeListNode::cast(allocation.ToObjectChecked());
+  node->set_size(space->heap(), new_linear_size);
+}
+
+
+UNINITIALIZED_TEST(NewSpaceGrowsToTargetCapacity) {
+  FLAG_target_semi_space_size = 2;
+  if (FLAG_optimize_for_size) return;
+
+  v8::Isolate* isolate = v8::Isolate::New();
+  {
+    v8::Isolate::Scope isolate_scope(isolate);
+    v8::HandleScope handle_scope(isolate);
+    v8::Context::New(isolate)->Enter();
+
+    Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
+
+    NewSpace* new_space = i_isolate->heap()->new_space();
+
+    // This test doesn't work if we start with a non-default new space
+    // configuration.
+    if (new_space->InitialTotalCapacity() == Page::kPageSize) {
+      CHECK(new_space->CommittedMemory() == new_space->InitialTotalCapacity());
+
+      // Fill up the first (and only) page of the semi space.
+      FillCurrentPage(new_space);
+
+      // Try to allocate out of the new space. A new page should be added and
+      // the
+      // allocation should succeed.
+      v8::internal::AllocationResult allocation = new_space->AllocateRaw(80);
+      CHECK(!allocation.IsRetry());
+      CHECK(new_space->CommittedMemory() == 2 * Page::kPageSize);
+
+      // Turn the allocation into a proper object so isolate teardown won't
+      // crash.
+      v8::internal::FreeListNode* node =
+          v8::internal::FreeListNode::cast(allocation.ToObjectChecked());
+      node->set_size(new_space->heap(), 80);
+    }
+  }
+  isolate->Dispose();
+}
diff --git a/test/cctest/test-strings.cc b/test/cctest/test-strings.cc
index ef13c4d..d1f23f7 100644
--- a/test/cctest/test-strings.cc
+++ b/test/cctest/test-strings.cc
@@ -37,6 +37,7 @@
 #include "src/api.h"
 #include "src/factory.h"
 #include "src/objects.h"
+#include "src/unicode-decoder.h"
 #include "test/cctest/cctest.h"
 
 // Adapted from http://en.wikipedia.org/wiki/Multiply-with-carry
@@ -356,10 +357,10 @@
 
 void AccumulateStatsWithOperator(
     ConsString* cons_string, ConsStringStats* stats) {
-  ConsStringIteratorOp op(cons_string);
+  ConsStringIterator iter(cons_string);
   String* string;
   int offset;
-  while (NULL != (string = op.Next(&offset))) {
+  while (NULL != (string = iter.Next(&offset))) {
     // Accumulate stats.
     CHECK_EQ(0, offset);
     stats->leaves_++;
@@ -523,13 +524,10 @@
 }
 
 
-static ConsStringIteratorOp cons_string_iterator_op_1;
-static ConsStringIteratorOp cons_string_iterator_op_2;
-
 static void Traverse(Handle<String> s1, Handle<String> s2) {
   int i = 0;
-  StringCharacterStream character_stream_1(*s1, &cons_string_iterator_op_1);
-  StringCharacterStream character_stream_2(*s2, &cons_string_iterator_op_2);
+  StringCharacterStream character_stream_1(*s1);
+  StringCharacterStream character_stream_2(*s2);
   while (character_stream_1.HasMore()) {
     CHECK(character_stream_2.HasMore());
     uint16_t c = character_stream_1.GetNext();
@@ -545,8 +543,8 @@
 
 static void TraverseFirst(Handle<String> s1, Handle<String> s2, int chars) {
   int i = 0;
-  StringCharacterStream character_stream_1(*s1, &cons_string_iterator_op_1);
-  StringCharacterStream character_stream_2(*s2, &cons_string_iterator_op_2);
+  StringCharacterStream character_stream_1(*s1);
+  StringCharacterStream character_stream_2(*s2);
   while (character_stream_1.HasMore() && i < chars) {
     CHECK(character_stream_2.HasMore());
     uint16_t c = character_stream_1.GetNext();
@@ -615,10 +613,8 @@
     if (offset < 0) offset = 0;
     // Want to test the offset == length case.
     if (offset > length) offset = length;
-    StringCharacterStream flat_stream(
-        flat_string, &cons_string_iterator_op_1, offset);
-    StringCharacterStream cons_stream(
-        cons_string, &cons_string_iterator_op_2, offset);
+    StringCharacterStream flat_stream(flat_string, offset);
+    StringCharacterStream cons_stream(cons_string, offset);
     for (int i = offset; i < length; i++) {
       uint16_t c = flat_string->Get(i);
       CHECK(flat_stream.HasMore());
@@ -634,14 +630,11 @@
 
 static inline void PrintStats(const ConsStringGenerationData& data) {
 #ifdef DEBUG
-printf(
-    "%s: [%d], %s: [%d], %s: [%d], %s: [%d], %s: [%d], %s: [%d]\n",
-    "leaves", data.stats_.leaves_,
-    "empty", data.stats_.empty_leaves_,
-    "chars", data.stats_.chars_,
-    "lefts", data.stats_.left_traversals_,
-    "rights", data.stats_.right_traversals_,
-    "early_terminations", data.early_terminations_);
+  printf("%s: [%u], %s: [%u], %s: [%u], %s: [%u], %s: [%u], %s: [%u]\n",
+         "leaves", data.stats_.leaves_, "empty", data.stats_.empty_leaves_,
+         "chars", data.stats_.chars_, "lefts", data.stats_.left_traversals_,
+         "rights", data.stats_.right_traversals_, "early_terminations",
+         data.early_terminations_);
 #endif
 }
 
@@ -1027,11 +1020,13 @@
   // into a two-byte external string.  Check that JSON.stringify works.
   v8::HandleScope handle_scope(CcTest::isolate());
   v8::Handle<v8::String> underlying =
-      CompileRun("var underlying = 'abcdefghijklmnopqrstuvwxyz';"
-                 "underlying")->ToString();
-  v8::Handle<v8::String> slice =
-      CompileRun("var slice = underlying.slice(1);"
-                 "slice")->ToString();
+      CompileRun(
+          "var underlying = 'abcdefghijklmnopqrstuvwxyz';"
+          "underlying")->ToString(CcTest::isolate());
+  v8::Handle<v8::String> slice = CompileRun(
+                                     "var slice = '';"
+                                     "slice = underlying.slice(1);"
+                                     "slice")->ToString(CcTest::isolate());
   CHECK(v8::Utils::OpenHandle(*slice)->IsSlicedString());
   CHECK(v8::Utils::OpenHandle(*underlying)->IsSeqOneByteString());
 
@@ -1089,7 +1084,7 @@
     CHECK_EQ(results[i]->IsNumber(), result->IsNumber());
     if (result->IsNumber()) {
       CHECK_EQ(Object::ToSmi(isolate, results[i]).ToHandleChecked()->value(),
-               result->ToInt32()->Value());
+               result->ToInt32(CcTest::isolate())->Value());
     }
   }
 }
@@ -1189,7 +1184,7 @@
   v8::Local<v8::Value> result;
   Handle<String> string;
   const char* init = "var str = 'abcdefghijklmnopqrstuvwxyz';";
-  const char* slice = "var slice = str.slice(1,-1); slice";
+  const char* slice = "var slice = ''; slice = str.slice(1,-1); slice";
   const char* slice_from_slice = "slice.slice(1,-1);";
 
   CompileRun(init);
@@ -1292,6 +1287,42 @@
 }
 
 
+namespace {
+
+int* global_use_counts = NULL;
+
+void MockUseCounterCallback(v8::Isolate* isolate,
+                            v8::Isolate::UseCounterFeature feature) {
+  ++global_use_counts[feature];
+}
+}
+
+
+TEST(CountBreakIterator) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+  LocalContext context;
+  int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
+  global_use_counts = use_counts;
+  CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
+  CHECK_EQ(0, use_counts[v8::Isolate::kBreakIterator]);
+  v8::Local<v8::Value> result = CompileRun(
+      "(function() {"
+      "  if (!this.Intl) return 0;"
+      "  var iterator = Intl.v8BreakIterator(['en']);"
+      "  iterator.adoptText('Now is the time');"
+      "  iterator.next();"
+      "  return iterator.next();"
+      "})();");
+  CHECK(result->IsNumber());
+  int uses = result->ToInt32(CcTest::isolate())->Value() == 0 ? 0 : 1;
+  CHECK_EQ(uses, use_counts[v8::Isolate::kBreakIterator]);
+  // Make sure GC cleans up the break iterator, so we don't get a memory leak
+  // reported by ASAN.
+  CcTest::isolate()->LowMemoryNotification();
+}
+
+
 TEST(StringReplaceAtomTwoByteResult) {
   CcTest::InitializeVM();
   v8::HandleScope scope(CcTest::isolate());
diff --git a/test/cctest/test-transitions.cc b/test/cctest/test-transitions.cc
new file mode 100644
index 0000000..6bcdb35
--- /dev/null
+++ b/test/cctest/test-transitions.cc
@@ -0,0 +1,301 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdlib.h>
+#include <utility>
+
+#include "src/v8.h"
+
+#include "src/compilation-cache.h"
+#include "src/execution.h"
+#include "src/factory.h"
+#include "src/global-handles.h"
+#include "test/cctest/cctest.h"
+
+using namespace v8::internal;
+
+
+//
+// Helper functions.
+//
+
+static void ConnectTransition(Handle<Map> parent,
+                              Handle<TransitionArray> transitions,
+                              Handle<Map> child) {
+  if (!parent->HasTransitionArray() || *transitions != parent->transitions()) {
+    parent->set_transitions(*transitions);
+  }
+  child->SetBackPointer(*parent);
+}
+
+
+static void CheckPropertyDetailsFieldsConsistency(PropertyType type,
+                                                  PropertyKind kind,
+                                                  PropertyLocation location) {
+  int type_value = PropertyDetails::TypeField::encode(type);
+  int kind_location_value = PropertyDetails::KindField::encode(kind) |
+                            PropertyDetails::LocationField::encode(location);
+  CHECK_EQ(type_value, kind_location_value);
+}
+
+
+TEST(PropertyDetailsFieldsConsistency) {
+  CheckPropertyDetailsFieldsConsistency(FIELD, DATA, IN_OBJECT);
+  CheckPropertyDetailsFieldsConsistency(CONSTANT, DATA, IN_DESCRIPTOR);
+  CheckPropertyDetailsFieldsConsistency(ACCESSOR_FIELD, ACCESSOR, IN_OBJECT);
+  CheckPropertyDetailsFieldsConsistency(CALLBACKS, ACCESSOR, IN_DESCRIPTOR);
+}
+
+
+TEST(TransitionArray_SimpleFieldTransitions) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* factory = isolate->factory();
+
+  Handle<String> name1 = factory->InternalizeUtf8String("foo");
+  Handle<String> name2 = factory->InternalizeUtf8String("bar");
+  PropertyAttributes attributes = NONE;
+
+  Handle<Map> map0 = Map::Create(isolate, 0);
+  Handle<Map> map1 =
+      Map::CopyWithField(map0, name1, handle(HeapType::Any(), isolate),
+                         attributes, Representation::Tagged(),
+                         OMIT_TRANSITION).ToHandleChecked();
+  Handle<Map> map2 =
+      Map::CopyWithField(map0, name2, handle(HeapType::Any(), isolate),
+                         attributes, Representation::Tagged(),
+                         OMIT_TRANSITION).ToHandleChecked();
+
+  CHECK(!map0->HasTransitionArray());
+  Handle<TransitionArray> transitions = TransitionArray::Allocate(isolate, 0);
+  CHECK(transitions->IsFullTransitionArray());
+
+  int transition;
+  transitions =
+      transitions->Insert(map0, name1, map1, SIMPLE_PROPERTY_TRANSITION);
+  ConnectTransition(map0, transitions, map1);
+  CHECK(transitions->IsSimpleTransition());
+  transition = transitions->Search(DATA, *name1, attributes);
+  CHECK_EQ(TransitionArray::kSimpleTransitionIndex, transition);
+  CHECK_EQ(*name1, transitions->GetKey(transition));
+  CHECK_EQ(*map1, transitions->GetTarget(transition));
+
+  transitions =
+      transitions->Insert(map0, name2, map2, SIMPLE_PROPERTY_TRANSITION);
+  ConnectTransition(map0, transitions, map2);
+  CHECK(transitions->IsFullTransitionArray());
+
+  transition = transitions->Search(DATA, *name1, attributes);
+  CHECK_EQ(*name1, transitions->GetKey(transition));
+  CHECK_EQ(*map1, transitions->GetTarget(transition));
+
+  transition = transitions->Search(DATA, *name2, attributes);
+  CHECK_EQ(*name2, transitions->GetKey(transition));
+  CHECK_EQ(*map2, transitions->GetTarget(transition));
+
+  DCHECK(transitions->IsSortedNoDuplicates());
+}
+
+
+TEST(TransitionArray_FullFieldTransitions) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* factory = isolate->factory();
+
+  Handle<String> name1 = factory->InternalizeUtf8String("foo");
+  Handle<String> name2 = factory->InternalizeUtf8String("bar");
+  PropertyAttributes attributes = NONE;
+
+  Handle<Map> map0 = Map::Create(isolate, 0);
+  Handle<Map> map1 =
+      Map::CopyWithField(map0, name1, handle(HeapType::Any(), isolate),
+                         attributes, Representation::Tagged(),
+                         OMIT_TRANSITION).ToHandleChecked();
+  Handle<Map> map2 =
+      Map::CopyWithField(map0, name2, handle(HeapType::Any(), isolate),
+                         attributes, Representation::Tagged(),
+                         OMIT_TRANSITION).ToHandleChecked();
+
+  CHECK(!map0->HasTransitionArray());
+  Handle<TransitionArray> transitions = TransitionArray::Allocate(isolate, 0);
+  CHECK(transitions->IsFullTransitionArray());
+
+  int transition;
+  transitions = transitions->Insert(map0, name1, map1, PROPERTY_TRANSITION);
+  ConnectTransition(map0, transitions, map1);
+  CHECK(transitions->IsFullTransitionArray());
+  transition = transitions->Search(DATA, *name1, attributes);
+  CHECK_EQ(*name1, transitions->GetKey(transition));
+  CHECK_EQ(*map1, transitions->GetTarget(transition));
+
+  transitions = transitions->Insert(map0, name2, map2, PROPERTY_TRANSITION);
+  ConnectTransition(map0, transitions, map2);
+  CHECK(transitions->IsFullTransitionArray());
+
+  transition = transitions->Search(DATA, *name1, attributes);
+  CHECK_EQ(*name1, transitions->GetKey(transition));
+  CHECK_EQ(*map1, transitions->GetTarget(transition));
+
+  transition = transitions->Search(DATA, *name2, attributes);
+  CHECK_EQ(*name2, transitions->GetKey(transition));
+  CHECK_EQ(*map2, transitions->GetTarget(transition));
+
+  DCHECK(transitions->IsSortedNoDuplicates());
+}
+
+
+TEST(TransitionArray_DifferentFieldNames) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* factory = isolate->factory();
+
+  const int PROPS_COUNT = 10;
+  Handle<String> names[PROPS_COUNT];
+  Handle<Map> maps[PROPS_COUNT];
+  PropertyAttributes attributes = NONE;
+
+  Handle<Map> map0 = Map::Create(isolate, 0);
+  CHECK(!map0->HasTransitionArray());
+  Handle<TransitionArray> transitions = TransitionArray::Allocate(isolate, 0);
+  CHECK(transitions->IsFullTransitionArray());
+
+  for (int i = 0; i < PROPS_COUNT; i++) {
+    EmbeddedVector<char, 64> buffer;
+    SNPrintF(buffer, "prop%d", i);
+    Handle<String> name = factory->InternalizeUtf8String(buffer.start());
+    Handle<Map> map =
+        Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate),
+                           attributes, Representation::Tagged(),
+                           OMIT_TRANSITION).ToHandleChecked();
+    names[i] = name;
+    maps[i] = map;
+
+    transitions = transitions->Insert(map0, name, map, PROPERTY_TRANSITION);
+    ConnectTransition(map0, transitions, map);
+  }
+
+  for (int i = 0; i < PROPS_COUNT; i++) {
+    int transition = transitions->Search(DATA, *names[i], attributes);
+    CHECK_EQ(*names[i], transitions->GetKey(transition));
+    CHECK_EQ(*maps[i], transitions->GetTarget(transition));
+  }
+
+  DCHECK(transitions->IsSortedNoDuplicates());
+}
+
+
+TEST(TransitionArray_SameFieldNamesDifferentAttributesSimple) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* factory = isolate->factory();
+
+  Handle<Map> map0 = Map::Create(isolate, 0);
+  CHECK(!map0->HasTransitionArray());
+  Handle<TransitionArray> transitions = TransitionArray::Allocate(isolate, 0);
+  CHECK(transitions->IsFullTransitionArray());
+
+  const int ATTRS_COUNT = (READ_ONLY | DONT_ENUM | DONT_DELETE) + 1;
+  STATIC_ASSERT(ATTRS_COUNT == 8);
+  Handle<Map> attr_maps[ATTRS_COUNT];
+  Handle<String> name = factory->InternalizeUtf8String("foo");
+
+  // Add transitions for same field name but different attributes.
+  for (int i = 0; i < ATTRS_COUNT; i++) {
+    PropertyAttributes attributes = static_cast<PropertyAttributes>(i);
+
+    Handle<Map> map =
+        Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate),
+                           attributes, Representation::Tagged(),
+                           OMIT_TRANSITION).ToHandleChecked();
+    attr_maps[i] = map;
+
+    transitions = transitions->Insert(map0, name, map, PROPERTY_TRANSITION);
+    ConnectTransition(map0, transitions, map);
+  }
+
+  // Ensure that transitions for |name| field are valid.
+  for (int i = 0; i < ATTRS_COUNT; i++) {
+    PropertyAttributes attributes = static_cast<PropertyAttributes>(i);
+
+    int transition = transitions->Search(DATA, *name, attributes);
+    CHECK_EQ(*name, transitions->GetKey(transition));
+    CHECK_EQ(*attr_maps[i], transitions->GetTarget(transition));
+  }
+
+  DCHECK(transitions->IsSortedNoDuplicates());
+}
+
+
+TEST(TransitionArray_SameFieldNamesDifferentAttributes) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* factory = isolate->factory();
+
+  const int PROPS_COUNT = 10;
+  Handle<String> names[PROPS_COUNT];
+  Handle<Map> maps[PROPS_COUNT];
+
+  Handle<Map> map0 = Map::Create(isolate, 0);
+  CHECK(!map0->HasTransitionArray());
+  Handle<TransitionArray> transitions = TransitionArray::Allocate(isolate, 0);
+  CHECK(transitions->IsFullTransitionArray());
+
+  // Some number of fields.
+  for (int i = 0; i < PROPS_COUNT; i++) {
+    EmbeddedVector<char, 64> buffer;
+    SNPrintF(buffer, "prop%d", i);
+    Handle<String> name = factory->InternalizeUtf8String(buffer.start());
+    Handle<Map> map =
+        Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate), NONE,
+                           Representation::Tagged(),
+                           OMIT_TRANSITION).ToHandleChecked();
+    names[i] = name;
+    maps[i] = map;
+
+    transitions = transitions->Insert(map0, name, map, PROPERTY_TRANSITION);
+    ConnectTransition(map0, transitions, map);
+  }
+
+  const int ATTRS_COUNT = (READ_ONLY | DONT_ENUM | DONT_DELETE) + 1;
+  STATIC_ASSERT(ATTRS_COUNT == 8);
+  Handle<Map> attr_maps[ATTRS_COUNT];
+  Handle<String> name = factory->InternalizeUtf8String("foo");
+
+  // Add transitions for same field name but different attributes.
+  for (int i = 0; i < ATTRS_COUNT; i++) {
+    PropertyAttributes attributes = static_cast<PropertyAttributes>(i);
+
+    Handle<Map> map =
+        Map::CopyWithField(map0, name, handle(HeapType::Any(), isolate),
+                           attributes, Representation::Tagged(),
+                           OMIT_TRANSITION).ToHandleChecked();
+    attr_maps[i] = map;
+
+    transitions = transitions->Insert(map0, name, map, PROPERTY_TRANSITION);
+    ConnectTransition(map0, transitions, map);
+  }
+
+  // Ensure that transitions for |name| field are valid.
+  for (int i = 0; i < ATTRS_COUNT; i++) {
+    PropertyAttributes attributes = static_cast<PropertyAttributes>(i);
+
+    int transition = transitions->Search(DATA, *name, attributes);
+    CHECK_EQ(*name, transitions->GetKey(transition));
+    CHECK_EQ(*attr_maps[i], transitions->GetTarget(transition));
+  }
+
+  // Ensure that info about the other fields still valid.
+  for (int i = 0; i < PROPS_COUNT; i++) {
+    int transition = transitions->Search(DATA, *names[i], NONE);
+    CHECK_EQ(*names[i], transitions->GetKey(transition));
+    CHECK_EQ(*maps[i], transitions->GetTarget(transition));
+  }
+
+  DCHECK(transitions->IsSortedNoDuplicates());
+}
diff --git a/test/cctest/test-types.cc b/test/cctest/test-types.cc
index 0cd2472..ebef527 100644
--- a/test/cctest/test-types.cc
+++ b/test/cctest/test-types.cc
@@ -8,12 +8,27 @@
 #include "src/isolate-inl.h"
 #include "src/types.h"
 #include "test/cctest/cctest.h"
+#include "test/cctest/types-fuzz.h"
 
 using namespace v8::internal;
 
+
 // Testing auxiliaries (breaking the Type abstraction).
+
+
+static bool IsInteger(double x) {
+  return nearbyint(x) == x && !i::IsMinusZero(x);  // Allows for infinities.
+}
+
+
+static bool IsInteger(i::Object* x) {
+  return x->IsNumber() && IsInteger(x->Number());
+}
+
+
 typedef uint32_t bitset;
 
+
 struct ZoneRep {
   typedef void* Struct;
 
@@ -76,262 +91,6 @@
 };
 
 
-template<class Type, class TypeHandle, class Region>
-class Types {
- public:
-  Types(Region* region, Isolate* isolate)
-      : region_(region), rng_(isolate->random_number_generator()) {
-    #define DECLARE_TYPE(name, value) \
-      name = Type::name(region); \
-      types.push_back(name);
-    PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
-    #undef DECLARE_TYPE
-
-    object_map = isolate->factory()->NewMap(
-        JS_OBJECT_TYPE, JSObject::kHeaderSize);
-    array_map = isolate->factory()->NewMap(
-        JS_ARRAY_TYPE, JSArray::kSize);
-    number_map = isolate->factory()->NewMap(
-        HEAP_NUMBER_TYPE, HeapNumber::kSize);
-    uninitialized_map = isolate->factory()->uninitialized_map();
-    ObjectClass = Type::Class(object_map, region);
-    ArrayClass = Type::Class(array_map, region);
-    NumberClass = Type::Class(number_map, region);
-    UninitializedClass = Type::Class(uninitialized_map, region);
-
-    maps.push_back(object_map);
-    maps.push_back(array_map);
-    maps.push_back(uninitialized_map);
-    for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) {
-      types.push_back(Type::Class(*it, region));
-    }
-
-    smi = handle(Smi::FromInt(666), isolate);
-    signed32 = isolate->factory()->NewHeapNumber(0x40000000);
-    object1 = isolate->factory()->NewJSObjectFromMap(object_map);
-    object2 = isolate->factory()->NewJSObjectFromMap(object_map);
-    array = isolate->factory()->NewJSArray(20);
-    uninitialized = isolate->factory()->uninitialized_value();
-    SmiConstant = Type::Constant(smi, region);
-    Signed32Constant = Type::Constant(signed32, region);
-    ObjectConstant1 = Type::Constant(object1, region);
-    ObjectConstant2 = Type::Constant(object2, region);
-    ArrayConstant = Type::Constant(array, region);
-    UninitializedConstant = Type::Constant(uninitialized, region);
-
-    values.push_back(smi);
-    values.push_back(signed32);
-    values.push_back(object1);
-    values.push_back(object2);
-    values.push_back(array);
-    values.push_back(uninitialized);
-    for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
-      types.push_back(Type::Constant(*it, region));
-    }
-
-    integers.push_back(isolate->factory()->NewNumber(-V8_INFINITY));
-    integers.push_back(isolate->factory()->NewNumber(+V8_INFINITY));
-    integers.push_back(isolate->factory()->NewNumber(-rng_->NextInt(10)));
-    integers.push_back(isolate->factory()->NewNumber(+rng_->NextInt(10)));
-    for (int i = 0; i < 10; ++i) {
-      double x = rng_->NextInt();
-      integers.push_back(isolate->factory()->NewNumber(x));
-      x *= rng_->NextInt();
-      if (!IsMinusZero(x)) integers.push_back(isolate->factory()->NewNumber(x));
-    }
-
-    NumberArray = Type::Array(Number, region);
-    StringArray = Type::Array(String, region);
-    AnyArray = Type::Array(Any, region);
-
-    SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region);
-    NumberFunction1 = Type::Function(Number, Number, region);
-    NumberFunction2 = Type::Function(Number, Number, Number, region);
-    MethodFunction = Type::Function(String, Object, 0, region);
-
-    for (int i = 0; i < 30; ++i) {
-      types.push_back(Fuzz());
-    }
-  }
-
-  Handle<i::Map> object_map;
-  Handle<i::Map> array_map;
-  Handle<i::Map> number_map;
-  Handle<i::Map> uninitialized_map;
-
-  Handle<i::Smi> smi;
-  Handle<i::HeapNumber> signed32;
-  Handle<i::JSObject> object1;
-  Handle<i::JSObject> object2;
-  Handle<i::JSArray> array;
-  Handle<i::Oddball> uninitialized;
-
-  #define DECLARE_TYPE(name, value) TypeHandle name;
-  BITSET_TYPE_LIST(DECLARE_TYPE)
-  #undef DECLARE_TYPE
-
-  TypeHandle ObjectClass;
-  TypeHandle ArrayClass;
-  TypeHandle NumberClass;
-  TypeHandle UninitializedClass;
-
-  TypeHandle SmiConstant;
-  TypeHandle Signed32Constant;
-  TypeHandle ObjectConstant1;
-  TypeHandle ObjectConstant2;
-  TypeHandle ArrayConstant;
-  TypeHandle UninitializedConstant;
-
-  TypeHandle NumberArray;
-  TypeHandle StringArray;
-  TypeHandle AnyArray;
-
-  TypeHandle SignedFunction1;
-  TypeHandle NumberFunction1;
-  TypeHandle NumberFunction2;
-  TypeHandle MethodFunction;
-
-  typedef std::vector<TypeHandle> TypeVector;
-  typedef std::vector<Handle<i::Map> > MapVector;
-  typedef std::vector<Handle<i::Object> > ValueVector;
-
-  TypeVector types;
-  MapVector maps;
-  ValueVector values;
-  ValueVector integers;  // "Integer" values used for range limits.
-
-  TypeHandle Of(Handle<i::Object> value) {
-    return Type::Of(value, region_);
-  }
-
-  TypeHandle NowOf(Handle<i::Object> value) {
-    return Type::NowOf(value, region_);
-  }
-
-  TypeHandle Class(Handle<i::Map> map) {
-    return Type::Class(map, region_);
-  }
-
-  TypeHandle Constant(Handle<i::Object> value) {
-    return Type::Constant(value, region_);
-  }
-
-  TypeHandle Range(Handle<i::Object> min, Handle<i::Object> max) {
-    return Type::Range(min, max, region_);
-  }
-
-  TypeHandle Context(TypeHandle outer) {
-    return Type::Context(outer, region_);
-  }
-
-  TypeHandle Array1(TypeHandle element) {
-    return Type::Array(element, region_);
-  }
-
-  TypeHandle Function0(TypeHandle result, TypeHandle receiver) {
-    return Type::Function(result, receiver, 0, region_);
-  }
-
-  TypeHandle Function1(TypeHandle result, TypeHandle receiver, TypeHandle arg) {
-    TypeHandle type = Type::Function(result, receiver, 1, region_);
-    type->AsFunction()->InitParameter(0, arg);
-    return type;
-  }
-
-  TypeHandle Function2(TypeHandle result, TypeHandle arg1, TypeHandle arg2) {
-    return Type::Function(result, arg1, arg2, region_);
-  }
-
-  TypeHandle Union(TypeHandle t1, TypeHandle t2) {
-    return Type::Union(t1, t2, region_);
-  }
-  TypeHandle Intersect(TypeHandle t1, TypeHandle t2) {
-    return Type::Intersect(t1, t2, region_);
-  }
-
-  template<class Type2, class TypeHandle2>
-  TypeHandle Convert(TypeHandle2 t) {
-    return Type::template Convert<Type2>(t, region_);
-  }
-
-  TypeHandle Random() {
-    return types[rng_->NextInt(static_cast<int>(types.size()))];
-  }
-
-  TypeHandle Fuzz(int depth = 4) {
-    switch (rng_->NextInt(depth == 0 ? 3 : 20)) {
-      case 0: {  // bitset
-        int n = 0
-        #define COUNT_BITSET_TYPES(type, value) + 1
-        PROPER_BITSET_TYPE_LIST(COUNT_BITSET_TYPES)
-        #undef COUNT_BITSET_TYPES
-        ;
-        int i = rng_->NextInt(n);
-        #define PICK_BITSET_TYPE(type, value) \
-          if (i-- == 0) return Type::type(region_);
-        PROPER_BITSET_TYPE_LIST(PICK_BITSET_TYPE)
-        #undef PICK_BITSET_TYPE
-        UNREACHABLE();
-      }
-      case 1: {  // class
-        int i = rng_->NextInt(static_cast<int>(maps.size()));
-        return Type::Class(maps[i], region_);
-      }
-      case 2: {  // constant
-        int i = rng_->NextInt(static_cast<int>(values.size()));
-        return Type::Constant(values[i], region_);
-      }
-      case 3: {  // range
-        int i = rng_->NextInt(static_cast<int>(integers.size()));
-        int j = rng_->NextInt(static_cast<int>(integers.size()));
-        i::Handle<i::Object> min = integers[i];
-        i::Handle<i::Object> max = integers[j];
-        if (min->Number() > max->Number()) std::swap(min, max);
-        return Type::Range(min, max, region_);
-      }
-      case 4: {  // context
-        int depth = rng_->NextInt(3);
-        TypeHandle type = Type::Internal(region_);
-        for (int i = 0; i < depth; ++i) type = Type::Context(type, region_);
-        return type;
-      }
-      case 5: {  // array
-        TypeHandle element = Fuzz(depth / 2);
-        return Type::Array(element, region_);
-      }
-      case 6:
-      case 7: {  // function
-        TypeHandle result = Fuzz(depth / 2);
-        TypeHandle receiver = Fuzz(depth / 2);
-        int arity = rng_->NextInt(3);
-        TypeHandle type = Type::Function(result, receiver, arity, region_);
-        for (int i = 0; i < type->AsFunction()->Arity(); ++i) {
-          TypeHandle parameter = Fuzz(depth / 2);
-          type->AsFunction()->InitParameter(i, parameter);
-        }
-        return type;
-      }
-      default: {  // union
-        int n = rng_->NextInt(10);
-        TypeHandle type = None;
-        for (int i = 0; i < n; ++i) {
-          TypeHandle operand = Fuzz(depth - 1);
-          type = Type::Union(type, operand, region_);
-        }
-        return type;
-      }
-    }
-    UNREACHABLE();
-  }
-
-  Region* region() { return region_; }
-
- private:
-  Region* region_;
-  v8::base::RandomNumberGenerator* rng_;
-};
-
-
 template<class Type, class TypeHandle, class Region, class Rep>
 struct Tests : Rep {
   typedef Types<Type, TypeHandle, Region> TypesInstance;
@@ -535,39 +294,55 @@
     CHECK(T.Constant(fac->NewNumber(0))->Is(T.UnsignedSmall));
     CHECK(T.Constant(fac->NewNumber(1))->Is(T.UnsignedSmall));
     CHECK(T.Constant(fac->NewNumber(0x3fffffff))->Is(T.UnsignedSmall));
-    CHECK(T.Constant(fac->NewNumber(-1))->Is(T.OtherSignedSmall));
-    CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.OtherSignedSmall));
-    CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.OtherSignedSmall));
+    CHECK(T.Constant(fac->NewNumber(-1))->Is(T.NegativeSignedSmall));
+    CHECK(T.Constant(fac->NewNumber(-0x3fffffff))->Is(T.NegativeSignedSmall));
+    CHECK(T.Constant(fac->NewNumber(-0x40000000))->Is(T.NegativeSignedSmall));
     if (SmiValuesAre31Bits()) {
-      CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
-      CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
-      CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
-      CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
-      CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
+      CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.NonNegativeSigned32));
+      CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall));
+      CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.NonNegativeSigned32));
+      CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall));
+      CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.NegativeSigned32));
+      CHECK(
+          !T.Constant(fac->NewNumber(-0x40000001))->Is(T.NegativeSignedSmall));
+      CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.NegativeSigned32));
+      CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 1))
+                 ->Is(T.NegativeSignedSmall));
     } else {
       CHECK(SmiValuesAre32Bits());
       CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.UnsignedSmall));
       CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.UnsignedSmall));
-      CHECK(!T.Constant(fac->NewNumber(0x40000000))->Is(T.OtherUnsigned31));
-      CHECK(!T.Constant(fac->NewNumber(0x7fffffff))->Is(T.OtherUnsigned31));
-      CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSignedSmall));
-      CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSignedSmall));
-      CHECK(T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSignedSmall));
-      CHECK(!T.Constant(fac->NewNumber(-0x40000001))->Is(T.OtherSigned32));
-      CHECK(!T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.OtherSigned32));
-      CHECK(!T.Constant(fac->NewNumber(-0x7fffffff-1))->Is(T.OtherSigned32));
+      CHECK(T.Constant(fac->NewNumber(0x40000000))->Is(T.NonNegativeSigned32));
+      CHECK(T.Constant(fac->NewNumber(0x7fffffff))->Is(T.NonNegativeSigned32));
+      CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.NegativeSignedSmall));
+      CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.NegativeSignedSmall));
+      CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 1))
+                ->Is(T.NegativeSignedSmall));
+      CHECK(T.Constant(fac->NewNumber(-0x40000001))->Is(T.NegativeSigned32));
+      CHECK(T.Constant(fac->NewNumber(-0x7fffffff))->Is(T.NegativeSigned32));
+      CHECK(
+          T.Constant(fac->NewNumber(-0x7fffffff - 1))->Is(T.NegativeSigned32));
     }
-    CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.OtherUnsigned32));
-    CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.OtherUnsigned32));
-    CHECK(T.Constant(fac->NewNumber(0xffffffffu+1.0))->Is(T.OtherNumber));
-    CHECK(T.Constant(fac->NewNumber(-0x7fffffff-2.0))->Is(T.OtherNumber));
-    CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.OtherNumber));
-    CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.OtherNumber));
-    CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.OtherNumber));
+    CHECK(T.Constant(fac->NewNumber(0x80000000u))->Is(T.Unsigned32));
+    CHECK(!T.Constant(fac->NewNumber(0x80000000u))->Is(T.NonNegativeSigned32));
+    CHECK(T.Constant(fac->NewNumber(0xffffffffu))->Is(T.Unsigned32));
+    CHECK(!T.Constant(fac->NewNumber(0xffffffffu))->Is(T.NonNegativeSigned32));
+    CHECK(T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.PlainNumber));
+    CHECK(!T.Constant(fac->NewNumber(0xffffffffu + 1.0))->Is(T.Integral32));
+    CHECK(T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.PlainNumber));
+    CHECK(!T.Constant(fac->NewNumber(-0x7fffffff - 2.0))->Is(T.Integral32));
+    CHECK(T.Constant(fac->NewNumber(0.1))->Is(T.PlainNumber));
+    CHECK(!T.Constant(fac->NewNumber(0.1))->Is(T.Integral32));
+    CHECK(T.Constant(fac->NewNumber(-10.1))->Is(T.PlainNumber));
+    CHECK(!T.Constant(fac->NewNumber(-10.1))->Is(T.Integral32));
+    CHECK(T.Constant(fac->NewNumber(10e60))->Is(T.PlainNumber));
+    CHECK(!T.Constant(fac->NewNumber(10e60))->Is(T.Integral32));
     CHECK(T.Constant(fac->NewNumber(-1.0*0.0))->Is(T.MinusZero));
     CHECK(T.Constant(fac->NewNumber(v8::base::OS::nan_value()))->Is(T.NaN));
-    CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.OtherNumber));
-    CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.OtherNumber));
+    CHECK(T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.PlainNumber));
+    CHECK(!T.Constant(fac->NewNumber(V8_INFINITY))->Is(T.Integral32));
+    CHECK(T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.PlainNumber));
+    CHECK(!T.Constant(fac->NewNumber(-V8_INFINITY))->Is(T.Integral32));
   }
 
   void Range() {
@@ -598,11 +373,11 @@
     // Range(min1, max1) = Range(min2, max2) <=> min1 = min2 /\ max1 = max2
     for (ValueIterator i1 = T.integers.begin();
         i1 != T.integers.end(); ++i1) {
-      for (ValueIterator j1 = T.integers.begin();
+      for (ValueIterator j1 = i1;
           j1 != T.integers.end(); ++j1) {
         for (ValueIterator i2 = T.integers.begin();
             i2 != T.integers.end(); ++i2) {
-          for (ValueIterator j2 = T.integers.begin();
+          for (ValueIterator j2 = i2;
               j2 != T.integers.end(); ++j2) {
             i::Handle<i::Object> min1 = *i1;
             i::Handle<i::Object> max1 = *j1;
@@ -619,6 +394,33 @@
     }
   }
 
+  void Context() {
+    // Constructor
+    for (int i = 0; i < 20; ++i) {
+      TypeHandle type = T.Random();
+      TypeHandle context = T.Context(type);
+      CHECK(context->Iscontext());
+    }
+
+    // Attributes
+    for (int i = 0; i < 20; ++i) {
+      TypeHandle type = T.Random();
+      TypeHandle context = T.Context(type);
+      CheckEqual(type, context->AsContext()->Outer());
+    }
+
+    // Functionality & Injectivity: Context(T1) = Context(T2) iff T1 = T2
+    for (int i = 0; i < 20; ++i) {
+      for (int j = 0; j < 20; ++j) {
+        TypeHandle type1 = T.Random();
+        TypeHandle type2 = T.Random();
+        TypeHandle context1 = T.Context(type1);
+        TypeHandle context2 = T.Context(type2);
+        CHECK(Equal(context1, context2) == Equal(type1, type2));
+      }
+    }
+  }
+
   void Array() {
     // Constructor
     for (int i = 0; i < 20; ++i) {
@@ -803,6 +605,66 @@
     }
   }
 
+  void MinMax() {
+    Factory* fac = isolate->factory();
+
+    // If b is regular numeric bitset, then Range(b->Min(), b->Max())->Is(b).
+    // TODO(neis): Need to ignore representation for this to be true.
+    /*
+    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+      TypeHandle type = *it;
+      if (this->IsBitset(type) && type->Is(T.Number) &&
+          !type->Is(T.None) && !type->Is(T.NaN)) {
+        TypeHandle range = T.Range(
+            isolate->factory()->NewNumber(type->Min()),
+            isolate->factory()->NewNumber(type->Max()));
+        CHECK(range->Is(type));
+      }
+    }
+    */
+
+    // If b is regular numeric bitset, then b->Min() and b->Max() are integers.
+    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+      TypeHandle type = *it;
+      if (this->IsBitset(type) && type->Is(T.Number) && !type->Is(T.NaN)) {
+        CHECK(IsInteger(type->Min()) && IsInteger(type->Max()));
+      }
+    }
+
+    // If b1 and b2 are regular numeric bitsets with b1->Is(b2), then
+    // b1->Min() >= b2->Min() and b1->Max() <= b2->Max().
+    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
+      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
+        TypeHandle type1 = *it1;
+        TypeHandle type2 = *it2;
+        if (this->IsBitset(type1) && type1->Is(type2) && type2->Is(T.Number) &&
+            !type1->Is(T.NaN) && !type2->Is(T.NaN)) {
+          CHECK(type1->Min() >= type2->Min());
+          CHECK(type1->Max() <= type2->Max());
+        }
+      }
+    }
+
+    // Lub(Range(x,y))->Min() <= x and y <= Lub(Range(x,y))->Max()
+    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+      TypeHandle type = *it;
+      if (type->IsRange()) {
+        TypeHandle lub = Rep::BitsetType::New(
+            Rep::BitsetType::Lub(type), T.region());
+        CHECK(lub->Min() <= type->Min() && type->Max() <= lub->Max());
+      }
+    }
+
+    // Rangification: If T->Is(Range(-inf,+inf)) and !T->Is(None), then
+    // T->Is(Range(T->Min(), T->Max())).
+    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+      TypeHandle type = *it;
+      CHECK(!(type->Is(T.Integer) && !type->Is(T.None)) ||
+            type->Is(T.Range(fac->NewNumber(type->Min()),
+                             fac->NewNumber(type->Max()))));
+    }
+  }
+
   void BitsetGlb() {
     // Lower: (T->BitsetGlb())->Is(T)
     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
@@ -871,7 +733,7 @@
     }
   }
 
-  void Is() {
+  void Is1() {
     // Least Element (Bottom): None->Is(T)
     for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
       TypeHandle type = *it;
@@ -923,6 +785,26 @@
       }
     }
 
+    // (In-)Compatibilities.
+    for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) {
+      for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) {
+        TypeHandle type1 = *i;
+        TypeHandle type2 = *j;
+        CHECK(!type1->Is(type2) || this->IsBitset(type2) ||
+              this->IsUnion(type2) || this->IsUnion(type1) ||
+              (type1->IsClass() && type2->IsClass()) ||
+              (type1->IsConstant() && type2->IsConstant()) ||
+              (type1->IsConstant() && type2->IsRange()) ||
+              (type1->IsRange() && type2->IsRange()) ||
+              (type1->IsContext() && type2->IsContext()) ||
+              (type1->IsArray() && type2->IsArray()) ||
+              (type1->IsFunction() && type2->IsFunction()) ||
+              type1->Equals(T.None));
+      }
+    }
+  }
+
+  void Is2() {
     // Class(M1)->Is(Class(M2)) iff M1 = M2
     for (MapIterator mt1 = T.maps.begin(); mt1 != T.maps.end(); ++mt1) {
       for (MapIterator mt2 = T.maps.begin(); mt2 != T.maps.end(); ++mt2) {
@@ -934,26 +816,14 @@
       }
     }
 
-    // Constant(V1)->Is(Constant(V2)) iff V1 = V2
-    for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
-      for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
-        Handle<i::Object> value1 = *vt1;
-        Handle<i::Object> value2 = *vt2;
-        TypeHandle const_type1 = T.Constant(value1);
-        TypeHandle const_type2 = T.Constant(value2);
-        CHECK(const_type1->Is(const_type2) == (*value1 == *value2));
-      }
-    }
-
-    // Range(min1, max1)->Is(Range(min2, max2)) iff
-    // min1 >= min2 /\ max1 <= max2
+    // Range(X1, Y1)->Is(Range(X2, Y2)) iff X1 >= X2 /\ Y1 <= Y2
     for (ValueIterator i1 = T.integers.begin();
         i1 != T.integers.end(); ++i1) {
-      for (ValueIterator j1 = T.integers.begin();
+      for (ValueIterator j1 = i1;
           j1 != T.integers.end(); ++j1) {
         for (ValueIterator i2 = T.integers.begin();
              i2 != T.integers.end(); ++i2) {
-          for (ValueIterator j2 = T.integers.begin();
+          for (ValueIterator j2 = i2;
                j2 != T.integers.end(); ++j2) {
             i::Handle<i::Object> min1 = *i1;
             i::Handle<i::Object> max1 = *j1;
@@ -964,13 +834,24 @@
             TypeHandle type1 = T.Range(min1, max1);
             TypeHandle type2 = T.Range(min2, max2);
             CHECK(type1->Is(type2) ==
-                (min2->Number() <= min1->Number() &&
+                (min1->Number() >= min2->Number() &&
                  max1->Number() <= max2->Number()));
           }
         }
       }
     }
 
+    // Constant(V1)->Is(Constant(V2)) iff V1 = V2
+    for (ValueIterator vt1 = T.values.begin(); vt1 != T.values.end(); ++vt1) {
+      for (ValueIterator vt2 = T.values.begin(); vt2 != T.values.end(); ++vt2) {
+        Handle<i::Object> value1 = *vt1;
+        Handle<i::Object> value2 = *vt2;
+        TypeHandle const_type1 = T.Constant(value1);
+        TypeHandle const_type2 = T.Constant(value2);
+        CHECK(const_type1->Is(const_type2) == (*value1 == *value2));
+      }
+    }
+
     // Context(T1)->Is(Context(T2)) iff T1 = T2
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
@@ -1007,25 +888,45 @@
       }
     }
 
-    // (In-)Compatibilities.
-    for (TypeIterator i = T.types.begin(); i != T.types.end(); ++i) {
-      for (TypeIterator j = T.types.begin(); j != T.types.end(); ++j) {
-        TypeHandle type1 = *i;
-        TypeHandle type2 = *j;
-        CHECK(!type1->Is(type2) || this->IsBitset(type2) ||
-              this->IsUnion(type2) || this->IsUnion(type1) ||
-              (type1->IsClass() && type2->IsClass()) ||
-              (type1->IsConstant() && type2->IsConstant()) ||
-              (type1->IsConstant() && type2->IsRange()) ||
-              (type1->IsRange() && type2->IsRange()) ||
-              (type1->IsContext() && type2->IsContext()) ||
-              (type1->IsArray() && type2->IsArray()) ||
-              (type1->IsFunction() && type2->IsFunction()) ||
-              type1->Equals(T.None));
+
+    // Range-specific subtyping
+
+    // If IsInteger(v) then Constant(v)->Is(Range(v, v)).
+    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+      TypeHandle type = *it;
+      if (type->IsConstant() && IsInteger(*type->AsConstant()->Value())) {
+        CHECK(type->Is(
+            T.Range(type->AsConstant()->Value(), type->AsConstant()->Value())));
       }
     }
 
-    // Basic types
+    // If Constant(x)->Is(Range(min,max)) then IsInteger(v) and min <= x <= max.
+    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
+      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
+        TypeHandle type1 = *it1;
+        TypeHandle type2 = *it2;
+        if (type1->IsConstant() && type2->IsRange() && type1->Is(type2)) {
+          double x = type1->AsConstant()->Value()->Number();
+          double min = type2->AsRange()->Min()->Number();
+          double max = type2->AsRange()->Max()->Number();
+          CHECK(IsInteger(x) && min <= x && x <= max);
+        }
+      }
+    }
+
+    // Lub(Range(x,y))->Is(T.Union(T.Integral32, T.OtherNumber))
+    for (TypeIterator it = T.types.begin(); it != T.types.end(); ++it) {
+      TypeHandle type = *it;
+      if (type->IsRange()) {
+        TypeHandle lub = Rep::BitsetType::New(
+            Rep::BitsetType::Lub(type), T.region());
+        CHECK(lub->Is(T.PlainNumber));
+      }
+    }
+
+
+    // Subtyping between concrete basic types
+
     CheckUnordered(T.Boolean, T.Null);
     CheckUnordered(T.Undefined, T.Null);
     CheckUnordered(T.Boolean, T.Undefined);
@@ -1049,12 +950,12 @@
 
     CheckSub(T.Object, T.Receiver);
     CheckSub(T.Array, T.Object);
-    CheckSub(T.Function, T.Object);
     CheckSub(T.Proxy, T.Receiver);
     CheckUnordered(T.Object, T.Proxy);
-    CheckUnordered(T.Array, T.Function);
 
-    // Structural types
+
+    // Subtyping between concrete structural types
+
     CheckSub(T.ObjectClass, T.Object);
     CheckSub(T.ArrayClass, T.Object);
     CheckSub(T.ArrayClass, T.Array);
@@ -1086,7 +987,7 @@
     CheckSub(T.NumberArray, T.Object);
     CheckUnordered(T.StringArray, T.AnyArray);
 
-    CheckSub(T.MethodFunction, T.Function);
+    CheckSub(T.MethodFunction, T.Object);
     CheckSub(T.NumberFunction1, T.Object);
     CheckUnordered(T.SignedFunction1, T.NumberFunction1);
     CheckUnordered(T.NumberFunction1, T.NumberFunction2);
@@ -1372,10 +1273,8 @@
     CheckDisjoint(T.InternalizedString, T.Symbol);
     CheckOverlap(T.Object, T.Receiver);
     CheckOverlap(T.Array, T.Object);
-    CheckOverlap(T.Function, T.Object);
     CheckOverlap(T.Proxy, T.Receiver);
     CheckDisjoint(T.Object, T.Proxy);
-    CheckDisjoint(T.Array, T.Function);
 
     // Structural types
     CheckOverlap(T.ObjectClass, T.Object);
@@ -1399,7 +1298,7 @@
     CheckOverlap(T.NumberArray, T.Array);
     CheckDisjoint(T.NumberArray, T.AnyArray);
     CheckDisjoint(T.NumberArray, T.StringArray);
-    CheckOverlap(T.MethodFunction, T.Function);
+    CheckOverlap(T.MethodFunction, T.Object);
     CheckDisjoint(T.SignedFunction1, T.NumberFunction1);
     CheckDisjoint(T.SignedFunction1, T.NumberFunction2);
     CheckDisjoint(T.NumberFunction1, T.NumberFunction2);
@@ -1443,7 +1342,9 @@
     }
 
     // Associativity: Union(T1, Union(T2, T3)) = Union(Union(T1, T2), T3)
-    // This does NOT hold!
+    // This does NOT hold!  For example:
+    // (Unsigned32 \/ Range(0,5)) \/ Range(-5,0) = Unsigned32 \/ Range(-5,0)
+    // Unsigned32 \/ (Range(0,5) \/ Range(-5,0)) = Unsigned32 \/ Range(-5,5)
     /*
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
@@ -1483,7 +1384,9 @@
     }
 
     // Monotonicity: T1->Is(T2) implies Union(T1, T3)->Is(Union(T2, T3))
-    // This does NOT hold.
+    // This does NOT hold.  For example:
+    // Range(-5,-1) <= Signed32
+    // Range(-5,-1) \/ Range(1,5) = Range(-5,5) </= Signed32 \/ Range(1,5)
     /*
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
@@ -1502,8 +1405,10 @@
 
   void Union2() {
     // Monotonicity: T1->Is(T3) and T2->Is(T3) implies Union(T1, T2)->Is(T3)
-    // This does NOT hold.  TODO(neis): Could fix this by splitting
-    // OtherNumber into a negative and a positive part.
+    // This does NOT hold.  For example:
+    // Range(-2^33, -2^33) <= OtherNumber
+    // Range(2^33, 2^33) <= OtherNumber
+    // Range(-2^33, 2^33) </= OtherNumber
     /*
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
@@ -1523,7 +1428,7 @@
     // Monotonicity: T1->Is(T2) or T1->Is(T3) implies T1->Is(Union(T2, T3))
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
-        for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
+        for (TypeIterator it3 = it2; it3 != T.types.end(); ++it3) {
           TypeHandle type1 = *it1;
           TypeHandle type2 = *it2;
           TypeHandle type3 = *it3;
@@ -1563,11 +1468,11 @@
     CheckDisjoint(T.Union(T.NumberArray, T.String), T.Number);
 
     // Bitset-function
-    CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Function)));
+    CHECK(this->IsBitset(T.Union(T.MethodFunction, T.Object)));
     CHECK(this->IsUnion(T.Union(T.NumberFunction1, T.Number)));
 
-    CheckEqual(T.Union(T.MethodFunction, T.Function), T.Function);
-    CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Function);
+    CheckEqual(T.Union(T.MethodFunction, T.Object), T.Object);
+    CheckUnordered(T.Union(T.NumberFunction1, T.String), T.Object);
     CheckOverlap(T.Union(T.NumberFunction2, T.String), T.Object);
     CheckDisjoint(T.Union(T.NumberFunction1, T.String), T.Number);
 
@@ -1635,7 +1540,7 @@
     CheckEqual(
         T.Union(T.NumberFunction1, T.NumberFunction2),
         T.Union(T.NumberFunction2, T.NumberFunction1));
-    CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Function);
+    CheckSub(T.Union(T.SignedFunction1, T.MethodFunction), T.Object);
 
     // Union-union
     CheckEqual(
@@ -1685,7 +1590,11 @@
 
     // Associativity:
     // Intersect(T1, Intersect(T2, T3)) = Intersect(Intersect(T1, T2), T3)
-    // This does NOT hold.
+    // This does NOT hold.  For example:
+    // (Class(..stringy1..) /\ Class(..stringy2..)) /\ Constant(..string..) =
+    // None
+    // Class(..stringy1..) /\ (Class(..stringy2..) /\ Constant(..string..)) =
+    // Constant(..string..)
     /*
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
@@ -1704,7 +1613,11 @@
     */
 
     // Join: Intersect(T1, T2)->Is(T1) and Intersect(T1, T2)->Is(T2)
-    // This does NOT hold.  Not even the disjunction.
+    // This does NOT hold.  For example:
+    // Class(..stringy..) /\ Constant(..string..) = Constant(..string..)
+    // Currently, not even the disjunction holds:
+    // Class(Internal/TaggedPtr) /\ (Any/Untagged \/ Context(..)) =
+    // Class(Internal/TaggedPtr) \/ Context(..)
     /*
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
@@ -1728,7 +1641,10 @@
     }
 
     // Monotonicity: T1->Is(T2) implies Intersect(T1, T3)->Is(Intersect(T2, T3))
-    // This does NOT hold.
+    // This does NOT hold.  For example:
+    // Class(OtherObject/TaggedPtr) <= Any/TaggedPtr
+    // Class(OtherObject/TaggedPtr) /\ Any/UntaggedInt1 = Class(..)
+    // Any/TaggedPtr /\ Any/UntaggedInt1 = None
     /*
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
@@ -1745,7 +1661,10 @@
     */
 
     // Monotonicity: T1->Is(T3) or T2->Is(T3) implies Intersect(T1, T2)->Is(T3)
-    // This does NOT hold.
+    // This does NOT hold.  For example:
+    // Class(..stringy..) <= Class(..stringy..)
+    // Class(..stringy..) /\ Constant(..string..) = Constant(..string..)
+    // Constant(..string..) </= Class(..stringy..)
     /*
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
@@ -1762,8 +1681,6 @@
     */
 
     // Monotonicity: T1->Is(T2) and T1->Is(T3) implies T1->Is(Intersect(T2, T3))
-    // This does NOT hold.
-    /*
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
         for (TypeIterator it3 = T.types.begin(); it3 != T.types.end(); ++it3) {
@@ -1776,7 +1693,6 @@
         }
       }
     }
-    */
 
     // Bitset-class
     CheckEqual(T.Intersect(T.ObjectClass, T.Object), T.ObjectClass);
@@ -1785,11 +1701,11 @@
 
     // Bitset-array
     CheckEqual(T.Intersect(T.NumberArray, T.Object), T.NumberArray);
-    CheckEqual(T.Intersect(T.AnyArray, T.Function), T.None);
+    CheckEqual(T.Intersect(T.AnyArray, T.Proxy), T.None);
 
     // Bitset-function
     CheckEqual(T.Intersect(T.MethodFunction, T.Object), T.MethodFunction);
-    CheckEqual(T.Intersect(T.NumberFunction1, T.Array), T.None);
+    CheckEqual(T.Intersect(T.NumberFunction1, T.Proxy), T.None);
 
     // Bitset-union
     CheckEqual(
@@ -1880,7 +1796,11 @@
 
   void Distributivity() {
     // Union(T1, Intersect(T2, T3)) = Intersect(Union(T1, T2), Union(T1, T3))
-    // This does NOT hold.
+    // This does NOT hold.  For example:
+    // Untagged \/ (Untagged /\ Class(../Tagged)) = Untagged \/ Class(../Tagged)
+    // (Untagged \/ Untagged) /\ (Untagged \/ Class(../Tagged)) =
+    // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged
+    // because Untagged <= Untagged \/ Class(../Tagged)
     /*
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
@@ -1900,7 +1820,10 @@
     */
 
     // Intersect(T1, Union(T2, T3)) = Union(Intersect(T1, T2), Intersect(T1,T3))
-    // This does NOT hold.
+    // This does NOT hold.  For example:
+    // Untagged /\ (Untagged \/ Class(../Tagged)) = Untagged
+    // (Untagged /\ Untagged) \/ (Untagged /\ Class(../Tagged)) =
+    // Untagged \/ Class(../Tagged)
     /*
     for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
       for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
@@ -1920,6 +1843,32 @@
     */
   }
 
+  void GetRange() {
+    // GetRange(Range(a, b)) = Range(a, b).
+    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
+      TypeHandle type1 = *it1;
+      if (type1->IsRange()) {
+        typename Type::RangeType* range = type1->GetRange();
+        CHECK(type1->Min() == range->Min()->Number());
+        CHECK(type1->Max() == range->Max()->Number());
+      }
+    }
+
+    // GetRange(Union(Constant(x), Range(min,max))) == Range(min, max).
+    for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
+      for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
+        TypeHandle type1 = *it1;
+        TypeHandle type2 = *it2;
+        if (type1->IsConstant() && type2->IsRange()) {
+          TypeHandle u = T.Union(type1, type2);
+
+          CHECK(type2->Min() == u->GetRange()->Min()->Number());
+          CHECK(type2->Max() == u->GetRange()->Max()->Number());
+        }
+      }
+    }
+  }
+
   template<class Type2, class TypeHandle2, class Region2, class Rep2>
   void Convert() {
     Types<Type2, TypeHandle2, Region2> T2(
@@ -2012,6 +1961,13 @@
 }
 
 
+TEST(MinMax) {
+  CcTest::InitializeVM();
+  ZoneTests().MinMax();
+  HeapTests().MinMax();
+}
+
+
 TEST(BitsetGlb) {
   CcTest::InitializeVM();
   ZoneTests().BitsetGlb();
@@ -2026,10 +1982,17 @@
 }
 
 
-TEST(Is) {
+TEST(Is1) {
   CcTest::InitializeVM();
-  ZoneTests().Is();
-  HeapTests().Is();
+  ZoneTests().Is1();
+  HeapTests().Is1();
+}
+
+
+TEST(Is2) {
+  CcTest::InitializeVM();
+  ZoneTests().Is2();
+  HeapTests().Is2();
 }
 
 
@@ -2098,13 +2061,18 @@
 }
 
 
-/*
 TEST(Distributivity) {
   CcTest::InitializeVM();
   ZoneTests().Distributivity();
   HeapTests().Distributivity();
 }
-*/
+
+
+TEST(GetRange) {
+  CcTest::InitializeVM();
+  ZoneTests().GetRange();
+  HeapTests().GetRange();
+}
 
 
 TEST(Convert) {
diff --git a/test/cctest/test-unboxed-doubles.cc b/test/cctest/test-unboxed-doubles.cc
new file mode 100644
index 0000000..a12bf47
--- /dev/null
+++ b/test/cctest/test-unboxed-doubles.cc
@@ -0,0 +1,1162 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdlib.h>
+#include <utility>
+
+#include "src/v8.h"
+
+#include "src/compilation-cache.h"
+#include "src/execution.h"
+#include "src/factory.h"
+#include "src/global-handles.h"
+#include "src/ic/ic.h"
+#include "src/macro-assembler.h"
+#include "test/cctest/cctest.h"
+
+using namespace v8::base;
+using namespace v8::internal;
+
+#if (V8_DOUBLE_FIELDS_UNBOXING)
+
+
+static double GetDoubleFieldValue(JSObject* obj, FieldIndex field_index) {
+  if (obj->IsUnboxedDoubleField(field_index)) {
+    return obj->RawFastDoublePropertyAt(field_index);
+  } else {
+    Object* value = obj->RawFastPropertyAt(field_index);
+    DCHECK(value->IsMutableHeapNumber());
+    return HeapNumber::cast(value)->value();
+  }
+}
+
+const int kNumberOfBits = 32;
+
+
+enum TestPropertyKind {
+  PROP_CONSTANT,
+  PROP_SMI,
+  PROP_DOUBLE,
+  PROP_TAGGED,
+  PROP_KIND_NUMBER
+};
+
+static Representation representations[PROP_KIND_NUMBER] = {
+    Representation::None(), Representation::Smi(), Representation::Double(),
+    Representation::Tagged()};
+
+
+static Handle<DescriptorArray> CreateDescriptorArray(Isolate* isolate,
+                                                     TestPropertyKind* props,
+                                                     int kPropsCount) {
+  Factory* factory = isolate->factory();
+
+  Handle<String> func_name = factory->InternalizeUtf8String("func");
+  Handle<JSFunction> func = factory->NewFunction(func_name);
+
+  Handle<DescriptorArray> descriptors =
+      DescriptorArray::Allocate(isolate, 0, kPropsCount);
+
+  int next_field_offset = 0;
+  for (int i = 0; i < kPropsCount; i++) {
+    EmbeddedVector<char, 64> buffer;
+    SNPrintF(buffer, "prop%d", i);
+    Handle<String> name = factory->InternalizeUtf8String(buffer.start());
+
+    TestPropertyKind kind = props[i];
+
+    if (kind == PROP_CONSTANT) {
+      ConstantDescriptor d(name, func, NONE);
+      descriptors->Append(&d);
+
+    } else {
+      FieldDescriptor f(name, next_field_offset, NONE, representations[kind]);
+      next_field_offset += f.GetDetails().field_width_in_words();
+      descriptors->Append(&f);
+    }
+  }
+  return descriptors;
+}
+
+
+TEST(LayoutDescriptorBasicFast) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+
+  LayoutDescriptor* layout_desc = LayoutDescriptor::FastPointerLayout();
+
+  CHECK(!layout_desc->IsSlowLayout());
+  CHECK(layout_desc->IsFastPointerLayout());
+  CHECK_EQ(kSmiValueSize, layout_desc->capacity());
+
+  for (int i = 0; i < kSmiValueSize + 13; i++) {
+    CHECK_EQ(true, layout_desc->IsTagged(i));
+  }
+  CHECK_EQ(true, layout_desc->IsTagged(-1));
+  CHECK_EQ(true, layout_desc->IsTagged(-12347));
+  CHECK_EQ(true, layout_desc->IsTagged(15635));
+  CHECK(layout_desc->IsFastPointerLayout());
+
+  for (int i = 0; i < kSmiValueSize; i++) {
+    layout_desc = layout_desc->SetTaggedForTesting(i, false);
+    CHECK_EQ(false, layout_desc->IsTagged(i));
+    layout_desc = layout_desc->SetTaggedForTesting(i, true);
+    CHECK_EQ(true, layout_desc->IsTagged(i));
+  }
+  CHECK(layout_desc->IsFastPointerLayout());
+
+  int sequence_length;
+  CHECK_EQ(true, layout_desc->IsTagged(0, std::numeric_limits<int>::max(),
+                                       &sequence_length));
+  CHECK_EQ(std::numeric_limits<int>::max(), sequence_length);
+
+  CHECK_EQ(true, layout_desc->IsTagged(0, 7, &sequence_length));
+  CHECK_EQ(7, sequence_length);
+}
+
+
+TEST(LayoutDescriptorBasicSlow) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::HandleScope scope(CcTest::isolate());
+
+  Handle<LayoutDescriptor> layout_descriptor;
+  const int kPropsCount = kSmiValueSize * 3;
+  TestPropertyKind props[kPropsCount];
+  for (int i = 0; i < kPropsCount; i++) {
+    // All properties tagged.
+    props[i] = PROP_TAGGED;
+  }
+
+  {
+    Handle<DescriptorArray> descriptors =
+        CreateDescriptorArray(isolate, props, kPropsCount);
+
+    Handle<Map> map = Map::Create(isolate, kPropsCount);
+
+    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
+    CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
+    CHECK_EQ(kSmiValueSize, layout_descriptor->capacity());
+    map->InitializeDescriptors(*descriptors, *layout_descriptor);
+    DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+  }
+
+  props[0] = PROP_DOUBLE;
+  props[kPropsCount - 1] = PROP_DOUBLE;
+
+  Handle<DescriptorArray> descriptors =
+      CreateDescriptorArray(isolate, props, kPropsCount);
+
+  {
+    int inobject_properties = kPropsCount - 1;
+    Handle<Map> map = Map::Create(isolate, inobject_properties);
+
+    // Should be fast as the only double property is the first one.
+    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
+    CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
+    CHECK(!layout_descriptor->IsSlowLayout());
+    CHECK(!layout_descriptor->IsFastPointerLayout());
+
+    CHECK_EQ(false, layout_descriptor->IsTagged(0));
+    for (int i = 1; i < kPropsCount; i++) {
+      CHECK_EQ(true, layout_descriptor->IsTagged(i));
+    }
+    map->InitializeDescriptors(*descriptors, *layout_descriptor);
+    DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+  }
+
+  {
+    int inobject_properties = kPropsCount;
+    Handle<Map> map = Map::Create(isolate, inobject_properties);
+
+    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
+    CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
+    CHECK(layout_descriptor->IsSlowLayout());
+    CHECK(!layout_descriptor->IsFastPointerLayout());
+    CHECK(layout_descriptor->capacity() > kSmiValueSize);
+
+    CHECK_EQ(false, layout_descriptor->IsTagged(0));
+    CHECK_EQ(false, layout_descriptor->IsTagged(kPropsCount - 1));
+    for (int i = 1; i < kPropsCount - 1; i++) {
+      CHECK_EQ(true, layout_descriptor->IsTagged(i));
+    }
+
+    map->InitializeDescriptors(*descriptors, *layout_descriptor);
+    DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+
+    // Here we have truly slow layout descriptor, so play with the bits.
+    CHECK_EQ(true, layout_descriptor->IsTagged(-1));
+    CHECK_EQ(true, layout_descriptor->IsTagged(-12347));
+    CHECK_EQ(true, layout_descriptor->IsTagged(15635));
+
+    LayoutDescriptor* layout_desc = *layout_descriptor;
+    // Play with the bits but leave it in consistent state with map at the end.
+    for (int i = 1; i < kPropsCount - 1; i++) {
+      layout_desc = layout_desc->SetTaggedForTesting(i, false);
+      CHECK_EQ(false, layout_desc->IsTagged(i));
+      layout_desc = layout_desc->SetTaggedForTesting(i, true);
+      CHECK_EQ(true, layout_desc->IsTagged(i));
+    }
+    CHECK(layout_desc->IsSlowLayout());
+    CHECK(!layout_desc->IsFastPointerLayout());
+
+    DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+  }
+}
+
+
+static void TestLayoutDescriptorQueries(int layout_descriptor_length,
+                                        int* bit_flip_positions,
+                                        int max_sequence_length) {
+  Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::NewForTesting(
+      CcTest::i_isolate(), layout_descriptor_length);
+  layout_descriptor_length = layout_descriptor->capacity();
+  LayoutDescriptor* layout_desc = *layout_descriptor;
+
+  {
+    // Fill in the layout descriptor.
+    int cur_bit_flip_index = 0;
+    bool tagged = true;
+    for (int i = 0; i < layout_descriptor_length; i++) {
+      if (i == bit_flip_positions[cur_bit_flip_index]) {
+        tagged = !tagged;
+        ++cur_bit_flip_index;
+        CHECK(i < bit_flip_positions[cur_bit_flip_index]);  // check test data
+      }
+      layout_desc = layout_desc->SetTaggedForTesting(i, tagged);
+    }
+  }
+
+  if (layout_desc->IsFastPointerLayout()) {
+    return;
+  }
+
+  {
+    // Check queries.
+    int cur_bit_flip_index = 0;
+    bool tagged = true;
+    for (int i = 0; i < layout_descriptor_length; i++) {
+      if (i == bit_flip_positions[cur_bit_flip_index]) {
+        tagged = !tagged;
+        ++cur_bit_flip_index;
+      }
+      CHECK_EQ(tagged, layout_desc->IsTagged(i));
+
+      int next_bit_flip_position = bit_flip_positions[cur_bit_flip_index];
+      int expected_sequence_length;
+      if (next_bit_flip_position < layout_desc->capacity()) {
+        expected_sequence_length = next_bit_flip_position - i;
+      } else {
+        expected_sequence_length = tagged ? std::numeric_limits<int>::max()
+                                          : (layout_desc->capacity() - i);
+      }
+      expected_sequence_length =
+          Min(expected_sequence_length, max_sequence_length);
+      int sequence_length;
+      CHECK_EQ(tagged,
+               layout_desc->IsTagged(i, max_sequence_length, &sequence_length));
+      CHECK(sequence_length > 0);
+
+      CHECK_EQ(expected_sequence_length, sequence_length);
+    }
+
+    int sequence_length;
+    CHECK_EQ(true,
+             layout_desc->IsTagged(layout_descriptor_length,
+                                   max_sequence_length, &sequence_length));
+    CHECK_EQ(max_sequence_length, sequence_length);
+  }
+}
+
+
+static void TestLayoutDescriptorQueriesFast(int max_sequence_length) {
+  {
+    LayoutDescriptor* layout_desc = LayoutDescriptor::FastPointerLayout();
+    int sequence_length;
+    for (int i = 0; i < kNumberOfBits; i++) {
+      CHECK_EQ(true,
+               layout_desc->IsTagged(i, max_sequence_length, &sequence_length));
+      CHECK(sequence_length > 0);
+      CHECK_EQ(max_sequence_length, sequence_length);
+    }
+  }
+
+  {
+    int bit_flip_positions[] = {1000};
+    TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
+                                max_sequence_length);
+  }
+
+  {
+    int bit_flip_positions[] = {0, 1000};
+    TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
+                                max_sequence_length);
+  }
+
+  {
+    int bit_flip_positions[kNumberOfBits + 1];
+    for (int i = 0; i <= kNumberOfBits; i++) {
+      bit_flip_positions[i] = i;
+    }
+    TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
+                                max_sequence_length);
+  }
+
+  {
+    int bit_flip_positions[] = {3, 7, 8, 10, 15, 21, 30, 1000};
+    TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
+                                max_sequence_length);
+  }
+
+  {
+    int bit_flip_positions[] = {0,  1,  2,  3,  5,  7,  9,
+                                12, 15, 18, 22, 26, 29, 1000};
+    TestLayoutDescriptorQueries(kSmiValueSize, bit_flip_positions,
+                                max_sequence_length);
+  }
+}
+
+
+TEST(LayoutDescriptorQueriesFastLimited7) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+
+  TestLayoutDescriptorQueriesFast(7);
+}
+
+
+TEST(LayoutDescriptorQueriesFastLimited13) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+
+  TestLayoutDescriptorQueriesFast(13);
+}
+
+
+TEST(LayoutDescriptorQueriesFastUnlimited) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+
+  TestLayoutDescriptorQueriesFast(std::numeric_limits<int>::max());
+}
+
+
+static void TestLayoutDescriptorQueriesSlow(int max_sequence_length) {
+  {
+    int bit_flip_positions[] = {10000};
+    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
+                                max_sequence_length);
+  }
+
+  {
+    int bit_flip_positions[] = {0, 10000};
+    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
+                                max_sequence_length);
+  }
+
+  {
+    int bit_flip_positions[kMaxNumberOfDescriptors + 1];
+    for (int i = 0; i < kMaxNumberOfDescriptors; i++) {
+      bit_flip_positions[i] = i;
+    }
+    bit_flip_positions[kMaxNumberOfDescriptors] = 10000;
+    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
+                                max_sequence_length);
+  }
+
+  {
+    int bit_flip_positions[] = {3,  7,  8,  10, 15,  21,   30,
+                                37, 54, 80, 99, 383, 10000};
+    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
+                                max_sequence_length);
+  }
+
+  {
+    int bit_flip_positions[] = {0,   10,  20,  30,  50,  70,  90,
+                                120, 150, 180, 220, 260, 290, 10000};
+    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
+                                max_sequence_length);
+  }
+
+  {
+    int bit_flip_positions[kMaxNumberOfDescriptors + 1];
+    int cur = 0;
+    for (int i = 0; i < kMaxNumberOfDescriptors; i++) {
+      bit_flip_positions[i] = cur;
+      cur = (cur + 1) * 2;
+    }
+    CHECK(cur < 10000);
+    bit_flip_positions[kMaxNumberOfDescriptors] = 10000;
+    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
+                                max_sequence_length);
+  }
+
+  {
+    int bit_flip_positions[kMaxNumberOfDescriptors + 1];
+    int cur = 3;
+    for (int i = 0; i < kMaxNumberOfDescriptors; i++) {
+      bit_flip_positions[i] = cur;
+      cur = (cur + 1) * 2;
+    }
+    CHECK(cur < 10000);
+    bit_flip_positions[kMaxNumberOfDescriptors] = 10000;
+    TestLayoutDescriptorQueries(kMaxNumberOfDescriptors, bit_flip_positions,
+                                max_sequence_length);
+  }
+}
+
+
+TEST(LayoutDescriptorQueriesSlowLimited7) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+
+  TestLayoutDescriptorQueriesSlow(7);
+}
+
+
+TEST(LayoutDescriptorQueriesSlowLimited13) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+
+  TestLayoutDescriptorQueriesSlow(13);
+}
+
+
+TEST(LayoutDescriptorQueriesSlowLimited42) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+
+  TestLayoutDescriptorQueriesSlow(42);
+}
+
+
+TEST(LayoutDescriptorQueriesSlowUnlimited) {
+  CcTest::InitializeVM();
+  v8::HandleScope scope(CcTest::isolate());
+
+  TestLayoutDescriptorQueriesSlow(std::numeric_limits<int>::max());
+}
+
+
+TEST(LayoutDescriptorCreateNewFast) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::HandleScope scope(CcTest::isolate());
+
+  Handle<LayoutDescriptor> layout_descriptor;
+  TestPropertyKind props[] = {
+      PROP_CONSTANT,
+      PROP_TAGGED,  // field #0
+      PROP_CONSTANT,
+      PROP_DOUBLE,  // field #1
+      PROP_CONSTANT,
+      PROP_TAGGED,  // field #2
+      PROP_CONSTANT,
+  };
+  const int kPropsCount = arraysize(props);
+
+  Handle<DescriptorArray> descriptors =
+      CreateDescriptorArray(isolate, props, kPropsCount);
+
+  {
+    Handle<Map> map = Map::Create(isolate, 0);
+    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
+    CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
+    map->InitializeDescriptors(*descriptors, *layout_descriptor);
+    DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+  }
+
+  {
+    Handle<Map> map = Map::Create(isolate, 1);
+    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
+    CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
+    map->InitializeDescriptors(*descriptors, *layout_descriptor);
+    DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+  }
+
+  {
+    Handle<Map> map = Map::Create(isolate, 2);
+    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
+    CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
+    CHECK(!layout_descriptor->IsSlowLayout());
+    CHECK_EQ(true, layout_descriptor->IsTagged(0));
+    CHECK_EQ(false, layout_descriptor->IsTagged(1));
+    CHECK_EQ(true, layout_descriptor->IsTagged(2));
+    CHECK_EQ(true, layout_descriptor->IsTagged(125));
+    map->InitializeDescriptors(*descriptors, *layout_descriptor);
+    DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+  }
+}
+
+
+TEST(LayoutDescriptorCreateNewSlow) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::HandleScope scope(CcTest::isolate());
+
+  Handle<LayoutDescriptor> layout_descriptor;
+  const int kPropsCount = kSmiValueSize * 3;
+  TestPropertyKind props[kPropsCount];
+  for (int i = 0; i < kPropsCount; i++) {
+    props[i] = static_cast<TestPropertyKind>(i % PROP_KIND_NUMBER);
+  }
+
+  Handle<DescriptorArray> descriptors =
+      CreateDescriptorArray(isolate, props, kPropsCount);
+
+  {
+    Handle<Map> map = Map::Create(isolate, 0);
+    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
+    CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
+    map->InitializeDescriptors(*descriptors, *layout_descriptor);
+    DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+  }
+
+  {
+    Handle<Map> map = Map::Create(isolate, 1);
+    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
+    CHECK_EQ(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
+    map->InitializeDescriptors(*descriptors, *layout_descriptor);
+    DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+  }
+
+  {
+    Handle<Map> map = Map::Create(isolate, 2);
+    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
+    CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
+    CHECK(!layout_descriptor->IsSlowLayout());
+    CHECK_EQ(true, layout_descriptor->IsTagged(0));
+    CHECK_EQ(false, layout_descriptor->IsTagged(1));
+    CHECK_EQ(true, layout_descriptor->IsTagged(2));
+    CHECK_EQ(true, layout_descriptor->IsTagged(125));
+    map->InitializeDescriptors(*descriptors, *layout_descriptor);
+    DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+  }
+
+  {
+    int inobject_properties = kPropsCount / 2;
+    Handle<Map> map = Map::Create(isolate, inobject_properties);
+    layout_descriptor = LayoutDescriptor::New(map, descriptors, kPropsCount);
+    CHECK_NE(LayoutDescriptor::FastPointerLayout(), *layout_descriptor);
+    CHECK(layout_descriptor->IsSlowLayout());
+    for (int i = 0; i < inobject_properties; i++) {
+      // PROP_DOUBLE has index 1 among FIELD properties.
+      const bool tagged = (i % (PROP_KIND_NUMBER - 1)) != 1;
+      CHECK_EQ(tagged, layout_descriptor->IsTagged(i));
+    }
+    // Every property after inobject_properties must be tagged.
+    for (int i = inobject_properties; i < kPropsCount; i++) {
+      CHECK_EQ(true, layout_descriptor->IsTagged(i));
+    }
+    map->InitializeDescriptors(*descriptors, *layout_descriptor);
+    DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+
+    // Now test LayoutDescriptor::cast_gc_safe().
+    Handle<LayoutDescriptor> layout_descriptor_copy =
+        LayoutDescriptor::New(map, descriptors, kPropsCount);
+
+    LayoutDescriptor* layout_desc = *layout_descriptor;
+    CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc));
+    CHECK_EQ(layout_desc, LayoutDescriptor::cast_gc_safe(layout_desc));
+    CHECK(layout_descriptor->IsFixedTypedArrayBase());
+    // Now make it look like a forwarding pointer to layout_descriptor_copy.
+    MapWord map_word = layout_desc->map_word();
+    CHECK(!map_word.IsForwardingAddress());
+    layout_desc->set_map_word(
+        MapWord::FromForwardingAddress(*layout_descriptor_copy));
+    CHECK(layout_desc->map_word().IsForwardingAddress());
+    CHECK_EQ(*layout_descriptor_copy,
+             LayoutDescriptor::cast_gc_safe(layout_desc));
+
+    // Restore it back.
+    layout_desc->set_map_word(map_word);
+    CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc));
+  }
+}
+
+
+static Handle<LayoutDescriptor> TestLayoutDescriptorAppend(
+    Isolate* isolate, int inobject_properties, TestPropertyKind* props,
+    int kPropsCount) {
+  Factory* factory = isolate->factory();
+
+  Handle<String> func_name = factory->InternalizeUtf8String("func");
+  Handle<JSFunction> func = factory->NewFunction(func_name);
+
+  Handle<DescriptorArray> descriptors =
+      DescriptorArray::Allocate(isolate, 0, kPropsCount);
+
+  Handle<Map> map = Map::Create(isolate, inobject_properties);
+  map->InitializeDescriptors(*descriptors,
+                             LayoutDescriptor::FastPointerLayout());
+
+  int next_field_offset = 0;
+  for (int i = 0; i < kPropsCount; i++) {
+    EmbeddedVector<char, 64> buffer;
+    SNPrintF(buffer, "prop%d", i);
+    Handle<String> name = factory->InternalizeUtf8String(buffer.start());
+
+    Handle<LayoutDescriptor> layout_descriptor;
+    TestPropertyKind kind = props[i];
+    if (kind == PROP_CONSTANT) {
+      ConstantDescriptor d(name, func, NONE);
+      layout_descriptor = LayoutDescriptor::Append(map, d.GetDetails());
+      descriptors->Append(&d);
+
+    } else {
+      FieldDescriptor f(name, next_field_offset, NONE, representations[kind]);
+      int field_width_in_words = f.GetDetails().field_width_in_words();
+      next_field_offset += field_width_in_words;
+      layout_descriptor = LayoutDescriptor::Append(map, f.GetDetails());
+      descriptors->Append(&f);
+
+      int field_index = f.GetDetails().field_index();
+      bool is_inobject = field_index < map->inobject_properties();
+      for (int bit = 0; bit < field_width_in_words; bit++) {
+        CHECK_EQ(is_inobject && (kind == PROP_DOUBLE),
+                 !layout_descriptor->IsTagged(field_index + bit));
+      }
+      CHECK(layout_descriptor->IsTagged(next_field_offset));
+    }
+    map->InitializeDescriptors(*descriptors, *layout_descriptor);
+  }
+  Handle<LayoutDescriptor> layout_descriptor(map->layout_descriptor(), isolate);
+  DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+  return layout_descriptor;
+}
+
+
+TEST(LayoutDescriptorAppend) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::HandleScope scope(CcTest::isolate());
+
+  Handle<LayoutDescriptor> layout_descriptor;
+  const int kPropsCount = kSmiValueSize * 3;
+  TestPropertyKind props[kPropsCount];
+  for (int i = 0; i < kPropsCount; i++) {
+    props[i] = static_cast<TestPropertyKind>(i % PROP_KIND_NUMBER);
+  }
+
+  layout_descriptor =
+      TestLayoutDescriptorAppend(isolate, 0, props, kPropsCount);
+  CHECK(!layout_descriptor->IsSlowLayout());
+
+  layout_descriptor =
+      TestLayoutDescriptorAppend(isolate, 13, props, kPropsCount);
+  CHECK(!layout_descriptor->IsSlowLayout());
+
+  layout_descriptor =
+      TestLayoutDescriptorAppend(isolate, kSmiValueSize, props, kPropsCount);
+  CHECK(!layout_descriptor->IsSlowLayout());
+
+  layout_descriptor = TestLayoutDescriptorAppend(isolate, kSmiValueSize * 2,
+                                                 props, kPropsCount);
+  CHECK(layout_descriptor->IsSlowLayout());
+
+  layout_descriptor =
+      TestLayoutDescriptorAppend(isolate, kPropsCount, props, kPropsCount);
+  CHECK(layout_descriptor->IsSlowLayout());
+}
+
+
+TEST(LayoutDescriptorAppendAllDoubles) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::HandleScope scope(CcTest::isolate());
+
+  Handle<LayoutDescriptor> layout_descriptor;
+  const int kPropsCount = kSmiValueSize * 3;
+  TestPropertyKind props[kPropsCount];
+  for (int i = 0; i < kPropsCount; i++) {
+    props[i] = PROP_DOUBLE;
+  }
+
+  layout_descriptor =
+      TestLayoutDescriptorAppend(isolate, 0, props, kPropsCount);
+  CHECK(!layout_descriptor->IsSlowLayout());
+
+  layout_descriptor =
+      TestLayoutDescriptorAppend(isolate, 13, props, kPropsCount);
+  CHECK(!layout_descriptor->IsSlowLayout());
+
+  layout_descriptor =
+      TestLayoutDescriptorAppend(isolate, kSmiValueSize, props, kPropsCount);
+  CHECK(!layout_descriptor->IsSlowLayout());
+
+  layout_descriptor = TestLayoutDescriptorAppend(isolate, kSmiValueSize + 1,
+                                                 props, kPropsCount);
+  CHECK(layout_descriptor->IsSlowLayout());
+
+  layout_descriptor = TestLayoutDescriptorAppend(isolate, kSmiValueSize * 2,
+                                                 props, kPropsCount);
+  CHECK(layout_descriptor->IsSlowLayout());
+
+  layout_descriptor =
+      TestLayoutDescriptorAppend(isolate, kPropsCount, props, kPropsCount);
+  CHECK(layout_descriptor->IsSlowLayout());
+
+  {
+    // Ensure layout descriptor switches into slow mode at the right moment.
+    layout_descriptor =
+        TestLayoutDescriptorAppend(isolate, kPropsCount, props, kSmiValueSize);
+    CHECK(!layout_descriptor->IsSlowLayout());
+
+    layout_descriptor = TestLayoutDescriptorAppend(isolate, kPropsCount, props,
+                                                   kSmiValueSize + 1);
+    CHECK(layout_descriptor->IsSlowLayout());
+  }
+}
+
+
+static Handle<LayoutDescriptor> TestLayoutDescriptorAppendIfFastOrUseFull(
+    Isolate* isolate, int inobject_properties,
+    Handle<DescriptorArray> descriptors, int number_of_descriptors) {
+  Handle<Map> map = Map::Create(isolate, inobject_properties);
+
+  Handle<LayoutDescriptor> full_layout_descriptor = LayoutDescriptor::New(
+      map, descriptors, descriptors->number_of_descriptors());
+
+  int nof = 0;
+  bool switched_to_slow_mode = false;
+
+  for (int i = 0; i < number_of_descriptors; i++) {
+    PropertyDetails details = descriptors->GetDetails(i);
+
+    // This method calls LayoutDescriptor::AppendIfFastOrUseFull() internally
+    // and does all the required map-descriptors related book keeping.
+    map = Map::CopyInstallDescriptorsForTesting(map, i, descriptors,
+                                                full_layout_descriptor);
+
+    LayoutDescriptor* layout_desc = map->layout_descriptor();
+
+    if (layout_desc->IsSlowLayout()) {
+      switched_to_slow_mode = true;
+      CHECK_EQ(*full_layout_descriptor, layout_desc);
+    } else {
+      CHECK(!switched_to_slow_mode);
+      if (details.type() == FIELD) {
+        nof++;
+        int field_index = details.field_index();
+        int field_width_in_words = details.field_width_in_words();
+
+        bool is_inobject = field_index < map->inobject_properties();
+        for (int bit = 0; bit < field_width_in_words; bit++) {
+          CHECK_EQ(is_inobject && details.representation().IsDouble(),
+                   !layout_desc->IsTagged(field_index + bit));
+        }
+        CHECK(layout_desc->IsTagged(field_index + field_width_in_words));
+      }
+    }
+    DCHECK(map->layout_descriptor()->IsConsistentWithMap(*map));
+  }
+
+  Handle<LayoutDescriptor> layout_descriptor(map->GetLayoutDescriptor(),
+                                             isolate);
+  DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+  return layout_descriptor;
+}
+
+
+TEST(LayoutDescriptorAppendIfFastOrUseFull) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::HandleScope scope(CcTest::isolate());
+
+  Handle<LayoutDescriptor> layout_descriptor;
+  const int kPropsCount = kSmiValueSize * 3;
+  TestPropertyKind props[kPropsCount];
+  for (int i = 0; i < kPropsCount; i++) {
+    props[i] = static_cast<TestPropertyKind>(i % PROP_KIND_NUMBER);
+  }
+  Handle<DescriptorArray> descriptors =
+      CreateDescriptorArray(isolate, props, kPropsCount);
+
+  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+      isolate, 0, descriptors, kPropsCount);
+  CHECK(!layout_descriptor->IsSlowLayout());
+
+  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+      isolate, 13, descriptors, kPropsCount);
+  CHECK(!layout_descriptor->IsSlowLayout());
+
+  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+      isolate, kSmiValueSize, descriptors, kPropsCount);
+  CHECK(!layout_descriptor->IsSlowLayout());
+
+  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+      isolate, kSmiValueSize * 2, descriptors, kPropsCount);
+  CHECK(layout_descriptor->IsSlowLayout());
+
+  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+      isolate, kPropsCount, descriptors, kPropsCount);
+  CHECK(layout_descriptor->IsSlowLayout());
+}
+
+
+TEST(LayoutDescriptorAppendIfFastOrUseFullAllDoubles) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::HandleScope scope(CcTest::isolate());
+
+  Handle<LayoutDescriptor> layout_descriptor;
+  const int kPropsCount = kSmiValueSize * 3;
+  TestPropertyKind props[kPropsCount];
+  for (int i = 0; i < kPropsCount; i++) {
+    props[i] = PROP_DOUBLE;
+  }
+  Handle<DescriptorArray> descriptors =
+      CreateDescriptorArray(isolate, props, kPropsCount);
+
+  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+      isolate, 0, descriptors, kPropsCount);
+  CHECK(!layout_descriptor->IsSlowLayout());
+
+  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+      isolate, 13, descriptors, kPropsCount);
+  CHECK(!layout_descriptor->IsSlowLayout());
+
+  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+      isolate, kSmiValueSize, descriptors, kPropsCount);
+  CHECK(!layout_descriptor->IsSlowLayout());
+
+  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+      isolate, kSmiValueSize + 1, descriptors, kPropsCount);
+  CHECK(layout_descriptor->IsSlowLayout());
+
+  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+      isolate, kSmiValueSize * 2, descriptors, kPropsCount);
+  CHECK(layout_descriptor->IsSlowLayout());
+
+  layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+      isolate, kPropsCount, descriptors, kPropsCount);
+  CHECK(layout_descriptor->IsSlowLayout());
+
+  {
+    // Ensure layout descriptor switches into slow mode at the right moment.
+    layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+        isolate, kPropsCount, descriptors, kSmiValueSize);
+    CHECK(!layout_descriptor->IsSlowLayout());
+
+    layout_descriptor = TestLayoutDescriptorAppendIfFastOrUseFull(
+        isolate, kPropsCount, descriptors, kSmiValueSize + 1);
+    CHECK(layout_descriptor->IsSlowLayout());
+  }
+}
+
+
+TEST(Regress436816) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* factory = isolate->factory();
+  v8::HandleScope scope(CcTest::isolate());
+
+  const int kPropsCount = kSmiValueSize * 3;
+  TestPropertyKind props[kPropsCount];
+  for (int i = 0; i < kPropsCount; i++) {
+    props[i] = PROP_DOUBLE;
+  }
+  Handle<DescriptorArray> descriptors =
+      CreateDescriptorArray(isolate, props, kPropsCount);
+
+  Handle<Map> map = Map::Create(isolate, kPropsCount);
+  Handle<LayoutDescriptor> layout_descriptor =
+      LayoutDescriptor::New(map, descriptors, kPropsCount);
+  map->InitializeDescriptors(*descriptors, *layout_descriptor);
+
+  Handle<JSObject> object = factory->NewJSObjectFromMap(map, TENURED);
+
+  Address fake_address = reinterpret_cast<Address>(~kHeapObjectTagMask);
+  HeapObject* fake_object = HeapObject::FromAddress(fake_address);
+  CHECK(fake_object->IsHeapObject());
+
+  double boom_value = bit_cast<double>(fake_object);
+  for (int i = 0; i < kPropsCount; i++) {
+    FieldIndex index = FieldIndex::ForDescriptor(*map, i);
+    CHECK(map->IsUnboxedDoubleField(index));
+    object->RawFastDoublePropertyAtPut(index, boom_value);
+  }
+  CHECK(object->HasFastProperties());
+  CHECK(!object->map()->HasFastPointerLayout());
+
+  Handle<Map> normalized_map =
+      Map::Normalize(map, KEEP_INOBJECT_PROPERTIES, "testing");
+  JSObject::MigrateToMap(object, normalized_map);
+  CHECK(!object->HasFastProperties());
+  CHECK(object->map()->HasFastPointerLayout());
+
+  // Trigger GCs and heap verification.
+  CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+}
+
+
+TEST(DoScavenge) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* factory = isolate->factory();
+  v8::HandleScope scope(CcTest::isolate());
+
+  CompileRun(
+      "function A() {"
+      "  this.x = 42.5;"
+      "  this.o = {};"
+      "};"
+      "var o = new A();");
+
+  Handle<String> obj_name = factory->InternalizeUtf8String("o");
+
+  Handle<Object> obj_value =
+      Object::GetProperty(isolate->global_object(), obj_name).ToHandleChecked();
+  CHECK(obj_value->IsJSObject());
+  Handle<JSObject> obj = Handle<JSObject>::cast(obj_value);
+
+  {
+    // Ensure the object is properly set up.
+    Map* map = obj->map();
+    DescriptorArray* descriptors = map->instance_descriptors();
+    CHECK(map->NumberOfOwnDescriptors() == 2);
+    CHECK(descriptors->GetDetails(0).representation().IsDouble());
+    CHECK(descriptors->GetDetails(1).representation().IsHeapObject());
+    FieldIndex field_index = FieldIndex::ForDescriptor(map, 0);
+    CHECK(field_index.is_inobject() && field_index.is_double());
+    CHECK_EQ(FLAG_unbox_double_fields, map->IsUnboxedDoubleField(field_index));
+    CHECK_EQ(42.5, GetDoubleFieldValue(*obj, field_index));
+  }
+  CHECK(isolate->heap()->new_space()->Contains(*obj));
+
+  // Trigger GCs so that the newly allocated object moves to old gen.
+  CcTest::heap()->CollectGarbage(i::NEW_SPACE);  // in survivor space now
+
+  // Create temp object in the new space.
+  Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, NOT_TENURED);
+  CHECK(isolate->heap()->new_space()->Contains(*temp));
+
+  // Construct a double value that looks like a pointer to the new space object
+  // and store it into the obj.
+  Address fake_object = reinterpret_cast<Address>(*temp) + kPointerSize;
+  double boom_value = bit_cast<double>(fake_object);
+
+  FieldIndex field_index = FieldIndex::ForDescriptor(obj->map(), 0);
+  Handle<HeapNumber> boom_number = factory->NewHeapNumber(boom_value, MUTABLE);
+  obj->FastPropertyAtPut(field_index, *boom_number);
+
+  // Now the object moves to old gen and it has a double field that looks like
+  // a pointer to a from semi-space.
+  CcTest::heap()->CollectGarbage(i::NEW_SPACE);  // in old gen now
+
+  CHECK(isolate->heap()->old_pointer_space()->Contains(*obj));
+
+  CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index));
+}
+
+
+static void TestLayoutDescriptorHelper(Isolate* isolate,
+                                       int inobject_properties,
+                                       Handle<DescriptorArray> descriptors,
+                                       int number_of_descriptors) {
+  Handle<Map> map = Map::Create(isolate, inobject_properties);
+
+  Handle<LayoutDescriptor> layout_descriptor = LayoutDescriptor::New(
+      map, descriptors, descriptors->number_of_descriptors());
+  map->InitializeDescriptors(*descriptors, *layout_descriptor);
+  DCHECK(layout_descriptor->IsConsistentWithMap(*map));
+
+  LayoutDescriptorHelper helper(*map);
+  bool all_fields_tagged = true;
+
+  int instance_size = map->instance_size();
+
+  int end_offset = instance_size * 2;
+  int first_non_tagged_field_offset = end_offset;
+  for (int i = 0; i < number_of_descriptors; i++) {
+    PropertyDetails details = descriptors->GetDetails(i);
+    if (details.type() != FIELD) continue;
+    FieldIndex index = FieldIndex::ForDescriptor(*map, i);
+    if (!index.is_inobject()) continue;
+    all_fields_tagged &= !details.representation().IsDouble();
+    bool expected_tagged = !index.is_double();
+    if (!expected_tagged) {
+      first_non_tagged_field_offset =
+          Min(first_non_tagged_field_offset, index.offset());
+    }
+
+    int end_of_region_offset;
+    CHECK_EQ(expected_tagged, helper.IsTagged(index.offset()));
+    CHECK_EQ(expected_tagged, helper.IsTagged(index.offset(), instance_size,
+                                              &end_of_region_offset));
+    CHECK(end_of_region_offset > 0);
+    CHECK(end_of_region_offset % kPointerSize == 0);
+    CHECK(end_of_region_offset <= instance_size);
+
+    for (int offset = index.offset(); offset < end_of_region_offset;
+         offset += kPointerSize) {
+      CHECK_EQ(expected_tagged, helper.IsTagged(index.offset()));
+    }
+    if (end_of_region_offset < instance_size) {
+      CHECK_EQ(!expected_tagged, helper.IsTagged(end_of_region_offset));
+    } else {
+      CHECK_EQ(true, helper.IsTagged(end_of_region_offset));
+    }
+  }
+
+  for (int offset = 0; offset < JSObject::kHeaderSize; offset += kPointerSize) {
+    // Header queries
+    CHECK_EQ(true, helper.IsTagged(offset));
+    int end_of_region_offset;
+    CHECK_EQ(true, helper.IsTagged(offset, end_offset, &end_of_region_offset));
+    CHECK_EQ(first_non_tagged_field_offset, end_of_region_offset);
+
+    // Out of bounds queries
+    CHECK_EQ(true, helper.IsTagged(offset + instance_size));
+  }
+
+  CHECK_EQ(all_fields_tagged, helper.all_fields_tagged());
+}
+
+
+TEST(LayoutDescriptorHelperMixed) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::HandleScope scope(CcTest::isolate());
+
+  Handle<LayoutDescriptor> layout_descriptor;
+  const int kPropsCount = kSmiValueSize * 3;
+  TestPropertyKind props[kPropsCount];
+  for (int i = 0; i < kPropsCount; i++) {
+    props[i] = static_cast<TestPropertyKind>(i % PROP_KIND_NUMBER);
+  }
+  Handle<DescriptorArray> descriptors =
+      CreateDescriptorArray(isolate, props, kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, 0, descriptors, kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, 13, descriptors, kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, kSmiValueSize, descriptors, kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, kSmiValueSize * 2, descriptors,
+                             kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, kPropsCount, descriptors, kPropsCount);
+}
+
+
+TEST(LayoutDescriptorHelperAllTagged) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::HandleScope scope(CcTest::isolate());
+
+  Handle<LayoutDescriptor> layout_descriptor;
+  const int kPropsCount = kSmiValueSize * 3;
+  TestPropertyKind props[kPropsCount];
+  for (int i = 0; i < kPropsCount; i++) {
+    props[i] = PROP_TAGGED;
+  }
+  Handle<DescriptorArray> descriptors =
+      CreateDescriptorArray(isolate, props, kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, 0, descriptors, kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, 13, descriptors, kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, kSmiValueSize, descriptors, kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, kSmiValueSize * 2, descriptors,
+                             kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, kPropsCount, descriptors, kPropsCount);
+}
+
+
+TEST(LayoutDescriptorHelperAllDoubles) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  v8::HandleScope scope(CcTest::isolate());
+
+  Handle<LayoutDescriptor> layout_descriptor;
+  const int kPropsCount = kSmiValueSize * 3;
+  TestPropertyKind props[kPropsCount];
+  for (int i = 0; i < kPropsCount; i++) {
+    props[i] = PROP_DOUBLE;
+  }
+  Handle<DescriptorArray> descriptors =
+      CreateDescriptorArray(isolate, props, kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, 0, descriptors, kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, 13, descriptors, kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, kSmiValueSize, descriptors, kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, kSmiValueSize * 2, descriptors,
+                             kPropsCount);
+
+  TestLayoutDescriptorHelper(isolate, kPropsCount, descriptors, kPropsCount);
+}
+
+
+TEST(StoreBufferScanOnScavenge) {
+  CcTest::InitializeVM();
+  Isolate* isolate = CcTest::i_isolate();
+  Factory* factory = isolate->factory();
+  v8::HandleScope scope(CcTest::isolate());
+
+  CompileRun(
+      "function A() {"
+      "  this.x = 42.5;"
+      "  this.o = {};"
+      "};"
+      "var o = new A();");
+
+  Handle<String> obj_name = factory->InternalizeUtf8String("o");
+
+  Handle<Object> obj_value =
+      Object::GetProperty(isolate->global_object(), obj_name).ToHandleChecked();
+  CHECK(obj_value->IsJSObject());
+  Handle<JSObject> obj = Handle<JSObject>::cast(obj_value);
+
+  {
+    // Ensure the object is properly set up.
+    Map* map = obj->map();
+    DescriptorArray* descriptors = map->instance_descriptors();
+    CHECK(map->NumberOfOwnDescriptors() == 2);
+    CHECK(descriptors->GetDetails(0).representation().IsDouble());
+    CHECK(descriptors->GetDetails(1).representation().IsHeapObject());
+    FieldIndex field_index = FieldIndex::ForDescriptor(map, 0);
+    CHECK(field_index.is_inobject() && field_index.is_double());
+    CHECK_EQ(FLAG_unbox_double_fields, map->IsUnboxedDoubleField(field_index));
+    CHECK_EQ(42.5, GetDoubleFieldValue(*obj, field_index));
+  }
+  CHECK(isolate->heap()->new_space()->Contains(*obj));
+
+  // Trigger GCs so that the newly allocated object moves to old gen.
+  CcTest::heap()->CollectGarbage(i::NEW_SPACE);  // in survivor space now
+  CcTest::heap()->CollectGarbage(i::NEW_SPACE);  // in old gen now
+
+  CHECK(isolate->heap()->old_pointer_space()->Contains(*obj));
+
+  // Create temp object in the new space.
+  Handle<JSArray> temp = factory->NewJSArray(FAST_ELEMENTS, NOT_TENURED);
+  CHECK(isolate->heap()->new_space()->Contains(*temp));
+
+  // Construct a double value that looks like a pointer to the new space object
+  // and store it into the obj.
+  Address fake_object = reinterpret_cast<Address>(*temp) + kPointerSize;
+  double boom_value = bit_cast<double>(fake_object);
+
+  FieldIndex field_index = FieldIndex::ForDescriptor(obj->map(), 0);
+  Handle<HeapNumber> boom_number = factory->NewHeapNumber(boom_value, MUTABLE);
+  obj->FastPropertyAtPut(field_index, *boom_number);
+
+  // Enforce scan on scavenge for the obj's page.
+  MemoryChunk* chunk = MemoryChunk::FromAddress(obj->address());
+  chunk->set_scan_on_scavenge(true);
+
+  // Trigger GCs and force evacuation. Should not crash there.
+  CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+
+  CHECK_EQ(boom_value, GetDoubleFieldValue(*obj, field_index));
+}
+
+#endif
diff --git a/test/cctest/test-utils.cc b/test/cctest/test-utils.cc
index 9ea8b2b..05a12f5 100644
--- a/test/cctest/test-utils.cc
+++ b/test/cctest/test-utils.cc
@@ -76,6 +76,47 @@
 }
 
 
+TEST(BitSetComputer) {
+  typedef BitSetComputer<bool, 1, kSmiValueSize, uint32_t> BoolComputer;
+  CHECK_EQ(0, BoolComputer::word_count(0));
+  CHECK_EQ(1, BoolComputer::word_count(8));
+  CHECK_EQ(2, BoolComputer::word_count(50));
+  CHECK_EQ(0, BoolComputer::index(0, 8));
+  CHECK_EQ(100, BoolComputer::index(100, 8));
+  CHECK_EQ(1, BoolComputer::index(0, 40));
+  uint32_t data = 0;
+  data = BoolComputer::encode(data, 1, true);
+  data = BoolComputer::encode(data, 4, true);
+  CHECK_EQ(true, BoolComputer::decode(data, 1));
+  CHECK_EQ(true, BoolComputer::decode(data, 4));
+  CHECK_EQ(false, BoolComputer::decode(data, 0));
+  CHECK_EQ(false, BoolComputer::decode(data, 2));
+  CHECK_EQ(false, BoolComputer::decode(data, 3));
+
+  // Lets store 2 bits per item with 3000 items and verify the values are
+  // correct.
+  typedef BitSetComputer<unsigned char, 2, 8, unsigned char> TwoBits;
+  const int words = 750;
+  CHECK_EQ(words, TwoBits::word_count(3000));
+  const int offset = 10;
+  Vector<unsigned char> buffer = Vector<unsigned char>::New(offset + words);
+  memset(buffer.start(), 0, sizeof(unsigned char) * buffer.length());
+  for (int i = 0; i < words; i++) {
+    const int index = TwoBits::index(offset, i);
+    unsigned char data = buffer[index];
+    data = TwoBits::encode(data, i, i % 4);
+    buffer[index] = data;
+  }
+
+  for (int i = 0; i < words; i++) {
+    const int index = TwoBits::index(offset, i);
+    unsigned char data = buffer[index];
+    CHECK_EQ(i % 4, TwoBits::decode(data, i));
+  }
+  buffer.Dispose();
+}
+
+
 TEST(SNPrintF) {
   // Make sure that strings that are truncated because of too small
   // buffers are zero-terminated anyway.
@@ -222,8 +263,6 @@
 }
 
 
-// TODO(svenpanne) Unconditionally test this when our infrastructure is fixed.
-#if !V8_OS_NACL
 TEST(CPlusPlus11Features) {
   struct S {
     bool x;
@@ -256,4 +295,3 @@
     j += 11;
   }
 }
-#endif
diff --git a/test/cctest/test-weakmaps.cc b/test/cctest/test-weakmaps.cc
index bb412a8..6c19cb8 100644
--- a/test/cctest/test-weakmaps.cc
+++ b/test/cctest/test-weakmaps.cc
@@ -97,19 +97,20 @@
   }
   CHECK(!global_handles->IsWeak(key.location()));
 
-  // Put entry into weak map.
+  // Put two chained entries into weak map.
   {
     HandleScope scope(isolate);
-    PutIntoWeakMap(weakmap,
-                   Handle<JSObject>(JSObject::cast(*key)),
-                   Handle<Smi>(Smi::FromInt(23), isolate));
+    Handle<Map> map = factory->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+    Handle<JSObject> object = factory->NewJSObjectFromMap(map);
+    PutIntoWeakMap(weakmap, Handle<JSObject>(JSObject::cast(*key)), object);
+    PutIntoWeakMap(weakmap, object, Handle<Smi>(Smi::FromInt(23), isolate));
   }
-  CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
+  CHECK_EQ(2, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
 
   // Force a full GC.
   heap->CollectAllGarbage(false);
   CHECK_EQ(0, NumberOfWeakCalls);
-  CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
+  CHECK_EQ(2, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
   CHECK_EQ(
       0, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements());
 
@@ -128,14 +129,14 @@
   // weak references whereas the second one will also clear weak maps.
   heap->CollectAllGarbage(false);
   CHECK_EQ(1, NumberOfWeakCalls);
-  CHECK_EQ(1, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
+  CHECK_EQ(2, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
   CHECK_EQ(
       0, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements());
   heap->CollectAllGarbage(false);
   CHECK_EQ(1, NumberOfWeakCalls);
   CHECK_EQ(0, ObjectHashTable::cast(weakmap->table())->NumberOfElements());
-  CHECK_EQ(
-      1, ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements());
+  CHECK_EQ(2,
+           ObjectHashTable::cast(weakmap->table())->NumberOfDeletedElements());
 }
 
 
diff --git a/test/cctest/trace-extension.cc b/test/cctest/trace-extension.cc
index 8f390e4..0a1ff87 100644
--- a/test/cctest/trace-extension.cc
+++ b/test/cctest/trace-extension.cc
@@ -91,7 +91,8 @@
   // sp is only used to define stack high bound
   regs.sp =
       reinterpret_cast<Address>(trace_env.sample) - 10240;
-  trace_env.sample->Init(CcTest::i_isolate(), regs);
+  trace_env.sample->Init(CcTest::i_isolate(), regs,
+                         TickSample::kSkipCEntryFrame);
 }
 
 
diff --git a/test/cctest/types-fuzz.h b/test/cctest/types-fuzz.h
new file mode 100644
index 0000000..4eac64c
--- /dev/null
+++ b/test/cctest/types-fuzz.h
@@ -0,0 +1,311 @@
+// Copyright 2014 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_TEST_CCTEST_TYPES_H_
+#define V8_TEST_CCTEST_TYPES_H_
+
+#include "src/v8.h"
+
+namespace v8 {
+namespace internal {
+
+
+template<class Type, class TypeHandle, class Region>
+class Types {
+ public:
+  Types(Region* region, Isolate* isolate)
+      : region_(region), rng_(isolate->random_number_generator()) {
+    #define DECLARE_TYPE(name, value) \
+      name = Type::name(region);      \
+      types.push_back(name);
+    PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
+    #undef DECLARE_TYPE
+
+    object_map = isolate->factory()->NewMap(
+        JS_OBJECT_TYPE, JSObject::kHeaderSize);
+    array_map = isolate->factory()->NewMap(
+        JS_ARRAY_TYPE, JSArray::kSize);
+    number_map = isolate->factory()->NewMap(
+        HEAP_NUMBER_TYPE, HeapNumber::kSize);
+    uninitialized_map = isolate->factory()->uninitialized_map();
+    ObjectClass = Type::Class(object_map, region);
+    ArrayClass = Type::Class(array_map, region);
+    NumberClass = Type::Class(number_map, region);
+    UninitializedClass = Type::Class(uninitialized_map, region);
+
+    maps.push_back(object_map);
+    maps.push_back(array_map);
+    maps.push_back(uninitialized_map);
+    for (MapVector::iterator it = maps.begin(); it != maps.end(); ++it) {
+      types.push_back(Type::Class(*it, region));
+    }
+
+    smi = handle(Smi::FromInt(666), isolate);
+    signed32 = isolate->factory()->NewHeapNumber(0x40000000);
+    object1 = isolate->factory()->NewJSObjectFromMap(object_map);
+    object2 = isolate->factory()->NewJSObjectFromMap(object_map);
+    array = isolate->factory()->NewJSArray(20);
+    uninitialized = isolate->factory()->uninitialized_value();
+    SmiConstant = Type::Constant(smi, region);
+    Signed32Constant = Type::Constant(signed32, region);
+    ObjectConstant1 = Type::Constant(object1, region);
+    ObjectConstant2 = Type::Constant(object2, region);
+    ArrayConstant = Type::Constant(array, region);
+    UninitializedConstant = Type::Constant(uninitialized, region);
+
+    values.push_back(smi);
+    values.push_back(signed32);
+    values.push_back(object1);
+    values.push_back(object2);
+    values.push_back(array);
+    values.push_back(uninitialized);
+    for (ValueVector::iterator it = values.begin(); it != values.end(); ++it) {
+      types.push_back(Type::Constant(*it, region));
+    }
+
+    integers.push_back(isolate->factory()->NewNumber(-V8_INFINITY));
+    integers.push_back(isolate->factory()->NewNumber(+V8_INFINITY));
+    integers.push_back(isolate->factory()->NewNumber(-rng_->NextInt(10)));
+    integers.push_back(isolate->factory()->NewNumber(+rng_->NextInt(10)));
+    for (int i = 0; i < 10; ++i) {
+      double x = rng_->NextInt();
+      integers.push_back(isolate->factory()->NewNumber(x));
+      x *= rng_->NextInt();
+      if (!IsMinusZero(x)) integers.push_back(isolate->factory()->NewNumber(x));
+    }
+
+    Integer = Type::Range(isolate->factory()->NewNumber(-V8_INFINITY),
+                          isolate->factory()->NewNumber(+V8_INFINITY), region);
+
+    NumberArray = Type::Array(Number, region);
+    StringArray = Type::Array(String, region);
+    AnyArray = Type::Array(Any, region);
+
+    SignedFunction1 = Type::Function(SignedSmall, SignedSmall, region);
+    NumberFunction1 = Type::Function(Number, Number, region);
+    NumberFunction2 = Type::Function(Number, Number, Number, region);
+    MethodFunction = Type::Function(String, Object, 0, region);
+
+    for (int i = 0; i < 30; ++i) {
+      types.push_back(Fuzz());
+    }
+  }
+
+  Handle<i::Map> object_map;
+  Handle<i::Map> array_map;
+  Handle<i::Map> number_map;
+  Handle<i::Map> uninitialized_map;
+
+  Handle<i::Smi> smi;
+  Handle<i::HeapNumber> signed32;
+  Handle<i::JSObject> object1;
+  Handle<i::JSObject> object2;
+  Handle<i::JSArray> array;
+  Handle<i::Oddball> uninitialized;
+
+  #define DECLARE_TYPE(name, value) TypeHandle name;
+  PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
+  #undef DECLARE_TYPE
+
+  TypeHandle ObjectClass;
+  TypeHandle ArrayClass;
+  TypeHandle NumberClass;
+  TypeHandle UninitializedClass;
+
+  TypeHandle SmiConstant;
+  TypeHandle Signed32Constant;
+  TypeHandle ObjectConstant1;
+  TypeHandle ObjectConstant2;
+  TypeHandle ArrayConstant;
+  TypeHandle UninitializedConstant;
+
+  TypeHandle Integer;
+
+  TypeHandle NumberArray;
+  TypeHandle StringArray;
+  TypeHandle AnyArray;
+
+  TypeHandle SignedFunction1;
+  TypeHandle NumberFunction1;
+  TypeHandle NumberFunction2;
+  TypeHandle MethodFunction;
+
+  typedef std::vector<TypeHandle> TypeVector;
+  typedef std::vector<Handle<i::Map> > MapVector;
+  typedef std::vector<Handle<i::Object> > ValueVector;
+
+  TypeVector types;
+  MapVector maps;
+  ValueVector values;
+  ValueVector integers;  // "Integer" values used for range limits.
+
+  TypeHandle Of(Handle<i::Object> value) {
+    return Type::Of(value, region_);
+  }
+
+  TypeHandle NowOf(Handle<i::Object> value) {
+    return Type::NowOf(value, region_);
+  }
+
+  TypeHandle Class(Handle<i::Map> map) {
+    return Type::Class(map, region_);
+  }
+
+  TypeHandle Constant(Handle<i::Object> value) {
+    return Type::Constant(value, region_);
+  }
+
+  TypeHandle Range(Handle<i::Object> min, Handle<i::Object> max) {
+    return Type::Range(min, max, region_);
+  }
+
+  TypeHandle Context(TypeHandle outer) {
+    return Type::Context(outer, region_);
+  }
+
+  TypeHandle Array1(TypeHandle element) {
+    return Type::Array(element, region_);
+  }
+
+  TypeHandle Function0(TypeHandle result, TypeHandle receiver) {
+    return Type::Function(result, receiver, 0, region_);
+  }
+
+  TypeHandle Function1(TypeHandle result, TypeHandle receiver, TypeHandle arg) {
+    TypeHandle type = Type::Function(result, receiver, 1, region_);
+    type->AsFunction()->InitParameter(0, arg);
+    return type;
+  }
+
+  TypeHandle Function2(TypeHandle result, TypeHandle arg1, TypeHandle arg2) {
+    return Type::Function(result, arg1, arg2, region_);
+  }
+
+  TypeHandle Union(TypeHandle t1, TypeHandle t2) {
+    return Type::Union(t1, t2, region_);
+  }
+  TypeHandle Intersect(TypeHandle t1, TypeHandle t2) {
+    return Type::Intersect(t1, t2, region_);
+  }
+
+  template<class Type2, class TypeHandle2>
+  TypeHandle Convert(TypeHandle2 t) {
+    return Type::template Convert<Type2>(t, region_);
+  }
+
+  TypeHandle Random() {
+    return types[rng_->NextInt(static_cast<int>(types.size()))];
+  }
+
+  TypeHandle Fuzz(int depth = 4) {
+    switch (rng_->NextInt(depth == 0 ? 3 : 20)) {
+      case 0: {  // bitset
+        #define COUNT_BITSET_TYPES(type, value) + 1
+        int n = 0 PROPER_BITSET_TYPE_LIST(COUNT_BITSET_TYPES);
+        #undef COUNT_BITSET_TYPES
+        // Pick a bunch of named bitsets and return their intersection.
+        TypeHandle result = Type::Any(region_);
+        for (int i = 0, m = 1 + rng_->NextInt(3); i < m; ++i) {
+          int j = rng_->NextInt(n);
+          #define PICK_BITSET_TYPE(type, value) \
+            if (j-- == 0) { \
+              TypeHandle tmp = Type::Intersect( \
+                  result, Type::type(region_), region_); \
+              if (tmp->Is(Type::None()) && i != 0) { \
+                break; \
+              } else { \
+                result = tmp; \
+                continue; \
+              } \
+            }
+          PROPER_BITSET_TYPE_LIST(PICK_BITSET_TYPE)
+          #undef PICK_BITSET_TYPE
+        }
+        return result;
+      }
+      case 1: {  // class
+        int i = rng_->NextInt(static_cast<int>(maps.size()));
+        return Type::Class(maps[i], region_);
+      }
+      case 2: {  // constant
+        int i = rng_->NextInt(static_cast<int>(values.size()));
+        return Type::Constant(values[i], region_);
+      }
+      case 3: {  // range
+        int i = rng_->NextInt(static_cast<int>(integers.size()));
+        int j = rng_->NextInt(static_cast<int>(integers.size()));
+        i::Handle<i::Object> min = integers[i];
+        i::Handle<i::Object> max = integers[j];
+        if (min->Number() > max->Number()) std::swap(min, max);
+        return Type::Range(min, max, region_);
+      }
+      case 4: {  // context
+        int depth = rng_->NextInt(3);
+        TypeHandle type = Type::Internal(region_);
+        for (int i = 0; i < depth; ++i) type = Type::Context(type, region_);
+        return type;
+      }
+      case 5: {  // array
+        TypeHandle element = Fuzz(depth / 2);
+        return Type::Array(element, region_);
+      }
+      case 6:
+      case 7: {  // function
+        TypeHandle result = Fuzz(depth / 2);
+        TypeHandle receiver = Fuzz(depth / 2);
+        int arity = rng_->NextInt(3);
+        TypeHandle type = Type::Function(result, receiver, arity, region_);
+        for (int i = 0; i < type->AsFunction()->Arity(); ++i) {
+          TypeHandle parameter = Fuzz(depth / 2);
+          type->AsFunction()->InitParameter(i, parameter);
+        }
+        return type;
+      }
+      default: {  // union
+        int n = rng_->NextInt(10);
+        TypeHandle type = None;
+        for (int i = 0; i < n; ++i) {
+          TypeHandle operand = Fuzz(depth - 1);
+          type = Type::Union(type, operand, region_);
+        }
+        return type;
+      }
+    }
+    UNREACHABLE();
+  }
+
+  Region* region() { return region_; }
+
+ private:
+  Region* region_;
+  v8::base::RandomNumberGenerator* rng_;
+};
+
+
+} }  // namespace v8::internal
+
+#endif
diff --git a/test/compiler-unittests/compiler-unittests.status b/test/compiler-unittests/compiler-unittests.status
deleted file mode 100644
index d439913..0000000
--- a/test/compiler-unittests/compiler-unittests.status
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright 2014 the V8 project authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-[
-]
diff --git a/test/fuzz-natives/base.js b/test/fuzz-natives/base.js
deleted file mode 100644
index d1f721d..0000000
--- a/test/fuzz-natives/base.js
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --allow-natives-syntax
-
-// TODO(jkummerow): There are many ways to improve these tests, e.g.:
-// - more variance in randomized inputs
-// - better time complexity management
-// - better code readability and documentation of intentions.
-
-var RUN_WITH_ALL_ARGUMENT_ENTRIES = false;
-var kOnManyArgumentsRemove = 5;
-
-function makeArguments() {
-  var result = [ ];
-  result.push(17);
-  result.push(-31);
-  result.push(new Array(100));
-  var a = %NormalizeElements([]);
-  a.length = 100003;
-  result.push(a);
-  result.push(Number.MIN_VALUE);
-  result.push("whoops");
-  result.push("x");
-  result.push({"x": 1, "y": 2});
-  var slowCaseObj = {"a": 3, "b": 4, "c": 5};
-  delete slowCaseObj.c;
-  result.push(slowCaseObj);
-  result.push(function () { return 8; });
-  return result;
-}
-
-var kArgObjects = makeArguments().length;
-
-function makeFunction(name, argc) {
-  var args = [];
-  for (var i = 0; i < argc; i++)
-    args.push("x" + i);
-  var argsStr = args.join(", ");
-  return new Function(argsStr,
-                      "return %" + name + "(" + argsStr + ");");
-}
-
-function testArgumentCount(name, argc) {
-  for (var i = 0; i < 10; i++) {
-    var func = null;
-    try {
-      func = makeFunction(name, i);
-    } catch (e) {
-      if (e != "SyntaxError: Illegal access") throw e;
-    }
-    if (func === null && i == argc) {
-      throw "unexpected exception";
-    }
-    var args = [ ];
-    for (var j = 0; j < i; j++)
-      args.push(0);
-    try {
-      func.apply(void 0, args);
-    } catch (e) {
-      // we don't care what happens as long as we don't crash
-    }
-  }
-}
-
-function testArgumentTypes(name, argc) {
-  var type = 0;
-  var hasMore = true;
-  var func = makeFunction(name, argc);
-  while (hasMore) {
-    var argPool = makeArguments();
-    // When we have 5 or more arguments we lower the amount of tests cases
-    // by randomly removing kOnManyArgumentsRemove entries
-    var numArguments = RUN_WITH_ALL_ARGUMENT_ENTRIES ?
-      kArgObjects : kArgObjects - kOnManyArgumentsRemove;
-    if (kArgObjects >= 5 && !RUN_WITH_ALL_ARGUMENT_ENTRIES) {
-      for (var i = 0; i < kOnManyArgumentsRemove; i++) {
-        var rand = Math.floor(Math.random() * (kArgObjects - i));
-        argPool.splice(rand, 1);
-      }
-    }
-    var current = type;
-    hasMore = false;
-    var argList = [ ];
-    for (var i = 0; i < argc; i++) {
-      var index = current % numArguments;
-      current = (current / numArguments) << 0;
-      if (index != (numArguments - 1))
-        hasMore = true;
-      argList.push(argPool[index]);
-    }
-    try {
-      func.apply(void 0, argList);
-    } catch (e) {
-      // we don't care what happens as long as we don't crash
-    }
-    type++;
-  }
-}
-
-testArgumentCount(NAME, ARGC);
-testArgumentTypes(NAME, ARGC);
diff --git a/test/fuzz-natives/fuzz-natives.status b/test/fuzz-natives/fuzz-natives.status
deleted file mode 100644
index c81188a..0000000
--- a/test/fuzz-natives/fuzz-natives.status
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2014 the V8 project authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-[
-[ALWAYS, {
-  # These are designed to crash:
-  "Abort": [SKIP],
-  "AbortJS": [SKIP],
-  "SystemBreak": [SKIP],
-  "_DebugBreakInOptimizedCode": [SKIP],
-
-  # varargs.
-  "Call": [SKIP],
-  "_CallFunction": [SKIP],
-
-  # Implemented in the parser, not callable.
-  "IS_VAR": [SKIP],
-
-  # Compile-time ASSERTs.
-  "_DateField": [SKIP],
-  "_GetFromCache": [SKIP],
-
-  # Riddled with ASSERTs.
-  "CompileForOnStackReplacement": [SKIP],
-
-  # Too slow for fuzzing.
-  "SetAllocationTimeout": [SKIP],
-
-  # TODO(jkummerow): Fix these and un-blacklist them!
-  "CreateDateTimeFormat": [SKIP],
-  "CreateNumberFormat": [SKIP],
-
-  # TODO(danno): Fix these internal function that are only callable form stubs
-  # and un-blacklist them!
-  "CompileLazy": [SKIP],
-  "NotifyDeoptimized": [SKIP],
-  "NotifyStubFailure": [SKIP],
-  "NewSloppyArguments": [SKIP],
-  "NewStrictArguments": [SKIP],
-  "ArrayConstructor": [SKIP],
-  "InternalArrayConstructor": [SKIP],
-  "FinalizeInstanceSize": [SKIP],
-  "PromoteScheduledException": [SKIP],
-  "NewFunctionContext": [SKIP],
-  "PushWithContext": [SKIP],
-  "PushCatchContext": [SKIP],
-  "PushModuleContext": [SKIP],
-  "LoadLookupSlot": [SKIP],
-  "LoadLookupSlotNoReferenceError": [SKIP],
-  "ResolvePossiblyDirectEval": [SKIP],
-  "ForInInit": [SKIP],
-  "ForInNext": [SKIP],
-
-  # TODO(jkummerow): Figure out what to do about inlined functions.
-  "_GeneratorNext": [SKIP],
-  "_GeneratorThrow": [SKIP],
-  "_GetCachedArrayIndex": [SKIP],
-  "_HasCachedArrayIndex": [SKIP],
-  "_IsStringWrapperSafeForDefaultValueOf": [SKIP],
-  "_OneByteSeqStringSetChar": [SKIP],
-  "_RegExpConstructResult": [SKIP],
-  "_TwoByteSeqStringSetChar": [SKIP],
-
-  # These are slow.
-  "DebugEvaluate": [PASS, SLOW],
-  "DebugReferencedBy": [PASS, SLOW],
-  "SetAccessorProperty": [PASS, SLOW],
-  "SetScopeVariableValue": [PASS, SLOW],
-}]  # ALWAYS
-]
diff --git a/test/fuzz-natives/testcfg.py b/test/fuzz-natives/testcfg.py
deleted file mode 100644
index 5e00b40..0000000
--- a/test/fuzz-natives/testcfg.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2014 the V8 project authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from testrunner.local import commands
-from testrunner.local import testsuite
-from testrunner.local import utils
-from testrunner.objects import testcase
-
-class FuzzNativesTestSuite(testsuite.TestSuite):
-
-  def __init__(self, name, root):
-    super(FuzzNativesTestSuite, self).__init__(name, root)
-
-  def ListTests(self, context):
-    shell = os.path.abspath(os.path.join(context.shell_dir, self.shell()))
-    if utils.IsWindows():
-      shell += ".exe"
-    output = commands.Execute(
-        context.command_prefix +
-        [shell, "--allow-natives-syntax", "-e",
-         "try { var natives = %ListNatives();"
-         "  for (var n in natives) { print(natives[n]); }"
-         "} catch(e) {}"] +
-        context.extra_flags)
-    if output.exit_code != 0:
-      print output.stdout
-      print output.stderr
-      assert False, "Failed to get natives list."
-    tests = []
-    for line in output.stdout.strip().split():
-      try:
-        (name, argc) = line.split(",")
-        flags = ["--allow-natives-syntax",
-                 "-e", "var NAME = '%s', ARGC = %s;" % (name, argc)]
-        test = testcase.TestCase(self, name, flags)
-        tests.append(test)
-      except:
-        # Work-around: If parsing didn't work, it might have been due to output
-        # caused by other d8 flags.
-        pass
-    return tests
-
-  def GetFlagsForTestCase(self, testcase, context):
-    name = testcase.path
-    basefile = os.path.join(self.root, "base.js")
-    return testcase.flags + [basefile] + context.mode_flags
-
-def GetSuite(name, root):
-  return FuzzNativesTestSuite(name, root)
diff --git a/test/heap-unittests/heap-unittests.status b/test/heap-unittests/heap-unittests.status
deleted file mode 100644
index d439913..0000000
--- a/test/heap-unittests/heap-unittests.status
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright 2014 the V8 project authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-[
-]
diff --git a/test/intl/general/smp-identifier.js b/test/intl/general/smp-identifier.js
new file mode 100644
index 0000000..8a8d2e6
--- /dev/null
+++ b/test/intl/general/smp-identifier.js
@@ -0,0 +1,43 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function toSurrogatePair(c) {
+  return String.fromCharCode(((c - 0x10000) >>> 10) & 0x3FF | 0xD800) +
+         String.fromCharCode(c & 0x3FF | 0xDC00);
+}
+
+function testIdStart(c, is_id_start) {
+  var source = "var " + toSurrogatePair(c);
+  print(source);
+  if (is_id_start) {
+    assertDoesNotThrow(source);
+  } else {
+    assertThrows(source);
+  }
+}
+
+function testIdPart(c, is_id_start) {
+  var source = "var v" + toSurrogatePair(c);
+  print(source);
+  if (is_id_start) {
+    assertDoesNotThrow(source);
+  } else {
+    assertThrows(source);
+  }
+}
+
+[0x10403, 0x1043C, 0x16F9C, 0x10048, 0x1014D].forEach(function(c) {
+  testIdStart(c, true);
+  testIdPart(c, true);
+});
+
+[0x101FD, 0x11002, 0x104A9].forEach(function(c) {
+  testIdStart(c, false);
+  testIdPart(c, true);
+});
+
+[0x10111, 0x1F4A9].forEach(function(c) {
+  testIdStart(c, false);
+  testIdPart(c, false);
+});
diff --git a/test/js-perf-test/Classes/default-constructor.js b/test/js-perf-test/Classes/default-constructor.js
new file mode 100644
index 0000000..49dcaa6
--- /dev/null
+++ b/test/js-perf-test/Classes/default-constructor.js
@@ -0,0 +1,33 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+'use strict';
+
+var DefaultConstructorBenchmark = new BenchmarkSuite('DefaultConstructor',
+    [100], [
+      new Benchmark('NoSuperClass', false, false, 0, NoSuperClass),
+      new Benchmark('WithSuperClass', false, false, 0, WithSuperClass),
+      new Benchmark('WithSuperClassArguments', false, false, 0,
+                    WithSuperClassArguments),
+    ]);
+
+
+class BaseClass {}
+
+
+class DerivedClass extends BaseClass {}
+
+
+function NoSuperClass() {
+  return new BaseClass();
+}
+
+
+function WithSuperClass() {
+  return new DerivedClass();
+}
+
+
+function WithSuperClassArguments() {
+  return new DerivedClass(0, 1, 2, 3, 4);
+}
diff --git a/test/js-perf-test/Classes/run.js b/test/js-perf-test/Classes/run.js
new file mode 100644
index 0000000..5d48b32
--- /dev/null
+++ b/test/js-perf-test/Classes/run.js
@@ -0,0 +1,28 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+load('../base.js');
+load('super.js');
+load('default-constructor.js');
+
+
+var success = true;
+
+function PrintResult(name, result) {
+  print(name + '-Classes(Score): ' + result);
+}
+
+
+function PrintError(name, error) {
+  PrintResult(name, error);
+  success = false;
+}
+
+
+BenchmarkSuite.config.doWarmup = undefined;
+BenchmarkSuite.config.doDeterministic = undefined;
+
+BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
+                           NotifyError: PrintError });
diff --git a/test/js-perf-test/Classes/super.js b/test/js-perf-test/Classes/super.js
new file mode 100644
index 0000000..a9ec766
--- /dev/null
+++ b/test/js-perf-test/Classes/super.js
@@ -0,0 +1,59 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+'use strict';
+
+var SuperBenchmark = new BenchmarkSuite('Super', [100], [
+     new Benchmark('SuperMethodCall', false, false, 0, SuperMethodCall),
+     new Benchmark('SuperGetterCall', false, false, 0, SuperGetterCall),
+     new Benchmark('SuperSetterCall', false, false, 0, SuperSetterCall),
+]);
+
+
+function Base() { }
+Base.prototype = {
+  constructor: Base,
+  get x() {
+    return this._x++;
+  },
+  set x(v) {
+    this._x += v;
+    return this._x;
+  }
+}
+
+Base.prototype.f = function() {
+  return this._x++;
+}.toMethod(Base.prototype);
+
+function Derived() {
+  this._x = 1;
+}
+Derived.prototype = Object.create(Base.prototype);
+Object.setPrototypeOf(Derived, Base);
+
+Derived.prototype.SuperCall = function() {
+  return super.f();
+}.toMethod(Derived.prototype);
+
+Derived.prototype.GetterCall = function() {
+  return super.x;
+}.toMethod(Derived.prototype);
+
+Derived.prototype.SetterCall = function() {
+  return super.x = 5;
+}.toMethod(Derived.prototype);
+
+var derived = new Derived();
+
+function SuperMethodCall() {
+  return derived.SuperCall();
+}
+
+function SuperGetterCall() {
+  return derived.GetterCall();
+}
+
+function SuperSetterCall() {
+  return derived.SetterCall();
+}
diff --git a/test/js-perf-test/Collections/common.js b/test/js-perf-test/Collections/common.js
new file mode 100644
index 0000000..3ea3933
--- /dev/null
+++ b/test/js-perf-test/Collections/common.js
@@ -0,0 +1,31 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+var N = 10;
+var keys;
+
+
+function SetupSmiKeys() {
+  keys = new Array(N * 2);
+  for (var i = 0; i < N * 2; i++) {
+    keys[i] = i;
+  }
+}
+
+
+function SetupStringKeys() {
+  keys = new Array(N * 2);
+  for (var i = 0; i < N * 2; i++) {
+    keys[i] = 's' + i;
+  }
+}
+
+
+function SetupObjectKeys() {
+  keys = new Array(N * 2);
+  for (var i = 0; i < N * 2; i++) {
+    keys[i] = {};
+  }
+}
diff --git a/test/js-perf-test/Collections/map.js b/test/js-perf-test/Collections/map.js
new file mode 100644
index 0000000..4f55798
--- /dev/null
+++ b/test/js-perf-test/Collections/map.js
@@ -0,0 +1,217 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+var MapSmiBenchmark = new BenchmarkSuite('Map-Smi', [1000], [
+  new Benchmark('Set', false, false, 0, MapSetSmi, MapSetupSmiBase, MapTearDown),
+  new Benchmark('Has', false, false, 0, MapHasSmi, MapSetupSmi, MapTearDown),
+  new Benchmark('Get', false, false, 0, MapGetSmi, MapSetupSmi, MapTearDown),
+  new Benchmark('Delete', false, false, 0, MapDeleteSmi, MapSetupSmi, MapTearDown),
+]);
+
+
+var MapStringBenchmark = new BenchmarkSuite('Map-String', [1000], [
+  new Benchmark('Set', false, false, 0, MapSetString, MapSetupStringBase, MapTearDown),
+  new Benchmark('Has', false, false, 0, MapHasString, MapSetupString, MapTearDown),
+  new Benchmark('Get', false, false, 0, MapGetString, MapSetupString, MapTearDown),
+  new Benchmark('Delete', false, false, 0, MapDeleteString, MapSetupString, MapTearDown),
+]);
+
+
+var MapObjectBenchmark = new BenchmarkSuite('Map-Object', [1000], [
+  new Benchmark('Set', false, false, 0, MapSetObject, MapSetupObjectBase, MapTearDown),
+  new Benchmark('Has', false, false, 0, MapHasObject, MapSetupObject, MapTearDown),
+  new Benchmark('Get', false, false, 0, MapGetObject, MapSetupObject, MapTearDown),
+  new Benchmark('Delete', false, false, 0, MapDeleteObject, MapSetupObject, MapTearDown),
+]);
+
+
+var MapIterationBenchmark = new BenchmarkSuite('Map-Iteration', [1000], [
+  new Benchmark('ForEach', false, false, 0, MapForEach, MapSetupSmi, MapTearDown),
+]);
+
+
+var map;
+
+
+function MapSetupSmiBase() {
+  SetupSmiKeys();
+  map = new Map;
+}
+
+
+function MapSetupSmi() {
+  MapSetupSmiBase();
+  MapSetSmi();
+}
+
+
+function MapSetupStringBase() {
+  SetupStringKeys();
+  map = new Map;
+}
+
+
+function MapSetupString() {
+  MapSetupStringBase();
+  MapSetString();
+}
+
+
+function MapSetupObjectBase() {
+  SetupObjectKeys();
+  map = new Map;
+}
+
+
+function MapSetupObject() {
+  MapSetupObjectBase();
+  MapSetObject();
+}
+
+
+function MapTearDown() {
+  map = null;
+}
+
+
+function MapSetSmi() {
+  for (var i = 0; i < N; i++) {
+    map.set(keys[i], i);
+  }
+}
+
+
+function MapHasSmi() {
+  for (var i = 0; i < N; i++) {
+    if (!map.has(keys[i])) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (map.has(keys[i])) {
+      throw new Error();
+    }
+  }
+}
+
+
+function MapGetSmi() {
+  for (var i = 0; i < N; i++) {
+    if (map.get(keys[i]) !== i) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (map.get(keys[i]) !== undefined) {
+      throw new Error();
+    }
+  }
+}
+
+
+function MapDeleteSmi() {
+  // This is run more than once per setup so we will end up deleting items
+  // more than once. Therefore, we do not the return value of delete.
+  for (var i = 0; i < N; i++) {
+    map.delete(keys[i]);
+  }
+}
+
+
+function MapSetString() {
+  for (var i = 0; i < N; i++) {
+    map.set(keys[i], i);
+  }
+}
+
+
+function MapHasString() {
+  for (var i = 0; i < N; i++) {
+    if (!map.has(keys[i])) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (map.has(keys[i])) {
+      throw new Error();
+    }
+  }
+}
+
+
+function MapGetString() {
+  for (var i = 0; i < N; i++) {
+    if (map.get(keys[i]) !== i) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (map.get(keys[i]) !== undefined) {
+      throw new Error();
+    }
+  }
+}
+
+
+function MapDeleteString() {
+  // This is run more than once per setup so we will end up deleting items
+  // more than once. Therefore, we do not the return value of delete.
+  for (var i = 0; i < N; i++) {
+    map.delete(keys[i]);
+  }
+}
+
+
+function MapSetObject() {
+  for (var i = 0; i < N; i++) {
+    map.set(keys[i], i);
+  }
+}
+
+
+function MapHasObject() {
+  for (var i = 0; i < N; i++) {
+    if (!map.has(keys[i])) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (map.has(keys[i])) {
+      throw new Error();
+    }
+  }
+}
+
+
+function MapGetObject() {
+  for (var i = 0; i < N; i++) {
+    if (map.get(keys[i]) !== i) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (map.get(keys[i]) !== undefined) {
+      throw new Error();
+    }
+  }
+}
+
+
+function MapDeleteObject() {
+  // This is run more than once per setup so we will end up deleting items
+  // more than once. Therefore, we do not the return value of delete.
+  for (var i = 0; i < N; i++) {
+    map.delete(keys[i]);
+  }
+}
+
+
+function MapForEach() {
+  map.forEach(function(v, k) {
+    if (v !== k) {
+      throw new Error();
+    }
+  });
+}
diff --git a/test/js-perf-test/Collections/run.js b/test/js-perf-test/Collections/run.js
new file mode 100644
index 0000000..50f1ee1
--- /dev/null
+++ b/test/js-perf-test/Collections/run.js
@@ -0,0 +1,31 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+load('../base.js');
+load('common.js');
+load('map.js');
+load('set.js');
+load('weakmap.js');
+load('weakset.js');
+
+
+var success = true;
+
+function PrintResult(name, result) {
+  print(name + '-Collections(Score): ' + result);
+}
+
+
+function PrintError(name, error) {
+  PrintResult(name, error);
+  success = false;
+}
+
+
+BenchmarkSuite.config.doWarmup = undefined;
+BenchmarkSuite.config.doDeterministic = undefined;
+
+BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
+                           NotifyError: PrintError });
diff --git a/test/js-perf-test/Collections/set.js b/test/js-perf-test/Collections/set.js
new file mode 100644
index 0000000..3be27f5
--- /dev/null
+++ b/test/js-perf-test/Collections/set.js
@@ -0,0 +1,172 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+var SetSmiBenchmark = new BenchmarkSuite('Set-Smi', [1000], [
+  new Benchmark('Set', false, false, 0, SetAddSmi, SetSetupSmiBase, SetTearDown),
+  new Benchmark('Has', false, false, 0, SetHasSmi, SetSetupSmi, SetTearDown),
+  new Benchmark('Delete', false, false, 0, SetDeleteSmi, SetSetupSmi, SetTearDown),
+]);
+
+
+var SetStringBenchmark = new BenchmarkSuite('Set-String', [1000], [
+  new Benchmark('Set', false, false, 0, SetAddString, SetSetupStringBase, SetTearDown),
+  new Benchmark('Has', false, false, 0, SetHasString, SetSetupString, SetTearDown),
+  new Benchmark('Delete', false, false, 0, SetDeleteString, SetSetupString, SetTearDown),
+]);
+
+
+var SetObjectBenchmark = new BenchmarkSuite('Set-Object', [1000], [
+  new Benchmark('Set', false, false, 0, SetAddObject, SetSetupObjectBase, SetTearDown),
+  new Benchmark('Has', false, false, 0, SetHasObject, SetSetupObject, SetTearDown),
+  new Benchmark('Delete', false, false, 0, SetDeleteObject, SetSetupObject, SetTearDown),
+]);
+
+
+var SetIterationBenchmark = new BenchmarkSuite('Set-Iteration', [1000], [
+  new Benchmark('ForEach', false, false, 0, SetForEach, SetSetupSmi, SetTearDown),
+]);
+
+
+var set;
+
+
+function SetSetupSmiBase() {
+  SetupSmiKeys();
+  set = new Set;
+}
+
+
+function SetSetupSmi() {
+  SetSetupSmiBase();
+  SetAddSmi();
+}
+
+
+function SetSetupStringBase() {
+  SetupStringKeys();
+  set = new Set;
+}
+
+
+function SetSetupString() {
+  SetSetupStringBase();
+  SetAddString();
+}
+
+
+function SetSetupObjectBase() {
+  SetupObjectKeys();
+  set = new Set;
+}
+
+
+function SetSetupObject() {
+  SetSetupObjectBase();
+  SetAddObject();
+}
+
+
+function SetTearDown() {
+  set = null;
+}
+
+
+function SetAddSmi() {
+  for (var i = 0; i < N; i++) {
+    set.add(keys[i], i);
+  }
+}
+
+
+function SetHasSmi() {
+  for (var i = 0; i < N; i++) {
+    if (!set.has(keys[i])) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (set.has(keys[i])) {
+      throw new Error();
+    }
+  }
+}
+
+
+function SetDeleteSmi() {
+  // This is run more than once per setup so we will end up deleting items
+  // more than once. Therefore, we do not the return value of delete.
+  for (var i = 0; i < N; i++) {
+    set.delete(keys[i]);
+  }
+}
+
+
+function SetAddString() {
+  for (var i = 0; i < N; i++) {
+    set.add(keys[i], i);
+  }
+}
+
+
+function SetHasString() {
+  for (var i = 0; i < N; i++) {
+    if (!set.has(keys[i])) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (set.has(keys[i])) {
+      throw new Error();
+    }
+  }
+}
+
+
+function SetDeleteString() {
+  // This is run more than once per setup so we will end up deleting items
+  // more than once. Therefore, we do not the return value of delete.
+  for (var i = 0; i < N; i++) {
+    set.delete(keys[i]);
+  }
+}
+
+
+function SetAddObject() {
+  for (var i = 0; i < N; i++) {
+    set.add(keys[i], i);
+  }
+}
+
+
+function SetHasObject() {
+  for (var i = 0; i < N; i++) {
+    if (!set.has(keys[i])) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (set.has(keys[i])) {
+      throw new Error();
+    }
+  }
+}
+
+
+function SetDeleteObject() {
+  // This is run more than once per setup so we will end up deleting items
+  // more than once. Therefore, we do not the return value of delete.
+  for (var i = 0; i < N; i++) {
+    set.delete(keys[i]);
+  }
+}
+
+
+function SetForEach() {
+  set.forEach(function(v, k) {
+    if (v !== k) {
+      throw new Error();
+    }
+  });
+}
diff --git a/test/js-perf-test/Collections/weakmap.js b/test/js-perf-test/Collections/weakmap.js
new file mode 100644
index 0000000..9aa265f
--- /dev/null
+++ b/test/js-perf-test/Collections/weakmap.js
@@ -0,0 +1,79 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+var MapBenchmark = new BenchmarkSuite('WeakMap', [1000], [
+  new Benchmark('Set', false, false, 0, WeakMapSet, WeakMapSetupBase,
+      WeakMapTearDown),
+  new Benchmark('Has', false, false, 0, WeakMapHas, WeakMapSetup,
+      WeakMapTearDown),
+  new Benchmark('Get', false, false, 0, WeakMapGet, WeakMapSetup,
+      WeakMapTearDown),
+  new Benchmark('Delete', false, false, 0, WeakMapDelete, WeakMapSetup,
+      WeakMapTearDown),
+]);
+
+
+var wm;
+
+
+function WeakMapSetupBase() {
+  SetupObjectKeys();
+  wm = new WeakMap;
+}
+
+
+function WeakMapSetup() {
+  WeakMapSetupBase();
+  WeakMapSet();
+}
+
+
+function WeakMapTearDown() {
+  wm = null;
+}
+
+
+function WeakMapSet() {
+  for (var i = 0; i < N; i++) {
+    wm.set(keys[i], i);
+  }
+}
+
+
+function WeakMapHas() {
+  for (var i = 0; i < N; i++) {
+    if (!wm.has(keys[i])) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (wm.has(keys[i])) {
+      throw new Error();
+    }
+  }
+}
+
+
+function WeakMapGet() {
+  for (var i = 0; i < N; i++) {
+    if (wm.get(keys[i]) !== i) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (wm.get(keys[i]) !== undefined) {
+      throw new Error();
+    }
+  }
+}
+
+
+function WeakMapDelete() {
+  // This is run more than once per setup so we will end up deleting items
+  // more than once. Therefore, we do not the return value of delete.
+  for (var i = 0; i < N; i++) {
+    wm.delete(keys[i]);
+  }
+}
diff --git a/test/js-perf-test/Collections/weakset.js b/test/js-perf-test/Collections/weakset.js
new file mode 100644
index 0000000..2936477
--- /dev/null
+++ b/test/js-perf-test/Collections/weakset.js
@@ -0,0 +1,63 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+var SetBenchmark = new BenchmarkSuite('WeakSet', [1000], [
+  new Benchmark('Add', false, false, 0, WeakSetAdd, WeakSetSetupBase,
+      WeakSetTearDown),
+  new Benchmark('Has', false, false, 0, WeakSetHas, WeakSetSetup,
+      WeakSetTearDown),
+  new Benchmark('Delete', false, false, 0, WeakSetDelete, WeakSetSetup,
+      WeakSetTearDown),
+]);
+
+
+var ws;
+
+
+function WeakSetSetupBase() {
+  SetupObjectKeys();
+  ws = new WeakSet;
+}
+
+
+function WeakSetSetup() {
+  WeakSetSetupBase();
+  WeakSetAdd();
+}
+
+
+function WeakSetTearDown() {
+  ws = null;
+}
+
+
+function WeakSetAdd() {
+  for (var i = 0; i < N; i++) {
+    ws.add(keys[i]);
+  }
+}
+
+
+function WeakSetHas() {
+  for (var i = 0; i < N; i++) {
+    if (!ws.has(keys[i])) {
+      throw new Error();
+    }
+  }
+  for (var i = N; i < 2 * N; i++) {
+    if (ws.has(keys[i])) {
+      throw new Error();
+    }
+  }
+}
+
+
+function WeakSetDelete() {
+  // This is run more than once per setup so we will end up deleting items
+  // more than once. Therefore, we do not the return value of delete.
+  for (var i = 0; i < N; i++) {
+    ws.delete(keys[i]);
+  }
+}
diff --git a/test/js-perf-test/Iterators/forof.js b/test/js-perf-test/Iterators/forof.js
new file mode 100644
index 0000000..1877ebe
--- /dev/null
+++ b/test/js-perf-test/Iterators/forof.js
@@ -0,0 +1,94 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+new BenchmarkSuite('ForOf', [1000], [
+  new Benchmark('ArrayValues', false, false, 0,
+                ForOf, ForOfArraySetup, ForOfTearDown),
+  new Benchmark('ArrayKeys', false, false, 0,
+                ForOf, ForOfArrayKeysSetup, ForOfTearDown),
+  new Benchmark('ArrayEntries', false, false, 0,
+                ForOf, ForOfArrayEntriesSetup, ForOfTearDown),
+  new Benchmark('Uint8Array', false, false, 0,
+                ForOf, ForOfUint8ArraySetup, ForOfTearDown),
+  new Benchmark('Float64Array', false, false, 0,
+                ForOf, ForOfFloat64ArraySetup, ForOfTearDown),
+  new Benchmark('String', false, false, 0,
+                ForOf, ForOfStringSetup, ForOfTearDown),
+]);
+
+
+var iterable;
+var N = 100;
+var expected, result;
+
+
+function ForOfArraySetupHelper(constructor) {
+  iterable = new constructor(N);
+  for (var i = 0; i < N; i++) iterable[i] = i;
+  expected = N - 1;
+}
+
+
+function ForOfArraySetup() {
+  ForOfArraySetupHelper(Array);
+  // Default iterator is values().
+}
+
+
+function ForOfArrayKeysSetup() {
+  ForOfArraySetupHelper(Array);
+  iterable = iterable.keys();
+}
+
+
+function ForOfArrayEntriesSetup() {
+  ForOfArraySetupHelper(Array);
+  iterable = iterable.entries();
+  expected = [N-1, N-1];
+}
+
+
+function ForOfUint8ArraySetup() {
+  ForOfArraySetupHelper(Uint8Array);
+}
+
+
+function ForOfFloat64ArraySetup() {
+  ForOfArraySetupHelper(Float64Array);
+}
+
+
+function ForOfStringSetup() {
+  iterable = "abcdefhijklmnopqrstuvwxyzABCDEFHIJKLMNOPQRSTUVWXYZ0123456789";
+  expected = "9";
+}
+
+
+function Equals(expected, actual) {
+  if (expected === actual) return true;
+  if (typeof expected !== typeof actual) return false;
+  if (typeof expected !== 'object') return false;
+  for (var k of Object.keys(expected)) {
+    if (!(k in actual)) return false;
+    if (!Equals(expected[k], actual[k])) return false;
+  }
+  for (var k of Object.keys(actual)) {
+    if (!(k in expected)) return false;
+  }
+  return true;
+}
+
+function ForOfTearDown() {
+  iterable = null;
+  if (!Equals(expected, result)) {
+    throw new Error("Bad result: " + result);
+  }
+}
+
+
+function ForOf() {
+  for (var x of iterable) {
+    result = x;
+  }
+}
diff --git a/test/js-perf-test/Iterators/run.js b/test/js-perf-test/Iterators/run.js
new file mode 100644
index 0000000..ff4897f
--- /dev/null
+++ b/test/js-perf-test/Iterators/run.js
@@ -0,0 +1,27 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+load('../base.js');
+load('forof.js');
+
+
+var success = true;
+
+function PrintResult(name, result) {
+  print(name + '-Iterators(Score): ' + result);
+}
+
+
+function PrintError(name, error) {
+  PrintResult(name, error);
+  success = false;
+}
+
+
+BenchmarkSuite.config.doWarmup = undefined;
+BenchmarkSuite.config.doDeterministic = undefined;
+
+BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
+                           NotifyError: PrintError });
diff --git a/test/js-perf-test/JSTests.json b/test/js-perf-test/JSTests.json
new file mode 100644
index 0000000..0a99ad4
--- /dev/null
+++ b/test/js-perf-test/JSTests.json
@@ -0,0 +1,86 @@
+{
+  "name": "JSTests",
+  "run_count": 5,
+  "run_count_android_arm": 3,
+  "run_count_android_arm64": 3,
+  "units": "score",
+  "total": true,
+  "resources": ["base.js"],
+  "tests": [
+    {
+      "name": "Classes",
+      "path": ["Classes"],
+      "main": "run.js",
+      "resources": ["super.js", "default-constructor.js"],
+      "flags": ["--harmony-classes"],
+      "results_regexp": "^%s\\-Classes\\(Score\\): (.+)$",
+      "tests": [
+        {"name": "Super"},
+        {"name": "DefaultConstructor"}
+      ]
+    },
+    {
+      "name": "Collections",
+      "path": ["Collections"],
+      "main": "run.js",
+      "resources": [
+        "common.js",
+        "map.js",
+        "run.js",
+        "set.js",
+        "weakmap.js",
+        "weakset.js"
+      ],
+      "results_regexp": "^%s\\-Collections\\(Score\\): (.+)$",
+      "tests": [
+        {"name": "Map-Smi"},
+        {"name": "Map-String"},
+        {"name": "Map-Object"},
+        {"name": "Map-Iteration"},
+        {"name": "Set-Smi"},
+        {"name": "Set-String"},
+        {"name": "Set-Object"},
+        {"name": "Set-Iteration"},
+        {"name": "WeakMap"},
+        {"name": "WeakSet"}
+      ]
+    },
+    {
+      "name": "Iterators",
+      "path": ["Iterators"],
+      "main": "run.js",
+      "resources": ["forof.js"],
+      "results_regexp": "^%s\\-Iterators\\(Score\\): (.+)$",
+      "tests": [
+        {"name": "ForOf"}
+      ]
+    },
+    {
+      "name": "Strings",
+      "path": ["Strings"],
+      "main": "run.js",
+      "resources": ["harmony-string.js"],
+      "flags": ["--harmony-strings"],
+      "results_regexp": "^%s\\-Strings\\(Score\\): (.+)$",
+      "tests": [
+        {"name": "StringFunctions"}
+      ]
+    },
+    {
+      "name": "Templates",
+      "path": ["Templates"],
+      "main": "run.js",
+      "resources": ["templates.js"],
+      "flags": ["--harmony-templates"],
+      "run_count": 5,
+      "units": "score",
+      "results_regexp": "^%s\\-Templates\\(Score\\): (.+)$",
+      "total": true,
+      "tests": [
+        {"name": "Untagged"},
+        {"name": "LargeUntagged"},
+        {"name": "Tagged"}
+      ]
+    }
+  ]
+}
diff --git a/test/js-perf-test/Strings/harmony-string.js b/test/js-perf-test/Strings/harmony-string.js
new file mode 100644
index 0000000..c2eac4e
--- /dev/null
+++ b/test/js-perf-test/Strings/harmony-string.js
@@ -0,0 +1,111 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+new BenchmarkSuite('StringFunctions', [1000], [
+  new Benchmark('StringRepeat', false, false, 0,
+                Repeat, RepeatSetup, RepeatTearDown),
+  new Benchmark('StringStartsWith', false, false, 0,
+                StartsWith, WithSetup, WithTearDown),
+  new Benchmark('StringEndsWith', false, false, 0,
+                EndsWith, WithSetup, WithTearDown),
+  new Benchmark('StringIncludes', false, false, 0,
+                Includes, IncludesSetup, WithTearDown),
+  new Benchmark('StringFromCodePoint', false, false, 0,
+                FromCodePoint, FromCodePointSetup, FromCodePointTearDown),
+  new Benchmark('StringCodePointAt', false, false, 0,
+                CodePointAt, CodePointAtSetup, CodePointAtTearDown),
+]);
+
+
+var result;
+
+var stringRepeatSource = "abc";
+
+function RepeatSetup() {
+  result = undefined;
+}
+
+function Repeat() {
+  result = stringRepeatSource.repeat(500);
+}
+
+function RepeatTearDown() {
+  var expected = "";
+  for(var i = 0; i < 1000; i++) {
+    expected += stringRepeatSource;
+  }
+  return result === expected;
+}
+
+
+var str;
+var substr;
+
+function WithSetup() {
+  str = "abc".repeat(500);
+  substr = "abc".repeat(200);
+  result = undefined;
+}
+
+function WithTearDown() {
+  return !!result;
+}
+
+function StartsWith() {
+  result = str.startsWith(substr);
+}
+
+function EndsWith() {
+  result = str.endsWith(substr);
+}
+
+function IncludesSetup() {
+  str = "def".repeat(100) + "abc".repeat(100) + "qqq".repeat(100);
+  substr = "abc".repeat(100);
+}
+
+function Includes() {
+  result = str.includes(substr);
+}
+
+var MAX_CODE_POINT = 0xFFFFF;
+
+function FromCodePointSetup() {
+  result = new Array(MAX_CODE_POINT + 1);
+}
+
+function FromCodePoint() {
+  for (var i = 0; i <= MAX_CODE_POINT; i++) {
+    result[i] = String.fromCodePoint(i);
+  }
+}
+
+function FromCodePointTearDown() {
+  for (var i = 0; i <= MAX_CODE_POINT; i++) {
+    if (i !== result[i].codePointAt(0)) return false;
+  }
+  return true;
+}
+
+
+var allCodePoints;
+
+function CodePointAtSetup() {
+  allCodePoints = new Array(MAX_CODE_POINT + 1);
+  for (var i = 0; i <= MAX_CODE_POINT; i++) {
+    allCodePoints = String.fromCodePoint(i);
+  }
+  result = undefined;
+}
+
+function CodePointAt() {
+  result = 0;
+  for (var i = 0; i <= MAX_CODE_POINT; i++) {
+    result += allCodePoints.codePointAt(i);
+  }
+}
+
+function CodePointAtTearDown() {
+  return result === MAX_CODE_POINT * (MAX_CODE_POINT + 1) / 2;
+}
diff --git a/test/js-perf-test/Strings/run.js b/test/js-perf-test/Strings/run.js
new file mode 100644
index 0000000..79ca26e
--- /dev/null
+++ b/test/js-perf-test/Strings/run.js
@@ -0,0 +1,27 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+load('../base.js');
+load('harmony-string.js');
+
+
+var success = true;
+
+function PrintResult(name, result) {
+  print(name + '-Strings(Score): ' + result);
+}
+
+
+function PrintError(name, error) {
+  PrintResult(name, error);
+  success = false;
+}
+
+
+BenchmarkSuite.config.doWarmup = undefined;
+BenchmarkSuite.config.doDeterministic = undefined;
+
+BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
+                           NotifyError: PrintError });
diff --git a/test/js-perf-test/Templates/run.js b/test/js-perf-test/Templates/run.js
new file mode 100644
index 0000000..73f1edd
--- /dev/null
+++ b/test/js-perf-test/Templates/run.js
@@ -0,0 +1,27 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+load('../base.js');
+load('templates.js');
+
+
+var success = true;
+
+function PrintResult(name, result) {
+  print(name + '-Templates(Score): ' + result);
+}
+
+
+function PrintError(name, error) {
+  PrintResult(name, error);
+  success = false;
+}
+
+
+BenchmarkSuite.config.doWarmup = undefined;
+BenchmarkSuite.config.doDeterministic = undefined;
+
+BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
+                           NotifyError: PrintError });
diff --git a/test/js-perf-test/Templates/templates.js b/test/js-perf-test/Templates/templates.js
new file mode 100644
index 0000000..4034ce7
--- /dev/null
+++ b/test/js-perf-test/Templates/templates.js
@@ -0,0 +1,87 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+new BenchmarkSuite('Untagged', [1000], [
+  new Benchmark('Untagged-Simple', false, false, 0,
+                Untagged, UntaggedSetup, UntaggedTearDown),
+]);
+
+new BenchmarkSuite('LargeUntagged', [1000], [
+  new Benchmark('Untagged-Large', false, false, 0,
+                UntaggedLarge, UntaggedLargeSetup, UntaggedLargeTearDown),
+]);
+
+new BenchmarkSuite('Tagged', [1000], [
+  new Benchmark('TaggedRawSimple', false, false, 0,
+                TaggedRaw, TaggedRawSetup, TaggedRawTearDown),
+]);
+
+var result;
+var SUBJECT = 'Bob';
+var TARGET = 'Mary';
+var OBJECT = 'apple';
+
+function UntaggedSetup() {
+  result = undefined;
+}
+
+function Untagged() {
+  result = `${SUBJECT} gives ${TARGET} an ${OBJECT}.`;
+}
+
+function UntaggedTearDown() {
+  var expected = '' + SUBJECT + ' gives ' + TARGET + ' an ' + OBJECT + '.';
+  return result === expected;
+}
+
+
+// ----------------------------------------------------------------------------
+
+function UntaggedLargeSetup() {
+  result = undefined;
+}
+
+function UntaggedLarge() {
+  result = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus
+ aliquam, elit euismod vestibulum ${0}lacinia, arcu odio sagittis mauris, id
+ blandit dolor felis pretium nisl. Maecenas porttitor, nunc ut accumsan mollis,
+ arcu metus rutrum arcu, ${1}ut varius dolor lorem nec risus. Integer convallis
+ tristique ante, non pretium ante suscipit at. Sed egestas massa enim, convallis
+ fermentum neque vehicula ac. Donec imperdiet a tortor ac semper. Morbi accumsan
+ quam nec erat viverra iaculis. ${2}Donec a scelerisque cras amet.`;
+}
+
+function UntaggedLargeTearDown() {
+  var expected = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
+      "Vivamus\n aliquam, elit euismod vestibulum " + 0 + "lacinia, arcu odio" +
+      " sagittis mauris, id\n blandit dolor felis pretium nisl. Maecenas " +
+      "porttitor, nunc ut accumsan mollis,\n arcu metus rutrum arcu, " + 1 +
+      "ut varius dolor lorem nec risus. Integer convallis\n tristique ante, " +
+      "non pretium ante suscipit at. Sed egestas massa enim, convallis\n " +
+      "fermentum neque vehicula ac. Donec imperdiet a tortor ac semper. Morbi" +
+      " accumsan\n quam nec erat viverra iaculis. " + 2 + "Donec a " +
+      "scelerisque cras amet.";
+  return result === expected;
+}
+
+
+// ----------------------------------------------------------------------------
+
+
+function TaggedRawSetup() {
+  result = undefined;
+}
+
+function TaggedRaw() {
+  result = String.raw `${SUBJECT} gives ${TARGET} an ${OBJECT} \ud83c\udf4f.`;
+}
+
+function TaggedRawTearDown() {
+  var expected =
+      '' + SUBJECT + ' gives ' + TARGET + ' an ' + OBJECT + ' \\ud83c\\udf4f.';
+  return result === expected;
+}
+
+
+// ----------------------------------------------------------------------------
diff --git a/test/perf-test/Collections/base.js b/test/js-perf-test/base.js
similarity index 100%
rename from test/perf-test/Collections/base.js
rename to test/js-perf-test/base.js
diff --git a/test/libplatform-unittests/libplatform-unittests.status b/test/libplatform-unittests/libplatform-unittests.status
deleted file mode 100644
index d439913..0000000
--- a/test/libplatform-unittests/libplatform-unittests.status
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright 2014 the V8 project authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-[
-]
diff --git a/test/message/single-function-literal.js b/test/message/single-function-literal.js
index 96d3bd6..fd73491 100644
--- a/test/message/single-function-literal.js
+++ b/test/message/single-function-literal.js
@@ -27,6 +27,6 @@
 
 // Flags: --allow-natives-syntax
 var single_function_good = "(function() { return 5; })";
-%CompileString(single_function_good, true);
+%CompileString(single_function_good, true, 0);
 var single_function_bad = "(function() { return 5; })();";
-%CompileString(single_function_bad, true);
+%CompileString(single_function_bad, true, 0);
diff --git a/test/message/super-constructor-extra-statement.js b/test/message/super-constructor-extra-statement.js
new file mode 100644
index 0000000..e8ffe2d
--- /dev/null
+++ b/test/message/super-constructor-extra-statement.js
@@ -0,0 +1,15 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --harmony-classes
+'use strict';
+
+class C {
+  constructor() {
+    var x;
+    super(x);
+  }
+}
+
+var c = new C();
diff --git a/test/message/super-constructor-extra-statement.out b/test/message/super-constructor-extra-statement.out
new file mode 100644
index 0000000..cbe1e07
--- /dev/null
+++ b/test/message/super-constructor-extra-statement.out
@@ -0,0 +1,8 @@
+# Copyright 2014 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+*%(basename)s:10: TypeError: A 'super' constructor call may only appear as the first statement of a function, and its arguments may not access 'this'. Other forms are not yet supported.
+    var x;
+    
+TypeError: A 'super' constructor call may only appear as the first statement of a function, and its arguments may not access 'this'. Other forms are not yet supported.
+    at *%(basename)s:15:9
diff --git a/test/message/super-constructor.js b/test/message/super-constructor.js
new file mode 100644
index 0000000..430dc58
--- /dev/null
+++ b/test/message/super-constructor.js
@@ -0,0 +1,14 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --harmony-classes
+'use strict';
+
+class C {
+  constructor() {
+    super(this.x);
+  }
+}
+
+var c = new C();
diff --git a/test/message/super-constructor.out b/test/message/super-constructor.out
new file mode 100644
index 0000000..bc3a699
--- /dev/null
+++ b/test/message/super-constructor.out
@@ -0,0 +1,8 @@
+# Copyright 2014 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+*%(basename)s:10: TypeError: A 'super' constructor call may only appear as the first statement of a function, and its arguments may not access 'this'. Other forms are not yet supported.
+    super(this.x);
+     
+TypeError: A 'super' constructor call may only appear as the first statement of a function, and its arguments may not access 'this'. Other forms are not yet supported.
+    at *%(basename)s:14:9
diff --git a/test/message/testcfg.py b/test/message/testcfg.py
index b472f9c..5d6ab84 100644
--- a/test/message/testcfg.py
+++ b/test/message/testcfg.py
@@ -75,6 +75,7 @@
   def _IgnoreLine(self, string):
     """Ignore empty lines, valgrind output, Android output."""
     if not string: return True
+    if not string.strip(): return True
     return (string.startswith("==") or string.startswith("**") or
             string.startswith("ANDROID") or
             # These five patterns appear in normal Native Client output.
diff --git a/test/mjsunit/array-iteration.js b/test/mjsunit/array-iteration.js
index d11f984..1324074 100644
--- a/test/mjsunit/array-iteration.js
+++ b/test/mjsunit/array-iteration.js
@@ -68,6 +68,23 @@
   assertEquals(3, count);
   for (var i in a) assertEquals(2, a[i]);
 
+  // Create a new object in each function call when receiver is a
+  // primitive value. See ECMA-262, Annex C.
+  a = [];
+  [1, 2].filter(function() { a.push(this) }, "");
+  assertTrue(a[0] !== a[1]);
+
+  // Do not create a new object otherwise.
+  a = [];
+  [1, 2].filter(function() { a.push(this) }, {});
+  assertEquals(a[0], a[1]);
+
+  // In strict mode primitive values should not be coerced to an object.
+  a = [];
+  [1, 2].filter(function() { 'use strict'; a.push(this); }, "");
+  assertEquals("", a[0]);
+  assertEquals(a[0], a[1]);
+
 })();
 
 
@@ -109,6 +126,23 @@
   a.forEach(function(n) { count++; });
   assertEquals(1, count);
 
+  // Create a new object in each function call when receiver is a
+  // primitive value. See ECMA-262, Annex C.
+  a = [];
+  [1, 2].forEach(function() { a.push(this) }, "");
+  assertTrue(a[0] !== a[1]);
+
+  // Do not create a new object otherwise.
+  a = [];
+  [1, 2].forEach(function() { a.push(this) }, {});
+  assertEquals(a[0], a[1]);
+
+  // In strict mode primitive values should not be coerced to an object.
+  a = [];
+  [1, 2].forEach(function() { 'use strict'; a.push(this); }, "");
+  assertEquals("", a[0]);
+  assertEquals(a[0], a[1]);
+
 })();
 
 
@@ -149,6 +183,23 @@
   assertTrue(a.every(function(n) { count++; return n == 2; }));
   assertEquals(2, count);
 
+  // Create a new object in each function call when receiver is a
+  // primitive value. See ECMA-262, Annex C.
+  a = [];
+  [1, 2].every(function() { a.push(this); return true; }, "");
+  assertTrue(a[0] !== a[1]);
+
+  // Do not create a new object otherwise.
+  a = [];
+  [1, 2].every(function() { a.push(this); return true; }, {});
+  assertEquals(a[0], a[1]);
+
+  // In strict mode primitive values should not be coerced to an object.
+  a = [];
+  [1, 2].every(function() { 'use strict'; a.push(this); return true; }, "");
+  assertEquals("", a[0]);
+  assertEquals(a[0], a[1]);
+
 })();
 
 //
@@ -186,6 +237,23 @@
   a = a.map(function(n) { return 2*n; });
   for (var i in a) assertEquals(4, a[i]);
 
+  // Create a new object in each function call when receiver is a
+  // primitive value. See ECMA-262, Annex C.
+  a = [];
+  [1, 2].map(function() { a.push(this) }, "");
+  assertTrue(a[0] !== a[1]);
+
+  // Do not create a new object otherwise.
+  a = [];
+  [1, 2].map(function() { a.push(this) }, {});
+  assertEquals(a[0], a[1]);
+
+  // In strict mode primitive values should not be coerced to an object.
+  a = [];
+  [1, 2].map(function() { 'use strict'; a.push(this); }, "");
+  assertEquals("", a[0]);
+  assertEquals(a[0], a[1]);
+
 })();
 
 //
@@ -224,4 +292,21 @@
   assertTrue(a.some(function(n) { count++; return n == 2; }));
   assertEquals(2, count);
 
+  // Create a new object in each function call when receiver is a
+  // primitive value. See ECMA-262, Annex C.
+  a = [];
+  [1, 2].some(function() { a.push(this) }, "");
+  assertTrue(a[0] !== a[1]);
+
+  // Do not create a new object otherwise.
+  a = [];
+  [1, 2].some(function() { a.push(this) }, {});
+  assertEquals(a[0], a[1]);
+
+  // In strict mode primitive values should not be coerced to an object.
+  a = [];
+  [1, 2].some(function() { 'use strict'; a.push(this); }, "");
+  assertEquals("", a[0]);
+  assertEquals(a[0], a[1]);
+
 })();
diff --git a/test/mjsunit/array-methods-read-only-length.js b/test/mjsunit/array-methods-read-only-length.js
new file mode 100644
index 0000000..2943b16
--- /dev/null
+++ b/test/mjsunit/array-methods-read-only-length.js
@@ -0,0 +1,166 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function testAdd(mode) {
+  var a = [];
+  Object.defineProperty(a, "length", { writable : false});
+
+  function check(f) {
+    assertThrows(function() { f(a) }, TypeError);
+    assertFalse(0 in a);
+    assertEquals(0, a.length);
+  }
+
+  function push(a) {
+    a.push(3);
+  }
+
+  if (mode == "fast properties") %ToFastProperties(a);
+
+  check(push);
+  check(push);
+  check(push);
+  %OptimizeFunctionOnNextCall(push);
+  check(push);
+
+  function unshift(a) {
+    a.unshift(3);
+  }
+
+  check(unshift);
+  check(unshift);
+  check(unshift);
+  %OptimizeFunctionOnNextCall(unshift);
+  check(unshift);
+
+  function splice(a) {
+    a.splice(0, 0, 3);
+  }
+
+  check(splice);
+  check(splice);
+  check(splice);
+  %OptimizeFunctionOnNextCall(splice);
+  check(splice);
+}
+
+testAdd("fast properties");
+
+testAdd("normalized");
+
+function testRemove(a, mode) {
+  Object.defineProperty(a, "length", { writable : false});
+
+  function check(f) {
+    assertThrows(function() { f(a) }, TypeError);
+    assertEquals(3, a.length);
+  }
+
+  if (mode == "fast properties") %ToFastProperties(a);
+
+  function pop(a) {
+    a.pop();
+  }
+
+  check(pop);
+  check(pop);
+  check(pop);
+  %OptimizeFunctionOnNextCall(pop);
+  check(pop);
+
+  function shift(a) {
+    a.shift();
+  }
+
+  check(shift);
+  check(shift);
+  check(shift);
+  %OptimizeFunctionOnNextCall(shift);
+  check(shift);
+
+  function splice(a) {
+    a.splice(0, 1);
+  }
+
+  check(splice);
+  check(splice);
+  check(splice);
+  %OptimizeFunctionOnNextCall(splice);
+  check(splice);
+
+  %ClearFunctionTypeFeedback(pop);
+  %ClearFunctionTypeFeedback(shift);
+  %ClearFunctionTypeFeedback(splice);
+}
+
+for (var i = 0; i < 3; i++) {
+  var a = [1, 2, 3];
+  if (i == 1) {
+    a = [1, 2, 3.5];
+  } else if (i == 2) {
+    a = [1, 2, "string"];
+  }
+  testRemove(a, "fast properties");
+  testRemove(a, "normalized");
+}
+
+var b = [];
+Object.defineProperty(b.__proto__, "0", {
+  set : function(v) {
+    b.x = v;
+    Object.defineProperty(b, "length", { writable : false });
+  },
+  get: function() {
+    return b.x;
+  }
+});
+
+b = [];
+try {
+  b.push(3, 4, 5);
+} catch(e) { }
+assertFalse(1 in b);
+assertFalse(2 in b);
+assertEquals(0, b.length);
+
+b = [];
+try {
+  b.unshift(3, 4, 5);
+} catch(e) { }
+assertFalse(1 in b);
+assertFalse(2 in b);
+assertEquals(0, b.length);
+
+b = [1, 2];
+try {
+  b.unshift(3, 4, 5);
+} catch(e) { }
+assertEquals(3, b[0]);
+assertEquals(4, b[1]);
+assertEquals(5, b[2]);
+assertEquals(1, b[3]);
+assertEquals(2, b[4]);
+assertEquals(5, b.length);
+
+b = [1, 2];
+
+Object.defineProperty(b.__proto__, "4", {
+  set : function(v) {
+    b.z = v;
+    Object.defineProperty(b, "length", { writable : false });
+  },
+  get: function() {
+    return b.z;
+  }
+});
+
+try {
+  b.unshift(3, 4, 5);
+} catch(e) { }
+
+assertFalse(2 in b);
+assertFalse(3 in b);
+assertEquals(2, b.length);
diff --git a/test/mjsunit/array-natives-elements.js b/test/mjsunit/array-natives-elements.js
index d63346d..a19a931 100644
--- a/test/mjsunit/array-natives-elements.js
+++ b/test/mjsunit/array-natives-elements.js
@@ -274,14 +274,11 @@
   assertEquals([1,1,2,3], a4);
   a4 = [1,2,3];
   a4.unshift(1.1);
-  // TODO(verwaest): We'll want to support double unshifting as well.
-  // assertTrue(%HasFastDoubleElements(a4));
-  assertTrue(%HasFastObjectElements(a4));
+  assertTrue(%HasFastDoubleElements(a4));
   assertEquals([1.1,1,2,3], a4);
   a4 = [1.1,2,3];
   a4.unshift(1);
-  // assertTrue(%HasFastDoubleElements(a4));
-  assertTrue(%HasFastObjectElements(a4));
+  assertTrue(%HasFastDoubleElements(a4));
   assertEquals([1,1.1,2,3], a4);
   a4 = [{},2,3];
   a4.unshift(1);
diff --git a/test/mjsunit/array-push-unshift-read-only-length.js b/test/mjsunit/array-push-unshift-read-only-length.js
deleted file mode 100644
index 67aa397..0000000
--- a/test/mjsunit/array-push-unshift-read-only-length.js
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --allow-natives-syntax
-
-function test(mode) {
-  var a = [];
-  Object.defineProperty(a, "length", { writable : false});
-
-  function check(f) {
-    try {
-      f(a);
-    } catch(e) { }
-    assertFalse(0 in a);
-    assertEquals(0, a.length);
-  }
-
-  function push(a) {
-    a.push(3);
-  }
-
-  if (mode == "fast properties") %ToFastProperties(a);
-
-  check(push);
-  check(push);
-  check(push);
-  %OptimizeFunctionOnNextCall(push);
-  check(push);
-
-  function unshift(a) {
-    a.unshift(3);
-  }
-
-  check(unshift);
-  check(unshift);
-  check(unshift);
-  %OptimizeFunctionOnNextCall(unshift);
-  check(unshift);
-}
-
-test("fast properties");
-
-test("normalized");
-
-var b = [];
-Object.defineProperty(b.__proto__, "0", {
-  set : function(v) {
-    b.x = v;
-    Object.defineProperty(b, "length", { writable : false });
-  },
-  get: function() {
-    return b.x;
-  }
-});
-
-b = [];
-try {
-  b.push(3, 4, 5);
-} catch(e) { }
-assertFalse(1 in b);
-assertFalse(2 in b);
-assertEquals(0, b.length);
-
-b = [];
-try {
-  b.unshift(3, 4, 5);
-} catch(e) { }
-assertFalse(1 in b);
-assertFalse(2 in b);
-assertEquals(0, b.length);
-
-b = [1, 2];
-try {
-  b.unshift(3, 4, 5);
-} catch(e) { }
-assertEquals(3, b[0]);
-assertEquals(4, b[1]);
-assertEquals(5, b[2]);
-assertEquals(1, b[3]);
-assertEquals(2, b[4]);
-assertEquals(5, b.length);
-
-b = [1, 2];
-
-Object.defineProperty(b.__proto__, "4", {
-  set : function(v) {
-    b.z = v;
-    Object.defineProperty(b, "length", { writable : false });
-  },
-  get: function() {
-    return b.z;
-  }
-});
-
-try {
-  b.unshift(3, 4, 5);
-} catch(e) { }
-
-// TODO(ulan): According to the ECMA-262 unshift should throw an exception
-// when moving b[0] to b[3] (see 15.4.4.13 step 6.d.ii). This is difficult
-// to do with our current implementation of SmartMove() in src/array.js and
-// it will regress performance. Uncomment the following line once acceptable
-// solution is found:
-// assertFalse(2 in b);
-// assertFalse(3 in b);
-// assertEquals(2, b.length);
diff --git a/test/mjsunit/array-reduce.js b/test/mjsunit/array-reduce.js
index 429f348..94e5144 100644
--- a/test/mjsunit/array-reduce.js
+++ b/test/mjsunit/array-reduce.js
@@ -521,3 +521,13 @@
             [3, 3, 2, [1, 2, 3, 4, 4, 5], 6],
             [6, 4, 3, [1, 2, 3, 4, 4, 5, 6], 10],
            ], arr, extender, 0);
+
+var arr = [];
+Object.defineProperty(arr, "0", { get: function() { delete this[0] },
+  configurable: true });
+assertEquals(undefined, arr.reduce(function(val) { return val }));
+
+var arr = [];
+Object.defineProperty(arr, "0", { get: function() { delete this[0] },
+  configurable: true});
+assertEquals(undefined, arr.reduceRight(function(val) { return val }));
diff --git a/test/mjsunit/array-shift2.js b/test/mjsunit/array-shift2.js
index 73d8cd4..75233ff 100644
--- a/test/mjsunit/array-shift2.js
+++ b/test/mjsunit/array-shift2.js
@@ -12,7 +12,17 @@
   array.shift();
   return array;
 }
-assertEquals(["element 1",2], test(["0",,2]));
-assertEquals(["element 1",{}], test([{},,{}]));
+
+var result = test(["0",,2]);
+assertEquals(["element 1","element 1"], result);
+assertTrue(result.hasOwnProperty("0"));
+assertFalse(result.hasOwnProperty("1"));
+result = test([{},,{}]);
+assertEquals(["element 1","element 1"], result);
+assertTrue(result.hasOwnProperty("0"));
+assertFalse(result.hasOwnProperty("1"));
 %OptimizeFunctionOnNextCall(test);
-assertEquals(["element 1",0], test([{},,0]));
+result = test([{},,0]);
+assertEquals(["element 1","element 1"], result);
+assertTrue(result.hasOwnProperty("0"));
+assertFalse(result.hasOwnProperty("1"));
diff --git a/test/mjsunit/array-shift4.js b/test/mjsunit/array-shift4.js
new file mode 100644
index 0000000..669b11a
--- /dev/null
+++ b/test/mjsunit/array-shift4.js
@@ -0,0 +1,24 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+// Inlining shift with holey smi arrays shouldn't deopt just because it
+// encounters the hole on the copy step.
+function doShift(a) {
+  var x = a.shift();
+  return x;
+}
+
+function makeArray() {
+  var a = [1, 2,, 3];
+  a[0] = 2;
+  return a;
+}
+
+doShift(makeArray());
+doShift(makeArray());
+%OptimizeFunctionOnNextCall(doShift);
+doShift(makeArray());
+assertOptimized(doShift);
diff --git a/test/mjsunit/array-unshift.js b/test/mjsunit/array-unshift.js
index 0eb299a..50aab4f 100644
--- a/test/mjsunit/array-unshift.js
+++ b/test/mjsunit/array-unshift.js
@@ -37,9 +37,7 @@
 })();
 
 
-// Check that unshift with no args has a side-effect of
-// filling the holes with elements from the prototype
-// (if present, of course)
+// Check that unshift with no args has no side-effects.
 (function() {
   var len = 3;
   var array = new Array(len);
@@ -65,15 +63,15 @@
   assertTrue(delete Array.prototype[0]);
   assertTrue(delete Array.prototype[2]);
 
-  // unshift makes array own 0 and 2...
-  assertTrue(array.hasOwnProperty(0));
+  // array still owns nothing...
+  assertFalse(array.hasOwnProperty(0));
   assertFalse(array.hasOwnProperty(1));
-  assertTrue(array.hasOwnProperty(2));
+  assertFalse(array.hasOwnProperty(2));
 
   // ... so they are not affected be delete.
-  assertEquals(array[0], at0);
+  assertEquals(array[0], undefined);
   assertEquals(array[1], undefined);
-  assertEquals(array[2], at2);
+  assertEquals(array[2], undefined);
 })();
 
 
@@ -115,9 +113,7 @@
   assertTrue(delete Array.prototype[7]);
 })();
 
-// Check that unshift with no args has a side-effect of
-// filling the holes with elements from the prototype
-// (if present, of course)
+// Check that unshift with no args has no side-effects.
 (function() {
   var len = 3;
   var array = new Array(len);
@@ -142,12 +138,12 @@
 
   assertEquals(len, array.unshift());
 
-  // unshift makes array own 0 and 2...
-  assertTrue(array.hasOwnProperty(0));
+  // array still owns nothing.
+  assertFalse(array.hasOwnProperty(0));
   assertFalse(array.hasOwnProperty(1));
-  assertTrue(array.hasOwnProperty(2));
+  assertFalse(array.hasOwnProperty(2));
 
-  // ... so they are not affected be delete.
+  // ... but still sees values from array_proto.
   assertEquals(array[0], at0);
   assertEquals(array[1], undefined);
   assertEquals(array[2], at2);
diff --git a/test/mjsunit/asm/do-while-false.js b/test/mjsunit/asm/do-while-false.js
new file mode 100644
index 0000000..ba906a0
--- /dev/null
+++ b/test/mjsunit/asm/do-while-false.js
@@ -0,0 +1,78 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module() {
+  "use asm";
+
+  function d0() {
+    do { } while(false);
+    return 110;
+  }
+
+  function d1() {
+    do { return 111; } while(false);
+    return 112;
+  }
+
+  function d2() {
+    do { break; } while(false);
+    return 113;
+  }
+
+  function d3(a) {
+    a = a | 0;
+    do { if (a) return 114; } while(false);
+    return 115;
+  }
+
+  function d4(a) {
+    a = a | 0;
+    do { if (a) return 116; else break; } while(false);
+    return 117;
+  }
+
+  function d5(a) {
+    a = a | 0;
+    do { if (a) return 118; } while(false);
+    return 119;
+  }
+
+  function d6(a) {
+    a = a | 0;
+    do {
+      if (a == 0) return 120;
+      if (a == 1) break;
+      if (a == 2) return 122;
+      if (a == 3) continue;
+      if (a == 4) return 124;
+    } while(false);
+    return 125;
+  }
+
+  return {d0: d0, d1: d1, d2: d2, d3: d3, d4: d4, d5: d5, d6: d6};
+}
+
+var m = Module();
+
+assertEquals(110, m.d0());
+
+assertEquals(111, m.d1());
+
+assertEquals(113, m.d2());
+
+assertEquals(114, m.d3(1));
+assertEquals(115, m.d3(0));
+
+assertEquals(116, m.d4(1));
+assertEquals(117, m.d4(0));
+
+assertEquals(118, m.d5(1));
+assertEquals(119, m.d5(0));
+
+assertEquals(120, m.d6(0));
+assertEquals(125, m.d6(1));
+assertEquals(122, m.d6(2));
+assertEquals(125, m.d6(3));
+assertEquals(124, m.d6(4));
+assertEquals(125, m.d6(5));
diff --git a/test/mjsunit/asm/do-while.js b/test/mjsunit/asm/do-while.js
new file mode 100644
index 0000000..214be64
--- /dev/null
+++ b/test/mjsunit/asm/do-while.js
@@ -0,0 +1,30 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, buffer) {
+  "use asm";
+  function f(i) {
+    var j;
+    i = i|0;
+    do {
+      if (i > 0) {
+        j = i != 0;
+        i = (i - 1) | 0;
+      } else {
+        j = 0;
+      }
+    } while (j);
+    return i;
+  }
+  return {f:f};
+}
+
+var m = Module(this, {}, new ArrayBuffer(64*1024));
+
+assertEquals(-1, m.f("-1"));
+assertEquals(0, m.f(-Math.infinity));
+assertEquals(0, m.f(undefined));
+assertEquals(0, m.f(0));
+assertEquals(0, m.f(1));
+assertEquals(0, m.f(100));
diff --git a/test/mjsunit/asm/embenchen/box2d.js b/test/mjsunit/asm/embenchen/box2d.js
new file mode 100644
index 0000000..9bb029e
--- /dev/null
+++ b/test/mjsunit/asm/embenchen/box2d.js
@@ -0,0 +1,20322 @@
+var EXPECTED_OUTPUT =
+  /frame averages: .+ \+- .+, range: .+ to .+ \n/;
+var Module = {
+  arguments: [1],
+  print: function(x) {Module.printBuffer += x + '\n';},
+  preRun: [function() {Module.printBuffer = ''}],
+  postRun: [function() {
+    assertTrue(EXPECTED_OUTPUT.test(Module.printBuffer));
+  }],
+};
+// The Module object: Our interface to the outside world. We import
+// and export values on it, and do the work to get that through
+// closure compiler if necessary. There are various ways Module can be used:
+// 1. Not defined. We create it here
+// 2. A function parameter, function(Module) { ..generated code.. }
+// 3. pre-run appended it, var Module = {}; ..generated code..
+// 4. External script tag defines var Module.
+// We need to do an eval in order to handle the closure compiler
+// case, where this code here is minified but Module was defined
+// elsewhere (e.g. case 4 above). We also need to check if Module
+// already exists (e.g. case 3 above).
+// Note that if you want to run closure, and also to use Module
+// after the generated code, you will need to define   var Module = {};
+// before the code. Then that object will be used in the code, and you
+// can continue to use Module afterwards as well.
+var Module;
+if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {};
+
+// Sometimes an existing Module object exists with properties
+// meant to overwrite the default module functionality. Here
+// we collect those properties and reapply _after_ we configure
+// the current environment's defaults to avoid having to be so
+// defensive during initialization.
+var moduleOverrides = {};
+for (var key in Module) {
+  if (Module.hasOwnProperty(key)) {
+    moduleOverrides[key] = Module[key];
+  }
+}
+
+// The environment setup code below is customized to use Module.
+// *** Environment setup code ***
+var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
+var ENVIRONMENT_IS_WEB = typeof window === 'object';
+var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
+var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
+
+if (ENVIRONMENT_IS_NODE) {
+  // Expose functionality in the same simple way that the shells work
+  // Note that we pollute the global namespace here, otherwise we break in node
+  if (!Module['print']) Module['print'] = function print(x) {
+    process['stdout'].write(x + '\n');
+  };
+  if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+    process['stderr'].write(x + '\n');
+  };
+
+  var nodeFS = require('fs');
+  var nodePath = require('path');
+
+  Module['read'] = function read(filename, binary) {
+    filename = nodePath['normalize'](filename);
+    var ret = nodeFS['readFileSync'](filename);
+    // The path is absolute if the normalized version is the same as the resolved.
+    if (!ret && filename != nodePath['resolve'](filename)) {
+      filename = path.join(__dirname, '..', 'src', filename);
+      ret = nodeFS['readFileSync'](filename);
+    }
+    if (ret && !binary) ret = ret.toString();
+    return ret;
+  };
+
+  Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) };
+
+  Module['load'] = function load(f) {
+    globalEval(read(f));
+  };
+
+  Module['arguments'] = process['argv'].slice(2);
+
+  module['exports'] = Module;
+}
+else if (ENVIRONMENT_IS_SHELL) {
+  if (!Module['print']) Module['print'] = print;
+  if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
+
+  if (typeof read != 'undefined') {
+    Module['read'] = read;
+  } else {
+    Module['read'] = function read() { throw 'no read() available (jsc?)' };
+  }
+
+  Module['readBinary'] = function readBinary(f) {
+    return read(f, 'binary');
+  };
+
+  if (typeof scriptArgs != 'undefined') {
+    Module['arguments'] = scriptArgs;
+  } else if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  this['Module'] = Module;
+
+  eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly)
+}
+else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+  Module['read'] = function read(url) {
+    var xhr = new XMLHttpRequest();
+    xhr.open('GET', url, false);
+    xhr.send(null);
+    return xhr.responseText;
+  };
+
+  if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  if (typeof console !== 'undefined') {
+    if (!Module['print']) Module['print'] = function print(x) {
+      console.log(x);
+    };
+    if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+      console.log(x);
+    };
+  } else {
+    // Probably a worker, and without console.log. We can do very little here...
+    var TRY_USE_DUMP = false;
+    if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
+      dump(x);
+    }) : (function(x) {
+      // self.postMessage(x); // enable this if you want stdout to be sent as messages
+    }));
+  }
+
+  if (ENVIRONMENT_IS_WEB) {
+    window['Module'] = Module;
+  } else {
+    Module['load'] = importScripts;
+  }
+}
+else {
+  // Unreachable because SHELL is dependant on the others
+  throw 'Unknown runtime environment. Where are we?';
+}
+
+function globalEval(x) {
+  eval.call(null, x);
+}
+if (!Module['load'] == 'undefined' && Module['read']) {
+  Module['load'] = function load(f) {
+    globalEval(Module['read'](f));
+  };
+}
+if (!Module['print']) {
+  Module['print'] = function(){};
+}
+if (!Module['printErr']) {
+  Module['printErr'] = Module['print'];
+}
+if (!Module['arguments']) {
+  Module['arguments'] = [];
+}
+// *** Environment setup code ***
+
+// Closure helpers
+Module.print = Module['print'];
+Module.printErr = Module['printErr'];
+
+// Callbacks
+Module['preRun'] = [];
+Module['postRun'] = [];
+
+// Merge back in the overrides
+for (var key in moduleOverrides) {
+  if (moduleOverrides.hasOwnProperty(key)) {
+    Module[key] = moduleOverrides[key];
+  }
+}
+
+
+
+// === Auto-generated preamble library stuff ===
+
+//========================================
+// Runtime code shared with compiler
+//========================================
+
+var Runtime = {
+  stackSave: function () {
+    return STACKTOP;
+  },
+  stackRestore: function (stackTop) {
+    STACKTOP = stackTop;
+  },
+  forceAlign: function (target, quantum) {
+    quantum = quantum || 4;
+    if (quantum == 1) return target;
+    if (isNumber(target) && isNumber(quantum)) {
+      return Math.ceil(target/quantum)*quantum;
+    } else if (isNumber(quantum) && isPowerOfTwo(quantum)) {
+      return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')';
+    }
+    return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
+  },
+  isNumberType: function (type) {
+    return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
+  },
+  isPointerType: function isPointerType(type) {
+  return type[type.length-1] == '*';
+},
+  isStructType: function isStructType(type) {
+  if (isPointerType(type)) return false;
+  if (isArrayType(type)) return true;
+  if (/<?\{ ?[^}]* ?\}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types
+  // See comment in isStructPointerType()
+  return type[0] == '%';
+},
+  INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
+  FLOAT_TYPES: {"float":0,"double":0},
+  or64: function (x, y) {
+    var l = (x | 0) | (y | 0);
+    var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  and64: function (x, y) {
+    var l = (x | 0) & (y | 0);
+    var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  xor64: function (x, y) {
+    var l = (x | 0) ^ (y | 0);
+    var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  getNativeTypeSize: function (type) {
+    switch (type) {
+      case 'i1': case 'i8': return 1;
+      case 'i16': return 2;
+      case 'i32': return 4;
+      case 'i64': return 8;
+      case 'float': return 4;
+      case 'double': return 8;
+      default: {
+        if (type[type.length-1] === '*') {
+          return Runtime.QUANTUM_SIZE; // A pointer
+        } else if (type[0] === 'i') {
+          var bits = parseInt(type.substr(1));
+          assert(bits % 8 === 0);
+          return bits/8;
+        } else {
+          return 0;
+        }
+      }
+    }
+  },
+  getNativeFieldSize: function (type) {
+    return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE);
+  },
+  dedup: function dedup(items, ident) {
+  var seen = {};
+  if (ident) {
+    return items.filter(function(item) {
+      if (seen[item[ident]]) return false;
+      seen[item[ident]] = true;
+      return true;
+    });
+  } else {
+    return items.filter(function(item) {
+      if (seen[item]) return false;
+      seen[item] = true;
+      return true;
+    });
+  }
+},
+  set: function set() {
+  var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
+  var ret = {};
+  for (var i = 0; i < args.length; i++) {
+    ret[args[i]] = 0;
+  }
+  return ret;
+},
+  STACK_ALIGN: 8,
+  getAlignSize: function (type, size, vararg) {
+    // we align i64s and doubles on 64-bit boundaries, unlike x86
+    if (!vararg && (type == 'i64' || type == 'double')) return 8;
+    if (!type) return Math.min(size, 8); // align structures internally to 64 bits
+    return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE);
+  },
+  calculateStructAlignment: function calculateStructAlignment(type) {
+    type.flatSize = 0;
+    type.alignSize = 0;
+    var diffs = [];
+    var prev = -1;
+    var index = 0;
+    type.flatIndexes = type.fields.map(function(field) {
+      index++;
+      var size, alignSize;
+      if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
+        size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
+        alignSize = Runtime.getAlignSize(field, size);
+      } else if (Runtime.isStructType(field)) {
+        if (field[1] === '0') {
+          // this is [0 x something]. When inside another structure like here, it must be at the end,
+          // and it adds no size
+          // XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!');
+          size = 0;
+          if (Types.types[field]) {
+            alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+          } else {
+            alignSize = type.alignSize || QUANTUM_SIZE;
+          }
+        } else {
+          size = Types.types[field].flatSize;
+          alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+        }
+      } else if (field[0] == 'b') {
+        // bN, large number field, like a [N x i8]
+        size = field.substr(1)|0;
+        alignSize = 1;
+      } else if (field[0] === '<') {
+        // vector type
+        size = alignSize = Types.types[field].flatSize; // fully aligned
+      } else if (field[0] === 'i') {
+        // illegal integer field, that could not be legalized because it is an internal structure field
+        // it is ok to have such fields, if we just use them as markers of field size and nothing more complex
+        size = alignSize = parseInt(field.substr(1))/8;
+        assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field);
+      } else {
+        assert(false, 'invalid type for calculateStructAlignment');
+      }
+      if (type.packed) alignSize = 1;
+      type.alignSize = Math.max(type.alignSize, alignSize);
+      var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
+      type.flatSize = curr + size;
+      if (prev >= 0) {
+        diffs.push(curr-prev);
+      }
+      prev = curr;
+      return curr;
+    });
+    if (type.name_ && type.name_[0] === '[') {
+      // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
+      // allocating a potentially huge array for [999999 x i8] etc.
+      type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
+    }
+    type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
+    if (diffs.length == 0) {
+      type.flatFactor = type.flatSize;
+    } else if (Runtime.dedup(diffs).length == 1) {
+      type.flatFactor = diffs[0];
+    }
+    type.needsFlattening = (type.flatFactor != 1);
+    return type.flatIndexes;
+  },
+  generateStructInfo: function (struct, typeName, offset) {
+    var type, alignment;
+    if (typeName) {
+      offset = offset || 0;
+      type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
+      if (!type) return null;
+      if (type.fields.length != struct.length) {
+        printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo');
+        return null;
+      }
+      alignment = type.flatIndexes;
+    } else {
+      var type = { fields: struct.map(function(item) { return item[0] }) };
+      alignment = Runtime.calculateStructAlignment(type);
+    }
+    var ret = {
+      __size__: type.flatSize
+    };
+    if (typeName) {
+      struct.forEach(function(item, i) {
+        if (typeof item === 'string') {
+          ret[item] = alignment[i] + offset;
+        } else {
+          // embedded struct
+          var key;
+          for (var k in item) key = k;
+          ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
+        }
+      });
+    } else {
+      struct.forEach(function(item, i) {
+        ret[item[1]] = alignment[i];
+      });
+    }
+    return ret;
+  },
+  dynCall: function (sig, ptr, args) {
+    if (args && args.length) {
+      if (!args.splice) args = Array.prototype.slice.call(args);
+      args.splice(0, 0, ptr);
+      return Module['dynCall_' + sig].apply(null, args);
+    } else {
+      return Module['dynCall_' + sig].call(null, ptr);
+    }
+  },
+  functionPointers: [],
+  addFunction: function (func) {
+    for (var i = 0; i < Runtime.functionPointers.length; i++) {
+      if (!Runtime.functionPointers[i]) {
+        Runtime.functionPointers[i] = func;
+        return 2*(1 + i);
+      }
+    }
+    throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
+  },
+  removeFunction: function (index) {
+    Runtime.functionPointers[(index-2)/2] = null;
+  },
+  getAsmConst: function (code, numArgs) {
+    // code is a constant string on the heap, so we can cache these
+    if (!Runtime.asmConstCache) Runtime.asmConstCache = {};
+    var func = Runtime.asmConstCache[code];
+    if (func) return func;
+    var args = [];
+    for (var i = 0; i < numArgs; i++) {
+      args.push(String.fromCharCode(36) + i); // $0, $1 etc
+    }
+    var source = Pointer_stringify(code);
+    if (source[0] === '"') {
+      // tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct
+      if (source.indexOf('"', 1) === source.length-1) {
+        source = source.substr(1, source.length-2);
+      } else {
+        // something invalid happened, e.g. EM_ASM("..code($0)..", input)
+        abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)');
+      }
+    }
+    try {
+      var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node
+    } catch(e) {
+      Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)');
+      throw e;
+    }
+    return Runtime.asmConstCache[code] = evalled;
+  },
+  warnOnce: function (text) {
+    if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
+    if (!Runtime.warnOnce.shown[text]) {
+      Runtime.warnOnce.shown[text] = 1;
+      Module.printErr(text);
+    }
+  },
+  funcWrappers: {},
+  getFuncWrapper: function (func, sig) {
+    assert(sig);
+    if (!Runtime.funcWrappers[func]) {
+      Runtime.funcWrappers[func] = function dynCall_wrapper() {
+        return Runtime.dynCall(sig, func, arguments);
+      };
+    }
+    return Runtime.funcWrappers[func];
+  },
+  UTF8Processor: function () {
+    var buffer = [];
+    var needed = 0;
+    this.processCChar = function (code) {
+      code = code & 0xFF;
+
+      if (buffer.length == 0) {
+        if ((code & 0x80) == 0x00) {        // 0xxxxxxx
+          return String.fromCharCode(code);
+        }
+        buffer.push(code);
+        if ((code & 0xE0) == 0xC0) {        // 110xxxxx
+          needed = 1;
+        } else if ((code & 0xF0) == 0xE0) { // 1110xxxx
+          needed = 2;
+        } else {                            // 11110xxx
+          needed = 3;
+        }
+        return '';
+      }
+
+      if (needed) {
+        buffer.push(code);
+        needed--;
+        if (needed > 0) return '';
+      }
+
+      var c1 = buffer[0];
+      var c2 = buffer[1];
+      var c3 = buffer[2];
+      var c4 = buffer[3];
+      var ret;
+      if (buffer.length == 2) {
+        ret = String.fromCharCode(((c1 & 0x1F) << 6)  | (c2 & 0x3F));
+      } else if (buffer.length == 3) {
+        ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6)  | (c3 & 0x3F));
+      } else {
+        // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+        var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
+                        ((c3 & 0x3F) << 6)  | (c4 & 0x3F);
+        ret = String.fromCharCode(
+          Math.floor((codePoint - 0x10000) / 0x400) + 0xD800,
+          (codePoint - 0x10000) % 0x400 + 0xDC00);
+      }
+      buffer.length = 0;
+      return ret;
+    }
+    this.processJSString = function processJSString(string) {
+      /* TODO: use TextEncoder when present,
+        var encoder = new TextEncoder();
+        encoder['encoding'] = "utf-8";
+        var utf8Array = encoder['encode'](aMsg.data);
+      */
+      string = unescape(encodeURIComponent(string));
+      var ret = [];
+      for (var i = 0; i < string.length; i++) {
+        ret.push(string.charCodeAt(i));
+      }
+      return ret;
+    }
+  },
+  getCompilerSetting: function (name) {
+    throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work';
+  },
+  stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+7)&-8); return ret; },
+  staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = (((STATICTOP)+7)&-8); return ret; },
+  dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = (((DYNAMICTOP)+7)&-8); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; },
+  alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; },
+  makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*(+4294967296))) : ((+((low>>>0)))+((+((high|0)))*(+4294967296)))); return ret; },
+  GLOBAL_BASE: 8,
+  QUANTUM_SIZE: 4,
+  __dummy__: 0
+}
+
+
+Module['Runtime'] = Runtime;
+
+
+
+
+
+
+
+
+
+//========================================
+// Runtime essentials
+//========================================
+
+var __THREW__ = 0; // Used in checking for thrown exceptions.
+
+var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort()
+var EXITSTATUS = 0;
+
+var undef = 0;
+// tempInt is used for 32-bit signed values or smaller. tempBigInt is used
+// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt
+var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat;
+var tempI64, tempI64b;
+var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9;
+
+function assert(condition, text) {
+  if (!condition) {
+    abort('Assertion failed: ' + text);
+  }
+}
+
+var globalScope = this;
+
+// C calling interface. A convenient way to call C functions (in C files, or
+// defined with extern "C").
+//
+// Note: LLVM optimizations can inline and remove functions, after which you will not be
+//       able to call them. Closure can also do so. To avoid that, add your function to
+//       the exports using something like
+//
+//         -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]'
+//
+// @param ident      The name of the C function (note that C++ functions will be name-mangled - use extern "C")
+// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and
+//                   'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit).
+// @param argTypes   An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType,
+//                   except that 'array' is not possible (there is no way for us to know the length of the array)
+// @param args       An array of the arguments to the function, as native JS values (as in returnType)
+//                   Note that string arguments will be stored on the stack (the JS string will become a C string on the stack).
+// @return           The return value, as a native JS value (as in returnType)
+function ccall(ident, returnType, argTypes, args) {
+  return ccallFunc(getCFunc(ident), returnType, argTypes, args);
+}
+Module["ccall"] = ccall;
+
+// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
+function getCFunc(ident) {
+  try {
+    var func = Module['_' + ident]; // closure exported function
+    if (!func) func = eval('_' + ident); // explicit lookup
+  } catch(e) {
+  }
+  assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)');
+  return func;
+}
+
+// Internal function that does a C call using a function, not an identifier
+function ccallFunc(func, returnType, argTypes, args) {
+  var stack = 0;
+  function toC(value, type) {
+    if (type == 'string') {
+      if (value === null || value === undefined || value === 0) return 0; // null string
+      value = intArrayFromString(value);
+      type = 'array';
+    }
+    if (type == 'array') {
+      if (!stack) stack = Runtime.stackSave();
+      var ret = Runtime.stackAlloc(value.length);
+      writeArrayToMemory(value, ret);
+      return ret;
+    }
+    return value;
+  }
+  function fromC(value, type) {
+    if (type == 'string') {
+      return Pointer_stringify(value);
+    }
+    assert(type != 'array');
+    return value;
+  }
+  var i = 0;
+  var cArgs = args ? args.map(function(arg) {
+    return toC(arg, argTypes[i++]);
+  }) : [];
+  var ret = fromC(func.apply(null, cArgs), returnType);
+  if (stack) Runtime.stackRestore(stack);
+  return ret;
+}
+
+// Returns a native JS wrapper for a C function. This is similar to ccall, but
+// returns a function you can call repeatedly in a normal way. For example:
+//
+//   var my_function = cwrap('my_c_function', 'number', ['number', 'number']);
+//   alert(my_function(5, 22));
+//   alert(my_function(99, 12));
+//
+function cwrap(ident, returnType, argTypes) {
+  var func = getCFunc(ident);
+  return function() {
+    return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments));
+  }
+}
+Module["cwrap"] = cwrap;
+
+// Sets a value in memory in a dynamic way at run-time. Uses the
+// type data. This is the same as makeSetValue, except that
+// makeSetValue is done at compile-time and generates the needed
+// code then, whereas this function picks the right code at
+// run-time.
+// Note that setValue and getValue only do *aligned* writes and reads!
+// Note that ccall uses JS types as for defining types, while setValue and
+// getValue need LLVM types ('i8', 'i32') - this is a lower-level operation
+function setValue(ptr, value, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': HEAP8[(ptr)]=value; break;
+      case 'i8': HEAP8[(ptr)]=value; break;
+      case 'i16': HEAP16[((ptr)>>1)]=value; break;
+      case 'i32': HEAP32[((ptr)>>2)]=value; break;
+      case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= (+1) ? (tempDouble > (+0) ? ((Math_min((+(Math_floor((tempDouble)/(+4294967296)))), (+4294967295)))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/(+4294967296))))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
+      case 'float': HEAPF32[((ptr)>>2)]=value; break;
+      case 'double': HEAPF64[((ptr)>>3)]=value; break;
+      default: abort('invalid type for setValue: ' + type);
+    }
+}
+Module['setValue'] = setValue;
+
+// Parallel to setValue.
+function getValue(ptr, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': return HEAP8[(ptr)];
+      case 'i8': return HEAP8[(ptr)];
+      case 'i16': return HEAP16[((ptr)>>1)];
+      case 'i32': return HEAP32[((ptr)>>2)];
+      case 'i64': return HEAP32[((ptr)>>2)];
+      case 'float': return HEAPF32[((ptr)>>2)];
+      case 'double': return HEAPF64[((ptr)>>3)];
+      default: abort('invalid type for setValue: ' + type);
+    }
+  return null;
+}
+Module['getValue'] = getValue;
+
+var ALLOC_NORMAL = 0; // Tries to use _malloc()
+var ALLOC_STACK = 1; // Lives for the duration of the current function call
+var ALLOC_STATIC = 2; // Cannot be freed
+var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
+var ALLOC_NONE = 4; // Do not allocate
+Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
+Module['ALLOC_STACK'] = ALLOC_STACK;
+Module['ALLOC_STATIC'] = ALLOC_STATIC;
+Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
+Module['ALLOC_NONE'] = ALLOC_NONE;
+
+// allocate(): This is for internal use. You can use it yourself as well, but the interface
+//             is a little tricky (see docs right below). The reason is that it is optimized
+//             for multiple syntaxes to save space in generated code. So you should
+//             normally not use allocate(), and instead allocate memory using _malloc(),
+//             initialize it with setValue(), and so forth.
+// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
+//        in *bytes* (note that this is sometimes confusing: the next parameter does not
+//        affect this!)
+// @types: Either an array of types, one for each byte (or 0 if no type at that position),
+//         or a single type which is used for the entire block. This only matters if there
+//         is initial data - if @slab is a number, then this does not matter at all and is
+//         ignored.
+// @allocator: How to allocate memory, see ALLOC_*
+function allocate(slab, types, allocator, ptr) {
+  var zeroinit, size;
+  if (typeof slab === 'number') {
+    zeroinit = true;
+    size = slab;
+  } else {
+    zeroinit = false;
+    size = slab.length;
+  }
+
+  var singleType = typeof types === 'string' ? types : null;
+
+  var ret;
+  if (allocator == ALLOC_NONE) {
+    ret = ptr;
+  } else {
+    ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
+  }
+
+  if (zeroinit) {
+    var ptr = ret, stop;
+    assert((ret & 3) == 0);
+    stop = ret + (size & ~3);
+    for (; ptr < stop; ptr += 4) {
+      HEAP32[((ptr)>>2)]=0;
+    }
+    stop = ret + size;
+    while (ptr < stop) {
+      HEAP8[((ptr++)|0)]=0;
+    }
+    return ret;
+  }
+
+  if (singleType === 'i8') {
+    if (slab.subarray || slab.slice) {
+      HEAPU8.set(slab, ret);
+    } else {
+      HEAPU8.set(new Uint8Array(slab), ret);
+    }
+    return ret;
+  }
+
+  var i = 0, type, typeSize, previousType;
+  while (i < size) {
+    var curr = slab[i];
+
+    if (typeof curr === 'function') {
+      curr = Runtime.getFunctionIndex(curr);
+    }
+
+    type = singleType || types[i];
+    if (type === 0) {
+      i++;
+      continue;
+    }
+
+    if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
+
+    setValue(ret+i, curr, type);
+
+    // no need to look up size unless type changes, so cache it
+    if (previousType !== type) {
+      typeSize = Runtime.getNativeTypeSize(type);
+      previousType = type;
+    }
+    i += typeSize;
+  }
+
+  return ret;
+}
+Module['allocate'] = allocate;
+
+function Pointer_stringify(ptr, /* optional */ length) {
+  // TODO: use TextDecoder
+  // Find the length, and check for UTF while doing so
+  var hasUtf = false;
+  var t;
+  var i = 0;
+  while (1) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    if (t >= 128) hasUtf = true;
+    else if (t == 0 && !length) break;
+    i++;
+    if (length && i == length) break;
+  }
+  if (!length) length = i;
+
+  var ret = '';
+
+  if (!hasUtf) {
+    var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack
+    var curr;
+    while (length > 0) {
+      curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
+      ret = ret ? ret + curr : curr;
+      ptr += MAX_CHUNK;
+      length -= MAX_CHUNK;
+    }
+    return ret;
+  }
+
+  var utf8 = new Runtime.UTF8Processor();
+  for (i = 0; i < length; i++) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    ret += utf8.processCChar(t);
+  }
+  return ret;
+}
+Module['Pointer_stringify'] = Pointer_stringify;
+
+// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF16ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
+    if (codeUnit == 0)
+      return str;
+    ++i;
+    // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
+    str += String.fromCharCode(codeUnit);
+  }
+}
+Module['UTF16ToString'] = UTF16ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF16LE form. The copy will require at most (str.length*2+1)*2 bytes of space in the HEAP.
+function stringToUTF16(str, outPtr) {
+  for(var i = 0; i < str.length; ++i) {
+    // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
+    var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
+    HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP16[(((outPtr)+(str.length*2))>>1)]=0;
+}
+Module['stringToUTF16'] = stringToUTF16;
+
+// Given a pointer 'ptr' to a null-terminated UTF32LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF32ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
+    if (utf32 == 0)
+      return str;
+    ++i;
+    // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
+    if (utf32 >= 0x10000) {
+      var ch = utf32 - 0x10000;
+      str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
+    } else {
+      str += String.fromCharCode(utf32);
+    }
+  }
+}
+Module['UTF32ToString'] = UTF32ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF32LE form. The copy will require at most (str.length+1)*4 bytes of space in the HEAP,
+// but can use less, since str.length does not return the number of characters in the string, but the number of UTF-16 code units in the string.
+function stringToUTF32(str, outPtr) {
+  var iChar = 0;
+  for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) {
+    // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
+    var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate
+    if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
+      var trailSurrogate = str.charCodeAt(++iCodeUnit);
+      codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
+    }
+    HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit;
+    ++iChar;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP32[(((outPtr)+(iChar*4))>>2)]=0;
+}
+Module['stringToUTF32'] = stringToUTF32;
+
+function demangle(func) {
+  var i = 3;
+  // params, etc.
+  var basicTypes = {
+    'v': 'void',
+    'b': 'bool',
+    'c': 'char',
+    's': 'short',
+    'i': 'int',
+    'l': 'long',
+    'f': 'float',
+    'd': 'double',
+    'w': 'wchar_t',
+    'a': 'signed char',
+    'h': 'unsigned char',
+    't': 'unsigned short',
+    'j': 'unsigned int',
+    'm': 'unsigned long',
+    'x': 'long long',
+    'y': 'unsigned long long',
+    'z': '...'
+  };
+  var subs = [];
+  var first = true;
+  function dump(x) {
+    //return;
+    if (x) Module.print(x);
+    Module.print(func);
+    var pre = '';
+    for (var a = 0; a < i; a++) pre += ' ';
+    Module.print (pre + '^');
+  }
+  function parseNested() {
+    i++;
+    if (func[i] === 'K') i++; // ignore const
+    var parts = [];
+    while (func[i] !== 'E') {
+      if (func[i] === 'S') { // substitution
+        i++;
+        var next = func.indexOf('_', i);
+        var num = func.substring(i, next) || 0;
+        parts.push(subs[num] || '?');
+        i = next+1;
+        continue;
+      }
+      if (func[i] === 'C') { // constructor
+        parts.push(parts[parts.length-1]);
+        i += 2;
+        continue;
+      }
+      var size = parseInt(func.substr(i));
+      var pre = size.toString().length;
+      if (!size || !pre) { i--; break; } // counter i++ below us
+      var curr = func.substr(i + pre, size);
+      parts.push(curr);
+      subs.push(curr);
+      i += pre + size;
+    }
+    i++; // skip E
+    return parts;
+  }
+  function parse(rawList, limit, allowVoid) { // main parser
+    limit = limit || Infinity;
+    var ret = '', list = [];
+    function flushList() {
+      return '(' + list.join(', ') + ')';
+    }
+    var name;
+    if (func[i] === 'N') {
+      // namespaced N-E
+      name = parseNested().join('::');
+      limit--;
+      if (limit === 0) return rawList ? [name] : name;
+    } else {
+      // not namespaced
+      if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L'
+      var size = parseInt(func.substr(i));
+      if (size) {
+        var pre = size.toString().length;
+        name = func.substr(i + pre, size);
+        i += pre + size;
+      }
+    }
+    first = false;
+    if (func[i] === 'I') {
+      i++;
+      var iList = parse(true);
+      var iRet = parse(true, 1, true);
+      ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>';
+    } else {
+      ret = name;
+    }
+    paramLoop: while (i < func.length && limit-- > 0) {
+      //dump('paramLoop');
+      var c = func[i++];
+      if (c in basicTypes) {
+        list.push(basicTypes[c]);
+      } else {
+        switch (c) {
+          case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer
+          case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference
+          case 'L': { // literal
+            i++; // skip basic type
+            var end = func.indexOf('E', i);
+            var size = end - i;
+            list.push(func.substr(i, size));
+            i += size + 2; // size + 'EE'
+            break;
+          }
+          case 'A': { // array
+            var size = parseInt(func.substr(i));
+            i += size.toString().length;
+            if (func[i] !== '_') throw '?';
+            i++; // skip _
+            list.push(parse(true, 1, true)[0] + ' [' + size + ']');
+            break;
+          }
+          case 'E': break paramLoop;
+          default: ret += '?' + c; break paramLoop;
+        }
+      }
+    }
+    if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void)
+    if (rawList) {
+      if (ret) {
+        list.push(ret + '?');
+      }
+      return list;
+    } else {
+      return ret + flushList();
+    }
+  }
+  try {
+    // Special-case the entry point, since its name differs from other name mangling.
+    if (func == 'Object._main' || func == '_main') {
+      return 'main()';
+    }
+    if (typeof func === 'number') func = Pointer_stringify(func);
+    if (func[0] !== '_') return func;
+    if (func[1] !== '_') return func; // C function
+    if (func[2] !== 'Z') return func;
+    switch (func[3]) {
+      case 'n': return 'operator new()';
+      case 'd': return 'operator delete()';
+    }
+    return parse();
+  } catch(e) {
+    return func;
+  }
+}
+
+function demangleAll(text) {
+  return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') });
+}
+
+function stackTrace() {
+  var stack = new Error().stack;
+  return stack ? demangleAll(stack) : '(no stack trace available)'; // Stack trace is not available at least on IE10 and Safari 6.
+}
+
+// Memory management
+
+var PAGE_SIZE = 4096;
+function alignMemoryPage(x) {
+  return (x+4095)&-4096;
+}
+
+var HEAP;
+var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
+
+var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area
+var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area
+var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk
+
+function enlargeMemory() {
+  abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
+}
+
+var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880;
+var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 134217728;
+var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152;
+
+var totalMemory = 4096;
+while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) {
+  if (totalMemory < 16*1024*1024) {
+    totalMemory *= 2;
+  } else {
+    totalMemory += 16*1024*1024
+  }
+}
+if (totalMemory !== TOTAL_MEMORY) {
+  Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be more reasonable');
+  TOTAL_MEMORY = totalMemory;
+}
+
+// Initialize the runtime's memory
+// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
+assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
+       'JS engine does not provide full typed array support');
+
+var buffer = new ArrayBuffer(TOTAL_MEMORY);
+HEAP8 = new Int8Array(buffer);
+HEAP16 = new Int16Array(buffer);
+HEAP32 = new Int32Array(buffer);
+HEAPU8 = new Uint8Array(buffer);
+HEAPU16 = new Uint16Array(buffer);
+HEAPU32 = new Uint32Array(buffer);
+HEAPF32 = new Float32Array(buffer);
+HEAPF64 = new Float64Array(buffer);
+
+// Endianness check (note: assumes compiler arch was little-endian)
+HEAP32[0] = 255;
+assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
+
+Module['HEAP'] = HEAP;
+Module['HEAP8'] = HEAP8;
+Module['HEAP16'] = HEAP16;
+Module['HEAP32'] = HEAP32;
+Module['HEAPU8'] = HEAPU8;
+Module['HEAPU16'] = HEAPU16;
+Module['HEAPU32'] = HEAPU32;
+Module['HEAPF32'] = HEAPF32;
+Module['HEAPF64'] = HEAPF64;
+
+function callRuntimeCallbacks(callbacks) {
+  while(callbacks.length > 0) {
+    var callback = callbacks.shift();
+    if (typeof callback == 'function') {
+      callback();
+      continue;
+    }
+    var func = callback.func;
+    if (typeof func === 'number') {
+      if (callback.arg === undefined) {
+        Runtime.dynCall('v', func);
+      } else {
+        Runtime.dynCall('vi', func, [callback.arg]);
+      }
+    } else {
+      func(callback.arg === undefined ? null : callback.arg);
+    }
+  }
+}
+
+var __ATPRERUN__  = []; // functions called before the runtime is initialized
+var __ATINIT__    = []; // functions called during startup
+var __ATMAIN__    = []; // functions called when main() is to be run
+var __ATEXIT__    = []; // functions called during shutdown
+var __ATPOSTRUN__ = []; // functions called after the runtime has exited
+
+var runtimeInitialized = false;
+
+function preRun() {
+  // compatibility - merge in anything from Module['preRun'] at this time
+  if (Module['preRun']) {
+    if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
+    while (Module['preRun'].length) {
+      addOnPreRun(Module['preRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPRERUN__);
+}
+
+function ensureInitRuntime() {
+  if (runtimeInitialized) return;
+  runtimeInitialized = true;
+  callRuntimeCallbacks(__ATINIT__);
+}
+
+function preMain() {
+  callRuntimeCallbacks(__ATMAIN__);
+}
+
+function exitRuntime() {
+  callRuntimeCallbacks(__ATEXIT__);
+}
+
+function postRun() {
+  // compatibility - merge in anything from Module['postRun'] at this time
+  if (Module['postRun']) {
+    if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
+    while (Module['postRun'].length) {
+      addOnPostRun(Module['postRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPOSTRUN__);
+}
+
+function addOnPreRun(cb) {
+  __ATPRERUN__.unshift(cb);
+}
+Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun;
+
+function addOnInit(cb) {
+  __ATINIT__.unshift(cb);
+}
+Module['addOnInit'] = Module.addOnInit = addOnInit;
+
+function addOnPreMain(cb) {
+  __ATMAIN__.unshift(cb);
+}
+Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain;
+
+function addOnExit(cb) {
+  __ATEXIT__.unshift(cb);
+}
+Module['addOnExit'] = Module.addOnExit = addOnExit;
+
+function addOnPostRun(cb) {
+  __ATPOSTRUN__.unshift(cb);
+}
+Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun;
+
+// Tools
+
+// This processes a JS string into a C-line array of numbers, 0-terminated.
+// For LLVM-originating strings, see parser.js:parseLLVMString function
+function intArrayFromString(stringy, dontAddNull, length /* optional */) {
+  var ret = (new Runtime.UTF8Processor()).processJSString(stringy);
+  if (length) {
+    ret.length = length;
+  }
+  if (!dontAddNull) {
+    ret.push(0);
+  }
+  return ret;
+}
+Module['intArrayFromString'] = intArrayFromString;
+
+function intArrayToString(array) {
+  var ret = [];
+  for (var i = 0; i < array.length; i++) {
+    var chr = array[i];
+    if (chr > 0xFF) {
+      chr &= 0xFF;
+    }
+    ret.push(String.fromCharCode(chr));
+  }
+  return ret.join('');
+}
+Module['intArrayToString'] = intArrayToString;
+
+// Write a Javascript array to somewhere in the heap
+function writeStringToMemory(string, buffer, dontAddNull) {
+  var array = intArrayFromString(string, dontAddNull);
+  var i = 0;
+  while (i < array.length) {
+    var chr = array[i];
+    HEAP8[(((buffer)+(i))|0)]=chr;
+    i = i + 1;
+  }
+}
+Module['writeStringToMemory'] = writeStringToMemory;
+
+function writeArrayToMemory(array, buffer) {
+  for (var i = 0; i < array.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=array[i];
+  }
+}
+Module['writeArrayToMemory'] = writeArrayToMemory;
+
+function writeAsciiToMemory(str, buffer, dontAddNull) {
+  for (var i = 0; i < str.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=str.charCodeAt(i);
+  }
+  if (!dontAddNull) HEAP8[(((buffer)+(str.length))|0)]=0;
+}
+Module['writeAsciiToMemory'] = writeAsciiToMemory;
+
+function unSign(value, bits, ignore) {
+  if (value >= 0) {
+    return value;
+  }
+  return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
+                    : Math.pow(2, bits)         + value;
+}
+function reSign(value, bits, ignore) {
+  if (value <= 0) {
+    return value;
+  }
+  var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
+                        : Math.pow(2, bits-1);
+  if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
+                                                       // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
+                                                       // TODO: In i64 mode 1, resign the two parts separately and safely
+    value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
+  }
+  return value;
+}
+
+// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
+if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) {
+  var ah  = a >>> 16;
+  var al = a & 0xffff;
+  var bh  = b >>> 16;
+  var bl = b & 0xffff;
+  return (al*bl + ((ah*bl + al*bh) << 16))|0;
+};
+Math.imul = Math['imul'];
+
+
+var Math_abs = Math.abs;
+var Math_cos = Math.cos;
+var Math_sin = Math.sin;
+var Math_tan = Math.tan;
+var Math_acos = Math.acos;
+var Math_asin = Math.asin;
+var Math_atan = Math.atan;
+var Math_atan2 = Math.atan2;
+var Math_exp = Math.exp;
+var Math_log = Math.log;
+var Math_sqrt = Math.sqrt;
+var Math_ceil = Math.ceil;
+var Math_floor = Math.floor;
+var Math_pow = Math.pow;
+var Math_imul = Math.imul;
+var Math_fround = Math.fround;
+var Math_min = Math.min;
+
+// A counter of dependencies for calling run(). If we need to
+// do asynchronous work before running, increment this and
+// decrement it. Incrementing must happen in a place like
+// PRE_RUN_ADDITIONS (used by emcc to add file preloading).
+// Note that you can add dependencies in preRun, even though
+// it happens right before run - run will be postponed until
+// the dependencies are met.
+var runDependencies = 0;
+var runDependencyWatcher = null;
+var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
+
+function addRunDependency(id) {
+  runDependencies++;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+}
+Module['addRunDependency'] = addRunDependency;
+function removeRunDependency(id) {
+  runDependencies--;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+  if (runDependencies == 0) {
+    if (runDependencyWatcher !== null) {
+      clearInterval(runDependencyWatcher);
+      runDependencyWatcher = null;
+    }
+    if (dependenciesFulfilled) {
+      var callback = dependenciesFulfilled;
+      dependenciesFulfilled = null;
+      callback(); // can add another dependenciesFulfilled
+    }
+  }
+}
+Module['removeRunDependency'] = removeRunDependency;
+
+Module["preloadedImages"] = {}; // maps url to image data
+Module["preloadedAudios"] = {}; // maps url to audio data
+
+
+var memoryInitializer = null;
+
+// === Body ===
+var __ZTVN10__cxxabiv117__class_type_infoE = 7024;
+var __ZTVN10__cxxabiv120__si_class_type_infoE = 7064;
+
+
+
+
+STATIC_BASE = 8;
+
+STATICTOP = STATIC_BASE + Runtime.alignMemory(7731);
+/* global initializers */ __ATINIT__.push();
+
+
+/* memory initializer */ allocate([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,232,118,72,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,114,114,111,114,58,32,37,100,92,110,0,0,0,0,0,102,114,97,109,101,32,97,118,101,114,97,103,101,115,58,32,37,46,51,102,32,43,45,32,37,46,51,102,44,32,114,97,110,103,101,58,32,37,46,51,102,32,116,111,32,37,46,51,102,32,10,0,0,0,0,0,105,102,32,40,77,111,100,117,108,101,46,114,101,112,111,114,116,67,111,109,112,108,101,116,105,111,110,41,32,77,111,100,117,108,101,46,114,101,112,111,114,116,67,111,109,112,108,101,116,105,111,110,40,41,0,0,114,101,115,112,111,110,115,105,118,101,32,109,97,105,110,32,108,111,111,112,0,0,0,0,0,0,0,0,56,1,0,0,1,0,0,0,2,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,49,49,98,50,69,100,103,101,83,104,97,112,101,0,0,0,55,98,50,83,104,97,112,101,0,0,0,0,0,0,0,0,120,27,0,0,32,1,0,0,160,27,0,0,16,1,0,0,48,1,0,0,0,0,0,0,66,111,120,50,68,47,67,111,108,108,105,115,105,111,110,47,83,104,97,112,101,115,47,98,50,80,111,108,121,103,111,110,83,104,97,112,101,46,99,112,112,0,0,0,0,0,0,0,48,46,48,102,32,60,61,32,108,111,119,101,114,32,38,38,32,108,111,119,101,114,32,60,61,32,105,110,112,117,116,46,109,97,120,70,114,97,99,116,105,111,110,0,0,0,0,0,82,97,121,67,97,115,116,0,109,95,118,101,114,116,101,120,67,111,117,110,116,32,62,61,32,51,0,0,0,0,0,0,67,111,109,112,117,116,101,77,97,115,115,0,0,0,0,0,97,114,101,97,32,62,32,49,46,49,57,50,48,57,50,57,48,101,45,48,55,70,0,0,0,0,0,0,48,2,0,0,3,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,49,52,98,50,80,111,108,121,103,111,110,83,104,97,112,101,0,0,0,0,0,0,0,0,160,27,0,0,24,2,0,0,48,1,0,0,0,0,0,0,16,0,0,0,32,0,0,0,64,0,0,0,96,0,0,0,128,0,0,0,160,0,0,0,192,0,0,0,224,0,0,0,0,1,0,0,64,1,0,0,128,1,0,0,192,1,0,0,0,2,0,0,128,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,106,32,60,32,98,50,95,98,108,111,99,107,83,105,122,101,115,0,0,0,0,0,0,0,66,111,120,50,68,47,67,111,109,109,111,110,47,98,50,66,108,111,99,107,65,108,108,111,99,97,116,111,114,46,99,112,112,0,0,0,0,0,0,0,98,50,66,108,111,99,107,65,108,108,111,99,97,116,111,114,0,0,0,0,0,0,0,0,48,32,60,32,115,105,122,101,0,0,0,0,0,0,0,0,65,108,108,111,99,97,116,101,0,0,0,0,0,0,0,0,48,32,60,61,32,105,110,100,101,120,32,38,38,32,105,110,100,101,120,32,60,32,98,50,95,98,108,111,99,107,83,105,122,101,115,0,0,0,0,0,98,108,111,99,107,67,111,117,110,116,32,42,32,98,108,111,99,107,83,105,122,101,32,60,61,32,98,50,95,99,104,117,110,107,83,105,122,101,0,0,70,114,101,101,0,0,0,0,98,100,45,62,112,111,115,105,116,105,111,110,46,73,115,86,97,108,105,100,40,41,0,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,98,50,66,111,100,121,46,99,112,112,0,0,0,0,0,0,0,98,50,66,111,100,121,0,0,98,100,45,62,108,105,110,101,97,114,86,101,108,111,99,105,116,121,46,73,115,86,97,108,105,100,40,41,0,0,0,0,98,50,73,115,86,97,108,105,100,40,98,100,45,62,97,110,103,108,101,41,0,0,0,0,98,50,73,115,86,97,108,105,100,40,98,100,45,62,97,110,103,117,108,97,114,86,101,108,111,99,105,116,121,41,0,0,98,50,73,115,86,97,108,105,100,40,98,100,45,62,97,110,103,117,108,97,114,68,97,109,112,105,110,103,41,32,38,38,32,98,100,45,62,97,110,103,117,108,97,114,68,97,109,112,105,110,103,32,62,61,32,48,46,48,102,0,0,0,0,0,98,50,73,115,86,97,108,105,100,40,98,100,45,62,108,105,110,101,97,114,68,97,109,112,105,110,103,41,32,38,38,32,98,100,45,62,108,105,110,101,97,114,68,97,109,112,105,110,103,32,62,61,32,48,46,48,102,0,0,0,0,0,0,0,109,95,119,111,114,108,100,45,62,73,115,76,111,99,107,101,100,40,41,32,61,61,32,102,97,108,115,101,0,0,0,0,67,114,101,97,116,101,70,105,120,116,117,114,101,0,0,0,109,95,116,121,112,101,32,61,61,32,98,50,95,100,121,110,97,109,105,99,66,111,100,121,0,0,0,0,0,0,0,0,82,101,115,101,116,77,97,115,115,68,97,116,97,0,0,0,109,95,73,32,62,32,48,46,48,102,0,0,0,0,0,0,0,10,0,0,0,0,0,0,240,7,0,0,0,0,0,0,48,32,60,61,32,112,114,111,120,121,73,100,32,38,38,32,112,114,111,120,121,73,100,32,60,32,109,95,110,111,100,101,67,97,112,97,99,105,116,121,0,0,0,0,0,0,0,0,46,47,66,111,120,50,68,47,67,111,108,108,105,115,105,111,110,47,98,50,68,121,110,97,109,105,99,84,114,101,101,46,104,0,0,0,0,0,0,0,71,101,116,85,115,101,114,68,97,116,97,0,0,0,0,0,71,101,116,70,97,116,65,65,66,66,0,0,0,0,0,0,0,0,0,0,32,8,0,0,5,0,0,0,6,0,0,0,1,0,0,0,2,0,0,0,1,0,0,0,2,0,0,0,49,55,98,50,67,111,110,116,97,99,116,76,105,115,116,101,110,101,114,0,0,0,0,0,120,27,0,0,8,8,0,0,109,95,112,114,111,120,121,67,111,117,110,116,32,61,61,32,48,0,0,0,0,0,0,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,98,50,70,105,120,116,117,114,101,46,99,112,112,0,0,0,0,67,114,101,97,116,101,80,114,111,120,105,101,115,0,0,0,73,115,76,111,99,107,101,100,40,41,32,61,61,32,102,97,108,115,101,0,0,0,0,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,98,50,87,111,114,108,100,46,99,112,112,0,0,0,0,0,0,67,114,101,97,116,101,66,111,100,121,0,0,0,0,0,0,98,45,62,73,115,65,99,116,105,118,101,40,41,32,61,61,32,116,114,117,101,0,0,0,83,111,108,118,101,0,0,0,115,116,97,99,107,67,111,117,110,116,32,60,32,115,116,97,99,107,83,105,122,101,0,0,116,121,112,101,65,32,61,61,32,98,50,95,100,121,110,97,109,105,99,66,111,100,121,32,124,124,32,116,121,112,101,66,32,61,61,32,98,50,95,100,121,110,97,109,105,99,66,111,100,121,0,0,0,0,0,0,83,111,108,118,101,84,79,73,0,0,0,0,0,0,0,0,97,108,112,104,97,48,32,60,32,49,46,48,102,0,0,0,46,47,66,111,120,50,68,47,67,111,109,109,111,110,47,98,50,77,97,116,104,46,104,0,65,100,118,97,110,99,101,0,109,95,106,111,105,110,116,67,111,117,110,116,32,60,32,109,95,106,111,105,110,116,67,97,112,97,99,105,116,121,0,0,46,47,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,98,50,73,115,108,97,110,100,46,104,0,0,0,0,0,65,100,100,0,0,0,0,0,109,95,99,111,110,116,97,99,116,67,111,117,110,116,32,60,32,109,95,99,111,110,116,97,99,116,67,97,112,97,99,105,116,121,0,0,0,0,0,0,109,95,98,111,100,121,67,111,117,110,116,32,60,32,109,95,98,111,100,121,67,97,112,97,99,105,116,121,0,0,0,0,0,0,0,0,40,10,0,0,7,0,0,0,8,0,0,0,3,0,0,0,0,0,0,0,49,53,98,50,67,111,110,116,97,99,116,70,105,108,116,101,114,0,0,0,0,0,0,0,120,27,0,0,16,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,32,60,61,32,105,110,100,101,120,32,38,38,32,105,110,100,101,120,32,60,32,99,104,97,105,110,45,62,109,95,99,111,117,110,116,0,0,0,0,66,111,120,50,68,47,67,111,108,108,105,115,105,111,110,47,98,50,68,105,115,116,97,110,99,101,46,99,112,112,0,0,83,101,116,0,0,0,0,0,102,97,108,115,101,0,0,0,98,50,68,105,115,116,97,110,99,101,0,0,0,0,0,0,71,101,116,77,101,116,114,105,99,0,0,0,0,0,0,0,71,101,116,87,105,116,110,101,115,115,80,111,105,110,116,115,0,0,0,0,0,0,0,0,48,32,60,61,32,105,110,100,101,120,32,38,38,32,105,110,100,101,120,32,60,32,109,95,99,111,117,110,116,0,0,0,46,47,66,111,120,50,68,47,67,111,108,108,105,115,105,111,110,47,98,50,68,105,115,116,97,110,99,101,46,104,0,0,71,101,116,86,101,114,116,101,120,0,0,0,0,0,0,0,71,101,116,67,108,111,115,101,115,116,80,111,105,110,116,0,99,97,99,104,101,45,62,99,111,117,110,116,32,60,61,32,51,0,0,0,0,0,0,0,82,101,97,100,67,97,99,104,101,0,0,0,0,0,0,0,109,95,110,111,100,101,67,111,117,110,116,32,61,61,32,109,95,110,111,100,101,67,97,112,97,99,105,116,121,0,0,0,66,111,120,50,68,47,67,111,108,108,105,115,105,111,110,47,98,50,68,121,110,97,109,105,99,84,114,101,101,46,99,112,112,0,0,0,0,0,0,0,65,108,108,111,99,97,116,101,78,111,100,101,0,0,0,0,48,32,60,61,32,110,111,100,101,73,100,32,38,38,32,110,111,100,101,73,100,32,60,32,109,95,110,111,100,101,67,97,112,97,99,105,116,121,0,0,70,114,101,101,78,111,100,101,0,0,0,0,0,0,0,0,48,32,60,32,109,95,110,111,100,101,67,111,117,110,116,0,48,32,60,61,32,112,114,111,120,121,73,100,32,38,38,32,112,114,111,120,121,73,100,32,60,32,109,95,110,111,100,101,67,97,112,97,99,105,116,121,0,0,0,0,0,0,0,0,109,95,110,111,100,101,115,91,112,114,111,120,121,73,100,93,46,73,115,76,101,97,102,40,41,0,0,0,0,0,0,0,77,111,118,101,80,114,111,120,121,0,0,0,0,0,0,0,99,104,105,108,100,49,32,33,61,32,40,45,49,41,0,0,73,110,115,101,114,116,76,101,97,102,0,0,0,0,0,0,99,104,105,108,100,50,32,33,61,32,40,45,49,41,0,0,105,65,32,33,61,32,40,45,49,41,0,0,0,0,0,0,66,97,108,97,110,99,101,0,48,32,60,61,32,105,66,32,38,38,32,105,66,32,60,32,109,95,110,111,100,101,67,97,112,97,99,105,116,121,0,0,48,32,60,61,32,105,67,32,38,38,32,105,67,32,60,32,109,95,110,111,100,101,67,97,112,97,99,105,116,121,0,0,48,32,60,61,32,105,70,32,38,38,32,105,70,32,60,32,109,95,110,111,100,101,67,97,112,97,99,105,116,121,0,0,48,32,60,61,32,105,71,32,38,38,32,105,71,32,60,32,109,95,110,111,100,101,67,97,112,97,99,105,116,121,0,0,109,95,110,111,100,101,115,91,67,45,62,112,97,114,101,110,116,93,46,99,104,105,108,100,50,32,61,61,32,105,65,0,48,32,60,61,32,105,68,32,38,38,32,105,68,32,60,32,109,95,110,111,100,101,67,97,112,97,99,105,116,121,0,0,48,32,60,61,32,105,69,32,38,38,32,105,69,32,60,32,109,95,110,111,100,101,67,97,112,97,99,105,116,121,0,0,109,95,110,111,100,101,115,91,66,45,62,112,97,114,101,110,116,93,46,99,104,105,108,100,50,32,61,61,32,105,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,116,97,114,103,101,116,32,62,32,116,111,108,101,114,97,110,99,101,0,0,0,0,0,0,66,111,120,50,68,47,67,111,108,108,105,115,105,111,110,47,98,50,84,105,109,101,79,102,73,109,112,97,99,116,46,99,112,112,0,0,0,0,0,0,98,50,84,105,109,101,79,102,73,109,112,97,99,116,0,0,102,97,108,115,101,0,0,0,69,118,97,108,117,97,116,101,0,0,0,0,0,0,0,0,48,32,60,61,32,105,110,100,101,120,32,38,38,32,105,110,100,101,120,32,60,32,109,95,99,111,117,110,116,0,0,0,46,47,66,111,120,50,68,47,67,111,108,108,105,115,105,111,110,47,98,50,68,105,115,116,97,110,99,101,46,104,0,0,71,101,116,86,101,114,116,101,120,0,0,0,0,0,0,0,70,105,110,100,77,105,110,83,101,112,97,114,97,116,105,111,110,0,0,0,0,0,0,0,48,32,60,32,99,111,117,110,116,32,38,38,32,99,111,117,110,116,32,60,32,51,0,0,73,110,105,116,105,97,108,105,122,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,109,95,105,110,100,101,120,32,61,61,32,48,0,0,0,0,66,111,120,50,68,47,67,111,109,109,111,110,47,98,50,83,116,97,99,107,65,108,108,111,99,97,116,111,114,46,99,112,112,0,0,0,0,0,0,0,126,98,50,83,116,97,99,107,65,108,108,111,99,97,116,111,114,0,0,0,0,0,0,0,109,95,101,110,116,114,121,67,111,117,110,116,32,61,61,32,48,0,0,0,0,0,0,0,109,95,101,110,116,114,121,67,111,117,110,116,32,60,32,98,50,95,109,97,120,83,116,97,99,107,69,110,116,114,105,101,115,0,0,0,0,0,0,0,65,108,108,111,99,97,116,101,0,0,0,0,0,0,0,0,109,95,101,110,116,114,121,67,111,117,110,116,32,62,32,48,0,0,0,0,0,0,0,0,70,114,101,101,0,0,0,0,112,32,61,61,32,101,110,116,114,121,45,62,100,97,116,97,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,32,60,61,32,116,121,112,101,49,32,38,38,32,116,121,112,101,49,32,60,32,98,50,83,104,97,112,101,58,58,101,95,116,121,112,101,67,111,117,110,116,0,0,0,0,0,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,67,111,110,116,97,99,116,115,47,98,50,67,111,110,116,97,99,116,46,99,112,112,0,0,0,48,32,60,61,32,116,121,112,101,50,32,38,38,32,116,121,112,101,50,32,60,32,98,50,83,104,97,112,101,58,58,101,95,116,121,112,101,67,111,117,110,116,0,0,0,0,0,0,67,114,101,97,116,101,0,0,115,95,105,110,105,116,105,97,108,105,122,101,100,32,61,61,32,116,114,117,101,0,0,0,68,101,115,116,114,111,121,0,48,32,60,61,32,116,121,112,101,65,32,38,38,32,116,121,112,101,66,32,60,32,98,50,83,104,97,112,101,58,58,101,95,116,121,112,101,67,111,117,110,116,0,0,0,0,0,0,0,0,0,0,120,17,0,0,1,0,0,0,9,0,0,0,10,0,0,0,0,0,0,0,57,98,50,67,111,110,116,97,99,116,0,0,0,0,0,0,120,27,0,0,104,17,0,0,0,0,0,0,104,18,0,0,3,0,0,0,11,0,0,0,12,0,0,0,0,0,0,0,109,95,102,105,120,116,117,114,101,65,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,101,100,103,101,0,0,0,0,0,0,0,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,67,111,110,116,97,99,116,115,47,98,50,69,100,103,101,65,110,100,67,105,114,99,108,101,67,111,110,116,97,99,116,46,99,112,112,0,0,0,0,0,0,98,50,69,100,103,101,65,110,100,67,105,114,99,108,101,67,111,110,116,97,99,116,0,0,109,95,102,105,120,116,117,114,101,66,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,99,105,114,99,108,101,0,0,0,0,0,0,50,50,98,50,69,100,103,101,65,110,100,67,105,114,99,108,101,67,111,110,116,97,99,116,0,0,0,0,0,0,0,0,160,27,0,0,72,18,0,0,120,17,0,0,0,0,0,0,0,0,0,0,96,19,0,0,4,0,0,0,13,0,0,0,14,0,0,0,0,0,0,0,109,95,102,105,120,116,117,114,101,65,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,101,100,103,101,0,0,0,0,0,0,0,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,67,111,110,116,97,99,116,115,47,98,50,69,100,103,101,65,110,100,80,111,108,121,103,111,110,67,111,110,116,97,99,116,46,99,112,112,0,0,0,0,0,98,50,69,100,103,101,65,110,100,80,111,108,121,103,111,110,67,111,110,116,97,99,116,0,109,95,102,105,120,116,117,114,101,66,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,112,111,108,121,103,111,110,0,0,0,0,0,50,51,98,50,69,100,103,101,65,110,100,80,111,108,121,103,111,110,67,111,110,116,97,99,116,0,0,0,0,0,0,0,160,27,0,0,64,19,0,0,120,17,0,0,0,0,0,0,0,0,0,0,96,20,0,0,5,0,0,0,15,0,0,0,16,0,0,0,0,0,0,0,109,95,102,105,120,116,117,114,101,65,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,112,111,108,121,103,111,110,0,0,0,0,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,67,111,110,116,97,99,116,115,47,98,50,80,111,108,121,103,111,110,65,110,100,67,105,114,99,108,101,67,111,110,116,97,99,116,46,99,112,112,0,0,0,98,50,80,111,108,121,103,111,110,65,110,100,67,105,114,99,108,101,67,111,110,116,97,99,116,0,0,0,0,0,0,0,109,95,102,105,120,116,117,114,101,66,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,99,105,114,99,108,101,0,0,0,0,0,0,50,53,98,50,80,111,108,121,103,111,110,65,110,100,67,105,114,99,108,101,67,111,110,116,97,99,116,0,0,0,0,0,160,27,0,0,64,20,0,0,120,17,0,0,0,0,0,0,0,0,0,0,72,21,0,0,6,0,0,0,17,0,0,0,18,0,0,0,0,0,0,0,109,95,102,105,120,116,117,114,101,65,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,112,111,108,121,103,111,110,0,0,0,0,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,67,111,110,116,97,99,116,115,47,98,50,80,111,108,121,103,111,110,67,111,110,116,97,99,116,46,99,112,112,0,0,0,0,98,50,80,111,108,121,103,111,110,67,111,110,116,97,99,116,0,0,0,0,0,0,0,0,109,95,102,105,120,116,117,114,101,66,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,112,111,108,121,103,111,110,0,0,0,0,0,49,54,98,50,80,111,108,121,103,111,110,67,111,110,116,97,99,116,0,0,0,0,0,0,160,27,0,0,48,21,0,0,120,17,0,0,0,0,0,0,116,111,105,73,110,100,101,120,65,32,60,32,109,95,98,111,100,121,67,111,117,110,116,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,98,50,73,115,108,97,110,100,46,99,112,112,0,0,0,0,0,83,111,108,118,101,84,79,73,0,0,0,0,0,0,0,0,116,111,105,73,110,100,101,120,66,32,60,32,109,95,98,111,100,121,67,111,117,110,116,0,100,101,110,32,62,32,48,46,48,102,0,0,0,0,0,0,66,111,120,50,68,47,67,111,108,108,105,115,105,111,110,47,98,50,67,111,108,108,105,100,101,69,100,103,101,46,99,112,112,0,0,0,0,0,0,0,98,50,67,111,108,108,105,100,101,69,100,103,101,65,110,100,67,105,114,99,108,101,0,0,48,32,60,61,32,101,100,103,101,49,32,38,38,32,101,100,103,101,49,32,60,32,112,111,108,121,49,45,62,109,95,118,101,114,116,101,120,67,111,117,110,116,0,0,0,0,0,0,66,111,120,50,68,47,67,111,108,108,105,115,105,111,110,47,98,50,67,111,108,108,105,100,101,80,111,108,121,103,111,110,46,99,112,112,0,0,0,0,98,50,70,105,110,100,73,110,99,105,100,101,110,116,69,100,103,101,0,0,0,0,0,0,98,50,69,100,103,101,83,101,112,97,114,97,116,105,111,110,0,0,0,0,0,0,0,0,0,0,0,0,120,23,0,0,7,0,0,0,19,0,0,0,20,0,0,0,0,0,0,0,109,95,102,105,120,116,117,114,101,65,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,99,104,97,105,110,0,0,0,0,0,0,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,67,111,110,116,97,99,116,115,47,98,50,67,104,97,105,110,65,110,100,67,105,114,99,108,101,67,111,110,116,97,99,116,46,99,112,112,0,0,0,0,0,98,50,67,104,97,105,110,65,110,100,67,105,114,99,108,101,67,111,110,116,97,99,116,0,109,95,102,105,120,116,117,114,101,66,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,99,105,114,99,108,101,0,0,0,0,0,0,50,51,98,50,67,104,97,105,110,65,110,100,67,105,114,99,108,101,67,111,110,116,97,99,116,0,0,0,0,0,0,0,160,27,0,0,88,23,0,0,120,17,0,0,0,0,0,0,0,0,0,0,120,24,0,0,8,0,0,0,21,0,0,0,22,0,0,0,0,0,0,0,109,95,102,105,120,116,117,114,101,65,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,99,104,97,105,110,0,0,0,0,0,0,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,67,111,110,116,97,99,116,115,47,98,50,67,104,97,105,110,65,110,100,80,111,108,121,103,111,110,67,111,110,116,97,99,116,46,99,112,112,0,0,0,0,98,50,67,104,97,105,110,65,110,100,80,111,108,121,103,111,110,67,111,110,116,97,99,116,0,0,0,0,0,0,0,0,109,95,102,105,120,116,117,114,101,66,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,112,111,108,121,103,111,110,0,0,0,0,0,50,52,98,50,67,104,97,105,110,65,110,100,80,111,108,121,103,111,110,67,111,110,116,97,99,116,0,0,0,0,0,0,160,27,0,0,88,24,0,0,120,17,0,0,0,0,0,0,0,0,0,0,88,25,0,0,9,0,0,0,23,0,0,0,24,0,0,0,0,0,0,0,109,95,102,105,120,116,117,114,101,65,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,99,105,114,99,108,101,0,0,0,0,0,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,67,111,110,116,97,99,116,115,47,98,50,67,105,114,99,108,101,67,111,110,116,97,99,116,46,99,112,112,0,0,0,0,0,98,50,67,105,114,99,108,101,67,111,110,116,97,99,116,0,109,95,102,105,120,116,117,114,101,66,45,62,71,101,116,84,121,112,101,40,41,32,61,61,32,98,50,83,104,97,112,101,58,58,101,95,99,105,114,99,108,101,0,0,0,0,0,0,49,53,98,50,67,105,114,99,108,101,67,111,110,116,97,99,116,0,0,0,0,0,0,0,160,27,0,0,64,25,0,0,120,17,0,0,0,0,0,0,112,111,105,110,116,67,111,117,110,116,32,62,32,48,0,0,66,111,120,50,68,47,68,121,110,97,109,105,99,115,47,67,111,110,116,97,99,116,115,47,98,50,67,111,110,116,97,99,116,83,111,108,118,101,114,46,99,112,112,0,0,0,0,0,98,50,67,111,110,116,97,99,116,83,111,108,118,101,114,0,109,97,110,105,102,111,108,100,45,62,112,111,105,110,116,67,111,117,110,116,32,62,32,48,0,0,0,0,0,0,0,0,73,110,105,116,105,97,108,105,122,101,86,101,108,111,99,105,116,121,67,111,110,115,116,114,97,105,110,116,115,0,0,0,112,111,105,110,116,67,111,117,110,116,32,61,61,32,49,32,124,124,32,112,111,105,110,116,67,111,117,110,116,32,61,61,32,50,0,0,0,0,0,0,83,111,108,118,101,86,101,108,111,99,105,116,121,67,111,110,115,116,114,97,105,110,116,115,0,0,0,0,0,0,0,0,97,46,120,32,62,61,32,48,46,48,102,32,38,38,32,97,46,121,32,62,61,32,48,46,48,102,0,0,0,0,0,0,112,99,45,62,112,111,105,110,116,67,111,117,110,116,32,62,32,48,0,0,0,0,0,0,73,110,105,116,105,97,108,105,122,101,0,0,0,0,0,0,66,111,120,50,68,47,67,111,108,108,105,115,105,111,110,47,83,104,97,112,101,115,47,98,50,67,104,97,105,110,83,104,97,112,101,46,99,112,112,0,48,32,60,61,32,105,110,100,101,120,32,38,38,32,105,110,100,101,120,32,60,32,109,95,99,111,117,110,116,32,45,32,49,0,0,0,0,0,0,0,71,101,116,67,104,105,108,100,69,100,103,101,0,0,0,0,83,116,57,116,121,112,101,95,105,110,102,111,0,0,0,0,120,27,0,0,232,26,0,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,54,95,95,115,104,105,109,95,116,121,112,101,95,105,110,102,111,69,0,0,0,0,0,0,0,0,160,27,0,0,0,27,0,0,248,26,0,0,0,0,0,0,78,49,48,95,95,99,120,120,97,98,105,118,49,49,55,95,95,99,108,97,115,115,95,116,121,112,101,95,105,110,102,111,69,0,0,0,0,0,0,0,160,27,0,0,56,27,0,0,40,27,0,0,0,0,0,0,0,0,0,0,96,27,0,0,25,0,0,0,26,0,0,0,27,0,0,0,28,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,10,0,0,0,0,0,0,0,232,27,0,0,25,0,0,0,29,0,0,0,27,0,0,0,28,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,11,0,0,0,78,49,48,95,95,99,120,120,97,98,105,118,49,50,48,95,95,115,105,95,99,108,97,115,115,95,116,121,112,101,95,105,110,102,111,69,0,0,0,0,160,27,0,0,192,27,0,0,96,27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40,30,0,0,30,0,0,0,31,0,0,0,3,0,0,0,0,0,0,0,115,116,100,58,58,98,97,100,95,97,108,108,111,99,0,0,83,116,57,98,97,100,95,97,108,108,111,99,0,0,0,0,160,27,0,0,24,30,0,0,0,0,0,0,0,0,0,0], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE);
+
+
+
+
+var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);
+
+assert(tempDoublePtr % 8 == 0);
+
+function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+}
+
+function copyTempDouble(ptr) {
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+  HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];
+
+  HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];
+
+  HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];
+
+  HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];
+
+}
+
+
+  function _emscripten_set_main_loop(func, fps, simulateInfiniteLoop, arg) {
+      Module['noExitRuntime'] = true;
+
+      Browser.mainLoop.runner = function Browser_mainLoop_runner() {
+        if (ABORT) return;
+        if (Browser.mainLoop.queue.length > 0) {
+          var start = Date.now();
+          var blocker = Browser.mainLoop.queue.shift();
+          blocker.func(blocker.arg);
+          if (Browser.mainLoop.remainingBlockers) {
+            var remaining = Browser.mainLoop.remainingBlockers;
+            var next = remaining%1 == 0 ? remaining-1 : Math.floor(remaining);
+            if (blocker.counted) {
+              Browser.mainLoop.remainingBlockers = next;
+            } else {
+              // not counted, but move the progress along a tiny bit
+              next = next + 0.5; // do not steal all the next one's progress
+              Browser.mainLoop.remainingBlockers = (8*remaining + next)/9;
+            }
+          }
+          console.log('main loop blocker "' + blocker.name + '" took ' + (Date.now() - start) + ' ms'); //, left: ' + Browser.mainLoop.remainingBlockers);
+          Browser.mainLoop.updateStatus();
+          setTimeout(Browser.mainLoop.runner, 0);
+          return;
+        }
+        if (Browser.mainLoop.shouldPause) {
+          // catch pauses from non-main loop sources
+          Browser.mainLoop.paused = true;
+          Browser.mainLoop.shouldPause = false;
+          return;
+        }
+
+        // Signal GL rendering layer that processing of a new frame is about to start. This helps it optimize
+        // VBO double-buffering and reduce GPU stalls.
+
+        if (Browser.mainLoop.method === 'timeout' && Module.ctx) {
+          Module.printErr('Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!');
+          Browser.mainLoop.method = ''; // just warn once per call to set main loop
+        }
+
+        if (Module['preMainLoop']) {
+          Module['preMainLoop']();
+        }
+
+        try {
+          if (typeof arg !== 'undefined') {
+            Runtime.dynCall('vi', func, [arg]);
+          } else {
+            Runtime.dynCall('v', func);
+          }
+        } catch (e) {
+          if (e instanceof ExitStatus) {
+            return;
+          } else {
+            if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
+            throw e;
+          }
+        }
+
+        if (Module['postMainLoop']) {
+          Module['postMainLoop']();
+        }
+
+        if (Browser.mainLoop.shouldPause) {
+          // catch pauses from the main loop itself
+          Browser.mainLoop.paused = true;
+          Browser.mainLoop.shouldPause = false;
+          return;
+        }
+        Browser.mainLoop.scheduler();
+      }
+      if (fps && fps > 0) {
+        Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler() {
+          setTimeout(Browser.mainLoop.runner, 1000/fps); // doing this each time means that on exception, we stop
+        };
+        Browser.mainLoop.method = 'timeout';
+      } else {
+        Browser.mainLoop.scheduler = function Browser_mainLoop_scheduler() {
+          Browser.requestAnimationFrame(Browser.mainLoop.runner);
+        };
+        Browser.mainLoop.method = 'rAF';
+      }
+      Browser.mainLoop.scheduler();
+
+      if (simulateInfiniteLoop) {
+        throw 'SimulateInfiniteLoop';
+      }
+    }
+
+  var _cosf=Math_cos;
+
+  function ___cxa_pure_virtual() {
+      ABORT = true;
+      throw 'Pure virtual function called!';
+    }
+
+  function _time(ptr) {
+      var ret = Math.floor(Date.now()/1000);
+      if (ptr) {
+        HEAP32[((ptr)>>2)]=ret;
+      }
+      return ret;
+    }
+
+  function ___assert_fail(condition, filename, line, func) {
+      ABORT = true;
+      throw 'Assertion failed: ' + Pointer_stringify(condition) + ', at: ' + [filename ? Pointer_stringify(filename) : 'unknown filename', line, func ? Pointer_stringify(func) : 'unknown function'] + ' at ' + stackTrace();
+    }
+
+
+  function __ZSt18uncaught_exceptionv() { // std::uncaught_exception()
+      return !!__ZSt18uncaught_exceptionv.uncaught_exception;
+    }
+
+
+
+  function ___cxa_is_number_type(type) {
+      var isNumber = false;
+      try { if (type == __ZTIi) isNumber = true } catch(e){}
+      try { if (type == __ZTIj) isNumber = true } catch(e){}
+      try { if (type == __ZTIl) isNumber = true } catch(e){}
+      try { if (type == __ZTIm) isNumber = true } catch(e){}
+      try { if (type == __ZTIx) isNumber = true } catch(e){}
+      try { if (type == __ZTIy) isNumber = true } catch(e){}
+      try { if (type == __ZTIf) isNumber = true } catch(e){}
+      try { if (type == __ZTId) isNumber = true } catch(e){}
+      try { if (type == __ZTIe) isNumber = true } catch(e){}
+      try { if (type == __ZTIc) isNumber = true } catch(e){}
+      try { if (type == __ZTIa) isNumber = true } catch(e){}
+      try { if (type == __ZTIh) isNumber = true } catch(e){}
+      try { if (type == __ZTIs) isNumber = true } catch(e){}
+      try { if (type == __ZTIt) isNumber = true } catch(e){}
+      return isNumber;
+    }function ___cxa_does_inherit(definiteType, possibilityType, possibility) {
+      if (possibility == 0) return false;
+      if (possibilityType == 0 || possibilityType == definiteType)
+        return true;
+      var possibility_type_info;
+      if (___cxa_is_number_type(possibilityType)) {
+        possibility_type_info = possibilityType;
+      } else {
+        var possibility_type_infoAddr = HEAP32[((possibilityType)>>2)] - 8;
+        possibility_type_info = HEAP32[((possibility_type_infoAddr)>>2)];
+      }
+      switch (possibility_type_info) {
+      case 0: // possibility is a pointer
+        // See if definite type is a pointer
+        var definite_type_infoAddr = HEAP32[((definiteType)>>2)] - 8;
+        var definite_type_info = HEAP32[((definite_type_infoAddr)>>2)];
+        if (definite_type_info == 0) {
+          // Also a pointer; compare base types of pointers
+          var defPointerBaseAddr = definiteType+8;
+          var defPointerBaseType = HEAP32[((defPointerBaseAddr)>>2)];
+          var possPointerBaseAddr = possibilityType+8;
+          var possPointerBaseType = HEAP32[((possPointerBaseAddr)>>2)];
+          return ___cxa_does_inherit(defPointerBaseType, possPointerBaseType, possibility);
+        } else
+          return false; // one pointer and one non-pointer
+      case 1: // class with no base class
+        return false;
+      case 2: // class with base class
+        var parentTypeAddr = possibilityType + 8;
+        var parentType = HEAP32[((parentTypeAddr)>>2)];
+        return ___cxa_does_inherit(definiteType, parentType, possibility);
+      default:
+        return false; // some unencountered type
+      }
+    }
+
+
+
+  var ___cxa_last_thrown_exception=0;function ___resumeException(ptr) {
+      if (!___cxa_last_thrown_exception) { ___cxa_last_thrown_exception = ptr; }
+      throw ptr + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.";
+    }
+
+  var ___cxa_exception_header_size=8;function ___cxa_find_matching_catch(thrown, throwntype) {
+      if (thrown == -1) thrown = ___cxa_last_thrown_exception;
+      header = thrown - ___cxa_exception_header_size;
+      if (throwntype == -1) throwntype = HEAP32[((header)>>2)];
+      var typeArray = Array.prototype.slice.call(arguments, 2);
+
+      // If throwntype is a pointer, this means a pointer has been
+      // thrown. When a pointer is thrown, actually what's thrown
+      // is a pointer to the pointer. We'll dereference it.
+      if (throwntype != 0 && !___cxa_is_number_type(throwntype)) {
+        var throwntypeInfoAddr= HEAP32[((throwntype)>>2)] - 8;
+        var throwntypeInfo= HEAP32[((throwntypeInfoAddr)>>2)];
+        if (throwntypeInfo == 0)
+          thrown = HEAP32[((thrown)>>2)];
+      }
+      // The different catch blocks are denoted by different types.
+      // Due to inheritance, those types may not precisely match the
+      // type of the thrown object. Find one which matches, and
+      // return the type of the catch block which should be called.
+      for (var i = 0; i < typeArray.length; i++) {
+        if (___cxa_does_inherit(typeArray[i], throwntype, thrown))
+          return ((asm["setTempRet0"](typeArray[i]),thrown)|0);
+      }
+      // Shouldn't happen unless we have bogus data in typeArray
+      // or encounter a type for which emscripten doesn't have suitable
+      // typeinfo defined. Best-efforts match just in case.
+      return ((asm["setTempRet0"](throwntype),thrown)|0);
+    }function ___cxa_throw(ptr, type, destructor) {
+      if (!___cxa_throw.initialized) {
+        try {
+          HEAP32[((__ZTVN10__cxxabiv119__pointer_type_infoE)>>2)]=0; // Workaround for libcxxabi integration bug
+        } catch(e){}
+        try {
+          HEAP32[((__ZTVN10__cxxabiv117__class_type_infoE)>>2)]=1; // Workaround for libcxxabi integration bug
+        } catch(e){}
+        try {
+          HEAP32[((__ZTVN10__cxxabiv120__si_class_type_infoE)>>2)]=2; // Workaround for libcxxabi integration bug
+        } catch(e){}
+        ___cxa_throw.initialized = true;
+      }
+      var header = ptr - ___cxa_exception_header_size;
+      HEAP32[((header)>>2)]=type;
+      HEAP32[(((header)+(4))>>2)]=destructor;
+      ___cxa_last_thrown_exception = ptr;
+      if (!("uncaught_exception" in __ZSt18uncaught_exceptionv)) {
+        __ZSt18uncaught_exceptionv.uncaught_exception = 1;
+      } else {
+        __ZSt18uncaught_exceptionv.uncaught_exception++;
+      }
+      throw ptr + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.";
+    }
+
+
+  Module["_memset"] = _memset;
+
+
+
+  function __exit(status) {
+      // void _exit(int status);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html
+      Module['exit'](status);
+    }function _exit(status) {
+      __exit(status);
+    }function __ZSt9terminatev() {
+      _exit(-1234);
+    }
+
+  function _abort() {
+      Module['abort']();
+    }
+
+
+
+
+
+  var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};
+
+  var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can   access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};
+
+
+  var ___errno_state=0;function ___setErrNo(value) {
+      // For convenient setting and returning of errno.
+      HEAP32[((___errno_state)>>2)]=value;
+      return value;
+    }
+
+  var PATH={splitPath:function (filename) {
+        var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+        return splitPathRe.exec(filename).slice(1);
+      },normalizeArray:function (parts, allowAboveRoot) {
+        // if the path tries to go above the root, `up` ends up > 0
+        var up = 0;
+        for (var i = parts.length - 1; i >= 0; i--) {
+          var last = parts[i];
+          if (last === '.') {
+            parts.splice(i, 1);
+          } else if (last === '..') {
+            parts.splice(i, 1);
+            up++;
+          } else if (up) {
+            parts.splice(i, 1);
+            up--;
+          }
+        }
+        // if the path is allowed to go above the root, restore leading ..s
+        if (allowAboveRoot) {
+          for (; up--; up) {
+            parts.unshift('..');
+          }
+        }
+        return parts;
+      },normalize:function (path) {
+        var isAbsolute = path.charAt(0) === '/',
+            trailingSlash = path.substr(-1) === '/';
+        // Normalize the path
+        path = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), !isAbsolute).join('/');
+        if (!path && !isAbsolute) {
+          path = '.';
+        }
+        if (path && trailingSlash) {
+          path += '/';
+        }
+        return (isAbsolute ? '/' : '') + path;
+      },dirname:function (path) {
+        var result = PATH.splitPath(path),
+            root = result[0],
+            dir = result[1];
+        if (!root && !dir) {
+          // No dirname whatsoever
+          return '.';
+        }
+        if (dir) {
+          // It has a dirname, strip trailing slash
+          dir = dir.substr(0, dir.length - 1);
+        }
+        return root + dir;
+      },basename:function (path) {
+        // EMSCRIPTEN return '/'' for '/', not an empty string
+        if (path === '/') return '/';
+        var lastSlash = path.lastIndexOf('/');
+        if (lastSlash === -1) return path;
+        return path.substr(lastSlash+1);
+      },extname:function (path) {
+        return PATH.splitPath(path)[3];
+      },join:function () {
+        var paths = Array.prototype.slice.call(arguments, 0);
+        return PATH.normalize(paths.join('/'));
+      },join2:function (l, r) {
+        return PATH.normalize(l + '/' + r);
+      },resolve:function () {
+        var resolvedPath = '',
+          resolvedAbsolute = false;
+        for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+          var path = (i >= 0) ? arguments[i] : FS.cwd();
+          // Skip empty and invalid entries
+          if (typeof path !== 'string') {
+            throw new TypeError('Arguments to path.resolve must be strings');
+          } else if (!path) {
+            continue;
+          }
+          resolvedPath = path + '/' + resolvedPath;
+          resolvedAbsolute = path.charAt(0) === '/';
+        }
+        // At this point the path should be resolved to a full absolute path, but
+        // handle relative paths to be safe (might happen when process.cwd() fails)
+        resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
+          return !!p;
+        }), !resolvedAbsolute).join('/');
+        return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+      },relative:function (from, to) {
+        from = PATH.resolve(from).substr(1);
+        to = PATH.resolve(to).substr(1);
+        function trim(arr) {
+          var start = 0;
+          for (; start < arr.length; start++) {
+            if (arr[start] !== '') break;
+          }
+          var end = arr.length - 1;
+          for (; end >= 0; end--) {
+            if (arr[end] !== '') break;
+          }
+          if (start > end) return [];
+          return arr.slice(start, end - start + 1);
+        }
+        var fromParts = trim(from.split('/'));
+        var toParts = trim(to.split('/'));
+        var length = Math.min(fromParts.length, toParts.length);
+        var samePartsLength = length;
+        for (var i = 0; i < length; i++) {
+          if (fromParts[i] !== toParts[i]) {
+            samePartsLength = i;
+            break;
+          }
+        }
+        var outputParts = [];
+        for (var i = samePartsLength; i < fromParts.length; i++) {
+          outputParts.push('..');
+        }
+        outputParts = outputParts.concat(toParts.slice(samePartsLength));
+        return outputParts.join('/');
+      }};
+
+  var TTY={ttys:[],init:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // currently, FS.init does not distinguish if process.stdin is a file or TTY
+        //   // device, it always assumes it's a TTY device. because of this, we're forcing
+        //   // process.stdin to UTF8 encoding to at least make stdin reading compatible
+        //   // with text files until FS.init can be refactored.
+        //   process['stdin']['setEncoding']('utf8');
+        // }
+      },shutdown:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
+        //   // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
+        //   // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
+        //   // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
+        //   // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
+        //   process['stdin']['pause']();
+        // }
+      },register:function (dev, ops) {
+        TTY.ttys[dev] = { input: [], output: [], ops: ops };
+        FS.registerDevice(dev, TTY.stream_ops);
+      },stream_ops:{open:function (stream) {
+          var tty = TTY.ttys[stream.node.rdev];
+          if (!tty) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          stream.tty = tty;
+          stream.seekable = false;
+        },close:function (stream) {
+          // flush any pending line data
+          if (stream.tty.output.length) {
+            stream.tty.ops.put_char(stream.tty, 10);
+          }
+        },read:function (stream, buffer, offset, length, pos /* ignored */) {
+          if (!stream.tty || !stream.tty.ops.get_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          var bytesRead = 0;
+          for (var i = 0; i < length; i++) {
+            var result;
+            try {
+              result = stream.tty.ops.get_char(stream.tty);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            if (result === undefined && bytesRead === 0) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+            if (result === null || result === undefined) break;
+            bytesRead++;
+            buffer[offset+i] = result;
+          }
+          if (bytesRead) {
+            stream.node.timestamp = Date.now();
+          }
+          return bytesRead;
+        },write:function (stream, buffer, offset, length, pos) {
+          if (!stream.tty || !stream.tty.ops.put_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          for (var i = 0; i < length; i++) {
+            try {
+              stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+          }
+          if (length) {
+            stream.node.timestamp = Date.now();
+          }
+          return i;
+        }},default_tty_ops:{get_char:function (tty) {
+          if (!tty.input.length) {
+            var result = null;
+            if (ENVIRONMENT_IS_NODE) {
+              result = process['stdin']['read']();
+              if (!result) {
+                if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) {
+                  return null;  // EOF
+                }
+                return undefined;  // no data available
+              }
+            } else if (typeof window != 'undefined' &&
+              typeof window.prompt == 'function') {
+              // Browser.
+              result = window.prompt('Input: ');  // returns null on cancel
+              if (result !== null) {
+                result += '\n';
+              }
+            } else if (typeof readline == 'function') {
+              // Command line.
+              result = readline();
+              if (result !== null) {
+                result += '\n';
+              }
+            }
+            if (!result) {
+              return null;
+            }
+            tty.input = intArrayFromString(result, true);
+          }
+          return tty.input.shift();
+        },put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['print'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }},default_tty1_ops:{put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['printErr'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }}};
+
+  var MEMFS={ops_table:null,CONTENT_OWNING:1,CONTENT_FLEXIBLE:2,CONTENT_FIXED:3,mount:function (mount) {
+        return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
+          // no supported
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (!MEMFS.ops_table) {
+          MEMFS.ops_table = {
+            dir: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                lookup: MEMFS.node_ops.lookup,
+                mknod: MEMFS.node_ops.mknod,
+                rename: MEMFS.node_ops.rename,
+                unlink: MEMFS.node_ops.unlink,
+                rmdir: MEMFS.node_ops.rmdir,
+                readdir: MEMFS.node_ops.readdir,
+                symlink: MEMFS.node_ops.symlink
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek
+              }
+            },
+            file: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek,
+                read: MEMFS.stream_ops.read,
+                write: MEMFS.stream_ops.write,
+                allocate: MEMFS.stream_ops.allocate,
+                mmap: MEMFS.stream_ops.mmap
+              }
+            },
+            link: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                readlink: MEMFS.node_ops.readlink
+              },
+              stream: {}
+            },
+            chrdev: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: FS.chrdev_stream_ops
+            },
+          };
+        }
+        var node = FS.createNode(parent, name, mode, dev);
+        if (FS.isDir(node.mode)) {
+          node.node_ops = MEMFS.ops_table.dir.node;
+          node.stream_ops = MEMFS.ops_table.dir.stream;
+          node.contents = {};
+        } else if (FS.isFile(node.mode)) {
+          node.node_ops = MEMFS.ops_table.file.node;
+          node.stream_ops = MEMFS.ops_table.file.stream;
+          node.contents = [];
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        } else if (FS.isLink(node.mode)) {
+          node.node_ops = MEMFS.ops_table.link.node;
+          node.stream_ops = MEMFS.ops_table.link.stream;
+        } else if (FS.isChrdev(node.mode)) {
+          node.node_ops = MEMFS.ops_table.chrdev.node;
+          node.stream_ops = MEMFS.ops_table.chrdev.stream;
+        }
+        node.timestamp = Date.now();
+        // add the new node to the parent
+        if (parent) {
+          parent.contents[name] = node;
+        }
+        return node;
+      },ensureFlexible:function (node) {
+        if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
+          var contents = node.contents;
+          node.contents = Array.prototype.slice.call(contents);
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        }
+      },node_ops:{getattr:function (node) {
+          var attr = {};
+          // device numbers reuse inode numbers.
+          attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
+          attr.ino = node.id;
+          attr.mode = node.mode;
+          attr.nlink = 1;
+          attr.uid = 0;
+          attr.gid = 0;
+          attr.rdev = node.rdev;
+          if (FS.isDir(node.mode)) {
+            attr.size = 4096;
+          } else if (FS.isFile(node.mode)) {
+            attr.size = node.contents.length;
+          } else if (FS.isLink(node.mode)) {
+            attr.size = node.link.length;
+          } else {
+            attr.size = 0;
+          }
+          attr.atime = new Date(node.timestamp);
+          attr.mtime = new Date(node.timestamp);
+          attr.ctime = new Date(node.timestamp);
+          // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
+          //       but this is not required by the standard.
+          attr.blksize = 4096;
+          attr.blocks = Math.ceil(attr.size / attr.blksize);
+          return attr;
+        },setattr:function (node, attr) {
+          if (attr.mode !== undefined) {
+            node.mode = attr.mode;
+          }
+          if (attr.timestamp !== undefined) {
+            node.timestamp = attr.timestamp;
+          }
+          if (attr.size !== undefined) {
+            MEMFS.ensureFlexible(node);
+            var contents = node.contents;
+            if (attr.size < contents.length) contents.length = attr.size;
+            else while (attr.size > contents.length) contents.push(0);
+          }
+        },lookup:function (parent, name) {
+          throw FS.genericErrors[ERRNO_CODES.ENOENT];
+        },mknod:function (parent, name, mode, dev) {
+          return MEMFS.createNode(parent, name, mode, dev);
+        },rename:function (old_node, new_dir, new_name) {
+          // if we're overwriting a directory at new_name, make sure it's empty.
+          if (FS.isDir(old_node.mode)) {
+            var new_node;
+            try {
+              new_node = FS.lookupNode(new_dir, new_name);
+            } catch (e) {
+            }
+            if (new_node) {
+              for (var i in new_node.contents) {
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+              }
+            }
+          }
+          // do the internal rewiring
+          delete old_node.parent.contents[old_node.name];
+          old_node.name = new_name;
+          new_dir.contents[new_name] = old_node;
+          old_node.parent = new_dir;
+        },unlink:function (parent, name) {
+          delete parent.contents[name];
+        },rmdir:function (parent, name) {
+          var node = FS.lookupNode(parent, name);
+          for (var i in node.contents) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+          }
+          delete parent.contents[name];
+        },readdir:function (node) {
+          var entries = ['.', '..']
+          for (var key in node.contents) {
+            if (!node.contents.hasOwnProperty(key)) {
+              continue;
+            }
+            entries.push(key);
+          }
+          return entries;
+        },symlink:function (parent, newname, oldpath) {
+          var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
+          node.link = oldpath;
+          return node;
+        },readlink:function (node) {
+          if (!FS.isLink(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          return node.link;
+        }},stream_ops:{read:function (stream, buffer, offset, length, position) {
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (size > 8 && contents.subarray) { // non-trivial, and typed array
+            buffer.set(contents.subarray(position, position + size), offset);
+          } else
+          {
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          }
+          return size;
+        },write:function (stream, buffer, offset, length, position, canOwn) {
+          var node = stream.node;
+          node.timestamp = Date.now();
+          var contents = node.contents;
+          if (length && contents.length === 0 && position === 0 && buffer.subarray) {
+            // just replace it with the new data
+            if (canOwn && offset === 0) {
+              node.contents = buffer; // this could be a subarray of Emscripten HEAP, or allocated from some other source.
+              node.contentMode = (buffer.buffer === HEAP8.buffer) ? MEMFS.CONTENT_OWNING : MEMFS.CONTENT_FIXED;
+            } else {
+              node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
+              node.contentMode = MEMFS.CONTENT_FIXED;
+            }
+            return length;
+          }
+          MEMFS.ensureFlexible(node);
+          var contents = node.contents;
+          while (contents.length < position) contents.push(0);
+          for (var i = 0; i < length; i++) {
+            contents[position + i] = buffer[offset + i];
+          }
+          return length;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              position += stream.node.contents.length;
+            }
+          }
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          stream.ungotten = [];
+          stream.position = position;
+          return position;
+        },allocate:function (stream, offset, length) {
+          MEMFS.ensureFlexible(stream.node);
+          var contents = stream.node.contents;
+          var limit = offset + length;
+          while (limit > contents.length) contents.push(0);
+        },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+          if (!FS.isFile(stream.node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          var ptr;
+          var allocated;
+          var contents = stream.node.contents;
+          // Only make a new copy when MAP_PRIVATE is specified.
+          if ( !(flags & 2) &&
+                (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
+            // We can't emulate MAP_SHARED when the file is not backed by the buffer
+            // we're mapping to (e.g. the HEAP buffer).
+            allocated = false;
+            ptr = contents.byteOffset;
+          } else {
+            // Try to avoid unnecessary slices.
+            if (position > 0 || position + length < contents.length) {
+              if (contents.subarray) {
+                contents = contents.subarray(position, position + length);
+              } else {
+                contents = Array.prototype.slice.call(contents, position, position + length);
+              }
+            }
+            allocated = true;
+            ptr = _malloc(length);
+            if (!ptr) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOMEM);
+            }
+            buffer.set(contents, ptr);
+          }
+          return { ptr: ptr, allocated: allocated };
+        }}};
+
+  var IDBFS={dbs:{},indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) {
+        // reuse all of the core MEMFS functionality
+        return MEMFS.mount.apply(null, arguments);
+      },syncfs:function (mount, populate, callback) {
+        IDBFS.getLocalSet(mount, function(err, local) {
+          if (err) return callback(err);
+
+          IDBFS.getRemoteSet(mount, function(err, remote) {
+            if (err) return callback(err);
+
+            var src = populate ? remote : local;
+            var dst = populate ? local : remote;
+
+            IDBFS.reconcile(src, dst, callback);
+          });
+        });
+      },getDB:function (name, callback) {
+        // check the cache first
+        var db = IDBFS.dbs[name];
+        if (db) {
+          return callback(null, db);
+        }
+
+        var req;
+        try {
+          req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
+        } catch (e) {
+          return callback(e);
+        }
+        req.onupgradeneeded = function(e) {
+          var db = e.target.result;
+          var transaction = e.target.transaction;
+
+          var fileStore;
+
+          if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
+            fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          } else {
+            fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
+          }
+
+          fileStore.createIndex('timestamp', 'timestamp', { unique: false });
+        };
+        req.onsuccess = function() {
+          db = req.result;
+
+          // add to the cache
+          IDBFS.dbs[name] = db;
+          callback(null, db);
+        };
+        req.onerror = function() {
+          callback(this.error);
+        };
+      },getLocalSet:function (mount, callback) {
+        var entries = {};
+
+        function isRealDir(p) {
+          return p !== '.' && p !== '..';
+        };
+        function toAbsolute(root) {
+          return function(p) {
+            return PATH.join2(root, p);
+          }
+        };
+
+        var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
+
+        while (check.length) {
+          var path = check.pop();
+          var stat;
+
+          try {
+            stat = FS.stat(path);
+          } catch (e) {
+            return callback(e);
+          }
+
+          if (FS.isDir(stat.mode)) {
+            check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
+          }
+
+          entries[path] = { timestamp: stat.mtime };
+        }
+
+        return callback(null, { type: 'local', entries: entries });
+      },getRemoteSet:function (mount, callback) {
+        var entries = {};
+
+        IDBFS.getDB(mount.mountpoint, function(err, db) {
+          if (err) return callback(err);
+
+          var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly');
+          transaction.onerror = function() { callback(this.error); };
+
+          var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          var index = store.index('timestamp');
+
+          index.openKeyCursor().onsuccess = function(event) {
+            var cursor = event.target.result;
+
+            if (!cursor) {
+              return callback(null, { type: 'remote', db: db, entries: entries });
+            }
+
+            entries[cursor.primaryKey] = { timestamp: cursor.key };
+
+            cursor.continue();
+          };
+        });
+      },loadLocalEntry:function (path, callback) {
+        var stat, node;
+
+        try {
+          var lookup = FS.lookupPath(path);
+          node = lookup.node;
+          stat = FS.stat(path);
+        } catch (e) {
+          return callback(e);
+        }
+
+        if (FS.isDir(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode });
+        } else if (FS.isFile(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents });
+        } else {
+          return callback(new Error('node type not supported'));
+        }
+      },storeLocalEntry:function (path, entry, callback) {
+        try {
+          if (FS.isDir(entry.mode)) {
+            FS.mkdir(path, entry.mode);
+          } else if (FS.isFile(entry.mode)) {
+            FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true });
+          } else {
+            return callback(new Error('node type not supported'));
+          }
+
+          FS.utime(path, entry.timestamp, entry.timestamp);
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },removeLocalEntry:function (path, callback) {
+        try {
+          var lookup = FS.lookupPath(path);
+          var stat = FS.stat(path);
+
+          if (FS.isDir(stat.mode)) {
+            FS.rmdir(path);
+          } else if (FS.isFile(stat.mode)) {
+            FS.unlink(path);
+          }
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },loadRemoteEntry:function (store, path, callback) {
+        var req = store.get(path);
+        req.onsuccess = function(event) { callback(null, event.target.result); };
+        req.onerror = function() { callback(this.error); };
+      },storeRemoteEntry:function (store, path, entry, callback) {
+        var req = store.put(entry, path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },removeRemoteEntry:function (store, path, callback) {
+        var req = store.delete(path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },reconcile:function (src, dst, callback) {
+        var total = 0;
+
+        var create = [];
+        Object.keys(src.entries).forEach(function (key) {
+          var e = src.entries[key];
+          var e2 = dst.entries[key];
+          if (!e2 || e.timestamp > e2.timestamp) {
+            create.push(key);
+            total++;
+          }
+        });
+
+        var remove = [];
+        Object.keys(dst.entries).forEach(function (key) {
+          var e = dst.entries[key];
+          var e2 = src.entries[key];
+          if (!e2) {
+            remove.push(key);
+            total++;
+          }
+        });
+
+        if (!total) {
+          return callback(null);
+        }
+
+        var errored = false;
+        var completed = 0;
+        var db = src.type === 'remote' ? src.db : dst.db;
+        var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
+        var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= total) {
+            return callback(null);
+          }
+        };
+
+        transaction.onerror = function() { done(this.error); };
+
+        // sort paths in ascending order so directory entries are created
+        // before the files inside them
+        create.sort().forEach(function (path) {
+          if (dst.type === 'local') {
+            IDBFS.loadRemoteEntry(store, path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeLocalEntry(path, entry, done);
+            });
+          } else {
+            IDBFS.loadLocalEntry(path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeRemoteEntry(store, path, entry, done);
+            });
+          }
+        });
+
+        // sort paths in descending order so files are deleted before their
+        // parent directories
+        remove.sort().reverse().forEach(function(path) {
+          if (dst.type === 'local') {
+            IDBFS.removeLocalEntry(path, done);
+          } else {
+            IDBFS.removeRemoteEntry(store, path, done);
+          }
+        });
+      }};
+
+  var NODEFS={isWindows:false,staticInit:function () {
+        NODEFS.isWindows = !!process.platform.match(/^win/);
+      },mount:function (mount) {
+        assert(ENVIRONMENT_IS_NODE);
+        return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node = FS.createNode(parent, name, mode);
+        node.node_ops = NODEFS.node_ops;
+        node.stream_ops = NODEFS.stream_ops;
+        return node;
+      },getMode:function (path) {
+        var stat;
+        try {
+          stat = fs.lstatSync(path);
+          if (NODEFS.isWindows) {
+            // On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so
+            // propagate write bits to execute bits.
+            stat.mode = stat.mode | ((stat.mode & 146) >> 1);
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        return stat.mode;
+      },realPath:function (node) {
+        var parts = [];
+        while (node.parent !== node) {
+          parts.push(node.name);
+          node = node.parent;
+        }
+        parts.push(node.mount.opts.root);
+        parts.reverse();
+        return PATH.join.apply(null, parts);
+      },flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) {
+        if (flags in NODEFS.flagsToPermissionStringMap) {
+          return NODEFS.flagsToPermissionStringMap[flags];
+        } else {
+          return flags;
+        }
+      },node_ops:{getattr:function (node) {
+          var path = NODEFS.realPath(node);
+          var stat;
+          try {
+            stat = fs.lstatSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096.
+          // See http://support.microsoft.com/kb/140365
+          if (NODEFS.isWindows && !stat.blksize) {
+            stat.blksize = 4096;
+          }
+          if (NODEFS.isWindows && !stat.blocks) {
+            stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0;
+          }
+          return {
+            dev: stat.dev,
+            ino: stat.ino,
+            mode: stat.mode,
+            nlink: stat.nlink,
+            uid: stat.uid,
+            gid: stat.gid,
+            rdev: stat.rdev,
+            size: stat.size,
+            atime: stat.atime,
+            mtime: stat.mtime,
+            ctime: stat.ctime,
+            blksize: stat.blksize,
+            blocks: stat.blocks
+          };
+        },setattr:function (node, attr) {
+          var path = NODEFS.realPath(node);
+          try {
+            if (attr.mode !== undefined) {
+              fs.chmodSync(path, attr.mode);
+              // update the common node structure mode as well
+              node.mode = attr.mode;
+            }
+            if (attr.timestamp !== undefined) {
+              var date = new Date(attr.timestamp);
+              fs.utimesSync(path, date, date);
+            }
+            if (attr.size !== undefined) {
+              fs.truncateSync(path, attr.size);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },lookup:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          var mode = NODEFS.getMode(path);
+          return NODEFS.createNode(parent, name, mode);
+        },mknod:function (parent, name, mode, dev) {
+          var node = NODEFS.createNode(parent, name, mode, dev);
+          // create the backing node for this in the fs root as well
+          var path = NODEFS.realPath(node);
+          try {
+            if (FS.isDir(node.mode)) {
+              fs.mkdirSync(path, node.mode);
+            } else {
+              fs.writeFileSync(path, '', { mode: node.mode });
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return node;
+        },rename:function (oldNode, newDir, newName) {
+          var oldPath = NODEFS.realPath(oldNode);
+          var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
+          try {
+            fs.renameSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },unlink:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.unlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },rmdir:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.rmdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readdir:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },symlink:function (parent, newName, oldPath) {
+          var newPath = PATH.join2(NODEFS.realPath(parent), newName);
+          try {
+            fs.symlinkSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readlink:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        }},stream_ops:{open:function (stream) {
+          var path = NODEFS.realPath(stream.node);
+          try {
+            if (FS.isFile(stream.node.mode)) {
+              stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags));
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },close:function (stream) {
+          try {
+            if (FS.isFile(stream.node.mode) && stream.nfd) {
+              fs.closeSync(stream.nfd);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },read:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(length);
+          var res;
+          try {
+            res = fs.readSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          if (res > 0) {
+            for (var i = 0; i < res; i++) {
+              buffer[offset + i] = nbuffer[i];
+            }
+          }
+          return res;
+        },write:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(buffer.subarray(offset, offset + length));
+          var res;
+          try {
+            res = fs.writeSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return res;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              try {
+                var stat = fs.fstatSync(stream.nfd);
+                position += stat.size;
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+              }
+            }
+          }
+
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+
+          stream.position = position;
+          return position;
+        }}};
+
+  var _stdin=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stdout=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stderr=allocate(1, "i32*", ALLOC_STATIC);
+
+  function _fflush(stream) {
+      // int fflush(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html
+      // we don't currently perform any user-space buffering of data
+    }var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},handleFSError:function (e) {
+        if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
+        return ___setErrNo(e.errno);
+      },lookupPath:function (path, opts) {
+        path = PATH.resolve(FS.cwd(), path);
+        opts = opts || {};
+
+        var defaults = {
+          follow_mount: true,
+          recurse_count: 0
+        };
+        for (var key in defaults) {
+          if (opts[key] === undefined) {
+            opts[key] = defaults[key];
+          }
+        }
+
+        if (opts.recurse_count > 8) {  // max recursive lookup of 8
+          throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+        }
+
+        // split the path
+        var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), false);
+
+        // start at the root
+        var current = FS.root;
+        var current_path = '/';
+
+        for (var i = 0; i < parts.length; i++) {
+          var islast = (i === parts.length-1);
+          if (islast && opts.parent) {
+            // stop resolving
+            break;
+          }
+
+          current = FS.lookupNode(current, parts[i]);
+          current_path = PATH.join2(current_path, parts[i]);
+
+          // jump to the mount's root node if this is a mountpoint
+          if (FS.isMountpoint(current)) {
+            if (!islast || (islast && opts.follow_mount)) {
+              current = current.mounted.root;
+            }
+          }
+
+          // by default, lookupPath will not follow a symlink if it is the final path component.
+          // setting opts.follow = true will override this behavior.
+          if (!islast || opts.follow) {
+            var count = 0;
+            while (FS.isLink(current.mode)) {
+              var link = FS.readlink(current_path);
+              current_path = PATH.resolve(PATH.dirname(current_path), link);
+
+              var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
+              current = lookup.node;
+
+              if (count++ > 40) {  // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
+                throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+              }
+            }
+          }
+        }
+
+        return { path: current_path, node: current };
+      },getPath:function (node) {
+        var path;
+        while (true) {
+          if (FS.isRoot(node)) {
+            var mount = node.mount.mountpoint;
+            if (!path) return mount;
+            return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
+          }
+          path = path ? node.name + '/' + path : node.name;
+          node = node.parent;
+        }
+      },hashName:function (parentid, name) {
+        var hash = 0;
+
+
+        for (var i = 0; i < name.length; i++) {
+          hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
+        }
+        return ((parentid + hash) >>> 0) % FS.nameTable.length;
+      },hashAddNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        node.name_next = FS.nameTable[hash];
+        FS.nameTable[hash] = node;
+      },hashRemoveNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        if (FS.nameTable[hash] === node) {
+          FS.nameTable[hash] = node.name_next;
+        } else {
+          var current = FS.nameTable[hash];
+          while (current) {
+            if (current.name_next === node) {
+              current.name_next = node.name_next;
+              break;
+            }
+            current = current.name_next;
+          }
+        }
+      },lookupNode:function (parent, name) {
+        var err = FS.mayLookup(parent);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        var hash = FS.hashName(parent.id, name);
+        for (var node = FS.nameTable[hash]; node; node = node.name_next) {
+          var nodeName = node.name;
+          if (node.parent.id === parent.id && nodeName === name) {
+            return node;
+          }
+        }
+        // if we failed to find it in the cache, call into the VFS
+        return FS.lookup(parent, name);
+      },createNode:function (parent, name, mode, rdev) {
+        if (!FS.FSNode) {
+          FS.FSNode = function(parent, name, mode, rdev) {
+            if (!parent) {
+              parent = this;  // root node sets parent to itself
+            }
+            this.parent = parent;
+            this.mount = parent.mount;
+            this.mounted = null;
+            this.id = FS.nextInode++;
+            this.name = name;
+            this.mode = mode;
+            this.node_ops = {};
+            this.stream_ops = {};
+            this.rdev = rdev;
+          };
+
+          FS.FSNode.prototype = {};
+
+          // compatibility
+          var readMode = 292 | 73;
+          var writeMode = 146;
+
+          // NOTE we must use Object.defineProperties instead of individual calls to
+          // Object.defineProperty in order to make closure compiler happy
+          Object.defineProperties(FS.FSNode.prototype, {
+            read: {
+              get: function() { return (this.mode & readMode) === readMode; },
+              set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; }
+            },
+            write: {
+              get: function() { return (this.mode & writeMode) === writeMode; },
+              set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; }
+            },
+            isFolder: {
+              get: function() { return FS.isDir(this.mode); },
+            },
+            isDevice: {
+              get: function() { return FS.isChrdev(this.mode); },
+            },
+          });
+        }
+
+        var node = new FS.FSNode(parent, name, mode, rdev);
+
+        FS.hashAddNode(node);
+
+        return node;
+      },destroyNode:function (node) {
+        FS.hashRemoveNode(node);
+      },isRoot:function (node) {
+        return node === node.parent;
+      },isMountpoint:function (node) {
+        return !!node.mounted;
+      },isFile:function (mode) {
+        return (mode & 61440) === 32768;
+      },isDir:function (mode) {
+        return (mode & 61440) === 16384;
+      },isLink:function (mode) {
+        return (mode & 61440) === 40960;
+      },isChrdev:function (mode) {
+        return (mode & 61440) === 8192;
+      },isBlkdev:function (mode) {
+        return (mode & 61440) === 24576;
+      },isFIFO:function (mode) {
+        return (mode & 61440) === 4096;
+      },isSocket:function (mode) {
+        return (mode & 49152) === 49152;
+      },flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function (str) {
+        var flags = FS.flagModes[str];
+        if (typeof flags === 'undefined') {
+          throw new Error('Unknown file open mode: ' + str);
+        }
+        return flags;
+      },flagsToPermissionString:function (flag) {
+        var accmode = flag & 2097155;
+        var perms = ['r', 'w', 'rw'][accmode];
+        if ((flag & 512)) {
+          perms += 'w';
+        }
+        return perms;
+      },nodePermissions:function (node, perms) {
+        if (FS.ignorePermissions) {
+          return 0;
+        }
+        // return 0 if any user, group or owner bits are set.
+        if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
+          return ERRNO_CODES.EACCES;
+        }
+        return 0;
+      },mayLookup:function (dir) {
+        return FS.nodePermissions(dir, 'x');
+      },mayCreate:function (dir, name) {
+        try {
+          var node = FS.lookupNode(dir, name);
+          return ERRNO_CODES.EEXIST;
+        } catch (e) {
+        }
+        return FS.nodePermissions(dir, 'wx');
+      },mayDelete:function (dir, name, isdir) {
+        var node;
+        try {
+          node = FS.lookupNode(dir, name);
+        } catch (e) {
+          return e.errno;
+        }
+        var err = FS.nodePermissions(dir, 'wx');
+        if (err) {
+          return err;
+        }
+        if (isdir) {
+          if (!FS.isDir(node.mode)) {
+            return ERRNO_CODES.ENOTDIR;
+          }
+          if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
+            return ERRNO_CODES.EBUSY;
+          }
+        } else {
+          if (FS.isDir(node.mode)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return 0;
+      },mayOpen:function (node, flags) {
+        if (!node) {
+          return ERRNO_CODES.ENOENT;
+        }
+        if (FS.isLink(node.mode)) {
+          return ERRNO_CODES.ELOOP;
+        } else if (FS.isDir(node.mode)) {
+          if ((flags & 2097155) !== 0 ||  // opening for write
+              (flags & 512)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
+      },MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) {
+        fd_start = fd_start || 0;
+        fd_end = fd_end || FS.MAX_OPEN_FDS;
+        for (var fd = fd_start; fd <= fd_end; fd++) {
+          if (!FS.streams[fd]) {
+            return fd;
+          }
+        }
+        throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
+      },getStream:function (fd) {
+        return FS.streams[fd];
+      },createStream:function (stream, fd_start, fd_end) {
+        if (!FS.FSStream) {
+          FS.FSStream = function(){};
+          FS.FSStream.prototype = {};
+          // compatibility
+          Object.defineProperties(FS.FSStream.prototype, {
+            object: {
+              get: function() { return this.node; },
+              set: function(val) { this.node = val; }
+            },
+            isRead: {
+              get: function() { return (this.flags & 2097155) !== 1; }
+            },
+            isWrite: {
+              get: function() { return (this.flags & 2097155) !== 0; }
+            },
+            isAppend: {
+              get: function() { return (this.flags & 1024); }
+            }
+          });
+        }
+        if (0) {
+          // reuse the object
+          stream.__proto__ = FS.FSStream.prototype;
+        } else {
+          var newStream = new FS.FSStream();
+          for (var p in stream) {
+            newStream[p] = stream[p];
+          }
+          stream = newStream;
+        }
+        var fd = FS.nextfd(fd_start, fd_end);
+        stream.fd = fd;
+        FS.streams[fd] = stream;
+        return stream;
+      },closeStream:function (fd) {
+        FS.streams[fd] = null;
+      },getStreamFromPtr:function (ptr) {
+        return FS.streams[ptr - 1];
+      },getPtrForStream:function (stream) {
+        return stream ? stream.fd + 1 : 0;
+      },chrdev_stream_ops:{open:function (stream) {
+          var device = FS.getDevice(stream.node.rdev);
+          // override node's stream ops with the device's
+          stream.stream_ops = device.stream_ops;
+          // forward the open call
+          if (stream.stream_ops.open) {
+            stream.stream_ops.open(stream);
+          }
+        },llseek:function () {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }},major:function (dev) {
+        return ((dev) >> 8);
+      },minor:function (dev) {
+        return ((dev) & 0xff);
+      },makedev:function (ma, mi) {
+        return ((ma) << 8 | (mi));
+      },registerDevice:function (dev, ops) {
+        FS.devices[dev] = { stream_ops: ops };
+      },getDevice:function (dev) {
+        return FS.devices[dev];
+      },getMounts:function (mount) {
+        var mounts = [];
+        var check = [mount];
+
+        while (check.length) {
+          var m = check.pop();
+
+          mounts.push(m);
+
+          check.push.apply(check, m.mounts);
+        }
+
+        return mounts;
+      },syncfs:function (populate, callback) {
+        if (typeof(populate) === 'function') {
+          callback = populate;
+          populate = false;
+        }
+
+        var mounts = FS.getMounts(FS.root.mount);
+        var completed = 0;
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= mounts.length) {
+            callback(null);
+          }
+        };
+
+        // sync all mounts
+        mounts.forEach(function (mount) {
+          if (!mount.type.syncfs) {
+            return done(null);
+          }
+          mount.type.syncfs(mount, populate, done);
+        });
+      },mount:function (type, opts, mountpoint) {
+        var root = mountpoint === '/';
+        var pseudo = !mountpoint;
+        var node;
+
+        if (root && FS.root) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        } else if (!root && !pseudo) {
+          var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+          mountpoint = lookup.path;  // use the absolute path
+          node = lookup.node;
+
+          if (FS.isMountpoint(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+          }
+
+          if (!FS.isDir(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+          }
+        }
+
+        var mount = {
+          type: type,
+          opts: opts,
+          mountpoint: mountpoint,
+          mounts: []
+        };
+
+        // create a root node for the fs
+        var mountRoot = type.mount(mount);
+        mountRoot.mount = mount;
+        mount.root = mountRoot;
+
+        if (root) {
+          FS.root = mountRoot;
+        } else if (node) {
+          // set as a mountpoint
+          node.mounted = mount;
+
+          // add the new mount to the current mount's children
+          if (node.mount) {
+            node.mount.mounts.push(mount);
+          }
+        }
+
+        return mountRoot;
+      },unmount:function (mountpoint) {
+        var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+        if (!FS.isMountpoint(lookup.node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+
+        // destroy the nodes for this mount, and all its child mounts
+        var node = lookup.node;
+        var mount = node.mounted;
+        var mounts = FS.getMounts(mount);
+
+        Object.keys(FS.nameTable).forEach(function (hash) {
+          var current = FS.nameTable[hash];
+
+          while (current) {
+            var next = current.name_next;
+
+            if (mounts.indexOf(current.mount) !== -1) {
+              FS.destroyNode(current);
+            }
+
+            current = next;
+          }
+        });
+
+        // no longer a mountpoint
+        node.mounted = null;
+
+        // remove this mount from the child mounts
+        var idx = node.mount.mounts.indexOf(mount);
+        assert(idx !== -1);
+        node.mount.mounts.splice(idx, 1);
+      },lookup:function (parent, name) {
+        return parent.node_ops.lookup(parent, name);
+      },mknod:function (path, mode, dev) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var err = FS.mayCreate(parent, name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.mknod) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.mknod(parent, name, mode, dev);
+      },create:function (path, mode) {
+        mode = mode !== undefined ? mode : 438 /* 0666 */;
+        mode &= 4095;
+        mode |= 32768;
+        return FS.mknod(path, mode, 0);
+      },mkdir:function (path, mode) {
+        mode = mode !== undefined ? mode : 511 /* 0777 */;
+        mode &= 511 | 512;
+        mode |= 16384;
+        return FS.mknod(path, mode, 0);
+      },mkdev:function (path, mode, dev) {
+        if (typeof(dev) === 'undefined') {
+          dev = mode;
+          mode = 438 /* 0666 */;
+        }
+        mode |= 8192;
+        return FS.mknod(path, mode, dev);
+      },symlink:function (oldpath, newpath) {
+        var lookup = FS.lookupPath(newpath, { parent: true });
+        var parent = lookup.node;
+        var newname = PATH.basename(newpath);
+        var err = FS.mayCreate(parent, newname);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.symlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.symlink(parent, newname, oldpath);
+      },rename:function (old_path, new_path) {
+        var old_dirname = PATH.dirname(old_path);
+        var new_dirname = PATH.dirname(new_path);
+        var old_name = PATH.basename(old_path);
+        var new_name = PATH.basename(new_path);
+        // parents must exist
+        var lookup, old_dir, new_dir;
+        try {
+          lookup = FS.lookupPath(old_path, { parent: true });
+          old_dir = lookup.node;
+          lookup = FS.lookupPath(new_path, { parent: true });
+          new_dir = lookup.node;
+        } catch (e) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // need to be part of the same mount
+        if (old_dir.mount !== new_dir.mount) {
+          throw new FS.ErrnoError(ERRNO_CODES.EXDEV);
+        }
+        // source must exist
+        var old_node = FS.lookupNode(old_dir, old_name);
+        // old path should not be an ancestor of the new path
+        var relative = PATH.relative(old_path, new_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        // new path should not be an ancestor of the old path
+        relative = PATH.relative(new_path, old_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+        }
+        // see if the new path already exists
+        var new_node;
+        try {
+          new_node = FS.lookupNode(new_dir, new_name);
+        } catch (e) {
+          // not fatal
+        }
+        // early out if nothing needs to change
+        if (old_node === new_node) {
+          return;
+        }
+        // we'll need to delete the old entry
+        var isdir = FS.isDir(old_node.mode);
+        var err = FS.mayDelete(old_dir, old_name, isdir);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // need delete permissions if we'll be overwriting.
+        // need create permissions if new doesn't already exist.
+        err = new_node ?
+          FS.mayDelete(new_dir, new_name, isdir) :
+          FS.mayCreate(new_dir, new_name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!old_dir.node_ops.rename) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // if we are going to change the parent, check write permissions
+        if (new_dir !== old_dir) {
+          err = FS.nodePermissions(old_dir, 'w');
+          if (err) {
+            throw new FS.ErrnoError(err);
+          }
+        }
+        // remove the node from the lookup hash
+        FS.hashRemoveNode(old_node);
+        // do the underlying fs rename
+        try {
+          old_dir.node_ops.rename(old_node, new_dir, new_name);
+        } catch (e) {
+          throw e;
+        } finally {
+          // add the node back to the hash (in case node_ops.rename
+          // changed its name)
+          FS.hashAddNode(old_node);
+        }
+      },rmdir:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, true);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.rmdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.rmdir(parent, name);
+        FS.destroyNode(node);
+      },readdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        if (!node.node_ops.readdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        return node.node_ops.readdir(node);
+      },unlink:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, false);
+        if (err) {
+          // POSIX says unlink should set EPERM, not EISDIR
+          if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM;
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.unlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.unlink(parent, name);
+        FS.destroyNode(node);
+      },readlink:function (path) {
+        var lookup = FS.lookupPath(path);
+        var link = lookup.node;
+        if (!link.node_ops.readlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        return link.node_ops.readlink(link);
+      },stat:function (path, dontFollow) {
+        var lookup = FS.lookupPath(path, { follow: !dontFollow });
+        var node = lookup.node;
+        if (!node.node_ops.getattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return node.node_ops.getattr(node);
+      },lstat:function (path) {
+        return FS.stat(path, true);
+      },chmod:function (path, mode, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          mode: (mode & 4095) | (node.mode & ~4095),
+          timestamp: Date.now()
+        });
+      },lchmod:function (path, mode) {
+        FS.chmod(path, mode, true);
+      },fchmod:function (fd, mode) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chmod(stream.node, mode);
+      },chown:function (path, uid, gid, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          timestamp: Date.now()
+          // we ignore the uid / gid for now
+        });
+      },lchown:function (path, uid, gid) {
+        FS.chown(path, uid, gid, true);
+      },fchown:function (fd, uid, gid) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chown(stream.node, uid, gid);
+      },truncate:function (path, len) {
+        if (len < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: true });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!FS.isFile(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var err = FS.nodePermissions(node, 'w');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        node.node_ops.setattr(node, {
+          size: len,
+          timestamp: Date.now()
+        });
+      },ftruncate:function (fd, len) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        FS.truncate(stream.node, len);
+      },utime:function (path, atime, mtime) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        node.node_ops.setattr(node, {
+          timestamp: Math.max(atime, mtime)
+        });
+      },open:function (path, flags, mode, fd_start, fd_end) {
+        flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
+        mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
+        if ((flags & 64)) {
+          mode = (mode & 4095) | 32768;
+        } else {
+          mode = 0;
+        }
+        var node;
+        if (typeof path === 'object') {
+          node = path;
+        } else {
+          path = PATH.normalize(path);
+          try {
+            var lookup = FS.lookupPath(path, {
+              follow: !(flags & 131072)
+            });
+            node = lookup.node;
+          } catch (e) {
+            // ignore
+          }
+        }
+        // perhaps we need to create the node
+        if ((flags & 64)) {
+          if (node) {
+            // if O_CREAT and O_EXCL are set, error out if the node already exists
+            if ((flags & 128)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EEXIST);
+            }
+          } else {
+            // node doesn't exist, try to create it
+            node = FS.mknod(path, mode, 0);
+          }
+        }
+        if (!node) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
+        }
+        // can't truncate a device
+        if (FS.isChrdev(node.mode)) {
+          flags &= ~512;
+        }
+        // check permissions
+        var err = FS.mayOpen(node, flags);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // do truncation if necessary
+        if ((flags & 512)) {
+          FS.truncate(node, 0);
+        }
+        // we've already handled these, don't pass down to the underlying vfs
+        flags &= ~(128 | 512);
+
+        // register the stream with the filesystem
+        var stream = FS.createStream({
+          node: node,
+          path: FS.getPath(node),  // we want the absolute path to the node
+          flags: flags,
+          seekable: true,
+          position: 0,
+          stream_ops: node.stream_ops,
+          // used by the file family libc calls (fopen, fwrite, ferror, etc.)
+          ungotten: [],
+          error: false
+        }, fd_start, fd_end);
+        // call the new stream's open function
+        if (stream.stream_ops.open) {
+          stream.stream_ops.open(stream);
+        }
+        if (Module['logReadFiles'] && !(flags & 1)) {
+          if (!FS.readFiles) FS.readFiles = {};
+          if (!(path in FS.readFiles)) {
+            FS.readFiles[path] = 1;
+            Module['printErr']('read file: ' + path);
+          }
+        }
+        return stream;
+      },close:function (stream) {
+        try {
+          if (stream.stream_ops.close) {
+            stream.stream_ops.close(stream);
+          }
+        } catch (e) {
+          throw e;
+        } finally {
+          FS.closeStream(stream.fd);
+        }
+      },llseek:function (stream, offset, whence) {
+        if (!stream.seekable || !stream.stream_ops.llseek) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        return stream.stream_ops.llseek(stream, offset, whence);
+      },read:function (stream, buffer, offset, length, position) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.read) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
+        if (!seeking) stream.position += bytesRead;
+        return bytesRead;
+      },write:function (stream, buffer, offset, length, position, canOwn) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.write) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        if (stream.flags & 1024) {
+          // seek to the end before writing in append mode
+          FS.llseek(stream, 0, 2);
+        }
+        var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
+        if (!seeking) stream.position += bytesWritten;
+        return bytesWritten;
+      },allocate:function (stream, offset, length) {
+        if (offset < 0 || length <= 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        if (!stream.stream_ops.allocate) {
+          throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+        }
+        stream.stream_ops.allocate(stream, offset, length);
+      },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+        // TODO if PROT is PROT_WRITE, make sure we have write access
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EACCES);
+        }
+        if (!stream.stream_ops.mmap) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
+      },ioctl:function (stream, cmd, arg) {
+        if (!stream.stream_ops.ioctl) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTTY);
+        }
+        return stream.stream_ops.ioctl(stream, cmd, arg);
+      },readFile:function (path, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'r';
+        opts.encoding = opts.encoding || 'binary';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var ret;
+        var stream = FS.open(path, opts.flags);
+        var stat = FS.stat(path);
+        var length = stat.size;
+        var buf = new Uint8Array(length);
+        FS.read(stream, buf, 0, length, 0);
+        if (opts.encoding === 'utf8') {
+          ret = '';
+          var utf8 = new Runtime.UTF8Processor();
+          for (var i = 0; i < length; i++) {
+            ret += utf8.processCChar(buf[i]);
+          }
+        } else if (opts.encoding === 'binary') {
+          ret = buf;
+        }
+        FS.close(stream);
+        return ret;
+      },writeFile:function (path, data, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'w';
+        opts.encoding = opts.encoding || 'utf8';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var stream = FS.open(path, opts.flags, opts.mode);
+        if (opts.encoding === 'utf8') {
+          var utf8 = new Runtime.UTF8Processor();
+          var buf = new Uint8Array(utf8.processJSString(data));
+          FS.write(stream, buf, 0, buf.length, 0, opts.canOwn);
+        } else if (opts.encoding === 'binary') {
+          FS.write(stream, data, 0, data.length, 0, opts.canOwn);
+        }
+        FS.close(stream);
+      },cwd:function () {
+        return FS.currentPath;
+      },chdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        if (!FS.isDir(lookup.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        var err = FS.nodePermissions(lookup.node, 'x');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        FS.currentPath = lookup.path;
+      },createDefaultDirectories:function () {
+        FS.mkdir('/tmp');
+      },createDefaultDevices:function () {
+        // create /dev
+        FS.mkdir('/dev');
+        // setup /dev/null
+        FS.registerDevice(FS.makedev(1, 3), {
+          read: function() { return 0; },
+          write: function() { return 0; }
+        });
+        FS.mkdev('/dev/null', FS.makedev(1, 3));
+        // setup /dev/tty and /dev/tty1
+        // stderr needs to print output using Module['printErr']
+        // so we register a second tty just for it.
+        TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
+        TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
+        FS.mkdev('/dev/tty', FS.makedev(5, 0));
+        FS.mkdev('/dev/tty1', FS.makedev(6, 0));
+        // we're not going to emulate the actual shm device,
+        // just create the tmp dirs that reside in it commonly
+        FS.mkdir('/dev/shm');
+        FS.mkdir('/dev/shm/tmp');
+      },createStandardStreams:function () {
+        // TODO deprecate the old functionality of a single
+        // input / output callback and that utilizes FS.createDevice
+        // and instead require a unique set of stream ops
+
+        // by default, we symlink the standard streams to the
+        // default tty devices. however, if the standard streams
+        // have been overwritten we create a unique device for
+        // them instead.
+        if (Module['stdin']) {
+          FS.createDevice('/dev', 'stdin', Module['stdin']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdin');
+        }
+        if (Module['stdout']) {
+          FS.createDevice('/dev', 'stdout', null, Module['stdout']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdout');
+        }
+        if (Module['stderr']) {
+          FS.createDevice('/dev', 'stderr', null, Module['stderr']);
+        } else {
+          FS.symlink('/dev/tty1', '/dev/stderr');
+        }
+
+        // open default streams for the stdin, stdout and stderr devices
+        var stdin = FS.open('/dev/stdin', 'r');
+        HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin);
+        assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
+
+        var stdout = FS.open('/dev/stdout', 'w');
+        HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout);
+        assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
+
+        var stderr = FS.open('/dev/stderr', 'w');
+        HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr);
+        assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
+      },ensureErrnoError:function () {
+        if (FS.ErrnoError) return;
+        FS.ErrnoError = function ErrnoError(errno) {
+          this.errno = errno;
+          for (var key in ERRNO_CODES) {
+            if (ERRNO_CODES[key] === errno) {
+              this.code = key;
+              break;
+            }
+          }
+          this.message = ERRNO_MESSAGES[errno];
+        };
+        FS.ErrnoError.prototype = new Error();
+        FS.ErrnoError.prototype.constructor = FS.ErrnoError;
+        // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
+        [ERRNO_CODES.ENOENT].forEach(function(code) {
+          FS.genericErrors[code] = new FS.ErrnoError(code);
+          FS.genericErrors[code].stack = '<generic error, no stack>';
+        });
+      },staticInit:function () {
+        FS.ensureErrnoError();
+
+        FS.nameTable = new Array(4096);
+
+        FS.mount(MEMFS, {}, '/');
+
+        FS.createDefaultDirectories();
+        FS.createDefaultDevices();
+      },init:function (input, output, error) {
+        assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
+        FS.init.initialized = true;
+
+        FS.ensureErrnoError();
+
+        // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
+        Module['stdin'] = input || Module['stdin'];
+        Module['stdout'] = output || Module['stdout'];
+        Module['stderr'] = error || Module['stderr'];
+
+        FS.createStandardStreams();
+      },quit:function () {
+        FS.init.initialized = false;
+        for (var i = 0; i < FS.streams.length; i++) {
+          var stream = FS.streams[i];
+          if (!stream) {
+            continue;
+          }
+          FS.close(stream);
+        }
+      },getMode:function (canRead, canWrite) {
+        var mode = 0;
+        if (canRead) mode |= 292 | 73;
+        if (canWrite) mode |= 146;
+        return mode;
+      },joinPath:function (parts, forceRelative) {
+        var path = PATH.join.apply(null, parts);
+        if (forceRelative && path[0] == '/') path = path.substr(1);
+        return path;
+      },absolutePath:function (relative, base) {
+        return PATH.resolve(base, relative);
+      },standardizePath:function (path) {
+        return PATH.normalize(path);
+      },findObject:function (path, dontResolveLastLink) {
+        var ret = FS.analyzePath(path, dontResolveLastLink);
+        if (ret.exists) {
+          return ret.object;
+        } else {
+          ___setErrNo(ret.error);
+          return null;
+        }
+      },analyzePath:function (path, dontResolveLastLink) {
+        // operate from within the context of the symlink's target
+        try {
+          var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          path = lookup.path;
+        } catch (e) {
+        }
+        var ret = {
+          isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
+          parentExists: false, parentPath: null, parentObject: null
+        };
+        try {
+          var lookup = FS.lookupPath(path, { parent: true });
+          ret.parentExists = true;
+          ret.parentPath = lookup.path;
+          ret.parentObject = lookup.node;
+          ret.name = PATH.basename(path);
+          lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          ret.exists = true;
+          ret.path = lookup.path;
+          ret.object = lookup.node;
+          ret.name = lookup.node.name;
+          ret.isRoot = lookup.path === '/';
+        } catch (e) {
+          ret.error = e.errno;
+        };
+        return ret;
+      },createFolder:function (parent, name, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.mkdir(path, mode);
+      },createPath:function (parent, path, canRead, canWrite) {
+        parent = typeof parent === 'string' ? parent : FS.getPath(parent);
+        var parts = path.split('/').reverse();
+        while (parts.length) {
+          var part = parts.pop();
+          if (!part) continue;
+          var current = PATH.join2(parent, part);
+          try {
+            FS.mkdir(current);
+          } catch (e) {
+            // ignore EEXIST
+          }
+          parent = current;
+        }
+        return current;
+      },createFile:function (parent, name, properties, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.create(path, mode);
+      },createDataFile:function (parent, name, data, canRead, canWrite, canOwn) {
+        var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
+        var mode = FS.getMode(canRead, canWrite);
+        var node = FS.create(path, mode);
+        if (data) {
+          if (typeof data === 'string') {
+            var arr = new Array(data.length);
+            for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
+            data = arr;
+          }
+          // make sure we can write to the file
+          FS.chmod(node, mode | 146);
+          var stream = FS.open(node, 'w');
+          FS.write(stream, data, 0, data.length, 0, canOwn);
+          FS.close(stream);
+          FS.chmod(node, mode);
+        }
+        return node;
+      },createDevice:function (parent, name, input, output) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(!!input, !!output);
+        if (!FS.createDevice.major) FS.createDevice.major = 64;
+        var dev = FS.makedev(FS.createDevice.major++, 0);
+        // Create a fake device that a set of stream ops to emulate
+        // the old behavior.
+        FS.registerDevice(dev, {
+          open: function(stream) {
+            stream.seekable = false;
+          },
+          close: function(stream) {
+            // flush any pending line data
+            if (output && output.buffer && output.buffer.length) {
+              output(10);
+            }
+          },
+          read: function(stream, buffer, offset, length, pos /* ignored */) {
+            var bytesRead = 0;
+            for (var i = 0; i < length; i++) {
+              var result;
+              try {
+                result = input();
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+              if (result === undefined && bytesRead === 0) {
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+              if (result === null || result === undefined) break;
+              bytesRead++;
+              buffer[offset+i] = result;
+            }
+            if (bytesRead) {
+              stream.node.timestamp = Date.now();
+            }
+            return bytesRead;
+          },
+          write: function(stream, buffer, offset, length, pos) {
+            for (var i = 0; i < length; i++) {
+              try {
+                output(buffer[offset+i]);
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+            }
+            if (length) {
+              stream.node.timestamp = Date.now();
+            }
+            return i;
+          }
+        });
+        return FS.mkdev(path, mode, dev);
+      },createLink:function (parent, name, target, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        return FS.symlink(target, path);
+      },forceLoadFile:function (obj) {
+        if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
+        var success = true;
+        if (typeof XMLHttpRequest !== 'undefined') {
+          throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
+        } else if (Module['read']) {
+          // Command-line.
+          try {
+            // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
+            //          read() will try to parse UTF8.
+            obj.contents = intArrayFromString(Module['read'](obj.url), true);
+          } catch (e) {
+            success = false;
+          }
+        } else {
+          throw new Error('Cannot load without read() or XMLHttpRequest.');
+        }
+        if (!success) ___setErrNo(ERRNO_CODES.EIO);
+        return success;
+      },createLazyFile:function (parent, name, url, canRead, canWrite) {
+        // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
+        function LazyUint8Array() {
+          this.lengthKnown = false;
+          this.chunks = []; // Loaded chunks. Index is the chunk number
+        }
+        LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
+          if (idx > this.length-1 || idx < 0) {
+            return undefined;
+          }
+          var chunkOffset = idx % this.chunkSize;
+          var chunkNum = Math.floor(idx / this.chunkSize);
+          return this.getter(chunkNum)[chunkOffset];
+        }
+        LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
+          this.getter = getter;
+        }
+        LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
+            // Find length
+            var xhr = new XMLHttpRequest();
+            xhr.open('HEAD', url, false);
+            xhr.send(null);
+            if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+            var datalength = Number(xhr.getResponseHeader("Content-length"));
+            var header;
+            var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
+            var chunkSize = 1024*1024; // Chunk size in bytes
+
+            if (!hasByteServing) chunkSize = datalength;
+
+            // Function to get a range from the remote URL.
+            var doXHR = (function(from, to) {
+              if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
+              if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
+
+              // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
+              var xhr = new XMLHttpRequest();
+              xhr.open('GET', url, false);
+              if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
+
+              // Some hints to the browser that we want binary data.
+              if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
+              if (xhr.overrideMimeType) {
+                xhr.overrideMimeType('text/plain; charset=x-user-defined');
+              }
+
+              xhr.send(null);
+              if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+              if (xhr.response !== undefined) {
+                return new Uint8Array(xhr.response || []);
+              } else {
+                return intArrayFromString(xhr.responseText || '', true);
+              }
+            });
+            var lazyArray = this;
+            lazyArray.setDataGetter(function(chunkNum) {
+              var start = chunkNum * chunkSize;
+              var end = (chunkNum+1) * chunkSize - 1; // including this byte
+              end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
+                lazyArray.chunks[chunkNum] = doXHR(start, end);
+              }
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
+              return lazyArray.chunks[chunkNum];
+            });
+
+            this._length = datalength;
+            this._chunkSize = chunkSize;
+            this.lengthKnown = true;
+        }
+        if (typeof XMLHttpRequest !== 'undefined') {
+          if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
+          var lazyArray = new LazyUint8Array();
+          Object.defineProperty(lazyArray, "length", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._length;
+              }
+          });
+          Object.defineProperty(lazyArray, "chunkSize", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._chunkSize;
+              }
+          });
+
+          var properties = { isDevice: false, contents: lazyArray };
+        } else {
+          var properties = { isDevice: false, url: url };
+        }
+
+        var node = FS.createFile(parent, name, properties, canRead, canWrite);
+        // This is a total hack, but I want to get this lazy file code out of the
+        // core of MEMFS. If we want to keep this lazy file concept I feel it should
+        // be its own thin LAZYFS proxying calls to MEMFS.
+        if (properties.contents) {
+          node.contents = properties.contents;
+        } else if (properties.url) {
+          node.contents = null;
+          node.url = properties.url;
+        }
+        // override each stream op with one that tries to force load the lazy file first
+        var stream_ops = {};
+        var keys = Object.keys(node.stream_ops);
+        keys.forEach(function(key) {
+          var fn = node.stream_ops[key];
+          stream_ops[key] = function forceLoadLazyFile() {
+            if (!FS.forceLoadFile(node)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            return fn.apply(null, arguments);
+          };
+        });
+        // use a custom read function
+        stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
+          if (!FS.forceLoadFile(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EIO);
+          }
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (contents.slice) { // normal array
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          } else {
+            for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
+              buffer[offset + i] = contents.get(position + i);
+            }
+          }
+          return size;
+        };
+        node.stream_ops = stream_ops;
+        return node;
+      },createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
+        Browser.init();
+        // TODO we should allow people to just pass in a complete filename instead
+        // of parent and name being that we just join them anyways
+        var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent;
+        function processData(byteArray) {
+          function finish(byteArray) {
+            if (!dontCreateFile) {
+              FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
+            }
+            if (onload) onload();
+            removeRunDependency('cp ' + fullname);
+          }
+          var handled = false;
+          Module['preloadPlugins'].forEach(function(plugin) {
+            if (handled) return;
+            if (plugin['canHandle'](fullname)) {
+              plugin['handle'](byteArray, fullname, finish, function() {
+                if (onerror) onerror();
+                removeRunDependency('cp ' + fullname);
+              });
+              handled = true;
+            }
+          });
+          if (!handled) finish(byteArray);
+        }
+        addRunDependency('cp ' + fullname);
+        if (typeof url == 'string') {
+          Browser.asyncLoad(url, function(byteArray) {
+            processData(byteArray);
+          }, onerror);
+        } else {
+          processData(url);
+        }
+      },indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_NAME:function () {
+        return 'EM_FS_' + window.location.pathname;
+      },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
+          console.log('creating db');
+          var db = openRequest.result;
+          db.createObjectStore(FS.DB_STORE_NAME);
+        };
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var putRequest = files.put(FS.analyzePath(path).object.contents, path);
+            putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
+            putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      },loadFilesFromDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = onerror; // no database to load from
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          try {
+            var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
+          } catch(e) {
+            onerror(e);
+            return;
+          }
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var getRequest = files.get(path);
+            getRequest.onsuccess = function getRequest_onsuccess() {
+              if (FS.analyzePath(path).exists) {
+                FS.unlink(path);
+              }
+              FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
+              ok++;
+              if (ok + fail == total) finish();
+            };
+            getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      }};
+
+
+
+
+  function _mkport() { throw 'TODO' }var SOCKFS={mount:function (mount) {
+        return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createSocket:function (family, type, protocol) {
+        var streaming = type == 1;
+        if (protocol) {
+          assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp
+        }
+
+        // create our internal socket structure
+        var sock = {
+          family: family,
+          type: type,
+          protocol: protocol,
+          server: null,
+          peers: {},
+          pending: [],
+          recv_queue: [],
+          sock_ops: SOCKFS.websocket_sock_ops
+        };
+
+        // create the filesystem node to store the socket structure
+        var name = SOCKFS.nextname();
+        var node = FS.createNode(SOCKFS.root, name, 49152, 0);
+        node.sock = sock;
+
+        // and the wrapping stream that enables library functions such
+        // as read and write to indirectly interact with the socket
+        var stream = FS.createStream({
+          path: name,
+          node: node,
+          flags: FS.modeStringToFlags('r+'),
+          seekable: false,
+          stream_ops: SOCKFS.stream_ops
+        });
+
+        // map the new stream to the socket structure (sockets have a 1:1
+        // relationship with a stream)
+        sock.stream = stream;
+
+        return sock;
+      },getSocket:function (fd) {
+        var stream = FS.getStream(fd);
+        if (!stream || !FS.isSocket(stream.node.mode)) {
+          return null;
+        }
+        return stream.node.sock;
+      },stream_ops:{poll:function (stream) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.poll(sock);
+        },ioctl:function (stream, request, varargs) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.ioctl(sock, request, varargs);
+        },read:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          var msg = sock.sock_ops.recvmsg(sock, length);
+          if (!msg) {
+            // socket is closed
+            return 0;
+          }
+          buffer.set(msg.buffer, offset);
+          return msg.buffer.length;
+        },write:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.sendmsg(sock, buffer, offset, length);
+        },close:function (stream) {
+          var sock = stream.node.sock;
+          sock.sock_ops.close(sock);
+        }},nextname:function () {
+        if (!SOCKFS.nextname.current) {
+          SOCKFS.nextname.current = 0;
+        }
+        return 'socket[' + (SOCKFS.nextname.current++) + ']';
+      },websocket_sock_ops:{createPeer:function (sock, addr, port) {
+          var ws;
+
+          if (typeof addr === 'object') {
+            ws = addr;
+            addr = null;
+            port = null;
+          }
+
+          if (ws) {
+            // for sockets that've already connected (e.g. we're the server)
+            // we can inspect the _socket property for the address
+            if (ws._socket) {
+              addr = ws._socket.remoteAddress;
+              port = ws._socket.remotePort;
+            }
+            // if we're just now initializing a connection to the remote,
+            // inspect the url property
+            else {
+              var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
+              if (!result) {
+                throw new Error('WebSocket URL must be in the format ws(s)://address:port');
+              }
+              addr = result[1];
+              port = parseInt(result[2], 10);
+            }
+          } else {
+            // create the actual websocket object and connect
+            try {
+              // runtimeConfig gets set to true if WebSocket runtime configuration is available.
+              var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
+
+              // The default value is 'ws://' the replace is needed because the compiler replaces "//" comments with '#'
+              // comments without checking context, so we'd end up with ws:#, the replace swaps the "#" for "//" again.
+              var url = 'ws:#'.replace('#', '//');
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['url']) {
+                  url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
+                }
+              }
+
+              if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
+                url = url + addr + ':' + port;
+              }
+
+              // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
+              var subProtocols = 'binary'; // The default value is 'binary'
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['subprotocol']) {
+                  subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
+                }
+              }
+
+              // The regex trims the string (removes spaces at the beginning and end, then splits the string by
+              // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
+              subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
+
+              // The node ws library API for specifying optional subprotocol is slightly different than the browser's.
+              var opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols;
+
+              // If node we use the ws library.
+              var WebSocket = ENVIRONMENT_IS_NODE ? require('ws') : window['WebSocket'];
+              ws = new WebSocket(url, opts);
+              ws.binaryType = 'arraybuffer';
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH);
+            }
+          }
+
+
+          var peer = {
+            addr: addr,
+            port: port,
+            socket: ws,
+            dgram_send_queue: []
+          };
+
+          SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+          SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
+
+          // if this is a bound dgram socket, send the port number first to allow
+          // us to override the ephemeral port reported to us by remotePort on the
+          // remote end.
+          if (sock.type === 2 && typeof sock.sport !== 'undefined') {
+            peer.dgram_send_queue.push(new Uint8Array([
+                255, 255, 255, 255,
+                'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
+                ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
+            ]));
+          }
+
+          return peer;
+        },getPeer:function (sock, addr, port) {
+          return sock.peers[addr + ':' + port];
+        },addPeer:function (sock, peer) {
+          sock.peers[peer.addr + ':' + peer.port] = peer;
+        },removePeer:function (sock, peer) {
+          delete sock.peers[peer.addr + ':' + peer.port];
+        },handlePeerEvents:function (sock, peer) {
+          var first = true;
+
+          var handleOpen = function () {
+            try {
+              var queued = peer.dgram_send_queue.shift();
+              while (queued) {
+                peer.socket.send(queued);
+                queued = peer.dgram_send_queue.shift();
+              }
+            } catch (e) {
+              // not much we can do here in the way of proper error handling as we've already
+              // lied and said this data was sent. shut it down.
+              peer.socket.close();
+            }
+          };
+
+          function handleMessage(data) {
+            assert(typeof data !== 'string' && data.byteLength !== undefined);  // must receive an ArrayBuffer
+            data = new Uint8Array(data);  // make a typed array view on the array buffer
+
+
+            // if this is the port message, override the peer's port with it
+            var wasfirst = first;
+            first = false;
+            if (wasfirst &&
+                data.length === 10 &&
+                data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
+                data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
+              // update the peer's port and it's key in the peer map
+              var newport = ((data[8] << 8) | data[9]);
+              SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+              peer.port = newport;
+              SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+              return;
+            }
+
+            sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
+          };
+
+          if (ENVIRONMENT_IS_NODE) {
+            peer.socket.on('open', handleOpen);
+            peer.socket.on('message', function(data, flags) {
+              if (!flags.binary) {
+                return;
+              }
+              handleMessage((new Uint8Array(data)).buffer);  // copy from node Buffer -> ArrayBuffer
+            });
+            peer.socket.on('error', function() {
+              // don't throw
+            });
+          } else {
+            peer.socket.onopen = handleOpen;
+            peer.socket.onmessage = function peer_socket_onmessage(event) {
+              handleMessage(event.data);
+            };
+          }
+        },poll:function (sock) {
+          if (sock.type === 1 && sock.server) {
+            // listen sockets should only say they're available for reading
+            // if there are pending clients.
+            return sock.pending.length ? (64 | 1) : 0;
+          }
+
+          var mask = 0;
+          var dest = sock.type === 1 ?  // we only care about the socket state for connection-based sockets
+            SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
+            null;
+
+          if (sock.recv_queue.length ||
+              !dest ||  // connection-less sockets are always ready to read
+              (dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {  // let recv return 0 once closed
+            mask |= (64 | 1);
+          }
+
+          if (!dest ||  // connection-less sockets are always ready to write
+              (dest && dest.socket.readyState === dest.socket.OPEN)) {
+            mask |= 4;
+          }
+
+          if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {
+            mask |= 16;
+          }
+
+          return mask;
+        },ioctl:function (sock, request, arg) {
+          switch (request) {
+            case 21531:
+              var bytes = 0;
+              if (sock.recv_queue.length) {
+                bytes = sock.recv_queue[0].data.length;
+              }
+              HEAP32[((arg)>>2)]=bytes;
+              return 0;
+            default:
+              return ERRNO_CODES.EINVAL;
+          }
+        },close:function (sock) {
+          // if we've spawned a listen server, close it
+          if (sock.server) {
+            try {
+              sock.server.close();
+            } catch (e) {
+            }
+            sock.server = null;
+          }
+          // close any peer connections
+          var peers = Object.keys(sock.peers);
+          for (var i = 0; i < peers.length; i++) {
+            var peer = sock.peers[peers[i]];
+            try {
+              peer.socket.close();
+            } catch (e) {
+            }
+            SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+          }
+          return 0;
+        },bind:function (sock, addr, port) {
+          if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already bound
+          }
+          sock.saddr = addr;
+          sock.sport = port || _mkport();
+          // in order to emulate dgram sockets, we need to launch a listen server when
+          // binding on a connection-less socket
+          // note: this is only required on the server side
+          if (sock.type === 2) {
+            // close the existing server if it exists
+            if (sock.server) {
+              sock.server.close();
+              sock.server = null;
+            }
+            // swallow error operation not supported error that occurs when binding in the
+            // browser where this isn't supported
+            try {
+              sock.sock_ops.listen(sock, 0);
+            } catch (e) {
+              if (!(e instanceof FS.ErrnoError)) throw e;
+              if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e;
+            }
+          }
+        },connect:function (sock, addr, port) {
+          if (sock.server) {
+            throw new FS.ErrnoError(ERRNO_CODS.EOPNOTSUPP);
+          }
+
+          // TODO autobind
+          // if (!sock.addr && sock.type == 2) {
+          // }
+
+          // early out if we're already connected / in the middle of connecting
+          if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') {
+            var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+            if (dest) {
+              if (dest.socket.readyState === dest.socket.CONNECTING) {
+                throw new FS.ErrnoError(ERRNO_CODES.EALREADY);
+              } else {
+                throw new FS.ErrnoError(ERRNO_CODES.EISCONN);
+              }
+            }
+          }
+
+          // add the socket to our peer list and set our
+          // destination address / port to match
+          var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+          sock.daddr = peer.addr;
+          sock.dport = peer.port;
+
+          // always "fail" in non-blocking mode
+          throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS);
+        },listen:function (sock, backlog) {
+          if (!ENVIRONMENT_IS_NODE) {
+            throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+          }
+          if (sock.server) {
+             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already listening
+          }
+          var WebSocketServer = require('ws').Server;
+          var host = sock.saddr;
+          sock.server = new WebSocketServer({
+            host: host,
+            port: sock.sport
+            // TODO support backlog
+          });
+
+          sock.server.on('connection', function(ws) {
+            if (sock.type === 1) {
+              var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
+
+              // create a peer on the new socket
+              var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
+              newsock.daddr = peer.addr;
+              newsock.dport = peer.port;
+
+              // push to queue for accept to pick up
+              sock.pending.push(newsock);
+            } else {
+              // create a peer on the listen socket so calling sendto
+              // with the listen socket and an address will resolve
+              // to the correct client
+              SOCKFS.websocket_sock_ops.createPeer(sock, ws);
+            }
+          });
+          sock.server.on('closed', function() {
+            sock.server = null;
+          });
+          sock.server.on('error', function() {
+            // don't throw
+          });
+        },accept:function (listensock) {
+          if (!listensock.server) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          var newsock = listensock.pending.shift();
+          newsock.stream.flags = listensock.stream.flags;
+          return newsock;
+        },getname:function (sock, peer) {
+          var addr, port;
+          if (peer) {
+            if (sock.daddr === undefined || sock.dport === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            }
+            addr = sock.daddr;
+            port = sock.dport;
+          } else {
+            // TODO saddr and sport will be set for bind()'d UDP sockets, but what
+            // should we be returning for TCP sockets that've been connect()'d?
+            addr = sock.saddr || 0;
+            port = sock.sport || 0;
+          }
+          return { addr: addr, port: port };
+        },sendmsg:function (sock, buffer, offset, length, addr, port) {
+          if (sock.type === 2) {
+            // connection-less sockets will honor the message address,
+            // and otherwise fall back to the bound destination address
+            if (addr === undefined || port === undefined) {
+              addr = sock.daddr;
+              port = sock.dport;
+            }
+            // if there was no address to fall back to, error out
+            if (addr === undefined || port === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ);
+            }
+          } else {
+            // connection-based sockets will only use the bound
+            addr = sock.daddr;
+            port = sock.dport;
+          }
+
+          // find the peer for the destination address
+          var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
+
+          // early out if not connected with a connection-based socket
+          if (sock.type === 1) {
+            if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            } else if (dest.socket.readyState === dest.socket.CONNECTING) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // create a copy of the incoming data to send, as the WebSocket API
+          // doesn't work entirely with an ArrayBufferView, it'll just send
+          // the entire underlying buffer
+          var data;
+          if (buffer instanceof Array || buffer instanceof ArrayBuffer) {
+            data = buffer.slice(offset, offset + length);
+          } else {  // ArrayBufferView
+            data = buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + length);
+          }
+
+          // if we're emulating a connection-less dgram socket and don't have
+          // a cached connection, queue the buffer to send upon connect and
+          // lie, saying the data was sent now.
+          if (sock.type === 2) {
+            if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
+              // if we're not connected, open a new connection
+              if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+              }
+              dest.dgram_send_queue.push(data);
+              return length;
+            }
+          }
+
+          try {
+            // send the actual data
+            dest.socket.send(data);
+            return length;
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+        },recvmsg:function (sock, length) {
+          // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
+          if (sock.type === 1 && sock.server) {
+            // tcp servers should not be recv()'ing on the listen socket
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+          }
+
+          var queued = sock.recv_queue.shift();
+          if (!queued) {
+            if (sock.type === 1) {
+              var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+
+              if (!dest) {
+                // if we have a destination address but are not connected, error out
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+              }
+              else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                // return null if the socket has closed
+                return null;
+              }
+              else {
+                // else, our socket is in a valid state but truly has nothing available
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+            } else {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
+          // requeued TCP data it'll be an ArrayBufferView
+          var queuedLength = queued.data.byteLength || queued.data.length;
+          var queuedOffset = queued.data.byteOffset || 0;
+          var queuedBuffer = queued.data.buffer || queued.data;
+          var bytesRead = Math.min(length, queuedLength);
+          var res = {
+            buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
+            addr: queued.addr,
+            port: queued.port
+          };
+
+
+          // push back any unread data for TCP connections
+          if (sock.type === 1 && bytesRead < queuedLength) {
+            var bytesRemaining = queuedLength - bytesRead;
+            queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
+            sock.recv_queue.unshift(queued);
+          }
+
+          return res;
+        }}};function _send(fd, buf, len, flags) {
+      var sock = SOCKFS.getSocket(fd);
+      if (!sock) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      // TODO honor flags
+      return _write(fd, buf, len);
+    }
+
+  function _pwrite(fildes, buf, nbyte, offset) {
+      // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte, offset);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _write(fildes, buf, nbyte) {
+      // ssize_t write(int fildes, const void *buf, size_t nbyte);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+
+
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }
+
+  function _fileno(stream) {
+      // int fileno(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
+      stream = FS.getStreamFromPtr(stream);
+      if (!stream) return -1;
+      return stream.fd;
+    }function _fwrite(ptr, size, nitems, stream) {
+      // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
+      var bytesToWrite = nitems * size;
+      if (bytesToWrite == 0) return 0;
+      var fd = _fileno(stream);
+      var bytesWritten = _write(fd, ptr, bytesToWrite);
+      if (bytesWritten == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return 0;
+      } else {
+        return Math.floor(bytesWritten / size);
+      }
+    }
+
+
+
+  Module["_strlen"] = _strlen;
+
+  function __reallyNegative(x) {
+      return x < 0 || (x === 0 && (1/x) === -Infinity);
+    }function __formatString(format, varargs) {
+      var textIndex = format;
+      var argIndex = 0;
+      function getNextArg(type) {
+        // NOTE: Explicitly ignoring type safety. Otherwise this fails:
+        //       int x = 4; printf("%c\n", (char)x);
+        var ret;
+        if (type === 'double') {
+          ret = HEAPF64[(((varargs)+(argIndex))>>3)];
+        } else if (type == 'i64') {
+          ret = [HEAP32[(((varargs)+(argIndex))>>2)],
+                 HEAP32[(((varargs)+(argIndex+4))>>2)]];
+
+        } else {
+          type = 'i32'; // varargs are always i32, i64, or double
+          ret = HEAP32[(((varargs)+(argIndex))>>2)];
+        }
+        argIndex += Runtime.getNativeFieldSize(type);
+        return ret;
+      }
+
+      var ret = [];
+      var curr, next, currArg;
+      while(1) {
+        var startTextIndex = textIndex;
+        curr = HEAP8[(textIndex)];
+        if (curr === 0) break;
+        next = HEAP8[((textIndex+1)|0)];
+        if (curr == 37) {
+          // Handle flags.
+          var flagAlwaysSigned = false;
+          var flagLeftAlign = false;
+          var flagAlternative = false;
+          var flagZeroPad = false;
+          var flagPadSign = false;
+          flagsLoop: while (1) {
+            switch (next) {
+              case 43:
+                flagAlwaysSigned = true;
+                break;
+              case 45:
+                flagLeftAlign = true;
+                break;
+              case 35:
+                flagAlternative = true;
+                break;
+              case 48:
+                if (flagZeroPad) {
+                  break flagsLoop;
+                } else {
+                  flagZeroPad = true;
+                  break;
+                }
+              case 32:
+                flagPadSign = true;
+                break;
+              default:
+                break flagsLoop;
+            }
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          }
+
+          // Handle width.
+          var width = 0;
+          if (next == 42) {
+            width = getNextArg('i32');
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          } else {
+            while (next >= 48 && next <= 57) {
+              width = width * 10 + (next - 48);
+              textIndex++;
+              next = HEAP8[((textIndex+1)|0)];
+            }
+          }
+
+          // Handle precision.
+          var precisionSet = false, precision = -1;
+          if (next == 46) {
+            precision = 0;
+            precisionSet = true;
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+            if (next == 42) {
+              precision = getNextArg('i32');
+              textIndex++;
+            } else {
+              while(1) {
+                var precisionChr = HEAP8[((textIndex+1)|0)];
+                if (precisionChr < 48 ||
+                    precisionChr > 57) break;
+                precision = precision * 10 + (precisionChr - 48);
+                textIndex++;
+              }
+            }
+            next = HEAP8[((textIndex+1)|0)];
+          }
+          if (precision < 0) {
+            precision = 6; // Standard default.
+            precisionSet = false;
+          }
+
+          // Handle integer sizes. WARNING: These assume a 32-bit architecture!
+          var argSize;
+          switch (String.fromCharCode(next)) {
+            case 'h':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 104) {
+                textIndex++;
+                argSize = 1; // char (actually i32 in varargs)
+              } else {
+                argSize = 2; // short (actually i32 in varargs)
+              }
+              break;
+            case 'l':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 108) {
+                textIndex++;
+                argSize = 8; // long long
+              } else {
+                argSize = 4; // long
+              }
+              break;
+            case 'L': // long long
+            case 'q': // int64_t
+            case 'j': // intmax_t
+              argSize = 8;
+              break;
+            case 'z': // size_t
+            case 't': // ptrdiff_t
+            case 'I': // signed ptrdiff_t or unsigned size_t
+              argSize = 4;
+              break;
+            default:
+              argSize = null;
+          }
+          if (argSize) textIndex++;
+          next = HEAP8[((textIndex+1)|0)];
+
+          // Handle type specifier.
+          switch (String.fromCharCode(next)) {
+            case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': {
+              // Integer.
+              var signed = next == 100 || next == 105;
+              argSize = argSize || 4;
+              var currArg = getNextArg('i' + (argSize * 8));
+              var argText;
+              // Flatten i64-1 [low, high] into a (slightly rounded) double
+              if (argSize == 8) {
+                currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117);
+              }
+              // Truncate to requested size.
+              if (argSize <= 4) {
+                var limit = Math.pow(256, argSize) - 1;
+                currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
+              }
+              // Format the number.
+              var currAbsArg = Math.abs(currArg);
+              var prefix = '';
+              if (next == 100 || next == 105) {
+                argText = reSign(currArg, 8 * argSize, 1).toString(10);
+              } else if (next == 117) {
+                argText = unSign(currArg, 8 * argSize, 1).toString(10);
+                currArg = Math.abs(currArg);
+              } else if (next == 111) {
+                argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
+              } else if (next == 120 || next == 88) {
+                prefix = (flagAlternative && currArg != 0) ? '0x' : '';
+                if (currArg < 0) {
+                  // Represent negative numbers in hex as 2's complement.
+                  currArg = -currArg;
+                  argText = (currAbsArg - 1).toString(16);
+                  var buffer = [];
+                  for (var i = 0; i < argText.length; i++) {
+                    buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
+                  }
+                  argText = buffer.join('');
+                  while (argText.length < argSize * 2) argText = 'f' + argText;
+                } else {
+                  argText = currAbsArg.toString(16);
+                }
+                if (next == 88) {
+                  prefix = prefix.toUpperCase();
+                  argText = argText.toUpperCase();
+                }
+              } else if (next == 112) {
+                if (currAbsArg === 0) {
+                  argText = '(nil)';
+                } else {
+                  prefix = '0x';
+                  argText = currAbsArg.toString(16);
+                }
+              }
+              if (precisionSet) {
+                while (argText.length < precision) {
+                  argText = '0' + argText;
+                }
+              }
+
+              // Add sign if needed
+              if (currArg >= 0) {
+                if (flagAlwaysSigned) {
+                  prefix = '+' + prefix;
+                } else if (flagPadSign) {
+                  prefix = ' ' + prefix;
+                }
+              }
+
+              // Move sign to prefix so we zero-pad after the sign
+              if (argText.charAt(0) == '-') {
+                prefix = '-' + prefix;
+                argText = argText.substr(1);
+              }
+
+              // Add padding.
+              while (prefix.length + argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad) {
+                    argText = '0' + argText;
+                  } else {
+                    prefix = ' ' + prefix;
+                  }
+                }
+              }
+
+              // Insert the result into the buffer.
+              argText = prefix + argText;
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': {
+              // Float.
+              var currArg = getNextArg('double');
+              var argText;
+              if (isNaN(currArg)) {
+                argText = 'nan';
+                flagZeroPad = false;
+              } else if (!isFinite(currArg)) {
+                argText = (currArg < 0 ? '-' : '') + 'inf';
+                flagZeroPad = false;
+              } else {
+                var isGeneral = false;
+                var effectivePrecision = Math.min(precision, 20);
+
+                // Convert g/G to f/F or e/E, as per:
+                // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
+                if (next == 103 || next == 71) {
+                  isGeneral = true;
+                  precision = precision || 1;
+                  var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
+                  if (precision > exponent && exponent >= -4) {
+                    next = ((next == 103) ? 'f' : 'F').charCodeAt(0);
+                    precision -= exponent + 1;
+                  } else {
+                    next = ((next == 103) ? 'e' : 'E').charCodeAt(0);
+                    precision--;
+                  }
+                  effectivePrecision = Math.min(precision, 20);
+                }
+
+                if (next == 101 || next == 69) {
+                  argText = currArg.toExponential(effectivePrecision);
+                  // Make sure the exponent has at least 2 digits.
+                  if (/[eE][-+]\d$/.test(argText)) {
+                    argText = argText.slice(0, -1) + '0' + argText.slice(-1);
+                  }
+                } else if (next == 102 || next == 70) {
+                  argText = currArg.toFixed(effectivePrecision);
+                  if (currArg === 0 && __reallyNegative(currArg)) {
+                    argText = '-' + argText;
+                  }
+                }
+
+                var parts = argText.split('e');
+                if (isGeneral && !flagAlternative) {
+                  // Discard trailing zeros and periods.
+                  while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
+                         (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
+                    parts[0] = parts[0].slice(0, -1);
+                  }
+                } else {
+                  // Make sure we have a period in alternative mode.
+                  if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
+                  // Zero pad until required precision.
+                  while (precision > effectivePrecision++) parts[0] += '0';
+                }
+                argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
+
+                // Capitalize 'E' if needed.
+                if (next == 69) argText = argText.toUpperCase();
+
+                // Add sign.
+                if (currArg >= 0) {
+                  if (flagAlwaysSigned) {
+                    argText = '+' + argText;
+                  } else if (flagPadSign) {
+                    argText = ' ' + argText;
+                  }
+                }
+              }
+
+              // Add padding.
+              while (argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
+                    argText = argText[0] + '0' + argText.slice(1);
+                  } else {
+                    argText = (flagZeroPad ? '0' : ' ') + argText;
+                  }
+                }
+              }
+
+              // Adjust case.
+              if (next < 97) argText = argText.toUpperCase();
+
+              // Insert the result into the buffer.
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 's': {
+              // String.
+              var arg = getNextArg('i8*');
+              var argLength = arg ? _strlen(arg) : '(null)'.length;
+              if (precisionSet) argLength = Math.min(argLength, precision);
+              if (!flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              if (arg) {
+                for (var i = 0; i < argLength; i++) {
+                  ret.push(HEAPU8[((arg++)|0)]);
+                }
+              } else {
+                ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true));
+              }
+              if (flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              break;
+            }
+            case 'c': {
+              // Character.
+              if (flagLeftAlign) ret.push(getNextArg('i8'));
+              while (--width > 0) {
+                ret.push(32);
+              }
+              if (!flagLeftAlign) ret.push(getNextArg('i8'));
+              break;
+            }
+            case 'n': {
+              // Write the length written so far to the next parameter.
+              var ptr = getNextArg('i32*');
+              HEAP32[((ptr)>>2)]=ret.length;
+              break;
+            }
+            case '%': {
+              // Literal percent sign.
+              ret.push(curr);
+              break;
+            }
+            default: {
+              // Unknown specifiers remain untouched.
+              for (var i = startTextIndex; i < textIndex + 2; i++) {
+                ret.push(HEAP8[(i)]);
+              }
+            }
+          }
+          textIndex += 2;
+          // TODO: Support a/A (hex float) and m (last error) specifiers.
+          // TODO: Support %1${specifier} for arg selection.
+        } else {
+          ret.push(curr);
+          textIndex += 1;
+        }
+      }
+      return ret;
+    }function _fprintf(stream, format, varargs) {
+      // int fprintf(FILE *restrict stream, const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var result = __formatString(format, varargs);
+      var stack = Runtime.stackSave();
+      var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream);
+      Runtime.stackRestore(stack);
+      return ret;
+    }function _printf(format, varargs) {
+      // int printf(const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var stdout = HEAP32[((_stdout)>>2)];
+      return _fprintf(stdout, format, varargs);
+    }
+
+  var _sinf=Math_sin;
+
+
+  var _sqrtf=Math_sqrt;
+
+  var _floorf=Math_floor;
+
+
+  function _fputs(s, stream) {
+      // int fputs(const char *restrict s, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fputs.html
+      var fd = _fileno(stream);
+      return _write(fd, s, _strlen(s));
+    }
+
+  function _fputc(c, stream) {
+      // int fputc(int c, FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fputc.html
+      var chr = unSign(c & 0xFF);
+      HEAP8[((_fputc.ret)|0)]=chr;
+      var fd = _fileno(stream);
+      var ret = _write(fd, _fputc.ret, 1);
+      if (ret == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return -1;
+      } else {
+        return chr;
+      }
+    }function _puts(s) {
+      // int puts(const char *s);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/puts.html
+      // NOTE: puts() always writes an extra newline.
+      var stdout = HEAP32[((_stdout)>>2)];
+      var ret = _fputs(s, stdout);
+      if (ret < 0) {
+        return ret;
+      } else {
+        var newlineRet = _fputc(10, stdout);
+        return (newlineRet < 0) ? -1 : ret + 1;
+      }
+    }
+
+  function _clock() {
+      if (_clock.start === undefined) _clock.start = Date.now();
+      return Math.floor((Date.now() - _clock.start) * (1000000/1000));
+    }
+
+
+  var ___cxa_caught_exceptions=[];function ___cxa_begin_catch(ptr) {
+      __ZSt18uncaught_exceptionv.uncaught_exception--;
+      ___cxa_caught_exceptions.push(___cxa_last_thrown_exception);
+      return ptr;
+    }
+
+  function ___errno_location() {
+      return ___errno_state;
+    }
+
+
+  function _emscripten_memcpy_big(dest, src, num) {
+      HEAPU8.set(HEAPU8.subarray(src, src+num), dest);
+      return dest;
+    }
+  Module["_memcpy"] = _memcpy;
+
+  function __ZNSt9exceptionD2Ev() {}
+
+  var Browser={mainLoop:{scheduler:null,method:"",shouldPause:false,paused:false,queue:[],pause:function () {
+          Browser.mainLoop.shouldPause = true;
+        },resume:function () {
+          if (Browser.mainLoop.paused) {
+            Browser.mainLoop.paused = false;
+            Browser.mainLoop.scheduler();
+          }
+          Browser.mainLoop.shouldPause = false;
+        },updateStatus:function () {
+          if (Module['setStatus']) {
+            var message = Module['statusMessage'] || 'Please wait...';
+            var remaining = Browser.mainLoop.remainingBlockers;
+            var expected = Browser.mainLoop.expectedBlockers;
+            if (remaining) {
+              if (remaining < expected) {
+                Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
+              } else {
+                Module['setStatus'](message);
+              }
+            } else {
+              Module['setStatus']('');
+            }
+          }
+        }},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () {
+        if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
+
+        if (Browser.initted || ENVIRONMENT_IS_WORKER) return;
+        Browser.initted = true;
+
+        try {
+          new Blob();
+          Browser.hasBlobConstructor = true;
+        } catch(e) {
+          Browser.hasBlobConstructor = false;
+          console.log("warning: no blob constructor, cannot create blobs with mimetypes");
+        }
+        Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
+        Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
+        if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
+          console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
+          Module.noImageDecoding = true;
+        }
+
+        // Support for plugins that can process preloaded files. You can add more of these to
+        // your app by creating and appending to Module.preloadPlugins.
+        //
+        // Each plugin is asked if it can handle a file based on the file's name. If it can,
+        // it is given the file's raw data. When it is done, it calls a callback with the file's
+        // (possibly modified) data. For example, a plugin might decompress a file, or it
+        // might create some side data structure for use later (like an Image element, etc.).
+
+        var imagePlugin = {};
+        imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
+          return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
+        };
+        imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
+          var b = null;
+          if (Browser.hasBlobConstructor) {
+            try {
+              b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+              if (b.size !== byteArray.length) { // Safari bug #118630
+                // Safari's Blob can only take an ArrayBuffer
+                b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
+              }
+            } catch(e) {
+              Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
+            }
+          }
+          if (!b) {
+            var bb = new Browser.BlobBuilder();
+            bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
+            b = bb.getBlob();
+          }
+          var url = Browser.URLObject.createObjectURL(b);
+          var img = new Image();
+          img.onload = function img_onload() {
+            assert(img.complete, 'Image ' + name + ' could not be decoded');
+            var canvas = document.createElement('canvas');
+            canvas.width = img.width;
+            canvas.height = img.height;
+            var ctx = canvas.getContext('2d');
+            ctx.drawImage(img, 0, 0);
+            Module["preloadedImages"][name] = canvas;
+            Browser.URLObject.revokeObjectURL(url);
+            if (onload) onload(byteArray);
+          };
+          img.onerror = function img_onerror(event) {
+            console.log('Image ' + url + ' could not be decoded');
+            if (onerror) onerror();
+          };
+          img.src = url;
+        };
+        Module['preloadPlugins'].push(imagePlugin);
+
+        var audioPlugin = {};
+        audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
+          return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
+        };
+        audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
+          var done = false;
+          function finish(audio) {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = audio;
+            if (onload) onload(byteArray);
+          }
+          function fail() {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = new Audio(); // empty shim
+            if (onerror) onerror();
+          }
+          if (Browser.hasBlobConstructor) {
+            try {
+              var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+            } catch(e) {
+              return fail();
+            }
+            var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
+            var audio = new Audio();
+            audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926
+            audio.onerror = function audio_onerror(event) {
+              if (done) return;
+              console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
+              function encode64(data) {
+                var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+                var PAD = '=';
+                var ret = '';
+                var leftchar = 0;
+                var leftbits = 0;
+                for (var i = 0; i < data.length; i++) {
+                  leftchar = (leftchar << 8) | data[i];
+                  leftbits += 8;
+                  while (leftbits >= 6) {
+                    var curr = (leftchar >> (leftbits-6)) & 0x3f;
+                    leftbits -= 6;
+                    ret += BASE[curr];
+                  }
+                }
+                if (leftbits == 2) {
+                  ret += BASE[(leftchar&3) << 4];
+                  ret += PAD + PAD;
+                } else if (leftbits == 4) {
+                  ret += BASE[(leftchar&0xf) << 2];
+                  ret += PAD;
+                }
+                return ret;
+              }
+              audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
+              finish(audio); // we don't wait for confirmation this worked - but it's worth trying
+            };
+            audio.src = url;
+            // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
+            Browser.safeSetTimeout(function() {
+              finish(audio); // try to use it even though it is not necessarily ready to play
+            }, 10000);
+          } else {
+            return fail();
+          }
+        };
+        Module['preloadPlugins'].push(audioPlugin);
+
+        // Canvas event setup
+
+        var canvas = Module['canvas'];
+
+        // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
+        // Module['forcedAspectRatio'] = 4 / 3;
+
+        canvas.requestPointerLock = canvas['requestPointerLock'] ||
+                                    canvas['mozRequestPointerLock'] ||
+                                    canvas['webkitRequestPointerLock'] ||
+                                    canvas['msRequestPointerLock'] ||
+                                    function(){};
+        canvas.exitPointerLock = document['exitPointerLock'] ||
+                                 document['mozExitPointerLock'] ||
+                                 document['webkitExitPointerLock'] ||
+                                 document['msExitPointerLock'] ||
+                                 function(){}; // no-op if function does not exist
+        canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
+
+        function pointerLockChange() {
+          Browser.pointerLock = document['pointerLockElement'] === canvas ||
+                                document['mozPointerLockElement'] === canvas ||
+                                document['webkitPointerLockElement'] === canvas ||
+                                document['msPointerLockElement'] === canvas;
+        }
+
+        document.addEventListener('pointerlockchange', pointerLockChange, false);
+        document.addEventListener('mozpointerlockchange', pointerLockChange, false);
+        document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
+        document.addEventListener('mspointerlockchange', pointerLockChange, false);
+
+        if (Module['elementPointerLock']) {
+          canvas.addEventListener("click", function(ev) {
+            if (!Browser.pointerLock && canvas.requestPointerLock) {
+              canvas.requestPointerLock();
+              ev.preventDefault();
+            }
+          }, false);
+        }
+      },createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) {
+        var ctx;
+        var errorInfo = '?';
+        function onContextCreationError(event) {
+          errorInfo = event.statusMessage || errorInfo;
+        }
+        try {
+          if (useWebGL) {
+            var contextAttributes = {
+              antialias: false,
+              alpha: false
+            };
+
+            if (webGLContextAttributes) {
+              for (var attribute in webGLContextAttributes) {
+                contextAttributes[attribute] = webGLContextAttributes[attribute];
+              }
+            }
+
+
+            canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
+            try {
+              ['experimental-webgl', 'webgl'].some(function(webglId) {
+                return ctx = canvas.getContext(webglId, contextAttributes);
+              });
+            } finally {
+              canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
+            }
+          } else {
+            ctx = canvas.getContext('2d');
+          }
+          if (!ctx) throw ':(';
+        } catch (e) {
+          Module.print('Could not create canvas: ' + [errorInfo, e]);
+          return null;
+        }
+        if (useWebGL) {
+          // Set the background of the WebGL canvas to black
+          canvas.style.backgroundColor = "black";
+
+          // Warn on context loss
+          canvas.addEventListener('webglcontextlost', function(event) {
+            alert('WebGL context lost. You will need to reload the page.');
+          }, false);
+        }
+        if (setInModule) {
+          GLctx = Module.ctx = ctx;
+          Module.useWebGL = useWebGL;
+          Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
+          Browser.init();
+        }
+        return ctx;
+      },destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) {
+        Browser.lockPointer = lockPointer;
+        Browser.resizeCanvas = resizeCanvas;
+        if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;
+        if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;
+
+        var canvas = Module['canvas'];
+        function fullScreenChange() {
+          Browser.isFullScreen = false;
+          var canvasContainer = canvas.parentNode;
+          if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+               document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+               document['fullScreenElement'] || document['fullscreenElement'] ||
+               document['msFullScreenElement'] || document['msFullscreenElement'] ||
+               document['webkitCurrentFullScreenElement']) === canvasContainer) {
+            canvas.cancelFullScreen = document['cancelFullScreen'] ||
+                                      document['mozCancelFullScreen'] ||
+                                      document['webkitCancelFullScreen'] ||
+                                      document['msExitFullscreen'] ||
+                                      document['exitFullscreen'] ||
+                                      function() {};
+            canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document);
+            if (Browser.lockPointer) canvas.requestPointerLock();
+            Browser.isFullScreen = true;
+            if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize();
+          } else {
+
+            // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
+            canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
+            canvasContainer.parentNode.removeChild(canvasContainer);
+
+            if (Browser.resizeCanvas) Browser.setWindowedCanvasSize();
+          }
+          if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen);
+          Browser.updateCanvasDimensions(canvas);
+        }
+
+        if (!Browser.fullScreenHandlersInstalled) {
+          Browser.fullScreenHandlersInstalled = true;
+          document.addEventListener('fullscreenchange', fullScreenChange, false);
+          document.addEventListener('mozfullscreenchange', fullScreenChange, false);
+          document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
+          document.addEventListener('MSFullscreenChange', fullScreenChange, false);
+        }
+
+        // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
+        var canvasContainer = document.createElement("div");
+        canvas.parentNode.insertBefore(canvasContainer, canvas);
+        canvasContainer.appendChild(canvas);
+
+        // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
+        canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] ||
+                                            canvasContainer['mozRequestFullScreen'] ||
+                                            canvasContainer['msRequestFullscreen'] ||
+                                           (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
+        canvasContainer.requestFullScreen();
+      },requestAnimationFrame:function requestAnimationFrame(func) {
+        if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js)
+          setTimeout(func, 1000/60);
+        } else {
+          if (!window.requestAnimationFrame) {
+            window.requestAnimationFrame = window['requestAnimationFrame'] ||
+                                           window['mozRequestAnimationFrame'] ||
+                                           window['webkitRequestAnimationFrame'] ||
+                                           window['msRequestAnimationFrame'] ||
+                                           window['oRequestAnimationFrame'] ||
+                                           window['setTimeout'];
+          }
+          window.requestAnimationFrame(func);
+        }
+      },safeCallback:function (func) {
+        return function() {
+          if (!ABORT) return func.apply(null, arguments);
+        };
+      },safeRequestAnimationFrame:function (func) {
+        return Browser.requestAnimationFrame(function() {
+          if (!ABORT) func();
+        });
+      },safeSetTimeout:function (func, timeout) {
+        return setTimeout(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },safeSetInterval:function (func, timeout) {
+        return setInterval(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },getMimetype:function (name) {
+        return {
+          'jpg': 'image/jpeg',
+          'jpeg': 'image/jpeg',
+          'png': 'image/png',
+          'bmp': 'image/bmp',
+          'ogg': 'audio/ogg',
+          'wav': 'audio/wav',
+          'mp3': 'audio/mpeg'
+        }[name.substr(name.lastIndexOf('.')+1)];
+      },getUserMedia:function (func) {
+        if(!window.getUserMedia) {
+          window.getUserMedia = navigator['getUserMedia'] ||
+                                navigator['mozGetUserMedia'];
+        }
+        window.getUserMedia(func);
+      },getMovementX:function (event) {
+        return event['movementX'] ||
+               event['mozMovementX'] ||
+               event['webkitMovementX'] ||
+               0;
+      },getMovementY:function (event) {
+        return event['movementY'] ||
+               event['mozMovementY'] ||
+               event['webkitMovementY'] ||
+               0;
+      },getMouseWheelDelta:function (event) {
+        return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta));
+      },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup
+        if (Browser.pointerLock) {
+          // When the pointer is locked, calculate the coordinates
+          // based on the movement of the mouse.
+          // Workaround for Firefox bug 764498
+          if (event.type != 'mousemove' &&
+              ('mozMovementX' in event)) {
+            Browser.mouseMovementX = Browser.mouseMovementY = 0;
+          } else {
+            Browser.mouseMovementX = Browser.getMovementX(event);
+            Browser.mouseMovementY = Browser.getMovementY(event);
+          }
+
+          // check if SDL is available
+          if (typeof SDL != "undefined") {
+    Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
+    Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
+          } else {
+    // just add the mouse delta to the current absolut mouse position
+    // FIXME: ideally this should be clamped against the canvas size and zero
+    Browser.mouseX += Browser.mouseMovementX;
+    Browser.mouseY += Browser.mouseMovementY;
+          }
+        } else {
+          // Otherwise, calculate the movement based on the changes
+          // in the coordinates.
+          var rect = Module["canvas"].getBoundingClientRect();
+          var x, y;
+
+          // Neither .scrollX or .pageXOffset are defined in a spec, but
+          // we prefer .scrollX because it is currently in a spec draft.
+          // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
+          var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);
+          var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);
+          if (event.type == 'touchstart' ||
+              event.type == 'touchend' ||
+              event.type == 'touchmove') {
+            var t = event.touches.item(0);
+            if (t) {
+              x = t.pageX - (scrollX + rect.left);
+              y = t.pageY - (scrollY + rect.top);
+            } else {
+              return;
+            }
+          } else {
+            x = event.pageX - (scrollX + rect.left);
+            y = event.pageY - (scrollY + rect.top);
+          }
+
+          // the canvas might be CSS-scaled compared to its backbuffer;
+          // SDL-using content will want mouse coordinates in terms
+          // of backbuffer units.
+          var cw = Module["canvas"].width;
+          var ch = Module["canvas"].height;
+          x = x * (cw / rect.width);
+          y = y * (ch / rect.height);
+
+          Browser.mouseMovementX = x - Browser.mouseX;
+          Browser.mouseMovementY = y - Browser.mouseY;
+          Browser.mouseX = x;
+          Browser.mouseY = y;
+        }
+      },xhrLoad:function (url, onload, onerror) {
+        var xhr = new XMLHttpRequest();
+        xhr.open('GET', url, true);
+        xhr.responseType = 'arraybuffer';
+        xhr.onload = function xhr_onload() {
+          if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
+            onload(xhr.response);
+          } else {
+            onerror();
+          }
+        };
+        xhr.onerror = onerror;
+        xhr.send(null);
+      },asyncLoad:function (url, onload, onerror, noRunDep) {
+        Browser.xhrLoad(url, function(arrayBuffer) {
+          assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
+          onload(new Uint8Array(arrayBuffer));
+          if (!noRunDep) removeRunDependency('al ' + url);
+        }, function(event) {
+          if (onerror) {
+            onerror();
+          } else {
+            throw 'Loading data file "' + url + '" failed.';
+          }
+        });
+        if (!noRunDep) addRunDependency('al ' + url);
+      },resizeListeners:[],updateResizeListeners:function () {
+        var canvas = Module['canvas'];
+        Browser.resizeListeners.forEach(function(listener) {
+          listener(canvas.width, canvas.height);
+        });
+      },setCanvasSize:function (width, height, noUpdates) {
+        var canvas = Module['canvas'];
+        Browser.updateCanvasDimensions(canvas, width, height);
+        if (!noUpdates) Browser.updateResizeListeners();
+      },windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+    var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+    flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
+    HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },setWindowedCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+    var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+    flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
+    HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },updateCanvasDimensions:function (canvas, wNative, hNative) {
+        if (wNative && hNative) {
+          canvas.widthNative = wNative;
+          canvas.heightNative = hNative;
+        } else {
+          wNative = canvas.widthNative;
+          hNative = canvas.heightNative;
+        }
+        var w = wNative;
+        var h = hNative;
+        if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
+          if (w/h < Module['forcedAspectRatio']) {
+            w = Math.round(h * Module['forcedAspectRatio']);
+          } else {
+            h = Math.round(w / Module['forcedAspectRatio']);
+          }
+        }
+        if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+             document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+             document['fullScreenElement'] || document['fullscreenElement'] ||
+             document['msFullScreenElement'] || document['msFullscreenElement'] ||
+             document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
+           var factor = Math.min(screen.width / w, screen.height / h);
+           w = Math.round(w * factor);
+           h = Math.round(h * factor);
+        }
+        if (Browser.resizeCanvas) {
+          if (canvas.width  != w) canvas.width  = w;
+          if (canvas.height != h) canvas.height = h;
+          if (typeof canvas.style != 'undefined') {
+            canvas.style.removeProperty( "width");
+            canvas.style.removeProperty("height");
+          }
+        } else {
+          if (canvas.width  != wNative) canvas.width  = wNative;
+          if (canvas.height != hNative) canvas.height = hNative;
+          if (typeof canvas.style != 'undefined') {
+            if (w != wNative || h != hNative) {
+              canvas.style.setProperty( "width", w + "px", "important");
+              canvas.style.setProperty("height", h + "px", "important");
+            } else {
+              canvas.style.removeProperty( "width");
+              canvas.style.removeProperty("height");
+            }
+          }
+        }
+      }};
+
+  function _sbrk(bytes) {
+      // Implement a Linux-like 'memory area' for our 'process'.
+      // Changes the size of the memory area by |bytes|; returns the
+      // address of the previous top ('break') of the memory area
+      // We control the "dynamic" memory - DYNAMIC_BASE to DYNAMICTOP
+      var self = _sbrk;
+      if (!self.called) {
+        DYNAMICTOP = alignMemoryPage(DYNAMICTOP); // make sure we start out aligned
+        self.called = true;
+        assert(Runtime.dynamicAlloc);
+        self.alloc = Runtime.dynamicAlloc;
+        Runtime.dynamicAlloc = function() { abort('cannot dynamically allocate, sbrk now has control') };
+      }
+      var ret = DYNAMICTOP;
+      if (bytes != 0) self.alloc(bytes);
+      return ret;  // Previous break location.
+    }
+
+  function _sysconf(name) {
+      // long sysconf(int name);
+      // http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html
+      switch(name) {
+        case 30: return PAGE_SIZE;
+        case 132:
+        case 133:
+        case 12:
+        case 137:
+        case 138:
+        case 15:
+        case 235:
+        case 16:
+        case 17:
+        case 18:
+        case 19:
+        case 20:
+        case 149:
+        case 13:
+        case 10:
+        case 236:
+        case 153:
+        case 9:
+        case 21:
+        case 22:
+        case 159:
+        case 154:
+        case 14:
+        case 77:
+        case 78:
+        case 139:
+        case 80:
+        case 81:
+        case 79:
+        case 82:
+        case 68:
+        case 67:
+        case 164:
+        case 11:
+        case 29:
+        case 47:
+        case 48:
+        case 95:
+        case 52:
+        case 51:
+        case 46:
+          return 200809;
+        case 27:
+        case 246:
+        case 127:
+        case 128:
+        case 23:
+        case 24:
+        case 160:
+        case 161:
+        case 181:
+        case 182:
+        case 242:
+        case 183:
+        case 184:
+        case 243:
+        case 244:
+        case 245:
+        case 165:
+        case 178:
+        case 179:
+        case 49:
+        case 50:
+        case 168:
+        case 169:
+        case 175:
+        case 170:
+        case 171:
+        case 172:
+        case 97:
+        case 76:
+        case 32:
+        case 173:
+        case 35:
+          return -1;
+        case 176:
+        case 177:
+        case 7:
+        case 155:
+        case 8:
+        case 157:
+        case 125:
+        case 126:
+        case 92:
+        case 93:
+        case 129:
+        case 130:
+        case 131:
+        case 94:
+        case 91:
+          return 1;
+        case 74:
+        case 60:
+        case 69:
+        case 70:
+        case 4:
+          return 1024;
+        case 31:
+        case 42:
+        case 72:
+          return 32;
+        case 87:
+        case 26:
+        case 33:
+          return 2147483647;
+        case 34:
+        case 1:
+          return 47839;
+        case 38:
+        case 36:
+          return 99;
+        case 43:
+        case 37:
+          return 2048;
+        case 0: return 2097152;
+        case 3: return 65536;
+        case 28: return 32768;
+        case 44: return 32767;
+        case 75: return 16384;
+        case 39: return 1000;
+        case 89: return 700;
+        case 71: return 256;
+        case 40: return 255;
+        case 2: return 100;
+        case 180: return 64;
+        case 25: return 20;
+        case 5: return 16;
+        case 6: return 6;
+        case 73: return 4;
+        case 84: return 1;
+      }
+      ___setErrNo(ERRNO_CODES.EINVAL);
+      return -1;
+    }
+
+  function _emscripten_run_script(ptr) {
+      eval(Pointer_stringify(ptr));
+    }
+
+
+  function _malloc(bytes) {
+      /* Over-allocate to make sure it is byte-aligned by 8.
+       * This will leak memory, but this is only the dummy
+       * implementation (replaced by dlmalloc normally) so
+       * not an issue.
+       */
+      var ptr = Runtime.dynamicAlloc(bytes + 8);
+      return (ptr+8) & 0xFFFFFFF8;
+    }
+  Module["_malloc"] = _malloc;function ___cxa_allocate_exception(size) {
+      var ptr = _malloc(size + ___cxa_exception_header_size);
+      return ptr + ___cxa_exception_header_size;
+    }
+
+  function _emscripten_cancel_main_loop() {
+      Browser.mainLoop.scheduler = null;
+      Browser.mainLoop.shouldPause = true;
+    }
+
+  var __ZTISt9exception=allocate([allocate([1,0,0,0,0,0,0], "i8", ALLOC_STATIC)+8, 0], "i32", ALLOC_STATIC);
+FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice;
+___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0;
+__ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor();
+if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); }
+__ATINIT__.push({ func: function() { SOCKFS.root = FS.mount(SOCKFS, {}, null); } });
+_fputc.ret = allocate([0], "i8", ALLOC_STATIC);
+Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };
+  Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
+  Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
+  Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
+  Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
+  Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }
+STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);
+
+staticSealed = true; // seal the static portion of memory
+
+STACK_MAX = STACK_BASE + 5242880;
+
+DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);
+
+assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");
+
+
+var Math_min = Math.min;
+function invoke_iiii(index,a1,a2,a3) {
+  try {
+    return Module["dynCall_iiii"](index,a1,a2,a3);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_viiiii(index,a1,a2,a3,a4,a5) {
+  try {
+    Module["dynCall_viiiii"](index,a1,a2,a3,a4,a5);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_vi(index,a1) {
+  try {
+    Module["dynCall_vi"](index,a1);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_vii(index,a1,a2) {
+  try {
+    Module["dynCall_vii"](index,a1,a2);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_ii(index,a1) {
+  try {
+    return Module["dynCall_ii"](index,a1);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_viii(index,a1,a2,a3) {
+  try {
+    Module["dynCall_viii"](index,a1,a2,a3);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_v(index) {
+  try {
+    Module["dynCall_v"](index);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_viid(index,a1,a2,a3) {
+  try {
+    Module["dynCall_viid"](index,a1,a2,a3);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_viiiiii(index,a1,a2,a3,a4,a5,a6) {
+  try {
+    Module["dynCall_viiiiii"](index,a1,a2,a3,a4,a5,a6);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_iii(index,a1,a2) {
+  try {
+    return Module["dynCall_iii"](index,a1,a2);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_iiiiii(index,a1,a2,a3,a4,a5) {
+  try {
+    return Module["dynCall_iiiiii"](index,a1,a2,a3,a4,a5);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_viiii(index,a1,a2,a3,a4) {
+  try {
+    Module["dynCall_viiii"](index,a1,a2,a3,a4);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function asmPrintInt(x, y) {
+  Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+function asmPrintFloat(x, y) {
+  Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+// EMSCRIPTEN_START_ASM
+var asm = (function(global, env, buffer) {
+  'use asm';
+  var HEAP8 = new global.Int8Array(buffer);
+  var HEAP16 = new global.Int16Array(buffer);
+  var HEAP32 = new global.Int32Array(buffer);
+  var HEAPU8 = new global.Uint8Array(buffer);
+  var HEAPU16 = new global.Uint16Array(buffer);
+  var HEAPU32 = new global.Uint32Array(buffer);
+  var HEAPF32 = new global.Float32Array(buffer);
+  var HEAPF64 = new global.Float64Array(buffer);
+
+  var STACKTOP=env.STACKTOP|0;
+  var STACK_MAX=env.STACK_MAX|0;
+  var tempDoublePtr=env.tempDoublePtr|0;
+  var ABORT=env.ABORT|0;
+  var __ZTISt9exception=env.__ZTISt9exception|0;
+
+  var __THREW__ = 0;
+  var threwValue = 0;
+  var setjmpId = 0;
+  var undef = 0;
+  var nan = +env.NaN, inf = +env.Infinity;
+  var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
+
+  var tempRet0 = 0;
+  var tempRet1 = 0;
+  var tempRet2 = 0;
+  var tempRet3 = 0;
+  var tempRet4 = 0;
+  var tempRet5 = 0;
+  var tempRet6 = 0;
+  var tempRet7 = 0;
+  var tempRet8 = 0;
+  var tempRet9 = 0;
+  var Math_floor=global.Math.floor;
+  var Math_abs=global.Math.abs;
+  var Math_sqrt=global.Math.sqrt;
+  var Math_pow=global.Math.pow;
+  var Math_cos=global.Math.cos;
+  var Math_sin=global.Math.sin;
+  var Math_tan=global.Math.tan;
+  var Math_acos=global.Math.acos;
+  var Math_asin=global.Math.asin;
+  var Math_atan=global.Math.atan;
+  var Math_atan2=global.Math.atan2;
+  var Math_exp=global.Math.exp;
+  var Math_log=global.Math.log;
+  var Math_ceil=global.Math.ceil;
+  var Math_imul=global.Math.imul;
+  var abort=env.abort;
+  var assert=env.assert;
+  var asmPrintInt=env.asmPrintInt;
+  var asmPrintFloat=env.asmPrintFloat;
+  var Math_min=env.min;
+  var invoke_iiii=env.invoke_iiii;
+  var invoke_viiiii=env.invoke_viiiii;
+  var invoke_vi=env.invoke_vi;
+  var invoke_vii=env.invoke_vii;
+  var invoke_ii=env.invoke_ii;
+  var invoke_viii=env.invoke_viii;
+  var invoke_v=env.invoke_v;
+  var invoke_viid=env.invoke_viid;
+  var invoke_viiiiii=env.invoke_viiiiii;
+  var invoke_iii=env.invoke_iii;
+  var invoke_iiiiii=env.invoke_iiiiii;
+  var invoke_viiii=env.invoke_viiii;
+  var ___cxa_throw=env.___cxa_throw;
+  var _emscripten_run_script=env._emscripten_run_script;
+  var _cosf=env._cosf;
+  var _send=env._send;
+  var __ZSt9terminatev=env.__ZSt9terminatev;
+  var __reallyNegative=env.__reallyNegative;
+  var ___cxa_is_number_type=env.___cxa_is_number_type;
+  var ___assert_fail=env.___assert_fail;
+  var ___cxa_allocate_exception=env.___cxa_allocate_exception;
+  var ___cxa_find_matching_catch=env.___cxa_find_matching_catch;
+  var _fflush=env._fflush;
+  var _pwrite=env._pwrite;
+  var ___setErrNo=env.___setErrNo;
+  var _sbrk=env._sbrk;
+  var ___cxa_begin_catch=env.___cxa_begin_catch;
+  var _sinf=env._sinf;
+  var _fileno=env._fileno;
+  var ___resumeException=env.___resumeException;
+  var __ZSt18uncaught_exceptionv=env.__ZSt18uncaught_exceptionv;
+  var _sysconf=env._sysconf;
+  var _clock=env._clock;
+  var _emscripten_memcpy_big=env._emscripten_memcpy_big;
+  var _puts=env._puts;
+  var _mkport=env._mkport;
+  var _floorf=env._floorf;
+  var _sqrtf=env._sqrtf;
+  var _write=env._write;
+  var _emscripten_set_main_loop=env._emscripten_set_main_loop;
+  var ___errno_location=env.___errno_location;
+  var __ZNSt9exceptionD2Ev=env.__ZNSt9exceptionD2Ev;
+  var _printf=env._printf;
+  var ___cxa_does_inherit=env.___cxa_does_inherit;
+  var __exit=env.__exit;
+  var _fputc=env._fputc;
+  var _abort=env._abort;
+  var _fwrite=env._fwrite;
+  var _time=env._time;
+  var _fprintf=env._fprintf;
+  var _emscripten_cancel_main_loop=env._emscripten_cancel_main_loop;
+  var __formatString=env.__formatString;
+  var _fputs=env._fputs;
+  var _exit=env._exit;
+  var ___cxa_pure_virtual=env.___cxa_pure_virtual;
+  var tempFloat = 0.0;
+
+// EMSCRIPTEN_START_FUNCS
+function _malloc(i12) {
+ i12 = i12 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0;
+ i1 = STACKTOP;
+ do {
+  if (i12 >>> 0 < 245) {
+   if (i12 >>> 0 < 11) {
+    i12 = 16;
+   } else {
+    i12 = i12 + 11 & -8;
+   }
+   i20 = i12 >>> 3;
+   i18 = HEAP32[1790] | 0;
+   i21 = i18 >>> i20;
+   if ((i21 & 3 | 0) != 0) {
+    i6 = (i21 & 1 ^ 1) + i20 | 0;
+    i5 = i6 << 1;
+    i3 = 7200 + (i5 << 2) | 0;
+    i5 = 7200 + (i5 + 2 << 2) | 0;
+    i7 = HEAP32[i5 >> 2] | 0;
+    i2 = i7 + 8 | 0;
+    i4 = HEAP32[i2 >> 2] | 0;
+    do {
+     if ((i3 | 0) != (i4 | 0)) {
+      if (i4 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i8 = i4 + 12 | 0;
+      if ((HEAP32[i8 >> 2] | 0) == (i7 | 0)) {
+       HEAP32[i8 >> 2] = i3;
+       HEAP32[i5 >> 2] = i4;
+       break;
+      } else {
+       _abort();
+      }
+     } else {
+      HEAP32[1790] = i18 & ~(1 << i6);
+     }
+    } while (0);
+    i32 = i6 << 3;
+    HEAP32[i7 + 4 >> 2] = i32 | 3;
+    i32 = i7 + (i32 | 4) | 0;
+    HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+    i32 = i2;
+    STACKTOP = i1;
+    return i32 | 0;
+   }
+   if (i12 >>> 0 > (HEAP32[7168 >> 2] | 0) >>> 0) {
+    if ((i21 | 0) != 0) {
+     i7 = 2 << i20;
+     i7 = i21 << i20 & (i7 | 0 - i7);
+     i7 = (i7 & 0 - i7) + -1 | 0;
+     i2 = i7 >>> 12 & 16;
+     i7 = i7 >>> i2;
+     i6 = i7 >>> 5 & 8;
+     i7 = i7 >>> i6;
+     i5 = i7 >>> 2 & 4;
+     i7 = i7 >>> i5;
+     i4 = i7 >>> 1 & 2;
+     i7 = i7 >>> i4;
+     i3 = i7 >>> 1 & 1;
+     i3 = (i6 | i2 | i5 | i4 | i3) + (i7 >>> i3) | 0;
+     i7 = i3 << 1;
+     i4 = 7200 + (i7 << 2) | 0;
+     i7 = 7200 + (i7 + 2 << 2) | 0;
+     i5 = HEAP32[i7 >> 2] | 0;
+     i2 = i5 + 8 | 0;
+     i6 = HEAP32[i2 >> 2] | 0;
+     do {
+      if ((i4 | 0) != (i6 | 0)) {
+       if (i6 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+        _abort();
+       }
+       i8 = i6 + 12 | 0;
+       if ((HEAP32[i8 >> 2] | 0) == (i5 | 0)) {
+        HEAP32[i8 >> 2] = i4;
+        HEAP32[i7 >> 2] = i6;
+        break;
+       } else {
+        _abort();
+       }
+      } else {
+       HEAP32[1790] = i18 & ~(1 << i3);
+      }
+     } while (0);
+     i6 = i3 << 3;
+     i4 = i6 - i12 | 0;
+     HEAP32[i5 + 4 >> 2] = i12 | 3;
+     i3 = i5 + i12 | 0;
+     HEAP32[i5 + (i12 | 4) >> 2] = i4 | 1;
+     HEAP32[i5 + i6 >> 2] = i4;
+     i6 = HEAP32[7168 >> 2] | 0;
+     if ((i6 | 0) != 0) {
+      i5 = HEAP32[7180 >> 2] | 0;
+      i8 = i6 >>> 3;
+      i9 = i8 << 1;
+      i6 = 7200 + (i9 << 2) | 0;
+      i7 = HEAP32[1790] | 0;
+      i8 = 1 << i8;
+      if ((i7 & i8 | 0) != 0) {
+       i7 = 7200 + (i9 + 2 << 2) | 0;
+       i8 = HEAP32[i7 >> 2] | 0;
+       if (i8 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        i28 = i7;
+        i27 = i8;
+       }
+      } else {
+       HEAP32[1790] = i7 | i8;
+       i28 = 7200 + (i9 + 2 << 2) | 0;
+       i27 = i6;
+      }
+      HEAP32[i28 >> 2] = i5;
+      HEAP32[i27 + 12 >> 2] = i5;
+      HEAP32[i5 + 8 >> 2] = i27;
+      HEAP32[i5 + 12 >> 2] = i6;
+     }
+     HEAP32[7168 >> 2] = i4;
+     HEAP32[7180 >> 2] = i3;
+     i32 = i2;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+    i18 = HEAP32[7164 >> 2] | 0;
+    if ((i18 | 0) != 0) {
+     i2 = (i18 & 0 - i18) + -1 | 0;
+     i31 = i2 >>> 12 & 16;
+     i2 = i2 >>> i31;
+     i30 = i2 >>> 5 & 8;
+     i2 = i2 >>> i30;
+     i32 = i2 >>> 2 & 4;
+     i2 = i2 >>> i32;
+     i6 = i2 >>> 1 & 2;
+     i2 = i2 >>> i6;
+     i3 = i2 >>> 1 & 1;
+     i3 = HEAP32[7464 + ((i30 | i31 | i32 | i6 | i3) + (i2 >>> i3) << 2) >> 2] | 0;
+     i2 = (HEAP32[i3 + 4 >> 2] & -8) - i12 | 0;
+     i6 = i3;
+     while (1) {
+      i5 = HEAP32[i6 + 16 >> 2] | 0;
+      if ((i5 | 0) == 0) {
+       i5 = HEAP32[i6 + 20 >> 2] | 0;
+       if ((i5 | 0) == 0) {
+        break;
+       }
+      }
+      i6 = (HEAP32[i5 + 4 >> 2] & -8) - i12 | 0;
+      i4 = i6 >>> 0 < i2 >>> 0;
+      i2 = i4 ? i6 : i2;
+      i6 = i5;
+      i3 = i4 ? i5 : i3;
+     }
+     i6 = HEAP32[7176 >> 2] | 0;
+     if (i3 >>> 0 < i6 >>> 0) {
+      _abort();
+     }
+     i4 = i3 + i12 | 0;
+     if (!(i3 >>> 0 < i4 >>> 0)) {
+      _abort();
+     }
+     i5 = HEAP32[i3 + 24 >> 2] | 0;
+     i7 = HEAP32[i3 + 12 >> 2] | 0;
+     do {
+      if ((i7 | 0) == (i3 | 0)) {
+       i8 = i3 + 20 | 0;
+       i7 = HEAP32[i8 >> 2] | 0;
+       if ((i7 | 0) == 0) {
+        i8 = i3 + 16 | 0;
+        i7 = HEAP32[i8 >> 2] | 0;
+        if ((i7 | 0) == 0) {
+         i26 = 0;
+         break;
+        }
+       }
+       while (1) {
+        i10 = i7 + 20 | 0;
+        i9 = HEAP32[i10 >> 2] | 0;
+        if ((i9 | 0) != 0) {
+         i7 = i9;
+         i8 = i10;
+         continue;
+        }
+        i10 = i7 + 16 | 0;
+        i9 = HEAP32[i10 >> 2] | 0;
+        if ((i9 | 0) == 0) {
+         break;
+        } else {
+         i7 = i9;
+         i8 = i10;
+        }
+       }
+       if (i8 >>> 0 < i6 >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i8 >> 2] = 0;
+        i26 = i7;
+        break;
+       }
+      } else {
+       i8 = HEAP32[i3 + 8 >> 2] | 0;
+       if (i8 >>> 0 < i6 >>> 0) {
+        _abort();
+       }
+       i6 = i8 + 12 | 0;
+       if ((HEAP32[i6 >> 2] | 0) != (i3 | 0)) {
+        _abort();
+       }
+       i9 = i7 + 8 | 0;
+       if ((HEAP32[i9 >> 2] | 0) == (i3 | 0)) {
+        HEAP32[i6 >> 2] = i7;
+        HEAP32[i9 >> 2] = i8;
+        i26 = i7;
+        break;
+       } else {
+        _abort();
+       }
+      }
+     } while (0);
+     do {
+      if ((i5 | 0) != 0) {
+       i7 = HEAP32[i3 + 28 >> 2] | 0;
+       i6 = 7464 + (i7 << 2) | 0;
+       if ((i3 | 0) == (HEAP32[i6 >> 2] | 0)) {
+        HEAP32[i6 >> 2] = i26;
+        if ((i26 | 0) == 0) {
+         HEAP32[7164 >> 2] = HEAP32[7164 >> 2] & ~(1 << i7);
+         break;
+        }
+       } else {
+        if (i5 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+         _abort();
+        }
+        i6 = i5 + 16 | 0;
+        if ((HEAP32[i6 >> 2] | 0) == (i3 | 0)) {
+         HEAP32[i6 >> 2] = i26;
+        } else {
+         HEAP32[i5 + 20 >> 2] = i26;
+        }
+        if ((i26 | 0) == 0) {
+         break;
+        }
+       }
+       if (i26 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+        _abort();
+       }
+       HEAP32[i26 + 24 >> 2] = i5;
+       i5 = HEAP32[i3 + 16 >> 2] | 0;
+       do {
+        if ((i5 | 0) != 0) {
+         if (i5 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i26 + 16 >> 2] = i5;
+          HEAP32[i5 + 24 >> 2] = i26;
+          break;
+         }
+        }
+       } while (0);
+       i5 = HEAP32[i3 + 20 >> 2] | 0;
+       if ((i5 | 0) != 0) {
+        if (i5 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i26 + 20 >> 2] = i5;
+         HEAP32[i5 + 24 >> 2] = i26;
+         break;
+        }
+       }
+      }
+     } while (0);
+     if (i2 >>> 0 < 16) {
+      i32 = i2 + i12 | 0;
+      HEAP32[i3 + 4 >> 2] = i32 | 3;
+      i32 = i3 + (i32 + 4) | 0;
+      HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+     } else {
+      HEAP32[i3 + 4 >> 2] = i12 | 3;
+      HEAP32[i3 + (i12 | 4) >> 2] = i2 | 1;
+      HEAP32[i3 + (i2 + i12) >> 2] = i2;
+      i6 = HEAP32[7168 >> 2] | 0;
+      if ((i6 | 0) != 0) {
+       i5 = HEAP32[7180 >> 2] | 0;
+       i8 = i6 >>> 3;
+       i9 = i8 << 1;
+       i6 = 7200 + (i9 << 2) | 0;
+       i7 = HEAP32[1790] | 0;
+       i8 = 1 << i8;
+       if ((i7 & i8 | 0) != 0) {
+        i7 = 7200 + (i9 + 2 << 2) | 0;
+        i8 = HEAP32[i7 >> 2] | 0;
+        if (i8 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+         _abort();
+        } else {
+         i25 = i7;
+         i24 = i8;
+        }
+       } else {
+        HEAP32[1790] = i7 | i8;
+        i25 = 7200 + (i9 + 2 << 2) | 0;
+        i24 = i6;
+       }
+       HEAP32[i25 >> 2] = i5;
+       HEAP32[i24 + 12 >> 2] = i5;
+       HEAP32[i5 + 8 >> 2] = i24;
+       HEAP32[i5 + 12 >> 2] = i6;
+      }
+      HEAP32[7168 >> 2] = i2;
+      HEAP32[7180 >> 2] = i4;
+     }
+     i32 = i3 + 8 | 0;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+   }
+  } else {
+   if (!(i12 >>> 0 > 4294967231)) {
+    i24 = i12 + 11 | 0;
+    i12 = i24 & -8;
+    i26 = HEAP32[7164 >> 2] | 0;
+    if ((i26 | 0) != 0) {
+     i25 = 0 - i12 | 0;
+     i24 = i24 >>> 8;
+     if ((i24 | 0) != 0) {
+      if (i12 >>> 0 > 16777215) {
+       i27 = 31;
+      } else {
+       i31 = (i24 + 1048320 | 0) >>> 16 & 8;
+       i32 = i24 << i31;
+       i30 = (i32 + 520192 | 0) >>> 16 & 4;
+       i32 = i32 << i30;
+       i27 = (i32 + 245760 | 0) >>> 16 & 2;
+       i27 = 14 - (i30 | i31 | i27) + (i32 << i27 >>> 15) | 0;
+       i27 = i12 >>> (i27 + 7 | 0) & 1 | i27 << 1;
+      }
+     } else {
+      i27 = 0;
+     }
+     i30 = HEAP32[7464 + (i27 << 2) >> 2] | 0;
+     L126 : do {
+      if ((i30 | 0) == 0) {
+       i29 = 0;
+       i24 = 0;
+      } else {
+       if ((i27 | 0) == 31) {
+        i24 = 0;
+       } else {
+        i24 = 25 - (i27 >>> 1) | 0;
+       }
+       i29 = 0;
+       i28 = i12 << i24;
+       i24 = 0;
+       while (1) {
+        i32 = HEAP32[i30 + 4 >> 2] & -8;
+        i31 = i32 - i12 | 0;
+        if (i31 >>> 0 < i25 >>> 0) {
+         if ((i32 | 0) == (i12 | 0)) {
+          i25 = i31;
+          i29 = i30;
+          i24 = i30;
+          break L126;
+         } else {
+          i25 = i31;
+          i24 = i30;
+         }
+        }
+        i31 = HEAP32[i30 + 20 >> 2] | 0;
+        i30 = HEAP32[i30 + (i28 >>> 31 << 2) + 16 >> 2] | 0;
+        i29 = (i31 | 0) == 0 | (i31 | 0) == (i30 | 0) ? i29 : i31;
+        if ((i30 | 0) == 0) {
+         break;
+        } else {
+         i28 = i28 << 1;
+        }
+       }
+      }
+     } while (0);
+     if ((i29 | 0) == 0 & (i24 | 0) == 0) {
+      i32 = 2 << i27;
+      i26 = i26 & (i32 | 0 - i32);
+      if ((i26 | 0) == 0) {
+       break;
+      }
+      i32 = (i26 & 0 - i26) + -1 | 0;
+      i28 = i32 >>> 12 & 16;
+      i32 = i32 >>> i28;
+      i27 = i32 >>> 5 & 8;
+      i32 = i32 >>> i27;
+      i30 = i32 >>> 2 & 4;
+      i32 = i32 >>> i30;
+      i31 = i32 >>> 1 & 2;
+      i32 = i32 >>> i31;
+      i29 = i32 >>> 1 & 1;
+      i29 = HEAP32[7464 + ((i27 | i28 | i30 | i31 | i29) + (i32 >>> i29) << 2) >> 2] | 0;
+     }
+     if ((i29 | 0) != 0) {
+      while (1) {
+       i27 = (HEAP32[i29 + 4 >> 2] & -8) - i12 | 0;
+       i26 = i27 >>> 0 < i25 >>> 0;
+       i25 = i26 ? i27 : i25;
+       i24 = i26 ? i29 : i24;
+       i26 = HEAP32[i29 + 16 >> 2] | 0;
+       if ((i26 | 0) != 0) {
+        i29 = i26;
+        continue;
+       }
+       i29 = HEAP32[i29 + 20 >> 2] | 0;
+       if ((i29 | 0) == 0) {
+        break;
+       }
+      }
+     }
+     if ((i24 | 0) != 0 ? i25 >>> 0 < ((HEAP32[7168 >> 2] | 0) - i12 | 0) >>> 0 : 0) {
+      i4 = HEAP32[7176 >> 2] | 0;
+      if (i24 >>> 0 < i4 >>> 0) {
+       _abort();
+      }
+      i2 = i24 + i12 | 0;
+      if (!(i24 >>> 0 < i2 >>> 0)) {
+       _abort();
+      }
+      i3 = HEAP32[i24 + 24 >> 2] | 0;
+      i6 = HEAP32[i24 + 12 >> 2] | 0;
+      do {
+       if ((i6 | 0) == (i24 | 0)) {
+        i6 = i24 + 20 | 0;
+        i5 = HEAP32[i6 >> 2] | 0;
+        if ((i5 | 0) == 0) {
+         i6 = i24 + 16 | 0;
+         i5 = HEAP32[i6 >> 2] | 0;
+         if ((i5 | 0) == 0) {
+          i22 = 0;
+          break;
+         }
+        }
+        while (1) {
+         i8 = i5 + 20 | 0;
+         i7 = HEAP32[i8 >> 2] | 0;
+         if ((i7 | 0) != 0) {
+          i5 = i7;
+          i6 = i8;
+          continue;
+         }
+         i7 = i5 + 16 | 0;
+         i8 = HEAP32[i7 >> 2] | 0;
+         if ((i8 | 0) == 0) {
+          break;
+         } else {
+          i5 = i8;
+          i6 = i7;
+         }
+        }
+        if (i6 >>> 0 < i4 >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i6 >> 2] = 0;
+         i22 = i5;
+         break;
+        }
+       } else {
+        i5 = HEAP32[i24 + 8 >> 2] | 0;
+        if (i5 >>> 0 < i4 >>> 0) {
+         _abort();
+        }
+        i7 = i5 + 12 | 0;
+        if ((HEAP32[i7 >> 2] | 0) != (i24 | 0)) {
+         _abort();
+        }
+        i4 = i6 + 8 | 0;
+        if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
+         HEAP32[i7 >> 2] = i6;
+         HEAP32[i4 >> 2] = i5;
+         i22 = i6;
+         break;
+        } else {
+         _abort();
+        }
+       }
+      } while (0);
+      do {
+       if ((i3 | 0) != 0) {
+        i4 = HEAP32[i24 + 28 >> 2] | 0;
+        i5 = 7464 + (i4 << 2) | 0;
+        if ((i24 | 0) == (HEAP32[i5 >> 2] | 0)) {
+         HEAP32[i5 >> 2] = i22;
+         if ((i22 | 0) == 0) {
+          HEAP32[7164 >> 2] = HEAP32[7164 >> 2] & ~(1 << i4);
+          break;
+         }
+        } else {
+         if (i3 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+          _abort();
+         }
+         i4 = i3 + 16 | 0;
+         if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
+          HEAP32[i4 >> 2] = i22;
+         } else {
+          HEAP32[i3 + 20 >> 2] = i22;
+         }
+         if ((i22 | 0) == 0) {
+          break;
+         }
+        }
+        if (i22 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+         _abort();
+        }
+        HEAP32[i22 + 24 >> 2] = i3;
+        i3 = HEAP32[i24 + 16 >> 2] | 0;
+        do {
+         if ((i3 | 0) != 0) {
+          if (i3 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           HEAP32[i22 + 16 >> 2] = i3;
+           HEAP32[i3 + 24 >> 2] = i22;
+           break;
+          }
+         }
+        } while (0);
+        i3 = HEAP32[i24 + 20 >> 2] | 0;
+        if ((i3 | 0) != 0) {
+         if (i3 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i22 + 20 >> 2] = i3;
+          HEAP32[i3 + 24 >> 2] = i22;
+          break;
+         }
+        }
+       }
+      } while (0);
+      L204 : do {
+       if (!(i25 >>> 0 < 16)) {
+        HEAP32[i24 + 4 >> 2] = i12 | 3;
+        HEAP32[i24 + (i12 | 4) >> 2] = i25 | 1;
+        HEAP32[i24 + (i25 + i12) >> 2] = i25;
+        i4 = i25 >>> 3;
+        if (i25 >>> 0 < 256) {
+         i6 = i4 << 1;
+         i3 = 7200 + (i6 << 2) | 0;
+         i5 = HEAP32[1790] | 0;
+         i4 = 1 << i4;
+         if ((i5 & i4 | 0) != 0) {
+          i5 = 7200 + (i6 + 2 << 2) | 0;
+          i4 = HEAP32[i5 >> 2] | 0;
+          if (i4 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           i21 = i5;
+           i20 = i4;
+          }
+         } else {
+          HEAP32[1790] = i5 | i4;
+          i21 = 7200 + (i6 + 2 << 2) | 0;
+          i20 = i3;
+         }
+         HEAP32[i21 >> 2] = i2;
+         HEAP32[i20 + 12 >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i20;
+         HEAP32[i24 + (i12 + 12) >> 2] = i3;
+         break;
+        }
+        i3 = i25 >>> 8;
+        if ((i3 | 0) != 0) {
+         if (i25 >>> 0 > 16777215) {
+          i3 = 31;
+         } else {
+          i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+          i32 = i3 << i31;
+          i30 = (i32 + 520192 | 0) >>> 16 & 4;
+          i32 = i32 << i30;
+          i3 = (i32 + 245760 | 0) >>> 16 & 2;
+          i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+          i3 = i25 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+         }
+        } else {
+         i3 = 0;
+        }
+        i6 = 7464 + (i3 << 2) | 0;
+        HEAP32[i24 + (i12 + 28) >> 2] = i3;
+        HEAP32[i24 + (i12 + 20) >> 2] = 0;
+        HEAP32[i24 + (i12 + 16) >> 2] = 0;
+        i4 = HEAP32[7164 >> 2] | 0;
+        i5 = 1 << i3;
+        if ((i4 & i5 | 0) == 0) {
+         HEAP32[7164 >> 2] = i4 | i5;
+         HEAP32[i6 >> 2] = i2;
+         HEAP32[i24 + (i12 + 24) >> 2] = i6;
+         HEAP32[i24 + (i12 + 12) >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i2;
+         break;
+        }
+        i4 = HEAP32[i6 >> 2] | 0;
+        if ((i3 | 0) == 31) {
+         i3 = 0;
+        } else {
+         i3 = 25 - (i3 >>> 1) | 0;
+        }
+        L225 : do {
+         if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i25 | 0)) {
+          i3 = i25 << i3;
+          while (1) {
+           i6 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+           i5 = HEAP32[i6 >> 2] | 0;
+           if ((i5 | 0) == 0) {
+            break;
+           }
+           if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i25 | 0)) {
+            i18 = i5;
+            break L225;
+           } else {
+            i3 = i3 << 1;
+            i4 = i5;
+           }
+          }
+          if (i6 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           HEAP32[i6 >> 2] = i2;
+           HEAP32[i24 + (i12 + 24) >> 2] = i4;
+           HEAP32[i24 + (i12 + 12) >> 2] = i2;
+           HEAP32[i24 + (i12 + 8) >> 2] = i2;
+           break L204;
+          }
+         } else {
+          i18 = i4;
+         }
+        } while (0);
+        i4 = i18 + 8 | 0;
+        i3 = HEAP32[i4 >> 2] | 0;
+        i5 = HEAP32[7176 >> 2] | 0;
+        if (i18 >>> 0 < i5 >>> 0) {
+         _abort();
+        }
+        if (i3 >>> 0 < i5 >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i3 + 12 >> 2] = i2;
+         HEAP32[i4 >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i3;
+         HEAP32[i24 + (i12 + 12) >> 2] = i18;
+         HEAP32[i24 + (i12 + 24) >> 2] = 0;
+         break;
+        }
+       } else {
+        i32 = i25 + i12 | 0;
+        HEAP32[i24 + 4 >> 2] = i32 | 3;
+        i32 = i24 + (i32 + 4) | 0;
+        HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+       }
+      } while (0);
+      i32 = i24 + 8 | 0;
+      STACKTOP = i1;
+      return i32 | 0;
+     }
+    }
+   } else {
+    i12 = -1;
+   }
+  }
+ } while (0);
+ i18 = HEAP32[7168 >> 2] | 0;
+ if (!(i12 >>> 0 > i18 >>> 0)) {
+  i3 = i18 - i12 | 0;
+  i2 = HEAP32[7180 >> 2] | 0;
+  if (i3 >>> 0 > 15) {
+   HEAP32[7180 >> 2] = i2 + i12;
+   HEAP32[7168 >> 2] = i3;
+   HEAP32[i2 + (i12 + 4) >> 2] = i3 | 1;
+   HEAP32[i2 + i18 >> 2] = i3;
+   HEAP32[i2 + 4 >> 2] = i12 | 3;
+  } else {
+   HEAP32[7168 >> 2] = 0;
+   HEAP32[7180 >> 2] = 0;
+   HEAP32[i2 + 4 >> 2] = i18 | 3;
+   i32 = i2 + (i18 + 4) | 0;
+   HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+  }
+  i32 = i2 + 8 | 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ i18 = HEAP32[7172 >> 2] | 0;
+ if (i12 >>> 0 < i18 >>> 0) {
+  i31 = i18 - i12 | 0;
+  HEAP32[7172 >> 2] = i31;
+  i32 = HEAP32[7184 >> 2] | 0;
+  HEAP32[7184 >> 2] = i32 + i12;
+  HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
+  HEAP32[i32 + 4 >> 2] = i12 | 3;
+  i32 = i32 + 8 | 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ do {
+  if ((HEAP32[1908] | 0) == 0) {
+   i18 = _sysconf(30) | 0;
+   if ((i18 + -1 & i18 | 0) == 0) {
+    HEAP32[7640 >> 2] = i18;
+    HEAP32[7636 >> 2] = i18;
+    HEAP32[7644 >> 2] = -1;
+    HEAP32[7648 >> 2] = -1;
+    HEAP32[7652 >> 2] = 0;
+    HEAP32[7604 >> 2] = 0;
+    HEAP32[1908] = (_time(0) | 0) & -16 ^ 1431655768;
+    break;
+   } else {
+    _abort();
+   }
+  }
+ } while (0);
+ i20 = i12 + 48 | 0;
+ i25 = HEAP32[7640 >> 2] | 0;
+ i21 = i12 + 47 | 0;
+ i22 = i25 + i21 | 0;
+ i25 = 0 - i25 | 0;
+ i18 = i22 & i25;
+ if (!(i18 >>> 0 > i12 >>> 0)) {
+  i32 = 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ i24 = HEAP32[7600 >> 2] | 0;
+ if ((i24 | 0) != 0 ? (i31 = HEAP32[7592 >> 2] | 0, i32 = i31 + i18 | 0, i32 >>> 0 <= i31 >>> 0 | i32 >>> 0 > i24 >>> 0) : 0) {
+  i32 = 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ L269 : do {
+  if ((HEAP32[7604 >> 2] & 4 | 0) == 0) {
+   i26 = HEAP32[7184 >> 2] | 0;
+   L271 : do {
+    if ((i26 | 0) != 0) {
+     i24 = 7608 | 0;
+     while (1) {
+      i27 = HEAP32[i24 >> 2] | 0;
+      if (!(i27 >>> 0 > i26 >>> 0) ? (i23 = i24 + 4 | 0, (i27 + (HEAP32[i23 >> 2] | 0) | 0) >>> 0 > i26 >>> 0) : 0) {
+       break;
+      }
+      i24 = HEAP32[i24 + 8 >> 2] | 0;
+      if ((i24 | 0) == 0) {
+       i13 = 182;
+       break L271;
+      }
+     }
+     if ((i24 | 0) != 0) {
+      i25 = i22 - (HEAP32[7172 >> 2] | 0) & i25;
+      if (i25 >>> 0 < 2147483647) {
+       i13 = _sbrk(i25 | 0) | 0;
+       i26 = (i13 | 0) == ((HEAP32[i24 >> 2] | 0) + (HEAP32[i23 >> 2] | 0) | 0);
+       i22 = i13;
+       i24 = i25;
+       i23 = i26 ? i13 : -1;
+       i25 = i26 ? i25 : 0;
+       i13 = 191;
+      } else {
+       i25 = 0;
+      }
+     } else {
+      i13 = 182;
+     }
+    } else {
+     i13 = 182;
+    }
+   } while (0);
+   do {
+    if ((i13 | 0) == 182) {
+     i23 = _sbrk(0) | 0;
+     if ((i23 | 0) != (-1 | 0)) {
+      i24 = i23;
+      i22 = HEAP32[7636 >> 2] | 0;
+      i25 = i22 + -1 | 0;
+      if ((i25 & i24 | 0) == 0) {
+       i25 = i18;
+      } else {
+       i25 = i18 - i24 + (i25 + i24 & 0 - i22) | 0;
+      }
+      i24 = HEAP32[7592 >> 2] | 0;
+      i26 = i24 + i25 | 0;
+      if (i25 >>> 0 > i12 >>> 0 & i25 >>> 0 < 2147483647) {
+       i22 = HEAP32[7600 >> 2] | 0;
+       if ((i22 | 0) != 0 ? i26 >>> 0 <= i24 >>> 0 | i26 >>> 0 > i22 >>> 0 : 0) {
+        i25 = 0;
+        break;
+       }
+       i22 = _sbrk(i25 | 0) | 0;
+       i13 = (i22 | 0) == (i23 | 0);
+       i24 = i25;
+       i23 = i13 ? i23 : -1;
+       i25 = i13 ? i25 : 0;
+       i13 = 191;
+      } else {
+       i25 = 0;
+      }
+     } else {
+      i25 = 0;
+     }
+    }
+   } while (0);
+   L291 : do {
+    if ((i13 | 0) == 191) {
+     i13 = 0 - i24 | 0;
+     if ((i23 | 0) != (-1 | 0)) {
+      i17 = i23;
+      i14 = i25;
+      i13 = 202;
+      break L269;
+     }
+     do {
+      if ((i22 | 0) != (-1 | 0) & i24 >>> 0 < 2147483647 & i24 >>> 0 < i20 >>> 0 ? (i19 = HEAP32[7640 >> 2] | 0, i19 = i21 - i24 + i19 & 0 - i19, i19 >>> 0 < 2147483647) : 0) {
+       if ((_sbrk(i19 | 0) | 0) == (-1 | 0)) {
+        _sbrk(i13 | 0) | 0;
+        break L291;
+       } else {
+        i24 = i19 + i24 | 0;
+        break;
+       }
+      }
+     } while (0);
+     if ((i22 | 0) != (-1 | 0)) {
+      i17 = i22;
+      i14 = i24;
+      i13 = 202;
+      break L269;
+     }
+    }
+   } while (0);
+   HEAP32[7604 >> 2] = HEAP32[7604 >> 2] | 4;
+   i13 = 199;
+  } else {
+   i25 = 0;
+   i13 = 199;
+  }
+ } while (0);
+ if ((((i13 | 0) == 199 ? i18 >>> 0 < 2147483647 : 0) ? (i17 = _sbrk(i18 | 0) | 0, i16 = _sbrk(0) | 0, (i16 | 0) != (-1 | 0) & (i17 | 0) != (-1 | 0) & i17 >>> 0 < i16 >>> 0) : 0) ? (i15 = i16 - i17 | 0, i14 = i15 >>> 0 > (i12 + 40 | 0) >>> 0, i14) : 0) {
+  i14 = i14 ? i15 : i25;
+  i13 = 202;
+ }
+ if ((i13 | 0) == 202) {
+  i15 = (HEAP32[7592 >> 2] | 0) + i14 | 0;
+  HEAP32[7592 >> 2] = i15;
+  if (i15 >>> 0 > (HEAP32[7596 >> 2] | 0) >>> 0) {
+   HEAP32[7596 >> 2] = i15;
+  }
+  i15 = HEAP32[7184 >> 2] | 0;
+  L311 : do {
+   if ((i15 | 0) != 0) {
+    i21 = 7608 | 0;
+    while (1) {
+     i16 = HEAP32[i21 >> 2] | 0;
+     i19 = i21 + 4 | 0;
+     i20 = HEAP32[i19 >> 2] | 0;
+     if ((i17 | 0) == (i16 + i20 | 0)) {
+      i13 = 214;
+      break;
+     }
+     i18 = HEAP32[i21 + 8 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      break;
+     } else {
+      i21 = i18;
+     }
+    }
+    if (((i13 | 0) == 214 ? (HEAP32[i21 + 12 >> 2] & 8 | 0) == 0 : 0) ? i15 >>> 0 >= i16 >>> 0 & i15 >>> 0 < i17 >>> 0 : 0) {
+     HEAP32[i19 >> 2] = i20 + i14;
+     i2 = (HEAP32[7172 >> 2] | 0) + i14 | 0;
+     i3 = i15 + 8 | 0;
+     if ((i3 & 7 | 0) == 0) {
+      i3 = 0;
+     } else {
+      i3 = 0 - i3 & 7;
+     }
+     i32 = i2 - i3 | 0;
+     HEAP32[7184 >> 2] = i15 + i3;
+     HEAP32[7172 >> 2] = i32;
+     HEAP32[i15 + (i3 + 4) >> 2] = i32 | 1;
+     HEAP32[i15 + (i2 + 4) >> 2] = 40;
+     HEAP32[7188 >> 2] = HEAP32[7648 >> 2];
+     break;
+    }
+    if (i17 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+     HEAP32[7176 >> 2] = i17;
+    }
+    i19 = i17 + i14 | 0;
+    i16 = 7608 | 0;
+    while (1) {
+     if ((HEAP32[i16 >> 2] | 0) == (i19 | 0)) {
+      i13 = 224;
+      break;
+     }
+     i18 = HEAP32[i16 + 8 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      break;
+     } else {
+      i16 = i18;
+     }
+    }
+    if ((i13 | 0) == 224 ? (HEAP32[i16 + 12 >> 2] & 8 | 0) == 0 : 0) {
+     HEAP32[i16 >> 2] = i17;
+     i6 = i16 + 4 | 0;
+     HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i14;
+     i6 = i17 + 8 | 0;
+     if ((i6 & 7 | 0) == 0) {
+      i6 = 0;
+     } else {
+      i6 = 0 - i6 & 7;
+     }
+     i7 = i17 + (i14 + 8) | 0;
+     if ((i7 & 7 | 0) == 0) {
+      i13 = 0;
+     } else {
+      i13 = 0 - i7 & 7;
+     }
+     i15 = i17 + (i13 + i14) | 0;
+     i8 = i6 + i12 | 0;
+     i7 = i17 + i8 | 0;
+     i10 = i15 - (i17 + i6) - i12 | 0;
+     HEAP32[i17 + (i6 + 4) >> 2] = i12 | 3;
+     L348 : do {
+      if ((i15 | 0) != (HEAP32[7184 >> 2] | 0)) {
+       if ((i15 | 0) == (HEAP32[7180 >> 2] | 0)) {
+        i32 = (HEAP32[7168 >> 2] | 0) + i10 | 0;
+        HEAP32[7168 >> 2] = i32;
+        HEAP32[7180 >> 2] = i7;
+        HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
+        HEAP32[i17 + (i32 + i8) >> 2] = i32;
+        break;
+       }
+       i12 = i14 + 4 | 0;
+       i18 = HEAP32[i17 + (i12 + i13) >> 2] | 0;
+       if ((i18 & 3 | 0) == 1) {
+        i11 = i18 & -8;
+        i16 = i18 >>> 3;
+        do {
+         if (!(i18 >>> 0 < 256)) {
+          i9 = HEAP32[i17 + ((i13 | 24) + i14) >> 2] | 0;
+          i19 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
+          do {
+           if ((i19 | 0) == (i15 | 0)) {
+            i19 = i13 | 16;
+            i18 = i17 + (i12 + i19) | 0;
+            i16 = HEAP32[i18 >> 2] | 0;
+            if ((i16 | 0) == 0) {
+             i18 = i17 + (i19 + i14) | 0;
+             i16 = HEAP32[i18 >> 2] | 0;
+             if ((i16 | 0) == 0) {
+              i5 = 0;
+              break;
+             }
+            }
+            while (1) {
+             i20 = i16 + 20 | 0;
+             i19 = HEAP32[i20 >> 2] | 0;
+             if ((i19 | 0) != 0) {
+              i16 = i19;
+              i18 = i20;
+              continue;
+             }
+             i19 = i16 + 16 | 0;
+             i20 = HEAP32[i19 >> 2] | 0;
+             if ((i20 | 0) == 0) {
+              break;
+             } else {
+              i16 = i20;
+              i18 = i19;
+             }
+            }
+            if (i18 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+             _abort();
+            } else {
+             HEAP32[i18 >> 2] = 0;
+             i5 = i16;
+             break;
+            }
+           } else {
+            i18 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
+            if (i18 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+             _abort();
+            }
+            i16 = i18 + 12 | 0;
+            if ((HEAP32[i16 >> 2] | 0) != (i15 | 0)) {
+             _abort();
+            }
+            i20 = i19 + 8 | 0;
+            if ((HEAP32[i20 >> 2] | 0) == (i15 | 0)) {
+             HEAP32[i16 >> 2] = i19;
+             HEAP32[i20 >> 2] = i18;
+             i5 = i19;
+             break;
+            } else {
+             _abort();
+            }
+           }
+          } while (0);
+          if ((i9 | 0) != 0) {
+           i16 = HEAP32[i17 + (i14 + 28 + i13) >> 2] | 0;
+           i18 = 7464 + (i16 << 2) | 0;
+           if ((i15 | 0) == (HEAP32[i18 >> 2] | 0)) {
+            HEAP32[i18 >> 2] = i5;
+            if ((i5 | 0) == 0) {
+             HEAP32[7164 >> 2] = HEAP32[7164 >> 2] & ~(1 << i16);
+             break;
+            }
+           } else {
+            if (i9 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+             _abort();
+            }
+            i16 = i9 + 16 | 0;
+            if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
+             HEAP32[i16 >> 2] = i5;
+            } else {
+             HEAP32[i9 + 20 >> 2] = i5;
+            }
+            if ((i5 | 0) == 0) {
+             break;
+            }
+           }
+           if (i5 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           HEAP32[i5 + 24 >> 2] = i9;
+           i15 = i13 | 16;
+           i9 = HEAP32[i17 + (i15 + i14) >> 2] | 0;
+           do {
+            if ((i9 | 0) != 0) {
+             if (i9 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+              _abort();
+             } else {
+              HEAP32[i5 + 16 >> 2] = i9;
+              HEAP32[i9 + 24 >> 2] = i5;
+              break;
+             }
+            }
+           } while (0);
+           i9 = HEAP32[i17 + (i12 + i15) >> 2] | 0;
+           if ((i9 | 0) != 0) {
+            if (i9 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+             _abort();
+            } else {
+             HEAP32[i5 + 20 >> 2] = i9;
+             HEAP32[i9 + 24 >> 2] = i5;
+             break;
+            }
+           }
+          }
+         } else {
+          i5 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
+          i12 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
+          i18 = 7200 + (i16 << 1 << 2) | 0;
+          if ((i5 | 0) != (i18 | 0)) {
+           if (i5 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           if ((HEAP32[i5 + 12 >> 2] | 0) != (i15 | 0)) {
+            _abort();
+           }
+          }
+          if ((i12 | 0) == (i5 | 0)) {
+           HEAP32[1790] = HEAP32[1790] & ~(1 << i16);
+           break;
+          }
+          if ((i12 | 0) != (i18 | 0)) {
+           if (i12 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           i16 = i12 + 8 | 0;
+           if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
+            i9 = i16;
+           } else {
+            _abort();
+           }
+          } else {
+           i9 = i12 + 8 | 0;
+          }
+          HEAP32[i5 + 12 >> 2] = i12;
+          HEAP32[i9 >> 2] = i5;
+         }
+        } while (0);
+        i15 = i17 + ((i11 | i13) + i14) | 0;
+        i10 = i11 + i10 | 0;
+       }
+       i5 = i15 + 4 | 0;
+       HEAP32[i5 >> 2] = HEAP32[i5 >> 2] & -2;
+       HEAP32[i17 + (i8 + 4) >> 2] = i10 | 1;
+       HEAP32[i17 + (i10 + i8) >> 2] = i10;
+       i5 = i10 >>> 3;
+       if (i10 >>> 0 < 256) {
+        i10 = i5 << 1;
+        i2 = 7200 + (i10 << 2) | 0;
+        i9 = HEAP32[1790] | 0;
+        i5 = 1 << i5;
+        if ((i9 & i5 | 0) != 0) {
+         i9 = 7200 + (i10 + 2 << 2) | 0;
+         i5 = HEAP32[i9 >> 2] | 0;
+         if (i5 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          i3 = i9;
+          i4 = i5;
+         }
+        } else {
+         HEAP32[1790] = i9 | i5;
+         i3 = 7200 + (i10 + 2 << 2) | 0;
+         i4 = i2;
+        }
+        HEAP32[i3 >> 2] = i7;
+        HEAP32[i4 + 12 >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i4;
+        HEAP32[i17 + (i8 + 12) >> 2] = i2;
+        break;
+       }
+       i3 = i10 >>> 8;
+       if ((i3 | 0) != 0) {
+        if (i10 >>> 0 > 16777215) {
+         i3 = 31;
+        } else {
+         i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+         i32 = i3 << i31;
+         i30 = (i32 + 520192 | 0) >>> 16 & 4;
+         i32 = i32 << i30;
+         i3 = (i32 + 245760 | 0) >>> 16 & 2;
+         i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+         i3 = i10 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+        }
+       } else {
+        i3 = 0;
+       }
+       i4 = 7464 + (i3 << 2) | 0;
+       HEAP32[i17 + (i8 + 28) >> 2] = i3;
+       HEAP32[i17 + (i8 + 20) >> 2] = 0;
+       HEAP32[i17 + (i8 + 16) >> 2] = 0;
+       i9 = HEAP32[7164 >> 2] | 0;
+       i5 = 1 << i3;
+       if ((i9 & i5 | 0) == 0) {
+        HEAP32[7164 >> 2] = i9 | i5;
+        HEAP32[i4 >> 2] = i7;
+        HEAP32[i17 + (i8 + 24) >> 2] = i4;
+        HEAP32[i17 + (i8 + 12) >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i7;
+        break;
+       }
+       i4 = HEAP32[i4 >> 2] | 0;
+       if ((i3 | 0) == 31) {
+        i3 = 0;
+       } else {
+        i3 = 25 - (i3 >>> 1) | 0;
+       }
+       L444 : do {
+        if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i10 | 0)) {
+         i3 = i10 << i3;
+         while (1) {
+          i5 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+          i9 = HEAP32[i5 >> 2] | 0;
+          if ((i9 | 0) == 0) {
+           break;
+          }
+          if ((HEAP32[i9 + 4 >> 2] & -8 | 0) == (i10 | 0)) {
+           i2 = i9;
+           break L444;
+          } else {
+           i3 = i3 << 1;
+           i4 = i9;
+          }
+         }
+         if (i5 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i5 >> 2] = i7;
+          HEAP32[i17 + (i8 + 24) >> 2] = i4;
+          HEAP32[i17 + (i8 + 12) >> 2] = i7;
+          HEAP32[i17 + (i8 + 8) >> 2] = i7;
+          break L348;
+         }
+        } else {
+         i2 = i4;
+        }
+       } while (0);
+       i4 = i2 + 8 | 0;
+       i3 = HEAP32[i4 >> 2] | 0;
+       i5 = HEAP32[7176 >> 2] | 0;
+       if (i2 >>> 0 < i5 >>> 0) {
+        _abort();
+       }
+       if (i3 >>> 0 < i5 >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i3 + 12 >> 2] = i7;
+        HEAP32[i4 >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i3;
+        HEAP32[i17 + (i8 + 12) >> 2] = i2;
+        HEAP32[i17 + (i8 + 24) >> 2] = 0;
+        break;
+       }
+      } else {
+       i32 = (HEAP32[7172 >> 2] | 0) + i10 | 0;
+       HEAP32[7172 >> 2] = i32;
+       HEAP32[7184 >> 2] = i7;
+       HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
+      }
+     } while (0);
+     i32 = i17 + (i6 | 8) | 0;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+    i3 = 7608 | 0;
+    while (1) {
+     i2 = HEAP32[i3 >> 2] | 0;
+     if (!(i2 >>> 0 > i15 >>> 0) ? (i11 = HEAP32[i3 + 4 >> 2] | 0, i10 = i2 + i11 | 0, i10 >>> 0 > i15 >>> 0) : 0) {
+      break;
+     }
+     i3 = HEAP32[i3 + 8 >> 2] | 0;
+    }
+    i3 = i2 + (i11 + -39) | 0;
+    if ((i3 & 7 | 0) == 0) {
+     i3 = 0;
+    } else {
+     i3 = 0 - i3 & 7;
+    }
+    i2 = i2 + (i11 + -47 + i3) | 0;
+    i2 = i2 >>> 0 < (i15 + 16 | 0) >>> 0 ? i15 : i2;
+    i3 = i2 + 8 | 0;
+    i4 = i17 + 8 | 0;
+    if ((i4 & 7 | 0) == 0) {
+     i4 = 0;
+    } else {
+     i4 = 0 - i4 & 7;
+    }
+    i32 = i14 + -40 - i4 | 0;
+    HEAP32[7184 >> 2] = i17 + i4;
+    HEAP32[7172 >> 2] = i32;
+    HEAP32[i17 + (i4 + 4) >> 2] = i32 | 1;
+    HEAP32[i17 + (i14 + -36) >> 2] = 40;
+    HEAP32[7188 >> 2] = HEAP32[7648 >> 2];
+    HEAP32[i2 + 4 >> 2] = 27;
+    HEAP32[i3 + 0 >> 2] = HEAP32[7608 >> 2];
+    HEAP32[i3 + 4 >> 2] = HEAP32[7612 >> 2];
+    HEAP32[i3 + 8 >> 2] = HEAP32[7616 >> 2];
+    HEAP32[i3 + 12 >> 2] = HEAP32[7620 >> 2];
+    HEAP32[7608 >> 2] = i17;
+    HEAP32[7612 >> 2] = i14;
+    HEAP32[7620 >> 2] = 0;
+    HEAP32[7616 >> 2] = i3;
+    i4 = i2 + 28 | 0;
+    HEAP32[i4 >> 2] = 7;
+    if ((i2 + 32 | 0) >>> 0 < i10 >>> 0) {
+     while (1) {
+      i3 = i4 + 4 | 0;
+      HEAP32[i3 >> 2] = 7;
+      if ((i4 + 8 | 0) >>> 0 < i10 >>> 0) {
+       i4 = i3;
+      } else {
+       break;
+      }
+     }
+    }
+    if ((i2 | 0) != (i15 | 0)) {
+     i2 = i2 - i15 | 0;
+     i3 = i15 + (i2 + 4) | 0;
+     HEAP32[i3 >> 2] = HEAP32[i3 >> 2] & -2;
+     HEAP32[i15 + 4 >> 2] = i2 | 1;
+     HEAP32[i15 + i2 >> 2] = i2;
+     i3 = i2 >>> 3;
+     if (i2 >>> 0 < 256) {
+      i4 = i3 << 1;
+      i2 = 7200 + (i4 << 2) | 0;
+      i5 = HEAP32[1790] | 0;
+      i3 = 1 << i3;
+      if ((i5 & i3 | 0) != 0) {
+       i4 = 7200 + (i4 + 2 << 2) | 0;
+       i3 = HEAP32[i4 >> 2] | 0;
+       if (i3 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        i7 = i4;
+        i8 = i3;
+       }
+      } else {
+       HEAP32[1790] = i5 | i3;
+       i7 = 7200 + (i4 + 2 << 2) | 0;
+       i8 = i2;
+      }
+      HEAP32[i7 >> 2] = i15;
+      HEAP32[i8 + 12 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i8;
+      HEAP32[i15 + 12 >> 2] = i2;
+      break;
+     }
+     i3 = i2 >>> 8;
+     if ((i3 | 0) != 0) {
+      if (i2 >>> 0 > 16777215) {
+       i3 = 31;
+      } else {
+       i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+       i32 = i3 << i31;
+       i30 = (i32 + 520192 | 0) >>> 16 & 4;
+       i32 = i32 << i30;
+       i3 = (i32 + 245760 | 0) >>> 16 & 2;
+       i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+       i3 = i2 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+      }
+     } else {
+      i3 = 0;
+     }
+     i7 = 7464 + (i3 << 2) | 0;
+     HEAP32[i15 + 28 >> 2] = i3;
+     HEAP32[i15 + 20 >> 2] = 0;
+     HEAP32[i15 + 16 >> 2] = 0;
+     i4 = HEAP32[7164 >> 2] | 0;
+     i5 = 1 << i3;
+     if ((i4 & i5 | 0) == 0) {
+      HEAP32[7164 >> 2] = i4 | i5;
+      HEAP32[i7 >> 2] = i15;
+      HEAP32[i15 + 24 >> 2] = i7;
+      HEAP32[i15 + 12 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i15;
+      break;
+     }
+     i4 = HEAP32[i7 >> 2] | 0;
+     if ((i3 | 0) == 31) {
+      i3 = 0;
+     } else {
+      i3 = 25 - (i3 >>> 1) | 0;
+     }
+     L499 : do {
+      if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i2 | 0)) {
+       i3 = i2 << i3;
+       while (1) {
+        i7 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+        i5 = HEAP32[i7 >> 2] | 0;
+        if ((i5 | 0) == 0) {
+         break;
+        }
+        if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i2 | 0)) {
+         i6 = i5;
+         break L499;
+        } else {
+         i3 = i3 << 1;
+         i4 = i5;
+        }
+       }
+       if (i7 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i7 >> 2] = i15;
+        HEAP32[i15 + 24 >> 2] = i4;
+        HEAP32[i15 + 12 >> 2] = i15;
+        HEAP32[i15 + 8 >> 2] = i15;
+        break L311;
+       }
+      } else {
+       i6 = i4;
+      }
+     } while (0);
+     i4 = i6 + 8 | 0;
+     i3 = HEAP32[i4 >> 2] | 0;
+     i2 = HEAP32[7176 >> 2] | 0;
+     if (i6 >>> 0 < i2 >>> 0) {
+      _abort();
+     }
+     if (i3 >>> 0 < i2 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i3 + 12 >> 2] = i15;
+      HEAP32[i4 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i3;
+      HEAP32[i15 + 12 >> 2] = i6;
+      HEAP32[i15 + 24 >> 2] = 0;
+      break;
+     }
+    }
+   } else {
+    i32 = HEAP32[7176 >> 2] | 0;
+    if ((i32 | 0) == 0 | i17 >>> 0 < i32 >>> 0) {
+     HEAP32[7176 >> 2] = i17;
+    }
+    HEAP32[7608 >> 2] = i17;
+    HEAP32[7612 >> 2] = i14;
+    HEAP32[7620 >> 2] = 0;
+    HEAP32[7196 >> 2] = HEAP32[1908];
+    HEAP32[7192 >> 2] = -1;
+    i2 = 0;
+    do {
+     i32 = i2 << 1;
+     i31 = 7200 + (i32 << 2) | 0;
+     HEAP32[7200 + (i32 + 3 << 2) >> 2] = i31;
+     HEAP32[7200 + (i32 + 2 << 2) >> 2] = i31;
+     i2 = i2 + 1 | 0;
+    } while ((i2 | 0) != 32);
+    i2 = i17 + 8 | 0;
+    if ((i2 & 7 | 0) == 0) {
+     i2 = 0;
+    } else {
+     i2 = 0 - i2 & 7;
+    }
+    i32 = i14 + -40 - i2 | 0;
+    HEAP32[7184 >> 2] = i17 + i2;
+    HEAP32[7172 >> 2] = i32;
+    HEAP32[i17 + (i2 + 4) >> 2] = i32 | 1;
+    HEAP32[i17 + (i14 + -36) >> 2] = 40;
+    HEAP32[7188 >> 2] = HEAP32[7648 >> 2];
+   }
+  } while (0);
+  i2 = HEAP32[7172 >> 2] | 0;
+  if (i2 >>> 0 > i12 >>> 0) {
+   i31 = i2 - i12 | 0;
+   HEAP32[7172 >> 2] = i31;
+   i32 = HEAP32[7184 >> 2] | 0;
+   HEAP32[7184 >> 2] = i32 + i12;
+   HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
+   HEAP32[i32 + 4 >> 2] = i12 | 3;
+   i32 = i32 + 8 | 0;
+   STACKTOP = i1;
+   return i32 | 0;
+  }
+ }
+ HEAP32[(___errno_location() | 0) >> 2] = 12;
+ i32 = 0;
+ STACKTOP = i1;
+ return i32 | 0;
+}
+function __ZN12b2EPCollider7CollideEP10b2ManifoldPK11b2EdgeShapeRK11b2TransformPK14b2PolygonShapeS7_(i12, i2, i16, i5, i8, i6) {
+ i12 = i12 | 0;
+ i2 = i2 | 0;
+ i16 = i16 | 0;
+ i5 = i5 | 0;
+ i8 = i8 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i7 = 0, i9 = 0, i10 = 0, i11 = 0, i13 = 0, i14 = 0, i15 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, d22 = 0.0, d23 = 0.0, d24 = 0.0, d25 = 0.0, d26 = 0.0, d27 = 0.0, d28 = 0.0, i29 = 0, d30 = 0.0, d31 = 0.0, d32 = 0.0, d33 = 0.0, i34 = 0, i35 = 0, d36 = 0.0, d37 = 0.0, i38 = 0, d39 = 0.0, i40 = 0, i41 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 144 | 0;
+ i18 = i1 + 128 | 0;
+ i11 = i1 + 24 | 0;
+ i9 = i1 + 72 | 0;
+ i10 = i1 + 48 | 0;
+ i3 = i1;
+ i4 = i12 + 132 | 0;
+ d28 = +HEAPF32[i5 + 12 >> 2];
+ d37 = +HEAPF32[i6 + 8 >> 2];
+ d23 = +HEAPF32[i5 + 8 >> 2];
+ d27 = +HEAPF32[i6 + 12 >> 2];
+ d22 = d28 * d37 - d23 * d27;
+ d27 = d37 * d23 + d28 * d27;
+ d37 = +d22;
+ d26 = +d27;
+ d25 = +HEAPF32[i6 >> 2] - +HEAPF32[i5 >> 2];
+ d36 = +HEAPF32[i6 + 4 >> 2] - +HEAPF32[i5 + 4 >> 2];
+ d24 = d28 * d25 + d23 * d36;
+ d25 = d28 * d36 - d23 * d25;
+ d23 = +d24;
+ d36 = +d25;
+ i5 = i4;
+ HEAPF32[i5 >> 2] = d23;
+ HEAPF32[i5 + 4 >> 2] = d36;
+ i5 = i12 + 140 | 0;
+ HEAPF32[i5 >> 2] = d37;
+ HEAPF32[i5 + 4 >> 2] = d26;
+ i5 = i12 + 144 | 0;
+ d26 = +HEAPF32[i8 + 12 >> 2];
+ i7 = i12 + 140 | 0;
+ d37 = +HEAPF32[i8 + 16 >> 2];
+ d24 = d24 + (d27 * d26 - d22 * d37);
+ i6 = i12 + 136 | 0;
+ d25 = d26 * d22 + d27 * d37 + d25;
+ d37 = +d24;
+ d27 = +d25;
+ i34 = i12 + 148 | 0;
+ HEAPF32[i34 >> 2] = d37;
+ HEAPF32[i34 + 4 >> 2] = d27;
+ i34 = i16 + 28 | 0;
+ i29 = HEAP32[i34 >> 2] | 0;
+ i34 = HEAP32[i34 + 4 >> 2] | 0;
+ i14 = i12 + 156 | 0;
+ HEAP32[i14 >> 2] = i29;
+ HEAP32[i14 + 4 >> 2] = i34;
+ i14 = i12 + 164 | 0;
+ i17 = i16 + 12 | 0;
+ i40 = HEAP32[i17 >> 2] | 0;
+ i17 = HEAP32[i17 + 4 >> 2] | 0;
+ i13 = i14;
+ HEAP32[i13 >> 2] = i40;
+ HEAP32[i13 + 4 >> 2] = i17;
+ i13 = i12 + 172 | 0;
+ i20 = i16 + 20 | 0;
+ i41 = HEAP32[i20 >> 2] | 0;
+ i20 = HEAP32[i20 + 4 >> 2] | 0;
+ i38 = i13;
+ HEAP32[i38 >> 2] = i41;
+ HEAP32[i38 + 4 >> 2] = i20;
+ i38 = i16 + 36 | 0;
+ i35 = HEAP32[i38 >> 2] | 0;
+ i38 = HEAP32[i38 + 4 >> 2] | 0;
+ i19 = i12 + 180 | 0;
+ HEAP32[i19 >> 2] = i35;
+ HEAP32[i19 + 4 >> 2] = i38;
+ i19 = (HEAP8[i16 + 44 | 0] | 0) != 0;
+ i21 = (HEAP8[i16 + 45 | 0] | 0) != 0;
+ d27 = (HEAP32[tempDoublePtr >> 2] = i41, +HEAPF32[tempDoublePtr >> 2]);
+ d37 = (HEAP32[tempDoublePtr >> 2] = i40, +HEAPF32[tempDoublePtr >> 2]);
+ d22 = d27 - d37;
+ d26 = (HEAP32[tempDoublePtr >> 2] = i20, +HEAPF32[tempDoublePtr >> 2]);
+ i20 = i12 + 168 | 0;
+ d36 = (HEAP32[tempDoublePtr >> 2] = i17, +HEAPF32[tempDoublePtr >> 2]);
+ d23 = d26 - d36;
+ d28 = +Math_sqrt(+(d22 * d22 + d23 * d23));
+ d33 = (HEAP32[tempDoublePtr >> 2] = i29, +HEAPF32[tempDoublePtr >> 2]);
+ d32 = (HEAP32[tempDoublePtr >> 2] = i34, +HEAPF32[tempDoublePtr >> 2]);
+ d31 = (HEAP32[tempDoublePtr >> 2] = i35, +HEAPF32[tempDoublePtr >> 2]);
+ d30 = (HEAP32[tempDoublePtr >> 2] = i38, +HEAPF32[tempDoublePtr >> 2]);
+ if (!(d28 < 1.1920928955078125e-7)) {
+  d39 = 1.0 / d28;
+  d22 = d22 * d39;
+  d23 = d23 * d39;
+ }
+ i16 = i12 + 196 | 0;
+ d28 = -d22;
+ HEAPF32[i16 >> 2] = d23;
+ i17 = i12 + 200 | 0;
+ HEAPF32[i17 >> 2] = d28;
+ d28 = (d24 - d37) * d23 + (d25 - d36) * d28;
+ if (i19) {
+  d37 = d37 - d33;
+  d36 = d36 - d32;
+  d39 = +Math_sqrt(+(d37 * d37 + d36 * d36));
+  if (!(d39 < 1.1920928955078125e-7)) {
+   d39 = 1.0 / d39;
+   d37 = d37 * d39;
+   d36 = d36 * d39;
+  }
+  d39 = -d37;
+  HEAPF32[i12 + 188 >> 2] = d36;
+  HEAPF32[i12 + 192 >> 2] = d39;
+  i29 = d23 * d37 - d22 * d36 >= 0.0;
+  d32 = (d24 - d33) * d36 + (d25 - d32) * d39;
+ } else {
+  i29 = 0;
+  d32 = 0.0;
+ }
+ L10 : do {
+  if (!i21) {
+   if (!i19) {
+    i41 = d28 >= 0.0;
+    HEAP8[i12 + 248 | 0] = i41 & 1;
+    i19 = i12 + 212 | 0;
+    if (i41) {
+     i15 = 64;
+     break;
+    } else {
+     i15 = 65;
+     break;
+    }
+   }
+   i19 = d32 >= 0.0;
+   if (i29) {
+    if (!i19) {
+     i41 = d28 >= 0.0;
+     HEAP8[i12 + 248 | 0] = i41 & 1;
+     i19 = i12 + 212 | 0;
+     if (!i41) {
+      d37 = +-d23;
+      d39 = +d22;
+      i38 = i19;
+      HEAPF32[i38 >> 2] = d37;
+      HEAPF32[i38 + 4 >> 2] = d39;
+      i38 = i16;
+      i40 = HEAP32[i38 >> 2] | 0;
+      i38 = HEAP32[i38 + 4 >> 2] | 0;
+      i41 = i12 + 228 | 0;
+      HEAP32[i41 >> 2] = i40;
+      HEAP32[i41 + 4 >> 2] = i38;
+      i41 = i12 + 236 | 0;
+      HEAPF32[i41 >> 2] = -(HEAP32[tempDoublePtr >> 2] = i40, +HEAPF32[tempDoublePtr >> 2]);
+      HEAPF32[i41 + 4 >> 2] = d39;
+      break;
+     }
+    } else {
+     HEAP8[i12 + 248 | 0] = 1;
+     i19 = i12 + 212 | 0;
+    }
+    i41 = i16;
+    i40 = HEAP32[i41 + 4 >> 2] | 0;
+    i38 = i19;
+    HEAP32[i38 >> 2] = HEAP32[i41 >> 2];
+    HEAP32[i38 + 4 >> 2] = i40;
+    i38 = i12 + 188 | 0;
+    i40 = HEAP32[i38 + 4 >> 2] | 0;
+    i41 = i12 + 228 | 0;
+    HEAP32[i41 >> 2] = HEAP32[i38 >> 2];
+    HEAP32[i41 + 4 >> 2] = i40;
+    d37 = +-+HEAPF32[i16 >> 2];
+    d39 = +-+HEAPF32[i17 >> 2];
+    i41 = i12 + 236 | 0;
+    HEAPF32[i41 >> 2] = d37;
+    HEAPF32[i41 + 4 >> 2] = d39;
+    break;
+   } else {
+    if (i19) {
+     i41 = d28 >= 0.0;
+     HEAP8[i12 + 248 | 0] = i41 & 1;
+     i19 = i12 + 212 | 0;
+     if (i41) {
+      i38 = i16;
+      i41 = HEAP32[i38 >> 2] | 0;
+      i38 = HEAP32[i38 + 4 >> 2] | 0;
+      i40 = i19;
+      HEAP32[i40 >> 2] = i41;
+      HEAP32[i40 + 4 >> 2] = i38;
+      i40 = i12 + 228 | 0;
+      HEAP32[i40 >> 2] = i41;
+      HEAP32[i40 + 4 >> 2] = i38;
+      d37 = +-(HEAP32[tempDoublePtr >> 2] = i41, +HEAPF32[tempDoublePtr >> 2]);
+      d39 = +d22;
+      i41 = i12 + 236 | 0;
+      HEAPF32[i41 >> 2] = d37;
+      HEAPF32[i41 + 4 >> 2] = d39;
+      break;
+     }
+    } else {
+     HEAP8[i12 + 248 | 0] = 0;
+     i19 = i12 + 212 | 0;
+    }
+    d39 = +-d23;
+    d37 = +d22;
+    i38 = i19;
+    HEAPF32[i38 >> 2] = d39;
+    HEAPF32[i38 + 4 >> 2] = d37;
+    i38 = i16;
+    i40 = HEAP32[i38 + 4 >> 2] | 0;
+    i41 = i12 + 228 | 0;
+    HEAP32[i41 >> 2] = HEAP32[i38 >> 2];
+    HEAP32[i41 + 4 >> 2] = i40;
+    d37 = +-+HEAPF32[i12 + 188 >> 2];
+    d39 = +-+HEAPF32[i12 + 192 >> 2];
+    i41 = i12 + 236 | 0;
+    HEAPF32[i41 >> 2] = d37;
+    HEAPF32[i41 + 4 >> 2] = d39;
+    break;
+   }
+  } else {
+   d33 = d31 - d27;
+   d31 = d30 - d26;
+   d30 = +Math_sqrt(+(d33 * d33 + d31 * d31));
+   if (d30 < 1.1920928955078125e-7) {
+    d30 = d33;
+   } else {
+    d39 = 1.0 / d30;
+    d30 = d33 * d39;
+    d31 = d31 * d39;
+   }
+   d39 = -d30;
+   i34 = i12 + 204 | 0;
+   HEAPF32[i34 >> 2] = d31;
+   i35 = i12 + 208 | 0;
+   HEAPF32[i35 >> 2] = d39;
+   i38 = d22 * d31 - d23 * d30 > 0.0;
+   d24 = (d24 - d27) * d31 + (d25 - d26) * d39;
+   if (!i19) {
+    i19 = d28 >= 0.0;
+    if (!i21) {
+     HEAP8[i12 + 248 | 0] = i19 & 1;
+     i15 = i12 + 212 | 0;
+     if (i19) {
+      i19 = i15;
+      i15 = 64;
+      break;
+     } else {
+      i19 = i15;
+      i15 = 65;
+      break;
+     }
+    }
+    if (i38) {
+     if (!i19) {
+      i41 = d24 >= 0.0;
+      HEAP8[i12 + 248 | 0] = i41 & 1;
+      i19 = i12 + 212 | 0;
+      if (!i41) {
+       d37 = +-d23;
+       d39 = +d22;
+       i38 = i19;
+       HEAPF32[i38 >> 2] = d37;
+       HEAPF32[i38 + 4 >> 2] = d39;
+       i38 = i12 + 228 | 0;
+       HEAPF32[i38 >> 2] = d37;
+       HEAPF32[i38 + 4 >> 2] = d39;
+       i38 = i16;
+       i40 = HEAP32[i38 + 4 >> 2] | 0;
+       i41 = i12 + 236 | 0;
+       HEAP32[i41 >> 2] = HEAP32[i38 >> 2];
+       HEAP32[i41 + 4 >> 2] = i40;
+       break;
+      }
+     } else {
+      HEAP8[i12 + 248 | 0] = 1;
+      i19 = i12 + 212 | 0;
+     }
+     i41 = i16;
+     i40 = HEAP32[i41 + 4 >> 2] | 0;
+     i38 = i19;
+     HEAP32[i38 >> 2] = HEAP32[i41 >> 2];
+     HEAP32[i38 + 4 >> 2] = i40;
+     d37 = +-+HEAPF32[i16 >> 2];
+     d39 = +-+HEAPF32[i17 >> 2];
+     i38 = i12 + 228 | 0;
+     HEAPF32[i38 >> 2] = d37;
+     HEAPF32[i38 + 4 >> 2] = d39;
+     i38 = i12 + 204 | 0;
+     i40 = HEAP32[i38 + 4 >> 2] | 0;
+     i41 = i12 + 236 | 0;
+     HEAP32[i41 >> 2] = HEAP32[i38 >> 2];
+     HEAP32[i41 + 4 >> 2] = i40;
+     break;
+    } else {
+     if (i19) {
+      i41 = d24 >= 0.0;
+      HEAP8[i12 + 248 | 0] = i41 & 1;
+      i19 = i12 + 212 | 0;
+      if (i41) {
+       i40 = i16;
+       i38 = HEAP32[i40 >> 2] | 0;
+       i40 = HEAP32[i40 + 4 >> 2] | 0;
+       i41 = i19;
+       HEAP32[i41 >> 2] = i38;
+       HEAP32[i41 + 4 >> 2] = i40;
+       d37 = +-(HEAP32[tempDoublePtr >> 2] = i38, +HEAPF32[tempDoublePtr >> 2]);
+       d39 = +d22;
+       i41 = i12 + 228 | 0;
+       HEAPF32[i41 >> 2] = d37;
+       HEAPF32[i41 + 4 >> 2] = d39;
+       i41 = i12 + 236 | 0;
+       HEAP32[i41 >> 2] = i38;
+       HEAP32[i41 + 4 >> 2] = i40;
+       break;
+      }
+     } else {
+      HEAP8[i12 + 248 | 0] = 0;
+      i19 = i12 + 212 | 0;
+     }
+     d39 = +-d23;
+     d37 = +d22;
+     i38 = i19;
+     HEAPF32[i38 >> 2] = d39;
+     HEAPF32[i38 + 4 >> 2] = d37;
+     d37 = +-+HEAPF32[i12 + 204 >> 2];
+     d39 = +-+HEAPF32[i12 + 208 >> 2];
+     i38 = i12 + 228 | 0;
+     HEAPF32[i38 >> 2] = d37;
+     HEAPF32[i38 + 4 >> 2] = d39;
+     i38 = i16;
+     i40 = HEAP32[i38 + 4 >> 2] | 0;
+     i41 = i12 + 236 | 0;
+     HEAP32[i41 >> 2] = HEAP32[i38 >> 2];
+     HEAP32[i41 + 4 >> 2] = i40;
+     break;
+    }
+   }
+   if (i29 & i38) {
+    if (!(d32 >= 0.0) & !(d28 >= 0.0)) {
+     i41 = d24 >= 0.0;
+     HEAP8[i12 + 248 | 0] = i41 & 1;
+     i19 = i12 + 212 | 0;
+     if (!i41) {
+      d37 = +-d23;
+      d39 = +d22;
+      i41 = i19;
+      HEAPF32[i41 >> 2] = d37;
+      HEAPF32[i41 + 4 >> 2] = d39;
+      i41 = i12 + 228 | 0;
+      HEAPF32[i41 >> 2] = d37;
+      HEAPF32[i41 + 4 >> 2] = d39;
+      i41 = i12 + 236 | 0;
+      HEAPF32[i41 >> 2] = d37;
+      HEAPF32[i41 + 4 >> 2] = d39;
+      break;
+     }
+    } else {
+     HEAP8[i12 + 248 | 0] = 1;
+     i19 = i12 + 212 | 0;
+    }
+    i38 = i16;
+    i40 = HEAP32[i38 + 4 >> 2] | 0;
+    i41 = i19;
+    HEAP32[i41 >> 2] = HEAP32[i38 >> 2];
+    HEAP32[i41 + 4 >> 2] = i40;
+    i41 = i12 + 188 | 0;
+    i40 = HEAP32[i41 + 4 >> 2] | 0;
+    i38 = i12 + 228 | 0;
+    HEAP32[i38 >> 2] = HEAP32[i41 >> 2];
+    HEAP32[i38 + 4 >> 2] = i40;
+    i38 = i12 + 204 | 0;
+    i40 = HEAP32[i38 + 4 >> 2] | 0;
+    i41 = i12 + 236 | 0;
+    HEAP32[i41 >> 2] = HEAP32[i38 >> 2];
+    HEAP32[i41 + 4 >> 2] = i40;
+    break;
+   }
+   if (i29) {
+    do {
+     if (!(d32 >= 0.0)) {
+      if (d28 >= 0.0) {
+       i41 = d24 >= 0.0;
+       HEAP8[i12 + 248 | 0] = i41 & 1;
+       i19 = i12 + 212 | 0;
+       if (i41) {
+        break;
+       }
+      } else {
+       HEAP8[i12 + 248 | 0] = 0;
+       i19 = i12 + 212 | 0;
+      }
+      d37 = +-d23;
+      d39 = +d22;
+      i41 = i19;
+      HEAPF32[i41 >> 2] = d37;
+      HEAPF32[i41 + 4 >> 2] = d39;
+      d39 = +-+HEAPF32[i34 >> 2];
+      d37 = +-+HEAPF32[i35 >> 2];
+      i41 = i12 + 228 | 0;
+      HEAPF32[i41 >> 2] = d39;
+      HEAPF32[i41 + 4 >> 2] = d37;
+      d37 = +-+HEAPF32[i16 >> 2];
+      d39 = +-+HEAPF32[i17 >> 2];
+      i41 = i12 + 236 | 0;
+      HEAPF32[i41 >> 2] = d37;
+      HEAPF32[i41 + 4 >> 2] = d39;
+      break L10;
+     } else {
+      HEAP8[i12 + 248 | 0] = 1;
+      i19 = i12 + 212 | 0;
+     }
+    } while (0);
+    i38 = i16;
+    i40 = HEAP32[i38 + 4 >> 2] | 0;
+    i41 = i19;
+    HEAP32[i41 >> 2] = HEAP32[i38 >> 2];
+    HEAP32[i41 + 4 >> 2] = i40;
+    i41 = i12 + 188 | 0;
+    i40 = HEAP32[i41 + 4 >> 2] | 0;
+    i38 = i12 + 228 | 0;
+    HEAP32[i38 >> 2] = HEAP32[i41 >> 2];
+    HEAP32[i38 + 4 >> 2] = i40;
+    i38 = i16;
+    i40 = HEAP32[i38 + 4 >> 2] | 0;
+    i41 = i12 + 236 | 0;
+    HEAP32[i41 >> 2] = HEAP32[i38 >> 2];
+    HEAP32[i41 + 4 >> 2] = i40;
+    break;
+   }
+   if (!i38) {
+    if (!(!(d32 >= 0.0) | !(d28 >= 0.0))) {
+     i41 = d24 >= 0.0;
+     HEAP8[i12 + 248 | 0] = i41 & 1;
+     i19 = i12 + 212 | 0;
+     if (i41) {
+      i40 = i16;
+      i38 = HEAP32[i40 >> 2] | 0;
+      i40 = HEAP32[i40 + 4 >> 2] | 0;
+      i41 = i19;
+      HEAP32[i41 >> 2] = i38;
+      HEAP32[i41 + 4 >> 2] = i40;
+      i41 = i12 + 228 | 0;
+      HEAP32[i41 >> 2] = i38;
+      HEAP32[i41 + 4 >> 2] = i40;
+      i41 = i12 + 236 | 0;
+      HEAP32[i41 >> 2] = i38;
+      HEAP32[i41 + 4 >> 2] = i40;
+      break;
+     }
+    } else {
+     HEAP8[i12 + 248 | 0] = 0;
+     i19 = i12 + 212 | 0;
+    }
+    d37 = +-d23;
+    d39 = +d22;
+    i41 = i19;
+    HEAPF32[i41 >> 2] = d37;
+    HEAPF32[i41 + 4 >> 2] = d39;
+    d39 = +-+HEAPF32[i34 >> 2];
+    d37 = +-+HEAPF32[i35 >> 2];
+    i41 = i12 + 228 | 0;
+    HEAPF32[i41 >> 2] = d39;
+    HEAPF32[i41 + 4 >> 2] = d37;
+    d37 = +-+HEAPF32[i12 + 188 >> 2];
+    d39 = +-+HEAPF32[i12 + 192 >> 2];
+    i41 = i12 + 236 | 0;
+    HEAPF32[i41 >> 2] = d37;
+    HEAPF32[i41 + 4 >> 2] = d39;
+    break;
+   }
+   do {
+    if (!(d24 >= 0.0)) {
+     if (d32 >= 0.0) {
+      i41 = d28 >= 0.0;
+      HEAP8[i12 + 248 | 0] = i41 & 1;
+      i19 = i12 + 212 | 0;
+      if (i41) {
+       break;
+      }
+     } else {
+      HEAP8[i12 + 248 | 0] = 0;
+      i19 = i12 + 212 | 0;
+     }
+     d37 = +-d23;
+     d39 = +d22;
+     i41 = i19;
+     HEAPF32[i41 >> 2] = d37;
+     HEAPF32[i41 + 4 >> 2] = d39;
+     d39 = +-+HEAPF32[i16 >> 2];
+     d37 = +-+HEAPF32[i17 >> 2];
+     i41 = i12 + 228 | 0;
+     HEAPF32[i41 >> 2] = d39;
+     HEAPF32[i41 + 4 >> 2] = d37;
+     d37 = +-+HEAPF32[i12 + 188 >> 2];
+     d39 = +-+HEAPF32[i12 + 192 >> 2];
+     i41 = i12 + 236 | 0;
+     HEAPF32[i41 >> 2] = d37;
+     HEAPF32[i41 + 4 >> 2] = d39;
+     break L10;
+    } else {
+     HEAP8[i12 + 248 | 0] = 1;
+     i19 = i12 + 212 | 0;
+    }
+   } while (0);
+   i38 = i16;
+   i40 = HEAP32[i38 + 4 >> 2] | 0;
+   i41 = i19;
+   HEAP32[i41 >> 2] = HEAP32[i38 >> 2];
+   HEAP32[i41 + 4 >> 2] = i40;
+   i41 = i16;
+   i40 = HEAP32[i41 + 4 >> 2] | 0;
+   i38 = i12 + 228 | 0;
+   HEAP32[i38 >> 2] = HEAP32[i41 >> 2];
+   HEAP32[i38 + 4 >> 2] = i40;
+   i38 = i12 + 204 | 0;
+   i40 = HEAP32[i38 + 4 >> 2] | 0;
+   i41 = i12 + 236 | 0;
+   HEAP32[i41 >> 2] = HEAP32[i38 >> 2];
+   HEAP32[i41 + 4 >> 2] = i40;
+  }
+ } while (0);
+ if ((i15 | 0) == 64) {
+  i38 = i16;
+  i41 = HEAP32[i38 >> 2] | 0;
+  i38 = HEAP32[i38 + 4 >> 2] | 0;
+  i40 = i19;
+  HEAP32[i40 >> 2] = i41;
+  HEAP32[i40 + 4 >> 2] = i38;
+  d37 = +-(HEAP32[tempDoublePtr >> 2] = i41, +HEAPF32[tempDoublePtr >> 2]);
+  d39 = +d22;
+  i41 = i12 + 228 | 0;
+  HEAPF32[i41 >> 2] = d37;
+  HEAPF32[i41 + 4 >> 2] = d39;
+  i41 = i12 + 236 | 0;
+  HEAPF32[i41 >> 2] = d37;
+  HEAPF32[i41 + 4 >> 2] = d39;
+ } else if ((i15 | 0) == 65) {
+  d37 = +-d23;
+  d39 = +d22;
+  i40 = i19;
+  HEAPF32[i40 >> 2] = d37;
+  HEAPF32[i40 + 4 >> 2] = d39;
+  i40 = i16;
+  i38 = HEAP32[i40 >> 2] | 0;
+  i40 = HEAP32[i40 + 4 >> 2] | 0;
+  i41 = i12 + 228 | 0;
+  HEAP32[i41 >> 2] = i38;
+  HEAP32[i41 + 4 >> 2] = i40;
+  i41 = i12 + 236 | 0;
+  HEAP32[i41 >> 2] = i38;
+  HEAP32[i41 + 4 >> 2] = i40;
+ }
+ i21 = i8 + 148 | 0;
+ i34 = i12 + 128 | 0;
+ HEAP32[i34 >> 2] = HEAP32[i21 >> 2];
+ if ((HEAP32[i21 >> 2] | 0) > 0) {
+  i19 = 0;
+  do {
+   d33 = +HEAPF32[i5 >> 2];
+   d37 = +HEAPF32[i8 + (i19 << 3) + 20 >> 2];
+   d39 = +HEAPF32[i7 >> 2];
+   d36 = +HEAPF32[i8 + (i19 << 3) + 24 >> 2];
+   d32 = +(+HEAPF32[i4 >> 2] + (d33 * d37 - d39 * d36));
+   d36 = +(d37 * d39 + d33 * d36 + +HEAPF32[i6 >> 2]);
+   i41 = i12 + (i19 << 3) | 0;
+   HEAPF32[i41 >> 2] = d32;
+   HEAPF32[i41 + 4 >> 2] = d36;
+   d36 = +HEAPF32[i5 >> 2];
+   d32 = +HEAPF32[i8 + (i19 << 3) + 84 >> 2];
+   d33 = +HEAPF32[i7 >> 2];
+   d39 = +HEAPF32[i8 + (i19 << 3) + 88 >> 2];
+   d37 = +(d36 * d32 - d33 * d39);
+   d39 = +(d32 * d33 + d36 * d39);
+   i41 = i12 + (i19 << 3) + 64 | 0;
+   HEAPF32[i41 >> 2] = d37;
+   HEAPF32[i41 + 4 >> 2] = d39;
+   i19 = i19 + 1 | 0;
+  } while ((i19 | 0) < (HEAP32[i21 >> 2] | 0));
+ }
+ i21 = i12 + 244 | 0;
+ HEAPF32[i21 >> 2] = .019999999552965164;
+ i19 = i2 + 60 | 0;
+ HEAP32[i19 >> 2] = 0;
+ i29 = i12 + 248 | 0;
+ i35 = HEAP32[i34 >> 2] | 0;
+ if ((i35 | 0) <= 0) {
+  STACKTOP = i1;
+  return;
+ }
+ d23 = +HEAPF32[i12 + 164 >> 2];
+ d26 = +HEAPF32[i20 >> 2];
+ d24 = +HEAPF32[i12 + 212 >> 2];
+ d27 = +HEAPF32[i12 + 216 >> 2];
+ d22 = 3.4028234663852886e+38;
+ i20 = 0;
+ do {
+  d25 = d24 * (+HEAPF32[i12 + (i20 << 3) >> 2] - d23) + d27 * (+HEAPF32[i12 + (i20 << 3) + 4 >> 2] - d26);
+  d22 = d25 < d22 ? d25 : d22;
+  i20 = i20 + 1 | 0;
+ } while ((i20 | 0) != (i35 | 0));
+ if (d22 > .019999999552965164) {
+  STACKTOP = i1;
+  return;
+ }
+ __ZN12b2EPCollider24ComputePolygonSeparationEv(i18, i12);
+ i20 = HEAP32[i18 >> 2] | 0;
+ if ((i20 | 0) != 0) {
+  d23 = +HEAPF32[i18 + 8 >> 2];
+  if (d23 > +HEAPF32[i21 >> 2]) {
+   STACKTOP = i1;
+   return;
+  }
+  if (d23 > d22 * .9800000190734863 + .0010000000474974513) {
+   i18 = HEAP32[i18 + 4 >> 2] | 0;
+   i35 = i2 + 56 | 0;
+   if ((i20 | 0) == 1) {
+    i18 = i11;
+    i15 = 77;
+   } else {
+    HEAP32[i35 >> 2] = 2;
+    i40 = i14;
+    i41 = HEAP32[i40 + 4 >> 2] | 0;
+    i38 = i11;
+    HEAP32[i38 >> 2] = HEAP32[i40 >> 2];
+    HEAP32[i38 + 4 >> 2] = i41;
+    i38 = i11 + 8 | 0;
+    HEAP8[i38] = 0;
+    i41 = i18 & 255;
+    HEAP8[i38 + 1 | 0] = i41;
+    HEAP8[i38 + 2 | 0] = 0;
+    HEAP8[i38 + 3 | 0] = 1;
+    i38 = i13;
+    i40 = HEAP32[i38 + 4 >> 2] | 0;
+    i13 = i11 + 12 | 0;
+    HEAP32[i13 >> 2] = HEAP32[i38 >> 2];
+    HEAP32[i13 + 4 >> 2] = i40;
+    i13 = i11 + 20 | 0;
+    HEAP8[i13] = 0;
+    HEAP8[i13 + 1 | 0] = i41;
+    HEAP8[i13 + 2 | 0] = 0;
+    HEAP8[i13 + 3 | 0] = 1;
+    HEAP32[i9 >> 2] = i18;
+    i13 = i18 + 1 | 0;
+    i16 = (i13 | 0) < (HEAP32[i34 >> 2] | 0) ? i13 : 0;
+    HEAP32[i9 + 4 >> 2] = i16;
+    i17 = i12 + (i18 << 3) | 0;
+    i13 = HEAP32[i17 >> 2] | 0;
+    i17 = HEAP32[i17 + 4 >> 2] | 0;
+    i29 = i9 + 8 | 0;
+    HEAP32[i29 >> 2] = i13;
+    HEAP32[i29 + 4 >> 2] = i17;
+    i16 = i12 + (i16 << 3) | 0;
+    i29 = HEAP32[i16 >> 2] | 0;
+    i16 = HEAP32[i16 + 4 >> 2] | 0;
+    i20 = i9 + 16 | 0;
+    HEAP32[i20 >> 2] = i29;
+    HEAP32[i20 + 4 >> 2] = i16;
+    i20 = i12 + (i18 << 3) + 64 | 0;
+    i12 = HEAP32[i20 >> 2] | 0;
+    i20 = HEAP32[i20 + 4 >> 2] | 0;
+    i14 = i9 + 24 | 0;
+    HEAP32[i14 >> 2] = i12;
+    HEAP32[i14 + 4 >> 2] = i20;
+    i14 = 0;
+   }
+  } else {
+   i15 = 75;
+  }
+ } else {
+  i15 = 75;
+ }
+ if ((i15 | 0) == 75) {
+  i18 = i11;
+  i35 = i2 + 56 | 0;
+  i15 = 77;
+ }
+ do {
+  if ((i15 | 0) == 77) {
+   HEAP32[i35 >> 2] = 1;
+   i15 = HEAP32[i34 >> 2] | 0;
+   if ((i15 | 0) > 1) {
+    d23 = +HEAPF32[i12 + 216 >> 2];
+    d22 = +HEAPF32[i12 + 212 >> 2];
+    i34 = 0;
+    d24 = d22 * +HEAPF32[i12 + 64 >> 2] + d23 * +HEAPF32[i12 + 68 >> 2];
+    i35 = 1;
+    while (1) {
+     d25 = d22 * +HEAPF32[i12 + (i35 << 3) + 64 >> 2] + d23 * +HEAPF32[i12 + (i35 << 3) + 68 >> 2];
+     i20 = d25 < d24;
+     i34 = i20 ? i35 : i34;
+     i35 = i35 + 1 | 0;
+     if ((i35 | 0) < (i15 | 0)) {
+      d24 = i20 ? d25 : d24;
+     } else {
+      break;
+     }
+    }
+   } else {
+    i34 = 0;
+   }
+   i20 = i34 + 1 | 0;
+   i40 = (i20 | 0) < (i15 | 0) ? i20 : 0;
+   i41 = i12 + (i34 << 3) | 0;
+   i38 = HEAP32[i41 + 4 >> 2] | 0;
+   i35 = i11;
+   HEAP32[i35 >> 2] = HEAP32[i41 >> 2];
+   HEAP32[i35 + 4 >> 2] = i38;
+   i35 = i11 + 8 | 0;
+   HEAP8[i35] = 0;
+   HEAP8[i35 + 1 | 0] = i34;
+   HEAP8[i35 + 2 | 0] = 1;
+   HEAP8[i35 + 3 | 0] = 0;
+   i35 = i12 + (i40 << 3) | 0;
+   i38 = HEAP32[i35 + 4 >> 2] | 0;
+   i41 = i11 + 12 | 0;
+   HEAP32[i41 >> 2] = HEAP32[i35 >> 2];
+   HEAP32[i41 + 4 >> 2] = i38;
+   i41 = i11 + 20 | 0;
+   HEAP8[i41] = 0;
+   HEAP8[i41 + 1 | 0] = i40;
+   HEAP8[i41 + 2 | 0] = 1;
+   HEAP8[i41 + 3 | 0] = 0;
+   if ((HEAP8[i29] | 0) == 0) {
+    HEAP32[i9 >> 2] = 1;
+    HEAP32[i9 + 4 >> 2] = 0;
+    i11 = i13;
+    i13 = HEAP32[i11 >> 2] | 0;
+    i11 = HEAP32[i11 + 4 >> 2] | 0;
+    i29 = i9 + 8 | 0;
+    HEAP32[i29 >> 2] = i13;
+    HEAP32[i29 + 4 >> 2] = i11;
+    i29 = HEAP32[i14 >> 2] | 0;
+    i14 = HEAP32[i14 + 4 >> 2] | 0;
+    i12 = i9 + 16 | 0;
+    HEAP32[i12 >> 2] = i29;
+    HEAP32[i12 + 4 >> 2] = i14;
+    i12 = (HEAPF32[tempDoublePtr >> 2] = -+HEAPF32[i16 >> 2], HEAP32[tempDoublePtr >> 2] | 0);
+    i20 = (HEAPF32[tempDoublePtr >> 2] = -+HEAPF32[i17 >> 2], HEAP32[tempDoublePtr >> 2] | 0);
+    i16 = i9 + 24 | 0;
+    HEAP32[i16 >> 2] = i12;
+    HEAP32[i16 + 4 >> 2] = i20;
+    i16 = i14;
+    i17 = i11;
+    i11 = i18;
+    i18 = 1;
+    i14 = 1;
+    break;
+   } else {
+    HEAP32[i9 >> 2] = 0;
+    HEAP32[i9 + 4 >> 2] = 1;
+    i17 = i14;
+    i11 = HEAP32[i17 >> 2] | 0;
+    i17 = HEAP32[i17 + 4 >> 2] | 0;
+    i29 = i9 + 8 | 0;
+    HEAP32[i29 >> 2] = i11;
+    HEAP32[i29 + 4 >> 2] = i17;
+    i29 = HEAP32[i13 >> 2] | 0;
+    i13 = HEAP32[i13 + 4 >> 2] | 0;
+    i20 = i9 + 16 | 0;
+    HEAP32[i20 >> 2] = i29;
+    HEAP32[i20 + 4 >> 2] = i13;
+    i20 = i16;
+    i12 = HEAP32[i20 >> 2] | 0;
+    i20 = HEAP32[i20 + 4 >> 2] | 0;
+    i16 = i9 + 24 | 0;
+    HEAP32[i16 >> 2] = i12;
+    HEAP32[i16 + 4 >> 2] = i20;
+    i16 = i13;
+    i13 = i11;
+    i11 = i18;
+    i18 = 0;
+    i14 = 1;
+    break;
+   }
+  }
+ } while (0);
+ d30 = (HEAP32[tempDoublePtr >> 2] = i20, +HEAPF32[tempDoublePtr >> 2]);
+ d39 = (HEAP32[tempDoublePtr >> 2] = i12, +HEAPF32[tempDoublePtr >> 2]);
+ d31 = (HEAP32[tempDoublePtr >> 2] = i13, +HEAPF32[tempDoublePtr >> 2]);
+ d32 = (HEAP32[tempDoublePtr >> 2] = i17, +HEAPF32[tempDoublePtr >> 2]);
+ d33 = (HEAP32[tempDoublePtr >> 2] = i29, +HEAPF32[tempDoublePtr >> 2]);
+ d37 = (HEAP32[tempDoublePtr >> 2] = i16, +HEAPF32[tempDoublePtr >> 2]);
+ i41 = i9 + 32 | 0;
+ i16 = i9 + 24 | 0;
+ i13 = i9 + 28 | 0;
+ d39 = -d39;
+ HEAPF32[i41 >> 2] = d30;
+ HEAPF32[i9 + 36 >> 2] = d39;
+ i20 = i9 + 44 | 0;
+ d36 = -d30;
+ i17 = i20;
+ HEAPF32[i17 >> 2] = d36;
+ HEAP32[i17 + 4 >> 2] = i12;
+ i17 = i9 + 8 | 0;
+ i15 = i9 + 12 | 0;
+ d39 = d30 * d31 + d32 * d39;
+ HEAPF32[i9 + 40 >> 2] = d39;
+ i29 = i9 + 52 | 0;
+ HEAPF32[i29 >> 2] = d33 * d36 + (HEAP32[tempDoublePtr >> 2] = i12, +HEAPF32[tempDoublePtr >> 2]) * d37;
+ if ((__Z19b2ClipSegmentToLineP12b2ClipVertexPKS_RK6b2Vec2fi(i10, i11, i41, d39, i18) | 0) < 2) {
+  STACKTOP = i1;
+  return;
+ }
+ if ((__Z19b2ClipSegmentToLineP12b2ClipVertexPKS_RK6b2Vec2fi(i3, i10, i20, +HEAPF32[i29 >> 2], HEAP32[i9 + 4 >> 2] | 0) | 0) < 2) {
+  STACKTOP = i1;
+  return;
+ }
+ i10 = i2 + 40 | 0;
+ if (i14) {
+  i40 = i16;
+  i41 = HEAP32[i40 >> 2] | 0;
+  i40 = HEAP32[i40 + 4 >> 2] | 0;
+  i35 = i10;
+  HEAP32[i35 >> 2] = i41;
+  HEAP32[i35 + 4 >> 2] = i40;
+  i35 = i17;
+  i40 = HEAP32[i35 >> 2] | 0;
+  i35 = HEAP32[i35 + 4 >> 2] | 0;
+  i38 = i2 + 48 | 0;
+  HEAP32[i38 >> 2] = i40;
+  HEAP32[i38 + 4 >> 2] = i35;
+  d23 = (HEAP32[tempDoublePtr >> 2] = i40, +HEAPF32[tempDoublePtr >> 2]);
+  d22 = (HEAP32[tempDoublePtr >> 2] = i41, +HEAPF32[tempDoublePtr >> 2]);
+  d24 = +HEAPF32[i15 >> 2];
+  d25 = +HEAPF32[i13 >> 2];
+  d28 = +HEAPF32[i3 >> 2];
+  d27 = +HEAPF32[i3 + 4 >> 2];
+  d26 = +HEAPF32[i21 >> 2];
+  if (!((d28 - d23) * d22 + (d27 - d24) * d25 <= d26)) {
+   d28 = d26;
+   i8 = 0;
+  } else {
+   d37 = d28 - +HEAPF32[i4 >> 2];
+   d36 = d27 - +HEAPF32[i6 >> 2];
+   d33 = +HEAPF32[i5 >> 2];
+   d28 = +HEAPF32[i7 >> 2];
+   d39 = +(d37 * d33 + d36 * d28);
+   d28 = +(d33 * d36 - d37 * d28);
+   i8 = i2;
+   HEAPF32[i8 >> 2] = d39;
+   HEAPF32[i8 + 4 >> 2] = d28;
+   HEAP32[i2 + 16 >> 2] = HEAP32[i3 + 8 >> 2];
+   d28 = +HEAPF32[i21 >> 2];
+   i8 = 1;
+  }
+  d26 = +HEAPF32[i3 + 12 >> 2];
+  d27 = +HEAPF32[i3 + 16 >> 2];
+  if ((d26 - d23) * d22 + (d27 - d24) * d25 <= d28) {
+   d36 = d26 - +HEAPF32[i4 >> 2];
+   d33 = d27 - +HEAPF32[i6 >> 2];
+   d32 = +HEAPF32[i5 >> 2];
+   d39 = +HEAPF32[i7 >> 2];
+   d37 = +(d36 * d32 + d33 * d39);
+   d39 = +(d32 * d33 - d36 * d39);
+   i41 = i2 + (i8 * 20 | 0) | 0;
+   HEAPF32[i41 >> 2] = d37;
+   HEAPF32[i41 + 4 >> 2] = d39;
+   HEAP32[i2 + (i8 * 20 | 0) + 16 >> 2] = HEAP32[i3 + 20 >> 2];
+   i8 = i8 + 1 | 0;
+  }
+ } else {
+  i38 = HEAP32[i9 >> 2] | 0;
+  i35 = i8 + (i38 << 3) + 84 | 0;
+  i41 = HEAP32[i35 + 4 >> 2] | 0;
+  i40 = i10;
+  HEAP32[i40 >> 2] = HEAP32[i35 >> 2];
+  HEAP32[i40 + 4 >> 2] = i41;
+  i38 = i8 + (i38 << 3) + 20 | 0;
+  i40 = HEAP32[i38 + 4 >> 2] | 0;
+  i41 = i2 + 48 | 0;
+  HEAP32[i41 >> 2] = HEAP32[i38 >> 2];
+  HEAP32[i41 + 4 >> 2] = i40;
+  d22 = +HEAPF32[i17 >> 2];
+  d23 = +HEAPF32[i16 >> 2];
+  d24 = +HEAPF32[i15 >> 2];
+  d25 = +HEAPF32[i13 >> 2];
+  d26 = +HEAPF32[i21 >> 2];
+  if (!((+HEAPF32[i3 >> 2] - d22) * d23 + (+HEAPF32[i3 + 4 >> 2] - d24) * d25 <= d26)) {
+   i8 = 0;
+  } else {
+   i40 = i3;
+   i8 = HEAP32[i40 + 4 >> 2] | 0;
+   i41 = i2;
+   HEAP32[i41 >> 2] = HEAP32[i40 >> 2];
+   HEAP32[i41 + 4 >> 2] = i8;
+   i41 = i3 + 8 | 0;
+   i8 = i2 + 16 | 0;
+   HEAP8[i8 + 2 | 0] = HEAP8[i41 + 3 | 0] | 0;
+   HEAP8[i8 + 3 | 0] = HEAP8[i41 + 2 | 0] | 0;
+   HEAP8[i8] = HEAP8[i41 + 1 | 0] | 0;
+   HEAP8[i8 + 1 | 0] = HEAP8[i41] | 0;
+   d26 = +HEAPF32[i21 >> 2];
+   i8 = 1;
+  }
+  i4 = i3 + 12 | 0;
+  if ((+HEAPF32[i4 >> 2] - d22) * d23 + (+HEAPF32[i3 + 16 >> 2] - d24) * d25 <= d26) {
+   i38 = i4;
+   i41 = HEAP32[i38 + 4 >> 2] | 0;
+   i40 = i2 + (i8 * 20 | 0) | 0;
+   HEAP32[i40 >> 2] = HEAP32[i38 >> 2];
+   HEAP32[i40 + 4 >> 2] = i41;
+   i40 = i3 + 20 | 0;
+   i41 = i2 + (i8 * 20 | 0) + 16 | 0;
+   HEAP8[i41 + 2 | 0] = HEAP8[i40 + 3 | 0] | 0;
+   HEAP8[i41 + 3 | 0] = HEAP8[i40 + 2 | 0] | 0;
+   HEAP8[i41] = HEAP8[i40 + 1 | 0] | 0;
+   HEAP8[i41 + 1 | 0] = HEAP8[i40] | 0;
+   i8 = i8 + 1 | 0;
+  }
+ }
+ HEAP32[i19 >> 2] = i8;
+ STACKTOP = i1;
+ return;
+}
+function __ZN7b2World8SolveTOIERK10b2TimeStep(i30, i11) {
+ i30 = i30 | 0;
+ i11 = i11 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i31 = 0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, i36 = 0, i37 = 0, i38 = 0, i39 = 0, i40 = 0, i41 = 0, d42 = 0.0, i43 = 0, i44 = 0, i45 = 0, i46 = 0, i47 = 0, i48 = 0, i49 = 0, i50 = 0, i51 = 0, i52 = 0, i53 = 0, i54 = 0, i55 = 0, i56 = 0, i57 = 0, i58 = 0, i59 = 0, i60 = 0, i61 = 0, i62 = 0, i63 = 0, i64 = 0, i65 = 0, i66 = 0, d67 = 0.0, d68 = 0.0, d69 = 0.0, d70 = 0.0, d71 = 0.0, d72 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 336 | 0;
+ i3 = i1 + 284 | 0;
+ i6 = i1 + 152 | 0;
+ i5 = i1 + 144 | 0;
+ i4 = i1 + 108 | 0;
+ i8 = i1 + 72 | 0;
+ i7 = i1 + 64 | 0;
+ i14 = i1 + 24 | 0;
+ i9 = i1;
+ i10 = i30 + 102872 | 0;
+ i13 = i30 + 102944 | 0;
+ __ZN8b2IslandC2EiiiP16b2StackAllocatorP17b2ContactListener(i3, 64, 32, 0, i30 + 68 | 0, HEAP32[i13 >> 2] | 0);
+ i2 = i30 + 102995 | 0;
+ if ((HEAP8[i2] | 0) != 0) {
+  i15 = HEAP32[i30 + 102952 >> 2] | 0;
+  if ((i15 | 0) != 0) {
+   do {
+    i66 = i15 + 4 | 0;
+    HEAP16[i66 >> 1] = HEAP16[i66 >> 1] & 65534;
+    HEAPF32[i15 + 60 >> 2] = 0.0;
+    i15 = HEAP32[i15 + 96 >> 2] | 0;
+   } while ((i15 | 0) != 0);
+  }
+  i15 = i30 + 102932 | 0;
+  i16 = HEAP32[i15 >> 2] | 0;
+  if ((i16 | 0) != 0) {
+   do {
+    i66 = i16 + 4 | 0;
+    HEAP32[i66 >> 2] = HEAP32[i66 >> 2] & -34;
+    HEAP32[i16 + 128 >> 2] = 0;
+    HEAPF32[i16 + 132 >> 2] = 1.0;
+    i16 = HEAP32[i16 + 12 >> 2] | 0;
+   } while ((i16 | 0) != 0);
+  }
+ } else {
+  i15 = i30 + 102932 | 0;
+ }
+ i25 = i3 + 28 | 0;
+ i26 = i3 + 36 | 0;
+ i27 = i3 + 32 | 0;
+ i28 = i3 + 40 | 0;
+ i29 = i3 + 8 | 0;
+ i24 = i3 + 44 | 0;
+ i23 = i3 + 12 | 0;
+ i22 = i7 + 4 | 0;
+ i21 = i9 + 4 | 0;
+ i20 = i9 + 8 | 0;
+ i19 = i9 + 16 | 0;
+ i18 = i11 + 12 | 0;
+ i17 = i9 + 12 | 0;
+ i16 = i9 + 20 | 0;
+ i39 = i30 + 102994 | 0;
+ i37 = i6 + 16 | 0;
+ i36 = i6 + 20 | 0;
+ i35 = i6 + 24 | 0;
+ i34 = i6 + 44 | 0;
+ i33 = i6 + 48 | 0;
+ i32 = i6 + 52 | 0;
+ i41 = i6 + 28 | 0;
+ i31 = i6 + 56 | 0;
+ i40 = i6 + 92 | 0;
+ i30 = i6 + 128 | 0;
+ i38 = i5 + 4 | 0;
+ L11 : while (1) {
+  i47 = HEAP32[i15 >> 2] | 0;
+  if ((i47 | 0) == 0) {
+   i4 = 36;
+   break;
+  } else {
+   d42 = 1.0;
+   i44 = 0;
+  }
+  do {
+   i48 = i47 + 4 | 0;
+   i43 = HEAP32[i48 >> 2] | 0;
+   do {
+    if ((i43 & 4 | 0) != 0 ? (HEAP32[i47 + 128 >> 2] | 0) <= 8 : 0) {
+     if ((i43 & 32 | 0) == 0) {
+      i43 = HEAP32[i47 + 48 >> 2] | 0;
+      i45 = HEAP32[i47 + 52 >> 2] | 0;
+      if ((HEAP8[i43 + 38 | 0] | 0) != 0) {
+       break;
+      }
+      if ((HEAP8[i45 + 38 | 0] | 0) != 0) {
+       break;
+      }
+      i46 = HEAP32[i43 + 8 >> 2] | 0;
+      i50 = HEAP32[i45 + 8 >> 2] | 0;
+      i53 = HEAP32[i46 >> 2] | 0;
+      i52 = HEAP32[i50 >> 2] | 0;
+      if (!((i53 | 0) == 2 | (i52 | 0) == 2)) {
+       i4 = 16;
+       break L11;
+      }
+      i51 = HEAP16[i46 + 4 >> 1] | 0;
+      i49 = HEAP16[i50 + 4 >> 1] | 0;
+      if (!((i51 & 2) != 0 & (i53 | 0) != 0 | (i49 & 2) != 0 & (i52 | 0) != 0)) {
+       break;
+      }
+      if (!((i51 & 8) != 0 | (i53 | 0) != 2 | ((i49 & 8) != 0 | (i52 | 0) != 2))) {
+       break;
+      }
+      i51 = i46 + 28 | 0;
+      i52 = i46 + 60 | 0;
+      d68 = +HEAPF32[i52 >> 2];
+      i49 = i50 + 28 | 0;
+      i53 = i50 + 60 | 0;
+      d67 = +HEAPF32[i53 >> 2];
+      if (!(d68 < d67)) {
+       if (d67 < d68) {
+        if (!(d67 < 1.0)) {
+         i4 = 25;
+         break L11;
+        }
+        d67 = (d68 - d67) / (1.0 - d67);
+        i66 = i50 + 36 | 0;
+        d69 = 1.0 - d67;
+        d71 = +(+HEAPF32[i66 >> 2] * d69 + d67 * +HEAPF32[i50 + 44 >> 2]);
+        d70 = +(d69 * +HEAPF32[i50 + 40 >> 2] + d67 * +HEAPF32[i50 + 48 >> 2]);
+        HEAPF32[i66 >> 2] = d71;
+        HEAPF32[i66 + 4 >> 2] = d70;
+        i66 = i50 + 52 | 0;
+        HEAPF32[i66 >> 2] = d69 * +HEAPF32[i66 >> 2] + d67 * +HEAPF32[i50 + 56 >> 2];
+        HEAPF32[i53 >> 2] = d68;
+        d67 = d68;
+       } else {
+        d67 = d68;
+       }
+      } else {
+       if (!(d68 < 1.0)) {
+        i4 = 21;
+        break L11;
+       }
+       d71 = (d67 - d68) / (1.0 - d68);
+       i66 = i46 + 36 | 0;
+       d70 = 1.0 - d71;
+       d68 = +(+HEAPF32[i66 >> 2] * d70 + d71 * +HEAPF32[i46 + 44 >> 2]);
+       d69 = +(d70 * +HEAPF32[i46 + 40 >> 2] + d71 * +HEAPF32[i46 + 48 >> 2]);
+       HEAPF32[i66 >> 2] = d68;
+       HEAPF32[i66 + 4 >> 2] = d69;
+       i66 = i46 + 52 | 0;
+       HEAPF32[i66 >> 2] = d70 * +HEAPF32[i66 >> 2] + d71 * +HEAPF32[i46 + 56 >> 2];
+       HEAPF32[i52 >> 2] = d67;
+      }
+      if (!(d67 < 1.0)) {
+       i4 = 28;
+       break L11;
+      }
+      i66 = HEAP32[i47 + 56 >> 2] | 0;
+      i46 = HEAP32[i47 + 60 >> 2] | 0;
+      HEAP32[i37 >> 2] = 0;
+      HEAP32[i36 >> 2] = 0;
+      HEAPF32[i35 >> 2] = 0.0;
+      HEAP32[i34 >> 2] = 0;
+      HEAP32[i33 >> 2] = 0;
+      HEAPF32[i32 >> 2] = 0.0;
+      __ZN15b2DistanceProxy3SetEPK7b2Shapei(i6, HEAP32[i43 + 12 >> 2] | 0, i66);
+      __ZN15b2DistanceProxy3SetEPK7b2Shapei(i41, HEAP32[i45 + 12 >> 2] | 0, i46);
+      i43 = i31 + 0 | 0;
+      i45 = i51 + 0 | 0;
+      i46 = i43 + 36 | 0;
+      do {
+       HEAP32[i43 >> 2] = HEAP32[i45 >> 2];
+       i43 = i43 + 4 | 0;
+       i45 = i45 + 4 | 0;
+      } while ((i43 | 0) < (i46 | 0));
+      i43 = i40 + 0 | 0;
+      i45 = i49 + 0 | 0;
+      i46 = i43 + 36 | 0;
+      do {
+       HEAP32[i43 >> 2] = HEAP32[i45 >> 2];
+       i43 = i43 + 4 | 0;
+       i45 = i45 + 4 | 0;
+      } while ((i43 | 0) < (i46 | 0));
+      HEAPF32[i30 >> 2] = 1.0;
+      __Z14b2TimeOfImpactP11b2TOIOutputPK10b2TOIInput(i5, i6);
+      if ((HEAP32[i5 >> 2] | 0) == 3) {
+       d67 = d67 + (1.0 - d67) * +HEAPF32[i38 >> 2];
+       d67 = d67 < 1.0 ? d67 : 1.0;
+      } else {
+       d67 = 1.0;
+      }
+      HEAPF32[i47 + 132 >> 2] = d67;
+      HEAP32[i48 >> 2] = HEAP32[i48 >> 2] | 32;
+     } else {
+      d67 = +HEAPF32[i47 + 132 >> 2];
+     }
+     if (d67 < d42) {
+      d42 = d67;
+      i44 = i47;
+     }
+    }
+   } while (0);
+   i47 = HEAP32[i47 + 12 >> 2] | 0;
+  } while ((i47 | 0) != 0);
+  if ((i44 | 0) == 0 | d42 > .9999988079071045) {
+   i4 = 36;
+   break;
+  }
+  i47 = HEAP32[(HEAP32[i44 + 48 >> 2] | 0) + 8 >> 2] | 0;
+  i48 = HEAP32[(HEAP32[i44 + 52 >> 2] | 0) + 8 >> 2] | 0;
+  i49 = i47 + 28 | 0;
+  i43 = i4 + 0 | 0;
+  i45 = i49 + 0 | 0;
+  i46 = i43 + 36 | 0;
+  do {
+   HEAP32[i43 >> 2] = HEAP32[i45 >> 2];
+   i43 = i43 + 4 | 0;
+   i45 = i45 + 4 | 0;
+  } while ((i43 | 0) < (i46 | 0));
+  i50 = i48 + 28 | 0;
+  i43 = i8 + 0 | 0;
+  i45 = i50 + 0 | 0;
+  i46 = i43 + 36 | 0;
+  do {
+   HEAP32[i43 >> 2] = HEAP32[i45 >> 2];
+   i43 = i43 + 4 | 0;
+   i45 = i45 + 4 | 0;
+  } while ((i43 | 0) < (i46 | 0));
+  i43 = i47 + 60 | 0;
+  d67 = +HEAPF32[i43 >> 2];
+  if (!(d67 < 1.0)) {
+   i4 = 38;
+   break;
+  }
+  d70 = (d42 - d67) / (1.0 - d67);
+  i57 = i47 + 36 | 0;
+  d67 = 1.0 - d70;
+  i52 = i47 + 44 | 0;
+  i53 = i47 + 48 | 0;
+  d71 = +HEAPF32[i57 >> 2] * d67 + d70 * +HEAPF32[i52 >> 2];
+  d72 = d67 * +HEAPF32[i47 + 40 >> 2] + d70 * +HEAPF32[i53 >> 2];
+  d69 = +d71;
+  d68 = +d72;
+  HEAPF32[i57 >> 2] = d69;
+  HEAPF32[i57 + 4 >> 2] = d68;
+  i57 = i47 + 52 | 0;
+  i51 = i47 + 56 | 0;
+  d70 = d67 * +HEAPF32[i57 >> 2] + d70 * +HEAPF32[i51 >> 2];
+  HEAPF32[i57 >> 2] = d70;
+  HEAPF32[i43 >> 2] = d42;
+  i57 = i47 + 44 | 0;
+  HEAPF32[i57 >> 2] = d69;
+  HEAPF32[i57 + 4 >> 2] = d68;
+  HEAPF32[i51 >> 2] = d70;
+  d68 = +Math_sin(+d70);
+  i57 = i47 + 20 | 0;
+  HEAPF32[i57 >> 2] = d68;
+  d70 = +Math_cos(+d70);
+  i56 = i47 + 24 | 0;
+  HEAPF32[i56 >> 2] = d70;
+  i58 = i47 + 12 | 0;
+  i55 = i47 + 28 | 0;
+  d69 = +HEAPF32[i55 >> 2];
+  i54 = i47 + 32 | 0;
+  d67 = +HEAPF32[i54 >> 2];
+  d71 = +(d71 - (d70 * d69 - d68 * d67));
+  d67 = +(d72 - (d68 * d69 + d70 * d67));
+  i43 = i58;
+  HEAPF32[i43 >> 2] = d71;
+  HEAPF32[i43 + 4 >> 2] = d67;
+  i43 = i48 + 60 | 0;
+  d67 = +HEAPF32[i43 >> 2];
+  if (!(d67 < 1.0)) {
+   i4 = 40;
+   break;
+  }
+  d70 = (d42 - d67) / (1.0 - d67);
+  i64 = i48 + 36 | 0;
+  d72 = 1.0 - d70;
+  i61 = i48 + 44 | 0;
+  i60 = i48 + 48 | 0;
+  d71 = +HEAPF32[i64 >> 2] * d72 + d70 * +HEAPF32[i61 >> 2];
+  d67 = d72 * +HEAPF32[i48 + 40 >> 2] + d70 * +HEAPF32[i60 >> 2];
+  d69 = +d71;
+  d68 = +d67;
+  HEAPF32[i64 >> 2] = d69;
+  HEAPF32[i64 + 4 >> 2] = d68;
+  i64 = i48 + 52 | 0;
+  i59 = i48 + 56 | 0;
+  d70 = d72 * +HEAPF32[i64 >> 2] + d70 * +HEAPF32[i59 >> 2];
+  HEAPF32[i64 >> 2] = d70;
+  HEAPF32[i43 >> 2] = d42;
+  i64 = i48 + 44 | 0;
+  HEAPF32[i64 >> 2] = d69;
+  HEAPF32[i64 + 4 >> 2] = d68;
+  HEAPF32[i59 >> 2] = d70;
+  d68 = +Math_sin(+d70);
+  i64 = i48 + 20 | 0;
+  HEAPF32[i64 >> 2] = d68;
+  d70 = +Math_cos(+d70);
+  i63 = i48 + 24 | 0;
+  HEAPF32[i63 >> 2] = d70;
+  i65 = i48 + 12 | 0;
+  i62 = i48 + 28 | 0;
+  d69 = +HEAPF32[i62 >> 2];
+  i66 = i48 + 32 | 0;
+  d72 = +HEAPF32[i66 >> 2];
+  d71 = +(d71 - (d70 * d69 - d68 * d72));
+  d72 = +(d67 - (d68 * d69 + d70 * d72));
+  i43 = i65;
+  HEAPF32[i43 >> 2] = d71;
+  HEAPF32[i43 + 4 >> 2] = d72;
+  __ZN9b2Contact6UpdateEP17b2ContactListener(i44, HEAP32[i13 >> 2] | 0);
+  i43 = i44 + 4 | 0;
+  i45 = HEAP32[i43 >> 2] | 0;
+  HEAP32[i43 >> 2] = i45 & -33;
+  i46 = i44 + 128 | 0;
+  HEAP32[i46 >> 2] = (HEAP32[i46 >> 2] | 0) + 1;
+  if ((i45 & 6 | 0) != 6) {
+   HEAP32[i43 >> 2] = i45 & -37;
+   i43 = i49 + 0 | 0;
+   i45 = i4 + 0 | 0;
+   i46 = i43 + 36 | 0;
+   do {
+    HEAP32[i43 >> 2] = HEAP32[i45 >> 2];
+    i43 = i43 + 4 | 0;
+    i45 = i45 + 4 | 0;
+   } while ((i43 | 0) < (i46 | 0));
+   i43 = i50 + 0 | 0;
+   i45 = i8 + 0 | 0;
+   i46 = i43 + 36 | 0;
+   do {
+    HEAP32[i43 >> 2] = HEAP32[i45 >> 2];
+    i43 = i43 + 4 | 0;
+    i45 = i45 + 4 | 0;
+   } while ((i43 | 0) < (i46 | 0));
+   d69 = +HEAPF32[i51 >> 2];
+   d71 = +Math_sin(+d69);
+   HEAPF32[i57 >> 2] = d71;
+   d69 = +Math_cos(+d69);
+   HEAPF32[i56 >> 2] = d69;
+   d72 = +HEAPF32[i55 >> 2];
+   d70 = +HEAPF32[i54 >> 2];
+   d68 = +(+HEAPF32[i52 >> 2] - (d69 * d72 - d71 * d70));
+   d70 = +(+HEAPF32[i53 >> 2] - (d71 * d72 + d69 * d70));
+   HEAPF32[i58 >> 2] = d68;
+   HEAPF32[i58 + 4 >> 2] = d70;
+   d70 = +HEAPF32[i59 >> 2];
+   d68 = +Math_sin(+d70);
+   HEAPF32[i64 >> 2] = d68;
+   d70 = +Math_cos(+d70);
+   HEAPF32[i63 >> 2] = d70;
+   d69 = +HEAPF32[i62 >> 2];
+   d72 = +HEAPF32[i66 >> 2];
+   d71 = +(+HEAPF32[i61 >> 2] - (d70 * d69 - d68 * d72));
+   d72 = +(+HEAPF32[i60 >> 2] - (d68 * d69 + d70 * d72));
+   i66 = i65;
+   HEAPF32[i66 >> 2] = d71;
+   HEAPF32[i66 + 4 >> 2] = d72;
+   continue;
+  }
+  i45 = i47 + 4 | 0;
+  i46 = HEAPU16[i45 >> 1] | 0;
+  if ((i46 & 2 | 0) == 0) {
+   HEAP16[i45 >> 1] = i46 | 2;
+   HEAPF32[i47 + 144 >> 2] = 0.0;
+  }
+  i46 = i48 + 4 | 0;
+  i49 = HEAPU16[i46 >> 1] | 0;
+  if ((i49 & 2 | 0) == 0) {
+   HEAP16[i46 >> 1] = i49 | 2;
+   HEAPF32[i48 + 144 >> 2] = 0.0;
+  }
+  HEAP32[i25 >> 2] = 0;
+  HEAP32[i26 >> 2] = 0;
+  HEAP32[i27 >> 2] = 0;
+  if ((HEAP32[i28 >> 2] | 0) <= 0) {
+   i4 = 48;
+   break;
+  }
+  i49 = i47 + 8 | 0;
+  HEAP32[i49 >> 2] = 0;
+  i51 = HEAP32[i25 >> 2] | 0;
+  HEAP32[(HEAP32[i29 >> 2] | 0) + (i51 << 2) >> 2] = i47;
+  i51 = i51 + 1 | 0;
+  HEAP32[i25 >> 2] = i51;
+  if ((i51 | 0) >= (HEAP32[i28 >> 2] | 0)) {
+   i4 = 50;
+   break;
+  }
+  i50 = i48 + 8 | 0;
+  HEAP32[i50 >> 2] = i51;
+  i51 = HEAP32[i25 >> 2] | 0;
+  HEAP32[(HEAP32[i29 >> 2] | 0) + (i51 << 2) >> 2] = i48;
+  HEAP32[i25 >> 2] = i51 + 1;
+  i51 = HEAP32[i26 >> 2] | 0;
+  if ((i51 | 0) >= (HEAP32[i24 >> 2] | 0)) {
+   i4 = 52;
+   break;
+  }
+  HEAP32[i26 >> 2] = i51 + 1;
+  HEAP32[(HEAP32[i23 >> 2] | 0) + (i51 << 2) >> 2] = i44;
+  HEAP16[i45 >> 1] = HEAPU16[i45 >> 1] | 1;
+  HEAP16[i46 >> 1] = HEAPU16[i46 >> 1] | 1;
+  HEAP32[i43 >> 2] = HEAP32[i43 >> 2] | 1;
+  HEAP32[i7 >> 2] = i47;
+  HEAP32[i22 >> 2] = i48;
+  i44 = 1;
+  while (1) {
+   L58 : do {
+    if ((HEAP32[i47 >> 2] | 0) == 2 ? (i12 = HEAP32[i47 + 112 >> 2] | 0, (i12 | 0) != 0) : 0) {
+     i47 = i47 + 4 | 0;
+     i51 = i12;
+     do {
+      if ((HEAP32[i25 >> 2] | 0) == (HEAP32[i28 >> 2] | 0)) {
+       break L58;
+      }
+      if ((HEAP32[i26 >> 2] | 0) == (HEAP32[i24 >> 2] | 0)) {
+       break L58;
+      }
+      i52 = HEAP32[i51 + 4 >> 2] | 0;
+      i53 = i52 + 4 | 0;
+      do {
+       if ((HEAP32[i53 >> 2] & 1 | 0) == 0) {
+        i48 = HEAP32[i51 >> 2] | 0;
+        if (((HEAP32[i48 >> 2] | 0) == 2 ? (HEAP16[i47 >> 1] & 8) == 0 : 0) ? (HEAP16[i48 + 4 >> 1] & 8) == 0 : 0) {
+         break;
+        }
+        if ((HEAP8[(HEAP32[i52 + 48 >> 2] | 0) + 38 | 0] | 0) == 0 ? (HEAP8[(HEAP32[i52 + 52 >> 2] | 0) + 38 | 0] | 0) == 0 : 0) {
+         i54 = i48 + 28 | 0;
+         i43 = i14 + 0 | 0;
+         i45 = i54 + 0 | 0;
+         i46 = i43 + 36 | 0;
+         do {
+          HEAP32[i43 >> 2] = HEAP32[i45 >> 2];
+          i43 = i43 + 4 | 0;
+          i45 = i45 + 4 | 0;
+         } while ((i43 | 0) < (i46 | 0));
+         i43 = i48 + 4 | 0;
+         if ((HEAP16[i43 >> 1] & 1) == 0) {
+          i45 = i48 + 60 | 0;
+          d67 = +HEAPF32[i45 >> 2];
+          if (!(d67 < 1.0)) {
+           i4 = 67;
+           break L11;
+          }
+          d70 = (d42 - d67) / (1.0 - d67);
+          i65 = i48 + 36 | 0;
+          d72 = 1.0 - d70;
+          d71 = +HEAPF32[i65 >> 2] * d72 + d70 * +HEAPF32[i48 + 44 >> 2];
+          d67 = d72 * +HEAPF32[i48 + 40 >> 2] + d70 * +HEAPF32[i48 + 48 >> 2];
+          d69 = +d71;
+          d68 = +d67;
+          HEAPF32[i65 >> 2] = d69;
+          HEAPF32[i65 + 4 >> 2] = d68;
+          i65 = i48 + 52 | 0;
+          i66 = i48 + 56 | 0;
+          d70 = d72 * +HEAPF32[i65 >> 2] + d70 * +HEAPF32[i66 >> 2];
+          HEAPF32[i65 >> 2] = d70;
+          HEAPF32[i45 >> 2] = d42;
+          i65 = i48 + 44 | 0;
+          HEAPF32[i65 >> 2] = d69;
+          HEAPF32[i65 + 4 >> 2] = d68;
+          HEAPF32[i66 >> 2] = d70;
+          d68 = +Math_sin(+d70);
+          HEAPF32[i48 + 20 >> 2] = d68;
+          d70 = +Math_cos(+d70);
+          HEAPF32[i48 + 24 >> 2] = d70;
+          d69 = +HEAPF32[i48 + 28 >> 2];
+          d72 = +HEAPF32[i48 + 32 >> 2];
+          d71 = +(d71 - (d70 * d69 - d68 * d72));
+          d72 = +(d67 - (d68 * d69 + d70 * d72));
+          i66 = i48 + 12 | 0;
+          HEAPF32[i66 >> 2] = d71;
+          HEAPF32[i66 + 4 >> 2] = d72;
+         }
+         __ZN9b2Contact6UpdateEP17b2ContactListener(i52, HEAP32[i13 >> 2] | 0);
+         i45 = HEAP32[i53 >> 2] | 0;
+         if ((i45 & 4 | 0) == 0) {
+          i43 = i54 + 0 | 0;
+          i45 = i14 + 0 | 0;
+          i46 = i43 + 36 | 0;
+          do {
+           HEAP32[i43 >> 2] = HEAP32[i45 >> 2];
+           i43 = i43 + 4 | 0;
+           i45 = i45 + 4 | 0;
+          } while ((i43 | 0) < (i46 | 0));
+          d70 = +HEAPF32[i48 + 56 >> 2];
+          d68 = +Math_sin(+d70);
+          HEAPF32[i48 + 20 >> 2] = d68;
+          d70 = +Math_cos(+d70);
+          HEAPF32[i48 + 24 >> 2] = d70;
+          d69 = +HEAPF32[i48 + 28 >> 2];
+          d72 = +HEAPF32[i48 + 32 >> 2];
+          d71 = +(+HEAPF32[i48 + 44 >> 2] - (d70 * d69 - d68 * d72));
+          d72 = +(+HEAPF32[i48 + 48 >> 2] - (d68 * d69 + d70 * d72));
+          i66 = i48 + 12 | 0;
+          HEAPF32[i66 >> 2] = d71;
+          HEAPF32[i66 + 4 >> 2] = d72;
+          break;
+         }
+         if ((i45 & 2 | 0) == 0) {
+          i43 = i54 + 0 | 0;
+          i45 = i14 + 0 | 0;
+          i46 = i43 + 36 | 0;
+          do {
+           HEAP32[i43 >> 2] = HEAP32[i45 >> 2];
+           i43 = i43 + 4 | 0;
+           i45 = i45 + 4 | 0;
+          } while ((i43 | 0) < (i46 | 0));
+          d70 = +HEAPF32[i48 + 56 >> 2];
+          d68 = +Math_sin(+d70);
+          HEAPF32[i48 + 20 >> 2] = d68;
+          d70 = +Math_cos(+d70);
+          HEAPF32[i48 + 24 >> 2] = d70;
+          d69 = +HEAPF32[i48 + 28 >> 2];
+          d72 = +HEAPF32[i48 + 32 >> 2];
+          d71 = +(+HEAPF32[i48 + 44 >> 2] - (d70 * d69 - d68 * d72));
+          d72 = +(+HEAPF32[i48 + 48 >> 2] - (d68 * d69 + d70 * d72));
+          i66 = i48 + 12 | 0;
+          HEAPF32[i66 >> 2] = d71;
+          HEAPF32[i66 + 4 >> 2] = d72;
+          break;
+         }
+         HEAP32[i53 >> 2] = i45 | 1;
+         i45 = HEAP32[i26 >> 2] | 0;
+         if ((i45 | 0) >= (HEAP32[i24 >> 2] | 0)) {
+          i4 = 74;
+          break L11;
+         }
+         HEAP32[i26 >> 2] = i45 + 1;
+         HEAP32[(HEAP32[i23 >> 2] | 0) + (i45 << 2) >> 2] = i52;
+         i45 = HEAPU16[i43 >> 1] | 0;
+         if ((i45 & 1 | 0) == 0) {
+          HEAP16[i43 >> 1] = i45 | 1;
+          if ((HEAP32[i48 >> 2] | 0) != 0 ? (i45 & 2 | 0) == 0 : 0) {
+           HEAP16[i43 >> 1] = i45 | 3;
+           HEAPF32[i48 + 144 >> 2] = 0.0;
+          }
+          i43 = HEAP32[i25 >> 2] | 0;
+          if ((i43 | 0) >= (HEAP32[i28 >> 2] | 0)) {
+           i4 = 80;
+           break L11;
+          }
+          HEAP32[i48 + 8 >> 2] = i43;
+          i66 = HEAP32[i25 >> 2] | 0;
+          HEAP32[(HEAP32[i29 >> 2] | 0) + (i66 << 2) >> 2] = i48;
+          HEAP32[i25 >> 2] = i66 + 1;
+         }
+        }
+       }
+      } while (0);
+      i51 = HEAP32[i51 + 12 >> 2] | 0;
+     } while ((i51 | 0) != 0);
+    }
+   } while (0);
+   if ((i44 | 0) >= 2) {
+    break;
+   }
+   i47 = HEAP32[i7 + (i44 << 2) >> 2] | 0;
+   i44 = i44 + 1 | 0;
+  }
+  d72 = (1.0 - d42) * +HEAPF32[i11 >> 2];
+  HEAPF32[i9 >> 2] = d72;
+  HEAPF32[i21 >> 2] = 1.0 / d72;
+  HEAPF32[i20 >> 2] = 1.0;
+  HEAP32[i19 >> 2] = 20;
+  HEAP32[i17 >> 2] = HEAP32[i18 >> 2];
+  HEAP8[i16] = 0;
+  __ZN8b2Island8SolveTOIERK10b2TimeStepii(i3, i9, HEAP32[i49 >> 2] | 0, HEAP32[i50 >> 2] | 0);
+  i44 = HEAP32[i25 >> 2] | 0;
+  if ((i44 | 0) > 0) {
+   i43 = 0;
+   do {
+    i45 = HEAP32[(HEAP32[i29 >> 2] | 0) + (i43 << 2) >> 2] | 0;
+    i66 = i45 + 4 | 0;
+    HEAP16[i66 >> 1] = HEAP16[i66 >> 1] & 65534;
+    if ((HEAP32[i45 >> 2] | 0) == 2) {
+     __ZN6b2Body19SynchronizeFixturesEv(i45);
+     i44 = HEAP32[i45 + 112 >> 2] | 0;
+     if ((i44 | 0) != 0) {
+      do {
+       i66 = (HEAP32[i44 + 4 >> 2] | 0) + 4 | 0;
+       HEAP32[i66 >> 2] = HEAP32[i66 >> 2] & -34;
+       i44 = HEAP32[i44 + 12 >> 2] | 0;
+      } while ((i44 | 0) != 0);
+     }
+     i44 = HEAP32[i25 >> 2] | 0;
+    }
+    i43 = i43 + 1 | 0;
+   } while ((i43 | 0) < (i44 | 0));
+  }
+  __ZN16b2ContactManager15FindNewContactsEv(i10);
+  if ((HEAP8[i39] | 0) != 0) {
+   i4 = 92;
+   break;
+  }
+ }
+ if ((i4 | 0) == 16) {
+  ___assert_fail(2288, 2184, 641, 2344);
+ } else if ((i4 | 0) == 21) {
+  ___assert_fail(2360, 2376, 723, 2400);
+ } else if ((i4 | 0) == 25) {
+  ___assert_fail(2360, 2376, 723, 2400);
+ } else if ((i4 | 0) == 28) {
+  ___assert_fail(2360, 2184, 676, 2344);
+ } else if ((i4 | 0) == 36) {
+  HEAP8[i2] = 1;
+  __ZN8b2IslandD2Ev(i3);
+  STACKTOP = i1;
+  return;
+ } else if ((i4 | 0) == 38) {
+  ___assert_fail(2360, 2376, 723, 2400);
+ } else if ((i4 | 0) == 40) {
+  ___assert_fail(2360, 2376, 723, 2400);
+ } else if ((i4 | 0) == 48) {
+  ___assert_fail(2520, 2440, 54, 2472);
+ } else if ((i4 | 0) == 50) {
+  ___assert_fail(2520, 2440, 54, 2472);
+ } else if ((i4 | 0) == 52) {
+  ___assert_fail(2480, 2440, 62, 2472);
+ } else if ((i4 | 0) == 67) {
+  ___assert_fail(2360, 2376, 723, 2400);
+ } else if ((i4 | 0) == 74) {
+  ___assert_fail(2480, 2440, 62, 2472);
+ } else if ((i4 | 0) == 80) {
+  ___assert_fail(2520, 2440, 54, 2472);
+ } else if ((i4 | 0) == 92) {
+  HEAP8[i2] = 0;
+  __ZN8b2IslandD2Ev(i3);
+  STACKTOP = i1;
+  return;
+ }
+}
+function __ZNSt3__16__sortIRPFbRK6b2PairS3_EPS1_EEvT0_S8_T_(i5, i8, i1) {
+ i5 = i5 | 0;
+ i8 = i8 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i3;
+ L1 : while (1) {
+  i7 = i8;
+  i4 = i8 + -12 | 0;
+  L3 : while (1) {
+   i9 = i5;
+   i11 = i7 - i9 | 0;
+   switch ((i11 | 0) / 12 | 0 | 0) {
+   case 4:
+    {
+     i6 = 14;
+     break L1;
+    }
+   case 2:
+    {
+     i6 = 4;
+     break L1;
+    }
+   case 3:
+    {
+     i6 = 6;
+     break L1;
+    }
+   case 5:
+    {
+     i6 = 15;
+     break L1;
+    }
+   case 1:
+   case 0:
+    {
+     i6 = 67;
+     break L1;
+    }
+   default:
+    {}
+   }
+   if ((i11 | 0) < 372) {
+    i6 = 21;
+    break L1;
+   }
+   i12 = (i11 | 0) / 24 | 0;
+   i10 = i5 + (i12 * 12 | 0) | 0;
+   do {
+    if ((i11 | 0) > 11988) {
+     i14 = (i11 | 0) / 48 | 0;
+     i11 = i5 + (i14 * 12 | 0) | 0;
+     i14 = i5 + ((i14 + i12 | 0) * 12 | 0) | 0;
+     i12 = __ZNSt3__17__sort4IRPFbRK6b2PairS3_EPS1_EEjT0_S8_S8_S8_T_(i5, i11, i10, i14, i1) | 0;
+     if (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i4, i14) | 0) {
+      HEAP32[i2 + 0 >> 2] = HEAP32[i14 + 0 >> 2];
+      HEAP32[i2 + 4 >> 2] = HEAP32[i14 + 4 >> 2];
+      HEAP32[i2 + 8 >> 2] = HEAP32[i14 + 8 >> 2];
+      HEAP32[i14 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+      HEAP32[i14 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+      HEAP32[i14 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+      HEAP32[i4 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+      HEAP32[i4 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+      HEAP32[i4 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+      i13 = i12 + 1 | 0;
+      if (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i14, i10) | 0) {
+       HEAP32[i2 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+       HEAP32[i2 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+       HEAP32[i2 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+       HEAP32[i10 + 0 >> 2] = HEAP32[i14 + 0 >> 2];
+       HEAP32[i10 + 4 >> 2] = HEAP32[i14 + 4 >> 2];
+       HEAP32[i10 + 8 >> 2] = HEAP32[i14 + 8 >> 2];
+       HEAP32[i14 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+       HEAP32[i14 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+       HEAP32[i14 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+       i13 = i12 + 2 | 0;
+       if (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i10, i11) | 0) {
+        HEAP32[i2 + 0 >> 2] = HEAP32[i11 + 0 >> 2];
+        HEAP32[i2 + 4 >> 2] = HEAP32[i11 + 4 >> 2];
+        HEAP32[i2 + 8 >> 2] = HEAP32[i11 + 8 >> 2];
+        HEAP32[i11 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+        HEAP32[i11 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+        HEAP32[i11 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+        HEAP32[i10 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+        HEAP32[i10 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+        HEAP32[i10 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+        if (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i11, i5) | 0) {
+         HEAP32[i2 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+         HEAP32[i2 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+         HEAP32[i2 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+         HEAP32[i5 + 0 >> 2] = HEAP32[i11 + 0 >> 2];
+         HEAP32[i5 + 4 >> 2] = HEAP32[i11 + 4 >> 2];
+         HEAP32[i5 + 8 >> 2] = HEAP32[i11 + 8 >> 2];
+         HEAP32[i11 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+         HEAP32[i11 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+         HEAP32[i11 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+         i12 = i12 + 4 | 0;
+        } else {
+         i12 = i12 + 3 | 0;
+        }
+       } else {
+        i12 = i13;
+       }
+      } else {
+       i12 = i13;
+      }
+     }
+    } else {
+     i15 = FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i10, i5) | 0;
+     i11 = FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i4, i10) | 0;
+     if (!i15) {
+      if (!i11) {
+       i12 = 0;
+       break;
+      }
+      HEAP32[i2 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+      HEAP32[i2 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+      HEAP32[i2 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+      HEAP32[i10 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+      HEAP32[i10 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+      HEAP32[i10 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+      HEAP32[i4 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+      HEAP32[i4 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+      HEAP32[i4 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+      if (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i10, i5) | 0)) {
+       i12 = 1;
+       break;
+      }
+      HEAP32[i2 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+      HEAP32[i2 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+      HEAP32[i2 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+      HEAP32[i5 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+      HEAP32[i5 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+      HEAP32[i5 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+      HEAP32[i10 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+      HEAP32[i10 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+      HEAP32[i10 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+      i12 = 2;
+      break;
+     }
+     if (i11) {
+      HEAP32[i2 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+      HEAP32[i2 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+      HEAP32[i2 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+      HEAP32[i5 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+      HEAP32[i5 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+      HEAP32[i5 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+      HEAP32[i4 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+      HEAP32[i4 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+      HEAP32[i4 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+      i12 = 1;
+      break;
+     }
+     HEAP32[i2 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+     HEAP32[i2 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+     HEAP32[i2 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+     HEAP32[i5 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+     HEAP32[i5 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+     HEAP32[i5 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+     HEAP32[i10 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+     HEAP32[i10 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+     HEAP32[i10 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+     if (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i4, i10) | 0) {
+      HEAP32[i2 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+      HEAP32[i2 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+      HEAP32[i2 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+      HEAP32[i10 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+      HEAP32[i10 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+      HEAP32[i10 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+      HEAP32[i4 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+      HEAP32[i4 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+      HEAP32[i4 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+      i12 = 2;
+     } else {
+      i12 = 1;
+     }
+    }
+   } while (0);
+   do {
+    if (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i5, i10) | 0) {
+     i13 = i4;
+    } else {
+     i13 = i4;
+     while (1) {
+      i13 = i13 + -12 | 0;
+      if ((i5 | 0) == (i13 | 0)) {
+       break;
+      }
+      if (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i13, i10) | 0) {
+       i6 = 50;
+       break;
+      }
+     }
+     if ((i6 | 0) == 50) {
+      i6 = 0;
+      HEAP32[i2 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+      HEAP32[i2 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+      HEAP32[i2 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+      HEAP32[i5 + 0 >> 2] = HEAP32[i13 + 0 >> 2];
+      HEAP32[i5 + 4 >> 2] = HEAP32[i13 + 4 >> 2];
+      HEAP32[i5 + 8 >> 2] = HEAP32[i13 + 8 >> 2];
+      HEAP32[i13 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+      HEAP32[i13 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+      HEAP32[i13 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+      i12 = i12 + 1 | 0;
+      break;
+     }
+     i10 = i5 + 12 | 0;
+     if (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i5, i4) | 0)) {
+      if ((i10 | 0) == (i4 | 0)) {
+       i6 = 67;
+       break L1;
+      }
+      while (1) {
+       i9 = i10 + 12 | 0;
+       if (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i5, i10) | 0) {
+        break;
+       }
+       if ((i9 | 0) == (i4 | 0)) {
+        i6 = 67;
+        break L1;
+       } else {
+        i10 = i9;
+       }
+      }
+      HEAP32[i2 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+      HEAP32[i2 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+      HEAP32[i2 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+      HEAP32[i10 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+      HEAP32[i10 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+      HEAP32[i10 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+      HEAP32[i4 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+      HEAP32[i4 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+      HEAP32[i4 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+      i10 = i9;
+     }
+     if ((i10 | 0) == (i4 | 0)) {
+      i6 = 67;
+      break L1;
+     } else {
+      i9 = i4;
+     }
+     while (1) {
+      while (1) {
+       i11 = i10 + 12 | 0;
+       if (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i5, i10) | 0) {
+        break;
+       } else {
+        i10 = i11;
+       }
+      }
+      do {
+       i9 = i9 + -12 | 0;
+      } while (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i5, i9) | 0);
+      if (!(i10 >>> 0 < i9 >>> 0)) {
+       i5 = i10;
+       continue L3;
+      }
+      HEAP32[i2 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+      HEAP32[i2 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+      HEAP32[i2 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+      HEAP32[i10 + 0 >> 2] = HEAP32[i9 + 0 >> 2];
+      HEAP32[i10 + 4 >> 2] = HEAP32[i9 + 4 >> 2];
+      HEAP32[i10 + 8 >> 2] = HEAP32[i9 + 8 >> 2];
+      HEAP32[i9 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+      HEAP32[i9 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+      HEAP32[i9 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+      i10 = i11;
+     }
+    }
+   } while (0);
+   i11 = i5 + 12 | 0;
+   L47 : do {
+    if (i11 >>> 0 < i13 >>> 0) {
+     while (1) {
+      i15 = i11;
+      while (1) {
+       i11 = i15 + 12 | 0;
+       if (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i15, i10) | 0) {
+        i15 = i11;
+       } else {
+        i14 = i13;
+        break;
+       }
+      }
+      do {
+       i14 = i14 + -12 | 0;
+      } while (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i14, i10) | 0));
+      if (i15 >>> 0 > i14 >>> 0) {
+       i11 = i15;
+       break L47;
+      }
+      HEAP32[i2 + 0 >> 2] = HEAP32[i15 + 0 >> 2];
+      HEAP32[i2 + 4 >> 2] = HEAP32[i15 + 4 >> 2];
+      HEAP32[i2 + 8 >> 2] = HEAP32[i15 + 8 >> 2];
+      HEAP32[i15 + 0 >> 2] = HEAP32[i14 + 0 >> 2];
+      HEAP32[i15 + 4 >> 2] = HEAP32[i14 + 4 >> 2];
+      HEAP32[i15 + 8 >> 2] = HEAP32[i14 + 8 >> 2];
+      HEAP32[i14 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+      HEAP32[i14 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+      HEAP32[i14 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+      i13 = i14;
+      i10 = (i10 | 0) == (i15 | 0) ? i14 : i10;
+      i12 = i12 + 1 | 0;
+     }
+    }
+   } while (0);
+   if ((i11 | 0) != (i10 | 0) ? FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i10, i11) | 0 : 0) {
+    HEAP32[i2 + 0 >> 2] = HEAP32[i11 + 0 >> 2];
+    HEAP32[i2 + 4 >> 2] = HEAP32[i11 + 4 >> 2];
+    HEAP32[i2 + 8 >> 2] = HEAP32[i11 + 8 >> 2];
+    HEAP32[i11 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+    HEAP32[i11 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+    HEAP32[i11 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+    HEAP32[i10 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+    HEAP32[i10 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+    HEAP32[i10 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+    i12 = i12 + 1 | 0;
+   }
+   if ((i12 | 0) == 0) {
+    i12 = __ZNSt3__127__insertion_sort_incompleteIRPFbRK6b2PairS3_EPS1_EEbT0_S8_T_(i5, i11, i1) | 0;
+    i10 = i11 + 12 | 0;
+    if (__ZNSt3__127__insertion_sort_incompleteIRPFbRK6b2PairS3_EPS1_EEbT0_S8_T_(i10, i8, i1) | 0) {
+     i6 = 62;
+     break;
+    }
+    if (i12) {
+     i5 = i10;
+     continue;
+    }
+   }
+   i15 = i11;
+   if ((i15 - i9 | 0) >= (i7 - i15 | 0)) {
+    i6 = 66;
+    break;
+   }
+   __ZNSt3__16__sortIRPFbRK6b2PairS3_EPS1_EEvT0_S8_T_(i5, i11, i1);
+   i5 = i11 + 12 | 0;
+  }
+  if ((i6 | 0) == 62) {
+   i6 = 0;
+   if (i12) {
+    i6 = 67;
+    break;
+   } else {
+    i8 = i11;
+    continue;
+   }
+  } else if ((i6 | 0) == 66) {
+   i6 = 0;
+   __ZNSt3__16__sortIRPFbRK6b2PairS3_EPS1_EEvT0_S8_T_(i11 + 12 | 0, i8, i1);
+   i8 = i11;
+   continue;
+  }
+ }
+ if ((i6 | 0) == 4) {
+  if (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i4, i5) | 0)) {
+   STACKTOP = i3;
+   return;
+  }
+  HEAP32[i2 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+  HEAP32[i2 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+  HEAP32[i2 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+  HEAP32[i5 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+  HEAP32[i5 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+  HEAP32[i5 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+  HEAP32[i4 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+  HEAP32[i4 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+  HEAP32[i4 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+  STACKTOP = i3;
+  return;
+ } else if ((i6 | 0) == 6) {
+  i6 = i5 + 12 | 0;
+  i15 = FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i6, i5) | 0;
+  i7 = FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i4, i6) | 0;
+  if (!i15) {
+   if (!i7) {
+    STACKTOP = i3;
+    return;
+   }
+   HEAP32[i2 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+   HEAP32[i2 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+   HEAP32[i2 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+   HEAP32[i6 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+   HEAP32[i6 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+   HEAP32[i6 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+   HEAP32[i4 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+   HEAP32[i4 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+   HEAP32[i4 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+   if (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i6, i5) | 0)) {
+    STACKTOP = i3;
+    return;
+   }
+   HEAP32[i2 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+   HEAP32[i2 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+   HEAP32[i2 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+   HEAP32[i5 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+   HEAP32[i5 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+   HEAP32[i5 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+   HEAP32[i6 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+   HEAP32[i6 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+   HEAP32[i6 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+   STACKTOP = i3;
+   return;
+  }
+  if (i7) {
+   HEAP32[i2 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+   HEAP32[i2 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+   HEAP32[i2 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+   HEAP32[i5 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+   HEAP32[i5 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+   HEAP32[i5 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+   HEAP32[i4 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+   HEAP32[i4 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+   HEAP32[i4 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+   STACKTOP = i3;
+   return;
+  }
+  HEAP32[i2 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+  HEAP32[i2 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+  HEAP32[i2 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+  HEAP32[i5 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+  HEAP32[i5 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+  HEAP32[i5 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+  HEAP32[i6 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+  HEAP32[i6 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+  HEAP32[i6 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+  if (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i4, i6) | 0)) {
+   STACKTOP = i3;
+   return;
+  }
+  HEAP32[i2 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+  HEAP32[i2 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+  HEAP32[i2 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+  HEAP32[i6 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+  HEAP32[i6 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+  HEAP32[i6 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+  HEAP32[i4 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+  HEAP32[i4 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+  HEAP32[i4 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+  STACKTOP = i3;
+  return;
+ } else if ((i6 | 0) == 14) {
+  __ZNSt3__17__sort4IRPFbRK6b2PairS3_EPS1_EEjT0_S8_S8_S8_T_(i5, i5 + 12 | 0, i5 + 24 | 0, i4, i1) | 0;
+  STACKTOP = i3;
+  return;
+ } else if ((i6 | 0) == 15) {
+  i6 = i5 + 12 | 0;
+  i7 = i5 + 24 | 0;
+  i8 = i5 + 36 | 0;
+  __ZNSt3__17__sort4IRPFbRK6b2PairS3_EPS1_EEjT0_S8_S8_S8_T_(i5, i6, i7, i8, i1) | 0;
+  if (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i4, i8) | 0)) {
+   STACKTOP = i3;
+   return;
+  }
+  HEAP32[i2 + 0 >> 2] = HEAP32[i8 + 0 >> 2];
+  HEAP32[i2 + 4 >> 2] = HEAP32[i8 + 4 >> 2];
+  HEAP32[i2 + 8 >> 2] = HEAP32[i8 + 8 >> 2];
+  HEAP32[i8 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+  HEAP32[i8 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+  HEAP32[i8 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+  HEAP32[i4 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+  HEAP32[i4 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+  HEAP32[i4 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+  if (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i8, i7) | 0)) {
+   STACKTOP = i3;
+   return;
+  }
+  HEAP32[i2 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+  HEAP32[i2 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+  HEAP32[i2 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+  HEAP32[i7 + 0 >> 2] = HEAP32[i8 + 0 >> 2];
+  HEAP32[i7 + 4 >> 2] = HEAP32[i8 + 4 >> 2];
+  HEAP32[i7 + 8 >> 2] = HEAP32[i8 + 8 >> 2];
+  HEAP32[i8 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+  HEAP32[i8 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+  HEAP32[i8 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+  if (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i7, i6) | 0)) {
+   STACKTOP = i3;
+   return;
+  }
+  HEAP32[i2 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+  HEAP32[i2 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+  HEAP32[i2 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+  HEAP32[i6 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+  HEAP32[i6 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+  HEAP32[i6 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+  HEAP32[i7 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+  HEAP32[i7 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+  HEAP32[i7 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+  if (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i6, i5) | 0)) {
+   STACKTOP = i3;
+   return;
+  }
+  HEAP32[i2 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+  HEAP32[i2 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+  HEAP32[i2 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+  HEAP32[i5 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+  HEAP32[i5 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+  HEAP32[i5 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+  HEAP32[i6 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+  HEAP32[i6 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+  HEAP32[i6 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+  STACKTOP = i3;
+  return;
+ } else if ((i6 | 0) == 21) {
+  __ZNSt3__118__insertion_sort_3IRPFbRK6b2PairS3_EPS1_EEvT0_S8_T_(i5, i8, i1);
+  STACKTOP = i3;
+  return;
+ } else if ((i6 | 0) == 67) {
+  STACKTOP = i3;
+  return;
+ }
+}
+function _free(i7) {
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0;
+ i1 = STACKTOP;
+ if ((i7 | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i15 = i7 + -8 | 0;
+ i16 = HEAP32[7176 >> 2] | 0;
+ if (i15 >>> 0 < i16 >>> 0) {
+  _abort();
+ }
+ i13 = HEAP32[i7 + -4 >> 2] | 0;
+ i12 = i13 & 3;
+ if ((i12 | 0) == 1) {
+  _abort();
+ }
+ i8 = i13 & -8;
+ i6 = i7 + (i8 + -8) | 0;
+ do {
+  if ((i13 & 1 | 0) == 0) {
+   i19 = HEAP32[i15 >> 2] | 0;
+   if ((i12 | 0) == 0) {
+    STACKTOP = i1;
+    return;
+   }
+   i15 = -8 - i19 | 0;
+   i13 = i7 + i15 | 0;
+   i12 = i19 + i8 | 0;
+   if (i13 >>> 0 < i16 >>> 0) {
+    _abort();
+   }
+   if ((i13 | 0) == (HEAP32[7180 >> 2] | 0)) {
+    i2 = i7 + (i8 + -4) | 0;
+    if ((HEAP32[i2 >> 2] & 3 | 0) != 3) {
+     i2 = i13;
+     i11 = i12;
+     break;
+    }
+    HEAP32[7168 >> 2] = i12;
+    HEAP32[i2 >> 2] = HEAP32[i2 >> 2] & -2;
+    HEAP32[i7 + (i15 + 4) >> 2] = i12 | 1;
+    HEAP32[i6 >> 2] = i12;
+    STACKTOP = i1;
+    return;
+   }
+   i18 = i19 >>> 3;
+   if (i19 >>> 0 < 256) {
+    i2 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
+    i11 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
+    i14 = 7200 + (i18 << 1 << 2) | 0;
+    if ((i2 | 0) != (i14 | 0)) {
+     if (i2 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i2 + 12 >> 2] | 0) != (i13 | 0)) {
+      _abort();
+     }
+    }
+    if ((i11 | 0) == (i2 | 0)) {
+     HEAP32[1790] = HEAP32[1790] & ~(1 << i18);
+     i2 = i13;
+     i11 = i12;
+     break;
+    }
+    if ((i11 | 0) != (i14 | 0)) {
+     if (i11 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     i14 = i11 + 8 | 0;
+     if ((HEAP32[i14 >> 2] | 0) == (i13 | 0)) {
+      i17 = i14;
+     } else {
+      _abort();
+     }
+    } else {
+     i17 = i11 + 8 | 0;
+    }
+    HEAP32[i2 + 12 >> 2] = i11;
+    HEAP32[i17 >> 2] = i2;
+    i2 = i13;
+    i11 = i12;
+    break;
+   }
+   i17 = HEAP32[i7 + (i15 + 24) >> 2] | 0;
+   i18 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
+   do {
+    if ((i18 | 0) == (i13 | 0)) {
+     i19 = i7 + (i15 + 20) | 0;
+     i18 = HEAP32[i19 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      i19 = i7 + (i15 + 16) | 0;
+      i18 = HEAP32[i19 >> 2] | 0;
+      if ((i18 | 0) == 0) {
+       i14 = 0;
+       break;
+      }
+     }
+     while (1) {
+      i21 = i18 + 20 | 0;
+      i20 = HEAP32[i21 >> 2] | 0;
+      if ((i20 | 0) != 0) {
+       i18 = i20;
+       i19 = i21;
+       continue;
+      }
+      i20 = i18 + 16 | 0;
+      i21 = HEAP32[i20 >> 2] | 0;
+      if ((i21 | 0) == 0) {
+       break;
+      } else {
+       i18 = i21;
+       i19 = i20;
+      }
+     }
+     if (i19 >>> 0 < i16 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i19 >> 2] = 0;
+      i14 = i18;
+      break;
+     }
+    } else {
+     i19 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
+     if (i19 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     i16 = i19 + 12 | 0;
+     if ((HEAP32[i16 >> 2] | 0) != (i13 | 0)) {
+      _abort();
+     }
+     i20 = i18 + 8 | 0;
+     if ((HEAP32[i20 >> 2] | 0) == (i13 | 0)) {
+      HEAP32[i16 >> 2] = i18;
+      HEAP32[i20 >> 2] = i19;
+      i14 = i18;
+      break;
+     } else {
+      _abort();
+     }
+    }
+   } while (0);
+   if ((i17 | 0) != 0) {
+    i18 = HEAP32[i7 + (i15 + 28) >> 2] | 0;
+    i16 = 7464 + (i18 << 2) | 0;
+    if ((i13 | 0) == (HEAP32[i16 >> 2] | 0)) {
+     HEAP32[i16 >> 2] = i14;
+     if ((i14 | 0) == 0) {
+      HEAP32[7164 >> 2] = HEAP32[7164 >> 2] & ~(1 << i18);
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    } else {
+     if (i17 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i16 = i17 + 16 | 0;
+     if ((HEAP32[i16 >> 2] | 0) == (i13 | 0)) {
+      HEAP32[i16 >> 2] = i14;
+     } else {
+      HEAP32[i17 + 20 >> 2] = i14;
+     }
+     if ((i14 | 0) == 0) {
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    }
+    if (i14 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+     _abort();
+    }
+    HEAP32[i14 + 24 >> 2] = i17;
+    i16 = HEAP32[i7 + (i15 + 16) >> 2] | 0;
+    do {
+     if ((i16 | 0) != 0) {
+      if (i16 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i14 + 16 >> 2] = i16;
+       HEAP32[i16 + 24 >> 2] = i14;
+       break;
+      }
+     }
+    } while (0);
+    i15 = HEAP32[i7 + (i15 + 20) >> 2] | 0;
+    if ((i15 | 0) != 0) {
+     if (i15 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i14 + 20 >> 2] = i15;
+      HEAP32[i15 + 24 >> 2] = i14;
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    } else {
+     i2 = i13;
+     i11 = i12;
+    }
+   } else {
+    i2 = i13;
+    i11 = i12;
+   }
+  } else {
+   i2 = i15;
+   i11 = i8;
+  }
+ } while (0);
+ if (!(i2 >>> 0 < i6 >>> 0)) {
+  _abort();
+ }
+ i12 = i7 + (i8 + -4) | 0;
+ i13 = HEAP32[i12 >> 2] | 0;
+ if ((i13 & 1 | 0) == 0) {
+  _abort();
+ }
+ if ((i13 & 2 | 0) == 0) {
+  if ((i6 | 0) == (HEAP32[7184 >> 2] | 0)) {
+   i21 = (HEAP32[7172 >> 2] | 0) + i11 | 0;
+   HEAP32[7172 >> 2] = i21;
+   HEAP32[7184 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i21 | 1;
+   if ((i2 | 0) != (HEAP32[7180 >> 2] | 0)) {
+    STACKTOP = i1;
+    return;
+   }
+   HEAP32[7180 >> 2] = 0;
+   HEAP32[7168 >> 2] = 0;
+   STACKTOP = i1;
+   return;
+  }
+  if ((i6 | 0) == (HEAP32[7180 >> 2] | 0)) {
+   i21 = (HEAP32[7168 >> 2] | 0) + i11 | 0;
+   HEAP32[7168 >> 2] = i21;
+   HEAP32[7180 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i21 | 1;
+   HEAP32[i2 + i21 >> 2] = i21;
+   STACKTOP = i1;
+   return;
+  }
+  i11 = (i13 & -8) + i11 | 0;
+  i12 = i13 >>> 3;
+  do {
+   if (!(i13 >>> 0 < 256)) {
+    i10 = HEAP32[i7 + (i8 + 16) >> 2] | 0;
+    i15 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
+    do {
+     if ((i15 | 0) == (i6 | 0)) {
+      i13 = i7 + (i8 + 12) | 0;
+      i12 = HEAP32[i13 >> 2] | 0;
+      if ((i12 | 0) == 0) {
+       i13 = i7 + (i8 + 8) | 0;
+       i12 = HEAP32[i13 >> 2] | 0;
+       if ((i12 | 0) == 0) {
+        i9 = 0;
+        break;
+       }
+      }
+      while (1) {
+       i14 = i12 + 20 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) != 0) {
+        i12 = i15;
+        i13 = i14;
+        continue;
+       }
+       i14 = i12 + 16 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) == 0) {
+        break;
+       } else {
+        i12 = i15;
+        i13 = i14;
+       }
+      }
+      if (i13 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i13 >> 2] = 0;
+       i9 = i12;
+       break;
+      }
+     } else {
+      i13 = HEAP32[i7 + i8 >> 2] | 0;
+      if (i13 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i14 = i13 + 12 | 0;
+      if ((HEAP32[i14 >> 2] | 0) != (i6 | 0)) {
+       _abort();
+      }
+      i12 = i15 + 8 | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+       HEAP32[i14 >> 2] = i15;
+       HEAP32[i12 >> 2] = i13;
+       i9 = i15;
+       break;
+      } else {
+       _abort();
+      }
+     }
+    } while (0);
+    if ((i10 | 0) != 0) {
+     i12 = HEAP32[i7 + (i8 + 20) >> 2] | 0;
+     i13 = 7464 + (i12 << 2) | 0;
+     if ((i6 | 0) == (HEAP32[i13 >> 2] | 0)) {
+      HEAP32[i13 >> 2] = i9;
+      if ((i9 | 0) == 0) {
+       HEAP32[7164 >> 2] = HEAP32[7164 >> 2] & ~(1 << i12);
+       break;
+      }
+     } else {
+      if (i10 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i12 = i10 + 16 | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+       HEAP32[i12 >> 2] = i9;
+      } else {
+       HEAP32[i10 + 20 >> 2] = i9;
+      }
+      if ((i9 | 0) == 0) {
+       break;
+      }
+     }
+     if (i9 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     HEAP32[i9 + 24 >> 2] = i10;
+     i6 = HEAP32[i7 + (i8 + 8) >> 2] | 0;
+     do {
+      if ((i6 | 0) != 0) {
+       if (i6 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i9 + 16 >> 2] = i6;
+        HEAP32[i6 + 24 >> 2] = i9;
+        break;
+       }
+      }
+     } while (0);
+     i6 = HEAP32[i7 + (i8 + 12) >> 2] | 0;
+     if ((i6 | 0) != 0) {
+      if (i6 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i9 + 20 >> 2] = i6;
+       HEAP32[i6 + 24 >> 2] = i9;
+       break;
+      }
+     }
+    }
+   } else {
+    i9 = HEAP32[i7 + i8 >> 2] | 0;
+    i7 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
+    i8 = 7200 + (i12 << 1 << 2) | 0;
+    if ((i9 | 0) != (i8 | 0)) {
+     if (i9 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i9 + 12 >> 2] | 0) != (i6 | 0)) {
+      _abort();
+     }
+    }
+    if ((i7 | 0) == (i9 | 0)) {
+     HEAP32[1790] = HEAP32[1790] & ~(1 << i12);
+     break;
+    }
+    if ((i7 | 0) != (i8 | 0)) {
+     if (i7 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i8 = i7 + 8 | 0;
+     if ((HEAP32[i8 >> 2] | 0) == (i6 | 0)) {
+      i10 = i8;
+     } else {
+      _abort();
+     }
+    } else {
+     i10 = i7 + 8 | 0;
+    }
+    HEAP32[i9 + 12 >> 2] = i7;
+    HEAP32[i10 >> 2] = i9;
+   }
+  } while (0);
+  HEAP32[i2 + 4 >> 2] = i11 | 1;
+  HEAP32[i2 + i11 >> 2] = i11;
+  if ((i2 | 0) == (HEAP32[7180 >> 2] | 0)) {
+   HEAP32[7168 >> 2] = i11;
+   STACKTOP = i1;
+   return;
+  }
+ } else {
+  HEAP32[i12 >> 2] = i13 & -2;
+  HEAP32[i2 + 4 >> 2] = i11 | 1;
+  HEAP32[i2 + i11 >> 2] = i11;
+ }
+ i6 = i11 >>> 3;
+ if (i11 >>> 0 < 256) {
+  i7 = i6 << 1;
+  i3 = 7200 + (i7 << 2) | 0;
+  i8 = HEAP32[1790] | 0;
+  i6 = 1 << i6;
+  if ((i8 & i6 | 0) != 0) {
+   i6 = 7200 + (i7 + 2 << 2) | 0;
+   i7 = HEAP32[i6 >> 2] | 0;
+   if (i7 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+    _abort();
+   } else {
+    i4 = i6;
+    i5 = i7;
+   }
+  } else {
+   HEAP32[1790] = i8 | i6;
+   i4 = 7200 + (i7 + 2 << 2) | 0;
+   i5 = i3;
+  }
+  HEAP32[i4 >> 2] = i2;
+  HEAP32[i5 + 12 >> 2] = i2;
+  HEAP32[i2 + 8 >> 2] = i5;
+  HEAP32[i2 + 12 >> 2] = i3;
+  STACKTOP = i1;
+  return;
+ }
+ i4 = i11 >>> 8;
+ if ((i4 | 0) != 0) {
+  if (i11 >>> 0 > 16777215) {
+   i4 = 31;
+  } else {
+   i20 = (i4 + 1048320 | 0) >>> 16 & 8;
+   i21 = i4 << i20;
+   i19 = (i21 + 520192 | 0) >>> 16 & 4;
+   i21 = i21 << i19;
+   i4 = (i21 + 245760 | 0) >>> 16 & 2;
+   i4 = 14 - (i19 | i20 | i4) + (i21 << i4 >>> 15) | 0;
+   i4 = i11 >>> (i4 + 7 | 0) & 1 | i4 << 1;
+  }
+ } else {
+  i4 = 0;
+ }
+ i5 = 7464 + (i4 << 2) | 0;
+ HEAP32[i2 + 28 >> 2] = i4;
+ HEAP32[i2 + 20 >> 2] = 0;
+ HEAP32[i2 + 16 >> 2] = 0;
+ i7 = HEAP32[7164 >> 2] | 0;
+ i6 = 1 << i4;
+ L199 : do {
+  if ((i7 & i6 | 0) != 0) {
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((i4 | 0) == 31) {
+    i4 = 0;
+   } else {
+    i4 = 25 - (i4 >>> 1) | 0;
+   }
+   L204 : do {
+    if ((HEAP32[i5 + 4 >> 2] & -8 | 0) != (i11 | 0)) {
+     i4 = i11 << i4;
+     i7 = i5;
+     while (1) {
+      i6 = i7 + (i4 >>> 31 << 2) + 16 | 0;
+      i5 = HEAP32[i6 >> 2] | 0;
+      if ((i5 | 0) == 0) {
+       break;
+      }
+      if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i11 | 0)) {
+       i3 = i5;
+       break L204;
+      } else {
+       i4 = i4 << 1;
+       i7 = i5;
+      }
+     }
+     if (i6 >>> 0 < (HEAP32[7176 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i6 >> 2] = i2;
+      HEAP32[i2 + 24 >> 2] = i7;
+      HEAP32[i2 + 12 >> 2] = i2;
+      HEAP32[i2 + 8 >> 2] = i2;
+      break L199;
+     }
+    } else {
+     i3 = i5;
+    }
+   } while (0);
+   i5 = i3 + 8 | 0;
+   i4 = HEAP32[i5 >> 2] | 0;
+   i6 = HEAP32[7176 >> 2] | 0;
+   if (i3 >>> 0 < i6 >>> 0) {
+    _abort();
+   }
+   if (i4 >>> 0 < i6 >>> 0) {
+    _abort();
+   } else {
+    HEAP32[i4 + 12 >> 2] = i2;
+    HEAP32[i5 >> 2] = i2;
+    HEAP32[i2 + 8 >> 2] = i4;
+    HEAP32[i2 + 12 >> 2] = i3;
+    HEAP32[i2 + 24 >> 2] = 0;
+    break;
+   }
+  } else {
+   HEAP32[7164 >> 2] = i7 | i6;
+   HEAP32[i5 >> 2] = i2;
+   HEAP32[i2 + 24 >> 2] = i5;
+   HEAP32[i2 + 12 >> 2] = i2;
+   HEAP32[i2 + 8 >> 2] = i2;
+  }
+ } while (0);
+ i21 = (HEAP32[7192 >> 2] | 0) + -1 | 0;
+ HEAP32[7192 >> 2] = i21;
+ if ((i21 | 0) == 0) {
+  i2 = 7616 | 0;
+ } else {
+  STACKTOP = i1;
+  return;
+ }
+ while (1) {
+  i2 = HEAP32[i2 >> 2] | 0;
+  if ((i2 | 0) == 0) {
+   break;
+  } else {
+   i2 = i2 + 8 | 0;
+  }
+ }
+ HEAP32[7192 >> 2] = -1;
+ STACKTOP = i1;
+ return;
+}
+function __ZNSt3__127__insertion_sort_incompleteIRPFbRK6b2PairS3_EPS1_EEbT0_S8_T_(i3, i4, i2) {
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i7 = i1 + 12 | 0;
+ i6 = i1;
+ switch ((i4 - i3 | 0) / 12 | 0 | 0) {
+ case 5:
+  {
+   i6 = i3 + 12 | 0;
+   i8 = i3 + 24 | 0;
+   i5 = i3 + 36 | 0;
+   i4 = i4 + -12 | 0;
+   __ZNSt3__17__sort4IRPFbRK6b2PairS3_EPS1_EEjT0_S8_S8_S8_T_(i3, i6, i8, i5, i2) | 0;
+   if (!(FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i4, i5) | 0)) {
+    i10 = 1;
+    STACKTOP = i1;
+    return i10 | 0;
+   }
+   HEAP32[i7 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+   HEAP32[i7 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+   HEAP32[i7 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+   HEAP32[i5 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+   HEAP32[i5 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+   HEAP32[i5 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+   HEAP32[i4 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+   HEAP32[i4 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+   HEAP32[i4 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+   if (!(FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i5, i8) | 0)) {
+    i10 = 1;
+    STACKTOP = i1;
+    return i10 | 0;
+   }
+   HEAP32[i7 + 0 >> 2] = HEAP32[i8 + 0 >> 2];
+   HEAP32[i7 + 4 >> 2] = HEAP32[i8 + 4 >> 2];
+   HEAP32[i7 + 8 >> 2] = HEAP32[i8 + 8 >> 2];
+   HEAP32[i8 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+   HEAP32[i8 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+   HEAP32[i8 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+   HEAP32[i5 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+   HEAP32[i5 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+   HEAP32[i5 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+   if (!(FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i8, i6) | 0)) {
+    i10 = 1;
+    STACKTOP = i1;
+    return i10 | 0;
+   }
+   HEAP32[i7 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+   HEAP32[i7 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+   HEAP32[i7 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+   HEAP32[i6 + 0 >> 2] = HEAP32[i8 + 0 >> 2];
+   HEAP32[i6 + 4 >> 2] = HEAP32[i8 + 4 >> 2];
+   HEAP32[i6 + 8 >> 2] = HEAP32[i8 + 8 >> 2];
+   HEAP32[i8 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+   HEAP32[i8 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+   HEAP32[i8 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+   if (!(FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i6, i3) | 0)) {
+    i10 = 1;
+    STACKTOP = i1;
+    return i10 | 0;
+   }
+   HEAP32[i7 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+   HEAP32[i7 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+   HEAP32[i7 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+   HEAP32[i3 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+   HEAP32[i3 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+   HEAP32[i3 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+   HEAP32[i6 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+   HEAP32[i6 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+   HEAP32[i6 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+   i10 = 1;
+   STACKTOP = i1;
+   return i10 | 0;
+  }
+ case 4:
+  {
+   __ZNSt3__17__sort4IRPFbRK6b2PairS3_EPS1_EEjT0_S8_S8_S8_T_(i3, i3 + 12 | 0, i3 + 24 | 0, i4 + -12 | 0, i2) | 0;
+   i10 = 1;
+   STACKTOP = i1;
+   return i10 | 0;
+  }
+ case 3:
+  {
+   i5 = i3 + 12 | 0;
+   i4 = i4 + -12 | 0;
+   i10 = FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i5, i3) | 0;
+   i6 = FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i4, i5) | 0;
+   if (!i10) {
+    if (!i6) {
+     i10 = 1;
+     STACKTOP = i1;
+     return i10 | 0;
+    }
+    HEAP32[i7 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+    HEAP32[i7 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+    HEAP32[i7 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+    HEAP32[i5 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+    HEAP32[i5 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+    HEAP32[i5 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+    HEAP32[i4 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+    HEAP32[i4 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+    HEAP32[i4 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+    if (!(FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i5, i3) | 0)) {
+     i10 = 1;
+     STACKTOP = i1;
+     return i10 | 0;
+    }
+    HEAP32[i7 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+    HEAP32[i7 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+    HEAP32[i7 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+    HEAP32[i3 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+    HEAP32[i3 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+    HEAP32[i3 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+    HEAP32[i5 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+    HEAP32[i5 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+    HEAP32[i5 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+    i10 = 1;
+    STACKTOP = i1;
+    return i10 | 0;
+   }
+   if (i6) {
+    HEAP32[i7 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+    HEAP32[i7 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+    HEAP32[i7 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+    HEAP32[i3 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+    HEAP32[i3 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+    HEAP32[i3 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+    HEAP32[i4 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+    HEAP32[i4 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+    HEAP32[i4 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+    i10 = 1;
+    STACKTOP = i1;
+    return i10 | 0;
+   }
+   HEAP32[i7 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+   HEAP32[i7 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+   HEAP32[i7 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+   HEAP32[i3 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+   HEAP32[i3 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+   HEAP32[i3 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+   HEAP32[i5 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+   HEAP32[i5 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+   HEAP32[i5 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+   if (!(FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i4, i5) | 0)) {
+    i10 = 1;
+    STACKTOP = i1;
+    return i10 | 0;
+   }
+   HEAP32[i7 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+   HEAP32[i7 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+   HEAP32[i7 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+   HEAP32[i5 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+   HEAP32[i5 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+   HEAP32[i5 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+   HEAP32[i4 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+   HEAP32[i4 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+   HEAP32[i4 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+   i10 = 1;
+   STACKTOP = i1;
+   return i10 | 0;
+  }
+ case 2:
+  {
+   i4 = i4 + -12 | 0;
+   if (!(FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i4, i3) | 0)) {
+    i10 = 1;
+    STACKTOP = i1;
+    return i10 | 0;
+   }
+   HEAP32[i7 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+   HEAP32[i7 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+   HEAP32[i7 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+   HEAP32[i3 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+   HEAP32[i3 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+   HEAP32[i3 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+   HEAP32[i4 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+   HEAP32[i4 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+   HEAP32[i4 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+   i10 = 1;
+   STACKTOP = i1;
+   return i10 | 0;
+  }
+ case 1:
+ case 0:
+  {
+   i10 = 1;
+   STACKTOP = i1;
+   return i10 | 0;
+  }
+ default:
+  {
+   i9 = i3 + 24 | 0;
+   i10 = i3 + 12 | 0;
+   i11 = FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i10, i3) | 0;
+   i8 = FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i9, i10) | 0;
+   do {
+    if (i11) {
+     if (i8) {
+      HEAP32[i7 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+      HEAP32[i7 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+      HEAP32[i7 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+      HEAP32[i3 + 0 >> 2] = HEAP32[i9 + 0 >> 2];
+      HEAP32[i3 + 4 >> 2] = HEAP32[i9 + 4 >> 2];
+      HEAP32[i3 + 8 >> 2] = HEAP32[i9 + 8 >> 2];
+      HEAP32[i9 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+      HEAP32[i9 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+      HEAP32[i9 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+      break;
+     }
+     HEAP32[i7 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+     HEAP32[i7 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+     HEAP32[i7 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+     HEAP32[i3 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+     HEAP32[i3 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+     HEAP32[i3 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+     HEAP32[i10 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+     HEAP32[i10 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+     HEAP32[i10 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+     if (FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i9, i10) | 0) {
+      HEAP32[i7 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+      HEAP32[i7 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+      HEAP32[i7 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+      HEAP32[i10 + 0 >> 2] = HEAP32[i9 + 0 >> 2];
+      HEAP32[i10 + 4 >> 2] = HEAP32[i9 + 4 >> 2];
+      HEAP32[i10 + 8 >> 2] = HEAP32[i9 + 8 >> 2];
+      HEAP32[i9 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+      HEAP32[i9 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+      HEAP32[i9 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+     }
+    } else {
+     if (i8) {
+      HEAP32[i7 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+      HEAP32[i7 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+      HEAP32[i7 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+      HEAP32[i10 + 0 >> 2] = HEAP32[i9 + 0 >> 2];
+      HEAP32[i10 + 4 >> 2] = HEAP32[i9 + 4 >> 2];
+      HEAP32[i10 + 8 >> 2] = HEAP32[i9 + 8 >> 2];
+      HEAP32[i9 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+      HEAP32[i9 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+      HEAP32[i9 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+      if (FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i10, i3) | 0) {
+       HEAP32[i7 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+       HEAP32[i7 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+       HEAP32[i7 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+       HEAP32[i3 + 0 >> 2] = HEAP32[i10 + 0 >> 2];
+       HEAP32[i3 + 4 >> 2] = HEAP32[i10 + 4 >> 2];
+       HEAP32[i3 + 8 >> 2] = HEAP32[i10 + 8 >> 2];
+       HEAP32[i10 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+       HEAP32[i10 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+       HEAP32[i10 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+      }
+     }
+    }
+   } while (0);
+   i7 = i3 + 36 | 0;
+   if ((i7 | 0) == (i4 | 0)) {
+    i11 = 1;
+    STACKTOP = i1;
+    return i11 | 0;
+   }
+   i8 = 0;
+   while (1) {
+    if (FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i7, i9) | 0) {
+     HEAP32[i6 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+     HEAP32[i6 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+     HEAP32[i6 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+     i10 = i7;
+     while (1) {
+      HEAP32[i10 + 0 >> 2] = HEAP32[i9 + 0 >> 2];
+      HEAP32[i10 + 4 >> 2] = HEAP32[i9 + 4 >> 2];
+      HEAP32[i10 + 8 >> 2] = HEAP32[i9 + 8 >> 2];
+      if ((i9 | 0) == (i3 | 0)) {
+       break;
+      }
+      i10 = i9 + -12 | 0;
+      if (FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i6, i10) | 0) {
+       i11 = i9;
+       i9 = i10;
+       i10 = i11;
+      } else {
+       break;
+      }
+     }
+     HEAP32[i9 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+     HEAP32[i9 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+     HEAP32[i9 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+     i8 = i8 + 1 | 0;
+     if ((i8 | 0) == 8) {
+      break;
+     }
+    }
+    i9 = i7 + 12 | 0;
+    if ((i9 | 0) == (i4 | 0)) {
+     i2 = 1;
+     i5 = 35;
+     break;
+    } else {
+     i11 = i7;
+     i7 = i9;
+     i9 = i11;
+    }
+   }
+   if ((i5 | 0) == 35) {
+    STACKTOP = i1;
+    return i2 | 0;
+   }
+   i11 = (i7 + 12 | 0) == (i4 | 0);
+   STACKTOP = i1;
+   return i11 | 0;
+  }
+ }
+ return 0;
+}
+function __ZN13b2DynamicTree7BalanceEi(i11, i6) {
+ i11 = i11 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, d19 = 0.0, i20 = 0, i21 = 0, d22 = 0.0, d23 = 0.0, d24 = 0.0, d25 = 0.0;
+ i1 = STACKTOP;
+ if ((i6 | 0) == -1) {
+  ___assert_fail(3216, 2944, 382, 3232);
+ }
+ i5 = HEAP32[i11 + 4 >> 2] | 0;
+ i13 = i5 + (i6 * 36 | 0) | 0;
+ i18 = i5 + (i6 * 36 | 0) + 24 | 0;
+ i8 = HEAP32[i18 >> 2] | 0;
+ if ((i8 | 0) == -1) {
+  i21 = i6;
+  STACKTOP = i1;
+  return i21 | 0;
+ }
+ i2 = i5 + (i6 * 36 | 0) + 32 | 0;
+ if ((HEAP32[i2 >> 2] | 0) < 2) {
+  i21 = i6;
+  STACKTOP = i1;
+  return i21 | 0;
+ }
+ i20 = i5 + (i6 * 36 | 0) + 28 | 0;
+ i7 = HEAP32[i20 >> 2] | 0;
+ if (!((i8 | 0) > -1)) {
+  ___assert_fail(3240, 2944, 392, 3232);
+ }
+ i12 = HEAP32[i11 + 12 >> 2] | 0;
+ if ((i8 | 0) >= (i12 | 0)) {
+  ___assert_fail(3240, 2944, 392, 3232);
+ }
+ if (!((i7 | 0) > -1 & (i7 | 0) < (i12 | 0))) {
+  ___assert_fail(3272, 2944, 393, 3232);
+ }
+ i9 = i5 + (i8 * 36 | 0) | 0;
+ i10 = i5 + (i7 * 36 | 0) | 0;
+ i3 = i5 + (i7 * 36 | 0) + 32 | 0;
+ i4 = i5 + (i8 * 36 | 0) + 32 | 0;
+ i14 = (HEAP32[i3 >> 2] | 0) - (HEAP32[i4 >> 2] | 0) | 0;
+ if ((i14 | 0) > 1) {
+  i21 = i5 + (i7 * 36 | 0) + 24 | 0;
+  i14 = HEAP32[i21 >> 2] | 0;
+  i18 = i5 + (i7 * 36 | 0) + 28 | 0;
+  i15 = HEAP32[i18 >> 2] | 0;
+  i16 = i5 + (i14 * 36 | 0) | 0;
+  i17 = i5 + (i15 * 36 | 0) | 0;
+  if (!((i14 | 0) > -1 & (i14 | 0) < (i12 | 0))) {
+   ___assert_fail(3304, 2944, 407, 3232);
+  }
+  if (!((i15 | 0) > -1 & (i15 | 0) < (i12 | 0))) {
+   ___assert_fail(3336, 2944, 408, 3232);
+  }
+  HEAP32[i21 >> 2] = i6;
+  i21 = i5 + (i6 * 36 | 0) + 20 | 0;
+  i12 = i5 + (i7 * 36 | 0) + 20 | 0;
+  HEAP32[i12 >> 2] = HEAP32[i21 >> 2];
+  HEAP32[i21 >> 2] = i7;
+  i12 = HEAP32[i12 >> 2] | 0;
+  do {
+   if (!((i12 | 0) == -1)) {
+    i11 = i5 + (i12 * 36 | 0) + 24 | 0;
+    if ((HEAP32[i11 >> 2] | 0) == (i6 | 0)) {
+     HEAP32[i11 >> 2] = i7;
+     break;
+    }
+    i11 = i5 + (i12 * 36 | 0) + 28 | 0;
+    if ((HEAP32[i11 >> 2] | 0) == (i6 | 0)) {
+     HEAP32[i11 >> 2] = i7;
+     break;
+    } else {
+     ___assert_fail(3368, 2944, 424, 3232);
+    }
+   } else {
+    HEAP32[i11 >> 2] = i7;
+   }
+  } while (0);
+  i11 = i5 + (i14 * 36 | 0) + 32 | 0;
+  i12 = i5 + (i15 * 36 | 0) + 32 | 0;
+  if ((HEAP32[i11 >> 2] | 0) > (HEAP32[i12 >> 2] | 0)) {
+   HEAP32[i18 >> 2] = i14;
+   HEAP32[i20 >> 2] = i15;
+   HEAP32[i5 + (i15 * 36 | 0) + 20 >> 2] = i6;
+   d19 = +HEAPF32[i9 >> 2];
+   d22 = +HEAPF32[i17 >> 2];
+   d19 = d19 < d22 ? d19 : d22;
+   d23 = +HEAPF32[i5 + (i8 * 36 | 0) + 4 >> 2];
+   d22 = +HEAPF32[i5 + (i15 * 36 | 0) + 4 >> 2];
+   d24 = +d19;
+   d23 = +(d23 < d22 ? d23 : d22);
+   i21 = i13;
+   HEAPF32[i21 >> 2] = d24;
+   HEAPF32[i21 + 4 >> 2] = d23;
+   d23 = +HEAPF32[i5 + (i8 * 36 | 0) + 8 >> 2];
+   d24 = +HEAPF32[i5 + (i15 * 36 | 0) + 8 >> 2];
+   d22 = +HEAPF32[i5 + (i8 * 36 | 0) + 12 >> 2];
+   d25 = +HEAPF32[i5 + (i15 * 36 | 0) + 12 >> 2];
+   d23 = +(d23 > d24 ? d23 : d24);
+   d24 = +(d22 > d25 ? d22 : d25);
+   i21 = i5 + (i6 * 36 | 0) + 8 | 0;
+   HEAPF32[i21 >> 2] = d23;
+   HEAPF32[i21 + 4 >> 2] = d24;
+   d24 = +HEAPF32[i16 >> 2];
+   d22 = +HEAPF32[i5 + (i6 * 36 | 0) + 4 >> 2];
+   d23 = +HEAPF32[i5 + (i14 * 36 | 0) + 4 >> 2];
+   d19 = +(d19 < d24 ? d19 : d24);
+   d22 = +(d22 < d23 ? d22 : d23);
+   i21 = i10;
+   HEAPF32[i21 >> 2] = d19;
+   HEAPF32[i21 + 4 >> 2] = d22;
+   d22 = +HEAPF32[i5 + (i6 * 36 | 0) + 8 >> 2];
+   d19 = +HEAPF32[i5 + (i14 * 36 | 0) + 8 >> 2];
+   d23 = +HEAPF32[i5 + (i6 * 36 | 0) + 12 >> 2];
+   d24 = +HEAPF32[i5 + (i14 * 36 | 0) + 12 >> 2];
+   d19 = +(d22 > d19 ? d22 : d19);
+   d25 = +(d23 > d24 ? d23 : d24);
+   i5 = i5 + (i7 * 36 | 0) + 8 | 0;
+   HEAPF32[i5 >> 2] = d19;
+   HEAPF32[i5 + 4 >> 2] = d25;
+   i4 = HEAP32[i4 >> 2] | 0;
+   i5 = HEAP32[i12 >> 2] | 0;
+   i4 = ((i4 | 0) > (i5 | 0) ? i4 : i5) + 1 | 0;
+   HEAP32[i2 >> 2] = i4;
+   i2 = HEAP32[i11 >> 2] | 0;
+   i2 = (i4 | 0) > (i2 | 0) ? i4 : i2;
+  } else {
+   HEAP32[i18 >> 2] = i15;
+   HEAP32[i20 >> 2] = i14;
+   HEAP32[i5 + (i14 * 36 | 0) + 20 >> 2] = i6;
+   d19 = +HEAPF32[i9 >> 2];
+   d22 = +HEAPF32[i16 >> 2];
+   d19 = d19 < d22 ? d19 : d22;
+   d23 = +HEAPF32[i5 + (i8 * 36 | 0) + 4 >> 2];
+   d24 = +HEAPF32[i5 + (i14 * 36 | 0) + 4 >> 2];
+   d22 = +d19;
+   d23 = +(d23 < d24 ? d23 : d24);
+   i21 = i13;
+   HEAPF32[i21 >> 2] = d22;
+   HEAPF32[i21 + 4 >> 2] = d23;
+   d23 = +HEAPF32[i5 + (i8 * 36 | 0) + 8 >> 2];
+   d24 = +HEAPF32[i5 + (i14 * 36 | 0) + 8 >> 2];
+   d22 = +HEAPF32[i5 + (i8 * 36 | 0) + 12 >> 2];
+   d25 = +HEAPF32[i5 + (i14 * 36 | 0) + 12 >> 2];
+   d23 = +(d23 > d24 ? d23 : d24);
+   d24 = +(d22 > d25 ? d22 : d25);
+   i21 = i5 + (i6 * 36 | 0) + 8 | 0;
+   HEAPF32[i21 >> 2] = d23;
+   HEAPF32[i21 + 4 >> 2] = d24;
+   d24 = +HEAPF32[i17 >> 2];
+   d22 = +HEAPF32[i5 + (i6 * 36 | 0) + 4 >> 2];
+   d23 = +HEAPF32[i5 + (i15 * 36 | 0) + 4 >> 2];
+   d19 = +(d19 < d24 ? d19 : d24);
+   d23 = +(d22 < d23 ? d22 : d23);
+   i21 = i10;
+   HEAPF32[i21 >> 2] = d19;
+   HEAPF32[i21 + 4 >> 2] = d23;
+   d23 = +HEAPF32[i5 + (i6 * 36 | 0) + 8 >> 2];
+   d19 = +HEAPF32[i5 + (i15 * 36 | 0) + 8 >> 2];
+   d22 = +HEAPF32[i5 + (i6 * 36 | 0) + 12 >> 2];
+   d24 = +HEAPF32[i5 + (i15 * 36 | 0) + 12 >> 2];
+   d19 = +(d23 > d19 ? d23 : d19);
+   d25 = +(d22 > d24 ? d22 : d24);
+   i5 = i5 + (i7 * 36 | 0) + 8 | 0;
+   HEAPF32[i5 >> 2] = d19;
+   HEAPF32[i5 + 4 >> 2] = d25;
+   i4 = HEAP32[i4 >> 2] | 0;
+   i5 = HEAP32[i11 >> 2] | 0;
+   i4 = ((i4 | 0) > (i5 | 0) ? i4 : i5) + 1 | 0;
+   HEAP32[i2 >> 2] = i4;
+   i2 = HEAP32[i12 >> 2] | 0;
+   i2 = (i4 | 0) > (i2 | 0) ? i4 : i2;
+  }
+  HEAP32[i3 >> 2] = i2 + 1;
+  i21 = i7;
+  STACKTOP = i1;
+  return i21 | 0;
+ }
+ if (!((i14 | 0) < -1)) {
+  i21 = i6;
+  STACKTOP = i1;
+  return i21 | 0;
+ }
+ i21 = i5 + (i8 * 36 | 0) + 24 | 0;
+ i14 = HEAP32[i21 >> 2] | 0;
+ i20 = i5 + (i8 * 36 | 0) + 28 | 0;
+ i15 = HEAP32[i20 >> 2] | 0;
+ i17 = i5 + (i14 * 36 | 0) | 0;
+ i16 = i5 + (i15 * 36 | 0) | 0;
+ if (!((i14 | 0) > -1 & (i14 | 0) < (i12 | 0))) {
+  ___assert_fail(3400, 2944, 467, 3232);
+ }
+ if (!((i15 | 0) > -1 & (i15 | 0) < (i12 | 0))) {
+  ___assert_fail(3432, 2944, 468, 3232);
+ }
+ HEAP32[i21 >> 2] = i6;
+ i21 = i5 + (i6 * 36 | 0) + 20 | 0;
+ i12 = i5 + (i8 * 36 | 0) + 20 | 0;
+ HEAP32[i12 >> 2] = HEAP32[i21 >> 2];
+ HEAP32[i21 >> 2] = i8;
+ i12 = HEAP32[i12 >> 2] | 0;
+ do {
+  if (!((i12 | 0) == -1)) {
+   i11 = i5 + (i12 * 36 | 0) + 24 | 0;
+   if ((HEAP32[i11 >> 2] | 0) == (i6 | 0)) {
+    HEAP32[i11 >> 2] = i8;
+    break;
+   }
+   i11 = i5 + (i12 * 36 | 0) + 28 | 0;
+   if ((HEAP32[i11 >> 2] | 0) == (i6 | 0)) {
+    HEAP32[i11 >> 2] = i8;
+    break;
+   } else {
+    ___assert_fail(3464, 2944, 484, 3232);
+   }
+  } else {
+   HEAP32[i11 >> 2] = i8;
+  }
+ } while (0);
+ i12 = i5 + (i14 * 36 | 0) + 32 | 0;
+ i11 = i5 + (i15 * 36 | 0) + 32 | 0;
+ if ((HEAP32[i12 >> 2] | 0) > (HEAP32[i11 >> 2] | 0)) {
+  HEAP32[i20 >> 2] = i14;
+  HEAP32[i18 >> 2] = i15;
+  HEAP32[i5 + (i15 * 36 | 0) + 20 >> 2] = i6;
+  d19 = +HEAPF32[i10 >> 2];
+  d22 = +HEAPF32[i16 >> 2];
+  d19 = d19 < d22 ? d19 : d22;
+  d23 = +HEAPF32[i5 + (i7 * 36 | 0) + 4 >> 2];
+  d22 = +HEAPF32[i5 + (i15 * 36 | 0) + 4 >> 2];
+  d24 = +d19;
+  d23 = +(d23 < d22 ? d23 : d22);
+  i21 = i13;
+  HEAPF32[i21 >> 2] = d24;
+  HEAPF32[i21 + 4 >> 2] = d23;
+  d23 = +HEAPF32[i5 + (i7 * 36 | 0) + 8 >> 2];
+  d22 = +HEAPF32[i5 + (i15 * 36 | 0) + 8 >> 2];
+  d24 = +HEAPF32[i5 + (i7 * 36 | 0) + 12 >> 2];
+  d25 = +HEAPF32[i5 + (i15 * 36 | 0) + 12 >> 2];
+  d22 = +(d23 > d22 ? d23 : d22);
+  d24 = +(d24 > d25 ? d24 : d25);
+  i21 = i5 + (i6 * 36 | 0) + 8 | 0;
+  HEAPF32[i21 >> 2] = d22;
+  HEAPF32[i21 + 4 >> 2] = d24;
+  d24 = +HEAPF32[i17 >> 2];
+  d23 = +HEAPF32[i5 + (i6 * 36 | 0) + 4 >> 2];
+  d22 = +HEAPF32[i5 + (i14 * 36 | 0) + 4 >> 2];
+  d19 = +(d19 < d24 ? d19 : d24);
+  d22 = +(d23 < d22 ? d23 : d22);
+  i21 = i9;
+  HEAPF32[i21 >> 2] = d19;
+  HEAPF32[i21 + 4 >> 2] = d22;
+  d22 = +HEAPF32[i5 + (i6 * 36 | 0) + 8 >> 2];
+  d23 = +HEAPF32[i5 + (i14 * 36 | 0) + 8 >> 2];
+  d19 = +HEAPF32[i5 + (i6 * 36 | 0) + 12 >> 2];
+  d24 = +HEAPF32[i5 + (i14 * 36 | 0) + 12 >> 2];
+  d22 = +(d22 > d23 ? d22 : d23);
+  d25 = +(d19 > d24 ? d19 : d24);
+  i5 = i5 + (i8 * 36 | 0) + 8 | 0;
+  HEAPF32[i5 >> 2] = d22;
+  HEAPF32[i5 + 4 >> 2] = d25;
+  i3 = HEAP32[i3 >> 2] | 0;
+  i5 = HEAP32[i11 >> 2] | 0;
+  i3 = ((i3 | 0) > (i5 | 0) ? i3 : i5) + 1 | 0;
+  HEAP32[i2 >> 2] = i3;
+  i2 = HEAP32[i12 >> 2] | 0;
+  i2 = (i3 | 0) > (i2 | 0) ? i3 : i2;
+ } else {
+  HEAP32[i20 >> 2] = i15;
+  HEAP32[i18 >> 2] = i14;
+  HEAP32[i5 + (i14 * 36 | 0) + 20 >> 2] = i6;
+  d19 = +HEAPF32[i10 >> 2];
+  d22 = +HEAPF32[i17 >> 2];
+  d19 = d19 < d22 ? d19 : d22;
+  d23 = +HEAPF32[i5 + (i7 * 36 | 0) + 4 >> 2];
+  d24 = +HEAPF32[i5 + (i14 * 36 | 0) + 4 >> 2];
+  d22 = +d19;
+  d24 = +(d23 < d24 ? d23 : d24);
+  i21 = i13;
+  HEAPF32[i21 >> 2] = d22;
+  HEAPF32[i21 + 4 >> 2] = d24;
+  d24 = +HEAPF32[i5 + (i7 * 36 | 0) + 8 >> 2];
+  d23 = +HEAPF32[i5 + (i14 * 36 | 0) + 8 >> 2];
+  d22 = +HEAPF32[i5 + (i7 * 36 | 0) + 12 >> 2];
+  d25 = +HEAPF32[i5 + (i14 * 36 | 0) + 12 >> 2];
+  d23 = +(d24 > d23 ? d24 : d23);
+  d24 = +(d22 > d25 ? d22 : d25);
+  i21 = i5 + (i6 * 36 | 0) + 8 | 0;
+  HEAPF32[i21 >> 2] = d23;
+  HEAPF32[i21 + 4 >> 2] = d24;
+  d24 = +HEAPF32[i16 >> 2];
+  d23 = +HEAPF32[i5 + (i6 * 36 | 0) + 4 >> 2];
+  d22 = +HEAPF32[i5 + (i15 * 36 | 0) + 4 >> 2];
+  d19 = +(d19 < d24 ? d19 : d24);
+  d22 = +(d23 < d22 ? d23 : d22);
+  i21 = i9;
+  HEAPF32[i21 >> 2] = d19;
+  HEAPF32[i21 + 4 >> 2] = d22;
+  d22 = +HEAPF32[i5 + (i6 * 36 | 0) + 8 >> 2];
+  d23 = +HEAPF32[i5 + (i15 * 36 | 0) + 8 >> 2];
+  d19 = +HEAPF32[i5 + (i6 * 36 | 0) + 12 >> 2];
+  d24 = +HEAPF32[i5 + (i15 * 36 | 0) + 12 >> 2];
+  d22 = +(d22 > d23 ? d22 : d23);
+  d25 = +(d19 > d24 ? d19 : d24);
+  i5 = i5 + (i8 * 36 | 0) + 8 | 0;
+  HEAPF32[i5 >> 2] = d22;
+  HEAPF32[i5 + 4 >> 2] = d25;
+  i3 = HEAP32[i3 >> 2] | 0;
+  i5 = HEAP32[i12 >> 2] | 0;
+  i3 = ((i3 | 0) > (i5 | 0) ? i3 : i5) + 1 | 0;
+  HEAP32[i2 >> 2] = i3;
+  i2 = HEAP32[i11 >> 2] | 0;
+  i2 = (i3 | 0) > (i2 | 0) ? i3 : i2;
+ }
+ HEAP32[i4 >> 2] = i2 + 1;
+ i21 = i8;
+ STACKTOP = i1;
+ return i21 | 0;
+}
+function __Z10b2DistanceP16b2DistanceOutputP14b2SimplexCachePK15b2DistanceInput(i2, i5, i3) {
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i4 = 0, i6 = 0, d7 = 0.0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, d16 = 0.0, d17 = 0.0, d18 = 0.0, d19 = 0.0, i20 = 0, d21 = 0.0, d22 = 0.0, i23 = 0, d24 = 0.0, d25 = 0.0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, d36 = 0.0, d37 = 0.0, d38 = 0.0, i39 = 0, i40 = 0, i41 = 0, i42 = 0, d43 = 0.0, d44 = 0.0, d45 = 0.0, i46 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 176 | 0;
+ i11 = i1 + 152 | 0;
+ i10 = i1 + 136 | 0;
+ i4 = i1 + 24 | 0;
+ i14 = i1 + 12 | 0;
+ i15 = i1;
+ HEAP32[652] = (HEAP32[652] | 0) + 1;
+ i9 = i3 + 28 | 0;
+ i31 = i3 + 56 | 0;
+ HEAP32[i11 + 0 >> 2] = HEAP32[i31 + 0 >> 2];
+ HEAP32[i11 + 4 >> 2] = HEAP32[i31 + 4 >> 2];
+ HEAP32[i11 + 8 >> 2] = HEAP32[i31 + 8 >> 2];
+ HEAP32[i11 + 12 >> 2] = HEAP32[i31 + 12 >> 2];
+ i31 = i3 + 72 | 0;
+ HEAP32[i10 + 0 >> 2] = HEAP32[i31 + 0 >> 2];
+ HEAP32[i10 + 4 >> 2] = HEAP32[i31 + 4 >> 2];
+ HEAP32[i10 + 8 >> 2] = HEAP32[i31 + 8 >> 2];
+ HEAP32[i10 + 12 >> 2] = HEAP32[i31 + 12 >> 2];
+ __ZN9b2Simplex9ReadCacheEPK14b2SimplexCachePK15b2DistanceProxyRK11b2TransformS5_S8_(i4, i5, i3, i11, i9, i10);
+ i9 = i4 + 108 | 0;
+ i31 = HEAP32[i9 >> 2] | 0;
+ if ((i31 | 0) == 3 | (i31 | 0) == 2 | (i31 | 0) == 1) {
+  i8 = i4 + 16 | 0;
+  i6 = i4 + 20 | 0;
+  d17 = +HEAPF32[i11 + 12 >> 2];
+  d18 = +HEAPF32[i11 + 8 >> 2];
+  i13 = i3 + 16 | 0;
+  i12 = i3 + 20 | 0;
+  d16 = +HEAPF32[i11 >> 2];
+  d21 = +HEAPF32[i11 + 4 >> 2];
+  d19 = +HEAPF32[i10 + 12 >> 2];
+  d22 = +HEAPF32[i10 + 8 >> 2];
+  i23 = i3 + 44 | 0;
+  i20 = i3 + 48 | 0;
+  d24 = +HEAPF32[i10 >> 2];
+  d25 = +HEAPF32[i10 + 4 >> 2];
+  i11 = i4 + 52 | 0;
+  i10 = i4 + 56 | 0;
+  i30 = i4 + 16 | 0;
+  i27 = i4 + 36 | 0;
+  i26 = i4 + 52 | 0;
+  i29 = i4 + 24 | 0;
+  i28 = i4 + 60 | 0;
+  i33 = 0;
+  L3 : while (1) {
+   i32 = (i31 | 0) > 0;
+   if (i32) {
+    i34 = 0;
+    do {
+     HEAP32[i14 + (i34 << 2) >> 2] = HEAP32[i4 + (i34 * 36 | 0) + 28 >> 2];
+     HEAP32[i15 + (i34 << 2) >> 2] = HEAP32[i4 + (i34 * 36 | 0) + 32 >> 2];
+     i34 = i34 + 1 | 0;
+    } while ((i34 | 0) != (i31 | 0));
+   }
+   do {
+    if ((i31 | 0) == 2) {
+     i46 = i30;
+     d45 = +HEAPF32[i46 >> 2];
+     d36 = +HEAPF32[i46 + 4 >> 2];
+     i46 = i26;
+     d38 = +HEAPF32[i46 >> 2];
+     d37 = +HEAPF32[i46 + 4 >> 2];
+     d43 = d38 - d45;
+     d44 = d37 - d36;
+     d36 = d45 * d43 + d36 * d44;
+     if (d36 >= -0.0) {
+      HEAPF32[i29 >> 2] = 1.0;
+      HEAP32[i9 >> 2] = 1;
+      i35 = 17;
+      break;
+     }
+     d37 = d38 * d43 + d37 * d44;
+     if (!(d37 <= 0.0)) {
+      d45 = 1.0 / (d37 - d36);
+      HEAPF32[i29 >> 2] = d37 * d45;
+      HEAPF32[i28 >> 2] = -(d36 * d45);
+      HEAP32[i9 >> 2] = 2;
+      i35 = 18;
+      break;
+     } else {
+      HEAPF32[i28 >> 2] = 1.0;
+      HEAP32[i9 >> 2] = 1;
+      i34 = i4 + 0 | 0;
+      i39 = i27 + 0 | 0;
+      i35 = i34 + 36 | 0;
+      do {
+       HEAP32[i34 >> 2] = HEAP32[i39 >> 2];
+       i34 = i34 + 4 | 0;
+       i39 = i39 + 4 | 0;
+      } while ((i34 | 0) < (i35 | 0));
+      i35 = 17;
+      break;
+     }
+    } else if ((i31 | 0) == 3) {
+     __ZN9b2Simplex6Solve3Ev(i4);
+     i34 = HEAP32[i9 >> 2] | 0;
+     if ((i34 | 0) == 1) {
+      i35 = 17;
+     } else if ((i34 | 0) == 0) {
+      i35 = 15;
+      break L3;
+     } else if ((i34 | 0) == 2) {
+      i35 = 18;
+     } else if ((i34 | 0) == 3) {
+      i35 = 42;
+      break L3;
+     } else {
+      i35 = 16;
+      break L3;
+     }
+    } else if ((i31 | 0) == 1) {
+     i35 = 17;
+    } else {
+     i35 = 13;
+     break L3;
+    }
+   } while (0);
+   do {
+    if ((i35 | 0) == 17) {
+     d36 = -+HEAPF32[i8 >> 2];
+     d37 = -+HEAPF32[i6 >> 2];
+     i34 = 1;
+    } else if ((i35 | 0) == 18) {
+     d44 = +HEAPF32[i8 >> 2];
+     d37 = +HEAPF32[i11 >> 2] - d44;
+     d45 = +HEAPF32[i6 >> 2];
+     d36 = +HEAPF32[i10 >> 2] - d45;
+     if (d44 * d36 - d37 * d45 > 0.0) {
+      d36 = -d36;
+      i34 = 2;
+      break;
+     } else {
+      d37 = -d37;
+      i34 = 2;
+      break;
+     }
+    }
+   } while (0);
+   if (d37 * d37 + d36 * d36 < 1.4210854715202004e-14) {
+    i35 = 42;
+    break;
+   }
+   i39 = i4 + (i34 * 36 | 0) | 0;
+   d44 = -d36;
+   d45 = -d37;
+   d43 = d17 * d44 + d18 * d45;
+   d44 = d17 * d45 - d18 * d44;
+   i40 = HEAP32[i13 >> 2] | 0;
+   i41 = HEAP32[i12 >> 2] | 0;
+   if ((i41 | 0) > 1) {
+    i42 = 0;
+    d45 = d44 * +HEAPF32[i40 + 4 >> 2] + d43 * +HEAPF32[i40 >> 2];
+    i46 = 1;
+    while (1) {
+     d38 = d43 * +HEAPF32[i40 + (i46 << 3) >> 2] + d44 * +HEAPF32[i40 + (i46 << 3) + 4 >> 2];
+     i35 = d38 > d45;
+     i42 = i35 ? i46 : i42;
+     i46 = i46 + 1 | 0;
+     if ((i46 | 0) == (i41 | 0)) {
+      break;
+     } else {
+      d45 = i35 ? d38 : d45;
+     }
+    }
+    i35 = i4 + (i34 * 36 | 0) + 28 | 0;
+    HEAP32[i35 >> 2] = i42;
+    if (!((i42 | 0) > -1)) {
+     i35 = 28;
+     break;
+    }
+   } else {
+    i35 = i4 + (i34 * 36 | 0) + 28 | 0;
+    HEAP32[i35 >> 2] = 0;
+    i42 = 0;
+   }
+   if ((i41 | 0) <= (i42 | 0)) {
+    i35 = 28;
+    break;
+   }
+   d45 = +HEAPF32[i40 + (i42 << 3) >> 2];
+   d43 = +HEAPF32[i40 + (i42 << 3) + 4 >> 2];
+   d38 = d16 + (d17 * d45 - d18 * d43);
+   d44 = +d38;
+   d43 = +(d45 * d18 + d17 * d43 + d21);
+   i40 = i39;
+   HEAPF32[i40 >> 2] = d44;
+   HEAPF32[i40 + 4 >> 2] = d43;
+   d43 = d36 * d19 + d37 * d22;
+   d44 = d37 * d19 - d36 * d22;
+   i40 = HEAP32[i23 >> 2] | 0;
+   i39 = HEAP32[i20 >> 2] | 0;
+   if ((i39 | 0) > 1) {
+    i41 = 0;
+    d37 = d44 * +HEAPF32[i40 + 4 >> 2] + d43 * +HEAPF32[i40 >> 2];
+    i42 = 1;
+    while (1) {
+     d36 = d43 * +HEAPF32[i40 + (i42 << 3) >> 2] + d44 * +HEAPF32[i40 + (i42 << 3) + 4 >> 2];
+     i46 = d36 > d37;
+     i41 = i46 ? i42 : i41;
+     i42 = i42 + 1 | 0;
+     if ((i42 | 0) == (i39 | 0)) {
+      break;
+     } else {
+      d37 = i46 ? d36 : d37;
+     }
+    }
+    i42 = i4 + (i34 * 36 | 0) + 32 | 0;
+    HEAP32[i42 >> 2] = i41;
+    if (!((i41 | 0) > -1)) {
+     i35 = 35;
+     break;
+    }
+   } else {
+    i42 = i4 + (i34 * 36 | 0) + 32 | 0;
+    HEAP32[i42 >> 2] = 0;
+    i41 = 0;
+   }
+   if ((i39 | 0) <= (i41 | 0)) {
+    i35 = 35;
+    break;
+   }
+   d37 = +HEAPF32[i40 + (i41 << 3) >> 2];
+   d45 = +HEAPF32[i40 + (i41 << 3) + 4 >> 2];
+   d44 = d24 + (d19 * d37 - d22 * d45);
+   d43 = +d44;
+   d45 = +(d37 * d22 + d19 * d45 + d25);
+   i46 = i4 + (i34 * 36 | 0) + 8 | 0;
+   HEAPF32[i46 >> 2] = d43;
+   HEAPF32[i46 + 4 >> 2] = d45;
+   d44 = +(d44 - d38);
+   d45 = +(+HEAPF32[i4 + (i34 * 36 | 0) + 12 >> 2] - +HEAPF32[i4 + (i34 * 36 | 0) + 4 >> 2]);
+   i46 = i4 + (i34 * 36 | 0) + 16 | 0;
+   HEAPF32[i46 >> 2] = d44;
+   HEAPF32[i46 + 4 >> 2] = d45;
+   i33 = i33 + 1 | 0;
+   HEAP32[654] = (HEAP32[654] | 0) + 1;
+   if (i32) {
+    i34 = HEAP32[i35 >> 2] | 0;
+    i32 = 0;
+    do {
+     if ((i34 | 0) == (HEAP32[i14 + (i32 << 2) >> 2] | 0) ? (HEAP32[i42 >> 2] | 0) == (HEAP32[i15 + (i32 << 2) >> 2] | 0) : 0) {
+      i35 = 42;
+      break L3;
+     }
+     i32 = i32 + 1 | 0;
+    } while ((i32 | 0) < (i31 | 0));
+   }
+   i31 = (HEAP32[i9 >> 2] | 0) + 1 | 0;
+   HEAP32[i9 >> 2] = i31;
+   if ((i33 | 0) >= 20) {
+    i35 = 42;
+    break;
+   }
+  }
+  if ((i35 | 0) == 13) {
+   ___assert_fail(2712, 2672, 498, 2720);
+  } else if ((i35 | 0) == 15) {
+   ___assert_fail(2712, 2672, 194, 2856);
+  } else if ((i35 | 0) == 16) {
+   ___assert_fail(2712, 2672, 207, 2856);
+  } else if ((i35 | 0) == 28) {
+   ___assert_fail(2776, 2808, 103, 2840);
+  } else if ((i35 | 0) == 35) {
+   ___assert_fail(2776, 2808, 103, 2840);
+  } else if ((i35 | 0) == 42) {
+   i12 = HEAP32[656] | 0;
+   HEAP32[656] = (i12 | 0) > (i33 | 0) ? i12 : i33;
+   i14 = i2 + 8 | 0;
+   __ZNK9b2Simplex16GetWitnessPointsEP6b2Vec2S1_(i4, i2, i14);
+   d44 = +HEAPF32[i2 >> 2] - +HEAPF32[i14 >> 2];
+   i13 = i2 + 4 | 0;
+   i12 = i2 + 12 | 0;
+   d45 = +HEAPF32[i13 >> 2] - +HEAPF32[i12 >> 2];
+   i15 = i2 + 16 | 0;
+   HEAPF32[i15 >> 2] = +Math_sqrt(+(d44 * d44 + d45 * d45));
+   HEAP32[i2 + 20 >> 2] = i33;
+   i9 = HEAP32[i9 >> 2] | 0;
+   if ((i9 | 0) == 2) {
+    d45 = +HEAPF32[i8 >> 2] - +HEAPF32[i11 >> 2];
+    d7 = +HEAPF32[i6 >> 2] - +HEAPF32[i10 >> 2];
+    d7 = +Math_sqrt(+(d45 * d45 + d7 * d7));
+   } else if ((i9 | 0) == 3) {
+    d7 = +HEAPF32[i8 >> 2];
+    d45 = +HEAPF32[i6 >> 2];
+    d7 = (+HEAPF32[i11 >> 2] - d7) * (+HEAPF32[i4 + 92 >> 2] - d45) - (+HEAPF32[i10 >> 2] - d45) * (+HEAPF32[i4 + 88 >> 2] - d7);
+   } else if ((i9 | 0) == 1) {
+    d7 = 0.0;
+   } else if ((i9 | 0) == 0) {
+    ___assert_fail(2712, 2672, 246, 2736);
+   } else {
+    ___assert_fail(2712, 2672, 259, 2736);
+   }
+   HEAPF32[i5 >> 2] = d7;
+   HEAP16[i5 + 4 >> 1] = i9;
+   i6 = 0;
+   do {
+    HEAP8[i5 + i6 + 6 | 0] = HEAP32[i4 + (i6 * 36 | 0) + 28 >> 2];
+    HEAP8[i5 + i6 + 9 | 0] = HEAP32[i4 + (i6 * 36 | 0) + 32 >> 2];
+    i6 = i6 + 1 | 0;
+   } while ((i6 | 0) < (i9 | 0));
+   if ((HEAP8[i3 + 88 | 0] | 0) == 0) {
+    STACKTOP = i1;
+    return;
+   }
+   d7 = +HEAPF32[i3 + 24 >> 2];
+   d16 = +HEAPF32[i3 + 52 >> 2];
+   d18 = +HEAPF32[i15 >> 2];
+   d17 = d7 + d16;
+   if (!(d18 > d17 & d18 > 1.1920928955078125e-7)) {
+    d44 = +((+HEAPF32[i2 >> 2] + +HEAPF32[i14 >> 2]) * .5);
+    d45 = +((+HEAPF32[i13 >> 2] + +HEAPF32[i12 >> 2]) * .5);
+    i46 = i2;
+    HEAPF32[i46 >> 2] = d44;
+    HEAPF32[i46 + 4 >> 2] = d45;
+    i46 = i14;
+    HEAPF32[i46 >> 2] = d44;
+    HEAPF32[i46 + 4 >> 2] = d45;
+    HEAPF32[i15 >> 2] = 0.0;
+    STACKTOP = i1;
+    return;
+   }
+   HEAPF32[i15 >> 2] = d18 - d17;
+   d18 = +HEAPF32[i14 >> 2];
+   d21 = +HEAPF32[i2 >> 2];
+   d24 = d18 - d21;
+   d17 = +HEAPF32[i12 >> 2];
+   d19 = +HEAPF32[i13 >> 2];
+   d22 = d17 - d19;
+   d25 = +Math_sqrt(+(d24 * d24 + d22 * d22));
+   if (!(d25 < 1.1920928955078125e-7)) {
+    d45 = 1.0 / d25;
+    d24 = d24 * d45;
+    d22 = d22 * d45;
+   }
+   HEAPF32[i2 >> 2] = d7 * d24 + d21;
+   HEAPF32[i13 >> 2] = d7 * d22 + d19;
+   HEAPF32[i14 >> 2] = d18 - d16 * d24;
+   HEAPF32[i12 >> 2] = d17 - d16 * d22;
+   STACKTOP = i1;
+   return;
+  }
+ } else if ((i31 | 0) == 0) {
+  ___assert_fail(2712, 2672, 194, 2856);
+ } else {
+  ___assert_fail(2712, 2672, 207, 2856);
+ }
+}
+function __ZN8b2Island5SolveEP9b2ProfileRK10b2TimeStepRK6b2Vec2b(i4, i8, i11, i17, i7) {
+ i4 = i4 | 0;
+ i8 = i8 | 0;
+ i11 = i11 | 0;
+ i17 = i17 | 0;
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, d5 = 0.0, i6 = 0, i9 = 0, i10 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i18 = 0, i19 = 0, i20 = 0, d21 = 0.0, i22 = 0, d23 = 0.0, d24 = 0.0, d25 = 0.0, d26 = 0.0, d27 = 0.0, d28 = 0.0, d29 = 0.0, i30 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 160 | 0;
+ i6 = i3 + 128 | 0;
+ i9 = i3 + 148 | 0;
+ i10 = i3 + 96 | 0;
+ i16 = i3 + 52 | 0;
+ i2 = i3;
+ __ZN7b2TimerC2Ev(i9);
+ d5 = +HEAPF32[i11 >> 2];
+ i1 = i4 + 28 | 0;
+ if ((HEAP32[i1 >> 2] | 0) > 0) {
+  i13 = i4 + 8 | 0;
+  i12 = i17 + 4 | 0;
+  i15 = i4 + 20 | 0;
+  i14 = i4 + 24 | 0;
+  i19 = 0;
+  do {
+   i22 = HEAP32[(HEAP32[i13 >> 2] | 0) + (i19 << 2) >> 2] | 0;
+   i18 = i22 + 44 | 0;
+   i20 = HEAP32[i18 >> 2] | 0;
+   i18 = HEAP32[i18 + 4 >> 2] | 0;
+   d21 = +HEAPF32[i22 + 56 >> 2];
+   i30 = i22 + 64 | 0;
+   d27 = +HEAPF32[i30 >> 2];
+   d24 = +HEAPF32[i30 + 4 >> 2];
+   d23 = +HEAPF32[i22 + 72 >> 2];
+   i30 = i22 + 36 | 0;
+   HEAP32[i30 >> 2] = i20;
+   HEAP32[i30 + 4 >> 2] = i18;
+   HEAPF32[i22 + 52 >> 2] = d21;
+   if ((HEAP32[i22 >> 2] | 0) == 2) {
+    d25 = +HEAPF32[i22 + 140 >> 2];
+    d26 = +HEAPF32[i22 + 120 >> 2];
+    d28 = 1.0 - d5 * +HEAPF32[i22 + 132 >> 2];
+    d28 = d28 < 1.0 ? d28 : 1.0;
+    d28 = d28 < 0.0 ? 0.0 : d28;
+    d29 = 1.0 - d5 * +HEAPF32[i22 + 136 >> 2];
+    d29 = d29 < 1.0 ? d29 : 1.0;
+    d27 = (d27 + d5 * (d25 * +HEAPF32[i17 >> 2] + d26 * +HEAPF32[i22 + 76 >> 2])) * d28;
+    d24 = (d24 + d5 * (d25 * +HEAPF32[i12 >> 2] + d26 * +HEAPF32[i22 + 80 >> 2])) * d28;
+    d23 = (d23 + d5 * +HEAPF32[i22 + 128 >> 2] * +HEAPF32[i22 + 84 >> 2]) * (d29 < 0.0 ? 0.0 : d29);
+   }
+   i30 = (HEAP32[i15 >> 2] | 0) + (i19 * 12 | 0) | 0;
+   HEAP32[i30 >> 2] = i20;
+   HEAP32[i30 + 4 >> 2] = i18;
+   HEAPF32[(HEAP32[i15 >> 2] | 0) + (i19 * 12 | 0) + 8 >> 2] = d21;
+   d28 = +d27;
+   d29 = +d24;
+   i30 = (HEAP32[i14 >> 2] | 0) + (i19 * 12 | 0) | 0;
+   HEAPF32[i30 >> 2] = d28;
+   HEAPF32[i30 + 4 >> 2] = d29;
+   HEAPF32[(HEAP32[i14 >> 2] | 0) + (i19 * 12 | 0) + 8 >> 2] = d23;
+   i19 = i19 + 1 | 0;
+  } while ((i19 | 0) < (HEAP32[i1 >> 2] | 0));
+ } else {
+  i14 = i4 + 24 | 0;
+  i15 = i4 + 20 | 0;
+ }
+ HEAP32[i10 + 0 >> 2] = HEAP32[i11 + 0 >> 2];
+ HEAP32[i10 + 4 >> 2] = HEAP32[i11 + 4 >> 2];
+ HEAP32[i10 + 8 >> 2] = HEAP32[i11 + 8 >> 2];
+ HEAP32[i10 + 12 >> 2] = HEAP32[i11 + 12 >> 2];
+ HEAP32[i10 + 16 >> 2] = HEAP32[i11 + 16 >> 2];
+ HEAP32[i10 + 20 >> 2] = HEAP32[i11 + 20 >> 2];
+ i22 = HEAP32[i15 >> 2] | 0;
+ HEAP32[i10 + 24 >> 2] = i22;
+ i30 = HEAP32[i14 >> 2] | 0;
+ HEAP32[i10 + 28 >> 2] = i30;
+ HEAP32[i16 + 0 >> 2] = HEAP32[i11 + 0 >> 2];
+ HEAP32[i16 + 4 >> 2] = HEAP32[i11 + 4 >> 2];
+ HEAP32[i16 + 8 >> 2] = HEAP32[i11 + 8 >> 2];
+ HEAP32[i16 + 12 >> 2] = HEAP32[i11 + 12 >> 2];
+ HEAP32[i16 + 16 >> 2] = HEAP32[i11 + 16 >> 2];
+ HEAP32[i16 + 20 >> 2] = HEAP32[i11 + 20 >> 2];
+ i13 = i4 + 12 | 0;
+ HEAP32[i16 + 24 >> 2] = HEAP32[i13 >> 2];
+ i12 = i4 + 36 | 0;
+ HEAP32[i16 + 28 >> 2] = HEAP32[i12 >> 2];
+ HEAP32[i16 + 32 >> 2] = i22;
+ HEAP32[i16 + 36 >> 2] = i30;
+ HEAP32[i16 + 40 >> 2] = HEAP32[i4 >> 2];
+ __ZN15b2ContactSolverC2EP18b2ContactSolverDef(i2, i16);
+ __ZN15b2ContactSolver29InitializeVelocityConstraintsEv(i2);
+ if ((HEAP8[i11 + 20 | 0] | 0) != 0) {
+  __ZN15b2ContactSolver9WarmStartEv(i2);
+ }
+ i16 = i4 + 32 | 0;
+ if ((HEAP32[i16 >> 2] | 0) > 0) {
+  i18 = i4 + 16 | 0;
+  i17 = 0;
+  do {
+   i30 = HEAP32[(HEAP32[i18 >> 2] | 0) + (i17 << 2) >> 2] | 0;
+   FUNCTION_TABLE_vii[HEAP32[(HEAP32[i30 >> 2] | 0) + 28 >> 2] & 15](i30, i10);
+   i17 = i17 + 1 | 0;
+  } while ((i17 | 0) < (HEAP32[i16 >> 2] | 0));
+ }
+ HEAPF32[i8 + 12 >> 2] = +__ZNK7b2Timer15GetMillisecondsEv(i9);
+ i17 = i11 + 12 | 0;
+ if ((HEAP32[i17 >> 2] | 0) > 0) {
+  i20 = i4 + 16 | 0;
+  i19 = 0;
+  do {
+   if ((HEAP32[i16 >> 2] | 0) > 0) {
+    i18 = 0;
+    do {
+     i30 = HEAP32[(HEAP32[i20 >> 2] | 0) + (i18 << 2) >> 2] | 0;
+     FUNCTION_TABLE_vii[HEAP32[(HEAP32[i30 >> 2] | 0) + 32 >> 2] & 15](i30, i10);
+     i18 = i18 + 1 | 0;
+    } while ((i18 | 0) < (HEAP32[i16 >> 2] | 0));
+   }
+   __ZN15b2ContactSolver24SolveVelocityConstraintsEv(i2);
+   i19 = i19 + 1 | 0;
+  } while ((i19 | 0) < (HEAP32[i17 >> 2] | 0));
+ }
+ __ZN15b2ContactSolver13StoreImpulsesEv(i2);
+ HEAPF32[i8 + 16 >> 2] = +__ZNK7b2Timer15GetMillisecondsEv(i9);
+ if ((HEAP32[i1 >> 2] | 0) > 0) {
+  i19 = HEAP32[i14 >> 2] | 0;
+  i18 = 0;
+  do {
+   i30 = HEAP32[i15 >> 2] | 0;
+   i17 = i30 + (i18 * 12 | 0) | 0;
+   i22 = i17;
+   d23 = +HEAPF32[i22 >> 2];
+   d21 = +HEAPF32[i22 + 4 >> 2];
+   d24 = +HEAPF32[i30 + (i18 * 12 | 0) + 8 >> 2];
+   i30 = i19 + (i18 * 12 | 0) | 0;
+   d26 = +HEAPF32[i30 >> 2];
+   d27 = +HEAPF32[i30 + 4 >> 2];
+   d25 = +HEAPF32[i19 + (i18 * 12 | 0) + 8 >> 2];
+   d29 = d5 * d26;
+   d28 = d5 * d27;
+   d28 = d29 * d29 + d28 * d28;
+   if (d28 > 4.0) {
+    d29 = 2.0 / +Math_sqrt(+d28);
+    d26 = d26 * d29;
+    d27 = d27 * d29;
+   }
+   d28 = d5 * d25;
+   if (d28 * d28 > 2.4674012660980225) {
+    if (!(d28 > 0.0)) {
+     d28 = -d28;
+    }
+    d25 = d25 * (1.5707963705062866 / d28);
+   }
+   d29 = +(d23 + d5 * d26);
+   d28 = +(d21 + d5 * d27);
+   i19 = i17;
+   HEAPF32[i19 >> 2] = d29;
+   HEAPF32[i19 + 4 >> 2] = d28;
+   HEAPF32[(HEAP32[i15 >> 2] | 0) + (i18 * 12 | 0) + 8 >> 2] = d24 + d5 * d25;
+   d28 = +d26;
+   d29 = +d27;
+   i19 = (HEAP32[i14 >> 2] | 0) + (i18 * 12 | 0) | 0;
+   HEAPF32[i19 >> 2] = d28;
+   HEAPF32[i19 + 4 >> 2] = d29;
+   i19 = HEAP32[i14 >> 2] | 0;
+   HEAPF32[i19 + (i18 * 12 | 0) + 8 >> 2] = d25;
+   i18 = i18 + 1 | 0;
+  } while ((i18 | 0) < (HEAP32[i1 >> 2] | 0));
+ }
+ i11 = i11 + 16 | 0;
+ L41 : do {
+  if ((HEAP32[i11 >> 2] | 0) > 0) {
+   i17 = i4 + 16 | 0;
+   i19 = 0;
+   while (1) {
+    i18 = __ZN15b2ContactSolver24SolvePositionConstraintsEv(i2) | 0;
+    if ((HEAP32[i16 >> 2] | 0) > 0) {
+     i20 = 0;
+     i22 = 1;
+     do {
+      i30 = HEAP32[(HEAP32[i17 >> 2] | 0) + (i20 << 2) >> 2] | 0;
+      i22 = i22 & (FUNCTION_TABLE_iii[HEAP32[(HEAP32[i30 >> 2] | 0) + 36 >> 2] & 3](i30, i10) | 0);
+      i20 = i20 + 1 | 0;
+     } while ((i20 | 0) < (HEAP32[i16 >> 2] | 0));
+    } else {
+     i22 = 1;
+    }
+    i19 = i19 + 1 | 0;
+    if (i18 & i22) {
+     i10 = 0;
+     break L41;
+    }
+    if ((i19 | 0) >= (HEAP32[i11 >> 2] | 0)) {
+     i10 = 1;
+     break;
+    }
+   }
+  } else {
+   i10 = 1;
+  }
+ } while (0);
+ if ((HEAP32[i1 >> 2] | 0) > 0) {
+  i11 = i4 + 8 | 0;
+  i16 = 0;
+  do {
+   i30 = HEAP32[(HEAP32[i11 >> 2] | 0) + (i16 << 2) >> 2] | 0;
+   i22 = (HEAP32[i15 >> 2] | 0) + (i16 * 12 | 0) | 0;
+   i20 = HEAP32[i22 >> 2] | 0;
+   i22 = HEAP32[i22 + 4 >> 2] | 0;
+   i17 = i30 + 44 | 0;
+   HEAP32[i17 >> 2] = i20;
+   HEAP32[i17 + 4 >> 2] = i22;
+   d27 = +HEAPF32[(HEAP32[i15 >> 2] | 0) + (i16 * 12 | 0) + 8 >> 2];
+   HEAPF32[i30 + 56 >> 2] = d27;
+   i17 = (HEAP32[i14 >> 2] | 0) + (i16 * 12 | 0) | 0;
+   i18 = HEAP32[i17 + 4 >> 2] | 0;
+   i19 = i30 + 64 | 0;
+   HEAP32[i19 >> 2] = HEAP32[i17 >> 2];
+   HEAP32[i19 + 4 >> 2] = i18;
+   HEAPF32[i30 + 72 >> 2] = +HEAPF32[(HEAP32[i14 >> 2] | 0) + (i16 * 12 | 0) + 8 >> 2];
+   d25 = +Math_sin(+d27);
+   HEAPF32[i30 + 20 >> 2] = d25;
+   d27 = +Math_cos(+d27);
+   HEAPF32[i30 + 24 >> 2] = d27;
+   d26 = +HEAPF32[i30 + 28 >> 2];
+   d29 = +HEAPF32[i30 + 32 >> 2];
+   d28 = (HEAP32[tempDoublePtr >> 2] = i20, +HEAPF32[tempDoublePtr >> 2]) - (d27 * d26 - d25 * d29);
+   d29 = (HEAP32[tempDoublePtr >> 2] = i22, +HEAPF32[tempDoublePtr >> 2]) - (d25 * d26 + d27 * d29);
+   d28 = +d28;
+   d29 = +d29;
+   i30 = i30 + 12 | 0;
+   HEAPF32[i30 >> 2] = d28;
+   HEAPF32[i30 + 4 >> 2] = d29;
+   i16 = i16 + 1 | 0;
+  } while ((i16 | 0) < (HEAP32[i1 >> 2] | 0));
+ }
+ HEAPF32[i8 + 20 >> 2] = +__ZNK7b2Timer15GetMillisecondsEv(i9);
+ i9 = HEAP32[i2 + 40 >> 2] | 0;
+ i8 = i4 + 4 | 0;
+ if ((HEAP32[i8 >> 2] | 0) != 0 ? (HEAP32[i12 >> 2] | 0) > 0 : 0) {
+  i11 = i6 + 16 | 0;
+  i14 = 0;
+  do {
+   i15 = HEAP32[(HEAP32[i13 >> 2] | 0) + (i14 << 2) >> 2] | 0;
+   i16 = HEAP32[i9 + (i14 * 152 | 0) + 144 >> 2] | 0;
+   HEAP32[i11 >> 2] = i16;
+   if ((i16 | 0) > 0) {
+    i17 = 0;
+    do {
+     HEAPF32[i6 + (i17 << 2) >> 2] = +HEAPF32[i9 + (i14 * 152 | 0) + (i17 * 36 | 0) + 16 >> 2];
+     HEAPF32[i6 + (i17 << 2) + 8 >> 2] = +HEAPF32[i9 + (i14 * 152 | 0) + (i17 * 36 | 0) + 20 >> 2];
+     i17 = i17 + 1 | 0;
+    } while ((i17 | 0) != (i16 | 0));
+   }
+   i30 = HEAP32[i8 >> 2] | 0;
+   FUNCTION_TABLE_viii[HEAP32[(HEAP32[i30 >> 2] | 0) + 20 >> 2] & 3](i30, i15, i6);
+   i14 = i14 + 1 | 0;
+  } while ((i14 | 0) < (HEAP32[i12 >> 2] | 0));
+ }
+ if (!i7) {
+  __ZN15b2ContactSolverD2Ev(i2);
+  STACKTOP = i3;
+  return;
+ }
+ i7 = HEAP32[i1 >> 2] | 0;
+ i6 = (i7 | 0) > 0;
+ if (i6) {
+  i8 = HEAP32[i4 + 8 >> 2] | 0;
+  i9 = 0;
+  d21 = 3.4028234663852886e+38;
+  do {
+   i11 = HEAP32[i8 + (i9 << 2) >> 2] | 0;
+   do {
+    if ((HEAP32[i11 >> 2] | 0) != 0) {
+     if ((!((HEAP16[i11 + 4 >> 1] & 4) == 0) ? (d29 = +HEAPF32[i11 + 72 >> 2], !(d29 * d29 > .001218469929881394)) : 0) ? (d28 = +HEAPF32[i11 + 64 >> 2], d29 = +HEAPF32[i11 + 68 >> 2], !(d28 * d28 + d29 * d29 > 9999999747378752.0e-20)) : 0) {
+      i30 = i11 + 144 | 0;
+      d23 = d5 + +HEAPF32[i30 >> 2];
+      HEAPF32[i30 >> 2] = d23;
+      d21 = d21 < d23 ? d21 : d23;
+      break;
+     }
+     HEAPF32[i11 + 144 >> 2] = 0.0;
+     d21 = 0.0;
+    }
+   } while (0);
+   i9 = i9 + 1 | 0;
+  } while ((i9 | 0) < (i7 | 0));
+ } else {
+  d21 = 3.4028234663852886e+38;
+ }
+ if (!(d21 >= .5) | i10 | i6 ^ 1) {
+  __ZN15b2ContactSolverD2Ev(i2);
+  STACKTOP = i3;
+  return;
+ }
+ i4 = i4 + 8 | 0;
+ i6 = 0;
+ do {
+  i30 = HEAP32[(HEAP32[i4 >> 2] | 0) + (i6 << 2) >> 2] | 0;
+  i22 = i30 + 4 | 0;
+  HEAP16[i22 >> 1] = HEAP16[i22 >> 1] & 65533;
+  HEAPF32[i30 + 144 >> 2] = 0.0;
+  i30 = i30 + 64 | 0;
+  HEAP32[i30 + 0 >> 2] = 0;
+  HEAP32[i30 + 4 >> 2] = 0;
+  HEAP32[i30 + 8 >> 2] = 0;
+  HEAP32[i30 + 12 >> 2] = 0;
+  HEAP32[i30 + 16 >> 2] = 0;
+  HEAP32[i30 + 20 >> 2] = 0;
+  i6 = i6 + 1 | 0;
+ } while ((i6 | 0) < (HEAP32[i1 >> 2] | 0));
+ __ZN15b2ContactSolverD2Ev(i2);
+ STACKTOP = i3;
+ return;
+}
+function __ZN15b2ContactSolver24SolveVelocityConstraintsEv(i4) {
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, d9 = 0.0, d10 = 0.0, d11 = 0.0, d12 = 0.0, d13 = 0.0, d14 = 0.0, d15 = 0.0, d16 = 0.0, d17 = 0.0, d18 = 0.0, i19 = 0, d20 = 0.0, d21 = 0.0, i22 = 0, d23 = 0.0, d24 = 0.0, d25 = 0.0, d26 = 0.0, d27 = 0.0, d28 = 0.0, d29 = 0.0, d30 = 0.0, d31 = 0.0, i32 = 0, i33 = 0, d34 = 0.0, d35 = 0.0, d36 = 0.0, d37 = 0.0, d38 = 0.0, d39 = 0.0, d40 = 0.0, i41 = 0, i42 = 0, d43 = 0.0, d44 = 0.0;
+ i1 = STACKTOP;
+ i2 = i4 + 48 | 0;
+ if ((HEAP32[i2 >> 2] | 0) <= 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i3 = i4 + 40 | 0;
+ i4 = i4 + 28 | 0;
+ i42 = HEAP32[i4 >> 2] | 0;
+ i5 = 0;
+ L4 : while (1) {
+  i19 = HEAP32[i3 >> 2] | 0;
+  i22 = i19 + (i5 * 152 | 0) | 0;
+  i8 = HEAP32[i19 + (i5 * 152 | 0) + 112 >> 2] | 0;
+  i6 = HEAP32[i19 + (i5 * 152 | 0) + 116 >> 2] | 0;
+  d12 = +HEAPF32[i19 + (i5 * 152 | 0) + 120 >> 2];
+  d10 = +HEAPF32[i19 + (i5 * 152 | 0) + 128 >> 2];
+  d11 = +HEAPF32[i19 + (i5 * 152 | 0) + 124 >> 2];
+  d9 = +HEAPF32[i19 + (i5 * 152 | 0) + 132 >> 2];
+  i32 = i19 + (i5 * 152 | 0) + 144 | 0;
+  i33 = HEAP32[i32 >> 2] | 0;
+  i7 = i42 + (i8 * 12 | 0) | 0;
+  i41 = i7;
+  d21 = +HEAPF32[i41 >> 2];
+  d20 = +HEAPF32[i41 + 4 >> 2];
+  i41 = i42 + (i6 * 12 | 0) | 0;
+  d14 = +HEAPF32[i41 >> 2];
+  d13 = +HEAPF32[i41 + 4 >> 2];
+  i41 = i19 + (i5 * 152 | 0) + 72 | 0;
+  d17 = +HEAPF32[i41 >> 2];
+  d16 = +HEAPF32[i41 + 4 >> 2];
+  d23 = -d17;
+  d24 = +HEAPF32[i19 + (i5 * 152 | 0) + 136 >> 2];
+  if ((i33 + -1 | 0) >>> 0 < 2) {
+   i41 = 0;
+   d18 = +HEAPF32[i42 + (i8 * 12 | 0) + 8 >> 2];
+   d15 = +HEAPF32[i42 + (i6 * 12 | 0) + 8 >> 2];
+  } else {
+   i2 = 4;
+   break;
+  }
+  do {
+   d30 = +HEAPF32[i19 + (i5 * 152 | 0) + (i41 * 36 | 0) + 12 >> 2];
+   d25 = +HEAPF32[i19 + (i5 * 152 | 0) + (i41 * 36 | 0) + 8 >> 2];
+   d26 = +HEAPF32[i19 + (i5 * 152 | 0) + (i41 * 36 | 0) + 4 >> 2];
+   d27 = +HEAPF32[i19 + (i5 * 152 | 0) + (i41 * 36 | 0) >> 2];
+   d34 = d24 * +HEAPF32[i19 + (i5 * 152 | 0) + (i41 * 36 | 0) + 16 >> 2];
+   i42 = i19 + (i5 * 152 | 0) + (i41 * 36 | 0) + 20 | 0;
+   d28 = +HEAPF32[i42 >> 2];
+   d31 = d28 - +HEAPF32[i19 + (i5 * 152 | 0) + (i41 * 36 | 0) + 28 >> 2] * (d16 * (d14 - d15 * d30 - d21 + d18 * d26) + (d13 + d15 * d25 - d20 - d18 * d27) * d23);
+   d29 = -d34;
+   d31 = d31 < d34 ? d31 : d34;
+   d40 = d31 < d29 ? d29 : d31;
+   d39 = d40 - d28;
+   HEAPF32[i42 >> 2] = d40;
+   d40 = d16 * d39;
+   d39 = d39 * d23;
+   d21 = d21 - d12 * d40;
+   d20 = d20 - d12 * d39;
+   d18 = d18 - d10 * (d27 * d39 - d26 * d40);
+   d14 = d14 + d11 * d40;
+   d13 = d13 + d11 * d39;
+   d15 = d15 + d9 * (d25 * d39 - d30 * d40);
+   i41 = i41 + 1 | 0;
+  } while ((i41 | 0) != (i33 | 0));
+  do {
+   if ((HEAP32[i32 >> 2] | 0) != 1) {
+    i32 = i19 + (i5 * 152 | 0) + 16 | 0;
+    d31 = +HEAPF32[i32 >> 2];
+    i33 = i19 + (i5 * 152 | 0) + 52 | 0;
+    d34 = +HEAPF32[i33 >> 2];
+    if (!(d31 >= 0.0) | !(d34 >= 0.0)) {
+     i2 = 9;
+     break L4;
+    }
+    d23 = +HEAPF32[i19 + (i5 * 152 | 0) + 12 >> 2];
+    d24 = +HEAPF32[i19 + (i5 * 152 | 0) + 8 >> 2];
+    d26 = +HEAPF32[i19 + (i5 * 152 | 0) + 4 >> 2];
+    d30 = +HEAPF32[i22 >> 2];
+    d27 = +HEAPF32[i19 + (i5 * 152 | 0) + 48 >> 2];
+    d25 = +HEAPF32[i19 + (i5 * 152 | 0) + 44 >> 2];
+    d28 = +HEAPF32[i19 + (i5 * 152 | 0) + 40 >> 2];
+    d29 = +HEAPF32[i19 + (i5 * 152 | 0) + 36 >> 2];
+    d37 = +HEAPF32[i19 + (i5 * 152 | 0) + 104 >> 2];
+    d38 = +HEAPF32[i19 + (i5 * 152 | 0) + 100 >> 2];
+    d35 = d17 * (d14 - d15 * d23 - d21 + d18 * d26) + d16 * (d13 + d15 * d24 - d20 - d18 * d30) - +HEAPF32[i19 + (i5 * 152 | 0) + 32 >> 2] - (d31 * +HEAPF32[i19 + (i5 * 152 | 0) + 96 >> 2] + d34 * d37);
+    d36 = d17 * (d14 - d15 * d27 - d21 + d18 * d28) + d16 * (d13 + d15 * d25 - d20 - d18 * d29) - +HEAPF32[i19 + (i5 * 152 | 0) + 68 >> 2] - (d31 * d38 + d34 * +HEAPF32[i19 + (i5 * 152 | 0) + 108 >> 2]);
+    d44 = +HEAPF32[i19 + (i5 * 152 | 0) + 80 >> 2] * d35 + +HEAPF32[i19 + (i5 * 152 | 0) + 88 >> 2] * d36;
+    d43 = d35 * +HEAPF32[i19 + (i5 * 152 | 0) + 84 >> 2] + d36 * +HEAPF32[i19 + (i5 * 152 | 0) + 92 >> 2];
+    d40 = -d44;
+    d39 = -d43;
+    if (!(!(d44 <= -0.0) | !(d43 <= -0.0))) {
+     d37 = d40 - d31;
+     d43 = d39 - d34;
+     d38 = d17 * d37;
+     d37 = d16 * d37;
+     d44 = d17 * d43;
+     d43 = d16 * d43;
+     d35 = d38 + d44;
+     d36 = d37 + d43;
+     HEAPF32[i32 >> 2] = d40;
+     HEAPF32[i33 >> 2] = d39;
+     d21 = d21 - d12 * d35;
+     d20 = d20 - d12 * d36;
+     d14 = d14 + d11 * d35;
+     d13 = d13 + d11 * d36;
+     d18 = d18 - d10 * (d30 * d37 - d26 * d38 + (d29 * d43 - d28 * d44));
+     d15 = d15 + d9 * (d24 * d37 - d23 * d38 + (d25 * d43 - d27 * d44));
+     break;
+    }
+    d44 = d35 * +HEAPF32[i19 + (i5 * 152 | 0) + 24 >> 2];
+    d39 = -d44;
+    if (d44 <= -0.0 ? d36 + d38 * d39 >= 0.0 : 0) {
+     d38 = d39 - d31;
+     d43 = 0.0 - d34;
+     d40 = d17 * d38;
+     d38 = d16 * d38;
+     d44 = d17 * d43;
+     d43 = d16 * d43;
+     d36 = d44 + d40;
+     d37 = d43 + d38;
+     HEAPF32[i32 >> 2] = d39;
+     HEAPF32[i33 >> 2] = 0.0;
+     d21 = d21 - d12 * d36;
+     d20 = d20 - d12 * d37;
+     d14 = d14 + d11 * d36;
+     d13 = d13 + d11 * d37;
+     d18 = d18 - d10 * (d38 * d30 - d40 * d26 + (d43 * d29 - d44 * d28));
+     d15 = d15 + d9 * (d38 * d24 - d40 * d23 + (d43 * d25 - d44 * d27));
+     break;
+    }
+    d44 = d36 * +HEAPF32[i19 + (i5 * 152 | 0) + 60 >> 2];
+    d38 = -d44;
+    if (d44 <= -0.0 ? d35 + d37 * d38 >= 0.0 : 0) {
+     d39 = 0.0 - d31;
+     d43 = d38 - d34;
+     d40 = d17 * d39;
+     d39 = d16 * d39;
+     d44 = d17 * d43;
+     d43 = d16 * d43;
+     d36 = d40 + d44;
+     d37 = d39 + d43;
+     HEAPF32[i32 >> 2] = 0.0;
+     HEAPF32[i33 >> 2] = d38;
+     d21 = d21 - d12 * d36;
+     d20 = d20 - d12 * d37;
+     d14 = d14 + d11 * d36;
+     d13 = d13 + d11 * d37;
+     d18 = d18 - d10 * (d39 * d30 - d40 * d26 + (d43 * d29 - d44 * d28));
+     d15 = d15 + d9 * (d39 * d24 - d40 * d23 + (d43 * d25 - d44 * d27));
+     break;
+    }
+    if (!(!(d35 >= 0.0) | !(d36 >= 0.0))) {
+     d39 = 0.0 - d31;
+     d43 = 0.0 - d34;
+     d40 = d17 * d39;
+     d39 = d16 * d39;
+     d44 = d17 * d43;
+     d43 = d16 * d43;
+     d37 = d40 + d44;
+     d38 = d39 + d43;
+     HEAPF32[i32 >> 2] = 0.0;
+     HEAPF32[i33 >> 2] = 0.0;
+     d21 = d21 - d12 * d37;
+     d20 = d20 - d12 * d38;
+     d14 = d14 + d11 * d37;
+     d13 = d13 + d11 * d38;
+     d18 = d18 - d10 * (d39 * d30 - d40 * d26 + (d43 * d29 - d44 * d28));
+     d15 = d15 + d9 * (d39 * d24 - d40 * d23 + (d43 * d25 - d44 * d27));
+    }
+   } else {
+    d23 = +HEAPF32[i19 + (i5 * 152 | 0) + 12 >> 2];
+    d24 = +HEAPF32[i19 + (i5 * 152 | 0) + 8 >> 2];
+    d25 = +HEAPF32[i19 + (i5 * 152 | 0) + 4 >> 2];
+    d26 = +HEAPF32[i22 >> 2];
+    i22 = i19 + (i5 * 152 | 0) + 16 | 0;
+    d27 = +HEAPF32[i22 >> 2];
+    d28 = d27 - +HEAPF32[i19 + (i5 * 152 | 0) + 24 >> 2] * (d17 * (d14 - d15 * d23 - d21 + d18 * d25) + d16 * (d13 + d15 * d24 - d20 - d18 * d26) - +HEAPF32[i19 + (i5 * 152 | 0) + 32 >> 2]);
+    d44 = d28 > 0.0 ? d28 : 0.0;
+    d43 = d44 - d27;
+    HEAPF32[i22 >> 2] = d44;
+    d44 = d17 * d43;
+    d43 = d16 * d43;
+    d21 = d21 - d12 * d44;
+    d20 = d20 - d12 * d43;
+    d14 = d14 + d11 * d44;
+    d13 = d13 + d11 * d43;
+    d18 = d18 - d10 * (d26 * d43 - d25 * d44);
+    d15 = d15 + d9 * (d24 * d43 - d23 * d44);
+   }
+  } while (0);
+  d44 = +d21;
+  d43 = +d20;
+  i42 = i7;
+  HEAPF32[i42 >> 2] = d44;
+  HEAPF32[i42 + 4 >> 2] = d43;
+  i42 = HEAP32[i4 >> 2] | 0;
+  HEAPF32[i42 + (i8 * 12 | 0) + 8 >> 2] = d18;
+  d43 = +d14;
+  d44 = +d13;
+  i42 = i42 + (i6 * 12 | 0) | 0;
+  HEAPF32[i42 >> 2] = d43;
+  HEAPF32[i42 + 4 >> 2] = d44;
+  i42 = HEAP32[i4 >> 2] | 0;
+  HEAPF32[i42 + (i6 * 12 | 0) + 8 >> 2] = d15;
+  i5 = i5 + 1 | 0;
+  if ((i5 | 0) >= (HEAP32[i2 >> 2] | 0)) {
+   i2 = 21;
+   break;
+  }
+ }
+ if ((i2 | 0) == 4) {
+  ___assert_fail(6648, 6520, 311, 6688);
+ } else if ((i2 | 0) == 9) {
+  ___assert_fail(6720, 6520, 406, 6688);
+ } else if ((i2 | 0) == 21) {
+  STACKTOP = i1;
+  return;
+ }
+}
+function __Z14b2TimeOfImpactP11b2TOIOutputPK10b2TOIInput(i3, i11) {
+ i3 = i3 | 0;
+ i11 = i11 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i12 = 0, i13 = 0, d14 = 0.0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, d28 = 0.0, i29 = 0, d30 = 0.0, d31 = 0.0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, i36 = 0, i37 = 0, i38 = 0, i39 = 0, d40 = 0.0, i41 = 0, d42 = 0.0, d43 = 0.0, i44 = 0, i45 = 0, d46 = 0.0, i47 = 0, d48 = 0.0, d49 = 0.0, d50 = 0.0, d51 = 0.0, i52 = 0, d53 = 0.0, d54 = 0.0, d55 = 0.0, d56 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 320 | 0;
+ i12 = i1 + 276 | 0;
+ i10 = i1 + 240 | 0;
+ i13 = i1 + 228 | 0;
+ i5 = i1 + 136 | 0;
+ i7 = i1 + 112 | 0;
+ i8 = i1 + 8 | 0;
+ i9 = i1 + 4 | 0;
+ i4 = i1;
+ HEAP32[874] = (HEAP32[874] | 0) + 1;
+ HEAP32[i3 >> 2] = 0;
+ i19 = i11 + 128 | 0;
+ i2 = i3 + 4 | 0;
+ HEAPF32[i2 >> 2] = +HEAPF32[i19 >> 2];
+ i6 = i11 + 28 | 0;
+ i16 = i12 + 0 | 0;
+ i15 = i11 + 56 | 0;
+ i17 = i16 + 36 | 0;
+ do {
+  HEAP32[i16 >> 2] = HEAP32[i15 >> 2];
+  i16 = i16 + 4 | 0;
+  i15 = i15 + 4 | 0;
+ } while ((i16 | 0) < (i17 | 0));
+ i16 = i10 + 0 | 0;
+ i15 = i11 + 92 | 0;
+ i17 = i16 + 36 | 0;
+ do {
+  HEAP32[i16 >> 2] = HEAP32[i15 >> 2];
+  i16 = i16 + 4 | 0;
+  i15 = i15 + 4 | 0;
+ } while ((i16 | 0) < (i17 | 0));
+ i15 = i12 + 24 | 0;
+ d42 = +HEAPF32[i15 >> 2];
+ d43 = +Math_floor(+(d42 / 6.2831854820251465)) * 6.2831854820251465;
+ d42 = d42 - d43;
+ HEAPF32[i15 >> 2] = d42;
+ i16 = i12 + 28 | 0;
+ d43 = +HEAPF32[i16 >> 2] - d43;
+ HEAPF32[i16 >> 2] = d43;
+ i17 = i10 + 24 | 0;
+ d46 = +HEAPF32[i17 >> 2];
+ d40 = +Math_floor(+(d46 / 6.2831854820251465)) * 6.2831854820251465;
+ d46 = d46 - d40;
+ HEAPF32[i17 >> 2] = d46;
+ i18 = i10 + 28 | 0;
+ d40 = +HEAPF32[i18 >> 2] - d40;
+ HEAPF32[i18 >> 2] = d40;
+ d14 = +HEAPF32[i19 >> 2];
+ d28 = +HEAPF32[i11 + 24 >> 2] + +HEAPF32[i11 + 52 >> 2] + -.014999999664723873;
+ d28 = d28 < .004999999888241291 ? .004999999888241291 : d28;
+ if (!(d28 > .0012499999720603228)) {
+  ___assert_fail(3536, 3560, 280, 3600);
+ }
+ HEAP16[i13 + 4 >> 1] = 0;
+ HEAP32[i5 + 0 >> 2] = HEAP32[i11 + 0 >> 2];
+ HEAP32[i5 + 4 >> 2] = HEAP32[i11 + 4 >> 2];
+ HEAP32[i5 + 8 >> 2] = HEAP32[i11 + 8 >> 2];
+ HEAP32[i5 + 12 >> 2] = HEAP32[i11 + 12 >> 2];
+ HEAP32[i5 + 16 >> 2] = HEAP32[i11 + 16 >> 2];
+ HEAP32[i5 + 20 >> 2] = HEAP32[i11 + 20 >> 2];
+ HEAP32[i5 + 24 >> 2] = HEAP32[i11 + 24 >> 2];
+ i38 = i5 + 28 | 0;
+ HEAP32[i38 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+ HEAP32[i38 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+ HEAP32[i38 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+ HEAP32[i38 + 12 >> 2] = HEAP32[i6 + 12 >> 2];
+ HEAP32[i38 + 16 >> 2] = HEAP32[i6 + 16 >> 2];
+ HEAP32[i38 + 20 >> 2] = HEAP32[i6 + 20 >> 2];
+ HEAP32[i38 + 24 >> 2] = HEAP32[i6 + 24 >> 2];
+ HEAP8[i5 + 88 | 0] = 0;
+ i38 = i12 + 8 | 0;
+ i27 = i12 + 12 | 0;
+ i29 = i12 + 16 | 0;
+ i22 = i12 + 20 | 0;
+ i32 = i12 + 4 | 0;
+ i34 = i10 + 8 | 0;
+ i36 = i10 + 12 | 0;
+ i35 = i10 + 16 | 0;
+ i37 = i10 + 20 | 0;
+ i33 = i10 + 4 | 0;
+ i26 = i5 + 56 | 0;
+ i25 = i5 + 64 | 0;
+ i24 = i5 + 68 | 0;
+ i23 = i5 + 72 | 0;
+ i20 = i5 + 80 | 0;
+ i19 = i5 + 84 | 0;
+ i21 = i7 + 16 | 0;
+ d30 = d28 + .0012499999720603228;
+ d31 = d28 + -.0012499999720603228;
+ d48 = d40;
+ i39 = 0;
+ d40 = 0.0;
+ L4 : while (1) {
+  d56 = 1.0 - d40;
+  d49 = d56 * d42 + d40 * d43;
+  d43 = +Math_sin(+d49);
+  d49 = +Math_cos(+d49);
+  d55 = +HEAPF32[i12 >> 2];
+  d54 = +HEAPF32[i32 >> 2];
+  d42 = d56 * d46 + d40 * d48;
+  d53 = +Math_sin(+d42);
+  d42 = +Math_cos(+d42);
+  d46 = +HEAPF32[i10 >> 2];
+  d51 = +HEAPF32[i33 >> 2];
+  d50 = d56 * +HEAPF32[i34 >> 2] + d40 * +HEAPF32[i35 >> 2] - (d42 * d46 - d53 * d51);
+  d51 = d56 * +HEAPF32[i36 >> 2] + d40 * +HEAPF32[i37 >> 2] - (d53 * d46 + d42 * d51);
+  d46 = +(d56 * +HEAPF32[i38 >> 2] + d40 * +HEAPF32[i29 >> 2] - (d49 * d55 - d43 * d54));
+  d48 = +(d56 * +HEAPF32[i27 >> 2] + d40 * +HEAPF32[i22 >> 2] - (d43 * d55 + d49 * d54));
+  i52 = i26;
+  HEAPF32[i52 >> 2] = d46;
+  HEAPF32[i52 + 4 >> 2] = d48;
+  HEAPF32[i25 >> 2] = d43;
+  HEAPF32[i24 >> 2] = d49;
+  d50 = +d50;
+  d51 = +d51;
+  i52 = i23;
+  HEAPF32[i52 >> 2] = d50;
+  HEAPF32[i52 + 4 >> 2] = d51;
+  HEAPF32[i20 >> 2] = d53;
+  HEAPF32[i19 >> 2] = d42;
+  __Z10b2DistanceP16b2DistanceOutputP14b2SimplexCachePK15b2DistanceInput(i7, i13, i5);
+  d42 = +HEAPF32[i21 >> 2];
+  if (d42 <= 0.0) {
+   i4 = 5;
+   break;
+  }
+  if (d42 < d30) {
+   i4 = 7;
+   break;
+  }
+  +__ZN20b2SeparationFunction10InitializeEPK14b2SimplexCachePK15b2DistanceProxyRK7b2SweepS5_S8_f(i8, i13, i11, i12, i6, i10, d40);
+  i41 = 0;
+  d42 = d14;
+  do {
+   d50 = +__ZNK20b2SeparationFunction17FindMinSeparationEPiS0_f(i8, i9, i4, d42);
+   if (d50 > d30) {
+    i4 = 10;
+    break L4;
+   }
+   if (d50 > d31) {
+    d40 = d42;
+    break;
+   }
+   i45 = HEAP32[i9 >> 2] | 0;
+   i44 = HEAP32[i4 >> 2] | 0;
+   d48 = +__ZNK20b2SeparationFunction8EvaluateEiif(i8, i45, i44, d40);
+   if (d48 < d31) {
+    i4 = 13;
+    break L4;
+   }
+   if (!(d48 <= d30)) {
+    d43 = d40;
+    d46 = d42;
+    i47 = 0;
+   } else {
+    i4 = 15;
+    break L4;
+   }
+   while (1) {
+    if ((i47 & 1 | 0) == 0) {
+     d49 = (d43 + d46) * .5;
+    } else {
+     d49 = d43 + (d28 - d48) * (d46 - d43) / (d50 - d48);
+    }
+    d51 = +__ZNK20b2SeparationFunction8EvaluateEiif(i8, i45, i44, d49);
+    d53 = d51 - d28;
+    if (!(d53 > 0.0)) {
+     d53 = -d53;
+    }
+    if (d53 < .0012499999720603228) {
+     d42 = d49;
+     break;
+    }
+    i52 = d51 > d28;
+    i47 = i47 + 1 | 0;
+    HEAP32[880] = (HEAP32[880] | 0) + 1;
+    if ((i47 | 0) == 50) {
+     i47 = 50;
+     break;
+    } else {
+     d43 = i52 ? d49 : d43;
+     d46 = i52 ? d46 : d49;
+     d48 = i52 ? d51 : d48;
+     d50 = i52 ? d50 : d51;
+    }
+   }
+   i44 = HEAP32[882] | 0;
+   HEAP32[882] = (i44 | 0) > (i47 | 0) ? i44 : i47;
+   i41 = i41 + 1 | 0;
+  } while ((i41 | 0) != 8);
+  i39 = i39 + 1 | 0;
+  HEAP32[876] = (HEAP32[876] | 0) + 1;
+  if ((i39 | 0) == 20) {
+   i4 = 27;
+   break;
+  }
+  d42 = +HEAPF32[i15 >> 2];
+  d43 = +HEAPF32[i16 >> 2];
+  d46 = +HEAPF32[i17 >> 2];
+  d48 = +HEAPF32[i18 >> 2];
+ }
+ if ((i4 | 0) == 5) {
+  HEAP32[i3 >> 2] = 2;
+  HEAPF32[i2 >> 2] = 0.0;
+  i2 = HEAP32[878] | 0;
+  i52 = (i2 | 0) > (i39 | 0);
+  i52 = i52 ? i2 : i39;
+  HEAP32[878] = i52;
+  STACKTOP = i1;
+  return;
+ } else if ((i4 | 0) == 7) {
+  HEAP32[i3 >> 2] = 3;
+  HEAPF32[i2 >> 2] = d40;
+  i2 = HEAP32[878] | 0;
+  i52 = (i2 | 0) > (i39 | 0);
+  i52 = i52 ? i2 : i39;
+  HEAP32[878] = i52;
+  STACKTOP = i1;
+  return;
+ } else if ((i4 | 0) == 10) {
+  HEAP32[i3 >> 2] = 4;
+  HEAPF32[i2 >> 2] = d14;
+ } else if ((i4 | 0) == 13) {
+  HEAP32[i3 >> 2] = 1;
+  HEAPF32[i2 >> 2] = d40;
+ } else if ((i4 | 0) == 15) {
+  HEAP32[i3 >> 2] = 3;
+  HEAPF32[i2 >> 2] = d40;
+ } else if ((i4 | 0) == 27) {
+  HEAP32[i3 >> 2] = 1;
+  HEAPF32[i2 >> 2] = d40;
+  i39 = 20;
+  i2 = HEAP32[878] | 0;
+  i52 = (i2 | 0) > (i39 | 0);
+  i52 = i52 ? i2 : i39;
+  HEAP32[878] = i52;
+  STACKTOP = i1;
+  return;
+ }
+ HEAP32[876] = (HEAP32[876] | 0) + 1;
+ i39 = i39 + 1 | 0;
+ i2 = HEAP32[878] | 0;
+ i52 = (i2 | 0) > (i39 | 0);
+ i52 = i52 ? i2 : i39;
+ HEAP32[878] = i52;
+ STACKTOP = i1;
+ return;
+}
+function __ZN7b2World5SolveERK10b2TimeStep(i5, i15) {
+ i5 = i5 | 0;
+ i15 = i15 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, i36 = 0, i37 = 0, i38 = 0, d39 = 0.0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 96 | 0;
+ i4 = i3 + 32 | 0;
+ i9 = i3;
+ i2 = i3 + 84 | 0;
+ i11 = i5 + 103008 | 0;
+ HEAPF32[i11 >> 2] = 0.0;
+ i14 = i5 + 103012 | 0;
+ HEAPF32[i14 >> 2] = 0.0;
+ i8 = i5 + 103016 | 0;
+ HEAPF32[i8 >> 2] = 0.0;
+ i16 = i5 + 102960 | 0;
+ i1 = i5 + 102872 | 0;
+ i6 = i5 + 68 | 0;
+ __ZN8b2IslandC2EiiiP16b2StackAllocatorP17b2ContactListener(i4, HEAP32[i16 >> 2] | 0, HEAP32[i5 + 102936 >> 2] | 0, HEAP32[i5 + 102964 >> 2] | 0, i6, HEAP32[i5 + 102944 >> 2] | 0);
+ i7 = i5 + 102952 | 0;
+ i17 = HEAP32[i7 >> 2] | 0;
+ if ((i17 | 0) != 0) {
+  do {
+   i38 = i17 + 4 | 0;
+   HEAP16[i38 >> 1] = HEAP16[i38 >> 1] & 65534;
+   i17 = HEAP32[i17 + 96 >> 2] | 0;
+  } while ((i17 | 0) != 0);
+ }
+ i17 = HEAP32[i5 + 102932 >> 2] | 0;
+ if ((i17 | 0) != 0) {
+  do {
+   i38 = i17 + 4 | 0;
+   HEAP32[i38 >> 2] = HEAP32[i38 >> 2] & -2;
+   i17 = HEAP32[i17 + 12 >> 2] | 0;
+  } while ((i17 | 0) != 0);
+ }
+ i17 = HEAP32[i5 + 102956 >> 2] | 0;
+ if ((i17 | 0) != 0) {
+  do {
+   HEAP8[i17 + 60 | 0] = 0;
+   i17 = HEAP32[i17 + 12 >> 2] | 0;
+  } while ((i17 | 0) != 0);
+ }
+ i24 = HEAP32[i16 >> 2] | 0;
+ i16 = __ZN16b2StackAllocator8AllocateEi(i6, i24 << 2) | 0;
+ i32 = HEAP32[i7 >> 2] | 0;
+ L13 : do {
+  if ((i32 | 0) != 0) {
+   i18 = i4 + 28 | 0;
+   i30 = i4 + 36 | 0;
+   i27 = i4 + 32 | 0;
+   i17 = i4 + 40 | 0;
+   i23 = i4 + 8 | 0;
+   i29 = i4 + 48 | 0;
+   i28 = i4 + 16 | 0;
+   i26 = i4 + 44 | 0;
+   i31 = i4 + 12 | 0;
+   i25 = i5 + 102968 | 0;
+   i22 = i5 + 102976 | 0;
+   i21 = i9 + 12 | 0;
+   i20 = i9 + 16 | 0;
+   i19 = i9 + 20 | 0;
+   L15 : while (1) {
+    i33 = i32 + 4 | 0;
+    i34 = HEAP16[i33 >> 1] | 0;
+    if ((i34 & 35) == 34 ? (HEAP32[i32 >> 2] | 0) != 0 : 0) {
+     HEAP32[i18 >> 2] = 0;
+     HEAP32[i30 >> 2] = 0;
+     HEAP32[i27 >> 2] = 0;
+     HEAP32[i16 >> 2] = i32;
+     HEAP16[i33 >> 1] = i34 & 65535 | 1;
+     i35 = 1;
+     do {
+      i35 = i35 + -1 | 0;
+      i33 = HEAP32[i16 + (i35 << 2) >> 2] | 0;
+      i34 = i33 + 4 | 0;
+      i36 = HEAP16[i34 >> 1] | 0;
+      if ((i36 & 32) == 0) {
+       i8 = 13;
+       break L15;
+      }
+      i37 = HEAP32[i18 >> 2] | 0;
+      if ((i37 | 0) >= (HEAP32[i17 >> 2] | 0)) {
+       i8 = 15;
+       break L15;
+      }
+      HEAP32[i33 + 8 >> 2] = i37;
+      i38 = HEAP32[i18 >> 2] | 0;
+      HEAP32[(HEAP32[i23 >> 2] | 0) + (i38 << 2) >> 2] = i33;
+      HEAP32[i18 >> 2] = i38 + 1;
+      i36 = i36 & 65535;
+      if ((i36 & 2 | 0) == 0) {
+       HEAP16[i34 >> 1] = i36 | 2;
+       HEAPF32[i33 + 144 >> 2] = 0.0;
+      }
+      if ((HEAP32[i33 >> 2] | 0) != 0) {
+       i34 = HEAP32[i33 + 112 >> 2] | 0;
+       if ((i34 | 0) != 0) {
+        do {
+         i38 = HEAP32[i34 + 4 >> 2] | 0;
+         i36 = i38 + 4 | 0;
+         if (((HEAP32[i36 >> 2] & 7 | 0) == 6 ? (HEAP8[(HEAP32[i38 + 48 >> 2] | 0) + 38 | 0] | 0) == 0 : 0) ? (HEAP8[(HEAP32[i38 + 52 >> 2] | 0) + 38 | 0] | 0) == 0 : 0) {
+          i37 = HEAP32[i30 >> 2] | 0;
+          if ((i37 | 0) >= (HEAP32[i26 >> 2] | 0)) {
+           i8 = 25;
+           break L15;
+          }
+          HEAP32[i30 >> 2] = i37 + 1;
+          HEAP32[(HEAP32[i31 >> 2] | 0) + (i37 << 2) >> 2] = i38;
+          HEAP32[i36 >> 2] = HEAP32[i36 >> 2] | 1;
+          i38 = HEAP32[i34 >> 2] | 0;
+          i36 = i38 + 4 | 0;
+          i37 = HEAP16[i36 >> 1] | 0;
+          if ((i37 & 1) == 0) {
+           if ((i35 | 0) >= (i24 | 0)) {
+            i8 = 28;
+            break L15;
+           }
+           HEAP32[i16 + (i35 << 2) >> 2] = i38;
+           HEAP16[i36 >> 1] = i37 & 65535 | 1;
+           i35 = i35 + 1 | 0;
+          }
+         }
+         i34 = HEAP32[i34 + 12 >> 2] | 0;
+        } while ((i34 | 0) != 0);
+       }
+       i33 = HEAP32[i33 + 108 >> 2] | 0;
+       if ((i33 | 0) != 0) {
+        do {
+         i37 = i33 + 4 | 0;
+         i36 = HEAP32[i37 >> 2] | 0;
+         if ((HEAP8[i36 + 60 | 0] | 0) == 0 ? (i10 = HEAP32[i33 >> 2] | 0, i13 = i10 + 4 | 0, i12 = HEAP16[i13 >> 1] | 0, !((i12 & 32) == 0)) : 0) {
+          i34 = HEAP32[i27 >> 2] | 0;
+          if ((i34 | 0) >= (HEAP32[i29 >> 2] | 0)) {
+           i8 = 35;
+           break L15;
+          }
+          HEAP32[i27 >> 2] = i34 + 1;
+          HEAP32[(HEAP32[i28 >> 2] | 0) + (i34 << 2) >> 2] = i36;
+          HEAP8[(HEAP32[i37 >> 2] | 0) + 60 | 0] = 1;
+          if ((i12 & 1) == 0) {
+           if ((i35 | 0) >= (i24 | 0)) {
+            i8 = 38;
+            break L15;
+           }
+           HEAP32[i16 + (i35 << 2) >> 2] = i10;
+           HEAP16[i13 >> 1] = i12 & 65535 | 1;
+           i35 = i35 + 1 | 0;
+          }
+         }
+         i33 = HEAP32[i33 + 12 >> 2] | 0;
+        } while ((i33 | 0) != 0);
+       }
+      }
+     } while ((i35 | 0) > 0);
+     __ZN8b2Island5SolveEP9b2ProfileRK10b2TimeStepRK6b2Vec2b(i4, i9, i15, i25, (HEAP8[i22] | 0) != 0);
+     HEAPF32[i11 >> 2] = +HEAPF32[i21 >> 2] + +HEAPF32[i11 >> 2];
+     HEAPF32[i14 >> 2] = +HEAPF32[i20 >> 2] + +HEAPF32[i14 >> 2];
+     HEAPF32[i8 >> 2] = +HEAPF32[i19 >> 2] + +HEAPF32[i8 >> 2];
+     i35 = HEAP32[i18 >> 2] | 0;
+     if ((i35 | 0) > 0) {
+      i33 = HEAP32[i23 >> 2] | 0;
+      i36 = 0;
+      do {
+       i34 = HEAP32[i33 + (i36 << 2) >> 2] | 0;
+       if ((HEAP32[i34 >> 2] | 0) == 0) {
+        i38 = i34 + 4 | 0;
+        HEAP16[i38 >> 1] = HEAP16[i38 >> 1] & 65534;
+       }
+       i36 = i36 + 1 | 0;
+      } while ((i36 | 0) < (i35 | 0));
+     }
+    }
+    i32 = HEAP32[i32 + 96 >> 2] | 0;
+    if ((i32 | 0) == 0) {
+     break L13;
+    }
+   }
+   if ((i8 | 0) == 13) {
+    ___assert_fail(2232, 2184, 445, 2256);
+   } else if ((i8 | 0) == 15) {
+    ___assert_fail(2520, 2440, 54, 2472);
+   } else if ((i8 | 0) == 25) {
+    ___assert_fail(2480, 2440, 62, 2472);
+   } else if ((i8 | 0) == 28) {
+    ___assert_fail(2264, 2184, 495, 2256);
+   } else if ((i8 | 0) == 35) {
+    ___assert_fail(2408, 2440, 68, 2472);
+   } else if ((i8 | 0) == 38) {
+    ___assert_fail(2264, 2184, 524, 2256);
+   }
+  }
+ } while (0);
+ __ZN16b2StackAllocator4FreeEPv(i6, i16);
+ __ZN7b2TimerC2Ev(i2);
+ i6 = HEAP32[i7 >> 2] | 0;
+ if ((i6 | 0) == 0) {
+  __ZN16b2ContactManager15FindNewContactsEv(i1);
+  d39 = +__ZNK7b2Timer15GetMillisecondsEv(i2);
+  i38 = i5 + 103020 | 0;
+  HEAPF32[i38 >> 2] = d39;
+  __ZN8b2IslandD2Ev(i4);
+  STACKTOP = i3;
+  return;
+ }
+ do {
+  if (!((HEAP16[i6 + 4 >> 1] & 1) == 0) ? (HEAP32[i6 >> 2] | 0) != 0 : 0) {
+   __ZN6b2Body19SynchronizeFixturesEv(i6);
+  }
+  i6 = HEAP32[i6 + 96 >> 2] | 0;
+ } while ((i6 | 0) != 0);
+ __ZN16b2ContactManager15FindNewContactsEv(i1);
+ d39 = +__ZNK7b2Timer15GetMillisecondsEv(i2);
+ i38 = i5 + 103020 | 0;
+ HEAPF32[i38 >> 2] = d39;
+ __ZN8b2IslandD2Ev(i4);
+ STACKTOP = i3;
+ return;
+}
+function __ZN15b2ContactSolver29InitializeVelocityConstraintsEv(i10) {
+ i10 = i10 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, d17 = 0.0, d18 = 0.0, d19 = 0.0, d20 = 0.0, d21 = 0.0, d22 = 0.0, d23 = 0.0, d24 = 0.0, d25 = 0.0, d26 = 0.0, d27 = 0.0, d28 = 0.0, d29 = 0.0, d30 = 0.0, i31 = 0, d32 = 0.0, i33 = 0, i34 = 0, i35 = 0, i36 = 0, i37 = 0, d38 = 0.0, d39 = 0.0, d40 = 0.0, d41 = 0.0, i42 = 0, d43 = 0.0, d44 = 0.0, d45 = 0.0, d46 = 0.0, d47 = 0.0, d48 = 0.0, i49 = 0, i50 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i8 = i1 + 40 | 0;
+ i3 = i1 + 24 | 0;
+ i5 = i1;
+ i4 = i10 + 48 | 0;
+ if ((HEAP32[i4 >> 2] | 0) <= 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i9 = i10 + 40 | 0;
+ i2 = i10 + 36 | 0;
+ i7 = i10 + 44 | 0;
+ i6 = i10 + 24 | 0;
+ i13 = i10 + 28 | 0;
+ i14 = i8 + 8 | 0;
+ i12 = i8 + 12 | 0;
+ i11 = i3 + 8 | 0;
+ i10 = i3 + 12 | 0;
+ i16 = 0;
+ while (1) {
+  i15 = HEAP32[i9 >> 2] | 0;
+  i33 = HEAP32[i2 >> 2] | 0;
+  i31 = HEAP32[(HEAP32[i7 >> 2] | 0) + (HEAP32[i15 + (i16 * 152 | 0) + 148 >> 2] << 2) >> 2] | 0;
+  i35 = HEAP32[i15 + (i16 * 152 | 0) + 112 >> 2] | 0;
+  i42 = HEAP32[i15 + (i16 * 152 | 0) + 116 >> 2] | 0;
+  d30 = +HEAPF32[i15 + (i16 * 152 | 0) + 120 >> 2];
+  d24 = +HEAPF32[i15 + (i16 * 152 | 0) + 124 >> 2];
+  d17 = +HEAPF32[i15 + (i16 * 152 | 0) + 128 >> 2];
+  d18 = +HEAPF32[i15 + (i16 * 152 | 0) + 132 >> 2];
+  i36 = i33 + (i16 * 88 | 0) + 48 | 0;
+  d39 = +HEAPF32[i36 >> 2];
+  d40 = +HEAPF32[i36 + 4 >> 2];
+  i36 = i33 + (i16 * 88 | 0) + 56 | 0;
+  d41 = +HEAPF32[i36 >> 2];
+  d43 = +HEAPF32[i36 + 4 >> 2];
+  i36 = HEAP32[i6 >> 2] | 0;
+  i37 = i36 + (i35 * 12 | 0) | 0;
+  d26 = +HEAPF32[i37 >> 2];
+  d27 = +HEAPF32[i37 + 4 >> 2];
+  d32 = +HEAPF32[i36 + (i35 * 12 | 0) + 8 >> 2];
+  i37 = HEAP32[i13 >> 2] | 0;
+  i34 = i37 + (i35 * 12 | 0) | 0;
+  d22 = +HEAPF32[i34 >> 2];
+  d25 = +HEAPF32[i34 + 4 >> 2];
+  d23 = +HEAPF32[i37 + (i35 * 12 | 0) + 8 >> 2];
+  i35 = i36 + (i42 * 12 | 0) | 0;
+  d28 = +HEAPF32[i35 >> 2];
+  d29 = +HEAPF32[i35 + 4 >> 2];
+  d38 = +HEAPF32[i36 + (i42 * 12 | 0) + 8 >> 2];
+  i36 = i37 + (i42 * 12 | 0) | 0;
+  d20 = +HEAPF32[i36 >> 2];
+  d19 = +HEAPF32[i36 + 4 >> 2];
+  d21 = +HEAPF32[i37 + (i42 * 12 | 0) + 8 >> 2];
+  if ((HEAP32[i31 + 124 >> 2] | 0) <= 0) {
+   i2 = 4;
+   break;
+  }
+  d44 = +HEAPF32[i33 + (i16 * 88 | 0) + 80 >> 2];
+  d45 = +HEAPF32[i33 + (i16 * 88 | 0) + 76 >> 2];
+  d47 = +Math_sin(+d32);
+  HEAPF32[i14 >> 2] = d47;
+  d48 = +Math_cos(+d32);
+  HEAPF32[i12 >> 2] = d48;
+  d32 = +Math_sin(+d38);
+  HEAPF32[i11 >> 2] = d32;
+  d38 = +Math_cos(+d38);
+  HEAPF32[i10 >> 2] = d38;
+  d46 = +(d26 - (d39 * d48 - d40 * d47));
+  d40 = +(d27 - (d40 * d48 + d39 * d47));
+  i37 = i8;
+  HEAPF32[i37 >> 2] = d46;
+  HEAPF32[i37 + 4 >> 2] = d40;
+  d40 = +(d28 - (d41 * d38 - d43 * d32));
+  d43 = +(d29 - (d43 * d38 + d41 * d32));
+  i37 = i3;
+  HEAPF32[i37 >> 2] = d40;
+  HEAPF32[i37 + 4 >> 2] = d43;
+  __ZN15b2WorldManifold10InitializeEPK10b2ManifoldRK11b2TransformfS5_f(i5, i31 + 64 | 0, i8, d45, i3, d44);
+  i37 = i15 + (i16 * 152 | 0) + 72 | 0;
+  i42 = i5;
+  i33 = HEAP32[i42 + 4 >> 2] | 0;
+  i31 = i37;
+  HEAP32[i31 >> 2] = HEAP32[i42 >> 2];
+  HEAP32[i31 + 4 >> 2] = i33;
+  i31 = i15 + (i16 * 152 | 0) + 144 | 0;
+  i33 = HEAP32[i31 >> 2] | 0;
+  do {
+   if ((i33 | 0) > 0) {
+    i36 = i15 + (i16 * 152 | 0) + 76 | 0;
+    d32 = d30 + d24;
+    i35 = i15 + (i16 * 152 | 0) + 140 | 0;
+    i34 = 0;
+    do {
+     i49 = i5 + (i34 << 3) + 8 | 0;
+     d41 = +HEAPF32[i49 >> 2] - d26;
+     i42 = i5 + (i34 << 3) + 12 | 0;
+     d39 = +d41;
+     d40 = +(+HEAPF32[i42 >> 2] - d27);
+     i50 = i15 + (i16 * 152 | 0) + (i34 * 36 | 0) | 0;
+     HEAPF32[i50 >> 2] = d39;
+     HEAPF32[i50 + 4 >> 2] = d40;
+     d40 = +HEAPF32[i49 >> 2] - d28;
+     d39 = +d40;
+     d47 = +(+HEAPF32[i42 >> 2] - d29);
+     i42 = i15 + (i16 * 152 | 0) + (i34 * 36 | 0) + 8 | 0;
+     HEAPF32[i42 >> 2] = d39;
+     HEAPF32[i42 + 4 >> 2] = d47;
+     d47 = +HEAPF32[i36 >> 2];
+     d39 = +HEAPF32[i15 + (i16 * 152 | 0) + (i34 * 36 | 0) + 4 >> 2];
+     d43 = +HEAPF32[i37 >> 2];
+     d48 = d41 * d47 - d39 * d43;
+     d38 = +HEAPF32[i15 + (i16 * 152 | 0) + (i34 * 36 | 0) + 12 >> 2];
+     d43 = d47 * d40 - d43 * d38;
+     d43 = d32 + d48 * d17 * d48 + d43 * d18 * d43;
+     if (d43 > 0.0) {
+      d43 = 1.0 / d43;
+     } else {
+      d43 = 0.0;
+     }
+     HEAPF32[i15 + (i16 * 152 | 0) + (i34 * 36 | 0) + 24 >> 2] = d43;
+     d43 = +HEAPF32[i36 >> 2];
+     d47 = -+HEAPF32[i37 >> 2];
+     d48 = d41 * d47 - d43 * d39;
+     d43 = d40 * d47 - d43 * d38;
+     d43 = d32 + d48 * d17 * d48 + d43 * d18 * d43;
+     if (d43 > 0.0) {
+      d43 = 1.0 / d43;
+     } else {
+      d43 = 0.0;
+     }
+     HEAPF32[i15 + (i16 * 152 | 0) + (i34 * 36 | 0) + 28 >> 2] = d43;
+     i42 = i15 + (i16 * 152 | 0) + (i34 * 36 | 0) + 32 | 0;
+     HEAPF32[i42 >> 2] = 0.0;
+     d38 = +HEAPF32[i37 >> 2] * (d20 - d21 * d38 - d22 + d23 * d39) + +HEAPF32[i36 >> 2] * (d19 + d21 * d40 - d25 - d23 * d41);
+     if (d38 < -1.0) {
+      HEAPF32[i42 >> 2] = -(d38 * +HEAPF32[i35 >> 2]);
+     }
+     i34 = i34 + 1 | 0;
+    } while ((i34 | 0) != (i33 | 0));
+    if ((HEAP32[i31 >> 2] | 0) == 2) {
+     d45 = +HEAPF32[i15 + (i16 * 152 | 0) + 76 >> 2];
+     d20 = +HEAPF32[i37 >> 2];
+     d44 = +HEAPF32[i15 + (i16 * 152 | 0) >> 2] * d45 - +HEAPF32[i15 + (i16 * 152 | 0) + 4 >> 2] * d20;
+     d19 = d45 * +HEAPF32[i15 + (i16 * 152 | 0) + 8 >> 2] - d20 * +HEAPF32[i15 + (i16 * 152 | 0) + 12 >> 2];
+     d47 = d45 * +HEAPF32[i15 + (i16 * 152 | 0) + 36 >> 2] - d20 * +HEAPF32[i15 + (i16 * 152 | 0) + 40 >> 2];
+     d20 = d45 * +HEAPF32[i15 + (i16 * 152 | 0) + 44 >> 2] - d20 * +HEAPF32[i15 + (i16 * 152 | 0) + 48 >> 2];
+     d45 = d30 + d24;
+     d46 = d17 * d44;
+     d48 = d18 * d19;
+     d19 = d45 + d44 * d46 + d19 * d48;
+     d18 = d45 + d47 * d17 * d47 + d20 * d18 * d20;
+     d17 = d45 + d46 * d47 + d48 * d20;
+     d20 = d19 * d18 - d17 * d17;
+     if (!(d19 * d19 < d20 * 1.0e3)) {
+      HEAP32[i31 >> 2] = 1;
+      break;
+     }
+     HEAPF32[i15 + (i16 * 152 | 0) + 96 >> 2] = d19;
+     HEAPF32[i15 + (i16 * 152 | 0) + 100 >> 2] = d17;
+     HEAPF32[i15 + (i16 * 152 | 0) + 104 >> 2] = d17;
+     HEAPF32[i15 + (i16 * 152 | 0) + 108 >> 2] = d18;
+     if (d20 != 0.0) {
+      d20 = 1.0 / d20;
+     }
+     d48 = -(d20 * d17);
+     HEAPF32[i15 + (i16 * 152 | 0) + 80 >> 2] = d18 * d20;
+     HEAPF32[i15 + (i16 * 152 | 0) + 84 >> 2] = d48;
+     HEAPF32[i15 + (i16 * 152 | 0) + 88 >> 2] = d48;
+     HEAPF32[i15 + (i16 * 152 | 0) + 92 >> 2] = d19 * d20;
+    }
+   }
+  } while (0);
+  i16 = i16 + 1 | 0;
+  if ((i16 | 0) >= (HEAP32[i4 >> 2] | 0)) {
+   i2 = 21;
+   break;
+  }
+ }
+ if ((i2 | 0) == 4) {
+  ___assert_fail(6584, 6520, 168, 6616);
+ } else if ((i2 | 0) == 21) {
+  STACKTOP = i1;
+  return;
+ }
+}
+function __Z17b2CollidePolygonsP10b2ManifoldPK14b2PolygonShapeRK11b2TransformS3_S6_(i5, i27, i28, i24, i14) {
+ i5 = i5 | 0;
+ i27 = i27 | 0;
+ i28 = i28 | 0;
+ i24 = i24 | 0;
+ i14 = i14 | 0;
+ var i1 = 0, i2 = 0, d3 = 0.0, i4 = 0, d6 = 0.0, d7 = 0.0, d8 = 0.0, d9 = 0.0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, d15 = 0.0, d16 = 0.0, i17 = 0, d18 = 0.0, d19 = 0.0, i20 = 0, d21 = 0.0, d22 = 0.0, d23 = 0.0, d25 = 0.0, d26 = 0.0, d29 = 0.0, d30 = 0.0, i31 = 0, d32 = 0.0, i33 = 0, i34 = 0, d35 = 0.0, d36 = 0.0, d37 = 0.0, d38 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 96 | 0;
+ i17 = i1 + 92 | 0;
+ i20 = i1 + 88 | 0;
+ i13 = i1;
+ i11 = i1 + 80 | 0;
+ i12 = i1 + 56 | 0;
+ i4 = i1 + 32 | 0;
+ i10 = i1 + 24 | 0;
+ i2 = i5 + 60 | 0;
+ HEAP32[i2 >> 2] = 0;
+ d3 = +HEAPF32[i27 + 8 >> 2] + +HEAPF32[i24 + 8 >> 2];
+ HEAP32[i17 >> 2] = 0;
+ d7 = +__ZL19b2FindMaxSeparationPiPK14b2PolygonShapeRK11b2TransformS2_S5_(i17, i27, i28, i24, i14);
+ if (d7 > d3) {
+  STACKTOP = i1;
+  return;
+ }
+ HEAP32[i20 >> 2] = 0;
+ d6 = +__ZL19b2FindMaxSeparationPiPK14b2PolygonShapeRK11b2TransformS2_S5_(i20, i24, i14, i27, i28);
+ if (d6 > d3) {
+  STACKTOP = i1;
+  return;
+ }
+ if (d6 > d7 * .9800000190734863 + .0010000000474974513) {
+  d18 = +HEAPF32[i14 >> 2];
+  d19 = +HEAPF32[i14 + 4 >> 2];
+  d15 = +HEAPF32[i14 + 8 >> 2];
+  d16 = +HEAPF32[i14 + 12 >> 2];
+  d9 = +HEAPF32[i28 >> 2];
+  d6 = +HEAPF32[i28 + 4 >> 2];
+  d7 = +HEAPF32[i28 + 8 >> 2];
+  d8 = +HEAPF32[i28 + 12 >> 2];
+  i17 = HEAP32[i20 >> 2] | 0;
+  HEAP32[i5 + 56 >> 2] = 2;
+  i14 = 1;
+  i20 = i24;
+ } else {
+  d18 = +HEAPF32[i28 >> 2];
+  d19 = +HEAPF32[i28 + 4 >> 2];
+  d15 = +HEAPF32[i28 + 8 >> 2];
+  d16 = +HEAPF32[i28 + 12 >> 2];
+  d9 = +HEAPF32[i14 >> 2];
+  d6 = +HEAPF32[i14 + 4 >> 2];
+  d7 = +HEAPF32[i14 + 8 >> 2];
+  d8 = +HEAPF32[i14 + 12 >> 2];
+  i17 = HEAP32[i17 >> 2] | 0;
+  HEAP32[i5 + 56 >> 2] = 1;
+  i14 = 0;
+  i20 = i27;
+  i27 = i24;
+ }
+ i28 = HEAP32[i27 + 148 >> 2] | 0;
+ if (!((i17 | 0) > -1)) {
+  ___assert_fail(5640, 5688, 151, 5728);
+ }
+ i24 = HEAP32[i20 + 148 >> 2] | 0;
+ if ((i24 | 0) <= (i17 | 0)) {
+  ___assert_fail(5640, 5688, 151, 5728);
+ }
+ d21 = +HEAPF32[i20 + (i17 << 3) + 84 >> 2];
+ d36 = +HEAPF32[i20 + (i17 << 3) + 88 >> 2];
+ d22 = d16 * d21 - d15 * d36;
+ d36 = d15 * d21 + d16 * d36;
+ d21 = d8 * d22 + d7 * d36;
+ d22 = d8 * d36 - d7 * d22;
+ if ((i28 | 0) > 0) {
+  i33 = 0;
+  i34 = 0;
+  d23 = 3.4028234663852886e+38;
+  while (1) {
+   d25 = d21 * +HEAPF32[i27 + (i33 << 3) + 84 >> 2] + d22 * +HEAPF32[i27 + (i33 << 3) + 88 >> 2];
+   i31 = d25 < d23;
+   i34 = i31 ? i33 : i34;
+   i33 = i33 + 1 | 0;
+   if ((i33 | 0) == (i28 | 0)) {
+    break;
+   } else {
+    d23 = i31 ? d25 : d23;
+   }
+  }
+ } else {
+  i34 = 0;
+ }
+ i31 = i34 + 1 | 0;
+ i33 = (i31 | 0) < (i28 | 0) ? i31 : 0;
+ d35 = +HEAPF32[i27 + (i34 << 3) + 20 >> 2];
+ d32 = +HEAPF32[i27 + (i34 << 3) + 24 >> 2];
+ d36 = +(d9 + (d8 * d35 - d7 * d32));
+ d32 = +(d6 + (d7 * d35 + d8 * d32));
+ i31 = i13;
+ HEAPF32[i31 >> 2] = d36;
+ HEAPF32[i31 + 4 >> 2] = d32;
+ i31 = i17 & 255;
+ i28 = i13 + 8 | 0;
+ HEAP8[i28] = i31;
+ HEAP8[i28 + 1 | 0] = i34;
+ HEAP8[i28 + 2 | 0] = 1;
+ HEAP8[i28 + 3 | 0] = 0;
+ d32 = +HEAPF32[i27 + (i33 << 3) + 20 >> 2];
+ d36 = +HEAPF32[i27 + (i33 << 3) + 24 >> 2];
+ d35 = +(d9 + (d8 * d32 - d7 * d36));
+ d36 = +(d6 + (d7 * d32 + d8 * d36));
+ i27 = i13 + 12 | 0;
+ HEAPF32[i27 >> 2] = d35;
+ HEAPF32[i27 + 4 >> 2] = d36;
+ i27 = i13 + 20 | 0;
+ HEAP8[i27] = i31;
+ HEAP8[i27 + 1 | 0] = i33;
+ HEAP8[i27 + 2 | 0] = 1;
+ HEAP8[i27 + 3 | 0] = 0;
+ i27 = i17 + 1 | 0;
+ i24 = (i27 | 0) < (i24 | 0) ? i27 : 0;
+ i34 = i20 + (i17 << 3) + 20 | 0;
+ d26 = +HEAPF32[i34 >> 2];
+ d25 = +HEAPF32[i34 + 4 >> 2];
+ i34 = i20 + (i24 << 3) + 20 | 0;
+ d30 = +HEAPF32[i34 >> 2];
+ d29 = +HEAPF32[i34 + 4 >> 2];
+ d32 = d30 - d26;
+ d35 = d29 - d25;
+ d21 = +Math_sqrt(+(d32 * d32 + d35 * d35));
+ if (!(d21 < 1.1920928955078125e-7)) {
+  d36 = 1.0 / d21;
+  d32 = d32 * d36;
+  d35 = d35 * d36;
+ }
+ d36 = d16 * d32 - d15 * d35;
+ d21 = d16 * d35 + d15 * d32;
+ HEAPF32[i11 >> 2] = d36;
+ HEAPF32[i11 + 4 >> 2] = d21;
+ d22 = -d36;
+ d38 = d18 + (d16 * d26 - d15 * d25);
+ d37 = d19 + (d15 * d26 + d16 * d25);
+ d23 = d38 * d21 + d37 * d22;
+ HEAPF32[i10 >> 2] = d22;
+ HEAPF32[i10 + 4 >> 2] = -d21;
+ if ((__Z19b2ClipSegmentToLineP12b2ClipVertexPKS_RK6b2Vec2fi(i12, i13, i10, d3 - (d38 * d36 + d37 * d21), i17) | 0) < 2) {
+  STACKTOP = i1;
+  return;
+ }
+ if ((__Z19b2ClipSegmentToLineP12b2ClipVertexPKS_RK6b2Vec2fi(i4, i12, i11, d3 + ((d18 + (d16 * d30 - d15 * d29)) * d36 + (d19 + (d15 * d30 + d16 * d29)) * d21), i24) | 0) < 2) {
+  STACKTOP = i1;
+  return;
+ }
+ d16 = +d35;
+ d15 = +-d32;
+ i10 = i5 + 40 | 0;
+ HEAPF32[i10 >> 2] = d16;
+ HEAPF32[i10 + 4 >> 2] = d15;
+ d15 = +((d26 + d30) * .5);
+ d16 = +((d25 + d29) * .5);
+ i10 = i5 + 48 | 0;
+ HEAPF32[i10 >> 2] = d15;
+ HEAPF32[i10 + 4 >> 2] = d16;
+ d16 = +HEAPF32[i4 >> 2];
+ d15 = +HEAPF32[i4 + 4 >> 2];
+ i10 = !(d21 * d16 + d15 * d22 - d23 <= d3);
+ if (i14 << 24 >> 24 == 0) {
+  if (i10) {
+   i10 = 0;
+  } else {
+   d38 = d16 - d9;
+   d36 = d15 - d6;
+   d37 = +(d8 * d38 + d7 * d36);
+   d38 = +(d8 * d36 - d7 * d38);
+   i10 = i5;
+   HEAPF32[i10 >> 2] = d37;
+   HEAPF32[i10 + 4 >> 2] = d38;
+   HEAP32[i5 + 16 >> 2] = HEAP32[i4 + 8 >> 2];
+   i10 = 1;
+  }
+  d16 = +HEAPF32[i4 + 12 >> 2];
+  d15 = +HEAPF32[i4 + 16 >> 2];
+  if (d21 * d16 + d15 * d22 - d23 <= d3) {
+   d38 = d16 - d9;
+   d36 = d15 - d6;
+   d37 = +(d8 * d38 + d7 * d36);
+   d38 = +(d8 * d36 - d7 * d38);
+   i34 = i5 + (i10 * 20 | 0) | 0;
+   HEAPF32[i34 >> 2] = d37;
+   HEAPF32[i34 + 4 >> 2] = d38;
+   HEAP32[i5 + (i10 * 20 | 0) + 16 >> 2] = HEAP32[i4 + 20 >> 2];
+   i10 = i10 + 1 | 0;
+  }
+ } else {
+  if (i10) {
+   i10 = 0;
+  } else {
+   d38 = d16 - d9;
+   d36 = d15 - d6;
+   d37 = +(d8 * d38 + d7 * d36);
+   d38 = +(d8 * d36 - d7 * d38);
+   i10 = i5;
+   HEAPF32[i10 >> 2] = d37;
+   HEAPF32[i10 + 4 >> 2] = d38;
+   i10 = i5 + 16 | 0;
+   i34 = HEAP32[i4 + 8 >> 2] | 0;
+   HEAP32[i10 >> 2] = i34;
+   HEAP8[i10] = i34 >>> 8;
+   HEAP8[i10 + 1 | 0] = i34;
+   HEAP8[i10 + 2 | 0] = i34 >>> 24;
+   HEAP8[i10 + 3 | 0] = i34 >>> 16;
+   i10 = 1;
+  }
+  d16 = +HEAPF32[i4 + 12 >> 2];
+  d15 = +HEAPF32[i4 + 16 >> 2];
+  if (d21 * d16 + d15 * d22 - d23 <= d3) {
+   d38 = d16 - d9;
+   d36 = d15 - d6;
+   d37 = +(d8 * d38 + d7 * d36);
+   d38 = +(d8 * d36 - d7 * d38);
+   i34 = i5 + (i10 * 20 | 0) | 0;
+   HEAPF32[i34 >> 2] = d37;
+   HEAPF32[i34 + 4 >> 2] = d38;
+   i34 = i5 + (i10 * 20 | 0) + 16 | 0;
+   i33 = HEAP32[i4 + 20 >> 2] | 0;
+   HEAP32[i34 >> 2] = i33;
+   HEAP8[i34] = i33 >>> 8;
+   HEAP8[i34 + 1 | 0] = i33;
+   HEAP8[i34 + 2 | 0] = i33 >>> 24;
+   HEAP8[i34 + 3 | 0] = i33 >>> 16;
+   i10 = i10 + 1 | 0;
+  }
+ }
+ HEAP32[i2 >> 2] = i10;
+ STACKTOP = i1;
+ return;
+}
+function __ZN8b2Island8SolveTOIERK10b2TimeStepii(i4, i11, i15, i18) {
+ i4 = i4 | 0;
+ i11 = i11 | 0;
+ i15 = i15 | 0;
+ i18 = i18 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, d12 = 0.0, d13 = 0.0, d14 = 0.0, d16 = 0.0, d17 = 0.0, d19 = 0.0, d20 = 0.0, d21 = 0.0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, d26 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 128 | 0;
+ i2 = i1 + 96 | 0;
+ i10 = i1 + 52 | 0;
+ i3 = i1;
+ i6 = i4 + 28 | 0;
+ i5 = HEAP32[i6 >> 2] | 0;
+ if ((i5 | 0) <= (i15 | 0)) {
+  ___assert_fail(5464, 5488, 386, 5520);
+ }
+ if ((i5 | 0) <= (i18 | 0)) {
+  ___assert_fail(5536, 5488, 387, 5520);
+ }
+ if ((i5 | 0) > 0) {
+  i9 = i4 + 8 | 0;
+  i8 = i4 + 20 | 0;
+  i7 = i4 + 24 | 0;
+  i22 = 0;
+  while (1) {
+   i23 = HEAP32[(HEAP32[i9 >> 2] | 0) + (i22 << 2) >> 2] | 0;
+   i5 = i23 + 44 | 0;
+   i24 = HEAP32[i5 + 4 >> 2] | 0;
+   i25 = (HEAP32[i8 >> 2] | 0) + (i22 * 12 | 0) | 0;
+   HEAP32[i25 >> 2] = HEAP32[i5 >> 2];
+   HEAP32[i25 + 4 >> 2] = i24;
+   HEAPF32[(HEAP32[i8 >> 2] | 0) + (i22 * 12 | 0) + 8 >> 2] = +HEAPF32[i23 + 56 >> 2];
+   i25 = i23 + 64 | 0;
+   i24 = HEAP32[i25 + 4 >> 2] | 0;
+   i5 = (HEAP32[i7 >> 2] | 0) + (i22 * 12 | 0) | 0;
+   HEAP32[i5 >> 2] = HEAP32[i25 >> 2];
+   HEAP32[i5 + 4 >> 2] = i24;
+   i5 = HEAP32[i7 >> 2] | 0;
+   HEAPF32[i5 + (i22 * 12 | 0) + 8 >> 2] = +HEAPF32[i23 + 72 >> 2];
+   i22 = i22 + 1 | 0;
+   if ((i22 | 0) >= (HEAP32[i6 >> 2] | 0)) {
+    i22 = i5;
+    break;
+   }
+  }
+ } else {
+  i8 = i4 + 20 | 0;
+  i22 = HEAP32[i4 + 24 >> 2] | 0;
+ }
+ i5 = i4 + 12 | 0;
+ HEAP32[i10 + 24 >> 2] = HEAP32[i5 >> 2];
+ i7 = i4 + 36 | 0;
+ HEAP32[i10 + 28 >> 2] = HEAP32[i7 >> 2];
+ HEAP32[i10 + 40 >> 2] = HEAP32[i4 >> 2];
+ HEAP32[i10 + 0 >> 2] = HEAP32[i11 + 0 >> 2];
+ HEAP32[i10 + 4 >> 2] = HEAP32[i11 + 4 >> 2];
+ HEAP32[i10 + 8 >> 2] = HEAP32[i11 + 8 >> 2];
+ HEAP32[i10 + 12 >> 2] = HEAP32[i11 + 12 >> 2];
+ HEAP32[i10 + 16 >> 2] = HEAP32[i11 + 16 >> 2];
+ HEAP32[i10 + 20 >> 2] = HEAP32[i11 + 20 >> 2];
+ HEAP32[i10 + 32 >> 2] = HEAP32[i8 >> 2];
+ i9 = i4 + 24 | 0;
+ HEAP32[i10 + 36 >> 2] = i22;
+ __ZN15b2ContactSolverC2EP18b2ContactSolverDef(i3, i10);
+ i10 = i11 + 16 | 0;
+ L13 : do {
+  if ((HEAP32[i10 >> 2] | 0) > 0) {
+   i22 = 0;
+   do {
+    i22 = i22 + 1 | 0;
+    if (__ZN15b2ContactSolver27SolveTOIPositionConstraintsEii(i3, i15, i18) | 0) {
+     break L13;
+    }
+   } while ((i22 | 0) < (HEAP32[i10 >> 2] | 0));
+  }
+ } while (0);
+ i10 = i4 + 8 | 0;
+ i24 = (HEAP32[i8 >> 2] | 0) + (i15 * 12 | 0) | 0;
+ i25 = HEAP32[i24 + 4 >> 2] | 0;
+ i23 = (HEAP32[(HEAP32[i10 >> 2] | 0) + (i15 << 2) >> 2] | 0) + 36 | 0;
+ HEAP32[i23 >> 2] = HEAP32[i24 >> 2];
+ HEAP32[i23 + 4 >> 2] = i25;
+ i23 = HEAP32[i8 >> 2] | 0;
+ i25 = HEAP32[i10 >> 2] | 0;
+ HEAPF32[(HEAP32[i25 + (i15 << 2) >> 2] | 0) + 52 >> 2] = +HEAPF32[i23 + (i15 * 12 | 0) + 8 >> 2];
+ i23 = i23 + (i18 * 12 | 0) | 0;
+ i24 = HEAP32[i23 + 4 >> 2] | 0;
+ i25 = (HEAP32[i25 + (i18 << 2) >> 2] | 0) + 36 | 0;
+ HEAP32[i25 >> 2] = HEAP32[i23 >> 2];
+ HEAP32[i25 + 4 >> 2] = i24;
+ HEAPF32[(HEAP32[(HEAP32[i10 >> 2] | 0) + (i18 << 2) >> 2] | 0) + 52 >> 2] = +HEAPF32[(HEAP32[i8 >> 2] | 0) + (i18 * 12 | 0) + 8 >> 2];
+ __ZN15b2ContactSolver29InitializeVelocityConstraintsEv(i3);
+ i18 = i11 + 12 | 0;
+ if ((HEAP32[i18 >> 2] | 0) > 0) {
+  i15 = 0;
+  do {
+   __ZN15b2ContactSolver24SolveVelocityConstraintsEv(i3);
+   i15 = i15 + 1 | 0;
+  } while ((i15 | 0) < (HEAP32[i18 >> 2] | 0));
+ }
+ d16 = +HEAPF32[i11 >> 2];
+ if ((HEAP32[i6 >> 2] | 0) > 0) {
+  i15 = 0;
+  do {
+   i25 = HEAP32[i8 >> 2] | 0;
+   i11 = i25 + (i15 * 12 | 0) | 0;
+   i24 = i11;
+   d12 = +HEAPF32[i24 >> 2];
+   d14 = +HEAPF32[i24 + 4 >> 2];
+   d13 = +HEAPF32[i25 + (i15 * 12 | 0) + 8 >> 2];
+   i25 = HEAP32[i9 >> 2] | 0;
+   i24 = i25 + (i15 * 12 | 0) | 0;
+   d19 = +HEAPF32[i24 >> 2];
+   d20 = +HEAPF32[i24 + 4 >> 2];
+   d17 = +HEAPF32[i25 + (i15 * 12 | 0) + 8 >> 2];
+   d26 = d16 * d19;
+   d21 = d16 * d20;
+   d21 = d26 * d26 + d21 * d21;
+   if (d21 > 4.0) {
+    d26 = 2.0 / +Math_sqrt(+d21);
+    d19 = d19 * d26;
+    d20 = d20 * d26;
+   }
+   d21 = d16 * d17;
+   if (d21 * d21 > 2.4674012660980225) {
+    if (!(d21 > 0.0)) {
+     d21 = -d21;
+    }
+    d17 = d17 * (1.5707963705062866 / d21);
+   }
+   d21 = d12 + d16 * d19;
+   d14 = d14 + d16 * d20;
+   d26 = d13 + d16 * d17;
+   d12 = +d21;
+   d13 = +d14;
+   i25 = i11;
+   HEAPF32[i25 >> 2] = d12;
+   HEAPF32[i25 + 4 >> 2] = d13;
+   HEAPF32[(HEAP32[i8 >> 2] | 0) + (i15 * 12 | 0) + 8 >> 2] = d26;
+   d19 = +d19;
+   d20 = +d20;
+   i25 = (HEAP32[i9 >> 2] | 0) + (i15 * 12 | 0) | 0;
+   HEAPF32[i25 >> 2] = d19;
+   HEAPF32[i25 + 4 >> 2] = d20;
+   HEAPF32[(HEAP32[i9 >> 2] | 0) + (i15 * 12 | 0) + 8 >> 2] = d17;
+   i25 = HEAP32[(HEAP32[i10 >> 2] | 0) + (i15 << 2) >> 2] | 0;
+   i24 = i25 + 44 | 0;
+   HEAPF32[i24 >> 2] = d12;
+   HEAPF32[i24 + 4 >> 2] = d13;
+   HEAPF32[i25 + 56 >> 2] = d26;
+   i24 = i25 + 64 | 0;
+   HEAPF32[i24 >> 2] = d19;
+   HEAPF32[i24 + 4 >> 2] = d20;
+   HEAPF32[i25 + 72 >> 2] = d17;
+   d17 = +Math_sin(+d26);
+   HEAPF32[i25 + 20 >> 2] = d17;
+   d20 = +Math_cos(+d26);
+   HEAPF32[i25 + 24 >> 2] = d20;
+   d19 = +HEAPF32[i25 + 28 >> 2];
+   d26 = +HEAPF32[i25 + 32 >> 2];
+   d21 = +(d21 - (d20 * d19 - d17 * d26));
+   d26 = +(d14 - (d17 * d19 + d20 * d26));
+   i25 = i25 + 12 | 0;
+   HEAPF32[i25 >> 2] = d21;
+   HEAPF32[i25 + 4 >> 2] = d26;
+   i15 = i15 + 1 | 0;
+  } while ((i15 | 0) < (HEAP32[i6 >> 2] | 0));
+ }
+ i6 = HEAP32[i3 + 40 >> 2] | 0;
+ i4 = i4 + 4 | 0;
+ if ((HEAP32[i4 >> 2] | 0) == 0) {
+  __ZN15b2ContactSolverD2Ev(i3);
+  STACKTOP = i1;
+  return;
+ }
+ if ((HEAP32[i7 >> 2] | 0) <= 0) {
+  __ZN15b2ContactSolverD2Ev(i3);
+  STACKTOP = i1;
+  return;
+ }
+ i8 = i2 + 16 | 0;
+ i9 = 0;
+ do {
+  i10 = HEAP32[(HEAP32[i5 >> 2] | 0) + (i9 << 2) >> 2] | 0;
+  i11 = HEAP32[i6 + (i9 * 152 | 0) + 144 >> 2] | 0;
+  HEAP32[i8 >> 2] = i11;
+  if ((i11 | 0) > 0) {
+   i15 = 0;
+   do {
+    HEAPF32[i2 + (i15 << 2) >> 2] = +HEAPF32[i6 + (i9 * 152 | 0) + (i15 * 36 | 0) + 16 >> 2];
+    HEAPF32[i2 + (i15 << 2) + 8 >> 2] = +HEAPF32[i6 + (i9 * 152 | 0) + (i15 * 36 | 0) + 20 >> 2];
+    i15 = i15 + 1 | 0;
+   } while ((i15 | 0) != (i11 | 0));
+  }
+  i25 = HEAP32[i4 >> 2] | 0;
+  FUNCTION_TABLE_viii[HEAP32[(HEAP32[i25 >> 2] | 0) + 20 >> 2] & 3](i25, i10, i2);
+  i9 = i9 + 1 | 0;
+ } while ((i9 | 0) < (HEAP32[i7 >> 2] | 0));
+ __ZN15b2ContactSolverD2Ev(i3);
+ STACKTOP = i1;
+ return;
+}
+function __ZN20b2SeparationFunction10InitializeEPK14b2SimplexCachePK15b2DistanceProxyRK7b2SweepS5_S8_f(i2, i11, i13, i21, i12, i24, d9) {
+ i2 = i2 | 0;
+ i11 = i11 | 0;
+ i13 = i13 | 0;
+ i21 = i21 | 0;
+ i12 = i12 | 0;
+ i24 = i24 | 0;
+ d9 = +d9;
+ var i1 = 0, d3 = 0.0, d4 = 0.0, d5 = 0.0, d6 = 0.0, d7 = 0.0, d8 = 0.0, d10 = 0.0, i14 = 0, d15 = 0.0, d16 = 0.0, d17 = 0.0, d18 = 0.0, d19 = 0.0, d20 = 0.0, d22 = 0.0, i23 = 0, i25 = 0, i26 = 0, i27 = 0, d28 = 0.0, d29 = 0.0;
+ i1 = STACKTOP;
+ HEAP32[i2 >> 2] = i13;
+ HEAP32[i2 + 4 >> 2] = i12;
+ i14 = HEAP16[i11 + 4 >> 1] | 0;
+ if (!(i14 << 16 >> 16 != 0 & (i14 & 65535) < 3)) {
+  ___assert_fail(3744, 3560, 50, 3768);
+ }
+ i23 = i2 + 8 | 0;
+ i25 = i23 + 0 | 0;
+ i27 = i21 + 0 | 0;
+ i26 = i25 + 36 | 0;
+ do {
+  HEAP32[i25 >> 2] = HEAP32[i27 >> 2];
+  i25 = i25 + 4 | 0;
+  i27 = i27 + 4 | 0;
+ } while ((i25 | 0) < (i26 | 0));
+ i21 = i2 + 44 | 0;
+ i25 = i21 + 0 | 0;
+ i27 = i24 + 0 | 0;
+ i26 = i25 + 36 | 0;
+ do {
+  HEAP32[i25 >> 2] = HEAP32[i27 >> 2];
+  i25 = i25 + 4 | 0;
+  i27 = i27 + 4 | 0;
+ } while ((i25 | 0) < (i26 | 0));
+ d19 = 1.0 - d9;
+ d4 = d19 * +HEAPF32[i2 + 32 >> 2] + +HEAPF32[i2 + 36 >> 2] * d9;
+ d3 = +Math_sin(+d4);
+ d4 = +Math_cos(+d4);
+ d7 = +HEAPF32[i23 >> 2];
+ d5 = +HEAPF32[i2 + 12 >> 2];
+ d8 = d19 * +HEAPF32[i2 + 16 >> 2] + +HEAPF32[i2 + 24 >> 2] * d9 - (d4 * d7 - d3 * d5);
+ d5 = d19 * +HEAPF32[i2 + 20 >> 2] + +HEAPF32[i2 + 28 >> 2] * d9 - (d3 * d7 + d4 * d5);
+ d7 = d19 * +HEAPF32[i2 + 68 >> 2] + +HEAPF32[i2 + 72 >> 2] * d9;
+ d6 = +Math_sin(+d7);
+ d7 = +Math_cos(+d7);
+ d20 = +HEAPF32[i21 >> 2];
+ d22 = +HEAPF32[i2 + 48 >> 2];
+ d10 = d19 * +HEAPF32[i2 + 52 >> 2] + +HEAPF32[i2 + 60 >> 2] * d9 - (d7 * d20 - d6 * d22);
+ d9 = d19 * +HEAPF32[i2 + 56 >> 2] + +HEAPF32[i2 + 64 >> 2] * d9 - (d6 * d20 + d7 * d22);
+ if (i14 << 16 >> 16 == 1) {
+  HEAP32[i2 + 80 >> 2] = 0;
+  i14 = HEAPU8[i11 + 6 | 0] | 0;
+  if ((HEAP32[i13 + 20 >> 2] | 0) <= (i14 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i27 = (HEAP32[i13 + 16 >> 2] | 0) + (i14 << 3) | 0;
+  d15 = +HEAPF32[i27 >> 2];
+  d16 = +HEAPF32[i27 + 4 >> 2];
+  i11 = HEAPU8[i11 + 9 | 0] | 0;
+  if ((HEAP32[i12 + 20 >> 2] | 0) <= (i11 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i11 = (HEAP32[i12 + 16 >> 2] | 0) + (i11 << 3) | 0;
+  d20 = +HEAPF32[i11 >> 2];
+  d22 = +HEAPF32[i11 + 4 >> 2];
+  i11 = i2 + 92 | 0;
+  d8 = d10 + (d7 * d20 - d6 * d22) - (d8 + (d4 * d15 - d3 * d16));
+  d4 = d9 + (d6 * d20 + d7 * d22) - (d5 + (d3 * d15 + d4 * d16));
+  d22 = +d8;
+  d3 = +d4;
+  i27 = i11;
+  HEAPF32[i27 >> 2] = d22;
+  HEAPF32[i27 + 4 >> 2] = d3;
+  d3 = +Math_sqrt(+(d8 * d8 + d4 * d4));
+  if (d3 < 1.1920928955078125e-7) {
+   d22 = 0.0;
+   STACKTOP = i1;
+   return +d22;
+  }
+  d22 = 1.0 / d3;
+  HEAPF32[i11 >> 2] = d8 * d22;
+  HEAPF32[i2 + 96 >> 2] = d4 * d22;
+  d22 = d3;
+  STACKTOP = i1;
+  return +d22;
+ }
+ i14 = i11 + 6 | 0;
+ i21 = i11 + 7 | 0;
+ i23 = i2 + 80 | 0;
+ if ((HEAP8[i14] | 0) == (HEAP8[i21] | 0)) {
+  HEAP32[i23 >> 2] = 2;
+  i23 = HEAPU8[i11 + 9 | 0] | 0;
+  i21 = HEAP32[i12 + 20 >> 2] | 0;
+  if ((i21 | 0) <= (i23 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i12 = HEAP32[i12 + 16 >> 2] | 0;
+  i27 = i12 + (i23 << 3) | 0;
+  d16 = +HEAPF32[i27 >> 2];
+  d15 = +HEAPF32[i27 + 4 >> 2];
+  i11 = HEAPU8[i11 + 10 | 0] | 0;
+  if ((i21 | 0) <= (i11 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i11 = i12 + (i11 << 3) | 0;
+  d20 = +HEAPF32[i11 >> 2];
+  d18 = +HEAPF32[i11 + 4 >> 2];
+  i11 = i2 + 92 | 0;
+  d22 = d20 - d16;
+  d19 = d18 - d15;
+  d17 = -d22;
+  d29 = +d19;
+  d28 = +d17;
+  i27 = i11;
+  HEAPF32[i27 >> 2] = d29;
+  HEAPF32[i27 + 4 >> 2] = d28;
+  d22 = +Math_sqrt(+(d19 * d19 + d22 * d22));
+  if (!(d22 < 1.1920928955078125e-7)) {
+   d29 = 1.0 / d22;
+   d19 = d19 * d29;
+   HEAPF32[i11 >> 2] = d19;
+   d17 = d29 * d17;
+   HEAPF32[i2 + 96 >> 2] = d17;
+  }
+  d16 = (d16 + d20) * .5;
+  d15 = (d15 + d18) * .5;
+  d28 = +d16;
+  d29 = +d15;
+  i2 = i2 + 84 | 0;
+  HEAPF32[i2 >> 2] = d28;
+  HEAPF32[i2 + 4 >> 2] = d29;
+  i2 = HEAPU8[i14] | 0;
+  if ((HEAP32[i13 + 20 >> 2] | 0) <= (i2 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i27 = (HEAP32[i13 + 16 >> 2] | 0) + (i2 << 3) | 0;
+  d28 = +HEAPF32[i27 >> 2];
+  d29 = +HEAPF32[i27 + 4 >> 2];
+  d3 = (d7 * d19 - d6 * d17) * (d8 + (d4 * d28 - d3 * d29) - (d10 + (d7 * d16 - d6 * d15))) + (d6 * d19 + d7 * d17) * (d5 + (d3 * d28 + d4 * d29) - (d9 + (d6 * d16 + d7 * d15)));
+  if (!(d3 < 0.0)) {
+   d29 = d3;
+   STACKTOP = i1;
+   return +d29;
+  }
+  d28 = +-d19;
+  d29 = +-d17;
+  i27 = i11;
+  HEAPF32[i27 >> 2] = d28;
+  HEAPF32[i27 + 4 >> 2] = d29;
+  d29 = -d3;
+  STACKTOP = i1;
+  return +d29;
+ } else {
+  HEAP32[i23 >> 2] = 1;
+  i23 = HEAPU8[i14] | 0;
+  i14 = HEAP32[i13 + 20 >> 2] | 0;
+  if ((i14 | 0) <= (i23 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i13 = HEAP32[i13 + 16 >> 2] | 0;
+  i27 = i13 + (i23 << 3) | 0;
+  d16 = +HEAPF32[i27 >> 2];
+  d15 = +HEAPF32[i27 + 4 >> 2];
+  i21 = HEAPU8[i21] | 0;
+  if ((i14 | 0) <= (i21 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i13 = i13 + (i21 << 3) | 0;
+  d20 = +HEAPF32[i13 >> 2];
+  d18 = +HEAPF32[i13 + 4 >> 2];
+  i13 = i2 + 92 | 0;
+  d22 = d20 - d16;
+  d19 = d18 - d15;
+  d17 = -d22;
+  d28 = +d19;
+  d29 = +d17;
+  i27 = i13;
+  HEAPF32[i27 >> 2] = d28;
+  HEAPF32[i27 + 4 >> 2] = d29;
+  d22 = +Math_sqrt(+(d19 * d19 + d22 * d22));
+  if (!(d22 < 1.1920928955078125e-7)) {
+   d29 = 1.0 / d22;
+   d19 = d19 * d29;
+   HEAPF32[i13 >> 2] = d19;
+   d17 = d29 * d17;
+   HEAPF32[i2 + 96 >> 2] = d17;
+  }
+  d16 = (d16 + d20) * .5;
+  d15 = (d15 + d18) * .5;
+  d28 = +d16;
+  d29 = +d15;
+  i2 = i2 + 84 | 0;
+  HEAPF32[i2 >> 2] = d28;
+  HEAPF32[i2 + 4 >> 2] = d29;
+  i2 = HEAPU8[i11 + 9 | 0] | 0;
+  if ((HEAP32[i12 + 20 >> 2] | 0) <= (i2 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i27 = (HEAP32[i12 + 16 >> 2] | 0) + (i2 << 3) | 0;
+  d28 = +HEAPF32[i27 >> 2];
+  d29 = +HEAPF32[i27 + 4 >> 2];
+  d3 = (d4 * d19 - d3 * d17) * (d10 + (d7 * d28 - d6 * d29) - (d8 + (d4 * d16 - d3 * d15))) + (d3 * d19 + d4 * d17) * (d9 + (d6 * d28 + d7 * d29) - (d5 + (d3 * d16 + d4 * d15)));
+  if (!(d3 < 0.0)) {
+   d29 = d3;
+   STACKTOP = i1;
+   return +d29;
+  }
+  d28 = +-d19;
+  d29 = +-d17;
+  i27 = i13;
+  HEAPF32[i27 >> 2] = d28;
+  HEAPF32[i27 + 4 >> 2] = d29;
+  d29 = -d3;
+  STACKTOP = i1;
+  return +d29;
+ }
+ return 0.0;
+}
+function __ZNK20b2SeparationFunction17FindMinSeparationEPiS0_f(i12, i10, i9, d5) {
+ i12 = i12 | 0;
+ i10 = i10 | 0;
+ i9 = i9 | 0;
+ d5 = +d5;
+ var i1 = 0, d2 = 0.0, d3 = 0.0, d4 = 0.0, d6 = 0.0, d7 = 0.0, d8 = 0.0, d11 = 0.0, d13 = 0.0, d14 = 0.0, i15 = 0, i16 = 0, d17 = 0.0, d18 = 0.0, i19 = 0, d20 = 0.0, d21 = 0.0, i22 = 0, d23 = 0.0, d24 = 0.0, i25 = 0, i26 = 0, i27 = 0;
+ i1 = STACKTOP;
+ d21 = 1.0 - d5;
+ d6 = d21 * +HEAPF32[i12 + 32 >> 2] + +HEAPF32[i12 + 36 >> 2] * d5;
+ d7 = +Math_sin(+d6);
+ d6 = +Math_cos(+d6);
+ d3 = +HEAPF32[i12 + 8 >> 2];
+ d8 = +HEAPF32[i12 + 12 >> 2];
+ d11 = d21 * +HEAPF32[i12 + 16 >> 2] + +HEAPF32[i12 + 24 >> 2] * d5 - (d6 * d3 - d7 * d8);
+ d8 = d21 * +HEAPF32[i12 + 20 >> 2] + +HEAPF32[i12 + 28 >> 2] * d5 - (d7 * d3 + d6 * d8);
+ d3 = d21 * +HEAPF32[i12 + 68 >> 2] + +HEAPF32[i12 + 72 >> 2] * d5;
+ d2 = +Math_sin(+d3);
+ d3 = +Math_cos(+d3);
+ d23 = +HEAPF32[i12 + 44 >> 2];
+ d24 = +HEAPF32[i12 + 48 >> 2];
+ d4 = d21 * +HEAPF32[i12 + 52 >> 2] + +HEAPF32[i12 + 60 >> 2] * d5 - (d3 * d23 - d2 * d24);
+ d5 = d21 * +HEAPF32[i12 + 56 >> 2] + +HEAPF32[i12 + 64 >> 2] * d5 - (d2 * d23 + d3 * d24);
+ i19 = HEAP32[i12 + 80 >> 2] | 0;
+ if ((i19 | 0) == 1) {
+  d23 = +HEAPF32[i12 + 92 >> 2];
+  d14 = +HEAPF32[i12 + 96 >> 2];
+  d13 = d6 * d23 - d7 * d14;
+  d14 = d7 * d23 + d6 * d14;
+  d23 = +HEAPF32[i12 + 84 >> 2];
+  d24 = +HEAPF32[i12 + 88 >> 2];
+  d11 = d11 + (d6 * d23 - d7 * d24);
+  d6 = d8 + (d7 * d23 + d6 * d24);
+  d7 = -d13;
+  d24 = -d14;
+  d8 = d3 * d7 + d2 * d24;
+  d7 = d3 * d24 - d2 * d7;
+  HEAP32[i10 >> 2] = -1;
+  i25 = i12 + 4 | 0;
+  i22 = HEAP32[i25 >> 2] | 0;
+  i19 = HEAP32[i22 + 16 >> 2] | 0;
+  i22 = HEAP32[i22 + 20 >> 2] | 0;
+  if ((i22 | 0) > 1) {
+   i10 = 0;
+   d18 = d7 * +HEAPF32[i19 + 4 >> 2] + d8 * +HEAPF32[i19 >> 2];
+   i12 = 1;
+   while (1) {
+    d17 = d8 * +HEAPF32[i19 + (i12 << 3) >> 2] + d7 * +HEAPF32[i19 + (i12 << 3) + 4 >> 2];
+    i16 = d17 > d18;
+    i10 = i16 ? i12 : i10;
+    i12 = i12 + 1 | 0;
+    if ((i12 | 0) == (i22 | 0)) {
+     break;
+    } else {
+     d18 = i16 ? d17 : d18;
+    }
+   }
+   HEAP32[i9 >> 2] = i10;
+   if ((i10 | 0) > -1) {
+    i15 = i10;
+   } else {
+    ___assert_fail(3640, 3672, 103, 3704);
+   }
+  } else {
+   HEAP32[i9 >> 2] = 0;
+   i15 = 0;
+  }
+  i9 = HEAP32[i25 >> 2] | 0;
+  if ((HEAP32[i9 + 20 >> 2] | 0) <= (i15 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i27 = (HEAP32[i9 + 16 >> 2] | 0) + (i15 << 3) | 0;
+  d23 = +HEAPF32[i27 >> 2];
+  d24 = +HEAPF32[i27 + 4 >> 2];
+  d24 = d13 * (d4 + (d3 * d23 - d2 * d24) - d11) + d14 * (d5 + (d2 * d23 + d3 * d24) - d6);
+  STACKTOP = i1;
+  return +d24;
+ } else if ((i19 | 0) == 0) {
+  d13 = +HEAPF32[i12 + 92 >> 2];
+  d14 = +HEAPF32[i12 + 96 >> 2];
+  d21 = d6 * d13 + d7 * d14;
+  d24 = d6 * d14 - d7 * d13;
+  d17 = -d13;
+  d23 = -d14;
+  d18 = d3 * d17 + d2 * d23;
+  d17 = d3 * d23 - d2 * d17;
+  i15 = HEAP32[i12 >> 2] | 0;
+  i16 = HEAP32[i15 + 16 >> 2] | 0;
+  i15 = i15 + 20 | 0;
+  i19 = HEAP32[i15 >> 2] | 0;
+  if ((i19 | 0) > 1) {
+   i25 = 0;
+   d23 = d24 * +HEAPF32[i16 + 4 >> 2] + d21 * +HEAPF32[i16 >> 2];
+   i26 = 1;
+   while (1) {
+    d20 = d21 * +HEAPF32[i16 + (i26 << 3) >> 2] + d24 * +HEAPF32[i16 + (i26 << 3) + 4 >> 2];
+    i22 = d20 > d23;
+    i25 = i22 ? i26 : i25;
+    i26 = i26 + 1 | 0;
+    if ((i26 | 0) == (i19 | 0)) {
+     break;
+    } else {
+     d23 = i22 ? d20 : d23;
+    }
+   }
+  } else {
+   i25 = 0;
+  }
+  HEAP32[i10 >> 2] = i25;
+  i19 = HEAP32[i12 + 4 >> 2] | 0;
+  i12 = HEAP32[i19 + 16 >> 2] | 0;
+  i19 = i19 + 20 | 0;
+  i25 = HEAP32[i19 >> 2] | 0;
+  if ((i25 | 0) > 1) {
+   i27 = 0;
+   d20 = d17 * +HEAPF32[i12 + 4 >> 2] + d18 * +HEAPF32[i12 >> 2];
+   i26 = 1;
+   while (1) {
+    d21 = d18 * +HEAPF32[i12 + (i26 << 3) >> 2] + d17 * +HEAPF32[i12 + (i26 << 3) + 4 >> 2];
+    i22 = d21 > d20;
+    i27 = i22 ? i26 : i27;
+    i26 = i26 + 1 | 0;
+    if ((i26 | 0) == (i25 | 0)) {
+     break;
+    } else {
+     d20 = i22 ? d21 : d20;
+    }
+   }
+  } else {
+   i27 = 0;
+  }
+  HEAP32[i9 >> 2] = i27;
+  i9 = HEAP32[i10 >> 2] | 0;
+  if (!((i9 | 0) > -1)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  if ((HEAP32[i15 >> 2] | 0) <= (i9 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i26 = i16 + (i9 << 3) | 0;
+  d18 = +HEAPF32[i26 >> 2];
+  d17 = +HEAPF32[i26 + 4 >> 2];
+  if (!((i27 | 0) > -1)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  if ((HEAP32[i19 >> 2] | 0) <= (i27 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i27 = i12 + (i27 << 3) | 0;
+  d23 = +HEAPF32[i27 >> 2];
+  d24 = +HEAPF32[i27 + 4 >> 2];
+  d24 = d13 * (d4 + (d3 * d23 - d2 * d24) - (d11 + (d6 * d18 - d7 * d17))) + d14 * (d5 + (d2 * d23 + d3 * d24) - (d8 + (d7 * d18 + d6 * d17)));
+  STACKTOP = i1;
+  return +d24;
+ } else if ((i19 | 0) == 2) {
+  d23 = +HEAPF32[i12 + 92 >> 2];
+  d13 = +HEAPF32[i12 + 96 >> 2];
+  d14 = d3 * d23 - d2 * d13;
+  d13 = d2 * d23 + d3 * d13;
+  d23 = +HEAPF32[i12 + 84 >> 2];
+  d24 = +HEAPF32[i12 + 88 >> 2];
+  d4 = d4 + (d3 * d23 - d2 * d24);
+  d2 = d5 + (d2 * d23 + d3 * d24);
+  d3 = -d14;
+  d24 = -d13;
+  d5 = d6 * d3 + d7 * d24;
+  d3 = d6 * d24 - d7 * d3;
+  HEAP32[i9 >> 2] = -1;
+  i22 = HEAP32[i12 >> 2] | 0;
+  i15 = HEAP32[i22 + 16 >> 2] | 0;
+  i22 = HEAP32[i22 + 20 >> 2] | 0;
+  if ((i22 | 0) > 1) {
+   i9 = 0;
+   d17 = d3 * +HEAPF32[i15 + 4 >> 2] + d5 * +HEAPF32[i15 >> 2];
+   i19 = 1;
+   while (1) {
+    d18 = d5 * +HEAPF32[i15 + (i19 << 3) >> 2] + d3 * +HEAPF32[i15 + (i19 << 3) + 4 >> 2];
+    i25 = d18 > d17;
+    i9 = i25 ? i19 : i9;
+    i19 = i19 + 1 | 0;
+    if ((i19 | 0) == (i22 | 0)) {
+     break;
+    } else {
+     d17 = i25 ? d18 : d17;
+    }
+   }
+   HEAP32[i10 >> 2] = i9;
+   if ((i9 | 0) > -1) {
+    i16 = i9;
+   } else {
+    ___assert_fail(3640, 3672, 103, 3704);
+   }
+  } else {
+   HEAP32[i10 >> 2] = 0;
+   i16 = 0;
+  }
+  i9 = HEAP32[i12 >> 2] | 0;
+  if ((HEAP32[i9 + 20 >> 2] | 0) <= (i16 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i27 = (HEAP32[i9 + 16 >> 2] | 0) + (i16 << 3) | 0;
+  d23 = +HEAPF32[i27 >> 2];
+  d24 = +HEAPF32[i27 + 4 >> 2];
+  d24 = d14 * (d11 + (d6 * d23 - d7 * d24) - d4) + d13 * (d8 + (d7 * d23 + d6 * d24) - d2);
+  STACKTOP = i1;
+  return +d24;
+ } else {
+  ___assert_fail(3616, 3560, 183, 3720);
+ }
+ return 0.0;
+}
+function __ZN13b2DynamicTree10InsertLeafEi(i3, i4) {
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, d5 = 0.0, d6 = 0.0, d7 = 0.0, d8 = 0.0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, d13 = 0.0, d14 = 0.0, d15 = 0.0, d16 = 0.0, d17 = 0.0, d18 = 0.0, d19 = 0.0, d20 = 0.0, d21 = 0.0, d22 = 0.0, d23 = 0.0, i24 = 0;
+ i1 = STACKTOP;
+ i11 = i3 + 24 | 0;
+ HEAP32[i11 >> 2] = (HEAP32[i11 >> 2] | 0) + 1;
+ i11 = HEAP32[i3 >> 2] | 0;
+ if ((i11 | 0) == -1) {
+  HEAP32[i3 >> 2] = i4;
+  HEAP32[(HEAP32[i3 + 4 >> 2] | 0) + (i4 * 36 | 0) + 20 >> 2] = -1;
+  STACKTOP = i1;
+  return;
+ }
+ i2 = i3 + 4 | 0;
+ i9 = HEAP32[i2 >> 2] | 0;
+ d8 = +HEAPF32[i9 + (i4 * 36 | 0) >> 2];
+ d7 = +HEAPF32[i9 + (i4 * 36 | 0) + 4 >> 2];
+ d6 = +HEAPF32[i9 + (i4 * 36 | 0) + 8 >> 2];
+ d5 = +HEAPF32[i9 + (i4 * 36 | 0) + 12 >> 2];
+ i10 = HEAP32[i9 + (i11 * 36 | 0) + 24 >> 2] | 0;
+ L5 : do {
+  if (!((i10 | 0) == -1)) {
+   do {
+    i12 = HEAP32[i9 + (i11 * 36 | 0) + 28 >> 2] | 0;
+    d14 = +HEAPF32[i9 + (i11 * 36 | 0) + 8 >> 2];
+    d15 = +HEAPF32[i9 + (i11 * 36 | 0) >> 2];
+    d17 = +HEAPF32[i9 + (i11 * 36 | 0) + 12 >> 2];
+    d16 = +HEAPF32[i9 + (i11 * 36 | 0) + 4 >> 2];
+    d21 = ((d14 > d6 ? d14 : d6) - (d15 < d8 ? d15 : d8) + ((d17 > d5 ? d17 : d5) - (d16 < d7 ? d16 : d7))) * 2.0;
+    d13 = d21 * 2.0;
+    d14 = (d21 - (d14 - d15 + (d17 - d16)) * 2.0) * 2.0;
+    d21 = +HEAPF32[i9 + (i10 * 36 | 0) >> 2];
+    d16 = d8 < d21 ? d8 : d21;
+    d17 = +HEAPF32[i9 + (i10 * 36 | 0) + 4 >> 2];
+    d18 = d7 < d17 ? d7 : d17;
+    d19 = +HEAPF32[i9 + (i10 * 36 | 0) + 8 >> 2];
+    d20 = d6 > d19 ? d6 : d19;
+    d15 = +HEAPF32[i9 + (i10 * 36 | 0) + 12 >> 2];
+    d22 = d5 > d15 ? d5 : d15;
+    if ((HEAP32[i9 + (i10 * 36 | 0) + 24 >> 2] | 0) == -1) {
+     d15 = (d20 - d16 + (d22 - d18)) * 2.0;
+    } else {
+     d15 = (d20 - d16 + (d22 - d18)) * 2.0 - (d19 - d21 + (d15 - d17)) * 2.0;
+    }
+    d15 = d14 + d15;
+    d17 = +HEAPF32[i9 + (i12 * 36 | 0) >> 2];
+    d18 = d8 < d17 ? d8 : d17;
+    d23 = +HEAPF32[i9 + (i12 * 36 | 0) + 4 >> 2];
+    d22 = d7 < d23 ? d7 : d23;
+    d21 = +HEAPF32[i9 + (i12 * 36 | 0) + 8 >> 2];
+    d20 = d6 > d21 ? d6 : d21;
+    d19 = +HEAPF32[i9 + (i12 * 36 | 0) + 12 >> 2];
+    d16 = d5 > d19 ? d5 : d19;
+    if ((HEAP32[i9 + (i12 * 36 | 0) + 24 >> 2] | 0) == -1) {
+     d16 = (d20 - d18 + (d16 - d22)) * 2.0;
+    } else {
+     d16 = (d20 - d18 + (d16 - d22)) * 2.0 - (d21 - d17 + (d19 - d23)) * 2.0;
+    }
+    d14 = d14 + d16;
+    if (d13 < d15 & d13 < d14) {
+     break L5;
+    }
+    i11 = d15 < d14 ? i10 : i12;
+    i10 = HEAP32[i9 + (i11 * 36 | 0) + 24 >> 2] | 0;
+   } while (!((i10 | 0) == -1));
+  }
+ } while (0);
+ i9 = HEAP32[i9 + (i11 * 36 | 0) + 20 >> 2] | 0;
+ i10 = __ZN13b2DynamicTree12AllocateNodeEv(i3) | 0;
+ i12 = HEAP32[i2 >> 2] | 0;
+ HEAP32[i12 + (i10 * 36 | 0) + 20 >> 2] = i9;
+ HEAP32[i12 + (i10 * 36 | 0) + 16 >> 2] = 0;
+ i12 = HEAP32[i2 >> 2] | 0;
+ d14 = +HEAPF32[i12 + (i11 * 36 | 0) >> 2];
+ d13 = +HEAPF32[i12 + (i11 * 36 | 0) + 4 >> 2];
+ d8 = +(d8 < d14 ? d8 : d14);
+ d7 = +(d7 < d13 ? d7 : d13);
+ i24 = i12 + (i10 * 36 | 0) | 0;
+ HEAPF32[i24 >> 2] = d8;
+ HEAPF32[i24 + 4 >> 2] = d7;
+ d8 = +HEAPF32[i12 + (i11 * 36 | 0) + 8 >> 2];
+ d7 = +HEAPF32[i12 + (i11 * 36 | 0) + 12 >> 2];
+ d6 = +(d6 > d8 ? d6 : d8);
+ d23 = +(d5 > d7 ? d5 : d7);
+ i12 = i12 + (i10 * 36 | 0) + 8 | 0;
+ HEAPF32[i12 >> 2] = d6;
+ HEAPF32[i12 + 4 >> 2] = d23;
+ i12 = HEAP32[i2 >> 2] | 0;
+ HEAP32[i12 + (i10 * 36 | 0) + 32 >> 2] = (HEAP32[i12 + (i11 * 36 | 0) + 32 >> 2] | 0) + 1;
+ if ((i9 | 0) == -1) {
+  HEAP32[i12 + (i10 * 36 | 0) + 24 >> 2] = i11;
+  HEAP32[i12 + (i10 * 36 | 0) + 28 >> 2] = i4;
+  HEAP32[i12 + (i11 * 36 | 0) + 20 >> 2] = i10;
+  i24 = i12 + (i4 * 36 | 0) + 20 | 0;
+  HEAP32[i24 >> 2] = i10;
+  HEAP32[i3 >> 2] = i10;
+  i10 = HEAP32[i24 >> 2] | 0;
+ } else {
+  i24 = i12 + (i9 * 36 | 0) + 24 | 0;
+  if ((HEAP32[i24 >> 2] | 0) == (i11 | 0)) {
+   HEAP32[i24 >> 2] = i10;
+  } else {
+   HEAP32[i12 + (i9 * 36 | 0) + 28 >> 2] = i10;
+  }
+  HEAP32[i12 + (i10 * 36 | 0) + 24 >> 2] = i11;
+  HEAP32[i12 + (i10 * 36 | 0) + 28 >> 2] = i4;
+  HEAP32[i12 + (i11 * 36 | 0) + 20 >> 2] = i10;
+  HEAP32[i12 + (i4 * 36 | 0) + 20 >> 2] = i10;
+ }
+ if ((i10 | 0) == -1) {
+  STACKTOP = i1;
+  return;
+ }
+ while (1) {
+  i9 = __ZN13b2DynamicTree7BalanceEi(i3, i10) | 0;
+  i4 = HEAP32[i2 >> 2] | 0;
+  i11 = HEAP32[i4 + (i9 * 36 | 0) + 24 >> 2] | 0;
+  i10 = HEAP32[i4 + (i9 * 36 | 0) + 28 >> 2] | 0;
+  if ((i11 | 0) == -1) {
+   i2 = 20;
+   break;
+  }
+  if ((i10 | 0) == -1) {
+   i2 = 22;
+   break;
+  }
+  i12 = HEAP32[i4 + (i11 * 36 | 0) + 32 >> 2] | 0;
+  i24 = HEAP32[i4 + (i10 * 36 | 0) + 32 >> 2] | 0;
+  HEAP32[i4 + (i9 * 36 | 0) + 32 >> 2] = ((i12 | 0) > (i24 | 0) ? i12 : i24) + 1;
+  d7 = +HEAPF32[i4 + (i11 * 36 | 0) >> 2];
+  d8 = +HEAPF32[i4 + (i10 * 36 | 0) >> 2];
+  d5 = +HEAPF32[i4 + (i11 * 36 | 0) + 4 >> 2];
+  d6 = +HEAPF32[i4 + (i10 * 36 | 0) + 4 >> 2];
+  d7 = +(d7 < d8 ? d7 : d8);
+  d5 = +(d5 < d6 ? d5 : d6);
+  i24 = i4 + (i9 * 36 | 0) | 0;
+  HEAPF32[i24 >> 2] = d7;
+  HEAPF32[i24 + 4 >> 2] = d5;
+  d5 = +HEAPF32[i4 + (i11 * 36 | 0) + 8 >> 2];
+  d6 = +HEAPF32[i4 + (i10 * 36 | 0) + 8 >> 2];
+  d7 = +HEAPF32[i4 + (i11 * 36 | 0) + 12 >> 2];
+  d8 = +HEAPF32[i4 + (i10 * 36 | 0) + 12 >> 2];
+  d5 = +(d5 > d6 ? d5 : d6);
+  d23 = +(d7 > d8 ? d7 : d8);
+  i10 = i4 + (i9 * 36 | 0) + 8 | 0;
+  HEAPF32[i10 >> 2] = d5;
+  HEAPF32[i10 + 4 >> 2] = d23;
+  i10 = HEAP32[(HEAP32[i2 >> 2] | 0) + (i9 * 36 | 0) + 20 >> 2] | 0;
+  if ((i10 | 0) == -1) {
+   i2 = 24;
+   break;
+  }
+ }
+ if ((i2 | 0) == 20) {
+  ___assert_fail(3168, 2944, 307, 3184);
+ } else if ((i2 | 0) == 22) {
+  ___assert_fail(3200, 2944, 308, 3184);
+ } else if ((i2 | 0) == 24) {
+  STACKTOP = i1;
+  return;
+ }
+}
+function __ZN15b2ContactSolverC2EP18b2ContactSolverDef(i7, i5) {
+ i7 = i7 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, d15 = 0.0, d16 = 0.0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0;
+ i1 = STACKTOP;
+ HEAP32[i7 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+ HEAP32[i7 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+ HEAP32[i7 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+ HEAP32[i7 + 12 >> 2] = HEAP32[i5 + 12 >> 2];
+ HEAP32[i7 + 16 >> 2] = HEAP32[i5 + 16 >> 2];
+ HEAP32[i7 + 20 >> 2] = HEAP32[i5 + 20 >> 2];
+ i14 = HEAP32[i5 + 40 >> 2] | 0;
+ i9 = i7 + 32 | 0;
+ HEAP32[i9 >> 2] = i14;
+ i2 = HEAP32[i5 + 28 >> 2] | 0;
+ i4 = i7 + 48 | 0;
+ HEAP32[i4 >> 2] = i2;
+ i3 = i7 + 36 | 0;
+ HEAP32[i3 >> 2] = __ZN16b2StackAllocator8AllocateEi(i14, i2 * 88 | 0) | 0;
+ i2 = i7 + 40 | 0;
+ HEAP32[i2 >> 2] = __ZN16b2StackAllocator8AllocateEi(HEAP32[i9 >> 2] | 0, (HEAP32[i4 >> 2] | 0) * 152 | 0) | 0;
+ HEAP32[i7 + 24 >> 2] = HEAP32[i5 + 32 >> 2];
+ HEAP32[i7 + 28 >> 2] = HEAP32[i5 + 36 >> 2];
+ i9 = HEAP32[i5 + 24 >> 2] | 0;
+ i5 = i7 + 44 | 0;
+ HEAP32[i5 >> 2] = i9;
+ if ((HEAP32[i4 >> 2] | 0) <= 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i6 = i7 + 20 | 0;
+ i7 = i7 + 8 | 0;
+ i8 = 0;
+ while (1) {
+  i10 = HEAP32[i9 + (i8 << 2) >> 2] | 0;
+  i11 = HEAP32[i10 + 48 >> 2] | 0;
+  i12 = HEAP32[i10 + 52 >> 2] | 0;
+  i14 = HEAP32[i11 + 8 >> 2] | 0;
+  i13 = HEAP32[i12 + 8 >> 2] | 0;
+  i9 = HEAP32[i10 + 124 >> 2] | 0;
+  if ((i9 | 0) <= 0) {
+   i2 = 4;
+   break;
+  }
+  d15 = +HEAPF32[(HEAP32[i12 + 12 >> 2] | 0) + 8 >> 2];
+  d16 = +HEAPF32[(HEAP32[i11 + 12 >> 2] | 0) + 8 >> 2];
+  i12 = HEAP32[i2 >> 2] | 0;
+  HEAPF32[i12 + (i8 * 152 | 0) + 136 >> 2] = +HEAPF32[i10 + 136 >> 2];
+  HEAPF32[i12 + (i8 * 152 | 0) + 140 >> 2] = +HEAPF32[i10 + 140 >> 2];
+  i22 = i14 + 8 | 0;
+  HEAP32[i12 + (i8 * 152 | 0) + 112 >> 2] = HEAP32[i22 >> 2];
+  i21 = i13 + 8 | 0;
+  HEAP32[i12 + (i8 * 152 | 0) + 116 >> 2] = HEAP32[i21 >> 2];
+  i19 = i14 + 120 | 0;
+  HEAPF32[i12 + (i8 * 152 | 0) + 120 >> 2] = +HEAPF32[i19 >> 2];
+  i20 = i13 + 120 | 0;
+  HEAPF32[i12 + (i8 * 152 | 0) + 124 >> 2] = +HEAPF32[i20 >> 2];
+  i18 = i14 + 128 | 0;
+  HEAPF32[i12 + (i8 * 152 | 0) + 128 >> 2] = +HEAPF32[i18 >> 2];
+  i17 = i13 + 128 | 0;
+  HEAPF32[i12 + (i8 * 152 | 0) + 132 >> 2] = +HEAPF32[i17 >> 2];
+  HEAP32[i12 + (i8 * 152 | 0) + 148 >> 2] = i8;
+  HEAP32[i12 + (i8 * 152 | 0) + 144 >> 2] = i9;
+  i11 = i12 + (i8 * 152 | 0) + 80 | 0;
+  HEAP32[i11 + 0 >> 2] = 0;
+  HEAP32[i11 + 4 >> 2] = 0;
+  HEAP32[i11 + 8 >> 2] = 0;
+  HEAP32[i11 + 12 >> 2] = 0;
+  HEAP32[i11 + 16 >> 2] = 0;
+  HEAP32[i11 + 20 >> 2] = 0;
+  HEAP32[i11 + 24 >> 2] = 0;
+  HEAP32[i11 + 28 >> 2] = 0;
+  i11 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i11 + (i8 * 88 | 0) + 32 >> 2] = HEAP32[i22 >> 2];
+  HEAP32[i11 + (i8 * 88 | 0) + 36 >> 2] = HEAP32[i21 >> 2];
+  HEAPF32[i11 + (i8 * 88 | 0) + 40 >> 2] = +HEAPF32[i19 >> 2];
+  HEAPF32[i11 + (i8 * 88 | 0) + 44 >> 2] = +HEAPF32[i20 >> 2];
+  i20 = i14 + 28 | 0;
+  i14 = HEAP32[i20 + 4 >> 2] | 0;
+  i19 = i11 + (i8 * 88 | 0) + 48 | 0;
+  HEAP32[i19 >> 2] = HEAP32[i20 >> 2];
+  HEAP32[i19 + 4 >> 2] = i14;
+  i19 = i13 + 28 | 0;
+  i14 = HEAP32[i19 + 4 >> 2] | 0;
+  i13 = i11 + (i8 * 88 | 0) + 56 | 0;
+  HEAP32[i13 >> 2] = HEAP32[i19 >> 2];
+  HEAP32[i13 + 4 >> 2] = i14;
+  HEAPF32[i11 + (i8 * 88 | 0) + 64 >> 2] = +HEAPF32[i18 >> 2];
+  HEAPF32[i11 + (i8 * 88 | 0) + 68 >> 2] = +HEAPF32[i17 >> 2];
+  i13 = i10 + 104 | 0;
+  i14 = HEAP32[i13 + 4 >> 2] | 0;
+  i17 = i11 + (i8 * 88 | 0) + 16 | 0;
+  HEAP32[i17 >> 2] = HEAP32[i13 >> 2];
+  HEAP32[i17 + 4 >> 2] = i14;
+  i17 = i10 + 112 | 0;
+  i14 = HEAP32[i17 + 4 >> 2] | 0;
+  i13 = i11 + (i8 * 88 | 0) + 24 | 0;
+  HEAP32[i13 >> 2] = HEAP32[i17 >> 2];
+  HEAP32[i13 + 4 >> 2] = i14;
+  HEAP32[i11 + (i8 * 88 | 0) + 84 >> 2] = i9;
+  HEAPF32[i11 + (i8 * 88 | 0) + 76 >> 2] = d16;
+  HEAPF32[i11 + (i8 * 88 | 0) + 80 >> 2] = d15;
+  HEAP32[i11 + (i8 * 88 | 0) + 72 >> 2] = HEAP32[i10 + 120 >> 2];
+  i13 = 0;
+  do {
+   i14 = i10 + (i13 * 20 | 0) + 64 | 0;
+   if ((HEAP8[i6] | 0) == 0) {
+    HEAPF32[i12 + (i8 * 152 | 0) + (i13 * 36 | 0) + 16 >> 2] = 0.0;
+    HEAPF32[i12 + (i8 * 152 | 0) + (i13 * 36 | 0) + 20 >> 2] = 0.0;
+   } else {
+    HEAPF32[i12 + (i8 * 152 | 0) + (i13 * 36 | 0) + 16 >> 2] = +HEAPF32[i7 >> 2] * +HEAPF32[i10 + (i13 * 20 | 0) + 72 >> 2];
+    HEAPF32[i12 + (i8 * 152 | 0) + (i13 * 36 | 0) + 20 >> 2] = +HEAPF32[i7 >> 2] * +HEAPF32[i10 + (i13 * 20 | 0) + 76 >> 2];
+   }
+   i20 = i12 + (i8 * 152 | 0) + (i13 * 36 | 0) | 0;
+   HEAPF32[i12 + (i8 * 152 | 0) + (i13 * 36 | 0) + 24 >> 2] = 0.0;
+   HEAPF32[i12 + (i8 * 152 | 0) + (i13 * 36 | 0) + 28 >> 2] = 0.0;
+   HEAPF32[i12 + (i8 * 152 | 0) + (i13 * 36 | 0) + 32 >> 2] = 0.0;
+   i22 = i11 + (i8 * 88 | 0) + (i13 << 3) | 0;
+   HEAP32[i20 + 0 >> 2] = 0;
+   HEAP32[i20 + 4 >> 2] = 0;
+   HEAP32[i20 + 8 >> 2] = 0;
+   HEAP32[i20 + 12 >> 2] = 0;
+   i20 = i14;
+   i21 = HEAP32[i20 + 4 >> 2] | 0;
+   HEAP32[i22 >> 2] = HEAP32[i20 >> 2];
+   HEAP32[i22 + 4 >> 2] = i21;
+   i13 = i13 + 1 | 0;
+  } while ((i13 | 0) != (i9 | 0));
+  i8 = i8 + 1 | 0;
+  if ((i8 | 0) >= (HEAP32[i4 >> 2] | 0)) {
+   i2 = 12;
+   break;
+  }
+  i9 = HEAP32[i5 >> 2] | 0;
+ }
+ if ((i2 | 0) == 4) {
+  ___assert_fail(6504, 6520, 71, 6568);
+ } else if ((i2 | 0) == 12) {
+  STACKTOP = i1;
+  return;
+ }
+}
+function __Z25b2CollidePolygonAndCircleP10b2ManifoldPK14b2PolygonShapeRK11b2TransformPK13b2CircleShapeS6_(i1, i4, i11, i9, i10) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i11 = i11 | 0;
+ i9 = i9 | 0;
+ i10 = i10 | 0;
+ var i2 = 0, i3 = 0, i5 = 0, d6 = 0.0, d7 = 0.0, d8 = 0.0, i12 = 0, d13 = 0.0, d14 = 0.0, i15 = 0, d16 = 0.0, d17 = 0.0, d18 = 0.0, d19 = 0.0, d20 = 0.0, d21 = 0.0, i22 = 0;
+ i3 = STACKTOP;
+ i5 = i1 + 60 | 0;
+ HEAP32[i5 >> 2] = 0;
+ i2 = i9 + 12 | 0;
+ d20 = +HEAPF32[i10 + 12 >> 2];
+ d7 = +HEAPF32[i2 >> 2];
+ d6 = +HEAPF32[i10 + 8 >> 2];
+ d21 = +HEAPF32[i9 + 16 >> 2];
+ d8 = +HEAPF32[i10 >> 2] + (d20 * d7 - d6 * d21) - +HEAPF32[i11 >> 2];
+ d21 = d7 * d6 + d20 * d21 + +HEAPF32[i10 + 4 >> 2] - +HEAPF32[i11 + 4 >> 2];
+ d20 = +HEAPF32[i11 + 12 >> 2];
+ d6 = +HEAPF32[i11 + 8 >> 2];
+ d7 = d8 * d20 + d21 * d6;
+ d6 = d20 * d21 - d8 * d6;
+ d8 = +HEAPF32[i4 + 8 >> 2] + +HEAPF32[i9 + 8 >> 2];
+ i12 = HEAP32[i4 + 148 >> 2] | 0;
+ do {
+  if ((i12 | 0) > 0) {
+   i10 = 0;
+   i9 = 0;
+   d13 = -3.4028234663852886e+38;
+   while (1) {
+    d14 = (d7 - +HEAPF32[i4 + (i10 << 3) + 20 >> 2]) * +HEAPF32[i4 + (i10 << 3) + 84 >> 2] + (d6 - +HEAPF32[i4 + (i10 << 3) + 24 >> 2]) * +HEAPF32[i4 + (i10 << 3) + 88 >> 2];
+    if (d14 > d8) {
+     i10 = 19;
+     break;
+    }
+    i11 = d14 > d13;
+    d13 = i11 ? d14 : d13;
+    i9 = i11 ? i10 : i9;
+    i10 = i10 + 1 | 0;
+    if ((i10 | 0) >= (i12 | 0)) {
+     i10 = 4;
+     break;
+    }
+   }
+   if ((i10 | 0) == 4) {
+    i22 = d13 < 1.1920928955078125e-7;
+    break;
+   } else if ((i10 | 0) == 19) {
+    STACKTOP = i3;
+    return;
+   }
+  } else {
+   i9 = 0;
+   i22 = 1;
+  }
+ } while (0);
+ i15 = i9 + 1 | 0;
+ i11 = i4 + (i9 << 3) + 20 | 0;
+ i10 = HEAP32[i11 >> 2] | 0;
+ i11 = HEAP32[i11 + 4 >> 2] | 0;
+ d14 = (HEAP32[tempDoublePtr >> 2] = i10, +HEAPF32[tempDoublePtr >> 2]);
+ d13 = (HEAP32[tempDoublePtr >> 2] = i11, +HEAPF32[tempDoublePtr >> 2]);
+ i12 = i4 + (((i15 | 0) < (i12 | 0) ? i15 : 0) << 3) + 20 | 0;
+ i15 = HEAP32[i12 >> 2] | 0;
+ i12 = HEAP32[i12 + 4 >> 2] | 0;
+ d21 = (HEAP32[tempDoublePtr >> 2] = i15, +HEAPF32[tempDoublePtr >> 2]);
+ d18 = (HEAP32[tempDoublePtr >> 2] = i12, +HEAPF32[tempDoublePtr >> 2]);
+ if (i22) {
+  HEAP32[i5 >> 2] = 1;
+  HEAP32[i1 + 56 >> 2] = 1;
+  i22 = i4 + (i9 << 3) + 84 | 0;
+  i15 = HEAP32[i22 + 4 >> 2] | 0;
+  i12 = i1 + 40 | 0;
+  HEAP32[i12 >> 2] = HEAP32[i22 >> 2];
+  HEAP32[i12 + 4 >> 2] = i15;
+  d20 = +((d14 + d21) * .5);
+  d21 = +((d13 + d18) * .5);
+  i12 = i1 + 48 | 0;
+  HEAPF32[i12 >> 2] = d20;
+  HEAPF32[i12 + 4 >> 2] = d21;
+  i12 = i2;
+  i15 = HEAP32[i12 + 4 >> 2] | 0;
+  i22 = i1;
+  HEAP32[i22 >> 2] = HEAP32[i12 >> 2];
+  HEAP32[i22 + 4 >> 2] = i15;
+  HEAP32[i1 + 16 >> 2] = 0;
+  STACKTOP = i3;
+  return;
+ }
+ d16 = d7 - d14;
+ d20 = d6 - d13;
+ d19 = d7 - d21;
+ d17 = d6 - d18;
+ if (d16 * (d21 - d14) + d20 * (d18 - d13) <= 0.0) {
+  if (d16 * d16 + d20 * d20 > d8 * d8) {
+   STACKTOP = i3;
+   return;
+  }
+  HEAP32[i5 >> 2] = 1;
+  HEAP32[i1 + 56 >> 2] = 1;
+  i4 = i1 + 40 | 0;
+  d21 = +d16;
+  d6 = +d20;
+  i22 = i4;
+  HEAPF32[i22 >> 2] = d21;
+  HEAPF32[i22 + 4 >> 2] = d6;
+  d6 = +Math_sqrt(+(d16 * d16 + d20 * d20));
+  if (!(d6 < 1.1920928955078125e-7)) {
+   d21 = 1.0 / d6;
+   HEAPF32[i4 >> 2] = d16 * d21;
+   HEAPF32[i1 + 44 >> 2] = d20 * d21;
+  }
+  i12 = i1 + 48 | 0;
+  HEAP32[i12 >> 2] = i10;
+  HEAP32[i12 + 4 >> 2] = i11;
+  i12 = i2;
+  i15 = HEAP32[i12 + 4 >> 2] | 0;
+  i22 = i1;
+  HEAP32[i22 >> 2] = HEAP32[i12 >> 2];
+  HEAP32[i22 + 4 >> 2] = i15;
+  HEAP32[i1 + 16 >> 2] = 0;
+  STACKTOP = i3;
+  return;
+ }
+ if (!(d19 * (d14 - d21) + d17 * (d13 - d18) <= 0.0)) {
+  d14 = (d14 + d21) * .5;
+  d13 = (d13 + d18) * .5;
+  i10 = i4 + (i9 << 3) + 84 | 0;
+  if ((d7 - d14) * +HEAPF32[i10 >> 2] + (d6 - d13) * +HEAPF32[i4 + (i9 << 3) + 88 >> 2] > d8) {
+   STACKTOP = i3;
+   return;
+  }
+  HEAP32[i5 >> 2] = 1;
+  HEAP32[i1 + 56 >> 2] = 1;
+  i22 = i10;
+  i15 = HEAP32[i22 + 4 >> 2] | 0;
+  i12 = i1 + 40 | 0;
+  HEAP32[i12 >> 2] = HEAP32[i22 >> 2];
+  HEAP32[i12 + 4 >> 2] = i15;
+  d20 = +d14;
+  d21 = +d13;
+  i12 = i1 + 48 | 0;
+  HEAPF32[i12 >> 2] = d20;
+  HEAPF32[i12 + 4 >> 2] = d21;
+  i12 = i2;
+  i15 = HEAP32[i12 + 4 >> 2] | 0;
+  i22 = i1;
+  HEAP32[i22 >> 2] = HEAP32[i12 >> 2];
+  HEAP32[i22 + 4 >> 2] = i15;
+  HEAP32[i1 + 16 >> 2] = 0;
+  STACKTOP = i3;
+  return;
+ }
+ if (d19 * d19 + d17 * d17 > d8 * d8) {
+  STACKTOP = i3;
+  return;
+ }
+ HEAP32[i5 >> 2] = 1;
+ HEAP32[i1 + 56 >> 2] = 1;
+ i4 = i1 + 40 | 0;
+ d21 = +d19;
+ d6 = +d17;
+ i22 = i4;
+ HEAPF32[i22 >> 2] = d21;
+ HEAPF32[i22 + 4 >> 2] = d6;
+ d6 = +Math_sqrt(+(d19 * d19 + d17 * d17));
+ if (!(d6 < 1.1920928955078125e-7)) {
+  d21 = 1.0 / d6;
+  HEAPF32[i4 >> 2] = d19 * d21;
+  HEAPF32[i1 + 44 >> 2] = d17 * d21;
+ }
+ i22 = i1 + 48 | 0;
+ HEAP32[i22 >> 2] = i15;
+ HEAP32[i22 + 4 >> 2] = i12;
+ i12 = i2;
+ i15 = HEAP32[i12 + 4 >> 2] | 0;
+ i22 = i1;
+ HEAP32[i22 >> 2] = HEAP32[i12 >> 2];
+ HEAP32[i22 + 4 >> 2] = i15;
+ HEAP32[i1 + 16 >> 2] = 0;
+ STACKTOP = i3;
+ return;
+}
+function __ZN15b2WorldManifold10InitializeEPK10b2ManifoldRK11b2TransformfS5_f(i1, i5, i7, d4, i8, d3) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i7 = i7 | 0;
+ d4 = +d4;
+ i8 = i8 | 0;
+ d3 = +d3;
+ var i2 = 0, i6 = 0, d9 = 0.0, d10 = 0.0, i11 = 0, i12 = 0, i13 = 0, d14 = 0.0, d15 = 0.0, i16 = 0, d17 = 0.0, d18 = 0.0, d19 = 0.0, i20 = 0, d21 = 0.0, d22 = 0.0;
+ i2 = STACKTOP;
+ i6 = i5 + 60 | 0;
+ if ((HEAP32[i6 >> 2] | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ i11 = HEAP32[i5 + 56 >> 2] | 0;
+ if ((i11 | 0) == 2) {
+  i13 = i8 + 12 | 0;
+  d17 = +HEAPF32[i13 >> 2];
+  d18 = +HEAPF32[i5 + 40 >> 2];
+  i16 = i8 + 8 | 0;
+  d19 = +HEAPF32[i16 >> 2];
+  d15 = +HEAPF32[i5 + 44 >> 2];
+  d14 = d17 * d18 - d19 * d15;
+  d15 = d18 * d19 + d17 * d15;
+  d17 = +d14;
+  d19 = +d15;
+  i12 = i1;
+  HEAPF32[i12 >> 2] = d17;
+  HEAPF32[i12 + 4 >> 2] = d19;
+  d19 = +HEAPF32[i13 >> 2];
+  d17 = +HEAPF32[i5 + 48 >> 2];
+  d18 = +HEAPF32[i16 >> 2];
+  d10 = +HEAPF32[i5 + 52 >> 2];
+  d9 = +HEAPF32[i8 >> 2] + (d19 * d17 - d18 * d10);
+  d10 = d17 * d18 + d19 * d10 + +HEAPF32[i8 + 4 >> 2];
+  if ((HEAP32[i6 >> 2] | 0) > 0) {
+   i8 = i7 + 12 | 0;
+   i11 = i7 + 8 | 0;
+   i12 = i7 + 4 | 0;
+   i13 = i1 + 4 | 0;
+   i16 = 0;
+   do {
+    d18 = +HEAPF32[i8 >> 2];
+    d22 = +HEAPF32[i5 + (i16 * 20 | 0) >> 2];
+    d21 = +HEAPF32[i11 >> 2];
+    d17 = +HEAPF32[i5 + (i16 * 20 | 0) + 4 >> 2];
+    d19 = +HEAPF32[i7 >> 2] + (d18 * d22 - d21 * d17);
+    d17 = d22 * d21 + d18 * d17 + +HEAPF32[i12 >> 2];
+    d18 = d3 - (d14 * (d19 - d9) + (d17 - d10) * d15);
+    d19 = +((d19 - d14 * d4 + (d19 + d14 * d18)) * .5);
+    d14 = +((d17 - d15 * d4 + (d17 + d15 * d18)) * .5);
+    i20 = i1 + (i16 << 3) + 8 | 0;
+    HEAPF32[i20 >> 2] = d19;
+    HEAPF32[i20 + 4 >> 2] = d14;
+    i16 = i16 + 1 | 0;
+    d14 = +HEAPF32[i1 >> 2];
+    d15 = +HEAPF32[i13 >> 2];
+   } while ((i16 | 0) < (HEAP32[i6 >> 2] | 0));
+  }
+  d21 = +-d14;
+  d22 = +-d15;
+  i20 = i1;
+  HEAPF32[i20 >> 2] = d21;
+  HEAPF32[i20 + 4 >> 2] = d22;
+  STACKTOP = i2;
+  return;
+ } else if ((i11 | 0) == 1) {
+  i16 = i7 + 12 | 0;
+  d19 = +HEAPF32[i16 >> 2];
+  d21 = +HEAPF32[i5 + 40 >> 2];
+  i20 = i7 + 8 | 0;
+  d22 = +HEAPF32[i20 >> 2];
+  d15 = +HEAPF32[i5 + 44 >> 2];
+  d14 = d19 * d21 - d22 * d15;
+  d15 = d21 * d22 + d19 * d15;
+  d19 = +d14;
+  d22 = +d15;
+  i13 = i1;
+  HEAPF32[i13 >> 2] = d19;
+  HEAPF32[i13 + 4 >> 2] = d22;
+  d22 = +HEAPF32[i16 >> 2];
+  d19 = +HEAPF32[i5 + 48 >> 2];
+  d21 = +HEAPF32[i20 >> 2];
+  d10 = +HEAPF32[i5 + 52 >> 2];
+  d9 = +HEAPF32[i7 >> 2] + (d22 * d19 - d21 * d10);
+  d10 = d19 * d21 + d22 * d10 + +HEAPF32[i7 + 4 >> 2];
+  if ((HEAP32[i6 >> 2] | 0) <= 0) {
+   STACKTOP = i2;
+   return;
+  }
+  i12 = i8 + 12 | 0;
+  i11 = i8 + 8 | 0;
+  i7 = i8 + 4 | 0;
+  i13 = i1 + 4 | 0;
+  i16 = 0;
+  while (1) {
+   d22 = +HEAPF32[i12 >> 2];
+   d17 = +HEAPF32[i5 + (i16 * 20 | 0) >> 2];
+   d18 = +HEAPF32[i11 >> 2];
+   d19 = +HEAPF32[i5 + (i16 * 20 | 0) + 4 >> 2];
+   d21 = +HEAPF32[i8 >> 2] + (d22 * d17 - d18 * d19);
+   d19 = d17 * d18 + d22 * d19 + +HEAPF32[i7 >> 2];
+   d22 = d4 - (d14 * (d21 - d9) + (d19 - d10) * d15);
+   d21 = +((d21 - d14 * d3 + (d21 + d14 * d22)) * .5);
+   d22 = +((d19 - d15 * d3 + (d19 + d15 * d22)) * .5);
+   i20 = i1 + (i16 << 3) + 8 | 0;
+   HEAPF32[i20 >> 2] = d21;
+   HEAPF32[i20 + 4 >> 2] = d22;
+   i16 = i16 + 1 | 0;
+   if ((i16 | 0) >= (HEAP32[i6 >> 2] | 0)) {
+    break;
+   }
+   d14 = +HEAPF32[i1 >> 2];
+   d15 = +HEAPF32[i13 >> 2];
+  }
+  STACKTOP = i2;
+  return;
+ } else if ((i11 | 0) == 0) {
+  HEAPF32[i1 >> 2] = 1.0;
+  i6 = i1 + 4 | 0;
+  HEAPF32[i6 >> 2] = 0.0;
+  d21 = +HEAPF32[i7 + 12 >> 2];
+  d22 = +HEAPF32[i5 + 48 >> 2];
+  d19 = +HEAPF32[i7 + 8 >> 2];
+  d10 = +HEAPF32[i5 + 52 >> 2];
+  d9 = +HEAPF32[i7 >> 2] + (d21 * d22 - d19 * d10);
+  d10 = d22 * d19 + d21 * d10 + +HEAPF32[i7 + 4 >> 2];
+  d21 = +HEAPF32[i8 + 12 >> 2];
+  d19 = +HEAPF32[i5 >> 2];
+  d22 = +HEAPF32[i8 + 8 >> 2];
+  d15 = +HEAPF32[i5 + 4 >> 2];
+  d14 = +HEAPF32[i8 >> 2] + (d21 * d19 - d22 * d15);
+  d15 = d19 * d22 + d21 * d15 + +HEAPF32[i8 + 4 >> 2];
+  d21 = d9 - d14;
+  d22 = d10 - d15;
+  if (d21 * d21 + d22 * d22 > 1.4210854715202004e-14) {
+   d19 = d14 - d9;
+   d17 = d15 - d10;
+   d22 = +d19;
+   d18 = +d17;
+   i20 = i1;
+   HEAPF32[i20 >> 2] = d22;
+   HEAPF32[i20 + 4 >> 2] = d18;
+   d18 = +Math_sqrt(+(d19 * d19 + d17 * d17));
+   if (!(d18 < 1.1920928955078125e-7)) {
+    d22 = 1.0 / d18;
+    d19 = d19 * d22;
+    HEAPF32[i1 >> 2] = d19;
+    d17 = d17 * d22;
+    HEAPF32[i6 >> 2] = d17;
+   }
+  } else {
+   d19 = 1.0;
+   d17 = 0.0;
+  }
+  d21 = +((d9 + d19 * d4 + (d14 - d19 * d3)) * .5);
+  d22 = +((d10 + d17 * d4 + (d15 - d17 * d3)) * .5);
+  i20 = i1 + 8 | 0;
+  HEAPF32[i20 >> 2] = d21;
+  HEAPF32[i20 + 4 >> 2] = d22;
+  STACKTOP = i2;
+  return;
+ } else {
+  STACKTOP = i2;
+  return;
+ }
+}
+function _main(i3, i2) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i4 = 0, i5 = 0, d6 = 0.0, d7 = 0.0, i8 = 0, i9 = 0, d10 = 0.0, d11 = 0.0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, d22 = 0.0, d23 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 240 | 0;
+ i5 = i1;
+ i12 = i1 + 224 | 0;
+ i4 = i1 + 168 | 0;
+ i9 = i1 + 160 | 0;
+ i8 = i1 + 152 | 0;
+ L1 : do {
+  if ((i3 | 0) > 1) {
+   i14 = HEAP8[HEAP32[i2 + 4 >> 2] | 0] | 0;
+   switch (i14 | 0) {
+   case 49:
+    {
+     HEAP32[2] = 5;
+     HEAP32[4] = 35;
+     i15 = 35;
+     i14 = 5;
+     break L1;
+    }
+   case 50:
+    {
+     HEAP32[2] = 32;
+     HEAP32[4] = 161;
+     i15 = 161;
+     i14 = 32;
+     break L1;
+    }
+   case 51:
+    {
+     i13 = 5;
+     break L1;
+    }
+   case 52:
+    {
+     HEAP32[2] = 320;
+     HEAP32[4] = 2331;
+     i15 = 2331;
+     i14 = 320;
+     break L1;
+    }
+   case 53:
+    {
+     HEAP32[2] = 640;
+     HEAP32[4] = 5661;
+     i15 = 5661;
+     i14 = 640;
+     break L1;
+    }
+   case 48:
+    {
+     i20 = 0;
+     STACKTOP = i1;
+     return i20 | 0;
+    }
+   default:
+    {
+     HEAP32[i5 >> 2] = i14 + -48;
+     _printf(80, i5 | 0) | 0;
+     i20 = -1;
+     STACKTOP = i1;
+     return i20 | 0;
+    }
+   }
+  } else {
+   i13 = 5;
+  }
+ } while (0);
+ if ((i13 | 0) == 5) {
+  HEAP32[2] = 64;
+  HEAP32[4] = 333;
+  i15 = 333;
+  i14 = 64;
+ }
+ i13 = i15 + i14 | 0;
+ HEAP32[4] = i13;
+ HEAP32[2] = 0;
+ HEAP32[8] = __Znaj(i13 >>> 0 > 1073741823 ? -1 : i13 << 2) | 0;
+ HEAPF32[i12 >> 2] = 0.0;
+ HEAPF32[i12 + 4 >> 2] = -10.0;
+ i15 = __Znwj(103028) | 0;
+ __ZN7b2WorldC2ERK6b2Vec2(i15, i12);
+ HEAP32[6] = i15;
+ __ZN7b2World16SetAllowSleepingEb(i15, 0);
+ HEAP32[i5 + 44 >> 2] = 0;
+ i15 = i5 + 4 | 0;
+ i14 = i5 + 36 | 0;
+ HEAP32[i15 + 0 >> 2] = 0;
+ HEAP32[i15 + 4 >> 2] = 0;
+ HEAP32[i15 + 8 >> 2] = 0;
+ HEAP32[i15 + 12 >> 2] = 0;
+ HEAP32[i15 + 16 >> 2] = 0;
+ HEAP32[i15 + 20 >> 2] = 0;
+ HEAP32[i15 + 24 >> 2] = 0;
+ HEAP32[i15 + 28 >> 2] = 0;
+ HEAP8[i14] = 1;
+ HEAP8[i5 + 37 | 0] = 1;
+ HEAP8[i5 + 38 | 0] = 0;
+ HEAP8[i5 + 39 | 0] = 0;
+ HEAP32[i5 >> 2] = 0;
+ HEAP8[i5 + 40 | 0] = 1;
+ HEAPF32[i5 + 48 >> 2] = 1.0;
+ i14 = __ZN7b2World10CreateBodyEPK9b2BodyDef(HEAP32[6] | 0, i5) | 0;
+ HEAP32[i4 >> 2] = 240;
+ HEAP32[i4 + 4 >> 2] = 1;
+ HEAPF32[i4 + 8 >> 2] = .009999999776482582;
+ i15 = i4 + 28 | 0;
+ HEAP32[i15 + 0 >> 2] = 0;
+ HEAP32[i15 + 4 >> 2] = 0;
+ HEAP32[i15 + 8 >> 2] = 0;
+ HEAP32[i15 + 12 >> 2] = 0;
+ HEAP16[i15 + 16 >> 1] = 0;
+ HEAPF32[i9 >> 2] = -40.0;
+ HEAPF32[i9 + 4 >> 2] = 0.0;
+ HEAPF32[i8 >> 2] = 40.0;
+ HEAPF32[i8 + 4 >> 2] = 0.0;
+ __ZN11b2EdgeShape3SetERK6b2Vec2S2_(i4, i9, i8);
+ __ZN6b2Body13CreateFixtureEPK7b2Shapef(i14, i4, 0.0) | 0;
+ HEAP32[i5 >> 2] = 504;
+ HEAP32[i5 + 4 >> 2] = 2;
+ HEAPF32[i5 + 8 >> 2] = .009999999776482582;
+ HEAP32[i5 + 148 >> 2] = 0;
+ HEAPF32[i5 + 12 >> 2] = 0.0;
+ HEAPF32[i5 + 16 >> 2] = 0.0;
+ __ZN14b2PolygonShape8SetAsBoxEff(i5, .5, .5);
+ i14 = i4 + 44 | 0;
+ i15 = i4 + 4 | 0;
+ i8 = i4 + 36 | 0;
+ i17 = i4 + 37 | 0;
+ i18 = i4 + 38 | 0;
+ i19 = i4 + 39 | 0;
+ i20 = i4 + 40 | 0;
+ i13 = i4 + 48 | 0;
+ i12 = i4 + 4 | 0;
+ d11 = -7.0;
+ d10 = .75;
+ i9 = 0;
+ while (1) {
+  d7 = d11;
+  d6 = d10;
+  i16 = i9;
+  while (1) {
+   HEAP32[i14 >> 2] = 0;
+   HEAP32[i15 + 0 >> 2] = 0;
+   HEAP32[i15 + 4 >> 2] = 0;
+   HEAP32[i15 + 8 >> 2] = 0;
+   HEAP32[i15 + 12 >> 2] = 0;
+   HEAP32[i15 + 16 >> 2] = 0;
+   HEAP32[i15 + 20 >> 2] = 0;
+   HEAP32[i15 + 24 >> 2] = 0;
+   HEAP32[i15 + 28 >> 2] = 0;
+   HEAP8[i8] = 1;
+   HEAP8[i17] = 1;
+   HEAP8[i18] = 0;
+   HEAP8[i19] = 0;
+   HEAP8[i20] = 1;
+   HEAPF32[i13 >> 2] = 1.0;
+   HEAP32[i4 >> 2] = 2;
+   d23 = +d7;
+   d22 = +d6;
+   i21 = i12;
+   HEAPF32[i21 >> 2] = d23;
+   HEAPF32[i21 + 4 >> 2] = d22;
+   i21 = __ZN7b2World10CreateBodyEPK9b2BodyDef(HEAP32[6] | 0, i4) | 0;
+   __ZN6b2Body13CreateFixtureEPK7b2Shapef(i21, i5, 5.0) | 0;
+   HEAP32[14] = i21;
+   i16 = i16 + 1 | 0;
+   if ((i16 | 0) >= 40) {
+    break;
+   } else {
+    d7 = d7 + 1.125;
+    d6 = d6 + 0.0;
+   }
+  }
+  i9 = i9 + 1 | 0;
+  if ((i9 | 0) >= 40) {
+   break;
+  } else {
+   d11 = d11 + .5625;
+   d10 = d10 + 1.0;
+  }
+ }
+ if ((HEAP32[2] | 0) > 0) {
+  i4 = 0;
+  do {
+   __ZN7b2World4StepEfii(HEAP32[6] | 0, .01666666753590107, 3, 3);
+   i4 = i4 + 1 | 0;
+  } while ((i4 | 0) < (HEAP32[2] | 0));
+ }
+ if ((i3 | 0) > 2) {
+  i21 = (HEAP8[HEAP32[i2 + 8 >> 2] | 0] | 0) + -48 | 0;
+  HEAP32[18] = i21;
+  if ((i21 | 0) != 0) {
+   _puts(208) | 0;
+   _emscripten_set_main_loop(2, 60, 1);
+   i21 = 0;
+   STACKTOP = i1;
+   return i21 | 0;
+  }
+ } else {
+  HEAP32[18] = 0;
+ }
+ while (1) {
+  __Z4iterv();
+  if ((HEAP32[16] | 0) > (HEAP32[4] | 0)) {
+   i2 = 0;
+   break;
+  }
+ }
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function __ZN9b2Simplex9ReadCacheEPK14b2SimplexCachePK15b2DistanceProxyRK11b2TransformS5_S8_(i2, i11, i10, i4, i3, i5) {
+ i2 = i2 | 0;
+ i11 = i11 | 0;
+ i10 = i10 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i6 = 0, i7 = 0, d8 = 0.0, i9 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, d24 = 0.0, d25 = 0.0, i26 = 0, d27 = 0.0, d28 = 0.0, d29 = 0.0, d30 = 0.0, d31 = 0.0, d32 = 0.0;
+ i1 = STACKTOP;
+ i13 = HEAP16[i11 + 4 >> 1] | 0;
+ if (!((i13 & 65535) < 4)) {
+  ___assert_fail(2872, 2672, 102, 2896);
+ }
+ i12 = i13 & 65535;
+ i6 = i2 + 108 | 0;
+ HEAP32[i6 >> 2] = i12;
+ L4 : do {
+  if (!(i13 << 16 >> 16 == 0)) {
+   i17 = i10 + 20 | 0;
+   i21 = i10 + 16 | 0;
+   i13 = i3 + 20 | 0;
+   i14 = i3 + 16 | 0;
+   i15 = i4 + 12 | 0;
+   i16 = i4 + 8 | 0;
+   i12 = i4 + 4 | 0;
+   i18 = i5 + 12 | 0;
+   i19 = i5 + 8 | 0;
+   i20 = i5 + 4 | 0;
+   i22 = 0;
+   while (1) {
+    i26 = HEAPU8[i11 + i22 + 6 | 0] | 0;
+    HEAP32[i2 + (i22 * 36 | 0) + 28 >> 2] = i26;
+    i23 = HEAPU8[i11 + i22 + 9 | 0] | 0;
+    HEAP32[i2 + (i22 * 36 | 0) + 32 >> 2] = i23;
+    if ((HEAP32[i17 >> 2] | 0) <= (i26 | 0)) {
+     i9 = 6;
+     break;
+    }
+    i26 = (HEAP32[i21 >> 2] | 0) + (i26 << 3) | 0;
+    d25 = +HEAPF32[i26 >> 2];
+    d24 = +HEAPF32[i26 + 4 >> 2];
+    if ((HEAP32[i13 >> 2] | 0) <= (i23 | 0)) {
+     i9 = 8;
+     break;
+    }
+    i23 = (HEAP32[i14 >> 2] | 0) + (i23 << 3) | 0;
+    d29 = +HEAPF32[i23 >> 2];
+    d31 = +HEAPF32[i23 + 4 >> 2];
+    d32 = +HEAPF32[i15 >> 2];
+    d30 = +HEAPF32[i16 >> 2];
+    d27 = +HEAPF32[i4 >> 2] + (d25 * d32 - d24 * d30);
+    d28 = +d27;
+    d30 = +(d24 * d32 + d25 * d30 + +HEAPF32[i12 >> 2]);
+    i23 = i2 + (i22 * 36 | 0) | 0;
+    HEAPF32[i23 >> 2] = d28;
+    HEAPF32[i23 + 4 >> 2] = d30;
+    d30 = +HEAPF32[i18 >> 2];
+    d25 = +HEAPF32[i19 >> 2];
+    d24 = +HEAPF32[i5 >> 2] + (d29 * d30 - d31 * d25);
+    d28 = +d24;
+    d25 = +(d31 * d30 + d29 * d25 + +HEAPF32[i20 >> 2]);
+    i23 = i2 + (i22 * 36 | 0) + 8 | 0;
+    HEAPF32[i23 >> 2] = d28;
+    HEAPF32[i23 + 4 >> 2] = d25;
+    d24 = +(d24 - d27);
+    d25 = +(+HEAPF32[i2 + (i22 * 36 | 0) + 12 >> 2] - +HEAPF32[i2 + (i22 * 36 | 0) + 4 >> 2]);
+    i23 = i2 + (i22 * 36 | 0) + 16 | 0;
+    HEAPF32[i23 >> 2] = d24;
+    HEAPF32[i23 + 4 >> 2] = d25;
+    HEAPF32[i2 + (i22 * 36 | 0) + 24 >> 2] = 0.0;
+    i22 = i22 + 1 | 0;
+    i23 = HEAP32[i6 >> 2] | 0;
+    if ((i22 | 0) >= (i23 | 0)) {
+     i7 = i23;
+     break L4;
+    }
+   }
+   if ((i9 | 0) == 6) {
+    ___assert_fail(2776, 2808, 103, 2840);
+   } else if ((i9 | 0) == 8) {
+    ___assert_fail(2776, 2808, 103, 2840);
+   }
+  } else {
+   i7 = i12;
+  }
+ } while (0);
+ do {
+  if ((i7 | 0) > 1) {
+   d24 = +HEAPF32[i11 >> 2];
+   if ((i7 | 0) == 2) {
+    d32 = +HEAPF32[i2 + 16 >> 2] - +HEAPF32[i2 + 52 >> 2];
+    d8 = +HEAPF32[i2 + 20 >> 2] - +HEAPF32[i2 + 56 >> 2];
+    d8 = +Math_sqrt(+(d32 * d32 + d8 * d8));
+   } else if ((i7 | 0) == 3) {
+    d8 = +HEAPF32[i2 + 16 >> 2];
+    d32 = +HEAPF32[i2 + 20 >> 2];
+    d8 = (+HEAPF32[i2 + 52 >> 2] - d8) * (+HEAPF32[i2 + 92 >> 2] - d32) - (+HEAPF32[i2 + 56 >> 2] - d32) * (+HEAPF32[i2 + 88 >> 2] - d8);
+   } else {
+    ___assert_fail(2712, 2672, 259, 2736);
+   }
+   if (!(d8 < d24 * .5) ? !(d24 * 2.0 < d8 | d8 < 1.1920928955078125e-7) : 0) {
+    i9 = 18;
+    break;
+   }
+   HEAP32[i6 >> 2] = 0;
+  } else {
+   i9 = 18;
+  }
+ } while (0);
+ if ((i9 | 0) == 18 ? (i7 | 0) != 0 : 0) {
+  STACKTOP = i1;
+  return;
+ }
+ HEAP32[i2 + 28 >> 2] = 0;
+ HEAP32[i2 + 32 >> 2] = 0;
+ if ((HEAP32[i10 + 20 >> 2] | 0) <= 0) {
+  ___assert_fail(2776, 2808, 103, 2840);
+ }
+ i26 = HEAP32[i10 + 16 >> 2] | 0;
+ d8 = +HEAPF32[i26 >> 2];
+ d24 = +HEAPF32[i26 + 4 >> 2];
+ if ((HEAP32[i3 + 20 >> 2] | 0) <= 0) {
+  ___assert_fail(2776, 2808, 103, 2840);
+ }
+ i26 = HEAP32[i3 + 16 >> 2] | 0;
+ d27 = +HEAPF32[i26 >> 2];
+ d25 = +HEAPF32[i26 + 4 >> 2];
+ d30 = +HEAPF32[i4 + 12 >> 2];
+ d32 = +HEAPF32[i4 + 8 >> 2];
+ d31 = +HEAPF32[i4 >> 2] + (d8 * d30 - d24 * d32);
+ d32 = d24 * d30 + d8 * d32 + +HEAPF32[i4 + 4 >> 2];
+ d30 = +d31;
+ d28 = +d32;
+ i26 = i2;
+ HEAPF32[i26 >> 2] = d30;
+ HEAPF32[i26 + 4 >> 2] = d28;
+ d28 = +HEAPF32[i5 + 12 >> 2];
+ d30 = +HEAPF32[i5 + 8 >> 2];
+ d29 = +HEAPF32[i5 >> 2] + (d27 * d28 - d25 * d30);
+ d30 = d25 * d28 + d27 * d30 + +HEAPF32[i5 + 4 >> 2];
+ d27 = +d29;
+ d28 = +d30;
+ i26 = i2 + 8 | 0;
+ HEAPF32[i26 >> 2] = d27;
+ HEAPF32[i26 + 4 >> 2] = d28;
+ d31 = +(d29 - d31);
+ d32 = +(d30 - d32);
+ i26 = i2 + 16 | 0;
+ HEAPF32[i26 >> 2] = d31;
+ HEAPF32[i26 + 4 >> 2] = d32;
+ HEAP32[i6 >> 2] = 1;
+ STACKTOP = i1;
+ return;
+}
+function __ZNSt3__17__sort4IRPFbRK6b2PairS3_EPS1_EEjT0_S8_S8_S8_T_(i6, i7, i5, i4, i1) {
+ i6 = i6 | 0;
+ i7 = i7 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i8 = 0, i9 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ i9 = FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i7, i6) | 0;
+ i8 = FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i5, i7) | 0;
+ do {
+  if (i9) {
+   if (i8) {
+    HEAP32[i3 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+    HEAP32[i3 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+    HEAP32[i3 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+    HEAP32[i6 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+    HEAP32[i6 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+    HEAP32[i6 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+    HEAP32[i5 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+    HEAP32[i5 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+    HEAP32[i5 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+    i8 = 1;
+    break;
+   }
+   HEAP32[i3 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+   HEAP32[i3 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+   HEAP32[i3 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+   HEAP32[i6 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+   HEAP32[i6 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+   HEAP32[i6 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+   HEAP32[i7 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+   HEAP32[i7 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+   HEAP32[i7 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+   if (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i5, i7) | 0) {
+    HEAP32[i3 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+    HEAP32[i3 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+    HEAP32[i3 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+    HEAP32[i7 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+    HEAP32[i7 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+    HEAP32[i7 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+    HEAP32[i5 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+    HEAP32[i5 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+    HEAP32[i5 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+    i8 = 2;
+   } else {
+    i8 = 1;
+   }
+  } else {
+   if (i8) {
+    HEAP32[i3 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+    HEAP32[i3 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+    HEAP32[i3 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+    HEAP32[i7 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+    HEAP32[i7 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+    HEAP32[i7 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+    HEAP32[i5 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+    HEAP32[i5 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+    HEAP32[i5 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+    if (FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i7, i6) | 0) {
+     HEAP32[i3 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+     HEAP32[i3 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+     HEAP32[i3 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+     HEAP32[i6 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+     HEAP32[i6 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+     HEAP32[i6 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+     HEAP32[i7 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+     HEAP32[i7 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+     HEAP32[i7 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+     i8 = 2;
+    } else {
+     i8 = 1;
+    }
+   } else {
+    i8 = 0;
+   }
+  }
+ } while (0);
+ if (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i4, i5) | 0)) {
+  i9 = i8;
+  STACKTOP = i2;
+  return i9 | 0;
+ }
+ HEAP32[i3 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+ HEAP32[i3 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+ HEAP32[i3 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+ HEAP32[i5 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+ HEAP32[i5 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+ HEAP32[i5 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+ HEAP32[i4 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+ HEAP32[i4 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+ HEAP32[i4 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+ if (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i5, i7) | 0)) {
+  i9 = i8 + 1 | 0;
+  STACKTOP = i2;
+  return i9 | 0;
+ }
+ HEAP32[i3 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+ HEAP32[i3 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+ HEAP32[i3 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+ HEAP32[i7 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+ HEAP32[i7 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+ HEAP32[i7 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+ HEAP32[i5 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+ HEAP32[i5 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+ HEAP32[i5 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+ if (!(FUNCTION_TABLE_iii[HEAP32[i1 >> 2] & 3](i7, i6) | 0)) {
+  i9 = i8 + 2 | 0;
+  STACKTOP = i2;
+  return i9 | 0;
+ }
+ HEAP32[i3 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+ HEAP32[i3 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+ HEAP32[i3 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+ HEAP32[i6 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+ HEAP32[i6 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+ HEAP32[i6 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+ HEAP32[i7 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+ HEAP32[i7 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+ HEAP32[i7 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+ i9 = i8 + 3 | 0;
+ STACKTOP = i2;
+ return i9 | 0;
+}
+function __ZN15b2ContactSolver27SolveTOIPositionConstraintsEii(i9, i2, i5) {
+ i9 = i9 | 0;
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, d21 = 0.0, d22 = 0.0, d23 = 0.0, d24 = 0.0, d25 = 0.0, d26 = 0.0, d27 = 0.0, d28 = 0.0, d29 = 0.0, d30 = 0.0, d31 = 0.0, d32 = 0.0, d33 = 0.0, d34 = 0.0, d35 = 0.0, d36 = 0.0, i37 = 0, d38 = 0.0, d39 = 0.0, d40 = 0.0, d41 = 0.0, d42 = 0.0, d43 = 0.0, d44 = 0.0, d45 = 0.0, i46 = 0, d47 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i8 = i1 + 40 | 0;
+ i3 = i1 + 24 | 0;
+ i4 = i1;
+ i6 = i9 + 48 | 0;
+ if ((HEAP32[i6 >> 2] | 0) <= 0) {
+  d45 = 0.0;
+  i37 = d45 >= -.007499999832361937;
+  STACKTOP = i1;
+  return i37 | 0;
+ }
+ i7 = i9 + 36 | 0;
+ i14 = i9 + 24 | 0;
+ i9 = i8 + 8 | 0;
+ i15 = i8 + 12 | 0;
+ i10 = i3 + 8 | 0;
+ i11 = i3 + 12 | 0;
+ i12 = i4 + 8 | 0;
+ i13 = i4 + 16 | 0;
+ i16 = 0;
+ d34 = 0.0;
+ do {
+  i37 = HEAP32[i7 >> 2] | 0;
+  i19 = i37 + (i16 * 88 | 0) | 0;
+  i17 = HEAP32[i37 + (i16 * 88 | 0) + 32 >> 2] | 0;
+  i18 = HEAP32[i37 + (i16 * 88 | 0) + 36 >> 2] | 0;
+  i20 = i37 + (i16 * 88 | 0) + 48 | 0;
+  d21 = +HEAPF32[i20 >> 2];
+  d22 = +HEAPF32[i20 + 4 >> 2];
+  i20 = i37 + (i16 * 88 | 0) + 56 | 0;
+  d23 = +HEAPF32[i20 >> 2];
+  d24 = +HEAPF32[i20 + 4 >> 2];
+  i20 = HEAP32[i37 + (i16 * 88 | 0) + 84 >> 2] | 0;
+  if ((i17 | 0) == (i2 | 0) | (i17 | 0) == (i5 | 0)) {
+   d26 = +HEAPF32[i37 + (i16 * 88 | 0) + 64 >> 2];
+   d27 = +HEAPF32[i37 + (i16 * 88 | 0) + 40 >> 2];
+  } else {
+   d26 = 0.0;
+   d27 = 0.0;
+  }
+  d25 = +HEAPF32[i37 + (i16 * 88 | 0) + 44 >> 2];
+  d28 = +HEAPF32[i37 + (i16 * 88 | 0) + 68 >> 2];
+  i37 = HEAP32[i14 >> 2] | 0;
+  i46 = i37 + (i17 * 12 | 0) | 0;
+  d33 = +HEAPF32[i46 >> 2];
+  d35 = +HEAPF32[i46 + 4 >> 2];
+  d29 = +HEAPF32[i37 + (i17 * 12 | 0) + 8 >> 2];
+  i46 = i37 + (i18 * 12 | 0) | 0;
+  d32 = +HEAPF32[i46 >> 2];
+  d36 = +HEAPF32[i46 + 4 >> 2];
+  d31 = +HEAPF32[i37 + (i18 * 12 | 0) + 8 >> 2];
+  if ((i20 | 0) > 0) {
+   d30 = d27 + d25;
+   i37 = 0;
+   do {
+    d38 = +Math_sin(+d29);
+    HEAPF32[i9 >> 2] = d38;
+    d44 = +Math_cos(+d29);
+    HEAPF32[i15 >> 2] = d44;
+    d43 = +Math_sin(+d31);
+    HEAPF32[i10 >> 2] = d43;
+    d41 = +Math_cos(+d31);
+    HEAPF32[i11 >> 2] = d41;
+    d40 = +(d33 - (d21 * d44 - d22 * d38));
+    d38 = +(d35 - (d22 * d44 + d21 * d38));
+    i46 = i8;
+    HEAPF32[i46 >> 2] = d40;
+    HEAPF32[i46 + 4 >> 2] = d38;
+    d38 = +(d32 - (d23 * d41 - d24 * d43));
+    d43 = +(d36 - (d24 * d41 + d23 * d43));
+    i46 = i3;
+    HEAPF32[i46 >> 2] = d38;
+    HEAPF32[i46 + 4 >> 2] = d43;
+    __ZN24b2PositionSolverManifold10InitializeEP27b2ContactPositionConstraintRK11b2TransformS4_i(i4, i19, i8, i3, i37);
+    i46 = i4;
+    d43 = +HEAPF32[i46 >> 2];
+    d38 = +HEAPF32[i46 + 4 >> 2];
+    i46 = i12;
+    d41 = +HEAPF32[i46 >> 2];
+    d40 = +HEAPF32[i46 + 4 >> 2];
+    d44 = +HEAPF32[i13 >> 2];
+    d39 = d41 - d33;
+    d42 = d40 - d35;
+    d41 = d41 - d32;
+    d40 = d40 - d36;
+    d34 = d34 < d44 ? d34 : d44;
+    d44 = (d44 + .004999999888241291) * .75;
+    d44 = d44 < 0.0 ? d44 : 0.0;
+    d45 = d38 * d39 - d43 * d42;
+    d47 = d38 * d41 - d43 * d40;
+    d45 = d47 * d28 * d47 + (d30 + d45 * d26 * d45);
+    if (d45 > 0.0) {
+     d44 = -(d44 < -.20000000298023224 ? -.20000000298023224 : d44) / d45;
+    } else {
+     d44 = 0.0;
+    }
+    d47 = d43 * d44;
+    d45 = d38 * d44;
+    d33 = d33 - d27 * d47;
+    d35 = d35 - d27 * d45;
+    d29 = d29 - d26 * (d39 * d45 - d42 * d47);
+    d32 = d32 + d25 * d47;
+    d36 = d36 + d25 * d45;
+    d31 = d31 + d28 * (d41 * d45 - d40 * d47);
+    i37 = i37 + 1 | 0;
+   } while ((i37 | 0) != (i20 | 0));
+   i37 = HEAP32[i14 >> 2] | 0;
+  }
+  d47 = +d33;
+  d45 = +d35;
+  i46 = i37 + (i17 * 12 | 0) | 0;
+  HEAPF32[i46 >> 2] = d47;
+  HEAPF32[i46 + 4 >> 2] = d45;
+  i46 = HEAP32[i14 >> 2] | 0;
+  HEAPF32[i46 + (i17 * 12 | 0) + 8 >> 2] = d29;
+  d45 = +d32;
+  d47 = +d36;
+  i46 = i46 + (i18 * 12 | 0) | 0;
+  HEAPF32[i46 >> 2] = d45;
+  HEAPF32[i46 + 4 >> 2] = d47;
+  HEAPF32[(HEAP32[i14 >> 2] | 0) + (i18 * 12 | 0) + 8 >> 2] = d31;
+  i16 = i16 + 1 | 0;
+ } while ((i16 | 0) < (HEAP32[i6 >> 2] | 0));
+ i46 = d34 >= -.007499999832361937;
+ STACKTOP = i1;
+ return i46 | 0;
+}
+function __ZN15b2ContactSolver24SolvePositionConstraintsEv(i7) {
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, d17 = 0.0, d18 = 0.0, d19 = 0.0, d20 = 0.0, i21 = 0, d22 = 0.0, d23 = 0.0, d24 = 0.0, d25 = 0.0, i26 = 0, d27 = 0.0, d28 = 0.0, d29 = 0.0, d30 = 0.0, d31 = 0.0, d32 = 0.0, d33 = 0.0, d34 = 0.0, i35 = 0, d36 = 0.0, d37 = 0.0, d38 = 0.0, d39 = 0.0, d40 = 0.0, d41 = 0.0, d42 = 0.0, d43 = 0.0, i44 = 0, d45 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i4 = i1 + 40 | 0;
+ i5 = i1 + 24 | 0;
+ i3 = i1;
+ i2 = i7 + 48 | 0;
+ if ((HEAP32[i2 >> 2] | 0) <= 0) {
+  d43 = 0.0;
+  i35 = d43 >= -.014999999664723873;
+  STACKTOP = i1;
+  return i35 | 0;
+ }
+ i6 = i7 + 36 | 0;
+ i9 = i7 + 24 | 0;
+ i13 = i4 + 8 | 0;
+ i7 = i4 + 12 | 0;
+ i8 = i5 + 8 | 0;
+ i12 = i5 + 12 | 0;
+ i10 = i3 + 8 | 0;
+ i11 = i3 + 16 | 0;
+ i35 = HEAP32[i9 >> 2] | 0;
+ i15 = 0;
+ d32 = 0.0;
+ do {
+  i21 = HEAP32[i6 >> 2] | 0;
+  i26 = i21 + (i15 * 88 | 0) | 0;
+  i16 = HEAP32[i21 + (i15 * 88 | 0) + 32 >> 2] | 0;
+  i14 = HEAP32[i21 + (i15 * 88 | 0) + 36 >> 2] | 0;
+  i44 = i21 + (i15 * 88 | 0) + 48 | 0;
+  d22 = +HEAPF32[i44 >> 2];
+  d23 = +HEAPF32[i44 + 4 >> 2];
+  d25 = +HEAPF32[i21 + (i15 * 88 | 0) + 40 >> 2];
+  d18 = +HEAPF32[i21 + (i15 * 88 | 0) + 64 >> 2];
+  i44 = i21 + (i15 * 88 | 0) + 56 | 0;
+  d24 = +HEAPF32[i44 >> 2];
+  d19 = +HEAPF32[i44 + 4 >> 2];
+  d17 = +HEAPF32[i21 + (i15 * 88 | 0) + 44 >> 2];
+  d20 = +HEAPF32[i21 + (i15 * 88 | 0) + 68 >> 2];
+  i21 = HEAP32[i21 + (i15 * 88 | 0) + 84 >> 2] | 0;
+  i44 = i35 + (i16 * 12 | 0) | 0;
+  d28 = +HEAPF32[i44 >> 2];
+  d33 = +HEAPF32[i44 + 4 >> 2];
+  d29 = +HEAPF32[i35 + (i16 * 12 | 0) + 8 >> 2];
+  i44 = i35 + (i14 * 12 | 0) | 0;
+  d30 = +HEAPF32[i44 >> 2];
+  d34 = +HEAPF32[i44 + 4 >> 2];
+  d31 = +HEAPF32[i35 + (i14 * 12 | 0) + 8 >> 2];
+  if ((i21 | 0) > 0) {
+   d27 = d25 + d17;
+   i35 = 0;
+   do {
+    d41 = +Math_sin(+d29);
+    HEAPF32[i13 >> 2] = d41;
+    d42 = +Math_cos(+d29);
+    HEAPF32[i7 >> 2] = d42;
+    d39 = +Math_sin(+d31);
+    HEAPF32[i8 >> 2] = d39;
+    d38 = +Math_cos(+d31);
+    HEAPF32[i12 >> 2] = d38;
+    d40 = +(d28 - (d22 * d42 - d23 * d41));
+    d41 = +(d33 - (d23 * d42 + d22 * d41));
+    i44 = i4;
+    HEAPF32[i44 >> 2] = d40;
+    HEAPF32[i44 + 4 >> 2] = d41;
+    d41 = +(d30 - (d24 * d38 - d19 * d39));
+    d39 = +(d34 - (d19 * d38 + d24 * d39));
+    i44 = i5;
+    HEAPF32[i44 >> 2] = d41;
+    HEAPF32[i44 + 4 >> 2] = d39;
+    __ZN24b2PositionSolverManifold10InitializeEP27b2ContactPositionConstraintRK11b2TransformS4_i(i3, i26, i4, i5, i35);
+    i44 = i3;
+    d39 = +HEAPF32[i44 >> 2];
+    d41 = +HEAPF32[i44 + 4 >> 2];
+    i44 = i10;
+    d38 = +HEAPF32[i44 >> 2];
+    d40 = +HEAPF32[i44 + 4 >> 2];
+    d42 = +HEAPF32[i11 >> 2];
+    d36 = d38 - d28;
+    d37 = d40 - d33;
+    d38 = d38 - d30;
+    d40 = d40 - d34;
+    d32 = d32 < d42 ? d32 : d42;
+    d42 = (d42 + .004999999888241291) * .20000000298023224;
+    d43 = d42 < 0.0 ? d42 : 0.0;
+    d42 = d41 * d36 - d39 * d37;
+    d45 = d41 * d38 - d39 * d40;
+    d42 = d45 * d20 * d45 + (d27 + d42 * d18 * d42);
+    if (d42 > 0.0) {
+     d42 = -(d43 < -.20000000298023224 ? -.20000000298023224 : d43) / d42;
+    } else {
+     d42 = 0.0;
+    }
+    d45 = d39 * d42;
+    d43 = d41 * d42;
+    d28 = d28 - d25 * d45;
+    d33 = d33 - d25 * d43;
+    d29 = d29 - d18 * (d36 * d43 - d37 * d45);
+    d30 = d30 + d17 * d45;
+    d34 = d34 + d17 * d43;
+    d31 = d31 + d20 * (d38 * d43 - d40 * d45);
+    i35 = i35 + 1 | 0;
+   } while ((i35 | 0) != (i21 | 0));
+   i35 = HEAP32[i9 >> 2] | 0;
+  }
+  d45 = +d28;
+  d43 = +d33;
+  i35 = i35 + (i16 * 12 | 0) | 0;
+  HEAPF32[i35 >> 2] = d45;
+  HEAPF32[i35 + 4 >> 2] = d43;
+  i35 = HEAP32[i9 >> 2] | 0;
+  HEAPF32[i35 + (i16 * 12 | 0) + 8 >> 2] = d29;
+  d43 = +d30;
+  d45 = +d34;
+  i35 = i35 + (i14 * 12 | 0) | 0;
+  HEAPF32[i35 >> 2] = d43;
+  HEAPF32[i35 + 4 >> 2] = d45;
+  i35 = HEAP32[i9 >> 2] | 0;
+  HEAPF32[i35 + (i14 * 12 | 0) + 8 >> 2] = d31;
+  i15 = i15 + 1 | 0;
+ } while ((i15 | 0) < (HEAP32[i2 >> 2] | 0));
+ i44 = d32 >= -.014999999664723873;
+ STACKTOP = i1;
+ return i44 | 0;
+}
+function __Z22b2CollideEdgeAndCircleP10b2ManifoldPK11b2EdgeShapeRK11b2TransformPK13b2CircleShapeS6_(i1, i7, i6, i22, i5) {
+ i1 = i1 | 0;
+ i7 = i7 | 0;
+ i6 = i6 | 0;
+ i22 = i22 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, d8 = 0.0, d9 = 0.0, d10 = 0.0, d11 = 0.0, d12 = 0.0, d13 = 0.0, i14 = 0, i15 = 0, d16 = 0.0, d17 = 0.0, d18 = 0.0, d19 = 0.0, d20 = 0.0, d21 = 0.0, d23 = 0.0, d24 = 0.0;
+ i4 = STACKTOP;
+ i2 = i1 + 60 | 0;
+ HEAP32[i2 >> 2] = 0;
+ i3 = i22 + 12 | 0;
+ d9 = +HEAPF32[i5 + 12 >> 2];
+ d23 = +HEAPF32[i3 >> 2];
+ d17 = +HEAPF32[i5 + 8 >> 2];
+ d18 = +HEAPF32[i22 + 16 >> 2];
+ d21 = +HEAPF32[i5 >> 2] + (d9 * d23 - d17 * d18) - +HEAPF32[i6 >> 2];
+ d18 = d23 * d17 + d9 * d18 + +HEAPF32[i5 + 4 >> 2] - +HEAPF32[i6 + 4 >> 2];
+ d9 = +HEAPF32[i6 + 12 >> 2];
+ d17 = +HEAPF32[i6 + 8 >> 2];
+ d23 = d21 * d9 + d18 * d17;
+ d17 = d9 * d18 - d21 * d17;
+ i6 = i7 + 12 | 0;
+ i5 = HEAP32[i6 >> 2] | 0;
+ i6 = HEAP32[i6 + 4 >> 2] | 0;
+ d21 = (HEAP32[tempDoublePtr >> 2] = i5, +HEAPF32[tempDoublePtr >> 2]);
+ d18 = (HEAP32[tempDoublePtr >> 2] = i6, +HEAPF32[tempDoublePtr >> 2]);
+ i15 = i7 + 20 | 0;
+ i14 = HEAP32[i15 >> 2] | 0;
+ i15 = HEAP32[i15 + 4 >> 2] | 0;
+ d9 = (HEAP32[tempDoublePtr >> 2] = i14, +HEAPF32[tempDoublePtr >> 2]);
+ d10 = (HEAP32[tempDoublePtr >> 2] = i15, +HEAPF32[tempDoublePtr >> 2]);
+ d8 = d9 - d21;
+ d16 = d10 - d18;
+ d19 = d8 * (d9 - d23) + d16 * (d10 - d17);
+ d13 = d23 - d21;
+ d12 = d17 - d18;
+ d20 = d13 * d8 + d12 * d16;
+ d11 = +HEAPF32[i7 + 8 >> 2] + +HEAPF32[i22 + 8 >> 2];
+ if (d20 <= 0.0) {
+  if (d13 * d13 + d12 * d12 > d11 * d11) {
+   STACKTOP = i4;
+   return;
+  }
+  if ((HEAP8[i7 + 44 | 0] | 0) != 0 ? (i22 = i7 + 28 | 0, d24 = +HEAPF32[i22 >> 2], (d21 - d23) * (d21 - d24) + (d18 - d17) * (d18 - +HEAPF32[i22 + 4 >> 2]) > 0.0) : 0) {
+   STACKTOP = i4;
+   return;
+  }
+  HEAP32[i2 >> 2] = 1;
+  HEAP32[i1 + 56 >> 2] = 0;
+  HEAPF32[i1 + 40 >> 2] = 0.0;
+  HEAPF32[i1 + 44 >> 2] = 0.0;
+  i14 = i1 + 48 | 0;
+  HEAP32[i14 >> 2] = i5;
+  HEAP32[i14 + 4 >> 2] = i6;
+  i14 = i1 + 16 | 0;
+  HEAP32[i14 >> 2] = 0;
+  HEAP8[i14] = 0;
+  HEAP8[i14 + 1 | 0] = 0;
+  HEAP8[i14 + 2 | 0] = 0;
+  HEAP8[i14 + 3 | 0] = 0;
+  i14 = i3;
+  i15 = HEAP32[i14 + 4 >> 2] | 0;
+  i22 = i1;
+  HEAP32[i22 >> 2] = HEAP32[i14 >> 2];
+  HEAP32[i22 + 4 >> 2] = i15;
+  STACKTOP = i4;
+  return;
+ }
+ if (d19 <= 0.0) {
+  d8 = d23 - d9;
+  d12 = d17 - d10;
+  if (d8 * d8 + d12 * d12 > d11 * d11) {
+   STACKTOP = i4;
+   return;
+  }
+  if ((HEAP8[i7 + 45 | 0] | 0) != 0 ? (i22 = i7 + 36 | 0, d24 = +HEAPF32[i22 >> 2], d8 * (d24 - d9) + d12 * (+HEAPF32[i22 + 4 >> 2] - d10) > 0.0) : 0) {
+   STACKTOP = i4;
+   return;
+  }
+  HEAP32[i2 >> 2] = 1;
+  HEAP32[i1 + 56 >> 2] = 0;
+  HEAPF32[i1 + 40 >> 2] = 0.0;
+  HEAPF32[i1 + 44 >> 2] = 0.0;
+  i22 = i1 + 48 | 0;
+  HEAP32[i22 >> 2] = i14;
+  HEAP32[i22 + 4 >> 2] = i15;
+  i14 = i1 + 16 | 0;
+  HEAP32[i14 >> 2] = 0;
+  HEAP8[i14] = 1;
+  HEAP8[i14 + 1 | 0] = 0;
+  HEAP8[i14 + 2 | 0] = 0;
+  HEAP8[i14 + 3 | 0] = 0;
+  i14 = i3;
+  i15 = HEAP32[i14 + 4 >> 2] | 0;
+  i22 = i1;
+  HEAP32[i22 >> 2] = HEAP32[i14 >> 2];
+  HEAP32[i22 + 4 >> 2] = i15;
+  STACKTOP = i4;
+  return;
+ }
+ d24 = d8 * d8 + d16 * d16;
+ if (!(d24 > 0.0)) {
+  ___assert_fail(5560, 5576, 127, 5616);
+ }
+ d24 = 1.0 / d24;
+ d23 = d23 - (d21 * d19 + d9 * d20) * d24;
+ d24 = d17 - (d18 * d19 + d10 * d20) * d24;
+ if (d23 * d23 + d24 * d24 > d11 * d11) {
+  STACKTOP = i4;
+  return;
+ }
+ d9 = -d16;
+ if (d8 * d12 + d13 * d9 < 0.0) {
+  d8 = -d8;
+ } else {
+  d16 = d9;
+ }
+ d9 = +Math_sqrt(+(d8 * d8 + d16 * d16));
+ if (!(d9 < 1.1920928955078125e-7)) {
+  d24 = 1.0 / d9;
+  d16 = d16 * d24;
+  d8 = d8 * d24;
+ }
+ HEAP32[i2 >> 2] = 1;
+ HEAP32[i1 + 56 >> 2] = 1;
+ d23 = +d16;
+ d24 = +d8;
+ i14 = i1 + 40 | 0;
+ HEAPF32[i14 >> 2] = d23;
+ HEAPF32[i14 + 4 >> 2] = d24;
+ i14 = i1 + 48 | 0;
+ HEAP32[i14 >> 2] = i5;
+ HEAP32[i14 + 4 >> 2] = i6;
+ i14 = i1 + 16 | 0;
+ HEAP32[i14 >> 2] = 0;
+ HEAP8[i14] = 0;
+ HEAP8[i14 + 1 | 0] = 0;
+ HEAP8[i14 + 2 | 0] = 1;
+ HEAP8[i14 + 3 | 0] = 0;
+ i14 = i3;
+ i15 = HEAP32[i14 + 4 >> 2] | 0;
+ i22 = i1;
+ HEAP32[i22 >> 2] = HEAP32[i14 >> 2];
+ HEAP32[i22 + 4 >> 2] = i15;
+ STACKTOP = i4;
+ return;
+}
+function __ZN6b2BodyC2EPK9b2BodyDefP7b2World(i1, i2, i5) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ var i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, d13 = 0.0;
+ i3 = STACKTOP;
+ i9 = i2 + 4 | 0;
+ d13 = +HEAPF32[i9 >> 2];
+ if (!(d13 == d13 & 0.0 == 0.0 & d13 > -inf & d13 < inf)) {
+  ___assert_fail(1496, 1520, 27, 1552);
+ }
+ d13 = +HEAPF32[i2 + 8 >> 2];
+ if (!(d13 == d13 & 0.0 == 0.0 & d13 > -inf & d13 < inf)) {
+  ___assert_fail(1496, 1520, 27, 1552);
+ }
+ i6 = i2 + 16 | 0;
+ d13 = +HEAPF32[i6 >> 2];
+ if (!(d13 == d13 & 0.0 == 0.0 & d13 > -inf & d13 < inf)) {
+  ___assert_fail(1560, 1520, 28, 1552);
+ }
+ d13 = +HEAPF32[i2 + 20 >> 2];
+ if (!(d13 == d13 & 0.0 == 0.0 & d13 > -inf & d13 < inf)) {
+  ___assert_fail(1560, 1520, 28, 1552);
+ }
+ i7 = i2 + 12 | 0;
+ d13 = +HEAPF32[i7 >> 2];
+ if (!(d13 == d13 & 0.0 == 0.0 & d13 > -inf & d13 < inf)) {
+  ___assert_fail(1592, 1520, 29, 1552);
+ }
+ i8 = i2 + 24 | 0;
+ d13 = +HEAPF32[i8 >> 2];
+ if (!(d13 == d13 & 0.0 == 0.0 & d13 > -inf & d13 < inf)) {
+  ___assert_fail(1616, 1520, 30, 1552);
+ }
+ i4 = i2 + 32 | 0;
+ d13 = +HEAPF32[i4 >> 2];
+ if (!(d13 >= 0.0) | d13 == d13 & 0.0 == 0.0 & d13 > -inf & d13 < inf ^ 1) {
+  ___assert_fail(1648, 1520, 31, 1552);
+ }
+ i10 = i2 + 28 | 0;
+ d13 = +HEAPF32[i10 >> 2];
+ if (!(d13 >= 0.0) | d13 == d13 & 0.0 == 0.0 & d13 > -inf & d13 < inf ^ 1) {
+  ___assert_fail(1712, 1520, 32, 1552);
+ }
+ i11 = i1 + 4 | 0;
+ i12 = (HEAP8[i2 + 39 | 0] | 0) == 0 ? 0 : 8;
+ HEAP16[i11 >> 1] = i12;
+ if ((HEAP8[i2 + 38 | 0] | 0) != 0) {
+  i12 = (i12 & 65535 | 16) & 65535;
+  HEAP16[i11 >> 1] = i12;
+ }
+ if ((HEAP8[i2 + 36 | 0] | 0) != 0) {
+  i12 = (i12 & 65535 | 4) & 65535;
+  HEAP16[i11 >> 1] = i12;
+ }
+ if ((HEAP8[i2 + 37 | 0] | 0) != 0) {
+  i12 = (i12 & 65535 | 2) & 65535;
+  HEAP16[i11 >> 1] = i12;
+ }
+ if ((HEAP8[i2 + 40 | 0] | 0) != 0) {
+  HEAP16[i11 >> 1] = i12 & 65535 | 32;
+ }
+ HEAP32[i1 + 88 >> 2] = i5;
+ i11 = i9;
+ i12 = HEAP32[i11 >> 2] | 0;
+ i11 = HEAP32[i11 + 4 >> 2] | 0;
+ i9 = i1 + 12 | 0;
+ HEAP32[i9 >> 2] = i12;
+ HEAP32[i9 + 4 >> 2] = i11;
+ d13 = +HEAPF32[i7 >> 2];
+ HEAPF32[i1 + 20 >> 2] = +Math_sin(+d13);
+ HEAPF32[i1 + 24 >> 2] = +Math_cos(+d13);
+ HEAPF32[i1 + 28 >> 2] = 0.0;
+ HEAPF32[i1 + 32 >> 2] = 0.0;
+ i9 = i1 + 36 | 0;
+ HEAP32[i9 >> 2] = i12;
+ HEAP32[i9 + 4 >> 2] = i11;
+ i9 = i1 + 44 | 0;
+ HEAP32[i9 >> 2] = i12;
+ HEAP32[i9 + 4 >> 2] = i11;
+ HEAPF32[i1 + 52 >> 2] = +HEAPF32[i7 >> 2];
+ HEAPF32[i1 + 56 >> 2] = +HEAPF32[i7 >> 2];
+ HEAPF32[i1 + 60 >> 2] = 0.0;
+ HEAP32[i1 + 108 >> 2] = 0;
+ HEAP32[i1 + 112 >> 2] = 0;
+ HEAP32[i1 + 92 >> 2] = 0;
+ HEAP32[i1 + 96 >> 2] = 0;
+ i9 = i6;
+ i11 = HEAP32[i9 + 4 >> 2] | 0;
+ i12 = i1 + 64 | 0;
+ HEAP32[i12 >> 2] = HEAP32[i9 >> 2];
+ HEAP32[i12 + 4 >> 2] = i11;
+ HEAPF32[i1 + 72 >> 2] = +HEAPF32[i8 >> 2];
+ HEAPF32[i1 + 132 >> 2] = +HEAPF32[i10 >> 2];
+ HEAPF32[i1 + 136 >> 2] = +HEAPF32[i4 >> 2];
+ HEAPF32[i1 + 140 >> 2] = +HEAPF32[i2 + 48 >> 2];
+ HEAPF32[i1 + 76 >> 2] = 0.0;
+ HEAPF32[i1 + 80 >> 2] = 0.0;
+ HEAPF32[i1 + 84 >> 2] = 0.0;
+ HEAPF32[i1 + 144 >> 2] = 0.0;
+ i12 = HEAP32[i2 >> 2] | 0;
+ HEAP32[i1 >> 2] = i12;
+ i4 = i1 + 116 | 0;
+ if ((i12 | 0) == 2) {
+  HEAPF32[i4 >> 2] = 1.0;
+  HEAPF32[i1 + 120 >> 2] = 1.0;
+  i11 = i1 + 124 | 0;
+  HEAPF32[i11 >> 2] = 0.0;
+  i11 = i1 + 128 | 0;
+  HEAPF32[i11 >> 2] = 0.0;
+  i11 = i2 + 44 | 0;
+  i11 = HEAP32[i11 >> 2] | 0;
+  i12 = i1 + 148 | 0;
+  HEAP32[i12 >> 2] = i11;
+  i12 = i1 + 100 | 0;
+  HEAP32[i12 >> 2] = 0;
+  i12 = i1 + 104 | 0;
+  HEAP32[i12 >> 2] = 0;
+  STACKTOP = i3;
+  return;
+ } else {
+  HEAPF32[i4 >> 2] = 0.0;
+  HEAPF32[i1 + 120 >> 2] = 0.0;
+  i11 = i1 + 124 | 0;
+  HEAPF32[i11 >> 2] = 0.0;
+  i11 = i1 + 128 | 0;
+  HEAPF32[i11 >> 2] = 0.0;
+  i11 = i2 + 44 | 0;
+  i11 = HEAP32[i11 >> 2] | 0;
+  i12 = i1 + 148 | 0;
+  HEAP32[i12 >> 2] = i11;
+  i12 = i1 + 100 | 0;
+  HEAP32[i12 >> 2] = 0;
+  i12 = i1 + 104 | 0;
+  HEAP32[i12 >> 2] = 0;
+  STACKTOP = i3;
+  return;
+ }
+}
+function __ZN24b2PositionSolverManifold10InitializeEP27b2ContactPositionConstraintRK11b2TransformS4_i(i2, i1, i13, i12, i15) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ i13 = i13 | 0;
+ i12 = i12 | 0;
+ i15 = i15 | 0;
+ var i3 = 0, d4 = 0.0, d5 = 0.0, d6 = 0.0, d7 = 0.0, d8 = 0.0, d9 = 0.0, d10 = 0.0, d11 = 0.0, i14 = 0, d16 = 0.0, d17 = 0.0, d18 = 0.0, i19 = 0, i20 = 0;
+ i3 = STACKTOP;
+ if ((HEAP32[i1 + 84 >> 2] | 0) <= 0) {
+  ___assert_fail(6752, 6520, 617, 6776);
+ }
+ i14 = HEAP32[i1 + 72 >> 2] | 0;
+ if ((i14 | 0) == 1) {
+  i19 = i13 + 12 | 0;
+  d5 = +HEAPF32[i19 >> 2];
+  d6 = +HEAPF32[i1 + 16 >> 2];
+  i14 = i13 + 8 | 0;
+  d7 = +HEAPF32[i14 >> 2];
+  d9 = +HEAPF32[i1 + 20 >> 2];
+  d4 = d5 * d6 - d7 * d9;
+  d9 = d6 * d7 + d5 * d9;
+  d5 = +d4;
+  d7 = +d9;
+  i20 = i2;
+  HEAPF32[i20 >> 2] = d5;
+  HEAPF32[i20 + 4 >> 2] = d7;
+  d7 = +HEAPF32[i19 >> 2];
+  d5 = +HEAPF32[i1 + 24 >> 2];
+  d6 = +HEAPF32[i14 >> 2];
+  d8 = +HEAPF32[i1 + 28 >> 2];
+  d16 = +HEAPF32[i12 + 12 >> 2];
+  d18 = +HEAPF32[i1 + (i15 << 3) >> 2];
+  d17 = +HEAPF32[i12 + 8 >> 2];
+  d11 = +HEAPF32[i1 + (i15 << 3) + 4 >> 2];
+  d10 = +HEAPF32[i12 >> 2] + (d16 * d18 - d17 * d11);
+  d11 = d18 * d17 + d16 * d11 + +HEAPF32[i12 + 4 >> 2];
+  HEAPF32[i2 + 16 >> 2] = d4 * (d10 - (+HEAPF32[i13 >> 2] + (d7 * d5 - d6 * d8))) + (d11 - (d5 * d6 + d7 * d8 + +HEAPF32[i13 + 4 >> 2])) * d9 - +HEAPF32[i1 + 76 >> 2] - +HEAPF32[i1 + 80 >> 2];
+  d10 = +d10;
+  d11 = +d11;
+  i15 = i2 + 8 | 0;
+  HEAPF32[i15 >> 2] = d10;
+  HEAPF32[i15 + 4 >> 2] = d11;
+  STACKTOP = i3;
+  return;
+ } else if ((i14 | 0) == 2) {
+  i19 = i12 + 12 | 0;
+  d7 = +HEAPF32[i19 >> 2];
+  d8 = +HEAPF32[i1 + 16 >> 2];
+  i20 = i12 + 8 | 0;
+  d9 = +HEAPF32[i20 >> 2];
+  d18 = +HEAPF32[i1 + 20 >> 2];
+  d17 = d7 * d8 - d9 * d18;
+  d18 = d8 * d9 + d7 * d18;
+  d7 = +d17;
+  d9 = +d18;
+  i14 = i2;
+  HEAPF32[i14 >> 2] = d7;
+  HEAPF32[i14 + 4 >> 2] = d9;
+  d9 = +HEAPF32[i19 >> 2];
+  d7 = +HEAPF32[i1 + 24 >> 2];
+  d8 = +HEAPF32[i20 >> 2];
+  d10 = +HEAPF32[i1 + 28 >> 2];
+  d6 = +HEAPF32[i13 + 12 >> 2];
+  d4 = +HEAPF32[i1 + (i15 << 3) >> 2];
+  d5 = +HEAPF32[i13 + 8 >> 2];
+  d16 = +HEAPF32[i1 + (i15 << 3) + 4 >> 2];
+  d11 = +HEAPF32[i13 >> 2] + (d6 * d4 - d5 * d16);
+  d16 = d4 * d5 + d6 * d16 + +HEAPF32[i13 + 4 >> 2];
+  HEAPF32[i2 + 16 >> 2] = d17 * (d11 - (+HEAPF32[i12 >> 2] + (d9 * d7 - d8 * d10))) + (d16 - (d7 * d8 + d9 * d10 + +HEAPF32[i12 + 4 >> 2])) * d18 - +HEAPF32[i1 + 76 >> 2] - +HEAPF32[i1 + 80 >> 2];
+  d11 = +d11;
+  d16 = +d16;
+  i20 = i2 + 8 | 0;
+  HEAPF32[i20 >> 2] = d11;
+  HEAPF32[i20 + 4 >> 2] = d16;
+  d17 = +-d17;
+  d18 = +-d18;
+  i20 = i2;
+  HEAPF32[i20 >> 2] = d17;
+  HEAPF32[i20 + 4 >> 2] = d18;
+  STACKTOP = i3;
+  return;
+ } else if ((i14 | 0) == 0) {
+  d7 = +HEAPF32[i13 + 12 >> 2];
+  d8 = +HEAPF32[i1 + 24 >> 2];
+  d18 = +HEAPF32[i13 + 8 >> 2];
+  d6 = +HEAPF32[i1 + 28 >> 2];
+  d4 = +HEAPF32[i13 >> 2] + (d7 * d8 - d18 * d6);
+  d6 = d8 * d18 + d7 * d6 + +HEAPF32[i13 + 4 >> 2];
+  d7 = +HEAPF32[i12 + 12 >> 2];
+  d18 = +HEAPF32[i1 >> 2];
+  d8 = +HEAPF32[i12 + 8 >> 2];
+  d9 = +HEAPF32[i1 + 4 >> 2];
+  d5 = +HEAPF32[i12 >> 2] + (d7 * d18 - d8 * d9);
+  d9 = d18 * d8 + d7 * d9 + +HEAPF32[i12 + 4 >> 2];
+  d7 = d5 - d4;
+  d8 = d9 - d6;
+  d18 = +d7;
+  d10 = +d8;
+  i20 = i2;
+  HEAPF32[i20 >> 2] = d18;
+  HEAPF32[i20 + 4 >> 2] = d10;
+  d10 = +Math_sqrt(+(d7 * d7 + d8 * d8));
+  if (d10 < 1.1920928955078125e-7) {
+   d10 = d7;
+   d11 = d8;
+  } else {
+   d11 = 1.0 / d10;
+   d10 = d7 * d11;
+   HEAPF32[i2 >> 2] = d10;
+   d11 = d8 * d11;
+   HEAPF32[i2 + 4 >> 2] = d11;
+  }
+  d17 = +((d4 + d5) * .5);
+  d18 = +((d6 + d9) * .5);
+  i20 = i2 + 8 | 0;
+  HEAPF32[i20 >> 2] = d17;
+  HEAPF32[i20 + 4 >> 2] = d18;
+  HEAPF32[i2 + 16 >> 2] = d7 * d10 + d8 * d11 - +HEAPF32[i1 + 76 >> 2] - +HEAPF32[i1 + 80 >> 2];
+  STACKTOP = i3;
+  return;
+ } else {
+  STACKTOP = i3;
+  return;
+ }
+}
+function __ZNSt3__118__insertion_sort_3IRPFbRK6b2PairS3_EPS1_EEvT0_S8_T_(i5, i1, i2) {
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i6 = i4 + 12 | 0;
+ i3 = i4;
+ i7 = i5 + 24 | 0;
+ i8 = i5 + 12 | 0;
+ i10 = FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i8, i5) | 0;
+ i9 = FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i7, i8) | 0;
+ do {
+  if (i10) {
+   if (i9) {
+    HEAP32[i6 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+    HEAP32[i6 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+    HEAP32[i6 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+    HEAP32[i5 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+    HEAP32[i5 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+    HEAP32[i5 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+    HEAP32[i7 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+    HEAP32[i7 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+    HEAP32[i7 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+    break;
+   }
+   HEAP32[i6 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+   HEAP32[i6 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+   HEAP32[i6 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+   HEAP32[i5 + 0 >> 2] = HEAP32[i8 + 0 >> 2];
+   HEAP32[i5 + 4 >> 2] = HEAP32[i8 + 4 >> 2];
+   HEAP32[i5 + 8 >> 2] = HEAP32[i8 + 8 >> 2];
+   HEAP32[i8 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+   HEAP32[i8 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+   HEAP32[i8 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+   if (FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i7, i8) | 0) {
+    HEAP32[i6 + 0 >> 2] = HEAP32[i8 + 0 >> 2];
+    HEAP32[i6 + 4 >> 2] = HEAP32[i8 + 4 >> 2];
+    HEAP32[i6 + 8 >> 2] = HEAP32[i8 + 8 >> 2];
+    HEAP32[i8 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+    HEAP32[i8 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+    HEAP32[i8 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+    HEAP32[i7 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+    HEAP32[i7 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+    HEAP32[i7 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+   }
+  } else {
+   if (i9) {
+    HEAP32[i6 + 0 >> 2] = HEAP32[i8 + 0 >> 2];
+    HEAP32[i6 + 4 >> 2] = HEAP32[i8 + 4 >> 2];
+    HEAP32[i6 + 8 >> 2] = HEAP32[i8 + 8 >> 2];
+    HEAP32[i8 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+    HEAP32[i8 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+    HEAP32[i8 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+    HEAP32[i7 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+    HEAP32[i7 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+    HEAP32[i7 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+    if (FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i8, i5) | 0) {
+     HEAP32[i6 + 0 >> 2] = HEAP32[i5 + 0 >> 2];
+     HEAP32[i6 + 4 >> 2] = HEAP32[i5 + 4 >> 2];
+     HEAP32[i6 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+     HEAP32[i5 + 0 >> 2] = HEAP32[i8 + 0 >> 2];
+     HEAP32[i5 + 4 >> 2] = HEAP32[i8 + 4 >> 2];
+     HEAP32[i5 + 8 >> 2] = HEAP32[i8 + 8 >> 2];
+     HEAP32[i8 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+     HEAP32[i8 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+     HEAP32[i8 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+    }
+   }
+  }
+ } while (0);
+ i6 = i5 + 36 | 0;
+ if ((i6 | 0) == (i1 | 0)) {
+  STACKTOP = i4;
+  return;
+ }
+ while (1) {
+  if (FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i6, i7) | 0) {
+   HEAP32[i3 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+   HEAP32[i3 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+   HEAP32[i3 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+   i8 = i6;
+   while (1) {
+    HEAP32[i8 + 0 >> 2] = HEAP32[i7 + 0 >> 2];
+    HEAP32[i8 + 4 >> 2] = HEAP32[i7 + 4 >> 2];
+    HEAP32[i8 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+    if ((i7 | 0) == (i5 | 0)) {
+     break;
+    }
+    i8 = i7 + -12 | 0;
+    if (FUNCTION_TABLE_iii[HEAP32[i2 >> 2] & 3](i3, i8) | 0) {
+     i10 = i7;
+     i7 = i8;
+     i8 = i10;
+    } else {
+     break;
+    }
+   }
+   HEAP32[i7 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+   HEAP32[i7 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+   HEAP32[i7 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+  }
+  i7 = i6 + 12 | 0;
+  if ((i7 | 0) == (i1 | 0)) {
+   break;
+  } else {
+   i10 = i6;
+   i6 = i7;
+   i7 = i10;
+  }
+ }
+ STACKTOP = i4;
+ return;
+}
+function __ZNK20b2SeparationFunction8EvaluateEiif(i10, i12, i11, d9) {
+ i10 = i10 | 0;
+ i12 = i12 | 0;
+ i11 = i11 | 0;
+ d9 = +d9;
+ var d1 = 0.0, d2 = 0.0, d3 = 0.0, d4 = 0.0, d5 = 0.0, d6 = 0.0, i7 = 0, d8 = 0.0, d13 = 0.0, d14 = 0.0, d15 = 0.0, d16 = 0.0, i17 = 0, d18 = 0.0, d19 = 0.0;
+ i7 = STACKTOP;
+ d14 = 1.0 - d9;
+ d3 = d14 * +HEAPF32[i10 + 32 >> 2] + +HEAPF32[i10 + 36 >> 2] * d9;
+ d4 = +Math_sin(+d3);
+ d3 = +Math_cos(+d3);
+ d5 = +HEAPF32[i10 + 8 >> 2];
+ d6 = +HEAPF32[i10 + 12 >> 2];
+ d2 = d14 * +HEAPF32[i10 + 16 >> 2] + +HEAPF32[i10 + 24 >> 2] * d9 - (d3 * d5 - d4 * d6);
+ d6 = d14 * +HEAPF32[i10 + 20 >> 2] + +HEAPF32[i10 + 28 >> 2] * d9 - (d4 * d5 + d3 * d6);
+ d5 = d14 * +HEAPF32[i10 + 68 >> 2] + +HEAPF32[i10 + 72 >> 2] * d9;
+ d1 = +Math_sin(+d5);
+ d5 = +Math_cos(+d5);
+ d15 = +HEAPF32[i10 + 44 >> 2];
+ d16 = +HEAPF32[i10 + 48 >> 2];
+ d8 = d14 * +HEAPF32[i10 + 52 >> 2] + +HEAPF32[i10 + 60 >> 2] * d9 - (d5 * d15 - d1 * d16);
+ d9 = d14 * +HEAPF32[i10 + 56 >> 2] + +HEAPF32[i10 + 64 >> 2] * d9 - (d1 * d15 + d5 * d16);
+ i17 = HEAP32[i10 + 80 >> 2] | 0;
+ if ((i17 | 0) == 0) {
+  d14 = +HEAPF32[i10 + 92 >> 2];
+  d13 = +HEAPF32[i10 + 96 >> 2];
+  i17 = HEAP32[i10 >> 2] | 0;
+  if (!((i12 | 0) > -1)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  if ((HEAP32[i17 + 20 >> 2] | 0) <= (i12 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i17 = (HEAP32[i17 + 16 >> 2] | 0) + (i12 << 3) | 0;
+  d15 = +HEAPF32[i17 >> 2];
+  d16 = +HEAPF32[i17 + 4 >> 2];
+  i10 = HEAP32[i10 + 4 >> 2] | 0;
+  if (!((i11 | 0) > -1)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  if ((HEAP32[i10 + 20 >> 2] | 0) <= (i11 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i17 = (HEAP32[i10 + 16 >> 2] | 0) + (i11 << 3) | 0;
+  d19 = +HEAPF32[i17 >> 2];
+  d18 = +HEAPF32[i17 + 4 >> 2];
+  d16 = d14 * (d8 + (d5 * d19 - d1 * d18) - (d2 + (d3 * d15 - d4 * d16))) + d13 * (d9 + (d1 * d19 + d5 * d18) - (d6 + (d4 * d15 + d3 * d16)));
+  STACKTOP = i7;
+  return +d16;
+ } else if ((i17 | 0) == 1) {
+  d14 = +HEAPF32[i10 + 92 >> 2];
+  d13 = +HEAPF32[i10 + 96 >> 2];
+  d16 = +HEAPF32[i10 + 84 >> 2];
+  d15 = +HEAPF32[i10 + 88 >> 2];
+  i10 = HEAP32[i10 + 4 >> 2] | 0;
+  if (!((i11 | 0) > -1)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  if ((HEAP32[i10 + 20 >> 2] | 0) <= (i11 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i17 = (HEAP32[i10 + 16 >> 2] | 0) + (i11 << 3) | 0;
+  d18 = +HEAPF32[i17 >> 2];
+  d19 = +HEAPF32[i17 + 4 >> 2];
+  d19 = (d3 * d14 - d4 * d13) * (d8 + (d5 * d18 - d1 * d19) - (d2 + (d3 * d16 - d4 * d15))) + (d4 * d14 + d3 * d13) * (d9 + (d1 * d18 + d5 * d19) - (d6 + (d4 * d16 + d3 * d15)));
+  STACKTOP = i7;
+  return +d19;
+ } else if ((i17 | 0) == 2) {
+  d16 = +HEAPF32[i10 + 92 >> 2];
+  d15 = +HEAPF32[i10 + 96 >> 2];
+  d14 = +HEAPF32[i10 + 84 >> 2];
+  d13 = +HEAPF32[i10 + 88 >> 2];
+  i10 = HEAP32[i10 >> 2] | 0;
+  if (!((i12 | 0) > -1)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  if ((HEAP32[i10 + 20 >> 2] | 0) <= (i12 | 0)) {
+   ___assert_fail(3640, 3672, 103, 3704);
+  }
+  i17 = (HEAP32[i10 + 16 >> 2] | 0) + (i12 << 3) | 0;
+  d18 = +HEAPF32[i17 >> 2];
+  d19 = +HEAPF32[i17 + 4 >> 2];
+  d19 = (d5 * d16 - d1 * d15) * (d2 + (d3 * d18 - d4 * d19) - (d8 + (d5 * d14 - d1 * d13))) + (d1 * d16 + d5 * d15) * (d6 + (d4 * d18 + d3 * d19) - (d9 + (d1 * d14 + d5 * d13)));
+  STACKTOP = i7;
+  return +d19;
+ } else {
+  ___assert_fail(3616, 3560, 242, 3624);
+ }
+ return 0.0;
+}
+function __ZN6b2Body13ResetMassDataEv(i2) {
+ i2 = i2 | 0;
+ var d1 = 0.0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, d14 = 0.0, d15 = 0.0, d16 = 0.0, i17 = 0, d18 = 0.0, d19 = 0.0, i20 = 0, d21 = 0.0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i10 = i3;
+ i8 = i2 + 116 | 0;
+ i9 = i2 + 120 | 0;
+ i4 = i2 + 124 | 0;
+ i5 = i2 + 128 | 0;
+ i6 = i2 + 28 | 0;
+ HEAPF32[i6 >> 2] = 0.0;
+ HEAPF32[i2 + 32 >> 2] = 0.0;
+ HEAP32[i8 + 0 >> 2] = 0;
+ HEAP32[i8 + 4 >> 2] = 0;
+ HEAP32[i8 + 8 >> 2] = 0;
+ HEAP32[i8 + 12 >> 2] = 0;
+ i11 = HEAP32[i2 >> 2] | 0;
+ if ((i11 | 0) == 2) {
+  i17 = 3784;
+  d16 = +HEAPF32[i17 >> 2];
+  d18 = +HEAPF32[i17 + 4 >> 2];
+  i17 = HEAP32[i2 + 100 >> 2] | 0;
+  if ((i17 | 0) != 0) {
+   i11 = i10 + 4 | 0;
+   i12 = i10 + 8 | 0;
+   i13 = i10 + 12 | 0;
+   d14 = 0.0;
+   d15 = 0.0;
+   do {
+    d19 = +HEAPF32[i17 >> 2];
+    if (!(d19 == 0.0)) {
+     i20 = HEAP32[i17 + 12 >> 2] | 0;
+     FUNCTION_TABLE_viid[HEAP32[(HEAP32[i20 >> 2] | 0) + 28 >> 2] & 3](i20, i10, d19);
+     d14 = +HEAPF32[i10 >> 2];
+     d15 = d14 + +HEAPF32[i8 >> 2];
+     HEAPF32[i8 >> 2] = d15;
+     d16 = d16 + d14 * +HEAPF32[i11 >> 2];
+     d18 = d18 + d14 * +HEAPF32[i12 >> 2];
+     d14 = +HEAPF32[i13 >> 2] + +HEAPF32[i4 >> 2];
+     HEAPF32[i4 >> 2] = d14;
+    }
+    i17 = HEAP32[i17 + 4 >> 2] | 0;
+   } while ((i17 | 0) != 0);
+   if (d15 > 0.0) {
+    d19 = 1.0 / d15;
+    HEAPF32[i9 >> 2] = d19;
+    d16 = d16 * d19;
+    d18 = d18 * d19;
+   } else {
+    i7 = 11;
+   }
+  } else {
+   d14 = 0.0;
+   i7 = 11;
+  }
+  if ((i7 | 0) == 11) {
+   HEAPF32[i8 >> 2] = 1.0;
+   HEAPF32[i9 >> 2] = 1.0;
+   d15 = 1.0;
+  }
+  do {
+   if (d14 > 0.0 ? (HEAP16[i2 + 4 >> 1] & 16) == 0 : 0) {
+    d14 = d14 - (d18 * d18 + d16 * d16) * d15;
+    HEAPF32[i4 >> 2] = d14;
+    if (d14 > 0.0) {
+     d1 = 1.0 / d14;
+     break;
+    } else {
+     ___assert_fail(1872, 1520, 319, 1856);
+    }
+   } else {
+    i7 = 17;
+   }
+  } while (0);
+  if ((i7 | 0) == 17) {
+   HEAPF32[i4 >> 2] = 0.0;
+   d1 = 0.0;
+  }
+  HEAPF32[i5 >> 2] = d1;
+  i20 = i2 + 44 | 0;
+  i17 = i20;
+  d19 = +HEAPF32[i17 >> 2];
+  d14 = +HEAPF32[i17 + 4 >> 2];
+  d21 = +d16;
+  d1 = +d18;
+  i17 = i6;
+  HEAPF32[i17 >> 2] = d21;
+  HEAPF32[i17 + 4 >> 2] = d1;
+  d1 = +HEAPF32[i2 + 24 >> 2];
+  d21 = +HEAPF32[i2 + 20 >> 2];
+  d15 = +HEAPF32[i2 + 12 >> 2] + (d1 * d16 - d21 * d18);
+  d16 = d16 * d21 + d1 * d18 + +HEAPF32[i2 + 16 >> 2];
+  d1 = +d15;
+  d18 = +d16;
+  HEAPF32[i20 >> 2] = d1;
+  HEAPF32[i20 + 4 >> 2] = d18;
+  i20 = i2 + 36 | 0;
+  HEAPF32[i20 >> 2] = d1;
+  HEAPF32[i20 + 4 >> 2] = d18;
+  d18 = +HEAPF32[i2 + 72 >> 2];
+  i20 = i2 + 64 | 0;
+  HEAPF32[i20 >> 2] = +HEAPF32[i20 >> 2] - d18 * (d16 - d14);
+  i20 = i2 + 68 | 0;
+  HEAPF32[i20 >> 2] = d18 * (d15 - d19) + +HEAPF32[i20 >> 2];
+  STACKTOP = i3;
+  return;
+ } else if ((i11 | 0) == 1 | (i11 | 0) == 0) {
+  i17 = i2 + 12 | 0;
+  i13 = HEAP32[i17 >> 2] | 0;
+  i17 = HEAP32[i17 + 4 >> 2] | 0;
+  i20 = i2 + 36 | 0;
+  HEAP32[i20 >> 2] = i13;
+  HEAP32[i20 + 4 >> 2] = i17;
+  i20 = i2 + 44 | 0;
+  HEAP32[i20 >> 2] = i13;
+  HEAP32[i20 + 4 >> 2] = i17;
+  HEAPF32[i2 + 52 >> 2] = +HEAPF32[i2 + 56 >> 2];
+  STACKTOP = i3;
+  return;
+ } else {
+  ___assert_fail(1824, 1520, 284, 1856);
+ }
+}
+function __ZN9b2Contact6UpdateEP17b2ContactListener(i1, i4) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i2 = i3;
+ i10 = i1 + 64 | 0;
+ i6 = i2 + 0 | 0;
+ i7 = i10 + 0 | 0;
+ i5 = i6 + 64 | 0;
+ do {
+  HEAP32[i6 >> 2] = HEAP32[i7 >> 2];
+  i6 = i6 + 4 | 0;
+  i7 = i7 + 4 | 0;
+ } while ((i6 | 0) < (i5 | 0));
+ i6 = i1 + 4 | 0;
+ i11 = HEAP32[i6 >> 2] | 0;
+ HEAP32[i6 >> 2] = i11 | 4;
+ i11 = i11 >>> 1;
+ i14 = HEAP32[i1 + 48 >> 2] | 0;
+ i15 = HEAP32[i1 + 52 >> 2] | 0;
+ i5 = (HEAP8[i15 + 38 | 0] | HEAP8[i14 + 38 | 0]) << 24 >> 24 != 0;
+ i8 = HEAP32[i14 + 8 >> 2] | 0;
+ i7 = HEAP32[i15 + 8 >> 2] | 0;
+ i12 = i8 + 12 | 0;
+ i13 = i7 + 12 | 0;
+ if (!i5) {
+  FUNCTION_TABLE_viiii[HEAP32[HEAP32[i1 >> 2] >> 2] & 15](i1, i10, i12, i13);
+  i12 = i1 + 124 | 0;
+  i10 = (HEAP32[i12 >> 2] | 0) > 0;
+  L4 : do {
+   if (i10) {
+    i19 = HEAP32[i2 + 60 >> 2] | 0;
+    if ((i19 | 0) > 0) {
+     i18 = 0;
+    } else {
+     i9 = 0;
+     while (1) {
+      HEAPF32[i1 + (i9 * 20 | 0) + 72 >> 2] = 0.0;
+      HEAPF32[i1 + (i9 * 20 | 0) + 76 >> 2] = 0.0;
+      i9 = i9 + 1 | 0;
+      if ((i9 | 0) >= (HEAP32[i12 >> 2] | 0)) {
+       break L4;
+      }
+     }
+    }
+    do {
+     i16 = i1 + (i18 * 20 | 0) + 72 | 0;
+     HEAPF32[i16 >> 2] = 0.0;
+     i15 = i1 + (i18 * 20 | 0) + 76 | 0;
+     HEAPF32[i15 >> 2] = 0.0;
+     i14 = HEAP32[i1 + (i18 * 20 | 0) + 80 >> 2] | 0;
+     i17 = 0;
+     while (1) {
+      i13 = i17 + 1 | 0;
+      if ((HEAP32[i2 + (i17 * 20 | 0) + 16 >> 2] | 0) == (i14 | 0)) {
+       i9 = 7;
+       break;
+      }
+      if ((i13 | 0) < (i19 | 0)) {
+       i17 = i13;
+      } else {
+       break;
+      }
+     }
+     if ((i9 | 0) == 7) {
+      i9 = 0;
+      HEAPF32[i16 >> 2] = +HEAPF32[i2 + (i17 * 20 | 0) + 8 >> 2];
+      HEAPF32[i15 >> 2] = +HEAPF32[i2 + (i17 * 20 | 0) + 12 >> 2];
+     }
+     i18 = i18 + 1 | 0;
+    } while ((i18 | 0) < (HEAP32[i12 >> 2] | 0));
+   }
+  } while (0);
+  i9 = i11 & 1;
+  if (i10 ^ (i9 | 0) != 0) {
+   i11 = i8 + 4 | 0;
+   i12 = HEAPU16[i11 >> 1] | 0;
+   if ((i12 & 2 | 0) == 0) {
+    HEAP16[i11 >> 1] = i12 | 2;
+    HEAPF32[i8 + 144 >> 2] = 0.0;
+   }
+   i8 = i7 + 4 | 0;
+   i11 = HEAPU16[i8 >> 1] | 0;
+   if ((i11 & 2 | 0) == 0) {
+    HEAP16[i8 >> 1] = i11 | 2;
+    HEAPF32[i7 + 144 >> 2] = 0.0;
+   }
+  }
+ } else {
+  i10 = __Z13b2TestOverlapPK7b2ShapeiS1_iRK11b2TransformS4_(HEAP32[i14 + 12 >> 2] | 0, HEAP32[i1 + 56 >> 2] | 0, HEAP32[i15 + 12 >> 2] | 0, HEAP32[i1 + 60 >> 2] | 0, i12, i13) | 0;
+  HEAP32[i1 + 124 >> 2] = 0;
+  i9 = i11 & 1;
+ }
+ i7 = HEAP32[i6 >> 2] | 0;
+ HEAP32[i6 >> 2] = i10 ? i7 | 2 : i7 & -3;
+ i8 = (i9 | 0) == 0;
+ i6 = i10 ^ 1;
+ i7 = (i4 | 0) == 0;
+ if (!(i8 ^ 1 | i6 | i7)) {
+  FUNCTION_TABLE_vii[HEAP32[(HEAP32[i4 >> 2] | 0) + 8 >> 2] & 15](i4, i1);
+ }
+ if (!(i8 | i10 | i7)) {
+  FUNCTION_TABLE_vii[HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] & 15](i4, i1);
+ }
+ if (i5 | i6 | i7) {
+  STACKTOP = i3;
+  return;
+ }
+ FUNCTION_TABLE_viii[HEAP32[(HEAP32[i4 >> 2] | 0) + 16 >> 2] & 3](i4, i1, i2);
+ STACKTOP = i3;
+ return;
+}
+function __ZN13b2DynamicTree10RemoveLeafEi(i1, i12) {
+ i1 = i1 | 0;
+ i12 = i12 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, d8 = 0.0, d9 = 0.0, d10 = 0.0, d11 = 0.0, i13 = 0;
+ i2 = STACKTOP;
+ if ((HEAP32[i1 >> 2] | 0) == (i12 | 0)) {
+  HEAP32[i1 >> 2] = -1;
+  STACKTOP = i2;
+  return;
+ }
+ i3 = i1 + 4 | 0;
+ i5 = HEAP32[i3 >> 2] | 0;
+ i6 = HEAP32[i5 + (i12 * 36 | 0) + 20 >> 2] | 0;
+ i4 = i5 + (i6 * 36 | 0) + 20 | 0;
+ i7 = HEAP32[i4 >> 2] | 0;
+ i13 = HEAP32[i5 + (i6 * 36 | 0) + 24 >> 2] | 0;
+ if ((i13 | 0) == (i12 | 0)) {
+  i13 = HEAP32[i5 + (i6 * 36 | 0) + 28 >> 2] | 0;
+ }
+ if ((i7 | 0) == -1) {
+  HEAP32[i1 >> 2] = i13;
+  HEAP32[i5 + (i13 * 36 | 0) + 20 >> 2] = -1;
+  if (!((i6 | 0) > -1)) {
+   ___assert_fail(3e3, 2944, 97, 3040);
+  }
+  if ((HEAP32[i1 + 12 >> 2] | 0) <= (i6 | 0)) {
+   ___assert_fail(3e3, 2944, 97, 3040);
+  }
+  i3 = i1 + 8 | 0;
+  if ((HEAP32[i3 >> 2] | 0) <= 0) {
+   ___assert_fail(3056, 2944, 98, 3040);
+  }
+  i13 = i1 + 16 | 0;
+  HEAP32[i4 >> 2] = HEAP32[i13 >> 2];
+  HEAP32[i5 + (i6 * 36 | 0) + 32 >> 2] = -1;
+  HEAP32[i13 >> 2] = i6;
+  HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + -1;
+  STACKTOP = i2;
+  return;
+ }
+ i12 = i5 + (i7 * 36 | 0) + 24 | 0;
+ if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+  HEAP32[i12 >> 2] = i13;
+ } else {
+  HEAP32[i5 + (i7 * 36 | 0) + 28 >> 2] = i13;
+ }
+ HEAP32[i5 + (i13 * 36 | 0) + 20 >> 2] = i7;
+ if (!((i6 | 0) > -1)) {
+  ___assert_fail(3e3, 2944, 97, 3040);
+ }
+ if ((HEAP32[i1 + 12 >> 2] | 0) <= (i6 | 0)) {
+  ___assert_fail(3e3, 2944, 97, 3040);
+ }
+ i12 = i1 + 8 | 0;
+ if ((HEAP32[i12 >> 2] | 0) <= 0) {
+  ___assert_fail(3056, 2944, 98, 3040);
+ }
+ i13 = i1 + 16 | 0;
+ HEAP32[i4 >> 2] = HEAP32[i13 >> 2];
+ HEAP32[i5 + (i6 * 36 | 0) + 32 >> 2] = -1;
+ HEAP32[i13 >> 2] = i6;
+ HEAP32[i12 >> 2] = (HEAP32[i12 >> 2] | 0) + -1;
+ do {
+  i4 = __ZN13b2DynamicTree7BalanceEi(i1, i7) | 0;
+  i7 = HEAP32[i3 >> 2] | 0;
+  i6 = HEAP32[i7 + (i4 * 36 | 0) + 24 >> 2] | 0;
+  i5 = HEAP32[i7 + (i4 * 36 | 0) + 28 >> 2] | 0;
+  d10 = +HEAPF32[i7 + (i6 * 36 | 0) >> 2];
+  d11 = +HEAPF32[i7 + (i5 * 36 | 0) >> 2];
+  d9 = +HEAPF32[i7 + (i6 * 36 | 0) + 4 >> 2];
+  d8 = +HEAPF32[i7 + (i5 * 36 | 0) + 4 >> 2];
+  d10 = +(d10 < d11 ? d10 : d11);
+  d11 = +(d9 < d8 ? d9 : d8);
+  i13 = i7 + (i4 * 36 | 0) | 0;
+  HEAPF32[i13 >> 2] = d10;
+  HEAPF32[i13 + 4 >> 2] = d11;
+  d11 = +HEAPF32[i7 + (i6 * 36 | 0) + 8 >> 2];
+  d10 = +HEAPF32[i7 + (i5 * 36 | 0) + 8 >> 2];
+  d9 = +HEAPF32[i7 + (i6 * 36 | 0) + 12 >> 2];
+  d8 = +HEAPF32[i7 + (i5 * 36 | 0) + 12 >> 2];
+  d10 = +(d11 > d10 ? d11 : d10);
+  d11 = +(d9 > d8 ? d9 : d8);
+  i7 = i7 + (i4 * 36 | 0) + 8 | 0;
+  HEAPF32[i7 >> 2] = d10;
+  HEAPF32[i7 + 4 >> 2] = d11;
+  i7 = HEAP32[i3 >> 2] | 0;
+  i6 = HEAP32[i7 + (i6 * 36 | 0) + 32 >> 2] | 0;
+  i5 = HEAP32[i7 + (i5 * 36 | 0) + 32 >> 2] | 0;
+  HEAP32[i7 + (i4 * 36 | 0) + 32 >> 2] = ((i6 | 0) > (i5 | 0) ? i6 : i5) + 1;
+  i7 = HEAP32[i7 + (i4 * 36 | 0) + 20 >> 2] | 0;
+ } while (!((i7 | 0) == -1));
+ STACKTOP = i2;
+ return;
+}
+function __ZN9b2Simplex6Solve3Ev(i7) {
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, d4 = 0.0, d5 = 0.0, d6 = 0.0, d8 = 0.0, d9 = 0.0, d10 = 0.0, d11 = 0.0, d12 = 0.0, d13 = 0.0, d14 = 0.0, d15 = 0.0, d16 = 0.0, d17 = 0.0, d18 = 0.0, d19 = 0.0, d20 = 0.0, d21 = 0.0, i22 = 0;
+ i1 = STACKTOP;
+ i2 = i7 + 16 | 0;
+ d17 = +HEAPF32[i2 >> 2];
+ d15 = +HEAPF32[i2 + 4 >> 2];
+ i2 = i7 + 36 | 0;
+ i3 = i7 + 52 | 0;
+ d14 = +HEAPF32[i3 >> 2];
+ d16 = +HEAPF32[i3 + 4 >> 2];
+ i3 = i7 + 72 | 0;
+ i22 = i7 + 88 | 0;
+ d18 = +HEAPF32[i22 >> 2];
+ d11 = +HEAPF32[i22 + 4 >> 2];
+ d20 = d14 - d17;
+ d10 = d16 - d15;
+ d9 = d17 * d20 + d15 * d10;
+ d8 = d14 * d20 + d16 * d10;
+ d4 = d18 - d17;
+ d19 = d11 - d15;
+ d6 = d17 * d4 + d15 * d19;
+ d5 = d18 * d4 + d11 * d19;
+ d21 = d18 - d14;
+ d12 = d11 - d16;
+ d13 = d14 * d21 + d16 * d12;
+ d12 = d18 * d21 + d11 * d12;
+ d4 = d20 * d19 - d10 * d4;
+ d10 = (d14 * d11 - d16 * d18) * d4;
+ d11 = (d15 * d18 - d17 * d11) * d4;
+ d4 = (d17 * d16 - d15 * d14) * d4;
+ if (!(!(d9 >= -0.0) | !(d6 >= -0.0))) {
+  HEAPF32[i7 + 24 >> 2] = 1.0;
+  HEAP32[i7 + 108 >> 2] = 1;
+  STACKTOP = i1;
+  return;
+ }
+ if (!(!(d9 < -0.0) | !(d8 > 0.0) | !(d4 <= 0.0))) {
+  d21 = 1.0 / (d8 - d9);
+  HEAPF32[i7 + 24 >> 2] = d8 * d21;
+  HEAPF32[i7 + 60 >> 2] = -(d9 * d21);
+  HEAP32[i7 + 108 >> 2] = 2;
+  STACKTOP = i1;
+  return;
+ }
+ if (!(!(d6 < -0.0) | !(d5 > 0.0) | !(d11 <= 0.0))) {
+  d21 = 1.0 / (d5 - d6);
+  HEAPF32[i7 + 24 >> 2] = d5 * d21;
+  HEAPF32[i7 + 96 >> 2] = -(d6 * d21);
+  HEAP32[i7 + 108 >> 2] = 2;
+  i7 = i2 + 0 | 0;
+  i3 = i3 + 0 | 0;
+  i2 = i7 + 36 | 0;
+  do {
+   HEAP32[i7 >> 2] = HEAP32[i3 >> 2];
+   i7 = i7 + 4 | 0;
+   i3 = i3 + 4 | 0;
+  } while ((i7 | 0) < (i2 | 0));
+  STACKTOP = i1;
+  return;
+ }
+ if (!(!(d8 <= 0.0) | !(d13 >= -0.0))) {
+  HEAPF32[i7 + 60 >> 2] = 1.0;
+  HEAP32[i7 + 108 >> 2] = 1;
+  i7 = i7 + 0 | 0;
+  i3 = i2 + 0 | 0;
+  i2 = i7 + 36 | 0;
+  do {
+   HEAP32[i7 >> 2] = HEAP32[i3 >> 2];
+   i7 = i7 + 4 | 0;
+   i3 = i3 + 4 | 0;
+  } while ((i7 | 0) < (i2 | 0));
+  STACKTOP = i1;
+  return;
+ }
+ if (!(!(d5 <= 0.0) | !(d12 <= 0.0))) {
+  HEAPF32[i7 + 96 >> 2] = 1.0;
+  HEAP32[i7 + 108 >> 2] = 1;
+  i7 = i7 + 0 | 0;
+  i3 = i3 + 0 | 0;
+  i2 = i7 + 36 | 0;
+  do {
+   HEAP32[i7 >> 2] = HEAP32[i3 >> 2];
+   i7 = i7 + 4 | 0;
+   i3 = i3 + 4 | 0;
+  } while ((i7 | 0) < (i2 | 0));
+  STACKTOP = i1;
+  return;
+ }
+ if (!(d13 < -0.0) | !(d12 > 0.0) | !(d10 <= 0.0)) {
+  d21 = 1.0 / (d4 + (d10 + d11));
+  HEAPF32[i7 + 24 >> 2] = d10 * d21;
+  HEAPF32[i7 + 60 >> 2] = d11 * d21;
+  HEAPF32[i7 + 96 >> 2] = d4 * d21;
+  HEAP32[i7 + 108 >> 2] = 3;
+  STACKTOP = i1;
+  return;
+ } else {
+  d21 = 1.0 / (d12 - d13);
+  HEAPF32[i7 + 60 >> 2] = d12 * d21;
+  HEAPF32[i7 + 96 >> 2] = -(d13 * d21);
+  HEAP32[i7 + 108 >> 2] = 2;
+  i7 = i7 + 0 | 0;
+  i3 = i3 + 0 | 0;
+  i2 = i7 + 36 | 0;
+  do {
+   HEAP32[i7 >> 2] = HEAP32[i3 >> 2];
+   i7 = i7 + 4 | 0;
+   i3 = i3 + 4 | 0;
+  } while ((i7 | 0) < (i2 | 0));
+  STACKTOP = i1;
+  return;
+ }
+}
+function __ZN16b2ContactManager7CollideEv(i3) {
+ i3 = i3 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0;
+ i2 = STACKTOP;
+ i8 = HEAP32[i3 + 60 >> 2] | 0;
+ if ((i8 | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ i7 = i3 + 12 | 0;
+ i6 = i3 + 4 | 0;
+ i5 = i3 + 72 | 0;
+ i4 = i3 + 68 | 0;
+ L4 : while (1) {
+  i12 = HEAP32[i8 + 48 >> 2] | 0;
+  i10 = HEAP32[i8 + 52 >> 2] | 0;
+  i11 = HEAP32[i8 + 56 >> 2] | 0;
+  i9 = HEAP32[i8 + 60 >> 2] | 0;
+  i15 = HEAP32[i12 + 8 >> 2] | 0;
+  i13 = HEAP32[i10 + 8 >> 2] | 0;
+  i16 = i8 + 4 | 0;
+  do {
+   if ((HEAP32[i16 >> 2] & 8 | 0) == 0) {
+    i1 = 11;
+   } else {
+    if (!(__ZNK6b2Body13ShouldCollideEPKS_(i13, i15) | 0)) {
+     i16 = HEAP32[i8 + 12 >> 2] | 0;
+     __ZN16b2ContactManager7DestroyEP9b2Contact(i3, i8);
+     i8 = i16;
+     break;
+    }
+    i14 = HEAP32[i4 >> 2] | 0;
+    if ((i14 | 0) != 0 ? !(FUNCTION_TABLE_iiii[HEAP32[(HEAP32[i14 >> 2] | 0) + 8 >> 2] & 7](i14, i12, i10) | 0) : 0) {
+     i16 = HEAP32[i8 + 12 >> 2] | 0;
+     __ZN16b2ContactManager7DestroyEP9b2Contact(i3, i8);
+     i8 = i16;
+     break;
+    }
+    HEAP32[i16 >> 2] = HEAP32[i16 >> 2] & -9;
+    i1 = 11;
+   }
+  } while (0);
+  do {
+   if ((i1 | 0) == 11) {
+    i1 = 0;
+    if ((HEAP16[i15 + 4 >> 1] & 2) == 0) {
+     i14 = 0;
+    } else {
+     i14 = (HEAP32[i15 >> 2] | 0) != 0;
+    }
+    if ((HEAP16[i13 + 4 >> 1] & 2) == 0) {
+     i13 = 0;
+    } else {
+     i13 = (HEAP32[i13 >> 2] | 0) != 0;
+    }
+    if (!(i14 | i13)) {
+     i8 = HEAP32[i8 + 12 >> 2] | 0;
+     break;
+    }
+    i11 = HEAP32[(HEAP32[i12 + 24 >> 2] | 0) + (i11 * 28 | 0) + 24 >> 2] | 0;
+    i9 = HEAP32[(HEAP32[i10 + 24 >> 2] | 0) + (i9 * 28 | 0) + 24 >> 2] | 0;
+    if (!((i11 | 0) > -1)) {
+     i1 = 19;
+     break L4;
+    }
+    i10 = HEAP32[i7 >> 2] | 0;
+    if ((i10 | 0) <= (i11 | 0)) {
+     i1 = 19;
+     break L4;
+    }
+    i12 = HEAP32[i6 >> 2] | 0;
+    if (!((i9 | 0) > -1 & (i10 | 0) > (i9 | 0))) {
+     i1 = 21;
+     break L4;
+    }
+    if (+HEAPF32[i12 + (i9 * 36 | 0) >> 2] - +HEAPF32[i12 + (i11 * 36 | 0) + 8 >> 2] > 0.0 | +HEAPF32[i12 + (i9 * 36 | 0) + 4 >> 2] - +HEAPF32[i12 + (i11 * 36 | 0) + 12 >> 2] > 0.0 | +HEAPF32[i12 + (i11 * 36 | 0) >> 2] - +HEAPF32[i12 + (i9 * 36 | 0) + 8 >> 2] > 0.0 | +HEAPF32[i12 + (i11 * 36 | 0) + 4 >> 2] - +HEAPF32[i12 + (i9 * 36 | 0) + 12 >> 2] > 0.0) {
+     i16 = HEAP32[i8 + 12 >> 2] | 0;
+     __ZN16b2ContactManager7DestroyEP9b2Contact(i3, i8);
+     i8 = i16;
+     break;
+    } else {
+     __ZN9b2Contact6UpdateEP17b2ContactListener(i8, HEAP32[i5 >> 2] | 0);
+     i8 = HEAP32[i8 + 12 >> 2] | 0;
+     break;
+    }
+   }
+  } while (0);
+  if ((i8 | 0) == 0) {
+   i1 = 25;
+   break;
+  }
+ }
+ if ((i1 | 0) == 19) {
+  ___assert_fail(1904, 1952, 159, 2008);
+ } else if ((i1 | 0) == 21) {
+  ___assert_fail(1904, 1952, 159, 2008);
+ } else if ((i1 | 0) == 25) {
+  STACKTOP = i2;
+  return;
+ }
+}
+function __ZN16b2ContactManager7AddPairEPvS0_(i1, i5, i6) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i5 + 16 >> 2] | 0;
+ i3 = HEAP32[i6 + 16 >> 2] | 0;
+ i5 = HEAP32[i5 + 20 >> 2] | 0;
+ i6 = HEAP32[i6 + 20 >> 2] | 0;
+ i8 = HEAP32[i4 + 8 >> 2] | 0;
+ i7 = HEAP32[i3 + 8 >> 2] | 0;
+ if ((i8 | 0) == (i7 | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ i10 = HEAP32[i7 + 112 >> 2] | 0;
+ L4 : do {
+  if ((i10 | 0) != 0) {
+   while (1) {
+    if ((HEAP32[i10 >> 2] | 0) == (i8 | 0)) {
+     i9 = HEAP32[i10 + 4 >> 2] | 0;
+     i12 = HEAP32[i9 + 48 >> 2] | 0;
+     i13 = HEAP32[i9 + 52 >> 2] | 0;
+     i11 = HEAP32[i9 + 56 >> 2] | 0;
+     i9 = HEAP32[i9 + 60 >> 2] | 0;
+     if ((i12 | 0) == (i4 | 0) & (i13 | 0) == (i3 | 0) & (i11 | 0) == (i5 | 0) & (i9 | 0) == (i6 | 0)) {
+      i9 = 22;
+      break;
+     }
+     if ((i12 | 0) == (i3 | 0) & (i13 | 0) == (i4 | 0) & (i11 | 0) == (i6 | 0) & (i9 | 0) == (i5 | 0)) {
+      i9 = 22;
+      break;
+     }
+    }
+    i10 = HEAP32[i10 + 12 >> 2] | 0;
+    if ((i10 | 0) == 0) {
+     break L4;
+    }
+   }
+   if ((i9 | 0) == 22) {
+    STACKTOP = i2;
+    return;
+   }
+  }
+ } while (0);
+ if (!(__ZNK6b2Body13ShouldCollideEPKS_(i7, i8) | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ i7 = HEAP32[i1 + 68 >> 2] | 0;
+ if ((i7 | 0) != 0 ? !(FUNCTION_TABLE_iiii[HEAP32[(HEAP32[i7 >> 2] | 0) + 8 >> 2] & 7](i7, i4, i3) | 0) : 0) {
+  STACKTOP = i2;
+  return;
+ }
+ i5 = __ZN9b2Contact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator(i4, i5, i3, i6, HEAP32[i1 + 76 >> 2] | 0) | 0;
+ if ((i5 | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ i4 = HEAP32[(HEAP32[i5 + 48 >> 2] | 0) + 8 >> 2] | 0;
+ i3 = HEAP32[(HEAP32[i5 + 52 >> 2] | 0) + 8 >> 2] | 0;
+ HEAP32[i5 + 8 >> 2] = 0;
+ i7 = i1 + 60 | 0;
+ HEAP32[i5 + 12 >> 2] = HEAP32[i7 >> 2];
+ i6 = HEAP32[i7 >> 2] | 0;
+ if ((i6 | 0) != 0) {
+  HEAP32[i6 + 8 >> 2] = i5;
+ }
+ HEAP32[i7 >> 2] = i5;
+ i8 = i5 + 16 | 0;
+ HEAP32[i5 + 20 >> 2] = i5;
+ HEAP32[i8 >> 2] = i3;
+ HEAP32[i5 + 24 >> 2] = 0;
+ i6 = i4 + 112 | 0;
+ HEAP32[i5 + 28 >> 2] = HEAP32[i6 >> 2];
+ i7 = HEAP32[i6 >> 2] | 0;
+ if ((i7 | 0) != 0) {
+  HEAP32[i7 + 8 >> 2] = i8;
+ }
+ HEAP32[i6 >> 2] = i8;
+ i6 = i5 + 32 | 0;
+ HEAP32[i5 + 36 >> 2] = i5;
+ HEAP32[i6 >> 2] = i4;
+ HEAP32[i5 + 40 >> 2] = 0;
+ i7 = i3 + 112 | 0;
+ HEAP32[i5 + 44 >> 2] = HEAP32[i7 >> 2];
+ i5 = HEAP32[i7 >> 2] | 0;
+ if ((i5 | 0) != 0) {
+  HEAP32[i5 + 8 >> 2] = i6;
+ }
+ HEAP32[i7 >> 2] = i6;
+ i5 = i4 + 4 | 0;
+ i6 = HEAPU16[i5 >> 1] | 0;
+ if ((i6 & 2 | 0) == 0) {
+  HEAP16[i5 >> 1] = i6 | 2;
+  HEAPF32[i4 + 144 >> 2] = 0.0;
+ }
+ i4 = i3 + 4 | 0;
+ i5 = HEAPU16[i4 >> 1] | 0;
+ if ((i5 & 2 | 0) == 0) {
+  HEAP16[i4 >> 1] = i5 | 2;
+  HEAPF32[i3 + 144 >> 2] = 0.0;
+ }
+ i13 = i1 + 64 | 0;
+ HEAP32[i13 >> 2] = (HEAP32[i13 >> 2] | 0) + 1;
+ STACKTOP = i2;
+ return;
+}
+function __ZN12b2BroadPhase11UpdatePairsI16b2ContactManagerEEvPT_(i5, i2) {
+ i5 = i5 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i6 = i3;
+ i1 = i5 + 52 | 0;
+ HEAP32[i1 >> 2] = 0;
+ i4 = i5 + 40 | 0;
+ i12 = HEAP32[i4 >> 2] | 0;
+ do {
+  if ((i12 | 0) > 0) {
+   i9 = i5 + 32 | 0;
+   i11 = i5 + 56 | 0;
+   i8 = i5 + 12 | 0;
+   i10 = i5 + 4 | 0;
+   i13 = 0;
+   while (1) {
+    i14 = HEAP32[(HEAP32[i9 >> 2] | 0) + (i13 << 2) >> 2] | 0;
+    HEAP32[i11 >> 2] = i14;
+    if (!((i14 | 0) == -1)) {
+     if (!((i14 | 0) > -1)) {
+      i8 = 6;
+      break;
+     }
+     if ((HEAP32[i8 >> 2] | 0) <= (i14 | 0)) {
+      i8 = 6;
+      break;
+     }
+     __ZNK13b2DynamicTree5QueryI12b2BroadPhaseEEvPT_RK6b2AABB(i5, i5, (HEAP32[i10 >> 2] | 0) + (i14 * 36 | 0) | 0);
+     i12 = HEAP32[i4 >> 2] | 0;
+    }
+    i13 = i13 + 1 | 0;
+    if ((i13 | 0) >= (i12 | 0)) {
+     i8 = 9;
+     break;
+    }
+   }
+   if ((i8 | 0) == 6) {
+    ___assert_fail(1904, 1952, 159, 2008);
+   } else if ((i8 | 0) == 9) {
+    i7 = HEAP32[i1 >> 2] | 0;
+    break;
+   }
+  } else {
+   i7 = 0;
+  }
+ } while (0);
+ HEAP32[i4 >> 2] = 0;
+ i4 = i5 + 44 | 0;
+ i14 = HEAP32[i4 >> 2] | 0;
+ HEAP32[i6 >> 2] = 3;
+ __ZNSt3__16__sortIRPFbRK6b2PairS3_EPS1_EEvT0_S8_T_(i14, i14 + (i7 * 12 | 0) | 0, i6);
+ if ((HEAP32[i1 >> 2] | 0) <= 0) {
+  STACKTOP = i3;
+  return;
+ }
+ i6 = i5 + 12 | 0;
+ i7 = i5 + 4 | 0;
+ i9 = 0;
+ L18 : while (1) {
+  i8 = HEAP32[i4 >> 2] | 0;
+  i5 = i8 + (i9 * 12 | 0) | 0;
+  i10 = HEAP32[i5 >> 2] | 0;
+  if (!((i10 | 0) > -1)) {
+   i8 = 14;
+   break;
+  }
+  i12 = HEAP32[i6 >> 2] | 0;
+  if ((i12 | 0) <= (i10 | 0)) {
+   i8 = 14;
+   break;
+  }
+  i11 = HEAP32[i7 >> 2] | 0;
+  i8 = i8 + (i9 * 12 | 0) + 4 | 0;
+  i13 = HEAP32[i8 >> 2] | 0;
+  if (!((i13 | 0) > -1 & (i12 | 0) > (i13 | 0))) {
+   i8 = 16;
+   break;
+  }
+  __ZN16b2ContactManager7AddPairEPvS0_(i2, HEAP32[i11 + (i10 * 36 | 0) + 16 >> 2] | 0, HEAP32[i11 + (i13 * 36 | 0) + 16 >> 2] | 0);
+  i10 = HEAP32[i1 >> 2] | 0;
+  while (1) {
+   i9 = i9 + 1 | 0;
+   if ((i9 | 0) >= (i10 | 0)) {
+    i8 = 21;
+    break L18;
+   }
+   i11 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i11 + (i9 * 12 | 0) >> 2] | 0) != (HEAP32[i5 >> 2] | 0)) {
+    continue L18;
+   }
+   if ((HEAP32[i11 + (i9 * 12 | 0) + 4 >> 2] | 0) != (HEAP32[i8 >> 2] | 0)) {
+    continue L18;
+   }
+  }
+ }
+ if ((i8 | 0) == 14) {
+  ___assert_fail(1904, 1952, 153, 1992);
+ } else if ((i8 | 0) == 16) {
+  ___assert_fail(1904, 1952, 153, 1992);
+ } else if ((i8 | 0) == 21) {
+  STACKTOP = i3;
+  return;
+ }
+}
+function __ZNK13b2DynamicTree5QueryI12b2BroadPhaseEEvPT_RK6b2AABB(i9, i4, i7) {
+ i9 = i9 | 0;
+ i4 = i4 | 0;
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i6 = 0, i8 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 1040 | 0;
+ i3 = i2;
+ i1 = i3 + 4 | 0;
+ HEAP32[i3 >> 2] = i1;
+ i5 = i3 + 1028 | 0;
+ HEAP32[i5 >> 2] = 0;
+ i6 = i3 + 1032 | 0;
+ HEAP32[i6 >> 2] = 256;
+ i14 = HEAP32[i3 >> 2] | 0;
+ HEAP32[i14 + (HEAP32[i5 >> 2] << 2) >> 2] = HEAP32[i9 >> 2];
+ i15 = HEAP32[i5 >> 2] | 0;
+ i16 = i15 + 1 | 0;
+ HEAP32[i5 >> 2] = i16;
+ L1 : do {
+  if ((i15 | 0) > -1) {
+   i9 = i9 + 4 | 0;
+   i11 = i7 + 4 | 0;
+   i12 = i7 + 8 | 0;
+   i10 = i7 + 12 | 0;
+   while (1) {
+    i16 = i16 + -1 | 0;
+    HEAP32[i5 >> 2] = i16;
+    i13 = HEAP32[i14 + (i16 << 2) >> 2] | 0;
+    do {
+     if (!((i13 | 0) == -1) ? (i8 = HEAP32[i9 >> 2] | 0, !(+HEAPF32[i7 >> 2] - +HEAPF32[i8 + (i13 * 36 | 0) + 8 >> 2] > 0.0 | +HEAPF32[i11 >> 2] - +HEAPF32[i8 + (i13 * 36 | 0) + 12 >> 2] > 0.0 | +HEAPF32[i8 + (i13 * 36 | 0) >> 2] - +HEAPF32[i12 >> 2] > 0.0 | +HEAPF32[i8 + (i13 * 36 | 0) + 4 >> 2] - +HEAPF32[i10 >> 2] > 0.0)) : 0) {
+      i15 = i8 + (i13 * 36 | 0) + 24 | 0;
+      if ((HEAP32[i15 >> 2] | 0) == -1) {
+       if (!(__ZN12b2BroadPhase13QueryCallbackEi(i4, i13) | 0)) {
+        break L1;
+       }
+       i16 = HEAP32[i5 >> 2] | 0;
+       break;
+      }
+      if ((i16 | 0) == (HEAP32[i6 >> 2] | 0) ? (HEAP32[i6 >> 2] = i16 << 1, i16 = __Z7b2Alloci(i16 << 3) | 0, HEAP32[i3 >> 2] = i16, _memcpy(i16 | 0, i14 | 0, HEAP32[i5 >> 2] << 2 | 0) | 0, (i14 | 0) != (i1 | 0)) : 0) {
+       __Z6b2FreePv(i14);
+      }
+      i14 = HEAP32[i3 >> 2] | 0;
+      HEAP32[i14 + (HEAP32[i5 >> 2] << 2) >> 2] = HEAP32[i15 >> 2];
+      i15 = (HEAP32[i5 >> 2] | 0) + 1 | 0;
+      HEAP32[i5 >> 2] = i15;
+      i13 = i8 + (i13 * 36 | 0) + 28 | 0;
+      if ((i15 | 0) == (HEAP32[i6 >> 2] | 0) ? (HEAP32[i6 >> 2] = i15 << 1, i16 = __Z7b2Alloci(i15 << 3) | 0, HEAP32[i3 >> 2] = i16, _memcpy(i16 | 0, i14 | 0, HEAP32[i5 >> 2] << 2 | 0) | 0, (i14 | 0) != (i1 | 0)) : 0) {
+       __Z6b2FreePv(i14);
+      }
+      HEAP32[(HEAP32[i3 >> 2] | 0) + (HEAP32[i5 >> 2] << 2) >> 2] = HEAP32[i13 >> 2];
+      i16 = (HEAP32[i5 >> 2] | 0) + 1 | 0;
+      HEAP32[i5 >> 2] = i16;
+     }
+    } while (0);
+    if ((i16 | 0) <= 0) {
+     break L1;
+    }
+    i14 = HEAP32[i3 >> 2] | 0;
+   }
+  }
+ } while (0);
+ i4 = HEAP32[i3 >> 2] | 0;
+ if ((i4 | 0) == (i1 | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ __Z6b2FreePv(i4);
+ HEAP32[i3 >> 2] = 0;
+ STACKTOP = i2;
+ return;
+}
+function __ZN15b2ContactSolver9WarmStartEv(i4) {
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, d10 = 0.0, d11 = 0.0, d12 = 0.0, i13 = 0, d14 = 0.0, d15 = 0.0, d16 = 0.0, d17 = 0.0, d18 = 0.0, d19 = 0.0, d20 = 0.0, d21 = 0.0, i22 = 0, d23 = 0.0, i24 = 0, d25 = 0.0, d26 = 0.0, d27 = 0.0;
+ i1 = STACKTOP;
+ i2 = i4 + 48 | 0;
+ if ((HEAP32[i2 >> 2] | 0) <= 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i3 = i4 + 40 | 0;
+ i5 = i4 + 28 | 0;
+ i22 = HEAP32[i5 >> 2] | 0;
+ i8 = 0;
+ do {
+  i9 = HEAP32[i3 >> 2] | 0;
+  i7 = HEAP32[i9 + (i8 * 152 | 0) + 112 >> 2] | 0;
+  i6 = HEAP32[i9 + (i8 * 152 | 0) + 116 >> 2] | 0;
+  d10 = +HEAPF32[i9 + (i8 * 152 | 0) + 120 >> 2];
+  d14 = +HEAPF32[i9 + (i8 * 152 | 0) + 128 >> 2];
+  d12 = +HEAPF32[i9 + (i8 * 152 | 0) + 124 >> 2];
+  d11 = +HEAPF32[i9 + (i8 * 152 | 0) + 132 >> 2];
+  i13 = HEAP32[i9 + (i8 * 152 | 0) + 144 >> 2] | 0;
+  i4 = i22 + (i7 * 12 | 0) | 0;
+  i24 = i4;
+  d17 = +HEAPF32[i24 >> 2];
+  d19 = +HEAPF32[i24 + 4 >> 2];
+  d20 = +HEAPF32[i22 + (i7 * 12 | 0) + 8 >> 2];
+  i24 = i22 + (i6 * 12 | 0) | 0;
+  d21 = +HEAPF32[i24 >> 2];
+  d23 = +HEAPF32[i24 + 4 >> 2];
+  d18 = +HEAPF32[i22 + (i6 * 12 | 0) + 8 >> 2];
+  i22 = i9 + (i8 * 152 | 0) + 72 | 0;
+  d15 = +HEAPF32[i22 >> 2];
+  d16 = +HEAPF32[i22 + 4 >> 2];
+  if ((i13 | 0) > 0) {
+   i22 = 0;
+   do {
+    d27 = +HEAPF32[i9 + (i8 * 152 | 0) + (i22 * 36 | 0) + 16 >> 2];
+    d25 = +HEAPF32[i9 + (i8 * 152 | 0) + (i22 * 36 | 0) + 20 >> 2];
+    d26 = d15 * d27 + d16 * d25;
+    d25 = d16 * d27 - d15 * d25;
+    d20 = d20 - d14 * (+HEAPF32[i9 + (i8 * 152 | 0) + (i22 * 36 | 0) >> 2] * d25 - +HEAPF32[i9 + (i8 * 152 | 0) + (i22 * 36 | 0) + 4 >> 2] * d26);
+    d17 = d17 - d10 * d26;
+    d19 = d19 - d10 * d25;
+    d18 = d18 + d11 * (d25 * +HEAPF32[i9 + (i8 * 152 | 0) + (i22 * 36 | 0) + 8 >> 2] - d26 * +HEAPF32[i9 + (i8 * 152 | 0) + (i22 * 36 | 0) + 12 >> 2]);
+    d21 = d21 + d12 * d26;
+    d23 = d23 + d12 * d25;
+    i22 = i22 + 1 | 0;
+   } while ((i22 | 0) != (i13 | 0));
+  }
+  d27 = +d17;
+  d26 = +d19;
+  i22 = i4;
+  HEAPF32[i22 >> 2] = d27;
+  HEAPF32[i22 + 4 >> 2] = d26;
+  i22 = HEAP32[i5 >> 2] | 0;
+  HEAPF32[i22 + (i7 * 12 | 0) + 8 >> 2] = d20;
+  d26 = +d21;
+  d27 = +d23;
+  i22 = i22 + (i6 * 12 | 0) | 0;
+  HEAPF32[i22 >> 2] = d26;
+  HEAPF32[i22 + 4 >> 2] = d27;
+  i22 = HEAP32[i5 >> 2] | 0;
+  HEAPF32[i22 + (i6 * 12 | 0) + 8 >> 2] = d18;
+  i8 = i8 + 1 | 0;
+ } while ((i8 | 0) < (HEAP32[i2 >> 2] | 0));
+ STACKTOP = i1;
+ return;
+}
+function __ZNK14b2PolygonShape7RayCastEP15b2RayCastOutputRK14b2RayCastInputRK11b2Transformi(i1, i5, i8, i7, i4) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i8 = i8 | 0;
+ i7 = i7 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, d3 = 0.0, i6 = 0, d9 = 0.0, d10 = 0.0, d11 = 0.0, d12 = 0.0, d13 = 0.0, i14 = 0, i15 = 0, i16 = 0, d17 = 0.0, d18 = 0.0, d19 = 0.0, d20 = 0.0;
+ i4 = STACKTOP;
+ d10 = +HEAPF32[i7 >> 2];
+ d9 = +HEAPF32[i8 >> 2] - d10;
+ d18 = +HEAPF32[i7 + 4 >> 2];
+ d11 = +HEAPF32[i8 + 4 >> 2] - d18;
+ i6 = i7 + 12 | 0;
+ d17 = +HEAPF32[i6 >> 2];
+ i7 = i7 + 8 | 0;
+ d19 = +HEAPF32[i7 >> 2];
+ d12 = d9 * d17 + d11 * d19;
+ d9 = d17 * d11 - d9 * d19;
+ d10 = +HEAPF32[i8 + 8 >> 2] - d10;
+ d18 = +HEAPF32[i8 + 12 >> 2] - d18;
+ d11 = d17 * d10 + d19 * d18 - d12;
+ d10 = d17 * d18 - d19 * d10 - d9;
+ i8 = i8 + 16 | 0;
+ i14 = HEAP32[i1 + 148 >> 2] | 0;
+ do {
+  if ((i14 | 0) > 0) {
+   i16 = 0;
+   i15 = -1;
+   d13 = 0.0;
+   d17 = +HEAPF32[i8 >> 2];
+   L3 : while (1) {
+    d20 = +HEAPF32[i1 + (i16 << 3) + 84 >> 2];
+    d19 = +HEAPF32[i1 + (i16 << 3) + 88 >> 2];
+    d18 = (+HEAPF32[i1 + (i16 << 3) + 20 >> 2] - d12) * d20 + (+HEAPF32[i1 + (i16 << 3) + 24 >> 2] - d9) * d19;
+    d19 = d11 * d20 + d10 * d19;
+    do {
+     if (d19 == 0.0) {
+      if (d18 < 0.0) {
+       i1 = 0;
+       i14 = 18;
+       break L3;
+      }
+     } else {
+      if (d19 < 0.0 ? d18 < d13 * d19 : 0) {
+       i15 = i16;
+       d13 = d18 / d19;
+       break;
+      }
+      if (d19 > 0.0 ? d18 < d17 * d19 : 0) {
+       d17 = d18 / d19;
+      }
+     }
+    } while (0);
+    i16 = i16 + 1 | 0;
+    if (d17 < d13) {
+     i1 = 0;
+     i14 = 18;
+     break;
+    }
+    if ((i16 | 0) >= (i14 | 0)) {
+     i14 = 13;
+     break;
+    }
+   }
+   if ((i14 | 0) == 13) {
+    if (d13 >= 0.0) {
+     i2 = i15;
+     d3 = d13;
+     break;
+    }
+    ___assert_fail(376, 328, 249, 424);
+   } else if ((i14 | 0) == 18) {
+    STACKTOP = i4;
+    return i1 | 0;
+   }
+  } else {
+   i2 = -1;
+   d3 = 0.0;
+  }
+ } while (0);
+ if (!(d3 <= +HEAPF32[i8 >> 2])) {
+  ___assert_fail(376, 328, 249, 424);
+ }
+ if (!((i2 | 0) > -1)) {
+  i16 = 0;
+  STACKTOP = i4;
+  return i16 | 0;
+ }
+ HEAPF32[i5 + 8 >> 2] = d3;
+ d18 = +HEAPF32[i6 >> 2];
+ d13 = +HEAPF32[i1 + (i2 << 3) + 84 >> 2];
+ d17 = +HEAPF32[i7 >> 2];
+ d20 = +HEAPF32[i1 + (i2 << 3) + 88 >> 2];
+ d19 = +(d18 * d13 - d17 * d20);
+ d20 = +(d13 * d17 + d18 * d20);
+ i16 = i5;
+ HEAPF32[i16 >> 2] = d19;
+ HEAPF32[i16 + 4 >> 2] = d20;
+ i16 = 1;
+ STACKTOP = i4;
+ return i16 | 0;
+}
+function __ZN7b2World4StepEfii(i1, d9, i11, i12) {
+ i1 = i1 | 0;
+ d9 = +d9;
+ i11 = i11 | 0;
+ i12 = i12 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i10 = 0, i13 = 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i3 = i4 + 27 | 0;
+ i5 = i4;
+ i8 = i4 + 26 | 0;
+ i10 = i4 + 25 | 0;
+ i7 = i4 + 24 | 0;
+ __ZN7b2TimerC2Ev(i3);
+ i2 = i1 + 102868 | 0;
+ i13 = HEAP32[i2 >> 2] | 0;
+ if ((i13 & 1 | 0) != 0) {
+  __ZN16b2ContactManager15FindNewContactsEv(i1 + 102872 | 0);
+  i13 = HEAP32[i2 >> 2] & -2;
+  HEAP32[i2 >> 2] = i13;
+ }
+ HEAP32[i2 >> 2] = i13 | 2;
+ HEAPF32[i5 >> 2] = d9;
+ HEAP32[i5 + 12 >> 2] = i11;
+ HEAP32[i5 + 16 >> 2] = i12;
+ if (d9 > 0.0) {
+  HEAPF32[i5 + 4 >> 2] = 1.0 / d9;
+ } else {
+  HEAPF32[i5 + 4 >> 2] = 0.0;
+ }
+ i11 = i1 + 102988 | 0;
+ HEAPF32[i5 + 8 >> 2] = +HEAPF32[i11 >> 2] * d9;
+ HEAP8[i5 + 20 | 0] = HEAP8[i1 + 102992 | 0] | 0;
+ __ZN7b2TimerC2Ev(i8);
+ __ZN16b2ContactManager7CollideEv(i1 + 102872 | 0);
+ HEAPF32[i1 + 103e3 >> 2] = +__ZNK7b2Timer15GetMillisecondsEv(i8);
+ if ((HEAP8[i1 + 102995 | 0] | 0) != 0 ? +HEAPF32[i5 >> 2] > 0.0 : 0) {
+  __ZN7b2TimerC2Ev(i10);
+  __ZN7b2World5SolveERK10b2TimeStep(i1, i5);
+  HEAPF32[i1 + 103004 >> 2] = +__ZNK7b2Timer15GetMillisecondsEv(i10);
+ }
+ if ((HEAP8[i1 + 102993 | 0] | 0) != 0) {
+  d9 = +HEAPF32[i5 >> 2];
+  if (d9 > 0.0) {
+   __ZN7b2TimerC2Ev(i7);
+   __ZN7b2World8SolveTOIERK10b2TimeStep(i1, i5);
+   HEAPF32[i1 + 103024 >> 2] = +__ZNK7b2Timer15GetMillisecondsEv(i7);
+   i6 = 12;
+  }
+ } else {
+  i6 = 12;
+ }
+ if ((i6 | 0) == 12) {
+  d9 = +HEAPF32[i5 >> 2];
+ }
+ if (d9 > 0.0) {
+  HEAPF32[i11 >> 2] = +HEAPF32[i5 + 4 >> 2];
+ }
+ i5 = HEAP32[i2 >> 2] | 0;
+ if ((i5 & 4 | 0) == 0) {
+  i13 = i5 & -3;
+  HEAP32[i2 >> 2] = i13;
+  d9 = +__ZNK7b2Timer15GetMillisecondsEv(i3);
+  i13 = i1 + 102996 | 0;
+  HEAPF32[i13 >> 2] = d9;
+  STACKTOP = i4;
+  return;
+ }
+ i6 = HEAP32[i1 + 102952 >> 2] | 0;
+ if ((i6 | 0) == 0) {
+  i13 = i5 & -3;
+  HEAP32[i2 >> 2] = i13;
+  d9 = +__ZNK7b2Timer15GetMillisecondsEv(i3);
+  i13 = i1 + 102996 | 0;
+  HEAPF32[i13 >> 2] = d9;
+  STACKTOP = i4;
+  return;
+ }
+ do {
+  HEAPF32[i6 + 76 >> 2] = 0.0;
+  HEAPF32[i6 + 80 >> 2] = 0.0;
+  HEAPF32[i6 + 84 >> 2] = 0.0;
+  i6 = HEAP32[i6 + 96 >> 2] | 0;
+ } while ((i6 | 0) != 0);
+ i13 = i5 & -3;
+ HEAP32[i2 >> 2] = i13;
+ d9 = +__ZNK7b2Timer15GetMillisecondsEv(i3);
+ i13 = i1 + 102996 | 0;
+ HEAPF32[i13 >> 2] = d9;
+ STACKTOP = i4;
+ return;
+}
+function __ZL19b2FindMaxSeparationPiPK14b2PolygonShapeRK11b2TransformS2_S5_(i1, i5, i6, i3, i4) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i7 = 0, d8 = 0.0, d9 = 0.0, d10 = 0.0, d11 = 0.0, i12 = 0, i13 = 0, i14 = 0, d15 = 0.0, d16 = 0.0, d17 = 0.0, d18 = 0.0, d19 = 0.0;
+ i2 = STACKTOP;
+ i7 = HEAP32[i5 + 148 >> 2] | 0;
+ d17 = +HEAPF32[i4 + 12 >> 2];
+ d19 = +HEAPF32[i3 + 12 >> 2];
+ d18 = +HEAPF32[i4 + 8 >> 2];
+ d16 = +HEAPF32[i3 + 16 >> 2];
+ d15 = +HEAPF32[i6 + 12 >> 2];
+ d10 = +HEAPF32[i5 + 12 >> 2];
+ d8 = +HEAPF32[i6 + 8 >> 2];
+ d9 = +HEAPF32[i5 + 16 >> 2];
+ d11 = +HEAPF32[i4 >> 2] + (d17 * d19 - d18 * d16) - (+HEAPF32[i6 >> 2] + (d15 * d10 - d8 * d9));
+ d9 = d19 * d18 + d17 * d16 + +HEAPF32[i4 + 4 >> 2] - (d10 * d8 + d15 * d9 + +HEAPF32[i6 + 4 >> 2]);
+ d10 = d15 * d11 + d8 * d9;
+ d8 = d15 * d9 - d11 * d8;
+ if ((i7 | 0) > 0) {
+  i14 = 0;
+  i13 = 0;
+  d9 = -3.4028234663852886e+38;
+  while (1) {
+   d11 = d10 * +HEAPF32[i5 + (i13 << 3) + 84 >> 2] + d8 * +HEAPF32[i5 + (i13 << 3) + 88 >> 2];
+   i12 = d11 > d9;
+   i14 = i12 ? i13 : i14;
+   i13 = i13 + 1 | 0;
+   if ((i13 | 0) == (i7 | 0)) {
+    break;
+   } else {
+    d9 = i12 ? d11 : d9;
+   }
+  }
+ } else {
+  i14 = 0;
+ }
+ d9 = +__ZL16b2EdgeSeparationPK14b2PolygonShapeRK11b2TransformiS1_S4_(i5, i6, i14, i3, i4);
+ i12 = ((i14 | 0) > 0 ? i14 : i7) + -1 | 0;
+ d8 = +__ZL16b2EdgeSeparationPK14b2PolygonShapeRK11b2TransformiS1_S4_(i5, i6, i12, i3, i4);
+ i13 = i14 + 1 | 0;
+ i13 = (i13 | 0) < (i7 | 0) ? i13 : 0;
+ d10 = +__ZL16b2EdgeSeparationPK14b2PolygonShapeRK11b2TransformiS1_S4_(i5, i6, i13, i3, i4);
+ if (d8 > d9 & d8 > d10) {
+  while (1) {
+   i13 = ((i12 | 0) > 0 ? i12 : i7) + -1 | 0;
+   d9 = +__ZL16b2EdgeSeparationPK14b2PolygonShapeRK11b2TransformiS1_S4_(i5, i6, i13, i3, i4);
+   if (d9 > d8) {
+    i12 = i13;
+    d8 = d9;
+   } else {
+    break;
+   }
+  }
+  HEAP32[i1 >> 2] = i12;
+  STACKTOP = i2;
+  return +d8;
+ }
+ if (d10 > d9) {
+  i12 = i13;
+  d8 = d10;
+ } else {
+  d19 = d9;
+  HEAP32[i1 >> 2] = i14;
+  STACKTOP = i2;
+  return +d19;
+ }
+ while (1) {
+  i13 = i12 + 1 | 0;
+  i13 = (i13 | 0) < (i7 | 0) ? i13 : 0;
+  d9 = +__ZL16b2EdgeSeparationPK14b2PolygonShapeRK11b2TransformiS1_S4_(i5, i6, i13, i3, i4);
+  if (d9 > d8) {
+   i12 = i13;
+   d8 = d9;
+  } else {
+   break;
+  }
+ }
+ HEAP32[i1 >> 2] = i12;
+ STACKTOP = i2;
+ return +d8;
+}
+function __ZN9b2Fixture11SynchronizeEP12b2BroadPhaseRK11b2TransformS4_(i10, i8, i7, i2) {
+ i10 = i10 | 0;
+ i8 = i8 | 0;
+ i7 = i7 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i9 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, d23 = 0.0, d24 = 0.0, d25 = 0.0, d26 = 0.0, i27 = 0;
+ i9 = STACKTOP;
+ STACKTOP = STACKTOP + 48 | 0;
+ i5 = i9 + 24 | 0;
+ i6 = i9 + 8 | 0;
+ i3 = i9;
+ i4 = i10 + 28 | 0;
+ if ((HEAP32[i4 >> 2] | 0) <= 0) {
+  STACKTOP = i9;
+  return;
+ }
+ i1 = i10 + 24 | 0;
+ i18 = i10 + 12 | 0;
+ i19 = i5 + 4 | 0;
+ i20 = i6 + 4 | 0;
+ i13 = i5 + 8 | 0;
+ i14 = i6 + 8 | 0;
+ i15 = i5 + 12 | 0;
+ i16 = i6 + 12 | 0;
+ i11 = i2 + 4 | 0;
+ i22 = i7 + 4 | 0;
+ i12 = i3 + 4 | 0;
+ i21 = 0;
+ do {
+  i10 = HEAP32[i1 >> 2] | 0;
+  i27 = HEAP32[i18 >> 2] | 0;
+  i17 = i10 + (i21 * 28 | 0) + 20 | 0;
+  FUNCTION_TABLE_viiii[HEAP32[(HEAP32[i27 >> 2] | 0) + 24 >> 2] & 15](i27, i5, i7, HEAP32[i17 >> 2] | 0);
+  i27 = HEAP32[i18 >> 2] | 0;
+  FUNCTION_TABLE_viiii[HEAP32[(HEAP32[i27 >> 2] | 0) + 24 >> 2] & 15](i27, i6, i2, HEAP32[i17 >> 2] | 0);
+  i17 = i10 + (i21 * 28 | 0) | 0;
+  d25 = +HEAPF32[i5 >> 2];
+  d26 = +HEAPF32[i6 >> 2];
+  d24 = +HEAPF32[i19 >> 2];
+  d23 = +HEAPF32[i20 >> 2];
+  d25 = +(d25 < d26 ? d25 : d26);
+  d26 = +(d24 < d23 ? d24 : d23);
+  i27 = i17;
+  HEAPF32[i27 >> 2] = d25;
+  HEAPF32[i27 + 4 >> 2] = d26;
+  d25 = +HEAPF32[i13 >> 2];
+  d26 = +HEAPF32[i14 >> 2];
+  d23 = +HEAPF32[i15 >> 2];
+  d24 = +HEAPF32[i16 >> 2];
+  d25 = +(d25 > d26 ? d25 : d26);
+  d26 = +(d23 > d24 ? d23 : d24);
+  i27 = i10 + (i21 * 28 | 0) + 8 | 0;
+  HEAPF32[i27 >> 2] = d25;
+  HEAPF32[i27 + 4 >> 2] = d26;
+  d26 = +HEAPF32[i11 >> 2] - +HEAPF32[i22 >> 2];
+  HEAPF32[i3 >> 2] = +HEAPF32[i2 >> 2] - +HEAPF32[i7 >> 2];
+  HEAPF32[i12 >> 2] = d26;
+  __ZN12b2BroadPhase9MoveProxyEiRK6b2AABBRK6b2Vec2(i8, HEAP32[i10 + (i21 * 28 | 0) + 24 >> 2] | 0, i17, i3);
+  i21 = i21 + 1 | 0;
+ } while ((i21 | 0) < (HEAP32[i4 >> 2] | 0));
+ STACKTOP = i9;
+ return;
+}
+function __ZN12b2EPCollider24ComputePolygonSeparationEv(i2, i9) {
+ i2 = i2 | 0;
+ i9 = i9 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, d6 = 0.0, d7 = 0.0, i8 = 0, d10 = 0.0, d11 = 0.0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, d16 = 0.0, d17 = 0.0, d18 = 0.0, d19 = 0.0, i20 = 0, d21 = 0.0, d22 = 0.0, d23 = 0.0, d24 = 0.0, d25 = 0.0, d26 = 0.0;
+ i15 = STACKTOP;
+ HEAP32[i2 >> 2] = 0;
+ i3 = i2 + 4 | 0;
+ HEAP32[i3 >> 2] = -1;
+ i4 = i2 + 8 | 0;
+ HEAPF32[i4 >> 2] = -3.4028234663852886e+38;
+ d7 = +HEAPF32[i9 + 216 >> 2];
+ d6 = +HEAPF32[i9 + 212 >> 2];
+ i5 = HEAP32[i9 + 128 >> 2] | 0;
+ if ((i5 | 0) <= 0) {
+  STACKTOP = i15;
+  return;
+ }
+ d17 = +HEAPF32[i9 + 164 >> 2];
+ d18 = +HEAPF32[i9 + 168 >> 2];
+ d11 = +HEAPF32[i9 + 172 >> 2];
+ d10 = +HEAPF32[i9 + 176 >> 2];
+ d16 = +HEAPF32[i9 + 244 >> 2];
+ i12 = i9 + 228 | 0;
+ i13 = i9 + 232 | 0;
+ i14 = i9 + 236 | 0;
+ i1 = i9 + 240 | 0;
+ d19 = -3.4028234663852886e+38;
+ i20 = 0;
+ while (1) {
+  d23 = +HEAPF32[i9 + (i20 << 3) + 64 >> 2];
+  d21 = -d23;
+  d22 = -+HEAPF32[i9 + (i20 << 3) + 68 >> 2];
+  d26 = +HEAPF32[i9 + (i20 << 3) >> 2];
+  d25 = +HEAPF32[i9 + (i20 << 3) + 4 >> 2];
+  d24 = (d26 - d17) * d21 + (d25 - d18) * d22;
+  d25 = (d26 - d11) * d21 + (d25 - d10) * d22;
+  d24 = d24 < d25 ? d24 : d25;
+  if (d24 > d16) {
+   break;
+  }
+  if (!(d7 * d23 + d6 * d22 >= 0.0)) {
+   if (!((d21 - +HEAPF32[i12 >> 2]) * d6 + (d22 - +HEAPF32[i13 >> 2]) * d7 < -.03490658849477768) & d24 > d19) {
+    i8 = 8;
+   }
+  } else {
+   if (!((d21 - +HEAPF32[i14 >> 2]) * d6 + (d22 - +HEAPF32[i1 >> 2]) * d7 < -.03490658849477768) & d24 > d19) {
+    i8 = 8;
+   }
+  }
+  if ((i8 | 0) == 8) {
+   i8 = 0;
+   HEAP32[i2 >> 2] = 2;
+   HEAP32[i3 >> 2] = i20;
+   HEAPF32[i4 >> 2] = d24;
+   d19 = d24;
+  }
+  i20 = i20 + 1 | 0;
+  if ((i20 | 0) >= (i5 | 0)) {
+   i8 = 10;
+   break;
+  }
+ }
+ if ((i8 | 0) == 10) {
+  STACKTOP = i15;
+  return;
+ }
+ HEAP32[i2 >> 2] = 2;
+ HEAP32[i3 >> 2] = i20;
+ HEAPF32[i4 >> 2] = d24;
+ STACKTOP = i15;
+ return;
+}
+function __ZNK11b2EdgeShape7RayCastEP15b2RayCastOutputRK14b2RayCastInputRK11b2Transformi(i17, i1, i2, i18, i3) {
+ i17 = i17 | 0;
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i18 = i18 | 0;
+ i3 = i3 | 0;
+ var d4 = 0.0, d5 = 0.0, d6 = 0.0, d7 = 0.0, d8 = 0.0, d9 = 0.0, d10 = 0.0, d11 = 0.0, d12 = 0.0, d13 = 0.0, d14 = 0.0, d15 = 0.0, d16 = 0.0;
+ i3 = STACKTOP;
+ d6 = +HEAPF32[i18 >> 2];
+ d7 = +HEAPF32[i2 >> 2] - d6;
+ d9 = +HEAPF32[i18 + 4 >> 2];
+ d4 = +HEAPF32[i2 + 4 >> 2] - d9;
+ d11 = +HEAPF32[i18 + 12 >> 2];
+ d5 = +HEAPF32[i18 + 8 >> 2];
+ d8 = d7 * d11 + d4 * d5;
+ d7 = d11 * d4 - d7 * d5;
+ d6 = +HEAPF32[i2 + 8 >> 2] - d6;
+ d9 = +HEAPF32[i2 + 12 >> 2] - d9;
+ d4 = d11 * d6 + d5 * d9 - d8;
+ d6 = d11 * d9 - d5 * d6 - d7;
+ i18 = i17 + 12 | 0;
+ d5 = +HEAPF32[i18 >> 2];
+ d9 = +HEAPF32[i18 + 4 >> 2];
+ i18 = i17 + 20 | 0;
+ d11 = +HEAPF32[i18 >> 2];
+ d11 = d11 - d5;
+ d12 = +HEAPF32[i18 + 4 >> 2] - d9;
+ d15 = -d11;
+ d10 = d11 * d11 + d12 * d12;
+ d13 = +Math_sqrt(+d10);
+ if (d13 < 1.1920928955078125e-7) {
+  d13 = d12;
+ } else {
+  d16 = 1.0 / d13;
+  d13 = d12 * d16;
+  d15 = d16 * d15;
+ }
+ d14 = (d9 - d7) * d15 + (d5 - d8) * d13;
+ d16 = d6 * d15 + d4 * d13;
+ if (d16 == 0.0) {
+  i18 = 0;
+  STACKTOP = i3;
+  return i18 | 0;
+ }
+ d16 = d14 / d16;
+ if (d16 < 0.0) {
+  i18 = 0;
+  STACKTOP = i3;
+  return i18 | 0;
+ }
+ if (+HEAPF32[i2 + 16 >> 2] < d16 | d10 == 0.0) {
+  i18 = 0;
+  STACKTOP = i3;
+  return i18 | 0;
+ }
+ d12 = (d11 * (d8 + d4 * d16 - d5) + d12 * (d7 + d6 * d16 - d9)) / d10;
+ if (d12 < 0.0 | d12 > 1.0) {
+  i18 = 0;
+  STACKTOP = i3;
+  return i18 | 0;
+ }
+ HEAPF32[i1 + 8 >> 2] = d16;
+ if (d14 > 0.0) {
+  d14 = +-d13;
+  d16 = +-d15;
+  i18 = i1;
+  HEAPF32[i18 >> 2] = d14;
+  HEAPF32[i18 + 4 >> 2] = d16;
+  i18 = 1;
+  STACKTOP = i3;
+  return i18 | 0;
+ } else {
+  d14 = +d13;
+  d16 = +d15;
+  i18 = i1;
+  HEAPF32[i18 >> 2] = d14;
+  HEAPF32[i18 + 4 >> 2] = d16;
+  i18 = 1;
+  STACKTOP = i3;
+  return i18 | 0;
+ }
+ return 0;
+}
+function ___dynamic_cast(i7, i6, i11, i5) {
+ i7 = i7 | 0;
+ i6 = i6 | 0;
+ i11 = i11 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i8 = 0, i9 = 0, i10 = 0, i12 = 0, i13 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i2 = i1;
+ i3 = HEAP32[i7 >> 2] | 0;
+ i4 = i7 + (HEAP32[i3 + -8 >> 2] | 0) | 0;
+ i3 = HEAP32[i3 + -4 >> 2] | 0;
+ HEAP32[i2 >> 2] = i11;
+ HEAP32[i2 + 4 >> 2] = i7;
+ HEAP32[i2 + 8 >> 2] = i6;
+ HEAP32[i2 + 12 >> 2] = i5;
+ i9 = i2 + 16 | 0;
+ i10 = i2 + 20 | 0;
+ i6 = i2 + 24 | 0;
+ i8 = i2 + 28 | 0;
+ i5 = i2 + 32 | 0;
+ i7 = i2 + 40 | 0;
+ i12 = (i3 | 0) == (i11 | 0);
+ i13 = i9 + 0 | 0;
+ i11 = i13 + 36 | 0;
+ do {
+  HEAP32[i13 >> 2] = 0;
+  i13 = i13 + 4 | 0;
+ } while ((i13 | 0) < (i11 | 0));
+ HEAP16[i9 + 36 >> 1] = 0;
+ HEAP8[i9 + 38 | 0] = 0;
+ if (i12) {
+  HEAP32[i2 + 48 >> 2] = 1;
+  FUNCTION_TABLE_viiiiii[HEAP32[(HEAP32[i3 >> 2] | 0) + 20 >> 2] & 3](i3, i2, i4, i4, 1, 0);
+  i13 = (HEAP32[i6 >> 2] | 0) == 1 ? i4 : 0;
+  STACKTOP = i1;
+  return i13 | 0;
+ }
+ FUNCTION_TABLE_viiiii[HEAP32[(HEAP32[i3 >> 2] | 0) + 24 >> 2] & 3](i3, i2, i4, 1, 0);
+ i2 = HEAP32[i2 + 36 >> 2] | 0;
+ if ((i2 | 0) == 0) {
+  if ((HEAP32[i7 >> 2] | 0) != 1) {
+   i13 = 0;
+   STACKTOP = i1;
+   return i13 | 0;
+  }
+  if ((HEAP32[i8 >> 2] | 0) != 1) {
+   i13 = 0;
+   STACKTOP = i1;
+   return i13 | 0;
+  }
+  i13 = (HEAP32[i5 >> 2] | 0) == 1 ? HEAP32[i10 >> 2] | 0 : 0;
+  STACKTOP = i1;
+  return i13 | 0;
+ } else if ((i2 | 0) == 1) {
+  if ((HEAP32[i6 >> 2] | 0) != 1) {
+   if ((HEAP32[i7 >> 2] | 0) != 0) {
+    i13 = 0;
+    STACKTOP = i1;
+    return i13 | 0;
+   }
+   if ((HEAP32[i8 >> 2] | 0) != 1) {
+    i13 = 0;
+    STACKTOP = i1;
+    return i13 | 0;
+   }
+   if ((HEAP32[i5 >> 2] | 0) != 1) {
+    i13 = 0;
+    STACKTOP = i1;
+    return i13 | 0;
+   }
+  }
+  i13 = HEAP32[i9 >> 2] | 0;
+  STACKTOP = i1;
+  return i13 | 0;
+ } else {
+  i13 = 0;
+  STACKTOP = i1;
+  return i13 | 0;
+ }
+ return 0;
+}
+function __ZNK14b2PolygonShape11ComputeMassEP10b2MassDataf(i4, i1, d2) {
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ d2 = +d2;
+ var i3 = 0, i5 = 0, d6 = 0.0, d7 = 0.0, d8 = 0.0, d9 = 0.0, d10 = 0.0, d11 = 0.0, i12 = 0, d13 = 0.0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, d18 = 0.0, i19 = 0, d20 = 0.0, d21 = 0.0, d22 = 0.0, d23 = 0.0;
+ i3 = STACKTOP;
+ i5 = HEAP32[i4 + 148 >> 2] | 0;
+ if ((i5 | 0) > 2) {
+  d7 = 0.0;
+  d6 = 0.0;
+  i12 = 0;
+ } else {
+  ___assert_fail(432, 328, 306, 456);
+ }
+ do {
+  d6 = d6 + +HEAPF32[i4 + (i12 << 3) + 20 >> 2];
+  d7 = d7 + +HEAPF32[i4 + (i12 << 3) + 24 >> 2];
+  i12 = i12 + 1 | 0;
+ } while ((i12 | 0) < (i5 | 0));
+ d11 = 1.0 / +(i5 | 0);
+ d6 = d6 * d11;
+ d11 = d7 * d11;
+ i16 = i4 + 20 | 0;
+ i19 = i4 + 24 | 0;
+ d9 = 0.0;
+ d10 = 0.0;
+ d7 = 0.0;
+ d8 = 0.0;
+ i17 = 0;
+ do {
+  d18 = +HEAPF32[i4 + (i17 << 3) + 20 >> 2] - d6;
+  d13 = +HEAPF32[i4 + (i17 << 3) + 24 >> 2] - d11;
+  i17 = i17 + 1 | 0;
+  i12 = (i17 | 0) < (i5 | 0);
+  if (i12) {
+   i14 = i4 + (i17 << 3) + 20 | 0;
+   i15 = i4 + (i17 << 3) + 24 | 0;
+  } else {
+   i14 = i16;
+   i15 = i19;
+  }
+  d21 = +HEAPF32[i14 >> 2] - d6;
+  d20 = +HEAPF32[i15 >> 2] - d11;
+  d22 = d18 * d20 - d13 * d21;
+  d23 = d22 * .5;
+  d8 = d8 + d23;
+  d23 = d23 * .3333333432674408;
+  d9 = d9 + (d18 + d21) * d23;
+  d10 = d10 + (d13 + d20) * d23;
+  d7 = d7 + d22 * .0833333358168602 * (d21 * d21 + (d18 * d18 + d18 * d21) + (d20 * d20 + (d13 * d13 + d13 * d20)));
+ } while (i12);
+ d13 = d8 * d2;
+ HEAPF32[i1 >> 2] = d13;
+ if (d8 > 1.1920928955078125e-7) {
+  d23 = 1.0 / d8;
+  d22 = d9 * d23;
+  d23 = d10 * d23;
+  d20 = d6 + d22;
+  d21 = d11 + d23;
+  d11 = +d20;
+  d18 = +d21;
+  i19 = i1 + 4 | 0;
+  HEAPF32[i19 >> 2] = d11;
+  HEAPF32[i19 + 4 >> 2] = d18;
+  HEAPF32[i1 + 12 >> 2] = d7 * d2 + d13 * (d20 * d20 + d21 * d21 - (d22 * d22 + d23 * d23));
+  STACKTOP = i3;
+  return;
+ } else {
+  ___assert_fail(472, 328, 352, 456);
+ }
+}
+function __ZN16b2ContactManager7DestroyEP9b2Contact(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i3 = STACKTOP;
+ i5 = HEAP32[(HEAP32[i2 + 48 >> 2] | 0) + 8 >> 2] | 0;
+ i4 = HEAP32[(HEAP32[i2 + 52 >> 2] | 0) + 8 >> 2] | 0;
+ i6 = HEAP32[i1 + 72 >> 2] | 0;
+ if ((i6 | 0) != 0 ? (HEAP32[i2 + 4 >> 2] & 2 | 0) != 0 : 0) {
+  FUNCTION_TABLE_vii[HEAP32[(HEAP32[i6 >> 2] | 0) + 12 >> 2] & 15](i6, i2);
+ }
+ i7 = i2 + 8 | 0;
+ i8 = HEAP32[i7 >> 2] | 0;
+ i6 = i2 + 12 | 0;
+ if ((i8 | 0) != 0) {
+  HEAP32[i8 + 12 >> 2] = HEAP32[i6 >> 2];
+ }
+ i8 = HEAP32[i6 >> 2] | 0;
+ if ((i8 | 0) != 0) {
+  HEAP32[i8 + 8 >> 2] = HEAP32[i7 >> 2];
+ }
+ i7 = i1 + 60 | 0;
+ if ((HEAP32[i7 >> 2] | 0) == (i2 | 0)) {
+  HEAP32[i7 >> 2] = HEAP32[i6 >> 2];
+ }
+ i7 = i2 + 24 | 0;
+ i8 = HEAP32[i7 >> 2] | 0;
+ i6 = i2 + 28 | 0;
+ if ((i8 | 0) != 0) {
+  HEAP32[i8 + 12 >> 2] = HEAP32[i6 >> 2];
+ }
+ i8 = HEAP32[i6 >> 2] | 0;
+ if ((i8 | 0) != 0) {
+  HEAP32[i8 + 8 >> 2] = HEAP32[i7 >> 2];
+ }
+ i5 = i5 + 112 | 0;
+ if ((i2 + 16 | 0) == (HEAP32[i5 >> 2] | 0)) {
+  HEAP32[i5 >> 2] = HEAP32[i6 >> 2];
+ }
+ i6 = i2 + 40 | 0;
+ i7 = HEAP32[i6 >> 2] | 0;
+ i5 = i2 + 44 | 0;
+ if ((i7 | 0) != 0) {
+  HEAP32[i7 + 12 >> 2] = HEAP32[i5 >> 2];
+ }
+ i7 = HEAP32[i5 >> 2] | 0;
+ if ((i7 | 0) != 0) {
+  HEAP32[i7 + 8 >> 2] = HEAP32[i6 >> 2];
+ }
+ i4 = i4 + 112 | 0;
+ if ((i2 + 32 | 0) != (HEAP32[i4 >> 2] | 0)) {
+  i8 = i1 + 76 | 0;
+  i8 = HEAP32[i8 >> 2] | 0;
+  __ZN9b2Contact7DestroyEPS_P16b2BlockAllocator(i2, i8);
+  i8 = i1 + 64 | 0;
+  i7 = HEAP32[i8 >> 2] | 0;
+  i7 = i7 + -1 | 0;
+  HEAP32[i8 >> 2] = i7;
+  STACKTOP = i3;
+  return;
+ }
+ HEAP32[i4 >> 2] = HEAP32[i5 >> 2];
+ i8 = i1 + 76 | 0;
+ i8 = HEAP32[i8 >> 2] | 0;
+ __ZN9b2Contact7DestroyEPS_P16b2BlockAllocator(i2, i8);
+ i8 = i1 + 64 | 0;
+ i7 = HEAP32[i8 >> 2] | 0;
+ i7 = i7 + -1 | 0;
+ HEAP32[i8 >> 2] = i7;
+ STACKTOP = i3;
+ return;
+}
+function __ZNK10__cxxabiv120__si_class_type_info16search_below_dstEPNS_19__dynamic_cast_infoEPKvib(i6, i3, i4, i8, i7) {
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i8 = i8 | 0;
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i5 = 0, i9 = 0, i10 = 0;
+ i1 = STACKTOP;
+ if ((i6 | 0) == (HEAP32[i3 + 8 >> 2] | 0)) {
+  if ((HEAP32[i3 + 4 >> 2] | 0) != (i4 | 0)) {
+   STACKTOP = i1;
+   return;
+  }
+  i2 = i3 + 28 | 0;
+  if ((HEAP32[i2 >> 2] | 0) == 1) {
+   STACKTOP = i1;
+   return;
+  }
+  HEAP32[i2 >> 2] = i8;
+  STACKTOP = i1;
+  return;
+ }
+ if ((i6 | 0) != (HEAP32[i3 >> 2] | 0)) {
+  i9 = HEAP32[i6 + 8 >> 2] | 0;
+  FUNCTION_TABLE_viiiii[HEAP32[(HEAP32[i9 >> 2] | 0) + 24 >> 2] & 3](i9, i3, i4, i8, i7);
+  STACKTOP = i1;
+  return;
+ }
+ if ((HEAP32[i3 + 16 >> 2] | 0) != (i4 | 0) ? (i5 = i3 + 20 | 0, (HEAP32[i5 >> 2] | 0) != (i4 | 0)) : 0) {
+  HEAP32[i3 + 32 >> 2] = i8;
+  i8 = i3 + 44 | 0;
+  if ((HEAP32[i8 >> 2] | 0) == 4) {
+   STACKTOP = i1;
+   return;
+  }
+  i9 = i3 + 52 | 0;
+  HEAP8[i9] = 0;
+  i10 = i3 + 53 | 0;
+  HEAP8[i10] = 0;
+  i6 = HEAP32[i6 + 8 >> 2] | 0;
+  FUNCTION_TABLE_viiiiii[HEAP32[(HEAP32[i6 >> 2] | 0) + 20 >> 2] & 3](i6, i3, i4, i4, 1, i7);
+  if ((HEAP8[i10] | 0) != 0) {
+   if ((HEAP8[i9] | 0) == 0) {
+    i6 = 1;
+    i2 = 13;
+   }
+  } else {
+   i6 = 0;
+   i2 = 13;
+  }
+  do {
+   if ((i2 | 0) == 13) {
+    HEAP32[i5 >> 2] = i4;
+    i10 = i3 + 40 | 0;
+    HEAP32[i10 >> 2] = (HEAP32[i10 >> 2] | 0) + 1;
+    if ((HEAP32[i3 + 36 >> 2] | 0) == 1 ? (HEAP32[i3 + 24 >> 2] | 0) == 2 : 0) {
+     HEAP8[i3 + 54 | 0] = 1;
+     if (i6) {
+      break;
+     }
+    } else {
+     i2 = 16;
+    }
+    if ((i2 | 0) == 16 ? i6 : 0) {
+     break;
+    }
+    HEAP32[i8 >> 2] = 4;
+    STACKTOP = i1;
+    return;
+   }
+  } while (0);
+  HEAP32[i8 >> 2] = 3;
+  STACKTOP = i1;
+  return;
+ }
+ if ((i8 | 0) != 1) {
+  STACKTOP = i1;
+  return;
+ }
+ HEAP32[i3 + 32 >> 2] = 1;
+ STACKTOP = i1;
+ return;
+}
+function __ZN16b2BlockAllocator8AllocateEi(i4, i2) {
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i1 = STACKTOP;
+ if ((i2 | 0) == 0) {
+  i9 = 0;
+  STACKTOP = i1;
+  return i9 | 0;
+ }
+ if ((i2 | 0) <= 0) {
+  ___assert_fail(1376, 1312, 104, 1392);
+ }
+ if ((i2 | 0) > 640) {
+  i9 = __Z7b2Alloci(i2) | 0;
+  STACKTOP = i1;
+  return i9 | 0;
+ }
+ i9 = HEAP8[632 + i2 | 0] | 0;
+ i5 = i9 & 255;
+ if (!((i9 & 255) < 14)) {
+  ___assert_fail(1408, 1312, 112, 1392);
+ }
+ i2 = i4 + (i5 << 2) + 12 | 0;
+ i3 = HEAP32[i2 >> 2] | 0;
+ if ((i3 | 0) != 0) {
+  HEAP32[i2 >> 2] = HEAP32[i3 >> 2];
+  i9 = i3;
+  STACKTOP = i1;
+  return i9 | 0;
+ }
+ i3 = i4 + 4 | 0;
+ i6 = HEAP32[i3 >> 2] | 0;
+ i7 = i4 + 8 | 0;
+ if ((i6 | 0) == (HEAP32[i7 >> 2] | 0)) {
+  i9 = HEAP32[i4 >> 2] | 0;
+  i6 = i6 + 128 | 0;
+  HEAP32[i7 >> 2] = i6;
+  i6 = __Z7b2Alloci(i6 << 3) | 0;
+  HEAP32[i4 >> 2] = i6;
+  _memcpy(i6 | 0, i9 | 0, HEAP32[i3 >> 2] << 3 | 0) | 0;
+  _memset((HEAP32[i4 >> 2] | 0) + (HEAP32[i3 >> 2] << 3) | 0, 0, 1024) | 0;
+  __Z6b2FreePv(i9);
+  i6 = HEAP32[i3 >> 2] | 0;
+ }
+ i9 = HEAP32[i4 >> 2] | 0;
+ i7 = __Z7b2Alloci(16384) | 0;
+ i4 = i9 + (i6 << 3) + 4 | 0;
+ HEAP32[i4 >> 2] = i7;
+ i5 = HEAP32[576 + (i5 << 2) >> 2] | 0;
+ HEAP32[i9 + (i6 << 3) >> 2] = i5;
+ i6 = 16384 / (i5 | 0) | 0;
+ if ((Math_imul(i6, i5) | 0) >= 16385) {
+  ___assert_fail(1448, 1312, 140, 1392);
+ }
+ i6 = i6 + -1 | 0;
+ if ((i6 | 0) > 0) {
+  i9 = 0;
+  while (1) {
+   i8 = i9 + 1 | 0;
+   HEAP32[i7 + (Math_imul(i9, i5) | 0) >> 2] = i7 + (Math_imul(i8, i5) | 0);
+   i7 = HEAP32[i4 >> 2] | 0;
+   if ((i8 | 0) == (i6 | 0)) {
+    break;
+   } else {
+    i9 = i8;
+   }
+  }
+ }
+ HEAP32[i7 + (Math_imul(i6, i5) | 0) >> 2] = 0;
+ HEAP32[i2 >> 2] = HEAP32[HEAP32[i4 >> 2] >> 2];
+ HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + 1;
+ i9 = HEAP32[i4 >> 2] | 0;
+ STACKTOP = i1;
+ return i9 | 0;
+}
+function __ZN9b2Contact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator(i4, i5, i1, i3, i6) {
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ var i2 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i2 = STACKTOP;
+ if ((HEAP8[4200] | 0) == 0) {
+  HEAP32[1002] = 3;
+  HEAP32[4012 >> 2] = 3;
+  HEAP8[4016 | 0] = 1;
+  HEAP32[4104 >> 2] = 4;
+  HEAP32[4108 >> 2] = 4;
+  HEAP8[4112 | 0] = 1;
+  HEAP32[4032 >> 2] = 4;
+  HEAP32[4036 >> 2] = 4;
+  HEAP8[4040 | 0] = 0;
+  HEAP32[4128 >> 2] = 5;
+  HEAP32[4132 >> 2] = 5;
+  HEAP8[4136 | 0] = 1;
+  HEAP32[4056 >> 2] = 6;
+  HEAP32[4060 >> 2] = 6;
+  HEAP8[4064 | 0] = 1;
+  HEAP32[4020 >> 2] = 6;
+  HEAP32[4024 >> 2] = 6;
+  HEAP8[4028 | 0] = 0;
+  HEAP32[4080 >> 2] = 7;
+  HEAP32[4084 >> 2] = 7;
+  HEAP8[4088 | 0] = 1;
+  HEAP32[4116 >> 2] = 7;
+  HEAP32[4120 >> 2] = 7;
+  HEAP8[4124 | 0] = 0;
+  HEAP32[4152 >> 2] = 8;
+  HEAP32[4156 >> 2] = 8;
+  HEAP8[4160 | 0] = 1;
+  HEAP32[4044 >> 2] = 8;
+  HEAP32[4048 >> 2] = 8;
+  HEAP8[4052 | 0] = 0;
+  HEAP32[4176 >> 2] = 9;
+  HEAP32[4180 >> 2] = 9;
+  HEAP8[4184 | 0] = 1;
+  HEAP32[4140 >> 2] = 9;
+  HEAP32[4144 >> 2] = 9;
+  HEAP8[4148 | 0] = 0;
+  HEAP8[4200] = 1;
+ }
+ i7 = HEAP32[(HEAP32[i4 + 12 >> 2] | 0) + 4 >> 2] | 0;
+ i8 = HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 4 >> 2] | 0;
+ if (!(i7 >>> 0 < 4)) {
+  ___assert_fail(4208, 4256, 80, 4344);
+ }
+ if (!(i8 >>> 0 < 4)) {
+  ___assert_fail(4296, 4256, 81, 4344);
+ }
+ i9 = HEAP32[4008 + (i7 * 48 | 0) + (i8 * 12 | 0) >> 2] | 0;
+ if ((i9 | 0) == 0) {
+  i9 = 0;
+  STACKTOP = i2;
+  return i9 | 0;
+ }
+ if ((HEAP8[4008 + (i7 * 48 | 0) + (i8 * 12 | 0) + 8 | 0] | 0) == 0) {
+  i9 = FUNCTION_TABLE_iiiiii[i9 & 15](i1, i3, i4, i5, i6) | 0;
+  STACKTOP = i2;
+  return i9 | 0;
+ } else {
+  i9 = FUNCTION_TABLE_iiiiii[i9 & 15](i4, i5, i1, i3, i6) | 0;
+  STACKTOP = i2;
+  return i9 | 0;
+ }
+ return 0;
+}
+function __ZN13b2DynamicTree9MoveProxyEiRK6b2AABBRK6b2Vec2(i1, i2, i13, i9) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i13 = i13 | 0;
+ i9 = i9 | 0;
+ var i3 = 0, i4 = 0, d5 = 0.0, d6 = 0.0, d7 = 0.0, d8 = 0.0, d10 = 0.0, d11 = 0.0, i12 = 0;
+ i4 = STACKTOP;
+ if (!((i2 | 0) > -1)) {
+  ___assert_fail(3072, 2944, 135, 3152);
+ }
+ if ((HEAP32[i1 + 12 >> 2] | 0) <= (i2 | 0)) {
+  ___assert_fail(3072, 2944, 135, 3152);
+ }
+ i3 = i1 + 4 | 0;
+ i12 = HEAP32[i3 >> 2] | 0;
+ if (!((HEAP32[i12 + (i2 * 36 | 0) + 24 >> 2] | 0) == -1)) {
+  ___assert_fail(3120, 2944, 137, 3152);
+ }
+ if (((+HEAPF32[i12 + (i2 * 36 | 0) >> 2] <= +HEAPF32[i13 >> 2] ? +HEAPF32[i12 + (i2 * 36 | 0) + 4 >> 2] <= +HEAPF32[i13 + 4 >> 2] : 0) ? +HEAPF32[i13 + 8 >> 2] <= +HEAPF32[i12 + (i2 * 36 | 0) + 8 >> 2] : 0) ? +HEAPF32[i13 + 12 >> 2] <= +HEAPF32[i12 + (i2 * 36 | 0) + 12 >> 2] : 0) {
+  i13 = 0;
+  STACKTOP = i4;
+  return i13 | 0;
+ }
+ __ZN13b2DynamicTree10RemoveLeafEi(i1, i2);
+ i12 = i13;
+ d6 = +HEAPF32[i12 >> 2];
+ d8 = +HEAPF32[i12 + 4 >> 2];
+ i13 = i13 + 8 | 0;
+ d10 = +HEAPF32[i13 >> 2];
+ d6 = d6 + -.10000000149011612;
+ d8 = d8 + -.10000000149011612;
+ d10 = d10 + .10000000149011612;
+ d5 = +HEAPF32[i13 + 4 >> 2] + .10000000149011612;
+ d11 = +HEAPF32[i9 >> 2] * 2.0;
+ d7 = +HEAPF32[i9 + 4 >> 2] * 2.0;
+ if (d11 < 0.0) {
+  d6 = d6 + d11;
+ } else {
+  d10 = d11 + d10;
+ }
+ if (d7 < 0.0) {
+  d8 = d8 + d7;
+ } else {
+  d5 = d7 + d5;
+ }
+ i13 = HEAP32[i3 >> 2] | 0;
+ d7 = +d6;
+ d11 = +d8;
+ i12 = i13 + (i2 * 36 | 0) | 0;
+ HEAPF32[i12 >> 2] = d7;
+ HEAPF32[i12 + 4 >> 2] = d11;
+ d10 = +d10;
+ d11 = +d5;
+ i13 = i13 + (i2 * 36 | 0) + 8 | 0;
+ HEAPF32[i13 >> 2] = d10;
+ HEAPF32[i13 + 4 >> 2] = d11;
+ __ZN13b2DynamicTree10InsertLeafEi(i1, i2);
+ i13 = 1;
+ STACKTOP = i4;
+ return i13 | 0;
+}
+function __ZNK9b2Simplex16GetWitnessPointsEP6b2Vec2S1_(i1, i4, i5) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, d6 = 0.0, d7 = 0.0, d8 = 0.0, i9 = 0, i10 = 0, d11 = 0.0;
+ i2 = STACKTOP;
+ i3 = HEAP32[i1 + 108 >> 2] | 0;
+ if ((i3 | 0) == 2) {
+  i9 = i1 + 24 | 0;
+  d7 = +HEAPF32[i9 >> 2];
+  i3 = i1 + 60 | 0;
+  d8 = +HEAPF32[i3 >> 2];
+  d6 = +(d7 * +HEAPF32[i1 >> 2] + d8 * +HEAPF32[i1 + 36 >> 2]);
+  d8 = +(d7 * +HEAPF32[i1 + 4 >> 2] + d8 * +HEAPF32[i1 + 40 >> 2]);
+  HEAPF32[i4 >> 2] = d6;
+  HEAPF32[i4 + 4 >> 2] = d8;
+  d8 = +HEAPF32[i9 >> 2];
+  d6 = +HEAPF32[i3 >> 2];
+  d7 = +(d8 * +HEAPF32[i1 + 8 >> 2] + d6 * +HEAPF32[i1 + 44 >> 2]);
+  d6 = +(d8 * +HEAPF32[i1 + 12 >> 2] + d6 * +HEAPF32[i1 + 48 >> 2]);
+  HEAPF32[i5 >> 2] = d7;
+  HEAPF32[i5 + 4 >> 2] = d6;
+  STACKTOP = i2;
+  return;
+ } else if ((i3 | 0) == 1) {
+  i10 = i1;
+  i9 = HEAP32[i10 + 4 >> 2] | 0;
+  i3 = i4;
+  HEAP32[i3 >> 2] = HEAP32[i10 >> 2];
+  HEAP32[i3 + 4 >> 2] = i9;
+  i3 = i1 + 8 | 0;
+  i4 = HEAP32[i3 + 4 >> 2] | 0;
+  i9 = i5;
+  HEAP32[i9 >> 2] = HEAP32[i3 >> 2];
+  HEAP32[i9 + 4 >> 2] = i4;
+  STACKTOP = i2;
+  return;
+ } else if ((i3 | 0) == 0) {
+  ___assert_fail(2712, 2672, 217, 2752);
+ } else if ((i3 | 0) == 3) {
+  d11 = +HEAPF32[i1 + 24 >> 2];
+  d6 = +HEAPF32[i1 + 60 >> 2];
+  d8 = +HEAPF32[i1 + 96 >> 2];
+  d7 = +(d11 * +HEAPF32[i1 >> 2] + d6 * +HEAPF32[i1 + 36 >> 2] + d8 * +HEAPF32[i1 + 72 >> 2]);
+  d8 = +(d11 * +HEAPF32[i1 + 4 >> 2] + d6 * +HEAPF32[i1 + 40 >> 2] + d8 * +HEAPF32[i1 + 76 >> 2]);
+  i10 = i4;
+  HEAPF32[i10 >> 2] = d7;
+  HEAPF32[i10 + 4 >> 2] = d8;
+  i10 = i5;
+  HEAPF32[i10 >> 2] = d7;
+  HEAPF32[i10 + 4 >> 2] = d8;
+  STACKTOP = i2;
+  return;
+ } else {
+  ___assert_fail(2712, 2672, 236, 2752);
+ }
+}
+function __ZNK12b2ChainShape12GetChildEdgeEP11b2EdgeShapei(i4, i3, i1) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i2 = STACKTOP;
+ if (!((i1 | 0) > -1)) {
+  ___assert_fail(6832, 6792, 89, 6872);
+ }
+ i5 = i4 + 16 | 0;
+ if (((HEAP32[i5 >> 2] | 0) + -1 | 0) <= (i1 | 0)) {
+  ___assert_fail(6832, 6792, 89, 6872);
+ }
+ HEAP32[i3 + 4 >> 2] = 1;
+ HEAPF32[i3 + 8 >> 2] = +HEAPF32[i4 + 8 >> 2];
+ i6 = i4 + 12 | 0;
+ i7 = (HEAP32[i6 >> 2] | 0) + (i1 << 3) | 0;
+ i8 = HEAP32[i7 + 4 >> 2] | 0;
+ i9 = i3 + 12 | 0;
+ HEAP32[i9 >> 2] = HEAP32[i7 >> 2];
+ HEAP32[i9 + 4 >> 2] = i8;
+ i9 = (HEAP32[i6 >> 2] | 0) + (i1 + 1 << 3) | 0;
+ i8 = HEAP32[i9 + 4 >> 2] | 0;
+ i7 = i3 + 20 | 0;
+ HEAP32[i7 >> 2] = HEAP32[i9 >> 2];
+ HEAP32[i7 + 4 >> 2] = i8;
+ i7 = i3 + 28 | 0;
+ if ((i1 | 0) > 0) {
+  i10 = (HEAP32[i6 >> 2] | 0) + (i1 + -1 << 3) | 0;
+  i8 = HEAP32[i10 + 4 >> 2] | 0;
+  i9 = i7;
+  HEAP32[i9 >> 2] = HEAP32[i10 >> 2];
+  HEAP32[i9 + 4 >> 2] = i8;
+  HEAP8[i3 + 44 | 0] = 1;
+ } else {
+  i8 = i4 + 20 | 0;
+  i9 = HEAP32[i8 + 4 >> 2] | 0;
+  i10 = i7;
+  HEAP32[i10 >> 2] = HEAP32[i8 >> 2];
+  HEAP32[i10 + 4 >> 2] = i9;
+  HEAP8[i3 + 44 | 0] = HEAP8[i4 + 36 | 0] | 0;
+ }
+ i7 = i3 + 36 | 0;
+ if (((HEAP32[i5 >> 2] | 0) + -2 | 0) > (i1 | 0)) {
+  i8 = (HEAP32[i6 >> 2] | 0) + (i1 + 2 << 3) | 0;
+  i9 = HEAP32[i8 + 4 >> 2] | 0;
+  i10 = i7;
+  HEAP32[i10 >> 2] = HEAP32[i8 >> 2];
+  HEAP32[i10 + 4 >> 2] = i9;
+  HEAP8[i3 + 45 | 0] = 1;
+  STACKTOP = i2;
+  return;
+ } else {
+  i8 = i4 + 28 | 0;
+  i9 = HEAP32[i8 + 4 >> 2] | 0;
+  i10 = i7;
+  HEAP32[i10 >> 2] = HEAP32[i8 >> 2];
+  HEAP32[i10 + 4 >> 2] = i9;
+  HEAP8[i3 + 45 | 0] = HEAP8[i4 + 37 | 0] | 0;
+  STACKTOP = i2;
+  return;
+ }
+}
+function __ZN15b2DistanceProxy3SetEPK7b2Shapei(i3, i1, i5) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i1 + 4 >> 2] | 0;
+ if ((i4 | 0) == 1) {
+  HEAP32[i3 + 16 >> 2] = i1 + 12;
+  HEAP32[i3 + 20 >> 2] = 2;
+  HEAPF32[i3 + 24 >> 2] = +HEAPF32[i1 + 8 >> 2];
+  STACKTOP = i2;
+  return;
+ } else if ((i4 | 0) == 3) {
+  if (!((i5 | 0) > -1)) {
+   ___assert_fail(2632, 2672, 53, 2704);
+  }
+  i4 = i1 + 16 | 0;
+  if ((HEAP32[i4 >> 2] | 0) <= (i5 | 0)) {
+   ___assert_fail(2632, 2672, 53, 2704);
+  }
+  i7 = i1 + 12 | 0;
+  i9 = (HEAP32[i7 >> 2] | 0) + (i5 << 3) | 0;
+  i8 = HEAP32[i9 + 4 >> 2] | 0;
+  i6 = i3;
+  HEAP32[i6 >> 2] = HEAP32[i9 >> 2];
+  HEAP32[i6 + 4 >> 2] = i8;
+  i6 = i5 + 1 | 0;
+  i5 = i3 + 8 | 0;
+  i7 = HEAP32[i7 >> 2] | 0;
+  if ((i6 | 0) < (HEAP32[i4 >> 2] | 0)) {
+   i7 = i7 + (i6 << 3) | 0;
+   i8 = HEAP32[i7 + 4 >> 2] | 0;
+   i9 = i5;
+   HEAP32[i9 >> 2] = HEAP32[i7 >> 2];
+   HEAP32[i9 + 4 >> 2] = i8;
+  } else {
+   i8 = HEAP32[i7 + 4 >> 2] | 0;
+   i9 = i5;
+   HEAP32[i9 >> 2] = HEAP32[i7 >> 2];
+   HEAP32[i9 + 4 >> 2] = i8;
+  }
+  HEAP32[i3 + 16 >> 2] = i3;
+  HEAP32[i3 + 20 >> 2] = 2;
+  HEAPF32[i3 + 24 >> 2] = +HEAPF32[i1 + 8 >> 2];
+  STACKTOP = i2;
+  return;
+ } else if ((i4 | 0) == 2) {
+  HEAP32[i3 + 16 >> 2] = i1 + 20;
+  HEAP32[i3 + 20 >> 2] = HEAP32[i1 + 148 >> 2];
+  HEAPF32[i3 + 24 >> 2] = +HEAPF32[i1 + 8 >> 2];
+  STACKTOP = i2;
+  return;
+ } else if ((i4 | 0) == 0) {
+  HEAP32[i3 + 16 >> 2] = i1 + 12;
+  HEAP32[i3 + 20 >> 2] = 1;
+  HEAPF32[i3 + 24 >> 2] = +HEAPF32[i1 + 8 >> 2];
+  STACKTOP = i2;
+  return;
+ } else {
+  ___assert_fail(2712, 2672, 81, 2704);
+ }
+}
+function __ZL16b2EdgeSeparationPK14b2PolygonShapeRK11b2TransformiS1_S4_(i2, i7, i4, i5, i6) {
+ i2 = i2 | 0;
+ i7 = i7 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ var d1 = 0.0, d3 = 0.0, d8 = 0.0, d9 = 0.0, d10 = 0.0, d11 = 0.0, i12 = 0, i13 = 0, d14 = 0.0, d15 = 0.0, d16 = 0.0, d17 = 0.0, i18 = 0, i19 = 0, i20 = 0;
+ i12 = STACKTOP;
+ i13 = HEAP32[i5 + 148 >> 2] | 0;
+ if (!((i4 | 0) > -1)) {
+  ___assert_fail(5640, 5688, 32, 5752);
+ }
+ if ((HEAP32[i2 + 148 >> 2] | 0) <= (i4 | 0)) {
+  ___assert_fail(5640, 5688, 32, 5752);
+ }
+ d11 = +HEAPF32[i7 + 12 >> 2];
+ d9 = +HEAPF32[i2 + (i4 << 3) + 84 >> 2];
+ d1 = +HEAPF32[i7 + 8 >> 2];
+ d3 = +HEAPF32[i2 + (i4 << 3) + 88 >> 2];
+ d8 = d11 * d9 - d1 * d3;
+ d3 = d9 * d1 + d11 * d3;
+ d9 = +HEAPF32[i6 + 12 >> 2];
+ d10 = +HEAPF32[i6 + 8 >> 2];
+ d16 = d9 * d8 + d10 * d3;
+ d14 = d9 * d3 - d8 * d10;
+ if ((i13 | 0) > 0) {
+  i19 = 0;
+  i20 = 0;
+  d15 = 3.4028234663852886e+38;
+  while (1) {
+   d17 = d16 * +HEAPF32[i5 + (i19 << 3) + 20 >> 2] + d14 * +HEAPF32[i5 + (i19 << 3) + 24 >> 2];
+   i18 = d17 < d15;
+   i20 = i18 ? i19 : i20;
+   i19 = i19 + 1 | 0;
+   if ((i19 | 0) == (i13 | 0)) {
+    break;
+   } else {
+    d15 = i18 ? d17 : d15;
+   }
+  }
+ } else {
+  i20 = 0;
+ }
+ d16 = +HEAPF32[i2 + (i4 << 3) + 20 >> 2];
+ d17 = +HEAPF32[i2 + (i4 << 3) + 24 >> 2];
+ d14 = +HEAPF32[i5 + (i20 << 3) + 20 >> 2];
+ d15 = +HEAPF32[i5 + (i20 << 3) + 24 >> 2];
+ STACKTOP = i12;
+ return +(d8 * (+HEAPF32[i6 >> 2] + (d9 * d14 - d10 * d15) - (+HEAPF32[i7 >> 2] + (d11 * d16 - d1 * d17))) + d3 * (d14 * d10 + d9 * d15 + +HEAPF32[i6 + 4 >> 2] - (d16 * d1 + d11 * d17 + +HEAPF32[i7 + 4 >> 2])));
+}
+function __Z4iterv() {
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, d5 = 0.0, d6 = 0.0, d7 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 48 | 0;
+ i2 = i1;
+ i3 = i1 + 32 | 0;
+ i4 = HEAP32[16] | 0;
+ if ((i4 | 0) >= (HEAP32[4] | 0)) {
+  HEAP32[16] = i4 + 1;
+  __Z7measurePl(i3, HEAP32[8] | 0);
+  d7 = +HEAPF32[i3 + 4 >> 2];
+  d6 = +(HEAP32[10] | 0) / 1.0e6 * 1.0e3;
+  d5 = +(HEAP32[12] | 0) / 1.0e6 * 1.0e3;
+  HEAPF64[tempDoublePtr >> 3] = +HEAPF32[i3 >> 2];
+  HEAP32[i2 >> 2] = HEAP32[tempDoublePtr >> 2];
+  HEAP32[i2 + 4 >> 2] = HEAP32[tempDoublePtr + 4 >> 2];
+  i4 = i2 + 8 | 0;
+  HEAPF64[tempDoublePtr >> 3] = d7;
+  HEAP32[i4 >> 2] = HEAP32[tempDoublePtr >> 2];
+  HEAP32[i4 + 4 >> 2] = HEAP32[tempDoublePtr + 4 >> 2];
+  i4 = i2 + 16 | 0;
+  HEAPF64[tempDoublePtr >> 3] = d6;
+  HEAP32[i4 >> 2] = HEAP32[tempDoublePtr >> 2];
+  HEAP32[i4 + 4 >> 2] = HEAP32[tempDoublePtr + 4 >> 2];
+  i4 = i2 + 24 | 0;
+  HEAPF64[tempDoublePtr >> 3] = d5;
+  HEAP32[i4 >> 2] = HEAP32[tempDoublePtr >> 2];
+  HEAP32[i4 + 4 >> 2] = HEAP32[tempDoublePtr + 4 >> 2];
+  _printf(96, i2 | 0) | 0;
+  _emscripten_run_script(152);
+  if ((HEAP32[18] | 0) == 0) {
+   STACKTOP = i1;
+   return;
+  }
+  _emscripten_cancel_main_loop();
+  STACKTOP = i1;
+  return;
+ }
+ i3 = _clock() | 0;
+ __ZN7b2World4StepEfii(HEAP32[6] | 0, .01666666753590107, 3, 3);
+ i3 = (_clock() | 0) - i3 | 0;
+ i2 = HEAP32[16] | 0;
+ HEAP32[(HEAP32[8] | 0) + (i2 << 2) >> 2] = i3;
+ if ((i3 | 0) < (HEAP32[10] | 0)) {
+  HEAP32[10] = i3;
+ }
+ if ((i3 | 0) > (HEAP32[12] | 0)) {
+  HEAP32[12] = i3;
+ }
+ HEAP32[16] = i2 + 1;
+ STACKTOP = i1;
+ return;
+}
+function __ZN13b2DynamicTree12AllocateNodeEv(i5) {
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i1 = STACKTOP;
+ i2 = i5 + 16 | 0;
+ i3 = HEAP32[i2 >> 2] | 0;
+ if ((i3 | 0) == -1) {
+  i4 = i5 + 8 | 0;
+  i6 = HEAP32[i4 >> 2] | 0;
+  i3 = i5 + 12 | 0;
+  if ((i6 | 0) != (HEAP32[i3 >> 2] | 0)) {
+   ___assert_fail(2912, 2944, 61, 2984);
+  }
+  i5 = i5 + 4 | 0;
+  i7 = HEAP32[i5 >> 2] | 0;
+  HEAP32[i3 >> 2] = i6 << 1;
+  i6 = __Z7b2Alloci(i6 * 72 | 0) | 0;
+  HEAP32[i5 >> 2] = i6;
+  _memcpy(i6 | 0, i7 | 0, (HEAP32[i4 >> 2] | 0) * 36 | 0) | 0;
+  __Z6b2FreePv(i7);
+  i6 = HEAP32[i4 >> 2] | 0;
+  i7 = (HEAP32[i3 >> 2] | 0) + -1 | 0;
+  i5 = HEAP32[i5 >> 2] | 0;
+  if ((i6 | 0) < (i7 | 0)) {
+   i7 = i6;
+   while (1) {
+    i6 = i7 + 1 | 0;
+    HEAP32[i5 + (i7 * 36 | 0) + 20 >> 2] = i6;
+    HEAP32[i5 + (i7 * 36 | 0) + 32 >> 2] = -1;
+    i7 = (HEAP32[i3 >> 2] | 0) + -1 | 0;
+    if ((i6 | 0) < (i7 | 0)) {
+     i7 = i6;
+    } else {
+     break;
+    }
+   }
+  }
+  HEAP32[i5 + (i7 * 36 | 0) + 20 >> 2] = -1;
+  HEAP32[i5 + (((HEAP32[i3 >> 2] | 0) + -1 | 0) * 36 | 0) + 32 >> 2] = -1;
+  i3 = HEAP32[i4 >> 2] | 0;
+  HEAP32[i2 >> 2] = i3;
+ } else {
+  i4 = i5 + 8 | 0;
+  i5 = HEAP32[i5 + 4 >> 2] | 0;
+ }
+ i7 = i5 + (i3 * 36 | 0) + 20 | 0;
+ HEAP32[i2 >> 2] = HEAP32[i7 >> 2];
+ HEAP32[i7 >> 2] = -1;
+ HEAP32[i5 + (i3 * 36 | 0) + 24 >> 2] = -1;
+ HEAP32[i5 + (i3 * 36 | 0) + 28 >> 2] = -1;
+ HEAP32[i5 + (i3 * 36 | 0) + 32 >> 2] = 0;
+ HEAP32[i5 + (i3 * 36 | 0) + 16 >> 2] = 0;
+ HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + 1;
+ STACKTOP = i1;
+ return i3 | 0;
+}
+function __ZN9b2Fixture6CreateEP16b2BlockAllocatorP6b2BodyPK12b2FixtureDef(i1, i5, i4, i3) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i6 = 0, i7 = 0, d8 = 0.0;
+ i2 = STACKTOP;
+ HEAP32[i1 + 40 >> 2] = HEAP32[i3 + 4 >> 2];
+ HEAPF32[i1 + 16 >> 2] = +HEAPF32[i3 + 8 >> 2];
+ HEAPF32[i1 + 20 >> 2] = +HEAPF32[i3 + 12 >> 2];
+ HEAP32[i1 + 8 >> 2] = i4;
+ HEAP32[i1 + 4 >> 2] = 0;
+ i4 = i1 + 32 | 0;
+ i6 = i3 + 22 | 0;
+ HEAP16[i4 + 0 >> 1] = HEAP16[i6 + 0 >> 1] | 0;
+ HEAP16[i4 + 2 >> 1] = HEAP16[i6 + 2 >> 1] | 0;
+ HEAP16[i4 + 4 >> 1] = HEAP16[i6 + 4 >> 1] | 0;
+ HEAP8[i1 + 38 | 0] = HEAP8[i3 + 20 | 0] | 0;
+ i4 = HEAP32[i3 >> 2] | 0;
+ i4 = FUNCTION_TABLE_iii[HEAP32[(HEAP32[i4 >> 2] | 0) + 8 >> 2] & 3](i4, i5) | 0;
+ HEAP32[i1 + 12 >> 2] = i4;
+ i4 = FUNCTION_TABLE_ii[HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] & 3](i4) | 0;
+ i6 = __ZN16b2BlockAllocator8AllocateEi(i5, i4 * 28 | 0) | 0;
+ i5 = i1 + 24 | 0;
+ HEAP32[i5 >> 2] = i6;
+ if ((i4 | 0) > 0) {
+  i7 = 0;
+ } else {
+  i7 = i1 + 28 | 0;
+  HEAP32[i7 >> 2] = 0;
+  i7 = i3 + 16 | 0;
+  d8 = +HEAPF32[i7 >> 2];
+  HEAPF32[i1 >> 2] = d8;
+  STACKTOP = i2;
+  return;
+ }
+ do {
+  HEAP32[i6 + (i7 * 28 | 0) + 16 >> 2] = 0;
+  i6 = HEAP32[i5 >> 2] | 0;
+  HEAP32[i6 + (i7 * 28 | 0) + 24 >> 2] = -1;
+  i7 = i7 + 1 | 0;
+ } while ((i7 | 0) != (i4 | 0));
+ i7 = i1 + 28 | 0;
+ HEAP32[i7 >> 2] = 0;
+ i7 = i3 + 16 | 0;
+ d8 = +HEAPF32[i7 >> 2];
+ HEAPF32[i1 >> 2] = d8;
+ STACKTOP = i2;
+ return;
+}
+function __Z19b2ClipSegmentToLineP12b2ClipVertexPKS_RK6b2Vec2fi(i4, i1, i5, d9, i2) {
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ d9 = +d9;
+ i2 = i2 | 0;
+ var i3 = 0, i6 = 0, d7 = 0.0, i8 = 0, i10 = 0, d11 = 0.0, d12 = 0.0, i13 = 0;
+ i3 = STACKTOP;
+ d12 = +HEAPF32[i5 >> 2];
+ d11 = +HEAPF32[i5 + 4 >> 2];
+ i5 = i1 + 4 | 0;
+ d7 = d12 * +HEAPF32[i1 >> 2] + d11 * +HEAPF32[i5 >> 2] - d9;
+ i6 = i1 + 12 | 0;
+ i8 = i1 + 16 | 0;
+ d9 = d12 * +HEAPF32[i6 >> 2] + d11 * +HEAPF32[i8 >> 2] - d9;
+ if (!(d7 <= 0.0)) {
+  i10 = 0;
+ } else {
+  HEAP32[i4 + 0 >> 2] = HEAP32[i1 + 0 >> 2];
+  HEAP32[i4 + 4 >> 2] = HEAP32[i1 + 4 >> 2];
+  HEAP32[i4 + 8 >> 2] = HEAP32[i1 + 8 >> 2];
+  i10 = 1;
+ }
+ if (d9 <= 0.0) {
+  i13 = i10 + 1 | 0;
+  i10 = i4 + (i10 * 12 | 0) | 0;
+  HEAP32[i10 + 0 >> 2] = HEAP32[i6 + 0 >> 2];
+  HEAP32[i10 + 4 >> 2] = HEAP32[i6 + 4 >> 2];
+  HEAP32[i10 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+  i10 = i13;
+ }
+ if (!(d7 * d9 < 0.0)) {
+  i13 = i10;
+  STACKTOP = i3;
+  return i13 | 0;
+ }
+ d9 = d7 / (d7 - d9);
+ d11 = +HEAPF32[i1 >> 2];
+ d12 = +HEAPF32[i5 >> 2];
+ d11 = +(d11 + d9 * (+HEAPF32[i6 >> 2] - d11));
+ d12 = +(d12 + d9 * (+HEAPF32[i8 >> 2] - d12));
+ i13 = i4 + (i10 * 12 | 0) | 0;
+ HEAPF32[i13 >> 2] = d11;
+ HEAPF32[i13 + 4 >> 2] = d12;
+ i13 = i4 + (i10 * 12 | 0) + 8 | 0;
+ HEAP8[i13] = i2;
+ HEAP8[i13 + 1 | 0] = HEAP8[i1 + 9 | 0] | 0;
+ HEAP8[i13 + 2 | 0] = 0;
+ HEAP8[i13 + 3 | 0] = 1;
+ i13 = i10 + 1 | 0;
+ STACKTOP = i3;
+ return i13 | 0;
+}
+function __Z16b2CollideCirclesP10b2ManifoldPK13b2CircleShapeRK11b2TransformS3_S6_(i1, i7, i8, i6, i9) {
+ i1 = i1 | 0;
+ i7 = i7 | 0;
+ i8 = i8 | 0;
+ i6 = i6 | 0;
+ i9 = i9 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, d10 = 0.0, d11 = 0.0, d12 = 0.0, d13 = 0.0, d14 = 0.0, d15 = 0.0, d16 = 0.0, d17 = 0.0, d18 = 0.0;
+ i2 = STACKTOP;
+ i4 = i1 + 60 | 0;
+ HEAP32[i4 >> 2] = 0;
+ i3 = i7 + 12 | 0;
+ d10 = +HEAPF32[i8 + 12 >> 2];
+ d14 = +HEAPF32[i3 >> 2];
+ d13 = +HEAPF32[i8 + 8 >> 2];
+ d11 = +HEAPF32[i7 + 16 >> 2];
+ i5 = i6 + 12 | 0;
+ d16 = +HEAPF32[i9 + 12 >> 2];
+ d18 = +HEAPF32[i5 >> 2];
+ d17 = +HEAPF32[i9 + 8 >> 2];
+ d15 = +HEAPF32[i6 + 16 >> 2];
+ d12 = +HEAPF32[i9 >> 2] + (d16 * d18 - d17 * d15) - (+HEAPF32[i8 >> 2] + (d10 * d14 - d13 * d11));
+ d11 = d18 * d17 + d16 * d15 + +HEAPF32[i9 + 4 >> 2] - (d14 * d13 + d10 * d11 + +HEAPF32[i8 + 4 >> 2]);
+ d10 = +HEAPF32[i7 + 8 >> 2] + +HEAPF32[i6 + 8 >> 2];
+ if (d12 * d12 + d11 * d11 > d10 * d10) {
+  STACKTOP = i2;
+  return;
+ }
+ HEAP32[i1 + 56 >> 2] = 0;
+ i9 = i3;
+ i8 = HEAP32[i9 + 4 >> 2] | 0;
+ i7 = i1 + 48 | 0;
+ HEAP32[i7 >> 2] = HEAP32[i9 >> 2];
+ HEAP32[i7 + 4 >> 2] = i8;
+ HEAPF32[i1 + 40 >> 2] = 0.0;
+ HEAPF32[i1 + 44 >> 2] = 0.0;
+ HEAP32[i4 >> 2] = 1;
+ i7 = i5;
+ i8 = HEAP32[i7 + 4 >> 2] | 0;
+ i9 = i1;
+ HEAP32[i9 >> 2] = HEAP32[i7 >> 2];
+ HEAP32[i9 + 4 >> 2] = i8;
+ HEAP32[i1 + 16 >> 2] = 0;
+ STACKTOP = i2;
+ return;
+}
+function __ZNK14b2PolygonShape11ComputeAABBEP6b2AABBRK11b2Transformi(i1, i2, i7, i3) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i7 = i7 | 0;
+ i3 = i3 | 0;
+ var d4 = 0.0, d5 = 0.0, d6 = 0.0, d8 = 0.0, d9 = 0.0, d10 = 0.0, d11 = 0.0, d12 = 0.0, i13 = 0, d14 = 0.0, d15 = 0.0, d16 = 0.0;
+ i3 = STACKTOP;
+ d4 = +HEAPF32[i7 + 12 >> 2];
+ d15 = +HEAPF32[i1 + 20 >> 2];
+ d5 = +HEAPF32[i7 + 8 >> 2];
+ d12 = +HEAPF32[i1 + 24 >> 2];
+ d6 = +HEAPF32[i7 >> 2];
+ d9 = d6 + (d4 * d15 - d5 * d12);
+ d8 = +HEAPF32[i7 + 4 >> 2];
+ d12 = d15 * d5 + d4 * d12 + d8;
+ i7 = HEAP32[i1 + 148 >> 2] | 0;
+ if ((i7 | 0) > 1) {
+  d10 = d9;
+  d11 = d12;
+  i13 = 1;
+  do {
+   d16 = +HEAPF32[i1 + (i13 << 3) + 20 >> 2];
+   d14 = +HEAPF32[i1 + (i13 << 3) + 24 >> 2];
+   d15 = d6 + (d4 * d16 - d5 * d14);
+   d14 = d16 * d5 + d4 * d14 + d8;
+   d10 = d10 < d15 ? d10 : d15;
+   d11 = d11 < d14 ? d11 : d14;
+   d9 = d9 > d15 ? d9 : d15;
+   d12 = d12 > d14 ? d12 : d14;
+   i13 = i13 + 1 | 0;
+  } while ((i13 | 0) < (i7 | 0));
+ } else {
+  d11 = d12;
+  d10 = d9;
+ }
+ d16 = +HEAPF32[i1 + 8 >> 2];
+ d14 = +(d10 - d16);
+ d15 = +(d11 - d16);
+ i13 = i2;
+ HEAPF32[i13 >> 2] = d14;
+ HEAPF32[i13 + 4 >> 2] = d15;
+ d15 = +(d9 + d16);
+ d16 = +(d12 + d16);
+ i13 = i2 + 8 | 0;
+ HEAPF32[i13 >> 2] = d15;
+ HEAPF32[i13 + 4 >> 2] = d16;
+ STACKTOP = i3;
+ return;
+}
+function __ZNK10__cxxabiv120__si_class_type_info16search_above_dstEPNS_19__dynamic_cast_infoEPKvS4_ib(i5, i1, i4, i6, i3, i7) {
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ i7 = i7 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((i5 | 0) != (HEAP32[i1 + 8 >> 2] | 0)) {
+  i5 = HEAP32[i5 + 8 >> 2] | 0;
+  FUNCTION_TABLE_viiiiii[HEAP32[(HEAP32[i5 >> 2] | 0) + 20 >> 2] & 3](i5, i1, i4, i6, i3, i7);
+  STACKTOP = i2;
+  return;
+ }
+ HEAP8[i1 + 53 | 0] = 1;
+ if ((HEAP32[i1 + 4 >> 2] | 0) != (i6 | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ HEAP8[i1 + 52 | 0] = 1;
+ i5 = i1 + 16 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ if ((i6 | 0) == 0) {
+  HEAP32[i5 >> 2] = i4;
+  HEAP32[i1 + 24 >> 2] = i3;
+  HEAP32[i1 + 36 >> 2] = 1;
+  if (!((HEAP32[i1 + 48 >> 2] | 0) == 1 & (i3 | 0) == 1)) {
+   STACKTOP = i2;
+   return;
+  }
+  HEAP8[i1 + 54 | 0] = 1;
+  STACKTOP = i2;
+  return;
+ }
+ if ((i6 | 0) != (i4 | 0)) {
+  i7 = i1 + 36 | 0;
+  HEAP32[i7 >> 2] = (HEAP32[i7 >> 2] | 0) + 1;
+  HEAP8[i1 + 54 | 0] = 1;
+  STACKTOP = i2;
+  return;
+ }
+ i4 = i1 + 24 | 0;
+ i5 = HEAP32[i4 >> 2] | 0;
+ if ((i5 | 0) == 2) {
+  HEAP32[i4 >> 2] = i3;
+ } else {
+  i3 = i5;
+ }
+ if (!((HEAP32[i1 + 48 >> 2] | 0) == 1 & (i3 | 0) == 1)) {
+  STACKTOP = i2;
+  return;
+ }
+ HEAP8[i1 + 54 | 0] = 1;
+ STACKTOP = i2;
+ return;
+}
+function __ZN6b2Body13CreateFixtureEPK12b2FixtureDef(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0;
+ i3 = STACKTOP;
+ i2 = i1 + 88 | 0;
+ i4 = HEAP32[i2 >> 2] | 0;
+ if ((HEAP32[i4 + 102868 >> 2] & 2 | 0) != 0) {
+  ___assert_fail(1776, 1520, 153, 1808);
+ }
+ i6 = __ZN16b2BlockAllocator8AllocateEi(i4, 44) | 0;
+ if ((i6 | 0) == 0) {
+  i6 = 0;
+ } else {
+  __ZN9b2FixtureC2Ev(i6);
+ }
+ __ZN9b2Fixture6CreateEP16b2BlockAllocatorP6b2BodyPK12b2FixtureDef(i6, i4, i1, i5);
+ if (!((HEAP16[i1 + 4 >> 1] & 32) == 0)) {
+  __ZN9b2Fixture13CreateProxiesEP12b2BroadPhaseRK11b2Transform(i6, (HEAP32[i2 >> 2] | 0) + 102872 | 0, i1 + 12 | 0);
+ }
+ i5 = i1 + 100 | 0;
+ HEAP32[i6 + 4 >> 2] = HEAP32[i5 >> 2];
+ HEAP32[i5 >> 2] = i6;
+ i5 = i1 + 104 | 0;
+ HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + 1;
+ HEAP32[i6 + 8 >> 2] = i1;
+ if (!(+HEAPF32[i6 >> 2] > 0.0)) {
+  i5 = HEAP32[i2 >> 2] | 0;
+  i5 = i5 + 102868 | 0;
+  i4 = HEAP32[i5 >> 2] | 0;
+  i4 = i4 | 1;
+  HEAP32[i5 >> 2] = i4;
+  STACKTOP = i3;
+  return i6 | 0;
+ }
+ __ZN6b2Body13ResetMassDataEv(i1);
+ i5 = HEAP32[i2 >> 2] | 0;
+ i5 = i5 + 102868 | 0;
+ i4 = HEAP32[i5 >> 2] | 0;
+ i4 = i4 | 1;
+ HEAP32[i5 >> 2] = i4;
+ STACKTOP = i3;
+ return i6 | 0;
+}
+function __Z13b2TestOverlapPK7b2ShapeiS1_iRK11b2TransformS4_(i6, i5, i4, i3, i2, i1) {
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i8 = STACKTOP;
+ STACKTOP = STACKTOP + 128 | 0;
+ i9 = i8 + 36 | 0;
+ i10 = i8 + 24 | 0;
+ i7 = i8;
+ HEAP32[i9 + 16 >> 2] = 0;
+ HEAP32[i9 + 20 >> 2] = 0;
+ HEAPF32[i9 + 24 >> 2] = 0.0;
+ HEAP32[i9 + 44 >> 2] = 0;
+ HEAP32[i9 + 48 >> 2] = 0;
+ HEAPF32[i9 + 52 >> 2] = 0.0;
+ __ZN15b2DistanceProxy3SetEPK7b2Shapei(i9, i6, i5);
+ __ZN15b2DistanceProxy3SetEPK7b2Shapei(i9 + 28 | 0, i4, i3);
+ i6 = i9 + 56 | 0;
+ HEAP32[i6 + 0 >> 2] = HEAP32[i2 + 0 >> 2];
+ HEAP32[i6 + 4 >> 2] = HEAP32[i2 + 4 >> 2];
+ HEAP32[i6 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+ HEAP32[i6 + 12 >> 2] = HEAP32[i2 + 12 >> 2];
+ i6 = i9 + 72 | 0;
+ HEAP32[i6 + 0 >> 2] = HEAP32[i1 + 0 >> 2];
+ HEAP32[i6 + 4 >> 2] = HEAP32[i1 + 4 >> 2];
+ HEAP32[i6 + 8 >> 2] = HEAP32[i1 + 8 >> 2];
+ HEAP32[i6 + 12 >> 2] = HEAP32[i1 + 12 >> 2];
+ HEAP8[i9 + 88 | 0] = 1;
+ HEAP16[i10 + 4 >> 1] = 0;
+ __Z10b2DistanceP16b2DistanceOutputP14b2SimplexCachePK15b2DistanceInput(i7, i10, i9);
+ STACKTOP = i8;
+ return +HEAPF32[i7 + 16 >> 2] < 11920928955078125.0e-22 | 0;
+}
+function __ZNK10__cxxabiv117__class_type_info16search_above_dstEPNS_19__dynamic_cast_infoEPKvS4_ib(i6, i1, i4, i5, i2, i3) {
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i3 = STACKTOP;
+ if ((HEAP32[i1 + 8 >> 2] | 0) != (i6 | 0)) {
+  STACKTOP = i3;
+  return;
+ }
+ HEAP8[i1 + 53 | 0] = 1;
+ if ((HEAP32[i1 + 4 >> 2] | 0) != (i5 | 0)) {
+  STACKTOP = i3;
+  return;
+ }
+ HEAP8[i1 + 52 | 0] = 1;
+ i5 = i1 + 16 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ if ((i6 | 0) == 0) {
+  HEAP32[i5 >> 2] = i4;
+  HEAP32[i1 + 24 >> 2] = i2;
+  HEAP32[i1 + 36 >> 2] = 1;
+  if (!((HEAP32[i1 + 48 >> 2] | 0) == 1 & (i2 | 0) == 1)) {
+   STACKTOP = i3;
+   return;
+  }
+  HEAP8[i1 + 54 | 0] = 1;
+  STACKTOP = i3;
+  return;
+ }
+ if ((i6 | 0) != (i4 | 0)) {
+  i6 = i1 + 36 | 0;
+  HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + 1;
+  HEAP8[i1 + 54 | 0] = 1;
+  STACKTOP = i3;
+  return;
+ }
+ i4 = i1 + 24 | 0;
+ i5 = HEAP32[i4 >> 2] | 0;
+ if ((i5 | 0) == 2) {
+  HEAP32[i4 >> 2] = i2;
+ } else {
+  i2 = i5;
+ }
+ if (!((HEAP32[i1 + 48 >> 2] | 0) == 1 & (i2 | 0) == 1)) {
+  STACKTOP = i3;
+  return;
+ }
+ HEAP8[i1 + 54 | 0] = 1;
+ STACKTOP = i3;
+ return;
+}
+function __ZNK11b2EdgeShape5CloneEP16b2BlockAllocator(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ i3 = __ZN16b2BlockAllocator8AllocateEi(i3, 48) | 0;
+ if ((i3 | 0) == 0) {
+  i3 = 0;
+ } else {
+  HEAP32[i3 >> 2] = 240;
+  HEAP32[i3 + 4 >> 2] = 1;
+  HEAPF32[i3 + 8 >> 2] = .009999999776482582;
+  i4 = i3 + 28 | 0;
+  HEAP32[i4 + 0 >> 2] = 0;
+  HEAP32[i4 + 4 >> 2] = 0;
+  HEAP32[i4 + 8 >> 2] = 0;
+  HEAP32[i4 + 12 >> 2] = 0;
+  HEAP16[i4 + 16 >> 1] = 0;
+ }
+ i6 = i1 + 4 | 0;
+ i5 = HEAP32[i6 + 4 >> 2] | 0;
+ i4 = i3 + 4 | 0;
+ HEAP32[i4 >> 2] = HEAP32[i6 >> 2];
+ HEAP32[i4 + 4 >> 2] = i5;
+ i4 = i3 + 12 | 0;
+ i1 = i1 + 12 | 0;
+ HEAP32[i4 + 0 >> 2] = HEAP32[i1 + 0 >> 2];
+ HEAP32[i4 + 4 >> 2] = HEAP32[i1 + 4 >> 2];
+ HEAP32[i4 + 8 >> 2] = HEAP32[i1 + 8 >> 2];
+ HEAP32[i4 + 12 >> 2] = HEAP32[i1 + 12 >> 2];
+ HEAP32[i4 + 16 >> 2] = HEAP32[i1 + 16 >> 2];
+ HEAP32[i4 + 20 >> 2] = HEAP32[i1 + 20 >> 2];
+ HEAP32[i4 + 24 >> 2] = HEAP32[i1 + 24 >> 2];
+ HEAP32[i4 + 28 >> 2] = HEAP32[i1 + 28 >> 2];
+ HEAP16[i4 + 32 >> 1] = HEAP16[i1 + 32 >> 1] | 0;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function __ZN7b2WorldC2ERK6b2Vec2(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i3 = STACKTOP;
+ __ZN16b2BlockAllocatorC2Ev(i1);
+ __ZN16b2StackAllocatorC2Ev(i1 + 68 | 0);
+ __ZN16b2ContactManagerC2Ev(i1 + 102872 | 0);
+ i6 = i1 + 102968 | 0;
+ HEAP32[i1 + 102980 >> 2] = 0;
+ HEAP32[i1 + 102984 >> 2] = 0;
+ i4 = i1 + 102952 | 0;
+ i5 = i1 + 102992 | 0;
+ HEAP32[i4 + 0 >> 2] = 0;
+ HEAP32[i4 + 4 >> 2] = 0;
+ HEAP32[i4 + 8 >> 2] = 0;
+ HEAP32[i4 + 12 >> 2] = 0;
+ HEAP8[i5] = 1;
+ HEAP8[i1 + 102993 | 0] = 1;
+ HEAP8[i1 + 102994 | 0] = 0;
+ HEAP8[i1 + 102995 | 0] = 1;
+ HEAP8[i1 + 102976 | 0] = 1;
+ i5 = i2;
+ i4 = HEAP32[i5 + 4 >> 2] | 0;
+ i2 = i6;
+ HEAP32[i2 >> 2] = HEAP32[i5 >> 2];
+ HEAP32[i2 + 4 >> 2] = i4;
+ HEAP32[i1 + 102868 >> 2] = 4;
+ HEAPF32[i1 + 102988 >> 2] = 0.0;
+ HEAP32[i1 + 102948 >> 2] = i1;
+ i2 = i1 + 102996 | 0;
+ HEAP32[i2 + 0 >> 2] = 0;
+ HEAP32[i2 + 4 >> 2] = 0;
+ HEAP32[i2 + 8 >> 2] = 0;
+ HEAP32[i2 + 12 >> 2] = 0;
+ HEAP32[i2 + 16 >> 2] = 0;
+ HEAP32[i2 + 20 >> 2] = 0;
+ HEAP32[i2 + 24 >> 2] = 0;
+ HEAP32[i2 + 28 >> 2] = 0;
+ STACKTOP = i3;
+ return;
+}
+function __ZNK10__cxxabiv117__class_type_info16search_below_dstEPNS_19__dynamic_cast_infoEPKvib(i6, i3, i4, i1, i2) {
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i5 = 0;
+ i2 = STACKTOP;
+ if ((HEAP32[i3 + 8 >> 2] | 0) == (i6 | 0)) {
+  if ((HEAP32[i3 + 4 >> 2] | 0) != (i4 | 0)) {
+   STACKTOP = i2;
+   return;
+  }
+  i3 = i3 + 28 | 0;
+  if ((HEAP32[i3 >> 2] | 0) == 1) {
+   STACKTOP = i2;
+   return;
+  }
+  HEAP32[i3 >> 2] = i1;
+  STACKTOP = i2;
+  return;
+ }
+ if ((HEAP32[i3 >> 2] | 0) != (i6 | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ if ((HEAP32[i3 + 16 >> 2] | 0) != (i4 | 0) ? (i5 = i3 + 20 | 0, (HEAP32[i5 >> 2] | 0) != (i4 | 0)) : 0) {
+  HEAP32[i3 + 32 >> 2] = i1;
+  HEAP32[i5 >> 2] = i4;
+  i6 = i3 + 40 | 0;
+  HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + 1;
+  if ((HEAP32[i3 + 36 >> 2] | 0) == 1 ? (HEAP32[i3 + 24 >> 2] | 0) == 2 : 0) {
+   HEAP8[i3 + 54 | 0] = 1;
+  }
+  HEAP32[i3 + 44 >> 2] = 4;
+  STACKTOP = i2;
+  return;
+ }
+ if ((i1 | 0) != 1) {
+  STACKTOP = i2;
+  return;
+ }
+ HEAP32[i3 + 32 >> 2] = 1;
+ STACKTOP = i2;
+ return;
+}
+function __ZN9b2Contact7DestroyEPS_P16b2BlockAllocator(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i3 = STACKTOP;
+ if ((HEAP8[4200] | 0) == 0) {
+  ___assert_fail(4352, 4256, 103, 4376);
+ }
+ i4 = HEAP32[i1 + 48 >> 2] | 0;
+ if ((HEAP32[i1 + 124 >> 2] | 0) > 0) {
+  i7 = HEAP32[i4 + 8 >> 2] | 0;
+  i6 = i7 + 4 | 0;
+  i5 = HEAPU16[i6 >> 1] | 0;
+  if ((i5 & 2 | 0) == 0) {
+   HEAP16[i6 >> 1] = i5 | 2;
+   HEAPF32[i7 + 144 >> 2] = 0.0;
+  }
+  i7 = HEAP32[i1 + 52 >> 2] | 0;
+  i6 = HEAP32[i7 + 8 >> 2] | 0;
+  i5 = i6 + 4 | 0;
+  i8 = HEAPU16[i5 >> 1] | 0;
+  if ((i8 & 2 | 0) == 0) {
+   HEAP16[i5 >> 1] = i8 | 2;
+   HEAPF32[i6 + 144 >> 2] = 0.0;
+  }
+ } else {
+  i7 = HEAP32[i1 + 52 >> 2] | 0;
+ }
+ i4 = HEAP32[(HEAP32[i4 + 12 >> 2] | 0) + 4 >> 2] | 0;
+ i5 = HEAP32[(HEAP32[i7 + 12 >> 2] | 0) + 4 >> 2] | 0;
+ if ((i4 | 0) > -1 & (i5 | 0) < 4) {
+  FUNCTION_TABLE_vii[HEAP32[4008 + (i4 * 48 | 0) + (i5 * 12 | 0) + 4 >> 2] & 15](i1, i2);
+  STACKTOP = i3;
+  return;
+ } else {
+  ___assert_fail(4384, 4256, 114, 4376);
+ }
+}
+function __ZN9b2Fixture13CreateProxiesEP12b2BroadPhaseRK11b2Transform(i5, i4, i1) {
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0;
+ i2 = STACKTOP;
+ i3 = i5 + 28 | 0;
+ if ((HEAP32[i3 >> 2] | 0) != 0) {
+  ___assert_fail(2088, 2112, 124, 2144);
+ }
+ i6 = i5 + 12 | 0;
+ i8 = HEAP32[i6 >> 2] | 0;
+ i8 = FUNCTION_TABLE_ii[HEAP32[(HEAP32[i8 >> 2] | 0) + 12 >> 2] & 3](i8) | 0;
+ HEAP32[i3 >> 2] = i8;
+ if ((i8 | 0) <= 0) {
+  STACKTOP = i2;
+  return;
+ }
+ i7 = i5 + 24 | 0;
+ i8 = 0;
+ do {
+  i9 = HEAP32[i7 >> 2] | 0;
+  i10 = i9 + (i8 * 28 | 0) | 0;
+  i11 = HEAP32[i6 >> 2] | 0;
+  FUNCTION_TABLE_viiii[HEAP32[(HEAP32[i11 >> 2] | 0) + 24 >> 2] & 15](i11, i10, i1, i8);
+  HEAP32[i9 + (i8 * 28 | 0) + 24 >> 2] = __ZN12b2BroadPhase11CreateProxyERK6b2AABBPv(i4, i10, i10) | 0;
+  HEAP32[i9 + (i8 * 28 | 0) + 16 >> 2] = i5;
+  HEAP32[i9 + (i8 * 28 | 0) + 20 >> 2] = i8;
+  i8 = i8 + 1 | 0;
+ } while ((i8 | 0) < (HEAP32[i3 >> 2] | 0));
+ STACKTOP = i2;
+ return;
+}
+function __ZNK10__cxxabiv117__class_type_info9can_catchEPKNS_16__shim_type_infoERPv(i1, i5, i4) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i3 = i2;
+ if ((i1 | 0) == (i5 | 0)) {
+  i7 = 1;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ if ((i5 | 0) == 0) {
+  i7 = 0;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ i5 = ___dynamic_cast(i5, 6952, 7008, 0) | 0;
+ if ((i5 | 0) == 0) {
+  i7 = 0;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ i7 = i3 + 0 | 0;
+ i6 = i7 + 56 | 0;
+ do {
+  HEAP32[i7 >> 2] = 0;
+  i7 = i7 + 4 | 0;
+ } while ((i7 | 0) < (i6 | 0));
+ HEAP32[i3 >> 2] = i5;
+ HEAP32[i3 + 8 >> 2] = i1;
+ HEAP32[i3 + 12 >> 2] = -1;
+ HEAP32[i3 + 48 >> 2] = 1;
+ FUNCTION_TABLE_viiii[HEAP32[(HEAP32[i5 >> 2] | 0) + 28 >> 2] & 15](i5, i3, HEAP32[i4 >> 2] | 0, 1);
+ if ((HEAP32[i3 + 24 >> 2] | 0) != 1) {
+  i7 = 0;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ HEAP32[i4 >> 2] = HEAP32[i3 + 16 >> 2];
+ i7 = 1;
+ STACKTOP = i2;
+ return i7 | 0;
+}
+function __ZN8b2IslandC2EiiiP16b2StackAllocatorP17b2ContactListener(i1, i4, i3, i2, i5, i6) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ var i7 = 0, i8 = 0;
+ i7 = STACKTOP;
+ i8 = i1 + 40 | 0;
+ HEAP32[i8 >> 2] = i4;
+ HEAP32[i1 + 44 >> 2] = i3;
+ HEAP32[i1 + 48 >> 2] = i2;
+ HEAP32[i1 + 28 >> 2] = 0;
+ HEAP32[i1 + 36 >> 2] = 0;
+ HEAP32[i1 + 32 >> 2] = 0;
+ HEAP32[i1 >> 2] = i5;
+ HEAP32[i1 + 4 >> 2] = i6;
+ HEAP32[i1 + 8 >> 2] = __ZN16b2StackAllocator8AllocateEi(i5, i4 << 2) | 0;
+ HEAP32[i1 + 12 >> 2] = __ZN16b2StackAllocator8AllocateEi(HEAP32[i1 >> 2] | 0, i3 << 2) | 0;
+ HEAP32[i1 + 16 >> 2] = __ZN16b2StackAllocator8AllocateEi(HEAP32[i1 >> 2] | 0, i2 << 2) | 0;
+ HEAP32[i1 + 24 >> 2] = __ZN16b2StackAllocator8AllocateEi(HEAP32[i1 >> 2] | 0, (HEAP32[i8 >> 2] | 0) * 12 | 0) | 0;
+ HEAP32[i1 + 20 >> 2] = __ZN16b2StackAllocator8AllocateEi(HEAP32[i1 >> 2] | 0, (HEAP32[i8 >> 2] | 0) * 12 | 0) | 0;
+ STACKTOP = i7;
+ return;
+}
+function __ZNK11b2EdgeShape11ComputeAABBEP6b2AABBRK11b2Transformi(i8, i1, i10, i2) {
+ i8 = i8 | 0;
+ i1 = i1 | 0;
+ i10 = i10 | 0;
+ i2 = i2 | 0;
+ var d3 = 0.0, d4 = 0.0, d5 = 0.0, d6 = 0.0, d7 = 0.0, d9 = 0.0, d11 = 0.0, d12 = 0.0;
+ i2 = STACKTOP;
+ d7 = +HEAPF32[i10 + 12 >> 2];
+ d9 = +HEAPF32[i8 + 12 >> 2];
+ d11 = +HEAPF32[i10 + 8 >> 2];
+ d3 = +HEAPF32[i8 + 16 >> 2];
+ d6 = +HEAPF32[i10 >> 2];
+ d5 = d6 + (d7 * d9 - d11 * d3);
+ d12 = +HEAPF32[i10 + 4 >> 2];
+ d3 = d9 * d11 + d7 * d3 + d12;
+ d9 = +HEAPF32[i8 + 20 >> 2];
+ d4 = +HEAPF32[i8 + 24 >> 2];
+ d6 = d6 + (d7 * d9 - d11 * d4);
+ d4 = d12 + (d11 * d9 + d7 * d4);
+ d7 = +HEAPF32[i8 + 8 >> 2];
+ d9 = +((d5 < d6 ? d5 : d6) - d7);
+ d12 = +((d3 < d4 ? d3 : d4) - d7);
+ i10 = i1;
+ HEAPF32[i10 >> 2] = d9;
+ HEAPF32[i10 + 4 >> 2] = d12;
+ d5 = +(d7 + (d5 > d6 ? d5 : d6));
+ d12 = +(d7 + (d3 > d4 ? d3 : d4));
+ i10 = i1 + 8 | 0;
+ HEAPF32[i10 >> 2] = d5;
+ HEAPF32[i10 + 4 >> 2] = d12;
+ STACKTOP = i2;
+ return;
+}
+function __ZNK14b2PolygonShape9TestPointERK11b2TransformRK6b2Vec2(i2, i3, i6) {
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, d4 = 0.0, d5 = 0.0, i7 = 0, d8 = 0.0, d9 = 0.0, d10 = 0.0;
+ i1 = STACKTOP;
+ d8 = +HEAPF32[i6 >> 2] - +HEAPF32[i3 >> 2];
+ d9 = +HEAPF32[i6 + 4 >> 2] - +HEAPF32[i3 + 4 >> 2];
+ d10 = +HEAPF32[i3 + 12 >> 2];
+ d5 = +HEAPF32[i3 + 8 >> 2];
+ d4 = d8 * d10 + d9 * d5;
+ d5 = d10 * d9 - d8 * d5;
+ i3 = HEAP32[i2 + 148 >> 2] | 0;
+ if ((i3 | 0) > 0) {
+  i6 = 0;
+ } else {
+  i7 = 1;
+  STACKTOP = i1;
+  return i7 | 0;
+ }
+ while (1) {
+  i7 = i6 + 1 | 0;
+  if ((d4 - +HEAPF32[i2 + (i6 << 3) + 20 >> 2]) * +HEAPF32[i2 + (i6 << 3) + 84 >> 2] + (d5 - +HEAPF32[i2 + (i6 << 3) + 24 >> 2]) * +HEAPF32[i2 + (i6 << 3) + 88 >> 2] > 0.0) {
+   i3 = 0;
+   i2 = 4;
+   break;
+  }
+  if ((i7 | 0) < (i3 | 0)) {
+   i6 = i7;
+  } else {
+   i3 = 1;
+   i2 = 4;
+   break;
+  }
+ }
+ if ((i2 | 0) == 4) {
+  STACKTOP = i1;
+  return i3 | 0;
+ }
+ return 0;
+}
+function __ZN16b2StackAllocator8AllocateEi(i4, i5) {
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ i3 = i4 + 102796 | 0;
+ i6 = HEAP32[i3 >> 2] | 0;
+ if ((i6 | 0) >= 32) {
+  ___assert_fail(3896, 3808, 38, 3936);
+ }
+ i1 = i4 + (i6 * 12 | 0) + 102412 | 0;
+ HEAP32[i4 + (i6 * 12 | 0) + 102416 >> 2] = i5;
+ i7 = i4 + 102400 | 0;
+ i8 = HEAP32[i7 >> 2] | 0;
+ if ((i8 + i5 | 0) > 102400) {
+  HEAP32[i1 >> 2] = __Z7b2Alloci(i5) | 0;
+  HEAP8[i4 + (i6 * 12 | 0) + 102420 | 0] = 1;
+ } else {
+  HEAP32[i1 >> 2] = i4 + i8;
+  HEAP8[i4 + (i6 * 12 | 0) + 102420 | 0] = 0;
+  HEAP32[i7 >> 2] = (HEAP32[i7 >> 2] | 0) + i5;
+ }
+ i6 = i4 + 102404 | 0;
+ i5 = (HEAP32[i6 >> 2] | 0) + i5 | 0;
+ HEAP32[i6 >> 2] = i5;
+ i4 = i4 + 102408 | 0;
+ i6 = HEAP32[i4 >> 2] | 0;
+ HEAP32[i4 >> 2] = (i6 | 0) > (i5 | 0) ? i6 : i5;
+ HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + 1;
+ STACKTOP = i2;
+ return HEAP32[i1 >> 2] | 0;
+}
+function __ZN12b2BroadPhase13QueryCallbackEi(i5, i1) {
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ i4 = i5 + 56 | 0;
+ i7 = HEAP32[i4 >> 2] | 0;
+ if ((i7 | 0) == (i1 | 0)) {
+  STACKTOP = i2;
+  return 1;
+ }
+ i3 = i5 + 52 | 0;
+ i6 = HEAP32[i3 >> 2] | 0;
+ i8 = i5 + 48 | 0;
+ i5 = i5 + 44 | 0;
+ if ((i6 | 0) == (HEAP32[i8 >> 2] | 0)) {
+  i7 = HEAP32[i5 >> 2] | 0;
+  HEAP32[i8 >> 2] = i6 << 1;
+  i6 = __Z7b2Alloci(i6 * 24 | 0) | 0;
+  HEAP32[i5 >> 2] = i6;
+  _memcpy(i6 | 0, i7 | 0, (HEAP32[i3 >> 2] | 0) * 12 | 0) | 0;
+  __Z6b2FreePv(i7);
+  i7 = HEAP32[i4 >> 2] | 0;
+  i6 = HEAP32[i3 >> 2] | 0;
+ }
+ i5 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i5 + (i6 * 12 | 0) >> 2] = (i7 | 0) > (i1 | 0) ? i1 : i7;
+ i4 = HEAP32[i4 >> 2] | 0;
+ HEAP32[i5 + ((HEAP32[i3 >> 2] | 0) * 12 | 0) + 4 >> 2] = (i4 | 0) < (i1 | 0) ? i1 : i4;
+ HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + 1;
+ STACKTOP = i2;
+ return 1;
+}
+function __ZNK10__cxxabiv120__si_class_type_info27has_unambiguous_public_baseEPNS_19__dynamic_cast_infoEPvi(i5, i4, i3, i1) {
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i6 = 0;
+ i2 = STACKTOP;
+ if ((i5 | 0) != (HEAP32[i4 + 8 >> 2] | 0)) {
+  i6 = HEAP32[i5 + 8 >> 2] | 0;
+  FUNCTION_TABLE_viiii[HEAP32[(HEAP32[i6 >> 2] | 0) + 28 >> 2] & 15](i6, i4, i3, i1);
+  STACKTOP = i2;
+  return;
+ }
+ i5 = i4 + 16 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ if ((i6 | 0) == 0) {
+  HEAP32[i5 >> 2] = i3;
+  HEAP32[i4 + 24 >> 2] = i1;
+  HEAP32[i4 + 36 >> 2] = 1;
+  STACKTOP = i2;
+  return;
+ }
+ if ((i6 | 0) != (i3 | 0)) {
+  i6 = i4 + 36 | 0;
+  HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + 1;
+  HEAP32[i4 + 24 >> 2] = 2;
+  HEAP8[i4 + 54 | 0] = 1;
+  STACKTOP = i2;
+  return;
+ }
+ i3 = i4 + 24 | 0;
+ if ((HEAP32[i3 >> 2] | 0) != 2) {
+  STACKTOP = i2;
+  return;
+ }
+ HEAP32[i3 >> 2] = i1;
+ STACKTOP = i2;
+ return;
+}
+function __ZN6b2Body19SynchronizeFixturesEv(i5) {
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, d6 = 0.0, d7 = 0.0, d8 = 0.0, d9 = 0.0, d10 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i1;
+ d8 = +HEAPF32[i5 + 52 >> 2];
+ d9 = +Math_sin(+d8);
+ HEAPF32[i3 + 8 >> 2] = d9;
+ d8 = +Math_cos(+d8);
+ HEAPF32[i3 + 12 >> 2] = d8;
+ d10 = +HEAPF32[i5 + 28 >> 2];
+ d6 = +HEAPF32[i5 + 32 >> 2];
+ d7 = +(+HEAPF32[i5 + 36 >> 2] - (d8 * d10 - d9 * d6));
+ d6 = +(+HEAPF32[i5 + 40 >> 2] - (d10 * d9 + d8 * d6));
+ i2 = i3;
+ HEAPF32[i2 >> 2] = d7;
+ HEAPF32[i2 + 4 >> 2] = d6;
+ i2 = (HEAP32[i5 + 88 >> 2] | 0) + 102872 | 0;
+ i4 = HEAP32[i5 + 100 >> 2] | 0;
+ if ((i4 | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i5 = i5 + 12 | 0;
+ do {
+  __ZN9b2Fixture11SynchronizeEP12b2BroadPhaseRK11b2TransformS4_(i4, i2, i3, i5);
+  i4 = HEAP32[i4 + 4 >> 2] | 0;
+ } while ((i4 | 0) != 0);
+ STACKTOP = i1;
+ return;
+}
+function __ZN13b2DynamicTreeC2Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i4 = STACKTOP;
+ HEAP32[i1 >> 2] = -1;
+ i3 = i1 + 12 | 0;
+ HEAP32[i3 >> 2] = 16;
+ HEAP32[i1 + 8 >> 2] = 0;
+ i6 = __Z7b2Alloci(576) | 0;
+ i2 = i1 + 4 | 0;
+ HEAP32[i2 >> 2] = i6;
+ _memset(i6 | 0, 0, (HEAP32[i3 >> 2] | 0) * 36 | 0) | 0;
+ i6 = (HEAP32[i3 >> 2] | 0) + -1 | 0;
+ i2 = HEAP32[i2 >> 2] | 0;
+ if ((i6 | 0) > 0) {
+  i6 = 0;
+  while (1) {
+   i5 = i6 + 1 | 0;
+   HEAP32[i2 + (i6 * 36 | 0) + 20 >> 2] = i5;
+   HEAP32[i2 + (i6 * 36 | 0) + 32 >> 2] = -1;
+   i6 = (HEAP32[i3 >> 2] | 0) + -1 | 0;
+   if ((i5 | 0) < (i6 | 0)) {
+    i6 = i5;
+   } else {
+    break;
+   }
+  }
+ }
+ HEAP32[i2 + (i6 * 36 | 0) + 20 >> 2] = -1;
+ HEAP32[i2 + (((HEAP32[i3 >> 2] | 0) + -1 | 0) * 36 | 0) + 32 >> 2] = -1;
+ HEAP32[i1 + 16 >> 2] = 0;
+ HEAP32[i1 + 20 >> 2] = 0;
+ HEAP32[i1 + 24 >> 2] = 0;
+ STACKTOP = i4;
+ return;
+}
+function __Z7measurePl(i1, i9) {
+ i1 = i1 | 0;
+ i9 = i9 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, d5 = 0.0, d6 = 0.0, i7 = 0, d8 = 0.0, i10 = 0, d11 = 0.0;
+ i2 = STACKTOP;
+ i3 = HEAP32[4] | 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + ((4 * i3 | 0) + 15 & -16) | 0;
+ i7 = (i3 | 0) > 0;
+ if (i7) {
+  i10 = 0;
+  d6 = 0.0;
+  do {
+   d8 = +(HEAP32[i9 + (i10 << 2) >> 2] | 0) / 1.0e6 * 1.0e3;
+   HEAPF32[i4 + (i10 << 2) >> 2] = d8;
+   d6 = d6 + d8;
+   i10 = i10 + 1 | 0;
+  } while ((i10 | 0) < (i3 | 0));
+  d5 = +(i3 | 0);
+  d6 = d6 / d5;
+  HEAPF32[i1 >> 2] = d6;
+  if (i7) {
+   i7 = 0;
+   d8 = 0.0;
+   do {
+    d11 = +HEAPF32[i4 + (i7 << 2) >> 2] - d6;
+    d8 = d8 + d11 * d11;
+    i7 = i7 + 1 | 0;
+   } while ((i7 | 0) < (i3 | 0));
+  } else {
+   d8 = 0.0;
+  }
+ } else {
+  d5 = +(i3 | 0);
+  HEAPF32[i1 >> 2] = 0.0 / d5;
+  d8 = 0.0;
+ }
+ HEAPF32[i1 + 4 >> 2] = +Math_sqrt(+(d8 / d5));
+ STACKTOP = i2;
+ return;
+}
+function __ZN13b2DynamicTree11CreateProxyERK6b2AABBPv(i1, i3, i2) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i4 = 0, i5 = 0, i6 = 0, d7 = 0.0, d8 = 0.0, i9 = 0;
+ i5 = STACKTOP;
+ i4 = __ZN13b2DynamicTree12AllocateNodeEv(i1) | 0;
+ i6 = i1 + 4 | 0;
+ d7 = +(+HEAPF32[i3 >> 2] + -.10000000149011612);
+ d8 = +(+HEAPF32[i3 + 4 >> 2] + -.10000000149011612);
+ i9 = (HEAP32[i6 >> 2] | 0) + (i4 * 36 | 0) | 0;
+ HEAPF32[i9 >> 2] = d7;
+ HEAPF32[i9 + 4 >> 2] = d8;
+ d8 = +(+HEAPF32[i3 + 8 >> 2] + .10000000149011612);
+ d7 = +(+HEAPF32[i3 + 12 >> 2] + .10000000149011612);
+ i3 = (HEAP32[i6 >> 2] | 0) + (i4 * 36 | 0) + 8 | 0;
+ HEAPF32[i3 >> 2] = d8;
+ HEAPF32[i3 + 4 >> 2] = d7;
+ HEAP32[(HEAP32[i6 >> 2] | 0) + (i4 * 36 | 0) + 16 >> 2] = i2;
+ HEAP32[(HEAP32[i6 >> 2] | 0) + (i4 * 36 | 0) + 32 >> 2] = 0;
+ __ZN13b2DynamicTree10InsertLeafEi(i1, i4);
+ STACKTOP = i5;
+ return i4 | 0;
+}
+function __ZN16b2BlockAllocatorC2Ev(i3) {
+ i3 = i3 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i4 = i3 + 8 | 0;
+ HEAP32[i4 >> 2] = 128;
+ HEAP32[i3 + 4 >> 2] = 0;
+ i5 = __Z7b2Alloci(1024) | 0;
+ HEAP32[i3 >> 2] = i5;
+ _memset(i5 | 0, 0, HEAP32[i4 >> 2] << 3 | 0) | 0;
+ i4 = i3 + 12 | 0;
+ i3 = i4 + 56 | 0;
+ do {
+  HEAP32[i4 >> 2] = 0;
+  i4 = i4 + 4 | 0;
+ } while ((i4 | 0) < (i3 | 0));
+ if ((HEAP8[1280] | 0) == 0) {
+  i3 = 1;
+  i4 = 0;
+ } else {
+  STACKTOP = i2;
+  return;
+ }
+ do {
+  if ((i4 | 0) >= 14) {
+   i1 = 3;
+   break;
+  }
+  if ((i3 | 0) > (HEAP32[576 + (i4 << 2) >> 2] | 0)) {
+   i4 = i4 + 1 | 0;
+   HEAP8[632 + i3 | 0] = i4;
+  } else {
+   HEAP8[632 + i3 | 0] = i4;
+  }
+  i3 = i3 + 1 | 0;
+ } while ((i3 | 0) < 641);
+ if ((i1 | 0) == 3) {
+  ___assert_fail(1288, 1312, 73, 1352);
+ }
+ HEAP8[1280] = 1;
+ STACKTOP = i2;
+ return;
+}
+function __ZN24b2ChainAndPolygonContact8EvaluateEP10b2ManifoldRK11b2TransformS4_(i2, i4, i3, i1) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i5 = STACKTOP;
+ STACKTOP = STACKTOP + 48 | 0;
+ i6 = i5;
+ i7 = HEAP32[(HEAP32[i2 + 48 >> 2] | 0) + 12 >> 2] | 0;
+ HEAP32[i6 >> 2] = 240;
+ HEAP32[i6 + 4 >> 2] = 1;
+ HEAPF32[i6 + 8 >> 2] = .009999999776482582;
+ i8 = i6 + 28 | 0;
+ HEAP32[i8 + 0 >> 2] = 0;
+ HEAP32[i8 + 4 >> 2] = 0;
+ HEAP32[i8 + 8 >> 2] = 0;
+ HEAP32[i8 + 12 >> 2] = 0;
+ HEAP16[i8 + 16 >> 1] = 0;
+ __ZNK12b2ChainShape12GetChildEdgeEP11b2EdgeShapei(i7, i6, HEAP32[i2 + 56 >> 2] | 0);
+ __Z23b2CollideEdgeAndPolygonP10b2ManifoldPK11b2EdgeShapeRK11b2TransformPK14b2PolygonShapeS6_(i4, i6, i3, HEAP32[(HEAP32[i2 + 52 >> 2] | 0) + 12 >> 2] | 0, i1);
+ STACKTOP = i5;
+ return;
+}
+function __ZN23b2ChainAndCircleContact8EvaluateEP10b2ManifoldRK11b2TransformS4_(i2, i4, i3, i1) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i5 = STACKTOP;
+ STACKTOP = STACKTOP + 48 | 0;
+ i6 = i5;
+ i7 = HEAP32[(HEAP32[i2 + 48 >> 2] | 0) + 12 >> 2] | 0;
+ HEAP32[i6 >> 2] = 240;
+ HEAP32[i6 + 4 >> 2] = 1;
+ HEAPF32[i6 + 8 >> 2] = .009999999776482582;
+ i8 = i6 + 28 | 0;
+ HEAP32[i8 + 0 >> 2] = 0;
+ HEAP32[i8 + 4 >> 2] = 0;
+ HEAP32[i8 + 8 >> 2] = 0;
+ HEAP32[i8 + 12 >> 2] = 0;
+ HEAP16[i8 + 16 >> 1] = 0;
+ __ZNK12b2ChainShape12GetChildEdgeEP11b2EdgeShapei(i7, i6, HEAP32[i2 + 56 >> 2] | 0);
+ __Z22b2CollideEdgeAndCircleP10b2ManifoldPK11b2EdgeShapeRK11b2TransformPK13b2CircleShapeS6_(i4, i6, i3, HEAP32[(HEAP32[i2 + 52 >> 2] | 0) + 12 >> 2] | 0, i1);
+ STACKTOP = i5;
+ return;
+}
+function __ZN15b2ContactSolver13StoreImpulsesEv(i4) {
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i1 = STACKTOP;
+ i2 = HEAP32[i4 + 48 >> 2] | 0;
+ if ((i2 | 0) <= 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i3 = HEAP32[i4 + 40 >> 2] | 0;
+ i4 = HEAP32[i4 + 44 >> 2] | 0;
+ i5 = 0;
+ do {
+  i6 = HEAP32[i4 + (HEAP32[i3 + (i5 * 152 | 0) + 148 >> 2] << 2) >> 2] | 0;
+  i7 = HEAP32[i3 + (i5 * 152 | 0) + 144 >> 2] | 0;
+  if ((i7 | 0) > 0) {
+   i8 = 0;
+   do {
+    HEAPF32[i6 + (i8 * 20 | 0) + 72 >> 2] = +HEAPF32[i3 + (i5 * 152 | 0) + (i8 * 36 | 0) + 16 >> 2];
+    HEAPF32[i6 + (i8 * 20 | 0) + 76 >> 2] = +HEAPF32[i3 + (i5 * 152 | 0) + (i8 * 36 | 0) + 20 >> 2];
+    i8 = i8 + 1 | 0;
+   } while ((i8 | 0) < (i7 | 0));
+  }
+  i5 = i5 + 1 | 0;
+ } while ((i5 | 0) < (i2 | 0));
+ STACKTOP = i1;
+ return;
+}
+function __ZN16b2StackAllocator4FreeEPv(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0;
+ i3 = STACKTOP;
+ i2 = i1 + 102796 | 0;
+ i4 = HEAP32[i2 >> 2] | 0;
+ if ((i4 | 0) <= 0) {
+  ___assert_fail(3952, 3808, 63, 3976);
+ }
+ i6 = i4 + -1 | 0;
+ if ((HEAP32[i1 + (i6 * 12 | 0) + 102412 >> 2] | 0) != (i5 | 0)) {
+  ___assert_fail(3984, 3808, 65, 3976);
+ }
+ if ((HEAP8[i1 + (i6 * 12 | 0) + 102420 | 0] | 0) == 0) {
+  i5 = i1 + (i6 * 12 | 0) + 102416 | 0;
+  i6 = i1 + 102400 | 0;
+  HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) - (HEAP32[i5 >> 2] | 0);
+ } else {
+  __Z6b2FreePv(i5);
+  i5 = i1 + (i6 * 12 | 0) + 102416 | 0;
+  i4 = HEAP32[i2 >> 2] | 0;
+ }
+ i6 = i1 + 102404 | 0;
+ HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) - (HEAP32[i5 >> 2] | 0);
+ HEAP32[i2 >> 2] = i4 + -1;
+ STACKTOP = i3;
+ return;
+}
+function __ZNK10__cxxabiv117__class_type_info27has_unambiguous_public_baseEPNS_19__dynamic_cast_infoEPvi(i5, i4, i3, i2) {
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i6 = 0;
+ i1 = STACKTOP;
+ if ((HEAP32[i4 + 8 >> 2] | 0) != (i5 | 0)) {
+  STACKTOP = i1;
+  return;
+ }
+ i5 = i4 + 16 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ if ((i6 | 0) == 0) {
+  HEAP32[i5 >> 2] = i3;
+  HEAP32[i4 + 24 >> 2] = i2;
+  HEAP32[i4 + 36 >> 2] = 1;
+  STACKTOP = i1;
+  return;
+ }
+ if ((i6 | 0) != (i3 | 0)) {
+  i6 = i4 + 36 | 0;
+  HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + 1;
+  HEAP32[i4 + 24 >> 2] = 2;
+  HEAP8[i4 + 54 | 0] = 1;
+  STACKTOP = i1;
+  return;
+ }
+ i3 = i4 + 24 | 0;
+ if ((HEAP32[i3 >> 2] | 0) != 2) {
+  STACKTOP = i1;
+  return;
+ }
+ HEAP32[i3 >> 2] = i2;
+ STACKTOP = i1;
+ return;
+}
+function __ZN12b2BroadPhase11CreateProxyERK6b2AABBPv(i2, i4, i3) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i1 = STACKTOP;
+ i3 = __ZN13b2DynamicTree11CreateProxyERK6b2AABBPv(i2, i4, i3) | 0;
+ i4 = i2 + 28 | 0;
+ HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + 1;
+ i4 = i2 + 40 | 0;
+ i5 = HEAP32[i4 >> 2] | 0;
+ i6 = i2 + 36 | 0;
+ i2 = i2 + 32 | 0;
+ if ((i5 | 0) == (HEAP32[i6 >> 2] | 0)) {
+  i7 = HEAP32[i2 >> 2] | 0;
+  HEAP32[i6 >> 2] = i5 << 1;
+  i5 = __Z7b2Alloci(i5 << 3) | 0;
+  HEAP32[i2 >> 2] = i5;
+  _memcpy(i5 | 0, i7 | 0, HEAP32[i4 >> 2] << 2 | 0) | 0;
+  __Z6b2FreePv(i7);
+  i5 = HEAP32[i4 >> 2] | 0;
+ }
+ HEAP32[(HEAP32[i2 >> 2] | 0) + (i5 << 2) >> 2] = i3;
+ HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + 1;
+ STACKTOP = i1;
+ return i3 | 0;
+}
+function __ZN9b2ContactC2EP9b2FixtureiS1_i(i1, i4, i6, i3, i5) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i7 = 0, d8 = 0.0, d9 = 0.0;
+ i2 = STACKTOP;
+ HEAP32[i1 >> 2] = 4440;
+ HEAP32[i1 + 4 >> 2] = 4;
+ HEAP32[i1 + 48 >> 2] = i4;
+ HEAP32[i1 + 52 >> 2] = i3;
+ HEAP32[i1 + 56 >> 2] = i6;
+ HEAP32[i1 + 60 >> 2] = i5;
+ HEAP32[i1 + 124 >> 2] = 0;
+ HEAP32[i1 + 128 >> 2] = 0;
+ i5 = i4 + 16 | 0;
+ i6 = i1 + 8 | 0;
+ i7 = i6 + 40 | 0;
+ do {
+  HEAP32[i6 >> 2] = 0;
+  i6 = i6 + 4 | 0;
+ } while ((i6 | 0) < (i7 | 0));
+ HEAPF32[i1 + 136 >> 2] = +Math_sqrt(+(+HEAPF32[i5 >> 2] * +HEAPF32[i3 + 16 >> 2]));
+ d8 = +HEAPF32[i4 + 20 >> 2];
+ d9 = +HEAPF32[i3 + 20 >> 2];
+ HEAPF32[i1 + 140 >> 2] = d8 > d9 ? d8 : d9;
+ STACKTOP = i2;
+ return;
+}
+function __ZN12b2BroadPhase9MoveProxyEiRK6b2AABBRK6b2Vec2(i3, i1, i5, i4) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ if (!(__ZN13b2DynamicTree9MoveProxyEiRK6b2AABBRK6b2Vec2(i3, i1, i5, i4) | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ i4 = i3 + 40 | 0;
+ i5 = HEAP32[i4 >> 2] | 0;
+ i6 = i3 + 36 | 0;
+ i3 = i3 + 32 | 0;
+ if ((i5 | 0) == (HEAP32[i6 >> 2] | 0)) {
+  i7 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i6 >> 2] = i5 << 1;
+  i5 = __Z7b2Alloci(i5 << 3) | 0;
+  HEAP32[i3 >> 2] = i5;
+  _memcpy(i5 | 0, i7 | 0, HEAP32[i4 >> 2] << 2 | 0) | 0;
+  __Z6b2FreePv(i7);
+  i5 = HEAP32[i4 >> 2] | 0;
+ }
+ HEAP32[(HEAP32[i3 >> 2] | 0) + (i5 << 2) >> 2] = i1;
+ HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + 1;
+ STACKTOP = i2;
+ return;
+}
+function __ZN24b2ChainAndPolygonContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator(i1, i3, i4, i5, i6) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i6 = __ZN16b2BlockAllocator8AllocateEi(i6, 144) | 0;
+ if ((i6 | 0) == 0) {
+  i6 = 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ __ZN9b2ContactC2EP9b2FixtureiS1_i(i6, i1, i3, i4, i5);
+ HEAP32[i6 >> 2] = 6032;
+ if ((HEAP32[(HEAP32[(HEAP32[i6 + 48 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) != 3) {
+  ___assert_fail(6048, 6096, 43, 6152);
+ }
+ if ((HEAP32[(HEAP32[(HEAP32[i6 + 52 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) == 2) {
+  STACKTOP = i2;
+  return i6 | 0;
+ } else {
+  ___assert_fail(6184, 6096, 44, 6152);
+ }
+ return 0;
+}
+function __ZN23b2ChainAndCircleContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator(i1, i3, i4, i5, i6) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i6 = __ZN16b2BlockAllocator8AllocateEi(i6, 144) | 0;
+ if ((i6 | 0) == 0) {
+  i6 = 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ __ZN9b2ContactC2EP9b2FixtureiS1_i(i6, i1, i3, i4, i5);
+ HEAP32[i6 >> 2] = 5784;
+ if ((HEAP32[(HEAP32[(HEAP32[i6 + 48 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) != 3) {
+  ___assert_fail(5800, 5848, 43, 5904);
+ }
+ if ((HEAP32[(HEAP32[(HEAP32[i6 + 52 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) == 0) {
+  STACKTOP = i2;
+  return i6 | 0;
+ } else {
+  ___assert_fail(5928, 5848, 44, 5904);
+ }
+ return 0;
+}
+function __ZN25b2PolygonAndCircleContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator(i1, i4, i2, i5, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ i4 = STACKTOP;
+ i3 = __ZN16b2BlockAllocator8AllocateEi(i3, 144) | 0;
+ if ((i3 | 0) == 0) {
+  i5 = 0;
+  STACKTOP = i4;
+  return i5 | 0;
+ }
+ __ZN9b2ContactC2EP9b2FixtureiS1_i(i3, i1, 0, i2, 0);
+ HEAP32[i3 >> 2] = 4984;
+ if ((HEAP32[(HEAP32[(HEAP32[i3 + 48 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) != 2) {
+  ___assert_fail(5e3, 5048, 41, 5104);
+ }
+ if ((HEAP32[(HEAP32[(HEAP32[i3 + 52 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) == 0) {
+  i5 = i3;
+  STACKTOP = i4;
+  return i5 | 0;
+ } else {
+  ___assert_fail(5136, 5048, 42, 5104);
+ }
+ return 0;
+}
+function __ZN23b2EdgeAndPolygonContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator(i1, i4, i2, i5, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ i4 = STACKTOP;
+ i3 = __ZN16b2BlockAllocator8AllocateEi(i3, 144) | 0;
+ if ((i3 | 0) == 0) {
+  i5 = 0;
+  STACKTOP = i4;
+  return i5 | 0;
+ }
+ __ZN9b2ContactC2EP9b2FixtureiS1_i(i3, i1, 0, i2, 0);
+ HEAP32[i3 >> 2] = 4736;
+ if ((HEAP32[(HEAP32[(HEAP32[i3 + 48 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) != 1) {
+  ___assert_fail(4752, 4800, 41, 4856);
+ }
+ if ((HEAP32[(HEAP32[(HEAP32[i3 + 52 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) == 2) {
+  i5 = i3;
+  STACKTOP = i4;
+  return i5 | 0;
+ } else {
+  ___assert_fail(4880, 4800, 42, 4856);
+ }
+ return 0;
+}
+function __ZN22b2EdgeAndCircleContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator(i1, i4, i2, i5, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ i4 = STACKTOP;
+ i3 = __ZN16b2BlockAllocator8AllocateEi(i3, 144) | 0;
+ if ((i3 | 0) == 0) {
+  i5 = 0;
+  STACKTOP = i4;
+  return i5 | 0;
+ }
+ __ZN9b2ContactC2EP9b2FixtureiS1_i(i3, i1, 0, i2, 0);
+ HEAP32[i3 >> 2] = 4488;
+ if ((HEAP32[(HEAP32[(HEAP32[i3 + 48 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) != 1) {
+  ___assert_fail(4504, 4552, 41, 4608);
+ }
+ if ((HEAP32[(HEAP32[(HEAP32[i3 + 52 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) == 0) {
+  i5 = i3;
+  STACKTOP = i4;
+  return i5 | 0;
+ } else {
+  ___assert_fail(4632, 4552, 42, 4608);
+ }
+ return 0;
+}
+function __ZN14b2PolygonShape8SetAsBoxEff(i1, d3, d2) {
+ i1 = i1 | 0;
+ d3 = +d3;
+ d2 = +d2;
+ var d4 = 0.0, d5 = 0.0;
+ HEAP32[i1 + 148 >> 2] = 4;
+ d4 = -d3;
+ d5 = -d2;
+ HEAPF32[i1 + 20 >> 2] = d4;
+ HEAPF32[i1 + 24 >> 2] = d5;
+ HEAPF32[i1 + 28 >> 2] = d3;
+ HEAPF32[i1 + 32 >> 2] = d5;
+ HEAPF32[i1 + 36 >> 2] = d3;
+ HEAPF32[i1 + 40 >> 2] = d2;
+ HEAPF32[i1 + 44 >> 2] = d4;
+ HEAPF32[i1 + 48 >> 2] = d2;
+ HEAPF32[i1 + 84 >> 2] = 0.0;
+ HEAPF32[i1 + 88 >> 2] = -1.0;
+ HEAPF32[i1 + 92 >> 2] = 1.0;
+ HEAPF32[i1 + 96 >> 2] = 0.0;
+ HEAPF32[i1 + 100 >> 2] = 0.0;
+ HEAPF32[i1 + 104 >> 2] = 1.0;
+ HEAPF32[i1 + 108 >> 2] = -1.0;
+ HEAPF32[i1 + 112 >> 2] = 0.0;
+ HEAPF32[i1 + 12 >> 2] = 0.0;
+ HEAPF32[i1 + 16 >> 2] = 0.0;
+ return;
+}
+function __ZN16b2PolygonContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator(i1, i4, i2, i5, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ i4 = STACKTOP;
+ i3 = __ZN16b2BlockAllocator8AllocateEi(i3, 144) | 0;
+ if ((i3 | 0) == 0) {
+  i5 = 0;
+  STACKTOP = i4;
+  return i5 | 0;
+ }
+ __ZN9b2ContactC2EP9b2FixtureiS1_i(i3, i1, 0, i2, 0);
+ HEAP32[i3 >> 2] = 5240;
+ if ((HEAP32[(HEAP32[(HEAP32[i3 + 48 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) != 2) {
+  ___assert_fail(5256, 5304, 44, 5352);
+ }
+ if ((HEAP32[(HEAP32[(HEAP32[i3 + 52 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) == 2) {
+  i5 = i3;
+  STACKTOP = i4;
+  return i5 | 0;
+ } else {
+  ___assert_fail(5376, 5304, 45, 5352);
+ }
+ return 0;
+}
+function __ZN15b2CircleContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator(i1, i4, i2, i5, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ i4 = STACKTOP;
+ i3 = __ZN16b2BlockAllocator8AllocateEi(i3, 144) | 0;
+ if ((i3 | 0) == 0) {
+  i5 = 0;
+  STACKTOP = i4;
+  return i5 | 0;
+ }
+ __ZN9b2ContactC2EP9b2FixtureiS1_i(i3, i1, 0, i2, 0);
+ HEAP32[i3 >> 2] = 6288;
+ if ((HEAP32[(HEAP32[(HEAP32[i3 + 48 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) != 0) {
+  ___assert_fail(6304, 6352, 44, 6400);
+ }
+ if ((HEAP32[(HEAP32[(HEAP32[i3 + 52 >> 2] | 0) + 12 >> 2] | 0) + 4 >> 2] | 0) == 0) {
+  i5 = i3;
+  STACKTOP = i4;
+  return i5 | 0;
+ } else {
+  ___assert_fail(6416, 6352, 45, 6400);
+ }
+ return 0;
+}
+function __ZN7b2World10CreateBodyEPK9b2BodyDef(i1, i4) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0, i5 = 0;
+ i2 = STACKTOP;
+ if ((HEAP32[i1 + 102868 >> 2] & 2 | 0) != 0) {
+  ___assert_fail(2160, 2184, 109, 2216);
+ }
+ i3 = __ZN16b2BlockAllocator8AllocateEi(i1, 152) | 0;
+ if ((i3 | 0) == 0) {
+  i3 = 0;
+ } else {
+  __ZN6b2BodyC2EPK9b2BodyDefP7b2World(i3, i4, i1);
+ }
+ HEAP32[i3 + 92 >> 2] = 0;
+ i4 = i1 + 102952 | 0;
+ HEAP32[i3 + 96 >> 2] = HEAP32[i4 >> 2];
+ i5 = HEAP32[i4 >> 2] | 0;
+ if ((i5 | 0) != 0) {
+  HEAP32[i5 + 92 >> 2] = i3;
+ }
+ HEAP32[i4 >> 2] = i3;
+ i5 = i1 + 102960 | 0;
+ HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + 1;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function __ZNK6b2Body13ShouldCollideEPKS_(i4, i2) {
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0;
+ i1 = STACKTOP;
+ if ((HEAP32[i4 >> 2] | 0) != 2 ? (HEAP32[i2 >> 2] | 0) != 2 : 0) {
+  i2 = 0;
+ } else {
+  i3 = 3;
+ }
+ L3 : do {
+  if ((i3 | 0) == 3) {
+   i3 = HEAP32[i4 + 108 >> 2] | 0;
+   if ((i3 | 0) == 0) {
+    i2 = 1;
+   } else {
+    while (1) {
+     if ((HEAP32[i3 >> 2] | 0) == (i2 | 0) ? (HEAP8[(HEAP32[i3 + 4 >> 2] | 0) + 61 | 0] | 0) == 0 : 0) {
+      i2 = 0;
+      break L3;
+     }
+     i3 = HEAP32[i3 + 12 >> 2] | 0;
+     if ((i3 | 0) == 0) {
+      i2 = 1;
+      break;
+     }
+    }
+   }
+  }
+ } while (0);
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function __ZNK14b2PolygonShape5CloneEP16b2BlockAllocator(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ i3 = __ZN16b2BlockAllocator8AllocateEi(i3, 152) | 0;
+ if ((i3 | 0) == 0) {
+  i3 = 0;
+ } else {
+  HEAP32[i3 >> 2] = 504;
+  HEAP32[i3 + 4 >> 2] = 2;
+  HEAPF32[i3 + 8 >> 2] = .009999999776482582;
+  HEAP32[i3 + 148 >> 2] = 0;
+  HEAPF32[i3 + 12 >> 2] = 0.0;
+  HEAPF32[i3 + 16 >> 2] = 0.0;
+ }
+ i6 = i1 + 4 | 0;
+ i5 = HEAP32[i6 + 4 >> 2] | 0;
+ i4 = i3 + 4 | 0;
+ HEAP32[i4 >> 2] = HEAP32[i6 >> 2];
+ HEAP32[i4 + 4 >> 2] = i5;
+ _memcpy(i3 + 12 | 0, i1 + 12 | 0, 140) | 0;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _memcpy(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ if ((i1 | 0) >= 4096) return _emscripten_memcpy_big(i3 | 0, i2 | 0, i1 | 0) | 0;
+ i4 = i3 | 0;
+ if ((i3 & 3) == (i2 & 3)) {
+  while (i3 & 3) {
+   if ((i1 | 0) == 0) return i4 | 0;
+   HEAP8[i3] = HEAP8[i2] | 0;
+   i3 = i3 + 1 | 0;
+   i2 = i2 + 1 | 0;
+   i1 = i1 - 1 | 0;
+  }
+  while ((i1 | 0) >= 4) {
+   HEAP32[i3 >> 2] = HEAP32[i2 >> 2];
+   i3 = i3 + 4 | 0;
+   i2 = i2 + 4 | 0;
+   i1 = i1 - 4 | 0;
+  }
+ }
+ while ((i1 | 0) > 0) {
+  HEAP8[i3] = HEAP8[i2] | 0;
+  i3 = i3 + 1 | 0;
+  i2 = i2 + 1 | 0;
+  i1 = i1 - 1 | 0;
+ }
+ return i4 | 0;
+}
+function __ZN7b2World16SetAllowSleepingEb(i2, i4) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i3 = 0;
+ i1 = STACKTOP;
+ i3 = i2 + 102976 | 0;
+ if ((i4 & 1 | 0) == (HEAPU8[i3] | 0 | 0)) {
+  STACKTOP = i1;
+  return;
+ }
+ HEAP8[i3] = i4 & 1;
+ if (i4) {
+  STACKTOP = i1;
+  return;
+ }
+ i2 = HEAP32[i2 + 102952 >> 2] | 0;
+ if ((i2 | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ do {
+  i3 = i2 + 4 | 0;
+  i4 = HEAPU16[i3 >> 1] | 0;
+  if ((i4 & 2 | 0) == 0) {
+   HEAP16[i3 >> 1] = i4 | 2;
+   HEAPF32[i2 + 144 >> 2] = 0.0;
+  }
+  i2 = HEAP32[i2 + 96 >> 2] | 0;
+ } while ((i2 | 0) != 0);
+ STACKTOP = i1;
+ return;
+}
+function __ZN16b2BlockAllocator4FreeEPvi(i3, i1, i4) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((i4 | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ if ((i4 | 0) <= 0) {
+  ___assert_fail(1376, 1312, 164, 1488);
+ }
+ if ((i4 | 0) > 640) {
+  __Z6b2FreePv(i1);
+  STACKTOP = i2;
+  return;
+ }
+ i4 = HEAP8[632 + i4 | 0] | 0;
+ if (!((i4 & 255) < 14)) {
+  ___assert_fail(1408, 1312, 173, 1488);
+ }
+ i4 = i3 + ((i4 & 255) << 2) + 12 | 0;
+ HEAP32[i1 >> 2] = HEAP32[i4 >> 2];
+ HEAP32[i4 >> 2] = i1;
+ STACKTOP = i2;
+ return;
+}
+function __ZN15b2ContactFilter13ShouldCollideEP9b2FixtureS1_(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ i3 = STACKTOP;
+ i4 = HEAP16[i2 + 36 >> 1] | 0;
+ if (!(i4 << 16 >> 16 != (HEAP16[i1 + 36 >> 1] | 0) | i4 << 16 >> 16 == 0)) {
+  i4 = i4 << 16 >> 16 > 0;
+  STACKTOP = i3;
+  return i4 | 0;
+ }
+ if ((HEAP16[i1 + 32 >> 1] & HEAP16[i2 + 34 >> 1]) << 16 >> 16 == 0) {
+  i4 = 0;
+  STACKTOP = i3;
+  return i4 | 0;
+ }
+ i4 = (HEAP16[i1 + 34 >> 1] & HEAP16[i2 + 32 >> 1]) << 16 >> 16 != 0;
+ STACKTOP = i3;
+ return i4 | 0;
+}
+function _memset(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = i1 + i3 | 0;
+ if ((i3 | 0) >= 20) {
+  i4 = i4 & 255;
+  i7 = i1 & 3;
+  i6 = i4 | i4 << 8 | i4 << 16 | i4 << 24;
+  i5 = i2 & ~3;
+  if (i7) {
+   i7 = i1 + 4 - i7 | 0;
+   while ((i1 | 0) < (i7 | 0)) {
+    HEAP8[i1] = i4;
+    i1 = i1 + 1 | 0;
+   }
+  }
+  while ((i1 | 0) < (i5 | 0)) {
+   HEAP32[i1 >> 2] = i6;
+   i1 = i1 + 4 | 0;
+  }
+ }
+ while ((i1 | 0) < (i2 | 0)) {
+  HEAP8[i1] = i4;
+  i1 = i1 + 1 | 0;
+ }
+ return i1 - i3 | 0;
+}
+function __ZN6b2Body13CreateFixtureEPK7b2Shapef(i1, i3, d2) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ d2 = +d2;
+ var i4 = 0, i5 = 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i5 = i4;
+ HEAP16[i5 + 22 >> 1] = 1;
+ HEAP16[i5 + 24 >> 1] = -1;
+ HEAP16[i5 + 26 >> 1] = 0;
+ HEAP32[i5 + 4 >> 2] = 0;
+ HEAPF32[i5 + 8 >> 2] = .20000000298023224;
+ HEAPF32[i5 + 12 >> 2] = 0.0;
+ HEAP8[i5 + 20 | 0] = 0;
+ HEAP32[i5 >> 2] = i3;
+ HEAPF32[i5 + 16 >> 2] = d2;
+ i3 = __ZN6b2Body13CreateFixtureEPK12b2FixtureDef(i1, i5) | 0;
+ STACKTOP = i4;
+ return i3 | 0;
+}
+function __Znwj(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0;
+ i1 = STACKTOP;
+ i2 = (i2 | 0) == 0 ? 1 : i2;
+ while (1) {
+  i3 = _malloc(i2) | 0;
+  if ((i3 | 0) != 0) {
+   i2 = 6;
+   break;
+  }
+  i3 = HEAP32[1914] | 0;
+  HEAP32[1914] = i3 + 0;
+  if ((i3 | 0) == 0) {
+   i2 = 5;
+   break;
+  }
+  FUNCTION_TABLE_v[i3 & 3]();
+ }
+ if ((i2 | 0) == 5) {
+  i3 = ___cxa_allocate_exception(4) | 0;
+  HEAP32[i3 >> 2] = 7672;
+  ___cxa_throw(i3 | 0, 7720, 30);
+ } else if ((i2 | 0) == 6) {
+  STACKTOP = i1;
+  return i3 | 0;
+ }
+ return 0;
+}
+function __ZN8b2IslandD2Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZN16b2StackAllocator4FreeEPv(HEAP32[i1 >> 2] | 0, HEAP32[i1 + 20 >> 2] | 0);
+ __ZN16b2StackAllocator4FreeEPv(HEAP32[i1 >> 2] | 0, HEAP32[i1 + 24 >> 2] | 0);
+ __ZN16b2StackAllocator4FreeEPv(HEAP32[i1 >> 2] | 0, HEAP32[i1 + 16 >> 2] | 0);
+ __ZN16b2StackAllocator4FreeEPv(HEAP32[i1 >> 2] | 0, HEAP32[i1 + 12 >> 2] | 0);
+ __ZN16b2StackAllocator4FreeEPv(HEAP32[i1 >> 2] | 0, HEAP32[i1 + 8 >> 2] | 0);
+ STACKTOP = i2;
+ return;
+}
+function __ZN16b2BlockAllocatorD2Ev(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i1 = STACKTOP;
+ i3 = i2 + 4 | 0;
+ i4 = HEAP32[i2 >> 2] | 0;
+ if ((HEAP32[i3 >> 2] | 0) > 0) {
+  i5 = 0;
+ } else {
+  i5 = i4;
+  __Z6b2FreePv(i5);
+  STACKTOP = i1;
+  return;
+ }
+ do {
+  __Z6b2FreePv(HEAP32[i4 + (i5 << 3) + 4 >> 2] | 0);
+  i5 = i5 + 1 | 0;
+  i4 = HEAP32[i2 >> 2] | 0;
+ } while ((i5 | 0) < (HEAP32[i3 >> 2] | 0));
+ __Z6b2FreePv(i4);
+ STACKTOP = i1;
+ return;
+}
+function copyTempDouble(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+ HEAP8[tempDoublePtr + 4 | 0] = HEAP8[i1 + 4 | 0];
+ HEAP8[tempDoublePtr + 5 | 0] = HEAP8[i1 + 5 | 0];
+ HEAP8[tempDoublePtr + 6 | 0] = HEAP8[i1 + 6 | 0];
+ HEAP8[tempDoublePtr + 7 | 0] = HEAP8[i1 + 7 | 0];
+}
+function __ZNK11b2EdgeShape11ComputeMassEP10b2MassDataf(i2, i1, d3) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ d3 = +d3;
+ var i4 = 0, d5 = 0.0;
+ i4 = STACKTOP;
+ HEAPF32[i1 >> 2] = 0.0;
+ d5 = +((+HEAPF32[i2 + 12 >> 2] + +HEAPF32[i2 + 20 >> 2]) * .5);
+ d3 = +((+HEAPF32[i2 + 16 >> 2] + +HEAPF32[i2 + 24 >> 2]) * .5);
+ i2 = i1 + 4 | 0;
+ HEAPF32[i2 >> 2] = d5;
+ HEAPF32[i2 + 4 >> 2] = d3;
+ HEAPF32[i1 + 12 >> 2] = 0.0;
+ STACKTOP = i4;
+ return;
+}
+function __ZN11b2EdgeShape3SetERK6b2Vec2S2_(i1, i3, i2) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i4 = 0, i5 = 0;
+ i5 = i3;
+ i3 = HEAP32[i5 + 4 >> 2] | 0;
+ i4 = i1 + 12 | 0;
+ HEAP32[i4 >> 2] = HEAP32[i5 >> 2];
+ HEAP32[i4 + 4 >> 2] = i3;
+ i4 = i2;
+ i2 = HEAP32[i4 + 4 >> 2] | 0;
+ i3 = i1 + 20 | 0;
+ HEAP32[i3 >> 2] = HEAP32[i4 >> 2];
+ HEAP32[i3 + 4 >> 2] = i2;
+ HEAP8[i1 + 44 | 0] = 0;
+ HEAP8[i1 + 45 | 0] = 0;
+ return;
+}
+function __ZN25b2PolygonAndCircleContact8EvaluateEP10b2ManifoldRK11b2TransformS4_(i2, i4, i3, i1) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i5 = 0;
+ i5 = STACKTOP;
+ __Z25b2CollidePolygonAndCircleP10b2ManifoldPK14b2PolygonShapeRK11b2TransformPK13b2CircleShapeS6_(i4, HEAP32[(HEAP32[i2 + 48 >> 2] | 0) + 12 >> 2] | 0, i3, HEAP32[(HEAP32[i2 + 52 >> 2] | 0) + 12 >> 2] | 0, i1);
+ STACKTOP = i5;
+ return;
+}
+function __ZN23b2EdgeAndPolygonContact8EvaluateEP10b2ManifoldRK11b2TransformS4_(i2, i4, i3, i1) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i5 = 0;
+ i5 = STACKTOP;
+ __Z23b2CollideEdgeAndPolygonP10b2ManifoldPK11b2EdgeShapeRK11b2TransformPK14b2PolygonShapeS6_(i4, HEAP32[(HEAP32[i2 + 48 >> 2] | 0) + 12 >> 2] | 0, i3, HEAP32[(HEAP32[i2 + 52 >> 2] | 0) + 12 >> 2] | 0, i1);
+ STACKTOP = i5;
+ return;
+}
+function __ZN22b2EdgeAndCircleContact8EvaluateEP10b2ManifoldRK11b2TransformS4_(i2, i4, i3, i1) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i5 = 0;
+ i5 = STACKTOP;
+ __Z22b2CollideEdgeAndCircleP10b2ManifoldPK11b2EdgeShapeRK11b2TransformPK13b2CircleShapeS6_(i4, HEAP32[(HEAP32[i2 + 48 >> 2] | 0) + 12 >> 2] | 0, i3, HEAP32[(HEAP32[i2 + 52 >> 2] | 0) + 12 >> 2] | 0, i1);
+ STACKTOP = i5;
+ return;
+}
+function __Z23b2CollideEdgeAndPolygonP10b2ManifoldPK11b2EdgeShapeRK11b2TransformPK14b2PolygonShapeS6_(i5, i4, i3, i2, i1) {
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i6 = 0;
+ i6 = STACKTOP;
+ STACKTOP = STACKTOP + 256 | 0;
+ __ZN12b2EPCollider7CollideEP10b2ManifoldPK11b2EdgeShapeRK11b2TransformPK14b2PolygonShapeS7_(i6, i5, i4, i3, i2, i1);
+ STACKTOP = i6;
+ return;
+}
+function __ZN16b2PolygonContact8EvaluateEP10b2ManifoldRK11b2TransformS4_(i2, i4, i3, i1) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i5 = 0;
+ i5 = STACKTOP;
+ __Z17b2CollidePolygonsP10b2ManifoldPK14b2PolygonShapeRK11b2TransformS3_S6_(i4, HEAP32[(HEAP32[i2 + 48 >> 2] | 0) + 12 >> 2] | 0, i3, HEAP32[(HEAP32[i2 + 52 >> 2] | 0) + 12 >> 2] | 0, i1);
+ STACKTOP = i5;
+ return;
+}
+function __ZN15b2CircleContact8EvaluateEP10b2ManifoldRK11b2TransformS4_(i2, i4, i3, i1) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i5 = 0;
+ i5 = STACKTOP;
+ __Z16b2CollideCirclesP10b2ManifoldPK13b2CircleShapeRK11b2TransformS3_S6_(i4, HEAP32[(HEAP32[i2 + 48 >> 2] | 0) + 12 >> 2] | 0, i3, HEAP32[(HEAP32[i2 + 52 >> 2] | 0) + 12 >> 2] | 0, i1);
+ STACKTOP = i5;
+ return;
+}
+function __Z14b2PairLessThanRK6b2PairS1_(i2, i5) {
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i3 = 0, i4 = 0;
+ i1 = STACKTOP;
+ i4 = HEAP32[i2 >> 2] | 0;
+ i3 = HEAP32[i5 >> 2] | 0;
+ if ((i4 | 0) >= (i3 | 0)) {
+  if ((i4 | 0) == (i3 | 0)) {
+   i2 = (HEAP32[i2 + 4 >> 2] | 0) < (HEAP32[i5 + 4 >> 2] | 0);
+  } else {
+   i2 = 0;
+  }
+ } else {
+  i2 = 1;
+ }
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function __ZN9b2FixtureC2Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ HEAP16[i1 + 32 >> 1] = 1;
+ HEAP16[i1 + 34 >> 1] = -1;
+ HEAP16[i1 + 36 >> 1] = 0;
+ HEAP32[i1 + 40 >> 2] = 0;
+ HEAP32[i1 + 24 >> 2] = 0;
+ HEAP32[i1 + 28 >> 2] = 0;
+ HEAP32[i1 + 0 >> 2] = 0;
+ HEAP32[i1 + 4 >> 2] = 0;
+ HEAP32[i1 + 8 >> 2] = 0;
+ HEAP32[i1 + 12 >> 2] = 0;
+ STACKTOP = i2;
+ return;
+}
+function __ZN12b2BroadPhaseC2Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZN13b2DynamicTreeC2Ev(i1);
+ HEAP32[i1 + 28 >> 2] = 0;
+ HEAP32[i1 + 48 >> 2] = 16;
+ HEAP32[i1 + 52 >> 2] = 0;
+ HEAP32[i1 + 44 >> 2] = __Z7b2Alloci(192) | 0;
+ HEAP32[i1 + 36 >> 2] = 16;
+ HEAP32[i1 + 40 >> 2] = 0;
+ HEAP32[i1 + 32 >> 2] = __Z7b2Alloci(64) | 0;
+ STACKTOP = i2;
+ return;
+}
+function __ZN16b2StackAllocatorD2Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((HEAP32[i1 + 102400 >> 2] | 0) != 0) {
+  ___assert_fail(3792, 3808, 32, 3848);
+ }
+ if ((HEAP32[i1 + 102796 >> 2] | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ } else {
+  ___assert_fail(3872, 3808, 33, 3848);
+ }
+}
+function __ZN15b2ContactSolverD2Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = i1 + 32 | 0;
+ __ZN16b2StackAllocator4FreeEPv(HEAP32[i3 >> 2] | 0, HEAP32[i1 + 40 >> 2] | 0);
+ __ZN16b2StackAllocator4FreeEPv(HEAP32[i3 >> 2] | 0, HEAP32[i1 + 36 >> 2] | 0);
+ STACKTOP = i2;
+ return;
+}
+function __ZN25b2PolygonAndCircleContact7DestroyEP9b2ContactP16b2BlockAllocator(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ FUNCTION_TABLE_vi[HEAP32[(HEAP32[i1 >> 2] | 0) + 4 >> 2] & 31](i1);
+ __ZN16b2BlockAllocator4FreeEPvi(i2, i1, 144);
+ STACKTOP = i3;
+ return;
+}
+function __ZN24b2ChainAndPolygonContact7DestroyEP9b2ContactP16b2BlockAllocator(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ FUNCTION_TABLE_vi[HEAP32[(HEAP32[i1 >> 2] | 0) + 4 >> 2] & 31](i1);
+ __ZN16b2BlockAllocator4FreeEPvi(i2, i1, 144);
+ STACKTOP = i3;
+ return;
+}
+function __ZN23b2EdgeAndPolygonContact7DestroyEP9b2ContactP16b2BlockAllocator(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ FUNCTION_TABLE_vi[HEAP32[(HEAP32[i1 >> 2] | 0) + 4 >> 2] & 31](i1);
+ __ZN16b2BlockAllocator4FreeEPvi(i2, i1, 144);
+ STACKTOP = i3;
+ return;
+}
+function __ZN23b2ChainAndCircleContact7DestroyEP9b2ContactP16b2BlockAllocator(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ FUNCTION_TABLE_vi[HEAP32[(HEAP32[i1 >> 2] | 0) + 4 >> 2] & 31](i1);
+ __ZN16b2BlockAllocator4FreeEPvi(i2, i1, 144);
+ STACKTOP = i3;
+ return;
+}
+function __ZN22b2EdgeAndCircleContact7DestroyEP9b2ContactP16b2BlockAllocator(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ FUNCTION_TABLE_vi[HEAP32[(HEAP32[i1 >> 2] | 0) + 4 >> 2] & 31](i1);
+ __ZN16b2BlockAllocator4FreeEPvi(i2, i1, 144);
+ STACKTOP = i3;
+ return;
+}
+function __ZN16b2ContactManagerC2Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZN12b2BroadPhaseC2Ev(i1);
+ HEAP32[i1 + 60 >> 2] = 0;
+ HEAP32[i1 + 64 >> 2] = 0;
+ HEAP32[i1 + 68 >> 2] = 1888;
+ HEAP32[i1 + 72 >> 2] = 1896;
+ HEAP32[i1 + 76 >> 2] = 0;
+ STACKTOP = i2;
+ return;
+}
+function __ZN16b2PolygonContact7DestroyEP9b2ContactP16b2BlockAllocator(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ FUNCTION_TABLE_vi[HEAP32[(HEAP32[i1 >> 2] | 0) + 4 >> 2] & 31](i1);
+ __ZN16b2BlockAllocator4FreeEPvi(i2, i1, 144);
+ STACKTOP = i3;
+ return;
+}
+function __ZN15b2CircleContact7DestroyEP9b2ContactP16b2BlockAllocator(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ FUNCTION_TABLE_vi[HEAP32[(HEAP32[i1 >> 2] | 0) + 4 >> 2] & 31](i1);
+ __ZN16b2BlockAllocator4FreeEPvi(i2, i1, 144);
+ STACKTOP = i3;
+ return;
+}
+function dynCall_viiiiii(i7, i6, i5, i4, i3, i2, i1) {
+ i7 = i7 | 0;
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ FUNCTION_TABLE_viiiiii[i7 & 3](i6 | 0, i5 | 0, i4 | 0, i3 | 0, i2 | 0, i1 | 0);
+}
+function copyTempFloat(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+}
+function dynCall_iiiiii(i6, i5, i4, i3, i2, i1) {
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ return FUNCTION_TABLE_iiiiii[i6 & 15](i5 | 0, i4 | 0, i3 | 0, i2 | 0, i1 | 0) | 0;
+}
+function dynCall_viiiii(i6, i5, i4, i3, i2, i1) {
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ FUNCTION_TABLE_viiiii[i6 & 3](i5 | 0, i4 | 0, i3 | 0, i2 | 0, i1 | 0);
+}
+function __ZN16b2ContactManager15FindNewContactsEv(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZN12b2BroadPhase11UpdatePairsI16b2ContactManagerEEvPT_(i1, i1);
+ STACKTOP = i2;
+ return;
+}
+function __ZN16b2StackAllocatorC2Ev(i1) {
+ i1 = i1 | 0;
+ HEAP32[i1 + 102400 >> 2] = 0;
+ HEAP32[i1 + 102404 >> 2] = 0;
+ HEAP32[i1 + 102408 >> 2] = 0;
+ HEAP32[i1 + 102796 >> 2] = 0;
+ return;
+}
+function dynCall_viiii(i5, i4, i3, i2, i1) {
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ FUNCTION_TABLE_viiii[i5 & 15](i4 | 0, i3 | 0, i2 | 0, i1 | 0);
+}
+function dynCall_iiii(i4, i3, i2, i1) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ return FUNCTION_TABLE_iiii[i4 & 7](i3 | 0, i2 | 0, i1 | 0) | 0;
+}
+function dynCall_viii(i4, i3, i2, i1) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ FUNCTION_TABLE_viii[i4 & 3](i3 | 0, i2 | 0, i1 | 0);
+}
+function __ZNSt9bad_allocD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZNSt9exceptionD2Ev(i1 | 0);
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function stackAlloc(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + i1 | 0;
+ STACKTOP = STACKTOP + 7 & -8;
+ return i2 | 0;
+}
+function __ZN13b2DynamicTreeD2Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __Z6b2FreePv(HEAP32[i1 + 4 >> 2] | 0);
+ STACKTOP = i2;
+ return;
+}
+function dynCall_viid(i4, i3, i2, d1) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ d1 = +d1;
+ FUNCTION_TABLE_viid[i4 & 3](i3 | 0, i2 | 0, +d1);
+}
+function __ZN17b2ContactListener9PostSolveEP9b2ContactPK16b2ContactImpulse(i1, i2, i3) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ return;
+}
+function __ZN10__cxxabiv120__si_class_type_infoD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function __ZN10__cxxabiv117__class_type_infoD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function __ZNSt9bad_allocD2Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZNSt9exceptionD2Ev(i1 | 0);
+ STACKTOP = i2;
+ return;
+}
+function dynCall_iii(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ return FUNCTION_TABLE_iii[i3 & 3](i2 | 0, i1 | 0) | 0;
+}
+function b8(i1, i2, i3, i4, i5, i6) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ abort(8);
+}
+function __ZN25b2PolygonAndCircleContactD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function __ZN17b2ContactListener8PreSolveEP9b2ContactPK10b2Manifold(i1, i2, i3) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ return;
+}
+function __ZN24b2ChainAndPolygonContactD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function __ZN23b2EdgeAndPolygonContactD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function __ZN23b2ChainAndCircleContactD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function __ZNK11b2EdgeShape9TestPointERK11b2TransformRK6b2Vec2(i1, i2, i3) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ return 0;
+}
+function __ZN22b2EdgeAndCircleContactD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function __ZdlPv(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((i1 | 0) != 0) {
+  _free(i1);
+ }
+ STACKTOP = i2;
+ return;
+}
+function b10(i1, i2, i3, i4, i5) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ abort(10);
+ return 0;
+}
+function _strlen(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = i1;
+ while (HEAP8[i2] | 0) {
+  i2 = i2 + 1 | 0;
+ }
+ return i2 - i1 | 0;
+}
+function __Z7b2Alloci(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i1 = _malloc(i1) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function setThrew(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ if ((__THREW__ | 0) == 0) {
+  __THREW__ = i1;
+  threwValue = i2;
+ }
+}
+function __ZN17b2ContactListenerD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function __ZN16b2PolygonContactD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function dynCall_vii(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ FUNCTION_TABLE_vii[i3 & 15](i2 | 0, i1 | 0);
+}
+function __ZN15b2ContactFilterD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function __ZN15b2CircleContactD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function __ZN14b2PolygonShapeD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function __Znaj(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i1 = __Znwj(i1) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function __ZN11b2EdgeShapeD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function __ZN9b2ContactD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function b1(i1, i2, i3, i4, i5) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ abort(1);
+}
+function __Z6b2FreePv(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _free(i1);
+ STACKTOP = i2;
+ return;
+}
+function ___clang_call_terminate(i1) {
+ i1 = i1 | 0;
+ ___cxa_begin_catch(i1 | 0) | 0;
+ __ZSt9terminatev();
+}
+function __ZN17b2ContactListener12BeginContactEP9b2Contact(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ return;
+}
+function dynCall_ii(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ return FUNCTION_TABLE_ii[i2 & 3](i1 | 0) | 0;
+}
+function __ZN17b2ContactListener10EndContactEP9b2Contact(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ return;
+}
+function b11(i1, i2, i3, i4) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ abort(11);
+}
+function dynCall_vi(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ FUNCTION_TABLE_vi[i2 & 31](i1 | 0);
+}
+function b0(i1, i2, i3) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ abort(0);
+ return 0;
+}
+function __ZNK10__cxxabiv116__shim_type_info5noop2Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function __ZNK10__cxxabiv116__shim_type_info5noop1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function b5(i1, i2, i3) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ abort(5);
+}
+function __ZNK14b2PolygonShape13GetChildCountEv(i1) {
+ i1 = i1 | 0;
+ return 1;
+}
+function __ZN10__cxxabiv116__shim_type_infoD2Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function b7(i1, i2, d3) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ d3 = +d3;
+ abort(7);
+}
+function __ZNK11b2EdgeShape13GetChildCountEv(i1) {
+ i1 = i1 | 0;
+ return 1;
+}
+function __ZNK7b2Timer15GetMillisecondsEv(i1) {
+ i1 = i1 | 0;
+ return 0.0;
+}
+function __ZN25b2PolygonAndCircleContactD1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function __ZN24b2ChainAndPolygonContactD1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function b9(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ abort(9);
+ return 0;
+}
+function __ZN23b2EdgeAndPolygonContactD1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function __ZN23b2ChainAndCircleContactD1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function __ZN22b2EdgeAndCircleContactD1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function dynCall_v(i1) {
+ i1 = i1 | 0;
+ FUNCTION_TABLE_v[i1 & 3]();
+}
+function __ZNKSt9bad_alloc4whatEv(i1) {
+ i1 = i1 | 0;
+ return 7688;
+}
+function ___cxa_pure_virtual__wrapper() {
+ ___cxa_pure_virtual();
+}
+function __ZN17b2ContactListenerD1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function __ZN16b2PolygonContactD1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function __ZN15b2ContactFilterD1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function __ZN15b2CircleContactD1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function __ZN14b2PolygonShapeD1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function b3(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ abort(3);
+}
+function runPostSets() {
+ HEAP32[1932] = __ZTISt9exception;
+}
+function __ZN11b2EdgeShapeD1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function __ZNSt9type_infoD2Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function __ZN7b2Timer5ResetEv(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function stackRestore(i1) {
+ i1 = i1 | 0;
+ STACKTOP = i1;
+}
+function setTempRet9(i1) {
+ i1 = i1 | 0;
+ tempRet9 = i1;
+}
+function setTempRet8(i1) {
+ i1 = i1 | 0;
+ tempRet8 = i1;
+}
+function setTempRet7(i1) {
+ i1 = i1 | 0;
+ tempRet7 = i1;
+}
+function setTempRet6(i1) {
+ i1 = i1 | 0;
+ tempRet6 = i1;
+}
+function setTempRet5(i1) {
+ i1 = i1 | 0;
+ tempRet5 = i1;
+}
+function setTempRet4(i1) {
+ i1 = i1 | 0;
+ tempRet4 = i1;
+}
+function setTempRet3(i1) {
+ i1 = i1 | 0;
+ tempRet3 = i1;
+}
+function setTempRet2(i1) {
+ i1 = i1 | 0;
+ tempRet2 = i1;
+}
+function setTempRet1(i1) {
+ i1 = i1 | 0;
+ tempRet1 = i1;
+}
+function setTempRet0(i1) {
+ i1 = i1 | 0;
+ tempRet0 = i1;
+}
+function __ZN9b2ContactD1Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function __ZN7b2TimerC2Ev(i1) {
+ i1 = i1 | 0;
+ return;
+}
+function b4(i1) {
+ i1 = i1 | 0;
+ abort(4);
+ return 0;
+}
+function stackSave() {
+ return STACKTOP | 0;
+}
+function b2(i1) {
+ i1 = i1 | 0;
+ abort(2);
+}
+function b6() {
+ abort(6);
+}
+
+// EMSCRIPTEN_END_FUNCS
+  var FUNCTION_TABLE_iiii = [b0,__ZNK11b2EdgeShape9TestPointERK11b2TransformRK6b2Vec2,__ZNK14b2PolygonShape9TestPointERK11b2TransformRK6b2Vec2,__ZN15b2ContactFilter13ShouldCollideEP9b2FixtureS1_,__ZNK10__cxxabiv117__class_type_info9can_catchEPKNS_16__shim_type_infoERPv,b0,b0,b0];
+  var FUNCTION_TABLE_viiiii = [b1,__ZNK10__cxxabiv117__class_type_info16search_below_dstEPNS_19__dynamic_cast_infoEPKvib,__ZNK10__cxxabiv120__si_class_type_info16search_below_dstEPNS_19__dynamic_cast_infoEPKvib,b1];
+  var FUNCTION_TABLE_vi = [b2,__ZN11b2EdgeShapeD1Ev,__ZN11b2EdgeShapeD0Ev,__ZN14b2PolygonShapeD1Ev,__ZN14b2PolygonShapeD0Ev,__ZN17b2ContactListenerD1Ev,__ZN17b2ContactListenerD0Ev,__ZN15b2ContactFilterD1Ev,__ZN15b2ContactFilterD0Ev,__ZN9b2ContactD1Ev,__ZN9b2ContactD0Ev,__ZN22b2EdgeAndCircleContactD1Ev,__ZN22b2EdgeAndCircleContactD0Ev,__ZN23b2EdgeAndPolygonContactD1Ev,__ZN23b2EdgeAndPolygonContactD0Ev,__ZN25b2PolygonAndCircleContactD1Ev,__ZN25b2PolygonAndCircleContactD0Ev,__ZN16b2PolygonContactD1Ev,__ZN16b2PolygonContactD0Ev,__ZN23b2ChainAndCircleContactD1Ev,__ZN23b2ChainAndCircleContactD0Ev,__ZN24b2ChainAndPolygonContactD1Ev,__ZN24b2ChainAndPolygonContactD0Ev,__ZN15b2CircleContactD1Ev,__ZN15b2CircleContactD0Ev,__ZN10__cxxabiv116__shim_type_infoD2Ev,__ZN10__cxxabiv117__class_type_infoD0Ev,__ZNK10__cxxabiv116__shim_type_info5noop1Ev,__ZNK10__cxxabiv116__shim_type_info5noop2Ev
+  ,__ZN10__cxxabiv120__si_class_type_infoD0Ev,__ZNSt9bad_allocD2Ev,__ZNSt9bad_allocD0Ev];
+  var FUNCTION_TABLE_vii = [b3,__ZN17b2ContactListener12BeginContactEP9b2Contact,__ZN17b2ContactListener10EndContactEP9b2Contact,__ZN15b2CircleContact7DestroyEP9b2ContactP16b2BlockAllocator,__ZN25b2PolygonAndCircleContact7DestroyEP9b2ContactP16b2BlockAllocator,__ZN16b2PolygonContact7DestroyEP9b2ContactP16b2BlockAllocator,__ZN22b2EdgeAndCircleContact7DestroyEP9b2ContactP16b2BlockAllocator,__ZN23b2EdgeAndPolygonContact7DestroyEP9b2ContactP16b2BlockAllocator,__ZN23b2ChainAndCircleContact7DestroyEP9b2ContactP16b2BlockAllocator,__ZN24b2ChainAndPolygonContact7DestroyEP9b2ContactP16b2BlockAllocator,b3,b3,b3,b3,b3,b3];
+  var FUNCTION_TABLE_ii = [b4,__ZNK11b2EdgeShape13GetChildCountEv,__ZNK14b2PolygonShape13GetChildCountEv,__ZNKSt9bad_alloc4whatEv];
+  var FUNCTION_TABLE_viii = [b5,__ZN17b2ContactListener8PreSolveEP9b2ContactPK10b2Manifold,__ZN17b2ContactListener9PostSolveEP9b2ContactPK16b2ContactImpulse,b5];
+  var FUNCTION_TABLE_v = [b6,___cxa_pure_virtual__wrapper,__Z4iterv,b6];
+  var FUNCTION_TABLE_viid = [b7,__ZNK11b2EdgeShape11ComputeMassEP10b2MassDataf,__ZNK14b2PolygonShape11ComputeMassEP10b2MassDataf,b7];
+  var FUNCTION_TABLE_viiiiii = [b8,__ZNK10__cxxabiv117__class_type_info16search_above_dstEPNS_19__dynamic_cast_infoEPKvS4_ib,__ZNK10__cxxabiv120__si_class_type_info16search_above_dstEPNS_19__dynamic_cast_infoEPKvS4_ib,b8];
+  var FUNCTION_TABLE_iii = [b9,__ZNK11b2EdgeShape5CloneEP16b2BlockAllocator,__ZNK14b2PolygonShape5CloneEP16b2BlockAllocator,__Z14b2PairLessThanRK6b2PairS1_];
+  var FUNCTION_TABLE_iiiiii = [b10,__ZNK11b2EdgeShape7RayCastEP15b2RayCastOutputRK14b2RayCastInputRK11b2Transformi,__ZNK14b2PolygonShape7RayCastEP15b2RayCastOutputRK14b2RayCastInputRK11b2Transformi,__ZN15b2CircleContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator,__ZN25b2PolygonAndCircleContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator,__ZN16b2PolygonContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator,__ZN22b2EdgeAndCircleContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator,__ZN23b2EdgeAndPolygonContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator,__ZN23b2ChainAndCircleContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator,__ZN24b2ChainAndPolygonContact6CreateEP9b2FixtureiS1_iP16b2BlockAllocator,b10,b10,b10,b10,b10,b10];
+  var FUNCTION_TABLE_viiii = [b11,__ZNK11b2EdgeShape11ComputeAABBEP6b2AABBRK11b2Transformi,__ZNK14b2PolygonShape11ComputeAABBEP6b2AABBRK11b2Transformi,__ZN22b2EdgeAndCircleContact8EvaluateEP10b2ManifoldRK11b2TransformS4_,__ZN23b2EdgeAndPolygonContact8EvaluateEP10b2ManifoldRK11b2TransformS4_,__ZN25b2PolygonAndCircleContact8EvaluateEP10b2ManifoldRK11b2TransformS4_,__ZN16b2PolygonContact8EvaluateEP10b2ManifoldRK11b2TransformS4_,__ZN23b2ChainAndCircleContact8EvaluateEP10b2ManifoldRK11b2TransformS4_,__ZN24b2ChainAndPolygonContact8EvaluateEP10b2ManifoldRK11b2TransformS4_,__ZN15b2CircleContact8EvaluateEP10b2ManifoldRK11b2TransformS4_,__ZNK10__cxxabiv117__class_type_info27has_unambiguous_public_baseEPNS_19__dynamic_cast_infoEPvi,__ZNK10__cxxabiv120__si_class_type_info27has_unambiguous_public_baseEPNS_19__dynamic_cast_infoEPvi,b11,b11,b11,b11];
+
+  return { _strlen: _strlen, _free: _free, _main: _main, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, setTempRet1: setTempRet1, setTempRet2: setTempRet2, setTempRet3: setTempRet3, setTempRet4: setTempRet4, setTempRet5: setTempRet5, setTempRet6: setTempRet6, setTempRet7: setTempRet7, setTempRet8: setTempRet8, setTempRet9: setTempRet9, dynCall_iiii: dynCall_iiii, dynCall_viiiii: dynCall_viiiii, dynCall_vi: dynCall_vi, dynCall_vii: dynCall_vii, dynCall_ii: dynCall_ii, dynCall_viii: dynCall_viii, dynCall_v: dynCall_v, dynCall_viid: dynCall_viid, dynCall_viiiiii: dynCall_viiiiii, dynCall_iii: dynCall_iii, dynCall_iiiiii: dynCall_iiiiii, dynCall_viiii: dynCall_viiii };
+})
+// EMSCRIPTEN_END_ASM
+({ "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array }, { "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "invoke_iiii": invoke_iiii, "invoke_viiiii": invoke_viiiii, "invoke_vi": invoke_vi, "invoke_vii": invoke_vii, "invoke_ii": invoke_ii, "invoke_viii": invoke_viii, "invoke_v": invoke_v, "invoke_viid": invoke_viid, "invoke_viiiiii": invoke_viiiiii, "invoke_iii": invoke_iii, "invoke_iiiiii": invoke_iiiiii, "invoke_viiii": invoke_viiii, "___cxa_throw": ___cxa_throw, "_emscripten_run_script": _emscripten_run_script, "_cosf": _cosf, "_send": _send, "__ZSt9terminatev": __ZSt9terminatev, "__reallyNegative": __reallyNegative, "___cxa_is_number_type": ___cxa_is_number_type, "___assert_fail": ___assert_fail, "___cxa_allocate_exception": ___cxa_allocate_exception, "___cxa_find_matching_catch": ___cxa_find_matching_catch, "_fflush": _fflush, "_pwrite": _pwrite, "___setErrNo": ___setErrNo, "_sbrk": _sbrk, "___cxa_begin_catch": ___cxa_begin_catch, "_sinf": _sinf, "_fileno": _fileno, "___resumeException": ___resumeException, "__ZSt18uncaught_exceptionv": __ZSt18uncaught_exceptionv, "_sysconf": _sysconf, "_clock": _clock, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_puts": _puts, "_mkport": _mkport, "_floorf": _floorf, "_sqrtf": _sqrtf, "_write": _write, "_emscripten_set_main_loop": _emscripten_set_main_loop, "___errno_location": ___errno_location, "__ZNSt9exceptionD2Ev": __ZNSt9exceptionD2Ev, "_printf": _printf, "___cxa_does_inherit": ___cxa_does_inherit, "__exit": __exit, "_fputc": _fputc, "_abort": _abort, "_fwrite": _fwrite, "_time": _time, "_fprintf": _fprintf, "_emscripten_cancel_main_loop": _emscripten_cancel_main_loop, "__formatString": __formatString, "_fputs": _fputs, "_exit": _exit, "___cxa_pure_virtual": ___cxa_pure_virtual, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "NaN": NaN, "Infinity": Infinity, "__ZTISt9exception": __ZTISt9exception }, buffer);
+var _strlen = Module["_strlen"] = asm["_strlen"];
+var _free = Module["_free"] = asm["_free"];
+var _main = Module["_main"] = asm["_main"];
+var _memset = Module["_memset"] = asm["_memset"];
+var _malloc = Module["_malloc"] = asm["_malloc"];
+var _memcpy = Module["_memcpy"] = asm["_memcpy"];
+var runPostSets = Module["runPostSets"] = asm["runPostSets"];
+var dynCall_iiii = Module["dynCall_iiii"] = asm["dynCall_iiii"];
+var dynCall_viiiii = Module["dynCall_viiiii"] = asm["dynCall_viiiii"];
+var dynCall_vi = Module["dynCall_vi"] = asm["dynCall_vi"];
+var dynCall_vii = Module["dynCall_vii"] = asm["dynCall_vii"];
+var dynCall_ii = Module["dynCall_ii"] = asm["dynCall_ii"];
+var dynCall_viii = Module["dynCall_viii"] = asm["dynCall_viii"];
+var dynCall_v = Module["dynCall_v"] = asm["dynCall_v"];
+var dynCall_viid = Module["dynCall_viid"] = asm["dynCall_viid"];
+var dynCall_viiiiii = Module["dynCall_viiiiii"] = asm["dynCall_viiiiii"];
+var dynCall_iii = Module["dynCall_iii"] = asm["dynCall_iii"];
+var dynCall_iiiiii = Module["dynCall_iiiiii"] = asm["dynCall_iiiiii"];
+var dynCall_viiii = Module["dynCall_viiii"] = asm["dynCall_viiii"];
+
+Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
+Runtime.stackSave = function() { return asm['stackSave']() };
+Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
+
+
+// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included
+var i64Math = null;
+
+// === Auto-generated postamble setup entry stuff ===
+
+if (memoryInitializer) {
+  if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
+    var data = Module['readBinary'](memoryInitializer);
+    HEAPU8.set(data, STATIC_BASE);
+  } else {
+    addRunDependency('memory initializer');
+    Browser.asyncLoad(memoryInitializer, function(data) {
+      HEAPU8.set(data, STATIC_BASE);
+      removeRunDependency('memory initializer');
+    }, function(data) {
+      throw 'could not load memory initializer ' + memoryInitializer;
+    });
+  }
+}
+
+function ExitStatus(status) {
+  this.name = "ExitStatus";
+  this.message = "Program terminated with exit(" + status + ")";
+  this.status = status;
+};
+ExitStatus.prototype = new Error();
+ExitStatus.prototype.constructor = ExitStatus;
+
+var initialStackTop;
+var preloadStartTime = null;
+var calledMain = false;
+
+dependenciesFulfilled = function runCaller() {
+  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
+  if (!Module['calledRun'] && shouldRunNow) run([].concat(Module["arguments"]));
+  if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
+}
+
+Module['callMain'] = Module.callMain = function callMain(args) {
+  assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
+  assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
+
+  args = args || [];
+
+  ensureInitRuntime();
+
+  var argc = args.length+1;
+  function pad() {
+    for (var i = 0; i < 4-1; i++) {
+      argv.push(0);
+    }
+  }
+  var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ];
+  pad();
+  for (var i = 0; i < argc-1; i = i + 1) {
+    argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL));
+    pad();
+  }
+  argv.push(0);
+  argv = allocate(argv, 'i32', ALLOC_NORMAL);
+
+  initialStackTop = STACKTOP;
+
+  try {
+
+    var ret = Module['_main'](argc, argv, 0);
+
+
+    // if we're not running an evented main loop, it's time to exit
+    if (!Module['noExitRuntime']) {
+      exit(ret);
+    }
+  }
+  catch(e) {
+    if (e instanceof ExitStatus) {
+      // exit() throws this once it's done to make sure execution
+      // has been stopped completely
+      return;
+    } else if (e == 'SimulateInfiniteLoop') {
+      // running an evented main loop, don't immediately exit
+      Module['noExitRuntime'] = true;
+      return;
+    } else {
+      if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
+      throw e;
+    }
+  } finally {
+    calledMain = true;
+  }
+}
+
+
+
+
+function run(args) {
+  args = args || Module['arguments'];
+
+  if (preloadStartTime === null) preloadStartTime = Date.now();
+
+  if (runDependencies > 0) {
+    Module.printErr('run() called, but dependencies remain, so not running');
+    return;
+  }
+
+  preRun();
+
+  if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
+  if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
+
+  function doRun() {
+    if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
+    Module['calledRun'] = true;
+
+    ensureInitRuntime();
+
+    preMain();
+
+    if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
+      Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
+    }
+
+    if (Module['_main'] && shouldRunNow) {
+      Module['callMain'](args);
+    }
+
+    postRun();
+  }
+
+  if (Module['setStatus']) {
+    Module['setStatus']('Running...');
+    setTimeout(function() {
+      setTimeout(function() {
+        Module['setStatus']('');
+      }, 1);
+      if (!ABORT) doRun();
+    }, 1);
+  } else {
+    doRun();
+  }
+}
+Module['run'] = Module.run = run;
+
+function exit(status) {
+  ABORT = true;
+  EXITSTATUS = status;
+  STACKTOP = initialStackTop;
+
+  // exit the runtime
+  exitRuntime();
+
+  // TODO We should handle this differently based on environment.
+  // In the browser, the best we can do is throw an exception
+  // to halt execution, but in node we could process.exit and
+  // I'd imagine SM shell would have something equivalent.
+  // This would let us set a proper exit status (which
+  // would be great for checking test exit statuses).
+  // https://github.com/kripken/emscripten/issues/1371
+
+  // throw an exception to halt the current execution
+  throw new ExitStatus(status);
+}
+Module['exit'] = Module.exit = exit;
+
+function abort(text) {
+  if (text) {
+    Module.print(text);
+    Module.printErr(text);
+  }
+
+  ABORT = true;
+  EXITSTATUS = 1;
+
+  var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.';
+
+  throw 'abort() at ' + stackTrace() + extra;
+}
+Module['abort'] = Module.abort = abort;
+
+// {{PRE_RUN_ADDITIONS}}
+
+if (Module['preInit']) {
+  if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
+  while (Module['preInit'].length > 0) {
+    Module['preInit'].pop()();
+  }
+}
+
+// shouldRunNow refers to calling main(), not run().
+var shouldRunNow = true;
+if (Module['noInitialRun']) {
+  shouldRunNow = false;
+}
+
+
+run([].concat(Module["arguments"]));
diff --git a/test/mjsunit/asm/embenchen/copy.js b/test/mjsunit/asm/embenchen/copy.js
new file mode 100644
index 0000000..bf8d177
--- /dev/null
+++ b/test/mjsunit/asm/embenchen/copy.js
@@ -0,0 +1,5976 @@
+var EXPECTED_OUTPUT = 'sum:8930\n';
+var Module = {
+  arguments: [1],
+  print: function(x) {Module.printBuffer += x + '\n';},
+  preRun: [function() {Module.printBuffer = ''}],
+  postRun: [function() {
+    assertEquals(EXPECTED_OUTPUT, Module.printBuffer);
+  }],
+};
+// The Module object: Our interface to the outside world. We import
+// and export values on it, and do the work to get that through
+// closure compiler if necessary. There are various ways Module can be used:
+// 1. Not defined. We create it here
+// 2. A function parameter, function(Module) { ..generated code.. }
+// 3. pre-run appended it, var Module = {}; ..generated code..
+// 4. External script tag defines var Module.
+// We need to do an eval in order to handle the closure compiler
+// case, where this code here is minified but Module was defined
+// elsewhere (e.g. case 4 above). We also need to check if Module
+// already exists (e.g. case 3 above).
+// Note that if you want to run closure, and also to use Module
+// after the generated code, you will need to define   var Module = {};
+// before the code. Then that object will be used in the code, and you
+// can continue to use Module afterwards as well.
+var Module;
+if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {};
+
+// Sometimes an existing Module object exists with properties
+// meant to overwrite the default module functionality. Here
+// we collect those properties and reapply _after_ we configure
+// the current environment's defaults to avoid having to be so
+// defensive during initialization.
+var moduleOverrides = {};
+for (var key in Module) {
+  if (Module.hasOwnProperty(key)) {
+    moduleOverrides[key] = Module[key];
+  }
+}
+
+// The environment setup code below is customized to use Module.
+// *** Environment setup code ***
+var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
+var ENVIRONMENT_IS_WEB = typeof window === 'object';
+var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
+var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
+
+if (ENVIRONMENT_IS_NODE) {
+  // Expose functionality in the same simple way that the shells work
+  // Note that we pollute the global namespace here, otherwise we break in node
+  if (!Module['print']) Module['print'] = function print(x) {
+    process['stdout'].write(x + '\n');
+  };
+  if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+    process['stderr'].write(x + '\n');
+  };
+
+  var nodeFS = require('fs');
+  var nodePath = require('path');
+
+  Module['read'] = function read(filename, binary) {
+    filename = nodePath['normalize'](filename);
+    var ret = nodeFS['readFileSync'](filename);
+    // The path is absolute if the normalized version is the same as the resolved.
+    if (!ret && filename != nodePath['resolve'](filename)) {
+      filename = path.join(__dirname, '..', 'src', filename);
+      ret = nodeFS['readFileSync'](filename);
+    }
+    if (ret && !binary) ret = ret.toString();
+    return ret;
+  };
+
+  Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) };
+
+  Module['load'] = function load(f) {
+    globalEval(read(f));
+  };
+
+  Module['arguments'] = process['argv'].slice(2);
+
+  module['exports'] = Module;
+}
+else if (ENVIRONMENT_IS_SHELL) {
+  if (!Module['print']) Module['print'] = print;
+  if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
+
+  if (typeof read != 'undefined') {
+    Module['read'] = read;
+  } else {
+    Module['read'] = function read() { throw 'no read() available (jsc?)' };
+  }
+
+  Module['readBinary'] = function readBinary(f) {
+    return read(f, 'binary');
+  };
+
+  if (typeof scriptArgs != 'undefined') {
+    Module['arguments'] = scriptArgs;
+  } else if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  this['Module'] = Module;
+
+  eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly)
+}
+else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+  Module['read'] = function read(url) {
+    var xhr = new XMLHttpRequest();
+    xhr.open('GET', url, false);
+    xhr.send(null);
+    return xhr.responseText;
+  };
+
+  if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  if (typeof console !== 'undefined') {
+    if (!Module['print']) Module['print'] = function print(x) {
+      console.log(x);
+    };
+    if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+      console.log(x);
+    };
+  } else {
+    // Probably a worker, and without console.log. We can do very little here...
+    var TRY_USE_DUMP = false;
+    if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
+      dump(x);
+    }) : (function(x) {
+      // self.postMessage(x); // enable this if you want stdout to be sent as messages
+    }));
+  }
+
+  if (ENVIRONMENT_IS_WEB) {
+    window['Module'] = Module;
+  } else {
+    Module['load'] = importScripts;
+  }
+}
+else {
+  // Unreachable because SHELL is dependant on the others
+  throw 'Unknown runtime environment. Where are we?';
+}
+
+function globalEval(x) {
+  eval.call(null, x);
+}
+if (!Module['load'] == 'undefined' && Module['read']) {
+  Module['load'] = function load(f) {
+    globalEval(Module['read'](f));
+  };
+}
+if (!Module['print']) {
+  Module['print'] = function(){};
+}
+if (!Module['printErr']) {
+  Module['printErr'] = Module['print'];
+}
+if (!Module['arguments']) {
+  Module['arguments'] = [];
+}
+// *** Environment setup code ***
+
+// Closure helpers
+Module.print = Module['print'];
+Module.printErr = Module['printErr'];
+
+// Callbacks
+Module['preRun'] = [];
+Module['postRun'] = [];
+
+// Merge back in the overrides
+for (var key in moduleOverrides) {
+  if (moduleOverrides.hasOwnProperty(key)) {
+    Module[key] = moduleOverrides[key];
+  }
+}
+
+
+
+// === Auto-generated preamble library stuff ===
+
+//========================================
+// Runtime code shared with compiler
+//========================================
+
+var Runtime = {
+  stackSave: function () {
+    return STACKTOP;
+  },
+  stackRestore: function (stackTop) {
+    STACKTOP = stackTop;
+  },
+  forceAlign: function (target, quantum) {
+    quantum = quantum || 4;
+    if (quantum == 1) return target;
+    if (isNumber(target) && isNumber(quantum)) {
+      return Math.ceil(target/quantum)*quantum;
+    } else if (isNumber(quantum) && isPowerOfTwo(quantum)) {
+      return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')';
+    }
+    return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
+  },
+  isNumberType: function (type) {
+    return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
+  },
+  isPointerType: function isPointerType(type) {
+  return type[type.length-1] == '*';
+},
+  isStructType: function isStructType(type) {
+  if (isPointerType(type)) return false;
+  if (isArrayType(type)) return true;
+  if (/<?\{ ?[^}]* ?\}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types
+  // See comment in isStructPointerType()
+  return type[0] == '%';
+},
+  INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
+  FLOAT_TYPES: {"float":0,"double":0},
+  or64: function (x, y) {
+    var l = (x | 0) | (y | 0);
+    var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  and64: function (x, y) {
+    var l = (x | 0) & (y | 0);
+    var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  xor64: function (x, y) {
+    var l = (x | 0) ^ (y | 0);
+    var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  getNativeTypeSize: function (type) {
+    switch (type) {
+      case 'i1': case 'i8': return 1;
+      case 'i16': return 2;
+      case 'i32': return 4;
+      case 'i64': return 8;
+      case 'float': return 4;
+      case 'double': return 8;
+      default: {
+        if (type[type.length-1] === '*') {
+          return Runtime.QUANTUM_SIZE; // A pointer
+        } else if (type[0] === 'i') {
+          var bits = parseInt(type.substr(1));
+          assert(bits % 8 === 0);
+          return bits/8;
+        } else {
+          return 0;
+        }
+      }
+    }
+  },
+  getNativeFieldSize: function (type) {
+    return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE);
+  },
+  dedup: function dedup(items, ident) {
+  var seen = {};
+  if (ident) {
+    return items.filter(function(item) {
+      if (seen[item[ident]]) return false;
+      seen[item[ident]] = true;
+      return true;
+    });
+  } else {
+    return items.filter(function(item) {
+      if (seen[item]) return false;
+      seen[item] = true;
+      return true;
+    });
+  }
+},
+  set: function set() {
+  var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
+  var ret = {};
+  for (var i = 0; i < args.length; i++) {
+    ret[args[i]] = 0;
+  }
+  return ret;
+},
+  STACK_ALIGN: 8,
+  getAlignSize: function (type, size, vararg) {
+    // we align i64s and doubles on 64-bit boundaries, unlike x86
+    if (!vararg && (type == 'i64' || type == 'double')) return 8;
+    if (!type) return Math.min(size, 8); // align structures internally to 64 bits
+    return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE);
+  },
+  calculateStructAlignment: function calculateStructAlignment(type) {
+    type.flatSize = 0;
+    type.alignSize = 0;
+    var diffs = [];
+    var prev = -1;
+    var index = 0;
+    type.flatIndexes = type.fields.map(function(field) {
+      index++;
+      var size, alignSize;
+      if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
+        size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
+        alignSize = Runtime.getAlignSize(field, size);
+      } else if (Runtime.isStructType(field)) {
+        if (field[1] === '0') {
+          // this is [0 x something]. When inside another structure like here, it must be at the end,
+          // and it adds no size
+          // XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!');
+          size = 0;
+          if (Types.types[field]) {
+            alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+          } else {
+            alignSize = type.alignSize || QUANTUM_SIZE;
+          }
+        } else {
+          size = Types.types[field].flatSize;
+          alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+        }
+      } else if (field[0] == 'b') {
+        // bN, large number field, like a [N x i8]
+        size = field.substr(1)|0;
+        alignSize = 1;
+      } else if (field[0] === '<') {
+        // vector type
+        size = alignSize = Types.types[field].flatSize; // fully aligned
+      } else if (field[0] === 'i') {
+        // illegal integer field, that could not be legalized because it is an internal structure field
+        // it is ok to have such fields, if we just use them as markers of field size and nothing more complex
+        size = alignSize = parseInt(field.substr(1))/8;
+        assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field);
+      } else {
+        assert(false, 'invalid type for calculateStructAlignment');
+      }
+      if (type.packed) alignSize = 1;
+      type.alignSize = Math.max(type.alignSize, alignSize);
+      var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
+      type.flatSize = curr + size;
+      if (prev >= 0) {
+        diffs.push(curr-prev);
+      }
+      prev = curr;
+      return curr;
+    });
+    if (type.name_ && type.name_[0] === '[') {
+      // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
+      // allocating a potentially huge array for [999999 x i8] etc.
+      type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
+    }
+    type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
+    if (diffs.length == 0) {
+      type.flatFactor = type.flatSize;
+    } else if (Runtime.dedup(diffs).length == 1) {
+      type.flatFactor = diffs[0];
+    }
+    type.needsFlattening = (type.flatFactor != 1);
+    return type.flatIndexes;
+  },
+  generateStructInfo: function (struct, typeName, offset) {
+    var type, alignment;
+    if (typeName) {
+      offset = offset || 0;
+      type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
+      if (!type) return null;
+      if (type.fields.length != struct.length) {
+        printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo');
+        return null;
+      }
+      alignment = type.flatIndexes;
+    } else {
+      var type = { fields: struct.map(function(item) { return item[0] }) };
+      alignment = Runtime.calculateStructAlignment(type);
+    }
+    var ret = {
+      __size__: type.flatSize
+    };
+    if (typeName) {
+      struct.forEach(function(item, i) {
+        if (typeof item === 'string') {
+          ret[item] = alignment[i] + offset;
+        } else {
+          // embedded struct
+          var key;
+          for (var k in item) key = k;
+          ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
+        }
+      });
+    } else {
+      struct.forEach(function(item, i) {
+        ret[item[1]] = alignment[i];
+      });
+    }
+    return ret;
+  },
+  dynCall: function (sig, ptr, args) {
+    if (args && args.length) {
+      if (!args.splice) args = Array.prototype.slice.call(args);
+      args.splice(0, 0, ptr);
+      return Module['dynCall_' + sig].apply(null, args);
+    } else {
+      return Module['dynCall_' + sig].call(null, ptr);
+    }
+  },
+  functionPointers: [],
+  addFunction: function (func) {
+    for (var i = 0; i < Runtime.functionPointers.length; i++) {
+      if (!Runtime.functionPointers[i]) {
+        Runtime.functionPointers[i] = func;
+        return 2*(1 + i);
+      }
+    }
+    throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
+  },
+  removeFunction: function (index) {
+    Runtime.functionPointers[(index-2)/2] = null;
+  },
+  getAsmConst: function (code, numArgs) {
+    // code is a constant string on the heap, so we can cache these
+    if (!Runtime.asmConstCache) Runtime.asmConstCache = {};
+    var func = Runtime.asmConstCache[code];
+    if (func) return func;
+    var args = [];
+    for (var i = 0; i < numArgs; i++) {
+      args.push(String.fromCharCode(36) + i); // $0, $1 etc
+    }
+    var source = Pointer_stringify(code);
+    if (source[0] === '"') {
+      // tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct
+      if (source.indexOf('"', 1) === source.length-1) {
+        source = source.substr(1, source.length-2);
+      } else {
+        // something invalid happened, e.g. EM_ASM("..code($0)..", input)
+        abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)');
+      }
+    }
+    try {
+      var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node
+    } catch(e) {
+      Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)');
+      throw e;
+    }
+    return Runtime.asmConstCache[code] = evalled;
+  },
+  warnOnce: function (text) {
+    if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
+    if (!Runtime.warnOnce.shown[text]) {
+      Runtime.warnOnce.shown[text] = 1;
+      Module.printErr(text);
+    }
+  },
+  funcWrappers: {},
+  getFuncWrapper: function (func, sig) {
+    assert(sig);
+    if (!Runtime.funcWrappers[func]) {
+      Runtime.funcWrappers[func] = function dynCall_wrapper() {
+        return Runtime.dynCall(sig, func, arguments);
+      };
+    }
+    return Runtime.funcWrappers[func];
+  },
+  UTF8Processor: function () {
+    var buffer = [];
+    var needed = 0;
+    this.processCChar = function (code) {
+      code = code & 0xFF;
+
+      if (buffer.length == 0) {
+        if ((code & 0x80) == 0x00) {        // 0xxxxxxx
+          return String.fromCharCode(code);
+        }
+        buffer.push(code);
+        if ((code & 0xE0) == 0xC0) {        // 110xxxxx
+          needed = 1;
+        } else if ((code & 0xF0) == 0xE0) { // 1110xxxx
+          needed = 2;
+        } else {                            // 11110xxx
+          needed = 3;
+        }
+        return '';
+      }
+
+      if (needed) {
+        buffer.push(code);
+        needed--;
+        if (needed > 0) return '';
+      }
+
+      var c1 = buffer[0];
+      var c2 = buffer[1];
+      var c3 = buffer[2];
+      var c4 = buffer[3];
+      var ret;
+      if (buffer.length == 2) {
+        ret = String.fromCharCode(((c1 & 0x1F) << 6)  | (c2 & 0x3F));
+      } else if (buffer.length == 3) {
+        ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6)  | (c3 & 0x3F));
+      } else {
+        // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+        var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
+                        ((c3 & 0x3F) << 6)  | (c4 & 0x3F);
+        ret = String.fromCharCode(
+          Math.floor((codePoint - 0x10000) / 0x400) + 0xD800,
+          (codePoint - 0x10000) % 0x400 + 0xDC00);
+      }
+      buffer.length = 0;
+      return ret;
+    }
+    this.processJSString = function processJSString(string) {
+      /* TODO: use TextEncoder when present,
+        var encoder = new TextEncoder();
+        encoder['encoding'] = "utf-8";
+        var utf8Array = encoder['encode'](aMsg.data);
+      */
+      string = unescape(encodeURIComponent(string));
+      var ret = [];
+      for (var i = 0; i < string.length; i++) {
+        ret.push(string.charCodeAt(i));
+      }
+      return ret;
+    }
+  },
+  getCompilerSetting: function (name) {
+    throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work';
+  },
+  stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+7)&-8); return ret; },
+  staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = (((STATICTOP)+7)&-8); return ret; },
+  dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = (((DYNAMICTOP)+7)&-8); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; },
+  alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; },
+  makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*(+4294967296))) : ((+((low>>>0)))+((+((high|0)))*(+4294967296)))); return ret; },
+  GLOBAL_BASE: 8,
+  QUANTUM_SIZE: 4,
+  __dummy__: 0
+}
+
+
+Module['Runtime'] = Runtime;
+
+
+
+
+
+
+
+
+
+//========================================
+// Runtime essentials
+//========================================
+
+var __THREW__ = 0; // Used in checking for thrown exceptions.
+
+var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort()
+var EXITSTATUS = 0;
+
+var undef = 0;
+// tempInt is used for 32-bit signed values or smaller. tempBigInt is used
+// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt
+var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat;
+var tempI64, tempI64b;
+var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9;
+
+function assert(condition, text) {
+  if (!condition) {
+    abort('Assertion failed: ' + text);
+  }
+}
+
+var globalScope = this;
+
+// C calling interface. A convenient way to call C functions (in C files, or
+// defined with extern "C").
+//
+// Note: LLVM optimizations can inline and remove functions, after which you will not be
+//       able to call them. Closure can also do so. To avoid that, add your function to
+//       the exports using something like
+//
+//         -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]'
+//
+// @param ident      The name of the C function (note that C++ functions will be name-mangled - use extern "C")
+// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and
+//                   'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit).
+// @param argTypes   An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType,
+//                   except that 'array' is not possible (there is no way for us to know the length of the array)
+// @param args       An array of the arguments to the function, as native JS values (as in returnType)
+//                   Note that string arguments will be stored on the stack (the JS string will become a C string on the stack).
+// @return           The return value, as a native JS value (as in returnType)
+function ccall(ident, returnType, argTypes, args) {
+  return ccallFunc(getCFunc(ident), returnType, argTypes, args);
+}
+Module["ccall"] = ccall;
+
+// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
+function getCFunc(ident) {
+  try {
+    var func = Module['_' + ident]; // closure exported function
+    if (!func) func = eval('_' + ident); // explicit lookup
+  } catch(e) {
+  }
+  assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)');
+  return func;
+}
+
+// Internal function that does a C call using a function, not an identifier
+function ccallFunc(func, returnType, argTypes, args) {
+  var stack = 0;
+  function toC(value, type) {
+    if (type == 'string') {
+      if (value === null || value === undefined || value === 0) return 0; // null string
+      value = intArrayFromString(value);
+      type = 'array';
+    }
+    if (type == 'array') {
+      if (!stack) stack = Runtime.stackSave();
+      var ret = Runtime.stackAlloc(value.length);
+      writeArrayToMemory(value, ret);
+      return ret;
+    }
+    return value;
+  }
+  function fromC(value, type) {
+    if (type == 'string') {
+      return Pointer_stringify(value);
+    }
+    assert(type != 'array');
+    return value;
+  }
+  var i = 0;
+  var cArgs = args ? args.map(function(arg) {
+    return toC(arg, argTypes[i++]);
+  }) : [];
+  var ret = fromC(func.apply(null, cArgs), returnType);
+  if (stack) Runtime.stackRestore(stack);
+  return ret;
+}
+
+// Returns a native JS wrapper for a C function. This is similar to ccall, but
+// returns a function you can call repeatedly in a normal way. For example:
+//
+//   var my_function = cwrap('my_c_function', 'number', ['number', 'number']);
+//   alert(my_function(5, 22));
+//   alert(my_function(99, 12));
+//
+function cwrap(ident, returnType, argTypes) {
+  var func = getCFunc(ident);
+  return function() {
+    return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments));
+  }
+}
+Module["cwrap"] = cwrap;
+
+// Sets a value in memory in a dynamic way at run-time. Uses the
+// type data. This is the same as makeSetValue, except that
+// makeSetValue is done at compile-time and generates the needed
+// code then, whereas this function picks the right code at
+// run-time.
+// Note that setValue and getValue only do *aligned* writes and reads!
+// Note that ccall uses JS types as for defining types, while setValue and
+// getValue need LLVM types ('i8', 'i32') - this is a lower-level operation
+function setValue(ptr, value, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': HEAP8[(ptr)]=value; break;
+      case 'i8': HEAP8[(ptr)]=value; break;
+      case 'i16': HEAP16[((ptr)>>1)]=value; break;
+      case 'i32': HEAP32[((ptr)>>2)]=value; break;
+      case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= (+1) ? (tempDouble > (+0) ? ((Math_min((+(Math_floor((tempDouble)/(+4294967296)))), (+4294967295)))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/(+4294967296))))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
+      case 'float': HEAPF32[((ptr)>>2)]=value; break;
+      case 'double': HEAPF64[((ptr)>>3)]=value; break;
+      default: abort('invalid type for setValue: ' + type);
+    }
+}
+Module['setValue'] = setValue;
+
+// Parallel to setValue.
+function getValue(ptr, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': return HEAP8[(ptr)];
+      case 'i8': return HEAP8[(ptr)];
+      case 'i16': return HEAP16[((ptr)>>1)];
+      case 'i32': return HEAP32[((ptr)>>2)];
+      case 'i64': return HEAP32[((ptr)>>2)];
+      case 'float': return HEAPF32[((ptr)>>2)];
+      case 'double': return HEAPF64[((ptr)>>3)];
+      default: abort('invalid type for setValue: ' + type);
+    }
+  return null;
+}
+Module['getValue'] = getValue;
+
+var ALLOC_NORMAL = 0; // Tries to use _malloc()
+var ALLOC_STACK = 1; // Lives for the duration of the current function call
+var ALLOC_STATIC = 2; // Cannot be freed
+var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
+var ALLOC_NONE = 4; // Do not allocate
+Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
+Module['ALLOC_STACK'] = ALLOC_STACK;
+Module['ALLOC_STATIC'] = ALLOC_STATIC;
+Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
+Module['ALLOC_NONE'] = ALLOC_NONE;
+
+// allocate(): This is for internal use. You can use it yourself as well, but the interface
+//             is a little tricky (see docs right below). The reason is that it is optimized
+//             for multiple syntaxes to save space in generated code. So you should
+//             normally not use allocate(), and instead allocate memory using _malloc(),
+//             initialize it with setValue(), and so forth.
+// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
+//        in *bytes* (note that this is sometimes confusing: the next parameter does not
+//        affect this!)
+// @types: Either an array of types, one for each byte (or 0 if no type at that position),
+//         or a single type which is used for the entire block. This only matters if there
+//         is initial data - if @slab is a number, then this does not matter at all and is
+//         ignored.
+// @allocator: How to allocate memory, see ALLOC_*
+function allocate(slab, types, allocator, ptr) {
+  var zeroinit, size;
+  if (typeof slab === 'number') {
+    zeroinit = true;
+    size = slab;
+  } else {
+    zeroinit = false;
+    size = slab.length;
+  }
+
+  var singleType = typeof types === 'string' ? types : null;
+
+  var ret;
+  if (allocator == ALLOC_NONE) {
+    ret = ptr;
+  } else {
+    ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
+  }
+
+  if (zeroinit) {
+    var ptr = ret, stop;
+    assert((ret & 3) == 0);
+    stop = ret + (size & ~3);
+    for (; ptr < stop; ptr += 4) {
+      HEAP32[((ptr)>>2)]=0;
+    }
+    stop = ret + size;
+    while (ptr < stop) {
+      HEAP8[((ptr++)|0)]=0;
+    }
+    return ret;
+  }
+
+  if (singleType === 'i8') {
+    if (slab.subarray || slab.slice) {
+      HEAPU8.set(slab, ret);
+    } else {
+      HEAPU8.set(new Uint8Array(slab), ret);
+    }
+    return ret;
+  }
+
+  var i = 0, type, typeSize, previousType;
+  while (i < size) {
+    var curr = slab[i];
+
+    if (typeof curr === 'function') {
+      curr = Runtime.getFunctionIndex(curr);
+    }
+
+    type = singleType || types[i];
+    if (type === 0) {
+      i++;
+      continue;
+    }
+
+    if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
+
+    setValue(ret+i, curr, type);
+
+    // no need to look up size unless type changes, so cache it
+    if (previousType !== type) {
+      typeSize = Runtime.getNativeTypeSize(type);
+      previousType = type;
+    }
+    i += typeSize;
+  }
+
+  return ret;
+}
+Module['allocate'] = allocate;
+
+function Pointer_stringify(ptr, /* optional */ length) {
+  // TODO: use TextDecoder
+  // Find the length, and check for UTF while doing so
+  var hasUtf = false;
+  var t;
+  var i = 0;
+  while (1) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    if (t >= 128) hasUtf = true;
+    else if (t == 0 && !length) break;
+    i++;
+    if (length && i == length) break;
+  }
+  if (!length) length = i;
+
+  var ret = '';
+
+  if (!hasUtf) {
+    var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack
+    var curr;
+    while (length > 0) {
+      curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
+      ret = ret ? ret + curr : curr;
+      ptr += MAX_CHUNK;
+      length -= MAX_CHUNK;
+    }
+    return ret;
+  }
+
+  var utf8 = new Runtime.UTF8Processor();
+  for (i = 0; i < length; i++) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    ret += utf8.processCChar(t);
+  }
+  return ret;
+}
+Module['Pointer_stringify'] = Pointer_stringify;
+
+// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF16ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
+    if (codeUnit == 0)
+      return str;
+    ++i;
+    // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
+    str += String.fromCharCode(codeUnit);
+  }
+}
+Module['UTF16ToString'] = UTF16ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF16LE form. The copy will require at most (str.length*2+1)*2 bytes of space in the HEAP.
+function stringToUTF16(str, outPtr) {
+  for(var i = 0; i < str.length; ++i) {
+    // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
+    var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
+    HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP16[(((outPtr)+(str.length*2))>>1)]=0;
+}
+Module['stringToUTF16'] = stringToUTF16;
+
+// Given a pointer 'ptr' to a null-terminated UTF32LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF32ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
+    if (utf32 == 0)
+      return str;
+    ++i;
+    // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
+    if (utf32 >= 0x10000) {
+      var ch = utf32 - 0x10000;
+      str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
+    } else {
+      str += String.fromCharCode(utf32);
+    }
+  }
+}
+Module['UTF32ToString'] = UTF32ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF32LE form. The copy will require at most (str.length+1)*4 bytes of space in the HEAP,
+// but can use less, since str.length does not return the number of characters in the string, but the number of UTF-16 code units in the string.
+function stringToUTF32(str, outPtr) {
+  var iChar = 0;
+  for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) {
+    // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
+    var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate
+    if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
+      var trailSurrogate = str.charCodeAt(++iCodeUnit);
+      codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
+    }
+    HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit;
+    ++iChar;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP32[(((outPtr)+(iChar*4))>>2)]=0;
+}
+Module['stringToUTF32'] = stringToUTF32;
+
+function demangle(func) {
+  var i = 3;
+  // params, etc.
+  var basicTypes = {
+    'v': 'void',
+    'b': 'bool',
+    'c': 'char',
+    's': 'short',
+    'i': 'int',
+    'l': 'long',
+    'f': 'float',
+    'd': 'double',
+    'w': 'wchar_t',
+    'a': 'signed char',
+    'h': 'unsigned char',
+    't': 'unsigned short',
+    'j': 'unsigned int',
+    'm': 'unsigned long',
+    'x': 'long long',
+    'y': 'unsigned long long',
+    'z': '...'
+  };
+  var subs = [];
+  var first = true;
+  function dump(x) {
+    //return;
+    if (x) Module.print(x);
+    Module.print(func);
+    var pre = '';
+    for (var a = 0; a < i; a++) pre += ' ';
+    Module.print (pre + '^');
+  }
+  function parseNested() {
+    i++;
+    if (func[i] === 'K') i++; // ignore const
+    var parts = [];
+    while (func[i] !== 'E') {
+      if (func[i] === 'S') { // substitution
+        i++;
+        var next = func.indexOf('_', i);
+        var num = func.substring(i, next) || 0;
+        parts.push(subs[num] || '?');
+        i = next+1;
+        continue;
+      }
+      if (func[i] === 'C') { // constructor
+        parts.push(parts[parts.length-1]);
+        i += 2;
+        continue;
+      }
+      var size = parseInt(func.substr(i));
+      var pre = size.toString().length;
+      if (!size || !pre) { i--; break; } // counter i++ below us
+      var curr = func.substr(i + pre, size);
+      parts.push(curr);
+      subs.push(curr);
+      i += pre + size;
+    }
+    i++; // skip E
+    return parts;
+  }
+  function parse(rawList, limit, allowVoid) { // main parser
+    limit = limit || Infinity;
+    var ret = '', list = [];
+    function flushList() {
+      return '(' + list.join(', ') + ')';
+    }
+    var name;
+    if (func[i] === 'N') {
+      // namespaced N-E
+      name = parseNested().join('::');
+      limit--;
+      if (limit === 0) return rawList ? [name] : name;
+    } else {
+      // not namespaced
+      if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L'
+      var size = parseInt(func.substr(i));
+      if (size) {
+        var pre = size.toString().length;
+        name = func.substr(i + pre, size);
+        i += pre + size;
+      }
+    }
+    first = false;
+    if (func[i] === 'I') {
+      i++;
+      var iList = parse(true);
+      var iRet = parse(true, 1, true);
+      ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>';
+    } else {
+      ret = name;
+    }
+    paramLoop: while (i < func.length && limit-- > 0) {
+      //dump('paramLoop');
+      var c = func[i++];
+      if (c in basicTypes) {
+        list.push(basicTypes[c]);
+      } else {
+        switch (c) {
+          case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer
+          case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference
+          case 'L': { // literal
+            i++; // skip basic type
+            var end = func.indexOf('E', i);
+            var size = end - i;
+            list.push(func.substr(i, size));
+            i += size + 2; // size + 'EE'
+            break;
+          }
+          case 'A': { // array
+            var size = parseInt(func.substr(i));
+            i += size.toString().length;
+            if (func[i] !== '_') throw '?';
+            i++; // skip _
+            list.push(parse(true, 1, true)[0] + ' [' + size + ']');
+            break;
+          }
+          case 'E': break paramLoop;
+          default: ret += '?' + c; break paramLoop;
+        }
+      }
+    }
+    if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void)
+    if (rawList) {
+      if (ret) {
+        list.push(ret + '?');
+      }
+      return list;
+    } else {
+      return ret + flushList();
+    }
+  }
+  try {
+    // Special-case the entry point, since its name differs from other name mangling.
+    if (func == 'Object._main' || func == '_main') {
+      return 'main()';
+    }
+    if (typeof func === 'number') func = Pointer_stringify(func);
+    if (func[0] !== '_') return func;
+    if (func[1] !== '_') return func; // C function
+    if (func[2] !== 'Z') return func;
+    switch (func[3]) {
+      case 'n': return 'operator new()';
+      case 'd': return 'operator delete()';
+    }
+    return parse();
+  } catch(e) {
+    return func;
+  }
+}
+
+function demangleAll(text) {
+  return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') });
+}
+
+function stackTrace() {
+  var stack = new Error().stack;
+  return stack ? demangleAll(stack) : '(no stack trace available)'; // Stack trace is not available at least on IE10 and Safari 6.
+}
+
+// Memory management
+
+var PAGE_SIZE = 4096;
+function alignMemoryPage(x) {
+  return (x+4095)&-4096;
+}
+
+var HEAP;
+var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
+
+var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area
+var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area
+var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk
+
+function enlargeMemory() {
+  abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
+}
+
+var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880;
+var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 134217728;
+var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152;
+
+var totalMemory = 4096;
+while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) {
+  if (totalMemory < 16*1024*1024) {
+    totalMemory *= 2;
+  } else {
+    totalMemory += 16*1024*1024
+  }
+}
+if (totalMemory !== TOTAL_MEMORY) {
+  Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be more reasonable');
+  TOTAL_MEMORY = totalMemory;
+}
+
+// Initialize the runtime's memory
+// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
+assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
+       'JS engine does not provide full typed array support');
+
+var buffer = new ArrayBuffer(TOTAL_MEMORY);
+HEAP8 = new Int8Array(buffer);
+HEAP16 = new Int16Array(buffer);
+HEAP32 = new Int32Array(buffer);
+HEAPU8 = new Uint8Array(buffer);
+HEAPU16 = new Uint16Array(buffer);
+HEAPU32 = new Uint32Array(buffer);
+HEAPF32 = new Float32Array(buffer);
+HEAPF64 = new Float64Array(buffer);
+
+// Endianness check (note: assumes compiler arch was little-endian)
+HEAP32[0] = 255;
+assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
+
+Module['HEAP'] = HEAP;
+Module['HEAP8'] = HEAP8;
+Module['HEAP16'] = HEAP16;
+Module['HEAP32'] = HEAP32;
+Module['HEAPU8'] = HEAPU8;
+Module['HEAPU16'] = HEAPU16;
+Module['HEAPU32'] = HEAPU32;
+Module['HEAPF32'] = HEAPF32;
+Module['HEAPF64'] = HEAPF64;
+
+function callRuntimeCallbacks(callbacks) {
+  while(callbacks.length > 0) {
+    var callback = callbacks.shift();
+    if (typeof callback == 'function') {
+      callback();
+      continue;
+    }
+    var func = callback.func;
+    if (typeof func === 'number') {
+      if (callback.arg === undefined) {
+        Runtime.dynCall('v', func);
+      } else {
+        Runtime.dynCall('vi', func, [callback.arg]);
+      }
+    } else {
+      func(callback.arg === undefined ? null : callback.arg);
+    }
+  }
+}
+
+var __ATPRERUN__  = []; // functions called before the runtime is initialized
+var __ATINIT__    = []; // functions called during startup
+var __ATMAIN__    = []; // functions called when main() is to be run
+var __ATEXIT__    = []; // functions called during shutdown
+var __ATPOSTRUN__ = []; // functions called after the runtime has exited
+
+var runtimeInitialized = false;
+
+function preRun() {
+  // compatibility - merge in anything from Module['preRun'] at this time
+  if (Module['preRun']) {
+    if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
+    while (Module['preRun'].length) {
+      addOnPreRun(Module['preRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPRERUN__);
+}
+
+function ensureInitRuntime() {
+  if (runtimeInitialized) return;
+  runtimeInitialized = true;
+  callRuntimeCallbacks(__ATINIT__);
+}
+
+function preMain() {
+  callRuntimeCallbacks(__ATMAIN__);
+}
+
+function exitRuntime() {
+  callRuntimeCallbacks(__ATEXIT__);
+}
+
+function postRun() {
+  // compatibility - merge in anything from Module['postRun'] at this time
+  if (Module['postRun']) {
+    if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
+    while (Module['postRun'].length) {
+      addOnPostRun(Module['postRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPOSTRUN__);
+}
+
+function addOnPreRun(cb) {
+  __ATPRERUN__.unshift(cb);
+}
+Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun;
+
+function addOnInit(cb) {
+  __ATINIT__.unshift(cb);
+}
+Module['addOnInit'] = Module.addOnInit = addOnInit;
+
+function addOnPreMain(cb) {
+  __ATMAIN__.unshift(cb);
+}
+Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain;
+
+function addOnExit(cb) {
+  __ATEXIT__.unshift(cb);
+}
+Module['addOnExit'] = Module.addOnExit = addOnExit;
+
+function addOnPostRun(cb) {
+  __ATPOSTRUN__.unshift(cb);
+}
+Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun;
+
+// Tools
+
+// This processes a JS string into a C-line array of numbers, 0-terminated.
+// For LLVM-originating strings, see parser.js:parseLLVMString function
+function intArrayFromString(stringy, dontAddNull, length /* optional */) {
+  var ret = (new Runtime.UTF8Processor()).processJSString(stringy);
+  if (length) {
+    ret.length = length;
+  }
+  if (!dontAddNull) {
+    ret.push(0);
+  }
+  return ret;
+}
+Module['intArrayFromString'] = intArrayFromString;
+
+function intArrayToString(array) {
+  var ret = [];
+  for (var i = 0; i < array.length; i++) {
+    var chr = array[i];
+    if (chr > 0xFF) {
+      chr &= 0xFF;
+    }
+    ret.push(String.fromCharCode(chr));
+  }
+  return ret.join('');
+}
+Module['intArrayToString'] = intArrayToString;
+
+// Write a Javascript array to somewhere in the heap
+function writeStringToMemory(string, buffer, dontAddNull) {
+  var array = intArrayFromString(string, dontAddNull);
+  var i = 0;
+  while (i < array.length) {
+    var chr = array[i];
+    HEAP8[(((buffer)+(i))|0)]=chr;
+    i = i + 1;
+  }
+}
+Module['writeStringToMemory'] = writeStringToMemory;
+
+function writeArrayToMemory(array, buffer) {
+  for (var i = 0; i < array.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=array[i];
+  }
+}
+Module['writeArrayToMemory'] = writeArrayToMemory;
+
+function writeAsciiToMemory(str, buffer, dontAddNull) {
+  for (var i = 0; i < str.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=str.charCodeAt(i);
+  }
+  if (!dontAddNull) HEAP8[(((buffer)+(str.length))|0)]=0;
+}
+Module['writeAsciiToMemory'] = writeAsciiToMemory;
+
+function unSign(value, bits, ignore) {
+  if (value >= 0) {
+    return value;
+  }
+  return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
+                    : Math.pow(2, bits)         + value;
+}
+function reSign(value, bits, ignore) {
+  if (value <= 0) {
+    return value;
+  }
+  var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
+                        : Math.pow(2, bits-1);
+  if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
+                                                       // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
+                                                       // TODO: In i64 mode 1, resign the two parts separately and safely
+    value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
+  }
+  return value;
+}
+
+// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
+if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) {
+  var ah  = a >>> 16;
+  var al = a & 0xffff;
+  var bh  = b >>> 16;
+  var bl = b & 0xffff;
+  return (al*bl + ((ah*bl + al*bh) << 16))|0;
+};
+Math.imul = Math['imul'];
+
+
+var Math_abs = Math.abs;
+var Math_cos = Math.cos;
+var Math_sin = Math.sin;
+var Math_tan = Math.tan;
+var Math_acos = Math.acos;
+var Math_asin = Math.asin;
+var Math_atan = Math.atan;
+var Math_atan2 = Math.atan2;
+var Math_exp = Math.exp;
+var Math_log = Math.log;
+var Math_sqrt = Math.sqrt;
+var Math_ceil = Math.ceil;
+var Math_floor = Math.floor;
+var Math_pow = Math.pow;
+var Math_imul = Math.imul;
+var Math_fround = Math.fround;
+var Math_min = Math.min;
+
+// A counter of dependencies for calling run(). If we need to
+// do asynchronous work before running, increment this and
+// decrement it. Incrementing must happen in a place like
+// PRE_RUN_ADDITIONS (used by emcc to add file preloading).
+// Note that you can add dependencies in preRun, even though
+// it happens right before run - run will be postponed until
+// the dependencies are met.
+var runDependencies = 0;
+var runDependencyWatcher = null;
+var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
+
+function addRunDependency(id) {
+  runDependencies++;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+}
+Module['addRunDependency'] = addRunDependency;
+function removeRunDependency(id) {
+  runDependencies--;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+  if (runDependencies == 0) {
+    if (runDependencyWatcher !== null) {
+      clearInterval(runDependencyWatcher);
+      runDependencyWatcher = null;
+    }
+    if (dependenciesFulfilled) {
+      var callback = dependenciesFulfilled;
+      dependenciesFulfilled = null;
+      callback(); // can add another dependenciesFulfilled
+    }
+  }
+}
+Module['removeRunDependency'] = removeRunDependency;
+
+Module["preloadedImages"] = {}; // maps url to image data
+Module["preloadedAudios"] = {}; // maps url to audio data
+
+
+var memoryInitializer = null;
+
+// === Body ===
+
+
+
+
+
+STATIC_BASE = 8;
+
+STATICTOP = STATIC_BASE + Runtime.alignMemory(27);
+/* global initializers */ __ATINIT__.push();
+
+
+/* memory initializer */ allocate([101,114,114,111,114,58,32,37,100,92,110,0,0,0,0,0,115,117,109,58,37,100,10,0], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE);
+
+
+
+
+var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);
+
+assert(tempDoublePtr % 8 == 0);
+
+function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+}
+
+function copyTempDouble(ptr) {
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+  HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];
+
+  HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];
+
+  HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];
+
+  HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];
+
+}
+
+
+  function _malloc(bytes) {
+      /* Over-allocate to make sure it is byte-aligned by 8.
+       * This will leak memory, but this is only the dummy
+       * implementation (replaced by dlmalloc normally) so
+       * not an issue.
+       */
+      var ptr = Runtime.dynamicAlloc(bytes + 8);
+      return (ptr+8) & 0xFFFFFFF8;
+    }
+  Module["_malloc"] = _malloc;
+
+
+
+
+  var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};
+
+  var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can   access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};
+
+
+  var ___errno_state=0;function ___setErrNo(value) {
+      // For convenient setting and returning of errno.
+      HEAP32[((___errno_state)>>2)]=value;
+      return value;
+    }
+
+  var TTY={ttys:[],init:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // currently, FS.init does not distinguish if process.stdin is a file or TTY
+        //   // device, it always assumes it's a TTY device. because of this, we're forcing
+        //   // process.stdin to UTF8 encoding to at least make stdin reading compatible
+        //   // with text files until FS.init can be refactored.
+        //   process['stdin']['setEncoding']('utf8');
+        // }
+      },shutdown:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
+        //   // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
+        //   // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
+        //   // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
+        //   // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
+        //   process['stdin']['pause']();
+        // }
+      },register:function (dev, ops) {
+        TTY.ttys[dev] = { input: [], output: [], ops: ops };
+        FS.registerDevice(dev, TTY.stream_ops);
+      },stream_ops:{open:function (stream) {
+          var tty = TTY.ttys[stream.node.rdev];
+          if (!tty) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          stream.tty = tty;
+          stream.seekable = false;
+        },close:function (stream) {
+          // flush any pending line data
+          if (stream.tty.output.length) {
+            stream.tty.ops.put_char(stream.tty, 10);
+          }
+        },read:function (stream, buffer, offset, length, pos /* ignored */) {
+          if (!stream.tty || !stream.tty.ops.get_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          var bytesRead = 0;
+          for (var i = 0; i < length; i++) {
+            var result;
+            try {
+              result = stream.tty.ops.get_char(stream.tty);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            if (result === undefined && bytesRead === 0) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+            if (result === null || result === undefined) break;
+            bytesRead++;
+            buffer[offset+i] = result;
+          }
+          if (bytesRead) {
+            stream.node.timestamp = Date.now();
+          }
+          return bytesRead;
+        },write:function (stream, buffer, offset, length, pos) {
+          if (!stream.tty || !stream.tty.ops.put_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          for (var i = 0; i < length; i++) {
+            try {
+              stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+          }
+          if (length) {
+            stream.node.timestamp = Date.now();
+          }
+          return i;
+        }},default_tty_ops:{get_char:function (tty) {
+          if (!tty.input.length) {
+            var result = null;
+            if (ENVIRONMENT_IS_NODE) {
+              result = process['stdin']['read']();
+              if (!result) {
+                if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) {
+                  return null;  // EOF
+                }
+                return undefined;  // no data available
+              }
+            } else if (typeof window != 'undefined' &&
+              typeof window.prompt == 'function') {
+              // Browser.
+              result = window.prompt('Input: ');  // returns null on cancel
+              if (result !== null) {
+                result += '\n';
+              }
+            } else if (typeof readline == 'function') {
+              // Command line.
+              result = readline();
+              if (result !== null) {
+                result += '\n';
+              }
+            }
+            if (!result) {
+              return null;
+            }
+            tty.input = intArrayFromString(result, true);
+          }
+          return tty.input.shift();
+        },put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['print'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }},default_tty1_ops:{put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['printErr'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }}};
+
+  var MEMFS={ops_table:null,CONTENT_OWNING:1,CONTENT_FLEXIBLE:2,CONTENT_FIXED:3,mount:function (mount) {
+        return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
+          // no supported
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (!MEMFS.ops_table) {
+          MEMFS.ops_table = {
+            dir: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                lookup: MEMFS.node_ops.lookup,
+                mknod: MEMFS.node_ops.mknod,
+                rename: MEMFS.node_ops.rename,
+                unlink: MEMFS.node_ops.unlink,
+                rmdir: MEMFS.node_ops.rmdir,
+                readdir: MEMFS.node_ops.readdir,
+                symlink: MEMFS.node_ops.symlink
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek
+              }
+            },
+            file: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek,
+                read: MEMFS.stream_ops.read,
+                write: MEMFS.stream_ops.write,
+                allocate: MEMFS.stream_ops.allocate,
+                mmap: MEMFS.stream_ops.mmap
+              }
+            },
+            link: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                readlink: MEMFS.node_ops.readlink
+              },
+              stream: {}
+            },
+            chrdev: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: FS.chrdev_stream_ops
+            },
+          };
+        }
+        var node = FS.createNode(parent, name, mode, dev);
+        if (FS.isDir(node.mode)) {
+          node.node_ops = MEMFS.ops_table.dir.node;
+          node.stream_ops = MEMFS.ops_table.dir.stream;
+          node.contents = {};
+        } else if (FS.isFile(node.mode)) {
+          node.node_ops = MEMFS.ops_table.file.node;
+          node.stream_ops = MEMFS.ops_table.file.stream;
+          node.contents = [];
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        } else if (FS.isLink(node.mode)) {
+          node.node_ops = MEMFS.ops_table.link.node;
+          node.stream_ops = MEMFS.ops_table.link.stream;
+        } else if (FS.isChrdev(node.mode)) {
+          node.node_ops = MEMFS.ops_table.chrdev.node;
+          node.stream_ops = MEMFS.ops_table.chrdev.stream;
+        }
+        node.timestamp = Date.now();
+        // add the new node to the parent
+        if (parent) {
+          parent.contents[name] = node;
+        }
+        return node;
+      },ensureFlexible:function (node) {
+        if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
+          var contents = node.contents;
+          node.contents = Array.prototype.slice.call(contents);
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        }
+      },node_ops:{getattr:function (node) {
+          var attr = {};
+          // device numbers reuse inode numbers.
+          attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
+          attr.ino = node.id;
+          attr.mode = node.mode;
+          attr.nlink = 1;
+          attr.uid = 0;
+          attr.gid = 0;
+          attr.rdev = node.rdev;
+          if (FS.isDir(node.mode)) {
+            attr.size = 4096;
+          } else if (FS.isFile(node.mode)) {
+            attr.size = node.contents.length;
+          } else if (FS.isLink(node.mode)) {
+            attr.size = node.link.length;
+          } else {
+            attr.size = 0;
+          }
+          attr.atime = new Date(node.timestamp);
+          attr.mtime = new Date(node.timestamp);
+          attr.ctime = new Date(node.timestamp);
+          // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
+          //       but this is not required by the standard.
+          attr.blksize = 4096;
+          attr.blocks = Math.ceil(attr.size / attr.blksize);
+          return attr;
+        },setattr:function (node, attr) {
+          if (attr.mode !== undefined) {
+            node.mode = attr.mode;
+          }
+          if (attr.timestamp !== undefined) {
+            node.timestamp = attr.timestamp;
+          }
+          if (attr.size !== undefined) {
+            MEMFS.ensureFlexible(node);
+            var contents = node.contents;
+            if (attr.size < contents.length) contents.length = attr.size;
+            else while (attr.size > contents.length) contents.push(0);
+          }
+        },lookup:function (parent, name) {
+          throw FS.genericErrors[ERRNO_CODES.ENOENT];
+        },mknod:function (parent, name, mode, dev) {
+          return MEMFS.createNode(parent, name, mode, dev);
+        },rename:function (old_node, new_dir, new_name) {
+          // if we're overwriting a directory at new_name, make sure it's empty.
+          if (FS.isDir(old_node.mode)) {
+            var new_node;
+            try {
+              new_node = FS.lookupNode(new_dir, new_name);
+            } catch (e) {
+            }
+            if (new_node) {
+              for (var i in new_node.contents) {
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+              }
+            }
+          }
+          // do the internal rewiring
+          delete old_node.parent.contents[old_node.name];
+          old_node.name = new_name;
+          new_dir.contents[new_name] = old_node;
+          old_node.parent = new_dir;
+        },unlink:function (parent, name) {
+          delete parent.contents[name];
+        },rmdir:function (parent, name) {
+          var node = FS.lookupNode(parent, name);
+          for (var i in node.contents) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+          }
+          delete parent.contents[name];
+        },readdir:function (node) {
+          var entries = ['.', '..']
+          for (var key in node.contents) {
+            if (!node.contents.hasOwnProperty(key)) {
+              continue;
+            }
+            entries.push(key);
+          }
+          return entries;
+        },symlink:function (parent, newname, oldpath) {
+          var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
+          node.link = oldpath;
+          return node;
+        },readlink:function (node) {
+          if (!FS.isLink(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          return node.link;
+        }},stream_ops:{read:function (stream, buffer, offset, length, position) {
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (size > 8 && contents.subarray) { // non-trivial, and typed array
+            buffer.set(contents.subarray(position, position + size), offset);
+          } else
+          {
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          }
+          return size;
+        },write:function (stream, buffer, offset, length, position, canOwn) {
+          var node = stream.node;
+          node.timestamp = Date.now();
+          var contents = node.contents;
+          if (length && contents.length === 0 && position === 0 && buffer.subarray) {
+            // just replace it with the new data
+            if (canOwn && offset === 0) {
+              node.contents = buffer; // this could be a subarray of Emscripten HEAP, or allocated from some other source.
+              node.contentMode = (buffer.buffer === HEAP8.buffer) ? MEMFS.CONTENT_OWNING : MEMFS.CONTENT_FIXED;
+            } else {
+              node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
+              node.contentMode = MEMFS.CONTENT_FIXED;
+            }
+            return length;
+          }
+          MEMFS.ensureFlexible(node);
+          var contents = node.contents;
+          while (contents.length < position) contents.push(0);
+          for (var i = 0; i < length; i++) {
+            contents[position + i] = buffer[offset + i];
+          }
+          return length;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              position += stream.node.contents.length;
+            }
+          }
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          stream.ungotten = [];
+          stream.position = position;
+          return position;
+        },allocate:function (stream, offset, length) {
+          MEMFS.ensureFlexible(stream.node);
+          var contents = stream.node.contents;
+          var limit = offset + length;
+          while (limit > contents.length) contents.push(0);
+        },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+          if (!FS.isFile(stream.node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          var ptr;
+          var allocated;
+          var contents = stream.node.contents;
+          // Only make a new copy when MAP_PRIVATE is specified.
+          if ( !(flags & 2) &&
+                (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
+            // We can't emulate MAP_SHARED when the file is not backed by the buffer
+            // we're mapping to (e.g. the HEAP buffer).
+            allocated = false;
+            ptr = contents.byteOffset;
+          } else {
+            // Try to avoid unnecessary slices.
+            if (position > 0 || position + length < contents.length) {
+              if (contents.subarray) {
+                contents = contents.subarray(position, position + length);
+              } else {
+                contents = Array.prototype.slice.call(contents, position, position + length);
+              }
+            }
+            allocated = true;
+            ptr = _malloc(length);
+            if (!ptr) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOMEM);
+            }
+            buffer.set(contents, ptr);
+          }
+          return { ptr: ptr, allocated: allocated };
+        }}};
+
+  var IDBFS={dbs:{},indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) {
+        // reuse all of the core MEMFS functionality
+        return MEMFS.mount.apply(null, arguments);
+      },syncfs:function (mount, populate, callback) {
+        IDBFS.getLocalSet(mount, function(err, local) {
+          if (err) return callback(err);
+
+          IDBFS.getRemoteSet(mount, function(err, remote) {
+            if (err) return callback(err);
+
+            var src = populate ? remote : local;
+            var dst = populate ? local : remote;
+
+            IDBFS.reconcile(src, dst, callback);
+          });
+        });
+      },getDB:function (name, callback) {
+        // check the cache first
+        var db = IDBFS.dbs[name];
+        if (db) {
+          return callback(null, db);
+        }
+
+        var req;
+        try {
+          req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
+        } catch (e) {
+          return callback(e);
+        }
+        req.onupgradeneeded = function(e) {
+          var db = e.target.result;
+          var transaction = e.target.transaction;
+
+          var fileStore;
+
+          if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
+            fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          } else {
+            fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
+          }
+
+          fileStore.createIndex('timestamp', 'timestamp', { unique: false });
+        };
+        req.onsuccess = function() {
+          db = req.result;
+
+          // add to the cache
+          IDBFS.dbs[name] = db;
+          callback(null, db);
+        };
+        req.onerror = function() {
+          callback(this.error);
+        };
+      },getLocalSet:function (mount, callback) {
+        var entries = {};
+
+        function isRealDir(p) {
+          return p !== '.' && p !== '..';
+        };
+        function toAbsolute(root) {
+          return function(p) {
+            return PATH.join2(root, p);
+          }
+        };
+
+        var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
+
+        while (check.length) {
+          var path = check.pop();
+          var stat;
+
+          try {
+            stat = FS.stat(path);
+          } catch (e) {
+            return callback(e);
+          }
+
+          if (FS.isDir(stat.mode)) {
+            check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
+          }
+
+          entries[path] = { timestamp: stat.mtime };
+        }
+
+        return callback(null, { type: 'local', entries: entries });
+      },getRemoteSet:function (mount, callback) {
+        var entries = {};
+
+        IDBFS.getDB(mount.mountpoint, function(err, db) {
+          if (err) return callback(err);
+
+          var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly');
+          transaction.onerror = function() { callback(this.error); };
+
+          var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          var index = store.index('timestamp');
+
+          index.openKeyCursor().onsuccess = function(event) {
+            var cursor = event.target.result;
+
+            if (!cursor) {
+              return callback(null, { type: 'remote', db: db, entries: entries });
+            }
+
+            entries[cursor.primaryKey] = { timestamp: cursor.key };
+
+            cursor.continue();
+          };
+        });
+      },loadLocalEntry:function (path, callback) {
+        var stat, node;
+
+        try {
+          var lookup = FS.lookupPath(path);
+          node = lookup.node;
+          stat = FS.stat(path);
+        } catch (e) {
+          return callback(e);
+        }
+
+        if (FS.isDir(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode });
+        } else if (FS.isFile(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents });
+        } else {
+          return callback(new Error('node type not supported'));
+        }
+      },storeLocalEntry:function (path, entry, callback) {
+        try {
+          if (FS.isDir(entry.mode)) {
+            FS.mkdir(path, entry.mode);
+          } else if (FS.isFile(entry.mode)) {
+            FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true });
+          } else {
+            return callback(new Error('node type not supported'));
+          }
+
+          FS.utime(path, entry.timestamp, entry.timestamp);
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },removeLocalEntry:function (path, callback) {
+        try {
+          var lookup = FS.lookupPath(path);
+          var stat = FS.stat(path);
+
+          if (FS.isDir(stat.mode)) {
+            FS.rmdir(path);
+          } else if (FS.isFile(stat.mode)) {
+            FS.unlink(path);
+          }
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },loadRemoteEntry:function (store, path, callback) {
+        var req = store.get(path);
+        req.onsuccess = function(event) { callback(null, event.target.result); };
+        req.onerror = function() { callback(this.error); };
+      },storeRemoteEntry:function (store, path, entry, callback) {
+        var req = store.put(entry, path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },removeRemoteEntry:function (store, path, callback) {
+        var req = store.delete(path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },reconcile:function (src, dst, callback) {
+        var total = 0;
+
+        var create = [];
+        Object.keys(src.entries).forEach(function (key) {
+          var e = src.entries[key];
+          var e2 = dst.entries[key];
+          if (!e2 || e.timestamp > e2.timestamp) {
+            create.push(key);
+            total++;
+          }
+        });
+
+        var remove = [];
+        Object.keys(dst.entries).forEach(function (key) {
+          var e = dst.entries[key];
+          var e2 = src.entries[key];
+          if (!e2) {
+            remove.push(key);
+            total++;
+          }
+        });
+
+        if (!total) {
+          return callback(null);
+        }
+
+        var errored = false;
+        var completed = 0;
+        var db = src.type === 'remote' ? src.db : dst.db;
+        var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
+        var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= total) {
+            return callback(null);
+          }
+        };
+
+        transaction.onerror = function() { done(this.error); };
+
+        // sort paths in ascending order so directory entries are created
+        // before the files inside them
+        create.sort().forEach(function (path) {
+          if (dst.type === 'local') {
+            IDBFS.loadRemoteEntry(store, path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeLocalEntry(path, entry, done);
+            });
+          } else {
+            IDBFS.loadLocalEntry(path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeRemoteEntry(store, path, entry, done);
+            });
+          }
+        });
+
+        // sort paths in descending order so files are deleted before their
+        // parent directories
+        remove.sort().reverse().forEach(function(path) {
+          if (dst.type === 'local') {
+            IDBFS.removeLocalEntry(path, done);
+          } else {
+            IDBFS.removeRemoteEntry(store, path, done);
+          }
+        });
+      }};
+
+  var NODEFS={isWindows:false,staticInit:function () {
+        NODEFS.isWindows = !!process.platform.match(/^win/);
+      },mount:function (mount) {
+        assert(ENVIRONMENT_IS_NODE);
+        return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node = FS.createNode(parent, name, mode);
+        node.node_ops = NODEFS.node_ops;
+        node.stream_ops = NODEFS.stream_ops;
+        return node;
+      },getMode:function (path) {
+        var stat;
+        try {
+          stat = fs.lstatSync(path);
+          if (NODEFS.isWindows) {
+            // On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so
+            // propagate write bits to execute bits.
+            stat.mode = stat.mode | ((stat.mode & 146) >> 1);
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        return stat.mode;
+      },realPath:function (node) {
+        var parts = [];
+        while (node.parent !== node) {
+          parts.push(node.name);
+          node = node.parent;
+        }
+        parts.push(node.mount.opts.root);
+        parts.reverse();
+        return PATH.join.apply(null, parts);
+      },flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) {
+        if (flags in NODEFS.flagsToPermissionStringMap) {
+          return NODEFS.flagsToPermissionStringMap[flags];
+        } else {
+          return flags;
+        }
+      },node_ops:{getattr:function (node) {
+          var path = NODEFS.realPath(node);
+          var stat;
+          try {
+            stat = fs.lstatSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096.
+          // See http://support.microsoft.com/kb/140365
+          if (NODEFS.isWindows && !stat.blksize) {
+            stat.blksize = 4096;
+          }
+          if (NODEFS.isWindows && !stat.blocks) {
+            stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0;
+          }
+          return {
+            dev: stat.dev,
+            ino: stat.ino,
+            mode: stat.mode,
+            nlink: stat.nlink,
+            uid: stat.uid,
+            gid: stat.gid,
+            rdev: stat.rdev,
+            size: stat.size,
+            atime: stat.atime,
+            mtime: stat.mtime,
+            ctime: stat.ctime,
+            blksize: stat.blksize,
+            blocks: stat.blocks
+          };
+        },setattr:function (node, attr) {
+          var path = NODEFS.realPath(node);
+          try {
+            if (attr.mode !== undefined) {
+              fs.chmodSync(path, attr.mode);
+              // update the common node structure mode as well
+              node.mode = attr.mode;
+            }
+            if (attr.timestamp !== undefined) {
+              var date = new Date(attr.timestamp);
+              fs.utimesSync(path, date, date);
+            }
+            if (attr.size !== undefined) {
+              fs.truncateSync(path, attr.size);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },lookup:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          var mode = NODEFS.getMode(path);
+          return NODEFS.createNode(parent, name, mode);
+        },mknod:function (parent, name, mode, dev) {
+          var node = NODEFS.createNode(parent, name, mode, dev);
+          // create the backing node for this in the fs root as well
+          var path = NODEFS.realPath(node);
+          try {
+            if (FS.isDir(node.mode)) {
+              fs.mkdirSync(path, node.mode);
+            } else {
+              fs.writeFileSync(path, '', { mode: node.mode });
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return node;
+        },rename:function (oldNode, newDir, newName) {
+          var oldPath = NODEFS.realPath(oldNode);
+          var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
+          try {
+            fs.renameSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },unlink:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.unlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },rmdir:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.rmdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readdir:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },symlink:function (parent, newName, oldPath) {
+          var newPath = PATH.join2(NODEFS.realPath(parent), newName);
+          try {
+            fs.symlinkSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readlink:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        }},stream_ops:{open:function (stream) {
+          var path = NODEFS.realPath(stream.node);
+          try {
+            if (FS.isFile(stream.node.mode)) {
+              stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags));
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },close:function (stream) {
+          try {
+            if (FS.isFile(stream.node.mode) && stream.nfd) {
+              fs.closeSync(stream.nfd);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },read:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(length);
+          var res;
+          try {
+            res = fs.readSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          if (res > 0) {
+            for (var i = 0; i < res; i++) {
+              buffer[offset + i] = nbuffer[i];
+            }
+          }
+          return res;
+        },write:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(buffer.subarray(offset, offset + length));
+          var res;
+          try {
+            res = fs.writeSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return res;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              try {
+                var stat = fs.fstatSync(stream.nfd);
+                position += stat.size;
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+              }
+            }
+          }
+
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+
+          stream.position = position;
+          return position;
+        }}};
+
+  var _stdin=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stdout=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stderr=allocate(1, "i32*", ALLOC_STATIC);
+
+  function _fflush(stream) {
+      // int fflush(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html
+      // we don't currently perform any user-space buffering of data
+    }var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},handleFSError:function (e) {
+        if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
+        return ___setErrNo(e.errno);
+      },lookupPath:function (path, opts) {
+        path = PATH.resolve(FS.cwd(), path);
+        opts = opts || {};
+
+        var defaults = {
+          follow_mount: true,
+          recurse_count: 0
+        };
+        for (var key in defaults) {
+          if (opts[key] === undefined) {
+            opts[key] = defaults[key];
+          }
+        }
+
+        if (opts.recurse_count > 8) {  // max recursive lookup of 8
+          throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+        }
+
+        // split the path
+        var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), false);
+
+        // start at the root
+        var current = FS.root;
+        var current_path = '/';
+
+        for (var i = 0; i < parts.length; i++) {
+          var islast = (i === parts.length-1);
+          if (islast && opts.parent) {
+            // stop resolving
+            break;
+          }
+
+          current = FS.lookupNode(current, parts[i]);
+          current_path = PATH.join2(current_path, parts[i]);
+
+          // jump to the mount's root node if this is a mountpoint
+          if (FS.isMountpoint(current)) {
+            if (!islast || (islast && opts.follow_mount)) {
+              current = current.mounted.root;
+            }
+          }
+
+          // by default, lookupPath will not follow a symlink if it is the final path component.
+          // setting opts.follow = true will override this behavior.
+          if (!islast || opts.follow) {
+            var count = 0;
+            while (FS.isLink(current.mode)) {
+              var link = FS.readlink(current_path);
+              current_path = PATH.resolve(PATH.dirname(current_path), link);
+
+              var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
+              current = lookup.node;
+
+              if (count++ > 40) {  // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
+                throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+              }
+            }
+          }
+        }
+
+        return { path: current_path, node: current };
+      },getPath:function (node) {
+        var path;
+        while (true) {
+          if (FS.isRoot(node)) {
+            var mount = node.mount.mountpoint;
+            if (!path) return mount;
+            return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
+          }
+          path = path ? node.name + '/' + path : node.name;
+          node = node.parent;
+        }
+      },hashName:function (parentid, name) {
+        var hash = 0;
+
+
+        for (var i = 0; i < name.length; i++) {
+          hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
+        }
+        return ((parentid + hash) >>> 0) % FS.nameTable.length;
+      },hashAddNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        node.name_next = FS.nameTable[hash];
+        FS.nameTable[hash] = node;
+      },hashRemoveNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        if (FS.nameTable[hash] === node) {
+          FS.nameTable[hash] = node.name_next;
+        } else {
+          var current = FS.nameTable[hash];
+          while (current) {
+            if (current.name_next === node) {
+              current.name_next = node.name_next;
+              break;
+            }
+            current = current.name_next;
+          }
+        }
+      },lookupNode:function (parent, name) {
+        var err = FS.mayLookup(parent);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        var hash = FS.hashName(parent.id, name);
+        for (var node = FS.nameTable[hash]; node; node = node.name_next) {
+          var nodeName = node.name;
+          if (node.parent.id === parent.id && nodeName === name) {
+            return node;
+          }
+        }
+        // if we failed to find it in the cache, call into the VFS
+        return FS.lookup(parent, name);
+      },createNode:function (parent, name, mode, rdev) {
+        if (!FS.FSNode) {
+          FS.FSNode = function(parent, name, mode, rdev) {
+            if (!parent) {
+              parent = this;  // root node sets parent to itself
+            }
+            this.parent = parent;
+            this.mount = parent.mount;
+            this.mounted = null;
+            this.id = FS.nextInode++;
+            this.name = name;
+            this.mode = mode;
+            this.node_ops = {};
+            this.stream_ops = {};
+            this.rdev = rdev;
+          };
+
+          FS.FSNode.prototype = {};
+
+          // compatibility
+          var readMode = 292 | 73;
+          var writeMode = 146;
+
+          // NOTE we must use Object.defineProperties instead of individual calls to
+          // Object.defineProperty in order to make closure compiler happy
+          Object.defineProperties(FS.FSNode.prototype, {
+            read: {
+              get: function() { return (this.mode & readMode) === readMode; },
+              set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; }
+            },
+            write: {
+              get: function() { return (this.mode & writeMode) === writeMode; },
+              set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; }
+            },
+            isFolder: {
+              get: function() { return FS.isDir(this.mode); },
+            },
+            isDevice: {
+              get: function() { return FS.isChrdev(this.mode); },
+            },
+          });
+        }
+
+        var node = new FS.FSNode(parent, name, mode, rdev);
+
+        FS.hashAddNode(node);
+
+        return node;
+      },destroyNode:function (node) {
+        FS.hashRemoveNode(node);
+      },isRoot:function (node) {
+        return node === node.parent;
+      },isMountpoint:function (node) {
+        return !!node.mounted;
+      },isFile:function (mode) {
+        return (mode & 61440) === 32768;
+      },isDir:function (mode) {
+        return (mode & 61440) === 16384;
+      },isLink:function (mode) {
+        return (mode & 61440) === 40960;
+      },isChrdev:function (mode) {
+        return (mode & 61440) === 8192;
+      },isBlkdev:function (mode) {
+        return (mode & 61440) === 24576;
+      },isFIFO:function (mode) {
+        return (mode & 61440) === 4096;
+      },isSocket:function (mode) {
+        return (mode & 49152) === 49152;
+      },flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function (str) {
+        var flags = FS.flagModes[str];
+        if (typeof flags === 'undefined') {
+          throw new Error('Unknown file open mode: ' + str);
+        }
+        return flags;
+      },flagsToPermissionString:function (flag) {
+        var accmode = flag & 2097155;
+        var perms = ['r', 'w', 'rw'][accmode];
+        if ((flag & 512)) {
+          perms += 'w';
+        }
+        return perms;
+      },nodePermissions:function (node, perms) {
+        if (FS.ignorePermissions) {
+          return 0;
+        }
+        // return 0 if any user, group or owner bits are set.
+        if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
+          return ERRNO_CODES.EACCES;
+        }
+        return 0;
+      },mayLookup:function (dir) {
+        return FS.nodePermissions(dir, 'x');
+      },mayCreate:function (dir, name) {
+        try {
+          var node = FS.lookupNode(dir, name);
+          return ERRNO_CODES.EEXIST;
+        } catch (e) {
+        }
+        return FS.nodePermissions(dir, 'wx');
+      },mayDelete:function (dir, name, isdir) {
+        var node;
+        try {
+          node = FS.lookupNode(dir, name);
+        } catch (e) {
+          return e.errno;
+        }
+        var err = FS.nodePermissions(dir, 'wx');
+        if (err) {
+          return err;
+        }
+        if (isdir) {
+          if (!FS.isDir(node.mode)) {
+            return ERRNO_CODES.ENOTDIR;
+          }
+          if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
+            return ERRNO_CODES.EBUSY;
+          }
+        } else {
+          if (FS.isDir(node.mode)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return 0;
+      },mayOpen:function (node, flags) {
+        if (!node) {
+          return ERRNO_CODES.ENOENT;
+        }
+        if (FS.isLink(node.mode)) {
+          return ERRNO_CODES.ELOOP;
+        } else if (FS.isDir(node.mode)) {
+          if ((flags & 2097155) !== 0 ||  // opening for write
+              (flags & 512)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
+      },MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) {
+        fd_start = fd_start || 0;
+        fd_end = fd_end || FS.MAX_OPEN_FDS;
+        for (var fd = fd_start; fd <= fd_end; fd++) {
+          if (!FS.streams[fd]) {
+            return fd;
+          }
+        }
+        throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
+      },getStream:function (fd) {
+        return FS.streams[fd];
+      },createStream:function (stream, fd_start, fd_end) {
+        if (!FS.FSStream) {
+          FS.FSStream = function(){};
+          FS.FSStream.prototype = {};
+          // compatibility
+          Object.defineProperties(FS.FSStream.prototype, {
+            object: {
+              get: function() { return this.node; },
+              set: function(val) { this.node = val; }
+            },
+            isRead: {
+              get: function() { return (this.flags & 2097155) !== 1; }
+            },
+            isWrite: {
+              get: function() { return (this.flags & 2097155) !== 0; }
+            },
+            isAppend: {
+              get: function() { return (this.flags & 1024); }
+            }
+          });
+        }
+        if (0) {
+          // reuse the object
+          stream.__proto__ = FS.FSStream.prototype;
+        } else {
+          var newStream = new FS.FSStream();
+          for (var p in stream) {
+            newStream[p] = stream[p];
+          }
+          stream = newStream;
+        }
+        var fd = FS.nextfd(fd_start, fd_end);
+        stream.fd = fd;
+        FS.streams[fd] = stream;
+        return stream;
+      },closeStream:function (fd) {
+        FS.streams[fd] = null;
+      },getStreamFromPtr:function (ptr) {
+        return FS.streams[ptr - 1];
+      },getPtrForStream:function (stream) {
+        return stream ? stream.fd + 1 : 0;
+      },chrdev_stream_ops:{open:function (stream) {
+          var device = FS.getDevice(stream.node.rdev);
+          // override node's stream ops with the device's
+          stream.stream_ops = device.stream_ops;
+          // forward the open call
+          if (stream.stream_ops.open) {
+            stream.stream_ops.open(stream);
+          }
+        },llseek:function () {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }},major:function (dev) {
+        return ((dev) >> 8);
+      },minor:function (dev) {
+        return ((dev) & 0xff);
+      },makedev:function (ma, mi) {
+        return ((ma) << 8 | (mi));
+      },registerDevice:function (dev, ops) {
+        FS.devices[dev] = { stream_ops: ops };
+      },getDevice:function (dev) {
+        return FS.devices[dev];
+      },getMounts:function (mount) {
+        var mounts = [];
+        var check = [mount];
+
+        while (check.length) {
+          var m = check.pop();
+
+          mounts.push(m);
+
+          check.push.apply(check, m.mounts);
+        }
+
+        return mounts;
+      },syncfs:function (populate, callback) {
+        if (typeof(populate) === 'function') {
+          callback = populate;
+          populate = false;
+        }
+
+        var mounts = FS.getMounts(FS.root.mount);
+        var completed = 0;
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= mounts.length) {
+            callback(null);
+          }
+        };
+
+        // sync all mounts
+        mounts.forEach(function (mount) {
+          if (!mount.type.syncfs) {
+            return done(null);
+          }
+          mount.type.syncfs(mount, populate, done);
+        });
+      },mount:function (type, opts, mountpoint) {
+        var root = mountpoint === '/';
+        var pseudo = !mountpoint;
+        var node;
+
+        if (root && FS.root) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        } else if (!root && !pseudo) {
+          var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+          mountpoint = lookup.path;  // use the absolute path
+          node = lookup.node;
+
+          if (FS.isMountpoint(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+          }
+
+          if (!FS.isDir(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+          }
+        }
+
+        var mount = {
+          type: type,
+          opts: opts,
+          mountpoint: mountpoint,
+          mounts: []
+        };
+
+        // create a root node for the fs
+        var mountRoot = type.mount(mount);
+        mountRoot.mount = mount;
+        mount.root = mountRoot;
+
+        if (root) {
+          FS.root = mountRoot;
+        } else if (node) {
+          // set as a mountpoint
+          node.mounted = mount;
+
+          // add the new mount to the current mount's children
+          if (node.mount) {
+            node.mount.mounts.push(mount);
+          }
+        }
+
+        return mountRoot;
+      },unmount:function (mountpoint) {
+        var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+        if (!FS.isMountpoint(lookup.node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+
+        // destroy the nodes for this mount, and all its child mounts
+        var node = lookup.node;
+        var mount = node.mounted;
+        var mounts = FS.getMounts(mount);
+
+        Object.keys(FS.nameTable).forEach(function (hash) {
+          var current = FS.nameTable[hash];
+
+          while (current) {
+            var next = current.name_next;
+
+            if (mounts.indexOf(current.mount) !== -1) {
+              FS.destroyNode(current);
+            }
+
+            current = next;
+          }
+        });
+
+        // no longer a mountpoint
+        node.mounted = null;
+
+        // remove this mount from the child mounts
+        var idx = node.mount.mounts.indexOf(mount);
+        assert(idx !== -1);
+        node.mount.mounts.splice(idx, 1);
+      },lookup:function (parent, name) {
+        return parent.node_ops.lookup(parent, name);
+      },mknod:function (path, mode, dev) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var err = FS.mayCreate(parent, name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.mknod) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.mknod(parent, name, mode, dev);
+      },create:function (path, mode) {
+        mode = mode !== undefined ? mode : 438 /* 0666 */;
+        mode &= 4095;
+        mode |= 32768;
+        return FS.mknod(path, mode, 0);
+      },mkdir:function (path, mode) {
+        mode = mode !== undefined ? mode : 511 /* 0777 */;
+        mode &= 511 | 512;
+        mode |= 16384;
+        return FS.mknod(path, mode, 0);
+      },mkdev:function (path, mode, dev) {
+        if (typeof(dev) === 'undefined') {
+          dev = mode;
+          mode = 438 /* 0666 */;
+        }
+        mode |= 8192;
+        return FS.mknod(path, mode, dev);
+      },symlink:function (oldpath, newpath) {
+        var lookup = FS.lookupPath(newpath, { parent: true });
+        var parent = lookup.node;
+        var newname = PATH.basename(newpath);
+        var err = FS.mayCreate(parent, newname);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.symlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.symlink(parent, newname, oldpath);
+      },rename:function (old_path, new_path) {
+        var old_dirname = PATH.dirname(old_path);
+        var new_dirname = PATH.dirname(new_path);
+        var old_name = PATH.basename(old_path);
+        var new_name = PATH.basename(new_path);
+        // parents must exist
+        var lookup, old_dir, new_dir;
+        try {
+          lookup = FS.lookupPath(old_path, { parent: true });
+          old_dir = lookup.node;
+          lookup = FS.lookupPath(new_path, { parent: true });
+          new_dir = lookup.node;
+        } catch (e) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // need to be part of the same mount
+        if (old_dir.mount !== new_dir.mount) {
+          throw new FS.ErrnoError(ERRNO_CODES.EXDEV);
+        }
+        // source must exist
+        var old_node = FS.lookupNode(old_dir, old_name);
+        // old path should not be an ancestor of the new path
+        var relative = PATH.relative(old_path, new_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        // new path should not be an ancestor of the old path
+        relative = PATH.relative(new_path, old_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+        }
+        // see if the new path already exists
+        var new_node;
+        try {
+          new_node = FS.lookupNode(new_dir, new_name);
+        } catch (e) {
+          // not fatal
+        }
+        // early out if nothing needs to change
+        if (old_node === new_node) {
+          return;
+        }
+        // we'll need to delete the old entry
+        var isdir = FS.isDir(old_node.mode);
+        var err = FS.mayDelete(old_dir, old_name, isdir);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // need delete permissions if we'll be overwriting.
+        // need create permissions if new doesn't already exist.
+        err = new_node ?
+          FS.mayDelete(new_dir, new_name, isdir) :
+          FS.mayCreate(new_dir, new_name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!old_dir.node_ops.rename) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // if we are going to change the parent, check write permissions
+        if (new_dir !== old_dir) {
+          err = FS.nodePermissions(old_dir, 'w');
+          if (err) {
+            throw new FS.ErrnoError(err);
+          }
+        }
+        // remove the node from the lookup hash
+        FS.hashRemoveNode(old_node);
+        // do the underlying fs rename
+        try {
+          old_dir.node_ops.rename(old_node, new_dir, new_name);
+        } catch (e) {
+          throw e;
+        } finally {
+          // add the node back to the hash (in case node_ops.rename
+          // changed its name)
+          FS.hashAddNode(old_node);
+        }
+      },rmdir:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, true);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.rmdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.rmdir(parent, name);
+        FS.destroyNode(node);
+      },readdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        if (!node.node_ops.readdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        return node.node_ops.readdir(node);
+      },unlink:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, false);
+        if (err) {
+          // POSIX says unlink should set EPERM, not EISDIR
+          if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM;
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.unlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.unlink(parent, name);
+        FS.destroyNode(node);
+      },readlink:function (path) {
+        var lookup = FS.lookupPath(path);
+        var link = lookup.node;
+        if (!link.node_ops.readlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        return link.node_ops.readlink(link);
+      },stat:function (path, dontFollow) {
+        var lookup = FS.lookupPath(path, { follow: !dontFollow });
+        var node = lookup.node;
+        if (!node.node_ops.getattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return node.node_ops.getattr(node);
+      },lstat:function (path) {
+        return FS.stat(path, true);
+      },chmod:function (path, mode, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          mode: (mode & 4095) | (node.mode & ~4095),
+          timestamp: Date.now()
+        });
+      },lchmod:function (path, mode) {
+        FS.chmod(path, mode, true);
+      },fchmod:function (fd, mode) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chmod(stream.node, mode);
+      },chown:function (path, uid, gid, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          timestamp: Date.now()
+          // we ignore the uid / gid for now
+        });
+      },lchown:function (path, uid, gid) {
+        FS.chown(path, uid, gid, true);
+      },fchown:function (fd, uid, gid) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chown(stream.node, uid, gid);
+      },truncate:function (path, len) {
+        if (len < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: true });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!FS.isFile(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var err = FS.nodePermissions(node, 'w');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        node.node_ops.setattr(node, {
+          size: len,
+          timestamp: Date.now()
+        });
+      },ftruncate:function (fd, len) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        FS.truncate(stream.node, len);
+      },utime:function (path, atime, mtime) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        node.node_ops.setattr(node, {
+          timestamp: Math.max(atime, mtime)
+        });
+      },open:function (path, flags, mode, fd_start, fd_end) {
+        flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
+        mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
+        if ((flags & 64)) {
+          mode = (mode & 4095) | 32768;
+        } else {
+          mode = 0;
+        }
+        var node;
+        if (typeof path === 'object') {
+          node = path;
+        } else {
+          path = PATH.normalize(path);
+          try {
+            var lookup = FS.lookupPath(path, {
+              follow: !(flags & 131072)
+            });
+            node = lookup.node;
+          } catch (e) {
+            // ignore
+          }
+        }
+        // perhaps we need to create the node
+        if ((flags & 64)) {
+          if (node) {
+            // if O_CREAT and O_EXCL are set, error out if the node already exists
+            if ((flags & 128)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EEXIST);
+            }
+          } else {
+            // node doesn't exist, try to create it
+            node = FS.mknod(path, mode, 0);
+          }
+        }
+        if (!node) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
+        }
+        // can't truncate a device
+        if (FS.isChrdev(node.mode)) {
+          flags &= ~512;
+        }
+        // check permissions
+        var err = FS.mayOpen(node, flags);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // do truncation if necessary
+        if ((flags & 512)) {
+          FS.truncate(node, 0);
+        }
+        // we've already handled these, don't pass down to the underlying vfs
+        flags &= ~(128 | 512);
+
+        // register the stream with the filesystem
+        var stream = FS.createStream({
+          node: node,
+          path: FS.getPath(node),  // we want the absolute path to the node
+          flags: flags,
+          seekable: true,
+          position: 0,
+          stream_ops: node.stream_ops,
+          // used by the file family libc calls (fopen, fwrite, ferror, etc.)
+          ungotten: [],
+          error: false
+        }, fd_start, fd_end);
+        // call the new stream's open function
+        if (stream.stream_ops.open) {
+          stream.stream_ops.open(stream);
+        }
+        if (Module['logReadFiles'] && !(flags & 1)) {
+          if (!FS.readFiles) FS.readFiles = {};
+          if (!(path in FS.readFiles)) {
+            FS.readFiles[path] = 1;
+            Module['printErr']('read file: ' + path);
+          }
+        }
+        return stream;
+      },close:function (stream) {
+        try {
+          if (stream.stream_ops.close) {
+            stream.stream_ops.close(stream);
+          }
+        } catch (e) {
+          throw e;
+        } finally {
+          FS.closeStream(stream.fd);
+        }
+      },llseek:function (stream, offset, whence) {
+        if (!stream.seekable || !stream.stream_ops.llseek) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        return stream.stream_ops.llseek(stream, offset, whence);
+      },read:function (stream, buffer, offset, length, position) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.read) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
+        if (!seeking) stream.position += bytesRead;
+        return bytesRead;
+      },write:function (stream, buffer, offset, length, position, canOwn) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.write) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        if (stream.flags & 1024) {
+          // seek to the end before writing in append mode
+          FS.llseek(stream, 0, 2);
+        }
+        var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
+        if (!seeking) stream.position += bytesWritten;
+        return bytesWritten;
+      },allocate:function (stream, offset, length) {
+        if (offset < 0 || length <= 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        if (!stream.stream_ops.allocate) {
+          throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+        }
+        stream.stream_ops.allocate(stream, offset, length);
+      },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+        // TODO if PROT is PROT_WRITE, make sure we have write access
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EACCES);
+        }
+        if (!stream.stream_ops.mmap) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
+      },ioctl:function (stream, cmd, arg) {
+        if (!stream.stream_ops.ioctl) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTTY);
+        }
+        return stream.stream_ops.ioctl(stream, cmd, arg);
+      },readFile:function (path, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'r';
+        opts.encoding = opts.encoding || 'binary';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var ret;
+        var stream = FS.open(path, opts.flags);
+        var stat = FS.stat(path);
+        var length = stat.size;
+        var buf = new Uint8Array(length);
+        FS.read(stream, buf, 0, length, 0);
+        if (opts.encoding === 'utf8') {
+          ret = '';
+          var utf8 = new Runtime.UTF8Processor();
+          for (var i = 0; i < length; i++) {
+            ret += utf8.processCChar(buf[i]);
+          }
+        } else if (opts.encoding === 'binary') {
+          ret = buf;
+        }
+        FS.close(stream);
+        return ret;
+      },writeFile:function (path, data, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'w';
+        opts.encoding = opts.encoding || 'utf8';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var stream = FS.open(path, opts.flags, opts.mode);
+        if (opts.encoding === 'utf8') {
+          var utf8 = new Runtime.UTF8Processor();
+          var buf = new Uint8Array(utf8.processJSString(data));
+          FS.write(stream, buf, 0, buf.length, 0, opts.canOwn);
+        } else if (opts.encoding === 'binary') {
+          FS.write(stream, data, 0, data.length, 0, opts.canOwn);
+        }
+        FS.close(stream);
+      },cwd:function () {
+        return FS.currentPath;
+      },chdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        if (!FS.isDir(lookup.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        var err = FS.nodePermissions(lookup.node, 'x');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        FS.currentPath = lookup.path;
+      },createDefaultDirectories:function () {
+        FS.mkdir('/tmp');
+      },createDefaultDevices:function () {
+        // create /dev
+        FS.mkdir('/dev');
+        // setup /dev/null
+        FS.registerDevice(FS.makedev(1, 3), {
+          read: function() { return 0; },
+          write: function() { return 0; }
+        });
+        FS.mkdev('/dev/null', FS.makedev(1, 3));
+        // setup /dev/tty and /dev/tty1
+        // stderr needs to print output using Module['printErr']
+        // so we register a second tty just for it.
+        TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
+        TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
+        FS.mkdev('/dev/tty', FS.makedev(5, 0));
+        FS.mkdev('/dev/tty1', FS.makedev(6, 0));
+        // we're not going to emulate the actual shm device,
+        // just create the tmp dirs that reside in it commonly
+        FS.mkdir('/dev/shm');
+        FS.mkdir('/dev/shm/tmp');
+      },createStandardStreams:function () {
+        // TODO deprecate the old functionality of a single
+        // input / output callback and that utilizes FS.createDevice
+        // and instead require a unique set of stream ops
+
+        // by default, we symlink the standard streams to the
+        // default tty devices. however, if the standard streams
+        // have been overwritten we create a unique device for
+        // them instead.
+        if (Module['stdin']) {
+          FS.createDevice('/dev', 'stdin', Module['stdin']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdin');
+        }
+        if (Module['stdout']) {
+          FS.createDevice('/dev', 'stdout', null, Module['stdout']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdout');
+        }
+        if (Module['stderr']) {
+          FS.createDevice('/dev', 'stderr', null, Module['stderr']);
+        } else {
+          FS.symlink('/dev/tty1', '/dev/stderr');
+        }
+
+        // open default streams for the stdin, stdout and stderr devices
+        var stdin = FS.open('/dev/stdin', 'r');
+        HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin);
+        assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
+
+        var stdout = FS.open('/dev/stdout', 'w');
+        HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout);
+        assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
+
+        var stderr = FS.open('/dev/stderr', 'w');
+        HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr);
+        assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
+      },ensureErrnoError:function () {
+        if (FS.ErrnoError) return;
+        FS.ErrnoError = function ErrnoError(errno) {
+          this.errno = errno;
+          for (var key in ERRNO_CODES) {
+            if (ERRNO_CODES[key] === errno) {
+              this.code = key;
+              break;
+            }
+          }
+          this.message = ERRNO_MESSAGES[errno];
+        };
+        FS.ErrnoError.prototype = new Error();
+        FS.ErrnoError.prototype.constructor = FS.ErrnoError;
+        // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
+        [ERRNO_CODES.ENOENT].forEach(function(code) {
+          FS.genericErrors[code] = new FS.ErrnoError(code);
+          FS.genericErrors[code].stack = '<generic error, no stack>';
+        });
+      },staticInit:function () {
+        FS.ensureErrnoError();
+
+        FS.nameTable = new Array(4096);
+
+        FS.mount(MEMFS, {}, '/');
+
+        FS.createDefaultDirectories();
+        FS.createDefaultDevices();
+      },init:function (input, output, error) {
+        assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
+        FS.init.initialized = true;
+
+        FS.ensureErrnoError();
+
+        // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
+        Module['stdin'] = input || Module['stdin'];
+        Module['stdout'] = output || Module['stdout'];
+        Module['stderr'] = error || Module['stderr'];
+
+        FS.createStandardStreams();
+      },quit:function () {
+        FS.init.initialized = false;
+        for (var i = 0; i < FS.streams.length; i++) {
+          var stream = FS.streams[i];
+          if (!stream) {
+            continue;
+          }
+          FS.close(stream);
+        }
+      },getMode:function (canRead, canWrite) {
+        var mode = 0;
+        if (canRead) mode |= 292 | 73;
+        if (canWrite) mode |= 146;
+        return mode;
+      },joinPath:function (parts, forceRelative) {
+        var path = PATH.join.apply(null, parts);
+        if (forceRelative && path[0] == '/') path = path.substr(1);
+        return path;
+      },absolutePath:function (relative, base) {
+        return PATH.resolve(base, relative);
+      },standardizePath:function (path) {
+        return PATH.normalize(path);
+      },findObject:function (path, dontResolveLastLink) {
+        var ret = FS.analyzePath(path, dontResolveLastLink);
+        if (ret.exists) {
+          return ret.object;
+        } else {
+          ___setErrNo(ret.error);
+          return null;
+        }
+      },analyzePath:function (path, dontResolveLastLink) {
+        // operate from within the context of the symlink's target
+        try {
+          var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          path = lookup.path;
+        } catch (e) {
+        }
+        var ret = {
+          isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
+          parentExists: false, parentPath: null, parentObject: null
+        };
+        try {
+          var lookup = FS.lookupPath(path, { parent: true });
+          ret.parentExists = true;
+          ret.parentPath = lookup.path;
+          ret.parentObject = lookup.node;
+          ret.name = PATH.basename(path);
+          lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          ret.exists = true;
+          ret.path = lookup.path;
+          ret.object = lookup.node;
+          ret.name = lookup.node.name;
+          ret.isRoot = lookup.path === '/';
+        } catch (e) {
+          ret.error = e.errno;
+        };
+        return ret;
+      },createFolder:function (parent, name, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.mkdir(path, mode);
+      },createPath:function (parent, path, canRead, canWrite) {
+        parent = typeof parent === 'string' ? parent : FS.getPath(parent);
+        var parts = path.split('/').reverse();
+        while (parts.length) {
+          var part = parts.pop();
+          if (!part) continue;
+          var current = PATH.join2(parent, part);
+          try {
+            FS.mkdir(current);
+          } catch (e) {
+            // ignore EEXIST
+          }
+          parent = current;
+        }
+        return current;
+      },createFile:function (parent, name, properties, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.create(path, mode);
+      },createDataFile:function (parent, name, data, canRead, canWrite, canOwn) {
+        var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
+        var mode = FS.getMode(canRead, canWrite);
+        var node = FS.create(path, mode);
+        if (data) {
+          if (typeof data === 'string') {
+            var arr = new Array(data.length);
+            for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
+            data = arr;
+          }
+          // make sure we can write to the file
+          FS.chmod(node, mode | 146);
+          var stream = FS.open(node, 'w');
+          FS.write(stream, data, 0, data.length, 0, canOwn);
+          FS.close(stream);
+          FS.chmod(node, mode);
+        }
+        return node;
+      },createDevice:function (parent, name, input, output) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(!!input, !!output);
+        if (!FS.createDevice.major) FS.createDevice.major = 64;
+        var dev = FS.makedev(FS.createDevice.major++, 0);
+        // Create a fake device that a set of stream ops to emulate
+        // the old behavior.
+        FS.registerDevice(dev, {
+          open: function(stream) {
+            stream.seekable = false;
+          },
+          close: function(stream) {
+            // flush any pending line data
+            if (output && output.buffer && output.buffer.length) {
+              output(10);
+            }
+          },
+          read: function(stream, buffer, offset, length, pos /* ignored */) {
+            var bytesRead = 0;
+            for (var i = 0; i < length; i++) {
+              var result;
+              try {
+                result = input();
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+              if (result === undefined && bytesRead === 0) {
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+              if (result === null || result === undefined) break;
+              bytesRead++;
+              buffer[offset+i] = result;
+            }
+            if (bytesRead) {
+              stream.node.timestamp = Date.now();
+            }
+            return bytesRead;
+          },
+          write: function(stream, buffer, offset, length, pos) {
+            for (var i = 0; i < length; i++) {
+              try {
+                output(buffer[offset+i]);
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+            }
+            if (length) {
+              stream.node.timestamp = Date.now();
+            }
+            return i;
+          }
+        });
+        return FS.mkdev(path, mode, dev);
+      },createLink:function (parent, name, target, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        return FS.symlink(target, path);
+      },forceLoadFile:function (obj) {
+        if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
+        var success = true;
+        if (typeof XMLHttpRequest !== 'undefined') {
+          throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
+        } else if (Module['read']) {
+          // Command-line.
+          try {
+            // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
+            //          read() will try to parse UTF8.
+            obj.contents = intArrayFromString(Module['read'](obj.url), true);
+          } catch (e) {
+            success = false;
+          }
+        } else {
+          throw new Error('Cannot load without read() or XMLHttpRequest.');
+        }
+        if (!success) ___setErrNo(ERRNO_CODES.EIO);
+        return success;
+      },createLazyFile:function (parent, name, url, canRead, canWrite) {
+        // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
+        function LazyUint8Array() {
+          this.lengthKnown = false;
+          this.chunks = []; // Loaded chunks. Index is the chunk number
+        }
+        LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
+          if (idx > this.length-1 || idx < 0) {
+            return undefined;
+          }
+          var chunkOffset = idx % this.chunkSize;
+          var chunkNum = Math.floor(idx / this.chunkSize);
+          return this.getter(chunkNum)[chunkOffset];
+        }
+        LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
+          this.getter = getter;
+        }
+        LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
+            // Find length
+            var xhr = new XMLHttpRequest();
+            xhr.open('HEAD', url, false);
+            xhr.send(null);
+            if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+            var datalength = Number(xhr.getResponseHeader("Content-length"));
+            var header;
+            var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
+            var chunkSize = 1024*1024; // Chunk size in bytes
+
+            if (!hasByteServing) chunkSize = datalength;
+
+            // Function to get a range from the remote URL.
+            var doXHR = (function(from, to) {
+              if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
+              if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
+
+              // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
+              var xhr = new XMLHttpRequest();
+              xhr.open('GET', url, false);
+              if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
+
+              // Some hints to the browser that we want binary data.
+              if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
+              if (xhr.overrideMimeType) {
+                xhr.overrideMimeType('text/plain; charset=x-user-defined');
+              }
+
+              xhr.send(null);
+              if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+              if (xhr.response !== undefined) {
+                return new Uint8Array(xhr.response || []);
+              } else {
+                return intArrayFromString(xhr.responseText || '', true);
+              }
+            });
+            var lazyArray = this;
+            lazyArray.setDataGetter(function(chunkNum) {
+              var start = chunkNum * chunkSize;
+              var end = (chunkNum+1) * chunkSize - 1; // including this byte
+              end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
+                lazyArray.chunks[chunkNum] = doXHR(start, end);
+              }
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
+              return lazyArray.chunks[chunkNum];
+            });
+
+            this._length = datalength;
+            this._chunkSize = chunkSize;
+            this.lengthKnown = true;
+        }
+        if (typeof XMLHttpRequest !== 'undefined') {
+          if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
+          var lazyArray = new LazyUint8Array();
+          Object.defineProperty(lazyArray, "length", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._length;
+              }
+          });
+          Object.defineProperty(lazyArray, "chunkSize", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._chunkSize;
+              }
+          });
+
+          var properties = { isDevice: false, contents: lazyArray };
+        } else {
+          var properties = { isDevice: false, url: url };
+        }
+
+        var node = FS.createFile(parent, name, properties, canRead, canWrite);
+        // This is a total hack, but I want to get this lazy file code out of the
+        // core of MEMFS. If we want to keep this lazy file concept I feel it should
+        // be its own thin LAZYFS proxying calls to MEMFS.
+        if (properties.contents) {
+          node.contents = properties.contents;
+        } else if (properties.url) {
+          node.contents = null;
+          node.url = properties.url;
+        }
+        // override each stream op with one that tries to force load the lazy file first
+        var stream_ops = {};
+        var keys = Object.keys(node.stream_ops);
+        keys.forEach(function(key) {
+          var fn = node.stream_ops[key];
+          stream_ops[key] = function forceLoadLazyFile() {
+            if (!FS.forceLoadFile(node)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            return fn.apply(null, arguments);
+          };
+        });
+        // use a custom read function
+        stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
+          if (!FS.forceLoadFile(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EIO);
+          }
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (contents.slice) { // normal array
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          } else {
+            for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
+              buffer[offset + i] = contents.get(position + i);
+            }
+          }
+          return size;
+        };
+        node.stream_ops = stream_ops;
+        return node;
+      },createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
+        Browser.init();
+        // TODO we should allow people to just pass in a complete filename instead
+        // of parent and name being that we just join them anyways
+        var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent;
+        function processData(byteArray) {
+          function finish(byteArray) {
+            if (!dontCreateFile) {
+              FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
+            }
+            if (onload) onload();
+            removeRunDependency('cp ' + fullname);
+          }
+          var handled = false;
+          Module['preloadPlugins'].forEach(function(plugin) {
+            if (handled) return;
+            if (plugin['canHandle'](fullname)) {
+              plugin['handle'](byteArray, fullname, finish, function() {
+                if (onerror) onerror();
+                removeRunDependency('cp ' + fullname);
+              });
+              handled = true;
+            }
+          });
+          if (!handled) finish(byteArray);
+        }
+        addRunDependency('cp ' + fullname);
+        if (typeof url == 'string') {
+          Browser.asyncLoad(url, function(byteArray) {
+            processData(byteArray);
+          }, onerror);
+        } else {
+          processData(url);
+        }
+      },indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_NAME:function () {
+        return 'EM_FS_' + window.location.pathname;
+      },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
+          console.log('creating db');
+          var db = openRequest.result;
+          db.createObjectStore(FS.DB_STORE_NAME);
+        };
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var putRequest = files.put(FS.analyzePath(path).object.contents, path);
+            putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
+            putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      },loadFilesFromDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = onerror; // no database to load from
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          try {
+            var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
+          } catch(e) {
+            onerror(e);
+            return;
+          }
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var getRequest = files.get(path);
+            getRequest.onsuccess = function getRequest_onsuccess() {
+              if (FS.analyzePath(path).exists) {
+                FS.unlink(path);
+              }
+              FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
+              ok++;
+              if (ok + fail == total) finish();
+            };
+            getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      }};var PATH={splitPath:function (filename) {
+        var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+        return splitPathRe.exec(filename).slice(1);
+      },normalizeArray:function (parts, allowAboveRoot) {
+        // if the path tries to go above the root, `up` ends up > 0
+        var up = 0;
+        for (var i = parts.length - 1; i >= 0; i--) {
+          var last = parts[i];
+          if (last === '.') {
+            parts.splice(i, 1);
+          } else if (last === '..') {
+            parts.splice(i, 1);
+            up++;
+          } else if (up) {
+            parts.splice(i, 1);
+            up--;
+          }
+        }
+        // if the path is allowed to go above the root, restore leading ..s
+        if (allowAboveRoot) {
+          for (; up--; up) {
+            parts.unshift('..');
+          }
+        }
+        return parts;
+      },normalize:function (path) {
+        var isAbsolute = path.charAt(0) === '/',
+            trailingSlash = path.substr(-1) === '/';
+        // Normalize the path
+        path = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), !isAbsolute).join('/');
+        if (!path && !isAbsolute) {
+          path = '.';
+        }
+        if (path && trailingSlash) {
+          path += '/';
+        }
+        return (isAbsolute ? '/' : '') + path;
+      },dirname:function (path) {
+        var result = PATH.splitPath(path),
+            root = result[0],
+            dir = result[1];
+        if (!root && !dir) {
+          // No dirname whatsoever
+          return '.';
+        }
+        if (dir) {
+          // It has a dirname, strip trailing slash
+          dir = dir.substr(0, dir.length - 1);
+        }
+        return root + dir;
+      },basename:function (path) {
+        // EMSCRIPTEN return '/'' for '/', not an empty string
+        if (path === '/') return '/';
+        var lastSlash = path.lastIndexOf('/');
+        if (lastSlash === -1) return path;
+        return path.substr(lastSlash+1);
+      },extname:function (path) {
+        return PATH.splitPath(path)[3];
+      },join:function () {
+        var paths = Array.prototype.slice.call(arguments, 0);
+        return PATH.normalize(paths.join('/'));
+      },join2:function (l, r) {
+        return PATH.normalize(l + '/' + r);
+      },resolve:function () {
+        var resolvedPath = '',
+          resolvedAbsolute = false;
+        for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+          var path = (i >= 0) ? arguments[i] : FS.cwd();
+          // Skip empty and invalid entries
+          if (typeof path !== 'string') {
+            throw new TypeError('Arguments to path.resolve must be strings');
+          } else if (!path) {
+            continue;
+          }
+          resolvedPath = path + '/' + resolvedPath;
+          resolvedAbsolute = path.charAt(0) === '/';
+        }
+        // At this point the path should be resolved to a full absolute path, but
+        // handle relative paths to be safe (might happen when process.cwd() fails)
+        resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
+          return !!p;
+        }), !resolvedAbsolute).join('/');
+        return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+      },relative:function (from, to) {
+        from = PATH.resolve(from).substr(1);
+        to = PATH.resolve(to).substr(1);
+        function trim(arr) {
+          var start = 0;
+          for (; start < arr.length; start++) {
+            if (arr[start] !== '') break;
+          }
+          var end = arr.length - 1;
+          for (; end >= 0; end--) {
+            if (arr[end] !== '') break;
+          }
+          if (start > end) return [];
+          return arr.slice(start, end - start + 1);
+        }
+        var fromParts = trim(from.split('/'));
+        var toParts = trim(to.split('/'));
+        var length = Math.min(fromParts.length, toParts.length);
+        var samePartsLength = length;
+        for (var i = 0; i < length; i++) {
+          if (fromParts[i] !== toParts[i]) {
+            samePartsLength = i;
+            break;
+          }
+        }
+        var outputParts = [];
+        for (var i = samePartsLength; i < fromParts.length; i++) {
+          outputParts.push('..');
+        }
+        outputParts = outputParts.concat(toParts.slice(samePartsLength));
+        return outputParts.join('/');
+      }};var Browser={mainLoop:{scheduler:null,method:"",shouldPause:false,paused:false,queue:[],pause:function () {
+          Browser.mainLoop.shouldPause = true;
+        },resume:function () {
+          if (Browser.mainLoop.paused) {
+            Browser.mainLoop.paused = false;
+            Browser.mainLoop.scheduler();
+          }
+          Browser.mainLoop.shouldPause = false;
+        },updateStatus:function () {
+          if (Module['setStatus']) {
+            var message = Module['statusMessage'] || 'Please wait...';
+            var remaining = Browser.mainLoop.remainingBlockers;
+            var expected = Browser.mainLoop.expectedBlockers;
+            if (remaining) {
+              if (remaining < expected) {
+                Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
+              } else {
+                Module['setStatus'](message);
+              }
+            } else {
+              Module['setStatus']('');
+            }
+          }
+        }},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () {
+        if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
+
+        if (Browser.initted || ENVIRONMENT_IS_WORKER) return;
+        Browser.initted = true;
+
+        try {
+          new Blob();
+          Browser.hasBlobConstructor = true;
+        } catch(e) {
+          Browser.hasBlobConstructor = false;
+          console.log("warning: no blob constructor, cannot create blobs with mimetypes");
+        }
+        Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
+        Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
+        if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
+          console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
+          Module.noImageDecoding = true;
+        }
+
+        // Support for plugins that can process preloaded files. You can add more of these to
+        // your app by creating and appending to Module.preloadPlugins.
+        //
+        // Each plugin is asked if it can handle a file based on the file's name. If it can,
+        // it is given the file's raw data. When it is done, it calls a callback with the file's
+        // (possibly modified) data. For example, a plugin might decompress a file, or it
+        // might create some side data structure for use later (like an Image element, etc.).
+
+        var imagePlugin = {};
+        imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
+          return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
+        };
+        imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
+          var b = null;
+          if (Browser.hasBlobConstructor) {
+            try {
+              b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+              if (b.size !== byteArray.length) { // Safari bug #118630
+                // Safari's Blob can only take an ArrayBuffer
+                b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
+              }
+            } catch(e) {
+              Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
+            }
+          }
+          if (!b) {
+            var bb = new Browser.BlobBuilder();
+            bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
+            b = bb.getBlob();
+          }
+          var url = Browser.URLObject.createObjectURL(b);
+          var img = new Image();
+          img.onload = function img_onload() {
+            assert(img.complete, 'Image ' + name + ' could not be decoded');
+            var canvas = document.createElement('canvas');
+            canvas.width = img.width;
+            canvas.height = img.height;
+            var ctx = canvas.getContext('2d');
+            ctx.drawImage(img, 0, 0);
+            Module["preloadedImages"][name] = canvas;
+            Browser.URLObject.revokeObjectURL(url);
+            if (onload) onload(byteArray);
+          };
+          img.onerror = function img_onerror(event) {
+            console.log('Image ' + url + ' could not be decoded');
+            if (onerror) onerror();
+          };
+          img.src = url;
+        };
+        Module['preloadPlugins'].push(imagePlugin);
+
+        var audioPlugin = {};
+        audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
+          return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
+        };
+        audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
+          var done = false;
+          function finish(audio) {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = audio;
+            if (onload) onload(byteArray);
+          }
+          function fail() {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = new Audio(); // empty shim
+            if (onerror) onerror();
+          }
+          if (Browser.hasBlobConstructor) {
+            try {
+              var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+            } catch(e) {
+              return fail();
+            }
+            var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
+            var audio = new Audio();
+            audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926
+            audio.onerror = function audio_onerror(event) {
+              if (done) return;
+              console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
+              function encode64(data) {
+                var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+                var PAD = '=';
+                var ret = '';
+                var leftchar = 0;
+                var leftbits = 0;
+                for (var i = 0; i < data.length; i++) {
+                  leftchar = (leftchar << 8) | data[i];
+                  leftbits += 8;
+                  while (leftbits >= 6) {
+                    var curr = (leftchar >> (leftbits-6)) & 0x3f;
+                    leftbits -= 6;
+                    ret += BASE[curr];
+                  }
+                }
+                if (leftbits == 2) {
+                  ret += BASE[(leftchar&3) << 4];
+                  ret += PAD + PAD;
+                } else if (leftbits == 4) {
+                  ret += BASE[(leftchar&0xf) << 2];
+                  ret += PAD;
+                }
+                return ret;
+              }
+              audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
+              finish(audio); // we don't wait for confirmation this worked - but it's worth trying
+            };
+            audio.src = url;
+            // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
+            Browser.safeSetTimeout(function() {
+              finish(audio); // try to use it even though it is not necessarily ready to play
+            }, 10000);
+          } else {
+            return fail();
+          }
+        };
+        Module['preloadPlugins'].push(audioPlugin);
+
+        // Canvas event setup
+
+        var canvas = Module['canvas'];
+
+        // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
+        // Module['forcedAspectRatio'] = 4 / 3;
+
+        canvas.requestPointerLock = canvas['requestPointerLock'] ||
+                                    canvas['mozRequestPointerLock'] ||
+                                    canvas['webkitRequestPointerLock'] ||
+                                    canvas['msRequestPointerLock'] ||
+                                    function(){};
+        canvas.exitPointerLock = document['exitPointerLock'] ||
+                                 document['mozExitPointerLock'] ||
+                                 document['webkitExitPointerLock'] ||
+                                 document['msExitPointerLock'] ||
+                                 function(){}; // no-op if function does not exist
+        canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
+
+        function pointerLockChange() {
+          Browser.pointerLock = document['pointerLockElement'] === canvas ||
+                                document['mozPointerLockElement'] === canvas ||
+                                document['webkitPointerLockElement'] === canvas ||
+                                document['msPointerLockElement'] === canvas;
+        }
+
+        document.addEventListener('pointerlockchange', pointerLockChange, false);
+        document.addEventListener('mozpointerlockchange', pointerLockChange, false);
+        document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
+        document.addEventListener('mspointerlockchange', pointerLockChange, false);
+
+        if (Module['elementPointerLock']) {
+          canvas.addEventListener("click", function(ev) {
+            if (!Browser.pointerLock && canvas.requestPointerLock) {
+              canvas.requestPointerLock();
+              ev.preventDefault();
+            }
+          }, false);
+        }
+      },createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) {
+        var ctx;
+        var errorInfo = '?';
+        function onContextCreationError(event) {
+          errorInfo = event.statusMessage || errorInfo;
+        }
+        try {
+          if (useWebGL) {
+            var contextAttributes = {
+              antialias: false,
+              alpha: false
+            };
+
+            if (webGLContextAttributes) {
+              for (var attribute in webGLContextAttributes) {
+                contextAttributes[attribute] = webGLContextAttributes[attribute];
+              }
+            }
+
+
+            canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
+            try {
+              ['experimental-webgl', 'webgl'].some(function(webglId) {
+                return ctx = canvas.getContext(webglId, contextAttributes);
+              });
+            } finally {
+              canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
+            }
+          } else {
+            ctx = canvas.getContext('2d');
+          }
+          if (!ctx) throw ':(';
+        } catch (e) {
+          Module.print('Could not create canvas: ' + [errorInfo, e]);
+          return null;
+        }
+        if (useWebGL) {
+          // Set the background of the WebGL canvas to black
+          canvas.style.backgroundColor = "black";
+
+          // Warn on context loss
+          canvas.addEventListener('webglcontextlost', function(event) {
+            alert('WebGL context lost. You will need to reload the page.');
+          }, false);
+        }
+        if (setInModule) {
+          GLctx = Module.ctx = ctx;
+          Module.useWebGL = useWebGL;
+          Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
+          Browser.init();
+        }
+        return ctx;
+      },destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) {
+        Browser.lockPointer = lockPointer;
+        Browser.resizeCanvas = resizeCanvas;
+        if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;
+        if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;
+
+        var canvas = Module['canvas'];
+        function fullScreenChange() {
+          Browser.isFullScreen = false;
+          var canvasContainer = canvas.parentNode;
+          if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+               document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+               document['fullScreenElement'] || document['fullscreenElement'] ||
+               document['msFullScreenElement'] || document['msFullscreenElement'] ||
+               document['webkitCurrentFullScreenElement']) === canvasContainer) {
+            canvas.cancelFullScreen = document['cancelFullScreen'] ||
+                                      document['mozCancelFullScreen'] ||
+                                      document['webkitCancelFullScreen'] ||
+                                      document['msExitFullscreen'] ||
+                                      document['exitFullscreen'] ||
+                                      function() {};
+            canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document);
+            if (Browser.lockPointer) canvas.requestPointerLock();
+            Browser.isFullScreen = true;
+            if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize();
+          } else {
+
+            // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
+            canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
+            canvasContainer.parentNode.removeChild(canvasContainer);
+
+            if (Browser.resizeCanvas) Browser.setWindowedCanvasSize();
+          }
+          if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen);
+          Browser.updateCanvasDimensions(canvas);
+        }
+
+        if (!Browser.fullScreenHandlersInstalled) {
+          Browser.fullScreenHandlersInstalled = true;
+          document.addEventListener('fullscreenchange', fullScreenChange, false);
+          document.addEventListener('mozfullscreenchange', fullScreenChange, false);
+          document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
+          document.addEventListener('MSFullscreenChange', fullScreenChange, false);
+        }
+
+        // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
+        var canvasContainer = document.createElement("div");
+        canvas.parentNode.insertBefore(canvasContainer, canvas);
+        canvasContainer.appendChild(canvas);
+
+        // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
+        canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] ||
+                                            canvasContainer['mozRequestFullScreen'] ||
+                                            canvasContainer['msRequestFullscreen'] ||
+                                           (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
+        canvasContainer.requestFullScreen();
+      },requestAnimationFrame:function requestAnimationFrame(func) {
+        if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js)
+          setTimeout(func, 1000/60);
+        } else {
+          if (!window.requestAnimationFrame) {
+            window.requestAnimationFrame = window['requestAnimationFrame'] ||
+                                           window['mozRequestAnimationFrame'] ||
+                                           window['webkitRequestAnimationFrame'] ||
+                                           window['msRequestAnimationFrame'] ||
+                                           window['oRequestAnimationFrame'] ||
+                                           window['setTimeout'];
+          }
+          window.requestAnimationFrame(func);
+        }
+      },safeCallback:function (func) {
+        return function() {
+          if (!ABORT) return func.apply(null, arguments);
+        };
+      },safeRequestAnimationFrame:function (func) {
+        return Browser.requestAnimationFrame(function() {
+          if (!ABORT) func();
+        });
+      },safeSetTimeout:function (func, timeout) {
+        return setTimeout(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },safeSetInterval:function (func, timeout) {
+        return setInterval(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },getMimetype:function (name) {
+        return {
+          'jpg': 'image/jpeg',
+          'jpeg': 'image/jpeg',
+          'png': 'image/png',
+          'bmp': 'image/bmp',
+          'ogg': 'audio/ogg',
+          'wav': 'audio/wav',
+          'mp3': 'audio/mpeg'
+        }[name.substr(name.lastIndexOf('.')+1)];
+      },getUserMedia:function (func) {
+        if(!window.getUserMedia) {
+          window.getUserMedia = navigator['getUserMedia'] ||
+                                navigator['mozGetUserMedia'];
+        }
+        window.getUserMedia(func);
+      },getMovementX:function (event) {
+        return event['movementX'] ||
+               event['mozMovementX'] ||
+               event['webkitMovementX'] ||
+               0;
+      },getMovementY:function (event) {
+        return event['movementY'] ||
+               event['mozMovementY'] ||
+               event['webkitMovementY'] ||
+               0;
+      },getMouseWheelDelta:function (event) {
+        return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta));
+      },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup
+        if (Browser.pointerLock) {
+          // When the pointer is locked, calculate the coordinates
+          // based on the movement of the mouse.
+          // Workaround for Firefox bug 764498
+          if (event.type != 'mousemove' &&
+              ('mozMovementX' in event)) {
+            Browser.mouseMovementX = Browser.mouseMovementY = 0;
+          } else {
+            Browser.mouseMovementX = Browser.getMovementX(event);
+            Browser.mouseMovementY = Browser.getMovementY(event);
+          }
+
+          // check if SDL is available
+          if (typeof SDL != "undefined") {
+    Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
+    Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
+          } else {
+    // just add the mouse delta to the current absolut mouse position
+    // FIXME: ideally this should be clamped against the canvas size and zero
+    Browser.mouseX += Browser.mouseMovementX;
+    Browser.mouseY += Browser.mouseMovementY;
+          }
+        } else {
+          // Otherwise, calculate the movement based on the changes
+          // in the coordinates.
+          var rect = Module["canvas"].getBoundingClientRect();
+          var x, y;
+
+          // Neither .scrollX or .pageXOffset are defined in a spec, but
+          // we prefer .scrollX because it is currently in a spec draft.
+          // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
+          var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);
+          var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);
+          if (event.type == 'touchstart' ||
+              event.type == 'touchend' ||
+              event.type == 'touchmove') {
+            var t = event.touches.item(0);
+            if (t) {
+              x = t.pageX - (scrollX + rect.left);
+              y = t.pageY - (scrollY + rect.top);
+            } else {
+              return;
+            }
+          } else {
+            x = event.pageX - (scrollX + rect.left);
+            y = event.pageY - (scrollY + rect.top);
+          }
+
+          // the canvas might be CSS-scaled compared to its backbuffer;
+          // SDL-using content will want mouse coordinates in terms
+          // of backbuffer units.
+          var cw = Module["canvas"].width;
+          var ch = Module["canvas"].height;
+          x = x * (cw / rect.width);
+          y = y * (ch / rect.height);
+
+          Browser.mouseMovementX = x - Browser.mouseX;
+          Browser.mouseMovementY = y - Browser.mouseY;
+          Browser.mouseX = x;
+          Browser.mouseY = y;
+        }
+      },xhrLoad:function (url, onload, onerror) {
+        var xhr = new XMLHttpRequest();
+        xhr.open('GET', url, true);
+        xhr.responseType = 'arraybuffer';
+        xhr.onload = function xhr_onload() {
+          if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
+            onload(xhr.response);
+          } else {
+            onerror();
+          }
+        };
+        xhr.onerror = onerror;
+        xhr.send(null);
+      },asyncLoad:function (url, onload, onerror, noRunDep) {
+        Browser.xhrLoad(url, function(arrayBuffer) {
+          assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
+          onload(new Uint8Array(arrayBuffer));
+          if (!noRunDep) removeRunDependency('al ' + url);
+        }, function(event) {
+          if (onerror) {
+            onerror();
+          } else {
+            throw 'Loading data file "' + url + '" failed.';
+          }
+        });
+        if (!noRunDep) addRunDependency('al ' + url);
+      },resizeListeners:[],updateResizeListeners:function () {
+        var canvas = Module['canvas'];
+        Browser.resizeListeners.forEach(function(listener) {
+          listener(canvas.width, canvas.height);
+        });
+      },setCanvasSize:function (width, height, noUpdates) {
+        var canvas = Module['canvas'];
+        Browser.updateCanvasDimensions(canvas, width, height);
+        if (!noUpdates) Browser.updateResizeListeners();
+      },windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+    var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+    flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
+    HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },setWindowedCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+    var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+    flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
+    HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },updateCanvasDimensions:function (canvas, wNative, hNative) {
+        if (wNative && hNative) {
+          canvas.widthNative = wNative;
+          canvas.heightNative = hNative;
+        } else {
+          wNative = canvas.widthNative;
+          hNative = canvas.heightNative;
+        }
+        var w = wNative;
+        var h = hNative;
+        if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
+          if (w/h < Module['forcedAspectRatio']) {
+            w = Math.round(h * Module['forcedAspectRatio']);
+          } else {
+            h = Math.round(w / Module['forcedAspectRatio']);
+          }
+        }
+        if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+             document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+             document['fullScreenElement'] || document['fullscreenElement'] ||
+             document['msFullScreenElement'] || document['msFullscreenElement'] ||
+             document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
+           var factor = Math.min(screen.width / w, screen.height / h);
+           w = Math.round(w * factor);
+           h = Math.round(h * factor);
+        }
+        if (Browser.resizeCanvas) {
+          if (canvas.width  != w) canvas.width  = w;
+          if (canvas.height != h) canvas.height = h;
+          if (typeof canvas.style != 'undefined') {
+            canvas.style.removeProperty( "width");
+            canvas.style.removeProperty("height");
+          }
+        } else {
+          if (canvas.width  != wNative) canvas.width  = wNative;
+          if (canvas.height != hNative) canvas.height = hNative;
+          if (typeof canvas.style != 'undefined') {
+            if (w != wNative || h != hNative) {
+              canvas.style.setProperty( "width", w + "px", "important");
+              canvas.style.setProperty("height", h + "px", "important");
+            } else {
+              canvas.style.removeProperty( "width");
+              canvas.style.removeProperty("height");
+            }
+          }
+        }
+      }};
+
+
+
+
+
+
+
+  function _mkport() { throw 'TODO' }var SOCKFS={mount:function (mount) {
+        return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createSocket:function (family, type, protocol) {
+        var streaming = type == 1;
+        if (protocol) {
+          assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp
+        }
+
+        // create our internal socket structure
+        var sock = {
+          family: family,
+          type: type,
+          protocol: protocol,
+          server: null,
+          peers: {},
+          pending: [],
+          recv_queue: [],
+          sock_ops: SOCKFS.websocket_sock_ops
+        };
+
+        // create the filesystem node to store the socket structure
+        var name = SOCKFS.nextname();
+        var node = FS.createNode(SOCKFS.root, name, 49152, 0);
+        node.sock = sock;
+
+        // and the wrapping stream that enables library functions such
+        // as read and write to indirectly interact with the socket
+        var stream = FS.createStream({
+          path: name,
+          node: node,
+          flags: FS.modeStringToFlags('r+'),
+          seekable: false,
+          stream_ops: SOCKFS.stream_ops
+        });
+
+        // map the new stream to the socket structure (sockets have a 1:1
+        // relationship with a stream)
+        sock.stream = stream;
+
+        return sock;
+      },getSocket:function (fd) {
+        var stream = FS.getStream(fd);
+        if (!stream || !FS.isSocket(stream.node.mode)) {
+          return null;
+        }
+        return stream.node.sock;
+      },stream_ops:{poll:function (stream) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.poll(sock);
+        },ioctl:function (stream, request, varargs) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.ioctl(sock, request, varargs);
+        },read:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          var msg = sock.sock_ops.recvmsg(sock, length);
+          if (!msg) {
+            // socket is closed
+            return 0;
+          }
+          buffer.set(msg.buffer, offset);
+          return msg.buffer.length;
+        },write:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.sendmsg(sock, buffer, offset, length);
+        },close:function (stream) {
+          var sock = stream.node.sock;
+          sock.sock_ops.close(sock);
+        }},nextname:function () {
+        if (!SOCKFS.nextname.current) {
+          SOCKFS.nextname.current = 0;
+        }
+        return 'socket[' + (SOCKFS.nextname.current++) + ']';
+      },websocket_sock_ops:{createPeer:function (sock, addr, port) {
+          var ws;
+
+          if (typeof addr === 'object') {
+            ws = addr;
+            addr = null;
+            port = null;
+          }
+
+          if (ws) {
+            // for sockets that've already connected (e.g. we're the server)
+            // we can inspect the _socket property for the address
+            if (ws._socket) {
+              addr = ws._socket.remoteAddress;
+              port = ws._socket.remotePort;
+            }
+            // if we're just now initializing a connection to the remote,
+            // inspect the url property
+            else {
+              var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
+              if (!result) {
+                throw new Error('WebSocket URL must be in the format ws(s)://address:port');
+              }
+              addr = result[1];
+              port = parseInt(result[2], 10);
+            }
+          } else {
+            // create the actual websocket object and connect
+            try {
+              // runtimeConfig gets set to true if WebSocket runtime configuration is available.
+              var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
+
+              // The default value is 'ws://' the replace is needed because the compiler replaces "//" comments with '#'
+              // comments without checking context, so we'd end up with ws:#, the replace swaps the "#" for "//" again.
+              var url = 'ws:#'.replace('#', '//');
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['url']) {
+                  url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
+                }
+              }
+
+              if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
+                url = url + addr + ':' + port;
+              }
+
+              // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
+              var subProtocols = 'binary'; // The default value is 'binary'
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['subprotocol']) {
+                  subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
+                }
+              }
+
+              // The regex trims the string (removes spaces at the beginning and end, then splits the string by
+              // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
+              subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
+
+              // The node ws library API for specifying optional subprotocol is slightly different than the browser's.
+              var opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols;
+
+              // If node we use the ws library.
+              var WebSocket = ENVIRONMENT_IS_NODE ? require('ws') : window['WebSocket'];
+              ws = new WebSocket(url, opts);
+              ws.binaryType = 'arraybuffer';
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH);
+            }
+          }
+
+
+          var peer = {
+            addr: addr,
+            port: port,
+            socket: ws,
+            dgram_send_queue: []
+          };
+
+          SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+          SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
+
+          // if this is a bound dgram socket, send the port number first to allow
+          // us to override the ephemeral port reported to us by remotePort on the
+          // remote end.
+          if (sock.type === 2 && typeof sock.sport !== 'undefined') {
+            peer.dgram_send_queue.push(new Uint8Array([
+                255, 255, 255, 255,
+                'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
+                ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
+            ]));
+          }
+
+          return peer;
+        },getPeer:function (sock, addr, port) {
+          return sock.peers[addr + ':' + port];
+        },addPeer:function (sock, peer) {
+          sock.peers[peer.addr + ':' + peer.port] = peer;
+        },removePeer:function (sock, peer) {
+          delete sock.peers[peer.addr + ':' + peer.port];
+        },handlePeerEvents:function (sock, peer) {
+          var first = true;
+
+          var handleOpen = function () {
+            try {
+              var queued = peer.dgram_send_queue.shift();
+              while (queued) {
+                peer.socket.send(queued);
+                queued = peer.dgram_send_queue.shift();
+              }
+            } catch (e) {
+              // not much we can do here in the way of proper error handling as we've already
+              // lied and said this data was sent. shut it down.
+              peer.socket.close();
+            }
+          };
+
+          function handleMessage(data) {
+            assert(typeof data !== 'string' && data.byteLength !== undefined);  // must receive an ArrayBuffer
+            data = new Uint8Array(data);  // make a typed array view on the array buffer
+
+
+            // if this is the port message, override the peer's port with it
+            var wasfirst = first;
+            first = false;
+            if (wasfirst &&
+                data.length === 10 &&
+                data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
+                data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
+              // update the peer's port and it's key in the peer map
+              var newport = ((data[8] << 8) | data[9]);
+              SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+              peer.port = newport;
+              SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+              return;
+            }
+
+            sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
+          };
+
+          if (ENVIRONMENT_IS_NODE) {
+            peer.socket.on('open', handleOpen);
+            peer.socket.on('message', function(data, flags) {
+              if (!flags.binary) {
+                return;
+              }
+              handleMessage((new Uint8Array(data)).buffer);  // copy from node Buffer -> ArrayBuffer
+            });
+            peer.socket.on('error', function() {
+              // don't throw
+            });
+          } else {
+            peer.socket.onopen = handleOpen;
+            peer.socket.onmessage = function peer_socket_onmessage(event) {
+              handleMessage(event.data);
+            };
+          }
+        },poll:function (sock) {
+          if (sock.type === 1 && sock.server) {
+            // listen sockets should only say they're available for reading
+            // if there are pending clients.
+            return sock.pending.length ? (64 | 1) : 0;
+          }
+
+          var mask = 0;
+          var dest = sock.type === 1 ?  // we only care about the socket state for connection-based sockets
+            SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
+            null;
+
+          if (sock.recv_queue.length ||
+              !dest ||  // connection-less sockets are always ready to read
+              (dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {  // let recv return 0 once closed
+            mask |= (64 | 1);
+          }
+
+          if (!dest ||  // connection-less sockets are always ready to write
+              (dest && dest.socket.readyState === dest.socket.OPEN)) {
+            mask |= 4;
+          }
+
+          if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {
+            mask |= 16;
+          }
+
+          return mask;
+        },ioctl:function (sock, request, arg) {
+          switch (request) {
+            case 21531:
+              var bytes = 0;
+              if (sock.recv_queue.length) {
+                bytes = sock.recv_queue[0].data.length;
+              }
+              HEAP32[((arg)>>2)]=bytes;
+              return 0;
+            default:
+              return ERRNO_CODES.EINVAL;
+          }
+        },close:function (sock) {
+          // if we've spawned a listen server, close it
+          if (sock.server) {
+            try {
+              sock.server.close();
+            } catch (e) {
+            }
+            sock.server = null;
+          }
+          // close any peer connections
+          var peers = Object.keys(sock.peers);
+          for (var i = 0; i < peers.length; i++) {
+            var peer = sock.peers[peers[i]];
+            try {
+              peer.socket.close();
+            } catch (e) {
+            }
+            SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+          }
+          return 0;
+        },bind:function (sock, addr, port) {
+          if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already bound
+          }
+          sock.saddr = addr;
+          sock.sport = port || _mkport();
+          // in order to emulate dgram sockets, we need to launch a listen server when
+          // binding on a connection-less socket
+          // note: this is only required on the server side
+          if (sock.type === 2) {
+            // close the existing server if it exists
+            if (sock.server) {
+              sock.server.close();
+              sock.server = null;
+            }
+            // swallow error operation not supported error that occurs when binding in the
+            // browser where this isn't supported
+            try {
+              sock.sock_ops.listen(sock, 0);
+            } catch (e) {
+              if (!(e instanceof FS.ErrnoError)) throw e;
+              if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e;
+            }
+          }
+        },connect:function (sock, addr, port) {
+          if (sock.server) {
+            throw new FS.ErrnoError(ERRNO_CODS.EOPNOTSUPP);
+          }
+
+          // TODO autobind
+          // if (!sock.addr && sock.type == 2) {
+          // }
+
+          // early out if we're already connected / in the middle of connecting
+          if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') {
+            var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+            if (dest) {
+              if (dest.socket.readyState === dest.socket.CONNECTING) {
+                throw new FS.ErrnoError(ERRNO_CODES.EALREADY);
+              } else {
+                throw new FS.ErrnoError(ERRNO_CODES.EISCONN);
+              }
+            }
+          }
+
+          // add the socket to our peer list and set our
+          // destination address / port to match
+          var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+          sock.daddr = peer.addr;
+          sock.dport = peer.port;
+
+          // always "fail" in non-blocking mode
+          throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS);
+        },listen:function (sock, backlog) {
+          if (!ENVIRONMENT_IS_NODE) {
+            throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+          }
+          if (sock.server) {
+             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already listening
+          }
+          var WebSocketServer = require('ws').Server;
+          var host = sock.saddr;
+          sock.server = new WebSocketServer({
+            host: host,
+            port: sock.sport
+            // TODO support backlog
+          });
+
+          sock.server.on('connection', function(ws) {
+            if (sock.type === 1) {
+              var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
+
+              // create a peer on the new socket
+              var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
+              newsock.daddr = peer.addr;
+              newsock.dport = peer.port;
+
+              // push to queue for accept to pick up
+              sock.pending.push(newsock);
+            } else {
+              // create a peer on the listen socket so calling sendto
+              // with the listen socket and an address will resolve
+              // to the correct client
+              SOCKFS.websocket_sock_ops.createPeer(sock, ws);
+            }
+          });
+          sock.server.on('closed', function() {
+            sock.server = null;
+          });
+          sock.server.on('error', function() {
+            // don't throw
+          });
+        },accept:function (listensock) {
+          if (!listensock.server) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          var newsock = listensock.pending.shift();
+          newsock.stream.flags = listensock.stream.flags;
+          return newsock;
+        },getname:function (sock, peer) {
+          var addr, port;
+          if (peer) {
+            if (sock.daddr === undefined || sock.dport === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            }
+            addr = sock.daddr;
+            port = sock.dport;
+          } else {
+            // TODO saddr and sport will be set for bind()'d UDP sockets, but what
+            // should we be returning for TCP sockets that've been connect()'d?
+            addr = sock.saddr || 0;
+            port = sock.sport || 0;
+          }
+          return { addr: addr, port: port };
+        },sendmsg:function (sock, buffer, offset, length, addr, port) {
+          if (sock.type === 2) {
+            // connection-less sockets will honor the message address,
+            // and otherwise fall back to the bound destination address
+            if (addr === undefined || port === undefined) {
+              addr = sock.daddr;
+              port = sock.dport;
+            }
+            // if there was no address to fall back to, error out
+            if (addr === undefined || port === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ);
+            }
+          } else {
+            // connection-based sockets will only use the bound
+            addr = sock.daddr;
+            port = sock.dport;
+          }
+
+          // find the peer for the destination address
+          var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
+
+          // early out if not connected with a connection-based socket
+          if (sock.type === 1) {
+            if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            } else if (dest.socket.readyState === dest.socket.CONNECTING) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // create a copy of the incoming data to send, as the WebSocket API
+          // doesn't work entirely with an ArrayBufferView, it'll just send
+          // the entire underlying buffer
+          var data;
+          if (buffer instanceof Array || buffer instanceof ArrayBuffer) {
+            data = buffer.slice(offset, offset + length);
+          } else {  // ArrayBufferView
+            data = buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + length);
+          }
+
+          // if we're emulating a connection-less dgram socket and don't have
+          // a cached connection, queue the buffer to send upon connect and
+          // lie, saying the data was sent now.
+          if (sock.type === 2) {
+            if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
+              // if we're not connected, open a new connection
+              if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+              }
+              dest.dgram_send_queue.push(data);
+              return length;
+            }
+          }
+
+          try {
+            // send the actual data
+            dest.socket.send(data);
+            return length;
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+        },recvmsg:function (sock, length) {
+          // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
+          if (sock.type === 1 && sock.server) {
+            // tcp servers should not be recv()'ing on the listen socket
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+          }
+
+          var queued = sock.recv_queue.shift();
+          if (!queued) {
+            if (sock.type === 1) {
+              var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+
+              if (!dest) {
+                // if we have a destination address but are not connected, error out
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+              }
+              else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                // return null if the socket has closed
+                return null;
+              }
+              else {
+                // else, our socket is in a valid state but truly has nothing available
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+            } else {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
+          // requeued TCP data it'll be an ArrayBufferView
+          var queuedLength = queued.data.byteLength || queued.data.length;
+          var queuedOffset = queued.data.byteOffset || 0;
+          var queuedBuffer = queued.data.buffer || queued.data;
+          var bytesRead = Math.min(length, queuedLength);
+          var res = {
+            buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
+            addr: queued.addr,
+            port: queued.port
+          };
+
+
+          // push back any unread data for TCP connections
+          if (sock.type === 1 && bytesRead < queuedLength) {
+            var bytesRemaining = queuedLength - bytesRead;
+            queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
+            sock.recv_queue.unshift(queued);
+          }
+
+          return res;
+        }}};function _send(fd, buf, len, flags) {
+      var sock = SOCKFS.getSocket(fd);
+      if (!sock) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      // TODO honor flags
+      return _write(fd, buf, len);
+    }
+
+  function _pwrite(fildes, buf, nbyte, offset) {
+      // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte, offset);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _write(fildes, buf, nbyte) {
+      // ssize_t write(int fildes, const void *buf, size_t nbyte);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+
+
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }
+
+  function _fileno(stream) {
+      // int fileno(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
+      stream = FS.getStreamFromPtr(stream);
+      if (!stream) return -1;
+      return stream.fd;
+    }function _fwrite(ptr, size, nitems, stream) {
+      // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
+      var bytesToWrite = nitems * size;
+      if (bytesToWrite == 0) return 0;
+      var fd = _fileno(stream);
+      var bytesWritten = _write(fd, ptr, bytesToWrite);
+      if (bytesWritten == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return 0;
+      } else {
+        return Math.floor(bytesWritten / size);
+      }
+    }
+
+
+
+  Module["_strlen"] = _strlen;
+
+  function __reallyNegative(x) {
+      return x < 0 || (x === 0 && (1/x) === -Infinity);
+    }function __formatString(format, varargs) {
+      var textIndex = format;
+      var argIndex = 0;
+      function getNextArg(type) {
+        // NOTE: Explicitly ignoring type safety. Otherwise this fails:
+        //       int x = 4; printf("%c\n", (char)x);
+        var ret;
+        if (type === 'double') {
+          ret = HEAPF64[(((varargs)+(argIndex))>>3)];
+        } else if (type == 'i64') {
+          ret = [HEAP32[(((varargs)+(argIndex))>>2)],
+                 HEAP32[(((varargs)+(argIndex+4))>>2)]];
+
+        } else {
+          type = 'i32'; // varargs are always i32, i64, or double
+          ret = HEAP32[(((varargs)+(argIndex))>>2)];
+        }
+        argIndex += Runtime.getNativeFieldSize(type);
+        return ret;
+      }
+
+      var ret = [];
+      var curr, next, currArg;
+      while(1) {
+        var startTextIndex = textIndex;
+        curr = HEAP8[(textIndex)];
+        if (curr === 0) break;
+        next = HEAP8[((textIndex+1)|0)];
+        if (curr == 37) {
+          // Handle flags.
+          var flagAlwaysSigned = false;
+          var flagLeftAlign = false;
+          var flagAlternative = false;
+          var flagZeroPad = false;
+          var flagPadSign = false;
+          flagsLoop: while (1) {
+            switch (next) {
+              case 43:
+                flagAlwaysSigned = true;
+                break;
+              case 45:
+                flagLeftAlign = true;
+                break;
+              case 35:
+                flagAlternative = true;
+                break;
+              case 48:
+                if (flagZeroPad) {
+                  break flagsLoop;
+                } else {
+                  flagZeroPad = true;
+                  break;
+                }
+              case 32:
+                flagPadSign = true;
+                break;
+              default:
+                break flagsLoop;
+            }
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          }
+
+          // Handle width.
+          var width = 0;
+          if (next == 42) {
+            width = getNextArg('i32');
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          } else {
+            while (next >= 48 && next <= 57) {
+              width = width * 10 + (next - 48);
+              textIndex++;
+              next = HEAP8[((textIndex+1)|0)];
+            }
+          }
+
+          // Handle precision.
+          var precisionSet = false, precision = -1;
+          if (next == 46) {
+            precision = 0;
+            precisionSet = true;
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+            if (next == 42) {
+              precision = getNextArg('i32');
+              textIndex++;
+            } else {
+              while(1) {
+                var precisionChr = HEAP8[((textIndex+1)|0)];
+                if (precisionChr < 48 ||
+                    precisionChr > 57) break;
+                precision = precision * 10 + (precisionChr - 48);
+                textIndex++;
+              }
+            }
+            next = HEAP8[((textIndex+1)|0)];
+          }
+          if (precision < 0) {
+            precision = 6; // Standard default.
+            precisionSet = false;
+          }
+
+          // Handle integer sizes. WARNING: These assume a 32-bit architecture!
+          var argSize;
+          switch (String.fromCharCode(next)) {
+            case 'h':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 104) {
+                textIndex++;
+                argSize = 1; // char (actually i32 in varargs)
+              } else {
+                argSize = 2; // short (actually i32 in varargs)
+              }
+              break;
+            case 'l':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 108) {
+                textIndex++;
+                argSize = 8; // long long
+              } else {
+                argSize = 4; // long
+              }
+              break;
+            case 'L': // long long
+            case 'q': // int64_t
+            case 'j': // intmax_t
+              argSize = 8;
+              break;
+            case 'z': // size_t
+            case 't': // ptrdiff_t
+            case 'I': // signed ptrdiff_t or unsigned size_t
+              argSize = 4;
+              break;
+            default:
+              argSize = null;
+          }
+          if (argSize) textIndex++;
+          next = HEAP8[((textIndex+1)|0)];
+
+          // Handle type specifier.
+          switch (String.fromCharCode(next)) {
+            case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': {
+              // Integer.
+              var signed = next == 100 || next == 105;
+              argSize = argSize || 4;
+              var currArg = getNextArg('i' + (argSize * 8));
+              var argText;
+              // Flatten i64-1 [low, high] into a (slightly rounded) double
+              if (argSize == 8) {
+                currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117);
+              }
+              // Truncate to requested size.
+              if (argSize <= 4) {
+                var limit = Math.pow(256, argSize) - 1;
+                currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
+              }
+              // Format the number.
+              var currAbsArg = Math.abs(currArg);
+              var prefix = '';
+              if (next == 100 || next == 105) {
+                argText = reSign(currArg, 8 * argSize, 1).toString(10);
+              } else if (next == 117) {
+                argText = unSign(currArg, 8 * argSize, 1).toString(10);
+                currArg = Math.abs(currArg);
+              } else if (next == 111) {
+                argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
+              } else if (next == 120 || next == 88) {
+                prefix = (flagAlternative && currArg != 0) ? '0x' : '';
+                if (currArg < 0) {
+                  // Represent negative numbers in hex as 2's complement.
+                  currArg = -currArg;
+                  argText = (currAbsArg - 1).toString(16);
+                  var buffer = [];
+                  for (var i = 0; i < argText.length; i++) {
+                    buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
+                  }
+                  argText = buffer.join('');
+                  while (argText.length < argSize * 2) argText = 'f' + argText;
+                } else {
+                  argText = currAbsArg.toString(16);
+                }
+                if (next == 88) {
+                  prefix = prefix.toUpperCase();
+                  argText = argText.toUpperCase();
+                }
+              } else if (next == 112) {
+                if (currAbsArg === 0) {
+                  argText = '(nil)';
+                } else {
+                  prefix = '0x';
+                  argText = currAbsArg.toString(16);
+                }
+              }
+              if (precisionSet) {
+                while (argText.length < precision) {
+                  argText = '0' + argText;
+                }
+              }
+
+              // Add sign if needed
+              if (currArg >= 0) {
+                if (flagAlwaysSigned) {
+                  prefix = '+' + prefix;
+                } else if (flagPadSign) {
+                  prefix = ' ' + prefix;
+                }
+              }
+
+              // Move sign to prefix so we zero-pad after the sign
+              if (argText.charAt(0) == '-') {
+                prefix = '-' + prefix;
+                argText = argText.substr(1);
+              }
+
+              // Add padding.
+              while (prefix.length + argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad) {
+                    argText = '0' + argText;
+                  } else {
+                    prefix = ' ' + prefix;
+                  }
+                }
+              }
+
+              // Insert the result into the buffer.
+              argText = prefix + argText;
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': {
+              // Float.
+              var currArg = getNextArg('double');
+              var argText;
+              if (isNaN(currArg)) {
+                argText = 'nan';
+                flagZeroPad = false;
+              } else if (!isFinite(currArg)) {
+                argText = (currArg < 0 ? '-' : '') + 'inf';
+                flagZeroPad = false;
+              } else {
+                var isGeneral = false;
+                var effectivePrecision = Math.min(precision, 20);
+
+                // Convert g/G to f/F or e/E, as per:
+                // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
+                if (next == 103 || next == 71) {
+                  isGeneral = true;
+                  precision = precision || 1;
+                  var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
+                  if (precision > exponent && exponent >= -4) {
+                    next = ((next == 103) ? 'f' : 'F').charCodeAt(0);
+                    precision -= exponent + 1;
+                  } else {
+                    next = ((next == 103) ? 'e' : 'E').charCodeAt(0);
+                    precision--;
+                  }
+                  effectivePrecision = Math.min(precision, 20);
+                }
+
+                if (next == 101 || next == 69) {
+                  argText = currArg.toExponential(effectivePrecision);
+                  // Make sure the exponent has at least 2 digits.
+                  if (/[eE][-+]\d$/.test(argText)) {
+                    argText = argText.slice(0, -1) + '0' + argText.slice(-1);
+                  }
+                } else if (next == 102 || next == 70) {
+                  argText = currArg.toFixed(effectivePrecision);
+                  if (currArg === 0 && __reallyNegative(currArg)) {
+                    argText = '-' + argText;
+                  }
+                }
+
+                var parts = argText.split('e');
+                if (isGeneral && !flagAlternative) {
+                  // Discard trailing zeros and periods.
+                  while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
+                         (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
+                    parts[0] = parts[0].slice(0, -1);
+                  }
+                } else {
+                  // Make sure we have a period in alternative mode.
+                  if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
+                  // Zero pad until required precision.
+                  while (precision > effectivePrecision++) parts[0] += '0';
+                }
+                argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
+
+                // Capitalize 'E' if needed.
+                if (next == 69) argText = argText.toUpperCase();
+
+                // Add sign.
+                if (currArg >= 0) {
+                  if (flagAlwaysSigned) {
+                    argText = '+' + argText;
+                  } else if (flagPadSign) {
+                    argText = ' ' + argText;
+                  }
+                }
+              }
+
+              // Add padding.
+              while (argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
+                    argText = argText[0] + '0' + argText.slice(1);
+                  } else {
+                    argText = (flagZeroPad ? '0' : ' ') + argText;
+                  }
+                }
+              }
+
+              // Adjust case.
+              if (next < 97) argText = argText.toUpperCase();
+
+              // Insert the result into the buffer.
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 's': {
+              // String.
+              var arg = getNextArg('i8*');
+              var argLength = arg ? _strlen(arg) : '(null)'.length;
+              if (precisionSet) argLength = Math.min(argLength, precision);
+              if (!flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              if (arg) {
+                for (var i = 0; i < argLength; i++) {
+                  ret.push(HEAPU8[((arg++)|0)]);
+                }
+              } else {
+                ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true));
+              }
+              if (flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              break;
+            }
+            case 'c': {
+              // Character.
+              if (flagLeftAlign) ret.push(getNextArg('i8'));
+              while (--width > 0) {
+                ret.push(32);
+              }
+              if (!flagLeftAlign) ret.push(getNextArg('i8'));
+              break;
+            }
+            case 'n': {
+              // Write the length written so far to the next parameter.
+              var ptr = getNextArg('i32*');
+              HEAP32[((ptr)>>2)]=ret.length;
+              break;
+            }
+            case '%': {
+              // Literal percent sign.
+              ret.push(curr);
+              break;
+            }
+            default: {
+              // Unknown specifiers remain untouched.
+              for (var i = startTextIndex; i < textIndex + 2; i++) {
+                ret.push(HEAP8[(i)]);
+              }
+            }
+          }
+          textIndex += 2;
+          // TODO: Support a/A (hex float) and m (last error) specifiers.
+          // TODO: Support %1${specifier} for arg selection.
+        } else {
+          ret.push(curr);
+          textIndex += 1;
+        }
+      }
+      return ret;
+    }function _fprintf(stream, format, varargs) {
+      // int fprintf(FILE *restrict stream, const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var result = __formatString(format, varargs);
+      var stack = Runtime.stackSave();
+      var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream);
+      Runtime.stackRestore(stack);
+      return ret;
+    }function _printf(format, varargs) {
+      // int printf(const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var stdout = HEAP32[((_stdout)>>2)];
+      return _fprintf(stdout, format, varargs);
+    }
+
+
+  Module["_memset"] = _memset;
+
+
+
+  function _emscripten_memcpy_big(dest, src, num) {
+      HEAPU8.set(HEAPU8.subarray(src, src+num), dest);
+      return dest;
+    }
+  Module["_memcpy"] = _memcpy;
+
+  function _free() {
+  }
+  Module["_free"] = _free;
+Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };
+  Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
+  Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
+  Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
+  Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
+  Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }
+FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice;
+___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0;
+__ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor();
+if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); }
+__ATINIT__.push({ func: function() { SOCKFS.root = FS.mount(SOCKFS, {}, null); } });
+STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);
+
+staticSealed = true; // seal the static portion of memory
+
+STACK_MAX = STACK_BASE + 5242880;
+
+DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);
+
+assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");
+
+
+var Math_min = Math.min;
+function asmPrintInt(x, y) {
+  Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+function asmPrintFloat(x, y) {
+  Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+// EMSCRIPTEN_START_ASM
+var asm = (function(global, env, buffer) {
+  'use asm';
+  var HEAP8 = new global.Int8Array(buffer);
+  var HEAP16 = new global.Int16Array(buffer);
+  var HEAP32 = new global.Int32Array(buffer);
+  var HEAPU8 = new global.Uint8Array(buffer);
+  var HEAPU16 = new global.Uint16Array(buffer);
+  var HEAPU32 = new global.Uint32Array(buffer);
+  var HEAPF32 = new global.Float32Array(buffer);
+  var HEAPF64 = new global.Float64Array(buffer);
+
+  var STACKTOP=env.STACKTOP|0;
+  var STACK_MAX=env.STACK_MAX|0;
+  var tempDoublePtr=env.tempDoublePtr|0;
+  var ABORT=env.ABORT|0;
+
+  var __THREW__ = 0;
+  var threwValue = 0;
+  var setjmpId = 0;
+  var undef = 0;
+  var nan = +env.NaN, inf = +env.Infinity;
+  var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
+
+  var tempRet0 = 0;
+  var tempRet1 = 0;
+  var tempRet2 = 0;
+  var tempRet3 = 0;
+  var tempRet4 = 0;
+  var tempRet5 = 0;
+  var tempRet6 = 0;
+  var tempRet7 = 0;
+  var tempRet8 = 0;
+  var tempRet9 = 0;
+  var Math_floor=global.Math.floor;
+  var Math_abs=global.Math.abs;
+  var Math_sqrt=global.Math.sqrt;
+  var Math_pow=global.Math.pow;
+  var Math_cos=global.Math.cos;
+  var Math_sin=global.Math.sin;
+  var Math_tan=global.Math.tan;
+  var Math_acos=global.Math.acos;
+  var Math_asin=global.Math.asin;
+  var Math_atan=global.Math.atan;
+  var Math_atan2=global.Math.atan2;
+  var Math_exp=global.Math.exp;
+  var Math_log=global.Math.log;
+  var Math_ceil=global.Math.ceil;
+  var Math_imul=global.Math.imul;
+  var abort=env.abort;
+  var assert=env.assert;
+  var asmPrintInt=env.asmPrintInt;
+  var asmPrintFloat=env.asmPrintFloat;
+  var Math_min=env.min;
+  var _free=env._free;
+  var _emscripten_memcpy_big=env._emscripten_memcpy_big;
+  var _printf=env._printf;
+  var _send=env._send;
+  var _pwrite=env._pwrite;
+  var __reallyNegative=env.__reallyNegative;
+  var _fwrite=env._fwrite;
+  var _malloc=env._malloc;
+  var _mkport=env._mkport;
+  var _fprintf=env._fprintf;
+  var ___setErrNo=env.___setErrNo;
+  var __formatString=env.__formatString;
+  var _fileno=env._fileno;
+  var _fflush=env._fflush;
+  var _write=env._write;
+  var tempFloat = 0.0;
+
+// EMSCRIPTEN_START_FUNCS
+function _main(i3, i5) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i1;
+ L1 : do {
+  if ((i3 | 0) > 1) {
+   i3 = HEAP8[HEAP32[i5 + 4 >> 2] | 0] | 0;
+   switch (i3 | 0) {
+   case 50:
+    {
+     i3 = 625;
+     break L1;
+    }
+   case 51:
+    {
+     i4 = 4;
+     break L1;
+    }
+   case 52:
+    {
+     i3 = 6250;
+     break L1;
+    }
+   case 53:
+    {
+     i3 = 12500;
+     break L1;
+    }
+   case 49:
+    {
+     i3 = 75;
+     break L1;
+    }
+   case 48:
+    {
+     i12 = 0;
+     STACKTOP = i1;
+     return i12 | 0;
+    }
+   default:
+    {
+     HEAP32[i2 >> 2] = i3 + -48;
+     _printf(8, i2 | 0) | 0;
+     i12 = -1;
+     STACKTOP = i1;
+     return i12 | 0;
+    }
+   }
+  } else {
+   i4 = 4;
+  }
+ } while (0);
+ if ((i4 | 0) == 4) {
+  i3 = 1250;
+ }
+ i4 = 0;
+ i12 = 0;
+ do {
+  i9 = (i4 | 0) % 10 | 0;
+  i5 = i9 + i4 | 0;
+  i6 = (i4 | 0) % 255 | 0;
+  i8 = (i4 | 0) % 15 | 0;
+  i10 = ((i4 | 0) % 120 | 0 | 0) % 1024 | 0;
+  i11 = ((i4 | 0) % 1024 | 0) + i4 | 0;
+  i5 = ((i5 | 0) % 1024 | 0) + i5 | 0;
+  i8 = ((i8 | 0) % 1024 | 0) + i8 | 0;
+  i6 = (((i6 | 0) % 1024 | 0) + i6 + i10 | 0) % 1024 | 0;
+  i7 = 0;
+  do {
+   i17 = i7 << 1;
+   i14 = (i7 | 0) % 120 | 0;
+   i18 = (i17 | 0) % 1024 | 0;
+   i19 = (i9 + i7 | 0) % 1024 | 0;
+   i16 = ((i7 | 0) % 255 | 0 | 0) % 1024 | 0;
+   i15 = (i7 | 0) % 1024 | 0;
+   i13 = ((i7 | 0) % 15 | 0 | 0) % 1024 | 0;
+   i12 = (((i19 + i18 + i16 + i10 + i15 + i13 + ((i11 + i19 | 0) % 1024 | 0) + ((i5 + i18 | 0) % 1024 | 0) + ((i18 + i17 + i16 | 0) % 1024 | 0) + i6 + ((i8 + i15 | 0) % 1024 | 0) + ((((i14 | 0) % 1024 | 0) + i14 + i13 | 0) % 1024 | 0) | 0) % 100 | 0) + i12 | 0) % 10240 | 0;
+   i7 = i7 + 1 | 0;
+  } while ((i7 | 0) != 5e4);
+  i4 = i4 + 1 | 0;
+ } while ((i4 | 0) < (i3 | 0));
+ HEAP32[i2 >> 2] = i12;
+ _printf(24, i2 | 0) | 0;
+ i19 = 0;
+ STACKTOP = i1;
+ return i19 | 0;
+}
+function _memcpy(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ if ((i1 | 0) >= 4096) return _emscripten_memcpy_big(i3 | 0, i2 | 0, i1 | 0) | 0;
+ i4 = i3 | 0;
+ if ((i3 & 3) == (i2 & 3)) {
+  while (i3 & 3) {
+   if ((i1 | 0) == 0) return i4 | 0;
+   HEAP8[i3] = HEAP8[i2] | 0;
+   i3 = i3 + 1 | 0;
+   i2 = i2 + 1 | 0;
+   i1 = i1 - 1 | 0;
+  }
+  while ((i1 | 0) >= 4) {
+   HEAP32[i3 >> 2] = HEAP32[i2 >> 2];
+   i3 = i3 + 4 | 0;
+   i2 = i2 + 4 | 0;
+   i1 = i1 - 4 | 0;
+  }
+ }
+ while ((i1 | 0) > 0) {
+  HEAP8[i3] = HEAP8[i2] | 0;
+  i3 = i3 + 1 | 0;
+  i2 = i2 + 1 | 0;
+  i1 = i1 - 1 | 0;
+ }
+ return i4 | 0;
+}
+function _memset(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = i1 + i3 | 0;
+ if ((i3 | 0) >= 20) {
+  i4 = i4 & 255;
+  i7 = i1 & 3;
+  i6 = i4 | i4 << 8 | i4 << 16 | i4 << 24;
+  i5 = i2 & ~3;
+  if (i7) {
+   i7 = i1 + 4 - i7 | 0;
+   while ((i1 | 0) < (i7 | 0)) {
+    HEAP8[i1] = i4;
+    i1 = i1 + 1 | 0;
+   }
+  }
+  while ((i1 | 0) < (i5 | 0)) {
+   HEAP32[i1 >> 2] = i6;
+   i1 = i1 + 4 | 0;
+  }
+ }
+ while ((i1 | 0) < (i2 | 0)) {
+  HEAP8[i1] = i4;
+  i1 = i1 + 1 | 0;
+ }
+ return i1 - i3 | 0;
+}
+function copyTempDouble(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+ HEAP8[tempDoublePtr + 4 | 0] = HEAP8[i1 + 4 | 0];
+ HEAP8[tempDoublePtr + 5 | 0] = HEAP8[i1 + 5 | 0];
+ HEAP8[tempDoublePtr + 6 | 0] = HEAP8[i1 + 6 | 0];
+ HEAP8[tempDoublePtr + 7 | 0] = HEAP8[i1 + 7 | 0];
+}
+function copyTempFloat(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+}
+function runPostSets() {}
+function _strlen(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = i1;
+ while (HEAP8[i2] | 0) {
+  i2 = i2 + 1 | 0;
+ }
+ return i2 - i1 | 0;
+}
+function stackAlloc(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + i1 | 0;
+ STACKTOP = STACKTOP + 7 & -8;
+ return i2 | 0;
+}
+function setThrew(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ if ((__THREW__ | 0) == 0) {
+  __THREW__ = i1;
+  threwValue = i2;
+ }
+}
+function stackRestore(i1) {
+ i1 = i1 | 0;
+ STACKTOP = i1;
+}
+function setTempRet9(i1) {
+ i1 = i1 | 0;
+ tempRet9 = i1;
+}
+function setTempRet8(i1) {
+ i1 = i1 | 0;
+ tempRet8 = i1;
+}
+function setTempRet7(i1) {
+ i1 = i1 | 0;
+ tempRet7 = i1;
+}
+function setTempRet6(i1) {
+ i1 = i1 | 0;
+ tempRet6 = i1;
+}
+function setTempRet5(i1) {
+ i1 = i1 | 0;
+ tempRet5 = i1;
+}
+function setTempRet4(i1) {
+ i1 = i1 | 0;
+ tempRet4 = i1;
+}
+function setTempRet3(i1) {
+ i1 = i1 | 0;
+ tempRet3 = i1;
+}
+function setTempRet2(i1) {
+ i1 = i1 | 0;
+ tempRet2 = i1;
+}
+function setTempRet1(i1) {
+ i1 = i1 | 0;
+ tempRet1 = i1;
+}
+function setTempRet0(i1) {
+ i1 = i1 | 0;
+ tempRet0 = i1;
+}
+function stackSave() {
+ return STACKTOP | 0;
+}
+
+// EMSCRIPTEN_END_FUNCS
+
+
+  return { _strlen: _strlen, _memcpy: _memcpy, _main: _main, _memset: _memset, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, setTempRet1: setTempRet1, setTempRet2: setTempRet2, setTempRet3: setTempRet3, setTempRet4: setTempRet4, setTempRet5: setTempRet5, setTempRet6: setTempRet6, setTempRet7: setTempRet7, setTempRet8: setTempRet8, setTempRet9: setTempRet9 };
+})
+// EMSCRIPTEN_END_ASM
+({ "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array }, { "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "_free": _free, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_printf": _printf, "_send": _send, "_pwrite": _pwrite, "__reallyNegative": __reallyNegative, "_fwrite": _fwrite, "_malloc": _malloc, "_mkport": _mkport, "_fprintf": _fprintf, "___setErrNo": ___setErrNo, "__formatString": __formatString, "_fileno": _fileno, "_fflush": _fflush, "_write": _write, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "NaN": NaN, "Infinity": Infinity }, buffer);
+var _strlen = Module["_strlen"] = asm["_strlen"];
+var _memcpy = Module["_memcpy"] = asm["_memcpy"];
+var _main = Module["_main"] = asm["_main"];
+var _memset = Module["_memset"] = asm["_memset"];
+var runPostSets = Module["runPostSets"] = asm["runPostSets"];
+
+Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
+Runtime.stackSave = function() { return asm['stackSave']() };
+Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
+
+
+// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included
+var i64Math = null;
+
+// === Auto-generated postamble setup entry stuff ===
+
+if (memoryInitializer) {
+  if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
+    var data = Module['readBinary'](memoryInitializer);
+    HEAPU8.set(data, STATIC_BASE);
+  } else {
+    addRunDependency('memory initializer');
+    Browser.asyncLoad(memoryInitializer, function(data) {
+      HEAPU8.set(data, STATIC_BASE);
+      removeRunDependency('memory initializer');
+    }, function(data) {
+      throw 'could not load memory initializer ' + memoryInitializer;
+    });
+  }
+}
+
+function ExitStatus(status) {
+  this.name = "ExitStatus";
+  this.message = "Program terminated with exit(" + status + ")";
+  this.status = status;
+};
+ExitStatus.prototype = new Error();
+ExitStatus.prototype.constructor = ExitStatus;
+
+var initialStackTop;
+var preloadStartTime = null;
+var calledMain = false;
+
+dependenciesFulfilled = function runCaller() {
+  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
+  if (!Module['calledRun'] && shouldRunNow) run([].concat(Module["arguments"]));
+  if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
+}
+
+Module['callMain'] = Module.callMain = function callMain(args) {
+  assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
+  assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
+
+  args = args || [];
+
+  ensureInitRuntime();
+
+  var argc = args.length+1;
+  function pad() {
+    for (var i = 0; i < 4-1; i++) {
+      argv.push(0);
+    }
+  }
+  var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ];
+  pad();
+  for (var i = 0; i < argc-1; i = i + 1) {
+    argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL));
+    pad();
+  }
+  argv.push(0);
+  argv = allocate(argv, 'i32', ALLOC_NORMAL);
+
+  initialStackTop = STACKTOP;
+
+  try {
+
+    var ret = Module['_main'](argc, argv, 0);
+
+
+    // if we're not running an evented main loop, it's time to exit
+    if (!Module['noExitRuntime']) {
+      exit(ret);
+    }
+  }
+  catch(e) {
+    if (e instanceof ExitStatus) {
+      // exit() throws this once it's done to make sure execution
+      // has been stopped completely
+      return;
+    } else if (e == 'SimulateInfiniteLoop') {
+      // running an evented main loop, don't immediately exit
+      Module['noExitRuntime'] = true;
+      return;
+    } else {
+      if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
+      throw e;
+    }
+  } finally {
+    calledMain = true;
+  }
+}
+
+
+
+
+function run(args) {
+  args = args || Module['arguments'];
+
+  if (preloadStartTime === null) preloadStartTime = Date.now();
+
+  if (runDependencies > 0) {
+    Module.printErr('run() called, but dependencies remain, so not running');
+    return;
+  }
+
+  preRun();
+
+  if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
+  if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
+
+  function doRun() {
+    if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
+    Module['calledRun'] = true;
+
+    ensureInitRuntime();
+
+    preMain();
+
+    if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
+      Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
+    }
+
+    if (Module['_main'] && shouldRunNow) {
+      Module['callMain'](args);
+    }
+
+    postRun();
+  }
+
+  if (Module['setStatus']) {
+    Module['setStatus']('Running...');
+    setTimeout(function() {
+      setTimeout(function() {
+        Module['setStatus']('');
+      }, 1);
+      if (!ABORT) doRun();
+    }, 1);
+  } else {
+    doRun();
+  }
+}
+Module['run'] = Module.run = run;
+
+function exit(status) {
+  ABORT = true;
+  EXITSTATUS = status;
+  STACKTOP = initialStackTop;
+
+  // exit the runtime
+  exitRuntime();
+
+  // TODO We should handle this differently based on environment.
+  // In the browser, the best we can do is throw an exception
+  // to halt execution, but in node we could process.exit and
+  // I'd imagine SM shell would have something equivalent.
+  // This would let us set a proper exit status (which
+  // would be great for checking test exit statuses).
+  // https://github.com/kripken/emscripten/issues/1371
+
+  // throw an exception to halt the current execution
+  throw new ExitStatus(status);
+}
+Module['exit'] = Module.exit = exit;
+
+function abort(text) {
+  if (text) {
+    Module.print(text);
+    Module.printErr(text);
+  }
+
+  ABORT = true;
+  EXITSTATUS = 1;
+
+  var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.';
+
+  throw 'abort() at ' + stackTrace() + extra;
+}
+Module['abort'] = Module.abort = abort;
+
+// {{PRE_RUN_ADDITIONS}}
+
+if (Module['preInit']) {
+  if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
+  while (Module['preInit'].length > 0) {
+    Module['preInit'].pop()();
+  }
+}
+
+// shouldRunNow refers to calling main(), not run().
+var shouldRunNow = true;
+if (Module['noInitialRun']) {
+  shouldRunNow = false;
+}
+
+
+run([].concat(Module["arguments"]));
diff --git a/test/mjsunit/asm/embenchen/corrections.js b/test/mjsunit/asm/embenchen/corrections.js
new file mode 100644
index 0000000..05cdc4c
--- /dev/null
+++ b/test/mjsunit/asm/embenchen/corrections.js
@@ -0,0 +1,5983 @@
+var EXPECTED_OUTPUT = 'final: 40006013:58243.\n';
+var Module = {
+  arguments: [1],
+  print: function(x) {Module.printBuffer += x + '\n';},
+  preRun: [function() {Module.printBuffer = ''}],
+  postRun: [function() {
+    assertEquals(EXPECTED_OUTPUT, Module.printBuffer);
+  }],
+};
+// The Module object: Our interface to the outside world. We import
+// and export values on it, and do the work to get that through
+// closure compiler if necessary. There are various ways Module can be used:
+// 1. Not defined. We create it here
+// 2. A function parameter, function(Module) { ..generated code.. }
+// 3. pre-run appended it, var Module = {}; ..generated code..
+// 4. External script tag defines var Module.
+// We need to do an eval in order to handle the closure compiler
+// case, where this code here is minified but Module was defined
+// elsewhere (e.g. case 4 above). We also need to check if Module
+// already exists (e.g. case 3 above).
+// Note that if you want to run closure, and also to use Module
+// after the generated code, you will need to define   var Module = {};
+// before the code. Then that object will be used in the code, and you
+// can continue to use Module afterwards as well.
+var Module;
+if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {};
+
+// Sometimes an existing Module object exists with properties
+// meant to overwrite the default module functionality. Here
+// we collect those properties and reapply _after_ we configure
+// the current environment's defaults to avoid having to be so
+// defensive during initialization.
+var moduleOverrides = {};
+for (var key in Module) {
+  if (Module.hasOwnProperty(key)) {
+    moduleOverrides[key] = Module[key];
+  }
+}
+
+// The environment setup code below is customized to use Module.
+// *** Environment setup code ***
+var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
+var ENVIRONMENT_IS_WEB = typeof window === 'object';
+var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
+var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
+
+if (ENVIRONMENT_IS_NODE) {
+  // Expose functionality in the same simple way that the shells work
+  // Note that we pollute the global namespace here, otherwise we break in node
+  if (!Module['print']) Module['print'] = function print(x) {
+    process['stdout'].write(x + '\n');
+  };
+  if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+    process['stderr'].write(x + '\n');
+  };
+
+  var nodeFS = require('fs');
+  var nodePath = require('path');
+
+  Module['read'] = function read(filename, binary) {
+    filename = nodePath['normalize'](filename);
+    var ret = nodeFS['readFileSync'](filename);
+    // The path is absolute if the normalized version is the same as the resolved.
+    if (!ret && filename != nodePath['resolve'](filename)) {
+      filename = path.join(__dirname, '..', 'src', filename);
+      ret = nodeFS['readFileSync'](filename);
+    }
+    if (ret && !binary) ret = ret.toString();
+    return ret;
+  };
+
+  Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) };
+
+  Module['load'] = function load(f) {
+    globalEval(read(f));
+  };
+
+  Module['arguments'] = process['argv'].slice(2);
+
+  module['exports'] = Module;
+}
+else if (ENVIRONMENT_IS_SHELL) {
+  if (!Module['print']) Module['print'] = print;
+  if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
+
+  if (typeof read != 'undefined') {
+    Module['read'] = read;
+  } else {
+    Module['read'] = function read() { throw 'no read() available (jsc?)' };
+  }
+
+  Module['readBinary'] = function readBinary(f) {
+    return read(f, 'binary');
+  };
+
+  if (typeof scriptArgs != 'undefined') {
+    Module['arguments'] = scriptArgs;
+  } else if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  this['Module'] = Module;
+
+  eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly)
+}
+else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+  Module['read'] = function read(url) {
+    var xhr = new XMLHttpRequest();
+    xhr.open('GET', url, false);
+    xhr.send(null);
+    return xhr.responseText;
+  };
+
+  if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  if (typeof console !== 'undefined') {
+    if (!Module['print']) Module['print'] = function print(x) {
+      console.log(x);
+    };
+    if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+      console.log(x);
+    };
+  } else {
+    // Probably a worker, and without console.log. We can do very little here...
+    var TRY_USE_DUMP = false;
+    if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
+      dump(x);
+    }) : (function(x) {
+      // self.postMessage(x); // enable this if you want stdout to be sent as messages
+    }));
+  }
+
+  if (ENVIRONMENT_IS_WEB) {
+    window['Module'] = Module;
+  } else {
+    Module['load'] = importScripts;
+  }
+}
+else {
+  // Unreachable because SHELL is dependant on the others
+  throw 'Unknown runtime environment. Where are we?';
+}
+
+function globalEval(x) {
+  eval.call(null, x);
+}
+if (!Module['load'] == 'undefined' && Module['read']) {
+  Module['load'] = function load(f) {
+    globalEval(Module['read'](f));
+  };
+}
+if (!Module['print']) {
+  Module['print'] = function(){};
+}
+if (!Module['printErr']) {
+  Module['printErr'] = Module['print'];
+}
+if (!Module['arguments']) {
+  Module['arguments'] = [];
+}
+// *** Environment setup code ***
+
+// Closure helpers
+Module.print = Module['print'];
+Module.printErr = Module['printErr'];
+
+// Callbacks
+Module['preRun'] = [];
+Module['postRun'] = [];
+
+// Merge back in the overrides
+for (var key in moduleOverrides) {
+  if (moduleOverrides.hasOwnProperty(key)) {
+    Module[key] = moduleOverrides[key];
+  }
+}
+
+
+
+// === Auto-generated preamble library stuff ===
+
+//========================================
+// Runtime code shared with compiler
+//========================================
+
+var Runtime = {
+  stackSave: function () {
+    return STACKTOP;
+  },
+  stackRestore: function (stackTop) {
+    STACKTOP = stackTop;
+  },
+  forceAlign: function (target, quantum) {
+    quantum = quantum || 4;
+    if (quantum == 1) return target;
+    if (isNumber(target) && isNumber(quantum)) {
+      return Math.ceil(target/quantum)*quantum;
+    } else if (isNumber(quantum) && isPowerOfTwo(quantum)) {
+      return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')';
+    }
+    return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
+  },
+  isNumberType: function (type) {
+    return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
+  },
+  isPointerType: function isPointerType(type) {
+  return type[type.length-1] == '*';
+},
+  isStructType: function isStructType(type) {
+  if (isPointerType(type)) return false;
+  if (isArrayType(type)) return true;
+  if (/<?\{ ?[^}]* ?\}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types
+  // See comment in isStructPointerType()
+  return type[0] == '%';
+},
+  INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
+  FLOAT_TYPES: {"float":0,"double":0},
+  or64: function (x, y) {
+    var l = (x | 0) | (y | 0);
+    var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  and64: function (x, y) {
+    var l = (x | 0) & (y | 0);
+    var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  xor64: function (x, y) {
+    var l = (x | 0) ^ (y | 0);
+    var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  getNativeTypeSize: function (type) {
+    switch (type) {
+      case 'i1': case 'i8': return 1;
+      case 'i16': return 2;
+      case 'i32': return 4;
+      case 'i64': return 8;
+      case 'float': return 4;
+      case 'double': return 8;
+      default: {
+        if (type[type.length-1] === '*') {
+          return Runtime.QUANTUM_SIZE; // A pointer
+        } else if (type[0] === 'i') {
+          var bits = parseInt(type.substr(1));
+          assert(bits % 8 === 0);
+          return bits/8;
+        } else {
+          return 0;
+        }
+      }
+    }
+  },
+  getNativeFieldSize: function (type) {
+    return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE);
+  },
+  dedup: function dedup(items, ident) {
+  var seen = {};
+  if (ident) {
+    return items.filter(function(item) {
+      if (seen[item[ident]]) return false;
+      seen[item[ident]] = true;
+      return true;
+    });
+  } else {
+    return items.filter(function(item) {
+      if (seen[item]) return false;
+      seen[item] = true;
+      return true;
+    });
+  }
+},
+  set: function set() {
+  var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
+  var ret = {};
+  for (var i = 0; i < args.length; i++) {
+    ret[args[i]] = 0;
+  }
+  return ret;
+},
+  STACK_ALIGN: 8,
+  getAlignSize: function (type, size, vararg) {
+    // we align i64s and doubles on 64-bit boundaries, unlike x86
+    if (!vararg && (type == 'i64' || type == 'double')) return 8;
+    if (!type) return Math.min(size, 8); // align structures internally to 64 bits
+    return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE);
+  },
+  calculateStructAlignment: function calculateStructAlignment(type) {
+    type.flatSize = 0;
+    type.alignSize = 0;
+    var diffs = [];
+    var prev = -1;
+    var index = 0;
+    type.flatIndexes = type.fields.map(function(field) {
+      index++;
+      var size, alignSize;
+      if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
+        size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
+        alignSize = Runtime.getAlignSize(field, size);
+      } else if (Runtime.isStructType(field)) {
+        if (field[1] === '0') {
+          // this is [0 x something]. When inside another structure like here, it must be at the end,
+          // and it adds no size
+          // XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!');
+          size = 0;
+          if (Types.types[field]) {
+            alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+          } else {
+            alignSize = type.alignSize || QUANTUM_SIZE;
+          }
+        } else {
+          size = Types.types[field].flatSize;
+          alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+        }
+      } else if (field[0] == 'b') {
+        // bN, large number field, like a [N x i8]
+        size = field.substr(1)|0;
+        alignSize = 1;
+      } else if (field[0] === '<') {
+        // vector type
+        size = alignSize = Types.types[field].flatSize; // fully aligned
+      } else if (field[0] === 'i') {
+        // illegal integer field, that could not be legalized because it is an internal structure field
+        // it is ok to have such fields, if we just use them as markers of field size and nothing more complex
+        size = alignSize = parseInt(field.substr(1))/8;
+        assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field);
+      } else {
+        assert(false, 'invalid type for calculateStructAlignment');
+      }
+      if (type.packed) alignSize = 1;
+      type.alignSize = Math.max(type.alignSize, alignSize);
+      var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
+      type.flatSize = curr + size;
+      if (prev >= 0) {
+        diffs.push(curr-prev);
+      }
+      prev = curr;
+      return curr;
+    });
+    if (type.name_ && type.name_[0] === '[') {
+      // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
+      // allocating a potentially huge array for [999999 x i8] etc.
+      type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
+    }
+    type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
+    if (diffs.length == 0) {
+      type.flatFactor = type.flatSize;
+    } else if (Runtime.dedup(diffs).length == 1) {
+      type.flatFactor = diffs[0];
+    }
+    type.needsFlattening = (type.flatFactor != 1);
+    return type.flatIndexes;
+  },
+  generateStructInfo: function (struct, typeName, offset) {
+    var type, alignment;
+    if (typeName) {
+      offset = offset || 0;
+      type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
+      if (!type) return null;
+      if (type.fields.length != struct.length) {
+        printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo');
+        return null;
+      }
+      alignment = type.flatIndexes;
+    } else {
+      var type = { fields: struct.map(function(item) { return item[0] }) };
+      alignment = Runtime.calculateStructAlignment(type);
+    }
+    var ret = {
+      __size__: type.flatSize
+    };
+    if (typeName) {
+      struct.forEach(function(item, i) {
+        if (typeof item === 'string') {
+          ret[item] = alignment[i] + offset;
+        } else {
+          // embedded struct
+          var key;
+          for (var k in item) key = k;
+          ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
+        }
+      });
+    } else {
+      struct.forEach(function(item, i) {
+        ret[item[1]] = alignment[i];
+      });
+    }
+    return ret;
+  },
+  dynCall: function (sig, ptr, args) {
+    if (args && args.length) {
+      if (!args.splice) args = Array.prototype.slice.call(args);
+      args.splice(0, 0, ptr);
+      return Module['dynCall_' + sig].apply(null, args);
+    } else {
+      return Module['dynCall_' + sig].call(null, ptr);
+    }
+  },
+  functionPointers: [],
+  addFunction: function (func) {
+    for (var i = 0; i < Runtime.functionPointers.length; i++) {
+      if (!Runtime.functionPointers[i]) {
+        Runtime.functionPointers[i] = func;
+        return 2*(1 + i);
+      }
+    }
+    throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
+  },
+  removeFunction: function (index) {
+    Runtime.functionPointers[(index-2)/2] = null;
+  },
+  getAsmConst: function (code, numArgs) {
+    // code is a constant string on the heap, so we can cache these
+    if (!Runtime.asmConstCache) Runtime.asmConstCache = {};
+    var func = Runtime.asmConstCache[code];
+    if (func) return func;
+    var args = [];
+    for (var i = 0; i < numArgs; i++) {
+      args.push(String.fromCharCode(36) + i); // $0, $1 etc
+    }
+    var source = Pointer_stringify(code);
+    if (source[0] === '"') {
+      // tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct
+      if (source.indexOf('"', 1) === source.length-1) {
+        source = source.substr(1, source.length-2);
+      } else {
+        // something invalid happened, e.g. EM_ASM("..code($0)..", input)
+        abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)');
+      }
+    }
+    try {
+      var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node
+    } catch(e) {
+      Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)');
+      throw e;
+    }
+    return Runtime.asmConstCache[code] = evalled;
+  },
+  warnOnce: function (text) {
+    if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
+    if (!Runtime.warnOnce.shown[text]) {
+      Runtime.warnOnce.shown[text] = 1;
+      Module.printErr(text);
+    }
+  },
+  funcWrappers: {},
+  getFuncWrapper: function (func, sig) {
+    assert(sig);
+    if (!Runtime.funcWrappers[func]) {
+      Runtime.funcWrappers[func] = function dynCall_wrapper() {
+        return Runtime.dynCall(sig, func, arguments);
+      };
+    }
+    return Runtime.funcWrappers[func];
+  },
+  UTF8Processor: function () {
+    var buffer = [];
+    var needed = 0;
+    this.processCChar = function (code) {
+      code = code & 0xFF;
+
+      if (buffer.length == 0) {
+        if ((code & 0x80) == 0x00) {        // 0xxxxxxx
+          return String.fromCharCode(code);
+        }
+        buffer.push(code);
+        if ((code & 0xE0) == 0xC0) {        // 110xxxxx
+          needed = 1;
+        } else if ((code & 0xF0) == 0xE0) { // 1110xxxx
+          needed = 2;
+        } else {                            // 11110xxx
+          needed = 3;
+        }
+        return '';
+      }
+
+      if (needed) {
+        buffer.push(code);
+        needed--;
+        if (needed > 0) return '';
+      }
+
+      var c1 = buffer[0];
+      var c2 = buffer[1];
+      var c3 = buffer[2];
+      var c4 = buffer[3];
+      var ret;
+      if (buffer.length == 2) {
+        ret = String.fromCharCode(((c1 & 0x1F) << 6)  | (c2 & 0x3F));
+      } else if (buffer.length == 3) {
+        ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6)  | (c3 & 0x3F));
+      } else {
+        // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+        var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
+                        ((c3 & 0x3F) << 6)  | (c4 & 0x3F);
+        ret = String.fromCharCode(
+          Math.floor((codePoint - 0x10000) / 0x400) + 0xD800,
+          (codePoint - 0x10000) % 0x400 + 0xDC00);
+      }
+      buffer.length = 0;
+      return ret;
+    }
+    this.processJSString = function processJSString(string) {
+      /* TODO: use TextEncoder when present,
+        var encoder = new TextEncoder();
+        encoder['encoding'] = "utf-8";
+        var utf8Array = encoder['encode'](aMsg.data);
+      */
+      string = unescape(encodeURIComponent(string));
+      var ret = [];
+      for (var i = 0; i < string.length; i++) {
+        ret.push(string.charCodeAt(i));
+      }
+      return ret;
+    }
+  },
+  getCompilerSetting: function (name) {
+    throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work';
+  },
+  stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+7)&-8); return ret; },
+  staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = (((STATICTOP)+7)&-8); return ret; },
+  dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = (((DYNAMICTOP)+7)&-8); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; },
+  alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; },
+  makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*(+4294967296))) : ((+((low>>>0)))+((+((high|0)))*(+4294967296)))); return ret; },
+  GLOBAL_BASE: 8,
+  QUANTUM_SIZE: 4,
+  __dummy__: 0
+}
+
+
+Module['Runtime'] = Runtime;
+
+
+
+
+
+
+
+
+
+//========================================
+// Runtime essentials
+//========================================
+
+var __THREW__ = 0; // Used in checking for thrown exceptions.
+
+var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort()
+var EXITSTATUS = 0;
+
+var undef = 0;
+// tempInt is used for 32-bit signed values or smaller. tempBigInt is used
+// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt
+var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat;
+var tempI64, tempI64b;
+var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9;
+
+function assert(condition, text) {
+  if (!condition) {
+    abort('Assertion failed: ' + text);
+  }
+}
+
+var globalScope = this;
+
+// C calling interface. A convenient way to call C functions (in C files, or
+// defined with extern "C").
+//
+// Note: LLVM optimizations can inline and remove functions, after which you will not be
+//       able to call them. Closure can also do so. To avoid that, add your function to
+//       the exports using something like
+//
+//         -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]'
+//
+// @param ident      The name of the C function (note that C++ functions will be name-mangled - use extern "C")
+// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and
+//                   'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit).
+// @param argTypes   An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType,
+//                   except that 'array' is not possible (there is no way for us to know the length of the array)
+// @param args       An array of the arguments to the function, as native JS values (as in returnType)
+//                   Note that string arguments will be stored on the stack (the JS string will become a C string on the stack).
+// @return           The return value, as a native JS value (as in returnType)
+function ccall(ident, returnType, argTypes, args) {
+  return ccallFunc(getCFunc(ident), returnType, argTypes, args);
+}
+Module["ccall"] = ccall;
+
+// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
+function getCFunc(ident) {
+  try {
+    var func = Module['_' + ident]; // closure exported function
+    if (!func) func = eval('_' + ident); // explicit lookup
+  } catch(e) {
+  }
+  assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)');
+  return func;
+}
+
+// Internal function that does a C call using a function, not an identifier
+function ccallFunc(func, returnType, argTypes, args) {
+  var stack = 0;
+  function toC(value, type) {
+    if (type == 'string') {
+      if (value === null || value === undefined || value === 0) return 0; // null string
+      value = intArrayFromString(value);
+      type = 'array';
+    }
+    if (type == 'array') {
+      if (!stack) stack = Runtime.stackSave();
+      var ret = Runtime.stackAlloc(value.length);
+      writeArrayToMemory(value, ret);
+      return ret;
+    }
+    return value;
+  }
+  function fromC(value, type) {
+    if (type == 'string') {
+      return Pointer_stringify(value);
+    }
+    assert(type != 'array');
+    return value;
+  }
+  var i = 0;
+  var cArgs = args ? args.map(function(arg) {
+    return toC(arg, argTypes[i++]);
+  }) : [];
+  var ret = fromC(func.apply(null, cArgs), returnType);
+  if (stack) Runtime.stackRestore(stack);
+  return ret;
+}
+
+// Returns a native JS wrapper for a C function. This is similar to ccall, but
+// returns a function you can call repeatedly in a normal way. For example:
+//
+//   var my_function = cwrap('my_c_function', 'number', ['number', 'number']);
+//   alert(my_function(5, 22));
+//   alert(my_function(99, 12));
+//
+function cwrap(ident, returnType, argTypes) {
+  var func = getCFunc(ident);
+  return function() {
+    return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments));
+  }
+}
+Module["cwrap"] = cwrap;
+
+// Sets a value in memory in a dynamic way at run-time. Uses the
+// type data. This is the same as makeSetValue, except that
+// makeSetValue is done at compile-time and generates the needed
+// code then, whereas this function picks the right code at
+// run-time.
+// Note that setValue and getValue only do *aligned* writes and reads!
+// Note that ccall uses JS types as for defining types, while setValue and
+// getValue need LLVM types ('i8', 'i32') - this is a lower-level operation
+function setValue(ptr, value, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': HEAP8[(ptr)]=value; break;
+      case 'i8': HEAP8[(ptr)]=value; break;
+      case 'i16': HEAP16[((ptr)>>1)]=value; break;
+      case 'i32': HEAP32[((ptr)>>2)]=value; break;
+      case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= (+1) ? (tempDouble > (+0) ? ((Math_min((+(Math_floor((tempDouble)/(+4294967296)))), (+4294967295)))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/(+4294967296))))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
+      case 'float': HEAPF32[((ptr)>>2)]=value; break;
+      case 'double': HEAPF64[((ptr)>>3)]=value; break;
+      default: abort('invalid type for setValue: ' + type);
+    }
+}
+Module['setValue'] = setValue;
+
+// Parallel to setValue.
+function getValue(ptr, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': return HEAP8[(ptr)];
+      case 'i8': return HEAP8[(ptr)];
+      case 'i16': return HEAP16[((ptr)>>1)];
+      case 'i32': return HEAP32[((ptr)>>2)];
+      case 'i64': return HEAP32[((ptr)>>2)];
+      case 'float': return HEAPF32[((ptr)>>2)];
+      case 'double': return HEAPF64[((ptr)>>3)];
+      default: abort('invalid type for setValue: ' + type);
+    }
+  return null;
+}
+Module['getValue'] = getValue;
+
+var ALLOC_NORMAL = 0; // Tries to use _malloc()
+var ALLOC_STACK = 1; // Lives for the duration of the current function call
+var ALLOC_STATIC = 2; // Cannot be freed
+var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
+var ALLOC_NONE = 4; // Do not allocate
+Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
+Module['ALLOC_STACK'] = ALLOC_STACK;
+Module['ALLOC_STATIC'] = ALLOC_STATIC;
+Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
+Module['ALLOC_NONE'] = ALLOC_NONE;
+
+// allocate(): This is for internal use. You can use it yourself as well, but the interface
+//             is a little tricky (see docs right below). The reason is that it is optimized
+//             for multiple syntaxes to save space in generated code. So you should
+//             normally not use allocate(), and instead allocate memory using _malloc(),
+//             initialize it with setValue(), and so forth.
+// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
+//        in *bytes* (note that this is sometimes confusing: the next parameter does not
+//        affect this!)
+// @types: Either an array of types, one for each byte (or 0 if no type at that position),
+//         or a single type which is used for the entire block. This only matters if there
+//         is initial data - if @slab is a number, then this does not matter at all and is
+//         ignored.
+// @allocator: How to allocate memory, see ALLOC_*
+function allocate(slab, types, allocator, ptr) {
+  var zeroinit, size;
+  if (typeof slab === 'number') {
+    zeroinit = true;
+    size = slab;
+  } else {
+    zeroinit = false;
+    size = slab.length;
+  }
+
+  var singleType = typeof types === 'string' ? types : null;
+
+  var ret;
+  if (allocator == ALLOC_NONE) {
+    ret = ptr;
+  } else {
+    ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
+  }
+
+  if (zeroinit) {
+    var ptr = ret, stop;
+    assert((ret & 3) == 0);
+    stop = ret + (size & ~3);
+    for (; ptr < stop; ptr += 4) {
+      HEAP32[((ptr)>>2)]=0;
+    }
+    stop = ret + size;
+    while (ptr < stop) {
+      HEAP8[((ptr++)|0)]=0;
+    }
+    return ret;
+  }
+
+  if (singleType === 'i8') {
+    if (slab.subarray || slab.slice) {
+      HEAPU8.set(slab, ret);
+    } else {
+      HEAPU8.set(new Uint8Array(slab), ret);
+    }
+    return ret;
+  }
+
+  var i = 0, type, typeSize, previousType;
+  while (i < size) {
+    var curr = slab[i];
+
+    if (typeof curr === 'function') {
+      curr = Runtime.getFunctionIndex(curr);
+    }
+
+    type = singleType || types[i];
+    if (type === 0) {
+      i++;
+      continue;
+    }
+
+    if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
+
+    setValue(ret+i, curr, type);
+
+    // no need to look up size unless type changes, so cache it
+    if (previousType !== type) {
+      typeSize = Runtime.getNativeTypeSize(type);
+      previousType = type;
+    }
+    i += typeSize;
+  }
+
+  return ret;
+}
+Module['allocate'] = allocate;
+
+function Pointer_stringify(ptr, /* optional */ length) {
+  // TODO: use TextDecoder
+  // Find the length, and check for UTF while doing so
+  var hasUtf = false;
+  var t;
+  var i = 0;
+  while (1) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    if (t >= 128) hasUtf = true;
+    else if (t == 0 && !length) break;
+    i++;
+    if (length && i == length) break;
+  }
+  if (!length) length = i;
+
+  var ret = '';
+
+  if (!hasUtf) {
+    var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack
+    var curr;
+    while (length > 0) {
+      curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
+      ret = ret ? ret + curr : curr;
+      ptr += MAX_CHUNK;
+      length -= MAX_CHUNK;
+    }
+    return ret;
+  }
+
+  var utf8 = new Runtime.UTF8Processor();
+  for (i = 0; i < length; i++) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    ret += utf8.processCChar(t);
+  }
+  return ret;
+}
+Module['Pointer_stringify'] = Pointer_stringify;
+
+// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF16ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
+    if (codeUnit == 0)
+      return str;
+    ++i;
+    // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
+    str += String.fromCharCode(codeUnit);
+  }
+}
+Module['UTF16ToString'] = UTF16ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF16LE form. The copy will require at most (str.length*2+1)*2 bytes of space in the HEAP.
+function stringToUTF16(str, outPtr) {
+  for(var i = 0; i < str.length; ++i) {
+    // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
+    var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
+    HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP16[(((outPtr)+(str.length*2))>>1)]=0;
+}
+Module['stringToUTF16'] = stringToUTF16;
+
+// Given a pointer 'ptr' to a null-terminated UTF32LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF32ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
+    if (utf32 == 0)
+      return str;
+    ++i;
+    // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
+    if (utf32 >= 0x10000) {
+      var ch = utf32 - 0x10000;
+      str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
+    } else {
+      str += String.fromCharCode(utf32);
+    }
+  }
+}
+Module['UTF32ToString'] = UTF32ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF32LE form. The copy will require at most (str.length+1)*4 bytes of space in the HEAP,
+// but can use less, since str.length does not return the number of characters in the string, but the number of UTF-16 code units in the string.
+function stringToUTF32(str, outPtr) {
+  var iChar = 0;
+  for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) {
+    // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
+    var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate
+    if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
+      var trailSurrogate = str.charCodeAt(++iCodeUnit);
+      codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
+    }
+    HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit;
+    ++iChar;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP32[(((outPtr)+(iChar*4))>>2)]=0;
+}
+Module['stringToUTF32'] = stringToUTF32;
+
+function demangle(func) {
+  var i = 3;
+  // params, etc.
+  var basicTypes = {
+    'v': 'void',
+    'b': 'bool',
+    'c': 'char',
+    's': 'short',
+    'i': 'int',
+    'l': 'long',
+    'f': 'float',
+    'd': 'double',
+    'w': 'wchar_t',
+    'a': 'signed char',
+    'h': 'unsigned char',
+    't': 'unsigned short',
+    'j': 'unsigned int',
+    'm': 'unsigned long',
+    'x': 'long long',
+    'y': 'unsigned long long',
+    'z': '...'
+  };
+  var subs = [];
+  var first = true;
+  function dump(x) {
+    //return;
+    if (x) Module.print(x);
+    Module.print(func);
+    var pre = '';
+    for (var a = 0; a < i; a++) pre += ' ';
+    Module.print (pre + '^');
+  }
+  function parseNested() {
+    i++;
+    if (func[i] === 'K') i++; // ignore const
+    var parts = [];
+    while (func[i] !== 'E') {
+      if (func[i] === 'S') { // substitution
+        i++;
+        var next = func.indexOf('_', i);
+        var num = func.substring(i, next) || 0;
+        parts.push(subs[num] || '?');
+        i = next+1;
+        continue;
+      }
+      if (func[i] === 'C') { // constructor
+        parts.push(parts[parts.length-1]);
+        i += 2;
+        continue;
+      }
+      var size = parseInt(func.substr(i));
+      var pre = size.toString().length;
+      if (!size || !pre) { i--; break; } // counter i++ below us
+      var curr = func.substr(i + pre, size);
+      parts.push(curr);
+      subs.push(curr);
+      i += pre + size;
+    }
+    i++; // skip E
+    return parts;
+  }
+  function parse(rawList, limit, allowVoid) { // main parser
+    limit = limit || Infinity;
+    var ret = '', list = [];
+    function flushList() {
+      return '(' + list.join(', ') + ')';
+    }
+    var name;
+    if (func[i] === 'N') {
+      // namespaced N-E
+      name = parseNested().join('::');
+      limit--;
+      if (limit === 0) return rawList ? [name] : name;
+    } else {
+      // not namespaced
+      if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L'
+      var size = parseInt(func.substr(i));
+      if (size) {
+        var pre = size.toString().length;
+        name = func.substr(i + pre, size);
+        i += pre + size;
+      }
+    }
+    first = false;
+    if (func[i] === 'I') {
+      i++;
+      var iList = parse(true);
+      var iRet = parse(true, 1, true);
+      ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>';
+    } else {
+      ret = name;
+    }
+    paramLoop: while (i < func.length && limit-- > 0) {
+      //dump('paramLoop');
+      var c = func[i++];
+      if (c in basicTypes) {
+        list.push(basicTypes[c]);
+      } else {
+        switch (c) {
+          case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer
+          case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference
+          case 'L': { // literal
+            i++; // skip basic type
+            var end = func.indexOf('E', i);
+            var size = end - i;
+            list.push(func.substr(i, size));
+            i += size + 2; // size + 'EE'
+            break;
+          }
+          case 'A': { // array
+            var size = parseInt(func.substr(i));
+            i += size.toString().length;
+            if (func[i] !== '_') throw '?';
+            i++; // skip _
+            list.push(parse(true, 1, true)[0] + ' [' + size + ']');
+            break;
+          }
+          case 'E': break paramLoop;
+          default: ret += '?' + c; break paramLoop;
+        }
+      }
+    }
+    if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void)
+    if (rawList) {
+      if (ret) {
+        list.push(ret + '?');
+      }
+      return list;
+    } else {
+      return ret + flushList();
+    }
+  }
+  try {
+    // Special-case the entry point, since its name differs from other name mangling.
+    if (func == 'Object._main' || func == '_main') {
+      return 'main()';
+    }
+    if (typeof func === 'number') func = Pointer_stringify(func);
+    if (func[0] !== '_') return func;
+    if (func[1] !== '_') return func; // C function
+    if (func[2] !== 'Z') return func;
+    switch (func[3]) {
+      case 'n': return 'operator new()';
+      case 'd': return 'operator delete()';
+    }
+    return parse();
+  } catch(e) {
+    return func;
+  }
+}
+
+function demangleAll(text) {
+  return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') });
+}
+
+function stackTrace() {
+  var stack = new Error().stack;
+  return stack ? demangleAll(stack) : '(no stack trace available)'; // Stack trace is not available at least on IE10 and Safari 6.
+}
+
+// Memory management
+
+var PAGE_SIZE = 4096;
+function alignMemoryPage(x) {
+  return (x+4095)&-4096;
+}
+
+var HEAP;
+var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
+
+var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area
+var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area
+var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk
+
+function enlargeMemory() {
+  abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
+}
+
+var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880;
+var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 134217728;
+var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152;
+
+var totalMemory = 4096;
+while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) {
+  if (totalMemory < 16*1024*1024) {
+    totalMemory *= 2;
+  } else {
+    totalMemory += 16*1024*1024
+  }
+}
+if (totalMemory !== TOTAL_MEMORY) {
+  Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be more reasonable');
+  TOTAL_MEMORY = totalMemory;
+}
+
+// Initialize the runtime's memory
+// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
+assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
+       'JS engine does not provide full typed array support');
+
+var buffer = new ArrayBuffer(TOTAL_MEMORY);
+HEAP8 = new Int8Array(buffer);
+HEAP16 = new Int16Array(buffer);
+HEAP32 = new Int32Array(buffer);
+HEAPU8 = new Uint8Array(buffer);
+HEAPU16 = new Uint16Array(buffer);
+HEAPU32 = new Uint32Array(buffer);
+HEAPF32 = new Float32Array(buffer);
+HEAPF64 = new Float64Array(buffer);
+
+// Endianness check (note: assumes compiler arch was little-endian)
+HEAP32[0] = 255;
+assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
+
+Module['HEAP'] = HEAP;
+Module['HEAP8'] = HEAP8;
+Module['HEAP16'] = HEAP16;
+Module['HEAP32'] = HEAP32;
+Module['HEAPU8'] = HEAPU8;
+Module['HEAPU16'] = HEAPU16;
+Module['HEAPU32'] = HEAPU32;
+Module['HEAPF32'] = HEAPF32;
+Module['HEAPF64'] = HEAPF64;
+
+function callRuntimeCallbacks(callbacks) {
+  while(callbacks.length > 0) {
+    var callback = callbacks.shift();
+    if (typeof callback == 'function') {
+      callback();
+      continue;
+    }
+    var func = callback.func;
+    if (typeof func === 'number') {
+      if (callback.arg === undefined) {
+        Runtime.dynCall('v', func);
+      } else {
+        Runtime.dynCall('vi', func, [callback.arg]);
+      }
+    } else {
+      func(callback.arg === undefined ? null : callback.arg);
+    }
+  }
+}
+
+var __ATPRERUN__  = []; // functions called before the runtime is initialized
+var __ATINIT__    = []; // functions called during startup
+var __ATMAIN__    = []; // functions called when main() is to be run
+var __ATEXIT__    = []; // functions called during shutdown
+var __ATPOSTRUN__ = []; // functions called after the runtime has exited
+
+var runtimeInitialized = false;
+
+function preRun() {
+  // compatibility - merge in anything from Module['preRun'] at this time
+  if (Module['preRun']) {
+    if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
+    while (Module['preRun'].length) {
+      addOnPreRun(Module['preRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPRERUN__);
+}
+
+function ensureInitRuntime() {
+  if (runtimeInitialized) return;
+  runtimeInitialized = true;
+  callRuntimeCallbacks(__ATINIT__);
+}
+
+function preMain() {
+  callRuntimeCallbacks(__ATMAIN__);
+}
+
+function exitRuntime() {
+  callRuntimeCallbacks(__ATEXIT__);
+}
+
+function postRun() {
+  // compatibility - merge in anything from Module['postRun'] at this time
+  if (Module['postRun']) {
+    if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
+    while (Module['postRun'].length) {
+      addOnPostRun(Module['postRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPOSTRUN__);
+}
+
+function addOnPreRun(cb) {
+  __ATPRERUN__.unshift(cb);
+}
+Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun;
+
+function addOnInit(cb) {
+  __ATINIT__.unshift(cb);
+}
+Module['addOnInit'] = Module.addOnInit = addOnInit;
+
+function addOnPreMain(cb) {
+  __ATMAIN__.unshift(cb);
+}
+Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain;
+
+function addOnExit(cb) {
+  __ATEXIT__.unshift(cb);
+}
+Module['addOnExit'] = Module.addOnExit = addOnExit;
+
+function addOnPostRun(cb) {
+  __ATPOSTRUN__.unshift(cb);
+}
+Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun;
+
+// Tools
+
+// This processes a JS string into a C-line array of numbers, 0-terminated.
+// For LLVM-originating strings, see parser.js:parseLLVMString function
+function intArrayFromString(stringy, dontAddNull, length /* optional */) {
+  var ret = (new Runtime.UTF8Processor()).processJSString(stringy);
+  if (length) {
+    ret.length = length;
+  }
+  if (!dontAddNull) {
+    ret.push(0);
+  }
+  return ret;
+}
+Module['intArrayFromString'] = intArrayFromString;
+
+function intArrayToString(array) {
+  var ret = [];
+  for (var i = 0; i < array.length; i++) {
+    var chr = array[i];
+    if (chr > 0xFF) {
+      chr &= 0xFF;
+    }
+    ret.push(String.fromCharCode(chr));
+  }
+  return ret.join('');
+}
+Module['intArrayToString'] = intArrayToString;
+
+// Write a Javascript array to somewhere in the heap
+function writeStringToMemory(string, buffer, dontAddNull) {
+  var array = intArrayFromString(string, dontAddNull);
+  var i = 0;
+  while (i < array.length) {
+    var chr = array[i];
+    HEAP8[(((buffer)+(i))|0)]=chr;
+    i = i + 1;
+  }
+}
+Module['writeStringToMemory'] = writeStringToMemory;
+
+function writeArrayToMemory(array, buffer) {
+  for (var i = 0; i < array.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=array[i];
+  }
+}
+Module['writeArrayToMemory'] = writeArrayToMemory;
+
+function writeAsciiToMemory(str, buffer, dontAddNull) {
+  for (var i = 0; i < str.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=str.charCodeAt(i);
+  }
+  if (!dontAddNull) HEAP8[(((buffer)+(str.length))|0)]=0;
+}
+Module['writeAsciiToMemory'] = writeAsciiToMemory;
+
+function unSign(value, bits, ignore) {
+  if (value >= 0) {
+    return value;
+  }
+  return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
+                    : Math.pow(2, bits)         + value;
+}
+function reSign(value, bits, ignore) {
+  if (value <= 0) {
+    return value;
+  }
+  var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
+                        : Math.pow(2, bits-1);
+  if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
+                                                       // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
+                                                       // TODO: In i64 mode 1, resign the two parts separately and safely
+    value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
+  }
+  return value;
+}
+
+// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
+if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) {
+  var ah  = a >>> 16;
+  var al = a & 0xffff;
+  var bh  = b >>> 16;
+  var bl = b & 0xffff;
+  return (al*bl + ((ah*bl + al*bh) << 16))|0;
+};
+Math.imul = Math['imul'];
+
+
+var Math_abs = Math.abs;
+var Math_cos = Math.cos;
+var Math_sin = Math.sin;
+var Math_tan = Math.tan;
+var Math_acos = Math.acos;
+var Math_asin = Math.asin;
+var Math_atan = Math.atan;
+var Math_atan2 = Math.atan2;
+var Math_exp = Math.exp;
+var Math_log = Math.log;
+var Math_sqrt = Math.sqrt;
+var Math_ceil = Math.ceil;
+var Math_floor = Math.floor;
+var Math_pow = Math.pow;
+var Math_imul = Math.imul;
+var Math_fround = Math.fround;
+var Math_min = Math.min;
+
+// A counter of dependencies for calling run(). If we need to
+// do asynchronous work before running, increment this and
+// decrement it. Incrementing must happen in a place like
+// PRE_RUN_ADDITIONS (used by emcc to add file preloading).
+// Note that you can add dependencies in preRun, even though
+// it happens right before run - run will be postponed until
+// the dependencies are met.
+var runDependencies = 0;
+var runDependencyWatcher = null;
+var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
+
+function addRunDependency(id) {
+  runDependencies++;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+}
+Module['addRunDependency'] = addRunDependency;
+function removeRunDependency(id) {
+  runDependencies--;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+  if (runDependencies == 0) {
+    if (runDependencyWatcher !== null) {
+      clearInterval(runDependencyWatcher);
+      runDependencyWatcher = null;
+    }
+    if (dependenciesFulfilled) {
+      var callback = dependenciesFulfilled;
+      dependenciesFulfilled = null;
+      callback(); // can add another dependenciesFulfilled
+    }
+  }
+}
+Module['removeRunDependency'] = removeRunDependency;
+
+Module["preloadedImages"] = {}; // maps url to image data
+Module["preloadedAudios"] = {}; // maps url to audio data
+
+
+var memoryInitializer = null;
+
+// === Body ===
+
+
+
+
+
+STATIC_BASE = 8;
+
+STATICTOP = STATIC_BASE + Runtime.alignMemory(35);
+/* global initializers */ __ATINIT__.push();
+
+
+/* memory initializer */ allocate([101,114,114,111,114,58,32,37,100,92,110,0,0,0,0,0,102,105,110,97,108,58,32,37,100,58,37,100,46,10,0,0], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE);
+
+
+
+
+var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);
+
+assert(tempDoublePtr % 8 == 0);
+
+function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+}
+
+function copyTempDouble(ptr) {
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+  HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];
+
+  HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];
+
+  HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];
+
+  HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];
+
+}
+
+
+  function _malloc(bytes) {
+      /* Over-allocate to make sure it is byte-aligned by 8.
+       * This will leak memory, but this is only the dummy
+       * implementation (replaced by dlmalloc normally) so
+       * not an issue.
+       */
+      var ptr = Runtime.dynamicAlloc(bytes + 8);
+      return (ptr+8) & 0xFFFFFFF8;
+    }
+  Module["_malloc"] = _malloc;
+
+
+
+
+  var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};
+
+  var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can   access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};
+
+
+  var ___errno_state=0;function ___setErrNo(value) {
+      // For convenient setting and returning of errno.
+      HEAP32[((___errno_state)>>2)]=value;
+      return value;
+    }
+
+  var TTY={ttys:[],init:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // currently, FS.init does not distinguish if process.stdin is a file or TTY
+        //   // device, it always assumes it's a TTY device. because of this, we're forcing
+        //   // process.stdin to UTF8 encoding to at least make stdin reading compatible
+        //   // with text files until FS.init can be refactored.
+        //   process['stdin']['setEncoding']('utf8');
+        // }
+      },shutdown:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
+        //   // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
+        //   // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
+        //   // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
+        //   // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
+        //   process['stdin']['pause']();
+        // }
+      },register:function (dev, ops) {
+        TTY.ttys[dev] = { input: [], output: [], ops: ops };
+        FS.registerDevice(dev, TTY.stream_ops);
+      },stream_ops:{open:function (stream) {
+          var tty = TTY.ttys[stream.node.rdev];
+          if (!tty) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          stream.tty = tty;
+          stream.seekable = false;
+        },close:function (stream) {
+          // flush any pending line data
+          if (stream.tty.output.length) {
+            stream.tty.ops.put_char(stream.tty, 10);
+          }
+        },read:function (stream, buffer, offset, length, pos /* ignored */) {
+          if (!stream.tty || !stream.tty.ops.get_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          var bytesRead = 0;
+          for (var i = 0; i < length; i++) {
+            var result;
+            try {
+              result = stream.tty.ops.get_char(stream.tty);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            if (result === undefined && bytesRead === 0) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+            if (result === null || result === undefined) break;
+            bytesRead++;
+            buffer[offset+i] = result;
+          }
+          if (bytesRead) {
+            stream.node.timestamp = Date.now();
+          }
+          return bytesRead;
+        },write:function (stream, buffer, offset, length, pos) {
+          if (!stream.tty || !stream.tty.ops.put_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          for (var i = 0; i < length; i++) {
+            try {
+              stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+          }
+          if (length) {
+            stream.node.timestamp = Date.now();
+          }
+          return i;
+        }},default_tty_ops:{get_char:function (tty) {
+          if (!tty.input.length) {
+            var result = null;
+            if (ENVIRONMENT_IS_NODE) {
+              result = process['stdin']['read']();
+              if (!result) {
+                if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) {
+                  return null;  // EOF
+                }
+                return undefined;  // no data available
+              }
+            } else if (typeof window != 'undefined' &&
+              typeof window.prompt == 'function') {
+              // Browser.
+              result = window.prompt('Input: ');  // returns null on cancel
+              if (result !== null) {
+                result += '\n';
+              }
+            } else if (typeof readline == 'function') {
+              // Command line.
+              result = readline();
+              if (result !== null) {
+                result += '\n';
+              }
+            }
+            if (!result) {
+              return null;
+            }
+            tty.input = intArrayFromString(result, true);
+          }
+          return tty.input.shift();
+        },put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['print'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }},default_tty1_ops:{put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['printErr'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }}};
+
+  var MEMFS={ops_table:null,CONTENT_OWNING:1,CONTENT_FLEXIBLE:2,CONTENT_FIXED:3,mount:function (mount) {
+        return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
+          // no supported
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (!MEMFS.ops_table) {
+          MEMFS.ops_table = {
+            dir: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                lookup: MEMFS.node_ops.lookup,
+                mknod: MEMFS.node_ops.mknod,
+                rename: MEMFS.node_ops.rename,
+                unlink: MEMFS.node_ops.unlink,
+                rmdir: MEMFS.node_ops.rmdir,
+                readdir: MEMFS.node_ops.readdir,
+                symlink: MEMFS.node_ops.symlink
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek
+              }
+            },
+            file: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek,
+                read: MEMFS.stream_ops.read,
+                write: MEMFS.stream_ops.write,
+                allocate: MEMFS.stream_ops.allocate,
+                mmap: MEMFS.stream_ops.mmap
+              }
+            },
+            link: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                readlink: MEMFS.node_ops.readlink
+              },
+              stream: {}
+            },
+            chrdev: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: FS.chrdev_stream_ops
+            },
+          };
+        }
+        var node = FS.createNode(parent, name, mode, dev);
+        if (FS.isDir(node.mode)) {
+          node.node_ops = MEMFS.ops_table.dir.node;
+          node.stream_ops = MEMFS.ops_table.dir.stream;
+          node.contents = {};
+        } else if (FS.isFile(node.mode)) {
+          node.node_ops = MEMFS.ops_table.file.node;
+          node.stream_ops = MEMFS.ops_table.file.stream;
+          node.contents = [];
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        } else if (FS.isLink(node.mode)) {
+          node.node_ops = MEMFS.ops_table.link.node;
+          node.stream_ops = MEMFS.ops_table.link.stream;
+        } else if (FS.isChrdev(node.mode)) {
+          node.node_ops = MEMFS.ops_table.chrdev.node;
+          node.stream_ops = MEMFS.ops_table.chrdev.stream;
+        }
+        node.timestamp = Date.now();
+        // add the new node to the parent
+        if (parent) {
+          parent.contents[name] = node;
+        }
+        return node;
+      },ensureFlexible:function (node) {
+        if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
+          var contents = node.contents;
+          node.contents = Array.prototype.slice.call(contents);
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        }
+      },node_ops:{getattr:function (node) {
+          var attr = {};
+          // device numbers reuse inode numbers.
+          attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
+          attr.ino = node.id;
+          attr.mode = node.mode;
+          attr.nlink = 1;
+          attr.uid = 0;
+          attr.gid = 0;
+          attr.rdev = node.rdev;
+          if (FS.isDir(node.mode)) {
+            attr.size = 4096;
+          } else if (FS.isFile(node.mode)) {
+            attr.size = node.contents.length;
+          } else if (FS.isLink(node.mode)) {
+            attr.size = node.link.length;
+          } else {
+            attr.size = 0;
+          }
+          attr.atime = new Date(node.timestamp);
+          attr.mtime = new Date(node.timestamp);
+          attr.ctime = new Date(node.timestamp);
+          // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
+          //       but this is not required by the standard.
+          attr.blksize = 4096;
+          attr.blocks = Math.ceil(attr.size / attr.blksize);
+          return attr;
+        },setattr:function (node, attr) {
+          if (attr.mode !== undefined) {
+            node.mode = attr.mode;
+          }
+          if (attr.timestamp !== undefined) {
+            node.timestamp = attr.timestamp;
+          }
+          if (attr.size !== undefined) {
+            MEMFS.ensureFlexible(node);
+            var contents = node.contents;
+            if (attr.size < contents.length) contents.length = attr.size;
+            else while (attr.size > contents.length) contents.push(0);
+          }
+        },lookup:function (parent, name) {
+          throw FS.genericErrors[ERRNO_CODES.ENOENT];
+        },mknod:function (parent, name, mode, dev) {
+          return MEMFS.createNode(parent, name, mode, dev);
+        },rename:function (old_node, new_dir, new_name) {
+          // if we're overwriting a directory at new_name, make sure it's empty.
+          if (FS.isDir(old_node.mode)) {
+            var new_node;
+            try {
+              new_node = FS.lookupNode(new_dir, new_name);
+            } catch (e) {
+            }
+            if (new_node) {
+              for (var i in new_node.contents) {
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+              }
+            }
+          }
+          // do the internal rewiring
+          delete old_node.parent.contents[old_node.name];
+          old_node.name = new_name;
+          new_dir.contents[new_name] = old_node;
+          old_node.parent = new_dir;
+        },unlink:function (parent, name) {
+          delete parent.contents[name];
+        },rmdir:function (parent, name) {
+          var node = FS.lookupNode(parent, name);
+          for (var i in node.contents) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+          }
+          delete parent.contents[name];
+        },readdir:function (node) {
+          var entries = ['.', '..']
+          for (var key in node.contents) {
+            if (!node.contents.hasOwnProperty(key)) {
+              continue;
+            }
+            entries.push(key);
+          }
+          return entries;
+        },symlink:function (parent, newname, oldpath) {
+          var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
+          node.link = oldpath;
+          return node;
+        },readlink:function (node) {
+          if (!FS.isLink(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          return node.link;
+        }},stream_ops:{read:function (stream, buffer, offset, length, position) {
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (size > 8 && contents.subarray) { // non-trivial, and typed array
+            buffer.set(contents.subarray(position, position + size), offset);
+          } else
+          {
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          }
+          return size;
+        },write:function (stream, buffer, offset, length, position, canOwn) {
+          var node = stream.node;
+          node.timestamp = Date.now();
+          var contents = node.contents;
+          if (length && contents.length === 0 && position === 0 && buffer.subarray) {
+            // just replace it with the new data
+            if (canOwn && offset === 0) {
+              node.contents = buffer; // this could be a subarray of Emscripten HEAP, or allocated from some other source.
+              node.contentMode = (buffer.buffer === HEAP8.buffer) ? MEMFS.CONTENT_OWNING : MEMFS.CONTENT_FIXED;
+            } else {
+              node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
+              node.contentMode = MEMFS.CONTENT_FIXED;
+            }
+            return length;
+          }
+          MEMFS.ensureFlexible(node);
+          var contents = node.contents;
+          while (contents.length < position) contents.push(0);
+          for (var i = 0; i < length; i++) {
+            contents[position + i] = buffer[offset + i];
+          }
+          return length;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              position += stream.node.contents.length;
+            }
+          }
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          stream.ungotten = [];
+          stream.position = position;
+          return position;
+        },allocate:function (stream, offset, length) {
+          MEMFS.ensureFlexible(stream.node);
+          var contents = stream.node.contents;
+          var limit = offset + length;
+          while (limit > contents.length) contents.push(0);
+        },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+          if (!FS.isFile(stream.node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          var ptr;
+          var allocated;
+          var contents = stream.node.contents;
+          // Only make a new copy when MAP_PRIVATE is specified.
+          if ( !(flags & 2) &&
+                (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
+            // We can't emulate MAP_SHARED when the file is not backed by the buffer
+            // we're mapping to (e.g. the HEAP buffer).
+            allocated = false;
+            ptr = contents.byteOffset;
+          } else {
+            // Try to avoid unnecessary slices.
+            if (position > 0 || position + length < contents.length) {
+              if (contents.subarray) {
+                contents = contents.subarray(position, position + length);
+              } else {
+                contents = Array.prototype.slice.call(contents, position, position + length);
+              }
+            }
+            allocated = true;
+            ptr = _malloc(length);
+            if (!ptr) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOMEM);
+            }
+            buffer.set(contents, ptr);
+          }
+          return { ptr: ptr, allocated: allocated };
+        }}};
+
+  var IDBFS={dbs:{},indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) {
+        // reuse all of the core MEMFS functionality
+        return MEMFS.mount.apply(null, arguments);
+      },syncfs:function (mount, populate, callback) {
+        IDBFS.getLocalSet(mount, function(err, local) {
+          if (err) return callback(err);
+
+          IDBFS.getRemoteSet(mount, function(err, remote) {
+            if (err) return callback(err);
+
+            var src = populate ? remote : local;
+            var dst = populate ? local : remote;
+
+            IDBFS.reconcile(src, dst, callback);
+          });
+        });
+      },getDB:function (name, callback) {
+        // check the cache first
+        var db = IDBFS.dbs[name];
+        if (db) {
+          return callback(null, db);
+        }
+
+        var req;
+        try {
+          req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
+        } catch (e) {
+          return callback(e);
+        }
+        req.onupgradeneeded = function(e) {
+          var db = e.target.result;
+          var transaction = e.target.transaction;
+
+          var fileStore;
+
+          if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
+            fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          } else {
+            fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
+          }
+
+          fileStore.createIndex('timestamp', 'timestamp', { unique: false });
+        };
+        req.onsuccess = function() {
+          db = req.result;
+
+          // add to the cache
+          IDBFS.dbs[name] = db;
+          callback(null, db);
+        };
+        req.onerror = function() {
+          callback(this.error);
+        };
+      },getLocalSet:function (mount, callback) {
+        var entries = {};
+
+        function isRealDir(p) {
+          return p !== '.' && p !== '..';
+        };
+        function toAbsolute(root) {
+          return function(p) {
+            return PATH.join2(root, p);
+          }
+        };
+
+        var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
+
+        while (check.length) {
+          var path = check.pop();
+          var stat;
+
+          try {
+            stat = FS.stat(path);
+          } catch (e) {
+            return callback(e);
+          }
+
+          if (FS.isDir(stat.mode)) {
+            check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
+          }
+
+          entries[path] = { timestamp: stat.mtime };
+        }
+
+        return callback(null, { type: 'local', entries: entries });
+      },getRemoteSet:function (mount, callback) {
+        var entries = {};
+
+        IDBFS.getDB(mount.mountpoint, function(err, db) {
+          if (err) return callback(err);
+
+          var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly');
+          transaction.onerror = function() { callback(this.error); };
+
+          var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          var index = store.index('timestamp');
+
+          index.openKeyCursor().onsuccess = function(event) {
+            var cursor = event.target.result;
+
+            if (!cursor) {
+              return callback(null, { type: 'remote', db: db, entries: entries });
+            }
+
+            entries[cursor.primaryKey] = { timestamp: cursor.key };
+
+            cursor.continue();
+          };
+        });
+      },loadLocalEntry:function (path, callback) {
+        var stat, node;
+
+        try {
+          var lookup = FS.lookupPath(path);
+          node = lookup.node;
+          stat = FS.stat(path);
+        } catch (e) {
+          return callback(e);
+        }
+
+        if (FS.isDir(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode });
+        } else if (FS.isFile(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents });
+        } else {
+          return callback(new Error('node type not supported'));
+        }
+      },storeLocalEntry:function (path, entry, callback) {
+        try {
+          if (FS.isDir(entry.mode)) {
+            FS.mkdir(path, entry.mode);
+          } else if (FS.isFile(entry.mode)) {
+            FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true });
+          } else {
+            return callback(new Error('node type not supported'));
+          }
+
+          FS.utime(path, entry.timestamp, entry.timestamp);
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },removeLocalEntry:function (path, callback) {
+        try {
+          var lookup = FS.lookupPath(path);
+          var stat = FS.stat(path);
+
+          if (FS.isDir(stat.mode)) {
+            FS.rmdir(path);
+          } else if (FS.isFile(stat.mode)) {
+            FS.unlink(path);
+          }
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },loadRemoteEntry:function (store, path, callback) {
+        var req = store.get(path);
+        req.onsuccess = function(event) { callback(null, event.target.result); };
+        req.onerror = function() { callback(this.error); };
+      },storeRemoteEntry:function (store, path, entry, callback) {
+        var req = store.put(entry, path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },removeRemoteEntry:function (store, path, callback) {
+        var req = store.delete(path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },reconcile:function (src, dst, callback) {
+        var total = 0;
+
+        var create = [];
+        Object.keys(src.entries).forEach(function (key) {
+          var e = src.entries[key];
+          var e2 = dst.entries[key];
+          if (!e2 || e.timestamp > e2.timestamp) {
+            create.push(key);
+            total++;
+          }
+        });
+
+        var remove = [];
+        Object.keys(dst.entries).forEach(function (key) {
+          var e = dst.entries[key];
+          var e2 = src.entries[key];
+          if (!e2) {
+            remove.push(key);
+            total++;
+          }
+        });
+
+        if (!total) {
+          return callback(null);
+        }
+
+        var errored = false;
+        var completed = 0;
+        var db = src.type === 'remote' ? src.db : dst.db;
+        var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
+        var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= total) {
+            return callback(null);
+          }
+        };
+
+        transaction.onerror = function() { done(this.error); };
+
+        // sort paths in ascending order so directory entries are created
+        // before the files inside them
+        create.sort().forEach(function (path) {
+          if (dst.type === 'local') {
+            IDBFS.loadRemoteEntry(store, path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeLocalEntry(path, entry, done);
+            });
+          } else {
+            IDBFS.loadLocalEntry(path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeRemoteEntry(store, path, entry, done);
+            });
+          }
+        });
+
+        // sort paths in descending order so files are deleted before their
+        // parent directories
+        remove.sort().reverse().forEach(function(path) {
+          if (dst.type === 'local') {
+            IDBFS.removeLocalEntry(path, done);
+          } else {
+            IDBFS.removeRemoteEntry(store, path, done);
+          }
+        });
+      }};
+
+  var NODEFS={isWindows:false,staticInit:function () {
+        NODEFS.isWindows = !!process.platform.match(/^win/);
+      },mount:function (mount) {
+        assert(ENVIRONMENT_IS_NODE);
+        return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node = FS.createNode(parent, name, mode);
+        node.node_ops = NODEFS.node_ops;
+        node.stream_ops = NODEFS.stream_ops;
+        return node;
+      },getMode:function (path) {
+        var stat;
+        try {
+          stat = fs.lstatSync(path);
+          if (NODEFS.isWindows) {
+            // On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so
+            // propagate write bits to execute bits.
+            stat.mode = stat.mode | ((stat.mode & 146) >> 1);
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        return stat.mode;
+      },realPath:function (node) {
+        var parts = [];
+        while (node.parent !== node) {
+          parts.push(node.name);
+          node = node.parent;
+        }
+        parts.push(node.mount.opts.root);
+        parts.reverse();
+        return PATH.join.apply(null, parts);
+      },flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) {
+        if (flags in NODEFS.flagsToPermissionStringMap) {
+          return NODEFS.flagsToPermissionStringMap[flags];
+        } else {
+          return flags;
+        }
+      },node_ops:{getattr:function (node) {
+          var path = NODEFS.realPath(node);
+          var stat;
+          try {
+            stat = fs.lstatSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096.
+          // See http://support.microsoft.com/kb/140365
+          if (NODEFS.isWindows && !stat.blksize) {
+            stat.blksize = 4096;
+          }
+          if (NODEFS.isWindows && !stat.blocks) {
+            stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0;
+          }
+          return {
+            dev: stat.dev,
+            ino: stat.ino,
+            mode: stat.mode,
+            nlink: stat.nlink,
+            uid: stat.uid,
+            gid: stat.gid,
+            rdev: stat.rdev,
+            size: stat.size,
+            atime: stat.atime,
+            mtime: stat.mtime,
+            ctime: stat.ctime,
+            blksize: stat.blksize,
+            blocks: stat.blocks
+          };
+        },setattr:function (node, attr) {
+          var path = NODEFS.realPath(node);
+          try {
+            if (attr.mode !== undefined) {
+              fs.chmodSync(path, attr.mode);
+              // update the common node structure mode as well
+              node.mode = attr.mode;
+            }
+            if (attr.timestamp !== undefined) {
+              var date = new Date(attr.timestamp);
+              fs.utimesSync(path, date, date);
+            }
+            if (attr.size !== undefined) {
+              fs.truncateSync(path, attr.size);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },lookup:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          var mode = NODEFS.getMode(path);
+          return NODEFS.createNode(parent, name, mode);
+        },mknod:function (parent, name, mode, dev) {
+          var node = NODEFS.createNode(parent, name, mode, dev);
+          // create the backing node for this in the fs root as well
+          var path = NODEFS.realPath(node);
+          try {
+            if (FS.isDir(node.mode)) {
+              fs.mkdirSync(path, node.mode);
+            } else {
+              fs.writeFileSync(path, '', { mode: node.mode });
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return node;
+        },rename:function (oldNode, newDir, newName) {
+          var oldPath = NODEFS.realPath(oldNode);
+          var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
+          try {
+            fs.renameSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },unlink:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.unlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },rmdir:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.rmdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readdir:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },symlink:function (parent, newName, oldPath) {
+          var newPath = PATH.join2(NODEFS.realPath(parent), newName);
+          try {
+            fs.symlinkSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readlink:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        }},stream_ops:{open:function (stream) {
+          var path = NODEFS.realPath(stream.node);
+          try {
+            if (FS.isFile(stream.node.mode)) {
+              stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags));
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },close:function (stream) {
+          try {
+            if (FS.isFile(stream.node.mode) && stream.nfd) {
+              fs.closeSync(stream.nfd);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },read:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(length);
+          var res;
+          try {
+            res = fs.readSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          if (res > 0) {
+            for (var i = 0; i < res; i++) {
+              buffer[offset + i] = nbuffer[i];
+            }
+          }
+          return res;
+        },write:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(buffer.subarray(offset, offset + length));
+          var res;
+          try {
+            res = fs.writeSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return res;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              try {
+                var stat = fs.fstatSync(stream.nfd);
+                position += stat.size;
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+              }
+            }
+          }
+
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+
+          stream.position = position;
+          return position;
+        }}};
+
+  var _stdin=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stdout=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stderr=allocate(1, "i32*", ALLOC_STATIC);
+
+  function _fflush(stream) {
+      // int fflush(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html
+      // we don't currently perform any user-space buffering of data
+    }var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},handleFSError:function (e) {
+        if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
+        return ___setErrNo(e.errno);
+      },lookupPath:function (path, opts) {
+        path = PATH.resolve(FS.cwd(), path);
+        opts = opts || {};
+
+        var defaults = {
+          follow_mount: true,
+          recurse_count: 0
+        };
+        for (var key in defaults) {
+          if (opts[key] === undefined) {
+            opts[key] = defaults[key];
+          }
+        }
+
+        if (opts.recurse_count > 8) {  // max recursive lookup of 8
+          throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+        }
+
+        // split the path
+        var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), false);
+
+        // start at the root
+        var current = FS.root;
+        var current_path = '/';
+
+        for (var i = 0; i < parts.length; i++) {
+          var islast = (i === parts.length-1);
+          if (islast && opts.parent) {
+            // stop resolving
+            break;
+          }
+
+          current = FS.lookupNode(current, parts[i]);
+          current_path = PATH.join2(current_path, parts[i]);
+
+          // jump to the mount's root node if this is a mountpoint
+          if (FS.isMountpoint(current)) {
+            if (!islast || (islast && opts.follow_mount)) {
+              current = current.mounted.root;
+            }
+          }
+
+          // by default, lookupPath will not follow a symlink if it is the final path component.
+          // setting opts.follow = true will override this behavior.
+          if (!islast || opts.follow) {
+            var count = 0;
+            while (FS.isLink(current.mode)) {
+              var link = FS.readlink(current_path);
+              current_path = PATH.resolve(PATH.dirname(current_path), link);
+
+              var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
+              current = lookup.node;
+
+              if (count++ > 40) {  // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
+                throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+              }
+            }
+          }
+        }
+
+        return { path: current_path, node: current };
+      },getPath:function (node) {
+        var path;
+        while (true) {
+          if (FS.isRoot(node)) {
+            var mount = node.mount.mountpoint;
+            if (!path) return mount;
+            return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
+          }
+          path = path ? node.name + '/' + path : node.name;
+          node = node.parent;
+        }
+      },hashName:function (parentid, name) {
+        var hash = 0;
+
+
+        for (var i = 0; i < name.length; i++) {
+          hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
+        }
+        return ((parentid + hash) >>> 0) % FS.nameTable.length;
+      },hashAddNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        node.name_next = FS.nameTable[hash];
+        FS.nameTable[hash] = node;
+      },hashRemoveNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        if (FS.nameTable[hash] === node) {
+          FS.nameTable[hash] = node.name_next;
+        } else {
+          var current = FS.nameTable[hash];
+          while (current) {
+            if (current.name_next === node) {
+              current.name_next = node.name_next;
+              break;
+            }
+            current = current.name_next;
+          }
+        }
+      },lookupNode:function (parent, name) {
+        var err = FS.mayLookup(parent);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        var hash = FS.hashName(parent.id, name);
+        for (var node = FS.nameTable[hash]; node; node = node.name_next) {
+          var nodeName = node.name;
+          if (node.parent.id === parent.id && nodeName === name) {
+            return node;
+          }
+        }
+        // if we failed to find it in the cache, call into the VFS
+        return FS.lookup(parent, name);
+      },createNode:function (parent, name, mode, rdev) {
+        if (!FS.FSNode) {
+          FS.FSNode = function(parent, name, mode, rdev) {
+            if (!parent) {
+              parent = this;  // root node sets parent to itself
+            }
+            this.parent = parent;
+            this.mount = parent.mount;
+            this.mounted = null;
+            this.id = FS.nextInode++;
+            this.name = name;
+            this.mode = mode;
+            this.node_ops = {};
+            this.stream_ops = {};
+            this.rdev = rdev;
+          };
+
+          FS.FSNode.prototype = {};
+
+          // compatibility
+          var readMode = 292 | 73;
+          var writeMode = 146;
+
+          // NOTE we must use Object.defineProperties instead of individual calls to
+          // Object.defineProperty in order to make closure compiler happy
+          Object.defineProperties(FS.FSNode.prototype, {
+            read: {
+              get: function() { return (this.mode & readMode) === readMode; },
+              set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; }
+            },
+            write: {
+              get: function() { return (this.mode & writeMode) === writeMode; },
+              set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; }
+            },
+            isFolder: {
+              get: function() { return FS.isDir(this.mode); },
+            },
+            isDevice: {
+              get: function() { return FS.isChrdev(this.mode); },
+            },
+          });
+        }
+
+        var node = new FS.FSNode(parent, name, mode, rdev);
+
+        FS.hashAddNode(node);
+
+        return node;
+      },destroyNode:function (node) {
+        FS.hashRemoveNode(node);
+      },isRoot:function (node) {
+        return node === node.parent;
+      },isMountpoint:function (node) {
+        return !!node.mounted;
+      },isFile:function (mode) {
+        return (mode & 61440) === 32768;
+      },isDir:function (mode) {
+        return (mode & 61440) === 16384;
+      },isLink:function (mode) {
+        return (mode & 61440) === 40960;
+      },isChrdev:function (mode) {
+        return (mode & 61440) === 8192;
+      },isBlkdev:function (mode) {
+        return (mode & 61440) === 24576;
+      },isFIFO:function (mode) {
+        return (mode & 61440) === 4096;
+      },isSocket:function (mode) {
+        return (mode & 49152) === 49152;
+      },flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function (str) {
+        var flags = FS.flagModes[str];
+        if (typeof flags === 'undefined') {
+          throw new Error('Unknown file open mode: ' + str);
+        }
+        return flags;
+      },flagsToPermissionString:function (flag) {
+        var accmode = flag & 2097155;
+        var perms = ['r', 'w', 'rw'][accmode];
+        if ((flag & 512)) {
+          perms += 'w';
+        }
+        return perms;
+      },nodePermissions:function (node, perms) {
+        if (FS.ignorePermissions) {
+          return 0;
+        }
+        // return 0 if any user, group or owner bits are set.
+        if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
+          return ERRNO_CODES.EACCES;
+        }
+        return 0;
+      },mayLookup:function (dir) {
+        return FS.nodePermissions(dir, 'x');
+      },mayCreate:function (dir, name) {
+        try {
+          var node = FS.lookupNode(dir, name);
+          return ERRNO_CODES.EEXIST;
+        } catch (e) {
+        }
+        return FS.nodePermissions(dir, 'wx');
+      },mayDelete:function (dir, name, isdir) {
+        var node;
+        try {
+          node = FS.lookupNode(dir, name);
+        } catch (e) {
+          return e.errno;
+        }
+        var err = FS.nodePermissions(dir, 'wx');
+        if (err) {
+          return err;
+        }
+        if (isdir) {
+          if (!FS.isDir(node.mode)) {
+            return ERRNO_CODES.ENOTDIR;
+          }
+          if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
+            return ERRNO_CODES.EBUSY;
+          }
+        } else {
+          if (FS.isDir(node.mode)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return 0;
+      },mayOpen:function (node, flags) {
+        if (!node) {
+          return ERRNO_CODES.ENOENT;
+        }
+        if (FS.isLink(node.mode)) {
+          return ERRNO_CODES.ELOOP;
+        } else if (FS.isDir(node.mode)) {
+          if ((flags & 2097155) !== 0 ||  // opening for write
+              (flags & 512)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
+      },MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) {
+        fd_start = fd_start || 0;
+        fd_end = fd_end || FS.MAX_OPEN_FDS;
+        for (var fd = fd_start; fd <= fd_end; fd++) {
+          if (!FS.streams[fd]) {
+            return fd;
+          }
+        }
+        throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
+      },getStream:function (fd) {
+        return FS.streams[fd];
+      },createStream:function (stream, fd_start, fd_end) {
+        if (!FS.FSStream) {
+          FS.FSStream = function(){};
+          FS.FSStream.prototype = {};
+          // compatibility
+          Object.defineProperties(FS.FSStream.prototype, {
+            object: {
+              get: function() { return this.node; },
+              set: function(val) { this.node = val; }
+            },
+            isRead: {
+              get: function() { return (this.flags & 2097155) !== 1; }
+            },
+            isWrite: {
+              get: function() { return (this.flags & 2097155) !== 0; }
+            },
+            isAppend: {
+              get: function() { return (this.flags & 1024); }
+            }
+          });
+        }
+        if (0) {
+          // reuse the object
+          stream.__proto__ = FS.FSStream.prototype;
+        } else {
+          var newStream = new FS.FSStream();
+          for (var p in stream) {
+            newStream[p] = stream[p];
+          }
+          stream = newStream;
+        }
+        var fd = FS.nextfd(fd_start, fd_end);
+        stream.fd = fd;
+        FS.streams[fd] = stream;
+        return stream;
+      },closeStream:function (fd) {
+        FS.streams[fd] = null;
+      },getStreamFromPtr:function (ptr) {
+        return FS.streams[ptr - 1];
+      },getPtrForStream:function (stream) {
+        return stream ? stream.fd + 1 : 0;
+      },chrdev_stream_ops:{open:function (stream) {
+          var device = FS.getDevice(stream.node.rdev);
+          // override node's stream ops with the device's
+          stream.stream_ops = device.stream_ops;
+          // forward the open call
+          if (stream.stream_ops.open) {
+            stream.stream_ops.open(stream);
+          }
+        },llseek:function () {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }},major:function (dev) {
+        return ((dev) >> 8);
+      },minor:function (dev) {
+        return ((dev) & 0xff);
+      },makedev:function (ma, mi) {
+        return ((ma) << 8 | (mi));
+      },registerDevice:function (dev, ops) {
+        FS.devices[dev] = { stream_ops: ops };
+      },getDevice:function (dev) {
+        return FS.devices[dev];
+      },getMounts:function (mount) {
+        var mounts = [];
+        var check = [mount];
+
+        while (check.length) {
+          var m = check.pop();
+
+          mounts.push(m);
+
+          check.push.apply(check, m.mounts);
+        }
+
+        return mounts;
+      },syncfs:function (populate, callback) {
+        if (typeof(populate) === 'function') {
+          callback = populate;
+          populate = false;
+        }
+
+        var mounts = FS.getMounts(FS.root.mount);
+        var completed = 0;
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= mounts.length) {
+            callback(null);
+          }
+        };
+
+        // sync all mounts
+        mounts.forEach(function (mount) {
+          if (!mount.type.syncfs) {
+            return done(null);
+          }
+          mount.type.syncfs(mount, populate, done);
+        });
+      },mount:function (type, opts, mountpoint) {
+        var root = mountpoint === '/';
+        var pseudo = !mountpoint;
+        var node;
+
+        if (root && FS.root) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        } else if (!root && !pseudo) {
+          var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+          mountpoint = lookup.path;  // use the absolute path
+          node = lookup.node;
+
+          if (FS.isMountpoint(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+          }
+
+          if (!FS.isDir(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+          }
+        }
+
+        var mount = {
+          type: type,
+          opts: opts,
+          mountpoint: mountpoint,
+          mounts: []
+        };
+
+        // create a root node for the fs
+        var mountRoot = type.mount(mount);
+        mountRoot.mount = mount;
+        mount.root = mountRoot;
+
+        if (root) {
+          FS.root = mountRoot;
+        } else if (node) {
+          // set as a mountpoint
+          node.mounted = mount;
+
+          // add the new mount to the current mount's children
+          if (node.mount) {
+            node.mount.mounts.push(mount);
+          }
+        }
+
+        return mountRoot;
+      },unmount:function (mountpoint) {
+        var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+        if (!FS.isMountpoint(lookup.node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+
+        // destroy the nodes for this mount, and all its child mounts
+        var node = lookup.node;
+        var mount = node.mounted;
+        var mounts = FS.getMounts(mount);
+
+        Object.keys(FS.nameTable).forEach(function (hash) {
+          var current = FS.nameTable[hash];
+
+          while (current) {
+            var next = current.name_next;
+
+            if (mounts.indexOf(current.mount) !== -1) {
+              FS.destroyNode(current);
+            }
+
+            current = next;
+          }
+        });
+
+        // no longer a mountpoint
+        node.mounted = null;
+
+        // remove this mount from the child mounts
+        var idx = node.mount.mounts.indexOf(mount);
+        assert(idx !== -1);
+        node.mount.mounts.splice(idx, 1);
+      },lookup:function (parent, name) {
+        return parent.node_ops.lookup(parent, name);
+      },mknod:function (path, mode, dev) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var err = FS.mayCreate(parent, name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.mknod) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.mknod(parent, name, mode, dev);
+      },create:function (path, mode) {
+        mode = mode !== undefined ? mode : 438 /* 0666 */;
+        mode &= 4095;
+        mode |= 32768;
+        return FS.mknod(path, mode, 0);
+      },mkdir:function (path, mode) {
+        mode = mode !== undefined ? mode : 511 /* 0777 */;
+        mode &= 511 | 512;
+        mode |= 16384;
+        return FS.mknod(path, mode, 0);
+      },mkdev:function (path, mode, dev) {
+        if (typeof(dev) === 'undefined') {
+          dev = mode;
+          mode = 438 /* 0666 */;
+        }
+        mode |= 8192;
+        return FS.mknod(path, mode, dev);
+      },symlink:function (oldpath, newpath) {
+        var lookup = FS.lookupPath(newpath, { parent: true });
+        var parent = lookup.node;
+        var newname = PATH.basename(newpath);
+        var err = FS.mayCreate(parent, newname);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.symlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.symlink(parent, newname, oldpath);
+      },rename:function (old_path, new_path) {
+        var old_dirname = PATH.dirname(old_path);
+        var new_dirname = PATH.dirname(new_path);
+        var old_name = PATH.basename(old_path);
+        var new_name = PATH.basename(new_path);
+        // parents must exist
+        var lookup, old_dir, new_dir;
+        try {
+          lookup = FS.lookupPath(old_path, { parent: true });
+          old_dir = lookup.node;
+          lookup = FS.lookupPath(new_path, { parent: true });
+          new_dir = lookup.node;
+        } catch (e) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // need to be part of the same mount
+        if (old_dir.mount !== new_dir.mount) {
+          throw new FS.ErrnoError(ERRNO_CODES.EXDEV);
+        }
+        // source must exist
+        var old_node = FS.lookupNode(old_dir, old_name);
+        // old path should not be an ancestor of the new path
+        var relative = PATH.relative(old_path, new_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        // new path should not be an ancestor of the old path
+        relative = PATH.relative(new_path, old_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+        }
+        // see if the new path already exists
+        var new_node;
+        try {
+          new_node = FS.lookupNode(new_dir, new_name);
+        } catch (e) {
+          // not fatal
+        }
+        // early out if nothing needs to change
+        if (old_node === new_node) {
+          return;
+        }
+        // we'll need to delete the old entry
+        var isdir = FS.isDir(old_node.mode);
+        var err = FS.mayDelete(old_dir, old_name, isdir);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // need delete permissions if we'll be overwriting.
+        // need create permissions if new doesn't already exist.
+        err = new_node ?
+          FS.mayDelete(new_dir, new_name, isdir) :
+          FS.mayCreate(new_dir, new_name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!old_dir.node_ops.rename) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // if we are going to change the parent, check write permissions
+        if (new_dir !== old_dir) {
+          err = FS.nodePermissions(old_dir, 'w');
+          if (err) {
+            throw new FS.ErrnoError(err);
+          }
+        }
+        // remove the node from the lookup hash
+        FS.hashRemoveNode(old_node);
+        // do the underlying fs rename
+        try {
+          old_dir.node_ops.rename(old_node, new_dir, new_name);
+        } catch (e) {
+          throw e;
+        } finally {
+          // add the node back to the hash (in case node_ops.rename
+          // changed its name)
+          FS.hashAddNode(old_node);
+        }
+      },rmdir:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, true);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.rmdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.rmdir(parent, name);
+        FS.destroyNode(node);
+      },readdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        if (!node.node_ops.readdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        return node.node_ops.readdir(node);
+      },unlink:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, false);
+        if (err) {
+          // POSIX says unlink should set EPERM, not EISDIR
+          if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM;
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.unlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.unlink(parent, name);
+        FS.destroyNode(node);
+      },readlink:function (path) {
+        var lookup = FS.lookupPath(path);
+        var link = lookup.node;
+        if (!link.node_ops.readlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        return link.node_ops.readlink(link);
+      },stat:function (path, dontFollow) {
+        var lookup = FS.lookupPath(path, { follow: !dontFollow });
+        var node = lookup.node;
+        if (!node.node_ops.getattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return node.node_ops.getattr(node);
+      },lstat:function (path) {
+        return FS.stat(path, true);
+      },chmod:function (path, mode, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          mode: (mode & 4095) | (node.mode & ~4095),
+          timestamp: Date.now()
+        });
+      },lchmod:function (path, mode) {
+        FS.chmod(path, mode, true);
+      },fchmod:function (fd, mode) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chmod(stream.node, mode);
+      },chown:function (path, uid, gid, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          timestamp: Date.now()
+          // we ignore the uid / gid for now
+        });
+      },lchown:function (path, uid, gid) {
+        FS.chown(path, uid, gid, true);
+      },fchown:function (fd, uid, gid) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chown(stream.node, uid, gid);
+      },truncate:function (path, len) {
+        if (len < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: true });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!FS.isFile(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var err = FS.nodePermissions(node, 'w');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        node.node_ops.setattr(node, {
+          size: len,
+          timestamp: Date.now()
+        });
+      },ftruncate:function (fd, len) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        FS.truncate(stream.node, len);
+      },utime:function (path, atime, mtime) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        node.node_ops.setattr(node, {
+          timestamp: Math.max(atime, mtime)
+        });
+      },open:function (path, flags, mode, fd_start, fd_end) {
+        flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
+        mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
+        if ((flags & 64)) {
+          mode = (mode & 4095) | 32768;
+        } else {
+          mode = 0;
+        }
+        var node;
+        if (typeof path === 'object') {
+          node = path;
+        } else {
+          path = PATH.normalize(path);
+          try {
+            var lookup = FS.lookupPath(path, {
+              follow: !(flags & 131072)
+            });
+            node = lookup.node;
+          } catch (e) {
+            // ignore
+          }
+        }
+        // perhaps we need to create the node
+        if ((flags & 64)) {
+          if (node) {
+            // if O_CREAT and O_EXCL are set, error out if the node already exists
+            if ((flags & 128)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EEXIST);
+            }
+          } else {
+            // node doesn't exist, try to create it
+            node = FS.mknod(path, mode, 0);
+          }
+        }
+        if (!node) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
+        }
+        // can't truncate a device
+        if (FS.isChrdev(node.mode)) {
+          flags &= ~512;
+        }
+        // check permissions
+        var err = FS.mayOpen(node, flags);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // do truncation if necessary
+        if ((flags & 512)) {
+          FS.truncate(node, 0);
+        }
+        // we've already handled these, don't pass down to the underlying vfs
+        flags &= ~(128 | 512);
+
+        // register the stream with the filesystem
+        var stream = FS.createStream({
+          node: node,
+          path: FS.getPath(node),  // we want the absolute path to the node
+          flags: flags,
+          seekable: true,
+          position: 0,
+          stream_ops: node.stream_ops,
+          // used by the file family libc calls (fopen, fwrite, ferror, etc.)
+          ungotten: [],
+          error: false
+        }, fd_start, fd_end);
+        // call the new stream's open function
+        if (stream.stream_ops.open) {
+          stream.stream_ops.open(stream);
+        }
+        if (Module['logReadFiles'] && !(flags & 1)) {
+          if (!FS.readFiles) FS.readFiles = {};
+          if (!(path in FS.readFiles)) {
+            FS.readFiles[path] = 1;
+            Module['printErr']('read file: ' + path);
+          }
+        }
+        return stream;
+      },close:function (stream) {
+        try {
+          if (stream.stream_ops.close) {
+            stream.stream_ops.close(stream);
+          }
+        } catch (e) {
+          throw e;
+        } finally {
+          FS.closeStream(stream.fd);
+        }
+      },llseek:function (stream, offset, whence) {
+        if (!stream.seekable || !stream.stream_ops.llseek) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        return stream.stream_ops.llseek(stream, offset, whence);
+      },read:function (stream, buffer, offset, length, position) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.read) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
+        if (!seeking) stream.position += bytesRead;
+        return bytesRead;
+      },write:function (stream, buffer, offset, length, position, canOwn) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.write) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        if (stream.flags & 1024) {
+          // seek to the end before writing in append mode
+          FS.llseek(stream, 0, 2);
+        }
+        var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
+        if (!seeking) stream.position += bytesWritten;
+        return bytesWritten;
+      },allocate:function (stream, offset, length) {
+        if (offset < 0 || length <= 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        if (!stream.stream_ops.allocate) {
+          throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+        }
+        stream.stream_ops.allocate(stream, offset, length);
+      },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+        // TODO if PROT is PROT_WRITE, make sure we have write access
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EACCES);
+        }
+        if (!stream.stream_ops.mmap) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
+      },ioctl:function (stream, cmd, arg) {
+        if (!stream.stream_ops.ioctl) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTTY);
+        }
+        return stream.stream_ops.ioctl(stream, cmd, arg);
+      },readFile:function (path, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'r';
+        opts.encoding = opts.encoding || 'binary';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var ret;
+        var stream = FS.open(path, opts.flags);
+        var stat = FS.stat(path);
+        var length = stat.size;
+        var buf = new Uint8Array(length);
+        FS.read(stream, buf, 0, length, 0);
+        if (opts.encoding === 'utf8') {
+          ret = '';
+          var utf8 = new Runtime.UTF8Processor();
+          for (var i = 0; i < length; i++) {
+            ret += utf8.processCChar(buf[i]);
+          }
+        } else if (opts.encoding === 'binary') {
+          ret = buf;
+        }
+        FS.close(stream);
+        return ret;
+      },writeFile:function (path, data, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'w';
+        opts.encoding = opts.encoding || 'utf8';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var stream = FS.open(path, opts.flags, opts.mode);
+        if (opts.encoding === 'utf8') {
+          var utf8 = new Runtime.UTF8Processor();
+          var buf = new Uint8Array(utf8.processJSString(data));
+          FS.write(stream, buf, 0, buf.length, 0, opts.canOwn);
+        } else if (opts.encoding === 'binary') {
+          FS.write(stream, data, 0, data.length, 0, opts.canOwn);
+        }
+        FS.close(stream);
+      },cwd:function () {
+        return FS.currentPath;
+      },chdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        if (!FS.isDir(lookup.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        var err = FS.nodePermissions(lookup.node, 'x');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        FS.currentPath = lookup.path;
+      },createDefaultDirectories:function () {
+        FS.mkdir('/tmp');
+      },createDefaultDevices:function () {
+        // create /dev
+        FS.mkdir('/dev');
+        // setup /dev/null
+        FS.registerDevice(FS.makedev(1, 3), {
+          read: function() { return 0; },
+          write: function() { return 0; }
+        });
+        FS.mkdev('/dev/null', FS.makedev(1, 3));
+        // setup /dev/tty and /dev/tty1
+        // stderr needs to print output using Module['printErr']
+        // so we register a second tty just for it.
+        TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
+        TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
+        FS.mkdev('/dev/tty', FS.makedev(5, 0));
+        FS.mkdev('/dev/tty1', FS.makedev(6, 0));
+        // we're not going to emulate the actual shm device,
+        // just create the tmp dirs that reside in it commonly
+        FS.mkdir('/dev/shm');
+        FS.mkdir('/dev/shm/tmp');
+      },createStandardStreams:function () {
+        // TODO deprecate the old functionality of a single
+        // input / output callback and that utilizes FS.createDevice
+        // and instead require a unique set of stream ops
+
+        // by default, we symlink the standard streams to the
+        // default tty devices. however, if the standard streams
+        // have been overwritten we create a unique device for
+        // them instead.
+        if (Module['stdin']) {
+          FS.createDevice('/dev', 'stdin', Module['stdin']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdin');
+        }
+        if (Module['stdout']) {
+          FS.createDevice('/dev', 'stdout', null, Module['stdout']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdout');
+        }
+        if (Module['stderr']) {
+          FS.createDevice('/dev', 'stderr', null, Module['stderr']);
+        } else {
+          FS.symlink('/dev/tty1', '/dev/stderr');
+        }
+
+        // open default streams for the stdin, stdout and stderr devices
+        var stdin = FS.open('/dev/stdin', 'r');
+        HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin);
+        assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
+
+        var stdout = FS.open('/dev/stdout', 'w');
+        HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout);
+        assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
+
+        var stderr = FS.open('/dev/stderr', 'w');
+        HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr);
+        assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
+      },ensureErrnoError:function () {
+        if (FS.ErrnoError) return;
+        FS.ErrnoError = function ErrnoError(errno) {
+          this.errno = errno;
+          for (var key in ERRNO_CODES) {
+            if (ERRNO_CODES[key] === errno) {
+              this.code = key;
+              break;
+            }
+          }
+          this.message = ERRNO_MESSAGES[errno];
+        };
+        FS.ErrnoError.prototype = new Error();
+        FS.ErrnoError.prototype.constructor = FS.ErrnoError;
+        // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
+        [ERRNO_CODES.ENOENT].forEach(function(code) {
+          FS.genericErrors[code] = new FS.ErrnoError(code);
+          FS.genericErrors[code].stack = '<generic error, no stack>';
+        });
+      },staticInit:function () {
+        FS.ensureErrnoError();
+
+        FS.nameTable = new Array(4096);
+
+        FS.mount(MEMFS, {}, '/');
+
+        FS.createDefaultDirectories();
+        FS.createDefaultDevices();
+      },init:function (input, output, error) {
+        assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
+        FS.init.initialized = true;
+
+        FS.ensureErrnoError();
+
+        // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
+        Module['stdin'] = input || Module['stdin'];
+        Module['stdout'] = output || Module['stdout'];
+        Module['stderr'] = error || Module['stderr'];
+
+        FS.createStandardStreams();
+      },quit:function () {
+        FS.init.initialized = false;
+        for (var i = 0; i < FS.streams.length; i++) {
+          var stream = FS.streams[i];
+          if (!stream) {
+            continue;
+          }
+          FS.close(stream);
+        }
+      },getMode:function (canRead, canWrite) {
+        var mode = 0;
+        if (canRead) mode |= 292 | 73;
+        if (canWrite) mode |= 146;
+        return mode;
+      },joinPath:function (parts, forceRelative) {
+        var path = PATH.join.apply(null, parts);
+        if (forceRelative && path[0] == '/') path = path.substr(1);
+        return path;
+      },absolutePath:function (relative, base) {
+        return PATH.resolve(base, relative);
+      },standardizePath:function (path) {
+        return PATH.normalize(path);
+      },findObject:function (path, dontResolveLastLink) {
+        var ret = FS.analyzePath(path, dontResolveLastLink);
+        if (ret.exists) {
+          return ret.object;
+        } else {
+          ___setErrNo(ret.error);
+          return null;
+        }
+      },analyzePath:function (path, dontResolveLastLink) {
+        // operate from within the context of the symlink's target
+        try {
+          var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          path = lookup.path;
+        } catch (e) {
+        }
+        var ret = {
+          isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
+          parentExists: false, parentPath: null, parentObject: null
+        };
+        try {
+          var lookup = FS.lookupPath(path, { parent: true });
+          ret.parentExists = true;
+          ret.parentPath = lookup.path;
+          ret.parentObject = lookup.node;
+          ret.name = PATH.basename(path);
+          lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          ret.exists = true;
+          ret.path = lookup.path;
+          ret.object = lookup.node;
+          ret.name = lookup.node.name;
+          ret.isRoot = lookup.path === '/';
+        } catch (e) {
+          ret.error = e.errno;
+        };
+        return ret;
+      },createFolder:function (parent, name, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.mkdir(path, mode);
+      },createPath:function (parent, path, canRead, canWrite) {
+        parent = typeof parent === 'string' ? parent : FS.getPath(parent);
+        var parts = path.split('/').reverse();
+        while (parts.length) {
+          var part = parts.pop();
+          if (!part) continue;
+          var current = PATH.join2(parent, part);
+          try {
+            FS.mkdir(current);
+          } catch (e) {
+            // ignore EEXIST
+          }
+          parent = current;
+        }
+        return current;
+      },createFile:function (parent, name, properties, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.create(path, mode);
+      },createDataFile:function (parent, name, data, canRead, canWrite, canOwn) {
+        var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
+        var mode = FS.getMode(canRead, canWrite);
+        var node = FS.create(path, mode);
+        if (data) {
+          if (typeof data === 'string') {
+            var arr = new Array(data.length);
+            for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
+            data = arr;
+          }
+          // make sure we can write to the file
+          FS.chmod(node, mode | 146);
+          var stream = FS.open(node, 'w');
+          FS.write(stream, data, 0, data.length, 0, canOwn);
+          FS.close(stream);
+          FS.chmod(node, mode);
+        }
+        return node;
+      },createDevice:function (parent, name, input, output) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(!!input, !!output);
+        if (!FS.createDevice.major) FS.createDevice.major = 64;
+        var dev = FS.makedev(FS.createDevice.major++, 0);
+        // Create a fake device that a set of stream ops to emulate
+        // the old behavior.
+        FS.registerDevice(dev, {
+          open: function(stream) {
+            stream.seekable = false;
+          },
+          close: function(stream) {
+            // flush any pending line data
+            if (output && output.buffer && output.buffer.length) {
+              output(10);
+            }
+          },
+          read: function(stream, buffer, offset, length, pos /* ignored */) {
+            var bytesRead = 0;
+            for (var i = 0; i < length; i++) {
+              var result;
+              try {
+                result = input();
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+              if (result === undefined && bytesRead === 0) {
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+              if (result === null || result === undefined) break;
+              bytesRead++;
+              buffer[offset+i] = result;
+            }
+            if (bytesRead) {
+              stream.node.timestamp = Date.now();
+            }
+            return bytesRead;
+          },
+          write: function(stream, buffer, offset, length, pos) {
+            for (var i = 0; i < length; i++) {
+              try {
+                output(buffer[offset+i]);
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+            }
+            if (length) {
+              stream.node.timestamp = Date.now();
+            }
+            return i;
+          }
+        });
+        return FS.mkdev(path, mode, dev);
+      },createLink:function (parent, name, target, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        return FS.symlink(target, path);
+      },forceLoadFile:function (obj) {
+        if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
+        var success = true;
+        if (typeof XMLHttpRequest !== 'undefined') {
+          throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
+        } else if (Module['read']) {
+          // Command-line.
+          try {
+            // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
+            //          read() will try to parse UTF8.
+            obj.contents = intArrayFromString(Module['read'](obj.url), true);
+          } catch (e) {
+            success = false;
+          }
+        } else {
+          throw new Error('Cannot load without read() or XMLHttpRequest.');
+        }
+        if (!success) ___setErrNo(ERRNO_CODES.EIO);
+        return success;
+      },createLazyFile:function (parent, name, url, canRead, canWrite) {
+        // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
+        function LazyUint8Array() {
+          this.lengthKnown = false;
+          this.chunks = []; // Loaded chunks. Index is the chunk number
+        }
+        LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
+          if (idx > this.length-1 || idx < 0) {
+            return undefined;
+          }
+          var chunkOffset = idx % this.chunkSize;
+          var chunkNum = Math.floor(idx / this.chunkSize);
+          return this.getter(chunkNum)[chunkOffset];
+        }
+        LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
+          this.getter = getter;
+        }
+        LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
+            // Find length
+            var xhr = new XMLHttpRequest();
+            xhr.open('HEAD', url, false);
+            xhr.send(null);
+            if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+            var datalength = Number(xhr.getResponseHeader("Content-length"));
+            var header;
+            var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
+            var chunkSize = 1024*1024; // Chunk size in bytes
+
+            if (!hasByteServing) chunkSize = datalength;
+
+            // Function to get a range from the remote URL.
+            var doXHR = (function(from, to) {
+              if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
+              if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
+
+              // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
+              var xhr = new XMLHttpRequest();
+              xhr.open('GET', url, false);
+              if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
+
+              // Some hints to the browser that we want binary data.
+              if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
+              if (xhr.overrideMimeType) {
+                xhr.overrideMimeType('text/plain; charset=x-user-defined');
+              }
+
+              xhr.send(null);
+              if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+              if (xhr.response !== undefined) {
+                return new Uint8Array(xhr.response || []);
+              } else {
+                return intArrayFromString(xhr.responseText || '', true);
+              }
+            });
+            var lazyArray = this;
+            lazyArray.setDataGetter(function(chunkNum) {
+              var start = chunkNum * chunkSize;
+              var end = (chunkNum+1) * chunkSize - 1; // including this byte
+              end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
+                lazyArray.chunks[chunkNum] = doXHR(start, end);
+              }
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
+              return lazyArray.chunks[chunkNum];
+            });
+
+            this._length = datalength;
+            this._chunkSize = chunkSize;
+            this.lengthKnown = true;
+        }
+        if (typeof XMLHttpRequest !== 'undefined') {
+          if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
+          var lazyArray = new LazyUint8Array();
+          Object.defineProperty(lazyArray, "length", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._length;
+              }
+          });
+          Object.defineProperty(lazyArray, "chunkSize", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._chunkSize;
+              }
+          });
+
+          var properties = { isDevice: false, contents: lazyArray };
+        } else {
+          var properties = { isDevice: false, url: url };
+        }
+
+        var node = FS.createFile(parent, name, properties, canRead, canWrite);
+        // This is a total hack, but I want to get this lazy file code out of the
+        // core of MEMFS. If we want to keep this lazy file concept I feel it should
+        // be its own thin LAZYFS proxying calls to MEMFS.
+        if (properties.contents) {
+          node.contents = properties.contents;
+        } else if (properties.url) {
+          node.contents = null;
+          node.url = properties.url;
+        }
+        // override each stream op with one that tries to force load the lazy file first
+        var stream_ops = {};
+        var keys = Object.keys(node.stream_ops);
+        keys.forEach(function(key) {
+          var fn = node.stream_ops[key];
+          stream_ops[key] = function forceLoadLazyFile() {
+            if (!FS.forceLoadFile(node)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            return fn.apply(null, arguments);
+          };
+        });
+        // use a custom read function
+        stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
+          if (!FS.forceLoadFile(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EIO);
+          }
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (contents.slice) { // normal array
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          } else {
+            for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
+              buffer[offset + i] = contents.get(position + i);
+            }
+          }
+          return size;
+        };
+        node.stream_ops = stream_ops;
+        return node;
+      },createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
+        Browser.init();
+        // TODO we should allow people to just pass in a complete filename instead
+        // of parent and name being that we just join them anyways
+        var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent;
+        function processData(byteArray) {
+          function finish(byteArray) {
+            if (!dontCreateFile) {
+              FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
+            }
+            if (onload) onload();
+            removeRunDependency('cp ' + fullname);
+          }
+          var handled = false;
+          Module['preloadPlugins'].forEach(function(plugin) {
+            if (handled) return;
+            if (plugin['canHandle'](fullname)) {
+              plugin['handle'](byteArray, fullname, finish, function() {
+                if (onerror) onerror();
+                removeRunDependency('cp ' + fullname);
+              });
+              handled = true;
+            }
+          });
+          if (!handled) finish(byteArray);
+        }
+        addRunDependency('cp ' + fullname);
+        if (typeof url == 'string') {
+          Browser.asyncLoad(url, function(byteArray) {
+            processData(byteArray);
+          }, onerror);
+        } else {
+          processData(url);
+        }
+      },indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_NAME:function () {
+        return 'EM_FS_' + window.location.pathname;
+      },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
+          console.log('creating db');
+          var db = openRequest.result;
+          db.createObjectStore(FS.DB_STORE_NAME);
+        };
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var putRequest = files.put(FS.analyzePath(path).object.contents, path);
+            putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
+            putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      },loadFilesFromDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = onerror; // no database to load from
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          try {
+            var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
+          } catch(e) {
+            onerror(e);
+            return;
+          }
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var getRequest = files.get(path);
+            getRequest.onsuccess = function getRequest_onsuccess() {
+              if (FS.analyzePath(path).exists) {
+                FS.unlink(path);
+              }
+              FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
+              ok++;
+              if (ok + fail == total) finish();
+            };
+            getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      }};var PATH={splitPath:function (filename) {
+        var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+        return splitPathRe.exec(filename).slice(1);
+      },normalizeArray:function (parts, allowAboveRoot) {
+        // if the path tries to go above the root, `up` ends up > 0
+        var up = 0;
+        for (var i = parts.length - 1; i >= 0; i--) {
+          var last = parts[i];
+          if (last === '.') {
+            parts.splice(i, 1);
+          } else if (last === '..') {
+            parts.splice(i, 1);
+            up++;
+          } else if (up) {
+            parts.splice(i, 1);
+            up--;
+          }
+        }
+        // if the path is allowed to go above the root, restore leading ..s
+        if (allowAboveRoot) {
+          for (; up--; up) {
+            parts.unshift('..');
+          }
+        }
+        return parts;
+      },normalize:function (path) {
+        var isAbsolute = path.charAt(0) === '/',
+            trailingSlash = path.substr(-1) === '/';
+        // Normalize the path
+        path = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), !isAbsolute).join('/');
+        if (!path && !isAbsolute) {
+          path = '.';
+        }
+        if (path && trailingSlash) {
+          path += '/';
+        }
+        return (isAbsolute ? '/' : '') + path;
+      },dirname:function (path) {
+        var result = PATH.splitPath(path),
+            root = result[0],
+            dir = result[1];
+        if (!root && !dir) {
+          // No dirname whatsoever
+          return '.';
+        }
+        if (dir) {
+          // It has a dirname, strip trailing slash
+          dir = dir.substr(0, dir.length - 1);
+        }
+        return root + dir;
+      },basename:function (path) {
+        // EMSCRIPTEN return '/'' for '/', not an empty string
+        if (path === '/') return '/';
+        var lastSlash = path.lastIndexOf('/');
+        if (lastSlash === -1) return path;
+        return path.substr(lastSlash+1);
+      },extname:function (path) {
+        return PATH.splitPath(path)[3];
+      },join:function () {
+        var paths = Array.prototype.slice.call(arguments, 0);
+        return PATH.normalize(paths.join('/'));
+      },join2:function (l, r) {
+        return PATH.normalize(l + '/' + r);
+      },resolve:function () {
+        var resolvedPath = '',
+          resolvedAbsolute = false;
+        for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+          var path = (i >= 0) ? arguments[i] : FS.cwd();
+          // Skip empty and invalid entries
+          if (typeof path !== 'string') {
+            throw new TypeError('Arguments to path.resolve must be strings');
+          } else if (!path) {
+            continue;
+          }
+          resolvedPath = path + '/' + resolvedPath;
+          resolvedAbsolute = path.charAt(0) === '/';
+        }
+        // At this point the path should be resolved to a full absolute path, but
+        // handle relative paths to be safe (might happen when process.cwd() fails)
+        resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
+          return !!p;
+        }), !resolvedAbsolute).join('/');
+        return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+      },relative:function (from, to) {
+        from = PATH.resolve(from).substr(1);
+        to = PATH.resolve(to).substr(1);
+        function trim(arr) {
+          var start = 0;
+          for (; start < arr.length; start++) {
+            if (arr[start] !== '') break;
+          }
+          var end = arr.length - 1;
+          for (; end >= 0; end--) {
+            if (arr[end] !== '') break;
+          }
+          if (start > end) return [];
+          return arr.slice(start, end - start + 1);
+        }
+        var fromParts = trim(from.split('/'));
+        var toParts = trim(to.split('/'));
+        var length = Math.min(fromParts.length, toParts.length);
+        var samePartsLength = length;
+        for (var i = 0; i < length; i++) {
+          if (fromParts[i] !== toParts[i]) {
+            samePartsLength = i;
+            break;
+          }
+        }
+        var outputParts = [];
+        for (var i = samePartsLength; i < fromParts.length; i++) {
+          outputParts.push('..');
+        }
+        outputParts = outputParts.concat(toParts.slice(samePartsLength));
+        return outputParts.join('/');
+      }};var Browser={mainLoop:{scheduler:null,method:"",shouldPause:false,paused:false,queue:[],pause:function () {
+          Browser.mainLoop.shouldPause = true;
+        },resume:function () {
+          if (Browser.mainLoop.paused) {
+            Browser.mainLoop.paused = false;
+            Browser.mainLoop.scheduler();
+          }
+          Browser.mainLoop.shouldPause = false;
+        },updateStatus:function () {
+          if (Module['setStatus']) {
+            var message = Module['statusMessage'] || 'Please wait...';
+            var remaining = Browser.mainLoop.remainingBlockers;
+            var expected = Browser.mainLoop.expectedBlockers;
+            if (remaining) {
+              if (remaining < expected) {
+                Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
+              } else {
+                Module['setStatus'](message);
+              }
+            } else {
+              Module['setStatus']('');
+            }
+          }
+        }},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () {
+        if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
+
+        if (Browser.initted || ENVIRONMENT_IS_WORKER) return;
+        Browser.initted = true;
+
+        try {
+          new Blob();
+          Browser.hasBlobConstructor = true;
+        } catch(e) {
+          Browser.hasBlobConstructor = false;
+          console.log("warning: no blob constructor, cannot create blobs with mimetypes");
+        }
+        Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
+        Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
+        if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
+          console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
+          Module.noImageDecoding = true;
+        }
+
+        // Support for plugins that can process preloaded files. You can add more of these to
+        // your app by creating and appending to Module.preloadPlugins.
+        //
+        // Each plugin is asked if it can handle a file based on the file's name. If it can,
+        // it is given the file's raw data. When it is done, it calls a callback with the file's
+        // (possibly modified) data. For example, a plugin might decompress a file, or it
+        // might create some side data structure for use later (like an Image element, etc.).
+
+        var imagePlugin = {};
+        imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
+          return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
+        };
+        imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
+          var b = null;
+          if (Browser.hasBlobConstructor) {
+            try {
+              b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+              if (b.size !== byteArray.length) { // Safari bug #118630
+                // Safari's Blob can only take an ArrayBuffer
+                b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
+              }
+            } catch(e) {
+              Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
+            }
+          }
+          if (!b) {
+            var bb = new Browser.BlobBuilder();
+            bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
+            b = bb.getBlob();
+          }
+          var url = Browser.URLObject.createObjectURL(b);
+          var img = new Image();
+          img.onload = function img_onload() {
+            assert(img.complete, 'Image ' + name + ' could not be decoded');
+            var canvas = document.createElement('canvas');
+            canvas.width = img.width;
+            canvas.height = img.height;
+            var ctx = canvas.getContext('2d');
+            ctx.drawImage(img, 0, 0);
+            Module["preloadedImages"][name] = canvas;
+            Browser.URLObject.revokeObjectURL(url);
+            if (onload) onload(byteArray);
+          };
+          img.onerror = function img_onerror(event) {
+            console.log('Image ' + url + ' could not be decoded');
+            if (onerror) onerror();
+          };
+          img.src = url;
+        };
+        Module['preloadPlugins'].push(imagePlugin);
+
+        var audioPlugin = {};
+        audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
+          return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
+        };
+        audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
+          var done = false;
+          function finish(audio) {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = audio;
+            if (onload) onload(byteArray);
+          }
+          function fail() {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = new Audio(); // empty shim
+            if (onerror) onerror();
+          }
+          if (Browser.hasBlobConstructor) {
+            try {
+              var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+            } catch(e) {
+              return fail();
+            }
+            var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
+            var audio = new Audio();
+            audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926
+            audio.onerror = function audio_onerror(event) {
+              if (done) return;
+              console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
+              function encode64(data) {
+                var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+                var PAD = '=';
+                var ret = '';
+                var leftchar = 0;
+                var leftbits = 0;
+                for (var i = 0; i < data.length; i++) {
+                  leftchar = (leftchar << 8) | data[i];
+                  leftbits += 8;
+                  while (leftbits >= 6) {
+                    var curr = (leftchar >> (leftbits-6)) & 0x3f;
+                    leftbits -= 6;
+                    ret += BASE[curr];
+                  }
+                }
+                if (leftbits == 2) {
+                  ret += BASE[(leftchar&3) << 4];
+                  ret += PAD + PAD;
+                } else if (leftbits == 4) {
+                  ret += BASE[(leftchar&0xf) << 2];
+                  ret += PAD;
+                }
+                return ret;
+              }
+              audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
+              finish(audio); // we don't wait for confirmation this worked - but it's worth trying
+            };
+            audio.src = url;
+            // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
+            Browser.safeSetTimeout(function() {
+              finish(audio); // try to use it even though it is not necessarily ready to play
+            }, 10000);
+          } else {
+            return fail();
+          }
+        };
+        Module['preloadPlugins'].push(audioPlugin);
+
+        // Canvas event setup
+
+        var canvas = Module['canvas'];
+
+        // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
+        // Module['forcedAspectRatio'] = 4 / 3;
+
+        canvas.requestPointerLock = canvas['requestPointerLock'] ||
+                                    canvas['mozRequestPointerLock'] ||
+                                    canvas['webkitRequestPointerLock'] ||
+                                    canvas['msRequestPointerLock'] ||
+                                    function(){};
+        canvas.exitPointerLock = document['exitPointerLock'] ||
+                                 document['mozExitPointerLock'] ||
+                                 document['webkitExitPointerLock'] ||
+                                 document['msExitPointerLock'] ||
+                                 function(){}; // no-op if function does not exist
+        canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
+
+        function pointerLockChange() {
+          Browser.pointerLock = document['pointerLockElement'] === canvas ||
+                                document['mozPointerLockElement'] === canvas ||
+                                document['webkitPointerLockElement'] === canvas ||
+                                document['msPointerLockElement'] === canvas;
+        }
+
+        document.addEventListener('pointerlockchange', pointerLockChange, false);
+        document.addEventListener('mozpointerlockchange', pointerLockChange, false);
+        document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
+        document.addEventListener('mspointerlockchange', pointerLockChange, false);
+
+        if (Module['elementPointerLock']) {
+          canvas.addEventListener("click", function(ev) {
+            if (!Browser.pointerLock && canvas.requestPointerLock) {
+              canvas.requestPointerLock();
+              ev.preventDefault();
+            }
+          }, false);
+        }
+      },createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) {
+        var ctx;
+        var errorInfo = '?';
+        function onContextCreationError(event) {
+          errorInfo = event.statusMessage || errorInfo;
+        }
+        try {
+          if (useWebGL) {
+            var contextAttributes = {
+              antialias: false,
+              alpha: false
+            };
+
+            if (webGLContextAttributes) {
+              for (var attribute in webGLContextAttributes) {
+                contextAttributes[attribute] = webGLContextAttributes[attribute];
+              }
+            }
+
+
+            canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
+            try {
+              ['experimental-webgl', 'webgl'].some(function(webglId) {
+                return ctx = canvas.getContext(webglId, contextAttributes);
+              });
+            } finally {
+              canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
+            }
+          } else {
+            ctx = canvas.getContext('2d');
+          }
+          if (!ctx) throw ':(';
+        } catch (e) {
+          Module.print('Could not create canvas: ' + [errorInfo, e]);
+          return null;
+        }
+        if (useWebGL) {
+          // Set the background of the WebGL canvas to black
+          canvas.style.backgroundColor = "black";
+
+          // Warn on context loss
+          canvas.addEventListener('webglcontextlost', function(event) {
+            alert('WebGL context lost. You will need to reload the page.');
+          }, false);
+        }
+        if (setInModule) {
+          GLctx = Module.ctx = ctx;
+          Module.useWebGL = useWebGL;
+          Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
+          Browser.init();
+        }
+        return ctx;
+      },destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) {
+        Browser.lockPointer = lockPointer;
+        Browser.resizeCanvas = resizeCanvas;
+        if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;
+        if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;
+
+        var canvas = Module['canvas'];
+        function fullScreenChange() {
+          Browser.isFullScreen = false;
+          var canvasContainer = canvas.parentNode;
+          if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+               document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+               document['fullScreenElement'] || document['fullscreenElement'] ||
+               document['msFullScreenElement'] || document['msFullscreenElement'] ||
+               document['webkitCurrentFullScreenElement']) === canvasContainer) {
+            canvas.cancelFullScreen = document['cancelFullScreen'] ||
+                                      document['mozCancelFullScreen'] ||
+                                      document['webkitCancelFullScreen'] ||
+                                      document['msExitFullscreen'] ||
+                                      document['exitFullscreen'] ||
+                                      function() {};
+            canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document);
+            if (Browser.lockPointer) canvas.requestPointerLock();
+            Browser.isFullScreen = true;
+            if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize();
+          } else {
+
+            // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
+            canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
+            canvasContainer.parentNode.removeChild(canvasContainer);
+
+            if (Browser.resizeCanvas) Browser.setWindowedCanvasSize();
+          }
+          if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen);
+          Browser.updateCanvasDimensions(canvas);
+        }
+
+        if (!Browser.fullScreenHandlersInstalled) {
+          Browser.fullScreenHandlersInstalled = true;
+          document.addEventListener('fullscreenchange', fullScreenChange, false);
+          document.addEventListener('mozfullscreenchange', fullScreenChange, false);
+          document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
+          document.addEventListener('MSFullscreenChange', fullScreenChange, false);
+        }
+
+        // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
+        var canvasContainer = document.createElement("div");
+        canvas.parentNode.insertBefore(canvasContainer, canvas);
+        canvasContainer.appendChild(canvas);
+
+        // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
+        canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] ||
+                                            canvasContainer['mozRequestFullScreen'] ||
+                                            canvasContainer['msRequestFullscreen'] ||
+                                           (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
+        canvasContainer.requestFullScreen();
+      },requestAnimationFrame:function requestAnimationFrame(func) {
+        if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js)
+          setTimeout(func, 1000/60);
+        } else {
+          if (!window.requestAnimationFrame) {
+            window.requestAnimationFrame = window['requestAnimationFrame'] ||
+                                           window['mozRequestAnimationFrame'] ||
+                                           window['webkitRequestAnimationFrame'] ||
+                                           window['msRequestAnimationFrame'] ||
+                                           window['oRequestAnimationFrame'] ||
+                                           window['setTimeout'];
+          }
+          window.requestAnimationFrame(func);
+        }
+      },safeCallback:function (func) {
+        return function() {
+          if (!ABORT) return func.apply(null, arguments);
+        };
+      },safeRequestAnimationFrame:function (func) {
+        return Browser.requestAnimationFrame(function() {
+          if (!ABORT) func();
+        });
+      },safeSetTimeout:function (func, timeout) {
+        return setTimeout(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },safeSetInterval:function (func, timeout) {
+        return setInterval(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },getMimetype:function (name) {
+        return {
+          'jpg': 'image/jpeg',
+          'jpeg': 'image/jpeg',
+          'png': 'image/png',
+          'bmp': 'image/bmp',
+          'ogg': 'audio/ogg',
+          'wav': 'audio/wav',
+          'mp3': 'audio/mpeg'
+        }[name.substr(name.lastIndexOf('.')+1)];
+      },getUserMedia:function (func) {
+        if(!window.getUserMedia) {
+          window.getUserMedia = navigator['getUserMedia'] ||
+                                navigator['mozGetUserMedia'];
+        }
+        window.getUserMedia(func);
+      },getMovementX:function (event) {
+        return event['movementX'] ||
+               event['mozMovementX'] ||
+               event['webkitMovementX'] ||
+               0;
+      },getMovementY:function (event) {
+        return event['movementY'] ||
+               event['mozMovementY'] ||
+               event['webkitMovementY'] ||
+               0;
+      },getMouseWheelDelta:function (event) {
+        return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta));
+      },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup
+        if (Browser.pointerLock) {
+          // When the pointer is locked, calculate the coordinates
+          // based on the movement of the mouse.
+          // Workaround for Firefox bug 764498
+          if (event.type != 'mousemove' &&
+              ('mozMovementX' in event)) {
+            Browser.mouseMovementX = Browser.mouseMovementY = 0;
+          } else {
+            Browser.mouseMovementX = Browser.getMovementX(event);
+            Browser.mouseMovementY = Browser.getMovementY(event);
+          }
+
+          // check if SDL is available
+          if (typeof SDL != "undefined") {
+            Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
+            Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
+          } else {
+            // just add the mouse delta to the current absolut mouse position
+            // FIXME: ideally this should be clamped against the canvas size and zero
+            Browser.mouseX += Browser.mouseMovementX;
+            Browser.mouseY += Browser.mouseMovementY;
+          }
+        } else {
+          // Otherwise, calculate the movement based on the changes
+          // in the coordinates.
+          var rect = Module["canvas"].getBoundingClientRect();
+          var x, y;
+
+          // Neither .scrollX or .pageXOffset are defined in a spec, but
+          // we prefer .scrollX because it is currently in a spec draft.
+          // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
+          var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);
+          var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);
+          if (event.type == 'touchstart' ||
+              event.type == 'touchend' ||
+              event.type == 'touchmove') {
+            var t = event.touches.item(0);
+            if (t) {
+              x = t.pageX - (scrollX + rect.left);
+              y = t.pageY - (scrollY + rect.top);
+            } else {
+              return;
+            }
+          } else {
+            x = event.pageX - (scrollX + rect.left);
+            y = event.pageY - (scrollY + rect.top);
+          }
+
+          // the canvas might be CSS-scaled compared to its backbuffer;
+          // SDL-using content will want mouse coordinates in terms
+          // of backbuffer units.
+          var cw = Module["canvas"].width;
+          var ch = Module["canvas"].height;
+          x = x * (cw / rect.width);
+          y = y * (ch / rect.height);
+
+          Browser.mouseMovementX = x - Browser.mouseX;
+          Browser.mouseMovementY = y - Browser.mouseY;
+          Browser.mouseX = x;
+          Browser.mouseY = y;
+        }
+      },xhrLoad:function (url, onload, onerror) {
+        var xhr = new XMLHttpRequest();
+        xhr.open('GET', url, true);
+        xhr.responseType = 'arraybuffer';
+        xhr.onload = function xhr_onload() {
+          if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
+            onload(xhr.response);
+          } else {
+            onerror();
+          }
+        };
+        xhr.onerror = onerror;
+        xhr.send(null);
+      },asyncLoad:function (url, onload, onerror, noRunDep) {
+        Browser.xhrLoad(url, function(arrayBuffer) {
+          assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
+          onload(new Uint8Array(arrayBuffer));
+          if (!noRunDep) removeRunDependency('al ' + url);
+        }, function(event) {
+          if (onerror) {
+            onerror();
+          } else {
+            throw 'Loading data file "' + url + '" failed.';
+          }
+        });
+        if (!noRunDep) addRunDependency('al ' + url);
+      },resizeListeners:[],updateResizeListeners:function () {
+        var canvas = Module['canvas'];
+        Browser.resizeListeners.forEach(function(listener) {
+          listener(canvas.width, canvas.height);
+        });
+      },setCanvasSize:function (width, height, noUpdates) {
+        var canvas = Module['canvas'];
+        Browser.updateCanvasDimensions(canvas, width, height);
+        if (!noUpdates) Browser.updateResizeListeners();
+      },windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+          var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+          flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
+          HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },setWindowedCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+          var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+          flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
+          HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },updateCanvasDimensions:function (canvas, wNative, hNative) {
+        if (wNative && hNative) {
+          canvas.widthNative = wNative;
+          canvas.heightNative = hNative;
+        } else {
+          wNative = canvas.widthNative;
+          hNative = canvas.heightNative;
+        }
+        var w = wNative;
+        var h = hNative;
+        if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
+          if (w/h < Module['forcedAspectRatio']) {
+            w = Math.round(h * Module['forcedAspectRatio']);
+          } else {
+            h = Math.round(w / Module['forcedAspectRatio']);
+          }
+        }
+        if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+             document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+             document['fullScreenElement'] || document['fullscreenElement'] ||
+             document['msFullScreenElement'] || document['msFullscreenElement'] ||
+             document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
+           var factor = Math.min(screen.width / w, screen.height / h);
+           w = Math.round(w * factor);
+           h = Math.round(h * factor);
+        }
+        if (Browser.resizeCanvas) {
+          if (canvas.width  != w) canvas.width  = w;
+          if (canvas.height != h) canvas.height = h;
+          if (typeof canvas.style != 'undefined') {
+            canvas.style.removeProperty( "width");
+            canvas.style.removeProperty("height");
+          }
+        } else {
+          if (canvas.width  != wNative) canvas.width  = wNative;
+          if (canvas.height != hNative) canvas.height = hNative;
+          if (typeof canvas.style != 'undefined') {
+            if (w != wNative || h != hNative) {
+              canvas.style.setProperty( "width", w + "px", "important");
+              canvas.style.setProperty("height", h + "px", "important");
+            } else {
+              canvas.style.removeProperty( "width");
+              canvas.style.removeProperty("height");
+            }
+          }
+        }
+      }};
+
+
+
+
+
+
+
+  function _mkport() { throw 'TODO' }var SOCKFS={mount:function (mount) {
+        return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createSocket:function (family, type, protocol) {
+        var streaming = type == 1;
+        if (protocol) {
+          assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp
+        }
+
+        // create our internal socket structure
+        var sock = {
+          family: family,
+          type: type,
+          protocol: protocol,
+          server: null,
+          peers: {},
+          pending: [],
+          recv_queue: [],
+          sock_ops: SOCKFS.websocket_sock_ops
+        };
+
+        // create the filesystem node to store the socket structure
+        var name = SOCKFS.nextname();
+        var node = FS.createNode(SOCKFS.root, name, 49152, 0);
+        node.sock = sock;
+
+        // and the wrapping stream that enables library functions such
+        // as read and write to indirectly interact with the socket
+        var stream = FS.createStream({
+          path: name,
+          node: node,
+          flags: FS.modeStringToFlags('r+'),
+          seekable: false,
+          stream_ops: SOCKFS.stream_ops
+        });
+
+        // map the new stream to the socket structure (sockets have a 1:1
+        // relationship with a stream)
+        sock.stream = stream;
+
+        return sock;
+      },getSocket:function (fd) {
+        var stream = FS.getStream(fd);
+        if (!stream || !FS.isSocket(stream.node.mode)) {
+          return null;
+        }
+        return stream.node.sock;
+      },stream_ops:{poll:function (stream) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.poll(sock);
+        },ioctl:function (stream, request, varargs) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.ioctl(sock, request, varargs);
+        },read:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          var msg = sock.sock_ops.recvmsg(sock, length);
+          if (!msg) {
+            // socket is closed
+            return 0;
+          }
+          buffer.set(msg.buffer, offset);
+          return msg.buffer.length;
+        },write:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.sendmsg(sock, buffer, offset, length);
+        },close:function (stream) {
+          var sock = stream.node.sock;
+          sock.sock_ops.close(sock);
+        }},nextname:function () {
+        if (!SOCKFS.nextname.current) {
+          SOCKFS.nextname.current = 0;
+        }
+        return 'socket[' + (SOCKFS.nextname.current++) + ']';
+      },websocket_sock_ops:{createPeer:function (sock, addr, port) {
+          var ws;
+
+          if (typeof addr === 'object') {
+            ws = addr;
+            addr = null;
+            port = null;
+          }
+
+          if (ws) {
+            // for sockets that've already connected (e.g. we're the server)
+            // we can inspect the _socket property for the address
+            if (ws._socket) {
+              addr = ws._socket.remoteAddress;
+              port = ws._socket.remotePort;
+            }
+            // if we're just now initializing a connection to the remote,
+            // inspect the url property
+            else {
+              var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
+              if (!result) {
+                throw new Error('WebSocket URL must be in the format ws(s)://address:port');
+              }
+              addr = result[1];
+              port = parseInt(result[2], 10);
+            }
+          } else {
+            // create the actual websocket object and connect
+            try {
+              // runtimeConfig gets set to true if WebSocket runtime configuration is available.
+              var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
+
+              // The default value is 'ws://' the replace is needed because the compiler replaces "//" comments with '#'
+              // comments without checking context, so we'd end up with ws:#, the replace swaps the "#" for "//" again.
+              var url = 'ws:#'.replace('#', '//');
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['url']) {
+                  url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
+                }
+              }
+
+              if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
+                url = url + addr + ':' + port;
+              }
+
+              // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
+              var subProtocols = 'binary'; // The default value is 'binary'
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['subprotocol']) {
+                  subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
+                }
+              }
+
+              // The regex trims the string (removes spaces at the beginning and end, then splits the string by
+              // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
+              subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
+
+              // The node ws library API for specifying optional subprotocol is slightly different than the browser's.
+              var opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols;
+
+              // If node we use the ws library.
+              var WebSocket = ENVIRONMENT_IS_NODE ? require('ws') : window['WebSocket'];
+              ws = new WebSocket(url, opts);
+              ws.binaryType = 'arraybuffer';
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH);
+            }
+          }
+
+
+          var peer = {
+            addr: addr,
+            port: port,
+            socket: ws,
+            dgram_send_queue: []
+          };
+
+          SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+          SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
+
+          // if this is a bound dgram socket, send the port number first to allow
+          // us to override the ephemeral port reported to us by remotePort on the
+          // remote end.
+          if (sock.type === 2 && typeof sock.sport !== 'undefined') {
+            peer.dgram_send_queue.push(new Uint8Array([
+                255, 255, 255, 255,
+                'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
+                ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
+            ]));
+          }
+
+          return peer;
+        },getPeer:function (sock, addr, port) {
+          return sock.peers[addr + ':' + port];
+        },addPeer:function (sock, peer) {
+          sock.peers[peer.addr + ':' + peer.port] = peer;
+        },removePeer:function (sock, peer) {
+          delete sock.peers[peer.addr + ':' + peer.port];
+        },handlePeerEvents:function (sock, peer) {
+          var first = true;
+
+          var handleOpen = function () {
+            try {
+              var queued = peer.dgram_send_queue.shift();
+              while (queued) {
+                peer.socket.send(queued);
+                queued = peer.dgram_send_queue.shift();
+              }
+            } catch (e) {
+              // not much we can do here in the way of proper error handling as we've already
+              // lied and said this data was sent. shut it down.
+              peer.socket.close();
+            }
+          };
+
+          function handleMessage(data) {
+            assert(typeof data !== 'string' && data.byteLength !== undefined);  // must receive an ArrayBuffer
+            data = new Uint8Array(data);  // make a typed array view on the array buffer
+
+
+            // if this is the port message, override the peer's port with it
+            var wasfirst = first;
+            first = false;
+            if (wasfirst &&
+                data.length === 10 &&
+                data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
+                data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
+              // update the peer's port and it's key in the peer map
+              var newport = ((data[8] << 8) | data[9]);
+              SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+              peer.port = newport;
+              SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+              return;
+            }
+
+            sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
+          };
+
+          if (ENVIRONMENT_IS_NODE) {
+            peer.socket.on('open', handleOpen);
+            peer.socket.on('message', function(data, flags) {
+              if (!flags.binary) {
+                return;
+              }
+              handleMessage((new Uint8Array(data)).buffer);  // copy from node Buffer -> ArrayBuffer
+            });
+            peer.socket.on('error', function() {
+              // don't throw
+            });
+          } else {
+            peer.socket.onopen = handleOpen;
+            peer.socket.onmessage = function peer_socket_onmessage(event) {
+              handleMessage(event.data);
+            };
+          }
+        },poll:function (sock) {
+          if (sock.type === 1 && sock.server) {
+            // listen sockets should only say they're available for reading
+            // if there are pending clients.
+            return sock.pending.length ? (64 | 1) : 0;
+          }
+
+          var mask = 0;
+          var dest = sock.type === 1 ?  // we only care about the socket state for connection-based sockets
+            SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
+            null;
+
+          if (sock.recv_queue.length ||
+              !dest ||  // connection-less sockets are always ready to read
+              (dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {  // let recv return 0 once closed
+            mask |= (64 | 1);
+          }
+
+          if (!dest ||  // connection-less sockets are always ready to write
+              (dest && dest.socket.readyState === dest.socket.OPEN)) {
+            mask |= 4;
+          }
+
+          if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {
+            mask |= 16;
+          }
+
+          return mask;
+        },ioctl:function (sock, request, arg) {
+          switch (request) {
+            case 21531:
+              var bytes = 0;
+              if (sock.recv_queue.length) {
+                bytes = sock.recv_queue[0].data.length;
+              }
+              HEAP32[((arg)>>2)]=bytes;
+              return 0;
+            default:
+              return ERRNO_CODES.EINVAL;
+          }
+        },close:function (sock) {
+          // if we've spawned a listen server, close it
+          if (sock.server) {
+            try {
+              sock.server.close();
+            } catch (e) {
+            }
+            sock.server = null;
+          }
+          // close any peer connections
+          var peers = Object.keys(sock.peers);
+          for (var i = 0; i < peers.length; i++) {
+            var peer = sock.peers[peers[i]];
+            try {
+              peer.socket.close();
+            } catch (e) {
+            }
+            SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+          }
+          return 0;
+        },bind:function (sock, addr, port) {
+          if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already bound
+          }
+          sock.saddr = addr;
+          sock.sport = port || _mkport();
+          // in order to emulate dgram sockets, we need to launch a listen server when
+          // binding on a connection-less socket
+          // note: this is only required on the server side
+          if (sock.type === 2) {
+            // close the existing server if it exists
+            if (sock.server) {
+              sock.server.close();
+              sock.server = null;
+            }
+            // swallow error operation not supported error that occurs when binding in the
+            // browser where this isn't supported
+            try {
+              sock.sock_ops.listen(sock, 0);
+            } catch (e) {
+              if (!(e instanceof FS.ErrnoError)) throw e;
+              if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e;
+            }
+          }
+        },connect:function (sock, addr, port) {
+          if (sock.server) {
+            throw new FS.ErrnoError(ERRNO_CODS.EOPNOTSUPP);
+          }
+
+          // TODO autobind
+          // if (!sock.addr && sock.type == 2) {
+          // }
+
+          // early out if we're already connected / in the middle of connecting
+          if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') {
+            var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+            if (dest) {
+              if (dest.socket.readyState === dest.socket.CONNECTING) {
+                throw new FS.ErrnoError(ERRNO_CODES.EALREADY);
+              } else {
+                throw new FS.ErrnoError(ERRNO_CODES.EISCONN);
+              }
+            }
+          }
+
+          // add the socket to our peer list and set our
+          // destination address / port to match
+          var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+          sock.daddr = peer.addr;
+          sock.dport = peer.port;
+
+          // always "fail" in non-blocking mode
+          throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS);
+        },listen:function (sock, backlog) {
+          if (!ENVIRONMENT_IS_NODE) {
+            throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+          }
+          if (sock.server) {
+             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already listening
+          }
+          var WebSocketServer = require('ws').Server;
+          var host = sock.saddr;
+          sock.server = new WebSocketServer({
+            host: host,
+            port: sock.sport
+            // TODO support backlog
+          });
+
+          sock.server.on('connection', function(ws) {
+            if (sock.type === 1) {
+              var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
+
+              // create a peer on the new socket
+              var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
+              newsock.daddr = peer.addr;
+              newsock.dport = peer.port;
+
+              // push to queue for accept to pick up
+              sock.pending.push(newsock);
+            } else {
+              // create a peer on the listen socket so calling sendto
+              // with the listen socket and an address will resolve
+              // to the correct client
+              SOCKFS.websocket_sock_ops.createPeer(sock, ws);
+            }
+          });
+          sock.server.on('closed', function() {
+            sock.server = null;
+          });
+          sock.server.on('error', function() {
+            // don't throw
+          });
+        },accept:function (listensock) {
+          if (!listensock.server) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          var newsock = listensock.pending.shift();
+          newsock.stream.flags = listensock.stream.flags;
+          return newsock;
+        },getname:function (sock, peer) {
+          var addr, port;
+          if (peer) {
+            if (sock.daddr === undefined || sock.dport === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            }
+            addr = sock.daddr;
+            port = sock.dport;
+          } else {
+            // TODO saddr and sport will be set for bind()'d UDP sockets, but what
+            // should we be returning for TCP sockets that've been connect()'d?
+            addr = sock.saddr || 0;
+            port = sock.sport || 0;
+          }
+          return { addr: addr, port: port };
+        },sendmsg:function (sock, buffer, offset, length, addr, port) {
+          if (sock.type === 2) {
+            // connection-less sockets will honor the message address,
+            // and otherwise fall back to the bound destination address
+            if (addr === undefined || port === undefined) {
+              addr = sock.daddr;
+              port = sock.dport;
+            }
+            // if there was no address to fall back to, error out
+            if (addr === undefined || port === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ);
+            }
+          } else {
+            // connection-based sockets will only use the bound
+            addr = sock.daddr;
+            port = sock.dport;
+          }
+
+          // find the peer for the destination address
+          var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
+
+          // early out if not connected with a connection-based socket
+          if (sock.type === 1) {
+            if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            } else if (dest.socket.readyState === dest.socket.CONNECTING) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // create a copy of the incoming data to send, as the WebSocket API
+          // doesn't work entirely with an ArrayBufferView, it'll just send
+          // the entire underlying buffer
+          var data;
+          if (buffer instanceof Array || buffer instanceof ArrayBuffer) {
+            data = buffer.slice(offset, offset + length);
+          } else {  // ArrayBufferView
+            data = buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + length);
+          }
+
+          // if we're emulating a connection-less dgram socket and don't have
+          // a cached connection, queue the buffer to send upon connect and
+          // lie, saying the data was sent now.
+          if (sock.type === 2) {
+            if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
+              // if we're not connected, open a new connection
+              if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+              }
+              dest.dgram_send_queue.push(data);
+              return length;
+            }
+          }
+
+          try {
+            // send the actual data
+            dest.socket.send(data);
+            return length;
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+        },recvmsg:function (sock, length) {
+          // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
+          if (sock.type === 1 && sock.server) {
+            // tcp servers should not be recv()'ing on the listen socket
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+          }
+
+          var queued = sock.recv_queue.shift();
+          if (!queued) {
+            if (sock.type === 1) {
+              var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+
+              if (!dest) {
+                // if we have a destination address but are not connected, error out
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+              }
+              else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                // return null if the socket has closed
+                return null;
+              }
+              else {
+                // else, our socket is in a valid state but truly has nothing available
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+            } else {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
+          // requeued TCP data it'll be an ArrayBufferView
+          var queuedLength = queued.data.byteLength || queued.data.length;
+          var queuedOffset = queued.data.byteOffset || 0;
+          var queuedBuffer = queued.data.buffer || queued.data;
+          var bytesRead = Math.min(length, queuedLength);
+          var res = {
+            buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
+            addr: queued.addr,
+            port: queued.port
+          };
+
+
+          // push back any unread data for TCP connections
+          if (sock.type === 1 && bytesRead < queuedLength) {
+            var bytesRemaining = queuedLength - bytesRead;
+            queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
+            sock.recv_queue.unshift(queued);
+          }
+
+          return res;
+        }}};function _send(fd, buf, len, flags) {
+      var sock = SOCKFS.getSocket(fd);
+      if (!sock) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      // TODO honor flags
+      return _write(fd, buf, len);
+    }
+
+  function _pwrite(fildes, buf, nbyte, offset) {
+      // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte, offset);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _write(fildes, buf, nbyte) {
+      // ssize_t write(int fildes, const void *buf, size_t nbyte);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+
+
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }
+
+  function _fileno(stream) {
+      // int fileno(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
+      stream = FS.getStreamFromPtr(stream);
+      if (!stream) return -1;
+      return stream.fd;
+    }function _fwrite(ptr, size, nitems, stream) {
+      // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
+      var bytesToWrite = nitems * size;
+      if (bytesToWrite == 0) return 0;
+      var fd = _fileno(stream);
+      var bytesWritten = _write(fd, ptr, bytesToWrite);
+      if (bytesWritten == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return 0;
+      } else {
+        return Math.floor(bytesWritten / size);
+      }
+    }
+
+
+
+  Module["_strlen"] = _strlen;
+
+  function __reallyNegative(x) {
+      return x < 0 || (x === 0 && (1/x) === -Infinity);
+    }function __formatString(format, varargs) {
+      var textIndex = format;
+      var argIndex = 0;
+      function getNextArg(type) {
+        // NOTE: Explicitly ignoring type safety. Otherwise this fails:
+        //       int x = 4; printf("%c\n", (char)x);
+        var ret;
+        if (type === 'double') {
+          ret = HEAPF64[(((varargs)+(argIndex))>>3)];
+        } else if (type == 'i64') {
+          ret = [HEAP32[(((varargs)+(argIndex))>>2)],
+                 HEAP32[(((varargs)+(argIndex+4))>>2)]];
+
+        } else {
+          type = 'i32'; // varargs are always i32, i64, or double
+          ret = HEAP32[(((varargs)+(argIndex))>>2)];
+        }
+        argIndex += Runtime.getNativeFieldSize(type);
+        return ret;
+      }
+
+      var ret = [];
+      var curr, next, currArg;
+      while(1) {
+        var startTextIndex = textIndex;
+        curr = HEAP8[(textIndex)];
+        if (curr === 0) break;
+        next = HEAP8[((textIndex+1)|0)];
+        if (curr == 37) {
+          // Handle flags.
+          var flagAlwaysSigned = false;
+          var flagLeftAlign = false;
+          var flagAlternative = false;
+          var flagZeroPad = false;
+          var flagPadSign = false;
+          flagsLoop: while (1) {
+            switch (next) {
+              case 43:
+                flagAlwaysSigned = true;
+                break;
+              case 45:
+                flagLeftAlign = true;
+                break;
+              case 35:
+                flagAlternative = true;
+                break;
+              case 48:
+                if (flagZeroPad) {
+                  break flagsLoop;
+                } else {
+                  flagZeroPad = true;
+                  break;
+                }
+              case 32:
+                flagPadSign = true;
+                break;
+              default:
+                break flagsLoop;
+            }
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          }
+
+          // Handle width.
+          var width = 0;
+          if (next == 42) {
+            width = getNextArg('i32');
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          } else {
+            while (next >= 48 && next <= 57) {
+              width = width * 10 + (next - 48);
+              textIndex++;
+              next = HEAP8[((textIndex+1)|0)];
+            }
+          }
+
+          // Handle precision.
+          var precisionSet = false, precision = -1;
+          if (next == 46) {
+            precision = 0;
+            precisionSet = true;
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+            if (next == 42) {
+              precision = getNextArg('i32');
+              textIndex++;
+            } else {
+              while(1) {
+                var precisionChr = HEAP8[((textIndex+1)|0)];
+                if (precisionChr < 48 ||
+                    precisionChr > 57) break;
+                precision = precision * 10 + (precisionChr - 48);
+                textIndex++;
+              }
+            }
+            next = HEAP8[((textIndex+1)|0)];
+          }
+          if (precision < 0) {
+            precision = 6; // Standard default.
+            precisionSet = false;
+          }
+
+          // Handle integer sizes. WARNING: These assume a 32-bit architecture!
+          var argSize;
+          switch (String.fromCharCode(next)) {
+            case 'h':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 104) {
+                textIndex++;
+                argSize = 1; // char (actually i32 in varargs)
+              } else {
+                argSize = 2; // short (actually i32 in varargs)
+              }
+              break;
+            case 'l':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 108) {
+                textIndex++;
+                argSize = 8; // long long
+              } else {
+                argSize = 4; // long
+              }
+              break;
+            case 'L': // long long
+            case 'q': // int64_t
+            case 'j': // intmax_t
+              argSize = 8;
+              break;
+            case 'z': // size_t
+            case 't': // ptrdiff_t
+            case 'I': // signed ptrdiff_t or unsigned size_t
+              argSize = 4;
+              break;
+            default:
+              argSize = null;
+          }
+          if (argSize) textIndex++;
+          next = HEAP8[((textIndex+1)|0)];
+
+          // Handle type specifier.
+          switch (String.fromCharCode(next)) {
+            case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': {
+              // Integer.
+              var signed = next == 100 || next == 105;
+              argSize = argSize || 4;
+              var currArg = getNextArg('i' + (argSize * 8));
+              var argText;
+              // Flatten i64-1 [low, high] into a (slightly rounded) double
+              if (argSize == 8) {
+                currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117);
+              }
+              // Truncate to requested size.
+              if (argSize <= 4) {
+                var limit = Math.pow(256, argSize) - 1;
+                currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
+              }
+              // Format the number.
+              var currAbsArg = Math.abs(currArg);
+              var prefix = '';
+              if (next == 100 || next == 105) {
+                argText = reSign(currArg, 8 * argSize, 1).toString(10);
+              } else if (next == 117) {
+                argText = unSign(currArg, 8 * argSize, 1).toString(10);
+                currArg = Math.abs(currArg);
+              } else if (next == 111) {
+                argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
+              } else if (next == 120 || next == 88) {
+                prefix = (flagAlternative && currArg != 0) ? '0x' : '';
+                if (currArg < 0) {
+                  // Represent negative numbers in hex as 2's complement.
+                  currArg = -currArg;
+                  argText = (currAbsArg - 1).toString(16);
+                  var buffer = [];
+                  for (var i = 0; i < argText.length; i++) {
+                    buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
+                  }
+                  argText = buffer.join('');
+                  while (argText.length < argSize * 2) argText = 'f' + argText;
+                } else {
+                  argText = currAbsArg.toString(16);
+                }
+                if (next == 88) {
+                  prefix = prefix.toUpperCase();
+                  argText = argText.toUpperCase();
+                }
+              } else if (next == 112) {
+                if (currAbsArg === 0) {
+                  argText = '(nil)';
+                } else {
+                  prefix = '0x';
+                  argText = currAbsArg.toString(16);
+                }
+              }
+              if (precisionSet) {
+                while (argText.length < precision) {
+                  argText = '0' + argText;
+                }
+              }
+
+              // Add sign if needed
+              if (currArg >= 0) {
+                if (flagAlwaysSigned) {
+                  prefix = '+' + prefix;
+                } else if (flagPadSign) {
+                  prefix = ' ' + prefix;
+                }
+              }
+
+              // Move sign to prefix so we zero-pad after the sign
+              if (argText.charAt(0) == '-') {
+                prefix = '-' + prefix;
+                argText = argText.substr(1);
+              }
+
+              // Add padding.
+              while (prefix.length + argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad) {
+                    argText = '0' + argText;
+                  } else {
+                    prefix = ' ' + prefix;
+                  }
+                }
+              }
+
+              // Insert the result into the buffer.
+              argText = prefix + argText;
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': {
+              // Float.
+              var currArg = getNextArg('double');
+              var argText;
+              if (isNaN(currArg)) {
+                argText = 'nan';
+                flagZeroPad = false;
+              } else if (!isFinite(currArg)) {
+                argText = (currArg < 0 ? '-' : '') + 'inf';
+                flagZeroPad = false;
+              } else {
+                var isGeneral = false;
+                var effectivePrecision = Math.min(precision, 20);
+
+                // Convert g/G to f/F or e/E, as per:
+                // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
+                if (next == 103 || next == 71) {
+                  isGeneral = true;
+                  precision = precision || 1;
+                  var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
+                  if (precision > exponent && exponent >= -4) {
+                    next = ((next == 103) ? 'f' : 'F').charCodeAt(0);
+                    precision -= exponent + 1;
+                  } else {
+                    next = ((next == 103) ? 'e' : 'E').charCodeAt(0);
+                    precision--;
+                  }
+                  effectivePrecision = Math.min(precision, 20);
+                }
+
+                if (next == 101 || next == 69) {
+                  argText = currArg.toExponential(effectivePrecision);
+                  // Make sure the exponent has at least 2 digits.
+                  if (/[eE][-+]\d$/.test(argText)) {
+                    argText = argText.slice(0, -1) + '0' + argText.slice(-1);
+                  }
+                } else if (next == 102 || next == 70) {
+                  argText = currArg.toFixed(effectivePrecision);
+                  if (currArg === 0 && __reallyNegative(currArg)) {
+                    argText = '-' + argText;
+                  }
+                }
+
+                var parts = argText.split('e');
+                if (isGeneral && !flagAlternative) {
+                  // Discard trailing zeros and periods.
+                  while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
+                         (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
+                    parts[0] = parts[0].slice(0, -1);
+                  }
+                } else {
+                  // Make sure we have a period in alternative mode.
+                  if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
+                  // Zero pad until required precision.
+                  while (precision > effectivePrecision++) parts[0] += '0';
+                }
+                argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
+
+                // Capitalize 'E' if needed.
+                if (next == 69) argText = argText.toUpperCase();
+
+                // Add sign.
+                if (currArg >= 0) {
+                  if (flagAlwaysSigned) {
+                    argText = '+' + argText;
+                  } else if (flagPadSign) {
+                    argText = ' ' + argText;
+                  }
+                }
+              }
+
+              // Add padding.
+              while (argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
+                    argText = argText[0] + '0' + argText.slice(1);
+                  } else {
+                    argText = (flagZeroPad ? '0' : ' ') + argText;
+                  }
+                }
+              }
+
+              // Adjust case.
+              if (next < 97) argText = argText.toUpperCase();
+
+              // Insert the result into the buffer.
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 's': {
+              // String.
+              var arg = getNextArg('i8*');
+              var argLength = arg ? _strlen(arg) : '(null)'.length;
+              if (precisionSet) argLength = Math.min(argLength, precision);
+              if (!flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              if (arg) {
+                for (var i = 0; i < argLength; i++) {
+                  ret.push(HEAPU8[((arg++)|0)]);
+                }
+              } else {
+                ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true));
+              }
+              if (flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              break;
+            }
+            case 'c': {
+              // Character.
+              if (flagLeftAlign) ret.push(getNextArg('i8'));
+              while (--width > 0) {
+                ret.push(32);
+              }
+              if (!flagLeftAlign) ret.push(getNextArg('i8'));
+              break;
+            }
+            case 'n': {
+              // Write the length written so far to the next parameter.
+              var ptr = getNextArg('i32*');
+              HEAP32[((ptr)>>2)]=ret.length;
+              break;
+            }
+            case '%': {
+              // Literal percent sign.
+              ret.push(curr);
+              break;
+            }
+            default: {
+              // Unknown specifiers remain untouched.
+              for (var i = startTextIndex; i < textIndex + 2; i++) {
+                ret.push(HEAP8[(i)]);
+              }
+            }
+          }
+          textIndex += 2;
+          // TODO: Support a/A (hex float) and m (last error) specifiers.
+          // TODO: Support %1${specifier} for arg selection.
+        } else {
+          ret.push(curr);
+          textIndex += 1;
+        }
+      }
+      return ret;
+    }function _fprintf(stream, format, varargs) {
+      // int fprintf(FILE *restrict stream, const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var result = __formatString(format, varargs);
+      var stack = Runtime.stackSave();
+      var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream);
+      Runtime.stackRestore(stack);
+      return ret;
+    }function _printf(format, varargs) {
+      // int printf(const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var stdout = HEAP32[((_stdout)>>2)];
+      return _fprintf(stdout, format, varargs);
+    }
+
+
+  Module["_memset"] = _memset;
+
+
+
+  function _emscripten_memcpy_big(dest, src, num) {
+      HEAPU8.set(HEAPU8.subarray(src, src+num), dest);
+      return dest;
+    }
+  Module["_memcpy"] = _memcpy;
+
+  function _free() {
+  }
+  Module["_free"] = _free;
+Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };
+  Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
+  Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
+  Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
+  Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
+  Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }
+FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice;
+___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0;
+__ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor();
+if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); }
+__ATINIT__.push({ func: function() { SOCKFS.root = FS.mount(SOCKFS, {}, null); } });
+STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);
+
+staticSealed = true; // seal the static portion of memory
+
+STACK_MAX = STACK_BASE + 5242880;
+
+DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);
+
+assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");
+
+
+var Math_min = Math.min;
+function asmPrintInt(x, y) {
+  Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+function asmPrintFloat(x, y) {
+  Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+// EMSCRIPTEN_START_ASM
+var asm = (function(global, env, buffer) {
+  'use asm';
+  var HEAP8 = new global.Int8Array(buffer);
+  var HEAP16 = new global.Int16Array(buffer);
+  var HEAP32 = new global.Int32Array(buffer);
+  var HEAPU8 = new global.Uint8Array(buffer);
+  var HEAPU16 = new global.Uint16Array(buffer);
+  var HEAPU32 = new global.Uint32Array(buffer);
+  var HEAPF32 = new global.Float32Array(buffer);
+  var HEAPF64 = new global.Float64Array(buffer);
+
+  var STACKTOP=env.STACKTOP|0;
+  var STACK_MAX=env.STACK_MAX|0;
+  var tempDoublePtr=env.tempDoublePtr|0;
+  var ABORT=env.ABORT|0;
+
+  var __THREW__ = 0;
+  var threwValue = 0;
+  var setjmpId = 0;
+  var undef = 0;
+  var nan = +env.NaN, inf = +env.Infinity;
+  var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
+
+  var tempRet0 = 0;
+  var tempRet1 = 0;
+  var tempRet2 = 0;
+  var tempRet3 = 0;
+  var tempRet4 = 0;
+  var tempRet5 = 0;
+  var tempRet6 = 0;
+  var tempRet7 = 0;
+  var tempRet8 = 0;
+  var tempRet9 = 0;
+  var Math_floor=global.Math.floor;
+  var Math_abs=global.Math.abs;
+  var Math_sqrt=global.Math.sqrt;
+  var Math_pow=global.Math.pow;
+  var Math_cos=global.Math.cos;
+  var Math_sin=global.Math.sin;
+  var Math_tan=global.Math.tan;
+  var Math_acos=global.Math.acos;
+  var Math_asin=global.Math.asin;
+  var Math_atan=global.Math.atan;
+  var Math_atan2=global.Math.atan2;
+  var Math_exp=global.Math.exp;
+  var Math_log=global.Math.log;
+  var Math_ceil=global.Math.ceil;
+  var Math_imul=global.Math.imul;
+  var abort=env.abort;
+  var assert=env.assert;
+  var asmPrintInt=env.asmPrintInt;
+  var asmPrintFloat=env.asmPrintFloat;
+  var Math_min=env.min;
+  var _free=env._free;
+  var _emscripten_memcpy_big=env._emscripten_memcpy_big;
+  var _printf=env._printf;
+  var _send=env._send;
+  var _pwrite=env._pwrite;
+  var __reallyNegative=env.__reallyNegative;
+  var _fwrite=env._fwrite;
+  var _malloc=env._malloc;
+  var _mkport=env._mkport;
+  var _fprintf=env._fprintf;
+  var ___setErrNo=env.___setErrNo;
+  var __formatString=env.__formatString;
+  var _fileno=env._fileno;
+  var _fflush=env._fflush;
+  var _write=env._write;
+  var tempFloat = 0.0;
+
+// EMSCRIPTEN_START_FUNCS
+function _main(i3, i5) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i1;
+ L1 : do {
+  if ((i3 | 0) > 1) {
+   i3 = HEAP8[HEAP32[i5 + 4 >> 2] | 0] | 0;
+   switch (i3 | 0) {
+   case 50:
+    {
+     i3 = 3500;
+     break L1;
+    }
+   case 51:
+    {
+     i4 = 4;
+     break L1;
+    }
+   case 52:
+    {
+     i3 = 35e3;
+     break L1;
+    }
+   case 53:
+    {
+     i3 = 7e4;
+     break L1;
+    }
+   case 49:
+    {
+     i3 = 550;
+     break L1;
+    }
+   case 48:
+    {
+     i11 = 0;
+     STACKTOP = i1;
+     return i11 | 0;
+    }
+   default:
+    {
+     HEAP32[i2 >> 2] = i3 + -48;
+     _printf(8, i2 | 0) | 0;
+     i11 = -1;
+     STACKTOP = i1;
+     return i11 | 0;
+    }
+   }
+  } else {
+   i4 = 4;
+  }
+ } while (0);
+ if ((i4 | 0) == 4) {
+  i3 = 7e3;
+ }
+ i11 = 0;
+ i8 = 0;
+ i5 = 0;
+ while (1) {
+  i6 = ((i5 | 0) % 5 | 0) + 1 | 0;
+  i4 = ((i5 | 0) % 3 | 0) + 1 | 0;
+  i7 = 0;
+  while (1) {
+   i11 = ((i7 | 0) / (i6 | 0) | 0) + i11 | 0;
+   if (i11 >>> 0 > 1e3) {
+    i11 = (i11 >>> 0) / (i4 >>> 0) | 0;
+   }
+   if ((i7 & 3 | 0) == 0) {
+    i11 = i11 + (Math_imul((i7 & 7 | 0) == 0 ? 1 : -1, i7) | 0) | 0;
+   }
+   i10 = i11 << 16 >> 16;
+   i10 = (Math_imul(i10, i10) | 0) & 255;
+   i9 = i10 + (i8 & 65535) | 0;
+   i7 = i7 + 1 | 0;
+   if ((i7 | 0) == 2e4) {
+    break;
+   } else {
+    i8 = i9;
+   }
+  }
+  i5 = i5 + 1 | 0;
+  if ((i5 | 0) < (i3 | 0)) {
+   i8 = i9;
+  } else {
+   break;
+  }
+ }
+ HEAP32[i2 >> 2] = i11;
+ HEAP32[i2 + 4 >> 2] = i8 + i10 & 65535;
+ _printf(24, i2 | 0) | 0;
+ i11 = 0;
+ STACKTOP = i1;
+ return i11 | 0;
+}
+function _memcpy(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ if ((i1 | 0) >= 4096) return _emscripten_memcpy_big(i3 | 0, i2 | 0, i1 | 0) | 0;
+ i4 = i3 | 0;
+ if ((i3 & 3) == (i2 & 3)) {
+  while (i3 & 3) {
+   if ((i1 | 0) == 0) return i4 | 0;
+   HEAP8[i3] = HEAP8[i2] | 0;
+   i3 = i3 + 1 | 0;
+   i2 = i2 + 1 | 0;
+   i1 = i1 - 1 | 0;
+  }
+  while ((i1 | 0) >= 4) {
+   HEAP32[i3 >> 2] = HEAP32[i2 >> 2];
+   i3 = i3 + 4 | 0;
+   i2 = i2 + 4 | 0;
+   i1 = i1 - 4 | 0;
+  }
+ }
+ while ((i1 | 0) > 0) {
+  HEAP8[i3] = HEAP8[i2] | 0;
+  i3 = i3 + 1 | 0;
+  i2 = i2 + 1 | 0;
+  i1 = i1 - 1 | 0;
+ }
+ return i4 | 0;
+}
+function _memset(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = i1 + i3 | 0;
+ if ((i3 | 0) >= 20) {
+  i4 = i4 & 255;
+  i7 = i1 & 3;
+  i6 = i4 | i4 << 8 | i4 << 16 | i4 << 24;
+  i5 = i2 & ~3;
+  if (i7) {
+   i7 = i1 + 4 - i7 | 0;
+   while ((i1 | 0) < (i7 | 0)) {
+    HEAP8[i1] = i4;
+    i1 = i1 + 1 | 0;
+   }
+  }
+  while ((i1 | 0) < (i5 | 0)) {
+   HEAP32[i1 >> 2] = i6;
+   i1 = i1 + 4 | 0;
+  }
+ }
+ while ((i1 | 0) < (i2 | 0)) {
+  HEAP8[i1] = i4;
+  i1 = i1 + 1 | 0;
+ }
+ return i1 - i3 | 0;
+}
+function copyTempDouble(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+ HEAP8[tempDoublePtr + 4 | 0] = HEAP8[i1 + 4 | 0];
+ HEAP8[tempDoublePtr + 5 | 0] = HEAP8[i1 + 5 | 0];
+ HEAP8[tempDoublePtr + 6 | 0] = HEAP8[i1 + 6 | 0];
+ HEAP8[tempDoublePtr + 7 | 0] = HEAP8[i1 + 7 | 0];
+}
+function copyTempFloat(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+}
+function runPostSets() {}
+function _strlen(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = i1;
+ while (HEAP8[i2] | 0) {
+  i2 = i2 + 1 | 0;
+ }
+ return i2 - i1 | 0;
+}
+function stackAlloc(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + i1 | 0;
+ STACKTOP = STACKTOP + 7 & -8;
+ return i2 | 0;
+}
+function setThrew(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ if ((__THREW__ | 0) == 0) {
+  __THREW__ = i1;
+  threwValue = i2;
+ }
+}
+function stackRestore(i1) {
+ i1 = i1 | 0;
+ STACKTOP = i1;
+}
+function setTempRet9(i1) {
+ i1 = i1 | 0;
+ tempRet9 = i1;
+}
+function setTempRet8(i1) {
+ i1 = i1 | 0;
+ tempRet8 = i1;
+}
+function setTempRet7(i1) {
+ i1 = i1 | 0;
+ tempRet7 = i1;
+}
+function setTempRet6(i1) {
+ i1 = i1 | 0;
+ tempRet6 = i1;
+}
+function setTempRet5(i1) {
+ i1 = i1 | 0;
+ tempRet5 = i1;
+}
+function setTempRet4(i1) {
+ i1 = i1 | 0;
+ tempRet4 = i1;
+}
+function setTempRet3(i1) {
+ i1 = i1 | 0;
+ tempRet3 = i1;
+}
+function setTempRet2(i1) {
+ i1 = i1 | 0;
+ tempRet2 = i1;
+}
+function setTempRet1(i1) {
+ i1 = i1 | 0;
+ tempRet1 = i1;
+}
+function setTempRet0(i1) {
+ i1 = i1 | 0;
+ tempRet0 = i1;
+}
+function stackSave() {
+ return STACKTOP | 0;
+}
+
+// EMSCRIPTEN_END_FUNCS
+
+
+  return { _strlen: _strlen, _memcpy: _memcpy, _main: _main, _memset: _memset, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, setTempRet1: setTempRet1, setTempRet2: setTempRet2, setTempRet3: setTempRet3, setTempRet4: setTempRet4, setTempRet5: setTempRet5, setTempRet6: setTempRet6, setTempRet7: setTempRet7, setTempRet8: setTempRet8, setTempRet9: setTempRet9 };
+})
+// EMSCRIPTEN_END_ASM
+({ "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array }, { "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "_free": _free, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_printf": _printf, "_send": _send, "_pwrite": _pwrite, "__reallyNegative": __reallyNegative, "_fwrite": _fwrite, "_malloc": _malloc, "_mkport": _mkport, "_fprintf": _fprintf, "___setErrNo": ___setErrNo, "__formatString": __formatString, "_fileno": _fileno, "_fflush": _fflush, "_write": _write, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "NaN": NaN, "Infinity": Infinity }, buffer);
+var _strlen = Module["_strlen"] = asm["_strlen"];
+var _memcpy = Module["_memcpy"] = asm["_memcpy"];
+var _main = Module["_main"] = asm["_main"];
+var _memset = Module["_memset"] = asm["_memset"];
+var runPostSets = Module["runPostSets"] = asm["runPostSets"];
+
+Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
+Runtime.stackSave = function() { return asm['stackSave']() };
+Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
+
+
+// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included
+var i64Math = null;
+
+// === Auto-generated postamble setup entry stuff ===
+
+if (memoryInitializer) {
+  if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
+    var data = Module['readBinary'](memoryInitializer);
+    HEAPU8.set(data, STATIC_BASE);
+  } else {
+    addRunDependency('memory initializer');
+    Browser.asyncLoad(memoryInitializer, function(data) {
+      HEAPU8.set(data, STATIC_BASE);
+      removeRunDependency('memory initializer');
+    }, function(data) {
+      throw 'could not load memory initializer ' + memoryInitializer;
+    });
+  }
+}
+
+function ExitStatus(status) {
+  this.name = "ExitStatus";
+  this.message = "Program terminated with exit(" + status + ")";
+  this.status = status;
+};
+ExitStatus.prototype = new Error();
+ExitStatus.prototype.constructor = ExitStatus;
+
+var initialStackTop;
+var preloadStartTime = null;
+var calledMain = false;
+
+dependenciesFulfilled = function runCaller() {
+  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
+  if (!Module['calledRun'] && shouldRunNow) run([].concat(Module["arguments"]));
+  if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
+}
+
+Module['callMain'] = Module.callMain = function callMain(args) {
+  assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
+  assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
+
+  args = args || [];
+
+  ensureInitRuntime();
+
+  var argc = args.length+1;
+  function pad() {
+    for (var i = 0; i < 4-1; i++) {
+      argv.push(0);
+    }
+  }
+  var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ];
+  pad();
+  for (var i = 0; i < argc-1; i = i + 1) {
+    argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL));
+    pad();
+  }
+  argv.push(0);
+  argv = allocate(argv, 'i32', ALLOC_NORMAL);
+
+  initialStackTop = STACKTOP;
+
+  try {
+
+    var ret = Module['_main'](argc, argv, 0);
+
+
+    // if we're not running an evented main loop, it's time to exit
+    if (!Module['noExitRuntime']) {
+      exit(ret);
+    }
+  }
+  catch(e) {
+    if (e instanceof ExitStatus) {
+      // exit() throws this once it's done to make sure execution
+      // has been stopped completely
+      return;
+    } else if (e == 'SimulateInfiniteLoop') {
+      // running an evented main loop, don't immediately exit
+      Module['noExitRuntime'] = true;
+      return;
+    } else {
+      if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
+      throw e;
+    }
+  } finally {
+    calledMain = true;
+  }
+}
+
+
+
+
+function run(args) {
+  args = args || Module['arguments'];
+
+  if (preloadStartTime === null) preloadStartTime = Date.now();
+
+  if (runDependencies > 0) {
+    Module.printErr('run() called, but dependencies remain, so not running');
+    return;
+  }
+
+  preRun();
+
+  if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
+  if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
+
+  function doRun() {
+    if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
+    Module['calledRun'] = true;
+
+    ensureInitRuntime();
+
+    preMain();
+
+    if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
+      Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
+    }
+
+    if (Module['_main'] && shouldRunNow) {
+      Module['callMain'](args);
+    }
+
+    postRun();
+  }
+
+  if (Module['setStatus']) {
+    Module['setStatus']('Running...');
+    setTimeout(function() {
+      setTimeout(function() {
+        Module['setStatus']('');
+      }, 1);
+      if (!ABORT) doRun();
+    }, 1);
+  } else {
+    doRun();
+  }
+}
+Module['run'] = Module.run = run;
+
+function exit(status) {
+  ABORT = true;
+  EXITSTATUS = status;
+  STACKTOP = initialStackTop;
+
+  // exit the runtime
+  exitRuntime();
+
+  // TODO We should handle this differently based on environment.
+  // In the browser, the best we can do is throw an exception
+  // to halt execution, but in node we could process.exit and
+  // I'd imagine SM shell would have something equivalent.
+  // This would let us set a proper exit status (which
+  // would be great for checking test exit statuses).
+  // https://github.com/kripken/emscripten/issues/1371
+
+  // throw an exception to halt the current execution
+  throw new ExitStatus(status);
+}
+Module['exit'] = Module.exit = exit;
+
+function abort(text) {
+  if (text) {
+    Module.print(text);
+    Module.printErr(text);
+  }
+
+  ABORT = true;
+  EXITSTATUS = 1;
+
+  var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.';
+
+  throw 'abort() at ' + stackTrace() + extra;
+}
+Module['abort'] = Module.abort = abort;
+
+// {{PRE_RUN_ADDITIONS}}
+
+if (Module['preInit']) {
+  if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
+  while (Module['preInit'].length > 0) {
+    Module['preInit'].pop()();
+  }
+}
+
+// shouldRunNow refers to calling main(), not run().
+var shouldRunNow = true;
+if (Module['noInitialRun']) {
+  shouldRunNow = false;
+}
+
+
+run([].concat(Module["arguments"]));
diff --git a/test/mjsunit/asm/embenchen/fannkuch.js b/test/mjsunit/asm/embenchen/fannkuch.js
new file mode 100644
index 0000000..64bd491
--- /dev/null
+++ b/test/mjsunit/asm/embenchen/fannkuch.js
@@ -0,0 +1,8435 @@
+var EXPECTED_OUTPUT =
+  '123456789\n' +
+  '213456789\n' +
+  '231456789\n' +
+  '321456789\n' +
+  '312456789\n' +
+  '132456789\n' +
+  '234156789\n' +
+  '324156789\n' +
+  '342156789\n' +
+  '432156789\n' +
+  '423156789\n' +
+  '243156789\n' +
+  '341256789\n' +
+  '431256789\n' +
+  '413256789\n' +
+  '143256789\n' +
+  '134256789\n' +
+  '314256789\n' +
+  '412356789\n' +
+  '142356789\n' +
+  '124356789\n' +
+  '214356789\n' +
+  '241356789\n' +
+  '421356789\n' +
+  '234516789\n' +
+  '324516789\n' +
+  '342516789\n' +
+  '432516789\n' +
+  '423516789\n' +
+  '243516789\n' +
+  'Pfannkuchen(9) = 30.\n';
+var Module = {
+  arguments: [1],
+  print: function(x) {Module.printBuffer += x + '\n';},
+  preRun: [function() {Module.printBuffer = ''}],
+  postRun: [function() {
+    assertEquals(EXPECTED_OUTPUT, Module.printBuffer);
+  }],
+};
+// The Module object: Our interface to the outside world. We import
+// and export values on it, and do the work to get that through
+// closure compiler if necessary. There are various ways Module can be used:
+// 1. Not defined. We create it here
+// 2. A function parameter, function(Module) { ..generated code.. }
+// 3. pre-run appended it, var Module = {}; ..generated code..
+// 4. External script tag defines var Module.
+// We need to do an eval in order to handle the closure compiler
+// case, where this code here is minified but Module was defined
+// elsewhere (e.g. case 4 above). We also need to check if Module
+// already exists (e.g. case 3 above).
+// Note that if you want to run closure, and also to use Module
+// after the generated code, you will need to define   var Module = {};
+// before the code. Then that object will be used in the code, and you
+// can continue to use Module afterwards as well.
+var Module;
+if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {};
+
+// Sometimes an existing Module object exists with properties
+// meant to overwrite the default module functionality. Here
+// we collect those properties and reapply _after_ we configure
+// the current environment's defaults to avoid having to be so
+// defensive during initialization.
+var moduleOverrides = {};
+for (var key in Module) {
+  if (Module.hasOwnProperty(key)) {
+    moduleOverrides[key] = Module[key];
+  }
+}
+
+// The environment setup code below is customized to use Module.
+// *** Environment setup code ***
+var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
+var ENVIRONMENT_IS_WEB = typeof window === 'object';
+var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
+var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
+
+if (ENVIRONMENT_IS_NODE) {
+  // Expose functionality in the same simple way that the shells work
+  // Note that we pollute the global namespace here, otherwise we break in node
+  if (!Module['print']) Module['print'] = function print(x) {
+    process['stdout'].write(x + '\n');
+  };
+  if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+    process['stderr'].write(x + '\n');
+  };
+
+  var nodeFS = require('fs');
+  var nodePath = require('path');
+
+  Module['read'] = function read(filename, binary) {
+    filename = nodePath['normalize'](filename);
+    var ret = nodeFS['readFileSync'](filename);
+    // The path is absolute if the normalized version is the same as the resolved.
+    if (!ret && filename != nodePath['resolve'](filename)) {
+      filename = path.join(__dirname, '..', 'src', filename);
+      ret = nodeFS['readFileSync'](filename);
+    }
+    if (ret && !binary) ret = ret.toString();
+    return ret;
+  };
+
+  Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) };
+
+  Module['load'] = function load(f) {
+    globalEval(read(f));
+  };
+
+  Module['arguments'] = process['argv'].slice(2);
+
+  module['exports'] = Module;
+}
+else if (ENVIRONMENT_IS_SHELL) {
+  if (!Module['print']) Module['print'] = print;
+  if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
+
+  if (typeof read != 'undefined') {
+    Module['read'] = read;
+  } else {
+    Module['read'] = function read() { throw 'no read() available (jsc?)' };
+  }
+
+  Module['readBinary'] = function readBinary(f) {
+    return read(f, 'binary');
+  };
+
+  if (typeof scriptArgs != 'undefined') {
+    Module['arguments'] = scriptArgs;
+  } else if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  this['Module'] = Module;
+
+  eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly)
+}
+else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+  Module['read'] = function read(url) {
+    var xhr = new XMLHttpRequest();
+    xhr.open('GET', url, false);
+    xhr.send(null);
+    return xhr.responseText;
+  };
+
+  if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  if (typeof console !== 'undefined') {
+    if (!Module['print']) Module['print'] = function print(x) {
+      console.log(x);
+    };
+    if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+      console.log(x);
+    };
+  } else {
+    // Probably a worker, and without console.log. We can do very little here...
+    var TRY_USE_DUMP = false;
+    if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
+      dump(x);
+    }) : (function(x) {
+      // self.postMessage(x); // enable this if you want stdout to be sent as messages
+    }));
+  }
+
+  if (ENVIRONMENT_IS_WEB) {
+    window['Module'] = Module;
+  } else {
+    Module['load'] = importScripts;
+  }
+}
+else {
+  // Unreachable because SHELL is dependant on the others
+  throw 'Unknown runtime environment. Where are we?';
+}
+
+function globalEval(x) {
+  eval.call(null, x);
+}
+if (!Module['load'] == 'undefined' && Module['read']) {
+  Module['load'] = function load(f) {
+    globalEval(Module['read'](f));
+  };
+}
+if (!Module['print']) {
+  Module['print'] = function(){};
+}
+if (!Module['printErr']) {
+  Module['printErr'] = Module['print'];
+}
+if (!Module['arguments']) {
+  Module['arguments'] = [];
+}
+// *** Environment setup code ***
+
+// Closure helpers
+Module.print = Module['print'];
+Module.printErr = Module['printErr'];
+
+// Callbacks
+Module['preRun'] = [];
+Module['postRun'] = [];
+
+// Merge back in the overrides
+for (var key in moduleOverrides) {
+  if (moduleOverrides.hasOwnProperty(key)) {
+    Module[key] = moduleOverrides[key];
+  }
+}
+
+
+
+// === Auto-generated preamble library stuff ===
+
+//========================================
+// Runtime code shared with compiler
+//========================================
+
+var Runtime = {
+  stackSave: function () {
+    return STACKTOP;
+  },
+  stackRestore: function (stackTop) {
+    STACKTOP = stackTop;
+  },
+  forceAlign: function (target, quantum) {
+    quantum = quantum || 4;
+    if (quantum == 1) return target;
+    if (isNumber(target) && isNumber(quantum)) {
+      return Math.ceil(target/quantum)*quantum;
+    } else if (isNumber(quantum) && isPowerOfTwo(quantum)) {
+      return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')';
+    }
+    return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
+  },
+  isNumberType: function (type) {
+    return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
+  },
+  isPointerType: function isPointerType(type) {
+  return type[type.length-1] == '*';
+},
+  isStructType: function isStructType(type) {
+  if (isPointerType(type)) return false;
+  if (isArrayType(type)) return true;
+  if (/<?\{ ?[^}]* ?\}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types
+  // See comment in isStructPointerType()
+  return type[0] == '%';
+},
+  INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
+  FLOAT_TYPES: {"float":0,"double":0},
+  or64: function (x, y) {
+    var l = (x | 0) | (y | 0);
+    var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  and64: function (x, y) {
+    var l = (x | 0) & (y | 0);
+    var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  xor64: function (x, y) {
+    var l = (x | 0) ^ (y | 0);
+    var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  getNativeTypeSize: function (type) {
+    switch (type) {
+      case 'i1': case 'i8': return 1;
+      case 'i16': return 2;
+      case 'i32': return 4;
+      case 'i64': return 8;
+      case 'float': return 4;
+      case 'double': return 8;
+      default: {
+        if (type[type.length-1] === '*') {
+          return Runtime.QUANTUM_SIZE; // A pointer
+        } else if (type[0] === 'i') {
+          var bits = parseInt(type.substr(1));
+          assert(bits % 8 === 0);
+          return bits/8;
+        } else {
+          return 0;
+        }
+      }
+    }
+  },
+  getNativeFieldSize: function (type) {
+    return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE);
+  },
+  dedup: function dedup(items, ident) {
+  var seen = {};
+  if (ident) {
+    return items.filter(function(item) {
+      if (seen[item[ident]]) return false;
+      seen[item[ident]] = true;
+      return true;
+    });
+  } else {
+    return items.filter(function(item) {
+      if (seen[item]) return false;
+      seen[item] = true;
+      return true;
+    });
+  }
+},
+  set: function set() {
+  var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
+  var ret = {};
+  for (var i = 0; i < args.length; i++) {
+    ret[args[i]] = 0;
+  }
+  return ret;
+},
+  STACK_ALIGN: 8,
+  getAlignSize: function (type, size, vararg) {
+    // we align i64s and doubles on 64-bit boundaries, unlike x86
+    if (!vararg && (type == 'i64' || type == 'double')) return 8;
+    if (!type) return Math.min(size, 8); // align structures internally to 64 bits
+    return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE);
+  },
+  calculateStructAlignment: function calculateStructAlignment(type) {
+    type.flatSize = 0;
+    type.alignSize = 0;
+    var diffs = [];
+    var prev = -1;
+    var index = 0;
+    type.flatIndexes = type.fields.map(function(field) {
+      index++;
+      var size, alignSize;
+      if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
+        size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
+        alignSize = Runtime.getAlignSize(field, size);
+      } else if (Runtime.isStructType(field)) {
+        if (field[1] === '0') {
+          // this is [0 x something]. When inside another structure like here, it must be at the end,
+          // and it adds no size
+          // XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!');
+          size = 0;
+          if (Types.types[field]) {
+            alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+          } else {
+            alignSize = type.alignSize || QUANTUM_SIZE;
+          }
+        } else {
+          size = Types.types[field].flatSize;
+          alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+        }
+      } else if (field[0] == 'b') {
+        // bN, large number field, like a [N x i8]
+        size = field.substr(1)|0;
+        alignSize = 1;
+      } else if (field[0] === '<') {
+        // vector type
+        size = alignSize = Types.types[field].flatSize; // fully aligned
+      } else if (field[0] === 'i') {
+        // illegal integer field, that could not be legalized because it is an internal structure field
+        // it is ok to have such fields, if we just use them as markers of field size and nothing more complex
+        size = alignSize = parseInt(field.substr(1))/8;
+        assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field);
+      } else {
+        assert(false, 'invalid type for calculateStructAlignment');
+      }
+      if (type.packed) alignSize = 1;
+      type.alignSize = Math.max(type.alignSize, alignSize);
+      var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
+      type.flatSize = curr + size;
+      if (prev >= 0) {
+        diffs.push(curr-prev);
+      }
+      prev = curr;
+      return curr;
+    });
+    if (type.name_ && type.name_[0] === '[') {
+      // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
+      // allocating a potentially huge array for [999999 x i8] etc.
+      type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
+    }
+    type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
+    if (diffs.length == 0) {
+      type.flatFactor = type.flatSize;
+    } else if (Runtime.dedup(diffs).length == 1) {
+      type.flatFactor = diffs[0];
+    }
+    type.needsFlattening = (type.flatFactor != 1);
+    return type.flatIndexes;
+  },
+  generateStructInfo: function (struct, typeName, offset) {
+    var type, alignment;
+    if (typeName) {
+      offset = offset || 0;
+      type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
+      if (!type) return null;
+      if (type.fields.length != struct.length) {
+        printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo');
+        return null;
+      }
+      alignment = type.flatIndexes;
+    } else {
+      var type = { fields: struct.map(function(item) { return item[0] }) };
+      alignment = Runtime.calculateStructAlignment(type);
+    }
+    var ret = {
+      __size__: type.flatSize
+    };
+    if (typeName) {
+      struct.forEach(function(item, i) {
+        if (typeof item === 'string') {
+          ret[item] = alignment[i] + offset;
+        } else {
+          // embedded struct
+          var key;
+          for (var k in item) key = k;
+          ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
+        }
+      });
+    } else {
+      struct.forEach(function(item, i) {
+        ret[item[1]] = alignment[i];
+      });
+    }
+    return ret;
+  },
+  dynCall: function (sig, ptr, args) {
+    if (args && args.length) {
+      if (!args.splice) args = Array.prototype.slice.call(args);
+      args.splice(0, 0, ptr);
+      return Module['dynCall_' + sig].apply(null, args);
+    } else {
+      return Module['dynCall_' + sig].call(null, ptr);
+    }
+  },
+  functionPointers: [],
+  addFunction: function (func) {
+    for (var i = 0; i < Runtime.functionPointers.length; i++) {
+      if (!Runtime.functionPointers[i]) {
+        Runtime.functionPointers[i] = func;
+        return 2*(1 + i);
+      }
+    }
+    throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
+  },
+  removeFunction: function (index) {
+    Runtime.functionPointers[(index-2)/2] = null;
+  },
+  getAsmConst: function (code, numArgs) {
+    // code is a constant string on the heap, so we can cache these
+    if (!Runtime.asmConstCache) Runtime.asmConstCache = {};
+    var func = Runtime.asmConstCache[code];
+    if (func) return func;
+    var args = [];
+    for (var i = 0; i < numArgs; i++) {
+      args.push(String.fromCharCode(36) + i); // $0, $1 etc
+    }
+    var source = Pointer_stringify(code);
+    if (source[0] === '"') {
+      // tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct
+      if (source.indexOf('"', 1) === source.length-1) {
+        source = source.substr(1, source.length-2);
+      } else {
+        // something invalid happened, e.g. EM_ASM("..code($0)..", input)
+        abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)');
+      }
+    }
+    try {
+      var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node
+    } catch(e) {
+      Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)');
+      throw e;
+    }
+    return Runtime.asmConstCache[code] = evalled;
+  },
+  warnOnce: function (text) {
+    if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
+    if (!Runtime.warnOnce.shown[text]) {
+      Runtime.warnOnce.shown[text] = 1;
+      Module.printErr(text);
+    }
+  },
+  funcWrappers: {},
+  getFuncWrapper: function (func, sig) {
+    assert(sig);
+    if (!Runtime.funcWrappers[func]) {
+      Runtime.funcWrappers[func] = function dynCall_wrapper() {
+        return Runtime.dynCall(sig, func, arguments);
+      };
+    }
+    return Runtime.funcWrappers[func];
+  },
+  UTF8Processor: function () {
+    var buffer = [];
+    var needed = 0;
+    this.processCChar = function (code) {
+      code = code & 0xFF;
+
+      if (buffer.length == 0) {
+        if ((code & 0x80) == 0x00) {        // 0xxxxxxx
+          return String.fromCharCode(code);
+        }
+        buffer.push(code);
+        if ((code & 0xE0) == 0xC0) {        // 110xxxxx
+          needed = 1;
+        } else if ((code & 0xF0) == 0xE0) { // 1110xxxx
+          needed = 2;
+        } else {                            // 11110xxx
+          needed = 3;
+        }
+        return '';
+      }
+
+      if (needed) {
+        buffer.push(code);
+        needed--;
+        if (needed > 0) return '';
+      }
+
+      var c1 = buffer[0];
+      var c2 = buffer[1];
+      var c3 = buffer[2];
+      var c4 = buffer[3];
+      var ret;
+      if (buffer.length == 2) {
+        ret = String.fromCharCode(((c1 & 0x1F) << 6)  | (c2 & 0x3F));
+      } else if (buffer.length == 3) {
+        ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6)  | (c3 & 0x3F));
+      } else {
+        // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+        var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
+                        ((c3 & 0x3F) << 6)  | (c4 & 0x3F);
+        ret = String.fromCharCode(
+          Math.floor((codePoint - 0x10000) / 0x400) + 0xD800,
+          (codePoint - 0x10000) % 0x400 + 0xDC00);
+      }
+      buffer.length = 0;
+      return ret;
+    }
+    this.processJSString = function processJSString(string) {
+      /* TODO: use TextEncoder when present,
+        var encoder = new TextEncoder();
+        encoder['encoding'] = "utf-8";
+        var utf8Array = encoder['encode'](aMsg.data);
+      */
+      string = unescape(encodeURIComponent(string));
+      var ret = [];
+      for (var i = 0; i < string.length; i++) {
+        ret.push(string.charCodeAt(i));
+      }
+      return ret;
+    }
+  },
+  getCompilerSetting: function (name) {
+    throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work';
+  },
+  stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+7)&-8); return ret; },
+  staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = (((STATICTOP)+7)&-8); return ret; },
+  dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = (((DYNAMICTOP)+7)&-8); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; },
+  alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; },
+  makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*(+4294967296))) : ((+((low>>>0)))+((+((high|0)))*(+4294967296)))); return ret; },
+  GLOBAL_BASE: 8,
+  QUANTUM_SIZE: 4,
+  __dummy__: 0
+}
+
+
+Module['Runtime'] = Runtime;
+
+
+
+
+
+
+
+
+
+//========================================
+// Runtime essentials
+//========================================
+
+var __THREW__ = 0; // Used in checking for thrown exceptions.
+
+var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort()
+var EXITSTATUS = 0;
+
+var undef = 0;
+// tempInt is used for 32-bit signed values or smaller. tempBigInt is used
+// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt
+var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat;
+var tempI64, tempI64b;
+var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9;
+
+function assert(condition, text) {
+  if (!condition) {
+    abort('Assertion failed: ' + text);
+  }
+}
+
+var globalScope = this;
+
+// C calling interface. A convenient way to call C functions (in C files, or
+// defined with extern "C").
+//
+// Note: LLVM optimizations can inline and remove functions, after which you will not be
+//       able to call them. Closure can also do so. To avoid that, add your function to
+//       the exports using something like
+//
+//         -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]'
+//
+// @param ident      The name of the C function (note that C++ functions will be name-mangled - use extern "C")
+// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and
+//                   'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit).
+// @param argTypes   An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType,
+//                   except that 'array' is not possible (there is no way for us to know the length of the array)
+// @param args       An array of the arguments to the function, as native JS values (as in returnType)
+//                   Note that string arguments will be stored on the stack (the JS string will become a C string on the stack).
+// @return           The return value, as a native JS value (as in returnType)
+function ccall(ident, returnType, argTypes, args) {
+  return ccallFunc(getCFunc(ident), returnType, argTypes, args);
+}
+Module["ccall"] = ccall;
+
+// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
+function getCFunc(ident) {
+  try {
+    var func = Module['_' + ident]; // closure exported function
+    if (!func) func = eval('_' + ident); // explicit lookup
+  } catch(e) {
+  }
+  assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)');
+  return func;
+}
+
+// Internal function that does a C call using a function, not an identifier
+function ccallFunc(func, returnType, argTypes, args) {
+  var stack = 0;
+  function toC(value, type) {
+    if (type == 'string') {
+      if (value === null || value === undefined || value === 0) return 0; // null string
+      value = intArrayFromString(value);
+      type = 'array';
+    }
+    if (type == 'array') {
+      if (!stack) stack = Runtime.stackSave();
+      var ret = Runtime.stackAlloc(value.length);
+      writeArrayToMemory(value, ret);
+      return ret;
+    }
+    return value;
+  }
+  function fromC(value, type) {
+    if (type == 'string') {
+      return Pointer_stringify(value);
+    }
+    assert(type != 'array');
+    return value;
+  }
+  var i = 0;
+  var cArgs = args ? args.map(function(arg) {
+    return toC(arg, argTypes[i++]);
+  }) : [];
+  var ret = fromC(func.apply(null, cArgs), returnType);
+  if (stack) Runtime.stackRestore(stack);
+  return ret;
+}
+
+// Returns a native JS wrapper for a C function. This is similar to ccall, but
+// returns a function you can call repeatedly in a normal way. For example:
+//
+//   var my_function = cwrap('my_c_function', 'number', ['number', 'number']);
+//   alert(my_function(5, 22));
+//   alert(my_function(99, 12));
+//
+function cwrap(ident, returnType, argTypes) {
+  var func = getCFunc(ident);
+  return function() {
+    return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments));
+  }
+}
+Module["cwrap"] = cwrap;
+
+// Sets a value in memory in a dynamic way at run-time. Uses the
+// type data. This is the same as makeSetValue, except that
+// makeSetValue is done at compile-time and generates the needed
+// code then, whereas this function picks the right code at
+// run-time.
+// Note that setValue and getValue only do *aligned* writes and reads!
+// Note that ccall uses JS types as for defining types, while setValue and
+// getValue need LLVM types ('i8', 'i32') - this is a lower-level operation
+function setValue(ptr, value, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': HEAP8[(ptr)]=value; break;
+      case 'i8': HEAP8[(ptr)]=value; break;
+      case 'i16': HEAP16[((ptr)>>1)]=value; break;
+      case 'i32': HEAP32[((ptr)>>2)]=value; break;
+      case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= (+1) ? (tempDouble > (+0) ? ((Math_min((+(Math_floor((tempDouble)/(+4294967296)))), (+4294967295)))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/(+4294967296))))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
+      case 'float': HEAPF32[((ptr)>>2)]=value; break;
+      case 'double': HEAPF64[((ptr)>>3)]=value; break;
+      default: abort('invalid type for setValue: ' + type);
+    }
+}
+Module['setValue'] = setValue;
+
+// Parallel to setValue.
+function getValue(ptr, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': return HEAP8[(ptr)];
+      case 'i8': return HEAP8[(ptr)];
+      case 'i16': return HEAP16[((ptr)>>1)];
+      case 'i32': return HEAP32[((ptr)>>2)];
+      case 'i64': return HEAP32[((ptr)>>2)];
+      case 'float': return HEAPF32[((ptr)>>2)];
+      case 'double': return HEAPF64[((ptr)>>3)];
+      default: abort('invalid type for setValue: ' + type);
+    }
+  return null;
+}
+Module['getValue'] = getValue;
+
+var ALLOC_NORMAL = 0; // Tries to use _malloc()
+var ALLOC_STACK = 1; // Lives for the duration of the current function call
+var ALLOC_STATIC = 2; // Cannot be freed
+var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
+var ALLOC_NONE = 4; // Do not allocate
+Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
+Module['ALLOC_STACK'] = ALLOC_STACK;
+Module['ALLOC_STATIC'] = ALLOC_STATIC;
+Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
+Module['ALLOC_NONE'] = ALLOC_NONE;
+
+// allocate(): This is for internal use. You can use it yourself as well, but the interface
+//             is a little tricky (see docs right below). The reason is that it is optimized
+//             for multiple syntaxes to save space in generated code. So you should
+//             normally not use allocate(), and instead allocate memory using _malloc(),
+//             initialize it with setValue(), and so forth.
+// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
+//        in *bytes* (note that this is sometimes confusing: the next parameter does not
+//        affect this!)
+// @types: Either an array of types, one for each byte (or 0 if no type at that position),
+//         or a single type which is used for the entire block. This only matters if there
+//         is initial data - if @slab is a number, then this does not matter at all and is
+//         ignored.
+// @allocator: How to allocate memory, see ALLOC_*
+function allocate(slab, types, allocator, ptr) {
+  var zeroinit, size;
+  if (typeof slab === 'number') {
+    zeroinit = true;
+    size = slab;
+  } else {
+    zeroinit = false;
+    size = slab.length;
+  }
+
+  var singleType = typeof types === 'string' ? types : null;
+
+  var ret;
+  if (allocator == ALLOC_NONE) {
+    ret = ptr;
+  } else {
+    ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
+  }
+
+  if (zeroinit) {
+    var ptr = ret, stop;
+    assert((ret & 3) == 0);
+    stop = ret + (size & ~3);
+    for (; ptr < stop; ptr += 4) {
+      HEAP32[((ptr)>>2)]=0;
+    }
+    stop = ret + size;
+    while (ptr < stop) {
+      HEAP8[((ptr++)|0)]=0;
+    }
+    return ret;
+  }
+
+  if (singleType === 'i8') {
+    if (slab.subarray || slab.slice) {
+      HEAPU8.set(slab, ret);
+    } else {
+      HEAPU8.set(new Uint8Array(slab), ret);
+    }
+    return ret;
+  }
+
+  var i = 0, type, typeSize, previousType;
+  while (i < size) {
+    var curr = slab[i];
+
+    if (typeof curr === 'function') {
+      curr = Runtime.getFunctionIndex(curr);
+    }
+
+    type = singleType || types[i];
+    if (type === 0) {
+      i++;
+      continue;
+    }
+
+    if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
+
+    setValue(ret+i, curr, type);
+
+    // no need to look up size unless type changes, so cache it
+    if (previousType !== type) {
+      typeSize = Runtime.getNativeTypeSize(type);
+      previousType = type;
+    }
+    i += typeSize;
+  }
+
+  return ret;
+}
+Module['allocate'] = allocate;
+
+function Pointer_stringify(ptr, /* optional */ length) {
+  // TODO: use TextDecoder
+  // Find the length, and check for UTF while doing so
+  var hasUtf = false;
+  var t;
+  var i = 0;
+  while (1) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    if (t >= 128) hasUtf = true;
+    else if (t == 0 && !length) break;
+    i++;
+    if (length && i == length) break;
+  }
+  if (!length) length = i;
+
+  var ret = '';
+
+  if (!hasUtf) {
+    var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack
+    var curr;
+    while (length > 0) {
+      curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
+      ret = ret ? ret + curr : curr;
+      ptr += MAX_CHUNK;
+      length -= MAX_CHUNK;
+    }
+    return ret;
+  }
+
+  var utf8 = new Runtime.UTF8Processor();
+  for (i = 0; i < length; i++) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    ret += utf8.processCChar(t);
+  }
+  return ret;
+}
+Module['Pointer_stringify'] = Pointer_stringify;
+
+// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF16ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
+    if (codeUnit == 0)
+      return str;
+    ++i;
+    // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
+    str += String.fromCharCode(codeUnit);
+  }
+}
+Module['UTF16ToString'] = UTF16ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF16LE form. The copy will require at most (str.length*2+1)*2 bytes of space in the HEAP.
+function stringToUTF16(str, outPtr) {
+  for(var i = 0; i < str.length; ++i) {
+    // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
+    var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
+    HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP16[(((outPtr)+(str.length*2))>>1)]=0;
+}
+Module['stringToUTF16'] = stringToUTF16;
+
+// Given a pointer 'ptr' to a null-terminated UTF32LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF32ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
+    if (utf32 == 0)
+      return str;
+    ++i;
+    // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
+    if (utf32 >= 0x10000) {
+      var ch = utf32 - 0x10000;
+      str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
+    } else {
+      str += String.fromCharCode(utf32);
+    }
+  }
+}
+Module['UTF32ToString'] = UTF32ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF32LE form. The copy will require at most (str.length+1)*4 bytes of space in the HEAP,
+// but can use less, since str.length does not return the number of characters in the string, but the number of UTF-16 code units in the string.
+function stringToUTF32(str, outPtr) {
+  var iChar = 0;
+  for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) {
+    // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
+    var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate
+    if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
+      var trailSurrogate = str.charCodeAt(++iCodeUnit);
+      codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
+    }
+    HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit;
+    ++iChar;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP32[(((outPtr)+(iChar*4))>>2)]=0;
+}
+Module['stringToUTF32'] = stringToUTF32;
+
+function demangle(func) {
+  var i = 3;
+  // params, etc.
+  var basicTypes = {
+    'v': 'void',
+    'b': 'bool',
+    'c': 'char',
+    's': 'short',
+    'i': 'int',
+    'l': 'long',
+    'f': 'float',
+    'd': 'double',
+    'w': 'wchar_t',
+    'a': 'signed char',
+    'h': 'unsigned char',
+    't': 'unsigned short',
+    'j': 'unsigned int',
+    'm': 'unsigned long',
+    'x': 'long long',
+    'y': 'unsigned long long',
+    'z': '...'
+  };
+  var subs = [];
+  var first = true;
+  function dump(x) {
+    //return;
+    if (x) Module.print(x);
+    Module.print(func);
+    var pre = '';
+    for (var a = 0; a < i; a++) pre += ' ';
+    Module.print (pre + '^');
+  }
+  function parseNested() {
+    i++;
+    if (func[i] === 'K') i++; // ignore const
+    var parts = [];
+    while (func[i] !== 'E') {
+      if (func[i] === 'S') { // substitution
+        i++;
+        var next = func.indexOf('_', i);
+        var num = func.substring(i, next) || 0;
+        parts.push(subs[num] || '?');
+        i = next+1;
+        continue;
+      }
+      if (func[i] === 'C') { // constructor
+        parts.push(parts[parts.length-1]);
+        i += 2;
+        continue;
+      }
+      var size = parseInt(func.substr(i));
+      var pre = size.toString().length;
+      if (!size || !pre) { i--; break; } // counter i++ below us
+      var curr = func.substr(i + pre, size);
+      parts.push(curr);
+      subs.push(curr);
+      i += pre + size;
+    }
+    i++; // skip E
+    return parts;
+  }
+  function parse(rawList, limit, allowVoid) { // main parser
+    limit = limit || Infinity;
+    var ret = '', list = [];
+    function flushList() {
+      return '(' + list.join(', ') + ')';
+    }
+    var name;
+    if (func[i] === 'N') {
+      // namespaced N-E
+      name = parseNested().join('::');
+      limit--;
+      if (limit === 0) return rawList ? [name] : name;
+    } else {
+      // not namespaced
+      if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L'
+      var size = parseInt(func.substr(i));
+      if (size) {
+        var pre = size.toString().length;
+        name = func.substr(i + pre, size);
+        i += pre + size;
+      }
+    }
+    first = false;
+    if (func[i] === 'I') {
+      i++;
+      var iList = parse(true);
+      var iRet = parse(true, 1, true);
+      ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>';
+    } else {
+      ret = name;
+    }
+    paramLoop: while (i < func.length && limit-- > 0) {
+      //dump('paramLoop');
+      var c = func[i++];
+      if (c in basicTypes) {
+        list.push(basicTypes[c]);
+      } else {
+        switch (c) {
+          case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer
+          case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference
+          case 'L': { // literal
+            i++; // skip basic type
+            var end = func.indexOf('E', i);
+            var size = end - i;
+            list.push(func.substr(i, size));
+            i += size + 2; // size + 'EE'
+            break;
+          }
+          case 'A': { // array
+            var size = parseInt(func.substr(i));
+            i += size.toString().length;
+            if (func[i] !== '_') throw '?';
+            i++; // skip _
+            list.push(parse(true, 1, true)[0] + ' [' + size + ']');
+            break;
+          }
+          case 'E': break paramLoop;
+          default: ret += '?' + c; break paramLoop;
+        }
+      }
+    }
+    if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void)
+    if (rawList) {
+      if (ret) {
+        list.push(ret + '?');
+      }
+      return list;
+    } else {
+      return ret + flushList();
+    }
+  }
+  try {
+    // Special-case the entry point, since its name differs from other name mangling.
+    if (func == 'Object._main' || func == '_main') {
+      return 'main()';
+    }
+    if (typeof func === 'number') func = Pointer_stringify(func);
+    if (func[0] !== '_') return func;
+    if (func[1] !== '_') return func; // C function
+    if (func[2] !== 'Z') return func;
+    switch (func[3]) {
+      case 'n': return 'operator new()';
+      case 'd': return 'operator delete()';
+    }
+    return parse();
+  } catch(e) {
+    return func;
+  }
+}
+
+function demangleAll(text) {
+  return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') });
+}
+
+function stackTrace() {
+  var stack = new Error().stack;
+  return stack ? demangleAll(stack) : '(no stack trace available)'; // Stack trace is not available at least on IE10 and Safari 6.
+}
+
+// Memory management
+
+var PAGE_SIZE = 4096;
+function alignMemoryPage(x) {
+  return (x+4095)&-4096;
+}
+
+var HEAP;
+var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
+
+var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area
+var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area
+var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk
+
+function enlargeMemory() {
+  abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
+}
+
+var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880;
+var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 134217728;
+var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152;
+
+var totalMemory = 4096;
+while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) {
+  if (totalMemory < 16*1024*1024) {
+    totalMemory *= 2;
+  } else {
+    totalMemory += 16*1024*1024
+  }
+}
+if (totalMemory !== TOTAL_MEMORY) {
+  Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be more reasonable');
+  TOTAL_MEMORY = totalMemory;
+}
+
+// Initialize the runtime's memory
+// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
+assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
+       'JS engine does not provide full typed array support');
+
+var buffer = new ArrayBuffer(TOTAL_MEMORY);
+HEAP8 = new Int8Array(buffer);
+HEAP16 = new Int16Array(buffer);
+HEAP32 = new Int32Array(buffer);
+HEAPU8 = new Uint8Array(buffer);
+HEAPU16 = new Uint16Array(buffer);
+HEAPU32 = new Uint32Array(buffer);
+HEAPF32 = new Float32Array(buffer);
+HEAPF64 = new Float64Array(buffer);
+
+// Endianness check (note: assumes compiler arch was little-endian)
+HEAP32[0] = 255;
+assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
+
+Module['HEAP'] = HEAP;
+Module['HEAP8'] = HEAP8;
+Module['HEAP16'] = HEAP16;
+Module['HEAP32'] = HEAP32;
+Module['HEAPU8'] = HEAPU8;
+Module['HEAPU16'] = HEAPU16;
+Module['HEAPU32'] = HEAPU32;
+Module['HEAPF32'] = HEAPF32;
+Module['HEAPF64'] = HEAPF64;
+
+function callRuntimeCallbacks(callbacks) {
+  while(callbacks.length > 0) {
+    var callback = callbacks.shift();
+    if (typeof callback == 'function') {
+      callback();
+      continue;
+    }
+    var func = callback.func;
+    if (typeof func === 'number') {
+      if (callback.arg === undefined) {
+        Runtime.dynCall('v', func);
+      } else {
+        Runtime.dynCall('vi', func, [callback.arg]);
+      }
+    } else {
+      func(callback.arg === undefined ? null : callback.arg);
+    }
+  }
+}
+
+var __ATPRERUN__  = []; // functions called before the runtime is initialized
+var __ATINIT__    = []; // functions called during startup
+var __ATMAIN__    = []; // functions called when main() is to be run
+var __ATEXIT__    = []; // functions called during shutdown
+var __ATPOSTRUN__ = []; // functions called after the runtime has exited
+
+var runtimeInitialized = false;
+
+function preRun() {
+  // compatibility - merge in anything from Module['preRun'] at this time
+  if (Module['preRun']) {
+    if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
+    while (Module['preRun'].length) {
+      addOnPreRun(Module['preRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPRERUN__);
+}
+
+function ensureInitRuntime() {
+  if (runtimeInitialized) return;
+  runtimeInitialized = true;
+  callRuntimeCallbacks(__ATINIT__);
+}
+
+function preMain() {
+  callRuntimeCallbacks(__ATMAIN__);
+}
+
+function exitRuntime() {
+  callRuntimeCallbacks(__ATEXIT__);
+}
+
+function postRun() {
+  // compatibility - merge in anything from Module['postRun'] at this time
+  if (Module['postRun']) {
+    if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
+    while (Module['postRun'].length) {
+      addOnPostRun(Module['postRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPOSTRUN__);
+}
+
+function addOnPreRun(cb) {
+  __ATPRERUN__.unshift(cb);
+}
+Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun;
+
+function addOnInit(cb) {
+  __ATINIT__.unshift(cb);
+}
+Module['addOnInit'] = Module.addOnInit = addOnInit;
+
+function addOnPreMain(cb) {
+  __ATMAIN__.unshift(cb);
+}
+Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain;
+
+function addOnExit(cb) {
+  __ATEXIT__.unshift(cb);
+}
+Module['addOnExit'] = Module.addOnExit = addOnExit;
+
+function addOnPostRun(cb) {
+  __ATPOSTRUN__.unshift(cb);
+}
+Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun;
+
+// Tools
+
+// This processes a JS string into a C-line array of numbers, 0-terminated.
+// For LLVM-originating strings, see parser.js:parseLLVMString function
+function intArrayFromString(stringy, dontAddNull, length /* optional */) {
+  var ret = (new Runtime.UTF8Processor()).processJSString(stringy);
+  if (length) {
+    ret.length = length;
+  }
+  if (!dontAddNull) {
+    ret.push(0);
+  }
+  return ret;
+}
+Module['intArrayFromString'] = intArrayFromString;
+
+function intArrayToString(array) {
+  var ret = [];
+  for (var i = 0; i < array.length; i++) {
+    var chr = array[i];
+    if (chr > 0xFF) {
+      chr &= 0xFF;
+    }
+    ret.push(String.fromCharCode(chr));
+  }
+  return ret.join('');
+}
+Module['intArrayToString'] = intArrayToString;
+
+// Write a Javascript array to somewhere in the heap
+function writeStringToMemory(string, buffer, dontAddNull) {
+  var array = intArrayFromString(string, dontAddNull);
+  var i = 0;
+  while (i < array.length) {
+    var chr = array[i];
+    HEAP8[(((buffer)+(i))|0)]=chr;
+    i = i + 1;
+  }
+}
+Module['writeStringToMemory'] = writeStringToMemory;
+
+function writeArrayToMemory(array, buffer) {
+  for (var i = 0; i < array.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=array[i];
+  }
+}
+Module['writeArrayToMemory'] = writeArrayToMemory;
+
+function writeAsciiToMemory(str, buffer, dontAddNull) {
+  for (var i = 0; i < str.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=str.charCodeAt(i);
+  }
+  if (!dontAddNull) HEAP8[(((buffer)+(str.length))|0)]=0;
+}
+Module['writeAsciiToMemory'] = writeAsciiToMemory;
+
+function unSign(value, bits, ignore) {
+  if (value >= 0) {
+    return value;
+  }
+  return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
+                    : Math.pow(2, bits)         + value;
+}
+function reSign(value, bits, ignore) {
+  if (value <= 0) {
+    return value;
+  }
+  var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
+                        : Math.pow(2, bits-1);
+  if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
+                                                       // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
+                                                       // TODO: In i64 mode 1, resign the two parts separately and safely
+    value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
+  }
+  return value;
+}
+
+// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
+if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) {
+  var ah  = a >>> 16;
+  var al = a & 0xffff;
+  var bh  = b >>> 16;
+  var bl = b & 0xffff;
+  return (al*bl + ((ah*bl + al*bh) << 16))|0;
+};
+Math.imul = Math['imul'];
+
+
+var Math_abs = Math.abs;
+var Math_cos = Math.cos;
+var Math_sin = Math.sin;
+var Math_tan = Math.tan;
+var Math_acos = Math.acos;
+var Math_asin = Math.asin;
+var Math_atan = Math.atan;
+var Math_atan2 = Math.atan2;
+var Math_exp = Math.exp;
+var Math_log = Math.log;
+var Math_sqrt = Math.sqrt;
+var Math_ceil = Math.ceil;
+var Math_floor = Math.floor;
+var Math_pow = Math.pow;
+var Math_imul = Math.imul;
+var Math_fround = Math.fround;
+var Math_min = Math.min;
+
+// A counter of dependencies for calling run(). If we need to
+// do asynchronous work before running, increment this and
+// decrement it. Incrementing must happen in a place like
+// PRE_RUN_ADDITIONS (used by emcc to add file preloading).
+// Note that you can add dependencies in preRun, even though
+// it happens right before run - run will be postponed until
+// the dependencies are met.
+var runDependencies = 0;
+var runDependencyWatcher = null;
+var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
+
+function addRunDependency(id) {
+  runDependencies++;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+}
+Module['addRunDependency'] = addRunDependency;
+function removeRunDependency(id) {
+  runDependencies--;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+  if (runDependencies == 0) {
+    if (runDependencyWatcher !== null) {
+      clearInterval(runDependencyWatcher);
+      runDependencyWatcher = null;
+    }
+    if (dependenciesFulfilled) {
+      var callback = dependenciesFulfilled;
+      dependenciesFulfilled = null;
+      callback(); // can add another dependenciesFulfilled
+    }
+  }
+}
+Module['removeRunDependency'] = removeRunDependency;
+
+Module["preloadedImages"] = {}; // maps url to image data
+Module["preloadedAudios"] = {}; // maps url to audio data
+
+
+var memoryInitializer = null;
+
+// === Body ===
+
+
+
+
+
+STATIC_BASE = 8;
+
+STATICTOP = STATIC_BASE + Runtime.alignMemory(547);
+/* global initializers */ __ATINIT__.push();
+
+
+/* memory initializer */ allocate([101,114,114,111,114,58,32,37,100,10,0,0,0,0,0,0,80,102,97,110,110,107,117,99,104,101,110,40,37,100,41,32,61,32,37,100,46,10,0,0,37,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE);
+
+
+
+
+var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);
+
+assert(tempDoublePtr % 8 == 0);
+
+function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+}
+
+function copyTempDouble(ptr) {
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+  HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];
+
+  HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];
+
+  HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];
+
+  HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];
+
+}
+
+
+
+
+
+
+  var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};
+
+  var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can   access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};
+
+
+  var ___errno_state=0;function ___setErrNo(value) {
+      // For convenient setting and returning of errno.
+      HEAP32[((___errno_state)>>2)]=value;
+      return value;
+    }
+
+  var PATH={splitPath:function (filename) {
+        var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+        return splitPathRe.exec(filename).slice(1);
+      },normalizeArray:function (parts, allowAboveRoot) {
+        // if the path tries to go above the root, `up` ends up > 0
+        var up = 0;
+        for (var i = parts.length - 1; i >= 0; i--) {
+          var last = parts[i];
+          if (last === '.') {
+            parts.splice(i, 1);
+          } else if (last === '..') {
+            parts.splice(i, 1);
+            up++;
+          } else if (up) {
+            parts.splice(i, 1);
+            up--;
+          }
+        }
+        // if the path is allowed to go above the root, restore leading ..s
+        if (allowAboveRoot) {
+          for (; up--; up) {
+            parts.unshift('..');
+          }
+        }
+        return parts;
+      },normalize:function (path) {
+        var isAbsolute = path.charAt(0) === '/',
+            trailingSlash = path.substr(-1) === '/';
+        // Normalize the path
+        path = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), !isAbsolute).join('/');
+        if (!path && !isAbsolute) {
+          path = '.';
+        }
+        if (path && trailingSlash) {
+          path += '/';
+        }
+        return (isAbsolute ? '/' : '') + path;
+      },dirname:function (path) {
+        var result = PATH.splitPath(path),
+            root = result[0],
+            dir = result[1];
+        if (!root && !dir) {
+          // No dirname whatsoever
+          return '.';
+        }
+        if (dir) {
+          // It has a dirname, strip trailing slash
+          dir = dir.substr(0, dir.length - 1);
+        }
+        return root + dir;
+      },basename:function (path) {
+        // EMSCRIPTEN return '/'' for '/', not an empty string
+        if (path === '/') return '/';
+        var lastSlash = path.lastIndexOf('/');
+        if (lastSlash === -1) return path;
+        return path.substr(lastSlash+1);
+      },extname:function (path) {
+        return PATH.splitPath(path)[3];
+      },join:function () {
+        var paths = Array.prototype.slice.call(arguments, 0);
+        return PATH.normalize(paths.join('/'));
+      },join2:function (l, r) {
+        return PATH.normalize(l + '/' + r);
+      },resolve:function () {
+        var resolvedPath = '',
+          resolvedAbsolute = false;
+        for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+          var path = (i >= 0) ? arguments[i] : FS.cwd();
+          // Skip empty and invalid entries
+          if (typeof path !== 'string') {
+            throw new TypeError('Arguments to path.resolve must be strings');
+          } else if (!path) {
+            continue;
+          }
+          resolvedPath = path + '/' + resolvedPath;
+          resolvedAbsolute = path.charAt(0) === '/';
+        }
+        // At this point the path should be resolved to a full absolute path, but
+        // handle relative paths to be safe (might happen when process.cwd() fails)
+        resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
+          return !!p;
+        }), !resolvedAbsolute).join('/');
+        return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+      },relative:function (from, to) {
+        from = PATH.resolve(from).substr(1);
+        to = PATH.resolve(to).substr(1);
+        function trim(arr) {
+          var start = 0;
+          for (; start < arr.length; start++) {
+            if (arr[start] !== '') break;
+          }
+          var end = arr.length - 1;
+          for (; end >= 0; end--) {
+            if (arr[end] !== '') break;
+          }
+          if (start > end) return [];
+          return arr.slice(start, end - start + 1);
+        }
+        var fromParts = trim(from.split('/'));
+        var toParts = trim(to.split('/'));
+        var length = Math.min(fromParts.length, toParts.length);
+        var samePartsLength = length;
+        for (var i = 0; i < length; i++) {
+          if (fromParts[i] !== toParts[i]) {
+            samePartsLength = i;
+            break;
+          }
+        }
+        var outputParts = [];
+        for (var i = samePartsLength; i < fromParts.length; i++) {
+          outputParts.push('..');
+        }
+        outputParts = outputParts.concat(toParts.slice(samePartsLength));
+        return outputParts.join('/');
+      }};
+
+  var TTY={ttys:[],init:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // currently, FS.init does not distinguish if process.stdin is a file or TTY
+        //   // device, it always assumes it's a TTY device. because of this, we're forcing
+        //   // process.stdin to UTF8 encoding to at least make stdin reading compatible
+        //   // with text files until FS.init can be refactored.
+        //   process['stdin']['setEncoding']('utf8');
+        // }
+      },shutdown:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
+        //   // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
+        //   // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
+        //   // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
+        //   // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
+        //   process['stdin']['pause']();
+        // }
+      },register:function (dev, ops) {
+        TTY.ttys[dev] = { input: [], output: [], ops: ops };
+        FS.registerDevice(dev, TTY.stream_ops);
+      },stream_ops:{open:function (stream) {
+          var tty = TTY.ttys[stream.node.rdev];
+          if (!tty) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          stream.tty = tty;
+          stream.seekable = false;
+        },close:function (stream) {
+          // flush any pending line data
+          if (stream.tty.output.length) {
+            stream.tty.ops.put_char(stream.tty, 10);
+          }
+        },read:function (stream, buffer, offset, length, pos /* ignored */) {
+          if (!stream.tty || !stream.tty.ops.get_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          var bytesRead = 0;
+          for (var i = 0; i < length; i++) {
+            var result;
+            try {
+              result = stream.tty.ops.get_char(stream.tty);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            if (result === undefined && bytesRead === 0) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+            if (result === null || result === undefined) break;
+            bytesRead++;
+            buffer[offset+i] = result;
+          }
+          if (bytesRead) {
+            stream.node.timestamp = Date.now();
+          }
+          return bytesRead;
+        },write:function (stream, buffer, offset, length, pos) {
+          if (!stream.tty || !stream.tty.ops.put_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          for (var i = 0; i < length; i++) {
+            try {
+              stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+          }
+          if (length) {
+            stream.node.timestamp = Date.now();
+          }
+          return i;
+        }},default_tty_ops:{get_char:function (tty) {
+          if (!tty.input.length) {
+            var result = null;
+            if (ENVIRONMENT_IS_NODE) {
+              result = process['stdin']['read']();
+              if (!result) {
+                if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) {
+                  return null;  // EOF
+                }
+                return undefined;  // no data available
+              }
+            } else if (typeof window != 'undefined' &&
+              typeof window.prompt == 'function') {
+              // Browser.
+              result = window.prompt('Input: ');  // returns null on cancel
+              if (result !== null) {
+                result += '\n';
+              }
+            } else if (typeof readline == 'function') {
+              // Command line.
+              result = readline();
+              if (result !== null) {
+                result += '\n';
+              }
+            }
+            if (!result) {
+              return null;
+            }
+            tty.input = intArrayFromString(result, true);
+          }
+          return tty.input.shift();
+        },put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['print'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }},default_tty1_ops:{put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['printErr'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }}};
+
+  var MEMFS={ops_table:null,CONTENT_OWNING:1,CONTENT_FLEXIBLE:2,CONTENT_FIXED:3,mount:function (mount) {
+        return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
+          // no supported
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (!MEMFS.ops_table) {
+          MEMFS.ops_table = {
+            dir: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                lookup: MEMFS.node_ops.lookup,
+                mknod: MEMFS.node_ops.mknod,
+                rename: MEMFS.node_ops.rename,
+                unlink: MEMFS.node_ops.unlink,
+                rmdir: MEMFS.node_ops.rmdir,
+                readdir: MEMFS.node_ops.readdir,
+                symlink: MEMFS.node_ops.symlink
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek
+              }
+            },
+            file: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek,
+                read: MEMFS.stream_ops.read,
+                write: MEMFS.stream_ops.write,
+                allocate: MEMFS.stream_ops.allocate,
+                mmap: MEMFS.stream_ops.mmap
+              }
+            },
+            link: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                readlink: MEMFS.node_ops.readlink
+              },
+              stream: {}
+            },
+            chrdev: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: FS.chrdev_stream_ops
+            },
+          };
+        }
+        var node = FS.createNode(parent, name, mode, dev);
+        if (FS.isDir(node.mode)) {
+          node.node_ops = MEMFS.ops_table.dir.node;
+          node.stream_ops = MEMFS.ops_table.dir.stream;
+          node.contents = {};
+        } else if (FS.isFile(node.mode)) {
+          node.node_ops = MEMFS.ops_table.file.node;
+          node.stream_ops = MEMFS.ops_table.file.stream;
+          node.contents = [];
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        } else if (FS.isLink(node.mode)) {
+          node.node_ops = MEMFS.ops_table.link.node;
+          node.stream_ops = MEMFS.ops_table.link.stream;
+        } else if (FS.isChrdev(node.mode)) {
+          node.node_ops = MEMFS.ops_table.chrdev.node;
+          node.stream_ops = MEMFS.ops_table.chrdev.stream;
+        }
+        node.timestamp = Date.now();
+        // add the new node to the parent
+        if (parent) {
+          parent.contents[name] = node;
+        }
+        return node;
+      },ensureFlexible:function (node) {
+        if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
+          var contents = node.contents;
+          node.contents = Array.prototype.slice.call(contents);
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        }
+      },node_ops:{getattr:function (node) {
+          var attr = {};
+          // device numbers reuse inode numbers.
+          attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
+          attr.ino = node.id;
+          attr.mode = node.mode;
+          attr.nlink = 1;
+          attr.uid = 0;
+          attr.gid = 0;
+          attr.rdev = node.rdev;
+          if (FS.isDir(node.mode)) {
+            attr.size = 4096;
+          } else if (FS.isFile(node.mode)) {
+            attr.size = node.contents.length;
+          } else if (FS.isLink(node.mode)) {
+            attr.size = node.link.length;
+          } else {
+            attr.size = 0;
+          }
+          attr.atime = new Date(node.timestamp);
+          attr.mtime = new Date(node.timestamp);
+          attr.ctime = new Date(node.timestamp);
+          // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
+          //       but this is not required by the standard.
+          attr.blksize = 4096;
+          attr.blocks = Math.ceil(attr.size / attr.blksize);
+          return attr;
+        },setattr:function (node, attr) {
+          if (attr.mode !== undefined) {
+            node.mode = attr.mode;
+          }
+          if (attr.timestamp !== undefined) {
+            node.timestamp = attr.timestamp;
+          }
+          if (attr.size !== undefined) {
+            MEMFS.ensureFlexible(node);
+            var contents = node.contents;
+            if (attr.size < contents.length) contents.length = attr.size;
+            else while (attr.size > contents.length) contents.push(0);
+          }
+        },lookup:function (parent, name) {
+          throw FS.genericErrors[ERRNO_CODES.ENOENT];
+        },mknod:function (parent, name, mode, dev) {
+          return MEMFS.createNode(parent, name, mode, dev);
+        },rename:function (old_node, new_dir, new_name) {
+          // if we're overwriting a directory at new_name, make sure it's empty.
+          if (FS.isDir(old_node.mode)) {
+            var new_node;
+            try {
+              new_node = FS.lookupNode(new_dir, new_name);
+            } catch (e) {
+            }
+            if (new_node) {
+              for (var i in new_node.contents) {
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+              }
+            }
+          }
+          // do the internal rewiring
+          delete old_node.parent.contents[old_node.name];
+          old_node.name = new_name;
+          new_dir.contents[new_name] = old_node;
+          old_node.parent = new_dir;
+        },unlink:function (parent, name) {
+          delete parent.contents[name];
+        },rmdir:function (parent, name) {
+          var node = FS.lookupNode(parent, name);
+          for (var i in node.contents) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+          }
+          delete parent.contents[name];
+        },readdir:function (node) {
+          var entries = ['.', '..']
+          for (var key in node.contents) {
+            if (!node.contents.hasOwnProperty(key)) {
+              continue;
+            }
+            entries.push(key);
+          }
+          return entries;
+        },symlink:function (parent, newname, oldpath) {
+          var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
+          node.link = oldpath;
+          return node;
+        },readlink:function (node) {
+          if (!FS.isLink(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          return node.link;
+        }},stream_ops:{read:function (stream, buffer, offset, length, position) {
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (size > 8 && contents.subarray) { // non-trivial, and typed array
+            buffer.set(contents.subarray(position, position + size), offset);
+          } else
+          {
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          }
+          return size;
+        },write:function (stream, buffer, offset, length, position, canOwn) {
+          var node = stream.node;
+          node.timestamp = Date.now();
+          var contents = node.contents;
+          if (length && contents.length === 0 && position === 0 && buffer.subarray) {
+            // just replace it with the new data
+            if (canOwn && offset === 0) {
+              node.contents = buffer; // this could be a subarray of Emscripten HEAP, or allocated from some other source.
+              node.contentMode = (buffer.buffer === HEAP8.buffer) ? MEMFS.CONTENT_OWNING : MEMFS.CONTENT_FIXED;
+            } else {
+              node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
+              node.contentMode = MEMFS.CONTENT_FIXED;
+            }
+            return length;
+          }
+          MEMFS.ensureFlexible(node);
+          var contents = node.contents;
+          while (contents.length < position) contents.push(0);
+          for (var i = 0; i < length; i++) {
+            contents[position + i] = buffer[offset + i];
+          }
+          return length;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              position += stream.node.contents.length;
+            }
+          }
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          stream.ungotten = [];
+          stream.position = position;
+          return position;
+        },allocate:function (stream, offset, length) {
+          MEMFS.ensureFlexible(stream.node);
+          var contents = stream.node.contents;
+          var limit = offset + length;
+          while (limit > contents.length) contents.push(0);
+        },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+          if (!FS.isFile(stream.node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          var ptr;
+          var allocated;
+          var contents = stream.node.contents;
+          // Only make a new copy when MAP_PRIVATE is specified.
+          if ( !(flags & 2) &&
+                (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
+            // We can't emulate MAP_SHARED when the file is not backed by the buffer
+            // we're mapping to (e.g. the HEAP buffer).
+            allocated = false;
+            ptr = contents.byteOffset;
+          } else {
+            // Try to avoid unnecessary slices.
+            if (position > 0 || position + length < contents.length) {
+              if (contents.subarray) {
+                contents = contents.subarray(position, position + length);
+              } else {
+                contents = Array.prototype.slice.call(contents, position, position + length);
+              }
+            }
+            allocated = true;
+            ptr = _malloc(length);
+            if (!ptr) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOMEM);
+            }
+            buffer.set(contents, ptr);
+          }
+          return { ptr: ptr, allocated: allocated };
+        }}};
+
+  var IDBFS={dbs:{},indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) {
+        // reuse all of the core MEMFS functionality
+        return MEMFS.mount.apply(null, arguments);
+      },syncfs:function (mount, populate, callback) {
+        IDBFS.getLocalSet(mount, function(err, local) {
+          if (err) return callback(err);
+
+          IDBFS.getRemoteSet(mount, function(err, remote) {
+            if (err) return callback(err);
+
+            var src = populate ? remote : local;
+            var dst = populate ? local : remote;
+
+            IDBFS.reconcile(src, dst, callback);
+          });
+        });
+      },getDB:function (name, callback) {
+        // check the cache first
+        var db = IDBFS.dbs[name];
+        if (db) {
+          return callback(null, db);
+        }
+
+        var req;
+        try {
+          req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
+        } catch (e) {
+          return callback(e);
+        }
+        req.onupgradeneeded = function(e) {
+          var db = e.target.result;
+          var transaction = e.target.transaction;
+
+          var fileStore;
+
+          if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
+            fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          } else {
+            fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
+          }
+
+          fileStore.createIndex('timestamp', 'timestamp', { unique: false });
+        };
+        req.onsuccess = function() {
+          db = req.result;
+
+          // add to the cache
+          IDBFS.dbs[name] = db;
+          callback(null, db);
+        };
+        req.onerror = function() {
+          callback(this.error);
+        };
+      },getLocalSet:function (mount, callback) {
+        var entries = {};
+
+        function isRealDir(p) {
+          return p !== '.' && p !== '..';
+        };
+        function toAbsolute(root) {
+          return function(p) {
+            return PATH.join2(root, p);
+          }
+        };
+
+        var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
+
+        while (check.length) {
+          var path = check.pop();
+          var stat;
+
+          try {
+            stat = FS.stat(path);
+          } catch (e) {
+            return callback(e);
+          }
+
+          if (FS.isDir(stat.mode)) {
+            check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
+          }
+
+          entries[path] = { timestamp: stat.mtime };
+        }
+
+        return callback(null, { type: 'local', entries: entries });
+      },getRemoteSet:function (mount, callback) {
+        var entries = {};
+
+        IDBFS.getDB(mount.mountpoint, function(err, db) {
+          if (err) return callback(err);
+
+          var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly');
+          transaction.onerror = function() { callback(this.error); };
+
+          var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          var index = store.index('timestamp');
+
+          index.openKeyCursor().onsuccess = function(event) {
+            var cursor = event.target.result;
+
+            if (!cursor) {
+              return callback(null, { type: 'remote', db: db, entries: entries });
+            }
+
+            entries[cursor.primaryKey] = { timestamp: cursor.key };
+
+            cursor.continue();
+          };
+        });
+      },loadLocalEntry:function (path, callback) {
+        var stat, node;
+
+        try {
+          var lookup = FS.lookupPath(path);
+          node = lookup.node;
+          stat = FS.stat(path);
+        } catch (e) {
+          return callback(e);
+        }
+
+        if (FS.isDir(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode });
+        } else if (FS.isFile(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents });
+        } else {
+          return callback(new Error('node type not supported'));
+        }
+      },storeLocalEntry:function (path, entry, callback) {
+        try {
+          if (FS.isDir(entry.mode)) {
+            FS.mkdir(path, entry.mode);
+          } else if (FS.isFile(entry.mode)) {
+            FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true });
+          } else {
+            return callback(new Error('node type not supported'));
+          }
+
+          FS.utime(path, entry.timestamp, entry.timestamp);
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },removeLocalEntry:function (path, callback) {
+        try {
+          var lookup = FS.lookupPath(path);
+          var stat = FS.stat(path);
+
+          if (FS.isDir(stat.mode)) {
+            FS.rmdir(path);
+          } else if (FS.isFile(stat.mode)) {
+            FS.unlink(path);
+          }
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },loadRemoteEntry:function (store, path, callback) {
+        var req = store.get(path);
+        req.onsuccess = function(event) { callback(null, event.target.result); };
+        req.onerror = function() { callback(this.error); };
+      },storeRemoteEntry:function (store, path, entry, callback) {
+        var req = store.put(entry, path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },removeRemoteEntry:function (store, path, callback) {
+        var req = store.delete(path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },reconcile:function (src, dst, callback) {
+        var total = 0;
+
+        var create = [];
+        Object.keys(src.entries).forEach(function (key) {
+          var e = src.entries[key];
+          var e2 = dst.entries[key];
+          if (!e2 || e.timestamp > e2.timestamp) {
+            create.push(key);
+            total++;
+          }
+        });
+
+        var remove = [];
+        Object.keys(dst.entries).forEach(function (key) {
+          var e = dst.entries[key];
+          var e2 = src.entries[key];
+          if (!e2) {
+            remove.push(key);
+            total++;
+          }
+        });
+
+        if (!total) {
+          return callback(null);
+        }
+
+        var errored = false;
+        var completed = 0;
+        var db = src.type === 'remote' ? src.db : dst.db;
+        var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
+        var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= total) {
+            return callback(null);
+          }
+        };
+
+        transaction.onerror = function() { done(this.error); };
+
+        // sort paths in ascending order so directory entries are created
+        // before the files inside them
+        create.sort().forEach(function (path) {
+          if (dst.type === 'local') {
+            IDBFS.loadRemoteEntry(store, path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeLocalEntry(path, entry, done);
+            });
+          } else {
+            IDBFS.loadLocalEntry(path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeRemoteEntry(store, path, entry, done);
+            });
+          }
+        });
+
+        // sort paths in descending order so files are deleted before their
+        // parent directories
+        remove.sort().reverse().forEach(function(path) {
+          if (dst.type === 'local') {
+            IDBFS.removeLocalEntry(path, done);
+          } else {
+            IDBFS.removeRemoteEntry(store, path, done);
+          }
+        });
+      }};
+
+  var NODEFS={isWindows:false,staticInit:function () {
+        NODEFS.isWindows = !!process.platform.match(/^win/);
+      },mount:function (mount) {
+        assert(ENVIRONMENT_IS_NODE);
+        return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node = FS.createNode(parent, name, mode);
+        node.node_ops = NODEFS.node_ops;
+        node.stream_ops = NODEFS.stream_ops;
+        return node;
+      },getMode:function (path) {
+        var stat;
+        try {
+          stat = fs.lstatSync(path);
+          if (NODEFS.isWindows) {
+            // On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so
+            // propagate write bits to execute bits.
+            stat.mode = stat.mode | ((stat.mode & 146) >> 1);
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        return stat.mode;
+      },realPath:function (node) {
+        var parts = [];
+        while (node.parent !== node) {
+          parts.push(node.name);
+          node = node.parent;
+        }
+        parts.push(node.mount.opts.root);
+        parts.reverse();
+        return PATH.join.apply(null, parts);
+      },flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) {
+        if (flags in NODEFS.flagsToPermissionStringMap) {
+          return NODEFS.flagsToPermissionStringMap[flags];
+        } else {
+          return flags;
+        }
+      },node_ops:{getattr:function (node) {
+          var path = NODEFS.realPath(node);
+          var stat;
+          try {
+            stat = fs.lstatSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096.
+          // See http://support.microsoft.com/kb/140365
+          if (NODEFS.isWindows && !stat.blksize) {
+            stat.blksize = 4096;
+          }
+          if (NODEFS.isWindows && !stat.blocks) {
+            stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0;
+          }
+          return {
+            dev: stat.dev,
+            ino: stat.ino,
+            mode: stat.mode,
+            nlink: stat.nlink,
+            uid: stat.uid,
+            gid: stat.gid,
+            rdev: stat.rdev,
+            size: stat.size,
+            atime: stat.atime,
+            mtime: stat.mtime,
+            ctime: stat.ctime,
+            blksize: stat.blksize,
+            blocks: stat.blocks
+          };
+        },setattr:function (node, attr) {
+          var path = NODEFS.realPath(node);
+          try {
+            if (attr.mode !== undefined) {
+              fs.chmodSync(path, attr.mode);
+              // update the common node structure mode as well
+              node.mode = attr.mode;
+            }
+            if (attr.timestamp !== undefined) {
+              var date = new Date(attr.timestamp);
+              fs.utimesSync(path, date, date);
+            }
+            if (attr.size !== undefined) {
+              fs.truncateSync(path, attr.size);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },lookup:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          var mode = NODEFS.getMode(path);
+          return NODEFS.createNode(parent, name, mode);
+        },mknod:function (parent, name, mode, dev) {
+          var node = NODEFS.createNode(parent, name, mode, dev);
+          // create the backing node for this in the fs root as well
+          var path = NODEFS.realPath(node);
+          try {
+            if (FS.isDir(node.mode)) {
+              fs.mkdirSync(path, node.mode);
+            } else {
+              fs.writeFileSync(path, '', { mode: node.mode });
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return node;
+        },rename:function (oldNode, newDir, newName) {
+          var oldPath = NODEFS.realPath(oldNode);
+          var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
+          try {
+            fs.renameSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },unlink:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.unlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },rmdir:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.rmdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readdir:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },symlink:function (parent, newName, oldPath) {
+          var newPath = PATH.join2(NODEFS.realPath(parent), newName);
+          try {
+            fs.symlinkSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readlink:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        }},stream_ops:{open:function (stream) {
+          var path = NODEFS.realPath(stream.node);
+          try {
+            if (FS.isFile(stream.node.mode)) {
+              stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags));
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },close:function (stream) {
+          try {
+            if (FS.isFile(stream.node.mode) && stream.nfd) {
+              fs.closeSync(stream.nfd);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },read:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(length);
+          var res;
+          try {
+            res = fs.readSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          if (res > 0) {
+            for (var i = 0; i < res; i++) {
+              buffer[offset + i] = nbuffer[i];
+            }
+          }
+          return res;
+        },write:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(buffer.subarray(offset, offset + length));
+          var res;
+          try {
+            res = fs.writeSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return res;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              try {
+                var stat = fs.fstatSync(stream.nfd);
+                position += stat.size;
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+              }
+            }
+          }
+
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+
+          stream.position = position;
+          return position;
+        }}};
+
+  var _stdin=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stdout=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stderr=allocate(1, "i32*", ALLOC_STATIC);
+
+  function _fflush(stream) {
+      // int fflush(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html
+      // we don't currently perform any user-space buffering of data
+    }var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},handleFSError:function (e) {
+        if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
+        return ___setErrNo(e.errno);
+      },lookupPath:function (path, opts) {
+        path = PATH.resolve(FS.cwd(), path);
+        opts = opts || {};
+
+        var defaults = {
+          follow_mount: true,
+          recurse_count: 0
+        };
+        for (var key in defaults) {
+          if (opts[key] === undefined) {
+            opts[key] = defaults[key];
+          }
+        }
+
+        if (opts.recurse_count > 8) {  // max recursive lookup of 8
+          throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+        }
+
+        // split the path
+        var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), false);
+
+        // start at the root
+        var current = FS.root;
+        var current_path = '/';
+
+        for (var i = 0; i < parts.length; i++) {
+          var islast = (i === parts.length-1);
+          if (islast && opts.parent) {
+            // stop resolving
+            break;
+          }
+
+          current = FS.lookupNode(current, parts[i]);
+          current_path = PATH.join2(current_path, parts[i]);
+
+          // jump to the mount's root node if this is a mountpoint
+          if (FS.isMountpoint(current)) {
+            if (!islast || (islast && opts.follow_mount)) {
+              current = current.mounted.root;
+            }
+          }
+
+          // by default, lookupPath will not follow a symlink if it is the final path component.
+          // setting opts.follow = true will override this behavior.
+          if (!islast || opts.follow) {
+            var count = 0;
+            while (FS.isLink(current.mode)) {
+              var link = FS.readlink(current_path);
+              current_path = PATH.resolve(PATH.dirname(current_path), link);
+
+              var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
+              current = lookup.node;
+
+              if (count++ > 40) {  // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
+                throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+              }
+            }
+          }
+        }
+
+        return { path: current_path, node: current };
+      },getPath:function (node) {
+        var path;
+        while (true) {
+          if (FS.isRoot(node)) {
+            var mount = node.mount.mountpoint;
+            if (!path) return mount;
+            return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
+          }
+          path = path ? node.name + '/' + path : node.name;
+          node = node.parent;
+        }
+      },hashName:function (parentid, name) {
+        var hash = 0;
+
+
+        for (var i = 0; i < name.length; i++) {
+          hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
+        }
+        return ((parentid + hash) >>> 0) % FS.nameTable.length;
+      },hashAddNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        node.name_next = FS.nameTable[hash];
+        FS.nameTable[hash] = node;
+      },hashRemoveNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        if (FS.nameTable[hash] === node) {
+          FS.nameTable[hash] = node.name_next;
+        } else {
+          var current = FS.nameTable[hash];
+          while (current) {
+            if (current.name_next === node) {
+              current.name_next = node.name_next;
+              break;
+            }
+            current = current.name_next;
+          }
+        }
+      },lookupNode:function (parent, name) {
+        var err = FS.mayLookup(parent);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        var hash = FS.hashName(parent.id, name);
+        for (var node = FS.nameTable[hash]; node; node = node.name_next) {
+          var nodeName = node.name;
+          if (node.parent.id === parent.id && nodeName === name) {
+            return node;
+          }
+        }
+        // if we failed to find it in the cache, call into the VFS
+        return FS.lookup(parent, name);
+      },createNode:function (parent, name, mode, rdev) {
+        if (!FS.FSNode) {
+          FS.FSNode = function(parent, name, mode, rdev) {
+            if (!parent) {
+              parent = this;  // root node sets parent to itself
+            }
+            this.parent = parent;
+            this.mount = parent.mount;
+            this.mounted = null;
+            this.id = FS.nextInode++;
+            this.name = name;
+            this.mode = mode;
+            this.node_ops = {};
+            this.stream_ops = {};
+            this.rdev = rdev;
+          };
+
+          FS.FSNode.prototype = {};
+
+          // compatibility
+          var readMode = 292 | 73;
+          var writeMode = 146;
+
+          // NOTE we must use Object.defineProperties instead of individual calls to
+          // Object.defineProperty in order to make closure compiler happy
+          Object.defineProperties(FS.FSNode.prototype, {
+            read: {
+              get: function() { return (this.mode & readMode) === readMode; },
+              set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; }
+            },
+            write: {
+              get: function() { return (this.mode & writeMode) === writeMode; },
+              set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; }
+            },
+            isFolder: {
+              get: function() { return FS.isDir(this.mode); },
+            },
+            isDevice: {
+              get: function() { return FS.isChrdev(this.mode); },
+            },
+          });
+        }
+
+        var node = new FS.FSNode(parent, name, mode, rdev);
+
+        FS.hashAddNode(node);
+
+        return node;
+      },destroyNode:function (node) {
+        FS.hashRemoveNode(node);
+      },isRoot:function (node) {
+        return node === node.parent;
+      },isMountpoint:function (node) {
+        return !!node.mounted;
+      },isFile:function (mode) {
+        return (mode & 61440) === 32768;
+      },isDir:function (mode) {
+        return (mode & 61440) === 16384;
+      },isLink:function (mode) {
+        return (mode & 61440) === 40960;
+      },isChrdev:function (mode) {
+        return (mode & 61440) === 8192;
+      },isBlkdev:function (mode) {
+        return (mode & 61440) === 24576;
+      },isFIFO:function (mode) {
+        return (mode & 61440) === 4096;
+      },isSocket:function (mode) {
+        return (mode & 49152) === 49152;
+      },flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function (str) {
+        var flags = FS.flagModes[str];
+        if (typeof flags === 'undefined') {
+          throw new Error('Unknown file open mode: ' + str);
+        }
+        return flags;
+      },flagsToPermissionString:function (flag) {
+        var accmode = flag & 2097155;
+        var perms = ['r', 'w', 'rw'][accmode];
+        if ((flag & 512)) {
+          perms += 'w';
+        }
+        return perms;
+      },nodePermissions:function (node, perms) {
+        if (FS.ignorePermissions) {
+          return 0;
+        }
+        // return 0 if any user, group or owner bits are set.
+        if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
+          return ERRNO_CODES.EACCES;
+        }
+        return 0;
+      },mayLookup:function (dir) {
+        return FS.nodePermissions(dir, 'x');
+      },mayCreate:function (dir, name) {
+        try {
+          var node = FS.lookupNode(dir, name);
+          return ERRNO_CODES.EEXIST;
+        } catch (e) {
+        }
+        return FS.nodePermissions(dir, 'wx');
+      },mayDelete:function (dir, name, isdir) {
+        var node;
+        try {
+          node = FS.lookupNode(dir, name);
+        } catch (e) {
+          return e.errno;
+        }
+        var err = FS.nodePermissions(dir, 'wx');
+        if (err) {
+          return err;
+        }
+        if (isdir) {
+          if (!FS.isDir(node.mode)) {
+            return ERRNO_CODES.ENOTDIR;
+          }
+          if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
+            return ERRNO_CODES.EBUSY;
+          }
+        } else {
+          if (FS.isDir(node.mode)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return 0;
+      },mayOpen:function (node, flags) {
+        if (!node) {
+          return ERRNO_CODES.ENOENT;
+        }
+        if (FS.isLink(node.mode)) {
+          return ERRNO_CODES.ELOOP;
+        } else if (FS.isDir(node.mode)) {
+          if ((flags & 2097155) !== 0 ||  // opening for write
+              (flags & 512)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
+      },MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) {
+        fd_start = fd_start || 0;
+        fd_end = fd_end || FS.MAX_OPEN_FDS;
+        for (var fd = fd_start; fd <= fd_end; fd++) {
+          if (!FS.streams[fd]) {
+            return fd;
+          }
+        }
+        throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
+      },getStream:function (fd) {
+        return FS.streams[fd];
+      },createStream:function (stream, fd_start, fd_end) {
+        if (!FS.FSStream) {
+          FS.FSStream = function(){};
+          FS.FSStream.prototype = {};
+          // compatibility
+          Object.defineProperties(FS.FSStream.prototype, {
+            object: {
+              get: function() { return this.node; },
+              set: function(val) { this.node = val; }
+            },
+            isRead: {
+              get: function() { return (this.flags & 2097155) !== 1; }
+            },
+            isWrite: {
+              get: function() { return (this.flags & 2097155) !== 0; }
+            },
+            isAppend: {
+              get: function() { return (this.flags & 1024); }
+            }
+          });
+        }
+        if (0) {
+          // reuse the object
+          stream.__proto__ = FS.FSStream.prototype;
+        } else {
+          var newStream = new FS.FSStream();
+          for (var p in stream) {
+            newStream[p] = stream[p];
+          }
+          stream = newStream;
+        }
+        var fd = FS.nextfd(fd_start, fd_end);
+        stream.fd = fd;
+        FS.streams[fd] = stream;
+        return stream;
+      },closeStream:function (fd) {
+        FS.streams[fd] = null;
+      },getStreamFromPtr:function (ptr) {
+        return FS.streams[ptr - 1];
+      },getPtrForStream:function (stream) {
+        return stream ? stream.fd + 1 : 0;
+      },chrdev_stream_ops:{open:function (stream) {
+          var device = FS.getDevice(stream.node.rdev);
+          // override node's stream ops with the device's
+          stream.stream_ops = device.stream_ops;
+          // forward the open call
+          if (stream.stream_ops.open) {
+            stream.stream_ops.open(stream);
+          }
+        },llseek:function () {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }},major:function (dev) {
+        return ((dev) >> 8);
+      },minor:function (dev) {
+        return ((dev) & 0xff);
+      },makedev:function (ma, mi) {
+        return ((ma) << 8 | (mi));
+      },registerDevice:function (dev, ops) {
+        FS.devices[dev] = { stream_ops: ops };
+      },getDevice:function (dev) {
+        return FS.devices[dev];
+      },getMounts:function (mount) {
+        var mounts = [];
+        var check = [mount];
+
+        while (check.length) {
+          var m = check.pop();
+
+          mounts.push(m);
+
+          check.push.apply(check, m.mounts);
+        }
+
+        return mounts;
+      },syncfs:function (populate, callback) {
+        if (typeof(populate) === 'function') {
+          callback = populate;
+          populate = false;
+        }
+
+        var mounts = FS.getMounts(FS.root.mount);
+        var completed = 0;
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= mounts.length) {
+            callback(null);
+          }
+        };
+
+        // sync all mounts
+        mounts.forEach(function (mount) {
+          if (!mount.type.syncfs) {
+            return done(null);
+          }
+          mount.type.syncfs(mount, populate, done);
+        });
+      },mount:function (type, opts, mountpoint) {
+        var root = mountpoint === '/';
+        var pseudo = !mountpoint;
+        var node;
+
+        if (root && FS.root) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        } else if (!root && !pseudo) {
+          var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+          mountpoint = lookup.path;  // use the absolute path
+          node = lookup.node;
+
+          if (FS.isMountpoint(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+          }
+
+          if (!FS.isDir(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+          }
+        }
+
+        var mount = {
+          type: type,
+          opts: opts,
+          mountpoint: mountpoint,
+          mounts: []
+        };
+
+        // create a root node for the fs
+        var mountRoot = type.mount(mount);
+        mountRoot.mount = mount;
+        mount.root = mountRoot;
+
+        if (root) {
+          FS.root = mountRoot;
+        } else if (node) {
+          // set as a mountpoint
+          node.mounted = mount;
+
+          // add the new mount to the current mount's children
+          if (node.mount) {
+            node.mount.mounts.push(mount);
+          }
+        }
+
+        return mountRoot;
+      },unmount:function (mountpoint) {
+        var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+        if (!FS.isMountpoint(lookup.node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+
+        // destroy the nodes for this mount, and all its child mounts
+        var node = lookup.node;
+        var mount = node.mounted;
+        var mounts = FS.getMounts(mount);
+
+        Object.keys(FS.nameTable).forEach(function (hash) {
+          var current = FS.nameTable[hash];
+
+          while (current) {
+            var next = current.name_next;
+
+            if (mounts.indexOf(current.mount) !== -1) {
+              FS.destroyNode(current);
+            }
+
+            current = next;
+          }
+        });
+
+        // no longer a mountpoint
+        node.mounted = null;
+
+        // remove this mount from the child mounts
+        var idx = node.mount.mounts.indexOf(mount);
+        assert(idx !== -1);
+        node.mount.mounts.splice(idx, 1);
+      },lookup:function (parent, name) {
+        return parent.node_ops.lookup(parent, name);
+      },mknod:function (path, mode, dev) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var err = FS.mayCreate(parent, name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.mknod) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.mknod(parent, name, mode, dev);
+      },create:function (path, mode) {
+        mode = mode !== undefined ? mode : 438 /* 0666 */;
+        mode &= 4095;
+        mode |= 32768;
+        return FS.mknod(path, mode, 0);
+      },mkdir:function (path, mode) {
+        mode = mode !== undefined ? mode : 511 /* 0777 */;
+        mode &= 511 | 512;
+        mode |= 16384;
+        return FS.mknod(path, mode, 0);
+      },mkdev:function (path, mode, dev) {
+        if (typeof(dev) === 'undefined') {
+          dev = mode;
+          mode = 438 /* 0666 */;
+        }
+        mode |= 8192;
+        return FS.mknod(path, mode, dev);
+      },symlink:function (oldpath, newpath) {
+        var lookup = FS.lookupPath(newpath, { parent: true });
+        var parent = lookup.node;
+        var newname = PATH.basename(newpath);
+        var err = FS.mayCreate(parent, newname);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.symlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.symlink(parent, newname, oldpath);
+      },rename:function (old_path, new_path) {
+        var old_dirname = PATH.dirname(old_path);
+        var new_dirname = PATH.dirname(new_path);
+        var old_name = PATH.basename(old_path);
+        var new_name = PATH.basename(new_path);
+        // parents must exist
+        var lookup, old_dir, new_dir;
+        try {
+          lookup = FS.lookupPath(old_path, { parent: true });
+          old_dir = lookup.node;
+          lookup = FS.lookupPath(new_path, { parent: true });
+          new_dir = lookup.node;
+        } catch (e) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // need to be part of the same mount
+        if (old_dir.mount !== new_dir.mount) {
+          throw new FS.ErrnoError(ERRNO_CODES.EXDEV);
+        }
+        // source must exist
+        var old_node = FS.lookupNode(old_dir, old_name);
+        // old path should not be an ancestor of the new path
+        var relative = PATH.relative(old_path, new_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        // new path should not be an ancestor of the old path
+        relative = PATH.relative(new_path, old_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+        }
+        // see if the new path already exists
+        var new_node;
+        try {
+          new_node = FS.lookupNode(new_dir, new_name);
+        } catch (e) {
+          // not fatal
+        }
+        // early out if nothing needs to change
+        if (old_node === new_node) {
+          return;
+        }
+        // we'll need to delete the old entry
+        var isdir = FS.isDir(old_node.mode);
+        var err = FS.mayDelete(old_dir, old_name, isdir);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // need delete permissions if we'll be overwriting.
+        // need create permissions if new doesn't already exist.
+        err = new_node ?
+          FS.mayDelete(new_dir, new_name, isdir) :
+          FS.mayCreate(new_dir, new_name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!old_dir.node_ops.rename) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // if we are going to change the parent, check write permissions
+        if (new_dir !== old_dir) {
+          err = FS.nodePermissions(old_dir, 'w');
+          if (err) {
+            throw new FS.ErrnoError(err);
+          }
+        }
+        // remove the node from the lookup hash
+        FS.hashRemoveNode(old_node);
+        // do the underlying fs rename
+        try {
+          old_dir.node_ops.rename(old_node, new_dir, new_name);
+        } catch (e) {
+          throw e;
+        } finally {
+          // add the node back to the hash (in case node_ops.rename
+          // changed its name)
+          FS.hashAddNode(old_node);
+        }
+      },rmdir:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, true);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.rmdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.rmdir(parent, name);
+        FS.destroyNode(node);
+      },readdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        if (!node.node_ops.readdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        return node.node_ops.readdir(node);
+      },unlink:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, false);
+        if (err) {
+          // POSIX says unlink should set EPERM, not EISDIR
+          if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM;
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.unlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.unlink(parent, name);
+        FS.destroyNode(node);
+      },readlink:function (path) {
+        var lookup = FS.lookupPath(path);
+        var link = lookup.node;
+        if (!link.node_ops.readlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        return link.node_ops.readlink(link);
+      },stat:function (path, dontFollow) {
+        var lookup = FS.lookupPath(path, { follow: !dontFollow });
+        var node = lookup.node;
+        if (!node.node_ops.getattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return node.node_ops.getattr(node);
+      },lstat:function (path) {
+        return FS.stat(path, true);
+      },chmod:function (path, mode, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          mode: (mode & 4095) | (node.mode & ~4095),
+          timestamp: Date.now()
+        });
+      },lchmod:function (path, mode) {
+        FS.chmod(path, mode, true);
+      },fchmod:function (fd, mode) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chmod(stream.node, mode);
+      },chown:function (path, uid, gid, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          timestamp: Date.now()
+          // we ignore the uid / gid for now
+        });
+      },lchown:function (path, uid, gid) {
+        FS.chown(path, uid, gid, true);
+      },fchown:function (fd, uid, gid) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chown(stream.node, uid, gid);
+      },truncate:function (path, len) {
+        if (len < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: true });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!FS.isFile(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var err = FS.nodePermissions(node, 'w');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        node.node_ops.setattr(node, {
+          size: len,
+          timestamp: Date.now()
+        });
+      },ftruncate:function (fd, len) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        FS.truncate(stream.node, len);
+      },utime:function (path, atime, mtime) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        node.node_ops.setattr(node, {
+          timestamp: Math.max(atime, mtime)
+        });
+      },open:function (path, flags, mode, fd_start, fd_end) {
+        flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
+        mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
+        if ((flags & 64)) {
+          mode = (mode & 4095) | 32768;
+        } else {
+          mode = 0;
+        }
+        var node;
+        if (typeof path === 'object') {
+          node = path;
+        } else {
+          path = PATH.normalize(path);
+          try {
+            var lookup = FS.lookupPath(path, {
+              follow: !(flags & 131072)
+            });
+            node = lookup.node;
+          } catch (e) {
+            // ignore
+          }
+        }
+        // perhaps we need to create the node
+        if ((flags & 64)) {
+          if (node) {
+            // if O_CREAT and O_EXCL are set, error out if the node already exists
+            if ((flags & 128)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EEXIST);
+            }
+          } else {
+            // node doesn't exist, try to create it
+            node = FS.mknod(path, mode, 0);
+          }
+        }
+        if (!node) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
+        }
+        // can't truncate a device
+        if (FS.isChrdev(node.mode)) {
+          flags &= ~512;
+        }
+        // check permissions
+        var err = FS.mayOpen(node, flags);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // do truncation if necessary
+        if ((flags & 512)) {
+          FS.truncate(node, 0);
+        }
+        // we've already handled these, don't pass down to the underlying vfs
+        flags &= ~(128 | 512);
+
+        // register the stream with the filesystem
+        var stream = FS.createStream({
+          node: node,
+          path: FS.getPath(node),  // we want the absolute path to the node
+          flags: flags,
+          seekable: true,
+          position: 0,
+          stream_ops: node.stream_ops,
+          // used by the file family libc calls (fopen, fwrite, ferror, etc.)
+          ungotten: [],
+          error: false
+        }, fd_start, fd_end);
+        // call the new stream's open function
+        if (stream.stream_ops.open) {
+          stream.stream_ops.open(stream);
+        }
+        if (Module['logReadFiles'] && !(flags & 1)) {
+          if (!FS.readFiles) FS.readFiles = {};
+          if (!(path in FS.readFiles)) {
+            FS.readFiles[path] = 1;
+            Module['printErr']('read file: ' + path);
+          }
+        }
+        return stream;
+      },close:function (stream) {
+        try {
+          if (stream.stream_ops.close) {
+            stream.stream_ops.close(stream);
+          }
+        } catch (e) {
+          throw e;
+        } finally {
+          FS.closeStream(stream.fd);
+        }
+      },llseek:function (stream, offset, whence) {
+        if (!stream.seekable || !stream.stream_ops.llseek) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        return stream.stream_ops.llseek(stream, offset, whence);
+      },read:function (stream, buffer, offset, length, position) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.read) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
+        if (!seeking) stream.position += bytesRead;
+        return bytesRead;
+      },write:function (stream, buffer, offset, length, position, canOwn) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.write) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        if (stream.flags & 1024) {
+          // seek to the end before writing in append mode
+          FS.llseek(stream, 0, 2);
+        }
+        var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
+        if (!seeking) stream.position += bytesWritten;
+        return bytesWritten;
+      },allocate:function (stream, offset, length) {
+        if (offset < 0 || length <= 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        if (!stream.stream_ops.allocate) {
+          throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+        }
+        stream.stream_ops.allocate(stream, offset, length);
+      },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+        // TODO if PROT is PROT_WRITE, make sure we have write access
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EACCES);
+        }
+        if (!stream.stream_ops.mmap) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
+      },ioctl:function (stream, cmd, arg) {
+        if (!stream.stream_ops.ioctl) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTTY);
+        }
+        return stream.stream_ops.ioctl(stream, cmd, arg);
+      },readFile:function (path, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'r';
+        opts.encoding = opts.encoding || 'binary';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var ret;
+        var stream = FS.open(path, opts.flags);
+        var stat = FS.stat(path);
+        var length = stat.size;
+        var buf = new Uint8Array(length);
+        FS.read(stream, buf, 0, length, 0);
+        if (opts.encoding === 'utf8') {
+          ret = '';
+          var utf8 = new Runtime.UTF8Processor();
+          for (var i = 0; i < length; i++) {
+            ret += utf8.processCChar(buf[i]);
+          }
+        } else if (opts.encoding === 'binary') {
+          ret = buf;
+        }
+        FS.close(stream);
+        return ret;
+      },writeFile:function (path, data, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'w';
+        opts.encoding = opts.encoding || 'utf8';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var stream = FS.open(path, opts.flags, opts.mode);
+        if (opts.encoding === 'utf8') {
+          var utf8 = new Runtime.UTF8Processor();
+          var buf = new Uint8Array(utf8.processJSString(data));
+          FS.write(stream, buf, 0, buf.length, 0, opts.canOwn);
+        } else if (opts.encoding === 'binary') {
+          FS.write(stream, data, 0, data.length, 0, opts.canOwn);
+        }
+        FS.close(stream);
+      },cwd:function () {
+        return FS.currentPath;
+      },chdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        if (!FS.isDir(lookup.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        var err = FS.nodePermissions(lookup.node, 'x');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        FS.currentPath = lookup.path;
+      },createDefaultDirectories:function () {
+        FS.mkdir('/tmp');
+      },createDefaultDevices:function () {
+        // create /dev
+        FS.mkdir('/dev');
+        // setup /dev/null
+        FS.registerDevice(FS.makedev(1, 3), {
+          read: function() { return 0; },
+          write: function() { return 0; }
+        });
+        FS.mkdev('/dev/null', FS.makedev(1, 3));
+        // setup /dev/tty and /dev/tty1
+        // stderr needs to print output using Module['printErr']
+        // so we register a second tty just for it.
+        TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
+        TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
+        FS.mkdev('/dev/tty', FS.makedev(5, 0));
+        FS.mkdev('/dev/tty1', FS.makedev(6, 0));
+        // we're not going to emulate the actual shm device,
+        // just create the tmp dirs that reside in it commonly
+        FS.mkdir('/dev/shm');
+        FS.mkdir('/dev/shm/tmp');
+      },createStandardStreams:function () {
+        // TODO deprecate the old functionality of a single
+        // input / output callback and that utilizes FS.createDevice
+        // and instead require a unique set of stream ops
+
+        // by default, we symlink the standard streams to the
+        // default tty devices. however, if the standard streams
+        // have been overwritten we create a unique device for
+        // them instead.
+        if (Module['stdin']) {
+          FS.createDevice('/dev', 'stdin', Module['stdin']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdin');
+        }
+        if (Module['stdout']) {
+          FS.createDevice('/dev', 'stdout', null, Module['stdout']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdout');
+        }
+        if (Module['stderr']) {
+          FS.createDevice('/dev', 'stderr', null, Module['stderr']);
+        } else {
+          FS.symlink('/dev/tty1', '/dev/stderr');
+        }
+
+        // open default streams for the stdin, stdout and stderr devices
+        var stdin = FS.open('/dev/stdin', 'r');
+        HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin);
+        assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
+
+        var stdout = FS.open('/dev/stdout', 'w');
+        HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout);
+        assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
+
+        var stderr = FS.open('/dev/stderr', 'w');
+        HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr);
+        assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
+      },ensureErrnoError:function () {
+        if (FS.ErrnoError) return;
+        FS.ErrnoError = function ErrnoError(errno) {
+          this.errno = errno;
+          for (var key in ERRNO_CODES) {
+            if (ERRNO_CODES[key] === errno) {
+              this.code = key;
+              break;
+            }
+          }
+          this.message = ERRNO_MESSAGES[errno];
+        };
+        FS.ErrnoError.prototype = new Error();
+        FS.ErrnoError.prototype.constructor = FS.ErrnoError;
+        // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
+        [ERRNO_CODES.ENOENT].forEach(function(code) {
+          FS.genericErrors[code] = new FS.ErrnoError(code);
+          FS.genericErrors[code].stack = '<generic error, no stack>';
+        });
+      },staticInit:function () {
+        FS.ensureErrnoError();
+
+        FS.nameTable = new Array(4096);
+
+        FS.mount(MEMFS, {}, '/');
+
+        FS.createDefaultDirectories();
+        FS.createDefaultDevices();
+      },init:function (input, output, error) {
+        assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
+        FS.init.initialized = true;
+
+        FS.ensureErrnoError();
+
+        // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
+        Module['stdin'] = input || Module['stdin'];
+        Module['stdout'] = output || Module['stdout'];
+        Module['stderr'] = error || Module['stderr'];
+
+        FS.createStandardStreams();
+      },quit:function () {
+        FS.init.initialized = false;
+        for (var i = 0; i < FS.streams.length; i++) {
+          var stream = FS.streams[i];
+          if (!stream) {
+            continue;
+          }
+          FS.close(stream);
+        }
+      },getMode:function (canRead, canWrite) {
+        var mode = 0;
+        if (canRead) mode |= 292 | 73;
+        if (canWrite) mode |= 146;
+        return mode;
+      },joinPath:function (parts, forceRelative) {
+        var path = PATH.join.apply(null, parts);
+        if (forceRelative && path[0] == '/') path = path.substr(1);
+        return path;
+      },absolutePath:function (relative, base) {
+        return PATH.resolve(base, relative);
+      },standardizePath:function (path) {
+        return PATH.normalize(path);
+      },findObject:function (path, dontResolveLastLink) {
+        var ret = FS.analyzePath(path, dontResolveLastLink);
+        if (ret.exists) {
+          return ret.object;
+        } else {
+          ___setErrNo(ret.error);
+          return null;
+        }
+      },analyzePath:function (path, dontResolveLastLink) {
+        // operate from within the context of the symlink's target
+        try {
+          var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          path = lookup.path;
+        } catch (e) {
+        }
+        var ret = {
+          isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
+          parentExists: false, parentPath: null, parentObject: null
+        };
+        try {
+          var lookup = FS.lookupPath(path, { parent: true });
+          ret.parentExists = true;
+          ret.parentPath = lookup.path;
+          ret.parentObject = lookup.node;
+          ret.name = PATH.basename(path);
+          lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          ret.exists = true;
+          ret.path = lookup.path;
+          ret.object = lookup.node;
+          ret.name = lookup.node.name;
+          ret.isRoot = lookup.path === '/';
+        } catch (e) {
+          ret.error = e.errno;
+        };
+        return ret;
+      },createFolder:function (parent, name, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.mkdir(path, mode);
+      },createPath:function (parent, path, canRead, canWrite) {
+        parent = typeof parent === 'string' ? parent : FS.getPath(parent);
+        var parts = path.split('/').reverse();
+        while (parts.length) {
+          var part = parts.pop();
+          if (!part) continue;
+          var current = PATH.join2(parent, part);
+          try {
+            FS.mkdir(current);
+          } catch (e) {
+            // ignore EEXIST
+          }
+          parent = current;
+        }
+        return current;
+      },createFile:function (parent, name, properties, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.create(path, mode);
+      },createDataFile:function (parent, name, data, canRead, canWrite, canOwn) {
+        var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
+        var mode = FS.getMode(canRead, canWrite);
+        var node = FS.create(path, mode);
+        if (data) {
+          if (typeof data === 'string') {
+            var arr = new Array(data.length);
+            for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
+            data = arr;
+          }
+          // make sure we can write to the file
+          FS.chmod(node, mode | 146);
+          var stream = FS.open(node, 'w');
+          FS.write(stream, data, 0, data.length, 0, canOwn);
+          FS.close(stream);
+          FS.chmod(node, mode);
+        }
+        return node;
+      },createDevice:function (parent, name, input, output) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(!!input, !!output);
+        if (!FS.createDevice.major) FS.createDevice.major = 64;
+        var dev = FS.makedev(FS.createDevice.major++, 0);
+        // Create a fake device that a set of stream ops to emulate
+        // the old behavior.
+        FS.registerDevice(dev, {
+          open: function(stream) {
+            stream.seekable = false;
+          },
+          close: function(stream) {
+            // flush any pending line data
+            if (output && output.buffer && output.buffer.length) {
+              output(10);
+            }
+          },
+          read: function(stream, buffer, offset, length, pos /* ignored */) {
+            var bytesRead = 0;
+            for (var i = 0; i < length; i++) {
+              var result;
+              try {
+                result = input();
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+              if (result === undefined && bytesRead === 0) {
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+              if (result === null || result === undefined) break;
+              bytesRead++;
+              buffer[offset+i] = result;
+            }
+            if (bytesRead) {
+              stream.node.timestamp = Date.now();
+            }
+            return bytesRead;
+          },
+          write: function(stream, buffer, offset, length, pos) {
+            for (var i = 0; i < length; i++) {
+              try {
+                output(buffer[offset+i]);
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+            }
+            if (length) {
+              stream.node.timestamp = Date.now();
+            }
+            return i;
+          }
+        });
+        return FS.mkdev(path, mode, dev);
+      },createLink:function (parent, name, target, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        return FS.symlink(target, path);
+      },forceLoadFile:function (obj) {
+        if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
+        var success = true;
+        if (typeof XMLHttpRequest !== 'undefined') {
+          throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
+        } else if (Module['read']) {
+          // Command-line.
+          try {
+            // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
+            //          read() will try to parse UTF8.
+            obj.contents = intArrayFromString(Module['read'](obj.url), true);
+          } catch (e) {
+            success = false;
+          }
+        } else {
+          throw new Error('Cannot load without read() or XMLHttpRequest.');
+        }
+        if (!success) ___setErrNo(ERRNO_CODES.EIO);
+        return success;
+      },createLazyFile:function (parent, name, url, canRead, canWrite) {
+        // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
+        function LazyUint8Array() {
+          this.lengthKnown = false;
+          this.chunks = []; // Loaded chunks. Index is the chunk number
+        }
+        LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
+          if (idx > this.length-1 || idx < 0) {
+            return undefined;
+          }
+          var chunkOffset = idx % this.chunkSize;
+          var chunkNum = Math.floor(idx / this.chunkSize);
+          return this.getter(chunkNum)[chunkOffset];
+        }
+        LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
+          this.getter = getter;
+        }
+        LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
+            // Find length
+            var xhr = new XMLHttpRequest();
+            xhr.open('HEAD', url, false);
+            xhr.send(null);
+            if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+            var datalength = Number(xhr.getResponseHeader("Content-length"));
+            var header;
+            var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
+            var chunkSize = 1024*1024; // Chunk size in bytes
+
+            if (!hasByteServing) chunkSize = datalength;
+
+            // Function to get a range from the remote URL.
+            var doXHR = (function(from, to) {
+              if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
+              if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
+
+              // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
+              var xhr = new XMLHttpRequest();
+              xhr.open('GET', url, false);
+              if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
+
+              // Some hints to the browser that we want binary data.
+              if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
+              if (xhr.overrideMimeType) {
+                xhr.overrideMimeType('text/plain; charset=x-user-defined');
+              }
+
+              xhr.send(null);
+              if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+              if (xhr.response !== undefined) {
+                return new Uint8Array(xhr.response || []);
+              } else {
+                return intArrayFromString(xhr.responseText || '', true);
+              }
+            });
+            var lazyArray = this;
+            lazyArray.setDataGetter(function(chunkNum) {
+              var start = chunkNum * chunkSize;
+              var end = (chunkNum+1) * chunkSize - 1; // including this byte
+              end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
+                lazyArray.chunks[chunkNum] = doXHR(start, end);
+              }
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
+              return lazyArray.chunks[chunkNum];
+            });
+
+            this._length = datalength;
+            this._chunkSize = chunkSize;
+            this.lengthKnown = true;
+        }
+        if (typeof XMLHttpRequest !== 'undefined') {
+          if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
+          var lazyArray = new LazyUint8Array();
+          Object.defineProperty(lazyArray, "length", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._length;
+              }
+          });
+          Object.defineProperty(lazyArray, "chunkSize", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._chunkSize;
+              }
+          });
+
+          var properties = { isDevice: false, contents: lazyArray };
+        } else {
+          var properties = { isDevice: false, url: url };
+        }
+
+        var node = FS.createFile(parent, name, properties, canRead, canWrite);
+        // This is a total hack, but I want to get this lazy file code out of the
+        // core of MEMFS. If we want to keep this lazy file concept I feel it should
+        // be its own thin LAZYFS proxying calls to MEMFS.
+        if (properties.contents) {
+          node.contents = properties.contents;
+        } else if (properties.url) {
+          node.contents = null;
+          node.url = properties.url;
+        }
+        // override each stream op with one that tries to force load the lazy file first
+        var stream_ops = {};
+        var keys = Object.keys(node.stream_ops);
+        keys.forEach(function(key) {
+          var fn = node.stream_ops[key];
+          stream_ops[key] = function forceLoadLazyFile() {
+            if (!FS.forceLoadFile(node)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            return fn.apply(null, arguments);
+          };
+        });
+        // use a custom read function
+        stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
+          if (!FS.forceLoadFile(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EIO);
+          }
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (contents.slice) { // normal array
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          } else {
+            for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
+              buffer[offset + i] = contents.get(position + i);
+            }
+          }
+          return size;
+        };
+        node.stream_ops = stream_ops;
+        return node;
+      },createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
+        Browser.init();
+        // TODO we should allow people to just pass in a complete filename instead
+        // of parent and name being that we just join them anyways
+        var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent;
+        function processData(byteArray) {
+          function finish(byteArray) {
+            if (!dontCreateFile) {
+              FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
+            }
+            if (onload) onload();
+            removeRunDependency('cp ' + fullname);
+          }
+          var handled = false;
+          Module['preloadPlugins'].forEach(function(plugin) {
+            if (handled) return;
+            if (plugin['canHandle'](fullname)) {
+              plugin['handle'](byteArray, fullname, finish, function() {
+                if (onerror) onerror();
+                removeRunDependency('cp ' + fullname);
+              });
+              handled = true;
+            }
+          });
+          if (!handled) finish(byteArray);
+        }
+        addRunDependency('cp ' + fullname);
+        if (typeof url == 'string') {
+          Browser.asyncLoad(url, function(byteArray) {
+            processData(byteArray);
+          }, onerror);
+        } else {
+          processData(url);
+        }
+      },indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_NAME:function () {
+        return 'EM_FS_' + window.location.pathname;
+      },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
+          console.log('creating db');
+          var db = openRequest.result;
+          db.createObjectStore(FS.DB_STORE_NAME);
+        };
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var putRequest = files.put(FS.analyzePath(path).object.contents, path);
+            putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
+            putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      },loadFilesFromDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = onerror; // no database to load from
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          try {
+            var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
+          } catch(e) {
+            onerror(e);
+            return;
+          }
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var getRequest = files.get(path);
+            getRequest.onsuccess = function getRequest_onsuccess() {
+              if (FS.analyzePath(path).exists) {
+                FS.unlink(path);
+              }
+              FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
+              ok++;
+              if (ok + fail == total) finish();
+            };
+            getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      }};
+
+
+
+
+  function _mkport() { throw 'TODO' }var SOCKFS={mount:function (mount) {
+        return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createSocket:function (family, type, protocol) {
+        var streaming = type == 1;
+        if (protocol) {
+          assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp
+        }
+
+        // create our internal socket structure
+        var sock = {
+          family: family,
+          type: type,
+          protocol: protocol,
+          server: null,
+          peers: {},
+          pending: [],
+          recv_queue: [],
+          sock_ops: SOCKFS.websocket_sock_ops
+        };
+
+        // create the filesystem node to store the socket structure
+        var name = SOCKFS.nextname();
+        var node = FS.createNode(SOCKFS.root, name, 49152, 0);
+        node.sock = sock;
+
+        // and the wrapping stream that enables library functions such
+        // as read and write to indirectly interact with the socket
+        var stream = FS.createStream({
+          path: name,
+          node: node,
+          flags: FS.modeStringToFlags('r+'),
+          seekable: false,
+          stream_ops: SOCKFS.stream_ops
+        });
+
+        // map the new stream to the socket structure (sockets have a 1:1
+        // relationship with a stream)
+        sock.stream = stream;
+
+        return sock;
+      },getSocket:function (fd) {
+        var stream = FS.getStream(fd);
+        if (!stream || !FS.isSocket(stream.node.mode)) {
+          return null;
+        }
+        return stream.node.sock;
+      },stream_ops:{poll:function (stream) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.poll(sock);
+        },ioctl:function (stream, request, varargs) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.ioctl(sock, request, varargs);
+        },read:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          var msg = sock.sock_ops.recvmsg(sock, length);
+          if (!msg) {
+            // socket is closed
+            return 0;
+          }
+          buffer.set(msg.buffer, offset);
+          return msg.buffer.length;
+        },write:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.sendmsg(sock, buffer, offset, length);
+        },close:function (stream) {
+          var sock = stream.node.sock;
+          sock.sock_ops.close(sock);
+        }},nextname:function () {
+        if (!SOCKFS.nextname.current) {
+          SOCKFS.nextname.current = 0;
+        }
+        return 'socket[' + (SOCKFS.nextname.current++) + ']';
+      },websocket_sock_ops:{createPeer:function (sock, addr, port) {
+          var ws;
+
+          if (typeof addr === 'object') {
+            ws = addr;
+            addr = null;
+            port = null;
+          }
+
+          if (ws) {
+            // for sockets that've already connected (e.g. we're the server)
+            // we can inspect the _socket property for the address
+            if (ws._socket) {
+              addr = ws._socket.remoteAddress;
+              port = ws._socket.remotePort;
+            }
+            // if we're just now initializing a connection to the remote,
+            // inspect the url property
+            else {
+              var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
+              if (!result) {
+                throw new Error('WebSocket URL must be in the format ws(s)://address:port');
+              }
+              addr = result[1];
+              port = parseInt(result[2], 10);
+            }
+          } else {
+            // create the actual websocket object and connect
+            try {
+              // runtimeConfig gets set to true if WebSocket runtime configuration is available.
+              var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
+
+              // The default value is 'ws://' the replace is needed because the compiler replaces "//" comments with '#'
+              // comments without checking context, so we'd end up with ws:#, the replace swaps the "#" for "//" again.
+              var url = 'ws:#'.replace('#', '//');
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['url']) {
+                  url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
+                }
+              }
+
+              if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
+                url = url + addr + ':' + port;
+              }
+
+              // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
+              var subProtocols = 'binary'; // The default value is 'binary'
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['subprotocol']) {
+                  subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
+                }
+              }
+
+              // The regex trims the string (removes spaces at the beginning and end, then splits the string by
+              // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
+              subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
+
+              // The node ws library API for specifying optional subprotocol is slightly different than the browser's.
+              var opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols;
+
+              // If node we use the ws library.
+              var WebSocket = ENVIRONMENT_IS_NODE ? require('ws') : window['WebSocket'];
+              ws = new WebSocket(url, opts);
+              ws.binaryType = 'arraybuffer';
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH);
+            }
+          }
+
+
+          var peer = {
+            addr: addr,
+            port: port,
+            socket: ws,
+            dgram_send_queue: []
+          };
+
+          SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+          SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
+
+          // if this is a bound dgram socket, send the port number first to allow
+          // us to override the ephemeral port reported to us by remotePort on the
+          // remote end.
+          if (sock.type === 2 && typeof sock.sport !== 'undefined') {
+            peer.dgram_send_queue.push(new Uint8Array([
+                255, 255, 255, 255,
+                'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
+                ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
+            ]));
+          }
+
+          return peer;
+        },getPeer:function (sock, addr, port) {
+          return sock.peers[addr + ':' + port];
+        },addPeer:function (sock, peer) {
+          sock.peers[peer.addr + ':' + peer.port] = peer;
+        },removePeer:function (sock, peer) {
+          delete sock.peers[peer.addr + ':' + peer.port];
+        },handlePeerEvents:function (sock, peer) {
+          var first = true;
+
+          var handleOpen = function () {
+            try {
+              var queued = peer.dgram_send_queue.shift();
+              while (queued) {
+                peer.socket.send(queued);
+                queued = peer.dgram_send_queue.shift();
+              }
+            } catch (e) {
+              // not much we can do here in the way of proper error handling as we've already
+              // lied and said this data was sent. shut it down.
+              peer.socket.close();
+            }
+          };
+
+          function handleMessage(data) {
+            assert(typeof data !== 'string' && data.byteLength !== undefined);  // must receive an ArrayBuffer
+            data = new Uint8Array(data);  // make a typed array view on the array buffer
+
+
+            // if this is the port message, override the peer's port with it
+            var wasfirst = first;
+            first = false;
+            if (wasfirst &&
+                data.length === 10 &&
+                data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
+                data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
+              // update the peer's port and it's key in the peer map
+              var newport = ((data[8] << 8) | data[9]);
+              SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+              peer.port = newport;
+              SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+              return;
+            }
+
+            sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
+          };
+
+          if (ENVIRONMENT_IS_NODE) {
+            peer.socket.on('open', handleOpen);
+            peer.socket.on('message', function(data, flags) {
+              if (!flags.binary) {
+                return;
+              }
+              handleMessage((new Uint8Array(data)).buffer);  // copy from node Buffer -> ArrayBuffer
+            });
+            peer.socket.on('error', function() {
+              // don't throw
+            });
+          } else {
+            peer.socket.onopen = handleOpen;
+            peer.socket.onmessage = function peer_socket_onmessage(event) {
+              handleMessage(event.data);
+            };
+          }
+        },poll:function (sock) {
+          if (sock.type === 1 && sock.server) {
+            // listen sockets should only say they're available for reading
+            // if there are pending clients.
+            return sock.pending.length ? (64 | 1) : 0;
+          }
+
+          var mask = 0;
+          var dest = sock.type === 1 ?  // we only care about the socket state for connection-based sockets
+            SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
+            null;
+
+          if (sock.recv_queue.length ||
+              !dest ||  // connection-less sockets are always ready to read
+              (dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {  // let recv return 0 once closed
+            mask |= (64 | 1);
+          }
+
+          if (!dest ||  // connection-less sockets are always ready to write
+              (dest && dest.socket.readyState === dest.socket.OPEN)) {
+            mask |= 4;
+          }
+
+          if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {
+            mask |= 16;
+          }
+
+          return mask;
+        },ioctl:function (sock, request, arg) {
+          switch (request) {
+            case 21531:
+              var bytes = 0;
+              if (sock.recv_queue.length) {
+                bytes = sock.recv_queue[0].data.length;
+              }
+              HEAP32[((arg)>>2)]=bytes;
+              return 0;
+            default:
+              return ERRNO_CODES.EINVAL;
+          }
+        },close:function (sock) {
+          // if we've spawned a listen server, close it
+          if (sock.server) {
+            try {
+              sock.server.close();
+            } catch (e) {
+            }
+            sock.server = null;
+          }
+          // close any peer connections
+          var peers = Object.keys(sock.peers);
+          for (var i = 0; i < peers.length; i++) {
+            var peer = sock.peers[peers[i]];
+            try {
+              peer.socket.close();
+            } catch (e) {
+            }
+            SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+          }
+          return 0;
+        },bind:function (sock, addr, port) {
+          if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already bound
+          }
+          sock.saddr = addr;
+          sock.sport = port || _mkport();
+          // in order to emulate dgram sockets, we need to launch a listen server when
+          // binding on a connection-less socket
+          // note: this is only required on the server side
+          if (sock.type === 2) {
+            // close the existing server if it exists
+            if (sock.server) {
+              sock.server.close();
+              sock.server = null;
+            }
+            // swallow error operation not supported error that occurs when binding in the
+            // browser where this isn't supported
+            try {
+              sock.sock_ops.listen(sock, 0);
+            } catch (e) {
+              if (!(e instanceof FS.ErrnoError)) throw e;
+              if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e;
+            }
+          }
+        },connect:function (sock, addr, port) {
+          if (sock.server) {
+            throw new FS.ErrnoError(ERRNO_CODS.EOPNOTSUPP);
+          }
+
+          // TODO autobind
+          // if (!sock.addr && sock.type == 2) {
+          // }
+
+          // early out if we're already connected / in the middle of connecting
+          if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') {
+            var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+            if (dest) {
+              if (dest.socket.readyState === dest.socket.CONNECTING) {
+                throw new FS.ErrnoError(ERRNO_CODES.EALREADY);
+              } else {
+                throw new FS.ErrnoError(ERRNO_CODES.EISCONN);
+              }
+            }
+          }
+
+          // add the socket to our peer list and set our
+          // destination address / port to match
+          var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+          sock.daddr = peer.addr;
+          sock.dport = peer.port;
+
+          // always "fail" in non-blocking mode
+          throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS);
+        },listen:function (sock, backlog) {
+          if (!ENVIRONMENT_IS_NODE) {
+            throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+          }
+          if (sock.server) {
+             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already listening
+          }
+          var WebSocketServer = require('ws').Server;
+          var host = sock.saddr;
+          sock.server = new WebSocketServer({
+            host: host,
+            port: sock.sport
+            // TODO support backlog
+          });
+
+          sock.server.on('connection', function(ws) {
+            if (sock.type === 1) {
+              var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
+
+              // create a peer on the new socket
+              var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
+              newsock.daddr = peer.addr;
+              newsock.dport = peer.port;
+
+              // push to queue for accept to pick up
+              sock.pending.push(newsock);
+            } else {
+              // create a peer on the listen socket so calling sendto
+              // with the listen socket and an address will resolve
+              // to the correct client
+              SOCKFS.websocket_sock_ops.createPeer(sock, ws);
+            }
+          });
+          sock.server.on('closed', function() {
+            sock.server = null;
+          });
+          sock.server.on('error', function() {
+            // don't throw
+          });
+        },accept:function (listensock) {
+          if (!listensock.server) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          var newsock = listensock.pending.shift();
+          newsock.stream.flags = listensock.stream.flags;
+          return newsock;
+        },getname:function (sock, peer) {
+          var addr, port;
+          if (peer) {
+            if (sock.daddr === undefined || sock.dport === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            }
+            addr = sock.daddr;
+            port = sock.dport;
+          } else {
+            // TODO saddr and sport will be set for bind()'d UDP sockets, but what
+            // should we be returning for TCP sockets that've been connect()'d?
+            addr = sock.saddr || 0;
+            port = sock.sport || 0;
+          }
+          return { addr: addr, port: port };
+        },sendmsg:function (sock, buffer, offset, length, addr, port) {
+          if (sock.type === 2) {
+            // connection-less sockets will honor the message address,
+            // and otherwise fall back to the bound destination address
+            if (addr === undefined || port === undefined) {
+              addr = sock.daddr;
+              port = sock.dport;
+            }
+            // if there was no address to fall back to, error out
+            if (addr === undefined || port === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ);
+            }
+          } else {
+            // connection-based sockets will only use the bound
+            addr = sock.daddr;
+            port = sock.dport;
+          }
+
+          // find the peer for the destination address
+          var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
+
+          // early out if not connected with a connection-based socket
+          if (sock.type === 1) {
+            if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            } else if (dest.socket.readyState === dest.socket.CONNECTING) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // create a copy of the incoming data to send, as the WebSocket API
+          // doesn't work entirely with an ArrayBufferView, it'll just send
+          // the entire underlying buffer
+          var data;
+          if (buffer instanceof Array || buffer instanceof ArrayBuffer) {
+            data = buffer.slice(offset, offset + length);
+          } else {  // ArrayBufferView
+            data = buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + length);
+          }
+
+          // if we're emulating a connection-less dgram socket and don't have
+          // a cached connection, queue the buffer to send upon connect and
+          // lie, saying the data was sent now.
+          if (sock.type === 2) {
+            if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
+              // if we're not connected, open a new connection
+              if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+              }
+              dest.dgram_send_queue.push(data);
+              return length;
+            }
+          }
+
+          try {
+            // send the actual data
+            dest.socket.send(data);
+            return length;
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+        },recvmsg:function (sock, length) {
+          // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
+          if (sock.type === 1 && sock.server) {
+            // tcp servers should not be recv()'ing on the listen socket
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+          }
+
+          var queued = sock.recv_queue.shift();
+          if (!queued) {
+            if (sock.type === 1) {
+              var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+
+              if (!dest) {
+                // if we have a destination address but are not connected, error out
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+              }
+              else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                // return null if the socket has closed
+                return null;
+              }
+              else {
+                // else, our socket is in a valid state but truly has nothing available
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+            } else {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
+          // requeued TCP data it'll be an ArrayBufferView
+          var queuedLength = queued.data.byteLength || queued.data.length;
+          var queuedOffset = queued.data.byteOffset || 0;
+          var queuedBuffer = queued.data.buffer || queued.data;
+          var bytesRead = Math.min(length, queuedLength);
+          var res = {
+            buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
+            addr: queued.addr,
+            port: queued.port
+          };
+
+
+          // push back any unread data for TCP connections
+          if (sock.type === 1 && bytesRead < queuedLength) {
+            var bytesRemaining = queuedLength - bytesRead;
+            queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
+            sock.recv_queue.unshift(queued);
+          }
+
+          return res;
+        }}};function _send(fd, buf, len, flags) {
+      var sock = SOCKFS.getSocket(fd);
+      if (!sock) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      // TODO honor flags
+      return _write(fd, buf, len);
+    }
+
+  function _pwrite(fildes, buf, nbyte, offset) {
+      // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte, offset);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _write(fildes, buf, nbyte) {
+      // ssize_t write(int fildes, const void *buf, size_t nbyte);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+
+
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }
+
+  function _fileno(stream) {
+      // int fileno(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
+      stream = FS.getStreamFromPtr(stream);
+      if (!stream) return -1;
+      return stream.fd;
+    }function _fwrite(ptr, size, nitems, stream) {
+      // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
+      var bytesToWrite = nitems * size;
+      if (bytesToWrite == 0) return 0;
+      var fd = _fileno(stream);
+      var bytesWritten = _write(fd, ptr, bytesToWrite);
+      if (bytesWritten == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return 0;
+      } else {
+        return Math.floor(bytesWritten / size);
+      }
+    }
+
+
+
+  Module["_strlen"] = _strlen;
+
+  function __reallyNegative(x) {
+      return x < 0 || (x === 0 && (1/x) === -Infinity);
+    }function __formatString(format, varargs) {
+      var textIndex = format;
+      var argIndex = 0;
+      function getNextArg(type) {
+        // NOTE: Explicitly ignoring type safety. Otherwise this fails:
+        //       int x = 4; printf("%c\n", (char)x);
+        var ret;
+        if (type === 'double') {
+          ret = HEAPF64[(((varargs)+(argIndex))>>3)];
+        } else if (type == 'i64') {
+          ret = [HEAP32[(((varargs)+(argIndex))>>2)],
+                 HEAP32[(((varargs)+(argIndex+4))>>2)]];
+
+        } else {
+          type = 'i32'; // varargs are always i32, i64, or double
+          ret = HEAP32[(((varargs)+(argIndex))>>2)];
+        }
+        argIndex += Runtime.getNativeFieldSize(type);
+        return ret;
+      }
+
+      var ret = [];
+      var curr, next, currArg;
+      while(1) {
+        var startTextIndex = textIndex;
+        curr = HEAP8[(textIndex)];
+        if (curr === 0) break;
+        next = HEAP8[((textIndex+1)|0)];
+        if (curr == 37) {
+          // Handle flags.
+          var flagAlwaysSigned = false;
+          var flagLeftAlign = false;
+          var flagAlternative = false;
+          var flagZeroPad = false;
+          var flagPadSign = false;
+          flagsLoop: while (1) {
+            switch (next) {
+              case 43:
+                flagAlwaysSigned = true;
+                break;
+              case 45:
+                flagLeftAlign = true;
+                break;
+              case 35:
+                flagAlternative = true;
+                break;
+              case 48:
+                if (flagZeroPad) {
+                  break flagsLoop;
+                } else {
+                  flagZeroPad = true;
+                  break;
+                }
+              case 32:
+                flagPadSign = true;
+                break;
+              default:
+                break flagsLoop;
+            }
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          }
+
+          // Handle width.
+          var width = 0;
+          if (next == 42) {
+            width = getNextArg('i32');
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          } else {
+            while (next >= 48 && next <= 57) {
+              width = width * 10 + (next - 48);
+              textIndex++;
+              next = HEAP8[((textIndex+1)|0)];
+            }
+          }
+
+          // Handle precision.
+          var precisionSet = false, precision = -1;
+          if (next == 46) {
+            precision = 0;
+            precisionSet = true;
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+            if (next == 42) {
+              precision = getNextArg('i32');
+              textIndex++;
+            } else {
+              while(1) {
+                var precisionChr = HEAP8[((textIndex+1)|0)];
+                if (precisionChr < 48 ||
+                    precisionChr > 57) break;
+                precision = precision * 10 + (precisionChr - 48);
+                textIndex++;
+              }
+            }
+            next = HEAP8[((textIndex+1)|0)];
+          }
+          if (precision < 0) {
+            precision = 6; // Standard default.
+            precisionSet = false;
+          }
+
+          // Handle integer sizes. WARNING: These assume a 32-bit architecture!
+          var argSize;
+          switch (String.fromCharCode(next)) {
+            case 'h':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 104) {
+                textIndex++;
+                argSize = 1; // char (actually i32 in varargs)
+              } else {
+                argSize = 2; // short (actually i32 in varargs)
+              }
+              break;
+            case 'l':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 108) {
+                textIndex++;
+                argSize = 8; // long long
+              } else {
+                argSize = 4; // long
+              }
+              break;
+            case 'L': // long long
+            case 'q': // int64_t
+            case 'j': // intmax_t
+              argSize = 8;
+              break;
+            case 'z': // size_t
+            case 't': // ptrdiff_t
+            case 'I': // signed ptrdiff_t or unsigned size_t
+              argSize = 4;
+              break;
+            default:
+              argSize = null;
+          }
+          if (argSize) textIndex++;
+          next = HEAP8[((textIndex+1)|0)];
+
+          // Handle type specifier.
+          switch (String.fromCharCode(next)) {
+            case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': {
+              // Integer.
+              var signed = next == 100 || next == 105;
+              argSize = argSize || 4;
+              var currArg = getNextArg('i' + (argSize * 8));
+              var argText;
+              // Flatten i64-1 [low, high] into a (slightly rounded) double
+              if (argSize == 8) {
+                currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117);
+              }
+              // Truncate to requested size.
+              if (argSize <= 4) {
+                var limit = Math.pow(256, argSize) - 1;
+                currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
+              }
+              // Format the number.
+              var currAbsArg = Math.abs(currArg);
+              var prefix = '';
+              if (next == 100 || next == 105) {
+                argText = reSign(currArg, 8 * argSize, 1).toString(10);
+              } else if (next == 117) {
+                argText = unSign(currArg, 8 * argSize, 1).toString(10);
+                currArg = Math.abs(currArg);
+              } else if (next == 111) {
+                argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
+              } else if (next == 120 || next == 88) {
+                prefix = (flagAlternative && currArg != 0) ? '0x' : '';
+                if (currArg < 0) {
+                  // Represent negative numbers in hex as 2's complement.
+                  currArg = -currArg;
+                  argText = (currAbsArg - 1).toString(16);
+                  var buffer = [];
+                  for (var i = 0; i < argText.length; i++) {
+                    buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
+                  }
+                  argText = buffer.join('');
+                  while (argText.length < argSize * 2) argText = 'f' + argText;
+                } else {
+                  argText = currAbsArg.toString(16);
+                }
+                if (next == 88) {
+                  prefix = prefix.toUpperCase();
+                  argText = argText.toUpperCase();
+                }
+              } else if (next == 112) {
+                if (currAbsArg === 0) {
+                  argText = '(nil)';
+                } else {
+                  prefix = '0x';
+                  argText = currAbsArg.toString(16);
+                }
+              }
+              if (precisionSet) {
+                while (argText.length < precision) {
+                  argText = '0' + argText;
+                }
+              }
+
+              // Add sign if needed
+              if (currArg >= 0) {
+                if (flagAlwaysSigned) {
+                  prefix = '+' + prefix;
+                } else if (flagPadSign) {
+                  prefix = ' ' + prefix;
+                }
+              }
+
+              // Move sign to prefix so we zero-pad after the sign
+              if (argText.charAt(0) == '-') {
+                prefix = '-' + prefix;
+                argText = argText.substr(1);
+              }
+
+              // Add padding.
+              while (prefix.length + argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad) {
+                    argText = '0' + argText;
+                  } else {
+                    prefix = ' ' + prefix;
+                  }
+                }
+              }
+
+              // Insert the result into the buffer.
+              argText = prefix + argText;
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': {
+              // Float.
+              var currArg = getNextArg('double');
+              var argText;
+              if (isNaN(currArg)) {
+                argText = 'nan';
+                flagZeroPad = false;
+              } else if (!isFinite(currArg)) {
+                argText = (currArg < 0 ? '-' : '') + 'inf';
+                flagZeroPad = false;
+              } else {
+                var isGeneral = false;
+                var effectivePrecision = Math.min(precision, 20);
+
+                // Convert g/G to f/F or e/E, as per:
+                // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
+                if (next == 103 || next == 71) {
+                  isGeneral = true;
+                  precision = precision || 1;
+                  var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
+                  if (precision > exponent && exponent >= -4) {
+                    next = ((next == 103) ? 'f' : 'F').charCodeAt(0);
+                    precision -= exponent + 1;
+                  } else {
+                    next = ((next == 103) ? 'e' : 'E').charCodeAt(0);
+                    precision--;
+                  }
+                  effectivePrecision = Math.min(precision, 20);
+                }
+
+                if (next == 101 || next == 69) {
+                  argText = currArg.toExponential(effectivePrecision);
+                  // Make sure the exponent has at least 2 digits.
+                  if (/[eE][-+]\d$/.test(argText)) {
+                    argText = argText.slice(0, -1) + '0' + argText.slice(-1);
+                  }
+                } else if (next == 102 || next == 70) {
+                  argText = currArg.toFixed(effectivePrecision);
+                  if (currArg === 0 && __reallyNegative(currArg)) {
+                    argText = '-' + argText;
+                  }
+                }
+
+                var parts = argText.split('e');
+                if (isGeneral && !flagAlternative) {
+                  // Discard trailing zeros and periods.
+                  while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
+                         (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
+                    parts[0] = parts[0].slice(0, -1);
+                  }
+                } else {
+                  // Make sure we have a period in alternative mode.
+                  if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
+                  // Zero pad until required precision.
+                  while (precision > effectivePrecision++) parts[0] += '0';
+                }
+                argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
+
+                // Capitalize 'E' if needed.
+                if (next == 69) argText = argText.toUpperCase();
+
+                // Add sign.
+                if (currArg >= 0) {
+                  if (flagAlwaysSigned) {
+                    argText = '+' + argText;
+                  } else if (flagPadSign) {
+                    argText = ' ' + argText;
+                  }
+                }
+              }
+
+              // Add padding.
+              while (argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
+                    argText = argText[0] + '0' + argText.slice(1);
+                  } else {
+                    argText = (flagZeroPad ? '0' : ' ') + argText;
+                  }
+                }
+              }
+
+              // Adjust case.
+              if (next < 97) argText = argText.toUpperCase();
+
+              // Insert the result into the buffer.
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 's': {
+              // String.
+              var arg = getNextArg('i8*');
+              var argLength = arg ? _strlen(arg) : '(null)'.length;
+              if (precisionSet) argLength = Math.min(argLength, precision);
+              if (!flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              if (arg) {
+                for (var i = 0; i < argLength; i++) {
+                  ret.push(HEAPU8[((arg++)|0)]);
+                }
+              } else {
+                ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true));
+              }
+              if (flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              break;
+            }
+            case 'c': {
+              // Character.
+              if (flagLeftAlign) ret.push(getNextArg('i8'));
+              while (--width > 0) {
+                ret.push(32);
+              }
+              if (!flagLeftAlign) ret.push(getNextArg('i8'));
+              break;
+            }
+            case 'n': {
+              // Write the length written so far to the next parameter.
+              var ptr = getNextArg('i32*');
+              HEAP32[((ptr)>>2)]=ret.length;
+              break;
+            }
+            case '%': {
+              // Literal percent sign.
+              ret.push(curr);
+              break;
+            }
+            default: {
+              // Unknown specifiers remain untouched.
+              for (var i = startTextIndex; i < textIndex + 2; i++) {
+                ret.push(HEAP8[(i)]);
+              }
+            }
+          }
+          textIndex += 2;
+          // TODO: Support a/A (hex float) and m (last error) specifiers.
+          // TODO: Support %1${specifier} for arg selection.
+        } else {
+          ret.push(curr);
+          textIndex += 1;
+        }
+      }
+      return ret;
+    }function _fprintf(stream, format, varargs) {
+      // int fprintf(FILE *restrict stream, const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var result = __formatString(format, varargs);
+      var stack = Runtime.stackSave();
+      var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream);
+      Runtime.stackRestore(stack);
+      return ret;
+    }function _printf(format, varargs) {
+      // int printf(const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var stdout = HEAP32[((_stdout)>>2)];
+      return _fprintf(stdout, format, varargs);
+    }
+
+
+  function _fputc(c, stream) {
+      // int fputc(int c, FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fputc.html
+      var chr = unSign(c & 0xFF);
+      HEAP8[((_fputc.ret)|0)]=chr;
+      var fd = _fileno(stream);
+      var ret = _write(fd, _fputc.ret, 1);
+      if (ret == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return -1;
+      } else {
+        return chr;
+      }
+    }function _putchar(c) {
+      // int putchar(int c);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/putchar.html
+      return _fputc(c, HEAP32[((_stdout)>>2)]);
+    }
+
+  function _sbrk(bytes) {
+      // Implement a Linux-like 'memory area' for our 'process'.
+      // Changes the size of the memory area by |bytes|; returns the
+      // address of the previous top ('break') of the memory area
+      // We control the "dynamic" memory - DYNAMIC_BASE to DYNAMICTOP
+      var self = _sbrk;
+      if (!self.called) {
+        DYNAMICTOP = alignMemoryPage(DYNAMICTOP); // make sure we start out aligned
+        self.called = true;
+        assert(Runtime.dynamicAlloc);
+        self.alloc = Runtime.dynamicAlloc;
+        Runtime.dynamicAlloc = function() { abort('cannot dynamically allocate, sbrk now has control') };
+      }
+      var ret = DYNAMICTOP;
+      if (bytes != 0) self.alloc(bytes);
+      return ret;  // Previous break location.
+    }
+
+  function _sysconf(name) {
+      // long sysconf(int name);
+      // http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html
+      switch(name) {
+        case 30: return PAGE_SIZE;
+        case 132:
+        case 133:
+        case 12:
+        case 137:
+        case 138:
+        case 15:
+        case 235:
+        case 16:
+        case 17:
+        case 18:
+        case 19:
+        case 20:
+        case 149:
+        case 13:
+        case 10:
+        case 236:
+        case 153:
+        case 9:
+        case 21:
+        case 22:
+        case 159:
+        case 154:
+        case 14:
+        case 77:
+        case 78:
+        case 139:
+        case 80:
+        case 81:
+        case 79:
+        case 82:
+        case 68:
+        case 67:
+        case 164:
+        case 11:
+        case 29:
+        case 47:
+        case 48:
+        case 95:
+        case 52:
+        case 51:
+        case 46:
+          return 200809;
+        case 27:
+        case 246:
+        case 127:
+        case 128:
+        case 23:
+        case 24:
+        case 160:
+        case 161:
+        case 181:
+        case 182:
+        case 242:
+        case 183:
+        case 184:
+        case 243:
+        case 244:
+        case 245:
+        case 165:
+        case 178:
+        case 179:
+        case 49:
+        case 50:
+        case 168:
+        case 169:
+        case 175:
+        case 170:
+        case 171:
+        case 172:
+        case 97:
+        case 76:
+        case 32:
+        case 173:
+        case 35:
+          return -1;
+        case 176:
+        case 177:
+        case 7:
+        case 155:
+        case 8:
+        case 157:
+        case 125:
+        case 126:
+        case 92:
+        case 93:
+        case 129:
+        case 130:
+        case 131:
+        case 94:
+        case 91:
+          return 1;
+        case 74:
+        case 60:
+        case 69:
+        case 70:
+        case 4:
+          return 1024;
+        case 31:
+        case 42:
+        case 72:
+          return 32;
+        case 87:
+        case 26:
+        case 33:
+          return 2147483647;
+        case 34:
+        case 1:
+          return 47839;
+        case 38:
+        case 36:
+          return 99;
+        case 43:
+        case 37:
+          return 2048;
+        case 0: return 2097152;
+        case 3: return 65536;
+        case 28: return 32768;
+        case 44: return 32767;
+        case 75: return 16384;
+        case 39: return 1000;
+        case 89: return 700;
+        case 71: return 256;
+        case 40: return 255;
+        case 2: return 100;
+        case 180: return 64;
+        case 25: return 20;
+        case 5: return 16;
+        case 6: return 6;
+        case 73: return 4;
+        case 84: return 1;
+      }
+      ___setErrNo(ERRNO_CODES.EINVAL);
+      return -1;
+    }
+
+
+  Module["_memset"] = _memset;
+
+  function ___errno_location() {
+      return ___errno_state;
+    }
+
+  function _abort() {
+      Module['abort']();
+    }
+
+  var Browser={mainLoop:{scheduler:null,method:"",shouldPause:false,paused:false,queue:[],pause:function () {
+          Browser.mainLoop.shouldPause = true;
+        },resume:function () {
+          if (Browser.mainLoop.paused) {
+            Browser.mainLoop.paused = false;
+            Browser.mainLoop.scheduler();
+          }
+          Browser.mainLoop.shouldPause = false;
+        },updateStatus:function () {
+          if (Module['setStatus']) {
+            var message = Module['statusMessage'] || 'Please wait...';
+            var remaining = Browser.mainLoop.remainingBlockers;
+            var expected = Browser.mainLoop.expectedBlockers;
+            if (remaining) {
+              if (remaining < expected) {
+                Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
+              } else {
+                Module['setStatus'](message);
+              }
+            } else {
+              Module['setStatus']('');
+            }
+          }
+        }},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () {
+        if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
+
+        if (Browser.initted || ENVIRONMENT_IS_WORKER) return;
+        Browser.initted = true;
+
+        try {
+          new Blob();
+          Browser.hasBlobConstructor = true;
+        } catch(e) {
+          Browser.hasBlobConstructor = false;
+          console.log("warning: no blob constructor, cannot create blobs with mimetypes");
+        }
+        Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
+        Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
+        if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
+          console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
+          Module.noImageDecoding = true;
+        }
+
+        // Support for plugins that can process preloaded files. You can add more of these to
+        // your app by creating and appending to Module.preloadPlugins.
+        //
+        // Each plugin is asked if it can handle a file based on the file's name. If it can,
+        // it is given the file's raw data. When it is done, it calls a callback with the file's
+        // (possibly modified) data. For example, a plugin might decompress a file, or it
+        // might create some side data structure for use later (like an Image element, etc.).
+
+        var imagePlugin = {};
+        imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
+          return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
+        };
+        imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
+          var b = null;
+          if (Browser.hasBlobConstructor) {
+            try {
+              b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+              if (b.size !== byteArray.length) { // Safari bug #118630
+                // Safari's Blob can only take an ArrayBuffer
+                b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
+              }
+            } catch(e) {
+              Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
+            }
+          }
+          if (!b) {
+            var bb = new Browser.BlobBuilder();
+            bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
+            b = bb.getBlob();
+          }
+          var url = Browser.URLObject.createObjectURL(b);
+          var img = new Image();
+          img.onload = function img_onload() {
+            assert(img.complete, 'Image ' + name + ' could not be decoded');
+            var canvas = document.createElement('canvas');
+            canvas.width = img.width;
+            canvas.height = img.height;
+            var ctx = canvas.getContext('2d');
+            ctx.drawImage(img, 0, 0);
+            Module["preloadedImages"][name] = canvas;
+            Browser.URLObject.revokeObjectURL(url);
+            if (onload) onload(byteArray);
+          };
+          img.onerror = function img_onerror(event) {
+            console.log('Image ' + url + ' could not be decoded');
+            if (onerror) onerror();
+          };
+          img.src = url;
+        };
+        Module['preloadPlugins'].push(imagePlugin);
+
+        var audioPlugin = {};
+        audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
+          return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
+        };
+        audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
+          var done = false;
+          function finish(audio) {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = audio;
+            if (onload) onload(byteArray);
+          }
+          function fail() {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = new Audio(); // empty shim
+            if (onerror) onerror();
+          }
+          if (Browser.hasBlobConstructor) {
+            try {
+              var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+            } catch(e) {
+              return fail();
+            }
+            var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
+            var audio = new Audio();
+            audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926
+            audio.onerror = function audio_onerror(event) {
+              if (done) return;
+              console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
+              function encode64(data) {
+                var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+                var PAD = '=';
+                var ret = '';
+                var leftchar = 0;
+                var leftbits = 0;
+                for (var i = 0; i < data.length; i++) {
+                  leftchar = (leftchar << 8) | data[i];
+                  leftbits += 8;
+                  while (leftbits >= 6) {
+                    var curr = (leftchar >> (leftbits-6)) & 0x3f;
+                    leftbits -= 6;
+                    ret += BASE[curr];
+                  }
+                }
+                if (leftbits == 2) {
+                  ret += BASE[(leftchar&3) << 4];
+                  ret += PAD + PAD;
+                } else if (leftbits == 4) {
+                  ret += BASE[(leftchar&0xf) << 2];
+                  ret += PAD;
+                }
+                return ret;
+              }
+              audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
+              finish(audio); // we don't wait for confirmation this worked - but it's worth trying
+            };
+            audio.src = url;
+            // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
+            Browser.safeSetTimeout(function() {
+              finish(audio); // try to use it even though it is not necessarily ready to play
+            }, 10000);
+          } else {
+            return fail();
+          }
+        };
+        Module['preloadPlugins'].push(audioPlugin);
+
+        // Canvas event setup
+
+        var canvas = Module['canvas'];
+
+        // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
+        // Module['forcedAspectRatio'] = 4 / 3;
+
+        canvas.requestPointerLock = canvas['requestPointerLock'] ||
+                                    canvas['mozRequestPointerLock'] ||
+                                    canvas['webkitRequestPointerLock'] ||
+                                    canvas['msRequestPointerLock'] ||
+                                    function(){};
+        canvas.exitPointerLock = document['exitPointerLock'] ||
+                                 document['mozExitPointerLock'] ||
+                                 document['webkitExitPointerLock'] ||
+                                 document['msExitPointerLock'] ||
+                                 function(){}; // no-op if function does not exist
+        canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
+
+        function pointerLockChange() {
+          Browser.pointerLock = document['pointerLockElement'] === canvas ||
+                                document['mozPointerLockElement'] === canvas ||
+                                document['webkitPointerLockElement'] === canvas ||
+                                document['msPointerLockElement'] === canvas;
+        }
+
+        document.addEventListener('pointerlockchange', pointerLockChange, false);
+        document.addEventListener('mozpointerlockchange', pointerLockChange, false);
+        document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
+        document.addEventListener('mspointerlockchange', pointerLockChange, false);
+
+        if (Module['elementPointerLock']) {
+          canvas.addEventListener("click", function(ev) {
+            if (!Browser.pointerLock && canvas.requestPointerLock) {
+              canvas.requestPointerLock();
+              ev.preventDefault();
+            }
+          }, false);
+        }
+      },createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) {
+        var ctx;
+        var errorInfo = '?';
+        function onContextCreationError(event) {
+          errorInfo = event.statusMessage || errorInfo;
+        }
+        try {
+          if (useWebGL) {
+            var contextAttributes = {
+              antialias: false,
+              alpha: false
+            };
+
+            if (webGLContextAttributes) {
+              for (var attribute in webGLContextAttributes) {
+                contextAttributes[attribute] = webGLContextAttributes[attribute];
+              }
+            }
+
+
+            canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
+            try {
+              ['experimental-webgl', 'webgl'].some(function(webglId) {
+                return ctx = canvas.getContext(webglId, contextAttributes);
+              });
+            } finally {
+              canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
+            }
+          } else {
+            ctx = canvas.getContext('2d');
+          }
+          if (!ctx) throw ':(';
+        } catch (e) {
+          Module.print('Could not create canvas: ' + [errorInfo, e]);
+          return null;
+        }
+        if (useWebGL) {
+          // Set the background of the WebGL canvas to black
+          canvas.style.backgroundColor = "black";
+
+          // Warn on context loss
+          canvas.addEventListener('webglcontextlost', function(event) {
+            alert('WebGL context lost. You will need to reload the page.');
+          }, false);
+        }
+        if (setInModule) {
+          GLctx = Module.ctx = ctx;
+          Module.useWebGL = useWebGL;
+          Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
+          Browser.init();
+        }
+        return ctx;
+      },destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) {
+        Browser.lockPointer = lockPointer;
+        Browser.resizeCanvas = resizeCanvas;
+        if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;
+        if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;
+
+        var canvas = Module['canvas'];
+        function fullScreenChange() {
+          Browser.isFullScreen = false;
+          var canvasContainer = canvas.parentNode;
+          if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+               document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+               document['fullScreenElement'] || document['fullscreenElement'] ||
+               document['msFullScreenElement'] || document['msFullscreenElement'] ||
+               document['webkitCurrentFullScreenElement']) === canvasContainer) {
+            canvas.cancelFullScreen = document['cancelFullScreen'] ||
+                                      document['mozCancelFullScreen'] ||
+                                      document['webkitCancelFullScreen'] ||
+                                      document['msExitFullscreen'] ||
+                                      document['exitFullscreen'] ||
+                                      function() {};
+            canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document);
+            if (Browser.lockPointer) canvas.requestPointerLock();
+            Browser.isFullScreen = true;
+            if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize();
+          } else {
+
+            // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
+            canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
+            canvasContainer.parentNode.removeChild(canvasContainer);
+
+            if (Browser.resizeCanvas) Browser.setWindowedCanvasSize();
+          }
+          if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen);
+          Browser.updateCanvasDimensions(canvas);
+        }
+
+        if (!Browser.fullScreenHandlersInstalled) {
+          Browser.fullScreenHandlersInstalled = true;
+          document.addEventListener('fullscreenchange', fullScreenChange, false);
+          document.addEventListener('mozfullscreenchange', fullScreenChange, false);
+          document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
+          document.addEventListener('MSFullscreenChange', fullScreenChange, false);
+        }
+
+        // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
+        var canvasContainer = document.createElement("div");
+        canvas.parentNode.insertBefore(canvasContainer, canvas);
+        canvasContainer.appendChild(canvas);
+
+        // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
+        canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] ||
+                                            canvasContainer['mozRequestFullScreen'] ||
+                                            canvasContainer['msRequestFullscreen'] ||
+                                           (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
+        canvasContainer.requestFullScreen();
+      },requestAnimationFrame:function requestAnimationFrame(func) {
+        if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js)
+          setTimeout(func, 1000/60);
+        } else {
+          if (!window.requestAnimationFrame) {
+            window.requestAnimationFrame = window['requestAnimationFrame'] ||
+                                           window['mozRequestAnimationFrame'] ||
+                                           window['webkitRequestAnimationFrame'] ||
+                                           window['msRequestAnimationFrame'] ||
+                                           window['oRequestAnimationFrame'] ||
+                                           window['setTimeout'];
+          }
+          window.requestAnimationFrame(func);
+        }
+      },safeCallback:function (func) {
+        return function() {
+          if (!ABORT) return func.apply(null, arguments);
+        };
+      },safeRequestAnimationFrame:function (func) {
+        return Browser.requestAnimationFrame(function() {
+          if (!ABORT) func();
+        });
+      },safeSetTimeout:function (func, timeout) {
+        return setTimeout(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },safeSetInterval:function (func, timeout) {
+        return setInterval(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },getMimetype:function (name) {
+        return {
+          'jpg': 'image/jpeg',
+          'jpeg': 'image/jpeg',
+          'png': 'image/png',
+          'bmp': 'image/bmp',
+          'ogg': 'audio/ogg',
+          'wav': 'audio/wav',
+          'mp3': 'audio/mpeg'
+        }[name.substr(name.lastIndexOf('.')+1)];
+      },getUserMedia:function (func) {
+        if(!window.getUserMedia) {
+          window.getUserMedia = navigator['getUserMedia'] ||
+                                navigator['mozGetUserMedia'];
+        }
+        window.getUserMedia(func);
+      },getMovementX:function (event) {
+        return event['movementX'] ||
+               event['mozMovementX'] ||
+               event['webkitMovementX'] ||
+               0;
+      },getMovementY:function (event) {
+        return event['movementY'] ||
+               event['mozMovementY'] ||
+               event['webkitMovementY'] ||
+               0;
+      },getMouseWheelDelta:function (event) {
+        return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta));
+      },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup
+        if (Browser.pointerLock) {
+          // When the pointer is locked, calculate the coordinates
+          // based on the movement of the mouse.
+          // Workaround for Firefox bug 764498
+          if (event.type != 'mousemove' &&
+              ('mozMovementX' in event)) {
+            Browser.mouseMovementX = Browser.mouseMovementY = 0;
+          } else {
+            Browser.mouseMovementX = Browser.getMovementX(event);
+            Browser.mouseMovementY = Browser.getMovementY(event);
+          }
+
+          // check if SDL is available
+          if (typeof SDL != "undefined") {
+            Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
+            Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
+          } else {
+            // just add the mouse delta to the current absolut mouse position
+            // FIXME: ideally this should be clamped against the canvas size and zero
+            Browser.mouseX += Browser.mouseMovementX;
+            Browser.mouseY += Browser.mouseMovementY;
+          }
+        } else {
+          // Otherwise, calculate the movement based on the changes
+          // in the coordinates.
+          var rect = Module["canvas"].getBoundingClientRect();
+          var x, y;
+
+          // Neither .scrollX or .pageXOffset are defined in a spec, but
+          // we prefer .scrollX because it is currently in a spec draft.
+          // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
+          var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);
+          var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);
+          if (event.type == 'touchstart' ||
+              event.type == 'touchend' ||
+              event.type == 'touchmove') {
+            var t = event.touches.item(0);
+            if (t) {
+              x = t.pageX - (scrollX + rect.left);
+              y = t.pageY - (scrollY + rect.top);
+            } else {
+              return;
+            }
+          } else {
+            x = event.pageX - (scrollX + rect.left);
+            y = event.pageY - (scrollY + rect.top);
+          }
+
+          // the canvas might be CSS-scaled compared to its backbuffer;
+          // SDL-using content will want mouse coordinates in terms
+          // of backbuffer units.
+          var cw = Module["canvas"].width;
+          var ch = Module["canvas"].height;
+          x = x * (cw / rect.width);
+          y = y * (ch / rect.height);
+
+          Browser.mouseMovementX = x - Browser.mouseX;
+          Browser.mouseMovementY = y - Browser.mouseY;
+          Browser.mouseX = x;
+          Browser.mouseY = y;
+        }
+      },xhrLoad:function (url, onload, onerror) {
+        var xhr = new XMLHttpRequest();
+        xhr.open('GET', url, true);
+        xhr.responseType = 'arraybuffer';
+        xhr.onload = function xhr_onload() {
+          if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
+            onload(xhr.response);
+          } else {
+            onerror();
+          }
+        };
+        xhr.onerror = onerror;
+        xhr.send(null);
+      },asyncLoad:function (url, onload, onerror, noRunDep) {
+        Browser.xhrLoad(url, function(arrayBuffer) {
+          assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
+          onload(new Uint8Array(arrayBuffer));
+          if (!noRunDep) removeRunDependency('al ' + url);
+        }, function(event) {
+          if (onerror) {
+            onerror();
+          } else {
+            throw 'Loading data file "' + url + '" failed.';
+          }
+        });
+        if (!noRunDep) addRunDependency('al ' + url);
+      },resizeListeners:[],updateResizeListeners:function () {
+        var canvas = Module['canvas'];
+        Browser.resizeListeners.forEach(function(listener) {
+          listener(canvas.width, canvas.height);
+        });
+      },setCanvasSize:function (width, height, noUpdates) {
+        var canvas = Module['canvas'];
+        Browser.updateCanvasDimensions(canvas, width, height);
+        if (!noUpdates) Browser.updateResizeListeners();
+      },windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+          var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+          flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
+          HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },setWindowedCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+          var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+          flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
+          HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },updateCanvasDimensions:function (canvas, wNative, hNative) {
+        if (wNative && hNative) {
+          canvas.widthNative = wNative;
+          canvas.heightNative = hNative;
+        } else {
+          wNative = canvas.widthNative;
+          hNative = canvas.heightNative;
+        }
+        var w = wNative;
+        var h = hNative;
+        if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
+          if (w/h < Module['forcedAspectRatio']) {
+            w = Math.round(h * Module['forcedAspectRatio']);
+          } else {
+            h = Math.round(w / Module['forcedAspectRatio']);
+          }
+        }
+        if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+             document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+             document['fullScreenElement'] || document['fullscreenElement'] ||
+             document['msFullScreenElement'] || document['msFullscreenElement'] ||
+             document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
+           var factor = Math.min(screen.width / w, screen.height / h);
+           w = Math.round(w * factor);
+           h = Math.round(h * factor);
+        }
+        if (Browser.resizeCanvas) {
+          if (canvas.width  != w) canvas.width  = w;
+          if (canvas.height != h) canvas.height = h;
+          if (typeof canvas.style != 'undefined') {
+            canvas.style.removeProperty( "width");
+            canvas.style.removeProperty("height");
+          }
+        } else {
+          if (canvas.width  != wNative) canvas.width  = wNative;
+          if (canvas.height != hNative) canvas.height = hNative;
+          if (typeof canvas.style != 'undefined') {
+            if (w != wNative || h != hNative) {
+              canvas.style.setProperty( "width", w + "px", "important");
+              canvas.style.setProperty("height", h + "px", "important");
+            } else {
+              canvas.style.removeProperty( "width");
+              canvas.style.removeProperty("height");
+            }
+          }
+        }
+      }};
+
+  function _time(ptr) {
+      var ret = Math.floor(Date.now()/1000);
+      if (ptr) {
+        HEAP32[((ptr)>>2)]=ret;
+      }
+      return ret;
+    }
+
+
+
+  function _emscripten_memcpy_big(dest, src, num) {
+      HEAPU8.set(HEAPU8.subarray(src, src+num), dest);
+      return dest;
+    }
+  Module["_memcpy"] = _memcpy;
+FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice;
+___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0;
+__ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor();
+if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); }
+__ATINIT__.push({ func: function() { SOCKFS.root = FS.mount(SOCKFS, {}, null); } });
+_fputc.ret = allocate([0], "i8", ALLOC_STATIC);
+Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };
+  Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
+  Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
+  Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
+  Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
+  Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }
+STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);
+
+staticSealed = true; // seal the static portion of memory
+
+STACK_MAX = STACK_BASE + 5242880;
+
+DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);
+
+assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");
+
+
+var Math_min = Math.min;
+function asmPrintInt(x, y) {
+  Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+function asmPrintFloat(x, y) {
+  Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+// EMSCRIPTEN_START_ASM
+var asm = (function(global, env, buffer) {
+  'use asm';
+  var HEAP8 = new global.Int8Array(buffer);
+  var HEAP16 = new global.Int16Array(buffer);
+  var HEAP32 = new global.Int32Array(buffer);
+  var HEAPU8 = new global.Uint8Array(buffer);
+  var HEAPU16 = new global.Uint16Array(buffer);
+  var HEAPU32 = new global.Uint32Array(buffer);
+  var HEAPF32 = new global.Float32Array(buffer);
+  var HEAPF64 = new global.Float64Array(buffer);
+
+  var STACKTOP=env.STACKTOP|0;
+  var STACK_MAX=env.STACK_MAX|0;
+  var tempDoublePtr=env.tempDoublePtr|0;
+  var ABORT=env.ABORT|0;
+
+  var __THREW__ = 0;
+  var threwValue = 0;
+  var setjmpId = 0;
+  var undef = 0;
+  var nan = +env.NaN, inf = +env.Infinity;
+  var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
+
+  var tempRet0 = 0;
+  var tempRet1 = 0;
+  var tempRet2 = 0;
+  var tempRet3 = 0;
+  var tempRet4 = 0;
+  var tempRet5 = 0;
+  var tempRet6 = 0;
+  var tempRet7 = 0;
+  var tempRet8 = 0;
+  var tempRet9 = 0;
+  var Math_floor=global.Math.floor;
+  var Math_abs=global.Math.abs;
+  var Math_sqrt=global.Math.sqrt;
+  var Math_pow=global.Math.pow;
+  var Math_cos=global.Math.cos;
+  var Math_sin=global.Math.sin;
+  var Math_tan=global.Math.tan;
+  var Math_acos=global.Math.acos;
+  var Math_asin=global.Math.asin;
+  var Math_atan=global.Math.atan;
+  var Math_atan2=global.Math.atan2;
+  var Math_exp=global.Math.exp;
+  var Math_log=global.Math.log;
+  var Math_ceil=global.Math.ceil;
+  var Math_imul=global.Math.imul;
+  var abort=env.abort;
+  var assert=env.assert;
+  var asmPrintInt=env.asmPrintInt;
+  var asmPrintFloat=env.asmPrintFloat;
+  var Math_min=env.min;
+  var _fflush=env._fflush;
+  var _emscripten_memcpy_big=env._emscripten_memcpy_big;
+  var _putchar=env._putchar;
+  var _fputc=env._fputc;
+  var _send=env._send;
+  var _pwrite=env._pwrite;
+  var _abort=env._abort;
+  var __reallyNegative=env.__reallyNegative;
+  var _fwrite=env._fwrite;
+  var _sbrk=env._sbrk;
+  var _mkport=env._mkport;
+  var _fprintf=env._fprintf;
+  var ___setErrNo=env.___setErrNo;
+  var __formatString=env.__formatString;
+  var _fileno=env._fileno;
+  var _printf=env._printf;
+  var _time=env._time;
+  var _sysconf=env._sysconf;
+  var _write=env._write;
+  var ___errno_location=env.___errno_location;
+  var tempFloat = 0.0;
+
+// EMSCRIPTEN_START_FUNCS
+function _malloc(i12) {
+ i12 = i12 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0;
+ i1 = STACKTOP;
+ do {
+  if (i12 >>> 0 < 245) {
+   if (i12 >>> 0 < 11) {
+    i12 = 16;
+   } else {
+    i12 = i12 + 11 & -8;
+   }
+   i20 = i12 >>> 3;
+   i18 = HEAP32[14] | 0;
+   i21 = i18 >>> i20;
+   if ((i21 & 3 | 0) != 0) {
+    i6 = (i21 & 1 ^ 1) + i20 | 0;
+    i5 = i6 << 1;
+    i3 = 96 + (i5 << 2) | 0;
+    i5 = 96 + (i5 + 2 << 2) | 0;
+    i7 = HEAP32[i5 >> 2] | 0;
+    i2 = i7 + 8 | 0;
+    i4 = HEAP32[i2 >> 2] | 0;
+    do {
+     if ((i3 | 0) != (i4 | 0)) {
+      if (i4 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i8 = i4 + 12 | 0;
+      if ((HEAP32[i8 >> 2] | 0) == (i7 | 0)) {
+       HEAP32[i8 >> 2] = i3;
+       HEAP32[i5 >> 2] = i4;
+       break;
+      } else {
+       _abort();
+      }
+     } else {
+      HEAP32[14] = i18 & ~(1 << i6);
+     }
+    } while (0);
+    i32 = i6 << 3;
+    HEAP32[i7 + 4 >> 2] = i32 | 3;
+    i32 = i7 + (i32 | 4) | 0;
+    HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+    i32 = i2;
+    STACKTOP = i1;
+    return i32 | 0;
+   }
+   if (i12 >>> 0 > (HEAP32[64 >> 2] | 0) >>> 0) {
+    if ((i21 | 0) != 0) {
+     i7 = 2 << i20;
+     i7 = i21 << i20 & (i7 | 0 - i7);
+     i7 = (i7 & 0 - i7) + -1 | 0;
+     i2 = i7 >>> 12 & 16;
+     i7 = i7 >>> i2;
+     i6 = i7 >>> 5 & 8;
+     i7 = i7 >>> i6;
+     i5 = i7 >>> 2 & 4;
+     i7 = i7 >>> i5;
+     i4 = i7 >>> 1 & 2;
+     i7 = i7 >>> i4;
+     i3 = i7 >>> 1 & 1;
+     i3 = (i6 | i2 | i5 | i4 | i3) + (i7 >>> i3) | 0;
+     i7 = i3 << 1;
+     i4 = 96 + (i7 << 2) | 0;
+     i7 = 96 + (i7 + 2 << 2) | 0;
+     i5 = HEAP32[i7 >> 2] | 0;
+     i2 = i5 + 8 | 0;
+     i6 = HEAP32[i2 >> 2] | 0;
+     do {
+      if ((i4 | 0) != (i6 | 0)) {
+       if (i6 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+        _abort();
+       }
+       i8 = i6 + 12 | 0;
+       if ((HEAP32[i8 >> 2] | 0) == (i5 | 0)) {
+        HEAP32[i8 >> 2] = i4;
+        HEAP32[i7 >> 2] = i6;
+        break;
+       } else {
+        _abort();
+       }
+      } else {
+       HEAP32[14] = i18 & ~(1 << i3);
+      }
+     } while (0);
+     i6 = i3 << 3;
+     i4 = i6 - i12 | 0;
+     HEAP32[i5 + 4 >> 2] = i12 | 3;
+     i3 = i5 + i12 | 0;
+     HEAP32[i5 + (i12 | 4) >> 2] = i4 | 1;
+     HEAP32[i5 + i6 >> 2] = i4;
+     i6 = HEAP32[64 >> 2] | 0;
+     if ((i6 | 0) != 0) {
+      i5 = HEAP32[76 >> 2] | 0;
+      i8 = i6 >>> 3;
+      i9 = i8 << 1;
+      i6 = 96 + (i9 << 2) | 0;
+      i7 = HEAP32[14] | 0;
+      i8 = 1 << i8;
+      if ((i7 & i8 | 0) != 0) {
+       i7 = 96 + (i9 + 2 << 2) | 0;
+       i8 = HEAP32[i7 >> 2] | 0;
+       if (i8 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        i28 = i7;
+        i27 = i8;
+       }
+      } else {
+       HEAP32[14] = i7 | i8;
+       i28 = 96 + (i9 + 2 << 2) | 0;
+       i27 = i6;
+      }
+      HEAP32[i28 >> 2] = i5;
+      HEAP32[i27 + 12 >> 2] = i5;
+      HEAP32[i5 + 8 >> 2] = i27;
+      HEAP32[i5 + 12 >> 2] = i6;
+     }
+     HEAP32[64 >> 2] = i4;
+     HEAP32[76 >> 2] = i3;
+     i32 = i2;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+    i18 = HEAP32[60 >> 2] | 0;
+    if ((i18 | 0) != 0) {
+     i2 = (i18 & 0 - i18) + -1 | 0;
+     i31 = i2 >>> 12 & 16;
+     i2 = i2 >>> i31;
+     i30 = i2 >>> 5 & 8;
+     i2 = i2 >>> i30;
+     i32 = i2 >>> 2 & 4;
+     i2 = i2 >>> i32;
+     i6 = i2 >>> 1 & 2;
+     i2 = i2 >>> i6;
+     i3 = i2 >>> 1 & 1;
+     i3 = HEAP32[360 + ((i30 | i31 | i32 | i6 | i3) + (i2 >>> i3) << 2) >> 2] | 0;
+     i2 = (HEAP32[i3 + 4 >> 2] & -8) - i12 | 0;
+     i6 = i3;
+     while (1) {
+      i5 = HEAP32[i6 + 16 >> 2] | 0;
+      if ((i5 | 0) == 0) {
+       i5 = HEAP32[i6 + 20 >> 2] | 0;
+       if ((i5 | 0) == 0) {
+        break;
+       }
+      }
+      i6 = (HEAP32[i5 + 4 >> 2] & -8) - i12 | 0;
+      i4 = i6 >>> 0 < i2 >>> 0;
+      i2 = i4 ? i6 : i2;
+      i6 = i5;
+      i3 = i4 ? i5 : i3;
+     }
+     i6 = HEAP32[72 >> 2] | 0;
+     if (i3 >>> 0 < i6 >>> 0) {
+      _abort();
+     }
+     i4 = i3 + i12 | 0;
+     if (!(i3 >>> 0 < i4 >>> 0)) {
+      _abort();
+     }
+     i5 = HEAP32[i3 + 24 >> 2] | 0;
+     i7 = HEAP32[i3 + 12 >> 2] | 0;
+     do {
+      if ((i7 | 0) == (i3 | 0)) {
+       i8 = i3 + 20 | 0;
+       i7 = HEAP32[i8 >> 2] | 0;
+       if ((i7 | 0) == 0) {
+        i8 = i3 + 16 | 0;
+        i7 = HEAP32[i8 >> 2] | 0;
+        if ((i7 | 0) == 0) {
+         i26 = 0;
+         break;
+        }
+       }
+       while (1) {
+        i10 = i7 + 20 | 0;
+        i9 = HEAP32[i10 >> 2] | 0;
+        if ((i9 | 0) != 0) {
+         i7 = i9;
+         i8 = i10;
+         continue;
+        }
+        i10 = i7 + 16 | 0;
+        i9 = HEAP32[i10 >> 2] | 0;
+        if ((i9 | 0) == 0) {
+         break;
+        } else {
+         i7 = i9;
+         i8 = i10;
+        }
+       }
+       if (i8 >>> 0 < i6 >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i8 >> 2] = 0;
+        i26 = i7;
+        break;
+       }
+      } else {
+       i8 = HEAP32[i3 + 8 >> 2] | 0;
+       if (i8 >>> 0 < i6 >>> 0) {
+        _abort();
+       }
+       i6 = i8 + 12 | 0;
+       if ((HEAP32[i6 >> 2] | 0) != (i3 | 0)) {
+        _abort();
+       }
+       i9 = i7 + 8 | 0;
+       if ((HEAP32[i9 >> 2] | 0) == (i3 | 0)) {
+        HEAP32[i6 >> 2] = i7;
+        HEAP32[i9 >> 2] = i8;
+        i26 = i7;
+        break;
+       } else {
+        _abort();
+       }
+      }
+     } while (0);
+     do {
+      if ((i5 | 0) != 0) {
+       i7 = HEAP32[i3 + 28 >> 2] | 0;
+       i6 = 360 + (i7 << 2) | 0;
+       if ((i3 | 0) == (HEAP32[i6 >> 2] | 0)) {
+        HEAP32[i6 >> 2] = i26;
+        if ((i26 | 0) == 0) {
+         HEAP32[60 >> 2] = HEAP32[60 >> 2] & ~(1 << i7);
+         break;
+        }
+       } else {
+        if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+         _abort();
+        }
+        i6 = i5 + 16 | 0;
+        if ((HEAP32[i6 >> 2] | 0) == (i3 | 0)) {
+         HEAP32[i6 >> 2] = i26;
+        } else {
+         HEAP32[i5 + 20 >> 2] = i26;
+        }
+        if ((i26 | 0) == 0) {
+         break;
+        }
+       }
+       if (i26 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+        _abort();
+       }
+       HEAP32[i26 + 24 >> 2] = i5;
+       i5 = HEAP32[i3 + 16 >> 2] | 0;
+       do {
+        if ((i5 | 0) != 0) {
+         if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i26 + 16 >> 2] = i5;
+          HEAP32[i5 + 24 >> 2] = i26;
+          break;
+         }
+        }
+       } while (0);
+       i5 = HEAP32[i3 + 20 >> 2] | 0;
+       if ((i5 | 0) != 0) {
+        if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i26 + 20 >> 2] = i5;
+         HEAP32[i5 + 24 >> 2] = i26;
+         break;
+        }
+       }
+      }
+     } while (0);
+     if (i2 >>> 0 < 16) {
+      i32 = i2 + i12 | 0;
+      HEAP32[i3 + 4 >> 2] = i32 | 3;
+      i32 = i3 + (i32 + 4) | 0;
+      HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+     } else {
+      HEAP32[i3 + 4 >> 2] = i12 | 3;
+      HEAP32[i3 + (i12 | 4) >> 2] = i2 | 1;
+      HEAP32[i3 + (i2 + i12) >> 2] = i2;
+      i6 = HEAP32[64 >> 2] | 0;
+      if ((i6 | 0) != 0) {
+       i5 = HEAP32[76 >> 2] | 0;
+       i8 = i6 >>> 3;
+       i9 = i8 << 1;
+       i6 = 96 + (i9 << 2) | 0;
+       i7 = HEAP32[14] | 0;
+       i8 = 1 << i8;
+       if ((i7 & i8 | 0) != 0) {
+        i7 = 96 + (i9 + 2 << 2) | 0;
+        i8 = HEAP32[i7 >> 2] | 0;
+        if (i8 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+         _abort();
+        } else {
+         i25 = i7;
+         i24 = i8;
+        }
+       } else {
+        HEAP32[14] = i7 | i8;
+        i25 = 96 + (i9 + 2 << 2) | 0;
+        i24 = i6;
+       }
+       HEAP32[i25 >> 2] = i5;
+       HEAP32[i24 + 12 >> 2] = i5;
+       HEAP32[i5 + 8 >> 2] = i24;
+       HEAP32[i5 + 12 >> 2] = i6;
+      }
+      HEAP32[64 >> 2] = i2;
+      HEAP32[76 >> 2] = i4;
+     }
+     i32 = i3 + 8 | 0;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+   }
+  } else {
+   if (!(i12 >>> 0 > 4294967231)) {
+    i24 = i12 + 11 | 0;
+    i12 = i24 & -8;
+    i26 = HEAP32[60 >> 2] | 0;
+    if ((i26 | 0) != 0) {
+     i25 = 0 - i12 | 0;
+     i24 = i24 >>> 8;
+     if ((i24 | 0) != 0) {
+      if (i12 >>> 0 > 16777215) {
+       i27 = 31;
+      } else {
+       i31 = (i24 + 1048320 | 0) >>> 16 & 8;
+       i32 = i24 << i31;
+       i30 = (i32 + 520192 | 0) >>> 16 & 4;
+       i32 = i32 << i30;
+       i27 = (i32 + 245760 | 0) >>> 16 & 2;
+       i27 = 14 - (i30 | i31 | i27) + (i32 << i27 >>> 15) | 0;
+       i27 = i12 >>> (i27 + 7 | 0) & 1 | i27 << 1;
+      }
+     } else {
+      i27 = 0;
+     }
+     i30 = HEAP32[360 + (i27 << 2) >> 2] | 0;
+     L126 : do {
+      if ((i30 | 0) == 0) {
+       i29 = 0;
+       i24 = 0;
+      } else {
+       if ((i27 | 0) == 31) {
+        i24 = 0;
+       } else {
+        i24 = 25 - (i27 >>> 1) | 0;
+       }
+       i29 = 0;
+       i28 = i12 << i24;
+       i24 = 0;
+       while (1) {
+        i32 = HEAP32[i30 + 4 >> 2] & -8;
+        i31 = i32 - i12 | 0;
+        if (i31 >>> 0 < i25 >>> 0) {
+         if ((i32 | 0) == (i12 | 0)) {
+          i25 = i31;
+          i29 = i30;
+          i24 = i30;
+          break L126;
+         } else {
+          i25 = i31;
+          i24 = i30;
+         }
+        }
+        i31 = HEAP32[i30 + 20 >> 2] | 0;
+        i30 = HEAP32[i30 + (i28 >>> 31 << 2) + 16 >> 2] | 0;
+        i29 = (i31 | 0) == 0 | (i31 | 0) == (i30 | 0) ? i29 : i31;
+        if ((i30 | 0) == 0) {
+         break;
+        } else {
+         i28 = i28 << 1;
+        }
+       }
+      }
+     } while (0);
+     if ((i29 | 0) == 0 & (i24 | 0) == 0) {
+      i32 = 2 << i27;
+      i26 = i26 & (i32 | 0 - i32);
+      if ((i26 | 0) == 0) {
+       break;
+      }
+      i32 = (i26 & 0 - i26) + -1 | 0;
+      i28 = i32 >>> 12 & 16;
+      i32 = i32 >>> i28;
+      i27 = i32 >>> 5 & 8;
+      i32 = i32 >>> i27;
+      i30 = i32 >>> 2 & 4;
+      i32 = i32 >>> i30;
+      i31 = i32 >>> 1 & 2;
+      i32 = i32 >>> i31;
+      i29 = i32 >>> 1 & 1;
+      i29 = HEAP32[360 + ((i27 | i28 | i30 | i31 | i29) + (i32 >>> i29) << 2) >> 2] | 0;
+     }
+     if ((i29 | 0) != 0) {
+      while (1) {
+       i27 = (HEAP32[i29 + 4 >> 2] & -8) - i12 | 0;
+       i26 = i27 >>> 0 < i25 >>> 0;
+       i25 = i26 ? i27 : i25;
+       i24 = i26 ? i29 : i24;
+       i26 = HEAP32[i29 + 16 >> 2] | 0;
+       if ((i26 | 0) != 0) {
+        i29 = i26;
+        continue;
+       }
+       i29 = HEAP32[i29 + 20 >> 2] | 0;
+       if ((i29 | 0) == 0) {
+        break;
+       }
+      }
+     }
+     if ((i24 | 0) != 0 ? i25 >>> 0 < ((HEAP32[64 >> 2] | 0) - i12 | 0) >>> 0 : 0) {
+      i4 = HEAP32[72 >> 2] | 0;
+      if (i24 >>> 0 < i4 >>> 0) {
+       _abort();
+      }
+      i2 = i24 + i12 | 0;
+      if (!(i24 >>> 0 < i2 >>> 0)) {
+       _abort();
+      }
+      i3 = HEAP32[i24 + 24 >> 2] | 0;
+      i6 = HEAP32[i24 + 12 >> 2] | 0;
+      do {
+       if ((i6 | 0) == (i24 | 0)) {
+        i6 = i24 + 20 | 0;
+        i5 = HEAP32[i6 >> 2] | 0;
+        if ((i5 | 0) == 0) {
+         i6 = i24 + 16 | 0;
+         i5 = HEAP32[i6 >> 2] | 0;
+         if ((i5 | 0) == 0) {
+          i22 = 0;
+          break;
+         }
+        }
+        while (1) {
+         i8 = i5 + 20 | 0;
+         i7 = HEAP32[i8 >> 2] | 0;
+         if ((i7 | 0) != 0) {
+          i5 = i7;
+          i6 = i8;
+          continue;
+         }
+         i7 = i5 + 16 | 0;
+         i8 = HEAP32[i7 >> 2] | 0;
+         if ((i8 | 0) == 0) {
+          break;
+         } else {
+          i5 = i8;
+          i6 = i7;
+         }
+        }
+        if (i6 >>> 0 < i4 >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i6 >> 2] = 0;
+         i22 = i5;
+         break;
+        }
+       } else {
+        i5 = HEAP32[i24 + 8 >> 2] | 0;
+        if (i5 >>> 0 < i4 >>> 0) {
+         _abort();
+        }
+        i7 = i5 + 12 | 0;
+        if ((HEAP32[i7 >> 2] | 0) != (i24 | 0)) {
+         _abort();
+        }
+        i4 = i6 + 8 | 0;
+        if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
+         HEAP32[i7 >> 2] = i6;
+         HEAP32[i4 >> 2] = i5;
+         i22 = i6;
+         break;
+        } else {
+         _abort();
+        }
+       }
+      } while (0);
+      do {
+       if ((i3 | 0) != 0) {
+        i4 = HEAP32[i24 + 28 >> 2] | 0;
+        i5 = 360 + (i4 << 2) | 0;
+        if ((i24 | 0) == (HEAP32[i5 >> 2] | 0)) {
+         HEAP32[i5 >> 2] = i22;
+         if ((i22 | 0) == 0) {
+          HEAP32[60 >> 2] = HEAP32[60 >> 2] & ~(1 << i4);
+          break;
+         }
+        } else {
+         if (i3 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+          _abort();
+         }
+         i4 = i3 + 16 | 0;
+         if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
+          HEAP32[i4 >> 2] = i22;
+         } else {
+          HEAP32[i3 + 20 >> 2] = i22;
+         }
+         if ((i22 | 0) == 0) {
+          break;
+         }
+        }
+        if (i22 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+         _abort();
+        }
+        HEAP32[i22 + 24 >> 2] = i3;
+        i3 = HEAP32[i24 + 16 >> 2] | 0;
+        do {
+         if ((i3 | 0) != 0) {
+          if (i3 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           HEAP32[i22 + 16 >> 2] = i3;
+           HEAP32[i3 + 24 >> 2] = i22;
+           break;
+          }
+         }
+        } while (0);
+        i3 = HEAP32[i24 + 20 >> 2] | 0;
+        if ((i3 | 0) != 0) {
+         if (i3 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i22 + 20 >> 2] = i3;
+          HEAP32[i3 + 24 >> 2] = i22;
+          break;
+         }
+        }
+       }
+      } while (0);
+      L204 : do {
+       if (!(i25 >>> 0 < 16)) {
+        HEAP32[i24 + 4 >> 2] = i12 | 3;
+        HEAP32[i24 + (i12 | 4) >> 2] = i25 | 1;
+        HEAP32[i24 + (i25 + i12) >> 2] = i25;
+        i4 = i25 >>> 3;
+        if (i25 >>> 0 < 256) {
+         i6 = i4 << 1;
+         i3 = 96 + (i6 << 2) | 0;
+         i5 = HEAP32[14] | 0;
+         i4 = 1 << i4;
+         if ((i5 & i4 | 0) != 0) {
+          i5 = 96 + (i6 + 2 << 2) | 0;
+          i4 = HEAP32[i5 >> 2] | 0;
+          if (i4 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           i21 = i5;
+           i20 = i4;
+          }
+         } else {
+          HEAP32[14] = i5 | i4;
+          i21 = 96 + (i6 + 2 << 2) | 0;
+          i20 = i3;
+         }
+         HEAP32[i21 >> 2] = i2;
+         HEAP32[i20 + 12 >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i20;
+         HEAP32[i24 + (i12 + 12) >> 2] = i3;
+         break;
+        }
+        i3 = i25 >>> 8;
+        if ((i3 | 0) != 0) {
+         if (i25 >>> 0 > 16777215) {
+          i3 = 31;
+         } else {
+          i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+          i32 = i3 << i31;
+          i30 = (i32 + 520192 | 0) >>> 16 & 4;
+          i32 = i32 << i30;
+          i3 = (i32 + 245760 | 0) >>> 16 & 2;
+          i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+          i3 = i25 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+         }
+        } else {
+         i3 = 0;
+        }
+        i6 = 360 + (i3 << 2) | 0;
+        HEAP32[i24 + (i12 + 28) >> 2] = i3;
+        HEAP32[i24 + (i12 + 20) >> 2] = 0;
+        HEAP32[i24 + (i12 + 16) >> 2] = 0;
+        i4 = HEAP32[60 >> 2] | 0;
+        i5 = 1 << i3;
+        if ((i4 & i5 | 0) == 0) {
+         HEAP32[60 >> 2] = i4 | i5;
+         HEAP32[i6 >> 2] = i2;
+         HEAP32[i24 + (i12 + 24) >> 2] = i6;
+         HEAP32[i24 + (i12 + 12) >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i2;
+         break;
+        }
+        i4 = HEAP32[i6 >> 2] | 0;
+        if ((i3 | 0) == 31) {
+         i3 = 0;
+        } else {
+         i3 = 25 - (i3 >>> 1) | 0;
+        }
+        L225 : do {
+         if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i25 | 0)) {
+          i3 = i25 << i3;
+          while (1) {
+           i6 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+           i5 = HEAP32[i6 >> 2] | 0;
+           if ((i5 | 0) == 0) {
+            break;
+           }
+           if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i25 | 0)) {
+            i18 = i5;
+            break L225;
+           } else {
+            i3 = i3 << 1;
+            i4 = i5;
+           }
+          }
+          if (i6 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           HEAP32[i6 >> 2] = i2;
+           HEAP32[i24 + (i12 + 24) >> 2] = i4;
+           HEAP32[i24 + (i12 + 12) >> 2] = i2;
+           HEAP32[i24 + (i12 + 8) >> 2] = i2;
+           break L204;
+          }
+         } else {
+          i18 = i4;
+         }
+        } while (0);
+        i4 = i18 + 8 | 0;
+        i3 = HEAP32[i4 >> 2] | 0;
+        i5 = HEAP32[72 >> 2] | 0;
+        if (i18 >>> 0 < i5 >>> 0) {
+         _abort();
+        }
+        if (i3 >>> 0 < i5 >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i3 + 12 >> 2] = i2;
+         HEAP32[i4 >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i3;
+         HEAP32[i24 + (i12 + 12) >> 2] = i18;
+         HEAP32[i24 + (i12 + 24) >> 2] = 0;
+         break;
+        }
+       } else {
+        i32 = i25 + i12 | 0;
+        HEAP32[i24 + 4 >> 2] = i32 | 3;
+        i32 = i24 + (i32 + 4) | 0;
+        HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+       }
+      } while (0);
+      i32 = i24 + 8 | 0;
+      STACKTOP = i1;
+      return i32 | 0;
+     }
+    }
+   } else {
+    i12 = -1;
+   }
+  }
+ } while (0);
+ i18 = HEAP32[64 >> 2] | 0;
+ if (!(i12 >>> 0 > i18 >>> 0)) {
+  i3 = i18 - i12 | 0;
+  i2 = HEAP32[76 >> 2] | 0;
+  if (i3 >>> 0 > 15) {
+   HEAP32[76 >> 2] = i2 + i12;
+   HEAP32[64 >> 2] = i3;
+   HEAP32[i2 + (i12 + 4) >> 2] = i3 | 1;
+   HEAP32[i2 + i18 >> 2] = i3;
+   HEAP32[i2 + 4 >> 2] = i12 | 3;
+  } else {
+   HEAP32[64 >> 2] = 0;
+   HEAP32[76 >> 2] = 0;
+   HEAP32[i2 + 4 >> 2] = i18 | 3;
+   i32 = i2 + (i18 + 4) | 0;
+   HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+  }
+  i32 = i2 + 8 | 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ i18 = HEAP32[68 >> 2] | 0;
+ if (i12 >>> 0 < i18 >>> 0) {
+  i31 = i18 - i12 | 0;
+  HEAP32[68 >> 2] = i31;
+  i32 = HEAP32[80 >> 2] | 0;
+  HEAP32[80 >> 2] = i32 + i12;
+  HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
+  HEAP32[i32 + 4 >> 2] = i12 | 3;
+  i32 = i32 + 8 | 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ do {
+  if ((HEAP32[132] | 0) == 0) {
+   i18 = _sysconf(30) | 0;
+   if ((i18 + -1 & i18 | 0) == 0) {
+    HEAP32[536 >> 2] = i18;
+    HEAP32[532 >> 2] = i18;
+    HEAP32[540 >> 2] = -1;
+    HEAP32[544 >> 2] = -1;
+    HEAP32[548 >> 2] = 0;
+    HEAP32[500 >> 2] = 0;
+    HEAP32[132] = (_time(0) | 0) & -16 ^ 1431655768;
+    break;
+   } else {
+    _abort();
+   }
+  }
+ } while (0);
+ i20 = i12 + 48 | 0;
+ i25 = HEAP32[536 >> 2] | 0;
+ i21 = i12 + 47 | 0;
+ i22 = i25 + i21 | 0;
+ i25 = 0 - i25 | 0;
+ i18 = i22 & i25;
+ if (!(i18 >>> 0 > i12 >>> 0)) {
+  i32 = 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ i24 = HEAP32[496 >> 2] | 0;
+ if ((i24 | 0) != 0 ? (i31 = HEAP32[488 >> 2] | 0, i32 = i31 + i18 | 0, i32 >>> 0 <= i31 >>> 0 | i32 >>> 0 > i24 >>> 0) : 0) {
+  i32 = 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ L269 : do {
+  if ((HEAP32[500 >> 2] & 4 | 0) == 0) {
+   i26 = HEAP32[80 >> 2] | 0;
+   L271 : do {
+    if ((i26 | 0) != 0) {
+     i24 = 504 | 0;
+     while (1) {
+      i27 = HEAP32[i24 >> 2] | 0;
+      if (!(i27 >>> 0 > i26 >>> 0) ? (i23 = i24 + 4 | 0, (i27 + (HEAP32[i23 >> 2] | 0) | 0) >>> 0 > i26 >>> 0) : 0) {
+       break;
+      }
+      i24 = HEAP32[i24 + 8 >> 2] | 0;
+      if ((i24 | 0) == 0) {
+       i13 = 182;
+       break L271;
+      }
+     }
+     if ((i24 | 0) != 0) {
+      i25 = i22 - (HEAP32[68 >> 2] | 0) & i25;
+      if (i25 >>> 0 < 2147483647) {
+       i13 = _sbrk(i25 | 0) | 0;
+       i26 = (i13 | 0) == ((HEAP32[i24 >> 2] | 0) + (HEAP32[i23 >> 2] | 0) | 0);
+       i22 = i13;
+       i24 = i25;
+       i23 = i26 ? i13 : -1;
+       i25 = i26 ? i25 : 0;
+       i13 = 191;
+      } else {
+       i25 = 0;
+      }
+     } else {
+      i13 = 182;
+     }
+    } else {
+     i13 = 182;
+    }
+   } while (0);
+   do {
+    if ((i13 | 0) == 182) {
+     i23 = _sbrk(0) | 0;
+     if ((i23 | 0) != (-1 | 0)) {
+      i24 = i23;
+      i22 = HEAP32[532 >> 2] | 0;
+      i25 = i22 + -1 | 0;
+      if ((i25 & i24 | 0) == 0) {
+       i25 = i18;
+      } else {
+       i25 = i18 - i24 + (i25 + i24 & 0 - i22) | 0;
+      }
+      i24 = HEAP32[488 >> 2] | 0;
+      i26 = i24 + i25 | 0;
+      if (i25 >>> 0 > i12 >>> 0 & i25 >>> 0 < 2147483647) {
+       i22 = HEAP32[496 >> 2] | 0;
+       if ((i22 | 0) != 0 ? i26 >>> 0 <= i24 >>> 0 | i26 >>> 0 > i22 >>> 0 : 0) {
+        i25 = 0;
+        break;
+       }
+       i22 = _sbrk(i25 | 0) | 0;
+       i13 = (i22 | 0) == (i23 | 0);
+       i24 = i25;
+       i23 = i13 ? i23 : -1;
+       i25 = i13 ? i25 : 0;
+       i13 = 191;
+      } else {
+       i25 = 0;
+      }
+     } else {
+      i25 = 0;
+     }
+    }
+   } while (0);
+   L291 : do {
+    if ((i13 | 0) == 191) {
+     i13 = 0 - i24 | 0;
+     if ((i23 | 0) != (-1 | 0)) {
+      i17 = i23;
+      i14 = i25;
+      i13 = 202;
+      break L269;
+     }
+     do {
+      if ((i22 | 0) != (-1 | 0) & i24 >>> 0 < 2147483647 & i24 >>> 0 < i20 >>> 0 ? (i19 = HEAP32[536 >> 2] | 0, i19 = i21 - i24 + i19 & 0 - i19, i19 >>> 0 < 2147483647) : 0) {
+       if ((_sbrk(i19 | 0) | 0) == (-1 | 0)) {
+        _sbrk(i13 | 0) | 0;
+        break L291;
+       } else {
+        i24 = i19 + i24 | 0;
+        break;
+       }
+      }
+     } while (0);
+     if ((i22 | 0) != (-1 | 0)) {
+      i17 = i22;
+      i14 = i24;
+      i13 = 202;
+      break L269;
+     }
+    }
+   } while (0);
+   HEAP32[500 >> 2] = HEAP32[500 >> 2] | 4;
+   i13 = 199;
+  } else {
+   i25 = 0;
+   i13 = 199;
+  }
+ } while (0);
+ if ((((i13 | 0) == 199 ? i18 >>> 0 < 2147483647 : 0) ? (i17 = _sbrk(i18 | 0) | 0, i16 = _sbrk(0) | 0, (i16 | 0) != (-1 | 0) & (i17 | 0) != (-1 | 0) & i17 >>> 0 < i16 >>> 0) : 0) ? (i15 = i16 - i17 | 0, i14 = i15 >>> 0 > (i12 + 40 | 0) >>> 0, i14) : 0) {
+  i14 = i14 ? i15 : i25;
+  i13 = 202;
+ }
+ if ((i13 | 0) == 202) {
+  i15 = (HEAP32[488 >> 2] | 0) + i14 | 0;
+  HEAP32[488 >> 2] = i15;
+  if (i15 >>> 0 > (HEAP32[492 >> 2] | 0) >>> 0) {
+   HEAP32[492 >> 2] = i15;
+  }
+  i15 = HEAP32[80 >> 2] | 0;
+  L311 : do {
+   if ((i15 | 0) != 0) {
+    i21 = 504 | 0;
+    while (1) {
+     i16 = HEAP32[i21 >> 2] | 0;
+     i19 = i21 + 4 | 0;
+     i20 = HEAP32[i19 >> 2] | 0;
+     if ((i17 | 0) == (i16 + i20 | 0)) {
+      i13 = 214;
+      break;
+     }
+     i18 = HEAP32[i21 + 8 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      break;
+     } else {
+      i21 = i18;
+     }
+    }
+    if (((i13 | 0) == 214 ? (HEAP32[i21 + 12 >> 2] & 8 | 0) == 0 : 0) ? i15 >>> 0 >= i16 >>> 0 & i15 >>> 0 < i17 >>> 0 : 0) {
+     HEAP32[i19 >> 2] = i20 + i14;
+     i2 = (HEAP32[68 >> 2] | 0) + i14 | 0;
+     i3 = i15 + 8 | 0;
+     if ((i3 & 7 | 0) == 0) {
+      i3 = 0;
+     } else {
+      i3 = 0 - i3 & 7;
+     }
+     i32 = i2 - i3 | 0;
+     HEAP32[80 >> 2] = i15 + i3;
+     HEAP32[68 >> 2] = i32;
+     HEAP32[i15 + (i3 + 4) >> 2] = i32 | 1;
+     HEAP32[i15 + (i2 + 4) >> 2] = 40;
+     HEAP32[84 >> 2] = HEAP32[544 >> 2];
+     break;
+    }
+    if (i17 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+     HEAP32[72 >> 2] = i17;
+    }
+    i19 = i17 + i14 | 0;
+    i16 = 504 | 0;
+    while (1) {
+     if ((HEAP32[i16 >> 2] | 0) == (i19 | 0)) {
+      i13 = 224;
+      break;
+     }
+     i18 = HEAP32[i16 + 8 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      break;
+     } else {
+      i16 = i18;
+     }
+    }
+    if ((i13 | 0) == 224 ? (HEAP32[i16 + 12 >> 2] & 8 | 0) == 0 : 0) {
+     HEAP32[i16 >> 2] = i17;
+     i6 = i16 + 4 | 0;
+     HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i14;
+     i6 = i17 + 8 | 0;
+     if ((i6 & 7 | 0) == 0) {
+      i6 = 0;
+     } else {
+      i6 = 0 - i6 & 7;
+     }
+     i7 = i17 + (i14 + 8) | 0;
+     if ((i7 & 7 | 0) == 0) {
+      i13 = 0;
+     } else {
+      i13 = 0 - i7 & 7;
+     }
+     i15 = i17 + (i13 + i14) | 0;
+     i8 = i6 + i12 | 0;
+     i7 = i17 + i8 | 0;
+     i10 = i15 - (i17 + i6) - i12 | 0;
+     HEAP32[i17 + (i6 + 4) >> 2] = i12 | 3;
+     L348 : do {
+      if ((i15 | 0) != (HEAP32[80 >> 2] | 0)) {
+       if ((i15 | 0) == (HEAP32[76 >> 2] | 0)) {
+        i32 = (HEAP32[64 >> 2] | 0) + i10 | 0;
+        HEAP32[64 >> 2] = i32;
+        HEAP32[76 >> 2] = i7;
+        HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
+        HEAP32[i17 + (i32 + i8) >> 2] = i32;
+        break;
+       }
+       i12 = i14 + 4 | 0;
+       i18 = HEAP32[i17 + (i12 + i13) >> 2] | 0;
+       if ((i18 & 3 | 0) == 1) {
+        i11 = i18 & -8;
+        i16 = i18 >>> 3;
+        do {
+         if (!(i18 >>> 0 < 256)) {
+          i9 = HEAP32[i17 + ((i13 | 24) + i14) >> 2] | 0;
+          i19 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
+          do {
+           if ((i19 | 0) == (i15 | 0)) {
+            i19 = i13 | 16;
+            i18 = i17 + (i12 + i19) | 0;
+            i16 = HEAP32[i18 >> 2] | 0;
+            if ((i16 | 0) == 0) {
+             i18 = i17 + (i19 + i14) | 0;
+             i16 = HEAP32[i18 >> 2] | 0;
+             if ((i16 | 0) == 0) {
+              i5 = 0;
+              break;
+             }
+            }
+            while (1) {
+             i20 = i16 + 20 | 0;
+             i19 = HEAP32[i20 >> 2] | 0;
+             if ((i19 | 0) != 0) {
+              i16 = i19;
+              i18 = i20;
+              continue;
+             }
+             i19 = i16 + 16 | 0;
+             i20 = HEAP32[i19 >> 2] | 0;
+             if ((i20 | 0) == 0) {
+              break;
+             } else {
+              i16 = i20;
+              i18 = i19;
+             }
+            }
+            if (i18 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+             _abort();
+            } else {
+             HEAP32[i18 >> 2] = 0;
+             i5 = i16;
+             break;
+            }
+           } else {
+            i18 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
+            if (i18 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+             _abort();
+            }
+            i16 = i18 + 12 | 0;
+            if ((HEAP32[i16 >> 2] | 0) != (i15 | 0)) {
+             _abort();
+            }
+            i20 = i19 + 8 | 0;
+            if ((HEAP32[i20 >> 2] | 0) == (i15 | 0)) {
+             HEAP32[i16 >> 2] = i19;
+             HEAP32[i20 >> 2] = i18;
+             i5 = i19;
+             break;
+            } else {
+             _abort();
+            }
+           }
+          } while (0);
+          if ((i9 | 0) != 0) {
+           i16 = HEAP32[i17 + (i14 + 28 + i13) >> 2] | 0;
+           i18 = 360 + (i16 << 2) | 0;
+           if ((i15 | 0) == (HEAP32[i18 >> 2] | 0)) {
+            HEAP32[i18 >> 2] = i5;
+            if ((i5 | 0) == 0) {
+             HEAP32[60 >> 2] = HEAP32[60 >> 2] & ~(1 << i16);
+             break;
+            }
+           } else {
+            if (i9 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+             _abort();
+            }
+            i16 = i9 + 16 | 0;
+            if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
+             HEAP32[i16 >> 2] = i5;
+            } else {
+             HEAP32[i9 + 20 >> 2] = i5;
+            }
+            if ((i5 | 0) == 0) {
+             break;
+            }
+           }
+           if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           HEAP32[i5 + 24 >> 2] = i9;
+           i15 = i13 | 16;
+           i9 = HEAP32[i17 + (i15 + i14) >> 2] | 0;
+           do {
+            if ((i9 | 0) != 0) {
+             if (i9 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+              _abort();
+             } else {
+              HEAP32[i5 + 16 >> 2] = i9;
+              HEAP32[i9 + 24 >> 2] = i5;
+              break;
+             }
+            }
+           } while (0);
+           i9 = HEAP32[i17 + (i12 + i15) >> 2] | 0;
+           if ((i9 | 0) != 0) {
+            if (i9 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+             _abort();
+            } else {
+             HEAP32[i5 + 20 >> 2] = i9;
+             HEAP32[i9 + 24 >> 2] = i5;
+             break;
+            }
+           }
+          }
+         } else {
+          i5 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
+          i12 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
+          i18 = 96 + (i16 << 1 << 2) | 0;
+          if ((i5 | 0) != (i18 | 0)) {
+           if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           if ((HEAP32[i5 + 12 >> 2] | 0) != (i15 | 0)) {
+            _abort();
+           }
+          }
+          if ((i12 | 0) == (i5 | 0)) {
+           HEAP32[14] = HEAP32[14] & ~(1 << i16);
+           break;
+          }
+          if ((i12 | 0) != (i18 | 0)) {
+           if (i12 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           i16 = i12 + 8 | 0;
+           if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
+            i9 = i16;
+           } else {
+            _abort();
+           }
+          } else {
+           i9 = i12 + 8 | 0;
+          }
+          HEAP32[i5 + 12 >> 2] = i12;
+          HEAP32[i9 >> 2] = i5;
+         }
+        } while (0);
+        i15 = i17 + ((i11 | i13) + i14) | 0;
+        i10 = i11 + i10 | 0;
+       }
+       i5 = i15 + 4 | 0;
+       HEAP32[i5 >> 2] = HEAP32[i5 >> 2] & -2;
+       HEAP32[i17 + (i8 + 4) >> 2] = i10 | 1;
+       HEAP32[i17 + (i10 + i8) >> 2] = i10;
+       i5 = i10 >>> 3;
+       if (i10 >>> 0 < 256) {
+        i10 = i5 << 1;
+        i2 = 96 + (i10 << 2) | 0;
+        i9 = HEAP32[14] | 0;
+        i5 = 1 << i5;
+        if ((i9 & i5 | 0) != 0) {
+         i9 = 96 + (i10 + 2 << 2) | 0;
+         i5 = HEAP32[i9 >> 2] | 0;
+         if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          i3 = i9;
+          i4 = i5;
+         }
+        } else {
+         HEAP32[14] = i9 | i5;
+         i3 = 96 + (i10 + 2 << 2) | 0;
+         i4 = i2;
+        }
+        HEAP32[i3 >> 2] = i7;
+        HEAP32[i4 + 12 >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i4;
+        HEAP32[i17 + (i8 + 12) >> 2] = i2;
+        break;
+       }
+       i3 = i10 >>> 8;
+       if ((i3 | 0) != 0) {
+        if (i10 >>> 0 > 16777215) {
+         i3 = 31;
+        } else {
+         i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+         i32 = i3 << i31;
+         i30 = (i32 + 520192 | 0) >>> 16 & 4;
+         i32 = i32 << i30;
+         i3 = (i32 + 245760 | 0) >>> 16 & 2;
+         i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+         i3 = i10 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+        }
+       } else {
+        i3 = 0;
+       }
+       i4 = 360 + (i3 << 2) | 0;
+       HEAP32[i17 + (i8 + 28) >> 2] = i3;
+       HEAP32[i17 + (i8 + 20) >> 2] = 0;
+       HEAP32[i17 + (i8 + 16) >> 2] = 0;
+       i9 = HEAP32[60 >> 2] | 0;
+       i5 = 1 << i3;
+       if ((i9 & i5 | 0) == 0) {
+        HEAP32[60 >> 2] = i9 | i5;
+        HEAP32[i4 >> 2] = i7;
+        HEAP32[i17 + (i8 + 24) >> 2] = i4;
+        HEAP32[i17 + (i8 + 12) >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i7;
+        break;
+       }
+       i4 = HEAP32[i4 >> 2] | 0;
+       if ((i3 | 0) == 31) {
+        i3 = 0;
+       } else {
+        i3 = 25 - (i3 >>> 1) | 0;
+       }
+       L444 : do {
+        if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i10 | 0)) {
+         i3 = i10 << i3;
+         while (1) {
+          i5 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+          i9 = HEAP32[i5 >> 2] | 0;
+          if ((i9 | 0) == 0) {
+           break;
+          }
+          if ((HEAP32[i9 + 4 >> 2] & -8 | 0) == (i10 | 0)) {
+           i2 = i9;
+           break L444;
+          } else {
+           i3 = i3 << 1;
+           i4 = i9;
+          }
+         }
+         if (i5 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i5 >> 2] = i7;
+          HEAP32[i17 + (i8 + 24) >> 2] = i4;
+          HEAP32[i17 + (i8 + 12) >> 2] = i7;
+          HEAP32[i17 + (i8 + 8) >> 2] = i7;
+          break L348;
+         }
+        } else {
+         i2 = i4;
+        }
+       } while (0);
+       i4 = i2 + 8 | 0;
+       i3 = HEAP32[i4 >> 2] | 0;
+       i5 = HEAP32[72 >> 2] | 0;
+       if (i2 >>> 0 < i5 >>> 0) {
+        _abort();
+       }
+       if (i3 >>> 0 < i5 >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i3 + 12 >> 2] = i7;
+        HEAP32[i4 >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i3;
+        HEAP32[i17 + (i8 + 12) >> 2] = i2;
+        HEAP32[i17 + (i8 + 24) >> 2] = 0;
+        break;
+       }
+      } else {
+       i32 = (HEAP32[68 >> 2] | 0) + i10 | 0;
+       HEAP32[68 >> 2] = i32;
+       HEAP32[80 >> 2] = i7;
+       HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
+      }
+     } while (0);
+     i32 = i17 + (i6 | 8) | 0;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+    i3 = 504 | 0;
+    while (1) {
+     i2 = HEAP32[i3 >> 2] | 0;
+     if (!(i2 >>> 0 > i15 >>> 0) ? (i11 = HEAP32[i3 + 4 >> 2] | 0, i10 = i2 + i11 | 0, i10 >>> 0 > i15 >>> 0) : 0) {
+      break;
+     }
+     i3 = HEAP32[i3 + 8 >> 2] | 0;
+    }
+    i3 = i2 + (i11 + -39) | 0;
+    if ((i3 & 7 | 0) == 0) {
+     i3 = 0;
+    } else {
+     i3 = 0 - i3 & 7;
+    }
+    i2 = i2 + (i11 + -47 + i3) | 0;
+    i2 = i2 >>> 0 < (i15 + 16 | 0) >>> 0 ? i15 : i2;
+    i3 = i2 + 8 | 0;
+    i4 = i17 + 8 | 0;
+    if ((i4 & 7 | 0) == 0) {
+     i4 = 0;
+    } else {
+     i4 = 0 - i4 & 7;
+    }
+    i32 = i14 + -40 - i4 | 0;
+    HEAP32[80 >> 2] = i17 + i4;
+    HEAP32[68 >> 2] = i32;
+    HEAP32[i17 + (i4 + 4) >> 2] = i32 | 1;
+    HEAP32[i17 + (i14 + -36) >> 2] = 40;
+    HEAP32[84 >> 2] = HEAP32[544 >> 2];
+    HEAP32[i2 + 4 >> 2] = 27;
+    HEAP32[i3 + 0 >> 2] = HEAP32[504 >> 2];
+    HEAP32[i3 + 4 >> 2] = HEAP32[508 >> 2];
+    HEAP32[i3 + 8 >> 2] = HEAP32[512 >> 2];
+    HEAP32[i3 + 12 >> 2] = HEAP32[516 >> 2];
+    HEAP32[504 >> 2] = i17;
+    HEAP32[508 >> 2] = i14;
+    HEAP32[516 >> 2] = 0;
+    HEAP32[512 >> 2] = i3;
+    i4 = i2 + 28 | 0;
+    HEAP32[i4 >> 2] = 7;
+    if ((i2 + 32 | 0) >>> 0 < i10 >>> 0) {
+     while (1) {
+      i3 = i4 + 4 | 0;
+      HEAP32[i3 >> 2] = 7;
+      if ((i4 + 8 | 0) >>> 0 < i10 >>> 0) {
+       i4 = i3;
+      } else {
+       break;
+      }
+     }
+    }
+    if ((i2 | 0) != (i15 | 0)) {
+     i2 = i2 - i15 | 0;
+     i3 = i15 + (i2 + 4) | 0;
+     HEAP32[i3 >> 2] = HEAP32[i3 >> 2] & -2;
+     HEAP32[i15 + 4 >> 2] = i2 | 1;
+     HEAP32[i15 + i2 >> 2] = i2;
+     i3 = i2 >>> 3;
+     if (i2 >>> 0 < 256) {
+      i4 = i3 << 1;
+      i2 = 96 + (i4 << 2) | 0;
+      i5 = HEAP32[14] | 0;
+      i3 = 1 << i3;
+      if ((i5 & i3 | 0) != 0) {
+       i4 = 96 + (i4 + 2 << 2) | 0;
+       i3 = HEAP32[i4 >> 2] | 0;
+       if (i3 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        i7 = i4;
+        i8 = i3;
+       }
+      } else {
+       HEAP32[14] = i5 | i3;
+       i7 = 96 + (i4 + 2 << 2) | 0;
+       i8 = i2;
+      }
+      HEAP32[i7 >> 2] = i15;
+      HEAP32[i8 + 12 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i8;
+      HEAP32[i15 + 12 >> 2] = i2;
+      break;
+     }
+     i3 = i2 >>> 8;
+     if ((i3 | 0) != 0) {
+      if (i2 >>> 0 > 16777215) {
+       i3 = 31;
+      } else {
+       i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+       i32 = i3 << i31;
+       i30 = (i32 + 520192 | 0) >>> 16 & 4;
+       i32 = i32 << i30;
+       i3 = (i32 + 245760 | 0) >>> 16 & 2;
+       i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+       i3 = i2 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+      }
+     } else {
+      i3 = 0;
+     }
+     i7 = 360 + (i3 << 2) | 0;
+     HEAP32[i15 + 28 >> 2] = i3;
+     HEAP32[i15 + 20 >> 2] = 0;
+     HEAP32[i15 + 16 >> 2] = 0;
+     i4 = HEAP32[60 >> 2] | 0;
+     i5 = 1 << i3;
+     if ((i4 & i5 | 0) == 0) {
+      HEAP32[60 >> 2] = i4 | i5;
+      HEAP32[i7 >> 2] = i15;
+      HEAP32[i15 + 24 >> 2] = i7;
+      HEAP32[i15 + 12 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i15;
+      break;
+     }
+     i4 = HEAP32[i7 >> 2] | 0;
+     if ((i3 | 0) == 31) {
+      i3 = 0;
+     } else {
+      i3 = 25 - (i3 >>> 1) | 0;
+     }
+     L499 : do {
+      if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i2 | 0)) {
+       i3 = i2 << i3;
+       while (1) {
+        i7 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+        i5 = HEAP32[i7 >> 2] | 0;
+        if ((i5 | 0) == 0) {
+         break;
+        }
+        if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i2 | 0)) {
+         i6 = i5;
+         break L499;
+        } else {
+         i3 = i3 << 1;
+         i4 = i5;
+        }
+       }
+       if (i7 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i7 >> 2] = i15;
+        HEAP32[i15 + 24 >> 2] = i4;
+        HEAP32[i15 + 12 >> 2] = i15;
+        HEAP32[i15 + 8 >> 2] = i15;
+        break L311;
+       }
+      } else {
+       i6 = i4;
+      }
+     } while (0);
+     i4 = i6 + 8 | 0;
+     i3 = HEAP32[i4 >> 2] | 0;
+     i2 = HEAP32[72 >> 2] | 0;
+     if (i6 >>> 0 < i2 >>> 0) {
+      _abort();
+     }
+     if (i3 >>> 0 < i2 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i3 + 12 >> 2] = i15;
+      HEAP32[i4 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i3;
+      HEAP32[i15 + 12 >> 2] = i6;
+      HEAP32[i15 + 24 >> 2] = 0;
+      break;
+     }
+    }
+   } else {
+    i32 = HEAP32[72 >> 2] | 0;
+    if ((i32 | 0) == 0 | i17 >>> 0 < i32 >>> 0) {
+     HEAP32[72 >> 2] = i17;
+    }
+    HEAP32[504 >> 2] = i17;
+    HEAP32[508 >> 2] = i14;
+    HEAP32[516 >> 2] = 0;
+    HEAP32[92 >> 2] = HEAP32[132];
+    HEAP32[88 >> 2] = -1;
+    i2 = 0;
+    do {
+     i32 = i2 << 1;
+     i31 = 96 + (i32 << 2) | 0;
+     HEAP32[96 + (i32 + 3 << 2) >> 2] = i31;
+     HEAP32[96 + (i32 + 2 << 2) >> 2] = i31;
+     i2 = i2 + 1 | 0;
+    } while ((i2 | 0) != 32);
+    i2 = i17 + 8 | 0;
+    if ((i2 & 7 | 0) == 0) {
+     i2 = 0;
+    } else {
+     i2 = 0 - i2 & 7;
+    }
+    i32 = i14 + -40 - i2 | 0;
+    HEAP32[80 >> 2] = i17 + i2;
+    HEAP32[68 >> 2] = i32;
+    HEAP32[i17 + (i2 + 4) >> 2] = i32 | 1;
+    HEAP32[i17 + (i14 + -36) >> 2] = 40;
+    HEAP32[84 >> 2] = HEAP32[544 >> 2];
+   }
+  } while (0);
+  i2 = HEAP32[68 >> 2] | 0;
+  if (i2 >>> 0 > i12 >>> 0) {
+   i31 = i2 - i12 | 0;
+   HEAP32[68 >> 2] = i31;
+   i32 = HEAP32[80 >> 2] | 0;
+   HEAP32[80 >> 2] = i32 + i12;
+   HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
+   HEAP32[i32 + 4 >> 2] = i12 | 3;
+   i32 = i32 + 8 | 0;
+   STACKTOP = i1;
+   return i32 | 0;
+  }
+ }
+ HEAP32[(___errno_location() | 0) >> 2] = 12;
+ i32 = 0;
+ STACKTOP = i1;
+ return i32 | 0;
+}
+function _free(i7) {
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0;
+ i1 = STACKTOP;
+ if ((i7 | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i15 = i7 + -8 | 0;
+ i16 = HEAP32[72 >> 2] | 0;
+ if (i15 >>> 0 < i16 >>> 0) {
+  _abort();
+ }
+ i13 = HEAP32[i7 + -4 >> 2] | 0;
+ i12 = i13 & 3;
+ if ((i12 | 0) == 1) {
+  _abort();
+ }
+ i8 = i13 & -8;
+ i6 = i7 + (i8 + -8) | 0;
+ do {
+  if ((i13 & 1 | 0) == 0) {
+   i19 = HEAP32[i15 >> 2] | 0;
+   if ((i12 | 0) == 0) {
+    STACKTOP = i1;
+    return;
+   }
+   i15 = -8 - i19 | 0;
+   i13 = i7 + i15 | 0;
+   i12 = i19 + i8 | 0;
+   if (i13 >>> 0 < i16 >>> 0) {
+    _abort();
+   }
+   if ((i13 | 0) == (HEAP32[76 >> 2] | 0)) {
+    i2 = i7 + (i8 + -4) | 0;
+    if ((HEAP32[i2 >> 2] & 3 | 0) != 3) {
+     i2 = i13;
+     i11 = i12;
+     break;
+    }
+    HEAP32[64 >> 2] = i12;
+    HEAP32[i2 >> 2] = HEAP32[i2 >> 2] & -2;
+    HEAP32[i7 + (i15 + 4) >> 2] = i12 | 1;
+    HEAP32[i6 >> 2] = i12;
+    STACKTOP = i1;
+    return;
+   }
+   i18 = i19 >>> 3;
+   if (i19 >>> 0 < 256) {
+    i2 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
+    i11 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
+    i14 = 96 + (i18 << 1 << 2) | 0;
+    if ((i2 | 0) != (i14 | 0)) {
+     if (i2 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i2 + 12 >> 2] | 0) != (i13 | 0)) {
+      _abort();
+     }
+    }
+    if ((i11 | 0) == (i2 | 0)) {
+     HEAP32[14] = HEAP32[14] & ~(1 << i18);
+     i2 = i13;
+     i11 = i12;
+     break;
+    }
+    if ((i11 | 0) != (i14 | 0)) {
+     if (i11 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     i14 = i11 + 8 | 0;
+     if ((HEAP32[i14 >> 2] | 0) == (i13 | 0)) {
+      i17 = i14;
+     } else {
+      _abort();
+     }
+    } else {
+     i17 = i11 + 8 | 0;
+    }
+    HEAP32[i2 + 12 >> 2] = i11;
+    HEAP32[i17 >> 2] = i2;
+    i2 = i13;
+    i11 = i12;
+    break;
+   }
+   i17 = HEAP32[i7 + (i15 + 24) >> 2] | 0;
+   i18 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
+   do {
+    if ((i18 | 0) == (i13 | 0)) {
+     i19 = i7 + (i15 + 20) | 0;
+     i18 = HEAP32[i19 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      i19 = i7 + (i15 + 16) | 0;
+      i18 = HEAP32[i19 >> 2] | 0;
+      if ((i18 | 0) == 0) {
+       i14 = 0;
+       break;
+      }
+     }
+     while (1) {
+      i21 = i18 + 20 | 0;
+      i20 = HEAP32[i21 >> 2] | 0;
+      if ((i20 | 0) != 0) {
+       i18 = i20;
+       i19 = i21;
+       continue;
+      }
+      i20 = i18 + 16 | 0;
+      i21 = HEAP32[i20 >> 2] | 0;
+      if ((i21 | 0) == 0) {
+       break;
+      } else {
+       i18 = i21;
+       i19 = i20;
+      }
+     }
+     if (i19 >>> 0 < i16 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i19 >> 2] = 0;
+      i14 = i18;
+      break;
+     }
+    } else {
+     i19 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
+     if (i19 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     i16 = i19 + 12 | 0;
+     if ((HEAP32[i16 >> 2] | 0) != (i13 | 0)) {
+      _abort();
+     }
+     i20 = i18 + 8 | 0;
+     if ((HEAP32[i20 >> 2] | 0) == (i13 | 0)) {
+      HEAP32[i16 >> 2] = i18;
+      HEAP32[i20 >> 2] = i19;
+      i14 = i18;
+      break;
+     } else {
+      _abort();
+     }
+    }
+   } while (0);
+   if ((i17 | 0) != 0) {
+    i18 = HEAP32[i7 + (i15 + 28) >> 2] | 0;
+    i16 = 360 + (i18 << 2) | 0;
+    if ((i13 | 0) == (HEAP32[i16 >> 2] | 0)) {
+     HEAP32[i16 >> 2] = i14;
+     if ((i14 | 0) == 0) {
+      HEAP32[60 >> 2] = HEAP32[60 >> 2] & ~(1 << i18);
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    } else {
+     if (i17 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i16 = i17 + 16 | 0;
+     if ((HEAP32[i16 >> 2] | 0) == (i13 | 0)) {
+      HEAP32[i16 >> 2] = i14;
+     } else {
+      HEAP32[i17 + 20 >> 2] = i14;
+     }
+     if ((i14 | 0) == 0) {
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    }
+    if (i14 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+     _abort();
+    }
+    HEAP32[i14 + 24 >> 2] = i17;
+    i16 = HEAP32[i7 + (i15 + 16) >> 2] | 0;
+    do {
+     if ((i16 | 0) != 0) {
+      if (i16 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i14 + 16 >> 2] = i16;
+       HEAP32[i16 + 24 >> 2] = i14;
+       break;
+      }
+     }
+    } while (0);
+    i15 = HEAP32[i7 + (i15 + 20) >> 2] | 0;
+    if ((i15 | 0) != 0) {
+     if (i15 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i14 + 20 >> 2] = i15;
+      HEAP32[i15 + 24 >> 2] = i14;
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    } else {
+     i2 = i13;
+     i11 = i12;
+    }
+   } else {
+    i2 = i13;
+    i11 = i12;
+   }
+  } else {
+   i2 = i15;
+   i11 = i8;
+  }
+ } while (0);
+ if (!(i2 >>> 0 < i6 >>> 0)) {
+  _abort();
+ }
+ i12 = i7 + (i8 + -4) | 0;
+ i13 = HEAP32[i12 >> 2] | 0;
+ if ((i13 & 1 | 0) == 0) {
+  _abort();
+ }
+ if ((i13 & 2 | 0) == 0) {
+  if ((i6 | 0) == (HEAP32[80 >> 2] | 0)) {
+   i21 = (HEAP32[68 >> 2] | 0) + i11 | 0;
+   HEAP32[68 >> 2] = i21;
+   HEAP32[80 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i21 | 1;
+   if ((i2 | 0) != (HEAP32[76 >> 2] | 0)) {
+    STACKTOP = i1;
+    return;
+   }
+   HEAP32[76 >> 2] = 0;
+   HEAP32[64 >> 2] = 0;
+   STACKTOP = i1;
+   return;
+  }
+  if ((i6 | 0) == (HEAP32[76 >> 2] | 0)) {
+   i21 = (HEAP32[64 >> 2] | 0) + i11 | 0;
+   HEAP32[64 >> 2] = i21;
+   HEAP32[76 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i21 | 1;
+   HEAP32[i2 + i21 >> 2] = i21;
+   STACKTOP = i1;
+   return;
+  }
+  i11 = (i13 & -8) + i11 | 0;
+  i12 = i13 >>> 3;
+  do {
+   if (!(i13 >>> 0 < 256)) {
+    i10 = HEAP32[i7 + (i8 + 16) >> 2] | 0;
+    i15 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
+    do {
+     if ((i15 | 0) == (i6 | 0)) {
+      i13 = i7 + (i8 + 12) | 0;
+      i12 = HEAP32[i13 >> 2] | 0;
+      if ((i12 | 0) == 0) {
+       i13 = i7 + (i8 + 8) | 0;
+       i12 = HEAP32[i13 >> 2] | 0;
+       if ((i12 | 0) == 0) {
+        i9 = 0;
+        break;
+       }
+      }
+      while (1) {
+       i14 = i12 + 20 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) != 0) {
+        i12 = i15;
+        i13 = i14;
+        continue;
+       }
+       i14 = i12 + 16 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) == 0) {
+        break;
+       } else {
+        i12 = i15;
+        i13 = i14;
+       }
+      }
+      if (i13 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i13 >> 2] = 0;
+       i9 = i12;
+       break;
+      }
+     } else {
+      i13 = HEAP32[i7 + i8 >> 2] | 0;
+      if (i13 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i14 = i13 + 12 | 0;
+      if ((HEAP32[i14 >> 2] | 0) != (i6 | 0)) {
+       _abort();
+      }
+      i12 = i15 + 8 | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+       HEAP32[i14 >> 2] = i15;
+       HEAP32[i12 >> 2] = i13;
+       i9 = i15;
+       break;
+      } else {
+       _abort();
+      }
+     }
+    } while (0);
+    if ((i10 | 0) != 0) {
+     i12 = HEAP32[i7 + (i8 + 20) >> 2] | 0;
+     i13 = 360 + (i12 << 2) | 0;
+     if ((i6 | 0) == (HEAP32[i13 >> 2] | 0)) {
+      HEAP32[i13 >> 2] = i9;
+      if ((i9 | 0) == 0) {
+       HEAP32[60 >> 2] = HEAP32[60 >> 2] & ~(1 << i12);
+       break;
+      }
+     } else {
+      if (i10 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i12 = i10 + 16 | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+       HEAP32[i12 >> 2] = i9;
+      } else {
+       HEAP32[i10 + 20 >> 2] = i9;
+      }
+      if ((i9 | 0) == 0) {
+       break;
+      }
+     }
+     if (i9 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     HEAP32[i9 + 24 >> 2] = i10;
+     i6 = HEAP32[i7 + (i8 + 8) >> 2] | 0;
+     do {
+      if ((i6 | 0) != 0) {
+       if (i6 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i9 + 16 >> 2] = i6;
+        HEAP32[i6 + 24 >> 2] = i9;
+        break;
+       }
+      }
+     } while (0);
+     i6 = HEAP32[i7 + (i8 + 12) >> 2] | 0;
+     if ((i6 | 0) != 0) {
+      if (i6 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i9 + 20 >> 2] = i6;
+       HEAP32[i6 + 24 >> 2] = i9;
+       break;
+      }
+     }
+    }
+   } else {
+    i9 = HEAP32[i7 + i8 >> 2] | 0;
+    i7 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
+    i8 = 96 + (i12 << 1 << 2) | 0;
+    if ((i9 | 0) != (i8 | 0)) {
+     if (i9 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i9 + 12 >> 2] | 0) != (i6 | 0)) {
+      _abort();
+     }
+    }
+    if ((i7 | 0) == (i9 | 0)) {
+     HEAP32[14] = HEAP32[14] & ~(1 << i12);
+     break;
+    }
+    if ((i7 | 0) != (i8 | 0)) {
+     if (i7 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i8 = i7 + 8 | 0;
+     if ((HEAP32[i8 >> 2] | 0) == (i6 | 0)) {
+      i10 = i8;
+     } else {
+      _abort();
+     }
+    } else {
+     i10 = i7 + 8 | 0;
+    }
+    HEAP32[i9 + 12 >> 2] = i7;
+    HEAP32[i10 >> 2] = i9;
+   }
+  } while (0);
+  HEAP32[i2 + 4 >> 2] = i11 | 1;
+  HEAP32[i2 + i11 >> 2] = i11;
+  if ((i2 | 0) == (HEAP32[76 >> 2] | 0)) {
+   HEAP32[64 >> 2] = i11;
+   STACKTOP = i1;
+   return;
+  }
+ } else {
+  HEAP32[i12 >> 2] = i13 & -2;
+  HEAP32[i2 + 4 >> 2] = i11 | 1;
+  HEAP32[i2 + i11 >> 2] = i11;
+ }
+ i6 = i11 >>> 3;
+ if (i11 >>> 0 < 256) {
+  i7 = i6 << 1;
+  i3 = 96 + (i7 << 2) | 0;
+  i8 = HEAP32[14] | 0;
+  i6 = 1 << i6;
+  if ((i8 & i6 | 0) != 0) {
+   i6 = 96 + (i7 + 2 << 2) | 0;
+   i7 = HEAP32[i6 >> 2] | 0;
+   if (i7 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+    _abort();
+   } else {
+    i4 = i6;
+    i5 = i7;
+   }
+  } else {
+   HEAP32[14] = i8 | i6;
+   i4 = 96 + (i7 + 2 << 2) | 0;
+   i5 = i3;
+  }
+  HEAP32[i4 >> 2] = i2;
+  HEAP32[i5 + 12 >> 2] = i2;
+  HEAP32[i2 + 8 >> 2] = i5;
+  HEAP32[i2 + 12 >> 2] = i3;
+  STACKTOP = i1;
+  return;
+ }
+ i4 = i11 >>> 8;
+ if ((i4 | 0) != 0) {
+  if (i11 >>> 0 > 16777215) {
+   i4 = 31;
+  } else {
+   i20 = (i4 + 1048320 | 0) >>> 16 & 8;
+   i21 = i4 << i20;
+   i19 = (i21 + 520192 | 0) >>> 16 & 4;
+   i21 = i21 << i19;
+   i4 = (i21 + 245760 | 0) >>> 16 & 2;
+   i4 = 14 - (i19 | i20 | i4) + (i21 << i4 >>> 15) | 0;
+   i4 = i11 >>> (i4 + 7 | 0) & 1 | i4 << 1;
+  }
+ } else {
+  i4 = 0;
+ }
+ i5 = 360 + (i4 << 2) | 0;
+ HEAP32[i2 + 28 >> 2] = i4;
+ HEAP32[i2 + 20 >> 2] = 0;
+ HEAP32[i2 + 16 >> 2] = 0;
+ i7 = HEAP32[60 >> 2] | 0;
+ i6 = 1 << i4;
+ L199 : do {
+  if ((i7 & i6 | 0) != 0) {
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((i4 | 0) == 31) {
+    i4 = 0;
+   } else {
+    i4 = 25 - (i4 >>> 1) | 0;
+   }
+   L205 : do {
+    if ((HEAP32[i5 + 4 >> 2] & -8 | 0) != (i11 | 0)) {
+     i4 = i11 << i4;
+     i7 = i5;
+     while (1) {
+      i6 = i7 + (i4 >>> 31 << 2) + 16 | 0;
+      i5 = HEAP32[i6 >> 2] | 0;
+      if ((i5 | 0) == 0) {
+       break;
+      }
+      if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i11 | 0)) {
+       i3 = i5;
+       break L205;
+      } else {
+       i4 = i4 << 1;
+       i7 = i5;
+      }
+     }
+     if (i6 >>> 0 < (HEAP32[72 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i6 >> 2] = i2;
+      HEAP32[i2 + 24 >> 2] = i7;
+      HEAP32[i2 + 12 >> 2] = i2;
+      HEAP32[i2 + 8 >> 2] = i2;
+      break L199;
+     }
+    } else {
+     i3 = i5;
+    }
+   } while (0);
+   i5 = i3 + 8 | 0;
+   i4 = HEAP32[i5 >> 2] | 0;
+   i6 = HEAP32[72 >> 2] | 0;
+   if (i3 >>> 0 < i6 >>> 0) {
+    _abort();
+   }
+   if (i4 >>> 0 < i6 >>> 0) {
+    _abort();
+   } else {
+    HEAP32[i4 + 12 >> 2] = i2;
+    HEAP32[i5 >> 2] = i2;
+    HEAP32[i2 + 8 >> 2] = i4;
+    HEAP32[i2 + 12 >> 2] = i3;
+    HEAP32[i2 + 24 >> 2] = 0;
+    break;
+   }
+  } else {
+   HEAP32[60 >> 2] = i7 | i6;
+   HEAP32[i5 >> 2] = i2;
+   HEAP32[i2 + 24 >> 2] = i5;
+   HEAP32[i2 + 12 >> 2] = i2;
+   HEAP32[i2 + 8 >> 2] = i2;
+  }
+ } while (0);
+ i21 = (HEAP32[88 >> 2] | 0) + -1 | 0;
+ HEAP32[88 >> 2] = i21;
+ if ((i21 | 0) == 0) {
+  i2 = 512 | 0;
+ } else {
+  STACKTOP = i1;
+  return;
+ }
+ while (1) {
+  i2 = HEAP32[i2 >> 2] | 0;
+  if ((i2 | 0) == 0) {
+   break;
+  } else {
+   i2 = i2 + 8 | 0;
+  }
+ }
+ HEAP32[88 >> 2] = -1;
+ STACKTOP = i1;
+ return;
+}
+function __Z15fannkuch_workerPv(i9) {
+ i9 = i9 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0;
+ i3 = STACKTOP;
+ i7 = HEAP32[i9 + 4 >> 2] | 0;
+ i6 = i7 << 2;
+ i5 = _malloc(i6) | 0;
+ i2 = _malloc(i6) | 0;
+ i6 = _malloc(i6) | 0;
+ i10 = (i7 | 0) > 0;
+ if (i10) {
+  i8 = 0;
+  do {
+   HEAP32[i5 + (i8 << 2) >> 2] = i8;
+   i8 = i8 + 1 | 0;
+  } while ((i8 | 0) != (i7 | 0));
+  i8 = i7 + -1 | 0;
+  i17 = HEAP32[i9 >> 2] | 0;
+  HEAP32[i5 + (i17 << 2) >> 2] = i8;
+  i9 = i5 + (i8 << 2) | 0;
+  HEAP32[i9 >> 2] = i17;
+  if (i10) {
+   i10 = i7 << 2;
+   i11 = 0;
+   i12 = i7;
+   L7 : while (1) {
+    if ((i12 | 0) > 1) {
+     while (1) {
+      i13 = i12 + -1 | 0;
+      HEAP32[i6 + (i13 << 2) >> 2] = i12;
+      if ((i13 | 0) > 1) {
+       i12 = i13;
+      } else {
+       i12 = 1;
+       break;
+      }
+     }
+    }
+    i13 = HEAP32[i5 >> 2] | 0;
+    if ((i13 | 0) != 0 ? (HEAP32[i9 >> 2] | 0) != (i8 | 0) : 0) {
+     _memcpy(i2 | 0, i5 | 0, i10 | 0) | 0;
+     i15 = 0;
+     i14 = HEAP32[i2 >> 2] | 0;
+     while (1) {
+      i17 = i14 + -1 | 0;
+      if ((i17 | 0) > 1) {
+       i16 = 1;
+       do {
+        i20 = i2 + (i16 << 2) | 0;
+        i19 = HEAP32[i20 >> 2] | 0;
+        i18 = i2 + (i17 << 2) | 0;
+        HEAP32[i20 >> 2] = HEAP32[i18 >> 2];
+        HEAP32[i18 >> 2] = i19;
+        i16 = i16 + 1 | 0;
+        i17 = i17 + -1 | 0;
+       } while ((i16 | 0) < (i17 | 0));
+      }
+      i15 = i15 + 1 | 0;
+      i20 = i2 + (i14 << 2) | 0;
+      i16 = HEAP32[i20 >> 2] | 0;
+      HEAP32[i20 >> 2] = i14;
+      if ((i16 | 0) == 0) {
+       break;
+      } else {
+       i14 = i16;
+      }
+     }
+     i11 = (i11 | 0) < (i15 | 0) ? i15 : i11;
+    }
+    if ((i12 | 0) >= (i8 | 0)) {
+     i8 = 34;
+     break;
+    }
+    while (1) {
+     if ((i12 | 0) > 0) {
+      i14 = 0;
+      while (1) {
+       i15 = i14 + 1 | 0;
+       HEAP32[i5 + (i14 << 2) >> 2] = HEAP32[i5 + (i15 << 2) >> 2];
+       if ((i15 | 0) == (i12 | 0)) {
+        i14 = i12;
+        break;
+       } else {
+        i14 = i15;
+       }
+      }
+     } else {
+      i14 = 0;
+     }
+     HEAP32[i5 + (i14 << 2) >> 2] = i13;
+     i14 = i6 + (i12 << 2) | 0;
+     i20 = (HEAP32[i14 >> 2] | 0) + -1 | 0;
+     HEAP32[i14 >> 2] = i20;
+     i14 = i12 + 1 | 0;
+     if ((i20 | 0) > 0) {
+      continue L7;
+     }
+     if ((i14 | 0) >= (i8 | 0)) {
+      i8 = 34;
+      break L7;
+     }
+     i13 = HEAP32[i5 >> 2] | 0;
+     i12 = i14;
+    }
+   }
+   if ((i8 | 0) == 34) {
+    _free(i5);
+    _free(i2);
+    _free(i6);
+    STACKTOP = i3;
+    return i11 | 0;
+   }
+  } else {
+   i1 = i9;
+   i4 = i8;
+  }
+ } else {
+  i4 = i7 + -1 | 0;
+  i20 = HEAP32[i9 >> 2] | 0;
+  HEAP32[i5 + (i20 << 2) >> 2] = i4;
+  i1 = i5 + (i4 << 2) | 0;
+  HEAP32[i1 >> 2] = i20;
+ }
+ i11 = 0;
+ L36 : while (1) {
+  if ((i7 | 0) > 1) {
+   while (1) {
+    i8 = i7 + -1 | 0;
+    HEAP32[i6 + (i8 << 2) >> 2] = i7;
+    if ((i8 | 0) > 1) {
+     i7 = i8;
+    } else {
+     i7 = 1;
+     break;
+    }
+   }
+  }
+  i8 = HEAP32[i5 >> 2] | 0;
+  if ((i8 | 0) != 0 ? (HEAP32[i1 >> 2] | 0) != (i4 | 0) : 0) {
+   i10 = 0;
+   i9 = HEAP32[i2 >> 2] | 0;
+   while (1) {
+    i13 = i9 + -1 | 0;
+    if ((i13 | 0) > 1) {
+     i12 = 1;
+     do {
+      i18 = i2 + (i12 << 2) | 0;
+      i19 = HEAP32[i18 >> 2] | 0;
+      i20 = i2 + (i13 << 2) | 0;
+      HEAP32[i18 >> 2] = HEAP32[i20 >> 2];
+      HEAP32[i20 >> 2] = i19;
+      i12 = i12 + 1 | 0;
+      i13 = i13 + -1 | 0;
+     } while ((i12 | 0) < (i13 | 0));
+    }
+    i10 = i10 + 1 | 0;
+    i20 = i2 + (i9 << 2) | 0;
+    i12 = HEAP32[i20 >> 2] | 0;
+    HEAP32[i20 >> 2] = i9;
+    if ((i12 | 0) == 0) {
+     break;
+    } else {
+     i9 = i12;
+    }
+   }
+   i11 = (i11 | 0) < (i10 | 0) ? i10 : i11;
+  }
+  if ((i7 | 0) >= (i4 | 0)) {
+   i8 = 34;
+   break;
+  }
+  while (1) {
+   if ((i7 | 0) > 0) {
+    i9 = 0;
+    while (1) {
+     i10 = i9 + 1 | 0;
+     HEAP32[i5 + (i9 << 2) >> 2] = HEAP32[i5 + (i10 << 2) >> 2];
+     if ((i10 | 0) == (i7 | 0)) {
+      i9 = i7;
+      break;
+     } else {
+      i9 = i10;
+     }
+    }
+   } else {
+    i9 = 0;
+   }
+   HEAP32[i5 + (i9 << 2) >> 2] = i8;
+   i9 = i6 + (i7 << 2) | 0;
+   i20 = (HEAP32[i9 >> 2] | 0) + -1 | 0;
+   HEAP32[i9 >> 2] = i20;
+   i9 = i7 + 1 | 0;
+   if ((i20 | 0) > 0) {
+    continue L36;
+   }
+   if ((i9 | 0) >= (i4 | 0)) {
+    i8 = 34;
+    break L36;
+   }
+   i8 = HEAP32[i5 >> 2] | 0;
+   i7 = i9;
+  }
+ }
+ if ((i8 | 0) == 34) {
+  _free(i5);
+  _free(i2);
+  _free(i6);
+  STACKTOP = i3;
+  return i11 | 0;
+ }
+ return 0;
+}
+function _main(i3, i5) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i1 = i2;
+ L1 : do {
+  if ((i3 | 0) > 1) {
+   i3 = HEAP8[HEAP32[i5 + 4 >> 2] | 0] | 0;
+   switch (i3 | 0) {
+   case 50:
+    {
+     i3 = 10;
+     break L1;
+    }
+   case 51:
+    {
+     i4 = 4;
+     break L1;
+    }
+   case 52:
+    {
+     i3 = 11;
+     break L1;
+    }
+   case 53:
+    {
+     i3 = 12;
+     break L1;
+    }
+   case 49:
+    {
+     i3 = 9;
+     break L1;
+    }
+   case 48:
+    {
+     i11 = 0;
+     STACKTOP = i2;
+     return i11 | 0;
+    }
+   default:
+    {
+     HEAP32[i1 >> 2] = i3 + -48;
+     _printf(8, i1 | 0) | 0;
+     i11 = -1;
+     STACKTOP = i2;
+     return i11 | 0;
+    }
+   }
+  } else {
+   i4 = 4;
+  }
+ } while (0);
+ if ((i4 | 0) == 4) {
+  i3 = 11;
+ }
+ i5 = i3 + -1 | 0;
+ i6 = 0;
+ i7 = 0;
+ while (1) {
+  i4 = _malloc(12) | 0;
+  HEAP32[i4 >> 2] = i7;
+  HEAP32[i4 + 4 >> 2] = i3;
+  HEAP32[i4 + 8 >> 2] = i6;
+  i7 = i7 + 1 | 0;
+  if ((i7 | 0) == (i5 | 0)) {
+   break;
+  } else {
+   i6 = i4;
+  }
+ }
+ i5 = i3 << 2;
+ i6 = _malloc(i5) | 0;
+ i5 = _malloc(i5) | 0;
+ i7 = 0;
+ do {
+  HEAP32[i6 + (i7 << 2) >> 2] = i7;
+  i7 = i7 + 1 | 0;
+ } while ((i7 | 0) != (i3 | 0));
+ i8 = i3;
+ i7 = 30;
+ L19 : do {
+  i9 = 0;
+  do {
+   HEAP32[i1 >> 2] = (HEAP32[i6 + (i9 << 2) >> 2] | 0) + 1;
+   _printf(48, i1 | 0) | 0;
+   i9 = i9 + 1 | 0;
+  } while ((i9 | 0) != (i3 | 0));
+  _putchar(10) | 0;
+  i7 = i7 + -1 | 0;
+  if ((i8 | 0) <= 1) {
+   if ((i8 | 0) == (i3 | 0)) {
+    break;
+   }
+  } else {
+   while (1) {
+    i9 = i8 + -1 | 0;
+    HEAP32[i5 + (i9 << 2) >> 2] = i8;
+    if ((i9 | 0) > 1) {
+     i8 = i9;
+    } else {
+     i8 = 1;
+     break;
+    }
+   }
+  }
+  while (1) {
+   i9 = HEAP32[i6 >> 2] | 0;
+   if ((i8 | 0) > 0) {
+    i11 = 0;
+    while (1) {
+     i10 = i11 + 1 | 0;
+     HEAP32[i6 + (i11 << 2) >> 2] = HEAP32[i6 + (i10 << 2) >> 2];
+     if ((i10 | 0) == (i8 | 0)) {
+      i10 = i8;
+      break;
+     } else {
+      i11 = i10;
+     }
+    }
+   } else {
+    i10 = 0;
+   }
+   HEAP32[i6 + (i10 << 2) >> 2] = i9;
+   i9 = i5 + (i8 << 2) | 0;
+   i11 = (HEAP32[i9 >> 2] | 0) + -1 | 0;
+   HEAP32[i9 >> 2] = i11;
+   i9 = i8 + 1 | 0;
+   if ((i11 | 0) > 0) {
+    break;
+   }
+   if ((i9 | 0) == (i3 | 0)) {
+    break L19;
+   } else {
+    i8 = i9;
+   }
+  }
+ } while ((i7 | 0) != 0);
+ _free(i6);
+ _free(i5);
+ if ((i4 | 0) == 0) {
+  i5 = 0;
+ } else {
+  i5 = 0;
+  while (1) {
+   i6 = __Z15fannkuch_workerPv(i4) | 0;
+   i5 = (i5 | 0) < (i6 | 0) ? i6 : i5;
+   i6 = HEAP32[i4 + 8 >> 2] | 0;
+   _free(i4);
+   if ((i6 | 0) == 0) {
+    break;
+   } else {
+    i4 = i6;
+   }
+  }
+ }
+ HEAP32[i1 >> 2] = i3;
+ HEAP32[i1 + 4 >> 2] = i5;
+ _printf(24, i1 | 0) | 0;
+ i11 = 0;
+ STACKTOP = i2;
+ return i11 | 0;
+}
+function _memcpy(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ if ((i1 | 0) >= 4096) return _emscripten_memcpy_big(i3 | 0, i2 | 0, i1 | 0) | 0;
+ i4 = i3 | 0;
+ if ((i3 & 3) == (i2 & 3)) {
+  while (i3 & 3) {
+   if ((i1 | 0) == 0) return i4 | 0;
+   HEAP8[i3] = HEAP8[i2] | 0;
+   i3 = i3 + 1 | 0;
+   i2 = i2 + 1 | 0;
+   i1 = i1 - 1 | 0;
+  }
+  while ((i1 | 0) >= 4) {
+   HEAP32[i3 >> 2] = HEAP32[i2 >> 2];
+   i3 = i3 + 4 | 0;
+   i2 = i2 + 4 | 0;
+   i1 = i1 - 4 | 0;
+  }
+ }
+ while ((i1 | 0) > 0) {
+  HEAP8[i3] = HEAP8[i2] | 0;
+  i3 = i3 + 1 | 0;
+  i2 = i2 + 1 | 0;
+  i1 = i1 - 1 | 0;
+ }
+ return i4 | 0;
+}
+function _memset(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = i1 + i3 | 0;
+ if ((i3 | 0) >= 20) {
+  i4 = i4 & 255;
+  i7 = i1 & 3;
+  i6 = i4 | i4 << 8 | i4 << 16 | i4 << 24;
+  i5 = i2 & ~3;
+  if (i7) {
+   i7 = i1 + 4 - i7 | 0;
+   while ((i1 | 0) < (i7 | 0)) {
+    HEAP8[i1] = i4;
+    i1 = i1 + 1 | 0;
+   }
+  }
+  while ((i1 | 0) < (i5 | 0)) {
+   HEAP32[i1 >> 2] = i6;
+   i1 = i1 + 4 | 0;
+  }
+ }
+ while ((i1 | 0) < (i2 | 0)) {
+  HEAP8[i1] = i4;
+  i1 = i1 + 1 | 0;
+ }
+ return i1 - i3 | 0;
+}
+function copyTempDouble(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+ HEAP8[tempDoublePtr + 4 | 0] = HEAP8[i1 + 4 | 0];
+ HEAP8[tempDoublePtr + 5 | 0] = HEAP8[i1 + 5 | 0];
+ HEAP8[tempDoublePtr + 6 | 0] = HEAP8[i1 + 6 | 0];
+ HEAP8[tempDoublePtr + 7 | 0] = HEAP8[i1 + 7 | 0];
+}
+function copyTempFloat(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+}
+function runPostSets() {}
+function _strlen(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = i1;
+ while (HEAP8[i2] | 0) {
+  i2 = i2 + 1 | 0;
+ }
+ return i2 - i1 | 0;
+}
+function stackAlloc(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + i1 | 0;
+ STACKTOP = STACKTOP + 7 & -8;
+ return i2 | 0;
+}
+function setThrew(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ if ((__THREW__ | 0) == 0) {
+  __THREW__ = i1;
+  threwValue = i2;
+ }
+}
+function stackRestore(i1) {
+ i1 = i1 | 0;
+ STACKTOP = i1;
+}
+function setTempRet9(i1) {
+ i1 = i1 | 0;
+ tempRet9 = i1;
+}
+function setTempRet8(i1) {
+ i1 = i1 | 0;
+ tempRet8 = i1;
+}
+function setTempRet7(i1) {
+ i1 = i1 | 0;
+ tempRet7 = i1;
+}
+function setTempRet6(i1) {
+ i1 = i1 | 0;
+ tempRet6 = i1;
+}
+function setTempRet5(i1) {
+ i1 = i1 | 0;
+ tempRet5 = i1;
+}
+function setTempRet4(i1) {
+ i1 = i1 | 0;
+ tempRet4 = i1;
+}
+function setTempRet3(i1) {
+ i1 = i1 | 0;
+ tempRet3 = i1;
+}
+function setTempRet2(i1) {
+ i1 = i1 | 0;
+ tempRet2 = i1;
+}
+function setTempRet1(i1) {
+ i1 = i1 | 0;
+ tempRet1 = i1;
+}
+function setTempRet0(i1) {
+ i1 = i1 | 0;
+ tempRet0 = i1;
+}
+function stackSave() {
+ return STACKTOP | 0;
+}
+
+// EMSCRIPTEN_END_FUNCS
+
+
+  return { _strlen: _strlen, _free: _free, _main: _main, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, setTempRet1: setTempRet1, setTempRet2: setTempRet2, setTempRet3: setTempRet3, setTempRet4: setTempRet4, setTempRet5: setTempRet5, setTempRet6: setTempRet6, setTempRet7: setTempRet7, setTempRet8: setTempRet8, setTempRet9: setTempRet9 };
+})
+// EMSCRIPTEN_END_ASM
+({ "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array }, { "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "_fflush": _fflush, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_putchar": _putchar, "_fputc": _fputc, "_send": _send, "_pwrite": _pwrite, "_abort": _abort, "__reallyNegative": __reallyNegative, "_fwrite": _fwrite, "_sbrk": _sbrk, "_mkport": _mkport, "_fprintf": _fprintf, "___setErrNo": ___setErrNo, "__formatString": __formatString, "_fileno": _fileno, "_printf": _printf, "_time": _time, "_sysconf": _sysconf, "_write": _write, "___errno_location": ___errno_location, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "NaN": NaN, "Infinity": Infinity }, buffer);
+var _strlen = Module["_strlen"] = asm["_strlen"];
+var _free = Module["_free"] = asm["_free"];
+var _main = Module["_main"] = asm["_main"];
+var _memset = Module["_memset"] = asm["_memset"];
+var _malloc = Module["_malloc"] = asm["_malloc"];
+var _memcpy = Module["_memcpy"] = asm["_memcpy"];
+var runPostSets = Module["runPostSets"] = asm["runPostSets"];
+
+Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
+Runtime.stackSave = function() { return asm['stackSave']() };
+Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
+
+
+// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included
+var i64Math = null;
+
+// === Auto-generated postamble setup entry stuff ===
+
+if (memoryInitializer) {
+  if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
+    var data = Module['readBinary'](memoryInitializer);
+    HEAPU8.set(data, STATIC_BASE);
+  } else {
+    addRunDependency('memory initializer');
+    Browser.asyncLoad(memoryInitializer, function(data) {
+      HEAPU8.set(data, STATIC_BASE);
+      removeRunDependency('memory initializer');
+    }, function(data) {
+      throw 'could not load memory initializer ' + memoryInitializer;
+    });
+  }
+}
+
+function ExitStatus(status) {
+  this.name = "ExitStatus";
+  this.message = "Program terminated with exit(" + status + ")";
+  this.status = status;
+};
+ExitStatus.prototype = new Error();
+ExitStatus.prototype.constructor = ExitStatus;
+
+var initialStackTop;
+var preloadStartTime = null;
+var calledMain = false;
+
+dependenciesFulfilled = function runCaller() {
+  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
+  if (!Module['calledRun'] && shouldRunNow) run([].concat(Module["arguments"]));
+  if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
+}
+
+Module['callMain'] = Module.callMain = function callMain(args) {
+  assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
+  assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
+
+  args = args || [];
+
+  ensureInitRuntime();
+
+  var argc = args.length+1;
+  function pad() {
+    for (var i = 0; i < 4-1; i++) {
+      argv.push(0);
+    }
+  }
+  var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ];
+  pad();
+  for (var i = 0; i < argc-1; i = i + 1) {
+    argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL));
+    pad();
+  }
+  argv.push(0);
+  argv = allocate(argv, 'i32', ALLOC_NORMAL);
+
+  initialStackTop = STACKTOP;
+
+  try {
+
+    var ret = Module['_main'](argc, argv, 0);
+
+
+    // if we're not running an evented main loop, it's time to exit
+    if (!Module['noExitRuntime']) {
+      exit(ret);
+    }
+  }
+  catch(e) {
+    if (e instanceof ExitStatus) {
+      // exit() throws this once it's done to make sure execution
+      // has been stopped completely
+      return;
+    } else if (e == 'SimulateInfiniteLoop') {
+      // running an evented main loop, don't immediately exit
+      Module['noExitRuntime'] = true;
+      return;
+    } else {
+      if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
+      throw e;
+    }
+  } finally {
+    calledMain = true;
+  }
+}
+
+
+
+
+function run(args) {
+  args = args || Module['arguments'];
+
+  if (preloadStartTime === null) preloadStartTime = Date.now();
+
+  if (runDependencies > 0) {
+    Module.printErr('run() called, but dependencies remain, so not running');
+    return;
+  }
+
+  preRun();
+
+  if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
+  if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
+
+  function doRun() {
+    if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
+    Module['calledRun'] = true;
+
+    ensureInitRuntime();
+
+    preMain();
+
+    if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
+      Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
+    }
+
+    if (Module['_main'] && shouldRunNow) {
+      Module['callMain'](args);
+    }
+
+    postRun();
+  }
+
+  if (Module['setStatus']) {
+    Module['setStatus']('Running...');
+    setTimeout(function() {
+      setTimeout(function() {
+        Module['setStatus']('');
+      }, 1);
+      if (!ABORT) doRun();
+    }, 1);
+  } else {
+    doRun();
+  }
+}
+Module['run'] = Module.run = run;
+
+function exit(status) {
+  ABORT = true;
+  EXITSTATUS = status;
+  STACKTOP = initialStackTop;
+
+  // exit the runtime
+  exitRuntime();
+
+  // TODO We should handle this differently based on environment.
+  // In the browser, the best we can do is throw an exception
+  // to halt execution, but in node we could process.exit and
+  // I'd imagine SM shell would have something equivalent.
+  // This would let us set a proper exit status (which
+  // would be great for checking test exit statuses).
+  // https://github.com/kripken/emscripten/issues/1371
+
+  // throw an exception to halt the current execution
+  throw new ExitStatus(status);
+}
+Module['exit'] = Module.exit = exit;
+
+function abort(text) {
+  if (text) {
+    Module.print(text);
+    Module.printErr(text);
+  }
+
+  ABORT = true;
+  EXITSTATUS = 1;
+
+  var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.';
+
+  throw 'abort() at ' + stackTrace() + extra;
+}
+Module['abort'] = Module.abort = abort;
+
+// {{PRE_RUN_ADDITIONS}}
+
+if (Module['preInit']) {
+  if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
+  while (Module['preInit'].length > 0) {
+    Module['preInit'].pop()();
+  }
+}
+
+// shouldRunNow refers to calling main(), not run().
+var shouldRunNow = true;
+if (Module['noInitialRun']) {
+  shouldRunNow = false;
+}
+
+
+run([].concat(Module["arguments"]));
diff --git a/test/mjsunit/asm/embenchen/fasta.js b/test/mjsunit/asm/embenchen/fasta.js
new file mode 100644
index 0000000..8c66354
--- /dev/null
+++ b/test/mjsunit/asm/embenchen/fasta.js
@@ -0,0 +1,8605 @@
+var EXPECTED_OUTPUT =
+  'GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGA\n' +
+  'TCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACT\n' +
+  'AAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAG\n' +
+  'GCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCG\n' +
+  'CCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAAGGCCGGGCGCGGT\n' +
+  'GGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCA\n' +
+  'GGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAA\n' +
+  'TTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAG\n' +
+  'AATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCA\n' +
+  'GCCTGGGCGA\n';
+var Module = {
+  arguments: [1],
+  print: function(x) {Module.printBuffer += x + '\n';},
+  preRun: [function() {Module.printBuffer = ''}],
+  postRun: [function() {
+    assertEquals(EXPECTED_OUTPUT, Module.printBuffer);
+  }],
+};
+// The Module object: Our interface to the outside world. We import
+// and export values on it, and do the work to get that through
+// closure compiler if necessary. There are various ways Module can be used:
+// 1. Not defined. We create it here
+// 2. A function parameter, function(Module) { ..generated code.. }
+// 3. pre-run appended it, var Module = {}; ..generated code..
+// 4. External script tag defines var Module.
+// We need to do an eval in order to handle the closure compiler
+// case, where this code here is minified but Module was defined
+// elsewhere (e.g. case 4 above). We also need to check if Module
+// already exists (e.g. case 3 above).
+// Note that if you want to run closure, and also to use Module
+// after the generated code, you will need to define   var Module = {};
+// before the code. Then that object will be used in the code, and you
+// can continue to use Module afterwards as well.
+var Module;
+if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {};
+
+// Sometimes an existing Module object exists with properties
+// meant to overwrite the default module functionality. Here
+// we collect those properties and reapply _after_ we configure
+// the current environment's defaults to avoid having to be so
+// defensive during initialization.
+var moduleOverrides = {};
+for (var key in Module) {
+  if (Module.hasOwnProperty(key)) {
+    moduleOverrides[key] = Module[key];
+  }
+}
+
+// The environment setup code below is customized to use Module.
+// *** Environment setup code ***
+var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
+var ENVIRONMENT_IS_WEB = typeof window === 'object';
+var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
+var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
+
+if (ENVIRONMENT_IS_NODE) {
+  // Expose functionality in the same simple way that the shells work
+  // Note that we pollute the global namespace here, otherwise we break in node
+  if (!Module['print']) Module['print'] = function print(x) {
+    process['stdout'].write(x + '\n');
+  };
+  if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+    process['stderr'].write(x + '\n');
+  };
+
+  var nodeFS = require('fs');
+  var nodePath = require('path');
+
+  Module['read'] = function read(filename, binary) {
+    filename = nodePath['normalize'](filename);
+    var ret = nodeFS['readFileSync'](filename);
+    // The path is absolute if the normalized version is the same as the resolved.
+    if (!ret && filename != nodePath['resolve'](filename)) {
+      filename = path.join(__dirname, '..', 'src', filename);
+      ret = nodeFS['readFileSync'](filename);
+    }
+    if (ret && !binary) ret = ret.toString();
+    return ret;
+  };
+
+  Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) };
+
+  Module['load'] = function load(f) {
+    globalEval(read(f));
+  };
+
+  Module['arguments'] = process['argv'].slice(2);
+
+  module['exports'] = Module;
+}
+else if (ENVIRONMENT_IS_SHELL) {
+  if (!Module['print']) Module['print'] = print;
+  if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
+
+  if (typeof read != 'undefined') {
+    Module['read'] = read;
+  } else {
+    Module['read'] = function read() { throw 'no read() available (jsc?)' };
+  }
+
+  Module['readBinary'] = function readBinary(f) {
+    return read(f, 'binary');
+  };
+
+  if (typeof scriptArgs != 'undefined') {
+    Module['arguments'] = scriptArgs;
+  } else if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  this['Module'] = Module;
+
+  eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly)
+}
+else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+  Module['read'] = function read(url) {
+    var xhr = new XMLHttpRequest();
+    xhr.open('GET', url, false);
+    xhr.send(null);
+    return xhr.responseText;
+  };
+
+  if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  if (typeof console !== 'undefined') {
+    if (!Module['print']) Module['print'] = function print(x) {
+      console.log(x);
+    };
+    if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+      console.log(x);
+    };
+  } else {
+    // Probably a worker, and without console.log. We can do very little here...
+    var TRY_USE_DUMP = false;
+    if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
+      dump(x);
+    }) : (function(x) {
+      // self.postMessage(x); // enable this if you want stdout to be sent as messages
+    }));
+  }
+
+  if (ENVIRONMENT_IS_WEB) {
+    window['Module'] = Module;
+  } else {
+    Module['load'] = importScripts;
+  }
+}
+else {
+  // Unreachable because SHELL is dependant on the others
+  throw 'Unknown runtime environment. Where are we?';
+}
+
+function globalEval(x) {
+  eval.call(null, x);
+}
+if (!Module['load'] == 'undefined' && Module['read']) {
+  Module['load'] = function load(f) {
+    globalEval(Module['read'](f));
+  };
+}
+if (!Module['print']) {
+  Module['print'] = function(){};
+}
+if (!Module['printErr']) {
+  Module['printErr'] = Module['print'];
+}
+if (!Module['arguments']) {
+  Module['arguments'] = [];
+}
+// *** Environment setup code ***
+
+// Closure helpers
+Module.print = Module['print'];
+Module.printErr = Module['printErr'];
+
+// Callbacks
+Module['preRun'] = [];
+Module['postRun'] = [];
+
+// Merge back in the overrides
+for (var key in moduleOverrides) {
+  if (moduleOverrides.hasOwnProperty(key)) {
+    Module[key] = moduleOverrides[key];
+  }
+}
+
+
+
+// === Auto-generated preamble library stuff ===
+
+//========================================
+// Runtime code shared with compiler
+//========================================
+
+var Runtime = {
+  stackSave: function () {
+    return STACKTOP;
+  },
+  stackRestore: function (stackTop) {
+    STACKTOP = stackTop;
+  },
+  forceAlign: function (target, quantum) {
+    quantum = quantum || 4;
+    if (quantum == 1) return target;
+    if (isNumber(target) && isNumber(quantum)) {
+      return Math.ceil(target/quantum)*quantum;
+    } else if (isNumber(quantum) && isPowerOfTwo(quantum)) {
+      return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')';
+    }
+    return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
+  },
+  isNumberType: function (type) {
+    return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
+  },
+  isPointerType: function isPointerType(type) {
+  return type[type.length-1] == '*';
+},
+  isStructType: function isStructType(type) {
+  if (isPointerType(type)) return false;
+  if (isArrayType(type)) return true;
+  if (/<?\{ ?[^}]* ?\}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types
+  // See comment in isStructPointerType()
+  return type[0] == '%';
+},
+  INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
+  FLOAT_TYPES: {"float":0,"double":0},
+  or64: function (x, y) {
+    var l = (x | 0) | (y | 0);
+    var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  and64: function (x, y) {
+    var l = (x | 0) & (y | 0);
+    var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  xor64: function (x, y) {
+    var l = (x | 0) ^ (y | 0);
+    var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  getNativeTypeSize: function (type) {
+    switch (type) {
+      case 'i1': case 'i8': return 1;
+      case 'i16': return 2;
+      case 'i32': return 4;
+      case 'i64': return 8;
+      case 'float': return 4;
+      case 'double': return 8;
+      default: {
+        if (type[type.length-1] === '*') {
+          return Runtime.QUANTUM_SIZE; // A pointer
+        } else if (type[0] === 'i') {
+          var bits = parseInt(type.substr(1));
+          assert(bits % 8 === 0);
+          return bits/8;
+        } else {
+          return 0;
+        }
+      }
+    }
+  },
+  getNativeFieldSize: function (type) {
+    return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE);
+  },
+  dedup: function dedup(items, ident) {
+  var seen = {};
+  if (ident) {
+    return items.filter(function(item) {
+      if (seen[item[ident]]) return false;
+      seen[item[ident]] = true;
+      return true;
+    });
+  } else {
+    return items.filter(function(item) {
+      if (seen[item]) return false;
+      seen[item] = true;
+      return true;
+    });
+  }
+},
+  set: function set() {
+  var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
+  var ret = {};
+  for (var i = 0; i < args.length; i++) {
+    ret[args[i]] = 0;
+  }
+  return ret;
+},
+  STACK_ALIGN: 8,
+  getAlignSize: function (type, size, vararg) {
+    // we align i64s and doubles on 64-bit boundaries, unlike x86
+    if (!vararg && (type == 'i64' || type == 'double')) return 8;
+    if (!type) return Math.min(size, 8); // align structures internally to 64 bits
+    return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE);
+  },
+  calculateStructAlignment: function calculateStructAlignment(type) {
+    type.flatSize = 0;
+    type.alignSize = 0;
+    var diffs = [];
+    var prev = -1;
+    var index = 0;
+    type.flatIndexes = type.fields.map(function(field) {
+      index++;
+      var size, alignSize;
+      if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
+        size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
+        alignSize = Runtime.getAlignSize(field, size);
+      } else if (Runtime.isStructType(field)) {
+        if (field[1] === '0') {
+          // this is [0 x something]. When inside another structure like here, it must be at the end,
+          // and it adds no size
+          // XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!');
+          size = 0;
+          if (Types.types[field]) {
+            alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+          } else {
+            alignSize = type.alignSize || QUANTUM_SIZE;
+          }
+        } else {
+          size = Types.types[field].flatSize;
+          alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+        }
+      } else if (field[0] == 'b') {
+        // bN, large number field, like a [N x i8]
+        size = field.substr(1)|0;
+        alignSize = 1;
+      } else if (field[0] === '<') {
+        // vector type
+        size = alignSize = Types.types[field].flatSize; // fully aligned
+      } else if (field[0] === 'i') {
+        // illegal integer field, that could not be legalized because it is an internal structure field
+        // it is ok to have such fields, if we just use them as markers of field size and nothing more complex
+        size = alignSize = parseInt(field.substr(1))/8;
+        assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field);
+      } else {
+        assert(false, 'invalid type for calculateStructAlignment');
+      }
+      if (type.packed) alignSize = 1;
+      type.alignSize = Math.max(type.alignSize, alignSize);
+      var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
+      type.flatSize = curr + size;
+      if (prev >= 0) {
+        diffs.push(curr-prev);
+      }
+      prev = curr;
+      return curr;
+    });
+    if (type.name_ && type.name_[0] === '[') {
+      // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
+      // allocating a potentially huge array for [999999 x i8] etc.
+      type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
+    }
+    type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
+    if (diffs.length == 0) {
+      type.flatFactor = type.flatSize;
+    } else if (Runtime.dedup(diffs).length == 1) {
+      type.flatFactor = diffs[0];
+    }
+    type.needsFlattening = (type.flatFactor != 1);
+    return type.flatIndexes;
+  },
+  generateStructInfo: function (struct, typeName, offset) {
+    var type, alignment;
+    if (typeName) {
+      offset = offset || 0;
+      type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
+      if (!type) return null;
+      if (type.fields.length != struct.length) {
+        printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo');
+        return null;
+      }
+      alignment = type.flatIndexes;
+    } else {
+      var type = { fields: struct.map(function(item) { return item[0] }) };
+      alignment = Runtime.calculateStructAlignment(type);
+    }
+    var ret = {
+      __size__: type.flatSize
+    };
+    if (typeName) {
+      struct.forEach(function(item, i) {
+        if (typeof item === 'string') {
+          ret[item] = alignment[i] + offset;
+        } else {
+          // embedded struct
+          var key;
+          for (var k in item) key = k;
+          ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
+        }
+      });
+    } else {
+      struct.forEach(function(item, i) {
+        ret[item[1]] = alignment[i];
+      });
+    }
+    return ret;
+  },
+  dynCall: function (sig, ptr, args) {
+    if (args && args.length) {
+      if (!args.splice) args = Array.prototype.slice.call(args);
+      args.splice(0, 0, ptr);
+      return Module['dynCall_' + sig].apply(null, args);
+    } else {
+      return Module['dynCall_' + sig].call(null, ptr);
+    }
+  },
+  functionPointers: [],
+  addFunction: function (func) {
+    for (var i = 0; i < Runtime.functionPointers.length; i++) {
+      if (!Runtime.functionPointers[i]) {
+        Runtime.functionPointers[i] = func;
+        return 2*(1 + i);
+      }
+    }
+    throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
+  },
+  removeFunction: function (index) {
+    Runtime.functionPointers[(index-2)/2] = null;
+  },
+  getAsmConst: function (code, numArgs) {
+    // code is a constant string on the heap, so we can cache these
+    if (!Runtime.asmConstCache) Runtime.asmConstCache = {};
+    var func = Runtime.asmConstCache[code];
+    if (func) return func;
+    var args = [];
+    for (var i = 0; i < numArgs; i++) {
+      args.push(String.fromCharCode(36) + i); // $0, $1 etc
+    }
+    var source = Pointer_stringify(code);
+    if (source[0] === '"') {
+      // tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct
+      if (source.indexOf('"', 1) === source.length-1) {
+        source = source.substr(1, source.length-2);
+      } else {
+        // something invalid happened, e.g. EM_ASM("..code($0)..", input)
+        abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)');
+      }
+    }
+    try {
+      var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node
+    } catch(e) {
+      Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)');
+      throw e;
+    }
+    return Runtime.asmConstCache[code] = evalled;
+  },
+  warnOnce: function (text) {
+    if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
+    if (!Runtime.warnOnce.shown[text]) {
+      Runtime.warnOnce.shown[text] = 1;
+      Module.printErr(text);
+    }
+  },
+  funcWrappers: {},
+  getFuncWrapper: function (func, sig) {
+    assert(sig);
+    if (!Runtime.funcWrappers[func]) {
+      Runtime.funcWrappers[func] = function dynCall_wrapper() {
+        return Runtime.dynCall(sig, func, arguments);
+      };
+    }
+    return Runtime.funcWrappers[func];
+  },
+  UTF8Processor: function () {
+    var buffer = [];
+    var needed = 0;
+    this.processCChar = function (code) {
+      code = code & 0xFF;
+
+      if (buffer.length == 0) {
+        if ((code & 0x80) == 0x00) {        // 0xxxxxxx
+          return String.fromCharCode(code);
+        }
+        buffer.push(code);
+        if ((code & 0xE0) == 0xC0) {        // 110xxxxx
+          needed = 1;
+        } else if ((code & 0xF0) == 0xE0) { // 1110xxxx
+          needed = 2;
+        } else {                            // 11110xxx
+          needed = 3;
+        }
+        return '';
+      }
+
+      if (needed) {
+        buffer.push(code);
+        needed--;
+        if (needed > 0) return '';
+      }
+
+      var c1 = buffer[0];
+      var c2 = buffer[1];
+      var c3 = buffer[2];
+      var c4 = buffer[3];
+      var ret;
+      if (buffer.length == 2) {
+        ret = String.fromCharCode(((c1 & 0x1F) << 6)  | (c2 & 0x3F));
+      } else if (buffer.length == 3) {
+        ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6)  | (c3 & 0x3F));
+      } else {
+        // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+        var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
+                        ((c3 & 0x3F) << 6)  | (c4 & 0x3F);
+        ret = String.fromCharCode(
+          Math.floor((codePoint - 0x10000) / 0x400) + 0xD800,
+          (codePoint - 0x10000) % 0x400 + 0xDC00);
+      }
+      buffer.length = 0;
+      return ret;
+    }
+    this.processJSString = function processJSString(string) {
+      /* TODO: use TextEncoder when present,
+        var encoder = new TextEncoder();
+        encoder['encoding'] = "utf-8";
+        var utf8Array = encoder['encode'](aMsg.data);
+      */
+      string = unescape(encodeURIComponent(string));
+      var ret = [];
+      for (var i = 0; i < string.length; i++) {
+        ret.push(string.charCodeAt(i));
+      }
+      return ret;
+    }
+  },
+  getCompilerSetting: function (name) {
+    throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work';
+  },
+  stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+7)&-8); return ret; },
+  staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = (((STATICTOP)+7)&-8); return ret; },
+  dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = (((DYNAMICTOP)+7)&-8); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; },
+  alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; },
+  makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*(+4294967296))) : ((+((low>>>0)))+((+((high|0)))*(+4294967296)))); return ret; },
+  GLOBAL_BASE: 8,
+  QUANTUM_SIZE: 4,
+  __dummy__: 0
+}
+
+
+Module['Runtime'] = Runtime;
+
+
+
+
+
+
+
+
+
+//========================================
+// Runtime essentials
+//========================================
+
+var __THREW__ = 0; // Used in checking for thrown exceptions.
+
+var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort()
+var EXITSTATUS = 0;
+
+var undef = 0;
+// tempInt is used for 32-bit signed values or smaller. tempBigInt is used
+// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt
+var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat;
+var tempI64, tempI64b;
+var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9;
+
+function assert(condition, text) {
+  if (!condition) {
+    abort('Assertion failed: ' + text);
+  }
+}
+
+var globalScope = this;
+
+// C calling interface. A convenient way to call C functions (in C files, or
+// defined with extern "C").
+//
+// Note: LLVM optimizations can inline and remove functions, after which you will not be
+//       able to call them. Closure can also do so. To avoid that, add your function to
+//       the exports using something like
+//
+//         -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]'
+//
+// @param ident      The name of the C function (note that C++ functions will be name-mangled - use extern "C")
+// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and
+//                   'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit).
+// @param argTypes   An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType,
+//                   except that 'array' is not possible (there is no way for us to know the length of the array)
+// @param args       An array of the arguments to the function, as native JS values (as in returnType)
+//                   Note that string arguments will be stored on the stack (the JS string will become a C string on the stack).
+// @return           The return value, as a native JS value (as in returnType)
+function ccall(ident, returnType, argTypes, args) {
+  return ccallFunc(getCFunc(ident), returnType, argTypes, args);
+}
+Module["ccall"] = ccall;
+
+// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
+function getCFunc(ident) {
+  try {
+    var func = Module['_' + ident]; // closure exported function
+    if (!func) func = eval('_' + ident); // explicit lookup
+  } catch(e) {
+  }
+  assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)');
+  return func;
+}
+
+// Internal function that does a C call using a function, not an identifier
+function ccallFunc(func, returnType, argTypes, args) {
+  var stack = 0;
+  function toC(value, type) {
+    if (type == 'string') {
+      if (value === null || value === undefined || value === 0) return 0; // null string
+      value = intArrayFromString(value);
+      type = 'array';
+    }
+    if (type == 'array') {
+      if (!stack) stack = Runtime.stackSave();
+      var ret = Runtime.stackAlloc(value.length);
+      writeArrayToMemory(value, ret);
+      return ret;
+    }
+    return value;
+  }
+  function fromC(value, type) {
+    if (type == 'string') {
+      return Pointer_stringify(value);
+    }
+    assert(type != 'array');
+    return value;
+  }
+  var i = 0;
+  var cArgs = args ? args.map(function(arg) {
+    return toC(arg, argTypes[i++]);
+  }) : [];
+  var ret = fromC(func.apply(null, cArgs), returnType);
+  if (stack) Runtime.stackRestore(stack);
+  return ret;
+}
+
+// Returns a native JS wrapper for a C function. This is similar to ccall, but
+// returns a function you can call repeatedly in a normal way. For example:
+//
+//   var my_function = cwrap('my_c_function', 'number', ['number', 'number']);
+//   alert(my_function(5, 22));
+//   alert(my_function(99, 12));
+//
+function cwrap(ident, returnType, argTypes) {
+  var func = getCFunc(ident);
+  return function() {
+    return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments));
+  }
+}
+Module["cwrap"] = cwrap;
+
+// Sets a value in memory in a dynamic way at run-time. Uses the
+// type data. This is the same as makeSetValue, except that
+// makeSetValue is done at compile-time and generates the needed
+// code then, whereas this function picks the right code at
+// run-time.
+// Note that setValue and getValue only do *aligned* writes and reads!
+// Note that ccall uses JS types as for defining types, while setValue and
+// getValue need LLVM types ('i8', 'i32') - this is a lower-level operation
+function setValue(ptr, value, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': HEAP8[(ptr)]=value; break;
+      case 'i8': HEAP8[(ptr)]=value; break;
+      case 'i16': HEAP16[((ptr)>>1)]=value; break;
+      case 'i32': HEAP32[((ptr)>>2)]=value; break;
+      case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= (+1) ? (tempDouble > (+0) ? ((Math_min((+(Math_floor((tempDouble)/(+4294967296)))), (+4294967295)))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/(+4294967296))))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
+      case 'float': HEAPF32[((ptr)>>2)]=value; break;
+      case 'double': HEAPF64[((ptr)>>3)]=value; break;
+      default: abort('invalid type for setValue: ' + type);
+    }
+}
+Module['setValue'] = setValue;
+
+// Parallel to setValue.
+function getValue(ptr, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': return HEAP8[(ptr)];
+      case 'i8': return HEAP8[(ptr)];
+      case 'i16': return HEAP16[((ptr)>>1)];
+      case 'i32': return HEAP32[((ptr)>>2)];
+      case 'i64': return HEAP32[((ptr)>>2)];
+      case 'float': return HEAPF32[((ptr)>>2)];
+      case 'double': return HEAPF64[((ptr)>>3)];
+      default: abort('invalid type for setValue: ' + type);
+    }
+  return null;
+}
+Module['getValue'] = getValue;
+
+var ALLOC_NORMAL = 0; // Tries to use _malloc()
+var ALLOC_STACK = 1; // Lives for the duration of the current function call
+var ALLOC_STATIC = 2; // Cannot be freed
+var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
+var ALLOC_NONE = 4; // Do not allocate
+Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
+Module['ALLOC_STACK'] = ALLOC_STACK;
+Module['ALLOC_STATIC'] = ALLOC_STATIC;
+Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
+Module['ALLOC_NONE'] = ALLOC_NONE;
+
+// allocate(): This is for internal use. You can use it yourself as well, but the interface
+//             is a little tricky (see docs right below). The reason is that it is optimized
+//             for multiple syntaxes to save space in generated code. So you should
+//             normally not use allocate(), and instead allocate memory using _malloc(),
+//             initialize it with setValue(), and so forth.
+// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
+//        in *bytes* (note that this is sometimes confusing: the next parameter does not
+//        affect this!)
+// @types: Either an array of types, one for each byte (or 0 if no type at that position),
+//         or a single type which is used for the entire block. This only matters if there
+//         is initial data - if @slab is a number, then this does not matter at all and is
+//         ignored.
+// @allocator: How to allocate memory, see ALLOC_*
+function allocate(slab, types, allocator, ptr) {
+  var zeroinit, size;
+  if (typeof slab === 'number') {
+    zeroinit = true;
+    size = slab;
+  } else {
+    zeroinit = false;
+    size = slab.length;
+  }
+
+  var singleType = typeof types === 'string' ? types : null;
+
+  var ret;
+  if (allocator == ALLOC_NONE) {
+    ret = ptr;
+  } else {
+    ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
+  }
+
+  if (zeroinit) {
+    var ptr = ret, stop;
+    assert((ret & 3) == 0);
+    stop = ret + (size & ~3);
+    for (; ptr < stop; ptr += 4) {
+      HEAP32[((ptr)>>2)]=0;
+    }
+    stop = ret + size;
+    while (ptr < stop) {
+      HEAP8[((ptr++)|0)]=0;
+    }
+    return ret;
+  }
+
+  if (singleType === 'i8') {
+    if (slab.subarray || slab.slice) {
+      HEAPU8.set(slab, ret);
+    } else {
+      HEAPU8.set(new Uint8Array(slab), ret);
+    }
+    return ret;
+  }
+
+  var i = 0, type, typeSize, previousType;
+  while (i < size) {
+    var curr = slab[i];
+
+    if (typeof curr === 'function') {
+      curr = Runtime.getFunctionIndex(curr);
+    }
+
+    type = singleType || types[i];
+    if (type === 0) {
+      i++;
+      continue;
+    }
+
+    if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
+
+    setValue(ret+i, curr, type);
+
+    // no need to look up size unless type changes, so cache it
+    if (previousType !== type) {
+      typeSize = Runtime.getNativeTypeSize(type);
+      previousType = type;
+    }
+    i += typeSize;
+  }
+
+  return ret;
+}
+Module['allocate'] = allocate;
+
+function Pointer_stringify(ptr, /* optional */ length) {
+  // TODO: use TextDecoder
+  // Find the length, and check for UTF while doing so
+  var hasUtf = false;
+  var t;
+  var i = 0;
+  while (1) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    if (t >= 128) hasUtf = true;
+    else if (t == 0 && !length) break;
+    i++;
+    if (length && i == length) break;
+  }
+  if (!length) length = i;
+
+  var ret = '';
+
+  if (!hasUtf) {
+    var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack
+    var curr;
+    while (length > 0) {
+      curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
+      ret = ret ? ret + curr : curr;
+      ptr += MAX_CHUNK;
+      length -= MAX_CHUNK;
+    }
+    return ret;
+  }
+
+  var utf8 = new Runtime.UTF8Processor();
+  for (i = 0; i < length; i++) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    ret += utf8.processCChar(t);
+  }
+  return ret;
+}
+Module['Pointer_stringify'] = Pointer_stringify;
+
+// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF16ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
+    if (codeUnit == 0)
+      return str;
+    ++i;
+    // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
+    str += String.fromCharCode(codeUnit);
+  }
+}
+Module['UTF16ToString'] = UTF16ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF16LE form. The copy will require at most (str.length*2+1)*2 bytes of space in the HEAP.
+function stringToUTF16(str, outPtr) {
+  for(var i = 0; i < str.length; ++i) {
+    // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
+    var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
+    HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP16[(((outPtr)+(str.length*2))>>1)]=0;
+}
+Module['stringToUTF16'] = stringToUTF16;
+
+// Given a pointer 'ptr' to a null-terminated UTF32LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF32ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
+    if (utf32 == 0)
+      return str;
+    ++i;
+    // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
+    if (utf32 >= 0x10000) {
+      var ch = utf32 - 0x10000;
+      str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
+    } else {
+      str += String.fromCharCode(utf32);
+    }
+  }
+}
+Module['UTF32ToString'] = UTF32ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF32LE form. The copy will require at most (str.length+1)*4 bytes of space in the HEAP,
+// but can use less, since str.length does not return the number of characters in the string, but the number of UTF-16 code units in the string.
+function stringToUTF32(str, outPtr) {
+  var iChar = 0;
+  for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) {
+    // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
+    var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate
+    if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
+      var trailSurrogate = str.charCodeAt(++iCodeUnit);
+      codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
+    }
+    HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit;
+    ++iChar;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP32[(((outPtr)+(iChar*4))>>2)]=0;
+}
+Module['stringToUTF32'] = stringToUTF32;
+
+function demangle(func) {
+  var i = 3;
+  // params, etc.
+  var basicTypes = {
+    'v': 'void',
+    'b': 'bool',
+    'c': 'char',
+    's': 'short',
+    'i': 'int',
+    'l': 'long',
+    'f': 'float',
+    'd': 'double',
+    'w': 'wchar_t',
+    'a': 'signed char',
+    'h': 'unsigned char',
+    't': 'unsigned short',
+    'j': 'unsigned int',
+    'm': 'unsigned long',
+    'x': 'long long',
+    'y': 'unsigned long long',
+    'z': '...'
+  };
+  var subs = [];
+  var first = true;
+  function dump(x) {
+    //return;
+    if (x) Module.print(x);
+    Module.print(func);
+    var pre = '';
+    for (var a = 0; a < i; a++) pre += ' ';
+    Module.print (pre + '^');
+  }
+  function parseNested() {
+    i++;
+    if (func[i] === 'K') i++; // ignore const
+    var parts = [];
+    while (func[i] !== 'E') {
+      if (func[i] === 'S') { // substitution
+        i++;
+        var next = func.indexOf('_', i);
+        var num = func.substring(i, next) || 0;
+        parts.push(subs[num] || '?');
+        i = next+1;
+        continue;
+      }
+      if (func[i] === 'C') { // constructor
+        parts.push(parts[parts.length-1]);
+        i += 2;
+        continue;
+      }
+      var size = parseInt(func.substr(i));
+      var pre = size.toString().length;
+      if (!size || !pre) { i--; break; } // counter i++ below us
+      var curr = func.substr(i + pre, size);
+      parts.push(curr);
+      subs.push(curr);
+      i += pre + size;
+    }
+    i++; // skip E
+    return parts;
+  }
+  function parse(rawList, limit, allowVoid) { // main parser
+    limit = limit || Infinity;
+    var ret = '', list = [];
+    function flushList() {
+      return '(' + list.join(', ') + ')';
+    }
+    var name;
+    if (func[i] === 'N') {
+      // namespaced N-E
+      name = parseNested().join('::');
+      limit--;
+      if (limit === 0) return rawList ? [name] : name;
+    } else {
+      // not namespaced
+      if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L'
+      var size = parseInt(func.substr(i));
+      if (size) {
+        var pre = size.toString().length;
+        name = func.substr(i + pre, size);
+        i += pre + size;
+      }
+    }
+    first = false;
+    if (func[i] === 'I') {
+      i++;
+      var iList = parse(true);
+      var iRet = parse(true, 1, true);
+      ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>';
+    } else {
+      ret = name;
+    }
+    paramLoop: while (i < func.length && limit-- > 0) {
+      //dump('paramLoop');
+      var c = func[i++];
+      if (c in basicTypes) {
+        list.push(basicTypes[c]);
+      } else {
+        switch (c) {
+          case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer
+          case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference
+          case 'L': { // literal
+            i++; // skip basic type
+            var end = func.indexOf('E', i);
+            var size = end - i;
+            list.push(func.substr(i, size));
+            i += size + 2; // size + 'EE'
+            break;
+          }
+          case 'A': { // array
+            var size = parseInt(func.substr(i));
+            i += size.toString().length;
+            if (func[i] !== '_') throw '?';
+            i++; // skip _
+            list.push(parse(true, 1, true)[0] + ' [' + size + ']');
+            break;
+          }
+          case 'E': break paramLoop;
+          default: ret += '?' + c; break paramLoop;
+        }
+      }
+    }
+    if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void)
+    if (rawList) {
+      if (ret) {
+        list.push(ret + '?');
+      }
+      return list;
+    } else {
+      return ret + flushList();
+    }
+  }
+  try {
+    // Special-case the entry point, since its name differs from other name mangling.
+    if (func == 'Object._main' || func == '_main') {
+      return 'main()';
+    }
+    if (typeof func === 'number') func = Pointer_stringify(func);
+    if (func[0] !== '_') return func;
+    if (func[1] !== '_') return func; // C function
+    if (func[2] !== 'Z') return func;
+    switch (func[3]) {
+      case 'n': return 'operator new()';
+      case 'd': return 'operator delete()';
+    }
+    return parse();
+  } catch(e) {
+    return func;
+  }
+}
+
+function demangleAll(text) {
+  return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') });
+}
+
+function stackTrace() {
+  var stack = new Error().stack;
+  return stack ? demangleAll(stack) : '(no stack trace available)'; // Stack trace is not available at least on IE10 and Safari 6.
+}
+
+// Memory management
+
+var PAGE_SIZE = 4096;
+function alignMemoryPage(x) {
+  return (x+4095)&-4096;
+}
+
+var HEAP;
+var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
+
+var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area
+var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area
+var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk
+
+function enlargeMemory() {
+  abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
+}
+
+var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880;
+var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 134217728;
+var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152;
+
+var totalMemory = 4096;
+while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) {
+  if (totalMemory < 16*1024*1024) {
+    totalMemory *= 2;
+  } else {
+    totalMemory += 16*1024*1024
+  }
+}
+if (totalMemory !== TOTAL_MEMORY) {
+  Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be more reasonable');
+  TOTAL_MEMORY = totalMemory;
+}
+
+// Initialize the runtime's memory
+// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
+assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
+       'JS engine does not provide full typed array support');
+
+var buffer = new ArrayBuffer(TOTAL_MEMORY);
+HEAP8 = new Int8Array(buffer);
+HEAP16 = new Int16Array(buffer);
+HEAP32 = new Int32Array(buffer);
+HEAPU8 = new Uint8Array(buffer);
+HEAPU16 = new Uint16Array(buffer);
+HEAPU32 = new Uint32Array(buffer);
+HEAPF32 = new Float32Array(buffer);
+HEAPF64 = new Float64Array(buffer);
+
+// Endianness check (note: assumes compiler arch was little-endian)
+HEAP32[0] = 255;
+assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
+
+Module['HEAP'] = HEAP;
+Module['HEAP8'] = HEAP8;
+Module['HEAP16'] = HEAP16;
+Module['HEAP32'] = HEAP32;
+Module['HEAPU8'] = HEAPU8;
+Module['HEAPU16'] = HEAPU16;
+Module['HEAPU32'] = HEAPU32;
+Module['HEAPF32'] = HEAPF32;
+Module['HEAPF64'] = HEAPF64;
+
+function callRuntimeCallbacks(callbacks) {
+  while(callbacks.length > 0) {
+    var callback = callbacks.shift();
+    if (typeof callback == 'function') {
+      callback();
+      continue;
+    }
+    var func = callback.func;
+    if (typeof func === 'number') {
+      if (callback.arg === undefined) {
+        Runtime.dynCall('v', func);
+      } else {
+        Runtime.dynCall('vi', func, [callback.arg]);
+      }
+    } else {
+      func(callback.arg === undefined ? null : callback.arg);
+    }
+  }
+}
+
+var __ATPRERUN__  = []; // functions called before the runtime is initialized
+var __ATINIT__    = []; // functions called during startup
+var __ATMAIN__    = []; // functions called when main() is to be run
+var __ATEXIT__    = []; // functions called during shutdown
+var __ATPOSTRUN__ = []; // functions called after the runtime has exited
+
+var runtimeInitialized = false;
+
+function preRun() {
+  // compatibility - merge in anything from Module['preRun'] at this time
+  if (Module['preRun']) {
+    if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
+    while (Module['preRun'].length) {
+      addOnPreRun(Module['preRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPRERUN__);
+}
+
+function ensureInitRuntime() {
+  if (runtimeInitialized) return;
+  runtimeInitialized = true;
+  callRuntimeCallbacks(__ATINIT__);
+}
+
+function preMain() {
+  callRuntimeCallbacks(__ATMAIN__);
+}
+
+function exitRuntime() {
+  callRuntimeCallbacks(__ATEXIT__);
+}
+
+function postRun() {
+  // compatibility - merge in anything from Module['postRun'] at this time
+  if (Module['postRun']) {
+    if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
+    while (Module['postRun'].length) {
+      addOnPostRun(Module['postRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPOSTRUN__);
+}
+
+function addOnPreRun(cb) {
+  __ATPRERUN__.unshift(cb);
+}
+Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun;
+
+function addOnInit(cb) {
+  __ATINIT__.unshift(cb);
+}
+Module['addOnInit'] = Module.addOnInit = addOnInit;
+
+function addOnPreMain(cb) {
+  __ATMAIN__.unshift(cb);
+}
+Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain;
+
+function addOnExit(cb) {
+  __ATEXIT__.unshift(cb);
+}
+Module['addOnExit'] = Module.addOnExit = addOnExit;
+
+function addOnPostRun(cb) {
+  __ATPOSTRUN__.unshift(cb);
+}
+Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun;
+
+// Tools
+
+// This processes a JS string into a C-line array of numbers, 0-terminated.
+// For LLVM-originating strings, see parser.js:parseLLVMString function
+function intArrayFromString(stringy, dontAddNull, length /* optional */) {
+  var ret = (new Runtime.UTF8Processor()).processJSString(stringy);
+  if (length) {
+    ret.length = length;
+  }
+  if (!dontAddNull) {
+    ret.push(0);
+  }
+  return ret;
+}
+Module['intArrayFromString'] = intArrayFromString;
+
+function intArrayToString(array) {
+  var ret = [];
+  for (var i = 0; i < array.length; i++) {
+    var chr = array[i];
+    if (chr > 0xFF) {
+      chr &= 0xFF;
+    }
+    ret.push(String.fromCharCode(chr));
+  }
+  return ret.join('');
+}
+Module['intArrayToString'] = intArrayToString;
+
+// Write a Javascript array to somewhere in the heap
+function writeStringToMemory(string, buffer, dontAddNull) {
+  var array = intArrayFromString(string, dontAddNull);
+  var i = 0;
+  while (i < array.length) {
+    var chr = array[i];
+    HEAP8[(((buffer)+(i))|0)]=chr;
+    i = i + 1;
+  }
+}
+Module['writeStringToMemory'] = writeStringToMemory;
+
+function writeArrayToMemory(array, buffer) {
+  for (var i = 0; i < array.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=array[i];
+  }
+}
+Module['writeArrayToMemory'] = writeArrayToMemory;
+
+function writeAsciiToMemory(str, buffer, dontAddNull) {
+  for (var i = 0; i < str.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=str.charCodeAt(i);
+  }
+  if (!dontAddNull) HEAP8[(((buffer)+(str.length))|0)]=0;
+}
+Module['writeAsciiToMemory'] = writeAsciiToMemory;
+
+function unSign(value, bits, ignore) {
+  if (value >= 0) {
+    return value;
+  }
+  return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
+                    : Math.pow(2, bits)         + value;
+}
+function reSign(value, bits, ignore) {
+  if (value <= 0) {
+    return value;
+  }
+  var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
+                        : Math.pow(2, bits-1);
+  if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
+                                                       // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
+                                                       // TODO: In i64 mode 1, resign the two parts separately and safely
+    value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
+  }
+  return value;
+}
+
+// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
+if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) {
+  var ah  = a >>> 16;
+  var al = a & 0xffff;
+  var bh  = b >>> 16;
+  var bl = b & 0xffff;
+  return (al*bl + ((ah*bl + al*bh) << 16))|0;
+};
+Math.imul = Math['imul'];
+
+
+var Math_abs = Math.abs;
+var Math_cos = Math.cos;
+var Math_sin = Math.sin;
+var Math_tan = Math.tan;
+var Math_acos = Math.acos;
+var Math_asin = Math.asin;
+var Math_atan = Math.atan;
+var Math_atan2 = Math.atan2;
+var Math_exp = Math.exp;
+var Math_log = Math.log;
+var Math_sqrt = Math.sqrt;
+var Math_ceil = Math.ceil;
+var Math_floor = Math.floor;
+var Math_pow = Math.pow;
+var Math_imul = Math.imul;
+var Math_fround = Math.fround;
+var Math_min = Math.min;
+
+// A counter of dependencies for calling run(). If we need to
+// do asynchronous work before running, increment this and
+// decrement it. Incrementing must happen in a place like
+// PRE_RUN_ADDITIONS (used by emcc to add file preloading).
+// Note that you can add dependencies in preRun, even though
+// it happens right before run - run will be postponed until
+// the dependencies are met.
+var runDependencies = 0;
+var runDependencyWatcher = null;
+var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
+
+function addRunDependency(id) {
+  runDependencies++;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+}
+Module['addRunDependency'] = addRunDependency;
+function removeRunDependency(id) {
+  runDependencies--;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+  if (runDependencies == 0) {
+    if (runDependencyWatcher !== null) {
+      clearInterval(runDependencyWatcher);
+      runDependencyWatcher = null;
+    }
+    if (dependenciesFulfilled) {
+      var callback = dependenciesFulfilled;
+      dependenciesFulfilled = null;
+      callback(); // can add another dependenciesFulfilled
+    }
+  }
+}
+Module['removeRunDependency'] = removeRunDependency;
+
+Module["preloadedImages"] = {}; // maps url to image data
+Module["preloadedAudios"] = {}; // maps url to audio data
+
+
+var memoryInitializer = null;
+
+// === Body ===
+
+
+
+
+
+STATIC_BASE = 8;
+
+STATICTOP = STATIC_BASE + Runtime.alignMemory(1155);
+/* global initializers */ __ATINIT__.push();
+
+
+/* memory initializer */ allocate([38,2,0,0,0,0,0,0,42,0,0,0,0,0,0,0,97,0,0,0,113,61,138,62,0,0,0,0,99,0,0,0,143,194,245,61,0,0,0,0,103,0,0,0,143,194,245,61,0,0,0,0,116,0,0,0,113,61,138,62,0,0,0,0,66,0,0,0,10,215,163,60,0,0,0,0,68,0,0,0,10,215,163,60,0,0,0,0,72,0,0,0,10,215,163,60,0,0,0,0,75,0,0,0,10,215,163,60,0,0,0,0,77,0,0,0,10,215,163,60,0,0,0,0,78,0,0,0,10,215,163,60,0,0,0,0,82,0,0,0,10,215,163,60,0,0,0,0,83,0,0,0,10,215,163,60,0,0,0,0,86,0,0,0,10,215,163,60,0,0,0,0,87,0,0,0,10,215,163,60,0,0,0,0,89,0,0,0,10,215,163,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,97,0,0,0,233,28,155,62,0,0,0,0,99,0,0,0,114,189,74,62,0,0,0,0,103,0,0,0,215,73,74,62,0,0,0,0,116,0,0,0,114,95,154,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,114,114,111,114,58,32,37,100,10,0,0,0,0,0,0,71,71,67,67,71,71,71,67,71,67,71,71,84,71,71,67,84,67,65,67,71,67,67,84,71,84,65,65,84,67,67,67,65,71,67,65,67,84,84,84,71,71,71,65,71,71,67,67,71,65,71,71,67,71,71,71,67,71,71,65,84,67,65,67,67,84,71,65,71,71,84,67,65,71,71,65,71,84,84,67,71,65,71,65,67,67,65,71,67,67,84,71,71,67,67,65,65,67,65,84,71,71,84,71,65,65,65,67,67,67,67,71,84,67,84,67,84,65,67,84,65,65,65,65,65,84,65,67,65,65,65,65,65,84,84,65,71,67,67,71,71,71,67,71,84,71,71,84,71,71,67,71,67,71,67,71,67,67,84,71,84,65,65,84,67,67,67,65,71,67,84,65,67,84,67,71,71,71,65,71,71,67,84,71,65,71,71,67,65,71,71,65,71,65,65,84,67,71,67,84,84,71,65,65,67,67,67,71,71,71,65,71,71,67,71,71,65,71,71,84,84,71,67,65,71,84,71,65,71,67,67,71,65,71,65,84,67,71,67,71,67,67,65,67,84,71,67,65,67,84,67,67,65,71,67,67,84,71,71,71,67,71,65,67,65,71,65,71,67,71,65,71,65,67,84,67,67,71,84,67,84,67,65,65,65,65,65,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,4,0,0,1,0,0,0,2,0,0,0,1,0,0,0,0,0,0,0,115,116,100,58,58,98,97,100,95,97,108,108,111,99,0,0,83,116,57,98,97,100,95,97,108,108,111,99,0,0,0,0,8,0,0,0,104,4,0,0,0,0,0,0,0,0,0,0], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE);
+
+
+
+
+var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);
+
+assert(tempDoublePtr % 8 == 0);
+
+function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+}
+
+function copyTempDouble(ptr) {
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+  HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];
+
+  HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];
+
+  HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];
+
+  HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];
+
+}
+
+
+
+
+  var ___errno_state=0;function ___setErrNo(value) {
+      // For convenient setting and returning of errno.
+      HEAP32[((___errno_state)>>2)]=value;
+      return value;
+    }
+
+  var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};function _sysconf(name) {
+      // long sysconf(int name);
+      // http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html
+      switch(name) {
+        case 30: return PAGE_SIZE;
+        case 132:
+        case 133:
+        case 12:
+        case 137:
+        case 138:
+        case 15:
+        case 235:
+        case 16:
+        case 17:
+        case 18:
+        case 19:
+        case 20:
+        case 149:
+        case 13:
+        case 10:
+        case 236:
+        case 153:
+        case 9:
+        case 21:
+        case 22:
+        case 159:
+        case 154:
+        case 14:
+        case 77:
+        case 78:
+        case 139:
+        case 80:
+        case 81:
+        case 79:
+        case 82:
+        case 68:
+        case 67:
+        case 164:
+        case 11:
+        case 29:
+        case 47:
+        case 48:
+        case 95:
+        case 52:
+        case 51:
+        case 46:
+          return 200809;
+        case 27:
+        case 246:
+        case 127:
+        case 128:
+        case 23:
+        case 24:
+        case 160:
+        case 161:
+        case 181:
+        case 182:
+        case 242:
+        case 183:
+        case 184:
+        case 243:
+        case 244:
+        case 245:
+        case 165:
+        case 178:
+        case 179:
+        case 49:
+        case 50:
+        case 168:
+        case 169:
+        case 175:
+        case 170:
+        case 171:
+        case 172:
+        case 97:
+        case 76:
+        case 32:
+        case 173:
+        case 35:
+          return -1;
+        case 176:
+        case 177:
+        case 7:
+        case 155:
+        case 8:
+        case 157:
+        case 125:
+        case 126:
+        case 92:
+        case 93:
+        case 129:
+        case 130:
+        case 131:
+        case 94:
+        case 91:
+          return 1;
+        case 74:
+        case 60:
+        case 69:
+        case 70:
+        case 4:
+          return 1024;
+        case 31:
+        case 42:
+        case 72:
+          return 32;
+        case 87:
+        case 26:
+        case 33:
+          return 2147483647;
+        case 34:
+        case 1:
+          return 47839;
+        case 38:
+        case 36:
+          return 99;
+        case 43:
+        case 37:
+          return 2048;
+        case 0: return 2097152;
+        case 3: return 65536;
+        case 28: return 32768;
+        case 44: return 32767;
+        case 75: return 16384;
+        case 39: return 1000;
+        case 89: return 700;
+        case 71: return 256;
+        case 40: return 255;
+        case 2: return 100;
+        case 180: return 64;
+        case 25: return 20;
+        case 5: return 16;
+        case 6: return 6;
+        case 73: return 4;
+        case 84: return 1;
+      }
+      ___setErrNo(ERRNO_CODES.EINVAL);
+      return -1;
+    }
+
+
+  function __ZSt18uncaught_exceptionv() { // std::uncaught_exception()
+      return !!__ZSt18uncaught_exceptionv.uncaught_exception;
+    }
+
+
+
+  function ___cxa_is_number_type(type) {
+      var isNumber = false;
+      try { if (type == __ZTIi) isNumber = true } catch(e){}
+      try { if (type == __ZTIj) isNumber = true } catch(e){}
+      try { if (type == __ZTIl) isNumber = true } catch(e){}
+      try { if (type == __ZTIm) isNumber = true } catch(e){}
+      try { if (type == __ZTIx) isNumber = true } catch(e){}
+      try { if (type == __ZTIy) isNumber = true } catch(e){}
+      try { if (type == __ZTIf) isNumber = true } catch(e){}
+      try { if (type == __ZTId) isNumber = true } catch(e){}
+      try { if (type == __ZTIe) isNumber = true } catch(e){}
+      try { if (type == __ZTIc) isNumber = true } catch(e){}
+      try { if (type == __ZTIa) isNumber = true } catch(e){}
+      try { if (type == __ZTIh) isNumber = true } catch(e){}
+      try { if (type == __ZTIs) isNumber = true } catch(e){}
+      try { if (type == __ZTIt) isNumber = true } catch(e){}
+      return isNumber;
+    }function ___cxa_does_inherit(definiteType, possibilityType, possibility) {
+      if (possibility == 0) return false;
+      if (possibilityType == 0 || possibilityType == definiteType)
+        return true;
+      var possibility_type_info;
+      if (___cxa_is_number_type(possibilityType)) {
+        possibility_type_info = possibilityType;
+      } else {
+        var possibility_type_infoAddr = HEAP32[((possibilityType)>>2)] - 8;
+        possibility_type_info = HEAP32[((possibility_type_infoAddr)>>2)];
+      }
+      switch (possibility_type_info) {
+      case 0: // possibility is a pointer
+        // See if definite type is a pointer
+        var definite_type_infoAddr = HEAP32[((definiteType)>>2)] - 8;
+        var definite_type_info = HEAP32[((definite_type_infoAddr)>>2)];
+        if (definite_type_info == 0) {
+          // Also a pointer; compare base types of pointers
+          var defPointerBaseAddr = definiteType+8;
+          var defPointerBaseType = HEAP32[((defPointerBaseAddr)>>2)];
+          var possPointerBaseAddr = possibilityType+8;
+          var possPointerBaseType = HEAP32[((possPointerBaseAddr)>>2)];
+          return ___cxa_does_inherit(defPointerBaseType, possPointerBaseType, possibility);
+        } else
+          return false; // one pointer and one non-pointer
+      case 1: // class with no base class
+        return false;
+      case 2: // class with base class
+        var parentTypeAddr = possibilityType + 8;
+        var parentType = HEAP32[((parentTypeAddr)>>2)];
+        return ___cxa_does_inherit(definiteType, parentType, possibility);
+      default:
+        return false; // some unencountered type
+      }
+    }
+
+
+
+  var ___cxa_last_thrown_exception=0;function ___resumeException(ptr) {
+      if (!___cxa_last_thrown_exception) { ___cxa_last_thrown_exception = ptr; }
+      throw ptr + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.";
+    }
+
+  var ___cxa_exception_header_size=8;function ___cxa_find_matching_catch(thrown, throwntype) {
+      if (thrown == -1) thrown = ___cxa_last_thrown_exception;
+      header = thrown - ___cxa_exception_header_size;
+      if (throwntype == -1) throwntype = HEAP32[((header)>>2)];
+      var typeArray = Array.prototype.slice.call(arguments, 2);
+
+      // If throwntype is a pointer, this means a pointer has been
+      // thrown. When a pointer is thrown, actually what's thrown
+      // is a pointer to the pointer. We'll dereference it.
+      if (throwntype != 0 && !___cxa_is_number_type(throwntype)) {
+        var throwntypeInfoAddr= HEAP32[((throwntype)>>2)] - 8;
+        var throwntypeInfo= HEAP32[((throwntypeInfoAddr)>>2)];
+        if (throwntypeInfo == 0)
+          thrown = HEAP32[((thrown)>>2)];
+      }
+      // The different catch blocks are denoted by different types.
+      // Due to inheritance, those types may not precisely match the
+      // type of the thrown object. Find one which matches, and
+      // return the type of the catch block which should be called.
+      for (var i = 0; i < typeArray.length; i++) {
+        if (___cxa_does_inherit(typeArray[i], throwntype, thrown))
+          return ((asm["setTempRet0"](typeArray[i]),thrown)|0);
+      }
+      // Shouldn't happen unless we have bogus data in typeArray
+      // or encounter a type for which emscripten doesn't have suitable
+      // typeinfo defined. Best-efforts match just in case.
+      return ((asm["setTempRet0"](throwntype),thrown)|0);
+    }function ___cxa_throw(ptr, type, destructor) {
+      if (!___cxa_throw.initialized) {
+        try {
+          HEAP32[((__ZTVN10__cxxabiv119__pointer_type_infoE)>>2)]=0; // Workaround for libcxxabi integration bug
+        } catch(e){}
+        try {
+          HEAP32[((__ZTVN10__cxxabiv117__class_type_infoE)>>2)]=1; // Workaround for libcxxabi integration bug
+        } catch(e){}
+        try {
+          HEAP32[((__ZTVN10__cxxabiv120__si_class_type_infoE)>>2)]=2; // Workaround for libcxxabi integration bug
+        } catch(e){}
+        ___cxa_throw.initialized = true;
+      }
+      var header = ptr - ___cxa_exception_header_size;
+      HEAP32[((header)>>2)]=type;
+      HEAP32[(((header)+(4))>>2)]=destructor;
+      ___cxa_last_thrown_exception = ptr;
+      if (!("uncaught_exception" in __ZSt18uncaught_exceptionv)) {
+        __ZSt18uncaught_exceptionv.uncaught_exception = 1;
+      } else {
+        __ZSt18uncaught_exceptionv.uncaught_exception++;
+      }
+      throw ptr + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch.";
+    }
+
+
+  Module["_memset"] = _memset;
+
+  function _abort() {
+      Module['abort']();
+    }
+
+
+
+
+
+  var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can   access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};
+
+  var PATH={splitPath:function (filename) {
+        var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+        return splitPathRe.exec(filename).slice(1);
+      },normalizeArray:function (parts, allowAboveRoot) {
+        // if the path tries to go above the root, `up` ends up > 0
+        var up = 0;
+        for (var i = parts.length - 1; i >= 0; i--) {
+          var last = parts[i];
+          if (last === '.') {
+            parts.splice(i, 1);
+          } else if (last === '..') {
+            parts.splice(i, 1);
+            up++;
+          } else if (up) {
+            parts.splice(i, 1);
+            up--;
+          }
+        }
+        // if the path is allowed to go above the root, restore leading ..s
+        if (allowAboveRoot) {
+          for (; up--; up) {
+            parts.unshift('..');
+          }
+        }
+        return parts;
+      },normalize:function (path) {
+        var isAbsolute = path.charAt(0) === '/',
+            trailingSlash = path.substr(-1) === '/';
+        // Normalize the path
+        path = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), !isAbsolute).join('/');
+        if (!path && !isAbsolute) {
+          path = '.';
+        }
+        if (path && trailingSlash) {
+          path += '/';
+        }
+        return (isAbsolute ? '/' : '') + path;
+      },dirname:function (path) {
+        var result = PATH.splitPath(path),
+            root = result[0],
+            dir = result[1];
+        if (!root && !dir) {
+          // No dirname whatsoever
+          return '.';
+        }
+        if (dir) {
+          // It has a dirname, strip trailing slash
+          dir = dir.substr(0, dir.length - 1);
+        }
+        return root + dir;
+      },basename:function (path) {
+        // EMSCRIPTEN return '/'' for '/', not an empty string
+        if (path === '/') return '/';
+        var lastSlash = path.lastIndexOf('/');
+        if (lastSlash === -1) return path;
+        return path.substr(lastSlash+1);
+      },extname:function (path) {
+        return PATH.splitPath(path)[3];
+      },join:function () {
+        var paths = Array.prototype.slice.call(arguments, 0);
+        return PATH.normalize(paths.join('/'));
+      },join2:function (l, r) {
+        return PATH.normalize(l + '/' + r);
+      },resolve:function () {
+        var resolvedPath = '',
+          resolvedAbsolute = false;
+        for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+          var path = (i >= 0) ? arguments[i] : FS.cwd();
+          // Skip empty and invalid entries
+          if (typeof path !== 'string') {
+            throw new TypeError('Arguments to path.resolve must be strings');
+          } else if (!path) {
+            continue;
+          }
+          resolvedPath = path + '/' + resolvedPath;
+          resolvedAbsolute = path.charAt(0) === '/';
+        }
+        // At this point the path should be resolved to a full absolute path, but
+        // handle relative paths to be safe (might happen when process.cwd() fails)
+        resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
+          return !!p;
+        }), !resolvedAbsolute).join('/');
+        return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+      },relative:function (from, to) {
+        from = PATH.resolve(from).substr(1);
+        to = PATH.resolve(to).substr(1);
+        function trim(arr) {
+          var start = 0;
+          for (; start < arr.length; start++) {
+            if (arr[start] !== '') break;
+          }
+          var end = arr.length - 1;
+          for (; end >= 0; end--) {
+            if (arr[end] !== '') break;
+          }
+          if (start > end) return [];
+          return arr.slice(start, end - start + 1);
+        }
+        var fromParts = trim(from.split('/'));
+        var toParts = trim(to.split('/'));
+        var length = Math.min(fromParts.length, toParts.length);
+        var samePartsLength = length;
+        for (var i = 0; i < length; i++) {
+          if (fromParts[i] !== toParts[i]) {
+            samePartsLength = i;
+            break;
+          }
+        }
+        var outputParts = [];
+        for (var i = samePartsLength; i < fromParts.length; i++) {
+          outputParts.push('..');
+        }
+        outputParts = outputParts.concat(toParts.slice(samePartsLength));
+        return outputParts.join('/');
+      }};
+
+  var TTY={ttys:[],init:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // currently, FS.init does not distinguish if process.stdin is a file or TTY
+        //   // device, it always assumes it's a TTY device. because of this, we're forcing
+        //   // process.stdin to UTF8 encoding to at least make stdin reading compatible
+        //   // with text files until FS.init can be refactored.
+        //   process['stdin']['setEncoding']('utf8');
+        // }
+      },shutdown:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
+        //   // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
+        //   // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
+        //   // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
+        //   // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
+        //   process['stdin']['pause']();
+        // }
+      },register:function (dev, ops) {
+        TTY.ttys[dev] = { input: [], output: [], ops: ops };
+        FS.registerDevice(dev, TTY.stream_ops);
+      },stream_ops:{open:function (stream) {
+          var tty = TTY.ttys[stream.node.rdev];
+          if (!tty) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          stream.tty = tty;
+          stream.seekable = false;
+        },close:function (stream) {
+          // flush any pending line data
+          if (stream.tty.output.length) {
+            stream.tty.ops.put_char(stream.tty, 10);
+          }
+        },read:function (stream, buffer, offset, length, pos /* ignored */) {
+          if (!stream.tty || !stream.tty.ops.get_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          var bytesRead = 0;
+          for (var i = 0; i < length; i++) {
+            var result;
+            try {
+              result = stream.tty.ops.get_char(stream.tty);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            if (result === undefined && bytesRead === 0) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+            if (result === null || result === undefined) break;
+            bytesRead++;
+            buffer[offset+i] = result;
+          }
+          if (bytesRead) {
+            stream.node.timestamp = Date.now();
+          }
+          return bytesRead;
+        },write:function (stream, buffer, offset, length, pos) {
+          if (!stream.tty || !stream.tty.ops.put_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          for (var i = 0; i < length; i++) {
+            try {
+              stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+          }
+          if (length) {
+            stream.node.timestamp = Date.now();
+          }
+          return i;
+        }},default_tty_ops:{get_char:function (tty) {
+          if (!tty.input.length) {
+            var result = null;
+            if (ENVIRONMENT_IS_NODE) {
+              result = process['stdin']['read']();
+              if (!result) {
+                if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) {
+                  return null;  // EOF
+                }
+                return undefined;  // no data available
+              }
+            } else if (typeof window != 'undefined' &&
+              typeof window.prompt == 'function') {
+              // Browser.
+              result = window.prompt('Input: ');  // returns null on cancel
+              if (result !== null) {
+                result += '\n';
+              }
+            } else if (typeof readline == 'function') {
+              // Command line.
+              result = readline();
+              if (result !== null) {
+                result += '\n';
+              }
+            }
+            if (!result) {
+              return null;
+            }
+            tty.input = intArrayFromString(result, true);
+          }
+          return tty.input.shift();
+        },put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['print'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }},default_tty1_ops:{put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['printErr'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }}};
+
+  var MEMFS={ops_table:null,CONTENT_OWNING:1,CONTENT_FLEXIBLE:2,CONTENT_FIXED:3,mount:function (mount) {
+        return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
+          // no supported
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (!MEMFS.ops_table) {
+          MEMFS.ops_table = {
+            dir: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                lookup: MEMFS.node_ops.lookup,
+                mknod: MEMFS.node_ops.mknod,
+                rename: MEMFS.node_ops.rename,
+                unlink: MEMFS.node_ops.unlink,
+                rmdir: MEMFS.node_ops.rmdir,
+                readdir: MEMFS.node_ops.readdir,
+                symlink: MEMFS.node_ops.symlink
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek
+              }
+            },
+            file: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek,
+                read: MEMFS.stream_ops.read,
+                write: MEMFS.stream_ops.write,
+                allocate: MEMFS.stream_ops.allocate,
+                mmap: MEMFS.stream_ops.mmap
+              }
+            },
+            link: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                readlink: MEMFS.node_ops.readlink
+              },
+              stream: {}
+            },
+            chrdev: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: FS.chrdev_stream_ops
+            },
+          };
+        }
+        var node = FS.createNode(parent, name, mode, dev);
+        if (FS.isDir(node.mode)) {
+          node.node_ops = MEMFS.ops_table.dir.node;
+          node.stream_ops = MEMFS.ops_table.dir.stream;
+          node.contents = {};
+        } else if (FS.isFile(node.mode)) {
+          node.node_ops = MEMFS.ops_table.file.node;
+          node.stream_ops = MEMFS.ops_table.file.stream;
+          node.contents = [];
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        } else if (FS.isLink(node.mode)) {
+          node.node_ops = MEMFS.ops_table.link.node;
+          node.stream_ops = MEMFS.ops_table.link.stream;
+        } else if (FS.isChrdev(node.mode)) {
+          node.node_ops = MEMFS.ops_table.chrdev.node;
+          node.stream_ops = MEMFS.ops_table.chrdev.stream;
+        }
+        node.timestamp = Date.now();
+        // add the new node to the parent
+        if (parent) {
+          parent.contents[name] = node;
+        }
+        return node;
+      },ensureFlexible:function (node) {
+        if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
+          var contents = node.contents;
+          node.contents = Array.prototype.slice.call(contents);
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        }
+      },node_ops:{getattr:function (node) {
+          var attr = {};
+          // device numbers reuse inode numbers.
+          attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
+          attr.ino = node.id;
+          attr.mode = node.mode;
+          attr.nlink = 1;
+          attr.uid = 0;
+          attr.gid = 0;
+          attr.rdev = node.rdev;
+          if (FS.isDir(node.mode)) {
+            attr.size = 4096;
+          } else if (FS.isFile(node.mode)) {
+            attr.size = node.contents.length;
+          } else if (FS.isLink(node.mode)) {
+            attr.size = node.link.length;
+          } else {
+            attr.size = 0;
+          }
+          attr.atime = new Date(node.timestamp);
+          attr.mtime = new Date(node.timestamp);
+          attr.ctime = new Date(node.timestamp);
+          // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
+          //       but this is not required by the standard.
+          attr.blksize = 4096;
+          attr.blocks = Math.ceil(attr.size / attr.blksize);
+          return attr;
+        },setattr:function (node, attr) {
+          if (attr.mode !== undefined) {
+            node.mode = attr.mode;
+          }
+          if (attr.timestamp !== undefined) {
+            node.timestamp = attr.timestamp;
+          }
+          if (attr.size !== undefined) {
+            MEMFS.ensureFlexible(node);
+            var contents = node.contents;
+            if (attr.size < contents.length) contents.length = attr.size;
+            else while (attr.size > contents.length) contents.push(0);
+          }
+        },lookup:function (parent, name) {
+          throw FS.genericErrors[ERRNO_CODES.ENOENT];
+        },mknod:function (parent, name, mode, dev) {
+          return MEMFS.createNode(parent, name, mode, dev);
+        },rename:function (old_node, new_dir, new_name) {
+          // if we're overwriting a directory at new_name, make sure it's empty.
+          if (FS.isDir(old_node.mode)) {
+            var new_node;
+            try {
+              new_node = FS.lookupNode(new_dir, new_name);
+            } catch (e) {
+            }
+            if (new_node) {
+              for (var i in new_node.contents) {
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+              }
+            }
+          }
+          // do the internal rewiring
+          delete old_node.parent.contents[old_node.name];
+          old_node.name = new_name;
+          new_dir.contents[new_name] = old_node;
+          old_node.parent = new_dir;
+        },unlink:function (parent, name) {
+          delete parent.contents[name];
+        },rmdir:function (parent, name) {
+          var node = FS.lookupNode(parent, name);
+          for (var i in node.contents) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+          }
+          delete parent.contents[name];
+        },readdir:function (node) {
+          var entries = ['.', '..']
+          for (var key in node.contents) {
+            if (!node.contents.hasOwnProperty(key)) {
+              continue;
+            }
+            entries.push(key);
+          }
+          return entries;
+        },symlink:function (parent, newname, oldpath) {
+          var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
+          node.link = oldpath;
+          return node;
+        },readlink:function (node) {
+          if (!FS.isLink(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          return node.link;
+        }},stream_ops:{read:function (stream, buffer, offset, length, position) {
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (size > 8 && contents.subarray) { // non-trivial, and typed array
+            buffer.set(contents.subarray(position, position + size), offset);
+          } else
+          {
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          }
+          return size;
+        },write:function (stream, buffer, offset, length, position, canOwn) {
+          var node = stream.node;
+          node.timestamp = Date.now();
+          var contents = node.contents;
+          if (length && contents.length === 0 && position === 0 && buffer.subarray) {
+            // just replace it with the new data
+            if (canOwn && offset === 0) {
+              node.contents = buffer; // this could be a subarray of Emscripten HEAP, or allocated from some other source.
+              node.contentMode = (buffer.buffer === HEAP8.buffer) ? MEMFS.CONTENT_OWNING : MEMFS.CONTENT_FIXED;
+            } else {
+              node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
+              node.contentMode = MEMFS.CONTENT_FIXED;
+            }
+            return length;
+          }
+          MEMFS.ensureFlexible(node);
+          var contents = node.contents;
+          while (contents.length < position) contents.push(0);
+          for (var i = 0; i < length; i++) {
+            contents[position + i] = buffer[offset + i];
+          }
+          return length;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              position += stream.node.contents.length;
+            }
+          }
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          stream.ungotten = [];
+          stream.position = position;
+          return position;
+        },allocate:function (stream, offset, length) {
+          MEMFS.ensureFlexible(stream.node);
+          var contents = stream.node.contents;
+          var limit = offset + length;
+          while (limit > contents.length) contents.push(0);
+        },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+          if (!FS.isFile(stream.node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          var ptr;
+          var allocated;
+          var contents = stream.node.contents;
+          // Only make a new copy when MAP_PRIVATE is specified.
+          if ( !(flags & 2) &&
+                (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
+            // We can't emulate MAP_SHARED when the file is not backed by the buffer
+            // we're mapping to (e.g. the HEAP buffer).
+            allocated = false;
+            ptr = contents.byteOffset;
+          } else {
+            // Try to avoid unnecessary slices.
+            if (position > 0 || position + length < contents.length) {
+              if (contents.subarray) {
+                contents = contents.subarray(position, position + length);
+              } else {
+                contents = Array.prototype.slice.call(contents, position, position + length);
+              }
+            }
+            allocated = true;
+            ptr = _malloc(length);
+            if (!ptr) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOMEM);
+            }
+            buffer.set(contents, ptr);
+          }
+          return { ptr: ptr, allocated: allocated };
+        }}};
+
+  var IDBFS={dbs:{},indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) {
+        // reuse all of the core MEMFS functionality
+        return MEMFS.mount.apply(null, arguments);
+      },syncfs:function (mount, populate, callback) {
+        IDBFS.getLocalSet(mount, function(err, local) {
+          if (err) return callback(err);
+
+          IDBFS.getRemoteSet(mount, function(err, remote) {
+            if (err) return callback(err);
+
+            var src = populate ? remote : local;
+            var dst = populate ? local : remote;
+
+            IDBFS.reconcile(src, dst, callback);
+          });
+        });
+      },getDB:function (name, callback) {
+        // check the cache first
+        var db = IDBFS.dbs[name];
+        if (db) {
+          return callback(null, db);
+        }
+
+        var req;
+        try {
+          req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
+        } catch (e) {
+          return callback(e);
+        }
+        req.onupgradeneeded = function(e) {
+          var db = e.target.result;
+          var transaction = e.target.transaction;
+
+          var fileStore;
+
+          if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
+            fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          } else {
+            fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
+          }
+
+          fileStore.createIndex('timestamp', 'timestamp', { unique: false });
+        };
+        req.onsuccess = function() {
+          db = req.result;
+
+          // add to the cache
+          IDBFS.dbs[name] = db;
+          callback(null, db);
+        };
+        req.onerror = function() {
+          callback(this.error);
+        };
+      },getLocalSet:function (mount, callback) {
+        var entries = {};
+
+        function isRealDir(p) {
+          return p !== '.' && p !== '..';
+        };
+        function toAbsolute(root) {
+          return function(p) {
+            return PATH.join2(root, p);
+          }
+        };
+
+        var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
+
+        while (check.length) {
+          var path = check.pop();
+          var stat;
+
+          try {
+            stat = FS.stat(path);
+          } catch (e) {
+            return callback(e);
+          }
+
+          if (FS.isDir(stat.mode)) {
+            check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
+          }
+
+          entries[path] = { timestamp: stat.mtime };
+        }
+
+        return callback(null, { type: 'local', entries: entries });
+      },getRemoteSet:function (mount, callback) {
+        var entries = {};
+
+        IDBFS.getDB(mount.mountpoint, function(err, db) {
+          if (err) return callback(err);
+
+          var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly');
+          transaction.onerror = function() { callback(this.error); };
+
+          var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          var index = store.index('timestamp');
+
+          index.openKeyCursor().onsuccess = function(event) {
+            var cursor = event.target.result;
+
+            if (!cursor) {
+              return callback(null, { type: 'remote', db: db, entries: entries });
+            }
+
+            entries[cursor.primaryKey] = { timestamp: cursor.key };
+
+            cursor.continue();
+          };
+        });
+      },loadLocalEntry:function (path, callback) {
+        var stat, node;
+
+        try {
+          var lookup = FS.lookupPath(path);
+          node = lookup.node;
+          stat = FS.stat(path);
+        } catch (e) {
+          return callback(e);
+        }
+
+        if (FS.isDir(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode });
+        } else if (FS.isFile(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents });
+        } else {
+          return callback(new Error('node type not supported'));
+        }
+      },storeLocalEntry:function (path, entry, callback) {
+        try {
+          if (FS.isDir(entry.mode)) {
+            FS.mkdir(path, entry.mode);
+          } else if (FS.isFile(entry.mode)) {
+            FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true });
+          } else {
+            return callback(new Error('node type not supported'));
+          }
+
+          FS.utime(path, entry.timestamp, entry.timestamp);
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },removeLocalEntry:function (path, callback) {
+        try {
+          var lookup = FS.lookupPath(path);
+          var stat = FS.stat(path);
+
+          if (FS.isDir(stat.mode)) {
+            FS.rmdir(path);
+          } else if (FS.isFile(stat.mode)) {
+            FS.unlink(path);
+          }
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },loadRemoteEntry:function (store, path, callback) {
+        var req = store.get(path);
+        req.onsuccess = function(event) { callback(null, event.target.result); };
+        req.onerror = function() { callback(this.error); };
+      },storeRemoteEntry:function (store, path, entry, callback) {
+        var req = store.put(entry, path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },removeRemoteEntry:function (store, path, callback) {
+        var req = store.delete(path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },reconcile:function (src, dst, callback) {
+        var total = 0;
+
+        var create = [];
+        Object.keys(src.entries).forEach(function (key) {
+          var e = src.entries[key];
+          var e2 = dst.entries[key];
+          if (!e2 || e.timestamp > e2.timestamp) {
+            create.push(key);
+            total++;
+          }
+        });
+
+        var remove = [];
+        Object.keys(dst.entries).forEach(function (key) {
+          var e = dst.entries[key];
+          var e2 = src.entries[key];
+          if (!e2) {
+            remove.push(key);
+            total++;
+          }
+        });
+
+        if (!total) {
+          return callback(null);
+        }
+
+        var errored = false;
+        var completed = 0;
+        var db = src.type === 'remote' ? src.db : dst.db;
+        var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
+        var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= total) {
+            return callback(null);
+          }
+        };
+
+        transaction.onerror = function() { done(this.error); };
+
+        // sort paths in ascending order so directory entries are created
+        // before the files inside them
+        create.sort().forEach(function (path) {
+          if (dst.type === 'local') {
+            IDBFS.loadRemoteEntry(store, path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeLocalEntry(path, entry, done);
+            });
+          } else {
+            IDBFS.loadLocalEntry(path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeRemoteEntry(store, path, entry, done);
+            });
+          }
+        });
+
+        // sort paths in descending order so files are deleted before their
+        // parent directories
+        remove.sort().reverse().forEach(function(path) {
+          if (dst.type === 'local') {
+            IDBFS.removeLocalEntry(path, done);
+          } else {
+            IDBFS.removeRemoteEntry(store, path, done);
+          }
+        });
+      }};
+
+  var NODEFS={isWindows:false,staticInit:function () {
+        NODEFS.isWindows = !!process.platform.match(/^win/);
+      },mount:function (mount) {
+        assert(ENVIRONMENT_IS_NODE);
+        return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node = FS.createNode(parent, name, mode);
+        node.node_ops = NODEFS.node_ops;
+        node.stream_ops = NODEFS.stream_ops;
+        return node;
+      },getMode:function (path) {
+        var stat;
+        try {
+          stat = fs.lstatSync(path);
+          if (NODEFS.isWindows) {
+            // On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so
+            // propagate write bits to execute bits.
+            stat.mode = stat.mode | ((stat.mode & 146) >> 1);
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        return stat.mode;
+      },realPath:function (node) {
+        var parts = [];
+        while (node.parent !== node) {
+          parts.push(node.name);
+          node = node.parent;
+        }
+        parts.push(node.mount.opts.root);
+        parts.reverse();
+        return PATH.join.apply(null, parts);
+      },flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) {
+        if (flags in NODEFS.flagsToPermissionStringMap) {
+          return NODEFS.flagsToPermissionStringMap[flags];
+        } else {
+          return flags;
+        }
+      },node_ops:{getattr:function (node) {
+          var path = NODEFS.realPath(node);
+          var stat;
+          try {
+            stat = fs.lstatSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096.
+          // See http://support.microsoft.com/kb/140365
+          if (NODEFS.isWindows && !stat.blksize) {
+            stat.blksize = 4096;
+          }
+          if (NODEFS.isWindows && !stat.blocks) {
+            stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0;
+          }
+          return {
+            dev: stat.dev,
+            ino: stat.ino,
+            mode: stat.mode,
+            nlink: stat.nlink,
+            uid: stat.uid,
+            gid: stat.gid,
+            rdev: stat.rdev,
+            size: stat.size,
+            atime: stat.atime,
+            mtime: stat.mtime,
+            ctime: stat.ctime,
+            blksize: stat.blksize,
+            blocks: stat.blocks
+          };
+        },setattr:function (node, attr) {
+          var path = NODEFS.realPath(node);
+          try {
+            if (attr.mode !== undefined) {
+              fs.chmodSync(path, attr.mode);
+              // update the common node structure mode as well
+              node.mode = attr.mode;
+            }
+            if (attr.timestamp !== undefined) {
+              var date = new Date(attr.timestamp);
+              fs.utimesSync(path, date, date);
+            }
+            if (attr.size !== undefined) {
+              fs.truncateSync(path, attr.size);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },lookup:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          var mode = NODEFS.getMode(path);
+          return NODEFS.createNode(parent, name, mode);
+        },mknod:function (parent, name, mode, dev) {
+          var node = NODEFS.createNode(parent, name, mode, dev);
+          // create the backing node for this in the fs root as well
+          var path = NODEFS.realPath(node);
+          try {
+            if (FS.isDir(node.mode)) {
+              fs.mkdirSync(path, node.mode);
+            } else {
+              fs.writeFileSync(path, '', { mode: node.mode });
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return node;
+        },rename:function (oldNode, newDir, newName) {
+          var oldPath = NODEFS.realPath(oldNode);
+          var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
+          try {
+            fs.renameSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },unlink:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.unlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },rmdir:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.rmdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readdir:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },symlink:function (parent, newName, oldPath) {
+          var newPath = PATH.join2(NODEFS.realPath(parent), newName);
+          try {
+            fs.symlinkSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readlink:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        }},stream_ops:{open:function (stream) {
+          var path = NODEFS.realPath(stream.node);
+          try {
+            if (FS.isFile(stream.node.mode)) {
+              stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags));
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },close:function (stream) {
+          try {
+            if (FS.isFile(stream.node.mode) && stream.nfd) {
+              fs.closeSync(stream.nfd);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },read:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(length);
+          var res;
+          try {
+            res = fs.readSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          if (res > 0) {
+            for (var i = 0; i < res; i++) {
+              buffer[offset + i] = nbuffer[i];
+            }
+          }
+          return res;
+        },write:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(buffer.subarray(offset, offset + length));
+          var res;
+          try {
+            res = fs.writeSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return res;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              try {
+                var stat = fs.fstatSync(stream.nfd);
+                position += stat.size;
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+              }
+            }
+          }
+
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+
+          stream.position = position;
+          return position;
+        }}};
+
+  var _stdin=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stdout=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stderr=allocate(1, "i32*", ALLOC_STATIC);
+
+  function _fflush(stream) {
+      // int fflush(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html
+      // we don't currently perform any user-space buffering of data
+    }var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},handleFSError:function (e) {
+        if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
+        return ___setErrNo(e.errno);
+      },lookupPath:function (path, opts) {
+        path = PATH.resolve(FS.cwd(), path);
+        opts = opts || {};
+
+        var defaults = {
+          follow_mount: true,
+          recurse_count: 0
+        };
+        for (var key in defaults) {
+          if (opts[key] === undefined) {
+            opts[key] = defaults[key];
+          }
+        }
+
+        if (opts.recurse_count > 8) {  // max recursive lookup of 8
+          throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+        }
+
+        // split the path
+        var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), false);
+
+        // start at the root
+        var current = FS.root;
+        var current_path = '/';
+
+        for (var i = 0; i < parts.length; i++) {
+          var islast = (i === parts.length-1);
+          if (islast && opts.parent) {
+            // stop resolving
+            break;
+          }
+
+          current = FS.lookupNode(current, parts[i]);
+          current_path = PATH.join2(current_path, parts[i]);
+
+          // jump to the mount's root node if this is a mountpoint
+          if (FS.isMountpoint(current)) {
+            if (!islast || (islast && opts.follow_mount)) {
+              current = current.mounted.root;
+            }
+          }
+
+          // by default, lookupPath will not follow a symlink if it is the final path component.
+          // setting opts.follow = true will override this behavior.
+          if (!islast || opts.follow) {
+            var count = 0;
+            while (FS.isLink(current.mode)) {
+              var link = FS.readlink(current_path);
+              current_path = PATH.resolve(PATH.dirname(current_path), link);
+
+              var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
+              current = lookup.node;
+
+              if (count++ > 40) {  // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
+                throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+              }
+            }
+          }
+        }
+
+        return { path: current_path, node: current };
+      },getPath:function (node) {
+        var path;
+        while (true) {
+          if (FS.isRoot(node)) {
+            var mount = node.mount.mountpoint;
+            if (!path) return mount;
+            return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
+          }
+          path = path ? node.name + '/' + path : node.name;
+          node = node.parent;
+        }
+      },hashName:function (parentid, name) {
+        var hash = 0;
+
+
+        for (var i = 0; i < name.length; i++) {
+          hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
+        }
+        return ((parentid + hash) >>> 0) % FS.nameTable.length;
+      },hashAddNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        node.name_next = FS.nameTable[hash];
+        FS.nameTable[hash] = node;
+      },hashRemoveNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        if (FS.nameTable[hash] === node) {
+          FS.nameTable[hash] = node.name_next;
+        } else {
+          var current = FS.nameTable[hash];
+          while (current) {
+            if (current.name_next === node) {
+              current.name_next = node.name_next;
+              break;
+            }
+            current = current.name_next;
+          }
+        }
+      },lookupNode:function (parent, name) {
+        var err = FS.mayLookup(parent);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        var hash = FS.hashName(parent.id, name);
+        for (var node = FS.nameTable[hash]; node; node = node.name_next) {
+          var nodeName = node.name;
+          if (node.parent.id === parent.id && nodeName === name) {
+            return node;
+          }
+        }
+        // if we failed to find it in the cache, call into the VFS
+        return FS.lookup(parent, name);
+      },createNode:function (parent, name, mode, rdev) {
+        if (!FS.FSNode) {
+          FS.FSNode = function(parent, name, mode, rdev) {
+            if (!parent) {
+              parent = this;  // root node sets parent to itself
+            }
+            this.parent = parent;
+            this.mount = parent.mount;
+            this.mounted = null;
+            this.id = FS.nextInode++;
+            this.name = name;
+            this.mode = mode;
+            this.node_ops = {};
+            this.stream_ops = {};
+            this.rdev = rdev;
+          };
+
+          FS.FSNode.prototype = {};
+
+          // compatibility
+          var readMode = 292 | 73;
+          var writeMode = 146;
+
+          // NOTE we must use Object.defineProperties instead of individual calls to
+          // Object.defineProperty in order to make closure compiler happy
+          Object.defineProperties(FS.FSNode.prototype, {
+            read: {
+              get: function() { return (this.mode & readMode) === readMode; },
+              set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; }
+            },
+            write: {
+              get: function() { return (this.mode & writeMode) === writeMode; },
+              set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; }
+            },
+            isFolder: {
+              get: function() { return FS.isDir(this.mode); },
+            },
+            isDevice: {
+              get: function() { return FS.isChrdev(this.mode); },
+            },
+          });
+        }
+
+        var node = new FS.FSNode(parent, name, mode, rdev);
+
+        FS.hashAddNode(node);
+
+        return node;
+      },destroyNode:function (node) {
+        FS.hashRemoveNode(node);
+      },isRoot:function (node) {
+        return node === node.parent;
+      },isMountpoint:function (node) {
+        return !!node.mounted;
+      },isFile:function (mode) {
+        return (mode & 61440) === 32768;
+      },isDir:function (mode) {
+        return (mode & 61440) === 16384;
+      },isLink:function (mode) {
+        return (mode & 61440) === 40960;
+      },isChrdev:function (mode) {
+        return (mode & 61440) === 8192;
+      },isBlkdev:function (mode) {
+        return (mode & 61440) === 24576;
+      },isFIFO:function (mode) {
+        return (mode & 61440) === 4096;
+      },isSocket:function (mode) {
+        return (mode & 49152) === 49152;
+      },flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function (str) {
+        var flags = FS.flagModes[str];
+        if (typeof flags === 'undefined') {
+          throw new Error('Unknown file open mode: ' + str);
+        }
+        return flags;
+      },flagsToPermissionString:function (flag) {
+        var accmode = flag & 2097155;
+        var perms = ['r', 'w', 'rw'][accmode];
+        if ((flag & 512)) {
+          perms += 'w';
+        }
+        return perms;
+      },nodePermissions:function (node, perms) {
+        if (FS.ignorePermissions) {
+          return 0;
+        }
+        // return 0 if any user, group or owner bits are set.
+        if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
+          return ERRNO_CODES.EACCES;
+        }
+        return 0;
+      },mayLookup:function (dir) {
+        return FS.nodePermissions(dir, 'x');
+      },mayCreate:function (dir, name) {
+        try {
+          var node = FS.lookupNode(dir, name);
+          return ERRNO_CODES.EEXIST;
+        } catch (e) {
+        }
+        return FS.nodePermissions(dir, 'wx');
+      },mayDelete:function (dir, name, isdir) {
+        var node;
+        try {
+          node = FS.lookupNode(dir, name);
+        } catch (e) {
+          return e.errno;
+        }
+        var err = FS.nodePermissions(dir, 'wx');
+        if (err) {
+          return err;
+        }
+        if (isdir) {
+          if (!FS.isDir(node.mode)) {
+            return ERRNO_CODES.ENOTDIR;
+          }
+          if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
+            return ERRNO_CODES.EBUSY;
+          }
+        } else {
+          if (FS.isDir(node.mode)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return 0;
+      },mayOpen:function (node, flags) {
+        if (!node) {
+          return ERRNO_CODES.ENOENT;
+        }
+        if (FS.isLink(node.mode)) {
+          return ERRNO_CODES.ELOOP;
+        } else if (FS.isDir(node.mode)) {
+          if ((flags & 2097155) !== 0 ||  // opening for write
+              (flags & 512)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
+      },MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) {
+        fd_start = fd_start || 0;
+        fd_end = fd_end || FS.MAX_OPEN_FDS;
+        for (var fd = fd_start; fd <= fd_end; fd++) {
+          if (!FS.streams[fd]) {
+            return fd;
+          }
+        }
+        throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
+      },getStream:function (fd) {
+        return FS.streams[fd];
+      },createStream:function (stream, fd_start, fd_end) {
+        if (!FS.FSStream) {
+          FS.FSStream = function(){};
+          FS.FSStream.prototype = {};
+          // compatibility
+          Object.defineProperties(FS.FSStream.prototype, {
+            object: {
+              get: function() { return this.node; },
+              set: function(val) { this.node = val; }
+            },
+            isRead: {
+              get: function() { return (this.flags & 2097155) !== 1; }
+            },
+            isWrite: {
+              get: function() { return (this.flags & 2097155) !== 0; }
+            },
+            isAppend: {
+              get: function() { return (this.flags & 1024); }
+            }
+          });
+        }
+        if (0) {
+          // reuse the object
+          stream.__proto__ = FS.FSStream.prototype;
+        } else {
+          var newStream = new FS.FSStream();
+          for (var p in stream) {
+            newStream[p] = stream[p];
+          }
+          stream = newStream;
+        }
+        var fd = FS.nextfd(fd_start, fd_end);
+        stream.fd = fd;
+        FS.streams[fd] = stream;
+        return stream;
+      },closeStream:function (fd) {
+        FS.streams[fd] = null;
+      },getStreamFromPtr:function (ptr) {
+        return FS.streams[ptr - 1];
+      },getPtrForStream:function (stream) {
+        return stream ? stream.fd + 1 : 0;
+      },chrdev_stream_ops:{open:function (stream) {
+          var device = FS.getDevice(stream.node.rdev);
+          // override node's stream ops with the device's
+          stream.stream_ops = device.stream_ops;
+          // forward the open call
+          if (stream.stream_ops.open) {
+            stream.stream_ops.open(stream);
+          }
+        },llseek:function () {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }},major:function (dev) {
+        return ((dev) >> 8);
+      },minor:function (dev) {
+        return ((dev) & 0xff);
+      },makedev:function (ma, mi) {
+        return ((ma) << 8 | (mi));
+      },registerDevice:function (dev, ops) {
+        FS.devices[dev] = { stream_ops: ops };
+      },getDevice:function (dev) {
+        return FS.devices[dev];
+      },getMounts:function (mount) {
+        var mounts = [];
+        var check = [mount];
+
+        while (check.length) {
+          var m = check.pop();
+
+          mounts.push(m);
+
+          check.push.apply(check, m.mounts);
+        }
+
+        return mounts;
+      },syncfs:function (populate, callback) {
+        if (typeof(populate) === 'function') {
+          callback = populate;
+          populate = false;
+        }
+
+        var mounts = FS.getMounts(FS.root.mount);
+        var completed = 0;
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= mounts.length) {
+            callback(null);
+          }
+        };
+
+        // sync all mounts
+        mounts.forEach(function (mount) {
+          if (!mount.type.syncfs) {
+            return done(null);
+          }
+          mount.type.syncfs(mount, populate, done);
+        });
+      },mount:function (type, opts, mountpoint) {
+        var root = mountpoint === '/';
+        var pseudo = !mountpoint;
+        var node;
+
+        if (root && FS.root) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        } else if (!root && !pseudo) {
+          var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+          mountpoint = lookup.path;  // use the absolute path
+          node = lookup.node;
+
+          if (FS.isMountpoint(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+          }
+
+          if (!FS.isDir(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+          }
+        }
+
+        var mount = {
+          type: type,
+          opts: opts,
+          mountpoint: mountpoint,
+          mounts: []
+        };
+
+        // create a root node for the fs
+        var mountRoot = type.mount(mount);
+        mountRoot.mount = mount;
+        mount.root = mountRoot;
+
+        if (root) {
+          FS.root = mountRoot;
+        } else if (node) {
+          // set as a mountpoint
+          node.mounted = mount;
+
+          // add the new mount to the current mount's children
+          if (node.mount) {
+            node.mount.mounts.push(mount);
+          }
+        }
+
+        return mountRoot;
+      },unmount:function (mountpoint) {
+        var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+        if (!FS.isMountpoint(lookup.node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+
+        // destroy the nodes for this mount, and all its child mounts
+        var node = lookup.node;
+        var mount = node.mounted;
+        var mounts = FS.getMounts(mount);
+
+        Object.keys(FS.nameTable).forEach(function (hash) {
+          var current = FS.nameTable[hash];
+
+          while (current) {
+            var next = current.name_next;
+
+            if (mounts.indexOf(current.mount) !== -1) {
+              FS.destroyNode(current);
+            }
+
+            current = next;
+          }
+        });
+
+        // no longer a mountpoint
+        node.mounted = null;
+
+        // remove this mount from the child mounts
+        var idx = node.mount.mounts.indexOf(mount);
+        assert(idx !== -1);
+        node.mount.mounts.splice(idx, 1);
+      },lookup:function (parent, name) {
+        return parent.node_ops.lookup(parent, name);
+      },mknod:function (path, mode, dev) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var err = FS.mayCreate(parent, name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.mknod) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.mknod(parent, name, mode, dev);
+      },create:function (path, mode) {
+        mode = mode !== undefined ? mode : 438 /* 0666 */;
+        mode &= 4095;
+        mode |= 32768;
+        return FS.mknod(path, mode, 0);
+      },mkdir:function (path, mode) {
+        mode = mode !== undefined ? mode : 511 /* 0777 */;
+        mode &= 511 | 512;
+        mode |= 16384;
+        return FS.mknod(path, mode, 0);
+      },mkdev:function (path, mode, dev) {
+        if (typeof(dev) === 'undefined') {
+          dev = mode;
+          mode = 438 /* 0666 */;
+        }
+        mode |= 8192;
+        return FS.mknod(path, mode, dev);
+      },symlink:function (oldpath, newpath) {
+        var lookup = FS.lookupPath(newpath, { parent: true });
+        var parent = lookup.node;
+        var newname = PATH.basename(newpath);
+        var err = FS.mayCreate(parent, newname);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.symlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.symlink(parent, newname, oldpath);
+      },rename:function (old_path, new_path) {
+        var old_dirname = PATH.dirname(old_path);
+        var new_dirname = PATH.dirname(new_path);
+        var old_name = PATH.basename(old_path);
+        var new_name = PATH.basename(new_path);
+        // parents must exist
+        var lookup, old_dir, new_dir;
+        try {
+          lookup = FS.lookupPath(old_path, { parent: true });
+          old_dir = lookup.node;
+          lookup = FS.lookupPath(new_path, { parent: true });
+          new_dir = lookup.node;
+        } catch (e) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // need to be part of the same mount
+        if (old_dir.mount !== new_dir.mount) {
+          throw new FS.ErrnoError(ERRNO_CODES.EXDEV);
+        }
+        // source must exist
+        var old_node = FS.lookupNode(old_dir, old_name);
+        // old path should not be an ancestor of the new path
+        var relative = PATH.relative(old_path, new_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        // new path should not be an ancestor of the old path
+        relative = PATH.relative(new_path, old_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+        }
+        // see if the new path already exists
+        var new_node;
+        try {
+          new_node = FS.lookupNode(new_dir, new_name);
+        } catch (e) {
+          // not fatal
+        }
+        // early out if nothing needs to change
+        if (old_node === new_node) {
+          return;
+        }
+        // we'll need to delete the old entry
+        var isdir = FS.isDir(old_node.mode);
+        var err = FS.mayDelete(old_dir, old_name, isdir);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // need delete permissions if we'll be overwriting.
+        // need create permissions if new doesn't already exist.
+        err = new_node ?
+          FS.mayDelete(new_dir, new_name, isdir) :
+          FS.mayCreate(new_dir, new_name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!old_dir.node_ops.rename) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // if we are going to change the parent, check write permissions
+        if (new_dir !== old_dir) {
+          err = FS.nodePermissions(old_dir, 'w');
+          if (err) {
+            throw new FS.ErrnoError(err);
+          }
+        }
+        // remove the node from the lookup hash
+        FS.hashRemoveNode(old_node);
+        // do the underlying fs rename
+        try {
+          old_dir.node_ops.rename(old_node, new_dir, new_name);
+        } catch (e) {
+          throw e;
+        } finally {
+          // add the node back to the hash (in case node_ops.rename
+          // changed its name)
+          FS.hashAddNode(old_node);
+        }
+      },rmdir:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, true);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.rmdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.rmdir(parent, name);
+        FS.destroyNode(node);
+      },readdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        if (!node.node_ops.readdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        return node.node_ops.readdir(node);
+      },unlink:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, false);
+        if (err) {
+          // POSIX says unlink should set EPERM, not EISDIR
+          if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM;
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.unlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.unlink(parent, name);
+        FS.destroyNode(node);
+      },readlink:function (path) {
+        var lookup = FS.lookupPath(path);
+        var link = lookup.node;
+        if (!link.node_ops.readlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        return link.node_ops.readlink(link);
+      },stat:function (path, dontFollow) {
+        var lookup = FS.lookupPath(path, { follow: !dontFollow });
+        var node = lookup.node;
+        if (!node.node_ops.getattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return node.node_ops.getattr(node);
+      },lstat:function (path) {
+        return FS.stat(path, true);
+      },chmod:function (path, mode, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          mode: (mode & 4095) | (node.mode & ~4095),
+          timestamp: Date.now()
+        });
+      },lchmod:function (path, mode) {
+        FS.chmod(path, mode, true);
+      },fchmod:function (fd, mode) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chmod(stream.node, mode);
+      },chown:function (path, uid, gid, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          timestamp: Date.now()
+          // we ignore the uid / gid for now
+        });
+      },lchown:function (path, uid, gid) {
+        FS.chown(path, uid, gid, true);
+      },fchown:function (fd, uid, gid) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chown(stream.node, uid, gid);
+      },truncate:function (path, len) {
+        if (len < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: true });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!FS.isFile(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var err = FS.nodePermissions(node, 'w');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        node.node_ops.setattr(node, {
+          size: len,
+          timestamp: Date.now()
+        });
+      },ftruncate:function (fd, len) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        FS.truncate(stream.node, len);
+      },utime:function (path, atime, mtime) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        node.node_ops.setattr(node, {
+          timestamp: Math.max(atime, mtime)
+        });
+      },open:function (path, flags, mode, fd_start, fd_end) {
+        flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
+        mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
+        if ((flags & 64)) {
+          mode = (mode & 4095) | 32768;
+        } else {
+          mode = 0;
+        }
+        var node;
+        if (typeof path === 'object') {
+          node = path;
+        } else {
+          path = PATH.normalize(path);
+          try {
+            var lookup = FS.lookupPath(path, {
+              follow: !(flags & 131072)
+            });
+            node = lookup.node;
+          } catch (e) {
+            // ignore
+          }
+        }
+        // perhaps we need to create the node
+        if ((flags & 64)) {
+          if (node) {
+            // if O_CREAT and O_EXCL are set, error out if the node already exists
+            if ((flags & 128)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EEXIST);
+            }
+          } else {
+            // node doesn't exist, try to create it
+            node = FS.mknod(path, mode, 0);
+          }
+        }
+        if (!node) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
+        }
+        // can't truncate a device
+        if (FS.isChrdev(node.mode)) {
+          flags &= ~512;
+        }
+        // check permissions
+        var err = FS.mayOpen(node, flags);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // do truncation if necessary
+        if ((flags & 512)) {
+          FS.truncate(node, 0);
+        }
+        // we've already handled these, don't pass down to the underlying vfs
+        flags &= ~(128 | 512);
+
+        // register the stream with the filesystem
+        var stream = FS.createStream({
+          node: node,
+          path: FS.getPath(node),  // we want the absolute path to the node
+          flags: flags,
+          seekable: true,
+          position: 0,
+          stream_ops: node.stream_ops,
+          // used by the file family libc calls (fopen, fwrite, ferror, etc.)
+          ungotten: [],
+          error: false
+        }, fd_start, fd_end);
+        // call the new stream's open function
+        if (stream.stream_ops.open) {
+          stream.stream_ops.open(stream);
+        }
+        if (Module['logReadFiles'] && !(flags & 1)) {
+          if (!FS.readFiles) FS.readFiles = {};
+          if (!(path in FS.readFiles)) {
+            FS.readFiles[path] = 1;
+            Module['printErr']('read file: ' + path);
+          }
+        }
+        return stream;
+      },close:function (stream) {
+        try {
+          if (stream.stream_ops.close) {
+            stream.stream_ops.close(stream);
+          }
+        } catch (e) {
+          throw e;
+        } finally {
+          FS.closeStream(stream.fd);
+        }
+      },llseek:function (stream, offset, whence) {
+        if (!stream.seekable || !stream.stream_ops.llseek) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        return stream.stream_ops.llseek(stream, offset, whence);
+      },read:function (stream, buffer, offset, length, position) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.read) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
+        if (!seeking) stream.position += bytesRead;
+        return bytesRead;
+      },write:function (stream, buffer, offset, length, position, canOwn) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.write) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        if (stream.flags & 1024) {
+          // seek to the end before writing in append mode
+          FS.llseek(stream, 0, 2);
+        }
+        var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
+        if (!seeking) stream.position += bytesWritten;
+        return bytesWritten;
+      },allocate:function (stream, offset, length) {
+        if (offset < 0 || length <= 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        if (!stream.stream_ops.allocate) {
+          throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+        }
+        stream.stream_ops.allocate(stream, offset, length);
+      },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+        // TODO if PROT is PROT_WRITE, make sure we have write access
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EACCES);
+        }
+        if (!stream.stream_ops.mmap) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
+      },ioctl:function (stream, cmd, arg) {
+        if (!stream.stream_ops.ioctl) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTTY);
+        }
+        return stream.stream_ops.ioctl(stream, cmd, arg);
+      },readFile:function (path, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'r';
+        opts.encoding = opts.encoding || 'binary';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var ret;
+        var stream = FS.open(path, opts.flags);
+        var stat = FS.stat(path);
+        var length = stat.size;
+        var buf = new Uint8Array(length);
+        FS.read(stream, buf, 0, length, 0);
+        if (opts.encoding === 'utf8') {
+          ret = '';
+          var utf8 = new Runtime.UTF8Processor();
+          for (var i = 0; i < length; i++) {
+            ret += utf8.processCChar(buf[i]);
+          }
+        } else if (opts.encoding === 'binary') {
+          ret = buf;
+        }
+        FS.close(stream);
+        return ret;
+      },writeFile:function (path, data, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'w';
+        opts.encoding = opts.encoding || 'utf8';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var stream = FS.open(path, opts.flags, opts.mode);
+        if (opts.encoding === 'utf8') {
+          var utf8 = new Runtime.UTF8Processor();
+          var buf = new Uint8Array(utf8.processJSString(data));
+          FS.write(stream, buf, 0, buf.length, 0, opts.canOwn);
+        } else if (opts.encoding === 'binary') {
+          FS.write(stream, data, 0, data.length, 0, opts.canOwn);
+        }
+        FS.close(stream);
+      },cwd:function () {
+        return FS.currentPath;
+      },chdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        if (!FS.isDir(lookup.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        var err = FS.nodePermissions(lookup.node, 'x');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        FS.currentPath = lookup.path;
+      },createDefaultDirectories:function () {
+        FS.mkdir('/tmp');
+      },createDefaultDevices:function () {
+        // create /dev
+        FS.mkdir('/dev');
+        // setup /dev/null
+        FS.registerDevice(FS.makedev(1, 3), {
+          read: function() { return 0; },
+          write: function() { return 0; }
+        });
+        FS.mkdev('/dev/null', FS.makedev(1, 3));
+        // setup /dev/tty and /dev/tty1
+        // stderr needs to print output using Module['printErr']
+        // so we register a second tty just for it.
+        TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
+        TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
+        FS.mkdev('/dev/tty', FS.makedev(5, 0));
+        FS.mkdev('/dev/tty1', FS.makedev(6, 0));
+        // we're not going to emulate the actual shm device,
+        // just create the tmp dirs that reside in it commonly
+        FS.mkdir('/dev/shm');
+        FS.mkdir('/dev/shm/tmp');
+      },createStandardStreams:function () {
+        // TODO deprecate the old functionality of a single
+        // input / output callback and that utilizes FS.createDevice
+        // and instead require a unique set of stream ops
+
+        // by default, we symlink the standard streams to the
+        // default tty devices. however, if the standard streams
+        // have been overwritten we create a unique device for
+        // them instead.
+        if (Module['stdin']) {
+          FS.createDevice('/dev', 'stdin', Module['stdin']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdin');
+        }
+        if (Module['stdout']) {
+          FS.createDevice('/dev', 'stdout', null, Module['stdout']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdout');
+        }
+        if (Module['stderr']) {
+          FS.createDevice('/dev', 'stderr', null, Module['stderr']);
+        } else {
+          FS.symlink('/dev/tty1', '/dev/stderr');
+        }
+
+        // open default streams for the stdin, stdout and stderr devices
+        var stdin = FS.open('/dev/stdin', 'r');
+        HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin);
+        assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
+
+        var stdout = FS.open('/dev/stdout', 'w');
+        HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout);
+        assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
+
+        var stderr = FS.open('/dev/stderr', 'w');
+        HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr);
+        assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
+      },ensureErrnoError:function () {
+        if (FS.ErrnoError) return;
+        FS.ErrnoError = function ErrnoError(errno) {
+          this.errno = errno;
+          for (var key in ERRNO_CODES) {
+            if (ERRNO_CODES[key] === errno) {
+              this.code = key;
+              break;
+            }
+          }
+          this.message = ERRNO_MESSAGES[errno];
+        };
+        FS.ErrnoError.prototype = new Error();
+        FS.ErrnoError.prototype.constructor = FS.ErrnoError;
+        // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
+        [ERRNO_CODES.ENOENT].forEach(function(code) {
+          FS.genericErrors[code] = new FS.ErrnoError(code);
+          FS.genericErrors[code].stack = '<generic error, no stack>';
+        });
+      },staticInit:function () {
+        FS.ensureErrnoError();
+
+        FS.nameTable = new Array(4096);
+
+        FS.mount(MEMFS, {}, '/');
+
+        FS.createDefaultDirectories();
+        FS.createDefaultDevices();
+      },init:function (input, output, error) {
+        assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
+        FS.init.initialized = true;
+
+        FS.ensureErrnoError();
+
+        // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
+        Module['stdin'] = input || Module['stdin'];
+        Module['stdout'] = output || Module['stdout'];
+        Module['stderr'] = error || Module['stderr'];
+
+        FS.createStandardStreams();
+      },quit:function () {
+        FS.init.initialized = false;
+        for (var i = 0; i < FS.streams.length; i++) {
+          var stream = FS.streams[i];
+          if (!stream) {
+            continue;
+          }
+          FS.close(stream);
+        }
+      },getMode:function (canRead, canWrite) {
+        var mode = 0;
+        if (canRead) mode |= 292 | 73;
+        if (canWrite) mode |= 146;
+        return mode;
+      },joinPath:function (parts, forceRelative) {
+        var path = PATH.join.apply(null, parts);
+        if (forceRelative && path[0] == '/') path = path.substr(1);
+        return path;
+      },absolutePath:function (relative, base) {
+        return PATH.resolve(base, relative);
+      },standardizePath:function (path) {
+        return PATH.normalize(path);
+      },findObject:function (path, dontResolveLastLink) {
+        var ret = FS.analyzePath(path, dontResolveLastLink);
+        if (ret.exists) {
+          return ret.object;
+        } else {
+          ___setErrNo(ret.error);
+          return null;
+        }
+      },analyzePath:function (path, dontResolveLastLink) {
+        // operate from within the context of the symlink's target
+        try {
+          var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          path = lookup.path;
+        } catch (e) {
+        }
+        var ret = {
+          isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
+          parentExists: false, parentPath: null, parentObject: null
+        };
+        try {
+          var lookup = FS.lookupPath(path, { parent: true });
+          ret.parentExists = true;
+          ret.parentPath = lookup.path;
+          ret.parentObject = lookup.node;
+          ret.name = PATH.basename(path);
+          lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          ret.exists = true;
+          ret.path = lookup.path;
+          ret.object = lookup.node;
+          ret.name = lookup.node.name;
+          ret.isRoot = lookup.path === '/';
+        } catch (e) {
+          ret.error = e.errno;
+        };
+        return ret;
+      },createFolder:function (parent, name, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.mkdir(path, mode);
+      },createPath:function (parent, path, canRead, canWrite) {
+        parent = typeof parent === 'string' ? parent : FS.getPath(parent);
+        var parts = path.split('/').reverse();
+        while (parts.length) {
+          var part = parts.pop();
+          if (!part) continue;
+          var current = PATH.join2(parent, part);
+          try {
+            FS.mkdir(current);
+          } catch (e) {
+            // ignore EEXIST
+          }
+          parent = current;
+        }
+        return current;
+      },createFile:function (parent, name, properties, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.create(path, mode);
+      },createDataFile:function (parent, name, data, canRead, canWrite, canOwn) {
+        var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
+        var mode = FS.getMode(canRead, canWrite);
+        var node = FS.create(path, mode);
+        if (data) {
+          if (typeof data === 'string') {
+            var arr = new Array(data.length);
+            for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
+            data = arr;
+          }
+          // make sure we can write to the file
+          FS.chmod(node, mode | 146);
+          var stream = FS.open(node, 'w');
+          FS.write(stream, data, 0, data.length, 0, canOwn);
+          FS.close(stream);
+          FS.chmod(node, mode);
+        }
+        return node;
+      },createDevice:function (parent, name, input, output) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(!!input, !!output);
+        if (!FS.createDevice.major) FS.createDevice.major = 64;
+        var dev = FS.makedev(FS.createDevice.major++, 0);
+        // Create a fake device that a set of stream ops to emulate
+        // the old behavior.
+        FS.registerDevice(dev, {
+          open: function(stream) {
+            stream.seekable = false;
+          },
+          close: function(stream) {
+            // flush any pending line data
+            if (output && output.buffer && output.buffer.length) {
+              output(10);
+            }
+          },
+          read: function(stream, buffer, offset, length, pos /* ignored */) {
+            var bytesRead = 0;
+            for (var i = 0; i < length; i++) {
+              var result;
+              try {
+                result = input();
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+              if (result === undefined && bytesRead === 0) {
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+              if (result === null || result === undefined) break;
+              bytesRead++;
+              buffer[offset+i] = result;
+            }
+            if (bytesRead) {
+              stream.node.timestamp = Date.now();
+            }
+            return bytesRead;
+          },
+          write: function(stream, buffer, offset, length, pos) {
+            for (var i = 0; i < length; i++) {
+              try {
+                output(buffer[offset+i]);
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+            }
+            if (length) {
+              stream.node.timestamp = Date.now();
+            }
+            return i;
+          }
+        });
+        return FS.mkdev(path, mode, dev);
+      },createLink:function (parent, name, target, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        return FS.symlink(target, path);
+      },forceLoadFile:function (obj) {
+        if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
+        var success = true;
+        if (typeof XMLHttpRequest !== 'undefined') {
+          throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
+        } else if (Module['read']) {
+          // Command-line.
+          try {
+            // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
+            //          read() will try to parse UTF8.
+            obj.contents = intArrayFromString(Module['read'](obj.url), true);
+          } catch (e) {
+            success = false;
+          }
+        } else {
+          throw new Error('Cannot load without read() or XMLHttpRequest.');
+        }
+        if (!success) ___setErrNo(ERRNO_CODES.EIO);
+        return success;
+      },createLazyFile:function (parent, name, url, canRead, canWrite) {
+        // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
+        function LazyUint8Array() {
+          this.lengthKnown = false;
+          this.chunks = []; // Loaded chunks. Index is the chunk number
+        }
+        LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
+          if (idx > this.length-1 || idx < 0) {
+            return undefined;
+          }
+          var chunkOffset = idx % this.chunkSize;
+          var chunkNum = Math.floor(idx / this.chunkSize);
+          return this.getter(chunkNum)[chunkOffset];
+        }
+        LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
+          this.getter = getter;
+        }
+        LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
+            // Find length
+            var xhr = new XMLHttpRequest();
+            xhr.open('HEAD', url, false);
+            xhr.send(null);
+            if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+            var datalength = Number(xhr.getResponseHeader("Content-length"));
+            var header;
+            var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
+            var chunkSize = 1024*1024; // Chunk size in bytes
+
+            if (!hasByteServing) chunkSize = datalength;
+
+            // Function to get a range from the remote URL.
+            var doXHR = (function(from, to) {
+              if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
+              if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
+
+              // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
+              var xhr = new XMLHttpRequest();
+              xhr.open('GET', url, false);
+              if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
+
+              // Some hints to the browser that we want binary data.
+              if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
+              if (xhr.overrideMimeType) {
+                xhr.overrideMimeType('text/plain; charset=x-user-defined');
+              }
+
+              xhr.send(null);
+              if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+              if (xhr.response !== undefined) {
+                return new Uint8Array(xhr.response || []);
+              } else {
+                return intArrayFromString(xhr.responseText || '', true);
+              }
+            });
+            var lazyArray = this;
+            lazyArray.setDataGetter(function(chunkNum) {
+              var start = chunkNum * chunkSize;
+              var end = (chunkNum+1) * chunkSize - 1; // including this byte
+              end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
+                lazyArray.chunks[chunkNum] = doXHR(start, end);
+              }
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
+              return lazyArray.chunks[chunkNum];
+            });
+
+            this._length = datalength;
+            this._chunkSize = chunkSize;
+            this.lengthKnown = true;
+        }
+        if (typeof XMLHttpRequest !== 'undefined') {
+          if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
+          var lazyArray = new LazyUint8Array();
+          Object.defineProperty(lazyArray, "length", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._length;
+              }
+          });
+          Object.defineProperty(lazyArray, "chunkSize", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._chunkSize;
+              }
+          });
+
+          var properties = { isDevice: false, contents: lazyArray };
+        } else {
+          var properties = { isDevice: false, url: url };
+        }
+
+        var node = FS.createFile(parent, name, properties, canRead, canWrite);
+        // This is a total hack, but I want to get this lazy file code out of the
+        // core of MEMFS. If we want to keep this lazy file concept I feel it should
+        // be its own thin LAZYFS proxying calls to MEMFS.
+        if (properties.contents) {
+          node.contents = properties.contents;
+        } else if (properties.url) {
+          node.contents = null;
+          node.url = properties.url;
+        }
+        // override each stream op with one that tries to force load the lazy file first
+        var stream_ops = {};
+        var keys = Object.keys(node.stream_ops);
+        keys.forEach(function(key) {
+          var fn = node.stream_ops[key];
+          stream_ops[key] = function forceLoadLazyFile() {
+            if (!FS.forceLoadFile(node)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            return fn.apply(null, arguments);
+          };
+        });
+        // use a custom read function
+        stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
+          if (!FS.forceLoadFile(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EIO);
+          }
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (contents.slice) { // normal array
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          } else {
+            for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
+              buffer[offset + i] = contents.get(position + i);
+            }
+          }
+          return size;
+        };
+        node.stream_ops = stream_ops;
+        return node;
+      },createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
+        Browser.init();
+        // TODO we should allow people to just pass in a complete filename instead
+        // of parent and name being that we just join them anyways
+        var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent;
+        function processData(byteArray) {
+          function finish(byteArray) {
+            if (!dontCreateFile) {
+              FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
+            }
+            if (onload) onload();
+            removeRunDependency('cp ' + fullname);
+          }
+          var handled = false;
+          Module['preloadPlugins'].forEach(function(plugin) {
+            if (handled) return;
+            if (plugin['canHandle'](fullname)) {
+              plugin['handle'](byteArray, fullname, finish, function() {
+                if (onerror) onerror();
+                removeRunDependency('cp ' + fullname);
+              });
+              handled = true;
+            }
+          });
+          if (!handled) finish(byteArray);
+        }
+        addRunDependency('cp ' + fullname);
+        if (typeof url == 'string') {
+          Browser.asyncLoad(url, function(byteArray) {
+            processData(byteArray);
+          }, onerror);
+        } else {
+          processData(url);
+        }
+      },indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_NAME:function () {
+        return 'EM_FS_' + window.location.pathname;
+      },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
+          console.log('creating db');
+          var db = openRequest.result;
+          db.createObjectStore(FS.DB_STORE_NAME);
+        };
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var putRequest = files.put(FS.analyzePath(path).object.contents, path);
+            putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
+            putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      },loadFilesFromDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = onerror; // no database to load from
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          try {
+            var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
+          } catch(e) {
+            onerror(e);
+            return;
+          }
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var getRequest = files.get(path);
+            getRequest.onsuccess = function getRequest_onsuccess() {
+              if (FS.analyzePath(path).exists) {
+                FS.unlink(path);
+              }
+              FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
+              ok++;
+              if (ok + fail == total) finish();
+            };
+            getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      }};
+
+
+
+
+  function _mkport() { throw 'TODO' }var SOCKFS={mount:function (mount) {
+        return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createSocket:function (family, type, protocol) {
+        var streaming = type == 1;
+        if (protocol) {
+          assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp
+        }
+
+        // create our internal socket structure
+        var sock = {
+          family: family,
+          type: type,
+          protocol: protocol,
+          server: null,
+          peers: {},
+          pending: [],
+          recv_queue: [],
+          sock_ops: SOCKFS.websocket_sock_ops
+        };
+
+        // create the filesystem node to store the socket structure
+        var name = SOCKFS.nextname();
+        var node = FS.createNode(SOCKFS.root, name, 49152, 0);
+        node.sock = sock;
+
+        // and the wrapping stream that enables library functions such
+        // as read and write to indirectly interact with the socket
+        var stream = FS.createStream({
+          path: name,
+          node: node,
+          flags: FS.modeStringToFlags('r+'),
+          seekable: false,
+          stream_ops: SOCKFS.stream_ops
+        });
+
+        // map the new stream to the socket structure (sockets have a 1:1
+        // relationship with a stream)
+        sock.stream = stream;
+
+        return sock;
+      },getSocket:function (fd) {
+        var stream = FS.getStream(fd);
+        if (!stream || !FS.isSocket(stream.node.mode)) {
+          return null;
+        }
+        return stream.node.sock;
+      },stream_ops:{poll:function (stream) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.poll(sock);
+        },ioctl:function (stream, request, varargs) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.ioctl(sock, request, varargs);
+        },read:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          var msg = sock.sock_ops.recvmsg(sock, length);
+          if (!msg) {
+            // socket is closed
+            return 0;
+          }
+          buffer.set(msg.buffer, offset);
+          return msg.buffer.length;
+        },write:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.sendmsg(sock, buffer, offset, length);
+        },close:function (stream) {
+          var sock = stream.node.sock;
+          sock.sock_ops.close(sock);
+        }},nextname:function () {
+        if (!SOCKFS.nextname.current) {
+          SOCKFS.nextname.current = 0;
+        }
+        return 'socket[' + (SOCKFS.nextname.current++) + ']';
+      },websocket_sock_ops:{createPeer:function (sock, addr, port) {
+          var ws;
+
+          if (typeof addr === 'object') {
+            ws = addr;
+            addr = null;
+            port = null;
+          }
+
+          if (ws) {
+            // for sockets that've already connected (e.g. we're the server)
+            // we can inspect the _socket property for the address
+            if (ws._socket) {
+              addr = ws._socket.remoteAddress;
+              port = ws._socket.remotePort;
+            }
+            // if we're just now initializing a connection to the remote,
+            // inspect the url property
+            else {
+              var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
+              if (!result) {
+                throw new Error('WebSocket URL must be in the format ws(s)://address:port');
+              }
+              addr = result[1];
+              port = parseInt(result[2], 10);
+            }
+          } else {
+            // create the actual websocket object and connect
+            try {
+              // runtimeConfig gets set to true if WebSocket runtime configuration is available.
+              var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
+
+              // The default value is 'ws://' the replace is needed because the compiler replaces "//" comments with '#'
+              // comments without checking context, so we'd end up with ws:#, the replace swaps the "#" for "//" again.
+              var url = 'ws:#'.replace('#', '//');
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['url']) {
+                  url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
+                }
+              }
+
+              if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
+                url = url + addr + ':' + port;
+              }
+
+              // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
+              var subProtocols = 'binary'; // The default value is 'binary'
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['subprotocol']) {
+                  subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
+                }
+              }
+
+              // The regex trims the string (removes spaces at the beginning and end, then splits the string by
+              // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
+              subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
+
+              // The node ws library API for specifying optional subprotocol is slightly different than the browser's.
+              var opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols;
+
+              // If node we use the ws library.
+              var WebSocket = ENVIRONMENT_IS_NODE ? require('ws') : window['WebSocket'];
+              ws = new WebSocket(url, opts);
+              ws.binaryType = 'arraybuffer';
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH);
+            }
+          }
+
+
+          var peer = {
+            addr: addr,
+            port: port,
+            socket: ws,
+            dgram_send_queue: []
+          };
+
+          SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+          SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
+
+          // if this is a bound dgram socket, send the port number first to allow
+          // us to override the ephemeral port reported to us by remotePort on the
+          // remote end.
+          if (sock.type === 2 && typeof sock.sport !== 'undefined') {
+            peer.dgram_send_queue.push(new Uint8Array([
+                255, 255, 255, 255,
+                'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
+                ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
+            ]));
+          }
+
+          return peer;
+        },getPeer:function (sock, addr, port) {
+          return sock.peers[addr + ':' + port];
+        },addPeer:function (sock, peer) {
+          sock.peers[peer.addr + ':' + peer.port] = peer;
+        },removePeer:function (sock, peer) {
+          delete sock.peers[peer.addr + ':' + peer.port];
+        },handlePeerEvents:function (sock, peer) {
+          var first = true;
+
+          var handleOpen = function () {
+            try {
+              var queued = peer.dgram_send_queue.shift();
+              while (queued) {
+                peer.socket.send(queued);
+                queued = peer.dgram_send_queue.shift();
+              }
+            } catch (e) {
+              // not much we can do here in the way of proper error handling as we've already
+              // lied and said this data was sent. shut it down.
+              peer.socket.close();
+            }
+          };
+
+          function handleMessage(data) {
+            assert(typeof data !== 'string' && data.byteLength !== undefined);  // must receive an ArrayBuffer
+            data = new Uint8Array(data);  // make a typed array view on the array buffer
+
+
+            // if this is the port message, override the peer's port with it
+            var wasfirst = first;
+            first = false;
+            if (wasfirst &&
+                data.length === 10 &&
+                data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
+                data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
+              // update the peer's port and it's key in the peer map
+              var newport = ((data[8] << 8) | data[9]);
+              SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+              peer.port = newport;
+              SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+              return;
+            }
+
+            sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
+          };
+
+          if (ENVIRONMENT_IS_NODE) {
+            peer.socket.on('open', handleOpen);
+            peer.socket.on('message', function(data, flags) {
+              if (!flags.binary) {
+                return;
+              }
+              handleMessage((new Uint8Array(data)).buffer);  // copy from node Buffer -> ArrayBuffer
+            });
+            peer.socket.on('error', function() {
+              // don't throw
+            });
+          } else {
+            peer.socket.onopen = handleOpen;
+            peer.socket.onmessage = function peer_socket_onmessage(event) {
+              handleMessage(event.data);
+            };
+          }
+        },poll:function (sock) {
+          if (sock.type === 1 && sock.server) {
+            // listen sockets should only say they're available for reading
+            // if there are pending clients.
+            return sock.pending.length ? (64 | 1) : 0;
+          }
+
+          var mask = 0;
+          var dest = sock.type === 1 ?  // we only care about the socket state for connection-based sockets
+            SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
+            null;
+
+          if (sock.recv_queue.length ||
+              !dest ||  // connection-less sockets are always ready to read
+              (dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {  // let recv return 0 once closed
+            mask |= (64 | 1);
+          }
+
+          if (!dest ||  // connection-less sockets are always ready to write
+              (dest && dest.socket.readyState === dest.socket.OPEN)) {
+            mask |= 4;
+          }
+
+          if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {
+            mask |= 16;
+          }
+
+          return mask;
+        },ioctl:function (sock, request, arg) {
+          switch (request) {
+            case 21531:
+              var bytes = 0;
+              if (sock.recv_queue.length) {
+                bytes = sock.recv_queue[0].data.length;
+              }
+              HEAP32[((arg)>>2)]=bytes;
+              return 0;
+            default:
+              return ERRNO_CODES.EINVAL;
+          }
+        },close:function (sock) {
+          // if we've spawned a listen server, close it
+          if (sock.server) {
+            try {
+              sock.server.close();
+            } catch (e) {
+            }
+            sock.server = null;
+          }
+          // close any peer connections
+          var peers = Object.keys(sock.peers);
+          for (var i = 0; i < peers.length; i++) {
+            var peer = sock.peers[peers[i]];
+            try {
+              peer.socket.close();
+            } catch (e) {
+            }
+            SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+          }
+          return 0;
+        },bind:function (sock, addr, port) {
+          if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already bound
+          }
+          sock.saddr = addr;
+          sock.sport = port || _mkport();
+          // in order to emulate dgram sockets, we need to launch a listen server when
+          // binding on a connection-less socket
+          // note: this is only required on the server side
+          if (sock.type === 2) {
+            // close the existing server if it exists
+            if (sock.server) {
+              sock.server.close();
+              sock.server = null;
+            }
+            // swallow error operation not supported error that occurs when binding in the
+            // browser where this isn't supported
+            try {
+              sock.sock_ops.listen(sock, 0);
+            } catch (e) {
+              if (!(e instanceof FS.ErrnoError)) throw e;
+              if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e;
+            }
+          }
+        },connect:function (sock, addr, port) {
+          if (sock.server) {
+            throw new FS.ErrnoError(ERRNO_CODS.EOPNOTSUPP);
+          }
+
+          // TODO autobind
+          // if (!sock.addr && sock.type == 2) {
+          // }
+
+          // early out if we're already connected / in the middle of connecting
+          if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') {
+            var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+            if (dest) {
+              if (dest.socket.readyState === dest.socket.CONNECTING) {
+                throw new FS.ErrnoError(ERRNO_CODES.EALREADY);
+              } else {
+                throw new FS.ErrnoError(ERRNO_CODES.EISCONN);
+              }
+            }
+          }
+
+          // add the socket to our peer list and set our
+          // destination address / port to match
+          var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+          sock.daddr = peer.addr;
+          sock.dport = peer.port;
+
+          // always "fail" in non-blocking mode
+          throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS);
+        },listen:function (sock, backlog) {
+          if (!ENVIRONMENT_IS_NODE) {
+            throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+          }
+          if (sock.server) {
+             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already listening
+          }
+          var WebSocketServer = require('ws').Server;
+          var host = sock.saddr;
+          sock.server = new WebSocketServer({
+            host: host,
+            port: sock.sport
+            // TODO support backlog
+          });
+
+          sock.server.on('connection', function(ws) {
+            if (sock.type === 1) {
+              var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
+
+              // create a peer on the new socket
+              var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
+              newsock.daddr = peer.addr;
+              newsock.dport = peer.port;
+
+              // push to queue for accept to pick up
+              sock.pending.push(newsock);
+            } else {
+              // create a peer on the listen socket so calling sendto
+              // with the listen socket and an address will resolve
+              // to the correct client
+              SOCKFS.websocket_sock_ops.createPeer(sock, ws);
+            }
+          });
+          sock.server.on('closed', function() {
+            sock.server = null;
+          });
+          sock.server.on('error', function() {
+            // don't throw
+          });
+        },accept:function (listensock) {
+          if (!listensock.server) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          var newsock = listensock.pending.shift();
+          newsock.stream.flags = listensock.stream.flags;
+          return newsock;
+        },getname:function (sock, peer) {
+          var addr, port;
+          if (peer) {
+            if (sock.daddr === undefined || sock.dport === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            }
+            addr = sock.daddr;
+            port = sock.dport;
+          } else {
+            // TODO saddr and sport will be set for bind()'d UDP sockets, but what
+            // should we be returning for TCP sockets that've been connect()'d?
+            addr = sock.saddr || 0;
+            port = sock.sport || 0;
+          }
+          return { addr: addr, port: port };
+        },sendmsg:function (sock, buffer, offset, length, addr, port) {
+          if (sock.type === 2) {
+            // connection-less sockets will honor the message address,
+            // and otherwise fall back to the bound destination address
+            if (addr === undefined || port === undefined) {
+              addr = sock.daddr;
+              port = sock.dport;
+            }
+            // if there was no address to fall back to, error out
+            if (addr === undefined || port === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ);
+            }
+          } else {
+            // connection-based sockets will only use the bound
+            addr = sock.daddr;
+            port = sock.dport;
+          }
+
+          // find the peer for the destination address
+          var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
+
+          // early out if not connected with a connection-based socket
+          if (sock.type === 1) {
+            if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            } else if (dest.socket.readyState === dest.socket.CONNECTING) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // create a copy of the incoming data to send, as the WebSocket API
+          // doesn't work entirely with an ArrayBufferView, it'll just send
+          // the entire underlying buffer
+          var data;
+          if (buffer instanceof Array || buffer instanceof ArrayBuffer) {
+            data = buffer.slice(offset, offset + length);
+          } else {  // ArrayBufferView
+            data = buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + length);
+          }
+
+          // if we're emulating a connection-less dgram socket and don't have
+          // a cached connection, queue the buffer to send upon connect and
+          // lie, saying the data was sent now.
+          if (sock.type === 2) {
+            if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
+              // if we're not connected, open a new connection
+              if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+              }
+              dest.dgram_send_queue.push(data);
+              return length;
+            }
+          }
+
+          try {
+            // send the actual data
+            dest.socket.send(data);
+            return length;
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+        },recvmsg:function (sock, length) {
+          // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
+          if (sock.type === 1 && sock.server) {
+            // tcp servers should not be recv()'ing on the listen socket
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+          }
+
+          var queued = sock.recv_queue.shift();
+          if (!queued) {
+            if (sock.type === 1) {
+              var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+
+              if (!dest) {
+                // if we have a destination address but are not connected, error out
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+              }
+              else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                // return null if the socket has closed
+                return null;
+              }
+              else {
+                // else, our socket is in a valid state but truly has nothing available
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+            } else {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
+          // requeued TCP data it'll be an ArrayBufferView
+          var queuedLength = queued.data.byteLength || queued.data.length;
+          var queuedOffset = queued.data.byteOffset || 0;
+          var queuedBuffer = queued.data.buffer || queued.data;
+          var bytesRead = Math.min(length, queuedLength);
+          var res = {
+            buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
+            addr: queued.addr,
+            port: queued.port
+          };
+
+
+          // push back any unread data for TCP connections
+          if (sock.type === 1 && bytesRead < queuedLength) {
+            var bytesRemaining = queuedLength - bytesRead;
+            queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
+            sock.recv_queue.unshift(queued);
+          }
+
+          return res;
+        }}};function _send(fd, buf, len, flags) {
+      var sock = SOCKFS.getSocket(fd);
+      if (!sock) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      // TODO honor flags
+      return _write(fd, buf, len);
+    }
+
+  function _pwrite(fildes, buf, nbyte, offset) {
+      // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte, offset);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _write(fildes, buf, nbyte) {
+      // ssize_t write(int fildes, const void *buf, size_t nbyte);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+
+
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }
+
+  function _fileno(stream) {
+      // int fileno(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
+      stream = FS.getStreamFromPtr(stream);
+      if (!stream) return -1;
+      return stream.fd;
+    }function _fwrite(ptr, size, nitems, stream) {
+      // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
+      var bytesToWrite = nitems * size;
+      if (bytesToWrite == 0) return 0;
+      var fd = _fileno(stream);
+      var bytesWritten = _write(fd, ptr, bytesToWrite);
+      if (bytesWritten == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return 0;
+      } else {
+        return Math.floor(bytesWritten / size);
+      }
+    }
+
+
+
+  Module["_strlen"] = _strlen;
+
+  function __reallyNegative(x) {
+      return x < 0 || (x === 0 && (1/x) === -Infinity);
+    }function __formatString(format, varargs) {
+      var textIndex = format;
+      var argIndex = 0;
+      function getNextArg(type) {
+        // NOTE: Explicitly ignoring type safety. Otherwise this fails:
+        //       int x = 4; printf("%c\n", (char)x);
+        var ret;
+        if (type === 'double') {
+          ret = HEAPF64[(((varargs)+(argIndex))>>3)];
+        } else if (type == 'i64') {
+          ret = [HEAP32[(((varargs)+(argIndex))>>2)],
+                 HEAP32[(((varargs)+(argIndex+4))>>2)]];
+
+        } else {
+          type = 'i32'; // varargs are always i32, i64, or double
+          ret = HEAP32[(((varargs)+(argIndex))>>2)];
+        }
+        argIndex += Runtime.getNativeFieldSize(type);
+        return ret;
+      }
+
+      var ret = [];
+      var curr, next, currArg;
+      while(1) {
+        var startTextIndex = textIndex;
+        curr = HEAP8[(textIndex)];
+        if (curr === 0) break;
+        next = HEAP8[((textIndex+1)|0)];
+        if (curr == 37) {
+          // Handle flags.
+          var flagAlwaysSigned = false;
+          var flagLeftAlign = false;
+          var flagAlternative = false;
+          var flagZeroPad = false;
+          var flagPadSign = false;
+          flagsLoop: while (1) {
+            switch (next) {
+              case 43:
+                flagAlwaysSigned = true;
+                break;
+              case 45:
+                flagLeftAlign = true;
+                break;
+              case 35:
+                flagAlternative = true;
+                break;
+              case 48:
+                if (flagZeroPad) {
+                  break flagsLoop;
+                } else {
+                  flagZeroPad = true;
+                  break;
+                }
+              case 32:
+                flagPadSign = true;
+                break;
+              default:
+                break flagsLoop;
+            }
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          }
+
+          // Handle width.
+          var width = 0;
+          if (next == 42) {
+            width = getNextArg('i32');
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          } else {
+            while (next >= 48 && next <= 57) {
+              width = width * 10 + (next - 48);
+              textIndex++;
+              next = HEAP8[((textIndex+1)|0)];
+            }
+          }
+
+          // Handle precision.
+          var precisionSet = false, precision = -1;
+          if (next == 46) {
+            precision = 0;
+            precisionSet = true;
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+            if (next == 42) {
+              precision = getNextArg('i32');
+              textIndex++;
+            } else {
+              while(1) {
+                var precisionChr = HEAP8[((textIndex+1)|0)];
+                if (precisionChr < 48 ||
+                    precisionChr > 57) break;
+                precision = precision * 10 + (precisionChr - 48);
+                textIndex++;
+              }
+            }
+            next = HEAP8[((textIndex+1)|0)];
+          }
+          if (precision < 0) {
+            precision = 6; // Standard default.
+            precisionSet = false;
+          }
+
+          // Handle integer sizes. WARNING: These assume a 32-bit architecture!
+          var argSize;
+          switch (String.fromCharCode(next)) {
+            case 'h':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 104) {
+                textIndex++;
+                argSize = 1; // char (actually i32 in varargs)
+              } else {
+                argSize = 2; // short (actually i32 in varargs)
+              }
+              break;
+            case 'l':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 108) {
+                textIndex++;
+                argSize = 8; // long long
+              } else {
+                argSize = 4; // long
+              }
+              break;
+            case 'L': // long long
+            case 'q': // int64_t
+            case 'j': // intmax_t
+              argSize = 8;
+              break;
+            case 'z': // size_t
+            case 't': // ptrdiff_t
+            case 'I': // signed ptrdiff_t or unsigned size_t
+              argSize = 4;
+              break;
+            default:
+              argSize = null;
+          }
+          if (argSize) textIndex++;
+          next = HEAP8[((textIndex+1)|0)];
+
+          // Handle type specifier.
+          switch (String.fromCharCode(next)) {
+            case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': {
+              // Integer.
+              var signed = next == 100 || next == 105;
+              argSize = argSize || 4;
+              var currArg = getNextArg('i' + (argSize * 8));
+              var argText;
+              // Flatten i64-1 [low, high] into a (slightly rounded) double
+              if (argSize == 8) {
+                currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117);
+              }
+              // Truncate to requested size.
+              if (argSize <= 4) {
+                var limit = Math.pow(256, argSize) - 1;
+                currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
+              }
+              // Format the number.
+              var currAbsArg = Math.abs(currArg);
+              var prefix = '';
+              if (next == 100 || next == 105) {
+                argText = reSign(currArg, 8 * argSize, 1).toString(10);
+              } else if (next == 117) {
+                argText = unSign(currArg, 8 * argSize, 1).toString(10);
+                currArg = Math.abs(currArg);
+              } else if (next == 111) {
+                argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
+              } else if (next == 120 || next == 88) {
+                prefix = (flagAlternative && currArg != 0) ? '0x' : '';
+                if (currArg < 0) {
+                  // Represent negative numbers in hex as 2's complement.
+                  currArg = -currArg;
+                  argText = (currAbsArg - 1).toString(16);
+                  var buffer = [];
+                  for (var i = 0; i < argText.length; i++) {
+                    buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
+                  }
+                  argText = buffer.join('');
+                  while (argText.length < argSize * 2) argText = 'f' + argText;
+                } else {
+                  argText = currAbsArg.toString(16);
+                }
+                if (next == 88) {
+                  prefix = prefix.toUpperCase();
+                  argText = argText.toUpperCase();
+                }
+              } else if (next == 112) {
+                if (currAbsArg === 0) {
+                  argText = '(nil)';
+                } else {
+                  prefix = '0x';
+                  argText = currAbsArg.toString(16);
+                }
+              }
+              if (precisionSet) {
+                while (argText.length < precision) {
+                  argText = '0' + argText;
+                }
+              }
+
+              // Add sign if needed
+              if (currArg >= 0) {
+                if (flagAlwaysSigned) {
+                  prefix = '+' + prefix;
+                } else if (flagPadSign) {
+                  prefix = ' ' + prefix;
+                }
+              }
+
+              // Move sign to prefix so we zero-pad after the sign
+              if (argText.charAt(0) == '-') {
+                prefix = '-' + prefix;
+                argText = argText.substr(1);
+              }
+
+              // Add padding.
+              while (prefix.length + argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad) {
+                    argText = '0' + argText;
+                  } else {
+                    prefix = ' ' + prefix;
+                  }
+                }
+              }
+
+              // Insert the result into the buffer.
+              argText = prefix + argText;
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': {
+              // Float.
+              var currArg = getNextArg('double');
+              var argText;
+              if (isNaN(currArg)) {
+                argText = 'nan';
+                flagZeroPad = false;
+              } else if (!isFinite(currArg)) {
+                argText = (currArg < 0 ? '-' : '') + 'inf';
+                flagZeroPad = false;
+              } else {
+                var isGeneral = false;
+                var effectivePrecision = Math.min(precision, 20);
+
+                // Convert g/G to f/F or e/E, as per:
+                // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
+                if (next == 103 || next == 71) {
+                  isGeneral = true;
+                  precision = precision || 1;
+                  var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
+                  if (precision > exponent && exponent >= -4) {
+                    next = ((next == 103) ? 'f' : 'F').charCodeAt(0);
+                    precision -= exponent + 1;
+                  } else {
+                    next = ((next == 103) ? 'e' : 'E').charCodeAt(0);
+                    precision--;
+                  }
+                  effectivePrecision = Math.min(precision, 20);
+                }
+
+                if (next == 101 || next == 69) {
+                  argText = currArg.toExponential(effectivePrecision);
+                  // Make sure the exponent has at least 2 digits.
+                  if (/[eE][-+]\d$/.test(argText)) {
+                    argText = argText.slice(0, -1) + '0' + argText.slice(-1);
+                  }
+                } else if (next == 102 || next == 70) {
+                  argText = currArg.toFixed(effectivePrecision);
+                  if (currArg === 0 && __reallyNegative(currArg)) {
+                    argText = '-' + argText;
+                  }
+                }
+
+                var parts = argText.split('e');
+                if (isGeneral && !flagAlternative) {
+                  // Discard trailing zeros and periods.
+                  while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
+                         (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
+                    parts[0] = parts[0].slice(0, -1);
+                  }
+                } else {
+                  // Make sure we have a period in alternative mode.
+                  if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
+                  // Zero pad until required precision.
+                  while (precision > effectivePrecision++) parts[0] += '0';
+                }
+                argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
+
+                // Capitalize 'E' if needed.
+                if (next == 69) argText = argText.toUpperCase();
+
+                // Add sign.
+                if (currArg >= 0) {
+                  if (flagAlwaysSigned) {
+                    argText = '+' + argText;
+                  } else if (flagPadSign) {
+                    argText = ' ' + argText;
+                  }
+                }
+              }
+
+              // Add padding.
+              while (argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
+                    argText = argText[0] + '0' + argText.slice(1);
+                  } else {
+                    argText = (flagZeroPad ? '0' : ' ') + argText;
+                  }
+                }
+              }
+
+              // Adjust case.
+              if (next < 97) argText = argText.toUpperCase();
+
+              // Insert the result into the buffer.
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 's': {
+              // String.
+              var arg = getNextArg('i8*');
+              var argLength = arg ? _strlen(arg) : '(null)'.length;
+              if (precisionSet) argLength = Math.min(argLength, precision);
+              if (!flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              if (arg) {
+                for (var i = 0; i < argLength; i++) {
+                  ret.push(HEAPU8[((arg++)|0)]);
+                }
+              } else {
+                ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true));
+              }
+              if (flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              break;
+            }
+            case 'c': {
+              // Character.
+              if (flagLeftAlign) ret.push(getNextArg('i8'));
+              while (--width > 0) {
+                ret.push(32);
+              }
+              if (!flagLeftAlign) ret.push(getNextArg('i8'));
+              break;
+            }
+            case 'n': {
+              // Write the length written so far to the next parameter.
+              var ptr = getNextArg('i32*');
+              HEAP32[((ptr)>>2)]=ret.length;
+              break;
+            }
+            case '%': {
+              // Literal percent sign.
+              ret.push(curr);
+              break;
+            }
+            default: {
+              // Unknown specifiers remain untouched.
+              for (var i = startTextIndex; i < textIndex + 2; i++) {
+                ret.push(HEAP8[(i)]);
+              }
+            }
+          }
+          textIndex += 2;
+          // TODO: Support a/A (hex float) and m (last error) specifiers.
+          // TODO: Support %1${specifier} for arg selection.
+        } else {
+          ret.push(curr);
+          textIndex += 1;
+        }
+      }
+      return ret;
+    }function _fprintf(stream, format, varargs) {
+      // int fprintf(FILE *restrict stream, const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var result = __formatString(format, varargs);
+      var stack = Runtime.stackSave();
+      var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream);
+      Runtime.stackRestore(stack);
+      return ret;
+    }function _printf(format, varargs) {
+      // int printf(const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var stdout = HEAP32[((_stdout)>>2)];
+      return _fprintf(stdout, format, varargs);
+    }
+
+
+
+  function _emscripten_memcpy_big(dest, src, num) {
+      HEAPU8.set(HEAPU8.subarray(src, src+num), dest);
+      return dest;
+    }
+  Module["_memcpy"] = _memcpy;
+
+
+  function _fputs(s, stream) {
+      // int fputs(const char *restrict s, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fputs.html
+      var fd = _fileno(stream);
+      return _write(fd, s, _strlen(s));
+    }
+
+  function _fputc(c, stream) {
+      // int fputc(int c, FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fputc.html
+      var chr = unSign(c & 0xFF);
+      HEAP8[((_fputc.ret)|0)]=chr;
+      var fd = _fileno(stream);
+      var ret = _write(fd, _fputc.ret, 1);
+      if (ret == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return -1;
+      } else {
+        return chr;
+      }
+    }function _puts(s) {
+      // int puts(const char *s);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/puts.html
+      // NOTE: puts() always writes an extra newline.
+      var stdout = HEAP32[((_stdout)>>2)];
+      var ret = _fputs(s, stdout);
+      if (ret < 0) {
+        return ret;
+      } else {
+        var newlineRet = _fputc(10, stdout);
+        return (newlineRet < 0) ? -1 : ret + 1;
+      }
+    }
+
+  function _sbrk(bytes) {
+      // Implement a Linux-like 'memory area' for our 'process'.
+      // Changes the size of the memory area by |bytes|; returns the
+      // address of the previous top ('break') of the memory area
+      // We control the "dynamic" memory - DYNAMIC_BASE to DYNAMICTOP
+      var self = _sbrk;
+      if (!self.called) {
+        DYNAMICTOP = alignMemoryPage(DYNAMICTOP); // make sure we start out aligned
+        self.called = true;
+        assert(Runtime.dynamicAlloc);
+        self.alloc = Runtime.dynamicAlloc;
+        Runtime.dynamicAlloc = function() { abort('cannot dynamically allocate, sbrk now has control') };
+      }
+      var ret = DYNAMICTOP;
+      if (bytes != 0) self.alloc(bytes);
+      return ret;  // Previous break location.
+    }
+
+  function ___errno_location() {
+      return ___errno_state;
+    }
+
+  function __ZNSt9exceptionD2Ev() {}
+
+  var Browser={mainLoop:{scheduler:null,method:"",shouldPause:false,paused:false,queue:[],pause:function () {
+          Browser.mainLoop.shouldPause = true;
+        },resume:function () {
+          if (Browser.mainLoop.paused) {
+            Browser.mainLoop.paused = false;
+            Browser.mainLoop.scheduler();
+          }
+          Browser.mainLoop.shouldPause = false;
+        },updateStatus:function () {
+          if (Module['setStatus']) {
+            var message = Module['statusMessage'] || 'Please wait...';
+            var remaining = Browser.mainLoop.remainingBlockers;
+            var expected = Browser.mainLoop.expectedBlockers;
+            if (remaining) {
+              if (remaining < expected) {
+                Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
+              } else {
+                Module['setStatus'](message);
+              }
+            } else {
+              Module['setStatus']('');
+            }
+          }
+        }},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () {
+        if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
+
+        if (Browser.initted || ENVIRONMENT_IS_WORKER) return;
+        Browser.initted = true;
+
+        try {
+          new Blob();
+          Browser.hasBlobConstructor = true;
+        } catch(e) {
+          Browser.hasBlobConstructor = false;
+          console.log("warning: no blob constructor, cannot create blobs with mimetypes");
+        }
+        Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
+        Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
+        if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
+          console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
+          Module.noImageDecoding = true;
+        }
+
+        // Support for plugins that can process preloaded files. You can add more of these to
+        // your app by creating and appending to Module.preloadPlugins.
+        //
+        // Each plugin is asked if it can handle a file based on the file's name. If it can,
+        // it is given the file's raw data. When it is done, it calls a callback with the file's
+        // (possibly modified) data. For example, a plugin might decompress a file, or it
+        // might create some side data structure for use later (like an Image element, etc.).
+
+        var imagePlugin = {};
+        imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
+          return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
+        };
+        imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
+          var b = null;
+          if (Browser.hasBlobConstructor) {
+            try {
+              b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+              if (b.size !== byteArray.length) { // Safari bug #118630
+                // Safari's Blob can only take an ArrayBuffer
+                b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
+              }
+            } catch(e) {
+              Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
+            }
+          }
+          if (!b) {
+            var bb = new Browser.BlobBuilder();
+            bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
+            b = bb.getBlob();
+          }
+          var url = Browser.URLObject.createObjectURL(b);
+          var img = new Image();
+          img.onload = function img_onload() {
+            assert(img.complete, 'Image ' + name + ' could not be decoded');
+            var canvas = document.createElement('canvas');
+            canvas.width = img.width;
+            canvas.height = img.height;
+            var ctx = canvas.getContext('2d');
+            ctx.drawImage(img, 0, 0);
+            Module["preloadedImages"][name] = canvas;
+            Browser.URLObject.revokeObjectURL(url);
+            if (onload) onload(byteArray);
+          };
+          img.onerror = function img_onerror(event) {
+            console.log('Image ' + url + ' could not be decoded');
+            if (onerror) onerror();
+          };
+          img.src = url;
+        };
+        Module['preloadPlugins'].push(imagePlugin);
+
+        var audioPlugin = {};
+        audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
+          return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
+        };
+        audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
+          var done = false;
+          function finish(audio) {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = audio;
+            if (onload) onload(byteArray);
+          }
+          function fail() {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = new Audio(); // empty shim
+            if (onerror) onerror();
+          }
+          if (Browser.hasBlobConstructor) {
+            try {
+              var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+            } catch(e) {
+              return fail();
+            }
+            var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
+            var audio = new Audio();
+            audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926
+            audio.onerror = function audio_onerror(event) {
+              if (done) return;
+              console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
+              function encode64(data) {
+                var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+                var PAD = '=';
+                var ret = '';
+                var leftchar = 0;
+                var leftbits = 0;
+                for (var i = 0; i < data.length; i++) {
+                  leftchar = (leftchar << 8) | data[i];
+                  leftbits += 8;
+                  while (leftbits >= 6) {
+                    var curr = (leftchar >> (leftbits-6)) & 0x3f;
+                    leftbits -= 6;
+                    ret += BASE[curr];
+                  }
+                }
+                if (leftbits == 2) {
+                  ret += BASE[(leftchar&3) << 4];
+                  ret += PAD + PAD;
+                } else if (leftbits == 4) {
+                  ret += BASE[(leftchar&0xf) << 2];
+                  ret += PAD;
+                }
+                return ret;
+              }
+              audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
+              finish(audio); // we don't wait for confirmation this worked - but it's worth trying
+            };
+            audio.src = url;
+            // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
+            Browser.safeSetTimeout(function() {
+              finish(audio); // try to use it even though it is not necessarily ready to play
+            }, 10000);
+          } else {
+            return fail();
+          }
+        };
+        Module['preloadPlugins'].push(audioPlugin);
+
+        // Canvas event setup
+
+        var canvas = Module['canvas'];
+
+        // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
+        // Module['forcedAspectRatio'] = 4 / 3;
+
+        canvas.requestPointerLock = canvas['requestPointerLock'] ||
+                                    canvas['mozRequestPointerLock'] ||
+                                    canvas['webkitRequestPointerLock'] ||
+                                    canvas['msRequestPointerLock'] ||
+                                    function(){};
+        canvas.exitPointerLock = document['exitPointerLock'] ||
+                                 document['mozExitPointerLock'] ||
+                                 document['webkitExitPointerLock'] ||
+                                 document['msExitPointerLock'] ||
+                                 function(){}; // no-op if function does not exist
+        canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
+
+        function pointerLockChange() {
+          Browser.pointerLock = document['pointerLockElement'] === canvas ||
+                                document['mozPointerLockElement'] === canvas ||
+                                document['webkitPointerLockElement'] === canvas ||
+                                document['msPointerLockElement'] === canvas;
+        }
+
+        document.addEventListener('pointerlockchange', pointerLockChange, false);
+        document.addEventListener('mozpointerlockchange', pointerLockChange, false);
+        document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
+        document.addEventListener('mspointerlockchange', pointerLockChange, false);
+
+        if (Module['elementPointerLock']) {
+          canvas.addEventListener("click", function(ev) {
+            if (!Browser.pointerLock && canvas.requestPointerLock) {
+              canvas.requestPointerLock();
+              ev.preventDefault();
+            }
+          }, false);
+        }
+      },createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) {
+        var ctx;
+        var errorInfo = '?';
+        function onContextCreationError(event) {
+          errorInfo = event.statusMessage || errorInfo;
+        }
+        try {
+          if (useWebGL) {
+            var contextAttributes = {
+              antialias: false,
+              alpha: false
+            };
+
+            if (webGLContextAttributes) {
+              for (var attribute in webGLContextAttributes) {
+                contextAttributes[attribute] = webGLContextAttributes[attribute];
+              }
+            }
+
+
+            canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
+            try {
+              ['experimental-webgl', 'webgl'].some(function(webglId) {
+                return ctx = canvas.getContext(webglId, contextAttributes);
+              });
+            } finally {
+              canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
+            }
+          } else {
+            ctx = canvas.getContext('2d');
+          }
+          if (!ctx) throw ':(';
+        } catch (e) {
+          Module.print('Could not create canvas: ' + [errorInfo, e]);
+          return null;
+        }
+        if (useWebGL) {
+          // Set the background of the WebGL canvas to black
+          canvas.style.backgroundColor = "black";
+
+          // Warn on context loss
+          canvas.addEventListener('webglcontextlost', function(event) {
+            alert('WebGL context lost. You will need to reload the page.');
+          }, false);
+        }
+        if (setInModule) {
+          GLctx = Module.ctx = ctx;
+          Module.useWebGL = useWebGL;
+          Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
+          Browser.init();
+        }
+        return ctx;
+      },destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) {
+        Browser.lockPointer = lockPointer;
+        Browser.resizeCanvas = resizeCanvas;
+        if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;
+        if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;
+
+        var canvas = Module['canvas'];
+        function fullScreenChange() {
+          Browser.isFullScreen = false;
+          var canvasContainer = canvas.parentNode;
+          if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+               document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+               document['fullScreenElement'] || document['fullscreenElement'] ||
+               document['msFullScreenElement'] || document['msFullscreenElement'] ||
+               document['webkitCurrentFullScreenElement']) === canvasContainer) {
+            canvas.cancelFullScreen = document['cancelFullScreen'] ||
+                                      document['mozCancelFullScreen'] ||
+                                      document['webkitCancelFullScreen'] ||
+                                      document['msExitFullscreen'] ||
+                                      document['exitFullscreen'] ||
+                                      function() {};
+            canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document);
+            if (Browser.lockPointer) canvas.requestPointerLock();
+            Browser.isFullScreen = true;
+            if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize();
+          } else {
+
+            // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
+            canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
+            canvasContainer.parentNode.removeChild(canvasContainer);
+
+            if (Browser.resizeCanvas) Browser.setWindowedCanvasSize();
+          }
+          if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen);
+          Browser.updateCanvasDimensions(canvas);
+        }
+
+        if (!Browser.fullScreenHandlersInstalled) {
+          Browser.fullScreenHandlersInstalled = true;
+          document.addEventListener('fullscreenchange', fullScreenChange, false);
+          document.addEventListener('mozfullscreenchange', fullScreenChange, false);
+          document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
+          document.addEventListener('MSFullscreenChange', fullScreenChange, false);
+        }
+
+        // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
+        var canvasContainer = document.createElement("div");
+        canvas.parentNode.insertBefore(canvasContainer, canvas);
+        canvasContainer.appendChild(canvas);
+
+        // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
+        canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] ||
+                                            canvasContainer['mozRequestFullScreen'] ||
+                                            canvasContainer['msRequestFullscreen'] ||
+                                           (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
+        canvasContainer.requestFullScreen();
+      },requestAnimationFrame:function requestAnimationFrame(func) {
+        if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js)
+          setTimeout(func, 1000/60);
+        } else {
+          if (!window.requestAnimationFrame) {
+            window.requestAnimationFrame = window['requestAnimationFrame'] ||
+                                           window['mozRequestAnimationFrame'] ||
+                                           window['webkitRequestAnimationFrame'] ||
+                                           window['msRequestAnimationFrame'] ||
+                                           window['oRequestAnimationFrame'] ||
+                                           window['setTimeout'];
+          }
+          window.requestAnimationFrame(func);
+        }
+      },safeCallback:function (func) {
+        return function() {
+          if (!ABORT) return func.apply(null, arguments);
+        };
+      },safeRequestAnimationFrame:function (func) {
+        return Browser.requestAnimationFrame(function() {
+          if (!ABORT) func();
+        });
+      },safeSetTimeout:function (func, timeout) {
+        return setTimeout(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },safeSetInterval:function (func, timeout) {
+        return setInterval(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },getMimetype:function (name) {
+        return {
+          'jpg': 'image/jpeg',
+          'jpeg': 'image/jpeg',
+          'png': 'image/png',
+          'bmp': 'image/bmp',
+          'ogg': 'audio/ogg',
+          'wav': 'audio/wav',
+          'mp3': 'audio/mpeg'
+        }[name.substr(name.lastIndexOf('.')+1)];
+      },getUserMedia:function (func) {
+        if(!window.getUserMedia) {
+          window.getUserMedia = navigator['getUserMedia'] ||
+                                navigator['mozGetUserMedia'];
+        }
+        window.getUserMedia(func);
+      },getMovementX:function (event) {
+        return event['movementX'] ||
+               event['mozMovementX'] ||
+               event['webkitMovementX'] ||
+               0;
+      },getMovementY:function (event) {
+        return event['movementY'] ||
+               event['mozMovementY'] ||
+               event['webkitMovementY'] ||
+               0;
+      },getMouseWheelDelta:function (event) {
+        return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta));
+      },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup
+        if (Browser.pointerLock) {
+          // When the pointer is locked, calculate the coordinates
+          // based on the movement of the mouse.
+          // Workaround for Firefox bug 764498
+          if (event.type != 'mousemove' &&
+              ('mozMovementX' in event)) {
+            Browser.mouseMovementX = Browser.mouseMovementY = 0;
+          } else {
+            Browser.mouseMovementX = Browser.getMovementX(event);
+            Browser.mouseMovementY = Browser.getMovementY(event);
+          }
+
+          // check if SDL is available
+          if (typeof SDL != "undefined") {
+            Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
+            Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
+          } else {
+            // just add the mouse delta to the current absolut mouse position
+            // FIXME: ideally this should be clamped against the canvas size and zero
+            Browser.mouseX += Browser.mouseMovementX;
+            Browser.mouseY += Browser.mouseMovementY;
+          }
+        } else {
+          // Otherwise, calculate the movement based on the changes
+          // in the coordinates.
+          var rect = Module["canvas"].getBoundingClientRect();
+          var x, y;
+
+          // Neither .scrollX or .pageXOffset are defined in a spec, but
+          // we prefer .scrollX because it is currently in a spec draft.
+          // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
+          var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);
+          var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);
+          if (event.type == 'touchstart' ||
+              event.type == 'touchend' ||
+              event.type == 'touchmove') {
+            var t = event.touches.item(0);
+            if (t) {
+              x = t.pageX - (scrollX + rect.left);
+              y = t.pageY - (scrollY + rect.top);
+            } else {
+              return;
+            }
+          } else {
+            x = event.pageX - (scrollX + rect.left);
+            y = event.pageY - (scrollY + rect.top);
+          }
+
+          // the canvas might be CSS-scaled compared to its backbuffer;
+          // SDL-using content will want mouse coordinates in terms
+          // of backbuffer units.
+          var cw = Module["canvas"].width;
+          var ch = Module["canvas"].height;
+          x = x * (cw / rect.width);
+          y = y * (ch / rect.height);
+
+          Browser.mouseMovementX = x - Browser.mouseX;
+          Browser.mouseMovementY = y - Browser.mouseY;
+          Browser.mouseX = x;
+          Browser.mouseY = y;
+        }
+      },xhrLoad:function (url, onload, onerror) {
+        var xhr = new XMLHttpRequest();
+        xhr.open('GET', url, true);
+        xhr.responseType = 'arraybuffer';
+        xhr.onload = function xhr_onload() {
+          if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
+            onload(xhr.response);
+          } else {
+            onerror();
+          }
+        };
+        xhr.onerror = onerror;
+        xhr.send(null);
+      },asyncLoad:function (url, onload, onerror, noRunDep) {
+        Browser.xhrLoad(url, function(arrayBuffer) {
+          assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
+          onload(new Uint8Array(arrayBuffer));
+          if (!noRunDep) removeRunDependency('al ' + url);
+        }, function(event) {
+          if (onerror) {
+            onerror();
+          } else {
+            throw 'Loading data file "' + url + '" failed.';
+          }
+        });
+        if (!noRunDep) addRunDependency('al ' + url);
+      },resizeListeners:[],updateResizeListeners:function () {
+        var canvas = Module['canvas'];
+        Browser.resizeListeners.forEach(function(listener) {
+          listener(canvas.width, canvas.height);
+        });
+      },setCanvasSize:function (width, height, noUpdates) {
+        var canvas = Module['canvas'];
+        Browser.updateCanvasDimensions(canvas, width, height);
+        if (!noUpdates) Browser.updateResizeListeners();
+      },windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+          var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+          flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
+          HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },setWindowedCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+          var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+          flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
+          HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },updateCanvasDimensions:function (canvas, wNative, hNative) {
+        if (wNative && hNative) {
+          canvas.widthNative = wNative;
+          canvas.heightNative = hNative;
+        } else {
+          wNative = canvas.widthNative;
+          hNative = canvas.heightNative;
+        }
+        var w = wNative;
+        var h = hNative;
+        if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
+          if (w/h < Module['forcedAspectRatio']) {
+            w = Math.round(h * Module['forcedAspectRatio']);
+          } else {
+            h = Math.round(w / Module['forcedAspectRatio']);
+          }
+        }
+        if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+             document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+             document['fullScreenElement'] || document['fullscreenElement'] ||
+             document['msFullScreenElement'] || document['msFullscreenElement'] ||
+             document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
+           var factor = Math.min(screen.width / w, screen.height / h);
+           w = Math.round(w * factor);
+           h = Math.round(h * factor);
+        }
+        if (Browser.resizeCanvas) {
+          if (canvas.width  != w) canvas.width  = w;
+          if (canvas.height != h) canvas.height = h;
+          if (typeof canvas.style != 'undefined') {
+            canvas.style.removeProperty( "width");
+            canvas.style.removeProperty("height");
+          }
+        } else {
+          if (canvas.width  != wNative) canvas.width  = wNative;
+          if (canvas.height != hNative) canvas.height = hNative;
+          if (typeof canvas.style != 'undefined') {
+            if (w != wNative || h != hNative) {
+              canvas.style.setProperty( "width", w + "px", "important");
+              canvas.style.setProperty("height", h + "px", "important");
+            } else {
+              canvas.style.removeProperty( "width");
+              canvas.style.removeProperty("height");
+            }
+          }
+        }
+      }};
+
+  function _time(ptr) {
+      var ret = Math.floor(Date.now()/1000);
+      if (ptr) {
+        HEAP32[((ptr)>>2)]=ret;
+      }
+      return ret;
+    }
+
+
+  function _malloc(bytes) {
+      /* Over-allocate to make sure it is byte-aligned by 8.
+       * This will leak memory, but this is only the dummy
+       * implementation (replaced by dlmalloc normally) so
+       * not an issue.
+       */
+      var ptr = Runtime.dynamicAlloc(bytes + 8);
+      return (ptr+8) & 0xFFFFFFF8;
+    }
+  Module["_malloc"] = _malloc;function ___cxa_allocate_exception(size) {
+      var ptr = _malloc(size + ___cxa_exception_header_size);
+      return ptr + ___cxa_exception_header_size;
+    }
+
+  var __ZTISt9exception=allocate([allocate([1,0,0,0,0,0,0], "i8", ALLOC_STATIC)+8, 0], "i32", ALLOC_STATIC);
+
+  function __ZTVN10__cxxabiv120__si_class_type_infoE() {
+  Module['printErr']('missing function: _ZTVN10__cxxabiv120__si_class_type_infoE'); abort(-1);
+  }
+___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0;
+FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice;
+__ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor();
+if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); }
+__ATINIT__.push({ func: function() { SOCKFS.root = FS.mount(SOCKFS, {}, null); } });
+_fputc.ret = allocate([0], "i8", ALLOC_STATIC);
+Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };
+  Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
+  Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
+  Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
+  Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
+  Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }
+STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);
+
+staticSealed = true; // seal the static portion of memory
+
+STACK_MAX = STACK_BASE + 5242880;
+
+DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);
+
+assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");
+
+
+var Math_min = Math.min;
+function invoke_ii(index,a1) {
+  try {
+    return Module["dynCall_ii"](index,a1);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_vi(index,a1) {
+  try {
+    Module["dynCall_vi"](index,a1);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_v(index) {
+  try {
+    Module["dynCall_v"](index);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function asmPrintInt(x, y) {
+  Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+function asmPrintFloat(x, y) {
+  Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+// EMSCRIPTEN_START_ASM
+var asm = (function(global, env, buffer) {
+  'use asm';
+  var HEAP8 = new global.Int8Array(buffer);
+  var HEAP16 = new global.Int16Array(buffer);
+  var HEAP32 = new global.Int32Array(buffer);
+  var HEAPU8 = new global.Uint8Array(buffer);
+  var HEAPU16 = new global.Uint16Array(buffer);
+  var HEAPU32 = new global.Uint32Array(buffer);
+  var HEAPF32 = new global.Float32Array(buffer);
+  var HEAPF64 = new global.Float64Array(buffer);
+
+  var STACKTOP=env.STACKTOP|0;
+  var STACK_MAX=env.STACK_MAX|0;
+  var tempDoublePtr=env.tempDoublePtr|0;
+  var ABORT=env.ABORT|0;
+  var __ZTISt9exception=env.__ZTISt9exception|0;
+  var __ZTVN10__cxxabiv120__si_class_type_infoE=env.__ZTVN10__cxxabiv120__si_class_type_infoE|0;
+
+  var __THREW__ = 0;
+  var threwValue = 0;
+  var setjmpId = 0;
+  var undef = 0;
+  var nan = +env.NaN, inf = +env.Infinity;
+  var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
+
+  var tempRet0 = 0;
+  var tempRet1 = 0;
+  var tempRet2 = 0;
+  var tempRet3 = 0;
+  var tempRet4 = 0;
+  var tempRet5 = 0;
+  var tempRet6 = 0;
+  var tempRet7 = 0;
+  var tempRet8 = 0;
+  var tempRet9 = 0;
+  var Math_floor=global.Math.floor;
+  var Math_abs=global.Math.abs;
+  var Math_sqrt=global.Math.sqrt;
+  var Math_pow=global.Math.pow;
+  var Math_cos=global.Math.cos;
+  var Math_sin=global.Math.sin;
+  var Math_tan=global.Math.tan;
+  var Math_acos=global.Math.acos;
+  var Math_asin=global.Math.asin;
+  var Math_atan=global.Math.atan;
+  var Math_atan2=global.Math.atan2;
+  var Math_exp=global.Math.exp;
+  var Math_log=global.Math.log;
+  var Math_ceil=global.Math.ceil;
+  var Math_imul=global.Math.imul;
+  var abort=env.abort;
+  var assert=env.assert;
+  var asmPrintInt=env.asmPrintInt;
+  var asmPrintFloat=env.asmPrintFloat;
+  var Math_min=env.min;
+  var invoke_ii=env.invoke_ii;
+  var invoke_vi=env.invoke_vi;
+  var invoke_v=env.invoke_v;
+  var _send=env._send;
+  var ___setErrNo=env.___setErrNo;
+  var ___cxa_is_number_type=env.___cxa_is_number_type;
+  var ___cxa_allocate_exception=env.___cxa_allocate_exception;
+  var ___cxa_find_matching_catch=env.___cxa_find_matching_catch;
+  var _fflush=env._fflush;
+  var _time=env._time;
+  var _pwrite=env._pwrite;
+  var __reallyNegative=env.__reallyNegative;
+  var _sbrk=env._sbrk;
+  var _emscripten_memcpy_big=env._emscripten_memcpy_big;
+  var _fileno=env._fileno;
+  var ___resumeException=env.___resumeException;
+  var __ZSt18uncaught_exceptionv=env.__ZSt18uncaught_exceptionv;
+  var _sysconf=env._sysconf;
+  var _puts=env._puts;
+  var _mkport=env._mkport;
+  var _write=env._write;
+  var ___errno_location=env.___errno_location;
+  var __ZNSt9exceptionD2Ev=env.__ZNSt9exceptionD2Ev;
+  var _fputc=env._fputc;
+  var ___cxa_throw=env.___cxa_throw;
+  var _abort=env._abort;
+  var _fwrite=env._fwrite;
+  var ___cxa_does_inherit=env.___cxa_does_inherit;
+  var _fprintf=env._fprintf;
+  var __formatString=env.__formatString;
+  var _fputs=env._fputs;
+  var _printf=env._printf;
+  var tempFloat = 0.0;
+
+// EMSCRIPTEN_START_FUNCS
+function _malloc(i12) {
+ i12 = i12 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0;
+ i1 = STACKTOP;
+ do {
+  if (i12 >>> 0 < 245) {
+   if (i12 >>> 0 < 11) {
+    i12 = 16;
+   } else {
+    i12 = i12 + 11 & -8;
+   }
+   i20 = i12 >>> 3;
+   i18 = HEAP32[146] | 0;
+   i21 = i18 >>> i20;
+   if ((i21 & 3 | 0) != 0) {
+    i6 = (i21 & 1 ^ 1) + i20 | 0;
+    i5 = i6 << 1;
+    i3 = 624 + (i5 << 2) | 0;
+    i5 = 624 + (i5 + 2 << 2) | 0;
+    i7 = HEAP32[i5 >> 2] | 0;
+    i2 = i7 + 8 | 0;
+    i4 = HEAP32[i2 >> 2] | 0;
+    do {
+     if ((i3 | 0) != (i4 | 0)) {
+      if (i4 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i8 = i4 + 12 | 0;
+      if ((HEAP32[i8 >> 2] | 0) == (i7 | 0)) {
+       HEAP32[i8 >> 2] = i3;
+       HEAP32[i5 >> 2] = i4;
+       break;
+      } else {
+       _abort();
+      }
+     } else {
+      HEAP32[146] = i18 & ~(1 << i6);
+     }
+    } while (0);
+    i32 = i6 << 3;
+    HEAP32[i7 + 4 >> 2] = i32 | 3;
+    i32 = i7 + (i32 | 4) | 0;
+    HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+    i32 = i2;
+    STACKTOP = i1;
+    return i32 | 0;
+   }
+   if (i12 >>> 0 > (HEAP32[592 >> 2] | 0) >>> 0) {
+    if ((i21 | 0) != 0) {
+     i7 = 2 << i20;
+     i7 = i21 << i20 & (i7 | 0 - i7);
+     i7 = (i7 & 0 - i7) + -1 | 0;
+     i2 = i7 >>> 12 & 16;
+     i7 = i7 >>> i2;
+     i6 = i7 >>> 5 & 8;
+     i7 = i7 >>> i6;
+     i5 = i7 >>> 2 & 4;
+     i7 = i7 >>> i5;
+     i4 = i7 >>> 1 & 2;
+     i7 = i7 >>> i4;
+     i3 = i7 >>> 1 & 1;
+     i3 = (i6 | i2 | i5 | i4 | i3) + (i7 >>> i3) | 0;
+     i7 = i3 << 1;
+     i4 = 624 + (i7 << 2) | 0;
+     i7 = 624 + (i7 + 2 << 2) | 0;
+     i5 = HEAP32[i7 >> 2] | 0;
+     i2 = i5 + 8 | 0;
+     i6 = HEAP32[i2 >> 2] | 0;
+     do {
+      if ((i4 | 0) != (i6 | 0)) {
+       if (i6 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+        _abort();
+       }
+       i8 = i6 + 12 | 0;
+       if ((HEAP32[i8 >> 2] | 0) == (i5 | 0)) {
+        HEAP32[i8 >> 2] = i4;
+        HEAP32[i7 >> 2] = i6;
+        break;
+       } else {
+        _abort();
+       }
+      } else {
+       HEAP32[146] = i18 & ~(1 << i3);
+      }
+     } while (0);
+     i6 = i3 << 3;
+     i4 = i6 - i12 | 0;
+     HEAP32[i5 + 4 >> 2] = i12 | 3;
+     i3 = i5 + i12 | 0;
+     HEAP32[i5 + (i12 | 4) >> 2] = i4 | 1;
+     HEAP32[i5 + i6 >> 2] = i4;
+     i6 = HEAP32[592 >> 2] | 0;
+     if ((i6 | 0) != 0) {
+      i5 = HEAP32[604 >> 2] | 0;
+      i8 = i6 >>> 3;
+      i9 = i8 << 1;
+      i6 = 624 + (i9 << 2) | 0;
+      i7 = HEAP32[146] | 0;
+      i8 = 1 << i8;
+      if ((i7 & i8 | 0) != 0) {
+       i7 = 624 + (i9 + 2 << 2) | 0;
+       i8 = HEAP32[i7 >> 2] | 0;
+       if (i8 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        i28 = i7;
+        i27 = i8;
+       }
+      } else {
+       HEAP32[146] = i7 | i8;
+       i28 = 624 + (i9 + 2 << 2) | 0;
+       i27 = i6;
+      }
+      HEAP32[i28 >> 2] = i5;
+      HEAP32[i27 + 12 >> 2] = i5;
+      HEAP32[i5 + 8 >> 2] = i27;
+      HEAP32[i5 + 12 >> 2] = i6;
+     }
+     HEAP32[592 >> 2] = i4;
+     HEAP32[604 >> 2] = i3;
+     i32 = i2;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+    i18 = HEAP32[588 >> 2] | 0;
+    if ((i18 | 0) != 0) {
+     i2 = (i18 & 0 - i18) + -1 | 0;
+     i31 = i2 >>> 12 & 16;
+     i2 = i2 >>> i31;
+     i30 = i2 >>> 5 & 8;
+     i2 = i2 >>> i30;
+     i32 = i2 >>> 2 & 4;
+     i2 = i2 >>> i32;
+     i6 = i2 >>> 1 & 2;
+     i2 = i2 >>> i6;
+     i3 = i2 >>> 1 & 1;
+     i3 = HEAP32[888 + ((i30 | i31 | i32 | i6 | i3) + (i2 >>> i3) << 2) >> 2] | 0;
+     i2 = (HEAP32[i3 + 4 >> 2] & -8) - i12 | 0;
+     i6 = i3;
+     while (1) {
+      i5 = HEAP32[i6 + 16 >> 2] | 0;
+      if ((i5 | 0) == 0) {
+       i5 = HEAP32[i6 + 20 >> 2] | 0;
+       if ((i5 | 0) == 0) {
+        break;
+       }
+      }
+      i6 = (HEAP32[i5 + 4 >> 2] & -8) - i12 | 0;
+      i4 = i6 >>> 0 < i2 >>> 0;
+      i2 = i4 ? i6 : i2;
+      i6 = i5;
+      i3 = i4 ? i5 : i3;
+     }
+     i6 = HEAP32[600 >> 2] | 0;
+     if (i3 >>> 0 < i6 >>> 0) {
+      _abort();
+     }
+     i4 = i3 + i12 | 0;
+     if (!(i3 >>> 0 < i4 >>> 0)) {
+      _abort();
+     }
+     i5 = HEAP32[i3 + 24 >> 2] | 0;
+     i7 = HEAP32[i3 + 12 >> 2] | 0;
+     do {
+      if ((i7 | 0) == (i3 | 0)) {
+       i8 = i3 + 20 | 0;
+       i7 = HEAP32[i8 >> 2] | 0;
+       if ((i7 | 0) == 0) {
+        i8 = i3 + 16 | 0;
+        i7 = HEAP32[i8 >> 2] | 0;
+        if ((i7 | 0) == 0) {
+         i26 = 0;
+         break;
+        }
+       }
+       while (1) {
+        i10 = i7 + 20 | 0;
+        i9 = HEAP32[i10 >> 2] | 0;
+        if ((i9 | 0) != 0) {
+         i7 = i9;
+         i8 = i10;
+         continue;
+        }
+        i10 = i7 + 16 | 0;
+        i9 = HEAP32[i10 >> 2] | 0;
+        if ((i9 | 0) == 0) {
+         break;
+        } else {
+         i7 = i9;
+         i8 = i10;
+        }
+       }
+       if (i8 >>> 0 < i6 >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i8 >> 2] = 0;
+        i26 = i7;
+        break;
+       }
+      } else {
+       i8 = HEAP32[i3 + 8 >> 2] | 0;
+       if (i8 >>> 0 < i6 >>> 0) {
+        _abort();
+       }
+       i6 = i8 + 12 | 0;
+       if ((HEAP32[i6 >> 2] | 0) != (i3 | 0)) {
+        _abort();
+       }
+       i9 = i7 + 8 | 0;
+       if ((HEAP32[i9 >> 2] | 0) == (i3 | 0)) {
+        HEAP32[i6 >> 2] = i7;
+        HEAP32[i9 >> 2] = i8;
+        i26 = i7;
+        break;
+       } else {
+        _abort();
+       }
+      }
+     } while (0);
+     do {
+      if ((i5 | 0) != 0) {
+       i7 = HEAP32[i3 + 28 >> 2] | 0;
+       i6 = 888 + (i7 << 2) | 0;
+       if ((i3 | 0) == (HEAP32[i6 >> 2] | 0)) {
+        HEAP32[i6 >> 2] = i26;
+        if ((i26 | 0) == 0) {
+         HEAP32[588 >> 2] = HEAP32[588 >> 2] & ~(1 << i7);
+         break;
+        }
+       } else {
+        if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+         _abort();
+        }
+        i6 = i5 + 16 | 0;
+        if ((HEAP32[i6 >> 2] | 0) == (i3 | 0)) {
+         HEAP32[i6 >> 2] = i26;
+        } else {
+         HEAP32[i5 + 20 >> 2] = i26;
+        }
+        if ((i26 | 0) == 0) {
+         break;
+        }
+       }
+       if (i26 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+        _abort();
+       }
+       HEAP32[i26 + 24 >> 2] = i5;
+       i5 = HEAP32[i3 + 16 >> 2] | 0;
+       do {
+        if ((i5 | 0) != 0) {
+         if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i26 + 16 >> 2] = i5;
+          HEAP32[i5 + 24 >> 2] = i26;
+          break;
+         }
+        }
+       } while (0);
+       i5 = HEAP32[i3 + 20 >> 2] | 0;
+       if ((i5 | 0) != 0) {
+        if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i26 + 20 >> 2] = i5;
+         HEAP32[i5 + 24 >> 2] = i26;
+         break;
+        }
+       }
+      }
+     } while (0);
+     if (i2 >>> 0 < 16) {
+      i32 = i2 + i12 | 0;
+      HEAP32[i3 + 4 >> 2] = i32 | 3;
+      i32 = i3 + (i32 + 4) | 0;
+      HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+     } else {
+      HEAP32[i3 + 4 >> 2] = i12 | 3;
+      HEAP32[i3 + (i12 | 4) >> 2] = i2 | 1;
+      HEAP32[i3 + (i2 + i12) >> 2] = i2;
+      i6 = HEAP32[592 >> 2] | 0;
+      if ((i6 | 0) != 0) {
+       i5 = HEAP32[604 >> 2] | 0;
+       i8 = i6 >>> 3;
+       i9 = i8 << 1;
+       i6 = 624 + (i9 << 2) | 0;
+       i7 = HEAP32[146] | 0;
+       i8 = 1 << i8;
+       if ((i7 & i8 | 0) != 0) {
+        i7 = 624 + (i9 + 2 << 2) | 0;
+        i8 = HEAP32[i7 >> 2] | 0;
+        if (i8 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+         _abort();
+        } else {
+         i25 = i7;
+         i24 = i8;
+        }
+       } else {
+        HEAP32[146] = i7 | i8;
+        i25 = 624 + (i9 + 2 << 2) | 0;
+        i24 = i6;
+       }
+       HEAP32[i25 >> 2] = i5;
+       HEAP32[i24 + 12 >> 2] = i5;
+       HEAP32[i5 + 8 >> 2] = i24;
+       HEAP32[i5 + 12 >> 2] = i6;
+      }
+      HEAP32[592 >> 2] = i2;
+      HEAP32[604 >> 2] = i4;
+     }
+     i32 = i3 + 8 | 0;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+   }
+  } else {
+   if (!(i12 >>> 0 > 4294967231)) {
+    i24 = i12 + 11 | 0;
+    i12 = i24 & -8;
+    i26 = HEAP32[588 >> 2] | 0;
+    if ((i26 | 0) != 0) {
+     i25 = 0 - i12 | 0;
+     i24 = i24 >>> 8;
+     if ((i24 | 0) != 0) {
+      if (i12 >>> 0 > 16777215) {
+       i27 = 31;
+      } else {
+       i31 = (i24 + 1048320 | 0) >>> 16 & 8;
+       i32 = i24 << i31;
+       i30 = (i32 + 520192 | 0) >>> 16 & 4;
+       i32 = i32 << i30;
+       i27 = (i32 + 245760 | 0) >>> 16 & 2;
+       i27 = 14 - (i30 | i31 | i27) + (i32 << i27 >>> 15) | 0;
+       i27 = i12 >>> (i27 + 7 | 0) & 1 | i27 << 1;
+      }
+     } else {
+      i27 = 0;
+     }
+     i30 = HEAP32[888 + (i27 << 2) >> 2] | 0;
+     L126 : do {
+      if ((i30 | 0) == 0) {
+       i29 = 0;
+       i24 = 0;
+      } else {
+       if ((i27 | 0) == 31) {
+        i24 = 0;
+       } else {
+        i24 = 25 - (i27 >>> 1) | 0;
+       }
+       i29 = 0;
+       i28 = i12 << i24;
+       i24 = 0;
+       while (1) {
+        i32 = HEAP32[i30 + 4 >> 2] & -8;
+        i31 = i32 - i12 | 0;
+        if (i31 >>> 0 < i25 >>> 0) {
+         if ((i32 | 0) == (i12 | 0)) {
+          i25 = i31;
+          i29 = i30;
+          i24 = i30;
+          break L126;
+         } else {
+          i25 = i31;
+          i24 = i30;
+         }
+        }
+        i31 = HEAP32[i30 + 20 >> 2] | 0;
+        i30 = HEAP32[i30 + (i28 >>> 31 << 2) + 16 >> 2] | 0;
+        i29 = (i31 | 0) == 0 | (i31 | 0) == (i30 | 0) ? i29 : i31;
+        if ((i30 | 0) == 0) {
+         break;
+        } else {
+         i28 = i28 << 1;
+        }
+       }
+      }
+     } while (0);
+     if ((i29 | 0) == 0 & (i24 | 0) == 0) {
+      i32 = 2 << i27;
+      i26 = i26 & (i32 | 0 - i32);
+      if ((i26 | 0) == 0) {
+       break;
+      }
+      i32 = (i26 & 0 - i26) + -1 | 0;
+      i28 = i32 >>> 12 & 16;
+      i32 = i32 >>> i28;
+      i27 = i32 >>> 5 & 8;
+      i32 = i32 >>> i27;
+      i30 = i32 >>> 2 & 4;
+      i32 = i32 >>> i30;
+      i31 = i32 >>> 1 & 2;
+      i32 = i32 >>> i31;
+      i29 = i32 >>> 1 & 1;
+      i29 = HEAP32[888 + ((i27 | i28 | i30 | i31 | i29) + (i32 >>> i29) << 2) >> 2] | 0;
+     }
+     if ((i29 | 0) != 0) {
+      while (1) {
+       i27 = (HEAP32[i29 + 4 >> 2] & -8) - i12 | 0;
+       i26 = i27 >>> 0 < i25 >>> 0;
+       i25 = i26 ? i27 : i25;
+       i24 = i26 ? i29 : i24;
+       i26 = HEAP32[i29 + 16 >> 2] | 0;
+       if ((i26 | 0) != 0) {
+        i29 = i26;
+        continue;
+       }
+       i29 = HEAP32[i29 + 20 >> 2] | 0;
+       if ((i29 | 0) == 0) {
+        break;
+       }
+      }
+     }
+     if ((i24 | 0) != 0 ? i25 >>> 0 < ((HEAP32[592 >> 2] | 0) - i12 | 0) >>> 0 : 0) {
+      i4 = HEAP32[600 >> 2] | 0;
+      if (i24 >>> 0 < i4 >>> 0) {
+       _abort();
+      }
+      i2 = i24 + i12 | 0;
+      if (!(i24 >>> 0 < i2 >>> 0)) {
+       _abort();
+      }
+      i3 = HEAP32[i24 + 24 >> 2] | 0;
+      i6 = HEAP32[i24 + 12 >> 2] | 0;
+      do {
+       if ((i6 | 0) == (i24 | 0)) {
+        i6 = i24 + 20 | 0;
+        i5 = HEAP32[i6 >> 2] | 0;
+        if ((i5 | 0) == 0) {
+         i6 = i24 + 16 | 0;
+         i5 = HEAP32[i6 >> 2] | 0;
+         if ((i5 | 0) == 0) {
+          i22 = 0;
+          break;
+         }
+        }
+        while (1) {
+         i8 = i5 + 20 | 0;
+         i7 = HEAP32[i8 >> 2] | 0;
+         if ((i7 | 0) != 0) {
+          i5 = i7;
+          i6 = i8;
+          continue;
+         }
+         i7 = i5 + 16 | 0;
+         i8 = HEAP32[i7 >> 2] | 0;
+         if ((i8 | 0) == 0) {
+          break;
+         } else {
+          i5 = i8;
+          i6 = i7;
+         }
+        }
+        if (i6 >>> 0 < i4 >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i6 >> 2] = 0;
+         i22 = i5;
+         break;
+        }
+       } else {
+        i5 = HEAP32[i24 + 8 >> 2] | 0;
+        if (i5 >>> 0 < i4 >>> 0) {
+         _abort();
+        }
+        i7 = i5 + 12 | 0;
+        if ((HEAP32[i7 >> 2] | 0) != (i24 | 0)) {
+         _abort();
+        }
+        i4 = i6 + 8 | 0;
+        if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
+         HEAP32[i7 >> 2] = i6;
+         HEAP32[i4 >> 2] = i5;
+         i22 = i6;
+         break;
+        } else {
+         _abort();
+        }
+       }
+      } while (0);
+      do {
+       if ((i3 | 0) != 0) {
+        i4 = HEAP32[i24 + 28 >> 2] | 0;
+        i5 = 888 + (i4 << 2) | 0;
+        if ((i24 | 0) == (HEAP32[i5 >> 2] | 0)) {
+         HEAP32[i5 >> 2] = i22;
+         if ((i22 | 0) == 0) {
+          HEAP32[588 >> 2] = HEAP32[588 >> 2] & ~(1 << i4);
+          break;
+         }
+        } else {
+         if (i3 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+          _abort();
+         }
+         i4 = i3 + 16 | 0;
+         if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
+          HEAP32[i4 >> 2] = i22;
+         } else {
+          HEAP32[i3 + 20 >> 2] = i22;
+         }
+         if ((i22 | 0) == 0) {
+          break;
+         }
+        }
+        if (i22 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+         _abort();
+        }
+        HEAP32[i22 + 24 >> 2] = i3;
+        i3 = HEAP32[i24 + 16 >> 2] | 0;
+        do {
+         if ((i3 | 0) != 0) {
+          if (i3 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           HEAP32[i22 + 16 >> 2] = i3;
+           HEAP32[i3 + 24 >> 2] = i22;
+           break;
+          }
+         }
+        } while (0);
+        i3 = HEAP32[i24 + 20 >> 2] | 0;
+        if ((i3 | 0) != 0) {
+         if (i3 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i22 + 20 >> 2] = i3;
+          HEAP32[i3 + 24 >> 2] = i22;
+          break;
+         }
+        }
+       }
+      } while (0);
+      L204 : do {
+       if (!(i25 >>> 0 < 16)) {
+        HEAP32[i24 + 4 >> 2] = i12 | 3;
+        HEAP32[i24 + (i12 | 4) >> 2] = i25 | 1;
+        HEAP32[i24 + (i25 + i12) >> 2] = i25;
+        i4 = i25 >>> 3;
+        if (i25 >>> 0 < 256) {
+         i6 = i4 << 1;
+         i3 = 624 + (i6 << 2) | 0;
+         i5 = HEAP32[146] | 0;
+         i4 = 1 << i4;
+         if ((i5 & i4 | 0) != 0) {
+          i5 = 624 + (i6 + 2 << 2) | 0;
+          i4 = HEAP32[i5 >> 2] | 0;
+          if (i4 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           i21 = i5;
+           i20 = i4;
+          }
+         } else {
+          HEAP32[146] = i5 | i4;
+          i21 = 624 + (i6 + 2 << 2) | 0;
+          i20 = i3;
+         }
+         HEAP32[i21 >> 2] = i2;
+         HEAP32[i20 + 12 >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i20;
+         HEAP32[i24 + (i12 + 12) >> 2] = i3;
+         break;
+        }
+        i3 = i25 >>> 8;
+        if ((i3 | 0) != 0) {
+         if (i25 >>> 0 > 16777215) {
+          i3 = 31;
+         } else {
+          i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+          i32 = i3 << i31;
+          i30 = (i32 + 520192 | 0) >>> 16 & 4;
+          i32 = i32 << i30;
+          i3 = (i32 + 245760 | 0) >>> 16 & 2;
+          i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+          i3 = i25 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+         }
+        } else {
+         i3 = 0;
+        }
+        i6 = 888 + (i3 << 2) | 0;
+        HEAP32[i24 + (i12 + 28) >> 2] = i3;
+        HEAP32[i24 + (i12 + 20) >> 2] = 0;
+        HEAP32[i24 + (i12 + 16) >> 2] = 0;
+        i4 = HEAP32[588 >> 2] | 0;
+        i5 = 1 << i3;
+        if ((i4 & i5 | 0) == 0) {
+         HEAP32[588 >> 2] = i4 | i5;
+         HEAP32[i6 >> 2] = i2;
+         HEAP32[i24 + (i12 + 24) >> 2] = i6;
+         HEAP32[i24 + (i12 + 12) >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i2;
+         break;
+        }
+        i4 = HEAP32[i6 >> 2] | 0;
+        if ((i3 | 0) == 31) {
+         i3 = 0;
+        } else {
+         i3 = 25 - (i3 >>> 1) | 0;
+        }
+        L225 : do {
+         if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i25 | 0)) {
+          i3 = i25 << i3;
+          while (1) {
+           i6 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+           i5 = HEAP32[i6 >> 2] | 0;
+           if ((i5 | 0) == 0) {
+            break;
+           }
+           if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i25 | 0)) {
+            i18 = i5;
+            break L225;
+           } else {
+            i3 = i3 << 1;
+            i4 = i5;
+           }
+          }
+          if (i6 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           HEAP32[i6 >> 2] = i2;
+           HEAP32[i24 + (i12 + 24) >> 2] = i4;
+           HEAP32[i24 + (i12 + 12) >> 2] = i2;
+           HEAP32[i24 + (i12 + 8) >> 2] = i2;
+           break L204;
+          }
+         } else {
+          i18 = i4;
+         }
+        } while (0);
+        i4 = i18 + 8 | 0;
+        i3 = HEAP32[i4 >> 2] | 0;
+        i5 = HEAP32[600 >> 2] | 0;
+        if (i18 >>> 0 < i5 >>> 0) {
+         _abort();
+        }
+        if (i3 >>> 0 < i5 >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i3 + 12 >> 2] = i2;
+         HEAP32[i4 >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i3;
+         HEAP32[i24 + (i12 + 12) >> 2] = i18;
+         HEAP32[i24 + (i12 + 24) >> 2] = 0;
+         break;
+        }
+       } else {
+        i32 = i25 + i12 | 0;
+        HEAP32[i24 + 4 >> 2] = i32 | 3;
+        i32 = i24 + (i32 + 4) | 0;
+        HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+       }
+      } while (0);
+      i32 = i24 + 8 | 0;
+      STACKTOP = i1;
+      return i32 | 0;
+     }
+    }
+   } else {
+    i12 = -1;
+   }
+  }
+ } while (0);
+ i18 = HEAP32[592 >> 2] | 0;
+ if (!(i12 >>> 0 > i18 >>> 0)) {
+  i3 = i18 - i12 | 0;
+  i2 = HEAP32[604 >> 2] | 0;
+  if (i3 >>> 0 > 15) {
+   HEAP32[604 >> 2] = i2 + i12;
+   HEAP32[592 >> 2] = i3;
+   HEAP32[i2 + (i12 + 4) >> 2] = i3 | 1;
+   HEAP32[i2 + i18 >> 2] = i3;
+   HEAP32[i2 + 4 >> 2] = i12 | 3;
+  } else {
+   HEAP32[592 >> 2] = 0;
+   HEAP32[604 >> 2] = 0;
+   HEAP32[i2 + 4 >> 2] = i18 | 3;
+   i32 = i2 + (i18 + 4) | 0;
+   HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+  }
+  i32 = i2 + 8 | 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ i18 = HEAP32[596 >> 2] | 0;
+ if (i12 >>> 0 < i18 >>> 0) {
+  i31 = i18 - i12 | 0;
+  HEAP32[596 >> 2] = i31;
+  i32 = HEAP32[608 >> 2] | 0;
+  HEAP32[608 >> 2] = i32 + i12;
+  HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
+  HEAP32[i32 + 4 >> 2] = i12 | 3;
+  i32 = i32 + 8 | 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ do {
+  if ((HEAP32[264] | 0) == 0) {
+   i18 = _sysconf(30) | 0;
+   if ((i18 + -1 & i18 | 0) == 0) {
+    HEAP32[1064 >> 2] = i18;
+    HEAP32[1060 >> 2] = i18;
+    HEAP32[1068 >> 2] = -1;
+    HEAP32[1072 >> 2] = -1;
+    HEAP32[1076 >> 2] = 0;
+    HEAP32[1028 >> 2] = 0;
+    HEAP32[264] = (_time(0) | 0) & -16 ^ 1431655768;
+    break;
+   } else {
+    _abort();
+   }
+  }
+ } while (0);
+ i20 = i12 + 48 | 0;
+ i25 = HEAP32[1064 >> 2] | 0;
+ i21 = i12 + 47 | 0;
+ i22 = i25 + i21 | 0;
+ i25 = 0 - i25 | 0;
+ i18 = i22 & i25;
+ if (!(i18 >>> 0 > i12 >>> 0)) {
+  i32 = 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ i24 = HEAP32[1024 >> 2] | 0;
+ if ((i24 | 0) != 0 ? (i31 = HEAP32[1016 >> 2] | 0, i32 = i31 + i18 | 0, i32 >>> 0 <= i31 >>> 0 | i32 >>> 0 > i24 >>> 0) : 0) {
+  i32 = 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ L269 : do {
+  if ((HEAP32[1028 >> 2] & 4 | 0) == 0) {
+   i26 = HEAP32[608 >> 2] | 0;
+   L271 : do {
+    if ((i26 | 0) != 0) {
+     i24 = 1032 | 0;
+     while (1) {
+      i27 = HEAP32[i24 >> 2] | 0;
+      if (!(i27 >>> 0 > i26 >>> 0) ? (i23 = i24 + 4 | 0, (i27 + (HEAP32[i23 >> 2] | 0) | 0) >>> 0 > i26 >>> 0) : 0) {
+       break;
+      }
+      i24 = HEAP32[i24 + 8 >> 2] | 0;
+      if ((i24 | 0) == 0) {
+       i13 = 182;
+       break L271;
+      }
+     }
+     if ((i24 | 0) != 0) {
+      i25 = i22 - (HEAP32[596 >> 2] | 0) & i25;
+      if (i25 >>> 0 < 2147483647) {
+       i13 = _sbrk(i25 | 0) | 0;
+       i26 = (i13 | 0) == ((HEAP32[i24 >> 2] | 0) + (HEAP32[i23 >> 2] | 0) | 0);
+       i22 = i13;
+       i24 = i25;
+       i23 = i26 ? i13 : -1;
+       i25 = i26 ? i25 : 0;
+       i13 = 191;
+      } else {
+       i25 = 0;
+      }
+     } else {
+      i13 = 182;
+     }
+    } else {
+     i13 = 182;
+    }
+   } while (0);
+   do {
+    if ((i13 | 0) == 182) {
+     i23 = _sbrk(0) | 0;
+     if ((i23 | 0) != (-1 | 0)) {
+      i24 = i23;
+      i22 = HEAP32[1060 >> 2] | 0;
+      i25 = i22 + -1 | 0;
+      if ((i25 & i24 | 0) == 0) {
+       i25 = i18;
+      } else {
+       i25 = i18 - i24 + (i25 + i24 & 0 - i22) | 0;
+      }
+      i24 = HEAP32[1016 >> 2] | 0;
+      i26 = i24 + i25 | 0;
+      if (i25 >>> 0 > i12 >>> 0 & i25 >>> 0 < 2147483647) {
+       i22 = HEAP32[1024 >> 2] | 0;
+       if ((i22 | 0) != 0 ? i26 >>> 0 <= i24 >>> 0 | i26 >>> 0 > i22 >>> 0 : 0) {
+        i25 = 0;
+        break;
+       }
+       i22 = _sbrk(i25 | 0) | 0;
+       i13 = (i22 | 0) == (i23 | 0);
+       i24 = i25;
+       i23 = i13 ? i23 : -1;
+       i25 = i13 ? i25 : 0;
+       i13 = 191;
+      } else {
+       i25 = 0;
+      }
+     } else {
+      i25 = 0;
+     }
+    }
+   } while (0);
+   L291 : do {
+    if ((i13 | 0) == 191) {
+     i13 = 0 - i24 | 0;
+     if ((i23 | 0) != (-1 | 0)) {
+      i17 = i23;
+      i14 = i25;
+      i13 = 202;
+      break L269;
+     }
+     do {
+      if ((i22 | 0) != (-1 | 0) & i24 >>> 0 < 2147483647 & i24 >>> 0 < i20 >>> 0 ? (i19 = HEAP32[1064 >> 2] | 0, i19 = i21 - i24 + i19 & 0 - i19, i19 >>> 0 < 2147483647) : 0) {
+       if ((_sbrk(i19 | 0) | 0) == (-1 | 0)) {
+        _sbrk(i13 | 0) | 0;
+        break L291;
+       } else {
+        i24 = i19 + i24 | 0;
+        break;
+       }
+      }
+     } while (0);
+     if ((i22 | 0) != (-1 | 0)) {
+      i17 = i22;
+      i14 = i24;
+      i13 = 202;
+      break L269;
+     }
+    }
+   } while (0);
+   HEAP32[1028 >> 2] = HEAP32[1028 >> 2] | 4;
+   i13 = 199;
+  } else {
+   i25 = 0;
+   i13 = 199;
+  }
+ } while (0);
+ if ((((i13 | 0) == 199 ? i18 >>> 0 < 2147483647 : 0) ? (i17 = _sbrk(i18 | 0) | 0, i16 = _sbrk(0) | 0, (i16 | 0) != (-1 | 0) & (i17 | 0) != (-1 | 0) & i17 >>> 0 < i16 >>> 0) : 0) ? (i15 = i16 - i17 | 0, i14 = i15 >>> 0 > (i12 + 40 | 0) >>> 0, i14) : 0) {
+  i14 = i14 ? i15 : i25;
+  i13 = 202;
+ }
+ if ((i13 | 0) == 202) {
+  i15 = (HEAP32[1016 >> 2] | 0) + i14 | 0;
+  HEAP32[1016 >> 2] = i15;
+  if (i15 >>> 0 > (HEAP32[1020 >> 2] | 0) >>> 0) {
+   HEAP32[1020 >> 2] = i15;
+  }
+  i15 = HEAP32[608 >> 2] | 0;
+  L311 : do {
+   if ((i15 | 0) != 0) {
+    i21 = 1032 | 0;
+    while (1) {
+     i16 = HEAP32[i21 >> 2] | 0;
+     i19 = i21 + 4 | 0;
+     i20 = HEAP32[i19 >> 2] | 0;
+     if ((i17 | 0) == (i16 + i20 | 0)) {
+      i13 = 214;
+      break;
+     }
+     i18 = HEAP32[i21 + 8 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      break;
+     } else {
+      i21 = i18;
+     }
+    }
+    if (((i13 | 0) == 214 ? (HEAP32[i21 + 12 >> 2] & 8 | 0) == 0 : 0) ? i15 >>> 0 >= i16 >>> 0 & i15 >>> 0 < i17 >>> 0 : 0) {
+     HEAP32[i19 >> 2] = i20 + i14;
+     i2 = (HEAP32[596 >> 2] | 0) + i14 | 0;
+     i3 = i15 + 8 | 0;
+     if ((i3 & 7 | 0) == 0) {
+      i3 = 0;
+     } else {
+      i3 = 0 - i3 & 7;
+     }
+     i32 = i2 - i3 | 0;
+     HEAP32[608 >> 2] = i15 + i3;
+     HEAP32[596 >> 2] = i32;
+     HEAP32[i15 + (i3 + 4) >> 2] = i32 | 1;
+     HEAP32[i15 + (i2 + 4) >> 2] = 40;
+     HEAP32[612 >> 2] = HEAP32[1072 >> 2];
+     break;
+    }
+    if (i17 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+     HEAP32[600 >> 2] = i17;
+    }
+    i19 = i17 + i14 | 0;
+    i16 = 1032 | 0;
+    while (1) {
+     if ((HEAP32[i16 >> 2] | 0) == (i19 | 0)) {
+      i13 = 224;
+      break;
+     }
+     i18 = HEAP32[i16 + 8 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      break;
+     } else {
+      i16 = i18;
+     }
+    }
+    if ((i13 | 0) == 224 ? (HEAP32[i16 + 12 >> 2] & 8 | 0) == 0 : 0) {
+     HEAP32[i16 >> 2] = i17;
+     i6 = i16 + 4 | 0;
+     HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i14;
+     i6 = i17 + 8 | 0;
+     if ((i6 & 7 | 0) == 0) {
+      i6 = 0;
+     } else {
+      i6 = 0 - i6 & 7;
+     }
+     i7 = i17 + (i14 + 8) | 0;
+     if ((i7 & 7 | 0) == 0) {
+      i13 = 0;
+     } else {
+      i13 = 0 - i7 & 7;
+     }
+     i15 = i17 + (i13 + i14) | 0;
+     i8 = i6 + i12 | 0;
+     i7 = i17 + i8 | 0;
+     i10 = i15 - (i17 + i6) - i12 | 0;
+     HEAP32[i17 + (i6 + 4) >> 2] = i12 | 3;
+     L348 : do {
+      if ((i15 | 0) != (HEAP32[608 >> 2] | 0)) {
+       if ((i15 | 0) == (HEAP32[604 >> 2] | 0)) {
+        i32 = (HEAP32[592 >> 2] | 0) + i10 | 0;
+        HEAP32[592 >> 2] = i32;
+        HEAP32[604 >> 2] = i7;
+        HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
+        HEAP32[i17 + (i32 + i8) >> 2] = i32;
+        break;
+       }
+       i12 = i14 + 4 | 0;
+       i18 = HEAP32[i17 + (i12 + i13) >> 2] | 0;
+       if ((i18 & 3 | 0) == 1) {
+        i11 = i18 & -8;
+        i16 = i18 >>> 3;
+        do {
+         if (!(i18 >>> 0 < 256)) {
+          i9 = HEAP32[i17 + ((i13 | 24) + i14) >> 2] | 0;
+          i19 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
+          do {
+           if ((i19 | 0) == (i15 | 0)) {
+            i19 = i13 | 16;
+            i18 = i17 + (i12 + i19) | 0;
+            i16 = HEAP32[i18 >> 2] | 0;
+            if ((i16 | 0) == 0) {
+             i18 = i17 + (i19 + i14) | 0;
+             i16 = HEAP32[i18 >> 2] | 0;
+             if ((i16 | 0) == 0) {
+              i5 = 0;
+              break;
+             }
+            }
+            while (1) {
+             i20 = i16 + 20 | 0;
+             i19 = HEAP32[i20 >> 2] | 0;
+             if ((i19 | 0) != 0) {
+              i16 = i19;
+              i18 = i20;
+              continue;
+             }
+             i19 = i16 + 16 | 0;
+             i20 = HEAP32[i19 >> 2] | 0;
+             if ((i20 | 0) == 0) {
+              break;
+             } else {
+              i16 = i20;
+              i18 = i19;
+             }
+            }
+            if (i18 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+             _abort();
+            } else {
+             HEAP32[i18 >> 2] = 0;
+             i5 = i16;
+             break;
+            }
+           } else {
+            i18 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
+            if (i18 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+             _abort();
+            }
+            i16 = i18 + 12 | 0;
+            if ((HEAP32[i16 >> 2] | 0) != (i15 | 0)) {
+             _abort();
+            }
+            i20 = i19 + 8 | 0;
+            if ((HEAP32[i20 >> 2] | 0) == (i15 | 0)) {
+             HEAP32[i16 >> 2] = i19;
+             HEAP32[i20 >> 2] = i18;
+             i5 = i19;
+             break;
+            } else {
+             _abort();
+            }
+           }
+          } while (0);
+          if ((i9 | 0) != 0) {
+           i16 = HEAP32[i17 + (i14 + 28 + i13) >> 2] | 0;
+           i18 = 888 + (i16 << 2) | 0;
+           if ((i15 | 0) == (HEAP32[i18 >> 2] | 0)) {
+            HEAP32[i18 >> 2] = i5;
+            if ((i5 | 0) == 0) {
+             HEAP32[588 >> 2] = HEAP32[588 >> 2] & ~(1 << i16);
+             break;
+            }
+           } else {
+            if (i9 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+             _abort();
+            }
+            i16 = i9 + 16 | 0;
+            if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
+             HEAP32[i16 >> 2] = i5;
+            } else {
+             HEAP32[i9 + 20 >> 2] = i5;
+            }
+            if ((i5 | 0) == 0) {
+             break;
+            }
+           }
+           if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           HEAP32[i5 + 24 >> 2] = i9;
+           i15 = i13 | 16;
+           i9 = HEAP32[i17 + (i15 + i14) >> 2] | 0;
+           do {
+            if ((i9 | 0) != 0) {
+             if (i9 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+              _abort();
+             } else {
+              HEAP32[i5 + 16 >> 2] = i9;
+              HEAP32[i9 + 24 >> 2] = i5;
+              break;
+             }
+            }
+           } while (0);
+           i9 = HEAP32[i17 + (i12 + i15) >> 2] | 0;
+           if ((i9 | 0) != 0) {
+            if (i9 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+             _abort();
+            } else {
+             HEAP32[i5 + 20 >> 2] = i9;
+             HEAP32[i9 + 24 >> 2] = i5;
+             break;
+            }
+           }
+          }
+         } else {
+          i5 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
+          i12 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
+          i18 = 624 + (i16 << 1 << 2) | 0;
+          if ((i5 | 0) != (i18 | 0)) {
+           if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           if ((HEAP32[i5 + 12 >> 2] | 0) != (i15 | 0)) {
+            _abort();
+           }
+          }
+          if ((i12 | 0) == (i5 | 0)) {
+           HEAP32[146] = HEAP32[146] & ~(1 << i16);
+           break;
+          }
+          if ((i12 | 0) != (i18 | 0)) {
+           if (i12 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           i16 = i12 + 8 | 0;
+           if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
+            i9 = i16;
+           } else {
+            _abort();
+           }
+          } else {
+           i9 = i12 + 8 | 0;
+          }
+          HEAP32[i5 + 12 >> 2] = i12;
+          HEAP32[i9 >> 2] = i5;
+         }
+        } while (0);
+        i15 = i17 + ((i11 | i13) + i14) | 0;
+        i10 = i11 + i10 | 0;
+       }
+       i5 = i15 + 4 | 0;
+       HEAP32[i5 >> 2] = HEAP32[i5 >> 2] & -2;
+       HEAP32[i17 + (i8 + 4) >> 2] = i10 | 1;
+       HEAP32[i17 + (i10 + i8) >> 2] = i10;
+       i5 = i10 >>> 3;
+       if (i10 >>> 0 < 256) {
+        i10 = i5 << 1;
+        i2 = 624 + (i10 << 2) | 0;
+        i9 = HEAP32[146] | 0;
+        i5 = 1 << i5;
+        if ((i9 & i5 | 0) != 0) {
+         i9 = 624 + (i10 + 2 << 2) | 0;
+         i5 = HEAP32[i9 >> 2] | 0;
+         if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          i3 = i9;
+          i4 = i5;
+         }
+        } else {
+         HEAP32[146] = i9 | i5;
+         i3 = 624 + (i10 + 2 << 2) | 0;
+         i4 = i2;
+        }
+        HEAP32[i3 >> 2] = i7;
+        HEAP32[i4 + 12 >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i4;
+        HEAP32[i17 + (i8 + 12) >> 2] = i2;
+        break;
+       }
+       i3 = i10 >>> 8;
+       if ((i3 | 0) != 0) {
+        if (i10 >>> 0 > 16777215) {
+         i3 = 31;
+        } else {
+         i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+         i32 = i3 << i31;
+         i30 = (i32 + 520192 | 0) >>> 16 & 4;
+         i32 = i32 << i30;
+         i3 = (i32 + 245760 | 0) >>> 16 & 2;
+         i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+         i3 = i10 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+        }
+       } else {
+        i3 = 0;
+       }
+       i4 = 888 + (i3 << 2) | 0;
+       HEAP32[i17 + (i8 + 28) >> 2] = i3;
+       HEAP32[i17 + (i8 + 20) >> 2] = 0;
+       HEAP32[i17 + (i8 + 16) >> 2] = 0;
+       i9 = HEAP32[588 >> 2] | 0;
+       i5 = 1 << i3;
+       if ((i9 & i5 | 0) == 0) {
+        HEAP32[588 >> 2] = i9 | i5;
+        HEAP32[i4 >> 2] = i7;
+        HEAP32[i17 + (i8 + 24) >> 2] = i4;
+        HEAP32[i17 + (i8 + 12) >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i7;
+        break;
+       }
+       i4 = HEAP32[i4 >> 2] | 0;
+       if ((i3 | 0) == 31) {
+        i3 = 0;
+       } else {
+        i3 = 25 - (i3 >>> 1) | 0;
+       }
+       L444 : do {
+        if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i10 | 0)) {
+         i3 = i10 << i3;
+         while (1) {
+          i5 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+          i9 = HEAP32[i5 >> 2] | 0;
+          if ((i9 | 0) == 0) {
+           break;
+          }
+          if ((HEAP32[i9 + 4 >> 2] & -8 | 0) == (i10 | 0)) {
+           i2 = i9;
+           break L444;
+          } else {
+           i3 = i3 << 1;
+           i4 = i9;
+          }
+         }
+         if (i5 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i5 >> 2] = i7;
+          HEAP32[i17 + (i8 + 24) >> 2] = i4;
+          HEAP32[i17 + (i8 + 12) >> 2] = i7;
+          HEAP32[i17 + (i8 + 8) >> 2] = i7;
+          break L348;
+         }
+        } else {
+         i2 = i4;
+        }
+       } while (0);
+       i4 = i2 + 8 | 0;
+       i3 = HEAP32[i4 >> 2] | 0;
+       i5 = HEAP32[600 >> 2] | 0;
+       if (i2 >>> 0 < i5 >>> 0) {
+        _abort();
+       }
+       if (i3 >>> 0 < i5 >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i3 + 12 >> 2] = i7;
+        HEAP32[i4 >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i3;
+        HEAP32[i17 + (i8 + 12) >> 2] = i2;
+        HEAP32[i17 + (i8 + 24) >> 2] = 0;
+        break;
+       }
+      } else {
+       i32 = (HEAP32[596 >> 2] | 0) + i10 | 0;
+       HEAP32[596 >> 2] = i32;
+       HEAP32[608 >> 2] = i7;
+       HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
+      }
+     } while (0);
+     i32 = i17 + (i6 | 8) | 0;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+    i3 = 1032 | 0;
+    while (1) {
+     i2 = HEAP32[i3 >> 2] | 0;
+     if (!(i2 >>> 0 > i15 >>> 0) ? (i11 = HEAP32[i3 + 4 >> 2] | 0, i10 = i2 + i11 | 0, i10 >>> 0 > i15 >>> 0) : 0) {
+      break;
+     }
+     i3 = HEAP32[i3 + 8 >> 2] | 0;
+    }
+    i3 = i2 + (i11 + -39) | 0;
+    if ((i3 & 7 | 0) == 0) {
+     i3 = 0;
+    } else {
+     i3 = 0 - i3 & 7;
+    }
+    i2 = i2 + (i11 + -47 + i3) | 0;
+    i2 = i2 >>> 0 < (i15 + 16 | 0) >>> 0 ? i15 : i2;
+    i3 = i2 + 8 | 0;
+    i4 = i17 + 8 | 0;
+    if ((i4 & 7 | 0) == 0) {
+     i4 = 0;
+    } else {
+     i4 = 0 - i4 & 7;
+    }
+    i32 = i14 + -40 - i4 | 0;
+    HEAP32[608 >> 2] = i17 + i4;
+    HEAP32[596 >> 2] = i32;
+    HEAP32[i17 + (i4 + 4) >> 2] = i32 | 1;
+    HEAP32[i17 + (i14 + -36) >> 2] = 40;
+    HEAP32[612 >> 2] = HEAP32[1072 >> 2];
+    HEAP32[i2 + 4 >> 2] = 27;
+    HEAP32[i3 + 0 >> 2] = HEAP32[1032 >> 2];
+    HEAP32[i3 + 4 >> 2] = HEAP32[1036 >> 2];
+    HEAP32[i3 + 8 >> 2] = HEAP32[1040 >> 2];
+    HEAP32[i3 + 12 >> 2] = HEAP32[1044 >> 2];
+    HEAP32[1032 >> 2] = i17;
+    HEAP32[1036 >> 2] = i14;
+    HEAP32[1044 >> 2] = 0;
+    HEAP32[1040 >> 2] = i3;
+    i4 = i2 + 28 | 0;
+    HEAP32[i4 >> 2] = 7;
+    if ((i2 + 32 | 0) >>> 0 < i10 >>> 0) {
+     while (1) {
+      i3 = i4 + 4 | 0;
+      HEAP32[i3 >> 2] = 7;
+      if ((i4 + 8 | 0) >>> 0 < i10 >>> 0) {
+       i4 = i3;
+      } else {
+       break;
+      }
+     }
+    }
+    if ((i2 | 0) != (i15 | 0)) {
+     i2 = i2 - i15 | 0;
+     i3 = i15 + (i2 + 4) | 0;
+     HEAP32[i3 >> 2] = HEAP32[i3 >> 2] & -2;
+     HEAP32[i15 + 4 >> 2] = i2 | 1;
+     HEAP32[i15 + i2 >> 2] = i2;
+     i3 = i2 >>> 3;
+     if (i2 >>> 0 < 256) {
+      i4 = i3 << 1;
+      i2 = 624 + (i4 << 2) | 0;
+      i5 = HEAP32[146] | 0;
+      i3 = 1 << i3;
+      if ((i5 & i3 | 0) != 0) {
+       i4 = 624 + (i4 + 2 << 2) | 0;
+       i3 = HEAP32[i4 >> 2] | 0;
+       if (i3 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        i7 = i4;
+        i8 = i3;
+       }
+      } else {
+       HEAP32[146] = i5 | i3;
+       i7 = 624 + (i4 + 2 << 2) | 0;
+       i8 = i2;
+      }
+      HEAP32[i7 >> 2] = i15;
+      HEAP32[i8 + 12 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i8;
+      HEAP32[i15 + 12 >> 2] = i2;
+      break;
+     }
+     i3 = i2 >>> 8;
+     if ((i3 | 0) != 0) {
+      if (i2 >>> 0 > 16777215) {
+       i3 = 31;
+      } else {
+       i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+       i32 = i3 << i31;
+       i30 = (i32 + 520192 | 0) >>> 16 & 4;
+       i32 = i32 << i30;
+       i3 = (i32 + 245760 | 0) >>> 16 & 2;
+       i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+       i3 = i2 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+      }
+     } else {
+      i3 = 0;
+     }
+     i7 = 888 + (i3 << 2) | 0;
+     HEAP32[i15 + 28 >> 2] = i3;
+     HEAP32[i15 + 20 >> 2] = 0;
+     HEAP32[i15 + 16 >> 2] = 0;
+     i4 = HEAP32[588 >> 2] | 0;
+     i5 = 1 << i3;
+     if ((i4 & i5 | 0) == 0) {
+      HEAP32[588 >> 2] = i4 | i5;
+      HEAP32[i7 >> 2] = i15;
+      HEAP32[i15 + 24 >> 2] = i7;
+      HEAP32[i15 + 12 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i15;
+      break;
+     }
+     i4 = HEAP32[i7 >> 2] | 0;
+     if ((i3 | 0) == 31) {
+      i3 = 0;
+     } else {
+      i3 = 25 - (i3 >>> 1) | 0;
+     }
+     L499 : do {
+      if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i2 | 0)) {
+       i3 = i2 << i3;
+       while (1) {
+        i7 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+        i5 = HEAP32[i7 >> 2] | 0;
+        if ((i5 | 0) == 0) {
+         break;
+        }
+        if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i2 | 0)) {
+         i6 = i5;
+         break L499;
+        } else {
+         i3 = i3 << 1;
+         i4 = i5;
+        }
+       }
+       if (i7 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i7 >> 2] = i15;
+        HEAP32[i15 + 24 >> 2] = i4;
+        HEAP32[i15 + 12 >> 2] = i15;
+        HEAP32[i15 + 8 >> 2] = i15;
+        break L311;
+       }
+      } else {
+       i6 = i4;
+      }
+     } while (0);
+     i4 = i6 + 8 | 0;
+     i3 = HEAP32[i4 >> 2] | 0;
+     i2 = HEAP32[600 >> 2] | 0;
+     if (i6 >>> 0 < i2 >>> 0) {
+      _abort();
+     }
+     if (i3 >>> 0 < i2 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i3 + 12 >> 2] = i15;
+      HEAP32[i4 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i3;
+      HEAP32[i15 + 12 >> 2] = i6;
+      HEAP32[i15 + 24 >> 2] = 0;
+      break;
+     }
+    }
+   } else {
+    i32 = HEAP32[600 >> 2] | 0;
+    if ((i32 | 0) == 0 | i17 >>> 0 < i32 >>> 0) {
+     HEAP32[600 >> 2] = i17;
+    }
+    HEAP32[1032 >> 2] = i17;
+    HEAP32[1036 >> 2] = i14;
+    HEAP32[1044 >> 2] = 0;
+    HEAP32[620 >> 2] = HEAP32[264];
+    HEAP32[616 >> 2] = -1;
+    i2 = 0;
+    do {
+     i32 = i2 << 1;
+     i31 = 624 + (i32 << 2) | 0;
+     HEAP32[624 + (i32 + 3 << 2) >> 2] = i31;
+     HEAP32[624 + (i32 + 2 << 2) >> 2] = i31;
+     i2 = i2 + 1 | 0;
+    } while ((i2 | 0) != 32);
+    i2 = i17 + 8 | 0;
+    if ((i2 & 7 | 0) == 0) {
+     i2 = 0;
+    } else {
+     i2 = 0 - i2 & 7;
+    }
+    i32 = i14 + -40 - i2 | 0;
+    HEAP32[608 >> 2] = i17 + i2;
+    HEAP32[596 >> 2] = i32;
+    HEAP32[i17 + (i2 + 4) >> 2] = i32 | 1;
+    HEAP32[i17 + (i14 + -36) >> 2] = 40;
+    HEAP32[612 >> 2] = HEAP32[1072 >> 2];
+   }
+  } while (0);
+  i2 = HEAP32[596 >> 2] | 0;
+  if (i2 >>> 0 > i12 >>> 0) {
+   i31 = i2 - i12 | 0;
+   HEAP32[596 >> 2] = i31;
+   i32 = HEAP32[608 >> 2] | 0;
+   HEAP32[608 >> 2] = i32 + i12;
+   HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
+   HEAP32[i32 + 4 >> 2] = i12 | 3;
+   i32 = i32 + 8 | 0;
+   STACKTOP = i1;
+   return i32 | 0;
+  }
+ }
+ HEAP32[(___errno_location() | 0) >> 2] = 12;
+ i32 = 0;
+ STACKTOP = i1;
+ return i32 | 0;
+}
+function _free(i7) {
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0;
+ i1 = STACKTOP;
+ if ((i7 | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i15 = i7 + -8 | 0;
+ i16 = HEAP32[600 >> 2] | 0;
+ if (i15 >>> 0 < i16 >>> 0) {
+  _abort();
+ }
+ i13 = HEAP32[i7 + -4 >> 2] | 0;
+ i12 = i13 & 3;
+ if ((i12 | 0) == 1) {
+  _abort();
+ }
+ i8 = i13 & -8;
+ i6 = i7 + (i8 + -8) | 0;
+ do {
+  if ((i13 & 1 | 0) == 0) {
+   i19 = HEAP32[i15 >> 2] | 0;
+   if ((i12 | 0) == 0) {
+    STACKTOP = i1;
+    return;
+   }
+   i15 = -8 - i19 | 0;
+   i13 = i7 + i15 | 0;
+   i12 = i19 + i8 | 0;
+   if (i13 >>> 0 < i16 >>> 0) {
+    _abort();
+   }
+   if ((i13 | 0) == (HEAP32[604 >> 2] | 0)) {
+    i2 = i7 + (i8 + -4) | 0;
+    if ((HEAP32[i2 >> 2] & 3 | 0) != 3) {
+     i2 = i13;
+     i11 = i12;
+     break;
+    }
+    HEAP32[592 >> 2] = i12;
+    HEAP32[i2 >> 2] = HEAP32[i2 >> 2] & -2;
+    HEAP32[i7 + (i15 + 4) >> 2] = i12 | 1;
+    HEAP32[i6 >> 2] = i12;
+    STACKTOP = i1;
+    return;
+   }
+   i18 = i19 >>> 3;
+   if (i19 >>> 0 < 256) {
+    i2 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
+    i11 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
+    i14 = 624 + (i18 << 1 << 2) | 0;
+    if ((i2 | 0) != (i14 | 0)) {
+     if (i2 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i2 + 12 >> 2] | 0) != (i13 | 0)) {
+      _abort();
+     }
+    }
+    if ((i11 | 0) == (i2 | 0)) {
+     HEAP32[146] = HEAP32[146] & ~(1 << i18);
+     i2 = i13;
+     i11 = i12;
+     break;
+    }
+    if ((i11 | 0) != (i14 | 0)) {
+     if (i11 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     i14 = i11 + 8 | 0;
+     if ((HEAP32[i14 >> 2] | 0) == (i13 | 0)) {
+      i17 = i14;
+     } else {
+      _abort();
+     }
+    } else {
+     i17 = i11 + 8 | 0;
+    }
+    HEAP32[i2 + 12 >> 2] = i11;
+    HEAP32[i17 >> 2] = i2;
+    i2 = i13;
+    i11 = i12;
+    break;
+   }
+   i17 = HEAP32[i7 + (i15 + 24) >> 2] | 0;
+   i18 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
+   do {
+    if ((i18 | 0) == (i13 | 0)) {
+     i19 = i7 + (i15 + 20) | 0;
+     i18 = HEAP32[i19 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      i19 = i7 + (i15 + 16) | 0;
+      i18 = HEAP32[i19 >> 2] | 0;
+      if ((i18 | 0) == 0) {
+       i14 = 0;
+       break;
+      }
+     }
+     while (1) {
+      i21 = i18 + 20 | 0;
+      i20 = HEAP32[i21 >> 2] | 0;
+      if ((i20 | 0) != 0) {
+       i18 = i20;
+       i19 = i21;
+       continue;
+      }
+      i20 = i18 + 16 | 0;
+      i21 = HEAP32[i20 >> 2] | 0;
+      if ((i21 | 0) == 0) {
+       break;
+      } else {
+       i18 = i21;
+       i19 = i20;
+      }
+     }
+     if (i19 >>> 0 < i16 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i19 >> 2] = 0;
+      i14 = i18;
+      break;
+     }
+    } else {
+     i19 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
+     if (i19 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     i16 = i19 + 12 | 0;
+     if ((HEAP32[i16 >> 2] | 0) != (i13 | 0)) {
+      _abort();
+     }
+     i20 = i18 + 8 | 0;
+     if ((HEAP32[i20 >> 2] | 0) == (i13 | 0)) {
+      HEAP32[i16 >> 2] = i18;
+      HEAP32[i20 >> 2] = i19;
+      i14 = i18;
+      break;
+     } else {
+      _abort();
+     }
+    }
+   } while (0);
+   if ((i17 | 0) != 0) {
+    i18 = HEAP32[i7 + (i15 + 28) >> 2] | 0;
+    i16 = 888 + (i18 << 2) | 0;
+    if ((i13 | 0) == (HEAP32[i16 >> 2] | 0)) {
+     HEAP32[i16 >> 2] = i14;
+     if ((i14 | 0) == 0) {
+      HEAP32[588 >> 2] = HEAP32[588 >> 2] & ~(1 << i18);
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    } else {
+     if (i17 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i16 = i17 + 16 | 0;
+     if ((HEAP32[i16 >> 2] | 0) == (i13 | 0)) {
+      HEAP32[i16 >> 2] = i14;
+     } else {
+      HEAP32[i17 + 20 >> 2] = i14;
+     }
+     if ((i14 | 0) == 0) {
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    }
+    if (i14 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+     _abort();
+    }
+    HEAP32[i14 + 24 >> 2] = i17;
+    i16 = HEAP32[i7 + (i15 + 16) >> 2] | 0;
+    do {
+     if ((i16 | 0) != 0) {
+      if (i16 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i14 + 16 >> 2] = i16;
+       HEAP32[i16 + 24 >> 2] = i14;
+       break;
+      }
+     }
+    } while (0);
+    i15 = HEAP32[i7 + (i15 + 20) >> 2] | 0;
+    if ((i15 | 0) != 0) {
+     if (i15 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i14 + 20 >> 2] = i15;
+      HEAP32[i15 + 24 >> 2] = i14;
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    } else {
+     i2 = i13;
+     i11 = i12;
+    }
+   } else {
+    i2 = i13;
+    i11 = i12;
+   }
+  } else {
+   i2 = i15;
+   i11 = i8;
+  }
+ } while (0);
+ if (!(i2 >>> 0 < i6 >>> 0)) {
+  _abort();
+ }
+ i12 = i7 + (i8 + -4) | 0;
+ i13 = HEAP32[i12 >> 2] | 0;
+ if ((i13 & 1 | 0) == 0) {
+  _abort();
+ }
+ if ((i13 & 2 | 0) == 0) {
+  if ((i6 | 0) == (HEAP32[608 >> 2] | 0)) {
+   i21 = (HEAP32[596 >> 2] | 0) + i11 | 0;
+   HEAP32[596 >> 2] = i21;
+   HEAP32[608 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i21 | 1;
+   if ((i2 | 0) != (HEAP32[604 >> 2] | 0)) {
+    STACKTOP = i1;
+    return;
+   }
+   HEAP32[604 >> 2] = 0;
+   HEAP32[592 >> 2] = 0;
+   STACKTOP = i1;
+   return;
+  }
+  if ((i6 | 0) == (HEAP32[604 >> 2] | 0)) {
+   i21 = (HEAP32[592 >> 2] | 0) + i11 | 0;
+   HEAP32[592 >> 2] = i21;
+   HEAP32[604 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i21 | 1;
+   HEAP32[i2 + i21 >> 2] = i21;
+   STACKTOP = i1;
+   return;
+  }
+  i11 = (i13 & -8) + i11 | 0;
+  i12 = i13 >>> 3;
+  do {
+   if (!(i13 >>> 0 < 256)) {
+    i10 = HEAP32[i7 + (i8 + 16) >> 2] | 0;
+    i15 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
+    do {
+     if ((i15 | 0) == (i6 | 0)) {
+      i13 = i7 + (i8 + 12) | 0;
+      i12 = HEAP32[i13 >> 2] | 0;
+      if ((i12 | 0) == 0) {
+       i13 = i7 + (i8 + 8) | 0;
+       i12 = HEAP32[i13 >> 2] | 0;
+       if ((i12 | 0) == 0) {
+        i9 = 0;
+        break;
+       }
+      }
+      while (1) {
+       i14 = i12 + 20 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) != 0) {
+        i12 = i15;
+        i13 = i14;
+        continue;
+       }
+       i14 = i12 + 16 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) == 0) {
+        break;
+       } else {
+        i12 = i15;
+        i13 = i14;
+       }
+      }
+      if (i13 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i13 >> 2] = 0;
+       i9 = i12;
+       break;
+      }
+     } else {
+      i13 = HEAP32[i7 + i8 >> 2] | 0;
+      if (i13 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i14 = i13 + 12 | 0;
+      if ((HEAP32[i14 >> 2] | 0) != (i6 | 0)) {
+       _abort();
+      }
+      i12 = i15 + 8 | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+       HEAP32[i14 >> 2] = i15;
+       HEAP32[i12 >> 2] = i13;
+       i9 = i15;
+       break;
+      } else {
+       _abort();
+      }
+     }
+    } while (0);
+    if ((i10 | 0) != 0) {
+     i12 = HEAP32[i7 + (i8 + 20) >> 2] | 0;
+     i13 = 888 + (i12 << 2) | 0;
+     if ((i6 | 0) == (HEAP32[i13 >> 2] | 0)) {
+      HEAP32[i13 >> 2] = i9;
+      if ((i9 | 0) == 0) {
+       HEAP32[588 >> 2] = HEAP32[588 >> 2] & ~(1 << i12);
+       break;
+      }
+     } else {
+      if (i10 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i12 = i10 + 16 | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+       HEAP32[i12 >> 2] = i9;
+      } else {
+       HEAP32[i10 + 20 >> 2] = i9;
+      }
+      if ((i9 | 0) == 0) {
+       break;
+      }
+     }
+     if (i9 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     HEAP32[i9 + 24 >> 2] = i10;
+     i6 = HEAP32[i7 + (i8 + 8) >> 2] | 0;
+     do {
+      if ((i6 | 0) != 0) {
+       if (i6 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i9 + 16 >> 2] = i6;
+        HEAP32[i6 + 24 >> 2] = i9;
+        break;
+       }
+      }
+     } while (0);
+     i6 = HEAP32[i7 + (i8 + 12) >> 2] | 0;
+     if ((i6 | 0) != 0) {
+      if (i6 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i9 + 20 >> 2] = i6;
+       HEAP32[i6 + 24 >> 2] = i9;
+       break;
+      }
+     }
+    }
+   } else {
+    i9 = HEAP32[i7 + i8 >> 2] | 0;
+    i7 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
+    i8 = 624 + (i12 << 1 << 2) | 0;
+    if ((i9 | 0) != (i8 | 0)) {
+     if (i9 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i9 + 12 >> 2] | 0) != (i6 | 0)) {
+      _abort();
+     }
+    }
+    if ((i7 | 0) == (i9 | 0)) {
+     HEAP32[146] = HEAP32[146] & ~(1 << i12);
+     break;
+    }
+    if ((i7 | 0) != (i8 | 0)) {
+     if (i7 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i8 = i7 + 8 | 0;
+     if ((HEAP32[i8 >> 2] | 0) == (i6 | 0)) {
+      i10 = i8;
+     } else {
+      _abort();
+     }
+    } else {
+     i10 = i7 + 8 | 0;
+    }
+    HEAP32[i9 + 12 >> 2] = i7;
+    HEAP32[i10 >> 2] = i9;
+   }
+  } while (0);
+  HEAP32[i2 + 4 >> 2] = i11 | 1;
+  HEAP32[i2 + i11 >> 2] = i11;
+  if ((i2 | 0) == (HEAP32[604 >> 2] | 0)) {
+   HEAP32[592 >> 2] = i11;
+   STACKTOP = i1;
+   return;
+  }
+ } else {
+  HEAP32[i12 >> 2] = i13 & -2;
+  HEAP32[i2 + 4 >> 2] = i11 | 1;
+  HEAP32[i2 + i11 >> 2] = i11;
+ }
+ i6 = i11 >>> 3;
+ if (i11 >>> 0 < 256) {
+  i7 = i6 << 1;
+  i3 = 624 + (i7 << 2) | 0;
+  i8 = HEAP32[146] | 0;
+  i6 = 1 << i6;
+  if ((i8 & i6 | 0) != 0) {
+   i6 = 624 + (i7 + 2 << 2) | 0;
+   i7 = HEAP32[i6 >> 2] | 0;
+   if (i7 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+    _abort();
+   } else {
+    i4 = i6;
+    i5 = i7;
+   }
+  } else {
+   HEAP32[146] = i8 | i6;
+   i4 = 624 + (i7 + 2 << 2) | 0;
+   i5 = i3;
+  }
+  HEAP32[i4 >> 2] = i2;
+  HEAP32[i5 + 12 >> 2] = i2;
+  HEAP32[i2 + 8 >> 2] = i5;
+  HEAP32[i2 + 12 >> 2] = i3;
+  STACKTOP = i1;
+  return;
+ }
+ i4 = i11 >>> 8;
+ if ((i4 | 0) != 0) {
+  if (i11 >>> 0 > 16777215) {
+   i4 = 31;
+  } else {
+   i20 = (i4 + 1048320 | 0) >>> 16 & 8;
+   i21 = i4 << i20;
+   i19 = (i21 + 520192 | 0) >>> 16 & 4;
+   i21 = i21 << i19;
+   i4 = (i21 + 245760 | 0) >>> 16 & 2;
+   i4 = 14 - (i19 | i20 | i4) + (i21 << i4 >>> 15) | 0;
+   i4 = i11 >>> (i4 + 7 | 0) & 1 | i4 << 1;
+  }
+ } else {
+  i4 = 0;
+ }
+ i5 = 888 + (i4 << 2) | 0;
+ HEAP32[i2 + 28 >> 2] = i4;
+ HEAP32[i2 + 20 >> 2] = 0;
+ HEAP32[i2 + 16 >> 2] = 0;
+ i7 = HEAP32[588 >> 2] | 0;
+ i6 = 1 << i4;
+ L199 : do {
+  if ((i7 & i6 | 0) != 0) {
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((i4 | 0) == 31) {
+    i4 = 0;
+   } else {
+    i4 = 25 - (i4 >>> 1) | 0;
+   }
+   L204 : do {
+    if ((HEAP32[i5 + 4 >> 2] & -8 | 0) != (i11 | 0)) {
+     i4 = i11 << i4;
+     i7 = i5;
+     while (1) {
+      i6 = i7 + (i4 >>> 31 << 2) + 16 | 0;
+      i5 = HEAP32[i6 >> 2] | 0;
+      if ((i5 | 0) == 0) {
+       break;
+      }
+      if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i11 | 0)) {
+       i3 = i5;
+       break L204;
+      } else {
+       i4 = i4 << 1;
+       i7 = i5;
+      }
+     }
+     if (i6 >>> 0 < (HEAP32[600 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i6 >> 2] = i2;
+      HEAP32[i2 + 24 >> 2] = i7;
+      HEAP32[i2 + 12 >> 2] = i2;
+      HEAP32[i2 + 8 >> 2] = i2;
+      break L199;
+     }
+    } else {
+     i3 = i5;
+    }
+   } while (0);
+   i5 = i3 + 8 | 0;
+   i4 = HEAP32[i5 >> 2] | 0;
+   i6 = HEAP32[600 >> 2] | 0;
+   if (i3 >>> 0 < i6 >>> 0) {
+    _abort();
+   }
+   if (i4 >>> 0 < i6 >>> 0) {
+    _abort();
+   } else {
+    HEAP32[i4 + 12 >> 2] = i2;
+    HEAP32[i5 >> 2] = i2;
+    HEAP32[i2 + 8 >> 2] = i4;
+    HEAP32[i2 + 12 >> 2] = i3;
+    HEAP32[i2 + 24 >> 2] = 0;
+    break;
+   }
+  } else {
+   HEAP32[588 >> 2] = i7 | i6;
+   HEAP32[i5 >> 2] = i2;
+   HEAP32[i2 + 24 >> 2] = i5;
+   HEAP32[i2 + 12 >> 2] = i2;
+   HEAP32[i2 + 8 >> 2] = i2;
+  }
+ } while (0);
+ i21 = (HEAP32[616 >> 2] | 0) + -1 | 0;
+ HEAP32[616 >> 2] = i21;
+ if ((i21 | 0) == 0) {
+  i2 = 1040 | 0;
+ } else {
+  STACKTOP = i1;
+  return;
+ }
+ while (1) {
+  i2 = HEAP32[i2 >> 2] | 0;
+  if ((i2 | 0) == 0) {
+   break;
+  } else {
+   i2 = i2 + 8 | 0;
+  }
+ }
+ HEAP32[616 >> 2] = -1;
+ STACKTOP = i1;
+ return;
+}
+function _main(i7, i8) {
+ i7 = i7 | 0;
+ i8 = i8 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, d9 = 0.0, d10 = 0.0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 4272 | 0;
+ i3 = i2;
+ i5 = i2 + 4248 | 0;
+ i4 = i2 + 2128 | 0;
+ i1 = i2 + 8 | 0;
+ L1 : do {
+  if ((i7 | 0) > 1) {
+   i7 = HEAP8[HEAP32[i8 + 4 >> 2] | 0] | 0;
+   switch (i7 | 0) {
+   case 50:
+    {
+     i3 = 95e5;
+     break L1;
+    }
+   case 51:
+    {
+     i6 = 4;
+     break L1;
+    }
+   case 52:
+    {
+     i3 = 95e6;
+     break L1;
+    }
+   case 53:
+    {
+     i3 = 19e7;
+     break L1;
+    }
+   case 49:
+    {
+     i3 = 95e4;
+     break L1;
+    }
+   case 48:
+    {
+     i8 = 0;
+     STACKTOP = i2;
+     return i8 | 0;
+    }
+   default:
+    {
+     HEAP32[i3 >> 2] = i7 + -48;
+     _printf(280, i3 | 0) | 0;
+     i8 = -1;
+     STACKTOP = i2;
+     return i8 | 0;
+    }
+   }
+  } else {
+   i6 = 4;
+  }
+ } while (0);
+ if ((i6 | 0) == 4) {
+  i3 = 19e6;
+ }
+ HEAP32[i5 + 8 >> 2] = 0;
+ HEAP32[i5 + 4 >> 2] = 287;
+ i8 = __Znaj(347) | 0;
+ HEAP32[i5 >> 2] = i8;
+ _memcpy(i8 | 0, 296, 287) | 0;
+ i8 = i8 + 287 | 0;
+ i7 = 296 | 0;
+ i6 = i8 + 60 | 0;
+ do {
+  HEAP8[i8] = HEAP8[i7] | 0;
+  i8 = i8 + 1 | 0;
+  i7 = i7 + 1 | 0;
+ } while ((i8 | 0) < (i6 | 0));
+ i7 = i3 << 1;
+ while (1) {
+  i6 = i7 >>> 0 < 60 ? i7 : 60;
+  __ZN14RotatingString5writeEj(i5, i6);
+  if ((i7 | 0) == (i6 | 0)) {
+   break;
+  } else {
+   i7 = i7 - i6 | 0;
+  }
+ }
+ i5 = HEAP32[i5 >> 2] | 0;
+ if ((i5 | 0) != 0) {
+  __ZdaPv(i5);
+ }
+ if ((HEAP32[6] | 0) == 0) {
+  i6 = 24;
+  i5 = 0;
+ } else {
+  i5 = 24;
+  d9 = 0.0;
+  while (1) {
+   i6 = i5 + 4 | 0;
+   d9 = d9 + +HEAPF32[i6 >> 2];
+   d10 = d9 < 1.0 ? d9 : 1.0;
+   HEAPF32[i6 >> 2] = d10;
+   HEAP32[i5 + 8 >> 2] = ~~(d10 * 512.0) >>> 0;
+   i5 = i5 + 12 | 0;
+   if ((HEAP32[i5 >> 2] | 0) == 0) {
+    i6 = 24;
+    i5 = 0;
+    break;
+   }
+  }
+ }
+ do {
+  while (1) {
+   i8 = HEAP32[i6 + 8 >> 2] | 0;
+   if (i5 >>> 0 > i8 >>> 0 & (i8 | 0) != 0) {
+    i6 = i6 + 12 | 0;
+   } else {
+    break;
+   }
+  }
+  HEAP32[i4 + (i5 << 2) >> 2] = i6;
+  i5 = i5 + 1 | 0;
+ } while ((i5 | 0) != 513);
+ HEAP32[i4 + 2116 >> 2] = 0;
+ __Z9makeFastaI10RandomizedEvPKcS2_jRT_(0, 0, i3 * 3 | 0, i4);
+ if ((HEAP32[54] | 0) == 0) {
+  i5 = 216;
+  i4 = 0;
+ } else {
+  i5 = 216;
+  d9 = 0.0;
+  while (1) {
+   i4 = i5 + 4 | 0;
+   d9 = d9 + +HEAPF32[i4 >> 2];
+   d10 = d9 < 1.0 ? d9 : 1.0;
+   HEAPF32[i4 >> 2] = d10;
+   HEAP32[i5 + 8 >> 2] = ~~(d10 * 512.0) >>> 0;
+   i5 = i5 + 12 | 0;
+   if ((HEAP32[i5 >> 2] | 0) == 0) {
+    i5 = 216;
+    i4 = 0;
+    break;
+   }
+  }
+ }
+ do {
+  while (1) {
+   i8 = HEAP32[i5 + 8 >> 2] | 0;
+   if (i4 >>> 0 > i8 >>> 0 & (i8 | 0) != 0) {
+    i5 = i5 + 12 | 0;
+   } else {
+    break;
+   }
+  }
+  HEAP32[i1 + (i4 << 2) >> 2] = i5;
+  i4 = i4 + 1 | 0;
+ } while ((i4 | 0) != 513);
+ HEAP32[i1 + 2116 >> 2] = 0;
+ __Z9makeFastaI10RandomizedEvPKcS2_jRT_(0, 0, i3 * 5 | 0, i1);
+ i8 = 0;
+ STACKTOP = i2;
+ return i8 | 0;
+}
+function __Z9makeFastaI10RandomizedEvPKcS2_jRT_(i3, i2, i6, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ var i4 = 0, i5 = 0, i7 = 0, d8 = 0.0, i9 = 0;
+ i2 = STACKTOP;
+ if ((i6 | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ i4 = i1 + 2116 | 0;
+ i3 = i1 + 2052 | 0;
+ while (1) {
+  i5 = i6 >>> 0 < 60 ? i6 : 60;
+  if ((i5 | 0) != 0) {
+   i7 = 0;
+   do {
+    i9 = ((((HEAP32[4] | 0) * 3877 | 0) + 29573 | 0) >>> 0) % 139968 | 0;
+    HEAP32[4] = i9;
+    d8 = +(i9 >>> 0) / 139968.0;
+    i9 = HEAP32[i1 + (~~(d8 * 512.0) >>> 0 << 2) >> 2] | 0;
+    while (1) {
+     if (+HEAPF32[i9 + 4 >> 2] < d8) {
+      i9 = i9 + 12 | 0;
+     } else {
+      break;
+     }
+    }
+    HEAP8[i1 + i7 + 2052 | 0] = HEAP32[i9 >> 2];
+    i7 = i7 + 1 | 0;
+   } while ((i7 | 0) != (i5 | 0));
+  }
+  HEAP8[i1 + i5 + 2052 | 0] = 10;
+  i9 = i5 + 1 | 0;
+  HEAP8[i1 + i9 + 2052 | 0] = 0;
+  HEAP32[i4 >> 2] = i9;
+  i9 = _strlen(i3 | 0) | 0;
+  i7 = HEAP32[2] | 0;
+  if ((i9 | 0) > (i7 | 0)) {
+   if ((i7 | 0) > 0) {
+    HEAP8[i1 + i7 + 2052 | 0] = 0;
+    _puts(i3 | 0) | 0;
+    HEAP8[i1 + (HEAP32[2] | 0) + 2052 | 0] = 122;
+    HEAP32[2] = 0;
+   }
+  } else {
+   _puts(i3 | 0) | 0;
+   HEAP32[2] = (HEAP32[2] | 0) - i9;
+  }
+  if ((i6 | 0) == (i5 | 0)) {
+   break;
+  } else {
+   i6 = i6 - i5 | 0;
+  }
+ }
+ STACKTOP = i2;
+ return;
+}
+function __ZN14RotatingString5writeEj(i3, i4) {
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i1 = STACKTOP;
+ i5 = __Znaj(i4 + 2 | 0) | 0;
+ i2 = i3 + 8 | 0;
+ _memcpy(i5 | 0, (HEAP32[i3 >> 2] | 0) + (HEAP32[i2 >> 2] | 0) | 0, i4 | 0) | 0;
+ HEAP8[i5 + i4 | 0] = 0;
+ i7 = _strlen(i5 | 0) | 0;
+ i6 = HEAP32[2] | 0;
+ if ((i7 | 0) > (i6 | 0)) {
+  if ((i6 | 0) > 0) {
+   HEAP8[i5 + i6 | 0] = 0;
+   _puts(i5 | 0) | 0;
+   HEAP32[2] = 0;
+   i6 = 6;
+  } else {
+   i6 = 5;
+  }
+ } else {
+  _puts(i5 | 0) | 0;
+  HEAP32[2] = (HEAP32[2] | 0) - i7;
+  i6 = 5;
+ }
+ if ((i6 | 0) == 5 ? (i5 | 0) != 0 : 0) {
+  i6 = 6;
+ }
+ if ((i6 | 0) == 6) {
+  __ZdlPv(i5);
+ }
+ i4 = (HEAP32[i2 >> 2] | 0) + i4 | 0;
+ HEAP32[i2 >> 2] = i4;
+ i3 = HEAP32[i3 + 4 >> 2] | 0;
+ if (!(i4 >>> 0 > i3 >>> 0)) {
+  STACKTOP = i1;
+  return;
+ }
+ HEAP32[i2 >> 2] = i4 - i3;
+ STACKTOP = i1;
+ return;
+}
+function _memcpy(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ if ((i1 | 0) >= 4096) return _emscripten_memcpy_big(i3 | 0, i2 | 0, i1 | 0) | 0;
+ i4 = i3 | 0;
+ if ((i3 & 3) == (i2 & 3)) {
+  while (i3 & 3) {
+   if ((i1 | 0) == 0) return i4 | 0;
+   HEAP8[i3] = HEAP8[i2] | 0;
+   i3 = i3 + 1 | 0;
+   i2 = i2 + 1 | 0;
+   i1 = i1 - 1 | 0;
+  }
+  while ((i1 | 0) >= 4) {
+   HEAP32[i3 >> 2] = HEAP32[i2 >> 2];
+   i3 = i3 + 4 | 0;
+   i2 = i2 + 4 | 0;
+   i1 = i1 - 4 | 0;
+  }
+ }
+ while ((i1 | 0) > 0) {
+  HEAP8[i3] = HEAP8[i2] | 0;
+  i3 = i3 + 1 | 0;
+  i2 = i2 + 1 | 0;
+  i1 = i1 - 1 | 0;
+ }
+ return i4 | 0;
+}
+function _memset(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = i1 + i3 | 0;
+ if ((i3 | 0) >= 20) {
+  i4 = i4 & 255;
+  i7 = i1 & 3;
+  i6 = i4 | i4 << 8 | i4 << 16 | i4 << 24;
+  i5 = i2 & ~3;
+  if (i7) {
+   i7 = i1 + 4 - i7 | 0;
+   while ((i1 | 0) < (i7 | 0)) {
+    HEAP8[i1] = i4;
+    i1 = i1 + 1 | 0;
+   }
+  }
+  while ((i1 | 0) < (i5 | 0)) {
+   HEAP32[i1 >> 2] = i6;
+   i1 = i1 + 4 | 0;
+  }
+ }
+ while ((i1 | 0) < (i2 | 0)) {
+  HEAP8[i1] = i4;
+  i1 = i1 + 1 | 0;
+ }
+ return i1 - i3 | 0;
+}
+function __Znwj(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0;
+ i1 = STACKTOP;
+ i2 = (i2 | 0) == 0 ? 1 : i2;
+ while (1) {
+  i3 = _malloc(i2) | 0;
+  if ((i3 | 0) != 0) {
+   i2 = 6;
+   break;
+  }
+  i3 = HEAP32[270] | 0;
+  HEAP32[270] = i3 + 0;
+  if ((i3 | 0) == 0) {
+   i2 = 5;
+   break;
+  }
+  FUNCTION_TABLE_v[i3 & 0]();
+ }
+ if ((i2 | 0) == 5) {
+  i3 = ___cxa_allocate_exception(4) | 0;
+  HEAP32[i3 >> 2] = 1096;
+  ___cxa_throw(i3 | 0, 1144, 1);
+ } else if ((i2 | 0) == 6) {
+  STACKTOP = i1;
+  return i3 | 0;
+ }
+ return 0;
+}
+function copyTempDouble(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+ HEAP8[tempDoublePtr + 4 | 0] = HEAP8[i1 + 4 | 0];
+ HEAP8[tempDoublePtr + 5 | 0] = HEAP8[i1 + 5 | 0];
+ HEAP8[tempDoublePtr + 6 | 0] = HEAP8[i1 + 6 | 0];
+ HEAP8[tempDoublePtr + 7 | 0] = HEAP8[i1 + 7 | 0];
+}
+function copyTempFloat(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+}
+function __ZNSt9bad_allocD0Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZNSt9exceptionD2Ev(i1 | 0);
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function stackAlloc(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + i1 | 0;
+ STACKTOP = STACKTOP + 7 & -8;
+ return i2 | 0;
+}
+function __ZNSt9bad_allocD2Ev(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZNSt9exceptionD2Ev(i1 | 0);
+ STACKTOP = i2;
+ return;
+}
+function __ZdlPv(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((i1 | 0) != 0) {
+  _free(i1);
+ }
+ STACKTOP = i2;
+ return;
+}
+function _strlen(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = i1;
+ while (HEAP8[i2] | 0) {
+  i2 = i2 + 1 | 0;
+ }
+ return i2 - i1 | 0;
+}
+function setThrew(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ if ((__THREW__ | 0) == 0) {
+  __THREW__ = i1;
+  threwValue = i2;
+ }
+}
+function __Znaj(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i1 = __Znwj(i1) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function runPostSets() {
+ HEAP32[286] = __ZTVN10__cxxabiv120__si_class_type_infoE;
+ HEAP32[288] = __ZTISt9exception;
+}
+function dynCall_ii(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ return FUNCTION_TABLE_ii[i2 & 1](i1 | 0) | 0;
+}
+function __ZdaPv(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ __ZdlPv(i1);
+ STACKTOP = i2;
+ return;
+}
+function dynCall_vi(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ FUNCTION_TABLE_vi[i2 & 3](i1 | 0);
+}
+function dynCall_v(i1) {
+ i1 = i1 | 0;
+ FUNCTION_TABLE_v[i1 & 0]();
+}
+function __ZNKSt9bad_alloc4whatEv(i1) {
+ i1 = i1 | 0;
+ return 1112;
+}
+function stackRestore(i1) {
+ i1 = i1 | 0;
+ STACKTOP = i1;
+}
+function setTempRet9(i1) {
+ i1 = i1 | 0;
+ tempRet9 = i1;
+}
+function setTempRet8(i1) {
+ i1 = i1 | 0;
+ tempRet8 = i1;
+}
+function setTempRet7(i1) {
+ i1 = i1 | 0;
+ tempRet7 = i1;
+}
+function setTempRet6(i1) {
+ i1 = i1 | 0;
+ tempRet6 = i1;
+}
+function setTempRet5(i1) {
+ i1 = i1 | 0;
+ tempRet5 = i1;
+}
+function setTempRet4(i1) {
+ i1 = i1 | 0;
+ tempRet4 = i1;
+}
+function setTempRet3(i1) {
+ i1 = i1 | 0;
+ tempRet3 = i1;
+}
+function setTempRet2(i1) {
+ i1 = i1 | 0;
+ tempRet2 = i1;
+}
+function setTempRet1(i1) {
+ i1 = i1 | 0;
+ tempRet1 = i1;
+}
+function setTempRet0(i1) {
+ i1 = i1 | 0;
+ tempRet0 = i1;
+}
+function b0(i1) {
+ i1 = i1 | 0;
+ abort(0);
+ return 0;
+}
+function stackSave() {
+ return STACKTOP | 0;
+}
+function b1(i1) {
+ i1 = i1 | 0;
+ abort(1);
+}
+function b2() {
+ abort(2);
+}
+
+// EMSCRIPTEN_END_FUNCS
+  var FUNCTION_TABLE_ii = [b0,__ZNKSt9bad_alloc4whatEv];
+  var FUNCTION_TABLE_vi = [b1,__ZNSt9bad_allocD2Ev,__ZNSt9bad_allocD0Ev,b1];
+  var FUNCTION_TABLE_v = [b2];
+
+  return { _strlen: _strlen, _free: _free, _main: _main, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, setTempRet1: setTempRet1, setTempRet2: setTempRet2, setTempRet3: setTempRet3, setTempRet4: setTempRet4, setTempRet5: setTempRet5, setTempRet6: setTempRet6, setTempRet7: setTempRet7, setTempRet8: setTempRet8, setTempRet9: setTempRet9, dynCall_ii: dynCall_ii, dynCall_vi: dynCall_vi, dynCall_v: dynCall_v };
+})
+// EMSCRIPTEN_END_ASM
+({ "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array }, { "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "invoke_ii": invoke_ii, "invoke_vi": invoke_vi, "invoke_v": invoke_v, "_send": _send, "___setErrNo": ___setErrNo, "___cxa_is_number_type": ___cxa_is_number_type, "___cxa_allocate_exception": ___cxa_allocate_exception, "___cxa_find_matching_catch": ___cxa_find_matching_catch, "_fflush": _fflush, "_time": _time, "_pwrite": _pwrite, "__reallyNegative": __reallyNegative, "_sbrk": _sbrk, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_fileno": _fileno, "___resumeException": ___resumeException, "__ZSt18uncaught_exceptionv": __ZSt18uncaught_exceptionv, "_sysconf": _sysconf, "_puts": _puts, "_mkport": _mkport, "_write": _write, "___errno_location": ___errno_location, "__ZNSt9exceptionD2Ev": __ZNSt9exceptionD2Ev, "_fputc": _fputc, "___cxa_throw": ___cxa_throw, "_abort": _abort, "_fwrite": _fwrite, "___cxa_does_inherit": ___cxa_does_inherit, "_fprintf": _fprintf, "__formatString": __formatString, "_fputs": _fputs, "_printf": _printf, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "NaN": NaN, "Infinity": Infinity, "__ZTISt9exception": __ZTISt9exception, "__ZTVN10__cxxabiv120__si_class_type_infoE": __ZTVN10__cxxabiv120__si_class_type_infoE }, buffer);
+var _strlen = Module["_strlen"] = asm["_strlen"];
+var _free = Module["_free"] = asm["_free"];
+var _main = Module["_main"] = asm["_main"];
+var _memset = Module["_memset"] = asm["_memset"];
+var _malloc = Module["_malloc"] = asm["_malloc"];
+var _memcpy = Module["_memcpy"] = asm["_memcpy"];
+var runPostSets = Module["runPostSets"] = asm["runPostSets"];
+var dynCall_ii = Module["dynCall_ii"] = asm["dynCall_ii"];
+var dynCall_vi = Module["dynCall_vi"] = asm["dynCall_vi"];
+var dynCall_v = Module["dynCall_v"] = asm["dynCall_v"];
+
+Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
+Runtime.stackSave = function() { return asm['stackSave']() };
+Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
+
+
+// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included
+var i64Math = null;
+
+// === Auto-generated postamble setup entry stuff ===
+
+if (memoryInitializer) {
+  if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
+    var data = Module['readBinary'](memoryInitializer);
+    HEAPU8.set(data, STATIC_BASE);
+  } else {
+    addRunDependency('memory initializer');
+    Browser.asyncLoad(memoryInitializer, function(data) {
+      HEAPU8.set(data, STATIC_BASE);
+      removeRunDependency('memory initializer');
+    }, function(data) {
+      throw 'could not load memory initializer ' + memoryInitializer;
+    });
+  }
+}
+
+function ExitStatus(status) {
+  this.name = "ExitStatus";
+  this.message = "Program terminated with exit(" + status + ")";
+  this.status = status;
+};
+ExitStatus.prototype = new Error();
+ExitStatus.prototype.constructor = ExitStatus;
+
+var initialStackTop;
+var preloadStartTime = null;
+var calledMain = false;
+
+dependenciesFulfilled = function runCaller() {
+  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
+  if (!Module['calledRun'] && shouldRunNow) run([].concat(Module["arguments"]));
+  if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
+}
+
+Module['callMain'] = Module.callMain = function callMain(args) {
+  assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
+  assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
+
+  args = args || [];
+
+  ensureInitRuntime();
+
+  var argc = args.length+1;
+  function pad() {
+    for (var i = 0; i < 4-1; i++) {
+      argv.push(0);
+    }
+  }
+  var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ];
+  pad();
+  for (var i = 0; i < argc-1; i = i + 1) {
+    argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL));
+    pad();
+  }
+  argv.push(0);
+  argv = allocate(argv, 'i32', ALLOC_NORMAL);
+
+  initialStackTop = STACKTOP;
+
+  try {
+
+    var ret = Module['_main'](argc, argv, 0);
+
+
+    // if we're not running an evented main loop, it's time to exit
+    if (!Module['noExitRuntime']) {
+      exit(ret);
+    }
+  }
+  catch(e) {
+    if (e instanceof ExitStatus) {
+      // exit() throws this once it's done to make sure execution
+      // has been stopped completely
+      return;
+    } else if (e == 'SimulateInfiniteLoop') {
+      // running an evented main loop, don't immediately exit
+      Module['noExitRuntime'] = true;
+      return;
+    } else {
+      if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
+      throw e;
+    }
+  } finally {
+    calledMain = true;
+  }
+}
+
+
+
+
+function run(args) {
+  args = args || Module['arguments'];
+
+  if (preloadStartTime === null) preloadStartTime = Date.now();
+
+  if (runDependencies > 0) {
+    Module.printErr('run() called, but dependencies remain, so not running');
+    return;
+  }
+
+  preRun();
+
+  if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
+  if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
+
+  function doRun() {
+    if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
+    Module['calledRun'] = true;
+
+    ensureInitRuntime();
+
+    preMain();
+
+    if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
+      Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
+    }
+
+    if (Module['_main'] && shouldRunNow) {
+      Module['callMain'](args);
+    }
+
+    postRun();
+  }
+
+  if (Module['setStatus']) {
+    Module['setStatus']('Running...');
+    setTimeout(function() {
+      setTimeout(function() {
+        Module['setStatus']('');
+      }, 1);
+      if (!ABORT) doRun();
+    }, 1);
+  } else {
+    doRun();
+  }
+}
+Module['run'] = Module.run = run;
+
+function exit(status) {
+  ABORT = true;
+  EXITSTATUS = status;
+  STACKTOP = initialStackTop;
+
+  // exit the runtime
+  exitRuntime();
+
+  // TODO We should handle this differently based on environment.
+  // In the browser, the best we can do is throw an exception
+  // to halt execution, but in node we could process.exit and
+  // I'd imagine SM shell would have something equivalent.
+  // This would let us set a proper exit status (which
+  // would be great for checking test exit statuses).
+  // https://github.com/kripken/emscripten/issues/1371
+
+  // throw an exception to halt the current execution
+  throw new ExitStatus(status);
+}
+Module['exit'] = Module.exit = exit;
+
+function abort(text) {
+  if (text) {
+    Module.print(text);
+    Module.printErr(text);
+  }
+
+  ABORT = true;
+  EXITSTATUS = 1;
+
+  var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.';
+
+  throw 'abort() at ' + stackTrace() + extra;
+}
+Module['abort'] = Module.abort = abort;
+
+// {{PRE_RUN_ADDITIONS}}
+
+if (Module['preInit']) {
+  if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
+  while (Module['preInit'].length > 0) {
+    Module['preInit'].pop()();
+  }
+}
+
+// shouldRunNow refers to calling main(), not run().
+var shouldRunNow = true;
+if (Module['noInitialRun']) {
+  shouldRunNow = false;
+}
+
+
+run([].concat(Module["arguments"]));
diff --git a/test/mjsunit/asm/embenchen/lua_binarytrees.js b/test/mjsunit/asm/embenchen/lua_binarytrees.js
new file mode 100644
index 0000000..e3a5d8c
--- /dev/null
+++ b/test/mjsunit/asm/embenchen/lua_binarytrees.js
@@ -0,0 +1,42710 @@
+var EXPECTED_OUTPUT =
+  'stretch tree of depth 10\t check: -1\n' +
+  '1448\t trees of depth 4\t check: -1448\n' +
+  '362\t trees of depth 6\t check: -362\n' +
+  '90\t trees of depth 8\t check: -90\n' +
+  'long lived tree of depth 9\t check: -1\n';
+var Module = {
+  arguments: [1],
+  print: function(x) {Module.printBuffer += x + '\n';},
+  preRun: [function() {Module.printBuffer = ''}],
+  postRun: [function() {
+    assertEquals(EXPECTED_OUTPUT, Module.printBuffer);
+  }],
+};
+
+var Module;
+if (typeof Module === 'undefined') Module = eval('(function() { try { return Module || {} } catch(e) { return {} } })()');
+if (!Module.expectedDataFileDownloads) {
+  Module.expectedDataFileDownloads = 0;
+  Module.finishedDataFileDownloads = 0;
+}
+Module.expectedDataFileDownloads++;
+(function() {
+
+  function runWithFS() {
+
+function assert(check, msg) {
+  if (!check) throw msg + new Error().stack;
+}
+Module['FS_createDataFile']('/', 'binarytrees.lua', [45, 45, 32, 84, 104, 101, 32, 67, 111, 109, 112, 117, 116, 101, 114, 32, 76, 97, 110, 103, 117, 97, 103, 101, 32, 66, 101, 110, 99, 104, 109, 97, 114, 107, 115, 32, 71, 97, 109, 101, 10, 45, 45, 32, 104, 116, 116, 112, 58, 47, 47, 98, 101, 110, 99, 104, 109, 97, 114, 107, 115, 103, 97, 109, 101, 46, 97, 108, 105, 111, 116, 104, 46, 100, 101, 98, 105, 97, 110, 46, 111, 114, 103, 47, 10, 45, 45, 32, 99, 111, 110, 116, 114, 105, 98, 117, 116, 101, 100, 32, 98, 121, 32, 77, 105, 107, 101, 32, 80, 97, 108, 108, 10, 10, 108, 111, 99, 97, 108, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 66, 111, 116, 116, 111, 109, 85, 112, 84, 114, 101, 101, 40, 105, 116, 101, 109, 44, 32, 100, 101, 112, 116, 104, 41, 10, 32, 32, 105, 102, 32, 100, 101, 112, 116, 104, 32, 62, 32, 48, 32, 116, 104, 101, 110, 10, 32, 32, 32, 32, 108, 111, 99, 97, 108, 32, 105, 32, 61, 32, 105, 116, 101, 109, 32, 43, 32, 105, 116, 101, 109, 10, 32, 32, 32, 32, 100, 101, 112, 116, 104, 32, 61, 32, 100, 101, 112, 116, 104, 32, 45, 32, 49, 10, 32, 32, 32, 32, 108, 111, 99, 97, 108, 32, 108, 101, 102, 116, 44, 32, 114, 105, 103, 104, 116, 32, 61, 32, 66, 111, 116, 116, 111, 109, 85, 112, 84, 114, 101, 101, 40, 105, 45, 49, 44, 32, 100, 101, 112, 116, 104, 41, 44, 32, 66, 111, 116, 116, 111, 109, 85, 112, 84, 114, 101, 101, 40, 105, 44, 32, 100, 101, 112, 116, 104, 41, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 123, 32, 105, 116, 101, 109, 44, 32, 108, 101, 102, 116, 44, 32, 114, 105, 103, 104, 116, 32, 125, 10, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 123, 32, 105, 116, 101, 109, 32, 125, 10, 32, 32, 101, 110, 100, 10, 101, 110, 100, 10, 10, 108, 111, 99, 97, 108, 32, 102, 117, 110, 99, 116, 105, 111, 110, 32, 73, 116, 101, 109, 67, 104, 101, 99, 107, 40, 116, 114, 101, 101, 41, 10, 32, 32, 105, 102, 32, 116, 114, 101, 101, 91, 50, 93, 32, 116, 104, 101, 110, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 116, 114, 101, 101, 91, 49, 93, 32, 43, 32, 73, 116, 101, 109, 67, 104, 101, 99, 107, 40, 116, 114, 101, 101, 91, 50, 93, 41, 32, 45, 32, 73, 116, 101, 109, 67, 104, 101, 99, 107, 40, 116, 114, 101, 101, 91, 51, 93, 41, 10, 32, 32, 101, 108, 115, 101, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 116, 114, 101, 101, 91, 49, 93, 10, 32, 32, 101, 110, 100, 10, 101, 110, 100, 10, 10, 108, 111, 99, 97, 108, 32, 78, 32, 61, 32, 116, 111, 110, 117, 109, 98, 101, 114, 40, 97, 114, 103, 32, 97, 110, 100, 32, 97, 114, 103, 91, 49, 93, 41, 32, 111, 114, 32, 52, 10, 10, 105, 102, 32, 78, 32, 61, 61, 32, 48, 32, 116, 104, 101, 110, 10, 32, 32, 78, 32, 61, 32, 48, 10, 101, 108, 115, 101, 105, 102, 32, 78, 32, 61, 61, 32, 49, 32, 116, 104, 101, 110, 10, 32, 32, 78, 32, 61, 32, 57, 46, 53, 10, 101, 108, 115, 101, 105, 102, 32, 78, 32, 61, 61, 32, 50, 32, 116, 104, 101, 110, 10, 32, 32, 78, 32, 61, 32, 49, 49, 46, 57, 57, 10, 101, 108, 115, 101, 105, 102, 32, 78, 32, 61, 61, 32, 51, 32, 116, 104, 101, 110, 10, 32, 32, 78, 32, 61, 32, 49, 50, 46, 56, 53, 10, 101, 108, 115, 101, 105, 102, 32, 78, 32, 61, 61, 32, 52, 32, 116, 104, 101, 110, 10, 32, 32, 78, 32, 61, 32, 49, 52, 46, 55, 50, 10, 101, 108, 115, 101, 105, 102, 32, 78, 32, 61, 61, 32, 53, 32, 116, 104, 101, 110, 10, 32, 32, 78, 32, 61, 32, 49, 53, 46, 56, 50, 10, 101, 110, 100, 10, 10, 108, 111, 99, 97, 108, 32, 109, 105, 110, 100, 101, 112, 116, 104, 32, 61, 32, 52, 10, 108, 111, 99, 97, 108, 32, 109, 97, 120, 100, 101, 112, 116, 104, 32, 61, 32, 109, 105, 110, 100, 101, 112, 116, 104, 32, 43, 32, 50, 10, 105, 102, 32, 109, 97, 120, 100, 101, 112, 116, 104, 32, 60, 32, 78, 32, 116, 104, 101, 110, 32, 109, 97, 120, 100, 101, 112, 116, 104, 32, 61, 32, 78, 32, 101, 110, 100, 10, 10, 100, 111, 10, 32, 32, 108, 111, 99, 97, 108, 32, 115, 116, 114, 101, 116, 99, 104, 100, 101, 112, 116, 104, 32, 61, 32, 109, 97, 120, 100, 101, 112, 116, 104, 32, 43, 32, 49, 10, 32, 32, 108, 111, 99, 97, 108, 32, 115, 116, 114, 101, 116, 99, 104, 116, 114, 101, 101, 32, 61, 32, 66, 111, 116, 116, 111, 109, 85, 112, 84, 114, 101, 101, 40, 48, 44, 32, 115, 116, 114, 101, 116, 99, 104, 100, 101, 112, 116, 104, 41, 10, 32, 32, 105, 111, 46, 119, 114, 105, 116, 101, 40, 115, 116, 114, 105, 110, 103, 46, 102, 111, 114, 109, 97, 116, 40, 34, 115, 116, 114, 101, 116, 99, 104, 32, 116, 114, 101, 101, 32, 111, 102, 32, 100, 101, 112, 116, 104, 32, 37, 100, 92, 116, 32, 99, 104, 101, 99, 107, 58, 32, 37, 100, 92, 110, 34, 44, 10, 32, 32, 32, 32, 115, 116, 114, 101, 116, 99, 104, 100, 101, 112, 116, 104, 44, 32, 73, 116, 101, 109, 67, 104, 101, 99, 107, 40, 115, 116, 114, 101, 116, 99, 104, 116, 114, 101, 101, 41, 41, 41, 10, 101, 110, 100, 10, 10, 108, 111, 99, 97, 108, 32, 108, 111, 110, 103, 108, 105, 118, 101, 100, 116, 114, 101, 101, 32, 61, 32, 66, 111, 116, 116, 111, 109, 85, 112, 84, 114, 101, 101, 40, 48, 44, 32, 109, 97, 120, 100, 101, 112, 116, 104, 41, 10, 10, 102, 111, 114, 32, 100, 101, 112, 116, 104, 61, 109, 105, 110, 100, 101, 112, 116, 104, 44, 109, 97, 120, 100, 101, 112, 116, 104, 44, 50, 32, 100, 111, 10, 32, 32, 108, 111, 99, 97, 108, 32, 105, 116, 101, 114, 97, 116, 105, 111, 110, 115, 32, 61, 32, 50, 32, 94, 32, 40, 109, 97, 120, 100, 101, 112, 116, 104, 32, 45, 32, 100, 101, 112, 116, 104, 32, 43, 32, 109, 105, 110, 100, 101, 112, 116, 104, 41, 10, 32, 32, 108, 111, 99, 97, 108, 32, 99, 104, 101, 99, 107, 32, 61, 32, 48, 10, 32, 32, 102, 111, 114, 32, 105, 61, 49, 44, 105, 116, 101, 114, 97, 116, 105, 111, 110, 115, 32, 100, 111, 10, 32, 32, 32, 32, 99, 104, 101, 99, 107, 32, 61, 32, 99, 104, 101, 99, 107, 32, 43, 32, 73, 116, 101, 109, 67, 104, 101, 99, 107, 40, 66, 111, 116, 116, 111, 109, 85, 112, 84, 114, 101, 101, 40, 49, 44, 32, 100, 101, 112, 116, 104, 41, 41, 32, 43, 10, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 73, 116, 101, 109, 67, 104, 101, 99, 107, 40, 66, 111, 116, 116, 111, 109, 85, 112, 84, 114, 101, 101, 40, 45, 49, 44, 32, 100, 101, 112, 116, 104, 41, 41, 10, 32, 32, 101, 110, 100, 10, 32, 32, 105, 111, 46, 119, 114, 105, 116, 101, 40, 115, 116, 114, 105, 110, 103, 46, 102, 111, 114, 109, 97, 116, 40, 34, 37, 100, 92, 116, 32, 116, 114, 101, 101, 115, 32, 111, 102, 32, 100, 101, 112, 116, 104, 32, 37, 100, 92, 116, 32, 99, 104, 101, 99, 107, 58, 32, 37, 100, 92, 110, 34, 44, 10, 32, 32, 32, 32, 105, 116, 101, 114, 97, 116, 105, 111, 110, 115, 42, 50, 44, 32, 100, 101, 112, 116, 104, 44, 32, 99, 104, 101, 99, 107, 41, 41, 10, 101, 110, 100, 10, 10, 105, 111, 46, 119, 114, 105, 116, 101, 40, 115, 116, 114, 105, 110, 103, 46, 102, 111, 114, 109, 97, 116, 40, 34, 108, 111, 110, 103, 32, 108, 105, 118, 101, 100, 32, 116, 114, 101, 101, 32, 111, 102, 32, 100, 101, 112, 116, 104, 32, 37, 100, 92, 116, 32, 99, 104, 101, 99, 107, 58, 32, 37, 100, 92, 110, 34, 44, 10, 32, 32, 109, 97, 120, 100, 101, 112, 116, 104, 44, 32, 73, 116, 101, 109, 67, 104, 101, 99, 107, 40, 108, 111, 110, 103, 108, 105, 118, 101, 100, 116, 114, 101, 101, 41, 41, 41, 10], true, true);
+
+  }
+  if (Module['calledRun']) {
+    runWithFS();
+  } else {
+    if (!Module['preRun']) Module['preRun'] = [];
+    Module["preRun"].push(runWithFS); // FS is not initialized yet, wait for it
+  }
+
+})();
+
+// The Module object: Our interface to the outside world. We import
+// and export values on it, and do the work to get that through
+// closure compiler if necessary. There are various ways Module can be used:
+// 1. Not defined. We create it here
+// 2. A function parameter, function(Module) { ..generated code.. }
+// 3. pre-run appended it, var Module = {}; ..generated code..
+// 4. External script tag defines var Module.
+// We need to do an eval in order to handle the closure compiler
+// case, where this code here is minified but Module was defined
+// elsewhere (e.g. case 4 above). We also need to check if Module
+// already exists (e.g. case 3 above).
+// Note that if you want to run closure, and also to use Module
+// after the generated code, you will need to define   var Module = {};
+// before the code. Then that object will be used in the code, and you
+// can continue to use Module afterwards as well.
+var Module;
+if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {};
+
+// Sometimes an existing Module object exists with properties
+// meant to overwrite the default module functionality. Here
+// we collect those properties and reapply _after_ we configure
+// the current environment's defaults to avoid having to be so
+// defensive during initialization.
+var moduleOverrides = {};
+for (var key in Module) {
+  if (Module.hasOwnProperty(key)) {
+    moduleOverrides[key] = Module[key];
+  }
+}
+
+// The environment setup code below is customized to use Module.
+// *** Environment setup code ***
+var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
+var ENVIRONMENT_IS_WEB = typeof window === 'object';
+var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
+var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
+
+if (ENVIRONMENT_IS_NODE) {
+  // Expose functionality in the same simple way that the shells work
+  // Note that we pollute the global namespace here, otherwise we break in node
+  if (!Module['print']) Module['print'] = function print(x) {
+    process['stdout'].write(x + '\n');
+  };
+  if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+    process['stderr'].write(x + '\n');
+  };
+
+  var nodeFS = require('fs');
+  var nodePath = require('path');
+
+  Module['read'] = function read(filename, binary) {
+    filename = nodePath['normalize'](filename);
+    var ret = nodeFS['readFileSync'](filename);
+    // The path is absolute if the normalized version is the same as the resolved.
+    if (!ret && filename != nodePath['resolve'](filename)) {
+      filename = path.join(__dirname, '..', 'src', filename);
+      ret = nodeFS['readFileSync'](filename);
+    }
+    if (ret && !binary) ret = ret.toString();
+    return ret;
+  };
+
+  Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) };
+
+  Module['load'] = function load(f) {
+    globalEval(read(f));
+  };
+
+  Module['arguments'] = process['argv'].slice(2);
+
+  module['exports'] = Module;
+}
+else if (ENVIRONMENT_IS_SHELL) {
+  if (!Module['print']) Module['print'] = print;
+  if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
+
+  if (typeof read != 'undefined') {
+    Module['read'] = read;
+  } else {
+    Module['read'] = function read() { throw 'no read() available (jsc?)' };
+  }
+
+  Module['readBinary'] = function readBinary(f) {
+    return read(f, 'binary');
+  };
+
+  if (typeof scriptArgs != 'undefined') {
+    Module['arguments'] = scriptArgs;
+  } else if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  this['Module'] = Module;
+
+  eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly)
+}
+else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+  Module['read'] = function read(url) {
+    var xhr = new XMLHttpRequest();
+    xhr.open('GET', url, false);
+    xhr.send(null);
+    return xhr.responseText;
+  };
+
+  if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  if (typeof console !== 'undefined') {
+    if (!Module['print']) Module['print'] = function print(x) {
+      console.log(x);
+    };
+    if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+      console.log(x);
+    };
+  } else {
+    // Probably a worker, and without console.log. We can do very little here...
+    var TRY_USE_DUMP = false;
+    if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
+      dump(x);
+    }) : (function(x) {
+      // self.postMessage(x); // enable this if you want stdout to be sent as messages
+    }));
+  }
+
+  if (ENVIRONMENT_IS_WEB) {
+    window['Module'] = Module;
+  } else {
+    Module['load'] = importScripts;
+  }
+}
+else {
+  // Unreachable because SHELL is dependant on the others
+  throw 'Unknown runtime environment. Where are we?';
+}
+
+function globalEval(x) {
+  eval.call(null, x);
+}
+if (!Module['load'] == 'undefined' && Module['read']) {
+  Module['load'] = function load(f) {
+    globalEval(Module['read'](f));
+  };
+}
+if (!Module['print']) {
+  Module['print'] = function(){};
+}
+if (!Module['printErr']) {
+  Module['printErr'] = Module['print'];
+}
+if (!Module['arguments']) {
+  Module['arguments'] = [];
+}
+// *** Environment setup code ***
+
+// Closure helpers
+Module.print = Module['print'];
+Module.printErr = Module['printErr'];
+
+// Callbacks
+Module['preRun'] = [];
+Module['postRun'] = [];
+
+// Merge back in the overrides
+for (var key in moduleOverrides) {
+  if (moduleOverrides.hasOwnProperty(key)) {
+    Module[key] = moduleOverrides[key];
+  }
+}
+
+
+
+// === Auto-generated preamble library stuff ===
+
+//========================================
+// Runtime code shared with compiler
+//========================================
+
+var Runtime = {
+  stackSave: function () {
+    return STACKTOP;
+  },
+  stackRestore: function (stackTop) {
+    STACKTOP = stackTop;
+  },
+  forceAlign: function (target, quantum) {
+    quantum = quantum || 4;
+    if (quantum == 1) return target;
+    if (isNumber(target) && isNumber(quantum)) {
+      return Math.ceil(target/quantum)*quantum;
+    } else if (isNumber(quantum) && isPowerOfTwo(quantum)) {
+      return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')';
+    }
+    return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
+  },
+  isNumberType: function (type) {
+    return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
+  },
+  isPointerType: function isPointerType(type) {
+  return type[type.length-1] == '*';
+},
+  isStructType: function isStructType(type) {
+  if (isPointerType(type)) return false;
+  if (isArrayType(type)) return true;
+  if (/<?\{ ?[^}]* ?\}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types
+  // See comment in isStructPointerType()
+  return type[0] == '%';
+},
+  INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
+  FLOAT_TYPES: {"float":0,"double":0},
+  or64: function (x, y) {
+    var l = (x | 0) | (y | 0);
+    var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  and64: function (x, y) {
+    var l = (x | 0) & (y | 0);
+    var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  xor64: function (x, y) {
+    var l = (x | 0) ^ (y | 0);
+    var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  getNativeTypeSize: function (type) {
+    switch (type) {
+      case 'i1': case 'i8': return 1;
+      case 'i16': return 2;
+      case 'i32': return 4;
+      case 'i64': return 8;
+      case 'float': return 4;
+      case 'double': return 8;
+      default: {
+        if (type[type.length-1] === '*') {
+          return Runtime.QUANTUM_SIZE; // A pointer
+        } else if (type[0] === 'i') {
+          var bits = parseInt(type.substr(1));
+          assert(bits % 8 === 0);
+          return bits/8;
+        } else {
+          return 0;
+        }
+      }
+    }
+  },
+  getNativeFieldSize: function (type) {
+    return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE);
+  },
+  dedup: function dedup(items, ident) {
+  var seen = {};
+  if (ident) {
+    return items.filter(function(item) {
+      if (seen[item[ident]]) return false;
+      seen[item[ident]] = true;
+      return true;
+    });
+  } else {
+    return items.filter(function(item) {
+      if (seen[item]) return false;
+      seen[item] = true;
+      return true;
+    });
+  }
+},
+  set: function set() {
+  var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
+  var ret = {};
+  for (var i = 0; i < args.length; i++) {
+    ret[args[i]] = 0;
+  }
+  return ret;
+},
+  STACK_ALIGN: 8,
+  getAlignSize: function (type, size, vararg) {
+    // we align i64s and doubles on 64-bit boundaries, unlike x86
+    if (!vararg && (type == 'i64' || type == 'double')) return 8;
+    if (!type) return Math.min(size, 8); // align structures internally to 64 bits
+    return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE);
+  },
+  calculateStructAlignment: function calculateStructAlignment(type) {
+    type.flatSize = 0;
+    type.alignSize = 0;
+    var diffs = [];
+    var prev = -1;
+    var index = 0;
+    type.flatIndexes = type.fields.map(function(field) {
+      index++;
+      var size, alignSize;
+      if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
+        size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
+        alignSize = Runtime.getAlignSize(field, size);
+      } else if (Runtime.isStructType(field)) {
+        if (field[1] === '0') {
+          // this is [0 x something]. When inside another structure like here, it must be at the end,
+          // and it adds no size
+          // XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!');
+          size = 0;
+          if (Types.types[field]) {
+            alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+          } else {
+            alignSize = type.alignSize || QUANTUM_SIZE;
+          }
+        } else {
+          size = Types.types[field].flatSize;
+          alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+        }
+      } else if (field[0] == 'b') {
+        // bN, large number field, like a [N x i8]
+        size = field.substr(1)|0;
+        alignSize = 1;
+      } else if (field[0] === '<') {
+        // vector type
+        size = alignSize = Types.types[field].flatSize; // fully aligned
+      } else if (field[0] === 'i') {
+        // illegal integer field, that could not be legalized because it is an internal structure field
+        // it is ok to have such fields, if we just use them as markers of field size and nothing more complex
+        size = alignSize = parseInt(field.substr(1))/8;
+        assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field);
+      } else {
+        assert(false, 'invalid type for calculateStructAlignment');
+      }
+      if (type.packed) alignSize = 1;
+      type.alignSize = Math.max(type.alignSize, alignSize);
+      var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
+      type.flatSize = curr + size;
+      if (prev >= 0) {
+        diffs.push(curr-prev);
+      }
+      prev = curr;
+      return curr;
+    });
+    if (type.name_ && type.name_[0] === '[') {
+      // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
+      // allocating a potentially huge array for [999999 x i8] etc.
+      type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
+    }
+    type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
+    if (diffs.length == 0) {
+      type.flatFactor = type.flatSize;
+    } else if (Runtime.dedup(diffs).length == 1) {
+      type.flatFactor = diffs[0];
+    }
+    type.needsFlattening = (type.flatFactor != 1);
+    return type.flatIndexes;
+  },
+  generateStructInfo: function (struct, typeName, offset) {
+    var type, alignment;
+    if (typeName) {
+      offset = offset || 0;
+      type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
+      if (!type) return null;
+      if (type.fields.length != struct.length) {
+        printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo');
+        return null;
+      }
+      alignment = type.flatIndexes;
+    } else {
+      var type = { fields: struct.map(function(item) { return item[0] }) };
+      alignment = Runtime.calculateStructAlignment(type);
+    }
+    var ret = {
+      __size__: type.flatSize
+    };
+    if (typeName) {
+      struct.forEach(function(item, i) {
+        if (typeof item === 'string') {
+          ret[item] = alignment[i] + offset;
+        } else {
+          // embedded struct
+          var key;
+          for (var k in item) key = k;
+          ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
+        }
+      });
+    } else {
+      struct.forEach(function(item, i) {
+        ret[item[1]] = alignment[i];
+      });
+    }
+    return ret;
+  },
+  dynCall: function (sig, ptr, args) {
+    if (args && args.length) {
+      if (!args.splice) args = Array.prototype.slice.call(args);
+      args.splice(0, 0, ptr);
+      return Module['dynCall_' + sig].apply(null, args);
+    } else {
+      return Module['dynCall_' + sig].call(null, ptr);
+    }
+  },
+  functionPointers: [],
+  addFunction: function (func) {
+    for (var i = 0; i < Runtime.functionPointers.length; i++) {
+      if (!Runtime.functionPointers[i]) {
+        Runtime.functionPointers[i] = func;
+        return 2*(1 + i);
+      }
+    }
+    throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
+  },
+  removeFunction: function (index) {
+    Runtime.functionPointers[(index-2)/2] = null;
+  },
+  getAsmConst: function (code, numArgs) {
+    // code is a constant string on the heap, so we can cache these
+    if (!Runtime.asmConstCache) Runtime.asmConstCache = {};
+    var func = Runtime.asmConstCache[code];
+    if (func) return func;
+    var args = [];
+    for (var i = 0; i < numArgs; i++) {
+      args.push(String.fromCharCode(36) + i); // $0, $1 etc
+    }
+    var source = Pointer_stringify(code);
+    if (source[0] === '"') {
+      // tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct
+      if (source.indexOf('"', 1) === source.length-1) {
+        source = source.substr(1, source.length-2);
+      } else {
+        // something invalid happened, e.g. EM_ASM("..code($0)..", input)
+        abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)');
+      }
+    }
+    try {
+      var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node
+    } catch(e) {
+      Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)');
+      throw e;
+    }
+    return Runtime.asmConstCache[code] = evalled;
+  },
+  warnOnce: function (text) {
+    if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
+    if (!Runtime.warnOnce.shown[text]) {
+      Runtime.warnOnce.shown[text] = 1;
+      Module.printErr(text);
+    }
+  },
+  funcWrappers: {},
+  getFuncWrapper: function (func, sig) {
+    assert(sig);
+    if (!Runtime.funcWrappers[func]) {
+      Runtime.funcWrappers[func] = function dynCall_wrapper() {
+        return Runtime.dynCall(sig, func, arguments);
+      };
+    }
+    return Runtime.funcWrappers[func];
+  },
+  UTF8Processor: function () {
+    var buffer = [];
+    var needed = 0;
+    this.processCChar = function (code) {
+      code = code & 0xFF;
+
+      if (buffer.length == 0) {
+        if ((code & 0x80) == 0x00) {        // 0xxxxxxx
+          return String.fromCharCode(code);
+        }
+        buffer.push(code);
+        if ((code & 0xE0) == 0xC0) {        // 110xxxxx
+          needed = 1;
+        } else if ((code & 0xF0) == 0xE0) { // 1110xxxx
+          needed = 2;
+        } else {                            // 11110xxx
+          needed = 3;
+        }
+        return '';
+      }
+
+      if (needed) {
+        buffer.push(code);
+        needed--;
+        if (needed > 0) return '';
+      }
+
+      var c1 = buffer[0];
+      var c2 = buffer[1];
+      var c3 = buffer[2];
+      var c4 = buffer[3];
+      var ret;
+      if (buffer.length == 2) {
+        ret = String.fromCharCode(((c1 & 0x1F) << 6)  | (c2 & 0x3F));
+      } else if (buffer.length == 3) {
+        ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6)  | (c3 & 0x3F));
+      } else {
+        // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+        var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
+                        ((c3 & 0x3F) << 6)  | (c4 & 0x3F);
+        ret = String.fromCharCode(
+          Math.floor((codePoint - 0x10000) / 0x400) + 0xD800,
+          (codePoint - 0x10000) % 0x400 + 0xDC00);
+      }
+      buffer.length = 0;
+      return ret;
+    }
+    this.processJSString = function processJSString(string) {
+      /* TODO: use TextEncoder when present,
+        var encoder = new TextEncoder();
+        encoder['encoding'] = "utf-8";
+        var utf8Array = encoder['encode'](aMsg.data);
+      */
+      string = unescape(encodeURIComponent(string));
+      var ret = [];
+      for (var i = 0; i < string.length; i++) {
+        ret.push(string.charCodeAt(i));
+      }
+      return ret;
+    }
+  },
+  getCompilerSetting: function (name) {
+    throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work';
+  },
+  stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+7)&-8); return ret; },
+  staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = (((STATICTOP)+7)&-8); return ret; },
+  dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = (((DYNAMICTOP)+7)&-8); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; },
+  alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; },
+  makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*(+4294967296))) : ((+((low>>>0)))+((+((high|0)))*(+4294967296)))); return ret; },
+  GLOBAL_BASE: 8,
+  QUANTUM_SIZE: 4,
+  __dummy__: 0
+}
+
+
+Module['Runtime'] = Runtime;
+
+
+
+
+
+
+
+
+
+//========================================
+// Runtime essentials
+//========================================
+
+var __THREW__ = 0; // Used in checking for thrown exceptions.
+
+var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort()
+var EXITSTATUS = 0;
+
+var undef = 0;
+// tempInt is used for 32-bit signed values or smaller. tempBigInt is used
+// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt
+var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat;
+var tempI64, tempI64b;
+var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9;
+
+function assert(condition, text) {
+  if (!condition) {
+    abort('Assertion failed: ' + text);
+  }
+}
+
+var globalScope = this;
+
+// C calling interface. A convenient way to call C functions (in C files, or
+// defined with extern "C").
+//
+// Note: LLVM optimizations can inline and remove functions, after which you will not be
+//       able to call them. Closure can also do so. To avoid that, add your function to
+//       the exports using something like
+//
+//         -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]'
+//
+// @param ident      The name of the C function (note that C++ functions will be name-mangled - use extern "C")
+// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and
+//                   'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit).
+// @param argTypes   An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType,
+//                   except that 'array' is not possible (there is no way for us to know the length of the array)
+// @param args       An array of the arguments to the function, as native JS values (as in returnType)
+//                   Note that string arguments will be stored on the stack (the JS string will become a C string on the stack).
+// @return           The return value, as a native JS value (as in returnType)
+function ccall(ident, returnType, argTypes, args) {
+  return ccallFunc(getCFunc(ident), returnType, argTypes, args);
+}
+Module["ccall"] = ccall;
+
+// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
+function getCFunc(ident) {
+  try {
+    var func = Module['_' + ident]; // closure exported function
+    if (!func) func = eval('_' + ident); // explicit lookup
+  } catch(e) {
+  }
+  assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)');
+  return func;
+}
+
+// Internal function that does a C call using a function, not an identifier
+function ccallFunc(func, returnType, argTypes, args) {
+  var stack = 0;
+  function toC(value, type) {
+    if (type == 'string') {
+      if (value === null || value === undefined || value === 0) return 0; // null string
+      value = intArrayFromString(value);
+      type = 'array';
+    }
+    if (type == 'array') {
+      if (!stack) stack = Runtime.stackSave();
+      var ret = Runtime.stackAlloc(value.length);
+      writeArrayToMemory(value, ret);
+      return ret;
+    }
+    return value;
+  }
+  function fromC(value, type) {
+    if (type == 'string') {
+      return Pointer_stringify(value);
+    }
+    assert(type != 'array');
+    return value;
+  }
+  var i = 0;
+  var cArgs = args ? args.map(function(arg) {
+    return toC(arg, argTypes[i++]);
+  }) : [];
+  var ret = fromC(func.apply(null, cArgs), returnType);
+  if (stack) Runtime.stackRestore(stack);
+  return ret;
+}
+
+// Returns a native JS wrapper for a C function. This is similar to ccall, but
+// returns a function you can call repeatedly in a normal way. For example:
+//
+//   var my_function = cwrap('my_c_function', 'number', ['number', 'number']);
+//   alert(my_function(5, 22));
+//   alert(my_function(99, 12));
+//
+function cwrap(ident, returnType, argTypes) {
+  var func = getCFunc(ident);
+  return function() {
+    return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments));
+  }
+}
+Module["cwrap"] = cwrap;
+
+// Sets a value in memory in a dynamic way at run-time. Uses the
+// type data. This is the same as makeSetValue, except that
+// makeSetValue is done at compile-time and generates the needed
+// code then, whereas this function picks the right code at
+// run-time.
+// Note that setValue and getValue only do *aligned* writes and reads!
+// Note that ccall uses JS types as for defining types, while setValue and
+// getValue need LLVM types ('i8', 'i32') - this is a lower-level operation
+function setValue(ptr, value, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': HEAP8[(ptr)]=value; break;
+      case 'i8': HEAP8[(ptr)]=value; break;
+      case 'i16': HEAP16[((ptr)>>1)]=value; break;
+      case 'i32': HEAP32[((ptr)>>2)]=value; break;
+      case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= (+1) ? (tempDouble > (+0) ? ((Math_min((+(Math_floor((tempDouble)/(+4294967296)))), (+4294967295)))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/(+4294967296))))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
+      case 'float': HEAPF32[((ptr)>>2)]=value; break;
+      case 'double': HEAPF64[((ptr)>>3)]=value; break;
+      default: abort('invalid type for setValue: ' + type);
+    }
+}
+Module['setValue'] = setValue;
+
+// Parallel to setValue.
+function getValue(ptr, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': return HEAP8[(ptr)];
+      case 'i8': return HEAP8[(ptr)];
+      case 'i16': return HEAP16[((ptr)>>1)];
+      case 'i32': return HEAP32[((ptr)>>2)];
+      case 'i64': return HEAP32[((ptr)>>2)];
+      case 'float': return HEAPF32[((ptr)>>2)];
+      case 'double': return HEAPF64[((ptr)>>3)];
+      default: abort('invalid type for setValue: ' + type);
+    }
+  return null;
+}
+Module['getValue'] = getValue;
+
+var ALLOC_NORMAL = 0; // Tries to use _malloc()
+var ALLOC_STACK = 1; // Lives for the duration of the current function call
+var ALLOC_STATIC = 2; // Cannot be freed
+var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
+var ALLOC_NONE = 4; // Do not allocate
+Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
+Module['ALLOC_STACK'] = ALLOC_STACK;
+Module['ALLOC_STATIC'] = ALLOC_STATIC;
+Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
+Module['ALLOC_NONE'] = ALLOC_NONE;
+
+// allocate(): This is for internal use. You can use it yourself as well, but the interface
+//             is a little tricky (see docs right below). The reason is that it is optimized
+//             for multiple syntaxes to save space in generated code. So you should
+//             normally not use allocate(), and instead allocate memory using _malloc(),
+//             initialize it with setValue(), and so forth.
+// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
+//        in *bytes* (note that this is sometimes confusing: the next parameter does not
+//        affect this!)
+// @types: Either an array of types, one for each byte (or 0 if no type at that position),
+//         or a single type which is used for the entire block. This only matters if there
+//         is initial data - if @slab is a number, then this does not matter at all and is
+//         ignored.
+// @allocator: How to allocate memory, see ALLOC_*
+function allocate(slab, types, allocator, ptr) {
+  var zeroinit, size;
+  if (typeof slab === 'number') {
+    zeroinit = true;
+    size = slab;
+  } else {
+    zeroinit = false;
+    size = slab.length;
+  }
+
+  var singleType = typeof types === 'string' ? types : null;
+
+  var ret;
+  if (allocator == ALLOC_NONE) {
+    ret = ptr;
+  } else {
+    ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
+  }
+
+  if (zeroinit) {
+    var ptr = ret, stop;
+    assert((ret & 3) == 0);
+    stop = ret + (size & ~3);
+    for (; ptr < stop; ptr += 4) {
+      HEAP32[((ptr)>>2)]=0;
+    }
+    stop = ret + size;
+    while (ptr < stop) {
+      HEAP8[((ptr++)|0)]=0;
+    }
+    return ret;
+  }
+
+  if (singleType === 'i8') {
+    if (slab.subarray || slab.slice) {
+      HEAPU8.set(slab, ret);
+    } else {
+      HEAPU8.set(new Uint8Array(slab), ret);
+    }
+    return ret;
+  }
+
+  var i = 0, type, typeSize, previousType;
+  while (i < size) {
+    var curr = slab[i];
+
+    if (typeof curr === 'function') {
+      curr = Runtime.getFunctionIndex(curr);
+    }
+
+    type = singleType || types[i];
+    if (type === 0) {
+      i++;
+      continue;
+    }
+
+    if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
+
+    setValue(ret+i, curr, type);
+
+    // no need to look up size unless type changes, so cache it
+    if (previousType !== type) {
+      typeSize = Runtime.getNativeTypeSize(type);
+      previousType = type;
+    }
+    i += typeSize;
+  }
+
+  return ret;
+}
+Module['allocate'] = allocate;
+
+function Pointer_stringify(ptr, /* optional */ length) {
+  // TODO: use TextDecoder
+  // Find the length, and check for UTF while doing so
+  var hasUtf = false;
+  var t;
+  var i = 0;
+  while (1) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    if (t >= 128) hasUtf = true;
+    else if (t == 0 && !length) break;
+    i++;
+    if (length && i == length) break;
+  }
+  if (!length) length = i;
+
+  var ret = '';
+
+  if (!hasUtf) {
+    var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack
+    var curr;
+    while (length > 0) {
+      curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
+      ret = ret ? ret + curr : curr;
+      ptr += MAX_CHUNK;
+      length -= MAX_CHUNK;
+    }
+    return ret;
+  }
+
+  var utf8 = new Runtime.UTF8Processor();
+  for (i = 0; i < length; i++) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    ret += utf8.processCChar(t);
+  }
+  return ret;
+}
+Module['Pointer_stringify'] = Pointer_stringify;
+
+// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF16ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
+    if (codeUnit == 0)
+      return str;
+    ++i;
+    // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
+    str += String.fromCharCode(codeUnit);
+  }
+}
+Module['UTF16ToString'] = UTF16ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF16LE form. The copy will require at most (str.length*2+1)*2 bytes of space in the HEAP.
+function stringToUTF16(str, outPtr) {
+  for(var i = 0; i < str.length; ++i) {
+    // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
+    var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
+    HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP16[(((outPtr)+(str.length*2))>>1)]=0;
+}
+Module['stringToUTF16'] = stringToUTF16;
+
+// Given a pointer 'ptr' to a null-terminated UTF32LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF32ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
+    if (utf32 == 0)
+      return str;
+    ++i;
+    // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
+    if (utf32 >= 0x10000) {
+      var ch = utf32 - 0x10000;
+      str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
+    } else {
+      str += String.fromCharCode(utf32);
+    }
+  }
+}
+Module['UTF32ToString'] = UTF32ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF32LE form. The copy will require at most (str.length+1)*4 bytes of space in the HEAP,
+// but can use less, since str.length does not return the number of characters in the string, but the number of UTF-16 code units in the string.
+function stringToUTF32(str, outPtr) {
+  var iChar = 0;
+  for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) {
+    // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
+    var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate
+    if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
+      var trailSurrogate = str.charCodeAt(++iCodeUnit);
+      codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
+    }
+    HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit;
+    ++iChar;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP32[(((outPtr)+(iChar*4))>>2)]=0;
+}
+Module['stringToUTF32'] = stringToUTF32;
+
+function demangle(func) {
+  var i = 3;
+  // params, etc.
+  var basicTypes = {
+    'v': 'void',
+    'b': 'bool',
+    'c': 'char',
+    's': 'short',
+    'i': 'int',
+    'l': 'long',
+    'f': 'float',
+    'd': 'double',
+    'w': 'wchar_t',
+    'a': 'signed char',
+    'h': 'unsigned char',
+    't': 'unsigned short',
+    'j': 'unsigned int',
+    'm': 'unsigned long',
+    'x': 'long long',
+    'y': 'unsigned long long',
+    'z': '...'
+  };
+  var subs = [];
+  var first = true;
+  function dump(x) {
+    //return;
+    if (x) Module.print(x);
+    Module.print(func);
+    var pre = '';
+    for (var a = 0; a < i; a++) pre += ' ';
+    Module.print (pre + '^');
+  }
+  function parseNested() {
+    i++;
+    if (func[i] === 'K') i++; // ignore const
+    var parts = [];
+    while (func[i] !== 'E') {
+      if (func[i] === 'S') { // substitution
+        i++;
+        var next = func.indexOf('_', i);
+        var num = func.substring(i, next) || 0;
+        parts.push(subs[num] || '?');
+        i = next+1;
+        continue;
+      }
+      if (func[i] === 'C') { // constructor
+        parts.push(parts[parts.length-1]);
+        i += 2;
+        continue;
+      }
+      var size = parseInt(func.substr(i));
+      var pre = size.toString().length;
+      if (!size || !pre) { i--; break; } // counter i++ below us
+      var curr = func.substr(i + pre, size);
+      parts.push(curr);
+      subs.push(curr);
+      i += pre + size;
+    }
+    i++; // skip E
+    return parts;
+  }
+  function parse(rawList, limit, allowVoid) { // main parser
+    limit = limit || Infinity;
+    var ret = '', list = [];
+    function flushList() {
+      return '(' + list.join(', ') + ')';
+    }
+    var name;
+    if (func[i] === 'N') {
+      // namespaced N-E
+      name = parseNested().join('::');
+      limit--;
+      if (limit === 0) return rawList ? [name] : name;
+    } else {
+      // not namespaced
+      if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L'
+      var size = parseInt(func.substr(i));
+      if (size) {
+        var pre = size.toString().length;
+        name = func.substr(i + pre, size);
+        i += pre + size;
+      }
+    }
+    first = false;
+    if (func[i] === 'I') {
+      i++;
+      var iList = parse(true);
+      var iRet = parse(true, 1, true);
+      ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>';
+    } else {
+      ret = name;
+    }
+    paramLoop: while (i < func.length && limit-- > 0) {
+      //dump('paramLoop');
+      var c = func[i++];
+      if (c in basicTypes) {
+        list.push(basicTypes[c]);
+      } else {
+        switch (c) {
+          case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer
+          case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference
+          case 'L': { // literal
+            i++; // skip basic type
+            var end = func.indexOf('E', i);
+            var size = end - i;
+            list.push(func.substr(i, size));
+            i += size + 2; // size + 'EE'
+            break;
+          }
+          case 'A': { // array
+            var size = parseInt(func.substr(i));
+            i += size.toString().length;
+            if (func[i] !== '_') throw '?';
+            i++; // skip _
+            list.push(parse(true, 1, true)[0] + ' [' + size + ']');
+            break;
+          }
+          case 'E': break paramLoop;
+          default: ret += '?' + c; break paramLoop;
+        }
+      }
+    }
+    if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void)
+    if (rawList) {
+      if (ret) {
+        list.push(ret + '?');
+      }
+      return list;
+    } else {
+      return ret + flushList();
+    }
+  }
+  try {
+    // Special-case the entry point, since its name differs from other name mangling.
+    if (func == 'Object._main' || func == '_main') {
+      return 'main()';
+    }
+    if (typeof func === 'number') func = Pointer_stringify(func);
+    if (func[0] !== '_') return func;
+    if (func[1] !== '_') return func; // C function
+    if (func[2] !== 'Z') return func;
+    switch (func[3]) {
+      case 'n': return 'operator new()';
+      case 'd': return 'operator delete()';
+    }
+    return parse();
+  } catch(e) {
+    return func;
+  }
+}
+
+function demangleAll(text) {
+  return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') });
+}
+
+function stackTrace() {
+  var stack = new Error().stack;
+  return stack ? demangleAll(stack) : '(no stack trace available)'; // Stack trace is not available at least on IE10 and Safari 6.
+}
+
+// Memory management
+
+var PAGE_SIZE = 4096;
+function alignMemoryPage(x) {
+  return (x+4095)&-4096;
+}
+
+var HEAP;
+var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
+
+var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area
+var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area
+var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk
+
+function enlargeMemory() {
+  abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
+}
+
+var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880;
+var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 134217728;
+var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152;
+
+var totalMemory = 4096;
+while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) {
+  if (totalMemory < 16*1024*1024) {
+    totalMemory *= 2;
+  } else {
+    totalMemory += 16*1024*1024
+  }
+}
+if (totalMemory !== TOTAL_MEMORY) {
+  Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be more reasonable');
+  TOTAL_MEMORY = totalMemory;
+}
+
+// Initialize the runtime's memory
+// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
+assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
+       'JS engine does not provide full typed array support');
+
+var buffer = new ArrayBuffer(TOTAL_MEMORY);
+HEAP8 = new Int8Array(buffer);
+HEAP16 = new Int16Array(buffer);
+HEAP32 = new Int32Array(buffer);
+HEAPU8 = new Uint8Array(buffer);
+HEAPU16 = new Uint16Array(buffer);
+HEAPU32 = new Uint32Array(buffer);
+HEAPF32 = new Float32Array(buffer);
+HEAPF64 = new Float64Array(buffer);
+
+// Endianness check (note: assumes compiler arch was little-endian)
+HEAP32[0] = 255;
+assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
+
+Module['HEAP'] = HEAP;
+Module['HEAP8'] = HEAP8;
+Module['HEAP16'] = HEAP16;
+Module['HEAP32'] = HEAP32;
+Module['HEAPU8'] = HEAPU8;
+Module['HEAPU16'] = HEAPU16;
+Module['HEAPU32'] = HEAPU32;
+Module['HEAPF32'] = HEAPF32;
+Module['HEAPF64'] = HEAPF64;
+
+function callRuntimeCallbacks(callbacks) {
+  while(callbacks.length > 0) {
+    var callback = callbacks.shift();
+    if (typeof callback == 'function') {
+      callback();
+      continue;
+    }
+    var func = callback.func;
+    if (typeof func === 'number') {
+      if (callback.arg === undefined) {
+        Runtime.dynCall('v', func);
+      } else {
+        Runtime.dynCall('vi', func, [callback.arg]);
+      }
+    } else {
+      func(callback.arg === undefined ? null : callback.arg);
+    }
+  }
+}
+
+var __ATPRERUN__  = []; // functions called before the runtime is initialized
+var __ATINIT__    = []; // functions called during startup
+var __ATMAIN__    = []; // functions called when main() is to be run
+var __ATEXIT__    = []; // functions called during shutdown
+var __ATPOSTRUN__ = []; // functions called after the runtime has exited
+
+var runtimeInitialized = false;
+
+function preRun() {
+  // compatibility - merge in anything from Module['preRun'] at this time
+  if (Module['preRun']) {
+    if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
+    while (Module['preRun'].length) {
+      addOnPreRun(Module['preRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPRERUN__);
+}
+
+function ensureInitRuntime() {
+  if (runtimeInitialized) return;
+  runtimeInitialized = true;
+  callRuntimeCallbacks(__ATINIT__);
+}
+
+function preMain() {
+  callRuntimeCallbacks(__ATMAIN__);
+}
+
+function exitRuntime() {
+  callRuntimeCallbacks(__ATEXIT__);
+}
+
+function postRun() {
+  // compatibility - merge in anything from Module['postRun'] at this time
+  if (Module['postRun']) {
+    if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
+    while (Module['postRun'].length) {
+      addOnPostRun(Module['postRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPOSTRUN__);
+}
+
+function addOnPreRun(cb) {
+  __ATPRERUN__.unshift(cb);
+}
+Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun;
+
+function addOnInit(cb) {
+  __ATINIT__.unshift(cb);
+}
+Module['addOnInit'] = Module.addOnInit = addOnInit;
+
+function addOnPreMain(cb) {
+  __ATMAIN__.unshift(cb);
+}
+Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain;
+
+function addOnExit(cb) {
+  __ATEXIT__.unshift(cb);
+}
+Module['addOnExit'] = Module.addOnExit = addOnExit;
+
+function addOnPostRun(cb) {
+  __ATPOSTRUN__.unshift(cb);
+}
+Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun;
+
+// Tools
+
+// This processes a JS string into a C-line array of numbers, 0-terminated.
+// For LLVM-originating strings, see parser.js:parseLLVMString function
+function intArrayFromString(stringy, dontAddNull, length /* optional */) {
+  var ret = (new Runtime.UTF8Processor()).processJSString(stringy);
+  if (length) {
+    ret.length = length;
+  }
+  if (!dontAddNull) {
+    ret.push(0);
+  }
+  return ret;
+}
+Module['intArrayFromString'] = intArrayFromString;
+
+function intArrayToString(array) {
+  var ret = [];
+  for (var i = 0; i < array.length; i++) {
+    var chr = array[i];
+    if (chr > 0xFF) {
+      chr &= 0xFF;
+    }
+    ret.push(String.fromCharCode(chr));
+  }
+  return ret.join('');
+}
+Module['intArrayToString'] = intArrayToString;
+
+// Write a Javascript array to somewhere in the heap
+function writeStringToMemory(string, buffer, dontAddNull) {
+  var array = intArrayFromString(string, dontAddNull);
+  var i = 0;
+  while (i < array.length) {
+    var chr = array[i];
+    HEAP8[(((buffer)+(i))|0)]=chr;
+    i = i + 1;
+  }
+}
+Module['writeStringToMemory'] = writeStringToMemory;
+
+function writeArrayToMemory(array, buffer) {
+  for (var i = 0; i < array.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=array[i];
+  }
+}
+Module['writeArrayToMemory'] = writeArrayToMemory;
+
+function writeAsciiToMemory(str, buffer, dontAddNull) {
+  for (var i = 0; i < str.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=str.charCodeAt(i);
+  }
+  if (!dontAddNull) HEAP8[(((buffer)+(str.length))|0)]=0;
+}
+Module['writeAsciiToMemory'] = writeAsciiToMemory;
+
+function unSign(value, bits, ignore) {
+  if (value >= 0) {
+    return value;
+  }
+  return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
+                    : Math.pow(2, bits)         + value;
+}
+function reSign(value, bits, ignore) {
+  if (value <= 0) {
+    return value;
+  }
+  var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
+                        : Math.pow(2, bits-1);
+  if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
+                                                       // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
+                                                       // TODO: In i64 mode 1, resign the two parts separately and safely
+    value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
+  }
+  return value;
+}
+
+// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
+if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) {
+  var ah  = a >>> 16;
+  var al = a & 0xffff;
+  var bh  = b >>> 16;
+  var bl = b & 0xffff;
+  return (al*bl + ((ah*bl + al*bh) << 16))|0;
+};
+Math.imul = Math['imul'];
+
+
+var Math_abs = Math.abs;
+var Math_cos = Math.cos;
+var Math_sin = Math.sin;
+var Math_tan = Math.tan;
+var Math_acos = Math.acos;
+var Math_asin = Math.asin;
+var Math_atan = Math.atan;
+var Math_atan2 = Math.atan2;
+var Math_exp = Math.exp;
+var Math_log = Math.log;
+var Math_sqrt = Math.sqrt;
+var Math_ceil = Math.ceil;
+var Math_floor = Math.floor;
+var Math_pow = Math.pow;
+var Math_imul = Math.imul;
+var Math_fround = Math.fround;
+var Math_min = Math.min;
+
+// A counter of dependencies for calling run(). If we need to
+// do asynchronous work before running, increment this and
+// decrement it. Incrementing must happen in a place like
+// PRE_RUN_ADDITIONS (used by emcc to add file preloading).
+// Note that you can add dependencies in preRun, even though
+// it happens right before run - run will be postponed until
+// the dependencies are met.
+var runDependencies = 0;
+var runDependencyWatcher = null;
+var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
+
+function addRunDependency(id) {
+  runDependencies++;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+}
+Module['addRunDependency'] = addRunDependency;
+function removeRunDependency(id) {
+  runDependencies--;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+  if (runDependencies == 0) {
+    if (runDependencyWatcher !== null) {
+      clearInterval(runDependencyWatcher);
+      runDependencyWatcher = null;
+    }
+    if (dependenciesFulfilled) {
+      var callback = dependenciesFulfilled;
+      dependenciesFulfilled = null;
+      callback(); // can add another dependenciesFulfilled
+    }
+  }
+}
+Module['removeRunDependency'] = removeRunDependency;
+
+Module["preloadedImages"] = {}; // maps url to image data
+Module["preloadedAudios"] = {}; // maps url to audio data
+
+
+var memoryInitializer = null;
+
+// === Body ===
+
+
+
+
+
+STATIC_BASE = 8;
+
+STATICTOP = STATIC_BASE + Runtime.alignMemory(13467);
+/* global initializers */ __ATINIT__.push();
+
+
+/* memory initializer */ allocate([99,97,110,110,111,116,32,99,114,101,97,116,101,32,115,116,97,116,101,58,32,110,111,116,32,101,110,111,117,103,104,32,109,101,109,111,114,121,0,0,40,101,114,114,111,114,32,111,98,106,101,99,116,32,105,115,32,110,111,116,32,97,32,115,116,114,105,110,103,41,0,0,88,0,0,0,0,0,0,0,108,117,97,0,0,0,0,0,76,85,65,95,78,79,69,78,86,0,0,0,0,0,0,0,116,111,111,32,109,97,110,121,32,114,101,115,117,108,116,115,32,116,111,32,112,114,105,110,116,0,0,0,0,0,0,0,112,114,105,110,116,0,0,0,101,114,114,111,114,32,99,97,108,108,105,110,103,32,39,112,114,105,110,116,39,32,40,37,115,41,0,0,0,0,0,0,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,105,110,116,101,114,114,117,112,116,101,100,33,0,0,0,0,95,95,116,111,115,116,114,105,110,103,0,0,0,0,0,0,40,110,111,32,101,114,114,111,114,32,109,101,115,115,97,103,101,41,0,0,0,0,0,0,61,115,116,100,105,110,0,0,60,101,111,102,62,0,0,0,114,101,116,117,114,110,32,37,115,0,0,0,0,0,0,0,95,80,82,79,77,80,84,0,95,80,82,79,77,80,84,50,0,0,0,0,0,0,0,0,62,32,0,0,0,0,0,0,62,62,32,0,0,0,0,0,97,114,103,0,0,0,0,0,45,0,0,0,0,0,0,0,45,45,0,0,0,0,0,0,116,111,111,32,109,97,110,121,32,97,114,103,117,109,101,110,116,115,32,116,111,32,115,99,114,105,112,116,0,0,0,0,61,40,99,111,109,109,97,110,100,32,108,105,110,101,41,0,114,101,113,117,105,114,101,0,61,76,85,65,95,73,78,73,84,95,53,95,50,0,0,0,61,76,85,65,95,73,78,73,84,0,0,0,0,0,0,0,76,117,97,32,53,46,50,46,50,32,32,67,111,112,121,114,105,103,104,116,32,40,67,41,32,49,57,57,52,45,50,48,49,51,32,76,117,97,46,111,114,103,44,32,80,85,67,45,82,105,111,0,0,0,0,0,37,115,58,32,0,0,0,0,39,37,115,39,32,110,101,101,100,115,32,97,114,103,117,109,101,110,116,10,0,0,0,0,117,110,114,101,99,111,103,110,105,122,101,100,32,111,112,116,105,111,110,32,39,37,115,39,10,0,0,0,0,0,0,0,117,115,97,103,101,58,32,37,115,32,91,111,112,116,105,111,110,115,93,32,91,115,99,114,105,112,116,32,91,97,114,103,115,93,93,10,65,118,97,105,108,97,98,108,101,32,111,112,116,105,111,110,115,32,97,114,101,58,10,32,32,45,101,32,115,116,97,116,32,32,101,120,101,99,117,116,101,32,115,116,114,105,110,103,32,39,115,116,97,116,39,10,32,32,45,105,32,32,32,32,32,32,32,101,110,116,101,114,32,105,110,116,101,114,97,99,116,105,118,101,32,109,111,100,101,32,97,102,116,101,114,32,101,120,101,99,117,116,105,110,103,32,39,115,99,114,105,112,116,39,10,32,32,45,108,32,110,97,109,101,32,32,114,101,113,117,105,114,101,32,108,105,98,114,97,114,121,32,39,110,97,109,101,39,10,32,32,45,118,32,32,32,32,32,32,32,115,104,111,119,32,118,101,114,115,105,111,110,32,105,110,102,111,114,109,97,116,105,111,110,10,32,32,45,69,32,32,32,32,32,32,32,105,103,110,111,114,101,32,101,110,118,105,114,111,110,109,101,110,116,32,118,97,114,105,97,98,108,101,115,10,32,32,45,45,32,32,32,32,32,32,32,115,116,111,112,32,104,97,110,100,108,105,110,103,32,111,112,116,105,111,110,115,10,32,32,45,32,32,32,32,32,32,32,32,115,116,111,112,32,104,97,110,100,108,105,110,103,32,111,112,116,105,111,110,115,32,97,110,100,32,101,120,101,99,117,116,101,32,115,116,100,105,110,10,0,0,0,0,0,0,0,37,115,10,0,0,0,0,0,0,0,0,0,0,96,127,64,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,37,115,10,0,0,0,0,0,115,116,97,99,107,32,116,114,97,99,101,98,97,99,107,58,0,0,0,0,0,0,0,0,10,9,46,46,46,0,0,0,83,108,110,116,0,0,0,0,10,9,37,115,58,0,0,0,37,100,58,0,0,0,0,0,32,105,110,32,0,0,0,0,10,9,40,46,46,46,116,97,105,108,32,99,97,108,108,115,46,46,46,41,0,0,0,0,98,97,100,32,97,114,103,117,109,101,110,116,32,35,37,100,32,40,37,115,41,0,0,0,110,0,0,0,0,0,0,0,109,101,116,104,111,100,0,0,99,97,108,108,105,110,103,32,39,37,115,39,32,111,110,32,98,97,100,32,115,101,108,102,32,40,37,115,41,0,0,0,63,0,0,0,0,0,0,0,98,97,100,32,97,114,103,117,109,101,110,116,32,35,37,100,32,116,111,32,39,37,115,39,32,40,37,115,41,0,0,0,83,108,0,0,0,0,0,0,37,115,58,37,100,58,32,0,0,0,0,0,0,0,0,0,37,115,58,32,37,115,0,0,101,120,105,116,0,0,0,0,105,110,118,97,108,105,100,32,111,112,116,105,111,110,32,39,37,115,39,0,0,0,0,0,115,116,97,99,107,32,111,118,101,114,102,108,111,119,32,40,37,115,41,0,0,0,0,0,115,116,97,99,107,32,111,118,101,114,102,108,111,119,0,0,118,97,108,117,101,32,101,120,112,101,99,116,101,100,0,0,98,117,102,102,101,114,32,116,111,111,32,108,97,114,103,101,0,0,0,0,0,0,0,0,61,115,116,100,105,110,0,0,64,37,115,0,0,0,0,0,114,0,0,0,0,0,0,0,111,112,101,110,0,0,0,0,114,98,0,0,0,0,0,0,114,101,111,112,101,110,0,0,114,101,97,100,0,0,0,0,111,98,106,101,99,116,32,108,101,110,103,116,104,32,105,115,32,110,111,116,32,97,32,110,117,109,98,101,114,0,0,0,95,95,116,111,115,116,114,105,110,103,0,0,0,0,0,0,116,114,117,101,0,0,0,0,102,97,108,115,101,0,0,0,110,105,108,0,0,0,0,0,37,115,58,32,37,112,0,0,95,76,79,65,68,69,68,0,110,97,109,101,32,99,111,110,102,108,105,99,116,32,102,111,114,32,109,111,100,117,108,101,32,39,37,115,39,0,0,0,116,111,111,32,109,97,110,121,32,117,112,118,97,108,117,101,115,0,0,0,0,0,0,0,109,117,108,116,105,112,108,101,32,76,117,97,32,86,77,115,32,100,101,116,101,99,116,101,100,0,0,0,0,0,0,0,118,101,114,115,105,111,110,32,109,105,115,109,97,116,99,104,58,32,97,112,112,46,32,110,101,101,100,115,32,37,102,44,32,76,117,97,32,99,111,114,101,32,112,114,111,118,105,100,101,115,32,37,102,0,0,0,98,97,100,32,99,111,110,118,101,114,115,105,111,110,32,110,117,109,98,101,114,45,62,105,110,116,59,32,109,117,115,116,32,114,101,99,111,109,112,105,108,101,32,76,117,97,32,119,105,116,104,32,112,114,111,112,101,114,32,115,101,116,116,105,110,103,115,0,0,0,0,0,80,65,78,73,67,58,32,117,110,112,114,111,116,101,99,116,101,100,32,101,114,114,111,114,32,105,110,32,99,97,108,108,32,116,111,32,76,117,97,32,65,80,73,32,40,37,115,41,10,0,0,0,0,0,0,0,239,187,191,0,0,0,0,0,99,97,110,110,111,116,32,37,115,32,37,115,58,32,37,115,0,0,0,0,0,0,0,0,37,115,32,101,120,112,101,99,116,101,100,44,32,103,111,116,32,37,115,0,0,0,0,0,102,0,0,0,0,0,0,0,46,0,0,0,0,0,0,0,102,117,110,99,116,105,111,110,32,39,37,115,39,0,0,0,109,97,105,110,32,99,104,117,110,107,0,0,0,0,0,0,102,117,110,99,116,105,111,110,32,60,37,115,58,37,100,62,0,0,0,0,0,0,0,0,97,116,116,101,109,112,116,32,116,111,32,37,115,32,37,115,32,39,37,115,39,32,40,97,32,37,115,32,118,97,108,117,101,41,0,0,0,0,0,0,97,116,116,101,109,112,116,32,116,111,32,37,115,32,97,32,37,115,32,118,97,108,117,101,0,0,0,0,0,0,0,0,99,111,110,99,97,116,101,110,97,116,101,0,0,0,0,0,112,101,114,102,111,114,109,32,97,114,105,116,104,109,101,116,105,99,32,111,110,0,0,0,97,116,116,101,109,112,116,32,116,111,32,99,111,109,112,97,114,101,32,116,119,111,32,37,115,32,118,97,108,117,101,115,0,0,0,0,0,0,0,0,97,116,116,101,109,112,116,32,116,111,32,99,111,109,112,97,114,101,32,37,115,32,119,105,116,104,32,37,115,0,0,0,37,115,58,37,100,58,32,37,115,0,0,0,0,0,0,0,108,111,99,97,108,0,0,0,95,69,78,86,0,0,0,0,103,108,111,98,97,108,0,0,102,105,101,108,100,0,0,0,117,112,118,97,108,117,101,0,99,111,110,115,116,97,110,116,0,0,0,0,0,0,0,0,109,101,116,104,111,100,0,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,102,111,114,32,105,116,101,114,97,116,111,114,0,0,0,0,109,101,116,97,109,101,116,104,111,100,0,0,0,0,0,0,61,91,67,93,0,0,0,0,67,0,0,0,0,0,0,0,61,63,0,0,0,0,0,0,109,97,105,110,0,0,0,0,76,117,97,0,0,0,0,0,40,42,116,101,109,112,111,114,97,114,121,41,0,0,0,0,40,42,118,97,114,97,114,103,41,0,0,0,0,0,0,0,115,116,97,99,107,32,111,118,101,114,102,108,111,119,0,0,67,32,115,116,97,99,107,32,111,118,101,114,102,108,111,119,0,0,0,0,0,0,0,0,97,116,116,101,109,112,116,32,116,111,32,121,105,101,108,100,32,97,99,114,111,115,115,32,97,32,67,45,99,97,108,108,32,98,111,117,110,100,97,114,121,0,0,0,0,0,0,0,97,116,116,101,109,112,116,32,116,111,32,121,105,101,108,100,32,102,114,111,109,32,111,117,116,115,105,100,101,32,97,32,99,111,114,111,117,116,105,110,101,0,0,0,0,0,0,0,98,105,110,97,114,121,0,0,116,101,120,116,0,0,0,0,97,116,116,101,109,112,116,32,116,111,32,108,111,97,100,32,97,32,37,115,32,99,104,117,110,107,32,40,109,111,100,101,32,105,115,32,39,37,115,39,41,0,0,0,0,0,0,0,101,114,114,111,114,32,105,110,32,101,114,114,111,114,32,104,97,110,100,108,105,110,103,0,99,97,110,110,111,116,32,114,101,115,117,109,101,32,110,111,110,45,115,117,115,112,101,110,100,101,100,32,99,111,114,111,117,116,105,110,101,0,0,0,99,97,110,110,111,116,32,114,101,115,117,109,101,32,100,101,97,100,32,99,111,114,111,117,116,105,110,101,0,0,0,0,99,97,108,108,0,0,0,0,110,111,32,109,101,115,115,97,103,101,0,0,0,0,0,0,101,114,114,111,114,32,105,110,32,95,95,103,99,32,109,101,116,97,109,101,116,104,111,100,32,40,37,115,41,0,0,0,95,80,82,69,76,79,65,68,0,0,0,0,0,0,0,0,95,71,0,0,0,0,0,0,112,97,99,107,97,103,101,0,99,111,114,111,117,116,105,110,101,0,0,0,0,0,0,0,116,97,98,108,101,0,0,0,105,111,0,0,0,0,0,0,111,115,0,0,0,0,0,0,115,116,114,105,110,103,0,0,98,105,116,51,50,0,0,0,109,97,116,104,0,0,0,0,100,101,98,117,103,0,0,0,144,11,0,0,1,0,0,0,152,11,0,0,2,0,0,0,48,13,0,0,3,0,0,0,160,11,0,0,4,0,0,0,56,13,0,0,5,0,0,0,64,13,0,0,6,0,0,0,72,13,0,0,7,0,0,0,168,11,0,0,8,0,0,0,80,13,0,0,9,0,0,0,88,13,0,0,10,0,0,0,192,11,0,0,11,0,0,0,0,0,0,0,0,0,0,0,95,73,79,95,105,110,112,117,116,0,0,0,0,0,0,0,115,116,100,105,110,0,0,0,95,73,79,95,111,117,116,112,117,116,0,0,0,0,0,0,115,116,100,111,117,116,0,0,115,116,100,101,114,114,0,0,70,73,76,69,42,0,0,0,99,97,110,110,111,116,32,99,108,111,115,101,32,115,116,97,110,100,97,114,100,32,102,105,108,101,0,0,0,0,0,0,95,95,105,110,100,101,120,0,144,11,0,0,1,0,0,0,152,11,0,0,12,0,0,0,160,11,0,0,13,0,0,0,168,11,0,0,14,0,0,0,176,11,0,0,15,0,0,0,184,11,0,0,16,0,0,0,192,11,0,0,17,0,0,0,200,11,0,0,18,0,0,0,208,11,0,0,19,0,0,0,0,0,0,0,0,0,0,0,99,108,111,115,101,0,0,0,102,108,117,115,104,0,0,0,108,105,110,101,115,0,0,0,114,101,97,100,0,0,0,0,115,101,101,107,0,0,0,0,115,101,116,118,98,117,102,0,119,114,105,116,101,0,0,0,95,95,103,99,0,0,0,0,95,95,116,111,115,116,114,105,110,103,0,0,0,0,0,0,102,105,108,101,32,40,99,108,111,115,101,100,41,0,0,0,102,105,108,101,32,40,37,112,41,0,0,0,0,0,0,0,37,46,49,52,103,0,0,0,97,116,116,101,109,112,116,32,116,111,32,117,115,101,32,97,32,99,108,111,115,101,100,32,102,105,108,101,0,0,0,0,2,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,72,12,0,0,80,12,0,0,88,12,0,0,0,0,0,0,110,111,0,0,0,0,0,0,102,117,108,108,0,0,0,0,108,105,110,101,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,128,12,0,0,136,12,0,0,144,12,0,0,0,0,0,0,115,101,116,0,0,0,0,0,99,117,114,0,0,0,0,0,101,110,100,0,0,0,0,0,110,111,116,32,97,110,32,105,110,116,101,103,101,114,32,105,110,32,112,114,111,112,101,114,32,114,97,110,103,101,0,0,116,111,111,32,109,97,110,121,32,97,114,103,117,109,101,110,116,115,0,0,0,0,0,0,105,110,118,97,108,105,100,32,111,112,116,105,111,110,0,0,105,110,118,97,108,105,100,32,102,111,114,109,97,116,0,0,37,108,102,0,0,0,0,0,116,111,111,32,109,97,110,121,32,111,112,116,105,111,110,115,0,0,0,0,0,0,0,0,102,105,108,101,32,105,115,32,97,108,114,101,97,100,121,32,99,108,111,115,101,100,0,0,37,115,0,0,0,0,0,0,105,110,112,117,116,0,0,0,111,112,101,110,0,0,0,0,111,117,116,112,117,116,0,0,112,111,112,101,110,0,0,0,116,109,112,102,105,108,101,0,116,121,112,101,0,0,0,0,115,116,97,110,100,97,114,100,32,37,115,32,102,105,108,101,32,105,115,32,99,108,111,115,101,100,0,0,0,0,0,0,99,108,111,115,101,100,32,102,105,108,101,0,0,0,0,0,102,105,108,101,0,0,0,0,114,0,0,0,0,0,0,0,39,112,111,112,101,110,39,32,110,111,116,32,115,117,112,112,111,114,116,101,100,0,0,0,119,0,0,0,0,0,0,0,99,97,110,110,111,116,32,111,112,101,110,32,102,105,108,101,32,39,37,115,39,32,40,37,115,41,0,0,0,0,0,0,114,119,97,0,0,0,0,0,105,110,118,97,108,105,100,32,109,111,100,101,0,0,0,0,240,14,0,0,20,0,0,0,248,14,0,0,21,0,0,0,0,15,0,0,22,0,0,0,8,15,0,0,23,0,0,0,16,15,0,0,24,0,0,0,24,15,0,0,25,0,0,0,32,15,0,0,26,0,0,0,40,15,0,0,27,0,0,0,48,15,0,0,28,0,0,0,56,15,0,0,29,0,0,0,64,15,0,0,30,0,0,0,72,15,0,0,31,0,0,0,80,15,0,0,32,0,0,0,88,15,0,0,33,0,0,0,96,15,0,0,34,0,0,0,104,15,0,0,35,0,0,0,112,15,0,0,36,0,0,0,120,15,0,0,37,0,0,0,128,15,0,0,38,0,0,0,136,15,0,0,39,0,0,0,144,15,0,0,40,0,0,0,152,15,0,0,41,0,0,0,160,15,0,0,42,0,0,0,176,15,0,0,43,0,0,0,184,15,0,0,44,0,0,0,192,15,0,0,45,0,0,0,200,15,0,0,46,0,0,0,208,15,0,0,47,0,0,0,0,0,0,0,0,0,0,0,112,105,0,0,0,0,0,0,104,117,103,101,0,0,0,0,97,98,115,0,0,0,0,0,97,99,111,115,0,0,0,0,97,115,105,110,0,0,0,0,97,116,97,110,50,0,0,0,97,116,97,110,0,0,0,0,99,101,105,108,0,0,0,0,99,111,115,104,0,0,0,0,99,111,115,0,0,0,0,0,100,101,103,0,0,0,0,0,101,120,112,0,0,0,0,0,102,108,111,111,114,0,0,0,102,109,111,100,0,0,0,0,102,114,101,120,112,0,0,0,108,100,101,120,112,0,0,0,108,111,103,49,48,0,0,0,108,111,103,0,0,0,0,0,109,97,120,0,0,0,0,0,109,105,110,0,0,0,0,0,109,111,100,102,0,0,0,0,112,111,119,0,0,0,0,0,114,97,100,0,0,0,0,0,114,97,110,100,111,109,0,0,114,97,110,100,111,109,115,101,101,100,0,0,0,0,0,0,115,105,110,104,0,0,0,0,115,105,110,0,0,0,0,0,115,113,114,116,0,0,0,0,116,97,110,104,0,0,0,0,116,97,110,0,0,0,0,0,105,110,116,101,114,118,97,108,32,105,115,32,101,109,112,116,121,0,0,0,0,0,0,0,119,114,111,110,103,32,110,117,109,98,101,114,32,111,102,32,97,114,103,117,109,101,110,116,115,0,0,0,0,0,0,0,116,111,111,32,109,97,110,121,32,37,115,32,40,108,105,109,105,116,32,105,115,32,37,100,41,0,0,0,0,0,0,0,109,101,109,111,114,121,32,97,108,108,111,99,97,116,105,111,110,32,101,114,114,111,114,58,32,98,108,111,99,107,32,116,111,111,32,98,105,103,0,0,95,67,76,73,66,83,0,0,95,95,103,99,0,0,0,0,16,20,0,0,48,0,0,0,24,20,0,0,49,0,0,0,40,20,0,0,50,0,0,0,0,0,0,0,0,0,0,0,108,111,97,100,101,114,115,0,115,101,97,114,99,104,101,114,115,0,0,0,0,0,0,0,112,97,116,104,0,0,0,0,76,85,65,95,80,65,84,72,95,53,95,50,0,0,0,0,76,85,65,95,80,65,84,72,0,0,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,115,104,97,114,101,47,108,117,97,47,53,46,50,47,63,46,108,117,97,59,47,117,115,114,47,108,111,99,97,108,47,115,104,97,114,101,47,108,117,97,47,53,46,50,47,63,47,105,110,105,116,46,108,117,97,59,47,117,115,114,47,108,111,99,97,108,47,108,105,98,47,108,117,97,47,53,46,50,47,63,46,108,117,97,59,47,117,115,114,47,108,111,99,97,108,47,108,105,98,47,108,117,97,47,53,46,50,47,63,47,105,110,105,116,46,108,117,97,59,46,47,63,46,108,117,97,0,0,0,0,0,0,0,99,112,97,116,104,0,0,0,76,85,65,95,67,80,65,84,72,95,53,95,50,0,0,0,76,85,65,95,67,80,65,84,72,0,0,0,0,0,0,0,47,117,115,114,47,108,111,99,97,108,47,108,105,98,47,108,117,97,47,53,46,50,47,63,46,115,111,59,47,117,115,114,47,108,111,99,97,108,47,108,105,98,47,108,117,97,47,53,46,50,47,108,111,97,100,97,108,108,46,115,111,59,46,47,63,46,115,111,0,0,0,0,47,10,59,10,63,10,33,10,45,10,0,0,0,0,0,0,99,111,110,102,105,103,0,0,95,76,79,65,68,69,68,0,108,111,97,100,101,100,0,0,95,80,82,69,76,79,65,68,0,0,0,0,0,0,0,0,112,114,101,108,111,97,100,0,32,18,0,0,51,0,0,0,40,18,0,0,52,0,0,0,0,0,0,0,0,0,0,0,109,111,100,117,108,101,0,0,114,101,113,117,105,114,101,0,39,112,97,99,107,97,103,101,46,115,101,97,114,99,104,101,114,115,39,32,109,117,115,116,32,98,101,32,97,32,116,97,98,108,101,0,0,0,0,0,109,111,100,117,108,101,32,39,37,115,39,32,110,111,116,32,102,111,117,110,100,58,37,115,0,0,0,0,0,0,0,0,95,78,65,77,69,0,0,0,102,0,0,0,0,0,0,0,39,109,111,100,117,108,101,39,32,110,111,116,32,99,97,108,108,101,100,32,102,114,111,109,32,97,32,76,117,97,32,102,117,110,99,116,105,111,110,0,95,77,0,0,0,0,0,0,95,80,65,67,75,65,71,69,0,0,0,0,0,0,0,0,59,59,0,0,0,0,0,0,59,1,59,0,0,0,0,0,1,0,0,0,0,0,0,0,76,85,65,95,78,79,69,78,86,0,0,0,0,0,0,0,47,0,0,0,0,0,0,0,10,9,110,111,32,109,111,100,117,108,101,32,39,37,115,39,32,105,110,32,102,105,108,101,32,39,37,115,39,0,0,0,101,114,114,111,114,32,108,111,97,100,105,110,103,32,109,111,100,117,108,101,32,39,37,115,39,32,102,114,111,109,32,102,105,108,101,32,39,37,115,39,58,10,9,37,115,0,0,0,46,0,0,0,0,0,0,0,95,0,0,0,0,0,0,0,108,117,97,111,112,101,110,95,37,115,0,0,0,0,0,0,100,121,110,97,109,105,99,32,108,105,98,114,97,114,105,101,115,32,110,111,116,32,101,110,97,98,108,101,100,59,32,99,104,101,99,107,32,121,111,117,114,32,76,117,97,32,105,110,115,116,97,108,108,97,116,105,111,110,0,0,0,0,0,0,39,112,97,99,107,97,103,101,46,37,115,39,32,109,117,115,116,32,98,101,32,97,32,115,116,114,105,110,103,0,0,0,63,0,0,0,0,0,0,0,10,9,110,111,32,102,105,108,101,32,39,37,115,39,0,0,114,0,0,0,0,0,0,0,10,9,110,111,32,102,105,101,108,100,32,112,97,99,107,97,103,101,46,112,114,101,108,111,97,100,91,39,37,115,39,93,0,0,0,0,0,0,0,0,108,111,97,100,108,105,98,0,115,101,97,114,99,104,112,97,116,104,0,0,0,0,0,0,115,101,101,97,108,108,0,0,95,95,105,110,100,101,120,0,97,98,115,101,110,116,0,0,105,110,105,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,110,78,0,0,0,0,0,0,120,88,0,0,0,0,0,0,40,110,117,108,108,41,0,0,37,112,0,0,0,0,0,0,37,0,0,0,0,0,0,0,105,110,118,97,108,105,100,32,111,112,116,105,111,110,32,39,37,37,37,99,39,32,116,111,32,39,108,117,97,95,112,117,115,104,102,115,116,114,105,110,103,39,0,0,0,0,0,0,46,46,46,0,0,0,0,0,91,115,116,114,105,110,103,32,34,0,0,0,0,0,0,0,34,93,0,0,0,0,0,0,96,113,65,84,80,80,92,108,60,16,60,84,108,124,124,124,124,124,124,96,96,96,104,34,188,188,188,132,228,84,84,16,98,98,4,98,20,81,80,23,88,22,0,0,53,0,0,0,96,22,0,0,54,0,0,0,104,22,0,0,55,0,0,0,120,22,0,0,56,0,0,0,128,22,0,0,57,0,0,0,136,22,0,0,58,0,0,0,144,22,0,0,59,0,0,0,152,22,0,0,60,0,0,0,160,22,0,0,61,0,0,0,176,22,0,0,62,0,0,0,184,22,0,0,63,0,0,0,0,0,0,0,0,0,0,0,99,108,111,99,107,0,0,0,100,97,116,101,0,0,0,0,100,105,102,102,116,105,109,101,0,0,0,0,0,0,0,0,101,120,101,99,117,116,101,0,101,120,105,116,0,0,0,0,103,101,116,101,110,118,0,0,114,101,109,111,118,101,0,0,114,101,110,97,109,101,0,0,115,101,116,108,111,99,97,108,101,0,0,0,0,0,0,0,116,105,109,101,0,0,0,0,116,109,112,110,97,109,101,0,117,110,97,98,108,101,32,116,111,32,103,101,110,101,114,97,116,101,32,97,32,117,110,105,113,117,101,32,102,105,108,101,110,97,109,101,0,0,0,0,115,101,99,0,0,0,0,0,109,105,110,0,0,0,0,0,104,111,117,114,0,0,0,0,100,97,121,0,0,0,0,0,109,111,110,116,104,0,0,0,121,101,97,114,0,0,0,0,105,115,100,115,116,0,0,0,102,105,101,108,100,32,39,37,115,39,32,109,105,115,115,105,110,103,32,105,110,32,100,97,116,101,32,116,97,98,108,101,0,0,0,0,0,0,0,0,6,0,0,0,3,0,0,0,0,0,0,0,4,0,0,0,1,0,0,0,2,0,0,0,128,23,0,0,136,23,0,0,144,23,0,0,152,23,0,0,168,23,0,0,176,22,0,0,0,0,0,0,0,0,0,0,97,108,108,0,0,0,0,0,99,111,108,108,97,116,101,0,99,116,121,112,101,0,0,0,109,111,110,101,116,97,114,121,0,0,0,0,0,0,0,0,110,117,109,101,114,105,99,0,37,99,0,0,0,0,0,0,42,116,0,0,0,0,0,0,119,100,97,121,0,0,0,0,121,100,97,121,0,0,0,0,97,65,98,66,99,100,72,73,106,109,77,112,83,85,119,87,120,88,121,89,122,37,0,0,105,110,118,97,108,105,100,32,99,111,110,118,101,114,115,105,111,110,32,115,112,101,99,105,102,105,101,114,32,39,37,37,37,115,39,0,0,0,0,0,60,37,115,62,32,97,116,32,108,105,110,101,32,37,100,32,110,111,116,32,105,110,115,105,100,101,32,97,32,108,111,111,112,0,0,0,0,0,0,0,110,111,32,118,105,115,105,98,108,101,32,108,97,98,101,108,32,39,37,115,39,32,102,111,114,32,60,103,111,116,111,62,32,97,116,32,108,105,110,101,32,37,100,0,0,0,0,0,60,103,111,116,111,32,37,115,62,32,97,116,32,108,105,110,101,32,37,100,32,106,117,109,112,115,32,105,110,116,111,32,116,104,101,32,115,99,111,112,101,32,111,102,32,108,111,99,97,108,32,39,37,115,39,0,98,114,101,97,107,0,0,0,108,97,98,101,108,115,47,103,111,116,111,115,0,0,0,0,37,115,32,101,120,112,101,99,116,101,100,0,0,0,0,0,115,121,110,116,97,120,32,101,114,114,111,114,0,0,0,0,67,32,108,101,118,101,108,115,0,0,0,0,0,0,0,0,6,6,6,6,7,7,7,7,7,7,10,9,5,4,3,3,3,3,3,3,3,3,3,3,3,3,2,2,1,1,0,0,99,97,110,110,111,116,32,117,115,101,32,39,46,46,46,39,32,111,117,116,115,105,100,101,32,97,32,118,97,114,97,114,103,32,102,117,110,99,116,105,111,110,0,0,0,0,0,0,115,101,108,102,0,0,0,0,60,110,97,109,101,62,32,111,114,32,39,46,46,46,39,32,101,120,112,101,99,116,101,100,0,0,0,0,0,0,0,0,108,111,99,97,108,32,118,97,114,105,97,98,108,101,115,0,102,117,110,99,116,105,111,110,115,0,0,0,0,0,0,0,105,116,101,109,115,32,105,110,32,97,32,99,111,110,115,116,114,117,99,116,111,114,0,0,109,97,105,110,32,102,117,110,99,116,105,111,110,0,0,0,102,117,110,99,116,105,111,110,32,97,116,32,108,105,110,101,32,37,100,0,0,0,0,0,116,111,111,32,109,97,110,121,32,37,115,32,40,108,105,109,105,116,32,105,115,32,37,100,41,32,105,110,32,37,115,0,102,117,110,99,116,105,111,110,32,97,114,103,117,109,101,110,116,115,32,101,120,112,101,99,116,101,100,0,0,0,0,0,117,110,101,120,112,101,99,116,101,100,32,115,121,109,98,111,108,0,0,0,0,0,0,0,108,97,98,101,108,32,39,37,115,39,32,97,108,114,101,97,100,121,32,100,101,102,105,110,101,100,32,111,110,32,108,105,110,101,32,37,100,0,0,0,39,61,39,32,111,114,32,39,105,110,39,32,101,120,112,101,99,116,101,100,0,0,0,0,40,102,111,114,32,103,101,110,101,114,97,116,111,114,41,0,40,102,111,114,32,115,116,97,116,101,41,0,0,0,0,0,40,102,111,114,32,99,111,110,116,114,111,108,41,0,0,0,40,102,111,114,32,105,110,100,101,120,41,0,0,0,0,0,40,102,111,114,32,108,105,109,105,116,41,0,0,0,0,0,40,102,111,114,32,115,116,101,112,41,0,0,0,0,0,0,37,115,32,101,120,112,101,99,116,101,100,32,40,116,111,32,99,108,111,115,101,32,37,115,32,97,116,32,108,105,110,101,32,37,100,41,0,0,0,0,117,112,118,97,108,117,101,115,0,0,0,0,0,0,0,0,110,111,116,32,101,110,111,117,103,104,32,109,101,109,111,114,121,0,0,0,0,0,0,0,144,27,0,0,64,0,0,0,152,27,0,0,65,0,0,0,160,27,0,0,66,0,0,0,168,27,0,0,67,0,0,0,176,27,0,0,68,0,0,0,184,27,0,0,69,0,0,0,192,27,0,0,70,0,0,0,200,27,0,0,71,0,0,0,208,27,0,0,72,0,0,0,216,27,0,0,73,0,0,0,224,27,0,0,74,0,0,0,232,27,0,0,75,0,0,0,240,27,0,0,76,0,0,0,248,27,0,0,77,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,95,95,105,110,100,101,120,0,98,121,116,101,0,0,0,0,99,104,97,114,0,0,0,0,100,117,109,112,0,0,0,0,102,105,110,100,0,0,0,0,102,111,114,109,97,116,0,0,103,109,97,116,99,104,0,0,103,115,117,98,0,0,0,0,108,101,110,0,0,0,0,0,108,111,119,101,114,0,0,0,109,97,116,99,104,0,0,0,114,101,112,0,0,0,0,0,114,101,118,101,114,115,101,0,115,117,98,0,0,0,0,0,117,112,112,101,114,0,0,0,114,101,115,117,108,116,105,110,103,32,115,116,114,105,110,103,32,116,111,111,32,108,97,114,103,101,0,0,0,0,0,0,116,111,111,32,109,97,110,121,32,99,97,112,116,117,114,101,115,0,0,0,0,0,0,0,105,110,118,97,108,105,100,32,99,97,112,116,117,114,101,32,105,110,100,101,120,0,0,0,117,110,102,105,110,105,115,104,101,100,32,99,97,112,116,117,114,101,0,0,0,0,0,0,112,97,116,116,101,114,110,32,116,111,111,32,99,111,109,112,108,101,120,0,0,0,0,0,109,105,115,115,105,110,103,32,39,91,39,32,97,102,116,101,114,32,39,37,37,102,39,32,105,110,32,112,97,116,116,101,114,110,0,0,0,0,0,0,105,110,118,97,108,105,100,32,99,97,112,116,117,114,101,32,105,110,100,101,120,32,37,37,37,100,0,0,0,0,0,0,109,97,108,102,111,114,109,101,100,32,112,97,116,116,101,114,110,32,40,101,110,100,115,32,119,105,116,104,32,39,37,37,39,41,0,0,0,0,0,0,109,97,108,102,111,114,109,101,100,32,112,97,116,116,101,114,110,32,40,109,105,115,115,105,110,103,32,39,93,39,41,0,109,97,108,102,111,114,109,101,100,32,112,97,116,116,101,114,110,32,40,109,105,115,115,105,110,103,32,97,114,103,117,109,101,110,116,115,32,116,111,32,39,37,37,98,39,41,0,0,105,110,118,97,108,105,100,32,112,97,116,116,101,114,110,32,99,97,112,116,117,114,101,0,94,36,42,43,63,46,40,91,37,45,0,0,0,0,0,0,115,116,114,105,110,103,47,102,117,110,99,116,105,111,110,47,116,97,98,108,101,32,101,120,112,101,99,116,101,100,0,0,105,110,118,97,108,105,100,32,114,101,112,108,97,99,101,109,101,110,116,32,118,97,108,117,101,32,40,97,32,37,115,41,0,0,0,0,0,0,0,0,105,110,118,97,108,105,100,32,117,115,101,32,111,102,32,39,37,99,39,32,105,110,32,114,101,112,108,97,99,101,109,101,110,116,32,115,116,114,105,110,103,0,0,0,0,0,0,0,110,111,32,118,97,108,117,101,0,0,0,0,0,0,0,0,110,111,116,32,97,32,110,117,109,98,101,114,32,105,110,32,112,114,111,112,101,114,32,114,97,110,103,101,0,0,0,0,110,111,116,32,97,32,110,111,110,45,110,101,103,97,116,105,118,101,32,110,117,109,98,101,114,32,105,110,32,112,114,111,112,101,114,32,114,97,110,103,101,0,0,0,0,0,0,0,105,110,118,97,108,105,100,32,111,112,116,105,111,110,32,39,37,37,37,99,39,32,116,111,32,39,102,111,114,109,97,116,39,0,0,0,0,0,0,0,92,37,100,0,0,0,0,0,92,37,48,51,100,0,0,0,45,43,32,35,48,0,0,0,105,110,118,97,108,105,100,32,102,111,114,109,97,116,32,40,114,101,112,101,97,116,101,100,32,102,108,97,103,115,41,0,105,110,118,97,108,105,100,32,102,111,114,109,97,116,32,40,119,105,100,116,104,32,111,114,32,112,114,101,99,105,115,105,111,110,32,116,111,111,32,108,111,110,103,41,0,0,0,0,117,110,97,98,108,101,32,116,111,32,100,117,109,112,32,103,105,118,101,110,32,102,117,110,99,116,105,111,110,0,0,0,118,97,108,117,101,32,111,117,116,32,111,102,32,114,97,110,103,101,0,0,0,0,0,0,115,116,114,105,110,103,32,115,108,105,99,101,32,116,111,111,32,108,111,110,103,0,0,0,116,97,98,108,101,32,105,110,100,101,120,32,105,115,32,110,105,108,0,0,0,0,0,0,116,97,98,108,101,32,105,110,100,101,120,32,105,115,32,78,97,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,116,97,98,108,101,32,111,118,101,114,102,108,111,119,0,0,105,110,118,97,108,105,100,32,107,101,121,32,116,111,32,39,110,101,120,116,39,0,0,0,224,31,0,0,78,0,0,0,232,31,0,0,79,0,0,0,240,31,0,0,80,0,0,0,248,31,0,0,81,0,0,0,216,31,0,0,82,0,0,0,0,32,0,0,83,0,0,0,8,32,0,0,84,0,0,0,0,0,0,0,0,0,0,0,117,110,112,97,99,107,0,0,99,111,110,99,97,116,0,0,109,97,120,110,0,0,0,0,105,110,115,101,114,116,0,0,112,97,99,107,0,0,0,0,114,101,109,111,118,101,0,0,115,111,114,116,0,0,0,0,0,0,0,0,0,0,0,0,105,110,118,97,108,105,100,32,111,114,100,101,114,32,102,117,110,99,116,105,111,110,32,102,111,114,32,115,111,114,116,105,110,103,0,0,0,0,0,0,112,111,115,105,116,105,111,110,32,111,117,116,32,111,102,32,98,111,117,110,100,115,0,0,116,111,111,32,109,97,110,121,32,114,101,115,117,108,116,115,32,116,111,32,117,110,112,97,99,107,0,0,0,0,0,0,110,0,0,0,0,0,0,0,119,114,111,110,103,32,110,117,109,98,101,114,32,111,102,32,97,114,103,117,109,101,110,116,115,32,116,111,32,39,105,110,115,101,114,116,39,0,0,0,105,110,118,97,108,105,100,32,118,97,108,117,101,32,40,37,115,41,32,97,116,32,105,110,100,101,120,32,37,100,32,105,110,32,116,97,98,108,101,32,102,111,114,32,39,99,111,110,99,97,116,39,0,0,0,0,110,111,32,118,97,108,117,101,0,0,0,0,0,0,0,0,110,105,108,0,0,0,0,0,98,111,111,108,101,97,110,0,117,115,101,114,100,97,116,97,0,0,0,0,0,0,0,0,110,117,109,98,101,114,0,0,115,116,114,105,110,103,0,0,116,97,98,108,101,0,0,0,102,117,110,99,116,105,111,110,0,0,0,0,0,0,0,0,116,104,114,101,97,100,0,0,112,114,111,116,111,0,0,0,117,112,118,97,108,0,0,0,224,32,0,0,240,32,0,0,248,32,0,0,0,33,0,0,16,33,0,0,24,33,0,0,32,33,0,0,40,33,0,0,0,33,0,0,56,33,0,0,64,33,0,0,72,33,0,0,200,33,0,0,208,33,0,0,224,33,0,0,232,33,0,0,240,33,0,0,248,33,0,0,0,34,0,0,8,34,0,0,16,34,0,0,24,34,0,0,32,34,0,0,40,34,0,0,48,34,0,0,56,34,0,0,64,34,0,0,72,34,0,0,88,34,0,0,0,0,0,0,95,95,105,110,100,101,120,0,95,95,110,101,119,105,110,100,101,120,0,0,0,0,0,0,95,95,103,99,0,0,0,0,95,95,109,111,100,101,0,0,95,95,108,101,110,0,0,0,95,95,101,113,0,0,0,0,95,95,97,100,100,0,0,0,95,95,115,117,98,0,0,0,95,95,109,117,108,0,0,0,95,95,100,105,118,0,0,0,95,95,109,111,100,0,0,0,95,95,112,111,119,0,0,0,95,95,117,110,109,0,0,0,95,95,108,116,0,0,0,0,95,95,108,101,0,0,0,0,95,95,99,111,110,99,97,116,0,0,0,0,0,0,0,0,95,95,99,97,108,108,0,0,98,105,110,97,114,121,32,115,116,114,105,110,103,0,0,0,25,147,13,10,26,10,0,0,116,114,117,110,99,97,116,101,100,0,0,0,0,0,0,0,37,115,58,32,37,115,32,112,114,101,99,111,109,112,105,108,101,100,32,99,104,117,110,107,0,0,0,0,0,0,0,0,99,111,114,114,117,112,116,101,100,0,0,0,0,0,0,0,110,111,116,32,97,0,0,0,118,101,114,115,105,111,110,32,109,105,115,109,97,116,99,104,32,105,110,0,0,0,0,0,105,110,99,111,109,112,97,116,105,98,108,101,0,0,0,0,37,46,49,52,103,0,0,0,105,110,100,101,120,0,0,0,108,111,111,112,32,105,110,32,103,101,116,116,97,98,108,101,0,0,0,0,0,0,0,0,108,111,111,112,32,105,110,32,115,101,116,116,97,98,108,101,0,0,0,0,0,0,0,0,115,116,114,105,110,103,32,108,101,110,103,116,104,32,111,118,101,114,102,108,111,119,0,0,103,101,116,32,108,101,110,103,116,104,32,111,102,0,0,0,39,102,111,114,39,32,105,110,105,116,105,97,108,32,118,97,108,117,101,32,109,117,115,116,32,98,101,32,97,32,110,117,109,98,101,114,0,0,0,0,39,102,111,114,39,32,108,105,109,105,116,32,109,117,115,116,32,98,101,32,97,32,110,117,109,98,101,114,0,0,0,0,39,102,111,114,39,32,115,116,101,112,32,109,117,115,116,32,98,101,32,97,32,110,117,109,98,101,114,0,0,0,0,0,95,71,0,0,0,0,0,0,152,36,0,0,85,0,0,0,160,36,0,0,86,0,0,0,176,36,0,0,87,0,0,0,184,36,0,0,88,0,0,0,192,36,0,0,89,0,0,0,208,36,0,0,90,0,0,0,216,36,0,0,91,0,0,0,232,36,0,0,92,0,0,0,240,36,0,0,92,0,0,0,0,37,0,0,93,0,0,0,8,37,0,0,94,0,0,0,16,37,0,0,95,0,0,0,24,37,0,0,96,0,0,0,32,37,0,0,97,0,0,0,48,37,0,0,98,0,0,0,56,37,0,0,99,0,0,0,64,37,0,0,100,0,0,0,72,37,0,0,101,0,0,0,80,37,0,0,102,0,0,0,96,37,0,0,103,0,0,0,112,37,0,0,104,0,0,0,128,37,0,0,105,0,0,0,136,37,0,0,106,0,0,0,0,0,0,0,0,0,0,0,76,117,97,32,53,46,50,0,95,86,69,82,83,73,79,78,0,0,0,0,0,0,0,0,97,115,115,101,114,116,0,0,99,111,108,108,101,99,116,103,97,114,98,97,103,101,0,0,100,111,102,105,108,101,0,0,101,114,114,111,114,0,0,0,103,101,116,109,101,116,97,116,97,98,108,101,0,0,0,0,105,112,97,105,114,115,0,0,108,111,97,100,102,105,108,101,0,0,0,0,0,0,0,0,108,111,97,100,0,0,0,0,108,111,97,100,115,116,114,105,110,103,0,0,0,0,0,0,110,101,120,116,0,0,0,0,112,97,105,114,115,0,0,0,112,99,97,108,108,0,0,0,112,114,105,110,116,0,0,0,114,97,119,101,113,117,97,108,0,0,0,0,0,0,0,0,114,97,119,108,101,110,0,0,114,97,119,103,101,116,0,0,114,97,119,115,101,116,0,0,115,101,108,101,99,116,0,0,115,101,116,109,101,116,97,116,97,98,108,101,0,0,0,0,116,111,110,117,109,98,101,114,0,0,0,0,0,0,0,0,116,111,115,116,114,105,110,103,0,0,0,0,0,0,0,0,116,121,112,101,0,0,0,0,120,112,99,97,108,108,0,0,118,97,108,117,101,32,101,120,112,101,99,116,101,100,0,0,115,116,97,99,107,32,111,118,101,114,102,108,111,119,0,0,98,97,115,101,32,111,117,116,32,111,102,32,114,97,110,103,101,0,0,0,0,0,0,0,32,12,10,13,9,11,0,0,110,105,108,32,111,114,32,116,97,98,108,101,32,101,120,112,101,99,116,101,100,0,0,0,95,95,109,101,116,97,116,97,98,108,101,0,0,0,0,0,99,97,110,110,111,116,32,99,104,97,110,103,101,32,97,32,112,114,111,116,101,99,116,101,100,32,109,101,116,97,116,97,98,108,101,0,0,0,0,0,105,110,100,101,120,32,111,117,116,32,111,102,32,114,97,110,103,101,0,0,0,0,0,0,116,97,98,108,101,32,111,114,32,115,116,114,105,110,103,32,101,120,112,101,99,116,101,100,0,0,0,0,0,0,0,0,39,116,111,115,116,114,105,110,103,39,32,109,117,115,116,32,114,101,116,117,114,110,32,97,32,115,116,114,105,110,103,32,116,111,32,39,112,114,105,110,116,39,0,0,0,0,0,0,95,95,112,97,105,114,115,0,98,116,0,0,0,0,0,0,61,40,108,111,97,100,41,0,116,111,111,32,109,97,110,121,32,110,101,115,116,101,100,32,102,117,110,99,116,105,111,110,115,0,0,0,0,0,0,0,114,101,97,100,101,114,32,102,117,110,99,116,105,111,110,32,109,117,115,116,32,114,101,116,117,114,110,32,97,32,115,116,114,105,110,103,0,0,0,0,95,95,105,112,97,105,114,115,0,0,0,0,0,0,0,0,40,39,0,0,48,39,0,0,56,39,0,0,64,39,0,0,72,39,0,0,80,39,0,0,96,39,0,0,112,39,0,0,128,39,0,0,144,39,0,0,160,39,0,0,0,0,0,0,115,116,111,112,0,0,0,0,114,101,115,116,97,114,116,0,99,111,108,108,101,99,116,0,99,111,117,110,116,0,0,0,115,116,101,112,0,0,0,0,115,101,116,112,97,117,115,101,0,0,0,0,0,0,0,0,115,101,116,115,116,101,112,109,117,108,0,0,0,0,0,0,115,101,116,109,97,106,111,114,105,110,99,0,0,0,0,0,105,115,114,117,110,110,105,110,103,0,0,0,0,0,0,0,103,101,110,101,114,97,116,105,111,110,97,108,0,0,0,0,105,110,99,114,101,109,101,110,116,97,108,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,9,0,0,0,10,0,0,0,11,0,0,0,0,0,0,0,37,115,0,0,0,0,0,0,97,115,115,101,114,116,105,111,110,32,102,97,105,108,101,100,33,0,0,0,0,0,0,0,104,40,0,0,107], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE);
+/* memory initializer */ allocate([112,40,0,0,108,0,0,0,120,40,0,0,109,0,0,0,128,40,0,0,110,0,0,0,136,40,0,0,111,0,0,0,144,40,0,0,112,0,0,0,152,40,0,0,113,0,0,0,160,40,0,0,114,0,0,0,168,40,0,0,115,0,0,0,176,40,0,0,116,0,0,0,184,40,0,0,117,0,0,0,192,40,0,0,118,0,0,0,0,0,0,0,0,0,0,0,97,114,115,104,105,102,116,0,98,97,110,100,0,0,0,0,98,110,111,116,0,0,0,0,98,111,114,0,0,0,0,0,98,120,111,114,0,0,0,0,98,116,101,115,116,0,0,0,101,120,116,114,97,99,116,0,108,114,111,116,97,116,101,0,108,115,104,105,102,116,0,0,114,101,112,108,97,99,101,0,114,114,111,116,97,116,101,0,114,115,104,105,102,116,0,0,102,105,101,108,100,32,99,97,110,110,111,116,32,98,101,32,110,101,103,97,116,105,118,101,0,0,0,0,0,0,0,0,119,105,100,116,104,32,109,117,115,116,32,98,101,32,112,111,115,105,116,105,118,101,0,0,116,114,121,105,110,103,32,116,111,32,97,99,99,101,115,115,32,110,111,110,45,101,120,105,115,116,101,110,116,32,98,105,116,115,0,0,0,0,0,0,102,117,110,99,116,105,111,110,32,111,114,32,101,120,112,114,101,115,115,105,111,110,32,116,111,111,32,99,111,109,112,108,101,120,0,0,0,0,0,0,99,111,110,115,116,114,117,99,116,111,114,32,116,111,111,32,108,111,110,103,0,0,0,0,99,111,110,115,116,97,110,116,115,0,0,0,0,0,0,0,111,112,99,111,100,101,115,0,99,111,110,116,114,111,108,32,115,116,114,117,99,116,117,114,101,32,116,111,111,32,108,111,110,103,0,0,0,0,0,0,216,41,0,0,119,0,0,0,224,41,0,0,120,0,0,0,232,41,0,0,121,0,0,0,240,41,0,0,122,0,0,0,248,41,0,0,123,0,0,0,0,42,0,0,124,0,0,0,0,0,0,0,0,0,0,0,99,114,101,97,116,101,0,0,114,101,115,117,109,101,0,0,114,117,110,110,105,110,103,0,115,116,97,116,117,115,0,0,119,114,97,112,0,0,0,0,121,105,101,108,100,0,0,0,116,111,111,32,109,97,110,121,32,97,114,103,117,109,101,110,116,115,32,116,111,32,114,101,115,117,109,101,0,0,0,0,99,97,110,110,111,116,32,114,101,115,117,109,101,32,100,101,97,100,32,99,111,114,111,117,116,105,110,101,0,0,0,0,116,111,111,32,109,97,110,121,32,114,101,115,117,108,116,115,32,116,111,32,114,101,115,117,109,101,0,0,0,0,0,0,99,111,114,111,117,116,105,110,101,32,101,120,112,101,99,116,101,100,0,0,0,0,0,0,115,117,115,112,101,110,100,101,100,0,0,0,0,0,0,0,110,111,114,109,97,108,0,0,100,101,97,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8,8,8,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,22,22,22,22,22,22,22,22,22,22,4,4,4,4,4,4,4,21,21,21,21,21,21,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,5,4,21,21,21,21,21,21,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,44,0,0,125,0,0,0,56,44,0,0,126,0,0,0,72,44,0,0,127,0,0,0,80,44,0,0,128,0,0,0,88,44,0,0,129,0,0,0,104,44,0,0,130,0,0,0,120,44,0,0,131,0,0,0,136,44,0,0,132,0,0,0,152,44,0,0,133,0,0,0,168,44,0,0,134,0,0,0,184,44,0,0,135,0,0,0,200,44,0,0,136,0,0,0,208,44,0,0,137,0,0,0,224,44,0,0,138,0,0,0,240,44,0,0,139,0,0,0,0,45,0,0,140,0,0,0,0,0,0,0,0,0,0,0,100,101,98,117,103,0,0,0,103,101,116,117,115,101,114,118,97,108,117,101,0,0,0,0,103,101,116,104,111,111,107,0,103,101,116,105,110,102,111,0,103,101,116,108,111,99,97,108,0,0,0,0,0,0,0,0,103,101,116,114,101,103,105,115,116,114,121,0,0,0,0,0,103,101,116,109,101,116,97,116,97,98,108,101,0,0,0,0,103,101,116,117,112,118,97,108,117,101,0,0,0,0,0,0,117,112,118,97,108,117,101,106,111,105,110,0,0,0,0,0,117,112,118,97,108,117,101,105,100,0,0,0,0,0,0,0,115,101,116,117,115,101,114,118,97,108,117,101,0,0,0,0,115,101,116,104,111,111,107,0,115,101,116,108,111,99,97,108,0,0,0,0,0,0,0,0,115,101,116,109,101,116,97,116,97,98,108,101,0,0,0,0,115,101,116,117,112,118,97,108,117,101,0,0,0,0,0,0,116,114,97,99,101,98,97,99,107,0,0,0,0,0,0,0,110,105,108,32,111,114,32,116,97,98,108,101,32,101,120,112,101,99,116,101,100,0,0,0,108,101,118,101,108,32,111,117,116,32,111,102,32,114,97,110,103,101,0,0,0,0,0,0,95,72,75,69,89,0,0,0,107,0,0,0,0,0,0,0,95,95,109,111,100,101,0,0,112,45,0,0,120,45,0,0,128,45,0,0,136,45,0,0,144,45,0,0,0,0,0,0,99,97,108,108,0,0,0,0,114,101,116,117,114,110,0,0,108,105,110,101,0,0,0,0,99,111,117,110,116,0,0,0,116,97,105,108,32,99,97,108,108,0,0,0,0,0,0,0,102,117,108,108,32,117,115,101,114,100,97,116,97,32,101,120,112,101,99,116,101,100,44,32,103,111,116,32,108,105,103,104,116,32,117,115,101,114,100,97,116,97,0,0,0,0,0,0,62,117,0,0,0,0,0,0,105,110,118,97,108,105,100,32,117,112,118,97,108,117,101,32,105,110,100,101,120,0,0,0,76,117,97,32,102,117,110,99,116,105,111,110,32,101,120,112,101,99,116,101,100,0,0,0,102,108,110,83,116,117,0,0,62,37,115,0,0,0,0,0,102,117,110,99,116,105,111,110,32,111,114,32,108,101,118,101,108,32,101,120,112,101,99,116,101,100,0,0,0,0,0,0,105,110,118,97,108,105,100,32,111,112,116,105,111,110,0,0,115,111,117,114,99,101,0,0,115,104,111,114,116,95,115,114,99,0,0,0,0,0,0,0,108,105,110,101,100,101,102,105,110,101,100,0,0,0,0,0,108,97,115,116,108,105,110,101,100,101,102,105,110,101,100,0,119,104,97,116,0,0,0,0,99,117,114,114,101,110,116,108,105,110,101,0,0,0,0,0,110,117,112,115,0,0,0,0,110,112,97,114,97,109,115,0,105,115,118,97,114,97,114,103,0,0,0,0,0,0,0,0,110,97,109,101,0,0,0,0,110,97,109,101,119,104,97,116,0,0,0,0,0,0,0,0,105,115,116,97,105,108,99,97,108,108,0,0,0,0,0,0,97,99,116,105,118,101,108,105,110,101,115,0,0,0,0,0,102,117,110,99,0,0,0,0,101,120,116,101,114,110,97,108,32,104,111,111,107,0,0,0,108,117,97,95,100,101,98,117,103,62,32,0,0,0,0,0,99,111,110,116,10,0,0,0,61,40,100,101,98,117,103,32,99,111,109,109,97,110,100,41,0,0,0,0,0,0,0,0,37,115,10,0,0,0,0,0,80,49,0,0,88,49,0,0,96,49,0,0,104,49,0,0,112,49,0,0,120,49,0,0,128,49,0,0,136,49,0,0,144,49,0,0,160,49,0,0,168,49,0,0,176,49,0,0,184,49,0,0,192,49,0,0,200,49,0,0,208,49,0,0,216,49,0,0,224,49,0,0,232,49,0,0,240,49,0,0,248,49,0,0,0,50,0,0,8,50,0,0,16,50,0,0,24,50,0,0,32,50,0,0,40,50,0,0,48,50,0,0,56,50,0,0,64,50,0,0,72,50,0,0,88,50,0,0,96,50,0,0,0,0,0,0,39,37,99,39,0,0,0,0,99,104,97,114,40,37,100,41,0,0,0,0,0,0,0,0,39,37,115,39,0,0,0,0,95,69,78,86,0,0,0,0,105,110,118,97,108,105,100,32,108,111,110,103,32,115,116,114,105,110,103,32,100,101,108,105,109,105,116,101,114,0,0,0,46,0,0,0,0,0,0,0,69,101,0,0,0,0,0,0,88,120,0,0,0,0,0,0,80,112,0,0,0,0,0,0,43,45,0,0,0,0,0,0,109,97,108,102,111,114,109,101,100,32,110,117,109,98,101,114,0,0,0,0,0,0,0,0,108,101,120,105,99,97,108,32,101,108,101,109,101,110,116,32,116,111,111,32,108,111,110,103,0,0,0,0,0,0,0,0,117,110,102,105,110,105,115,104,101,100,32,115,116,114,105,110,103,0,0,0,0,0,0,0,105,110,118,97,108,105,100,32,101,115,99,97,112,101,32,115,101,113,117,101,110,99,101,0,100,101,99,105,109,97,108,32,101,115,99,97,112,101,32,116,111,111,32,108,97,114,103,101,0,0,0,0,0,0,0,0,104,101,120,97,100,101,99,105,109,97,108,32,100,105,103,105,116,32,101,120,112,101,99,116,101,100,0,0,0,0,0,0,117,110,102,105,110,105,115,104,101,100,32,108,111,110,103,32,115,116,114,105,110,103,0,0,117,110,102,105,110,105,115,104,101,100,32,108,111,110,103,32,99,111,109,109,101,110,116,0,99,104,117,110,107,32,104,97,115,32,116,111,111,32,109,97,110,121,32,108,105,110,101,115,0,0,0,0,0,0,0,0,37,115,58,37,100,58,32,37,115,0,0,0,0,0,0,0,37,115,32,110,101,97,114,32,37,115,0,0,0,0,0,0,97,110,100,0,0,0,0,0,98,114,101,97,107,0,0,0,100,111,0,0,0,0,0,0,101,108,115,101,0,0,0,0,101,108,115,101,105,102,0,0,101,110,100,0,0,0,0,0,102,97,108,115,101,0,0,0,102,111,114,0,0,0,0,0,102,117,110,99,116,105,111,110,0,0,0,0,0,0,0,0,103,111,116,111,0,0,0,0,105,102,0,0,0,0,0,0,105,110,0,0,0,0,0,0,108,111,99,97,108,0,0,0,110,105,108,0,0,0,0,0,110,111,116,0,0,0,0,0,111,114,0,0,0,0,0,0,114,101,112,101,97,116,0,0,114,101,116,117,114,110,0,0,116,104,101,110,0,0,0,0,116,114,117,101,0,0,0,0,117,110,116,105,108,0,0,0,119,104,105,108,101,0,0,0,46,46,0,0,0,0,0,0,46,46,46,0,0,0,0,0,61,61,0,0,0,0,0,0,62,61,0,0,0,0,0,0,60,61,0,0,0,0,0,0,126,61,0,0,0,0,0,0,58,58,0,0,0,0,0,0,60,101,111,102,62,0,0,0,60,110,117,109,98,101,114,62,0,0,0,0,0,0,0,0,60,110,97,109,101,62,0,0,60,115,116,114,105,110,103,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,105,110,102,105,110,105,116,121,0,0,0,0,0,0,0,0,110,97,110,0,0,0,0,0,95,112,137,0,255,9,47,15,10,0,0,0,100,0,0,0,232,3,0,0,16,39,0,0,160,134,1,0,64,66,15,0,128,150,152,0,0,225,245,5], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE+10240);
+
+
+
+
+var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);
+
+assert(tempDoublePtr % 8 == 0);
+
+function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+}
+
+function copyTempDouble(ptr) {
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+  HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];
+
+  HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];
+
+  HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];
+
+  HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];
+
+}
+
+
+
+
+  Module["_rand_r"] = _rand_r;
+
+  var ___rand_seed=allocate([0x0273459b, 0, 0, 0], "i32", ALLOC_STATIC);
+  Module["_rand"] = _rand;
+
+
+
+  var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};
+
+  var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can   access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};
+
+
+  var ___errno_state=0;function ___setErrNo(value) {
+      // For convenient setting and returning of errno.
+      HEAP32[((___errno_state)>>2)]=value;
+      return value;
+    }
+
+  var PATH={splitPath:function (filename) {
+        var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+        return splitPathRe.exec(filename).slice(1);
+      },normalizeArray:function (parts, allowAboveRoot) {
+        // if the path tries to go above the root, `up` ends up > 0
+        var up = 0;
+        for (var i = parts.length - 1; i >= 0; i--) {
+          var last = parts[i];
+          if (last === '.') {
+            parts.splice(i, 1);
+          } else if (last === '..') {
+            parts.splice(i, 1);
+            up++;
+          } else if (up) {
+            parts.splice(i, 1);
+            up--;
+          }
+        }
+        // if the path is allowed to go above the root, restore leading ..s
+        if (allowAboveRoot) {
+          for (; up--; up) {
+            parts.unshift('..');
+          }
+        }
+        return parts;
+      },normalize:function (path) {
+        var isAbsolute = path.charAt(0) === '/',
+            trailingSlash = path.substr(-1) === '/';
+        // Normalize the path
+        path = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), !isAbsolute).join('/');
+        if (!path && !isAbsolute) {
+          path = '.';
+        }
+        if (path && trailingSlash) {
+          path += '/';
+        }
+        return (isAbsolute ? '/' : '') + path;
+      },dirname:function (path) {
+        var result = PATH.splitPath(path),
+            root = result[0],
+            dir = result[1];
+        if (!root && !dir) {
+          // No dirname whatsoever
+          return '.';
+        }
+        if (dir) {
+          // It has a dirname, strip trailing slash
+          dir = dir.substr(0, dir.length - 1);
+        }
+        return root + dir;
+      },basename:function (path) {
+        // EMSCRIPTEN return '/'' for '/', not an empty string
+        if (path === '/') return '/';
+        var lastSlash = path.lastIndexOf('/');
+        if (lastSlash === -1) return path;
+        return path.substr(lastSlash+1);
+      },extname:function (path) {
+        return PATH.splitPath(path)[3];
+      },join:function () {
+        var paths = Array.prototype.slice.call(arguments, 0);
+        return PATH.normalize(paths.join('/'));
+      },join2:function (l, r) {
+        return PATH.normalize(l + '/' + r);
+      },resolve:function () {
+        var resolvedPath = '',
+          resolvedAbsolute = false;
+        for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+          var path = (i >= 0) ? arguments[i] : FS.cwd();
+          // Skip empty and invalid entries
+          if (typeof path !== 'string') {
+            throw new TypeError('Arguments to path.resolve must be strings');
+          } else if (!path) {
+            continue;
+          }
+          resolvedPath = path + '/' + resolvedPath;
+          resolvedAbsolute = path.charAt(0) === '/';
+        }
+        // At this point the path should be resolved to a full absolute path, but
+        // handle relative paths to be safe (might happen when process.cwd() fails)
+        resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
+          return !!p;
+        }), !resolvedAbsolute).join('/');
+        return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+      },relative:function (from, to) {
+        from = PATH.resolve(from).substr(1);
+        to = PATH.resolve(to).substr(1);
+        function trim(arr) {
+          var start = 0;
+          for (; start < arr.length; start++) {
+            if (arr[start] !== '') break;
+          }
+          var end = arr.length - 1;
+          for (; end >= 0; end--) {
+            if (arr[end] !== '') break;
+          }
+          if (start > end) return [];
+          return arr.slice(start, end - start + 1);
+        }
+        var fromParts = trim(from.split('/'));
+        var toParts = trim(to.split('/'));
+        var length = Math.min(fromParts.length, toParts.length);
+        var samePartsLength = length;
+        for (var i = 0; i < length; i++) {
+          if (fromParts[i] !== toParts[i]) {
+            samePartsLength = i;
+            break;
+          }
+        }
+        var outputParts = [];
+        for (var i = samePartsLength; i < fromParts.length; i++) {
+          outputParts.push('..');
+        }
+        outputParts = outputParts.concat(toParts.slice(samePartsLength));
+        return outputParts.join('/');
+      }};
+
+  var TTY={ttys:[],init:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // currently, FS.init does not distinguish if process.stdin is a file or TTY
+        //   // device, it always assumes it's a TTY device. because of this, we're forcing
+        //   // process.stdin to UTF8 encoding to at least make stdin reading compatible
+        //   // with text files until FS.init can be refactored.
+        //   process['stdin']['setEncoding']('utf8');
+        // }
+      },shutdown:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
+        //   // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
+        //   // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
+        //   // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
+        //   // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
+        //   process['stdin']['pause']();
+        // }
+      },register:function (dev, ops) {
+        TTY.ttys[dev] = { input: [], output: [], ops: ops };
+        FS.registerDevice(dev, TTY.stream_ops);
+      },stream_ops:{open:function (stream) {
+          var tty = TTY.ttys[stream.node.rdev];
+          if (!tty) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          stream.tty = tty;
+          stream.seekable = false;
+        },close:function (stream) {
+          // flush any pending line data
+          if (stream.tty.output.length) {
+            stream.tty.ops.put_char(stream.tty, 10);
+          }
+        },read:function (stream, buffer, offset, length, pos /* ignored */) {
+          if (!stream.tty || !stream.tty.ops.get_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          var bytesRead = 0;
+          for (var i = 0; i < length; i++) {
+            var result;
+            try {
+              result = stream.tty.ops.get_char(stream.tty);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            if (result === undefined && bytesRead === 0) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+            if (result === null || result === undefined) break;
+            bytesRead++;
+            buffer[offset+i] = result;
+          }
+          if (bytesRead) {
+            stream.node.timestamp = Date.now();
+          }
+          return bytesRead;
+        },write:function (stream, buffer, offset, length, pos) {
+          if (!stream.tty || !stream.tty.ops.put_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          for (var i = 0; i < length; i++) {
+            try {
+              stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+          }
+          if (length) {
+            stream.node.timestamp = Date.now();
+          }
+          return i;
+        }},default_tty_ops:{get_char:function (tty) {
+          if (!tty.input.length) {
+            var result = null;
+            if (ENVIRONMENT_IS_NODE) {
+              result = process['stdin']['read']();
+              if (!result) {
+                if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) {
+                  return null;  // EOF
+                }
+                return undefined;  // no data available
+              }
+            } else if (typeof window != 'undefined' &&
+              typeof window.prompt == 'function') {
+              // Browser.
+              result = window.prompt('Input: ');  // returns null on cancel
+              if (result !== null) {
+                result += '\n';
+              }
+            } else if (typeof readline == 'function') {
+              // Command line.
+              result = readline();
+              if (result !== null) {
+                result += '\n';
+              }
+            }
+            if (!result) {
+              return null;
+            }
+            tty.input = intArrayFromString(result, true);
+          }
+          return tty.input.shift();
+        },put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['print'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }},default_tty1_ops:{put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['printErr'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }}};
+
+  var MEMFS={ops_table:null,CONTENT_OWNING:1,CONTENT_FLEXIBLE:2,CONTENT_FIXED:3,mount:function (mount) {
+        return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
+          // no supported
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (!MEMFS.ops_table) {
+          MEMFS.ops_table = {
+            dir: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                lookup: MEMFS.node_ops.lookup,
+                mknod: MEMFS.node_ops.mknod,
+                rename: MEMFS.node_ops.rename,
+                unlink: MEMFS.node_ops.unlink,
+                rmdir: MEMFS.node_ops.rmdir,
+                readdir: MEMFS.node_ops.readdir,
+                symlink: MEMFS.node_ops.symlink
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek
+              }
+            },
+            file: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek,
+                read: MEMFS.stream_ops.read,
+                write: MEMFS.stream_ops.write,
+                allocate: MEMFS.stream_ops.allocate,
+                mmap: MEMFS.stream_ops.mmap
+              }
+            },
+            link: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                readlink: MEMFS.node_ops.readlink
+              },
+              stream: {}
+            },
+            chrdev: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: FS.chrdev_stream_ops
+            },
+          };
+        }
+        var node = FS.createNode(parent, name, mode, dev);
+        if (FS.isDir(node.mode)) {
+          node.node_ops = MEMFS.ops_table.dir.node;
+          node.stream_ops = MEMFS.ops_table.dir.stream;
+          node.contents = {};
+        } else if (FS.isFile(node.mode)) {
+          node.node_ops = MEMFS.ops_table.file.node;
+          node.stream_ops = MEMFS.ops_table.file.stream;
+          node.contents = [];
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        } else if (FS.isLink(node.mode)) {
+          node.node_ops = MEMFS.ops_table.link.node;
+          node.stream_ops = MEMFS.ops_table.link.stream;
+        } else if (FS.isChrdev(node.mode)) {
+          node.node_ops = MEMFS.ops_table.chrdev.node;
+          node.stream_ops = MEMFS.ops_table.chrdev.stream;
+        }
+        node.timestamp = Date.now();
+        // add the new node to the parent
+        if (parent) {
+          parent.contents[name] = node;
+        }
+        return node;
+      },ensureFlexible:function (node) {
+        if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
+          var contents = node.contents;
+          node.contents = Array.prototype.slice.call(contents);
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        }
+      },node_ops:{getattr:function (node) {
+          var attr = {};
+          // device numbers reuse inode numbers.
+          attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
+          attr.ino = node.id;
+          attr.mode = node.mode;
+          attr.nlink = 1;
+          attr.uid = 0;
+          attr.gid = 0;
+          attr.rdev = node.rdev;
+          if (FS.isDir(node.mode)) {
+            attr.size = 4096;
+          } else if (FS.isFile(node.mode)) {
+            attr.size = node.contents.length;
+          } else if (FS.isLink(node.mode)) {
+            attr.size = node.link.length;
+          } else {
+            attr.size = 0;
+          }
+          attr.atime = new Date(node.timestamp);
+          attr.mtime = new Date(node.timestamp);
+          attr.ctime = new Date(node.timestamp);
+          // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
+          //       but this is not required by the standard.
+          attr.blksize = 4096;
+          attr.blocks = Math.ceil(attr.size / attr.blksize);
+          return attr;
+        },setattr:function (node, attr) {
+          if (attr.mode !== undefined) {
+            node.mode = attr.mode;
+          }
+          if (attr.timestamp !== undefined) {
+            node.timestamp = attr.timestamp;
+          }
+          if (attr.size !== undefined) {
+            MEMFS.ensureFlexible(node);
+            var contents = node.contents;
+            if (attr.size < contents.length) contents.length = attr.size;
+            else while (attr.size > contents.length) contents.push(0);
+          }
+        },lookup:function (parent, name) {
+          throw FS.genericErrors[ERRNO_CODES.ENOENT];
+        },mknod:function (parent, name, mode, dev) {
+          return MEMFS.createNode(parent, name, mode, dev);
+        },rename:function (old_node, new_dir, new_name) {
+          // if we're overwriting a directory at new_name, make sure it's empty.
+          if (FS.isDir(old_node.mode)) {
+            var new_node;
+            try {
+              new_node = FS.lookupNode(new_dir, new_name);
+            } catch (e) {
+            }
+            if (new_node) {
+              for (var i in new_node.contents) {
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+              }
+            }
+          }
+          // do the internal rewiring
+          delete old_node.parent.contents[old_node.name];
+          old_node.name = new_name;
+          new_dir.contents[new_name] = old_node;
+          old_node.parent = new_dir;
+        },unlink:function (parent, name) {
+          delete parent.contents[name];
+        },rmdir:function (parent, name) {
+          var node = FS.lookupNode(parent, name);
+          for (var i in node.contents) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+          }
+          delete parent.contents[name];
+        },readdir:function (node) {
+          var entries = ['.', '..']
+          for (var key in node.contents) {
+            if (!node.contents.hasOwnProperty(key)) {
+              continue;
+            }
+            entries.push(key);
+          }
+          return entries;
+        },symlink:function (parent, newname, oldpath) {
+          var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
+          node.link = oldpath;
+          return node;
+        },readlink:function (node) {
+          if (!FS.isLink(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          return node.link;
+        }},stream_ops:{read:function (stream, buffer, offset, length, position) {
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (size > 8 && contents.subarray) { // non-trivial, and typed array
+            buffer.set(contents.subarray(position, position + size), offset);
+          } else
+          {
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          }
+          return size;
+        },write:function (stream, buffer, offset, length, position, canOwn) {
+          var node = stream.node;
+          node.timestamp = Date.now();
+          var contents = node.contents;
+          if (length && contents.length === 0 && position === 0 && buffer.subarray) {
+            // just replace it with the new data
+            if (canOwn && offset === 0) {
+              node.contents = buffer; // this could be a subarray of Emscripten HEAP, or allocated from some other source.
+              node.contentMode = (buffer.buffer === HEAP8.buffer) ? MEMFS.CONTENT_OWNING : MEMFS.CONTENT_FIXED;
+            } else {
+              node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
+              node.contentMode = MEMFS.CONTENT_FIXED;
+            }
+            return length;
+          }
+          MEMFS.ensureFlexible(node);
+          var contents = node.contents;
+          while (contents.length < position) contents.push(0);
+          for (var i = 0; i < length; i++) {
+            contents[position + i] = buffer[offset + i];
+          }
+          return length;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              position += stream.node.contents.length;
+            }
+          }
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          stream.ungotten = [];
+          stream.position = position;
+          return position;
+        },allocate:function (stream, offset, length) {
+          MEMFS.ensureFlexible(stream.node);
+          var contents = stream.node.contents;
+          var limit = offset + length;
+          while (limit > contents.length) contents.push(0);
+        },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+          if (!FS.isFile(stream.node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          var ptr;
+          var allocated;
+          var contents = stream.node.contents;
+          // Only make a new copy when MAP_PRIVATE is specified.
+          if ( !(flags & 2) &&
+                (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
+            // We can't emulate MAP_SHARED when the file is not backed by the buffer
+            // we're mapping to (e.g. the HEAP buffer).
+            allocated = false;
+            ptr = contents.byteOffset;
+          } else {
+            // Try to avoid unnecessary slices.
+            if (position > 0 || position + length < contents.length) {
+              if (contents.subarray) {
+                contents = contents.subarray(position, position + length);
+              } else {
+                contents = Array.prototype.slice.call(contents, position, position + length);
+              }
+            }
+            allocated = true;
+            ptr = _malloc(length);
+            if (!ptr) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOMEM);
+            }
+            buffer.set(contents, ptr);
+          }
+          return { ptr: ptr, allocated: allocated };
+        }}};
+
+  var IDBFS={dbs:{},indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) {
+        // reuse all of the core MEMFS functionality
+        return MEMFS.mount.apply(null, arguments);
+      },syncfs:function (mount, populate, callback) {
+        IDBFS.getLocalSet(mount, function(err, local) {
+          if (err) return callback(err);
+
+          IDBFS.getRemoteSet(mount, function(err, remote) {
+            if (err) return callback(err);
+
+            var src = populate ? remote : local;
+            var dst = populate ? local : remote;
+
+            IDBFS.reconcile(src, dst, callback);
+          });
+        });
+      },getDB:function (name, callback) {
+        // check the cache first
+        var db = IDBFS.dbs[name];
+        if (db) {
+          return callback(null, db);
+        }
+
+        var req;
+        try {
+          req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
+        } catch (e) {
+          return callback(e);
+        }
+        req.onupgradeneeded = function(e) {
+          var db = e.target.result;
+          var transaction = e.target.transaction;
+
+          var fileStore;
+
+          if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
+            fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          } else {
+            fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
+          }
+
+          fileStore.createIndex('timestamp', 'timestamp', { unique: false });
+        };
+        req.onsuccess = function() {
+          db = req.result;
+
+          // add to the cache
+          IDBFS.dbs[name] = db;
+          callback(null, db);
+        };
+        req.onerror = function() {
+          callback(this.error);
+        };
+      },getLocalSet:function (mount, callback) {
+        var entries = {};
+
+        function isRealDir(p) {
+          return p !== '.' && p !== '..';
+        };
+        function toAbsolute(root) {
+          return function(p) {
+            return PATH.join2(root, p);
+          }
+        };
+
+        var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
+
+        while (check.length) {
+          var path = check.pop();
+          var stat;
+
+          try {
+            stat = FS.stat(path);
+          } catch (e) {
+            return callback(e);
+          }
+
+          if (FS.isDir(stat.mode)) {
+            check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
+          }
+
+          entries[path] = { timestamp: stat.mtime };
+        }
+
+        return callback(null, { type: 'local', entries: entries });
+      },getRemoteSet:function (mount, callback) {
+        var entries = {};
+
+        IDBFS.getDB(mount.mountpoint, function(err, db) {
+          if (err) return callback(err);
+
+          var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly');
+          transaction.onerror = function() { callback(this.error); };
+
+          var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          var index = store.index('timestamp');
+
+          index.openKeyCursor().onsuccess = function(event) {
+            var cursor = event.target.result;
+
+            if (!cursor) {
+              return callback(null, { type: 'remote', db: db, entries: entries });
+            }
+
+            entries[cursor.primaryKey] = { timestamp: cursor.key };
+
+            cursor.continue();
+          };
+        });
+      },loadLocalEntry:function (path, callback) {
+        var stat, node;
+
+        try {
+          var lookup = FS.lookupPath(path);
+          node = lookup.node;
+          stat = FS.stat(path);
+        } catch (e) {
+          return callback(e);
+        }
+
+        if (FS.isDir(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode });
+        } else if (FS.isFile(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents });
+        } else {
+          return callback(new Error('node type not supported'));
+        }
+      },storeLocalEntry:function (path, entry, callback) {
+        try {
+          if (FS.isDir(entry.mode)) {
+            FS.mkdir(path, entry.mode);
+          } else if (FS.isFile(entry.mode)) {
+            FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true });
+          } else {
+            return callback(new Error('node type not supported'));
+          }
+
+          FS.utime(path, entry.timestamp, entry.timestamp);
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },removeLocalEntry:function (path, callback) {
+        try {
+          var lookup = FS.lookupPath(path);
+          var stat = FS.stat(path);
+
+          if (FS.isDir(stat.mode)) {
+            FS.rmdir(path);
+          } else if (FS.isFile(stat.mode)) {
+            FS.unlink(path);
+          }
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },loadRemoteEntry:function (store, path, callback) {
+        var req = store.get(path);
+        req.onsuccess = function(event) { callback(null, event.target.result); };
+        req.onerror = function() { callback(this.error); };
+      },storeRemoteEntry:function (store, path, entry, callback) {
+        var req = store.put(entry, path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },removeRemoteEntry:function (store, path, callback) {
+        var req = store.delete(path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },reconcile:function (src, dst, callback) {
+        var total = 0;
+
+        var create = [];
+        Object.keys(src.entries).forEach(function (key) {
+          var e = src.entries[key];
+          var e2 = dst.entries[key];
+          if (!e2 || e.timestamp > e2.timestamp) {
+            create.push(key);
+            total++;
+          }
+        });
+
+        var remove = [];
+        Object.keys(dst.entries).forEach(function (key) {
+          var e = dst.entries[key];
+          var e2 = src.entries[key];
+          if (!e2) {
+            remove.push(key);
+            total++;
+          }
+        });
+
+        if (!total) {
+          return callback(null);
+        }
+
+        var errored = false;
+        var completed = 0;
+        var db = src.type === 'remote' ? src.db : dst.db;
+        var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
+        var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= total) {
+            return callback(null);
+          }
+        };
+
+        transaction.onerror = function() { done(this.error); };
+
+        // sort paths in ascending order so directory entries are created
+        // before the files inside them
+        create.sort().forEach(function (path) {
+          if (dst.type === 'local') {
+            IDBFS.loadRemoteEntry(store, path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeLocalEntry(path, entry, done);
+            });
+          } else {
+            IDBFS.loadLocalEntry(path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeRemoteEntry(store, path, entry, done);
+            });
+          }
+        });
+
+        // sort paths in descending order so files are deleted before their
+        // parent directories
+        remove.sort().reverse().forEach(function(path) {
+          if (dst.type === 'local') {
+            IDBFS.removeLocalEntry(path, done);
+          } else {
+            IDBFS.removeRemoteEntry(store, path, done);
+          }
+        });
+      }};
+
+  var NODEFS={isWindows:false,staticInit:function () {
+        NODEFS.isWindows = !!process.platform.match(/^win/);
+      },mount:function (mount) {
+        assert(ENVIRONMENT_IS_NODE);
+        return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node = FS.createNode(parent, name, mode);
+        node.node_ops = NODEFS.node_ops;
+        node.stream_ops = NODEFS.stream_ops;
+        return node;
+      },getMode:function (path) {
+        var stat;
+        try {
+          stat = fs.lstatSync(path);
+          if (NODEFS.isWindows) {
+            // On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so
+            // propagate write bits to execute bits.
+            stat.mode = stat.mode | ((stat.mode & 146) >> 1);
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        return stat.mode;
+      },realPath:function (node) {
+        var parts = [];
+        while (node.parent !== node) {
+          parts.push(node.name);
+          node = node.parent;
+        }
+        parts.push(node.mount.opts.root);
+        parts.reverse();
+        return PATH.join.apply(null, parts);
+      },flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) {
+        if (flags in NODEFS.flagsToPermissionStringMap) {
+          return NODEFS.flagsToPermissionStringMap[flags];
+        } else {
+          return flags;
+        }
+      },node_ops:{getattr:function (node) {
+          var path = NODEFS.realPath(node);
+          var stat;
+          try {
+            stat = fs.lstatSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096.
+          // See http://support.microsoft.com/kb/140365
+          if (NODEFS.isWindows && !stat.blksize) {
+            stat.blksize = 4096;
+          }
+          if (NODEFS.isWindows && !stat.blocks) {
+            stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0;
+          }
+          return {
+            dev: stat.dev,
+            ino: stat.ino,
+            mode: stat.mode,
+            nlink: stat.nlink,
+            uid: stat.uid,
+            gid: stat.gid,
+            rdev: stat.rdev,
+            size: stat.size,
+            atime: stat.atime,
+            mtime: stat.mtime,
+            ctime: stat.ctime,
+            blksize: stat.blksize,
+            blocks: stat.blocks
+          };
+        },setattr:function (node, attr) {
+          var path = NODEFS.realPath(node);
+          try {
+            if (attr.mode !== undefined) {
+              fs.chmodSync(path, attr.mode);
+              // update the common node structure mode as well
+              node.mode = attr.mode;
+            }
+            if (attr.timestamp !== undefined) {
+              var date = new Date(attr.timestamp);
+              fs.utimesSync(path, date, date);
+            }
+            if (attr.size !== undefined) {
+              fs.truncateSync(path, attr.size);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },lookup:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          var mode = NODEFS.getMode(path);
+          return NODEFS.createNode(parent, name, mode);
+        },mknod:function (parent, name, mode, dev) {
+          var node = NODEFS.createNode(parent, name, mode, dev);
+          // create the backing node for this in the fs root as well
+          var path = NODEFS.realPath(node);
+          try {
+            if (FS.isDir(node.mode)) {
+              fs.mkdirSync(path, node.mode);
+            } else {
+              fs.writeFileSync(path, '', { mode: node.mode });
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return node;
+        },rename:function (oldNode, newDir, newName) {
+          var oldPath = NODEFS.realPath(oldNode);
+          var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
+          try {
+            fs.renameSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },unlink:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.unlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },rmdir:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.rmdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readdir:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },symlink:function (parent, newName, oldPath) {
+          var newPath = PATH.join2(NODEFS.realPath(parent), newName);
+          try {
+            fs.symlinkSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readlink:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        }},stream_ops:{open:function (stream) {
+          var path = NODEFS.realPath(stream.node);
+          try {
+            if (FS.isFile(stream.node.mode)) {
+              stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags));
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },close:function (stream) {
+          try {
+            if (FS.isFile(stream.node.mode) && stream.nfd) {
+              fs.closeSync(stream.nfd);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },read:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(length);
+          var res;
+          try {
+            res = fs.readSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          if (res > 0) {
+            for (var i = 0; i < res; i++) {
+              buffer[offset + i] = nbuffer[i];
+            }
+          }
+          return res;
+        },write:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(buffer.subarray(offset, offset + length));
+          var res;
+          try {
+            res = fs.writeSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return res;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              try {
+                var stat = fs.fstatSync(stream.nfd);
+                position += stat.size;
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+              }
+            }
+          }
+
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+
+          stream.position = position;
+          return position;
+        }}};
+
+  var _stdin=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stdout=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stderr=allocate(1, "i32*", ALLOC_STATIC);
+
+  function _fflush(stream) {
+      // int fflush(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html
+      // we don't currently perform any user-space buffering of data
+    }var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},handleFSError:function (e) {
+        if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
+        return ___setErrNo(e.errno);
+      },lookupPath:function (path, opts) {
+        path = PATH.resolve(FS.cwd(), path);
+        opts = opts || {};
+
+        var defaults = {
+          follow_mount: true,
+          recurse_count: 0
+        };
+        for (var key in defaults) {
+          if (opts[key] === undefined) {
+            opts[key] = defaults[key];
+          }
+        }
+
+        if (opts.recurse_count > 8) {  // max recursive lookup of 8
+          throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+        }
+
+        // split the path
+        var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), false);
+
+        // start at the root
+        var current = FS.root;
+        var current_path = '/';
+
+        for (var i = 0; i < parts.length; i++) {
+          var islast = (i === parts.length-1);
+          if (islast && opts.parent) {
+            // stop resolving
+            break;
+          }
+
+          current = FS.lookupNode(current, parts[i]);
+          current_path = PATH.join2(current_path, parts[i]);
+
+          // jump to the mount's root node if this is a mountpoint
+          if (FS.isMountpoint(current)) {
+            if (!islast || (islast && opts.follow_mount)) {
+              current = current.mounted.root;
+            }
+          }
+
+          // by default, lookupPath will not follow a symlink if it is the final path component.
+          // setting opts.follow = true will override this behavior.
+          if (!islast || opts.follow) {
+            var count = 0;
+            while (FS.isLink(current.mode)) {
+              var link = FS.readlink(current_path);
+              current_path = PATH.resolve(PATH.dirname(current_path), link);
+
+              var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
+              current = lookup.node;
+
+              if (count++ > 40) {  // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
+                throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+              }
+            }
+          }
+        }
+
+        return { path: current_path, node: current };
+      },getPath:function (node) {
+        var path;
+        while (true) {
+          if (FS.isRoot(node)) {
+            var mount = node.mount.mountpoint;
+            if (!path) return mount;
+            return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
+          }
+          path = path ? node.name + '/' + path : node.name;
+          node = node.parent;
+        }
+      },hashName:function (parentid, name) {
+        var hash = 0;
+
+
+        for (var i = 0; i < name.length; i++) {
+          hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
+        }
+        return ((parentid + hash) >>> 0) % FS.nameTable.length;
+      },hashAddNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        node.name_next = FS.nameTable[hash];
+        FS.nameTable[hash] = node;
+      },hashRemoveNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        if (FS.nameTable[hash] === node) {
+          FS.nameTable[hash] = node.name_next;
+        } else {
+          var current = FS.nameTable[hash];
+          while (current) {
+            if (current.name_next === node) {
+              current.name_next = node.name_next;
+              break;
+            }
+            current = current.name_next;
+          }
+        }
+      },lookupNode:function (parent, name) {
+        var err = FS.mayLookup(parent);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        var hash = FS.hashName(parent.id, name);
+        for (var node = FS.nameTable[hash]; node; node = node.name_next) {
+          var nodeName = node.name;
+          if (node.parent.id === parent.id && nodeName === name) {
+            return node;
+          }
+        }
+        // if we failed to find it in the cache, call into the VFS
+        return FS.lookup(parent, name);
+      },createNode:function (parent, name, mode, rdev) {
+        if (!FS.FSNode) {
+          FS.FSNode = function(parent, name, mode, rdev) {
+            if (!parent) {
+              parent = this;  // root node sets parent to itself
+            }
+            this.parent = parent;
+            this.mount = parent.mount;
+            this.mounted = null;
+            this.id = FS.nextInode++;
+            this.name = name;
+            this.mode = mode;
+            this.node_ops = {};
+            this.stream_ops = {};
+            this.rdev = rdev;
+          };
+
+          FS.FSNode.prototype = {};
+
+          // compatibility
+          var readMode = 292 | 73;
+          var writeMode = 146;
+
+          // NOTE we must use Object.defineProperties instead of individual calls to
+          // Object.defineProperty in order to make closure compiler happy
+          Object.defineProperties(FS.FSNode.prototype, {
+            read: {
+              get: function() { return (this.mode & readMode) === readMode; },
+              set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; }
+            },
+            write: {
+              get: function() { return (this.mode & writeMode) === writeMode; },
+              set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; }
+            },
+            isFolder: {
+              get: function() { return FS.isDir(this.mode); },
+            },
+            isDevice: {
+              get: function() { return FS.isChrdev(this.mode); },
+            },
+          });
+        }
+
+        var node = new FS.FSNode(parent, name, mode, rdev);
+
+        FS.hashAddNode(node);
+
+        return node;
+      },destroyNode:function (node) {
+        FS.hashRemoveNode(node);
+      },isRoot:function (node) {
+        return node === node.parent;
+      },isMountpoint:function (node) {
+        return !!node.mounted;
+      },isFile:function (mode) {
+        return (mode & 61440) === 32768;
+      },isDir:function (mode) {
+        return (mode & 61440) === 16384;
+      },isLink:function (mode) {
+        return (mode & 61440) === 40960;
+      },isChrdev:function (mode) {
+        return (mode & 61440) === 8192;
+      },isBlkdev:function (mode) {
+        return (mode & 61440) === 24576;
+      },isFIFO:function (mode) {
+        return (mode & 61440) === 4096;
+      },isSocket:function (mode) {
+        return (mode & 49152) === 49152;
+      },flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function (str) {
+        var flags = FS.flagModes[str];
+        if (typeof flags === 'undefined') {
+          throw new Error('Unknown file open mode: ' + str);
+        }
+        return flags;
+      },flagsToPermissionString:function (flag) {
+        var accmode = flag & 2097155;
+        var perms = ['r', 'w', 'rw'][accmode];
+        if ((flag & 512)) {
+          perms += 'w';
+        }
+        return perms;
+      },nodePermissions:function (node, perms) {
+        if (FS.ignorePermissions) {
+          return 0;
+        }
+        // return 0 if any user, group or owner bits are set.
+        if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
+          return ERRNO_CODES.EACCES;
+        }
+        return 0;
+      },mayLookup:function (dir) {
+        return FS.nodePermissions(dir, 'x');
+      },mayCreate:function (dir, name) {
+        try {
+          var node = FS.lookupNode(dir, name);
+          return ERRNO_CODES.EEXIST;
+        } catch (e) {
+        }
+        return FS.nodePermissions(dir, 'wx');
+      },mayDelete:function (dir, name, isdir) {
+        var node;
+        try {
+          node = FS.lookupNode(dir, name);
+        } catch (e) {
+          return e.errno;
+        }
+        var err = FS.nodePermissions(dir, 'wx');
+        if (err) {
+          return err;
+        }
+        if (isdir) {
+          if (!FS.isDir(node.mode)) {
+            return ERRNO_CODES.ENOTDIR;
+          }
+          if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
+            return ERRNO_CODES.EBUSY;
+          }
+        } else {
+          if (FS.isDir(node.mode)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return 0;
+      },mayOpen:function (node, flags) {
+        if (!node) {
+          return ERRNO_CODES.ENOENT;
+        }
+        if (FS.isLink(node.mode)) {
+          return ERRNO_CODES.ELOOP;
+        } else if (FS.isDir(node.mode)) {
+          if ((flags & 2097155) !== 0 ||  // opening for write
+              (flags & 512)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
+      },MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) {
+        fd_start = fd_start || 0;
+        fd_end = fd_end || FS.MAX_OPEN_FDS;
+        for (var fd = fd_start; fd <= fd_end; fd++) {
+          if (!FS.streams[fd]) {
+            return fd;
+          }
+        }
+        throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
+      },getStream:function (fd) {
+        return FS.streams[fd];
+      },createStream:function (stream, fd_start, fd_end) {
+        if (!FS.FSStream) {
+          FS.FSStream = function(){};
+          FS.FSStream.prototype = {};
+          // compatibility
+          Object.defineProperties(FS.FSStream.prototype, {
+            object: {
+              get: function() { return this.node; },
+              set: function(val) { this.node = val; }
+            },
+            isRead: {
+              get: function() { return (this.flags & 2097155) !== 1; }
+            },
+            isWrite: {
+              get: function() { return (this.flags & 2097155) !== 0; }
+            },
+            isAppend: {
+              get: function() { return (this.flags & 1024); }
+            }
+          });
+        }
+        if (0) {
+          // reuse the object
+          stream.__proto__ = FS.FSStream.prototype;
+        } else {
+          var newStream = new FS.FSStream();
+          for (var p in stream) {
+            newStream[p] = stream[p];
+          }
+          stream = newStream;
+        }
+        var fd = FS.nextfd(fd_start, fd_end);
+        stream.fd = fd;
+        FS.streams[fd] = stream;
+        return stream;
+      },closeStream:function (fd) {
+        FS.streams[fd] = null;
+      },getStreamFromPtr:function (ptr) {
+        return FS.streams[ptr - 1];
+      },getPtrForStream:function (stream) {
+        return stream ? stream.fd + 1 : 0;
+      },chrdev_stream_ops:{open:function (stream) {
+          var device = FS.getDevice(stream.node.rdev);
+          // override node's stream ops with the device's
+          stream.stream_ops = device.stream_ops;
+          // forward the open call
+          if (stream.stream_ops.open) {
+            stream.stream_ops.open(stream);
+          }
+        },llseek:function () {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }},major:function (dev) {
+        return ((dev) >> 8);
+      },minor:function (dev) {
+        return ((dev) & 0xff);
+      },makedev:function (ma, mi) {
+        return ((ma) << 8 | (mi));
+      },registerDevice:function (dev, ops) {
+        FS.devices[dev] = { stream_ops: ops };
+      },getDevice:function (dev) {
+        return FS.devices[dev];
+      },getMounts:function (mount) {
+        var mounts = [];
+        var check = [mount];
+
+        while (check.length) {
+          var m = check.pop();
+
+          mounts.push(m);
+
+          check.push.apply(check, m.mounts);
+        }
+
+        return mounts;
+      },syncfs:function (populate, callback) {
+        if (typeof(populate) === 'function') {
+          callback = populate;
+          populate = false;
+        }
+
+        var mounts = FS.getMounts(FS.root.mount);
+        var completed = 0;
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= mounts.length) {
+            callback(null);
+          }
+        };
+
+        // sync all mounts
+        mounts.forEach(function (mount) {
+          if (!mount.type.syncfs) {
+            return done(null);
+          }
+          mount.type.syncfs(mount, populate, done);
+        });
+      },mount:function (type, opts, mountpoint) {
+        var root = mountpoint === '/';
+        var pseudo = !mountpoint;
+        var node;
+
+        if (root && FS.root) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        } else if (!root && !pseudo) {
+          var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+          mountpoint = lookup.path;  // use the absolute path
+          node = lookup.node;
+
+          if (FS.isMountpoint(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+          }
+
+          if (!FS.isDir(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+          }
+        }
+
+        var mount = {
+          type: type,
+          opts: opts,
+          mountpoint: mountpoint,
+          mounts: []
+        };
+
+        // create a root node for the fs
+        var mountRoot = type.mount(mount);
+        mountRoot.mount = mount;
+        mount.root = mountRoot;
+
+        if (root) {
+          FS.root = mountRoot;
+        } else if (node) {
+          // set as a mountpoint
+          node.mounted = mount;
+
+          // add the new mount to the current mount's children
+          if (node.mount) {
+            node.mount.mounts.push(mount);
+          }
+        }
+
+        return mountRoot;
+      },unmount:function (mountpoint) {
+        var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+        if (!FS.isMountpoint(lookup.node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+
+        // destroy the nodes for this mount, and all its child mounts
+        var node = lookup.node;
+        var mount = node.mounted;
+        var mounts = FS.getMounts(mount);
+
+        Object.keys(FS.nameTable).forEach(function (hash) {
+          var current = FS.nameTable[hash];
+
+          while (current) {
+            var next = current.name_next;
+
+            if (mounts.indexOf(current.mount) !== -1) {
+              FS.destroyNode(current);
+            }
+
+            current = next;
+          }
+        });
+
+        // no longer a mountpoint
+        node.mounted = null;
+
+        // remove this mount from the child mounts
+        var idx = node.mount.mounts.indexOf(mount);
+        assert(idx !== -1);
+        node.mount.mounts.splice(idx, 1);
+      },lookup:function (parent, name) {
+        return parent.node_ops.lookup(parent, name);
+      },mknod:function (path, mode, dev) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var err = FS.mayCreate(parent, name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.mknod) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.mknod(parent, name, mode, dev);
+      },create:function (path, mode) {
+        mode = mode !== undefined ? mode : 438 /* 0666 */;
+        mode &= 4095;
+        mode |= 32768;
+        return FS.mknod(path, mode, 0);
+      },mkdir:function (path, mode) {
+        mode = mode !== undefined ? mode : 511 /* 0777 */;
+        mode &= 511 | 512;
+        mode |= 16384;
+        return FS.mknod(path, mode, 0);
+      },mkdev:function (path, mode, dev) {
+        if (typeof(dev) === 'undefined') {
+          dev = mode;
+          mode = 438 /* 0666 */;
+        }
+        mode |= 8192;
+        return FS.mknod(path, mode, dev);
+      },symlink:function (oldpath, newpath) {
+        var lookup = FS.lookupPath(newpath, { parent: true });
+        var parent = lookup.node;
+        var newname = PATH.basename(newpath);
+        var err = FS.mayCreate(parent, newname);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.symlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.symlink(parent, newname, oldpath);
+      },rename:function (old_path, new_path) {
+        var old_dirname = PATH.dirname(old_path);
+        var new_dirname = PATH.dirname(new_path);
+        var old_name = PATH.basename(old_path);
+        var new_name = PATH.basename(new_path);
+        // parents must exist
+        var lookup, old_dir, new_dir;
+        try {
+          lookup = FS.lookupPath(old_path, { parent: true });
+          old_dir = lookup.node;
+          lookup = FS.lookupPath(new_path, { parent: true });
+          new_dir = lookup.node;
+        } catch (e) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // need to be part of the same mount
+        if (old_dir.mount !== new_dir.mount) {
+          throw new FS.ErrnoError(ERRNO_CODES.EXDEV);
+        }
+        // source must exist
+        var old_node = FS.lookupNode(old_dir, old_name);
+        // old path should not be an ancestor of the new path
+        var relative = PATH.relative(old_path, new_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        // new path should not be an ancestor of the old path
+        relative = PATH.relative(new_path, old_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+        }
+        // see if the new path already exists
+        var new_node;
+        try {
+          new_node = FS.lookupNode(new_dir, new_name);
+        } catch (e) {
+          // not fatal
+        }
+        // early out if nothing needs to change
+        if (old_node === new_node) {
+          return;
+        }
+        // we'll need to delete the old entry
+        var isdir = FS.isDir(old_node.mode);
+        var err = FS.mayDelete(old_dir, old_name, isdir);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // need delete permissions if we'll be overwriting.
+        // need create permissions if new doesn't already exist.
+        err = new_node ?
+          FS.mayDelete(new_dir, new_name, isdir) :
+          FS.mayCreate(new_dir, new_name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!old_dir.node_ops.rename) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // if we are going to change the parent, check write permissions
+        if (new_dir !== old_dir) {
+          err = FS.nodePermissions(old_dir, 'w');
+          if (err) {
+            throw new FS.ErrnoError(err);
+          }
+        }
+        // remove the node from the lookup hash
+        FS.hashRemoveNode(old_node);
+        // do the underlying fs rename
+        try {
+          old_dir.node_ops.rename(old_node, new_dir, new_name);
+        } catch (e) {
+          throw e;
+        } finally {
+          // add the node back to the hash (in case node_ops.rename
+          // changed its name)
+          FS.hashAddNode(old_node);
+        }
+      },rmdir:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, true);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.rmdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.rmdir(parent, name);
+        FS.destroyNode(node);
+      },readdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        if (!node.node_ops.readdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        return node.node_ops.readdir(node);
+      },unlink:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, false);
+        if (err) {
+          // POSIX says unlink should set EPERM, not EISDIR
+          if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM;
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.unlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.unlink(parent, name);
+        FS.destroyNode(node);
+      },readlink:function (path) {
+        var lookup = FS.lookupPath(path);
+        var link = lookup.node;
+        if (!link.node_ops.readlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        return link.node_ops.readlink(link);
+      },stat:function (path, dontFollow) {
+        var lookup = FS.lookupPath(path, { follow: !dontFollow });
+        var node = lookup.node;
+        if (!node.node_ops.getattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return node.node_ops.getattr(node);
+      },lstat:function (path) {
+        return FS.stat(path, true);
+      },chmod:function (path, mode, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          mode: (mode & 4095) | (node.mode & ~4095),
+          timestamp: Date.now()
+        });
+      },lchmod:function (path, mode) {
+        FS.chmod(path, mode, true);
+      },fchmod:function (fd, mode) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chmod(stream.node, mode);
+      },chown:function (path, uid, gid, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          timestamp: Date.now()
+          // we ignore the uid / gid for now
+        });
+      },lchown:function (path, uid, gid) {
+        FS.chown(path, uid, gid, true);
+      },fchown:function (fd, uid, gid) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chown(stream.node, uid, gid);
+      },truncate:function (path, len) {
+        if (len < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: true });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!FS.isFile(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var err = FS.nodePermissions(node, 'w');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        node.node_ops.setattr(node, {
+          size: len,
+          timestamp: Date.now()
+        });
+      },ftruncate:function (fd, len) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        FS.truncate(stream.node, len);
+      },utime:function (path, atime, mtime) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        node.node_ops.setattr(node, {
+          timestamp: Math.max(atime, mtime)
+        });
+      },open:function (path, flags, mode, fd_start, fd_end) {
+        flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
+        mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
+        if ((flags & 64)) {
+          mode = (mode & 4095) | 32768;
+        } else {
+          mode = 0;
+        }
+        var node;
+        if (typeof path === 'object') {
+          node = path;
+        } else {
+          path = PATH.normalize(path);
+          try {
+            var lookup = FS.lookupPath(path, {
+              follow: !(flags & 131072)
+            });
+            node = lookup.node;
+          } catch (e) {
+            // ignore
+          }
+        }
+        // perhaps we need to create the node
+        if ((flags & 64)) {
+          if (node) {
+            // if O_CREAT and O_EXCL are set, error out if the node already exists
+            if ((flags & 128)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EEXIST);
+            }
+          } else {
+            // node doesn't exist, try to create it
+            node = FS.mknod(path, mode, 0);
+          }
+        }
+        if (!node) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
+        }
+        // can't truncate a device
+        if (FS.isChrdev(node.mode)) {
+          flags &= ~512;
+        }
+        // check permissions
+        var err = FS.mayOpen(node, flags);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // do truncation if necessary
+        if ((flags & 512)) {
+          FS.truncate(node, 0);
+        }
+        // we've already handled these, don't pass down to the underlying vfs
+        flags &= ~(128 | 512);
+
+        // register the stream with the filesystem
+        var stream = FS.createStream({
+          node: node,
+          path: FS.getPath(node),  // we want the absolute path to the node
+          flags: flags,
+          seekable: true,
+          position: 0,
+          stream_ops: node.stream_ops,
+          // used by the file family libc calls (fopen, fwrite, ferror, etc.)
+          ungotten: [],
+          error: false
+        }, fd_start, fd_end);
+        // call the new stream's open function
+        if (stream.stream_ops.open) {
+          stream.stream_ops.open(stream);
+        }
+        if (Module['logReadFiles'] && !(flags & 1)) {
+          if (!FS.readFiles) FS.readFiles = {};
+          if (!(path in FS.readFiles)) {
+            FS.readFiles[path] = 1;
+            Module['printErr']('read file: ' + path);
+          }
+        }
+        return stream;
+      },close:function (stream) {
+        try {
+          if (stream.stream_ops.close) {
+            stream.stream_ops.close(stream);
+          }
+        } catch (e) {
+          throw e;
+        } finally {
+          FS.closeStream(stream.fd);
+        }
+      },llseek:function (stream, offset, whence) {
+        if (!stream.seekable || !stream.stream_ops.llseek) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        return stream.stream_ops.llseek(stream, offset, whence);
+      },read:function (stream, buffer, offset, length, position) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.read) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
+        if (!seeking) stream.position += bytesRead;
+        return bytesRead;
+      },write:function (stream, buffer, offset, length, position, canOwn) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.write) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        if (stream.flags & 1024) {
+          // seek to the end before writing in append mode
+          FS.llseek(stream, 0, 2);
+        }
+        var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
+        if (!seeking) stream.position += bytesWritten;
+        return bytesWritten;
+      },allocate:function (stream, offset, length) {
+        if (offset < 0 || length <= 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        if (!stream.stream_ops.allocate) {
+          throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+        }
+        stream.stream_ops.allocate(stream, offset, length);
+      },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+        // TODO if PROT is PROT_WRITE, make sure we have write access
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EACCES);
+        }
+        if (!stream.stream_ops.mmap) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
+      },ioctl:function (stream, cmd, arg) {
+        if (!stream.stream_ops.ioctl) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTTY);
+        }
+        return stream.stream_ops.ioctl(stream, cmd, arg);
+      },readFile:function (path, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'r';
+        opts.encoding = opts.encoding || 'binary';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var ret;
+        var stream = FS.open(path, opts.flags);
+        var stat = FS.stat(path);
+        var length = stat.size;
+        var buf = new Uint8Array(length);
+        FS.read(stream, buf, 0, length, 0);
+        if (opts.encoding === 'utf8') {
+          ret = '';
+          var utf8 = new Runtime.UTF8Processor();
+          for (var i = 0; i < length; i++) {
+            ret += utf8.processCChar(buf[i]);
+          }
+        } else if (opts.encoding === 'binary') {
+          ret = buf;
+        }
+        FS.close(stream);
+        return ret;
+      },writeFile:function (path, data, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'w';
+        opts.encoding = opts.encoding || 'utf8';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var stream = FS.open(path, opts.flags, opts.mode);
+        if (opts.encoding === 'utf8') {
+          var utf8 = new Runtime.UTF8Processor();
+          var buf = new Uint8Array(utf8.processJSString(data));
+          FS.write(stream, buf, 0, buf.length, 0, opts.canOwn);
+        } else if (opts.encoding === 'binary') {
+          FS.write(stream, data, 0, data.length, 0, opts.canOwn);
+        }
+        FS.close(stream);
+      },cwd:function () {
+        return FS.currentPath;
+      },chdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        if (!FS.isDir(lookup.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        var err = FS.nodePermissions(lookup.node, 'x');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        FS.currentPath = lookup.path;
+      },createDefaultDirectories:function () {
+        FS.mkdir('/tmp');
+      },createDefaultDevices:function () {
+        // create /dev
+        FS.mkdir('/dev');
+        // setup /dev/null
+        FS.registerDevice(FS.makedev(1, 3), {
+          read: function() { return 0; },
+          write: function() { return 0; }
+        });
+        FS.mkdev('/dev/null', FS.makedev(1, 3));
+        // setup /dev/tty and /dev/tty1
+        // stderr needs to print output using Module['printErr']
+        // so we register a second tty just for it.
+        TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
+        TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
+        FS.mkdev('/dev/tty', FS.makedev(5, 0));
+        FS.mkdev('/dev/tty1', FS.makedev(6, 0));
+        // we're not going to emulate the actual shm device,
+        // just create the tmp dirs that reside in it commonly
+        FS.mkdir('/dev/shm');
+        FS.mkdir('/dev/shm/tmp');
+      },createStandardStreams:function () {
+        // TODO deprecate the old functionality of a single
+        // input / output callback and that utilizes FS.createDevice
+        // and instead require a unique set of stream ops
+
+        // by default, we symlink the standard streams to the
+        // default tty devices. however, if the standard streams
+        // have been overwritten we create a unique device for
+        // them instead.
+        if (Module['stdin']) {
+          FS.createDevice('/dev', 'stdin', Module['stdin']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdin');
+        }
+        if (Module['stdout']) {
+          FS.createDevice('/dev', 'stdout', null, Module['stdout']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdout');
+        }
+        if (Module['stderr']) {
+          FS.createDevice('/dev', 'stderr', null, Module['stderr']);
+        } else {
+          FS.symlink('/dev/tty1', '/dev/stderr');
+        }
+
+        // open default streams for the stdin, stdout and stderr devices
+        var stdin = FS.open('/dev/stdin', 'r');
+        HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin);
+        assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
+
+        var stdout = FS.open('/dev/stdout', 'w');
+        HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout);
+        assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
+
+        var stderr = FS.open('/dev/stderr', 'w');
+        HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr);
+        assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
+      },ensureErrnoError:function () {
+        if (FS.ErrnoError) return;
+        FS.ErrnoError = function ErrnoError(errno) {
+          this.errno = errno;
+          for (var key in ERRNO_CODES) {
+            if (ERRNO_CODES[key] === errno) {
+              this.code = key;
+              break;
+            }
+          }
+          this.message = ERRNO_MESSAGES[errno];
+        };
+        FS.ErrnoError.prototype = new Error();
+        FS.ErrnoError.prototype.constructor = FS.ErrnoError;
+        // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
+        [ERRNO_CODES.ENOENT].forEach(function(code) {
+          FS.genericErrors[code] = new FS.ErrnoError(code);
+          FS.genericErrors[code].stack = '<generic error, no stack>';
+        });
+      },staticInit:function () {
+        FS.ensureErrnoError();
+
+        FS.nameTable = new Array(4096);
+
+        FS.mount(MEMFS, {}, '/');
+
+        FS.createDefaultDirectories();
+        FS.createDefaultDevices();
+      },init:function (input, output, error) {
+        assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
+        FS.init.initialized = true;
+
+        FS.ensureErrnoError();
+
+        // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
+        Module['stdin'] = input || Module['stdin'];
+        Module['stdout'] = output || Module['stdout'];
+        Module['stderr'] = error || Module['stderr'];
+
+        FS.createStandardStreams();
+      },quit:function () {
+        FS.init.initialized = false;
+        for (var i = 0; i < FS.streams.length; i++) {
+          var stream = FS.streams[i];
+          if (!stream) {
+            continue;
+          }
+          FS.close(stream);
+        }
+      },getMode:function (canRead, canWrite) {
+        var mode = 0;
+        if (canRead) mode |= 292 | 73;
+        if (canWrite) mode |= 146;
+        return mode;
+      },joinPath:function (parts, forceRelative) {
+        var path = PATH.join.apply(null, parts);
+        if (forceRelative && path[0] == '/') path = path.substr(1);
+        return path;
+      },absolutePath:function (relative, base) {
+        return PATH.resolve(base, relative);
+      },standardizePath:function (path) {
+        return PATH.normalize(path);
+      },findObject:function (path, dontResolveLastLink) {
+        var ret = FS.analyzePath(path, dontResolveLastLink);
+        if (ret.exists) {
+          return ret.object;
+        } else {
+          ___setErrNo(ret.error);
+          return null;
+        }
+      },analyzePath:function (path, dontResolveLastLink) {
+        // operate from within the context of the symlink's target
+        try {
+          var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          path = lookup.path;
+        } catch (e) {
+        }
+        var ret = {
+          isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
+          parentExists: false, parentPath: null, parentObject: null
+        };
+        try {
+          var lookup = FS.lookupPath(path, { parent: true });
+          ret.parentExists = true;
+          ret.parentPath = lookup.path;
+          ret.parentObject = lookup.node;
+          ret.name = PATH.basename(path);
+          lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          ret.exists = true;
+          ret.path = lookup.path;
+          ret.object = lookup.node;
+          ret.name = lookup.node.name;
+          ret.isRoot = lookup.path === '/';
+        } catch (e) {
+          ret.error = e.errno;
+        };
+        return ret;
+      },createFolder:function (parent, name, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.mkdir(path, mode);
+      },createPath:function (parent, path, canRead, canWrite) {
+        parent = typeof parent === 'string' ? parent : FS.getPath(parent);
+        var parts = path.split('/').reverse();
+        while (parts.length) {
+          var part = parts.pop();
+          if (!part) continue;
+          var current = PATH.join2(parent, part);
+          try {
+            FS.mkdir(current);
+          } catch (e) {
+            // ignore EEXIST
+          }
+          parent = current;
+        }
+        return current;
+      },createFile:function (parent, name, properties, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.create(path, mode);
+      },createDataFile:function (parent, name, data, canRead, canWrite, canOwn) {
+        var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
+        var mode = FS.getMode(canRead, canWrite);
+        var node = FS.create(path, mode);
+        if (data) {
+          if (typeof data === 'string') {
+            var arr = new Array(data.length);
+            for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
+            data = arr;
+          }
+          // make sure we can write to the file
+          FS.chmod(node, mode | 146);
+          var stream = FS.open(node, 'w');
+          FS.write(stream, data, 0, data.length, 0, canOwn);
+          FS.close(stream);
+          FS.chmod(node, mode);
+        }
+        return node;
+      },createDevice:function (parent, name, input, output) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(!!input, !!output);
+        if (!FS.createDevice.major) FS.createDevice.major = 64;
+        var dev = FS.makedev(FS.createDevice.major++, 0);
+        // Create a fake device that a set of stream ops to emulate
+        // the old behavior.
+        FS.registerDevice(dev, {
+          open: function(stream) {
+            stream.seekable = false;
+          },
+          close: function(stream) {
+            // flush any pending line data
+            if (output && output.buffer && output.buffer.length) {
+              output(10);
+            }
+          },
+          read: function(stream, buffer, offset, length, pos /* ignored */) {
+            var bytesRead = 0;
+            for (var i = 0; i < length; i++) {
+              var result;
+              try {
+                result = input();
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+              if (result === undefined && bytesRead === 0) {
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+              if (result === null || result === undefined) break;
+              bytesRead++;
+              buffer[offset+i] = result;
+            }
+            if (bytesRead) {
+              stream.node.timestamp = Date.now();
+            }
+            return bytesRead;
+          },
+          write: function(stream, buffer, offset, length, pos) {
+            for (var i = 0; i < length; i++) {
+              try {
+                output(buffer[offset+i]);
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+            }
+            if (length) {
+              stream.node.timestamp = Date.now();
+            }
+            return i;
+          }
+        });
+        return FS.mkdev(path, mode, dev);
+      },createLink:function (parent, name, target, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        return FS.symlink(target, path);
+      },forceLoadFile:function (obj) {
+        if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
+        var success = true;
+        if (typeof XMLHttpRequest !== 'undefined') {
+          throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
+        } else if (Module['read']) {
+          // Command-line.
+          try {
+            // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
+            //          read() will try to parse UTF8.
+            obj.contents = intArrayFromString(Module['read'](obj.url), true);
+          } catch (e) {
+            success = false;
+          }
+        } else {
+          throw new Error('Cannot load without read() or XMLHttpRequest.');
+        }
+        if (!success) ___setErrNo(ERRNO_CODES.EIO);
+        return success;
+      },createLazyFile:function (parent, name, url, canRead, canWrite) {
+        // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
+        function LazyUint8Array() {
+          this.lengthKnown = false;
+          this.chunks = []; // Loaded chunks. Index is the chunk number
+        }
+        LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
+          if (idx > this.length-1 || idx < 0) {
+            return undefined;
+          }
+          var chunkOffset = idx % this.chunkSize;
+          var chunkNum = Math.floor(idx / this.chunkSize);
+          return this.getter(chunkNum)[chunkOffset];
+        }
+        LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
+          this.getter = getter;
+        }
+        LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
+            // Find length
+            var xhr = new XMLHttpRequest();
+            xhr.open('HEAD', url, false);
+            xhr.send(null);
+            if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+            var datalength = Number(xhr.getResponseHeader("Content-length"));
+            var header;
+            var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
+            var chunkSize = 1024*1024; // Chunk size in bytes
+
+            if (!hasByteServing) chunkSize = datalength;
+
+            // Function to get a range from the remote URL.
+            var doXHR = (function(from, to) {
+              if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
+              if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
+
+              // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
+              var xhr = new XMLHttpRequest();
+              xhr.open('GET', url, false);
+              if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
+
+              // Some hints to the browser that we want binary data.
+              if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
+              if (xhr.overrideMimeType) {
+                xhr.overrideMimeType('text/plain; charset=x-user-defined');
+              }
+
+              xhr.send(null);
+              if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+              if (xhr.response !== undefined) {
+                return new Uint8Array(xhr.response || []);
+              } else {
+                return intArrayFromString(xhr.responseText || '', true);
+              }
+            });
+            var lazyArray = this;
+            lazyArray.setDataGetter(function(chunkNum) {
+              var start = chunkNum * chunkSize;
+              var end = (chunkNum+1) * chunkSize - 1; // including this byte
+              end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
+                lazyArray.chunks[chunkNum] = doXHR(start, end);
+              }
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
+              return lazyArray.chunks[chunkNum];
+            });
+
+            this._length = datalength;
+            this._chunkSize = chunkSize;
+            this.lengthKnown = true;
+        }
+        if (typeof XMLHttpRequest !== 'undefined') {
+          if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
+          var lazyArray = new LazyUint8Array();
+          Object.defineProperty(lazyArray, "length", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._length;
+              }
+          });
+          Object.defineProperty(lazyArray, "chunkSize", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._chunkSize;
+              }
+          });
+
+          var properties = { isDevice: false, contents: lazyArray };
+        } else {
+          var properties = { isDevice: false, url: url };
+        }
+
+        var node = FS.createFile(parent, name, properties, canRead, canWrite);
+        // This is a total hack, but I want to get this lazy file code out of the
+        // core of MEMFS. If we want to keep this lazy file concept I feel it should
+        // be its own thin LAZYFS proxying calls to MEMFS.
+        if (properties.contents) {
+          node.contents = properties.contents;
+        } else if (properties.url) {
+          node.contents = null;
+          node.url = properties.url;
+        }
+        // override each stream op with one that tries to force load the lazy file first
+        var stream_ops = {};
+        var keys = Object.keys(node.stream_ops);
+        keys.forEach(function(key) {
+          var fn = node.stream_ops[key];
+          stream_ops[key] = function forceLoadLazyFile() {
+            if (!FS.forceLoadFile(node)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            return fn.apply(null, arguments);
+          };
+        });
+        // use a custom read function
+        stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
+          if (!FS.forceLoadFile(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EIO);
+          }
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (contents.slice) { // normal array
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          } else {
+            for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
+              buffer[offset + i] = contents.get(position + i);
+            }
+          }
+          return size;
+        };
+        node.stream_ops = stream_ops;
+        return node;
+      },createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
+        Browser.init();
+        // TODO we should allow people to just pass in a complete filename instead
+        // of parent and name being that we just join them anyways
+        var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent;
+        function processData(byteArray) {
+          function finish(byteArray) {
+            if (!dontCreateFile) {
+              FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
+            }
+            if (onload) onload();
+            removeRunDependency('cp ' + fullname);
+          }
+          var handled = false;
+          Module['preloadPlugins'].forEach(function(plugin) {
+            if (handled) return;
+            if (plugin['canHandle'](fullname)) {
+              plugin['handle'](byteArray, fullname, finish, function() {
+                if (onerror) onerror();
+                removeRunDependency('cp ' + fullname);
+              });
+              handled = true;
+            }
+          });
+          if (!handled) finish(byteArray);
+        }
+        addRunDependency('cp ' + fullname);
+        if (typeof url == 'string') {
+          Browser.asyncLoad(url, function(byteArray) {
+            processData(byteArray);
+          }, onerror);
+        } else {
+          processData(url);
+        }
+      },indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_NAME:function () {
+        return 'EM_FS_' + window.location.pathname;
+      },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
+          console.log('creating db');
+          var db = openRequest.result;
+          db.createObjectStore(FS.DB_STORE_NAME);
+        };
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var putRequest = files.put(FS.analyzePath(path).object.contents, path);
+            putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
+            putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      },loadFilesFromDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = onerror; // no database to load from
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          try {
+            var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
+          } catch(e) {
+            onerror(e);
+            return;
+          }
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var getRequest = files.get(path);
+            getRequest.onsuccess = function getRequest_onsuccess() {
+              if (FS.analyzePath(path).exists) {
+                FS.unlink(path);
+              }
+              FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
+              ok++;
+              if (ok + fail == total) finish();
+            };
+            getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      }};
+
+  function _lseek(fildes, offset, whence) {
+      // off_t lseek(int fildes, off_t offset, int whence);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/lseek.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      try {
+        return FS.llseek(stream, offset, whence);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }
+
+  function _fileno(stream) {
+      // int fileno(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
+      stream = FS.getStreamFromPtr(stream);
+      if (!stream) return -1;
+      return stream.fd;
+    }function _fseek(stream, offset, whence) {
+      // int fseek(FILE *stream, long offset, int whence);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fseek.html
+      var fd = _fileno(stream);
+      var ret = _lseek(fd, offset, whence);
+      if (ret == -1) {
+        return -1;
+      }
+      stream = FS.getStreamFromPtr(stream);
+      stream.eof = false;
+      return 0;
+    }
+
+
+  Module["_i64Subtract"] = _i64Subtract;
+
+
+  Module["_i64Add"] = _i64Add;
+
+  function _setlocale(category, locale) {
+      if (!_setlocale.ret) _setlocale.ret = allocate([0], 'i8', ALLOC_NORMAL);
+      return _setlocale.ret;
+    }
+
+
+  function _close(fildes) {
+      // int close(int fildes);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/close.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      try {
+        FS.close(stream);
+        return 0;
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }
+
+  function _fsync(fildes) {
+      // int fsync(int fildes);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fsync.html
+      var stream = FS.getStream(fildes);
+      if (stream) {
+        // We write directly to the file system, so there's nothing to do here.
+        return 0;
+      } else {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+    }function _fclose(stream) {
+      // int fclose(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fclose.html
+      var fd = _fileno(stream);
+      _fsync(fd);
+      return _close(fd);
+    }
+
+
+
+
+
+  function _mkport() { throw 'TODO' }var SOCKFS={mount:function (mount) {
+        return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createSocket:function (family, type, protocol) {
+        var streaming = type == 1;
+        if (protocol) {
+          assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp
+        }
+
+        // create our internal socket structure
+        var sock = {
+          family: family,
+          type: type,
+          protocol: protocol,
+          server: null,
+          peers: {},
+          pending: [],
+          recv_queue: [],
+          sock_ops: SOCKFS.websocket_sock_ops
+        };
+
+        // create the filesystem node to store the socket structure
+        var name = SOCKFS.nextname();
+        var node = FS.createNode(SOCKFS.root, name, 49152, 0);
+        node.sock = sock;
+
+        // and the wrapping stream that enables library functions such
+        // as read and write to indirectly interact with the socket
+        var stream = FS.createStream({
+          path: name,
+          node: node,
+          flags: FS.modeStringToFlags('r+'),
+          seekable: false,
+          stream_ops: SOCKFS.stream_ops
+        });
+
+        // map the new stream to the socket structure (sockets have a 1:1
+        // relationship with a stream)
+        sock.stream = stream;
+
+        return sock;
+      },getSocket:function (fd) {
+        var stream = FS.getStream(fd);
+        if (!stream || !FS.isSocket(stream.node.mode)) {
+          return null;
+        }
+        return stream.node.sock;
+      },stream_ops:{poll:function (stream) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.poll(sock);
+        },ioctl:function (stream, request, varargs) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.ioctl(sock, request, varargs);
+        },read:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          var msg = sock.sock_ops.recvmsg(sock, length);
+          if (!msg) {
+            // socket is closed
+            return 0;
+          }
+          buffer.set(msg.buffer, offset);
+          return msg.buffer.length;
+        },write:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.sendmsg(sock, buffer, offset, length);
+        },close:function (stream) {
+          var sock = stream.node.sock;
+          sock.sock_ops.close(sock);
+        }},nextname:function () {
+        if (!SOCKFS.nextname.current) {
+          SOCKFS.nextname.current = 0;
+        }
+        return 'socket[' + (SOCKFS.nextname.current++) + ']';
+      },websocket_sock_ops:{createPeer:function (sock, addr, port) {
+          var ws;
+
+          if (typeof addr === 'object') {
+            ws = addr;
+            addr = null;
+            port = null;
+          }
+
+          if (ws) {
+            // for sockets that've already connected (e.g. we're the server)
+            // we can inspect the _socket property for the address
+            if (ws._socket) {
+              addr = ws._socket.remoteAddress;
+              port = ws._socket.remotePort;
+            }
+            // if we're just now initializing a connection to the remote,
+            // inspect the url property
+            else {
+              var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
+              if (!result) {
+                throw new Error('WebSocket URL must be in the format ws(s)://address:port');
+              }
+              addr = result[1];
+              port = parseInt(result[2], 10);
+            }
+          } else {
+            // create the actual websocket object and connect
+            try {
+              // runtimeConfig gets set to true if WebSocket runtime configuration is available.
+              var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
+
+              // The default value is 'ws://' the replace is needed because the compiler replaces "//" comments with '#'
+              // comments without checking context, so we'd end up with ws:#, the replace swaps the "#" for "//" again.
+              var url = 'ws:#'.replace('#', '//');
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['url']) {
+                  url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
+                }
+              }
+
+              if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
+                url = url + addr + ':' + port;
+              }
+
+              // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
+              var subProtocols = 'binary'; // The default value is 'binary'
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['subprotocol']) {
+                  subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
+                }
+              }
+
+              // The regex trims the string (removes spaces at the beginning and end, then splits the string by
+              // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
+              subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
+
+              // The node ws library API for specifying optional subprotocol is slightly different than the browser's.
+              var opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols;
+
+              // If node we use the ws library.
+              var WebSocket = ENVIRONMENT_IS_NODE ? require('ws') : window['WebSocket'];
+              ws = new WebSocket(url, opts);
+              ws.binaryType = 'arraybuffer';
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH);
+            }
+          }
+
+
+          var peer = {
+            addr: addr,
+            port: port,
+            socket: ws,
+            dgram_send_queue: []
+          };
+
+          SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+          SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
+
+          // if this is a bound dgram socket, send the port number first to allow
+          // us to override the ephemeral port reported to us by remotePort on the
+          // remote end.
+          if (sock.type === 2 && typeof sock.sport !== 'undefined') {
+            peer.dgram_send_queue.push(new Uint8Array([
+                255, 255, 255, 255,
+                'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
+                ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
+            ]));
+          }
+
+          return peer;
+        },getPeer:function (sock, addr, port) {
+          return sock.peers[addr + ':' + port];
+        },addPeer:function (sock, peer) {
+          sock.peers[peer.addr + ':' + peer.port] = peer;
+        },removePeer:function (sock, peer) {
+          delete sock.peers[peer.addr + ':' + peer.port];
+        },handlePeerEvents:function (sock, peer) {
+          var first = true;
+
+          var handleOpen = function () {
+            try {
+              var queued = peer.dgram_send_queue.shift();
+              while (queued) {
+                peer.socket.send(queued);
+                queued = peer.dgram_send_queue.shift();
+              }
+            } catch (e) {
+              // not much we can do here in the way of proper error handling as we've already
+              // lied and said this data was sent. shut it down.
+              peer.socket.close();
+            }
+          };
+
+          function handleMessage(data) {
+            assert(typeof data !== 'string' && data.byteLength !== undefined);  // must receive an ArrayBuffer
+            data = new Uint8Array(data);  // make a typed array view on the array buffer
+
+
+            // if this is the port message, override the peer's port with it
+            var wasfirst = first;
+            first = false;
+            if (wasfirst &&
+                data.length === 10 &&
+                data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
+                data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
+              // update the peer's port and it's key in the peer map
+              var newport = ((data[8] << 8) | data[9]);
+              SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+              peer.port = newport;
+              SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+              return;
+            }
+
+            sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
+          };
+
+          if (ENVIRONMENT_IS_NODE) {
+            peer.socket.on('open', handleOpen);
+            peer.socket.on('message', function(data, flags) {
+              if (!flags.binary) {
+                return;
+              }
+              handleMessage((new Uint8Array(data)).buffer);  // copy from node Buffer -> ArrayBuffer
+            });
+            peer.socket.on('error', function() {
+              // don't throw
+            });
+          } else {
+            peer.socket.onopen = handleOpen;
+            peer.socket.onmessage = function peer_socket_onmessage(event) {
+              handleMessage(event.data);
+            };
+          }
+        },poll:function (sock) {
+          if (sock.type === 1 && sock.server) {
+            // listen sockets should only say they're available for reading
+            // if there are pending clients.
+            return sock.pending.length ? (64 | 1) : 0;
+          }
+
+          var mask = 0;
+          var dest = sock.type === 1 ?  // we only care about the socket state for connection-based sockets
+            SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
+            null;
+
+          if (sock.recv_queue.length ||
+              !dest ||  // connection-less sockets are always ready to read
+              (dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {  // let recv return 0 once closed
+            mask |= (64 | 1);
+          }
+
+          if (!dest ||  // connection-less sockets are always ready to write
+              (dest && dest.socket.readyState === dest.socket.OPEN)) {
+            mask |= 4;
+          }
+
+          if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {
+            mask |= 16;
+          }
+
+          return mask;
+        },ioctl:function (sock, request, arg) {
+          switch (request) {
+            case 21531:
+              var bytes = 0;
+              if (sock.recv_queue.length) {
+                bytes = sock.recv_queue[0].data.length;
+              }
+              HEAP32[((arg)>>2)]=bytes;
+              return 0;
+            default:
+              return ERRNO_CODES.EINVAL;
+          }
+        },close:function (sock) {
+          // if we've spawned a listen server, close it
+          if (sock.server) {
+            try {
+              sock.server.close();
+            } catch (e) {
+            }
+            sock.server = null;
+          }
+          // close any peer connections
+          var peers = Object.keys(sock.peers);
+          for (var i = 0; i < peers.length; i++) {
+            var peer = sock.peers[peers[i]];
+            try {
+              peer.socket.close();
+            } catch (e) {
+            }
+            SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+          }
+          return 0;
+        },bind:function (sock, addr, port) {
+          if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already bound
+          }
+          sock.saddr = addr;
+          sock.sport = port || _mkport();
+          // in order to emulate dgram sockets, we need to launch a listen server when
+          // binding on a connection-less socket
+          // note: this is only required on the server side
+          if (sock.type === 2) {
+            // close the existing server if it exists
+            if (sock.server) {
+              sock.server.close();
+              sock.server = null;
+            }
+            // swallow error operation not supported error that occurs when binding in the
+            // browser where this isn't supported
+            try {
+              sock.sock_ops.listen(sock, 0);
+            } catch (e) {
+              if (!(e instanceof FS.ErrnoError)) throw e;
+              if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e;
+            }
+          }
+        },connect:function (sock, addr, port) {
+          if (sock.server) {
+            throw new FS.ErrnoError(ERRNO_CODS.EOPNOTSUPP);
+          }
+
+          // TODO autobind
+          // if (!sock.addr && sock.type == 2) {
+          // }
+
+          // early out if we're already connected / in the middle of connecting
+          if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') {
+            var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+            if (dest) {
+              if (dest.socket.readyState === dest.socket.CONNECTING) {
+                throw new FS.ErrnoError(ERRNO_CODES.EALREADY);
+              } else {
+                throw new FS.ErrnoError(ERRNO_CODES.EISCONN);
+              }
+            }
+          }
+
+          // add the socket to our peer list and set our
+          // destination address / port to match
+          var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+          sock.daddr = peer.addr;
+          sock.dport = peer.port;
+
+          // always "fail" in non-blocking mode
+          throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS);
+        },listen:function (sock, backlog) {
+          if (!ENVIRONMENT_IS_NODE) {
+            throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+          }
+          if (sock.server) {
+             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already listening
+          }
+          var WebSocketServer = require('ws').Server;
+          var host = sock.saddr;
+          sock.server = new WebSocketServer({
+            host: host,
+            port: sock.sport
+            // TODO support backlog
+          });
+
+          sock.server.on('connection', function(ws) {
+            if (sock.type === 1) {
+              var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
+
+              // create a peer on the new socket
+              var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
+              newsock.daddr = peer.addr;
+              newsock.dport = peer.port;
+
+              // push to queue for accept to pick up
+              sock.pending.push(newsock);
+            } else {
+              // create a peer on the listen socket so calling sendto
+              // with the listen socket and an address will resolve
+              // to the correct client
+              SOCKFS.websocket_sock_ops.createPeer(sock, ws);
+            }
+          });
+          sock.server.on('closed', function() {
+            sock.server = null;
+          });
+          sock.server.on('error', function() {
+            // don't throw
+          });
+        },accept:function (listensock) {
+          if (!listensock.server) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          var newsock = listensock.pending.shift();
+          newsock.stream.flags = listensock.stream.flags;
+          return newsock;
+        },getname:function (sock, peer) {
+          var addr, port;
+          if (peer) {
+            if (sock.daddr === undefined || sock.dport === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            }
+            addr = sock.daddr;
+            port = sock.dport;
+          } else {
+            // TODO saddr and sport will be set for bind()'d UDP sockets, but what
+            // should we be returning for TCP sockets that've been connect()'d?
+            addr = sock.saddr || 0;
+            port = sock.sport || 0;
+          }
+          return { addr: addr, port: port };
+        },sendmsg:function (sock, buffer, offset, length, addr, port) {
+          if (sock.type === 2) {
+            // connection-less sockets will honor the message address,
+            // and otherwise fall back to the bound destination address
+            if (addr === undefined || port === undefined) {
+              addr = sock.daddr;
+              port = sock.dport;
+            }
+            // if there was no address to fall back to, error out
+            if (addr === undefined || port === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ);
+            }
+          } else {
+            // connection-based sockets will only use the bound
+            addr = sock.daddr;
+            port = sock.dport;
+          }
+
+          // find the peer for the destination address
+          var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
+
+          // early out if not connected with a connection-based socket
+          if (sock.type === 1) {
+            if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            } else if (dest.socket.readyState === dest.socket.CONNECTING) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // create a copy of the incoming data to send, as the WebSocket API
+          // doesn't work entirely with an ArrayBufferView, it'll just send
+          // the entire underlying buffer
+          var data;
+          if (buffer instanceof Array || buffer instanceof ArrayBuffer) {
+            data = buffer.slice(offset, offset + length);
+          } else {  // ArrayBufferView
+            data = buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + length);
+          }
+
+          // if we're emulating a connection-less dgram socket and don't have
+          // a cached connection, queue the buffer to send upon connect and
+          // lie, saying the data was sent now.
+          if (sock.type === 2) {
+            if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
+              // if we're not connected, open a new connection
+              if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+              }
+              dest.dgram_send_queue.push(data);
+              return length;
+            }
+          }
+
+          try {
+            // send the actual data
+            dest.socket.send(data);
+            return length;
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+        },recvmsg:function (sock, length) {
+          // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
+          if (sock.type === 1 && sock.server) {
+            // tcp servers should not be recv()'ing on the listen socket
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+          }
+
+          var queued = sock.recv_queue.shift();
+          if (!queued) {
+            if (sock.type === 1) {
+              var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+
+              if (!dest) {
+                // if we have a destination address but are not connected, error out
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+              }
+              else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                // return null if the socket has closed
+                return null;
+              }
+              else {
+                // else, our socket is in a valid state but truly has nothing available
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+            } else {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
+          // requeued TCP data it'll be an ArrayBufferView
+          var queuedLength = queued.data.byteLength || queued.data.length;
+          var queuedOffset = queued.data.byteOffset || 0;
+          var queuedBuffer = queued.data.buffer || queued.data;
+          var bytesRead = Math.min(length, queuedLength);
+          var res = {
+            buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
+            addr: queued.addr,
+            port: queued.port
+          };
+
+
+          // push back any unread data for TCP connections
+          if (sock.type === 1 && bytesRead < queuedLength) {
+            var bytesRemaining = queuedLength - bytesRead;
+            queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
+            sock.recv_queue.unshift(queued);
+          }
+
+          return res;
+        }}};function _recv(fd, buf, len, flags) {
+      var sock = SOCKFS.getSocket(fd);
+      if (!sock) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      // TODO honor flags
+      return _read(fd, buf, len);
+    }
+
+  function _pread(fildes, buf, nbyte, offset) {
+      // ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/read.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      try {
+        var slab = HEAP8;
+        return FS.read(stream, slab, buf, nbyte, offset);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _read(fildes, buf, nbyte) {
+      // ssize_t read(int fildes, void *buf, size_t nbyte);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/read.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+
+
+      try {
+        var slab = HEAP8;
+        return FS.read(stream, slab, buf, nbyte);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _fread(ptr, size, nitems, stream) {
+      // size_t fread(void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fread.html
+      var bytesToRead = nitems * size;
+      if (bytesToRead == 0) {
+        return 0;
+      }
+      var bytesRead = 0;
+      var streamObj = FS.getStreamFromPtr(stream);
+      if (!streamObj) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return 0;
+      }
+      while (streamObj.ungotten.length && bytesToRead > 0) {
+        HEAP8[((ptr++)|0)]=streamObj.ungotten.pop();
+        bytesToRead--;
+        bytesRead++;
+      }
+      var err = _read(streamObj.fd, ptr, bytesToRead);
+      if (err == -1) {
+        if (streamObj) streamObj.error = true;
+        return 0;
+      }
+      bytesRead += err;
+      if (bytesRead < bytesToRead) streamObj.eof = true;
+      return Math.floor(bytesRead / size);
+    }
+
+  function _toupper(chr) {
+      if (chr >= 97 && chr <= 122) {
+        return chr - 97 + 65;
+      } else {
+        return chr;
+      }
+    }
+
+
+
+  function _open(path, oflag, varargs) {
+      // int open(const char *path, int oflag, ...);
+      // http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html
+      var mode = HEAP32[((varargs)>>2)];
+      path = Pointer_stringify(path);
+      try {
+        var stream = FS.open(path, oflag, mode);
+        return stream.fd;
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _fopen(filename, mode) {
+      // FILE *fopen(const char *restrict filename, const char *restrict mode);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fopen.html
+      var flags;
+      mode = Pointer_stringify(mode);
+      if (mode[0] == 'r') {
+        if (mode.indexOf('+') != -1) {
+          flags = 2;
+        } else {
+          flags = 0;
+        }
+      } else if (mode[0] == 'w') {
+        if (mode.indexOf('+') != -1) {
+          flags = 2;
+        } else {
+          flags = 1;
+        }
+        flags |= 64;
+        flags |= 512;
+      } else if (mode[0] == 'a') {
+        if (mode.indexOf('+') != -1) {
+          flags = 2;
+        } else {
+          flags = 1;
+        }
+        flags |= 64;
+        flags |= 1024;
+      } else {
+        ___setErrNo(ERRNO_CODES.EINVAL);
+        return 0;
+      }
+      var fd = _open(filename, flags, allocate([0x1FF, 0, 0, 0], 'i32', ALLOC_STACK));  // All creation permissions.
+      return fd === -1 ? 0 : FS.getPtrForStream(FS.getStream(fd));
+    }
+
+  var _emscripten_check_longjmp=true;
+
+
+
+  function _send(fd, buf, len, flags) {
+      var sock = SOCKFS.getSocket(fd);
+      if (!sock) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      // TODO honor flags
+      return _write(fd, buf, len);
+    }
+
+  function _pwrite(fildes, buf, nbyte, offset) {
+      // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte, offset);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _write(fildes, buf, nbyte) {
+      // ssize_t write(int fildes, const void *buf, size_t nbyte);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+
+
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _fputc(c, stream) {
+      // int fputc(int c, FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fputc.html
+      var chr = unSign(c & 0xFF);
+      HEAP8[((_fputc.ret)|0)]=chr;
+      var fd = _fileno(stream);
+      var ret = _write(fd, _fputc.ret, 1);
+      if (ret == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return -1;
+      } else {
+        return chr;
+      }
+    }
+
+  var _log=Math_log;
+
+  var _emscripten_postinvoke=true;
+
+
+  function _putchar(c) {
+      // int putchar(int c);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/putchar.html
+      return _fputc(c, HEAP32[((_stdout)>>2)]);
+    }
+  Module["_saveSetjmp"] = _saveSetjmp;
+
+  function _fwrite(ptr, size, nitems, stream) {
+      // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
+      var bytesToWrite = nitems * size;
+      if (bytesToWrite == 0) return 0;
+      var fd = _fileno(stream);
+      var bytesWritten = _write(fd, ptr, bytesToWrite);
+      if (bytesWritten == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return 0;
+      } else {
+        return Math.floor(bytesWritten / size);
+      }
+    }
+
+  function _system(command) {
+      // int system(const char *command);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/system.html
+      // Can't call external programs.
+      ___setErrNo(ERRNO_CODES.EAGAIN);
+      return -1;
+    }
+
+  function _frexp(x, exp_addr) {
+      var sig = 0, exp_ = 0;
+      if (x !== 0) {
+        var sign = 1;
+        if (x < 0) {
+          x = -x;
+          sign = -1;
+        }
+        var raw_exp = Math.log(x)/Math.log(2);
+        exp_ = Math.ceil(raw_exp);
+        if (exp_ === raw_exp) exp_ += 1;
+        sig = sign*x/Math.pow(2, exp_);
+      }
+      HEAP32[((exp_addr)>>2)]=exp_;
+      return sig;
+    }
+
+
+
+  var _tzname=allocate(8, "i32*", ALLOC_STATIC);
+
+  var _daylight=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _timezone=allocate(1, "i32*", ALLOC_STATIC);function _tzset() {
+      // TODO: Use (malleable) environment variables instead of system settings.
+      if (_tzset.called) return;
+      _tzset.called = true;
+
+      HEAP32[((_timezone)>>2)]=-(new Date()).getTimezoneOffset() * 60;
+
+      var winter = new Date(2000, 0, 1);
+      var summer = new Date(2000, 6, 1);
+      HEAP32[((_daylight)>>2)]=Number(winter.getTimezoneOffset() != summer.getTimezoneOffset());
+
+      var winterName = 'GMT'; // XXX do not rely on browser timezone info, it is very unpredictable | winter.toString().match(/\(([A-Z]+)\)/)[1];
+      var summerName = 'GMT'; // XXX do not rely on browser timezone info, it is very unpredictable | summer.toString().match(/\(([A-Z]+)\)/)[1];
+      var winterNamePtr = allocate(intArrayFromString(winterName), 'i8', ALLOC_NORMAL);
+      var summerNamePtr = allocate(intArrayFromString(summerName), 'i8', ALLOC_NORMAL);
+      HEAP32[((_tzname)>>2)]=winterNamePtr;
+      HEAP32[(((_tzname)+(4))>>2)]=summerNamePtr;
+    }function _mktime(tmPtr) {
+      _tzset();
+      var year = HEAP32[(((tmPtr)+(20))>>2)];
+      var timestamp = new Date(year >= 1900 ? year : year + 1900,
+                               HEAP32[(((tmPtr)+(16))>>2)],
+                               HEAP32[(((tmPtr)+(12))>>2)],
+                               HEAP32[(((tmPtr)+(8))>>2)],
+                               HEAP32[(((tmPtr)+(4))>>2)],
+                               HEAP32[((tmPtr)>>2)],
+                               0).getTime() / 1000;
+      HEAP32[(((tmPtr)+(24))>>2)]=new Date(timestamp).getDay();
+      var yday = Math.round((timestamp - (new Date(year, 0, 1)).getTime()) / (1000 * 60 * 60 * 24));
+      HEAP32[(((tmPtr)+(28))>>2)]=yday;
+      return timestamp;
+    }
+
+  function _isalpha(chr) {
+      return (chr >= 97 && chr <= 122) ||
+             (chr >= 65 && chr <= 90);
+    }
+
+
+  function _malloc(bytes) {
+      /* Over-allocate to make sure it is byte-aligned by 8.
+       * This will leak memory, but this is only the dummy
+       * implementation (replaced by dlmalloc normally) so
+       * not an issue.
+       */
+      var ptr = Runtime.dynamicAlloc(bytes + 8);
+      return (ptr+8) & 0xFFFFFFF8;
+    }
+  Module["_malloc"] = _malloc;function _tmpnam(s, dir, prefix) {
+      // char *tmpnam(char *s);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/tmpnam.html
+      // NOTE: The dir and prefix arguments are for internal use only.
+      var folder = FS.findObject(dir || '/tmp');
+      if (!folder || !folder.isFolder) {
+        dir = '/tmp';
+        folder = FS.findObject(dir);
+        if (!folder || !folder.isFolder) return 0;
+      }
+      var name = prefix || 'file';
+      do {
+        name += String.fromCharCode(65 + Math.floor(Math.random() * 25));
+      } while (name in folder.contents);
+      var result = dir + '/' + name;
+      if (!_tmpnam.buffer) _tmpnam.buffer = _malloc(256);
+      if (!s) s = _tmpnam.buffer;
+      writeAsciiToMemory(result, s);
+      return s;
+    }
+
+  var Browser={mainLoop:{scheduler:null,method:"",shouldPause:false,paused:false,queue:[],pause:function () {
+          Browser.mainLoop.shouldPause = true;
+        },resume:function () {
+          if (Browser.mainLoop.paused) {
+            Browser.mainLoop.paused = false;
+            Browser.mainLoop.scheduler();
+          }
+          Browser.mainLoop.shouldPause = false;
+        },updateStatus:function () {
+          if (Module['setStatus']) {
+            var message = Module['statusMessage'] || 'Please wait...';
+            var remaining = Browser.mainLoop.remainingBlockers;
+            var expected = Browser.mainLoop.expectedBlockers;
+            if (remaining) {
+              if (remaining < expected) {
+                Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
+              } else {
+                Module['setStatus'](message);
+              }
+            } else {
+              Module['setStatus']('');
+            }
+          }
+        }},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () {
+        if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
+
+        if (Browser.initted || ENVIRONMENT_IS_WORKER) return;
+        Browser.initted = true;
+
+        try {
+          new Blob();
+          Browser.hasBlobConstructor = true;
+        } catch(e) {
+          Browser.hasBlobConstructor = false;
+          console.log("warning: no blob constructor, cannot create blobs with mimetypes");
+        }
+        Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
+        Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
+        if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
+          console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
+          Module.noImageDecoding = true;
+        }
+
+        // Support for plugins that can process preloaded files. You can add more of these to
+        // your app by creating and appending to Module.preloadPlugins.
+        //
+        // Each plugin is asked if it can handle a file based on the file's name. If it can,
+        // it is given the file's raw data. When it is done, it calls a callback with the file's
+        // (possibly modified) data. For example, a plugin might decompress a file, or it
+        // might create some side data structure for use later (like an Image element, etc.).
+
+        var imagePlugin = {};
+        imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
+          return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
+        };
+        imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
+          var b = null;
+          if (Browser.hasBlobConstructor) {
+            try {
+              b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+              if (b.size !== byteArray.length) { // Safari bug #118630
+                // Safari's Blob can only take an ArrayBuffer
+                b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
+              }
+            } catch(e) {
+              Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
+            }
+          }
+          if (!b) {
+            var bb = new Browser.BlobBuilder();
+            bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
+            b = bb.getBlob();
+          }
+          var url = Browser.URLObject.createObjectURL(b);
+          var img = new Image();
+          img.onload = function img_onload() {
+            assert(img.complete, 'Image ' + name + ' could not be decoded');
+            var canvas = document.createElement('canvas');
+            canvas.width = img.width;
+            canvas.height = img.height;
+            var ctx = canvas.getContext('2d');
+            ctx.drawImage(img, 0, 0);
+            Module["preloadedImages"][name] = canvas;
+            Browser.URLObject.revokeObjectURL(url);
+            if (onload) onload(byteArray);
+          };
+          img.onerror = function img_onerror(event) {
+            console.log('Image ' + url + ' could not be decoded');
+            if (onerror) onerror();
+          };
+          img.src = url;
+        };
+        Module['preloadPlugins'].push(imagePlugin);
+
+        var audioPlugin = {};
+        audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
+          return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
+        };
+        audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
+          var done = false;
+          function finish(audio) {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = audio;
+            if (onload) onload(byteArray);
+          }
+          function fail() {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = new Audio(); // empty shim
+            if (onerror) onerror();
+          }
+          if (Browser.hasBlobConstructor) {
+            try {
+              var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+            } catch(e) {
+              return fail();
+            }
+            var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
+            var audio = new Audio();
+            audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926
+            audio.onerror = function audio_onerror(event) {
+              if (done) return;
+              console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
+              function encode64(data) {
+                var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+                var PAD = '=';
+                var ret = '';
+                var leftchar = 0;
+                var leftbits = 0;
+                for (var i = 0; i < data.length; i++) {
+                  leftchar = (leftchar << 8) | data[i];
+                  leftbits += 8;
+                  while (leftbits >= 6) {
+                    var curr = (leftchar >> (leftbits-6)) & 0x3f;
+                    leftbits -= 6;
+                    ret += BASE[curr];
+                  }
+                }
+                if (leftbits == 2) {
+                  ret += BASE[(leftchar&3) << 4];
+                  ret += PAD + PAD;
+                } else if (leftbits == 4) {
+                  ret += BASE[(leftchar&0xf) << 2];
+                  ret += PAD;
+                }
+                return ret;
+              }
+              audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
+              finish(audio); // we don't wait for confirmation this worked - but it's worth trying
+            };
+            audio.src = url;
+            // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
+            Browser.safeSetTimeout(function() {
+              finish(audio); // try to use it even though it is not necessarily ready to play
+            }, 10000);
+          } else {
+            return fail();
+          }
+        };
+        Module['preloadPlugins'].push(audioPlugin);
+
+        // Canvas event setup
+
+        var canvas = Module['canvas'];
+
+        // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
+        // Module['forcedAspectRatio'] = 4 / 3;
+
+        canvas.requestPointerLock = canvas['requestPointerLock'] ||
+                                    canvas['mozRequestPointerLock'] ||
+                                    canvas['webkitRequestPointerLock'] ||
+                                    canvas['msRequestPointerLock'] ||
+                                    function(){};
+        canvas.exitPointerLock = document['exitPointerLock'] ||
+                                 document['mozExitPointerLock'] ||
+                                 document['webkitExitPointerLock'] ||
+                                 document['msExitPointerLock'] ||
+                                 function(){}; // no-op if function does not exist
+        canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
+
+        function pointerLockChange() {
+          Browser.pointerLock = document['pointerLockElement'] === canvas ||
+                                document['mozPointerLockElement'] === canvas ||
+                                document['webkitPointerLockElement'] === canvas ||
+                                document['msPointerLockElement'] === canvas;
+        }
+
+        document.addEventListener('pointerlockchange', pointerLockChange, false);
+        document.addEventListener('mozpointerlockchange', pointerLockChange, false);
+        document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
+        document.addEventListener('mspointerlockchange', pointerLockChange, false);
+
+        if (Module['elementPointerLock']) {
+          canvas.addEventListener("click", function(ev) {
+            if (!Browser.pointerLock && canvas.requestPointerLock) {
+              canvas.requestPointerLock();
+              ev.preventDefault();
+            }
+          }, false);
+        }
+      },createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) {
+        var ctx;
+        var errorInfo = '?';
+        function onContextCreationError(event) {
+          errorInfo = event.statusMessage || errorInfo;
+        }
+        try {
+          if (useWebGL) {
+            var contextAttributes = {
+              antialias: false,
+              alpha: false
+            };
+
+            if (webGLContextAttributes) {
+              for (var attribute in webGLContextAttributes) {
+                contextAttributes[attribute] = webGLContextAttributes[attribute];
+              }
+            }
+
+
+            canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
+            try {
+              ['experimental-webgl', 'webgl'].some(function(webglId) {
+                return ctx = canvas.getContext(webglId, contextAttributes);
+              });
+            } finally {
+              canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
+            }
+          } else {
+            ctx = canvas.getContext('2d');
+          }
+          if (!ctx) throw ':(';
+        } catch (e) {
+          Module.print('Could not create canvas: ' + [errorInfo, e]);
+          return null;
+        }
+        if (useWebGL) {
+          // Set the background of the WebGL canvas to black
+          canvas.style.backgroundColor = "black";
+
+          // Warn on context loss
+          canvas.addEventListener('webglcontextlost', function(event) {
+            alert('WebGL context lost. You will need to reload the page.');
+          }, false);
+        }
+        if (setInModule) {
+          GLctx = Module.ctx = ctx;
+          Module.useWebGL = useWebGL;
+          Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
+          Browser.init();
+        }
+        return ctx;
+      },destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) {
+        Browser.lockPointer = lockPointer;
+        Browser.resizeCanvas = resizeCanvas;
+        if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;
+        if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;
+
+        var canvas = Module['canvas'];
+        function fullScreenChange() {
+          Browser.isFullScreen = false;
+          var canvasContainer = canvas.parentNode;
+          if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+               document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+               document['fullScreenElement'] || document['fullscreenElement'] ||
+               document['msFullScreenElement'] || document['msFullscreenElement'] ||
+               document['webkitCurrentFullScreenElement']) === canvasContainer) {
+            canvas.cancelFullScreen = document['cancelFullScreen'] ||
+                                      document['mozCancelFullScreen'] ||
+                                      document['webkitCancelFullScreen'] ||
+                                      document['msExitFullscreen'] ||
+                                      document['exitFullscreen'] ||
+                                      function() {};
+            canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document);
+            if (Browser.lockPointer) canvas.requestPointerLock();
+            Browser.isFullScreen = true;
+            if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize();
+          } else {
+
+            // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
+            canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
+            canvasContainer.parentNode.removeChild(canvasContainer);
+
+            if (Browser.resizeCanvas) Browser.setWindowedCanvasSize();
+          }
+          if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen);
+          Browser.updateCanvasDimensions(canvas);
+        }
+
+        if (!Browser.fullScreenHandlersInstalled) {
+          Browser.fullScreenHandlersInstalled = true;
+          document.addEventListener('fullscreenchange', fullScreenChange, false);
+          document.addEventListener('mozfullscreenchange', fullScreenChange, false);
+          document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
+          document.addEventListener('MSFullscreenChange', fullScreenChange, false);
+        }
+
+        // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
+        var canvasContainer = document.createElement("div");
+        canvas.parentNode.insertBefore(canvasContainer, canvas);
+        canvasContainer.appendChild(canvas);
+
+        // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
+        canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] ||
+                                            canvasContainer['mozRequestFullScreen'] ||
+                                            canvasContainer['msRequestFullscreen'] ||
+                                           (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
+        canvasContainer.requestFullScreen();
+      },requestAnimationFrame:function requestAnimationFrame(func) {
+        if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js)
+          setTimeout(func, 1000/60);
+        } else {
+          if (!window.requestAnimationFrame) {
+            window.requestAnimationFrame = window['requestAnimationFrame'] ||
+                                           window['mozRequestAnimationFrame'] ||
+                                           window['webkitRequestAnimationFrame'] ||
+                                           window['msRequestAnimationFrame'] ||
+                                           window['oRequestAnimationFrame'] ||
+                                           window['setTimeout'];
+          }
+          window.requestAnimationFrame(func);
+        }
+      },safeCallback:function (func) {
+        return function() {
+          if (!ABORT) return func.apply(null, arguments);
+        };
+      },safeRequestAnimationFrame:function (func) {
+        return Browser.requestAnimationFrame(function() {
+          if (!ABORT) func();
+        });
+      },safeSetTimeout:function (func, timeout) {
+        return setTimeout(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },safeSetInterval:function (func, timeout) {
+        return setInterval(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },getMimetype:function (name) {
+        return {
+          'jpg': 'image/jpeg',
+          'jpeg': 'image/jpeg',
+          'png': 'image/png',
+          'bmp': 'image/bmp',
+          'ogg': 'audio/ogg',
+          'wav': 'audio/wav',
+          'mp3': 'audio/mpeg'
+        }[name.substr(name.lastIndexOf('.')+1)];
+      },getUserMedia:function (func) {
+        if(!window.getUserMedia) {
+          window.getUserMedia = navigator['getUserMedia'] ||
+                                navigator['mozGetUserMedia'];
+        }
+        window.getUserMedia(func);
+      },getMovementX:function (event) {
+        return event['movementX'] ||
+               event['mozMovementX'] ||
+               event['webkitMovementX'] ||
+               0;
+      },getMovementY:function (event) {
+        return event['movementY'] ||
+               event['mozMovementY'] ||
+               event['webkitMovementY'] ||
+               0;
+      },getMouseWheelDelta:function (event) {
+        return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta));
+      },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup
+        if (Browser.pointerLock) {
+          // When the pointer is locked, calculate the coordinates
+          // based on the movement of the mouse.
+          // Workaround for Firefox bug 764498
+          if (event.type != 'mousemove' &&
+              ('mozMovementX' in event)) {
+            Browser.mouseMovementX = Browser.mouseMovementY = 0;
+          } else {
+            Browser.mouseMovementX = Browser.getMovementX(event);
+            Browser.mouseMovementY = Browser.getMovementY(event);
+          }
+
+          // check if SDL is available
+          if (typeof SDL != "undefined") {
+            Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
+            Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
+          } else {
+            // just add the mouse delta to the current absolut mouse position
+            // FIXME: ideally this should be clamped against the canvas size and zero
+            Browser.mouseX += Browser.mouseMovementX;
+            Browser.mouseY += Browser.mouseMovementY;
+          }
+        } else {
+          // Otherwise, calculate the movement based on the changes
+          // in the coordinates.
+          var rect = Module["canvas"].getBoundingClientRect();
+          var x, y;
+
+          // Neither .scrollX or .pageXOffset are defined in a spec, but
+          // we prefer .scrollX because it is currently in a spec draft.
+          // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
+          var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);
+          var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);
+          if (event.type == 'touchstart' ||
+              event.type == 'touchend' ||
+              event.type == 'touchmove') {
+            var t = event.touches.item(0);
+            if (t) {
+              x = t.pageX - (scrollX + rect.left);
+              y = t.pageY - (scrollY + rect.top);
+            } else {
+              return;
+            }
+          } else {
+            x = event.pageX - (scrollX + rect.left);
+            y = event.pageY - (scrollY + rect.top);
+          }
+
+          // the canvas might be CSS-scaled compared to its backbuffer;
+          // SDL-using content will want mouse coordinates in terms
+          // of backbuffer units.
+          var cw = Module["canvas"].width;
+          var ch = Module["canvas"].height;
+          x = x * (cw / rect.width);
+          y = y * (ch / rect.height);
+
+          Browser.mouseMovementX = x - Browser.mouseX;
+          Browser.mouseMovementY = y - Browser.mouseY;
+          Browser.mouseX = x;
+          Browser.mouseY = y;
+        }
+      },xhrLoad:function (url, onload, onerror) {
+        var xhr = new XMLHttpRequest();
+        xhr.open('GET', url, true);
+        xhr.responseType = 'arraybuffer';
+        xhr.onload = function xhr_onload() {
+          if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
+            onload(xhr.response);
+          } else {
+            onerror();
+          }
+        };
+        xhr.onerror = onerror;
+        xhr.send(null);
+      },asyncLoad:function (url, onload, onerror, noRunDep) {
+        Browser.xhrLoad(url, function(arrayBuffer) {
+          assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
+          onload(new Uint8Array(arrayBuffer));
+          if (!noRunDep) removeRunDependency('al ' + url);
+        }, function(event) {
+          if (onerror) {
+            onerror();
+          } else {
+            throw 'Loading data file "' + url + '" failed.';
+          }
+        });
+        if (!noRunDep) addRunDependency('al ' + url);
+      },resizeListeners:[],updateResizeListeners:function () {
+        var canvas = Module['canvas'];
+        Browser.resizeListeners.forEach(function(listener) {
+          listener(canvas.width, canvas.height);
+        });
+      },setCanvasSize:function (width, height, noUpdates) {
+        var canvas = Module['canvas'];
+        Browser.updateCanvasDimensions(canvas, width, height);
+        if (!noUpdates) Browser.updateResizeListeners();
+      },windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+          var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+          flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
+          HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },setWindowedCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+          var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+          flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
+          HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },updateCanvasDimensions:function (canvas, wNative, hNative) {
+        if (wNative && hNative) {
+          canvas.widthNative = wNative;
+          canvas.heightNative = hNative;
+        } else {
+          wNative = canvas.widthNative;
+          hNative = canvas.heightNative;
+        }
+        var w = wNative;
+        var h = hNative;
+        if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
+          if (w/h < Module['forcedAspectRatio']) {
+            w = Math.round(h * Module['forcedAspectRatio']);
+          } else {
+            h = Math.round(w / Module['forcedAspectRatio']);
+          }
+        }
+        if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+             document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+             document['fullScreenElement'] || document['fullscreenElement'] ||
+             document['msFullScreenElement'] || document['msFullscreenElement'] ||
+             document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
+           var factor = Math.min(screen.width / w, screen.height / h);
+           w = Math.round(w * factor);
+           h = Math.round(h * factor);
+        }
+        if (Browser.resizeCanvas) {
+          if (canvas.width  != w) canvas.width  = w;
+          if (canvas.height != h) canvas.height = h;
+          if (typeof canvas.style != 'undefined') {
+            canvas.style.removeProperty( "width");
+            canvas.style.removeProperty("height");
+          }
+        } else {
+          if (canvas.width  != wNative) canvas.width  = wNative;
+          if (canvas.height != hNative) canvas.height = hNative;
+          if (typeof canvas.style != 'undefined') {
+            if (w != wNative || h != hNative) {
+              canvas.style.setProperty( "width", w + "px", "important");
+              canvas.style.setProperty("height", h + "px", "important");
+            } else {
+              canvas.style.removeProperty( "width");
+              canvas.style.removeProperty("height");
+            }
+          }
+        }
+      }};
+
+  function _log10(x) {
+      return Math.log(x) / Math.LN10;
+    }
+
+  function _isspace(chr) {
+      return (chr == 32) || (chr >= 9 && chr <= 13);
+    }
+
+
+  var ___tm_current=allocate(44, "i8", ALLOC_STATIC);
+
+
+  var ___tm_timezone=allocate(intArrayFromString("GMT"), "i8", ALLOC_STATIC);function _localtime_r(time, tmPtr) {
+      _tzset();
+      var date = new Date(HEAP32[((time)>>2)]*1000);
+      HEAP32[((tmPtr)>>2)]=date.getSeconds();
+      HEAP32[(((tmPtr)+(4))>>2)]=date.getMinutes();
+      HEAP32[(((tmPtr)+(8))>>2)]=date.getHours();
+      HEAP32[(((tmPtr)+(12))>>2)]=date.getDate();
+      HEAP32[(((tmPtr)+(16))>>2)]=date.getMonth();
+      HEAP32[(((tmPtr)+(20))>>2)]=date.getFullYear()-1900;
+      HEAP32[(((tmPtr)+(24))>>2)]=date.getDay();
+
+      var start = new Date(date.getFullYear(), 0, 1);
+      var yday = Math.floor((date.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
+      HEAP32[(((tmPtr)+(28))>>2)]=yday;
+      HEAP32[(((tmPtr)+(36))>>2)]=start.getTimezoneOffset() * 60;
+
+      var dst = Number(start.getTimezoneOffset() != date.getTimezoneOffset());
+      HEAP32[(((tmPtr)+(32))>>2)]=dst;
+
+      HEAP32[(((tmPtr)+(40))>>2)]=___tm_timezone;
+
+      return tmPtr;
+    }function _localtime(time) {
+      return _localtime_r(time, ___tm_current);
+    }
+
+  function _srand(seed) {
+      HEAP32[((___rand_seed)>>2)]=seed
+    }
+
+  var _emscripten_prep_setjmp=true;
+
+
+
+
+  Module["_testSetjmp"] = _testSetjmp;function _longjmp(env, value) {
+      asm['setThrew'](env, value || 1);
+      throw 'longjmp';
+    }function _emscripten_longjmp(env, value) {
+      _longjmp(env, value);
+    }
+
+  var _ceil=Math_ceil;
+
+
+  function _emscripten_memcpy_big(dest, src, num) {
+      HEAPU8.set(HEAPU8.subarray(src, src+num), dest);
+      return dest;
+    }
+  Module["_memcpy"] = _memcpy;
+
+  var _llvm_pow_f64=Math_pow;
+
+
+
+  Module["_strlen"] = _strlen;function _fputs(s, stream) {
+      // int fputs(const char *restrict s, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fputs.html
+      var fd = _fileno(stream);
+      return _write(fd, s, _strlen(s));
+    }
+
+  function _sbrk(bytes) {
+      // Implement a Linux-like 'memory area' for our 'process'.
+      // Changes the size of the memory area by |bytes|; returns the
+      // address of the previous top ('break') of the memory area
+      // We control the "dynamic" memory - DYNAMIC_BASE to DYNAMICTOP
+      var self = _sbrk;
+      if (!self.called) {
+        DYNAMICTOP = alignMemoryPage(DYNAMICTOP); // make sure we start out aligned
+        self.called = true;
+        assert(Runtime.dynamicAlloc);
+        self.alloc = Runtime.dynamicAlloc;
+        Runtime.dynamicAlloc = function() { abort('cannot dynamically allocate, sbrk now has control') };
+      }
+      var ret = DYNAMICTOP;
+      if (bytes != 0) self.alloc(bytes);
+      return ret;  // Previous break location.
+    }
+
+
+  function _sinh(x) {
+      var p = Math.pow(Math.E, x);
+      return (p - (1 / p)) / 2;
+    }
+
+  function _cosh(x) {
+      var p = Math.pow(Math.E, x);
+      return (p + (1 / p)) / 2;
+    }function _tanh(x) {
+      return _sinh(x) / _cosh(x);
+    }
+
+  function _signal(sig, func) {
+      // TODO
+      return 0;
+    }
+
+
+
+  function __getFloat(text) {
+      return /^[+-]?[0-9]*\.?[0-9]+([eE][+-]?[0-9]+)?/.exec(text);
+    }function __scanString(format, get, unget, varargs) {
+      if (!__scanString.whiteSpace) {
+        __scanString.whiteSpace = {};
+        __scanString.whiteSpace[32] = 1;
+        __scanString.whiteSpace[9] = 1;
+        __scanString.whiteSpace[10] = 1;
+        __scanString.whiteSpace[11] = 1;
+        __scanString.whiteSpace[12] = 1;
+        __scanString.whiteSpace[13] = 1;
+      }
+      // Supports %x, %4x, %d.%d, %lld, %s, %f, %lf.
+      // TODO: Support all format specifiers.
+      format = Pointer_stringify(format);
+      var soFar = 0;
+      if (format.indexOf('%n') >= 0) {
+        // need to track soFar
+        var _get = get;
+        get = function get() {
+          soFar++;
+          return _get();
+        }
+        var _unget = unget;
+        unget = function unget() {
+          soFar--;
+          return _unget();
+        }
+      }
+      var formatIndex = 0;
+      var argsi = 0;
+      var fields = 0;
+      var argIndex = 0;
+      var next;
+
+      mainLoop:
+      for (var formatIndex = 0; formatIndex < format.length;) {
+        if (format[formatIndex] === '%' && format[formatIndex+1] == 'n') {
+          var argPtr = HEAP32[(((varargs)+(argIndex))>>2)];
+          argIndex += Runtime.getAlignSize('void*', null, true);
+          HEAP32[((argPtr)>>2)]=soFar;
+          formatIndex += 2;
+          continue;
+        }
+
+        if (format[formatIndex] === '%') {
+          var nextC = format.indexOf('c', formatIndex+1);
+          if (nextC > 0) {
+            var maxx = 1;
+            if (nextC > formatIndex+1) {
+              var sub = format.substring(formatIndex+1, nextC);
+              maxx = parseInt(sub);
+              if (maxx != sub) maxx = 0;
+            }
+            if (maxx) {
+              var argPtr = HEAP32[(((varargs)+(argIndex))>>2)];
+              argIndex += Runtime.getAlignSize('void*', null, true);
+              fields++;
+              for (var i = 0; i < maxx; i++) {
+                next = get();
+                HEAP8[((argPtr++)|0)]=next;
+                if (next === 0) return i > 0 ? fields : fields-1; // we failed to read the full length of this field
+              }
+              formatIndex += nextC - formatIndex + 1;
+              continue;
+            }
+          }
+        }
+
+        // handle %[...]
+        if (format[formatIndex] === '%' && format.indexOf('[', formatIndex+1) > 0) {
+          var match = /\%([0-9]*)\[(\^)?(\]?[^\]]*)\]/.exec(format.substring(formatIndex));
+          if (match) {
+            var maxNumCharacters = parseInt(match[1]) || Infinity;
+            var negateScanList = (match[2] === '^');
+            var scanList = match[3];
+
+            // expand "middle" dashs into character sets
+            var middleDashMatch;
+            while ((middleDashMatch = /([^\-])\-([^\-])/.exec(scanList))) {
+              var rangeStartCharCode = middleDashMatch[1].charCodeAt(0);
+              var rangeEndCharCode = middleDashMatch[2].charCodeAt(0);
+              for (var expanded = ''; rangeStartCharCode <= rangeEndCharCode; expanded += String.fromCharCode(rangeStartCharCode++));
+              scanList = scanList.replace(middleDashMatch[1] + '-' + middleDashMatch[2], expanded);
+            }
+
+            var argPtr = HEAP32[(((varargs)+(argIndex))>>2)];
+            argIndex += Runtime.getAlignSize('void*', null, true);
+            fields++;
+
+            for (var i = 0; i < maxNumCharacters; i++) {
+              next = get();
+              if (negateScanList) {
+                if (scanList.indexOf(String.fromCharCode(next)) < 0) {
+                  HEAP8[((argPtr++)|0)]=next;
+                } else {
+                  unget();
+                  break;
+                }
+              } else {
+                if (scanList.indexOf(String.fromCharCode(next)) >= 0) {
+                  HEAP8[((argPtr++)|0)]=next;
+                } else {
+                  unget();
+                  break;
+                }
+              }
+            }
+
+            // write out null-terminating character
+            HEAP8[((argPtr++)|0)]=0;
+            formatIndex += match[0].length;
+
+            continue;
+          }
+        }
+        // remove whitespace
+        while (1) {
+          next = get();
+          if (next == 0) return fields;
+          if (!(next in __scanString.whiteSpace)) break;
+        }
+        unget();
+
+        if (format[formatIndex] === '%') {
+          formatIndex++;
+          var suppressAssignment = false;
+          if (format[formatIndex] == '*') {
+            suppressAssignment = true;
+            formatIndex++;
+          }
+          var maxSpecifierStart = formatIndex;
+          while (format[formatIndex].charCodeAt(0) >= 48 &&
+                 format[formatIndex].charCodeAt(0) <= 57) {
+            formatIndex++;
+          }
+          var max_;
+          if (formatIndex != maxSpecifierStart) {
+            max_ = parseInt(format.slice(maxSpecifierStart, formatIndex), 10);
+          }
+          var long_ = false;
+          var half = false;
+          var longLong = false;
+          if (format[formatIndex] == 'l') {
+            long_ = true;
+            formatIndex++;
+            if (format[formatIndex] == 'l') {
+              longLong = true;
+              formatIndex++;
+            }
+          } else if (format[formatIndex] == 'h') {
+            half = true;
+            formatIndex++;
+          }
+          var type = format[formatIndex];
+          formatIndex++;
+          var curr = 0;
+          var buffer = [];
+          // Read characters according to the format. floats are trickier, they may be in an unfloat state in the middle, then be a valid float later
+          if (type == 'f' || type == 'e' || type == 'g' ||
+              type == 'F' || type == 'E' || type == 'G') {
+            next = get();
+            while (next > 0 && (!(next in __scanString.whiteSpace)))  {
+              buffer.push(String.fromCharCode(next));
+              next = get();
+            }
+            var m = __getFloat(buffer.join(''));
+            var last = m ? m[0].length : 0;
+            for (var i = 0; i < buffer.length - last + 1; i++) {
+              unget();
+            }
+            buffer.length = last;
+          } else {
+            next = get();
+            var first = true;
+
+            // Strip the optional 0x prefix for %x.
+            if ((type == 'x' || type == 'X') && (next == 48)) {
+              var peek = get();
+              if (peek == 120 || peek == 88) {
+                next = get();
+              } else {
+                unget();
+              }
+            }
+
+            while ((curr < max_ || isNaN(max_)) && next > 0) {
+              if (!(next in __scanString.whiteSpace) && // stop on whitespace
+                  (type == 's' ||
+                   ((type === 'd' || type == 'u' || type == 'i') && ((next >= 48 && next <= 57) ||
+                                                                     (first && next == 45))) ||
+                   ((type === 'x' || type === 'X') && (next >= 48 && next <= 57 ||
+                                     next >= 97 && next <= 102 ||
+                                     next >= 65 && next <= 70))) &&
+                  (formatIndex >= format.length || next !== format[formatIndex].charCodeAt(0))) { // Stop when we read something that is coming up
+                buffer.push(String.fromCharCode(next));
+                next = get();
+                curr++;
+                first = false;
+              } else {
+                break;
+              }
+            }
+            unget();
+          }
+          if (buffer.length === 0) return 0;  // Failure.
+          if (suppressAssignment) continue;
+
+          var text = buffer.join('');
+          var argPtr = HEAP32[(((varargs)+(argIndex))>>2)];
+          argIndex += Runtime.getAlignSize('void*', null, true);
+          switch (type) {
+            case 'd': case 'u': case 'i':
+              if (half) {
+                HEAP16[((argPtr)>>1)]=parseInt(text, 10);
+              } else if (longLong) {
+                (tempI64 = [parseInt(text, 10)>>>0,(tempDouble=parseInt(text, 10),(+(Math_abs(tempDouble))) >= (+1) ? (tempDouble > (+0) ? ((Math_min((+(Math_floor((tempDouble)/(+4294967296)))), (+4294967295)))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/(+4294967296))))))>>>0) : 0)],HEAP32[((argPtr)>>2)]=tempI64[0],HEAP32[(((argPtr)+(4))>>2)]=tempI64[1]);
+              } else {
+                HEAP32[((argPtr)>>2)]=parseInt(text, 10);
+              }
+              break;
+            case 'X':
+            case 'x':
+              HEAP32[((argPtr)>>2)]=parseInt(text, 16);
+              break;
+            case 'F':
+            case 'f':
+            case 'E':
+            case 'e':
+            case 'G':
+            case 'g':
+            case 'E':
+              // fallthrough intended
+              if (long_) {
+                HEAPF64[((argPtr)>>3)]=parseFloat(text);
+              } else {
+                HEAPF32[((argPtr)>>2)]=parseFloat(text);
+              }
+              break;
+            case 's':
+              var array = intArrayFromString(text);
+              for (var j = 0; j < array.length; j++) {
+                HEAP8[(((argPtr)+(j))|0)]=array[j];
+              }
+              break;
+          }
+          fields++;
+        } else if (format[formatIndex].charCodeAt(0) in __scanString.whiteSpace) {
+          next = get();
+          while (next in __scanString.whiteSpace) {
+            if (next <= 0) break mainLoop;  // End of input.
+            next = get();
+          }
+          unget(next);
+          formatIndex++;
+        } else {
+          // Not a specifier.
+          next = get();
+          if (format[formatIndex].charCodeAt(0) !== next) {
+            unget(next);
+            break mainLoop;
+          }
+          formatIndex++;
+        }
+      }
+      return fields;
+    }
+
+  function _fgetc(stream) {
+      // int fgetc(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fgetc.html
+      var streamObj = FS.getStreamFromPtr(stream);
+      if (!streamObj) return -1;
+      if (streamObj.eof || streamObj.error) return -1;
+      var ret = _fread(_fgetc.ret, 1, 1, stream);
+      if (ret == 0) {
+        return -1;
+      } else if (ret == -1) {
+        streamObj.error = true;
+        return -1;
+      } else {
+        return HEAPU8[((_fgetc.ret)|0)];
+      }
+    }
+
+  function _ungetc(c, stream) {
+      // int ungetc(int c, FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/ungetc.html
+      stream = FS.getStreamFromPtr(stream);
+      if (!stream) {
+        return -1;
+      }
+      if (c === -1) {
+        // do nothing for EOF character
+        return c;
+      }
+      c = unSign(c & 0xFF);
+      stream.ungotten.push(c);
+      stream.eof = false;
+      return c;
+    }function _fscanf(stream, format, varargs) {
+      // int fscanf(FILE *restrict stream, const char *restrict format, ... );
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/scanf.html
+      var streamObj = FS.getStreamFromPtr(stream);
+      if (!streamObj) {
+        return -1;
+      }
+      var buffer = [];
+      function get() {
+        var c = _fgetc(stream);
+        buffer.push(c);
+        return c;
+      };
+      function unget() {
+        _ungetc(buffer.pop(), stream);
+      };
+      return __scanString(format, get, unget, varargs);
+    }
+
+  var _emscripten_preinvoke=true;
+
+  function _localeconv() {
+      // %struct.timeval = type { char* decimal point, other stuff... }
+      // var indexes = Runtime.calculateStructAlignment({ fields: ['i32', 'i32'] });
+      var me = _localeconv;
+      if (!me.ret) {
+      // These are defaults from the "C" locale
+        me.ret = allocate([
+          allocate(intArrayFromString('.'), 'i8', ALLOC_NORMAL),0,0,0, // decimal_point
+          allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // thousands_sep
+          allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // grouping
+          allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // int_curr_symbol
+          allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // currency_symbol
+          allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // mon_decimal_point
+          allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // mon_thousands_sep
+          allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // mon_grouping
+          allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0, // positive_sign
+          allocate(intArrayFromString(''), 'i8', ALLOC_NORMAL),0,0,0 // negative_sign
+        ], 'i8*', ALLOC_NORMAL); // Allocate strings in lconv, still don't allocate chars
+      }
+      return me.ret;
+    }
+
+
+  function _unlink(path) {
+      // int unlink(const char *path);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/unlink.html
+      path = Pointer_stringify(path);
+      try {
+        FS.unlink(path);
+        return 0;
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }
+
+  function _rmdir(path) {
+      // int rmdir(const char *path);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/rmdir.html
+      path = Pointer_stringify(path);
+      try {
+        FS.rmdir(path);
+        return 0;
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _remove(path) {
+      // int remove(const char *path);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/remove.html
+      var ret = _unlink(path);
+      if (ret == -1) ret = _rmdir(path);
+      return ret;
+    }
+
+  function _freopen(filename, mode, stream) {
+      // FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/freopen.html
+      if (!filename) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (!streamObj) {
+          ___setErrNo(ERRNO_CODES.EBADF);
+          return 0;
+        }
+        if (_freopen.buffer) _free(_freopen.buffer);
+        filename = intArrayFromString(streamObj.path);
+        filename = allocate(filename, 'i8', ALLOC_NORMAL);
+      }
+      _fclose(stream);
+      return _fopen(filename, mode);
+    }
+
+
+  function _rename(old_path, new_path) {
+      // int rename(const char *old, const char *new);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/rename.html
+      old_path = Pointer_stringify(old_path);
+      new_path = Pointer_stringify(new_path);
+      try {
+        FS.rename(old_path, new_path);
+        return 0;
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }
+
+  function _tmpfile() {
+      // FILE *tmpfile(void);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/tmpfile.html
+      // TODO: Delete the created file on closing.
+      if (_tmpfile.mode) {
+        _tmpfile.mode = allocate(intArrayFromString('w+'), 'i8', ALLOC_NORMAL);
+      }
+      return _fopen(_tmpnam(0), _tmpfile.mode);
+    }
+
+  function _sysconf(name) {
+      // long sysconf(int name);
+      // http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html
+      switch(name) {
+        case 30: return PAGE_SIZE;
+        case 132:
+        case 133:
+        case 12:
+        case 137:
+        case 138:
+        case 15:
+        case 235:
+        case 16:
+        case 17:
+        case 18:
+        case 19:
+        case 20:
+        case 149:
+        case 13:
+        case 10:
+        case 236:
+        case 153:
+        case 9:
+        case 21:
+        case 22:
+        case 159:
+        case 154:
+        case 14:
+        case 77:
+        case 78:
+        case 139:
+        case 80:
+        case 81:
+        case 79:
+        case 82:
+        case 68:
+        case 67:
+        case 164:
+        case 11:
+        case 29:
+        case 47:
+        case 48:
+        case 95:
+        case 52:
+        case 51:
+        case 46:
+          return 200809;
+        case 27:
+        case 246:
+        case 127:
+        case 128:
+        case 23:
+        case 24:
+        case 160:
+        case 161:
+        case 181:
+        case 182:
+        case 242:
+        case 183:
+        case 184:
+        case 243:
+        case 244:
+        case 245:
+        case 165:
+        case 178:
+        case 179:
+        case 49:
+        case 50:
+        case 168:
+        case 169:
+        case 175:
+        case 170:
+        case 171:
+        case 172:
+        case 97:
+        case 76:
+        case 32:
+        case 173:
+        case 35:
+          return -1;
+        case 176:
+        case 177:
+        case 7:
+        case 155:
+        case 8:
+        case 157:
+        case 125:
+        case 126:
+        case 92:
+        case 93:
+        case 129:
+        case 130:
+        case 131:
+        case 94:
+        case 91:
+          return 1;
+        case 74:
+        case 60:
+        case 69:
+        case 70:
+        case 4:
+          return 1024;
+        case 31:
+        case 42:
+        case 72:
+          return 32;
+        case 87:
+        case 26:
+        case 33:
+          return 2147483647;
+        case 34:
+        case 1:
+          return 47839;
+        case 38:
+        case 36:
+          return 99;
+        case 43:
+        case 37:
+          return 2048;
+        case 0: return 2097152;
+        case 3: return 65536;
+        case 28: return 32768;
+        case 44: return 32767;
+        case 75: return 16384;
+        case 39: return 1000;
+        case 89: return 700;
+        case 71: return 256;
+        case 40: return 255;
+        case 2: return 100;
+        case 180: return 64;
+        case 25: return 20;
+        case 5: return 16;
+        case 6: return 6;
+        case 73: return 4;
+        case 84: return 1;
+      }
+      ___setErrNo(ERRNO_CODES.EINVAL);
+      return -1;
+    }
+
+
+  function ___errno_location() {
+      return ___errno_state;
+    }
+
+
+  Module["_memset"] = _memset;
+
+
+
+  Module["_bitshift64Shl"] = _bitshift64Shl;
+
+  function _abort() {
+      Module['abort']();
+    }
+
+
+
+  function __reallyNegative(x) {
+      return x < 0 || (x === 0 && (1/x) === -Infinity);
+    }function __formatString(format, varargs) {
+      var textIndex = format;
+      var argIndex = 0;
+      function getNextArg(type) {
+        // NOTE: Explicitly ignoring type safety. Otherwise this fails:
+        //       int x = 4; printf("%c\n", (char)x);
+        var ret;
+        if (type === 'double') {
+          ret = HEAPF64[(((varargs)+(argIndex))>>3)];
+        } else if (type == 'i64') {
+          ret = [HEAP32[(((varargs)+(argIndex))>>2)],
+                 HEAP32[(((varargs)+(argIndex+4))>>2)]];
+
+        } else {
+          type = 'i32'; // varargs are always i32, i64, or double
+          ret = HEAP32[(((varargs)+(argIndex))>>2)];
+        }
+        argIndex += Runtime.getNativeFieldSize(type);
+        return ret;
+      }
+
+      var ret = [];
+      var curr, next, currArg;
+      while(1) {
+        var startTextIndex = textIndex;
+        curr = HEAP8[(textIndex)];
+        if (curr === 0) break;
+        next = HEAP8[((textIndex+1)|0)];
+        if (curr == 37) {
+          // Handle flags.
+          var flagAlwaysSigned = false;
+          var flagLeftAlign = false;
+          var flagAlternative = false;
+          var flagZeroPad = false;
+          var flagPadSign = false;
+          flagsLoop: while (1) {
+            switch (next) {
+              case 43:
+                flagAlwaysSigned = true;
+                break;
+              case 45:
+                flagLeftAlign = true;
+                break;
+              case 35:
+                flagAlternative = true;
+                break;
+              case 48:
+                if (flagZeroPad) {
+                  break flagsLoop;
+                } else {
+                  flagZeroPad = true;
+                  break;
+                }
+              case 32:
+                flagPadSign = true;
+                break;
+              default:
+                break flagsLoop;
+            }
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          }
+
+          // Handle width.
+          var width = 0;
+          if (next == 42) {
+            width = getNextArg('i32');
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          } else {
+            while (next >= 48 && next <= 57) {
+              width = width * 10 + (next - 48);
+              textIndex++;
+              next = HEAP8[((textIndex+1)|0)];
+            }
+          }
+
+          // Handle precision.
+          var precisionSet = false, precision = -1;
+          if (next == 46) {
+            precision = 0;
+            precisionSet = true;
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+            if (next == 42) {
+              precision = getNextArg('i32');
+              textIndex++;
+            } else {
+              while(1) {
+                var precisionChr = HEAP8[((textIndex+1)|0)];
+                if (precisionChr < 48 ||
+                    precisionChr > 57) break;
+                precision = precision * 10 + (precisionChr - 48);
+                textIndex++;
+              }
+            }
+            next = HEAP8[((textIndex+1)|0)];
+          }
+          if (precision < 0) {
+            precision = 6; // Standard default.
+            precisionSet = false;
+          }
+
+          // Handle integer sizes. WARNING: These assume a 32-bit architecture!
+          var argSize;
+          switch (String.fromCharCode(next)) {
+            case 'h':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 104) {
+                textIndex++;
+                argSize = 1; // char (actually i32 in varargs)
+              } else {
+                argSize = 2; // short (actually i32 in varargs)
+              }
+              break;
+            case 'l':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 108) {
+                textIndex++;
+                argSize = 8; // long long
+              } else {
+                argSize = 4; // long
+              }
+              break;
+            case 'L': // long long
+            case 'q': // int64_t
+            case 'j': // intmax_t
+              argSize = 8;
+              break;
+            case 'z': // size_t
+            case 't': // ptrdiff_t
+            case 'I': // signed ptrdiff_t or unsigned size_t
+              argSize = 4;
+              break;
+            default:
+              argSize = null;
+          }
+          if (argSize) textIndex++;
+          next = HEAP8[((textIndex+1)|0)];
+
+          // Handle type specifier.
+          switch (String.fromCharCode(next)) {
+            case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': {
+              // Integer.
+              var signed = next == 100 || next == 105;
+              argSize = argSize || 4;
+              var currArg = getNextArg('i' + (argSize * 8));
+              var origArg = currArg;
+              var argText;
+              // Flatten i64-1 [low, high] into a (slightly rounded) double
+              if (argSize == 8) {
+                currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117);
+              }
+              // Truncate to requested size.
+              if (argSize <= 4) {
+                var limit = Math.pow(256, argSize) - 1;
+                currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
+              }
+              // Format the number.
+              var currAbsArg = Math.abs(currArg);
+              var prefix = '';
+              if (next == 100 || next == 105) {
+                if (argSize == 8 && i64Math) argText = i64Math.stringify(origArg[0], origArg[1], null); else
+                argText = reSign(currArg, 8 * argSize, 1).toString(10);
+              } else if (next == 117) {
+                if (argSize == 8 && i64Math) argText = i64Math.stringify(origArg[0], origArg[1], true); else
+                argText = unSign(currArg, 8 * argSize, 1).toString(10);
+                currArg = Math.abs(currArg);
+              } else if (next == 111) {
+                argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
+              } else if (next == 120 || next == 88) {
+                prefix = (flagAlternative && currArg != 0) ? '0x' : '';
+                if (argSize == 8 && i64Math) {
+                  if (origArg[1]) {
+                    argText = (origArg[1]>>>0).toString(16);
+                    var lower = (origArg[0]>>>0).toString(16);
+                    while (lower.length < 8) lower = '0' + lower;
+                    argText += lower;
+                  } else {
+                    argText = (origArg[0]>>>0).toString(16);
+                  }
+                } else
+                if (currArg < 0) {
+                  // Represent negative numbers in hex as 2's complement.
+                  currArg = -currArg;
+                  argText = (currAbsArg - 1).toString(16);
+                  var buffer = [];
+                  for (var i = 0; i < argText.length; i++) {
+                    buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
+                  }
+                  argText = buffer.join('');
+                  while (argText.length < argSize * 2) argText = 'f' + argText;
+                } else {
+                  argText = currAbsArg.toString(16);
+                }
+                if (next == 88) {
+                  prefix = prefix.toUpperCase();
+                  argText = argText.toUpperCase();
+                }
+              } else if (next == 112) {
+                if (currAbsArg === 0) {
+                  argText = '(nil)';
+                } else {
+                  prefix = '0x';
+                  argText = currAbsArg.toString(16);
+                }
+              }
+              if (precisionSet) {
+                while (argText.length < precision) {
+                  argText = '0' + argText;
+                }
+              }
+
+              // Add sign if needed
+              if (currArg >= 0) {
+                if (flagAlwaysSigned) {
+                  prefix = '+' + prefix;
+                } else if (flagPadSign) {
+                  prefix = ' ' + prefix;
+                }
+              }
+
+              // Move sign to prefix so we zero-pad after the sign
+              if (argText.charAt(0) == '-') {
+                prefix = '-' + prefix;
+                argText = argText.substr(1);
+              }
+
+              // Add padding.
+              while (prefix.length + argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad) {
+                    argText = '0' + argText;
+                  } else {
+                    prefix = ' ' + prefix;
+                  }
+                }
+              }
+
+              // Insert the result into the buffer.
+              argText = prefix + argText;
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': {
+              // Float.
+              var currArg = getNextArg('double');
+              var argText;
+              if (isNaN(currArg)) {
+                argText = 'nan';
+                flagZeroPad = false;
+              } else if (!isFinite(currArg)) {
+                argText = (currArg < 0 ? '-' : '') + 'inf';
+                flagZeroPad = false;
+              } else {
+                var isGeneral = false;
+                var effectivePrecision = Math.min(precision, 20);
+
+                // Convert g/G to f/F or e/E, as per:
+                // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
+                if (next == 103 || next == 71) {
+                  isGeneral = true;
+                  precision = precision || 1;
+                  var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
+                  if (precision > exponent && exponent >= -4) {
+                    next = ((next == 103) ? 'f' : 'F').charCodeAt(0);
+                    precision -= exponent + 1;
+                  } else {
+                    next = ((next == 103) ? 'e' : 'E').charCodeAt(0);
+                    precision--;
+                  }
+                  effectivePrecision = Math.min(precision, 20);
+                }
+
+                if (next == 101 || next == 69) {
+                  argText = currArg.toExponential(effectivePrecision);
+                  // Make sure the exponent has at least 2 digits.
+                  if (/[eE][-+]\d$/.test(argText)) {
+                    argText = argText.slice(0, -1) + '0' + argText.slice(-1);
+                  }
+                } else if (next == 102 || next == 70) {
+                  argText = currArg.toFixed(effectivePrecision);
+                  if (currArg === 0 && __reallyNegative(currArg)) {
+                    argText = '-' + argText;
+                  }
+                }
+
+                var parts = argText.split('e');
+                if (isGeneral && !flagAlternative) {
+                  // Discard trailing zeros and periods.
+                  while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
+                         (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
+                    parts[0] = parts[0].slice(0, -1);
+                  }
+                } else {
+                  // Make sure we have a period in alternative mode.
+                  if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
+                  // Zero pad until required precision.
+                  while (precision > effectivePrecision++) parts[0] += '0';
+                }
+                argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
+
+                // Capitalize 'E' if needed.
+                if (next == 69) argText = argText.toUpperCase();
+
+                // Add sign.
+                if (currArg >= 0) {
+                  if (flagAlwaysSigned) {
+                    argText = '+' + argText;
+                  } else if (flagPadSign) {
+                    argText = ' ' + argText;
+                  }
+                }
+              }
+
+              // Add padding.
+              while (argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
+                    argText = argText[0] + '0' + argText.slice(1);
+                  } else {
+                    argText = (flagZeroPad ? '0' : ' ') + argText;
+                  }
+                }
+              }
+
+              // Adjust case.
+              if (next < 97) argText = argText.toUpperCase();
+
+              // Insert the result into the buffer.
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 's': {
+              // String.
+              var arg = getNextArg('i8*');
+              var argLength = arg ? _strlen(arg) : '(null)'.length;
+              if (precisionSet) argLength = Math.min(argLength, precision);
+              if (!flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              if (arg) {
+                for (var i = 0; i < argLength; i++) {
+                  ret.push(HEAPU8[((arg++)|0)]);
+                }
+              } else {
+                ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true));
+              }
+              if (flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              break;
+            }
+            case 'c': {
+              // Character.
+              if (flagLeftAlign) ret.push(getNextArg('i8'));
+              while (--width > 0) {
+                ret.push(32);
+              }
+              if (!flagLeftAlign) ret.push(getNextArg('i8'));
+              break;
+            }
+            case 'n': {
+              // Write the length written so far to the next parameter.
+              var ptr = getNextArg('i32*');
+              HEAP32[((ptr)>>2)]=ret.length;
+              break;
+            }
+            case '%': {
+              // Literal percent sign.
+              ret.push(curr);
+              break;
+            }
+            default: {
+              // Unknown specifiers remain untouched.
+              for (var i = startTextIndex; i < textIndex + 2; i++) {
+                ret.push(HEAP8[(i)]);
+              }
+            }
+          }
+          textIndex += 2;
+          // TODO: Support a/A (hex float) and m (last error) specifiers.
+          // TODO: Support %1${specifier} for arg selection.
+        } else {
+          ret.push(curr);
+          textIndex += 1;
+        }
+      }
+      return ret;
+    }function _fprintf(stream, format, varargs) {
+      // int fprintf(FILE *restrict stream, const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var result = __formatString(format, varargs);
+      var stack = Runtime.stackSave();
+      var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream);
+      Runtime.stackRestore(stack);
+      return ret;
+    }
+
+  function _fgets(s, n, stream) {
+      // char *fgets(char *restrict s, int n, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fgets.html
+      var streamObj = FS.getStreamFromPtr(stream);
+      if (!streamObj) return 0;
+      if (streamObj.error || streamObj.eof) return 0;
+      var byte_;
+      for (var i = 0; i < n - 1 && byte_ != 10; i++) {
+        byte_ = _fgetc(stream);
+        if (byte_ == -1) {
+          if (streamObj.error || (streamObj.eof && i == 0)) return 0;
+          else if (streamObj.eof) break;
+        }
+        HEAP8[(((s)+(i))|0)]=byte_;
+      }
+      HEAP8[(((s)+(i))|0)]=0;
+      return s;
+    }
+
+  var _tan=Math_tan;
+
+  function _ispunct(chr) {
+      return (chr >= 33 && chr <= 47) ||
+             (chr >= 58 && chr <= 64) ||
+             (chr >= 91 && chr <= 96) ||
+             (chr >= 123 && chr <= 126);
+    }
+
+  function _feof(stream) {
+      // int feof(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/feof.html
+      stream = FS.getStreamFromPtr(stream);
+      return Number(stream && stream.eof);
+    }
+
+
+  Module["_tolower"] = _tolower;
+
+  var _asin=Math_asin;
+
+  function _clearerr(stream) {
+      // void clearerr(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/clearerr.html
+      stream = FS.getStreamFromPtr(stream);
+      if (!stream) {
+        return;
+      }
+      stream.eof = false;
+      stream.error = false;
+    }
+
+  var _fabs=Math_abs;
+
+  function _clock() {
+      if (_clock.start === undefined) _clock.start = Date.now();
+      return Math.floor((Date.now() - _clock.start) * (1000000/1000));
+    }
+
+
+  var _getc=_fgetc;
+
+  function _modf(x, intpart) {
+      HEAPF64[((intpart)>>3)]=Math.floor(x);
+      return x - HEAPF64[((intpart)>>3)];
+    }
+
+  var _sqrt=Math_sqrt;
+
+  function _isxdigit(chr) {
+      return (chr >= 48 && chr <= 57) ||
+             (chr >= 97 && chr <= 102) ||
+             (chr >= 65 && chr <= 70);
+    }
+
+  function _ftell(stream) {
+      // long ftell(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/ftell.html
+      stream = FS.getStreamFromPtr(stream);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      if (FS.isChrdev(stream.node.mode)) {
+        ___setErrNo(ERRNO_CODES.ESPIPE);
+        return -1;
+      } else {
+        return stream.position;
+      }
+    }
+
+
+  function __exit(status) {
+      // void _exit(int status);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/exit.html
+      Module['exit'](status);
+    }function _exit(status) {
+      __exit(status);
+    }
+
+
+  function _snprintf(s, n, format, varargs) {
+      // int snprintf(char *restrict s, size_t n, const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var result = __formatString(format, varargs);
+      var limit = (n === undefined) ? result.length
+                                    : Math.min(result.length, Math.max(n - 1, 0));
+      if (s < 0) {
+        s = -s;
+        var buf = _malloc(limit+1);
+        HEAP32[((s)>>2)]=buf;
+        s = buf;
+      }
+      for (var i = 0; i < limit; i++) {
+        HEAP8[(((s)+(i))|0)]=result[i];
+      }
+      if (limit < n || (n === undefined)) HEAP8[(((s)+(i))|0)]=0;
+      return result.length;
+    }function _sprintf(s, format, varargs) {
+      // int sprintf(char *restrict s, const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      return _snprintf(s, undefined, format, varargs);
+    }
+
+  var _emscripten_get_longjmp_result=true;
+
+  var _sin=Math_sin;
+
+
+  function _fmod(x, y) {
+      return x % y;
+    }var _fmodl=_fmod;
+
+
+
+  var _atan=Math_atan;
+
+  function _ferror(stream) {
+      // int ferror(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/ferror.html
+      stream = FS.getStreamFromPtr(stream);
+      return Number(stream && stream.error);
+    }
+
+  function _time(ptr) {
+      var ret = Math.floor(Date.now()/1000);
+      if (ptr) {
+        HEAP32[((ptr)>>2)]=ret;
+      }
+      return ret;
+    }
+
+  function _copysign(a, b) {
+      return __reallyNegative(a) === __reallyNegative(b) ? a : -a;
+    }
+
+
+  function _gmtime_r(time, tmPtr) {
+      var date = new Date(HEAP32[((time)>>2)]*1000);
+      HEAP32[((tmPtr)>>2)]=date.getUTCSeconds();
+      HEAP32[(((tmPtr)+(4))>>2)]=date.getUTCMinutes();
+      HEAP32[(((tmPtr)+(8))>>2)]=date.getUTCHours();
+      HEAP32[(((tmPtr)+(12))>>2)]=date.getUTCDate();
+      HEAP32[(((tmPtr)+(16))>>2)]=date.getUTCMonth();
+      HEAP32[(((tmPtr)+(20))>>2)]=date.getUTCFullYear()-1900;
+      HEAP32[(((tmPtr)+(24))>>2)]=date.getUTCDay();
+      HEAP32[(((tmPtr)+(36))>>2)]=0;
+      HEAP32[(((tmPtr)+(32))>>2)]=0;
+      var start = new Date(date); // define date using UTC, start from Jan 01 00:00:00 UTC
+      start.setUTCDate(1);
+      start.setUTCMonth(0);
+      start.setUTCHours(0);
+      start.setUTCMinutes(0);
+      start.setUTCSeconds(0);
+      start.setUTCMilliseconds(0);
+      var yday = Math.floor((date.getTime() - start.getTime()) / (1000 * 60 * 60 * 24));
+      HEAP32[(((tmPtr)+(28))>>2)]=yday;
+      HEAP32[(((tmPtr)+(40))>>2)]=___tm_timezone;
+
+      return tmPtr;
+    }function _gmtime(time) {
+      return _gmtime_r(time, ___tm_current);
+    }
+
+  function _isgraph(chr) {
+      return 0x20 < chr && chr < 0x7F;
+    }
+
+
+
+  function _strerror_r(errnum, strerrbuf, buflen) {
+      if (errnum in ERRNO_MESSAGES) {
+        if (ERRNO_MESSAGES[errnum].length > buflen - 1) {
+          return ___setErrNo(ERRNO_CODES.ERANGE);
+        } else {
+          var msg = ERRNO_MESSAGES[errnum];
+          writeAsciiToMemory(msg, strerrbuf);
+          return 0;
+        }
+      } else {
+        return ___setErrNo(ERRNO_CODES.EINVAL);
+      }
+    }function _strerror(errnum) {
+      if (!_strerror.buffer) _strerror.buffer = _malloc(256);
+      _strerror_r(errnum, _strerror.buffer, 256);
+      return _strerror.buffer;
+    }
+
+
+
+
+
+  var _environ=allocate(1, "i32*", ALLOC_STATIC);var ___environ=_environ;function ___buildEnvironment(env) {
+      // WARNING: Arbitrary limit!
+      var MAX_ENV_VALUES = 64;
+      var TOTAL_ENV_SIZE = 1024;
+
+      // Statically allocate memory for the environment.
+      var poolPtr;
+      var envPtr;
+      if (!___buildEnvironment.called) {
+        ___buildEnvironment.called = true;
+        // Set default values. Use string keys for Closure Compiler compatibility.
+        ENV['USER'] = 'root';
+        ENV['PATH'] = '/';
+        ENV['PWD'] = '/';
+        ENV['HOME'] = '/home/emscripten';
+        ENV['LANG'] = 'en_US.UTF-8';
+        ENV['_'] = './this.program';
+        // Allocate memory.
+        poolPtr = allocate(TOTAL_ENV_SIZE, 'i8', ALLOC_STATIC);
+        envPtr = allocate(MAX_ENV_VALUES * 4,
+                          'i8*', ALLOC_STATIC);
+        HEAP32[((envPtr)>>2)]=poolPtr;
+        HEAP32[((_environ)>>2)]=envPtr;
+      } else {
+        envPtr = HEAP32[((_environ)>>2)];
+        poolPtr = HEAP32[((envPtr)>>2)];
+      }
+
+      // Collect key=value lines.
+      var strings = [];
+      var totalSize = 0;
+      for (var key in env) {
+        if (typeof env[key] === 'string') {
+          var line = key + '=' + env[key];
+          strings.push(line);
+          totalSize += line.length;
+        }
+      }
+      if (totalSize > TOTAL_ENV_SIZE) {
+        throw new Error('Environment size exceeded TOTAL_ENV_SIZE!');
+      }
+
+      // Make new.
+      var ptrSize = 4;
+      for (var i = 0; i < strings.length; i++) {
+        var line = strings[i];
+        writeAsciiToMemory(line, poolPtr);
+        HEAP32[(((envPtr)+(i * ptrSize))>>2)]=poolPtr;
+        poolPtr += line.length + 1;
+      }
+      HEAP32[(((envPtr)+(strings.length * ptrSize))>>2)]=0;
+    }var ENV={};function _getenv(name) {
+      // char *getenv(const char *name);
+      // http://pubs.opengroup.org/onlinepubs/009695399/functions/getenv.html
+      if (name === 0) return 0;
+      name = Pointer_stringify(name);
+      if (!ENV.hasOwnProperty(name)) return 0;
+
+      if (_getenv.ret) _free(_getenv.ret);
+      _getenv.ret = allocate(intArrayFromString(ENV[name]), 'i8', ALLOC_NORMAL);
+      return _getenv.ret;
+    }
+
+  var _emscripten_setjmp=true;
+
+  var _cos=Math_cos;
+
+  function _isalnum(chr) {
+      return (chr >= 48 && chr <= 57) ||
+             (chr >= 97 && chr <= 122) ||
+             (chr >= 65 && chr <= 90);
+    }
+
+  var _BItoD=true;
+
+  function _difftime(time1, time0) {
+      return time1 - time0;
+    }
+
+  var _floor=Math_floor;
+
+  function _iscntrl(chr) {
+      return (0 <= chr && chr <= 0x1F) || chr === 0x7F;
+    }
+
+  var _atan2=Math_atan2;
+
+  function _setvbuf(stream, buf, type, size) {
+      // int setvbuf(FILE *restrict stream, char *restrict buf, int type, size_t size);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/setvbuf.html
+      // TODO: Implement custom buffering.
+      return 0;
+    }
+
+  var _exp=Math_exp;
+
+  var _copysignl=_copysign;
+
+  function _islower(chr) {
+      return chr >= 97 && chr <= 122;
+    }
+
+  var _acos=Math_acos;
+
+  function _isupper(chr) {
+      return chr >= 65 && chr <= 90;
+    }
+
+
+  function __isLeapYear(year) {
+        return year%4 === 0 && (year%100 !== 0 || year%400 === 0);
+    }
+
+  function __arraySum(array, index) {
+      var sum = 0;
+      for (var i = 0; i <= index; sum += array[i++]);
+      return sum;
+    }
+
+
+  var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];
+
+  var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date, days) {
+      var newDate = new Date(date.getTime());
+      while(days > 0) {
+        var leap = __isLeapYear(newDate.getFullYear());
+        var currentMonth = newDate.getMonth();
+        var daysInCurrentMonth = (leap ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR)[currentMonth];
+
+        if (days > daysInCurrentMonth-newDate.getDate()) {
+          // we spill over to next month
+          days -= (daysInCurrentMonth-newDate.getDate()+1);
+          newDate.setDate(1);
+          if (currentMonth < 11) {
+            newDate.setMonth(currentMonth+1)
+          } else {
+            newDate.setMonth(0);
+            newDate.setFullYear(newDate.getFullYear()+1);
+          }
+        } else {
+          // we stay in current month
+          newDate.setDate(newDate.getDate()+days);
+          return newDate;
+        }
+      }
+
+      return newDate;
+    }function _strftime(s, maxsize, format, tm) {
+      // size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr);
+      // http://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html
+
+      var date = {
+        tm_sec: HEAP32[((tm)>>2)],
+        tm_min: HEAP32[(((tm)+(4))>>2)],
+        tm_hour: HEAP32[(((tm)+(8))>>2)],
+        tm_mday: HEAP32[(((tm)+(12))>>2)],
+        tm_mon: HEAP32[(((tm)+(16))>>2)],
+        tm_year: HEAP32[(((tm)+(20))>>2)],
+        tm_wday: HEAP32[(((tm)+(24))>>2)],
+        tm_yday: HEAP32[(((tm)+(28))>>2)],
+        tm_isdst: HEAP32[(((tm)+(32))>>2)]
+      };
+
+      var pattern = Pointer_stringify(format);
+
+      // expand format
+      var EXPANSION_RULES_1 = {
+        '%c': '%a %b %d %H:%M:%S %Y',     // Replaced by the locale's appropriate date and time representation - e.g., Mon Aug  3 14:02:01 2013
+        '%D': '%m/%d/%y',                 // Equivalent to %m / %d / %y
+        '%F': '%Y-%m-%d',                 // Equivalent to %Y - %m - %d
+        '%h': '%b',                       // Equivalent to %b
+        '%r': '%I:%M:%S %p',              // Replaced by the time in a.m. and p.m. notation
+        '%R': '%H:%M',                    // Replaced by the time in 24-hour notation
+        '%T': '%H:%M:%S',                 // Replaced by the time
+        '%x': '%m/%d/%y',                 // Replaced by the locale's appropriate date representation
+        '%X': '%H:%M:%S',                 // Replaced by the locale's appropriate date representation
+      };
+      for (var rule in EXPANSION_RULES_1) {
+        pattern = pattern.replace(new RegExp(rule, 'g'), EXPANSION_RULES_1[rule]);
+      }
+
+      var WEEKDAYS = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+      var MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
+
+      function leadingSomething(value, digits, character) {
+        var str = typeof value === 'number' ? value.toString() : (value || '');
+        while (str.length < digits) {
+          str = character[0]+str;
+        }
+        return str;
+      };
+
+      function leadingNulls(value, digits) {
+        return leadingSomething(value, digits, '0');
+      };
+
+      function compareByDay(date1, date2) {
+        function sgn(value) {
+          return value < 0 ? -1 : (value > 0 ? 1 : 0);
+        };
+
+        var compare;
+        if ((compare = sgn(date1.getFullYear()-date2.getFullYear())) === 0) {
+          if ((compare = sgn(date1.getMonth()-date2.getMonth())) === 0) {
+            compare = sgn(date1.getDate()-date2.getDate());
+          }
+        }
+        return compare;
+      };
+
+      function getFirstWeekStartDate(janFourth) {
+          switch (janFourth.getDay()) {
+            case 0: // Sunday
+              return new Date(janFourth.getFullYear()-1, 11, 29);
+            case 1: // Monday
+              return janFourth;
+            case 2: // Tuesday
+              return new Date(janFourth.getFullYear(), 0, 3);
+            case 3: // Wednesday
+              return new Date(janFourth.getFullYear(), 0, 2);
+            case 4: // Thursday
+              return new Date(janFourth.getFullYear(), 0, 1);
+            case 5: // Friday
+              return new Date(janFourth.getFullYear()-1, 11, 31);
+            case 6: // Saturday
+              return new Date(janFourth.getFullYear()-1, 11, 30);
+          }
+      };
+
+      function getWeekBasedYear(date) {
+          var thisDate = __addDays(new Date(date.tm_year+1900, 0, 1), date.tm_yday);
+
+          var janFourthThisYear = new Date(thisDate.getFullYear(), 0, 4);
+          var janFourthNextYear = new Date(thisDate.getFullYear()+1, 0, 4);
+
+          var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear);
+          var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear);
+
+          if (compareByDay(firstWeekStartThisYear, thisDate) <= 0) {
+            // this date is after the start of the first week of this year
+            if (compareByDay(firstWeekStartNextYear, thisDate) <= 0) {
+              return thisDate.getFullYear()+1;
+            } else {
+              return thisDate.getFullYear();
+            }
+          } else {
+            return thisDate.getFullYear()-1;
+          }
+      };
+
+      var EXPANSION_RULES_2 = {
+        '%a': function(date) {
+          return WEEKDAYS[date.tm_wday].substring(0,3);
+        },
+        '%A': function(date) {
+          return WEEKDAYS[date.tm_wday];
+        },
+        '%b': function(date) {
+          return MONTHS[date.tm_mon].substring(0,3);
+        },
+        '%B': function(date) {
+          return MONTHS[date.tm_mon];
+        },
+        '%C': function(date) {
+          var year = date.tm_year+1900;
+          return leadingNulls(Math.floor(year/100),2);
+        },
+        '%d': function(date) {
+          return leadingNulls(date.tm_mday, 2);
+        },
+        '%e': function(date) {
+          return leadingSomething(date.tm_mday, 2, ' ');
+        },
+        '%g': function(date) {
+          // %g, %G, and %V give values according to the ISO 8601:2000 standard week-based year.
+          // In this system, weeks begin on a Monday and week 1 of the year is the week that includes
+          // January 4th, which is also the week that includes the first Thursday of the year, and
+          // is also the first week that contains at least four days in the year.
+          // If the first Monday of January is the 2nd, 3rd, or 4th, the preceding days are part of
+          // the last week of the preceding year; thus, for Saturday 2nd January 1999,
+          // %G is replaced by 1998 and %V is replaced by 53. If December 29th, 30th,
+          // or 31st is a Monday, it and any following days are part of week 1 of the following year.
+          // Thus, for Tuesday 30th December 1997, %G is replaced by 1998 and %V is replaced by 01.
+
+          return getWeekBasedYear(date).toString().substring(2);
+        },
+        '%G': function(date) {
+          return getWeekBasedYear(date);
+        },
+        '%H': function(date) {
+          return leadingNulls(date.tm_hour, 2);
+        },
+        '%I': function(date) {
+          return leadingNulls(date.tm_hour < 13 ? date.tm_hour : date.tm_hour-12, 2);
+        },
+        '%j': function(date) {
+          // Day of the year (001-366)
+          return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, date.tm_mon-1), 3);
+        },
+        '%m': function(date) {
+          return leadingNulls(date.tm_mon+1, 2);
+        },
+        '%M': function(date) {
+          return leadingNulls(date.tm_min, 2);
+        },
+        '%n': function() {
+          return '\n';
+        },
+        '%p': function(date) {
+          if (date.tm_hour > 0 && date.tm_hour < 13) {
+            return 'AM';
+          } else {
+            return 'PM';
+          }
+        },
+        '%S': function(date) {
+          return leadingNulls(date.tm_sec, 2);
+        },
+        '%t': function() {
+          return '\t';
+        },
+        '%u': function(date) {
+          var day = new Date(date.tm_year+1900, date.tm_mon+1, date.tm_mday, 0, 0, 0, 0);
+          return day.getDay() || 7;
+        },
+        '%U': function(date) {
+          // Replaced by the week number of the year as a decimal number [00,53].
+          // The first Sunday of January is the first day of week 1;
+          // days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
+          var janFirst = new Date(date.tm_year+1900, 0, 1);
+          var firstSunday = janFirst.getDay() === 0 ? janFirst : __addDays(janFirst, 7-janFirst.getDay());
+          var endDate = new Date(date.tm_year+1900, date.tm_mon, date.tm_mday);
+
+          // is target date after the first Sunday?
+          if (compareByDay(firstSunday, endDate) < 0) {
+            // calculate difference in days between first Sunday and endDate
+            var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth()-1)-31;
+            var firstSundayUntilEndJanuary = 31-firstSunday.getDate();
+            var days = firstSundayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();
+            return leadingNulls(Math.ceil(days/7), 2);
+          }
+
+          return compareByDay(firstSunday, janFirst) === 0 ? '01': '00';
+        },
+        '%V': function(date) {
+          // Replaced by the week number of the year (Monday as the first day of the week)
+          // as a decimal number [01,53]. If the week containing 1 January has four
+          // or more days in the new year, then it is considered week 1.
+          // Otherwise, it is the last week of the previous year, and the next week is week 1.
+          // Both January 4th and the first Thursday of January are always in week 1. [ tm_year, tm_wday, tm_yday]
+          var janFourthThisYear = new Date(date.tm_year+1900, 0, 4);
+          var janFourthNextYear = new Date(date.tm_year+1901, 0, 4);
+
+          var firstWeekStartThisYear = getFirstWeekStartDate(janFourthThisYear);
+          var firstWeekStartNextYear = getFirstWeekStartDate(janFourthNextYear);
+
+          var endDate = __addDays(new Date(date.tm_year+1900, 0, 1), date.tm_yday);
+
+          if (compareByDay(endDate, firstWeekStartThisYear) < 0) {
+            // if given date is before this years first week, then it belongs to the 53rd week of last year
+            return '53';
+          }
+
+          if (compareByDay(firstWeekStartNextYear, endDate) <= 0) {
+            // if given date is after next years first week, then it belongs to the 01th week of next year
+            return '01';
+          }
+
+          // given date is in between CW 01..53 of this calendar year
+          var daysDifference;
+          if (firstWeekStartThisYear.getFullYear() < date.tm_year+1900) {
+            // first CW of this year starts last year
+            daysDifference = date.tm_yday+32-firstWeekStartThisYear.getDate()
+          } else {
+            // first CW of this year starts this year
+            daysDifference = date.tm_yday+1-firstWeekStartThisYear.getDate();
+          }
+          return leadingNulls(Math.ceil(daysDifference/7), 2);
+        },
+        '%w': function(date) {
+          var day = new Date(date.tm_year+1900, date.tm_mon+1, date.tm_mday, 0, 0, 0, 0);
+          return day.getDay();
+        },
+        '%W': function(date) {
+          // Replaced by the week number of the year as a decimal number [00,53].
+          // The first Monday of January is the first day of week 1;
+          // days in the new year before this are in week 0. [ tm_year, tm_wday, tm_yday]
+          var janFirst = new Date(date.tm_year, 0, 1);
+          var firstMonday = janFirst.getDay() === 1 ? janFirst : __addDays(janFirst, janFirst.getDay() === 0 ? 1 : 7-janFirst.getDay()+1);
+          var endDate = new Date(date.tm_year+1900, date.tm_mon, date.tm_mday);
+
+          // is target date after the first Monday?
+          if (compareByDay(firstMonday, endDate) < 0) {
+            var februaryFirstUntilEndMonth = __arraySum(__isLeapYear(endDate.getFullYear()) ? __MONTH_DAYS_LEAP : __MONTH_DAYS_REGULAR, endDate.getMonth()-1)-31;
+            var firstMondayUntilEndJanuary = 31-firstMonday.getDate();
+            var days = firstMondayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();
+            return leadingNulls(Math.ceil(days/7), 2);
+          }
+          return compareByDay(firstMonday, janFirst) === 0 ? '01': '00';
+        },
+        '%y': function(date) {
+          // Replaced by the last two digits of the year as a decimal number [00,99]. [ tm_year]
+          return (date.tm_year+1900).toString().substring(2);
+        },
+        '%Y': function(date) {
+          // Replaced by the year as a decimal number (for example, 1997). [ tm_year]
+          return date.tm_year+1900;
+        },
+        '%z': function(date) {
+          // Replaced by the offset from UTC in the ISO 8601:2000 standard format ( +hhmm or -hhmm ),
+          // or by no characters if no timezone is determinable.
+          // For example, "-0430" means 4 hours 30 minutes behind UTC (west of Greenwich).
+          // If tm_isdst is zero, the standard time offset is used.
+          // If tm_isdst is greater than zero, the daylight savings time offset is used.
+          // If tm_isdst is negative, no characters are returned.
+          // FIXME: we cannot determine time zone (or can we?)
+          return '';
+        },
+        '%Z': function(date) {
+          // Replaced by the timezone name or abbreviation, or by no bytes if no timezone information exists. [ tm_isdst]
+          // FIXME: we cannot determine time zone (or can we?)
+          return '';
+        },
+        '%%': function() {
+          return '%';
+        }
+      };
+      for (var rule in EXPANSION_RULES_2) {
+        if (pattern.indexOf(rule) >= 0) {
+          pattern = pattern.replace(new RegExp(rule, 'g'), EXPANSION_RULES_2[rule](date));
+        }
+      }
+
+      var bytes = intArrayFromString(pattern, false);
+      if (bytes.length > maxsize) {
+        return 0;
+      }
+
+      writeArrayToMemory(bytes, s);
+      return bytes.length-1;
+    }
+
+
+
+FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice;
+___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0;
+__ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor();
+if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); }
+__ATINIT__.push({ func: function() { SOCKFS.root = FS.mount(SOCKFS, {}, null); } });
+_fputc.ret = allocate([0], "i8", ALLOC_STATIC);
+Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };
+  Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
+  Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
+  Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
+  Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
+  Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }
+_fgetc.ret = allocate([0], "i8", ALLOC_STATIC);
+___buildEnvironment(ENV);
+STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);
+
+staticSealed = true; // seal the static portion of memory
+
+STACK_MAX = STACK_BASE + 5242880;
+
+DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);
+
+assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");
+
+ var ctlz_i8 = allocate([8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "i8", ALLOC_DYNAMIC);
+ var cttz_i8 = allocate([8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0], "i8", ALLOC_DYNAMIC);
+
+var Math_min = Math.min;
+function invoke_iiii(index,a1,a2,a3) {
+  try {
+    return Module["dynCall_iiii"](index,a1,a2,a3);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_vi(index,a1) {
+  try {
+    Module["dynCall_vi"](index,a1);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_vii(index,a1,a2) {
+  try {
+    Module["dynCall_vii"](index,a1,a2);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_ii(index,a1) {
+  try {
+    return Module["dynCall_ii"](index,a1);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_iiiii(index,a1,a2,a3,a4) {
+  try {
+    return Module["dynCall_iiiii"](index,a1,a2,a3,a4);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_iii(index,a1,a2) {
+  try {
+    return Module["dynCall_iii"](index,a1,a2);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function asmPrintInt(x, y) {
+  Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+function asmPrintFloat(x, y) {
+  Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+// EMSCRIPTEN_START_ASM
+var asm = (function(global, env, buffer) {
+  'use asm';
+  var HEAP8 = new global.Int8Array(buffer);
+  var HEAP16 = new global.Int16Array(buffer);
+  var HEAP32 = new global.Int32Array(buffer);
+  var HEAPU8 = new global.Uint8Array(buffer);
+  var HEAPU16 = new global.Uint16Array(buffer);
+  var HEAPU32 = new global.Uint32Array(buffer);
+  var HEAPF32 = new global.Float32Array(buffer);
+  var HEAPF64 = new global.Float64Array(buffer);
+
+  var STACKTOP=env.STACKTOP|0;
+  var STACK_MAX=env.STACK_MAX|0;
+  var tempDoublePtr=env.tempDoublePtr|0;
+  var ABORT=env.ABORT|0;
+  var cttz_i8=env.cttz_i8|0;
+  var ctlz_i8=env.ctlz_i8|0;
+  var ___rand_seed=env.___rand_seed|0;
+  var _stderr=env._stderr|0;
+  var _stdin=env._stdin|0;
+  var _stdout=env._stdout|0;
+
+  var __THREW__ = 0;
+  var threwValue = 0;
+  var setjmpId = 0;
+  var undef = 0;
+  var nan = +env.NaN, inf = +env.Infinity;
+  var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
+
+  var tempRet0 = 0;
+  var tempRet1 = 0;
+  var tempRet2 = 0;
+  var tempRet3 = 0;
+  var tempRet4 = 0;
+  var tempRet5 = 0;
+  var tempRet6 = 0;
+  var tempRet7 = 0;
+  var tempRet8 = 0;
+  var tempRet9 = 0;
+  var Math_floor=global.Math.floor;
+  var Math_abs=global.Math.abs;
+  var Math_sqrt=global.Math.sqrt;
+  var Math_pow=global.Math.pow;
+  var Math_cos=global.Math.cos;
+  var Math_sin=global.Math.sin;
+  var Math_tan=global.Math.tan;
+  var Math_acos=global.Math.acos;
+  var Math_asin=global.Math.asin;
+  var Math_atan=global.Math.atan;
+  var Math_atan2=global.Math.atan2;
+  var Math_exp=global.Math.exp;
+  var Math_log=global.Math.log;
+  var Math_ceil=global.Math.ceil;
+  var Math_imul=global.Math.imul;
+  var abort=env.abort;
+  var assert=env.assert;
+  var asmPrintInt=env.asmPrintInt;
+  var asmPrintFloat=env.asmPrintFloat;
+  var Math_min=env.min;
+  var invoke_iiii=env.invoke_iiii;
+  var invoke_vi=env.invoke_vi;
+  var invoke_vii=env.invoke_vii;
+  var invoke_ii=env.invoke_ii;
+  var invoke_iiiii=env.invoke_iiiii;
+  var invoke_iii=env.invoke_iii;
+  var _isalnum=env._isalnum;
+  var _fabs=env._fabs;
+  var _frexp=env._frexp;
+  var _exp=env._exp;
+  var _fread=env._fread;
+  var __reallyNegative=env.__reallyNegative;
+  var _longjmp=env._longjmp;
+  var __addDays=env.__addDays;
+  var _fsync=env._fsync;
+  var _signal=env._signal;
+  var _rename=env._rename;
+  var _sbrk=env._sbrk;
+  var _emscripten_memcpy_big=env._emscripten_memcpy_big;
+  var _sinh=env._sinh;
+  var _sysconf=env._sysconf;
+  var _close=env._close;
+  var _ferror=env._ferror;
+  var _clock=env._clock;
+  var _cos=env._cos;
+  var _tanh=env._tanh;
+  var _unlink=env._unlink;
+  var _write=env._write;
+  var __isLeapYear=env.__isLeapYear;
+  var _ftell=env._ftell;
+  var _isupper=env._isupper;
+  var _gmtime_r=env._gmtime_r;
+  var _islower=env._islower;
+  var _tmpnam=env._tmpnam;
+  var _tmpfile=env._tmpfile;
+  var _send=env._send;
+  var _abort=env._abort;
+  var _setvbuf=env._setvbuf;
+  var _atan2=env._atan2;
+  var _setlocale=env._setlocale;
+  var _isgraph=env._isgraph;
+  var _modf=env._modf;
+  var _strerror_r=env._strerror_r;
+  var _fscanf=env._fscanf;
+  var ___setErrNo=env.___setErrNo;
+  var _isalpha=env._isalpha;
+  var _srand=env._srand;
+  var _mktime=env._mktime;
+  var _putchar=env._putchar;
+  var _gmtime=env._gmtime;
+  var _localeconv=env._localeconv;
+  var _sprintf=env._sprintf;
+  var _localtime=env._localtime;
+  var _read=env._read;
+  var _fwrite=env._fwrite;
+  var _time=env._time;
+  var _fprintf=env._fprintf;
+  var _exit=env._exit;
+  var _freopen=env._freopen;
+  var _llvm_pow_f64=env._llvm_pow_f64;
+  var _fgetc=env._fgetc;
+  var _fmod=env._fmod;
+  var _lseek=env._lseek;
+  var _rmdir=env._rmdir;
+  var _asin=env._asin;
+  var _floor=env._floor;
+  var _pwrite=env._pwrite;
+  var _localtime_r=env._localtime_r;
+  var _tzset=env._tzset;
+  var _open=env._open;
+  var _remove=env._remove;
+  var _snprintf=env._snprintf;
+  var __scanString=env.__scanString;
+  var _strftime=env._strftime;
+  var _fseek=env._fseek;
+  var _iscntrl=env._iscntrl;
+  var _isxdigit=env._isxdigit;
+  var _fclose=env._fclose;
+  var _log=env._log;
+  var _recv=env._recv;
+  var _tan=env._tan;
+  var _copysign=env._copysign;
+  var __getFloat=env.__getFloat;
+  var _fputc=env._fputc;
+  var _ispunct=env._ispunct;
+  var _ceil=env._ceil;
+  var _isspace=env._isspace;
+  var _fopen=env._fopen;
+  var _sin=env._sin;
+  var _acos=env._acos;
+  var _cosh=env._cosh;
+  var ___buildEnvironment=env.___buildEnvironment;
+  var _difftime=env._difftime;
+  var _ungetc=env._ungetc;
+  var _system=env._system;
+  var _fflush=env._fflush;
+  var _log10=env._log10;
+  var _fileno=env._fileno;
+  var __exit=env.__exit;
+  var __arraySum=env.__arraySum;
+  var _fgets=env._fgets;
+  var _atan=env._atan;
+  var _pread=env._pread;
+  var _mkport=env._mkport;
+  var _toupper=env._toupper;
+  var _feof=env._feof;
+  var ___errno_location=env.___errno_location;
+  var _clearerr=env._clearerr;
+  var _getenv=env._getenv;
+  var _strerror=env._strerror;
+  var _emscripten_longjmp=env._emscripten_longjmp;
+  var __formatString=env.__formatString;
+  var _fputs=env._fputs;
+  var _sqrt=env._sqrt;
+  var tempFloat = 0.0;
+
+// EMSCRIPTEN_START_FUNCS
+function _malloc(i12) {
+ i12 = i12 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0;
+ i1 = STACKTOP;
+ do {
+  if (i12 >>> 0 < 245) {
+   if (i12 >>> 0 < 11) {
+    i12 = 16;
+   } else {
+    i12 = i12 + 11 & -8;
+   }
+   i20 = i12 >>> 3;
+   i18 = HEAP32[3228] | 0;
+   i21 = i18 >>> i20;
+   if ((i21 & 3 | 0) != 0) {
+    i6 = (i21 & 1 ^ 1) + i20 | 0;
+    i5 = i6 << 1;
+    i3 = 12952 + (i5 << 2) | 0;
+    i5 = 12952 + (i5 + 2 << 2) | 0;
+    i7 = HEAP32[i5 >> 2] | 0;
+    i2 = i7 + 8 | 0;
+    i4 = HEAP32[i2 >> 2] | 0;
+    do {
+     if ((i3 | 0) != (i4 | 0)) {
+      if (i4 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i8 = i4 + 12 | 0;
+      if ((HEAP32[i8 >> 2] | 0) == (i7 | 0)) {
+       HEAP32[i8 >> 2] = i3;
+       HEAP32[i5 >> 2] = i4;
+       break;
+      } else {
+       _abort();
+      }
+     } else {
+      HEAP32[3228] = i18 & ~(1 << i6);
+     }
+    } while (0);
+    i32 = i6 << 3;
+    HEAP32[i7 + 4 >> 2] = i32 | 3;
+    i32 = i7 + (i32 | 4) | 0;
+    HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+    i32 = i2;
+    STACKTOP = i1;
+    return i32 | 0;
+   }
+   if (i12 >>> 0 > (HEAP32[12920 >> 2] | 0) >>> 0) {
+    if ((i21 | 0) != 0) {
+     i7 = 2 << i20;
+     i7 = i21 << i20 & (i7 | 0 - i7);
+     i7 = (i7 & 0 - i7) + -1 | 0;
+     i2 = i7 >>> 12 & 16;
+     i7 = i7 >>> i2;
+     i6 = i7 >>> 5 & 8;
+     i7 = i7 >>> i6;
+     i5 = i7 >>> 2 & 4;
+     i7 = i7 >>> i5;
+     i4 = i7 >>> 1 & 2;
+     i7 = i7 >>> i4;
+     i3 = i7 >>> 1 & 1;
+     i3 = (i6 | i2 | i5 | i4 | i3) + (i7 >>> i3) | 0;
+     i7 = i3 << 1;
+     i4 = 12952 + (i7 << 2) | 0;
+     i7 = 12952 + (i7 + 2 << 2) | 0;
+     i5 = HEAP32[i7 >> 2] | 0;
+     i2 = i5 + 8 | 0;
+     i6 = HEAP32[i2 >> 2] | 0;
+     do {
+      if ((i4 | 0) != (i6 | 0)) {
+       if (i6 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+        _abort();
+       }
+       i8 = i6 + 12 | 0;
+       if ((HEAP32[i8 >> 2] | 0) == (i5 | 0)) {
+        HEAP32[i8 >> 2] = i4;
+        HEAP32[i7 >> 2] = i6;
+        break;
+       } else {
+        _abort();
+       }
+      } else {
+       HEAP32[3228] = i18 & ~(1 << i3);
+      }
+     } while (0);
+     i6 = i3 << 3;
+     i4 = i6 - i12 | 0;
+     HEAP32[i5 + 4 >> 2] = i12 | 3;
+     i3 = i5 + i12 | 0;
+     HEAP32[i5 + (i12 | 4) >> 2] = i4 | 1;
+     HEAP32[i5 + i6 >> 2] = i4;
+     i6 = HEAP32[12920 >> 2] | 0;
+     if ((i6 | 0) != 0) {
+      i5 = HEAP32[12932 >> 2] | 0;
+      i8 = i6 >>> 3;
+      i9 = i8 << 1;
+      i6 = 12952 + (i9 << 2) | 0;
+      i7 = HEAP32[3228] | 0;
+      i8 = 1 << i8;
+      if ((i7 & i8 | 0) != 0) {
+       i7 = 12952 + (i9 + 2 << 2) | 0;
+       i8 = HEAP32[i7 >> 2] | 0;
+       if (i8 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        i28 = i7;
+        i27 = i8;
+       }
+      } else {
+       HEAP32[3228] = i7 | i8;
+       i28 = 12952 + (i9 + 2 << 2) | 0;
+       i27 = i6;
+      }
+      HEAP32[i28 >> 2] = i5;
+      HEAP32[i27 + 12 >> 2] = i5;
+      HEAP32[i5 + 8 >> 2] = i27;
+      HEAP32[i5 + 12 >> 2] = i6;
+     }
+     HEAP32[12920 >> 2] = i4;
+     HEAP32[12932 >> 2] = i3;
+     i32 = i2;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+    i18 = HEAP32[12916 >> 2] | 0;
+    if ((i18 | 0) != 0) {
+     i2 = (i18 & 0 - i18) + -1 | 0;
+     i31 = i2 >>> 12 & 16;
+     i2 = i2 >>> i31;
+     i30 = i2 >>> 5 & 8;
+     i2 = i2 >>> i30;
+     i32 = i2 >>> 2 & 4;
+     i2 = i2 >>> i32;
+     i6 = i2 >>> 1 & 2;
+     i2 = i2 >>> i6;
+     i3 = i2 >>> 1 & 1;
+     i3 = HEAP32[13216 + ((i30 | i31 | i32 | i6 | i3) + (i2 >>> i3) << 2) >> 2] | 0;
+     i2 = (HEAP32[i3 + 4 >> 2] & -8) - i12 | 0;
+     i6 = i3;
+     while (1) {
+      i5 = HEAP32[i6 + 16 >> 2] | 0;
+      if ((i5 | 0) == 0) {
+       i5 = HEAP32[i6 + 20 >> 2] | 0;
+       if ((i5 | 0) == 0) {
+        break;
+       }
+      }
+      i6 = (HEAP32[i5 + 4 >> 2] & -8) - i12 | 0;
+      i4 = i6 >>> 0 < i2 >>> 0;
+      i2 = i4 ? i6 : i2;
+      i6 = i5;
+      i3 = i4 ? i5 : i3;
+     }
+     i6 = HEAP32[12928 >> 2] | 0;
+     if (i3 >>> 0 < i6 >>> 0) {
+      _abort();
+     }
+     i4 = i3 + i12 | 0;
+     if (!(i3 >>> 0 < i4 >>> 0)) {
+      _abort();
+     }
+     i5 = HEAP32[i3 + 24 >> 2] | 0;
+     i7 = HEAP32[i3 + 12 >> 2] | 0;
+     do {
+      if ((i7 | 0) == (i3 | 0)) {
+       i8 = i3 + 20 | 0;
+       i7 = HEAP32[i8 >> 2] | 0;
+       if ((i7 | 0) == 0) {
+        i8 = i3 + 16 | 0;
+        i7 = HEAP32[i8 >> 2] | 0;
+        if ((i7 | 0) == 0) {
+         i26 = 0;
+         break;
+        }
+       }
+       while (1) {
+        i10 = i7 + 20 | 0;
+        i9 = HEAP32[i10 >> 2] | 0;
+        if ((i9 | 0) != 0) {
+         i7 = i9;
+         i8 = i10;
+         continue;
+        }
+        i10 = i7 + 16 | 0;
+        i9 = HEAP32[i10 >> 2] | 0;
+        if ((i9 | 0) == 0) {
+         break;
+        } else {
+         i7 = i9;
+         i8 = i10;
+        }
+       }
+       if (i8 >>> 0 < i6 >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i8 >> 2] = 0;
+        i26 = i7;
+        break;
+       }
+      } else {
+       i8 = HEAP32[i3 + 8 >> 2] | 0;
+       if (i8 >>> 0 < i6 >>> 0) {
+        _abort();
+       }
+       i6 = i8 + 12 | 0;
+       if ((HEAP32[i6 >> 2] | 0) != (i3 | 0)) {
+        _abort();
+       }
+       i9 = i7 + 8 | 0;
+       if ((HEAP32[i9 >> 2] | 0) == (i3 | 0)) {
+        HEAP32[i6 >> 2] = i7;
+        HEAP32[i9 >> 2] = i8;
+        i26 = i7;
+        break;
+       } else {
+        _abort();
+       }
+      }
+     } while (0);
+     do {
+      if ((i5 | 0) != 0) {
+       i7 = HEAP32[i3 + 28 >> 2] | 0;
+       i6 = 13216 + (i7 << 2) | 0;
+       if ((i3 | 0) == (HEAP32[i6 >> 2] | 0)) {
+        HEAP32[i6 >> 2] = i26;
+        if ((i26 | 0) == 0) {
+         HEAP32[12916 >> 2] = HEAP32[12916 >> 2] & ~(1 << i7);
+         break;
+        }
+       } else {
+        if (i5 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+         _abort();
+        }
+        i6 = i5 + 16 | 0;
+        if ((HEAP32[i6 >> 2] | 0) == (i3 | 0)) {
+         HEAP32[i6 >> 2] = i26;
+        } else {
+         HEAP32[i5 + 20 >> 2] = i26;
+        }
+        if ((i26 | 0) == 0) {
+         break;
+        }
+       }
+       if (i26 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+        _abort();
+       }
+       HEAP32[i26 + 24 >> 2] = i5;
+       i5 = HEAP32[i3 + 16 >> 2] | 0;
+       do {
+        if ((i5 | 0) != 0) {
+         if (i5 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i26 + 16 >> 2] = i5;
+          HEAP32[i5 + 24 >> 2] = i26;
+          break;
+         }
+        }
+       } while (0);
+       i5 = HEAP32[i3 + 20 >> 2] | 0;
+       if ((i5 | 0) != 0) {
+        if (i5 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i26 + 20 >> 2] = i5;
+         HEAP32[i5 + 24 >> 2] = i26;
+         break;
+        }
+       }
+      }
+     } while (0);
+     if (i2 >>> 0 < 16) {
+      i32 = i2 + i12 | 0;
+      HEAP32[i3 + 4 >> 2] = i32 | 3;
+      i32 = i3 + (i32 + 4) | 0;
+      HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+     } else {
+      HEAP32[i3 + 4 >> 2] = i12 | 3;
+      HEAP32[i3 + (i12 | 4) >> 2] = i2 | 1;
+      HEAP32[i3 + (i2 + i12) >> 2] = i2;
+      i6 = HEAP32[12920 >> 2] | 0;
+      if ((i6 | 0) != 0) {
+       i5 = HEAP32[12932 >> 2] | 0;
+       i8 = i6 >>> 3;
+       i9 = i8 << 1;
+       i6 = 12952 + (i9 << 2) | 0;
+       i7 = HEAP32[3228] | 0;
+       i8 = 1 << i8;
+       if ((i7 & i8 | 0) != 0) {
+        i7 = 12952 + (i9 + 2 << 2) | 0;
+        i8 = HEAP32[i7 >> 2] | 0;
+        if (i8 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+         _abort();
+        } else {
+         i25 = i7;
+         i24 = i8;
+        }
+       } else {
+        HEAP32[3228] = i7 | i8;
+        i25 = 12952 + (i9 + 2 << 2) | 0;
+        i24 = i6;
+       }
+       HEAP32[i25 >> 2] = i5;
+       HEAP32[i24 + 12 >> 2] = i5;
+       HEAP32[i5 + 8 >> 2] = i24;
+       HEAP32[i5 + 12 >> 2] = i6;
+      }
+      HEAP32[12920 >> 2] = i2;
+      HEAP32[12932 >> 2] = i4;
+     }
+     i32 = i3 + 8 | 0;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+   }
+  } else {
+   if (!(i12 >>> 0 > 4294967231)) {
+    i24 = i12 + 11 | 0;
+    i12 = i24 & -8;
+    i26 = HEAP32[12916 >> 2] | 0;
+    if ((i26 | 0) != 0) {
+     i25 = 0 - i12 | 0;
+     i24 = i24 >>> 8;
+     if ((i24 | 0) != 0) {
+      if (i12 >>> 0 > 16777215) {
+       i27 = 31;
+      } else {
+       i31 = (i24 + 1048320 | 0) >>> 16 & 8;
+       i32 = i24 << i31;
+       i30 = (i32 + 520192 | 0) >>> 16 & 4;
+       i32 = i32 << i30;
+       i27 = (i32 + 245760 | 0) >>> 16 & 2;
+       i27 = 14 - (i30 | i31 | i27) + (i32 << i27 >>> 15) | 0;
+       i27 = i12 >>> (i27 + 7 | 0) & 1 | i27 << 1;
+      }
+     } else {
+      i27 = 0;
+     }
+     i30 = HEAP32[13216 + (i27 << 2) >> 2] | 0;
+     L126 : do {
+      if ((i30 | 0) == 0) {
+       i29 = 0;
+       i24 = 0;
+      } else {
+       if ((i27 | 0) == 31) {
+        i24 = 0;
+       } else {
+        i24 = 25 - (i27 >>> 1) | 0;
+       }
+       i29 = 0;
+       i28 = i12 << i24;
+       i24 = 0;
+       while (1) {
+        i32 = HEAP32[i30 + 4 >> 2] & -8;
+        i31 = i32 - i12 | 0;
+        if (i31 >>> 0 < i25 >>> 0) {
+         if ((i32 | 0) == (i12 | 0)) {
+          i25 = i31;
+          i29 = i30;
+          i24 = i30;
+          break L126;
+         } else {
+          i25 = i31;
+          i24 = i30;
+         }
+        }
+        i31 = HEAP32[i30 + 20 >> 2] | 0;
+        i30 = HEAP32[i30 + (i28 >>> 31 << 2) + 16 >> 2] | 0;
+        i29 = (i31 | 0) == 0 | (i31 | 0) == (i30 | 0) ? i29 : i31;
+        if ((i30 | 0) == 0) {
+         break;
+        } else {
+         i28 = i28 << 1;
+        }
+       }
+      }
+     } while (0);
+     if ((i29 | 0) == 0 & (i24 | 0) == 0) {
+      i32 = 2 << i27;
+      i26 = i26 & (i32 | 0 - i32);
+      if ((i26 | 0) == 0) {
+       break;
+      }
+      i32 = (i26 & 0 - i26) + -1 | 0;
+      i28 = i32 >>> 12 & 16;
+      i32 = i32 >>> i28;
+      i27 = i32 >>> 5 & 8;
+      i32 = i32 >>> i27;
+      i30 = i32 >>> 2 & 4;
+      i32 = i32 >>> i30;
+      i31 = i32 >>> 1 & 2;
+      i32 = i32 >>> i31;
+      i29 = i32 >>> 1 & 1;
+      i29 = HEAP32[13216 + ((i27 | i28 | i30 | i31 | i29) + (i32 >>> i29) << 2) >> 2] | 0;
+     }
+     if ((i29 | 0) != 0) {
+      while (1) {
+       i27 = (HEAP32[i29 + 4 >> 2] & -8) - i12 | 0;
+       i26 = i27 >>> 0 < i25 >>> 0;
+       i25 = i26 ? i27 : i25;
+       i24 = i26 ? i29 : i24;
+       i26 = HEAP32[i29 + 16 >> 2] | 0;
+       if ((i26 | 0) != 0) {
+        i29 = i26;
+        continue;
+       }
+       i29 = HEAP32[i29 + 20 >> 2] | 0;
+       if ((i29 | 0) == 0) {
+        break;
+       }
+      }
+     }
+     if ((i24 | 0) != 0 ? i25 >>> 0 < ((HEAP32[12920 >> 2] | 0) - i12 | 0) >>> 0 : 0) {
+      i4 = HEAP32[12928 >> 2] | 0;
+      if (i24 >>> 0 < i4 >>> 0) {
+       _abort();
+      }
+      i2 = i24 + i12 | 0;
+      if (!(i24 >>> 0 < i2 >>> 0)) {
+       _abort();
+      }
+      i3 = HEAP32[i24 + 24 >> 2] | 0;
+      i6 = HEAP32[i24 + 12 >> 2] | 0;
+      do {
+       if ((i6 | 0) == (i24 | 0)) {
+        i6 = i24 + 20 | 0;
+        i5 = HEAP32[i6 >> 2] | 0;
+        if ((i5 | 0) == 0) {
+         i6 = i24 + 16 | 0;
+         i5 = HEAP32[i6 >> 2] | 0;
+         if ((i5 | 0) == 0) {
+          i22 = 0;
+          break;
+         }
+        }
+        while (1) {
+         i8 = i5 + 20 | 0;
+         i7 = HEAP32[i8 >> 2] | 0;
+         if ((i7 | 0) != 0) {
+          i5 = i7;
+          i6 = i8;
+          continue;
+         }
+         i7 = i5 + 16 | 0;
+         i8 = HEAP32[i7 >> 2] | 0;
+         if ((i8 | 0) == 0) {
+          break;
+         } else {
+          i5 = i8;
+          i6 = i7;
+         }
+        }
+        if (i6 >>> 0 < i4 >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i6 >> 2] = 0;
+         i22 = i5;
+         break;
+        }
+       } else {
+        i5 = HEAP32[i24 + 8 >> 2] | 0;
+        if (i5 >>> 0 < i4 >>> 0) {
+         _abort();
+        }
+        i7 = i5 + 12 | 0;
+        if ((HEAP32[i7 >> 2] | 0) != (i24 | 0)) {
+         _abort();
+        }
+        i4 = i6 + 8 | 0;
+        if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
+         HEAP32[i7 >> 2] = i6;
+         HEAP32[i4 >> 2] = i5;
+         i22 = i6;
+         break;
+        } else {
+         _abort();
+        }
+       }
+      } while (0);
+      do {
+       if ((i3 | 0) != 0) {
+        i4 = HEAP32[i24 + 28 >> 2] | 0;
+        i5 = 13216 + (i4 << 2) | 0;
+        if ((i24 | 0) == (HEAP32[i5 >> 2] | 0)) {
+         HEAP32[i5 >> 2] = i22;
+         if ((i22 | 0) == 0) {
+          HEAP32[12916 >> 2] = HEAP32[12916 >> 2] & ~(1 << i4);
+          break;
+         }
+        } else {
+         if (i3 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+          _abort();
+         }
+         i4 = i3 + 16 | 0;
+         if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
+          HEAP32[i4 >> 2] = i22;
+         } else {
+          HEAP32[i3 + 20 >> 2] = i22;
+         }
+         if ((i22 | 0) == 0) {
+          break;
+         }
+        }
+        if (i22 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+         _abort();
+        }
+        HEAP32[i22 + 24 >> 2] = i3;
+        i3 = HEAP32[i24 + 16 >> 2] | 0;
+        do {
+         if ((i3 | 0) != 0) {
+          if (i3 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           HEAP32[i22 + 16 >> 2] = i3;
+           HEAP32[i3 + 24 >> 2] = i22;
+           break;
+          }
+         }
+        } while (0);
+        i3 = HEAP32[i24 + 20 >> 2] | 0;
+        if ((i3 | 0) != 0) {
+         if (i3 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i22 + 20 >> 2] = i3;
+          HEAP32[i3 + 24 >> 2] = i22;
+          break;
+         }
+        }
+       }
+      } while (0);
+      L204 : do {
+       if (!(i25 >>> 0 < 16)) {
+        HEAP32[i24 + 4 >> 2] = i12 | 3;
+        HEAP32[i24 + (i12 | 4) >> 2] = i25 | 1;
+        HEAP32[i24 + (i25 + i12) >> 2] = i25;
+        i4 = i25 >>> 3;
+        if (i25 >>> 0 < 256) {
+         i6 = i4 << 1;
+         i3 = 12952 + (i6 << 2) | 0;
+         i5 = HEAP32[3228] | 0;
+         i4 = 1 << i4;
+         if ((i5 & i4 | 0) != 0) {
+          i5 = 12952 + (i6 + 2 << 2) | 0;
+          i4 = HEAP32[i5 >> 2] | 0;
+          if (i4 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           i21 = i5;
+           i20 = i4;
+          }
+         } else {
+          HEAP32[3228] = i5 | i4;
+          i21 = 12952 + (i6 + 2 << 2) | 0;
+          i20 = i3;
+         }
+         HEAP32[i21 >> 2] = i2;
+         HEAP32[i20 + 12 >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i20;
+         HEAP32[i24 + (i12 + 12) >> 2] = i3;
+         break;
+        }
+        i3 = i25 >>> 8;
+        if ((i3 | 0) != 0) {
+         if (i25 >>> 0 > 16777215) {
+          i3 = 31;
+         } else {
+          i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+          i32 = i3 << i31;
+          i30 = (i32 + 520192 | 0) >>> 16 & 4;
+          i32 = i32 << i30;
+          i3 = (i32 + 245760 | 0) >>> 16 & 2;
+          i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+          i3 = i25 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+         }
+        } else {
+         i3 = 0;
+        }
+        i6 = 13216 + (i3 << 2) | 0;
+        HEAP32[i24 + (i12 + 28) >> 2] = i3;
+        HEAP32[i24 + (i12 + 20) >> 2] = 0;
+        HEAP32[i24 + (i12 + 16) >> 2] = 0;
+        i4 = HEAP32[12916 >> 2] | 0;
+        i5 = 1 << i3;
+        if ((i4 & i5 | 0) == 0) {
+         HEAP32[12916 >> 2] = i4 | i5;
+         HEAP32[i6 >> 2] = i2;
+         HEAP32[i24 + (i12 + 24) >> 2] = i6;
+         HEAP32[i24 + (i12 + 12) >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i2;
+         break;
+        }
+        i4 = HEAP32[i6 >> 2] | 0;
+        if ((i3 | 0) == 31) {
+         i3 = 0;
+        } else {
+         i3 = 25 - (i3 >>> 1) | 0;
+        }
+        L225 : do {
+         if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i25 | 0)) {
+          i3 = i25 << i3;
+          while (1) {
+           i6 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+           i5 = HEAP32[i6 >> 2] | 0;
+           if ((i5 | 0) == 0) {
+            break;
+           }
+           if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i25 | 0)) {
+            i18 = i5;
+            break L225;
+           } else {
+            i3 = i3 << 1;
+            i4 = i5;
+           }
+          }
+          if (i6 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           HEAP32[i6 >> 2] = i2;
+           HEAP32[i24 + (i12 + 24) >> 2] = i4;
+           HEAP32[i24 + (i12 + 12) >> 2] = i2;
+           HEAP32[i24 + (i12 + 8) >> 2] = i2;
+           break L204;
+          }
+         } else {
+          i18 = i4;
+         }
+        } while (0);
+        i4 = i18 + 8 | 0;
+        i3 = HEAP32[i4 >> 2] | 0;
+        i5 = HEAP32[12928 >> 2] | 0;
+        if (i18 >>> 0 < i5 >>> 0) {
+         _abort();
+        }
+        if (i3 >>> 0 < i5 >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i3 + 12 >> 2] = i2;
+         HEAP32[i4 >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i3;
+         HEAP32[i24 + (i12 + 12) >> 2] = i18;
+         HEAP32[i24 + (i12 + 24) >> 2] = 0;
+         break;
+        }
+       } else {
+        i32 = i25 + i12 | 0;
+        HEAP32[i24 + 4 >> 2] = i32 | 3;
+        i32 = i24 + (i32 + 4) | 0;
+        HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+       }
+      } while (0);
+      i32 = i24 + 8 | 0;
+      STACKTOP = i1;
+      return i32 | 0;
+     }
+    }
+   } else {
+    i12 = -1;
+   }
+  }
+ } while (0);
+ i18 = HEAP32[12920 >> 2] | 0;
+ if (!(i12 >>> 0 > i18 >>> 0)) {
+  i3 = i18 - i12 | 0;
+  i2 = HEAP32[12932 >> 2] | 0;
+  if (i3 >>> 0 > 15) {
+   HEAP32[12932 >> 2] = i2 + i12;
+   HEAP32[12920 >> 2] = i3;
+   HEAP32[i2 + (i12 + 4) >> 2] = i3 | 1;
+   HEAP32[i2 + i18 >> 2] = i3;
+   HEAP32[i2 + 4 >> 2] = i12 | 3;
+  } else {
+   HEAP32[12920 >> 2] = 0;
+   HEAP32[12932 >> 2] = 0;
+   HEAP32[i2 + 4 >> 2] = i18 | 3;
+   i32 = i2 + (i18 + 4) | 0;
+   HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+  }
+  i32 = i2 + 8 | 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ i18 = HEAP32[12924 >> 2] | 0;
+ if (i12 >>> 0 < i18 >>> 0) {
+  i31 = i18 - i12 | 0;
+  HEAP32[12924 >> 2] = i31;
+  i32 = HEAP32[12936 >> 2] | 0;
+  HEAP32[12936 >> 2] = i32 + i12;
+  HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
+  HEAP32[i32 + 4 >> 2] = i12 | 3;
+  i32 = i32 + 8 | 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ do {
+  if ((HEAP32[3346] | 0) == 0) {
+   i18 = _sysconf(30) | 0;
+   if ((i18 + -1 & i18 | 0) == 0) {
+    HEAP32[13392 >> 2] = i18;
+    HEAP32[13388 >> 2] = i18;
+    HEAP32[13396 >> 2] = -1;
+    HEAP32[13400 >> 2] = -1;
+    HEAP32[13404 >> 2] = 0;
+    HEAP32[13356 >> 2] = 0;
+    HEAP32[3346] = (_time(0) | 0) & -16 ^ 1431655768;
+    break;
+   } else {
+    _abort();
+   }
+  }
+ } while (0);
+ i20 = i12 + 48 | 0;
+ i25 = HEAP32[13392 >> 2] | 0;
+ i21 = i12 + 47 | 0;
+ i22 = i25 + i21 | 0;
+ i25 = 0 - i25 | 0;
+ i18 = i22 & i25;
+ if (!(i18 >>> 0 > i12 >>> 0)) {
+  i32 = 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ i24 = HEAP32[13352 >> 2] | 0;
+ if ((i24 | 0) != 0 ? (i31 = HEAP32[13344 >> 2] | 0, i32 = i31 + i18 | 0, i32 >>> 0 <= i31 >>> 0 | i32 >>> 0 > i24 >>> 0) : 0) {
+  i32 = 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ L269 : do {
+  if ((HEAP32[13356 >> 2] & 4 | 0) == 0) {
+   i26 = HEAP32[12936 >> 2] | 0;
+   L271 : do {
+    if ((i26 | 0) != 0) {
+     i24 = 13360 | 0;
+     while (1) {
+      i27 = HEAP32[i24 >> 2] | 0;
+      if (!(i27 >>> 0 > i26 >>> 0) ? (i23 = i24 + 4 | 0, (i27 + (HEAP32[i23 >> 2] | 0) | 0) >>> 0 > i26 >>> 0) : 0) {
+       break;
+      }
+      i24 = HEAP32[i24 + 8 >> 2] | 0;
+      if ((i24 | 0) == 0) {
+       i13 = 182;
+       break L271;
+      }
+     }
+     if ((i24 | 0) != 0) {
+      i25 = i22 - (HEAP32[12924 >> 2] | 0) & i25;
+      if (i25 >>> 0 < 2147483647) {
+       i13 = _sbrk(i25 | 0) | 0;
+       i26 = (i13 | 0) == ((HEAP32[i24 >> 2] | 0) + (HEAP32[i23 >> 2] | 0) | 0);
+       i22 = i13;
+       i24 = i25;
+       i23 = i26 ? i13 : -1;
+       i25 = i26 ? i25 : 0;
+       i13 = 191;
+      } else {
+       i25 = 0;
+      }
+     } else {
+      i13 = 182;
+     }
+    } else {
+     i13 = 182;
+    }
+   } while (0);
+   do {
+    if ((i13 | 0) == 182) {
+     i23 = _sbrk(0) | 0;
+     if ((i23 | 0) != (-1 | 0)) {
+      i24 = i23;
+      i22 = HEAP32[13388 >> 2] | 0;
+      i25 = i22 + -1 | 0;
+      if ((i25 & i24 | 0) == 0) {
+       i25 = i18;
+      } else {
+       i25 = i18 - i24 + (i25 + i24 & 0 - i22) | 0;
+      }
+      i24 = HEAP32[13344 >> 2] | 0;
+      i26 = i24 + i25 | 0;
+      if (i25 >>> 0 > i12 >>> 0 & i25 >>> 0 < 2147483647) {
+       i22 = HEAP32[13352 >> 2] | 0;
+       if ((i22 | 0) != 0 ? i26 >>> 0 <= i24 >>> 0 | i26 >>> 0 > i22 >>> 0 : 0) {
+        i25 = 0;
+        break;
+       }
+       i22 = _sbrk(i25 | 0) | 0;
+       i13 = (i22 | 0) == (i23 | 0);
+       i24 = i25;
+       i23 = i13 ? i23 : -1;
+       i25 = i13 ? i25 : 0;
+       i13 = 191;
+      } else {
+       i25 = 0;
+      }
+     } else {
+      i25 = 0;
+     }
+    }
+   } while (0);
+   L291 : do {
+    if ((i13 | 0) == 191) {
+     i13 = 0 - i24 | 0;
+     if ((i23 | 0) != (-1 | 0)) {
+      i17 = i23;
+      i14 = i25;
+      i13 = 202;
+      break L269;
+     }
+     do {
+      if ((i22 | 0) != (-1 | 0) & i24 >>> 0 < 2147483647 & i24 >>> 0 < i20 >>> 0 ? (i19 = HEAP32[13392 >> 2] | 0, i19 = i21 - i24 + i19 & 0 - i19, i19 >>> 0 < 2147483647) : 0) {
+       if ((_sbrk(i19 | 0) | 0) == (-1 | 0)) {
+        _sbrk(i13 | 0) | 0;
+        break L291;
+       } else {
+        i24 = i19 + i24 | 0;
+        break;
+       }
+      }
+     } while (0);
+     if ((i22 | 0) != (-1 | 0)) {
+      i17 = i22;
+      i14 = i24;
+      i13 = 202;
+      break L269;
+     }
+    }
+   } while (0);
+   HEAP32[13356 >> 2] = HEAP32[13356 >> 2] | 4;
+   i13 = 199;
+  } else {
+   i25 = 0;
+   i13 = 199;
+  }
+ } while (0);
+ if ((((i13 | 0) == 199 ? i18 >>> 0 < 2147483647 : 0) ? (i17 = _sbrk(i18 | 0) | 0, i16 = _sbrk(0) | 0, (i16 | 0) != (-1 | 0) & (i17 | 0) != (-1 | 0) & i17 >>> 0 < i16 >>> 0) : 0) ? (i15 = i16 - i17 | 0, i14 = i15 >>> 0 > (i12 + 40 | 0) >>> 0, i14) : 0) {
+  i14 = i14 ? i15 : i25;
+  i13 = 202;
+ }
+ if ((i13 | 0) == 202) {
+  i15 = (HEAP32[13344 >> 2] | 0) + i14 | 0;
+  HEAP32[13344 >> 2] = i15;
+  if (i15 >>> 0 > (HEAP32[13348 >> 2] | 0) >>> 0) {
+   HEAP32[13348 >> 2] = i15;
+  }
+  i15 = HEAP32[12936 >> 2] | 0;
+  L311 : do {
+   if ((i15 | 0) != 0) {
+    i21 = 13360 | 0;
+    while (1) {
+     i16 = HEAP32[i21 >> 2] | 0;
+     i19 = i21 + 4 | 0;
+     i20 = HEAP32[i19 >> 2] | 0;
+     if ((i17 | 0) == (i16 + i20 | 0)) {
+      i13 = 214;
+      break;
+     }
+     i18 = HEAP32[i21 + 8 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      break;
+     } else {
+      i21 = i18;
+     }
+    }
+    if (((i13 | 0) == 214 ? (HEAP32[i21 + 12 >> 2] & 8 | 0) == 0 : 0) ? i15 >>> 0 >= i16 >>> 0 & i15 >>> 0 < i17 >>> 0 : 0) {
+     HEAP32[i19 >> 2] = i20 + i14;
+     i2 = (HEAP32[12924 >> 2] | 0) + i14 | 0;
+     i3 = i15 + 8 | 0;
+     if ((i3 & 7 | 0) == 0) {
+      i3 = 0;
+     } else {
+      i3 = 0 - i3 & 7;
+     }
+     i32 = i2 - i3 | 0;
+     HEAP32[12936 >> 2] = i15 + i3;
+     HEAP32[12924 >> 2] = i32;
+     HEAP32[i15 + (i3 + 4) >> 2] = i32 | 1;
+     HEAP32[i15 + (i2 + 4) >> 2] = 40;
+     HEAP32[12940 >> 2] = HEAP32[13400 >> 2];
+     break;
+    }
+    if (i17 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+     HEAP32[12928 >> 2] = i17;
+    }
+    i19 = i17 + i14 | 0;
+    i16 = 13360 | 0;
+    while (1) {
+     if ((HEAP32[i16 >> 2] | 0) == (i19 | 0)) {
+      i13 = 224;
+      break;
+     }
+     i18 = HEAP32[i16 + 8 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      break;
+     } else {
+      i16 = i18;
+     }
+    }
+    if ((i13 | 0) == 224 ? (HEAP32[i16 + 12 >> 2] & 8 | 0) == 0 : 0) {
+     HEAP32[i16 >> 2] = i17;
+     i6 = i16 + 4 | 0;
+     HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i14;
+     i6 = i17 + 8 | 0;
+     if ((i6 & 7 | 0) == 0) {
+      i6 = 0;
+     } else {
+      i6 = 0 - i6 & 7;
+     }
+     i7 = i17 + (i14 + 8) | 0;
+     if ((i7 & 7 | 0) == 0) {
+      i13 = 0;
+     } else {
+      i13 = 0 - i7 & 7;
+     }
+     i15 = i17 + (i13 + i14) | 0;
+     i8 = i6 + i12 | 0;
+     i7 = i17 + i8 | 0;
+     i10 = i15 - (i17 + i6) - i12 | 0;
+     HEAP32[i17 + (i6 + 4) >> 2] = i12 | 3;
+     L348 : do {
+      if ((i15 | 0) != (HEAP32[12936 >> 2] | 0)) {
+       if ((i15 | 0) == (HEAP32[12932 >> 2] | 0)) {
+        i32 = (HEAP32[12920 >> 2] | 0) + i10 | 0;
+        HEAP32[12920 >> 2] = i32;
+        HEAP32[12932 >> 2] = i7;
+        HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
+        HEAP32[i17 + (i32 + i8) >> 2] = i32;
+        break;
+       }
+       i12 = i14 + 4 | 0;
+       i18 = HEAP32[i17 + (i12 + i13) >> 2] | 0;
+       if ((i18 & 3 | 0) == 1) {
+        i11 = i18 & -8;
+        i16 = i18 >>> 3;
+        do {
+         if (!(i18 >>> 0 < 256)) {
+          i9 = HEAP32[i17 + ((i13 | 24) + i14) >> 2] | 0;
+          i19 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
+          do {
+           if ((i19 | 0) == (i15 | 0)) {
+            i19 = i13 | 16;
+            i18 = i17 + (i12 + i19) | 0;
+            i16 = HEAP32[i18 >> 2] | 0;
+            if ((i16 | 0) == 0) {
+             i18 = i17 + (i19 + i14) | 0;
+             i16 = HEAP32[i18 >> 2] | 0;
+             if ((i16 | 0) == 0) {
+              i5 = 0;
+              break;
+             }
+            }
+            while (1) {
+             i20 = i16 + 20 | 0;
+             i19 = HEAP32[i20 >> 2] | 0;
+             if ((i19 | 0) != 0) {
+              i16 = i19;
+              i18 = i20;
+              continue;
+             }
+             i19 = i16 + 16 | 0;
+             i20 = HEAP32[i19 >> 2] | 0;
+             if ((i20 | 0) == 0) {
+              break;
+             } else {
+              i16 = i20;
+              i18 = i19;
+             }
+            }
+            if (i18 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+             _abort();
+            } else {
+             HEAP32[i18 >> 2] = 0;
+             i5 = i16;
+             break;
+            }
+           } else {
+            i18 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
+            if (i18 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+             _abort();
+            }
+            i16 = i18 + 12 | 0;
+            if ((HEAP32[i16 >> 2] | 0) != (i15 | 0)) {
+             _abort();
+            }
+            i20 = i19 + 8 | 0;
+            if ((HEAP32[i20 >> 2] | 0) == (i15 | 0)) {
+             HEAP32[i16 >> 2] = i19;
+             HEAP32[i20 >> 2] = i18;
+             i5 = i19;
+             break;
+            } else {
+             _abort();
+            }
+           }
+          } while (0);
+          if ((i9 | 0) != 0) {
+           i16 = HEAP32[i17 + (i14 + 28 + i13) >> 2] | 0;
+           i18 = 13216 + (i16 << 2) | 0;
+           if ((i15 | 0) == (HEAP32[i18 >> 2] | 0)) {
+            HEAP32[i18 >> 2] = i5;
+            if ((i5 | 0) == 0) {
+             HEAP32[12916 >> 2] = HEAP32[12916 >> 2] & ~(1 << i16);
+             break;
+            }
+           } else {
+            if (i9 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+             _abort();
+            }
+            i16 = i9 + 16 | 0;
+            if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
+             HEAP32[i16 >> 2] = i5;
+            } else {
+             HEAP32[i9 + 20 >> 2] = i5;
+            }
+            if ((i5 | 0) == 0) {
+             break;
+            }
+           }
+           if (i5 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           HEAP32[i5 + 24 >> 2] = i9;
+           i15 = i13 | 16;
+           i9 = HEAP32[i17 + (i15 + i14) >> 2] | 0;
+           do {
+            if ((i9 | 0) != 0) {
+             if (i9 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+              _abort();
+             } else {
+              HEAP32[i5 + 16 >> 2] = i9;
+              HEAP32[i9 + 24 >> 2] = i5;
+              break;
+             }
+            }
+           } while (0);
+           i9 = HEAP32[i17 + (i12 + i15) >> 2] | 0;
+           if ((i9 | 0) != 0) {
+            if (i9 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+             _abort();
+            } else {
+             HEAP32[i5 + 20 >> 2] = i9;
+             HEAP32[i9 + 24 >> 2] = i5;
+             break;
+            }
+           }
+          }
+         } else {
+          i5 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
+          i12 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
+          i18 = 12952 + (i16 << 1 << 2) | 0;
+          if ((i5 | 0) != (i18 | 0)) {
+           if (i5 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           if ((HEAP32[i5 + 12 >> 2] | 0) != (i15 | 0)) {
+            _abort();
+           }
+          }
+          if ((i12 | 0) == (i5 | 0)) {
+           HEAP32[3228] = HEAP32[3228] & ~(1 << i16);
+           break;
+          }
+          if ((i12 | 0) != (i18 | 0)) {
+           if (i12 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           i16 = i12 + 8 | 0;
+           if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
+            i9 = i16;
+           } else {
+            _abort();
+           }
+          } else {
+           i9 = i12 + 8 | 0;
+          }
+          HEAP32[i5 + 12 >> 2] = i12;
+          HEAP32[i9 >> 2] = i5;
+         }
+        } while (0);
+        i15 = i17 + ((i11 | i13) + i14) | 0;
+        i10 = i11 + i10 | 0;
+       }
+       i5 = i15 + 4 | 0;
+       HEAP32[i5 >> 2] = HEAP32[i5 >> 2] & -2;
+       HEAP32[i17 + (i8 + 4) >> 2] = i10 | 1;
+       HEAP32[i17 + (i10 + i8) >> 2] = i10;
+       i5 = i10 >>> 3;
+       if (i10 >>> 0 < 256) {
+        i10 = i5 << 1;
+        i2 = 12952 + (i10 << 2) | 0;
+        i9 = HEAP32[3228] | 0;
+        i5 = 1 << i5;
+        if ((i9 & i5 | 0) != 0) {
+         i9 = 12952 + (i10 + 2 << 2) | 0;
+         i5 = HEAP32[i9 >> 2] | 0;
+         if (i5 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          i3 = i9;
+          i4 = i5;
+         }
+        } else {
+         HEAP32[3228] = i9 | i5;
+         i3 = 12952 + (i10 + 2 << 2) | 0;
+         i4 = i2;
+        }
+        HEAP32[i3 >> 2] = i7;
+        HEAP32[i4 + 12 >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i4;
+        HEAP32[i17 + (i8 + 12) >> 2] = i2;
+        break;
+       }
+       i3 = i10 >>> 8;
+       if ((i3 | 0) != 0) {
+        if (i10 >>> 0 > 16777215) {
+         i3 = 31;
+        } else {
+         i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+         i32 = i3 << i31;
+         i30 = (i32 + 520192 | 0) >>> 16 & 4;
+         i32 = i32 << i30;
+         i3 = (i32 + 245760 | 0) >>> 16 & 2;
+         i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+         i3 = i10 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+        }
+       } else {
+        i3 = 0;
+       }
+       i4 = 13216 + (i3 << 2) | 0;
+       HEAP32[i17 + (i8 + 28) >> 2] = i3;
+       HEAP32[i17 + (i8 + 20) >> 2] = 0;
+       HEAP32[i17 + (i8 + 16) >> 2] = 0;
+       i9 = HEAP32[12916 >> 2] | 0;
+       i5 = 1 << i3;
+       if ((i9 & i5 | 0) == 0) {
+        HEAP32[12916 >> 2] = i9 | i5;
+        HEAP32[i4 >> 2] = i7;
+        HEAP32[i17 + (i8 + 24) >> 2] = i4;
+        HEAP32[i17 + (i8 + 12) >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i7;
+        break;
+       }
+       i4 = HEAP32[i4 >> 2] | 0;
+       if ((i3 | 0) == 31) {
+        i3 = 0;
+       } else {
+        i3 = 25 - (i3 >>> 1) | 0;
+       }
+       L445 : do {
+        if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i10 | 0)) {
+         i3 = i10 << i3;
+         while (1) {
+          i5 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+          i9 = HEAP32[i5 >> 2] | 0;
+          if ((i9 | 0) == 0) {
+           break;
+          }
+          if ((HEAP32[i9 + 4 >> 2] & -8 | 0) == (i10 | 0)) {
+           i2 = i9;
+           break L445;
+          } else {
+           i3 = i3 << 1;
+           i4 = i9;
+          }
+         }
+         if (i5 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i5 >> 2] = i7;
+          HEAP32[i17 + (i8 + 24) >> 2] = i4;
+          HEAP32[i17 + (i8 + 12) >> 2] = i7;
+          HEAP32[i17 + (i8 + 8) >> 2] = i7;
+          break L348;
+         }
+        } else {
+         i2 = i4;
+        }
+       } while (0);
+       i4 = i2 + 8 | 0;
+       i3 = HEAP32[i4 >> 2] | 0;
+       i5 = HEAP32[12928 >> 2] | 0;
+       if (i2 >>> 0 < i5 >>> 0) {
+        _abort();
+       }
+       if (i3 >>> 0 < i5 >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i3 + 12 >> 2] = i7;
+        HEAP32[i4 >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i3;
+        HEAP32[i17 + (i8 + 12) >> 2] = i2;
+        HEAP32[i17 + (i8 + 24) >> 2] = 0;
+        break;
+       }
+      } else {
+       i32 = (HEAP32[12924 >> 2] | 0) + i10 | 0;
+       HEAP32[12924 >> 2] = i32;
+       HEAP32[12936 >> 2] = i7;
+       HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
+      }
+     } while (0);
+     i32 = i17 + (i6 | 8) | 0;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+    i3 = 13360 | 0;
+    while (1) {
+     i2 = HEAP32[i3 >> 2] | 0;
+     if (!(i2 >>> 0 > i15 >>> 0) ? (i11 = HEAP32[i3 + 4 >> 2] | 0, i10 = i2 + i11 | 0, i10 >>> 0 > i15 >>> 0) : 0) {
+      break;
+     }
+     i3 = HEAP32[i3 + 8 >> 2] | 0;
+    }
+    i3 = i2 + (i11 + -39) | 0;
+    if ((i3 & 7 | 0) == 0) {
+     i3 = 0;
+    } else {
+     i3 = 0 - i3 & 7;
+    }
+    i2 = i2 + (i11 + -47 + i3) | 0;
+    i2 = i2 >>> 0 < (i15 + 16 | 0) >>> 0 ? i15 : i2;
+    i3 = i2 + 8 | 0;
+    i4 = i17 + 8 | 0;
+    if ((i4 & 7 | 0) == 0) {
+     i4 = 0;
+    } else {
+     i4 = 0 - i4 & 7;
+    }
+    i32 = i14 + -40 - i4 | 0;
+    HEAP32[12936 >> 2] = i17 + i4;
+    HEAP32[12924 >> 2] = i32;
+    HEAP32[i17 + (i4 + 4) >> 2] = i32 | 1;
+    HEAP32[i17 + (i14 + -36) >> 2] = 40;
+    HEAP32[12940 >> 2] = HEAP32[13400 >> 2];
+    HEAP32[i2 + 4 >> 2] = 27;
+    HEAP32[i3 + 0 >> 2] = HEAP32[13360 >> 2];
+    HEAP32[i3 + 4 >> 2] = HEAP32[13364 >> 2];
+    HEAP32[i3 + 8 >> 2] = HEAP32[13368 >> 2];
+    HEAP32[i3 + 12 >> 2] = HEAP32[13372 >> 2];
+    HEAP32[13360 >> 2] = i17;
+    HEAP32[13364 >> 2] = i14;
+    HEAP32[13372 >> 2] = 0;
+    HEAP32[13368 >> 2] = i3;
+    i4 = i2 + 28 | 0;
+    HEAP32[i4 >> 2] = 7;
+    if ((i2 + 32 | 0) >>> 0 < i10 >>> 0) {
+     while (1) {
+      i3 = i4 + 4 | 0;
+      HEAP32[i3 >> 2] = 7;
+      if ((i4 + 8 | 0) >>> 0 < i10 >>> 0) {
+       i4 = i3;
+      } else {
+       break;
+      }
+     }
+    }
+    if ((i2 | 0) != (i15 | 0)) {
+     i2 = i2 - i15 | 0;
+     i3 = i15 + (i2 + 4) | 0;
+     HEAP32[i3 >> 2] = HEAP32[i3 >> 2] & -2;
+     HEAP32[i15 + 4 >> 2] = i2 | 1;
+     HEAP32[i15 + i2 >> 2] = i2;
+     i3 = i2 >>> 3;
+     if (i2 >>> 0 < 256) {
+      i4 = i3 << 1;
+      i2 = 12952 + (i4 << 2) | 0;
+      i5 = HEAP32[3228] | 0;
+      i3 = 1 << i3;
+      if ((i5 & i3 | 0) != 0) {
+       i4 = 12952 + (i4 + 2 << 2) | 0;
+       i3 = HEAP32[i4 >> 2] | 0;
+       if (i3 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        i7 = i4;
+        i8 = i3;
+       }
+      } else {
+       HEAP32[3228] = i5 | i3;
+       i7 = 12952 + (i4 + 2 << 2) | 0;
+       i8 = i2;
+      }
+      HEAP32[i7 >> 2] = i15;
+      HEAP32[i8 + 12 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i8;
+      HEAP32[i15 + 12 >> 2] = i2;
+      break;
+     }
+     i3 = i2 >>> 8;
+     if ((i3 | 0) != 0) {
+      if (i2 >>> 0 > 16777215) {
+       i3 = 31;
+      } else {
+       i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+       i32 = i3 << i31;
+       i30 = (i32 + 520192 | 0) >>> 16 & 4;
+       i32 = i32 << i30;
+       i3 = (i32 + 245760 | 0) >>> 16 & 2;
+       i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+       i3 = i2 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+      }
+     } else {
+      i3 = 0;
+     }
+     i7 = 13216 + (i3 << 2) | 0;
+     HEAP32[i15 + 28 >> 2] = i3;
+     HEAP32[i15 + 20 >> 2] = 0;
+     HEAP32[i15 + 16 >> 2] = 0;
+     i4 = HEAP32[12916 >> 2] | 0;
+     i5 = 1 << i3;
+     if ((i4 & i5 | 0) == 0) {
+      HEAP32[12916 >> 2] = i4 | i5;
+      HEAP32[i7 >> 2] = i15;
+      HEAP32[i15 + 24 >> 2] = i7;
+      HEAP32[i15 + 12 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i15;
+      break;
+     }
+     i4 = HEAP32[i7 >> 2] | 0;
+     if ((i3 | 0) == 31) {
+      i3 = 0;
+     } else {
+      i3 = 25 - (i3 >>> 1) | 0;
+     }
+     L499 : do {
+      if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i2 | 0)) {
+       i3 = i2 << i3;
+       while (1) {
+        i7 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+        i5 = HEAP32[i7 >> 2] | 0;
+        if ((i5 | 0) == 0) {
+         break;
+        }
+        if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i2 | 0)) {
+         i6 = i5;
+         break L499;
+        } else {
+         i3 = i3 << 1;
+         i4 = i5;
+        }
+       }
+       if (i7 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i7 >> 2] = i15;
+        HEAP32[i15 + 24 >> 2] = i4;
+        HEAP32[i15 + 12 >> 2] = i15;
+        HEAP32[i15 + 8 >> 2] = i15;
+        break L311;
+       }
+      } else {
+       i6 = i4;
+      }
+     } while (0);
+     i4 = i6 + 8 | 0;
+     i3 = HEAP32[i4 >> 2] | 0;
+     i2 = HEAP32[12928 >> 2] | 0;
+     if (i6 >>> 0 < i2 >>> 0) {
+      _abort();
+     }
+     if (i3 >>> 0 < i2 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i3 + 12 >> 2] = i15;
+      HEAP32[i4 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i3;
+      HEAP32[i15 + 12 >> 2] = i6;
+      HEAP32[i15 + 24 >> 2] = 0;
+      break;
+     }
+    }
+   } else {
+    i32 = HEAP32[12928 >> 2] | 0;
+    if ((i32 | 0) == 0 | i17 >>> 0 < i32 >>> 0) {
+     HEAP32[12928 >> 2] = i17;
+    }
+    HEAP32[13360 >> 2] = i17;
+    HEAP32[13364 >> 2] = i14;
+    HEAP32[13372 >> 2] = 0;
+    HEAP32[12948 >> 2] = HEAP32[3346];
+    HEAP32[12944 >> 2] = -1;
+    i2 = 0;
+    do {
+     i32 = i2 << 1;
+     i31 = 12952 + (i32 << 2) | 0;
+     HEAP32[12952 + (i32 + 3 << 2) >> 2] = i31;
+     HEAP32[12952 + (i32 + 2 << 2) >> 2] = i31;
+     i2 = i2 + 1 | 0;
+    } while ((i2 | 0) != 32);
+    i2 = i17 + 8 | 0;
+    if ((i2 & 7 | 0) == 0) {
+     i2 = 0;
+    } else {
+     i2 = 0 - i2 & 7;
+    }
+    i32 = i14 + -40 - i2 | 0;
+    HEAP32[12936 >> 2] = i17 + i2;
+    HEAP32[12924 >> 2] = i32;
+    HEAP32[i17 + (i2 + 4) >> 2] = i32 | 1;
+    HEAP32[i17 + (i14 + -36) >> 2] = 40;
+    HEAP32[12940 >> 2] = HEAP32[13400 >> 2];
+   }
+  } while (0);
+  i2 = HEAP32[12924 >> 2] | 0;
+  if (i2 >>> 0 > i12 >>> 0) {
+   i31 = i2 - i12 | 0;
+   HEAP32[12924 >> 2] = i31;
+   i32 = HEAP32[12936 >> 2] | 0;
+   HEAP32[12936 >> 2] = i32 + i12;
+   HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
+   HEAP32[i32 + 4 >> 2] = i12 | 3;
+   i32 = i32 + 8 | 0;
+   STACKTOP = i1;
+   return i32 | 0;
+  }
+ }
+ HEAP32[(___errno_location() | 0) >> 2] = 12;
+ i32 = 0;
+ STACKTOP = i1;
+ return i32 | 0;
+}
+function _llex(i2, i3) {
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i12 = i1;
+ i4 = i2 + 60 | 0;
+ HEAP32[(HEAP32[i4 >> 2] | 0) + 4 >> 2] = 0;
+ i5 = i2 + 56 | 0;
+ L1 : while (1) {
+  i13 = HEAP32[i2 >> 2] | 0;
+  L3 : while (1) {
+   switch (i13 | 0) {
+   case 11:
+   case 9:
+   case 12:
+   case 32:
+    {
+     break;
+    }
+   case 91:
+    {
+     i9 = 25;
+     break L1;
+    }
+   case 62:
+    {
+     i9 = 45;
+     break L1;
+    }
+   case 46:
+    {
+     i9 = 161;
+     break L1;
+    }
+   case 13:
+   case 10:
+    {
+     i9 = 4;
+     break L3;
+    }
+   case 45:
+    {
+     break L3;
+    }
+   case 61:
+    {
+     i9 = 29;
+     break L1;
+    }
+   case 39:
+   case 34:
+    {
+     i9 = 69;
+     break L1;
+    }
+   case 126:
+    {
+     i9 = 53;
+     break L1;
+    }
+   case 60:
+    {
+     i9 = 37;
+     break L1;
+    }
+   case 58:
+    {
+     i9 = 61;
+     break L1;
+    }
+   case 57:
+   case 56:
+   case 55:
+   case 54:
+   case 53:
+   case 52:
+   case 51:
+   case 50:
+   case 49:
+   case 48:
+    {
+     i20 = i13;
+     break L1;
+    }
+   case -1:
+    {
+     i2 = 286;
+     i9 = 306;
+     break L1;
+    }
+   default:
+    {
+     i9 = 283;
+     break L1;
+    }
+   }
+   i13 = HEAP32[i5 >> 2] | 0;
+   i27 = HEAP32[i13 >> 2] | 0;
+   HEAP32[i13 >> 2] = i27 + -1;
+   if ((i27 | 0) == 0) {
+    i13 = _luaZ_fill(i13) | 0;
+   } else {
+    i27 = i13 + 4 | 0;
+    i13 = HEAP32[i27 >> 2] | 0;
+    HEAP32[i27 >> 2] = i13 + 1;
+    i13 = HEAPU8[i13] | 0;
+   }
+   HEAP32[i2 >> 2] = i13;
+  }
+  if ((i9 | 0) == 4) {
+   i9 = 0;
+   _inclinenumber(i2);
+   continue;
+  }
+  i13 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i13 >> 2] | 0;
+  HEAP32[i13 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i13 = _luaZ_fill(i13) | 0;
+  } else {
+   i27 = i13 + 4 | 0;
+   i13 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i13 + 1;
+   i13 = HEAPU8[i13] | 0;
+  }
+  HEAP32[i2 >> 2] = i13;
+  if ((i13 | 0) != 45) {
+   i2 = 45;
+   i9 = 306;
+   break;
+  }
+  i13 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i13 >> 2] | 0;
+  HEAP32[i13 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i13 = _luaZ_fill(i13) | 0;
+  } else {
+   i27 = i13 + 4 | 0;
+   i13 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i13 + 1;
+   i13 = HEAPU8[i13] | 0;
+  }
+  HEAP32[i2 >> 2] = i13;
+  do {
+   if ((i13 | 0) == 91) {
+    i13 = _skip_sep(i2) | 0;
+    HEAP32[(HEAP32[i4 >> 2] | 0) + 4 >> 2] = 0;
+    if ((i13 | 0) > -1) {
+     _read_long_string(i2, 0, i13);
+     HEAP32[(HEAP32[i4 >> 2] | 0) + 4 >> 2] = 0;
+     continue L1;
+    } else {
+     i13 = HEAP32[i2 >> 2] | 0;
+     break;
+    }
+   }
+  } while (0);
+  while (1) {
+   if ((i13 | 0) == -1 | (i13 | 0) == 13 | (i13 | 0) == 10) {
+    continue L1;
+   }
+   i13 = HEAP32[i5 >> 2] | 0;
+   i27 = HEAP32[i13 >> 2] | 0;
+   HEAP32[i13 >> 2] = i27 + -1;
+   if ((i27 | 0) == 0) {
+    i13 = _luaZ_fill(i13) | 0;
+   } else {
+    i27 = i13 + 4 | 0;
+    i13 = HEAP32[i27 >> 2] | 0;
+    HEAP32[i27 >> 2] = i13 + 1;
+    i13 = HEAPU8[i13] | 0;
+   }
+   HEAP32[i2 >> 2] = i13;
+  }
+ }
+ if ((i9 | 0) == 25) {
+  i9 = _skip_sep(i2) | 0;
+  if ((i9 | 0) > -1) {
+   _read_long_string(i2, i3, i9);
+   i27 = 289;
+   STACKTOP = i1;
+   return i27 | 0;
+  }
+  if ((i9 | 0) == -1) {
+   i27 = 91;
+   STACKTOP = i1;
+   return i27 | 0;
+  } else {
+   _lexerror(i2, 12272, 289);
+  }
+ } else if ((i9 | 0) == 29) {
+  i3 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i3 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i3 = _luaZ_fill(i3) | 0;
+  } else {
+   i27 = i3 + 4 | 0;
+   i3 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i3 + 1;
+   i3 = HEAPU8[i3] | 0;
+  }
+  HEAP32[i2 >> 2] = i3;
+  if ((i3 | 0) != 61) {
+   i27 = 61;
+   STACKTOP = i1;
+   return i27 | 0;
+  }
+  i3 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i3 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i3 = _luaZ_fill(i3) | 0;
+  } else {
+   i27 = i3 + 4 | 0;
+   i3 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i3 + 1;
+   i3 = HEAPU8[i3] | 0;
+  }
+  HEAP32[i2 >> 2] = i3;
+  i27 = 281;
+  STACKTOP = i1;
+  return i27 | 0;
+ } else if ((i9 | 0) == 37) {
+  i3 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i3 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i3 = _luaZ_fill(i3) | 0;
+  } else {
+   i27 = i3 + 4 | 0;
+   i3 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i3 + 1;
+   i3 = HEAPU8[i3] | 0;
+  }
+  HEAP32[i2 >> 2] = i3;
+  if ((i3 | 0) != 61) {
+   i27 = 60;
+   STACKTOP = i1;
+   return i27 | 0;
+  }
+  i3 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i3 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i3 = _luaZ_fill(i3) | 0;
+  } else {
+   i27 = i3 + 4 | 0;
+   i3 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i3 + 1;
+   i3 = HEAPU8[i3] | 0;
+  }
+  HEAP32[i2 >> 2] = i3;
+  i27 = 283;
+  STACKTOP = i1;
+  return i27 | 0;
+ } else if ((i9 | 0) == 45) {
+  i3 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i3 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i3 = _luaZ_fill(i3) | 0;
+  } else {
+   i27 = i3 + 4 | 0;
+   i3 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i3 + 1;
+   i3 = HEAPU8[i3] | 0;
+  }
+  HEAP32[i2 >> 2] = i3;
+  if ((i3 | 0) != 61) {
+   i27 = 62;
+   STACKTOP = i1;
+   return i27 | 0;
+  }
+  i3 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i3 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i3 = _luaZ_fill(i3) | 0;
+  } else {
+   i27 = i3 + 4 | 0;
+   i3 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i3 + 1;
+   i3 = HEAPU8[i3] | 0;
+  }
+  HEAP32[i2 >> 2] = i3;
+  i27 = 282;
+  STACKTOP = i1;
+  return i27 | 0;
+ } else if ((i9 | 0) == 53) {
+  i3 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i3 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i3 = _luaZ_fill(i3) | 0;
+  } else {
+   i27 = i3 + 4 | 0;
+   i3 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i3 + 1;
+   i3 = HEAPU8[i3] | 0;
+  }
+  HEAP32[i2 >> 2] = i3;
+  if ((i3 | 0) != 61) {
+   i27 = 126;
+   STACKTOP = i1;
+   return i27 | 0;
+  }
+  i3 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i3 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i3 = _luaZ_fill(i3) | 0;
+  } else {
+   i27 = i3 + 4 | 0;
+   i3 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i3 + 1;
+   i3 = HEAPU8[i3] | 0;
+  }
+  HEAP32[i2 >> 2] = i3;
+  i27 = 284;
+  STACKTOP = i1;
+  return i27 | 0;
+ } else if ((i9 | 0) == 61) {
+  i3 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i3 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i3 = _luaZ_fill(i3) | 0;
+  } else {
+   i27 = i3 + 4 | 0;
+   i3 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i3 + 1;
+   i3 = HEAPU8[i3] | 0;
+  }
+  HEAP32[i2 >> 2] = i3;
+  if ((i3 | 0) != 58) {
+   i27 = 58;
+   STACKTOP = i1;
+   return i27 | 0;
+  }
+  i3 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i3 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i3 = _luaZ_fill(i3) | 0;
+  } else {
+   i27 = i3 + 4 | 0;
+   i3 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i3 + 1;
+   i3 = HEAPU8[i3] | 0;
+  }
+  HEAP32[i2 >> 2] = i3;
+  i27 = 285;
+  STACKTOP = i1;
+  return i27 | 0;
+ } else if ((i9 | 0) == 69) {
+  i14 = HEAP32[i4 >> 2] | 0;
+  i7 = i14 + 4 | 0;
+  i15 = HEAP32[i7 >> 2] | 0;
+  i8 = i14 + 8 | 0;
+  i6 = HEAP32[i8 >> 2] | 0;
+  do {
+   if ((i15 + 1 | 0) >>> 0 > i6 >>> 0) {
+    if (i6 >>> 0 > 2147483645) {
+     _lexerror(i2, 12368, 0);
+    }
+    i16 = i6 << 1;
+    i15 = HEAP32[i2 + 52 >> 2] | 0;
+    if ((i16 | 0) == -2) {
+     _luaM_toobig(i15);
+    } else {
+     i24 = _luaM_realloc_(i15, HEAP32[i14 >> 2] | 0, i6, i16) | 0;
+     HEAP32[i14 >> 2] = i24;
+     HEAP32[i8 >> 2] = i16;
+     i23 = HEAP32[i7 >> 2] | 0;
+     break;
+    }
+   } else {
+    i23 = i15;
+    i24 = HEAP32[i14 >> 2] | 0;
+   }
+  } while (0);
+  i6 = i13 & 255;
+  HEAP32[i7 >> 2] = i23 + 1;
+  HEAP8[i24 + i23 | 0] = i6;
+  i7 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i7 >> 2] | 0;
+  HEAP32[i7 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i14 = _luaZ_fill(i7) | 0;
+  } else {
+   i27 = i7 + 4 | 0;
+   i14 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i14 + 1;
+   i14 = HEAPU8[i14] | 0;
+  }
+  HEAP32[i2 >> 2] = i14;
+  L139 : do {
+   if ((i14 | 0) != (i13 | 0)) {
+    i7 = i2 + 52 | 0;
+    L141 : while (1) {
+     L143 : do {
+      if ((i14 | 0) == 92) {
+       i8 = HEAP32[i5 >> 2] | 0;
+       i27 = HEAP32[i8 >> 2] | 0;
+       HEAP32[i8 >> 2] = i27 + -1;
+       if ((i27 | 0) == 0) {
+        i8 = _luaZ_fill(i8) | 0;
+       } else {
+        i27 = i8 + 4 | 0;
+        i8 = HEAP32[i27 >> 2] | 0;
+        HEAP32[i27 >> 2] = i8 + 1;
+        i8 = HEAPU8[i8] | 0;
+       }
+       HEAP32[i2 >> 2] = i8;
+       switch (i8 | 0) {
+       case 13:
+       case 10:
+        {
+         _inclinenumber(i2);
+         i8 = 10;
+         break;
+        }
+       case 39:
+       case 34:
+       case 92:
+        {
+         i9 = 124;
+         break;
+        }
+       case 122:
+        {
+         i8 = HEAP32[i5 >> 2] | 0;
+         i27 = HEAP32[i8 >> 2] | 0;
+         HEAP32[i8 >> 2] = i27 + -1;
+         if ((i27 | 0) == 0) {
+          i14 = _luaZ_fill(i8) | 0;
+         } else {
+          i27 = i8 + 4 | 0;
+          i14 = HEAP32[i27 >> 2] | 0;
+          HEAP32[i27 >> 2] = i14 + 1;
+          i14 = HEAPU8[i14] | 0;
+         }
+         HEAP32[i2 >> 2] = i14;
+         if ((HEAP8[i14 + 10913 | 0] & 8) == 0) {
+          break L143;
+         }
+         while (1) {
+          if ((i14 | 0) == 13 | (i14 | 0) == 10) {
+           _inclinenumber(i2);
+           i14 = HEAP32[i2 >> 2] | 0;
+          } else {
+           i8 = HEAP32[i5 >> 2] | 0;
+           i27 = HEAP32[i8 >> 2] | 0;
+           HEAP32[i8 >> 2] = i27 + -1;
+           if ((i27 | 0) == 0) {
+            i14 = _luaZ_fill(i8) | 0;
+           } else {
+            i27 = i8 + 4 | 0;
+            i14 = HEAP32[i27 >> 2] | 0;
+            HEAP32[i27 >> 2] = i14 + 1;
+            i14 = HEAPU8[i14] | 0;
+           }
+           HEAP32[i2 >> 2] = i14;
+          }
+          if ((HEAP8[i14 + 10913 | 0] & 8) == 0) {
+           break L143;
+          }
+         }
+        }
+       case 118:
+        {
+         i8 = 11;
+         i9 = 124;
+         break;
+        }
+       case 120:
+        {
+         HEAP32[i12 >> 2] = 120;
+         i14 = 1;
+         i8 = 0;
+         while (1) {
+          i9 = HEAP32[i5 >> 2] | 0;
+          i27 = HEAP32[i9 >> 2] | 0;
+          HEAP32[i9 >> 2] = i27 + -1;
+          if ((i27 | 0) == 0) {
+           i9 = _luaZ_fill(i9) | 0;
+          } else {
+           i27 = i9 + 4 | 0;
+           i9 = HEAP32[i27 >> 2] | 0;
+           HEAP32[i27 >> 2] = i9 + 1;
+           i9 = HEAPU8[i9] | 0;
+          }
+          HEAP32[i2 >> 2] = i9;
+          HEAP32[i12 + (i14 << 2) >> 2] = i9;
+          if ((HEAP8[i9 + 10913 | 0] & 16) == 0) {
+           i9 = 100;
+           break L141;
+          }
+          i8 = (_luaO_hexavalue(i9) | 0) + (i8 << 4) | 0;
+          i14 = i14 + 1 | 0;
+          if ((i14 | 0) >= 3) {
+           i9 = 124;
+           break;
+          }
+         }
+         break;
+        }
+       case -1:
+        {
+         i14 = -1;
+         break L143;
+        }
+       case 98:
+        {
+         i8 = 8;
+         i9 = 124;
+         break;
+        }
+       case 102:
+        {
+         i8 = 12;
+         i9 = 124;
+         break;
+        }
+       case 110:
+        {
+         i8 = 10;
+         i9 = 124;
+         break;
+        }
+       case 114:
+        {
+         i8 = 13;
+         i9 = 124;
+         break;
+        }
+       case 116:
+        {
+         i8 = 9;
+         i9 = 124;
+         break;
+        }
+       case 97:
+        {
+         i8 = 7;
+         i9 = 124;
+         break;
+        }
+       default:
+        {
+         if ((HEAP8[i8 + 10913 | 0] & 2) == 0) {
+          i9 = 116;
+          break L141;
+         } else {
+          i15 = i8;
+          i14 = 0;
+          i8 = 0;
+         }
+         do {
+          if ((HEAP8[i15 + 10913 | 0] & 2) == 0) {
+           break;
+          }
+          HEAP32[i12 + (i14 << 2) >> 2] = i15;
+          i8 = i15 + -48 + (i8 * 10 | 0) | 0;
+          i15 = HEAP32[i5 >> 2] | 0;
+          i27 = HEAP32[i15 >> 2] | 0;
+          HEAP32[i15 >> 2] = i27 + -1;
+          if ((i27 | 0) == 0) {
+           i15 = _luaZ_fill(i15) | 0;
+          } else {
+           i27 = i15 + 4 | 0;
+           i15 = HEAP32[i27 >> 2] | 0;
+           HEAP32[i27 >> 2] = i15 + 1;
+           i15 = HEAPU8[i15] | 0;
+          }
+          HEAP32[i2 >> 2] = i15;
+          i14 = i14 + 1 | 0;
+         } while ((i14 | 0) < 3);
+         if ((i8 | 0) > 255) {
+          i9 = 123;
+          break L141;
+         }
+        }
+       }
+       if ((i9 | 0) == 124) {
+        i9 = 0;
+        i14 = HEAP32[i5 >> 2] | 0;
+        i27 = HEAP32[i14 >> 2] | 0;
+        HEAP32[i14 >> 2] = i27 + -1;
+        if ((i27 | 0) == 0) {
+         i14 = _luaZ_fill(i14) | 0;
+        } else {
+         i27 = i14 + 4 | 0;
+         i14 = HEAP32[i27 >> 2] | 0;
+         HEAP32[i27 >> 2] = i14 + 1;
+         i14 = HEAPU8[i14] | 0;
+        }
+        HEAP32[i2 >> 2] = i14;
+       }
+       i15 = HEAP32[i4 >> 2] | 0;
+       i14 = i15 + 4 | 0;
+       i18 = HEAP32[i14 >> 2] | 0;
+       i16 = i15 + 8 | 0;
+       i17 = HEAP32[i16 >> 2] | 0;
+       if ((i18 + 1 | 0) >>> 0 > i17 >>> 0) {
+        if (i17 >>> 0 > 2147483645) {
+         i9 = 131;
+         break L141;
+        }
+        i18 = i17 << 1;
+        i19 = HEAP32[i7 >> 2] | 0;
+        if ((i18 | 0) == -2) {
+         i9 = 133;
+         break L141;
+        }
+        i27 = _luaM_realloc_(i19, HEAP32[i15 >> 2] | 0, i17, i18) | 0;
+        HEAP32[i15 >> 2] = i27;
+        HEAP32[i16 >> 2] = i18;
+        i18 = HEAP32[i14 >> 2] | 0;
+        i15 = i27;
+       } else {
+        i15 = HEAP32[i15 >> 2] | 0;
+       }
+       HEAP32[i14 >> 2] = i18 + 1;
+       HEAP8[i15 + i18 | 0] = i8;
+       i14 = HEAP32[i2 >> 2] | 0;
+      } else if ((i14 | 0) == -1) {
+       i9 = 82;
+       break L141;
+      } else if ((i14 | 0) == 13 | (i14 | 0) == 10) {
+       i9 = 83;
+       break L141;
+      } else {
+       i15 = HEAP32[i4 >> 2] | 0;
+       i8 = i15 + 4 | 0;
+       i18 = HEAP32[i8 >> 2] | 0;
+       i17 = i15 + 8 | 0;
+       i16 = HEAP32[i17 >> 2] | 0;
+       if ((i18 + 1 | 0) >>> 0 > i16 >>> 0) {
+        if (i16 >>> 0 > 2147483645) {
+         i9 = 139;
+         break L141;
+        }
+        i19 = i16 << 1;
+        i18 = HEAP32[i7 >> 2] | 0;
+        if ((i19 | 0) == -2) {
+         i9 = 141;
+         break L141;
+        }
+        i27 = _luaM_realloc_(i18, HEAP32[i15 >> 2] | 0, i16, i19) | 0;
+        HEAP32[i15 >> 2] = i27;
+        HEAP32[i17 >> 2] = i19;
+        i18 = HEAP32[i8 >> 2] | 0;
+        i15 = i27;
+       } else {
+        i15 = HEAP32[i15 >> 2] | 0;
+       }
+       HEAP32[i8 >> 2] = i18 + 1;
+       HEAP8[i15 + i18 | 0] = i14;
+       i8 = HEAP32[i5 >> 2] | 0;
+       i27 = HEAP32[i8 >> 2] | 0;
+       HEAP32[i8 >> 2] = i27 + -1;
+       if ((i27 | 0) == 0) {
+        i14 = _luaZ_fill(i8) | 0;
+       } else {
+        i27 = i8 + 4 | 0;
+        i14 = HEAP32[i27 >> 2] | 0;
+        HEAP32[i27 >> 2] = i14 + 1;
+        i14 = HEAPU8[i14] | 0;
+       }
+       HEAP32[i2 >> 2] = i14;
+      }
+     } while (0);
+     if ((i14 | 0) == (i13 | 0)) {
+      break L139;
+     }
+    }
+    if ((i9 | 0) == 82) {
+     _lexerror(i2, 12400, 286);
+    } else if ((i9 | 0) == 83) {
+     _lexerror(i2, 12400, 289);
+    } else if ((i9 | 0) == 100) {
+     _escerror(i2, i12, i14 + 1 | 0, 12480);
+    } else if ((i9 | 0) == 116) {
+     _escerror(i2, i2, 1, 12424);
+    } else if ((i9 | 0) == 123) {
+     _escerror(i2, i12, i14, 12448);
+    } else if ((i9 | 0) == 131) {
+     _lexerror(i2, 12368, 0);
+    } else if ((i9 | 0) == 133) {
+     _luaM_toobig(i19);
+    } else if ((i9 | 0) == 139) {
+     _lexerror(i2, 12368, 0);
+    } else if ((i9 | 0) == 141) {
+     _luaM_toobig(i18);
+    }
+   }
+  } while (0);
+  i7 = HEAP32[i4 >> 2] | 0;
+  i8 = i7 + 4 | 0;
+  i13 = HEAP32[i8 >> 2] | 0;
+  i12 = i7 + 8 | 0;
+  i9 = HEAP32[i12 >> 2] | 0;
+  do {
+   if ((i13 + 1 | 0) >>> 0 > i9 >>> 0) {
+    if (i9 >>> 0 > 2147483645) {
+     _lexerror(i2, 12368, 0);
+    }
+    i14 = i9 << 1;
+    i13 = HEAP32[i2 + 52 >> 2] | 0;
+    if ((i14 | 0) == -2) {
+     _luaM_toobig(i13);
+    } else {
+     i11 = _luaM_realloc_(i13, HEAP32[i7 >> 2] | 0, i9, i14) | 0;
+     HEAP32[i7 >> 2] = i11;
+     HEAP32[i12 >> 2] = i14;
+     i10 = HEAP32[i8 >> 2] | 0;
+     break;
+    }
+   } else {
+    i10 = i13;
+    i11 = HEAP32[i7 >> 2] | 0;
+   }
+  } while (0);
+  HEAP32[i8 >> 2] = i10 + 1;
+  HEAP8[i11 + i10 | 0] = i6;
+  i5 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i5 >> 2] | 0;
+  HEAP32[i5 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i5 = _luaZ_fill(i5) | 0;
+  } else {
+   i27 = i5 + 4 | 0;
+   i5 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i5 + 1;
+   i5 = HEAPU8[i5] | 0;
+  }
+  HEAP32[i2 >> 2] = i5;
+  i5 = HEAP32[i4 >> 2] | 0;
+  i4 = HEAP32[i2 + 52 >> 2] | 0;
+  i5 = _luaS_newlstr(i4, (HEAP32[i5 >> 2] | 0) + 1 | 0, (HEAP32[i5 + 4 >> 2] | 0) + -2 | 0) | 0;
+  i6 = i4 + 8 | 0;
+  i7 = HEAP32[i6 >> 2] | 0;
+  HEAP32[i6 >> 2] = i7 + 16;
+  HEAP32[i7 >> 2] = i5;
+  HEAP32[i7 + 8 >> 2] = HEAPU8[i5 + 4 | 0] | 64;
+  i7 = _luaH_set(i4, HEAP32[(HEAP32[i2 + 48 >> 2] | 0) + 4 >> 2] | 0, (HEAP32[i6 >> 2] | 0) + -16 | 0) | 0;
+  i2 = i7 + 8 | 0;
+  if ((HEAP32[i2 >> 2] | 0) == 0 ? (HEAP32[i7 >> 2] = 1, HEAP32[i2 >> 2] = 1, (HEAP32[(HEAP32[i4 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) : 0) {
+   _luaC_step(i4);
+  }
+  HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + -16;
+  HEAP32[i3 >> 2] = i5;
+  i27 = 289;
+  STACKTOP = i1;
+  return i27 | 0;
+ } else if ((i9 | 0) == 161) {
+  i10 = HEAP32[i4 >> 2] | 0;
+  i9 = i10 + 4 | 0;
+  i13 = HEAP32[i9 >> 2] | 0;
+  i12 = i10 + 8 | 0;
+  i11 = HEAP32[i12 >> 2] | 0;
+  do {
+   if ((i13 + 1 | 0) >>> 0 > i11 >>> 0) {
+    if (i11 >>> 0 > 2147483645) {
+     _lexerror(i2, 12368, 0);
+    }
+    i13 = i11 << 1;
+    i20 = HEAP32[i2 + 52 >> 2] | 0;
+    if ((i13 | 0) == -2) {
+     _luaM_toobig(i20);
+    } else {
+     i25 = _luaM_realloc_(i20, HEAP32[i10 >> 2] | 0, i11, i13) | 0;
+     HEAP32[i10 >> 2] = i25;
+     HEAP32[i12 >> 2] = i13;
+     i26 = HEAP32[i9 >> 2] | 0;
+     break;
+    }
+   } else {
+    i26 = i13;
+    i25 = HEAP32[i10 >> 2] | 0;
+   }
+  } while (0);
+  HEAP32[i9 >> 2] = i26 + 1;
+  HEAP8[i25 + i26 | 0] = 46;
+  i9 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i9 >> 2] | 0;
+  HEAP32[i9 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i20 = _luaZ_fill(i9) | 0;
+  } else {
+   i27 = i9 + 4 | 0;
+   i20 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i20 + 1;
+   i20 = HEAPU8[i20] | 0;
+  }
+  HEAP32[i2 >> 2] = i20;
+  if ((i20 | 0) != 0 ? (_memchr(12304, i20, 2) | 0) != 0 : 0) {
+   i6 = HEAP32[i4 >> 2] | 0;
+   i3 = i6 + 4 | 0;
+   i9 = HEAP32[i3 >> 2] | 0;
+   i8 = i6 + 8 | 0;
+   i7 = HEAP32[i8 >> 2] | 0;
+   do {
+    if ((i9 + 1 | 0) >>> 0 > i7 >>> 0) {
+     if (i7 >>> 0 > 2147483645) {
+      _lexerror(i2, 12368, 0);
+     }
+     i9 = i7 << 1;
+     i10 = HEAP32[i2 + 52 >> 2] | 0;
+     if ((i9 | 0) == -2) {
+      _luaM_toobig(i10);
+     } else {
+      i21 = _luaM_realloc_(i10, HEAP32[i6 >> 2] | 0, i7, i9) | 0;
+      HEAP32[i6 >> 2] = i21;
+      HEAP32[i8 >> 2] = i9;
+      i22 = HEAP32[i3 >> 2] | 0;
+      break;
+     }
+    } else {
+     i22 = i9;
+     i21 = HEAP32[i6 >> 2] | 0;
+    }
+   } while (0);
+   HEAP32[i3 >> 2] = i22 + 1;
+   HEAP8[i21 + i22 | 0] = i20;
+   i3 = HEAP32[i5 >> 2] | 0;
+   i27 = HEAP32[i3 >> 2] | 0;
+   HEAP32[i3 >> 2] = i27 + -1;
+   if ((i27 | 0) == 0) {
+    i3 = _luaZ_fill(i3) | 0;
+   } else {
+    i27 = i3 + 4 | 0;
+    i3 = HEAP32[i27 >> 2] | 0;
+    HEAP32[i27 >> 2] = i3 + 1;
+    i3 = HEAPU8[i3] | 0;
+   }
+   HEAP32[i2 >> 2] = i3;
+   if ((i3 | 0) == 0) {
+    i27 = 279;
+    STACKTOP = i1;
+    return i27 | 0;
+   }
+   if ((_memchr(12304, i3, 2) | 0) == 0) {
+    i27 = 279;
+    STACKTOP = i1;
+    return i27 | 0;
+   }
+   i6 = HEAP32[i4 >> 2] | 0;
+   i7 = i6 + 4 | 0;
+   i9 = HEAP32[i7 >> 2] | 0;
+   i8 = i6 + 8 | 0;
+   i4 = HEAP32[i8 >> 2] | 0;
+   do {
+    if ((i9 + 1 | 0) >>> 0 > i4 >>> 0) {
+     if (i4 >>> 0 > 2147483645) {
+      _lexerror(i2, 12368, 0);
+     }
+     i10 = i4 << 1;
+     i9 = HEAP32[i2 + 52 >> 2] | 0;
+     if ((i10 | 0) == -2) {
+      _luaM_toobig(i9);
+     } else {
+      i18 = _luaM_realloc_(i9, HEAP32[i6 >> 2] | 0, i4, i10) | 0;
+      HEAP32[i6 >> 2] = i18;
+      HEAP32[i8 >> 2] = i10;
+      i19 = HEAP32[i7 >> 2] | 0;
+      break;
+     }
+    } else {
+     i19 = i9;
+     i18 = HEAP32[i6 >> 2] | 0;
+    }
+   } while (0);
+   HEAP32[i7 >> 2] = i19 + 1;
+   HEAP8[i18 + i19 | 0] = i3;
+   i3 = HEAP32[i5 >> 2] | 0;
+   i27 = HEAP32[i3 >> 2] | 0;
+   HEAP32[i3 >> 2] = i27 + -1;
+   if ((i27 | 0) == 0) {
+    i3 = _luaZ_fill(i3) | 0;
+   } else {
+    i27 = i3 + 4 | 0;
+    i3 = HEAP32[i27 >> 2] | 0;
+    HEAP32[i27 >> 2] = i3 + 1;
+    i3 = HEAPU8[i3] | 0;
+   }
+   HEAP32[i2 >> 2] = i3;
+   i27 = 280;
+   STACKTOP = i1;
+   return i27 | 0;
+  }
+  if ((HEAP8[i20 + 10913 | 0] & 2) == 0) {
+   i27 = 46;
+   STACKTOP = i1;
+   return i27 | 0;
+  }
+ } else if ((i9 | 0) == 283) {
+  if ((HEAP8[i13 + 10913 | 0] & 1) == 0) {
+   i3 = HEAP32[i5 >> 2] | 0;
+   i27 = HEAP32[i3 >> 2] | 0;
+   HEAP32[i3 >> 2] = i27 + -1;
+   if ((i27 | 0) == 0) {
+    i3 = _luaZ_fill(i3) | 0;
+   } else {
+    i27 = i3 + 4 | 0;
+    i3 = HEAP32[i27 >> 2] | 0;
+    HEAP32[i27 >> 2] = i3 + 1;
+    i3 = HEAPU8[i3] | 0;
+   }
+   HEAP32[i2 >> 2] = i3;
+   i27 = i13;
+   STACKTOP = i1;
+   return i27 | 0;
+  }
+  i10 = i2 + 52 | 0;
+  while (1) {
+   i11 = HEAP32[i4 >> 2] | 0;
+   i9 = i11 + 4 | 0;
+   i12 = HEAP32[i9 >> 2] | 0;
+   i19 = i11 + 8 | 0;
+   i18 = HEAP32[i19 >> 2] | 0;
+   if ((i12 + 1 | 0) >>> 0 > i18 >>> 0) {
+    if (i18 >>> 0 > 2147483645) {
+     i9 = 288;
+     break;
+    }
+    i21 = i18 << 1;
+    i12 = HEAP32[i10 >> 2] | 0;
+    if ((i21 | 0) == -2) {
+     i9 = 290;
+     break;
+    }
+    i27 = _luaM_realloc_(i12, HEAP32[i11 >> 2] | 0, i18, i21) | 0;
+    HEAP32[i11 >> 2] = i27;
+    HEAP32[i19 >> 2] = i21;
+    i12 = HEAP32[i9 >> 2] | 0;
+    i11 = i27;
+   } else {
+    i11 = HEAP32[i11 >> 2] | 0;
+   }
+   HEAP32[i9 >> 2] = i12 + 1;
+   HEAP8[i11 + i12 | 0] = i13;
+   i9 = HEAP32[i5 >> 2] | 0;
+   i27 = HEAP32[i9 >> 2] | 0;
+   HEAP32[i9 >> 2] = i27 + -1;
+   if ((i27 | 0) == 0) {
+    i13 = _luaZ_fill(i9) | 0;
+   } else {
+    i27 = i9 + 4 | 0;
+    i13 = HEAP32[i27 >> 2] | 0;
+    HEAP32[i27 >> 2] = i13 + 1;
+    i13 = HEAPU8[i13] | 0;
+   }
+   HEAP32[i2 >> 2] = i13;
+   if ((HEAP8[i13 + 10913 | 0] & 3) == 0) {
+    i9 = 296;
+    break;
+   }
+  }
+  if ((i9 | 0) == 288) {
+   _lexerror(i2, 12368, 0);
+  } else if ((i9 | 0) == 290) {
+   _luaM_toobig(i12);
+  } else if ((i9 | 0) == 296) {
+   i6 = HEAP32[i4 >> 2] | 0;
+   i4 = HEAP32[i10 >> 2] | 0;
+   i6 = _luaS_newlstr(i4, HEAP32[i6 >> 2] | 0, HEAP32[i6 + 4 >> 2] | 0) | 0;
+   i7 = i4 + 8 | 0;
+   i8 = HEAP32[i7 >> 2] | 0;
+   HEAP32[i7 >> 2] = i8 + 16;
+   HEAP32[i8 >> 2] = i6;
+   i5 = i6 + 4 | 0;
+   HEAP32[i8 + 8 >> 2] = HEAPU8[i5] | 64;
+   i8 = _luaH_set(i4, HEAP32[(HEAP32[i2 + 48 >> 2] | 0) + 4 >> 2] | 0, (HEAP32[i7 >> 2] | 0) + -16 | 0) | 0;
+   i2 = i8 + 8 | 0;
+   if ((HEAP32[i2 >> 2] | 0) == 0 ? (HEAP32[i8 >> 2] = 1, HEAP32[i2 >> 2] = 1, (HEAP32[(HEAP32[i4 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) : 0) {
+    _luaC_step(i4);
+   }
+   HEAP32[i7 >> 2] = (HEAP32[i7 >> 2] | 0) + -16;
+   HEAP32[i3 >> 2] = i6;
+   if ((HEAP8[i5] | 0) != 4) {
+    i27 = 288;
+    STACKTOP = i1;
+    return i27 | 0;
+   }
+   i2 = HEAP8[i6 + 6 | 0] | 0;
+   if (i2 << 24 >> 24 == 0) {
+    i27 = 288;
+    STACKTOP = i1;
+    return i27 | 0;
+   }
+   i27 = i2 & 255 | 256;
+   STACKTOP = i1;
+   return i27 | 0;
+  }
+ } else if ((i9 | 0) == 306) {
+  STACKTOP = i1;
+  return i2 | 0;
+ }
+ i9 = HEAP32[i4 >> 2] | 0;
+ i12 = i9 + 4 | 0;
+ i13 = HEAP32[i12 >> 2] | 0;
+ i11 = i9 + 8 | 0;
+ i10 = HEAP32[i11 >> 2] | 0;
+ do {
+  if ((i13 + 1 | 0) >>> 0 > i10 >>> 0) {
+   if (i10 >>> 0 > 2147483645) {
+    _lexerror(i2, 12368, 0);
+   }
+   i18 = i10 << 1;
+   i13 = HEAP32[i2 + 52 >> 2] | 0;
+   if ((i18 | 0) == -2) {
+    _luaM_toobig(i13);
+   } else {
+    i16 = _luaM_realloc_(i13, HEAP32[i9 >> 2] | 0, i10, i18) | 0;
+    HEAP32[i9 >> 2] = i16;
+    HEAP32[i11 >> 2] = i18;
+    i17 = HEAP32[i12 >> 2] | 0;
+    break;
+   }
+  } else {
+   i17 = i13;
+   i16 = HEAP32[i9 >> 2] | 0;
+  }
+ } while (0);
+ HEAP32[i12 >> 2] = i17 + 1;
+ HEAP8[i16 + i17 | 0] = i20;
+ i9 = HEAP32[i5 >> 2] | 0;
+ i27 = HEAP32[i9 >> 2] | 0;
+ HEAP32[i9 >> 2] = i27 + -1;
+ if ((i27 | 0) == 0) {
+  i9 = _luaZ_fill(i9) | 0;
+ } else {
+  i27 = i9 + 4 | 0;
+  i9 = HEAP32[i27 >> 2] | 0;
+  HEAP32[i27 >> 2] = i9 + 1;
+  i9 = HEAPU8[i9] | 0;
+ }
+ HEAP32[i2 >> 2] = i9;
+ if ((i20 | 0) == 48) {
+  if ((i9 | 0) != 0) {
+   if ((_memchr(12320, i9, 3) | 0) == 0) {
+    i15 = i9;
+    i9 = 12312;
+   } else {
+    i10 = HEAP32[i4 >> 2] | 0;
+    i13 = i10 + 4 | 0;
+    i16 = HEAP32[i13 >> 2] | 0;
+    i11 = i10 + 8 | 0;
+    i12 = HEAP32[i11 >> 2] | 0;
+    do {
+     if ((i16 + 1 | 0) >>> 0 > i12 >>> 0) {
+      if (i12 >>> 0 > 2147483645) {
+       _lexerror(i2, 12368, 0);
+      }
+      i17 = i12 << 1;
+      i16 = HEAP32[i2 + 52 >> 2] | 0;
+      if ((i17 | 0) == -2) {
+       _luaM_toobig(i16);
+      } else {
+       i15 = _luaM_realloc_(i16, HEAP32[i10 >> 2] | 0, i12, i17) | 0;
+       HEAP32[i10 >> 2] = i15;
+       HEAP32[i11 >> 2] = i17;
+       i14 = HEAP32[i13 >> 2] | 0;
+       break;
+      }
+     } else {
+      i14 = i16;
+      i15 = HEAP32[i10 >> 2] | 0;
+     }
+    } while (0);
+    HEAP32[i13 >> 2] = i14 + 1;
+    HEAP8[i15 + i14 | 0] = i9;
+    i9 = HEAP32[i5 >> 2] | 0;
+    i27 = HEAP32[i9 >> 2] | 0;
+    HEAP32[i9 >> 2] = i27 + -1;
+    if ((i27 | 0) == 0) {
+     i15 = _luaZ_fill(i9) | 0;
+    } else {
+     i27 = i9 + 4 | 0;
+     i15 = HEAP32[i27 >> 2] | 0;
+     HEAP32[i27 >> 2] = i15 + 1;
+     i15 = HEAPU8[i15] | 0;
+    }
+    HEAP32[i2 >> 2] = i15;
+    i9 = 12328;
+   }
+  } else {
+   i15 = 0;
+   i9 = 12312;
+  }
+ } else {
+  i15 = i9;
+  i9 = 12312;
+ }
+ i10 = i2 + 52 | 0;
+ while (1) {
+  if ((i15 | 0) != 0) {
+   if ((_memchr(i9, i15, 3) | 0) != 0) {
+    i12 = HEAP32[i4 >> 2] | 0;
+    i11 = i12 + 4 | 0;
+    i16 = HEAP32[i11 >> 2] | 0;
+    i14 = i12 + 8 | 0;
+    i13 = HEAP32[i14 >> 2] | 0;
+    if ((i16 + 1 | 0) >>> 0 > i13 >>> 0) {
+     if (i13 >>> 0 > 2147483645) {
+      i9 = 227;
+      break;
+     }
+     i17 = i13 << 1;
+     i16 = HEAP32[i10 >> 2] | 0;
+     if ((i17 | 0) == -2) {
+      i9 = 229;
+      break;
+     }
+     i27 = _luaM_realloc_(i16, HEAP32[i12 >> 2] | 0, i13, i17) | 0;
+     HEAP32[i12 >> 2] = i27;
+     HEAP32[i14 >> 2] = i17;
+     i16 = HEAP32[i11 >> 2] | 0;
+     i12 = i27;
+    } else {
+     i12 = HEAP32[i12 >> 2] | 0;
+    }
+    HEAP32[i11 >> 2] = i16 + 1;
+    HEAP8[i12 + i16 | 0] = i15;
+    i11 = HEAP32[i5 >> 2] | 0;
+    i27 = HEAP32[i11 >> 2] | 0;
+    HEAP32[i11 >> 2] = i27 + -1;
+    if ((i27 | 0) == 0) {
+     i15 = _luaZ_fill(i11) | 0;
+    } else {
+     i27 = i11 + 4 | 0;
+     i15 = HEAP32[i27 >> 2] | 0;
+     HEAP32[i27 >> 2] = i15 + 1;
+     i15 = HEAPU8[i15] | 0;
+    }
+    HEAP32[i2 >> 2] = i15;
+    if ((i15 | 0) != 0) {
+     if ((_memchr(12336, i15, 3) | 0) != 0) {
+      i12 = HEAP32[i4 >> 2] | 0;
+      i11 = i12 + 4 | 0;
+      i16 = HEAP32[i11 >> 2] | 0;
+      i14 = i12 + 8 | 0;
+      i13 = HEAP32[i14 >> 2] | 0;
+      if ((i16 + 1 | 0) >>> 0 > i13 >>> 0) {
+       if (i13 >>> 0 > 2147483645) {
+        i9 = 239;
+        break;
+       }
+       i17 = i13 << 1;
+       i16 = HEAP32[i10 >> 2] | 0;
+       if ((i17 | 0) == -2) {
+        i9 = 241;
+        break;
+       }
+       i27 = _luaM_realloc_(i16, HEAP32[i12 >> 2] | 0, i13, i17) | 0;
+       HEAP32[i12 >> 2] = i27;
+       HEAP32[i14 >> 2] = i17;
+       i16 = HEAP32[i11 >> 2] | 0;
+       i12 = i27;
+      } else {
+       i12 = HEAP32[i12 >> 2] | 0;
+      }
+      HEAP32[i11 >> 2] = i16 + 1;
+      HEAP8[i12 + i16 | 0] = i15;
+      i11 = HEAP32[i5 >> 2] | 0;
+      i27 = HEAP32[i11 >> 2] | 0;
+      HEAP32[i11 >> 2] = i27 + -1;
+      if ((i27 | 0) == 0) {
+       i15 = _luaZ_fill(i11) | 0;
+      } else {
+       i27 = i11 + 4 | 0;
+       i15 = HEAP32[i27 >> 2] | 0;
+       HEAP32[i27 >> 2] = i15 + 1;
+       i15 = HEAPU8[i15] | 0;
+      }
+      HEAP32[i2 >> 2] = i15;
+     }
+    } else {
+     i15 = 0;
+    }
+   }
+  } else {
+   i15 = 0;
+  }
+  i12 = HEAP32[i4 >> 2] | 0;
+  i11 = i12 + 4 | 0;
+  i17 = HEAP32[i11 >> 2] | 0;
+  i14 = i12 + 8 | 0;
+  i13 = HEAP32[i14 >> 2] | 0;
+  i16 = (i17 + 1 | 0) >>> 0 > i13 >>> 0;
+  if (!((HEAP8[i15 + 10913 | 0] & 16) != 0 | (i15 | 0) == 46)) {
+   i9 = 259;
+   break;
+  }
+  if (i16) {
+   if (i13 >>> 0 > 2147483645) {
+    i9 = 251;
+    break;
+   }
+   i17 = i13 << 1;
+   i16 = HEAP32[i10 >> 2] | 0;
+   if ((i17 | 0) == -2) {
+    i9 = 253;
+    break;
+   }
+   i27 = _luaM_realloc_(i16, HEAP32[i12 >> 2] | 0, i13, i17) | 0;
+   HEAP32[i12 >> 2] = i27;
+   HEAP32[i14 >> 2] = i17;
+   i17 = HEAP32[i11 >> 2] | 0;
+   i12 = i27;
+  } else {
+   i12 = HEAP32[i12 >> 2] | 0;
+  }
+  HEAP32[i11 >> 2] = i17 + 1;
+  HEAP8[i12 + i17 | 0] = i15;
+  i11 = HEAP32[i5 >> 2] | 0;
+  i27 = HEAP32[i11 >> 2] | 0;
+  HEAP32[i11 >> 2] = i27 + -1;
+  if ((i27 | 0) == 0) {
+   i15 = _luaZ_fill(i11) | 0;
+  } else {
+   i27 = i11 + 4 | 0;
+   i15 = HEAP32[i27 >> 2] | 0;
+   HEAP32[i27 >> 2] = i15 + 1;
+   i15 = HEAPU8[i15] | 0;
+  }
+  HEAP32[i2 >> 2] = i15;
+ }
+ if ((i9 | 0) == 227) {
+  _lexerror(i2, 12368, 0);
+ } else if ((i9 | 0) == 229) {
+  _luaM_toobig(i16);
+ } else if ((i9 | 0) == 239) {
+  _lexerror(i2, 12368, 0);
+ } else if ((i9 | 0) == 241) {
+  _luaM_toobig(i16);
+ } else if ((i9 | 0) == 251) {
+  _lexerror(i2, 12368, 0);
+ } else if ((i9 | 0) == 253) {
+  _luaM_toobig(i16);
+ } else if ((i9 | 0) == 259) {
+  do {
+   if (i16) {
+    if (i13 >>> 0 > 2147483645) {
+     _lexerror(i2, 12368, 0);
+    }
+    i5 = i13 << 1;
+    i9 = HEAP32[i10 >> 2] | 0;
+    if ((i5 | 0) == -2) {
+     _luaM_toobig(i9);
+    } else {
+     i7 = _luaM_realloc_(i9, HEAP32[i12 >> 2] | 0, i13, i5) | 0;
+     HEAP32[i12 >> 2] = i7;
+     HEAP32[i14 >> 2] = i5;
+     i8 = HEAP32[i11 >> 2] | 0;
+     break;
+    }
+   } else {
+    i8 = i17;
+    i7 = HEAP32[i12 >> 2] | 0;
+   }
+  } while (0);
+  HEAP32[i11 >> 2] = i8 + 1;
+  HEAP8[i7 + i8 | 0] = 0;
+  i5 = i2 + 76 | 0;
+  i7 = HEAP8[i5] | 0;
+  i10 = HEAP32[i4 >> 2] | 0;
+  i8 = HEAP32[i10 >> 2] | 0;
+  i10 = HEAP32[i10 + 4 >> 2] | 0;
+  if ((i10 | 0) == 0) {
+   i7 = -1;
+  } else {
+   do {
+    i10 = i10 + -1 | 0;
+    i9 = i8 + i10 | 0;
+    if ((HEAP8[i9] | 0) == 46) {
+     HEAP8[i9] = i7;
+    }
+   } while ((i10 | 0) != 0);
+   i7 = HEAP32[i4 >> 2] | 0;
+   i8 = HEAP32[i7 >> 2] | 0;
+   i7 = (HEAP32[i7 + 4 >> 2] | 0) + -1 | 0;
+  }
+  if ((_luaO_str2d(i8, i7, i3) | 0) != 0) {
+   i27 = 287;
+   STACKTOP = i1;
+   return i27 | 0;
+  }
+  i9 = HEAP8[i5] | 0;
+  i8 = HEAP8[HEAP32[(_localeconv() | 0) >> 2] | 0] | 0;
+  HEAP8[i5] = i8;
+  i10 = HEAP32[i4 >> 2] | 0;
+  i7 = HEAP32[i10 >> 2] | 0;
+  i10 = HEAP32[i10 + 4 >> 2] | 0;
+  if ((i10 | 0) == 0) {
+   i8 = -1;
+  } else {
+   do {
+    i10 = i10 + -1 | 0;
+    i11 = i7 + i10 | 0;
+    if ((HEAP8[i11] | 0) == i9 << 24 >> 24) {
+     HEAP8[i11] = i8;
+    }
+   } while ((i10 | 0) != 0);
+   i8 = HEAP32[i4 >> 2] | 0;
+   i7 = HEAP32[i8 >> 2] | 0;
+   i8 = (HEAP32[i8 + 4 >> 2] | 0) + -1 | 0;
+  }
+  if ((_luaO_str2d(i7, i8, i3) | 0) != 0) {
+   i27 = 287;
+   STACKTOP = i1;
+   return i27 | 0;
+  }
+  i1 = HEAP8[i5] | 0;
+  i4 = HEAP32[i4 >> 2] | 0;
+  i3 = HEAP32[i4 >> 2] | 0;
+  i4 = HEAP32[i4 + 4 >> 2] | 0;
+  if ((i4 | 0) == 0) {
+   _lexerror(i2, 12344, 287);
+  } else {
+   i6 = i4;
+  }
+  do {
+   i6 = i6 + -1 | 0;
+   i4 = i3 + i6 | 0;
+   if ((HEAP8[i4] | 0) == i1 << 24 >> 24) {
+    HEAP8[i4] = 46;
+   }
+  } while ((i6 | 0) != 0);
+  _lexerror(i2, 12344, 287);
+ }
+ return 0;
+}
+function _luaV_execute(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, i36 = 0, d37 = 0.0, d38 = 0.0, d39 = 0.0;
+ i12 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i13 = i12 + 24 | 0;
+ i10 = i12 + 16 | 0;
+ i9 = i12 + 8 | 0;
+ i8 = i12;
+ i3 = i1 + 16 | 0;
+ i4 = i1 + 40 | 0;
+ i6 = i1 + 12 | 0;
+ i5 = i1 + 8 | 0;
+ i11 = i1 + 24 | 0;
+ i17 = i1 + 48 | 0;
+ i2 = i1 + 20 | 0;
+ i16 = i1 + 6 | 0;
+ i7 = i1 + 44 | 0;
+ i19 = HEAP32[i3 >> 2] | 0;
+ L1 : while (1) {
+  i22 = HEAP32[HEAP32[i19 >> 2] >> 2] | 0;
+  i18 = i22 + 12 | 0;
+  i23 = HEAP32[(HEAP32[i18 >> 2] | 0) + 8 >> 2] | 0;
+  i20 = i19 + 24 | 0;
+  i21 = i19 + 28 | 0;
+  i22 = i22 + 16 | 0;
+  i24 = i19 + 4 | 0;
+  i25 = HEAP32[i20 >> 2] | 0;
+  L3 : while (1) {
+   i28 = HEAP32[i21 >> 2] | 0;
+   HEAP32[i21 >> 2] = i28 + 4;
+   i28 = HEAP32[i28 >> 2] | 0;
+   i27 = HEAP8[i4] | 0;
+   do {
+    if (!((i27 & 12) == 0)) {
+     i26 = (HEAP32[i17 >> 2] | 0) + -1 | 0;
+     HEAP32[i17 >> 2] = i26;
+     i26 = (i26 | 0) == 0;
+     if (!i26 ? (i27 & 4) == 0 : 0) {
+      break;
+     }
+     i25 = HEAP32[i3 >> 2] | 0;
+     i29 = i27 & 255;
+     if ((i29 & 8 | 0) == 0 | i26 ^ 1) {
+      i27 = 0;
+     } else {
+      HEAP32[i17 >> 2] = HEAP32[i7 >> 2];
+      i27 = 1;
+     }
+     i26 = i25 + 18 | 0;
+     i30 = HEAPU8[i26] | 0;
+     if ((i30 & 128 | 0) == 0) {
+      if (i27) {
+       _luaD_hook(i1, 3, -1);
+      }
+      do {
+       if ((i29 & 4 | 0) == 0) {
+        i29 = i25 + 28 | 0;
+       } else {
+        i34 = HEAP32[(HEAP32[HEAP32[i25 >> 2] >> 2] | 0) + 12 >> 2] | 0;
+        i29 = i25 + 28 | 0;
+        i32 = HEAP32[i29 >> 2] | 0;
+        i35 = HEAP32[i34 + 12 >> 2] | 0;
+        i33 = (i32 - i35 >> 2) + -1 | 0;
+        i34 = HEAP32[i34 + 20 >> 2] | 0;
+        i31 = (i34 | 0) == 0;
+        if (i31) {
+         i30 = 0;
+        } else {
+         i30 = HEAP32[i34 + (i33 << 2) >> 2] | 0;
+        }
+        if ((i33 | 0) != 0 ? (i14 = HEAP32[i2 >> 2] | 0, i32 >>> 0 > i14 >>> 0) : 0) {
+         if (i31) {
+          i31 = 0;
+         } else {
+          i31 = HEAP32[i34 + ((i14 - i35 >> 2) + -1 << 2) >> 2] | 0;
+         }
+         if ((i30 | 0) == (i31 | 0)) {
+          break;
+         }
+        }
+        _luaD_hook(i1, 2, i30);
+       }
+      } while (0);
+      HEAP32[i2 >> 2] = HEAP32[i29 >> 2];
+      if ((HEAP8[i16] | 0) == 1) {
+       i15 = 23;
+       break L1;
+      }
+     } else {
+      HEAP8[i26] = i30 & 127;
+     }
+     i25 = HEAP32[i20 >> 2] | 0;
+    }
+   } while (0);
+   i26 = i28 >>> 6 & 255;
+   i27 = i25 + (i26 << 4) | 0;
+   switch (i28 & 63 | 0) {
+   case 9:
+    {
+     i28 = HEAP32[i22 + (i28 >>> 23 << 2) >> 2] | 0;
+     i35 = HEAP32[i28 + 8 >> 2] | 0;
+     i33 = i27;
+     i34 = HEAP32[i33 + 4 >> 2] | 0;
+     i36 = i35;
+     HEAP32[i36 >> 2] = HEAP32[i33 >> 2];
+     HEAP32[i36 + 4 >> 2] = i34;
+     i36 = i25 + (i26 << 4) + 8 | 0;
+     HEAP32[i35 + 8 >> 2] = HEAP32[i36 >> 2];
+     if ((HEAP32[i36 >> 2] & 64 | 0) == 0) {
+      continue L3;
+     }
+     i26 = HEAP32[i27 >> 2] | 0;
+     if ((HEAP8[i26 + 5 | 0] & 3) == 0) {
+      continue L3;
+     }
+     if ((HEAP8[i28 + 5 | 0] & 4) == 0) {
+      continue L3;
+     }
+     _luaC_barrier_(i1, i28, i26);
+     continue L3;
+    }
+   case 10:
+    {
+     i26 = i28 >>> 23;
+     if ((i26 & 256 | 0) == 0) {
+      i26 = i25 + (i26 << 4) | 0;
+     } else {
+      i26 = i23 + ((i26 & 255) << 4) | 0;
+     }
+     i28 = i28 >>> 14;
+     if ((i28 & 256 | 0) == 0) {
+      i25 = i25 + ((i28 & 511) << 4) | 0;
+     } else {
+      i25 = i23 + ((i28 & 255) << 4) | 0;
+     }
+     _luaV_settable(i1, i27, i26, i25);
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 17:
+    {
+     i29 = i28 >>> 23;
+     if ((i29 & 256 | 0) == 0) {
+      i29 = i25 + (i29 << 4) | 0;
+     } else {
+      i29 = i23 + ((i29 & 255) << 4) | 0;
+     }
+     i28 = i28 >>> 14;
+     if ((i28 & 256 | 0) == 0) {
+      i28 = i25 + ((i28 & 511) << 4) | 0;
+     } else {
+      i28 = i23 + ((i28 & 255) << 4) | 0;
+     }
+     if ((HEAP32[i29 + 8 >> 2] | 0) == 3 ? (HEAP32[i28 + 8 >> 2] | 0) == 3 : 0) {
+      d37 = +HEAPF64[i29 >> 3];
+      d38 = +HEAPF64[i28 >> 3];
+      HEAPF64[i27 >> 3] = d37 - d38 * +Math_floor(+(d37 / d38));
+      HEAP32[i25 + (i26 << 4) + 8 >> 2] = 3;
+      continue L3;
+     }
+     _luaV_arith(i1, i27, i29, i28, 10);
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 23:
+    {
+     if ((i26 | 0) != 0) {
+      _luaF_close(i1, (HEAP32[i20 >> 2] | 0) + (i26 + -1 << 4) | 0);
+     }
+     HEAP32[i21 >> 2] = (HEAP32[i21 >> 2] | 0) + ((i28 >>> 14) + -131071 << 2);
+     continue L3;
+    }
+   case 24:
+    {
+     i27 = i28 >>> 23;
+     if ((i27 & 256 | 0) == 0) {
+      i27 = i25 + (i27 << 4) | 0;
+     } else {
+      i27 = i23 + ((i27 & 255) << 4) | 0;
+     }
+     i28 = i28 >>> 14;
+     if ((i28 & 256 | 0) == 0) {
+      i25 = i25 + ((i28 & 511) << 4) | 0;
+     } else {
+      i25 = i23 + ((i28 & 255) << 4) | 0;
+     }
+     if ((HEAP32[i27 + 8 >> 2] | 0) == (HEAP32[i25 + 8 >> 2] | 0)) {
+      i27 = (_luaV_equalobj_(i1, i27, i25) | 0) != 0;
+     } else {
+      i27 = 0;
+     }
+     i25 = HEAP32[i21 >> 2] | 0;
+     if ((i27 & 1 | 0) == (i26 | 0)) {
+      i26 = HEAP32[i25 >> 2] | 0;
+      i27 = i26 >>> 6 & 255;
+      if ((i27 | 0) != 0) {
+       _luaF_close(i1, (HEAP32[i20 >> 2] | 0) + (i27 + -1 << 4) | 0);
+       i25 = HEAP32[i21 >> 2] | 0;
+      }
+      i25 = i25 + ((i26 >>> 14) + -131070 << 2) | 0;
+     } else {
+      i25 = i25 + 4 | 0;
+     }
+     HEAP32[i21 >> 2] = i25;
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 18:
+    {
+     i29 = i28 >>> 23;
+     if ((i29 & 256 | 0) == 0) {
+      i29 = i25 + (i29 << 4) | 0;
+     } else {
+      i29 = i23 + ((i29 & 255) << 4) | 0;
+     }
+     i28 = i28 >>> 14;
+     if ((i28 & 256 | 0) == 0) {
+      i28 = i25 + ((i28 & 511) << 4) | 0;
+     } else {
+      i28 = i23 + ((i28 & 255) << 4) | 0;
+     }
+     if ((HEAP32[i29 + 8 >> 2] | 0) == 3 ? (HEAP32[i28 + 8 >> 2] | 0) == 3 : 0) {
+      HEAPF64[i27 >> 3] = +Math_pow(+(+HEAPF64[i29 >> 3]), +(+HEAPF64[i28 >> 3]));
+      HEAP32[i25 + (i26 << 4) + 8 >> 2] = 3;
+      continue L3;
+     }
+     _luaV_arith(i1, i27, i29, i28, 11);
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 1:
+    {
+     i36 = i28 >>> 14;
+     i33 = i23 + (i36 << 4) | 0;
+     i34 = HEAP32[i33 + 4 >> 2] | 0;
+     i35 = i27;
+     HEAP32[i35 >> 2] = HEAP32[i33 >> 2];
+     HEAP32[i35 + 4 >> 2] = i34;
+     HEAP32[i25 + (i26 << 4) + 8 >> 2] = HEAP32[i23 + (i36 << 4) + 8 >> 2];
+     continue L3;
+    }
+   case 0:
+    {
+     i36 = i28 >>> 23;
+     i33 = i25 + (i36 << 4) | 0;
+     i34 = HEAP32[i33 + 4 >> 2] | 0;
+     i35 = i27;
+     HEAP32[i35 >> 2] = HEAP32[i33 >> 2];
+     HEAP32[i35 + 4 >> 2] = i34;
+     HEAP32[i25 + (i26 << 4) + 8 >> 2] = HEAP32[i25 + (i36 << 4) + 8 >> 2];
+     continue L3;
+    }
+   case 2:
+    {
+     i36 = HEAP32[i21 >> 2] | 0;
+     HEAP32[i21 >> 2] = i36 + 4;
+     i36 = (HEAP32[i36 >> 2] | 0) >>> 6;
+     i33 = i23 + (i36 << 4) | 0;
+     i34 = HEAP32[i33 + 4 >> 2] | 0;
+     i35 = i27;
+     HEAP32[i35 >> 2] = HEAP32[i33 >> 2];
+     HEAP32[i35 + 4 >> 2] = i34;
+     HEAP32[i25 + (i26 << 4) + 8 >> 2] = HEAP32[i23 + (i36 << 4) + 8 >> 2];
+     continue L3;
+    }
+   case 5:
+    {
+     i36 = HEAP32[(HEAP32[i22 + (i28 >>> 23 << 2) >> 2] | 0) + 8 >> 2] | 0;
+     i33 = i36;
+     i34 = HEAP32[i33 + 4 >> 2] | 0;
+     i35 = i27;
+     HEAP32[i35 >> 2] = HEAP32[i33 >> 2];
+     HEAP32[i35 + 4 >> 2] = i34;
+     HEAP32[i25 + (i26 << 4) + 8 >> 2] = HEAP32[i36 + 8 >> 2];
+     continue L3;
+    }
+   case 3:
+    {
+     HEAP32[i27 >> 2] = i28 >>> 23;
+     HEAP32[i25 + (i26 << 4) + 8 >> 2] = 1;
+     if ((i28 & 8372224 | 0) == 0) {
+      continue L3;
+     }
+     HEAP32[i21 >> 2] = (HEAP32[i21 >> 2] | 0) + 4;
+     continue L3;
+    }
+   case 7:
+    {
+     i26 = i28 >>> 14;
+     if ((i26 & 256 | 0) == 0) {
+      i26 = i25 + ((i26 & 511) << 4) | 0;
+     } else {
+      i26 = i23 + ((i26 & 255) << 4) | 0;
+     }
+     _luaV_gettable(i1, i25 + (i28 >>> 23 << 4) | 0, i26, i27);
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 12:
+    {
+     i36 = i28 >>> 23;
+     i29 = i25 + (i36 << 4) | 0;
+     i26 = i26 + 1 | 0;
+     i33 = i29;
+     i34 = HEAP32[i33 + 4 >> 2] | 0;
+     i35 = i25 + (i26 << 4) | 0;
+     HEAP32[i35 >> 2] = HEAP32[i33 >> 2];
+     HEAP32[i35 + 4 >> 2] = i34;
+     HEAP32[i25 + (i26 << 4) + 8 >> 2] = HEAP32[i25 + (i36 << 4) + 8 >> 2];
+     i26 = i28 >>> 14;
+     if ((i26 & 256 | 0) == 0) {
+      i25 = i25 + ((i26 & 511) << 4) | 0;
+     } else {
+      i25 = i23 + ((i26 & 255) << 4) | 0;
+     }
+     _luaV_gettable(i1, i29, i25, i27);
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 13:
+    {
+     i29 = i28 >>> 23;
+     if ((i29 & 256 | 0) == 0) {
+      i29 = i25 + (i29 << 4) | 0;
+     } else {
+      i29 = i23 + ((i29 & 255) << 4) | 0;
+     }
+     i28 = i28 >>> 14;
+     if ((i28 & 256 | 0) == 0) {
+      i28 = i25 + ((i28 & 511) << 4) | 0;
+     } else {
+      i28 = i23 + ((i28 & 255) << 4) | 0;
+     }
+     if ((HEAP32[i29 + 8 >> 2] | 0) == 3 ? (HEAP32[i28 + 8 >> 2] | 0) == 3 : 0) {
+      HEAPF64[i27 >> 3] = +HEAPF64[i29 >> 3] + +HEAPF64[i28 >> 3];
+      HEAP32[i25 + (i26 << 4) + 8 >> 2] = 3;
+      continue L3;
+     }
+     _luaV_arith(i1, i27, i29, i28, 6);
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 14:
+    {
+     i29 = i28 >>> 23;
+     if ((i29 & 256 | 0) == 0) {
+      i29 = i25 + (i29 << 4) | 0;
+     } else {
+      i29 = i23 + ((i29 & 255) << 4) | 0;
+     }
+     i28 = i28 >>> 14;
+     if ((i28 & 256 | 0) == 0) {
+      i28 = i25 + ((i28 & 511) << 4) | 0;
+     } else {
+      i28 = i23 + ((i28 & 255) << 4) | 0;
+     }
+     if ((HEAP32[i29 + 8 >> 2] | 0) == 3 ? (HEAP32[i28 + 8 >> 2] | 0) == 3 : 0) {
+      HEAPF64[i27 >> 3] = +HEAPF64[i29 >> 3] - +HEAPF64[i28 >> 3];
+      HEAP32[i25 + (i26 << 4) + 8 >> 2] = 3;
+      continue L3;
+     }
+     _luaV_arith(i1, i27, i29, i28, 7);
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 6:
+    {
+     i26 = i28 >>> 14;
+     if ((i26 & 256 | 0) == 0) {
+      i25 = i25 + ((i26 & 511) << 4) | 0;
+     } else {
+      i25 = i23 + ((i26 & 255) << 4) | 0;
+     }
+     _luaV_gettable(i1, HEAP32[(HEAP32[i22 + (i28 >>> 23 << 2) >> 2] | 0) + 8 >> 2] | 0, i25, i27);
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 4:
+    {
+     i26 = i28 >>> 23;
+     while (1) {
+      HEAP32[i27 + 8 >> 2] = 0;
+      if ((i26 | 0) == 0) {
+       continue L3;
+      } else {
+       i26 = i26 + -1 | 0;
+       i27 = i27 + 16 | 0;
+      }
+     }
+    }
+   case 8:
+    {
+     i27 = i28 >>> 23;
+     if ((i27 & 256 | 0) == 0) {
+      i27 = i25 + (i27 << 4) | 0;
+     } else {
+      i27 = i23 + ((i27 & 255) << 4) | 0;
+     }
+     i28 = i28 >>> 14;
+     if ((i28 & 256 | 0) == 0) {
+      i25 = i25 + ((i28 & 511) << 4) | 0;
+     } else {
+      i25 = i23 + ((i28 & 255) << 4) | 0;
+     }
+     _luaV_settable(i1, HEAP32[(HEAP32[i22 + (i26 << 2) >> 2] | 0) + 8 >> 2] | 0, i27, i25);
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 11:
+    {
+     i29 = i28 >>> 23;
+     i28 = i28 >>> 14 & 511;
+     i30 = _luaH_new(i1) | 0;
+     HEAP32[i27 >> 2] = i30;
+     HEAP32[i25 + (i26 << 4) + 8 >> 2] = 69;
+     if ((i28 | i29 | 0) != 0) {
+      i36 = _luaO_fb2int(i29) | 0;
+      _luaH_resize(i1, i30, i36, _luaO_fb2int(i28) | 0);
+     }
+     if ((HEAP32[(HEAP32[i6 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+      HEAP32[i5 >> 2] = i25 + (i26 + 1 << 4);
+      _luaC_step(i1);
+      HEAP32[i5 >> 2] = HEAP32[i24 >> 2];
+     }
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 19:
+    {
+     i36 = i28 >>> 23;
+     i28 = i25 + (i36 << 4) | 0;
+     if ((HEAP32[i25 + (i36 << 4) + 8 >> 2] | 0) == 3) {
+      HEAPF64[i27 >> 3] = -+HEAPF64[i28 >> 3];
+      HEAP32[i25 + (i26 << 4) + 8 >> 2] = 3;
+      continue L3;
+     } else {
+      _luaV_arith(i1, i27, i28, i28, 12);
+      i25 = HEAP32[i20 >> 2] | 0;
+      continue L3;
+     }
+    }
+   case 15:
+    {
+     i29 = i28 >>> 23;
+     if ((i29 & 256 | 0) == 0) {
+      i29 = i25 + (i29 << 4) | 0;
+     } else {
+      i29 = i23 + ((i29 & 255) << 4) | 0;
+     }
+     i28 = i28 >>> 14;
+     if ((i28 & 256 | 0) == 0) {
+      i28 = i25 + ((i28 & 511) << 4) | 0;
+     } else {
+      i28 = i23 + ((i28 & 255) << 4) | 0;
+     }
+     if ((HEAP32[i29 + 8 >> 2] | 0) == 3 ? (HEAP32[i28 + 8 >> 2] | 0) == 3 : 0) {
+      HEAPF64[i27 >> 3] = +HEAPF64[i29 >> 3] * +HEAPF64[i28 >> 3];
+      HEAP32[i25 + (i26 << 4) + 8 >> 2] = 3;
+      continue L3;
+     }
+     _luaV_arith(i1, i27, i29, i28, 8);
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 16:
+    {
+     i29 = i28 >>> 23;
+     if ((i29 & 256 | 0) == 0) {
+      i29 = i25 + (i29 << 4) | 0;
+     } else {
+      i29 = i23 + ((i29 & 255) << 4) | 0;
+     }
+     i28 = i28 >>> 14;
+     if ((i28 & 256 | 0) == 0) {
+      i28 = i25 + ((i28 & 511) << 4) | 0;
+     } else {
+      i28 = i23 + ((i28 & 255) << 4) | 0;
+     }
+     if ((HEAP32[i29 + 8 >> 2] | 0) == 3 ? (HEAP32[i28 + 8 >> 2] | 0) == 3 : 0) {
+      HEAPF64[i27 >> 3] = +HEAPF64[i29 >> 3] / +HEAPF64[i28 >> 3];
+      HEAP32[i25 + (i26 << 4) + 8 >> 2] = 3;
+      continue L3;
+     }
+     _luaV_arith(i1, i27, i29, i28, 9);
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 20:
+    {
+     i29 = i28 >>> 23;
+     i28 = HEAP32[i25 + (i29 << 4) + 8 >> 2] | 0;
+     if ((i28 | 0) != 0) {
+      if ((i28 | 0) == 1) {
+       i28 = (HEAP32[i25 + (i29 << 4) >> 2] | 0) == 0;
+      } else {
+       i28 = 0;
+      }
+     } else {
+      i28 = 1;
+     }
+     HEAP32[i27 >> 2] = i28 & 1;
+     HEAP32[i25 + (i26 << 4) + 8 >> 2] = 1;
+     continue L3;
+    }
+   case 21:
+    {
+     _luaV_objlen(i1, i27, i25 + (i28 >>> 23 << 4) | 0);
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 22:
+    {
+     i27 = i28 >>> 23;
+     i28 = i28 >>> 14 & 511;
+     HEAP32[i5 >> 2] = i25 + (i28 + 1 << 4);
+     _luaV_concat(i1, 1 - i27 + i28 | 0);
+     i25 = HEAP32[i20 >> 2] | 0;
+     i28 = i25 + (i27 << 4) | 0;
+     i34 = i28;
+     i35 = HEAP32[i34 + 4 >> 2] | 0;
+     i36 = i25 + (i26 << 4) | 0;
+     HEAP32[i36 >> 2] = HEAP32[i34 >> 2];
+     HEAP32[i36 + 4 >> 2] = i35;
+     HEAP32[i25 + (i26 << 4) + 8 >> 2] = HEAP32[i25 + (i27 << 4) + 8 >> 2];
+     if ((HEAP32[(HEAP32[i6 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+      if (!(i26 >>> 0 < i27 >>> 0)) {
+       i28 = i25 + (i26 + 1 << 4) | 0;
+      }
+      HEAP32[i5 >> 2] = i28;
+      _luaC_step(i1);
+      HEAP32[i5 >> 2] = HEAP32[i24 >> 2];
+     }
+     i25 = HEAP32[i20 >> 2] | 0;
+     HEAP32[i5 >> 2] = HEAP32[i24 >> 2];
+     continue L3;
+    }
+   case 25:
+    {
+     i27 = i28 >>> 23;
+     if ((i27 & 256 | 0) == 0) {
+      i27 = i25 + (i27 << 4) | 0;
+     } else {
+      i27 = i23 + ((i27 & 255) << 4) | 0;
+     }
+     i28 = i28 >>> 14;
+     if ((i28 & 256 | 0) == 0) {
+      i25 = i25 + ((i28 & 511) << 4) | 0;
+     } else {
+      i25 = i23 + ((i28 & 255) << 4) | 0;
+     }
+     i36 = (_luaV_lessthan(i1, i27, i25) | 0) == (i26 | 0);
+     i26 = HEAP32[i21 >> 2] | 0;
+     if (i36) {
+      i25 = HEAP32[i26 >> 2] | 0;
+      i27 = i25 >>> 6 & 255;
+      if ((i27 | 0) != 0) {
+       _luaF_close(i1, (HEAP32[i20 >> 2] | 0) + (i27 + -1 << 4) | 0);
+       i26 = HEAP32[i21 >> 2] | 0;
+      }
+      i25 = i26 + ((i25 >>> 14) + -131070 << 2) | 0;
+     } else {
+      i25 = i26 + 4 | 0;
+     }
+     HEAP32[i21 >> 2] = i25;
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 27:
+    {
+     i29 = HEAP32[i25 + (i26 << 4) + 8 >> 2] | 0;
+     i26 = (i29 | 0) == 0;
+     if ((i28 & 8372224 | 0) == 0) {
+      if (!i26) {
+       if (!((i29 | 0) == 1 ? (HEAP32[i27 >> 2] | 0) == 0 : 0)) {
+        i15 = 192;
+       }
+      }
+     } else {
+      if (!i26) {
+       if ((i29 | 0) == 1 ? (HEAP32[i27 >> 2] | 0) == 0 : 0) {
+        i15 = 192;
+       }
+      } else {
+       i15 = 192;
+      }
+     }
+     if ((i15 | 0) == 192) {
+      i15 = 0;
+      HEAP32[i21 >> 2] = (HEAP32[i21 >> 2] | 0) + 4;
+      continue L3;
+     }
+     i27 = HEAP32[i21 >> 2] | 0;
+     i26 = HEAP32[i27 >> 2] | 0;
+     i28 = i26 >>> 6 & 255;
+     if ((i28 | 0) != 0) {
+      _luaF_close(i1, (HEAP32[i20 >> 2] | 0) + (i28 + -1 << 4) | 0);
+      i27 = HEAP32[i21 >> 2] | 0;
+     }
+     HEAP32[i21 >> 2] = i27 + ((i26 >>> 14) + -131070 << 2);
+     continue L3;
+    }
+   case 26:
+    {
+     i27 = i28 >>> 23;
+     if ((i27 & 256 | 0) == 0) {
+      i27 = i25 + (i27 << 4) | 0;
+     } else {
+      i27 = i23 + ((i27 & 255) << 4) | 0;
+     }
+     i28 = i28 >>> 14;
+     if ((i28 & 256 | 0) == 0) {
+      i25 = i25 + ((i28 & 511) << 4) | 0;
+     } else {
+      i25 = i23 + ((i28 & 255) << 4) | 0;
+     }
+     i36 = (_luaV_lessequal(i1, i27, i25) | 0) == (i26 | 0);
+     i26 = HEAP32[i21 >> 2] | 0;
+     if (i36) {
+      i25 = HEAP32[i26 >> 2] | 0;
+      i27 = i25 >>> 6 & 255;
+      if ((i27 | 0) != 0) {
+       _luaF_close(i1, (HEAP32[i20 >> 2] | 0) + (i27 + -1 << 4) | 0);
+       i26 = HEAP32[i21 >> 2] | 0;
+      }
+      i25 = i26 + ((i25 >>> 14) + -131070 << 2) | 0;
+     } else {
+      i25 = i26 + 4 | 0;
+     }
+     HEAP32[i21 >> 2] = i25;
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 28:
+    {
+     i30 = i28 >>> 23;
+     i29 = i25 + (i30 << 4) | 0;
+     i30 = HEAP32[i25 + (i30 << 4) + 8 >> 2] | 0;
+     i31 = (i30 | 0) == 0;
+     if ((i28 & 8372224 | 0) == 0) {
+      if (!i31) {
+       if (!((i30 | 0) == 1 ? (HEAP32[i29 >> 2] | 0) == 0 : 0)) {
+        i15 = 203;
+       }
+      }
+     } else {
+      if (!i31) {
+       if ((i30 | 0) == 1 ? (HEAP32[i29 >> 2] | 0) == 0 : 0) {
+        i15 = 203;
+       }
+      } else {
+       i15 = 203;
+      }
+     }
+     if ((i15 | 0) == 203) {
+      i15 = 0;
+      HEAP32[i21 >> 2] = (HEAP32[i21 >> 2] | 0) + 4;
+      continue L3;
+     }
+     i36 = i29;
+     i28 = HEAP32[i36 + 4 >> 2] | 0;
+     HEAP32[i27 >> 2] = HEAP32[i36 >> 2];
+     HEAP32[i27 + 4 >> 2] = i28;
+     HEAP32[i25 + (i26 << 4) + 8 >> 2] = i30;
+     i27 = HEAP32[i21 >> 2] | 0;
+     i26 = HEAP32[i27 >> 2] | 0;
+     i28 = i26 >>> 6 & 255;
+     if ((i28 | 0) != 0) {
+      _luaF_close(i1, (HEAP32[i20 >> 2] | 0) + (i28 + -1 << 4) | 0);
+      i27 = HEAP32[i21 >> 2] | 0;
+     }
+     HEAP32[i21 >> 2] = i27 + ((i26 >>> 14) + -131070 << 2);
+     continue L3;
+    }
+   case 30:
+    {
+     i28 = i28 >>> 23;
+     if ((i28 | 0) != 0) {
+      HEAP32[i5 >> 2] = i25 + (i26 + i28 << 4);
+     }
+     if ((_luaD_precall(i1, i27, -1) | 0) == 0) {
+      i15 = 218;
+      break L3;
+     }
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 29:
+    {
+     i29 = i28 >>> 23;
+     i28 = i28 >>> 14 & 511;
+     if ((i29 | 0) != 0) {
+      HEAP32[i5 >> 2] = i25 + (i26 + i29 << 4);
+     }
+     if ((_luaD_precall(i1, i27, i28 + -1 | 0) | 0) == 0) {
+      i15 = 213;
+      break L3;
+     }
+     if ((i28 | 0) != 0) {
+      HEAP32[i5 >> 2] = HEAP32[i24 >> 2];
+     }
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 32:
+    {
+     d39 = +HEAPF64[i25 + (i26 + 2 << 4) >> 3];
+     d38 = d39 + +HEAPF64[i27 >> 3];
+     d37 = +HEAPF64[i25 + (i26 + 1 << 4) >> 3];
+     if (d39 > 0.0) {
+      if (!(d38 <= d37)) {
+       continue L3;
+      }
+     } else {
+      if (!(d37 <= d38)) {
+       continue L3;
+      }
+     }
+     HEAP32[i21 >> 2] = (HEAP32[i21 >> 2] | 0) + ((i28 >>> 14) + -131071 << 2);
+     HEAPF64[i27 >> 3] = d38;
+     HEAP32[i25 + (i26 << 4) + 8 >> 2] = 3;
+     i36 = i26 + 3 | 0;
+     HEAPF64[i25 + (i36 << 4) >> 3] = d38;
+     HEAP32[i25 + (i36 << 4) + 8 >> 2] = 3;
+     continue L3;
+    }
+   case 33:
+    {
+     i32 = i26 + 1 | 0;
+     i30 = i25 + (i32 << 4) | 0;
+     i31 = i26 + 2 | 0;
+     i29 = i25 + (i31 << 4) | 0;
+     i26 = i25 + (i26 << 4) + 8 | 0;
+     i33 = HEAP32[i26 >> 2] | 0;
+     if ((i33 | 0) != 3) {
+      if ((i33 & 15 | 0) != 4) {
+       i15 = 239;
+       break L1;
+      }
+      i36 = HEAP32[i27 >> 2] | 0;
+      if ((_luaO_str2d(i36 + 16 | 0, HEAP32[i36 + 12 >> 2] | 0, i8) | 0) == 0) {
+       i15 = 239;
+       break L1;
+      }
+      HEAPF64[i27 >> 3] = +HEAPF64[i8 >> 3];
+      HEAP32[i26 >> 2] = 3;
+      if ((i27 | 0) == 0) {
+       i15 = 239;
+       break L1;
+      }
+     }
+     i33 = i25 + (i32 << 4) + 8 | 0;
+     i32 = HEAP32[i33 >> 2] | 0;
+     if ((i32 | 0) != 3) {
+      if ((i32 & 15 | 0) != 4) {
+       i15 = 244;
+       break L1;
+      }
+      i36 = HEAP32[i30 >> 2] | 0;
+      if ((_luaO_str2d(i36 + 16 | 0, HEAP32[i36 + 12 >> 2] | 0, i9) | 0) == 0) {
+       i15 = 244;
+       break L1;
+      }
+      HEAPF64[i30 >> 3] = +HEAPF64[i9 >> 3];
+      HEAP32[i33 >> 2] = 3;
+     }
+     i31 = i25 + (i31 << 4) + 8 | 0;
+     i30 = HEAP32[i31 >> 2] | 0;
+     if ((i30 | 0) != 3) {
+      if ((i30 & 15 | 0) != 4) {
+       i15 = 249;
+       break L1;
+      }
+      i36 = HEAP32[i29 >> 2] | 0;
+      if ((_luaO_str2d(i36 + 16 | 0, HEAP32[i36 + 12 >> 2] | 0, i10) | 0) == 0) {
+       i15 = 249;
+       break L1;
+      }
+      HEAPF64[i29 >> 3] = +HEAPF64[i10 >> 3];
+      HEAP32[i31 >> 2] = 3;
+     }
+     HEAPF64[i27 >> 3] = +HEAPF64[i27 >> 3] - +HEAPF64[i29 >> 3];
+     HEAP32[i26 >> 2] = 3;
+     HEAP32[i21 >> 2] = (HEAP32[i21 >> 2] | 0) + ((i28 >>> 14) + -131071 << 2);
+     continue L3;
+    }
+   case 31:
+    {
+     i15 = 223;
+     break L3;
+    }
+   case 34:
+    {
+     i35 = i26 + 3 | 0;
+     i36 = i25 + (i35 << 4) | 0;
+     i33 = i26 + 2 | 0;
+     i34 = i26 + 5 | 0;
+     i32 = i25 + (i33 << 4) | 0;
+     i31 = HEAP32[i32 + 4 >> 2] | 0;
+     i30 = i25 + (i34 << 4) | 0;
+     HEAP32[i30 >> 2] = HEAP32[i32 >> 2];
+     HEAP32[i30 + 4 >> 2] = i31;
+     HEAP32[i25 + (i34 << 4) + 8 >> 2] = HEAP32[i25 + (i33 << 4) + 8 >> 2];
+     i34 = i26 + 1 | 0;
+     i33 = i26 + 4 | 0;
+     i30 = i25 + (i34 << 4) | 0;
+     i31 = HEAP32[i30 + 4 >> 2] | 0;
+     i32 = i25 + (i33 << 4) | 0;
+     HEAP32[i32 >> 2] = HEAP32[i30 >> 2];
+     HEAP32[i32 + 4 >> 2] = i31;
+     HEAP32[i25 + (i33 << 4) + 8 >> 2] = HEAP32[i25 + (i34 << 4) + 8 >> 2];
+     i33 = i27;
+     i34 = HEAP32[i33 + 4 >> 2] | 0;
+     i27 = i36;
+     HEAP32[i27 >> 2] = HEAP32[i33 >> 2];
+     HEAP32[i27 + 4 >> 2] = i34;
+     HEAP32[i25 + (i35 << 4) + 8 >> 2] = HEAP32[i25 + (i26 << 4) + 8 >> 2];
+     HEAP32[i5 >> 2] = i25 + (i26 + 6 << 4);
+     _luaD_call(i1, i36, i28 >>> 14 & 511, 1);
+     i36 = HEAP32[i20 >> 2] | 0;
+     HEAP32[i5 >> 2] = HEAP32[i24 >> 2];
+     i27 = HEAP32[i21 >> 2] | 0;
+     HEAP32[i21 >> 2] = i27 + 4;
+     i27 = HEAP32[i27 >> 2] | 0;
+     i25 = i36;
+     i28 = i27;
+     i27 = i36 + ((i27 >>> 6 & 255) << 4) | 0;
+     break;
+    }
+   case 35:
+    {
+     break;
+    }
+   case 36:
+    {
+     i29 = i28 >>> 23;
+     i28 = i28 >>> 14 & 511;
+     if ((i29 | 0) == 0) {
+      i29 = ((HEAP32[i5 >> 2] | 0) - i27 >> 4) + -1 | 0;
+     }
+     if ((i28 | 0) == 0) {
+      i28 = HEAP32[i21 >> 2] | 0;
+      HEAP32[i21 >> 2] = i28 + 4;
+      i28 = (HEAP32[i28 >> 2] | 0) >>> 6;
+     }
+     i27 = HEAP32[i27 >> 2] | 0;
+     i30 = i29 + -50 + (i28 * 50 | 0) | 0;
+     if ((i30 | 0) > (HEAP32[i27 + 28 >> 2] | 0)) {
+      _luaH_resizearray(i1, i27, i30);
+     }
+     if ((i29 | 0) > 0) {
+      i28 = i27 + 5 | 0;
+      while (1) {
+       i36 = i29 + i26 | 0;
+       i32 = i25 + (i36 << 4) | 0;
+       i31 = i30 + -1 | 0;
+       _luaH_setint(i1, i27, i30, i32);
+       if (((HEAP32[i25 + (i36 << 4) + 8 >> 2] & 64 | 0) != 0 ? !((HEAP8[(HEAP32[i32 >> 2] | 0) + 5 | 0] & 3) == 0) : 0) ? !((HEAP8[i28] & 4) == 0) : 0) {
+        _luaC_barrierback_(i1, i27);
+       }
+       i29 = i29 + -1 | 0;
+       if ((i29 | 0) > 0) {
+        i30 = i31;
+       } else {
+        break;
+       }
+      }
+     }
+     HEAP32[i5 >> 2] = HEAP32[i24 >> 2];
+     continue L3;
+    }
+   case 37:
+    {
+     i29 = HEAP32[(HEAP32[(HEAP32[i18 >> 2] | 0) + 16 >> 2] | 0) + (i28 >>> 14 << 2) >> 2] | 0;
+     i28 = i29 + 32 | 0;
+     i33 = HEAP32[i28 >> 2] | 0;
+     i30 = HEAP32[i29 + 40 >> 2] | 0;
+     i31 = HEAP32[i29 + 28 >> 2] | 0;
+     L323 : do {
+      if ((i33 | 0) == 0) {
+       i15 = 276;
+      } else {
+       if ((i30 | 0) > 0) {
+        i34 = i33 + 16 | 0;
+        i32 = 0;
+        while (1) {
+         i35 = HEAPU8[i31 + (i32 << 3) + 5 | 0] | 0;
+         if ((HEAP8[i31 + (i32 << 3) + 4 | 0] | 0) == 0) {
+          i36 = HEAP32[(HEAP32[i22 + (i35 << 2) >> 2] | 0) + 8 >> 2] | 0;
+         } else {
+          i36 = i25 + (i35 << 4) | 0;
+         }
+         i35 = i32 + 1 | 0;
+         if ((HEAP32[(HEAP32[i34 + (i32 << 2) >> 2] | 0) + 8 >> 2] | 0) != (i36 | 0)) {
+          i15 = 276;
+          break L323;
+         }
+         if ((i35 | 0) < (i30 | 0)) {
+          i32 = i35;
+         } else {
+          break;
+         }
+        }
+       }
+       HEAP32[i27 >> 2] = i33;
+       HEAP32[i25 + (i26 << 4) + 8 >> 2] = 70;
+      }
+     } while (0);
+     if ((i15 | 0) == 276) {
+      i15 = 0;
+      i32 = _luaF_newLclosure(i1, i30) | 0;
+      HEAP32[i32 + 12 >> 2] = i29;
+      HEAP32[i27 >> 2] = i32;
+      HEAP32[i25 + (i26 << 4) + 8 >> 2] = 70;
+      if ((i30 | 0) > 0) {
+       i27 = i32 + 16 | 0;
+       i34 = 0;
+       do {
+        i33 = HEAPU8[i31 + (i34 << 3) + 5 | 0] | 0;
+        if ((HEAP8[i31 + (i34 << 3) + 4 | 0] | 0) == 0) {
+         HEAP32[i27 + (i34 << 2) >> 2] = HEAP32[i22 + (i33 << 2) >> 2];
+        } else {
+         HEAP32[i27 + (i34 << 2) >> 2] = _luaF_findupval(i1, i25 + (i33 << 4) | 0) | 0;
+        }
+        i34 = i34 + 1 | 0;
+       } while ((i34 | 0) != (i30 | 0));
+      }
+      if (!((HEAP8[i29 + 5 | 0] & 4) == 0)) {
+       _luaC_barrierproto_(i1, i29, i32);
+      }
+      HEAP32[i28 >> 2] = i32;
+     }
+     if ((HEAP32[(HEAP32[i6 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+      HEAP32[i5 >> 2] = i25 + (i26 + 1 << 4);
+      _luaC_step(i1);
+      HEAP32[i5 >> 2] = HEAP32[i24 >> 2];
+     }
+     i25 = HEAP32[i20 >> 2] | 0;
+     continue L3;
+    }
+   case 38:
+    {
+     i36 = i28 >>> 23;
+     i29 = i36 + -1 | 0;
+     i30 = (i25 - (HEAP32[i19 >> 2] | 0) >> 4) - (HEAPU8[(HEAP32[i18 >> 2] | 0) + 76 | 0] | 0) | 0;
+     i28 = i30 + -1 | 0;
+     if ((i36 | 0) == 0) {
+      if (((HEAP32[i11 >> 2] | 0) - (HEAP32[i5 >> 2] | 0) >> 4 | 0) <= (i28 | 0)) {
+       _luaD_growstack(i1, i28);
+      }
+      i27 = HEAP32[i20 >> 2] | 0;
+      HEAP32[i5 >> 2] = i27 + (i28 + i26 << 4);
+      i29 = i28;
+      i25 = i27;
+      i27 = i27 + (i26 << 4) | 0;
+     }
+     if ((i29 | 0) <= 0) {
+      continue L3;
+     }
+     i26 = 1 - i30 | 0;
+     i30 = 0;
+     while (1) {
+      if ((i30 | 0) < (i28 | 0)) {
+       i36 = i30 + i26 | 0;
+       i33 = i25 + (i36 << 4) | 0;
+       i34 = HEAP32[i33 + 4 >> 2] | 0;
+       i35 = i27 + (i30 << 4) | 0;
+       HEAP32[i35 >> 2] = HEAP32[i33 >> 2];
+       HEAP32[i35 + 4 >> 2] = i34;
+       HEAP32[i27 + (i30 << 4) + 8 >> 2] = HEAP32[i25 + (i36 << 4) + 8 >> 2];
+      } else {
+       HEAP32[i27 + (i30 << 4) + 8 >> 2] = 0;
+      }
+      i30 = i30 + 1 | 0;
+      if ((i30 | 0) == (i29 | 0)) {
+       continue L3;
+      }
+     }
+    }
+   default:
+    {
+     continue L3;
+    }
+   }
+   i26 = HEAP32[i27 + 24 >> 2] | 0;
+   if ((i26 | 0) == 0) {
+    continue;
+   }
+   i34 = i27 + 16 | 0;
+   i35 = HEAP32[i34 + 4 >> 2] | 0;
+   i36 = i27;
+   HEAP32[i36 >> 2] = HEAP32[i34 >> 2];
+   HEAP32[i36 + 4 >> 2] = i35;
+   HEAP32[i27 + 8 >> 2] = i26;
+   HEAP32[i21 >> 2] = (HEAP32[i21 >> 2] | 0) + ((i28 >>> 14) + -131071 << 2);
+  }
+  if ((i15 | 0) == 213) {
+   i15 = 0;
+   i19 = HEAP32[i3 >> 2] | 0;
+   i36 = i19 + 18 | 0;
+   HEAP8[i36] = HEAPU8[i36] | 4;
+   continue;
+  } else if ((i15 | 0) == 218) {
+   i15 = 0;
+   i22 = HEAP32[i3 >> 2] | 0;
+   i19 = HEAP32[i22 + 8 >> 2] | 0;
+   i23 = HEAP32[i22 >> 2] | 0;
+   i24 = HEAP32[i19 >> 2] | 0;
+   i20 = i22 + 24 | 0;
+   i21 = (HEAP32[i20 >> 2] | 0) + (HEAPU8[(HEAP32[(HEAP32[i23 >> 2] | 0) + 12 >> 2] | 0) + 76 | 0] << 4) | 0;
+   if ((HEAP32[(HEAP32[i18 >> 2] | 0) + 56 >> 2] | 0) > 0) {
+    _luaF_close(i1, HEAP32[i19 + 24 >> 2] | 0);
+   }
+   if (i23 >>> 0 < i21 >>> 0) {
+    i25 = i23;
+    i18 = 0;
+    do {
+     i34 = i25;
+     i35 = HEAP32[i34 + 4 >> 2] | 0;
+     i36 = i24 + (i18 << 4) | 0;
+     HEAP32[i36 >> 2] = HEAP32[i34 >> 2];
+     HEAP32[i36 + 4 >> 2] = i35;
+     HEAP32[i24 + (i18 << 4) + 8 >> 2] = HEAP32[i23 + (i18 << 4) + 8 >> 2];
+     i18 = i18 + 1 | 0;
+     i25 = i23 + (i18 << 4) | 0;
+    } while (i25 >>> 0 < i21 >>> 0);
+   }
+   i36 = i23;
+   HEAP32[i19 + 24 >> 2] = i24 + ((HEAP32[i20 >> 2] | 0) - i36 >> 4 << 4);
+   i36 = i24 + ((HEAP32[i5 >> 2] | 0) - i36 >> 4 << 4) | 0;
+   HEAP32[i5 >> 2] = i36;
+   HEAP32[i19 + 4 >> 2] = i36;
+   HEAP32[i19 + 28 >> 2] = HEAP32[i22 + 28 >> 2];
+   i36 = i19 + 18 | 0;
+   HEAP8[i36] = HEAPU8[i36] | 64;
+   HEAP32[i3 >> 2] = i19;
+   continue;
+  } else if ((i15 | 0) == 223) {
+   i15 = 0;
+   i20 = i28 >>> 23;
+   if ((i20 | 0) != 0) {
+    HEAP32[i5 >> 2] = i25 + (i20 + -1 + i26 << 4);
+   }
+   if ((HEAP32[(HEAP32[i18 >> 2] | 0) + 56 >> 2] | 0) > 0) {
+    _luaF_close(i1, i25);
+   }
+   i18 = _luaD_poscall(i1, i27) | 0;
+   if ((HEAP8[i19 + 18 | 0] & 4) == 0) {
+    i15 = 228;
+    break;
+   }
+   i19 = HEAP32[i3 >> 2] | 0;
+   if ((i18 | 0) == 0) {
+    continue;
+   }
+   HEAP32[i5 >> 2] = HEAP32[i19 + 4 >> 2];
+   continue;
+  }
+ }
+ if ((i15 | 0) == 23) {
+  if (!i27) {
+   i36 = HEAP32[i29 >> 2] | 0;
+   i36 = i36 + -4 | 0;
+   HEAP32[i29 >> 2] = i36;
+   i36 = HEAP8[i26] | 0;
+   i36 = i36 & 255;
+   i36 = i36 | 128;
+   i36 = i36 & 255;
+   HEAP8[i26] = i36;
+   i36 = HEAP32[i5 >> 2] | 0;
+   i36 = i36 + -16 | 0;
+   HEAP32[i25 >> 2] = i36;
+   _luaD_throw(i1, 1);
+  }
+  HEAP32[i17 >> 2] = 1;
+  i36 = HEAP32[i29 >> 2] | 0;
+  i36 = i36 + -4 | 0;
+  HEAP32[i29 >> 2] = i36;
+  i36 = HEAP8[i26] | 0;
+  i36 = i36 & 255;
+  i36 = i36 | 128;
+  i36 = i36 & 255;
+  HEAP8[i26] = i36;
+  i36 = HEAP32[i5 >> 2] | 0;
+  i36 = i36 + -16 | 0;
+  HEAP32[i25 >> 2] = i36;
+  _luaD_throw(i1, 1);
+ } else if ((i15 | 0) == 228) {
+  STACKTOP = i12;
+  return;
+ } else if ((i15 | 0) == 239) {
+  _luaG_runerror(i1, 9040, i13);
+ } else if ((i15 | 0) == 244) {
+  _luaG_runerror(i1, 9080, i13);
+ } else if ((i15 | 0) == 249) {
+  _luaG_runerror(i1, 9112, i13);
+ }
+}
+function ___floatscan(i8, i2, i11) {
+ i8 = i8 | 0;
+ i2 = i2 | 0;
+ i11 = i11 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i9 = 0, i10 = 0, i12 = 0, i13 = 0, d14 = 0.0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, d28 = 0.0, i29 = 0, d30 = 0.0, d31 = 0.0, d32 = 0.0, d33 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 512 | 0;
+ i5 = i1;
+ if ((i2 | 0) == 1) {
+  i2 = 53;
+  i3 = -1074;
+ } else if ((i2 | 0) == 2) {
+  i2 = 53;
+  i3 = -1074;
+ } else if ((i2 | 0) == 0) {
+  i2 = 24;
+  i3 = -149;
+ } else {
+  d31 = 0.0;
+  STACKTOP = i1;
+  return +d31;
+ }
+ i9 = i8 + 4 | 0;
+ i10 = i8 + 100 | 0;
+ do {
+  i4 = HEAP32[i9 >> 2] | 0;
+  if (i4 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+   HEAP32[i9 >> 2] = i4 + 1;
+   i21 = HEAPU8[i4] | 0;
+  } else {
+   i21 = ___shgetc(i8) | 0;
+  }
+ } while ((_isspace(i21 | 0) | 0) != 0);
+ do {
+  if ((i21 | 0) == 43 | (i21 | 0) == 45) {
+   i4 = 1 - (((i21 | 0) == 45) << 1) | 0;
+   i7 = HEAP32[i9 >> 2] | 0;
+   if (i7 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+    HEAP32[i9 >> 2] = i7 + 1;
+    i21 = HEAPU8[i7] | 0;
+    break;
+   } else {
+    i21 = ___shgetc(i8) | 0;
+    break;
+   }
+  } else {
+   i4 = 1;
+  }
+ } while (0);
+ i7 = 0;
+ do {
+  if ((i21 | 32 | 0) != (HEAP8[13408 + i7 | 0] | 0)) {
+   break;
+  }
+  do {
+   if (i7 >>> 0 < 7) {
+    i12 = HEAP32[i9 >> 2] | 0;
+    if (i12 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+     HEAP32[i9 >> 2] = i12 + 1;
+     i21 = HEAPU8[i12] | 0;
+     break;
+    } else {
+     i21 = ___shgetc(i8) | 0;
+     break;
+    }
+   }
+  } while (0);
+  i7 = i7 + 1 | 0;
+ } while (i7 >>> 0 < 8);
+ do {
+  if ((i7 | 0) == 3) {
+   i13 = 23;
+  } else if ((i7 | 0) != 8) {
+   i12 = (i11 | 0) == 0;
+   if (!(i7 >>> 0 < 4 | i12)) {
+    if ((i7 | 0) == 8) {
+     break;
+    } else {
+     i13 = 23;
+     break;
+    }
+   }
+   L34 : do {
+    if ((i7 | 0) == 0) {
+     i7 = 0;
+     do {
+      if ((i21 | 32 | 0) != (HEAP8[13424 + i7 | 0] | 0)) {
+       break L34;
+      }
+      do {
+       if (i7 >>> 0 < 2) {
+        i15 = HEAP32[i9 >> 2] | 0;
+        if (i15 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+         HEAP32[i9 >> 2] = i15 + 1;
+         i21 = HEAPU8[i15] | 0;
+         break;
+        } else {
+         i21 = ___shgetc(i8) | 0;
+         break;
+        }
+       }
+      } while (0);
+      i7 = i7 + 1 | 0;
+     } while (i7 >>> 0 < 3);
+    }
+   } while (0);
+   if ((i7 | 0) == 0) {
+    do {
+     if ((i21 | 0) == 48) {
+      i7 = HEAP32[i9 >> 2] | 0;
+      if (i7 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+       HEAP32[i9 >> 2] = i7 + 1;
+       i7 = HEAPU8[i7] | 0;
+      } else {
+       i7 = ___shgetc(i8) | 0;
+      }
+      if ((i7 | 32 | 0) != 120) {
+       if ((HEAP32[i10 >> 2] | 0) == 0) {
+        i21 = 48;
+        break;
+       }
+       HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + -1;
+       i21 = 48;
+       break;
+      }
+      i5 = HEAP32[i9 >> 2] | 0;
+      if (i5 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+       HEAP32[i9 >> 2] = i5 + 1;
+       i21 = HEAPU8[i5] | 0;
+       i19 = 0;
+      } else {
+       i21 = ___shgetc(i8) | 0;
+       i19 = 0;
+      }
+      while (1) {
+       if ((i21 | 0) == 46) {
+        i13 = 70;
+        break;
+       } else if ((i21 | 0) != 48) {
+        i5 = 0;
+        i7 = 0;
+        i15 = 0;
+        i16 = 0;
+        i18 = 0;
+        i20 = 0;
+        d28 = 1.0;
+        i17 = 0;
+        d14 = 0.0;
+        break;
+       }
+       i5 = HEAP32[i9 >> 2] | 0;
+       if (i5 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+        HEAP32[i9 >> 2] = i5 + 1;
+        i21 = HEAPU8[i5] | 0;
+        i19 = 1;
+        continue;
+       } else {
+        i21 = ___shgetc(i8) | 0;
+        i19 = 1;
+        continue;
+       }
+      }
+      L66 : do {
+       if ((i13 | 0) == 70) {
+        i5 = HEAP32[i9 >> 2] | 0;
+        if (i5 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+         HEAP32[i9 >> 2] = i5 + 1;
+         i21 = HEAPU8[i5] | 0;
+        } else {
+         i21 = ___shgetc(i8) | 0;
+        }
+        if ((i21 | 0) == 48) {
+         i15 = -1;
+         i16 = -1;
+         while (1) {
+          i5 = HEAP32[i9 >> 2] | 0;
+          if (i5 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+           HEAP32[i9 >> 2] = i5 + 1;
+           i21 = HEAPU8[i5] | 0;
+          } else {
+           i21 = ___shgetc(i8) | 0;
+          }
+          if ((i21 | 0) != 48) {
+           i5 = 0;
+           i7 = 0;
+           i19 = 1;
+           i18 = 1;
+           i20 = 0;
+           d28 = 1.0;
+           i17 = 0;
+           d14 = 0.0;
+           break L66;
+          }
+          i29 = _i64Add(i15 | 0, i16 | 0, -1, -1) | 0;
+          i15 = i29;
+          i16 = tempRet0;
+         }
+        } else {
+         i5 = 0;
+         i7 = 0;
+         i15 = 0;
+         i16 = 0;
+         i18 = 1;
+         i20 = 0;
+         d28 = 1.0;
+         i17 = 0;
+         d14 = 0.0;
+        }
+       }
+      } while (0);
+      L79 : while (1) {
+       i24 = i21 + -48 | 0;
+       do {
+        if (!(i24 >>> 0 < 10)) {
+         i23 = i21 | 32;
+         i22 = (i21 | 0) == 46;
+         if (!((i23 + -97 | 0) >>> 0 < 6 | i22)) {
+          break L79;
+         }
+         if (i22) {
+          if ((i18 | 0) == 0) {
+           i15 = i7;
+           i16 = i5;
+           i18 = 1;
+           break;
+          } else {
+           i21 = 46;
+           break L79;
+          }
+         } else {
+          i24 = (i21 | 0) > 57 ? i23 + -87 | 0 : i24;
+          i13 = 84;
+          break;
+         }
+        } else {
+         i13 = 84;
+        }
+       } while (0);
+       if ((i13 | 0) == 84) {
+        i13 = 0;
+        do {
+         if (!((i5 | 0) < 0 | (i5 | 0) == 0 & i7 >>> 0 < 8)) {
+          if ((i5 | 0) < 0 | (i5 | 0) == 0 & i7 >>> 0 < 14) {
+           d31 = d28 * .0625;
+           d30 = d31;
+           d14 = d14 + d31 * +(i24 | 0);
+           break;
+          }
+          if ((i24 | 0) != 0 & (i20 | 0) == 0) {
+           i20 = 1;
+           d30 = d28;
+           d14 = d14 + d28 * .5;
+          } else {
+           d30 = d28;
+          }
+         } else {
+          d30 = d28;
+          i17 = i24 + (i17 << 4) | 0;
+         }
+        } while (0);
+        i7 = _i64Add(i7 | 0, i5 | 0, 1, 0) | 0;
+        i5 = tempRet0;
+        i19 = 1;
+        d28 = d30;
+       }
+       i21 = HEAP32[i9 >> 2] | 0;
+       if (i21 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+        HEAP32[i9 >> 2] = i21 + 1;
+        i21 = HEAPU8[i21] | 0;
+        continue;
+       } else {
+        i21 = ___shgetc(i8) | 0;
+        continue;
+       }
+      }
+      if ((i19 | 0) == 0) {
+       i2 = (HEAP32[i10 >> 2] | 0) == 0;
+       if (!i2) {
+        HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + -1;
+       }
+       if (!i12) {
+        if (!i2 ? (i6 = HEAP32[i9 >> 2] | 0, HEAP32[i9 >> 2] = i6 + -1, (i18 | 0) != 0) : 0) {
+         HEAP32[i9 >> 2] = i6 + -2;
+        }
+       } else {
+        ___shlim(i8, 0);
+       }
+       d31 = +(i4 | 0) * 0.0;
+       STACKTOP = i1;
+       return +d31;
+      }
+      i13 = (i18 | 0) == 0;
+      i6 = i13 ? i7 : i15;
+      i13 = i13 ? i5 : i16;
+      if ((i5 | 0) < 0 | (i5 | 0) == 0 & i7 >>> 0 < 8) {
+       do {
+        i17 = i17 << 4;
+        i7 = _i64Add(i7 | 0, i5 | 0, 1, 0) | 0;
+        i5 = tempRet0;
+       } while ((i5 | 0) < 0 | (i5 | 0) == 0 & i7 >>> 0 < 8);
+      }
+      do {
+       if ((i21 | 32 | 0) == 112) {
+        i7 = _scanexp(i8, i11) | 0;
+        i5 = tempRet0;
+        if ((i7 | 0) == 0 & (i5 | 0) == -2147483648) {
+         if (i12) {
+          ___shlim(i8, 0);
+          d31 = 0.0;
+          STACKTOP = i1;
+          return +d31;
+         } else {
+          if ((HEAP32[i10 >> 2] | 0) == 0) {
+           i7 = 0;
+           i5 = 0;
+           break;
+          }
+          HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + -1;
+          i7 = 0;
+          i5 = 0;
+          break;
+         }
+        }
+       } else {
+        if ((HEAP32[i10 >> 2] | 0) == 0) {
+         i7 = 0;
+         i5 = 0;
+        } else {
+         HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + -1;
+         i7 = 0;
+         i5 = 0;
+        }
+       }
+      } while (0);
+      i6 = _bitshift64Shl(i6 | 0, i13 | 0, 2) | 0;
+      i6 = _i64Add(i6 | 0, tempRet0 | 0, -32, -1) | 0;
+      i5 = _i64Add(i6 | 0, tempRet0 | 0, i7 | 0, i5 | 0) | 0;
+      i6 = tempRet0;
+      if ((i17 | 0) == 0) {
+       d31 = +(i4 | 0) * 0.0;
+       STACKTOP = i1;
+       return +d31;
+      }
+      if ((i6 | 0) > 0 | (i6 | 0) == 0 & i5 >>> 0 > (0 - i3 | 0) >>> 0) {
+       HEAP32[(___errno_location() | 0) >> 2] = 34;
+       d31 = +(i4 | 0) * 1.7976931348623157e+308 * 1.7976931348623157e+308;
+       STACKTOP = i1;
+       return +d31;
+      }
+      i29 = i3 + -106 | 0;
+      i27 = ((i29 | 0) < 0) << 31 >> 31;
+      if ((i6 | 0) < (i27 | 0) | (i6 | 0) == (i27 | 0) & i5 >>> 0 < i29 >>> 0) {
+       HEAP32[(___errno_location() | 0) >> 2] = 34;
+       d31 = +(i4 | 0) * 2.2250738585072014e-308 * 2.2250738585072014e-308;
+       STACKTOP = i1;
+       return +d31;
+      }
+      if ((i17 | 0) > -1) {
+       do {
+        i17 = i17 << 1;
+        if (!(d14 >= .5)) {
+         d28 = d14;
+        } else {
+         d28 = d14 + -1.0;
+         i17 = i17 | 1;
+        }
+        d14 = d14 + d28;
+        i5 = _i64Add(i5 | 0, i6 | 0, -1, -1) | 0;
+        i6 = tempRet0;
+       } while ((i17 | 0) > -1);
+      }
+      i3 = _i64Subtract(32, 0, i3 | 0, ((i3 | 0) < 0) << 31 >> 31 | 0) | 0;
+      i3 = _i64Add(i5 | 0, i6 | 0, i3 | 0, tempRet0 | 0) | 0;
+      i29 = tempRet0;
+      if (0 > (i29 | 0) | 0 == (i29 | 0) & i2 >>> 0 > i3 >>> 0) {
+       i2 = (i3 | 0) < 0 ? 0 : i3;
+      }
+      if ((i2 | 0) < 53) {
+       d28 = +(i4 | 0);
+       d30 = +_copysign(+(+_scalbn(1.0, 84 - i2 | 0)), +d28);
+       if ((i2 | 0) < 32 & d14 != 0.0) {
+        i29 = i17 & 1;
+        i17 = (i29 ^ 1) + i17 | 0;
+        d14 = (i29 | 0) == 0 ? 0.0 : d14;
+       }
+      } else {
+       d28 = +(i4 | 0);
+       d30 = 0.0;
+      }
+      d14 = d28 * d14 + (d30 + d28 * +(i17 >>> 0)) - d30;
+      if (!(d14 != 0.0)) {
+       HEAP32[(___errno_location() | 0) >> 2] = 34;
+      }
+      d31 = +_scalbnl(d14, i5);
+      STACKTOP = i1;
+      return +d31;
+     }
+    } while (0);
+    i7 = i3 + i2 | 0;
+    i6 = 0 - i7 | 0;
+    i20 = 0;
+    while (1) {
+     if ((i21 | 0) == 46) {
+      i13 = 139;
+      break;
+     } else if ((i21 | 0) != 48) {
+      i25 = 0;
+      i22 = 0;
+      i19 = 0;
+      break;
+     }
+     i15 = HEAP32[i9 >> 2] | 0;
+     if (i15 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+      HEAP32[i9 >> 2] = i15 + 1;
+      i21 = HEAPU8[i15] | 0;
+      i20 = 1;
+      continue;
+     } else {
+      i21 = ___shgetc(i8) | 0;
+      i20 = 1;
+      continue;
+     }
+    }
+    L168 : do {
+     if ((i13 | 0) == 139) {
+      i15 = HEAP32[i9 >> 2] | 0;
+      if (i15 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+       HEAP32[i9 >> 2] = i15 + 1;
+       i21 = HEAPU8[i15] | 0;
+      } else {
+       i21 = ___shgetc(i8) | 0;
+      }
+      if ((i21 | 0) == 48) {
+       i25 = -1;
+       i22 = -1;
+       while (1) {
+        i15 = HEAP32[i9 >> 2] | 0;
+        if (i15 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+         HEAP32[i9 >> 2] = i15 + 1;
+         i21 = HEAPU8[i15] | 0;
+        } else {
+         i21 = ___shgetc(i8) | 0;
+        }
+        if ((i21 | 0) != 48) {
+         i20 = 1;
+         i19 = 1;
+         break L168;
+        }
+        i29 = _i64Add(i25 | 0, i22 | 0, -1, -1) | 0;
+        i25 = i29;
+        i22 = tempRet0;
+       }
+      } else {
+       i25 = 0;
+       i22 = 0;
+       i19 = 1;
+      }
+     }
+    } while (0);
+    HEAP32[i5 >> 2] = 0;
+    i26 = i21 + -48 | 0;
+    i27 = (i21 | 0) == 46;
+    L182 : do {
+     if (i26 >>> 0 < 10 | i27) {
+      i15 = i5 + 496 | 0;
+      i24 = 0;
+      i23 = 0;
+      i18 = 0;
+      i17 = 0;
+      i16 = 0;
+      while (1) {
+       do {
+        if (i27) {
+         if ((i19 | 0) == 0) {
+          i25 = i24;
+          i22 = i23;
+          i19 = 1;
+         } else {
+          break L182;
+         }
+        } else {
+         i27 = _i64Add(i24 | 0, i23 | 0, 1, 0) | 0;
+         i23 = tempRet0;
+         i29 = (i21 | 0) != 48;
+         if ((i17 | 0) >= 125) {
+          if (!i29) {
+           i24 = i27;
+           break;
+          }
+          HEAP32[i15 >> 2] = HEAP32[i15 >> 2] | 1;
+          i24 = i27;
+          break;
+         }
+         i20 = i5 + (i17 << 2) | 0;
+         if ((i18 | 0) != 0) {
+          i26 = i21 + -48 + ((HEAP32[i20 >> 2] | 0) * 10 | 0) | 0;
+         }
+         HEAP32[i20 >> 2] = i26;
+         i18 = i18 + 1 | 0;
+         i21 = (i18 | 0) == 9;
+         i24 = i27;
+         i20 = 1;
+         i18 = i21 ? 0 : i18;
+         i17 = (i21 & 1) + i17 | 0;
+         i16 = i29 ? i27 : i16;
+        }
+       } while (0);
+       i21 = HEAP32[i9 >> 2] | 0;
+       if (i21 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+        HEAP32[i9 >> 2] = i21 + 1;
+        i21 = HEAPU8[i21] | 0;
+       } else {
+        i21 = ___shgetc(i8) | 0;
+       }
+       i26 = i21 + -48 | 0;
+       i27 = (i21 | 0) == 46;
+       if (!(i26 >>> 0 < 10 | i27)) {
+        i13 = 162;
+        break;
+       }
+      }
+     } else {
+      i24 = 0;
+      i23 = 0;
+      i18 = 0;
+      i17 = 0;
+      i16 = 0;
+      i13 = 162;
+     }
+    } while (0);
+    if ((i13 | 0) == 162) {
+     i13 = (i19 | 0) == 0;
+     i25 = i13 ? i24 : i25;
+     i22 = i13 ? i23 : i22;
+    }
+    i13 = (i20 | 0) != 0;
+    if (i13 ? (i21 | 32 | 0) == 101 : 0) {
+     i15 = _scanexp(i8, i11) | 0;
+     i11 = tempRet0;
+     do {
+      if ((i15 | 0) == 0 & (i11 | 0) == -2147483648) {
+       if (i12) {
+        ___shlim(i8, 0);
+        d31 = 0.0;
+        STACKTOP = i1;
+        return +d31;
+       } else {
+        if ((HEAP32[i10 >> 2] | 0) == 0) {
+         i15 = 0;
+         i11 = 0;
+         break;
+        }
+        HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + -1;
+        i15 = 0;
+        i11 = 0;
+        break;
+       }
+      }
+     } while (0);
+     i9 = _i64Add(i15 | 0, i11 | 0, i25 | 0, i22 | 0) | 0;
+     i22 = tempRet0;
+    } else {
+     if ((i21 | 0) > -1 ? (HEAP32[i10 >> 2] | 0) != 0 : 0) {
+      HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + -1;
+      i9 = i25;
+     } else {
+      i9 = i25;
+     }
+    }
+    if (!i13) {
+     HEAP32[(___errno_location() | 0) >> 2] = 22;
+     ___shlim(i8, 0);
+     d31 = 0.0;
+     STACKTOP = i1;
+     return +d31;
+    }
+    i8 = HEAP32[i5 >> 2] | 0;
+    if ((i8 | 0) == 0) {
+     d31 = +(i4 | 0) * 0.0;
+     STACKTOP = i1;
+     return +d31;
+    }
+    do {
+     if ((i9 | 0) == (i24 | 0) & (i22 | 0) == (i23 | 0) & ((i23 | 0) < 0 | (i23 | 0) == 0 & i24 >>> 0 < 10)) {
+      if (!(i2 >>> 0 > 30) ? (i8 >>> i2 | 0) != 0 : 0) {
+       break;
+      }
+      d31 = +(i4 | 0) * +(i8 >>> 0);
+      STACKTOP = i1;
+      return +d31;
+     }
+    } while (0);
+    i29 = (i3 | 0) / -2 | 0;
+    i27 = ((i29 | 0) < 0) << 31 >> 31;
+    if ((i22 | 0) > (i27 | 0) | (i22 | 0) == (i27 | 0) & i9 >>> 0 > i29 >>> 0) {
+     HEAP32[(___errno_location() | 0) >> 2] = 34;
+     d31 = +(i4 | 0) * 1.7976931348623157e+308 * 1.7976931348623157e+308;
+     STACKTOP = i1;
+     return +d31;
+    }
+    i29 = i3 + -106 | 0;
+    i27 = ((i29 | 0) < 0) << 31 >> 31;
+    if ((i22 | 0) < (i27 | 0) | (i22 | 0) == (i27 | 0) & i9 >>> 0 < i29 >>> 0) {
+     HEAP32[(___errno_location() | 0) >> 2] = 34;
+     d31 = +(i4 | 0) * 2.2250738585072014e-308 * 2.2250738585072014e-308;
+     STACKTOP = i1;
+     return +d31;
+    }
+    if ((i18 | 0) != 0) {
+     if ((i18 | 0) < 9) {
+      i8 = i5 + (i17 << 2) | 0;
+      i10 = HEAP32[i8 >> 2] | 0;
+      do {
+       i10 = i10 * 10 | 0;
+       i18 = i18 + 1 | 0;
+      } while ((i18 | 0) != 9);
+      HEAP32[i8 >> 2] = i10;
+     }
+     i17 = i17 + 1 | 0;
+    }
+    do {
+     if ((i16 | 0) < 9 ? (i16 | 0) <= (i9 | 0) & (i9 | 0) < 18 : 0) {
+      if ((i9 | 0) == 9) {
+       d31 = +(i4 | 0) * +((HEAP32[i5 >> 2] | 0) >>> 0);
+       STACKTOP = i1;
+       return +d31;
+      }
+      if ((i9 | 0) < 9) {
+       d31 = +(i4 | 0) * +((HEAP32[i5 >> 2] | 0) >>> 0) / +(HEAP32[13440 + (8 - i9 << 2) >> 2] | 0);
+       STACKTOP = i1;
+       return +d31;
+      }
+      i10 = i2 + 27 + (Math_imul(i9, -3) | 0) | 0;
+      i8 = HEAP32[i5 >> 2] | 0;
+      if ((i10 | 0) <= 30 ? (i8 >>> i10 | 0) != 0 : 0) {
+       break;
+      }
+      d31 = +(i4 | 0) * +(i8 >>> 0) * +(HEAP32[13440 + (i9 + -10 << 2) >> 2] | 0);
+      STACKTOP = i1;
+      return +d31;
+     }
+    } while (0);
+    i8 = (i9 | 0) % 9 | 0;
+    if ((i8 | 0) == 0) {
+     i8 = 0;
+     i10 = 0;
+    } else {
+     i11 = (i9 | 0) > -1 ? i8 : i8 + 9 | 0;
+     i12 = HEAP32[13440 + (8 - i11 << 2) >> 2] | 0;
+     if ((i17 | 0) != 0) {
+      i10 = 1e9 / (i12 | 0) | 0;
+      i8 = 0;
+      i16 = 0;
+      i15 = 0;
+      while (1) {
+       i27 = i5 + (i15 << 2) | 0;
+       i13 = HEAP32[i27 >> 2] | 0;
+       i29 = ((i13 >>> 0) / (i12 >>> 0) | 0) + i16 | 0;
+       HEAP32[i27 >> 2] = i29;
+       i16 = Math_imul((i13 >>> 0) % (i12 >>> 0) | 0, i10) | 0;
+       i13 = i15 + 1 | 0;
+       if ((i15 | 0) == (i8 | 0) & (i29 | 0) == 0) {
+        i8 = i13 & 127;
+        i9 = i9 + -9 | 0;
+       }
+       if ((i13 | 0) == (i17 | 0)) {
+        break;
+       } else {
+        i15 = i13;
+       }
+      }
+      if ((i16 | 0) != 0) {
+       HEAP32[i5 + (i17 << 2) >> 2] = i16;
+       i17 = i17 + 1 | 0;
+      }
+     } else {
+      i8 = 0;
+      i17 = 0;
+     }
+     i10 = 0;
+     i9 = 9 - i11 + i9 | 0;
+    }
+    L280 : while (1) {
+     i11 = i5 + (i8 << 2) | 0;
+     if ((i9 | 0) < 18) {
+      do {
+       i13 = 0;
+       i11 = i17 + 127 | 0;
+       while (1) {
+        i11 = i11 & 127;
+        i12 = i5 + (i11 << 2) | 0;
+        i15 = _bitshift64Shl(HEAP32[i12 >> 2] | 0, 0, 29) | 0;
+        i15 = _i64Add(i15 | 0, tempRet0 | 0, i13 | 0, 0) | 0;
+        i13 = tempRet0;
+        if (i13 >>> 0 > 0 | (i13 | 0) == 0 & i15 >>> 0 > 1e9) {
+         i29 = ___udivdi3(i15 | 0, i13 | 0, 1e9, 0) | 0;
+         i15 = ___uremdi3(i15 | 0, i13 | 0, 1e9, 0) | 0;
+         i13 = i29;
+        } else {
+         i13 = 0;
+        }
+        HEAP32[i12 >> 2] = i15;
+        i12 = (i11 | 0) == (i8 | 0);
+        if (!((i11 | 0) != (i17 + 127 & 127 | 0) | i12)) {
+         i17 = (i15 | 0) == 0 ? i11 : i17;
+        }
+        if (i12) {
+         break;
+        } else {
+         i11 = i11 + -1 | 0;
+        }
+       }
+       i10 = i10 + -29 | 0;
+      } while ((i13 | 0) == 0);
+     } else {
+      if ((i9 | 0) != 18) {
+       break;
+      }
+      do {
+       if (!((HEAP32[i11 >> 2] | 0) >>> 0 < 9007199)) {
+        i9 = 18;
+        break L280;
+       }
+       i13 = 0;
+       i12 = i17 + 127 | 0;
+       while (1) {
+        i12 = i12 & 127;
+        i15 = i5 + (i12 << 2) | 0;
+        i16 = _bitshift64Shl(HEAP32[i15 >> 2] | 0, 0, 29) | 0;
+        i16 = _i64Add(i16 | 0, tempRet0 | 0, i13 | 0, 0) | 0;
+        i13 = tempRet0;
+        if (i13 >>> 0 > 0 | (i13 | 0) == 0 & i16 >>> 0 > 1e9) {
+         i29 = ___udivdi3(i16 | 0, i13 | 0, 1e9, 0) | 0;
+         i16 = ___uremdi3(i16 | 0, i13 | 0, 1e9, 0) | 0;
+         i13 = i29;
+        } else {
+         i13 = 0;
+        }
+        HEAP32[i15 >> 2] = i16;
+        i15 = (i12 | 0) == (i8 | 0);
+        if (!((i12 | 0) != (i17 + 127 & 127 | 0) | i15)) {
+         i17 = (i16 | 0) == 0 ? i12 : i17;
+        }
+        if (i15) {
+         break;
+        } else {
+         i12 = i12 + -1 | 0;
+        }
+       }
+       i10 = i10 + -29 | 0;
+      } while ((i13 | 0) == 0);
+     }
+     i8 = i8 + 127 & 127;
+     if ((i8 | 0) == (i17 | 0)) {
+      i29 = i17 + 127 & 127;
+      i17 = i5 + ((i17 + 126 & 127) << 2) | 0;
+      HEAP32[i17 >> 2] = HEAP32[i17 >> 2] | HEAP32[i5 + (i29 << 2) >> 2];
+      i17 = i29;
+     }
+     HEAP32[i5 + (i8 << 2) >> 2] = i13;
+     i9 = i9 + 9 | 0;
+    }
+    L311 : while (1) {
+     i11 = i17 + 1 & 127;
+     i12 = i5 + ((i17 + 127 & 127) << 2) | 0;
+     while (1) {
+      i15 = (i9 | 0) == 18;
+      i13 = (i9 | 0) > 27 ? 9 : 1;
+      while (1) {
+       i16 = 0;
+       while (1) {
+        i18 = i16 + i8 & 127;
+        if ((i18 | 0) == (i17 | 0)) {
+         i16 = 2;
+         break;
+        }
+        i18 = HEAP32[i5 + (i18 << 2) >> 2] | 0;
+        i19 = HEAP32[13432 + (i16 << 2) >> 2] | 0;
+        if (i18 >>> 0 < i19 >>> 0) {
+         i16 = 2;
+         break;
+        }
+        i20 = i16 + 1 | 0;
+        if (i18 >>> 0 > i19 >>> 0) {
+         break;
+        }
+        if ((i20 | 0) < 2) {
+         i16 = i20;
+        } else {
+         i16 = i20;
+         break;
+        }
+       }
+       if ((i16 | 0) == 2 & i15) {
+        break L311;
+       }
+       i10 = i13 + i10 | 0;
+       if ((i8 | 0) == (i17 | 0)) {
+        i8 = i17;
+       } else {
+        break;
+       }
+      }
+      i15 = (1 << i13) + -1 | 0;
+      i19 = 1e9 >>> i13;
+      i18 = i8;
+      i16 = 0;
+      do {
+       i27 = i5 + (i8 << 2) | 0;
+       i29 = HEAP32[i27 >> 2] | 0;
+       i20 = (i29 >>> i13) + i16 | 0;
+       HEAP32[i27 >> 2] = i20;
+       i16 = Math_imul(i29 & i15, i19) | 0;
+       i20 = (i8 | 0) == (i18 | 0) & (i20 | 0) == 0;
+       i8 = i8 + 1 & 127;
+       i9 = i20 ? i9 + -9 | 0 : i9;
+       i18 = i20 ? i8 : i18;
+      } while ((i8 | 0) != (i17 | 0));
+      if ((i16 | 0) == 0) {
+       i8 = i18;
+       continue;
+      }
+      if ((i11 | 0) != (i18 | 0)) {
+       break;
+      }
+      HEAP32[i12 >> 2] = HEAP32[i12 >> 2] | 1;
+      i8 = i18;
+     }
+     HEAP32[i5 + (i17 << 2) >> 2] = i16;
+     i8 = i18;
+     i17 = i11;
+    }
+    i9 = i8 & 127;
+    if ((i9 | 0) == (i17 | 0)) {
+     HEAP32[i5 + (i11 + -1 << 2) >> 2] = 0;
+     i17 = i11;
+    }
+    d28 = +((HEAP32[i5 + (i9 << 2) >> 2] | 0) >>> 0);
+    i9 = i8 + 1 & 127;
+    if ((i9 | 0) == (i17 | 0)) {
+     i17 = i17 + 1 & 127;
+     HEAP32[i5 + (i17 + -1 << 2) >> 2] = 0;
+    }
+    d14 = +(i4 | 0);
+    d30 = d14 * (d28 * 1.0e9 + +((HEAP32[i5 + (i9 << 2) >> 2] | 0) >>> 0));
+    i4 = i10 + 53 | 0;
+    i3 = i4 - i3 | 0;
+    if ((i3 | 0) < (i2 | 0)) {
+     i2 = (i3 | 0) < 0 ? 0 : i3;
+     i9 = 1;
+    } else {
+     i9 = 0;
+    }
+    if ((i2 | 0) < 53) {
+     d33 = +_copysign(+(+_scalbn(1.0, 105 - i2 | 0)), +d30);
+     d32 = +_fmod(+d30, +(+_scalbn(1.0, 53 - i2 | 0)));
+     d28 = d33;
+     d31 = d32;
+     d30 = d33 + (d30 - d32);
+    } else {
+     d28 = 0.0;
+     d31 = 0.0;
+    }
+    i11 = i8 + 2 & 127;
+    if ((i11 | 0) != (i17 | 0)) {
+     i5 = HEAP32[i5 + (i11 << 2) >> 2] | 0;
+     do {
+      if (!(i5 >>> 0 < 5e8)) {
+       if (i5 >>> 0 > 5e8) {
+        d31 = d14 * .75 + d31;
+        break;
+       }
+       if ((i8 + 3 & 127 | 0) == (i17 | 0)) {
+        d31 = d14 * .5 + d31;
+        break;
+       } else {
+        d31 = d14 * .75 + d31;
+        break;
+       }
+      } else {
+       if ((i5 | 0) == 0 ? (i8 + 3 & 127 | 0) == (i17 | 0) : 0) {
+        break;
+       }
+       d31 = d14 * .25 + d31;
+      }
+     } while (0);
+     if ((53 - i2 | 0) > 1 ? !(+_fmod(+d31, 1.0) != 0.0) : 0) {
+      d31 = d31 + 1.0;
+     }
+    }
+    d14 = d30 + d31 - d28;
+    do {
+     if ((i4 & 2147483647 | 0) > (-2 - i7 | 0)) {
+      if (+Math_abs(+d14) >= 9007199254740992.0) {
+       i9 = (i9 | 0) != 0 & (i2 | 0) == (i3 | 0) ? 0 : i9;
+       i10 = i10 + 1 | 0;
+       d14 = d14 * .5;
+      }
+      if ((i10 + 50 | 0) <= (i6 | 0) ? !((i9 | 0) != 0 & d31 != 0.0) : 0) {
+       break;
+      }
+      HEAP32[(___errno_location() | 0) >> 2] = 34;
+     }
+    } while (0);
+    d33 = +_scalbnl(d14, i10);
+    STACKTOP = i1;
+    return +d33;
+   } else if ((i7 | 0) == 3) {
+    i2 = HEAP32[i9 >> 2] | 0;
+    if (i2 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+     HEAP32[i9 >> 2] = i2 + 1;
+     i2 = HEAPU8[i2] | 0;
+    } else {
+     i2 = ___shgetc(i8) | 0;
+    }
+    if ((i2 | 0) == 40) {
+     i2 = 1;
+    } else {
+     if ((HEAP32[i10 >> 2] | 0) == 0) {
+      d33 = nan;
+      STACKTOP = i1;
+      return +d33;
+     }
+     HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + -1;
+     d33 = nan;
+     STACKTOP = i1;
+     return +d33;
+    }
+    while (1) {
+     i3 = HEAP32[i9 >> 2] | 0;
+     if (i3 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0) {
+      HEAP32[i9 >> 2] = i3 + 1;
+      i3 = HEAPU8[i3] | 0;
+     } else {
+      i3 = ___shgetc(i8) | 0;
+     }
+     if (!((i3 + -48 | 0) >>> 0 < 10 | (i3 + -65 | 0) >>> 0 < 26) ? !((i3 + -97 | 0) >>> 0 < 26 | (i3 | 0) == 95) : 0) {
+      break;
+     }
+     i2 = i2 + 1 | 0;
+    }
+    if ((i3 | 0) == 41) {
+     d33 = nan;
+     STACKTOP = i1;
+     return +d33;
+    }
+    i3 = (HEAP32[i10 >> 2] | 0) == 0;
+    if (!i3) {
+     HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + -1;
+    }
+    if (i12) {
+     HEAP32[(___errno_location() | 0) >> 2] = 22;
+     ___shlim(i8, 0);
+     d33 = 0.0;
+     STACKTOP = i1;
+     return +d33;
+    }
+    if ((i2 | 0) == 0 | i3) {
+     d33 = nan;
+     STACKTOP = i1;
+     return +d33;
+    }
+    while (1) {
+     i2 = i2 + -1 | 0;
+     HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + -1;
+     if ((i2 | 0) == 0) {
+      d14 = nan;
+      break;
+     }
+    }
+    STACKTOP = i1;
+    return +d14;
+   } else {
+    if ((HEAP32[i10 >> 2] | 0) != 0) {
+     HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + -1;
+    }
+    HEAP32[(___errno_location() | 0) >> 2] = 22;
+    ___shlim(i8, 0);
+    d33 = 0.0;
+    STACKTOP = i1;
+    return +d33;
+   }
+  }
+ } while (0);
+ if ((i13 | 0) == 23) {
+  i2 = (HEAP32[i10 >> 2] | 0) == 0;
+  if (!i2) {
+   HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + -1;
+  }
+  if (!(i7 >>> 0 < 4 | (i11 | 0) == 0 | i2)) {
+   do {
+    HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + -1;
+    i7 = i7 + -1 | 0;
+   } while (i7 >>> 0 > 3);
+  }
+ }
+ d33 = +(i4 | 0) * inf;
+ STACKTOP = i1;
+ return +d33;
+}
+function _statement(i4) {
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 160 | 0;
+ i8 = i2 + 120 | 0;
+ i24 = i2 + 96 | 0;
+ i15 = i2 + 72 | 0;
+ i25 = i2 + 48 | 0;
+ i20 = i2 + 24 | 0;
+ i21 = i2;
+ i19 = i4 + 4 | 0;
+ i6 = HEAP32[i19 >> 2] | 0;
+ i3 = i4 + 48 | 0;
+ i9 = HEAP32[i3 >> 2] | 0;
+ i1 = i4 + 52 | 0;
+ i26 = (HEAP32[i1 >> 2] | 0) + 38 | 0;
+ i27 = (HEAP16[i26 >> 1] | 0) + 1 << 16 >> 16;
+ HEAP16[i26 >> 1] = i27;
+ if ((i27 & 65535) > 200) {
+  i27 = i9 + 12 | 0;
+  i26 = HEAP32[(HEAP32[i27 >> 2] | 0) + 52 >> 2] | 0;
+  i5 = HEAP32[(HEAP32[i9 >> 2] | 0) + 64 >> 2] | 0;
+  if ((i5 | 0) == 0) {
+   i29 = 6552;
+   HEAP32[i8 >> 2] = 6360;
+   i28 = i8 + 4 | 0;
+   HEAP32[i28 >> 2] = 200;
+   i28 = i8 + 8 | 0;
+   HEAP32[i28 >> 2] = i29;
+   i28 = _luaO_pushfstring(i26, 6592, i8) | 0;
+   i29 = HEAP32[i27 >> 2] | 0;
+   _luaX_syntaxerror(i29, i28);
+  }
+  HEAP32[i8 >> 2] = i5;
+  i28 = _luaO_pushfstring(i26, 6568, i8) | 0;
+  HEAP32[i8 >> 2] = 6360;
+  i29 = i8 + 4 | 0;
+  HEAP32[i29 >> 2] = 200;
+  i29 = i8 + 8 | 0;
+  HEAP32[i29 >> 2] = i28;
+  i29 = _luaO_pushfstring(i26, 6592, i8) | 0;
+  i28 = HEAP32[i27 >> 2] | 0;
+  _luaX_syntaxerror(i28, i29);
+ }
+ i5 = i4 + 16 | 0;
+ L8 : do {
+  switch (HEAP32[i5 >> 2] | 0) {
+  case 59:
+   {
+    _luaX_next(i4);
+    break;
+   }
+  case 267:
+   {
+    HEAP32[i21 >> 2] = -1;
+    _test_then_block(i4, i21);
+    while (1) {
+     i8 = HEAP32[i5 >> 2] | 0;
+     if ((i8 | 0) == 260) {
+      i7 = 10;
+      break;
+     } else if ((i8 | 0) != 261) {
+      break;
+     }
+     _test_then_block(i4, i21);
+    }
+    if ((i7 | 0) == 10) {
+     _luaX_next(i4);
+     i7 = HEAP32[i3 >> 2] | 0;
+     HEAP8[i20 + 10 | 0] = 0;
+     HEAP8[i20 + 8 | 0] = HEAP8[i7 + 46 | 0] | 0;
+     i29 = HEAP32[(HEAP32[i7 + 12 >> 2] | 0) + 64 >> 2] | 0;
+     HEAP16[i20 + 4 >> 1] = HEAP32[i29 + 28 >> 2];
+     HEAP16[i20 + 6 >> 1] = HEAP32[i29 + 16 >> 2];
+     HEAP8[i20 + 9 | 0] = 0;
+     i29 = i7 + 16 | 0;
+     HEAP32[i20 >> 2] = HEAP32[i29 >> 2];
+     HEAP32[i29 >> 2] = i20;
+     L16 : do {
+      i8 = HEAP32[i5 >> 2] | 0;
+      switch (i8 | 0) {
+      case 277:
+      case 286:
+      case 262:
+      case 261:
+      case 260:
+       {
+        break L16;
+       }
+      default:
+       {}
+      }
+      _statement(i4);
+     } while ((i8 | 0) != 274);
+     _leaveblock(i7);
+    }
+    _check_match(i4, 262, 267, i6);
+    _luaK_patchtohere(i9, HEAP32[i21 >> 2] | 0);
+    break;
+   }
+  case 259:
+   {
+    _luaX_next(i4);
+    i7 = HEAP32[i3 >> 2] | 0;
+    HEAP8[i20 + 10 | 0] = 0;
+    HEAP8[i20 + 8 | 0] = HEAP8[i7 + 46 | 0] | 0;
+    i29 = HEAP32[(HEAP32[i7 + 12 >> 2] | 0) + 64 >> 2] | 0;
+    HEAP16[i20 + 4 >> 1] = HEAP32[i29 + 28 >> 2];
+    HEAP16[i20 + 6 >> 1] = HEAP32[i29 + 16 >> 2];
+    HEAP8[i20 + 9 | 0] = 0;
+    i29 = i7 + 16 | 0;
+    HEAP32[i20 >> 2] = HEAP32[i29 >> 2];
+    HEAP32[i29 >> 2] = i20;
+    L22 : do {
+     i8 = HEAP32[i5 >> 2] | 0;
+     switch (i8 | 0) {
+     case 277:
+     case 286:
+     case 262:
+     case 261:
+     case 260:
+      {
+       break L22;
+      }
+     default:
+      {}
+     }
+     _statement(i4);
+    } while ((i8 | 0) != 274);
+    _leaveblock(i7);
+    _check_match(i4, 262, 259, i6);
+    break;
+   }
+  case 269:
+   {
+    _luaX_next(i4);
+    i6 = HEAP32[i5 >> 2] | 0;
+    if ((i6 | 0) == 265) {
+     _luaX_next(i4);
+     i7 = HEAP32[i3 >> 2] | 0;
+     if ((HEAP32[i5 >> 2] | 0) == 288) {
+      i29 = HEAP32[i4 + 24 >> 2] | 0;
+      _luaX_next(i4);
+      _new_localvar(i4, i29);
+      i29 = HEAP32[i3 >> 2] | 0;
+      i27 = i29 + 46 | 0;
+      i28 = (HEAPU8[i27] | 0) + 1 | 0;
+      HEAP8[i27] = i28;
+      HEAP32[(HEAP32[(HEAP32[i29 >> 2] | 0) + 24 >> 2] | 0) + ((HEAP16[(HEAP32[HEAP32[(HEAP32[i29 + 12 >> 2] | 0) + 64 >> 2] >> 2] | 0) + ((i28 & 255) + -1 + (HEAP32[i29 + 40 >> 2] | 0) << 1) >> 1] | 0) * 12 | 0) + 4 >> 2] = HEAP32[i29 + 20 >> 2];
+      _body(i4, i25, 0, HEAP32[i19 >> 2] | 0);
+      HEAP32[(HEAP32[(HEAP32[i7 >> 2] | 0) + 24 >> 2] | 0) + ((HEAP16[(HEAP32[HEAP32[(HEAP32[i7 + 12 >> 2] | 0) + 64 >> 2] >> 2] | 0) + ((HEAP32[i7 + 40 >> 2] | 0) + (HEAP32[i25 + 8 >> 2] | 0) << 1) >> 1] | 0) * 12 | 0) + 4 >> 2] = HEAP32[i7 + 20 >> 2];
+      break L8;
+     } else {
+      _error_expected(i4, 288);
+     }
+    }
+    if ((i6 | 0) != 288) {
+     _error_expected(i4, 288);
+    }
+    i7 = i4 + 24 | 0;
+    i6 = 1;
+    while (1) {
+     i8 = HEAP32[i7 >> 2] | 0;
+     _luaX_next(i4);
+     _new_localvar(i4, i8);
+     i8 = HEAP32[i5 >> 2] | 0;
+     if ((i8 | 0) == 61) {
+      i7 = 81;
+      break;
+     } else if ((i8 | 0) != 44) {
+      i7 = 83;
+      break;
+     }
+     _luaX_next(i4);
+     if ((HEAP32[i5 >> 2] | 0) == 288) {
+      i6 = i6 + 1 | 0;
+     } else {
+      i7 = 78;
+      break;
+     }
+    }
+    do {
+     if ((i7 | 0) == 78) {
+      _error_expected(i4, 288);
+     } else if ((i7 | 0) == 81) {
+      _luaX_next(i4);
+      _subexpr(i4, i15, 0) | 0;
+      if ((HEAP32[i5 >> 2] | 0) == 44) {
+       i8 = 1;
+       do {
+        _luaX_next(i4);
+        _luaK_exp2nextreg(HEAP32[i3 >> 2] | 0, i15);
+        _subexpr(i4, i15, 0) | 0;
+        i8 = i8 + 1 | 0;
+       } while ((HEAP32[i5 >> 2] | 0) == 44);
+      } else {
+       i8 = 1;
+      }
+      i5 = HEAP32[i15 >> 2] | 0;
+      i4 = HEAP32[i3 >> 2] | 0;
+      i8 = i6 - i8 | 0;
+      if ((i5 | 0) == 0) {
+       i17 = i8;
+       i18 = i4;
+       i7 = 88;
+       break;
+      } else if (!((i5 | 0) == 13 | (i5 | 0) == 12)) {
+       _luaK_exp2nextreg(i4, i15);
+       i17 = i8;
+       i18 = i4;
+       i7 = 88;
+       break;
+      }
+      i5 = i8 + 1 | 0;
+      i5 = (i5 | 0) < 0 ? 0 : i5;
+      _luaK_setreturns(i4, i15, i5);
+      if ((i5 | 0) > 1) {
+       _luaK_reserveregs(i4, i5 + -1 | 0);
+      }
+     } else if ((i7 | 0) == 83) {
+      HEAP32[i15 >> 2] = 0;
+      i17 = i6;
+      i18 = HEAP32[i3 >> 2] | 0;
+      i7 = 88;
+     }
+    } while (0);
+    if ((i7 | 0) == 88 ? (i17 | 0) > 0 : 0) {
+     i29 = HEAPU8[i18 + 48 | 0] | 0;
+     _luaK_reserveregs(i18, i17);
+     _luaK_nil(i18, i29, i17);
+    }
+    i5 = HEAP32[i3 >> 2] | 0;
+    i4 = i5 + 46 | 0;
+    i7 = (HEAPU8[i4] | 0) + i6 | 0;
+    HEAP8[i4] = i7;
+    if ((i6 | 0) != 0 ? (i11 = i5 + 20 | 0, i14 = i5 + 40 | 0, i12 = HEAP32[(HEAP32[i5 >> 2] | 0) + 24 >> 2] | 0, i13 = HEAP32[HEAP32[(HEAP32[i5 + 12 >> 2] | 0) + 64 >> 2] >> 2] | 0, HEAP32[i12 + ((HEAP16[i13 + ((i7 & 255) - i6 + (HEAP32[i14 >> 2] | 0) << 1) >> 1] | 0) * 12 | 0) + 4 >> 2] = HEAP32[i11 >> 2], i16 = i6 + -1 | 0, (i16 | 0) != 0) : 0) {
+     do {
+      HEAP32[i12 + ((HEAP16[i13 + ((HEAPU8[i4] | 0) - i16 + (HEAP32[i14 >> 2] | 0) << 1) >> 1] | 0) * 12 | 0) + 4 >> 2] = HEAP32[i11 >> 2];
+      i16 = i16 + -1 | 0;
+     } while ((i16 | 0) != 0);
+    }
+    break;
+   }
+  case 264:
+   {
+    HEAP8[i24 + 10 | 0] = 1;
+    HEAP8[i24 + 8 | 0] = HEAP8[i9 + 46 | 0] | 0;
+    i29 = HEAP32[(HEAP32[i9 + 12 >> 2] | 0) + 64 >> 2] | 0;
+    HEAP16[i24 + 4 >> 1] = HEAP32[i29 + 28 >> 2];
+    HEAP16[i24 + 6 >> 1] = HEAP32[i29 + 16 >> 2];
+    HEAP8[i24 + 9 | 0] = 0;
+    i29 = i9 + 16 | 0;
+    HEAP32[i24 >> 2] = HEAP32[i29 >> 2];
+    HEAP32[i29 >> 2] = i24;
+    _luaX_next(i4);
+    if ((HEAP32[i5 >> 2] | 0) != 288) {
+     _error_expected(i4, 288);
+    }
+    i14 = i4 + 24 | 0;
+    i13 = HEAP32[i14 >> 2] | 0;
+    _luaX_next(i4);
+    i11 = HEAP32[i5 >> 2] | 0;
+    if ((i11 | 0) == 268 | (i11 | 0) == 44) {
+     i12 = HEAP32[i3 >> 2] | 0;
+     i11 = HEAPU8[i12 + 48 | 0] | 0;
+     _new_localvar(i4, _luaX_newstring(i4, 6744, 15) | 0);
+     _new_localvar(i4, _luaX_newstring(i4, 6760, 11) | 0);
+     _new_localvar(i4, _luaX_newstring(i4, 6776, 13) | 0);
+     _new_localvar(i4, i13);
+     i13 = HEAP32[i5 >> 2] | 0;
+     do {
+      if ((i13 | 0) == 44) {
+       i15 = 4;
+       while (1) {
+        _luaX_next(i4);
+        if ((HEAP32[i5 >> 2] | 0) != 288) {
+         i7 = 40;
+         break;
+        }
+        i13 = HEAP32[i14 >> 2] | 0;
+        _luaX_next(i4);
+        _new_localvar(i4, i13);
+        i13 = HEAP32[i5 >> 2] | 0;
+        if ((i13 | 0) == 44) {
+         i15 = i15 + 1 | 0;
+        } else {
+         i7 = 42;
+         break;
+        }
+       }
+       if ((i7 | 0) == 40) {
+        _error_expected(i4, 288);
+       } else if ((i7 | 0) == 42) {
+        i22 = i13;
+        i10 = i15 + -2 | 0;
+        break;
+       }
+      } else {
+       i22 = i13;
+       i10 = 1;
+      }
+     } while (0);
+     if ((i22 | 0) != 268) {
+      _error_expected(i4, 268);
+     }
+     _luaX_next(i4);
+     i13 = HEAP32[i19 >> 2] | 0;
+     _subexpr(i4, i8, 0) | 0;
+     if ((HEAP32[i5 >> 2] | 0) == 44) {
+      i14 = 1;
+      do {
+       _luaX_next(i4);
+       _luaK_exp2nextreg(HEAP32[i3 >> 2] | 0, i8);
+       _subexpr(i4, i8, 0) | 0;
+       i14 = i14 + 1 | 0;
+      } while ((HEAP32[i5 >> 2] | 0) == 44);
+     } else {
+      i14 = 1;
+     }
+     i5 = HEAP32[i3 >> 2] | 0;
+     i14 = 3 - i14 | 0;
+     i15 = HEAP32[i8 >> 2] | 0;
+     if ((i15 | 0) == 0) {
+      i7 = 51;
+     } else if ((i15 | 0) == 13 | (i15 | 0) == 12) {
+      i15 = i14 + 1 | 0;
+      i15 = (i15 | 0) < 0 ? 0 : i15;
+      _luaK_setreturns(i5, i8, i15);
+      if ((i15 | 0) > 1) {
+       _luaK_reserveregs(i5, i15 + -1 | 0);
+      }
+     } else {
+      _luaK_exp2nextreg(i5, i8);
+      i7 = 51;
+     }
+     if ((i7 | 0) == 51 ? (i14 | 0) > 0 : 0) {
+      i29 = HEAPU8[i5 + 48 | 0] | 0;
+      _luaK_reserveregs(i5, i14);
+      _luaK_nil(i5, i29, i14);
+     }
+     _luaK_checkstack(i12, 3);
+     _forbody(i4, i11, i13, i10, 0);
+    } else if ((i11 | 0) == 61) {
+     i11 = HEAP32[i3 >> 2] | 0;
+     i7 = i11 + 48 | 0;
+     i10 = HEAPU8[i7] | 0;
+     _new_localvar(i4, _luaX_newstring(i4, 6792, 11) | 0);
+     _new_localvar(i4, _luaX_newstring(i4, 6808, 11) | 0);
+     _new_localvar(i4, _luaX_newstring(i4, 6824, 10) | 0);
+     _new_localvar(i4, i13);
+     if ((HEAP32[i5 >> 2] | 0) != 61) {
+      _error_expected(i4, 61);
+     }
+     _luaX_next(i4);
+     _subexpr(i4, i8, 0) | 0;
+     _luaK_exp2nextreg(HEAP32[i3 >> 2] | 0, i8);
+     if ((HEAP32[i5 >> 2] | 0) != 44) {
+      _error_expected(i4, 44);
+     }
+     _luaX_next(i4);
+     _subexpr(i4, i8, 0) | 0;
+     _luaK_exp2nextreg(HEAP32[i3 >> 2] | 0, i8);
+     if ((HEAP32[i5 >> 2] | 0) == 44) {
+      _luaX_next(i4);
+      _subexpr(i4, i8, 0) | 0;
+      _luaK_exp2nextreg(HEAP32[i3 >> 2] | 0, i8);
+     } else {
+      i29 = HEAPU8[i7] | 0;
+      _luaK_codek(i11, i29, _luaK_numberK(i11, 1.0) | 0) | 0;
+      _luaK_reserveregs(i11, 1);
+     }
+     _forbody(i4, i10, i6, 1, 1);
+    } else {
+     _luaX_syntaxerror(i4, 6720);
+    }
+    _check_match(i4, 262, 264, i6);
+    _leaveblock(i9);
+    break;
+   }
+  case 265:
+   {
+    _luaX_next(i4);
+    if ((HEAP32[i5 >> 2] | 0) != 288) {
+     _error_expected(i4, 288);
+    }
+    i8 = HEAP32[i4 + 24 >> 2] | 0;
+    _luaX_next(i4);
+    i9 = HEAP32[i3 >> 2] | 0;
+    if ((_singlevaraux(i9, i8, i20, 1) | 0) == 0) {
+     _singlevaraux(i9, HEAP32[i4 + 72 >> 2] | 0, i20, 1) | 0;
+     i29 = _luaK_stringK(HEAP32[i3 >> 2] | 0, i8) | 0;
+     HEAP32[i25 + 16 >> 2] = -1;
+     HEAP32[i25 + 20 >> 2] = -1;
+     HEAP32[i25 >> 2] = 4;
+     HEAP32[i25 + 8 >> 2] = i29;
+     _luaK_indexed(i9, i20, i25);
+    }
+    while (1) {
+     i8 = HEAP32[i5 >> 2] | 0;
+     if ((i8 | 0) == 58) {
+      i7 = 70;
+      break;
+     } else if ((i8 | 0) != 46) {
+      i5 = 0;
+      break;
+     }
+     _fieldsel(i4, i20);
+    }
+    if ((i7 | 0) == 70) {
+     _fieldsel(i4, i20);
+     i5 = 1;
+    }
+    _body(i4, i21, i5, i6);
+    _luaK_storevar(HEAP32[i3 >> 2] | 0, i20, i21);
+    _luaK_fixline(HEAP32[i3 >> 2] | 0, i6);
+    break;
+   }
+  case 278:
+   {
+    _luaX_next(i4);
+    i7 = _luaK_getlabel(i9) | 0;
+    _subexpr(i4, i20, 0) | 0;
+    if ((HEAP32[i20 >> 2] | 0) == 1) {
+     HEAP32[i20 >> 2] = 3;
+    }
+    _luaK_goiftrue(HEAP32[i3 >> 2] | 0, i20);
+    i8 = HEAP32[i20 + 20 >> 2] | 0;
+    HEAP8[i21 + 10 | 0] = 1;
+    HEAP8[i21 + 8 | 0] = HEAP8[i9 + 46 | 0] | 0;
+    i29 = HEAP32[(HEAP32[i9 + 12 >> 2] | 0) + 64 >> 2] | 0;
+    HEAP16[i21 + 4 >> 1] = HEAP32[i29 + 28 >> 2];
+    HEAP16[i21 + 6 >> 1] = HEAP32[i29 + 16 >> 2];
+    HEAP8[i21 + 9 | 0] = 0;
+    i29 = i9 + 16 | 0;
+    HEAP32[i21 >> 2] = HEAP32[i29 >> 2];
+    HEAP32[i29 >> 2] = i21;
+    if ((HEAP32[i5 >> 2] | 0) != 259) {
+     _error_expected(i4, 259);
+    }
+    _luaX_next(i4);
+    i10 = HEAP32[i3 >> 2] | 0;
+    HEAP8[i20 + 10 | 0] = 0;
+    HEAP8[i20 + 8 | 0] = HEAP8[i10 + 46 | 0] | 0;
+    i29 = HEAP32[(HEAP32[i10 + 12 >> 2] | 0) + 64 >> 2] | 0;
+    HEAP16[i20 + 4 >> 1] = HEAP32[i29 + 28 >> 2];
+    HEAP16[i20 + 6 >> 1] = HEAP32[i29 + 16 >> 2];
+    HEAP8[i20 + 9 | 0] = 0;
+    i29 = i10 + 16 | 0;
+    HEAP32[i20 >> 2] = HEAP32[i29 >> 2];
+    HEAP32[i29 >> 2] = i20;
+    L119 : do {
+     i11 = HEAP32[i5 >> 2] | 0;
+     switch (i11 | 0) {
+     case 277:
+     case 286:
+     case 262:
+     case 261:
+     case 260:
+      {
+       break L119;
+      }
+     default:
+      {}
+     }
+     _statement(i4);
+    } while ((i11 | 0) != 274);
+    _leaveblock(i10);
+    _luaK_patchlist(i9, _luaK_jump(i9) | 0, i7);
+    _check_match(i4, 262, 278, i6);
+    _leaveblock(i9);
+    _luaK_patchtohere(i9, i8);
+    break;
+   }
+  case 273:
+   {
+    i7 = _luaK_getlabel(i9) | 0;
+    HEAP8[i24 + 10 | 0] = 1;
+    i28 = i9 + 46 | 0;
+    HEAP8[i24 + 8 | 0] = HEAP8[i28] | 0;
+    i11 = i9 + 12 | 0;
+    i29 = HEAP32[(HEAP32[i11 >> 2] | 0) + 64 >> 2] | 0;
+    HEAP16[i24 + 4 >> 1] = HEAP32[i29 + 28 >> 2];
+    HEAP16[i24 + 6 >> 1] = HEAP32[i29 + 16 >> 2];
+    HEAP8[i24 + 9 | 0] = 0;
+    i29 = i9 + 16 | 0;
+    HEAP32[i24 >> 2] = HEAP32[i29 >> 2];
+    HEAP32[i29 >> 2] = i24;
+    HEAP8[i15 + 10 | 0] = 0;
+    i10 = i15 + 8 | 0;
+    HEAP8[i10] = HEAP8[i28] | 0;
+    i11 = HEAP32[(HEAP32[i11 >> 2] | 0) + 64 >> 2] | 0;
+    HEAP16[i15 + 4 >> 1] = HEAP32[i11 + 28 >> 2];
+    HEAP16[i15 + 6 >> 1] = HEAP32[i11 + 16 >> 2];
+    i11 = i15 + 9 | 0;
+    HEAP8[i11] = 0;
+    HEAP32[i15 >> 2] = HEAP32[i29 >> 2];
+    HEAP32[i29 >> 2] = i15;
+    _luaX_next(i4);
+    L124 : do {
+     i12 = HEAP32[i5 >> 2] | 0;
+     switch (i12 | 0) {
+     case 277:
+     case 286:
+     case 262:
+     case 261:
+     case 260:
+      {
+       break L124;
+      }
+     default:
+      {}
+     }
+     _statement(i4);
+    } while ((i12 | 0) != 274);
+    _check_match(i4, 277, 273, i6);
+    _subexpr(i4, i8, 0) | 0;
+    if ((HEAP32[i8 >> 2] | 0) == 1) {
+     HEAP32[i8 >> 2] = 3;
+    }
+    _luaK_goiftrue(HEAP32[i3 >> 2] | 0, i8);
+    i4 = HEAP32[i8 + 20 >> 2] | 0;
+    if ((HEAP8[i11] | 0) != 0) {
+     _luaK_patchclose(i9, i4, HEAPU8[i10] | 0);
+    }
+    _leaveblock(i9);
+    _luaK_patchlist(i9, i4, i7);
+    _leaveblock(i9);
+    break;
+   }
+  case 285:
+   {
+    _luaX_next(i4);
+    if ((HEAP32[i5 >> 2] | 0) != 288) {
+     _error_expected(i4, 288);
+    }
+    i10 = HEAP32[i4 + 24 >> 2] | 0;
+    _luaX_next(i4);
+    i15 = HEAP32[i3 >> 2] | 0;
+    i9 = i4 + 64 | 0;
+    i14 = HEAP32[i9 >> 2] | 0;
+    i12 = i14 + 24 | 0;
+    i11 = i15 + 16 | 0;
+    i16 = HEAP16[(HEAP32[i11 >> 2] | 0) + 4 >> 1] | 0;
+    i13 = i14 + 28 | 0;
+    L138 : do {
+     if ((i16 | 0) < (HEAP32[i13 >> 2] | 0)) {
+      while (1) {
+       i17 = i16 + 1 | 0;
+       if ((_luaS_eqstr(i10, HEAP32[(HEAP32[i12 >> 2] | 0) + (i16 << 4) >> 2] | 0) | 0) != 0) {
+        break;
+       }
+       if ((i17 | 0) < (HEAP32[i13 >> 2] | 0)) {
+        i16 = i17;
+       } else {
+        break L138;
+       }
+      }
+      i28 = i15 + 12 | 0;
+      i29 = HEAP32[(HEAP32[i28 >> 2] | 0) + 52 >> 2] | 0;
+      i27 = HEAP32[(HEAP32[i12 >> 2] | 0) + (i16 << 4) + 8 >> 2] | 0;
+      HEAP32[i8 >> 2] = i10 + 16;
+      HEAP32[i8 + 4 >> 2] = i27;
+      i29 = _luaO_pushfstring(i29, 6680, i8) | 0;
+      _semerror(HEAP32[i28 >> 2] | 0, i29);
+     }
+    } while (0);
+    if ((HEAP32[i5 >> 2] | 0) != 285) {
+     _error_expected(i4, 285);
+    }
+    _luaX_next(i4);
+    i8 = HEAP32[i15 + 20 >> 2] | 0;
+    i15 = HEAP32[i13 >> 2] | 0;
+    i14 = i14 + 32 | 0;
+    if ((i15 | 0) < (HEAP32[i14 >> 2] | 0)) {
+     i14 = HEAP32[i12 >> 2] | 0;
+    } else {
+     i14 = _luaM_growaux_(HEAP32[i1 >> 2] | 0, HEAP32[i12 >> 2] | 0, i14, 16, 32767, 6312) | 0;
+     HEAP32[i12 >> 2] = i14;
+    }
+    HEAP32[i14 + (i15 << 4) >> 2] = i10;
+    i29 = HEAP32[i12 >> 2] | 0;
+    HEAP32[i29 + (i15 << 4) + 8 >> 2] = i6;
+    HEAP8[i29 + (i15 << 4) + 12 | 0] = HEAP8[(HEAP32[i3 >> 2] | 0) + 46 | 0] | 0;
+    HEAP32[(HEAP32[i12 >> 2] | 0) + (i15 << 4) + 4 >> 2] = i8;
+    HEAP32[i13 >> 2] = (HEAP32[i13 >> 2] | 0) + 1;
+    L152 : while (1) {
+     switch (HEAP32[i5 >> 2] | 0) {
+     case 285:
+     case 59:
+      {
+       break;
+      }
+     case 286:
+     case 262:
+     case 261:
+     case 260:
+      {
+       i7 = 108;
+       break L152;
+      }
+     default:
+      {
+       break L152;
+      }
+     }
+     _statement(i4);
+    }
+    if ((i7 | 0) == 108) {
+     HEAP8[(HEAP32[i12 >> 2] | 0) + (i15 << 4) + 12 | 0] = HEAP8[(HEAP32[i11 >> 2] | 0) + 8 | 0] | 0;
+    }
+    i5 = (HEAP32[i12 >> 2] | 0) + (i15 << 4) | 0;
+    i8 = HEAP32[i9 >> 2] | 0;
+    i7 = HEAP16[(HEAP32[(HEAP32[i3 >> 2] | 0) + 16 >> 2] | 0) + 6 >> 1] | 0;
+    i6 = i8 + 16 | 0;
+    if ((i7 | 0) < (HEAP32[i6 >> 2] | 0)) {
+     i8 = i8 + 12 | 0;
+     do {
+      while (1) {
+       if ((_luaS_eqstr(HEAP32[(HEAP32[i8 >> 2] | 0) + (i7 << 4) >> 2] | 0, HEAP32[i5 >> 2] | 0) | 0) == 0) {
+        break;
+       }
+       _closegoto(i4, i7, i5);
+       if ((i7 | 0) >= (HEAP32[i6 >> 2] | 0)) {
+        break L8;
+       }
+      }
+      i7 = i7 + 1 | 0;
+     } while ((i7 | 0) < (HEAP32[i6 >> 2] | 0));
+    }
+    break;
+   }
+  case 274:
+   {
+    _luaX_next(i4);
+    i6 = HEAP32[i3 >> 2] | 0;
+    L166 : do {
+     switch (HEAP32[i5 >> 2] | 0) {
+     case 59:
+     case 277:
+     case 286:
+     case 262:
+     case 261:
+     case 260:
+      {
+       i8 = 0;
+       i7 = 0;
+       break;
+      }
+     default:
+      {
+       _subexpr(i4, i24, 0) | 0;
+       if ((HEAP32[i5 >> 2] | 0) == 44) {
+        i7 = 1;
+        do {
+         _luaX_next(i4);
+         _luaK_exp2nextreg(HEAP32[i3 >> 2] | 0, i24);
+         _subexpr(i4, i24, 0) | 0;
+         i7 = i7 + 1 | 0;
+        } while ((HEAP32[i5 >> 2] | 0) == 44);
+       } else {
+        i7 = 1;
+       }
+       if (!(((HEAP32[i24 >> 2] | 0) + -12 | 0) >>> 0 < 2)) {
+        if ((i7 | 0) == 1) {
+         i8 = _luaK_exp2anyreg(i6, i24) | 0;
+         i7 = 1;
+         break L166;
+        } else {
+         _luaK_exp2nextreg(i6, i24);
+         i8 = HEAPU8[i6 + 46 | 0] | 0;
+         break L166;
+        }
+       } else {
+        _luaK_setreturns(i6, i24, -1);
+        if ((HEAP32[i24 >> 2] | 0) == 12 & (i7 | 0) == 1) {
+         i29 = (HEAP32[(HEAP32[i6 >> 2] | 0) + 12 >> 2] | 0) + (HEAP32[i24 + 8 >> 2] << 2) | 0;
+         HEAP32[i29 >> 2] = HEAP32[i29 >> 2] & -64 | 30;
+        }
+        i8 = HEAPU8[i6 + 46 | 0] | 0;
+        i7 = -1;
+        break L166;
+       }
+      }
+     }
+    } while (0);
+    _luaK_ret(i6, i8, i7);
+    if ((HEAP32[i5 >> 2] | 0) == 59) {
+     _luaX_next(i4);
+    }
+    break;
+   }
+  case 266:
+  case 258:
+   {
+    i6 = _luaK_jump(i9) | 0;
+    i7 = HEAP32[i19 >> 2] | 0;
+    i29 = (HEAP32[i5 >> 2] | 0) == 266;
+    _luaX_next(i4);
+    do {
+     if (i29) {
+      if ((HEAP32[i5 >> 2] | 0) == 288) {
+       i23 = HEAP32[i4 + 24 >> 2] | 0;
+       _luaX_next(i4);
+       break;
+      } else {
+       _error_expected(i4, 288);
+      }
+     } else {
+      i23 = _luaS_new(HEAP32[i1 >> 2] | 0, 6304) | 0;
+     }
+    } while (0);
+    i10 = HEAP32[i4 + 64 >> 2] | 0;
+    i9 = i10 + 12 | 0;
+    i5 = i10 + 16 | 0;
+    i8 = HEAP32[i5 >> 2] | 0;
+    i10 = i10 + 20 | 0;
+    if ((i8 | 0) < (HEAP32[i10 >> 2] | 0)) {
+     i10 = HEAP32[i9 >> 2] | 0;
+    } else {
+     i10 = _luaM_growaux_(HEAP32[i1 >> 2] | 0, HEAP32[i9 >> 2] | 0, i10, 16, 32767, 6312) | 0;
+     HEAP32[i9 >> 2] = i10;
+    }
+    HEAP32[i10 + (i8 << 4) >> 2] = i23;
+    i29 = HEAP32[i9 >> 2] | 0;
+    HEAP32[i29 + (i8 << 4) + 8 >> 2] = i7;
+    HEAP8[i29 + (i8 << 4) + 12 | 0] = HEAP8[(HEAP32[i3 >> 2] | 0) + 46 | 0] | 0;
+    HEAP32[(HEAP32[i9 >> 2] | 0) + (i8 << 4) + 4 >> 2] = i6;
+    HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + 1;
+    _findlabel(i4, i8) | 0;
+    break;
+   }
+  default:
+   {
+    i6 = i8 + 8 | 0;
+    _suffixedexp(i4, i6);
+    i29 = HEAP32[i5 >> 2] | 0;
+    if ((i29 | 0) == 44 | (i29 | 0) == 61) {
+     HEAP32[i8 >> 2] = 0;
+     _assignment(i4, i8, 1);
+     break L8;
+    }
+    if ((HEAP32[i6 >> 2] | 0) == 12) {
+     i29 = (HEAP32[(HEAP32[i9 >> 2] | 0) + 12 >> 2] | 0) + (HEAP32[i8 + 16 >> 2] << 2) | 0;
+     HEAP32[i29 >> 2] = HEAP32[i29 >> 2] & -8372225 | 16384;
+     break L8;
+    } else {
+     _luaX_syntaxerror(i4, 6344);
+    }
+   }
+  }
+ } while (0);
+ i29 = HEAP32[i3 >> 2] | 0;
+ HEAP8[i29 + 48 | 0] = HEAP8[i29 + 46 | 0] | 0;
+ i29 = (HEAP32[i1 >> 2] | 0) + 38 | 0;
+ HEAP16[i29 >> 1] = (HEAP16[i29 >> 1] | 0) + -1 << 16 >> 16;
+ STACKTOP = i2;
+ return;
+}
+function _match(i1, i12, i11) {
+ i1 = i1 | 0;
+ i12 = i12 | 0;
+ i11 = i11 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i8 = i2;
+ i32 = HEAP32[i1 >> 2] | 0;
+ HEAP32[i1 >> 2] = i32 + -1;
+ if ((i32 | 0) == 0) {
+  _luaL_error(HEAP32[i1 + 16 >> 2] | 0, 7272, i8) | 0;
+ }
+ i14 = i1 + 12 | 0;
+ i22 = HEAP32[i14 >> 2] | 0;
+ L4 : do {
+  if ((i22 | 0) != (i11 | 0)) {
+   i3 = i1 + 8 | 0;
+   i9 = i1 + 16 | 0;
+   i16 = i1 + 4 | 0;
+   i10 = i1 + 20 | 0;
+   L6 : while (1) {
+    i19 = i12 + 1 | 0;
+    i20 = i12 + -1 | 0;
+    L8 : while (1) {
+     i23 = HEAP8[i11] | 0;
+     i21 = i23 << 24 >> 24;
+     L10 : do {
+      if ((i21 | 0) == 36) {
+       i7 = i11 + 1 | 0;
+       if ((i7 | 0) == (i22 | 0)) {
+        i7 = 23;
+        break L6;
+       } else {
+        i22 = i7;
+        i21 = i7;
+        i7 = 89;
+       }
+      } else if ((i21 | 0) == 37) {
+       i21 = i11 + 1 | 0;
+       i23 = HEAP8[i21] | 0;
+       switch (i23 << 24 >> 24 | 0) {
+       case 57:
+       case 56:
+       case 55:
+       case 54:
+       case 53:
+       case 52:
+       case 51:
+       case 50:
+       case 49:
+       case 48:
+        {
+         i7 = 69;
+         break L8;
+        }
+       case 98:
+        {
+         i7 = 25;
+         break L8;
+        }
+       case 102:
+        {
+         break;
+        }
+       default:
+        {
+         if ((i21 | 0) == (i22 | 0)) {
+          _luaL_error(HEAP32[i9 >> 2] | 0, 7368, i8) | 0;
+         }
+         i22 = i11 + 2 | 0;
+         i7 = 89;
+         break L10;
+        }
+       }
+       i22 = i11 + 2 | 0;
+       if ((HEAP8[i22] | 0) == 91) {
+        i21 = 91;
+       } else {
+        _luaL_error(HEAP32[i9 >> 2] | 0, 7296, i8) | 0;
+        i21 = HEAP8[i22] | 0;
+       }
+       i23 = i11 + 3 | 0;
+       i21 = i21 << 24 >> 24;
+       if ((i21 | 0) == 91) {
+        i21 = (HEAP8[i23] | 0) == 94 ? i11 + 4 | 0 : i23;
+        while (1) {
+         if ((i21 | 0) == (HEAP32[i14 >> 2] | 0)) {
+          _luaL_error(HEAP32[i9 >> 2] | 0, 7408, i8) | 0;
+         }
+         i11 = i21 + 1 | 0;
+         if ((HEAP8[i21] | 0) == 37) {
+          i11 = i11 >>> 0 < (HEAP32[i14 >> 2] | 0) >>> 0 ? i21 + 2 | 0 : i11;
+         }
+         if ((HEAP8[i11] | 0) == 93) {
+          break;
+         } else {
+          i21 = i11;
+         }
+        }
+        i11 = i11 + 1 | 0;
+       } else if ((i21 | 0) == 37) {
+        if ((i23 | 0) == (HEAP32[i14 >> 2] | 0)) {
+         _luaL_error(HEAP32[i9 >> 2] | 0, 7368, i8) | 0;
+        }
+        i11 = i11 + 4 | 0;
+       } else {
+        i11 = i23;
+       }
+       if ((i12 | 0) == (HEAP32[i16 >> 2] | 0)) {
+        i25 = 0;
+       } else {
+        i25 = HEAP8[i20] | 0;
+       }
+       i24 = i25 & 255;
+       i21 = i11 + -1 | 0;
+       i26 = (HEAP8[i23] | 0) == 94;
+       i28 = i26 ? i23 : i22;
+       i27 = i26 & 1;
+       i26 = i27 ^ 1;
+       i30 = i28 + 1 | 0;
+       L41 : do {
+        if (i30 >>> 0 < i21 >>> 0) {
+         while (1) {
+          i32 = HEAP8[i30] | 0;
+          i29 = i28 + 2 | 0;
+          i31 = HEAP8[i29] | 0;
+          do {
+           if (i32 << 24 >> 24 == 37) {
+            if ((_match_class(i24, i31 & 255) | 0) == 0) {
+             i28 = i29;
+            } else {
+             break L41;
+            }
+           } else {
+            if (i31 << 24 >> 24 == 45 ? (i18 = i28 + 3 | 0, i18 >>> 0 < i21 >>> 0) : 0) {
+             if ((i32 & 255) > (i25 & 255)) {
+              i28 = i18;
+              break;
+             }
+             if ((HEAPU8[i18] | 0) < (i25 & 255)) {
+              i28 = i18;
+              break;
+             } else {
+              break L41;
+             }
+            }
+            if (i32 << 24 >> 24 == i25 << 24 >> 24) {
+             break L41;
+            } else {
+             i28 = i30;
+            }
+           }
+          } while (0);
+          i30 = i28 + 1 | 0;
+          if (!(i30 >>> 0 < i21 >>> 0)) {
+           i26 = i27;
+           break;
+          }
+         }
+        } else {
+         i26 = i27;
+        }
+       } while (0);
+       if ((i26 | 0) != 0) {
+        i12 = 0;
+        break L4;
+       }
+       i24 = HEAP8[i12] | 0;
+       i25 = i24 & 255;
+       i27 = (HEAP8[i23] | 0) == 94;
+       i26 = i27 ? i23 : i22;
+       i22 = i27 & 1;
+       i23 = i22 ^ 1;
+       i30 = i26 + 1 | 0;
+       L55 : do {
+        if (i30 >>> 0 < i21 >>> 0) {
+         do {
+          i29 = HEAP8[i30] | 0;
+          i28 = i26 + 2 | 0;
+          i27 = HEAP8[i28] | 0;
+          do {
+           if (i29 << 24 >> 24 == 37) {
+            if ((_match_class(i25, i27 & 255) | 0) == 0) {
+             i26 = i28;
+            } else {
+             i22 = i23;
+             break L55;
+            }
+           } else {
+            if (i27 << 24 >> 24 == 45 ? (i17 = i26 + 3 | 0, i17 >>> 0 < i21 >>> 0) : 0) {
+             if ((i29 & 255) > (i24 & 255)) {
+              i26 = i17;
+              break;
+             }
+             if ((HEAPU8[i17] | 0) < (i24 & 255)) {
+              i26 = i17;
+              break;
+             } else {
+              i22 = i23;
+              break L55;
+             }
+            }
+            if (i29 << 24 >> 24 == i24 << 24 >> 24) {
+             i22 = i23;
+             break L55;
+            } else {
+             i26 = i30;
+            }
+           }
+          } while (0);
+          i30 = i26 + 1 | 0;
+         } while (i30 >>> 0 < i21 >>> 0);
+        }
+       } while (0);
+       if ((i22 | 0) == 0) {
+        i12 = 0;
+        break L4;
+       }
+      } else if ((i21 | 0) == 40) {
+       i7 = 7;
+       break L6;
+      } else if ((i21 | 0) != 41) {
+       i21 = i11 + 1 | 0;
+       if (i23 << 24 >> 24 == 91) {
+        i7 = (HEAP8[i21] | 0) == 94 ? i11 + 2 | 0 : i21;
+        while (1) {
+         if ((i7 | 0) == (i22 | 0)) {
+          _luaL_error(HEAP32[i9 >> 2] | 0, 7408, i8) | 0;
+         }
+         i22 = i7 + 1 | 0;
+         if ((HEAP8[i7] | 0) == 37) {
+          i7 = i22 >>> 0 < (HEAP32[i14 >> 2] | 0) >>> 0 ? i7 + 2 | 0 : i22;
+         } else {
+          i7 = i22;
+         }
+         if ((HEAP8[i7] | 0) == 93) {
+          break;
+         }
+         i22 = HEAP32[i14 >> 2] | 0;
+        }
+        i22 = i7 + 1 | 0;
+        i7 = 89;
+       } else {
+        i22 = i21;
+        i7 = 89;
+       }
+      } else {
+       i7 = 16;
+       break L6;
+      }
+     } while (0);
+     L80 : do {
+      if ((i7 | 0) == 89) {
+       i7 = 0;
+       do {
+        if ((HEAP32[i3 >> 2] | 0) >>> 0 > i12 >>> 0) {
+         i23 = HEAP8[i12] | 0;
+         i24 = i23 & 255;
+         i26 = HEAP8[i11] | 0;
+         i25 = i26 << 24 >> 24;
+         L85 : do {
+          if ((i25 | 0) == 46) {
+           i23 = HEAP8[i22] | 0;
+          } else if ((i25 | 0) == 37) {
+           i25 = _match_class(i24, HEAPU8[i21] | 0) | 0;
+           i7 = 104;
+          } else if ((i25 | 0) == 91) {
+           i7 = i22 + -1 | 0;
+           i25 = (HEAP8[i21] | 0) == 94;
+           i27 = i25 ? i21 : i11;
+           i26 = i25 & 1;
+           i25 = i26 ^ 1;
+           i30 = i27 + 1 | 0;
+           if (i30 >>> 0 < i7 >>> 0) {
+            while (1) {
+             i31 = HEAP8[i30] | 0;
+             i29 = i27 + 2 | 0;
+             i28 = HEAP8[i29] | 0;
+             do {
+              if (i31 << 24 >> 24 == 37) {
+               if ((_match_class(i24, i28 & 255) | 0) == 0) {
+                i27 = i29;
+               } else {
+                i7 = 104;
+                break L85;
+               }
+              } else {
+               if (i28 << 24 >> 24 == 45 ? (i13 = i27 + 3 | 0, i13 >>> 0 < i7 >>> 0) : 0) {
+                if ((i31 & 255) > (i23 & 255)) {
+                 i27 = i13;
+                 break;
+                }
+                if ((HEAPU8[i13] | 0) < (i23 & 255)) {
+                 i27 = i13;
+                 break;
+                } else {
+                 i7 = 104;
+                 break L85;
+                }
+               }
+               if (i31 << 24 >> 24 == i23 << 24 >> 24) {
+                i7 = 104;
+                break L85;
+               } else {
+                i27 = i30;
+               }
+              }
+             } while (0);
+             i30 = i27 + 1 | 0;
+             if (!(i30 >>> 0 < i7 >>> 0)) {
+              i25 = i26;
+              i7 = 104;
+              break;
+             }
+            }
+           } else {
+            i25 = i26;
+            i7 = 104;
+           }
+          } else {
+           i25 = i26 << 24 >> 24 == i23 << 24 >> 24 | 0;
+           i7 = 104;
+          }
+         } while (0);
+         if ((i7 | 0) == 104) {
+          i7 = 0;
+          i23 = HEAP8[i22] | 0;
+          if ((i25 | 0) == 0) {
+           break;
+          }
+         }
+         i23 = i23 << 24 >> 24;
+         if ((i23 | 0) == 45) {
+          i7 = 109;
+          break L6;
+         } else if ((i23 | 0) == 42) {
+          i7 = 112;
+          break L6;
+         } else if ((i23 | 0) == 43) {
+          break L6;
+         } else if ((i23 | 0) != 63) {
+          i12 = i19;
+          i11 = i22;
+          break L8;
+         }
+         i11 = i22 + 1 | 0;
+         i21 = _match(i1, i19, i11) | 0;
+         if ((i21 | 0) == 0) {
+          break L80;
+         } else {
+          i12 = i21;
+          break L4;
+         }
+        } else {
+         i23 = HEAP8[i22] | 0;
+        }
+       } while (0);
+       if (!(i23 << 24 >> 24 == 45 | i23 << 24 >> 24 == 63 | i23 << 24 >> 24 == 42)) {
+        i12 = 0;
+        break L4;
+       }
+       i11 = i22 + 1 | 0;
+      }
+     } while (0);
+     i22 = HEAP32[i14 >> 2] | 0;
+     if ((i11 | 0) == (i22 | 0)) {
+      break L4;
+     }
+    }
+    if ((i7 | 0) == 25) {
+     i7 = 0;
+     i21 = i11 + 2 | 0;
+     if (!((i22 + -1 | 0) >>> 0 > i21 >>> 0)) {
+      _luaL_error(HEAP32[i9 >> 2] | 0, 7440, i8) | 0;
+     }
+     i20 = HEAP8[i12] | 0;
+     if (!(i20 << 24 >> 24 == (HEAP8[i21] | 0))) {
+      i12 = 0;
+      break L4;
+     }
+     i21 = HEAP8[i11 + 3 | 0] | 0;
+     i22 = HEAP32[i3 >> 2] | 0;
+     if (i19 >>> 0 < i22 >>> 0) {
+      i24 = 1;
+     } else {
+      i12 = 0;
+      break L4;
+     }
+     while (1) {
+      i23 = HEAP8[i19] | 0;
+      if (i23 << 24 >> 24 == i21 << 24 >> 24) {
+       i24 = i24 + -1 | 0;
+       if ((i24 | 0) == 0) {
+        break;
+       }
+      } else {
+       i24 = (i23 << 24 >> 24 == i20 << 24 >> 24) + i24 | 0;
+      }
+      i12 = i19 + 1 | 0;
+      if (i12 >>> 0 < i22 >>> 0) {
+       i32 = i19;
+       i19 = i12;
+       i12 = i32;
+      } else {
+       i12 = 0;
+       break L4;
+      }
+     }
+     i12 = i12 + 2 | 0;
+     i11 = i11 + 4 | 0;
+    } else if ((i7 | 0) == 69) {
+     i7 = 0;
+     i20 = i23 & 255;
+     i19 = i20 + -49 | 0;
+     if (((i19 | 0) >= 0 ? (i19 | 0) < (HEAP32[i10 >> 2] | 0) : 0) ? (i15 = HEAP32[i1 + (i19 << 3) + 28 >> 2] | 0, !((i15 | 0) == -1)) : 0) {
+      i20 = i15;
+     } else {
+      i19 = HEAP32[i9 >> 2] | 0;
+      HEAP32[i8 >> 2] = i20 + -48;
+      i20 = _luaL_error(i19, 7336, i8) | 0;
+      i19 = i20;
+      i20 = HEAP32[i1 + (i20 << 3) + 28 >> 2] | 0;
+     }
+     if (((HEAP32[i3 >> 2] | 0) - i12 | 0) >>> 0 < i20 >>> 0) {
+      i12 = 0;
+      break L4;
+     }
+     if ((_memcmp(HEAP32[i1 + (i19 << 3) + 24 >> 2] | 0, i12, i20) | 0) != 0) {
+      i12 = 0;
+      break L4;
+     }
+     i12 = i12 + i20 | 0;
+     if ((i12 | 0) == 0) {
+      i12 = 0;
+      break L4;
+     }
+     i11 = i11 + 2 | 0;
+    }
+    i22 = HEAP32[i14 >> 2] | 0;
+    if ((i11 | 0) == (i22 | 0)) {
+     break L4;
+    }
+   }
+   if ((i7 | 0) == 7) {
+    i3 = i11 + 1 | 0;
+    if ((HEAP8[i3] | 0) == 41) {
+     i3 = HEAP32[i10 >> 2] | 0;
+     if ((i3 | 0) > 31) {
+      _luaL_error(HEAP32[i9 >> 2] | 0, 7200, i8) | 0;
+     }
+     HEAP32[i1 + (i3 << 3) + 24 >> 2] = i12;
+     HEAP32[i1 + (i3 << 3) + 28 >> 2] = -2;
+     HEAP32[i10 >> 2] = i3 + 1;
+     i12 = _match(i1, i12, i11 + 2 | 0) | 0;
+     if ((i12 | 0) != 0) {
+      break;
+     }
+     HEAP32[i10 >> 2] = (HEAP32[i10 >> 2] | 0) + -1;
+     i12 = 0;
+     break;
+    } else {
+     i4 = HEAP32[i10 >> 2] | 0;
+     if ((i4 | 0) > 31) {
+      _luaL_error(HEAP32[i9 >> 2] | 0, 7200, i8) | 0;
+     }
+     HEAP32[i1 + (i4 << 3) + 24 >> 2] = i12;
+     HEAP32[i1 + (i4 << 3) + 28 >> 2] = -1;
+     HEAP32[i10 >> 2] = i4 + 1;
+     i12 = _match(i1, i12, i3) | 0;
+     if ((i12 | 0) != 0) {
+      break;
+     }
+     HEAP32[i10 >> 2] = (HEAP32[i10 >> 2] | 0) + -1;
+     i12 = 0;
+     break;
+    }
+   } else if ((i7 | 0) == 16) {
+    i3 = i11 + 1 | 0;
+    i5 = HEAP32[i10 >> 2] | 0;
+    while (1) {
+     i4 = i5 + -1 | 0;
+     if ((i5 | 0) <= 0) {
+      i7 = 19;
+      break;
+     }
+     if ((HEAP32[i1 + (i4 << 3) + 28 >> 2] | 0) == -1) {
+      break;
+     } else {
+      i5 = i4;
+     }
+    }
+    if ((i7 | 0) == 19) {
+     i4 = _luaL_error(HEAP32[i9 >> 2] | 0, 7488, i8) | 0;
+    }
+    i5 = i1 + (i4 << 3) + 28 | 0;
+    HEAP32[i5 >> 2] = i12 - (HEAP32[i1 + (i4 << 3) + 24 >> 2] | 0);
+    i12 = _match(i1, i12, i3) | 0;
+    if ((i12 | 0) != 0) {
+     break;
+    }
+    HEAP32[i5 >> 2] = -1;
+    i12 = 0;
+    break;
+   } else if ((i7 | 0) == 23) {
+    i12 = (i12 | 0) == (HEAP32[i3 >> 2] | 0) ? i12 : 0;
+    break;
+   } else if ((i7 | 0) == 109) {
+    i4 = i22 + 1 | 0;
+    i8 = _match(i1, i12, i4) | 0;
+    if ((i8 | 0) != 0) {
+     i12 = i8;
+     break;
+    }
+    i8 = i22 + -1 | 0;
+    while (1) {
+     if (!((HEAP32[i3 >> 2] | 0) >>> 0 > i12 >>> 0)) {
+      i12 = 0;
+      break L4;
+     }
+     i9 = HEAP8[i12] | 0;
+     i10 = i9 & 255;
+     i14 = HEAP8[i11] | 0;
+     i13 = i14 << 24 >> 24;
+     L139 : do {
+      if ((i13 | 0) == 91) {
+       i6 = (HEAP8[i21] | 0) == 94;
+       i13 = i6 ? i21 : i11;
+       i6 = i6 & 1;
+       i7 = i6 ^ 1;
+       i14 = i13 + 1 | 0;
+       if (i14 >>> 0 < i8 >>> 0) {
+        while (1) {
+         i17 = HEAP8[i14] | 0;
+         i15 = i13 + 2 | 0;
+         i16 = HEAP8[i15] | 0;
+         do {
+          if (i17 << 24 >> 24 == 37) {
+           if ((_match_class(i10, i16 & 255) | 0) == 0) {
+            i13 = i15;
+           } else {
+            i6 = i7;
+            i7 = 147;
+            break L139;
+           }
+          } else {
+           if (i16 << 24 >> 24 == 45 ? (i5 = i13 + 3 | 0, i5 >>> 0 < i8 >>> 0) : 0) {
+            if ((i17 & 255) > (i9 & 255)) {
+             i13 = i5;
+             break;
+            }
+            if ((HEAPU8[i5] | 0) < (i9 & 255)) {
+             i13 = i5;
+             break;
+            } else {
+             i6 = i7;
+             i7 = 147;
+             break L139;
+            }
+           }
+           if (i17 << 24 >> 24 == i9 << 24 >> 24) {
+            i6 = i7;
+            i7 = 147;
+            break L139;
+           } else {
+            i13 = i14;
+           }
+          }
+         } while (0);
+         i14 = i13 + 1 | 0;
+         if (!(i14 >>> 0 < i8 >>> 0)) {
+          i7 = 147;
+          break;
+         }
+        }
+       } else {
+        i7 = 147;
+       }
+      } else if ((i13 | 0) == 37) {
+       i6 = _match_class(i10, HEAPU8[i21] | 0) | 0;
+       i7 = 147;
+      } else if ((i13 | 0) != 46) {
+       i6 = i14 << 24 >> 24 == i9 << 24 >> 24 | 0;
+       i7 = 147;
+      }
+     } while (0);
+     if ((i7 | 0) == 147 ? (i7 = 0, (i6 | 0) == 0) : 0) {
+      i12 = 0;
+      break L4;
+     }
+     i9 = i12 + 1 | 0;
+     i12 = _match(i1, i9, i4) | 0;
+     if ((i12 | 0) == 0) {
+      i12 = i9;
+     } else {
+      break L4;
+     }
+    }
+   } else if ((i7 | 0) == 112) {
+    i19 = i12;
+   }
+   i10 = HEAP32[i3 >> 2] | 0;
+   if (i10 >>> 0 > i19 >>> 0) {
+    i5 = i22 + -1 | 0;
+    i8 = i19;
+    i6 = 0;
+    do {
+     i8 = HEAP8[i8] | 0;
+     i9 = i8 & 255;
+     i13 = HEAP8[i11] | 0;
+     i12 = i13 << 24 >> 24;
+     L183 : do {
+      if ((i12 | 0) == 37) {
+       i10 = _match_class(i9, HEAPU8[i21] | 0) | 0;
+       i7 = 129;
+      } else if ((i12 | 0) == 91) {
+       i7 = (HEAP8[i21] | 0) == 94;
+       i12 = i7 ? i21 : i11;
+       i10 = i7 & 1;
+       i7 = i10 ^ 1;
+       i13 = i12 + 1 | 0;
+       if (i13 >>> 0 < i5 >>> 0) {
+        while (1) {
+         i14 = HEAP8[i13] | 0;
+         i16 = i12 + 2 | 0;
+         i15 = HEAP8[i16] | 0;
+         do {
+          if (i14 << 24 >> 24 == 37) {
+           if ((_match_class(i9, i15 & 255) | 0) == 0) {
+            i12 = i16;
+           } else {
+            i10 = i7;
+            i7 = 129;
+            break L183;
+           }
+          } else {
+           if (i15 << 24 >> 24 == 45 ? (i4 = i12 + 3 | 0, i4 >>> 0 < i5 >>> 0) : 0) {
+            if ((i14 & 255) > (i8 & 255)) {
+             i12 = i4;
+             break;
+            }
+            if ((HEAPU8[i4] | 0) < (i8 & 255)) {
+             i12 = i4;
+             break;
+            } else {
+             i10 = i7;
+             i7 = 129;
+             break L183;
+            }
+           }
+           if (i14 << 24 >> 24 == i8 << 24 >> 24) {
+            i10 = i7;
+            i7 = 129;
+            break L183;
+           } else {
+            i12 = i13;
+           }
+          }
+         } while (0);
+         i13 = i12 + 1 | 0;
+         if (!(i13 >>> 0 < i5 >>> 0)) {
+          i7 = 129;
+          break;
+         }
+        }
+       } else {
+        i7 = 129;
+       }
+      } else if ((i12 | 0) != 46) {
+       i10 = i13 << 24 >> 24 == i8 << 24 >> 24 | 0;
+       i7 = 129;
+      }
+     } while (0);
+     if ((i7 | 0) == 129) {
+      i7 = 0;
+      if ((i10 | 0) == 0) {
+       break;
+      }
+      i10 = HEAP32[i3 >> 2] | 0;
+     }
+     i6 = i6 + 1 | 0;
+     i8 = i19 + i6 | 0;
+    } while (i10 >>> 0 > i8 >>> 0);
+    if (!((i6 | 0) > -1)) {
+     i12 = 0;
+     break;
+    }
+   } else {
+    i6 = 0;
+   }
+   i3 = i22 + 1 | 0;
+   while (1) {
+    i12 = _match(i1, i19 + i6 | 0, i3) | 0;
+    if ((i12 | 0) != 0) {
+     break L4;
+    }
+    if ((i6 | 0) > 0) {
+     i6 = i6 + -1 | 0;
+    } else {
+     i12 = 0;
+     break;
+    }
+   }
+  }
+ } while (0);
+ HEAP32[i1 >> 2] = (HEAP32[i1 >> 2] | 0) + 1;
+ STACKTOP = i2;
+ return i12 | 0;
+}
+function _free(i7) {
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0;
+ i1 = STACKTOP;
+ if ((i7 | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i15 = i7 + -8 | 0;
+ i16 = HEAP32[12928 >> 2] | 0;
+ if (i15 >>> 0 < i16 >>> 0) {
+  _abort();
+ }
+ i13 = HEAP32[i7 + -4 >> 2] | 0;
+ i12 = i13 & 3;
+ if ((i12 | 0) == 1) {
+  _abort();
+ }
+ i8 = i13 & -8;
+ i6 = i7 + (i8 + -8) | 0;
+ do {
+  if ((i13 & 1 | 0) == 0) {
+   i19 = HEAP32[i15 >> 2] | 0;
+   if ((i12 | 0) == 0) {
+    STACKTOP = i1;
+    return;
+   }
+   i15 = -8 - i19 | 0;
+   i13 = i7 + i15 | 0;
+   i12 = i19 + i8 | 0;
+   if (i13 >>> 0 < i16 >>> 0) {
+    _abort();
+   }
+   if ((i13 | 0) == (HEAP32[12932 >> 2] | 0)) {
+    i2 = i7 + (i8 + -4) | 0;
+    if ((HEAP32[i2 >> 2] & 3 | 0) != 3) {
+     i2 = i13;
+     i11 = i12;
+     break;
+    }
+    HEAP32[12920 >> 2] = i12;
+    HEAP32[i2 >> 2] = HEAP32[i2 >> 2] & -2;
+    HEAP32[i7 + (i15 + 4) >> 2] = i12 | 1;
+    HEAP32[i6 >> 2] = i12;
+    STACKTOP = i1;
+    return;
+   }
+   i18 = i19 >>> 3;
+   if (i19 >>> 0 < 256) {
+    i2 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
+    i11 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
+    i14 = 12952 + (i18 << 1 << 2) | 0;
+    if ((i2 | 0) != (i14 | 0)) {
+     if (i2 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i2 + 12 >> 2] | 0) != (i13 | 0)) {
+      _abort();
+     }
+    }
+    if ((i11 | 0) == (i2 | 0)) {
+     HEAP32[3228] = HEAP32[3228] & ~(1 << i18);
+     i2 = i13;
+     i11 = i12;
+     break;
+    }
+    if ((i11 | 0) != (i14 | 0)) {
+     if (i11 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     i14 = i11 + 8 | 0;
+     if ((HEAP32[i14 >> 2] | 0) == (i13 | 0)) {
+      i17 = i14;
+     } else {
+      _abort();
+     }
+    } else {
+     i17 = i11 + 8 | 0;
+    }
+    HEAP32[i2 + 12 >> 2] = i11;
+    HEAP32[i17 >> 2] = i2;
+    i2 = i13;
+    i11 = i12;
+    break;
+   }
+   i17 = HEAP32[i7 + (i15 + 24) >> 2] | 0;
+   i18 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
+   do {
+    if ((i18 | 0) == (i13 | 0)) {
+     i19 = i7 + (i15 + 20) | 0;
+     i18 = HEAP32[i19 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      i19 = i7 + (i15 + 16) | 0;
+      i18 = HEAP32[i19 >> 2] | 0;
+      if ((i18 | 0) == 0) {
+       i14 = 0;
+       break;
+      }
+     }
+     while (1) {
+      i21 = i18 + 20 | 0;
+      i20 = HEAP32[i21 >> 2] | 0;
+      if ((i20 | 0) != 0) {
+       i18 = i20;
+       i19 = i21;
+       continue;
+      }
+      i20 = i18 + 16 | 0;
+      i21 = HEAP32[i20 >> 2] | 0;
+      if ((i21 | 0) == 0) {
+       break;
+      } else {
+       i18 = i21;
+       i19 = i20;
+      }
+     }
+     if (i19 >>> 0 < i16 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i19 >> 2] = 0;
+      i14 = i18;
+      break;
+     }
+    } else {
+     i19 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
+     if (i19 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     i16 = i19 + 12 | 0;
+     if ((HEAP32[i16 >> 2] | 0) != (i13 | 0)) {
+      _abort();
+     }
+     i20 = i18 + 8 | 0;
+     if ((HEAP32[i20 >> 2] | 0) == (i13 | 0)) {
+      HEAP32[i16 >> 2] = i18;
+      HEAP32[i20 >> 2] = i19;
+      i14 = i18;
+      break;
+     } else {
+      _abort();
+     }
+    }
+   } while (0);
+   if ((i17 | 0) != 0) {
+    i18 = HEAP32[i7 + (i15 + 28) >> 2] | 0;
+    i16 = 13216 + (i18 << 2) | 0;
+    if ((i13 | 0) == (HEAP32[i16 >> 2] | 0)) {
+     HEAP32[i16 >> 2] = i14;
+     if ((i14 | 0) == 0) {
+      HEAP32[12916 >> 2] = HEAP32[12916 >> 2] & ~(1 << i18);
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    } else {
+     if (i17 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i16 = i17 + 16 | 0;
+     if ((HEAP32[i16 >> 2] | 0) == (i13 | 0)) {
+      HEAP32[i16 >> 2] = i14;
+     } else {
+      HEAP32[i17 + 20 >> 2] = i14;
+     }
+     if ((i14 | 0) == 0) {
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    }
+    if (i14 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+     _abort();
+    }
+    HEAP32[i14 + 24 >> 2] = i17;
+    i16 = HEAP32[i7 + (i15 + 16) >> 2] | 0;
+    do {
+     if ((i16 | 0) != 0) {
+      if (i16 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i14 + 16 >> 2] = i16;
+       HEAP32[i16 + 24 >> 2] = i14;
+       break;
+      }
+     }
+    } while (0);
+    i15 = HEAP32[i7 + (i15 + 20) >> 2] | 0;
+    if ((i15 | 0) != 0) {
+     if (i15 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i14 + 20 >> 2] = i15;
+      HEAP32[i15 + 24 >> 2] = i14;
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    } else {
+     i2 = i13;
+     i11 = i12;
+    }
+   } else {
+    i2 = i13;
+    i11 = i12;
+   }
+  } else {
+   i2 = i15;
+   i11 = i8;
+  }
+ } while (0);
+ if (!(i2 >>> 0 < i6 >>> 0)) {
+  _abort();
+ }
+ i12 = i7 + (i8 + -4) | 0;
+ i13 = HEAP32[i12 >> 2] | 0;
+ if ((i13 & 1 | 0) == 0) {
+  _abort();
+ }
+ if ((i13 & 2 | 0) == 0) {
+  if ((i6 | 0) == (HEAP32[12936 >> 2] | 0)) {
+   i21 = (HEAP32[12924 >> 2] | 0) + i11 | 0;
+   HEAP32[12924 >> 2] = i21;
+   HEAP32[12936 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i21 | 1;
+   if ((i2 | 0) != (HEAP32[12932 >> 2] | 0)) {
+    STACKTOP = i1;
+    return;
+   }
+   HEAP32[12932 >> 2] = 0;
+   HEAP32[12920 >> 2] = 0;
+   STACKTOP = i1;
+   return;
+  }
+  if ((i6 | 0) == (HEAP32[12932 >> 2] | 0)) {
+   i21 = (HEAP32[12920 >> 2] | 0) + i11 | 0;
+   HEAP32[12920 >> 2] = i21;
+   HEAP32[12932 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i21 | 1;
+   HEAP32[i2 + i21 >> 2] = i21;
+   STACKTOP = i1;
+   return;
+  }
+  i11 = (i13 & -8) + i11 | 0;
+  i12 = i13 >>> 3;
+  do {
+   if (!(i13 >>> 0 < 256)) {
+    i10 = HEAP32[i7 + (i8 + 16) >> 2] | 0;
+    i15 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
+    do {
+     if ((i15 | 0) == (i6 | 0)) {
+      i13 = i7 + (i8 + 12) | 0;
+      i12 = HEAP32[i13 >> 2] | 0;
+      if ((i12 | 0) == 0) {
+       i13 = i7 + (i8 + 8) | 0;
+       i12 = HEAP32[i13 >> 2] | 0;
+       if ((i12 | 0) == 0) {
+        i9 = 0;
+        break;
+       }
+      }
+      while (1) {
+       i14 = i12 + 20 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) != 0) {
+        i12 = i15;
+        i13 = i14;
+        continue;
+       }
+       i14 = i12 + 16 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) == 0) {
+        break;
+       } else {
+        i12 = i15;
+        i13 = i14;
+       }
+      }
+      if (i13 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i13 >> 2] = 0;
+       i9 = i12;
+       break;
+      }
+     } else {
+      i13 = HEAP32[i7 + i8 >> 2] | 0;
+      if (i13 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i14 = i13 + 12 | 0;
+      if ((HEAP32[i14 >> 2] | 0) != (i6 | 0)) {
+       _abort();
+      }
+      i12 = i15 + 8 | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+       HEAP32[i14 >> 2] = i15;
+       HEAP32[i12 >> 2] = i13;
+       i9 = i15;
+       break;
+      } else {
+       _abort();
+      }
+     }
+    } while (0);
+    if ((i10 | 0) != 0) {
+     i12 = HEAP32[i7 + (i8 + 20) >> 2] | 0;
+     i13 = 13216 + (i12 << 2) | 0;
+     if ((i6 | 0) == (HEAP32[i13 >> 2] | 0)) {
+      HEAP32[i13 >> 2] = i9;
+      if ((i9 | 0) == 0) {
+       HEAP32[12916 >> 2] = HEAP32[12916 >> 2] & ~(1 << i12);
+       break;
+      }
+     } else {
+      if (i10 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i12 = i10 + 16 | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+       HEAP32[i12 >> 2] = i9;
+      } else {
+       HEAP32[i10 + 20 >> 2] = i9;
+      }
+      if ((i9 | 0) == 0) {
+       break;
+      }
+     }
+     if (i9 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     HEAP32[i9 + 24 >> 2] = i10;
+     i6 = HEAP32[i7 + (i8 + 8) >> 2] | 0;
+     do {
+      if ((i6 | 0) != 0) {
+       if (i6 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i9 + 16 >> 2] = i6;
+        HEAP32[i6 + 24 >> 2] = i9;
+        break;
+       }
+      }
+     } while (0);
+     i6 = HEAP32[i7 + (i8 + 12) >> 2] | 0;
+     if ((i6 | 0) != 0) {
+      if (i6 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i9 + 20 >> 2] = i6;
+       HEAP32[i6 + 24 >> 2] = i9;
+       break;
+      }
+     }
+    }
+   } else {
+    i9 = HEAP32[i7 + i8 >> 2] | 0;
+    i7 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
+    i8 = 12952 + (i12 << 1 << 2) | 0;
+    if ((i9 | 0) != (i8 | 0)) {
+     if (i9 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i9 + 12 >> 2] | 0) != (i6 | 0)) {
+      _abort();
+     }
+    }
+    if ((i7 | 0) == (i9 | 0)) {
+     HEAP32[3228] = HEAP32[3228] & ~(1 << i12);
+     break;
+    }
+    if ((i7 | 0) != (i8 | 0)) {
+     if (i7 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i8 = i7 + 8 | 0;
+     if ((HEAP32[i8 >> 2] | 0) == (i6 | 0)) {
+      i10 = i8;
+     } else {
+      _abort();
+     }
+    } else {
+     i10 = i7 + 8 | 0;
+    }
+    HEAP32[i9 + 12 >> 2] = i7;
+    HEAP32[i10 >> 2] = i9;
+   }
+  } while (0);
+  HEAP32[i2 + 4 >> 2] = i11 | 1;
+  HEAP32[i2 + i11 >> 2] = i11;
+  if ((i2 | 0) == (HEAP32[12932 >> 2] | 0)) {
+   HEAP32[12920 >> 2] = i11;
+   STACKTOP = i1;
+   return;
+  }
+ } else {
+  HEAP32[i12 >> 2] = i13 & -2;
+  HEAP32[i2 + 4 >> 2] = i11 | 1;
+  HEAP32[i2 + i11 >> 2] = i11;
+ }
+ i6 = i11 >>> 3;
+ if (i11 >>> 0 < 256) {
+  i7 = i6 << 1;
+  i3 = 12952 + (i7 << 2) | 0;
+  i8 = HEAP32[3228] | 0;
+  i6 = 1 << i6;
+  if ((i8 & i6 | 0) != 0) {
+   i6 = 12952 + (i7 + 2 << 2) | 0;
+   i7 = HEAP32[i6 >> 2] | 0;
+   if (i7 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+    _abort();
+   } else {
+    i4 = i6;
+    i5 = i7;
+   }
+  } else {
+   HEAP32[3228] = i8 | i6;
+   i4 = 12952 + (i7 + 2 << 2) | 0;
+   i5 = i3;
+  }
+  HEAP32[i4 >> 2] = i2;
+  HEAP32[i5 + 12 >> 2] = i2;
+  HEAP32[i2 + 8 >> 2] = i5;
+  HEAP32[i2 + 12 >> 2] = i3;
+  STACKTOP = i1;
+  return;
+ }
+ i4 = i11 >>> 8;
+ if ((i4 | 0) != 0) {
+  if (i11 >>> 0 > 16777215) {
+   i4 = 31;
+  } else {
+   i20 = (i4 + 1048320 | 0) >>> 16 & 8;
+   i21 = i4 << i20;
+   i19 = (i21 + 520192 | 0) >>> 16 & 4;
+   i21 = i21 << i19;
+   i4 = (i21 + 245760 | 0) >>> 16 & 2;
+   i4 = 14 - (i19 | i20 | i4) + (i21 << i4 >>> 15) | 0;
+   i4 = i11 >>> (i4 + 7 | 0) & 1 | i4 << 1;
+  }
+ } else {
+  i4 = 0;
+ }
+ i5 = 13216 + (i4 << 2) | 0;
+ HEAP32[i2 + 28 >> 2] = i4;
+ HEAP32[i2 + 20 >> 2] = 0;
+ HEAP32[i2 + 16 >> 2] = 0;
+ i7 = HEAP32[12916 >> 2] | 0;
+ i6 = 1 << i4;
+ L199 : do {
+  if ((i7 & i6 | 0) != 0) {
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((i4 | 0) == 31) {
+    i4 = 0;
+   } else {
+    i4 = 25 - (i4 >>> 1) | 0;
+   }
+   L204 : do {
+    if ((HEAP32[i5 + 4 >> 2] & -8 | 0) != (i11 | 0)) {
+     i4 = i11 << i4;
+     i7 = i5;
+     while (1) {
+      i6 = i7 + (i4 >>> 31 << 2) + 16 | 0;
+      i5 = HEAP32[i6 >> 2] | 0;
+      if ((i5 | 0) == 0) {
+       break;
+      }
+      if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i11 | 0)) {
+       i3 = i5;
+       break L204;
+      } else {
+       i4 = i4 << 1;
+       i7 = i5;
+      }
+     }
+     if (i6 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i6 >> 2] = i2;
+      HEAP32[i2 + 24 >> 2] = i7;
+      HEAP32[i2 + 12 >> 2] = i2;
+      HEAP32[i2 + 8 >> 2] = i2;
+      break L199;
+     }
+    } else {
+     i3 = i5;
+    }
+   } while (0);
+   i5 = i3 + 8 | 0;
+   i4 = HEAP32[i5 >> 2] | 0;
+   i6 = HEAP32[12928 >> 2] | 0;
+   if (i3 >>> 0 < i6 >>> 0) {
+    _abort();
+   }
+   if (i4 >>> 0 < i6 >>> 0) {
+    _abort();
+   } else {
+    HEAP32[i4 + 12 >> 2] = i2;
+    HEAP32[i5 >> 2] = i2;
+    HEAP32[i2 + 8 >> 2] = i4;
+    HEAP32[i2 + 12 >> 2] = i3;
+    HEAP32[i2 + 24 >> 2] = 0;
+    break;
+   }
+  } else {
+   HEAP32[12916 >> 2] = i7 | i6;
+   HEAP32[i5 >> 2] = i2;
+   HEAP32[i2 + 24 >> 2] = i5;
+   HEAP32[i2 + 12 >> 2] = i2;
+   HEAP32[i2 + 8 >> 2] = i2;
+  }
+ } while (0);
+ i21 = (HEAP32[12944 >> 2] | 0) + -1 | 0;
+ HEAP32[12944 >> 2] = i21;
+ if ((i21 | 0) == 0) {
+  i2 = 13368 | 0;
+ } else {
+  STACKTOP = i1;
+  return;
+ }
+ while (1) {
+  i2 = HEAP32[i2 >> 2] | 0;
+  if ((i2 | 0) == 0) {
+   break;
+  } else {
+   i2 = i2 + 8 | 0;
+  }
+ }
+ HEAP32[12944 >> 2] = -1;
+ STACKTOP = i1;
+ return;
+}
+function _dispose_chunk(i6, i7) {
+ i6 = i6 | 0;
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0;
+ i1 = STACKTOP;
+ i5 = i6 + i7 | 0;
+ i10 = HEAP32[i6 + 4 >> 2] | 0;
+ do {
+  if ((i10 & 1 | 0) == 0) {
+   i14 = HEAP32[i6 >> 2] | 0;
+   if ((i10 & 3 | 0) == 0) {
+    STACKTOP = i1;
+    return;
+   }
+   i10 = i6 + (0 - i14) | 0;
+   i11 = i14 + i7 | 0;
+   i15 = HEAP32[12928 >> 2] | 0;
+   if (i10 >>> 0 < i15 >>> 0) {
+    _abort();
+   }
+   if ((i10 | 0) == (HEAP32[12932 >> 2] | 0)) {
+    i2 = i6 + (i7 + 4) | 0;
+    if ((HEAP32[i2 >> 2] & 3 | 0) != 3) {
+     i2 = i10;
+     i12 = i11;
+     break;
+    }
+    HEAP32[12920 >> 2] = i11;
+    HEAP32[i2 >> 2] = HEAP32[i2 >> 2] & -2;
+    HEAP32[i6 + (4 - i14) >> 2] = i11 | 1;
+    HEAP32[i5 >> 2] = i11;
+    STACKTOP = i1;
+    return;
+   }
+   i17 = i14 >>> 3;
+   if (i14 >>> 0 < 256) {
+    i2 = HEAP32[i6 + (8 - i14) >> 2] | 0;
+    i12 = HEAP32[i6 + (12 - i14) >> 2] | 0;
+    i13 = 12952 + (i17 << 1 << 2) | 0;
+    if ((i2 | 0) != (i13 | 0)) {
+     if (i2 >>> 0 < i15 >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i2 + 12 >> 2] | 0) != (i10 | 0)) {
+      _abort();
+     }
+    }
+    if ((i12 | 0) == (i2 | 0)) {
+     HEAP32[3228] = HEAP32[3228] & ~(1 << i17);
+     i2 = i10;
+     i12 = i11;
+     break;
+    }
+    if ((i12 | 0) != (i13 | 0)) {
+     if (i12 >>> 0 < i15 >>> 0) {
+      _abort();
+     }
+     i13 = i12 + 8 | 0;
+     if ((HEAP32[i13 >> 2] | 0) == (i10 | 0)) {
+      i16 = i13;
+     } else {
+      _abort();
+     }
+    } else {
+     i16 = i12 + 8 | 0;
+    }
+    HEAP32[i2 + 12 >> 2] = i12;
+    HEAP32[i16 >> 2] = i2;
+    i2 = i10;
+    i12 = i11;
+    break;
+   }
+   i16 = HEAP32[i6 + (24 - i14) >> 2] | 0;
+   i18 = HEAP32[i6 + (12 - i14) >> 2] | 0;
+   do {
+    if ((i18 | 0) == (i10 | 0)) {
+     i19 = 16 - i14 | 0;
+     i18 = i6 + (i19 + 4) | 0;
+     i17 = HEAP32[i18 >> 2] | 0;
+     if ((i17 | 0) == 0) {
+      i18 = i6 + i19 | 0;
+      i17 = HEAP32[i18 >> 2] | 0;
+      if ((i17 | 0) == 0) {
+       i13 = 0;
+       break;
+      }
+     }
+     while (1) {
+      i19 = i17 + 20 | 0;
+      i20 = HEAP32[i19 >> 2] | 0;
+      if ((i20 | 0) != 0) {
+       i17 = i20;
+       i18 = i19;
+       continue;
+      }
+      i20 = i17 + 16 | 0;
+      i19 = HEAP32[i20 >> 2] | 0;
+      if ((i19 | 0) == 0) {
+       break;
+      } else {
+       i17 = i19;
+       i18 = i20;
+      }
+     }
+     if (i18 >>> 0 < i15 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i18 >> 2] = 0;
+      i13 = i17;
+      break;
+     }
+    } else {
+     i17 = HEAP32[i6 + (8 - i14) >> 2] | 0;
+     if (i17 >>> 0 < i15 >>> 0) {
+      _abort();
+     }
+     i19 = i17 + 12 | 0;
+     if ((HEAP32[i19 >> 2] | 0) != (i10 | 0)) {
+      _abort();
+     }
+     i15 = i18 + 8 | 0;
+     if ((HEAP32[i15 >> 2] | 0) == (i10 | 0)) {
+      HEAP32[i19 >> 2] = i18;
+      HEAP32[i15 >> 2] = i17;
+      i13 = i18;
+      break;
+     } else {
+      _abort();
+     }
+    }
+   } while (0);
+   if ((i16 | 0) != 0) {
+    i15 = HEAP32[i6 + (28 - i14) >> 2] | 0;
+    i17 = 13216 + (i15 << 2) | 0;
+    if ((i10 | 0) == (HEAP32[i17 >> 2] | 0)) {
+     HEAP32[i17 >> 2] = i13;
+     if ((i13 | 0) == 0) {
+      HEAP32[12916 >> 2] = HEAP32[12916 >> 2] & ~(1 << i15);
+      i2 = i10;
+      i12 = i11;
+      break;
+     }
+    } else {
+     if (i16 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i15 = i16 + 16 | 0;
+     if ((HEAP32[i15 >> 2] | 0) == (i10 | 0)) {
+      HEAP32[i15 >> 2] = i13;
+     } else {
+      HEAP32[i16 + 20 >> 2] = i13;
+     }
+     if ((i13 | 0) == 0) {
+      i2 = i10;
+      i12 = i11;
+      break;
+     }
+    }
+    if (i13 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+     _abort();
+    }
+    HEAP32[i13 + 24 >> 2] = i16;
+    i14 = 16 - i14 | 0;
+    i15 = HEAP32[i6 + i14 >> 2] | 0;
+    do {
+     if ((i15 | 0) != 0) {
+      if (i15 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i13 + 16 >> 2] = i15;
+       HEAP32[i15 + 24 >> 2] = i13;
+       break;
+      }
+     }
+    } while (0);
+    i14 = HEAP32[i6 + (i14 + 4) >> 2] | 0;
+    if ((i14 | 0) != 0) {
+     if (i14 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i13 + 20 >> 2] = i14;
+      HEAP32[i14 + 24 >> 2] = i13;
+      i2 = i10;
+      i12 = i11;
+      break;
+     }
+    } else {
+     i2 = i10;
+     i12 = i11;
+    }
+   } else {
+    i2 = i10;
+    i12 = i11;
+   }
+  } else {
+   i2 = i6;
+   i12 = i7;
+  }
+ } while (0);
+ i10 = HEAP32[12928 >> 2] | 0;
+ if (i5 >>> 0 < i10 >>> 0) {
+  _abort();
+ }
+ i11 = i6 + (i7 + 4) | 0;
+ i13 = HEAP32[i11 >> 2] | 0;
+ if ((i13 & 2 | 0) == 0) {
+  if ((i5 | 0) == (HEAP32[12936 >> 2] | 0)) {
+   i20 = (HEAP32[12924 >> 2] | 0) + i12 | 0;
+   HEAP32[12924 >> 2] = i20;
+   HEAP32[12936 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i20 | 1;
+   if ((i2 | 0) != (HEAP32[12932 >> 2] | 0)) {
+    STACKTOP = i1;
+    return;
+   }
+   HEAP32[12932 >> 2] = 0;
+   HEAP32[12920 >> 2] = 0;
+   STACKTOP = i1;
+   return;
+  }
+  if ((i5 | 0) == (HEAP32[12932 >> 2] | 0)) {
+   i20 = (HEAP32[12920 >> 2] | 0) + i12 | 0;
+   HEAP32[12920 >> 2] = i20;
+   HEAP32[12932 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i20 | 1;
+   HEAP32[i2 + i20 >> 2] = i20;
+   STACKTOP = i1;
+   return;
+  }
+  i12 = (i13 & -8) + i12 | 0;
+  i11 = i13 >>> 3;
+  do {
+   if (!(i13 >>> 0 < 256)) {
+    i9 = HEAP32[i6 + (i7 + 24) >> 2] | 0;
+    i11 = HEAP32[i6 + (i7 + 12) >> 2] | 0;
+    do {
+     if ((i11 | 0) == (i5 | 0)) {
+      i13 = i6 + (i7 + 20) | 0;
+      i11 = HEAP32[i13 >> 2] | 0;
+      if ((i11 | 0) == 0) {
+       i13 = i6 + (i7 + 16) | 0;
+       i11 = HEAP32[i13 >> 2] | 0;
+       if ((i11 | 0) == 0) {
+        i8 = 0;
+        break;
+       }
+      }
+      while (1) {
+       i15 = i11 + 20 | 0;
+       i14 = HEAP32[i15 >> 2] | 0;
+       if ((i14 | 0) != 0) {
+        i11 = i14;
+        i13 = i15;
+        continue;
+       }
+       i14 = i11 + 16 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) == 0) {
+        break;
+       } else {
+        i11 = i15;
+        i13 = i14;
+       }
+      }
+      if (i13 >>> 0 < i10 >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i13 >> 2] = 0;
+       i8 = i11;
+       break;
+      }
+     } else {
+      i13 = HEAP32[i6 + (i7 + 8) >> 2] | 0;
+      if (i13 >>> 0 < i10 >>> 0) {
+       _abort();
+      }
+      i10 = i13 + 12 | 0;
+      if ((HEAP32[i10 >> 2] | 0) != (i5 | 0)) {
+       _abort();
+      }
+      i14 = i11 + 8 | 0;
+      if ((HEAP32[i14 >> 2] | 0) == (i5 | 0)) {
+       HEAP32[i10 >> 2] = i11;
+       HEAP32[i14 >> 2] = i13;
+       i8 = i11;
+       break;
+      } else {
+       _abort();
+      }
+     }
+    } while (0);
+    if ((i9 | 0) != 0) {
+     i10 = HEAP32[i6 + (i7 + 28) >> 2] | 0;
+     i11 = 13216 + (i10 << 2) | 0;
+     if ((i5 | 0) == (HEAP32[i11 >> 2] | 0)) {
+      HEAP32[i11 >> 2] = i8;
+      if ((i8 | 0) == 0) {
+       HEAP32[12916 >> 2] = HEAP32[12916 >> 2] & ~(1 << i10);
+       break;
+      }
+     } else {
+      if (i9 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i10 = i9 + 16 | 0;
+      if ((HEAP32[i10 >> 2] | 0) == (i5 | 0)) {
+       HEAP32[i10 >> 2] = i8;
+      } else {
+       HEAP32[i9 + 20 >> 2] = i8;
+      }
+      if ((i8 | 0) == 0) {
+       break;
+      }
+     }
+     if (i8 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     HEAP32[i8 + 24 >> 2] = i9;
+     i5 = HEAP32[i6 + (i7 + 16) >> 2] | 0;
+     do {
+      if ((i5 | 0) != 0) {
+       if (i5 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i8 + 16 >> 2] = i5;
+        HEAP32[i5 + 24 >> 2] = i8;
+        break;
+       }
+      }
+     } while (0);
+     i5 = HEAP32[i6 + (i7 + 20) >> 2] | 0;
+     if ((i5 | 0) != 0) {
+      if (i5 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i8 + 20 >> 2] = i5;
+       HEAP32[i5 + 24 >> 2] = i8;
+       break;
+      }
+     }
+    }
+   } else {
+    i8 = HEAP32[i6 + (i7 + 8) >> 2] | 0;
+    i6 = HEAP32[i6 + (i7 + 12) >> 2] | 0;
+    i7 = 12952 + (i11 << 1 << 2) | 0;
+    if ((i8 | 0) != (i7 | 0)) {
+     if (i8 >>> 0 < i10 >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i8 + 12 >> 2] | 0) != (i5 | 0)) {
+      _abort();
+     }
+    }
+    if ((i6 | 0) == (i8 | 0)) {
+     HEAP32[3228] = HEAP32[3228] & ~(1 << i11);
+     break;
+    }
+    if ((i6 | 0) != (i7 | 0)) {
+     if (i6 >>> 0 < i10 >>> 0) {
+      _abort();
+     }
+     i7 = i6 + 8 | 0;
+     if ((HEAP32[i7 >> 2] | 0) == (i5 | 0)) {
+      i9 = i7;
+     } else {
+      _abort();
+     }
+    } else {
+     i9 = i6 + 8 | 0;
+    }
+    HEAP32[i8 + 12 >> 2] = i6;
+    HEAP32[i9 >> 2] = i8;
+   }
+  } while (0);
+  HEAP32[i2 + 4 >> 2] = i12 | 1;
+  HEAP32[i2 + i12 >> 2] = i12;
+  if ((i2 | 0) == (HEAP32[12932 >> 2] | 0)) {
+   HEAP32[12920 >> 2] = i12;
+   STACKTOP = i1;
+   return;
+  }
+ } else {
+  HEAP32[i11 >> 2] = i13 & -2;
+  HEAP32[i2 + 4 >> 2] = i12 | 1;
+  HEAP32[i2 + i12 >> 2] = i12;
+ }
+ i6 = i12 >>> 3;
+ if (i12 >>> 0 < 256) {
+  i7 = i6 << 1;
+  i5 = 12952 + (i7 << 2) | 0;
+  i8 = HEAP32[3228] | 0;
+  i6 = 1 << i6;
+  if ((i8 & i6 | 0) != 0) {
+   i7 = 12952 + (i7 + 2 << 2) | 0;
+   i6 = HEAP32[i7 >> 2] | 0;
+   if (i6 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+    _abort();
+   } else {
+    i4 = i7;
+    i3 = i6;
+   }
+  } else {
+   HEAP32[3228] = i8 | i6;
+   i4 = 12952 + (i7 + 2 << 2) | 0;
+   i3 = i5;
+  }
+  HEAP32[i4 >> 2] = i2;
+  HEAP32[i3 + 12 >> 2] = i2;
+  HEAP32[i2 + 8 >> 2] = i3;
+  HEAP32[i2 + 12 >> 2] = i5;
+  STACKTOP = i1;
+  return;
+ }
+ i3 = i12 >>> 8;
+ if ((i3 | 0) != 0) {
+  if (i12 >>> 0 > 16777215) {
+   i3 = 31;
+  } else {
+   i19 = (i3 + 1048320 | 0) >>> 16 & 8;
+   i20 = i3 << i19;
+   i18 = (i20 + 520192 | 0) >>> 16 & 4;
+   i20 = i20 << i18;
+   i3 = (i20 + 245760 | 0) >>> 16 & 2;
+   i3 = 14 - (i18 | i19 | i3) + (i20 << i3 >>> 15) | 0;
+   i3 = i12 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+  }
+ } else {
+  i3 = 0;
+ }
+ i6 = 13216 + (i3 << 2) | 0;
+ HEAP32[i2 + 28 >> 2] = i3;
+ HEAP32[i2 + 20 >> 2] = 0;
+ HEAP32[i2 + 16 >> 2] = 0;
+ i5 = HEAP32[12916 >> 2] | 0;
+ i4 = 1 << i3;
+ if ((i5 & i4 | 0) == 0) {
+  HEAP32[12916 >> 2] = i5 | i4;
+  HEAP32[i6 >> 2] = i2;
+  HEAP32[i2 + 24 >> 2] = i6;
+  HEAP32[i2 + 12 >> 2] = i2;
+  HEAP32[i2 + 8 >> 2] = i2;
+  STACKTOP = i1;
+  return;
+ }
+ i4 = HEAP32[i6 >> 2] | 0;
+ if ((i3 | 0) == 31) {
+  i3 = 0;
+ } else {
+  i3 = 25 - (i3 >>> 1) | 0;
+ }
+ L194 : do {
+  if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i12 | 0)) {
+   i3 = i12 << i3;
+   i6 = i4;
+   while (1) {
+    i5 = i6 + (i3 >>> 31 << 2) + 16 | 0;
+    i4 = HEAP32[i5 >> 2] | 0;
+    if ((i4 | 0) == 0) {
+     break;
+    }
+    if ((HEAP32[i4 + 4 >> 2] & -8 | 0) == (i12 | 0)) {
+     break L194;
+    } else {
+     i3 = i3 << 1;
+     i6 = i4;
+    }
+   }
+   if (i5 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+    _abort();
+   }
+   HEAP32[i5 >> 2] = i2;
+   HEAP32[i2 + 24 >> 2] = i6;
+   HEAP32[i2 + 12 >> 2] = i2;
+   HEAP32[i2 + 8 >> 2] = i2;
+   STACKTOP = i1;
+   return;
+  }
+ } while (0);
+ i3 = i4 + 8 | 0;
+ i6 = HEAP32[i3 >> 2] | 0;
+ i5 = HEAP32[12928 >> 2] | 0;
+ if (i4 >>> 0 < i5 >>> 0) {
+  _abort();
+ }
+ if (i6 >>> 0 < i5 >>> 0) {
+  _abort();
+ }
+ HEAP32[i6 + 12 >> 2] = i2;
+ HEAP32[i3 >> 2] = i2;
+ HEAP32[i2 + 8 >> 2] = i6;
+ HEAP32[i2 + 12 >> 2] = i4;
+ HEAP32[i2 + 24 >> 2] = 0;
+ STACKTOP = i1;
+ return;
+}
+function _singlestep(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i14 = i1;
+ i3 = i2 + 12 | 0;
+ i8 = HEAP32[i3 >> 2] | 0;
+ i6 = i8 + 61 | 0;
+ switch (HEAPU8[i6] | 0) {
+ case 0:
+  {
+   if ((HEAP32[i8 + 84 >> 2] | 0) != 0) {
+    i21 = i8 + 16 | 0;
+    i22 = HEAP32[i21 >> 2] | 0;
+    _propagatemark(i8);
+    i22 = (HEAP32[i21 >> 2] | 0) - i22 | 0;
+    STACKTOP = i1;
+    return i22 | 0;
+   }
+   HEAP8[i6] = 1;
+   i6 = i8 + 20 | 0;
+   HEAP32[i6 >> 2] = HEAP32[i8 + 16 >> 2];
+   i8 = HEAP32[i3 >> 2] | 0;
+   i7 = i8 + 16 | 0;
+   i14 = HEAP32[i7 >> 2] | 0;
+   if ((i2 | 0) != 0 ? !((HEAP8[i2 + 5 | 0] & 3) == 0) : 0) {
+    _reallymarkobject(i8, i2);
+   }
+   if ((HEAP32[i8 + 48 >> 2] & 64 | 0) != 0 ? (i13 = HEAP32[i8 + 40 >> 2] | 0, !((HEAP8[i13 + 5 | 0] & 3) == 0)) : 0) {
+    _reallymarkobject(i8, i13);
+   }
+   _markmt(i8);
+   i13 = i8 + 112 | 0;
+   i15 = HEAP32[i8 + 132 >> 2] | 0;
+   if ((i15 | 0) != (i13 | 0)) {
+    do {
+     if (((HEAP8[i15 + 5 | 0] & 7) == 0 ? (i12 = HEAP32[i15 + 8 >> 2] | 0, (HEAP32[i12 + 8 >> 2] & 64 | 0) != 0) : 0) ? (i11 = HEAP32[i12 >> 2] | 0, !((HEAP8[i11 + 5 | 0] & 3) == 0)) : 0) {
+      _reallymarkobject(i8, i11);
+     }
+     i15 = HEAP32[i15 + 20 >> 2] | 0;
+    } while ((i15 | 0) != (i13 | 0));
+   }
+   i16 = i8 + 84 | 0;
+   if ((HEAP32[i16 >> 2] | 0) != 0) {
+    do {
+     _propagatemark(i8);
+    } while ((HEAP32[i16 >> 2] | 0) != 0);
+   }
+   i17 = (HEAP32[i7 >> 2] | 0) - i14 | 0;
+   i11 = i8 + 92 | 0;
+   i12 = HEAP32[i11 >> 2] | 0;
+   i21 = i8 + 88 | 0;
+   i22 = HEAP32[i21 >> 2] | 0;
+   i15 = i8 + 96 | 0;
+   i13 = HEAP32[i15 >> 2] | 0;
+   HEAP32[i15 >> 2] = 0;
+   HEAP32[i21 >> 2] = 0;
+   HEAP32[i11 >> 2] = 0;
+   HEAP32[i16 >> 2] = i22;
+   if ((i22 | 0) != 0) {
+    do {
+     _propagatemark(i8);
+    } while ((HEAP32[i16 >> 2] | 0) != 0);
+   }
+   HEAP32[i16 >> 2] = i12;
+   if ((i12 | 0) != 0) {
+    do {
+     _propagatemark(i8);
+    } while ((HEAP32[i16 >> 2] | 0) != 0);
+   }
+   HEAP32[i16 >> 2] = i13;
+   if ((i13 | 0) != 0) {
+    do {
+     _propagatemark(i8);
+    } while ((HEAP32[i16 >> 2] | 0) != 0);
+   }
+   i18 = HEAP32[i7 >> 2] | 0;
+   while (1) {
+    i13 = HEAP32[i15 >> 2] | 0;
+    HEAP32[i15 >> 2] = 0;
+    i12 = 0;
+    L42 : while (1) {
+     i14 = i13;
+     while (1) {
+      if ((i14 | 0) == 0) {
+       break L42;
+      }
+      i13 = HEAP32[i14 + 24 >> 2] | 0;
+      if ((_traverseephemeron(i8, i14) | 0) == 0) {
+       i14 = i13;
+      } else {
+       break;
+      }
+     }
+     if ((HEAP32[i16 >> 2] | 0) == 0) {
+      i12 = 1;
+      continue;
+     }
+     while (1) {
+      _propagatemark(i8);
+      if ((HEAP32[i16 >> 2] | 0) == 0) {
+       i12 = 1;
+       continue L42;
+      }
+     }
+    }
+    if ((i12 | 0) == 0) {
+     break;
+    }
+   }
+   _clearvalues(i8, HEAP32[i11 >> 2] | 0, 0);
+   i14 = i8 + 100 | 0;
+   _clearvalues(i8, HEAP32[i14 >> 2] | 0, 0);
+   i13 = HEAP32[i11 >> 2] | 0;
+   i12 = HEAP32[i14 >> 2] | 0;
+   i21 = HEAP32[i7 >> 2] | 0;
+   i20 = HEAP32[i3 >> 2] | 0;
+   i19 = i20 + 104 | 0;
+   while (1) {
+    i22 = HEAP32[i19 >> 2] | 0;
+    if ((i22 | 0) == 0) {
+     break;
+    } else {
+     i19 = i22;
+    }
+   }
+   i17 = i17 - i18 + i21 | 0;
+   i20 = i20 + 72 | 0;
+   i21 = HEAP32[i20 >> 2] | 0;
+   L55 : do {
+    if ((i21 | 0) != 0) {
+     while (1) {
+      i18 = i21;
+      while (1) {
+       i22 = i18 + 5 | 0;
+       i21 = HEAP8[i22] | 0;
+       if ((i21 & 3) == 0) {
+        break;
+       }
+       HEAP8[i22] = i21 & 255 | 8;
+       HEAP32[i20 >> 2] = HEAP32[i18 >> 2];
+       HEAP32[i18 >> 2] = HEAP32[i19 >> 2];
+       HEAP32[i19 >> 2] = i18;
+       i19 = HEAP32[i20 >> 2] | 0;
+       if ((i19 | 0) == 0) {
+        break L55;
+       } else {
+        i22 = i18;
+        i18 = i19;
+        i19 = i22;
+       }
+      }
+      i21 = HEAP32[i18 >> 2] | 0;
+      if ((i21 | 0) == 0) {
+       break;
+      } else {
+       i20 = i18;
+      }
+     }
+    }
+   } while (0);
+   i19 = HEAP32[i8 + 104 >> 2] | 0;
+   if ((i19 | 0) != 0) {
+    i18 = i8 + 60 | 0;
+    do {
+     i22 = i19 + 5 | 0;
+     HEAP8[i22] = HEAP8[i18] & 3 | HEAP8[i22] & 184;
+     _reallymarkobject(i8, i19);
+     i19 = HEAP32[i19 >> 2] | 0;
+    } while ((i19 | 0) != 0);
+   }
+   if ((HEAP32[i16 >> 2] | 0) != 0) {
+    do {
+     _propagatemark(i8);
+    } while ((HEAP32[i16 >> 2] | 0) != 0);
+   }
+   i18 = HEAP32[i7 >> 2] | 0;
+   while (1) {
+    i20 = HEAP32[i15 >> 2] | 0;
+    HEAP32[i15 >> 2] = 0;
+    i19 = 0;
+    L74 : while (1) {
+     i21 = i20;
+     while (1) {
+      if ((i21 | 0) == 0) {
+       break L74;
+      }
+      i20 = HEAP32[i21 + 24 >> 2] | 0;
+      if ((_traverseephemeron(i8, i21) | 0) == 0) {
+       i21 = i20;
+      } else {
+       break;
+      }
+     }
+     if ((HEAP32[i16 >> 2] | 0) == 0) {
+      i19 = 1;
+      continue;
+     }
+     while (1) {
+      _propagatemark(i8);
+      if ((HEAP32[i16 >> 2] | 0) == 0) {
+       i19 = 1;
+       continue L74;
+      }
+     }
+    }
+    if ((i19 | 0) == 0) {
+     break;
+    }
+   }
+   i16 = i17 - i18 | 0;
+   i15 = HEAP32[i15 >> 2] | 0;
+   if ((i15 | 0) != 0) {
+    do {
+     i22 = 1 << HEAPU8[i15 + 7 | 0];
+     i19 = HEAP32[i15 + 16 >> 2] | 0;
+     i17 = i19 + (i22 << 5) | 0;
+     if ((i22 | 0) > 0) {
+      do {
+       i18 = i19 + 8 | 0;
+       do {
+        if ((HEAP32[i18 >> 2] | 0) != 0 ? (i9 = i19 + 24 | 0, i10 = HEAP32[i9 >> 2] | 0, (i10 & 64 | 0) != 0) : 0) {
+         i20 = HEAP32[i19 + 16 >> 2] | 0;
+         if ((i10 & 15 | 0) == 4) {
+          if ((i20 | 0) == 0) {
+           break;
+          }
+          if ((HEAP8[i20 + 5 | 0] & 3) == 0) {
+           break;
+          }
+          _reallymarkobject(i8, i20);
+          break;
+         } else {
+          i20 = i20 + 5 | 0;
+          if ((HEAP8[i20] & 3) == 0) {
+           break;
+          }
+          HEAP32[i18 >> 2] = 0;
+          if ((HEAP8[i20] & 3) == 0) {
+           break;
+          }
+          HEAP32[i9 >> 2] = 11;
+          break;
+         }
+        }
+       } while (0);
+       i19 = i19 + 32 | 0;
+      } while (i19 >>> 0 < i17 >>> 0);
+     }
+     i15 = HEAP32[i15 + 24 >> 2] | 0;
+    } while ((i15 | 0) != 0);
+   }
+   i10 = HEAP32[i14 >> 2] | 0;
+   if ((i10 | 0) != 0) {
+    do {
+     i22 = 1 << HEAPU8[i10 + 7 | 0];
+     i17 = HEAP32[i10 + 16 >> 2] | 0;
+     i9 = i17 + (i22 << 5) | 0;
+     if ((i22 | 0) > 0) {
+      do {
+       i15 = i17 + 8 | 0;
+       do {
+        if ((HEAP32[i15 >> 2] | 0) != 0 ? (i5 = i17 + 24 | 0, i4 = HEAP32[i5 >> 2] | 0, (i4 & 64 | 0) != 0) : 0) {
+         i18 = HEAP32[i17 + 16 >> 2] | 0;
+         if ((i4 & 15 | 0) == 4) {
+          if ((i18 | 0) == 0) {
+           break;
+          }
+          if ((HEAP8[i18 + 5 | 0] & 3) == 0) {
+           break;
+          }
+          _reallymarkobject(i8, i18);
+          break;
+         } else {
+          i18 = i18 + 5 | 0;
+          if ((HEAP8[i18] & 3) == 0) {
+           break;
+          }
+          HEAP32[i15 >> 2] = 0;
+          if ((HEAP8[i18] & 3) == 0) {
+           break;
+          }
+          HEAP32[i5 >> 2] = 11;
+          break;
+         }
+        }
+       } while (0);
+       i17 = i17 + 32 | 0;
+      } while (i17 >>> 0 < i9 >>> 0);
+     }
+     i10 = HEAP32[i10 + 24 >> 2] | 0;
+    } while ((i10 | 0) != 0);
+   }
+   _clearvalues(i8, HEAP32[i11 >> 2] | 0, i13);
+   _clearvalues(i8, HEAP32[i14 >> 2] | 0, i12);
+   i4 = i8 + 60 | 0;
+   HEAP8[i4] = HEAPU8[i4] ^ 3;
+   i4 = i16 + (HEAP32[i7 >> 2] | 0) | 0;
+   HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i4;
+   i3 = HEAP32[i3 >> 2] | 0;
+   HEAP8[i3 + 61 | 0] = 2;
+   HEAP32[i3 + 64 >> 2] = 0;
+   i7 = i3 + 72 | 0;
+   i5 = 0;
+   do {
+    i5 = i5 + 1 | 0;
+    i6 = _sweeplist(i2, i7, 1) | 0;
+   } while ((i6 | 0) == (i7 | 0));
+   HEAP32[i3 + 80 >> 2] = i6;
+   i6 = i3 + 68 | 0;
+   i7 = 0;
+   do {
+    i7 = i7 + 1 | 0;
+    i8 = _sweeplist(i2, i6, 1) | 0;
+   } while ((i8 | 0) == (i6 | 0));
+   HEAP32[i3 + 76 >> 2] = i8;
+   i22 = ((i7 + i5 | 0) * 5 | 0) + i4 | 0;
+   STACKTOP = i1;
+   return i22 | 0;
+  }
+ case 2:
+  {
+   i3 = i8 + 64 | 0;
+   i4 = i8 + 32 | 0;
+   i8 = i8 + 24 | 0;
+   i5 = 0;
+   while (1) {
+    i10 = HEAP32[i3 >> 2] | 0;
+    i11 = i10 + i5 | 0;
+    i9 = HEAP32[i4 >> 2] | 0;
+    if ((i11 | 0) >= (i9 | 0)) {
+     i2 = i10;
+     break;
+    }
+    _sweeplist(i2, (HEAP32[i8 >> 2] | 0) + (i11 << 2) | 0, -3) | 0;
+    i5 = i5 + 1 | 0;
+    if ((i5 | 0) >= 80) {
+     i7 = 96;
+     break;
+    }
+   }
+   if ((i7 | 0) == 96) {
+    i2 = HEAP32[i3 >> 2] | 0;
+    i9 = HEAP32[i4 >> 2] | 0;
+   }
+   i22 = i2 + i5 | 0;
+   HEAP32[i3 >> 2] = i22;
+   if ((i22 | 0) >= (i9 | 0)) {
+    HEAP8[i6] = 3;
+   }
+   i22 = i5 * 5 | 0;
+   STACKTOP = i1;
+   return i22 | 0;
+  }
+ case 5:
+  {
+   i2 = i8 + 16 | 0;
+   HEAP32[i2 >> 2] = HEAP32[i8 + 32 >> 2] << 2;
+   i22 = i8 + 84 | 0;
+   i3 = i8 + 172 | 0;
+   HEAP32[i22 + 0 >> 2] = 0;
+   HEAP32[i22 + 4 >> 2] = 0;
+   HEAP32[i22 + 8 >> 2] = 0;
+   HEAP32[i22 + 12 >> 2] = 0;
+   HEAP32[i22 + 16 >> 2] = 0;
+   i3 = HEAP32[i3 >> 2] | 0;
+   if ((i3 | 0) != 0 ? !((HEAP8[i3 + 5 | 0] & 3) == 0) : 0) {
+    _reallymarkobject(i8, i3);
+   }
+   if ((HEAP32[i8 + 48 >> 2] & 64 | 0) != 0 ? (i15 = HEAP32[i8 + 40 >> 2] | 0, !((HEAP8[i15 + 5 | 0] & 3) == 0)) : 0) {
+    _reallymarkobject(i8, i15);
+   }
+   _markmt(i8);
+   i4 = HEAP32[i8 + 104 >> 2] | 0;
+   if ((i4 | 0) != 0) {
+    i3 = i8 + 60 | 0;
+    do {
+     i22 = i4 + 5 | 0;
+     HEAP8[i22] = HEAP8[i3] & 3 | HEAP8[i22] & 184;
+     _reallymarkobject(i8, i4);
+     i4 = HEAP32[i4 >> 2] | 0;
+    } while ((i4 | 0) != 0);
+   }
+   HEAP8[i6] = 0;
+   i22 = HEAP32[i2 >> 2] | 0;
+   STACKTOP = i1;
+   return i22 | 0;
+  }
+ case 3:
+  {
+   i3 = i8 + 80 | 0;
+   i4 = HEAP32[i3 >> 2] | 0;
+   if ((i4 | 0) == 0) {
+    HEAP8[i6] = 4;
+    i22 = 0;
+    STACKTOP = i1;
+    return i22 | 0;
+   } else {
+    HEAP32[i3 >> 2] = _sweeplist(i2, i4, 80) | 0;
+    i22 = 400;
+    STACKTOP = i1;
+    return i22 | 0;
+   }
+  }
+ case 4:
+  {
+   i4 = i8 + 76 | 0;
+   i5 = HEAP32[i4 >> 2] | 0;
+   if ((i5 | 0) != 0) {
+    HEAP32[i4 >> 2] = _sweeplist(i2, i5, 80) | 0;
+    i22 = 400;
+    STACKTOP = i1;
+    return i22 | 0;
+   }
+   HEAP32[i14 >> 2] = HEAP32[i8 + 172 >> 2];
+   _sweeplist(i2, i14, 1) | 0;
+   i3 = HEAP32[i3 >> 2] | 0;
+   if ((HEAP8[i3 + 62 | 0] | 0) != 1) {
+    i4 = (HEAP32[i3 + 32 >> 2] | 0) / 2 | 0;
+    if ((HEAP32[i3 + 28 >> 2] | 0) >>> 0 < i4 >>> 0) {
+     _luaS_resize(i2, i4);
+    }
+    i21 = i3 + 144 | 0;
+    i22 = i3 + 152 | 0;
+    HEAP32[i21 >> 2] = _luaM_realloc_(i2, HEAP32[i21 >> 2] | 0, HEAP32[i22 >> 2] | 0, 0) | 0;
+    HEAP32[i22 >> 2] = 0;
+   }
+   HEAP8[i6] = 5;
+   i22 = 5;
+   STACKTOP = i1;
+   return i22 | 0;
+  }
+ default:
+  {
+   i22 = 0;
+   STACKTOP = i1;
+   return i22 | 0;
+  }
+ }
+ return 0;
+}
+function _pmain(i3) {
+ i3 = i3 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i1;
+ i7 = _lua_tointegerx(i3, 1, 0) | 0;
+ i4 = _lua_touserdata(i3, 2) | 0;
+ i5 = HEAP32[i4 >> 2] | 0;
+ if ((i5 | 0) != 0 ? (HEAP8[i5] | 0) != 0 : 0) {
+  HEAP32[20] = i5;
+ }
+ i12 = HEAP32[i4 + 4 >> 2] | 0;
+ do {
+  if ((i12 | 0) == 0) {
+   i5 = 0;
+   i6 = 0;
+   i8 = 0;
+   i9 = 1;
+   i10 = 1;
+  } else {
+   i9 = 0;
+   i8 = 0;
+   i11 = 0;
+   i6 = 0;
+   i5 = 1;
+   L6 : while (1) {
+    if ((HEAP8[i12] | 0) != 45) {
+     i10 = 18;
+     break;
+    }
+    switch (HEAP8[i12 + 1 | 0] | 0) {
+    case 108:
+     {
+      i10 = 12;
+      break;
+     }
+    case 69:
+     {
+      i9 = 1;
+      break;
+     }
+    case 45:
+     {
+      i10 = 7;
+      break L6;
+     }
+    case 105:
+     {
+      if ((HEAP8[i12 + 2 | 0] | 0) == 0) {
+       i11 = 1;
+       i6 = 1;
+      } else {
+       i5 = -1;
+       break L6;
+      }
+      break;
+     }
+    case 101:
+     {
+      i8 = 1;
+      i10 = 12;
+      break;
+     }
+    case 118:
+     {
+      if ((HEAP8[i12 + 2 | 0] | 0) == 0) {
+       i11 = 1;
+      } else {
+       i5 = -1;
+       break L6;
+      }
+      break;
+     }
+    case 0:
+     {
+      i10 = 18;
+      break L6;
+     }
+    default:
+     {
+      i10 = 16;
+      break L6;
+     }
+    }
+    if ((i10 | 0) == 12) {
+     i10 = 0;
+     if ((HEAP8[i12 + 2 | 0] | 0) == 0) {
+      i12 = i5 + 1 | 0;
+      i13 = HEAP32[i4 + (i12 << 2) >> 2] | 0;
+      if ((i13 | 0) == 0) {
+       i10 = 15;
+       break;
+      }
+      if ((HEAP8[i13] | 0) == 45) {
+       i10 = 15;
+       break;
+      } else {
+       i5 = i12;
+      }
+     }
+    }
+    i5 = i5 + 1 | 0;
+    i12 = HEAP32[i4 + (i5 << 2) >> 2] | 0;
+    if ((i12 | 0) == 0) {
+     i5 = 0;
+     i12 = i9;
+     i10 = 23;
+     break;
+    }
+   }
+   if ((i10 | 0) == 7) {
+    if ((HEAP8[i12 + 2 | 0] | 0) == 0) {
+     i5 = i5 + 1 | 0;
+     i5 = (HEAP32[i4 + (i5 << 2) >> 2] | 0) == 0 ? 0 : i5;
+     i10 = 18;
+    } else {
+     i5 = -1;
+    }
+   } else if ((i10 | 0) == 15) {
+    i5 = 0 - i5 | 0;
+    i10 = 18;
+   } else if ((i10 | 0) == 16) {
+    i5 = 0 - i5 | 0;
+    i10 = 18;
+   }
+   if ((i10 | 0) == 18) {
+    if ((i5 | 0) >= 0) {
+     i12 = i9;
+     i10 = 23;
+    }
+   }
+   if ((i10 | 0) == 23) {
+    if ((i11 | 0) == 0) {
+     i9 = 1;
+    } else {
+     i9 = HEAP32[_stdout >> 2] | 0;
+     _fwrite(440, 1, 51, i9 | 0) | 0;
+     _fputc(10, i9 | 0) | 0;
+     _fflush(i9 | 0) | 0;
+     i9 = 0;
+    }
+    if ((i12 | 0) == 0) {
+     i10 = 1;
+     break;
+    }
+    _lua_pushboolean(i3, 1);
+    _lua_setfield(i3, -1001e3, 96);
+    i10 = 0;
+    break;
+   }
+   i3 = HEAP32[i4 + (0 - i5 << 2) >> 2] | 0;
+   i4 = HEAP32[_stderr >> 2] | 0;
+   HEAP32[i2 >> 2] = HEAP32[20];
+   _fprintf(i4 | 0, 496, i2 | 0) | 0;
+   _fflush(i4 | 0) | 0;
+   i13 = HEAP8[i3 + 1 | 0] | 0;
+   if (i13 << 24 >> 24 == 108 | i13 << 24 >> 24 == 101) {
+    HEAP32[i2 >> 2] = i3;
+    _fprintf(i4 | 0, 504, i2 | 0) | 0;
+    _fflush(i4 | 0) | 0;
+   } else {
+    HEAP32[i2 >> 2] = i3;
+    _fprintf(i4 | 0, 528, i2 | 0) | 0;
+    _fflush(i4 | 0) | 0;
+   }
+   HEAP32[i2 >> 2] = HEAP32[20];
+   _fprintf(i4 | 0, 560, i2 | 0) | 0;
+   _fflush(i4 | 0) | 0;
+   i13 = 0;
+   STACKTOP = i1;
+   return i13 | 0;
+  }
+ } while (0);
+ _luaL_checkversion_(i3, 502.0);
+ _lua_gc(i3, 0, 0) | 0;
+ _luaL_openlibs(i3);
+ _lua_gc(i3, 1, 0) | 0;
+ do {
+  if (i10) {
+   i10 = _getenv(409 | 0) | 0;
+   if ((i10 | 0) == 0) {
+    i10 = _getenv(425 | 0) | 0;
+    if ((i10 | 0) == 0) {
+     break;
+    } else {
+     i11 = 424;
+    }
+   } else {
+    i11 = 408;
+   }
+   if ((HEAP8[i10] | 0) == 64) {
+    i13 = _luaL_loadfilex(i3, i10 + 1 | 0, 0) | 0;
+    if ((i13 | 0) == 0) {
+     i12 = _lua_gettop(i3) | 0;
+     _lua_pushcclosure(i3, 142, 0);
+     _lua_insert(i3, i12);
+     HEAP32[48] = i3;
+     _signal(2, 1) | 0;
+     i13 = _lua_pcallk(i3, 0, 0, i12, 0, 0) | 0;
+     _signal(2, 0) | 0;
+     _lua_remove(i3, i12);
+     if ((i13 | 0) == 0) {
+      break;
+     }
+    }
+    if ((_lua_type(i3, -1) | 0) == 0) {
+     i13 = 0;
+     STACKTOP = i1;
+     return i13 | 0;
+    }
+    i11 = _lua_tolstring(i3, -1, 0) | 0;
+    i12 = HEAP32[20] | 0;
+    i10 = HEAP32[_stderr >> 2] | 0;
+    if ((i12 | 0) != 0) {
+     HEAP32[i2 >> 2] = i12;
+     _fprintf(i10 | 0, 496, i2 | 0) | 0;
+     _fflush(i10 | 0) | 0;
+    }
+    HEAP32[i2 >> 2] = (i11 | 0) == 0 ? 48 : i11;
+    _fprintf(i10 | 0, 912, i2 | 0) | 0;
+    _fflush(i10 | 0) | 0;
+    _lua_settop(i3, -2);
+    _lua_gc(i3, 2, 0) | 0;
+   } else {
+    i13 = _luaL_loadbufferx(i3, i10, _strlen(i10 | 0) | 0, i11, 0) | 0;
+    if ((i13 | 0) == 0) {
+     i12 = _lua_gettop(i3) | 0;
+     _lua_pushcclosure(i3, 142, 0);
+     _lua_insert(i3, i12);
+     HEAP32[48] = i3;
+     _signal(2, 1) | 0;
+     i13 = _lua_pcallk(i3, 0, 0, i12, 0, 0) | 0;
+     _signal(2, 0) | 0;
+     _lua_remove(i3, i12);
+     if ((i13 | 0) == 0) {
+      break;
+     }
+    }
+    if ((_lua_type(i3, -1) | 0) == 0) {
+     i13 = 0;
+     STACKTOP = i1;
+     return i13 | 0;
+    }
+    i11 = _lua_tolstring(i3, -1, 0) | 0;
+    i10 = HEAP32[20] | 0;
+    i12 = HEAP32[_stderr >> 2] | 0;
+    if ((i10 | 0) != 0) {
+     HEAP32[i2 >> 2] = i10;
+     _fprintf(i12 | 0, 496, i2 | 0) | 0;
+     _fflush(i12 | 0) | 0;
+    }
+    HEAP32[i2 >> 2] = (i11 | 0) == 0 ? 48 : i11;
+    _fprintf(i12 | 0, 912, i2 | 0) | 0;
+    _fflush(i12 | 0) | 0;
+    _lua_settop(i3, -2);
+    _lua_gc(i3, 2, 0) | 0;
+   }
+   if ((i13 | 0) != 0) {
+    i13 = 0;
+    STACKTOP = i1;
+    return i13 | 0;
+   }
+  }
+ } while (0);
+ i7 = (i5 | 0) > 0 ? i5 : i7;
+ L67 : do {
+  if ((i7 | 0) > 1) {
+   i10 = 1;
+   while (1) {
+    i11 = HEAP32[i4 + (i10 << 2) >> 2] | 0;
+    i12 = HEAP8[i11 + 1 | 0] | 0;
+    if ((i12 | 0) == 108) {
+     i11 = i11 + 2 | 0;
+     if ((HEAP8[i11] | 0) == 0) {
+      i10 = i10 + 1 | 0;
+      i11 = HEAP32[i4 + (i10 << 2) >> 2] | 0;
+     }
+     _lua_getglobal(i3, 400);
+     _lua_pushstring(i3, i11) | 0;
+     i12 = (_lua_gettop(i3) | 0) + -1 | 0;
+     _lua_pushcclosure(i3, 142, 0);
+     _lua_insert(i3, i12);
+     HEAP32[48] = i3;
+     _signal(2, 1) | 0;
+     i13 = _lua_pcallk(i3, 1, 1, i12, 0, 0) | 0;
+     _signal(2, 0) | 0;
+     _lua_remove(i3, i12);
+     if ((i13 | 0) != 0) {
+      i10 = 58;
+      break;
+     }
+     _lua_setglobal(i3, i11);
+    } else if ((i12 | 0) == 101) {
+     i11 = i11 + 2 | 0;
+     if ((HEAP8[i11] | 0) == 0) {
+      i10 = i10 + 1 | 0;
+      i11 = HEAP32[i4 + (i10 << 2) >> 2] | 0;
+     }
+     if ((_luaL_loadbufferx(i3, i11, _strlen(i11 | 0) | 0, 384, 0) | 0) != 0) {
+      i10 = 50;
+      break;
+     }
+     i12 = _lua_gettop(i3) | 0;
+     _lua_pushcclosure(i3, 142, 0);
+     _lua_insert(i3, i12);
+     HEAP32[48] = i3;
+     _signal(2, 1) | 0;
+     i13 = _lua_pcallk(i3, 0, 0, i12, 0, 0) | 0;
+     _signal(2, 0) | 0;
+     _lua_remove(i3, i12);
+     if ((i13 | 0) != 0) {
+      i10 = 50;
+      break;
+     }
+    }
+    i10 = i10 + 1 | 0;
+    if ((i10 | 0) >= (i7 | 0)) {
+     break L67;
+    }
+   }
+   if ((i10 | 0) == 50) {
+    if ((_lua_type(i3, -1) | 0) == 0) {
+     i13 = 0;
+     STACKTOP = i1;
+     return i13 | 0;
+    }
+    i5 = _lua_tolstring(i3, -1, 0) | 0;
+    i6 = HEAP32[20] | 0;
+    i4 = HEAP32[_stderr >> 2] | 0;
+    if ((i6 | 0) != 0) {
+     HEAP32[i2 >> 2] = i6;
+     _fprintf(i4 | 0, 496, i2 | 0) | 0;
+     _fflush(i4 | 0) | 0;
+    }
+    HEAP32[i2 >> 2] = (i5 | 0) == 0 ? 48 : i5;
+    _fprintf(i4 | 0, 912, i2 | 0) | 0;
+    _fflush(i4 | 0) | 0;
+    _lua_settop(i3, -2);
+    _lua_gc(i3, 2, 0) | 0;
+    i13 = 0;
+    STACKTOP = i1;
+    return i13 | 0;
+   } else if ((i10 | 0) == 58) {
+    if ((_lua_type(i3, -1) | 0) == 0) {
+     i13 = 0;
+     STACKTOP = i1;
+     return i13 | 0;
+    }
+    i5 = _lua_tolstring(i3, -1, 0) | 0;
+    i6 = HEAP32[20] | 0;
+    i4 = HEAP32[_stderr >> 2] | 0;
+    if ((i6 | 0) != 0) {
+     HEAP32[i2 >> 2] = i6;
+     _fprintf(i4 | 0, 496, i2 | 0) | 0;
+     _fflush(i4 | 0) | 0;
+    }
+    HEAP32[i2 >> 2] = (i5 | 0) == 0 ? 48 : i5;
+    _fprintf(i4 | 0, 912, i2 | 0) | 0;
+    _fflush(i4 | 0) | 0;
+    _lua_settop(i3, -2);
+    _lua_gc(i3, 2, 0) | 0;
+    i13 = 0;
+    STACKTOP = i1;
+    return i13 | 0;
+   }
+  }
+ } while (0);
+ do {
+  if ((i5 | 0) != 0) {
+   i10 = 0;
+   while (1) {
+    if ((HEAP32[i4 + (i10 << 2) >> 2] | 0) == 0) {
+     break;
+    } else {
+     i10 = i10 + 1 | 0;
+    }
+   }
+   i11 = i5 + 1 | 0;
+   i7 = i10 - i11 | 0;
+   _luaL_checkstack(i3, i7 + 3 | 0, 352);
+   if ((i11 | 0) < (i10 | 0)) {
+    i12 = i11;
+    do {
+     _lua_pushstring(i3, HEAP32[i4 + (i12 << 2) >> 2] | 0) | 0;
+     i12 = i12 + 1 | 0;
+    } while ((i12 | 0) != (i10 | 0));
+   }
+   _lua_createtable(i3, i7, i11);
+   if ((i10 | 0) > 0) {
+    i11 = 0;
+    do {
+     _lua_pushstring(i3, HEAP32[i4 + (i11 << 2) >> 2] | 0) | 0;
+     _lua_rawseti(i3, -2, i11 - i5 | 0);
+     i11 = i11 + 1 | 0;
+    } while ((i11 | 0) != (i10 | 0));
+   }
+   _lua_setglobal(i3, 328);
+   i10 = HEAP32[i4 + (i5 << 2) >> 2] | 0;
+   if ((_strcmp(i10, 336) | 0) == 0) {
+    i13 = (_strcmp(HEAP32[i4 + (i5 + -1 << 2) >> 2] | 0, 344) | 0) == 0;
+    i10 = i13 ? i10 : 0;
+   }
+   i10 = _luaL_loadfilex(i3, i10, 0) | 0;
+   i4 = ~i7;
+   _lua_insert(i3, i4);
+   if ((i10 | 0) == 0) {
+    i13 = (_lua_gettop(i3) | 0) - i7 | 0;
+    _lua_pushcclosure(i3, 142, 0);
+    _lua_insert(i3, i13);
+    HEAP32[48] = i3;
+    _signal(2, 1) | 0;
+    i10 = _lua_pcallk(i3, i7, -1, i13, 0, 0) | 0;
+    _signal(2, 0) | 0;
+    _lua_remove(i3, i13);
+    if ((i10 | 0) == 0) {
+     break;
+    }
+   } else {
+    _lua_settop(i3, i4);
+   }
+   if ((_lua_type(i3, -1) | 0) != 0) {
+    i7 = _lua_tolstring(i3, -1, 0) | 0;
+    i11 = HEAP32[20] | 0;
+    i4 = HEAP32[_stderr >> 2] | 0;
+    if ((i11 | 0) != 0) {
+     HEAP32[i2 >> 2] = i11;
+     _fprintf(i4 | 0, 496, i2 | 0) | 0;
+     _fflush(i4 | 0) | 0;
+    }
+    HEAP32[i2 >> 2] = (i7 | 0) == 0 ? 48 : i7;
+    _fprintf(i4 | 0, 912, i2 | 0) | 0;
+    _fflush(i4 | 0) | 0;
+    _lua_settop(i3, -2);
+    _lua_gc(i3, 2, 0) | 0;
+   }
+   if ((i10 | 0) != 0) {
+    i13 = 0;
+    STACKTOP = i1;
+    return i13 | 0;
+   }
+  }
+ } while (0);
+ if ((i6 | 0) == 0) {
+  if (!((i8 | i5 | 0) != 0 | i9 ^ 1)) {
+   i13 = HEAP32[_stdout >> 2] | 0;
+   _fwrite(440, 1, 51, i13 | 0) | 0;
+   _fputc(10, i13 | 0) | 0;
+   _fflush(i13 | 0) | 0;
+   _dotty(i3);
+  }
+ } else {
+  _dotty(i3);
+ }
+ _lua_pushboolean(i3, 1);
+ i13 = 1;
+ STACKTOP = i1;
+ return i13 | 0;
+}
+function _DumpFunction(i6, i2) {
+ i6 = i6 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0;
+ i5 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i17 = i5 + 56 | 0;
+ i19 = i5 + 52 | 0;
+ i20 = i5 + 48 | 0;
+ i18 = i5;
+ i21 = i5 + 60 | 0;
+ i22 = i5 + 44 | 0;
+ i1 = i5 + 40 | 0;
+ i16 = i5 + 36 | 0;
+ i23 = i5 + 32 | 0;
+ i3 = i5 + 28 | 0;
+ i7 = i5 + 24 | 0;
+ i8 = i5 + 20 | 0;
+ i9 = i5 + 16 | 0;
+ i10 = i5 + 12 | 0;
+ i12 = i5 + 8 | 0;
+ HEAP32[i17 >> 2] = HEAP32[i6 + 64 >> 2];
+ i4 = i2 + 16 | 0;
+ i28 = HEAP32[i4 >> 2] | 0;
+ if ((i28 | 0) == 0) {
+  i28 = FUNCTION_TABLE_iiiii[HEAP32[i2 + 4 >> 2] & 3](HEAP32[i2 >> 2] | 0, i17, 4, HEAP32[i2 + 8 >> 2] | 0) | 0;
+  HEAP32[i4 >> 2] = i28;
+ }
+ HEAP32[i17 >> 2] = HEAP32[i6 + 68 >> 2];
+ if ((i28 | 0) == 0) {
+  i28 = FUNCTION_TABLE_iiiii[HEAP32[i2 + 4 >> 2] & 3](HEAP32[i2 >> 2] | 0, i17, 4, HEAP32[i2 + 8 >> 2] | 0) | 0;
+  HEAP32[i4 >> 2] = i28;
+ }
+ HEAP8[i17] = HEAP8[i6 + 76 | 0] | 0;
+ if ((i28 | 0) == 0) {
+  i28 = FUNCTION_TABLE_iiiii[HEAP32[i2 + 4 >> 2] & 3](HEAP32[i2 >> 2] | 0, i17, 1, HEAP32[i2 + 8 >> 2] | 0) | 0;
+  HEAP32[i4 >> 2] = i28;
+ }
+ HEAP8[i17] = HEAP8[i6 + 77 | 0] | 0;
+ if ((i28 | 0) == 0) {
+  i28 = FUNCTION_TABLE_iiiii[HEAP32[i2 + 4 >> 2] & 3](HEAP32[i2 >> 2] | 0, i17, 1, HEAP32[i2 + 8 >> 2] | 0) | 0;
+  HEAP32[i4 >> 2] = i28;
+ }
+ HEAP8[i17] = HEAP8[i6 + 78 | 0] | 0;
+ if ((i28 | 0) == 0) {
+  i28 = FUNCTION_TABLE_iiiii[HEAP32[i2 + 4 >> 2] & 3](HEAP32[i2 >> 2] | 0, i17, 1, HEAP32[i2 + 8 >> 2] | 0) | 0;
+  HEAP32[i4 >> 2] = i28;
+ }
+ i25 = HEAP32[i6 + 12 >> 2] | 0;
+ i24 = HEAP32[i6 + 48 >> 2] | 0;
+ HEAP32[i23 >> 2] = i24;
+ if ((i28 | 0) == 0) {
+  i26 = i2 + 4 | 0;
+  i27 = i2 + 8 | 0;
+  i28 = FUNCTION_TABLE_iiiii[HEAP32[i26 >> 2] & 3](HEAP32[i2 >> 2] | 0, i23, 4, HEAP32[i27 >> 2] | 0) | 0;
+  HEAP32[i4 >> 2] = i28;
+  if ((i28 | 0) == 0) {
+   i28 = FUNCTION_TABLE_iiiii[HEAP32[i26 >> 2] & 3](HEAP32[i2 >> 2] | 0, i25, i24 << 2, HEAP32[i27 >> 2] | 0) | 0;
+   HEAP32[i4 >> 2] = i28;
+   i25 = HEAP32[i6 + 44 >> 2] | 0;
+   HEAP32[i22 >> 2] = i25;
+   if ((i28 | 0) == 0) {
+    i28 = FUNCTION_TABLE_iiiii[HEAP32[i2 + 4 >> 2] & 3](HEAP32[i2 >> 2] | 0, i22, 4, HEAP32[i2 + 8 >> 2] | 0) | 0;
+    HEAP32[i4 >> 2] = i28;
+   }
+  } else {
+   i11 = 13;
+  }
+ } else {
+  i11 = 13;
+ }
+ if ((i11 | 0) == 13) {
+  i25 = HEAP32[i6 + 44 >> 2] | 0;
+  HEAP32[i22 >> 2] = i25;
+ }
+ if ((i25 | 0) > 0) {
+  i24 = i6 + 8 | 0;
+  i23 = i2 + 4 | 0;
+  i22 = i2 + 8 | 0;
+  i26 = 0;
+  do {
+   i30 = HEAP32[i24 >> 2] | 0;
+   i27 = i30 + (i26 << 4) | 0;
+   i30 = i30 + (i26 << 4) + 8 | 0;
+   i29 = HEAP32[i30 >> 2] | 0;
+   HEAP8[i17] = i29 & 15;
+   if ((i28 | 0) == 0) {
+    i28 = FUNCTION_TABLE_iiiii[HEAP32[i23 >> 2] & 3](HEAP32[i2 >> 2] | 0, i17, 1, HEAP32[i22 >> 2] | 0) | 0;
+    HEAP32[i4 >> 2] = i28;
+    i29 = HEAP32[i30 >> 2] | 0;
+   }
+   i29 = i29 & 15;
+   do {
+    if ((i29 | 0) == 3) {
+     HEAPF64[i18 >> 3] = +HEAPF64[i27 >> 3];
+     if ((i28 | 0) == 0) {
+      i28 = FUNCTION_TABLE_iiiii[HEAP32[i23 >> 2] & 3](HEAP32[i2 >> 2] | 0, i18, 8, HEAP32[i22 >> 2] | 0) | 0;
+      HEAP32[i4 >> 2] = i28;
+     }
+    } else if ((i29 | 0) == 1) {
+     HEAP8[i21] = HEAP32[i27 >> 2];
+     if ((i28 | 0) == 0) {
+      i28 = FUNCTION_TABLE_iiiii[HEAP32[i23 >> 2] & 3](HEAP32[i2 >> 2] | 0, i21, 1, HEAP32[i22 >> 2] | 0) | 0;
+      HEAP32[i4 >> 2] = i28;
+     }
+    } else if ((i29 | 0) == 4) {
+     i27 = HEAP32[i27 >> 2] | 0;
+     if ((i27 | 0) == 0) {
+      HEAP32[i19 >> 2] = 0;
+      if ((i28 | 0) != 0) {
+       break;
+      }
+      i28 = FUNCTION_TABLE_iiiii[HEAP32[i23 >> 2] & 3](HEAP32[i2 >> 2] | 0, i19, 4, HEAP32[i22 >> 2] | 0) | 0;
+      HEAP32[i4 >> 2] = i28;
+      break;
+     }
+     HEAP32[i20 >> 2] = (HEAP32[i27 + 12 >> 2] | 0) + 1;
+     if ((i28 | 0) == 0) {
+      i28 = FUNCTION_TABLE_iiiii[HEAP32[i23 >> 2] & 3](HEAP32[i2 >> 2] | 0, i20, 4, HEAP32[i22 >> 2] | 0) | 0;
+      HEAP32[i4 >> 2] = i28;
+      if ((i28 | 0) == 0) {
+       i28 = FUNCTION_TABLE_iiiii[HEAP32[i23 >> 2] & 3](HEAP32[i2 >> 2] | 0, i27 + 16 | 0, HEAP32[i20 >> 2] | 0, HEAP32[i22 >> 2] | 0) | 0;
+       HEAP32[i4 >> 2] = i28;
+      }
+     }
+    }
+   } while (0);
+   i26 = i26 + 1 | 0;
+  } while ((i26 | 0) != (i25 | 0));
+ }
+ i18 = HEAP32[i6 + 56 >> 2] | 0;
+ HEAP32[i17 >> 2] = i18;
+ if ((i28 | 0) == 0) {
+  i28 = FUNCTION_TABLE_iiiii[HEAP32[i2 + 4 >> 2] & 3](HEAP32[i2 >> 2] | 0, i17, 4, HEAP32[i2 + 8 >> 2] | 0) | 0;
+  HEAP32[i4 >> 2] = i28;
+ }
+ if ((i18 | 0) > 0) {
+  i17 = i6 + 16 | 0;
+  i19 = 0;
+  do {
+   _DumpFunction(HEAP32[(HEAP32[i17 >> 2] | 0) + (i19 << 2) >> 2] | 0, i2);
+   i19 = i19 + 1 | 0;
+  } while ((i19 | 0) != (i18 | 0));
+  i28 = HEAP32[i4 >> 2] | 0;
+ }
+ i17 = i6 + 40 | 0;
+ i18 = HEAP32[i17 >> 2] | 0;
+ HEAP32[i16 >> 2] = i18;
+ if ((i28 | 0) == 0) {
+  i28 = FUNCTION_TABLE_iiiii[HEAP32[i2 + 4 >> 2] & 3](HEAP32[i2 >> 2] | 0, i16, 4, HEAP32[i2 + 8 >> 2] | 0) | 0;
+  HEAP32[i4 >> 2] = i28;
+ }
+ if ((i18 | 0) > 0) {
+  i19 = i6 + 28 | 0;
+  i16 = i2 + 4 | 0;
+  i20 = i2 + 8 | 0;
+  i21 = 0;
+  do {
+   i22 = HEAP32[i19 >> 2] | 0;
+   HEAP8[i1] = HEAP8[i22 + (i21 << 3) + 4 | 0] | 0;
+   if ((i28 | 0) == 0) {
+    i28 = FUNCTION_TABLE_iiiii[HEAP32[i16 >> 2] & 3](HEAP32[i2 >> 2] | 0, i1, 1, HEAP32[i20 >> 2] | 0) | 0;
+    HEAP32[i4 >> 2] = i28;
+    i22 = HEAP32[i19 >> 2] | 0;
+   }
+   HEAP8[i1] = HEAP8[i22 + (i21 << 3) + 5 | 0] | 0;
+   if ((i28 | 0) == 0) {
+    i28 = FUNCTION_TABLE_iiiii[HEAP32[i16 >> 2] & 3](HEAP32[i2 >> 2] | 0, i1, 1, HEAP32[i20 >> 2] | 0) | 0;
+    HEAP32[i4 >> 2] = i28;
+   }
+   i21 = i21 + 1 | 0;
+  } while ((i21 | 0) != (i18 | 0));
+ }
+ i16 = i2 + 12 | 0;
+ if ((HEAP32[i16 >> 2] | 0) == 0 ? (i13 = HEAP32[i6 + 36 >> 2] | 0, (i13 | 0) != 0) : 0) {
+  HEAP32[i12 >> 2] = (HEAP32[i13 + 12 >> 2] | 0) + 1;
+  if ((i28 | 0) == 0 ? (i14 = i2 + 4 | 0, i15 = i2 + 8 | 0, i30 = FUNCTION_TABLE_iiiii[HEAP32[i14 >> 2] & 3](HEAP32[i2 >> 2] | 0, i12, 4, HEAP32[i15 >> 2] | 0) | 0, HEAP32[i4 >> 2] = i30, (i30 | 0) == 0) : 0) {
+   HEAP32[i4 >> 2] = FUNCTION_TABLE_iiiii[HEAP32[i14 >> 2] & 3](HEAP32[i2 >> 2] | 0, i13 + 16 | 0, HEAP32[i12 >> 2] | 0, HEAP32[i15 >> 2] | 0) | 0;
+  }
+ } else {
+  i12 = i10;
+  i11 = 50;
+ }
+ if ((i11 | 0) == 50) {
+  HEAP32[i10 >> 2] = 0;
+  if ((i28 | 0) == 0) {
+   HEAP32[i4 >> 2] = FUNCTION_TABLE_iiiii[HEAP32[i2 + 4 >> 2] & 3](HEAP32[i2 >> 2] | 0, i12, 4, HEAP32[i2 + 8 >> 2] | 0) | 0;
+  }
+ }
+ if ((HEAP32[i16 >> 2] | 0) == 0) {
+  i11 = HEAP32[i6 + 52 >> 2] | 0;
+ } else {
+  i11 = 0;
+ }
+ i10 = HEAP32[i6 + 20 >> 2] | 0;
+ HEAP32[i9 >> 2] = i11;
+ i14 = HEAP32[i4 >> 2] | 0;
+ if ((i14 | 0) == 0) {
+  i12 = i2 + 4 | 0;
+  i13 = i2 + 8 | 0;
+  i14 = FUNCTION_TABLE_iiiii[HEAP32[i12 >> 2] & 3](HEAP32[i2 >> 2] | 0, i9, 4, HEAP32[i13 >> 2] | 0) | 0;
+  HEAP32[i4 >> 2] = i14;
+  if ((i14 | 0) == 0) {
+   i14 = FUNCTION_TABLE_iiiii[HEAP32[i12 >> 2] & 3](HEAP32[i2 >> 2] | 0, i10, i11 << 2, HEAP32[i13 >> 2] | 0) | 0;
+   HEAP32[i4 >> 2] = i14;
+  }
+ }
+ if ((HEAP32[i16 >> 2] | 0) == 0) {
+  i9 = HEAP32[i6 + 60 >> 2] | 0;
+ } else {
+  i9 = 0;
+ }
+ HEAP32[i8 >> 2] = i9;
+ if ((i14 | 0) == 0) {
+  i14 = FUNCTION_TABLE_iiiii[HEAP32[i2 + 4 >> 2] & 3](HEAP32[i2 >> 2] | 0, i8, 4, HEAP32[i2 + 8 >> 2] | 0) | 0;
+  HEAP32[i4 >> 2] = i14;
+ }
+ if ((i9 | 0) > 0) {
+  i10 = i6 + 24 | 0;
+  i11 = i2 + 4 | 0;
+  i8 = i2 + 8 | 0;
+  i12 = 0;
+  do {
+   i13 = HEAP32[(HEAP32[i10 >> 2] | 0) + (i12 * 12 | 0) >> 2] | 0;
+   if ((i13 | 0) == 0) {
+    HEAP32[i1 >> 2] = 0;
+    if ((i14 | 0) == 0) {
+     i14 = FUNCTION_TABLE_iiiii[HEAP32[i11 >> 2] & 3](HEAP32[i2 >> 2] | 0, i1, 4, HEAP32[i8 >> 2] | 0) | 0;
+     HEAP32[i4 >> 2] = i14;
+    }
+   } else {
+    HEAP32[i3 >> 2] = (HEAP32[i13 + 12 >> 2] | 0) + 1;
+    if ((i14 | 0) == 0) {
+     i14 = FUNCTION_TABLE_iiiii[HEAP32[i11 >> 2] & 3](HEAP32[i2 >> 2] | 0, i3, 4, HEAP32[i8 >> 2] | 0) | 0;
+     HEAP32[i4 >> 2] = i14;
+     if ((i14 | 0) == 0) {
+      i14 = FUNCTION_TABLE_iiiii[HEAP32[i11 >> 2] & 3](HEAP32[i2 >> 2] | 0, i13 + 16 | 0, HEAP32[i3 >> 2] | 0, HEAP32[i8 >> 2] | 0) | 0;
+      HEAP32[i4 >> 2] = i14;
+     }
+    }
+   }
+   i13 = HEAP32[i10 >> 2] | 0;
+   HEAP32[i1 >> 2] = HEAP32[i13 + (i12 * 12 | 0) + 4 >> 2];
+   if ((i14 | 0) == 0) {
+    i14 = FUNCTION_TABLE_iiiii[HEAP32[i11 >> 2] & 3](HEAP32[i2 >> 2] | 0, i1, 4, HEAP32[i8 >> 2] | 0) | 0;
+    HEAP32[i4 >> 2] = i14;
+    i13 = HEAP32[i10 >> 2] | 0;
+   }
+   HEAP32[i1 >> 2] = HEAP32[i13 + (i12 * 12 | 0) + 8 >> 2];
+   if ((i14 | 0) == 0) {
+    i14 = FUNCTION_TABLE_iiiii[HEAP32[i11 >> 2] & 3](HEAP32[i2 >> 2] | 0, i1, 4, HEAP32[i8 >> 2] | 0) | 0;
+    HEAP32[i4 >> 2] = i14;
+   }
+   i12 = i12 + 1 | 0;
+  } while ((i12 | 0) != (i9 | 0));
+ }
+ if ((HEAP32[i16 >> 2] | 0) == 0) {
+  i8 = HEAP32[i17 >> 2] | 0;
+ } else {
+  i8 = 0;
+ }
+ HEAP32[i7 >> 2] = i8;
+ if ((i14 | 0) == 0) {
+  i14 = FUNCTION_TABLE_iiiii[HEAP32[i2 + 4 >> 2] & 3](HEAP32[i2 >> 2] | 0, i7, 4, HEAP32[i2 + 8 >> 2] | 0) | 0;
+  HEAP32[i4 >> 2] = i14;
+ }
+ if ((i8 | 0) <= 0) {
+  STACKTOP = i5;
+  return;
+ }
+ i7 = i6 + 28 | 0;
+ i6 = i2 + 4 | 0;
+ i9 = i2 + 8 | 0;
+ i10 = 0;
+ do {
+  i11 = HEAP32[(HEAP32[i7 >> 2] | 0) + (i10 << 3) >> 2] | 0;
+  if ((i11 | 0) == 0) {
+   HEAP32[i1 >> 2] = 0;
+   if ((i14 | 0) == 0) {
+    i14 = FUNCTION_TABLE_iiiii[HEAP32[i6 >> 2] & 3](HEAP32[i2 >> 2] | 0, i1, 4, HEAP32[i9 >> 2] | 0) | 0;
+    HEAP32[i4 >> 2] = i14;
+   }
+  } else {
+   HEAP32[i3 >> 2] = (HEAP32[i11 + 12 >> 2] | 0) + 1;
+   if ((i14 | 0) == 0) {
+    i14 = FUNCTION_TABLE_iiiii[HEAP32[i6 >> 2] & 3](HEAP32[i2 >> 2] | 0, i3, 4, HEAP32[i9 >> 2] | 0) | 0;
+    HEAP32[i4 >> 2] = i14;
+    if ((i14 | 0) == 0) {
+     i14 = FUNCTION_TABLE_iiiii[HEAP32[i6 >> 2] & 3](HEAP32[i2 >> 2] | 0, i11 + 16 | 0, HEAP32[i3 >> 2] | 0, HEAP32[i9 >> 2] | 0) | 0;
+     HEAP32[i4 >> 2] = i14;
+    }
+   }
+  }
+  i10 = i10 + 1 | 0;
+ } while ((i10 | 0) != (i8 | 0));
+ STACKTOP = i5;
+ return;
+}
+function _LoadFunction(i2, i6) {
+ i2 = i2 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i1;
+ i5 = i1 + 8 | 0;
+ i4 = i2 + 4 | 0;
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ i8 = HEAP32[i3 >> 2] | 0;
+ if ((i8 | 0) < 0) {
+  _error(i2, 8872);
+ }
+ HEAP32[i6 + 64 >> 2] = i8;
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ i8 = HEAP32[i3 >> 2] | 0;
+ if ((i8 | 0) < 0) {
+  _error(i2, 8872);
+ }
+ HEAP32[i6 + 68 >> 2] = i8;
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 1) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ HEAP8[i6 + 76 | 0] = HEAP8[i3] | 0;
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 1) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ HEAP8[i6 + 77 | 0] = HEAP8[i3] | 0;
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 1) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ HEAP8[i6 + 78 | 0] = HEAP8[i3] | 0;
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ i9 = HEAP32[i3 >> 2] | 0;
+ if ((i9 | 0) < 0) {
+  _error(i2, 8872);
+ }
+ i8 = HEAP32[i2 >> 2] | 0;
+ if ((i9 + 1 | 0) >>> 0 > 1073741823) {
+  _luaM_toobig(i8);
+ }
+ i14 = i9 << 2;
+ i13 = _luaM_realloc_(i8, 0, 0, i14) | 0;
+ HEAP32[i6 + 12 >> 2] = i13;
+ HEAP32[i6 + 48 >> 2] = i9;
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i13, i14) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ i8 = HEAP32[i3 >> 2] | 0;
+ if ((i8 | 0) < 0) {
+  _error(i2, 8872);
+ }
+ i9 = HEAP32[i2 >> 2] | 0;
+ if ((i8 + 1 | 0) >>> 0 > 268435455) {
+  _luaM_toobig(i9);
+ }
+ i11 = _luaM_realloc_(i9, 0, 0, i8 << 4) | 0;
+ i9 = i6 + 8 | 0;
+ HEAP32[i9 >> 2] = i11;
+ HEAP32[i6 + 44 >> 2] = i8;
+ i12 = (i8 | 0) > 0;
+ L43 : do {
+  if (i12) {
+   i10 = 0;
+   do {
+    HEAP32[i11 + (i10 << 4) + 8 >> 2] = 0;
+    i10 = i10 + 1 | 0;
+   } while ((i10 | 0) != (i8 | 0));
+   if (i12) {
+    i10 = i2 + 8 | 0;
+    i13 = 0;
+    while (1) {
+     i12 = i11 + (i13 << 4) | 0;
+     if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 1) | 0) != 0) {
+      i9 = 34;
+      break;
+     }
+     i14 = HEAP8[i3] | 0;
+     if ((i14 | 0) == 4) {
+      if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+       i9 = 44;
+       break;
+      }
+      i14 = HEAP32[i3 >> 2] | 0;
+      if ((i14 | 0) == 0) {
+       i14 = 0;
+      } else {
+       i14 = _luaZ_openspace(HEAP32[i2 >> 2] | 0, HEAP32[i10 >> 2] | 0, i14) | 0;
+       if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i14, HEAP32[i3 >> 2] | 0) | 0) != 0) {
+        i9 = 47;
+        break;
+       }
+       i14 = _luaS_newlstr(HEAP32[i2 >> 2] | 0, i14, (HEAP32[i3 >> 2] | 0) + -1 | 0) | 0;
+      }
+      HEAP32[i12 >> 2] = i14;
+      HEAP32[i11 + (i13 << 4) + 8 >> 2] = HEAPU8[i14 + 4 | 0] | 64;
+     } else if ((i14 | 0) == 1) {
+      if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 1) | 0) != 0) {
+       i9 = 38;
+       break;
+      }
+      HEAP32[i12 >> 2] = HEAP8[i3] | 0;
+      HEAP32[i11 + (i13 << 4) + 8 >> 2] = 1;
+     } else if ((i14 | 0) == 3) {
+      if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 8) | 0) != 0) {
+       i9 = 41;
+       break;
+      }
+      HEAPF64[i12 >> 3] = +HEAPF64[i3 >> 3];
+      HEAP32[i11 + (i13 << 4) + 8 >> 2] = 3;
+     } else if ((i14 | 0) == 0) {
+      HEAP32[i11 + (i13 << 4) + 8 >> 2] = 0;
+     }
+     i13 = i13 + 1 | 0;
+     if ((i13 | 0) >= (i8 | 0)) {
+      break L43;
+     }
+     i11 = HEAP32[i9 >> 2] | 0;
+    }
+    if ((i9 | 0) == 34) {
+     _error(i2, 8824);
+    } else if ((i9 | 0) == 38) {
+     _error(i2, 8824);
+    } else if ((i9 | 0) == 41) {
+     _error(i2, 8824);
+    } else if ((i9 | 0) == 44) {
+     _error(i2, 8824);
+    } else if ((i9 | 0) == 47) {
+     _error(i2, 8824);
+    }
+   }
+  }
+ } while (0);
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ i8 = HEAP32[i3 >> 2] | 0;
+ if ((i8 | 0) < 0) {
+  _error(i2, 8872);
+ }
+ i9 = HEAP32[i2 >> 2] | 0;
+ if ((i8 + 1 | 0) >>> 0 > 1073741823) {
+  _luaM_toobig(i9);
+ }
+ i11 = _luaM_realloc_(i9, 0, 0, i8 << 2) | 0;
+ i9 = i6 + 16 | 0;
+ HEAP32[i9 >> 2] = i11;
+ HEAP32[i6 + 56 >> 2] = i8;
+ i10 = (i8 | 0) > 0;
+ if (i10) {
+  i12 = 0;
+  while (1) {
+   HEAP32[i11 + (i12 << 2) >> 2] = 0;
+   i12 = i12 + 1 | 0;
+   if ((i12 | 0) == (i8 | 0)) {
+    break;
+   }
+   i11 = HEAP32[i9 >> 2] | 0;
+  }
+  if (i10) {
+   i10 = 0;
+   do {
+    i14 = _luaF_newproto(HEAP32[i2 >> 2] | 0) | 0;
+    HEAP32[(HEAP32[i9 >> 2] | 0) + (i10 << 2) >> 2] = i14;
+    _LoadFunction(i2, HEAP32[(HEAP32[i9 >> 2] | 0) + (i10 << 2) >> 2] | 0);
+    i10 = i10 + 1 | 0;
+   } while ((i10 | 0) != (i8 | 0));
+  }
+ }
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ i9 = HEAP32[i3 >> 2] | 0;
+ if ((i9 | 0) < 0) {
+  _error(i2, 8872);
+ }
+ i8 = HEAP32[i2 >> 2] | 0;
+ if ((i9 + 1 | 0) >>> 0 > 536870911) {
+  _luaM_toobig(i8);
+ }
+ i10 = _luaM_realloc_(i8, 0, 0, i9 << 3) | 0;
+ i8 = i6 + 28 | 0;
+ HEAP32[i8 >> 2] = i10;
+ HEAP32[i6 + 40 >> 2] = i9;
+ L98 : do {
+  if ((i9 | 0) > 0) {
+   HEAP32[i10 >> 2] = 0;
+   if ((i9 | 0) == 1) {
+    i10 = 0;
+   } else {
+    i10 = 1;
+    while (1) {
+     HEAP32[(HEAP32[i8 >> 2] | 0) + (i10 << 3) >> 2] = 0;
+     i10 = i10 + 1 | 0;
+     if ((i10 | 0) == (i9 | 0)) {
+      i10 = 0;
+      break;
+     }
+    }
+   }
+   while (1) {
+    if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 1) | 0) != 0) {
+     i9 = 73;
+     break;
+    }
+    HEAP8[(HEAP32[i8 >> 2] | 0) + (i10 << 3) + 4 | 0] = HEAP8[i3] | 0;
+    if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 1) | 0) != 0) {
+     i9 = 75;
+     break;
+    }
+    HEAP8[(HEAP32[i8 >> 2] | 0) + (i10 << 3) + 5 | 0] = HEAP8[i3] | 0;
+    i10 = i10 + 1 | 0;
+    if ((i10 | 0) >= (i9 | 0)) {
+     break L98;
+    }
+   }
+   if ((i9 | 0) == 73) {
+    _error(i2, 8824);
+   } else if ((i9 | 0) == 75) {
+    _error(i2, 8824);
+   }
+  }
+ } while (0);
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ i9 = HEAP32[i3 >> 2] | 0;
+ do {
+  if ((i9 | 0) != 0) {
+   i9 = _luaZ_openspace(HEAP32[i2 >> 2] | 0, HEAP32[i2 + 8 >> 2] | 0, i9) | 0;
+   if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i9, HEAP32[i3 >> 2] | 0) | 0) == 0) {
+    i7 = _luaS_newlstr(HEAP32[i2 >> 2] | 0, i9, (HEAP32[i3 >> 2] | 0) + -1 | 0) | 0;
+    break;
+   } else {
+    _error(i2, 8824);
+   }
+  } else {
+   i7 = 0;
+  }
+ } while (0);
+ HEAP32[i6 + 36 >> 2] = i7;
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ i7 = HEAP32[i3 >> 2] | 0;
+ if ((i7 | 0) < 0) {
+  _error(i2, 8872);
+ }
+ i9 = HEAP32[i2 >> 2] | 0;
+ if ((i7 + 1 | 0) >>> 0 > 1073741823) {
+  _luaM_toobig(i9);
+ }
+ i14 = i7 << 2;
+ i13 = _luaM_realloc_(i9, 0, 0, i14) | 0;
+ HEAP32[i6 + 20 >> 2] = i13;
+ HEAP32[i6 + 52 >> 2] = i7;
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i13, i14) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ i7 = HEAP32[i3 >> 2] | 0;
+ if ((i7 | 0) < 0) {
+  _error(i2, 8872);
+ }
+ i9 = HEAP32[i2 >> 2] | 0;
+ if ((i7 + 1 | 0) >>> 0 > 357913941) {
+  _luaM_toobig(i9);
+ }
+ i10 = _luaM_realloc_(i9, 0, 0, i7 * 12 | 0) | 0;
+ i9 = i6 + 24 | 0;
+ HEAP32[i9 >> 2] = i10;
+ HEAP32[i6 + 60 >> 2] = i7;
+ L141 : do {
+  if ((i7 | 0) > 0) {
+   HEAP32[i10 >> 2] = 0;
+   if ((i7 | 0) != 1) {
+    i6 = 1;
+    do {
+     HEAP32[(HEAP32[i9 >> 2] | 0) + (i6 * 12 | 0) >> 2] = 0;
+     i6 = i6 + 1 | 0;
+    } while ((i6 | 0) != (i7 | 0));
+   }
+   i6 = i2 + 8 | 0;
+   i10 = 0;
+   while (1) {
+    if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+     i9 = 102;
+     break;
+    }
+    i11 = HEAP32[i3 >> 2] | 0;
+    if ((i11 | 0) == 0) {
+     i11 = 0;
+    } else {
+     i11 = _luaZ_openspace(HEAP32[i2 >> 2] | 0, HEAP32[i6 >> 2] | 0, i11) | 0;
+     if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i11, HEAP32[i3 >> 2] | 0) | 0) != 0) {
+      i9 = 105;
+      break;
+     }
+     i11 = _luaS_newlstr(HEAP32[i2 >> 2] | 0, i11, (HEAP32[i3 >> 2] | 0) + -1 | 0) | 0;
+    }
+    HEAP32[(HEAP32[i9 >> 2] | 0) + (i10 * 12 | 0) >> 2] = i11;
+    if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+     i9 = 108;
+     break;
+    }
+    i11 = HEAP32[i3 >> 2] | 0;
+    if ((i11 | 0) < 0) {
+     i9 = 110;
+     break;
+    }
+    HEAP32[(HEAP32[i9 >> 2] | 0) + (i10 * 12 | 0) + 4 >> 2] = i11;
+    if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+     i9 = 112;
+     break;
+    }
+    i11 = HEAP32[i3 >> 2] | 0;
+    if ((i11 | 0) < 0) {
+     i9 = 114;
+     break;
+    }
+    HEAP32[(HEAP32[i9 >> 2] | 0) + (i10 * 12 | 0) + 8 >> 2] = i11;
+    i10 = i10 + 1 | 0;
+    if ((i10 | 0) >= (i7 | 0)) {
+     break L141;
+    }
+   }
+   if ((i9 | 0) == 102) {
+    _error(i2, 8824);
+   } else if ((i9 | 0) == 105) {
+    _error(i2, 8824);
+   } else if ((i9 | 0) == 108) {
+    _error(i2, 8824);
+   } else if ((i9 | 0) == 110) {
+    _error(i2, 8872);
+   } else if ((i9 | 0) == 112) {
+    _error(i2, 8824);
+   } else if ((i9 | 0) == 114) {
+    _error(i2, 8872);
+   }
+  }
+ } while (0);
+ if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i5, 4) | 0) != 0) {
+  _error(i2, 8824);
+ }
+ i6 = HEAP32[i5 >> 2] | 0;
+ if ((i6 | 0) < 0) {
+  _error(i2, 8872);
+ }
+ if ((i6 | 0) <= 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i5 = i2 + 8 | 0;
+ i7 = 0;
+ while (1) {
+  if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i3, 4) | 0) != 0) {
+   i9 = 123;
+   break;
+  }
+  i9 = HEAP32[i3 >> 2] | 0;
+  if ((i9 | 0) == 0) {
+   i9 = 0;
+  } else {
+   i9 = _luaZ_openspace(HEAP32[i2 >> 2] | 0, HEAP32[i5 >> 2] | 0, i9) | 0;
+   if ((_luaZ_read(HEAP32[i4 >> 2] | 0, i9, HEAP32[i3 >> 2] | 0) | 0) != 0) {
+    i9 = 126;
+    break;
+   }
+   i9 = _luaS_newlstr(HEAP32[i2 >> 2] | 0, i9, (HEAP32[i3 >> 2] | 0) + -1 | 0) | 0;
+  }
+  HEAP32[(HEAP32[i8 >> 2] | 0) + (i7 << 3) >> 2] = i9;
+  i7 = i7 + 1 | 0;
+  if ((i7 | 0) >= (i6 | 0)) {
+   i9 = 129;
+   break;
+  }
+ }
+ if ((i9 | 0) == 123) {
+  _error(i2, 8824);
+ } else if ((i9 | 0) == 126) {
+  _error(i2, 8824);
+ } else if ((i9 | 0) == 129) {
+  STACKTOP = i1;
+  return;
+ }
+}
+function _exp2reg(i4, i1, i7) {
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ i7 = i7 | 0;
+ var i2 = 0, i3 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0;
+ i5 = STACKTOP;
+ _discharge2reg(i4, i1, i7);
+ i6 = i1 + 16 | 0;
+ do {
+  if ((HEAP32[i1 >> 2] | 0) == 10 ? (i10 = HEAP32[i1 + 8 >> 2] | 0, !((i10 | 0) == -1)) : 0) {
+   i22 = HEAP32[i6 >> 2] | 0;
+   if ((i22 | 0) == -1) {
+    HEAP32[i6 >> 2] = i10;
+    break;
+   }
+   i20 = HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] | 0;
+   while (1) {
+    i19 = i20 + (i22 << 2) | 0;
+    i21 = HEAP32[i19 >> 2] | 0;
+    i23 = (i21 >>> 14) + -131071 | 0;
+    if ((i23 | 0) == -1) {
+     break;
+    }
+    i23 = i22 + 1 + i23 | 0;
+    if ((i23 | 0) == -1) {
+     break;
+    } else {
+     i22 = i23;
+    }
+   }
+   i10 = i10 + ~i22 | 0;
+   if ((((i10 | 0) > -1 ? i10 : 0 - i10 | 0) | 0) > 131071) {
+    _luaX_syntaxerror(HEAP32[i4 + 12 >> 2] | 0, 10624);
+   } else {
+    HEAP32[i19 >> 2] = (i10 << 14) + 2147467264 | i21 & 16383;
+    break;
+   }
+  }
+ } while (0);
+ i21 = HEAP32[i6 >> 2] | 0;
+ i10 = i1 + 20 | 0;
+ i19 = HEAP32[i10 >> 2] | 0;
+ if ((i21 | 0) == (i19 | 0)) {
+  HEAP32[i6 >> 2] = -1;
+  HEAP32[i10 >> 2] = -1;
+  i25 = i1 + 8 | 0;
+  HEAP32[i25 >> 2] = i7;
+  HEAP32[i1 >> 2] = 6;
+  STACKTOP = i5;
+  return;
+ }
+ L18 : do {
+  if ((i21 | 0) == -1) {
+   i18 = 20;
+  } else {
+   i20 = HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] | 0;
+   while (1) {
+    i23 = i20 + (i21 << 2) | 0;
+    if ((i21 | 0) > 0 ? (i18 = HEAP32[i20 + (i21 + -1 << 2) >> 2] | 0, (HEAP8[5584 + (i18 & 63) | 0] | 0) < 0) : 0) {
+     i22 = i18;
+    } else {
+     i22 = HEAP32[i23 >> 2] | 0;
+    }
+    if ((i22 & 63 | 0) != 28) {
+     i18 = 28;
+     break L18;
+    }
+    i22 = ((HEAP32[i23 >> 2] | 0) >>> 14) + -131071 | 0;
+    if ((i22 | 0) == -1) {
+     i18 = 20;
+     break L18;
+    }
+    i21 = i21 + 1 + i22 | 0;
+    if ((i21 | 0) == -1) {
+     i18 = 20;
+     break;
+    }
+   }
+  }
+ } while (0);
+ L29 : do {
+  if ((i18 | 0) == 20) {
+   if ((i19 | 0) == -1) {
+    i15 = -1;
+    i8 = -1;
+   } else {
+    i20 = HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] | 0;
+    while (1) {
+     i21 = i20 + (i19 << 2) | 0;
+     if ((i19 | 0) > 0 ? (i17 = HEAP32[i20 + (i19 + -1 << 2) >> 2] | 0, (HEAP8[5584 + (i17 & 63) | 0] | 0) < 0) : 0) {
+      i22 = i17;
+     } else {
+      i22 = HEAP32[i21 >> 2] | 0;
+     }
+     if ((i22 & 63 | 0) != 28) {
+      i18 = 28;
+      break L29;
+     }
+     i21 = ((HEAP32[i21 >> 2] | 0) >>> 14) + -131071 | 0;
+     if ((i21 | 0) == -1) {
+      i15 = -1;
+      i8 = -1;
+      break L29;
+     }
+     i19 = i19 + 1 + i21 | 0;
+     if ((i19 | 0) == -1) {
+      i15 = -1;
+      i8 = -1;
+      break;
+     }
+    }
+   }
+  }
+ } while (0);
+ do {
+  if ((i18 | 0) == 28) {
+   i17 = i4 + 28 | 0;
+   do {
+    if ((HEAP32[i1 >> 2] | 0) != 10) {
+     i21 = HEAP32[i17 >> 2] | 0;
+     HEAP32[i17 >> 2] = -1;
+     i18 = _luaK_code(i4, 2147450903) | 0;
+     if (!((i21 | 0) == -1)) {
+      if (!((i18 | 0) == -1)) {
+       i23 = HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] | 0;
+       i22 = i18;
+       while (1) {
+        i20 = i23 + (i22 << 2) | 0;
+        i19 = HEAP32[i20 >> 2] | 0;
+        i24 = (i19 >>> 14) + -131071 | 0;
+        if ((i24 | 0) == -1) {
+         break;
+        }
+        i24 = i22 + 1 + i24 | 0;
+        if ((i24 | 0) == -1) {
+         break;
+        } else {
+         i22 = i24;
+        }
+       }
+       i21 = i21 + ~i22 | 0;
+       if ((((i21 | 0) > -1 ? i21 : 0 - i21 | 0) | 0) > 131071) {
+        _luaX_syntaxerror(HEAP32[i4 + 12 >> 2] | 0, 10624);
+       } else {
+        HEAP32[i20 >> 2] = (i21 << 14) + 2147467264 | i19 & 16383;
+        i16 = i18;
+        break;
+       }
+      } else {
+       i16 = i21;
+      }
+     } else {
+      i16 = i18;
+     }
+    } else {
+     i16 = -1;
+    }
+   } while (0);
+   i24 = i4 + 20 | 0;
+   i25 = i4 + 24 | 0;
+   HEAP32[i25 >> 2] = HEAP32[i24 >> 2];
+   i19 = i7 << 6;
+   i18 = _luaK_code(i4, i19 | 16387) | 0;
+   HEAP32[i25 >> 2] = HEAP32[i24 >> 2];
+   i19 = _luaK_code(i4, i19 | 8388611) | 0;
+   HEAP32[i25 >> 2] = HEAP32[i24 >> 2];
+   if (!((i16 | 0) == -1)) {
+    i22 = HEAP32[i17 >> 2] | 0;
+    if ((i22 | 0) == -1) {
+     HEAP32[i17 >> 2] = i16;
+     i15 = i18;
+     i8 = i19;
+     break;
+    }
+    i17 = HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] | 0;
+    while (1) {
+     i21 = i17 + (i22 << 2) | 0;
+     i20 = HEAP32[i21 >> 2] | 0;
+     i23 = (i20 >>> 14) + -131071 | 0;
+     if ((i23 | 0) == -1) {
+      break;
+     }
+     i23 = i22 + 1 + i23 | 0;
+     if ((i23 | 0) == -1) {
+      break;
+     } else {
+      i22 = i23;
+     }
+    }
+    i16 = i16 + ~i22 | 0;
+    if ((((i16 | 0) > -1 ? i16 : 0 - i16 | 0) | 0) > 131071) {
+     _luaX_syntaxerror(HEAP32[i4 + 12 >> 2] | 0, 10624);
+    } else {
+     HEAP32[i21 >> 2] = (i16 << 14) + 2147467264 | i20 & 16383;
+     i15 = i18;
+     i8 = i19;
+     break;
+    }
+   } else {
+    i15 = i18;
+    i8 = i19;
+   }
+  }
+ } while (0);
+ i16 = HEAP32[i4 + 20 >> 2] | 0;
+ HEAP32[i4 + 24 >> 2] = i16;
+ i22 = HEAP32[i10 >> 2] | 0;
+ L67 : do {
+  if (!((i22 | 0) == -1)) {
+   i19 = (i7 | 0) == 255;
+   i17 = i7 << 6 & 16320;
+   i18 = HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] | 0;
+   while (1) {
+    i20 = i18 + (i22 << 2) | 0;
+    i23 = HEAP32[i20 >> 2] | 0;
+    i21 = (i23 >>> 14) + -131071 | 0;
+    if ((i21 | 0) == -1) {
+     i21 = -1;
+    } else {
+     i21 = i22 + 1 + i21 | 0;
+    }
+    if ((i22 | 0) > 0 ? (i14 = i18 + (i22 + -1 << 2) | 0, i13 = HEAP32[i14 >> 2] | 0, (HEAP8[5584 + (i13 & 63) | 0] | 0) < 0) : 0) {
+     i24 = i14;
+     i25 = i13;
+    } else {
+     i24 = i20;
+     i25 = i23;
+    }
+    if ((i25 & 63 | 0) == 28) {
+     i23 = i25 >>> 23;
+     if (i19 | (i23 | 0) == (i7 | 0)) {
+      i23 = i25 & 8372224 | i23 << 6 | 27;
+     } else {
+      i23 = i25 & -16321 | i17;
+     }
+     HEAP32[i24 >> 2] = i23;
+     i22 = i16 + ~i22 | 0;
+     if ((((i22 | 0) > -1 ? i22 : 0 - i22 | 0) | 0) > 131071) {
+      i18 = 58;
+      break;
+     }
+     i22 = HEAP32[i20 >> 2] & 16383 | (i22 << 14) + 2147467264;
+    } else {
+     i22 = i15 + ~i22 | 0;
+     if ((((i22 | 0) > -1 ? i22 : 0 - i22 | 0) | 0) > 131071) {
+      i18 = 61;
+      break;
+     }
+     i22 = i23 & 16383 | (i22 << 14) + 2147467264;
+    }
+    HEAP32[i20 >> 2] = i22;
+    if ((i21 | 0) == -1) {
+     break L67;
+    } else {
+     i22 = i21;
+    }
+   }
+   if ((i18 | 0) == 58) {
+    _luaX_syntaxerror(HEAP32[i4 + 12 >> 2] | 0, 10624);
+   } else if ((i18 | 0) == 61) {
+    _luaX_syntaxerror(HEAP32[i4 + 12 >> 2] | 0, 10624);
+   }
+  }
+ } while (0);
+ i20 = HEAP32[i6 >> 2] | 0;
+ if ((i20 | 0) == -1) {
+  HEAP32[i6 >> 2] = -1;
+  HEAP32[i10 >> 2] = -1;
+  i25 = i1 + 8 | 0;
+  HEAP32[i25 >> 2] = i7;
+  HEAP32[i1 >> 2] = 6;
+  STACKTOP = i5;
+  return;
+ }
+ i13 = i7 << 6;
+ i15 = i13 & 16320;
+ i14 = HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] | 0;
+ if ((i7 | 0) == 255) {
+  while (1) {
+   i17 = i14 + (i20 << 2) | 0;
+   i19 = HEAP32[i17 >> 2] | 0;
+   i18 = (i19 >>> 14) + -131071 | 0;
+   if ((i18 | 0) == -1) {
+    i18 = -1;
+   } else {
+    i18 = i20 + 1 + i18 | 0;
+   }
+   if ((i20 | 0) > 0 ? (i12 = i14 + (i20 + -1 << 2) | 0, i11 = HEAP32[i12 >> 2] | 0, (HEAP8[5584 + (i11 & 63) | 0] | 0) < 0) : 0) {
+    i22 = i12;
+    i21 = i11;
+   } else {
+    i22 = i17;
+    i21 = i19;
+   }
+   if ((i21 & 63 | 0) == 28) {
+    HEAP32[i22 >> 2] = i21 & 8372224 | i21 >>> 23 << 6 | 27;
+    i19 = i16 + ~i20 | 0;
+    if ((((i19 | 0) > -1 ? i19 : 0 - i19 | 0) | 0) > 131071) {
+     i18 = 87;
+     break;
+    }
+    i19 = HEAP32[i17 >> 2] & 16383 | (i19 << 14) + 2147467264;
+   } else {
+    i20 = i8 + ~i20 | 0;
+    if ((((i20 | 0) > -1 ? i20 : 0 - i20 | 0) | 0) > 131071) {
+     i18 = 90;
+     break;
+    }
+    i19 = i19 & 16383 | (i20 << 14) + 2147467264;
+   }
+   HEAP32[i17 >> 2] = i19;
+   if ((i18 | 0) == -1) {
+    i18 = 93;
+    break;
+   } else {
+    i20 = i18;
+   }
+  }
+  if ((i18 | 0) == 87) {
+   i25 = i4 + 12 | 0;
+   i25 = HEAP32[i25 >> 2] | 0;
+   _luaX_syntaxerror(i25, 10624);
+  } else if ((i18 | 0) == 90) {
+   i25 = i4 + 12 | 0;
+   i25 = HEAP32[i25 >> 2] | 0;
+   _luaX_syntaxerror(i25, 10624);
+  } else if ((i18 | 0) == 93) {
+   HEAP32[i6 >> 2] = -1;
+   HEAP32[i10 >> 2] = -1;
+   i25 = i1 + 8 | 0;
+   HEAP32[i25 >> 2] = i7;
+   HEAP32[i1 >> 2] = 6;
+   STACKTOP = i5;
+   return;
+  }
+ } else {
+  i9 = i20;
+ }
+ while (1) {
+  i11 = i14 + (i9 << 2) | 0;
+  i17 = HEAP32[i11 >> 2] | 0;
+  i12 = (i17 >>> 14) + -131071 | 0;
+  if ((i12 | 0) == -1) {
+   i12 = -1;
+  } else {
+   i12 = i9 + 1 + i12 | 0;
+  }
+  if ((i9 | 0) > 0 ? (i3 = i14 + (i9 + -1 << 2) | 0, i2 = HEAP32[i3 >> 2] | 0, (HEAP8[5584 + (i2 & 63) | 0] | 0) < 0) : 0) {
+   i18 = i3;
+   i19 = i2;
+  } else {
+   i18 = i11;
+   i19 = i17;
+  }
+  if ((i19 & 63 | 0) == 28) {
+   if ((i19 >>> 23 | 0) == (i7 | 0)) {
+    i17 = i19 & 8372224 | i13 | 27;
+   } else {
+    i17 = i19 & -16321 | i15;
+   }
+   HEAP32[i18 >> 2] = i17;
+   i9 = i16 + ~i9 | 0;
+   if ((((i9 | 0) > -1 ? i9 : 0 - i9 | 0) | 0) > 131071) {
+    i18 = 87;
+    break;
+   }
+   i9 = HEAP32[i11 >> 2] & 16383 | (i9 << 14) + 2147467264;
+  } else {
+   i9 = i8 + ~i9 | 0;
+   if ((((i9 | 0) > -1 ? i9 : 0 - i9 | 0) | 0) > 131071) {
+    i18 = 90;
+    break;
+   }
+   i9 = i17 & 16383 | (i9 << 14) + 2147467264;
+  }
+  HEAP32[i11 >> 2] = i9;
+  if ((i12 | 0) == -1) {
+   i18 = 93;
+   break;
+  } else {
+   i9 = i12;
+  }
+ }
+ if ((i18 | 0) == 87) {
+  i25 = i4 + 12 | 0;
+  i25 = HEAP32[i25 >> 2] | 0;
+  _luaX_syntaxerror(i25, 10624);
+ } else if ((i18 | 0) == 90) {
+  i25 = i4 + 12 | 0;
+  i25 = HEAP32[i25 >> 2] | 0;
+  _luaX_syntaxerror(i25, 10624);
+ } else if ((i18 | 0) == 93) {
+  HEAP32[i6 >> 2] = -1;
+  HEAP32[i10 >> 2] = -1;
+  i25 = i1 + 8 | 0;
+  HEAP32[i25 >> 2] = i7;
+  HEAP32[i1 >> 2] = 6;
+  STACKTOP = i5;
+  return;
+ }
+}
+function _propagatemark(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0;
+ i1 = STACKTOP;
+ i15 = i2 + 84 | 0;
+ i3 = HEAP32[i15 >> 2] | 0;
+ i10 = i3 + 5 | 0;
+ HEAP8[i10] = HEAPU8[i10] | 4;
+ switch (HEAPU8[i3 + 4 | 0] | 0) {
+ case 5:
+  {
+   i9 = i3 + 24 | 0;
+   HEAP32[i15 >> 2] = HEAP32[i9 >> 2];
+   i15 = i3 + 8 | 0;
+   i14 = HEAP32[i15 >> 2] | 0;
+   do {
+    if ((i14 | 0) != 0) {
+     if ((HEAP8[i14 + 6 | 0] & 8) == 0) {
+      i11 = _luaT_gettm(i14, 3, HEAP32[i2 + 196 >> 2] | 0) | 0;
+      i14 = HEAP32[i15 >> 2] | 0;
+      if ((i14 | 0) != 0) {
+       i6 = 5;
+      }
+     } else {
+      i11 = 0;
+      i6 = 5;
+     }
+     if ((i6 | 0) == 5) {
+      if (!((HEAP8[i14 + 5 | 0] & 3) == 0)) {
+       _reallymarkobject(i2, i14);
+      }
+     }
+     if (((i11 | 0) != 0 ? (HEAP32[i11 + 8 >> 2] & 15 | 0) == 4 : 0) ? (i13 = (HEAP32[i11 >> 2] | 0) + 16 | 0, i12 = _strchr(i13, 107) | 0, i12 = (i12 | 0) != 0, i13 = (_strchr(i13, 118) | 0) == 0, !(i13 & (i12 ^ 1))) : 0) {
+      HEAP8[i10] = HEAP8[i10] & 251;
+      if (i12) {
+       if (i13) {
+        _traverseephemeron(i2, i3) | 0;
+        break;
+       } else {
+        i15 = i2 + 100 | 0;
+        HEAP32[i9 >> 2] = HEAP32[i15 >> 2];
+        HEAP32[i15 >> 2] = i3;
+        break;
+       }
+      }
+      i15 = 1 << HEAPU8[i3 + 7 | 0];
+      i5 = HEAP32[i3 + 16 >> 2] | 0;
+      i4 = i5 + (i15 << 5) | 0;
+      i8 = (HEAP32[i3 + 28 >> 2] | 0) > 0 | 0;
+      if ((i15 | 0) > 0) {
+       do {
+        i12 = i5 + 8 | 0;
+        i10 = i5 + 24 | 0;
+        i11 = (HEAP32[i10 >> 2] & 64 | 0) == 0;
+        do {
+         if ((HEAP32[i12 >> 2] | 0) == 0) {
+          if (!i11 ? !((HEAP8[(HEAP32[i5 + 16 >> 2] | 0) + 5 | 0] & 3) == 0) : 0) {
+           HEAP32[i10 >> 2] = 11;
+          }
+         } else {
+          if (!i11 ? (i7 = HEAP32[i5 + 16 >> 2] | 0, !((HEAP8[i7 + 5 | 0] & 3) == 0)) : 0) {
+           _reallymarkobject(i2, i7);
+          }
+          if ((i8 | 0) == 0) {
+           i10 = HEAP32[i12 >> 2] | 0;
+           if ((i10 & 64 | 0) != 0) {
+            i8 = HEAP32[i5 >> 2] | 0;
+            if ((i10 & 15 | 0) != 4) {
+             i8 = (HEAP8[i8 + 5 | 0] & 3) != 0 | 0;
+             break;
+            }
+            if ((i8 | 0) != 0 ? !((HEAP8[i8 + 5 | 0] & 3) == 0) : 0) {
+             _reallymarkobject(i2, i8);
+             i8 = 0;
+            } else {
+             i8 = 0;
+            }
+           } else {
+            i8 = 0;
+           }
+          }
+         }
+        } while (0);
+        i5 = i5 + 32 | 0;
+       } while (i5 >>> 0 < i4 >>> 0);
+      }
+      if ((i8 | 0) == 0) {
+       i15 = i2 + 88 | 0;
+       HEAP32[i9 >> 2] = HEAP32[i15 >> 2];
+       HEAP32[i15 >> 2] = i3;
+       break;
+      } else {
+       i15 = i2 + 92 | 0;
+       HEAP32[i9 >> 2] = HEAP32[i15 >> 2];
+       HEAP32[i15 >> 2] = i3;
+       break;
+      }
+     } else {
+      i6 = 33;
+     }
+    } else {
+     i6 = 33;
+    }
+   } while (0);
+   if ((i6 | 0) == 33) {
+    i7 = i3 + 16 | 0;
+    i10 = HEAP32[i7 >> 2] | 0;
+    i6 = i10 + (1 << HEAPU8[i3 + 7 | 0] << 5) | 0;
+    i9 = i3 + 28 | 0;
+    i13 = HEAP32[i9 >> 2] | 0;
+    if ((i13 | 0) > 0) {
+     i10 = i3 + 12 | 0;
+     i11 = 0;
+     do {
+      i12 = HEAP32[i10 >> 2] | 0;
+      if ((HEAP32[i12 + (i11 << 4) + 8 >> 2] & 64 | 0) != 0 ? (i8 = HEAP32[i12 + (i11 << 4) >> 2] | 0, !((HEAP8[i8 + 5 | 0] & 3) == 0)) : 0) {
+       _reallymarkobject(i2, i8);
+       i13 = HEAP32[i9 >> 2] | 0;
+      }
+      i11 = i11 + 1 | 0;
+     } while ((i11 | 0) < (i13 | 0));
+     i7 = HEAP32[i7 >> 2] | 0;
+    } else {
+     i7 = i10;
+    }
+    if (i7 >>> 0 < i6 >>> 0) {
+     do {
+      i10 = i7 + 8 | 0;
+      i11 = HEAP32[i10 >> 2] | 0;
+      i9 = i7 + 24 | 0;
+      i8 = (HEAP32[i9 >> 2] & 64 | 0) == 0;
+      if ((i11 | 0) == 0) {
+       if (!i8 ? !((HEAP8[(HEAP32[i7 + 16 >> 2] | 0) + 5 | 0] & 3) == 0) : 0) {
+        HEAP32[i9 >> 2] = 11;
+       }
+      } else {
+       if (!i8 ? (i5 = HEAP32[i7 + 16 >> 2] | 0, !((HEAP8[i5 + 5 | 0] & 3) == 0)) : 0) {
+        _reallymarkobject(i2, i5);
+        i11 = HEAP32[i10 >> 2] | 0;
+       }
+       if ((i11 & 64 | 0) != 0 ? (i4 = HEAP32[i7 >> 2] | 0, !((HEAP8[i4 + 5 | 0] & 3) == 0)) : 0) {
+        _reallymarkobject(i2, i4);
+       }
+      }
+      i7 = i7 + 32 | 0;
+     } while (i7 >>> 0 < i6 >>> 0);
+    }
+   }
+   i3 = (HEAP32[i3 + 28 >> 2] << 4) + 32 + (32 << HEAPU8[i3 + 7 | 0]) | 0;
+   break;
+  }
+ case 8:
+  {
+   i7 = i3 + 60 | 0;
+   HEAP32[i15 >> 2] = HEAP32[i7 >> 2];
+   i4 = i2 + 88 | 0;
+   HEAP32[i7 >> 2] = HEAP32[i4 >> 2];
+   HEAP32[i4 >> 2] = i3;
+   HEAP8[i10] = HEAP8[i10] & 251;
+   i4 = i3 + 28 | 0;
+   i7 = HEAP32[i4 >> 2] | 0;
+   if ((i7 | 0) == 0) {
+    i3 = 1;
+   } else {
+    i5 = i3 + 8 | 0;
+    i6 = HEAP32[i5 >> 2] | 0;
+    if (i7 >>> 0 < i6 >>> 0) {
+     do {
+      if ((HEAP32[i7 + 8 >> 2] & 64 | 0) != 0 ? (i11 = HEAP32[i7 >> 2] | 0, !((HEAP8[i11 + 5 | 0] & 3) == 0)) : 0) {
+       _reallymarkobject(i2, i11);
+       i6 = HEAP32[i5 >> 2] | 0;
+      }
+      i7 = i7 + 16 | 0;
+     } while (i7 >>> 0 < i6 >>> 0);
+    }
+    if ((HEAP8[i2 + 61 | 0] | 0) == 1) {
+     i3 = i3 + 32 | 0;
+     i4 = (HEAP32[i4 >> 2] | 0) + (HEAP32[i3 >> 2] << 4) | 0;
+     if (i7 >>> 0 < i4 >>> 0) {
+      do {
+       HEAP32[i7 + 8 >> 2] = 0;
+       i7 = i7 + 16 | 0;
+      } while (i7 >>> 0 < i4 >>> 0);
+     }
+    } else {
+     i3 = i3 + 32 | 0;
+    }
+    i3 = (HEAP32[i3 >> 2] << 4) + 112 | 0;
+   }
+   break;
+  }
+ case 9:
+  {
+   HEAP32[i15 >> 2] = HEAP32[i3 + 72 >> 2];
+   i5 = i3 + 32 | 0;
+   i4 = HEAP32[i5 >> 2] | 0;
+   if ((i4 | 0) != 0 ? !((HEAP8[i4 + 5 | 0] & 3) == 0) : 0) {
+    HEAP32[i5 >> 2] = 0;
+   }
+   i4 = HEAP32[i3 + 36 >> 2] | 0;
+   if ((i4 | 0) != 0 ? !((HEAP8[i4 + 5 | 0] & 3) == 0) : 0) {
+    _reallymarkobject(i2, i4);
+   }
+   i4 = i3 + 44 | 0;
+   i8 = HEAP32[i4 >> 2] | 0;
+   if ((i8 | 0) > 0) {
+    i5 = i3 + 8 | 0;
+    i6 = 0;
+    do {
+     i7 = HEAP32[i5 >> 2] | 0;
+     if ((HEAP32[i7 + (i6 << 4) + 8 >> 2] & 64 | 0) != 0 ? (i9 = HEAP32[i7 + (i6 << 4) >> 2] | 0, !((HEAP8[i9 + 5 | 0] & 3) == 0)) : 0) {
+      _reallymarkobject(i2, i9);
+      i8 = HEAP32[i4 >> 2] | 0;
+     }
+     i6 = i6 + 1 | 0;
+    } while ((i6 | 0) < (i8 | 0));
+   }
+   i5 = i3 + 40 | 0;
+   i8 = HEAP32[i5 >> 2] | 0;
+   if ((i8 | 0) > 0) {
+    i6 = i3 + 28 | 0;
+    i7 = 0;
+    do {
+     i9 = HEAP32[(HEAP32[i6 >> 2] | 0) + (i7 << 3) >> 2] | 0;
+     if ((i9 | 0) != 0 ? !((HEAP8[i9 + 5 | 0] & 3) == 0) : 0) {
+      _reallymarkobject(i2, i9);
+      i8 = HEAP32[i5 >> 2] | 0;
+     }
+     i7 = i7 + 1 | 0;
+    } while ((i7 | 0) < (i8 | 0));
+   }
+   i6 = i3 + 56 | 0;
+   i8 = HEAP32[i6 >> 2] | 0;
+   if ((i8 | 0) > 0) {
+    i7 = i3 + 16 | 0;
+    i9 = 0;
+    do {
+     i10 = HEAP32[(HEAP32[i7 >> 2] | 0) + (i9 << 2) >> 2] | 0;
+     if ((i10 | 0) != 0 ? !((HEAP8[i10 + 5 | 0] & 3) == 0) : 0) {
+      _reallymarkobject(i2, i10);
+      i8 = HEAP32[i6 >> 2] | 0;
+     }
+     i9 = i9 + 1 | 0;
+    } while ((i9 | 0) < (i8 | 0));
+   }
+   i7 = i3 + 60 | 0;
+   i11 = HEAP32[i7 >> 2] | 0;
+   if ((i11 | 0) > 0) {
+    i8 = i3 + 24 | 0;
+    i9 = 0;
+    do {
+     i10 = HEAP32[(HEAP32[i8 >> 2] | 0) + (i9 * 12 | 0) >> 2] | 0;
+     if ((i10 | 0) != 0 ? !((HEAP8[i10 + 5 | 0] & 3) == 0) : 0) {
+      _reallymarkobject(i2, i10);
+      i11 = HEAP32[i7 >> 2] | 0;
+     }
+     i9 = i9 + 1 | 0;
+    } while ((i9 | 0) < (i11 | 0));
+    i8 = HEAP32[i6 >> 2] | 0;
+   }
+   i3 = (i11 * 12 | 0) + 80 + (HEAP32[i4 >> 2] << 4) + (HEAP32[i5 >> 2] << 3) + ((HEAP32[i3 + 48 >> 2] | 0) + i8 + (HEAP32[i3 + 52 >> 2] | 0) << 2) | 0;
+   break;
+  }
+ case 38:
+  {
+   HEAP32[i15 >> 2] = HEAP32[i3 + 8 >> 2];
+   i4 = i3 + 6 | 0;
+   i5 = HEAP8[i4] | 0;
+   if (i5 << 24 >> 24 == 0) {
+    i7 = i5 & 255;
+   } else {
+    i6 = 0;
+    do {
+     if ((HEAP32[i3 + (i6 << 4) + 24 >> 2] & 64 | 0) != 0 ? (i14 = HEAP32[i3 + (i6 << 4) + 16 >> 2] | 0, !((HEAP8[i14 + 5 | 0] & 3) == 0)) : 0) {
+      _reallymarkobject(i2, i14);
+      i5 = HEAP8[i4] | 0;
+     }
+     i6 = i6 + 1 | 0;
+     i7 = i5 & 255;
+    } while ((i6 | 0) < (i7 | 0));
+   }
+   i3 = (i7 << 4) + 16 | 0;
+   break;
+  }
+ case 6:
+  {
+   HEAP32[i15 >> 2] = HEAP32[i3 + 8 >> 2];
+   i4 = HEAP32[i3 + 12 >> 2] | 0;
+   if ((i4 | 0) != 0 ? !((HEAP8[i4 + 5 | 0] & 3) == 0) : 0) {
+    _reallymarkobject(i2, i4);
+   }
+   i4 = i3 + 6 | 0;
+   i6 = HEAP8[i4] | 0;
+   if (i6 << 24 >> 24 == 0) {
+    i7 = i6 & 255;
+   } else {
+    i5 = 0;
+    do {
+     i7 = HEAP32[i3 + (i5 << 2) + 16 >> 2] | 0;
+     if ((i7 | 0) != 0 ? !((HEAP8[i7 + 5 | 0] & 3) == 0) : 0) {
+      _reallymarkobject(i2, i7);
+      i6 = HEAP8[i4] | 0;
+     }
+     i5 = i5 + 1 | 0;
+     i7 = i6 & 255;
+    } while ((i5 | 0) < (i7 | 0));
+   }
+   i3 = (i7 << 2) + 16 | 0;
+   break;
+  }
+ default:
+  {
+   STACKTOP = i1;
+   return;
+  }
+ }
+ i15 = i2 + 16 | 0;
+ HEAP32[i15 >> 2] = (HEAP32[i15 >> 2] | 0) + i3;
+ STACKTOP = i1;
+ return;
+}
+function _strstr(i8, i4) {
+ i8 = i8 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 1056 | 0;
+ i6 = i1 + 1024 | 0;
+ i2 = i1;
+ i10 = HEAP8[i4] | 0;
+ if (i10 << 24 >> 24 == 0) {
+  i20 = i8;
+  STACKTOP = i1;
+  return i20 | 0;
+ }
+ i8 = _strchr(i8, i10 << 24 >> 24) | 0;
+ if ((i8 | 0) == 0) {
+  i20 = 0;
+  STACKTOP = i1;
+  return i20 | 0;
+ }
+ i13 = HEAP8[i4 + 1 | 0] | 0;
+ if (i13 << 24 >> 24 == 0) {
+  i20 = i8;
+  STACKTOP = i1;
+  return i20 | 0;
+ }
+ i11 = i8 + 1 | 0;
+ i9 = HEAP8[i11] | 0;
+ if (i9 << 24 >> 24 == 0) {
+  i20 = 0;
+  STACKTOP = i1;
+  return i20 | 0;
+ }
+ i15 = HEAP8[i4 + 2 | 0] | 0;
+ if (i15 << 24 >> 24 == 0) {
+  i2 = i13 & 255 | (i10 & 255) << 8;
+  i3 = i9;
+  i4 = HEAPU8[i8] << 8 | i9 & 255;
+  while (1) {
+   i5 = i4 & 65535;
+   if ((i5 | 0) == (i2 | 0)) {
+    break;
+   }
+   i11 = i11 + 1 | 0;
+   i4 = HEAP8[i11] | 0;
+   if (i4 << 24 >> 24 == 0) {
+    i3 = 0;
+    break;
+   } else {
+    i3 = i4;
+    i4 = i4 & 255 | i5 << 8;
+   }
+  }
+  i20 = i3 << 24 >> 24 == 0 ? 0 : i11 + -1 | 0;
+  STACKTOP = i1;
+  return i20 | 0;
+ }
+ i16 = i8 + 2 | 0;
+ i11 = HEAP8[i16] | 0;
+ if (i11 << 24 >> 24 == 0) {
+  i20 = 0;
+  STACKTOP = i1;
+  return i20 | 0;
+ }
+ i18 = HEAP8[i4 + 3 | 0] | 0;
+ if (i18 << 24 >> 24 == 0) {
+  i2 = (i13 & 255) << 16 | (i10 & 255) << 24 | (i15 & 255) << 8;
+  i4 = (i11 & 255) << 8 | (i9 & 255) << 16 | HEAPU8[i8] << 24;
+  if ((i4 | 0) == (i2 | 0)) {
+   i3 = 0;
+  } else {
+   do {
+    i16 = i16 + 1 | 0;
+    i3 = HEAP8[i16] | 0;
+    i4 = (i3 & 255 | i4) << 8;
+    i3 = i3 << 24 >> 24 == 0;
+   } while (!(i3 | (i4 | 0) == (i2 | 0)));
+  }
+  i20 = i3 ? 0 : i16 + -2 | 0;
+  STACKTOP = i1;
+  return i20 | 0;
+ }
+ i16 = i8 + 3 | 0;
+ i17 = HEAP8[i16] | 0;
+ if (i17 << 24 >> 24 == 0) {
+  i20 = 0;
+  STACKTOP = i1;
+  return i20 | 0;
+ }
+ if ((HEAP8[i4 + 4 | 0] | 0) == 0) {
+  i2 = (i13 & 255) << 16 | (i10 & 255) << 24 | (i15 & 255) << 8 | i18 & 255;
+  i3 = (i11 & 255) << 8 | (i9 & 255) << 16 | i17 & 255 | HEAPU8[i8] << 24;
+  if ((i3 | 0) == (i2 | 0)) {
+   i4 = 0;
+  } else {
+   do {
+    i16 = i16 + 1 | 0;
+    i4 = HEAP8[i16] | 0;
+    i3 = i4 & 255 | i3 << 8;
+    i4 = i4 << 24 >> 24 == 0;
+   } while (!(i4 | (i3 | 0) == (i2 | 0)));
+  }
+  i20 = i4 ? 0 : i16 + -3 | 0;
+  STACKTOP = i1;
+  return i20 | 0;
+ }
+ HEAP32[i6 + 0 >> 2] = 0;
+ HEAP32[i6 + 4 >> 2] = 0;
+ HEAP32[i6 + 8 >> 2] = 0;
+ HEAP32[i6 + 12 >> 2] = 0;
+ HEAP32[i6 + 16 >> 2] = 0;
+ HEAP32[i6 + 20 >> 2] = 0;
+ HEAP32[i6 + 24 >> 2] = 0;
+ HEAP32[i6 + 28 >> 2] = 0;
+ i9 = 0;
+ while (1) {
+  if ((HEAP8[i8 + i9 | 0] | 0) == 0) {
+   i14 = 0;
+   i12 = 80;
+   break;
+  }
+  i20 = i10 & 255;
+  i3 = i6 + (i20 >>> 5 << 2) | 0;
+  HEAP32[i3 >> 2] = HEAP32[i3 >> 2] | 1 << (i20 & 31);
+  i3 = i9 + 1 | 0;
+  HEAP32[i2 + (i20 << 2) >> 2] = i3;
+  i10 = HEAP8[i4 + i3 | 0] | 0;
+  if (i10 << 24 >> 24 == 0) {
+   break;
+  } else {
+   i9 = i3;
+  }
+ }
+ if ((i12 | 0) == 80) {
+  STACKTOP = i1;
+  return i14 | 0;
+ }
+ L49 : do {
+  if (i3 >>> 0 > 1) {
+   i14 = 1;
+   i11 = -1;
+   i12 = 0;
+   L50 : while (1) {
+    i10 = 1;
+    while (1) {
+     i13 = i14;
+     L54 : while (1) {
+      i14 = 1;
+      while (1) {
+       i15 = HEAP8[i4 + (i14 + i11) | 0] | 0;
+       i16 = HEAP8[i4 + i13 | 0] | 0;
+       if (!(i15 << 24 >> 24 == i16 << 24 >> 24)) {
+        break L54;
+       }
+       i15 = i14 + 1 | 0;
+       if ((i14 | 0) == (i10 | 0)) {
+        break;
+       }
+       i13 = i15 + i12 | 0;
+       if (i13 >>> 0 < i3 >>> 0) {
+        i14 = i15;
+       } else {
+        break L50;
+       }
+      }
+      i12 = i12 + i10 | 0;
+      i13 = i12 + 1 | 0;
+      if (!(i13 >>> 0 < i3 >>> 0)) {
+       break L50;
+      }
+     }
+     i10 = i13 - i11 | 0;
+     if (!((i15 & 255) > (i16 & 255))) {
+      break;
+     }
+     i14 = i13 + 1 | 0;
+     if (i14 >>> 0 < i3 >>> 0) {
+      i12 = i13;
+     } else {
+      break L50;
+     }
+    }
+    i14 = i12 + 2 | 0;
+    if (i14 >>> 0 < i3 >>> 0) {
+     i11 = i12;
+     i12 = i12 + 1 | 0;
+    } else {
+     i11 = i12;
+     i10 = 1;
+     break;
+    }
+   }
+   i16 = 1;
+   i12 = -1;
+   i14 = 0;
+   while (1) {
+    i13 = 1;
+    while (1) {
+     i15 = i16;
+     L69 : while (1) {
+      i18 = 1;
+      while (1) {
+       i17 = HEAP8[i4 + (i18 + i12) | 0] | 0;
+       i16 = HEAP8[i4 + i15 | 0] | 0;
+       if (!(i17 << 24 >> 24 == i16 << 24 >> 24)) {
+        break L69;
+       }
+       i16 = i18 + 1 | 0;
+       if ((i18 | 0) == (i13 | 0)) {
+        break;
+       }
+       i15 = i16 + i14 | 0;
+       if (i15 >>> 0 < i3 >>> 0) {
+        i18 = i16;
+       } else {
+        i14 = i12;
+        break L49;
+       }
+      }
+      i14 = i14 + i13 | 0;
+      i15 = i14 + 1 | 0;
+      if (!(i15 >>> 0 < i3 >>> 0)) {
+       i14 = i12;
+       break L49;
+      }
+     }
+     i13 = i15 - i12 | 0;
+     if (!((i17 & 255) < (i16 & 255))) {
+      break;
+     }
+     i16 = i15 + 1 | 0;
+     if (i16 >>> 0 < i3 >>> 0) {
+      i14 = i15;
+     } else {
+      i14 = i12;
+      break L49;
+     }
+    }
+    i16 = i14 + 2 | 0;
+    if (i16 >>> 0 < i3 >>> 0) {
+     i12 = i14;
+     i14 = i14 + 1 | 0;
+    } else {
+     i13 = 1;
+     break;
+    }
+   }
+  } else {
+   i11 = -1;
+   i14 = -1;
+   i10 = 1;
+   i13 = 1;
+  }
+ } while (0);
+ i15 = (i14 + 1 | 0) >>> 0 > (i11 + 1 | 0) >>> 0;
+ i12 = i15 ? i13 : i10;
+ i11 = i15 ? i14 : i11;
+ i10 = i11 + 1 | 0;
+ if ((_memcmp(i4, i4 + i12 | 0, i10) | 0) == 0) {
+  i15 = i3 - i12 | 0;
+  i16 = i3 | 63;
+  if ((i3 | 0) != (i12 | 0)) {
+   i14 = i8;
+   i13 = 0;
+   i17 = i8;
+   L82 : while (1) {
+    i18 = i14;
+    do {
+     if ((i17 - i18 | 0) >>> 0 < i3 >>> 0) {
+      i19 = _memchr(i17, 0, i16) | 0;
+      if ((i19 | 0) != 0) {
+       if ((i19 - i18 | 0) >>> 0 < i3 >>> 0) {
+        i14 = 0;
+        i12 = 80;
+        break L82;
+       } else {
+        i17 = i19;
+        break;
+       }
+      } else {
+       i17 = i17 + i16 | 0;
+       break;
+      }
+     }
+    } while (0);
+    i18 = HEAPU8[i14 + i9 | 0] | 0;
+    if ((1 << (i18 & 31) & HEAP32[i6 + (i18 >>> 5 << 2) >> 2] | 0) == 0) {
+     i14 = i14 + i3 | 0;
+     i13 = 0;
+     continue;
+    }
+    i20 = HEAP32[i2 + (i18 << 2) >> 2] | 0;
+    i18 = i3 - i20 | 0;
+    if ((i3 | 0) != (i20 | 0)) {
+     i14 = i14 + ((i13 | 0) != 0 & i18 >>> 0 < i12 >>> 0 ? i15 : i18) | 0;
+     i13 = 0;
+     continue;
+    }
+    i20 = i10 >>> 0 > i13 >>> 0 ? i10 : i13;
+    i18 = HEAP8[i4 + i20 | 0] | 0;
+    L96 : do {
+     if (i18 << 24 >> 24 == 0) {
+      i19 = i10;
+     } else {
+      while (1) {
+       i19 = i20 + 1 | 0;
+       if (!(i18 << 24 >> 24 == (HEAP8[i14 + i20 | 0] | 0))) {
+        break;
+       }
+       i18 = HEAP8[i4 + i19 | 0] | 0;
+       if (i18 << 24 >> 24 == 0) {
+        i19 = i10;
+        break L96;
+       } else {
+        i20 = i19;
+       }
+      }
+      i14 = i14 + (i20 - i11) | 0;
+      i13 = 0;
+      continue L82;
+     }
+    } while (0);
+    while (1) {
+     if (!(i19 >>> 0 > i13 >>> 0)) {
+      break;
+     }
+     i18 = i19 + -1 | 0;
+     if ((HEAP8[i4 + i18 | 0] | 0) == (HEAP8[i14 + i18 | 0] | 0)) {
+      i19 = i18;
+     } else {
+      break;
+     }
+    }
+    if ((i19 | 0) == (i13 | 0)) {
+     i12 = 80;
+     break;
+    }
+    i14 = i14 + i12 | 0;
+    i13 = i15;
+   }
+   if ((i12 | 0) == 80) {
+    STACKTOP = i1;
+    return i14 | 0;
+   }
+  } else {
+   i5 = i16;
+   i7 = i3;
+  }
+ } else {
+  i7 = i3 - i11 + -1 | 0;
+  i5 = i3 | 63;
+  i7 = (i11 >>> 0 > i7 >>> 0 ? i11 : i7) + 1 | 0;
+ }
+ i12 = i4 + i10 | 0;
+ i14 = i8;
+ L111 : while (1) {
+  i13 = i14;
+  do {
+   if ((i8 - i13 | 0) >>> 0 < i3 >>> 0) {
+    i15 = _memchr(i8, 0, i5) | 0;
+    if ((i15 | 0) != 0) {
+     if ((i15 - i13 | 0) >>> 0 < i3 >>> 0) {
+      i14 = 0;
+      i12 = 80;
+      break L111;
+     } else {
+      i8 = i15;
+      break;
+     }
+    } else {
+     i8 = i8 + i5 | 0;
+     break;
+    }
+   }
+  } while (0);
+  i13 = HEAPU8[i14 + i9 | 0] | 0;
+  if ((1 << (i13 & 31) & HEAP32[i6 + (i13 >>> 5 << 2) >> 2] | 0) == 0) {
+   i14 = i14 + i3 | 0;
+   continue;
+  }
+  i13 = HEAP32[i2 + (i13 << 2) >> 2] | 0;
+  if ((i3 | 0) != (i13 | 0)) {
+   i14 = i14 + (i3 - i13) | 0;
+   continue;
+  }
+  i15 = HEAP8[i12] | 0;
+  L125 : do {
+   if (i15 << 24 >> 24 == 0) {
+    i13 = i10;
+   } else {
+    i16 = i10;
+    while (1) {
+     i13 = i16 + 1 | 0;
+     if (!(i15 << 24 >> 24 == (HEAP8[i14 + i16 | 0] | 0))) {
+      break;
+     }
+     i15 = HEAP8[i4 + i13 | 0] | 0;
+     if (i15 << 24 >> 24 == 0) {
+      i13 = i10;
+      break L125;
+     } else {
+      i16 = i13;
+     }
+    }
+    i14 = i14 + (i16 - i11) | 0;
+    continue L111;
+   }
+  } while (0);
+  do {
+   if ((i13 | 0) == 0) {
+    i12 = 80;
+    break L111;
+   }
+   i13 = i13 + -1 | 0;
+  } while ((HEAP8[i4 + i13 | 0] | 0) == (HEAP8[i14 + i13 | 0] | 0));
+  i14 = i14 + i7 | 0;
+ }
+ if ((i12 | 0) == 80) {
+  STACKTOP = i1;
+  return i14 | 0;
+ }
+ return 0;
+}
+function _str_format(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, d21 = 0.0, i22 = 0;
+ i12 = STACKTOP;
+ STACKTOP = STACKTOP + 1104 | 0;
+ i4 = i12;
+ i7 = i12 + 1060 | 0;
+ i9 = i12 + 1082 | 0;
+ i20 = i12 + 1056 | 0;
+ i10 = i12 + 16 | 0;
+ i5 = i12 + 1064 | 0;
+ i6 = i12 + 8 | 0;
+ i8 = _lua_gettop(i2) | 0;
+ i16 = _luaL_checklstring(i2, 1, i20) | 0;
+ i20 = HEAP32[i20 >> 2] | 0;
+ i3 = i16 + i20 | 0;
+ _luaL_buffinit(i2, i10);
+ L1 : do {
+  if ((i20 | 0) > 0) {
+   i1 = i10 + 8 | 0;
+   i13 = i10 + 4 | 0;
+   i14 = i5 + 1 | 0;
+   i19 = 1;
+   L3 : while (1) {
+    while (1) {
+     i15 = HEAP8[i16] | 0;
+     if (i15 << 24 >> 24 == 37) {
+      i18 = i16 + 1 | 0;
+      if ((HEAP8[i18] | 0) != 37) {
+       break;
+      }
+      i15 = HEAP32[i1 >> 2] | 0;
+      if (i15 >>> 0 < (HEAP32[i13 >> 2] | 0) >>> 0) {
+       i17 = 37;
+      } else {
+       _luaL_prepbuffsize(i10, 1) | 0;
+       i15 = HEAP32[i1 >> 2] | 0;
+       i17 = HEAP8[i18] | 0;
+      }
+      HEAP32[i1 >> 2] = i15 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i15 | 0] = i17;
+      i16 = i16 + 2 | 0;
+     } else {
+      i17 = HEAP32[i1 >> 2] | 0;
+      if (!(i17 >>> 0 < (HEAP32[i13 >> 2] | 0) >>> 0)) {
+       _luaL_prepbuffsize(i10, 1) | 0;
+       i17 = HEAP32[i1 >> 2] | 0;
+       i15 = HEAP8[i16] | 0;
+      }
+      HEAP32[i1 >> 2] = i17 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i17 | 0] = i15;
+      i16 = i16 + 1 | 0;
+     }
+     if (!(i16 >>> 0 < i3 >>> 0)) {
+      break L1;
+     }
+    }
+    i17 = _luaL_prepbuffsize(i10, 512) | 0;
+    i15 = i19 + 1 | 0;
+    if ((i19 | 0) >= (i8 | 0)) {
+     _luaL_argerror(i2, i15, 7648) | 0;
+    }
+    i19 = HEAP8[i18] | 0;
+    L22 : do {
+     if (i19 << 24 >> 24 == 0) {
+      i19 = 0;
+      i20 = i18;
+     } else {
+      i20 = i18;
+      while (1) {
+       i16 = i20 + 1 | 0;
+       if ((_memchr(7800, i19 << 24 >> 24, 6) | 0) == 0) {
+        break L22;
+       }
+       i19 = HEAP8[i16] | 0;
+       if (i19 << 24 >> 24 == 0) {
+        i19 = 0;
+        i20 = i16;
+        break;
+       } else {
+        i20 = i16;
+       }
+      }
+     }
+    } while (0);
+    i16 = i18;
+    if ((i20 - i16 | 0) >>> 0 > 5) {
+     _luaL_error(i2, 7808, i4) | 0;
+     i19 = HEAP8[i20] | 0;
+    }
+    i19 = ((i19 & 255) + -48 | 0) >>> 0 < 10 ? i20 + 1 | 0 : i20;
+    i19 = ((HEAPU8[i19] | 0) + -48 | 0) >>> 0 < 10 ? i19 + 1 | 0 : i19;
+    i20 = HEAP8[i19] | 0;
+    if (i20 << 24 >> 24 == 46) {
+     i20 = i19 + 1 | 0;
+     i19 = ((HEAPU8[i20] | 0) + -48 | 0) >>> 0 < 10 ? i19 + 2 | 0 : i20;
+     i19 = ((HEAPU8[i19] | 0) + -48 | 0) >>> 0 < 10 ? i19 + 1 | 0 : i19;
+     i20 = HEAP8[i19] | 0;
+    }
+    if (((i20 & 255) + -48 | 0) >>> 0 < 10) {
+     _luaL_error(i2, 7840, i4) | 0;
+    }
+    HEAP8[i5] = 37;
+    i16 = i19 - i16 | 0;
+    _memcpy(i14 | 0, i18 | 0, i16 + 1 | 0) | 0;
+    HEAP8[i5 + (i16 + 2) | 0] = 0;
+    i16 = i19 + 1 | 0;
+    i18 = HEAP8[i19] | 0;
+    L36 : do {
+     switch (i18 | 0) {
+     case 115:
+      {
+       i18 = _luaL_tolstring(i2, i15, i6) | 0;
+       if ((_strchr(i5, 46) | 0) == 0 ? (HEAP32[i6 >> 2] | 0) >>> 0 > 99 : 0) {
+        _luaL_addvalue(i10);
+        i17 = 0;
+        break L36;
+       }
+       HEAP32[i4 >> 2] = i18;
+       i17 = _sprintf(i17 | 0, i5 | 0, i4 | 0) | 0;
+       _lua_settop(i2, -2);
+       break;
+      }
+     case 88:
+     case 120:
+     case 117:
+     case 111:
+      {
+       d21 = +_luaL_checknumber(i2, i15);
+       i18 = ~~d21 >>> 0;
+       d21 = d21 - +(i18 >>> 0);
+       if (!(d21 > -1.0 & d21 < 1.0)) {
+        _luaL_argerror(i2, i15, 7696) | 0;
+       }
+       i20 = _strlen(i5 | 0) | 0;
+       i22 = i5 + (i20 + -1) | 0;
+       i19 = HEAP8[i22] | 0;
+       HEAP8[i22] = 108;
+       HEAP8[i22 + 1 | 0] = 0;
+       HEAP8[i5 + i20 | 0] = i19;
+       HEAP8[i5 + (i20 + 1) | 0] = 0;
+       HEAP32[i4 >> 2] = i18;
+       i17 = _sprintf(i17 | 0, i5 | 0, i4 | 0) | 0;
+       break;
+      }
+     case 99:
+      {
+       HEAP32[i4 >> 2] = _luaL_checkinteger(i2, i15) | 0;
+       i17 = _sprintf(i17 | 0, i5 | 0, i4 | 0) | 0;
+       break;
+      }
+     case 113:
+      {
+       i17 = _luaL_checklstring(i2, i15, i7) | 0;
+       i18 = HEAP32[i1 >> 2] | 0;
+       if (!(i18 >>> 0 < (HEAP32[i13 >> 2] | 0) >>> 0)) {
+        _luaL_prepbuffsize(i10, 1) | 0;
+        i18 = HEAP32[i1 >> 2] | 0;
+       }
+       HEAP32[i1 >> 2] = i18 + 1;
+       HEAP8[(HEAP32[i10 >> 2] | 0) + i18 | 0] = 34;
+       i22 = HEAP32[i7 >> 2] | 0;
+       HEAP32[i7 >> 2] = i22 + -1;
+       if ((i22 | 0) != 0) {
+        while (1) {
+         i18 = HEAP8[i17] | 0;
+         do {
+          if (i18 << 24 >> 24 == 10 | i18 << 24 >> 24 == 92 | i18 << 24 >> 24 == 34) {
+           i18 = HEAP32[i1 >> 2] | 0;
+           if (!(i18 >>> 0 < (HEAP32[i13 >> 2] | 0) >>> 0)) {
+            _luaL_prepbuffsize(i10, 1) | 0;
+            i18 = HEAP32[i1 >> 2] | 0;
+           }
+           HEAP32[i1 >> 2] = i18 + 1;
+           HEAP8[(HEAP32[i10 >> 2] | 0) + i18 | 0] = 92;
+           i18 = HEAP32[i1 >> 2] | 0;
+           if (!(i18 >>> 0 < (HEAP32[i13 >> 2] | 0) >>> 0)) {
+            _luaL_prepbuffsize(i10, 1) | 0;
+            i18 = HEAP32[i1 >> 2] | 0;
+           }
+           i22 = HEAP8[i17] | 0;
+           HEAP32[i1 >> 2] = i18 + 1;
+           HEAP8[(HEAP32[i10 >> 2] | 0) + i18 | 0] = i22;
+          } else if (i18 << 24 >> 24 == 0) {
+           i18 = 0;
+           i11 = 44;
+          } else {
+           if ((_iscntrl(i18 & 255 | 0) | 0) != 0) {
+            i18 = HEAP8[i17] | 0;
+            i11 = 44;
+            break;
+           }
+           i18 = HEAP32[i1 >> 2] | 0;
+           if (!(i18 >>> 0 < (HEAP32[i13 >> 2] | 0) >>> 0)) {
+            _luaL_prepbuffsize(i10, 1) | 0;
+            i18 = HEAP32[i1 >> 2] | 0;
+           }
+           i22 = HEAP8[i17] | 0;
+           HEAP32[i1 >> 2] = i18 + 1;
+           HEAP8[(HEAP32[i10 >> 2] | 0) + i18 | 0] = i22;
+          }
+         } while (0);
+         if ((i11 | 0) == 44) {
+          i11 = 0;
+          i18 = i18 & 255;
+          if (((HEAPU8[i17 + 1 | 0] | 0) + -48 | 0) >>> 0 < 10) {
+           HEAP32[i4 >> 2] = i18;
+           _sprintf(i9 | 0, 7792, i4 | 0) | 0;
+          } else {
+           HEAP32[i4 >> 2] = i18;
+           _sprintf(i9 | 0, 7784, i4 | 0) | 0;
+          }
+          _luaL_addstring(i10, i9);
+         }
+         i22 = HEAP32[i7 >> 2] | 0;
+         HEAP32[i7 >> 2] = i22 + -1;
+         if ((i22 | 0) == 0) {
+          break;
+         } else {
+          i17 = i17 + 1 | 0;
+         }
+        }
+       }
+       i17 = HEAP32[i1 >> 2] | 0;
+       if (!(i17 >>> 0 < (HEAP32[i13 >> 2] | 0) >>> 0)) {
+        _luaL_prepbuffsize(i10, 1) | 0;
+        i17 = HEAP32[i1 >> 2] | 0;
+       }
+       HEAP32[i1 >> 2] = i17 + 1;
+       HEAP8[(HEAP32[i10 >> 2] | 0) + i17 | 0] = 34;
+       i17 = 0;
+       break;
+      }
+     case 71:
+     case 103:
+     case 102:
+     case 69:
+     case 101:
+      {
+       HEAP8[i5 + (_strlen(i5 | 0) | 0) | 0] = 0;
+       d21 = +_luaL_checknumber(i2, i15);
+       HEAPF64[tempDoublePtr >> 3] = d21;
+       HEAP32[i4 >> 2] = HEAP32[tempDoublePtr >> 2];
+       HEAP32[i4 + 4 >> 2] = HEAP32[tempDoublePtr + 4 >> 2];
+       i17 = _sprintf(i17 | 0, i5 | 0, i4 | 0) | 0;
+       break;
+      }
+     case 105:
+     case 100:
+      {
+       d21 = +_luaL_checknumber(i2, i15);
+       i18 = ~~d21;
+       d21 = d21 - +(i18 | 0);
+       if (!(d21 > -1.0 & d21 < 1.0)) {
+        _luaL_argerror(i2, i15, 7664) | 0;
+       }
+       i22 = _strlen(i5 | 0) | 0;
+       i19 = i5 + (i22 + -1) | 0;
+       i20 = HEAP8[i19] | 0;
+       HEAP8[i19] = 108;
+       HEAP8[i19 + 1 | 0] = 0;
+       HEAP8[i5 + i22 | 0] = i20;
+       HEAP8[i5 + (i22 + 1) | 0] = 0;
+       HEAP32[i4 >> 2] = i18;
+       i17 = _sprintf(i17 | 0, i5 | 0, i4 | 0) | 0;
+       break;
+      }
+     default:
+      {
+       break L3;
+      }
+     }
+    } while (0);
+    HEAP32[i1 >> 2] = (HEAP32[i1 >> 2] | 0) + i17;
+    if (i16 >>> 0 < i3 >>> 0) {
+     i19 = i15;
+    } else {
+     break L1;
+    }
+   }
+   HEAP32[i4 >> 2] = i18;
+   i22 = _luaL_error(i2, 7744, i4) | 0;
+   STACKTOP = i12;
+   return i22 | 0;
+  }
+ } while (0);
+ _luaL_pushresult(i10);
+ i22 = 1;
+ STACKTOP = i12;
+ return i22 | 0;
+}
+function _luaD_precall(i3, i17, i4) {
+ i3 = i3 | 0;
+ i17 = i17 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i8 = i1;
+ i6 = i3 + 28 | 0;
+ i2 = i3 + 8 | 0;
+ i13 = i3 + 24 | 0;
+ i14 = i3 + 32 | 0;
+ while (1) {
+  i15 = HEAP32[i6 >> 2] | 0;
+  i16 = i17;
+  i12 = i15;
+  i5 = i16 - i12 | 0;
+  i11 = HEAP32[i17 + 8 >> 2] & 63;
+  if ((i11 | 0) == 38) {
+   i11 = 4;
+   break;
+  } else if ((i11 | 0) == 22) {
+   i11 = 3;
+   break;
+  } else if ((i11 | 0) == 6) {
+   i11 = 31;
+   break;
+  }
+  i11 = _luaT_gettmbyobj(i3, i17, 16) | 0;
+  i15 = i16 - (HEAP32[i6 >> 2] | 0) | 0;
+  i16 = i11 + 8 | 0;
+  if ((HEAP32[i16 >> 2] & 15 | 0) != 6) {
+   i11 = 54;
+   break;
+  }
+  i19 = HEAP32[i2 >> 2] | 0;
+  if (i19 >>> 0 > i17 >>> 0) {
+   while (1) {
+    i18 = i19 + -16 | 0;
+    i22 = i18;
+    i21 = HEAP32[i22 + 4 >> 2] | 0;
+    i20 = i19;
+    HEAP32[i20 >> 2] = HEAP32[i22 >> 2];
+    HEAP32[i20 + 4 >> 2] = i21;
+    HEAP32[i19 + 8 >> 2] = HEAP32[i19 + -8 >> 2];
+    if (i18 >>> 0 > i17 >>> 0) {
+     i19 = i18;
+    } else {
+     break;
+    }
+   }
+   i19 = HEAP32[i2 >> 2] | 0;
+  }
+  i17 = i19 + 16 | 0;
+  HEAP32[i2 >> 2] = i17;
+  if (((HEAP32[i13 >> 2] | 0) - i17 | 0) < 16) {
+   i18 = HEAP32[i14 >> 2] | 0;
+   if ((i18 | 0) > 1e6) {
+    i11 = 60;
+    break;
+   }
+   i17 = (i17 - (HEAP32[i6 >> 2] | 0) >> 4) + 5 | 0;
+   i18 = i18 << 1;
+   i18 = (i18 | 0) > 1e6 ? 1e6 : i18;
+   i17 = (i18 | 0) < (i17 | 0) ? i17 : i18;
+   if ((i17 | 0) > 1e6) {
+    i11 = 62;
+    break;
+   }
+   _luaD_reallocstack(i3, i17);
+  }
+  i22 = HEAP32[i6 >> 2] | 0;
+  i17 = i22 + i15 | 0;
+  i19 = i11;
+  i20 = HEAP32[i19 + 4 >> 2] | 0;
+  i21 = i17;
+  HEAP32[i21 >> 2] = HEAP32[i19 >> 2];
+  HEAP32[i21 + 4 >> 2] = i20;
+  HEAP32[i22 + (i15 + 8) >> 2] = HEAP32[i16 >> 2];
+ }
+ if ((i11 | 0) == 3) {
+  i10 = i17;
+ } else if ((i11 | 0) == 4) {
+  i10 = (HEAP32[i17 >> 2] | 0) + 12 | 0;
+ } else if ((i11 | 0) == 31) {
+  i10 = HEAP32[(HEAP32[i17 >> 2] | 0) + 12 >> 2] | 0;
+  i18 = HEAP32[i2 >> 2] | 0;
+  i16 = i18;
+  i11 = i10 + 78 | 0;
+  i17 = HEAPU8[i11] | 0;
+  do {
+   if (((HEAP32[i13 >> 2] | 0) - i16 >> 4 | 0) <= (i17 | 0)) {
+    i13 = HEAP32[i14 >> 2] | 0;
+    if ((i13 | 0) > 1e6) {
+     _luaD_throw(i3, 6);
+    }
+    i12 = i17 + 5 + (i16 - i12 >> 4) | 0;
+    i13 = i13 << 1;
+    i13 = (i13 | 0) > 1e6 ? 1e6 : i13;
+    i12 = (i13 | 0) < (i12 | 0) ? i12 : i13;
+    if ((i12 | 0) > 1e6) {
+     _luaD_reallocstack(i3, 1000200);
+     _luaG_runerror(i3, 2224, i8);
+    } else {
+     _luaD_reallocstack(i3, i12);
+     i7 = HEAP32[i6 >> 2] | 0;
+     i9 = HEAP32[i2 >> 2] | 0;
+     break;
+    }
+   } else {
+    i7 = i15;
+    i9 = i18;
+   }
+  } while (0);
+  i6 = i7 + i5 | 0;
+  i22 = i9 - i6 >> 4;
+  i12 = i22 + -1 | 0;
+  i8 = i10 + 76 | 0;
+  i13 = HEAP8[i8] | 0;
+  if ((i22 | 0) > (i13 & 255 | 0)) {
+   i8 = i13;
+  } else {
+   i13 = i9;
+   while (1) {
+    i9 = i13 + 16 | 0;
+    HEAP32[i2 >> 2] = i9;
+    HEAP32[i13 + 8 >> 2] = 0;
+    i12 = i12 + 1 | 0;
+    i13 = HEAP8[i8] | 0;
+    if ((i12 | 0) < (i13 & 255 | 0)) {
+     i13 = i9;
+    } else {
+     i8 = i13;
+     break;
+    }
+   }
+  }
+  if ((HEAP8[i10 + 77 | 0] | 0) != 0) {
+   i5 = i8 & 255;
+   if (!(i8 << 24 >> 24 == 0) ? (i22 = 0 - i12 | 0, HEAP32[i2 >> 2] = i9 + 16, i19 = i9 + (i22 << 4) | 0, i20 = HEAP32[i19 + 4 >> 2] | 0, i21 = i9, HEAP32[i21 >> 2] = HEAP32[i19 >> 2], HEAP32[i21 + 4 >> 2] = i20, i22 = i9 + (i22 << 4) + 8 | 0, HEAP32[i9 + 8 >> 2] = HEAP32[i22 >> 2], HEAP32[i22 >> 2] = 0, (i8 & 255) > 1) : 0) {
+    i7 = 1;
+    do {
+     i21 = HEAP32[i2 >> 2] | 0;
+     i22 = i7 - i12 | 0;
+     HEAP32[i2 >> 2] = i21 + 16;
+     i18 = i9 + (i22 << 4) | 0;
+     i19 = HEAP32[i18 + 4 >> 2] | 0;
+     i20 = i21;
+     HEAP32[i20 >> 2] = HEAP32[i18 >> 2];
+     HEAP32[i20 + 4 >> 2] = i19;
+     i22 = i9 + (i22 << 4) + 8 | 0;
+     HEAP32[i21 + 8 >> 2] = HEAP32[i22 >> 2];
+     HEAP32[i22 >> 2] = 0;
+     i7 = i7 + 1 | 0;
+    } while ((i7 | 0) < (i5 | 0));
+   }
+  } else {
+   i9 = i7 + (i5 + 16) | 0;
+  }
+  i7 = i3 + 16 | 0;
+  i5 = HEAP32[(HEAP32[i7 >> 2] | 0) + 12 >> 2] | 0;
+  if ((i5 | 0) == 0) {
+   i5 = _luaE_extendCI(i3) | 0;
+  }
+  HEAP32[i7 >> 2] = i5;
+  HEAP16[i5 + 16 >> 1] = i4;
+  HEAP32[i5 >> 2] = i6;
+  HEAP32[i5 + 24 >> 2] = i9;
+  i22 = i9 + (HEAPU8[i11] << 4) | 0;
+  HEAP32[i5 + 4 >> 2] = i22;
+  i4 = i5 + 28 | 0;
+  HEAP32[i4 >> 2] = HEAP32[i10 + 12 >> 2];
+  i6 = i5 + 18 | 0;
+  HEAP8[i6] = 1;
+  HEAP32[i2 >> 2] = i22;
+  if ((HEAP32[(HEAP32[i3 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+   _luaC_step(i3);
+  }
+  if ((HEAP8[i3 + 40 | 0] & 1) == 0) {
+   i22 = 0;
+   STACKTOP = i1;
+   return i22 | 0;
+  }
+  HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + 4;
+  i2 = HEAP32[i5 + 8 >> 2] | 0;
+  if (!((HEAP8[i2 + 18 | 0] & 1) == 0) ? (HEAP32[(HEAP32[i2 + 28 >> 2] | 0) + -4 >> 2] & 63 | 0) == 30 : 0) {
+   HEAP8[i6] = HEAPU8[i6] | 64;
+   i2 = 4;
+  } else {
+   i2 = 0;
+  }
+  _luaD_hook(i3, i2, -1);
+  HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + -4;
+  i22 = 0;
+  STACKTOP = i1;
+  return i22 | 0;
+ } else if ((i11 | 0) == 54) {
+  _luaG_typeerror(i3, i17, 2520);
+ } else if ((i11 | 0) == 60) {
+  _luaD_throw(i3, 6);
+ } else if ((i11 | 0) == 62) {
+  _luaD_reallocstack(i3, 1000200);
+  _luaG_runerror(i3, 2224, i8);
+ }
+ i7 = HEAP32[i10 >> 2] | 0;
+ i9 = HEAP32[i2 >> 2] | 0;
+ do {
+  if (((HEAP32[i13 >> 2] | 0) - i9 | 0) < 336) {
+   i10 = HEAP32[i14 >> 2] | 0;
+   if ((i10 | 0) > 1e6) {
+    _luaD_throw(i3, 6);
+   }
+   i9 = (i9 - i12 >> 4) + 25 | 0;
+   i10 = i10 << 1;
+   i10 = (i10 | 0) > 1e6 ? 1e6 : i10;
+   i9 = (i10 | 0) < (i9 | 0) ? i9 : i10;
+   if ((i9 | 0) > 1e6) {
+    _luaD_reallocstack(i3, 1000200);
+    _luaG_runerror(i3, 2224, i8);
+   } else {
+    _luaD_reallocstack(i3, i9);
+    break;
+   }
+  }
+ } while (0);
+ i8 = i3 + 16 | 0;
+ i9 = HEAP32[(HEAP32[i8 >> 2] | 0) + 12 >> 2] | 0;
+ if ((i9 | 0) == 0) {
+  i9 = _luaE_extendCI(i3) | 0;
+ }
+ HEAP32[i8 >> 2] = i9;
+ HEAP16[i9 + 16 >> 1] = i4;
+ HEAP32[i9 >> 2] = (HEAP32[i6 >> 2] | 0) + i5;
+ HEAP32[i9 + 4 >> 2] = (HEAP32[i2 >> 2] | 0) + 320;
+ HEAP8[i9 + 18 | 0] = 0;
+ if ((HEAP32[(HEAP32[i3 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+  _luaC_step(i3);
+ }
+ i5 = i3 + 40 | 0;
+ if (!((HEAP8[i5] & 1) == 0)) {
+  _luaD_hook(i3, 0, -1);
+ }
+ i7 = FUNCTION_TABLE_ii[i7 & 255](i3) | 0;
+ i7 = (HEAP32[i2 >> 2] | 0) + (0 - i7 << 4) | 0;
+ i4 = HEAP32[i8 >> 2] | 0;
+ i5 = HEAPU8[i5] | 0;
+ if ((i5 & 6 | 0) == 0) {
+  i5 = i7;
+  i6 = i4 + 8 | 0;
+ } else {
+  if ((i5 & 2 | 0) == 0) {
+   i5 = i7;
+  } else {
+   i5 = i7 - (HEAP32[i6 >> 2] | 0) | 0;
+   _luaD_hook(i3, 1, -1);
+   i5 = (HEAP32[i6 >> 2] | 0) + i5 | 0;
+  }
+  i6 = i4 + 8 | 0;
+  HEAP32[i3 + 20 >> 2] = HEAP32[(HEAP32[i6 >> 2] | 0) + 28 >> 2];
+ }
+ i3 = HEAP32[i4 >> 2] | 0;
+ i4 = HEAP16[i4 + 16 >> 1] | 0;
+ HEAP32[i8 >> 2] = HEAP32[i6 >> 2];
+ L82 : do {
+  if (!(i4 << 16 >> 16 == 0)) {
+   i4 = i4 << 16 >> 16;
+   while (1) {
+    if (!(i5 >>> 0 < (HEAP32[i2 >> 2] | 0) >>> 0)) {
+     break;
+    }
+    i6 = i3 + 16 | 0;
+    i20 = i5;
+    i21 = HEAP32[i20 + 4 >> 2] | 0;
+    i22 = i3;
+    HEAP32[i22 >> 2] = HEAP32[i20 >> 2];
+    HEAP32[i22 + 4 >> 2] = i21;
+    HEAP32[i3 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+    i4 = i4 + -1 | 0;
+    if ((i4 | 0) == 0) {
+     i3 = i6;
+     break L82;
+    }
+    i5 = i5 + 16 | 0;
+    i3 = i6;
+   }
+   if ((i4 | 0) > 0) {
+    i5 = i4;
+    i6 = i3;
+    while (1) {
+     i5 = i5 + -1 | 0;
+     HEAP32[i6 + 8 >> 2] = 0;
+     if ((i5 | 0) <= 0) {
+      break;
+     } else {
+      i6 = i6 + 16 | 0;
+     }
+    }
+    i3 = i3 + (i4 << 4) | 0;
+   }
+  }
+ } while (0);
+ HEAP32[i2 >> 2] = i3;
+ i22 = 1;
+ STACKTOP = i1;
+ return i22 | 0;
+}
+function _lua_getinfo(i1, i6, i29) {
+ i1 = i1 | 0;
+ i6 = i6 | 0;
+ i29 = i29 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i30 = 0, i31 = 0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, i36 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i3;
+ if ((HEAP8[i6] | 0) == 62) {
+  i10 = i1 + 8 | 0;
+  i7 = (HEAP32[i10 >> 2] | 0) + -16 | 0;
+  HEAP32[i10 >> 2] = i7;
+  i6 = i6 + 1 | 0;
+  i10 = 0;
+ } else {
+  i7 = HEAP32[i29 + 96 >> 2] | 0;
+  i10 = i7;
+  i7 = HEAP32[i7 >> 2] | 0;
+ }
+ i8 = i7 + 8 | 0;
+ if ((HEAP32[i8 >> 2] & 31 | 0) == 6) {
+  i9 = HEAP32[i7 >> 2] | 0;
+ } else {
+  i9 = 0;
+ }
+ i34 = HEAP8[i6] | 0;
+ L8 : do {
+  if (i34 << 24 >> 24 == 0) {
+   i33 = 1;
+  } else {
+   i12 = (i9 | 0) == 0;
+   i27 = i29 + 16 | 0;
+   i28 = i29 + 24 | 0;
+   i21 = i29 + 28 | 0;
+   i25 = i29 + 12 | 0;
+   i26 = i29 + 36 | 0;
+   i19 = i9 + 4 | 0;
+   i24 = i9 + 12 | 0;
+   i18 = (i10 | 0) == 0;
+   i23 = i29 + 20 | 0;
+   i17 = i10 + 18 | 0;
+   i22 = i10 + 28 | 0;
+   i15 = i29 + 32 | 0;
+   i14 = i29 + 34 | 0;
+   i13 = i29 + 33 | 0;
+   i11 = i9 + 6 | 0;
+   i16 = i29 + 35 | 0;
+   i20 = i29 + 8 | 0;
+   i30 = i29 + 4 | 0;
+   i29 = i10 + 8 | 0;
+   i31 = i1 + 12 | 0;
+   i32 = i6;
+   i33 = 1;
+   while (1) {
+    L12 : do {
+     switch (i34 << 24 >> 24 | 0) {
+     case 116:
+      {
+       if (i18) {
+        i34 = 0;
+       } else {
+        i34 = HEAPU8[i17] & 64;
+       }
+       HEAP8[i16] = i34;
+       break;
+      }
+     case 110:
+      {
+       L18 : do {
+        if ((!i18 ? (HEAP8[i17] & 64) == 0 : 0) ? (i5 = HEAP32[i29 >> 2] | 0, !((HEAP8[i5 + 18 | 0] & 1) == 0)) : 0) {
+         i36 = HEAP32[(HEAP32[HEAP32[i5 >> 2] >> 2] | 0) + 12 >> 2] | 0;
+         i35 = HEAP32[i36 + 12 >> 2] | 0;
+         i34 = ((HEAP32[i5 + 28 >> 2] | 0) - i35 >> 2) + -1 | 0;
+         i35 = HEAP32[i35 + (i34 << 2) >> 2] | 0;
+         switch (i35 & 63 | 0) {
+         case 10:
+         case 8:
+          {
+           i34 = 1;
+           i4 = 46;
+           break;
+          }
+         case 24:
+          {
+           i34 = 5;
+           i4 = 46;
+           break;
+          }
+         case 13:
+          {
+           i34 = 6;
+           i4 = 46;
+           break;
+          }
+         case 14:
+          {
+           i34 = 7;
+           i4 = 46;
+           break;
+          }
+         case 15:
+          {
+           i34 = 8;
+           i4 = 46;
+           break;
+          }
+         case 16:
+          {
+           i34 = 9;
+           i4 = 46;
+           break;
+          }
+         case 17:
+          {
+           i34 = 10;
+           i4 = 46;
+           break;
+          }
+         case 18:
+          {
+           i34 = 11;
+           i4 = 46;
+           break;
+          }
+         case 19:
+          {
+           i34 = 12;
+           i4 = 46;
+           break;
+          }
+         case 21:
+          {
+           i34 = 4;
+           i4 = 46;
+           break;
+          }
+         case 25:
+          {
+           i34 = 13;
+           i4 = 46;
+           break;
+          }
+         case 26:
+          {
+           i34 = 14;
+           i4 = 46;
+           break;
+          }
+         case 22:
+          {
+           i34 = 15;
+           i4 = 46;
+           break;
+          }
+         case 7:
+         case 6:
+         case 12:
+          {
+           i34 = 0;
+           i4 = 46;
+           break;
+          }
+         case 34:
+          {
+           i34 = 2120;
+           i35 = 2120;
+           break;
+          }
+         case 30:
+         case 29:
+          {
+           i36 = _getobjname(i36, i34, i35 >>> 6 & 255, i30) | 0;
+           HEAP32[i20 >> 2] = i36;
+           if ((i36 | 0) == 0) {
+            break L18;
+           } else {
+            break L12;
+           }
+          }
+         default:
+          {
+           i4 = 47;
+           break L18;
+          }
+         }
+         if ((i4 | 0) == 46) {
+          i4 = 0;
+          i34 = (HEAP32[(HEAP32[i31 >> 2] | 0) + (i34 << 2) + 184 >> 2] | 0) + 16 | 0;
+          i35 = 2136;
+         }
+         HEAP32[i30 >> 2] = i34;
+         HEAP32[i20 >> 2] = i35;
+         break L12;
+        } else {
+         i4 = 47;
+        }
+       } while (0);
+       if ((i4 | 0) == 47) {
+        i4 = 0;
+        HEAP32[i20 >> 2] = 0;
+       }
+       HEAP32[i20 >> 2] = 2112;
+       HEAP32[i30 >> 2] = 0;
+       break;
+      }
+     case 108:
+      {
+       if (!i18 ? !((HEAP8[i17] & 1) == 0) : 0) {
+        i35 = HEAP32[(HEAP32[HEAP32[i10 >> 2] >> 2] | 0) + 12 >> 2] | 0;
+        i34 = HEAP32[i35 + 20 >> 2] | 0;
+        if ((i34 | 0) == 0) {
+         i34 = 0;
+        } else {
+         i34 = HEAP32[i34 + (((HEAP32[i22 >> 2] | 0) - (HEAP32[i35 + 12 >> 2] | 0) >> 2) + -1 << 2) >> 2] | 0;
+        }
+       } else {
+        i34 = -1;
+       }
+       HEAP32[i23 >> 2] = i34;
+       break;
+      }
+     case 83:
+      {
+       if (!i12 ? (HEAP8[i19] | 0) != 38 : 0) {
+        i34 = HEAP32[i24 >> 2] | 0;
+        i35 = HEAP32[i34 + 36 >> 2] | 0;
+        if ((i35 | 0) == 0) {
+         i35 = 2168;
+        } else {
+         i35 = i35 + 16 | 0;
+        }
+        HEAP32[i27 >> 2] = i35;
+        i36 = HEAP32[i34 + 64 >> 2] | 0;
+        HEAP32[i28 >> 2] = i36;
+        HEAP32[i21 >> 2] = HEAP32[i34 + 68 >> 2];
+        i34 = (i36 | 0) == 0 ? 2176 : 2184;
+       } else {
+        HEAP32[i27 >> 2] = 2152;
+        HEAP32[i28 >> 2] = -1;
+        HEAP32[i21 >> 2] = -1;
+        i35 = 2152;
+        i34 = 2160;
+       }
+       HEAP32[i25 >> 2] = i34;
+       _luaO_chunkid(i26, i35, 60);
+       break;
+      }
+     case 117:
+      {
+       if (!i12) {
+        HEAP8[i15] = HEAP8[i11] | 0;
+        if ((HEAP8[i19] | 0) != 38) {
+         HEAP8[i14] = HEAP8[(HEAP32[i24 >> 2] | 0) + 77 | 0] | 0;
+         HEAP8[i13] = HEAP8[(HEAP32[i24 >> 2] | 0) + 76 | 0] | 0;
+         break L12;
+        }
+       } else {
+        HEAP8[i15] = 0;
+       }
+       HEAP8[i14] = 1;
+       HEAP8[i13] = 0;
+       break;
+      }
+     case 102:
+     case 76:
+      {
+       break;
+      }
+     default:
+      {
+       i33 = 0;
+      }
+     }
+    } while (0);
+    i32 = i32 + 1 | 0;
+    i34 = HEAP8[i32] | 0;
+    if (i34 << 24 >> 24 == 0) {
+     break L8;
+    }
+   }
+  }
+ } while (0);
+ if ((_strchr(i6, 102) | 0) != 0) {
+  i36 = i1 + 8 | 0;
+  i35 = HEAP32[i36 >> 2] | 0;
+  i31 = i7;
+  i32 = HEAP32[i31 + 4 >> 2] | 0;
+  i34 = i35;
+  HEAP32[i34 >> 2] = HEAP32[i31 >> 2];
+  HEAP32[i34 + 4 >> 2] = i32;
+  HEAP32[i35 + 8 >> 2] = HEAP32[i8 >> 2];
+  HEAP32[i36 >> 2] = (HEAP32[i36 >> 2] | 0) + 16;
+ }
+ if ((_strchr(i6, 76) | 0) == 0) {
+  STACKTOP = i3;
+  return i33 | 0;
+ }
+ if ((i9 | 0) != 0 ? (HEAP8[i9 + 4 | 0] | 0) != 38 : 0) {
+  i6 = i9 + 12 | 0;
+  i5 = HEAP32[(HEAP32[i6 >> 2] | 0) + 20 >> 2] | 0;
+  i4 = _luaH_new(i1) | 0;
+  i36 = i1 + 8 | 0;
+  i35 = HEAP32[i36 >> 2] | 0;
+  HEAP32[i35 >> 2] = i4;
+  HEAP32[i35 + 8 >> 2] = 69;
+  HEAP32[i36 >> 2] = (HEAP32[i36 >> 2] | 0) + 16;
+  HEAP32[i2 >> 2] = 1;
+  HEAP32[i2 + 8 >> 2] = 1;
+  if ((HEAP32[(HEAP32[i6 >> 2] | 0) + 52 >> 2] | 0) > 0) {
+   i7 = 0;
+  } else {
+   STACKTOP = i3;
+   return i33 | 0;
+  }
+  do {
+   _luaH_setint(i1, i4, HEAP32[i5 + (i7 << 2) >> 2] | 0, i2);
+   i7 = i7 + 1 | 0;
+  } while ((i7 | 0) < (HEAP32[(HEAP32[i6 >> 2] | 0) + 52 >> 2] | 0));
+  STACKTOP = i3;
+  return i33 | 0;
+ }
+ i36 = i1 + 8 | 0;
+ i35 = HEAP32[i36 >> 2] | 0;
+ HEAP32[i35 + 8 >> 2] = 0;
+ HEAP32[i36 >> 2] = i35 + 16;
+ STACKTOP = i3;
+ return i33 | 0;
+}
+function _read_long_string(i3, i1, i5) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0;
+ i2 = STACKTOP;
+ i14 = HEAP32[i3 >> 2] | 0;
+ i4 = i3 + 60 | 0;
+ i13 = HEAP32[i4 >> 2] | 0;
+ i15 = i13 + 4 | 0;
+ i16 = HEAP32[i15 >> 2] | 0;
+ i10 = i13 + 8 | 0;
+ i12 = HEAP32[i10 >> 2] | 0;
+ do {
+  if ((i16 + 1 | 0) >>> 0 > i12 >>> 0) {
+   if (i12 >>> 0 > 2147483645) {
+    _lexerror(i3, 12368, 0);
+   }
+   i16 = i12 << 1;
+   i17 = HEAP32[i3 + 52 >> 2] | 0;
+   if ((i16 | 0) == -2) {
+    _luaM_toobig(i17);
+   } else {
+    i8 = _luaM_realloc_(i17, HEAP32[i13 >> 2] | 0, i12, i16) | 0;
+    HEAP32[i13 >> 2] = i8;
+    HEAP32[i10 >> 2] = i16;
+    i9 = HEAP32[i15 >> 2] | 0;
+    break;
+   }
+  } else {
+   i9 = i16;
+   i8 = HEAP32[i13 >> 2] | 0;
+  }
+ } while (0);
+ HEAP32[i15 >> 2] = i9 + 1;
+ HEAP8[i8 + i9 | 0] = i14;
+ i9 = i3 + 56 | 0;
+ i8 = HEAP32[i9 >> 2] | 0;
+ i18 = HEAP32[i8 >> 2] | 0;
+ HEAP32[i8 >> 2] = i18 + -1;
+ if ((i18 | 0) == 0) {
+  i12 = _luaZ_fill(i8) | 0;
+ } else {
+  i18 = i8 + 4 | 0;
+  i12 = HEAP32[i18 >> 2] | 0;
+  HEAP32[i18 >> 2] = i12 + 1;
+  i12 = HEAPU8[i12] | 0;
+ }
+ HEAP32[i3 >> 2] = i12;
+ if ((i12 | 0) == 13 | (i12 | 0) == 10) {
+  _inclinenumber(i3);
+  i11 = 13;
+ }
+ L17 : while (1) {
+  if ((i11 | 0) == 13) {
+   i11 = 0;
+   i12 = HEAP32[i3 >> 2] | 0;
+  }
+  i8 = (i1 | 0) == 0;
+  i10 = i3 + 52 | 0;
+  L21 : do {
+   if (i8) {
+    while (1) {
+     if ((i12 | 0) == 13 | (i12 | 0) == 10) {
+      break L21;
+     } else if ((i12 | 0) == 93) {
+      i11 = 22;
+      break L21;
+     } else if ((i12 | 0) == -1) {
+      i11 = 21;
+      break L17;
+     }
+     i12 = HEAP32[i9 >> 2] | 0;
+     i18 = HEAP32[i12 >> 2] | 0;
+     HEAP32[i12 >> 2] = i18 + -1;
+     if ((i18 | 0) == 0) {
+      i12 = _luaZ_fill(i12) | 0;
+     } else {
+      i18 = i12 + 4 | 0;
+      i12 = HEAP32[i18 >> 2] | 0;
+      HEAP32[i18 >> 2] = i12 + 1;
+      i12 = HEAPU8[i12] | 0;
+     }
+     HEAP32[i3 >> 2] = i12;
+    }
+   } else {
+    while (1) {
+     if ((i12 | 0) == 13 | (i12 | 0) == 10) {
+      break L21;
+     } else if ((i12 | 0) == 93) {
+      i11 = 22;
+      break L21;
+     } else if ((i12 | 0) == -1) {
+      i11 = 21;
+      break L17;
+     }
+     i14 = HEAP32[i4 >> 2] | 0;
+     i13 = i14 + 4 | 0;
+     i17 = HEAP32[i13 >> 2] | 0;
+     i16 = i14 + 8 | 0;
+     i15 = HEAP32[i16 >> 2] | 0;
+     if ((i17 + 1 | 0) >>> 0 > i15 >>> 0) {
+      if (i15 >>> 0 > 2147483645) {
+       i11 = 46;
+       break L17;
+      }
+      i17 = i15 << 1;
+      i18 = HEAP32[i10 >> 2] | 0;
+      if ((i17 | 0) == -2) {
+       i11 = 48;
+       break L17;
+      }
+      i18 = _luaM_realloc_(i18, HEAP32[i14 >> 2] | 0, i15, i17) | 0;
+      HEAP32[i14 >> 2] = i18;
+      HEAP32[i16 >> 2] = i17;
+      i17 = HEAP32[i13 >> 2] | 0;
+      i14 = i18;
+     } else {
+      i14 = HEAP32[i14 >> 2] | 0;
+     }
+     HEAP32[i13 >> 2] = i17 + 1;
+     HEAP8[i14 + i17 | 0] = i12;
+     i12 = HEAP32[i9 >> 2] | 0;
+     i18 = HEAP32[i12 >> 2] | 0;
+     HEAP32[i12 >> 2] = i18 + -1;
+     if ((i18 | 0) == 0) {
+      i12 = _luaZ_fill(i12) | 0;
+     } else {
+      i18 = i12 + 4 | 0;
+      i12 = HEAP32[i18 >> 2] | 0;
+      HEAP32[i18 >> 2] = i12 + 1;
+      i12 = HEAPU8[i12] | 0;
+     }
+     HEAP32[i3 >> 2] = i12;
+    }
+   }
+  } while (0);
+  if ((i11 | 0) == 22) {
+   if ((_skip_sep(i3) | 0) == (i5 | 0)) {
+    i11 = 23;
+    break;
+   } else {
+    i11 = 13;
+    continue;
+   }
+  }
+  i12 = HEAP32[i4 >> 2] | 0;
+  i11 = i12 + 4 | 0;
+  i15 = HEAP32[i11 >> 2] | 0;
+  i14 = i12 + 8 | 0;
+  i13 = HEAP32[i14 >> 2] | 0;
+  if ((i15 + 1 | 0) >>> 0 > i13 >>> 0) {
+   if (i13 >>> 0 > 2147483645) {
+    i11 = 37;
+    break;
+   }
+   i15 = i13 << 1;
+   i10 = HEAP32[i10 >> 2] | 0;
+   if ((i15 | 0) == -2) {
+    i11 = 39;
+    break;
+   }
+   i10 = _luaM_realloc_(i10, HEAP32[i12 >> 2] | 0, i13, i15) | 0;
+   HEAP32[i12 >> 2] = i10;
+   HEAP32[i14 >> 2] = i15;
+   i15 = HEAP32[i11 >> 2] | 0;
+  } else {
+   i10 = HEAP32[i12 >> 2] | 0;
+  }
+  HEAP32[i11 >> 2] = i15 + 1;
+  HEAP8[i10 + i15 | 0] = 10;
+  _inclinenumber(i3);
+  if (!i8) {
+   i11 = 13;
+   continue;
+  }
+  HEAP32[(HEAP32[i4 >> 2] | 0) + 4 >> 2] = 0;
+  i11 = 13;
+ }
+ if ((i11 | 0) == 21) {
+  _lexerror(i3, (i1 | 0) != 0 ? 12512 : 12536, 286);
+ } else if ((i11 | 0) == 23) {
+  i15 = HEAP32[i3 >> 2] | 0;
+  i13 = HEAP32[i4 >> 2] | 0;
+  i14 = i13 + 4 | 0;
+  i16 = HEAP32[i14 >> 2] | 0;
+  i11 = i13 + 8 | 0;
+  i12 = HEAP32[i11 >> 2] | 0;
+  do {
+   if ((i16 + 1 | 0) >>> 0 > i12 >>> 0) {
+    if (i12 >>> 0 > 2147483645) {
+     _lexerror(i3, 12368, 0);
+    }
+    i17 = i12 << 1;
+    i16 = HEAP32[i10 >> 2] | 0;
+    if ((i17 | 0) == -2) {
+     _luaM_toobig(i16);
+    } else {
+     i6 = _luaM_realloc_(i16, HEAP32[i13 >> 2] | 0, i12, i17) | 0;
+     HEAP32[i13 >> 2] = i6;
+     HEAP32[i11 >> 2] = i17;
+     i7 = HEAP32[i14 >> 2] | 0;
+     break;
+    }
+   } else {
+    i7 = i16;
+    i6 = HEAP32[i13 >> 2] | 0;
+   }
+  } while (0);
+  HEAP32[i14 >> 2] = i7 + 1;
+  HEAP8[i6 + i7 | 0] = i15;
+  i6 = HEAP32[i9 >> 2] | 0;
+  i18 = HEAP32[i6 >> 2] | 0;
+  HEAP32[i6 >> 2] = i18 + -1;
+  if ((i18 | 0) == 0) {
+   i6 = _luaZ_fill(i6) | 0;
+  } else {
+   i18 = i6 + 4 | 0;
+   i6 = HEAP32[i18 >> 2] | 0;
+   HEAP32[i18 >> 2] = i6 + 1;
+   i6 = HEAPU8[i6] | 0;
+  }
+  HEAP32[i3 >> 2] = i6;
+  if (i8) {
+   STACKTOP = i2;
+   return;
+  }
+  i4 = HEAP32[i4 >> 2] | 0;
+  i5 = i5 + 2 | 0;
+  i6 = HEAP32[i10 >> 2] | 0;
+  i5 = _luaS_newlstr(i6, (HEAP32[i4 >> 2] | 0) + i5 | 0, (HEAP32[i4 + 4 >> 2] | 0) - (i5 << 1) | 0) | 0;
+  i4 = i6 + 8 | 0;
+  i7 = HEAP32[i4 >> 2] | 0;
+  HEAP32[i4 >> 2] = i7 + 16;
+  HEAP32[i7 >> 2] = i5;
+  HEAP32[i7 + 8 >> 2] = HEAPU8[i5 + 4 | 0] | 0 | 64;
+  i7 = _luaH_set(i6, HEAP32[(HEAP32[i3 + 48 >> 2] | 0) + 4 >> 2] | 0, (HEAP32[i4 >> 2] | 0) + -16 | 0) | 0;
+  i3 = i7 + 8 | 0;
+  if ((HEAP32[i3 >> 2] | 0) == 0 ? (HEAP32[i7 >> 2] = 1, HEAP32[i3 >> 2] = 1, (HEAP32[(HEAP32[i6 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) : 0) {
+   _luaC_step(i6);
+  }
+  HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + -16;
+  HEAP32[i1 >> 2] = i5;
+  STACKTOP = i2;
+  return;
+ } else if ((i11 | 0) == 37) {
+  _lexerror(i3, 12368, 0);
+ } else if ((i11 | 0) == 39) {
+  _luaM_toobig(i10);
+ } else if ((i11 | 0) == 46) {
+  _lexerror(i3, 12368, 0);
+ } else if ((i11 | 0) == 48) {
+  _luaM_toobig(i18);
+ }
+}
+function _try_realloc_chunk(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0;
+ i2 = STACKTOP;
+ i4 = i1 + 4 | 0;
+ i6 = HEAP32[i4 >> 2] | 0;
+ i8 = i6 & -8;
+ i5 = i1 + i8 | 0;
+ i10 = HEAP32[12928 >> 2] | 0;
+ if (i1 >>> 0 < i10 >>> 0) {
+  _abort();
+ }
+ i12 = i6 & 3;
+ if (!((i12 | 0) != 1 & i1 >>> 0 < i5 >>> 0)) {
+  _abort();
+ }
+ i7 = i1 + (i8 | 4) | 0;
+ i13 = HEAP32[i7 >> 2] | 0;
+ if ((i13 & 1 | 0) == 0) {
+  _abort();
+ }
+ if ((i12 | 0) == 0) {
+  if (i3 >>> 0 < 256) {
+   i15 = 0;
+   STACKTOP = i2;
+   return i15 | 0;
+  }
+  if (!(i8 >>> 0 < (i3 + 4 | 0) >>> 0) ? !((i8 - i3 | 0) >>> 0 > HEAP32[13392 >> 2] << 1 >>> 0) : 0) {
+   i15 = i1;
+   STACKTOP = i2;
+   return i15 | 0;
+  }
+  i15 = 0;
+  STACKTOP = i2;
+  return i15 | 0;
+ }
+ if (!(i8 >>> 0 < i3 >>> 0)) {
+  i5 = i8 - i3 | 0;
+  if (!(i5 >>> 0 > 15)) {
+   i15 = i1;
+   STACKTOP = i2;
+   return i15 | 0;
+  }
+  HEAP32[i4 >> 2] = i6 & 1 | i3 | 2;
+  HEAP32[i1 + (i3 + 4) >> 2] = i5 | 3;
+  HEAP32[i7 >> 2] = HEAP32[i7 >> 2] | 1;
+  _dispose_chunk(i1 + i3 | 0, i5);
+  i15 = i1;
+  STACKTOP = i2;
+  return i15 | 0;
+ }
+ if ((i5 | 0) == (HEAP32[12936 >> 2] | 0)) {
+  i5 = (HEAP32[12924 >> 2] | 0) + i8 | 0;
+  if (!(i5 >>> 0 > i3 >>> 0)) {
+   i15 = 0;
+   STACKTOP = i2;
+   return i15 | 0;
+  }
+  i15 = i5 - i3 | 0;
+  HEAP32[i4 >> 2] = i6 & 1 | i3 | 2;
+  HEAP32[i1 + (i3 + 4) >> 2] = i15 | 1;
+  HEAP32[12936 >> 2] = i1 + i3;
+  HEAP32[12924 >> 2] = i15;
+  i15 = i1;
+  STACKTOP = i2;
+  return i15 | 0;
+ }
+ if ((i5 | 0) == (HEAP32[12932 >> 2] | 0)) {
+  i7 = (HEAP32[12920 >> 2] | 0) + i8 | 0;
+  if (i7 >>> 0 < i3 >>> 0) {
+   i15 = 0;
+   STACKTOP = i2;
+   return i15 | 0;
+  }
+  i5 = i7 - i3 | 0;
+  if (i5 >>> 0 > 15) {
+   HEAP32[i4 >> 2] = i6 & 1 | i3 | 2;
+   HEAP32[i1 + (i3 + 4) >> 2] = i5 | 1;
+   HEAP32[i1 + i7 >> 2] = i5;
+   i15 = i1 + (i7 + 4) | 0;
+   HEAP32[i15 >> 2] = HEAP32[i15 >> 2] & -2;
+   i3 = i1 + i3 | 0;
+  } else {
+   HEAP32[i4 >> 2] = i6 & 1 | i7 | 2;
+   i3 = i1 + (i7 + 4) | 0;
+   HEAP32[i3 >> 2] = HEAP32[i3 >> 2] | 1;
+   i3 = 0;
+   i5 = 0;
+  }
+  HEAP32[12920 >> 2] = i5;
+  HEAP32[12932 >> 2] = i3;
+  i15 = i1;
+  STACKTOP = i2;
+  return i15 | 0;
+ }
+ if ((i13 & 2 | 0) != 0) {
+  i15 = 0;
+  STACKTOP = i2;
+  return i15 | 0;
+ }
+ i7 = (i13 & -8) + i8 | 0;
+ if (i7 >>> 0 < i3 >>> 0) {
+  i15 = 0;
+  STACKTOP = i2;
+  return i15 | 0;
+ }
+ i6 = i7 - i3 | 0;
+ i12 = i13 >>> 3;
+ do {
+  if (!(i13 >>> 0 < 256)) {
+   i11 = HEAP32[i1 + (i8 + 24) >> 2] | 0;
+   i13 = HEAP32[i1 + (i8 + 12) >> 2] | 0;
+   do {
+    if ((i13 | 0) == (i5 | 0)) {
+     i13 = i1 + (i8 + 20) | 0;
+     i12 = HEAP32[i13 >> 2] | 0;
+     if ((i12 | 0) == 0) {
+      i13 = i1 + (i8 + 16) | 0;
+      i12 = HEAP32[i13 >> 2] | 0;
+      if ((i12 | 0) == 0) {
+       i9 = 0;
+       break;
+      }
+     }
+     while (1) {
+      i15 = i12 + 20 | 0;
+      i14 = HEAP32[i15 >> 2] | 0;
+      if ((i14 | 0) != 0) {
+       i12 = i14;
+       i13 = i15;
+       continue;
+      }
+      i15 = i12 + 16 | 0;
+      i14 = HEAP32[i15 >> 2] | 0;
+      if ((i14 | 0) == 0) {
+       break;
+      } else {
+       i12 = i14;
+       i13 = i15;
+      }
+     }
+     if (i13 >>> 0 < i10 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i13 >> 2] = 0;
+      i9 = i12;
+      break;
+     }
+    } else {
+     i12 = HEAP32[i1 + (i8 + 8) >> 2] | 0;
+     if (i12 >>> 0 < i10 >>> 0) {
+      _abort();
+     }
+     i14 = i12 + 12 | 0;
+     if ((HEAP32[i14 >> 2] | 0) != (i5 | 0)) {
+      _abort();
+     }
+     i10 = i13 + 8 | 0;
+     if ((HEAP32[i10 >> 2] | 0) == (i5 | 0)) {
+      HEAP32[i14 >> 2] = i13;
+      HEAP32[i10 >> 2] = i12;
+      i9 = i13;
+      break;
+     } else {
+      _abort();
+     }
+    }
+   } while (0);
+   if ((i11 | 0) != 0) {
+    i10 = HEAP32[i1 + (i8 + 28) >> 2] | 0;
+    i12 = 13216 + (i10 << 2) | 0;
+    if ((i5 | 0) == (HEAP32[i12 >> 2] | 0)) {
+     HEAP32[i12 >> 2] = i9;
+     if ((i9 | 0) == 0) {
+      HEAP32[12916 >> 2] = HEAP32[12916 >> 2] & ~(1 << i10);
+      break;
+     }
+    } else {
+     if (i11 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i10 = i11 + 16 | 0;
+     if ((HEAP32[i10 >> 2] | 0) == (i5 | 0)) {
+      HEAP32[i10 >> 2] = i9;
+     } else {
+      HEAP32[i11 + 20 >> 2] = i9;
+     }
+     if ((i9 | 0) == 0) {
+      break;
+     }
+    }
+    if (i9 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+     _abort();
+    }
+    HEAP32[i9 + 24 >> 2] = i11;
+    i5 = HEAP32[i1 + (i8 + 16) >> 2] | 0;
+    do {
+     if ((i5 | 0) != 0) {
+      if (i5 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i9 + 16 >> 2] = i5;
+       HEAP32[i5 + 24 >> 2] = i9;
+       break;
+      }
+     }
+    } while (0);
+    i5 = HEAP32[i1 + (i8 + 20) >> 2] | 0;
+    if ((i5 | 0) != 0) {
+     if (i5 >>> 0 < (HEAP32[12928 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i9 + 20 >> 2] = i5;
+      HEAP32[i5 + 24 >> 2] = i9;
+      break;
+     }
+    }
+   }
+  } else {
+   i9 = HEAP32[i1 + (i8 + 8) >> 2] | 0;
+   i8 = HEAP32[i1 + (i8 + 12) >> 2] | 0;
+   i13 = 12952 + (i12 << 1 << 2) | 0;
+   if ((i9 | 0) != (i13 | 0)) {
+    if (i9 >>> 0 < i10 >>> 0) {
+     _abort();
+    }
+    if ((HEAP32[i9 + 12 >> 2] | 0) != (i5 | 0)) {
+     _abort();
+    }
+   }
+   if ((i8 | 0) == (i9 | 0)) {
+    HEAP32[3228] = HEAP32[3228] & ~(1 << i12);
+    break;
+   }
+   if ((i8 | 0) != (i13 | 0)) {
+    if (i8 >>> 0 < i10 >>> 0) {
+     _abort();
+    }
+    i10 = i8 + 8 | 0;
+    if ((HEAP32[i10 >> 2] | 0) == (i5 | 0)) {
+     i11 = i10;
+    } else {
+     _abort();
+    }
+   } else {
+    i11 = i8 + 8 | 0;
+   }
+   HEAP32[i9 + 12 >> 2] = i8;
+   HEAP32[i11 >> 2] = i9;
+  }
+ } while (0);
+ if (i6 >>> 0 < 16) {
+  HEAP32[i4 >> 2] = i7 | HEAP32[i4 >> 2] & 1 | 2;
+  i15 = i1 + (i7 | 4) | 0;
+  HEAP32[i15 >> 2] = HEAP32[i15 >> 2] | 1;
+  i15 = i1;
+  STACKTOP = i2;
+  return i15 | 0;
+ } else {
+  HEAP32[i4 >> 2] = HEAP32[i4 >> 2] & 1 | i3 | 2;
+  HEAP32[i1 + (i3 + 4) >> 2] = i6 | 3;
+  i15 = i1 + (i7 | 4) | 0;
+  HEAP32[i15 >> 2] = HEAP32[i15 >> 2] | 1;
+  _dispose_chunk(i1 + i3 | 0, i6);
+  i15 = i1;
+  STACKTOP = i2;
+  return i15 | 0;
+ }
+ return 0;
+}
+function _luaK_posfix(i3, i16, i1, i4, i14) {
+ i3 = i3 | 0;
+ i16 = i16 | 0;
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i14 = i14 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i15 = 0;
+ i2 = STACKTOP;
+ switch (i16 | 0) {
+ case 14:
+  {
+   _luaK_dischargevars(i3, i4);
+   i6 = i4 + 16 | 0;
+   i5 = HEAP32[i1 + 16 >> 2] | 0;
+   do {
+    if (!((i5 | 0) == -1)) {
+     i9 = HEAP32[i6 >> 2] | 0;
+     if ((i9 | 0) == -1) {
+      HEAP32[i6 >> 2] = i5;
+      break;
+     }
+     i7 = HEAP32[(HEAP32[i3 >> 2] | 0) + 12 >> 2] | 0;
+     while (1) {
+      i6 = i7 + (i9 << 2) | 0;
+      i8 = HEAP32[i6 >> 2] | 0;
+      i10 = (i8 >>> 14) + -131071 | 0;
+      if ((i10 | 0) == -1) {
+       break;
+      }
+      i10 = i9 + 1 + i10 | 0;
+      if ((i10 | 0) == -1) {
+       break;
+      } else {
+       i9 = i10;
+      }
+     }
+     i5 = i5 + ~i9 | 0;
+     if ((((i5 | 0) > -1 ? i5 : 0 - i5 | 0) | 0) > 131071) {
+      _luaX_syntaxerror(HEAP32[i3 + 12 >> 2] | 0, 10624);
+     } else {
+      HEAP32[i6 >> 2] = (i5 << 14) + 2147467264 | i8 & 16383;
+      break;
+     }
+    }
+   } while (0);
+   HEAP32[i1 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+   HEAP32[i1 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+   HEAP32[i1 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+   HEAP32[i1 + 12 >> 2] = HEAP32[i4 + 12 >> 2];
+   HEAP32[i1 + 16 >> 2] = HEAP32[i4 + 16 >> 2];
+   HEAP32[i1 + 20 >> 2] = HEAP32[i4 + 20 >> 2];
+   STACKTOP = i2;
+   return;
+  }
+ case 13:
+  {
+   _luaK_dischargevars(i3, i4);
+   i6 = i4 + 20 | 0;
+   i5 = HEAP32[i1 + 20 >> 2] | 0;
+   do {
+    if (!((i5 | 0) == -1)) {
+     i9 = HEAP32[i6 >> 2] | 0;
+     if ((i9 | 0) == -1) {
+      HEAP32[i6 >> 2] = i5;
+      break;
+     }
+     i7 = HEAP32[(HEAP32[i3 >> 2] | 0) + 12 >> 2] | 0;
+     while (1) {
+      i8 = i7 + (i9 << 2) | 0;
+      i6 = HEAP32[i8 >> 2] | 0;
+      i10 = (i6 >>> 14) + -131071 | 0;
+      if ((i10 | 0) == -1) {
+       break;
+      }
+      i10 = i9 + 1 + i10 | 0;
+      if ((i10 | 0) == -1) {
+       break;
+      } else {
+       i9 = i10;
+      }
+     }
+     i5 = i5 + ~i9 | 0;
+     if ((((i5 | 0) > -1 ? i5 : 0 - i5 | 0) | 0) > 131071) {
+      _luaX_syntaxerror(HEAP32[i3 + 12 >> 2] | 0, 10624);
+     } else {
+      HEAP32[i8 >> 2] = (i5 << 14) + 2147467264 | i6 & 16383;
+      break;
+     }
+    }
+   } while (0);
+   HEAP32[i1 + 0 >> 2] = HEAP32[i4 + 0 >> 2];
+   HEAP32[i1 + 4 >> 2] = HEAP32[i4 + 4 >> 2];
+   HEAP32[i1 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+   HEAP32[i1 + 12 >> 2] = HEAP32[i4 + 12 >> 2];
+   HEAP32[i1 + 16 >> 2] = HEAP32[i4 + 16 >> 2];
+   HEAP32[i1 + 20 >> 2] = HEAP32[i4 + 20 >> 2];
+   STACKTOP = i2;
+   return;
+  }
+ case 6:
+  {
+   i12 = i4 + 16 | 0;
+   i13 = i4 + 20 | 0;
+   i16 = (HEAP32[i12 >> 2] | 0) == (HEAP32[i13 >> 2] | 0);
+   _luaK_dischargevars(i3, i4);
+   do {
+    if (!i16) {
+     if ((HEAP32[i4 >> 2] | 0) == 6) {
+      i10 = HEAP32[i4 + 8 >> 2] | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (HEAP32[i13 >> 2] | 0)) {
+       break;
+      }
+      if ((i10 | 0) >= (HEAPU8[i3 + 46 | 0] | 0 | 0)) {
+       _exp2reg(i3, i4, i10);
+       break;
+      }
+     }
+     _luaK_exp2nextreg(i3, i4);
+    }
+   } while (0);
+   if ((HEAP32[i4 >> 2] | 0) == 11 ? (i5 = i4 + 8 | 0, i7 = HEAP32[i5 >> 2] | 0, i8 = (HEAP32[i3 >> 2] | 0) + 12 | 0, i9 = HEAP32[i8 >> 2] | 0, i6 = HEAP32[i9 + (i7 << 2) >> 2] | 0, (i6 & 63 | 0) == 22) : 0) {
+    i4 = i1 + 8 | 0;
+    if (((HEAP32[i1 >> 2] | 0) == 6 ? (i11 = HEAP32[i4 >> 2] | 0, (i11 & 256 | 0) == 0) : 0) ? (HEAPU8[i3 + 46 | 0] | 0 | 0) <= (i11 | 0) : 0) {
+     i6 = i3 + 48 | 0;
+     HEAP8[i6] = (HEAP8[i6] | 0) + -1 << 24 >> 24;
+     i6 = HEAP32[i5 >> 2] | 0;
+     i16 = HEAP32[i8 >> 2] | 0;
+     i9 = i16;
+     i7 = i6;
+     i6 = HEAP32[i16 + (i6 << 2) >> 2] | 0;
+    }
+    HEAP32[i9 + (i7 << 2) >> 2] = HEAP32[i4 >> 2] << 23 | i6 & 8388607;
+    HEAP32[i1 >> 2] = 11;
+    HEAP32[i4 >> 2] = HEAP32[i5 >> 2];
+    STACKTOP = i2;
+    return;
+   }
+   _luaK_exp2nextreg(i3, i4);
+   _codearith(i3, 22, i1, i4, i14);
+   STACKTOP = i2;
+   return;
+  }
+ case 9:
+ case 8:
+ case 7:
+  {
+   i7 = i16 + 17 | 0;
+   i6 = _luaK_exp2RK(i3, i1) | 0;
+   i5 = _luaK_exp2RK(i3, i4) | 0;
+   if (((HEAP32[i4 >> 2] | 0) == 6 ? (i15 = HEAP32[i4 + 8 >> 2] | 0, (i15 & 256 | 0) == 0) : 0) ? (HEAPU8[i3 + 46 | 0] | 0 | 0) <= (i15 | 0) : 0) {
+    i16 = i3 + 48 | 0;
+    HEAP8[i16] = (HEAP8[i16] | 0) + -1 << 24 >> 24;
+   }
+   i4 = i1 + 8 | 0;
+   if (((HEAP32[i1 >> 2] | 0) == 6 ? (i10 = HEAP32[i4 >> 2] | 0, (i10 & 256 | 0) == 0) : 0) ? (HEAPU8[i3 + 46 | 0] | 0 | 0) <= (i10 | 0) : 0) {
+    i16 = i3 + 48 | 0;
+    HEAP8[i16] = (HEAP8[i16] | 0) + -1 << 24 >> 24;
+   }
+   HEAP32[i4 >> 2] = _condjump(i3, i7, 1, i6, i5) | 0;
+   HEAP32[i1 >> 2] = 10;
+   STACKTOP = i2;
+   return;
+  }
+ case 12:
+ case 11:
+ case 10:
+  {
+   i7 = i16 + 14 | 0;
+   i6 = _luaK_exp2RK(i3, i1) | 0;
+   i5 = _luaK_exp2RK(i3, i4) | 0;
+   if (((HEAP32[i4 >> 2] | 0) == 6 ? (i13 = HEAP32[i4 + 8 >> 2] | 0, (i13 & 256 | 0) == 0) : 0) ? (HEAPU8[i3 + 46 | 0] | 0 | 0) <= (i13 | 0) : 0) {
+    i16 = i3 + 48 | 0;
+    HEAP8[i16] = (HEAP8[i16] | 0) + -1 << 24 >> 24;
+   }
+   i4 = i1 + 8 | 0;
+   if (((HEAP32[i1 >> 2] | 0) == 6 ? (i12 = HEAP32[i4 >> 2] | 0, (i12 & 256 | 0) == 0) : 0) ? (HEAPU8[i3 + 46 | 0] | 0 | 0) <= (i12 | 0) : 0) {
+    i16 = i3 + 48 | 0;
+    HEAP8[i16] = (HEAP8[i16] | 0) + -1 << 24 >> 24;
+   }
+   i8 = (i7 | 0) == 24;
+   HEAP32[i4 >> 2] = _condjump(i3, i7, i8 & 1 ^ 1, i8 ? i6 : i5, i8 ? i5 : i6) | 0;
+   HEAP32[i1 >> 2] = 10;
+   STACKTOP = i2;
+   return;
+  }
+ case 5:
+ case 4:
+ case 3:
+ case 2:
+ case 1:
+ case 0:
+  {
+   _codearith(i3, i16 + 13 | 0, i1, i4, i14);
+   STACKTOP = i2;
+   return;
+  }
+ default:
+  {
+   STACKTOP = i2;
+   return;
+  }
+ }
+}
+function _body(i1, i4, i13, i5) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i13 = i13 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0;
+ i6 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i3 = i6 + 12 | 0;
+ i14 = i6;
+ i2 = i1 + 48 | 0;
+ i19 = HEAP32[i2 >> 2] | 0;
+ i18 = i1 + 52 | 0;
+ i17 = HEAP32[i18 >> 2] | 0;
+ i16 = HEAP32[i19 >> 2] | 0;
+ i19 = i19 + 36 | 0;
+ i23 = i16 + 56 | 0;
+ i24 = HEAP32[i23 >> 2] | 0;
+ i15 = i16 + 16 | 0;
+ if (((HEAP32[i19 >> 2] | 0) >= (i24 | 0) ? (i21 = _luaM_growaux_(i17, HEAP32[i15 >> 2] | 0, i23, 4, 262143, 6512) | 0, HEAP32[i15 >> 2] = i21, i20 = HEAP32[i23 >> 2] | 0, (i24 | 0) < (i20 | 0)) : 0) ? (i22 = i24 + 1 | 0, HEAP32[i21 + (i24 << 2) >> 2] = 0, (i22 | 0) < (i20 | 0)) : 0) {
+  while (1) {
+   i21 = i22 + 1 | 0;
+   HEAP32[(HEAP32[i15 >> 2] | 0) + (i22 << 2) >> 2] = 0;
+   if ((i21 | 0) == (i20 | 0)) {
+    break;
+   } else {
+    i22 = i21;
+   }
+  }
+ }
+ i20 = _luaF_newproto(i17) | 0;
+ i24 = HEAP32[i19 >> 2] | 0;
+ HEAP32[i19 >> 2] = i24 + 1;
+ HEAP32[(HEAP32[i15 >> 2] | 0) + (i24 << 2) >> 2] = i20;
+ if (!((HEAP8[i20 + 5 | 0] & 3) == 0) ? !((HEAP8[i16 + 5 | 0] & 4) == 0) : 0) {
+  _luaC_barrier_(i17, i16, i20);
+ }
+ HEAP32[i3 >> 2] = i20;
+ HEAP32[i20 + 64 >> 2] = i5;
+ i16 = HEAP32[i18 >> 2] | 0;
+ HEAP32[i3 + 8 >> 2] = HEAP32[i2 >> 2];
+ i17 = i3 + 12 | 0;
+ HEAP32[i17 >> 2] = i1;
+ HEAP32[i2 >> 2] = i3;
+ HEAP32[i3 + 20 >> 2] = 0;
+ HEAP32[i3 + 24 >> 2] = 0;
+ HEAP32[i3 + 28 >> 2] = -1;
+ HEAP32[i3 + 32 >> 2] = 0;
+ HEAP32[i3 + 36 >> 2] = 0;
+ i22 = i3 + 44 | 0;
+ i15 = i1 + 64 | 0;
+ HEAP32[i22 + 0 >> 2] = 0;
+ HEAP8[i22 + 4 | 0] = 0;
+ HEAP32[i3 + 40 >> 2] = HEAP32[(HEAP32[i15 >> 2] | 0) + 4 >> 2];
+ i15 = i3 + 16 | 0;
+ HEAP32[i15 >> 2] = 0;
+ HEAP32[i20 + 36 >> 2] = HEAP32[i1 + 68 >> 2];
+ HEAP8[i20 + 78 | 0] = 2;
+ i22 = _luaH_new(i16) | 0;
+ HEAP32[i3 + 4 >> 2] = i22;
+ i23 = i16 + 8 | 0;
+ i24 = HEAP32[i23 >> 2] | 0;
+ HEAP32[i24 >> 2] = i22;
+ HEAP32[i24 + 8 >> 2] = 69;
+ i24 = (HEAP32[i23 >> 2] | 0) + 16 | 0;
+ HEAP32[i23 >> 2] = i24;
+ if (((HEAP32[i16 + 24 >> 2] | 0) - i24 | 0) < 16) {
+  _luaD_growstack(i16, 0);
+ }
+ HEAP8[i14 + 10 | 0] = 0;
+ HEAP8[i14 + 8 | 0] = HEAP8[i3 + 46 | 0] | 0;
+ i24 = HEAP32[(HEAP32[i17 >> 2] | 0) + 64 >> 2] | 0;
+ HEAP16[i14 + 4 >> 1] = HEAP32[i24 + 28 >> 2];
+ HEAP16[i14 + 6 >> 1] = HEAP32[i24 + 16 >> 2];
+ HEAP8[i14 + 9 | 0] = 0;
+ HEAP32[i14 >> 2] = HEAP32[i15 >> 2];
+ HEAP32[i15 >> 2] = i14;
+ i14 = i1 + 16 | 0;
+ if ((HEAP32[i14 >> 2] | 0) != 40) {
+  _error_expected(i1, 40);
+ }
+ _luaX_next(i1);
+ if ((i13 | 0) != 0) {
+  _new_localvar(i1, _luaX_newstring(i1, 6456, 4) | 0);
+  i24 = HEAP32[i2 >> 2] | 0;
+  i22 = i24 + 46 | 0;
+  i23 = (HEAPU8[i22] | 0) + 1 | 0;
+  HEAP8[i22] = i23;
+  HEAP32[(HEAP32[(HEAP32[i24 >> 2] | 0) + 24 >> 2] | 0) + ((HEAP16[(HEAP32[HEAP32[(HEAP32[i24 + 12 >> 2] | 0) + 64 >> 2] >> 2] | 0) + ((i23 & 255) + -1 + (HEAP32[i24 + 40 >> 2] | 0) << 1) >> 1] | 0) * 12 | 0) + 4 >> 2] = HEAP32[i24 + 20 >> 2];
+ }
+ i13 = HEAP32[i2 >> 2] | 0;
+ i15 = HEAP32[i13 >> 2] | 0;
+ i16 = i15 + 77 | 0;
+ HEAP8[i16] = 0;
+ i19 = HEAP32[i14 >> 2] | 0;
+ L20 : do {
+  if ((i19 | 0) != 41) {
+   i17 = i1 + 24 | 0;
+   i18 = 0;
+   while (1) {
+    if ((i19 | 0) == 280) {
+     i17 = 18;
+     break;
+    } else if ((i19 | 0) != 288) {
+     i17 = 19;
+     break;
+    }
+    i24 = HEAP32[i17 >> 2] | 0;
+    _luaX_next(i1);
+    _new_localvar(i1, i24);
+    i18 = i18 + 1 | 0;
+    if ((HEAP8[i16] | 0) != 0) {
+     i11 = i18;
+     break L20;
+    }
+    if ((HEAP32[i14 >> 2] | 0) != 44) {
+     i11 = i18;
+     break L20;
+    }
+    _luaX_next(i1);
+    i19 = HEAP32[i14 >> 2] | 0;
+   }
+   if ((i17 | 0) == 18) {
+    _luaX_next(i1);
+    HEAP8[i16] = 1;
+    i11 = i18;
+    break;
+   } else if ((i17 | 0) == 19) {
+    _luaX_syntaxerror(i1, 6464);
+   }
+  } else {
+   i11 = 0;
+  }
+ } while (0);
+ i18 = HEAP32[i2 >> 2] | 0;
+ i16 = i18 + 46 | 0;
+ i17 = (HEAPU8[i16] | 0) + i11 | 0;
+ HEAP8[i16] = i17;
+ if ((i11 | 0) != 0 ? (i8 = i18 + 20 | 0, i9 = i18 + 40 | 0, i7 = HEAP32[(HEAP32[i18 >> 2] | 0) + 24 >> 2] | 0, i10 = HEAP32[HEAP32[(HEAP32[i18 + 12 >> 2] | 0) + 64 >> 2] >> 2] | 0, HEAP32[i7 + ((HEAP16[i10 + ((i17 & 255) - i11 + (HEAP32[i9 >> 2] | 0) << 1) >> 1] | 0) * 12 | 0) + 4 >> 2] = HEAP32[i8 >> 2], i12 = i11 + -1 | 0, (i12 | 0) != 0) : 0) {
+  do {
+   HEAP32[i7 + ((HEAP16[i10 + ((HEAPU8[i16] | 0) - i12 + (HEAP32[i9 >> 2] | 0) << 1) >> 1] | 0) * 12 | 0) + 4 >> 2] = HEAP32[i8 >> 2];
+   i12 = i12 + -1 | 0;
+  } while ((i12 | 0) != 0);
+ }
+ i24 = i13 + 46 | 0;
+ HEAP8[i15 + 76 | 0] = HEAP8[i24] | 0;
+ _luaK_reserveregs(i13, HEAPU8[i24] | 0);
+ if ((HEAP32[i14 >> 2] | 0) != 41) {
+  _error_expected(i1, 41);
+ }
+ _luaX_next(i1);
+ L39 : while (1) {
+  i7 = HEAP32[i14 >> 2] | 0;
+  switch (i7 | 0) {
+  case 277:
+  case 286:
+  case 262:
+  case 261:
+  case 260:
+   {
+    i17 = 30;
+    break L39;
+   }
+  default:
+   {}
+  }
+  _statement(i1);
+  if ((i7 | 0) == 274) {
+   i17 = 30;
+   break;
+  }
+ }
+ if ((i17 | 0) == 30) {
+  HEAP32[(HEAP32[i3 >> 2] | 0) + 68 >> 2] = HEAP32[i1 + 4 >> 2];
+  _check_match(i1, 262, 265, i5);
+  i24 = HEAP32[(HEAP32[i2 >> 2] | 0) + 8 >> 2] | 0;
+  i23 = _luaK_codeABx(i24, 37, 0, (HEAP32[i24 + 36 >> 2] | 0) + -1 | 0) | 0;
+  HEAP32[i4 + 16 >> 2] = -1;
+  HEAP32[i4 + 20 >> 2] = -1;
+  HEAP32[i4 >> 2] = 11;
+  HEAP32[i4 + 8 >> 2] = i23;
+  _luaK_exp2nextreg(i24, i4);
+  _close_func(i1);
+  STACKTOP = i6;
+  return;
+ }
+}
+function _luaH_newkey(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, d21 = 0.0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 144 | 0;
+ i8 = i4 + 8 | 0;
+ i10 = i4;
+ i5 = i4 + 16 | 0;
+ i6 = i1 + 8 | 0;
+ i11 = HEAP32[i6 >> 2] | 0;
+ if ((i11 | 0) == 0) {
+  _luaG_runerror(i3, 7968, i8);
+ } else if ((i11 | 0) == 3) {
+  i15 = 3;
+ }
+ if ((i15 | 0) == 3 ? (d21 = +HEAPF64[i1 >> 3], !(d21 == d21 & 0.0 == 0.0)) : 0) {
+  _luaG_runerror(i3, 7992, i8);
+ }
+ i13 = _mainposition(i2, i1) | 0;
+ i14 = i13 + 8 | 0;
+ do {
+  if ((HEAP32[i14 >> 2] | 0) != 0 | (i13 | 0) == 8016) {
+   i18 = i2 + 20 | 0;
+   i11 = i2 + 16 | 0;
+   i17 = HEAP32[i11 >> 2] | 0;
+   i16 = HEAP32[i18 >> 2] | 0;
+   while (1) {
+    if (!(i16 >>> 0 > i17 >>> 0)) {
+     break;
+    }
+    i12 = i16 + -32 | 0;
+    HEAP32[i18 >> 2] = i12;
+    if ((HEAP32[i16 + -8 >> 2] | 0) == 0) {
+     i15 = 37;
+     break;
+    } else {
+     i16 = i12;
+    }
+   }
+   if ((i15 | 0) == 37) {
+    i5 = _mainposition(i2, i13 + 16 | 0) | 0;
+    if ((i5 | 0) == (i13 | 0)) {
+     i20 = i13 + 28 | 0;
+     HEAP32[i16 + -4 >> 2] = HEAP32[i20 >> 2];
+     HEAP32[i20 >> 2] = i12;
+     break;
+    } else {
+     i7 = i5;
+    }
+    do {
+     i5 = i7 + 28 | 0;
+     i7 = HEAP32[i5 >> 2] | 0;
+    } while ((i7 | 0) != (i13 | 0));
+    HEAP32[i5 >> 2] = i12;
+    HEAP32[i12 + 0 >> 2] = HEAP32[i13 + 0 >> 2];
+    HEAP32[i12 + 4 >> 2] = HEAP32[i13 + 4 >> 2];
+    HEAP32[i12 + 8 >> 2] = HEAP32[i13 + 8 >> 2];
+    HEAP32[i12 + 12 >> 2] = HEAP32[i13 + 12 >> 2];
+    HEAP32[i12 + 16 >> 2] = HEAP32[i13 + 16 >> 2];
+    HEAP32[i12 + 20 >> 2] = HEAP32[i13 + 20 >> 2];
+    HEAP32[i12 + 24 >> 2] = HEAP32[i13 + 24 >> 2];
+    HEAP32[i12 + 28 >> 2] = HEAP32[i13 + 28 >> 2];
+    HEAP32[i13 + 28 >> 2] = 0;
+    HEAP32[i14 >> 2] = 0;
+    i12 = i13;
+    break;
+   }
+   i13 = i5 + 0 | 0;
+   i12 = i13 + 124 | 0;
+   do {
+    HEAP32[i13 >> 2] = 0;
+    i13 = i13 + 4 | 0;
+   } while ((i13 | 0) < (i12 | 0));
+   i15 = i2 + 12 | 0;
+   i13 = HEAP32[i2 + 28 >> 2] | 0;
+   i12 = 0;
+   i20 = 1;
+   i16 = 0;
+   i14 = 1;
+   while (1) {
+    if ((i14 | 0) > (i13 | 0)) {
+     if ((i20 | 0) > (i13 | 0)) {
+      break;
+     } else {
+      i19 = i13;
+     }
+    } else {
+     i19 = i14;
+    }
+    if ((i20 | 0) > (i19 | 0)) {
+     i18 = i20;
+     i17 = 0;
+    } else {
+     i18 = HEAP32[i15 >> 2] | 0;
+     i17 = 0;
+     while (1) {
+      i17 = ((HEAP32[i18 + (i20 + -1 << 4) + 8 >> 2] | 0) != 0) + i17 | 0;
+      if ((i20 | 0) >= (i19 | 0)) {
+       break;
+      } else {
+       i20 = i20 + 1 | 0;
+      }
+     }
+     i18 = i19 + 1 | 0;
+    }
+    i20 = i5 + (i16 << 2) | 0;
+    HEAP32[i20 >> 2] = (HEAP32[i20 >> 2] | 0) + i17;
+    i12 = i17 + i12 | 0;
+    i16 = i16 + 1 | 0;
+    if ((i16 | 0) < 31) {
+     i20 = i18;
+     i14 = i14 << 1;
+    } else {
+     break;
+    }
+   }
+   i14 = 0;
+   i15 = 1 << (HEAPU8[i2 + 7 | 0] | 0);
+   i13 = 0;
+   L32 : while (1) {
+    i16 = i15;
+    while (1) {
+     i15 = i16 + -1 | 0;
+     if ((i16 | 0) == 0) {
+      break L32;
+     }
+     i16 = HEAP32[i11 >> 2] | 0;
+     if ((HEAP32[i16 + (i15 << 5) + 8 >> 2] | 0) == 0) {
+      i16 = i15;
+     } else {
+      break;
+     }
+    }
+    if (((HEAP32[i16 + (i15 << 5) + 24 >> 2] | 0) == 3 ? (d21 = +HEAPF64[i16 + (i15 << 5) + 16 >> 3], HEAPF64[i10 >> 3] = d21 + 6755399441055744.0, i9 = HEAP32[i10 >> 2] | 0, +(i9 | 0) == d21) : 0) ? (i9 + -1 | 0) >>> 0 < 1073741824 : 0) {
+     i16 = i5 + ((_luaO_ceillog2(i9) | 0) << 2) | 0;
+     HEAP32[i16 >> 2] = (HEAP32[i16 >> 2] | 0) + 1;
+     i16 = 1;
+    } else {
+     i16 = 0;
+    }
+    i14 = i16 + i14 | 0;
+    i13 = i13 + 1 | 0;
+   }
+   i9 = i14 + i12 | 0;
+   if (((HEAP32[i6 >> 2] | 0) == 3 ? (d21 = +HEAPF64[i1 >> 3], HEAPF64[i8 >> 3] = d21 + 6755399441055744.0, i7 = HEAP32[i8 >> 2] | 0, +(i7 | 0) == d21) : 0) ? (i7 + -1 | 0) >>> 0 < 1073741824 : 0) {
+    i6 = i5 + ((_luaO_ceillog2(i7) | 0) << 2) | 0;
+    HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + 1;
+    i6 = 1;
+   } else {
+    i6 = 0;
+   }
+   i7 = i9 + i6 | 0;
+   L49 : do {
+    if ((i7 | 0) > 0) {
+     i14 = 0;
+     i10 = 0;
+     i6 = 0;
+     i8 = 0;
+     i11 = 0;
+     i9 = 1;
+     while (1) {
+      i15 = HEAP32[i5 + (i6 << 2) >> 2] | 0;
+      if ((i15 | 0) > 0) {
+       i15 = i15 + i10 | 0;
+       i14 = (i15 | 0) > (i14 | 0);
+       i10 = i15;
+       i8 = i14 ? i9 : i8;
+       i11 = i14 ? i15 : i11;
+      }
+      if ((i10 | 0) == (i7 | 0)) {
+       break L49;
+      }
+      i9 = i9 << 1;
+      i14 = (i9 | 0) / 2 | 0;
+      if ((i14 | 0) < (i7 | 0)) {
+       i6 = i6 + 1 | 0;
+      } else {
+       break;
+      }
+     }
+    } else {
+     i8 = 0;
+     i11 = 0;
+    }
+   } while (0);
+   _luaH_resize(i3, i2, i8, i12 + 1 + i13 - i11 | 0);
+   i5 = _luaH_get(i2, i1) | 0;
+   if ((i5 | 0) != 5192) {
+    i20 = i5;
+    STACKTOP = i4;
+    return i20 | 0;
+   }
+   i20 = _luaH_newkey(i3, i2, i1) | 0;
+   STACKTOP = i4;
+   return i20 | 0;
+  } else {
+   i12 = i13;
+  }
+ } while (0);
+ i18 = i1;
+ i19 = HEAP32[i18 + 4 >> 2] | 0;
+ i20 = i12 + 16 | 0;
+ HEAP32[i20 >> 2] = HEAP32[i18 >> 2];
+ HEAP32[i20 + 4 >> 2] = i19;
+ HEAP32[i12 + 24 >> 2] = HEAP32[i6 >> 2];
+ if (((HEAP32[i6 >> 2] & 64 | 0) != 0 ? !((HEAP8[(HEAP32[i1 >> 2] | 0) + 5 | 0] & 3) == 0) : 0) ? !((HEAP8[i2 + 5 | 0] & 4) == 0) : 0) {
+  _luaC_barrierback_(i3, i2);
+ }
+ i20 = i12;
+ STACKTOP = i4;
+ return i20 | 0;
+}
+function _luaV_concat(i7, i10) {
+ i7 = i7 | 0;
+ i10 = i10 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0;
+ i5 = STACKTOP;
+ STACKTOP = STACKTOP + 48 | 0;
+ i9 = i5;
+ i8 = i5 + 8 | 0;
+ i6 = i7 + 8 | 0;
+ i2 = i7 + 12 | 0;
+ i3 = i7 + 28 | 0;
+ i4 = i7 + 16 | 0;
+ i11 = HEAP32[i6 >> 2] | 0;
+ L1 : while (1) {
+  i14 = i11 + -32 | 0;
+  i12 = i11 + -24 | 0;
+  i17 = HEAP32[i12 >> 2] | 0;
+  i13 = i11 + -16 | 0;
+  do {
+   if ((i17 & 15 | 0) == 4 | (i17 | 0) == 3) {
+    i15 = i11 + -8 | 0;
+    i16 = HEAP32[i15 >> 2] | 0;
+    if ((i16 & 15 | 0) == 4) {
+     i16 = i13;
+    } else {
+     if ((i16 | 0) != 3) {
+      i1 = 7;
+      break;
+     }
+     HEAPF64[tempDoublePtr >> 3] = +HEAPF64[i13 >> 3];
+     HEAP32[i9 >> 2] = HEAP32[tempDoublePtr >> 2];
+     HEAP32[i9 + 4 >> 2] = HEAP32[tempDoublePtr + 4 >> 2];
+     i16 = _luaS_newlstr(i7, i8, _sprintf(i8 | 0, 8936, i9 | 0) | 0) | 0;
+     HEAP32[i13 >> 2] = i16;
+     HEAP32[i15 >> 2] = HEAPU8[i16 + 4 | 0] | 0 | 64;
+     i16 = i13;
+     i17 = HEAP32[i12 >> 2] | 0;
+    }
+    i16 = HEAP32[(HEAP32[i16 >> 2] | 0) + 12 >> 2] | 0;
+    i18 = (i17 & 15 | 0) == 4;
+    if ((i16 | 0) == 0) {
+     if (i18) {
+      i12 = 2;
+      break;
+     }
+     if ((i17 | 0) != 3) {
+      i12 = 2;
+      break;
+     }
+     HEAPF64[tempDoublePtr >> 3] = +HEAPF64[i14 >> 3];
+     HEAP32[i9 >> 2] = HEAP32[tempDoublePtr >> 2];
+     HEAP32[i9 + 4 >> 2] = HEAP32[tempDoublePtr + 4 >> 2];
+     i18 = _luaS_newlstr(i7, i8, _sprintf(i8 | 0, 8936, i9 | 0) | 0) | 0;
+     HEAP32[i14 >> 2] = i18;
+     HEAP32[i12 >> 2] = HEAPU8[i18 + 4 | 0] | 0 | 64;
+     i12 = 2;
+     break;
+    }
+    if (i18 ? (HEAP32[(HEAP32[i14 >> 2] | 0) + 12 >> 2] | 0) == 0 : 0) {
+     i16 = i13;
+     i17 = HEAP32[i16 + 4 >> 2] | 0;
+     i18 = i14;
+     HEAP32[i18 >> 2] = HEAP32[i16 >> 2];
+     HEAP32[i18 + 4 >> 2] = i17;
+     HEAP32[i12 >> 2] = HEAP32[i15 >> 2];
+     i12 = 2;
+     break;
+    }
+    L19 : do {
+     if ((i10 | 0) > 1) {
+      i12 = 1;
+      do {
+       i15 = ~i12;
+       i14 = i11 + (i15 << 4) | 0;
+       i15 = i11 + (i15 << 4) + 8 | 0;
+       i13 = HEAP32[i15 >> 2] | 0;
+       if ((i13 & 15 | 0) != 4) {
+        if ((i13 | 0) != 3) {
+         break L19;
+        }
+        HEAPF64[tempDoublePtr >> 3] = +HEAPF64[i14 >> 3];
+        HEAP32[i9 >> 2] = HEAP32[tempDoublePtr >> 2];
+        HEAP32[i9 + 4 >> 2] = HEAP32[tempDoublePtr + 4 >> 2];
+        i18 = _luaS_newlstr(i7, i8, _sprintf(i8 | 0, 8936, i9 | 0) | 0) | 0;
+        HEAP32[i14 >> 2] = i18;
+        HEAP32[i15 >> 2] = HEAPU8[i18 + 4 | 0] | 0 | 64;
+       }
+       i13 = HEAP32[(HEAP32[i14 >> 2] | 0) + 12 >> 2] | 0;
+       if (!(i13 >>> 0 < (-3 - i16 | 0) >>> 0)) {
+        i1 = 24;
+        break L1;
+       }
+       i16 = i13 + i16 | 0;
+       i12 = i12 + 1 | 0;
+      } while ((i12 | 0) < (i10 | 0));
+     } else {
+      i12 = 1;
+     }
+    } while (0);
+    i14 = _luaZ_openspace(i7, (HEAP32[i2 >> 2] | 0) + 144 | 0, i16) | 0;
+    i15 = i12;
+    i13 = 0;
+    do {
+     i17 = HEAP32[i11 + (0 - i15 << 4) >> 2] | 0;
+     i18 = HEAP32[i17 + 12 >> 2] | 0;
+     _memcpy(i14 + i13 | 0, i17 + 16 | 0, i18 | 0) | 0;
+     i13 = i18 + i13 | 0;
+     i15 = i15 + -1 | 0;
+    } while ((i15 | 0) > 0);
+    i18 = 0 - i12 | 0;
+    i17 = _luaS_newlstr(i7, i14, i13) | 0;
+    HEAP32[i11 + (i18 << 4) >> 2] = i17;
+    HEAP32[i11 + (i18 << 4) + 8 >> 2] = HEAPU8[i17 + 4 | 0] | 0 | 64;
+   } else {
+    i1 = 7;
+   }
+  } while (0);
+  if ((i1 | 0) == 7) {
+   i1 = 0;
+   i15 = _luaT_gettmbyobj(i7, i14, 15) | 0;
+   if ((HEAP32[i15 + 8 >> 2] | 0) == 0) {
+    i15 = _luaT_gettmbyobj(i7, i13, 15) | 0;
+    if ((HEAP32[i15 + 8 >> 2] | 0) == 0) {
+     i1 = 10;
+     break;
+    }
+   }
+   i18 = i14 - (HEAP32[i3 >> 2] | 0) | 0;
+   i16 = HEAP32[i6 >> 2] | 0;
+   HEAP32[i6 >> 2] = i16 + 16;
+   i20 = i15;
+   i19 = HEAP32[i20 + 4 >> 2] | 0;
+   i17 = i16;
+   HEAP32[i17 >> 2] = HEAP32[i20 >> 2];
+   HEAP32[i17 + 4 >> 2] = i19;
+   HEAP32[i16 + 8 >> 2] = HEAP32[i15 + 8 >> 2];
+   i15 = HEAP32[i6 >> 2] | 0;
+   HEAP32[i6 >> 2] = i15 + 16;
+   i16 = i14;
+   i17 = HEAP32[i16 + 4 >> 2] | 0;
+   i14 = i15;
+   HEAP32[i14 >> 2] = HEAP32[i16 >> 2];
+   HEAP32[i14 + 4 >> 2] = i17;
+   HEAP32[i15 + 8 >> 2] = HEAP32[i12 >> 2];
+   i12 = HEAP32[i6 >> 2] | 0;
+   HEAP32[i6 >> 2] = i12 + 16;
+   i15 = i13;
+   i14 = HEAP32[i15 + 4 >> 2] | 0;
+   i17 = i12;
+   HEAP32[i17 >> 2] = HEAP32[i15 >> 2];
+   HEAP32[i17 + 4 >> 2] = i14;
+   HEAP32[i12 + 8 >> 2] = HEAP32[i11 + -8 >> 2];
+   _luaD_call(i7, (HEAP32[i6 >> 2] | 0) + -48 | 0, 1, HEAP8[(HEAP32[i4 >> 2] | 0) + 18 | 0] & 1);
+   i12 = HEAP32[i3 >> 2] | 0;
+   i17 = HEAP32[i6 >> 2] | 0;
+   i14 = i17 + -16 | 0;
+   HEAP32[i6 >> 2] = i14;
+   i15 = HEAP32[i14 + 4 >> 2] | 0;
+   i16 = i12 + i18 | 0;
+   HEAP32[i16 >> 2] = HEAP32[i14 >> 2];
+   HEAP32[i16 + 4 >> 2] = i15;
+   HEAP32[i12 + (i18 + 8) >> 2] = HEAP32[i17 + -8 >> 2];
+   i12 = 2;
+  }
+  i10 = i10 + 1 - i12 | 0;
+  i11 = (HEAP32[i6 >> 2] | 0) + (1 - i12 << 4) | 0;
+  HEAP32[i6 >> 2] = i11;
+  if ((i10 | 0) <= 1) {
+   i1 = 30;
+   break;
+  }
+ }
+ if ((i1 | 0) == 10) {
+  _luaG_concaterror(i7, i14, i13);
+ } else if ((i1 | 0) == 24) {
+  _luaG_runerror(i7, 9e3, i9);
+ } else if ((i1 | 0) == 30) {
+  STACKTOP = i5;
+  return;
+ }
+}
+function _str_gsub(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 1344 | 0;
+ i4 = i3;
+ i5 = i3 + 1336 | 0;
+ i14 = i3 + 1332 | 0;
+ i10 = i3 + 1328 | 0;
+ i6 = i3 + 1048 | 0;
+ i2 = i3 + 8 | 0;
+ i20 = _luaL_checklstring(i1, 1, i14) | 0;
+ i13 = _luaL_checklstring(i1, 2, i10) | 0;
+ i8 = _lua_type(i1, 3) | 0;
+ i9 = _luaL_optinteger(i1, 4, (HEAP32[i14 >> 2] | 0) + 1 | 0) | 0;
+ i7 = (HEAP8[i13] | 0) == 94;
+ if (!((i8 + -3 | 0) >>> 0 < 2 | (i8 | 0) == 6 | (i8 | 0) == 5)) {
+  _luaL_argerror(i1, 3, 7528) | 0;
+ }
+ _luaL_buffinit(i1, i2);
+ if (i7) {
+  i15 = (HEAP32[i10 >> 2] | 0) + -1 | 0;
+  HEAP32[i10 >> 2] = i15;
+  i13 = i13 + 1 | 0;
+ } else {
+  i15 = HEAP32[i10 >> 2] | 0;
+ }
+ i11 = i6 + 16 | 0;
+ HEAP32[i11 >> 2] = i1;
+ HEAP32[i6 >> 2] = 200;
+ i12 = i6 + 4 | 0;
+ HEAP32[i12 >> 2] = i20;
+ i10 = i6 + 8 | 0;
+ HEAP32[i10 >> 2] = i20 + (HEAP32[i14 >> 2] | 0);
+ HEAP32[i6 + 12 >> 2] = i13 + i15;
+ i14 = i6 + 20 | 0;
+ i15 = i2 + 8 | 0;
+ i18 = i2 + 4 | 0;
+ i16 = i6 + 28 | 0;
+ i17 = i6 + 24 | 0;
+ i22 = 0;
+ while (1) {
+  if (!(i22 >>> 0 < i9 >>> 0)) {
+   i19 = 48;
+   break;
+  }
+  HEAP32[i14 >> 2] = 0;
+  i21 = _match(i6, i20, i13) | 0;
+  if ((i21 | 0) != 0) {
+   i22 = i22 + 1 | 0;
+   i23 = HEAP32[i11 >> 2] | 0;
+   if ((i8 | 0) == 5) {
+    do {
+     if ((HEAP32[i14 >> 2] | 0) > 0) {
+      i24 = HEAP32[i16 >> 2] | 0;
+      if (!((i24 | 0) == -1)) {
+       i25 = HEAP32[i17 >> 2] | 0;
+       if ((i24 | 0) == -2) {
+        _lua_pushinteger(i23, i25 + 1 - (HEAP32[i12 >> 2] | 0) | 0);
+        break;
+       } else {
+        i19 = i23;
+       }
+      } else {
+       _luaL_error(i23, 7248, i4) | 0;
+       i19 = HEAP32[i11 >> 2] | 0;
+       i25 = HEAP32[i17 >> 2] | 0;
+      }
+      _lua_pushlstring(i19, i25, i24) | 0;
+     } else {
+      _lua_pushlstring(i23, i20, i21 - i20 | 0) | 0;
+     }
+    } while (0);
+    _lua_gettable(i23, 3);
+    i19 = 37;
+   } else if ((i8 | 0) != 6) {
+    i24 = _lua_tolstring(i23, 3, i5) | 0;
+    if ((HEAP32[i5 >> 2] | 0) != 0) {
+     i23 = i21 - i20 | 0;
+     i25 = 0;
+     do {
+      i26 = i24 + i25 | 0;
+      i27 = HEAP8[i26] | 0;
+      do {
+       if (i27 << 24 >> 24 == 37) {
+        i25 = i25 + 1 | 0;
+        i26 = i24 + i25 | 0;
+        i28 = HEAP8[i26] | 0;
+        i27 = i28 << 24 >> 24;
+        if (((i28 & 255) + -48 | 0) >>> 0 < 10) {
+         if (i28 << 24 >> 24 == 48) {
+          _luaL_addlstring(i2, i20, i23);
+          break;
+         } else {
+          _push_onecapture(i6, i27 + -49 | 0, i20, i21);
+          _luaL_addvalue(i2);
+          break;
+         }
+        }
+        if (!(i28 << 24 >> 24 == 37)) {
+         i28 = HEAP32[i11 >> 2] | 0;
+         HEAP32[i4 >> 2] = 37;
+         _luaL_error(i28, 7600, i4) | 0;
+        }
+        i27 = HEAP32[i15 >> 2] | 0;
+        if (!(i27 >>> 0 < (HEAP32[i18 >> 2] | 0) >>> 0)) {
+         _luaL_prepbuffsize(i2, 1) | 0;
+         i27 = HEAP32[i15 >> 2] | 0;
+        }
+        i28 = HEAP8[i26] | 0;
+        HEAP32[i15 >> 2] = i27 + 1;
+        HEAP8[(HEAP32[i2 >> 2] | 0) + i27 | 0] = i28;
+       } else {
+        i28 = HEAP32[i15 >> 2] | 0;
+        if (!(i28 >>> 0 < (HEAP32[i18 >> 2] | 0) >>> 0)) {
+         _luaL_prepbuffsize(i2, 1) | 0;
+         i28 = HEAP32[i15 >> 2] | 0;
+         i27 = HEAP8[i26] | 0;
+        }
+        HEAP32[i15 >> 2] = i28 + 1;
+        HEAP8[(HEAP32[i2 >> 2] | 0) + i28 | 0] = i27;
+       }
+      } while (0);
+      i25 = i25 + 1 | 0;
+     } while (i25 >>> 0 < (HEAP32[i5 >> 2] | 0) >>> 0);
+    }
+   } else {
+    _lua_pushvalue(i23, 3);
+    i19 = HEAP32[i14 >> 2] | 0;
+    i19 = (i19 | 0) != 0 | (i20 | 0) == 0 ? i19 : 1;
+    _luaL_checkstack(HEAP32[i11 >> 2] | 0, i19, 7200);
+    if ((i19 | 0) > 0) {
+     i24 = 0;
+     do {
+      _push_onecapture(i6, i24, i20, i21);
+      i24 = i24 + 1 | 0;
+     } while ((i24 | 0) != (i19 | 0));
+    }
+    _lua_callk(i23, i19, 1, 0, 0);
+    i19 = 37;
+   }
+   if ((i19 | 0) == 37) {
+    i19 = 0;
+    if ((_lua_toboolean(i23, -1) | 0) != 0) {
+     if ((_lua_isstring(i23, -1) | 0) == 0) {
+      HEAP32[i4 >> 2] = _lua_typename(i23, _lua_type(i23, -1) | 0) | 0;
+      _luaL_error(i23, 7560, i4) | 0;
+     }
+    } else {
+     _lua_settop(i23, -2);
+     _lua_pushlstring(i23, i20, i21 - i20 | 0) | 0;
+    }
+    _luaL_addvalue(i2);
+   }
+   if (i21 >>> 0 > i20 >>> 0) {
+    i20 = i21;
+   } else {
+    i19 = 43;
+   }
+  } else {
+   i19 = 43;
+  }
+  if ((i19 | 0) == 43) {
+   i19 = 0;
+   if (!(i20 >>> 0 < (HEAP32[i10 >> 2] | 0) >>> 0)) {
+    i19 = 48;
+    break;
+   }
+   i21 = HEAP32[i15 >> 2] | 0;
+   if (!(i21 >>> 0 < (HEAP32[i18 >> 2] | 0) >>> 0)) {
+    _luaL_prepbuffsize(i2, 1) | 0;
+    i21 = HEAP32[i15 >> 2] | 0;
+   }
+   i28 = HEAP8[i20] | 0;
+   HEAP32[i15 >> 2] = i21 + 1;
+   HEAP8[(HEAP32[i2 >> 2] | 0) + i21 | 0] = i28;
+   i20 = i20 + 1 | 0;
+  }
+  if (i7) {
+   i19 = 48;
+   break;
+  }
+ }
+ if ((i19 | 0) == 48) {
+  _luaL_addlstring(i2, i20, (HEAP32[i10 >> 2] | 0) - i20 | 0);
+  _luaL_pushresult(i2);
+  _lua_pushinteger(i1, i22);
+  STACKTOP = i3;
+  return 2;
+ }
+ return 0;
+}
+function _constructor(i11, i13) {
+ i11 = i11 | 0;
+ i13 = i13 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i12 = 0, i14 = 0, i15 = 0, i16 = 0;
+ i5 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i10 = i5 + 40 | 0;
+ i8 = i5;
+ i12 = i11 + 48 | 0;
+ i6 = HEAP32[i12 >> 2] | 0;
+ i9 = HEAP32[i11 + 4 >> 2] | 0;
+ i2 = _luaK_codeABC(i6, 11, 0, 0, 0) | 0;
+ i7 = i8 + 36 | 0;
+ HEAP32[i7 >> 2] = 0;
+ i4 = i8 + 28 | 0;
+ HEAP32[i4 >> 2] = 0;
+ i3 = i8 + 32 | 0;
+ HEAP32[i3 >> 2] = 0;
+ i1 = i8 + 24 | 0;
+ HEAP32[i1 >> 2] = i13;
+ HEAP32[i13 + 16 >> 2] = -1;
+ HEAP32[i13 + 20 >> 2] = -1;
+ HEAP32[i13 >> 2] = 11;
+ HEAP32[i13 + 8 >> 2] = i2;
+ HEAP32[i8 + 16 >> 2] = -1;
+ HEAP32[i8 + 20 >> 2] = -1;
+ HEAP32[i8 >> 2] = 0;
+ HEAP32[i8 + 8 >> 2] = 0;
+ _luaK_exp2nextreg(HEAP32[i12 >> 2] | 0, i13);
+ i13 = i11 + 16 | 0;
+ if ((HEAP32[i13 >> 2] | 0) != 123) {
+  _error_expected(i11, 123);
+ }
+ _luaX_next(i11);
+ L4 : do {
+  if ((HEAP32[i13 >> 2] | 0) != 125) {
+   L5 : while (1) {
+    if ((HEAP32[i8 >> 2] | 0) != 0 ? (_luaK_exp2nextreg(i6, i8), HEAP32[i8 >> 2] = 0, (HEAP32[i7 >> 2] | 0) == 50) : 0) {
+     _luaK_setlist(i6, HEAP32[(HEAP32[i1 >> 2] | 0) + 8 >> 2] | 0, HEAP32[i3 >> 2] | 0, 50);
+     HEAP32[i7 >> 2] = 0;
+    }
+    i14 = HEAP32[i13 >> 2] | 0;
+    do {
+     if ((i14 | 0) == 288) {
+      if ((_luaX_lookahead(i11) | 0) == 61) {
+       _recfield(i11, i8);
+       break;
+      }
+      _subexpr(i11, i8, 0) | 0;
+      i14 = HEAP32[i12 >> 2] | 0;
+      i15 = HEAP32[i3 >> 2] | 0;
+      if ((i15 | 0) > 2147483645) {
+       i12 = 10;
+       break L5;
+      }
+      HEAP32[i3 >> 2] = i15 + 1;
+      HEAP32[i7 >> 2] = (HEAP32[i7 >> 2] | 0) + 1;
+     } else if ((i14 | 0) == 91) {
+      _recfield(i11, i8);
+     } else {
+      _subexpr(i11, i8, 0) | 0;
+      i14 = HEAP32[i12 >> 2] | 0;
+      i15 = HEAP32[i3 >> 2] | 0;
+      if ((i15 | 0) > 2147483645) {
+       i12 = 17;
+       break L5;
+      }
+      HEAP32[i3 >> 2] = i15 + 1;
+      HEAP32[i7 >> 2] = (HEAP32[i7 >> 2] | 0) + 1;
+     }
+    } while (0);
+    i14 = HEAP32[i13 >> 2] | 0;
+    if ((i14 | 0) == 44) {
+     _luaX_next(i11);
+    } else if ((i14 | 0) == 59) {
+     _luaX_next(i11);
+    } else {
+     break L4;
+    }
+    if ((HEAP32[i13 >> 2] | 0) == 125) {
+     break L4;
+    }
+   }
+   if ((i12 | 0) == 10) {
+    i12 = i14 + 12 | 0;
+    i13 = HEAP32[(HEAP32[i12 >> 2] | 0) + 52 >> 2] | 0;
+    i14 = HEAP32[(HEAP32[i14 >> 2] | 0) + 64 >> 2] | 0;
+    if ((i14 | 0) == 0) {
+     i16 = 6552;
+     HEAP32[i10 >> 2] = 6528;
+     i15 = i10 + 4 | 0;
+     HEAP32[i15 >> 2] = 2147483645;
+     i15 = i10 + 8 | 0;
+     HEAP32[i15 >> 2] = i16;
+     i15 = _luaO_pushfstring(i13, 6592, i10) | 0;
+     i16 = HEAP32[i12 >> 2] | 0;
+     _luaX_syntaxerror(i16, i15);
+    }
+    HEAP32[i10 >> 2] = i14;
+    i15 = _luaO_pushfstring(i13, 6568, i10) | 0;
+    HEAP32[i10 >> 2] = 6528;
+    i16 = i10 + 4 | 0;
+    HEAP32[i16 >> 2] = 2147483645;
+    i16 = i10 + 8 | 0;
+    HEAP32[i16 >> 2] = i15;
+    i16 = _luaO_pushfstring(i13, 6592, i10) | 0;
+    i15 = HEAP32[i12 >> 2] | 0;
+    _luaX_syntaxerror(i15, i16);
+   } else if ((i12 | 0) == 17) {
+    i13 = i14 + 12 | 0;
+    i12 = HEAP32[(HEAP32[i13 >> 2] | 0) + 52 >> 2] | 0;
+    i14 = HEAP32[(HEAP32[i14 >> 2] | 0) + 64 >> 2] | 0;
+    if ((i14 | 0) == 0) {
+     i15 = 6552;
+     HEAP32[i10 >> 2] = 6528;
+     i16 = i10 + 4 | 0;
+     HEAP32[i16 >> 2] = 2147483645;
+     i16 = i10 + 8 | 0;
+     HEAP32[i16 >> 2] = i15;
+     i16 = _luaO_pushfstring(i12, 6592, i10) | 0;
+     i15 = HEAP32[i13 >> 2] | 0;
+     _luaX_syntaxerror(i15, i16);
+    }
+    HEAP32[i10 >> 2] = i14;
+    i15 = _luaO_pushfstring(i12, 6568, i10) | 0;
+    HEAP32[i10 >> 2] = 6528;
+    i16 = i10 + 4 | 0;
+    HEAP32[i16 >> 2] = 2147483645;
+    i16 = i10 + 8 | 0;
+    HEAP32[i16 >> 2] = i15;
+    i16 = _luaO_pushfstring(i12, 6592, i10) | 0;
+    i15 = HEAP32[i13 >> 2] | 0;
+    _luaX_syntaxerror(i15, i16);
+   }
+  }
+ } while (0);
+ _check_match(i11, 125, 123, i9);
+ i9 = HEAP32[i7 >> 2] | 0;
+ do {
+  if ((i9 | 0) != 0) {
+   i10 = HEAP32[i8 >> 2] | 0;
+   if ((i10 | 0) != 0) if ((i10 | 0) == 13 | (i10 | 0) == 12) {
+    _luaK_setreturns(i6, i8, -1);
+    _luaK_setlist(i6, HEAP32[(HEAP32[i1 >> 2] | 0) + 8 >> 2] | 0, HEAP32[i3 >> 2] | 0, -1);
+    HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + -1;
+    break;
+   } else {
+    _luaK_exp2nextreg(i6, i8);
+    i9 = HEAP32[i7 >> 2] | 0;
+   }
+   _luaK_setlist(i6, HEAP32[(HEAP32[i1 >> 2] | 0) + 8 >> 2] | 0, HEAP32[i3 >> 2] | 0, i9);
+  }
+ } while (0);
+ i16 = HEAP32[(HEAP32[(HEAP32[i6 >> 2] | 0) + 12 >> 2] | 0) + (i2 << 2) >> 2] & 8388607;
+ i16 = (_luaO_int2fb(HEAP32[i3 >> 2] | 0) | 0) << 23 | i16;
+ HEAP32[(HEAP32[(HEAP32[i6 >> 2] | 0) + 12 >> 2] | 0) + (i2 << 2) >> 2] = i16;
+ i16 = (_luaO_int2fb(HEAP32[i4 >> 2] | 0) | 0) << 14 & 8372224 | i16 & -8372225;
+ HEAP32[(HEAP32[(HEAP32[i6 >> 2] | 0) + 12 >> 2] | 0) + (i2 << 2) >> 2] = i16;
+ STACKTOP = i5;
+ return;
+}
+function _luaK_prefix(i4, i14, i7, i13) {
+ i4 = i4 | 0;
+ i14 = i14 | 0;
+ i7 = i7 | 0;
+ i13 = i13 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i12 = i1;
+ HEAP32[i12 + 20 >> 2] = -1;
+ HEAP32[i12 + 16 >> 2] = -1;
+ HEAP32[i12 >> 2] = 5;
+ HEAPF64[i12 + 8 >> 3] = 0.0;
+ if ((i14 | 0) == 1) {
+  _luaK_dischargevars(i4, i7);
+  switch (HEAP32[i7 >> 2] | 0) {
+  case 2:
+  case 5:
+  case 4:
+   {
+    HEAP32[i7 >> 2] = 3;
+    break;
+   }
+  case 10:
+   {
+    i13 = HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] | 0;
+    i12 = HEAP32[i7 + 8 >> 2] | 0;
+    i10 = i13 + (i12 << 2) | 0;
+    if (!((i12 | 0) > 0 ? (i11 = i13 + (i12 + -1 << 2) | 0, i9 = HEAP32[i11 >> 2] | 0, (HEAP8[5584 + (i9 & 63) | 0] | 0) < 0) : 0)) {
+     i11 = i10;
+     i9 = HEAP32[i10 >> 2] | 0;
+    }
+    HEAP32[i11 >> 2] = ((i9 & 16320 | 0) == 0) << 6 | i9 & -16321;
+    break;
+   }
+  case 6:
+   {
+    i8 = 25;
+    break;
+   }
+  case 3:
+  case 1:
+   {
+    HEAP32[i7 >> 2] = 2;
+    break;
+   }
+  case 11:
+   {
+    i12 = i4 + 48 | 0;
+    i8 = HEAP8[i12] | 0;
+    i11 = (i8 & 255) + 1 | 0;
+    i9 = (HEAP32[i4 >> 2] | 0) + 78 | 0;
+    do {
+     if (i11 >>> 0 > (HEAPU8[i9] | 0) >>> 0) {
+      if (i11 >>> 0 > 249) {
+       _luaX_syntaxerror(HEAP32[i4 + 12 >> 2] | 0, 10536);
+      } else {
+       HEAP8[i9] = i11;
+       i10 = HEAP8[i12] | 0;
+       break;
+      }
+     } else {
+      i10 = i8;
+     }
+    } while (0);
+    i14 = (i10 & 255) + 1 | 0;
+    HEAP8[i12] = i14;
+    _discharge2reg(i4, i7, (i14 & 255) + -1 | 0);
+    if ((HEAP32[i7 >> 2] | 0) == 6) {
+     i8 = 25;
+    } else {
+     i9 = i7 + 8 | 0;
+     i8 = 28;
+    }
+    break;
+   }
+  default:
+   {}
+  }
+  if ((i8 | 0) == 25) {
+   i8 = i7 + 8 | 0;
+   i9 = HEAP32[i8 >> 2] | 0;
+   if ((i9 & 256 | 0) == 0 ? (HEAPU8[i4 + 46 | 0] | 0) <= (i9 | 0) : 0) {
+    i9 = i4 + 48 | 0;
+    HEAP8[i9] = (HEAP8[i9] | 0) + -1 << 24 >> 24;
+    i9 = i8;
+    i8 = 28;
+   } else {
+    i9 = i8;
+    i8 = 28;
+   }
+  }
+  if ((i8 | 0) == 28) {
+   HEAP32[i9 >> 2] = _luaK_code(i4, HEAP32[i9 >> 2] << 23 | 20) | 0;
+   HEAP32[i7 >> 2] = 11;
+  }
+  i14 = i7 + 20 | 0;
+  i8 = HEAP32[i14 >> 2] | 0;
+  i7 = i7 + 16 | 0;
+  i9 = HEAP32[i7 >> 2] | 0;
+  HEAP32[i14 >> 2] = i9;
+  HEAP32[i7 >> 2] = i8;
+  if (!((i9 | 0) == -1)) {
+   i8 = HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] | 0;
+   do {
+    i12 = i8 + (i9 << 2) | 0;
+    if ((i9 | 0) > 0 ? (i5 = i8 + (i9 + -1 << 2) | 0, i6 = HEAP32[i5 >> 2] | 0, (HEAP8[5584 + (i6 & 63) | 0] | 0) < 0) : 0) {
+     i10 = i5;
+     i11 = i6;
+    } else {
+     i10 = i12;
+     i11 = HEAP32[i12 >> 2] | 0;
+    }
+    if ((i11 & 63 | 0) == 28) {
+     HEAP32[i10 >> 2] = i11 & 8372224 | i11 >>> 23 << 6 | 27;
+    }
+    i10 = ((HEAP32[i12 >> 2] | 0) >>> 14) + -131071 | 0;
+    if ((i10 | 0) == -1) {
+     break;
+    }
+    i9 = i9 + 1 + i10 | 0;
+   } while (!((i9 | 0) == -1));
+   i8 = HEAP32[i7 >> 2] | 0;
+  }
+  if ((i8 | 0) == -1) {
+   STACKTOP = i1;
+   return;
+  }
+  i4 = HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] | 0;
+  while (1) {
+   i6 = i4 + (i8 << 2) | 0;
+   if ((i8 | 0) > 0 ? (i2 = i4 + (i8 + -1 << 2) | 0, i3 = HEAP32[i2 >> 2] | 0, (HEAP8[5584 + (i3 & 63) | 0] | 0) < 0) : 0) {
+    i7 = i2;
+    i5 = i3;
+   } else {
+    i7 = i6;
+    i5 = HEAP32[i6 >> 2] | 0;
+   }
+   if ((i5 & 63 | 0) == 28) {
+    HEAP32[i7 >> 2] = i5 & 8372224 | i5 >>> 23 << 6 | 27;
+   }
+   i5 = ((HEAP32[i6 >> 2] | 0) >>> 14) + -131071 | 0;
+   if ((i5 | 0) == -1) {
+    i8 = 54;
+    break;
+   }
+   i8 = i8 + 1 + i5 | 0;
+   if ((i8 | 0) == -1) {
+    i8 = 54;
+    break;
+   }
+  }
+  if ((i8 | 0) == 54) {
+   STACKTOP = i1;
+   return;
+  }
+ } else if ((i14 | 0) == 0) {
+  if (((HEAP32[i7 >> 2] | 0) == 5 ? (HEAP32[i7 + 16 >> 2] | 0) == -1 : 0) ? (HEAP32[i7 + 20 >> 2] | 0) == -1 : 0) {
+   i14 = i7 + 8 | 0;
+   HEAPF64[i14 >> 3] = -+HEAPF64[i14 >> 3];
+   STACKTOP = i1;
+   return;
+  }
+  _luaK_dischargevars(i4, i7);
+  if ((HEAP32[i7 >> 2] | 0) == 6) {
+   i2 = HEAP32[i7 + 8 >> 2] | 0;
+   if ((HEAP32[i7 + 16 >> 2] | 0) != (HEAP32[i7 + 20 >> 2] | 0)) {
+    if ((i2 | 0) < (HEAPU8[i4 + 46 | 0] | 0)) {
+     i8 = 10;
+    } else {
+     _exp2reg(i4, i7, i2);
+    }
+   }
+  } else {
+   i8 = 10;
+  }
+  if ((i8 | 0) == 10) {
+   _luaK_exp2nextreg(i4, i7);
+  }
+  _codearith(i4, 19, i7, i12, i13);
+  STACKTOP = i1;
+  return;
+ } else if ((i14 | 0) == 2) {
+  _luaK_dischargevars(i4, i7);
+  if ((HEAP32[i7 >> 2] | 0) == 6) {
+   i2 = HEAP32[i7 + 8 >> 2] | 0;
+   if ((HEAP32[i7 + 16 >> 2] | 0) != (HEAP32[i7 + 20 >> 2] | 0)) {
+    if ((i2 | 0) < (HEAPU8[i4 + 46 | 0] | 0)) {
+     i8 = 52;
+    } else {
+     _exp2reg(i4, i7, i2);
+    }
+   }
+  } else {
+   i8 = 52;
+  }
+  if ((i8 | 0) == 52) {
+   _luaK_exp2nextreg(i4, i7);
+  }
+  _codearith(i4, 21, i7, i12, i13);
+  STACKTOP = i1;
+  return;
+ } else {
+  STACKTOP = i1;
+  return;
+ }
+}
+function _subexpr(i6, i3, i7) {
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 48 | 0;
+ i11 = i2 + 24 | 0;
+ i5 = i2;
+ i4 = i6 + 48 | 0;
+ i9 = HEAP32[i4 >> 2] | 0;
+ i1 = i6 + 52 | 0;
+ i12 = (HEAP32[i1 >> 2] | 0) + 38 | 0;
+ i13 = (HEAP16[i12 >> 1] | 0) + 1 << 16 >> 16;
+ HEAP16[i12 >> 1] = i13;
+ if ((i13 & 65535) > 200) {
+  i10 = i9 + 12 | 0;
+  i12 = HEAP32[(HEAP32[i10 >> 2] | 0) + 52 >> 2] | 0;
+  i13 = HEAP32[(HEAP32[i9 >> 2] | 0) + 64 >> 2] | 0;
+  if ((i13 | 0) == 0) {
+   i15 = 6552;
+   HEAP32[i11 >> 2] = 6360;
+   i14 = i11 + 4 | 0;
+   HEAP32[i14 >> 2] = 200;
+   i14 = i11 + 8 | 0;
+   HEAP32[i14 >> 2] = i15;
+   i14 = _luaO_pushfstring(i12, 6592, i11) | 0;
+   i15 = HEAP32[i10 >> 2] | 0;
+   _luaX_syntaxerror(i15, i14);
+  }
+  HEAP32[i11 >> 2] = i13;
+  i14 = _luaO_pushfstring(i12, 6568, i11) | 0;
+  HEAP32[i11 >> 2] = 6360;
+  i15 = i11 + 4 | 0;
+  HEAP32[i15 >> 2] = 200;
+  i15 = i11 + 8 | 0;
+  HEAP32[i15 >> 2] = i14;
+  i15 = _luaO_pushfstring(i12, 6592, i11) | 0;
+  i14 = HEAP32[i10 >> 2] | 0;
+  _luaX_syntaxerror(i14, i15);
+ }
+ i10 = i6 + 16 | 0;
+ L8 : do {
+  switch (HEAP32[i10 >> 2] | 0) {
+  case 287:
+   {
+    HEAP32[i3 + 16 >> 2] = -1;
+    HEAP32[i3 + 20 >> 2] = -1;
+    HEAP32[i3 >> 2] = 5;
+    HEAP32[i3 + 8 >> 2] = 0;
+    HEAPF64[i3 + 8 >> 3] = +HEAPF64[i6 + 24 >> 3];
+    i8 = 20;
+    break;
+   }
+  case 271:
+   {
+    i9 = 1;
+    i8 = 8;
+    break;
+   }
+  case 289:
+   {
+    i8 = _luaK_stringK(i9, HEAP32[i6 + 24 >> 2] | 0) | 0;
+    HEAP32[i3 + 16 >> 2] = -1;
+    HEAP32[i3 + 20 >> 2] = -1;
+    HEAP32[i3 >> 2] = 4;
+    HEAP32[i3 + 8 >> 2] = i8;
+    i8 = 20;
+    break;
+   }
+  case 265:
+   {
+    _luaX_next(i6);
+    _body(i6, i3, 0, HEAP32[i6 + 4 >> 2] | 0);
+    break;
+   }
+  case 276:
+   {
+    HEAP32[i3 + 16 >> 2] = -1;
+    HEAP32[i3 + 20 >> 2] = -1;
+    HEAP32[i3 >> 2] = 2;
+    HEAP32[i3 + 8 >> 2] = 0;
+    i8 = 20;
+    break;
+   }
+  case 45:
+   {
+    i9 = 0;
+    i8 = 8;
+    break;
+   }
+  case 35:
+   {
+    i9 = 2;
+    i8 = 8;
+    break;
+   }
+  case 123:
+   {
+    _constructor(i6, i3);
+    break;
+   }
+  case 263:
+   {
+    HEAP32[i3 + 16 >> 2] = -1;
+    HEAP32[i3 + 20 >> 2] = -1;
+    HEAP32[i3 >> 2] = 3;
+    HEAP32[i3 + 8 >> 2] = 0;
+    i8 = 20;
+    break;
+   }
+  case 280:
+   {
+    if ((HEAP8[(HEAP32[i9 >> 2] | 0) + 77 | 0] | 0) == 0) {
+     _luaX_syntaxerror(i6, 6408);
+    } else {
+     i8 = _luaK_codeABC(i9, 38, 0, 1, 0) | 0;
+     HEAP32[i3 + 16 >> 2] = -1;
+     HEAP32[i3 + 20 >> 2] = -1;
+     HEAP32[i3 >> 2] = 13;
+     HEAP32[i3 + 8 >> 2] = i8;
+     i8 = 20;
+     break L8;
+    }
+    break;
+   }
+  case 270:
+   {
+    HEAP32[i3 + 16 >> 2] = -1;
+    HEAP32[i3 + 20 >> 2] = -1;
+    HEAP32[i3 >> 2] = 1;
+    HEAP32[i3 + 8 >> 2] = 0;
+    i8 = 20;
+    break;
+   }
+  default:
+   {
+    _suffixedexp(i6, i3);
+   }
+  }
+ } while (0);
+ if ((i8 | 0) == 8) {
+  i15 = HEAP32[i6 + 4 >> 2] | 0;
+  _luaX_next(i6);
+  _subexpr(i6, i3, 8) | 0;
+  _luaK_prefix(HEAP32[i4 >> 2] | 0, i9, i3, i15);
+ } else if ((i8 | 0) == 20) {
+  _luaX_next(i6);
+ }
+ switch (HEAP32[i10 >> 2] | 0) {
+ case 257:
+  {
+   i9 = 13;
+   break;
+  }
+ case 272:
+  {
+   i9 = 14;
+   break;
+  }
+ case 47:
+  {
+   i9 = 3;
+   break;
+  }
+ case 37:
+  {
+   i9 = 4;
+   break;
+  }
+ case 43:
+  {
+   i9 = 0;
+   break;
+  }
+ case 284:
+  {
+   i9 = 10;
+   break;
+  }
+ case 281:
+  {
+   i9 = 7;
+   break;
+  }
+ case 62:
+  {
+   i9 = 11;
+   break;
+  }
+ case 282:
+  {
+   i9 = 12;
+   break;
+  }
+ case 45:
+  {
+   i9 = 1;
+   break;
+  }
+ case 42:
+  {
+   i9 = 2;
+   break;
+  }
+ case 60:
+  {
+   i9 = 8;
+   break;
+  }
+ case 283:
+  {
+   i9 = 9;
+   break;
+  }
+ case 94:
+  {
+   i9 = 5;
+   break;
+  }
+ case 279:
+  {
+   i9 = 6;
+   break;
+  }
+ default:
+  {
+   i15 = 15;
+   i14 = HEAP32[i1 >> 2] | 0;
+   i14 = i14 + 38 | 0;
+   i13 = HEAP16[i14 >> 1] | 0;
+   i13 = i13 + -1 << 16 >> 16;
+   HEAP16[i14 >> 1] = i13;
+   STACKTOP = i2;
+   return i15 | 0;
+  }
+ }
+ i8 = i6 + 4 | 0;
+ while (1) {
+  if ((HEAPU8[6376 + (i9 << 1) | 0] | 0) <= (i7 | 0)) {
+   i8 = 39;
+   break;
+  }
+  i15 = HEAP32[i8 >> 2] | 0;
+  _luaX_next(i6);
+  _luaK_infix(HEAP32[i4 >> 2] | 0, i9, i3);
+  i10 = _subexpr(i6, i5, HEAPU8[6377 + (i9 << 1) | 0] | 0) | 0;
+  _luaK_posfix(HEAP32[i4 >> 2] | 0, i9, i3, i5, i15);
+  if ((i10 | 0) == 15) {
+   i9 = 15;
+   i8 = 39;
+   break;
+  } else {
+   i9 = i10;
+  }
+ }
+ if ((i8 | 0) == 39) {
+  i15 = HEAP32[i1 >> 2] | 0;
+  i15 = i15 + 38 | 0;
+  i14 = HEAP16[i15 >> 1] | 0;
+  i14 = i14 + -1 << 16 >> 16;
+  HEAP16[i15 >> 1] = i14;
+  STACKTOP = i2;
+  return i9 | 0;
+ }
+ return 0;
+}
+function _luaV_lessequal(i5, i3, i2) {
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i1 = STACKTOP;
+ i4 = i3 + 8 | 0;
+ i7 = HEAP32[i4 >> 2] | 0;
+ if ((i7 | 0) == 3) {
+  if ((HEAP32[i2 + 8 >> 2] | 0) == 3) {
+   i9 = +HEAPF64[i3 >> 3] <= +HEAPF64[i2 >> 3] | 0;
+   STACKTOP = i1;
+   return i9 | 0;
+  }
+ } else {
+  if ((i7 & 15 | 0) == 4 ? (HEAP32[i2 + 8 >> 2] & 15 | 0) == 4 : 0) {
+   i3 = HEAP32[i3 >> 2] | 0;
+   i6 = HEAP32[i2 >> 2] | 0;
+   i4 = i3 + 16 | 0;
+   i5 = i6 + 16 | 0;
+   i7 = _strcmp(i4, i5) | 0;
+   L8 : do {
+    if ((i7 | 0) == 0) {
+     i2 = HEAP32[i3 + 12 >> 2] | 0;
+     i3 = HEAP32[i6 + 12 >> 2] | 0;
+     i6 = i5;
+     while (1) {
+      i5 = _strlen(i4 | 0) | 0;
+      i7 = (i5 | 0) == (i2 | 0);
+      if ((i5 | 0) == (i3 | 0)) {
+       break;
+      }
+      if (i7) {
+       i7 = -1;
+       break L8;
+      }
+      i5 = i5 + 1 | 0;
+      i4 = i4 + i5 | 0;
+      i6 = i6 + i5 | 0;
+      i7 = _strcmp(i4, i6) | 0;
+      if ((i7 | 0) == 0) {
+       i2 = i2 - i5 | 0;
+       i3 = i3 - i5 | 0;
+      } else {
+       break L8;
+      }
+     }
+     i7 = i7 & 1 ^ 1;
+    }
+   } while (0);
+   i9 = (i7 | 0) < 1 | 0;
+   STACKTOP = i1;
+   return i9 | 0;
+  }
+ }
+ i7 = i5 + 8 | 0;
+ i8 = HEAP32[i7 >> 2] | 0;
+ i9 = _luaT_gettmbyobj(i5, i3, 14) | 0;
+ if ((HEAP32[i9 + 8 >> 2] | 0) == 0) {
+  i9 = _luaT_gettmbyobj(i5, i2, 14) | 0;
+  if ((HEAP32[i9 + 8 >> 2] | 0) == 0) {
+   i8 = HEAP32[i7 >> 2] | 0;
+   i9 = _luaT_gettmbyobj(i5, i2, 13) | 0;
+   if ((HEAP32[i9 + 8 >> 2] | 0) == 0) {
+    i9 = _luaT_gettmbyobj(i5, i3, 13) | 0;
+    if ((HEAP32[i9 + 8 >> 2] | 0) == 0) {
+     _luaG_ordererror(i5, i3, i2);
+    } else {
+     i6 = i9;
+    }
+   } else {
+    i6 = i9;
+   }
+   i10 = i5 + 28 | 0;
+   i9 = i8 - (HEAP32[i10 >> 2] | 0) | 0;
+   i8 = HEAP32[i7 >> 2] | 0;
+   HEAP32[i7 >> 2] = i8 + 16;
+   i13 = i6;
+   i11 = HEAP32[i13 + 4 >> 2] | 0;
+   i12 = i8;
+   HEAP32[i12 >> 2] = HEAP32[i13 >> 2];
+   HEAP32[i12 + 4 >> 2] = i11;
+   HEAP32[i8 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+   i8 = HEAP32[i7 >> 2] | 0;
+   HEAP32[i7 >> 2] = i8 + 16;
+   i12 = i2;
+   i11 = HEAP32[i12 + 4 >> 2] | 0;
+   i6 = i8;
+   HEAP32[i6 >> 2] = HEAP32[i12 >> 2];
+   HEAP32[i6 + 4 >> 2] = i11;
+   HEAP32[i8 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+   i2 = HEAP32[i7 >> 2] | 0;
+   HEAP32[i7 >> 2] = i2 + 16;
+   i8 = i3;
+   i6 = HEAP32[i8 + 4 >> 2] | 0;
+   i3 = i2;
+   HEAP32[i3 >> 2] = HEAP32[i8 >> 2];
+   HEAP32[i3 + 4 >> 2] = i6;
+   HEAP32[i2 + 8 >> 2] = HEAP32[i4 >> 2];
+   _luaD_call(i5, (HEAP32[i7 >> 2] | 0) + -48 | 0, 1, HEAP8[(HEAP32[i5 + 16 >> 2] | 0) + 18 | 0] & 1);
+   i3 = HEAP32[i10 >> 2] | 0;
+   i2 = HEAP32[i7 >> 2] | 0;
+   i5 = i2 + -16 | 0;
+   HEAP32[i7 >> 2] = i5;
+   i6 = HEAP32[i5 + 4 >> 2] | 0;
+   i8 = i3 + i9 | 0;
+   HEAP32[i8 >> 2] = HEAP32[i5 >> 2];
+   HEAP32[i8 + 4 >> 2] = i6;
+   HEAP32[i3 + (i9 + 8) >> 2] = HEAP32[i2 + -8 >> 2];
+   i3 = HEAP32[i7 >> 2] | 0;
+   i2 = HEAP32[i3 + 8 >> 2] | 0;
+   if ((i2 | 0) != 0) {
+    if ((i2 | 0) == 1) {
+     i2 = (HEAP32[i3 >> 2] | 0) != 0;
+    } else {
+     i2 = 1;
+    }
+   } else {
+    i2 = 0;
+   }
+   i13 = i2 & 1 ^ 1;
+   STACKTOP = i1;
+   return i13 | 0;
+  }
+ }
+ i10 = i5 + 28 | 0;
+ i13 = i8 - (HEAP32[i10 >> 2] | 0) | 0;
+ i11 = HEAP32[i7 >> 2] | 0;
+ HEAP32[i7 >> 2] = i11 + 16;
+ i6 = i9;
+ i8 = HEAP32[i6 + 4 >> 2] | 0;
+ i12 = i11;
+ HEAP32[i12 >> 2] = HEAP32[i6 >> 2];
+ HEAP32[i12 + 4 >> 2] = i8;
+ HEAP32[i11 + 8 >> 2] = HEAP32[i9 + 8 >> 2];
+ i9 = HEAP32[i7 >> 2] | 0;
+ HEAP32[i7 >> 2] = i9 + 16;
+ i11 = i3;
+ i12 = HEAP32[i11 + 4 >> 2] | 0;
+ i3 = i9;
+ HEAP32[i3 >> 2] = HEAP32[i11 >> 2];
+ HEAP32[i3 + 4 >> 2] = i12;
+ HEAP32[i9 + 8 >> 2] = HEAP32[i4 >> 2];
+ i3 = HEAP32[i7 >> 2] | 0;
+ HEAP32[i7 >> 2] = i3 + 16;
+ i9 = i2;
+ i12 = HEAP32[i9 + 4 >> 2] | 0;
+ i11 = i3;
+ HEAP32[i11 >> 2] = HEAP32[i9 >> 2];
+ HEAP32[i11 + 4 >> 2] = i12;
+ HEAP32[i3 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+ _luaD_call(i5, (HEAP32[i7 >> 2] | 0) + -48 | 0, 1, HEAP8[(HEAP32[i5 + 16 >> 2] | 0) + 18 | 0] & 1);
+ i2 = HEAP32[i10 >> 2] | 0;
+ i3 = HEAP32[i7 >> 2] | 0;
+ i10 = i3 + -16 | 0;
+ HEAP32[i7 >> 2] = i10;
+ i11 = HEAP32[i10 + 4 >> 2] | 0;
+ i12 = i2 + i13 | 0;
+ HEAP32[i12 >> 2] = HEAP32[i10 >> 2];
+ HEAP32[i12 + 4 >> 2] = i11;
+ HEAP32[i2 + (i13 + 8) >> 2] = HEAP32[i3 + -8 >> 2];
+ i2 = HEAP32[i7 >> 2] | 0;
+ i3 = HEAP32[i2 + 8 >> 2] | 0;
+ if ((i3 | 0) != 0) {
+  if ((i3 | 0) == 1) {
+   i2 = (HEAP32[i2 >> 2] | 0) != 0;
+  } else {
+   i2 = 1;
+  }
+ } else {
+  i2 = 0;
+ }
+ i13 = i2 & 1;
+ STACKTOP = i1;
+ return i13 | 0;
+}
+function ___udivmoddi4(i6, i8, i2, i4, i1) {
+ i6 = i6 | 0;
+ i8 = i8 | 0;
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ var i3 = 0, i5 = 0, i7 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0;
+ i5 = i6;
+ i9 = i8;
+ i7 = i9;
+ i10 = i2;
+ i3 = i4;
+ i11 = i3;
+ if ((i7 | 0) == 0) {
+  i2 = (i1 | 0) != 0;
+  if ((i11 | 0) == 0) {
+   if (i2) {
+    HEAP32[i1 >> 2] = (i5 >>> 0) % (i10 >>> 0);
+    HEAP32[i1 + 4 >> 2] = 0;
+   }
+   i11 = 0;
+   i12 = (i5 >>> 0) / (i10 >>> 0) >>> 0;
+   return (tempRet0 = i11, i12) | 0;
+  } else {
+   if (!i2) {
+    i11 = 0;
+    i12 = 0;
+    return (tempRet0 = i11, i12) | 0;
+   }
+   HEAP32[i1 >> 2] = i6 | 0;
+   HEAP32[i1 + 4 >> 2] = i8 & 0;
+   i11 = 0;
+   i12 = 0;
+   return (tempRet0 = i11, i12) | 0;
+  }
+ }
+ i12 = (i11 | 0) == 0;
+ do {
+  if ((i10 | 0) != 0) {
+   if (!i12) {
+    i10 = (_llvm_ctlz_i32(i11 | 0) | 0) - (_llvm_ctlz_i32(i7 | 0) | 0) | 0;
+    if (i10 >>> 0 <= 31) {
+     i11 = i10 + 1 | 0;
+     i12 = 31 - i10 | 0;
+     i8 = i10 - 31 >> 31;
+     i9 = i11;
+     i6 = i5 >>> (i11 >>> 0) & i8 | i7 << i12;
+     i8 = i7 >>> (i11 >>> 0) & i8;
+     i11 = 0;
+     i7 = i5 << i12;
+     break;
+    }
+    if ((i1 | 0) == 0) {
+     i11 = 0;
+     i12 = 0;
+     return (tempRet0 = i11, i12) | 0;
+    }
+    HEAP32[i1 >> 2] = i6 | 0;
+    HEAP32[i1 + 4 >> 2] = i9 | i8 & 0;
+    i11 = 0;
+    i12 = 0;
+    return (tempRet0 = i11, i12) | 0;
+   }
+   i11 = i10 - 1 | 0;
+   if ((i11 & i10 | 0) != 0) {
+    i12 = (_llvm_ctlz_i32(i10 | 0) | 0) + 33 - (_llvm_ctlz_i32(i7 | 0) | 0) | 0;
+    i15 = 64 - i12 | 0;
+    i10 = 32 - i12 | 0;
+    i13 = i10 >> 31;
+    i14 = i12 - 32 | 0;
+    i8 = i14 >> 31;
+    i9 = i12;
+    i6 = i10 - 1 >> 31 & i7 >>> (i14 >>> 0) | (i7 << i10 | i5 >>> (i12 >>> 0)) & i8;
+    i8 = i8 & i7 >>> (i12 >>> 0);
+    i11 = i5 << i15 & i13;
+    i7 = (i7 << i15 | i5 >>> (i14 >>> 0)) & i13 | i5 << i10 & i12 - 33 >> 31;
+    break;
+   }
+   if ((i1 | 0) != 0) {
+    HEAP32[i1 >> 2] = i11 & i5;
+    HEAP32[i1 + 4 >> 2] = 0;
+   }
+   if ((i10 | 0) == 1) {
+    i14 = i9 | i8 & 0;
+    i15 = i6 | 0 | 0;
+    return (tempRet0 = i14, i15) | 0;
+   } else {
+    i15 = _llvm_cttz_i32(i10 | 0) | 0;
+    i14 = i7 >>> (i15 >>> 0) | 0;
+    i15 = i7 << 32 - i15 | i5 >>> (i15 >>> 0) | 0;
+    return (tempRet0 = i14, i15) | 0;
+   }
+  } else {
+   if (i12) {
+    if ((i1 | 0) != 0) {
+     HEAP32[i1 >> 2] = (i7 >>> 0) % (i10 >>> 0);
+     HEAP32[i1 + 4 >> 2] = 0;
+    }
+    i14 = 0;
+    i15 = (i7 >>> 0) / (i10 >>> 0) >>> 0;
+    return (tempRet0 = i14, i15) | 0;
+   }
+   if ((i5 | 0) == 0) {
+    if ((i1 | 0) != 0) {
+     HEAP32[i1 >> 2] = 0;
+     HEAP32[i1 + 4 >> 2] = (i7 >>> 0) % (i11 >>> 0);
+    }
+    i14 = 0;
+    i15 = (i7 >>> 0) / (i11 >>> 0) >>> 0;
+    return (tempRet0 = i14, i15) | 0;
+   }
+   i10 = i11 - 1 | 0;
+   if ((i10 & i11 | 0) == 0) {
+    if ((i1 | 0) != 0) {
+     HEAP32[i1 >> 2] = i6 | 0;
+     HEAP32[i1 + 4 >> 2] = i10 & i7 | i8 & 0;
+    }
+    i14 = 0;
+    i15 = i7 >>> ((_llvm_cttz_i32(i11 | 0) | 0) >>> 0);
+    return (tempRet0 = i14, i15) | 0;
+   }
+   i10 = (_llvm_ctlz_i32(i11 | 0) | 0) - (_llvm_ctlz_i32(i7 | 0) | 0) | 0;
+   if (i10 >>> 0 <= 30) {
+    i8 = i10 + 1 | 0;
+    i15 = 31 - i10 | 0;
+    i9 = i8;
+    i6 = i7 << i15 | i5 >>> (i8 >>> 0);
+    i8 = i7 >>> (i8 >>> 0);
+    i11 = 0;
+    i7 = i5 << i15;
+    break;
+   }
+   if ((i1 | 0) == 0) {
+    i14 = 0;
+    i15 = 0;
+    return (tempRet0 = i14, i15) | 0;
+   }
+   HEAP32[i1 >> 2] = i6 | 0;
+   HEAP32[i1 + 4 >> 2] = i9 | i8 & 0;
+   i14 = 0;
+   i15 = 0;
+   return (tempRet0 = i14, i15) | 0;
+  }
+ } while (0);
+ if ((i9 | 0) == 0) {
+  i12 = i6;
+  i2 = 0;
+  i6 = 0;
+ } else {
+  i2 = i2 | 0 | 0;
+  i3 = i3 | i4 & 0;
+  i4 = _i64Add(i2, i3, -1, -1) | 0;
+  i5 = tempRet0;
+  i10 = i8;
+  i12 = i6;
+  i6 = 0;
+  while (1) {
+   i8 = i11 >>> 31 | i7 << 1;
+   i11 = i6 | i11 << 1;
+   i7 = i12 << 1 | i7 >>> 31 | 0;
+   i10 = i12 >>> 31 | i10 << 1 | 0;
+   _i64Subtract(i4, i5, i7, i10) | 0;
+   i12 = tempRet0;
+   i15 = i12 >> 31 | ((i12 | 0) < 0 ? -1 : 0) << 1;
+   i6 = i15 & 1;
+   i12 = _i64Subtract(i7, i10, i15 & i2, (((i12 | 0) < 0 ? -1 : 0) >> 31 | ((i12 | 0) < 0 ? -1 : 0) << 1) & i3) | 0;
+   i10 = tempRet0;
+   i9 = i9 - 1 | 0;
+   if ((i9 | 0) == 0) {
+    break;
+   } else {
+    i7 = i8;
+   }
+  }
+  i7 = i8;
+  i8 = i10;
+  i2 = 0;
+ }
+ i3 = 0;
+ if ((i1 | 0) != 0) {
+  HEAP32[i1 >> 2] = i12;
+  HEAP32[i1 + 4 >> 2] = i8;
+ }
+ i14 = (i11 | 0) >>> 31 | (i7 | i3) << 1 | (i3 << 1 | i11 >>> 31) & 0 | i2;
+ i15 = (i11 << 1 | 0 >>> 31) & -2 | i6;
+ return (tempRet0 = i14, i15) | 0;
+}
+function _leaveblock(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i5 = i3;
+ i7 = i1 + 16 | 0;
+ i4 = HEAP32[i7 >> 2] | 0;
+ i2 = i1 + 12 | 0;
+ i6 = HEAP32[i2 >> 2] | 0;
+ if ((HEAP32[i4 >> 2] | 0) != 0 ? (HEAP8[i4 + 9 | 0] | 0) != 0 : 0) {
+  i16 = _luaK_jump(i1) | 0;
+  _luaK_patchclose(i1, i16, HEAPU8[i4 + 8 | 0] | 0);
+  _luaK_patchtohere(i1, i16);
+ }
+ L5 : do {
+  if ((HEAP8[i4 + 10 | 0] | 0) != 0) {
+   i15 = i6 + 52 | 0;
+   i14 = _luaS_new(HEAP32[i15 >> 2] | 0, 6304) | 0;
+   i13 = i6 + 64 | 0;
+   i16 = HEAP32[i13 >> 2] | 0;
+   i10 = i16 + 24 | 0;
+   i8 = i6 + 48 | 0;
+   i11 = HEAP32[(HEAP32[i8 >> 2] | 0) + 20 >> 2] | 0;
+   i12 = i16 + 28 | 0;
+   i9 = HEAP32[i12 >> 2] | 0;
+   i16 = i16 + 32 | 0;
+   if ((i9 | 0) < (HEAP32[i16 >> 2] | 0)) {
+    i15 = HEAP32[i10 >> 2] | 0;
+   } else {
+    i15 = _luaM_growaux_(HEAP32[i15 >> 2] | 0, HEAP32[i10 >> 2] | 0, i16, 16, 32767, 6312) | 0;
+    HEAP32[i10 >> 2] = i15;
+   }
+   HEAP32[i15 + (i9 << 4) >> 2] = i14;
+   i16 = HEAP32[i10 >> 2] | 0;
+   HEAP32[i16 + (i9 << 4) + 8 >> 2] = 0;
+   HEAP8[i16 + (i9 << 4) + 12 | 0] = HEAP8[(HEAP32[i8 >> 2] | 0) + 46 | 0] | 0;
+   HEAP32[(HEAP32[i10 >> 2] | 0) + (i9 << 4) + 4 >> 2] = i11;
+   HEAP32[i12 >> 2] = (HEAP32[i12 >> 2] | 0) + 1;
+   i10 = HEAP32[i13 >> 2] | 0;
+   i9 = (HEAP32[i10 + 24 >> 2] | 0) + (i9 << 4) | 0;
+   i11 = HEAP16[(HEAP32[(HEAP32[i8 >> 2] | 0) + 16 >> 2] | 0) + 6 >> 1] | 0;
+   i8 = i10 + 16 | 0;
+   if ((i11 | 0) < (HEAP32[i8 >> 2] | 0)) {
+    i10 = i10 + 12 | 0;
+    do {
+     while (1) {
+      if ((_luaS_eqstr(HEAP32[(HEAP32[i10 >> 2] | 0) + (i11 << 4) >> 2] | 0, HEAP32[i9 >> 2] | 0) | 0) == 0) {
+       break;
+      }
+      _closegoto(i6, i11, i9);
+      if ((i11 | 0) >= (HEAP32[i8 >> 2] | 0)) {
+       break L5;
+      }
+     }
+     i11 = i11 + 1 | 0;
+    } while ((i11 | 0) < (HEAP32[i8 >> 2] | 0));
+   }
+  }
+ } while (0);
+ HEAP32[i7 >> 2] = HEAP32[i4 >> 2];
+ i7 = i4 + 8 | 0;
+ i9 = HEAP8[i7] | 0;
+ i10 = i1 + 46 | 0;
+ i8 = (HEAP32[i2 >> 2] | 0) + 64 | 0;
+ i14 = (HEAP32[i8 >> 2] | 0) + 4 | 0;
+ HEAP32[i14 >> 2] = (i9 & 255) - (HEAPU8[i10] | 0) + (HEAP32[i14 >> 2] | 0);
+ i14 = HEAP8[i10] | 0;
+ if ((i14 & 255) > (i9 & 255)) {
+  i13 = i1 + 20 | 0;
+  i11 = i1 + 40 | 0;
+  i12 = (HEAP32[i1 >> 2] | 0) + 24 | 0;
+  do {
+   i16 = HEAP32[i13 >> 2] | 0;
+   i14 = i14 + -1 << 24 >> 24;
+   HEAP8[i10] = i14;
+   HEAP32[(HEAP32[i12 >> 2] | 0) + ((HEAP16[(HEAP32[HEAP32[i8 >> 2] >> 2] | 0) + ((HEAP32[i11 >> 2] | 0) + (i14 & 255) << 1) >> 1] | 0) * 12 | 0) + 8 >> 2] = i16;
+   i14 = HEAP8[i10] | 0;
+  } while ((i14 & 255) > (i9 & 255));
+ }
+ HEAP8[i1 + 48 | 0] = i14;
+ i10 = HEAP32[i6 + 64 >> 2] | 0;
+ HEAP32[i10 + 28 >> 2] = HEAP16[i4 + 4 >> 1] | 0;
+ i9 = HEAP16[i4 + 6 >> 1] | 0;
+ if ((HEAP32[i4 >> 2] | 0) == 0) {
+  if ((i9 | 0) >= (HEAP32[i10 + 16 >> 2] | 0)) {
+   STACKTOP = i3;
+   return;
+  }
+  i10 = HEAP32[i10 + 12 >> 2] | 0;
+  i11 = HEAP32[i10 + (i9 << 4) >> 2] | 0;
+  if ((HEAP8[i11 + 4 | 0] | 0) != 4) {
+   i16 = 6200;
+   i15 = i6 + 52 | 0;
+   i15 = HEAP32[i15 >> 2] | 0;
+   i14 = i11 + 16 | 0;
+   i13 = i10 + (i9 << 4) + 8 | 0;
+   i13 = HEAP32[i13 >> 2] | 0;
+   HEAP32[i5 >> 2] = i14;
+   i14 = i5 + 4 | 0;
+   HEAP32[i14 >> 2] = i13;
+   i16 = _luaO_pushfstring(i15, i16, i5) | 0;
+   _semerror(i6, i16);
+  }
+  i16 = (HEAP8[i11 + 6 | 0] | 0) != 0 ? 6160 : 6200;
+  i15 = i6 + 52 | 0;
+  i15 = HEAP32[i15 >> 2] | 0;
+  i14 = i11 + 16 | 0;
+  i13 = i10 + (i9 << 4) + 8 | 0;
+  i13 = HEAP32[i13 >> 2] | 0;
+  HEAP32[i5 >> 2] = i14;
+  i14 = i5 + 4 | 0;
+  HEAP32[i14 >> 2] = i13;
+  i16 = _luaO_pushfstring(i15, i16, i5) | 0;
+  _semerror(i6, i16);
+ }
+ i6 = HEAP32[i8 >> 2] | 0;
+ i5 = i6 + 16 | 0;
+ if ((i9 | 0) >= (HEAP32[i5 >> 2] | 0)) {
+  STACKTOP = i3;
+  return;
+ }
+ i6 = i6 + 12 | 0;
+ i4 = i4 + 9 | 0;
+ do {
+  i10 = HEAP32[i6 >> 2] | 0;
+  i8 = i10 + (i9 << 4) + 12 | 0;
+  i11 = HEAP8[i7] | 0;
+  i12 = i11 & 255;
+  if ((HEAPU8[i8] | 0) > (i11 & 255)) {
+   if ((HEAP8[i4] | 0) != 0) {
+    _luaK_patchclose(i1, HEAP32[i10 + (i9 << 4) + 4 >> 2] | 0, i12);
+    i11 = HEAP8[i7] | 0;
+   }
+   HEAP8[i8] = i11;
+  }
+  i9 = ((_findlabel(HEAP32[i2 >> 2] | 0, i9) | 0) == 0) + i9 | 0;
+ } while ((i9 | 0) < (HEAP32[i5 >> 2] | 0));
+ STACKTOP = i3;
+ return;
+}
+function _getobjname(i3, i7, i9, i2) {
+ i3 = i3 | 0;
+ i7 = i7 | 0;
+ i9 = i9 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i1 = STACKTOP;
+ i4 = i3 + 12 | 0;
+ L1 : while (1) {
+  i13 = _luaF_getlocalname(i3, i9 + 1 | 0, i7) | 0;
+  HEAP32[i2 >> 2] = i13;
+  if ((i13 | 0) != 0) {
+   i2 = 2040;
+   i4 = 42;
+   break;
+  }
+  if ((i7 | 0) <= 0) {
+   i2 = 0;
+   i4 = 42;
+   break;
+  }
+  i6 = HEAP32[i4 >> 2] | 0;
+  i8 = 0;
+  i5 = -1;
+  do {
+   i12 = HEAP32[i6 + (i8 << 2) >> 2] | 0;
+   i13 = i12 & 63;
+   i11 = i12 >>> 6 & 255;
+   switch (i13 | 0) {
+   case 27:
+    {
+     i10 = i8;
+     i5 = (i11 | 0) == (i9 | 0) ? i8 : i5;
+     break;
+    }
+   case 30:
+   case 29:
+    {
+     i10 = i8;
+     i5 = (i11 | 0) > (i9 | 0) ? i5 : i8;
+     break;
+    }
+   case 23:
+    {
+     i10 = (i12 >>> 14) + -131071 | 0;
+     i13 = i8 + 1 + i10 | 0;
+     i10 = ((i8 | 0) >= (i13 | 0) | (i13 | 0) > (i7 | 0) ? 0 : i10) + i8 | 0;
+     break;
+    }
+   case 4:
+    {
+     if ((i11 | 0) > (i9 | 0)) {
+      i10 = i8;
+     } else {
+      i10 = i8;
+      i5 = (i11 + (i12 >>> 23) | 0) < (i9 | 0) ? i5 : i8;
+     }
+     break;
+    }
+   case 34:
+    {
+     i10 = i8;
+     i5 = (i11 + 2 | 0) > (i9 | 0) ? i5 : i8;
+     break;
+    }
+   default:
+    {
+     i10 = i8;
+     i5 = (HEAP8[5584 + i13 | 0] & 64) != 0 & (i11 | 0) == (i9 | 0) ? i8 : i5;
+    }
+   }
+   i8 = i10 + 1 | 0;
+  } while ((i8 | 0) < (i7 | 0));
+  if ((i5 | 0) == -1) {
+   i2 = 0;
+   i4 = 42;
+   break;
+  }
+  i7 = HEAP32[i6 + (i5 << 2) >> 2] | 0;
+  i9 = i7 & 63;
+  switch (i9 | 0) {
+  case 0:
+   {
+    break;
+   }
+  case 7:
+  case 6:
+   {
+    i4 = 17;
+    break L1;
+   }
+  case 5:
+   {
+    i4 = 29;
+    break L1;
+   }
+  case 1:
+   {
+    i4 = 32;
+    break L1;
+   }
+  case 2:
+   {
+    i4 = 33;
+    break L1;
+   }
+  case 12:
+   {
+    i4 = 36;
+    break L1;
+   }
+  default:
+   {
+    i2 = 0;
+    i4 = 42;
+    break L1;
+   }
+  }
+  i9 = i7 >>> 23;
+  if (i9 >>> 0 < (i7 >>> 6 & 255) >>> 0) {
+   i7 = i5;
+  } else {
+   i2 = 0;
+   i4 = 42;
+   break;
+  }
+ }
+ if ((i4 | 0) == 17) {
+  i6 = i7 >>> 14;
+  i8 = i6 & 511;
+  i7 = i7 >>> 23;
+  if ((i9 | 0) != 7) {
+   i7 = HEAP32[(HEAP32[i3 + 28 >> 2] | 0) + (i7 << 3) >> 2] | 0;
+   if ((i7 | 0) == 0) {
+    i7 = 2104;
+   } else {
+    i7 = i7 + 16 | 0;
+   }
+  } else {
+   i7 = _luaF_getlocalname(i3, i7 + 1 | 0, i5) | 0;
+  }
+  if ((i6 & 256 | 0) == 0) {
+   i3 = _getobjname(i3, i5, i8, i2) | 0;
+   if (!((i3 | 0) != 0 ? (HEAP8[i3] | 0) == 99 : 0)) {
+    i4 = 26;
+   }
+  } else {
+   i5 = i6 & 255;
+   i3 = HEAP32[i3 + 8 >> 2] | 0;
+   if ((HEAP32[i3 + (i5 << 4) + 8 >> 2] & 15 | 0) == 4) {
+    HEAP32[i2 >> 2] = (HEAP32[i3 + (i5 << 4) >> 2] | 0) + 16;
+   } else {
+    i4 = 26;
+   }
+  }
+  if ((i4 | 0) == 26) {
+   HEAP32[i2 >> 2] = 2104;
+  }
+  if ((i7 | 0) == 0) {
+   i13 = 2064;
+   STACKTOP = i1;
+   return i13 | 0;
+  }
+  i13 = (_strcmp(i7, 2048) | 0) == 0;
+  i13 = i13 ? 2056 : 2064;
+  STACKTOP = i1;
+  return i13 | 0;
+ } else if ((i4 | 0) == 29) {
+  i3 = HEAP32[(HEAP32[i3 + 28 >> 2] | 0) + (i7 >>> 23 << 3) >> 2] | 0;
+  if ((i3 | 0) == 0) {
+   i3 = 2104;
+  } else {
+   i3 = i3 + 16 | 0;
+  }
+  HEAP32[i2 >> 2] = i3;
+  i13 = 2072;
+  STACKTOP = i1;
+  return i13 | 0;
+ } else if ((i4 | 0) == 32) {
+  i5 = i7 >>> 14;
+ } else if ((i4 | 0) == 33) {
+  i5 = (HEAP32[i6 + (i5 + 1 << 2) >> 2] | 0) >>> 6;
+ } else if ((i4 | 0) == 36) {
+  i4 = i7 >>> 14;
+  if ((i4 & 256 | 0) == 0) {
+   i3 = _getobjname(i3, i5, i4 & 511, i2) | 0;
+   if ((i3 | 0) != 0 ? (HEAP8[i3] | 0) == 99 : 0) {
+    i13 = 2096;
+    STACKTOP = i1;
+    return i13 | 0;
+   }
+  } else {
+   i4 = i4 & 255;
+   i3 = HEAP32[i3 + 8 >> 2] | 0;
+   if ((HEAP32[i3 + (i4 << 4) + 8 >> 2] & 15 | 0) == 4) {
+    HEAP32[i2 >> 2] = (HEAP32[i3 + (i4 << 4) >> 2] | 0) + 16;
+    i13 = 2096;
+    STACKTOP = i1;
+    return i13 | 0;
+   }
+  }
+  HEAP32[i2 >> 2] = 2104;
+  i13 = 2096;
+  STACKTOP = i1;
+  return i13 | 0;
+ } else if ((i4 | 0) == 42) {
+  STACKTOP = i1;
+  return i2 | 0;
+ }
+ i3 = HEAP32[i3 + 8 >> 2] | 0;
+ if ((HEAP32[i3 + (i5 << 4) + 8 >> 2] & 15 | 0) != 4) {
+  i13 = 0;
+  STACKTOP = i1;
+  return i13 | 0;
+ }
+ HEAP32[i2 >> 2] = (HEAP32[i3 + (i5 << 4) >> 2] | 0) + 16;
+ i13 = 2080;
+ STACKTOP = i1;
+ return i13 | 0;
+}
+function _assignment(i2, i16, i5) {
+ i2 = i2 | 0;
+ i16 = i16 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 80 | 0;
+ i6 = i3 + 56 | 0;
+ i1 = i3 + 32 | 0;
+ i8 = i3;
+ i4 = i16 + 8 | 0;
+ if (!(((HEAP32[i4 >> 2] | 0) + -7 | 0) >>> 0 < 3)) {
+  _luaX_syntaxerror(i2, 6344);
+ }
+ i13 = i2 + 16 | 0;
+ i14 = HEAP32[i13 >> 2] | 0;
+ do {
+  if ((i14 | 0) == 44) {
+   _luaX_next(i2);
+   HEAP32[i8 >> 2] = i16;
+   i14 = i8 + 8 | 0;
+   _suffixedexp(i2, i14);
+   i15 = i2 + 48 | 0;
+   if ((HEAP32[i14 >> 2] | 0) != 9 ? (i10 = HEAP32[i15 >> 2] | 0, i11 = HEAP8[i10 + 48 | 0] | 0, i9 = i11 & 255, (i16 | 0) != 0) : 0) {
+    i13 = i8 + 16 | 0;
+    i12 = i11 & 255;
+    i18 = 0;
+    do {
+     if ((HEAP32[i16 + 8 >> 2] | 0) == 9) {
+      i17 = i16 + 16 | 0;
+      i19 = i17 + 3 | 0;
+      i20 = HEAPU8[i19] | 0;
+      i21 = HEAP32[i14 >> 2] | 0;
+      if ((i20 | 0) == (i21 | 0)) {
+       i21 = i17 + 2 | 0;
+       if ((HEAPU8[i21] | 0) == (HEAP32[i13 >> 2] | 0)) {
+        HEAP8[i19] = 7;
+        HEAP8[i21] = i11;
+        i20 = HEAP32[i14 >> 2] | 0;
+        i18 = 1;
+       }
+      } else {
+       i20 = i21;
+      }
+      if ((i20 | 0) == 7 ? (HEAP16[i17 >> 1] | 0) == (HEAP32[i13 >> 2] | 0) : 0) {
+       HEAP16[i17 >> 1] = i12;
+       i18 = 1;
+      }
+     }
+     i16 = HEAP32[i16 >> 2] | 0;
+    } while ((i16 | 0) != 0);
+    if ((i18 | 0) != 0) {
+     _luaK_codeABC(i10, (HEAP32[i14 >> 2] | 0) == 7 ? 0 : 5, i9, HEAP32[i13 >> 2] | 0, 0) | 0;
+     _luaK_reserveregs(i10, 1);
+    }
+   }
+   i9 = HEAP32[i15 >> 2] | 0;
+   if (((HEAPU16[(HEAP32[i2 + 52 >> 2] | 0) + 38 >> 1] | 0) + i5 | 0) <= 200) {
+    _assignment(i2, i8, i5 + 1 | 0);
+    i7 = i1;
+    break;
+   }
+   i8 = i9 + 12 | 0;
+   i5 = HEAP32[(HEAP32[i8 >> 2] | 0) + 52 >> 2] | 0;
+   i9 = HEAP32[(HEAP32[i9 >> 2] | 0) + 64 >> 2] | 0;
+   if ((i9 | 0) == 0) {
+    i20 = 6552;
+    HEAP32[i6 >> 2] = 6360;
+    i21 = i6 + 4 | 0;
+    HEAP32[i21 >> 2] = 200;
+    i21 = i6 + 8 | 0;
+    HEAP32[i21 >> 2] = i20;
+    i21 = _luaO_pushfstring(i5, 6592, i6) | 0;
+    i20 = HEAP32[i8 >> 2] | 0;
+    _luaX_syntaxerror(i20, i21);
+   }
+   HEAP32[i6 >> 2] = i9;
+   i20 = _luaO_pushfstring(i5, 6568, i6) | 0;
+   HEAP32[i6 >> 2] = 6360;
+   i21 = i6 + 4 | 0;
+   HEAP32[i21 >> 2] = 200;
+   i21 = i6 + 8 | 0;
+   HEAP32[i21 >> 2] = i20;
+   i21 = _luaO_pushfstring(i5, 6592, i6) | 0;
+   i20 = HEAP32[i8 >> 2] | 0;
+   _luaX_syntaxerror(i20, i21);
+  } else if ((i14 | 0) == 61) {
+   _luaX_next(i2);
+   _subexpr(i2, i1, 0) | 0;
+   i6 = i2 + 48 | 0;
+   if ((HEAP32[i13 >> 2] | 0) == 44) {
+    i9 = 1;
+    do {
+     _luaX_next(i2);
+     _luaK_exp2nextreg(HEAP32[i6 >> 2] | 0, i1);
+     _subexpr(i2, i1, 0) | 0;
+     i9 = i9 + 1 | 0;
+    } while ((HEAP32[i13 >> 2] | 0) == 44);
+   } else {
+    i9 = 1;
+   }
+   i8 = HEAP32[i6 >> 2] | 0;
+   if ((i9 | 0) == (i5 | 0)) {
+    _luaK_setoneret(i8, i1);
+    _luaK_storevar(HEAP32[i6 >> 2] | 0, i4, i1);
+    STACKTOP = i3;
+    return;
+   }
+   i7 = i5 - i9 | 0;
+   i10 = HEAP32[i1 >> 2] | 0;
+   if ((i10 | 0) == 13 | (i10 | 0) == 12) {
+    i10 = i7 + 1 | 0;
+    i10 = (i10 | 0) < 0 ? 0 : i10;
+    _luaK_setreturns(i8, i1, i10);
+    if ((i10 | 0) > 1) {
+     _luaK_reserveregs(i8, i10 + -1 | 0);
+    }
+   } else if ((i10 | 0) == 0) {
+    i12 = 30;
+   } else {
+    _luaK_exp2nextreg(i8, i1);
+    i12 = 30;
+   }
+   if ((i12 | 0) == 30 ? (i7 | 0) > 0 : 0) {
+    i21 = HEAPU8[i8 + 48 | 0] | 0;
+    _luaK_reserveregs(i8, i7);
+    _luaK_nil(i8, i21, i7);
+   }
+   if ((i9 | 0) > (i5 | 0)) {
+    i21 = (HEAP32[i6 >> 2] | 0) + 48 | 0;
+    HEAP8[i21] = i7 + (HEAPU8[i21] | 0);
+    i7 = i1;
+   } else {
+    i7 = i1;
+   }
+  } else {
+   _error_expected(i2, 61);
+  }
+ } while (0);
+ i21 = HEAP32[i2 + 48 >> 2] | 0;
+ i20 = (HEAPU8[i21 + 48 | 0] | 0) + -1 | 0;
+ HEAP32[i1 + 16 >> 2] = -1;
+ HEAP32[i1 + 20 >> 2] = -1;
+ HEAP32[i7 >> 2] = 6;
+ HEAP32[i1 + 8 >> 2] = i20;
+ _luaK_storevar(i21, i4, i1);
+ STACKTOP = i3;
+ return;
+}
+function _str_find_aux(i3, i7) {
+ i3 = i3 | 0;
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 288 | 0;
+ i9 = i1 + 284 | 0;
+ i5 = i1 + 280 | 0;
+ i4 = i1;
+ i2 = _luaL_checklstring(i3, 1, i9) | 0;
+ i8 = _luaL_checklstring(i3, 2, i5) | 0;
+ i12 = _luaL_optinteger(i3, 3, 1) | 0;
+ i10 = HEAP32[i9 >> 2] | 0;
+ if (!((i12 | 0) > -1)) {
+  if (i10 >>> 0 < (0 - i12 | 0) >>> 0) {
+   i12 = 1;
+  } else {
+   i12 = i12 + 1 + i10 | 0;
+   i6 = 4;
+  }
+ } else {
+  i6 = 4;
+ }
+ if ((i6 | 0) == 4) {
+  if ((i12 | 0) != 0) {
+   if (i12 >>> 0 > (i10 + 1 | 0) >>> 0) {
+    _lua_pushnil(i3);
+    i13 = 1;
+    STACKTOP = i1;
+    return i13 | 0;
+   }
+  } else {
+   i12 = 1;
+  }
+ }
+ i7 = (i7 | 0) != 0;
+ L10 : do {
+  if (i7) {
+   i13 = (_lua_toboolean(i3, 4) | 0) == 0;
+   i10 = HEAP32[i5 >> 2] | 0;
+   if (i13) {
+    i11 = 0;
+    do {
+     i13 = i8 + i11 | 0;
+     if ((_strpbrk(i13, 7512) | 0) != 0) {
+      i6 = 20;
+      break L10;
+     }
+     i11 = i11 + 1 + (_strlen(i13 | 0) | 0) | 0;
+    } while (!(i11 >>> 0 > i10 >>> 0));
+   }
+   i11 = i2 + (i12 + -1) | 0;
+   i9 = (HEAP32[i9 >> 2] | 0) - i12 + 1 | 0;
+   L17 : do {
+    if ((i10 | 0) == 0) {
+     if ((i11 | 0) == 0) {
+      break L10;
+     }
+    } else {
+     if (i10 >>> 0 > i9 >>> 0) {
+      break L10;
+     }
+     i4 = i10 + -1 | 0;
+     if ((i4 | 0) == (i9 | 0)) {
+      break L10;
+     }
+     i7 = HEAP8[i8] | 0;
+     i8 = i8 + 1 | 0;
+     i9 = i9 - i4 | 0;
+     i12 = i11;
+     while (1) {
+      i11 = _memchr(i12, i7, i9) | 0;
+      if ((i11 | 0) == 0) {
+       break L10;
+      }
+      i10 = i11 + 1 | 0;
+      if ((_memcmp(i10, i8, i4) | 0) == 0) {
+       break L17;
+      }
+      i11 = i10;
+      i9 = i12 + i9 | 0;
+      if ((i9 | 0) == (i11 | 0)) {
+       break L10;
+      } else {
+       i9 = i9 - i11 | 0;
+       i12 = i10;
+      }
+     }
+    }
+   } while (0);
+   i13 = i11 - i2 | 0;
+   _lua_pushinteger(i3, i13 + 1 | 0);
+   _lua_pushinteger(i3, i13 + (HEAP32[i5 >> 2] | 0) | 0);
+   i13 = 2;
+   STACKTOP = i1;
+   return i13 | 0;
+  } else {
+   i6 = 20;
+  }
+ } while (0);
+ L28 : do {
+  if ((i6 | 0) == 20) {
+   i6 = i2 + (i12 + -1) | 0;
+   i10 = (HEAP8[i8] | 0) == 94;
+   if (i10) {
+    i12 = (HEAP32[i5 >> 2] | 0) + -1 | 0;
+    HEAP32[i5 >> 2] = i12;
+    i8 = i8 + 1 | 0;
+   } else {
+    i12 = HEAP32[i5 >> 2] | 0;
+   }
+   i5 = i4 + 16 | 0;
+   HEAP32[i5 >> 2] = i3;
+   HEAP32[i4 >> 2] = 200;
+   HEAP32[i4 + 4 >> 2] = i2;
+   i11 = i4 + 8 | 0;
+   HEAP32[i11 >> 2] = i2 + (HEAP32[i9 >> 2] | 0);
+   HEAP32[i4 + 12 >> 2] = i8 + i12;
+   i9 = i4 + 20 | 0;
+   L34 : do {
+    if (i10) {
+     HEAP32[i9 >> 2] = 0;
+     i8 = _match(i4, i6, i8) | 0;
+     if ((i8 | 0) == 0) {
+      break L28;
+     }
+    } else {
+     while (1) {
+      HEAP32[i9 >> 2] = 0;
+      i10 = _match(i4, i6, i8) | 0;
+      if ((i10 | 0) != 0) {
+       i8 = i10;
+       break L34;
+      }
+      if (!(i6 >>> 0 < (HEAP32[i11 >> 2] | 0) >>> 0)) {
+       break L28;
+      }
+      i6 = i6 + 1 | 0;
+     }
+    }
+   } while (0);
+   if (i7) {
+    _lua_pushinteger(i3, 1 - i2 + i6 | 0);
+    _lua_pushinteger(i3, i8 - i2 | 0);
+    i2 = HEAP32[i9 >> 2] | 0;
+    _luaL_checkstack(HEAP32[i5 >> 2] | 0, i2, 7200);
+    if ((i2 | 0) > 0) {
+     i3 = 0;
+     do {
+      _push_onecapture(i4, i3, 0, 0);
+      i3 = i3 + 1 | 0;
+     } while ((i3 | 0) != (i2 | 0));
+    }
+    i13 = i2 + 2 | 0;
+    STACKTOP = i1;
+    return i13 | 0;
+   } else {
+    i3 = HEAP32[i9 >> 2] | 0;
+    i2 = (i3 | 0) != 0 | (i6 | 0) == 0 ? i3 : 1;
+    _luaL_checkstack(HEAP32[i5 >> 2] | 0, i2, 7200);
+    if ((i2 | 0) > 0) {
+     i3 = 0;
+    } else {
+     i13 = i3;
+     STACKTOP = i1;
+     return i13 | 0;
+    }
+    do {
+     _push_onecapture(i4, i3, i6, i8);
+     i3 = i3 + 1 | 0;
+    } while ((i3 | 0) != (i2 | 0));
+    STACKTOP = i1;
+    return i2 | 0;
+   }
+  }
+ } while (0);
+ _lua_pushnil(i3);
+ i13 = 1;
+ STACKTOP = i1;
+ return i13 | 0;
+}
+function _luaO_pushvfstring(i2, i13, i10) {
+ i2 = i2 | 0;
+ i13 = i13 | 0;
+ i10 = i10 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i11 = 0, i12 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, d18 = 0.0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 48 | 0;
+ i7 = i3;
+ i9 = i3 + 32 | 0;
+ i8 = i3 + 8 | 0;
+ i14 = _strchr(i13, 37) | 0;
+ i6 = i2 + 24 | 0;
+ i4 = i2 + 8 | 0;
+ i15 = HEAP32[i4 >> 2] | 0;
+ i17 = (HEAP32[i6 >> 2] | 0) - i15 | 0;
+ L1 : do {
+  if ((i14 | 0) == 0) {
+   i5 = i13;
+   i11 = i17;
+   i12 = i15;
+   i1 = 0;
+  } else {
+   i16 = 0;
+   L3 : while (1) {
+    if ((i17 | 0) < 48) {
+     _luaD_growstack(i2, 2);
+     i15 = HEAP32[i4 >> 2] | 0;
+    }
+    HEAP32[i4 >> 2] = i15 + 16;
+    i13 = _luaS_newlstr(i2, i13, i14 - i13 | 0) | 0;
+    HEAP32[i15 >> 2] = i13;
+    HEAP32[i15 + 8 >> 2] = HEAPU8[i13 + 4 | 0] | 64;
+    i13 = HEAP8[i14 + 1 | 0] | 0;
+    switch (i13 | 0) {
+    case 115:
+     {
+      i17 = HEAP32[i10 >> 2] | 0;
+      i13 = HEAP32[i17 >> 2] | 0;
+      HEAP32[i10 >> 2] = i17 + 4;
+      i13 = (i13 | 0) == 0 ? 5480 : i13;
+      i15 = _strlen(i13 | 0) | 0;
+      i17 = HEAP32[i4 >> 2] | 0;
+      HEAP32[i4 >> 2] = i17 + 16;
+      i15 = _luaS_newlstr(i2, i13, i15) | 0;
+      HEAP32[i17 >> 2] = i15;
+      HEAP32[i17 + 8 >> 2] = HEAPU8[i15 + 4 | 0] | 64;
+      break;
+     }
+    case 100:
+     {
+      i17 = HEAP32[i4 >> 2] | 0;
+      HEAP32[i4 >> 2] = i17 + 16;
+      i13 = HEAP32[i10 >> 2] | 0;
+      i15 = HEAP32[i13 >> 2] | 0;
+      HEAP32[i10 >> 2] = i13 + 4;
+      HEAPF64[i17 >> 3] = +(i15 | 0);
+      HEAP32[i17 + 8 >> 2] = 3;
+      break;
+     }
+    case 37:
+     {
+      i17 = HEAP32[i4 >> 2] | 0;
+      HEAP32[i4 >> 2] = i17 + 16;
+      i15 = _luaS_newlstr(i2, 5496, 1) | 0;
+      HEAP32[i17 >> 2] = i15;
+      HEAP32[i17 + 8 >> 2] = HEAPU8[i15 + 4 | 0] | 64;
+      break;
+     }
+    case 99:
+     {
+      i15 = HEAP32[i10 >> 2] | 0;
+      i17 = HEAP32[i15 >> 2] | 0;
+      HEAP32[i10 >> 2] = i15 + 4;
+      HEAP8[i9] = i17;
+      i17 = HEAP32[i4 >> 2] | 0;
+      HEAP32[i4 >> 2] = i17 + 16;
+      i15 = _luaS_newlstr(i2, i9, 1) | 0;
+      HEAP32[i17 >> 2] = i15;
+      HEAP32[i17 + 8 >> 2] = HEAPU8[i15 + 4 | 0] | 64;
+      break;
+     }
+    case 102:
+     {
+      i17 = HEAP32[i4 >> 2] | 0;
+      HEAP32[i4 >> 2] = i17 + 16;
+      i15 = HEAP32[i10 >> 2] | 0;
+      d18 = +HEAPF64[i15 >> 3];
+      HEAP32[i10 >> 2] = i15 + 8;
+      HEAPF64[i17 >> 3] = d18;
+      HEAP32[i17 + 8 >> 2] = 3;
+      break;
+     }
+    case 112:
+     {
+      i17 = HEAP32[i10 >> 2] | 0;
+      i15 = HEAP32[i17 >> 2] | 0;
+      HEAP32[i10 >> 2] = i17 + 4;
+      HEAP32[i7 >> 2] = i15;
+      i15 = _sprintf(i8 | 0, 5488, i7 | 0) | 0;
+      i17 = HEAP32[i4 >> 2] | 0;
+      HEAP32[i4 >> 2] = i17 + 16;
+      i15 = _luaS_newlstr(i2, i8, i15) | 0;
+      HEAP32[i17 >> 2] = i15;
+      HEAP32[i17 + 8 >> 2] = HEAPU8[i15 + 4 | 0] | 64;
+      break;
+     }
+    default:
+     {
+      break L3;
+     }
+    }
+    i16 = i16 + 2 | 0;
+    i13 = i14 + 2 | 0;
+    i14 = _strchr(i13, 37) | 0;
+    i15 = HEAP32[i4 >> 2] | 0;
+    i17 = (HEAP32[i6 >> 2] | 0) - i15 | 0;
+    if ((i14 | 0) == 0) {
+     i5 = i13;
+     i11 = i17;
+     i12 = i15;
+     i1 = i16;
+     break L1;
+    }
+   }
+   HEAP32[i7 >> 2] = i13;
+   _luaG_runerror(i2, 5504, i7);
+  }
+ } while (0);
+ if ((i11 | 0) < 32) {
+  _luaD_growstack(i2, 1);
+  i12 = HEAP32[i4 >> 2] | 0;
+ }
+ i17 = _strlen(i5 | 0) | 0;
+ HEAP32[i4 >> 2] = i12 + 16;
+ i17 = _luaS_newlstr(i2, i5, i17) | 0;
+ HEAP32[i12 >> 2] = i17;
+ HEAP32[i12 + 8 >> 2] = HEAPU8[i17 + 4 | 0] | 64;
+ if ((i1 | 0) <= 0) {
+  i17 = HEAP32[i4 >> 2] | 0;
+  i17 = i17 + -16 | 0;
+  i17 = HEAP32[i17 >> 2] | 0;
+  i17 = i17 + 16 | 0;
+  STACKTOP = i3;
+  return i17 | 0;
+ }
+ _luaV_concat(i2, i1 | 1);
+ i17 = HEAP32[i4 >> 2] | 0;
+ i17 = i17 + -16 | 0;
+ i17 = HEAP32[i17 >> 2] | 0;
+ i17 = i17 + 16 | 0;
+ STACKTOP = i3;
+ return i17 | 0;
+}
+function _luaH_getn(i6) {
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, d11 = 0.0, i12 = 0, i13 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i1;
+ i3 = i6 + 28 | 0;
+ i12 = HEAP32[i3 >> 2] | 0;
+ if ((i12 | 0) != 0 ? (i4 = HEAP32[i6 + 12 >> 2] | 0, (HEAP32[i4 + (i12 + -1 << 4) + 8 >> 2] | 0) == 0) : 0) {
+  if (i12 >>> 0 > 1) {
+   i10 = 0;
+  } else {
+   i13 = 0;
+   STACKTOP = i1;
+   return i13 | 0;
+  }
+  do {
+   i2 = (i10 + i12 | 0) >>> 1;
+   i3 = (HEAP32[i4 + (i2 + -1 << 4) + 8 >> 2] | 0) == 0;
+   i12 = i3 ? i2 : i12;
+   i10 = i3 ? i10 : i2;
+  } while ((i12 - i10 | 0) >>> 0 > 1);
+  STACKTOP = i1;
+  return i10 | 0;
+ }
+ i4 = i6 + 16 | 0;
+ if ((HEAP32[i4 >> 2] | 0) == 8016) {
+  i13 = i12;
+  STACKTOP = i1;
+  return i13 | 0;
+ }
+ i5 = i6 + 12 | 0;
+ i6 = i6 + 7 | 0;
+ i9 = i2 + 4 | 0;
+ i8 = i12 + 1 | 0;
+ i13 = i12;
+ i10 = i12;
+ while (1) {
+  i12 = i8 + -1 | 0;
+  L15 : do {
+   if (i12 >>> 0 < i13 >>> 0) {
+    i12 = (HEAP32[i5 >> 2] | 0) + (i12 << 4) | 0;
+   } else {
+    d11 = +(i8 | 0);
+    HEAPF64[i2 >> 3] = d11 + 1.0;
+    i13 = (HEAP32[i9 >> 2] | 0) + (HEAP32[i2 >> 2] | 0) | 0;
+    if ((i13 | 0) < 0) {
+     i12 = 0 - i13 | 0;
+     i13 = (i13 | 0) == (i12 | 0) ? 0 : i12;
+    }
+    i12 = (HEAP32[i4 >> 2] | 0) + (((i13 | 0) % ((1 << (HEAPU8[i6] | 0)) + -1 | 1 | 0) | 0) << 5) | 0;
+    while (1) {
+     if ((HEAP32[i12 + 24 >> 2] | 0) == 3 ? +HEAPF64[i12 + 16 >> 3] == d11 : 0) {
+      break;
+     }
+     i12 = HEAP32[i12 + 28 >> 2] | 0;
+     if ((i12 | 0) == 0) {
+      i12 = 5192;
+      break L15;
+     }
+    }
+   }
+  } while (0);
+  if ((HEAP32[i12 + 8 >> 2] | 0) == 0) {
+   break;
+  }
+  i10 = i8 << 1;
+  if (i10 >>> 0 > 2147483645) {
+   i7 = 21;
+   break;
+  }
+  i12 = i8;
+  i8 = i10;
+  i13 = HEAP32[i3 >> 2] | 0;
+  i10 = i12;
+ }
+ if ((i7 | 0) == 21) {
+  i8 = i2 + 4 | 0;
+  i7 = 1;
+  while (1) {
+   i10 = i7 + -1 | 0;
+   L34 : do {
+    if (i10 >>> 0 < (HEAP32[i3 >> 2] | 0) >>> 0) {
+     i9 = (HEAP32[i5 >> 2] | 0) + (i10 << 4) | 0;
+    } else {
+     d11 = +(i7 | 0);
+     HEAPF64[i2 >> 3] = d11 + 1.0;
+     i9 = (HEAP32[i8 >> 2] | 0) + (HEAP32[i2 >> 2] | 0) | 0;
+     if ((i9 | 0) < 0) {
+      i12 = 0 - i9 | 0;
+      i9 = (i9 | 0) == (i12 | 0) ? 0 : i12;
+     }
+     i9 = (HEAP32[i4 >> 2] | 0) + (((i9 | 0) % ((1 << (HEAPU8[i6] | 0)) + -1 | 1 | 0) | 0) << 5) | 0;
+     while (1) {
+      if ((HEAP32[i9 + 24 >> 2] | 0) == 3 ? +HEAPF64[i9 + 16 >> 3] == d11 : 0) {
+       break;
+      }
+      i9 = HEAP32[i9 + 28 >> 2] | 0;
+      if ((i9 | 0) == 0) {
+       i9 = 5192;
+       break L34;
+      }
+     }
+    }
+   } while (0);
+   if ((HEAP32[i9 + 8 >> 2] | 0) == 0) {
+    break;
+   }
+   i7 = i7 + 1 | 0;
+  }
+  STACKTOP = i1;
+  return i10 | 0;
+ }
+ if (!((i8 - i10 | 0) >>> 0 > 1)) {
+  i13 = i10;
+  STACKTOP = i1;
+  return i13 | 0;
+ }
+ i7 = i2 + 4 | 0;
+ do {
+  i9 = (i8 + i10 | 0) >>> 1;
+  i12 = i9 + -1 | 0;
+  L55 : do {
+   if (i12 >>> 0 < (HEAP32[i3 >> 2] | 0) >>> 0) {
+    i12 = (HEAP32[i5 >> 2] | 0) + (i12 << 4) | 0;
+   } else {
+    d11 = +(i9 | 0);
+    HEAPF64[i2 >> 3] = d11 + 1.0;
+    i13 = (HEAP32[i7 >> 2] | 0) + (HEAP32[i2 >> 2] | 0) | 0;
+    if ((i13 | 0) < 0) {
+     i12 = 0 - i13 | 0;
+     i13 = (i13 | 0) == (i12 | 0) ? 0 : i12;
+    }
+    i12 = (HEAP32[i4 >> 2] | 0) + (((i13 | 0) % ((1 << (HEAPU8[i6] | 0)) + -1 | 1 | 0) | 0) << 5) | 0;
+    while (1) {
+     if ((HEAP32[i12 + 24 >> 2] | 0) == 3 ? +HEAPF64[i12 + 16 >> 3] == d11 : 0) {
+      break;
+     }
+     i12 = HEAP32[i12 + 28 >> 2] | 0;
+     if ((i12 | 0) == 0) {
+      i12 = 5192;
+      break L55;
+     }
+    }
+   }
+  } while (0);
+  i12 = (HEAP32[i12 + 8 >> 2] | 0) == 0;
+  i8 = i12 ? i9 : i8;
+  i10 = i12 ? i10 : i9;
+ } while ((i8 - i10 | 0) >>> 0 > 1);
+ STACKTOP = i1;
+ return i10 | 0;
+}
+function _lua_resume(i4, i3, i7) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0;
+ i1 = STACKTOP;
+ if ((i3 | 0) == 0) {
+  i5 = 1;
+ } else {
+  i5 = (HEAPU16[i3 + 38 >> 1] | 0) + 1 & 65535;
+ }
+ i3 = i4 + 38 | 0;
+ HEAP16[i3 >> 1] = i5;
+ i5 = i4 + 36 | 0;
+ HEAP16[i5 >> 1] = 0;
+ i6 = i4 + 8 | 0;
+ i13 = _luaD_rawrunprotected(i4, 4, (HEAP32[i6 >> 2] | 0) + (0 - i7 << 4) | 0) | 0;
+ if ((i13 | 0) == -1) {
+  i18 = 2;
+  HEAP16[i5 >> 1] = 1;
+  i17 = HEAP16[i3 >> 1] | 0;
+  i17 = i17 + -1 << 16 >> 16;
+  HEAP16[i3 >> 1] = i17;
+  STACKTOP = i1;
+  return i18 | 0;
+ }
+ if (!(i13 >>> 0 > 1)) {
+  i18 = i13;
+  HEAP16[i5 >> 1] = 1;
+  i17 = HEAP16[i3 >> 1] | 0;
+  i17 = i17 + -1 << 16 >> 16;
+  HEAP16[i3 >> 1] = i17;
+  STACKTOP = i1;
+  return i18 | 0;
+ }
+ i7 = i4 + 16 | 0;
+ i12 = i4 + 28 | 0;
+ i11 = i4 + 41 | 0;
+ i10 = i4 + 68 | 0;
+ i9 = i4 + 32 | 0;
+ i8 = i4 + 12 | 0;
+ L10 : while (1) {
+  i15 = HEAP32[i7 >> 2] | 0;
+  if ((i15 | 0) == 0) {
+   break;
+  }
+  while (1) {
+   i14 = i15 + 18 | 0;
+   if (!((HEAP8[i14] & 16) == 0)) {
+    break;
+   }
+   i15 = HEAP32[i15 + 8 >> 2] | 0;
+   if ((i15 | 0) == 0) {
+    break L10;
+   }
+  }
+  i16 = HEAP32[i12 >> 2] | 0;
+  i17 = HEAP32[i15 + 20 >> 2] | 0;
+  i18 = i16 + i17 | 0;
+  _luaF_close(i4, i18);
+  if ((i13 | 0) == 4) {
+   i19 = HEAP32[(HEAP32[i8 >> 2] | 0) + 180 >> 2] | 0;
+   HEAP32[i18 >> 2] = i19;
+   HEAP32[i16 + (i17 + 8) >> 2] = HEAPU8[i19 + 4 | 0] | 0 | 64;
+  } else if ((i13 | 0) == 6) {
+   i19 = _luaS_newlstr(i4, 2424, 23) | 0;
+   HEAP32[i18 >> 2] = i19;
+   HEAP32[i16 + (i17 + 8) >> 2] = HEAPU8[i19 + 4 | 0] | 0 | 64;
+  } else {
+   i19 = HEAP32[i6 >> 2] | 0;
+   i21 = i19 + -16 | 0;
+   i20 = HEAP32[i21 + 4 >> 2] | 0;
+   HEAP32[i18 >> 2] = HEAP32[i21 >> 2];
+   HEAP32[i18 + 4 >> 2] = i20;
+   HEAP32[i16 + (i17 + 8) >> 2] = HEAP32[i19 + -8 >> 2];
+  }
+  i17 = i16 + (i17 + 16) | 0;
+  HEAP32[i6 >> 2] = i17;
+  HEAP32[i7 >> 2] = i15;
+  HEAP8[i11] = HEAP8[i15 + 36 | 0] | 0;
+  HEAP16[i5 >> 1] = 0;
+  if ((i15 | 0) != 0) {
+   i16 = i15;
+   do {
+    i18 = HEAP32[i16 + 4 >> 2] | 0;
+    i17 = i17 >>> 0 < i18 >>> 0 ? i18 : i17;
+    i16 = HEAP32[i16 + 8 >> 2] | 0;
+   } while ((i16 | 0) != 0);
+  }
+  i16 = i17 - (HEAP32[i12 >> 2] | 0) | 0;
+  i17 = (i16 >> 4) + 1 | 0;
+  i17 = ((i17 | 0) / 8 | 0) + 10 + i17 | 0;
+  i17 = (i17 | 0) > 1e6 ? 1e6 : i17;
+  if ((i16 | 0) <= 15999984 ? (i17 | 0) < (HEAP32[i9 >> 2] | 0) : 0) {
+   _luaD_reallocstack(i4, i17);
+  }
+  HEAP32[i10 >> 2] = HEAP32[i15 + 32 >> 2];
+  HEAP8[i14] = HEAPU8[i14] | 0 | 32;
+  HEAP8[i15 + 37 | 0] = i13;
+  i13 = _luaD_rawrunprotected(i4, 5, 0) | 0;
+  if (!(i13 >>> 0 > 1)) {
+   i2 = 24;
+   break;
+  }
+ }
+ if ((i2 | 0) == 24) {
+  HEAP16[i5 >> 1] = 1;
+  i21 = HEAP16[i3 >> 1] | 0;
+  i21 = i21 + -1 << 16 >> 16;
+  HEAP16[i3 >> 1] = i21;
+  STACKTOP = i1;
+  return i13 | 0;
+ }
+ HEAP8[i4 + 6 | 0] = i13;
+ i2 = HEAP32[i6 >> 2] | 0;
+ if ((i13 | 0) == 4) {
+  i21 = HEAP32[(HEAP32[i8 >> 2] | 0) + 180 >> 2] | 0;
+  HEAP32[i2 >> 2] = i21;
+  HEAP32[i2 + 8 >> 2] = HEAPU8[i21 + 4 | 0] | 0 | 64;
+ } else if ((i13 | 0) == 6) {
+  i21 = _luaS_newlstr(i4, 2424, 23) | 0;
+  HEAP32[i2 >> 2] = i21;
+  HEAP32[i2 + 8 >> 2] = HEAPU8[i21 + 4 | 0] | 0 | 64;
+ } else {
+  i19 = i2 + -16 | 0;
+  i20 = HEAP32[i19 + 4 >> 2] | 0;
+  i21 = i2;
+  HEAP32[i21 >> 2] = HEAP32[i19 >> 2];
+  HEAP32[i21 + 4 >> 2] = i20;
+  HEAP32[i2 + 8 >> 2] = HEAP32[i2 + -8 >> 2];
+ }
+ i21 = i2 + 16 | 0;
+ HEAP32[i6 >> 2] = i21;
+ HEAP32[(HEAP32[i7 >> 2] | 0) + 4 >> 2] = i21;
+ i21 = i13;
+ HEAP16[i5 >> 1] = 1;
+ i20 = HEAP16[i3 >> 1] | 0;
+ i20 = i20 + -1 << 16 >> 16;
+ HEAP16[i3 >> 1] = i20;
+ STACKTOP = i1;
+ return i21 | 0;
+}
+function _luaK_goiftrue(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0;
+ i2 = STACKTOP;
+ _luaK_dischargevars(i1, i3);
+ i12 = HEAP32[i3 >> 2] | 0;
+ do {
+  if ((i12 | 0) == 10) {
+   i9 = HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0;
+   i5 = i3 + 8 | 0;
+   i8 = HEAP32[i5 >> 2] | 0;
+   i7 = i9 + (i8 << 2) | 0;
+   if (!((i8 | 0) > 0 ? (i10 = i9 + (i8 + -1 << 2) | 0, i6 = HEAP32[i10 >> 2] | 0, (HEAP8[5584 + (i6 & 63) | 0] | 0) < 0) : 0)) {
+    i10 = i7;
+    i6 = HEAP32[i7 >> 2] | 0;
+   }
+   HEAP32[i10 >> 2] = ((i6 & 16320 | 0) == 0) << 6 | i6 & -16321;
+   i5 = HEAP32[i5 >> 2] | 0;
+   i8 = 18;
+  } else if (!((i12 | 0) == 2 | (i12 | 0) == 5 | (i12 | 0) == 4)) {
+   i5 = i3 + 8 | 0;
+   if ((i12 | 0) == 6) {
+    i8 = 14;
+   } else if ((i12 | 0) == 11 ? (i11 = HEAP32[(HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0) + (HEAP32[i5 >> 2] << 2) >> 2] | 0, (i11 & 63 | 0) == 20) : 0) {
+    i5 = i1 + 20 | 0;
+    HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + -1;
+    i5 = _condjump(i1, 27, i11 >>> 23, 0, 1) | 0;
+    i8 = 18;
+    break;
+   } else {
+    i8 = 9;
+   }
+   if ((i8 | 0) == 9) {
+    i12 = i1 + 48 | 0;
+    i10 = HEAP8[i12] | 0;
+    i11 = (i10 & 255) + 1 | 0;
+    i6 = (HEAP32[i1 >> 2] | 0) + 78 | 0;
+    do {
+     if (i11 >>> 0 > (HEAPU8[i6] | 0) >>> 0) {
+      if (i11 >>> 0 > 249) {
+       _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10536);
+      } else {
+       HEAP8[i6] = i11;
+       i9 = HEAP8[i12] | 0;
+       break;
+      }
+     } else {
+      i9 = i10;
+     }
+    } while (0);
+    i11 = (i9 & 255) + 1 | 0;
+    HEAP8[i12] = i11;
+    _discharge2reg(i1, i3, (i11 & 255) + -1 | 0);
+    if ((HEAP32[i3 >> 2] | 0) == 6) {
+     i8 = 14;
+    }
+   }
+   if (((i8 | 0) == 14 ? (i7 = HEAP32[i5 >> 2] | 0, (i7 & 256 | 0) == 0) : 0) ? (HEAPU8[i1 + 46 | 0] | 0) <= (i7 | 0) : 0) {
+    i12 = i1 + 48 | 0;
+    HEAP8[i12] = (HEAP8[i12] | 0) + -1 << 24 >> 24;
+   }
+   i5 = _condjump(i1, 28, 255, HEAP32[i5 >> 2] | 0, 0) | 0;
+   i8 = 18;
+  }
+ } while (0);
+ do {
+  if ((i8 | 0) == 18 ? (i4 = i3 + 20 | 0, !((i5 | 0) == -1)) : 0) {
+   i8 = HEAP32[i4 >> 2] | 0;
+   if ((i8 | 0) == -1) {
+    HEAP32[i4 >> 2] = i5;
+    break;
+   }
+   i4 = HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0;
+   while (1) {
+    i7 = i4 + (i8 << 2) | 0;
+    i6 = HEAP32[i7 >> 2] | 0;
+    i9 = (i6 >>> 14) + -131071 | 0;
+    if ((i9 | 0) == -1) {
+     break;
+    }
+    i9 = i8 + 1 + i9 | 0;
+    if ((i9 | 0) == -1) {
+     break;
+    } else {
+     i8 = i9;
+    }
+   }
+   i4 = i5 + ~i8 | 0;
+   if ((((i4 | 0) > -1 ? i4 : 0 - i4 | 0) | 0) > 131071) {
+    _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10624);
+   } else {
+    HEAP32[i7 >> 2] = (i4 << 14) + 2147467264 | i6 & 16383;
+    break;
+   }
+  }
+ } while (0);
+ i3 = i3 + 16 | 0;
+ i4 = HEAP32[i3 >> 2] | 0;
+ HEAP32[i1 + 24 >> 2] = HEAP32[i1 + 20 >> 2];
+ i5 = i1 + 28 | 0;
+ if ((i4 | 0) == -1) {
+  HEAP32[i3 >> 2] = -1;
+  STACKTOP = i2;
+  return;
+ }
+ i8 = HEAP32[i5 >> 2] | 0;
+ if ((i8 | 0) == -1) {
+  HEAP32[i5 >> 2] = i4;
+  HEAP32[i3 >> 2] = -1;
+  STACKTOP = i2;
+  return;
+ }
+ i7 = HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0;
+ while (1) {
+  i5 = i7 + (i8 << 2) | 0;
+  i6 = HEAP32[i5 >> 2] | 0;
+  i9 = (i6 >>> 14) + -131071 | 0;
+  if ((i9 | 0) == -1) {
+   break;
+  }
+  i9 = i8 + 1 + i9 | 0;
+  if ((i9 | 0) == -1) {
+   break;
+  } else {
+   i8 = i9;
+  }
+ }
+ i4 = i4 + ~i8 | 0;
+ if ((((i4 | 0) > -1 ? i4 : 0 - i4 | 0) | 0) > 131071) {
+  _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10624);
+ }
+ HEAP32[i5 >> 2] = (i4 << 14) + 2147467264 | i6 & 16383;
+ HEAP32[i3 >> 2] = -1;
+ STACKTOP = i2;
+ return;
+}
+function _luaO_str2d(i1, i3, i5) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, d9 = 0.0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ if ((_strpbrk(i1, 5464) | 0) != 0) {
+  i13 = 0;
+  STACKTOP = i2;
+  return i13 | 0;
+ }
+ do {
+  if ((_strpbrk(i1, 5472) | 0) == 0) {
+   d9 = +_strtod(i1, i4);
+   i10 = HEAP32[i4 >> 2] | 0;
+  } else {
+   HEAP32[i4 >> 2] = i1;
+   i8 = i1;
+   while (1) {
+    i6 = HEAP8[i8] | 0;
+    i10 = i8 + 1 | 0;
+    if ((HEAP8[(i6 & 255) + 10913 | 0] & 8) == 0) {
+     break;
+    } else {
+     i8 = i10;
+    }
+   }
+   if (i6 << 24 >> 24 == 43) {
+    i6 = 0;
+    i8 = i10;
+   } else if (i6 << 24 >> 24 == 45) {
+    i6 = 1;
+    i8 = i10;
+   } else {
+    i6 = 0;
+   }
+   if ((HEAP8[i8] | 0) == 48 ? (i13 = HEAP8[i8 + 1 | 0] | 0, i13 << 24 >> 24 == 88 | i13 << 24 >> 24 == 120) : 0) {
+    i10 = i8 + 2 | 0;
+    i8 = HEAP8[i10] | 0;
+    i12 = i8 & 255;
+    i11 = HEAP8[i12 + 10913 | 0] | 0;
+    if ((i11 & 16) == 0) {
+     d9 = 0.0;
+     i11 = i8;
+     i8 = 0;
+    } else {
+     d9 = 0.0;
+     i8 = 0;
+     while (1) {
+      if ((i11 & 2) == 0) {
+       i11 = (i12 | 32) + -87 | 0;
+      } else {
+       i11 = i12 + -48 | 0;
+      }
+      d9 = d9 * 16.0 + +(i11 | 0);
+      i8 = i8 + 1 | 0;
+      i10 = i10 + 1 | 0;
+      i13 = HEAP8[i10] | 0;
+      i12 = i13 & 255;
+      i11 = HEAP8[i12 + 10913 | 0] | 0;
+      if ((i11 & 16) == 0) {
+       i11 = i13;
+       break;
+      }
+     }
+    }
+    if (i11 << 24 >> 24 == 46) {
+     i10 = i10 + 1 | 0;
+     i13 = HEAPU8[i10] | 0;
+     i11 = HEAP8[i13 + 10913 | 0] | 0;
+     if ((i11 & 16) == 0) {
+      i12 = 0;
+     } else {
+      i12 = 0;
+      do {
+       if ((i11 & 2) == 0) {
+        i11 = (i13 | 32) + -87 | 0;
+       } else {
+        i11 = i13 + -48 | 0;
+       }
+       d9 = d9 * 16.0 + +(i11 | 0);
+       i12 = i12 + 1 | 0;
+       i10 = i10 + 1 | 0;
+       i13 = HEAPU8[i10] | 0;
+       i11 = HEAP8[i13 + 10913 | 0] | 0;
+      } while (!((i11 & 16) == 0));
+     }
+    } else {
+     i12 = 0;
+    }
+    if ((i12 | i8 | 0) != 0) {
+     i8 = Math_imul(i12, -4) | 0;
+     HEAP32[i4 >> 2] = i10;
+     i13 = HEAP8[i10] | 0;
+     if (i13 << 24 >> 24 == 80 | i13 << 24 >> 24 == 112) {
+      i13 = i10 + 1 | 0;
+      i11 = HEAP8[i13] | 0;
+      if (i11 << 24 >> 24 == 45) {
+       i11 = 1;
+       i13 = i10 + 2 | 0;
+      } else if (i11 << 24 >> 24 == 43) {
+       i11 = 0;
+       i13 = i10 + 2 | 0;
+      } else {
+       i11 = 0;
+      }
+      i12 = HEAP8[i13] | 0;
+      if (!((HEAP8[(i12 & 255) + 10913 | 0] & 2) == 0)) {
+       i10 = i13;
+       i7 = 0;
+       do {
+        i10 = i10 + 1 | 0;
+        i7 = (i12 << 24 >> 24) + -48 + (i7 * 10 | 0) | 0;
+        i12 = HEAP8[i10] | 0;
+       } while (!((HEAP8[(i12 & 255) + 10913 | 0] & 2) == 0));
+       i8 = ((i11 | 0) == 0 ? i7 : 0 - i7 | 0) + i8 | 0;
+       i7 = 29;
+      }
+     } else {
+      i7 = 29;
+     }
+     if ((i7 | 0) == 29) {
+      HEAP32[i4 >> 2] = i10;
+     }
+     if ((i6 | 0) != 0) {
+      d9 = -d9;
+     }
+     d9 = +_ldexp(d9, i8);
+     break;
+    }
+   }
+   HEAPF64[i5 >> 3] = 0.0;
+   i13 = 0;
+   STACKTOP = i2;
+   return i13 | 0;
+  }
+ } while (0);
+ HEAPF64[i5 >> 3] = d9;
+ if ((i10 | 0) == (i1 | 0)) {
+  i13 = 0;
+  STACKTOP = i2;
+  return i13 | 0;
+ }
+ if (!((HEAP8[(HEAPU8[i10] | 0) + 10913 | 0] & 8) == 0)) {
+  do {
+   i10 = i10 + 1 | 0;
+  } while (!((HEAP8[(HEAPU8[i10] | 0) + 10913 | 0] & 8) == 0));
+  HEAP32[i4 >> 2] = i10;
+ }
+ i13 = (i10 | 0) == (i1 + i3 | 0) | 0;
+ STACKTOP = i2;
+ return i13 | 0;
+}
+function _luaV_equalobj_(i2, i4, i5) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i1 = STACKTOP;
+ i3 = i4 + 8 | 0;
+ L1 : do {
+  switch (HEAP32[i3 >> 2] & 63 | 0) {
+  case 7:
+   {
+    i6 = HEAP32[i4 >> 2] | 0;
+    i7 = HEAP32[i5 >> 2] | 0;
+    if ((i6 | 0) == (i7 | 0)) {
+     i7 = 1;
+     STACKTOP = i1;
+     return i7 | 0;
+    }
+    if ((i2 | 0) == 0) {
+     i7 = 0;
+     STACKTOP = i1;
+     return i7 | 0;
+    } else {
+     i6 = _get_equalTM(i2, HEAP32[i6 + 8 >> 2] | 0, HEAP32[i7 + 8 >> 2] | 0) | 0;
+     break L1;
+    }
+   }
+  case 5:
+   {
+    i7 = HEAP32[i4 >> 2] | 0;
+    i6 = HEAP32[i5 >> 2] | 0;
+    if ((i7 | 0) == (i6 | 0)) {
+     i7 = 1;
+     STACKTOP = i1;
+     return i7 | 0;
+    }
+    if ((i2 | 0) == 0) {
+     i7 = 0;
+     STACKTOP = i1;
+     return i7 | 0;
+    } else {
+     i6 = _get_equalTM(i2, HEAP32[i7 + 8 >> 2] | 0, HEAP32[i6 + 8 >> 2] | 0) | 0;
+     break L1;
+    }
+   }
+  case 4:
+   {
+    i7 = (HEAP32[i4 >> 2] | 0) == (HEAP32[i5 >> 2] | 0) | 0;
+    STACKTOP = i1;
+    return i7 | 0;
+   }
+  case 20:
+   {
+    i7 = _luaS_eqlngstr(HEAP32[i4 >> 2] | 0, HEAP32[i5 >> 2] | 0) | 0;
+    STACKTOP = i1;
+    return i7 | 0;
+   }
+  case 3:
+   {
+    i7 = +HEAPF64[i4 >> 3] == +HEAPF64[i5 >> 3] | 0;
+    STACKTOP = i1;
+    return i7 | 0;
+   }
+  case 1:
+   {
+    i7 = (HEAP32[i4 >> 2] | 0) == (HEAP32[i5 >> 2] | 0) | 0;
+    STACKTOP = i1;
+    return i7 | 0;
+   }
+  case 22:
+   {
+    i7 = (HEAP32[i4 >> 2] | 0) == (HEAP32[i5 >> 2] | 0) | 0;
+    STACKTOP = i1;
+    return i7 | 0;
+   }
+  case 2:
+   {
+    i7 = (HEAP32[i4 >> 2] | 0) == (HEAP32[i5 >> 2] | 0) | 0;
+    STACKTOP = i1;
+    return i7 | 0;
+   }
+  case 0:
+   {
+    i7 = 1;
+    STACKTOP = i1;
+    return i7 | 0;
+   }
+  default:
+   {
+    i7 = (HEAP32[i4 >> 2] | 0) == (HEAP32[i5 >> 2] | 0) | 0;
+    STACKTOP = i1;
+    return i7 | 0;
+   }
+  }
+ } while (0);
+ if ((i6 | 0) == 0) {
+  i7 = 0;
+  STACKTOP = i1;
+  return i7 | 0;
+ }
+ i7 = i2 + 8 | 0;
+ i10 = HEAP32[i7 >> 2] | 0;
+ i9 = i2 + 28 | 0;
+ i8 = i10 - (HEAP32[i9 >> 2] | 0) | 0;
+ HEAP32[i7 >> 2] = i10 + 16;
+ i13 = i6;
+ i12 = HEAP32[i13 + 4 >> 2] | 0;
+ i11 = i10;
+ HEAP32[i11 >> 2] = HEAP32[i13 >> 2];
+ HEAP32[i11 + 4 >> 2] = i12;
+ HEAP32[i10 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+ i10 = HEAP32[i7 >> 2] | 0;
+ HEAP32[i7 >> 2] = i10 + 16;
+ i11 = i4;
+ i4 = HEAP32[i11 + 4 >> 2] | 0;
+ i6 = i10;
+ HEAP32[i6 >> 2] = HEAP32[i11 >> 2];
+ HEAP32[i6 + 4 >> 2] = i4;
+ HEAP32[i10 + 8 >> 2] = HEAP32[i3 >> 2];
+ i3 = HEAP32[i7 >> 2] | 0;
+ HEAP32[i7 >> 2] = i3 + 16;
+ i10 = i5;
+ i6 = HEAP32[i10 + 4 >> 2] | 0;
+ i4 = i3;
+ HEAP32[i4 >> 2] = HEAP32[i10 >> 2];
+ HEAP32[i4 + 4 >> 2] = i6;
+ HEAP32[i3 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+ _luaD_call(i2, (HEAP32[i7 >> 2] | 0) + -48 | 0, 1, HEAP8[(HEAP32[i2 + 16 >> 2] | 0) + 18 | 0] & 1);
+ i2 = HEAP32[i9 >> 2] | 0;
+ i3 = HEAP32[i7 >> 2] | 0;
+ i4 = i3 + -16 | 0;
+ HEAP32[i7 >> 2] = i4;
+ i5 = HEAP32[i4 + 4 >> 2] | 0;
+ i6 = i2 + i8 | 0;
+ HEAP32[i6 >> 2] = HEAP32[i4 >> 2];
+ HEAP32[i6 + 4 >> 2] = i5;
+ HEAP32[i2 + (i8 + 8) >> 2] = HEAP32[i3 + -8 >> 2];
+ i2 = HEAP32[i7 >> 2] | 0;
+ i3 = HEAP32[i2 + 8 >> 2] | 0;
+ if ((i3 | 0) != 0) {
+  if ((i3 | 0) == 1) {
+   i2 = (HEAP32[i2 >> 2] | 0) != 0;
+  } else {
+   i2 = 1;
+  }
+ } else {
+  i2 = 0;
+ }
+ i13 = i2 & 1;
+ STACKTOP = i1;
+ return i13 | 0;
+}
+function _forbody(i1, i5, i6, i4, i9) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ i4 = i4 | 0;
+ i9 = i9 | 0;
+ var i2 = 0, i3 = 0, i7 = 0, i8 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i8 = i3 + 12 | 0;
+ i19 = i3;
+ i11 = i1 + 48 | 0;
+ i7 = HEAP32[i11 >> 2] | 0;
+ i18 = i7 + 46 | 0;
+ i22 = (HEAPU8[i18] | 0) + 3 | 0;
+ HEAP8[i18] = i22;
+ i21 = i7 + 20 | 0;
+ i17 = i7 + 12 | 0;
+ i2 = i7 + 40 | 0;
+ i20 = HEAP32[(HEAP32[i7 >> 2] | 0) + 24 >> 2] | 0;
+ i10 = HEAP32[HEAP32[(HEAP32[i17 >> 2] | 0) + 64 >> 2] >> 2] | 0;
+ HEAP32[i20 + ((HEAP16[i10 + ((i22 & 255) + -3 + (HEAP32[i2 >> 2] | 0) << 1) >> 1] | 0) * 12 | 0) + 4 >> 2] = HEAP32[i21 >> 2];
+ HEAP32[i20 + ((HEAP16[i10 + ((HEAPU8[i18] | 0) + -2 + (HEAP32[i2 >> 2] | 0) << 1) >> 1] | 0) * 12 | 0) + 4 >> 2] = HEAP32[i21 >> 2];
+ HEAP32[i20 + ((HEAP16[i10 + ((HEAPU8[i18] | 0) + -1 + (HEAP32[i2 >> 2] | 0) << 1) >> 1] | 0) * 12 | 0) + 4 >> 2] = HEAP32[i21 >> 2];
+ i2 = i1 + 16 | 0;
+ if ((HEAP32[i2 >> 2] | 0) != 259) {
+  _error_expected(i1, 259);
+ }
+ _luaX_next(i1);
+ i10 = (i9 | 0) != 0;
+ if (i10) {
+  i9 = _luaK_codeABx(i7, 33, i5, 131070) | 0;
+ } else {
+  i9 = _luaK_jump(i7) | 0;
+ }
+ HEAP8[i19 + 10 | 0] = 0;
+ HEAP8[i19 + 8 | 0] = HEAP8[i18] | 0;
+ i17 = HEAP32[(HEAP32[i17 >> 2] | 0) + 64 >> 2] | 0;
+ HEAP16[i19 + 4 >> 1] = HEAP32[i17 + 28 >> 2];
+ HEAP16[i19 + 6 >> 1] = HEAP32[i17 + 16 >> 2];
+ HEAP8[i19 + 9 | 0] = 0;
+ i17 = i7 + 16 | 0;
+ HEAP32[i19 >> 2] = HEAP32[i17 >> 2];
+ HEAP32[i17 >> 2] = i19;
+ i19 = HEAP32[i11 >> 2] | 0;
+ i17 = i19 + 46 | 0;
+ i18 = (HEAPU8[i17] | 0) + i4 | 0;
+ HEAP8[i17] = i18;
+ if ((i4 | 0) != 0 ? (i13 = i19 + 20 | 0, i12 = i19 + 40 | 0, i14 = HEAP32[(HEAP32[i19 >> 2] | 0) + 24 >> 2] | 0, i15 = HEAP32[HEAP32[(HEAP32[i19 + 12 >> 2] | 0) + 64 >> 2] >> 2] | 0, HEAP32[i14 + ((HEAP16[i15 + ((i18 & 255) - i4 + (HEAP32[i12 >> 2] | 0) << 1) >> 1] | 0) * 12 | 0) + 4 >> 2] = HEAP32[i13 >> 2], i16 = i4 + -1 | 0, (i16 | 0) != 0) : 0) {
+  do {
+   HEAP32[i14 + ((HEAP16[i15 + ((HEAPU8[i17] | 0) - i16 + (HEAP32[i12 >> 2] | 0) << 1) >> 1] | 0) * 12 | 0) + 4 >> 2] = HEAP32[i13 >> 2];
+   i16 = i16 + -1 | 0;
+  } while ((i16 | 0) != 0);
+ }
+ _luaK_reserveregs(i7, i4);
+ i11 = HEAP32[i11 >> 2] | 0;
+ HEAP8[i8 + 10 | 0] = 0;
+ HEAP8[i8 + 8 | 0] = HEAP8[i11 + 46 | 0] | 0;
+ i22 = HEAP32[(HEAP32[i11 + 12 >> 2] | 0) + 64 >> 2] | 0;
+ HEAP16[i8 + 4 >> 1] = HEAP32[i22 + 28 >> 2];
+ HEAP16[i8 + 6 >> 1] = HEAP32[i22 + 16 >> 2];
+ HEAP8[i8 + 9 | 0] = 0;
+ i22 = i11 + 16 | 0;
+ HEAP32[i8 >> 2] = HEAP32[i22 >> 2];
+ HEAP32[i22 >> 2] = i8;
+ L13 : do {
+  i8 = HEAP32[i2 >> 2] | 0;
+  switch (i8 | 0) {
+  case 277:
+  case 286:
+  case 262:
+  case 261:
+  case 260:
+   {
+    break L13;
+   }
+  default:
+   {}
+  }
+  _statement(i1);
+ } while ((i8 | 0) != 274);
+ _leaveblock(i11);
+ _leaveblock(i7);
+ _luaK_patchtohere(i7, i9);
+ if (i10) {
+  i21 = _luaK_codeABx(i7, 32, i5, 131070) | 0;
+  i22 = i9 + 1 | 0;
+  _luaK_patchlist(i7, i21, i22);
+  _luaK_fixline(i7, i6);
+  STACKTOP = i3;
+  return;
+ } else {
+  _luaK_codeABC(i7, 34, i5, 0, i4) | 0;
+  _luaK_fixline(i7, i6);
+  i21 = _luaK_codeABx(i7, 35, i5 + 2 | 0, 131070) | 0;
+  i22 = i9 + 1 | 0;
+  _luaK_patchlist(i7, i21, i22);
+  _luaK_fixline(i7, i6);
+  STACKTOP = i3;
+  return;
+ }
+}
+function _dotty(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i6 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i6;
+ i4 = i6 + 4 | 0;
+ i2 = HEAP32[20] | 0;
+ HEAP32[20] = 0;
+ _lua_settop(i1, 0);
+ if ((_pushline(i1, 1) | 0) == 0) {
+  _lua_settop(i1, 0);
+  i10 = HEAP32[_stdout >> 2] | 0;
+  _fputc(10, i10 | 0) | 0;
+  _fflush(i10 | 0) | 0;
+  HEAP32[20] = i2;
+  STACKTOP = i6;
+  return;
+ }
+ i5 = HEAP32[_stderr >> 2] | 0;
+ L4 : while (1) {
+  i8 = _lua_tolstring(i1, 1, i4) | 0;
+  i8 = _luaL_loadbufferx(i1, i8, HEAP32[i4 >> 2] | 0, 256, 0) | 0;
+  L6 : do {
+   if ((i8 | 0) == 3) {
+    while (1) {
+     i8 = _lua_tolstring(i1, -1, i3) | 0;
+     i7 = HEAP32[i3 >> 2] | 0;
+     if (!(i7 >>> 0 > 4)) {
+      break;
+     }
+     if ((_strcmp(i8 + (i7 + -5) | 0, 264) | 0) != 0) {
+      break;
+     }
+     _lua_settop(i1, -2);
+     if ((_pushline(i1, 0) | 0) == 0) {
+      i7 = 23;
+      break L4;
+     }
+     _lua_pushlstring(i1, 184, 1) | 0;
+     _lua_insert(i1, -2);
+     _lua_concat(i1, 3);
+     i8 = _lua_tolstring(i1, 1, i4) | 0;
+     i8 = _luaL_loadbufferx(i1, i8, HEAP32[i4 >> 2] | 0, 256, 0) | 0;
+     if ((i8 | 0) != 3) {
+      i7 = 9;
+      break L6;
+     }
+    }
+    _lua_remove(i1, 1);
+    i8 = 3;
+    i7 = 10;
+   } else {
+    i7 = 9;
+   }
+  } while (0);
+  do {
+   if ((i7 | 0) == 9) {
+    _lua_remove(i1, 1);
+    if ((i8 | 0) == -1) {
+     i7 = 23;
+     break L4;
+    } else if ((i8 | 0) != 0) {
+     i7 = 10;
+     break;
+    }
+    i9 = _lua_gettop(i1) | 0;
+    _lua_pushcclosure(i1, 142, 0);
+    _lua_insert(i1, i9);
+    HEAP32[48] = i1;
+    _signal(2, 1) | 0;
+    i10 = _lua_pcallk(i1, 0, -1, i9, 0, 0) | 0;
+    _signal(2, 0) | 0;
+    _lua_remove(i1, i9);
+    if ((i10 | 0) == 0) {
+     i7 = 17;
+    } else {
+     i9 = 0;
+     i7 = 12;
+    }
+   }
+  } while (0);
+  if ((i7 | 0) == 10) {
+   i9 = (i8 | 0) == 0;
+   i7 = 12;
+  }
+  do {
+   if ((i7 | 0) == 12) {
+    i7 = 0;
+    if ((_lua_type(i1, -1) | 0) == 0) {
+     if (i9) {
+      i7 = 17;
+      break;
+     } else {
+      break;
+     }
+    }
+    i10 = _lua_tolstring(i1, -1, 0) | 0;
+    i8 = HEAP32[20] | 0;
+    if ((i8 | 0) != 0) {
+     HEAP32[i3 >> 2] = i8;
+     _fprintf(i5 | 0, 496, i3 | 0) | 0;
+     _fflush(i5 | 0) | 0;
+    }
+    HEAP32[i3 >> 2] = (i10 | 0) == 0 ? 48 : i10;
+    _fprintf(i5 | 0, 912, i3 | 0) | 0;
+    _fflush(i5 | 0) | 0;
+    _lua_settop(i1, -2);
+    _lua_gc(i1, 2, 0) | 0;
+    if (i9) {
+     i7 = 17;
+    }
+   }
+  } while (0);
+  if (((i7 | 0) == 17 ? (0, (_lua_gettop(i1) | 0) > 0) : 0) ? (_luaL_checkstack(i1, 20, 112), _lua_getglobal(i1, 144), _lua_insert(i1, 1), (_lua_pcallk(i1, (_lua_gettop(i1) | 0) + -1 | 0, 0, 0, 0, 0) | 0) != 0) : 0) {
+   i7 = HEAP32[20] | 0;
+   HEAP32[i3 >> 2] = _lua_tolstring(i1, -1, 0) | 0;
+   i8 = _lua_pushfstring(i1, 152, i3) | 0;
+   if ((i7 | 0) != 0) {
+    HEAP32[i3 >> 2] = i7;
+    _fprintf(i5 | 0, 496, i3 | 0) | 0;
+    _fflush(i5 | 0) | 0;
+   }
+   HEAP32[i3 >> 2] = i8;
+   _fprintf(i5 | 0, 912, i3 | 0) | 0;
+   _fflush(i5 | 0) | 0;
+  }
+  _lua_settop(i1, 0);
+  if ((_pushline(i1, 1) | 0) == 0) {
+   i7 = 23;
+   break;
+  }
+ }
+ if ((i7 | 0) == 23) {
+  _lua_settop(i1, 0);
+  i10 = HEAP32[_stdout >> 2] | 0;
+  _fputc(10, i10 | 0) | 0;
+  _fflush(i10 | 0) | 0;
+  HEAP32[20] = i2;
+  STACKTOP = i6;
+  return;
+ }
+}
+function _test_then_block(i5, i1) {
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 48 | 0;
+ i10 = i2 + 24 | 0;
+ i9 = i2;
+ i8 = i5 + 48 | 0;
+ i4 = HEAP32[i8 >> 2] | 0;
+ _luaX_next(i5);
+ _subexpr(i5, i9, 0) | 0;
+ i3 = i5 + 16 | 0;
+ if ((HEAP32[i3 >> 2] | 0) != 275) {
+  _error_expected(i5, 275);
+ }
+ _luaX_next(i5);
+ i14 = HEAP32[i3 >> 2] | 0;
+ do {
+  if ((i14 | 0) == 258 | (i14 | 0) == 266) {
+   _luaK_goiffalse(HEAP32[i8 >> 2] | 0, i9);
+   HEAP8[i10 + 10 | 0] = 0;
+   HEAP8[i10 + 8 | 0] = HEAP8[i4 + 46 | 0] | 0;
+   i11 = HEAP32[(HEAP32[i4 + 12 >> 2] | 0) + 64 >> 2] | 0;
+   HEAP16[i10 + 4 >> 1] = HEAP32[i11 + 28 >> 2];
+   HEAP16[i10 + 6 >> 1] = HEAP32[i11 + 16 >> 2];
+   HEAP8[i10 + 9 | 0] = 0;
+   i11 = i4 + 16 | 0;
+   HEAP32[i10 >> 2] = HEAP32[i11 >> 2];
+   HEAP32[i11 >> 2] = i10;
+   i11 = HEAP32[i9 + 16 >> 2] | 0;
+   i10 = HEAP32[i5 + 4 >> 2] | 0;
+   i14 = (HEAP32[i3 >> 2] | 0) == 266;
+   _luaX_next(i5);
+   do {
+    if (i14) {
+     if ((HEAP32[i3 >> 2] | 0) == 288) {
+      i7 = HEAP32[i5 + 24 >> 2] | 0;
+      _luaX_next(i5);
+      break;
+     } else {
+      _error_expected(i5, 288);
+     }
+    } else {
+     i7 = _luaS_new(HEAP32[i5 + 52 >> 2] | 0, 6304) | 0;
+    }
+   } while (0);
+   i14 = HEAP32[i5 + 64 >> 2] | 0;
+   i12 = i14 + 12 | 0;
+   i13 = i14 + 16 | 0;
+   i9 = HEAP32[i13 >> 2] | 0;
+   i14 = i14 + 20 | 0;
+   if ((i9 | 0) < (HEAP32[i14 >> 2] | 0)) {
+    i14 = HEAP32[i12 >> 2] | 0;
+   } else {
+    i14 = _luaM_growaux_(HEAP32[i5 + 52 >> 2] | 0, HEAP32[i12 >> 2] | 0, i14, 16, 32767, 6312) | 0;
+    HEAP32[i12 >> 2] = i14;
+   }
+   HEAP32[i14 + (i9 << 4) >> 2] = i7;
+   i14 = HEAP32[i12 >> 2] | 0;
+   HEAP32[i14 + (i9 << 4) + 8 >> 2] = i10;
+   HEAP8[i14 + (i9 << 4) + 12 | 0] = HEAP8[(HEAP32[i8 >> 2] | 0) + 46 | 0] | 0;
+   HEAP32[(HEAP32[i12 >> 2] | 0) + (i9 << 4) + 4 >> 2] = i11;
+   HEAP32[i13 >> 2] = (HEAP32[i13 >> 2] | 0) + 1;
+   _findlabel(i5, i9) | 0;
+   L18 : while (1) {
+    switch (HEAP32[i3 >> 2] | 0) {
+    case 286:
+    case 262:
+    case 261:
+    case 260:
+     {
+      break L18;
+     }
+    case 285:
+    case 59:
+     {
+      break;
+     }
+    default:
+     {
+      i6 = 16;
+      break L18;
+     }
+    }
+    _statement(i5);
+   }
+   if ((i6 | 0) == 16) {
+    i6 = _luaK_jump(i4) | 0;
+    break;
+   }
+   _leaveblock(i4);
+   STACKTOP = i2;
+   return;
+  } else {
+   _luaK_goiftrue(HEAP32[i8 >> 2] | 0, i9);
+   HEAP8[i10 + 10 | 0] = 0;
+   HEAP8[i10 + 8 | 0] = HEAP8[i4 + 46 | 0] | 0;
+   i6 = HEAP32[(HEAP32[i4 + 12 >> 2] | 0) + 64 >> 2] | 0;
+   HEAP16[i10 + 4 >> 1] = HEAP32[i6 + 28 >> 2];
+   HEAP16[i10 + 6 >> 1] = HEAP32[i6 + 16 >> 2];
+   HEAP8[i10 + 9 | 0] = 0;
+   i6 = i4 + 16 | 0;
+   HEAP32[i10 >> 2] = HEAP32[i6 >> 2];
+   HEAP32[i6 >> 2] = i10;
+   i6 = HEAP32[i9 + 20 >> 2] | 0;
+  }
+ } while (0);
+ L26 : do {
+  i7 = HEAP32[i3 >> 2] | 0;
+  switch (i7 | 0) {
+  case 277:
+  case 286:
+  case 262:
+  case 261:
+  case 260:
+   {
+    break L26;
+   }
+  default:
+   {}
+  }
+  _statement(i5);
+ } while ((i7 | 0) != 274);
+ _leaveblock(i4);
+ if (((HEAP32[i3 >> 2] | 0) + -260 | 0) >>> 0 < 2) {
+  _luaK_concat(i4, i1, _luaK_jump(i4) | 0);
+ }
+ _luaK_patchtohere(i4, i6);
+ STACKTOP = i2;
+ return;
+}
+function _luaL_gsub(i2, i13, i11, i10) {
+ i2 = i2 | 0;
+ i13 = i13 | 0;
+ i11 = i11 | 0;
+ i10 = i10 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i12 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 1056 | 0;
+ i8 = i1;
+ i4 = i1 + 8 | 0;
+ i9 = _strlen(i11 | 0) | 0;
+ i6 = i4 + 12 | 0;
+ HEAP32[i6 >> 2] = i2;
+ i3 = i4 + 16 | 0;
+ HEAP32[i4 >> 2] = i3;
+ i5 = i4 + 8 | 0;
+ HEAP32[i5 >> 2] = 0;
+ i7 = i4 + 4 | 0;
+ HEAP32[i7 >> 2] = 1024;
+ i12 = _strstr(i13, i11) | 0;
+ if ((i12 | 0) == 0) {
+  i14 = 0;
+  i17 = 1024;
+  i16 = i2;
+ } else {
+  i14 = 0;
+  i17 = 1024;
+  i16 = i2;
+  do {
+   i15 = i12 - i13 | 0;
+   if ((i17 - i14 | 0) >>> 0 < i15 >>> 0) {
+    i17 = i17 << 1;
+    i17 = (i17 - i14 | 0) >>> 0 < i15 >>> 0 ? i14 + i15 | 0 : i17;
+    if (i17 >>> 0 < i14 >>> 0 | (i17 - i14 | 0) >>> 0 < i15 >>> 0) {
+     _luaL_error(i16, 1272, i8) | 0;
+    }
+    i14 = _lua_newuserdata(i16, i17) | 0;
+    _memcpy(i14 | 0, HEAP32[i4 >> 2] | 0, HEAP32[i5 >> 2] | 0) | 0;
+    if ((HEAP32[i4 >> 2] | 0) != (i3 | 0)) {
+     _lua_remove(i16, -2);
+    }
+    HEAP32[i4 >> 2] = i14;
+    HEAP32[i7 >> 2] = i17;
+    i16 = i14;
+    i14 = HEAP32[i5 >> 2] | 0;
+   } else {
+    i16 = HEAP32[i4 >> 2] | 0;
+   }
+   _memcpy(i16 + i14 | 0, i13 | 0, i15 | 0) | 0;
+   i15 = (HEAP32[i5 >> 2] | 0) + i15 | 0;
+   HEAP32[i5 >> 2] = i15;
+   i13 = _strlen(i10 | 0) | 0;
+   i14 = HEAP32[i6 >> 2] | 0;
+   i16 = HEAP32[i7 >> 2] | 0;
+   if ((i16 - i15 | 0) >>> 0 < i13 >>> 0) {
+    i16 = i16 << 1;
+    i16 = (i16 - i15 | 0) >>> 0 < i13 >>> 0 ? i15 + i13 | 0 : i16;
+    if (i16 >>> 0 < i15 >>> 0 | (i16 - i15 | 0) >>> 0 < i13 >>> 0) {
+     _luaL_error(i14, 1272, i8) | 0;
+    }
+    i15 = _lua_newuserdata(i14, i16) | 0;
+    _memcpy(i15 | 0, HEAP32[i4 >> 2] | 0, HEAP32[i5 >> 2] | 0) | 0;
+    if ((HEAP32[i4 >> 2] | 0) != (i3 | 0)) {
+     _lua_remove(i14, -2);
+    }
+    HEAP32[i4 >> 2] = i15;
+    HEAP32[i7 >> 2] = i16;
+    i14 = i15;
+    i15 = HEAP32[i5 >> 2] | 0;
+   } else {
+    i14 = HEAP32[i4 >> 2] | 0;
+   }
+   _memcpy(i14 + i15 | 0, i10 | 0, i13 | 0) | 0;
+   i14 = (HEAP32[i5 >> 2] | 0) + i13 | 0;
+   HEAP32[i5 >> 2] = i14;
+   i13 = i12 + i9 | 0;
+   i12 = _strstr(i13, i11) | 0;
+   i16 = HEAP32[i6 >> 2] | 0;
+   i17 = HEAP32[i7 >> 2] | 0;
+  } while ((i12 | 0) != 0);
+ }
+ i9 = _strlen(i13 | 0) | 0;
+ if ((i17 - i14 | 0) >>> 0 < i9 >>> 0) {
+  i10 = i17 << 1;
+  i10 = (i10 - i14 | 0) >>> 0 < i9 >>> 0 ? i14 + i9 | 0 : i10;
+  if (i10 >>> 0 < i14 >>> 0 | (i10 - i14 | 0) >>> 0 < i9 >>> 0) {
+   _luaL_error(i16, 1272, i8) | 0;
+  }
+  i8 = _lua_newuserdata(i16, i10) | 0;
+  _memcpy(i8 | 0, HEAP32[i4 >> 2] | 0, HEAP32[i5 >> 2] | 0) | 0;
+  if ((HEAP32[i4 >> 2] | 0) != (i3 | 0)) {
+   _lua_remove(i16, -2);
+  }
+  HEAP32[i4 >> 2] = i8;
+  HEAP32[i7 >> 2] = i10;
+  i14 = HEAP32[i5 >> 2] | 0;
+ } else {
+  i8 = HEAP32[i4 >> 2] | 0;
+ }
+ _memcpy(i8 + i14 | 0, i13 | 0, i9 | 0) | 0;
+ i17 = (HEAP32[i5 >> 2] | 0) + i9 | 0;
+ HEAP32[i5 >> 2] = i17;
+ i5 = HEAP32[i6 >> 2] | 0;
+ _lua_pushlstring(i5, HEAP32[i4 >> 2] | 0, i17) | 0;
+ if ((HEAP32[i4 >> 2] | 0) == (i3 | 0)) {
+  i17 = _lua_tolstring(i2, -1, 0) | 0;
+  STACKTOP = i1;
+  return i17 | 0;
+ }
+ _lua_remove(i5, -2);
+ i17 = _lua_tolstring(i2, -1, 0) | 0;
+ STACKTOP = i1;
+ return i17 | 0;
+}
+function _luaK_goiffalse(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0;
+ i2 = STACKTOP;
+ _luaK_dischargevars(i1, i3);
+ i9 = HEAP32[i3 >> 2] | 0;
+ do {
+  if ((i9 | 0) == 10) {
+   i4 = HEAP32[i3 + 8 >> 2] | 0;
+   i8 = 15;
+  } else if (!((i9 | 0) == 3 | (i9 | 0) == 1)) {
+   i4 = i3 + 8 | 0;
+   if ((i9 | 0) == 6) {
+    i8 = 11;
+   } else if ((i9 | 0) == 11 ? (i10 = HEAP32[(HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0) + (HEAP32[i4 >> 2] << 2) >> 2] | 0, (i10 & 63 | 0) == 20) : 0) {
+    i4 = i1 + 20 | 0;
+    HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + -1;
+    i4 = _condjump(i1, 27, i10 >>> 23, 0, 0) | 0;
+    i8 = 15;
+    break;
+   } else {
+    i8 = 6;
+   }
+   if ((i8 | 0) == 6) {
+    i9 = i1 + 48 | 0;
+    i11 = HEAP8[i9] | 0;
+    i10 = (i11 & 255) + 1 | 0;
+    i12 = (HEAP32[i1 >> 2] | 0) + 78 | 0;
+    do {
+     if (i10 >>> 0 > (HEAPU8[i12] | 0) >>> 0) {
+      if (i10 >>> 0 > 249) {
+       _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10536);
+      } else {
+       HEAP8[i12] = i10;
+       i7 = HEAP8[i9] | 0;
+       break;
+      }
+     } else {
+      i7 = i11;
+     }
+    } while (0);
+    i12 = (i7 & 255) + 1 | 0;
+    HEAP8[i9] = i12;
+    _discharge2reg(i1, i3, (i12 & 255) + -1 | 0);
+    if ((HEAP32[i3 >> 2] | 0) == 6) {
+     i8 = 11;
+    }
+   }
+   if (((i8 | 0) == 11 ? (i6 = HEAP32[i4 >> 2] | 0, (i6 & 256 | 0) == 0) : 0) ? (HEAPU8[i1 + 46 | 0] | 0 | 0) <= (i6 | 0) : 0) {
+    i12 = i1 + 48 | 0;
+    HEAP8[i12] = (HEAP8[i12] | 0) + -1 << 24 >> 24;
+   }
+   i4 = _condjump(i1, 28, 255, HEAP32[i4 >> 2] | 0, 1) | 0;
+   i8 = 15;
+  }
+ } while (0);
+ do {
+  if ((i8 | 0) == 15 ? (i5 = i3 + 16 | 0, !((i4 | 0) == -1)) : 0) {
+   i8 = HEAP32[i5 >> 2] | 0;
+   if ((i8 | 0) == -1) {
+    HEAP32[i5 >> 2] = i4;
+    break;
+   }
+   i5 = HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0;
+   while (1) {
+    i7 = i5 + (i8 << 2) | 0;
+    i6 = HEAP32[i7 >> 2] | 0;
+    i9 = (i6 >>> 14) + -131071 | 0;
+    if ((i9 | 0) == -1) {
+     break;
+    }
+    i9 = i8 + 1 + i9 | 0;
+    if ((i9 | 0) == -1) {
+     break;
+    } else {
+     i8 = i9;
+    }
+   }
+   i4 = i4 + ~i8 | 0;
+   if ((((i4 | 0) > -1 ? i4 : 0 - i4 | 0) | 0) > 131071) {
+    _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10624);
+   } else {
+    HEAP32[i7 >> 2] = (i4 << 14) + 2147467264 | i6 & 16383;
+    break;
+   }
+  }
+ } while (0);
+ i3 = i3 + 20 | 0;
+ i4 = HEAP32[i3 >> 2] | 0;
+ HEAP32[i1 + 24 >> 2] = HEAP32[i1 + 20 >> 2];
+ i5 = i1 + 28 | 0;
+ if ((i4 | 0) == -1) {
+  HEAP32[i3 >> 2] = -1;
+  STACKTOP = i2;
+  return;
+ }
+ i8 = HEAP32[i5 >> 2] | 0;
+ if ((i8 | 0) == -1) {
+  HEAP32[i5 >> 2] = i4;
+  HEAP32[i3 >> 2] = -1;
+  STACKTOP = i2;
+  return;
+ }
+ i7 = HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0;
+ while (1) {
+  i5 = i7 + (i8 << 2) | 0;
+  i6 = HEAP32[i5 >> 2] | 0;
+  i9 = (i6 >>> 14) + -131071 | 0;
+  if ((i9 | 0) == -1) {
+   break;
+  }
+  i9 = i8 + 1 + i9 | 0;
+  if ((i9 | 0) == -1) {
+   break;
+  } else {
+   i8 = i9;
+  }
+ }
+ i4 = i4 + ~i8 | 0;
+ if ((((i4 | 0) > -1 ? i4 : 0 - i4 | 0) | 0) > 131071) {
+  _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10624);
+ }
+ HEAP32[i5 >> 2] = (i4 << 14) + 2147467264 | i6 & 16383;
+ HEAP32[i3 >> 2] = -1;
+ STACKTOP = i2;
+ return;
+}
+function _luaV_settable(i2, i11, i7, i9) {
+ i2 = i2 | 0;
+ i11 = i11 | 0;
+ i7 = i7 | 0;
+ i9 = i9 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i10 = 0, i12 = 0, i13 = 0, i14 = 0;
+ i6 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i5 = i6;
+ i4 = i2 + 12 | 0;
+ i3 = i11;
+ i13 = HEAP32[i11 + 8 >> 2] | 0;
+ i12 = 0;
+ while (1) {
+  i11 = i3 + 8 | 0;
+  if ((i13 | 0) != 69) {
+   i14 = _luaT_gettmbyobj(i2, i3, 1) | 0;
+   i13 = HEAP32[i14 + 8 >> 2] | 0;
+   if ((i13 | 0) == 0) {
+    i1 = 16;
+    break;
+   }
+  } else {
+   i8 = HEAP32[i3 >> 2] | 0;
+   i13 = _luaH_get(i8, i7) | 0;
+   if ((HEAP32[i13 + 8 >> 2] | 0) != 0) {
+    i10 = i13;
+    break;
+   }
+   i14 = HEAP32[i8 + 8 >> 2] | 0;
+   if ((i14 | 0) == 0) {
+    i1 = 9;
+    break;
+   }
+   if (!((HEAP8[i14 + 6 | 0] & 2) == 0)) {
+    i1 = 9;
+    break;
+   }
+   i14 = _luaT_gettm(i14, 1, HEAP32[(HEAP32[i4 >> 2] | 0) + 188 >> 2] | 0) | 0;
+   if ((i14 | 0) == 0) {
+    i1 = 9;
+    break;
+   }
+   i13 = HEAP32[i14 + 8 >> 2] | 0;
+  }
+  i12 = i12 + 1 | 0;
+  if ((i13 & 15 | 0) == 6) {
+   i1 = 18;
+   break;
+  }
+  if ((i12 | 0) < 100) {
+   i3 = i14;
+  } else {
+   i1 = 19;
+   break;
+  }
+ }
+ if ((i1 | 0) == 9) {
+  if ((i13 | 0) == 5192) {
+   i10 = _luaH_newkey(i2, i8, i7) | 0;
+  } else {
+   i10 = i13;
+  }
+ } else if ((i1 | 0) == 16) {
+  _luaG_typeerror(i2, i3, 8944);
+ } else if ((i1 | 0) == 18) {
+  i13 = i2 + 8 | 0;
+  i8 = HEAP32[i13 >> 2] | 0;
+  HEAP32[i13 >> 2] = i8 + 16;
+  i5 = i14;
+  i12 = HEAP32[i5 + 4 >> 2] | 0;
+  i10 = i8;
+  HEAP32[i10 >> 2] = HEAP32[i5 >> 2];
+  HEAP32[i10 + 4 >> 2] = i12;
+  HEAP32[i8 + 8 >> 2] = HEAP32[i14 + 8 >> 2];
+  i14 = HEAP32[i13 >> 2] | 0;
+  HEAP32[i13 >> 2] = i14 + 16;
+  i8 = i3;
+  i10 = HEAP32[i8 + 4 >> 2] | 0;
+  i12 = i14;
+  HEAP32[i12 >> 2] = HEAP32[i8 >> 2];
+  HEAP32[i12 + 4 >> 2] = i10;
+  HEAP32[i14 + 8 >> 2] = HEAP32[i11 >> 2];
+  i14 = HEAP32[i13 >> 2] | 0;
+  HEAP32[i13 >> 2] = i14 + 16;
+  i12 = i7;
+  i11 = HEAP32[i12 + 4 >> 2] | 0;
+  i10 = i14;
+  HEAP32[i10 >> 2] = HEAP32[i12 >> 2];
+  HEAP32[i10 + 4 >> 2] = i11;
+  HEAP32[i14 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+  i14 = HEAP32[i13 >> 2] | 0;
+  HEAP32[i13 >> 2] = i14 + 16;
+  i10 = i9;
+  i11 = HEAP32[i10 + 4 >> 2] | 0;
+  i12 = i14;
+  HEAP32[i12 >> 2] = HEAP32[i10 >> 2];
+  HEAP32[i12 + 4 >> 2] = i11;
+  HEAP32[i14 + 8 >> 2] = HEAP32[i9 + 8 >> 2];
+  _luaD_call(i2, (HEAP32[i13 >> 2] | 0) + -64 | 0, 0, HEAP8[(HEAP32[i2 + 16 >> 2] | 0) + 18 | 0] & 1);
+  STACKTOP = i6;
+  return;
+ } else if ((i1 | 0) == 19) {
+  _luaG_runerror(i2, 8976, i5);
+ }
+ i12 = i9;
+ i13 = HEAP32[i12 + 4 >> 2] | 0;
+ i14 = i10;
+ HEAP32[i14 >> 2] = HEAP32[i12 >> 2];
+ HEAP32[i14 + 4 >> 2] = i13;
+ i14 = i9 + 8 | 0;
+ HEAP32[i10 + 8 >> 2] = HEAP32[i14 >> 2];
+ HEAP8[i8 + 6 | 0] = 0;
+ if ((HEAP32[i14 >> 2] & 64 | 0) == 0) {
+  STACKTOP = i6;
+  return;
+ }
+ if ((HEAP8[(HEAP32[i9 >> 2] | 0) + 5 | 0] & 3) == 0) {
+  STACKTOP = i6;
+  return;
+ }
+ if ((HEAP8[i8 + 5 | 0] & 4) == 0) {
+  STACKTOP = i6;
+  return;
+ }
+ _luaC_barrierback_(i2, i8);
+ STACKTOP = i6;
+ return;
+}
+function _luaK_code(i4, i5) {
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0;
+ i2 = STACKTOP;
+ i1 = HEAP32[i4 >> 2] | 0;
+ i7 = i4 + 28 | 0;
+ i15 = HEAP32[i7 >> 2] | 0;
+ i3 = i4 + 20 | 0;
+ i8 = HEAP32[i3 >> 2] | 0;
+ do {
+  if (!((i15 | 0) == -1)) {
+   i11 = HEAP32[i1 + 12 >> 2] | 0;
+   while (1) {
+    i12 = i11 + (i15 << 2) | 0;
+    i14 = HEAP32[i12 >> 2] | 0;
+    i13 = (i14 >>> 14) + -131071 | 0;
+    if ((i13 | 0) == -1) {
+     i13 = -1;
+    } else {
+     i13 = i15 + 1 + i13 | 0;
+    }
+    if ((i15 | 0) > 0 ? (i9 = i11 + (i15 + -1 << 2) | 0, i10 = HEAP32[i9 >> 2] | 0, (HEAP8[5584 + (i10 & 63) | 0] | 0) < 0) : 0) {
+     i17 = i9;
+     i16 = i10;
+    } else {
+     i17 = i12;
+     i16 = i14;
+    }
+    if ((i16 & 63 | 0) == 28) {
+     HEAP32[i17 >> 2] = i16 & 8372224 | i16 >>> 23 << 6 | 27;
+     i14 = i8 + ~i15 | 0;
+     if ((((i14 | 0) > -1 ? i14 : 0 - i14 | 0) | 0) > 131071) {
+      i8 = 10;
+      break;
+     }
+     i14 = HEAP32[i12 >> 2] & 16383 | (i14 << 14) + 2147467264;
+    } else {
+     i15 = i8 + ~i15 | 0;
+     if ((((i15 | 0) > -1 ? i15 : 0 - i15 | 0) | 0) > 131071) {
+      i8 = 13;
+      break;
+     }
+     i14 = (i15 << 14) + 2147467264 | i14 & 16383;
+    }
+    HEAP32[i12 >> 2] = i14;
+    if ((i13 | 0) == -1) {
+     i8 = 16;
+     break;
+    } else {
+     i15 = i13;
+    }
+   }
+   if ((i8 | 0) == 10) {
+    _luaX_syntaxerror(HEAP32[i4 + 12 >> 2] | 0, 10624);
+   } else if ((i8 | 0) == 13) {
+    _luaX_syntaxerror(HEAP32[i4 + 12 >> 2] | 0, 10624);
+   } else if ((i8 | 0) == 16) {
+    i6 = HEAP32[i3 >> 2] | 0;
+    break;
+   }
+  } else {
+   i6 = i8;
+  }
+ } while (0);
+ HEAP32[i7 >> 2] = -1;
+ i7 = i1 + 48 | 0;
+ if ((i6 | 0) < (HEAP32[i7 >> 2] | 0)) {
+  i7 = i1 + 12 | 0;
+ } else {
+  i6 = i1 + 12 | 0;
+  HEAP32[i6 >> 2] = _luaM_growaux_(HEAP32[(HEAP32[i4 + 12 >> 2] | 0) + 52 >> 2] | 0, HEAP32[i6 >> 2] | 0, i7, 4, 2147483645, 10616) | 0;
+  i7 = i6;
+  i6 = HEAP32[i3 >> 2] | 0;
+ }
+ HEAP32[(HEAP32[i7 >> 2] | 0) + (i6 << 2) >> 2] = i5;
+ i5 = HEAP32[i3 >> 2] | 0;
+ i6 = i1 + 52 | 0;
+ i4 = i4 + 12 | 0;
+ if ((i5 | 0) < (HEAP32[i6 >> 2] | 0)) {
+  i15 = i1 + 20 | 0;
+  i17 = i5;
+  i16 = HEAP32[i4 >> 2] | 0;
+  i16 = i16 + 8 | 0;
+  i16 = HEAP32[i16 >> 2] | 0;
+  i15 = HEAP32[i15 >> 2] | 0;
+  i17 = i15 + (i17 << 2) | 0;
+  HEAP32[i17 >> 2] = i16;
+  i17 = HEAP32[i3 >> 2] | 0;
+  i16 = i17 + 1 | 0;
+  HEAP32[i3 >> 2] = i16;
+  STACKTOP = i2;
+  return i17 | 0;
+ } else {
+  i15 = i1 + 20 | 0;
+  HEAP32[i15 >> 2] = _luaM_growaux_(HEAP32[(HEAP32[i4 >> 2] | 0) + 52 >> 2] | 0, HEAP32[i15 >> 2] | 0, i6, 4, 2147483645, 10616) | 0;
+  i17 = HEAP32[i3 >> 2] | 0;
+  i16 = HEAP32[i4 >> 2] | 0;
+  i16 = i16 + 8 | 0;
+  i16 = HEAP32[i16 >> 2] | 0;
+  i15 = HEAP32[i15 >> 2] | 0;
+  i17 = i15 + (i17 << 2) | 0;
+  HEAP32[i17 >> 2] = i16;
+  i17 = HEAP32[i3 >> 2] | 0;
+  i16 = i17 + 1 | 0;
+  HEAP32[i3 >> 2] = i16;
+  STACKTOP = i2;
+  return i17 | 0;
+ }
+ return 0;
+}
+function _luaH_next(i9, i5, i2) {
+ i9 = i9 | 0;
+ i5 = i5 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, d14 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i8 = i1 + 8 | 0;
+ i11 = i1;
+ i3 = i2 + 8 | 0;
+ i10 = HEAP32[i3 >> 2] | 0;
+ do {
+  if ((i10 | 0) != 0) {
+   if ((((i10 | 0) == 3 ? (d14 = +HEAPF64[i2 >> 3], HEAPF64[i11 >> 3] = d14 + 6755399441055744.0, i12 = HEAP32[i11 >> 2] | 0, +(i12 | 0) == d14) : 0) ? (i12 | 0) > 0 : 0) ? (i13 = HEAP32[i5 + 28 >> 2] | 0, (i12 | 0) <= (i13 | 0)) : 0) {
+    i6 = i13;
+    i7 = i12 + -1 | 0;
+    break;
+   }
+   i10 = _mainposition(i5, i2) | 0;
+   while (1) {
+    i4 = i10 + 16 | 0;
+    i11 = i10 + 24 | 0;
+    i12 = HEAP32[i11 >> 2] | 0;
+    if ((i12 | 0) == (HEAP32[i3 >> 2] | 0)) {
+     if ((_luaV_equalobj_(0, i4, i2) | 0) != 0) {
+      i4 = 15;
+      break;
+     }
+     i12 = HEAP32[i11 >> 2] | 0;
+    }
+    if (((i12 | 0) == 11 ? (HEAP32[i3 >> 2] & 64 | 0) != 0 : 0) ? (HEAP32[i4 >> 2] | 0) == (HEAP32[i2 >> 2] | 0) : 0) {
+     i4 = 15;
+     break;
+    }
+    i10 = HEAP32[i10 + 28 >> 2] | 0;
+    if ((i10 | 0) == 0) {
+     i4 = 18;
+     break;
+    }
+   }
+   if ((i4 | 0) == 15) {
+    i7 = HEAP32[i5 + 28 >> 2] | 0;
+    i6 = i7;
+    i7 = (i10 - (HEAP32[i5 + 16 >> 2] | 0) >> 5) + i7 | 0;
+    break;
+   } else if ((i4 | 0) == 18) {
+    _luaG_runerror(i9, 8064, i8);
+   }
+  } else {
+   i6 = HEAP32[i5 + 28 >> 2] | 0;
+   i7 = -1;
+  }
+ } while (0);
+ i8 = i5 + 12 | 0;
+ while (1) {
+  i9 = i7 + 1 | 0;
+  if ((i9 | 0) >= (i6 | 0)) {
+   break;
+  }
+  i11 = HEAP32[i8 >> 2] | 0;
+  i10 = i11 + (i9 << 4) + 8 | 0;
+  if ((HEAP32[i10 >> 2] | 0) == 0) {
+   i7 = i9;
+  } else {
+   i4 = 21;
+   break;
+  }
+ }
+ if ((i4 | 0) == 21) {
+  HEAPF64[i2 >> 3] = +(i7 + 2 | 0);
+  HEAP32[i3 >> 2] = 3;
+  i11 = i11 + (i9 << 4) | 0;
+  i12 = HEAP32[i11 + 4 >> 2] | 0;
+  i13 = i2 + 16 | 0;
+  HEAP32[i13 >> 2] = HEAP32[i11 >> 2];
+  HEAP32[i13 + 4 >> 2] = i12;
+  HEAP32[i2 + 24 >> 2] = HEAP32[i10 >> 2];
+  i13 = 1;
+  STACKTOP = i1;
+  return i13 | 0;
+ }
+ i8 = i9 - i6 | 0;
+ i6 = 1 << (HEAPU8[i5 + 7 | 0] | 0);
+ if ((i8 | 0) >= (i6 | 0)) {
+  i13 = 0;
+  STACKTOP = i1;
+  return i13 | 0;
+ }
+ i7 = i5 + 16 | 0;
+ i5 = HEAP32[i7 >> 2] | 0;
+ while (1) {
+  i9 = i8 + 1 | 0;
+  if ((HEAP32[i5 + (i8 << 5) + 8 >> 2] | 0) != 0) {
+   break;
+  }
+  if ((i9 | 0) < (i6 | 0)) {
+   i8 = i9;
+  } else {
+   i2 = 0;
+   i4 = 27;
+   break;
+  }
+ }
+ if ((i4 | 0) == 27) {
+  STACKTOP = i1;
+  return i2 | 0;
+ }
+ i11 = i5 + (i8 << 5) + 16 | 0;
+ i10 = HEAP32[i11 + 4 >> 2] | 0;
+ i13 = i2;
+ HEAP32[i13 >> 2] = HEAP32[i11 >> 2];
+ HEAP32[i13 + 4 >> 2] = i10;
+ HEAP32[i3 >> 2] = HEAP32[i5 + (i8 << 5) + 24 >> 2];
+ i13 = HEAP32[i7 >> 2] | 0;
+ i10 = i13 + (i8 << 5) | 0;
+ i11 = HEAP32[i10 + 4 >> 2] | 0;
+ i12 = i2 + 16 | 0;
+ HEAP32[i12 >> 2] = HEAP32[i10 >> 2];
+ HEAP32[i12 + 4 >> 2] = i11;
+ HEAP32[i2 + 24 >> 2] = HEAP32[i13 + (i8 << 5) + 8 >> 2];
+ i13 = 1;
+ STACKTOP = i1;
+ return i13 | 0;
+}
+function _g_read(i1, i3, i2) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 1056 | 0;
+ i7 = i4 + 8 | 0;
+ i9 = i4;
+ i10 = _lua_gettop(i1) | 0;
+ _clearerr(i3 | 0);
+ L1 : do {
+  if ((i10 | 0) == 1) {
+   i11 = i2 + 1 | 0;
+   i12 = _read_line(i1, i3, 1) | 0;
+  } else {
+   _luaL_checkstack(i1, i10 + 19 | 0, 3256);
+   i6 = i7 + 8 | 0;
+   i5 = i7 + 8 | 0;
+   i10 = i10 + -2 | 0;
+   i11 = i2;
+   L4 : while (1) {
+    do {
+     if ((_lua_type(i1, i11) | 0) == 3) {
+      i12 = _lua_tointegerx(i1, i11, 0) | 0;
+      if ((i12 | 0) == 0) {
+       i12 = _fgetc(i3 | 0) | 0;
+       _ungetc(i12 | 0, i3 | 0) | 0;
+       _lua_pushlstring(i1, 0, 0) | 0;
+       i12 = (i12 | 0) != -1 | 0;
+       break;
+      } else {
+       _luaL_buffinit(i1, i7);
+       i12 = _fread(_luaL_prepbuffsize(i7, i12) | 0, 1, i12 | 0, i3 | 0) | 0;
+       HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i12;
+       _luaL_pushresult(i7);
+       i12 = (i12 | 0) != 0 | 0;
+       break;
+      }
+     } else {
+      i12 = _lua_tolstring(i1, i11, 0) | 0;
+      if (!((i12 | 0) != 0 ? (HEAP8[i12] | 0) == 42 : 0)) {
+       _luaL_argerror(i1, i11, 3280) | 0;
+      }
+      i12 = HEAP8[i12 + 1 | 0] | 0;
+      if ((i12 | 0) == 110) {
+       HEAP32[i7 >> 2] = i9;
+       if ((_fscanf(i3 | 0, 3312, i7 | 0) | 0) != 1) {
+        i8 = 14;
+        break L4;
+       }
+       _lua_pushnumber(i1, +HEAPF64[i9 >> 3]);
+       i12 = 1;
+       break;
+      } else if ((i12 | 0) == 108) {
+       i12 = _read_line(i1, i3, 1) | 0;
+       break;
+      } else if ((i12 | 0) == 76) {
+       i12 = _read_line(i1, i3, 0) | 0;
+       break;
+      } else if ((i12 | 0) == 97) {
+       _luaL_buffinit(i1, i7);
+       i12 = _fread(_luaL_prepbuffsize(i7, 1024) | 0, 1, 1024, i3 | 0) | 0;
+       HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + i12;
+       if (!(i12 >>> 0 < 1024)) {
+        i12 = 1024;
+        do {
+         i12 = i12 << (i12 >>> 0 < 1073741824);
+         i13 = _fread(_luaL_prepbuffsize(i7, i12) | 0, 1, i12 | 0, i3 | 0) | 0;
+         HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + i13;
+        } while (!(i13 >>> 0 < i12 >>> 0));
+       }
+       _luaL_pushresult(i7);
+       i12 = 1;
+       break;
+      } else {
+       break L4;
+      }
+     }
+    } while (0);
+    i11 = i11 + 1 | 0;
+    if ((i10 | 0) == 0 | (i12 | 0) == 0) {
+     break L1;
+    } else {
+     i10 = i10 + -1 | 0;
+    }
+   }
+   if ((i8 | 0) == 14) {
+    _lua_pushnil(i1);
+    i11 = i11 + 1 | 0;
+    i12 = 0;
+    break;
+   }
+   i13 = _luaL_argerror(i1, i11, 3296) | 0;
+   STACKTOP = i4;
+   return i13 | 0;
+  }
+ } while (0);
+ if ((_ferror(i3 | 0) | 0) != 0) {
+  i13 = _luaL_fileresult(i1, 0, 0) | 0;
+  STACKTOP = i4;
+  return i13 | 0;
+ }
+ if ((i12 | 0) == 0) {
+  _lua_settop(i1, -2);
+  _lua_pushnil(i1);
+ }
+ i13 = i11 - i2 | 0;
+ STACKTOP = i4;
+ return i13 | 0;
+}
+function _luaY_parser(i8, i12, i10, i11, i9, i13) {
+ i8 = i8 | 0;
+ i12 = i12 | 0;
+ i10 = i10 | 0;
+ i11 = i11 | 0;
+ i9 = i9 | 0;
+ i13 = i13 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i14 = 0, i15 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 176 | 0;
+ i5 = i2 + 156 | 0;
+ i7 = i2 + 80 | 0;
+ i4 = i2;
+ i6 = i2 + 104 | 0;
+ i3 = _luaF_newLclosure(i8, 1) | 0;
+ i15 = i8 + 8 | 0;
+ i14 = HEAP32[i15 >> 2] | 0;
+ HEAP32[i14 >> 2] = i3;
+ HEAP32[i14 + 8 >> 2] = 70;
+ i14 = (HEAP32[i15 >> 2] | 0) + 16 | 0;
+ HEAP32[i15 >> 2] = i14;
+ if (((HEAP32[i8 + 24 >> 2] | 0) - i14 | 0) < 16) {
+  _luaD_growstack(i8, 0);
+ }
+ i14 = _luaF_newproto(i8) | 0;
+ HEAP32[i3 + 12 >> 2] = i14;
+ HEAP32[i6 >> 2] = i14;
+ i9 = _luaS_new(i8, i9) | 0;
+ HEAP32[(HEAP32[i6 >> 2] | 0) + 36 >> 2] = i9;
+ HEAP32[i4 + 60 >> 2] = i10;
+ i9 = i4 + 64 | 0;
+ HEAP32[i9 >> 2] = i11;
+ HEAP32[i11 + 28 >> 2] = 0;
+ HEAP32[i11 + 16 >> 2] = 0;
+ HEAP32[i11 + 4 >> 2] = 0;
+ _luaX_setinput(i8, i4, i12, HEAP32[(HEAP32[i6 >> 2] | 0) + 36 >> 2] | 0, i13);
+ i10 = HEAP32[i4 + 52 >> 2] | 0;
+ i13 = i4 + 48 | 0;
+ HEAP32[i6 + 8 >> 2] = HEAP32[i13 >> 2];
+ i8 = i6 + 12 | 0;
+ HEAP32[i8 >> 2] = i4;
+ HEAP32[i13 >> 2] = i6;
+ HEAP32[i6 + 20 >> 2] = 0;
+ HEAP32[i6 + 24 >> 2] = 0;
+ HEAP32[i6 + 28 >> 2] = -1;
+ HEAP32[i6 + 32 >> 2] = 0;
+ HEAP32[i6 + 36 >> 2] = 0;
+ i13 = i6 + 44 | 0;
+ HEAP32[i13 + 0 >> 2] = 0;
+ HEAP8[i13 + 4 | 0] = 0;
+ HEAP32[i6 + 40 >> 2] = HEAP32[(HEAP32[i9 >> 2] | 0) + 4 >> 2];
+ i9 = i6 + 16 | 0;
+ HEAP32[i9 >> 2] = 0;
+ i13 = HEAP32[i6 >> 2] | 0;
+ HEAP32[i13 + 36 >> 2] = HEAP32[i4 + 68 >> 2];
+ HEAP8[i13 + 78 | 0] = 2;
+ i13 = _luaH_new(i10) | 0;
+ HEAP32[i6 + 4 >> 2] = i13;
+ i14 = i10 + 8 | 0;
+ i15 = HEAP32[i14 >> 2] | 0;
+ HEAP32[i15 >> 2] = i13;
+ HEAP32[i15 + 8 >> 2] = 69;
+ i15 = (HEAP32[i14 >> 2] | 0) + 16 | 0;
+ HEAP32[i14 >> 2] = i15;
+ if (((HEAP32[i10 + 24 >> 2] | 0) - i15 | 0) < 16) {
+  _luaD_growstack(i10, 0);
+ }
+ HEAP8[i5 + 10 | 0] = 0;
+ HEAP8[i5 + 8 | 0] = HEAP8[i6 + 46 | 0] | 0;
+ i15 = HEAP32[(HEAP32[i8 >> 2] | 0) + 64 >> 2] | 0;
+ HEAP16[i5 + 4 >> 1] = HEAP32[i15 + 28 >> 2];
+ HEAP16[i5 + 6 >> 1] = HEAP32[i15 + 16 >> 2];
+ HEAP8[i5 + 9 | 0] = 0;
+ HEAP32[i5 >> 2] = HEAP32[i9 >> 2];
+ HEAP32[i9 >> 2] = i5;
+ HEAP8[(HEAP32[i6 >> 2] | 0) + 77 | 0] = 1;
+ HEAP32[i7 + 16 >> 2] = -1;
+ HEAP32[i7 + 20 >> 2] = -1;
+ HEAP32[i7 >> 2] = 7;
+ HEAP32[i7 + 8 >> 2] = 0;
+ _newupvalue(i6, HEAP32[i4 + 72 >> 2] | 0, i7) | 0;
+ _luaX_next(i4);
+ i5 = i4 + 16 | 0;
+ L7 : while (1) {
+  i6 = HEAP32[i5 >> 2] | 0;
+  switch (i6 | 0) {
+  case 277:
+  case 286:
+  case 262:
+  case 261:
+  case 260:
+   {
+    break L7;
+   }
+  default:
+   {}
+  }
+  _statement(i4);
+  if ((i6 | 0) == 274) {
+   i1 = 8;
+   break;
+  }
+ }
+ if ((i1 | 0) == 8) {
+  i6 = HEAP32[i5 >> 2] | 0;
+ }
+ if ((i6 | 0) == 286) {
+  _close_func(i4);
+  STACKTOP = i2;
+  return i3 | 0;
+ } else {
+  _error_expected(i4, 286);
+ }
+ return 0;
+}
+function _luaV_lessthan(i5, i4, i2) {
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i1 = STACKTOP;
+ i6 = i4 + 8 | 0;
+ i7 = HEAP32[i6 >> 2] | 0;
+ if ((i7 | 0) == 3) {
+  if ((HEAP32[i2 + 8 >> 2] | 0) == 3) {
+   i9 = +HEAPF64[i4 >> 3] < +HEAPF64[i2 >> 3] | 0;
+   STACKTOP = i1;
+   return i9 | 0;
+  }
+ } else {
+  if ((i7 & 15 | 0) == 4 ? (HEAP32[i2 + 8 >> 2] & 15 | 0) == 4 : 0) {
+   i6 = HEAP32[i4 >> 2] | 0;
+   i4 = HEAP32[i2 >> 2] | 0;
+   i3 = i6 + 16 | 0;
+   i5 = i4 + 16 | 0;
+   i7 = _strcmp(i3, i5) | 0;
+   L8 : do {
+    if ((i7 | 0) == 0) {
+     i2 = HEAP32[i6 + 12 >> 2] | 0;
+     i4 = HEAP32[i4 + 12 >> 2] | 0;
+     while (1) {
+      i7 = _strlen(i3 | 0) | 0;
+      i6 = (i7 | 0) == (i2 | 0);
+      if ((i7 | 0) == (i4 | 0)) {
+       break;
+      }
+      if (i6) {
+       i7 = -1;
+       break L8;
+      }
+      i6 = i7 + 1 | 0;
+      i3 = i3 + i6 | 0;
+      i5 = i5 + i6 | 0;
+      i7 = _strcmp(i3, i5) | 0;
+      if ((i7 | 0) == 0) {
+       i2 = i2 - i6 | 0;
+       i4 = i4 - i6 | 0;
+      } else {
+       break L8;
+      }
+     }
+     i7 = i6 & 1 ^ 1;
+    }
+   } while (0);
+   i9 = i7 >>> 31;
+   STACKTOP = i1;
+   return i9 | 0;
+  }
+ }
+ i8 = i5 + 8 | 0;
+ i7 = HEAP32[i8 >> 2] | 0;
+ i9 = _luaT_gettmbyobj(i5, i4, 13) | 0;
+ if ((HEAP32[i9 + 8 >> 2] | 0) == 0) {
+  i9 = _luaT_gettmbyobj(i5, i2, 13) | 0;
+  if ((HEAP32[i9 + 8 >> 2] | 0) == 0) {
+   _luaG_ordererror(i5, i4, i2);
+  } else {
+   i3 = i9;
+  }
+ } else {
+  i3 = i9;
+ }
+ i10 = i5 + 28 | 0;
+ i9 = i7 - (HEAP32[i10 >> 2] | 0) | 0;
+ i11 = HEAP32[i8 >> 2] | 0;
+ HEAP32[i8 >> 2] = i11 + 16;
+ i13 = i3;
+ i12 = HEAP32[i13 + 4 >> 2] | 0;
+ i7 = i11;
+ HEAP32[i7 >> 2] = HEAP32[i13 >> 2];
+ HEAP32[i7 + 4 >> 2] = i12;
+ HEAP32[i11 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+ i3 = HEAP32[i8 >> 2] | 0;
+ HEAP32[i8 >> 2] = i3 + 16;
+ i11 = i4;
+ i7 = HEAP32[i11 + 4 >> 2] | 0;
+ i4 = i3;
+ HEAP32[i4 >> 2] = HEAP32[i11 >> 2];
+ HEAP32[i4 + 4 >> 2] = i7;
+ HEAP32[i3 + 8 >> 2] = HEAP32[i6 >> 2];
+ i3 = HEAP32[i8 >> 2] | 0;
+ HEAP32[i8 >> 2] = i3 + 16;
+ i4 = i2;
+ i7 = HEAP32[i4 + 4 >> 2] | 0;
+ i6 = i3;
+ HEAP32[i6 >> 2] = HEAP32[i4 >> 2];
+ HEAP32[i6 + 4 >> 2] = i7;
+ HEAP32[i3 + 8 >> 2] = HEAP32[i2 + 8 >> 2];
+ _luaD_call(i5, (HEAP32[i8 >> 2] | 0) + -48 | 0, 1, HEAP8[(HEAP32[i5 + 16 >> 2] | 0) + 18 | 0] & 1);
+ i2 = HEAP32[i10 >> 2] | 0;
+ i3 = HEAP32[i8 >> 2] | 0;
+ i5 = i3 + -16 | 0;
+ HEAP32[i8 >> 2] = i5;
+ i6 = HEAP32[i5 + 4 >> 2] | 0;
+ i7 = i2 + i9 | 0;
+ HEAP32[i7 >> 2] = HEAP32[i5 >> 2];
+ HEAP32[i7 + 4 >> 2] = i6;
+ HEAP32[i2 + (i9 + 8) >> 2] = HEAP32[i3 + -8 >> 2];
+ i2 = HEAP32[i8 >> 2] | 0;
+ i3 = HEAP32[i2 + 8 >> 2] | 0;
+ if ((i3 | 0) != 0) {
+  if ((i3 | 0) == 1) {
+   i2 = (HEAP32[i2 >> 2] | 0) != 0;
+  } else {
+   i2 = 1;
+  }
+ } else {
+  i2 = 0;
+ }
+ i13 = i2 & 1;
+ STACKTOP = i1;
+ return i13 | 0;
+}
+function _discharge2reg(i4, i3, i1) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, d11 = 0.0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i9 = i2 + 16 | 0;
+ i8 = i2;
+ _luaK_dischargevars(i4, i3);
+ i10 = HEAP32[i3 >> 2] | 0;
+ L1 : do {
+  switch (i10 | 0) {
+  case 5:
+   {
+    d11 = +HEAPF64[i3 + 8 >> 3];
+    HEAPF64[i9 >> 3] = d11;
+    i5 = HEAP32[(HEAP32[i4 + 12 >> 2] | 0) + 52 >> 2] | 0;
+    HEAPF64[i8 >> 3] = d11;
+    HEAP32[i8 + 8 >> 2] = 3;
+    if (d11 != d11 | 0.0 != 0.0 | d11 == 0.0) {
+     i10 = i5 + 8 | 0;
+     i7 = HEAP32[i10 >> 2] | 0;
+     HEAP32[i10 >> 2] = i7 + 16;
+     i5 = _luaS_newlstr(i5, i9, 8) | 0;
+     HEAP32[i7 >> 2] = i5;
+     HEAP32[i7 + 8 >> 2] = HEAPU8[i5 + 4 | 0] | 0 | 64;
+     i5 = _addk(i4, (HEAP32[i10 >> 2] | 0) + -16 | 0, i8) | 0;
+     HEAP32[i10 >> 2] = (HEAP32[i10 >> 2] | 0) + -16;
+    } else {
+     i5 = _addk(i4, i8, i8) | 0;
+    }
+    i6 = i1 << 6;
+    if ((i5 | 0) < 262144) {
+     _luaK_code(i4, i6 | i5 << 14 | 1) | 0;
+     break L1;
+    } else {
+     _luaK_code(i4, i6 | 2) | 0;
+     _luaK_code(i4, i5 << 6 | 39) | 0;
+     break L1;
+    }
+   }
+  case 2:
+  case 3:
+   {
+    _luaK_code(i4, i1 << 6 | ((i10 | 0) == 2) << 23 | 3) | 0;
+    break;
+   }
+  case 4:
+   {
+    i6 = HEAP32[i3 + 8 >> 2] | 0;
+    i5 = i1 << 6;
+    if ((i6 | 0) < 262144) {
+     _luaK_code(i4, i5 | i6 << 14 | 1) | 0;
+     break L1;
+    } else {
+     _luaK_code(i4, i5 | 2) | 0;
+     _luaK_code(i4, i6 << 6 | 39) | 0;
+     break L1;
+    }
+   }
+  case 1:
+   {
+    i9 = i1 + 1 | 0;
+    i8 = HEAP32[i4 + 20 >> 2] | 0;
+    do {
+     if ((i8 | 0) > (HEAP32[i4 + 24 >> 2] | 0) ? (i5 = (HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] | 0) + (i8 + -1 << 2) | 0, i6 = HEAP32[i5 >> 2] | 0, (i6 & 63 | 0) == 4) : 0) {
+      i10 = i6 >>> 6 & 255;
+      i8 = i10 + (i6 >>> 23) | 0;
+      if (!((i10 | 0) <= (i1 | 0) ? (i8 + 1 | 0) >= (i1 | 0) : 0)) {
+       i7 = 6;
+      }
+      if ((i7 | 0) == 6 ? (i10 | 0) < (i1 | 0) | (i10 | 0) > (i9 | 0) : 0) {
+       break;
+      }
+      i4 = (i10 | 0) < (i1 | 0) ? i10 : i1;
+      HEAP32[i5 >> 2] = i4 << 6 & 16320 | i6 & 8372287 | ((i8 | 0) > (i1 | 0) ? i8 : i1) - i4 << 23;
+      break L1;
+     }
+    } while (0);
+    _luaK_code(i4, i1 << 6 | 4) | 0;
+    break;
+   }
+  case 6:
+   {
+    i5 = HEAP32[i3 + 8 >> 2] | 0;
+    if ((i5 | 0) != (i1 | 0)) {
+     _luaK_code(i4, i5 << 23 | i1 << 6) | 0;
+    }
+    break;
+   }
+  case 11:
+   {
+    i10 = (HEAP32[(HEAP32[i4 >> 2] | 0) + 12 >> 2] | 0) + (HEAP32[i3 + 8 >> 2] << 2) | 0;
+    HEAP32[i10 >> 2] = HEAP32[i10 >> 2] & -16321 | i1 << 6 & 16320;
+    break;
+   }
+  default:
+   {
+    STACKTOP = i2;
+    return;
+   }
+  }
+ } while (0);
+ HEAP32[i3 + 8 >> 2] = i1;
+ HEAP32[i3 >> 2] = 6;
+ STACKTOP = i2;
+ return;
+}
+function _unroll(i3, i4) {
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0;
+ i9 = STACKTOP;
+ i11 = i3 + 16 | 0;
+ i13 = HEAP32[i11 >> 2] | 0;
+ i5 = i3 + 72 | 0;
+ if ((i13 | 0) == (i5 | 0)) {
+  STACKTOP = i9;
+  return;
+ }
+ i6 = i3 + 8 | 0;
+ i10 = i3 + 40 | 0;
+ i7 = i3 + 20 | 0;
+ i8 = i3 + 28 | 0;
+ i4 = i3 + 68 | 0;
+ do {
+  i12 = i13 + 18 | 0;
+  i14 = HEAP8[i12] | 0;
+  if ((i14 & 1) == 0) {
+   i14 = i14 & 255;
+   if ((i14 & 16 | 0) != 0) {
+    HEAP8[i12] = i14 & 239;
+    HEAP32[i4 >> 2] = HEAP32[i13 + 32 >> 2];
+   }
+   if ((HEAP16[i13 + 16 >> 1] | 0) == -1 ? (i2 = (HEAP32[i11 >> 2] | 0) + 4 | 0, i1 = HEAP32[i6 >> 2] | 0, (HEAP32[i2 >> 2] | 0) >>> 0 < i1 >>> 0) : 0) {
+    HEAP32[i2 >> 2] = i1;
+   }
+   i14 = HEAP8[i12] | 0;
+   if ((i14 & 32) == 0) {
+    HEAP8[i13 + 37 | 0] = 1;
+   }
+   HEAP8[i12] = i14 & 199 | 8;
+   i14 = FUNCTION_TABLE_ii[HEAP32[i13 + 28 >> 2] & 255](i3) | 0;
+   i14 = (HEAP32[i6 >> 2] | 0) + (0 - i14 << 4) | 0;
+   i13 = HEAP32[i11 >> 2] | 0;
+   i12 = HEAPU8[i10] | 0;
+   if ((i12 & 6 | 0) == 0) {
+    i15 = i13 + 8 | 0;
+   } else {
+    if ((i12 & 2 | 0) != 0) {
+     i14 = i14 - (HEAP32[i8 >> 2] | 0) | 0;
+     _luaD_hook(i3, 1, -1);
+     i14 = (HEAP32[i8 >> 2] | 0) + i14 | 0;
+    }
+    i15 = i13 + 8 | 0;
+    HEAP32[i7 >> 2] = HEAP32[(HEAP32[i15 >> 2] | 0) + 28 >> 2];
+   }
+   i12 = HEAP32[i13 >> 2] | 0;
+   i13 = HEAP16[i13 + 16 >> 1] | 0;
+   HEAP32[i11 >> 2] = HEAP32[i15 >> 2];
+   L25 : do {
+    if (!(i13 << 16 >> 16 == 0)) {
+     i15 = i13 << 16 >> 16;
+     if (i14 >>> 0 < (HEAP32[i6 >> 2] | 0) >>> 0) {
+      i13 = i14;
+      i14 = i15;
+      i15 = i12;
+      while (1) {
+       i12 = i15 + 16 | 0;
+       i18 = i13;
+       i17 = HEAP32[i18 + 4 >> 2] | 0;
+       i16 = i15;
+       HEAP32[i16 >> 2] = HEAP32[i18 >> 2];
+       HEAP32[i16 + 4 >> 2] = i17;
+       HEAP32[i15 + 8 >> 2] = HEAP32[i13 + 8 >> 2];
+       i14 = i14 + -1 | 0;
+       i13 = i13 + 16 | 0;
+       if ((i14 | 0) == 0) {
+        break L25;
+       }
+       if (i13 >>> 0 < (HEAP32[i6 >> 2] | 0) >>> 0) {
+        i15 = i12;
+       } else {
+        i13 = i14;
+        break;
+       }
+      }
+     } else {
+      i13 = i15;
+     }
+     if ((i13 | 0) > 0) {
+      i14 = i13;
+      i15 = i12;
+      while (1) {
+       i14 = i14 + -1 | 0;
+       HEAP32[i15 + 8 >> 2] = 0;
+       if ((i14 | 0) <= 0) {
+        break;
+       } else {
+        i15 = i15 + 16 | 0;
+       }
+      }
+      i12 = i12 + (i13 << 4) | 0;
+     }
+    }
+   } while (0);
+   HEAP32[i6 >> 2] = i12;
+  } else {
+   _luaV_finishOp(i3);
+   _luaV_execute(i3);
+  }
+  i13 = HEAP32[i11 >> 2] | 0;
+ } while ((i13 | 0) != (i5 | 0));
+ STACKTOP = i9;
+ return;
+}
+function _traverseephemeron(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0;
+ i3 = STACKTOP;
+ i11 = i2 + 16 | 0;
+ i9 = HEAP32[i11 >> 2] | 0;
+ i5 = i9 + (1 << (HEAPU8[i2 + 7 | 0] | 0) << 5) | 0;
+ i10 = i2 + 28 | 0;
+ i13 = HEAP32[i10 >> 2] | 0;
+ if ((i13 | 0) > 0) {
+  i9 = i2 + 12 | 0;
+  i12 = 0;
+  i8 = 0;
+  do {
+   i14 = HEAP32[i9 >> 2] | 0;
+   if ((HEAP32[i14 + (i12 << 4) + 8 >> 2] & 64 | 0) != 0 ? (i7 = HEAP32[i14 + (i12 << 4) >> 2] | 0, !((HEAP8[i7 + 5 | 0] & 3) == 0)) : 0) {
+    _reallymarkobject(i1, i7);
+    i13 = HEAP32[i10 >> 2] | 0;
+    i8 = 1;
+   }
+   i12 = i12 + 1 | 0;
+  } while ((i12 | 0) < (i13 | 0));
+  i9 = HEAP32[i11 >> 2] | 0;
+ } else {
+  i8 = 0;
+ }
+ if (i9 >>> 0 < i5 >>> 0) {
+  i7 = 0;
+  i10 = 0;
+  do {
+   i11 = i9 + 8 | 0;
+   i12 = HEAP32[i11 >> 2] | 0;
+   i14 = i9 + 24 | 0;
+   i13 = HEAP32[i14 >> 2] | 0;
+   i15 = (i13 & 64 | 0) == 0;
+   L14 : do {
+    if ((i12 | 0) == 0) {
+     if (!i15 ? !((HEAP8[(HEAP32[i9 + 16 >> 2] | 0) + 5 | 0] & 3) == 0) : 0) {
+      HEAP32[i14 >> 2] = 11;
+     }
+    } else {
+     do {
+      if (i15) {
+       i6 = i12;
+       i4 = 18;
+      } else {
+       i14 = HEAP32[i9 + 16 >> 2] | 0;
+       if ((i13 & 15 | 0) == 4) {
+        if ((i14 | 0) == 0) {
+         i6 = i12;
+         i4 = 18;
+         break;
+        }
+        if ((HEAP8[i14 + 5 | 0] & 3) == 0) {
+         i6 = i12;
+         i4 = 18;
+         break;
+        }
+        _reallymarkobject(i1, i14);
+        i6 = HEAP32[i11 >> 2] | 0;
+        i4 = 18;
+        break;
+       }
+       i11 = (i12 & 64 | 0) == 0;
+       if ((HEAP8[i14 + 5 | 0] & 3) == 0) {
+        if (i11) {
+         break L14;
+        } else {
+         break;
+        }
+       }
+       if (i11) {
+        i7 = 1;
+        break L14;
+       }
+       i7 = 1;
+       i10 = (HEAP8[(HEAP32[i9 >> 2] | 0) + 5 | 0] & 3) == 0 ? i10 : 1;
+       break L14;
+      }
+     } while (0);
+     if ((i4 | 0) == 18 ? (i4 = 0, (i6 & 64 | 0) == 0) : 0) {
+      break;
+     }
+     i11 = HEAP32[i9 >> 2] | 0;
+     if (!((HEAP8[i11 + 5 | 0] & 3) == 0)) {
+      _reallymarkobject(i1, i11);
+      i8 = 1;
+     }
+    }
+   } while (0);
+   i9 = i9 + 32 | 0;
+  } while (i9 >>> 0 < i5 >>> 0);
+  if ((i10 | 0) != 0) {
+   i15 = i1 + 96 | 0;
+   HEAP32[i2 + 24 >> 2] = HEAP32[i15 >> 2];
+   HEAP32[i15 >> 2] = i2;
+   i15 = i8;
+   STACKTOP = i3;
+   return i15 | 0;
+  }
+  if ((i7 | 0) != 0) {
+   i15 = i1 + 100 | 0;
+   HEAP32[i2 + 24 >> 2] = HEAP32[i15 >> 2];
+   HEAP32[i15 >> 2] = i2;
+   i15 = i8;
+   STACKTOP = i3;
+   return i15 | 0;
+  }
+ }
+ i15 = i1 + 88 | 0;
+ HEAP32[i2 + 24 >> 2] = HEAP32[i15 >> 2];
+ HEAP32[i15 >> 2] = i2;
+ i15 = i8;
+ STACKTOP = i3;
+ return i15 | 0;
+}
+function _luaV_gettable(i2, i7, i5, i1) {
+ i2 = i2 | 0;
+ i7 = i7 | 0;
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ var i3 = 0, i4 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i6 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i6;
+ i8 = i2 + 12 | 0;
+ i3 = i7;
+ i10 = HEAP32[i7 + 8 >> 2] | 0;
+ i9 = 0;
+ while (1) {
+  i7 = i3 + 8 | 0;
+  if ((i10 | 0) != 69) {
+   i12 = _luaT_gettmbyobj(i2, i3, 0) | 0;
+   i10 = HEAP32[i12 + 8 >> 2] | 0;
+   if ((i10 | 0) == 0) {
+    i8 = 11;
+    break;
+   }
+  } else {
+   i12 = HEAP32[i3 >> 2] | 0;
+   i11 = _luaH_get(i12, i5) | 0;
+   i10 = i11 + 8 | 0;
+   if ((HEAP32[i10 >> 2] | 0) != 0) {
+    i8 = 9;
+    break;
+   }
+   i12 = HEAP32[i12 + 8 >> 2] | 0;
+   if ((i12 | 0) == 0) {
+    i8 = 9;
+    break;
+   }
+   if (!((HEAP8[i12 + 6 | 0] & 1) == 0)) {
+    i8 = 9;
+    break;
+   }
+   i12 = _luaT_gettm(i12, 0, HEAP32[(HEAP32[i8 >> 2] | 0) + 184 >> 2] | 0) | 0;
+   if ((i12 | 0) == 0) {
+    i8 = 9;
+    break;
+   }
+   i10 = HEAP32[i12 + 8 >> 2] | 0;
+  }
+  i9 = i9 + 1 | 0;
+  if ((i10 & 15 | 0) == 6) {
+   i8 = 13;
+   break;
+  }
+  if ((i9 | 0) < 100) {
+   i3 = i12;
+  } else {
+   i8 = 14;
+   break;
+  }
+ }
+ if ((i8 | 0) == 9) {
+  i9 = i11;
+  i11 = HEAP32[i9 + 4 >> 2] | 0;
+  i12 = i1;
+  HEAP32[i12 >> 2] = HEAP32[i9 >> 2];
+  HEAP32[i12 + 4 >> 2] = i11;
+  HEAP32[i1 + 8 >> 2] = HEAP32[i10 >> 2];
+  STACKTOP = i6;
+  return;
+ } else if ((i8 | 0) == 11) {
+  _luaG_typeerror(i2, i3, 8944);
+ } else if ((i8 | 0) == 13) {
+  i10 = i2 + 28 | 0;
+  i11 = i1 - (HEAP32[i10 >> 2] | 0) | 0;
+  i8 = i2 + 8 | 0;
+  i9 = HEAP32[i8 >> 2] | 0;
+  HEAP32[i8 >> 2] = i9 + 16;
+  i13 = i12;
+  i1 = HEAP32[i13 + 4 >> 2] | 0;
+  i4 = i9;
+  HEAP32[i4 >> 2] = HEAP32[i13 >> 2];
+  HEAP32[i4 + 4 >> 2] = i1;
+  HEAP32[i9 + 8 >> 2] = HEAP32[i12 + 8 >> 2];
+  i12 = HEAP32[i8 >> 2] | 0;
+  HEAP32[i8 >> 2] = i12 + 16;
+  i9 = HEAP32[i3 + 4 >> 2] | 0;
+  i4 = i12;
+  HEAP32[i4 >> 2] = HEAP32[i3 >> 2];
+  HEAP32[i4 + 4 >> 2] = i9;
+  HEAP32[i12 + 8 >> 2] = HEAP32[i7 >> 2];
+  i12 = HEAP32[i8 >> 2] | 0;
+  HEAP32[i8 >> 2] = i12 + 16;
+  i4 = i5;
+  i9 = HEAP32[i4 + 4 >> 2] | 0;
+  i7 = i12;
+  HEAP32[i7 >> 2] = HEAP32[i4 >> 2];
+  HEAP32[i7 + 4 >> 2] = i9;
+  HEAP32[i12 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+  _luaD_call(i2, (HEAP32[i8 >> 2] | 0) + -48 | 0, 1, HEAP8[(HEAP32[i2 + 16 >> 2] | 0) + 18 | 0] & 1);
+  i12 = HEAP32[i10 >> 2] | 0;
+  i10 = HEAP32[i8 >> 2] | 0;
+  i7 = i10 + -16 | 0;
+  HEAP32[i8 >> 2] = i7;
+  i8 = HEAP32[i7 + 4 >> 2] | 0;
+  i9 = i12 + i11 | 0;
+  HEAP32[i9 >> 2] = HEAP32[i7 >> 2];
+  HEAP32[i9 + 4 >> 2] = i8;
+  HEAP32[i12 + (i11 + 8) >> 2] = HEAP32[i10 + -8 >> 2];
+  STACKTOP = i6;
+  return;
+ } else if ((i8 | 0) == 14) {
+  _luaG_runerror(i2, 8952, i4);
+ }
+}
+function _db_getinfo(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 112 | 0;
+ i3 = i2;
+ if ((_lua_type(i1, 1) | 0) == 8) {
+  i4 = _lua_tothread(i1, 1) | 0;
+  i7 = 1;
+ } else {
+  i4 = i1;
+  i7 = 0;
+ }
+ i5 = i7 | 2;
+ i6 = _luaL_optlstring(i1, i5, 11784, 0) | 0;
+ i7 = i7 + 1 | 0;
+ do {
+  if ((_lua_isnumber(i1, i7) | 0) != 0) {
+   if ((_lua_getstack(i4, _lua_tointegerx(i1, i7, 0) | 0, i3) | 0) == 0) {
+    _lua_pushnil(i1);
+    i7 = 1;
+    STACKTOP = i2;
+    return i7 | 0;
+   }
+  } else {
+   if ((_lua_type(i1, i7) | 0) == 6) {
+    HEAP32[i3 >> 2] = i6;
+    _lua_pushfstring(i1, 11792, i3) | 0;
+    i6 = _lua_tolstring(i1, -1, 0) | 0;
+    _lua_pushvalue(i1, i7);
+    _lua_xmove(i1, i4, 1);
+    break;
+   }
+   i7 = _luaL_argerror(i1, i7, 11800) | 0;
+   STACKTOP = i2;
+   return i7 | 0;
+  }
+ } while (0);
+ if ((_lua_getinfo(i4, i6, i3) | 0) == 0) {
+  i7 = _luaL_argerror(i1, i5, 11832) | 0;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ _lua_createtable(i1, 0, 2);
+ if ((_strchr(i6, 83) | 0) != 0) {
+  _lua_pushstring(i1, HEAP32[i3 + 16 >> 2] | 0) | 0;
+  _lua_setfield(i1, -2, 11848);
+  _lua_pushstring(i1, i3 + 36 | 0) | 0;
+  _lua_setfield(i1, -2, 11856);
+  _lua_pushinteger(i1, HEAP32[i3 + 24 >> 2] | 0);
+  _lua_setfield(i1, -2, 11872);
+  _lua_pushinteger(i1, HEAP32[i3 + 28 >> 2] | 0);
+  _lua_setfield(i1, -2, 11888);
+  _lua_pushstring(i1, HEAP32[i3 + 12 >> 2] | 0) | 0;
+  _lua_setfield(i1, -2, 11904);
+ }
+ if ((_strchr(i6, 108) | 0) != 0) {
+  _lua_pushinteger(i1, HEAP32[i3 + 20 >> 2] | 0);
+  _lua_setfield(i1, -2, 11912);
+ }
+ if ((_strchr(i6, 117) | 0) != 0) {
+  _lua_pushinteger(i1, HEAPU8[i3 + 32 | 0] | 0);
+  _lua_setfield(i1, -2, 11928);
+  _lua_pushinteger(i1, HEAPU8[i3 + 33 | 0] | 0);
+  _lua_setfield(i1, -2, 11936);
+  _lua_pushboolean(i1, HEAP8[i3 + 34 | 0] | 0);
+  _lua_setfield(i1, -2, 11944);
+ }
+ if ((_strchr(i6, 110) | 0) != 0) {
+  _lua_pushstring(i1, HEAP32[i3 + 4 >> 2] | 0) | 0;
+  _lua_setfield(i1, -2, 11960);
+  _lua_pushstring(i1, HEAP32[i3 + 8 >> 2] | 0) | 0;
+  _lua_setfield(i1, -2, 11968);
+ }
+ if ((_strchr(i6, 116) | 0) != 0) {
+  _lua_pushboolean(i1, HEAP8[i3 + 35 | 0] | 0);
+  _lua_setfield(i1, -2, 11984);
+ }
+ if ((_strchr(i6, 76) | 0) != 0) {
+  if ((i4 | 0) == (i1 | 0)) {
+   _lua_pushvalue(i1, -2);
+   _lua_remove(i1, -3);
+  } else {
+   _lua_xmove(i4, i1, 1);
+  }
+  _lua_setfield(i1, -2, 12e3);
+ }
+ if ((_strchr(i6, 102) | 0) == 0) {
+  i7 = 1;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ if ((i4 | 0) == (i1 | 0)) {
+  _lua_pushvalue(i1, -2);
+  _lua_remove(i1, -3);
+ } else {
+  _lua_xmove(i4, i1, 1);
+ }
+ _lua_setfield(i1, -2, 12016);
+ i7 = 1;
+ STACKTOP = i2;
+ return i7 | 0;
+}
+function _luaL_traceback(i4, i1, i9, i7) {
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ i9 = i9 | 0;
+ i7 = i7 | 0;
+ var i2 = 0, i3 = 0, i5 = 0, i6 = 0, i8 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 208 | 0;
+ i6 = i3;
+ i5 = i3 + 100 | 0;
+ i2 = _lua_gettop(i4) | 0;
+ i8 = 1;
+ i10 = 1;
+ while (1) {
+  if ((_lua_getstack(i1, i8, i6) | 0) == 0) {
+   break;
+  } else {
+   i10 = i8;
+   i8 = i8 << 1;
+  }
+ }
+ if ((i10 | 0) < (i8 | 0)) {
+  while (1) {
+   i11 = (i8 + i10 | 0) / 2 | 0;
+   i12 = (_lua_getstack(i1, i11, i6) | 0) == 0;
+   i8 = i12 ? i11 : i8;
+   i10 = i12 ? i10 : i11 + 1 | 0;
+   if ((i10 | 0) >= (i8 | 0)) {
+    i10 = i8;
+    break;
+   }
+  }
+ } else {
+  i10 = i8;
+ }
+ i8 = (i10 + -1 | 0) > 22 ? 12 : 0;
+ if ((i9 | 0) != 0) {
+  HEAP32[i6 >> 2] = i9;
+  _lua_pushfstring(i4, 944, i6) | 0;
+ }
+ _lua_pushlstring(i4, 952, 16) | 0;
+ if ((_lua_getstack(i1, i7, i5) | 0) == 0) {
+  i17 = _lua_gettop(i4) | 0;
+  i17 = i17 - i2 | 0;
+  _lua_concat(i4, i17);
+  STACKTOP = i3;
+  return;
+ }
+ i10 = i10 + -11 | 0;
+ i13 = i5 + 36 | 0;
+ i9 = i5 + 20 | 0;
+ i16 = i5 + 8 | 0;
+ i12 = i5 + 12 | 0;
+ i15 = i5 + 24 | 0;
+ i14 = i5 + 35 | 0;
+ i11 = i5 + 4 | 0;
+ do {
+  i7 = i7 + 1 | 0;
+  if ((i7 | 0) == (i8 | 0)) {
+   _lua_pushlstring(i4, 976, 5) | 0;
+   i7 = i10;
+  } else {
+   _lua_getinfo(i1, 984, i5) | 0;
+   HEAP32[i6 >> 2] = i13;
+   _lua_pushfstring(i4, 992, i6) | 0;
+   i17 = HEAP32[i9 >> 2] | 0;
+   if ((i17 | 0) > 0) {
+    HEAP32[i6 >> 2] = i17;
+    _lua_pushfstring(i4, 1e3, i6) | 0;
+   }
+   _lua_pushlstring(i4, 1008, 4) | 0;
+   do {
+    if ((HEAP8[HEAP32[i16 >> 2] | 0] | 0) == 0) {
+     i17 = HEAP8[HEAP32[i12 >> 2] | 0] | 0;
+     if (i17 << 24 >> 24 == 109) {
+      _lua_pushlstring(i4, 1800, 10) | 0;
+      break;
+     } else if (i17 << 24 >> 24 == 67) {
+      if ((_pushglobalfuncname(i4, i5) | 0) == 0) {
+       _lua_pushlstring(i4, 1112, 1) | 0;
+       break;
+      } else {
+       HEAP32[i6 >> 2] = _lua_tolstring(i4, -1, 0) | 0;
+       _lua_pushfstring(i4, 1784, i6) | 0;
+       _lua_remove(i4, -2);
+       break;
+      }
+     } else {
+      i17 = HEAP32[i15 >> 2] | 0;
+      HEAP32[i6 >> 2] = i13;
+      HEAP32[i6 + 4 >> 2] = i17;
+      _lua_pushfstring(i4, 1816, i6) | 0;
+      break;
+     }
+    } else {
+     HEAP32[i6 >> 2] = HEAP32[i11 >> 2];
+     _lua_pushfstring(i4, 1784, i6) | 0;
+    }
+   } while (0);
+   if ((HEAP8[i14] | 0) != 0) {
+    _lua_pushlstring(i4, 1016, 20) | 0;
+   }
+   _lua_concat(i4, (_lua_gettop(i4) | 0) - i2 | 0);
+  }
+ } while ((_lua_getstack(i1, i7, i5) | 0) != 0);
+ i17 = _lua_gettop(i4) | 0;
+ i17 = i17 - i2 | 0;
+ _lua_concat(i4, i17);
+ STACKTOP = i3;
+ return;
+}
+function _luaK_exp2RK(i3, i1) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, d11 = 0.0, i12 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i7 = i2 + 16 | 0;
+ i6 = i2;
+ i4 = i1 + 16 | 0;
+ i5 = i1 + 20 | 0;
+ i10 = (HEAP32[i4 >> 2] | 0) == (HEAP32[i5 >> 2] | 0);
+ _luaK_dischargevars(i3, i1);
+ do {
+  if (!i10) {
+   if ((HEAP32[i1 >> 2] | 0) == 6) {
+    i10 = HEAP32[i1 + 8 >> 2] | 0;
+    if ((HEAP32[i4 >> 2] | 0) == (HEAP32[i5 >> 2] | 0)) {
+     break;
+    }
+    if ((i10 | 0) >= (HEAPU8[i3 + 46 | 0] | 0 | 0)) {
+     _exp2reg(i3, i1, i10);
+     break;
+    }
+   }
+   _luaK_exp2nextreg(i3, i1);
+  }
+ } while (0);
+ i10 = HEAP32[i1 >> 2] | 0;
+ switch (i10 | 0) {
+ case 4:
+  {
+   i8 = HEAP32[i1 + 8 >> 2] | 0;
+   i9 = 18;
+   break;
+  }
+ case 1:
+ case 3:
+ case 2:
+  {
+   if ((HEAP32[i3 + 32 >> 2] | 0) < 256) {
+    if ((i10 | 0) == 1) {
+     HEAP32[i6 + 8 >> 2] = 0;
+     HEAP32[i7 >> 2] = HEAP32[i3 + 4 >> 2];
+     HEAP32[i7 + 8 >> 2] = 69;
+     i3 = _addk(i3, i7, i6) | 0;
+    } else {
+     HEAP32[i7 >> 2] = (i10 | 0) == 2;
+     HEAP32[i7 + 8 >> 2] = 1;
+     i3 = _addk(i3, i7, i7) | 0;
+    }
+    HEAP32[i1 + 8 >> 2] = i3;
+    HEAP32[i1 >> 2] = 4;
+    i10 = i3 | 256;
+    STACKTOP = i2;
+    return i10 | 0;
+   }
+   break;
+  }
+ case 5:
+  {
+   i9 = i1 + 8 | 0;
+   d11 = +HEAPF64[i9 >> 3];
+   HEAPF64[i7 >> 3] = d11;
+   i8 = HEAP32[(HEAP32[i3 + 12 >> 2] | 0) + 52 >> 2] | 0;
+   HEAPF64[i6 >> 3] = d11;
+   HEAP32[i6 + 8 >> 2] = 3;
+   if (d11 != d11 | 0.0 != 0.0 | d11 == 0.0) {
+    i10 = i8 + 8 | 0;
+    i12 = HEAP32[i10 >> 2] | 0;
+    HEAP32[i10 >> 2] = i12 + 16;
+    i8 = _luaS_newlstr(i8, i7, 8) | 0;
+    HEAP32[i12 >> 2] = i8;
+    HEAP32[i12 + 8 >> 2] = HEAPU8[i8 + 4 | 0] | 0 | 64;
+    i8 = _addk(i3, (HEAP32[i10 >> 2] | 0) + -16 | 0, i6) | 0;
+    HEAP32[i10 >> 2] = (HEAP32[i10 >> 2] | 0) + -16;
+   } else {
+    i8 = _addk(i3, i6, i6) | 0;
+   }
+   HEAP32[i9 >> 2] = i8;
+   HEAP32[i1 >> 2] = 4;
+   i9 = 18;
+   break;
+  }
+ default:
+  {}
+ }
+ if ((i9 | 0) == 18 ? (i8 | 0) < 256 : 0) {
+  i12 = i8 | 256;
+  STACKTOP = i2;
+  return i12 | 0;
+ }
+ _luaK_dischargevars(i3, i1);
+ if ((HEAP32[i1 >> 2] | 0) == 6) {
+  i7 = i1 + 8 | 0;
+  i6 = HEAP32[i7 >> 2] | 0;
+  if ((HEAP32[i4 >> 2] | 0) == (HEAP32[i5 >> 2] | 0)) {
+   i12 = i6;
+   STACKTOP = i2;
+   return i12 | 0;
+  }
+  if ((i6 | 0) >= (HEAPU8[i3 + 46 | 0] | 0 | 0)) {
+   _exp2reg(i3, i1, i6);
+   i12 = HEAP32[i7 >> 2] | 0;
+   STACKTOP = i2;
+   return i12 | 0;
+  }
+ } else {
+  i7 = i1 + 8 | 0;
+ }
+ _luaK_exp2nextreg(i3, i1);
+ i12 = HEAP32[i7 >> 2] | 0;
+ STACKTOP = i2;
+ return i12 | 0;
+}
+function _os_date(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 1264 | 0;
+ i4 = i2;
+ i7 = i2 + 1048 | 0;
+ i6 = i2 + 1256 | 0;
+ i3 = i2 + 8 | 0;
+ i5 = i2 + 1056 | 0;
+ i12 = _luaL_optlstring(i1, 1, 6064, 0) | 0;
+ if ((_lua_type(i1, 2) | 0) < 1) {
+  i8 = _time(0) | 0;
+ } else {
+  i8 = ~~+_luaL_checknumber(i1, 2);
+ }
+ HEAP32[i7 >> 2] = i8;
+ if ((HEAP8[i12] | 0) == 33) {
+  i12 = i12 + 1 | 0;
+  i10 = _gmtime(i7 | 0) | 0;
+ } else {
+  i10 = _localtime(i7 | 0) | 0;
+ }
+ if ((i10 | 0) == 0) {
+  _lua_pushnil(i1);
+  STACKTOP = i2;
+  return 1;
+ }
+ if ((_strcmp(i12, 6072) | 0) == 0) {
+  _lua_createtable(i1, 0, 9);
+  _lua_pushinteger(i1, HEAP32[i10 >> 2] | 0);
+  _lua_setfield(i1, -2, 5864);
+  _lua_pushinteger(i1, HEAP32[i10 + 4 >> 2] | 0);
+  _lua_setfield(i1, -2, 5872);
+  _lua_pushinteger(i1, HEAP32[i10 + 8 >> 2] | 0);
+  _lua_setfield(i1, -2, 5880);
+  _lua_pushinteger(i1, HEAP32[i10 + 12 >> 2] | 0);
+  _lua_setfield(i1, -2, 5888);
+  _lua_pushinteger(i1, (HEAP32[i10 + 16 >> 2] | 0) + 1 | 0);
+  _lua_setfield(i1, -2, 5896);
+  _lua_pushinteger(i1, (HEAP32[i10 + 20 >> 2] | 0) + 1900 | 0);
+  _lua_setfield(i1, -2, 5904);
+  _lua_pushinteger(i1, (HEAP32[i10 + 24 >> 2] | 0) + 1 | 0);
+  _lua_setfield(i1, -2, 6080);
+  _lua_pushinteger(i1, (HEAP32[i10 + 28 >> 2] | 0) + 1 | 0);
+  _lua_setfield(i1, -2, 6088);
+  i3 = HEAP32[i10 + 32 >> 2] | 0;
+  if ((i3 | 0) < 0) {
+   STACKTOP = i2;
+   return 1;
+  }
+  _lua_pushboolean(i1, i3);
+  _lua_setfield(i1, -2, 5912);
+  STACKTOP = i2;
+  return 1;
+ }
+ HEAP8[i6] = 37;
+ _luaL_buffinit(i1, i3);
+ i11 = i3 + 8 | 0;
+ i9 = i3 + 4 | 0;
+ i8 = i6 + 1 | 0;
+ i7 = i6 + 2 | 0;
+ while (1) {
+  i14 = HEAP8[i12] | 0;
+  if (i14 << 24 >> 24 == 0) {
+   break;
+  } else if (!(i14 << 24 >> 24 == 37)) {
+   i13 = HEAP32[i11 >> 2] | 0;
+   if (!(i13 >>> 0 < (HEAP32[i9 >> 2] | 0) >>> 0)) {
+    _luaL_prepbuffsize(i3, 1) | 0;
+    i13 = HEAP32[i11 >> 2] | 0;
+    i14 = HEAP8[i12] | 0;
+   }
+   HEAP32[i11 >> 2] = i13 + 1;
+   HEAP8[(HEAP32[i3 >> 2] | 0) + i13 | 0] = i14;
+   i12 = i12 + 1 | 0;
+   continue;
+  }
+  i13 = i12 + 1 | 0;
+  i12 = i12 + 2 | 0;
+  i14 = HEAP8[i13] | 0;
+  if (!(i14 << 24 >> 24 == 0) ? (_memchr(6096, i14 << 24 >> 24, 23) | 0) != 0 : 0) {
+   HEAP8[i8] = i14;
+   HEAP8[i7] = 0;
+  } else {
+   HEAP32[i4 >> 2] = i13;
+   _luaL_argerror(i1, 1, _lua_pushfstring(i1, 6120, i4) | 0) | 0;
+   i12 = i13;
+  }
+  _luaL_addlstring(i3, i5, _strftime(i5 | 0, 200, i6 | 0, i10 | 0) | 0);
+ }
+ _luaL_pushresult(i3);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaV_finishOp(i3) {
+ i3 = i3 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0;
+ i1 = STACKTOP;
+ i8 = HEAP32[i3 + 16 >> 2] | 0;
+ i7 = i8 + 24 | 0;
+ i4 = HEAP32[i7 >> 2] | 0;
+ i5 = i8 + 28 | 0;
+ i2 = HEAP32[(HEAP32[i5 >> 2] | 0) + -4 >> 2] | 0;
+ i6 = i2 & 63;
+ switch (i6 | 0) {
+ case 34:
+  {
+   HEAP32[i3 + 8 >> 2] = HEAP32[i8 + 4 >> 2];
+   STACKTOP = i1;
+   return;
+  }
+ case 24:
+ case 25:
+ case 26:
+  {
+   i7 = i3 + 8 | 0;
+   i8 = HEAP32[i7 >> 2] | 0;
+   i9 = HEAP32[i8 + -8 >> 2] | 0;
+   if ((i9 | 0) != 0) {
+    if ((i9 | 0) == 1) {
+     i9 = (HEAP32[i8 + -16 >> 2] | 0) == 0;
+    } else {
+     i9 = 0;
+    }
+   } else {
+    i9 = 1;
+   }
+   i9 = i9 & 1;
+   i10 = i9 ^ 1;
+   HEAP32[i7 >> 2] = i8 + -16;
+   if ((i6 | 0) == 26) {
+    i8 = (HEAP32[(_luaT_gettmbyobj(i3, i4 + (i2 >>> 23 << 4) | 0, 14) | 0) + 8 >> 2] | 0) == 0;
+    i10 = i8 ? i9 : i10;
+   }
+   if ((i10 | 0) == (i2 >>> 6 & 255 | 0)) {
+    STACKTOP = i1;
+    return;
+   }
+   HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + 4;
+   STACKTOP = i1;
+   return;
+  }
+ case 22:
+  {
+   i5 = i3 + 8 | 0;
+   i10 = HEAP32[i5 >> 2] | 0;
+   i6 = i10 + -32 | 0;
+   i4 = i6 - (i4 + (i2 >>> 23 << 4)) | 0;
+   i12 = i10 + -16 | 0;
+   i11 = HEAP32[i12 + 4 >> 2] | 0;
+   i9 = i10 + -48 | 0;
+   HEAP32[i9 >> 2] = HEAP32[i12 >> 2];
+   HEAP32[i9 + 4 >> 2] = i11;
+   HEAP32[i10 + -40 >> 2] = HEAP32[i10 + -8 >> 2];
+   if ((i4 | 0) > 16) {
+    HEAP32[i5 >> 2] = i6;
+    _luaV_concat(i3, i4 >> 4);
+   }
+   i10 = HEAP32[i5 >> 2] | 0;
+   i11 = HEAP32[i7 >> 2] | 0;
+   i12 = i2 >>> 6 & 255;
+   i6 = i10 + -16 | 0;
+   i7 = HEAP32[i6 + 4 >> 2] | 0;
+   i9 = i11 + (i12 << 4) | 0;
+   HEAP32[i9 >> 2] = HEAP32[i6 >> 2];
+   HEAP32[i9 + 4 >> 2] = i7;
+   HEAP32[i11 + (i12 << 4) + 8 >> 2] = HEAP32[i10 + -8 >> 2];
+   HEAP32[i5 >> 2] = HEAP32[i8 + 4 >> 2];
+   STACKTOP = i1;
+   return;
+  }
+ case 12:
+ case 7:
+ case 6:
+ case 21:
+ case 19:
+ case 18:
+ case 17:
+ case 16:
+ case 15:
+ case 14:
+ case 13:
+  {
+   i12 = i3 + 8 | 0;
+   i11 = HEAP32[i12 >> 2] | 0;
+   i8 = i11 + -16 | 0;
+   HEAP32[i12 >> 2] = i8;
+   i12 = i2 >>> 6 & 255;
+   i9 = HEAP32[i8 + 4 >> 2] | 0;
+   i10 = i4 + (i12 << 4) | 0;
+   HEAP32[i10 >> 2] = HEAP32[i8 >> 2];
+   HEAP32[i10 + 4 >> 2] = i9;
+   HEAP32[i4 + (i12 << 4) + 8 >> 2] = HEAP32[i11 + -8 >> 2];
+   STACKTOP = i1;
+   return;
+  }
+ case 29:
+  {
+   if ((i2 & 8372224 | 0) == 0) {
+    STACKTOP = i1;
+    return;
+   }
+   HEAP32[i3 + 8 >> 2] = HEAP32[i8 + 4 >> 2];
+   STACKTOP = i1;
+   return;
+  }
+ default:
+  {
+   STACKTOP = i1;
+   return;
+  }
+ }
+}
+function _auxsort(i2, i4, i5) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i1;
+ if ((i4 | 0) >= (i5 | 0)) {
+  STACKTOP = i1;
+  return;
+ }
+ while (1) {
+  _lua_rawgeti(i2, 1, i4);
+  _lua_rawgeti(i2, 1, i5);
+  if ((_sort_comp(i2, -1, -2) | 0) == 0) {
+   _lua_settop(i2, -3);
+  } else {
+   _lua_rawseti(i2, 1, i4);
+   _lua_rawseti(i2, 1, i5);
+  }
+  i6 = i5 - i4 | 0;
+  if ((i6 | 0) == 1) {
+   i2 = 24;
+   break;
+  }
+  i7 = (i5 + i4 | 0) / 2 | 0;
+  _lua_rawgeti(i2, 1, i7);
+  _lua_rawgeti(i2, 1, i4);
+  do {
+   if ((_sort_comp(i2, -2, -1) | 0) == 0) {
+    _lua_settop(i2, -2);
+    _lua_rawgeti(i2, 1, i5);
+    if ((_sort_comp(i2, -1, -2) | 0) == 0) {
+     _lua_settop(i2, -3);
+     break;
+    } else {
+     _lua_rawseti(i2, 1, i7);
+     _lua_rawseti(i2, 1, i5);
+     break;
+    }
+   } else {
+    _lua_rawseti(i2, 1, i7);
+    _lua_rawseti(i2, 1, i4);
+   }
+  } while (0);
+  if ((i6 | 0) == 2) {
+   i2 = 24;
+   break;
+  }
+  _lua_rawgeti(i2, 1, i7);
+  _lua_pushvalue(i2, -1);
+  i6 = i5 + -1 | 0;
+  _lua_rawgeti(i2, 1, i6);
+  _lua_rawseti(i2, 1, i7);
+  _lua_rawseti(i2, 1, i6);
+  i7 = i4;
+  i9 = i6;
+  while (1) {
+   i8 = i7 + 1 | 0;
+   _lua_rawgeti(i2, 1, i8);
+   if ((_sort_comp(i2, -1, -2) | 0) != 0) {
+    i7 = i8;
+    while (1) {
+     if ((i7 | 0) >= (i5 | 0)) {
+      _luaL_error(i2, 8216, i3) | 0;
+     }
+     _lua_settop(i2, -2);
+     i8 = i7 + 1 | 0;
+     _lua_rawgeti(i2, 1, i8);
+     if ((_sort_comp(i2, -1, -2) | 0) == 0) {
+      break;
+     } else {
+      i7 = i8;
+     }
+    }
+   }
+   i10 = i9 + -1 | 0;
+   _lua_rawgeti(i2, 1, i10);
+   if ((_sort_comp(i2, -3, -1) | 0) != 0) {
+    i9 = i10;
+    while (1) {
+     if ((i9 | 0) <= (i4 | 0)) {
+      _luaL_error(i2, 8216, i3) | 0;
+     }
+     _lua_settop(i2, -2);
+     i10 = i9 + -1 | 0;
+     _lua_rawgeti(i2, 1, i10);
+     if ((_sort_comp(i2, -3, -1) | 0) == 0) {
+      break;
+     } else {
+      i9 = i10;
+     }
+    }
+   }
+   if ((i9 | 0) <= (i8 | 0)) {
+    break;
+   }
+   _lua_rawseti(i2, 1, i8);
+   _lua_rawseti(i2, 1, i10);
+   i7 = i8;
+   i9 = i10;
+  }
+  _lua_settop(i2, -4);
+  _lua_rawgeti(i2, 1, i6);
+  _lua_rawgeti(i2, 1, i8);
+  _lua_rawseti(i2, 1, i6);
+  _lua_rawseti(i2, 1, i8);
+  i8 = (i8 - i4 | 0) < (i5 - i8 | 0);
+  i9 = i7 + 2 | 0;
+  i10 = i8 ? i9 : i4;
+  i6 = i8 ? i5 : i7;
+  _auxsort(i2, i8 ? i4 : i9, i8 ? i7 : i5);
+  if ((i10 | 0) < (i6 | 0)) {
+   i4 = i10;
+   i5 = i6;
+  } else {
+   i2 = 24;
+   break;
+  }
+ }
+ if ((i2 | 0) == 24) {
+  STACKTOP = i1;
+  return;
+ }
+}
+function _skip_sep(i3) {
+ i3 = i3 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i1 = STACKTOP;
+ i2 = HEAP32[i3 >> 2] | 0;
+ i4 = i3 + 60 | 0;
+ i10 = HEAP32[i4 >> 2] | 0;
+ i8 = i10 + 4 | 0;
+ i11 = HEAP32[i8 >> 2] | 0;
+ i7 = i10 + 8 | 0;
+ i5 = HEAP32[i7 >> 2] | 0;
+ do {
+  if ((i11 + 1 | 0) >>> 0 > i5 >>> 0) {
+   if (i5 >>> 0 > 2147483645) {
+    _lexerror(i3, 12368, 0);
+   }
+   i12 = i5 << 1;
+   i11 = HEAP32[i3 + 52 >> 2] | 0;
+   if ((i12 | 0) == -2) {
+    _luaM_toobig(i11);
+   } else {
+    i9 = _luaM_realloc_(i11, HEAP32[i10 >> 2] | 0, i5, i12) | 0;
+    HEAP32[i10 >> 2] = i9;
+    HEAP32[i7 >> 2] = i12;
+    i6 = HEAP32[i8 >> 2] | 0;
+    break;
+   }
+  } else {
+   i6 = i11;
+   i9 = HEAP32[i10 >> 2] | 0;
+  }
+ } while (0);
+ HEAP32[i8 >> 2] = i6 + 1;
+ HEAP8[i9 + i6 | 0] = i2;
+ i5 = i3 + 56 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ i13 = HEAP32[i6 >> 2] | 0;
+ HEAP32[i6 >> 2] = i13 + -1;
+ if ((i13 | 0) == 0) {
+  i6 = _luaZ_fill(i6) | 0;
+ } else {
+  i13 = i6 + 4 | 0;
+  i6 = HEAP32[i13 >> 2] | 0;
+  HEAP32[i13 >> 2] = i6 + 1;
+  i6 = HEAPU8[i6] | 0;
+ }
+ HEAP32[i3 >> 2] = i6;
+ if ((i6 | 0) != 61) {
+  i12 = i6;
+  i13 = 0;
+  i12 = (i12 | 0) != (i2 | 0);
+  i12 = i12 << 31 >> 31;
+  i13 = i12 ^ i13;
+  STACKTOP = i1;
+  return i13 | 0;
+ }
+ i6 = i3 + 52 | 0;
+ i7 = 0;
+ while (1) {
+  i9 = HEAP32[i4 >> 2] | 0;
+  i8 = i9 + 4 | 0;
+  i10 = HEAP32[i8 >> 2] | 0;
+  i11 = i9 + 8 | 0;
+  i12 = HEAP32[i11 >> 2] | 0;
+  if ((i10 + 1 | 0) >>> 0 > i12 >>> 0) {
+   if (i12 >>> 0 > 2147483645) {
+    i4 = 16;
+    break;
+   }
+   i13 = i12 << 1;
+   i10 = HEAP32[i6 >> 2] | 0;
+   if ((i13 | 0) == -2) {
+    i4 = 18;
+    break;
+   }
+   i12 = _luaM_realloc_(i10, HEAP32[i9 >> 2] | 0, i12, i13) | 0;
+   HEAP32[i9 >> 2] = i12;
+   HEAP32[i11 >> 2] = i13;
+   i10 = HEAP32[i8 >> 2] | 0;
+   i9 = i12;
+  } else {
+   i9 = HEAP32[i9 >> 2] | 0;
+  }
+  HEAP32[i8 >> 2] = i10 + 1;
+  HEAP8[i9 + i10 | 0] = 61;
+  i8 = HEAP32[i5 >> 2] | 0;
+  i13 = HEAP32[i8 >> 2] | 0;
+  HEAP32[i8 >> 2] = i13 + -1;
+  if ((i13 | 0) == 0) {
+   i8 = _luaZ_fill(i8) | 0;
+  } else {
+   i13 = i8 + 4 | 0;
+   i8 = HEAP32[i13 >> 2] | 0;
+   HEAP32[i13 >> 2] = i8 + 1;
+   i8 = HEAPU8[i8] | 0;
+  }
+  HEAP32[i3 >> 2] = i8;
+  i7 = i7 + 1 | 0;
+  if ((i8 | 0) != 61) {
+   i4 = 24;
+   break;
+  }
+ }
+ if ((i4 | 0) == 16) {
+  _lexerror(i3, 12368, 0);
+ } else if ((i4 | 0) == 18) {
+  _luaM_toobig(i10);
+ } else if ((i4 | 0) == 24) {
+  i13 = (i8 | 0) != (i2 | 0);
+  i13 = i13 << 31 >> 31;
+  i13 = i13 ^ i7;
+  STACKTOP = i1;
+  return i13 | 0;
+ }
+ return 0;
+}
+function _luaV_arith(i8, i2, i3, i5, i4) {
+ i8 = i8 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i6 = 0, i7 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, d14 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i9 = i1 + 24 | 0;
+ i13 = i1 + 16 | 0;
+ i12 = i1;
+ i6 = i3 + 8 | 0;
+ i11 = HEAP32[i6 >> 2] | 0;
+ if ((i11 | 0) != 3) {
+  if ((i11 & 15 | 0) == 4 ? (i11 = HEAP32[i3 >> 2] | 0, (_luaO_str2d(i11 + 16 | 0, HEAP32[i11 + 12 >> 2] | 0, i13) | 0) != 0) : 0) {
+   HEAPF64[i12 >> 3] = +HEAPF64[i13 >> 3];
+   HEAP32[i12 + 8 >> 2] = 3;
+   i10 = 5;
+  }
+ } else {
+  i12 = i3;
+  i10 = 5;
+ }
+ do {
+  if ((i10 | 0) == 5) {
+   i10 = HEAP32[i5 + 8 >> 2] | 0;
+   if ((i10 | 0) == 3) {
+    if ((i5 | 0) == 0) {
+     break;
+    }
+    d14 = +HEAPF64[i5 >> 3];
+   } else {
+    if ((i10 & 15 | 0) != 4) {
+     break;
+    }
+    i13 = HEAP32[i5 >> 2] | 0;
+    if ((_luaO_str2d(i13 + 16 | 0, HEAP32[i13 + 12 >> 2] | 0, i9) | 0) == 0) {
+     break;
+    }
+    d14 = +HEAPF64[i9 >> 3];
+   }
+   HEAPF64[i2 >> 3] = +_luaO_arith(i4 + -6 | 0, +HEAPF64[i12 >> 3], d14);
+   HEAP32[i2 + 8 >> 2] = 3;
+   STACKTOP = i1;
+   return;
+  }
+ } while (0);
+ i9 = _luaT_gettmbyobj(i8, i3, i4) | 0;
+ if ((HEAP32[i9 + 8 >> 2] | 0) == 0) {
+  i4 = _luaT_gettmbyobj(i8, i5, i4) | 0;
+  if ((HEAP32[i4 + 8 >> 2] | 0) == 0) {
+   _luaG_aritherror(i8, i3, i5);
+  } else {
+   i7 = i4;
+  }
+ } else {
+  i7 = i9;
+ }
+ i12 = i8 + 28 | 0;
+ i13 = i2 - (HEAP32[i12 >> 2] | 0) | 0;
+ i9 = i8 + 8 | 0;
+ i11 = HEAP32[i9 >> 2] | 0;
+ HEAP32[i9 >> 2] = i11 + 16;
+ i2 = i7;
+ i10 = HEAP32[i2 + 4 >> 2] | 0;
+ i4 = i11;
+ HEAP32[i4 >> 2] = HEAP32[i2 >> 2];
+ HEAP32[i4 + 4 >> 2] = i10;
+ HEAP32[i11 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+ i11 = HEAP32[i9 >> 2] | 0;
+ HEAP32[i9 >> 2] = i11 + 16;
+ i4 = i3;
+ i10 = HEAP32[i4 + 4 >> 2] | 0;
+ i7 = i11;
+ HEAP32[i7 >> 2] = HEAP32[i4 >> 2];
+ HEAP32[i7 + 4 >> 2] = i10;
+ HEAP32[i11 + 8 >> 2] = HEAP32[i6 >> 2];
+ i11 = HEAP32[i9 >> 2] | 0;
+ HEAP32[i9 >> 2] = i11 + 16;
+ i6 = i5;
+ i7 = HEAP32[i6 + 4 >> 2] | 0;
+ i10 = i11;
+ HEAP32[i10 >> 2] = HEAP32[i6 >> 2];
+ HEAP32[i10 + 4 >> 2] = i7;
+ HEAP32[i11 + 8 >> 2] = HEAP32[i5 + 8 >> 2];
+ _luaD_call(i8, (HEAP32[i9 >> 2] | 0) + -48 | 0, 1, HEAP8[(HEAP32[i8 + 16 >> 2] | 0) + 18 | 0] & 1);
+ i12 = HEAP32[i12 >> 2] | 0;
+ i11 = HEAP32[i9 >> 2] | 0;
+ i8 = i11 + -16 | 0;
+ HEAP32[i9 >> 2] = i8;
+ i9 = HEAP32[i8 + 4 >> 2] | 0;
+ i10 = i12 + i13 | 0;
+ HEAP32[i10 >> 2] = HEAP32[i8 >> 2];
+ HEAP32[i10 + 4 >> 2] = i9;
+ HEAP32[i12 + (i13 + 8) >> 2] = HEAP32[i11 + -8 >> 2];
+ STACKTOP = i1;
+ return;
+}
+function _new_localvar(i1, i8) {
+ i1 = i1 | 0;
+ i8 = i8 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i3;
+ i5 = HEAP32[i1 + 48 >> 2] | 0;
+ i2 = HEAP32[i1 + 64 >> 2] | 0;
+ i7 = HEAP32[i5 >> 2] | 0;
+ i10 = i7 + 60 | 0;
+ i11 = HEAP32[i10 >> 2] | 0;
+ i6 = i5 + 44 | 0;
+ if ((HEAP16[i6 >> 1] | 0) < (i11 | 0)) {
+  i9 = i7 + 24 | 0;
+  i10 = i11;
+ } else {
+  i9 = i7 + 24 | 0;
+  HEAP32[i9 >> 2] = _luaM_growaux_(HEAP32[i1 + 52 >> 2] | 0, HEAP32[i9 >> 2] | 0, i10, 12, 32767, 6496) | 0;
+  i10 = HEAP32[i10 >> 2] | 0;
+ }
+ if ((i11 | 0) < (i10 | 0)) {
+  i12 = i11;
+  while (1) {
+   i11 = i12 + 1 | 0;
+   HEAP32[(HEAP32[i9 >> 2] | 0) + (i12 * 12 | 0) >> 2] = 0;
+   if ((i11 | 0) == (i10 | 0)) {
+    break;
+   } else {
+    i12 = i11;
+   }
+  }
+ }
+ i10 = HEAP16[i6 >> 1] | 0;
+ HEAP32[(HEAP32[i9 >> 2] | 0) + ((i10 << 16 >> 16) * 12 | 0) >> 2] = i8;
+ if (!((HEAP8[i8 + 5 | 0] & 3) == 0) ? !((HEAP8[i7 + 5 | 0] & 4) == 0) : 0) {
+  _luaC_barrier_(HEAP32[i1 + 52 >> 2] | 0, i7, i8);
+  i7 = HEAP16[i6 >> 1] | 0;
+ } else {
+  i7 = i10;
+ }
+ HEAP16[i6 >> 1] = i7 + 1 << 16 >> 16;
+ i6 = i2 + 4 | 0;
+ i8 = HEAP32[i6 >> 2] | 0;
+ if ((i8 + 1 - (HEAP32[i5 + 40 >> 2] | 0) | 0) > 200) {
+  i10 = i5 + 12 | 0;
+  i9 = HEAP32[(HEAP32[i10 >> 2] | 0) + 52 >> 2] | 0;
+  i5 = HEAP32[(HEAP32[i5 >> 2] | 0) + 64 >> 2] | 0;
+  if ((i5 | 0) == 0) {
+   i11 = 6552;
+   HEAP32[i4 >> 2] = 6496;
+   i12 = i4 + 4 | 0;
+   HEAP32[i12 >> 2] = 200;
+   i12 = i4 + 8 | 0;
+   HEAP32[i12 >> 2] = i11;
+   i12 = _luaO_pushfstring(i9, 6592, i4) | 0;
+   i11 = HEAP32[i10 >> 2] | 0;
+   _luaX_syntaxerror(i11, i12);
+  }
+  HEAP32[i4 >> 2] = i5;
+  i11 = _luaO_pushfstring(i9, 6568, i4) | 0;
+  HEAP32[i4 >> 2] = 6496;
+  i12 = i4 + 4 | 0;
+  HEAP32[i12 >> 2] = 200;
+  i12 = i4 + 8 | 0;
+  HEAP32[i12 >> 2] = i11;
+  i12 = _luaO_pushfstring(i9, 6592, i4) | 0;
+  i11 = HEAP32[i10 >> 2] | 0;
+  _luaX_syntaxerror(i11, i12);
+ }
+ i4 = i2 + 8 | 0;
+ if ((i8 + 2 | 0) > (HEAP32[i4 >> 2] | 0)) {
+  i11 = _luaM_growaux_(HEAP32[i1 + 52 >> 2] | 0, HEAP32[i2 >> 2] | 0, i4, 2, 2147483645, 6496) | 0;
+  HEAP32[i2 >> 2] = i11;
+  i12 = HEAP32[i6 >> 2] | 0;
+  i10 = i12 + 1 | 0;
+  HEAP32[i6 >> 2] = i10;
+  i12 = i11 + (i12 << 1) | 0;
+  HEAP16[i12 >> 1] = i7;
+  STACKTOP = i3;
+  return;
+ } else {
+  i12 = i8;
+  i11 = HEAP32[i2 >> 2] | 0;
+  i10 = i12 + 1 | 0;
+  HEAP32[i6 >> 2] = i10;
+  i12 = i11 + (i12 << 1) | 0;
+  HEAP16[i12 >> 1] = i7;
+  STACKTOP = i3;
+  return;
+ }
+}
+function _luaC_fullgc(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0;
+ i2 = STACKTOP;
+ i4 = i1 + 12 | 0;
+ i3 = HEAP32[i4 >> 2] | 0;
+ i6 = i3 + 62 | 0;
+ i8 = HEAP8[i6] | 0;
+ i5 = (i5 | 0) != 0;
+ if (!i5) {
+  HEAP8[i6] = 0;
+  i9 = (HEAP32[i4 >> 2] | 0) + 104 | 0;
+  i10 = HEAP32[i9 >> 2] | 0;
+  if ((i10 | 0) != 0) {
+   do {
+    i11 = i10 + 5 | 0;
+    HEAP8[i11] = HEAP8[i11] & 191;
+    _GCTM(i1, 1);
+    i10 = HEAP32[i9 >> 2] | 0;
+   } while ((i10 | 0) != 0);
+   if ((HEAP8[i6] | 0) == 2) {
+    i9 = 7;
+   } else {
+    i9 = 6;
+   }
+  } else {
+   i9 = 6;
+  }
+ } else {
+  HEAP8[i6] = 1;
+  i9 = 6;
+ }
+ if ((i9 | 0) == 6 ? (HEAPU8[i3 + 61 | 0] | 0) < 2 : 0) {
+  i9 = 7;
+ }
+ if ((i9 | 0) == 7) {
+  i9 = HEAP32[i4 >> 2] | 0;
+  HEAP8[i9 + 61 | 0] = 2;
+  HEAP32[i9 + 64 >> 2] = 0;
+  i10 = i9 + 72 | 0;
+  do {
+   i11 = _sweeplist(i1, i10, 1) | 0;
+  } while ((i11 | 0) == (i10 | 0));
+  HEAP32[i9 + 80 >> 2] = i11;
+  i11 = i9 + 68 | 0;
+  do {
+   i10 = _sweeplist(i1, i11, 1) | 0;
+  } while ((i10 | 0) == (i11 | 0));
+  HEAP32[i9 + 76 >> 2] = i10;
+ }
+ i11 = HEAP32[i4 >> 2] | 0;
+ i9 = i11 + 61 | 0;
+ if ((HEAP8[i9] | 0) == 5) {
+  i9 = 5;
+ } else {
+  do {
+   _singlestep(i1) | 0;
+  } while ((HEAP8[i9] | 0) != 5);
+  i9 = HEAP32[i4 >> 2] | 0;
+  i11 = i9;
+  i9 = HEAP8[i9 + 61 | 0] | 0;
+ }
+ i10 = i11 + 61 | 0;
+ if ((1 << (i9 & 255) & -33 | 0) == 0) {
+  do {
+   _singlestep(i1) | 0;
+  } while ((1 << HEAPU8[i10] & -33 | 0) == 0);
+  i9 = HEAP32[i4 >> 2] | 0;
+  i11 = i9;
+  i9 = HEAP8[i9 + 61 | 0] | 0;
+ }
+ i10 = i11 + 61 | 0;
+ if (!(i9 << 24 >> 24 == 5)) {
+  do {
+   _singlestep(i1) | 0;
+  } while ((HEAP8[i10] | 0) != 5);
+ }
+ if (i8 << 24 >> 24 == 2 ? (i7 = (HEAP32[i4 >> 2] | 0) + 61 | 0, (HEAP8[i7] | 0) != 0) : 0) {
+  do {
+   _singlestep(i1) | 0;
+  } while ((HEAP8[i7] | 0) != 0);
+ }
+ HEAP8[i6] = i8;
+ i6 = HEAP32[i3 + 8 >> 2] | 0;
+ i7 = HEAP32[i3 + 12 >> 2] | 0;
+ i8 = (i7 + i6 | 0) / 100 | 0;
+ i9 = HEAP32[i3 + 156 >> 2] | 0;
+ if ((i9 | 0) < (2147483644 / (i8 | 0) | 0 | 0)) {
+  i8 = Math_imul(i9, i8) | 0;
+ } else {
+  i8 = 2147483644;
+ }
+ _luaE_setdebt(i3, i6 - i8 + i7 | 0);
+ if (i5) {
+  STACKTOP = i2;
+  return;
+ }
+ i3 = (HEAP32[i4 >> 2] | 0) + 104 | 0;
+ i4 = HEAP32[i3 >> 2] | 0;
+ if ((i4 | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ do {
+  i11 = i4 + 5 | 0;
+  HEAP8[i11] = HEAP8[i11] & 191;
+  _GCTM(i1, 1);
+  i4 = HEAP32[i3 >> 2] | 0;
+ } while ((i4 | 0) != 0);
+ STACKTOP = i2;
+ return;
+}
+function _scanexp(i3, i6) {
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0;
+ i1 = STACKTOP;
+ i2 = i3 + 4 | 0;
+ i5 = HEAP32[i2 >> 2] | 0;
+ i4 = i3 + 100 | 0;
+ if (i5 >>> 0 < (HEAP32[i4 >> 2] | 0) >>> 0) {
+  HEAP32[i2 >> 2] = i5 + 1;
+  i8 = HEAPU8[i5] | 0;
+ } else {
+  i8 = ___shgetc(i3) | 0;
+ }
+ if ((i8 | 0) == 43 | (i8 | 0) == 45) {
+  i5 = (i8 | 0) == 45 | 0;
+  i7 = HEAP32[i2 >> 2] | 0;
+  if (i7 >>> 0 < (HEAP32[i4 >> 2] | 0) >>> 0) {
+   HEAP32[i2 >> 2] = i7 + 1;
+   i8 = HEAPU8[i7] | 0;
+  } else {
+   i8 = ___shgetc(i3) | 0;
+  }
+  if (!((i8 + -48 | 0) >>> 0 < 10 | (i6 | 0) == 0) ? (HEAP32[i4 >> 2] | 0) != 0 : 0) {
+   HEAP32[i2 >> 2] = (HEAP32[i2 >> 2] | 0) + -1;
+  }
+ } else {
+  i5 = 0;
+ }
+ if ((i8 + -48 | 0) >>> 0 > 9) {
+  if ((HEAP32[i4 >> 2] | 0) == 0) {
+   i7 = -2147483648;
+   i8 = 0;
+   tempRet0 = i7;
+   STACKTOP = i1;
+   return i8 | 0;
+  }
+  HEAP32[i2 >> 2] = (HEAP32[i2 >> 2] | 0) + -1;
+  i7 = -2147483648;
+  i8 = 0;
+  tempRet0 = i7;
+  STACKTOP = i1;
+  return i8 | 0;
+ } else {
+  i6 = 0;
+ }
+ while (1) {
+  i6 = i8 + -48 + i6 | 0;
+  i7 = HEAP32[i2 >> 2] | 0;
+  if (i7 >>> 0 < (HEAP32[i4 >> 2] | 0) >>> 0) {
+   HEAP32[i2 >> 2] = i7 + 1;
+   i8 = HEAPU8[i7] | 0;
+  } else {
+   i8 = ___shgetc(i3) | 0;
+  }
+  if (!((i8 + -48 | 0) >>> 0 < 10 & (i6 | 0) < 214748364)) {
+   break;
+  }
+  i6 = i6 * 10 | 0;
+ }
+ i7 = ((i6 | 0) < 0) << 31 >> 31;
+ if ((i8 + -48 | 0) >>> 0 < 10) {
+  do {
+   i7 = ___muldi3(i6 | 0, i7 | 0, 10, 0) | 0;
+   i6 = tempRet0;
+   i8 = _i64Add(i8 | 0, ((i8 | 0) < 0) << 31 >> 31 | 0, -48, -1) | 0;
+   i6 = _i64Add(i8 | 0, tempRet0 | 0, i7 | 0, i6 | 0) | 0;
+   i7 = tempRet0;
+   i8 = HEAP32[i2 >> 2] | 0;
+   if (i8 >>> 0 < (HEAP32[i4 >> 2] | 0) >>> 0) {
+    HEAP32[i2 >> 2] = i8 + 1;
+    i8 = HEAPU8[i8] | 0;
+   } else {
+    i8 = ___shgetc(i3) | 0;
+   }
+  } while ((i8 + -48 | 0) >>> 0 < 10 & ((i7 | 0) < 21474836 | (i7 | 0) == 21474836 & i6 >>> 0 < 2061584302));
+ }
+ if ((i8 + -48 | 0) >>> 0 < 10) {
+  do {
+   i8 = HEAP32[i2 >> 2] | 0;
+   if (i8 >>> 0 < (HEAP32[i4 >> 2] | 0) >>> 0) {
+    HEAP32[i2 >> 2] = i8 + 1;
+    i8 = HEAPU8[i8] | 0;
+   } else {
+    i8 = ___shgetc(i3) | 0;
+   }
+  } while ((i8 + -48 | 0) >>> 0 < 10);
+ }
+ if ((HEAP32[i4 >> 2] | 0) != 0) {
+  HEAP32[i2 >> 2] = (HEAP32[i2 >> 2] | 0) + -1;
+ }
+ i3 = (i5 | 0) != 0;
+ i2 = _i64Subtract(0, 0, i6 | 0, i7 | 0) | 0;
+ i4 = i3 ? tempRet0 : i7;
+ i8 = i3 ? i2 : i6;
+ tempRet0 = i4;
+ STACKTOP = i1;
+ return i8 | 0;
+}
+function _sweeplist(i3, i8, i9) {
+ i3 = i3 | 0;
+ i8 = i8 | 0;
+ i9 = i9 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i10 = 0, i11 = 0, i12 = 0;
+ i1 = STACKTOP;
+ i5 = i3 + 12 | 0;
+ i7 = HEAP32[i5 >> 2] | 0;
+ i6 = HEAPU8[i7 + 60 | 0] | 0;
+ i2 = i6 ^ 3;
+ i7 = (HEAP8[i7 + 62 | 0] | 0) == 2;
+ i4 = i7 ? 255 : 184;
+ i6 = i7 ? 64 : i6 & 3;
+ i7 = i7 ? 64 : 0;
+ i10 = HEAP32[i8 >> 2] | 0;
+ L1 : do {
+  if ((i10 | 0) == 0) {
+   i10 = 0;
+  } else {
+   i11 = i9;
+   L2 : while (1) {
+    i9 = i11 + -1 | 0;
+    if ((i11 | 0) == 0) {
+     break L1;
+    }
+    i11 = i10 + 5 | 0;
+    i12 = HEAPU8[i11] | 0;
+    L5 : do {
+     if (((i12 ^ 3) & i2 | 0) == 0) {
+      HEAP32[i8 >> 2] = HEAP32[i10 >> 2];
+      switch (HEAPU8[i10 + 4 | 0] | 0) {
+      case 4:
+       {
+        i12 = (HEAP32[i5 >> 2] | 0) + 28 | 0;
+        HEAP32[i12 >> 2] = (HEAP32[i12 >> 2] | 0) + -1;
+        break;
+       }
+      case 38:
+       {
+        _luaM_realloc_(i3, i10, (HEAPU8[i10 + 6 | 0] << 4) + 16 | 0, 0) | 0;
+        break L5;
+       }
+      case 6:
+       {
+        _luaM_realloc_(i3, i10, (HEAPU8[i10 + 6 | 0] << 2) + 16 | 0, 0) | 0;
+        break L5;
+       }
+      case 20:
+       {
+        break;
+       }
+      case 5:
+       {
+        _luaH_free(i3, i10);
+        break L5;
+       }
+      case 10:
+       {
+        _luaF_freeupval(i3, i10);
+        break L5;
+       }
+      case 8:
+       {
+        _luaE_freethread(i3, i10);
+        break L5;
+       }
+      case 9:
+       {
+        _luaF_freeproto(i3, i10);
+        break L5;
+       }
+      case 7:
+       {
+        _luaM_realloc_(i3, i10, (HEAP32[i10 + 16 >> 2] | 0) + 24 | 0, 0) | 0;
+        break L5;
+       }
+      default:
+       {
+        break L5;
+       }
+      }
+      _luaM_realloc_(i3, i10, (HEAP32[i10 + 12 >> 2] | 0) + 17 | 0, 0) | 0;
+     } else {
+      if ((i12 & i7 | 0) != 0) {
+       i2 = 0;
+       break L2;
+      }
+      if (((HEAP8[i10 + 4 | 0] | 0) == 8 ? (HEAP32[i10 + 28 >> 2] | 0) != 0 : 0) ? (_sweeplist(i3, i10 + 56 | 0, -3) | 0, _luaE_freeCI(i10), (HEAP8[(HEAP32[i5 >> 2] | 0) + 62 | 0] | 0) != 1) : 0) {
+       _luaD_shrinkstack(i10);
+      }
+      HEAP8[i11] = i12 & i4 | i6;
+      i8 = i10;
+     }
+    } while (0);
+    i10 = HEAP32[i8 >> 2] | 0;
+    if ((i10 | 0) == 0) {
+     i10 = 0;
+     break L1;
+    } else {
+     i11 = i9;
+    }
+   }
+   STACKTOP = i1;
+   return i2 | 0;
+  }
+ } while (0);
+ i12 = (i10 | 0) == 0 ? 0 : i8;
+ STACKTOP = i1;
+ return i12 | 0;
+}
+function _resume(i1, i6) {
+ i1 = i1 | 0;
+ i6 = i6 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i2 = STACKTOP;
+ i3 = i1 + 16 | 0;
+ i5 = HEAP32[i3 >> 2] | 0;
+ if ((HEAPU16[i1 + 38 >> 1] | 0) > 199) {
+  _resume_error(i1, 2240, i6);
+ }
+ i4 = i1 + 6 | 0;
+ i7 = HEAP8[i4] | 0;
+ if (i7 << 24 >> 24 == 0) {
+  if ((i5 | 0) != (i1 + 72 | 0)) {
+   _resume_error(i1, 2448, i6);
+  }
+  if ((_luaD_precall(i1, i6 + -16 | 0, -1) | 0) != 0) {
+   STACKTOP = i2;
+   return;
+  }
+  _luaV_execute(i1);
+  STACKTOP = i2;
+  return;
+ } else if (i7 << 24 >> 24 == 1) {
+  HEAP8[i4] = 0;
+  i4 = i1 + 28 | 0;
+  HEAP32[i5 >> 2] = (HEAP32[i4 >> 2] | 0) + (HEAP32[i5 + 20 >> 2] | 0);
+  i8 = i5 + 18 | 0;
+  i7 = HEAP8[i8] | 0;
+  if ((i7 & 1) == 0) {
+   i9 = HEAP32[i5 + 28 >> 2] | 0;
+   if ((i9 | 0) != 0) {
+    HEAP8[i5 + 37 | 0] = 1;
+    HEAP8[i8] = i7 & 255 | 8;
+    i6 = FUNCTION_TABLE_ii[i9 & 255](i1) | 0;
+    i6 = (HEAP32[i1 + 8 >> 2] | 0) + (0 - i6 << 4) | 0;
+   }
+   i5 = HEAP32[i3 >> 2] | 0;
+   i7 = HEAPU8[i1 + 40 | 0] | 0;
+   if ((i7 & 6 | 0) == 0) {
+    i7 = i5 + 8 | 0;
+   } else {
+    if ((i7 & 2 | 0) != 0) {
+     i6 = i6 - (HEAP32[i4 >> 2] | 0) | 0;
+     _luaD_hook(i1, 1, -1);
+     i6 = (HEAP32[i4 >> 2] | 0) + i6 | 0;
+    }
+    i7 = i5 + 8 | 0;
+    HEAP32[i1 + 20 >> 2] = HEAP32[(HEAP32[i7 >> 2] | 0) + 28 >> 2];
+   }
+   i4 = HEAP32[i5 >> 2] | 0;
+   i5 = HEAP16[i5 + 16 >> 1] | 0;
+   HEAP32[i3 >> 2] = HEAP32[i7 >> 2];
+   i3 = i1 + 8 | 0;
+   L27 : do {
+    if (!(i5 << 16 >> 16 == 0)) {
+     i5 = i5 << 16 >> 16;
+     while (1) {
+      if (!(i6 >>> 0 < (HEAP32[i3 >> 2] | 0) >>> 0)) {
+       break;
+      }
+      i7 = i4 + 16 | 0;
+      i10 = i6;
+      i8 = HEAP32[i10 + 4 >> 2] | 0;
+      i9 = i4;
+      HEAP32[i9 >> 2] = HEAP32[i10 >> 2];
+      HEAP32[i9 + 4 >> 2] = i8;
+      HEAP32[i4 + 8 >> 2] = HEAP32[i6 + 8 >> 2];
+      i5 = i5 + -1 | 0;
+      if ((i5 | 0) == 0) {
+       i4 = i7;
+       break L27;
+      }
+      i6 = i6 + 16 | 0;
+      i4 = i7;
+     }
+     if ((i5 | 0) > 0) {
+      i7 = i5;
+      i6 = i4;
+      while (1) {
+       i7 = i7 + -1 | 0;
+       HEAP32[i6 + 8 >> 2] = 0;
+       if ((i7 | 0) <= 0) {
+        break;
+       } else {
+        i6 = i6 + 16 | 0;
+       }
+      }
+      i4 = i4 + (i5 << 4) | 0;
+     }
+    }
+   } while (0);
+   HEAP32[i3 >> 2] = i4;
+  } else {
+   _luaV_execute(i1);
+  }
+  _unroll(i1, 0);
+  STACKTOP = i2;
+  return;
+ } else {
+  _resume_error(i1, 2488, i6);
+ }
+}
+function _lua_setupvalue(i1, i5, i3) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i2 = STACKTOP;
+ i6 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i5 = (HEAP32[i1 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i5 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i5 | 0;
+   i6 = HEAP32[i6 >> 2] | 0;
+   if ((HEAP32[i6 + 8 >> 2] | 0) != 22 ? (i4 = HEAP32[i6 >> 2] | 0, (i5 | 0) <= (HEAPU8[i4 + 6 | 0] | 0 | 0)) : 0) {
+    i5 = i4 + (i5 + -1 << 4) + 16 | 0;
+   } else {
+    i5 = 5192;
+   }
+  } else {
+   i4 = (HEAP32[i6 >> 2] | 0) + (i5 << 4) | 0;
+   i5 = i4 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i4 : 5192;
+  }
+ } while (0);
+ i4 = HEAP32[i5 + 8 >> 2] & 63;
+ do {
+  if ((i4 | 0) == 6) {
+   i5 = HEAP32[i5 >> 2] | 0;
+   i4 = HEAP32[i5 + 12 >> 2] | 0;
+   if ((i3 | 0) <= 0) {
+    i6 = 0;
+    STACKTOP = i2;
+    return i6 | 0;
+   }
+   if ((HEAP32[i4 + 40 >> 2] | 0) < (i3 | 0)) {
+    i6 = 0;
+    STACKTOP = i2;
+    return i6 | 0;
+   }
+   i6 = i3 + -1 | 0;
+   i3 = HEAP32[i5 + 16 + (i6 << 2) >> 2] | 0;
+   i5 = HEAP32[i3 + 8 >> 2] | 0;
+   i4 = HEAP32[(HEAP32[i4 + 28 >> 2] | 0) + (i6 << 3) >> 2] | 0;
+   if ((i4 | 0) == 0) {
+    i4 = 936;
+   } else {
+    i4 = i4 + 16 | 0;
+   }
+  } else if ((i4 | 0) == 38) {
+   i6 = HEAP32[i5 >> 2] | 0;
+   if ((i3 | 0) <= 0) {
+    i6 = 0;
+    STACKTOP = i2;
+    return i6 | 0;
+   }
+   if ((HEAPU8[i6 + 6 | 0] | 0 | 0) >= (i3 | 0)) {
+    i4 = 936;
+    i5 = i6 + (i3 + -1 << 4) + 16 | 0;
+    i3 = i6;
+    break;
+   } else {
+    i6 = 0;
+    STACKTOP = i2;
+    return i6 | 0;
+   }
+  } else {
+   i6 = 0;
+   STACKTOP = i2;
+   return i6 | 0;
+  }
+ } while (0);
+ i6 = i1 + 8 | 0;
+ i7 = HEAP32[i6 >> 2] | 0;
+ i10 = i7 + -16 | 0;
+ HEAP32[i6 >> 2] = i10;
+ i9 = HEAP32[i10 + 4 >> 2] | 0;
+ i8 = i5;
+ HEAP32[i8 >> 2] = HEAP32[i10 >> 2];
+ HEAP32[i8 + 4 >> 2] = i9;
+ HEAP32[i5 + 8 >> 2] = HEAP32[i7 + -8 >> 2];
+ i5 = HEAP32[i6 >> 2] | 0;
+ if ((HEAP32[i5 + 8 >> 2] & 64 | 0) == 0) {
+  i10 = i4;
+  STACKTOP = i2;
+  return i10 | 0;
+ }
+ i5 = HEAP32[i5 >> 2] | 0;
+ if ((HEAP8[i5 + 5 | 0] & 3) == 0) {
+  i10 = i4;
+  STACKTOP = i2;
+  return i10 | 0;
+ }
+ if ((HEAP8[i3 + 5 | 0] & 4) == 0) {
+  i10 = i4;
+  STACKTOP = i2;
+  return i10 | 0;
+ }
+ _luaC_barrier_(i1, i3, i5);
+ i10 = i4;
+ STACKTOP = i2;
+ return i10 | 0;
+}
+function _luaC_forcestep(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i1 = STACKTOP;
+ i3 = HEAP32[i2 + 12 >> 2] | 0;
+ do {
+  if ((HEAP8[i3 + 62 | 0] | 0) == 2) {
+   i4 = i3 + 20 | 0;
+   i6 = HEAP32[i4 >> 2] | 0;
+   do {
+    if ((i6 | 0) != 0) {
+     i5 = i3 + 61 | 0;
+     if ((HEAP8[i5] | 0) != 5) {
+      do {
+       _singlestep(i2) | 0;
+      } while ((HEAP8[i5] | 0) != 5);
+     }
+     HEAP8[i5] = 0;
+     i5 = HEAP32[i3 + 8 >> 2] | 0;
+     i7 = HEAP32[i3 + 12 >> 2] | 0;
+     if ((i7 + i5 | 0) >>> 0 > (Math_imul(HEAP32[i3 + 160 >> 2] | 0, (i6 >>> 0) / 100 | 0) | 0) >>> 0) {
+      HEAP32[i4 >> 2] = 0;
+      break;
+     } else {
+      HEAP32[i4 >> 2] = i6;
+      break;
+     }
+    } else {
+     _luaC_fullgc(i2, 0);
+     i5 = HEAP32[i3 + 8 >> 2] | 0;
+     i7 = HEAP32[i3 + 12 >> 2] | 0;
+     HEAP32[i4 >> 2] = i7 + i5;
+    }
+   } while (0);
+   i4 = i5 + i7 | 0;
+   i5 = (i4 | 0) / 100 | 0;
+   i6 = HEAP32[i3 + 156 >> 2] | 0;
+   if ((i6 | 0) < (2147483644 / (i5 | 0) | 0 | 0)) {
+    i5 = Math_imul(i6, i5) | 0;
+   } else {
+    i5 = 2147483644;
+   }
+   _luaE_setdebt(i3, i4 - i5 | 0);
+   i5 = i3 + 61 | 0;
+  } else {
+   i4 = i3 + 12 | 0;
+   i5 = HEAP32[i3 + 164 >> 2] | 0;
+   i7 = (i5 | 0) < 40 ? 40 : i5;
+   i5 = ((HEAP32[i4 >> 2] | 0) / 200 | 0) + 1 | 0;
+   if ((i5 | 0) < (2147483644 / (i7 | 0) | 0 | 0)) {
+    i8 = Math_imul(i5, i7) | 0;
+   } else {
+    i8 = 2147483644;
+   }
+   i5 = i3 + 61 | 0;
+   do {
+    i8 = i8 - (_singlestep(i2) | 0) | 0;
+    i9 = (HEAP8[i5] | 0) == 5;
+    if (!((i8 | 0) > -1600)) {
+     i6 = 17;
+     break;
+    }
+   } while (!i9);
+   if ((i6 | 0) == 17 ? !i9 : 0) {
+    _luaE_setdebt(i3, ((i8 | 0) / (i7 | 0) | 0) * 200 | 0);
+    break;
+   }
+   i6 = (HEAP32[i3 + 20 >> 2] | 0) / 100 | 0;
+   i7 = HEAP32[i3 + 156 >> 2] | 0;
+   if ((i7 | 0) < (2147483644 / (i6 | 0) | 0 | 0)) {
+    i6 = Math_imul(i7, i6) | 0;
+   } else {
+    i6 = 2147483644;
+   }
+   _luaE_setdebt(i3, (HEAP32[i3 + 8 >> 2] | 0) - i6 + (HEAP32[i4 >> 2] | 0) | 0);
+  }
+ } while (0);
+ i3 = i3 + 104 | 0;
+ if ((HEAP32[i3 >> 2] | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ } else {
+  i4 = 0;
+ }
+ while (1) {
+  if ((i4 | 0) >= 4 ? (HEAP8[i5] | 0) != 5 : 0) {
+   i6 = 26;
+   break;
+  }
+  _GCTM(i2, 1);
+  if ((HEAP32[i3 >> 2] | 0) == 0) {
+   i6 = 26;
+   break;
+  } else {
+   i4 = i4 + 1 | 0;
+  }
+ }
+ if ((i6 | 0) == 26) {
+  STACKTOP = i1;
+  return;
+ }
+}
+function _luaL_loadfilex(i1, i9, i7) {
+ i1 = i1 | 0;
+ i9 = i9 | 0;
+ i7 = i7 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i10 = 0, i11 = 0;
+ i5 = STACKTOP;
+ STACKTOP = STACKTOP + 1056 | 0;
+ i3 = i5;
+ i6 = i5 + 16 | 0;
+ i8 = i5 + 12 | 0;
+ i2 = (_lua_gettop(i1) | 0) + 1 | 0;
+ i4 = (i9 | 0) == 0;
+ if (!i4) {
+  HEAP32[i3 >> 2] = i9;
+  _lua_pushfstring(i1, 1304, i3) | 0;
+  i10 = _fopen(i9 | 0, 1312) | 0;
+  HEAP32[i6 + 4 >> 2] = i10;
+  if ((i10 | 0) == 0) {
+   i10 = _strerror(HEAP32[(___errno_location() | 0) >> 2] | 0) | 0;
+   i9 = (_lua_tolstring(i1, i2, 0) | 0) + 1 | 0;
+   HEAP32[i3 >> 2] = 1320;
+   HEAP32[i3 + 4 >> 2] = i9;
+   HEAP32[i3 + 8 >> 2] = i10;
+   _lua_pushfstring(i1, 1720, i3) | 0;
+   _lua_remove(i1, i2);
+   i10 = 7;
+   STACKTOP = i5;
+   return i10 | 0;
+  }
+ } else {
+  _lua_pushlstring(i1, 1296, 6) | 0;
+  HEAP32[i6 + 4 >> 2] = HEAP32[_stdin >> 2];
+ }
+ if ((_skipcomment(i6, i8) | 0) != 0) {
+  i10 = HEAP32[i6 >> 2] | 0;
+  HEAP32[i6 >> 2] = i10 + 1;
+  HEAP8[i6 + i10 + 8 | 0] = 10;
+ }
+ i10 = HEAP32[i8 >> 2] | 0;
+ do {
+  if (!((i10 | 0) != 27 | i4)) {
+   i11 = i6 + 4 | 0;
+   i10 = _freopen(i9 | 0, 1328, HEAP32[i11 >> 2] | 0) | 0;
+   HEAP32[i11 >> 2] = i10;
+   if ((i10 | 0) != 0) {
+    _skipcomment(i6, i8) | 0;
+    i10 = HEAP32[i8 >> 2] | 0;
+    break;
+   }
+   i11 = _strerror(HEAP32[(___errno_location() | 0) >> 2] | 0) | 0;
+   i10 = (_lua_tolstring(i1, i2, 0) | 0) + 1 | 0;
+   HEAP32[i3 >> 2] = 1336;
+   HEAP32[i3 + 4 >> 2] = i10;
+   HEAP32[i3 + 8 >> 2] = i11;
+   _lua_pushfstring(i1, 1720, i3) | 0;
+   _lua_remove(i1, i2);
+   i11 = 7;
+   STACKTOP = i5;
+   return i11 | 0;
+  }
+ } while (0);
+ if (!((i10 | 0) == -1)) {
+  i11 = HEAP32[i6 >> 2] | 0;
+  HEAP32[i6 >> 2] = i11 + 1;
+  HEAP8[i6 + i11 + 8 | 0] = i10;
+ }
+ i7 = _lua_load(i1, 1, i6, _lua_tolstring(i1, -1, 0) | 0, i7) | 0;
+ i8 = HEAP32[i6 + 4 >> 2] | 0;
+ i6 = _ferror(i8 | 0) | 0;
+ if (!i4) {
+  _fclose(i8 | 0) | 0;
+ }
+ if ((i6 | 0) == 0) {
+  _lua_remove(i1, i2);
+  i11 = i7;
+  STACKTOP = i5;
+  return i11 | 0;
+ } else {
+  _lua_settop(i1, i2);
+  i11 = _strerror(HEAP32[(___errno_location() | 0) >> 2] | 0) | 0;
+  i10 = (_lua_tolstring(i1, i2, 0) | 0) + 1 | 0;
+  HEAP32[i3 >> 2] = 1344;
+  HEAP32[i3 + 4 >> 2] = i10;
+  HEAP32[i3 + 8 >> 2] = i11;
+  _lua_pushfstring(i1, 1720, i3) | 0;
+  _lua_remove(i1, i2);
+  i11 = 7;
+  STACKTOP = i5;
+  return i11 | 0;
+ }
+ return 0;
+}
+function _newupvalue(i3, i1, i2) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i12 = i4;
+ i5 = HEAP32[i3 >> 2] | 0;
+ i9 = i5 + 40 | 0;
+ i7 = HEAP32[i9 >> 2] | 0;
+ i6 = i3 + 47 | 0;
+ i10 = HEAPU8[i6] | 0;
+ if ((i10 + 1 | 0) >>> 0 > 255) {
+  i11 = i3 + 12 | 0;
+  i8 = HEAP32[(HEAP32[i11 >> 2] | 0) + 52 >> 2] | 0;
+  i13 = HEAP32[i5 + 64 >> 2] | 0;
+  if ((i13 | 0) == 0) {
+   i15 = 6552;
+   HEAP32[i12 >> 2] = 6880;
+   i14 = i12 + 4 | 0;
+   HEAP32[i14 >> 2] = 255;
+   i14 = i12 + 8 | 0;
+   HEAP32[i14 >> 2] = i15;
+   i14 = _luaO_pushfstring(i8, 6592, i12) | 0;
+   i15 = HEAP32[i11 >> 2] | 0;
+   _luaX_syntaxerror(i15, i14);
+  }
+  HEAP32[i12 >> 2] = i13;
+  i14 = _luaO_pushfstring(i8, 6568, i12) | 0;
+  HEAP32[i12 >> 2] = 6880;
+  i15 = i12 + 4 | 0;
+  HEAP32[i15 >> 2] = 255;
+  i15 = i12 + 8 | 0;
+  HEAP32[i15 >> 2] = i14;
+  i15 = _luaO_pushfstring(i8, 6592, i12) | 0;
+  i14 = HEAP32[i11 >> 2] | 0;
+  _luaX_syntaxerror(i14, i15);
+ }
+ if ((i10 | 0) < (i7 | 0)) {
+  i8 = i7;
+ } else {
+  i8 = i5 + 28 | 0;
+  HEAP32[i8 >> 2] = _luaM_growaux_(HEAP32[(HEAP32[i3 + 12 >> 2] | 0) + 52 >> 2] | 0, HEAP32[i8 >> 2] | 0, i9, 8, 255, 6880) | 0;
+  i8 = HEAP32[i9 >> 2] | 0;
+ }
+ i9 = i5 + 28 | 0;
+ if ((i7 | 0) < (i8 | 0)) {
+  while (1) {
+   i10 = i7 + 1 | 0;
+   HEAP32[(HEAP32[i9 >> 2] | 0) + (i7 << 3) >> 2] = 0;
+   if ((i10 | 0) < (i8 | 0)) {
+    i7 = i10;
+   } else {
+    break;
+   }
+  }
+ }
+ HEAP8[(HEAP32[i9 >> 2] | 0) + ((HEAPU8[i6] | 0) << 3) + 4 | 0] = (HEAP32[i2 >> 2] | 0) == 7 | 0;
+ HEAP8[(HEAP32[i9 >> 2] | 0) + ((HEAPU8[i6] | 0) << 3) + 5 | 0] = HEAP32[i2 + 8 >> 2];
+ HEAP32[(HEAP32[i9 >> 2] | 0) + ((HEAPU8[i6] | 0) << 3) >> 2] = i1;
+ if ((HEAP8[i1 + 5 | 0] & 3) == 0) {
+  i15 = HEAP8[i6] | 0;
+  i14 = i15 + 1 << 24 >> 24;
+  HEAP8[i6] = i14;
+  i15 = i15 & 255;
+  STACKTOP = i4;
+  return i15 | 0;
+ }
+ if ((HEAP8[i5 + 5 | 0] & 4) == 0) {
+  i15 = HEAP8[i6] | 0;
+  i14 = i15 + 1 << 24 >> 24;
+  HEAP8[i6] = i14;
+  i15 = i15 & 255;
+  STACKTOP = i4;
+  return i15 | 0;
+ }
+ _luaC_barrier_(HEAP32[(HEAP32[i3 + 12 >> 2] | 0) + 52 >> 2] | 0, i5, i1);
+ i15 = HEAP8[i6] | 0;
+ i14 = i15 + 1 << 24 >> 24;
+ HEAP8[i6] = i14;
+ i15 = i15 & 255;
+ STACKTOP = i4;
+ return i15 | 0;
+}
+function _close_func(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i6 = STACKTOP;
+ i2 = HEAP32[i1 + 52 >> 2] | 0;
+ i5 = i1 + 48 | 0;
+ i4 = HEAP32[i5 >> 2] | 0;
+ i3 = HEAP32[i4 >> 2] | 0;
+ _luaK_ret(i4, 0, 0);
+ _leaveblock(i4);
+ i7 = i4 + 20 | 0;
+ i8 = HEAP32[i7 >> 2] | 0;
+ if ((i8 + 1 | 0) >>> 0 > 1073741823) {
+  _luaM_toobig(i2);
+ }
+ i10 = i3 + 12 | 0;
+ i9 = i3 + 48 | 0;
+ HEAP32[i10 >> 2] = _luaM_realloc_(i2, HEAP32[i10 >> 2] | 0, HEAP32[i9 >> 2] << 2, i8 << 2) | 0;
+ HEAP32[i9 >> 2] = HEAP32[i7 >> 2];
+ i8 = HEAP32[i7 >> 2] | 0;
+ if ((i8 + 1 | 0) >>> 0 > 1073741823) {
+  _luaM_toobig(i2);
+ }
+ i9 = i3 + 20 | 0;
+ i10 = i3 + 52 | 0;
+ HEAP32[i9 >> 2] = _luaM_realloc_(i2, HEAP32[i9 >> 2] | 0, HEAP32[i10 >> 2] << 2, i8 << 2) | 0;
+ HEAP32[i10 >> 2] = HEAP32[i7 >> 2];
+ i8 = i4 + 32 | 0;
+ i7 = HEAP32[i8 >> 2] | 0;
+ if ((i7 + 1 | 0) >>> 0 > 268435455) {
+  _luaM_toobig(i2);
+ }
+ i9 = i3 + 8 | 0;
+ i10 = i3 + 44 | 0;
+ HEAP32[i9 >> 2] = _luaM_realloc_(i2, HEAP32[i9 >> 2] | 0, HEAP32[i10 >> 2] << 4, i7 << 4) | 0;
+ HEAP32[i10 >> 2] = HEAP32[i8 >> 2];
+ i8 = i4 + 36 | 0;
+ i7 = HEAP32[i8 >> 2] | 0;
+ if ((i7 + 1 | 0) >>> 0 > 1073741823) {
+  _luaM_toobig(i2);
+ }
+ i9 = i3 + 16 | 0;
+ i10 = i3 + 56 | 0;
+ HEAP32[i9 >> 2] = _luaM_realloc_(i2, HEAP32[i9 >> 2] | 0, HEAP32[i10 >> 2] << 2, i7 << 2) | 0;
+ HEAP32[i10 >> 2] = HEAP32[i8 >> 2];
+ i7 = i4 + 44 | 0;
+ i8 = HEAP16[i7 >> 1] | 0;
+ if ((i8 + 1 | 0) >>> 0 > 357913941) {
+  _luaM_toobig(i2);
+ }
+ i10 = i3 + 24 | 0;
+ i9 = i3 + 60 | 0;
+ HEAP32[i10 >> 2] = _luaM_realloc_(i2, HEAP32[i10 >> 2] | 0, (HEAP32[i9 >> 2] | 0) * 12 | 0, i8 * 12 | 0) | 0;
+ HEAP32[i9 >> 2] = HEAP16[i7 >> 1] | 0;
+ i9 = i4 + 47 | 0;
+ i8 = i3 + 28 | 0;
+ i10 = i3 + 40 | 0;
+ HEAP32[i8 >> 2] = _luaM_realloc_(i2, HEAP32[i8 >> 2] | 0, HEAP32[i10 >> 2] << 3, HEAPU8[i9] << 3) | 0;
+ HEAP32[i10 >> 2] = HEAPU8[i9] | 0;
+ HEAP32[i5 >> 2] = HEAP32[i4 + 8 >> 2];
+ if (((HEAP32[i1 + 16 >> 2] | 0) + -288 | 0) >>> 0 < 2) {
+  i10 = HEAP32[i1 + 24 >> 2] | 0;
+  _luaX_newstring(i1, i10 + 16 | 0, HEAP32[i10 + 12 >> 2] | 0) | 0;
+ }
+ i10 = i2 + 8 | 0;
+ HEAP32[i10 >> 2] = (HEAP32[i10 >> 2] | 0) + -16;
+ if ((HEAP32[(HEAP32[i2 + 12 >> 2] | 0) + 12 >> 2] | 0) <= 0) {
+  STACKTOP = i6;
+  return;
+ }
+ _luaC_step(i2);
+ STACKTOP = i6;
+ return;
+}
+function _lua_topointer(i3, i6) {
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i1 = STACKTOP;
+ i4 = HEAP32[i3 + 16 >> 2] | 0;
+ i5 = (i6 | 0) > 0;
+ do {
+  if (!i5) {
+   if (!((i6 | 0) < -1000999)) {
+    i7 = (HEAP32[i3 + 8 >> 2] | 0) + (i6 << 4) | 0;
+    break;
+   }
+   if ((i6 | 0) == -1001e3) {
+    i7 = (HEAP32[i3 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i8 = -1001e3 - i6 | 0;
+   i9 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i9 + 8 >> 2] | 0) != 22 ? (i7 = HEAP32[i9 >> 2] | 0, (i8 | 0) <= (HEAPU8[i7 + 6 | 0] | 0 | 0)) : 0) {
+    i7 = i7 + (i8 + -1 << 4) + 16 | 0;
+   } else {
+    i7 = 5192;
+   }
+  } else {
+   i7 = (HEAP32[i4 >> 2] | 0) + (i6 << 4) | 0;
+   i7 = i7 >>> 0 < (HEAP32[i3 + 8 >> 2] | 0) >>> 0 ? i7 : 5192;
+  }
+ } while (0);
+ switch (HEAP32[i7 + 8 >> 2] & 63 | 0) {
+ case 22:
+  {
+   i9 = HEAP32[i7 >> 2] | 0;
+   STACKTOP = i1;
+   return i9 | 0;
+  }
+ case 2:
+ case 7:
+  {
+   do {
+    if (!i5) {
+     if (!((i6 | 0) < -1000999)) {
+      i2 = (HEAP32[i3 + 8 >> 2] | 0) + (i6 << 4) | 0;
+      break;
+     }
+     if ((i6 | 0) == -1001e3) {
+      i2 = (HEAP32[i3 + 12 >> 2] | 0) + 40 | 0;
+      break;
+     }
+     i3 = -1001e3 - i6 | 0;
+     i4 = HEAP32[i4 >> 2] | 0;
+     if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i2 = HEAP32[i4 >> 2] | 0, (i3 | 0) <= (HEAPU8[i2 + 6 | 0] | 0 | 0)) : 0) {
+      i2 = i2 + (i3 + -1 << 4) + 16 | 0;
+     } else {
+      i2 = 5192;
+     }
+    } else {
+     i2 = (HEAP32[i4 >> 2] | 0) + (i6 << 4) | 0;
+     i2 = i2 >>> 0 < (HEAP32[i3 + 8 >> 2] | 0) >>> 0 ? i2 : 5192;
+    }
+   } while (0);
+   i3 = HEAP32[i2 + 8 >> 2] & 15;
+   if ((i3 | 0) == 7) {
+    i9 = (HEAP32[i2 >> 2] | 0) + 24 | 0;
+    STACKTOP = i1;
+    return i9 | 0;
+   } else if ((i3 | 0) == 2) {
+    i9 = HEAP32[i2 >> 2] | 0;
+    STACKTOP = i1;
+    return i9 | 0;
+   } else {
+    i9 = 0;
+    STACKTOP = i1;
+    return i9 | 0;
+   }
+  }
+ case 8:
+  {
+   i9 = HEAP32[i7 >> 2] | 0;
+   STACKTOP = i1;
+   return i9 | 0;
+  }
+ case 5:
+  {
+   i9 = HEAP32[i7 >> 2] | 0;
+   STACKTOP = i1;
+   return i9 | 0;
+  }
+ case 38:
+  {
+   i9 = HEAP32[i7 >> 2] | 0;
+   STACKTOP = i1;
+   return i9 | 0;
+  }
+ case 6:
+  {
+   i9 = HEAP32[i7 >> 2] | 0;
+   STACKTOP = i1;
+   return i9 | 0;
+  }
+ default:
+  {
+   i9 = 0;
+   STACKTOP = i1;
+   return i9 | 0;
+  }
+ }
+ return 0;
+}
+function _luaH_get(i4, i6) {
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, d5 = 0.0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, d11 = 0.0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i8 = i3 + 8 | 0;
+ i9 = i3;
+ i7 = i6 + 8 | 0;
+ i10 = HEAP32[i7 >> 2] & 63;
+ if ((i10 | 0) == 4) {
+  i6 = HEAP32[i6 >> 2] | 0;
+  i7 = (HEAP32[i4 + 16 >> 2] | 0) + (((1 << (HEAPU8[i4 + 7 | 0] | 0)) + -1 & HEAP32[i6 + 8 >> 2]) << 5) | 0;
+  while (1) {
+   if ((HEAP32[i7 + 24 >> 2] | 0) == 68 ? (HEAP32[i7 + 16 >> 2] | 0) == (i6 | 0) : 0) {
+    break;
+   }
+   i4 = HEAP32[i7 + 28 >> 2] | 0;
+   if ((i4 | 0) == 0) {
+    i2 = 5192;
+    i1 = 22;
+    break;
+   } else {
+    i7 = i4;
+   }
+  }
+  if ((i1 | 0) == 22) {
+   STACKTOP = i3;
+   return i2 | 0;
+  }
+  i10 = i7;
+  STACKTOP = i3;
+  return i10 | 0;
+ } else if ((i10 | 0) == 3) {
+  d11 = +HEAPF64[i6 >> 3];
+  HEAPF64[i9 >> 3] = d11 + 6755399441055744.0;
+  i9 = HEAP32[i9 >> 2] | 0;
+  d5 = +(i9 | 0);
+  if (d5 == d11) {
+   i6 = i9 + -1 | 0;
+   if (i6 >>> 0 < (HEAP32[i4 + 28 >> 2] | 0) >>> 0) {
+    i10 = (HEAP32[i4 + 12 >> 2] | 0) + (i6 << 4) | 0;
+    STACKTOP = i3;
+    return i10 | 0;
+   }
+   HEAPF64[i8 >> 3] = d5 + 1.0;
+   i6 = (HEAP32[i8 + 4 >> 2] | 0) + (HEAP32[i8 >> 2] | 0) | 0;
+   if ((i6 | 0) < 0) {
+    i7 = 0 - i6 | 0;
+    i6 = (i6 | 0) == (i7 | 0) ? 0 : i7;
+   }
+   i4 = (HEAP32[i4 + 16 >> 2] | 0) + (((i6 | 0) % ((1 << (HEAPU8[i4 + 7 | 0] | 0)) + -1 | 1 | 0) | 0) << 5) | 0;
+   while (1) {
+    if ((HEAP32[i4 + 24 >> 2] | 0) == 3 ? +HEAPF64[i4 + 16 >> 3] == d5 : 0) {
+     break;
+    }
+    i6 = HEAP32[i4 + 28 >> 2] | 0;
+    if ((i6 | 0) == 0) {
+     i2 = 5192;
+     i1 = 22;
+     break;
+    } else {
+     i4 = i6;
+    }
+   }
+   if ((i1 | 0) == 22) {
+    STACKTOP = i3;
+    return i2 | 0;
+   }
+   i10 = i4;
+   STACKTOP = i3;
+   return i10 | 0;
+  }
+ } else if ((i10 | 0) == 0) {
+  i10 = 5192;
+  STACKTOP = i3;
+  return i10 | 0;
+ }
+ i8 = _mainposition(i4, i6) | 0;
+ while (1) {
+  if ((HEAP32[i8 + 24 >> 2] | 0) == (HEAP32[i7 >> 2] | 0) ? (_luaV_equalobj_(0, i8 + 16 | 0, i6) | 0) != 0 : 0) {
+   break;
+  }
+  i4 = HEAP32[i8 + 28 >> 2] | 0;
+  if ((i4 | 0) == 0) {
+   i2 = 5192;
+   i1 = 22;
+   break;
+  } else {
+   i8 = i4;
+  }
+ }
+ if ((i1 | 0) == 22) {
+  STACKTOP = i3;
+  return i2 | 0;
+ }
+ i10 = i8;
+ STACKTOP = i3;
+ return i10 | 0;
+}
+function _suffixedexp(i1, i8) {
+ i1 = i1 | 0;
+ i8 = i8 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 80 | 0;
+ i10 = i2 + 48 | 0;
+ i3 = i2 + 24 | 0;
+ i6 = i2;
+ i4 = i1 + 48 | 0;
+ i9 = HEAP32[i4 >> 2] | 0;
+ i5 = HEAP32[i1 + 4 >> 2] | 0;
+ i7 = i1 + 16 | 0;
+ i12 = HEAP32[i7 >> 2] | 0;
+ if ((i12 | 0) == 40) {
+  _luaX_next(i1);
+  _subexpr(i1, i8, 0) | 0;
+  _check_match(i1, 41, 40, i5);
+  _luaK_dischargevars(HEAP32[i4 >> 2] | 0, i8);
+  i11 = i1 + 24 | 0;
+ } else if ((i12 | 0) == 288) {
+  i11 = i1 + 24 | 0;
+  i13 = HEAP32[i11 >> 2] | 0;
+  _luaX_next(i1);
+  i12 = HEAP32[i4 >> 2] | 0;
+  if ((_singlevaraux(i12, i13, i8, 1) | 0) == 0) {
+   _singlevaraux(i12, HEAP32[i1 + 72 >> 2] | 0, i8, 1) | 0;
+   i13 = _luaK_stringK(HEAP32[i4 >> 2] | 0, i13) | 0;
+   HEAP32[i10 + 16 >> 2] = -1;
+   HEAP32[i10 + 20 >> 2] = -1;
+   HEAP32[i10 >> 2] = 4;
+   HEAP32[i10 + 8 >> 2] = i13;
+   _luaK_indexed(i12, i8, i10);
+  }
+ } else {
+  _luaX_syntaxerror(i1, 6656);
+ }
+ i10 = i6 + 16 | 0;
+ i12 = i6 + 20 | 0;
+ i13 = i6 + 8 | 0;
+ L7 : while (1) {
+  switch (HEAP32[i7 >> 2] | 0) {
+  case 46:
+   {
+    _fieldsel(i1, i8);
+    continue L7;
+   }
+  case 91:
+   {
+    _luaK_exp2anyregup(i9, i8);
+    _luaX_next(i1);
+    _subexpr(i1, i3, 0) | 0;
+    _luaK_exp2val(HEAP32[i4 >> 2] | 0, i3);
+    if ((HEAP32[i7 >> 2] | 0) != 93) {
+     i3 = 10;
+     break L7;
+    }
+    _luaX_next(i1);
+    _luaK_indexed(i9, i8, i3);
+    continue L7;
+   }
+  case 58:
+   {
+    _luaX_next(i1);
+    if ((HEAP32[i7 >> 2] | 0) != 288) {
+     i3 = 13;
+     break L7;
+    }
+    i14 = HEAP32[i11 >> 2] | 0;
+    _luaX_next(i1);
+    i14 = _luaK_stringK(HEAP32[i4 >> 2] | 0, i14) | 0;
+    HEAP32[i10 >> 2] = -1;
+    HEAP32[i12 >> 2] = -1;
+    HEAP32[i6 >> 2] = 4;
+    HEAP32[i13 >> 2] = i14;
+    _luaK_self(i9, i8, i6);
+    _funcargs(i1, i8, i5);
+    continue L7;
+   }
+  case 123:
+  case 289:
+  case 40:
+   {
+    _luaK_exp2nextreg(i9, i8);
+    _funcargs(i1, i8, i5);
+    continue L7;
+   }
+  default:
+   {
+    i3 = 16;
+    break L7;
+   }
+  }
+ }
+ if ((i3 | 0) == 10) {
+  _error_expected(i1, 93);
+ } else if ((i3 | 0) == 13) {
+  _error_expected(i1, 288);
+ } else if ((i3 | 0) == 16) {
+  STACKTOP = i2;
+  return;
+ }
+}
+function _luaK_patchlist(i2, i7, i3) {
+ i2 = i2 | 0;
+ i7 = i7 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0;
+ i1 = STACKTOP;
+ if ((HEAP32[i2 + 20 >> 2] | 0) == (i3 | 0)) {
+  HEAP32[i2 + 24 >> 2] = i3;
+  i3 = i2 + 28 | 0;
+  if ((i7 | 0) == -1) {
+   STACKTOP = i1;
+   return;
+  }
+  i6 = HEAP32[i3 >> 2] | 0;
+  if ((i6 | 0) == -1) {
+   HEAP32[i3 >> 2] = i7;
+   STACKTOP = i1;
+   return;
+  }
+  i5 = HEAP32[(HEAP32[i2 >> 2] | 0) + 12 >> 2] | 0;
+  while (1) {
+   i3 = i5 + (i6 << 2) | 0;
+   i4 = HEAP32[i3 >> 2] | 0;
+   i8 = (i4 >>> 14) + -131071 | 0;
+   if ((i8 | 0) == -1) {
+    break;
+   }
+   i8 = i6 + 1 + i8 | 0;
+   if ((i8 | 0) == -1) {
+    break;
+   } else {
+    i6 = i8;
+   }
+  }
+  i5 = ~i6 + i7 | 0;
+  if ((((i5 | 0) > -1 ? i5 : 0 - i5 | 0) | 0) > 131071) {
+   _luaX_syntaxerror(HEAP32[i2 + 12 >> 2] | 0, 10624);
+  }
+  HEAP32[i3 >> 2] = (i5 << 14) + 2147467264 | i4 & 16383;
+  STACKTOP = i1;
+  return;
+ }
+ if ((i7 | 0) == -1) {
+  STACKTOP = i1;
+  return;
+ }
+ i6 = HEAP32[(HEAP32[i2 >> 2] | 0) + 12 >> 2] | 0;
+ i10 = i7;
+ while (1) {
+  i7 = i6 + (i10 << 2) | 0;
+  i9 = HEAP32[i7 >> 2] | 0;
+  i8 = (i9 >>> 14) + -131071 | 0;
+  if ((i8 | 0) == -1) {
+   i8 = -1;
+  } else {
+   i8 = i10 + 1 + i8 | 0;
+  }
+  if ((i10 | 0) > 0 ? (i4 = i6 + (i10 + -1 << 2) | 0, i5 = HEAP32[i4 >> 2] | 0, (HEAP8[5584 + (i5 & 63) | 0] | 0) < 0) : 0) {
+   i12 = i4;
+   i11 = i5;
+  } else {
+   i12 = i7;
+   i11 = i9;
+  }
+  if ((i11 & 63 | 0) == 28) {
+   HEAP32[i12 >> 2] = i11 & 8372224 | i11 >>> 23 << 6 | 27;
+   i9 = ~i10 + i3 | 0;
+   if ((((i9 | 0) > -1 ? i9 : 0 - i9 | 0) | 0) > 131071) {
+    i3 = 20;
+    break;
+   }
+   i9 = HEAP32[i7 >> 2] & 16383 | (i9 << 14) + 2147467264;
+  } else {
+   i10 = ~i10 + i3 | 0;
+   if ((((i10 | 0) > -1 ? i10 : 0 - i10 | 0) | 0) > 131071) {
+    i3 = 23;
+    break;
+   }
+   i9 = i9 & 16383 | (i10 << 14) + 2147467264;
+  }
+  HEAP32[i7 >> 2] = i9;
+  if ((i8 | 0) == -1) {
+   i3 = 26;
+   break;
+  } else {
+   i10 = i8;
+  }
+ }
+ if ((i3 | 0) == 20) {
+  _luaX_syntaxerror(HEAP32[i2 + 12 >> 2] | 0, 10624);
+ } else if ((i3 | 0) == 23) {
+  _luaX_syntaxerror(HEAP32[i2 + 12 >> 2] | 0, 10624);
+ } else if ((i3 | 0) == 26) {
+  STACKTOP = i1;
+  return;
+ }
+}
+function _luaG_typeerror(i5, i6, i1) {
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i3 = i2;
+ i2 = i2 + 16 | 0;
+ i8 = HEAP32[i5 + 16 >> 2] | 0;
+ HEAP32[i2 >> 2] = 0;
+ i4 = HEAP32[8528 + ((HEAP32[i6 + 8 >> 2] & 15) + 1 << 2) >> 2] | 0;
+ L1 : do {
+  if (!((HEAP8[i8 + 18 | 0] & 1) == 0)) {
+   i7 = HEAP32[HEAP32[i8 >> 2] >> 2] | 0;
+   i10 = HEAP8[i7 + 6 | 0] | 0;
+   L3 : do {
+    if (!(i10 << 24 >> 24 == 0)) {
+     i9 = i7 + 16 | 0;
+     i11 = i10 & 255;
+     i10 = 0;
+     while (1) {
+      i12 = i10 + 1 | 0;
+      if ((HEAP32[(HEAP32[i9 + (i10 << 2) >> 2] | 0) + 8 >> 2] | 0) == (i6 | 0)) {
+       break;
+      }
+      if ((i12 | 0) < (i11 | 0)) {
+       i10 = i12;
+      } else {
+       break L3;
+      }
+     }
+     i9 = HEAP32[(HEAP32[(HEAP32[i7 + 12 >> 2] | 0) + 28 >> 2] | 0) + (i10 << 3) >> 2] | 0;
+     if ((i9 | 0) == 0) {
+      i9 = 2104;
+     } else {
+      i9 = i9 + 16 | 0;
+     }
+     HEAP32[i2 >> 2] = i9;
+     i11 = i9;
+     i10 = 2072;
+     HEAP32[i3 >> 2] = i1;
+     i12 = i3 + 4 | 0;
+     HEAP32[i12 >> 2] = i10;
+     i12 = i3 + 8 | 0;
+     HEAP32[i12 >> 2] = i11;
+     i12 = i3 + 12 | 0;
+     HEAP32[i12 >> 2] = i4;
+     _luaG_runerror(i5, 1840, i3);
+    }
+   } while (0);
+   i9 = HEAP32[i8 + 24 >> 2] | 0;
+   i10 = HEAP32[i8 + 4 >> 2] | 0;
+   if (i9 >>> 0 < i10 >>> 0) {
+    i12 = i9;
+    while (1) {
+     i11 = i12 + 16 | 0;
+     if ((i12 | 0) == (i6 | 0)) {
+      break;
+     }
+     if (i11 >>> 0 < i10 >>> 0) {
+      i12 = i11;
+     } else {
+      break L1;
+     }
+    }
+    i12 = HEAP32[i7 + 12 >> 2] | 0;
+    i6 = _getobjname(i12, ((HEAP32[i8 + 28 >> 2] | 0) - (HEAP32[i12 + 12 >> 2] | 0) >> 2) + -1 | 0, i6 - i9 >> 4, i2) | 0;
+    if ((i6 | 0) != 0) {
+     i11 = HEAP32[i2 >> 2] | 0;
+     i10 = i6;
+     HEAP32[i3 >> 2] = i1;
+     i12 = i3 + 4 | 0;
+     HEAP32[i12 >> 2] = i10;
+     i12 = i3 + 8 | 0;
+     HEAP32[i12 >> 2] = i11;
+     i12 = i3 + 12 | 0;
+     HEAP32[i12 >> 2] = i4;
+     _luaG_runerror(i5, 1840, i3);
+    }
+   }
+  }
+ } while (0);
+ HEAP32[i3 >> 2] = i1;
+ HEAP32[i3 + 4 >> 2] = i4;
+ _luaG_runerror(i5, 1880, i3);
+}
+function _lua_setmetatable(i1, i7) {
+ i1 = i1 | 0;
+ i7 = i7 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0;
+ i4 = STACKTOP;
+ i6 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i7 | 0) <= 0) {
+   if (!((i7 | 0) < -1000999)) {
+    i5 = (HEAP32[i1 + 8 >> 2] | 0) + (i7 << 4) | 0;
+    break;
+   }
+   if ((i7 | 0) == -1001e3) {
+    i5 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i7 = -1001e3 - i7 | 0;
+   i6 = HEAP32[i6 >> 2] | 0;
+   if ((HEAP32[i6 + 8 >> 2] | 0) != 22 ? (i5 = HEAP32[i6 >> 2] | 0, (i7 | 0) <= (HEAPU8[i5 + 6 | 0] | 0 | 0)) : 0) {
+    i5 = i5 + (i7 + -1 << 4) + 16 | 0;
+   } else {
+    i5 = 5192;
+   }
+  } else {
+   i5 = (HEAP32[i6 >> 2] | 0) + (i7 << 4) | 0;
+   i5 = i5 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i5 : 5192;
+  }
+ } while (0);
+ i6 = i1 + 8 | 0;
+ i7 = HEAP32[i6 >> 2] | 0;
+ if ((HEAP32[i7 + -8 >> 2] | 0) == 0) {
+  i7 = 0;
+ } else {
+  i7 = HEAP32[i7 + -16 >> 2] | 0;
+ }
+ i8 = HEAP32[i5 + 8 >> 2] & 15;
+ if ((i8 | 0) == 5) {
+  HEAP32[(HEAP32[i5 >> 2] | 0) + 8 >> 2] = i7;
+  if ((i7 | 0) == 0) {
+   i8 = HEAP32[i6 >> 2] | 0;
+   i8 = i8 + -16 | 0;
+   HEAP32[i6 >> 2] = i8;
+   STACKTOP = i4;
+   return 1;
+  }
+  if (!((HEAP8[i7 + 5 | 0] & 3) == 0) ? (i2 = HEAP32[i5 >> 2] | 0, !((HEAP8[i2 + 5 | 0] & 4) == 0)) : 0) {
+   _luaC_barrierback_(i1, i2);
+  }
+  _luaC_checkfinalizer(i1, HEAP32[i5 >> 2] | 0, i7);
+  i8 = HEAP32[i6 >> 2] | 0;
+  i8 = i8 + -16 | 0;
+  HEAP32[i6 >> 2] = i8;
+  STACKTOP = i4;
+  return 1;
+ } else if ((i8 | 0) == 7) {
+  HEAP32[(HEAP32[i5 >> 2] | 0) + 8 >> 2] = i7;
+  if ((i7 | 0) == 0) {
+   i8 = HEAP32[i6 >> 2] | 0;
+   i8 = i8 + -16 | 0;
+   HEAP32[i6 >> 2] = i8;
+   STACKTOP = i4;
+   return 1;
+  }
+  if (!((HEAP8[i7 + 5 | 0] & 3) == 0) ? (i3 = HEAP32[i5 >> 2] | 0, !((HEAP8[i3 + 5 | 0] & 4) == 0)) : 0) {
+   _luaC_barrier_(i1, i3, i7);
+  }
+  _luaC_checkfinalizer(i1, HEAP32[i5 >> 2] | 0, i7);
+  i8 = HEAP32[i6 >> 2] | 0;
+  i8 = i8 + -16 | 0;
+  HEAP32[i6 >> 2] = i8;
+  STACKTOP = i4;
+  return 1;
+ } else {
+  HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + (i8 << 2) + 252 >> 2] = i7;
+  i8 = HEAP32[i6 >> 2] | 0;
+  i8 = i8 + -16 | 0;
+  HEAP32[i6 >> 2] = i8;
+  STACKTOP = i4;
+  return 1;
+ }
+ return 0;
+}
+function _recfield(i2, i10) {
+ i2 = i2 | 0;
+ i10 = i10 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i9 = i1 + 48 | 0;
+ i6 = i1 + 24 | 0;
+ i3 = i1;
+ i13 = i2 + 48 | 0;
+ i8 = HEAP32[i13 >> 2] | 0;
+ i5 = i8 + 48 | 0;
+ i4 = HEAP8[i5] | 0;
+ i7 = i2 + 16 | 0;
+ do {
+  if ((HEAP32[i7 >> 2] | 0) != 288) {
+   _luaX_next(i2);
+   _subexpr(i2, i6, 0) | 0;
+   _luaK_exp2val(HEAP32[i13 >> 2] | 0, i6);
+   if ((HEAP32[i7 >> 2] | 0) == 93) {
+    _luaX_next(i2);
+    i11 = i10 + 28 | 0;
+    break;
+   } else {
+    _error_expected(i2, 93);
+   }
+  } else {
+   i12 = i10 + 28 | 0;
+   if ((HEAP32[i12 >> 2] | 0) <= 2147483645) {
+    i11 = HEAP32[i2 + 24 >> 2] | 0;
+    _luaX_next(i2);
+    i11 = _luaK_stringK(HEAP32[i13 >> 2] | 0, i11) | 0;
+    HEAP32[i6 + 16 >> 2] = -1;
+    HEAP32[i6 + 20 >> 2] = -1;
+    HEAP32[i6 >> 2] = 4;
+    HEAP32[i6 + 8 >> 2] = i11;
+    i11 = i12;
+    break;
+   }
+   i14 = i8 + 12 | 0;
+   i13 = HEAP32[(HEAP32[i14 >> 2] | 0) + 52 >> 2] | 0;
+   i12 = HEAP32[(HEAP32[i8 >> 2] | 0) + 64 >> 2] | 0;
+   if ((i12 | 0) == 0) {
+    i16 = 6552;
+    HEAP32[i9 >> 2] = 6528;
+    i15 = i9 + 4 | 0;
+    HEAP32[i15 >> 2] = 2147483645;
+    i15 = i9 + 8 | 0;
+    HEAP32[i15 >> 2] = i16;
+    i15 = _luaO_pushfstring(i13, 6592, i9) | 0;
+    i16 = HEAP32[i14 >> 2] | 0;
+    _luaX_syntaxerror(i16, i15);
+   }
+   HEAP32[i9 >> 2] = i12;
+   i15 = _luaO_pushfstring(i13, 6568, i9) | 0;
+   HEAP32[i9 >> 2] = 6528;
+   i16 = i9 + 4 | 0;
+   HEAP32[i16 >> 2] = 2147483645;
+   i16 = i9 + 8 | 0;
+   HEAP32[i16 >> 2] = i15;
+   i16 = _luaO_pushfstring(i13, 6592, i9) | 0;
+   i15 = HEAP32[i14 >> 2] | 0;
+   _luaX_syntaxerror(i15, i16);
+  }
+ } while (0);
+ HEAP32[i11 >> 2] = (HEAP32[i11 >> 2] | 0) + 1;
+ if ((HEAP32[i7 >> 2] | 0) == 61) {
+  _luaX_next(i2);
+  i16 = _luaK_exp2RK(i8, i6) | 0;
+  _subexpr(i2, i3, 0) | 0;
+  i15 = HEAP32[(HEAP32[i10 + 24 >> 2] | 0) + 8 >> 2] | 0;
+  _luaK_codeABC(i8, 10, i15, i16, _luaK_exp2RK(i8, i3) | 0) | 0;
+  HEAP8[i5] = i4;
+  STACKTOP = i1;
+  return;
+ } else {
+  _error_expected(i2, 61);
+ }
+}
+function _lua_newstate(i3, i6) {
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i7 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i5 = i1 + 8 | 0;
+ i4 = i1;
+ i2 = FUNCTION_TABLE_iiiii[i3 & 3](i6, 0, 8, 400) | 0;
+ if ((i2 | 0) == 0) {
+  i6 = 0;
+  STACKTOP = i1;
+  return i6 | 0;
+ }
+ i7 = i2 + 112 | 0;
+ HEAP32[i2 >> 2] = 0;
+ HEAP8[i2 + 4 | 0] = 8;
+ HEAP8[i2 + 172 | 0] = 33;
+ HEAP8[i2 + 5 | 0] = 1;
+ HEAP8[i2 + 174 | 0] = 0;
+ HEAP32[i2 + 12 >> 2] = i7;
+ HEAP32[i2 + 28 >> 2] = 0;
+ HEAP32[i2 + 16 >> 2] = 0;
+ HEAP32[i2 + 32 >> 2] = 0;
+ HEAP32[i2 + 64 >> 2] = 0;
+ HEAP16[i2 + 38 >> 1] = 0;
+ HEAP32[i2 + 52 >> 2] = 0;
+ HEAP8[i2 + 40 | 0] = 0;
+ HEAP32[i2 + 44 >> 2] = 0;
+ HEAP8[i2 + 41 | 0] = 1;
+ HEAP32[i2 + 48 >> 2] = 0;
+ HEAP32[i2 + 56 >> 2] = 0;
+ HEAP16[i2 + 36 >> 1] = 1;
+ HEAP8[i2 + 6 | 0] = 0;
+ HEAP32[i2 + 68 >> 2] = 0;
+ HEAP32[i7 >> 2] = i3;
+ HEAP32[i2 + 116 >> 2] = i6;
+ HEAP32[i2 + 284 >> 2] = i2;
+ i3 = _time(0) | 0;
+ HEAP32[i4 >> 2] = i3;
+ HEAP32[i5 >> 2] = i2;
+ HEAP32[i5 + 4 >> 2] = i4;
+ HEAP32[i5 + 8 >> 2] = 5192;
+ HEAP32[i5 + 12 >> 2] = 1;
+ HEAP32[i2 + 168 >> 2] = _luaS_hash(i5, 16, i3) | 0;
+ i4 = i2 + 224 | 0;
+ HEAP32[i2 + 240 >> 2] = i4;
+ HEAP32[i2 + 244 >> 2] = i4;
+ HEAP8[i2 + 175 | 0] = 0;
+ i4 = i2 + 132 | 0;
+ HEAP32[i2 + 160 >> 2] = 0;
+ HEAP32[i2 + 256 >> 2] = 0;
+ HEAP32[i2 + 264 >> 2] = 0;
+ HEAP32[i2 + 280 >> 2] = 0;
+ HEAP32[i4 + 0 >> 2] = 0;
+ HEAP32[i4 + 4 >> 2] = 0;
+ HEAP32[i4 + 8 >> 2] = 0;
+ HEAP32[i4 + 12 >> 2] = 0;
+ HEAP32[i2 + 288 >> 2] = _lua_version(0) | 0;
+ HEAP8[i2 + 173 | 0] = 5;
+ i4 = i2 + 120 | 0;
+ i5 = i2 + 180 | 0;
+ i3 = i5 + 40 | 0;
+ do {
+  HEAP32[i5 >> 2] = 0;
+  i5 = i5 + 4 | 0;
+ } while ((i5 | 0) < (i3 | 0));
+ HEAP32[i4 >> 2] = 400;
+ HEAP32[i2 + 124 >> 2] = 0;
+ HEAP32[i2 + 268 >> 2] = 200;
+ HEAP32[i2 + 272 >> 2] = 200;
+ HEAP32[i2 + 276 >> 2] = 200;
+ i5 = i2 + 364 | 0;
+ i3 = i5 + 36 | 0;
+ do {
+  HEAP32[i5 >> 2] = 0;
+  i5 = i5 + 4 | 0;
+ } while ((i5 | 0) < (i3 | 0));
+ if ((_luaD_rawrunprotected(i2, 8, 0) | 0) == 0) {
+  i7 = i2;
+  STACKTOP = i1;
+  return i7 | 0;
+ }
+ _close_state(i2);
+ i7 = 0;
+ STACKTOP = i1;
+ return i7 | 0;
+}
+function _luaU_undump(i1, i7, i8, i9) {
+ i1 = i1 | 0;
+ i7 = i7 | 0;
+ i8 = i8 | 0;
+ i9 = i9 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i4 = i2 + 16 | 0;
+ i5 = i2 + 34 | 0;
+ i3 = i2;
+ i6 = HEAP8[i9] | 0;
+ if (i6 << 24 >> 24 == 27) {
+  HEAP32[i3 + 12 >> 2] = 8800;
+ } else if (i6 << 24 >> 24 == 61 | i6 << 24 >> 24 == 64) {
+  HEAP32[i3 + 12 >> 2] = i9 + 1;
+ } else {
+  HEAP32[i3 + 12 >> 2] = i9;
+ }
+ HEAP32[i3 >> 2] = i1;
+ HEAP32[i3 + 4 >> 2] = i7;
+ HEAP32[i3 + 8 >> 2] = i8;
+ HEAP32[i4 >> 2] = 1635077147;
+ HEAP8[i4 + 4 | 0] = 82;
+ HEAP8[i4 + 5 | 0] = 0;
+ HEAP8[i4 + 6 | 0] = 1;
+ HEAP8[i4 + 7 | 0] = 4;
+ HEAP8[i4 + 8 | 0] = 4;
+ HEAP8[i4 + 9 | 0] = 4;
+ HEAP8[i4 + 10 | 0] = 8;
+ i9 = i4 + 12 | 0;
+ HEAP8[i4 + 11 | 0] = 0;
+ HEAP8[i9 + 0 | 0] = HEAP8[8816 | 0] | 0;
+ HEAP8[i9 + 1 | 0] = HEAP8[8817 | 0] | 0;
+ HEAP8[i9 + 2 | 0] = HEAP8[8818 | 0] | 0;
+ HEAP8[i9 + 3 | 0] = HEAP8[8819 | 0] | 0;
+ HEAP8[i9 + 4 | 0] = HEAP8[8820 | 0] | 0;
+ HEAP8[i9 + 5 | 0] = HEAP8[8821 | 0] | 0;
+ HEAP8[i5] = 27;
+ if ((_luaZ_read(i7, i5 + 1 | 0, 17) | 0) != 0) {
+  _error(i3, 8824);
+ }
+ if ((_memcmp(i4, i5, 18) | 0) == 0) {
+  i4 = _luaF_newLclosure(i1, 1) | 0;
+  i5 = i1 + 8 | 0;
+  i9 = HEAP32[i5 >> 2] | 0;
+  HEAP32[i9 >> 2] = i4;
+  HEAP32[i9 + 8 >> 2] = 70;
+  i9 = (HEAP32[i5 >> 2] | 0) + 16 | 0;
+  HEAP32[i5 >> 2] = i9;
+  if (((HEAP32[i1 + 24 >> 2] | 0) - i9 | 0) < 16) {
+   _luaD_growstack(i1, 0);
+  }
+  i9 = _luaF_newproto(i1) | 0;
+  i6 = i4 + 12 | 0;
+  HEAP32[i6 >> 2] = i9;
+  _LoadFunction(i3, i9);
+  i6 = HEAP32[i6 >> 2] | 0;
+  i3 = HEAP32[i6 + 40 >> 2] | 0;
+  if ((i3 | 0) == 1) {
+   i9 = i4;
+   STACKTOP = i2;
+   return i9 | 0;
+  }
+  i9 = _luaF_newLclosure(i1, i3) | 0;
+  HEAP32[i9 + 12 >> 2] = i6;
+  i8 = HEAP32[i5 >> 2] | 0;
+  HEAP32[i8 + -16 >> 2] = i9;
+  HEAP32[i8 + -8 >> 2] = 70;
+  STACKTOP = i2;
+  return i9 | 0;
+ }
+ if ((_memcmp(i4, i5, 4) | 0) != 0) {
+  _error(i3, 8888);
+ }
+ if ((_memcmp(i4, i5, 6) | 0) != 0) {
+  _error(i3, 8896);
+ }
+ if ((_memcmp(i4, i5, 12) | 0) == 0) {
+  _error(i3, 8872);
+ } else {
+  _error(i3, 8920);
+ }
+ return 0;
+}
+function _lua_compare(i2, i7, i5, i3) {
+ i2 = i2 | 0;
+ i7 = i7 | 0;
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i4 = 0, i6 = 0, i8 = 0;
+ i1 = STACKTOP;
+ i4 = HEAP32[i2 + 16 >> 2] | 0;
+ do {
+  if ((i7 | 0) <= 0) {
+   if (!((i7 | 0) < -1000999)) {
+    i6 = (HEAP32[i2 + 8 >> 2] | 0) + (i7 << 4) | 0;
+    break;
+   }
+   if ((i7 | 0) == -1001e3) {
+    i6 = (HEAP32[i2 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i7 = -1001e3 - i7 | 0;
+   i8 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i8 + 8 >> 2] | 0) != 22 ? (i6 = HEAP32[i8 >> 2] | 0, (i7 | 0) <= (HEAPU8[i6 + 6 | 0] | 0 | 0)) : 0) {
+    i6 = i6 + (i7 + -1 << 4) + 16 | 0;
+   } else {
+    i6 = 5192;
+   }
+  } else {
+   i6 = (HEAP32[i4 >> 2] | 0) + (i7 << 4) | 0;
+   i6 = i6 >>> 0 < (HEAP32[i2 + 8 >> 2] | 0) >>> 0 ? i6 : 5192;
+  }
+ } while (0);
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i4 = (HEAP32[i2 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i4 = (HEAP32[i2 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) == 22) {
+    i8 = 0;
+    STACKTOP = i1;
+    return i8 | 0;
+   }
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((i5 | 0) > (HEAPU8[i4 + 6 | 0] | 0 | 0)) {
+    i8 = 0;
+    STACKTOP = i1;
+    return i8 | 0;
+   } else {
+    i4 = i4 + (i5 + -1 << 4) + 16 | 0;
+    break;
+   }
+  } else {
+   i4 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i4 = i4 >>> 0 < (HEAP32[i2 + 8 >> 2] | 0) >>> 0 ? i4 : 5192;
+  }
+ } while (0);
+ if ((i6 | 0) == 5192 | (i4 | 0) == 5192) {
+  i8 = 0;
+  STACKTOP = i1;
+  return i8 | 0;
+ }
+ if ((i3 | 0) == 1) {
+  i8 = _luaV_lessthan(i2, i6, i4) | 0;
+  STACKTOP = i1;
+  return i8 | 0;
+ } else if ((i3 | 0) == 2) {
+  i8 = _luaV_lessequal(i2, i6, i4) | 0;
+  STACKTOP = i1;
+  return i8 | 0;
+ } else if ((i3 | 0) == 0) {
+  if ((HEAP32[i6 + 8 >> 2] | 0) == (HEAP32[i4 + 8 >> 2] | 0)) {
+   i2 = (_luaV_equalobj_(i2, i6, i4) | 0) != 0;
+  } else {
+   i2 = 0;
+  }
+  i8 = i2 & 1;
+  STACKTOP = i1;
+  return i8 | 0;
+ } else {
+  i8 = 0;
+  STACKTOP = i1;
+  return i8 | 0;
+ }
+ return 0;
+}
+function _lexerror(i7, i3, i8) {
+ i7 = i7 | 0;
+ i3 = i3 | 0;
+ i8 = i8 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i6 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i12 = STACKTOP;
+ STACKTOP = STACKTOP + 80 | 0;
+ i2 = i12;
+ i12 = i12 + 12 | 0;
+ _luaO_chunkid(i12, (HEAP32[i7 + 68 >> 2] | 0) + 16 | 0, 60);
+ i1 = i7 + 52 | 0;
+ i4 = HEAP32[i1 >> 2] | 0;
+ i13 = HEAP32[i7 + 4 >> 2] | 0;
+ HEAP32[i2 >> 2] = i12;
+ HEAP32[i2 + 4 >> 2] = i13;
+ HEAP32[i2 + 8 >> 2] = i3;
+ i4 = _luaO_pushfstring(i4, 12592, i2) | 0;
+ if ((i8 | 0) == 0) {
+  i13 = HEAP32[i1 >> 2] | 0;
+  _luaD_throw(i13, 3);
+ }
+ i3 = HEAP32[i1 >> 2] | 0;
+ do {
+  if (!((i8 + -287 | 0) >>> 0 < 3)) {
+   if ((i8 | 0) >= 257) {
+    i5 = HEAP32[12096 + (i8 + -257 << 2) >> 2] | 0;
+    if ((i8 | 0) >= 286) {
+     break;
+    }
+    HEAP32[i2 >> 2] = i5;
+    i5 = _luaO_pushfstring(i3, 12256, i2) | 0;
+    break;
+   }
+   if ((HEAP8[i8 + 10913 | 0] & 4) == 0) {
+    HEAP32[i2 >> 2] = i8;
+    i5 = _luaO_pushfstring(i3, 12240, i2) | 0;
+    break;
+   } else {
+    HEAP32[i2 >> 2] = i8;
+    i5 = _luaO_pushfstring(i3, 12232, i2) | 0;
+    break;
+   }
+  } else {
+   i11 = i7 + 60 | 0;
+   i12 = HEAP32[i11 >> 2] | 0;
+   i10 = i12 + 4 | 0;
+   i13 = HEAP32[i10 >> 2] | 0;
+   i8 = i12 + 8 | 0;
+   i9 = HEAP32[i8 >> 2] | 0;
+   do {
+    if ((i13 + 1 | 0) >>> 0 > i9 >>> 0) {
+     if (i9 >>> 0 > 2147483645) {
+      _lexerror(i7, 12368, 0);
+     }
+     i7 = i9 << 1;
+     if ((i7 | 0) == -2) {
+      _luaM_toobig(i3);
+     } else {
+      i6 = _luaM_realloc_(i3, HEAP32[i12 >> 2] | 0, i9, i7) | 0;
+      HEAP32[i12 >> 2] = i6;
+      HEAP32[i8 >> 2] = i7;
+      i5 = HEAP32[i10 >> 2] | 0;
+      break;
+     }
+    } else {
+     i5 = i13;
+     i6 = HEAP32[i12 >> 2] | 0;
+    }
+   } while (0);
+   HEAP32[i10 >> 2] = i5 + 1;
+   HEAP8[i6 + i5 | 0] = 0;
+   i5 = HEAP32[i1 >> 2] | 0;
+   HEAP32[i2 >> 2] = HEAP32[HEAP32[i11 >> 2] >> 2];
+   i5 = _luaO_pushfstring(i5, 12256, i2) | 0;
+  }
+ } while (0);
+ HEAP32[i2 >> 2] = i4;
+ HEAP32[i2 + 4 >> 2] = i5;
+ _luaO_pushfstring(i3, 12608, i2) | 0;
+ i13 = HEAP32[i1 >> 2] | 0;
+ _luaD_throw(i13, 3);
+}
+function _luaV_objlen(i2, i5, i1) {
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ var i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0;
+ i3 = STACKTOP;
+ i4 = i1 + 8 | 0;
+ i8 = HEAP32[i4 >> 2] & 15;
+ do {
+  if ((i8 | 0) == 5) {
+   i7 = HEAP32[i1 >> 2] | 0;
+   i8 = HEAP32[i7 + 8 >> 2] | 0;
+   if (((i8 | 0) != 0 ? (HEAP8[i8 + 6 | 0] & 16) == 0 : 0) ? (i6 = _luaT_gettm(i8, 4, HEAP32[(HEAP32[i2 + 12 >> 2] | 0) + 200 >> 2] | 0) | 0, (i6 | 0) != 0) : 0) {
+    i7 = i6;
+    break;
+   }
+   HEAPF64[i5 >> 3] = +(_luaH_getn(i7) | 0);
+   HEAP32[i5 + 8 >> 2] = 3;
+   STACKTOP = i3;
+   return;
+  } else if ((i8 | 0) != 4) {
+   i6 = _luaT_gettmbyobj(i2, i1, 4) | 0;
+   if ((HEAP32[i6 + 8 >> 2] | 0) == 0) {
+    _luaG_typeerror(i2, i1, 9024);
+   } else {
+    i7 = i6;
+   }
+  } else {
+   HEAPF64[i5 >> 3] = +((HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0) >>> 0);
+   HEAP32[i5 + 8 >> 2] = 3;
+   STACKTOP = i3;
+   return;
+  }
+ } while (0);
+ i6 = i2 + 28 | 0;
+ i8 = i5 - (HEAP32[i6 >> 2] | 0) | 0;
+ i5 = i2 + 8 | 0;
+ i11 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i5 >> 2] = i11 + 16;
+ i12 = i7;
+ i10 = HEAP32[i12 + 4 >> 2] | 0;
+ i9 = i11;
+ HEAP32[i9 >> 2] = HEAP32[i12 >> 2];
+ HEAP32[i9 + 4 >> 2] = i10;
+ HEAP32[i11 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+ i7 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i5 >> 2] = i7 + 16;
+ i11 = i1;
+ i9 = HEAP32[i11 + 4 >> 2] | 0;
+ i10 = i7;
+ HEAP32[i10 >> 2] = HEAP32[i11 >> 2];
+ HEAP32[i10 + 4 >> 2] = i9;
+ HEAP32[i7 + 8 >> 2] = HEAP32[i4 >> 2];
+ i7 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i5 >> 2] = i7 + 16;
+ i10 = i1;
+ i9 = HEAP32[i10 + 4 >> 2] | 0;
+ i1 = i7;
+ HEAP32[i1 >> 2] = HEAP32[i10 >> 2];
+ HEAP32[i1 + 4 >> 2] = i9;
+ HEAP32[i7 + 8 >> 2] = HEAP32[i4 >> 2];
+ _luaD_call(i2, (HEAP32[i5 >> 2] | 0) + -48 | 0, 1, HEAP8[(HEAP32[i2 + 16 >> 2] | 0) + 18 | 0] & 1);
+ i7 = HEAP32[i6 >> 2] | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ i2 = i6 + -16 | 0;
+ HEAP32[i5 >> 2] = i2;
+ i4 = HEAP32[i2 + 4 >> 2] | 0;
+ i5 = i7 + i8 | 0;
+ HEAP32[i5 >> 2] = HEAP32[i2 >> 2];
+ HEAP32[i5 + 4 >> 2] = i4;
+ HEAP32[i7 + (i8 + 8) >> 2] = HEAP32[i6 + -8 >> 2];
+ STACKTOP = i3;
+ return;
+}
+function _get_equalTM(i6, i5, i4) {
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i7 = 0;
+ i1 = STACKTOP;
+ L1 : do {
+  if (((i5 | 0) != 0 ? (HEAP8[i5 + 6 | 0] & 32) == 0 : 0) ? (i7 = i6 + 12 | 0, i2 = _luaT_gettm(i5, 5, HEAP32[(HEAP32[i7 >> 2] | 0) + 204 >> 2] | 0) | 0, (i2 | 0) != 0) : 0) {
+   if ((i5 | 0) != (i4 | 0)) {
+    if (((i4 | 0) != 0 ? (HEAP8[i4 + 6 | 0] & 32) == 0 : 0) ? (i3 = _luaT_gettm(i4, 5, HEAP32[(HEAP32[i7 >> 2] | 0) + 204 >> 2] | 0) | 0, (i3 | 0) != 0) : 0) {
+     i4 = HEAP32[i2 + 8 >> 2] | 0;
+     L9 : do {
+      if ((i4 | 0) == (HEAP32[i3 + 8 >> 2] | 0)) {
+       switch (i4 & 63 | 0) {
+       case 3:
+        {
+         i3 = +HEAPF64[i2 >> 3] == +HEAPF64[i3 >> 3] | 0;
+         break;
+        }
+       case 22:
+        {
+         i3 = (HEAP32[i2 >> 2] | 0) == (HEAP32[i3 >> 2] | 0) | 0;
+         break;
+        }
+       case 5:
+        {
+         if ((HEAP32[i2 >> 2] | 0) == (HEAP32[i3 >> 2] | 0)) {
+          break L1;
+         } else {
+          break L9;
+         }
+        }
+       case 1:
+        {
+         i3 = (HEAP32[i2 >> 2] | 0) == (HEAP32[i3 >> 2] | 0) | 0;
+         break;
+        }
+       case 4:
+        {
+         i3 = (HEAP32[i2 >> 2] | 0) == (HEAP32[i3 >> 2] | 0) | 0;
+         break;
+        }
+       case 0:
+        {
+         break L1;
+        }
+       case 7:
+        {
+         if ((HEAP32[i2 >> 2] | 0) == (HEAP32[i3 >> 2] | 0)) {
+          break L1;
+         } else {
+          break L9;
+         }
+        }
+       case 2:
+        {
+         i3 = (HEAP32[i2 >> 2] | 0) == (HEAP32[i3 >> 2] | 0) | 0;
+         break;
+        }
+       case 20:
+        {
+         i3 = _luaS_eqlngstr(HEAP32[i2 >> 2] | 0, HEAP32[i3 >> 2] | 0) | 0;
+         break;
+        }
+       default:
+        {
+         i3 = (HEAP32[i2 >> 2] | 0) == (HEAP32[i3 >> 2] | 0) | 0;
+        }
+       }
+       if ((i3 | 0) != 0) {
+        break L1;
+       }
+      }
+     } while (0);
+     i2 = 0;
+    } else {
+     i2 = 0;
+    }
+   }
+  } else {
+   i2 = 0;
+  }
+ } while (0);
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _luaS_newlstr(i2, i4, i3) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0;
+ i1 = STACKTOP;
+ if (!(i3 >>> 0 < 41)) {
+  if ((i3 + 1 | 0) >>> 0 > 4294967277) {
+   _luaM_toobig(i2);
+  }
+  i10 = HEAP32[(HEAP32[i2 + 12 >> 2] | 0) + 56 >> 2] | 0;
+  i11 = _luaC_newobj(i2, 20, i3 + 17 | 0, 0, 0) | 0;
+  HEAP32[i11 + 12 >> 2] = i3;
+  HEAP32[i11 + 8 >> 2] = i10;
+  HEAP8[i11 + 6 | 0] = 0;
+  i10 = i11 + 16 | 0;
+  _memcpy(i10 | 0, i4 | 0, i3 | 0) | 0;
+  HEAP8[i10 + i3 | 0] = 0;
+  STACKTOP = i1;
+  return i11 | 0;
+ }
+ i5 = HEAP32[i2 + 12 >> 2] | 0;
+ i6 = HEAP32[i5 + 56 >> 2] ^ i3;
+ i7 = (i3 >>> 5) + 1 | 0;
+ if (!(i7 >>> 0 > i3 >>> 0)) {
+  i8 = i3;
+  do {
+   i6 = (i6 << 5) + (i6 >>> 2) + (HEAPU8[i4 + (i8 + -1) | 0] | 0) ^ i6;
+   i8 = i8 - i7 | 0;
+  } while (!(i8 >>> 0 < i7 >>> 0));
+ }
+ i10 = i5 + 32 | 0;
+ i9 = HEAP32[i10 >> 2] | 0;
+ i7 = i5 + 24 | 0;
+ i8 = HEAP32[i7 >> 2] | 0;
+ i11 = HEAP32[i8 + ((i9 + -1 & i6) << 2) >> 2] | 0;
+ L12 : do {
+  if ((i11 | 0) != 0) {
+   while (1) {
+    if (((i6 | 0) == (HEAP32[i11 + 8 >> 2] | 0) ? (HEAP32[i11 + 12 >> 2] | 0) == (i3 | 0) : 0) ? (_memcmp(i4, i11 + 16 | 0, i3) | 0) == 0 : 0) {
+     break;
+    }
+    i11 = HEAP32[i11 >> 2] | 0;
+    if ((i11 | 0) == 0) {
+     break L12;
+    }
+   }
+   i2 = i11 + 5 | 0;
+   i3 = (HEAPU8[i2] | 0) ^ 3;
+   if ((((HEAPU8[i5 + 60 | 0] | 0) ^ 3) & i3 | 0) != 0) {
+    STACKTOP = i1;
+    return i11 | 0;
+   }
+   HEAP8[i2] = i3;
+   STACKTOP = i1;
+   return i11 | 0;
+  }
+ } while (0);
+ i5 = i5 + 28 | 0;
+ if ((HEAP32[i5 >> 2] | 0) >>> 0 >= i9 >>> 0 & (i9 | 0) < 1073741823) {
+  _luaS_resize(i2, i9 << 1);
+  i9 = HEAP32[i10 >> 2] | 0;
+  i8 = HEAP32[i7 >> 2] | 0;
+ }
+ i11 = _luaC_newobj(i2, 4, i3 + 17 | 0, i8 + ((i9 + -1 & i6) << 2) | 0, 0) | 0;
+ HEAP32[i11 + 12 >> 2] = i3;
+ HEAP32[i11 + 8 >> 2] = i6;
+ HEAP8[i11 + 6 | 0] = 0;
+ i10 = i11 + 16 | 0;
+ _memcpy(i10 | 0, i4 | 0, i3 | 0) | 0;
+ HEAP8[i10 + i3 | 0] = 0;
+ HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + 1;
+ STACKTOP = i1;
+ return i11 | 0;
+}
+function _lua_pcallk(i3, i7, i2, i9, i6, i5) {
+ i3 = i3 | 0;
+ i7 = i7 | 0;
+ i2 = i2 | 0;
+ i9 = i9 | 0;
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i4 = 0, i8 = 0, i10 = 0, i11 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i1;
+ if ((i9 | 0) == 0) {
+  i9 = 0;
+ } else {
+  i10 = HEAP32[i3 + 16 >> 2] | 0;
+  do {
+   if ((i9 | 0) <= 0) {
+    if (!((i9 | 0) < -1000999)) {
+     i8 = (HEAP32[i3 + 8 >> 2] | 0) + (i9 << 4) | 0;
+     break;
+    }
+    if ((i9 | 0) == -1001e3) {
+     i8 = (HEAP32[i3 + 12 >> 2] | 0) + 40 | 0;
+     break;
+    }
+    i9 = -1001e3 - i9 | 0;
+    i10 = HEAP32[i10 >> 2] | 0;
+    if ((HEAP32[i10 + 8 >> 2] | 0) != 22 ? (i8 = HEAP32[i10 >> 2] | 0, (i9 | 0) <= (HEAPU8[i8 + 6 | 0] | 0)) : 0) {
+     i8 = i8 + (i9 + -1 << 4) + 16 | 0;
+    } else {
+     i8 = 5192;
+    }
+   } else {
+    i8 = (HEAP32[i10 >> 2] | 0) + (i9 << 4) | 0;
+    i8 = i8 >>> 0 < (HEAP32[i3 + 8 >> 2] | 0) >>> 0 ? i8 : 5192;
+   }
+  } while (0);
+  i9 = i8 - (HEAP32[i3 + 28 >> 2] | 0) | 0;
+ }
+ i8 = i3 + 8 | 0;
+ i7 = (HEAP32[i8 >> 2] | 0) + (~i7 << 4) | 0;
+ HEAP32[i4 >> 2] = i7;
+ if ((i5 | 0) != 0 ? (HEAP16[i3 + 36 >> 1] | 0) == 0 : 0) {
+  i11 = HEAP32[i3 + 16 >> 2] | 0;
+  HEAP32[i11 + 28 >> 2] = i5;
+  HEAP32[i11 + 24 >> 2] = i6;
+  HEAP32[i11 + 20 >> 2] = (HEAP32[i4 >> 2] | 0) - (HEAP32[i3 + 28 >> 2] | 0);
+  HEAP8[i11 + 36 | 0] = HEAP8[i3 + 41 | 0] | 0;
+  i10 = i3 + 68 | 0;
+  i7 = i11 + 32 | 0;
+  HEAP32[i7 >> 2] = HEAP32[i10 >> 2];
+  HEAP32[i10 >> 2] = i9;
+  i9 = i11 + 18 | 0;
+  HEAP8[i9] = HEAPU8[i9] | 16;
+  _luaD_call(i3, HEAP32[i4 >> 2] | 0, i2, 1);
+  HEAP8[i9] = HEAP8[i9] & 239;
+  HEAP32[i10 >> 2] = HEAP32[i7 >> 2];
+  i4 = 0;
+ } else {
+  HEAP32[i4 + 4 >> 2] = i2;
+  i4 = _luaD_pcall(i3, 3, i4, i7 - (HEAP32[i3 + 28 >> 2] | 0) | 0, i9) | 0;
+ }
+ if (!((i2 | 0) == -1)) {
+  STACKTOP = i1;
+  return i4 | 0;
+ }
+ i2 = (HEAP32[i3 + 16 >> 2] | 0) + 4 | 0;
+ i3 = HEAP32[i8 >> 2] | 0;
+ if (!((HEAP32[i2 >> 2] | 0) >>> 0 < i3 >>> 0)) {
+  STACKTOP = i1;
+  return i4 | 0;
+ }
+ HEAP32[i2 >> 2] = i3;
+ STACKTOP = i1;
+ return i4 | 0;
+}
+function _lua_getupvalue(i1, i6, i3) {
+ i1 = i1 | 0;
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ i5 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i6 | 0) <= 0) {
+   if (!((i6 | 0) < -1000999)) {
+    i4 = (HEAP32[i1 + 8 >> 2] | 0) + (i6 << 4) | 0;
+    break;
+   }
+   if ((i6 | 0) == -1001e3) {
+    i4 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i6 = -1001e3 - i6 | 0;
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((HEAP32[i5 + 8 >> 2] | 0) != 22 ? (i4 = HEAP32[i5 >> 2] | 0, (i6 | 0) <= (HEAPU8[i4 + 6 | 0] | 0 | 0)) : 0) {
+    i4 = i4 + (i6 + -1 << 4) + 16 | 0;
+   } else {
+    i4 = 5192;
+   }
+  } else {
+   i4 = (HEAP32[i5 >> 2] | 0) + (i6 << 4) | 0;
+   i4 = i4 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i4 : 5192;
+  }
+ } while (0);
+ i5 = HEAP32[i4 + 8 >> 2] & 63;
+ do {
+  if ((i5 | 0) == 38) {
+   i5 = HEAP32[i4 >> 2] | 0;
+   if ((i3 | 0) <= 0) {
+    i6 = 0;
+    STACKTOP = i2;
+    return i6 | 0;
+   }
+   if ((HEAPU8[i5 + 6 | 0] | 0 | 0) < (i3 | 0)) {
+    i6 = 0;
+    STACKTOP = i2;
+    return i6 | 0;
+   } else {
+    i4 = 936;
+    i3 = i5 + (i3 + -1 << 4) + 16 | 0;
+    break;
+   }
+  } else if ((i5 | 0) == 6) {
+   i5 = HEAP32[i4 >> 2] | 0;
+   i4 = HEAP32[i5 + 12 >> 2] | 0;
+   if ((i3 | 0) <= 0) {
+    i6 = 0;
+    STACKTOP = i2;
+    return i6 | 0;
+   }
+   if ((HEAP32[i4 + 40 >> 2] | 0) < (i3 | 0)) {
+    i6 = 0;
+    STACKTOP = i2;
+    return i6 | 0;
+   }
+   i6 = i3 + -1 | 0;
+   i3 = HEAP32[(HEAP32[i5 + 16 + (i6 << 2) >> 2] | 0) + 8 >> 2] | 0;
+   i4 = HEAP32[(HEAP32[i4 + 28 >> 2] | 0) + (i6 << 3) >> 2] | 0;
+   if ((i4 | 0) == 0) {
+    i4 = 936;
+   } else {
+    i4 = i4 + 16 | 0;
+   }
+  } else {
+   i6 = 0;
+   STACKTOP = i2;
+   return i6 | 0;
+  }
+ } while (0);
+ i6 = i1 + 8 | 0;
+ i5 = HEAP32[i6 >> 2] | 0;
+ i8 = i3;
+ i7 = HEAP32[i8 + 4 >> 2] | 0;
+ i1 = i5;
+ HEAP32[i1 >> 2] = HEAP32[i8 >> 2];
+ HEAP32[i1 + 4 >> 2] = i7;
+ HEAP32[i5 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+ HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + 16;
+ i6 = i4;
+ STACKTOP = i2;
+ return i6 | 0;
+}
+function _lua_copy(i1, i8, i4) {
+ i1 = i1 | 0;
+ i8 = i8 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i9 = 0;
+ i2 = STACKTOP;
+ i3 = i1 + 16 | 0;
+ i6 = HEAP32[i3 >> 2] | 0;
+ do {
+  if ((i8 | 0) <= 0) {
+   if (!((i8 | 0) < -1000999)) {
+    i7 = (HEAP32[i1 + 8 >> 2] | 0) + (i8 << 4) | 0;
+    break;
+   }
+   if ((i8 | 0) == -1001e3) {
+    i7 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i8 = -1001e3 - i8 | 0;
+   i9 = HEAP32[i6 >> 2] | 0;
+   if ((HEAP32[i9 + 8 >> 2] | 0) != 22 ? (i7 = HEAP32[i9 >> 2] | 0, (i8 | 0) <= (HEAPU8[i7 + 6 | 0] | 0 | 0)) : 0) {
+    i7 = i7 + (i8 + -1 << 4) + 16 | 0;
+   } else {
+    i7 = 5192;
+   }
+  } else {
+   i7 = (HEAP32[i6 >> 2] | 0) + (i8 << 4) | 0;
+   i7 = i7 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i7 : 5192;
+  }
+ } while (0);
+ do {
+  if ((i4 | 0) <= 0) {
+   if (!((i4 | 0) < -1000999)) {
+    i5 = (HEAP32[i1 + 8 >> 2] | 0) + (i4 << 4) | 0;
+    break;
+   }
+   if ((i4 | 0) == -1001e3) {
+    i5 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i8 = -1001e3 - i4 | 0;
+   i6 = HEAP32[i6 >> 2] | 0;
+   if ((HEAP32[i6 + 8 >> 2] | 0) != 22 ? (i5 = HEAP32[i6 >> 2] | 0, (i8 | 0) <= (HEAPU8[i5 + 6 | 0] | 0 | 0)) : 0) {
+    i5 = i5 + (i8 + -1 << 4) + 16 | 0;
+   } else {
+    i5 = 5192;
+   }
+  } else {
+   i5 = (HEAP32[i6 >> 2] | 0) + (i4 << 4) | 0;
+   i5 = i5 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i5 : 5192;
+  }
+ } while (0);
+ i8 = i7;
+ i9 = HEAP32[i8 + 4 >> 2] | 0;
+ i6 = i5;
+ HEAP32[i6 >> 2] = HEAP32[i8 >> 2];
+ HEAP32[i6 + 4 >> 2] = i9;
+ i6 = i7 + 8 | 0;
+ HEAP32[i5 + 8 >> 2] = HEAP32[i6 >> 2];
+ if (!((i4 | 0) < -1001e3)) {
+  STACKTOP = i2;
+  return;
+ }
+ if ((HEAP32[i6 >> 2] & 64 | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ i4 = HEAP32[i7 >> 2] | 0;
+ if ((HEAP8[i4 + 5 | 0] & 3) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ i3 = HEAP32[HEAP32[HEAP32[i3 >> 2] >> 2] >> 2] | 0;
+ if ((HEAP8[i3 + 5 | 0] & 4) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ _luaC_barrier_(i1, i3, i4);
+ STACKTOP = i2;
+ return;
+}
+function _lua_tolstring(i4, i5, i1) {
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i2 = STACKTOP;
+ i7 = i4 + 16 | 0;
+ i10 = HEAP32[i7 >> 2] | 0;
+ i6 = (i5 | 0) > 0;
+ do {
+  if (!i6) {
+   if (!((i5 | 0) < -1000999)) {
+    i8 = (HEAP32[i4 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i8 = (HEAP32[i4 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i9 = -1001e3 - i5 | 0;
+   i10 = HEAP32[i10 >> 2] | 0;
+   if ((HEAP32[i10 + 8 >> 2] | 0) != 22 ? (i8 = HEAP32[i10 >> 2] | 0, (i9 | 0) <= (HEAPU8[i8 + 6 | 0] | 0 | 0)) : 0) {
+    i8 = i8 + (i9 + -1 << 4) + 16 | 0;
+   } else {
+    i8 = 5192;
+   }
+  } else {
+   i8 = (HEAP32[i10 >> 2] | 0) + (i5 << 4) | 0;
+   i8 = i8 >>> 0 < (HEAP32[i4 + 8 >> 2] | 0) >>> 0 ? i8 : 5192;
+  }
+ } while (0);
+ do {
+  if ((HEAP32[i8 + 8 >> 2] & 15 | 0) != 4) {
+   if ((_luaV_tostring(i4, i8) | 0) == 0) {
+    if ((i1 | 0) == 0) {
+     i10 = 0;
+     STACKTOP = i2;
+     return i10 | 0;
+    }
+    HEAP32[i1 >> 2] = 0;
+    i10 = 0;
+    STACKTOP = i2;
+    return i10 | 0;
+   }
+   i8 = i4 + 12 | 0;
+   if ((HEAP32[(HEAP32[i8 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+    _luaC_step(i4);
+   }
+   i7 = HEAP32[i7 >> 2] | 0;
+   if (i6) {
+    i3 = (HEAP32[i7 >> 2] | 0) + (i5 << 4) | 0;
+    i8 = i3 >>> 0 < (HEAP32[i4 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+    break;
+   }
+   if (!((i5 | 0) < -1000999)) {
+    i8 = (HEAP32[i4 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i8 = (HEAP32[i8 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i4 = -1001e3 - i5 | 0;
+   i5 = HEAP32[i7 >> 2] | 0;
+   if ((HEAP32[i5 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i5 >> 2] | 0, (i4 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i8 = i3 + (i4 + -1 << 4) + 16 | 0;
+   } else {
+    i8 = 5192;
+   }
+  }
+ } while (0);
+ i3 = HEAP32[i8 >> 2] | 0;
+ if ((i1 | 0) != 0) {
+  HEAP32[i1 >> 2] = HEAP32[i3 + 12 >> 2];
+ }
+ i10 = i3 + 16 | 0;
+ STACKTOP = i2;
+ return i10 | 0;
+}
+function _luaD_pcall(i3, i6, i5, i13, i14) {
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ i13 = i13 | 0;
+ i14 = i14 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0;
+ i1 = STACKTOP;
+ i10 = i3 + 16 | 0;
+ i11 = HEAP32[i10 >> 2] | 0;
+ i12 = i3 + 41 | 0;
+ i7 = HEAP8[i12] | 0;
+ i9 = i3 + 36 | 0;
+ i8 = HEAP16[i9 >> 1] | 0;
+ i4 = i3 + 68 | 0;
+ i2 = HEAP32[i4 >> 2] | 0;
+ HEAP32[i4 >> 2] = i14;
+ i5 = _luaD_rawrunprotected(i3, i6, i5) | 0;
+ if ((i5 | 0) == 0) {
+  HEAP32[i4 >> 2] = i2;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ i6 = i3 + 28 | 0;
+ i14 = HEAP32[i6 >> 2] | 0;
+ i15 = i14 + i13 | 0;
+ _luaF_close(i3, i15);
+ if ((i5 | 0) == 6) {
+  i16 = _luaS_newlstr(i3, 2424, 23) | 0;
+  HEAP32[i15 >> 2] = i16;
+  HEAP32[i14 + (i13 + 8) >> 2] = HEAPU8[i16 + 4 | 0] | 0 | 64;
+ } else if ((i5 | 0) == 4) {
+  i16 = HEAP32[(HEAP32[i3 + 12 >> 2] | 0) + 180 >> 2] | 0;
+  HEAP32[i15 >> 2] = i16;
+  HEAP32[i14 + (i13 + 8) >> 2] = HEAPU8[i16 + 4 | 0] | 0 | 64;
+ } else {
+  i16 = HEAP32[i3 + 8 >> 2] | 0;
+  i18 = i16 + -16 | 0;
+  i17 = HEAP32[i18 + 4 >> 2] | 0;
+  HEAP32[i15 >> 2] = HEAP32[i18 >> 2];
+  HEAP32[i15 + 4 >> 2] = i17;
+  HEAP32[i14 + (i13 + 8) >> 2] = HEAP32[i16 + -8 >> 2];
+ }
+ i13 = i14 + (i13 + 16) | 0;
+ HEAP32[i3 + 8 >> 2] = i13;
+ HEAP32[i10 >> 2] = i11;
+ HEAP8[i12] = i7;
+ HEAP16[i9 >> 1] = i8;
+ if ((i11 | 0) != 0) {
+  do {
+   i7 = HEAP32[i11 + 4 >> 2] | 0;
+   i13 = i13 >>> 0 < i7 >>> 0 ? i7 : i13;
+   i11 = HEAP32[i11 + 8 >> 2] | 0;
+  } while ((i11 | 0) != 0);
+ }
+ i6 = i13 - (HEAP32[i6 >> 2] | 0) | 0;
+ i7 = (i6 >> 4) + 1 | 0;
+ i7 = ((i7 | 0) / 8 | 0) + 10 + i7 | 0;
+ i7 = (i7 | 0) > 1e6 ? 1e6 : i7;
+ if ((i6 | 0) > 15999984) {
+  HEAP32[i4 >> 2] = i2;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ if ((i7 | 0) >= (HEAP32[i3 + 32 >> 2] | 0)) {
+  HEAP32[i4 >> 2] = i2;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ _luaD_reallocstack(i3, i7);
+ HEAP32[i4 >> 2] = i2;
+ STACKTOP = i1;
+ return i5 | 0;
+}
+function _luaH_resize(i1, i4, i6, i9) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ i9 = i9 | 0;
+ var i2 = 0, i3 = 0, i5 = 0, i7 = 0, i8 = 0, i10 = 0, i11 = 0;
+ i3 = STACKTOP;
+ i8 = i4 + 28 | 0;
+ i5 = HEAP32[i8 >> 2] | 0;
+ i7 = HEAPU8[i4 + 7 | 0] | 0;
+ i2 = HEAP32[i4 + 16 >> 2] | 0;
+ if ((i5 | 0) < (i6 | 0)) {
+  if ((i6 + 1 | 0) >>> 0 > 268435455) {
+   _luaM_toobig(i1);
+  }
+  i11 = i4 + 12 | 0;
+  i10 = _luaM_realloc_(i1, HEAP32[i11 >> 2] | 0, i5 << 4, i6 << 4) | 0;
+  HEAP32[i11 >> 2] = i10;
+  i11 = HEAP32[i8 >> 2] | 0;
+  if ((i11 | 0) < (i6 | 0)) {
+   do {
+    HEAP32[i10 + (i11 << 4) + 8 >> 2] = 0;
+    i11 = i11 + 1 | 0;
+   } while ((i11 | 0) != (i6 | 0));
+  }
+  HEAP32[i8 >> 2] = i6;
+ }
+ _setnodevector(i1, i4, i9);
+ do {
+  if ((i5 | 0) > (i6 | 0)) {
+   HEAP32[i8 >> 2] = i6;
+   i8 = i4 + 12 | 0;
+   i9 = i6;
+   do {
+    i10 = HEAP32[i8 >> 2] | 0;
+    if ((HEAP32[i10 + (i9 << 4) + 8 >> 2] | 0) == 0) {
+     i9 = i9 + 1 | 0;
+    } else {
+     i11 = i9 + 1 | 0;
+     _luaH_setint(i1, i4, i11, i10 + (i9 << 4) | 0);
+     i9 = i11;
+    }
+   } while ((i9 | 0) != (i5 | 0));
+   if ((i6 + 1 | 0) >>> 0 > 268435455) {
+    _luaM_toobig(i1);
+   } else {
+    i11 = i4 + 12 | 0;
+    HEAP32[i11 >> 2] = _luaM_realloc_(i1, HEAP32[i11 >> 2] | 0, i5 << 4, i6 << 4) | 0;
+    break;
+   }
+  }
+ } while (0);
+ i5 = 1 << i7;
+ if ((i5 | 0) > 0) {
+  i6 = i5;
+  do {
+   i6 = i6 + -1 | 0;
+   i7 = i2 + (i6 << 5) + 8 | 0;
+   if ((HEAP32[i7 >> 2] | 0) != 0) {
+    i8 = i2 + (i6 << 5) + 16 | 0;
+    i9 = _luaH_get(i4, i8) | 0;
+    if ((i9 | 0) == 5192) {
+     i9 = _luaH_newkey(i1, i4, i8) | 0;
+    }
+    i8 = i2 + (i6 << 5) | 0;
+    i10 = HEAP32[i8 + 4 >> 2] | 0;
+    i11 = i9;
+    HEAP32[i11 >> 2] = HEAP32[i8 >> 2];
+    HEAP32[i11 + 4 >> 2] = i10;
+    HEAP32[i9 + 8 >> 2] = HEAP32[i7 >> 2];
+   }
+  } while ((i6 | 0) > 0);
+ }
+ if ((i2 | 0) == 8016) {
+  STACKTOP = i3;
+  return;
+ }
+ _luaM_realloc_(i1, i2, i5 << 5, 0) | 0;
+ STACKTOP = i3;
+ return;
+}
+function _codearith(i4, i3, i2, i6, i5) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, d13 = 0.0;
+ i7 = STACKTOP;
+ if (((((((HEAP32[i2 >> 2] | 0) == 5 ? (HEAP32[i2 + 16 >> 2] | 0) == -1 : 0) ? (HEAP32[i2 + 20 >> 2] | 0) == -1 : 0) ? (HEAP32[i6 >> 2] | 0) == 5 : 0) ? (HEAP32[i6 + 16 >> 2] | 0) == -1 : 0) ? (HEAP32[i6 + 20 >> 2] | 0) == -1 : 0) ? (d13 = +HEAPF64[i6 + 8 >> 3], !((i3 & -2 | 0) == 16 & d13 == 0.0)) : 0) {
+  i12 = i2 + 8 | 0;
+  HEAPF64[i12 >> 3] = +_luaO_arith(i3 + -13 | 0, +HEAPF64[i12 >> 3], d13);
+  STACKTOP = i7;
+  return;
+ }
+ if ((i3 | 0) == 19 | (i3 | 0) == 21) {
+  i11 = 0;
+ } else {
+  i11 = _luaK_exp2RK(i4, i6) | 0;
+ }
+ i12 = _luaK_exp2RK(i4, i2) | 0;
+ if ((i12 | 0) > (i11 | 0)) {
+  if (((HEAP32[i2 >> 2] | 0) == 6 ? (i8 = HEAP32[i2 + 8 >> 2] | 0, (i8 & 256 | 0) == 0) : 0) ? (HEAPU8[i4 + 46 | 0] | 0 | 0) <= (i8 | 0) : 0) {
+   i10 = i4 + 48 | 0;
+   HEAP8[i10] = (HEAP8[i10] | 0) + -1 << 24 >> 24;
+  }
+  if (((HEAP32[i6 >> 2] | 0) == 6 ? (i1 = HEAP32[i6 + 8 >> 2] | 0, (i1 & 256 | 0) == 0) : 0) ? (HEAPU8[i4 + 46 | 0] | 0 | 0) <= (i1 | 0) : 0) {
+   i10 = i4 + 48 | 0;
+   HEAP8[i10] = (HEAP8[i10] | 0) + -1 << 24 >> 24;
+  }
+ } else {
+  if (((HEAP32[i6 >> 2] | 0) == 6 ? (i10 = HEAP32[i6 + 8 >> 2] | 0, (i10 & 256 | 0) == 0) : 0) ? (HEAPU8[i4 + 46 | 0] | 0 | 0) <= (i10 | 0) : 0) {
+   i10 = i4 + 48 | 0;
+   HEAP8[i10] = (HEAP8[i10] | 0) + -1 << 24 >> 24;
+  }
+  if (((HEAP32[i2 >> 2] | 0) == 6 ? (i9 = HEAP32[i2 + 8 >> 2] | 0, (i9 & 256 | 0) == 0) : 0) ? (HEAPU8[i4 + 46 | 0] | 0 | 0) <= (i9 | 0) : 0) {
+   i10 = i4 + 48 | 0;
+   HEAP8[i10] = (HEAP8[i10] | 0) + -1 << 24 >> 24;
+  }
+ }
+ HEAP32[i2 + 8 >> 2] = _luaK_code(i4, i11 << 14 | i3 | i12 << 23) | 0;
+ HEAP32[i2 >> 2] = 11;
+ HEAP32[(HEAP32[(HEAP32[i4 >> 2] | 0) + 20 >> 2] | 0) + ((HEAP32[i4 + 20 >> 2] | 0) + -1 << 2) >> 2] = i5;
+ STACKTOP = i7;
+ return;
+}
+function _GCTM(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i2 = i4 + 16 | 0;
+ i5 = i4;
+ i6 = HEAP32[i1 + 12 >> 2] | 0;
+ i9 = i6 + 104 | 0;
+ i8 = HEAP32[i9 >> 2] | 0;
+ HEAP32[i9 >> 2] = HEAP32[i8 >> 2];
+ i9 = i6 + 68 | 0;
+ HEAP32[i8 >> 2] = HEAP32[i9 >> 2];
+ HEAP32[i9 >> 2] = i8;
+ i9 = i8 + 5 | 0;
+ i7 = HEAPU8[i9] | 0;
+ HEAP8[i9] = i7 & 239;
+ if ((HEAPU8[i6 + 61 | 0] | 0) >= 2) {
+  HEAP8[i9] = HEAP8[i6 + 60 | 0] & 3 | i7 & 168;
+ }
+ HEAP32[i5 >> 2] = i8;
+ i7 = i5 + 8 | 0;
+ HEAP32[i7 >> 2] = HEAPU8[i8 + 4 | 0] | 0 | 64;
+ i8 = _luaT_gettmbyobj(i1, i5, 2) | 0;
+ if ((i8 | 0) == 0) {
+  STACKTOP = i4;
+  return;
+ }
+ i9 = i8 + 8 | 0;
+ if ((HEAP32[i9 >> 2] & 15 | 0) != 6) {
+  STACKTOP = i4;
+  return;
+ }
+ i12 = i1 + 41 | 0;
+ i13 = HEAP8[i12] | 0;
+ i10 = i6 + 63 | 0;
+ i11 = HEAP8[i10] | 0;
+ HEAP8[i12] = 0;
+ HEAP8[i10] = 0;
+ i6 = i1 + 8 | 0;
+ i14 = HEAP32[i6 >> 2] | 0;
+ i16 = i8;
+ i15 = HEAP32[i16 + 4 >> 2] | 0;
+ i8 = i14;
+ HEAP32[i8 >> 2] = HEAP32[i16 >> 2];
+ HEAP32[i8 + 4 >> 2] = i15;
+ HEAP32[i14 + 8 >> 2] = HEAP32[i9 >> 2];
+ i9 = HEAP32[i6 >> 2] | 0;
+ i14 = i5;
+ i8 = HEAP32[i14 + 4 >> 2] | 0;
+ i5 = i9 + 16 | 0;
+ HEAP32[i5 >> 2] = HEAP32[i14 >> 2];
+ HEAP32[i5 + 4 >> 2] = i8;
+ HEAP32[i9 + 24 >> 2] = HEAP32[i7 >> 2];
+ i5 = HEAP32[i6 >> 2] | 0;
+ HEAP32[i6 >> 2] = i5 + 32;
+ i5 = _luaD_pcall(i1, 7, 0, i5 - (HEAP32[i1 + 28 >> 2] | 0) | 0, 0) | 0;
+ HEAP8[i12] = i13;
+ HEAP8[i10] = i11;
+ if ((i5 | 0) == 0 | (i3 | 0) == 0) {
+  STACKTOP = i4;
+  return;
+ }
+ if ((i5 | 0) != 2) {
+  i16 = i5;
+  _luaD_throw(i1, i16);
+ }
+ i3 = HEAP32[i6 >> 2] | 0;
+ if ((HEAP32[i3 + -8 >> 2] & 15 | 0) == 4) {
+  i3 = (HEAP32[i3 + -16 >> 2] | 0) + 16 | 0;
+ } else {
+  i3 = 2528;
+ }
+ HEAP32[i2 >> 2] = i3;
+ _luaO_pushfstring(i1, 2544, i2) | 0;
+ i16 = 5;
+ _luaD_throw(i1, i16);
+}
+function _lua_gc(i3, i5, i4) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0;
+ i1 = STACKTOP;
+ i2 = HEAP32[i3 + 12 >> 2] | 0;
+ L1 : do {
+  switch (i5 | 0) {
+  case 8:
+   {
+    i5 = i2 + 160 | 0;
+    i2 = HEAP32[i5 >> 2] | 0;
+    HEAP32[i5 >> 2] = i4;
+    break;
+   }
+  case 11:
+   {
+    _luaC_changemode(i3, 0);
+    i2 = 0;
+    break;
+   }
+  case 2:
+   {
+    _luaC_fullgc(i3, 0);
+    i2 = 0;
+    break;
+   }
+  case 5:
+   {
+    if ((HEAP8[i2 + 62 | 0] | 0) == 2) {
+     i2 = (HEAP32[i2 + 20 >> 2] | 0) == 0 | 0;
+     _luaC_forcestep(i3);
+     break L1;
+    }
+    i4 = (i4 << 10) + -1600 | 0;
+    if ((HEAP8[i2 + 63 | 0] | 0) == 0) {
+     i5 = i4;
+     _luaE_setdebt(i2, i5);
+     _luaC_forcestep(i3);
+     i5 = i2 + 61 | 0;
+     i5 = HEAP8[i5] | 0;
+     i5 = i5 << 24 >> 24 == 5;
+     i5 = i5 & 1;
+     STACKTOP = i1;
+     return i5 | 0;
+    }
+    i5 = (HEAP32[i2 + 12 >> 2] | 0) + i4 | 0;
+    _luaE_setdebt(i2, i5);
+    _luaC_forcestep(i3);
+    i5 = i2 + 61 | 0;
+    i5 = HEAP8[i5] | 0;
+    i5 = i5 << 24 >> 24 == 5;
+    i5 = i5 & 1;
+    STACKTOP = i1;
+    return i5 | 0;
+   }
+  case 4:
+   {
+    i2 = (HEAP32[i2 + 12 >> 2] | 0) + (HEAP32[i2 + 8 >> 2] | 0) & 1023;
+    break;
+   }
+  case 1:
+   {
+    _luaE_setdebt(i2, 0);
+    HEAP8[i2 + 63 | 0] = 1;
+    i2 = 0;
+    break;
+   }
+  case 3:
+   {
+    i2 = ((HEAP32[i2 + 12 >> 2] | 0) + (HEAP32[i2 + 8 >> 2] | 0) | 0) >>> 10;
+    break;
+   }
+  case 7:
+   {
+    i5 = i2 + 164 | 0;
+    i2 = HEAP32[i5 >> 2] | 0;
+    HEAP32[i5 >> 2] = i4;
+    break;
+   }
+  case 0:
+   {
+    HEAP8[i2 + 63 | 0] = 0;
+    i2 = 0;
+    break;
+   }
+  case 6:
+   {
+    i5 = i2 + 156 | 0;
+    i2 = HEAP32[i5 >> 2] | 0;
+    HEAP32[i5 >> 2] = i4;
+    break;
+   }
+  case 9:
+   {
+    i2 = HEAPU8[i2 + 63 | 0] | 0;
+    break;
+   }
+  case 10:
+   {
+    _luaC_changemode(i3, 2);
+    i2 = 0;
+    break;
+   }
+  default:
+   {
+    i2 = -1;
+   }
+  }
+ } while (0);
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _os_time(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i4 = i2;
+ i5 = i2 + 48 | 0;
+ i3 = i2 + 4 | 0;
+ if ((_lua_type(i1, 1) | 0) < 1) {
+  i3 = _time(0) | 0;
+ } else {
+  _luaL_checktype(i1, 1, 5);
+  _lua_settop(i1, 1);
+  _lua_getfield(i1, -1, 5864);
+  i6 = _lua_tointegerx(i1, -1, i4) | 0;
+  i6 = (HEAP32[i4 >> 2] | 0) == 0 ? 0 : i6;
+  _lua_settop(i1, -2);
+  HEAP32[i3 >> 2] = i6;
+  _lua_getfield(i1, -1, 5872);
+  i6 = _lua_tointegerx(i1, -1, i4) | 0;
+  i6 = (HEAP32[i4 >> 2] | 0) == 0 ? 0 : i6;
+  _lua_settop(i1, -2);
+  HEAP32[i3 + 4 >> 2] = i6;
+  _lua_getfield(i1, -1, 5880);
+  i6 = _lua_tointegerx(i1, -1, i4) | 0;
+  i6 = (HEAP32[i4 >> 2] | 0) == 0 ? 12 : i6;
+  _lua_settop(i1, -2);
+  HEAP32[i3 + 8 >> 2] = i6;
+  _lua_getfield(i1, -1, 5888);
+  i6 = _lua_tointegerx(i1, -1, i5) | 0;
+  if ((HEAP32[i5 >> 2] | 0) == 0) {
+   HEAP32[i4 >> 2] = 5888;
+   i6 = _luaL_error(i1, 5920, i4) | 0;
+  } else {
+   _lua_settop(i1, -2);
+  }
+  HEAP32[i3 + 12 >> 2] = i6;
+  _lua_getfield(i1, -1, 5896);
+  i6 = _lua_tointegerx(i1, -1, i5) | 0;
+  if ((HEAP32[i5 >> 2] | 0) == 0) {
+   HEAP32[i4 >> 2] = 5896;
+   i6 = _luaL_error(i1, 5920, i4) | 0;
+  } else {
+   _lua_settop(i1, -2);
+  }
+  HEAP32[i3 + 16 >> 2] = i6 + -1;
+  _lua_getfield(i1, -1, 5904);
+  i6 = _lua_tointegerx(i1, -1, i5) | 0;
+  if ((HEAP32[i5 >> 2] | 0) == 0) {
+   HEAP32[i4 >> 2] = 5904;
+   i6 = _luaL_error(i1, 5920, i4) | 0;
+  } else {
+   _lua_settop(i1, -2);
+  }
+  HEAP32[i3 + 20 >> 2] = i6 + -1900;
+  _lua_getfield(i1, -1, 5912);
+  if ((_lua_type(i1, -1) | 0) == 0) {
+   i4 = -1;
+  } else {
+   i4 = _lua_toboolean(i1, -1) | 0;
+  }
+  _lua_settop(i1, -2);
+  HEAP32[i3 + 32 >> 2] = i4;
+  i3 = _mktime(i3 | 0) | 0;
+ }
+ if ((i3 | 0) == -1) {
+  _lua_pushnil(i1);
+  STACKTOP = i2;
+  return 1;
+ } else {
+  _lua_pushnumber(i1, +(i3 | 0));
+  STACKTOP = i2;
+  return 1;
+ }
+ return 0;
+}
+function _addk(i6, i4, i3) {
+ i6 = i6 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i2 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i10 = i1;
+ i2 = HEAP32[(HEAP32[i6 + 12 >> 2] | 0) + 52 >> 2] | 0;
+ i8 = _luaH_set(i2, HEAP32[i6 + 4 >> 2] | 0, i4) | 0;
+ i4 = HEAP32[i6 >> 2] | 0;
+ i9 = i8 + 8 | 0;
+ if (((HEAP32[i9 >> 2] | 0) == 3 ? (HEAPF64[i10 >> 3] = +HEAPF64[i8 >> 3] + 6755399441055744.0, i7 = HEAP32[i10 >> 2] | 0, i5 = HEAP32[i4 + 8 >> 2] | 0, (HEAP32[i5 + (i7 << 4) + 8 >> 2] | 0) == (HEAP32[i3 + 8 >> 2] | 0)) : 0) ? (_luaV_equalobj_(0, i5 + (i7 << 4) | 0, i3) | 0) != 0 : 0) {
+  i10 = i7;
+  STACKTOP = i1;
+  return i10 | 0;
+ }
+ i5 = i4 + 44 | 0;
+ i10 = HEAP32[i5 >> 2] | 0;
+ i7 = i6 + 32 | 0;
+ i6 = HEAP32[i7 >> 2] | 0;
+ HEAPF64[i8 >> 3] = +(i6 | 0);
+ HEAP32[i9 >> 2] = 3;
+ i9 = HEAP32[i5 >> 2] | 0;
+ if ((i6 | 0) >= (i9 | 0)) {
+  i9 = i4 + 8 | 0;
+  HEAP32[i9 >> 2] = _luaM_growaux_(i2, HEAP32[i9 >> 2] | 0, i5, 16, 67108863, 10600) | 0;
+  i9 = HEAP32[i5 >> 2] | 0;
+ }
+ i8 = HEAP32[i4 + 8 >> 2] | 0;
+ if ((i10 | 0) < (i9 | 0)) {
+  while (1) {
+   i9 = i10 + 1 | 0;
+   HEAP32[i8 + (i10 << 4) + 8 >> 2] = 0;
+   if ((i9 | 0) < (HEAP32[i5 >> 2] | 0)) {
+    i10 = i9;
+   } else {
+    break;
+   }
+  }
+ }
+ i5 = i3;
+ i9 = HEAP32[i5 + 4 >> 2] | 0;
+ i10 = i8 + (i6 << 4) | 0;
+ HEAP32[i10 >> 2] = HEAP32[i5 >> 2];
+ HEAP32[i10 + 4 >> 2] = i9;
+ i10 = i3 + 8 | 0;
+ HEAP32[i8 + (i6 << 4) + 8 >> 2] = HEAP32[i10 >> 2];
+ HEAP32[i7 >> 2] = (HEAP32[i7 >> 2] | 0) + 1;
+ if ((HEAP32[i10 >> 2] & 64 | 0) == 0) {
+  i10 = i6;
+  STACKTOP = i1;
+  return i10 | 0;
+ }
+ i3 = HEAP32[i3 >> 2] | 0;
+ if ((HEAP8[i3 + 5 | 0] & 3) == 0) {
+  i10 = i6;
+  STACKTOP = i1;
+  return i10 | 0;
+ }
+ if ((HEAP8[i4 + 5 | 0] & 4) == 0) {
+  i10 = i6;
+  STACKTOP = i1;
+  return i10 | 0;
+ }
+ _luaC_barrier_(i2, i4, i3);
+ i10 = i6;
+ STACKTOP = i1;
+ return i10 | 0;
+}
+function _singlevaraux(i5, i4, i2, i11) {
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i11 = i11 | 0;
+ var i1 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i1 = STACKTOP;
+ if ((i5 | 0) == 0) {
+  i11 = 0;
+  STACKTOP = i1;
+  return i11 | 0;
+ }
+ i7 = i5 + 12 | 0;
+ i8 = i5 + 40 | 0;
+ i9 = HEAPU8[i5 + 46 | 0] | 0;
+ while (1) {
+  i6 = i9 + -1 | 0;
+  i10 = HEAP32[i5 >> 2] | 0;
+  if ((i9 | 0) <= 0) {
+   break;
+  }
+  if ((_luaS_eqstr(i4, HEAP32[(HEAP32[i10 + 24 >> 2] | 0) + ((HEAP16[(HEAP32[HEAP32[(HEAP32[i7 >> 2] | 0) + 64 >> 2] >> 2] | 0) + ((HEAP32[i8 >> 2] | 0) + i6 << 1) >> 1] | 0) * 12 | 0) >> 2] | 0) | 0) == 0) {
+   i9 = i6;
+  } else {
+   i3 = 5;
+   break;
+  }
+ }
+ if ((i3 | 0) == 5) {
+  HEAP32[i2 + 16 >> 2] = -1;
+  HEAP32[i2 + 20 >> 2] = -1;
+  HEAP32[i2 >> 2] = 7;
+  HEAP32[i2 + 8 >> 2] = i6;
+  if ((i11 | 0) != 0) {
+   i11 = 7;
+   STACKTOP = i1;
+   return i11 | 0;
+  }
+  i2 = i5 + 16 | 0;
+  do {
+   i2 = HEAP32[i2 >> 2] | 0;
+  } while ((HEAPU8[i2 + 8 | 0] | 0) > (i6 | 0));
+  HEAP8[i2 + 9 | 0] = 1;
+  i11 = 7;
+  STACKTOP = i1;
+  return i11 | 0;
+ }
+ i7 = HEAP32[i10 + 28 >> 2] | 0;
+ i6 = i5 + 47 | 0;
+ L17 : do {
+  if ((HEAP8[i6] | 0) != 0) {
+   i8 = 0;
+   while (1) {
+    i9 = i8 + 1 | 0;
+    if ((_luaS_eqstr(HEAP32[i7 + (i8 << 3) >> 2] | 0, i4) | 0) != 0) {
+     break;
+    }
+    if ((i9 | 0) < (HEAPU8[i6] | 0)) {
+     i8 = i9;
+    } else {
+     i3 = 13;
+     break L17;
+    }
+   }
+   if ((i8 | 0) < 0) {
+    i3 = 13;
+   }
+  } else {
+   i3 = 13;
+  }
+ } while (0);
+ do {
+  if ((i3 | 0) == 13) {
+   if ((_singlevaraux(HEAP32[i5 + 8 >> 2] | 0, i4, i2, 0) | 0) == 0) {
+    i11 = 0;
+    STACKTOP = i1;
+    return i11 | 0;
+   } else {
+    i8 = _newupvalue(i5, i4, i2) | 0;
+    break;
+   }
+  }
+ } while (0);
+ HEAP32[i2 + 16 >> 2] = -1;
+ HEAP32[i2 + 20 >> 2] = -1;
+ HEAP32[i2 >> 2] = 8;
+ HEAP32[i2 + 8 >> 2] = i8;
+ i11 = 8;
+ STACKTOP = i1;
+ return i11 | 0;
+}
+function _mainposition(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ switch (HEAP32[i3 + 8 >> 2] & 63 | 0) {
+ case 3:
+  {
+   HEAPF64[i4 >> 3] = +HEAPF64[i3 >> 3] + 1.0;
+   i3 = (HEAP32[i4 + 4 >> 2] | 0) + (HEAP32[i4 >> 2] | 0) | 0;
+   if ((i3 | 0) < 0) {
+    i4 = 0 - i3 | 0;
+    i3 = (i3 | 0) == (i4 | 0) ? 0 : i4;
+   }
+   i5 = (HEAP32[i1 + 16 >> 2] | 0) + (((i3 | 0) % ((1 << HEAPU8[i1 + 7 | 0]) + -1 | 1 | 0) | 0) << 5) | 0;
+   STACKTOP = i2;
+   return i5 | 0;
+  }
+ case 2:
+  {
+   i5 = (HEAP32[i1 + 16 >> 2] | 0) + ((((HEAP32[i3 >> 2] | 0) >>> 0) % (((1 << HEAPU8[i1 + 7 | 0]) + -1 | 1) >>> 0) | 0) << 5) | 0;
+   STACKTOP = i2;
+   return i5 | 0;
+  }
+ case 20:
+  {
+   i5 = HEAP32[i3 >> 2] | 0;
+   i4 = i5 + 6 | 0;
+   if ((HEAP8[i4] | 0) == 0) {
+    i6 = i5 + 8 | 0;
+    HEAP32[i6 >> 2] = _luaS_hash(i5 + 16 | 0, HEAP32[i5 + 12 >> 2] | 0, HEAP32[i6 >> 2] | 0) | 0;
+    HEAP8[i4] = 1;
+    i5 = HEAP32[i3 >> 2] | 0;
+   }
+   i6 = (HEAP32[i1 + 16 >> 2] | 0) + (((1 << HEAPU8[i1 + 7 | 0]) + -1 & HEAP32[i5 + 8 >> 2]) << 5) | 0;
+   STACKTOP = i2;
+   return i6 | 0;
+  }
+ case 22:
+  {
+   i6 = (HEAP32[i1 + 16 >> 2] | 0) + ((((HEAP32[i3 >> 2] | 0) >>> 0) % (((1 << HEAPU8[i1 + 7 | 0]) + -1 | 1) >>> 0) | 0) << 5) | 0;
+   STACKTOP = i2;
+   return i6 | 0;
+  }
+ case 4:
+  {
+   i6 = (HEAP32[i1 + 16 >> 2] | 0) + (((1 << HEAPU8[i1 + 7 | 0]) + -1 & HEAP32[(HEAP32[i3 >> 2] | 0) + 8 >> 2]) << 5) | 0;
+   STACKTOP = i2;
+   return i6 | 0;
+  }
+ case 1:
+  {
+   i6 = (HEAP32[i1 + 16 >> 2] | 0) + (((1 << HEAPU8[i1 + 7 | 0]) + -1 & HEAP32[i3 >> 2]) << 5) | 0;
+   STACKTOP = i2;
+   return i6 | 0;
+  }
+ default:
+  {
+   i6 = (HEAP32[i1 + 16 >> 2] | 0) + ((((HEAP32[i3 >> 2] | 0) >>> 0) % (((1 << HEAPU8[i1 + 7 | 0]) + -1 | 1) >>> 0) | 0) << 5) | 0;
+   STACKTOP = i2;
+   return i6 | 0;
+  }
+ }
+ return 0;
+}
+function _clearvalues(i2, i5, i1) {
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ var i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i4 = STACKTOP;
+ if ((i5 | 0) == (i1 | 0)) {
+  STACKTOP = i4;
+  return;
+ }
+ do {
+  i7 = i5 + 16 | 0;
+  i9 = HEAP32[i7 >> 2] | 0;
+  i6 = i9 + (1 << (HEAPU8[i5 + 7 | 0] | 0) << 5) | 0;
+  i8 = i5 + 28 | 0;
+  if ((HEAP32[i8 >> 2] | 0) > 0) {
+   i11 = i5 + 12 | 0;
+   i12 = 0;
+   do {
+    i13 = HEAP32[i11 >> 2] | 0;
+    i10 = i13 + (i12 << 4) + 8 | 0;
+    i9 = HEAP32[i10 >> 2] | 0;
+    do {
+     if ((i9 & 64 | 0) != 0) {
+      i13 = HEAP32[i13 + (i12 << 4) >> 2] | 0;
+      if ((i9 & 15 | 0) != 4) {
+       if ((HEAP8[i13 + 5 | 0] & 3) == 0) {
+        break;
+       }
+       HEAP32[i10 >> 2] = 0;
+       break;
+      }
+      if ((i13 | 0) != 0 ? !((HEAP8[i13 + 5 | 0] & 3) == 0) : 0) {
+       _reallymarkobject(i2, i13);
+      }
+     }
+    } while (0);
+    i12 = i12 + 1 | 0;
+   } while ((i12 | 0) < (HEAP32[i8 >> 2] | 0));
+   i7 = HEAP32[i7 >> 2] | 0;
+  } else {
+   i7 = i9;
+  }
+  if (i7 >>> 0 < i6 >>> 0) {
+   do {
+    i8 = i7 + 8 | 0;
+    i9 = HEAP32[i8 >> 2] | 0;
+    do {
+     if (!((i9 | 0) == 0 | (i9 & 64 | 0) == 0)) {
+      i10 = HEAP32[i7 >> 2] | 0;
+      if ((i9 & 15 | 0) == 4) {
+       if ((i10 | 0) == 0) {
+        break;
+       }
+       if ((HEAP8[i10 + 5 | 0] & 3) == 0) {
+        break;
+       }
+       _reallymarkobject(i2, i10);
+       break;
+      }
+      if ((!((HEAP8[i10 + 5 | 0] & 3) == 0) ? (HEAP32[i8 >> 2] = 0, i3 = i7 + 24 | 0, (HEAP32[i3 >> 2] & 64 | 0) != 0) : 0) ? !((HEAP8[(HEAP32[i7 + 16 >> 2] | 0) + 5 | 0] & 3) == 0) : 0) {
+       HEAP32[i3 >> 2] = 11;
+      }
+     }
+    } while (0);
+    i7 = i7 + 32 | 0;
+   } while (i7 >>> 0 < i6 >>> 0);
+  }
+  i5 = HEAP32[i5 + 24 >> 2] | 0;
+ } while ((i5 | 0) != (i1 | 0));
+ STACKTOP = i4;
+ return;
+}
+function _reallymarkobject(i1, i4) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i3 = STACKTOP;
+ i2 = i4 + 5 | 0;
+ HEAP8[i2] = HEAP8[i2] & 252;
+ switch (HEAPU8[i4 + 4 | 0] | 0 | 0) {
+ case 6:
+  {
+   i7 = i1 + 84 | 0;
+   HEAP32[i4 + 8 >> 2] = HEAP32[i7 >> 2];
+   HEAP32[i7 >> 2] = i4;
+   STACKTOP = i3;
+   return;
+  }
+ case 20:
+ case 4:
+  {
+   i4 = (HEAP32[i4 + 12 >> 2] | 0) + 17 | 0;
+   break;
+  }
+ case 7:
+  {
+   i5 = HEAP32[i4 + 8 >> 2] | 0;
+   if ((i5 | 0) != 0 ? !((HEAP8[i5 + 5 | 0] & 3) == 0) : 0) {
+    _reallymarkobject(i1, i5);
+   }
+   i5 = HEAP32[i4 + 12 >> 2] | 0;
+   if ((i5 | 0) != 0 ? !((HEAP8[i5 + 5 | 0] & 3) == 0) : 0) {
+    _reallymarkobject(i1, i5);
+   }
+   i4 = (HEAP32[i4 + 16 >> 2] | 0) + 24 | 0;
+   break;
+  }
+ case 8:
+  {
+   i7 = i1 + 84 | 0;
+   HEAP32[i4 + 60 >> 2] = HEAP32[i7 >> 2];
+   HEAP32[i7 >> 2] = i4;
+   STACKTOP = i3;
+   return;
+  }
+ case 10:
+  {
+   i6 = i4 + 8 | 0;
+   i7 = HEAP32[i6 >> 2] | 0;
+   if ((HEAP32[i7 + 8 >> 2] & 64 | 0) != 0 ? (i5 = HEAP32[i7 >> 2] | 0, !((HEAP8[i5 + 5 | 0] & 3) == 0)) : 0) {
+    _reallymarkobject(i1, i5);
+    i7 = HEAP32[i6 >> 2] | 0;
+   }
+   if ((i7 | 0) == (i4 + 16 | 0)) {
+    i4 = 32;
+   } else {
+    STACKTOP = i3;
+    return;
+   }
+   break;
+  }
+ case 5:
+  {
+   i7 = i1 + 84 | 0;
+   HEAP32[i4 + 24 >> 2] = HEAP32[i7 >> 2];
+   HEAP32[i7 >> 2] = i4;
+   STACKTOP = i3;
+   return;
+  }
+ case 38:
+  {
+   i7 = i1 + 84 | 0;
+   HEAP32[i4 + 8 >> 2] = HEAP32[i7 >> 2];
+   HEAP32[i7 >> 2] = i4;
+   STACKTOP = i3;
+   return;
+  }
+ case 9:
+  {
+   i7 = i1 + 84 | 0;
+   HEAP32[i4 + 72 >> 2] = HEAP32[i7 >> 2];
+   HEAP32[i7 >> 2] = i4;
+   STACKTOP = i3;
+   return;
+  }
+ default:
+  {
+   STACKTOP = i3;
+   return;
+  }
+ }
+ HEAP8[i2] = HEAPU8[i2] | 0 | 4;
+ i7 = i1 + 16 | 0;
+ HEAP32[i7 >> 2] = (HEAP32[i7 >> 2] | 0) + i4;
+ STACKTOP = i3;
+ return;
+}
+function _lua_upvaluejoin(i1, i9, i7, i6, i3) {
+ i1 = i1 | 0;
+ i9 = i9 | 0;
+ i7 = i7 | 0;
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i8 = 0, i10 = 0;
+ i2 = STACKTOP;
+ i5 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i9 | 0) <= 0) {
+   if (!((i9 | 0) < -1000999)) {
+    i8 = (HEAP32[i1 + 8 >> 2] | 0) + (i9 << 4) | 0;
+    break;
+   }
+   if ((i9 | 0) == -1001e3) {
+    i8 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i10 = -1001e3 - i9 | 0;
+   i9 = HEAP32[i5 >> 2] | 0;
+   if ((HEAP32[i9 + 8 >> 2] | 0) != 22 ? (i8 = HEAP32[i9 >> 2] | 0, (i10 | 0) <= (HEAPU8[i8 + 6 | 0] | 0 | 0)) : 0) {
+    i8 = i8 + (i10 + -1 << 4) + 16 | 0;
+   } else {
+    i8 = 5192;
+   }
+  } else {
+   i8 = (HEAP32[i5 >> 2] | 0) + (i9 << 4) | 0;
+   i8 = i8 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i8 : 5192;
+  }
+ } while (0);
+ i8 = HEAP32[i8 >> 2] | 0;
+ i7 = i8 + 16 + (i7 + -1 << 2) | 0;
+ do {
+  if ((i6 | 0) <= 0) {
+   if (!((i6 | 0) < -1000999)) {
+    i4 = (HEAP32[i1 + 8 >> 2] | 0) + (i6 << 4) | 0;
+    break;
+   }
+   if ((i6 | 0) == -1001e3) {
+    i4 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i6 = -1001e3 - i6 | 0;
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((HEAP32[i5 + 8 >> 2] | 0) != 22 ? (i4 = HEAP32[i5 >> 2] | 0, (i6 | 0) <= (HEAPU8[i4 + 6 | 0] | 0 | 0)) : 0) {
+    i4 = i4 + (i6 + -1 << 4) + 16 | 0;
+   } else {
+    i4 = 5192;
+   }
+  } else {
+   i4 = (HEAP32[i5 >> 2] | 0) + (i6 << 4) | 0;
+   i4 = i4 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i4 : 5192;
+  }
+ } while (0);
+ i3 = (HEAP32[i4 >> 2] | 0) + 16 + (i3 + -1 << 2) | 0;
+ HEAP32[i7 >> 2] = HEAP32[i3 >> 2];
+ i3 = HEAP32[i3 >> 2] | 0;
+ if ((HEAP8[i3 + 5 | 0] & 3) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ if ((HEAP8[i8 + 5 | 0] & 4) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ _luaC_barrier_(i1, i8, i3);
+ STACKTOP = i2;
+ return;
+}
+function _lua_upvalueid(i5, i7, i1) {
+ i5 = i5 | 0;
+ i7 = i7 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i5 + 16 >> 2] | 0;
+ i6 = (i7 | 0) > 0;
+ do {
+  if (!i6) {
+   if (!((i7 | 0) < -1000999)) {
+    i8 = (HEAP32[i5 + 8 >> 2] | 0) + (i7 << 4) | 0;
+    break;
+   }
+   if ((i7 | 0) == -1001e3) {
+    i8 = (HEAP32[i5 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i10 = -1001e3 - i7 | 0;
+   i9 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i9 + 8 >> 2] | 0) != 22 ? (i8 = HEAP32[i9 >> 2] | 0, (i10 | 0) <= (HEAPU8[i8 + 6 | 0] | 0 | 0)) : 0) {
+    i8 = i8 + (i10 + -1 << 4) + 16 | 0;
+   } else {
+    i8 = 5192;
+   }
+  } else {
+   i8 = (HEAP32[i4 >> 2] | 0) + (i7 << 4) | 0;
+   i8 = i8 >>> 0 < (HEAP32[i5 + 8 >> 2] | 0) >>> 0 ? i8 : 5192;
+  }
+ } while (0);
+ i9 = HEAP32[i8 + 8 >> 2] & 63;
+ if ((i9 | 0) == 38) {
+  i10 = (HEAP32[i8 >> 2] | 0) + (i1 + -1 << 4) + 16 | 0;
+  STACKTOP = i2;
+  return i10 | 0;
+ } else if ((i9 | 0) == 6) {
+  do {
+   if (!i6) {
+    if (!((i7 | 0) < -1000999)) {
+     i3 = (HEAP32[i5 + 8 >> 2] | 0) + (i7 << 4) | 0;
+     break;
+    }
+    if ((i7 | 0) == -1001e3) {
+     i3 = (HEAP32[i5 + 12 >> 2] | 0) + 40 | 0;
+     break;
+    }
+    i5 = -1001e3 - i7 | 0;
+    i4 = HEAP32[i4 >> 2] | 0;
+    if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i4 >> 2] | 0, (i5 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+     i3 = i3 + (i5 + -1 << 4) + 16 | 0;
+    } else {
+     i3 = 5192;
+    }
+   } else {
+    i3 = (HEAP32[i4 >> 2] | 0) + (i7 << 4) | 0;
+    i3 = i3 >>> 0 < (HEAP32[i5 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+   }
+  } while (0);
+  i10 = HEAP32[(HEAP32[i3 >> 2] | 0) + 16 + (i1 + -1 << 2) >> 2] | 0;
+  STACKTOP = i2;
+  return i10 | 0;
+ } else {
+  i10 = 0;
+  STACKTOP = i2;
+  return i10 | 0;
+ }
+ return 0;
+}
+function _lua_rawequal(i2, i6, i4) {
+ i2 = i2 | 0;
+ i6 = i6 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i3 = 0, i5 = 0, i7 = 0;
+ i1 = STACKTOP;
+ i3 = HEAP32[i2 + 16 >> 2] | 0;
+ do {
+  if ((i6 | 0) <= 0) {
+   if (!((i6 | 0) < -1000999)) {
+    i5 = (HEAP32[i2 + 8 >> 2] | 0) + (i6 << 4) | 0;
+    break;
+   }
+   if ((i6 | 0) == -1001e3) {
+    i5 = (HEAP32[i2 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i7 = -1001e3 - i6 | 0;
+   i6 = HEAP32[i3 >> 2] | 0;
+   if ((HEAP32[i6 + 8 >> 2] | 0) != 22 ? (i5 = HEAP32[i6 >> 2] | 0, (i7 | 0) <= (HEAPU8[i5 + 6 | 0] | 0 | 0)) : 0) {
+    i5 = i5 + (i7 + -1 << 4) + 16 | 0;
+   } else {
+    i5 = 5192;
+   }
+  } else {
+   i5 = (HEAP32[i3 >> 2] | 0) + (i6 << 4) | 0;
+   i5 = i5 >>> 0 < (HEAP32[i2 + 8 >> 2] | 0) >>> 0 ? i5 : 5192;
+  }
+ } while (0);
+ do {
+  if ((i4 | 0) <= 0) {
+   if (!((i4 | 0) < -1000999)) {
+    i2 = (HEAP32[i2 + 8 >> 2] | 0) + (i4 << 4) | 0;
+    break;
+   }
+   if ((i4 | 0) == -1001e3) {
+    i2 = (HEAP32[i2 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i2 = -1001e3 - i4 | 0;
+   i3 = HEAP32[i3 >> 2] | 0;
+   if ((HEAP32[i3 + 8 >> 2] | 0) == 22) {
+    i7 = 0;
+    STACKTOP = i1;
+    return i7 | 0;
+   }
+   i3 = HEAP32[i3 >> 2] | 0;
+   if ((i2 | 0) > (HEAPU8[i3 + 6 | 0] | 0 | 0)) {
+    i7 = 0;
+    STACKTOP = i1;
+    return i7 | 0;
+   } else {
+    i2 = i3 + (i2 + -1 << 4) + 16 | 0;
+    break;
+   }
+  } else {
+   i3 = (HEAP32[i3 >> 2] | 0) + (i4 << 4) | 0;
+   i2 = i3 >>> 0 < (HEAP32[i2 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ if ((i5 | 0) == 5192 | (i2 | 0) == 5192) {
+  i7 = 0;
+  STACKTOP = i1;
+  return i7 | 0;
+ }
+ if ((HEAP32[i5 + 8 >> 2] | 0) == (HEAP32[i2 + 8 >> 2] | 0)) {
+  i2 = (_luaV_equalobj_(0, i5, i2) | 0) != 0;
+ } else {
+  i2 = 0;
+ }
+ i7 = i2 & 1;
+ STACKTOP = i1;
+ return i7 | 0;
+}
+function _luaO_chunkid(i1, i4, i6) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ var i2 = 0, i3 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i2 = STACKTOP;
+ i3 = _strlen(i4 | 0) | 0;
+ i5 = HEAP8[i4] | 0;
+ if (i5 << 24 >> 24 == 64) {
+  if (i3 >>> 0 > i6 >>> 0) {
+   HEAP8[i1 + 0 | 0] = HEAP8[5552 | 0] | 0;
+   HEAP8[i1 + 1 | 0] = HEAP8[5553 | 0] | 0;
+   HEAP8[i1 + 2 | 0] = HEAP8[5554 | 0] | 0;
+   _memcpy(i1 + 3 | 0, i4 + (4 - i6 + i3) | 0, i6 + -3 | 0) | 0;
+   STACKTOP = i2;
+   return;
+  } else {
+   _memcpy(i1 | 0, i4 + 1 | 0, i3 | 0) | 0;
+   STACKTOP = i2;
+   return;
+  }
+ } else if (i5 << 24 >> 24 == 61) {
+  i4 = i4 + 1 | 0;
+  if (i3 >>> 0 > i6 >>> 0) {
+   i9 = i6 + -1 | 0;
+   _memcpy(i1 | 0, i4 | 0, i9 | 0) | 0;
+   HEAP8[i1 + i9 | 0] = 0;
+   STACKTOP = i2;
+   return;
+  } else {
+   _memcpy(i1 | 0, i4 | 0, i3 | 0) | 0;
+   STACKTOP = i2;
+   return;
+  }
+ } else {
+  i5 = _strchr(i4, 10) | 0;
+  i9 = i1 + 0 | 0;
+  i8 = 5560 | 0;
+  i7 = i9 + 9 | 0;
+  do {
+   HEAP8[i9] = HEAP8[i8] | 0;
+   i9 = i9 + 1 | 0;
+   i8 = i8 + 1 | 0;
+  } while ((i9 | 0) < (i7 | 0));
+  i7 = i1 + 9 | 0;
+  i6 = i6 + -15 | 0;
+  i8 = (i5 | 0) == 0;
+  if (i3 >>> 0 < i6 >>> 0 & i8) {
+   _memcpy(i7 | 0, i4 | 0, i3 | 0) | 0;
+   i3 = i3 + 9 | 0;
+  } else {
+   if (!i8) {
+    i3 = i5 - i4 | 0;
+   }
+   i3 = i3 >>> 0 > i6 >>> 0 ? i6 : i3;
+   _memcpy(i7 | 0, i4 | 0, i3 | 0) | 0;
+   i9 = i1 + (i3 + 9) | 0;
+   HEAP8[i9 + 0 | 0] = HEAP8[5552 | 0] | 0;
+   HEAP8[i9 + 1 | 0] = HEAP8[5553 | 0] | 0;
+   HEAP8[i9 + 2 | 0] = HEAP8[5554 | 0] | 0;
+   i3 = i3 + 12 | 0;
+  }
+  i9 = i1 + i3 | 0;
+  HEAP8[i9 + 0 | 0] = HEAP8[5576 | 0] | 0;
+  HEAP8[i9 + 1 | 0] = HEAP8[5577 | 0] | 0;
+  HEAP8[i9 + 2 | 0] = HEAP8[5578 | 0] | 0;
+  STACKTOP = i2;
+  return;
+ }
+}
+function _luaS_resize(i4, i1) {
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i3 = STACKTOP;
+ i5 = HEAP32[i4 + 12 >> 2] | 0;
+ i2 = i5 + 24 | 0;
+ _luaC_runtilstate(i4, -5);
+ i5 = i5 + 32 | 0;
+ i8 = HEAP32[i5 >> 2] | 0;
+ L1 : do {
+  if ((i8 | 0) < (i1 | 0)) {
+   if ((i1 + 1 | 0) >>> 0 > 1073741823) {
+    _luaM_toobig(i4);
+   }
+   i7 = _luaM_realloc_(i4, HEAP32[i2 >> 2] | 0, i8 << 2, i1 << 2) | 0;
+   HEAP32[i2 >> 2] = i7;
+   i6 = HEAP32[i5 >> 2] | 0;
+   if ((i6 | 0) < (i1 | 0)) {
+    i8 = i6;
+    while (1) {
+     HEAP32[i7 + (i8 << 2) >> 2] = 0;
+     i8 = i8 + 1 | 0;
+     if ((i8 | 0) == (i1 | 0)) {
+      i8 = i6;
+      break L1;
+     }
+     i7 = HEAP32[i2 >> 2] | 0;
+    }
+   } else {
+    i8 = i6;
+   }
+  }
+ } while (0);
+ if ((i8 | 0) > 0) {
+  i6 = i1 + -1 | 0;
+  i7 = 0;
+  do {
+   i10 = (HEAP32[i2 >> 2] | 0) + (i7 << 2) | 0;
+   i9 = HEAP32[i10 >> 2] | 0;
+   HEAP32[i10 >> 2] = 0;
+   if ((i9 | 0) != 0) {
+    while (1) {
+     i8 = HEAP32[i9 >> 2] | 0;
+     i10 = HEAP32[i9 + 8 >> 2] & i6;
+     HEAP32[i9 >> 2] = HEAP32[(HEAP32[i2 >> 2] | 0) + (i10 << 2) >> 2];
+     HEAP32[(HEAP32[i2 >> 2] | 0) + (i10 << 2) >> 2] = i9;
+     i10 = i9 + 5 | 0;
+     HEAP8[i10] = HEAP8[i10] & 191;
+     if ((i8 | 0) == 0) {
+      break;
+     } else {
+      i9 = i8;
+     }
+    }
+    i8 = HEAP32[i5 >> 2] | 0;
+   }
+   i7 = i7 + 1 | 0;
+  } while ((i7 | 0) < (i8 | 0));
+ }
+ if ((i8 | 0) <= (i1 | 0)) {
+  HEAP32[i5 >> 2] = i1;
+  STACKTOP = i3;
+  return;
+ }
+ if ((i1 + 1 | 0) >>> 0 > 1073741823) {
+  _luaM_toobig(i4);
+ }
+ HEAP32[i2 >> 2] = _luaM_realloc_(i4, HEAP32[i2 >> 2] | 0, i8 << 2, i1 << 2) | 0;
+ HEAP32[i5 >> 2] = i1;
+ STACKTOP = i3;
+ return;
+}
+function _luaD_poscall(i6, i7) {
+ i6 = i6 | 0;
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0;
+ i1 = STACKTOP;
+ i4 = i6 + 16 | 0;
+ i3 = HEAP32[i4 >> 2] | 0;
+ i5 = HEAPU8[i6 + 40 | 0] | 0;
+ if ((i5 & 6 | 0) == 0) {
+  i8 = i3 + 8 | 0;
+ } else {
+  if ((i5 & 2 | 0) != 0) {
+   i8 = i6 + 28 | 0;
+   i7 = i7 - (HEAP32[i8 >> 2] | 0) | 0;
+   _luaD_hook(i6, 1, -1);
+   i7 = (HEAP32[i8 >> 2] | 0) + i7 | 0;
+  }
+  i8 = i3 + 8 | 0;
+  HEAP32[i6 + 20 >> 2] = HEAP32[(HEAP32[i8 >> 2] | 0) + 28 >> 2];
+ }
+ i5 = HEAP32[i3 >> 2] | 0;
+ i9 = HEAP16[i3 + 16 >> 1] | 0;
+ i3 = i9 << 16 >> 16;
+ HEAP32[i4 >> 2] = HEAP32[i8 >> 2];
+ i4 = i6 + 8 | 0;
+ if (i9 << 16 >> 16 == 0) {
+  i9 = i5;
+  HEAP32[i4 >> 2] = i9;
+  i9 = i3 + 1 | 0;
+  STACKTOP = i1;
+  return i9 | 0;
+ } else {
+  i6 = i3;
+ }
+ while (1) {
+  if (!(i7 >>> 0 < (HEAP32[i4 >> 2] | 0) >>> 0)) {
+   break;
+  }
+  i8 = i5 + 16 | 0;
+  i11 = i7;
+  i10 = HEAP32[i11 + 4 >> 2] | 0;
+  i9 = i5;
+  HEAP32[i9 >> 2] = HEAP32[i11 >> 2];
+  HEAP32[i9 + 4 >> 2] = i10;
+  HEAP32[i5 + 8 >> 2] = HEAP32[i7 + 8 >> 2];
+  i6 = i6 + -1 | 0;
+  if ((i6 | 0) == 0) {
+   i2 = 12;
+   break;
+  } else {
+   i7 = i7 + 16 | 0;
+   i5 = i8;
+  }
+ }
+ if ((i2 | 0) == 12) {
+  HEAP32[i4 >> 2] = i8;
+  i11 = i3 + 1 | 0;
+  STACKTOP = i1;
+  return i11 | 0;
+ }
+ if ((i6 | 0) > 0) {
+  i2 = i6;
+  i7 = i5;
+ } else {
+  i11 = i5;
+  HEAP32[i4 >> 2] = i11;
+  i11 = i3 + 1 | 0;
+  STACKTOP = i1;
+  return i11 | 0;
+ }
+ while (1) {
+  i2 = i2 + -1 | 0;
+  HEAP32[i7 + 8 >> 2] = 0;
+  if ((i2 | 0) <= 0) {
+   break;
+  } else {
+   i7 = i7 + 16 | 0;
+  }
+ }
+ i11 = i5 + (i6 << 4) | 0;
+ HEAP32[i4 >> 2] = i11;
+ i11 = i3 + 1 | 0;
+ STACKTOP = i1;
+ return i11 | 0;
+}
+function _lua_rawset(i1, i4) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i2 = STACKTOP;
+ i5 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i4 | 0) <= 0) {
+   if (!((i4 | 0) < -1000999)) {
+    i5 = (HEAP32[i1 + 8 >> 2] | 0) + (i4 << 4) | 0;
+    break;
+   }
+   if ((i4 | 0) == -1001e3) {
+    i5 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i4 = -1001e3 - i4 | 0;
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((HEAP32[i5 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i5 >> 2] | 0, (i4 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i5 = i3 + (i4 + -1 << 4) + 16 | 0;
+   } else {
+    i5 = 5192;
+   }
+  } else {
+   i3 = (HEAP32[i5 >> 2] | 0) + (i4 << 4) | 0;
+   i5 = i3 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ i4 = i1 + 8 | 0;
+ i6 = HEAP32[i4 >> 2] | 0;
+ i3 = _luaH_set(i1, HEAP32[i5 >> 2] | 0, i6 + -32 | 0) | 0;
+ i9 = i6 + -16 | 0;
+ i8 = HEAP32[i9 + 4 >> 2] | 0;
+ i7 = i3;
+ HEAP32[i7 >> 2] = HEAP32[i9 >> 2];
+ HEAP32[i7 + 4 >> 2] = i8;
+ HEAP32[i3 + 8 >> 2] = HEAP32[i6 + -8 >> 2];
+ HEAP8[(HEAP32[i5 >> 2] | 0) + 6 | 0] = 0;
+ i3 = HEAP32[i4 >> 2] | 0;
+ if ((HEAP32[i3 + -8 >> 2] & 64 | 0) == 0) {
+  i9 = i3;
+  i9 = i9 + -32 | 0;
+  HEAP32[i4 >> 2] = i9;
+  STACKTOP = i2;
+  return;
+ }
+ if ((HEAP8[(HEAP32[i3 + -16 >> 2] | 0) + 5 | 0] & 3) == 0) {
+  i9 = i3;
+  i9 = i9 + -32 | 0;
+  HEAP32[i4 >> 2] = i9;
+  STACKTOP = i2;
+  return;
+ }
+ i5 = HEAP32[i5 >> 2] | 0;
+ if ((HEAP8[i5 + 5 | 0] & 4) == 0) {
+  i9 = i3;
+  i9 = i9 + -32 | 0;
+  HEAP32[i4 >> 2] = i9;
+  STACKTOP = i2;
+  return;
+ }
+ _luaC_barrierback_(i1, i5);
+ i9 = HEAP32[i4 >> 2] | 0;
+ i9 = i9 + -32 | 0;
+ HEAP32[i4 >> 2] = i9;
+ STACKTOP = i2;
+ return;
+}
+function _saveSetjmp(i4, i3, i1) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i2 = 0;
+ setjmpId = setjmpId + 1 | 0;
+ HEAP32[i4 >> 2] = setjmpId;
+ while ((i2 | 0) < 40) {
+  if ((HEAP32[i1 + (i2 << 2) >> 2] | 0) == 0) {
+   HEAP32[i1 + (i2 << 2) >> 2] = setjmpId;
+   HEAP32[i1 + ((i2 << 2) + 4) >> 2] = i3;
+   HEAP32[i1 + ((i2 << 2) + 8) >> 2] = 0;
+   return 0;
+  }
+  i2 = i2 + 2 | 0;
+ }
+ _putchar(116);
+ _putchar(111);
+ _putchar(111);
+ _putchar(32);
+ _putchar(109);
+ _putchar(97);
+ _putchar(110);
+ _putchar(121);
+ _putchar(32);
+ _putchar(115);
+ _putchar(101);
+ _putchar(116);
+ _putchar(106);
+ _putchar(109);
+ _putchar(112);
+ _putchar(115);
+ _putchar(32);
+ _putchar(105);
+ _putchar(110);
+ _putchar(32);
+ _putchar(97);
+ _putchar(32);
+ _putchar(102);
+ _putchar(117);
+ _putchar(110);
+ _putchar(99);
+ _putchar(116);
+ _putchar(105);
+ _putchar(111);
+ _putchar(110);
+ _putchar(32);
+ _putchar(99);
+ _putchar(97);
+ _putchar(108);
+ _putchar(108);
+ _putchar(44);
+ _putchar(32);
+ _putchar(98);
+ _putchar(117);
+ _putchar(105);
+ _putchar(108);
+ _putchar(100);
+ _putchar(32);
+ _putchar(119);
+ _putchar(105);
+ _putchar(116);
+ _putchar(104);
+ _putchar(32);
+ _putchar(97);
+ _putchar(32);
+ _putchar(104);
+ _putchar(105);
+ _putchar(103);
+ _putchar(104);
+ _putchar(101);
+ _putchar(114);
+ _putchar(32);
+ _putchar(118);
+ _putchar(97);
+ _putchar(108);
+ _putchar(117);
+ _putchar(101);
+ _putchar(32);
+ _putchar(102);
+ _putchar(111);
+ _putchar(114);
+ _putchar(32);
+ _putchar(77);
+ _putchar(65);
+ _putchar(88);
+ _putchar(95);
+ _putchar(83);
+ _putchar(69);
+ _putchar(84);
+ _putchar(74);
+ _putchar(77);
+ _putchar(80);
+ _putchar(83);
+ _putchar(10);
+ abort(0);
+ return 0;
+}
+function _lua_newthread(i5) {
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i1 = STACKTOP;
+ i3 = i5 + 12 | 0;
+ if ((HEAP32[(HEAP32[i3 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+  _luaC_step(i5);
+ }
+ i2 = _luaC_newobj(i5, 8, 112, 0, 0) | 0;
+ i6 = i5 + 8 | 0;
+ i4 = HEAP32[i6 >> 2] | 0;
+ HEAP32[i4 >> 2] = i2;
+ HEAP32[i4 + 8 >> 2] = 72;
+ HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + 16;
+ HEAP32[i2 + 12 >> 2] = HEAP32[i3 >> 2];
+ i6 = i2 + 28 | 0;
+ HEAP32[i6 >> 2] = 0;
+ i4 = i2 + 16 | 0;
+ HEAP32[i4 >> 2] = 0;
+ i3 = i2 + 32 | 0;
+ HEAP32[i3 >> 2] = 0;
+ HEAP32[i2 + 64 >> 2] = 0;
+ HEAP16[i2 + 38 >> 1] = 0;
+ i9 = i2 + 52 | 0;
+ HEAP32[i9 >> 2] = 0;
+ i8 = i2 + 40 | 0;
+ HEAP8[i8] = 0;
+ i10 = i2 + 44 | 0;
+ HEAP32[i10 >> 2] = 0;
+ HEAP8[i2 + 41 | 0] = 1;
+ i7 = i2 + 48 | 0;
+ HEAP32[i7 >> 2] = 0;
+ HEAP32[i2 + 56 >> 2] = 0;
+ HEAP16[i2 + 36 >> 1] = 1;
+ HEAP8[i2 + 6 | 0] = 0;
+ HEAP32[i2 + 68 >> 2] = 0;
+ HEAP8[i8] = HEAP8[i5 + 40 | 0] | 0;
+ i8 = HEAP32[i5 + 44 >> 2] | 0;
+ HEAP32[i10 >> 2] = i8;
+ HEAP32[i9 >> 2] = HEAP32[i5 + 52 >> 2];
+ HEAP32[i7 >> 2] = i8;
+ i5 = _luaM_realloc_(i5, 0, 0, 640) | 0;
+ HEAP32[i6 >> 2] = i5;
+ HEAP32[i3 >> 2] = 40;
+ i6 = 0;
+ do {
+  HEAP32[i5 + (i6 << 4) + 8 >> 2] = 0;
+  i6 = i6 + 1 | 0;
+ } while ((i6 | 0) != 40);
+ HEAP32[i2 + 24 >> 2] = i5 + ((HEAP32[i3 >> 2] | 0) + -5 << 4);
+ i10 = i2 + 72 | 0;
+ HEAP32[i2 + 80 >> 2] = 0;
+ HEAP32[i2 + 84 >> 2] = 0;
+ HEAP8[i2 + 90 | 0] = 0;
+ HEAP32[i10 >> 2] = i5;
+ HEAP32[i2 + 8 >> 2] = i5 + 16;
+ HEAP32[i5 + 8 >> 2] = 0;
+ HEAP32[i2 + 76 >> 2] = i5 + 336;
+ HEAP32[i4 >> 2] = i10;
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _luaK_self(i2, i5, i3) {
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i1 = STACKTOP;
+ _luaK_dischargevars(i2, i5);
+ if ((HEAP32[i5 >> 2] | 0) == 6) {
+  i6 = i5 + 8 | 0;
+  i8 = HEAP32[i6 >> 2] | 0;
+  if ((HEAP32[i5 + 16 >> 2] | 0) != (HEAP32[i5 + 20 >> 2] | 0)) {
+   if ((i8 | 0) < (HEAPU8[i2 + 46 | 0] | 0 | 0)) {
+    i7 = 6;
+   } else {
+    _exp2reg(i2, i5, i8);
+   }
+  }
+ } else {
+  i6 = i5 + 8 | 0;
+  i7 = 6;
+ }
+ if ((i7 | 0) == 6) {
+  _luaK_exp2nextreg(i2, i5);
+ }
+ i8 = HEAP32[i6 >> 2] | 0;
+ if (((HEAP32[i5 >> 2] | 0) == 6 ? (i8 & 256 | 0) == 0 : 0) ? (HEAPU8[i2 + 46 | 0] | 0 | 0) <= (i8 | 0) : 0) {
+  i10 = i2 + 48 | 0;
+  HEAP8[i10] = (HEAP8[i10] | 0) + -1 << 24 >> 24;
+ }
+ i7 = i2 + 48 | 0;
+ HEAP32[i6 >> 2] = HEAPU8[i7] | 0;
+ HEAP32[i5 >> 2] = 6;
+ i10 = HEAP8[i7] | 0;
+ i5 = (i10 & 255) + 2 | 0;
+ i9 = (HEAP32[i2 >> 2] | 0) + 78 | 0;
+ do {
+  if (i5 >>> 0 > (HEAPU8[i9] | 0) >>> 0) {
+   if (i5 >>> 0 > 249) {
+    _luaX_syntaxerror(HEAP32[i2 + 12 >> 2] | 0, 10536);
+   } else {
+    HEAP8[i9] = i5;
+    i4 = HEAP8[i7] | 0;
+    break;
+   }
+  } else {
+   i4 = i10;
+  }
+ } while (0);
+ HEAP8[i7] = (i4 & 255) + 2;
+ i10 = HEAP32[i6 >> 2] | 0;
+ _luaK_code(i2, i8 << 23 | i10 << 6 | (_luaK_exp2RK(i2, i3) | 0) << 14 | 12) | 0;
+ if ((HEAP32[i3 >> 2] | 0) != 6) {
+  STACKTOP = i1;
+  return;
+ }
+ i3 = HEAP32[i3 + 8 >> 2] | 0;
+ if ((i3 & 256 | 0) != 0) {
+  STACKTOP = i1;
+  return;
+ }
+ if ((HEAPU8[i2 + 46 | 0] | 0 | 0) > (i3 | 0)) {
+  STACKTOP = i1;
+  return;
+ }
+ HEAP8[i7] = (HEAP8[i7] | 0) + -1 << 24 >> 24;
+ STACKTOP = i1;
+ return;
+}
+function _luaD_rawrunprotected(i10, i9, i11) {
+ i10 = i10 | 0;
+ i9 = i9 | 0;
+ i11 = i11 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i12 = 0, i13 = 0;
+ i7 = STACKTOP;
+ STACKTOP = STACKTOP + 176 | 0;
+ i8 = STACKTOP;
+ STACKTOP = STACKTOP + 168 | 0;
+ HEAP32[i8 >> 2] = 0;
+ i6 = i7;
+ i5 = i10 + 38 | 0;
+ i4 = HEAP16[i5 >> 1] | 0;
+ i1 = i6 + 160 | 0;
+ HEAP32[i1 >> 2] = 0;
+ i3 = i10 + 64 | 0;
+ HEAP32[i6 >> 2] = HEAP32[i3 >> 2];
+ HEAP32[i3 >> 2] = i6;
+ _saveSetjmp(i6 + 4 | 0, 1, i8 | 0) | 0;
+ __THREW__ = 0;
+ i13 = __THREW__;
+ __THREW__ = 0;
+ if ((i13 | 0) != 0 & (threwValue | 0) != 0) {
+  i12 = _testSetjmp(HEAP32[i13 >> 2] | 0, i8) | 0;
+  if ((i12 | 0) == 0) {
+   _longjmp(i13 | 0, threwValue | 0);
+  }
+  tempRet0 = threwValue;
+ } else {
+  i12 = -1;
+ }
+ if ((i12 | 0) == 1) {
+  i12 = tempRet0;
+ } else {
+  i12 = 0;
+ }
+ while (1) {
+  if ((i12 | 0) != 0) {
+   i2 = 6;
+   break;
+  }
+  __THREW__ = 0;
+  invoke_vii(i9 | 0, i10 | 0, i11 | 0);
+  i13 = __THREW__;
+  __THREW__ = 0;
+  if ((i13 | 0) != 0 & (threwValue | 0) != 0) {
+   i12 = _testSetjmp(HEAP32[i13 >> 2] | 0, i8) | 0;
+   if ((i12 | 0) == 0) {
+    _longjmp(i13 | 0, threwValue | 0);
+   }
+   tempRet0 = threwValue;
+  } else {
+   i12 = -1;
+  }
+  if ((i12 | 0) == 1) {
+   i12 = tempRet0;
+  } else {
+   break;
+  }
+ }
+ if ((i2 | 0) == 6) {
+  i13 = HEAP32[i6 >> 2] | 0;
+  HEAP32[i3 >> 2] = i13;
+  HEAP16[i5 >> 1] = i4;
+  i13 = HEAP32[i1 >> 2] | 0;
+  STACKTOP = i7;
+  return i13 | 0;
+ }
+ i13 = HEAP32[i6 >> 2] | 0;
+ HEAP32[i3 >> 2] = i13;
+ HEAP16[i5 >> 1] = i4;
+ i13 = HEAP32[i1 >> 2] | 0;
+ STACKTOP = i7;
+ return i13 | 0;
+}
+function _luaB_tonumber(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, d6 = 0.0, i7 = 0, d8 = 0.0, i9 = 0, i10 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2 + 4 | 0;
+ i4 = i2;
+ do {
+  if ((_lua_type(i1, 2) | 0) >= 1) {
+   i9 = _luaL_checklstring(i1, 1, i4) | 0;
+   i3 = i9 + (HEAP32[i4 >> 2] | 0) | 0;
+   i5 = _luaL_checkinteger(i1, 2) | 0;
+   if (!((i5 + -2 | 0) >>> 0 < 35)) {
+    _luaL_argerror(i1, 2, 9648) | 0;
+   }
+   i10 = _strspn(i9, 9672) | 0;
+   i7 = i9 + i10 | 0;
+   i4 = HEAP8[i7] | 0;
+   if (i4 << 24 >> 24 == 43) {
+    i4 = 0;
+    i7 = i9 + (i10 + 1) | 0;
+   } else if (i4 << 24 >> 24 == 45) {
+    i4 = 1;
+    i7 = i9 + (i10 + 1) | 0;
+   } else {
+    i4 = 0;
+   }
+   if ((_isalnum(HEAPU8[i7] | 0 | 0) | 0) != 0) {
+    d6 = +(i5 | 0);
+    d8 = 0.0;
+    do {
+     i9 = HEAP8[i7] | 0;
+     i10 = i9 & 255;
+     if ((i10 + -48 | 0) >>> 0 < 10) {
+      i9 = (i9 << 24 >> 24) + -48 | 0;
+     } else {
+      i9 = (_toupper(i10 | 0) | 0) + -55 | 0;
+     }
+     if ((i9 | 0) >= (i5 | 0)) {
+      break;
+     }
+     d8 = d6 * d8 + +(i9 | 0);
+     i7 = i7 + 1 | 0;
+    } while ((_isalnum(HEAPU8[i7] | 0 | 0) | 0) != 0);
+    if ((i7 + (_strspn(i7, 9672) | 0) | 0) == (i3 | 0)) {
+     if ((i4 | 0) != 0) {
+      d8 = -d8;
+     }
+     _lua_pushnumber(i1, d8);
+     STACKTOP = i2;
+     return 1;
+    }
+   }
+  } else {
+   d6 = +_lua_tonumberx(i1, 1, i3);
+   if ((HEAP32[i3 >> 2] | 0) == 0) {
+    _luaL_checkany(i1, 1);
+    break;
+   }
+   _lua_pushnumber(i1, d6);
+   STACKTOP = i2;
+   return 1;
+  }
+ } while (0);
+ _lua_pushnil(i1);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaK_storevar(i1, i5, i3) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ i7 = HEAP32[i5 >> 2] | 0;
+ if ((i7 | 0) == 7) {
+  if (((HEAP32[i3 >> 2] | 0) == 6 ? (i6 = HEAP32[i3 + 8 >> 2] | 0, (i6 & 256 | 0) == 0) : 0) ? (HEAPU8[i1 + 46 | 0] | 0) <= (i6 | 0) : 0) {
+   i7 = i1 + 48 | 0;
+   HEAP8[i7] = (HEAP8[i7] | 0) + -1 << 24 >> 24;
+  }
+  _exp2reg(i1, i3, HEAP32[i5 + 8 >> 2] | 0);
+  STACKTOP = i2;
+  return;
+ } else if ((i7 | 0) == 9) {
+  i4 = i5 + 8 | 0;
+  i7 = (HEAP8[i4 + 3 | 0] | 0) == 7 ? 10 : 8;
+  i6 = _luaK_exp2RK(i1, i3) | 0;
+  _luaK_code(i1, i6 << 14 | i7 | HEAPU8[i4 + 2 | 0] << 6 | HEAPU16[i4 >> 1] << 23) | 0;
+ } else if ((i7 | 0) == 8) {
+  _luaK_dischargevars(i1, i3);
+  if ((HEAP32[i3 >> 2] | 0) == 6) {
+   i6 = i3 + 8 | 0;
+   i7 = HEAP32[i6 >> 2] | 0;
+   if ((HEAP32[i3 + 16 >> 2] | 0) != (HEAP32[i3 + 20 >> 2] | 0)) {
+    if ((i7 | 0) < (HEAPU8[i1 + 46 | 0] | 0)) {
+     i4 = 12;
+    } else {
+     _exp2reg(i1, i3, i7);
+     i7 = HEAP32[i6 >> 2] | 0;
+    }
+   }
+  } else {
+   i6 = i3 + 8 | 0;
+   i4 = 12;
+  }
+  if ((i4 | 0) == 12) {
+   _luaK_exp2nextreg(i1, i3);
+   i7 = HEAP32[i6 >> 2] | 0;
+  }
+  _luaK_code(i1, i7 << 6 | HEAP32[i5 + 8 >> 2] << 23 | 9) | 0;
+ }
+ if ((HEAP32[i3 >> 2] | 0) != 6) {
+  STACKTOP = i2;
+  return;
+ }
+ i3 = HEAP32[i3 + 8 >> 2] | 0;
+ if ((i3 & 256 | 0) != 0) {
+  STACKTOP = i2;
+  return;
+ }
+ if ((HEAPU8[i1 + 46 | 0] | 0) > (i3 | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ i7 = i1 + 48 | 0;
+ HEAP8[i7] = (HEAP8[i7] | 0) + -1 << 24 >> 24;
+ STACKTOP = i2;
+ return;
+}
+function _closegoto(i10, i3, i9) {
+ i10 = i10 | 0;
+ i3 = i3 | 0;
+ i9 = i9 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i11 = 0, i12 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i7 = i1;
+ i4 = HEAP32[i10 + 48 >> 2] | 0;
+ i6 = HEAP32[i10 + 64 >> 2] | 0;
+ i2 = i6 + 12 | 0;
+ i5 = HEAP32[i2 >> 2] | 0;
+ i8 = HEAP8[i5 + (i3 << 4) + 12 | 0] | 0;
+ if ((i8 & 255) < (HEAPU8[i9 + 12 | 0] | 0)) {
+  i11 = HEAP32[i10 + 52 >> 2] | 0;
+  i12 = HEAP32[i5 + (i3 << 4) + 8 >> 2] | 0;
+  i8 = (HEAP32[(HEAP32[(HEAP32[i4 >> 2] | 0) + 24 >> 2] | 0) + ((HEAP16[(HEAP32[HEAP32[(HEAP32[i4 + 12 >> 2] | 0) + 64 >> 2] >> 2] | 0) + ((HEAP32[i4 + 40 >> 2] | 0) + (i8 & 255) << 1) >> 1] | 0) * 12 | 0) >> 2] | 0) + 16 | 0;
+  HEAP32[i7 >> 2] = (HEAP32[i5 + (i3 << 4) >> 2] | 0) + 16;
+  HEAP32[i7 + 4 >> 2] = i12;
+  HEAP32[i7 + 8 >> 2] = i8;
+  _semerror(i10, _luaO_pushfstring(i11, 6248, i7) | 0);
+ }
+ _luaK_patchlist(i4, HEAP32[i5 + (i3 << 4) + 4 >> 2] | 0, HEAP32[i9 + 4 >> 2] | 0);
+ i4 = i6 + 16 | 0;
+ i5 = (HEAP32[i4 >> 2] | 0) + -1 | 0;
+ if ((i5 | 0) <= (i3 | 0)) {
+  i12 = i5;
+  HEAP32[i4 >> 2] = i12;
+  STACKTOP = i1;
+  return;
+ }
+ do {
+  i12 = HEAP32[i2 >> 2] | 0;
+  i5 = i12 + (i3 << 4) | 0;
+  i3 = i3 + 1 | 0;
+  i12 = i12 + (i3 << 4) | 0;
+  HEAP32[i5 + 0 >> 2] = HEAP32[i12 + 0 >> 2];
+  HEAP32[i5 + 4 >> 2] = HEAP32[i12 + 4 >> 2];
+  HEAP32[i5 + 8 >> 2] = HEAP32[i12 + 8 >> 2];
+  HEAP32[i5 + 12 >> 2] = HEAP32[i12 + 12 >> 2];
+  i5 = (HEAP32[i4 >> 2] | 0) + -1 | 0;
+ } while ((i3 | 0) < (i5 | 0));
+ HEAP32[i4 >> 2] = i5;
+ STACKTOP = i1;
+ return;
+}
+function _luaM_growaux_(i4, i5, i1, i7, i8, i9) {
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ i7 = i7 | 0;
+ i8 = i8 | 0;
+ i9 = i9 | 0;
+ var i2 = 0, i3 = 0, i6 = 0, i10 = 0, i11 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i10 = i2;
+ i6 = HEAP32[i1 >> 2] | 0;
+ if ((i6 | 0) >= ((i8 | 0) / 2 | 0 | 0)) {
+  if ((i6 | 0) < (i8 | 0)) {
+   i3 = i8;
+  } else {
+   HEAP32[i10 >> 2] = i9;
+   HEAP32[i10 + 4 >> 2] = i8;
+   _luaG_runerror(i4, 4112, i10);
+  }
+ } else {
+  i3 = i6 << 1;
+  i3 = (i3 | 0) < 4 ? 4 : i3;
+ }
+ if ((i3 + 1 | 0) >>> 0 > (4294967293 / (i7 >>> 0) | 0) >>> 0) {
+  _luaM_toobig(i4);
+ }
+ i6 = Math_imul(i6, i7) | 0;
+ i8 = Math_imul(i3, i7) | 0;
+ i9 = HEAP32[i4 + 12 >> 2] | 0;
+ i7 = (i5 | 0) != 0;
+ i11 = i9 + 4 | 0;
+ i10 = FUNCTION_TABLE_iiiii[HEAP32[i9 >> 2] & 3](HEAP32[i11 >> 2] | 0, i5, i6, i8) | 0;
+ if ((i10 | 0) != 0 | (i8 | 0) == 0) {
+  i5 = i9 + 12 | 0;
+  i4 = HEAP32[i5 >> 2] | 0;
+  i6 = 0 - i6 | 0;
+  i11 = i7 ? i6 : 0;
+  i11 = i11 + i8 | 0;
+  i11 = i11 + i4 | 0;
+  HEAP32[i5 >> 2] = i11;
+  HEAP32[i1 >> 2] = i3;
+  STACKTOP = i2;
+  return i10 | 0;
+ }
+ if ((HEAP8[i9 + 63 | 0] | 0) == 0) {
+  _luaD_throw(i4, 4);
+ }
+ _luaC_fullgc(i4, 1);
+ i10 = FUNCTION_TABLE_iiiii[HEAP32[i9 >> 2] & 3](HEAP32[i11 >> 2] | 0, i5, i6, i8) | 0;
+ if ((i10 | 0) == 0) {
+  _luaD_throw(i4, 4);
+ } else {
+  i5 = i9 + 12 | 0;
+  i4 = HEAP32[i5 >> 2] | 0;
+  i6 = 0 - i6 | 0;
+  i11 = i7 ? i6 : 0;
+  i11 = i11 + i8 | 0;
+  i11 = i11 + i4 | 0;
+  HEAP32[i5 >> 2] = i11;
+  HEAP32[i1 >> 2] = i3;
+  STACKTOP = i2;
+  return i10 | 0;
+ }
+ return 0;
+}
+function _luaD_hook(i5, i14, i13) {
+ i5 = i5 | 0;
+ i14 = i14 | 0;
+ i13 = i13 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i15 = 0, i16 = 0;
+ i11 = STACKTOP;
+ STACKTOP = STACKTOP + 112 | 0;
+ i4 = i11;
+ i3 = HEAP32[i5 + 52 >> 2] | 0;
+ if ((i3 | 0) == 0) {
+  STACKTOP = i11;
+  return;
+ }
+ i8 = i5 + 41 | 0;
+ if ((HEAP8[i8] | 0) == 0) {
+  STACKTOP = i11;
+  return;
+ }
+ i10 = HEAP32[i5 + 16 >> 2] | 0;
+ i6 = i5 + 8 | 0;
+ i15 = HEAP32[i6 >> 2] | 0;
+ i1 = i5 + 28 | 0;
+ i16 = i15;
+ i12 = HEAP32[i1 >> 2] | 0;
+ i7 = i16 - i12 | 0;
+ i9 = i10 + 4 | 0;
+ i12 = (HEAP32[i9 >> 2] | 0) - i12 | 0;
+ HEAP32[i4 >> 2] = i14;
+ HEAP32[i4 + 20 >> 2] = i13;
+ HEAP32[i4 + 96 >> 2] = i10;
+ do {
+  if (((HEAP32[i5 + 24 >> 2] | 0) - i16 | 0) < 336) {
+   i14 = HEAP32[i5 + 32 >> 2] | 0;
+   if ((i14 | 0) > 1e6) {
+    _luaD_throw(i5, 6);
+   }
+   i13 = (i7 >> 4) + 25 | 0;
+   i14 = i14 << 1;
+   i14 = (i14 | 0) > 1e6 ? 1e6 : i14;
+   i13 = (i14 | 0) < (i13 | 0) ? i13 : i14;
+   if ((i13 | 0) > 1e6) {
+    _luaD_reallocstack(i5, 1000200);
+    _luaG_runerror(i5, 2224, i4);
+   } else {
+    _luaD_reallocstack(i5, i13);
+    i2 = HEAP32[i6 >> 2] | 0;
+    break;
+   }
+  } else {
+   i2 = i15;
+  }
+ } while (0);
+ HEAP32[i9 >> 2] = i2 + 320;
+ HEAP8[i8] = 0;
+ i16 = i10 + 18 | 0;
+ HEAP8[i16] = HEAPU8[i16] | 2;
+ FUNCTION_TABLE_vii[i3 & 15](i5, i4);
+ HEAP8[i8] = 1;
+ HEAP32[i9 >> 2] = (HEAP32[i1 >> 2] | 0) + i12;
+ HEAP32[i6 >> 2] = (HEAP32[i1 >> 2] | 0) + i7;
+ HEAP8[i16] = HEAP8[i16] & 253;
+ STACKTOP = i11;
+ return;
+}
+function _funcargs(i10, i2, i1) {
+ i10 = i10 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i6 = i3;
+ i9 = i10 + 48 | 0;
+ i5 = HEAP32[i9 >> 2] | 0;
+ i7 = i10 + 16 | 0;
+ i8 = HEAP32[i7 >> 2] | 0;
+ if ((i8 | 0) == 289) {
+  i9 = _luaK_stringK(i5, HEAP32[i10 + 24 >> 2] | 0) | 0;
+  HEAP32[i6 + 16 >> 2] = -1;
+  HEAP32[i6 + 20 >> 2] = -1;
+  HEAP32[i6 >> 2] = 4;
+  HEAP32[i6 + 8 >> 2] = i9;
+  _luaX_next(i10);
+ } else if ((i8 | 0) == 40) {
+  _luaX_next(i10);
+  if ((HEAP32[i7 >> 2] | 0) == 41) {
+   HEAP32[i6 >> 2] = 0;
+  } else {
+   _subexpr(i10, i6, 0) | 0;
+   if ((HEAP32[i7 >> 2] | 0) == 44) {
+    do {
+     _luaX_next(i10);
+     _luaK_exp2nextreg(HEAP32[i9 >> 2] | 0, i6);
+     _subexpr(i10, i6, 0) | 0;
+    } while ((HEAP32[i7 >> 2] | 0) == 44);
+   }
+   _luaK_setreturns(i5, i6, -1);
+  }
+  _check_match(i10, 41, 40, i1);
+ } else if ((i8 | 0) == 123) {
+  _constructor(i10, i6);
+ } else {
+  _luaX_syntaxerror(i10, 6624);
+ }
+ i8 = i2 + 8 | 0;
+ i7 = HEAP32[i8 >> 2] | 0;
+ i9 = HEAP32[i6 >> 2] | 0;
+ if ((i9 | 0) == 0) {
+  i4 = 13;
+ } else if ((i9 | 0) == 13 | (i9 | 0) == 12) {
+  i6 = 0;
+ } else {
+  _luaK_exp2nextreg(i5, i6);
+  i4 = 13;
+ }
+ if ((i4 | 0) == 13) {
+  i6 = (HEAPU8[i5 + 48 | 0] | 0) - i7 | 0;
+ }
+ i10 = _luaK_codeABC(i5, 29, i7, i6, 2) | 0;
+ HEAP32[i2 + 16 >> 2] = -1;
+ HEAP32[i2 + 20 >> 2] = -1;
+ HEAP32[i2 >> 2] = 12;
+ HEAP32[i8 >> 2] = i10;
+ _luaK_fixline(i5, i1);
+ HEAP8[i5 + 48 | 0] = i7 + 1;
+ STACKTOP = i3;
+ return;
+}
+function _luaD_reallocstack(i3, i6) {
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i1 = STACKTOP;
+ i2 = i3 + 28 | 0;
+ i8 = HEAP32[i2 >> 2] | 0;
+ i7 = i3 + 32 | 0;
+ i9 = HEAP32[i7 >> 2] | 0;
+ if ((i6 + 1 | 0) >>> 0 > 268435455) {
+  _luaM_toobig(i3);
+ }
+ i5 = _luaM_realloc_(i3, i8, i9 << 4, i6 << 4) | 0;
+ HEAP32[i2 >> 2] = i5;
+ if ((i9 | 0) < (i6 | 0)) {
+  do {
+   HEAP32[i5 + (i9 << 4) + 8 >> 2] = 0;
+   i9 = i9 + 1 | 0;
+  } while ((i9 | 0) != (i6 | 0));
+ }
+ HEAP32[i7 >> 2] = i6;
+ HEAP32[i3 + 24 >> 2] = i5 + (i6 + -5 << 4);
+ i6 = i3 + 8 | 0;
+ HEAP32[i6 >> 2] = i5 + ((HEAP32[i6 >> 2] | 0) - i8 >> 4 << 4);
+ i6 = HEAP32[i3 + 56 >> 2] | 0;
+ if ((i6 | 0) != 0 ? (i4 = i6 + 8 | 0, HEAP32[i4 >> 2] = i5 + ((HEAP32[i4 >> 2] | 0) - i8 >> 4 << 4), i4 = HEAP32[i6 >> 2] | 0, (i4 | 0) != 0) : 0) {
+  do {
+   i9 = i4 + 8 | 0;
+   HEAP32[i9 >> 2] = (HEAP32[i2 >> 2] | 0) + ((HEAP32[i9 >> 2] | 0) - i8 >> 4 << 4);
+   i4 = HEAP32[i4 >> 2] | 0;
+  } while ((i4 | 0) != 0);
+ }
+ i3 = HEAP32[i3 + 16 >> 2] | 0;
+ if ((i3 | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ do {
+  i9 = i3 + 4 | 0;
+  HEAP32[i9 >> 2] = (HEAP32[i2 >> 2] | 0) + ((HEAP32[i9 >> 2] | 0) - i8 >> 4 << 4);
+  HEAP32[i3 >> 2] = (HEAP32[i2 >> 2] | 0) + ((HEAP32[i3 >> 2] | 0) - i8 >> 4 << 4);
+  if (!((HEAP8[i3 + 18 | 0] & 1) == 0)) {
+   i9 = i3 + 24 | 0;
+   HEAP32[i9 >> 2] = (HEAP32[i2 >> 2] | 0) + ((HEAP32[i9 >> 2] | 0) - i8 >> 4 << 4);
+  }
+  i3 = HEAP32[i3 + 8 >> 2] | 0;
+ } while ((i3 | 0) != 0);
+ STACKTOP = i1;
+ return;
+}
+function _luaF_close(i7, i6) {
+ i7 = i7 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0;
+ i1 = STACKTOP;
+ i4 = HEAP32[i7 + 12 >> 2] | 0;
+ i3 = i7 + 56 | 0;
+ i8 = HEAP32[i3 >> 2] | 0;
+ if ((i8 | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i5 = i4 + 60 | 0;
+ i2 = i4 + 68 | 0;
+ while (1) {
+  i9 = i8 + 8 | 0;
+  if ((HEAP32[i9 >> 2] | 0) >>> 0 < i6 >>> 0) {
+   i2 = 10;
+   break;
+  }
+  HEAP32[i3 >> 2] = HEAP32[i8 >> 2];
+  if ((((HEAPU8[i5] | 0) ^ 3) & ((HEAPU8[i8 + 5 | 0] | 0) ^ 3) | 0) == 0) {
+   if ((HEAP32[i9 >> 2] | 0) != (i8 + 16 | 0)) {
+    i9 = i8 + 16 | 0;
+    i10 = i9 + 4 | 0;
+    HEAP32[(HEAP32[i10 >> 2] | 0) + 16 >> 2] = HEAP32[i9 >> 2];
+    HEAP32[(HEAP32[i9 >> 2] | 0) + 20 >> 2] = HEAP32[i10 >> 2];
+   }
+   _luaM_realloc_(i7, i8, 32, 0) | 0;
+  } else {
+   i11 = i8 + 16 | 0;
+   i10 = i11 + 4 | 0;
+   HEAP32[(HEAP32[i10 >> 2] | 0) + 16 >> 2] = HEAP32[i11 >> 2];
+   HEAP32[(HEAP32[i11 >> 2] | 0) + 20 >> 2] = HEAP32[i10 >> 2];
+   i11 = HEAP32[i9 >> 2] | 0;
+   i10 = i8 + 16 | 0;
+   i14 = i11;
+   i13 = HEAP32[i14 + 4 >> 2] | 0;
+   i12 = i10;
+   HEAP32[i12 >> 2] = HEAP32[i14 >> 2];
+   HEAP32[i12 + 4 >> 2] = i13;
+   HEAP32[i8 + 24 >> 2] = HEAP32[i11 + 8 >> 2];
+   HEAP32[i9 >> 2] = i10;
+   HEAP32[i8 >> 2] = HEAP32[i2 >> 2];
+   HEAP32[i2 >> 2] = i8;
+   _luaC_checkupvalcolor(i4, i8);
+  }
+  i8 = HEAP32[i3 >> 2] | 0;
+  if ((i8 | 0) == 0) {
+   i2 = 10;
+   break;
+  }
+ }
+ if ((i2 | 0) == 10) {
+  STACKTOP = i1;
+  return;
+ }
+}
+function _luaK_dischargevars(i3, i1) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ switch (HEAP32[i1 >> 2] | 0) {
+ case 12:
+  {
+   HEAP32[i1 >> 2] = 6;
+   i6 = i1 + 8 | 0;
+   HEAP32[i6 >> 2] = (HEAP32[(HEAP32[(HEAP32[i3 >> 2] | 0) + 12 >> 2] | 0) + (HEAP32[i6 >> 2] << 2) >> 2] | 0) >>> 6 & 255;
+   STACKTOP = i2;
+   return;
+  }
+ case 13:
+  {
+   i6 = (HEAP32[(HEAP32[i3 >> 2] | 0) + 12 >> 2] | 0) + (HEAP32[i1 + 8 >> 2] << 2) | 0;
+   HEAP32[i6 >> 2] = HEAP32[i6 >> 2] & 8388607 | 16777216;
+   HEAP32[i1 >> 2] = 11;
+   STACKTOP = i2;
+   return;
+  }
+ case 9:
+  {
+   i4 = i1 + 8 | 0;
+   i5 = HEAP16[i4 >> 1] | 0;
+   if ((i5 & 256 | 0) == 0 ? (HEAPU8[i3 + 46 | 0] | 0) <= (i5 | 0) : 0) {
+    i6 = i3 + 48 | 0;
+    HEAP8[i6] = (HEAP8[i6] | 0) + -1 << 24 >> 24;
+   }
+   i5 = i4 + 2 | 0;
+   if ((HEAP8[i4 + 3 | 0] | 0) == 7) {
+    if ((HEAPU8[i3 + 46 | 0] | 0) > (HEAPU8[i5] | 0)) {
+     i6 = 7;
+    } else {
+     i6 = i3 + 48 | 0;
+     HEAP8[i6] = (HEAP8[i6] | 0) + -1 << 24 >> 24;
+     i6 = 7;
+    }
+   } else {
+    i6 = 6;
+   }
+   HEAP32[i4 >> 2] = _luaK_code(i3, HEAPU8[i5] << 23 | i6 | HEAP16[i4 >> 1] << 14) | 0;
+   HEAP32[i1 >> 2] = 11;
+   STACKTOP = i2;
+   return;
+  }
+ case 7:
+  {
+   HEAP32[i1 >> 2] = 6;
+   STACKTOP = i2;
+   return;
+  }
+ case 8:
+  {
+   i6 = i1 + 8 | 0;
+   HEAP32[i6 >> 2] = _luaK_code(i3, HEAP32[i6 >> 2] << 23 | 5) | 0;
+   HEAP32[i1 >> 2] = 11;
+   STACKTOP = i2;
+   return;
+  }
+ default:
+  {
+   STACKTOP = i2;
+   return;
+  }
+ }
+}
+function _gmatch_aux(i10) {
+ i10 = i10 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i11 = 0, i12 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 288 | 0;
+ i2 = i1 + 8 | 0;
+ i12 = i1 + 4 | 0;
+ i3 = i1;
+ i8 = _lua_tolstring(i10, -1001001, i12) | 0;
+ i7 = _lua_tolstring(i10, -1001002, i3) | 0;
+ i5 = i2 + 16 | 0;
+ HEAP32[i5 >> 2] = i10;
+ HEAP32[i2 >> 2] = 200;
+ HEAP32[i2 + 4 >> 2] = i8;
+ i9 = i2 + 8 | 0;
+ HEAP32[i9 >> 2] = i8 + (HEAP32[i12 >> 2] | 0);
+ HEAP32[i2 + 12 >> 2] = i7 + (HEAP32[i3 >> 2] | 0);
+ i3 = i8 + (_lua_tointegerx(i10, -1001003, 0) | 0) | 0;
+ if (i3 >>> 0 > (HEAP32[i9 >> 2] | 0) >>> 0) {
+  i12 = 0;
+  STACKTOP = i1;
+  return i12 | 0;
+ }
+ i11 = i2 + 20 | 0;
+ while (1) {
+  HEAP32[i11 >> 2] = 0;
+  i4 = _match(i2, i3, i7) | 0;
+  i12 = i3 + 1 | 0;
+  if ((i4 | 0) != 0) {
+   break;
+  }
+  if (i12 >>> 0 > (HEAP32[i9 >> 2] | 0) >>> 0) {
+   i2 = 0;
+   i6 = 7;
+   break;
+  } else {
+   i3 = i12;
+  }
+ }
+ if ((i6 | 0) == 7) {
+  STACKTOP = i1;
+  return i2 | 0;
+ }
+ _lua_pushinteger(i10, i4 - i8 + ((i4 | 0) == (i3 | 0)) | 0);
+ _lua_replace(i10, -1001003);
+ i7 = HEAP32[i11 >> 2] | 0;
+ i6 = (i7 | 0) != 0 | (i3 | 0) == 0 ? i7 : 1;
+ _luaL_checkstack(HEAP32[i5 >> 2] | 0, i6, 7200);
+ if ((i6 | 0) > 0) {
+  i5 = 0;
+ } else {
+  i12 = i7;
+  STACKTOP = i1;
+  return i12 | 0;
+ }
+ while (1) {
+  _push_onecapture(i2, i5, i3, i4);
+  i5 = i5 + 1 | 0;
+  if ((i5 | 0) == (i6 | 0)) {
+   i2 = i6;
+   break;
+  }
+ }
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _lua_rawseti(i1, i5, i3) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i6 = 0;
+ i2 = STACKTOP;
+ i6 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i5 = (HEAP32[i1 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i5 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i5 | 0;
+   i6 = HEAP32[i6 >> 2] | 0;
+   if ((HEAP32[i6 + 8 >> 2] | 0) != 22 ? (i4 = HEAP32[i6 >> 2] | 0, (i5 | 0) <= (HEAPU8[i4 + 6 | 0] | 0 | 0)) : 0) {
+    i5 = i4 + (i5 + -1 << 4) + 16 | 0;
+   } else {
+    i5 = 5192;
+   }
+  } else {
+   i4 = (HEAP32[i6 >> 2] | 0) + (i5 << 4) | 0;
+   i5 = i4 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i4 : 5192;
+  }
+ } while (0);
+ i4 = i1 + 8 | 0;
+ _luaH_setint(i1, HEAP32[i5 >> 2] | 0, i3, (HEAP32[i4 >> 2] | 0) + -16 | 0);
+ i3 = HEAP32[i4 >> 2] | 0;
+ if ((HEAP32[i3 + -8 >> 2] & 64 | 0) == 0) {
+  i6 = i3;
+  i6 = i6 + -16 | 0;
+  HEAP32[i4 >> 2] = i6;
+  STACKTOP = i2;
+  return;
+ }
+ if ((HEAP8[(HEAP32[i3 + -16 >> 2] | 0) + 5 | 0] & 3) == 0) {
+  i6 = i3;
+  i6 = i6 + -16 | 0;
+  HEAP32[i4 >> 2] = i6;
+  STACKTOP = i2;
+  return;
+ }
+ i5 = HEAP32[i5 >> 2] | 0;
+ if ((HEAP8[i5 + 5 | 0] & 4) == 0) {
+  i6 = i3;
+  i6 = i6 + -16 | 0;
+  HEAP32[i4 >> 2] = i6;
+  STACKTOP = i2;
+  return;
+ }
+ _luaC_barrierback_(i1, i5);
+ i6 = HEAP32[i4 >> 2] | 0;
+ i6 = i6 + -16 | 0;
+ HEAP32[i4 >> 2] = i6;
+ STACKTOP = i2;
+ return;
+}
+function _ll_require(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 1056 | 0;
+ i5 = i2;
+ i4 = i2 + 8 | 0;
+ i3 = _luaL_checklstring(i1, 1, 0) | 0;
+ _lua_settop(i1, 1);
+ _lua_getfield(i1, -1001e3, 4576);
+ _lua_getfield(i1, 2, i3);
+ if ((_lua_toboolean(i1, -1) | 0) != 0) {
+  STACKTOP = i2;
+  return 1;
+ }
+ _lua_settop(i1, -2);
+ _luaL_buffinit(i1, i4);
+ _lua_getfield(i1, -1001001, 4240);
+ if ((_lua_type(i1, 3) | 0) == 5) {
+  i6 = 1;
+ } else {
+  _luaL_error(i1, 4656, i5) | 0;
+  i6 = 1;
+ }
+ while (1) {
+  _lua_rawgeti(i1, 3, i6);
+  if ((_lua_type(i1, -1) | 0) == 0) {
+   _lua_settop(i1, -2);
+   _luaL_pushresult(i4);
+   i7 = _lua_tolstring(i1, -1, 0) | 0;
+   HEAP32[i5 >> 2] = i3;
+   HEAP32[i5 + 4 >> 2] = i7;
+   _luaL_error(i1, 4696, i5) | 0;
+  }
+  _lua_pushstring(i1, i3) | 0;
+  _lua_callk(i1, 1, 2, 0, 0);
+  if ((_lua_type(i1, -2) | 0) == 6) {
+   break;
+  }
+  if ((_lua_isstring(i1, -2) | 0) == 0) {
+   _lua_settop(i1, -3);
+  } else {
+   _lua_settop(i1, -2);
+   _luaL_addvalue(i4);
+  }
+  i6 = i6 + 1 | 0;
+ }
+ _lua_pushstring(i1, i3) | 0;
+ _lua_insert(i1, -2);
+ _lua_callk(i1, 2, 1, 0, 0);
+ if ((_lua_type(i1, -1) | 0) != 0) {
+  _lua_setfield(i1, 2, i3);
+ }
+ _lua_getfield(i1, 2, i3);
+ if ((_lua_type(i1, -1) | 0) != 0) {
+  STACKTOP = i2;
+  return 1;
+ }
+ _lua_pushboolean(i1, 1);
+ _lua_pushvalue(i1, -1);
+ _lua_setfield(i1, 2, i3);
+ STACKTOP = i2;
+ return 1;
+}
+function _f_parser(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ i5 = HEAP32[i3 >> 2] | 0;
+ i8 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i5 >> 2] = i8 + -1;
+ if ((i8 | 0) == 0) {
+  i6 = _luaZ_fill(i5) | 0;
+ } else {
+  i8 = i5 + 4 | 0;
+  i6 = HEAP32[i8 >> 2] | 0;
+  HEAP32[i8 >> 2] = i6 + 1;
+  i6 = HEAPU8[i6] | 0;
+ }
+ i5 = HEAP32[i3 + 52 >> 2] | 0;
+ i7 = (i5 | 0) == 0;
+ if ((i6 | 0) == 27) {
+  if (!i7 ? (_strchr(i5, 98) | 0) == 0 : 0) {
+   HEAP32[i4 >> 2] = 2360;
+   HEAP32[i4 + 4 >> 2] = i5;
+   _luaO_pushfstring(i1, 2376, i4) | 0;
+   _luaD_throw(i1, 3);
+  }
+  i8 = _luaU_undump(i1, HEAP32[i3 >> 2] | 0, i3 + 4 | 0, HEAP32[i3 + 56 >> 2] | 0) | 0;
+ } else {
+  if (!i7 ? (_strchr(i5, 116) | 0) == 0 : 0) {
+   HEAP32[i4 >> 2] = 2368;
+   HEAP32[i4 + 4 >> 2] = i5;
+   _luaO_pushfstring(i1, 2376, i4) | 0;
+   _luaD_throw(i1, 3);
+  }
+  i8 = _luaY_parser(i1, HEAP32[i3 >> 2] | 0, i3 + 4 | 0, i3 + 16 | 0, HEAP32[i3 + 56 >> 2] | 0, i6) | 0;
+ }
+ i7 = i8 + 6 | 0;
+ if ((HEAP8[i7] | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ i5 = i8 + 16 | 0;
+ i6 = i8 + 5 | 0;
+ i4 = 0;
+ do {
+  i3 = _luaF_newupval(i1) | 0;
+  HEAP32[i5 + (i4 << 2) >> 2] = i3;
+  if (!((HEAP8[i3 + 5 | 0] & 3) == 0) ? !((HEAP8[i6] & 4) == 0) : 0) {
+   _luaC_barrier_(i1, i8, i3);
+  }
+  i4 = i4 + 1 | 0;
+ } while ((i4 | 0) < (HEAPU8[i7] | 0));
+ STACKTOP = i2;
+ return;
+}
+function _str_rep(i9) {
+ i9 = i9 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i10 = 0, i11 = 0, i12 = 0;
+ i6 = STACKTOP;
+ STACKTOP = STACKTOP + 1056 | 0;
+ i4 = i6;
+ i2 = i6 + 1044 | 0;
+ i3 = i6 + 1040 | 0;
+ i1 = _luaL_checklstring(i9, 1, i2) | 0;
+ i8 = _luaL_checkinteger(i9, 2) | 0;
+ i5 = _luaL_optlstring(i9, 3, 7040, i3) | 0;
+ if ((i8 | 0) < 1) {
+  _lua_pushlstring(i9, 7040, 0) | 0;
+  i12 = 1;
+  STACKTOP = i6;
+  return i12 | 0;
+ }
+ i7 = HEAP32[i2 >> 2] | 0;
+ i10 = HEAP32[i3 >> 2] | 0;
+ i11 = i10 + i7 | 0;
+ if (!(i11 >>> 0 < i7 >>> 0) ? i11 >>> 0 < (2147483647 / (i8 >>> 0) | 0) >>> 0 : 0) {
+  i7 = (Math_imul(i10, i8 + -1 | 0) | 0) + (Math_imul(i7, i8) | 0) | 0;
+  i11 = _luaL_buffinitsize(i9, i4, i7) | 0;
+  _memcpy(i11 | 0, i1 | 0, HEAP32[i2 >> 2] | 0) | 0;
+  if ((i8 | 0) > 1) {
+   while (1) {
+    i8 = i8 + -1 | 0;
+    i9 = HEAP32[i2 >> 2] | 0;
+    i10 = i11 + i9 | 0;
+    i12 = HEAP32[i3 >> 2] | 0;
+    if ((i12 | 0) == 0) {
+     i12 = i9;
+    } else {
+     _memcpy(i10 | 0, i5 | 0, i12 | 0) | 0;
+     i12 = HEAP32[i2 >> 2] | 0;
+     i10 = i11 + ((HEAP32[i3 >> 2] | 0) + i9) | 0;
+    }
+    _memcpy(i10 | 0, i1 | 0, i12 | 0) | 0;
+    if ((i8 | 0) <= 1) {
+     break;
+    } else {
+     i11 = i10;
+    }
+   }
+  }
+  _luaL_pushresultsize(i4, i7);
+  i12 = 1;
+  STACKTOP = i6;
+  return i12 | 0;
+ }
+ i12 = _luaL_error(i9, 7168, i4) | 0;
+ STACKTOP = i6;
+ return i12 | 0;
+}
+function ___strchrnul(i6, i2) {
+ i6 = i6 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0;
+ i1 = STACKTOP;
+ i3 = i2 & 255;
+ if ((i3 | 0) == 0) {
+  i7 = i6 + (_strlen(i6 | 0) | 0) | 0;
+  STACKTOP = i1;
+  return i7 | 0;
+ }
+ L5 : do {
+  if ((i6 & 3 | 0) != 0) {
+   i4 = i2 & 255;
+   while (1) {
+    i5 = HEAP8[i6] | 0;
+    if (i5 << 24 >> 24 == 0) {
+     i4 = i6;
+     i5 = 13;
+     break;
+    }
+    i7 = i6 + 1 | 0;
+    if (i5 << 24 >> 24 == i4 << 24 >> 24) {
+     i4 = i6;
+     i5 = 13;
+     break;
+    }
+    if ((i7 & 3 | 0) == 0) {
+     i4 = i7;
+     break L5;
+    } else {
+     i6 = i7;
+    }
+   }
+   if ((i5 | 0) == 13) {
+    STACKTOP = i1;
+    return i4 | 0;
+   }
+  } else {
+   i4 = i6;
+  }
+ } while (0);
+ i3 = Math_imul(i3, 16843009) | 0;
+ i6 = HEAP32[i4 >> 2] | 0;
+ L15 : do {
+  if (((i6 & -2139062144 ^ -2139062144) & i6 + -16843009 | 0) == 0) {
+   while (1) {
+    i7 = i6 ^ i3;
+    i5 = i4 + 4 | 0;
+    if (((i7 & -2139062144 ^ -2139062144) & i7 + -16843009 | 0) != 0) {
+     break L15;
+    }
+    i6 = HEAP32[i5 >> 2] | 0;
+    if (((i6 & -2139062144 ^ -2139062144) & i6 + -16843009 | 0) == 0) {
+     i4 = i5;
+    } else {
+     i4 = i5;
+     break;
+    }
+   }
+  }
+ } while (0);
+ i2 = i2 & 255;
+ while (1) {
+  i7 = HEAP8[i4] | 0;
+  if (i7 << 24 >> 24 == 0 | i7 << 24 >> 24 == i2 << 24 >> 24) {
+   break;
+  } else {
+   i4 = i4 + 1 | 0;
+  }
+ }
+ STACKTOP = i1;
+ return i4 | 0;
+}
+function _lua_replace(i2, i6) {
+ i2 = i2 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i3 = STACKTOP;
+ i7 = i2 + 8 | 0;
+ i9 = HEAP32[i7 >> 2] | 0;
+ i5 = i9 + -16 | 0;
+ i4 = i2 + 16 | 0;
+ i12 = HEAP32[i4 >> 2] | 0;
+ do {
+  if ((i6 | 0) <= 0) {
+   if (!((i6 | 0) < -1000999)) {
+    i10 = i9 + (i6 << 4) | 0;
+    break;
+   }
+   if ((i6 | 0) == -1001e3) {
+    i10 = (HEAP32[i2 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i11 = -1001e3 - i6 | 0;
+   i12 = HEAP32[i12 >> 2] | 0;
+   if ((HEAP32[i12 + 8 >> 2] | 0) != 22 ? (i10 = HEAP32[i12 >> 2] | 0, (i11 | 0) <= (HEAPU8[i10 + 6 | 0] | 0 | 0)) : 0) {
+    i10 = i10 + (i11 + -1 << 4) + 16 | 0;
+   } else {
+    i10 = 5192;
+   }
+  } else {
+   i10 = (HEAP32[i12 >> 2] | 0) + (i6 << 4) | 0;
+   i10 = i10 >>> 0 < i9 >>> 0 ? i10 : 5192;
+  }
+ } while (0);
+ i13 = i5;
+ i11 = HEAP32[i13 + 4 >> 2] | 0;
+ i12 = i10;
+ HEAP32[i12 >> 2] = HEAP32[i13 >> 2];
+ HEAP32[i12 + 4 >> 2] = i11;
+ i9 = i9 + -8 | 0;
+ HEAP32[i10 + 8 >> 2] = HEAP32[i9 >> 2];
+ if ((((i6 | 0) < -1001e3 ? (HEAP32[i9 >> 2] & 64 | 0) != 0 : 0) ? (i1 = HEAP32[i5 >> 2] | 0, !((HEAP8[i1 + 5 | 0] & 3) == 0)) : 0) ? (i8 = HEAP32[HEAP32[HEAP32[i4 >> 2] >> 2] >> 2] | 0, !((HEAP8[i8 + 5 | 0] & 4) == 0)) : 0) {
+  _luaC_barrier_(i2, i8, i1);
+ }
+ HEAP32[i7 >> 2] = (HEAP32[i7 >> 2] | 0) + -16;
+ STACKTOP = i3;
+ return;
+}
+function _memchr(i4, i3, i6) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i5 = 0, i7 = 0;
+ i1 = STACKTOP;
+ i2 = i3 & 255;
+ i7 = (i6 | 0) == 0;
+ L1 : do {
+  if ((i4 & 3 | 0) == 0 | i7) {
+   i5 = i6;
+   i6 = 5;
+  } else {
+   i5 = i3 & 255;
+   while (1) {
+    if ((HEAP8[i4] | 0) == i5 << 24 >> 24) {
+     i5 = i6;
+     i6 = 6;
+     break L1;
+    }
+    i4 = i4 + 1 | 0;
+    i6 = i6 + -1 | 0;
+    i7 = (i6 | 0) == 0;
+    if ((i4 & 3 | 0) == 0 | i7) {
+     i5 = i6;
+     i6 = 5;
+     break;
+    }
+   }
+  }
+ } while (0);
+ if ((i6 | 0) == 5) {
+  if (i7) {
+   i5 = 0;
+  } else {
+   i6 = 6;
+  }
+ }
+ L8 : do {
+  if ((i6 | 0) == 6) {
+   i3 = i3 & 255;
+   if (!((HEAP8[i4] | 0) == i3 << 24 >> 24)) {
+    i2 = Math_imul(i2, 16843009) | 0;
+    L11 : do {
+     if (i5 >>> 0 > 3) {
+      do {
+       i7 = HEAP32[i4 >> 2] ^ i2;
+       if (((i7 & -2139062144 ^ -2139062144) & i7 + -16843009 | 0) != 0) {
+        break L11;
+       }
+       i4 = i4 + 4 | 0;
+       i5 = i5 + -4 | 0;
+      } while (i5 >>> 0 > 3);
+     }
+    } while (0);
+    if ((i5 | 0) == 0) {
+     i5 = 0;
+    } else {
+     while (1) {
+      if ((HEAP8[i4] | 0) == i3 << 24 >> 24) {
+       break L8;
+      }
+      i4 = i4 + 1 | 0;
+      i5 = i5 + -1 | 0;
+      if ((i5 | 0) == 0) {
+       i5 = 0;
+       break;
+      }
+     }
+    }
+   }
+  }
+ } while (0);
+ STACKTOP = i1;
+ return ((i5 | 0) != 0 ? i4 : 0) | 0;
+}
+function _lua_insert(i2, i5) {
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i1 = STACKTOP;
+ i4 = HEAP32[i2 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i3 = (HEAP32[i2 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i3 = (HEAP32[i2 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i4 >> 2] | 0, (i5 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i3 = i3 + (i5 + -1 << 4) + 16 | 0;
+   } else {
+    i3 = 5192;
+   }
+  } else {
+   i3 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i3 = i3 >>> 0 < (HEAP32[i2 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ i2 = i2 + 8 | 0;
+ i4 = HEAP32[i2 >> 2] | 0;
+ if (i4 >>> 0 > i3 >>> 0) {
+  while (1) {
+   i5 = i4 + -16 | 0;
+   i8 = i5;
+   i7 = HEAP32[i8 + 4 >> 2] | 0;
+   i6 = i4;
+   HEAP32[i6 >> 2] = HEAP32[i8 >> 2];
+   HEAP32[i6 + 4 >> 2] = i7;
+   HEAP32[i4 + 8 >> 2] = HEAP32[i4 + -8 >> 2];
+   if (i5 >>> 0 > i3 >>> 0) {
+    i4 = i5;
+   } else {
+    break;
+   }
+  }
+  i4 = HEAP32[i2 >> 2] | 0;
+ }
+ i6 = i4;
+ i7 = HEAP32[i6 + 4 >> 2] | 0;
+ i8 = i3;
+ HEAP32[i8 >> 2] = HEAP32[i6 >> 2];
+ HEAP32[i8 + 4 >> 2] = i7;
+ HEAP32[i3 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+ STACKTOP = i1;
+ return;
+}
+function _findlocal(i6, i4, i1, i2) {
+ i6 = i6 | 0;
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i5 = 0, i7 = 0, i8 = 0;
+ i3 = STACKTOP;
+ do {
+  if ((HEAP8[i4 + 18 | 0] & 1) == 0) {
+   i7 = (HEAP32[i4 >> 2] | 0) + 16 | 0;
+   i5 = 7;
+  } else {
+   if ((i1 | 0) >= 0) {
+    i8 = HEAP32[i4 + 24 >> 2] | 0;
+    i7 = HEAP32[(HEAP32[HEAP32[i4 >> 2] >> 2] | 0) + 12 >> 2] | 0;
+    i7 = _luaF_getlocalname(i7, i1, ((HEAP32[i4 + 28 >> 2] | 0) - (HEAP32[i7 + 12 >> 2] | 0) >> 2) + -1 | 0) | 0;
+    if ((i7 | 0) == 0) {
+     i7 = i8;
+     i5 = 7;
+     break;
+    } else {
+     break;
+    }
+   }
+   i5 = HEAP32[i4 >> 2] | 0;
+   i6 = HEAPU8[(HEAP32[(HEAP32[i5 >> 2] | 0) + 12 >> 2] | 0) + 76 | 0] | 0;
+   if ((((HEAP32[i4 + 24 >> 2] | 0) - i5 >> 4) - i6 | 0) <= (0 - i1 | 0)) {
+    i8 = 0;
+    STACKTOP = i3;
+    return i8 | 0;
+   }
+   HEAP32[i2 >> 2] = i5 + (i6 - i1 << 4);
+   i8 = 2208;
+   STACKTOP = i3;
+   return i8 | 0;
+  }
+ } while (0);
+ if ((i5 | 0) == 7) {
+  if ((HEAP32[i6 + 16 >> 2] | 0) == (i4 | 0)) {
+   i4 = i6 + 8 | 0;
+  } else {
+   i4 = HEAP32[i4 + 12 >> 2] | 0;
+  }
+  if (((HEAP32[i4 >> 2] | 0) - i7 >> 4 | 0) >= (i1 | 0) & (i1 | 0) > 0) {
+   i8 = i7;
+   i7 = 2192;
+  } else {
+   i8 = 0;
+   STACKTOP = i3;
+   return i8 | 0;
+  }
+ }
+ HEAP32[i2 >> 2] = i8 + (i1 + -1 << 4);
+ i8 = i7;
+ STACKTOP = i3;
+ return i8 | 0;
+}
+function _luaH_setint(i4, i5, i6, i1) {
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, d7 = 0.0, i8 = 0, i9 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i8 = i2 + 16 | 0;
+ i3 = i2;
+ i9 = i6 + -1 | 0;
+ L1 : do {
+  if (i9 >>> 0 < (HEAP32[i5 + 28 >> 2] | 0) >>> 0) {
+   i9 = (HEAP32[i5 + 12 >> 2] | 0) + (i9 << 4) | 0;
+   i8 = 10;
+  } else {
+   d7 = +(i6 | 0);
+   HEAPF64[i8 >> 3] = d7 + 1.0;
+   i8 = (HEAP32[i8 + 4 >> 2] | 0) + (HEAP32[i8 >> 2] | 0) | 0;
+   if ((i8 | 0) < 0) {
+    i9 = 0 - i8 | 0;
+    i8 = (i8 | 0) == (i9 | 0) ? 0 : i9;
+   }
+   i9 = (HEAP32[i5 + 16 >> 2] | 0) + (((i8 | 0) % ((1 << (HEAPU8[i5 + 7 | 0] | 0)) + -1 | 1 | 0) | 0) << 5) | 0;
+   while (1) {
+    if ((HEAP32[i9 + 24 >> 2] | 0) == 3 ? +HEAPF64[i9 + 16 >> 3] == d7 : 0) {
+     break;
+    }
+    i9 = HEAP32[i9 + 28 >> 2] | 0;
+    if ((i9 | 0) == 0) {
+     i8 = 12;
+     break L1;
+    }
+   }
+   i8 = 10;
+  }
+ } while (0);
+ if ((i8 | 0) == 10) {
+  if ((i9 | 0) == 5192) {
+   d7 = +(i6 | 0);
+   i8 = 12;
+  }
+ }
+ if ((i8 | 0) == 12) {
+  HEAPF64[i3 >> 3] = d7;
+  HEAP32[i3 + 8 >> 2] = 3;
+  i9 = _luaH_newkey(i4, i5, i3) | 0;
+ }
+ i5 = i1;
+ i6 = HEAP32[i5 + 4 >> 2] | 0;
+ i8 = i9;
+ HEAP32[i8 >> 2] = HEAP32[i5 >> 2];
+ HEAP32[i8 + 4 >> 2] = i6;
+ HEAP32[i9 + 8 >> 2] = HEAP32[i1 + 8 >> 2];
+ STACKTOP = i2;
+ return;
+}
+function _lua_tounsignedx(i6, i8, i1) {
+ i6 = i6 | 0;
+ i8 = i8 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i4 = i2 + 8 | 0;
+ i3 = i2;
+ i7 = HEAP32[i6 + 16 >> 2] | 0;
+ do {
+  if ((i8 | 0) <= 0) {
+   if (!((i8 | 0) < -1000999)) {
+    i5 = (HEAP32[i6 + 8 >> 2] | 0) + (i8 << 4) | 0;
+    break;
+   }
+   if ((i8 | 0) == -1001e3) {
+    i5 = (HEAP32[i6 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i6 = -1001e3 - i8 | 0;
+   i7 = HEAP32[i7 >> 2] | 0;
+   if ((HEAP32[i7 + 8 >> 2] | 0) != 22 ? (i5 = HEAP32[i7 >> 2] | 0, (i6 | 0) <= (HEAPU8[i5 + 6 | 0] | 0 | 0)) : 0) {
+    i5 = i5 + (i6 + -1 << 4) + 16 | 0;
+   } else {
+    i5 = 5192;
+   }
+  } else {
+   i5 = (HEAP32[i7 >> 2] | 0) + (i8 << 4) | 0;
+   i5 = i5 >>> 0 < (HEAP32[i6 + 8 >> 2] | 0) >>> 0 ? i5 : 5192;
+  }
+ } while (0);
+ if ((HEAP32[i5 + 8 >> 2] | 0) != 3) {
+  i5 = _luaV_tonumber(i5, i4) | 0;
+  if ((i5 | 0) == 0) {
+   if ((i1 | 0) == 0) {
+    i8 = 0;
+    STACKTOP = i2;
+    return i8 | 0;
+   }
+   HEAP32[i1 >> 2] = 0;
+   i8 = 0;
+   STACKTOP = i2;
+   return i8 | 0;
+  }
+ }
+ HEAPF64[i3 >> 3] = +HEAPF64[i5 >> 3] + 6755399441055744.0;
+ i3 = HEAP32[i3 >> 2] | 0;
+ if ((i1 | 0) == 0) {
+  i8 = i3;
+  STACKTOP = i2;
+  return i8 | 0;
+ }
+ HEAP32[i1 >> 2] = 1;
+ i8 = i3;
+ STACKTOP = i2;
+ return i8 | 0;
+}
+function _luaC_freeallobjects(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ i5 = i1 + 12 | 0;
+ i3 = HEAP32[i5 >> 2] | 0;
+ i7 = i3 + 104 | 0;
+ while (1) {
+  i4 = HEAP32[i7 >> 2] | 0;
+  if ((i4 | 0) == 0) {
+   break;
+  } else {
+   i7 = i4;
+  }
+ }
+ i4 = i3 + 72 | 0;
+ i6 = HEAP32[i4 >> 2] | 0;
+ if ((i6 | 0) == 0) {
+  i5 = i3;
+ } else {
+  while (1) {
+   i8 = i6 + 5 | 0;
+   HEAP8[i8] = HEAPU8[i8] | 0 | 8;
+   HEAP32[i4 >> 2] = HEAP32[i6 >> 2];
+   HEAP32[i6 >> 2] = HEAP32[i7 >> 2];
+   HEAP32[i7 >> 2] = i6;
+   i7 = HEAP32[i4 >> 2] | 0;
+   if ((i7 | 0) == 0) {
+    break;
+   } else {
+    i8 = i6;
+    i6 = i7;
+    i7 = i8;
+   }
+  }
+  i5 = HEAP32[i5 >> 2] | 0;
+ }
+ i5 = i5 + 104 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ if ((i6 | 0) != 0) {
+  do {
+   i8 = i6 + 5 | 0;
+   HEAP8[i8] = HEAP8[i8] & 191;
+   _GCTM(i1, 0);
+   i6 = HEAP32[i5 >> 2] | 0;
+  } while ((i6 | 0) != 0);
+ }
+ HEAP8[i3 + 60 | 0] = 3;
+ HEAP8[i3 + 62 | 0] = 0;
+ _sweeplist(i1, i4, -3) | 0;
+ _sweeplist(i1, i3 + 68 | 0, -3) | 0;
+ i4 = i3 + 32 | 0;
+ if ((HEAP32[i4 >> 2] | 0) <= 0) {
+  STACKTOP = i2;
+  return;
+ }
+ i3 = i3 + 24 | 0;
+ i5 = 0;
+ do {
+  _sweeplist(i1, (HEAP32[i3 >> 2] | 0) + (i5 << 2) | 0, -3) | 0;
+  i5 = i5 + 1 | 0;
+ } while ((i5 | 0) < (HEAP32[i4 >> 2] | 0));
+ STACKTOP = i2;
+ return;
+}
+function _strspn(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i3 = i2;
+ HEAP32[i3 + 0 >> 2] = 0;
+ HEAP32[i3 + 4 >> 2] = 0;
+ HEAP32[i3 + 8 >> 2] = 0;
+ HEAP32[i3 + 12 >> 2] = 0;
+ HEAP32[i3 + 16 >> 2] = 0;
+ HEAP32[i3 + 20 >> 2] = 0;
+ HEAP32[i3 + 24 >> 2] = 0;
+ HEAP32[i3 + 28 >> 2] = 0;
+ i4 = HEAP8[i5] | 0;
+ if (i4 << 24 >> 24 == 0) {
+  i6 = 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ if ((HEAP8[i5 + 1 | 0] | 0) == 0) {
+  i3 = i1;
+  while (1) {
+   if ((HEAP8[i3] | 0) == i4 << 24 >> 24) {
+    i3 = i3 + 1 | 0;
+   } else {
+    break;
+   }
+  }
+  i6 = i3 - i1 | 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ do {
+  i7 = i4 & 255;
+  i6 = i3 + (i7 >>> 5 << 2) | 0;
+  HEAP32[i6 >> 2] = HEAP32[i6 >> 2] | 1 << (i7 & 31);
+  i5 = i5 + 1 | 0;
+  i4 = HEAP8[i5] | 0;
+ } while (!(i4 << 24 >> 24 == 0));
+ i5 = HEAP8[i1] | 0;
+ L12 : do {
+  if (i5 << 24 >> 24 == 0) {
+   i4 = i1;
+  } else {
+   i4 = i1;
+   while (1) {
+    i7 = i5 & 255;
+    i6 = i4 + 1 | 0;
+    if ((HEAP32[i3 + (i7 >>> 5 << 2) >> 2] & 1 << (i7 & 31) | 0) == 0) {
+     break L12;
+    }
+    i5 = HEAP8[i6] | 0;
+    if (i5 << 24 >> 24 == 0) {
+     i4 = i6;
+     break;
+    } else {
+     i4 = i6;
+    }
+   }
+  }
+ } while (0);
+ i7 = i4 - i1 | 0;
+ STACKTOP = i2;
+ return i7 | 0;
+}
+function _lua_remove(i2, i4) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i1 = STACKTOP;
+ i5 = HEAP32[i2 + 16 >> 2] | 0;
+ do {
+  if ((i4 | 0) <= 0) {
+   if (!((i4 | 0) < -1000999)) {
+    i3 = (HEAP32[i2 + 8 >> 2] | 0) + (i4 << 4) | 0;
+    break;
+   }
+   if ((i4 | 0) == -1001e3) {
+    i3 = (HEAP32[i2 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i4 = -1001e3 - i4 | 0;
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((HEAP32[i5 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i5 >> 2] | 0, (i4 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i3 = i3 + (i4 + -1 << 4) + 16 | 0;
+   } else {
+    i3 = 5192;
+   }
+  } else {
+   i3 = (HEAP32[i5 >> 2] | 0) + (i4 << 4) | 0;
+   i3 = i3 >>> 0 < (HEAP32[i2 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ i4 = i3 + 16 | 0;
+ i2 = i2 + 8 | 0;
+ i5 = HEAP32[i2 >> 2] | 0;
+ if (!(i4 >>> 0 < i5 >>> 0)) {
+  i5 = i5 + -16 | 0;
+  HEAP32[i2 >> 2] = i5;
+  STACKTOP = i1;
+  return;
+ }
+ while (1) {
+  i7 = i4;
+  i6 = HEAP32[i7 + 4 >> 2] | 0;
+  i5 = i3;
+  HEAP32[i5 >> 2] = HEAP32[i7 >> 2];
+  HEAP32[i5 + 4 >> 2] = i6;
+  HEAP32[i3 + 8 >> 2] = HEAP32[i3 + 24 >> 2];
+  i5 = i4 + 16 | 0;
+  i3 = HEAP32[i2 >> 2] | 0;
+  if (i5 >>> 0 < i3 >>> 0) {
+   i3 = i4;
+   i4 = i5;
+  } else {
+   break;
+  }
+ }
+ i7 = i3 + -16 | 0;
+ HEAP32[i2 >> 2] = i7;
+ STACKTOP = i1;
+ return;
+}
+function _luaD_protectedparser(i1, i4, i3, i2) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0;
+ i5 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i13 = i5;
+ i6 = i1 + 36 | 0;
+ HEAP16[i6 >> 1] = (HEAP16[i6 >> 1] | 0) + 1 << 16 >> 16;
+ HEAP32[i13 >> 2] = i4;
+ HEAP32[i13 + 56 >> 2] = i3;
+ HEAP32[i13 + 52 >> 2] = i2;
+ i10 = i13 + 16 | 0;
+ HEAP32[i10 >> 2] = 0;
+ i9 = i13 + 24 | 0;
+ HEAP32[i9 >> 2] = 0;
+ i8 = i13 + 28 | 0;
+ HEAP32[i8 >> 2] = 0;
+ i7 = i13 + 36 | 0;
+ HEAP32[i7 >> 2] = 0;
+ i2 = i13 + 40 | 0;
+ HEAP32[i2 >> 2] = 0;
+ i3 = i13 + 48 | 0;
+ HEAP32[i3 >> 2] = 0;
+ i12 = i13 + 4 | 0;
+ HEAP32[i12 >> 2] = 0;
+ i11 = i13 + 12 | 0;
+ HEAP32[i11 >> 2] = 0;
+ i4 = _luaD_pcall(i1, 6, i13, (HEAP32[i1 + 8 >> 2] | 0) - (HEAP32[i1 + 28 >> 2] | 0) | 0, HEAP32[i1 + 68 >> 2] | 0) | 0;
+ HEAP32[i12 >> 2] = _luaM_realloc_(i1, HEAP32[i12 >> 2] | 0, HEAP32[i11 >> 2] | 0, 0) | 0;
+ HEAP32[i11 >> 2] = 0;
+ _luaM_realloc_(i1, HEAP32[i10 >> 2] | 0, HEAP32[i9 >> 2] << 1, 0) | 0;
+ _luaM_realloc_(i1, HEAP32[i8 >> 2] | 0, HEAP32[i7 >> 2] << 4, 0) | 0;
+ _luaM_realloc_(i1, HEAP32[i2 >> 2] | 0, HEAP32[i3 >> 2] << 4, 0) | 0;
+ HEAP16[i6 >> 1] = (HEAP16[i6 >> 1] | 0) + -1 << 16 >> 16;
+ STACKTOP = i5;
+ return i4 | 0;
+}
+function _markmt(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = HEAP32[i1 + 252 >> 2] | 0;
+ if ((i3 | 0) != 0 ? !((HEAP8[i3 + 5 | 0] & 3) == 0) : 0) {
+  _reallymarkobject(i1, i3);
+ }
+ i3 = HEAP32[i1 + 256 >> 2] | 0;
+ if ((i3 | 0) != 0 ? !((HEAP8[i3 + 5 | 0] & 3) == 0) : 0) {
+  _reallymarkobject(i1, i3);
+ }
+ i3 = HEAP32[i1 + 260 >> 2] | 0;
+ if ((i3 | 0) != 0 ? !((HEAP8[i3 + 5 | 0] & 3) == 0) : 0) {
+  _reallymarkobject(i1, i3);
+ }
+ i3 = HEAP32[i1 + 264 >> 2] | 0;
+ if ((i3 | 0) != 0 ? !((HEAP8[i3 + 5 | 0] & 3) == 0) : 0) {
+  _reallymarkobject(i1, i3);
+ }
+ i3 = HEAP32[i1 + 268 >> 2] | 0;
+ if ((i3 | 0) != 0 ? !((HEAP8[i3 + 5 | 0] & 3) == 0) : 0) {
+  _reallymarkobject(i1, i3);
+ }
+ i3 = HEAP32[i1 + 272 >> 2] | 0;
+ if ((i3 | 0) != 0 ? !((HEAP8[i3 + 5 | 0] & 3) == 0) : 0) {
+  _reallymarkobject(i1, i3);
+ }
+ i3 = HEAP32[i1 + 276 >> 2] | 0;
+ if ((i3 | 0) != 0 ? !((HEAP8[i3 + 5 | 0] & 3) == 0) : 0) {
+  _reallymarkobject(i1, i3);
+ }
+ i3 = HEAP32[i1 + 280 >> 2] | 0;
+ if ((i3 | 0) != 0 ? !((HEAP8[i3 + 5 | 0] & 3) == 0) : 0) {
+  _reallymarkobject(i1, i3);
+ }
+ i3 = HEAP32[i1 + 284 >> 2] | 0;
+ if ((i3 | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ if ((HEAP8[i3 + 5 | 0] & 3) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ _reallymarkobject(i1, i3);
+ STACKTOP = i2;
+ return;
+}
+function _findlabel(i9, i2) {
+ i9 = i9 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0;
+ i1 = STACKTOP;
+ i3 = i9 + 48 | 0;
+ i7 = HEAP32[(HEAP32[i3 >> 2] | 0) + 16 >> 2] | 0;
+ i10 = HEAP32[i9 + 64 >> 2] | 0;
+ i4 = HEAP32[i10 + 12 >> 2] | 0;
+ i6 = i7 + 4 | 0;
+ i13 = HEAP16[i6 >> 1] | 0;
+ i5 = i10 + 28 | 0;
+ if ((i13 | 0) >= (HEAP32[i5 >> 2] | 0)) {
+  i15 = 0;
+  STACKTOP = i1;
+  return i15 | 0;
+ }
+ i10 = i10 + 24 | 0;
+ i11 = i4 + (i2 << 4) | 0;
+ while (1) {
+  i14 = HEAP32[i10 >> 2] | 0;
+  i12 = i14 + (i13 << 4) | 0;
+  i15 = i13 + 1 | 0;
+  if ((_luaS_eqstr(HEAP32[i12 >> 2] | 0, HEAP32[i11 >> 2] | 0) | 0) != 0) {
+   break;
+  }
+  if ((i15 | 0) < (HEAP32[i5 >> 2] | 0)) {
+   i13 = i15;
+  } else {
+   i2 = 0;
+   i8 = 10;
+   break;
+  }
+ }
+ if ((i8 | 0) == 10) {
+  STACKTOP = i1;
+  return i2 | 0;
+ }
+ i8 = HEAP8[i14 + (i13 << 4) + 12 | 0] | 0;
+ do {
+  if ((HEAPU8[i4 + (i2 << 4) + 12 | 0] | 0) > (i8 & 255)) {
+   if ((HEAP8[i7 + 9 | 0] | 0) == 0 ? (HEAP32[i5 >> 2] | 0) <= (HEAP16[i6 >> 1] | 0) : 0) {
+    break;
+   }
+   _luaK_patchclose(HEAP32[i3 >> 2] | 0, HEAP32[i4 + (i2 << 4) + 4 >> 2] | 0, i8 & 255);
+  }
+ } while (0);
+ _closegoto(i9, i2, i12);
+ i15 = 1;
+ STACKTOP = i1;
+ return i15 | 0;
+}
+function _lua_getmetatable(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i4 = (HEAP32[i1 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i4 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i4 >> 2] | 0, (i5 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i4 = i3 + (i5 + -1 << 4) + 16 | 0;
+   } else {
+    i4 = 5192;
+   }
+  } else {
+   i3 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i4 = i3 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ i3 = HEAP32[i4 + 8 >> 2] & 15;
+ if ((i3 | 0) == 7) {
+  i3 = HEAP32[(HEAP32[i4 >> 2] | 0) + 8 >> 2] | 0;
+ } else if ((i3 | 0) == 5) {
+  i3 = HEAP32[(HEAP32[i4 >> 2] | 0) + 8 >> 2] | 0;
+ } else {
+  i3 = HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + (i3 << 2) + 252 >> 2] | 0;
+ }
+ if ((i3 | 0) == 0) {
+  i5 = 0;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ i5 = i1 + 8 | 0;
+ i4 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i4 >> 2] = i3;
+ HEAP32[i4 + 8 >> 2] = 69;
+ HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + 16;
+ i5 = 1;
+ STACKTOP = i2;
+ return i5 | 0;
+}
+function _str_byte(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i6 = i1;
+ i4 = i1 + 4 | 0;
+ i3 = _luaL_checklstring(i2, 1, i4) | 0;
+ i5 = _luaL_optinteger(i2, 2, 1) | 0;
+ i7 = HEAP32[i4 >> 2] | 0;
+ if (!((i5 | 0) > -1)) {
+  if (i7 >>> 0 < (0 - i5 | 0) >>> 0) {
+   i5 = 0;
+  } else {
+   i5 = i5 + 1 + i7 | 0;
+  }
+ }
+ i8 = _luaL_optinteger(i2, 3, i5) | 0;
+ i7 = HEAP32[i4 >> 2] | 0;
+ if (!((i8 | 0) > -1)) {
+  if (i7 >>> 0 < (0 - i8 | 0) >>> 0) {
+   i8 = 0;
+  } else {
+   i8 = i8 + 1 + i7 | 0;
+  }
+ }
+ i9 = (i5 | 0) == 0 ? 1 : i5;
+ i10 = i8 >>> 0 > i7 >>> 0 ? i7 : i8;
+ if (i9 >>> 0 > i10 >>> 0) {
+  i10 = 0;
+  STACKTOP = i1;
+  return i10 | 0;
+ }
+ i4 = i10 - i9 + 1 | 0;
+ if ((i10 | 0) == -1) {
+  i10 = _luaL_error(i2, 7944, i6) | 0;
+  STACKTOP = i1;
+  return i10 | 0;
+ }
+ _luaL_checkstack(i2, i4, 7944);
+ if ((i4 | 0) <= 0) {
+  i10 = i4;
+  STACKTOP = i1;
+  return i10 | 0;
+ }
+ i6 = i9 + -1 | 0;
+ i8 = ~i8;
+ i7 = ~i7;
+ i5 = 0 - (i8 >>> 0 > i7 >>> 0 ? i8 : i7) - (i5 >>> 0 > 1 ? i5 : 1) | 0;
+ i7 = 0;
+ do {
+  _lua_pushinteger(i2, HEAPU8[i3 + (i6 + i7) | 0] | 0);
+  i7 = i7 + 1 | 0;
+ } while ((i7 | 0) != (i5 | 0));
+ STACKTOP = i1;
+ return i4 | 0;
+}
+function _lua_setuservalue(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0;
+ i3 = STACKTOP;
+ i6 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i5 = (HEAP32[i1 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i5 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i5 | 0;
+   i6 = HEAP32[i6 >> 2] | 0;
+   if ((HEAP32[i6 + 8 >> 2] | 0) != 22 ? (i4 = HEAP32[i6 >> 2] | 0, (i5 | 0) <= (HEAPU8[i4 + 6 | 0] | 0 | 0)) : 0) {
+    i5 = i4 + (i5 + -1 << 4) + 16 | 0;
+   } else {
+    i5 = 5192;
+   }
+  } else {
+   i4 = (HEAP32[i6 >> 2] | 0) + (i5 << 4) | 0;
+   i5 = i4 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i4 : 5192;
+  }
+ } while (0);
+ i4 = i1 + 8 | 0;
+ i6 = HEAP32[i4 >> 2] | 0;
+ if ((HEAP32[i6 + -8 >> 2] | 0) != 0) {
+  HEAP32[(HEAP32[i5 >> 2] | 0) + 12 >> 2] = HEAP32[i6 + -16 >> 2];
+  i6 = HEAP32[(HEAP32[i4 >> 2] | 0) + -16 >> 2] | 0;
+  if (!((HEAP8[i6 + 5 | 0] & 3) == 0) ? (i2 = HEAP32[i5 >> 2] | 0, !((HEAP8[i2 + 5 | 0] & 4) == 0)) : 0) {
+   _luaC_barrier_(i1, i2, i6);
+  }
+ } else {
+  HEAP32[(HEAP32[i5 >> 2] | 0) + 12 >> 2] = 0;
+ }
+ HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + -16;
+ STACKTOP = i3;
+ return;
+}
+function _f_luaopen(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i6 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i5 = i6;
+ i4 = HEAP32[i1 + 12 >> 2] | 0;
+ i2 = _luaM_realloc_(i1, 0, 0, 640) | 0;
+ HEAP32[i1 + 28 >> 2] = i2;
+ i3 = i1 + 32 | 0;
+ HEAP32[i3 >> 2] = 40;
+ i7 = 0;
+ do {
+  HEAP32[i2 + (i7 << 4) + 8 >> 2] = 0;
+  i7 = i7 + 1 | 0;
+ } while ((i7 | 0) != 40);
+ HEAP32[i1 + 24 >> 2] = i2 + ((HEAP32[i3 >> 2] | 0) + -5 << 4);
+ i7 = i1 + 72 | 0;
+ HEAP32[i1 + 80 >> 2] = 0;
+ HEAP32[i1 + 84 >> 2] = 0;
+ HEAP8[i1 + 90 | 0] = 0;
+ HEAP32[i7 >> 2] = i2;
+ HEAP32[i1 + 8 >> 2] = i2 + 16;
+ HEAP32[i2 + 8 >> 2] = 0;
+ HEAP32[i1 + 76 >> 2] = i2 + 336;
+ HEAP32[i1 + 16 >> 2] = i7;
+ i7 = _luaH_new(i1) | 0;
+ HEAP32[i4 + 40 >> 2] = i7;
+ HEAP32[i4 + 48 >> 2] = 69;
+ _luaH_resize(i1, i7, 2, 0);
+ HEAP32[i5 >> 2] = i1;
+ i3 = i5 + 8 | 0;
+ HEAP32[i3 >> 2] = 72;
+ _luaH_setint(i1, i7, 1, i5);
+ HEAP32[i5 >> 2] = _luaH_new(i1) | 0;
+ HEAP32[i3 >> 2] = 69;
+ _luaH_setint(i1, i7, 2, i5);
+ _luaS_resize(i1, 32);
+ _luaT_init(i1);
+ _luaX_init(i1);
+ i7 = _luaS_newlstr(i1, 6896, 17) | 0;
+ HEAP32[i4 + 180 >> 2] = i7;
+ i7 = i7 + 5 | 0;
+ HEAP8[i7] = HEAPU8[i7] | 0 | 32;
+ HEAP8[i4 + 63 | 0] = 1;
+ STACKTOP = i6;
+ return;
+}
+function _lua_tointegerx(i6, i7, i1) {
+ i6 = i6 | 0;
+ i7 = i7 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ i5 = HEAP32[i6 + 16 >> 2] | 0;
+ do {
+  if ((i7 | 0) <= 0) {
+   if (!((i7 | 0) < -1000999)) {
+    i4 = (HEAP32[i6 + 8 >> 2] | 0) + (i7 << 4) | 0;
+    break;
+   }
+   if ((i7 | 0) == -1001e3) {
+    i4 = (HEAP32[i6 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i6 = -1001e3 - i7 | 0;
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((HEAP32[i5 + 8 >> 2] | 0) != 22 ? (i4 = HEAP32[i5 >> 2] | 0, (i6 | 0) <= (HEAPU8[i4 + 6 | 0] | 0 | 0)) : 0) {
+    i4 = i4 + (i6 + -1 << 4) + 16 | 0;
+   } else {
+    i4 = 5192;
+   }
+  } else {
+   i4 = (HEAP32[i5 >> 2] | 0) + (i7 << 4) | 0;
+   i4 = i4 >>> 0 < (HEAP32[i6 + 8 >> 2] | 0) >>> 0 ? i4 : 5192;
+  }
+ } while (0);
+ if ((HEAP32[i4 + 8 >> 2] | 0) != 3) {
+  i4 = _luaV_tonumber(i4, i3) | 0;
+  if ((i4 | 0) == 0) {
+   if ((i1 | 0) == 0) {
+    i7 = 0;
+    STACKTOP = i2;
+    return i7 | 0;
+   }
+   HEAP32[i1 >> 2] = 0;
+   i7 = 0;
+   STACKTOP = i2;
+   return i7 | 0;
+  }
+ }
+ i3 = ~~+HEAPF64[i4 >> 3];
+ if ((i1 | 0) == 0) {
+  i7 = i3;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ HEAP32[i1 >> 2] = 1;
+ i7 = i3;
+ STACKTOP = i2;
+ return i7 | 0;
+}
+function _close_state(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ i6 = i1 + 12 | 0;
+ i3 = HEAP32[i6 >> 2] | 0;
+ i4 = i1 + 28 | 0;
+ _luaF_close(i1, HEAP32[i4 >> 2] | 0);
+ _luaC_freeallobjects(i1);
+ i6 = HEAP32[i6 >> 2] | 0;
+ _luaM_realloc_(i1, HEAP32[i6 + 24 >> 2] | 0, HEAP32[i6 + 32 >> 2] << 2, 0) | 0;
+ i6 = i3 + 144 | 0;
+ i5 = i3 + 152 | 0;
+ HEAP32[i6 >> 2] = _luaM_realloc_(i1, HEAP32[i6 >> 2] | 0, HEAP32[i5 >> 2] | 0, 0) | 0;
+ HEAP32[i5 >> 2] = 0;
+ i5 = HEAP32[i4 >> 2] | 0;
+ if ((i5 | 0) == 0) {
+  i5 = HEAP32[i3 >> 2] | 0;
+  i6 = i3 + 4 | 0;
+  i6 = HEAP32[i6 >> 2] | 0;
+  FUNCTION_TABLE_iiiii[i5 & 3](i6, i1, 400, 0) | 0;
+  STACKTOP = i2;
+  return;
+ }
+ HEAP32[i1 + 16 >> 2] = i1 + 72;
+ i7 = i1 + 84 | 0;
+ i6 = HEAP32[i7 >> 2] | 0;
+ HEAP32[i7 >> 2] = 0;
+ if ((i6 | 0) != 0) {
+  while (1) {
+   i5 = HEAP32[i6 + 12 >> 2] | 0;
+   _luaM_realloc_(i1, i6, 40, 0) | 0;
+   if ((i5 | 0) == 0) {
+    break;
+   } else {
+    i6 = i5;
+   }
+  }
+  i5 = HEAP32[i4 >> 2] | 0;
+ }
+ _luaM_realloc_(i1, i5, HEAP32[i1 + 32 >> 2] << 4, 0) | 0;
+ i6 = HEAP32[i3 >> 2] | 0;
+ i7 = i3 + 4 | 0;
+ i7 = HEAP32[i7 >> 2] | 0;
+ FUNCTION_TABLE_iiiii[i6 & 3](i7, i1, 400, 0) | 0;
+ STACKTOP = i2;
+ return;
+}
+function _ll_module(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 112 | 0;
+ i4 = i2;
+ i5 = i2 + 4 | 0;
+ i6 = _luaL_checklstring(i1, 1, 0) | 0;
+ i3 = _lua_gettop(i1) | 0;
+ _luaL_pushmodule(i1, i6, 1);
+ _lua_getfield(i1, -1, 4728);
+ i7 = (_lua_type(i1, -1) | 0) == 0;
+ _lua_settop(i1, -2);
+ if (i7) {
+  _lua_pushvalue(i1, -1);
+  _lua_setfield(i1, -2, 4784);
+  _lua_pushstring(i1, i6) | 0;
+  _lua_setfield(i1, -2, 4728);
+  i7 = _strrchr(i6, 46) | 0;
+  _lua_pushlstring(i1, i6, ((i7 | 0) == 0 ? i6 : i7 + 1 | 0) - i6 | 0) | 0;
+  _lua_setfield(i1, -2, 4792);
+ }
+ _lua_pushvalue(i1, -1);
+ if (!(((_lua_getstack(i1, 1, i5) | 0) != 0 ? (_lua_getinfo(i1, 4736, i5) | 0) != 0 : 0) ? (_lua_iscfunction(i1, -1) | 0) == 0 : 0)) {
+  _luaL_error(i1, 4744, i4) | 0;
+ }
+ _lua_pushvalue(i1, -2);
+ _lua_setupvalue(i1, -2, 1) | 0;
+ _lua_settop(i1, -2);
+ if ((i3 | 0) < 2) {
+  STACKTOP = i2;
+  return 1;
+ } else {
+  i4 = 2;
+ }
+ while (1) {
+  if ((_lua_type(i1, i4) | 0) == 6) {
+   _lua_pushvalue(i1, i4);
+   _lua_pushvalue(i1, -2);
+   _lua_callk(i1, 1, 0, 0, 0);
+  }
+  if ((i4 | 0) == (i3 | 0)) {
+   break;
+  } else {
+   i4 = i4 + 1 | 0;
+  }
+ }
+ STACKTOP = i2;
+ return 1;
+}
+function _strcspn(i2, i5) {
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i3 = i1;
+ i4 = HEAP8[i5] | 0;
+ if (!(i4 << 24 >> 24 == 0) ? (HEAP8[i5 + 1 | 0] | 0) != 0 : 0) {
+  HEAP32[i3 + 0 >> 2] = 0;
+  HEAP32[i3 + 4 >> 2] = 0;
+  HEAP32[i3 + 8 >> 2] = 0;
+  HEAP32[i3 + 12 >> 2] = 0;
+  HEAP32[i3 + 16 >> 2] = 0;
+  HEAP32[i3 + 20 >> 2] = 0;
+  HEAP32[i3 + 24 >> 2] = 0;
+  HEAP32[i3 + 28 >> 2] = 0;
+  do {
+   i7 = i4 & 255;
+   i6 = i3 + (i7 >>> 5 << 2) | 0;
+   HEAP32[i6 >> 2] = HEAP32[i6 >> 2] | 1 << (i7 & 31);
+   i5 = i5 + 1 | 0;
+   i4 = HEAP8[i5] | 0;
+  } while (!(i4 << 24 >> 24 == 0));
+  i5 = HEAP8[i2] | 0;
+  L7 : do {
+   if (i5 << 24 >> 24 == 0) {
+    i4 = i2;
+   } else {
+    i4 = i2;
+    while (1) {
+     i7 = i5 & 255;
+     i6 = i4 + 1 | 0;
+     if ((HEAP32[i3 + (i7 >>> 5 << 2) >> 2] & 1 << (i7 & 31) | 0) != 0) {
+      break L7;
+     }
+     i5 = HEAP8[i6] | 0;
+     if (i5 << 24 >> 24 == 0) {
+      i4 = i6;
+      break;
+     } else {
+      i4 = i6;
+     }
+    }
+   }
+  } while (0);
+  i7 = i4 - i2 | 0;
+  STACKTOP = i1;
+  return i7 | 0;
+ }
+ i7 = (___strchrnul(i2, i4 << 24 >> 24) | 0) - i2 | 0;
+ STACKTOP = i1;
+ return i7 | 0;
+}
+function _main(i4, i5) {
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i1;
+ i3 = _luaL_newstate() | 0;
+ if ((i3 | 0) == 0) {
+  i4 = HEAP32[i5 >> 2] | 0;
+  i3 = HEAP32[_stderr >> 2] | 0;
+  if ((i4 | 0) != 0) {
+   HEAP32[i2 >> 2] = i4;
+   _fprintf(i3 | 0, 496, i2 | 0) | 0;
+   _fflush(i3 | 0) | 0;
+  }
+  HEAP32[i2 >> 2] = 8;
+  _fprintf(i3 | 0, 912, i2 | 0) | 0;
+  _fflush(i3 | 0) | 0;
+  i8 = 1;
+  STACKTOP = i1;
+  return i8 | 0;
+ }
+ _lua_pushcclosure(i3, 141, 0);
+ _lua_pushinteger(i3, i4);
+ _lua_pushlightuserdata(i3, i5);
+ i6 = _lua_pcallk(i3, 2, 1, 0, 0, 0) | 0;
+ i7 = _lua_toboolean(i3, -1) | 0;
+ i6 = (i6 | 0) == 0;
+ if (!i6) {
+  if ((_lua_type(i3, -1) | 0) == 4) {
+   i8 = _lua_tolstring(i3, -1, 0) | 0;
+  } else {
+   i8 = 0;
+  }
+  i4 = HEAP32[20] | 0;
+  i5 = HEAP32[_stderr >> 2] | 0;
+  if ((i4 | 0) != 0) {
+   HEAP32[i2 >> 2] = i4;
+   _fprintf(i5 | 0, 496, i2 | 0) | 0;
+   _fflush(i5 | 0) | 0;
+  }
+  HEAP32[i2 >> 2] = (i8 | 0) == 0 ? 48 : i8;
+  _fprintf(i5 | 0, 912, i2 | 0) | 0;
+  _fflush(i5 | 0) | 0;
+  _lua_settop(i3, -2);
+ }
+ _lua_close(i3);
+ i8 = i6 & (i7 | 0) != 0 & 1 ^ 1;
+ STACKTOP = i1;
+ return i8 | 0;
+}
+function _db_sethook(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i4 = STACKTOP;
+ if ((_lua_type(i1, 1) | 0) == 8) {
+  i2 = _lua_tothread(i1, 1) | 0;
+  i5 = 1;
+ } else {
+  i2 = i1;
+  i5 = 0;
+ }
+ i3 = i5 + 1 | 0;
+ if ((_lua_type(i1, i3) | 0) < 1) {
+  _lua_settop(i1, i3);
+  i6 = 0;
+  i7 = 0;
+  i5 = 0;
+ } else {
+  i6 = _luaL_checklstring(i1, i5 | 2, 0) | 0;
+  _luaL_checktype(i1, i3, 6);
+  i5 = _luaL_optinteger(i1, i5 + 3 | 0, 0) | 0;
+  i7 = (_strchr(i6, 99) | 0) != 0 | 0;
+  i8 = (_strchr(i6, 114) | 0) == 0;
+  i7 = i8 ? i7 : i7 | 2;
+  i8 = (_strchr(i6, 108) | 0) == 0;
+  i8 = i8 ? i7 : i7 | 4;
+  i6 = i5;
+  i7 = 9;
+  i5 = (i5 | 0) > 0 ? i8 | 8 : i8;
+ }
+ if ((_luaL_getsubtable(i1, -1001e3, 11584) | 0) != 0) {
+  _lua_pushthread(i2) | 0;
+  _lua_xmove(i2, i1, 1);
+  _lua_pushvalue(i1, i3);
+  _lua_rawset(i1, -3);
+  _lua_sethook(i2, i7, i5, i6) | 0;
+  STACKTOP = i4;
+  return 0;
+ }
+ _lua_pushstring(i1, 11592) | 0;
+ _lua_setfield(i1, -2, 11600);
+ _lua_pushvalue(i1, -1);
+ _lua_setmetatable(i1, -2) | 0;
+ _lua_pushthread(i2) | 0;
+ _lua_xmove(i2, i1, 1);
+ _lua_pushvalue(i1, i3);
+ _lua_rawset(i1, -3);
+ _lua_sethook(i2, i7, i5, i6) | 0;
+ STACKTOP = i4;
+ return 0;
+}
+function _tconcat(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 1056 | 0;
+ i6 = i3;
+ i2 = i3 + 16 | 0;
+ i5 = i3 + 8 | 0;
+ i4 = _luaL_optlstring(i1, 2, 8208, i5) | 0;
+ _luaL_checktype(i1, 1, 5);
+ i8 = _luaL_optinteger(i1, 3, 1) | 0;
+ if ((_lua_type(i1, 4) | 0) < 1) {
+  i7 = _luaL_len(i1, 1) | 0;
+ } else {
+  i7 = _luaL_checkinteger(i1, 4) | 0;
+ }
+ _luaL_buffinit(i1, i2);
+ if ((i8 | 0) >= (i7 | 0)) {
+  if ((i8 | 0) != (i7 | 0)) {
+   _luaL_pushresult(i2);
+   STACKTOP = i3;
+   return 1;
+  }
+ } else {
+  do {
+   _lua_rawgeti(i1, 1, i8);
+   if ((_lua_isstring(i1, -1) | 0) == 0) {
+    HEAP32[i6 >> 2] = _lua_typename(i1, _lua_type(i1, -1) | 0) | 0;
+    HEAP32[i6 + 4 >> 2] = i8;
+    _luaL_error(i1, 8360, i6) | 0;
+   }
+   _luaL_addvalue(i2);
+   _luaL_addlstring(i2, i4, HEAP32[i5 >> 2] | 0);
+   i8 = i8 + 1 | 0;
+  } while ((i8 | 0) != (i7 | 0));
+ }
+ _lua_rawgeti(i1, 1, i7);
+ if ((_lua_isstring(i1, -1) | 0) == 0) {
+  HEAP32[i6 >> 2] = _lua_typename(i1, _lua_type(i1, -1) | 0) | 0;
+  HEAP32[i6 + 4 >> 2] = i7;
+  _luaL_error(i1, 8360, i6) | 0;
+ }
+ _luaL_addvalue(i2);
+ _luaL_pushresult(i2);
+ STACKTOP = i3;
+ return 1;
+}
+function _searcher_Croot(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ i4 = _luaL_checklstring(i1, 1, 0) | 0;
+ i5 = _strchr(i4, 46) | 0;
+ if ((i5 | 0) == 0) {
+  i6 = 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ _lua_pushlstring(i1, i4, i5 - i4 | 0) | 0;
+ i5 = _lua_tolstring(i1, -1, 0) | 0;
+ _lua_getfield(i1, -1001001, 4440);
+ i6 = _lua_tolstring(i1, -1, 0) | 0;
+ if ((i6 | 0) == 0) {
+  HEAP32[i3 >> 2] = 4440;
+  _luaL_error(i1, 5032, i3) | 0;
+ }
+ i5 = _searchpath(i1, i5, i6, 4936, 4848) | 0;
+ if ((i5 | 0) == 0) {
+  i6 = 1;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ i6 = _loadfunc(i1, i5, i4) | 0;
+ if ((i6 | 0) == 2) {
+  HEAP32[i3 >> 2] = i4;
+  HEAP32[i3 + 4 >> 2] = i5;
+  _lua_pushfstring(i1, 4856, i3) | 0;
+  i6 = 1;
+  STACKTOP = i2;
+  return i6 | 0;
+ } else if ((i6 | 0) == 0) {
+  _lua_pushstring(i1, i5) | 0;
+  i6 = 2;
+  STACKTOP = i2;
+  return i6 | 0;
+ } else {
+  i4 = _lua_tolstring(i1, 1, 0) | 0;
+  i6 = _lua_tolstring(i1, -1, 0) | 0;
+  HEAP32[i3 >> 2] = i4;
+  HEAP32[i3 + 4 >> 2] = i5;
+  HEAP32[i3 + 8 >> 2] = i6;
+  i6 = _luaL_error(i1, 4888, i3) | 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ return 0;
+}
+function _lua_tonumberx(i5, i7, i1) {
+ i5 = i5 | 0;
+ i7 = i7 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0, d8 = 0.0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ i6 = HEAP32[i5 + 16 >> 2] | 0;
+ do {
+  if ((i7 | 0) <= 0) {
+   if (!((i7 | 0) < -1000999)) {
+    i4 = (HEAP32[i5 + 8 >> 2] | 0) + (i7 << 4) | 0;
+    break;
+   }
+   if ((i7 | 0) == -1001e3) {
+    i4 = (HEAP32[i5 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i7 | 0;
+   i6 = HEAP32[i6 >> 2] | 0;
+   if ((HEAP32[i6 + 8 >> 2] | 0) != 22 ? (i4 = HEAP32[i6 >> 2] | 0, (i5 | 0) <= (HEAPU8[i4 + 6 | 0] | 0 | 0)) : 0) {
+    i4 = i4 + (i5 + -1 << 4) + 16 | 0;
+   } else {
+    i4 = 5192;
+   }
+  } else {
+   i4 = (HEAP32[i6 >> 2] | 0) + (i7 << 4) | 0;
+   i4 = i4 >>> 0 < (HEAP32[i5 + 8 >> 2] | 0) >>> 0 ? i4 : 5192;
+  }
+ } while (0);
+ if ((HEAP32[i4 + 8 >> 2] | 0) != 3) {
+  i4 = _luaV_tonumber(i4, i3) | 0;
+  if ((i4 | 0) == 0) {
+   if ((i1 | 0) == 0) {
+    d8 = 0.0;
+    STACKTOP = i2;
+    return +d8;
+   }
+   HEAP32[i1 >> 2] = 0;
+   d8 = 0.0;
+   STACKTOP = i2;
+   return +d8;
+  }
+ }
+ if ((i1 | 0) != 0) {
+  HEAP32[i1 >> 2] = 1;
+ }
+ d8 = +HEAPF64[i4 >> 3];
+ STACKTOP = i2;
+ return +d8;
+}
+function _luaopen_package(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_getsubtable(i1, -1001e3, 4184) | 0;
+ _lua_createtable(i1, 0, 1);
+ _lua_pushcclosure(i1, 158, 0);
+ _lua_setfield(i1, -2, 4192);
+ _lua_setmetatable(i1, -2) | 0;
+ _lua_createtable(i1, 0, 3);
+ _luaL_setfuncs(i1, 4200, 0);
+ _lua_createtable(i1, 4, 0);
+ _lua_pushvalue(i1, -2);
+ _lua_pushcclosure(i1, 159, 1);
+ _lua_rawseti(i1, -2, 1);
+ _lua_pushvalue(i1, -2);
+ _lua_pushcclosure(i1, 160, 1);
+ _lua_rawseti(i1, -2, 2);
+ _lua_pushvalue(i1, -2);
+ _lua_pushcclosure(i1, 161, 1);
+ _lua_rawseti(i1, -2, 3);
+ _lua_pushvalue(i1, -2);
+ _lua_pushcclosure(i1, 162, 1);
+ _lua_rawseti(i1, -2, 4);
+ _lua_pushvalue(i1, -1);
+ _lua_setfield(i1, -3, 4232);
+ _lua_setfield(i1, -2, 4240);
+ _setpath(i1, 4256, 4264, 4280, 4296);
+ _setpath(i1, 4440, 4448, 4464, 4480);
+ _lua_pushlstring(i1, 4552, 10) | 0;
+ _lua_setfield(i1, -2, 4568);
+ _luaL_getsubtable(i1, -1001e3, 4576) | 0;
+ _lua_setfield(i1, -2, 4584);
+ _luaL_getsubtable(i1, -1001e3, 4592) | 0;
+ _lua_setfield(i1, -2, 4608);
+ _lua_rawgeti(i1, -1001e3, 2);
+ _lua_pushvalue(i1, -2);
+ _luaL_setfuncs(i1, 4616, 1);
+ _lua_settop(i1, -2);
+ STACKTOP = i2;
+ return 1;
+}
+function _lua_rawlen(i3, i5) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i4 = 0;
+ i1 = STACKTOP;
+ i4 = HEAP32[i3 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i2 = (HEAP32[i3 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i2 = (HEAP32[i3 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i3 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i2 = HEAP32[i4 >> 2] | 0, (i3 | 0) <= (HEAPU8[i2 + 6 | 0] | 0 | 0)) : 0) {
+    i2 = i2 + (i3 + -1 << 4) + 16 | 0;
+   } else {
+    i2 = 5192;
+   }
+  } else {
+   i2 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i2 = i2 >>> 0 < (HEAP32[i3 + 8 >> 2] | 0) >>> 0 ? i2 : 5192;
+  }
+ } while (0);
+ i3 = HEAP32[i2 + 8 >> 2] & 15;
+ if ((i3 | 0) == 5) {
+  i5 = _luaH_getn(HEAP32[i2 >> 2] | 0) | 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ } else if ((i3 | 0) == 4) {
+  i5 = HEAP32[(HEAP32[i2 >> 2] | 0) + 12 >> 2] | 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ } else if ((i3 | 0) == 7) {
+  i5 = HEAP32[(HEAP32[i2 >> 2] | 0) + 16 >> 2] | 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ } else {
+  i5 = 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ return 0;
+}
+function _searchpath(i3, i5, i6, i7, i8) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ i7 = i7 | 0;
+ i8 = i8 | 0;
+ var i1 = 0, i2 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 1056 | 0;
+ i4 = i2;
+ i1 = i2 + 8 | 0;
+ _luaL_buffinit(i3, i1);
+ if ((HEAP8[i7] | 0) != 0) {
+  i5 = _luaL_gsub(i3, i5, i7, i8) | 0;
+ }
+ while (1) {
+  i7 = HEAP8[i6] | 0;
+  if (i7 << 24 >> 24 == 59) {
+   i6 = i6 + 1 | 0;
+   continue;
+  } else if (i7 << 24 >> 24 == 0) {
+   i3 = 12;
+   break;
+  }
+  i8 = _strchr(i6, 59) | 0;
+  if ((i8 | 0) == 0) {
+   i8 = i6 + (_strlen(i6 | 0) | 0) | 0;
+  }
+  _lua_pushlstring(i3, i6, i8 - i6 | 0) | 0;
+  if ((i8 | 0) == 0) {
+   i3 = 12;
+   break;
+  }
+  i6 = _luaL_gsub(i3, _lua_tolstring(i3, -1, 0) | 0, 5064, i5) | 0;
+  _lua_remove(i3, -2);
+  i7 = _fopen(i6 | 0, 5088) | 0;
+  if ((i7 | 0) != 0) {
+   i3 = 10;
+   break;
+  }
+  HEAP32[i4 >> 2] = i6;
+  _lua_pushfstring(i3, 5072, i4) | 0;
+  _lua_remove(i3, -2);
+  _luaL_addvalue(i1);
+  i6 = i8;
+ }
+ if ((i3 | 0) == 10) {
+  _fclose(i7 | 0) | 0;
+  i8 = i6;
+  STACKTOP = i2;
+  return i8 | 0;
+ } else if ((i3 | 0) == 12) {
+  _luaL_pushresult(i1);
+  i8 = 0;
+  STACKTOP = i2;
+  return i8 | 0;
+ }
+ return 0;
+}
+function _io_readline(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ i4 = _lua_touserdata(i1, -1001001) | 0;
+ i5 = _lua_tointegerx(i1, -1001002, 0) | 0;
+ if ((HEAP32[i4 + 4 >> 2] | 0) == 0) {
+  i6 = _luaL_error(i1, 3344, i3) | 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ _lua_settop(i1, 1);
+ if ((i5 | 0) >= 1) {
+  i6 = 1;
+  while (1) {
+   _lua_pushvalue(i1, -1001003 - i6 | 0);
+   if ((i6 | 0) == (i5 | 0)) {
+    break;
+   } else {
+    i6 = i6 + 1 | 0;
+   }
+  }
+ }
+ i4 = _g_read(i1, HEAP32[i4 >> 2] | 0, 2) | 0;
+ if ((_lua_type(i1, 0 - i4 | 0) | 0) != 0) {
+  i6 = i4;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ if ((i4 | 0) > 1) {
+  HEAP32[i3 >> 2] = _lua_tolstring(i1, 1 - i4 | 0, 0) | 0;
+  i6 = _luaL_error(i1, 3368, i3) | 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ if ((_lua_toboolean(i1, -1001003) | 0) == 0) {
+  i6 = 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ _lua_settop(i1, 0);
+ _lua_pushvalue(i1, -1001001);
+ i5 = (_luaL_checkudata(i1, 1, 2832) | 0) + 4 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i5 >> 2] = 0;
+ FUNCTION_TABLE_ii[i6 & 255](i1) | 0;
+ i6 = 0;
+ STACKTOP = i2;
+ return i6 | 0;
+}
+function _luaK_setreturns(i3, i5, i6) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i5 >> 2] | 0;
+ if ((i4 | 0) == 13) {
+  i7 = i5 + 8 | 0;
+  i8 = HEAP32[i3 >> 2] | 0;
+  i4 = HEAP32[i8 + 12 >> 2] | 0;
+  i5 = i4 + (HEAP32[i7 >> 2] << 2) | 0;
+  HEAP32[i5 >> 2] = HEAP32[i5 >> 2] & 8388607 | (i6 << 23) + 8388608;
+  i7 = i4 + (HEAP32[i7 >> 2] << 2) | 0;
+  i4 = i3 + 48 | 0;
+  HEAP32[i7 >> 2] = (HEAPU8[i4] | 0) << 6 | HEAP32[i7 >> 2] & -16321;
+  i7 = HEAP8[i4] | 0;
+  i5 = (i7 & 255) + 1 | 0;
+  i6 = i8 + 78 | 0;
+  do {
+   if (i5 >>> 0 > (HEAPU8[i6] | 0) >>> 0) {
+    if (i5 >>> 0 > 249) {
+     _luaX_syntaxerror(HEAP32[i3 + 12 >> 2] | 0, 10536);
+    } else {
+     HEAP8[i6] = i5;
+     i1 = HEAP8[i4] | 0;
+     break;
+    }
+   } else {
+    i1 = i7;
+   }
+  } while (0);
+  HEAP8[i4] = (i1 & 255) + 1;
+  STACKTOP = i2;
+  return;
+ } else if ((i4 | 0) == 12) {
+  i8 = (HEAP32[(HEAP32[i3 >> 2] | 0) + 12 >> 2] | 0) + (HEAP32[i5 + 8 >> 2] << 2) | 0;
+  HEAP32[i8 >> 2] = HEAP32[i8 >> 2] & -8372225 | (i6 << 14) + 16384 & 8372224;
+  STACKTOP = i2;
+  return;
+ } else {
+  STACKTOP = i2;
+  return;
+ }
+}
+function _luaZ_read(i2, i9, i8) {
+ i2 = i2 | 0;
+ i9 = i9 | 0;
+ i8 = i8 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i10 = 0, i11 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i1;
+ if ((i8 | 0) == 0) {
+  i11 = 0;
+  STACKTOP = i1;
+  return i11 | 0;
+ }
+ i7 = i2 + 16 | 0;
+ i6 = i2 + 8 | 0;
+ i4 = i2 + 12 | 0;
+ i5 = i2 + 4 | 0;
+ i11 = HEAP32[i2 >> 2] | 0;
+ while (1) {
+  if ((i11 | 0) == 0) {
+   i10 = FUNCTION_TABLE_iiii[HEAP32[i6 >> 2] & 3](HEAP32[i7 >> 2] | 0, HEAP32[i4 >> 2] | 0, i3) | 0;
+   if ((i10 | 0) == 0) {
+    i2 = 9;
+    break;
+   }
+   i11 = HEAP32[i3 >> 2] | 0;
+   if ((i11 | 0) == 0) {
+    i2 = 9;
+    break;
+   }
+   HEAP32[i2 >> 2] = i11;
+   HEAP32[i5 >> 2] = i10;
+  } else {
+   i10 = HEAP32[i5 >> 2] | 0;
+  }
+  i11 = i8 >>> 0 > i11 >>> 0 ? i11 : i8;
+  _memcpy(i9 | 0, i10 | 0, i11 | 0) | 0;
+  i10 = (HEAP32[i2 >> 2] | 0) - i11 | 0;
+  HEAP32[i2 >> 2] = i10;
+  HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + i11;
+  if ((i8 | 0) == (i11 | 0)) {
+   i8 = 0;
+   i2 = 9;
+   break;
+  } else {
+   i8 = i8 - i11 | 0;
+   i9 = i9 + i11 | 0;
+   i11 = i10;
+  }
+ }
+ if ((i2 | 0) == 9) {
+  STACKTOP = i1;
+  return i8 | 0;
+ }
+ return 0;
+}
+function _lua_load(i1, i5, i4, i3, i6) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ var i2 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i7 = i2;
+ _luaZ_init(i1, i7, i5, i4);
+ i3 = _luaD_protectedparser(i1, i7, (i3 | 0) == 0 ? 928 : i3, i6) | 0;
+ if ((i3 | 0) != 0) {
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ i4 = HEAP32[(HEAP32[i1 + 8 >> 2] | 0) + -16 >> 2] | 0;
+ if ((HEAP8[i4 + 6 | 0] | 0) != 1) {
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ i5 = _luaH_getint(HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 40 >> 2] | 0, 2) | 0;
+ i4 = i4 + 16 | 0;
+ i6 = HEAP32[(HEAP32[i4 >> 2] | 0) + 8 >> 2] | 0;
+ i9 = i5;
+ i8 = HEAP32[i9 + 4 >> 2] | 0;
+ i7 = i6;
+ HEAP32[i7 >> 2] = HEAP32[i9 >> 2];
+ HEAP32[i7 + 4 >> 2] = i8;
+ i7 = i5 + 8 | 0;
+ HEAP32[i6 + 8 >> 2] = HEAP32[i7 >> 2];
+ if ((HEAP32[i7 >> 2] & 64 | 0) == 0) {
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ i5 = HEAP32[i5 >> 2] | 0;
+ if ((HEAP8[i5 + 5 | 0] & 3) == 0) {
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ i4 = HEAP32[i4 >> 2] | 0;
+ if ((HEAP8[i4 + 5 | 0] & 4) == 0) {
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ _luaC_barrier_(i1, i4, i5);
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _g_write(i1, i4, i8) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i8 = i8 | 0;
+ var i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i9 = 0, d10 = 0.0;
+ i5 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i5;
+ i3 = i5 + 8 | 0;
+ i7 = _lua_gettop(i1) | 0;
+ if ((i7 | 0) == (i8 | 0)) {
+  i9 = 1;
+  STACKTOP = i5;
+  return i9 | 0;
+ }
+ i6 = i8;
+ i7 = i7 - i8 | 0;
+ i9 = 1;
+ while (1) {
+  i7 = i7 + -1 | 0;
+  if ((_lua_type(i1, i6) | 0) == 3) {
+   if ((i9 | 0) == 0) {
+    i8 = 0;
+   } else {
+    d10 = +_lua_tonumberx(i1, i6, 0);
+    HEAPF64[tempDoublePtr >> 3] = d10;
+    HEAP32[i2 >> 2] = HEAP32[tempDoublePtr >> 2];
+    HEAP32[i2 + 4 >> 2] = HEAP32[tempDoublePtr + 4 >> 2];
+    i8 = (_fprintf(i4 | 0, 3072, i2 | 0) | 0) > 0;
+   }
+  } else {
+   i8 = _luaL_checklstring(i1, i6, i3) | 0;
+   if ((i9 | 0) == 0) {
+    i8 = 0;
+   } else {
+    i8 = _fwrite(i8 | 0, 1, HEAP32[i3 >> 2] | 0, i4 | 0) | 0;
+    i8 = (i8 | 0) == (HEAP32[i3 >> 2] | 0);
+   }
+  }
+  if ((i7 | 0) == 0) {
+   break;
+  } else {
+   i6 = i6 + 1 | 0;
+   i9 = i8 & 1;
+  }
+ }
+ if (i8) {
+  i9 = 1;
+  STACKTOP = i5;
+  return i9 | 0;
+ }
+ i9 = _luaL_fileresult(i1, 0, 0) | 0;
+ STACKTOP = i5;
+ return i9 | 0;
+}
+function _lua_getuservalue(i2, i5) {
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i3 = 0, i4 = 0;
+ i1 = STACKTOP;
+ i4 = HEAP32[i2 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i3 = (HEAP32[i2 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i3 = (HEAP32[i2 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i4 >> 2] | 0, (i5 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i3 = i3 + (i5 + -1 << 4) + 16 | 0;
+   } else {
+    i3 = 5192;
+   }
+  } else {
+   i3 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i3 = i3 >>> 0 < (HEAP32[i2 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ i3 = HEAP32[(HEAP32[i3 >> 2] | 0) + 12 >> 2] | 0;
+ i2 = i2 + 8 | 0;
+ i4 = HEAP32[i2 >> 2] | 0;
+ if ((i3 | 0) == 0) {
+  HEAP32[i4 + 8 >> 2] = 0;
+  i5 = i4;
+  i5 = i5 + 16 | 0;
+  HEAP32[i2 >> 2] = i5;
+  STACKTOP = i1;
+  return;
+ } else {
+  HEAP32[i4 >> 2] = i3;
+  HEAP32[i4 + 8 >> 2] = 69;
+  i5 = HEAP32[i2 >> 2] | 0;
+  i5 = i5 + 16 | 0;
+  HEAP32[i2 >> 2] = i5;
+  STACKTOP = i1;
+  return;
+ }
+}
+function _luaL_addlstring(i7, i6, i1) {
+ i7 = i7 | 0;
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i8 = 0, i9 = 0;
+ i5 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = HEAP32[i7 + 12 >> 2] | 0;
+ i3 = i7 + 4 | 0;
+ i9 = HEAP32[i3 >> 2] | 0;
+ i2 = i7 + 8 | 0;
+ i8 = HEAP32[i2 >> 2] | 0;
+ if (!((i9 - i8 | 0) >>> 0 < i1 >>> 0)) {
+  i7 = HEAP32[i7 >> 2] | 0;
+  i9 = i8;
+  i9 = i7 + i9 | 0;
+  _memcpy(i9 | 0, i6 | 0, i1 | 0) | 0;
+  i9 = HEAP32[i2 >> 2] | 0;
+  i9 = i9 + i1 | 0;
+  HEAP32[i2 >> 2] = i9;
+  STACKTOP = i5;
+  return;
+ }
+ i9 = i9 << 1;
+ i9 = (i9 - i8 | 0) >>> 0 < i1 >>> 0 ? i8 + i1 | 0 : i9;
+ if (i9 >>> 0 < i8 >>> 0 | (i9 - i8 | 0) >>> 0 < i1 >>> 0) {
+  _luaL_error(i4, 1272, i5) | 0;
+ }
+ i8 = _lua_newuserdata(i4, i9) | 0;
+ _memcpy(i8 | 0, HEAP32[i7 >> 2] | 0, HEAP32[i2 >> 2] | 0) | 0;
+ if ((HEAP32[i7 >> 2] | 0) != (i7 + 16 | 0)) {
+  _lua_remove(i4, -2);
+ }
+ HEAP32[i7 >> 2] = i8;
+ HEAP32[i3 >> 2] = i9;
+ i9 = HEAP32[i2 >> 2] | 0;
+ i9 = i8 + i9 | 0;
+ _memcpy(i9 | 0, i6 | 0, i1 | 0) | 0;
+ i9 = HEAP32[i2 >> 2] | 0;
+ i9 = i9 + i1 | 0;
+ HEAP32[i2 >> 2] = i9;
+ STACKTOP = i5;
+ return;
+}
+function _lua_rawgeti(i3, i6, i1) {
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i7 = 0;
+ i2 = STACKTOP;
+ i5 = HEAP32[i3 + 16 >> 2] | 0;
+ do {
+  if ((i6 | 0) <= 0) {
+   if (!((i6 | 0) < -1000999)) {
+    i4 = (HEAP32[i3 + 8 >> 2] | 0) + (i6 << 4) | 0;
+    break;
+   }
+   if ((i6 | 0) == -1001e3) {
+    i4 = (HEAP32[i3 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i6 = -1001e3 - i6 | 0;
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((HEAP32[i5 + 8 >> 2] | 0) != 22 ? (i4 = HEAP32[i5 >> 2] | 0, (i6 | 0) <= (HEAPU8[i4 + 6 | 0] | 0 | 0)) : 0) {
+    i4 = i4 + (i6 + -1 << 4) + 16 | 0;
+   } else {
+    i4 = 5192;
+   }
+  } else {
+   i4 = (HEAP32[i5 >> 2] | 0) + (i6 << 4) | 0;
+   i4 = i4 >>> 0 < (HEAP32[i3 + 8 >> 2] | 0) >>> 0 ? i4 : 5192;
+  }
+ } while (0);
+ i4 = _luaH_getint(HEAP32[i4 >> 2] | 0, i1) | 0;
+ i6 = i3 + 8 | 0;
+ i5 = HEAP32[i6 >> 2] | 0;
+ i7 = i4;
+ i1 = HEAP32[i7 + 4 >> 2] | 0;
+ i3 = i5;
+ HEAP32[i3 >> 2] = HEAP32[i7 >> 2];
+ HEAP32[i3 + 4 >> 2] = i1;
+ HEAP32[i5 + 8 >> 2] = HEAP32[i4 + 8 >> 2];
+ HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + 16;
+ STACKTOP = i2;
+ return;
+}
+function _lua_setfield(i1, i6, i3) {
+ i1 = i1 | 0;
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i5 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i6 | 0) <= 0) {
+   if (!((i6 | 0) < -1000999)) {
+    i4 = (HEAP32[i1 + 8 >> 2] | 0) + (i6 << 4) | 0;
+    break;
+   }
+   if ((i6 | 0) == -1001e3) {
+    i4 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i6 = -1001e3 - i6 | 0;
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((HEAP32[i5 + 8 >> 2] | 0) != 22 ? (i4 = HEAP32[i5 >> 2] | 0, (i6 | 0) <= (HEAPU8[i4 + 6 | 0] | 0 | 0)) : 0) {
+    i4 = i4 + (i6 + -1 << 4) + 16 | 0;
+   } else {
+    i4 = 5192;
+   }
+  } else {
+   i4 = (HEAP32[i5 >> 2] | 0) + (i6 << 4) | 0;
+   i4 = i4 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i4 : 5192;
+  }
+ } while (0);
+ i6 = i1 + 8 | 0;
+ i5 = HEAP32[i6 >> 2] | 0;
+ HEAP32[i6 >> 2] = i5 + 16;
+ i3 = _luaS_new(i1, i3) | 0;
+ HEAP32[i5 >> 2] = i3;
+ HEAP32[i5 + 8 >> 2] = HEAPU8[i3 + 4 | 0] | 0 | 64;
+ i5 = HEAP32[i6 >> 2] | 0;
+ _luaV_settable(i1, i4, i5 + -16 | 0, i5 + -32 | 0);
+ HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + -32;
+ STACKTOP = i2;
+ return;
+}
+function _luaopen_io(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ _lua_createtable(i1, 0, 11);
+ _luaL_setfuncs(i1, 2680, 0);
+ _luaL_newmetatable(i1, 2832) | 0;
+ _lua_pushvalue(i1, -1);
+ _lua_setfield(i1, -2, 2872);
+ _luaL_setfuncs(i1, 2880, 0);
+ _lua_settop(i1, -2);
+ i5 = HEAP32[_stdin >> 2] | 0;
+ i4 = _lua_newuserdata(i1, 8) | 0;
+ i3 = i4 + 4 | 0;
+ HEAP32[i3 >> 2] = 0;
+ _luaL_setmetatable(i1, 2832);
+ HEAP32[i4 >> 2] = i5;
+ HEAP32[i3 >> 2] = 154;
+ _lua_pushvalue(i1, -1);
+ _lua_setfield(i1, -1001e3, 2776);
+ _lua_setfield(i1, -2, 2792);
+ i3 = HEAP32[_stdout >> 2] | 0;
+ i4 = _lua_newuserdata(i1, 8) | 0;
+ i5 = i4 + 4 | 0;
+ HEAP32[i5 >> 2] = 0;
+ _luaL_setmetatable(i1, 2832);
+ HEAP32[i4 >> 2] = i3;
+ HEAP32[i5 >> 2] = 154;
+ _lua_pushvalue(i1, -1);
+ _lua_setfield(i1, -1001e3, 2800);
+ _lua_setfield(i1, -2, 2816);
+ i5 = HEAP32[_stderr >> 2] | 0;
+ i4 = _lua_newuserdata(i1, 8) | 0;
+ i3 = i4 + 4 | 0;
+ HEAP32[i3 >> 2] = 0;
+ _luaL_setmetatable(i1, 2832);
+ HEAP32[i4 >> 2] = i5;
+ HEAP32[i3 >> 2] = 154;
+ _lua_setfield(i1, -2, 2824);
+ STACKTOP = i2;
+ return 1;
+}
+function _lua_pushcclosure(i1, i4, i5) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i2 = STACKTOP;
+ if ((i5 | 0) == 0) {
+  i6 = HEAP32[i1 + 8 >> 2] | 0;
+  HEAP32[i6 >> 2] = i4;
+  HEAP32[i6 + 8 >> 2] = 22;
+  i6 = i1 + 8 | 0;
+  i5 = HEAP32[i6 >> 2] | 0;
+  i5 = i5 + 16 | 0;
+  HEAP32[i6 >> 2] = i5;
+  STACKTOP = i2;
+  return;
+ }
+ if ((HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+  _luaC_step(i1);
+ }
+ i3 = _luaF_newCclosure(i1, i5) | 0;
+ HEAP32[i3 + 12 >> 2] = i4;
+ i4 = i1 + 8 | 0;
+ i6 = (HEAP32[i4 >> 2] | 0) + (0 - i5 << 4) | 0;
+ HEAP32[i4 >> 2] = i6;
+ do {
+  i5 = i5 + -1 | 0;
+  i9 = i6 + (i5 << 4) | 0;
+  i8 = HEAP32[i9 + 4 >> 2] | 0;
+  i7 = i3 + (i5 << 4) + 16 | 0;
+  HEAP32[i7 >> 2] = HEAP32[i9 >> 2];
+  HEAP32[i7 + 4 >> 2] = i8;
+  HEAP32[i3 + (i5 << 4) + 24 >> 2] = HEAP32[i6 + (i5 << 4) + 8 >> 2];
+  i6 = HEAP32[i4 >> 2] | 0;
+ } while ((i5 | 0) != 0);
+ HEAP32[i6 >> 2] = i3;
+ HEAP32[i6 + 8 >> 2] = 102;
+ i9 = i1 + 8 | 0;
+ i8 = HEAP32[i9 >> 2] | 0;
+ i8 = i8 + 16 | 0;
+ HEAP32[i9 >> 2] = i8;
+ STACKTOP = i2;
+ return;
+}
+function _luaF_findupval(i3, i4) {
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i1 = STACKTOP;
+ i2 = HEAP32[i3 + 12 >> 2] | 0;
+ i6 = i3 + 56 | 0;
+ i5 = HEAP32[i6 >> 2] | 0;
+ L1 : do {
+  if ((i5 | 0) == 0) {
+   i5 = i6;
+  } else {
+   while (1) {
+    i7 = HEAP32[i5 + 8 >> 2] | 0;
+    if (i7 >>> 0 < i4 >>> 0) {
+     i5 = i6;
+     break L1;
+    }
+    if ((i7 | 0) == (i4 | 0)) {
+     break;
+    }
+    i6 = HEAP32[i5 >> 2] | 0;
+    if ((i6 | 0) == 0) {
+     break L1;
+    } else {
+     i7 = i5;
+     i5 = i6;
+     i6 = i7;
+    }
+   }
+   i4 = i5 + 5 | 0;
+   i3 = (HEAPU8[i4] | 0) ^ 3;
+   if ((((HEAPU8[i2 + 60 | 0] | 0) ^ 3) & i3 | 0) != 0) {
+    i7 = i5;
+    STACKTOP = i1;
+    return i7 | 0;
+   }
+   HEAP8[i4] = i3;
+   i7 = i5;
+   STACKTOP = i1;
+   return i7 | 0;
+  }
+ } while (0);
+ i7 = _luaC_newobj(i3, 10, 32, i5, 0) | 0;
+ HEAP32[i7 + 8 >> 2] = i4;
+ i4 = i7 + 16 | 0;
+ HEAP32[i4 >> 2] = i2 + 112;
+ i6 = i2 + 132 | 0;
+ i5 = HEAP32[i6 >> 2] | 0;
+ HEAP32[i4 + 4 >> 2] = i5;
+ HEAP32[i5 + 16 >> 2] = i7;
+ HEAP32[i6 >> 2] = i7;
+ STACKTOP = i1;
+ return i7 | 0;
+}
+function _luaC_checkfinalizer(i5, i4, i6) {
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i7 = 0, i8 = 0;
+ i3 = STACKTOP;
+ i1 = HEAP32[i5 + 12 >> 2] | 0;
+ i2 = i4 + 5 | 0;
+ if ((HEAP8[i2] & 24) != 0 | (i6 | 0) == 0) {
+  STACKTOP = i3;
+  return;
+ }
+ if (!((HEAP8[i6 + 6 | 0] & 4) == 0)) {
+  STACKTOP = i3;
+  return;
+ }
+ if ((_luaT_gettm(i6, 2, HEAP32[i1 + 192 >> 2] | 0) | 0) == 0) {
+  STACKTOP = i3;
+  return;
+ }
+ i7 = i1 + 76 | 0;
+ i8 = HEAP32[i7 >> 2] | 0;
+ if ((i8 | 0) == (i4 | 0)) {
+  do {
+   i6 = _sweeplist(i5, i8, 1) | 0;
+  } while ((i6 | 0) == (i8 | 0));
+  HEAP32[i7 >> 2] = i6;
+ }
+ i5 = i1 + 68 | 0;
+ while (1) {
+  i6 = HEAP32[i5 >> 2] | 0;
+  if ((i6 | 0) == (i4 | 0)) {
+   break;
+  } else {
+   i5 = i6;
+  }
+ }
+ HEAP32[i5 >> 2] = HEAP32[i4 >> 2];
+ i8 = i1 + 72 | 0;
+ HEAP32[i4 >> 2] = HEAP32[i8 >> 2];
+ HEAP32[i8 >> 2] = i4;
+ i4 = HEAPU8[i2] | 0 | 16;
+ HEAP8[i2] = i4;
+ if ((HEAPU8[i1 + 61 | 0] | 0) < 2) {
+  HEAP8[i2] = i4 & 191;
+  STACKTOP = i3;
+  return;
+ } else {
+  HEAP8[i2] = HEAP8[i1 + 60 | 0] & 3 | i4 & 184;
+  STACKTOP = i3;
+  return;
+ }
+}
+function _io_lines(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ if ((_lua_type(i1, 1) | 0) == -1) {
+  _lua_pushnil(i1);
+ }
+ if ((_lua_type(i1, 1) | 0) == 0) {
+  _lua_getfield(i1, -1001e3, 2776);
+  _lua_replace(i1, 1);
+  if ((HEAP32[(_luaL_checkudata(i1, 1, 2832) | 0) + 4 >> 2] | 0) != 0) {
+   i4 = 0;
+   _aux_lines(i1, i4);
+   STACKTOP = i2;
+   return 1;
+  }
+  _luaL_error(i1, 3080, i3) | 0;
+  i4 = 0;
+  _aux_lines(i1, i4);
+  STACKTOP = i2;
+  return 1;
+ } else {
+  i4 = _luaL_checklstring(i1, 1, 0) | 0;
+  i6 = _lua_newuserdata(i1, 8) | 0;
+  i5 = i6 + 4 | 0;
+  HEAP32[i5 >> 2] = 0;
+  _luaL_setmetatable(i1, 2832);
+  HEAP32[i6 >> 2] = 0;
+  HEAP32[i5 >> 2] = 156;
+  i5 = _fopen(i4 | 0, 3480) | 0;
+  HEAP32[i6 >> 2] = i5;
+  if ((i5 | 0) == 0) {
+   i6 = _strerror(HEAP32[(___errno_location() | 0) >> 2] | 0) | 0;
+   HEAP32[i3 >> 2] = i4;
+   HEAP32[i3 + 4 >> 2] = i6;
+   _luaL_error(i1, 3520, i3) | 0;
+  }
+  _lua_replace(i1, 1);
+  i6 = 1;
+  _aux_lines(i1, i6);
+  STACKTOP = i2;
+  return 1;
+ }
+ return 0;
+}
+function _luaC_changemode(i2, i6) {
+ i2 = i2 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i1 = STACKTOP;
+ i3 = i2 + 12 | 0;
+ i5 = HEAP32[i3 >> 2] | 0;
+ i4 = i5 + 62 | 0;
+ if ((HEAPU8[i4] | 0) == (i6 | 0)) {
+  STACKTOP = i1;
+  return;
+ }
+ if ((i6 | 0) == 2) {
+  i3 = i5 + 61 | 0;
+  if ((HEAP8[i3] | 0) != 0) {
+   do {
+    _singlestep(i2) | 0;
+   } while ((HEAP8[i3] | 0) != 0);
+  }
+  HEAP32[i5 + 20 >> 2] = (HEAP32[i5 + 12 >> 2] | 0) + (HEAP32[i5 + 8 >> 2] | 0);
+  HEAP8[i4] = 2;
+  STACKTOP = i1;
+  return;
+ }
+ HEAP8[i4] = 0;
+ i4 = HEAP32[i3 >> 2] | 0;
+ HEAP8[i4 + 61 | 0] = 2;
+ HEAP32[i4 + 64 >> 2] = 0;
+ i5 = i4 + 72 | 0;
+ do {
+  i6 = _sweeplist(i2, i5, 1) | 0;
+ } while ((i6 | 0) == (i5 | 0));
+ HEAP32[i4 + 80 >> 2] = i6;
+ i5 = i4 + 68 | 0;
+ do {
+  i6 = _sweeplist(i2, i5, 1) | 0;
+ } while ((i6 | 0) == (i5 | 0));
+ HEAP32[i4 + 76 >> 2] = i6;
+ i3 = (HEAP32[i3 >> 2] | 0) + 61 | 0;
+ if ((1 << HEAPU8[i3] & -29 | 0) != 0) {
+  STACKTOP = i1;
+  return;
+ }
+ do {
+  _singlestep(i2) | 0;
+ } while ((1 << HEAPU8[i3] & -29 | 0) == 0);
+ STACKTOP = i1;
+ return;
+}
+function _lua_rawget(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i3 = (HEAP32[i1 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i3 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i4 >> 2] | 0, (i5 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i3 = i3 + (i5 + -1 << 4) + 16 | 0;
+   } else {
+    i3 = 5192;
+   }
+  } else {
+   i3 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i3 = i3 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ i5 = i1 + 8 | 0;
+ i4 = _luaH_get(HEAP32[i3 >> 2] | 0, (HEAP32[i5 >> 2] | 0) + -16 | 0) | 0;
+ i5 = HEAP32[i5 >> 2] | 0;
+ i6 = i4;
+ i1 = HEAP32[i6 + 4 >> 2] | 0;
+ i3 = i5 + -16 | 0;
+ HEAP32[i3 >> 2] = HEAP32[i6 >> 2];
+ HEAP32[i3 + 4 >> 2] = i1;
+ HEAP32[i5 + -8 >> 2] = HEAP32[i4 + 8 >> 2];
+ STACKTOP = i2;
+ return;
+}
+function _lua_isstring(i2, i4) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i3 = 0;
+ i1 = STACKTOP;
+ i3 = HEAP32[i2 + 16 >> 2] | 0;
+ do {
+  if ((i4 | 0) <= 0) {
+   if (!((i4 | 0) < -1000999)) {
+    i2 = (HEAP32[i2 + 8 >> 2] | 0) + (i4 << 4) | 0;
+    break;
+   }
+   if ((i4 | 0) == -1001e3) {
+    i2 = (HEAP32[i2 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i2 = -1001e3 - i4 | 0;
+   i3 = HEAP32[i3 >> 2] | 0;
+   if ((HEAP32[i3 + 8 >> 2] | 0) == 22) {
+    i4 = 0;
+    i4 = i4 & 1;
+    STACKTOP = i1;
+    return i4 | 0;
+   }
+   i3 = HEAP32[i3 >> 2] | 0;
+   if ((i2 | 0) > (HEAPU8[i3 + 6 | 0] | 0 | 0)) {
+    i4 = 0;
+    i4 = i4 & 1;
+    STACKTOP = i1;
+    return i4 | 0;
+   } else {
+    i2 = i3 + (i2 + -1 << 4) + 16 | 0;
+    break;
+   }
+  } else {
+   i3 = (HEAP32[i3 >> 2] | 0) + (i4 << 4) | 0;
+   i2 = i3 >>> 0 < (HEAP32[i2 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ if ((i2 | 0) == 5192) {
+  i4 = 0;
+  i4 = i4 & 1;
+  STACKTOP = i1;
+  return i4 | 0;
+ }
+ i4 = ((HEAP32[i2 + 8 >> 2] & 15) + -3 | 0) >>> 0 < 2;
+ i4 = i4 & 1;
+ STACKTOP = i1;
+ return i4 | 0;
+}
+function _setnodevector(i5, i1, i3) {
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ if ((i3 | 0) == 0) {
+  HEAP32[i1 + 16 >> 2] = 8016;
+  i6 = 0;
+  i7 = 8016;
+  i4 = 0;
+  i5 = i1 + 7 | 0;
+  HEAP8[i5] = i4;
+  i6 = i7 + (i6 << 5) | 0;
+  i7 = i1 + 20 | 0;
+  HEAP32[i7 >> 2] = i6;
+  STACKTOP = i2;
+  return;
+ }
+ i4 = _luaO_ceillog2(i3) | 0;
+ if ((i4 | 0) > 30) {
+  _luaG_runerror(i5, 8048, i2);
+ }
+ i3 = 1 << i4;
+ if ((i3 + 1 | 0) >>> 0 > 134217727) {
+  _luaM_toobig(i5);
+ }
+ i6 = _luaM_realloc_(i5, 0, 0, i3 << 5) | 0;
+ i5 = i1 + 16 | 0;
+ HEAP32[i5 >> 2] = i6;
+ if ((i3 | 0) > 0) {
+  i7 = 0;
+  do {
+   HEAP32[i6 + (i7 << 5) + 28 >> 2] = 0;
+   HEAP32[i6 + (i7 << 5) + 24 >> 2] = 0;
+   HEAP32[i6 + (i7 << 5) + 8 >> 2] = 0;
+   i7 = i7 + 1 | 0;
+   i6 = HEAP32[i5 >> 2] | 0;
+  } while ((i7 | 0) != (i3 | 0));
+ }
+ i7 = i3;
+ i4 = i4 & 255;
+ i5 = i1 + 7 | 0;
+ HEAP8[i5] = i4;
+ i6 = i6 + (i7 << 5) | 0;
+ i7 = i1 + 20 | 0;
+ HEAP32[i7 >> 2] = i6;
+ STACKTOP = i2;
+ return;
+}
+function _lua_pushvalue(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i3 = (HEAP32[i1 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i3 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i4 >> 2] | 0, (i5 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i3 = i3 + (i5 + -1 << 4) + 16 | 0;
+   } else {
+    i3 = 5192;
+   }
+  } else {
+   i3 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i3 = i3 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ i5 = i1 + 8 | 0;
+ i4 = HEAP32[i5 >> 2] | 0;
+ i7 = i3;
+ i6 = HEAP32[i7 + 4 >> 2] | 0;
+ i1 = i4;
+ HEAP32[i1 >> 2] = HEAP32[i7 >> 2];
+ HEAP32[i1 + 4 >> 2] = i6;
+ HEAP32[i4 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+ HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + 16;
+ STACKTOP = i2;
+ return;
+}
+function _luaL_setfuncs(i3, i6, i1) {
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ _luaL_checkversion_(i3, 502.0);
+ if ((_lua_checkstack(i3, i1 + 20 | 0) | 0) == 0) {
+  HEAP32[i4 >> 2] = 1472;
+  _luaL_error(i3, 1216, i4) | 0;
+ }
+ if ((HEAP32[i6 >> 2] | 0) == 0) {
+  i7 = ~i1;
+  _lua_settop(i3, i7);
+  STACKTOP = i2;
+  return;
+ }
+ i4 = -2 - i1 | 0;
+ i5 = 0 - i1 | 0;
+ if ((i1 | 0) <= 0) {
+  do {
+   _lua_pushcclosure(i3, HEAP32[i6 + 4 >> 2] | 0, i1);
+   _lua_setfield(i3, i4, HEAP32[i6 >> 2] | 0);
+   i6 = i6 + 8 | 0;
+  } while ((HEAP32[i6 >> 2] | 0) != 0);
+  i7 = ~i1;
+  _lua_settop(i3, i7);
+  STACKTOP = i2;
+  return;
+ }
+ do {
+  i7 = 0;
+  do {
+   _lua_pushvalue(i3, i5);
+   i7 = i7 + 1 | 0;
+  } while ((i7 | 0) != (i1 | 0));
+  _lua_pushcclosure(i3, HEAP32[i6 + 4 >> 2] | 0, i1);
+  _lua_setfield(i3, i4, HEAP32[i6 >> 2] | 0);
+  i6 = i6 + 8 | 0;
+ } while ((HEAP32[i6 >> 2] | 0) != 0);
+ i7 = ~i1;
+ _lua_settop(i3, i7);
+ STACKTOP = i2;
+ return;
+}
+function _lua_touserdata(i3, i5) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i4 = 0;
+ i1 = STACKTOP;
+ i4 = HEAP32[i3 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i2 = (HEAP32[i3 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i2 = (HEAP32[i3 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i3 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i2 = HEAP32[i4 >> 2] | 0, (i3 | 0) <= (HEAPU8[i2 + 6 | 0] | 0 | 0)) : 0) {
+    i2 = i2 + (i3 + -1 << 4) + 16 | 0;
+   } else {
+    i2 = 5192;
+   }
+  } else {
+   i2 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i2 = i2 >>> 0 < (HEAP32[i3 + 8 >> 2] | 0) >>> 0 ? i2 : 5192;
+  }
+ } while (0);
+ i3 = HEAP32[i2 + 8 >> 2] & 15;
+ if ((i3 | 0) == 2) {
+  i5 = HEAP32[i2 >> 2] | 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ } else if ((i3 | 0) == 7) {
+  i5 = (HEAP32[i2 >> 2] | 0) + 24 | 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ } else {
+  i5 = 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ return 0;
+}
+function _luaL_checkoption(i2, i3, i6, i4) {
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i5 = i1;
+ if ((i6 | 0) == 0) {
+  i6 = _lua_tolstring(i2, i3, 0) | 0;
+  if ((i6 | 0) == 0) {
+   i9 = _lua_typename(i2, 4) | 0;
+   i6 = _lua_typename(i2, _lua_type(i2, i3) | 0) | 0;
+   HEAP32[i5 >> 2] = i9;
+   HEAP32[i5 + 4 >> 2] = i6;
+   _luaL_argerror(i2, i3, _lua_pushfstring(i2, 1744, i5) | 0) | 0;
+   i6 = 0;
+  }
+ } else {
+  i6 = _luaL_optlstring(i2, i3, i6, 0) | 0;
+ }
+ i9 = HEAP32[i4 >> 2] | 0;
+ L6 : do {
+  if ((i9 | 0) != 0) {
+   i8 = 0;
+   while (1) {
+    i7 = i8 + 1 | 0;
+    if ((_strcmp(i9, i6) | 0) == 0) {
+     break;
+    }
+    i9 = HEAP32[i4 + (i7 << 2) >> 2] | 0;
+    if ((i9 | 0) == 0) {
+     break L6;
+    } else {
+     i8 = i7;
+    }
+   }
+   STACKTOP = i1;
+   return i8 | 0;
+  }
+ } while (0);
+ HEAP32[i5 >> 2] = i6;
+ i9 = _luaL_argerror(i2, i3, _lua_pushfstring(i2, 1192, i5) | 0) | 0;
+ STACKTOP = i1;
+ return i9 | 0;
+}
+function _lua_toboolean(i3, i5) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i4 = 0;
+ i1 = STACKTOP;
+ i4 = HEAP32[i3 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i3 = (HEAP32[i3 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i3 = (HEAP32[i3 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i3 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i2 = HEAP32[i4 >> 2] | 0, (i3 | 0) <= (HEAPU8[i2 + 6 | 0] | 0 | 0)) : 0) {
+    i3 = i2 + (i3 + -1 << 4) + 16 | 0;
+   } else {
+    i3 = 5192;
+   }
+  } else {
+   i2 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i3 = i2 >>> 0 < (HEAP32[i3 + 8 >> 2] | 0) >>> 0 ? i2 : 5192;
+  }
+ } while (0);
+ i2 = HEAP32[i3 + 8 >> 2] | 0;
+ if ((i2 | 0) == 0) {
+  i5 = 0;
+  i5 = i5 & 1;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ if ((i2 | 0) != 1) {
+  i5 = 1;
+  i5 = i5 & 1;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ i5 = (HEAP32[i3 >> 2] | 0) != 0;
+ i5 = i5 & 1;
+ STACKTOP = i1;
+ return i5 | 0;
+}
+function _lua_getfield(i1, i6, i3) {
+ i1 = i1 | 0;
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i5 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i6 | 0) <= 0) {
+   if (!((i6 | 0) < -1000999)) {
+    i4 = (HEAP32[i1 + 8 >> 2] | 0) + (i6 << 4) | 0;
+    break;
+   }
+   if ((i6 | 0) == -1001e3) {
+    i4 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i6 = -1001e3 - i6 | 0;
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((HEAP32[i5 + 8 >> 2] | 0) != 22 ? (i4 = HEAP32[i5 >> 2] | 0, (i6 | 0) <= (HEAPU8[i4 + 6 | 0] | 0 | 0)) : 0) {
+    i4 = i4 + (i6 + -1 << 4) + 16 | 0;
+   } else {
+    i4 = 5192;
+   }
+  } else {
+   i4 = (HEAP32[i5 >> 2] | 0) + (i6 << 4) | 0;
+   i4 = i4 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i4 : 5192;
+  }
+ } while (0);
+ i5 = i1 + 8 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ i3 = _luaS_new(i1, i3) | 0;
+ HEAP32[i6 >> 2] = i3;
+ HEAP32[i6 + 8 >> 2] = HEAPU8[i3 + 4 | 0] | 0 | 64;
+ i6 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i5 >> 2] = i6 + 16;
+ _luaV_gettable(i1, i4, i6, i6);
+ STACKTOP = i2;
+ return;
+}
+function _luaL_argerror(i1, i6, i3) {
+ i1 = i1 | 0;
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 112 | 0;
+ i2 = i4;
+ i5 = i4 + 12 | 0;
+ if ((_lua_getstack(i1, 0, i5) | 0) == 0) {
+  HEAP32[i2 >> 2] = i6;
+  HEAP32[i2 + 4 >> 2] = i3;
+  i8 = _luaL_error(i1, 1040, i2) | 0;
+  STACKTOP = i4;
+  return i8 | 0;
+ }
+ _lua_getinfo(i1, 1064, i5) | 0;
+ if ((_strcmp(HEAP32[i5 + 8 >> 2] | 0, 1072) | 0) == 0) {
+  i6 = i6 + -1 | 0;
+  if ((i6 | 0) == 0) {
+   HEAP32[i2 >> 2] = HEAP32[i5 + 4 >> 2];
+   HEAP32[i2 + 4 >> 2] = i3;
+   i8 = _luaL_error(i1, 1080, i2) | 0;
+   STACKTOP = i4;
+   return i8 | 0;
+  }
+ }
+ i7 = i5 + 4 | 0;
+ i8 = HEAP32[i7 >> 2] | 0;
+ if ((i8 | 0) == 0) {
+  if ((_pushglobalfuncname(i1, i5) | 0) == 0) {
+   i8 = 1112;
+  } else {
+   i8 = _lua_tolstring(i1, -1, 0) | 0;
+  }
+  HEAP32[i7 >> 2] = i8;
+ }
+ HEAP32[i2 >> 2] = i6;
+ HEAP32[i2 + 4 >> 2] = i8;
+ HEAP32[i2 + 8 >> 2] = i3;
+ i8 = _luaL_error(i1, 1120, i2) | 0;
+ STACKTOP = i4;
+ return i8 | 0;
+}
+function _match_class(i3, i2) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i1 = 0;
+ i1 = STACKTOP;
+ switch (_tolower(i2 | 0) | 0) {
+ case 117:
+  {
+   i3 = _isupper(i3 | 0) | 0;
+   break;
+  }
+ case 97:
+  {
+   i3 = _isalpha(i3 | 0) | 0;
+   break;
+  }
+ case 99:
+  {
+   i3 = _iscntrl(i3 | 0) | 0;
+   break;
+  }
+ case 120:
+  {
+   i3 = _isxdigit(i3 | 0) | 0;
+   break;
+  }
+ case 119:
+  {
+   i3 = _isalnum(i3 | 0) | 0;
+   break;
+  }
+ case 112:
+  {
+   i3 = _ispunct(i3 | 0) | 0;
+   break;
+  }
+ case 100:
+  {
+   i3 = (i3 + -48 | 0) >>> 0 < 10 | 0;
+   break;
+  }
+ case 108:
+  {
+   i3 = _islower(i3 | 0) | 0;
+   break;
+  }
+ case 122:
+  {
+   i3 = (i3 | 0) == 0 | 0;
+   break;
+  }
+ case 103:
+  {
+   i3 = _isgraph(i3 | 0) | 0;
+   break;
+  }
+ case 115:
+  {
+   i3 = _isspace(i3 | 0) | 0;
+   break;
+  }
+ default:
+  {
+   i3 = (i2 | 0) == (i3 | 0) | 0;
+   STACKTOP = i1;
+   return i3 | 0;
+  }
+ }
+ if ((_islower(i2 | 0) | 0) != 0) {
+  STACKTOP = i1;
+  return i3 | 0;
+ }
+ i3 = (i3 | 0) == 0 | 0;
+ STACKTOP = i1;
+ return i3 | 0;
+}
+function _condjump(i1, i3, i6, i4, i5) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i2 = STACKTOP;
+ _luaK_code(i1, i6 << 6 | i3 | i4 << 23 | i5 << 14) | 0;
+ i3 = i1 + 28 | 0;
+ i6 = HEAP32[i3 >> 2] | 0;
+ HEAP32[i3 >> 2] = -1;
+ i3 = _luaK_code(i1, 2147450903) | 0;
+ if ((i6 | 0) == -1) {
+  i9 = i3;
+  STACKTOP = i2;
+  return i9 | 0;
+ }
+ if ((i3 | 0) == -1) {
+  i9 = i6;
+  STACKTOP = i2;
+  return i9 | 0;
+ }
+ i8 = HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0;
+ i7 = i3;
+ while (1) {
+  i4 = i8 + (i7 << 2) | 0;
+  i5 = HEAP32[i4 >> 2] | 0;
+  i9 = (i5 >>> 14) + -131071 | 0;
+  if ((i9 | 0) == -1) {
+   break;
+  }
+  i9 = i7 + 1 + i9 | 0;
+  if ((i9 | 0) == -1) {
+   break;
+  } else {
+   i7 = i9;
+  }
+ }
+ i6 = i6 + ~i7 | 0;
+ if ((((i6 | 0) > -1 ? i6 : 0 - i6 | 0) | 0) > 131071) {
+  _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10624);
+ }
+ HEAP32[i4 >> 2] = (i6 << 14) + 2147467264 | i5 & 16383;
+ i9 = i3;
+ STACKTOP = i2;
+ return i9 | 0;
+}
+function _skipcomment(i6, i1) {
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ HEAP32[i6 >> 2] = 0;
+ i3 = i6 + 4 | 0;
+ i5 = 1712;
+ while (1) {
+  i7 = _fgetc(HEAP32[i3 >> 2] | 0) | 0;
+  if ((i7 | 0) == -1) {
+   i4 = 3;
+   break;
+  }
+  i8 = i5 + 1 | 0;
+  if ((i7 | 0) != (HEAPU8[i5] | 0)) {
+   break;
+  }
+  i5 = HEAP32[i6 >> 2] | 0;
+  HEAP32[i6 >> 2] = i5 + 1;
+  HEAP8[i6 + i5 + 8 | 0] = i7;
+  if ((HEAP8[i8] | 0) == 0) {
+   i4 = 6;
+   break;
+  } else {
+   i5 = i8;
+  }
+ }
+ if ((i4 | 0) == 3) {
+  HEAP32[i1 >> 2] = -1;
+  i8 = 0;
+  STACKTOP = i2;
+  return i8 | 0;
+ } else if ((i4 | 0) == 6) {
+  HEAP32[i6 >> 2] = 0;
+  i7 = _fgetc(HEAP32[i3 >> 2] | 0) | 0;
+ }
+ HEAP32[i1 >> 2] = i7;
+ if ((i7 | 0) != 35) {
+  i8 = 0;
+  STACKTOP = i2;
+  return i8 | 0;
+ }
+ do {
+  i8 = _fgetc(HEAP32[i3 >> 2] | 0) | 0;
+ } while (!((i8 | 0) == 10 | (i8 | 0) == -1));
+ HEAP32[i1 >> 2] = _fgetc(HEAP32[i3 >> 2] | 0) | 0;
+ i8 = 1;
+ STACKTOP = i2;
+ return i8 | 0;
+}
+function _lua_isnumber(i4, i6) {
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i1;
+ i5 = HEAP32[i4 + 16 >> 2] | 0;
+ do {
+  if ((i6 | 0) <= 0) {
+   if (!((i6 | 0) < -1000999)) {
+    i3 = (HEAP32[i4 + 8 >> 2] | 0) + (i6 << 4) | 0;
+    break;
+   }
+   if ((i6 | 0) == -1001e3) {
+    i3 = (HEAP32[i4 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i4 = -1001e3 - i6 | 0;
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((HEAP32[i5 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i5 >> 2] | 0, (i4 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i3 = i3 + (i4 + -1 << 4) + 16 | 0;
+   } else {
+    i3 = 5192;
+   }
+  } else {
+   i3 = (HEAP32[i5 >> 2] | 0) + (i6 << 4) | 0;
+   i3 = i3 >>> 0 < (HEAP32[i4 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ if ((HEAP32[i3 + 8 >> 2] | 0) == 3) {
+  i6 = 1;
+  i6 = i6 & 1;
+  STACKTOP = i1;
+  return i6 | 0;
+ }
+ i6 = (_luaV_tonumber(i3, i2) | 0) != 0;
+ i6 = i6 & 1;
+ STACKTOP = i1;
+ return i6 | 0;
+}
+function ___shgetc(i3) {
+ i3 = i3 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ i7 = i3 + 104 | 0;
+ i6 = HEAP32[i7 >> 2] | 0;
+ if (!((i6 | 0) != 0 ? (HEAP32[i3 + 108 >> 2] | 0) >= (i6 | 0) : 0)) {
+  i8 = 3;
+ }
+ if ((i8 | 0) == 3 ? (i1 = ___uflow(i3) | 0, (i1 | 0) >= 0) : 0) {
+  i7 = HEAP32[i7 >> 2] | 0;
+  i6 = HEAP32[i3 + 8 >> 2] | 0;
+  if ((i7 | 0) != 0 ? (i4 = HEAP32[i3 + 4 >> 2] | 0, i5 = i7 - (HEAP32[i3 + 108 >> 2] | 0) + -1 | 0, (i6 - i4 | 0) > (i5 | 0)) : 0) {
+   HEAP32[i3 + 100 >> 2] = i4 + i5;
+  } else {
+   HEAP32[i3 + 100 >> 2] = i6;
+  }
+  i4 = HEAP32[i3 + 4 >> 2] | 0;
+  if ((i6 | 0) != 0) {
+   i8 = i3 + 108 | 0;
+   HEAP32[i8 >> 2] = i6 + 1 - i4 + (HEAP32[i8 >> 2] | 0);
+  }
+  i3 = i4 + -1 | 0;
+  if ((HEAPU8[i3] | 0 | 0) == (i1 | 0)) {
+   i8 = i1;
+   STACKTOP = i2;
+   return i8 | 0;
+  }
+  HEAP8[i3] = i1;
+  i8 = i1;
+  STACKTOP = i2;
+  return i8 | 0;
+ }
+ HEAP32[i3 + 100 >> 2] = 0;
+ i8 = -1;
+ STACKTOP = i2;
+ return i8 | 0;
+}
+function _lua_type(i2, i4) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i3 = 0;
+ i1 = STACKTOP;
+ i3 = HEAP32[i2 + 16 >> 2] | 0;
+ do {
+  if ((i4 | 0) <= 0) {
+   if (!((i4 | 0) < -1000999)) {
+    i2 = (HEAP32[i2 + 8 >> 2] | 0) + (i4 << 4) | 0;
+    break;
+   }
+   if ((i4 | 0) == -1001e3) {
+    i2 = (HEAP32[i2 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i2 = -1001e3 - i4 | 0;
+   i3 = HEAP32[i3 >> 2] | 0;
+   if ((HEAP32[i3 + 8 >> 2] | 0) == 22) {
+    i4 = -1;
+    STACKTOP = i1;
+    return i4 | 0;
+   }
+   i3 = HEAP32[i3 >> 2] | 0;
+   if ((i2 | 0) > (HEAPU8[i3 + 6 | 0] | 0 | 0)) {
+    i4 = -1;
+    STACKTOP = i1;
+    return i4 | 0;
+   } else {
+    i2 = i3 + (i2 + -1 << 4) + 16 | 0;
+    break;
+   }
+  } else {
+   i3 = (HEAP32[i3 >> 2] | 0) + (i4 << 4) | 0;
+   i2 = i3 >>> 0 < (HEAP32[i2 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ if ((i2 | 0) == 5192) {
+  i4 = -1;
+  STACKTOP = i1;
+  return i4 | 0;
+ }
+ i4 = HEAP32[i2 + 8 >> 2] & 15;
+ STACKTOP = i1;
+ return i4 | 0;
+}
+function _g_iofile(i4, i1, i5) {
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ if ((_lua_type(i4, 1) | 0) < 1) {
+  _lua_getfield(i4, -1001e3, i1);
+  STACKTOP = i2;
+  return;
+ }
+ i6 = _lua_tolstring(i4, 1, 0) | 0;
+ if ((i6 | 0) != 0) {
+  i7 = _lua_newuserdata(i4, 8) | 0;
+  i8 = i7 + 4 | 0;
+  HEAP32[i8 >> 2] = 0;
+  _luaL_setmetatable(i4, 2832);
+  HEAP32[i7 >> 2] = 0;
+  HEAP32[i8 >> 2] = 156;
+  i5 = _fopen(i6 | 0, i5 | 0) | 0;
+  HEAP32[i7 >> 2] = i5;
+  if ((i5 | 0) == 0) {
+   i8 = _strerror(HEAP32[(___errno_location() | 0) >> 2] | 0) | 0;
+   HEAP32[i3 >> 2] = i6;
+   HEAP32[i3 + 4 >> 2] = i8;
+   _luaL_error(i4, 3520, i3) | 0;
+  }
+ } else {
+  if ((HEAP32[(_luaL_checkudata(i4, 1, 2832) | 0) + 4 >> 2] | 0) == 0) {
+   _luaL_error(i4, 3080, i3) | 0;
+  }
+  _lua_pushvalue(i4, 1);
+ }
+ _lua_setfield(i4, -1001e3, i1);
+ _lua_getfield(i4, -1001e3, i1);
+ STACKTOP = i2;
+ return;
+}
+function _lua_getlocal(i4, i5, i2) {
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i1;
+ if ((i5 | 0) == 0) {
+  i3 = HEAP32[i4 + 8 >> 2] | 0;
+  if ((HEAP32[i3 + -8 >> 2] | 0) != 70) {
+   i5 = 0;
+   STACKTOP = i1;
+   return i5 | 0;
+  }
+  i5 = _luaF_getlocalname(HEAP32[(HEAP32[i3 + -16 >> 2] | 0) + 12 >> 2] | 0, i2, 0) | 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ } else {
+  HEAP32[i3 >> 2] = 0;
+  i2 = _findlocal(i4, HEAP32[i5 + 96 >> 2] | 0, i2, i3) | 0;
+  if ((i2 | 0) == 0) {
+   i5 = 0;
+   STACKTOP = i1;
+   return i5 | 0;
+  }
+  i3 = HEAP32[i3 >> 2] | 0;
+  i5 = i4 + 8 | 0;
+  i4 = HEAP32[i5 >> 2] | 0;
+  i8 = i3;
+  i7 = HEAP32[i8 + 4 >> 2] | 0;
+  i6 = i4;
+  HEAP32[i6 >> 2] = HEAP32[i8 >> 2];
+  HEAP32[i6 + 4 >> 2] = i7;
+  HEAP32[i4 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+  HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + 16;
+  i5 = i2;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ return 0;
+}
+function _lua_checkstack(i7, i4) {
+ i7 = i7 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i6 = 0, i8 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i1;
+ HEAP32[i3 >> 2] = i4;
+ i2 = HEAP32[i7 + 16 >> 2] | 0;
+ i5 = i7 + 8 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ i8 = i6;
+ do {
+  if (((HEAP32[i7 + 24 >> 2] | 0) - i8 >> 4 | 0) <= (i4 | 0)) {
+   if (((i8 - (HEAP32[i7 + 28 >> 2] | 0) >> 4) + 5 | 0) > (1e6 - i4 | 0)) {
+    i8 = 0;
+    STACKTOP = i1;
+    return i8 | 0;
+   }
+   i6 = (_luaD_rawrunprotected(i7, 2, i3) | 0) == 0;
+   if (i6) {
+    i5 = HEAP32[i5 >> 2] | 0;
+    i4 = HEAP32[i3 >> 2] | 0;
+    i3 = i6 & 1;
+    break;
+   } else {
+    i8 = 0;
+    STACKTOP = i1;
+    return i8 | 0;
+   }
+  } else {
+   i5 = i6;
+   i3 = 1;
+  }
+ } while (0);
+ i2 = i2 + 4 | 0;
+ i4 = i5 + (i4 << 4) | 0;
+ if (!((HEAP32[i2 >> 2] | 0) >>> 0 < i4 >>> 0)) {
+  i8 = i3;
+  STACKTOP = i1;
+  return i8 | 0;
+ }
+ HEAP32[i2 >> 2] = i4;
+ i8 = i3;
+ STACKTOP = i1;
+ return i8 | 0;
+}
+function _luaK_exp2nextreg(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ _luaK_dischargevars(i1, i3);
+ if (((HEAP32[i3 >> 2] | 0) == 6 ? (i4 = HEAP32[i3 + 8 >> 2] | 0, (i4 & 256 | 0) == 0) : 0) ? (HEAPU8[i1 + 46 | 0] | 0 | 0) <= (i4 | 0) : 0) {
+  i7 = i1 + 48 | 0;
+  HEAP8[i7] = (HEAP8[i7] | 0) + -1 << 24 >> 24;
+ }
+ i4 = i1 + 48 | 0;
+ i5 = HEAP8[i4] | 0;
+ i6 = (i5 & 255) + 1 | 0;
+ i7 = (HEAP32[i1 >> 2] | 0) + 78 | 0;
+ if (!(i6 >>> 0 > (HEAPU8[i7] | 0) >>> 0)) {
+  i7 = i5;
+  i7 = i7 & 255;
+  i7 = i7 + 1 | 0;
+  i6 = i7 & 255;
+  HEAP8[i4] = i6;
+  i7 = i7 & 255;
+  i7 = i7 + -1 | 0;
+  _exp2reg(i1, i3, i7);
+  STACKTOP = i2;
+  return;
+ }
+ if (i6 >>> 0 > 249) {
+  _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10536);
+ }
+ HEAP8[i7] = i6;
+ i7 = HEAP8[i4] | 0;
+ i7 = i7 & 255;
+ i7 = i7 + 1 | 0;
+ i6 = i7 & 255;
+ HEAP8[i4] = i6;
+ i7 = i7 & 255;
+ i7 = i7 + -1 | 0;
+ _exp2reg(i1, i3, i7);
+ STACKTOP = i2;
+ return;
+}
+function _lua_next(i2, i4) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i3 = 0, i5 = 0;
+ i1 = STACKTOP;
+ i5 = HEAP32[i2 + 16 >> 2] | 0;
+ do {
+  if ((i4 | 0) <= 0) {
+   if (!((i4 | 0) < -1000999)) {
+    i4 = (HEAP32[i2 + 8 >> 2] | 0) + (i4 << 4) | 0;
+    break;
+   }
+   if ((i4 | 0) == -1001e3) {
+    i4 = (HEAP32[i2 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i4 = -1001e3 - i4 | 0;
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((HEAP32[i5 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i5 >> 2] | 0, (i4 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i4 = i3 + (i4 + -1 << 4) + 16 | 0;
+   } else {
+    i4 = 5192;
+   }
+  } else {
+   i3 = (HEAP32[i5 >> 2] | 0) + (i4 << 4) | 0;
+   i4 = i3 >>> 0 < (HEAP32[i2 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ i3 = i2 + 8 | 0;
+ i2 = _luaH_next(i2, HEAP32[i4 >> 2] | 0, (HEAP32[i3 >> 2] | 0) + -16 | 0) | 0;
+ i4 = HEAP32[i3 >> 2] | 0;
+ HEAP32[i3 >> 2] = (i2 | 0) == 0 ? i4 + -16 | 0 : i4 + 16 | 0;
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _inclinenumber(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i1 >> 2] | 0;
+ i3 = i1 + 56 | 0;
+ i5 = HEAP32[i3 >> 2] | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i5 >> 2] = i6 + -1;
+ if ((i6 | 0) == 0) {
+  i5 = _luaZ_fill(i5) | 0;
+ } else {
+  i6 = i5 + 4 | 0;
+  i5 = HEAP32[i6 >> 2] | 0;
+  HEAP32[i6 >> 2] = i5 + 1;
+  i5 = HEAPU8[i5] | 0;
+ }
+ HEAP32[i1 >> 2] = i5;
+ if ((i5 | 0) == 13 | (i5 | 0) == 10 ? (i5 | 0) != (i4 | 0) : 0) {
+  i3 = HEAP32[i3 >> 2] | 0;
+  i6 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i3 >> 2] = i6 + -1;
+  if ((i6 | 0) == 0) {
+   i3 = _luaZ_fill(i3) | 0;
+  } else {
+   i6 = i3 + 4 | 0;
+   i3 = HEAP32[i6 >> 2] | 0;
+   HEAP32[i6 >> 2] = i3 + 1;
+   i3 = HEAPU8[i3] | 0;
+  }
+  HEAP32[i1 >> 2] = i3;
+ }
+ i5 = i1 + 4 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i5 >> 2] = i6 + 1;
+ if ((i6 | 0) > 2147483643) {
+  _luaX_syntaxerror(i1, 12560);
+ } else {
+  STACKTOP = i2;
+  return;
+ }
+}
+function _lua_yieldk(i5, i6, i1, i7) {
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ i7 = i7 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ i3 = HEAP32[i5 + 16 >> 2] | 0;
+ if ((HEAP16[i5 + 36 >> 1] | 0) != 0) {
+  if ((HEAP32[(HEAP32[i5 + 12 >> 2] | 0) + 172 >> 2] | 0) == (i5 | 0)) {
+   _luaG_runerror(i5, 2312, i4);
+  } else {
+   _luaG_runerror(i5, 2264, i4);
+  }
+ }
+ HEAP8[i5 + 6 | 0] = 1;
+ HEAP32[i3 + 20 >> 2] = (HEAP32[i3 >> 2] | 0) - (HEAP32[i5 + 28 >> 2] | 0);
+ if (!((HEAP8[i3 + 18 | 0] & 1) == 0)) {
+  STACKTOP = i2;
+  return 0;
+ }
+ HEAP32[i3 + 28 >> 2] = i7;
+ if ((i7 | 0) == 0) {
+  i4 = i5 + 8 | 0;
+  i4 = HEAP32[i4 >> 2] | 0;
+  i7 = ~i6;
+  i7 = i4 + (i7 << 4) | 0;
+  HEAP32[i3 >> 2] = i7;
+  _luaD_throw(i5, 1);
+ }
+ HEAP32[i3 + 24 >> 2] = i1;
+ i4 = i5 + 8 | 0;
+ i4 = HEAP32[i4 >> 2] | 0;
+ i7 = ~i6;
+ i7 = i4 + (i7 << 4) | 0;
+ HEAP32[i3 >> 2] = i7;
+ _luaD_throw(i5, 1);
+ return 0;
+}
+function _luaH_getint(i4, i6) {
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, d3 = 0.0, i5 = 0, i7 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i5 = i1;
+ i7 = i6 + -1 | 0;
+ if (i7 >>> 0 < (HEAP32[i4 + 28 >> 2] | 0) >>> 0) {
+  i7 = (HEAP32[i4 + 12 >> 2] | 0) + (i7 << 4) | 0;
+  STACKTOP = i1;
+  return i7 | 0;
+ }
+ d3 = +(i6 | 0);
+ HEAPF64[i5 >> 3] = d3 + 1.0;
+ i5 = (HEAP32[i5 + 4 >> 2] | 0) + (HEAP32[i5 >> 2] | 0) | 0;
+ if ((i5 | 0) < 0) {
+  i6 = 0 - i5 | 0;
+  i5 = (i5 | 0) == (i6 | 0) ? 0 : i6;
+ }
+ i4 = (HEAP32[i4 + 16 >> 2] | 0) + (((i5 | 0) % ((1 << (HEAPU8[i4 + 7 | 0] | 0)) + -1 | 1 | 0) | 0) << 5) | 0;
+ while (1) {
+  if ((HEAP32[i4 + 24 >> 2] | 0) == 3 ? +HEAPF64[i4 + 16 >> 3] == d3 : 0) {
+   break;
+  }
+  i4 = HEAP32[i4 + 28 >> 2] | 0;
+  if ((i4 | 0) == 0) {
+   i4 = 5192;
+   i2 = 10;
+   break;
+  }
+ }
+ if ((i2 | 0) == 10) {
+  STACKTOP = i1;
+  return i4 | 0;
+ }
+ i7 = i4;
+ STACKTOP = i1;
+ return i7 | 0;
+}
+function _luaL_checkversion_(i1, d4) {
+ i1 = i1 | 0;
+ d4 = +d4;
+ var i2 = 0, i3 = 0, i5 = 0, d6 = 0.0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ i5 = _lua_version(i1) | 0;
+ if ((i5 | 0) == (_lua_version(0) | 0)) {
+  d6 = +HEAPF64[i5 >> 3];
+  if (d6 != d4) {
+   HEAPF64[tempDoublePtr >> 3] = d4;
+   HEAP32[i3 >> 2] = HEAP32[tempDoublePtr >> 2];
+   HEAP32[i3 + 4 >> 2] = HEAP32[tempDoublePtr + 4 >> 2];
+   i5 = i3 + 8 | 0;
+   HEAPF64[tempDoublePtr >> 3] = d6;
+   HEAP32[i5 >> 2] = HEAP32[tempDoublePtr >> 2];
+   HEAP32[i5 + 4 >> 2] = HEAP32[tempDoublePtr + 4 >> 2];
+   _luaL_error(i1, 1528, i3) | 0;
+  }
+ } else {
+  _luaL_error(i1, 1496, i3) | 0;
+ }
+ _lua_pushnumber(i1, -4660.0);
+ if ((_lua_tointegerx(i1, -1, 0) | 0) == -4660 ? (_lua_tounsignedx(i1, -1, 0) | 0) == -4660 : 0) {
+  _lua_settop(i1, -2);
+  STACKTOP = i2;
+  return;
+ }
+ _luaL_error(i1, 1584, i3) | 0;
+ _lua_settop(i1, -2);
+ STACKTOP = i2;
+ return;
+}
+function _math_random(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, d3 = 0.0, i4 = 0, i5 = 0, d6 = 0.0, d7 = 0.0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ d3 = +((_rand() | 0) % 2147483647 | 0 | 0) / 2147483647.0;
+ i5 = _lua_gettop(i1) | 0;
+ if ((i5 | 0) == 0) {
+  _lua_pushnumber(i1, d3);
+  i5 = 1;
+  STACKTOP = i2;
+  return i5 | 0;
+ } else if ((i5 | 0) == 1) {
+  d6 = +_luaL_checknumber(i1, 1);
+  if (!(d6 >= 1.0)) {
+   _luaL_argerror(i1, 1, 4056) | 0;
+  }
+  _lua_pushnumber(i1, +Math_floor(+(d3 * d6)) + 1.0);
+  i5 = 1;
+  STACKTOP = i2;
+  return i5 | 0;
+ } else if ((i5 | 0) == 2) {
+  d6 = +_luaL_checknumber(i1, 1);
+  d7 = +_luaL_checknumber(i1, 2);
+  if (!(d6 <= d7)) {
+   _luaL_argerror(i1, 2, 4056) | 0;
+  }
+  _lua_pushnumber(i1, d6 + +Math_floor(+(d3 * (d7 - d6 + 1.0))));
+  i5 = 1;
+  STACKTOP = i2;
+  return i5 | 0;
+ } else {
+  i5 = _luaL_error(i1, 4080, i4) | 0;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ return 0;
+}
+function _push_onecapture(i2, i3, i4, i6) {
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i5 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i5 = i1;
+ if ((HEAP32[i2 + 20 >> 2] | 0) <= (i3 | 0)) {
+  i2 = HEAP32[i2 + 16 >> 2] | 0;
+  if ((i3 | 0) == 0) {
+   _lua_pushlstring(i2, i4, i6 - i4 | 0) | 0;
+   STACKTOP = i1;
+   return;
+  } else {
+   _luaL_error(i2, 7224, i5) | 0;
+   STACKTOP = i1;
+   return;
+  }
+ }
+ i4 = HEAP32[i2 + (i3 << 3) + 28 >> 2] | 0;
+ if (!((i4 | 0) == -1)) {
+  i5 = HEAP32[i2 + 16 >> 2] | 0;
+  i3 = HEAP32[i2 + (i3 << 3) + 24 >> 2] | 0;
+  if ((i4 | 0) == -2) {
+   _lua_pushinteger(i5, i3 + 1 - (HEAP32[i2 + 4 >> 2] | 0) | 0);
+   STACKTOP = i1;
+   return;
+  }
+ } else {
+  i6 = i2 + 16 | 0;
+  _luaL_error(HEAP32[i6 >> 2] | 0, 7248, i5) | 0;
+  i5 = HEAP32[i6 >> 2] | 0;
+  i3 = HEAP32[i2 + (i3 << 3) + 24 >> 2] | 0;
+ }
+ _lua_pushlstring(i5, i3, i4) | 0;
+ STACKTOP = i1;
+ return;
+}
+function _luaK_nil(i7, i6, i5) {
+ i7 = i7 | 0;
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0;
+ i2 = STACKTOP;
+ i9 = i5 + i6 | 0;
+ i1 = i9 + -1 | 0;
+ i10 = HEAP32[i7 + 20 >> 2] | 0;
+ do {
+  if ((i10 | 0) > (HEAP32[i7 + 24 >> 2] | 0) ? (i4 = (HEAP32[(HEAP32[i7 >> 2] | 0) + 12 >> 2] | 0) + (i10 + -1 << 2) | 0, i3 = HEAP32[i4 >> 2] | 0, (i3 & 63 | 0) == 4) : 0) {
+   i11 = i3 >>> 6 & 255;
+   i10 = i11 + (i3 >>> 23) | 0;
+   if (!((i11 | 0) <= (i6 | 0) ? (i10 + 1 | 0) >= (i6 | 0) : 0)) {
+    i8 = 5;
+   }
+   if ((i8 | 0) == 5 ? (i11 | 0) < (i6 | 0) | (i11 | 0) > (i9 | 0) : 0) {
+    break;
+   }
+   i5 = (i11 | 0) < (i6 | 0) ? i11 : i6;
+   HEAP32[i4 >> 2] = ((i10 | 0) > (i1 | 0) ? i10 : i1) - i5 << 23 | i5 << 6 & 16320 | i3 & 8372287;
+   STACKTOP = i2;
+   return;
+  }
+ } while (0);
+ _luaK_code(i7, i6 << 6 | (i5 << 23) + -8388608 | 4) | 0;
+ STACKTOP = i2;
+ return;
+}
+function _lua_settable(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i3 = (HEAP32[i1 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i3 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i4 >> 2] | 0, (i5 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i3 = i3 + (i5 + -1 << 4) + 16 | 0;
+   } else {
+    i3 = 5192;
+   }
+  } else {
+   i3 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i3 = i3 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ i5 = i1 + 8 | 0;
+ i4 = HEAP32[i5 >> 2] | 0;
+ _luaV_settable(i1, i3, i4 + -32 | 0, i4 + -16 | 0);
+ HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + -32;
+ STACKTOP = i2;
+ return;
+}
+function _luaL_findtable(i3, i6, i5, i4) {
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i7 = 0;
+ i2 = STACKTOP;
+ if ((i6 | 0) != 0) {
+  _lua_pushvalue(i3, i6);
+ }
+ while (1) {
+  i6 = _strchr(i5, 46) | 0;
+  if ((i6 | 0) == 0) {
+   i6 = i5 + (_strlen(i5 | 0) | 0) | 0;
+  }
+  i7 = i6 - i5 | 0;
+  _lua_pushlstring(i3, i5, i7) | 0;
+  _lua_rawget(i3, -2);
+  if ((_lua_type(i3, -1) | 0) != 0) {
+   if ((_lua_type(i3, -1) | 0) != 5) {
+    break;
+   }
+  } else {
+   _lua_settop(i3, -2);
+   _lua_createtable(i3, 0, (HEAP8[i6] | 0) == 46 ? 1 : i4);
+   _lua_pushlstring(i3, i5, i7) | 0;
+   _lua_pushvalue(i3, -2);
+   _lua_settable(i3, -4);
+  }
+  _lua_remove(i3, -2);
+  if ((HEAP8[i6] | 0) == 46) {
+   i5 = i6 + 1 | 0;
+  } else {
+   i3 = 0;
+   i1 = 10;
+   break;
+  }
+ }
+ if ((i1 | 0) == 10) {
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ _lua_settop(i3, -3);
+ i7 = i5;
+ STACKTOP = i2;
+ return i7 | 0;
+}
+function _luaD_call(i1, i4, i5, i8) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i8 = i8 | 0;
+ var i2 = 0, i3 = 0, i6 = 0, i7 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i7 = i3;
+ i2 = i1 + 38 | 0;
+ i6 = (HEAP16[i2 >> 1] | 0) + 1 << 16 >> 16;
+ HEAP16[i2 >> 1] = i6;
+ if ((i6 & 65535) > 199) {
+  if (i6 << 16 >> 16 == 200) {
+   _luaG_runerror(i1, 2240, i7);
+  }
+  if ((i6 & 65535) > 224) {
+   _luaD_throw(i1, 6);
+  }
+ }
+ i6 = (i8 | 0) != 0;
+ if (!i6) {
+  i8 = i1 + 36 | 0;
+  HEAP16[i8 >> 1] = (HEAP16[i8 >> 1] | 0) + 1 << 16 >> 16;
+ }
+ if ((_luaD_precall(i1, i4, i5) | 0) == 0) {
+  _luaV_execute(i1);
+ }
+ if (i6) {
+  i8 = HEAP16[i2 >> 1] | 0;
+  i8 = i8 + -1 << 16 >> 16;
+  HEAP16[i2 >> 1] = i8;
+  STACKTOP = i3;
+  return;
+ }
+ i8 = i1 + 36 | 0;
+ HEAP16[i8 >> 1] = (HEAP16[i8 >> 1] | 0) + -1 << 16 >> 16;
+ i8 = HEAP16[i2 >> 1] | 0;
+ i8 = i8 + -1 << 16 >> 16;
+ HEAP16[i2 >> 1] = i8;
+ STACKTOP = i3;
+ return;
+}
+function _pushline(i6, i1) {
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 528 | 0;
+ i4 = i2;
+ i3 = i2 + 8 | 0;
+ i7 = (i1 | 0) != 0;
+ _lua_getglobal(i6, i7 ? 288 : 296);
+ i8 = _lua_tolstring(i6, -1, 0) | 0;
+ if ((i8 | 0) == 0) {
+  i8 = i7 ? 312 : 320;
+ }
+ i7 = HEAP32[_stdout >> 2] | 0;
+ _fputs(i8 | 0, i7 | 0) | 0;
+ _fflush(i7 | 0) | 0;
+ i8 = (_fgets(i3 | 0, 512, HEAP32[_stdin >> 2] | 0) | 0) == 0;
+ _lua_settop(i6, -2);
+ if (i8) {
+  i8 = 0;
+  STACKTOP = i2;
+  return i8 | 0;
+ }
+ i7 = _strlen(i3 | 0) | 0;
+ if ((i7 | 0) != 0 ? (i5 = i3 + (i7 + -1) | 0, (HEAP8[i5] | 0) == 10) : 0) {
+  HEAP8[i5] = 0;
+ }
+ if ((i1 | 0) != 0 ? (HEAP8[i3] | 0) == 61 : 0) {
+  HEAP32[i4 >> 2] = i3 + 1;
+  _lua_pushfstring(i6, 272, i4) | 0;
+  i8 = 1;
+  STACKTOP = i2;
+  return i8 | 0;
+ }
+ _lua_pushstring(i6, i3) | 0;
+ i8 = 1;
+ STACKTOP = i2;
+ return i8 | 0;
+}
+function _db_getlocal(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 112 | 0;
+ i4 = i2;
+ if ((_lua_type(i1, 1) | 0) == 8) {
+  i3 = _lua_tothread(i1, 1) | 0;
+  i6 = 1;
+ } else {
+  i3 = i1;
+  i6 = 0;
+ }
+ i5 = _luaL_checkinteger(i1, i6 | 2) | 0;
+ i6 = i6 + 1 | 0;
+ if ((_lua_type(i1, i6) | 0) == 6) {
+  _lua_pushvalue(i1, i6);
+  _lua_pushstring(i1, _lua_getlocal(i1, 0, i5) | 0) | 0;
+  i6 = 1;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ if ((_lua_getstack(i3, _luaL_checkinteger(i1, i6) | 0, i4) | 0) == 0) {
+  i6 = _luaL_argerror(i1, i6, 11560) | 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ i4 = _lua_getlocal(i3, i4, i5) | 0;
+ if ((i4 | 0) == 0) {
+  _lua_pushnil(i1);
+  i6 = 1;
+  STACKTOP = i2;
+  return i6 | 0;
+ } else {
+  _lua_xmove(i3, i1, 1);
+  _lua_pushstring(i1, i4) | 0;
+  _lua_pushvalue(i1, -2);
+  i6 = 2;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ return 0;
+}
+function _luaB_print(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i3;
+ i4 = i3 + 4 | 0;
+ i6 = _lua_gettop(i1) | 0;
+ _lua_getglobal(i1, 9584);
+ i5 = HEAP32[_stdout >> 2] | 0;
+ L1 : do {
+  if ((i6 | 0) >= 1) {
+   i7 = 1;
+   while (1) {
+    _lua_pushvalue(i1, -1);
+    _lua_pushvalue(i1, i7);
+    _lua_callk(i1, 1, 1, 0, 0);
+    i8 = _lua_tolstring(i1, -1, i4) | 0;
+    if ((i8 | 0) == 0) {
+     break;
+    }
+    if ((i7 | 0) > 1) {
+     _fputc(9, i5 | 0) | 0;
+    }
+    _fwrite(i8 | 0, 1, HEAP32[i4 >> 2] | 0, i5 | 0) | 0;
+    _lua_settop(i1, -2);
+    if ((i7 | 0) < (i6 | 0)) {
+     i7 = i7 + 1 | 0;
+    } else {
+     break L1;
+    }
+   }
+   i8 = _luaL_error(i1, 9816, i2) | 0;
+   STACKTOP = i3;
+   return i8 | 0;
+  }
+ } while (0);
+ _fputc(10, i5 | 0) | 0;
+ _fflush(i5 | 0) | 0;
+ i8 = 0;
+ STACKTOP = i3;
+ return i8 | 0;
+}
+function _luaB_load(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i5 = i2;
+ i6 = _lua_tolstring(i1, 1, i5) | 0;
+ i4 = _luaL_optlstring(i1, 3, 9872, 0) | 0;
+ i3 = (_lua_type(i1, 4) | 0) != -1;
+ if ((i6 | 0) == 0) {
+  i6 = _luaL_optlstring(i1, 2, 9880, 0) | 0;
+  _luaL_checktype(i1, 1, 6);
+  _lua_settop(i1, 5);
+  i4 = _lua_load(i1, 3, 0, i6, i4) | 0;
+ } else {
+  i7 = _luaL_optlstring(i1, 2, i6, 0) | 0;
+  i4 = _luaL_loadbufferx(i1, i6, HEAP32[i5 >> 2] | 0, i7, i4) | 0;
+ }
+ if ((i4 | 0) != 0) {
+  _lua_pushnil(i1);
+  _lua_insert(i1, -2);
+  i7 = 2;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ if (!i3) {
+  i7 = 1;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ _lua_pushvalue(i1, i3 ? 4 : 0);
+ if ((_lua_setupvalue(i1, -2, 1) | 0) != 0) {
+  i7 = 1;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ _lua_settop(i1, -2);
+ i7 = 1;
+ STACKTOP = i2;
+ return i7 | 0;
+}
+function _db_debug(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 256 | 0;
+ i6 = i1;
+ i4 = i1 + 4 | 0;
+ i3 = HEAP32[_stderr >> 2] | 0;
+ _fwrite(12040, 11, 1, i3 | 0) | 0;
+ _fflush(i3 | 0) | 0;
+ i5 = HEAP32[_stdin >> 2] | 0;
+ if ((_fgets(i4 | 0, 250, i5 | 0) | 0) == 0) {
+  STACKTOP = i1;
+  return 0;
+ }
+ while (1) {
+  if ((_strcmp(i4, 12056) | 0) == 0) {
+   i2 = 7;
+   break;
+  }
+  if (!((_luaL_loadbufferx(i2, i4, _strlen(i4 | 0) | 0, 12064, 0) | 0) == 0 ? (_lua_pcallk(i2, 0, 0, 0, 0, 0) | 0) == 0 : 0)) {
+   HEAP32[i6 >> 2] = _lua_tolstring(i2, -1, 0) | 0;
+   _fprintf(i3 | 0, 12088, i6 | 0) | 0;
+   _fflush(i3 | 0) | 0;
+  }
+  _lua_settop(i2, 0);
+  _fwrite(12040, 11, 1, i3 | 0) | 0;
+  _fflush(i3 | 0) | 0;
+  if ((_fgets(i4 | 0, 250, i5 | 0) | 0) == 0) {
+   i2 = 7;
+   break;
+  }
+ }
+ if ((i2 | 0) == 7) {
+  STACKTOP = i1;
+  return 0;
+ }
+ return 0;
+}
+function _luaL_prepbuffsize(i2, i7) {
+ i2 = i2 | 0;
+ i7 = i7 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i1 = HEAP32[i2 + 12 >> 2] | 0;
+ i4 = i2 + 4 | 0;
+ i8 = HEAP32[i4 >> 2] | 0;
+ i5 = i2 + 8 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ if (!((i8 - i6 | 0) >>> 0 < i7 >>> 0)) {
+  i7 = HEAP32[i2 >> 2] | 0;
+  i8 = i6;
+  i8 = i7 + i8 | 0;
+  STACKTOP = i3;
+  return i8 | 0;
+ }
+ i8 = i8 << 1;
+ i8 = (i8 - i6 | 0) >>> 0 < i7 >>> 0 ? i6 + i7 | 0 : i8;
+ if (i8 >>> 0 < i6 >>> 0 | (i8 - i6 | 0) >>> 0 < i7 >>> 0) {
+  _luaL_error(i1, 1272, i3) | 0;
+ }
+ i6 = _lua_newuserdata(i1, i8) | 0;
+ _memcpy(i6 | 0, HEAP32[i2 >> 2] | 0, HEAP32[i5 >> 2] | 0) | 0;
+ if ((HEAP32[i2 >> 2] | 0) != (i2 + 16 | 0)) {
+  _lua_remove(i1, -2);
+ }
+ HEAP32[i2 >> 2] = i6;
+ HEAP32[i4 >> 2] = i8;
+ i7 = i6;
+ i8 = HEAP32[i5 >> 2] | 0;
+ i8 = i7 + i8 | 0;
+ STACKTOP = i3;
+ return i8 | 0;
+}
+function _luaG_runerror(i1, i5, i4) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0, i6 = 0, i7 = 0;
+ i6 = STACKTOP;
+ STACKTOP = STACKTOP + 96 | 0;
+ i2 = i6;
+ i3 = i6 + 32 | 0;
+ i6 = i6 + 16 | 0;
+ HEAP32[i6 >> 2] = i4;
+ i4 = _luaO_pushvfstring(i1, i5, i6) | 0;
+ i6 = HEAP32[i1 + 16 >> 2] | 0;
+ if ((HEAP8[i6 + 18 | 0] & 1) == 0) {
+  _luaG_errormsg(i1);
+ }
+ i5 = HEAP32[(HEAP32[HEAP32[i6 >> 2] >> 2] | 0) + 12 >> 2] | 0;
+ i7 = HEAP32[i5 + 20 >> 2] | 0;
+ if ((i7 | 0) == 0) {
+  i6 = 0;
+ } else {
+  i6 = HEAP32[i7 + (((HEAP32[i6 + 28 >> 2] | 0) - (HEAP32[i5 + 12 >> 2] | 0) >> 2) + -1 << 2) >> 2] | 0;
+ }
+ i5 = HEAP32[i5 + 36 >> 2] | 0;
+ if ((i5 | 0) == 0) {
+  HEAP8[i3] = 63;
+  HEAP8[i3 + 1 | 0] = 0;
+ } else {
+  _luaO_chunkid(i3, i5 + 16 | 0, 60);
+ }
+ HEAP32[i2 >> 2] = i3;
+ HEAP32[i2 + 4 >> 2] = i6;
+ HEAP32[i2 + 8 >> 2] = i4;
+ _luaO_pushfstring(i1, 2024, i2) | 0;
+ _luaG_errormsg(i1);
+}
+function _db_upvaluejoin(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 112 | 0;
+ i4 = i3;
+ i2 = _luaL_checkinteger(i1, 2) | 0;
+ _luaL_checktype(i1, 1, 6);
+ _lua_pushvalue(i1, 1);
+ _lua_getinfo(i1, 11728, i4) | 0;
+ if (!((i2 | 0) > 0 ? (i2 | 0) <= (HEAPU8[i4 + 32 | 0] | 0 | 0) : 0)) {
+  _luaL_argerror(i1, 2, 11736) | 0;
+ }
+ i5 = _luaL_checkinteger(i1, 4) | 0;
+ _luaL_checktype(i1, 3, 6);
+ _lua_pushvalue(i1, 3);
+ _lua_getinfo(i1, 11728, i4) | 0;
+ if (!((i5 | 0) > 0 ? (i5 | 0) <= (HEAPU8[i4 + 32 | 0] | 0 | 0) : 0)) {
+  _luaL_argerror(i1, 4, 11736) | 0;
+ }
+ if ((_lua_iscfunction(i1, 1) | 0) != 0) {
+  _luaL_argerror(i1, 1, 11760) | 0;
+ }
+ if ((_lua_iscfunction(i1, 3) | 0) == 0) {
+  _lua_upvaluejoin(i1, 1, i2, 3, i5);
+  STACKTOP = i3;
+  return 0;
+ }
+ _luaL_argerror(i1, 3, 11760) | 0;
+ _lua_upvaluejoin(i1, 1, i2, 3, i5);
+ STACKTOP = i3;
+ return 0;
+}
+function _luaK_jump(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i3 = STACKTOP;
+ i2 = i1 + 28 | 0;
+ i7 = HEAP32[i2 >> 2] | 0;
+ HEAP32[i2 >> 2] = -1;
+ i2 = _luaK_code(i1, 2147450903) | 0;
+ if ((i7 | 0) == -1) {
+  i9 = i2;
+  STACKTOP = i3;
+  return i9 | 0;
+ }
+ if ((i2 | 0) == -1) {
+  i9 = i7;
+  STACKTOP = i3;
+  return i9 | 0;
+ }
+ i6 = HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0;
+ i8 = i2;
+ while (1) {
+  i5 = i6 + (i8 << 2) | 0;
+  i4 = HEAP32[i5 >> 2] | 0;
+  i9 = (i4 >>> 14) + -131071 | 0;
+  if ((i9 | 0) == -1) {
+   break;
+  }
+  i9 = i8 + 1 + i9 | 0;
+  if ((i9 | 0) == -1) {
+   break;
+  } else {
+   i8 = i9;
+  }
+ }
+ i6 = i7 + ~i8 | 0;
+ if ((((i6 | 0) > -1 ? i6 : 0 - i6 | 0) | 0) > 131071) {
+  _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10624);
+ }
+ HEAP32[i5 >> 2] = (i6 << 14) + 2147467264 | i4 & 16383;
+ i9 = i2;
+ STACKTOP = i3;
+ return i9 | 0;
+}
+function _findfield(i2, i3, i4) {
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i1 = 0;
+ i1 = STACKTOP;
+ L1 : do {
+  if (((i4 | 0) != 0 ? (_lua_type(i2, -1) | 0) == 5 : 0) ? (_lua_pushnil(i2), (_lua_next(i2, -2) | 0) != 0) : 0) {
+   i4 = i4 + -1 | 0;
+   while (1) {
+    if ((_lua_type(i2, -2) | 0) == 4) {
+     if ((_lua_rawequal(i2, i3, -1) | 0) != 0) {
+      i3 = 7;
+      break;
+     }
+     if ((_findfield(i2, i3, i4) | 0) != 0) {
+      i3 = 9;
+      break;
+     }
+    }
+    _lua_settop(i2, -2);
+    if ((_lua_next(i2, -2) | 0) == 0) {
+     i2 = 0;
+     break L1;
+    }
+   }
+   if ((i3 | 0) == 7) {
+    _lua_settop(i2, -2);
+    i2 = 1;
+    break;
+   } else if ((i3 | 0) == 9) {
+    _lua_remove(i2, -2);
+    _lua_pushlstring(i2, 1776, 1) | 0;
+    _lua_insert(i2, -2);
+    _lua_concat(i2, 3);
+    i2 = 1;
+    break;
+   }
+  } else {
+   i2 = 0;
+  }
+ } while (0);
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _db_gethook(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i3;
+ if ((_lua_type(i1, 1) | 0) == 8) {
+  i4 = _lua_tothread(i1, 1) | 0;
+ } else {
+  i4 = i1;
+ }
+ i5 = _lua_gethookmask(i4) | 0;
+ i6 = _lua_gethook(i4) | 0;
+ if ((i6 | 0) != 0 & (i6 | 0) != 9) {
+  _lua_pushlstring(i1, 12024, 13) | 0;
+ } else {
+  _luaL_getsubtable(i1, -1001e3, 11584) | 0;
+  _lua_pushthread(i4) | 0;
+  _lua_xmove(i4, i1, 1);
+  _lua_rawget(i1, -2);
+  _lua_remove(i1, -2);
+ }
+ if ((i5 & 1 | 0) == 0) {
+  i6 = 0;
+ } else {
+  HEAP8[i2] = 99;
+  i6 = 1;
+ }
+ if ((i5 & 2 | 0) != 0) {
+  HEAP8[i2 + i6 | 0] = 114;
+  i6 = i6 + 1 | 0;
+ }
+ if ((i5 & 4 | 0) != 0) {
+  HEAP8[i2 + i6 | 0] = 108;
+  i6 = i6 + 1 | 0;
+ }
+ HEAP8[i2 + i6 | 0] = 0;
+ _lua_pushstring(i1, i2) | 0;
+ _lua_pushinteger(i1, _lua_gethookcount(i4) | 0);
+ STACKTOP = i3;
+ return 3;
+}
+function _lua_tothread(i3, i5) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i4 = 0;
+ i1 = STACKTOP;
+ i4 = HEAP32[i3 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i2 = (HEAP32[i3 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i2 = (HEAP32[i3 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i3 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i2 = HEAP32[i4 >> 2] | 0, (i3 | 0) <= (HEAPU8[i2 + 6 | 0] | 0 | 0)) : 0) {
+    i2 = i2 + (i3 + -1 << 4) + 16 | 0;
+   } else {
+    i2 = 5192;
+   }
+  } else {
+   i2 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i2 = i2 >>> 0 < (HEAP32[i3 + 8 >> 2] | 0) >>> 0 ? i2 : 5192;
+  }
+ } while (0);
+ if ((HEAP32[i2 + 8 >> 2] | 0) != 72) {
+  i5 = 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ i5 = HEAP32[i2 >> 2] | 0;
+ STACKTOP = i1;
+ return i5 | 0;
+}
+function _luaD_throw(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i3 = i1 + 64 | 0;
+ i4 = HEAP32[i3 >> 2] | 0;
+ if ((i4 | 0) != 0) {
+  HEAP32[i4 + 160 >> 2] = i2;
+  _longjmp((HEAP32[i3 >> 2] | 0) + 4 | 0, 1);
+ }
+ HEAP8[i1 + 6 | 0] = i2;
+ i4 = i1 + 12 | 0;
+ i3 = HEAP32[i4 >> 2] | 0;
+ i5 = HEAP32[i3 + 172 >> 2] | 0;
+ if ((HEAP32[i5 + 64 >> 2] | 0) != 0) {
+  i6 = HEAP32[i1 + 8 >> 2] | 0;
+  i9 = i5 + 8 | 0;
+  i5 = HEAP32[i9 >> 2] | 0;
+  HEAP32[i9 >> 2] = i5 + 16;
+  i9 = i6 + -16 | 0;
+  i8 = HEAP32[i9 + 4 >> 2] | 0;
+  i7 = i5;
+  HEAP32[i7 >> 2] = HEAP32[i9 >> 2];
+  HEAP32[i7 + 4 >> 2] = i8;
+  HEAP32[i5 + 8 >> 2] = HEAP32[i6 + -8 >> 2];
+  _luaD_throw(HEAP32[(HEAP32[i4 >> 2] | 0) + 172 >> 2] | 0, i2);
+ }
+ i2 = HEAP32[i3 + 168 >> 2] | 0;
+ if ((i2 | 0) == 0) {
+  _abort();
+ }
+ FUNCTION_TABLE_ii[i2 & 255](i1) | 0;
+ _abort();
+}
+function _lua_len(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i3 = (HEAP32[i1 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i3 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i4 >> 2] | 0, (i5 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i3 = i3 + (i5 + -1 << 4) + 16 | 0;
+   } else {
+    i3 = 5192;
+   }
+  } else {
+   i3 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i3 = i3 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ i5 = i1 + 8 | 0;
+ _luaV_objlen(i1, HEAP32[i5 >> 2] | 0, i3);
+ HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + 16;
+ STACKTOP = i2;
+ return;
+}
+function _read_line(i4, i5, i1) {
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 1040 | 0;
+ i2 = i3;
+ _luaL_buffinit(i4, i2);
+ i7 = _luaL_prepbuffsize(i2, 1024) | 0;
+ L1 : do {
+  if ((_fgets(i7 | 0, 1024, i5 | 0) | 0) != 0) {
+   i6 = i2 + 8 | 0;
+   while (1) {
+    i8 = _strlen(i7 | 0) | 0;
+    if ((i8 | 0) != 0 ? (HEAP8[i7 + (i8 + -1) | 0] | 0) == 10 : 0) {
+     break;
+    }
+    HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i8;
+    i7 = _luaL_prepbuffsize(i2, 1024) | 0;
+    if ((_fgets(i7 | 0, 1024, i5 | 0) | 0) == 0) {
+     break L1;
+    }
+   }
+   HEAP32[i6 >> 2] = i8 - i1 + (HEAP32[i6 >> 2] | 0);
+   _luaL_pushresult(i2);
+   i8 = 1;
+   STACKTOP = i3;
+   return i8 | 0;
+  }
+ } while (0);
+ _luaL_pushresult(i2);
+ i8 = (_lua_rawlen(i4, -1) | 0) != 0 | 0;
+ STACKTOP = i3;
+ return i8 | 0;
+}
+function _luaL_tolstring(i1, i5, i4) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ do {
+  if ((_luaL_callmeta(i1, i5, 1384) | 0) == 0) {
+   i6 = _lua_type(i1, i5) | 0;
+   if ((i6 | 0) == 0) {
+    _lua_pushlstring(i1, 1416, 3) | 0;
+    break;
+   } else if ((i6 | 0) == 1) {
+    i6 = (_lua_toboolean(i1, i5) | 0) != 0;
+    _lua_pushstring(i1, i6 ? 1400 : 1408) | 0;
+    break;
+   } else if ((i6 | 0) == 4 | (i6 | 0) == 3) {
+    _lua_pushvalue(i1, i5);
+    break;
+   } else {
+    i7 = _lua_typename(i1, _lua_type(i1, i5) | 0) | 0;
+    i6 = _lua_topointer(i1, i5) | 0;
+    HEAP32[i3 >> 2] = i7;
+    HEAP32[i3 + 4 >> 2] = i6;
+    _lua_pushfstring(i1, 1424, i3) | 0;
+    break;
+   }
+  }
+ } while (0);
+ i7 = _lua_tolstring(i1, -1, i4) | 0;
+ STACKTOP = i2;
+ return i7 | 0;
+}
+function _save(i7, i1) {
+ i7 = i7 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i7 + 60 >> 2] | 0;
+ i3 = i4 + 4 | 0;
+ i8 = HEAP32[i3 >> 2] | 0;
+ i6 = i4 + 8 | 0;
+ i5 = HEAP32[i6 >> 2] | 0;
+ if (!((i8 + 1 | 0) >>> 0 > i5 >>> 0)) {
+  i6 = HEAP32[i4 >> 2] | 0;
+  i7 = i1 & 255;
+  i5 = i8 + 1 | 0;
+  HEAP32[i3 >> 2] = i5;
+  i8 = i6 + i8 | 0;
+  HEAP8[i8] = i7;
+  STACKTOP = i2;
+  return;
+ }
+ if (i5 >>> 0 > 2147483645) {
+  _lexerror(i7, 12368, 0);
+ }
+ i8 = i5 << 1;
+ i7 = HEAP32[i7 + 52 >> 2] | 0;
+ if ((i8 | 0) == -2) {
+  _luaM_toobig(i7);
+ }
+ i7 = _luaM_realloc_(i7, HEAP32[i4 >> 2] | 0, i5, i8) | 0;
+ HEAP32[i4 >> 2] = i7;
+ HEAP32[i6 >> 2] = i8;
+ i8 = HEAP32[i3 >> 2] | 0;
+ i6 = i7;
+ i7 = i1 & 255;
+ i5 = i8 + 1 | 0;
+ HEAP32[i3 >> 2] = i5;
+ i8 = i6 + i8 | 0;
+ HEAP8[i8] = i7;
+ STACKTOP = i2;
+ return;
+}
+function _luaK_patchtohere(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ HEAP32[i1 + 24 >> 2] = HEAP32[i1 + 20 >> 2];
+ i4 = i1 + 28 | 0;
+ if ((i3 | 0) == -1) {
+  STACKTOP = i2;
+  return;
+ }
+ i7 = HEAP32[i4 >> 2] | 0;
+ if ((i7 | 0) == -1) {
+  HEAP32[i4 >> 2] = i3;
+  STACKTOP = i2;
+  return;
+ }
+ i4 = HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0;
+ while (1) {
+  i6 = i4 + (i7 << 2) | 0;
+  i5 = HEAP32[i6 >> 2] | 0;
+  i8 = (i5 >>> 14) + -131071 | 0;
+  if ((i8 | 0) == -1) {
+   break;
+  }
+  i8 = i7 + 1 + i8 | 0;
+  if ((i8 | 0) == -1) {
+   break;
+  } else {
+   i7 = i8;
+  }
+ }
+ i3 = ~i7 + i3 | 0;
+ if ((((i3 | 0) > -1 ? i3 : 0 - i3 | 0) | 0) > 131071) {
+  _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10624);
+ }
+ HEAP32[i6 >> 2] = (i3 << 14) + 2147467264 | i5 & 16383;
+ STACKTOP = i2;
+ return;
+}
+function _tinsert(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i7 = i2;
+ _luaL_checktype(i1, 1, 5);
+ i4 = _luaL_len(i1, 1) | 0;
+ i3 = i4 + 1 | 0;
+ i6 = _lua_gettop(i1) | 0;
+ if ((i6 | 0) == 3) {
+  i5 = 2;
+ } else if ((i6 | 0) != 2) {
+  i7 = _luaL_error(i1, 8320, i7) | 0;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ if ((i5 | 0) == 2) {
+  i5 = _luaL_checkinteger(i1, 2) | 0;
+  if ((i5 | 0) < 1 | (i5 | 0) > (i3 | 0)) {
+   _luaL_argerror(i1, 2, 8256) | 0;
+  }
+  if ((i4 | 0) < (i5 | 0)) {
+   i3 = i5;
+  } else {
+   while (1) {
+    i4 = i3 + -1 | 0;
+    _lua_rawgeti(i1, 1, i4);
+    _lua_rawseti(i1, 1, i3);
+    if ((i4 | 0) > (i5 | 0)) {
+     i3 = i4;
+    } else {
+     i3 = i5;
+     break;
+    }
+   }
+  }
+ }
+ _lua_rawseti(i1, 1, i3);
+ i7 = 0;
+ STACKTOP = i2;
+ return i7 | 0;
+}
+function _lua_iscfunction(i3, i5) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i4 = 0;
+ i1 = STACKTOP;
+ i4 = HEAP32[i3 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i2 = (HEAP32[i3 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i2 = (HEAP32[i3 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i3 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i2 = HEAP32[i4 >> 2] | 0, (i3 | 0) <= (HEAPU8[i2 + 6 | 0] | 0 | 0)) : 0) {
+    i2 = i2 + (i3 + -1 << 4) + 16 | 0;
+   } else {
+    i2 = 5192;
+   }
+  } else {
+   i2 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i2 = i2 >>> 0 < (HEAP32[i3 + 8 >> 2] | 0) >>> 0 ? i2 : 5192;
+  }
+ } while (0);
+ i5 = HEAP32[i2 + 8 >> 2] | 0;
+ STACKTOP = i1;
+ return ((i5 | 0) == 22 | (i5 | 0) == 102) & 1 | 0;
+}
+function _lua_gettable(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i1 + 16 >> 2] | 0;
+ do {
+  if ((i5 | 0) <= 0) {
+   if (!((i5 | 0) < -1000999)) {
+    i3 = (HEAP32[i1 + 8 >> 2] | 0) + (i5 << 4) | 0;
+    break;
+   }
+   if ((i5 | 0) == -1001e3) {
+    i3 = (HEAP32[i1 + 12 >> 2] | 0) + 40 | 0;
+    break;
+   }
+   i5 = -1001e3 - i5 | 0;
+   i4 = HEAP32[i4 >> 2] | 0;
+   if ((HEAP32[i4 + 8 >> 2] | 0) != 22 ? (i3 = HEAP32[i4 >> 2] | 0, (i5 | 0) <= (HEAPU8[i3 + 6 | 0] | 0 | 0)) : 0) {
+    i3 = i3 + (i5 + -1 << 4) + 16 | 0;
+   } else {
+    i3 = 5192;
+   }
+  } else {
+   i3 = (HEAP32[i4 >> 2] | 0) + (i5 << 4) | 0;
+   i3 = i3 >>> 0 < (HEAP32[i1 + 8 >> 2] | 0) >>> 0 ? i3 : 5192;
+  }
+ } while (0);
+ i5 = (HEAP32[i1 + 8 >> 2] | 0) + -16 | 0;
+ _luaV_gettable(i1, i3, i5, i5);
+ STACKTOP = i2;
+ return;
+}
+function _luaG_errormsg(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i2 = HEAP32[i1 + 68 >> 2] | 0;
+ if ((i2 | 0) == 0) {
+  _luaD_throw(i1, 2);
+ }
+ i4 = HEAP32[i1 + 28 >> 2] | 0;
+ i3 = i4 + (i2 + 8) | 0;
+ if ((HEAP32[i3 >> 2] & 15 | 0) != 6) {
+  _luaD_throw(i1, 6);
+ }
+ i5 = i1 + 8 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ i9 = i6 + -16 | 0;
+ i8 = HEAP32[i9 + 4 >> 2] | 0;
+ i7 = i6;
+ HEAP32[i7 >> 2] = HEAP32[i9 >> 2];
+ HEAP32[i7 + 4 >> 2] = i8;
+ HEAP32[i6 + 8 >> 2] = HEAP32[i6 + -8 >> 2];
+ i6 = HEAP32[i5 >> 2] | 0;
+ i7 = i4 + i2 | 0;
+ i2 = HEAP32[i7 + 4 >> 2] | 0;
+ i4 = i6 + -16 | 0;
+ HEAP32[i4 >> 2] = HEAP32[i7 >> 2];
+ HEAP32[i4 + 4 >> 2] = i2;
+ HEAP32[i6 + -8 >> 2] = HEAP32[i3 >> 2];
+ i4 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i5 >> 2] = i4 + 16;
+ _luaD_call(i1, i4 + -16 | 0, 1, 0);
+ _luaD_throw(i1, 2);
+}
+function _luaB_costatus(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 112 | 0;
+ i3 = i4;
+ i2 = _lua_tothread(i1, 1) | 0;
+ if ((i2 | 0) == 0) {
+  _luaL_argerror(i1, 1, 10856) | 0;
+ }
+ do {
+  if ((i2 | 0) != (i1 | 0)) {
+   i5 = _lua_status(i2) | 0;
+   if ((i5 | 0) == 0) {
+    if ((_lua_getstack(i2, 0, i3) | 0) > 0) {
+     _lua_pushlstring(i1, 10896, 6) | 0;
+     break;
+    }
+    if ((_lua_gettop(i2) | 0) == 0) {
+     _lua_pushlstring(i1, 10904, 4) | 0;
+     break;
+    } else {
+     _lua_pushlstring(i1, 10880, 9) | 0;
+     break;
+    }
+   } else if ((i5 | 0) == 1) {
+    _lua_pushlstring(i1, 10880, 9) | 0;
+    break;
+   } else {
+    _lua_pushlstring(i1, 10904, 4) | 0;
+    break;
+   }
+  } else {
+   _lua_pushlstring(i1, 10728, 7) | 0;
+  }
+ } while (0);
+ STACKTOP = i4;
+ return 1;
+}
+function _searcher_Lua(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ i4 = _luaL_checklstring(i1, 1, 0) | 0;
+ _lua_getfield(i1, -1001001, 4256);
+ i5 = _lua_tolstring(i1, -1, 0) | 0;
+ if ((i5 | 0) == 0) {
+  HEAP32[i3 >> 2] = 4256;
+  _luaL_error(i1, 5032, i3) | 0;
+ }
+ i4 = _searchpath(i1, i4, i5, 4936, 4848) | 0;
+ if ((i4 | 0) == 0) {
+  i5 = 1;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ if ((_luaL_loadfilex(i1, i4, 0) | 0) == 0) {
+  _lua_pushstring(i1, i4) | 0;
+  i5 = 2;
+  STACKTOP = i2;
+  return i5 | 0;
+ } else {
+  i6 = _lua_tolstring(i1, 1, 0) | 0;
+  i5 = _lua_tolstring(i1, -1, 0) | 0;
+  HEAP32[i3 >> 2] = i6;
+  HEAP32[i3 + 4 >> 2] = i4;
+  HEAP32[i3 + 8 >> 2] = i5;
+  i5 = _luaL_error(i1, 4888, i3) | 0;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ return 0;
+}
+function _str_sub(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i3;
+ i2 = _luaL_checklstring(i1, 1, i4) | 0;
+ i5 = _luaL_checkinteger(i1, 2) | 0;
+ i6 = HEAP32[i4 >> 2] | 0;
+ if (!((i5 | 0) > -1)) {
+  if (i6 >>> 0 < (0 - i5 | 0) >>> 0) {
+   i5 = 0;
+  } else {
+   i5 = i5 + 1 + i6 | 0;
+  }
+ }
+ i6 = _luaL_optinteger(i1, 3, -1) | 0;
+ i4 = HEAP32[i4 >> 2] | 0;
+ if (!((i6 | 0) > -1)) {
+  if (i4 >>> 0 < (0 - i6 | 0) >>> 0) {
+   i6 = 0;
+  } else {
+   i6 = i6 + 1 + i4 | 0;
+  }
+ }
+ i5 = (i5 | 0) == 0 ? 1 : i5;
+ i4 = i6 >>> 0 > i4 >>> 0 ? i4 : i6;
+ if (i5 >>> 0 > i4 >>> 0) {
+  _lua_pushlstring(i1, 7040, 0) | 0;
+  STACKTOP = i3;
+  return 1;
+ } else {
+  _lua_pushlstring(i1, i2 + (i5 + -1) | 0, 1 - i5 + i4 | 0) | 0;
+  STACKTOP = i3;
+  return 1;
+ }
+ return 0;
+}
+function _searcher_C(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ i4 = _luaL_checklstring(i1, 1, 0) | 0;
+ _lua_getfield(i1, -1001001, 4440);
+ i5 = _lua_tolstring(i1, -1, 0) | 0;
+ if ((i5 | 0) == 0) {
+  HEAP32[i3 >> 2] = 4440;
+  _luaL_error(i1, 5032, i3) | 0;
+ }
+ i5 = _searchpath(i1, i4, i5, 4936, 4848) | 0;
+ if ((i5 | 0) == 0) {
+  i5 = 1;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ if ((_loadfunc(i1, i5, i4) | 0) == 0) {
+  _lua_pushstring(i1, i5) | 0;
+  i5 = 2;
+  STACKTOP = i2;
+  return i5 | 0;
+ } else {
+  i6 = _lua_tolstring(i1, 1, 0) | 0;
+  i4 = _lua_tolstring(i1, -1, 0) | 0;
+  HEAP32[i3 >> 2] = i6;
+  HEAP32[i3 + 4 >> 2] = i5;
+  HEAP32[i3 + 8 >> 2] = i4;
+  i5 = _luaL_error(i1, 4888, i3) | 0;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ return 0;
+}
+function _io_open(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i5 = STACKTOP;
+ i2 = _luaL_checklstring(i1, 1, 0) | 0;
+ i3 = _luaL_optlstring(i1, 2, 3480, 0) | 0;
+ i4 = _lua_newuserdata(i1, 8) | 0;
+ i6 = i4 + 4 | 0;
+ HEAP32[i6 >> 2] = 0;
+ _luaL_setmetatable(i1, 2832);
+ HEAP32[i4 >> 2] = 0;
+ HEAP32[i6 >> 2] = 156;
+ i6 = HEAP8[i3] | 0;
+ if (!((!(i6 << 24 >> 24 == 0) ? (i7 = i3 + 1 | 0, (_memchr(3552, i6 << 24 >> 24, 4) | 0) != 0) : 0) ? (i6 = (HEAP8[i7] | 0) == 43 ? i3 + 2 | 0 : i7, (HEAP8[(HEAP8[i6] | 0) == 98 ? i6 + 1 | 0 : i6] | 0) == 0) : 0)) {
+  _luaL_argerror(i1, 2, 3560) | 0;
+ }
+ i7 = _fopen(i2 | 0, i3 | 0) | 0;
+ HEAP32[i4 >> 2] = i7;
+ if ((i7 | 0) != 0) {
+  i7 = 1;
+  STACKTOP = i5;
+  return i7 | 0;
+ }
+ i7 = _luaL_fileresult(i1, 0, i2) | 0;
+ STACKTOP = i5;
+ return i7 | 0;
+}
+function _unpack(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i6 = i1;
+ _luaL_checktype(i2, 1, 5);
+ i5 = _luaL_optinteger(i2, 2, 1) | 0;
+ if ((_lua_type(i2, 3) | 0) < 1) {
+  i3 = _luaL_len(i2, 1) | 0;
+ } else {
+  i3 = _luaL_checkinteger(i2, 3) | 0;
+ }
+ if ((i5 | 0) > (i3 | 0)) {
+  i6 = 0;
+  STACKTOP = i1;
+  return i6 | 0;
+ }
+ i7 = i3 - i5 | 0;
+ i4 = i7 + 1 | 0;
+ if ((i7 | 0) >= 0 ? (_lua_checkstack(i2, i4) | 0) != 0 : 0) {
+  _lua_rawgeti(i2, 1, i5);
+  if ((i5 | 0) >= (i3 | 0)) {
+   i7 = i4;
+   STACKTOP = i1;
+   return i7 | 0;
+  }
+  do {
+   i5 = i5 + 1 | 0;
+   _lua_rawgeti(i2, 1, i5);
+  } while ((i5 | 0) != (i3 | 0));
+  STACKTOP = i1;
+  return i4 | 0;
+ }
+ i7 = _luaL_error(i2, 8280, i6) | 0;
+ STACKTOP = i1;
+ return i7 | 0;
+}
+function _luaF_getlocalname(i4, i6, i2) {
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i5 = 0;
+ i1 = STACKTOP;
+ i3 = HEAP32[i4 + 60 >> 2] | 0;
+ if ((i3 | 0) <= 0) {
+  i6 = 0;
+  STACKTOP = i1;
+  return i6 | 0;
+ }
+ i4 = HEAP32[i4 + 24 >> 2] | 0;
+ i5 = 0;
+ while (1) {
+  if ((HEAP32[i4 + (i5 * 12 | 0) + 4 >> 2] | 0) > (i2 | 0)) {
+   i3 = 0;
+   i2 = 8;
+   break;
+  }
+  if ((HEAP32[i4 + (i5 * 12 | 0) + 8 >> 2] | 0) > (i2 | 0)) {
+   i6 = i6 + -1 | 0;
+   if ((i6 | 0) == 0) {
+    i2 = 6;
+    break;
+   }
+  }
+  i5 = i5 + 1 | 0;
+  if ((i5 | 0) >= (i3 | 0)) {
+   i3 = 0;
+   i2 = 8;
+   break;
+  }
+ }
+ if ((i2 | 0) == 6) {
+  i6 = (HEAP32[i4 + (i5 * 12 | 0) >> 2] | 0) + 16 | 0;
+  STACKTOP = i1;
+  return i6 | 0;
+ } else if ((i2 | 0) == 8) {
+  STACKTOP = i1;
+  return i3 | 0;
+ }
+ return 0;
+}
+function _luaK_concat(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ if ((i3 | 0) == -1) {
+  STACKTOP = i2;
+  return;
+ }
+ i7 = HEAP32[i4 >> 2] | 0;
+ if ((i7 | 0) == -1) {
+  HEAP32[i4 >> 2] = i3;
+  STACKTOP = i2;
+  return;
+ }
+ i4 = HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0;
+ while (1) {
+  i6 = i4 + (i7 << 2) | 0;
+  i5 = HEAP32[i6 >> 2] | 0;
+  i8 = (i5 >>> 14) + -131071 | 0;
+  if ((i8 | 0) == -1) {
+   break;
+  }
+  i8 = i7 + 1 + i8 | 0;
+  if ((i8 | 0) == -1) {
+   break;
+  } else {
+   i7 = i8;
+  }
+ }
+ i3 = ~i7 + i3 | 0;
+ if ((((i3 | 0) > -1 ? i3 : 0 - i3 | 0) | 0) > 131071) {
+  _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10624);
+ }
+ HEAP32[i6 >> 2] = i5 & 16383 | (i3 << 14) + 2147467264;
+ STACKTOP = i2;
+ return;
+}
+function _scalbn(d3, i2) {
+ d3 = +d3;
+ i2 = i2 | 0;
+ var i1 = 0, i4 = 0;
+ i1 = STACKTOP;
+ if ((i2 | 0) > 1023) {
+  d3 = d3 * 8.98846567431158e+307;
+  i4 = i2 + -1023 | 0;
+  if ((i4 | 0) > 1023) {
+   i2 = i2 + -2046 | 0;
+   i2 = (i2 | 0) > 1023 ? 1023 : i2;
+   d3 = d3 * 8.98846567431158e+307;
+  } else {
+   i2 = i4;
+  }
+ } else {
+  if ((i2 | 0) < -1022) {
+   d3 = d3 * 2.2250738585072014e-308;
+   i4 = i2 + 1022 | 0;
+   if ((i4 | 0) < -1022) {
+    i2 = i2 + 2044 | 0;
+    i2 = (i2 | 0) < -1022 ? -1022 : i2;
+    d3 = d3 * 2.2250738585072014e-308;
+   } else {
+    i2 = i4;
+   }
+  }
+ }
+ i2 = _bitshift64Shl(i2 + 1023 | 0, 0, 52) | 0;
+ i4 = tempRet0;
+ HEAP32[tempDoublePtr >> 2] = i2;
+ HEAP32[tempDoublePtr + 4 >> 2] = i4;
+ d3 = d3 * +HEAPF64[tempDoublePtr >> 3];
+ STACKTOP = i1;
+ return +d3;
+}
+function _luaK_numberK(i1, d6) {
+ i1 = i1 | 0;
+ d6 = +d6;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i4 = i2 + 16 | 0;
+ i3 = i2;
+ HEAPF64[i4 >> 3] = d6;
+ i5 = HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 52 >> 2] | 0;
+ HEAPF64[i3 >> 3] = d6;
+ HEAP32[i3 + 8 >> 2] = 3;
+ if (d6 != d6 | 0.0 != 0.0 | d6 == 0.0) {
+  i7 = i5 + 8 | 0;
+  i8 = HEAP32[i7 >> 2] | 0;
+  HEAP32[i7 >> 2] = i8 + 16;
+  i5 = _luaS_newlstr(i5, i4, 8) | 0;
+  HEAP32[i8 >> 2] = i5;
+  HEAP32[i8 + 8 >> 2] = HEAPU8[i5 + 4 | 0] | 0 | 64;
+  i5 = _addk(i1, (HEAP32[i7 >> 2] | 0) + -16 | 0, i3) | 0;
+  HEAP32[i7 >> 2] = (HEAP32[i7 >> 2] | 0) + -16;
+  STACKTOP = i2;
+  return i5 | 0;
+ } else {
+  i8 = _addk(i1, i3, i3) | 0;
+  STACKTOP = i2;
+  return i8 | 0;
+ }
+ return 0;
+}
+function _auxresume(i2, i3, i4) {
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i1 = 0;
+ i1 = STACKTOP;
+ do {
+  if ((_lua_checkstack(i3, i4) | 0) != 0) {
+   if ((_lua_status(i3) | 0) == 0 ? (_lua_gettop(i3) | 0) == 0 : 0) {
+    _lua_pushlstring(i2, 10792, 28) | 0;
+    i4 = -1;
+    break;
+   }
+   _lua_xmove(i2, i3, i4);
+   if (!((_lua_resume(i3, i2, i4) | 0) >>> 0 < 2)) {
+    _lua_xmove(i3, i2, 1);
+    i4 = -1;
+    break;
+   }
+   i4 = _lua_gettop(i3) | 0;
+   if ((_lua_checkstack(i2, i4 + 1 | 0) | 0) == 0) {
+    _lua_settop(i3, ~i4);
+    _lua_pushlstring(i2, 10824, 26) | 0;
+    i4 = -1;
+    break;
+   } else {
+    _lua_xmove(i3, i2, i4);
+    break;
+   }
+  } else {
+   _lua_pushlstring(i2, 10760, 28) | 0;
+   i4 = -1;
+  }
+ } while (0);
+ STACKTOP = i1;
+ return i4 | 0;
+}
+function _luaX_setinput(i2, i1, i4, i3, i5) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i6 = 0, i7 = 0;
+ i6 = STACKTOP;
+ HEAP8[i1 + 76 | 0] = 46;
+ i7 = i1 + 52 | 0;
+ HEAP32[i7 >> 2] = i2;
+ HEAP32[i1 >> 2] = i5;
+ HEAP32[i1 + 32 >> 2] = 286;
+ HEAP32[i1 + 56 >> 2] = i4;
+ HEAP32[i1 + 48 >> 2] = 0;
+ HEAP32[i1 + 4 >> 2] = 1;
+ HEAP32[i1 + 8 >> 2] = 1;
+ HEAP32[i1 + 68 >> 2] = i3;
+ i5 = _luaS_new(i2, 12264) | 0;
+ HEAP32[i1 + 72 >> 2] = i5;
+ i5 = i5 + 5 | 0;
+ HEAP8[i5] = HEAPU8[i5] | 0 | 32;
+ i5 = i1 + 60 | 0;
+ i4 = HEAP32[i5 >> 2] | 0;
+ i4 = _luaM_realloc_(HEAP32[i7 >> 2] | 0, HEAP32[i4 >> 2] | 0, HEAP32[i4 + 8 >> 2] | 0, 32) | 0;
+ HEAP32[HEAP32[i5 >> 2] >> 2] = i4;
+ HEAP32[(HEAP32[i5 >> 2] | 0) + 8 >> 2] = 32;
+ STACKTOP = i6;
+ return;
+}
+function _luaL_optlstring(i2, i4, i6, i5) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i3 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i1;
+ if ((_lua_type(i2, i4) | 0) >= 1) {
+  i5 = _lua_tolstring(i2, i4, i5) | 0;
+  if ((i5 | 0) != 0) {
+   i6 = i5;
+   STACKTOP = i1;
+   return i6 | 0;
+  }
+  i5 = _lua_typename(i2, 4) | 0;
+  i6 = _lua_typename(i2, _lua_type(i2, i4) | 0) | 0;
+  HEAP32[i3 >> 2] = i5;
+  HEAP32[i3 + 4 >> 2] = i6;
+  _luaL_argerror(i2, i4, _lua_pushfstring(i2, 1744, i3) | 0) | 0;
+  i6 = 0;
+  STACKTOP = i1;
+  return i6 | 0;
+ }
+ if ((i5 | 0) == 0) {
+  STACKTOP = i1;
+  return i6 | 0;
+ }
+ if ((i6 | 0) == 0) {
+  i2 = 0;
+ } else {
+  i2 = _strlen(i6 | 0) | 0;
+ }
+ HEAP32[i5 >> 2] = i2;
+ STACKTOP = i1;
+ return i6 | 0;
+}
+function _lua_xmove(i3, i4, i1) {
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i2 = STACKTOP;
+ if ((i3 | 0) == (i4 | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ i3 = i3 + 8 | 0;
+ i5 = (HEAP32[i3 >> 2] | 0) + (0 - i1 << 4) | 0;
+ HEAP32[i3 >> 2] = i5;
+ if ((i1 | 0) <= 0) {
+  STACKTOP = i2;
+  return;
+ }
+ i4 = i4 + 8 | 0;
+ i6 = 0;
+ while (1) {
+  i7 = HEAP32[i4 >> 2] | 0;
+  HEAP32[i4 >> 2] = i7 + 16;
+  i10 = i5 + (i6 << 4) | 0;
+  i9 = HEAP32[i10 + 4 >> 2] | 0;
+  i8 = i7;
+  HEAP32[i8 >> 2] = HEAP32[i10 >> 2];
+  HEAP32[i8 + 4 >> 2] = i9;
+  HEAP32[i7 + 8 >> 2] = HEAP32[i5 + (i6 << 4) + 8 >> 2];
+  i6 = i6 + 1 | 0;
+  if ((i6 | 0) == (i1 | 0)) {
+   break;
+  }
+  i5 = HEAP32[i3 >> 2] | 0;
+ }
+ STACKTOP = i2;
+ return;
+}
+function _luaM_realloc_(i7, i10, i3, i2) {
+ i7 = i7 | 0;
+ i10 = i10 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0;
+ i5 = STACKTOP;
+ i6 = HEAP32[i7 + 12 >> 2] | 0;
+ i4 = (i10 | 0) != 0;
+ i9 = i6 + 4 | 0;
+ i8 = FUNCTION_TABLE_iiiii[HEAP32[i6 >> 2] & 3](HEAP32[i9 >> 2] | 0, i10, i3, i2) | 0;
+ if (!((i8 | 0) != 0 | (i2 | 0) == 0)) {
+  if ((HEAP8[i6 + 63 | 0] | 0) == 0) {
+   _luaD_throw(i7, 4);
+  }
+  _luaC_fullgc(i7, 1);
+  i8 = FUNCTION_TABLE_iiiii[HEAP32[i6 >> 2] & 3](HEAP32[i9 >> 2] | 0, i10, i3, i2) | 0;
+  if ((i8 | 0) == 0) {
+   _luaD_throw(i7, 4);
+  } else {
+   i1 = i8;
+  }
+ } else {
+  i1 = i8;
+ }
+ i6 = i6 + 12 | 0;
+ HEAP32[i6 >> 2] = (i4 ? 0 - i3 | 0 : 0) + i2 + (HEAP32[i6 >> 2] | 0);
+ STACKTOP = i5;
+ return i1 | 0;
+}
+function _realloc(i2, i3) {
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i4 = 0, i5 = 0;
+ i1 = STACKTOP;
+ do {
+  if ((i2 | 0) != 0) {
+   if (i3 >>> 0 > 4294967231) {
+    HEAP32[(___errno_location() | 0) >> 2] = 12;
+    i4 = 0;
+    break;
+   }
+   if (i3 >>> 0 < 11) {
+    i4 = 16;
+   } else {
+    i4 = i3 + 11 & -8;
+   }
+   i4 = _try_realloc_chunk(i2 + -8 | 0, i4) | 0;
+   if ((i4 | 0) != 0) {
+    i4 = i4 + 8 | 0;
+    break;
+   }
+   i4 = _malloc(i3) | 0;
+   if ((i4 | 0) == 0) {
+    i4 = 0;
+   } else {
+    i5 = HEAP32[i2 + -4 >> 2] | 0;
+    i5 = (i5 & -8) - ((i5 & 3 | 0) == 0 ? 8 : 4) | 0;
+    _memcpy(i4 | 0, i2 | 0, (i5 >>> 0 < i3 >>> 0 ? i5 : i3) | 0) | 0;
+    _free(i2);
+   }
+  } else {
+   i4 = _malloc(i3) | 0;
+  }
+ } while (0);
+ STACKTOP = i1;
+ return i4 | 0;
+}
+function _lua_setlocal(i3, i5, i4) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i1;
+ HEAP32[i2 >> 2] = 0;
+ i4 = _findlocal(i3, HEAP32[i5 + 96 >> 2] | 0, i4, i2) | 0;
+ i3 = i3 + 8 | 0;
+ if ((i4 | 0) == 0) {
+  i5 = HEAP32[i3 >> 2] | 0;
+  i5 = i5 + -16 | 0;
+  HEAP32[i3 >> 2] = i5;
+  STACKTOP = i1;
+  return i4 | 0;
+ }
+ i6 = HEAP32[i3 >> 2] | 0;
+ i5 = HEAP32[i2 >> 2] | 0;
+ i8 = i6 + -16 | 0;
+ i7 = HEAP32[i8 + 4 >> 2] | 0;
+ i2 = i5;
+ HEAP32[i2 >> 2] = HEAP32[i8 >> 2];
+ HEAP32[i2 + 4 >> 2] = i7;
+ HEAP32[i5 + 8 >> 2] = HEAP32[i6 + -8 >> 2];
+ i5 = HEAP32[i3 >> 2] | 0;
+ i5 = i5 + -16 | 0;
+ HEAP32[i3 >> 2] = i5;
+ STACKTOP = i1;
+ return i4 | 0;
+}
+function ___remdi3(i1, i4, i5, i6) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ var i2 = 0, i3 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 8 | 0;
+ i2 = i3 | 0;
+ i7 = i4 >> 31 | ((i4 | 0) < 0 ? -1 : 0) << 1;
+ i8 = ((i4 | 0) < 0 ? -1 : 0) >> 31 | ((i4 | 0) < 0 ? -1 : 0) << 1;
+ i9 = i6 >> 31 | ((i6 | 0) < 0 ? -1 : 0) << 1;
+ i10 = ((i6 | 0) < 0 ? -1 : 0) >> 31 | ((i6 | 0) < 0 ? -1 : 0) << 1;
+ i1 = _i64Subtract(i7 ^ i1, i8 ^ i4, i7, i8) | 0;
+ i4 = tempRet0;
+ ___udivmoddi4(i1, i4, _i64Subtract(i9 ^ i5, i10 ^ i6, i9, i10) | 0, tempRet0, i2) | 0;
+ i9 = _i64Subtract(HEAP32[i2 >> 2] ^ i7, HEAP32[i2 + 4 >> 2] ^ i8, i7, i8) | 0;
+ i8 = tempRet0;
+ STACKTOP = i3;
+ return (tempRet0 = i8, i9) | 0;
+}
+function _luaC_barrierproto_(i3, i4, i2) {
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i5 = 0;
+ i1 = STACKTOP;
+ if ((HEAP32[i4 + 32 >> 2] | 0) != 0) {
+  i5 = HEAP32[i3 + 12 >> 2] | 0;
+  i3 = i4 + 5 | 0;
+  HEAP8[i3] = HEAP8[i3] & 251;
+  i5 = i5 + 88 | 0;
+  HEAP32[i4 + 72 >> 2] = HEAP32[i5 >> 2];
+  HEAP32[i5 >> 2] = i4;
+  STACKTOP = i1;
+  return;
+ }
+ if ((HEAP8[i2 + 5 | 0] & 3) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i5 = i4 + 5 | 0;
+ i4 = HEAP8[i5] | 0;
+ if ((i4 & 4) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i3 = HEAP32[i3 + 12 >> 2] | 0;
+ if ((HEAPU8[i3 + 61 | 0] | 0) < 2) {
+  _reallymarkobject(i3, i2);
+  STACKTOP = i1;
+  return;
+ } else {
+  HEAP8[i5] = HEAP8[i3 + 60 | 0] & 3 | i4 & 184;
+  STACKTOP = i1;
+  return;
+ }
+}
+function _luaL_openlibs(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_requiref(i1, 2592, 144, 1);
+ _lua_settop(i1, -2);
+ _luaL_requiref(i1, 2600, 145, 1);
+ _lua_settop(i1, -2);
+ _luaL_requiref(i1, 2608, 146, 1);
+ _lua_settop(i1, -2);
+ _luaL_requiref(i1, 2624, 147, 1);
+ _lua_settop(i1, -2);
+ _luaL_requiref(i1, 2632, 148, 1);
+ _lua_settop(i1, -2);
+ _luaL_requiref(i1, 2640, 149, 1);
+ _lua_settop(i1, -2);
+ _luaL_requiref(i1, 2648, 150, 1);
+ _lua_settop(i1, -2);
+ _luaL_requiref(i1, 2656, 151, 1);
+ _lua_settop(i1, -2);
+ _luaL_requiref(i1, 2664, 152, 1);
+ _lua_settop(i1, -2);
+ _luaL_requiref(i1, 2672, 153, 1);
+ _lua_settop(i1, -2);
+ _luaL_getsubtable(i1, -1001e3, 2576) | 0;
+ _lua_settop(i1, -2);
+ STACKTOP = i2;
+ return;
+}
+function _luaX_token2str(i4, i3) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i2 = 0, i5 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i1;
+ if ((i3 | 0) >= 257) {
+  i5 = HEAP32[12096 + (i3 + -257 << 2) >> 2] | 0;
+  if ((i3 | 0) >= 286) {
+   STACKTOP = i1;
+   return i5 | 0;
+  }
+  i4 = HEAP32[i4 + 52 >> 2] | 0;
+  HEAP32[i2 >> 2] = i5;
+  i5 = _luaO_pushfstring(i4, 12256, i2) | 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ i4 = HEAP32[i4 + 52 >> 2] | 0;
+ if ((HEAP8[i3 + 10913 | 0] & 4) == 0) {
+  HEAP32[i2 >> 2] = i3;
+  i5 = _luaO_pushfstring(i4, 12240, i2) | 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ } else {
+  HEAP32[i2 >> 2] = i3;
+  i5 = _luaO_pushfstring(i4, 12232, i2) | 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ return 0;
+}
+function _luaL_buffinitsize(i6, i1, i7) {
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ i7 = i7 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i8 = 0;
+ i2 = STACKTOP;
+ HEAP32[i1 + 12 >> 2] = i6;
+ i3 = i1 + 16 | 0;
+ HEAP32[i1 >> 2] = i3;
+ i5 = i1 + 8 | 0;
+ HEAP32[i5 >> 2] = 0;
+ i4 = i1 + 4 | 0;
+ HEAP32[i4 >> 2] = 1024;
+ if (!(i7 >>> 0 > 1024)) {
+  i7 = i3;
+  i8 = 0;
+  i8 = i7 + i8 | 0;
+  STACKTOP = i2;
+  return i8 | 0;
+ }
+ i8 = i7 >>> 0 > 2048 ? i7 : 2048;
+ i7 = _lua_newuserdata(i6, i8) | 0;
+ _memcpy(i7 | 0, HEAP32[i1 >> 2] | 0, HEAP32[i5 >> 2] | 0) | 0;
+ if ((HEAP32[i1 >> 2] | 0) != (i3 | 0)) {
+  _lua_remove(i6, -2);
+ }
+ HEAP32[i1 >> 2] = i7;
+ HEAP32[i4 >> 2] = i8;
+ i8 = HEAP32[i5 >> 2] | 0;
+ i8 = i7 + i8 | 0;
+ STACKTOP = i2;
+ return i8 | 0;
+}
+function _luaE_freethread(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ i4 = i3 + 28 | 0;
+ _luaF_close(i3, HEAP32[i4 >> 2] | 0);
+ i5 = HEAP32[i4 >> 2] | 0;
+ if ((i5 | 0) == 0) {
+  _luaM_realloc_(i1, i3, 112, 0) | 0;
+  STACKTOP = i2;
+  return;
+ }
+ HEAP32[i3 + 16 >> 2] = i3 + 72;
+ i7 = i3 + 84 | 0;
+ i6 = HEAP32[i7 >> 2] | 0;
+ HEAP32[i7 >> 2] = 0;
+ if ((i6 | 0) != 0) {
+  while (1) {
+   i5 = HEAP32[i6 + 12 >> 2] | 0;
+   _luaM_realloc_(i3, i6, 40, 0) | 0;
+   if ((i5 | 0) == 0) {
+    break;
+   } else {
+    i6 = i5;
+   }
+  }
+  i5 = HEAP32[i4 >> 2] | 0;
+ }
+ _luaM_realloc_(i3, i5, HEAP32[i3 + 32 >> 2] << 4, 0) | 0;
+ _luaM_realloc_(i1, i3, 112, 0) | 0;
+ STACKTOP = i2;
+ return;
+}
+function ___toread(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i3 = STACKTOP;
+ i4 = i1 + 74 | 0;
+ i2 = HEAP8[i4] | 0;
+ HEAP8[i4] = i2 + 255 | i2;
+ i4 = i1 + 20 | 0;
+ i2 = i1 + 44 | 0;
+ if ((HEAP32[i4 >> 2] | 0) >>> 0 > (HEAP32[i2 >> 2] | 0) >>> 0) {
+  FUNCTION_TABLE_iiii[HEAP32[i1 + 36 >> 2] & 3](i1, 0, 0) | 0;
+ }
+ HEAP32[i1 + 16 >> 2] = 0;
+ HEAP32[i1 + 28 >> 2] = 0;
+ HEAP32[i4 >> 2] = 0;
+ i4 = HEAP32[i1 >> 2] | 0;
+ if ((i4 & 20 | 0) == 0) {
+  i4 = HEAP32[i2 >> 2] | 0;
+  HEAP32[i1 + 8 >> 2] = i4;
+  HEAP32[i1 + 4 >> 2] = i4;
+  i4 = 0;
+  STACKTOP = i3;
+  return i4 | 0;
+ }
+ if ((i4 & 4 | 0) == 0) {
+  i4 = -1;
+  STACKTOP = i3;
+  return i4 | 0;
+ }
+ HEAP32[i1 >> 2] = i4 | 32;
+ i4 = -1;
+ STACKTOP = i3;
+ return i4 | 0;
+}
+function _lua_callk(i3, i7, i4, i6, i5) {
+ i3 = i3 | 0;
+ i7 = i7 | 0;
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i8 = 0;
+ i1 = STACKTOP;
+ i2 = i3 + 8 | 0;
+ i7 = (HEAP32[i2 >> 2] | 0) + (~i7 << 4) | 0;
+ if ((i5 | 0) != 0 ? (HEAP16[i3 + 36 >> 1] | 0) == 0 : 0) {
+  i8 = i3 + 16 | 0;
+  HEAP32[(HEAP32[i8 >> 2] | 0) + 28 >> 2] = i5;
+  HEAP32[(HEAP32[i8 >> 2] | 0) + 24 >> 2] = i6;
+  _luaD_call(i3, i7, i4, 1);
+ } else {
+  _luaD_call(i3, i7, i4, 0);
+ }
+ if (!((i4 | 0) == -1)) {
+  STACKTOP = i1;
+  return;
+ }
+ i3 = (HEAP32[i3 + 16 >> 2] | 0) + 4 | 0;
+ i2 = HEAP32[i2 >> 2] | 0;
+ if (!((HEAP32[i3 >> 2] | 0) >>> 0 < i2 >>> 0)) {
+  STACKTOP = i1;
+  return;
+ }
+ HEAP32[i3 >> 2] = i2;
+ STACKTOP = i1;
+ return;
+}
+function _luaX_newstring(i3, i5, i4) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i6 = 0;
+ i1 = STACKTOP;
+ i2 = HEAP32[i3 + 52 >> 2] | 0;
+ i5 = _luaS_newlstr(i2, i5, i4) | 0;
+ i4 = i2 + 8 | 0;
+ i6 = HEAP32[i4 >> 2] | 0;
+ HEAP32[i4 >> 2] = i6 + 16;
+ HEAP32[i6 >> 2] = i5;
+ HEAP32[i6 + 8 >> 2] = HEAPU8[i5 + 4 | 0] | 0 | 64;
+ i6 = _luaH_set(i2, HEAP32[(HEAP32[i3 + 48 >> 2] | 0) + 4 >> 2] | 0, (HEAP32[i4 >> 2] | 0) + -16 | 0) | 0;
+ i3 = i6 + 8 | 0;
+ if ((HEAP32[i3 >> 2] | 0) == 0 ? (HEAP32[i6 >> 2] = 1, HEAP32[i3 >> 2] = 1, (HEAP32[(HEAP32[i2 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) : 0) {
+  _luaC_step(i2);
+ }
+ HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + -16;
+ STACKTOP = i1;
+ return i5 | 0;
+}
+function _strtod(i3, i2) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i4 = 0, d5 = 0.0, i6 = 0, i7 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 112 | 0;
+ i4 = i1;
+ i7 = i4 + 0 | 0;
+ i6 = i7 + 112 | 0;
+ do {
+  HEAP32[i7 >> 2] = 0;
+  i7 = i7 + 4 | 0;
+ } while ((i7 | 0) < (i6 | 0));
+ i6 = i4 + 4 | 0;
+ HEAP32[i6 >> 2] = i3;
+ i7 = i4 + 8 | 0;
+ HEAP32[i7 >> 2] = -1;
+ HEAP32[i4 + 44 >> 2] = i3;
+ HEAP32[i4 + 76 >> 2] = -1;
+ ___shlim(i4, 0);
+ d5 = +___floatscan(i4, 1, 1);
+ i4 = (HEAP32[i6 >> 2] | 0) - (HEAP32[i7 >> 2] | 0) + (HEAP32[i4 + 108 >> 2] | 0) | 0;
+ if ((i2 | 0) == 0) {
+  STACKTOP = i1;
+  return +d5;
+ }
+ if ((i4 | 0) != 0) {
+  i3 = i3 + i4 | 0;
+ }
+ HEAP32[i2 >> 2] = i3;
+ STACKTOP = i1;
+ return +d5;
+}
+function _f_seek(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, d6 = 0.0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = _luaL_checkudata(i1, 1, 2832) | 0;
+ if ((HEAP32[i3 + 4 >> 2] | 0) == 0) {
+  _luaL_error(i1, 3080, i2) | 0;
+ }
+ i3 = HEAP32[i3 >> 2] | 0;
+ i5 = _luaL_checkoption(i1, 2, 3208, 3184) | 0;
+ d6 = +_luaL_optnumber(i1, 3, 0.0);
+ i4 = ~~d6;
+ if (!(+(i4 | 0) == d6)) {
+  _luaL_argerror(i1, 3, 3224) | 0;
+ }
+ if ((_fseek(i3 | 0, i4 | 0, HEAP32[3168 + (i5 << 2) >> 2] | 0) | 0) == 0) {
+  _lua_pushnumber(i1, +(_ftell(i3 | 0) | 0));
+  i5 = 1;
+  STACKTOP = i2;
+  return i5 | 0;
+ } else {
+  i5 = _luaL_fileresult(i1, 0, 0) | 0;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ return 0;
+}
+function _setpath(i1, i4, i8, i7, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i8 = i8 | 0;
+ i7 = i7 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ i8 = _getenv(i8 | 0) | 0;
+ if ((i8 | 0) == 0) {
+  i7 = _getenv(i7 | 0) | 0;
+  if ((i7 | 0) != 0) {
+   i5 = i7;
+   i6 = 3;
+  }
+ } else {
+  i5 = i8;
+  i6 = 3;
+ }
+ if ((i6 | 0) == 3 ? (_lua_getfield(i1, -1001e3, 4832), i8 = _lua_toboolean(i1, -1) | 0, _lua_settop(i1, -2), (i8 | 0) == 0) : 0) {
+  _luaL_gsub(i1, _luaL_gsub(i1, i5, 4808, 4816) | 0, 4824, i3) | 0;
+  _lua_remove(i1, -2);
+  _lua_setfield(i1, -2, i4);
+  STACKTOP = i2;
+  return;
+ }
+ _lua_pushstring(i1, i3) | 0;
+ _lua_setfield(i1, -2, i4);
+ STACKTOP = i2;
+ return;
+}
+function _luaU_header(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ HEAP8[i1] = 1635077147;
+ HEAP8[i1 + 1 | 0] = 6387020;
+ HEAP8[i1 + 2 | 0] = 24949;
+ HEAP8[i1 + 3 | 0] = 97;
+ HEAP8[i1 + 4 | 0] = 82;
+ HEAP8[i1 + 5 | 0] = 0;
+ HEAP8[i1 + 6 | 0] = 1;
+ HEAP8[i1 + 7 | 0] = 4;
+ HEAP8[i1 + 8 | 0] = 4;
+ HEAP8[i1 + 9 | 0] = 4;
+ HEAP8[i1 + 10 | 0] = 8;
+ i3 = i1 + 12 | 0;
+ HEAP8[i1 + 11 | 0] = 0;
+ HEAP8[i3 + 0 | 0] = HEAP8[8816 | 0] | 0;
+ HEAP8[i3 + 1 | 0] = HEAP8[8817 | 0] | 0;
+ HEAP8[i3 + 2 | 0] = HEAP8[8818 | 0] | 0;
+ HEAP8[i3 + 3 | 0] = HEAP8[8819 | 0] | 0;
+ HEAP8[i3 + 4 | 0] = HEAP8[8820 | 0] | 0;
+ HEAP8[i3 + 5 | 0] = HEAP8[8821 | 0] | 0;
+ STACKTOP = i2;
+ return;
+}
+function _db_setlocal(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 112 | 0;
+ i3 = i2;
+ if ((_lua_type(i1, 1) | 0) == 8) {
+  i5 = _lua_tothread(i1, 1) | 0;
+  i4 = 1;
+ } else {
+  i5 = i1;
+  i4 = 0;
+ }
+ i6 = i4 + 1 | 0;
+ if ((_lua_getstack(i5, _luaL_checkinteger(i1, i6) | 0, i3) | 0) == 0) {
+  i6 = _luaL_argerror(i1, i6, 11560) | 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ } else {
+  i6 = i4 + 3 | 0;
+  _luaL_checkany(i1, i6);
+  _lua_settop(i1, i6);
+  _lua_xmove(i1, i5, 1);
+  _lua_pushstring(i1, _lua_setlocal(i5, i3, _luaL_checkinteger(i1, i4 | 2) | 0) | 0) | 0;
+  i6 = 1;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ return 0;
+}
+function _tremove(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ _luaL_checktype(i1, 1, 5);
+ i3 = _luaL_len(i1, 1) | 0;
+ i4 = _luaL_optinteger(i1, 2, i3) | 0;
+ if ((i4 | 0) != (i3 | 0) ? (i4 | 0) < 1 | (i4 | 0) > (i3 + 1 | 0) : 0) {
+  _luaL_argerror(i1, 1, 8256) | 0;
+ }
+ _lua_rawgeti(i1, 1, i4);
+ if ((i4 | 0) >= (i3 | 0)) {
+  i5 = i4;
+  _lua_pushnil(i1);
+  _lua_rawseti(i1, 1, i5);
+  STACKTOP = i2;
+  return 1;
+ }
+ while (1) {
+  i5 = i4 + 1 | 0;
+  _lua_rawgeti(i1, 1, i5);
+  _lua_rawseti(i1, 1, i4);
+  if ((i5 | 0) == (i3 | 0)) {
+   break;
+  } else {
+   i4 = i5;
+  }
+ }
+ _lua_pushnil(i1);
+ _lua_rawseti(i1, 1, i3);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaL_checkudata(i1, i7, i5) {
+ i1 = i1 | 0;
+ i7 = i7 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ i3 = _lua_touserdata(i1, i7) | 0;
+ if (((i3 | 0) != 0 ? (_lua_getmetatable(i1, i7) | 0) != 0 : 0) ? (_lua_getfield(i1, -1001e3, i5), i6 = (_lua_rawequal(i1, -1, -2) | 0) == 0, i6 = i6 ? 0 : i3, _lua_settop(i1, -3), (i6 | 0) != 0) : 0) {
+  i7 = i6;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ i6 = _lua_typename(i1, _lua_type(i1, i7) | 0) | 0;
+ HEAP32[i4 >> 2] = i5;
+ HEAP32[i4 + 4 >> 2] = i6;
+ _luaL_argerror(i1, i7, _lua_pushfstring(i1, 1744, i4) | 0) | 0;
+ i7 = 0;
+ STACKTOP = i2;
+ return i7 | 0;
+}
+function _luaL_error(i1, i5, i7) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i7 = i7 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 128 | 0;
+ i3 = i4;
+ i2 = i4 + 24 | 0;
+ i4 = i4 + 8 | 0;
+ HEAP32[i4 >> 2] = i7;
+ if ((_lua_getstack(i1, 1, i2) | 0) != 0 ? (_lua_getinfo(i1, 1152, i2) | 0, i6 = HEAP32[i2 + 20 >> 2] | 0, (i6 | 0) > 0) : 0) {
+  HEAP32[i3 >> 2] = i2 + 36;
+  HEAP32[i3 + 4 >> 2] = i6;
+  _lua_pushfstring(i1, 1160, i3) | 0;
+  _lua_pushvfstring(i1, i5, i4) | 0;
+  _lua_concat(i1, 2);
+  _lua_error(i1) | 0;
+ }
+ _lua_pushlstring(i1, 1168, 0) | 0;
+ _lua_pushvfstring(i1, i5, i4) | 0;
+ _lua_concat(i1, 2);
+ _lua_error(i1) | 0;
+ return 0;
+}
+function _luaK_infix(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ L1 : do {
+  switch (i4 | 0) {
+  case 6:
+   {
+    _luaK_exp2nextreg(i1, i3);
+    break;
+   }
+  case 5:
+  case 4:
+  case 3:
+  case 2:
+  case 1:
+  case 0:
+   {
+    if (((HEAP32[i3 >> 2] | 0) == 5 ? (HEAP32[i3 + 16 >> 2] | 0) == -1 : 0) ? (HEAP32[i3 + 20 >> 2] | 0) == -1 : 0) {
+     break L1;
+    }
+    _luaK_exp2RK(i1, i3) | 0;
+    break;
+   }
+  case 13:
+   {
+    _luaK_goiftrue(i1, i3);
+    break;
+   }
+  case 14:
+   {
+    _luaK_goiffalse(i1, i3);
+    break;
+   }
+  default:
+   {
+    _luaK_exp2RK(i1, i3) | 0;
+   }
+  }
+ } while (0);
+ STACKTOP = i2;
+ return;
+}
+function _luaD_shrinkstack(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i1 + 8 >> 2] | 0;
+ i3 = HEAP32[i1 + 16 >> 2] | 0;
+ if ((i3 | 0) != 0) {
+  do {
+   i5 = HEAP32[i3 + 4 >> 2] | 0;
+   i4 = i4 >>> 0 < i5 >>> 0 ? i5 : i4;
+   i3 = HEAP32[i3 + 8 >> 2] | 0;
+  } while ((i3 | 0) != 0);
+ }
+ i3 = i4 - (HEAP32[i1 + 28 >> 2] | 0) | 0;
+ i4 = (i3 >> 4) + 1 | 0;
+ i4 = ((i4 | 0) / 8 | 0) + 10 + i4 | 0;
+ i4 = (i4 | 0) > 1e6 ? 1e6 : i4;
+ if ((i3 | 0) > 15999984) {
+  STACKTOP = i2;
+  return;
+ }
+ if ((i4 | 0) >= (HEAP32[i1 + 32 >> 2] | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ _luaD_reallocstack(i1, i4);
+ STACKTOP = i2;
+ return;
+}
+function _luaF_newproto(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i1 = _luaC_newobj(i1, 9, 80, 0, 0) | 0;
+ HEAP32[i1 + 8 >> 2] = 0;
+ HEAP32[i1 + 44 >> 2] = 0;
+ HEAP32[i1 + 16 >> 2] = 0;
+ HEAP32[i1 + 56 >> 2] = 0;
+ HEAP32[i1 + 12 >> 2] = 0;
+ HEAP32[i1 + 32 >> 2] = 0;
+ HEAP32[i1 + 48 >> 2] = 0;
+ HEAP32[i1 + 20 >> 2] = 0;
+ HEAP32[i1 + 52 >> 2] = 0;
+ HEAP32[i1 + 28 >> 2] = 0;
+ HEAP32[i1 + 40 >> 2] = 0;
+ HEAP8[i1 + 76 | 0] = 0;
+ HEAP8[i1 + 77 | 0] = 0;
+ HEAP8[i1 + 78 | 0] = 0;
+ HEAP32[i1 + 24 >> 2] = 0;
+ HEAP32[i1 + 60 >> 2] = 0;
+ HEAP32[i1 + 64 >> 2] = 0;
+ HEAP32[i1 + 68 >> 2] = 0;
+ HEAP32[i1 + 36 >> 2] = 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _luaF_freeproto(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ _luaM_realloc_(i2, HEAP32[i1 + 12 >> 2] | 0, HEAP32[i1 + 48 >> 2] << 2, 0) | 0;
+ _luaM_realloc_(i2, HEAP32[i1 + 16 >> 2] | 0, HEAP32[i1 + 56 >> 2] << 2, 0) | 0;
+ _luaM_realloc_(i2, HEAP32[i1 + 8 >> 2] | 0, HEAP32[i1 + 44 >> 2] << 4, 0) | 0;
+ _luaM_realloc_(i2, HEAP32[i1 + 20 >> 2] | 0, HEAP32[i1 + 52 >> 2] << 2, 0) | 0;
+ _luaM_realloc_(i2, HEAP32[i1 + 24 >> 2] | 0, (HEAP32[i1 + 60 >> 2] | 0) * 12 | 0, 0) | 0;
+ _luaM_realloc_(i2, HEAP32[i1 + 28 >> 2] | 0, HEAP32[i1 + 40 >> 2] << 3, 0) | 0;
+ _luaM_realloc_(i2, i1, 80, 0) | 0;
+ STACKTOP = i3;
+ return;
+}
+function _luaK_patchclose(i3, i7, i4) {
+ i3 = i3 | 0;
+ i7 = i7 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i5 = 0, i6 = 0, i8 = 0;
+ i2 = STACKTOP;
+ if ((i7 | 0) == -1) {
+  STACKTOP = i2;
+  return;
+ }
+ i3 = HEAP32[(HEAP32[i3 >> 2] | 0) + 12 >> 2] | 0;
+ i4 = (i4 << 6) + 64 & 16320;
+ while (1) {
+  i6 = i3 + (i7 << 2) | 0;
+  i5 = HEAP32[i6 >> 2] | 0;
+  i8 = (i5 >>> 14) + -131071 | 0;
+  if ((i8 | 0) == -1) {
+   break;
+  }
+  i7 = i7 + 1 + i8 | 0;
+  HEAP32[i6 >> 2] = i5 & -16321 | i4;
+  if ((i7 | 0) == -1) {
+   i1 = 6;
+   break;
+  }
+ }
+ if ((i1 | 0) == 6) {
+  STACKTOP = i2;
+  return;
+ }
+ HEAP32[i6 >> 2] = i5 & -16321 | i4;
+ STACKTOP = i2;
+ return;
+}
+function _loadfunc(i1, i4, i5) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ i6 = _luaL_gsub(i1, i5, 4936, 4944) | 0;
+ i5 = _strchr(i6, 45) | 0;
+ do {
+  if ((i5 | 0) != 0) {
+   HEAP32[i3 >> 2] = _lua_pushlstring(i1, i6, i5 - i6 | 0) | 0;
+   i6 = _ll_loadfunc(i1, i4, _lua_pushfstring(i1, 4952, i3) | 0) | 0;
+   if ((i6 | 0) == 2) {
+    i6 = i5 + 1 | 0;
+    break;
+   } else {
+    STACKTOP = i2;
+    return i6 | 0;
+   }
+  }
+ } while (0);
+ HEAP32[i3 >> 2] = i6;
+ i6 = _ll_loadfunc(i1, i4, _lua_pushfstring(i1, 4952, i3) | 0) | 0;
+ STACKTOP = i2;
+ return i6 | 0;
+}
+function _luaK_setlist(i1, i3, i4, i5) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i4 = ((i4 + -1 | 0) / 50 | 0) + 1 | 0;
+ i5 = (i5 | 0) == -1 ? 0 : i5;
+ if ((i4 | 0) < 512) {
+  _luaK_code(i1, i3 << 6 | i5 << 23 | i4 << 14 | 36) | 0;
+  i4 = i3 + 1 | 0;
+  i4 = i4 & 255;
+  i5 = i1 + 48 | 0;
+  HEAP8[i5] = i4;
+  STACKTOP = i2;
+  return;
+ }
+ if ((i4 | 0) >= 67108864) {
+  _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10576);
+ }
+ _luaK_code(i1, i3 << 6 | i5 << 23 | 36) | 0;
+ _luaK_code(i1, i4 << 6 | 39) | 0;
+ i4 = i3 + 1 | 0;
+ i4 = i4 & 255;
+ i5 = i1 + 48 | 0;
+ HEAP8[i5] = i4;
+ STACKTOP = i2;
+ return;
+}
+function _lua_getstack(i2, i6, i3) {
+ i2 = i2 | 0;
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i4 = 0, i5 = 0;
+ i1 = STACKTOP;
+ L1 : do {
+  if ((i6 | 0) >= 0) {
+   i5 = HEAP32[i2 + 16 >> 2] | 0;
+   if ((i6 | 0) > 0) {
+    i4 = i2 + 72 | 0;
+    do {
+     if ((i5 | 0) == (i4 | 0)) {
+      i2 = 0;
+      break L1;
+     }
+     i6 = i6 + -1 | 0;
+     i5 = HEAP32[i5 + 8 >> 2] | 0;
+    } while ((i6 | 0) > 0);
+    if ((i6 | 0) != 0) {
+     i2 = 0;
+     break;
+    }
+   }
+   if ((i5 | 0) != (i2 + 72 | 0)) {
+    HEAP32[i3 + 96 >> 2] = i5;
+    i2 = 1;
+   } else {
+    i2 = 0;
+   }
+  } else {
+   i2 = 0;
+  }
+ } while (0);
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _luaC_checkupvalcolor(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i4 = i5 + 5 | 0;
+ i3 = HEAPU8[i4] | 0;
+ if ((i3 & 7 | 0) != 0) {
+  STACKTOP = i2;
+  return;
+ }
+ if ((HEAP8[i1 + 62 | 0] | 0) != 2 ? (HEAPU8[i1 + 61 | 0] | 0) >= 2 : 0) {
+  HEAP8[i4] = HEAP8[i1 + 60 | 0] & 3 | i3 & 184;
+  STACKTOP = i2;
+  return;
+ }
+ HEAP8[i4] = i3 & 187 | 4;
+ i3 = HEAP32[i5 + 8 >> 2] | 0;
+ if ((HEAP32[i3 + 8 >> 2] & 64 | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ i3 = HEAP32[i3 >> 2] | 0;
+ if ((HEAP8[i3 + 5 | 0] & 3) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ _reallymarkobject(i1, i3);
+ STACKTOP = i2;
+ return;
+}
+function _luaB_collectgarbage(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[10160 + ((_luaL_checkoption(i1, 1, 10040, 9976) | 0) << 2) >> 2] | 0;
+ i3 = _lua_gc(i1, i4, _luaL_optinteger(i1, 2, 0) | 0) | 0;
+ if ((i4 | 0) == 3) {
+  i4 = _lua_gc(i1, 4, 0) | 0;
+  _lua_pushnumber(i1, +(i3 | 0) + +(i4 | 0) * .0009765625);
+  _lua_pushinteger(i1, i4);
+  i4 = 2;
+  STACKTOP = i2;
+  return i4 | 0;
+ } else if ((i4 | 0) == 9 | (i4 | 0) == 5) {
+  _lua_pushboolean(i1, i3);
+  i4 = 1;
+  STACKTOP = i2;
+  return i4 | 0;
+ } else {
+  _lua_pushinteger(i1, i3);
+  i4 = 1;
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ return 0;
+}
+function _maxn(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, d3 = 0.0, d4 = 0.0;
+ i2 = STACKTOP;
+ _luaL_checktype(i1, 1, 5);
+ _lua_pushnil(i1);
+ L1 : do {
+  if ((_lua_next(i1, 1) | 0) == 0) {
+   d3 = 0.0;
+  } else {
+   d4 = 0.0;
+   while (1) {
+    while (1) {
+     _lua_settop(i1, -2);
+     if ((_lua_type(i1, -1) | 0) == 3 ? (d3 = +_lua_tonumberx(i1, -1, 0), d3 > d4) : 0) {
+      break;
+     }
+     if ((_lua_next(i1, 1) | 0) == 0) {
+      d3 = d4;
+      break L1;
+     }
+    }
+    if ((_lua_next(i1, 1) | 0) == 0) {
+     break;
+    } else {
+     d4 = d3;
+    }
+   }
+  }
+ } while (0);
+ _lua_pushnumber(i1, d3);
+ STACKTOP = i2;
+ return 1;
+}
+function _str_char(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 1040 | 0;
+ i4 = i2;
+ i3 = _lua_gettop(i1) | 0;
+ i5 = _luaL_buffinitsize(i1, i4, i3) | 0;
+ if ((i3 | 0) < 1) {
+  _luaL_pushresultsize(i4, i3);
+  STACKTOP = i2;
+  return 1;
+ } else {
+  i6 = 1;
+ }
+ while (1) {
+  i7 = _luaL_checkinteger(i1, i6) | 0;
+  if ((i7 & 255 | 0) != (i7 | 0)) {
+   _luaL_argerror(i1, i6, 7920) | 0;
+  }
+  HEAP8[i5 + (i6 + -1) | 0] = i7;
+  if ((i6 | 0) == (i3 | 0)) {
+   break;
+  } else {
+   i6 = i6 + 1 | 0;
+  }
+ }
+ _luaL_pushresultsize(i4, i3);
+ STACKTOP = i2;
+ return 1;
+}
+function _memcpy(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ if ((i1 | 0) >= 4096) return _emscripten_memcpy_big(i3 | 0, i2 | 0, i1 | 0) | 0;
+ i4 = i3 | 0;
+ if ((i3 & 3) == (i2 & 3)) {
+  while (i3 & 3) {
+   if ((i1 | 0) == 0) return i4 | 0;
+   HEAP8[i3] = HEAP8[i2] | 0;
+   i3 = i3 + 1 | 0;
+   i2 = i2 + 1 | 0;
+   i1 = i1 - 1 | 0;
+  }
+  while ((i1 | 0) >= 4) {
+   HEAP32[i3 >> 2] = HEAP32[i2 >> 2];
+   i3 = i3 + 4 | 0;
+   i2 = i2 + 4 | 0;
+   i1 = i1 - 4 | 0;
+  }
+ }
+ while ((i1 | 0) > 0) {
+  HEAP8[i3] = HEAP8[i2] | 0;
+  i3 = i3 + 1 | 0;
+  i2 = i2 + 1 | 0;
+  i1 = i1 - 1 | 0;
+ }
+ return i4 | 0;
+}
+function _luaK_exp2val(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0;
+ i2 = STACKTOP;
+ i3 = i5 + 16 | 0;
+ i4 = i5 + 20 | 0;
+ if ((HEAP32[i3 >> 2] | 0) == (HEAP32[i4 >> 2] | 0)) {
+  _luaK_dischargevars(i1, i5);
+  STACKTOP = i2;
+  return;
+ }
+ _luaK_dischargevars(i1, i5);
+ if ((HEAP32[i5 >> 2] | 0) == 6) {
+  i6 = HEAP32[i5 + 8 >> 2] | 0;
+  if ((HEAP32[i3 >> 2] | 0) == (HEAP32[i4 >> 2] | 0)) {
+   STACKTOP = i2;
+   return;
+  }
+  if ((i6 | 0) >= (HEAPU8[i1 + 46 | 0] | 0 | 0)) {
+   _exp2reg(i1, i5, i6);
+   STACKTOP = i2;
+   return;
+  }
+ }
+ _luaK_exp2nextreg(i1, i5);
+ STACKTOP = i2;
+ return;
+}
+function _str_reverse(i5) {
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 1056 | 0;
+ i4 = i2 + 1040 | 0;
+ i1 = i2;
+ i3 = _luaL_checklstring(i5, 1, i4) | 0;
+ i5 = _luaL_buffinitsize(i5, i1, HEAP32[i4 >> 2] | 0) | 0;
+ i6 = HEAP32[i4 >> 2] | 0;
+ if ((i6 | 0) == 0) {
+  i7 = 0;
+  _luaL_pushresultsize(i1, i7);
+  STACKTOP = i2;
+  return 1;
+ } else {
+  i7 = 0;
+ }
+ do {
+  HEAP8[i5 + i7 | 0] = HEAP8[i3 + (i6 + ~i7) | 0] | 0;
+  i7 = i7 + 1 | 0;
+  i6 = HEAP32[i4 >> 2] | 0;
+ } while (i7 >>> 0 < i6 >>> 0);
+ _luaL_pushresultsize(i1, i6);
+ STACKTOP = i2;
+ return 1;
+}
+function _str_upper(i5) {
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 1056 | 0;
+ i4 = i1 + 1040 | 0;
+ i2 = i1;
+ i3 = _luaL_checklstring(i5, 1, i4) | 0;
+ i5 = _luaL_buffinitsize(i5, i2, HEAP32[i4 >> 2] | 0) | 0;
+ if ((HEAP32[i4 >> 2] | 0) == 0) {
+  i7 = 0;
+  _luaL_pushresultsize(i2, i7);
+  STACKTOP = i1;
+  return 1;
+ } else {
+  i6 = 0;
+ }
+ do {
+  HEAP8[i5 + i6 | 0] = _toupper(HEAPU8[i3 + i6 | 0] | 0 | 0) | 0;
+  i6 = i6 + 1 | 0;
+  i7 = HEAP32[i4 >> 2] | 0;
+ } while (i6 >>> 0 < i7 >>> 0);
+ _luaL_pushresultsize(i2, i7);
+ STACKTOP = i1;
+ return 1;
+}
+function _str_lower(i5) {
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 1056 | 0;
+ i4 = i1 + 1040 | 0;
+ i2 = i1;
+ i3 = _luaL_checklstring(i5, 1, i4) | 0;
+ i5 = _luaL_buffinitsize(i5, i2, HEAP32[i4 >> 2] | 0) | 0;
+ if ((HEAP32[i4 >> 2] | 0) == 0) {
+  i7 = 0;
+  _luaL_pushresultsize(i2, i7);
+  STACKTOP = i1;
+  return 1;
+ } else {
+  i6 = 0;
+ }
+ do {
+  HEAP8[i5 + i6 | 0] = _tolower(HEAPU8[i3 + i6 | 0] | 0 | 0) | 0;
+  i6 = i6 + 1 | 0;
+  i7 = HEAP32[i4 >> 2] | 0;
+ } while (i6 >>> 0 < i7 >>> 0);
+ _luaL_pushresultsize(i2, i7);
+ STACKTOP = i1;
+ return 1;
+}
+function ___divdi3(i1, i2, i3, i4) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i5 = 0, i6 = 0, i7 = 0, i8 = 0;
+ i5 = i2 >> 31 | ((i2 | 0) < 0 ? -1 : 0) << 1;
+ i6 = ((i2 | 0) < 0 ? -1 : 0) >> 31 | ((i2 | 0) < 0 ? -1 : 0) << 1;
+ i7 = i4 >> 31 | ((i4 | 0) < 0 ? -1 : 0) << 1;
+ i8 = ((i4 | 0) < 0 ? -1 : 0) >> 31 | ((i4 | 0) < 0 ? -1 : 0) << 1;
+ i1 = _i64Subtract(i5 ^ i1, i6 ^ i2, i5, i6) | 0;
+ i2 = tempRet0;
+ i5 = i7 ^ i5;
+ i6 = i8 ^ i6;
+ i7 = _i64Subtract((___udivmoddi4(i1, i2, _i64Subtract(i7 ^ i3, i8 ^ i4, i7, i8) | 0, tempRet0, 0) | 0) ^ i5, tempRet0 ^ i6, i5, i6) | 0;
+ return i7 | 0;
+}
+function _luaK_setoneret(i1, i4) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = HEAP32[i4 >> 2] | 0;
+ if ((i3 | 0) == 13) {
+  i3 = (HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0) + (HEAP32[i4 + 8 >> 2] << 2) | 0;
+  HEAP32[i3 >> 2] = HEAP32[i3 >> 2] & 8388607 | 16777216;
+  HEAP32[i4 >> 2] = 11;
+  STACKTOP = i2;
+  return;
+ } else if ((i3 | 0) == 12) {
+  HEAP32[i4 >> 2] = 6;
+  i4 = i4 + 8 | 0;
+  HEAP32[i4 >> 2] = (HEAP32[(HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] | 0) + (HEAP32[i4 >> 2] << 2) >> 2] | 0) >>> 6 & 255;
+  STACKTOP = i2;
+  return;
+ } else {
+  STACKTOP = i2;
+  return;
+ }
+}
+function _luaV_tostring(i6, i1) {
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 48 | 0;
+ i3 = i2;
+ i4 = i2 + 8 | 0;
+ i5 = i1 + 8 | 0;
+ if ((HEAP32[i5 >> 2] | 0) != 3) {
+  i6 = 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ HEAPF64[tempDoublePtr >> 3] = +HEAPF64[i1 >> 3];
+ HEAP32[i3 >> 2] = HEAP32[tempDoublePtr >> 2];
+ HEAP32[i3 + 4 >> 2] = HEAP32[tempDoublePtr + 4 >> 2];
+ i6 = _luaS_newlstr(i6, i4, _sprintf(i4 | 0, 8936, i3 | 0) | 0) | 0;
+ HEAP32[i1 >> 2] = i6;
+ HEAP32[i5 >> 2] = HEAPU8[i6 + 4 | 0] | 0 | 64;
+ i6 = 1;
+ STACKTOP = i2;
+ return i6 | 0;
+}
+function _strcmp(i4, i2) {
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i5 = 0;
+ i1 = STACKTOP;
+ i5 = HEAP8[i4] | 0;
+ i3 = HEAP8[i2] | 0;
+ if (i5 << 24 >> 24 != i3 << 24 >> 24 | i5 << 24 >> 24 == 0 | i3 << 24 >> 24 == 0) {
+  i4 = i5;
+  i5 = i3;
+  i4 = i4 & 255;
+  i5 = i5 & 255;
+  i5 = i4 - i5 | 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ do {
+  i4 = i4 + 1 | 0;
+  i2 = i2 + 1 | 0;
+  i5 = HEAP8[i4] | 0;
+  i3 = HEAP8[i2] | 0;
+ } while (!(i5 << 24 >> 24 != i3 << 24 >> 24 | i5 << 24 >> 24 == 0 | i3 << 24 >> 24 == 0));
+ i4 = i5 & 255;
+ i5 = i3 & 255;
+ i5 = i4 - i5 | 0;
+ STACKTOP = i1;
+ return i5 | 0;
+}
+function _lua_pushstring(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0;
+ i2 = STACKTOP;
+ if ((i3 | 0) == 0) {
+  i3 = i1 + 8 | 0;
+  i1 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i1 + 8 >> 2] = 0;
+  HEAP32[i3 >> 2] = i1 + 16;
+  i3 = 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ if ((HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+  _luaC_step(i1);
+ }
+ i3 = _luaS_new(i1, i3) | 0;
+ i1 = i1 + 8 | 0;
+ i4 = HEAP32[i1 >> 2] | 0;
+ HEAP32[i4 >> 2] = i3;
+ HEAP32[i4 + 8 >> 2] = HEAPU8[i3 + 4 | 0] | 0 | 64;
+ HEAP32[i1 >> 2] = (HEAP32[i1 >> 2] | 0) + 16;
+ i3 = i3 + 16 | 0;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _luaK_exp2anyreg(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ _luaK_dischargevars(i1, i3);
+ if ((HEAP32[i3 >> 2] | 0) == 6) {
+  i5 = i3 + 8 | 0;
+  i4 = HEAP32[i5 >> 2] | 0;
+  if ((HEAP32[i3 + 16 >> 2] | 0) == (HEAP32[i3 + 20 >> 2] | 0)) {
+   i5 = i4;
+   STACKTOP = i2;
+   return i5 | 0;
+  }
+  if ((i4 | 0) >= (HEAPU8[i1 + 46 | 0] | 0 | 0)) {
+   _exp2reg(i1, i3, i4);
+   i5 = HEAP32[i5 >> 2] | 0;
+   STACKTOP = i2;
+   return i5 | 0;
+  }
+ } else {
+  i5 = i3 + 8 | 0;
+ }
+ _luaK_exp2nextreg(i1, i3);
+ i5 = HEAP32[i5 >> 2] | 0;
+ STACKTOP = i2;
+ return i5 | 0;
+}
+function _check_match(i1, i4, i5, i6) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ if ((HEAP32[i1 + 16 >> 2] | 0) == (i4 | 0)) {
+  _luaX_next(i1);
+  STACKTOP = i2;
+  return;
+ }
+ if ((HEAP32[i1 + 4 >> 2] | 0) == (i6 | 0)) {
+  _error_expected(i1, i4);
+ } else {
+  i2 = HEAP32[i1 + 52 >> 2] | 0;
+  i4 = _luaX_token2str(i1, i4) | 0;
+  i5 = _luaX_token2str(i1, i5) | 0;
+  HEAP32[i3 >> 2] = i4;
+  HEAP32[i3 + 4 >> 2] = i5;
+  HEAP32[i3 + 8 >> 2] = i6;
+  _luaX_syntaxerror(i1, _luaO_pushfstring(i2, 6840, i3) | 0);
+ }
+}
+function _fieldsel(i1, i6) {
+ i1 = i1 | 0;
+ i6 = i6 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i3 = i2;
+ i5 = i1 + 48 | 0;
+ i4 = HEAP32[i5 >> 2] | 0;
+ _luaK_exp2anyregup(i4, i6);
+ _luaX_next(i1);
+ if ((HEAP32[i1 + 16 >> 2] | 0) == 288) {
+  i7 = HEAP32[i1 + 24 >> 2] | 0;
+  _luaX_next(i1);
+  i5 = _luaK_stringK(HEAP32[i5 >> 2] | 0, i7) | 0;
+  HEAP32[i3 + 16 >> 2] = -1;
+  HEAP32[i3 + 20 >> 2] = -1;
+  HEAP32[i3 >> 2] = 4;
+  HEAP32[i3 + 8 >> 2] = i5;
+  _luaK_indexed(i4, i6, i3);
+  STACKTOP = i2;
+  return;
+ } else {
+  _error_expected(i1, 288);
+ }
+}
+function _luaK_exp2anyregup(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0;
+ i2 = STACKTOP;
+ if ((HEAP32[i3 >> 2] | 0) == 8 ? (HEAP32[i3 + 16 >> 2] | 0) == (HEAP32[i3 + 20 >> 2] | 0) : 0) {
+  STACKTOP = i2;
+  return;
+ }
+ _luaK_dischargevars(i1, i3);
+ if ((HEAP32[i3 >> 2] | 0) == 6) {
+  i4 = HEAP32[i3 + 8 >> 2] | 0;
+  if ((HEAP32[i3 + 16 >> 2] | 0) == (HEAP32[i3 + 20 >> 2] | 0)) {
+   STACKTOP = i2;
+   return;
+  }
+  if ((i4 | 0) >= (HEAPU8[i1 + 46 | 0] | 0 | 0)) {
+   _exp2reg(i1, i3, i4);
+   STACKTOP = i2;
+   return;
+  }
+ }
+ _luaK_exp2nextreg(i1, i3);
+ STACKTOP = i2;
+ return;
+}
+function _lua_settop(i3, i5) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i4 = 0;
+ i1 = STACKTOP;
+ if (!((i5 | 0) > -1)) {
+  i4 = i3 + 8 | 0;
+  HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + (i5 + 1 << 4);
+  STACKTOP = i1;
+  return;
+ }
+ i2 = i3 + 8 | 0;
+ i4 = HEAP32[i2 >> 2] | 0;
+ i3 = (HEAP32[HEAP32[i3 + 16 >> 2] >> 2] | 0) + (i5 + 1 << 4) | 0;
+ if (i4 >>> 0 < i3 >>> 0) {
+  while (1) {
+   i5 = i4 + 16 | 0;
+   HEAP32[i4 + 8 >> 2] = 0;
+   if (i5 >>> 0 < i3 >>> 0) {
+    i4 = i5;
+   } else {
+    break;
+   }
+  }
+  HEAP32[i2 >> 2] = i5;
+ }
+ HEAP32[i2 >> 2] = i3;
+ STACKTOP = i1;
+ return;
+}
+function _luaL_fileresult(i1, i6, i5) {
+ i1 = i1 | 0;
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ i3 = HEAP32[(___errno_location() | 0) >> 2] | 0;
+ if ((i6 | 0) != 0) {
+  _lua_pushboolean(i1, 1);
+  i6 = 1;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ _lua_pushnil(i1);
+ i6 = _strerror(i3 | 0) | 0;
+ if ((i5 | 0) == 0) {
+  _lua_pushstring(i1, i6) | 0;
+ } else {
+  HEAP32[i4 >> 2] = i5;
+  HEAP32[i4 + 4 >> 2] = i6;
+  _lua_pushfstring(i1, 1176, i4) | 0;
+ }
+ _lua_pushinteger(i1, i3);
+ i6 = 3;
+ STACKTOP = i2;
+ return i6 | 0;
+}
+function _luaL_pushmodule(i1, i4, i5) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ _luaL_findtable(i1, -1001e3, 1432, 1) | 0;
+ _lua_getfield(i1, -1, i4);
+ if ((_lua_type(i1, -1) | 0) == 5) {
+  _lua_remove(i1, -2);
+  STACKTOP = i2;
+  return;
+ }
+ _lua_settop(i1, -2);
+ _lua_rawgeti(i1, -1001e3, 2);
+ if ((_luaL_findtable(i1, 0, i4, i5) | 0) != 0) {
+  HEAP32[i3 >> 2] = i4;
+  _luaL_error(i1, 1440, i3) | 0;
+ }
+ _lua_pushvalue(i1, -1);
+ _lua_setfield(i1, -3, i4);
+ _lua_remove(i1, -2);
+ STACKTOP = i2;
+ return;
+}
+function _b_replace(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i6 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = _luaL_checkunsigned(i1, 1) | 0;
+ i5 = _luaL_checkunsigned(i1, 2) | 0;
+ i4 = _luaL_checkinteger(i1, 3) | 0;
+ i2 = _luaL_optinteger(i1, 4, 1) | 0;
+ if (!((i4 | 0) > -1)) {
+  _luaL_argerror(i1, 3, 10440) | 0;
+ }
+ if ((i2 | 0) <= 0) {
+  _luaL_argerror(i1, 4, 10472) | 0;
+ }
+ if ((i2 + i4 | 0) > 32) {
+  _luaL_error(i1, 10496, i6) | 0;
+ }
+ i2 = ~(-2 << i2 + -1);
+ _lua_pushunsigned(i1, i3 & ~(i2 << i4) | (i5 & i2) << i4);
+ STACKTOP = i6;
+ return 1;
+}
+function _luaT_gettmbyobj(i1, i5, i3) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i5 + 8 >> 2] & 15;
+ if ((i4 | 0) == 5) {
+  i4 = HEAP32[(HEAP32[i5 >> 2] | 0) + 8 >> 2] | 0;
+ } else if ((i4 | 0) == 7) {
+  i4 = HEAP32[(HEAP32[i5 >> 2] | 0) + 8 >> 2] | 0;
+ } else {
+  i4 = HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + (i4 << 2) + 252 >> 2] | 0;
+ }
+ if ((i4 | 0) == 0) {
+  i5 = 5192;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ i5 = _luaH_getstr(i4, HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + (i3 << 2) + 184 >> 2] | 0) | 0;
+ STACKTOP = i2;
+ return i5 | 0;
+}
+function _luaS_eqstr(i2, i3) {
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i4 = 0;
+ i1 = STACKTOP;
+ i4 = HEAP8[i2 + 4 | 0] | 0;
+ do {
+  if (i4 << 24 >> 24 == (HEAP8[i3 + 4 | 0] | 0)) {
+   if (i4 << 24 >> 24 == 4) {
+    i2 = (i2 | 0) == (i3 | 0);
+    break;
+   }
+   i4 = HEAP32[i2 + 12 >> 2] | 0;
+   if ((i2 | 0) != (i3 | 0)) {
+    if ((i4 | 0) == (HEAP32[i3 + 12 >> 2] | 0)) {
+     i2 = (_memcmp(i2 + 16 | 0, i3 + 16 | 0, i4) | 0) == 0;
+    } else {
+     i2 = 0;
+    }
+   } else {
+    i2 = 1;
+   }
+  } else {
+   i2 = 0;
+  }
+ } while (0);
+ STACKTOP = i1;
+ return i2 & 1 | 0;
+}
+function _lua_concat(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0;
+ i2 = STACKTOP;
+ if ((i3 | 0) > 1) {
+  if ((HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+   _luaC_step(i1);
+  }
+  _luaV_concat(i1, i3);
+  STACKTOP = i2;
+  return;
+ } else {
+  if ((i3 | 0) != 0) {
+   STACKTOP = i2;
+   return;
+  }
+  i3 = i1 + 8 | 0;
+  i4 = HEAP32[i3 >> 2] | 0;
+  i1 = _luaS_newlstr(i1, 936, 0) | 0;
+  HEAP32[i4 >> 2] = i1;
+  HEAP32[i4 + 8 >> 2] = HEAPU8[i1 + 4 | 0] | 0 | 64;
+  HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + 16;
+  STACKTOP = i2;
+  return;
+ }
+}
+function _ll_loadfunc(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_getfield(i1, -1001e3, 4184);
+ _lua_getfield(i1, -1, i4);
+ i4 = _lua_touserdata(i1, -1) | 0;
+ _lua_settop(i1, -3);
+ if ((i4 | 0) == 0) {
+  _lua_pushlstring(i1, 4968, 58) | 0;
+  i4 = 1;
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ if ((HEAP8[i3] | 0) == 42) {
+  _lua_pushboolean(i1, 1);
+  i4 = 0;
+  STACKTOP = i2;
+  return i4 | 0;
+ } else {
+  _lua_pushlstring(i1, 4968, 58) | 0;
+  i4 = 2;
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ return 0;
+}
+function _memset(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = i1 + i3 | 0;
+ if ((i3 | 0) >= 20) {
+  i4 = i4 & 255;
+  i7 = i1 & 3;
+  i6 = i4 | i4 << 8 | i4 << 16 | i4 << 24;
+  i5 = i2 & ~3;
+  if (i7) {
+   i7 = i1 + 4 - i7 | 0;
+   while ((i1 | 0) < (i7 | 0)) {
+    HEAP8[i1] = i4;
+    i1 = i1 + 1 | 0;
+   }
+  }
+  while ((i1 | 0) < (i5 | 0)) {
+   HEAP32[i1 >> 2] = i6;
+   i1 = i1 + 4 | 0;
+  }
+ }
+ while ((i1 | 0) < (i2 | 0)) {
+  HEAP8[i1] = i4;
+  i1 = i1 + 1 | 0;
+ }
+ return i1 - i3 | 0;
+}
+function _luaD_growstack(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = HEAP32[i1 + 32 >> 2] | 0;
+ if ((i4 | 0) > 1e6) {
+  _luaD_throw(i1, 6);
+ }
+ i3 = i3 + 5 + ((HEAP32[i1 + 8 >> 2] | 0) - (HEAP32[i1 + 28 >> 2] | 0) >> 4) | 0;
+ i4 = i4 << 1;
+ i4 = (i4 | 0) > 1e6 ? 1e6 : i4;
+ i3 = (i4 | 0) < (i3 | 0) ? i3 : i4;
+ if ((i3 | 0) > 1e6) {
+  _luaD_reallocstack(i1, 1000200);
+  _luaG_runerror(i1, 2224, i2);
+ } else {
+  _luaD_reallocstack(i1, i3);
+  STACKTOP = i2;
+  return;
+ }
+}
+function _luaL_callmeta(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i4 = _lua_absindex(i1, i4) | 0;
+ if ((_lua_getmetatable(i1, i4) | 0) == 0) {
+  i4 = 0;
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ _lua_pushstring(i1, i3) | 0;
+ _lua_rawget(i1, -2);
+ if ((_lua_type(i1, -1) | 0) == 0) {
+  _lua_settop(i1, -3);
+  i4 = 0;
+  STACKTOP = i2;
+  return i4 | 0;
+ } else {
+  _lua_remove(i1, -2);
+  _lua_pushvalue(i1, i4);
+  _lua_callk(i1, 1, 1, 0, 0);
+  i4 = 1;
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ return 0;
+}
+function _luaK_reserveregs(i8, i7) {
+ i8 = i8 | 0;
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i3 = STACKTOP;
+ i2 = i8 + 48 | 0;
+ i6 = HEAP8[i2] | 0;
+ i4 = (i6 & 255) + i7 | 0;
+ i5 = (HEAP32[i8 >> 2] | 0) + 78 | 0;
+ do {
+  if ((i4 | 0) > (HEAPU8[i5] | 0 | 0)) {
+   if ((i4 | 0) > 249) {
+    _luaX_syntaxerror(HEAP32[i8 + 12 >> 2] | 0, 10536);
+   } else {
+    HEAP8[i5] = i4;
+    i1 = HEAP8[i2] | 0;
+    break;
+   }
+  } else {
+   i1 = i6;
+  }
+ } while (0);
+ HEAP8[i2] = (i1 & 255) + i7;
+ STACKTOP = i3;
+ return;
+}
+function _aux_lines(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0;
+ i4 = STACKTOP;
+ i3 = _lua_gettop(i1) | 0;
+ i2 = i3 + -1 | 0;
+ if ((i3 | 0) >= 19) {
+  _luaL_argerror(i1, 17, 3320) | 0;
+ }
+ _lua_pushvalue(i1, 1);
+ _lua_pushinteger(i1, i2);
+ _lua_pushboolean(i1, i5);
+ if ((i3 | 0) >= 2) {
+  i5 = 1;
+  while (1) {
+   i6 = i5 + 1 | 0;
+   _lua_pushvalue(i1, i6);
+   if ((i5 | 0) < (i2 | 0)) {
+    i5 = i6;
+   } else {
+    break;
+   }
+  }
+ }
+ _lua_pushcclosure(i1, 155, i3 + 2 | 0);
+ STACKTOP = i4;
+ return;
+}
+function _memcmp(i2, i4, i3) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i5 = 0, i6 = 0;
+ i1 = STACKTOP;
+ L1 : do {
+  if ((i3 | 0) == 0) {
+   i2 = 0;
+  } else {
+   while (1) {
+    i6 = HEAP8[i2] | 0;
+    i5 = HEAP8[i4] | 0;
+    if (!(i6 << 24 >> 24 == i5 << 24 >> 24)) {
+     break;
+    }
+    i3 = i3 + -1 | 0;
+    if ((i3 | 0) == 0) {
+     i2 = 0;
+     break L1;
+    } else {
+     i2 = i2 + 1 | 0;
+     i4 = i4 + 1 | 0;
+    }
+   }
+   i2 = (i6 & 255) - (i5 & 255) | 0;
+  }
+ } while (0);
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _b_arshift(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i3 = _luaL_checkunsigned(i1, 1) | 0;
+ i4 = _luaL_checkinteger(i1, 2) | 0;
+ if ((i4 | 0) > -1 & (i3 | 0) < 0) {
+  if ((i4 | 0) > 31) {
+   i3 = -1;
+  } else {
+   i3 = i3 >>> i4 | ~(-1 >>> i4);
+  }
+  _lua_pushunsigned(i1, i3);
+  STACKTOP = i2;
+  return 1;
+ }
+ i5 = 0 - i4 | 0;
+ if ((i4 | 0) > 0) {
+  i3 = (i4 | 0) > 31 ? 0 : i3 >>> i4;
+ } else {
+  i3 = (i5 | 0) > 31 ? 0 : i3 << i5;
+ }
+ _lua_pushunsigned(i1, i3);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaL_checkunsigned(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i3;
+ i6 = i3 + 8 | 0;
+ i2 = _lua_tounsignedx(i1, i5, i6) | 0;
+ if ((HEAP32[i6 >> 2] | 0) != 0) {
+  STACKTOP = i3;
+  return i2 | 0;
+ }
+ i7 = _lua_typename(i1, 3) | 0;
+ i6 = _lua_typename(i1, _lua_type(i1, i5) | 0) | 0;
+ HEAP32[i4 >> 2] = i7;
+ HEAP32[i4 + 4 >> 2] = i6;
+ _luaL_argerror(i1, i5, _lua_pushfstring(i1, 1744, i4) | 0) | 0;
+ STACKTOP = i3;
+ return i2 | 0;
+}
+function _luaB_loadfile(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i1 = STACKTOP;
+ i4 = _luaL_optlstring(i2, 1, 0, 0) | 0;
+ i5 = _luaL_optlstring(i2, 2, 0, 0) | 0;
+ i3 = (_lua_type(i2, 3) | 0) != -1;
+ i6 = i3 ? 3 : 0;
+ if ((_luaL_loadfilex(i2, i4, i5) | 0) == 0) {
+  if (i3 ? (_lua_pushvalue(i2, i6), (_lua_setupvalue(i2, -2, 1) | 0) == 0) : 0) {
+   _lua_settop(i2, -2);
+   i2 = 1;
+  } else {
+   i2 = 1;
+  }
+ } else {
+  _lua_pushnil(i2);
+  _lua_insert(i2, -2);
+  i2 = 2;
+ }
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _luaL_checkinteger(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i3;
+ i6 = i3 + 8 | 0;
+ i2 = _lua_tointegerx(i1, i5, i6) | 0;
+ if ((HEAP32[i6 >> 2] | 0) != 0) {
+  STACKTOP = i3;
+  return i2 | 0;
+ }
+ i7 = _lua_typename(i1, 3) | 0;
+ i6 = _lua_typename(i1, _lua_type(i1, i5) | 0) | 0;
+ HEAP32[i4 >> 2] = i7;
+ HEAP32[i4 + 4 >> 2] = i6;
+ _luaL_argerror(i1, i5, _lua_pushfstring(i1, 1744, i4) | 0) | 0;
+ STACKTOP = i3;
+ return i2 | 0;
+}
+function _luaB_select(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i3 = STACKTOP;
+ i2 = _lua_gettop(i1) | 0;
+ if ((_lua_type(i1, 1) | 0) == 4 ? (HEAP8[_lua_tolstring(i1, 1, 0) | 0] | 0) == 35 : 0) {
+  _lua_pushinteger(i1, i2 + -1 | 0);
+  i4 = 1;
+  STACKTOP = i3;
+  return i4 | 0;
+ }
+ i4 = _luaL_checkinteger(i1, 1) | 0;
+ if ((i4 | 0) < 0) {
+  i4 = i4 + i2 | 0;
+ } else {
+  i4 = (i4 | 0) > (i2 | 0) ? i2 : i4;
+ }
+ if ((i4 | 0) <= 0) {
+  _luaL_argerror(i1, 1, 9760) | 0;
+ }
+ i4 = i2 - i4 | 0;
+ STACKTOP = i3;
+ return i4 | 0;
+}
+function _luaX_next(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ HEAP32[i1 + 8 >> 2] = HEAP32[i1 + 4 >> 2];
+ i3 = i1 + 32 | 0;
+ if ((HEAP32[i3 >> 2] | 0) == 286) {
+  HEAP32[i1 + 16 >> 2] = _llex(i1, i1 + 24 | 0) | 0;
+  STACKTOP = i2;
+  return;
+ } else {
+  i1 = i1 + 16 | 0;
+  HEAP32[i1 + 0 >> 2] = HEAP32[i3 + 0 >> 2];
+  HEAP32[i1 + 4 >> 2] = HEAP32[i3 + 4 >> 2];
+  HEAP32[i1 + 8 >> 2] = HEAP32[i3 + 8 >> 2];
+  HEAP32[i1 + 12 >> 2] = HEAP32[i3 + 12 >> 2];
+  HEAP32[i3 >> 2] = 286;
+  STACKTOP = i2;
+  return;
+ }
+}
+function _lua_setglobal(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i3 = STACKTOP;
+ i5 = _luaH_getint(HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 40 >> 2] | 0, 2) | 0;
+ i4 = i1 + 8 | 0;
+ i6 = HEAP32[i4 >> 2] | 0;
+ HEAP32[i4 >> 2] = i6 + 16;
+ i2 = _luaS_new(i1, i2) | 0;
+ HEAP32[i6 >> 2] = i2;
+ HEAP32[i6 + 8 >> 2] = HEAPU8[i2 + 4 | 0] | 0 | 64;
+ i2 = HEAP32[i4 >> 2] | 0;
+ _luaV_settable(i1, i5, i2 + -16 | 0, i2 + -32 | 0);
+ HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + -32;
+ STACKTOP = i3;
+ return;
+}
+function _luaL_checknumber(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var d2 = 0.0, i3 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i3;
+ i6 = i3 + 8 | 0;
+ d2 = +_lua_tonumberx(i1, i5, i6);
+ if ((HEAP32[i6 >> 2] | 0) != 0) {
+  STACKTOP = i3;
+  return +d2;
+ }
+ i7 = _lua_typename(i1, 3) | 0;
+ i6 = _lua_typename(i1, _lua_type(i1, i5) | 0) | 0;
+ HEAP32[i4 >> 2] = i7;
+ HEAP32[i4 + 4 >> 2] = i6;
+ _luaL_argerror(i1, i5, _lua_pushfstring(i1, 1744, i4) | 0) | 0;
+ STACKTOP = i3;
+ return +d2;
+}
+function _luaZ_fill(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ i3 = FUNCTION_TABLE_iiii[HEAP32[i1 + 8 >> 2] & 3](HEAP32[i1 + 16 >> 2] | 0, HEAP32[i1 + 12 >> 2] | 0, i4) | 0;
+ if ((i3 | 0) == 0) {
+  i4 = -1;
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ i4 = HEAP32[i4 >> 2] | 0;
+ if ((i4 | 0) == 0) {
+  i4 = -1;
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ HEAP32[i1 >> 2] = i4 + -1;
+ HEAP32[i1 + 4 >> 2] = i3 + 1;
+ i4 = HEAPU8[i3] | 0;
+ STACKTOP = i2;
+ return i4 | 0;
+}
+function _lua_createtable(i1, i3, i4) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ if ((HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+  _luaC_step(i1);
+ }
+ i5 = _luaH_new(i1) | 0;
+ i6 = i1 + 8 | 0;
+ i7 = HEAP32[i6 >> 2] | 0;
+ HEAP32[i7 >> 2] = i5;
+ HEAP32[i7 + 8 >> 2] = 69;
+ HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + 16;
+ if (!((i3 | 0) > 0 | (i4 | 0) > 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ _luaH_resize(i1, i5, i3, i4);
+ STACKTOP = i2;
+ return;
+}
+function _generic_reader(i1, i3, i2) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ _luaL_checkstack(i1, 2, 9888);
+ _lua_pushvalue(i1, 1);
+ _lua_callk(i1, 0, 1, 0, 0);
+ if ((_lua_type(i1, -1) | 0) == 0) {
+  _lua_settop(i1, -2);
+  HEAP32[i2 >> 2] = 0;
+  i2 = 0;
+  STACKTOP = i3;
+  return i2 | 0;
+ }
+ if ((_lua_isstring(i1, -1) | 0) == 0) {
+  _luaL_error(i1, 9920, i3) | 0;
+ }
+ _lua_replace(i1, 5);
+ i2 = _lua_tolstring(i1, 5, i2) | 0;
+ STACKTOP = i3;
+ return i2 | 0;
+}
+function _luaZ_openspace(i5, i1, i6) {
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ i6 = i6 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i4 = i1 + 8 | 0;
+ i3 = HEAP32[i4 >> 2] | 0;
+ if (!(i3 >>> 0 < i6 >>> 0)) {
+  i6 = HEAP32[i1 >> 2] | 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ i6 = i6 >>> 0 < 32 ? 32 : i6;
+ if ((i6 + 1 | 0) >>> 0 > 4294967293) {
+  _luaM_toobig(i5);
+ }
+ i5 = _luaM_realloc_(i5, HEAP32[i1 >> 2] | 0, i3, i6) | 0;
+ HEAP32[i1 >> 2] = i5;
+ HEAP32[i4 >> 2] = i6;
+ i6 = i5;
+ STACKTOP = i2;
+ return i6 | 0;
+}
+function _luaH_getstr(i4, i3) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i2 = 0;
+ i2 = STACKTOP;
+ i4 = (HEAP32[i4 + 16 >> 2] | 0) + (((1 << (HEAPU8[i4 + 7 | 0] | 0)) + -1 & HEAP32[i3 + 8 >> 2]) << 5) | 0;
+ while (1) {
+  if ((HEAP32[i4 + 24 >> 2] | 0) == 68 ? (HEAP32[i4 + 16 >> 2] | 0) == (i3 | 0) : 0) {
+   break;
+  }
+  i4 = HEAP32[i4 + 28 >> 2] | 0;
+  if ((i4 | 0) == 0) {
+   i3 = 5192;
+   i1 = 6;
+   break;
+  }
+ }
+ if ((i1 | 0) == 6) {
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ STACKTOP = i2;
+ return i4 | 0;
+}
+function _b_extract(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i5 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = _luaL_checkunsigned(i1, 1) | 0;
+ i3 = _luaL_checkinteger(i1, 2) | 0;
+ i4 = _luaL_optinteger(i1, 3, 1) | 0;
+ if (!((i3 | 0) > -1)) {
+  _luaL_argerror(i1, 2, 10440) | 0;
+ }
+ if ((i4 | 0) <= 0) {
+  _luaL_argerror(i1, 3, 10472) | 0;
+ }
+ if ((i4 + i3 | 0) > 32) {
+  _luaL_error(i1, 10496, i5) | 0;
+ }
+ _lua_pushunsigned(i1, i2 >>> i3 & ~(-2 << i4 + -1));
+ STACKTOP = i5;
+ return 1;
+}
+function _luaL_checklstring(i1, i4, i5) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i6 = 0, i7 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ i5 = _lua_tolstring(i1, i4, i5) | 0;
+ if ((i5 | 0) != 0) {
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ i7 = _lua_typename(i1, 4) | 0;
+ i6 = _lua_typename(i1, _lua_type(i1, i4) | 0) | 0;
+ HEAP32[i3 >> 2] = i7;
+ HEAP32[i3 + 4 >> 2] = i6;
+ _luaL_argerror(i1, i4, _lua_pushfstring(i1, 1744, i3) | 0) | 0;
+ STACKTOP = i2;
+ return i5 | 0;
+}
+function _db_traceback(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ if ((_lua_type(i1, 1) | 0) == 8) {
+  i3 = _lua_tothread(i1, 1) | 0;
+  i4 = 1;
+ } else {
+  i3 = i1;
+  i4 = 0;
+ }
+ i5 = i4 + 1 | 0;
+ i6 = _lua_tolstring(i1, i5, 0) | 0;
+ if ((i6 | 0) == 0 ? (_lua_type(i1, i5) | 0) >= 1 : 0) {
+  _lua_pushvalue(i1, i5);
+  STACKTOP = i2;
+  return 1;
+ }
+ _luaL_traceback(i1, i3, i6, _luaL_optinteger(i1, i4 | 2, (i3 | 0) == (i1 | 0) | 0) | 0);
+ STACKTOP = i2;
+ return 1;
+}
+function _f_setvbuf(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = _luaL_checkudata(i1, 1, 2832) | 0;
+ if ((HEAP32[i3 + 4 >> 2] | 0) == 0) {
+  _luaL_error(i1, 3080, i2) | 0;
+ }
+ i5 = HEAP32[i3 >> 2] | 0;
+ i4 = _luaL_checkoption(i1, 2, 0, 3128) | 0;
+ i3 = _luaL_optinteger(i1, 3, 1024) | 0;
+ i3 = _luaL_fileresult(i1, (_setvbuf(i5 | 0, 0, HEAP32[3112 + (i4 << 2) >> 2] | 0, i3 | 0) | 0) == 0 | 0, 0) | 0;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _luaU_dump(i3, i1, i4, i2, i5) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ var i6 = 0, i7 = 0, i8 = 0;
+ i6 = STACKTOP;
+ STACKTOP = STACKTOP + 48 | 0;
+ i8 = i6 + 20 | 0;
+ i7 = i6;
+ HEAP32[i7 >> 2] = i3;
+ HEAP32[i7 + 4 >> 2] = i4;
+ HEAP32[i7 + 8 >> 2] = i2;
+ HEAP32[i7 + 12 >> 2] = i5;
+ i5 = i7 + 16 | 0;
+ _luaU_header(i8);
+ HEAP32[i5 >> 2] = FUNCTION_TABLE_iiiii[i4 & 3](i3, i8, 18, i2) | 0;
+ _DumpFunction(i1, i7);
+ STACKTOP = i6;
+ return HEAP32[i5 >> 2] | 0;
+}
+function _luaB_setmetatable(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = _lua_type(i1, 2) | 0;
+ _luaL_checktype(i1, 1, 5);
+ if (!((i3 | 0) == 0 | (i3 | 0) == 5)) {
+  _luaL_argerror(i1, 2, 9680) | 0;
+ }
+ if ((_luaL_getmetafield(i1, 1, 9704) | 0) == 0) {
+  _lua_settop(i1, 2);
+  _lua_setmetatable(i1, 1) | 0;
+  i3 = 1;
+  STACKTOP = i2;
+  return i3 | 0;
+ } else {
+  i3 = _luaL_error(i1, 9720, i2) | 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ return 0;
+}
+function _getF(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ i3 = STACKTOP;
+ i4 = HEAP32[i2 >> 2] | 0;
+ if ((i4 | 0) > 0) {
+  HEAP32[i1 >> 2] = i4;
+  HEAP32[i2 >> 2] = 0;
+  i4 = i2 + 8 | 0;
+  STACKTOP = i3;
+  return i4 | 0;
+ }
+ i4 = i2 + 4 | 0;
+ if ((_feof(HEAP32[i4 >> 2] | 0) | 0) != 0) {
+  i4 = 0;
+  STACKTOP = i3;
+  return i4 | 0;
+ }
+ i2 = i2 + 8 | 0;
+ HEAP32[i1 >> 2] = _fread(i2 | 0, 1, 1024, HEAP32[i4 >> 2] | 0) | 0;
+ i4 = i2;
+ STACKTOP = i3;
+ return i4 | 0;
+}
+function _luaL_where(i1, i6) {
+ i1 = i1 | 0;
+ i6 = i6 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 112 | 0;
+ i3 = i4;
+ i2 = i4 + 8 | 0;
+ if ((_lua_getstack(i1, i6, i2) | 0) != 0 ? (_lua_getinfo(i1, 1152, i2) | 0, i5 = HEAP32[i2 + 20 >> 2] | 0, (i5 | 0) > 0) : 0) {
+  HEAP32[i3 >> 2] = i2 + 36;
+  HEAP32[i3 + 4 >> 2] = i5;
+  _lua_pushfstring(i1, 1160, i3) | 0;
+  STACKTOP = i4;
+  return;
+ }
+ _lua_pushlstring(i1, 1168, 0) | 0;
+ STACKTOP = i4;
+ return;
+}
+function _hookf(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_getsubtable(i1, -1001e3, 11584) | 0;
+ _lua_pushthread(i1) | 0;
+ _lua_rawget(i1, -2);
+ if ((_lua_type(i1, -1) | 0) != 6) {
+  STACKTOP = i2;
+  return;
+ }
+ _lua_pushstring(i1, HEAP32[11608 + (HEAP32[i3 >> 2] << 2) >> 2] | 0) | 0;
+ i3 = HEAP32[i3 + 20 >> 2] | 0;
+ if ((i3 | 0) > -1) {
+  _lua_pushinteger(i1, i3);
+ } else {
+  _lua_pushnil(i1);
+ }
+ _lua_callk(i1, 2, 0, 0, 0);
+ STACKTOP = i2;
+ return;
+}
+function _luaV_tonumber(i5, i2) {
+ i5 = i5 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i1;
+ i4 = HEAP32[i5 + 8 >> 2] | 0;
+ if ((i4 | 0) != 3) {
+  if ((i4 & 15 | 0) == 4 ? (i5 = HEAP32[i5 >> 2] | 0, (_luaO_str2d(i5 + 16 | 0, HEAP32[i5 + 12 >> 2] | 0, i3) | 0) != 0) : 0) {
+   HEAPF64[i2 >> 3] = +HEAPF64[i3 >> 3];
+   HEAP32[i2 + 8 >> 2] = 3;
+  } else {
+   i2 = 0;
+  }
+ } else {
+  i2 = i5;
+ }
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _luaO_arith(i3, d1, d2) {
+ i3 = i3 | 0;
+ d1 = +d1;
+ d2 = +d2;
+ switch (i3 | 0) {
+ case 4:
+  {
+   d1 = d1 - +Math_floor(+(d1 / d2)) * d2;
+   break;
+  }
+ case 6:
+  {
+   d1 = -d1;
+   break;
+  }
+ case 0:
+  {
+   d1 = d1 + d2;
+   break;
+  }
+ case 1:
+  {
+   d1 = d1 - d2;
+   break;
+  }
+ case 5:
+  {
+   d1 = +Math_pow(+d1, +d2);
+   break;
+  }
+ case 3:
+  {
+   d1 = d1 / d2;
+   break;
+  }
+ case 2:
+  {
+   d1 = d1 * d2;
+   break;
+  }
+ default:
+  {
+   d1 = 0.0;
+  }
+ }
+ return +d1;
+}
+function _luaB_coresume(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _lua_tothread(i1, 1) | 0;
+ if ((i3 | 0) == 0) {
+  _luaL_argerror(i1, 1, 10856) | 0;
+ }
+ i3 = _auxresume(i1, i3, (_lua_gettop(i1) | 0) + -1 | 0) | 0;
+ if ((i3 | 0) < 0) {
+  _lua_pushboolean(i1, 0);
+  _lua_insert(i1, -2);
+  i3 = 2;
+  STACKTOP = i2;
+  return i3 | 0;
+ } else {
+  _lua_pushboolean(i1, 1);
+  _lua_insert(i1, ~i3);
+  i3 = i3 + 1 | 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ return 0;
+}
+function _pairsmeta(i1, i5, i4, i3) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((_luaL_getmetafield(i1, 1, i5) | 0) != 0) {
+  _lua_pushvalue(i1, 1);
+  _lua_callk(i1, 1, 3, 0, 0);
+  STACKTOP = i2;
+  return;
+ }
+ _luaL_checktype(i1, 1, 5);
+ _lua_pushcclosure(i1, i3, 0);
+ _lua_pushvalue(i1, 1);
+ if ((i4 | 0) == 0) {
+  _lua_pushnil(i1);
+  STACKTOP = i2;
+  return;
+ } else {
+  _lua_pushinteger(i1, 0);
+  STACKTOP = i2;
+  return;
+ }
+}
+function _io_close(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ if ((_lua_type(i1, 1) | 0) == -1) {
+  _lua_getfield(i1, -1001e3, 2800);
+ }
+ if ((HEAP32[(_luaL_checkudata(i1, 1, 2832) | 0) + 4 >> 2] | 0) == 0) {
+  _luaL_error(i1, 3080, i2) | 0;
+ }
+ i4 = (_luaL_checkudata(i1, 1, 2832) | 0) + 4 | 0;
+ i3 = HEAP32[i4 >> 2] | 0;
+ HEAP32[i4 >> 2] = 0;
+ i1 = FUNCTION_TABLE_ii[i3 & 255](i1) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _pack(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _lua_gettop(i1) | 0;
+ _lua_createtable(i1, i3, 1);
+ _lua_pushinteger(i1, i3);
+ _lua_setfield(i1, -2, 8312);
+ if ((i3 | 0) <= 0) {
+  STACKTOP = i2;
+  return 1;
+ }
+ _lua_pushvalue(i1, 1);
+ _lua_rawseti(i1, -2, 1);
+ _lua_replace(i1, 1);
+ if ((i3 | 0) <= 1) {
+  STACKTOP = i2;
+  return 1;
+ }
+ do {
+  _lua_rawseti(i1, 1, i3);
+  i3 = i3 + -1 | 0;
+ } while ((i3 | 0) > 1);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaL_execresult(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((i3 | 0) == -1) {
+  i3 = HEAP32[(___errno_location() | 0) >> 2] | 0;
+  _lua_pushnil(i1);
+  _lua_pushstring(i1, _strerror(i3 | 0) | 0) | 0;
+  _lua_pushinteger(i1, i3);
+  STACKTOP = i2;
+  return 3;
+ } else if ((i3 | 0) == 0) {
+  _lua_pushboolean(i1, 1);
+ } else {
+  _lua_pushnil(i1);
+ }
+ _lua_pushstring(i1, 1184) | 0;
+ _lua_pushinteger(i1, i3);
+ STACKTOP = i2;
+ return 3;
+}
+function _lua_getglobal(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i3 = STACKTOP;
+ i4 = _luaH_getint(HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 40 >> 2] | 0, 2) | 0;
+ i5 = i1 + 8 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i5 >> 2] = i6 + 16;
+ i2 = _luaS_new(i1, i2) | 0;
+ HEAP32[i6 >> 2] = i2;
+ HEAP32[i6 + 8 >> 2] = HEAPU8[i2 + 4 | 0] | 0 | 64;
+ i2 = (HEAP32[i5 >> 2] | 0) + -16 | 0;
+ _luaV_gettable(i1, i4, i2, i2);
+ STACKTOP = i3;
+ return;
+}
+function _luaL_checktype(i1, i5, i4) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ if ((_lua_type(i1, i5) | 0) == (i4 | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ i6 = _lua_typename(i1, i4) | 0;
+ i4 = _lua_typename(i1, _lua_type(i1, i5) | 0) | 0;
+ HEAP32[i3 >> 2] = i6;
+ HEAP32[i3 + 4 >> 2] = i4;
+ _luaL_argerror(i1, i5, _lua_pushfstring(i1, 1744, i3) | 0) | 0;
+ STACKTOP = i2;
+ return;
+}
+function _luaC_newobj(i7, i4, i6, i5, i1) {
+ i7 = i7 | 0;
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = HEAP32[i7 + 12 >> 2] | 0;
+ i7 = _luaM_realloc_(i7, 0, i4 & 15, i6) | 0;
+ i6 = i7 + i1 | 0;
+ i5 = (i5 | 0) == 0 ? i3 + 68 | 0 : i5;
+ HEAP8[i7 + (i1 + 5) | 0] = HEAP8[i3 + 60 | 0] & 3;
+ HEAP8[i7 + (i1 + 4) | 0] = i4;
+ HEAP32[i6 >> 2] = HEAP32[i5 >> 2];
+ HEAP32[i5 >> 2] = i6;
+ STACKTOP = i2;
+ return i6 | 0;
+}
+function _luaL_requiref(i1, i3, i5, i4) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushcclosure(i1, i5, 0);
+ _lua_pushstring(i1, i3) | 0;
+ _lua_callk(i1, 1, 1, 0, 0);
+ _luaL_getsubtable(i1, -1001e3, 1432) | 0;
+ _lua_pushvalue(i1, -2);
+ _lua_setfield(i1, -2, i3);
+ _lua_settop(i1, -2);
+ if ((i4 | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ _lua_pushvalue(i1, -1);
+ _lua_setglobal(i1, i3);
+ STACKTOP = i2;
+ return;
+}
+function _luaG_ordererror(i1, i3, i4) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = HEAP32[8528 + ((HEAP32[i3 + 8 >> 2] & 15) + 1 << 2) >> 2] | 0;
+ i4 = HEAP32[8528 + ((HEAP32[i4 + 8 >> 2] & 15) + 1 << 2) >> 2] | 0;
+ if ((i3 | 0) == (i4 | 0)) {
+  HEAP32[i2 >> 2] = i3;
+  _luaG_runerror(i1, 1952, i2);
+ } else {
+  HEAP32[i2 >> 2] = i3;
+  HEAP32[i2 + 4 >> 2] = i4;
+  _luaG_runerror(i1, 1992, i2);
+ }
+}
+function _io_popen(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = _luaL_checklstring(i1, 1, 0) | 0;
+ _luaL_optlstring(i1, 2, 3480, 0) | 0;
+ i5 = _lua_newuserdata(i1, 8) | 0;
+ i4 = i5 + 4 | 0;
+ HEAP32[i4 >> 2] = 0;
+ _luaL_setmetatable(i1, 2832);
+ _luaL_error(i1, 3488, i2) | 0;
+ HEAP32[i5 >> 2] = 0;
+ HEAP32[i4 >> 2] = 157;
+ i1 = _luaL_fileresult(i1, 0, i3) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _sort_comp(i1, i3, i4) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((_lua_type(i1, 2) | 0) == 0) {
+  i4 = _lua_compare(i1, i3, i4, 1) | 0;
+  STACKTOP = i2;
+  return i4 | 0;
+ } else {
+  _lua_pushvalue(i1, 2);
+  _lua_pushvalue(i1, i3 + -1 | 0);
+  _lua_pushvalue(i1, i4 + -2 | 0);
+  _lua_callk(i1, 2, 1, 0, 0);
+  i4 = _lua_toboolean(i1, -1) | 0;
+  _lua_settop(i1, -2);
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ return 0;
+}
+function _db_upvalueid(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 112 | 0;
+ i4 = i3;
+ i2 = _luaL_checkinteger(i1, 2) | 0;
+ _luaL_checktype(i1, 1, 6);
+ _lua_pushvalue(i1, 1);
+ _lua_getinfo(i1, 11728, i4) | 0;
+ if (!((i2 | 0) > 0 ? (i2 | 0) <= (HEAPU8[i4 + 32 | 0] | 0 | 0) : 0)) {
+  _luaL_argerror(i1, 2, 11736) | 0;
+ }
+ _lua_pushlightuserdata(i1, _lua_upvalueid(i1, 1, i2) | 0);
+ STACKTOP = i3;
+ return 1;
+}
+function _luaL_getmetafield(i2, i4, i3) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i1 = 0;
+ i1 = STACKTOP;
+ do {
+  if ((_lua_getmetatable(i2, i4) | 0) != 0) {
+   _lua_pushstring(i2, i3) | 0;
+   _lua_rawget(i2, -2);
+   if ((_lua_type(i2, -1) | 0) == 0) {
+    _lua_settop(i2, -3);
+    i2 = 0;
+    break;
+   } else {
+    _lua_remove(i2, -2);
+    i2 = 1;
+    break;
+   }
+  } else {
+   i2 = 0;
+  }
+ } while (0);
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _luaF_freeupval(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ if ((HEAP32[i3 + 8 >> 2] | 0) == (i3 + 16 | 0)) {
+  _luaM_realloc_(i1, i3, 32, 0) | 0;
+  STACKTOP = i2;
+  return;
+ }
+ i4 = i3 + 16 | 0;
+ i5 = i4 + 4 | 0;
+ HEAP32[(HEAP32[i5 >> 2] | 0) + 16 >> 2] = HEAP32[i4 >> 2];
+ HEAP32[(HEAP32[i4 >> 2] | 0) + 20 >> 2] = HEAP32[i5 >> 2];
+ _luaM_realloc_(i1, i3, 32, 0) | 0;
+ STACKTOP = i2;
+ return;
+}
+function _luaL_addvalue(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ i5 = HEAP32[i1 + 12 >> 2] | 0;
+ i3 = _lua_tolstring(i5, -1, i4) | 0;
+ i6 = i1 + 16 | 0;
+ if ((HEAP32[i1 >> 2] | 0) != (i6 | 0)) {
+  _lua_insert(i5, -2);
+ }
+ _luaL_addlstring(i1, i3, HEAP32[i4 >> 2] | 0);
+ _lua_remove(i5, (HEAP32[i1 >> 2] | 0) != (i6 | 0) ? -2 : -1);
+ STACKTOP = i2;
+ return;
+}
+function _escerror(i1, i4, i3, i2) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i5 = 0, i6 = 0;
+ HEAP32[(HEAP32[i1 + 60 >> 2] | 0) + 4 >> 2] = 0;
+ _save(i1, 92);
+ L1 : do {
+  if ((i3 | 0) > 0) {
+   i5 = 0;
+   do {
+    i6 = HEAP32[i4 + (i5 << 2) >> 2] | 0;
+    if ((i6 | 0) == -1) {
+     break L1;
+    }
+    _save(i1, i6);
+    i5 = i5 + 1 | 0;
+   } while ((i5 | 0) < (i3 | 0));
+  }
+ } while (0);
+ _lexerror(i1, i2, 289);
+}
+function _pushglobalfuncname(i1, i4) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _lua_gettop(i1) | 0;
+ _lua_getinfo(i1, 1768, i4) | 0;
+ _lua_rawgeti(i1, -1001e3, 2);
+ i4 = i3 + 1 | 0;
+ if ((_findfield(i1, i4, 2) | 0) == 0) {
+  _lua_settop(i1, i3);
+  i4 = 0;
+  STACKTOP = i2;
+  return i4 | 0;
+ } else {
+  _lua_copy(i1, -1, i4);
+  _lua_settop(i1, -3);
+  i4 = 1;
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ return 0;
+}
+function copyTempDouble(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+ HEAP8[tempDoublePtr + 4 | 0] = HEAP8[i1 + 4 | 0];
+ HEAP8[tempDoublePtr + 5 | 0] = HEAP8[i1 + 5 | 0];
+ HEAP8[tempDoublePtr + 6 | 0] = HEAP8[i1 + 6 | 0];
+ HEAP8[tempDoublePtr + 7 | 0] = HEAP8[i1 + 7 | 0];
+}
+function _lua_pushlstring(i1, i3, i4) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+  _luaC_step(i1);
+ }
+ i4 = _luaS_newlstr(i1, i3, i4) | 0;
+ i3 = i1 + 8 | 0;
+ i1 = HEAP32[i3 >> 2] | 0;
+ HEAP32[i1 >> 2] = i4;
+ HEAP32[i1 + 8 >> 2] = HEAPU8[i4 + 4 | 0] | 0 | 64;
+ HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + 16;
+ STACKTOP = i2;
+ return i4 + 16 | 0;
+}
+function _ll_searchpath(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i5 = _luaL_checklstring(i1, 1, 0) | 0;
+ i4 = _luaL_checklstring(i1, 2, 0) | 0;
+ i3 = _luaL_optlstring(i1, 3, 4936, 0) | 0;
+ if ((_searchpath(i1, i5, i4, i3, _luaL_optlstring(i1, 4, 4848, 0) | 0) | 0) != 0) {
+  i5 = 1;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ _lua_pushnil(i1);
+ _lua_insert(i1, -2);
+ i5 = 2;
+ STACKTOP = i2;
+ return i5 | 0;
+}
+function _math_log(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, d3 = 0.0, d4 = 0.0;
+ i2 = STACKTOP;
+ d3 = +_luaL_checknumber(i1, 1);
+ do {
+  if ((_lua_type(i1, 2) | 0) >= 1) {
+   d4 = +_luaL_checknumber(i1, 2);
+   if (d4 == 10.0) {
+    d3 = +_log10(+d3);
+    break;
+   } else {
+    d3 = +Math_log(+d3) / +Math_log(+d4);
+    break;
+   }
+  } else {
+   d3 = +Math_log(+d3);
+  }
+ } while (0);
+ _lua_pushnumber(i1, d3);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaT_init(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i3 = i1 + 12 | 0;
+ i4 = 0;
+ do {
+  i5 = _luaS_new(i1, HEAP32[8576 + (i4 << 2) >> 2] | 0) | 0;
+  HEAP32[(HEAP32[i3 >> 2] | 0) + (i4 << 2) + 184 >> 2] = i5;
+  i5 = (HEAP32[(HEAP32[i3 >> 2] | 0) + (i4 << 2) + 184 >> 2] | 0) + 5 | 0;
+  HEAP8[i5] = HEAPU8[i5] | 0 | 32;
+  i4 = i4 + 1 | 0;
+ } while ((i4 | 0) != 17);
+ STACKTOP = i2;
+ return;
+}
+function _f_gc(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i3 = _luaL_checkudata(i1, 1, 2832) | 0;
+ if ((HEAP32[i3 + 4 >> 2] | 0) == 0) {
+  STACKTOP = i2;
+  return 0;
+ }
+ if ((HEAP32[i3 >> 2] | 0) == 0) {
+  STACKTOP = i2;
+  return 0;
+ }
+ i4 = (_luaL_checkudata(i1, 1, 2832) | 0) + 4 | 0;
+ i3 = HEAP32[i4 >> 2] | 0;
+ HEAP32[i4 >> 2] = 0;
+ FUNCTION_TABLE_ii[i3 & 255](i1) | 0;
+ STACKTOP = i2;
+ return 0;
+}
+function ___shlim(i1, i5) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i6 = 0;
+ i2 = STACKTOP;
+ HEAP32[i1 + 104 >> 2] = i5;
+ i4 = HEAP32[i1 + 8 >> 2] | 0;
+ i3 = HEAP32[i1 + 4 >> 2] | 0;
+ i6 = i4 - i3 | 0;
+ HEAP32[i1 + 108 >> 2] = i6;
+ if ((i5 | 0) != 0 & (i6 | 0) > (i5 | 0)) {
+  HEAP32[i1 + 100 >> 2] = i3 + i5;
+  STACKTOP = i2;
+  return;
+ } else {
+  HEAP32[i1 + 100 >> 2] = i4;
+  STACKTOP = i2;
+  return;
+ }
+}
+function _lua_sethook(i4, i6, i1, i5) {
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = (i6 | 0) == 0 | (i1 | 0) == 0;
+ i3 = HEAP32[i4 + 16 >> 2] | 0;
+ if (!((HEAP8[i3 + 18 | 0] & 1) == 0)) {
+  HEAP32[i4 + 20 >> 2] = HEAP32[i3 + 28 >> 2];
+ }
+ HEAP32[i4 + 52 >> 2] = i2 ? 0 : i6;
+ HEAP32[i4 + 44 >> 2] = i5;
+ HEAP32[i4 + 48 >> 2] = i5;
+ HEAP8[i4 + 40 | 0] = i2 ? 0 : i1 & 255;
+ return 1;
+}
+function _io_tmpfile(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i4 = _lua_newuserdata(i1, 8) | 0;
+ i3 = i4 + 4 | 0;
+ HEAP32[i3 >> 2] = 0;
+ _luaL_setmetatable(i1, 2832);
+ HEAP32[i4 >> 2] = 0;
+ HEAP32[i3 >> 2] = 156;
+ i3 = _tmpfile() | 0;
+ HEAP32[i4 >> 2] = i3;
+ if ((i3 | 0) != 0) {
+  i4 = 1;
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ i4 = _luaL_fileresult(i1, 0, 0) | 0;
+ STACKTOP = i2;
+ return i4 | 0;
+}
+function _luaL_checkstack(i1, i5, i4) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ if ((_lua_checkstack(i1, i5 + 20 | 0) | 0) != 0) {
+  STACKTOP = i2;
+  return;
+ }
+ if ((i4 | 0) == 0) {
+  _luaL_error(i1, 1240, i3) | 0;
+  STACKTOP = i2;
+  return;
+ } else {
+  HEAP32[i3 >> 2] = i4;
+  _luaL_error(i1, 1216, i3) | 0;
+  STACKTOP = i2;
+  return;
+ }
+}
+function _b_rshift(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i4 = _luaL_checkunsigned(i1, 1) | 0;
+ i3 = _luaL_checkinteger(i1, 2) | 0;
+ i5 = 0 - i3 | 0;
+ if ((i3 | 0) > 0) {
+  i5 = (i3 | 0) > 31 ? 0 : i4 >>> i3;
+  _lua_pushunsigned(i1, i5);
+  STACKTOP = i2;
+  return 1;
+ } else {
+  i5 = (i5 | 0) > 31 ? 0 : i4 << i5;
+  _lua_pushunsigned(i1, i5);
+  STACKTOP = i2;
+  return 1;
+ }
+ return 0;
+}
+function _b_lshift(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i3 = _luaL_checkunsigned(i1, 1) | 0;
+ i4 = _luaL_checkinteger(i1, 2) | 0;
+ if ((i4 | 0) < 0) {
+  i4 = 0 - i4 | 0;
+  i4 = (i4 | 0) > 31 ? 0 : i3 >>> i4;
+  _lua_pushunsigned(i1, i4);
+  STACKTOP = i2;
+  return 1;
+ } else {
+  i4 = (i4 | 0) > 31 ? 0 : i3 << i4;
+  _lua_pushunsigned(i1, i4);
+  STACKTOP = i2;
+  return 1;
+ }
+ return 0;
+}
+function _math_min(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, d5 = 0.0, d6 = 0.0;
+ i2 = STACKTOP;
+ i3 = _lua_gettop(i1) | 0;
+ d5 = +_luaL_checknumber(i1, 1);
+ if ((i3 | 0) >= 2) {
+  i4 = 2;
+  while (1) {
+   d6 = +_luaL_checknumber(i1, i4);
+   d5 = d6 < d5 ? d6 : d5;
+   if ((i4 | 0) == (i3 | 0)) {
+    break;
+   } else {
+    i4 = i4 + 1 | 0;
+   }
+  }
+ }
+ _lua_pushnumber(i1, d5);
+ STACKTOP = i2;
+ return 1;
+}
+function _math_max(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, d5 = 0.0, d6 = 0.0;
+ i2 = STACKTOP;
+ i3 = _lua_gettop(i1) | 0;
+ d5 = +_luaL_checknumber(i1, 1);
+ if ((i3 | 0) >= 2) {
+  i4 = 2;
+  while (1) {
+   d6 = +_luaL_checknumber(i1, i4);
+   d5 = d6 > d5 ? d6 : d5;
+   if ((i4 | 0) == (i3 | 0)) {
+    break;
+   } else {
+    i4 = i4 + 1 | 0;
+   }
+  }
+ }
+ _lua_pushnumber(i1, d5);
+ STACKTOP = i2;
+ return 1;
+}
+function _io_type(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ _luaL_checkany(i1, 1);
+ i3 = _luaL_testudata(i1, 1, 2832) | 0;
+ if ((i3 | 0) == 0) {
+  _lua_pushnil(i1);
+  STACKTOP = i2;
+  return 1;
+ }
+ if ((HEAP32[i3 + 4 >> 2] | 0) == 0) {
+  _lua_pushlstring(i1, 3456, 11) | 0;
+  STACKTOP = i2;
+  return 1;
+ } else {
+  _lua_pushlstring(i1, 3472, 4) | 0;
+  STACKTOP = i2;
+  return 1;
+ }
+ return 0;
+}
+function _luaF_newLclosure(i3, i2) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i4 = 0;
+ i1 = STACKTOP;
+ i3 = _luaC_newobj(i3, 6, (i2 << 2) + 16 | 0, 0, 0) | 0;
+ HEAP32[i3 + 12 >> 2] = 0;
+ HEAP8[i3 + 6 | 0] = i2;
+ if ((i2 | 0) == 0) {
+  STACKTOP = i1;
+  return i3 | 0;
+ }
+ i4 = i3 + 16 | 0;
+ do {
+  i2 = i2 + -1 | 0;
+  HEAP32[i4 + (i2 << 2) >> 2] = 0;
+ } while ((i2 | 0) != 0);
+ STACKTOP = i1;
+ return i3 | 0;
+}
+function _io_flush(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ _lua_getfield(i1, -1001e3, 2800);
+ i3 = _lua_touserdata(i1, -1) | 0;
+ if ((HEAP32[i3 + 4 >> 2] | 0) == 0) {
+  HEAP32[i4 >> 2] = 2804;
+  _luaL_error(i1, 3424, i4) | 0;
+ }
+ i4 = _luaL_fileresult(i1, (_fflush(HEAP32[i3 >> 2] | 0) | 0) == 0 | 0, 0) | 0;
+ STACKTOP = i2;
+ return i4 | 0;
+}
+function _b_test(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i3 = _lua_gettop(i1) | 0;
+ if ((i3 | 0) < 1) {
+  i3 = 1;
+ } else {
+  i4 = 1;
+  i5 = -1;
+  while (1) {
+   i5 = (_luaL_checkunsigned(i1, i4) | 0) & i5;
+   if ((i4 | 0) == (i3 | 0)) {
+    break;
+   } else {
+    i4 = i4 + 1 | 0;
+   }
+  }
+  i3 = (i5 | 0) != 0;
+ }
+ _lua_pushboolean(i1, i3 & 1);
+ STACKTOP = i2;
+ return 1;
+}
+function ___muldsi3(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0, i4 = 0, i5 = 0, i6 = 0;
+ i6 = i2 & 65535;
+ i4 = i1 & 65535;
+ i3 = Math_imul(i4, i6) | 0;
+ i5 = i2 >>> 16;
+ i4 = (i3 >>> 16) + (Math_imul(i4, i5) | 0) | 0;
+ i1 = i1 >>> 16;
+ i2 = Math_imul(i1, i6) | 0;
+ return (tempRet0 = (i4 >>> 16) + (Math_imul(i1, i5) | 0) + (((i4 & 65535) + i2 | 0) >>> 16) | 0, i4 + i2 << 16 | i3 & 65535 | 0) | 0;
+}
+function _str_dump(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 1056 | 0;
+ i3 = i2 + 8 | 0;
+ _luaL_checktype(i1, 1, 6);
+ _lua_settop(i1, 1);
+ _luaL_buffinit(i1, i3);
+ if ((_lua_dump(i1, 2, i3) | 0) == 0) {
+  _luaL_pushresult(i3);
+  i3 = 1;
+  STACKTOP = i2;
+  return i3 | 0;
+ } else {
+  i3 = _luaL_error(i1, 7888, i2) | 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ return 0;
+}
+function ___memrchr(i2, i3, i5) {
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i4 = 0;
+ i1 = STACKTOP;
+ i3 = i3 & 255;
+ while (1) {
+  i4 = i5 + -1 | 0;
+  if ((i5 | 0) == 0) {
+   i5 = 0;
+   i2 = 4;
+   break;
+  }
+  i5 = i2 + i4 | 0;
+  if ((HEAP8[i5] | 0) == i3 << 24 >> 24) {
+   i2 = 4;
+   break;
+  } else {
+   i5 = i4;
+  }
+ }
+ if ((i2 | 0) == 4) {
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ return 0;
+}
+function _luaL_getsubtable(i1, i3, i4) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_getfield(i1, i3, i4);
+ if ((_lua_type(i1, -1) | 0) == 5) {
+  i4 = 1;
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ _lua_settop(i1, -2);
+ i3 = _lua_absindex(i1, i3) | 0;
+ _lua_createtable(i1, 0, 0);
+ _lua_pushvalue(i1, -1);
+ _lua_setfield(i1, i3, i4);
+ i4 = 0;
+ STACKTOP = i2;
+ return i4 | 0;
+}
+function _luaE_freeCI(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i4 = (HEAP32[i1 + 16 >> 2] | 0) + 12 | 0;
+ i3 = HEAP32[i4 >> 2] | 0;
+ HEAP32[i4 >> 2] = 0;
+ if ((i3 | 0) == 0) {
+  STACKTOP = i2;
+  return;
+ }
+ while (1) {
+  i4 = HEAP32[i3 + 12 >> 2] | 0;
+  _luaM_realloc_(i1, i3, 40, 0) | 0;
+  if ((i4 | 0) == 0) {
+   break;
+  } else {
+   i3 = i4;
+  }
+ }
+ STACKTOP = i2;
+ return;
+}
+function _f_tostring(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ i4 = _luaL_checkudata(i1, 1, 2832) | 0;
+ if ((HEAP32[i4 + 4 >> 2] | 0) == 0) {
+  _lua_pushlstring(i1, 3040, 13) | 0;
+  STACKTOP = i2;
+  return 1;
+ } else {
+  HEAP32[i3 >> 2] = HEAP32[i4 >> 2];
+  _lua_pushfstring(i1, 3056, i3) | 0;
+  STACKTOP = i2;
+  return 1;
+ }
+ return 0;
+}
+function _lua_newuserdata(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0;
+ i2 = STACKTOP;
+ if ((HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+  _luaC_step(i1);
+ }
+ i3 = _luaS_newudata(i1, i3, 0) | 0;
+ i1 = i1 + 8 | 0;
+ i4 = HEAP32[i1 >> 2] | 0;
+ HEAP32[i4 >> 2] = i3;
+ HEAP32[i4 + 8 >> 2] = 71;
+ HEAP32[i1 >> 2] = (HEAP32[i1 >> 2] | 0) + 16;
+ STACKTOP = i2;
+ return i3 + 24 | 0;
+}
+function _luaL_pushresultsize(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i5 = i1 + 8 | 0;
+ i4 = (HEAP32[i5 >> 2] | 0) + i3 | 0;
+ HEAP32[i5 >> 2] = i4;
+ i3 = HEAP32[i1 + 12 >> 2] | 0;
+ _lua_pushlstring(i3, HEAP32[i1 >> 2] | 0, i4) | 0;
+ if ((HEAP32[i1 >> 2] | 0) == (i1 + 16 | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ _lua_remove(i3, -2);
+ STACKTOP = i2;
+ return;
+}
+function _luaL_testudata(i2, i5, i4) {
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i3 = 0;
+ i1 = STACKTOP;
+ i3 = _lua_touserdata(i2, i5) | 0;
+ if ((i3 | 0) != 0 ? (_lua_getmetatable(i2, i5) | 0) != 0 : 0) {
+  _lua_getfield(i2, -1001e3, i4);
+  i5 = (_lua_rawequal(i2, -1, -2) | 0) == 0;
+  _lua_settop(i2, -3);
+  i2 = i5 ? 0 : i3;
+ } else {
+  i2 = 0;
+ }
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _finishpcall(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((_lua_checkstack(i1, 1) | 0) == 0) {
+  _lua_settop(i1, 0);
+  _lua_pushboolean(i1, 0);
+  _lua_pushstring(i1, 9632) | 0;
+  i3 = 2;
+  STACKTOP = i2;
+  return i3 | 0;
+ } else {
+  _lua_pushboolean(i1, i3);
+  _lua_replace(i1, 1);
+  i3 = _lua_gettop(i1) | 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ return 0;
+}
+function _searcher_preload(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ i3 = _luaL_checklstring(i1, 1, 0) | 0;
+ _lua_getfield(i1, -1001e3, 4592);
+ _lua_getfield(i1, -1, i3);
+ if ((_lua_type(i1, -1) | 0) != 0) {
+  STACKTOP = i2;
+  return 1;
+ }
+ HEAP32[i4 >> 2] = i3;
+ _lua_pushfstring(i1, 5096, i4) | 0;
+ STACKTOP = i2;
+ return 1;
+}
+function _luaB_auxwrap(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i3 = STACKTOP;
+ i2 = _lua_tothread(i1, -1001001) | 0;
+ i2 = _auxresume(i1, i2, _lua_gettop(i1) | 0) | 0;
+ if ((i2 | 0) >= 0) {
+  STACKTOP = i3;
+  return i2 | 0;
+ }
+ if ((_lua_isstring(i1, -1) | 0) == 0) {
+  _lua_error(i1) | 0;
+ }
+ _luaL_where(i1, 1);
+ _lua_insert(i1, -2);
+ _lua_concat(i1, 2);
+ _lua_error(i1) | 0;
+ return 0;
+}
+function _ll_loadlib(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _luaL_checklstring(i1, 1, 0) | 0;
+ i3 = _ll_loadfunc(i1, i3, _luaL_checklstring(i1, 2, 0) | 0) | 0;
+ if ((i3 | 0) == 0) {
+  i3 = 1;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ _lua_pushnil(i1);
+ _lua_insert(i1, -2);
+ _lua_pushstring(i1, (i3 | 0) == 1 ? 5176 : 5184) | 0;
+ i3 = 3;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _luaS_hash(i2, i4, i3) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i5 = 0;
+ i1 = STACKTOP;
+ i5 = i3 ^ i4;
+ i3 = (i4 >>> 5) + 1 | 0;
+ if (i3 >>> 0 > i4 >>> 0) {
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ do {
+  i5 = (i5 << 5) + (i5 >>> 2) + (HEAPU8[i2 + (i4 + -1) | 0] | 0) ^ i5;
+  i4 = i4 - i3 | 0;
+ } while (!(i4 >>> 0 < i3 >>> 0));
+ STACKTOP = i1;
+ return i5 | 0;
+}
+function _b_and(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i3 = _lua_gettop(i1) | 0;
+ if ((i3 | 0) < 1) {
+  i5 = -1;
+ } else {
+  i4 = 1;
+  i5 = -1;
+  while (1) {
+   i5 = (_luaL_checkunsigned(i1, i4) | 0) & i5;
+   if ((i4 | 0) == (i3 | 0)) {
+    break;
+   } else {
+    i4 = i4 + 1 | 0;
+   }
+  }
+ }
+ _lua_pushunsigned(i1, i5);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaopen_string(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_createtable(i1, 0, 14);
+ _luaL_setfuncs(i1, 6920, 0);
+ _lua_createtable(i1, 0, 1);
+ _lua_pushlstring(i1, 7040, 0) | 0;
+ _lua_pushvalue(i1, -2);
+ _lua_setmetatable(i1, -2) | 0;
+ _lua_settop(i1, -2);
+ _lua_pushvalue(i1, -2);
+ _lua_setfield(i1, -2, 7048);
+ _lua_settop(i1, -2);
+ STACKTOP = i2;
+ return 1;
+}
+function _b_xor(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i3 = _lua_gettop(i1) | 0;
+ if ((i3 | 0) < 1) {
+  i5 = 0;
+ } else {
+  i4 = 1;
+  i5 = 0;
+  while (1) {
+   i5 = (_luaL_checkunsigned(i1, i4) | 0) ^ i5;
+   if ((i4 | 0) == (i3 | 0)) {
+    break;
+   } else {
+    i4 = i4 + 1 | 0;
+   }
+  }
+ }
+ _lua_pushunsigned(i1, i5);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaB_assert(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ if ((_lua_toboolean(i1, 1) | 0) == 0) {
+  HEAP32[i3 >> 2] = _luaL_optlstring(i1, 2, 10216, 0) | 0;
+  i3 = _luaL_error(i1, 10208, i3) | 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ } else {
+  i3 = _lua_gettop(i1) | 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ return 0;
+}
+function _b_or(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i3 = _lua_gettop(i1) | 0;
+ if ((i3 | 0) < 1) {
+  i5 = 0;
+ } else {
+  i4 = 1;
+  i5 = 0;
+  while (1) {
+   i5 = _luaL_checkunsigned(i1, i4) | 0 | i5;
+   if ((i4 | 0) == (i3 | 0)) {
+    break;
+   } else {
+    i4 = i4 + 1 | 0;
+   }
+  }
+ }
+ _lua_pushunsigned(i1, i5);
+ STACKTOP = i2;
+ return 1;
+}
+function _io_write(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ _lua_getfield(i1, -1001e3, 2800);
+ i3 = _lua_touserdata(i1, -1) | 0;
+ if ((HEAP32[i3 + 4 >> 2] | 0) == 0) {
+  HEAP32[i4 >> 2] = 2804;
+  _luaL_error(i1, 3424, i4) | 0;
+ }
+ i4 = _g_write(i1, HEAP32[i3 >> 2] | 0, 1) | 0;
+ STACKTOP = i2;
+ return i4 | 0;
+}
+function _luaK_checkstack(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i3 = (HEAPU8[i1 + 48 | 0] | 0) + i3 | 0;
+ i4 = (HEAP32[i1 >> 2] | 0) + 78 | 0;
+ if ((i3 | 0) <= (HEAPU8[i4] | 0 | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ if ((i3 | 0) > 249) {
+  _luaX_syntaxerror(HEAP32[i1 + 12 >> 2] | 0, 10536);
+ }
+ HEAP8[i4] = i3;
+ STACKTOP = i2;
+ return;
+}
+function _io_read(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ _lua_getfield(i1, -1001e3, 2776);
+ i3 = _lua_touserdata(i1, -1) | 0;
+ if ((HEAP32[i3 + 4 >> 2] | 0) == 0) {
+  HEAP32[i4 >> 2] = 2780;
+  _luaL_error(i1, 3424, i4) | 0;
+ }
+ i4 = _g_read(i1, HEAP32[i3 >> 2] | 0, 1) | 0;
+ STACKTOP = i2;
+ return i4 | 0;
+}
+function _db_setupvalue(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ _luaL_checkany(i1, 3);
+ i3 = _luaL_checkinteger(i1, 2) | 0;
+ _luaL_checktype(i1, 1, 6);
+ i3 = _lua_setupvalue(i1, 1, i3) | 0;
+ if ((i3 | 0) == 0) {
+  i3 = 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ _lua_pushstring(i1, i3) | 0;
+ _lua_insert(i1, -1);
+ i3 = 1;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function ___uflow(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i1;
+ if ((HEAP32[i2 + 8 >> 2] | 0) == 0 ? (___toread(i2) | 0) != 0 : 0) {
+  i2 = -1;
+ } else {
+  if ((FUNCTION_TABLE_iiii[HEAP32[i2 + 32 >> 2] & 3](i2, i3, 1) | 0) == 1) {
+   i2 = HEAPU8[i3] | 0;
+  } else {
+   i2 = -1;
+  }
+ }
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _llvm_cttz_i32(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = HEAP8[cttz_i8 + (i1 & 255) | 0] | 0;
+ if ((i2 | 0) < 8) return i2 | 0;
+ i2 = HEAP8[cttz_i8 + (i1 >> 8 & 255) | 0] | 0;
+ if ((i2 | 0) < 8) return i2 + 8 | 0;
+ i2 = HEAP8[cttz_i8 + (i1 >> 16 & 255) | 0] | 0;
+ if ((i2 | 0) < 8) return i2 + 16 | 0;
+ return (HEAP8[cttz_i8 + (i1 >>> 24) | 0] | 0) + 24 | 0;
+}
+function _llvm_ctlz_i32(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = HEAP8[ctlz_i8 + (i1 >>> 24) | 0] | 0;
+ if ((i2 | 0) < 8) return i2 | 0;
+ i2 = HEAP8[ctlz_i8 + (i1 >> 16 & 255) | 0] | 0;
+ if ((i2 | 0) < 8) return i2 + 8 | 0;
+ i2 = HEAP8[ctlz_i8 + (i1 >> 8 & 255) | 0] | 0;
+ if ((i2 | 0) < 8) return i2 + 16 | 0;
+ return (HEAP8[ctlz_i8 + (i1 & 255) | 0] | 0) + 24 | 0;
+}
+function _luaO_ceillog2(i2) {
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i4 = 0;
+ i1 = STACKTOP;
+ i2 = i2 + -1 | 0;
+ if (i2 >>> 0 > 255) {
+  i3 = 0;
+  while (1) {
+   i3 = i3 + 8 | 0;
+   i4 = i2 >>> 8;
+   if (i2 >>> 0 > 65535) {
+    i2 = i4;
+   } else {
+    i2 = i4;
+    break;
+   }
+  }
+ } else {
+  i3 = 0;
+ }
+ STACKTOP = i1;
+ return (HEAPU8[5208 + i2 | 0] | 0) + i3 | 0;
+}
+function _os_exit(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ if ((_lua_type(i1, 1) | 0) == 1) {
+  i3 = (_lua_toboolean(i1, 1) | 0) == 0 | 0;
+ } else {
+  i3 = _luaL_optinteger(i1, 1, 0) | 0;
+ }
+ if ((_lua_toboolean(i1, 2) | 0) != 0) {
+  _lua_close(i1);
+ }
+ if ((i1 | 0) == 0) {
+  STACKTOP = i2;
+  return 0;
+ } else {
+  _exit(i3 | 0);
+ }
+ return 0;
+}
+function _luaL_newmetatable(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_getfield(i1, -1001e3, i3);
+ if ((_lua_type(i1, -1) | 0) != 0) {
+  i3 = 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ _lua_settop(i1, -2);
+ _lua_createtable(i1, 0, 0);
+ _lua_pushvalue(i1, -1);
+ _lua_setfield(i1, -1001e3, i3);
+ i3 = 1;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _luaH_free(i1, i4) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = HEAP32[i4 + 16 >> 2] | 0;
+ if ((i3 | 0) != 8016) {
+  _luaM_realloc_(i1, i3, 32 << (HEAPU8[i4 + 7 | 0] | 0), 0) | 0;
+ }
+ _luaM_realloc_(i1, HEAP32[i4 + 12 >> 2] | 0, HEAP32[i4 + 28 >> 2] << 4, 0) | 0;
+ _luaM_realloc_(i1, i4, 32, 0) | 0;
+ STACKTOP = i2;
+ return;
+}
+function _luaO_int2fb(i3) {
+ i3 = i3 | 0;
+ var i1 = 0, i2 = 0, i4 = 0;
+ i1 = STACKTOP;
+ if (i3 >>> 0 < 8) {
+  STACKTOP = i1;
+  return i3 | 0;
+ }
+ if (i3 >>> 0 > 15) {
+  i2 = 1;
+  do {
+   i4 = i3 + 1 | 0;
+   i3 = i4 >>> 1;
+   i2 = i2 + 1 | 0;
+  } while (i4 >>> 0 > 31);
+  i2 = i2 << 3;
+ } else {
+  i2 = 8;
+ }
+ i4 = i2 | i3 + -8;
+ STACKTOP = i1;
+ return i4 | 0;
+}
+function _luaK_codek(i3, i4, i1) {
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i4 = i4 << 6;
+ if ((i1 | 0) < 262144) {
+  i4 = _luaK_code(i3, i4 | i1 << 14 | 1) | 0;
+  STACKTOP = i2;
+  return i4 | 0;
+ } else {
+  i4 = _luaK_code(i3, i4 | 2) | 0;
+  _luaK_code(i3, i1 << 6 | 39) | 0;
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ return 0;
+}
+function _luaB_xpcall(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _lua_gettop(i1) | 0;
+ if ((i3 | 0) <= 1) {
+  _luaL_argerror(i1, 2, 9616) | 0;
+ }
+ _lua_pushvalue(i1, 1);
+ _lua_copy(i1, 2, 1);
+ _lua_replace(i1, 2);
+ i3 = _finishpcall(i1, (_lua_pcallk(i1, i3 + -2 | 0, -1, 1, 0, 166) | 0) == 0 | 0) | 0;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _luaS_newudata(i1, i3, i4) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if (i3 >>> 0 > 4294967269) {
+  _luaM_toobig(i1);
+ } else {
+  i1 = _luaC_newobj(i1, 7, i3 + 24 | 0, 0, 0) | 0;
+  HEAP32[i1 + 16 >> 2] = i3;
+  HEAP32[i1 + 8 >> 2] = 0;
+  HEAP32[i1 + 12 >> 2] = i4;
+  STACKTOP = i2;
+  return i1 | 0;
+ }
+ return 0;
+}
+function _lua_dump(i1, i4, i5) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = HEAP32[i1 + 8 >> 2] | 0;
+ if ((HEAP32[i3 + -8 >> 2] | 0) != 70) {
+  i5 = 1;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ i5 = _luaU_dump(i1, HEAP32[(HEAP32[i3 + -16 >> 2] | 0) + 12 >> 2] | 0, i4, i5, 0) | 0;
+ STACKTOP = i2;
+ return i5 | 0;
+}
+function _luaS_eqlngstr(i2, i4) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i3 = 0;
+ i1 = STACKTOP;
+ i3 = HEAP32[i2 + 12 >> 2] | 0;
+ if ((i2 | 0) != (i4 | 0)) {
+  if ((i3 | 0) == (HEAP32[i4 + 12 >> 2] | 0)) {
+   i2 = (_memcmp(i2 + 16 | 0, i4 + 16 | 0, i3) | 0) == 0;
+  } else {
+   i2 = 0;
+  }
+ } else {
+  i2 = 1;
+ }
+ STACKTOP = i1;
+ return i2 & 1 | 0;
+}
+function _luaC_barrier_(i4, i3, i1) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i4 = HEAP32[i4 + 12 >> 2] | 0;
+ if ((HEAPU8[i4 + 61 | 0] | 0) < 2) {
+  _reallymarkobject(i4, i1);
+  STACKTOP = i2;
+  return;
+ } else {
+  i3 = i3 + 5 | 0;
+  HEAP8[i3] = HEAP8[i4 + 60 | 0] & 3 | HEAP8[i3] & 184;
+  STACKTOP = i2;
+  return;
+ }
+}
+function _db_getupvalue(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _luaL_checkinteger(i1, 2) | 0;
+ _luaL_checktype(i1, 1, 6);
+ i3 = _lua_getupvalue(i1, 1, i3) | 0;
+ if ((i3 | 0) == 0) {
+  i3 = 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ _lua_pushstring(i1, i3) | 0;
+ _lua_insert(i1, -2);
+ i3 = 2;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _os_execute(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i4 = _luaL_optlstring(i1, 1, 0, 0) | 0;
+ i3 = _system(i4 | 0) | 0;
+ if ((i4 | 0) == 0) {
+  _lua_pushboolean(i1, i3);
+  i4 = 1;
+  STACKTOP = i2;
+  return i4 | 0;
+ } else {
+  i4 = _luaL_execresult(i1, i3) | 0;
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ return 0;
+}
+function _lua_pushfstring(i4, i5, i1) {
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ if ((HEAP32[(HEAP32[i4 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+  _luaC_step(i4);
+ }
+ HEAP32[i3 >> 2] = i1;
+ i5 = _luaO_pushvfstring(i4, i5, i3) | 0;
+ STACKTOP = i2;
+ return i5 | 0;
+}
+function _luaB_dofile(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _luaL_optlstring(i1, 1, 0, 0) | 0;
+ _lua_settop(i1, 1);
+ if ((_luaL_loadfilex(i1, i3, 0) | 0) == 0) {
+  _lua_callk(i1, 0, -1, 0, 164);
+  i3 = (_lua_gettop(i1) | 0) + -1 | 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ } else {
+  _lua_error(i1) | 0;
+ }
+ return 0;
+}
+function _f_write(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = _luaL_checkudata(i1, 1, 2832) | 0;
+ if ((HEAP32[i3 + 4 >> 2] | 0) == 0) {
+  _luaL_error(i1, 3080, i2) | 0;
+ }
+ i3 = HEAP32[i3 >> 2] | 0;
+ _lua_pushvalue(i1, 1);
+ i3 = _g_write(i1, i3, 2) | 0;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _lua_getctx(i3, i1) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i3 = HEAP32[i3 + 16 >> 2] | 0;
+ if ((HEAP8[i3 + 18 | 0] & 8) == 0) {
+  i3 = 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ if ((i1 | 0) != 0) {
+  HEAP32[i1 >> 2] = HEAP32[i3 + 24 >> 2];
+ }
+ i3 = HEAPU8[i3 + 37 | 0] | 0;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _f_flush(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = _luaL_checkudata(i1, 1, 2832) | 0;
+ if ((HEAP32[i3 + 4 >> 2] | 0) == 0) {
+  _luaL_error(i1, 3080, i2) | 0;
+ }
+ i3 = _luaL_fileresult(i1, (_fflush(HEAP32[i3 >> 2] | 0) | 0) == 0 | 0, 0) | 0;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _os_tmpname(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i3 = i2 + 4 | 0;
+ if ((_tmpnam(i3 | 0) | 0) == 0) {
+  i3 = _luaL_error(i1, 5824, i2) | 0;
+  STACKTOP = i2;
+  return i3 | 0;
+ } else {
+  _lua_pushstring(i1, i3) | 0;
+  i3 = 1;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ return 0;
+}
+function _traceback(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _lua_tolstring(i1, 1, 0) | 0;
+ if ((i3 | 0) == 0) {
+  if ((_lua_type(i1, 1) | 0) >= 1 ? (_luaL_callmeta(i1, 1, 216) | 0) == 0 : 0) {
+   _lua_pushlstring(i1, 232, 18) | 0;
+  }
+ } else {
+  _luaL_traceback(i1, i1, i3, 1);
+ }
+ STACKTOP = i2;
+ return 1;
+}
+function _luaH_new(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i1 = _luaC_newobj(i1, 5, 32, 0, 0) | 0;
+ HEAP32[i1 + 8 >> 2] = 0;
+ HEAP8[i1 + 6 | 0] = -1;
+ HEAP32[i1 + 12 >> 2] = 0;
+ HEAP32[i1 + 28 >> 2] = 0;
+ HEAP32[i1 + 16 >> 2] = 8016;
+ HEAP8[i1 + 7 | 0] = 0;
+ HEAP32[i1 + 20 >> 2] = 8016;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _luaL_len(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2 + 4 | 0;
+ _lua_len(i1, i3);
+ i3 = _lua_tointegerx(i1, -1, i4) | 0;
+ if ((HEAP32[i4 >> 2] | 0) == 0) {
+  _luaL_error(i1, 1352, i2) | 0;
+ }
+ _lua_settop(i1, -2);
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _getS(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0, i5 = 0;
+ i3 = STACKTOP;
+ i5 = i2 + 4 | 0;
+ i4 = HEAP32[i5 >> 2] | 0;
+ if ((i4 | 0) == 0) {
+  i5 = 0;
+  STACKTOP = i3;
+  return i5 | 0;
+ }
+ HEAP32[i1 >> 2] = i4;
+ HEAP32[i5 >> 2] = 0;
+ i5 = HEAP32[i2 >> 2] | 0;
+ STACKTOP = i3;
+ return i5 | 0;
+}
+function _luaC_runtilstate(i1, i4) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = (HEAP32[i1 + 12 >> 2] | 0) + 61 | 0;
+ if ((1 << (HEAPU8[i3] | 0) & i4 | 0) != 0) {
+  STACKTOP = i2;
+  return;
+ }
+ do {
+  _singlestep(i1) | 0;
+ } while ((1 << (HEAPU8[i3] | 0) & i4 | 0) == 0);
+ STACKTOP = i2;
+ return;
+}
+function _luaX_init(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ i3 = 0;
+ do {
+  i4 = _luaS_new(i1, HEAP32[12096 + (i3 << 2) >> 2] | 0) | 0;
+  i5 = i4 + 5 | 0;
+  HEAP8[i5] = HEAPU8[i5] | 0 | 32;
+  i3 = i3 + 1 | 0;
+  HEAP8[i4 + 6 | 0] = i3;
+ } while ((i3 | 0) != 22);
+ STACKTOP = i2;
+ return;
+}
+function _luaK_indexed(i5, i1, i4) {
+ i5 = i5 | 0;
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i3 = 0;
+ i3 = STACKTOP;
+ i2 = i1 + 8 | 0;
+ HEAP8[i2 + 2 | 0] = HEAP32[i2 >> 2];
+ HEAP16[i2 >> 1] = _luaK_exp2RK(i5, i4) | 0;
+ HEAP8[i2 + 3 | 0] = (HEAP32[i1 >> 2] | 0) == 8 ? 8 : 7;
+ HEAP32[i1 >> 2] = 9;
+ STACKTOP = i3;
+ return;
+}
+function _db_setuservalue(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((_lua_type(i1, 1) | 0) == 2) {
+  _luaL_argerror(i1, 1, 11680) | 0;
+ }
+ _luaL_checktype(i1, 1, 7);
+ if ((_lua_type(i1, 2) | 0) >= 1) {
+  _luaL_checktype(i1, 2, 5);
+ }
+ _lua_settop(i1, 2);
+ _lua_setuservalue(i1, 1);
+ STACKTOP = i2;
+ return 1;
+}
+function _ll_seeall(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_checktype(i1, 1, 5);
+ if ((_lua_getmetatable(i1, 1) | 0) == 0) {
+  _lua_createtable(i1, 0, 1);
+  _lua_pushvalue(i1, -1);
+  _lua_setmetatable(i1, 1) | 0;
+ }
+ _lua_rawgeti(i1, -1001e3, 2);
+ _lua_setfield(i1, -2, 5168);
+ STACKTOP = i2;
+ return 0;
+}
+function _luaL_loadbufferx(i3, i5, i4, i2, i1) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i6 = 0, i7 = 0;
+ i6 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i7 = i6;
+ HEAP32[i7 >> 2] = i5;
+ HEAP32[i7 + 4 >> 2] = i4;
+ i5 = _lua_load(i3, 2, i7, i2, i1) | 0;
+ STACKTOP = i6;
+ return i5 | 0;
+}
+function _luaT_gettm(i1, i3, i4) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i4 = _luaH_getstr(i1, i4) | 0;
+ if ((HEAP32[i4 + 8 >> 2] | 0) != 0) {
+  STACKTOP = i2;
+  return i4 | 0;
+ }
+ i4 = i1 + 6 | 0;
+ HEAP8[i4] = HEAPU8[i4] | 0 | 1 << i3;
+ i4 = 0;
+ STACKTOP = i2;
+ return i4 | 0;
+}
+function _luaL_pushresult(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = HEAP32[i1 + 12 >> 2] | 0;
+ _lua_pushlstring(i3, HEAP32[i1 >> 2] | 0, HEAP32[i1 + 8 >> 2] | 0) | 0;
+ if ((HEAP32[i1 >> 2] | 0) == (i1 + 16 | 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ _lua_remove(i3, -2);
+ STACKTOP = i2;
+ return;
+}
+function _resume_error(i1, i3, i2) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ var i4 = 0;
+ i4 = i1 + 8 | 0;
+ HEAP32[i4 >> 2] = i2;
+ i3 = _luaS_new(i1, i3) | 0;
+ HEAP32[i2 >> 2] = i3;
+ HEAP32[i2 + 8 >> 2] = HEAPU8[i3 + 4 | 0] | 0 | 64;
+ HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + 16;
+ _luaD_throw(i1, -1);
+}
+function _lua_absindex(i3, i1) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((i1 + 1000999 | 0) >>> 0 > 1000999) {
+  i3 = i1;
+  STACKTOP = i2;
+  return i3 | 0;
+ }
+ i3 = ((HEAP32[i3 + 8 >> 2] | 0) - (HEAP32[HEAP32[i3 + 16 >> 2] >> 2] | 0) >> 4) + i1 | 0;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function ___uremdi3(i4, i3, i2, i1) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i5 = 0, i6 = 0;
+ i6 = STACKTOP;
+ STACKTOP = STACKTOP + 8 | 0;
+ i5 = i6 | 0;
+ ___udivmoddi4(i4, i3, i2, i1, i5) | 0;
+ STACKTOP = i6;
+ return (tempRet0 = HEAP32[i5 + 4 >> 2] | 0, HEAP32[i5 >> 2] | 0) | 0;
+}
+function _f_read(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = _luaL_checkudata(i1, 1, 2832) | 0;
+ if ((HEAP32[i3 + 4 >> 2] | 0) == 0) {
+  _luaL_error(i1, 3080, i2) | 0;
+ }
+ i3 = _g_read(i1, HEAP32[i3 >> 2] | 0, 2) | 0;
+ STACKTOP = i2;
+ return i3 | 0;
+}
+function _sort(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ _luaL_checktype(i1, 1, 5);
+ i3 = _luaL_len(i1, 1) | 0;
+ _luaL_checkstack(i1, 40, 8208);
+ if ((_lua_type(i1, 2) | 0) >= 1) {
+  _luaL_checktype(i1, 2, 6);
+ }
+ _lua_settop(i1, 2);
+ _auxsort(i1, 1, i3);
+ STACKTOP = i2;
+ return 0;
+}
+function _luaB_error(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = _luaL_optinteger(i1, 2, 1) | 0;
+ _lua_settop(i1, 1);
+ if (!((_lua_isstring(i1, 1) | 0) != 0 & (i2 | 0) > 0)) {
+  _lua_error(i1) | 0;
+ }
+ _luaL_where(i1, i2);
+ _lua_pushvalue(i1, 1);
+ _lua_concat(i1, 2);
+ _lua_error(i1) | 0;
+ return 0;
+}
+function _error(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = HEAP32[i1 >> 2] | 0;
+ HEAP32[i3 >> 2] = HEAP32[i1 + 12 >> 2];
+ HEAP32[i3 + 4 >> 2] = i2;
+ _luaO_pushfstring(i4, 8840, i3) | 0;
+ _luaD_throw(HEAP32[i1 >> 2] | 0, 3);
+}
+function _ipairsaux(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _luaL_checkinteger(i1, 2) | 0;
+ _luaL_checktype(i1, 1, 5);
+ i3 = i3 + 1 | 0;
+ _lua_pushinteger(i1, i3);
+ _lua_rawgeti(i1, 1, i3);
+ i1 = (_lua_type(i1, -1) | 0) == 0;
+ STACKTOP = i2;
+ return (i1 ? 1 : 2) | 0;
+}
+function _panic(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ i3 = HEAP32[_stderr >> 2] | 0;
+ HEAP32[i4 >> 2] = _lua_tolstring(i1, -1, 0) | 0;
+ _fprintf(i3 | 0, 1656, i4 | 0) | 0;
+ _fflush(i3 | 0) | 0;
+ STACKTOP = i2;
+ return 0;
+}
+function _testSetjmp(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0;
+ while ((i3 | 0) < 20) {
+  i4 = HEAP32[i2 + (i3 << 2) >> 2] | 0;
+  if ((i4 | 0) == 0) break;
+  if ((i4 | 0) == (i1 | 0)) {
+   return HEAP32[i2 + ((i3 << 2) + 4) >> 2] | 0;
+  }
+  i3 = i3 + 2 | 0;
+ }
+ return 0;
+}
+function _luaopen_math(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_createtable(i1, 0, 28);
+ _luaL_setfuncs(i1, 3576, 0);
+ _lua_pushnumber(i1, 3.141592653589793);
+ _lua_setfield(i1, -2, 3808);
+ _lua_pushnumber(i1, inf);
+ _lua_setfield(i1, -2, 3816);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaopen_base(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_rawgeti(i1, -1001e3, 2);
+ _lua_rawgeti(i1, -1001e3, 2);
+ _lua_setfield(i1, -2, 9144);
+ _luaL_setfuncs(i1, 9152, 0);
+ _lua_pushlstring(i1, 9344, 7) | 0;
+ _lua_setfield(i1, -2, 9352);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaE_extendCI(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i3 = STACKTOP;
+ i2 = _luaM_realloc_(i1, 0, 0, 40) | 0;
+ i1 = i1 + 16 | 0;
+ HEAP32[(HEAP32[i1 >> 2] | 0) + 12 >> 2] = i2;
+ HEAP32[i2 + 8 >> 2] = HEAP32[i1 >> 2];
+ HEAP32[i2 + 12 >> 2] = 0;
+ STACKTOP = i3;
+ return i2 | 0;
+}
+function _luaB_getmetatable(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_checkany(i1, 1);
+ if ((_lua_getmetatable(i1, 1) | 0) == 0) {
+  _lua_pushnil(i1);
+  STACKTOP = i2;
+  return 1;
+ } else {
+  _luaL_getmetafield(i1, 1, 9704) | 0;
+  STACKTOP = i2;
+  return 1;
+ }
+ return 0;
+}
+function _lua_pushunsigned(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var d3 = 0.0;
+ if ((i2 | 0) > -1) {
+  d3 = +(i2 | 0);
+ } else {
+  d3 = +(i2 >>> 0);
+ }
+ i2 = i1 + 8 | 0;
+ i1 = HEAP32[i2 >> 2] | 0;
+ HEAPF64[i1 >> 3] = d3;
+ HEAP32[i1 + 8 >> 2] = 3;
+ HEAP32[i2 >> 2] = i1 + 16;
+ return;
+}
+function _lua_pushthread(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = i1 + 8 | 0;
+ i3 = HEAP32[i2 >> 2] | 0;
+ HEAP32[i3 >> 2] = i1;
+ HEAP32[i3 + 8 >> 2] = 72;
+ HEAP32[i2 >> 2] = (HEAP32[i2 >> 2] | 0) + 16;
+ return (HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 172 >> 2] | 0) == (i1 | 0) | 0;
+}
+function _gctm(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _luaL_len(i1, 1) | 0;
+ if ((i3 | 0) <= 0) {
+  STACKTOP = i2;
+  return 0;
+ }
+ do {
+  _lua_rawgeti(i1, 1, i3);
+  _lua_settop(i1, -2);
+  i3 = i3 + -1 | 0;
+ } while ((i3 | 0) > 0);
+ STACKTOP = i2;
+ return 0;
+}
+function ___muldi3(i4, i2, i3, i1) {
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i5 = 0, i6 = 0;
+ i5 = i4;
+ i6 = i3;
+ i4 = ___muldsi3(i5, i6) | 0;
+ i3 = tempRet0;
+ return (tempRet0 = (Math_imul(i2, i6) | 0) + (Math_imul(i1, i5) | 0) + i3 | i3 & 0, i4 | 0 | 0) | 0;
+}
+function _luaH_resizearray(i1, i3, i4) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i5 = 0;
+ i2 = STACKTOP;
+ if ((HEAP32[i3 + 16 >> 2] | 0) == 8016) {
+  i5 = 0;
+ } else {
+  i5 = 1 << (HEAPU8[i3 + 7 | 0] | 0);
+ }
+ _luaH_resize(i1, i3, i4, i5);
+ STACKTOP = i2;
+ return;
+}
+function _luaK_stringK(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i3;
+ HEAP32[i4 >> 2] = i2;
+ HEAP32[i4 + 8 >> 2] = HEAPU8[i2 + 4 | 0] | 0 | 64;
+ i2 = _addk(i1, i4, i4) | 0;
+ STACKTOP = i3;
+ return i2 | 0;
+}
+function _math_modf(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, d3 = 0.0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i2;
+ d3 = +_modf(+(+_luaL_checknumber(i1, 1)), i4 | 0);
+ _lua_pushnumber(i1, +HEAPF64[i4 >> 3]);
+ _lua_pushnumber(i1, d3);
+ STACKTOP = i2;
+ return 2;
+}
+function _os_setlocale(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _luaL_optlstring(i1, 1, 0, 0) | 0;
+ _lua_pushstring(i1, _setlocale(HEAP32[5960 + ((_luaL_checkoption(i1, 2, 6016, 5984) | 0) << 2) >> 2] | 0, i3 | 0) | 0) | 0;
+ STACKTOP = i2;
+ return 1;
+}
+function _luaB_pcall(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_checkany(i1, 1);
+ _lua_pushnil(i1);
+ _lua_insert(i1, 1);
+ i1 = _finishpcall(i1, (_lua_pcallk(i1, (_lua_gettop(i1) | 0) + -2 | 0, -1, 0, 0, 166) | 0) == 0 | 0) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _error_expected(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0, i4 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = HEAP32[i1 + 52 >> 2] | 0;
+ HEAP32[i3 >> 2] = _luaX_token2str(i1, i2) | 0;
+ _luaX_syntaxerror(i1, _luaO_pushfstring(i4, 6328, i3) | 0);
+}
+function _lua_pushvfstring(i1, i3, i4) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 12 >> 2] | 0) > 0) {
+  _luaC_step(i1);
+ }
+ i4 = _luaO_pushvfstring(i1, i3, i4) | 0;
+ STACKTOP = i2;
+ return i4 | 0;
+}
+function _db_setmetatable(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _lua_type(i1, 2) | 0;
+ if (!((i3 | 0) == 0 | (i3 | 0) == 5)) {
+  _luaL_argerror(i1, 2, 11536) | 0;
+ }
+ _lua_settop(i1, 2);
+ _lua_setmetatable(i1, 1) | 0;
+ STACKTOP = i2;
+ return 1;
+}
+function _b_rrot(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i3 = 0 - (_luaL_checkinteger(i1, 2) | 0) | 0;
+ i4 = _luaL_checkunsigned(i1, 1) | 0;
+ i3 = i3 & 31;
+ _lua_pushunsigned(i1, i4 >>> (32 - i3 | 0) | i4 << i3);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaC_step(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = HEAP32[i1 + 12 >> 2] | 0;
+ if ((HEAP8[i3 + 63 | 0] | 0) == 0) {
+  _luaE_setdebt(i3, -1600);
+  STACKTOP = i2;
+  return;
+ } else {
+  _luaC_forcestep(i1);
+  STACKTOP = i2;
+  return;
+ }
+}
+function _math_frexp(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ _lua_pushnumber(i1, +_frexp(+(+_luaL_checknumber(i1, 1)), i3 | 0));
+ _lua_pushinteger(i1, HEAP32[i3 >> 2] | 0);
+ STACKTOP = i2;
+ return 2;
+}
+function _luaO_pushfstring(i2, i1, i3) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i4 = 0, i5 = 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i5 = i4;
+ HEAP32[i5 >> 2] = i3;
+ i3 = _luaO_pushvfstring(i2, i1, i5) | 0;
+ STACKTOP = i4;
+ return i3 | 0;
+}
+function _luaO_hexavalue(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((HEAP8[i1 + 10913 | 0] & 2) == 0) {
+  i1 = (i1 | 32) + -87 | 0;
+  STACKTOP = i2;
+  return i1 | 0;
+ } else {
+  i1 = i1 + -48 | 0;
+  STACKTOP = i2;
+  return i1 | 0;
+ }
+ return 0;
+}
+function _b_lrot(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ i3 = _luaL_checkinteger(i1, 2) | 0;
+ i4 = _luaL_checkunsigned(i1, 1) | 0;
+ i3 = i3 & 31;
+ _lua_pushunsigned(i1, i4 >>> (32 - i3 | 0) | i4 << i3);
+ STACKTOP = i2;
+ return 1;
+}
+function _f_lines(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ if ((HEAP32[(_luaL_checkudata(i1, 1, 2832) | 0) + 4 >> 2] | 0) == 0) {
+  _luaL_error(i1, 3080, i2) | 0;
+ }
+ _aux_lines(i1, 0);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaC_barrierback_(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i2 = HEAP32[i2 + 12 >> 2] | 0;
+ i3 = i1 + 5 | 0;
+ HEAP8[i3] = HEAP8[i3] & 251;
+ i2 = i2 + 88 | 0;
+ HEAP32[i1 + 24 >> 2] = HEAP32[i2 >> 2];
+ HEAP32[i2 >> 2] = i1;
+ return;
+}
+function _os_rename(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _luaL_checklstring(i1, 1, 0) | 0;
+ i1 = _luaL_fileresult(i1, (_rename(i3 | 0, _luaL_checklstring(i1, 2, 0) | 0) | 0) == 0 | 0, 0) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _bitshift64Ashr(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ if ((i1 | 0) < 32) {
+  tempRet0 = i2 >> i1;
+  return i3 >>> i1 | (i2 & (1 << i1) - 1) << 32 - i1;
+ }
+ tempRet0 = (i2 | 0) < 0 ? -1 : 0;
+ return i2 >> i1 - 32 | 0;
+}
+function _luaB_cowrap(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ _luaL_checktype(i1, 1, 6);
+ i3 = _lua_newthread(i1) | 0;
+ _lua_pushvalue(i1, 1);
+ _lua_xmove(i1, i3, 1);
+ _lua_pushcclosure(i1, 167, 1);
+ STACKTOP = i2;
+ return 1;
+}
+function _gmatch(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_checklstring(i1, 1, 0) | 0;
+ _luaL_checklstring(i1, 2, 0) | 0;
+ _lua_settop(i1, 2);
+ _lua_pushinteger(i1, 0);
+ _lua_pushcclosure(i1, 163, 3);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaB_next(i2) {
+ i2 = i2 | 0;
+ var i1 = 0;
+ i1 = STACKTOP;
+ _luaL_checktype(i2, 1, 5);
+ _lua_settop(i2, 2);
+ if ((_lua_next(i2, 1) | 0) == 0) {
+  _lua_pushnil(i2);
+  i2 = 1;
+ } else {
+  i2 = 2;
+ }
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _luaK_codeABC(i5, i3, i4, i2, i1) {
+ i5 = i5 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i6 = 0;
+ i6 = STACKTOP;
+ i5 = _luaK_code(i5, i4 << 6 | i3 | i2 << 23 | i1 << 14) | 0;
+ STACKTOP = i6;
+ return i5 | 0;
+}
+function _luaH_set(i2, i4, i5) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i3 = 0;
+ i1 = STACKTOP;
+ i3 = _luaH_get(i4, i5) | 0;
+ if ((i3 | 0) == 5192) {
+  i3 = _luaH_newkey(i2, i4, i5) | 0;
+ }
+ STACKTOP = i1;
+ return i3 | 0;
+}
+function _luaZ_init(i4, i1, i3, i2) {
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ HEAP32[i1 + 16 >> 2] = i4;
+ HEAP32[i1 + 8 >> 2] = i3;
+ HEAP32[i1 + 12 >> 2] = i2;
+ HEAP32[i1 >> 2] = 0;
+ HEAP32[i1 + 4 >> 2] = 0;
+ return;
+}
+function _lua_pushlightuserdata(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i2 = i2 + 8 | 0;
+ i3 = HEAP32[i2 >> 2] | 0;
+ HEAP32[i3 >> 2] = i1;
+ HEAP32[i3 + 8 >> 2] = 2;
+ HEAP32[i2 >> 2] = (HEAP32[i2 >> 2] | 0) + 16;
+ return;
+}
+function copyTempFloat(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+}
+function _bitshift64Shl(i2, i3, i1) {
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ if ((i1 | 0) < 32) {
+  tempRet0 = i3 << i1 | (i2 & (1 << i1) - 1 << 32 - i1) >>> 32 - i1;
+  return i2 << i1;
+ }
+ tempRet0 = i2 << i1 - 32;
+ return 0;
+}
+function _luaB_rawlen(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if (((_lua_type(i1, 1) | 0) & -2 | 0) != 4) {
+  _luaL_argerror(i1, 1, 9784) | 0;
+ }
+ _lua_pushinteger(i1, _lua_rawlen(i1, 1) | 0);
+ STACKTOP = i2;
+ return 1;
+}
+function _l_alloc(i3, i1, i4, i2) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i3 = STACKTOP;
+ if ((i2 | 0) == 0) {
+  _free(i1);
+  i1 = 0;
+ } else {
+  i1 = _realloc(i1, i2) | 0;
+ }
+ STACKTOP = i3;
+ return i1 | 0;
+}
+function _bitshift64Lshr(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ if ((i1 | 0) < 32) {
+  tempRet0 = i2 >>> i1;
+  return i3 >>> i1 | (i2 & (1 << i1) - 1) << 32 - i1;
+ }
+ tempRet0 = 0;
+ return i2 >>> i1 - 32 | 0;
+}
+function _luaG_aritherror(i3, i1, i2) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i4 = 0;
+ i4 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = (_luaV_tonumber(i1, i4) | 0) == 0;
+ _luaG_typeerror(i3, i4 ? i1 : i2, 1928);
+}
+function _str_len(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i3 = i2;
+ _luaL_checklstring(i1, 1, i3) | 0;
+ _lua_pushinteger(i1, HEAP32[i3 >> 2] | 0);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaL_optinteger(i3, i4, i2) {
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ var i1 = 0;
+ i1 = STACKTOP;
+ if ((_lua_type(i3, i4) | 0) >= 1) {
+  i2 = _luaL_checkinteger(i3, i4) | 0;
+ }
+ STACKTOP = i1;
+ return i2 | 0;
+}
+function _os_difftime(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = ~~+_luaL_checknumber(i1, 1);
+ _lua_pushnumber(i1, +_difftime(i3 | 0, ~~+_luaL_optnumber(i1, 2, 0.0) | 0));
+ STACKTOP = i2;
+ return 1;
+}
+function _lua_pushboolean(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i2 = i2 + 8 | 0;
+ i3 = HEAP32[i2 >> 2] | 0;
+ HEAP32[i3 >> 2] = (i1 | 0) != 0;
+ HEAP32[i3 + 8 >> 2] = 1;
+ HEAP32[i2 >> 2] = i3 + 16;
+ return;
+}
+function _os_remove(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = _luaL_checklstring(i1, 1, 0) | 0;
+ i1 = _luaL_fileresult(i1, (_remove(i3 | 0) | 0) == 0 | 0, i3) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _luaopen_table(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_createtable(i1, 0, 7);
+ _luaL_setfuncs(i1, 8088, 0);
+ _lua_getfield(i1, -1, 8152);
+ _lua_setglobal(i1, 8152);
+ STACKTOP = i2;
+ return 1;
+}
+function _lua_pushinteger(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i2 = i2 + 8 | 0;
+ i3 = HEAP32[i2 >> 2] | 0;
+ HEAPF64[i3 >> 3] = +(i1 | 0);
+ HEAP32[i3 + 8 >> 2] = 3;
+ HEAP32[i2 >> 2] = i3 + 16;
+ return;
+}
+function _luaB_rawset(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_checktype(i1, 1, 5);
+ _luaL_checkany(i1, 2);
+ _luaL_checkany(i1, 3);
+ _lua_settop(i1, 3);
+ _lua_rawset(i1, 1);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaE_setdebt(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = i2 + 12 | 0;
+ i2 = i2 + 8 | 0;
+ HEAP32[i2 >> 2] = (HEAP32[i3 >> 2] | 0) - i1 + (HEAP32[i2 >> 2] | 0);
+ HEAP32[i3 >> 2] = i1;
+ return;
+}
+function _luaB_cocreate(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ _luaL_checktype(i1, 1, 6);
+ i3 = _lua_newthread(i1) | 0;
+ _lua_pushvalue(i1, 1);
+ _lua_xmove(i1, i3, 1);
+ STACKTOP = i2;
+ return 1;
+}
+function _io_noclose(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ HEAP32[(_luaL_checkudata(i1, 1, 2832) | 0) + 4 >> 2] = 154;
+ _lua_pushnil(i1);
+ _lua_pushlstring(i1, 2840, 26) | 0;
+ STACKTOP = i2;
+ return 2;
+}
+function _io_fclose(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i1 = _luaL_fileresult(i1, (_fclose(HEAP32[(_luaL_checkudata(i1, 1, 2832) | 0) >> 2] | 0) | 0) == 0 | 0, 0) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _luaL_optnumber(i3, i4, d2) {
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ d2 = +d2;
+ var i1 = 0;
+ i1 = STACKTOP;
+ if ((_lua_type(i3, i4) | 0) >= 1) {
+  d2 = +_luaL_checknumber(i3, i4);
+ }
+ STACKTOP = i1;
+ return +d2;
+}
+function _math_atan2(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, d3 = 0.0;
+ i2 = STACKTOP;
+ d3 = +_luaL_checknumber(i1, 1);
+ _lua_pushnumber(i1, +Math_atan2(+d3, +(+_luaL_checknumber(i1, 2))));
+ STACKTOP = i2;
+ return 1;
+}
+function _luaK_codeABx(i4, i2, i3, i1) {
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ var i5 = 0;
+ i5 = STACKTOP;
+ i4 = _luaK_code(i4, i3 << 6 | i2 | i1 << 14) | 0;
+ STACKTOP = i5;
+ return i4 | 0;
+}
+function _luaF_newCclosure(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ i2 = _luaC_newobj(i2, 38, (i1 << 4) + 16 | 0, 0, 0) | 0;
+ HEAP8[i2 + 6 | 0] = i1;
+ STACKTOP = i3;
+ return i2 | 0;
+}
+function _math_pow(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, d3 = 0.0;
+ i2 = STACKTOP;
+ d3 = +_luaL_checknumber(i1, 1);
+ _lua_pushnumber(i1, +Math_pow(+d3, +(+_luaL_checknumber(i1, 2))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_ldexp(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, d3 = 0.0;
+ i2 = STACKTOP;
+ d3 = +_luaL_checknumber(i1, 1);
+ _lua_pushnumber(i1, +_ldexp(d3, _luaL_checkinteger(i1, 2) | 0));
+ STACKTOP = i2;
+ return 1;
+}
+function _luaF_newupval(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i1 = _luaC_newobj(i1, 10, 32, 0, 0) | 0;
+ HEAP32[i1 + 8 >> 2] = i1 + 16;
+ HEAP32[i1 + 24 >> 2] = 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _lua_pushnumber(i2, d1) {
+ i2 = i2 | 0;
+ d1 = +d1;
+ var i3 = 0;
+ i2 = i2 + 8 | 0;
+ i3 = HEAP32[i2 >> 2] | 0;
+ HEAPF64[i3 >> 3] = d1;
+ HEAP32[i3 + 8 >> 2] = 3;
+ HEAP32[i2 >> 2] = i3 + 16;
+ return;
+}
+function _math_fmod(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, d3 = 0.0;
+ i2 = STACKTOP;
+ d3 = +_luaL_checknumber(i1, 1);
+ _lua_pushnumber(i1, +_fmod(+d3, +(+_luaL_checknumber(i1, 2))));
+ STACKTOP = i2;
+ return 1;
+}
+function _luaG_concaterror(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ i4 = HEAP32[i2 + 8 >> 2] | 0;
+ _luaG_typeerror(i3, (i4 & 15 | 0) == 4 | (i4 | 0) == 3 ? i1 : i2, 1912);
+}
+function _luaB_rawequal(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_checkany(i1, 1);
+ _luaL_checkany(i1, 2);
+ _lua_pushboolean(i1, _lua_rawequal(i1, 1, 2) | 0);
+ STACKTOP = i2;
+ return 1;
+}
+function _db_getuservalue(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((_lua_type(i1, 1) | 0) == 7) {
+  _lua_getuservalue(i1, 1);
+ } else {
+  _lua_pushnil(i1);
+ }
+ STACKTOP = i2;
+ return 1;
+}
+function _strchr(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ i2 = ___strchrnul(i2, i1) | 0;
+ STACKTOP = i3;
+ return ((HEAP8[i2] | 0) == (i1 & 255) << 24 >> 24 ? i2 : 0) | 0;
+}
+function runPostSets() {}
+function _rand_r(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = (Math_imul(HEAP32[i1 >> 2] | 0, 31010991) | 0) + 1735287159 & 2147483647;
+ HEAP32[i1 >> 2] = i2;
+ return i2 | 0;
+}
+function _luaL_checkany(i1, i3) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ if ((_lua_type(i1, i3) | 0) == -1) {
+  _luaL_argerror(i1, i3, 1256) | 0;
+ }
+ STACKTOP = i2;
+ return;
+}
+function _i64Subtract(i2, i4, i1, i3) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 - i3 - (i1 >>> 0 > i2 >>> 0 | 0) >>> 0;
+ return (tempRet0 = i4, i2 - i1 >>> 0 | 0) | 0;
+}
+function _db_getmetatable(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_checkany(i1, 1);
+ if ((_lua_getmetatable(i1, 1) | 0) == 0) {
+  _lua_pushnil(i1);
+ }
+ STACKTOP = i2;
+ return 1;
+}
+function _luaB_rawget(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_checktype(i1, 1, 5);
+ _luaL_checkany(i1, 2);
+ _lua_settop(i1, 2);
+ _lua_rawget(i1, 1);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaB_type(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_checkany(i1, 1);
+ _lua_pushstring(i1, _lua_typename(i1, _lua_type(i1, 1) | 0) | 0) | 0;
+ STACKTOP = i2;
+ return 1;
+}
+function dynCall_iiiii(i5, i4, i3, i2, i1) {
+ i5 = i5 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ return FUNCTION_TABLE_iiiii[i5 & 3](i4 | 0, i3 | 0, i2 | 0, i1 | 0) | 0;
+}
+function _lstop(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ _lua_sethook(i1, 0, 0, 0) | 0;
+ _luaL_error(i1, 200, i2) | 0;
+ STACKTOP = i2;
+ return;
+}
+function _i64Add(i1, i3, i4, i2) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i4 = i1 + i4 >>> 0;
+ return (tempRet0 = i3 + i2 + (i4 >>> 0 < i1 >>> 0 | 0) >>> 0, i4 | 0) | 0;
+}
+function _luaK_ret(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ i4 = STACKTOP;
+ _luaK_code(i3, i2 << 6 | (i1 << 23) + 8388608 | 31) | 0;
+ STACKTOP = i4;
+ return;
+}
+function _strpbrk(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ i1 = i2 + (_strcspn(i2, i1) | 0) | 0;
+ STACKTOP = i3;
+ return ((HEAP8[i1] | 0) != 0 ? i1 : 0) | 0;
+}
+function _luaL_setmetatable(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ _lua_getfield(i1, -1001e3, i2);
+ _lua_setmetatable(i1, -2) | 0;
+ STACKTOP = i3;
+ return;
+}
+function _lua_atpanic(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = (HEAP32[i2 + 12 >> 2] | 0) + 168 | 0;
+ i2 = HEAP32[i3 >> 2] | 0;
+ HEAP32[i3 >> 2] = i1;
+ return i2 | 0;
+}
+function _luaL_newstate() {
+ var i1 = 0, i2 = 0;
+ i2 = STACKTOP;
+ i1 = _lua_newstate(1, 0) | 0;
+ if ((i1 | 0) != 0) {
+  _lua_atpanic(i1, 143) | 0;
+ }
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _luaL_buffinit(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ HEAP32[i1 + 12 >> 2] = i2;
+ HEAP32[i1 >> 2] = i1 + 16;
+ HEAP32[i1 + 8 >> 2] = 0;
+ HEAP32[i1 + 4 >> 2] = 1024;
+ return;
+}
+function _strrchr(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ i2 = ___memrchr(i1, i2, (_strlen(i1 | 0) | 0) + 1 | 0) | 0;
+ STACKTOP = i3;
+ return i2 | 0;
+}
+function _luaK_fixline(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ HEAP32[(HEAP32[(HEAP32[i1 >> 2] | 0) + 20 >> 2] | 0) + ((HEAP32[i1 + 20 >> 2] | 0) + -1 << 2) >> 2] = i2;
+ return;
+}
+function _luaX_lookahead(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i3 = STACKTOP;
+ i2 = _llex(i1, i1 + 40 | 0) | 0;
+ HEAP32[i1 + 32 >> 2] = i2;
+ STACKTOP = i3;
+ return i2 | 0;
+}
+function _f_call(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ _luaD_call(i2, HEAP32[i1 >> 2] | 0, HEAP32[i1 + 4 >> 2] | 0, 0);
+ STACKTOP = i3;
+ return;
+}
+function _io_pclose(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_checkudata(i1, 1, 2832) | 0;
+ i1 = _luaL_execresult(i1, -1) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _luaS_new(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ i2 = _luaS_newlstr(i2, i1, _strlen(i1 | 0) | 0) | 0;
+ STACKTOP = i3;
+ return i2 | 0;
+}
+function _os_getenv(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushstring(i1, _getenv(_luaL_checklstring(i1, 1, 0) | 0) | 0) | 0;
+ STACKTOP = i2;
+ return 1;
+}
+function _math_rad(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +_luaL_checknumber(i1, 1) * .017453292519943295);
+ STACKTOP = i2;
+ return 1;
+}
+function _math_deg(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +_luaL_checknumber(i1, 1) / .017453292519943295);
+ STACKTOP = i2;
+ return 1;
+}
+function _writer(i4, i2, i1, i3) {
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = STACKTOP;
+ _luaL_addlstring(i3, i2, i1);
+ STACKTOP = i4;
+ return 0;
+}
+function _luaL_addstring(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ _luaL_addlstring(i2, i1, _strlen(i1 | 0) | 0);
+ STACKTOP = i3;
+ return;
+}
+function _pcallcont(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i1 = _finishpcall(i1, (_lua_getctx(i1, 0) | 0) == 1 | 0) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _luaopen_coroutine(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_createtable(i1, 0, 6);
+ _luaL_setfuncs(i1, 10656, 0);
+ STACKTOP = i2;
+ return 1;
+}
+function _lua_version(i1) {
+ i1 = i1 | 0;
+ if ((i1 | 0) == 0) {
+  i1 = 920;
+ } else {
+  i1 = HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 176 >> 2] | 0;
+ }
+ return i1 | 0;
+}
+function _lua_pushnil(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i1 = i1 + 8 | 0;
+ i2 = HEAP32[i1 >> 2] | 0;
+ HEAP32[i2 + 8 >> 2] = 0;
+ HEAP32[i1 >> 2] = i2 + 16;
+ return;
+}
+function _math_floor(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +Math_floor(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _laction(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _signal(i1 | 0, 0) | 0;
+ _lua_sethook(HEAP32[48] | 0, 1, 11, 1) | 0;
+ STACKTOP = i2;
+ return;
+}
+function dynCall_iiii(i4, i3, i2, i1) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ return FUNCTION_TABLE_iiii[i4 & 3](i3 | 0, i2 | 0, i1 | 0) | 0;
+}
+function _luaopen_debug(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_createtable(i1, 0, 16);
+ _luaL_setfuncs(i1, 11176, 0);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaopen_bit32(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_createtable(i1, 0, 12);
+ _luaL_setfuncs(i1, 10240, 0);
+ STACKTOP = i2;
+ return 1;
+}
+function _math_sqrt(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +Math_sqrt(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_ceil(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +Math_ceil(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_atan(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +Math_atan(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_asin(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +Math_asin(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_acos(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +Math_acos(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _lua_close(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _close_state(HEAP32[(HEAP32[i1 + 12 >> 2] | 0) + 172 >> 2] | 0);
+ STACKTOP = i2;
+ return;
+}
+function _dothecall(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i2 = STACKTOP;
+ _luaD_call(i1, (HEAP32[i1 + 8 >> 2] | 0) + -32 | 0, 0, 0);
+ STACKTOP = i2;
+ return;
+}
+function _math_tan(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +Math_tan(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_sin(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +Math_sin(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_log10(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +_log10(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_exp(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +Math_exp(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_cos(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +Math_cos(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_abs(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +Math_abs(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_randomseed(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _srand(_luaL_checkunsigned(i1, 1) | 0);
+ _rand() | 0;
+ STACKTOP = i2;
+ return 0;
+}
+function _luaopen_os(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_createtable(i1, 0, 11);
+ _luaL_setfuncs(i1, 5624, 0);
+ STACKTOP = i2;
+ return 1;
+}
+function _math_tanh(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +_tanh(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_sinh(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +_sinh(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _math_cosh(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +_cosh(+(+_luaL_checknumber(i1, 1))));
+ STACKTOP = i2;
+ return 1;
+}
+function _luaB_yield(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i1 = _lua_yieldk(i1, _lua_gettop(i1) | 0, 0, 0) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _luaB_tostring(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _luaL_checkany(i1, 1);
+ _luaL_tolstring(i1, 1, 0) | 0;
+ STACKTOP = i2;
+ return 1;
+}
+function _growstack(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ _luaD_growstack(i2, HEAP32[i1 >> 2] | 0);
+ STACKTOP = i3;
+ return;
+}
+function ___udivdi3(i4, i3, i2, i1) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ i4 = ___udivmoddi4(i4, i3, i2, i1, 0) | 0;
+ return i4 | 0;
+}
+function _b_not(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushunsigned(i1, ~(_luaL_checkunsigned(i1, 1) | 0));
+ STACKTOP = i2;
+ return 1;
+}
+function _luaO_fb2int(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = i1 >>> 3 & 31;
+ if ((i2 | 0) != 0) {
+  i1 = (i1 & 7 | 8) << i2 + -1;
+ }
+ return i1 | 0;
+}
+function _luaB_corunning(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushboolean(i1, _lua_pushthread(i1) | 0);
+ STACKTOP = i2;
+ return 2;
+}
+function stackAlloc(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + i1 | 0;
+ STACKTOP = STACKTOP + 7 & -8;
+ return i2 | 0;
+}
+function _strcoll(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ i2 = _strcmp(i2, i1) | 0;
+ STACKTOP = i3;
+ return i2 | 0;
+}
+function _os_clock(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushnumber(i1, +(_clock() | 0) / 1.0e6);
+ STACKTOP = i2;
+ return 1;
+}
+function _dofilecont(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i1 = (_lua_gettop(i1) | 0) + -1 | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _scalbnl(d2, i1) {
+ d2 = +d2;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ d2 = +_scalbn(d2, i1);
+ STACKTOP = i3;
+ return +d2;
+}
+function _tolower(i1) {
+ i1 = i1 | 0;
+ if ((i1 | 0) < 65) return i1 | 0;
+ if ((i1 | 0) > 90) return i1 | 0;
+ return i1 - 65 + 97 | 0;
+}
+function _lua_gettop(i1) {
+ i1 = i1 | 0;
+ return (HEAP32[i1 + 8 >> 2] | 0) - ((HEAP32[HEAP32[i1 + 16 >> 2] >> 2] | 0) + 16) >> 4 | 0;
+}
+function dynCall_iii(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ return FUNCTION_TABLE_iii[i3 & 1](i2 | 0, i1 | 0) | 0;
+}
+function _str_match(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i1 = _str_find_aux(i1, 0) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _luaM_toobig(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ _luaG_runerror(i1, 4144, i2);
+}
+function _luaK_getlabel(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = HEAP32[i1 + 20 >> 2] | 0;
+ HEAP32[i1 + 24 >> 2] = i2;
+ return i2 | 0;
+}
+function _ldexp(d2, i1) {
+ d2 = +d2;
+ i1 = i1 | 0;
+ var i3 = 0;
+ i3 = STACKTOP;
+ d2 = +_scalbn(d2, i1);
+ STACKTOP = i3;
+ return +d2;
+}
+function _str_find(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ i1 = _str_find_aux(i1, 1) | 0;
+ STACKTOP = i2;
+ return i1 | 0;
+}
+function _db_getregistry(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _lua_pushvalue(i1, -1001e3);
+ STACKTOP = i2;
+ return 1;
+}
+function _luaB_ipairs(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _pairsmeta(i1, 9960, 1, 165);
+ STACKTOP = i2;
+ return 3;
+}
+function _strlen(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = i1;
+ while (HEAP8[i2] | 0) {
+  i2 = i2 + 1 | 0;
+ }
+ return i2 - i1 | 0;
+}
+function _luaB_pairs(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _pairsmeta(i1, 9864, 0, 93);
+ STACKTOP = i2;
+ return 3;
+}
+function setThrew(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ if ((__THREW__ | 0) == 0) {
+  __THREW__ = i1;
+  threwValue = i2;
+ }
+}
+function _io_output(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _g_iofile(i1, 2800, 3512);
+ STACKTOP = i2;
+ return 1;
+}
+function dynCall_vii(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ FUNCTION_TABLE_vii[i3 & 15](i2 | 0, i1 | 0);
+}
+function _io_input(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ _g_iofile(i1, 2776, 3480);
+ STACKTOP = i2;
+ return 1;
+}
+function _semerror(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ HEAP32[i2 + 16 >> 2] = 0;
+ _luaX_syntaxerror(i2, i1);
+}
+function _luaX_syntaxerror(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ _lexerror(i1, i2, HEAP32[i1 + 16 >> 2] | 0);
+}
+function b4(i1, i2, i3, i4) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ abort(4);
+ return 0;
+}
+function _lua_typename(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ return HEAP32[8528 + (i1 + 1 << 2) >> 2] | 0;
+}
+function dynCall_ii(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ return FUNCTION_TABLE_ii[i2 & 255](i1 | 0) | 0;
+}
+function dynCall_vi(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ FUNCTION_TABLE_vi[i2 & 1](i1 | 0);
+}
+function b0(i1, i2, i3) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ abort(0);
+ return 0;
+}
+function _lua_gethookmask(i1) {
+ i1 = i1 | 0;
+ return HEAPU8[i1 + 40 | 0] | 0 | 0;
+}
+function _lua_gethookcount(i1) {
+ i1 = i1 | 0;
+ return HEAP32[i1 + 44 >> 2] | 0;
+}
+function _lua_status(i1) {
+ i1 = i1 | 0;
+ return HEAPU8[i1 + 6 | 0] | 0 | 0;
+}
+function _lua_gethook(i1) {
+ i1 = i1 | 0;
+ return HEAP32[i1 + 52 >> 2] | 0;
+}
+function b5(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ abort(5);
+ return 0;
+}
+function _lua_error(i1) {
+ i1 = i1 | 0;
+ _luaG_errormsg(i1);
+ return 0;
+}
+function b2(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ abort(2);
+}
+function stackRestore(i1) {
+ i1 = i1 | 0;
+ STACKTOP = i1;
+}
+function setTempRet9(i1) {
+ i1 = i1 | 0;
+ tempRet9 = i1;
+}
+function setTempRet8(i1) {
+ i1 = i1 | 0;
+ tempRet8 = i1;
+}
+function setTempRet7(i1) {
+ i1 = i1 | 0;
+ tempRet7 = i1;
+}
+function setTempRet6(i1) {
+ i1 = i1 | 0;
+ tempRet6 = i1;
+}
+function setTempRet5(i1) {
+ i1 = i1 | 0;
+ tempRet5 = i1;
+}
+function setTempRet4(i1) {
+ i1 = i1 | 0;
+ tempRet4 = i1;
+}
+function setTempRet3(i1) {
+ i1 = i1 | 0;
+ tempRet3 = i1;
+}
+function setTempRet2(i1) {
+ i1 = i1 | 0;
+ tempRet2 = i1;
+}
+function setTempRet1(i1) {
+ i1 = i1 | 0;
+ tempRet1 = i1;
+}
+function setTempRet0(i1) {
+ i1 = i1 | 0;
+ tempRet0 = i1;
+}
+function b3(i1) {
+ i1 = i1 | 0;
+ abort(3);
+ return 0;
+}
+function _rand() {
+ return _rand_r(___rand_seed) | 0;
+}
+function stackSave() {
+ return STACKTOP | 0;
+}
+function b1(i1) {
+ i1 = i1 | 0;
+ abort(1);
+}
+
+// EMSCRIPTEN_END_FUNCS
+  var FUNCTION_TABLE_iiii = [b0,_getF,_getS,_generic_reader];
+  var FUNCTION_TABLE_vi = [b1,_laction];
+  var FUNCTION_TABLE_vii = [b2,_lstop,_growstack,_f_call,_resume,_unroll,_f_parser,_dothecall,_f_luaopen,_hookf,b2,b2,b2,b2,b2,b2];
+  var FUNCTION_TABLE_ii = [b3,_io_close,_io_flush,_io_input,_io_lines,_io_open,_io_output,_io_popen,_io_read,_io_tmpfile,_io_type,_io_write,_f_flush,_f_lines,_f_read,_f_seek,_f_setvbuf,_f_write,_f_gc,_f_tostring,_math_abs,_math_acos,_math_asin,_math_atan2,_math_atan,_math_ceil,_math_cosh,_math_cos,_math_deg
+  ,_math_exp,_math_floor,_math_fmod,_math_frexp,_math_ldexp,_math_log10,_math_log,_math_max,_math_min,_math_modf,_math_pow,_math_rad,_math_random,_math_randomseed,_math_sinh,_math_sin,_math_sqrt,_math_tanh,_math_tan,_ll_loadlib,_ll_searchpath,_ll_seeall,_ll_module,_ll_require,_os_clock,_os_date,_os_difftime,_os_execute,_os_exit,_os_getenv
+  ,_os_remove,_os_rename,_os_setlocale,_os_time,_os_tmpname,_str_byte,_str_char,_str_dump,_str_find,_str_format,_gmatch,_str_gsub,_str_len,_str_lower,_str_match,_str_rep,_str_reverse,_str_sub,_str_upper,_tconcat,_maxn,_tinsert,_pack,_unpack,_tremove,_sort,_luaB_assert,_luaB_collectgarbage,_luaB_dofile,_luaB_error
+  ,_luaB_getmetatable,_luaB_ipairs,_luaB_loadfile,_luaB_load,_luaB_next,_luaB_pairs,_luaB_pcall,_luaB_print,_luaB_rawequal,_luaB_rawlen,_luaB_rawget,_luaB_rawset,_luaB_select,_luaB_setmetatable,_luaB_tonumber,_luaB_tostring,_luaB_type,_luaB_xpcall,_b_arshift,_b_and,_b_not,_b_or,_b_xor,_b_test,_b_extract,_b_lrot,_b_lshift,_b_replace,_b_rrot,_b_rshift
+  ,_luaB_cocreate,_luaB_coresume,_luaB_corunning,_luaB_costatus,_luaB_cowrap,_luaB_yield,_db_debug,_db_getuservalue,_db_gethook,_db_getinfo,_db_getlocal,_db_getregistry,_db_getmetatable,_db_getupvalue,_db_upvaluejoin,_db_upvalueid,_db_setuservalue,_db_sethook,_db_setlocal,_db_setmetatable,_db_setupvalue,_db_traceback,_pmain,_traceback,_panic,_luaopen_base,_luaopen_package,_luaopen_coroutine,_luaopen_table,_luaopen_io
+  ,_luaopen_os,_luaopen_string,_luaopen_bit32,_luaopen_math,_luaopen_debug,_io_noclose,_io_readline,_io_fclose,_io_pclose,_gctm,_searcher_preload,_searcher_Lua,_searcher_C,_searcher_Croot,_gmatch_aux,_dofilecont,_ipairsaux,_pcallcont,_luaB_auxwrap,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3
+  ,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3
+  ,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3
+  ,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3,b3];
+  var FUNCTION_TABLE_iiiii = [b4,_l_alloc,_writer,b4];
+  var FUNCTION_TABLE_iii = [b5,_lua_newstate];
+
+  return { _testSetjmp: _testSetjmp, _i64Subtract: _i64Subtract, _free: _free, _main: _main, _rand_r: _rand_r, _realloc: _realloc, _i64Add: _i64Add, _tolower: _tolower, _saveSetjmp: _saveSetjmp, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, _strlen: _strlen, _rand: _rand, _bitshift64Shl: _bitshift64Shl, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, setTempRet1: setTempRet1, setTempRet2: setTempRet2, setTempRet3: setTempRet3, setTempRet4: setTempRet4, setTempRet5: setTempRet5, setTempRet6: setTempRet6, setTempRet7: setTempRet7, setTempRet8: setTempRet8, setTempRet9: setTempRet9, dynCall_iiii: dynCall_iiii, dynCall_vi: dynCall_vi, dynCall_vii: dynCall_vii, dynCall_ii: dynCall_ii, dynCall_iiiii: dynCall_iiiii, dynCall_iii: dynCall_iii };
+})
+// EMSCRIPTEN_END_ASM
+({ "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array }, { "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "invoke_iiii": invoke_iiii, "invoke_vi": invoke_vi, "invoke_vii": invoke_vii, "invoke_ii": invoke_ii, "invoke_iiiii": invoke_iiiii, "invoke_iii": invoke_iii, "_isalnum": _isalnum, "_fabs": _fabs, "_frexp": _frexp, "_exp": _exp, "_fread": _fread, "__reallyNegative": __reallyNegative, "_longjmp": _longjmp, "__addDays": __addDays, "_fsync": _fsync, "_signal": _signal, "_rename": _rename, "_sbrk": _sbrk, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_sinh": _sinh, "_sysconf": _sysconf, "_close": _close, "_ferror": _ferror, "_clock": _clock, "_cos": _cos, "_tanh": _tanh, "_unlink": _unlink, "_write": _write, "__isLeapYear": __isLeapYear, "_ftell": _ftell, "_isupper": _isupper, "_gmtime_r": _gmtime_r, "_islower": _islower, "_tmpnam": _tmpnam, "_tmpfile": _tmpfile, "_send": _send, "_abort": _abort, "_setvbuf": _setvbuf, "_atan2": _atan2, "_setlocale": _setlocale, "_isgraph": _isgraph, "_modf": _modf, "_strerror_r": _strerror_r, "_fscanf": _fscanf, "___setErrNo": ___setErrNo, "_isalpha": _isalpha, "_srand": _srand, "_mktime": _mktime, "_putchar": _putchar, "_gmtime": _gmtime, "_localeconv": _localeconv, "_sprintf": _sprintf, "_localtime": _localtime, "_read": _read, "_fwrite": _fwrite, "_time": _time, "_fprintf": _fprintf, "_exit": _exit, "_freopen": _freopen, "_llvm_pow_f64": _llvm_pow_f64, "_fgetc": _fgetc, "_fmod": _fmod, "_lseek": _lseek, "_rmdir": _rmdir, "_asin": _asin, "_floor": _floor, "_pwrite": _pwrite, "_localtime_r": _localtime_r, "_tzset": _tzset, "_open": _open, "_remove": _remove, "_snprintf": _snprintf, "__scanString": __scanString, "_strftime": _strftime, "_fseek": _fseek, "_iscntrl": _iscntrl, "_isxdigit": _isxdigit, "_fclose": _fclose, "_log": _log, "_recv": _recv, "_tan": _tan, "_copysign": _copysign, "__getFloat": __getFloat, "_fputc": _fputc, "_ispunct": _ispunct, "_ceil": _ceil, "_isspace": _isspace, "_fopen": _fopen, "_sin": _sin, "_acos": _acos, "_cosh": _cosh, "___buildEnvironment": ___buildEnvironment, "_difftime": _difftime, "_ungetc": _ungetc, "_system": _system, "_fflush": _fflush, "_log10": _log10, "_fileno": _fileno, "__exit": __exit, "__arraySum": __arraySum, "_fgets": _fgets, "_atan": _atan, "_pread": _pread, "_mkport": _mkport, "_toupper": _toupper, "_feof": _feof, "___errno_location": ___errno_location, "_clearerr": _clearerr, "_getenv": _getenv, "_strerror": _strerror, "_emscripten_longjmp": _emscripten_longjmp, "__formatString": __formatString, "_fputs": _fputs, "_sqrt": _sqrt, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "cttz_i8": cttz_i8, "ctlz_i8": ctlz_i8, "___rand_seed": ___rand_seed, "NaN": NaN, "Infinity": Infinity, "_stderr": _stderr, "_stdin": _stdin, "_stdout": _stdout }, buffer);
+var _testSetjmp = Module["_testSetjmp"] = asm["_testSetjmp"];
+var _i64Subtract = Module["_i64Subtract"] = asm["_i64Subtract"];
+var _free = Module["_free"] = asm["_free"];
+var _main = Module["_main"] = asm["_main"];
+var _rand_r = Module["_rand_r"] = asm["_rand_r"];
+var _realloc = Module["_realloc"] = asm["_realloc"];
+var _i64Add = Module["_i64Add"] = asm["_i64Add"];
+var _tolower = Module["_tolower"] = asm["_tolower"];
+var _saveSetjmp = Module["_saveSetjmp"] = asm["_saveSetjmp"];
+var _memset = Module["_memset"] = asm["_memset"];
+var _malloc = Module["_malloc"] = asm["_malloc"];
+var _memcpy = Module["_memcpy"] = asm["_memcpy"];
+var _strlen = Module["_strlen"] = asm["_strlen"];
+var _rand = Module["_rand"] = asm["_rand"];
+var _bitshift64Shl = Module["_bitshift64Shl"] = asm["_bitshift64Shl"];
+var runPostSets = Module["runPostSets"] = asm["runPostSets"];
+var dynCall_iiii = Module["dynCall_iiii"] = asm["dynCall_iiii"];
+var dynCall_vi = Module["dynCall_vi"] = asm["dynCall_vi"];
+var dynCall_vii = Module["dynCall_vii"] = asm["dynCall_vii"];
+var dynCall_ii = Module["dynCall_ii"] = asm["dynCall_ii"];
+var dynCall_iiiii = Module["dynCall_iiiii"] = asm["dynCall_iiiii"];
+var dynCall_iii = Module["dynCall_iii"] = asm["dynCall_iii"];
+
+Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
+Runtime.stackSave = function() { return asm['stackSave']() };
+Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
+
+
+// TODO: strip out parts of this we do not need
+
+//======= begin closure i64 code =======
+
+// Copyright 2009 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Defines a Long class for representing a 64-bit two's-complement
+ * integer value, which faithfully simulates the behavior of a Java "long". This
+ * implementation is derived from LongLib in GWT.
+ *
+ */
+
+var i64Math = (function() { // Emscripten wrapper
+  var goog = { math: {} };
+
+
+  /**
+   * Constructs a 64-bit two's-complement integer, given its low and high 32-bit
+   * values as *signed* integers.  See the from* functions below for more
+   * convenient ways of constructing Longs.
+   *
+   * The internal representation of a long is the two given signed, 32-bit values.
+   * We use 32-bit pieces because these are the size of integers on which
+   * Javascript performs bit-operations.  For operations like addition and
+   * multiplication, we split each number into 16-bit pieces, which can easily be
+   * multiplied within Javascript's floating-point representation without overflow
+   * or change in sign.
+   *
+   * In the algorithms below, we frequently reduce the negative case to the
+   * positive case by negating the input(s) and then post-processing the result.
+   * Note that we must ALWAYS check specially whether those values are MIN_VALUE
+   * (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
+   * a positive number, it overflows back into a negative).  Not handling this
+   * case would often result in infinite recursion.
+   *
+   * @param {number} low  The low (signed) 32 bits of the long.
+   * @param {number} high  The high (signed) 32 bits of the long.
+   * @constructor
+   */
+  goog.math.Long = function(low, high) {
+    /**
+     * @type {number}
+     * @private
+     */
+    this.low_ = low | 0;  // force into 32 signed bits.
+
+    /**
+     * @type {number}
+     * @private
+     */
+    this.high_ = high | 0;  // force into 32 signed bits.
+  };
+
+
+  // NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the
+  // from* methods on which they depend.
+
+
+  /**
+   * A cache of the Long representations of small integer values.
+   * @type {!Object}
+   * @private
+   */
+  goog.math.Long.IntCache_ = {};
+
+
+  /**
+   * Returns a Long representing the given (32-bit) integer value.
+   * @param {number} value The 32-bit integer in question.
+   * @return {!goog.math.Long} The corresponding Long value.
+   */
+  goog.math.Long.fromInt = function(value) {
+    if (-128 <= value && value < 128) {
+      var cachedObj = goog.math.Long.IntCache_[value];
+      if (cachedObj) {
+        return cachedObj;
+      }
+    }
+
+    var obj = new goog.math.Long(value | 0, value < 0 ? -1 : 0);
+    if (-128 <= value && value < 128) {
+      goog.math.Long.IntCache_[value] = obj;
+    }
+    return obj;
+  };
+
+
+  /**
+   * Returns a Long representing the given value, provided that it is a finite
+   * number.  Otherwise, zero is returned.
+   * @param {number} value The number in question.
+   * @return {!goog.math.Long} The corresponding Long value.
+   */
+  goog.math.Long.fromNumber = function(value) {
+    if (isNaN(value) || !isFinite(value)) {
+      return goog.math.Long.ZERO;
+    } else if (value <= -goog.math.Long.TWO_PWR_63_DBL_) {
+      return goog.math.Long.MIN_VALUE;
+    } else if (value + 1 >= goog.math.Long.TWO_PWR_63_DBL_) {
+      return goog.math.Long.MAX_VALUE;
+    } else if (value < 0) {
+      return goog.math.Long.fromNumber(-value).negate();
+    } else {
+      return new goog.math.Long(
+          (value % goog.math.Long.TWO_PWR_32_DBL_) | 0,
+          (value / goog.math.Long.TWO_PWR_32_DBL_) | 0);
+    }
+  };
+
+
+  /**
+   * Returns a Long representing the 64-bit integer that comes by concatenating
+   * the given high and low bits.  Each is assumed to use 32 bits.
+   * @param {number} lowBits The low 32-bits.
+   * @param {number} highBits The high 32-bits.
+   * @return {!goog.math.Long} The corresponding Long value.
+   */
+  goog.math.Long.fromBits = function(lowBits, highBits) {
+    return new goog.math.Long(lowBits, highBits);
+  };
+
+
+  /**
+   * Returns a Long representation of the given string, written using the given
+   * radix.
+   * @param {string} str The textual representation of the Long.
+   * @param {number=} opt_radix The radix in which the text is written.
+   * @return {!goog.math.Long} The corresponding Long value.
+   */
+  goog.math.Long.fromString = function(str, opt_radix) {
+    if (str.length == 0) {
+      throw Error('number format error: empty string');
+    }
+
+    var radix = opt_radix || 10;
+    if (radix < 2 || 36 < radix) {
+      throw Error('radix out of range: ' + radix);
+    }
+
+    if (str.charAt(0) == '-') {
+      return goog.math.Long.fromString(str.substring(1), radix).negate();
+    } else if (str.indexOf('-') >= 0) {
+      throw Error('number format error: interior "-" character: ' + str);
+    }
+
+    // Do several (8) digits each time through the loop, so as to
+    // minimize the calls to the very expensive emulated div.
+    var radixToPower = goog.math.Long.fromNumber(Math.pow(radix, 8));
+
+    var result = goog.math.Long.ZERO;
+    for (var i = 0; i < str.length; i += 8) {
+      var size = Math.min(8, str.length - i);
+      var value = parseInt(str.substring(i, i + size), radix);
+      if (size < 8) {
+        var power = goog.math.Long.fromNumber(Math.pow(radix, size));
+        result = result.multiply(power).add(goog.math.Long.fromNumber(value));
+      } else {
+        result = result.multiply(radixToPower);
+        result = result.add(goog.math.Long.fromNumber(value));
+      }
+    }
+    return result;
+  };
+
+
+  // NOTE: the compiler should inline these constant values below and then remove
+  // these variables, so there should be no runtime penalty for these.
+
+
+  /**
+   * Number used repeated below in calculations.  This must appear before the
+   * first call to any from* function below.
+   * @type {number}
+   * @private
+   */
+  goog.math.Long.TWO_PWR_16_DBL_ = 1 << 16;
+
+
+  /**
+   * @type {number}
+   * @private
+   */
+  goog.math.Long.TWO_PWR_24_DBL_ = 1 << 24;
+
+
+  /**
+   * @type {number}
+   * @private
+   */
+  goog.math.Long.TWO_PWR_32_DBL_ =
+      goog.math.Long.TWO_PWR_16_DBL_ * goog.math.Long.TWO_PWR_16_DBL_;
+
+
+  /**
+   * @type {number}
+   * @private
+   */
+  goog.math.Long.TWO_PWR_31_DBL_ =
+      goog.math.Long.TWO_PWR_32_DBL_ / 2;
+
+
+  /**
+   * @type {number}
+   * @private
+   */
+  goog.math.Long.TWO_PWR_48_DBL_ =
+      goog.math.Long.TWO_PWR_32_DBL_ * goog.math.Long.TWO_PWR_16_DBL_;
+
+
+  /**
+   * @type {number}
+   * @private
+   */
+  goog.math.Long.TWO_PWR_64_DBL_ =
+      goog.math.Long.TWO_PWR_32_DBL_ * goog.math.Long.TWO_PWR_32_DBL_;
+
+
+  /**
+   * @type {number}
+   * @private
+   */
+  goog.math.Long.TWO_PWR_63_DBL_ =
+      goog.math.Long.TWO_PWR_64_DBL_ / 2;
+
+
+  /** @type {!goog.math.Long} */
+  goog.math.Long.ZERO = goog.math.Long.fromInt(0);
+
+
+  /** @type {!goog.math.Long} */
+  goog.math.Long.ONE = goog.math.Long.fromInt(1);
+
+
+  /** @type {!goog.math.Long} */
+  goog.math.Long.NEG_ONE = goog.math.Long.fromInt(-1);
+
+
+  /** @type {!goog.math.Long} */
+  goog.math.Long.MAX_VALUE =
+      goog.math.Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0);
+
+
+  /** @type {!goog.math.Long} */
+  goog.math.Long.MIN_VALUE = goog.math.Long.fromBits(0, 0x80000000 | 0);
+
+
+  /**
+   * @type {!goog.math.Long}
+   * @private
+   */
+  goog.math.Long.TWO_PWR_24_ = goog.math.Long.fromInt(1 << 24);
+
+
+  /** @return {number} The value, assuming it is a 32-bit integer. */
+  goog.math.Long.prototype.toInt = function() {
+    return this.low_;
+  };
+
+
+  /** @return {number} The closest floating-point representation to this value. */
+  goog.math.Long.prototype.toNumber = function() {
+    return this.high_ * goog.math.Long.TWO_PWR_32_DBL_ +
+           this.getLowBitsUnsigned();
+  };
+
+
+  /**
+   * @param {number=} opt_radix The radix in which the text should be written.
+   * @return {string} The textual representation of this value.
+   */
+  goog.math.Long.prototype.toString = function(opt_radix) {
+    var radix = opt_radix || 10;
+    if (radix < 2 || 36 < radix) {
+      throw Error('radix out of range: ' + radix);
+    }
+
+    if (this.isZero()) {
+      return '0';
+    }
+
+    if (this.isNegative()) {
+      if (this.equals(goog.math.Long.MIN_VALUE)) {
+        // We need to change the Long value before it can be negated, so we remove
+        // the bottom-most digit in this base and then recurse to do the rest.
+        var radixLong = goog.math.Long.fromNumber(radix);
+        var div = this.div(radixLong);
+        var rem = div.multiply(radixLong).subtract(this);
+        return div.toString(radix) + rem.toInt().toString(radix);
+      } else {
+        return '-' + this.negate().toString(radix);
+      }
+    }
+
+    // Do several (6) digits each time through the loop, so as to
+    // minimize the calls to the very expensive emulated div.
+    var radixToPower = goog.math.Long.fromNumber(Math.pow(radix, 6));
+
+    var rem = this;
+    var result = '';
+    while (true) {
+      var remDiv = rem.div(radixToPower);
+      var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt();
+      var digits = intval.toString(radix);
+
+      rem = remDiv;
+      if (rem.isZero()) {
+        return digits + result;
+      } else {
+        while (digits.length < 6) {
+          digits = '0' + digits;
+        }
+        result = '' + digits + result;
+      }
+    }
+  };
+
+
+  /** @return {number} The high 32-bits as a signed value. */
+  goog.math.Long.prototype.getHighBits = function() {
+    return this.high_;
+  };
+
+
+  /** @return {number} The low 32-bits as a signed value. */
+  goog.math.Long.prototype.getLowBits = function() {
+    return this.low_;
+  };
+
+
+  /** @return {number} The low 32-bits as an unsigned value. */
+  goog.math.Long.prototype.getLowBitsUnsigned = function() {
+    return (this.low_ >= 0) ?
+        this.low_ : goog.math.Long.TWO_PWR_32_DBL_ + this.low_;
+  };
+
+
+  /**
+   * @return {number} Returns the number of bits needed to represent the absolute
+   *     value of this Long.
+   */
+  goog.math.Long.prototype.getNumBitsAbs = function() {
+    if (this.isNegative()) {
+      if (this.equals(goog.math.Long.MIN_VALUE)) {
+        return 64;
+      } else {
+        return this.negate().getNumBitsAbs();
+      }
+    } else {
+      var val = this.high_ != 0 ? this.high_ : this.low_;
+      for (var bit = 31; bit > 0; bit--) {
+        if ((val & (1 << bit)) != 0) {
+          break;
+        }
+      }
+      return this.high_ != 0 ? bit + 33 : bit + 1;
+    }
+  };
+
+
+  /** @return {boolean} Whether this value is zero. */
+  goog.math.Long.prototype.isZero = function() {
+    return this.high_ == 0 && this.low_ == 0;
+  };
+
+
+  /** @return {boolean} Whether this value is negative. */
+  goog.math.Long.prototype.isNegative = function() {
+    return this.high_ < 0;
+  };
+
+
+  /** @return {boolean} Whether this value is odd. */
+  goog.math.Long.prototype.isOdd = function() {
+    return (this.low_ & 1) == 1;
+  };
+
+
+  /**
+   * @param {goog.math.Long} other Long to compare against.
+   * @return {boolean} Whether this Long equals the other.
+   */
+  goog.math.Long.prototype.equals = function(other) {
+    return (this.high_ == other.high_) && (this.low_ == other.low_);
+  };
+
+
+  /**
+   * @param {goog.math.Long} other Long to compare against.
+   * @return {boolean} Whether this Long does not equal the other.
+   */
+  goog.math.Long.prototype.notEquals = function(other) {
+    return (this.high_ != other.high_) || (this.low_ != other.low_);
+  };
+
+
+  /**
+   * @param {goog.math.Long} other Long to compare against.
+   * @return {boolean} Whether this Long is less than the other.
+   */
+  goog.math.Long.prototype.lessThan = function(other) {
+    return this.compare(other) < 0;
+  };
+
+
+  /**
+   * @param {goog.math.Long} other Long to compare against.
+   * @return {boolean} Whether this Long is less than or equal to the other.
+   */
+  goog.math.Long.prototype.lessThanOrEqual = function(other) {
+    return this.compare(other) <= 0;
+  };
+
+
+  /**
+   * @param {goog.math.Long} other Long to compare against.
+   * @return {boolean} Whether this Long is greater than the other.
+   */
+  goog.math.Long.prototype.greaterThan = function(other) {
+    return this.compare(other) > 0;
+  };
+
+
+  /**
+   * @param {goog.math.Long} other Long to compare against.
+   * @return {boolean} Whether this Long is greater than or equal to the other.
+   */
+  goog.math.Long.prototype.greaterThanOrEqual = function(other) {
+    return this.compare(other) >= 0;
+  };
+
+
+  /**
+   * Compares this Long with the given one.
+   * @param {goog.math.Long} other Long to compare against.
+   * @return {number} 0 if they are the same, 1 if the this is greater, and -1
+   *     if the given one is greater.
+   */
+  goog.math.Long.prototype.compare = function(other) {
+    if (this.equals(other)) {
+      return 0;
+    }
+
+    var thisNeg = this.isNegative();
+    var otherNeg = other.isNegative();
+    if (thisNeg && !otherNeg) {
+      return -1;
+    }
+    if (!thisNeg && otherNeg) {
+      return 1;
+    }
+
+    // at this point, the signs are the same, so subtraction will not overflow
+    if (this.subtract(other).isNegative()) {
+      return -1;
+    } else {
+      return 1;
+    }
+  };
+
+
+  /** @return {!goog.math.Long} The negation of this value. */
+  goog.math.Long.prototype.negate = function() {
+    if (this.equals(goog.math.Long.MIN_VALUE)) {
+      return goog.math.Long.MIN_VALUE;
+    } else {
+      return this.not().add(goog.math.Long.ONE);
+    }
+  };
+
+
+  /**
+   * Returns the sum of this and the given Long.
+   * @param {goog.math.Long} other Long to add to this one.
+   * @return {!goog.math.Long} The sum of this and the given Long.
+   */
+  goog.math.Long.prototype.add = function(other) {
+    // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
+
+    var a48 = this.high_ >>> 16;
+    var a32 = this.high_ & 0xFFFF;
+    var a16 = this.low_ >>> 16;
+    var a00 = this.low_ & 0xFFFF;
+
+    var b48 = other.high_ >>> 16;
+    var b32 = other.high_ & 0xFFFF;
+    var b16 = other.low_ >>> 16;
+    var b00 = other.low_ & 0xFFFF;
+
+    var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
+    c00 += a00 + b00;
+    c16 += c00 >>> 16;
+    c00 &= 0xFFFF;
+    c16 += a16 + b16;
+    c32 += c16 >>> 16;
+    c16 &= 0xFFFF;
+    c32 += a32 + b32;
+    c48 += c32 >>> 16;
+    c32 &= 0xFFFF;
+    c48 += a48 + b48;
+    c48 &= 0xFFFF;
+    return goog.math.Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32);
+  };
+
+
+  /**
+   * Returns the difference of this and the given Long.
+   * @param {goog.math.Long} other Long to subtract from this.
+   * @return {!goog.math.Long} The difference of this and the given Long.
+   */
+  goog.math.Long.prototype.subtract = function(other) {
+    return this.add(other.negate());
+  };
+
+
+  /**
+   * Returns the product of this and the given long.
+   * @param {goog.math.Long} other Long to multiply with this.
+   * @return {!goog.math.Long} The product of this and the other.
+   */
+  goog.math.Long.prototype.multiply = function(other) {
+    if (this.isZero()) {
+      return goog.math.Long.ZERO;
+    } else if (other.isZero()) {
+      return goog.math.Long.ZERO;
+    }
+
+    if (this.equals(goog.math.Long.MIN_VALUE)) {
+      return other.isOdd() ? goog.math.Long.MIN_VALUE : goog.math.Long.ZERO;
+    } else if (other.equals(goog.math.Long.MIN_VALUE)) {
+      return this.isOdd() ? goog.math.Long.MIN_VALUE : goog.math.Long.ZERO;
+    }
+
+    if (this.isNegative()) {
+      if (other.isNegative()) {
+        return this.negate().multiply(other.negate());
+      } else {
+        return this.negate().multiply(other).negate();
+      }
+    } else if (other.isNegative()) {
+      return this.multiply(other.negate()).negate();
+    }
+
+    // If both longs are small, use float multiplication
+    if (this.lessThan(goog.math.Long.TWO_PWR_24_) &&
+        other.lessThan(goog.math.Long.TWO_PWR_24_)) {
+      return goog.math.Long.fromNumber(this.toNumber() * other.toNumber());
+    }
+
+    // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
+    // We can skip products that would overflow.
+
+    var a48 = this.high_ >>> 16;
+    var a32 = this.high_ & 0xFFFF;
+    var a16 = this.low_ >>> 16;
+    var a00 = this.low_ & 0xFFFF;
+
+    var b48 = other.high_ >>> 16;
+    var b32 = other.high_ & 0xFFFF;
+    var b16 = other.low_ >>> 16;
+    var b00 = other.low_ & 0xFFFF;
+
+    var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
+    c00 += a00 * b00;
+    c16 += c00 >>> 16;
+    c00 &= 0xFFFF;
+    c16 += a16 * b00;
+    c32 += c16 >>> 16;
+    c16 &= 0xFFFF;
+    c16 += a00 * b16;
+    c32 += c16 >>> 16;
+    c16 &= 0xFFFF;
+    c32 += a32 * b00;
+    c48 += c32 >>> 16;
+    c32 &= 0xFFFF;
+    c32 += a16 * b16;
+    c48 += c32 >>> 16;
+    c32 &= 0xFFFF;
+    c32 += a00 * b32;
+    c48 += c32 >>> 16;
+    c32 &= 0xFFFF;
+    c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
+    c48 &= 0xFFFF;
+    return goog.math.Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32);
+  };
+
+
+  /**
+   * Returns this Long divided by the given one.
+   * @param {goog.math.Long} other Long by which to divide.
+   * @return {!goog.math.Long} This Long divided by the given one.
+   */
+  goog.math.Long.prototype.div = function(other) {
+    if (other.isZero()) {
+      throw Error('division by zero');
+    } else if (this.isZero()) {
+      return goog.math.Long.ZERO;
+    }
+
+    if (this.equals(goog.math.Long.MIN_VALUE)) {
+      if (other.equals(goog.math.Long.ONE) ||
+          other.equals(goog.math.Long.NEG_ONE)) {
+        return goog.math.Long.MIN_VALUE;  // recall that -MIN_VALUE == MIN_VALUE
+      } else if (other.equals(goog.math.Long.MIN_VALUE)) {
+        return goog.math.Long.ONE;
+      } else {
+        // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
+        var halfThis = this.shiftRight(1);
+        var approx = halfThis.div(other).shiftLeft(1);
+        if (approx.equals(goog.math.Long.ZERO)) {
+          return other.isNegative() ? goog.math.Long.ONE : goog.math.Long.NEG_ONE;
+        } else {
+          var rem = this.subtract(other.multiply(approx));
+          var result = approx.add(rem.div(other));
+          return result;
+        }
+      }
+    } else if (other.equals(goog.math.Long.MIN_VALUE)) {
+      return goog.math.Long.ZERO;
+    }
+
+    if (this.isNegative()) {
+      if (other.isNegative()) {
+        return this.negate().div(other.negate());
+      } else {
+        return this.negate().div(other).negate();
+      }
+    } else if (other.isNegative()) {
+      return this.div(other.negate()).negate();
+    }
+
+    // Repeat the following until the remainder is less than other:  find a
+    // floating-point that approximates remainder / other *from below*, add this
+    // into the result, and subtract it from the remainder.  It is critical that
+    // the approximate value is less than or equal to the real value so that the
+    // remainder never becomes negative.
+    var res = goog.math.Long.ZERO;
+    var rem = this;
+    while (rem.greaterThanOrEqual(other)) {
+      // Approximate the result of division. This may be a little greater or
+      // smaller than the actual value.
+      var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber()));
+
+      // We will tweak the approximate result by changing it in the 48-th digit or
+      // the smallest non-fractional digit, whichever is larger.
+      var log2 = Math.ceil(Math.log(approx) / Math.LN2);
+      var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48);
+
+      // Decrease the approximation until it is smaller than the remainder.  Note
+      // that if it is too large, the product overflows and is negative.
+      var approxRes = goog.math.Long.fromNumber(approx);
+      var approxRem = approxRes.multiply(other);
+      while (approxRem.isNegative() || approxRem.greaterThan(rem)) {
+        approx -= delta;
+        approxRes = goog.math.Long.fromNumber(approx);
+        approxRem = approxRes.multiply(other);
+      }
+
+      // We know the answer can't be zero... and actually, zero would cause
+      // infinite recursion since we would make no progress.
+      if (approxRes.isZero()) {
+        approxRes = goog.math.Long.ONE;
+      }
+
+      res = res.add(approxRes);
+      rem = rem.subtract(approxRem);
+    }
+    return res;
+  };
+
+
+  /**
+   * Returns this Long modulo the given one.
+   * @param {goog.math.Long} other Long by which to mod.
+   * @return {!goog.math.Long} This Long modulo the given one.
+   */
+  goog.math.Long.prototype.modulo = function(other) {
+    return this.subtract(this.div(other).multiply(other));
+  };
+
+
+  /** @return {!goog.math.Long} The bitwise-NOT of this value. */
+  goog.math.Long.prototype.not = function() {
+    return goog.math.Long.fromBits(~this.low_, ~this.high_);
+  };
+
+
+  /**
+   * Returns the bitwise-AND of this Long and the given one.
+   * @param {goog.math.Long} other The Long with which to AND.
+   * @return {!goog.math.Long} The bitwise-AND of this and the other.
+   */
+  goog.math.Long.prototype.and = function(other) {
+    return goog.math.Long.fromBits(this.low_ & other.low_,
+                                   this.high_ & other.high_);
+  };
+
+
+  /**
+   * Returns the bitwise-OR of this Long and the given one.
+   * @param {goog.math.Long} other The Long with which to OR.
+   * @return {!goog.math.Long} The bitwise-OR of this and the other.
+   */
+  goog.math.Long.prototype.or = function(other) {
+    return goog.math.Long.fromBits(this.low_ | other.low_,
+                                   this.high_ | other.high_);
+  };
+
+
+  /**
+   * Returns the bitwise-XOR of this Long and the given one.
+   * @param {goog.math.Long} other The Long with which to XOR.
+   * @return {!goog.math.Long} The bitwise-XOR of this and the other.
+   */
+  goog.math.Long.prototype.xor = function(other) {
+    return goog.math.Long.fromBits(this.low_ ^ other.low_,
+                                   this.high_ ^ other.high_);
+  };
+
+
+  /**
+   * Returns this Long with bits shifted to the left by the given amount.
+   * @param {number} numBits The number of bits by which to shift.
+   * @return {!goog.math.Long} This shifted to the left by the given amount.
+   */
+  goog.math.Long.prototype.shiftLeft = function(numBits) {
+    numBits &= 63;
+    if (numBits == 0) {
+      return this;
+    } else {
+      var low = this.low_;
+      if (numBits < 32) {
+        var high = this.high_;
+        return goog.math.Long.fromBits(
+            low << numBits,
+            (high << numBits) | (low >>> (32 - numBits)));
+      } else {
+        return goog.math.Long.fromBits(0, low << (numBits - 32));
+      }
+    }
+  };
+
+
+  /**
+   * Returns this Long with bits shifted to the right by the given amount.
+   * @param {number} numBits The number of bits by which to shift.
+   * @return {!goog.math.Long} This shifted to the right by the given amount.
+   */
+  goog.math.Long.prototype.shiftRight = function(numBits) {
+    numBits &= 63;
+    if (numBits == 0) {
+      return this;
+    } else {
+      var high = this.high_;
+      if (numBits < 32) {
+        var low = this.low_;
+        return goog.math.Long.fromBits(
+            (low >>> numBits) | (high << (32 - numBits)),
+            high >> numBits);
+      } else {
+        return goog.math.Long.fromBits(
+            high >> (numBits - 32),
+            high >= 0 ? 0 : -1);
+      }
+    }
+  };
+
+
+  /**
+   * Returns this Long with bits shifted to the right by the given amount, with
+   * the new top bits matching the current sign bit.
+   * @param {number} numBits The number of bits by which to shift.
+   * @return {!goog.math.Long} This shifted to the right by the given amount, with
+   *     zeros placed into the new leading bits.
+   */
+  goog.math.Long.prototype.shiftRightUnsigned = function(numBits) {
+    numBits &= 63;
+    if (numBits == 0) {
+      return this;
+    } else {
+      var high = this.high_;
+      if (numBits < 32) {
+        var low = this.low_;
+        return goog.math.Long.fromBits(
+            (low >>> numBits) | (high << (32 - numBits)),
+            high >>> numBits);
+      } else if (numBits == 32) {
+        return goog.math.Long.fromBits(high, 0);
+      } else {
+        return goog.math.Long.fromBits(high >>> (numBits - 32), 0);
+      }
+    }
+  };
+
+  //======= begin jsbn =======
+
+  var navigator = { appName: 'Modern Browser' }; // polyfill a little
+
+  // Copyright (c) 2005  Tom Wu
+  // All Rights Reserved.
+  // http://www-cs-students.stanford.edu/~tjw/jsbn/
+
+  /*
+   * Copyright (c) 2003-2005  Tom Wu
+   * All Rights Reserved.
+   *
+   * Permission is hereby granted, free of charge, to any person obtaining
+   * a copy of this software and associated documentation files (the
+   * "Software"), to deal in the Software without restriction, including
+   * without limitation the rights to use, copy, modify, merge, publish,
+   * distribute, sublicense, and/or sell copies of the Software, and to
+   * permit persons to whom the Software is furnished to do so, subject to
+   * the following conditions:
+   *
+   * The above copyright notice and this permission notice shall be
+   * included in all copies or substantial portions of the Software.
+   *
+   * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+   * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+   * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+   *
+   * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+   * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+   * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+   * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+   * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+   *
+   * In addition, the following condition applies:
+   *
+   * All redistributions must retain an intact copy of this copyright notice
+   * and disclaimer.
+   */
+
+  // Basic JavaScript BN library - subset useful for RSA encryption.
+
+  // Bits per digit
+  var dbits;
+
+  // JavaScript engine analysis
+  var canary = 0xdeadbeefcafe;
+  var j_lm = ((canary&0xffffff)==0xefcafe);
+
+  // (public) Constructor
+  function BigInteger(a,b,c) {
+    if(a != null)
+      if("number" == typeof a) this.fromNumber(a,b,c);
+      else if(b == null && "string" != typeof a) this.fromString(a,256);
+      else this.fromString(a,b);
+  }
+
+  // return new, unset BigInteger
+  function nbi() { return new BigInteger(null); }
+
+  // am: Compute w_j += (x*this_i), propagate carries,
+  // c is initial carry, returns final carry.
+  // c < 3*dvalue, x < 2*dvalue, this_i < dvalue
+  // We need to select the fastest one that works in this environment.
+
+  // am1: use a single mult and divide to get the high bits,
+  // max digit bits should be 26 because
+  // max internal value = 2*dvalue^2-2*dvalue (< 2^53)
+  function am1(i,x,w,j,c,n) {
+    while(--n >= 0) {
+      var v = x*this[i++]+w[j]+c;
+      c = Math.floor(v/0x4000000);
+      w[j++] = v&0x3ffffff;
+    }
+    return c;
+  }
+  // am2 avoids a big mult-and-extract completely.
+  // Max digit bits should be <= 30 because we do bitwise ops
+  // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
+  function am2(i,x,w,j,c,n) {
+    var xl = x&0x7fff, xh = x>>15;
+    while(--n >= 0) {
+      var l = this[i]&0x7fff;
+      var h = this[i++]>>15;
+      var m = xh*l+h*xl;
+      l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
+      c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
+      w[j++] = l&0x3fffffff;
+    }
+    return c;
+  }
+  // Alternately, set max digit bits to 28 since some
+  // browsers slow down when dealing with 32-bit numbers.
+  function am3(i,x,w,j,c,n) {
+    var xl = x&0x3fff, xh = x>>14;
+    while(--n >= 0) {
+      var l = this[i]&0x3fff;
+      var h = this[i++]>>14;
+      var m = xh*l+h*xl;
+      l = xl*l+((m&0x3fff)<<14)+w[j]+c;
+      c = (l>>28)+(m>>14)+xh*h;
+      w[j++] = l&0xfffffff;
+    }
+    return c;
+  }
+  if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
+    BigInteger.prototype.am = am2;
+    dbits = 30;
+  }
+  else if(j_lm && (navigator.appName != "Netscape")) {
+    BigInteger.prototype.am = am1;
+    dbits = 26;
+  }
+  else { // Mozilla/Netscape seems to prefer am3
+    BigInteger.prototype.am = am3;
+    dbits = 28;
+  }
+
+  BigInteger.prototype.DB = dbits;
+  BigInteger.prototype.DM = ((1<<dbits)-1);
+  BigInteger.prototype.DV = (1<<dbits);
+
+  var BI_FP = 52;
+  BigInteger.prototype.FV = Math.pow(2,BI_FP);
+  BigInteger.prototype.F1 = BI_FP-dbits;
+  BigInteger.prototype.F2 = 2*dbits-BI_FP;
+
+  // Digit conversions
+  var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
+  var BI_RC = new Array();
+  var rr,vv;
+  rr = "0".charCodeAt(0);
+  for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
+  rr = "a".charCodeAt(0);
+  for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+  rr = "A".charCodeAt(0);
+  for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+
+  function int2char(n) { return BI_RM.charAt(n); }
+  function intAt(s,i) {
+    var c = BI_RC[s.charCodeAt(i)];
+    return (c==null)?-1:c;
+  }
+
+  // (protected) copy this to r
+  function bnpCopyTo(r) {
+    for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
+    r.t = this.t;
+    r.s = this.s;
+  }
+
+  // (protected) set from integer value x, -DV <= x < DV
+  function bnpFromInt(x) {
+    this.t = 1;
+    this.s = (x<0)?-1:0;
+    if(x > 0) this[0] = x;
+    else if(x < -1) this[0] = x+DV;
+    else this.t = 0;
+  }
+
+  // return bigint initialized to value
+  function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
+
+  // (protected) set from string and radix
+  function bnpFromString(s,b) {
+    var k;
+    if(b == 16) k = 4;
+    else if(b == 8) k = 3;
+    else if(b == 256) k = 8; // byte array
+    else if(b == 2) k = 1;
+    else if(b == 32) k = 5;
+    else if(b == 4) k = 2;
+    else { this.fromRadix(s,b); return; }
+    this.t = 0;
+    this.s = 0;
+    var i = s.length, mi = false, sh = 0;
+    while(--i >= 0) {
+      var x = (k==8)?s[i]&0xff:intAt(s,i);
+      if(x < 0) {
+        if(s.charAt(i) == "-") mi = true;
+        continue;
+      }
+      mi = false;
+      if(sh == 0)
+        this[this.t++] = x;
+      else if(sh+k > this.DB) {
+        this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
+        this[this.t++] = (x>>(this.DB-sh));
+      }
+      else
+        this[this.t-1] |= x<<sh;
+      sh += k;
+      if(sh >= this.DB) sh -= this.DB;
+    }
+    if(k == 8 && (s[0]&0x80) != 0) {
+      this.s = -1;
+      if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
+    }
+    this.clamp();
+    if(mi) BigInteger.ZERO.subTo(this,this);
+  }
+
+  // (protected) clamp off excess high words
+  function bnpClamp() {
+    var c = this.s&this.DM;
+    while(this.t > 0 && this[this.t-1] == c) --this.t;
+  }
+
+  // (public) return string representation in given radix
+  function bnToString(b) {
+    if(this.s < 0) return "-"+this.negate().toString(b);
+    var k;
+    if(b == 16) k = 4;
+    else if(b == 8) k = 3;
+    else if(b == 2) k = 1;
+    else if(b == 32) k = 5;
+    else if(b == 4) k = 2;
+    else return this.toRadix(b);
+    var km = (1<<k)-1, d, m = false, r = "", i = this.t;
+    var p = this.DB-(i*this.DB)%k;
+    if(i-- > 0) {
+      if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
+      while(i >= 0) {
+        if(p < k) {
+          d = (this[i]&((1<<p)-1))<<(k-p);
+          d |= this[--i]>>(p+=this.DB-k);
+        }
+        else {
+          d = (this[i]>>(p-=k))&km;
+          if(p <= 0) { p += this.DB; --i; }
+        }
+        if(d > 0) m = true;
+        if(m) r += int2char(d);
+      }
+    }
+    return m?r:"0";
+  }
+
+  // (public) -this
+  function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
+
+  // (public) |this|
+  function bnAbs() { return (this.s<0)?this.negate():this; }
+
+  // (public) return + if this > a, - if this < a, 0 if equal
+  function bnCompareTo(a) {
+    var r = this.s-a.s;
+    if(r != 0) return r;
+    var i = this.t;
+    r = i-a.t;
+    if(r != 0) return (this.s<0)?-r:r;
+    while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
+    return 0;
+  }
+
+  // returns bit length of the integer x
+  function nbits(x) {
+    var r = 1, t;
+    if((t=x>>>16) != 0) { x = t; r += 16; }
+    if((t=x>>8) != 0) { x = t; r += 8; }
+    if((t=x>>4) != 0) { x = t; r += 4; }
+    if((t=x>>2) != 0) { x = t; r += 2; }
+    if((t=x>>1) != 0) { x = t; r += 1; }
+    return r;
+  }
+
+  // (public) return the number of bits in "this"
+  function bnBitLength() {
+    if(this.t <= 0) return 0;
+    return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
+  }
+
+  // (protected) r = this << n*DB
+  function bnpDLShiftTo(n,r) {
+    var i;
+    for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
+    for(i = n-1; i >= 0; --i) r[i] = 0;
+    r.t = this.t+n;
+    r.s = this.s;
+  }
+
+  // (protected) r = this >> n*DB
+  function bnpDRShiftTo(n,r) {
+    for(var i = n; i < this.t; ++i) r[i-n] = this[i];
+    r.t = Math.max(this.t-n,0);
+    r.s = this.s;
+  }
+
+  // (protected) r = this << n
+  function bnpLShiftTo(n,r) {
+    var bs = n%this.DB;
+    var cbs = this.DB-bs;
+    var bm = (1<<cbs)-1;
+    var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
+    for(i = this.t-1; i >= 0; --i) {
+      r[i+ds+1] = (this[i]>>cbs)|c;
+      c = (this[i]&bm)<<bs;
+    }
+    for(i = ds-1; i >= 0; --i) r[i] = 0;
+    r[ds] = c;
+    r.t = this.t+ds+1;
+    r.s = this.s;
+    r.clamp();
+  }
+
+  // (protected) r = this >> n
+  function bnpRShiftTo(n,r) {
+    r.s = this.s;
+    var ds = Math.floor(n/this.DB);
+    if(ds >= this.t) { r.t = 0; return; }
+    var bs = n%this.DB;
+    var cbs = this.DB-bs;
+    var bm = (1<<bs)-1;
+    r[0] = this[ds]>>bs;
+    for(var i = ds+1; i < this.t; ++i) {
+      r[i-ds-1] |= (this[i]&bm)<<cbs;
+      r[i-ds] = this[i]>>bs;
+    }
+    if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
+    r.t = this.t-ds;
+    r.clamp();
+  }
+
+  // (protected) r = this - a
+  function bnpSubTo(a,r) {
+    var i = 0, c = 0, m = Math.min(a.t,this.t);
+    while(i < m) {
+      c += this[i]-a[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    if(a.t < this.t) {
+      c -= a.s;
+      while(i < this.t) {
+        c += this[i];
+        r[i++] = c&this.DM;
+        c >>= this.DB;
+      }
+      c += this.s;
+    }
+    else {
+      c += this.s;
+      while(i < a.t) {
+        c -= a[i];
+        r[i++] = c&this.DM;
+        c >>= this.DB;
+      }
+      c -= a.s;
+    }
+    r.s = (c<0)?-1:0;
+    if(c < -1) r[i++] = this.DV+c;
+    else if(c > 0) r[i++] = c;
+    r.t = i;
+    r.clamp();
+  }
+
+  // (protected) r = this * a, r != this,a (HAC 14.12)
+  // "this" should be the larger one if appropriate.
+  function bnpMultiplyTo(a,r) {
+    var x = this.abs(), y = a.abs();
+    var i = x.t;
+    r.t = i+y.t;
+    while(--i >= 0) r[i] = 0;
+    for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
+    r.s = 0;
+    r.clamp();
+    if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
+  }
+
+  // (protected) r = this^2, r != this (HAC 14.16)
+  function bnpSquareTo(r) {
+    var x = this.abs();
+    var i = r.t = 2*x.t;
+    while(--i >= 0) r[i] = 0;
+    for(i = 0; i < x.t-1; ++i) {
+      var c = x.am(i,x[i],r,2*i,0,1);
+      if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
+        r[i+x.t] -= x.DV;
+        r[i+x.t+1] = 1;
+      }
+    }
+    if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
+    r.s = 0;
+    r.clamp();
+  }
+
+  // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
+  // r != q, this != m.  q or r may be null.
+  function bnpDivRemTo(m,q,r) {
+    var pm = m.abs();
+    if(pm.t <= 0) return;
+    var pt = this.abs();
+    if(pt.t < pm.t) {
+      if(q != null) q.fromInt(0);
+      if(r != null) this.copyTo(r);
+      return;
+    }
+    if(r == null) r = nbi();
+    var y = nbi(), ts = this.s, ms = m.s;
+    var nsh = this.DB-nbits(pm[pm.t-1]);  // normalize modulus
+    if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
+    else { pm.copyTo(y); pt.copyTo(r); }
+    var ys = y.t;
+    var y0 = y[ys-1];
+    if(y0 == 0) return;
+    var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
+    var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
+    var i = r.t, j = i-ys, t = (q==null)?nbi():q;
+    y.dlShiftTo(j,t);
+    if(r.compareTo(t) >= 0) {
+      r[r.t++] = 1;
+      r.subTo(t,r);
+    }
+    BigInteger.ONE.dlShiftTo(ys,t);
+    t.subTo(y,y);  // "negative" y so we can replace sub with am later
+    while(y.t < ys) y[y.t++] = 0;
+    while(--j >= 0) {
+      // Estimate quotient digit
+      var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
+      if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) {  // Try it out
+        y.dlShiftTo(j,t);
+        r.subTo(t,r);
+        while(r[i] < --qd) r.subTo(t,r);
+      }
+    }
+    if(q != null) {
+      r.drShiftTo(ys,q);
+      if(ts != ms) BigInteger.ZERO.subTo(q,q);
+    }
+    r.t = ys;
+    r.clamp();
+    if(nsh > 0) r.rShiftTo(nsh,r);  // Denormalize remainder
+    if(ts < 0) BigInteger.ZERO.subTo(r,r);
+  }
+
+  // (public) this mod a
+  function bnMod(a) {
+    var r = nbi();
+    this.abs().divRemTo(a,null,r);
+    if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
+    return r;
+  }
+
+  // Modular reduction using "classic" algorithm
+  function Classic(m) { this.m = m; }
+  function cConvert(x) {
+    if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
+    else return x;
+  }
+  function cRevert(x) { return x; }
+  function cReduce(x) { x.divRemTo(this.m,null,x); }
+  function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+  function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+  Classic.prototype.convert = cConvert;
+  Classic.prototype.revert = cRevert;
+  Classic.prototype.reduce = cReduce;
+  Classic.prototype.mulTo = cMulTo;
+  Classic.prototype.sqrTo = cSqrTo;
+
+  // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
+  // justification:
+  //         xy == 1 (mod m)
+  //         xy =  1+km
+  //   xy(2-xy) = (1+km)(1-km)
+  // x[y(2-xy)] = 1-k^2m^2
+  // x[y(2-xy)] == 1 (mod m^2)
+  // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+  // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
+  // JS multiply "overflows" differently from C/C++, so care is needed here.
+  function bnpInvDigit() {
+    if(this.t < 1) return 0;
+    var x = this[0];
+    if((x&1) == 0) return 0;
+    var y = x&3;    // y == 1/x mod 2^2
+    y = (y*(2-(x&0xf)*y))&0xf;  // y == 1/x mod 2^4
+    y = (y*(2-(x&0xff)*y))&0xff;  // y == 1/x mod 2^8
+    y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff;  // y == 1/x mod 2^16
+    // last step - calculate inverse mod DV directly;
+    // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
+    y = (y*(2-x*y%this.DV))%this.DV;    // y == 1/x mod 2^dbits
+    // we really want the negative inverse, and -DV < y < DV
+    return (y>0)?this.DV-y:-y;
+  }
+
+  // Montgomery reduction
+  function Montgomery(m) {
+    this.m = m;
+    this.mp = m.invDigit();
+    this.mpl = this.mp&0x7fff;
+    this.mph = this.mp>>15;
+    this.um = (1<<(m.DB-15))-1;
+    this.mt2 = 2*m.t;
+  }
+
+  // xR mod m
+  function montConvert(x) {
+    var r = nbi();
+    x.abs().dlShiftTo(this.m.t,r);
+    r.divRemTo(this.m,null,r);
+    if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
+    return r;
+  }
+
+  // x/R mod m
+  function montRevert(x) {
+    var r = nbi();
+    x.copyTo(r);
+    this.reduce(r);
+    return r;
+  }
+
+  // x = x/R mod m (HAC 14.32)
+  function montReduce(x) {
+    while(x.t <= this.mt2)  // pad x so am has enough room later
+      x[x.t++] = 0;
+    for(var i = 0; i < this.m.t; ++i) {
+      // faster way of calculating u0 = x[i]*mp mod DV
+      var j = x[i]&0x7fff;
+      var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
+      // use am to combine the multiply-shift-add into one call
+      j = i+this.m.t;
+      x[j] += this.m.am(0,u0,x,i,0,this.m.t);
+      // propagate carry
+      while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
+    }
+    x.clamp();
+    x.drShiftTo(this.m.t,x);
+    if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
+  }
+
+  // r = "x^2/R mod m"; x != r
+  function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+  // r = "xy/R mod m"; x,y != r
+  function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+
+  Montgomery.prototype.convert = montConvert;
+  Montgomery.prototype.revert = montRevert;
+  Montgomery.prototype.reduce = montReduce;
+  Montgomery.prototype.mulTo = montMulTo;
+  Montgomery.prototype.sqrTo = montSqrTo;
+
+  // (protected) true iff this is even
+  function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
+
+  // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
+  function bnpExp(e,z) {
+    if(e > 0xffffffff || e < 1) return BigInteger.ONE;
+    var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
+    g.copyTo(r);
+    while(--i >= 0) {
+      z.sqrTo(r,r2);
+      if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
+      else { var t = r; r = r2; r2 = t; }
+    }
+    return z.revert(r);
+  }
+
+  // (public) this^e % m, 0 <= e < 2^32
+  function bnModPowInt(e,m) {
+    var z;
+    if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
+    return this.exp(e,z);
+  }
+
+  // protected
+  BigInteger.prototype.copyTo = bnpCopyTo;
+  BigInteger.prototype.fromInt = bnpFromInt;
+  BigInteger.prototype.fromString = bnpFromString;
+  BigInteger.prototype.clamp = bnpClamp;
+  BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
+  BigInteger.prototype.drShiftTo = bnpDRShiftTo;
+  BigInteger.prototype.lShiftTo = bnpLShiftTo;
+  BigInteger.prototype.rShiftTo = bnpRShiftTo;
+  BigInteger.prototype.subTo = bnpSubTo;
+  BigInteger.prototype.multiplyTo = bnpMultiplyTo;
+  BigInteger.prototype.squareTo = bnpSquareTo;
+  BigInteger.prototype.divRemTo = bnpDivRemTo;
+  BigInteger.prototype.invDigit = bnpInvDigit;
+  BigInteger.prototype.isEven = bnpIsEven;
+  BigInteger.prototype.exp = bnpExp;
+
+  // public
+  BigInteger.prototype.toString = bnToString;
+  BigInteger.prototype.negate = bnNegate;
+  BigInteger.prototype.abs = bnAbs;
+  BigInteger.prototype.compareTo = bnCompareTo;
+  BigInteger.prototype.bitLength = bnBitLength;
+  BigInteger.prototype.mod = bnMod;
+  BigInteger.prototype.modPowInt = bnModPowInt;
+
+  // "constants"
+  BigInteger.ZERO = nbv(0);
+  BigInteger.ONE = nbv(1);
+
+  // jsbn2 stuff
+
+  // (protected) convert from radix string
+  function bnpFromRadix(s,b) {
+    this.fromInt(0);
+    if(b == null) b = 10;
+    var cs = this.chunkSize(b);
+    var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
+    for(var i = 0; i < s.length; ++i) {
+      var x = intAt(s,i);
+      if(x < 0) {
+        if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
+        continue;
+      }
+      w = b*w+x;
+      if(++j >= cs) {
+        this.dMultiply(d);
+        this.dAddOffset(w,0);
+        j = 0;
+        w = 0;
+      }
+    }
+    if(j > 0) {
+      this.dMultiply(Math.pow(b,j));
+      this.dAddOffset(w,0);
+    }
+    if(mi) BigInteger.ZERO.subTo(this,this);
+  }
+
+  // (protected) return x s.t. r^x < DV
+  function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
+
+  // (public) 0 if this == 0, 1 if this > 0
+  function bnSigNum() {
+    if(this.s < 0) return -1;
+    else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
+    else return 1;
+  }
+
+  // (protected) this *= n, this >= 0, 1 < n < DV
+  function bnpDMultiply(n) {
+    this[this.t] = this.am(0,n-1,this,0,0,this.t);
+    ++this.t;
+    this.clamp();
+  }
+
+  // (protected) this += n << w words, this >= 0
+  function bnpDAddOffset(n,w) {
+    if(n == 0) return;
+    while(this.t <= w) this[this.t++] = 0;
+    this[w] += n;
+    while(this[w] >= this.DV) {
+      this[w] -= this.DV;
+      if(++w >= this.t) this[this.t++] = 0;
+      ++this[w];
+    }
+  }
+
+  // (protected) convert to radix string
+  function bnpToRadix(b) {
+    if(b == null) b = 10;
+    if(this.signum() == 0 || b < 2 || b > 36) return "0";
+    var cs = this.chunkSize(b);
+    var a = Math.pow(b,cs);
+    var d = nbv(a), y = nbi(), z = nbi(), r = "";
+    this.divRemTo(d,y,z);
+    while(y.signum() > 0) {
+      r = (a+z.intValue()).toString(b).substr(1) + r;
+      y.divRemTo(d,y,z);
+    }
+    return z.intValue().toString(b) + r;
+  }
+
+  // (public) return value as integer
+  function bnIntValue() {
+    if(this.s < 0) {
+      if(this.t == 1) return this[0]-this.DV;
+      else if(this.t == 0) return -1;
+    }
+    else if(this.t == 1) return this[0];
+    else if(this.t == 0) return 0;
+    // assumes 16 < DB < 32
+    return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];
+  }
+
+  // (protected) r = this + a
+  function bnpAddTo(a,r) {
+    var i = 0, c = 0, m = Math.min(a.t,this.t);
+    while(i < m) {
+      c += this[i]+a[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    if(a.t < this.t) {
+      c += a.s;
+      while(i < this.t) {
+        c += this[i];
+        r[i++] = c&this.DM;
+        c >>= this.DB;
+      }
+      c += this.s;
+    }
+    else {
+      c += this.s;
+      while(i < a.t) {
+        c += a[i];
+        r[i++] = c&this.DM;
+        c >>= this.DB;
+      }
+      c += a.s;
+    }
+    r.s = (c<0)?-1:0;
+    if(c > 0) r[i++] = c;
+    else if(c < -1) r[i++] = this.DV+c;
+    r.t = i;
+    r.clamp();
+  }
+
+  BigInteger.prototype.fromRadix = bnpFromRadix;
+  BigInteger.prototype.chunkSize = bnpChunkSize;
+  BigInteger.prototype.signum = bnSigNum;
+  BigInteger.prototype.dMultiply = bnpDMultiply;
+  BigInteger.prototype.dAddOffset = bnpDAddOffset;
+  BigInteger.prototype.toRadix = bnpToRadix;
+  BigInteger.prototype.intValue = bnIntValue;
+  BigInteger.prototype.addTo = bnpAddTo;
+
+  //======= end jsbn =======
+
+  // Emscripten wrapper
+  var Wrapper = {
+    abs: function(l, h) {
+      var x = new goog.math.Long(l, h);
+      var ret;
+      if (x.isNegative()) {
+        ret = x.negate();
+      } else {
+        ret = x;
+      }
+      HEAP32[tempDoublePtr>>2] = ret.low_;
+      HEAP32[tempDoublePtr+4>>2] = ret.high_;
+    },
+    ensureTemps: function() {
+      if (Wrapper.ensuredTemps) return;
+      Wrapper.ensuredTemps = true;
+      Wrapper.two32 = new BigInteger();
+      Wrapper.two32.fromString('4294967296', 10);
+      Wrapper.two64 = new BigInteger();
+      Wrapper.two64.fromString('18446744073709551616', 10);
+      Wrapper.temp1 = new BigInteger();
+      Wrapper.temp2 = new BigInteger();
+    },
+    lh2bignum: function(l, h) {
+      var a = new BigInteger();
+      a.fromString(h.toString(), 10);
+      var b = new BigInteger();
+      a.multiplyTo(Wrapper.two32, b);
+      var c = new BigInteger();
+      c.fromString(l.toString(), 10);
+      var d = new BigInteger();
+      c.addTo(b, d);
+      return d;
+    },
+    stringify: function(l, h, unsigned) {
+      var ret = new goog.math.Long(l, h).toString();
+      if (unsigned && ret[0] == '-') {
+        // unsign slowly using jsbn bignums
+        Wrapper.ensureTemps();
+        var bignum = new BigInteger();
+        bignum.fromString(ret, 10);
+        ret = new BigInteger();
+        Wrapper.two64.addTo(bignum, ret);
+        ret = ret.toString(10);
+      }
+      return ret;
+    },
+    fromString: function(str, base, min, max, unsigned) {
+      Wrapper.ensureTemps();
+      var bignum = new BigInteger();
+      bignum.fromString(str, base);
+      var bigmin = new BigInteger();
+      bigmin.fromString(min, 10);
+      var bigmax = new BigInteger();
+      bigmax.fromString(max, 10);
+      if (unsigned && bignum.compareTo(BigInteger.ZERO) < 0) {
+        var temp = new BigInteger();
+        bignum.addTo(Wrapper.two64, temp);
+        bignum = temp;
+      }
+      var error = false;
+      if (bignum.compareTo(bigmin) < 0) {
+        bignum = bigmin;
+        error = true;
+      } else if (bignum.compareTo(bigmax) > 0) {
+        bignum = bigmax;
+        error = true;
+      }
+      var ret = goog.math.Long.fromString(bignum.toString()); // min-max checks should have clamped this to a range goog.math.Long can handle well
+      HEAP32[tempDoublePtr>>2] = ret.low_;
+      HEAP32[tempDoublePtr+4>>2] = ret.high_;
+      if (error) throw 'range error';
+    }
+  };
+  return Wrapper;
+})();
+
+//======= end closure i64 code =======
+
+
+
+// === Auto-generated postamble setup entry stuff ===
+
+if (memoryInitializer) {
+  if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
+    var data = Module['readBinary'](memoryInitializer);
+    HEAPU8.set(data, STATIC_BASE);
+  } else {
+    addRunDependency('memory initializer');
+    Browser.asyncLoad(memoryInitializer, function(data) {
+      HEAPU8.set(data, STATIC_BASE);
+      removeRunDependency('memory initializer');
+    }, function(data) {
+      throw 'could not load memory initializer ' + memoryInitializer;
+    });
+  }
+}
+
+function ExitStatus(status) {
+  this.name = "ExitStatus";
+  this.message = "Program terminated with exit(" + status + ")";
+  this.status = status;
+};
+ExitStatus.prototype = new Error();
+ExitStatus.prototype.constructor = ExitStatus;
+
+var initialStackTop;
+var preloadStartTime = null;
+var calledMain = false;
+
+dependenciesFulfilled = function runCaller() {
+  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
+  if (!Module['calledRun'] && shouldRunNow) run(['binarytrees.lua'].concat(Module["arguments"]));
+  if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
+}
+
+Module['callMain'] = Module.callMain = function callMain(args) {
+  assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
+  assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
+
+  args = args || [];
+
+  ensureInitRuntime();
+
+  var argc = args.length+1;
+  function pad() {
+    for (var i = 0; i < 4-1; i++) {
+      argv.push(0);
+    }
+  }
+  var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ];
+  pad();
+  for (var i = 0; i < argc-1; i = i + 1) {
+    argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL));
+    pad();
+  }
+  argv.push(0);
+  argv = allocate(argv, 'i32', ALLOC_NORMAL);
+
+  initialStackTop = STACKTOP;
+
+  try {
+
+    var ret = Module['_main'](argc, argv, 0);
+
+
+    // if we're not running an evented main loop, it's time to exit
+    if (!Module['noExitRuntime']) {
+      exit(ret);
+    }
+  }
+  catch(e) {
+    if (e instanceof ExitStatus) {
+      // exit() throws this once it's done to make sure execution
+      // has been stopped completely
+      return;
+    } else if (e == 'SimulateInfiniteLoop') {
+      // running an evented main loop, don't immediately exit
+      Module['noExitRuntime'] = true;
+      return;
+    } else {
+      if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
+      throw e;
+    }
+  } finally {
+    calledMain = true;
+  }
+}
+
+
+
+
+function run(args) {
+  args = args || Module['arguments'];
+
+  if (preloadStartTime === null) preloadStartTime = Date.now();
+
+  if (runDependencies > 0) {
+    Module.printErr('run() called, but dependencies remain, so not running');
+    return;
+  }
+
+  preRun();
+
+  if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
+  if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
+
+  function doRun() {
+    if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
+    Module['calledRun'] = true;
+
+    ensureInitRuntime();
+
+    preMain();
+
+    if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
+      Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
+    }
+
+    if (Module['_main'] && shouldRunNow) {
+      Module['callMain'](args);
+    }
+
+    postRun();
+  }
+
+  if (Module['setStatus']) {
+    Module['setStatus']('Running...');
+    setTimeout(function() {
+      setTimeout(function() {
+        Module['setStatus']('');
+      }, 1);
+      if (!ABORT) doRun();
+    }, 1);
+  } else {
+    doRun();
+  }
+}
+Module['run'] = Module.run = run;
+
+function exit(status) {
+  ABORT = true;
+  EXITSTATUS = status;
+  STACKTOP = initialStackTop;
+
+  // exit the runtime
+  exitRuntime();
+
+  // TODO We should handle this differently based on environment.
+  // In the browser, the best we can do is throw an exception
+  // to halt execution, but in node we could process.exit and
+  // I'd imagine SM shell would have something equivalent.
+  // This would let us set a proper exit status (which
+  // would be great for checking test exit statuses).
+  // https://github.com/kripken/emscripten/issues/1371
+
+  // throw an exception to halt the current execution
+  throw new ExitStatus(status);
+}
+Module['exit'] = Module.exit = exit;
+
+function abort(text) {
+  if (text) {
+    Module.print(text);
+    Module.printErr(text);
+  }
+
+  ABORT = true;
+  EXITSTATUS = 1;
+
+  var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.';
+
+  throw 'abort() at ' + stackTrace() + extra;
+}
+Module['abort'] = Module.abort = abort;
+
+// {{PRE_RUN_ADDITIONS}}
+
+if (Module['preInit']) {
+  if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
+  while (Module['preInit'].length > 0) {
+    Module['preInit'].pop()();
+  }
+}
+
+// shouldRunNow refers to calling main(), not run().
+var shouldRunNow = true;
+if (Module['noInitialRun']) {
+  shouldRunNow = false;
+}
+
+
+run(['binarytrees.lua'].concat(Module["arguments"]));
diff --git a/test/mjsunit/asm/embenchen/memops.js b/test/mjsunit/asm/embenchen/memops.js
new file mode 100644
index 0000000..e8e607c
--- /dev/null
+++ b/test/mjsunit/asm/embenchen/memops.js
@@ -0,0 +1,8087 @@
+var EXPECTED_OUTPUT = 'final: 840.\n';
+var Module = {
+  arguments: [1],
+  print: function(x) {Module.printBuffer += x + '\n';},
+  preRun: [function() {Module.printBuffer = ''}],
+  postRun: [function() {
+    assertEquals(EXPECTED_OUTPUT, Module.printBuffer);
+  }],
+};
+// The Module object: Our interface to the outside world. We import
+// and export values on it, and do the work to get that through
+// closure compiler if necessary. There are various ways Module can be used:
+// 1. Not defined. We create it here
+// 2. A function parameter, function(Module) { ..generated code.. }
+// 3. pre-run appended it, var Module = {}; ..generated code..
+// 4. External script tag defines var Module.
+// We need to do an eval in order to handle the closure compiler
+// case, where this code here is minified but Module was defined
+// elsewhere (e.g. case 4 above). We also need to check if Module
+// already exists (e.g. case 3 above).
+// Note that if you want to run closure, and also to use Module
+// after the generated code, you will need to define   var Module = {};
+// before the code. Then that object will be used in the code, and you
+// can continue to use Module afterwards as well.
+var Module;
+if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {};
+
+// Sometimes an existing Module object exists with properties
+// meant to overwrite the default module functionality. Here
+// we collect those properties and reapply _after_ we configure
+// the current environment's defaults to avoid having to be so
+// defensive during initialization.
+var moduleOverrides = {};
+for (var key in Module) {
+  if (Module.hasOwnProperty(key)) {
+    moduleOverrides[key] = Module[key];
+  }
+}
+
+// The environment setup code below is customized to use Module.
+// *** Environment setup code ***
+var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
+var ENVIRONMENT_IS_WEB = typeof window === 'object';
+var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
+var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
+
+if (ENVIRONMENT_IS_NODE) {
+  // Expose functionality in the same simple way that the shells work
+  // Note that we pollute the global namespace here, otherwise we break in node
+  if (!Module['print']) Module['print'] = function print(x) {
+    process['stdout'].write(x + '\n');
+  };
+  if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+    process['stderr'].write(x + '\n');
+  };
+
+  var nodeFS = require('fs');
+  var nodePath = require('path');
+
+  Module['read'] = function read(filename, binary) {
+    filename = nodePath['normalize'](filename);
+    var ret = nodeFS['readFileSync'](filename);
+    // The path is absolute if the normalized version is the same as the resolved.
+    if (!ret && filename != nodePath['resolve'](filename)) {
+      filename = path.join(__dirname, '..', 'src', filename);
+      ret = nodeFS['readFileSync'](filename);
+    }
+    if (ret && !binary) ret = ret.toString();
+    return ret;
+  };
+
+  Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) };
+
+  Module['load'] = function load(f) {
+    globalEval(read(f));
+  };
+
+  Module['arguments'] = process['argv'].slice(2);
+
+  module['exports'] = Module;
+}
+else if (ENVIRONMENT_IS_SHELL) {
+  if (!Module['print']) Module['print'] = print;
+  if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
+
+  if (typeof read != 'undefined') {
+    Module['read'] = read;
+  } else {
+    Module['read'] = function read() { throw 'no read() available (jsc?)' };
+  }
+
+  Module['readBinary'] = function readBinary(f) {
+    return read(f, 'binary');
+  };
+
+  if (typeof scriptArgs != 'undefined') {
+    Module['arguments'] = scriptArgs;
+  } else if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  this['Module'] = Module;
+
+  eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly)
+}
+else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+  Module['read'] = function read(url) {
+    var xhr = new XMLHttpRequest();
+    xhr.open('GET', url, false);
+    xhr.send(null);
+    return xhr.responseText;
+  };
+
+  if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  if (typeof console !== 'undefined') {
+    if (!Module['print']) Module['print'] = function print(x) {
+      console.log(x);
+    };
+    if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+      console.log(x);
+    };
+  } else {
+    // Probably a worker, and without console.log. We can do very little here...
+    var TRY_USE_DUMP = false;
+    if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
+      dump(x);
+    }) : (function(x) {
+      // self.postMessage(x); // enable this if you want stdout to be sent as messages
+    }));
+  }
+
+  if (ENVIRONMENT_IS_WEB) {
+    window['Module'] = Module;
+  } else {
+    Module['load'] = importScripts;
+  }
+}
+else {
+  // Unreachable because SHELL is dependant on the others
+  throw 'Unknown runtime environment. Where are we?';
+}
+
+function globalEval(x) {
+  eval.call(null, x);
+}
+if (!Module['load'] == 'undefined' && Module['read']) {
+  Module['load'] = function load(f) {
+    globalEval(Module['read'](f));
+  };
+}
+if (!Module['print']) {
+  Module['print'] = function(){};
+}
+if (!Module['printErr']) {
+  Module['printErr'] = Module['print'];
+}
+if (!Module['arguments']) {
+  Module['arguments'] = [];
+}
+// *** Environment setup code ***
+
+// Closure helpers
+Module.print = Module['print'];
+Module.printErr = Module['printErr'];
+
+// Callbacks
+Module['preRun'] = [];
+Module['postRun'] = [];
+
+// Merge back in the overrides
+for (var key in moduleOverrides) {
+  if (moduleOverrides.hasOwnProperty(key)) {
+    Module[key] = moduleOverrides[key];
+  }
+}
+
+
+
+// === Auto-generated preamble library stuff ===
+
+//========================================
+// Runtime code shared with compiler
+//========================================
+
+var Runtime = {
+  stackSave: function () {
+    return STACKTOP;
+  },
+  stackRestore: function (stackTop) {
+    STACKTOP = stackTop;
+  },
+  forceAlign: function (target, quantum) {
+    quantum = quantum || 4;
+    if (quantum == 1) return target;
+    if (isNumber(target) && isNumber(quantum)) {
+      return Math.ceil(target/quantum)*quantum;
+    } else if (isNumber(quantum) && isPowerOfTwo(quantum)) {
+      return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')';
+    }
+    return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
+  },
+  isNumberType: function (type) {
+    return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
+  },
+  isPointerType: function isPointerType(type) {
+  return type[type.length-1] == '*';
+},
+  isStructType: function isStructType(type) {
+  if (isPointerType(type)) return false;
+  if (isArrayType(type)) return true;
+  if (/<?\{ ?[^}]* ?\}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types
+  // See comment in isStructPointerType()
+  return type[0] == '%';
+},
+  INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
+  FLOAT_TYPES: {"float":0,"double":0},
+  or64: function (x, y) {
+    var l = (x | 0) | (y | 0);
+    var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  and64: function (x, y) {
+    var l = (x | 0) & (y | 0);
+    var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  xor64: function (x, y) {
+    var l = (x | 0) ^ (y | 0);
+    var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  getNativeTypeSize: function (type) {
+    switch (type) {
+      case 'i1': case 'i8': return 1;
+      case 'i16': return 2;
+      case 'i32': return 4;
+      case 'i64': return 8;
+      case 'float': return 4;
+      case 'double': return 8;
+      default: {
+        if (type[type.length-1] === '*') {
+          return Runtime.QUANTUM_SIZE; // A pointer
+        } else if (type[0] === 'i') {
+          var bits = parseInt(type.substr(1));
+          assert(bits % 8 === 0);
+          return bits/8;
+        } else {
+          return 0;
+        }
+      }
+    }
+  },
+  getNativeFieldSize: function (type) {
+    return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE);
+  },
+  dedup: function dedup(items, ident) {
+  var seen = {};
+  if (ident) {
+    return items.filter(function(item) {
+      if (seen[item[ident]]) return false;
+      seen[item[ident]] = true;
+      return true;
+    });
+  } else {
+    return items.filter(function(item) {
+      if (seen[item]) return false;
+      seen[item] = true;
+      return true;
+    });
+  }
+},
+  set: function set() {
+  var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
+  var ret = {};
+  for (var i = 0; i < args.length; i++) {
+    ret[args[i]] = 0;
+  }
+  return ret;
+},
+  STACK_ALIGN: 8,
+  getAlignSize: function (type, size, vararg) {
+    // we align i64s and doubles on 64-bit boundaries, unlike x86
+    if (!vararg && (type == 'i64' || type == 'double')) return 8;
+    if (!type) return Math.min(size, 8); // align structures internally to 64 bits
+    return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE);
+  },
+  calculateStructAlignment: function calculateStructAlignment(type) {
+    type.flatSize = 0;
+    type.alignSize = 0;
+    var diffs = [];
+    var prev = -1;
+    var index = 0;
+    type.flatIndexes = type.fields.map(function(field) {
+      index++;
+      var size, alignSize;
+      if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
+        size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
+        alignSize = Runtime.getAlignSize(field, size);
+      } else if (Runtime.isStructType(field)) {
+        if (field[1] === '0') {
+          // this is [0 x something]. When inside another structure like here, it must be at the end,
+          // and it adds no size
+          // XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!');
+          size = 0;
+          if (Types.types[field]) {
+            alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+          } else {
+            alignSize = type.alignSize || QUANTUM_SIZE;
+          }
+        } else {
+          size = Types.types[field].flatSize;
+          alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+        }
+      } else if (field[0] == 'b') {
+        // bN, large number field, like a [N x i8]
+        size = field.substr(1)|0;
+        alignSize = 1;
+      } else if (field[0] === '<') {
+        // vector type
+        size = alignSize = Types.types[field].flatSize; // fully aligned
+      } else if (field[0] === 'i') {
+        // illegal integer field, that could not be legalized because it is an internal structure field
+        // it is ok to have such fields, if we just use them as markers of field size and nothing more complex
+        size = alignSize = parseInt(field.substr(1))/8;
+        assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field);
+      } else {
+        assert(false, 'invalid type for calculateStructAlignment');
+      }
+      if (type.packed) alignSize = 1;
+      type.alignSize = Math.max(type.alignSize, alignSize);
+      var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
+      type.flatSize = curr + size;
+      if (prev >= 0) {
+        diffs.push(curr-prev);
+      }
+      prev = curr;
+      return curr;
+    });
+    if (type.name_ && type.name_[0] === '[') {
+      // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
+      // allocating a potentially huge array for [999999 x i8] etc.
+      type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
+    }
+    type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
+    if (diffs.length == 0) {
+      type.flatFactor = type.flatSize;
+    } else if (Runtime.dedup(diffs).length == 1) {
+      type.flatFactor = diffs[0];
+    }
+    type.needsFlattening = (type.flatFactor != 1);
+    return type.flatIndexes;
+  },
+  generateStructInfo: function (struct, typeName, offset) {
+    var type, alignment;
+    if (typeName) {
+      offset = offset || 0;
+      type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
+      if (!type) return null;
+      if (type.fields.length != struct.length) {
+        printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo');
+        return null;
+      }
+      alignment = type.flatIndexes;
+    } else {
+      var type = { fields: struct.map(function(item) { return item[0] }) };
+      alignment = Runtime.calculateStructAlignment(type);
+    }
+    var ret = {
+      __size__: type.flatSize
+    };
+    if (typeName) {
+      struct.forEach(function(item, i) {
+        if (typeof item === 'string') {
+          ret[item] = alignment[i] + offset;
+        } else {
+          // embedded struct
+          var key;
+          for (var k in item) key = k;
+          ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
+        }
+      });
+    } else {
+      struct.forEach(function(item, i) {
+        ret[item[1]] = alignment[i];
+      });
+    }
+    return ret;
+  },
+  dynCall: function (sig, ptr, args) {
+    if (args && args.length) {
+      if (!args.splice) args = Array.prototype.slice.call(args);
+      args.splice(0, 0, ptr);
+      return Module['dynCall_' + sig].apply(null, args);
+    } else {
+      return Module['dynCall_' + sig].call(null, ptr);
+    }
+  },
+  functionPointers: [],
+  addFunction: function (func) {
+    for (var i = 0; i < Runtime.functionPointers.length; i++) {
+      if (!Runtime.functionPointers[i]) {
+        Runtime.functionPointers[i] = func;
+        return 2*(1 + i);
+      }
+    }
+    throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
+  },
+  removeFunction: function (index) {
+    Runtime.functionPointers[(index-2)/2] = null;
+  },
+  getAsmConst: function (code, numArgs) {
+    // code is a constant string on the heap, so we can cache these
+    if (!Runtime.asmConstCache) Runtime.asmConstCache = {};
+    var func = Runtime.asmConstCache[code];
+    if (func) return func;
+    var args = [];
+    for (var i = 0; i < numArgs; i++) {
+      args.push(String.fromCharCode(36) + i); // $0, $1 etc
+    }
+    var source = Pointer_stringify(code);
+    if (source[0] === '"') {
+      // tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct
+      if (source.indexOf('"', 1) === source.length-1) {
+        source = source.substr(1, source.length-2);
+      } else {
+        // something invalid happened, e.g. EM_ASM("..code($0)..", input)
+        abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)');
+      }
+    }
+    try {
+      var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node
+    } catch(e) {
+      Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)');
+      throw e;
+    }
+    return Runtime.asmConstCache[code] = evalled;
+  },
+  warnOnce: function (text) {
+    if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
+    if (!Runtime.warnOnce.shown[text]) {
+      Runtime.warnOnce.shown[text] = 1;
+      Module.printErr(text);
+    }
+  },
+  funcWrappers: {},
+  getFuncWrapper: function (func, sig) {
+    assert(sig);
+    if (!Runtime.funcWrappers[func]) {
+      Runtime.funcWrappers[func] = function dynCall_wrapper() {
+        return Runtime.dynCall(sig, func, arguments);
+      };
+    }
+    return Runtime.funcWrappers[func];
+  },
+  UTF8Processor: function () {
+    var buffer = [];
+    var needed = 0;
+    this.processCChar = function (code) {
+      code = code & 0xFF;
+
+      if (buffer.length == 0) {
+        if ((code & 0x80) == 0x00) {        // 0xxxxxxx
+          return String.fromCharCode(code);
+        }
+        buffer.push(code);
+        if ((code & 0xE0) == 0xC0) {        // 110xxxxx
+          needed = 1;
+        } else if ((code & 0xF0) == 0xE0) { // 1110xxxx
+          needed = 2;
+        } else {                            // 11110xxx
+          needed = 3;
+        }
+        return '';
+      }
+
+      if (needed) {
+        buffer.push(code);
+        needed--;
+        if (needed > 0) return '';
+      }
+
+      var c1 = buffer[0];
+      var c2 = buffer[1];
+      var c3 = buffer[2];
+      var c4 = buffer[3];
+      var ret;
+      if (buffer.length == 2) {
+        ret = String.fromCharCode(((c1 & 0x1F) << 6)  | (c2 & 0x3F));
+      } else if (buffer.length == 3) {
+        ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6)  | (c3 & 0x3F));
+      } else {
+        // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+        var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
+                        ((c3 & 0x3F) << 6)  | (c4 & 0x3F);
+        ret = String.fromCharCode(
+          Math.floor((codePoint - 0x10000) / 0x400) + 0xD800,
+          (codePoint - 0x10000) % 0x400 + 0xDC00);
+      }
+      buffer.length = 0;
+      return ret;
+    }
+    this.processJSString = function processJSString(string) {
+      /* TODO: use TextEncoder when present,
+        var encoder = new TextEncoder();
+        encoder['encoding'] = "utf-8";
+        var utf8Array = encoder['encode'](aMsg.data);
+      */
+      string = unescape(encodeURIComponent(string));
+      var ret = [];
+      for (var i = 0; i < string.length; i++) {
+        ret.push(string.charCodeAt(i));
+      }
+      return ret;
+    }
+  },
+  getCompilerSetting: function (name) {
+    throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work';
+  },
+  stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+7)&-8); return ret; },
+  staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = (((STATICTOP)+7)&-8); return ret; },
+  dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = (((DYNAMICTOP)+7)&-8); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; },
+  alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; },
+  makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*(+4294967296))) : ((+((low>>>0)))+((+((high|0)))*(+4294967296)))); return ret; },
+  GLOBAL_BASE: 8,
+  QUANTUM_SIZE: 4,
+  __dummy__: 0
+}
+
+
+Module['Runtime'] = Runtime;
+
+
+
+
+
+
+
+
+
+//========================================
+// Runtime essentials
+//========================================
+
+var __THREW__ = 0; // Used in checking for thrown exceptions.
+
+var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort()
+var EXITSTATUS = 0;
+
+var undef = 0;
+// tempInt is used for 32-bit signed values or smaller. tempBigInt is used
+// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt
+var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat;
+var tempI64, tempI64b;
+var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9;
+
+function assert(condition, text) {
+  if (!condition) {
+    abort('Assertion failed: ' + text);
+  }
+}
+
+var globalScope = this;
+
+// C calling interface. A convenient way to call C functions (in C files, or
+// defined with extern "C").
+//
+// Note: LLVM optimizations can inline and remove functions, after which you will not be
+//       able to call them. Closure can also do so. To avoid that, add your function to
+//       the exports using something like
+//
+//         -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]'
+//
+// @param ident      The name of the C function (note that C++ functions will be name-mangled - use extern "C")
+// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and
+//                   'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit).
+// @param argTypes   An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType,
+//                   except that 'array' is not possible (there is no way for us to know the length of the array)
+// @param args       An array of the arguments to the function, as native JS values (as in returnType)
+//                   Note that string arguments will be stored on the stack (the JS string will become a C string on the stack).
+// @return           The return value, as a native JS value (as in returnType)
+function ccall(ident, returnType, argTypes, args) {
+  return ccallFunc(getCFunc(ident), returnType, argTypes, args);
+}
+Module["ccall"] = ccall;
+
+// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
+function getCFunc(ident) {
+  try {
+    var func = Module['_' + ident]; // closure exported function
+    if (!func) func = eval('_' + ident); // explicit lookup
+  } catch(e) {
+  }
+  assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)');
+  return func;
+}
+
+// Internal function that does a C call using a function, not an identifier
+function ccallFunc(func, returnType, argTypes, args) {
+  var stack = 0;
+  function toC(value, type) {
+    if (type == 'string') {
+      if (value === null || value === undefined || value === 0) return 0; // null string
+      value = intArrayFromString(value);
+      type = 'array';
+    }
+    if (type == 'array') {
+      if (!stack) stack = Runtime.stackSave();
+      var ret = Runtime.stackAlloc(value.length);
+      writeArrayToMemory(value, ret);
+      return ret;
+    }
+    return value;
+  }
+  function fromC(value, type) {
+    if (type == 'string') {
+      return Pointer_stringify(value);
+    }
+    assert(type != 'array');
+    return value;
+  }
+  var i = 0;
+  var cArgs = args ? args.map(function(arg) {
+    return toC(arg, argTypes[i++]);
+  }) : [];
+  var ret = fromC(func.apply(null, cArgs), returnType);
+  if (stack) Runtime.stackRestore(stack);
+  return ret;
+}
+
+// Returns a native JS wrapper for a C function. This is similar to ccall, but
+// returns a function you can call repeatedly in a normal way. For example:
+//
+//   var my_function = cwrap('my_c_function', 'number', ['number', 'number']);
+//   alert(my_function(5, 22));
+//   alert(my_function(99, 12));
+//
+function cwrap(ident, returnType, argTypes) {
+  var func = getCFunc(ident);
+  return function() {
+    return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments));
+  }
+}
+Module["cwrap"] = cwrap;
+
+// Sets a value in memory in a dynamic way at run-time. Uses the
+// type data. This is the same as makeSetValue, except that
+// makeSetValue is done at compile-time and generates the needed
+// code then, whereas this function picks the right code at
+// run-time.
+// Note that setValue and getValue only do *aligned* writes and reads!
+// Note that ccall uses JS types as for defining types, while setValue and
+// getValue need LLVM types ('i8', 'i32') - this is a lower-level operation
+function setValue(ptr, value, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': HEAP8[(ptr)]=value; break;
+      case 'i8': HEAP8[(ptr)]=value; break;
+      case 'i16': HEAP16[((ptr)>>1)]=value; break;
+      case 'i32': HEAP32[((ptr)>>2)]=value; break;
+      case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= (+1) ? (tempDouble > (+0) ? ((Math_min((+(Math_floor((tempDouble)/(+4294967296)))), (+4294967295)))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/(+4294967296))))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
+      case 'float': HEAPF32[((ptr)>>2)]=value; break;
+      case 'double': HEAPF64[((ptr)>>3)]=value; break;
+      default: abort('invalid type for setValue: ' + type);
+    }
+}
+Module['setValue'] = setValue;
+
+// Parallel to setValue.
+function getValue(ptr, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': return HEAP8[(ptr)];
+      case 'i8': return HEAP8[(ptr)];
+      case 'i16': return HEAP16[((ptr)>>1)];
+      case 'i32': return HEAP32[((ptr)>>2)];
+      case 'i64': return HEAP32[((ptr)>>2)];
+      case 'float': return HEAPF32[((ptr)>>2)];
+      case 'double': return HEAPF64[((ptr)>>3)];
+      default: abort('invalid type for setValue: ' + type);
+    }
+  return null;
+}
+Module['getValue'] = getValue;
+
+var ALLOC_NORMAL = 0; // Tries to use _malloc()
+var ALLOC_STACK = 1; // Lives for the duration of the current function call
+var ALLOC_STATIC = 2; // Cannot be freed
+var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
+var ALLOC_NONE = 4; // Do not allocate
+Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
+Module['ALLOC_STACK'] = ALLOC_STACK;
+Module['ALLOC_STATIC'] = ALLOC_STATIC;
+Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
+Module['ALLOC_NONE'] = ALLOC_NONE;
+
+// allocate(): This is for internal use. You can use it yourself as well, but the interface
+//             is a little tricky (see docs right below). The reason is that it is optimized
+//             for multiple syntaxes to save space in generated code. So you should
+//             normally not use allocate(), and instead allocate memory using _malloc(),
+//             initialize it with setValue(), and so forth.
+// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
+//        in *bytes* (note that this is sometimes confusing: the next parameter does not
+//        affect this!)
+// @types: Either an array of types, one for each byte (or 0 if no type at that position),
+//         or a single type which is used for the entire block. This only matters if there
+//         is initial data - if @slab is a number, then this does not matter at all and is
+//         ignored.
+// @allocator: How to allocate memory, see ALLOC_*
+function allocate(slab, types, allocator, ptr) {
+  var zeroinit, size;
+  if (typeof slab === 'number') {
+    zeroinit = true;
+    size = slab;
+  } else {
+    zeroinit = false;
+    size = slab.length;
+  }
+
+  var singleType = typeof types === 'string' ? types : null;
+
+  var ret;
+  if (allocator == ALLOC_NONE) {
+    ret = ptr;
+  } else {
+    ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
+  }
+
+  if (zeroinit) {
+    var ptr = ret, stop;
+    assert((ret & 3) == 0);
+    stop = ret + (size & ~3);
+    for (; ptr < stop; ptr += 4) {
+      HEAP32[((ptr)>>2)]=0;
+    }
+    stop = ret + size;
+    while (ptr < stop) {
+      HEAP8[((ptr++)|0)]=0;
+    }
+    return ret;
+  }
+
+  if (singleType === 'i8') {
+    if (slab.subarray || slab.slice) {
+      HEAPU8.set(slab, ret);
+    } else {
+      HEAPU8.set(new Uint8Array(slab), ret);
+    }
+    return ret;
+  }
+
+  var i = 0, type, typeSize, previousType;
+  while (i < size) {
+    var curr = slab[i];
+
+    if (typeof curr === 'function') {
+      curr = Runtime.getFunctionIndex(curr);
+    }
+
+    type = singleType || types[i];
+    if (type === 0) {
+      i++;
+      continue;
+    }
+
+    if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
+
+    setValue(ret+i, curr, type);
+
+    // no need to look up size unless type changes, so cache it
+    if (previousType !== type) {
+      typeSize = Runtime.getNativeTypeSize(type);
+      previousType = type;
+    }
+    i += typeSize;
+  }
+
+  return ret;
+}
+Module['allocate'] = allocate;
+
+function Pointer_stringify(ptr, /* optional */ length) {
+  // TODO: use TextDecoder
+  // Find the length, and check for UTF while doing so
+  var hasUtf = false;
+  var t;
+  var i = 0;
+  while (1) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    if (t >= 128) hasUtf = true;
+    else if (t == 0 && !length) break;
+    i++;
+    if (length && i == length) break;
+  }
+  if (!length) length = i;
+
+  var ret = '';
+
+  if (!hasUtf) {
+    var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack
+    var curr;
+    while (length > 0) {
+      curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
+      ret = ret ? ret + curr : curr;
+      ptr += MAX_CHUNK;
+      length -= MAX_CHUNK;
+    }
+    return ret;
+  }
+
+  var utf8 = new Runtime.UTF8Processor();
+  for (i = 0; i < length; i++) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    ret += utf8.processCChar(t);
+  }
+  return ret;
+}
+Module['Pointer_stringify'] = Pointer_stringify;
+
+// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF16ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
+    if (codeUnit == 0)
+      return str;
+    ++i;
+    // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
+    str += String.fromCharCode(codeUnit);
+  }
+}
+Module['UTF16ToString'] = UTF16ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF16LE form. The copy will require at most (str.length*2+1)*2 bytes of space in the HEAP.
+function stringToUTF16(str, outPtr) {
+  for(var i = 0; i < str.length; ++i) {
+    // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
+    var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
+    HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP16[(((outPtr)+(str.length*2))>>1)]=0;
+}
+Module['stringToUTF16'] = stringToUTF16;
+
+// Given a pointer 'ptr' to a null-terminated UTF32LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF32ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
+    if (utf32 == 0)
+      return str;
+    ++i;
+    // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
+    if (utf32 >= 0x10000) {
+      var ch = utf32 - 0x10000;
+      str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
+    } else {
+      str += String.fromCharCode(utf32);
+    }
+  }
+}
+Module['UTF32ToString'] = UTF32ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF32LE form. The copy will require at most (str.length+1)*4 bytes of space in the HEAP,
+// but can use less, since str.length does not return the number of characters in the string, but the number of UTF-16 code units in the string.
+function stringToUTF32(str, outPtr) {
+  var iChar = 0;
+  for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) {
+    // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
+    var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate
+    if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
+      var trailSurrogate = str.charCodeAt(++iCodeUnit);
+      codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
+    }
+    HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit;
+    ++iChar;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP32[(((outPtr)+(iChar*4))>>2)]=0;
+}
+Module['stringToUTF32'] = stringToUTF32;
+
+function demangle(func) {
+  var i = 3;
+  // params, etc.
+  var basicTypes = {
+    'v': 'void',
+    'b': 'bool',
+    'c': 'char',
+    's': 'short',
+    'i': 'int',
+    'l': 'long',
+    'f': 'float',
+    'd': 'double',
+    'w': 'wchar_t',
+    'a': 'signed char',
+    'h': 'unsigned char',
+    't': 'unsigned short',
+    'j': 'unsigned int',
+    'm': 'unsigned long',
+    'x': 'long long',
+    'y': 'unsigned long long',
+    'z': '...'
+  };
+  var subs = [];
+  var first = true;
+  function dump(x) {
+    //return;
+    if (x) Module.print(x);
+    Module.print(func);
+    var pre = '';
+    for (var a = 0; a < i; a++) pre += ' ';
+    Module.print (pre + '^');
+  }
+  function parseNested() {
+    i++;
+    if (func[i] === 'K') i++; // ignore const
+    var parts = [];
+    while (func[i] !== 'E') {
+      if (func[i] === 'S') { // substitution
+        i++;
+        var next = func.indexOf('_', i);
+        var num = func.substring(i, next) || 0;
+        parts.push(subs[num] || '?');
+        i = next+1;
+        continue;
+      }
+      if (func[i] === 'C') { // constructor
+        parts.push(parts[parts.length-1]);
+        i += 2;
+        continue;
+      }
+      var size = parseInt(func.substr(i));
+      var pre = size.toString().length;
+      if (!size || !pre) { i--; break; } // counter i++ below us
+      var curr = func.substr(i + pre, size);
+      parts.push(curr);
+      subs.push(curr);
+      i += pre + size;
+    }
+    i++; // skip E
+    return parts;
+  }
+  function parse(rawList, limit, allowVoid) { // main parser
+    limit = limit || Infinity;
+    var ret = '', list = [];
+    function flushList() {
+      return '(' + list.join(', ') + ')';
+    }
+    var name;
+    if (func[i] === 'N') {
+      // namespaced N-E
+      name = parseNested().join('::');
+      limit--;
+      if (limit === 0) return rawList ? [name] : name;
+    } else {
+      // not namespaced
+      if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L'
+      var size = parseInt(func.substr(i));
+      if (size) {
+        var pre = size.toString().length;
+        name = func.substr(i + pre, size);
+        i += pre + size;
+      }
+    }
+    first = false;
+    if (func[i] === 'I') {
+      i++;
+      var iList = parse(true);
+      var iRet = parse(true, 1, true);
+      ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>';
+    } else {
+      ret = name;
+    }
+    paramLoop: while (i < func.length && limit-- > 0) {
+      //dump('paramLoop');
+      var c = func[i++];
+      if (c in basicTypes) {
+        list.push(basicTypes[c]);
+      } else {
+        switch (c) {
+          case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer
+          case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference
+          case 'L': { // literal
+            i++; // skip basic type
+            var end = func.indexOf('E', i);
+            var size = end - i;
+            list.push(func.substr(i, size));
+            i += size + 2; // size + 'EE'
+            break;
+          }
+          case 'A': { // array
+            var size = parseInt(func.substr(i));
+            i += size.toString().length;
+            if (func[i] !== '_') throw '?';
+            i++; // skip _
+            list.push(parse(true, 1, true)[0] + ' [' + size + ']');
+            break;
+          }
+          case 'E': break paramLoop;
+          default: ret += '?' + c; break paramLoop;
+        }
+      }
+    }
+    if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void)
+    if (rawList) {
+      if (ret) {
+        list.push(ret + '?');
+      }
+      return list;
+    } else {
+      return ret + flushList();
+    }
+  }
+  try {
+    // Special-case the entry point, since its name differs from other name mangling.
+    if (func == 'Object._main' || func == '_main') {
+      return 'main()';
+    }
+    if (typeof func === 'number') func = Pointer_stringify(func);
+    if (func[0] !== '_') return func;
+    if (func[1] !== '_') return func; // C function
+    if (func[2] !== 'Z') return func;
+    switch (func[3]) {
+      case 'n': return 'operator new()';
+      case 'd': return 'operator delete()';
+    }
+    return parse();
+  } catch(e) {
+    return func;
+  }
+}
+
+function demangleAll(text) {
+  return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') });
+}
+
+function stackTrace() {
+  var stack = new Error().stack;
+  return stack ? demangleAll(stack) : '(no stack trace available)'; // Stack trace is not available at least on IE10 and Safari 6.
+}
+
+// Memory management
+
+var PAGE_SIZE = 4096;
+function alignMemoryPage(x) {
+  return (x+4095)&-4096;
+}
+
+var HEAP;
+var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
+
+var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area
+var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area
+var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk
+
+function enlargeMemory() {
+  abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
+}
+
+var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880;
+var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 134217728;
+var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152;
+
+var totalMemory = 4096;
+while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) {
+  if (totalMemory < 16*1024*1024) {
+    totalMemory *= 2;
+  } else {
+    totalMemory += 16*1024*1024
+  }
+}
+if (totalMemory !== TOTAL_MEMORY) {
+  Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be more reasonable');
+  TOTAL_MEMORY = totalMemory;
+}
+
+// Initialize the runtime's memory
+// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
+assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
+       'JS engine does not provide full typed array support');
+
+var buffer = new ArrayBuffer(TOTAL_MEMORY);
+HEAP8 = new Int8Array(buffer);
+HEAP16 = new Int16Array(buffer);
+HEAP32 = new Int32Array(buffer);
+HEAPU8 = new Uint8Array(buffer);
+HEAPU16 = new Uint16Array(buffer);
+HEAPU32 = new Uint32Array(buffer);
+HEAPF32 = new Float32Array(buffer);
+HEAPF64 = new Float64Array(buffer);
+
+// Endianness check (note: assumes compiler arch was little-endian)
+HEAP32[0] = 255;
+assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
+
+Module['HEAP'] = HEAP;
+Module['HEAP8'] = HEAP8;
+Module['HEAP16'] = HEAP16;
+Module['HEAP32'] = HEAP32;
+Module['HEAPU8'] = HEAPU8;
+Module['HEAPU16'] = HEAPU16;
+Module['HEAPU32'] = HEAPU32;
+Module['HEAPF32'] = HEAPF32;
+Module['HEAPF64'] = HEAPF64;
+
+function callRuntimeCallbacks(callbacks) {
+  while(callbacks.length > 0) {
+    var callback = callbacks.shift();
+    if (typeof callback == 'function') {
+      callback();
+      continue;
+    }
+    var func = callback.func;
+    if (typeof func === 'number') {
+      if (callback.arg === undefined) {
+        Runtime.dynCall('v', func);
+      } else {
+        Runtime.dynCall('vi', func, [callback.arg]);
+      }
+    } else {
+      func(callback.arg === undefined ? null : callback.arg);
+    }
+  }
+}
+
+var __ATPRERUN__  = []; // functions called before the runtime is initialized
+var __ATINIT__    = []; // functions called during startup
+var __ATMAIN__    = []; // functions called when main() is to be run
+var __ATEXIT__    = []; // functions called during shutdown
+var __ATPOSTRUN__ = []; // functions called after the runtime has exited
+
+var runtimeInitialized = false;
+
+function preRun() {
+  // compatibility - merge in anything from Module['preRun'] at this time
+  if (Module['preRun']) {
+    if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
+    while (Module['preRun'].length) {
+      addOnPreRun(Module['preRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPRERUN__);
+}
+
+function ensureInitRuntime() {
+  if (runtimeInitialized) return;
+  runtimeInitialized = true;
+  callRuntimeCallbacks(__ATINIT__);
+}
+
+function preMain() {
+  callRuntimeCallbacks(__ATMAIN__);
+}
+
+function exitRuntime() {
+  callRuntimeCallbacks(__ATEXIT__);
+}
+
+function postRun() {
+  // compatibility - merge in anything from Module['postRun'] at this time
+  if (Module['postRun']) {
+    if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
+    while (Module['postRun'].length) {
+      addOnPostRun(Module['postRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPOSTRUN__);
+}
+
+function addOnPreRun(cb) {
+  __ATPRERUN__.unshift(cb);
+}
+Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun;
+
+function addOnInit(cb) {
+  __ATINIT__.unshift(cb);
+}
+Module['addOnInit'] = Module.addOnInit = addOnInit;
+
+function addOnPreMain(cb) {
+  __ATMAIN__.unshift(cb);
+}
+Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain;
+
+function addOnExit(cb) {
+  __ATEXIT__.unshift(cb);
+}
+Module['addOnExit'] = Module.addOnExit = addOnExit;
+
+function addOnPostRun(cb) {
+  __ATPOSTRUN__.unshift(cb);
+}
+Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun;
+
+// Tools
+
+// This processes a JS string into a C-line array of numbers, 0-terminated.
+// For LLVM-originating strings, see parser.js:parseLLVMString function
+function intArrayFromString(stringy, dontAddNull, length /* optional */) {
+  var ret = (new Runtime.UTF8Processor()).processJSString(stringy);
+  if (length) {
+    ret.length = length;
+  }
+  if (!dontAddNull) {
+    ret.push(0);
+  }
+  return ret;
+}
+Module['intArrayFromString'] = intArrayFromString;
+
+function intArrayToString(array) {
+  var ret = [];
+  for (var i = 0; i < array.length; i++) {
+    var chr = array[i];
+    if (chr > 0xFF) {
+      chr &= 0xFF;
+    }
+    ret.push(String.fromCharCode(chr));
+  }
+  return ret.join('');
+}
+Module['intArrayToString'] = intArrayToString;
+
+// Write a Javascript array to somewhere in the heap
+function writeStringToMemory(string, buffer, dontAddNull) {
+  var array = intArrayFromString(string, dontAddNull);
+  var i = 0;
+  while (i < array.length) {
+    var chr = array[i];
+    HEAP8[(((buffer)+(i))|0)]=chr;
+    i = i + 1;
+  }
+}
+Module['writeStringToMemory'] = writeStringToMemory;
+
+function writeArrayToMemory(array, buffer) {
+  for (var i = 0; i < array.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=array[i];
+  }
+}
+Module['writeArrayToMemory'] = writeArrayToMemory;
+
+function writeAsciiToMemory(str, buffer, dontAddNull) {
+  for (var i = 0; i < str.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=str.charCodeAt(i);
+  }
+  if (!dontAddNull) HEAP8[(((buffer)+(str.length))|0)]=0;
+}
+Module['writeAsciiToMemory'] = writeAsciiToMemory;
+
+function unSign(value, bits, ignore) {
+  if (value >= 0) {
+    return value;
+  }
+  return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
+                    : Math.pow(2, bits)         + value;
+}
+function reSign(value, bits, ignore) {
+  if (value <= 0) {
+    return value;
+  }
+  var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
+                        : Math.pow(2, bits-1);
+  if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
+                                                       // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
+                                                       // TODO: In i64 mode 1, resign the two parts separately and safely
+    value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
+  }
+  return value;
+}
+
+// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
+if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) {
+  var ah  = a >>> 16;
+  var al = a & 0xffff;
+  var bh  = b >>> 16;
+  var bl = b & 0xffff;
+  return (al*bl + ((ah*bl + al*bh) << 16))|0;
+};
+Math.imul = Math['imul'];
+
+
+var Math_abs = Math.abs;
+var Math_cos = Math.cos;
+var Math_sin = Math.sin;
+var Math_tan = Math.tan;
+var Math_acos = Math.acos;
+var Math_asin = Math.asin;
+var Math_atan = Math.atan;
+var Math_atan2 = Math.atan2;
+var Math_exp = Math.exp;
+var Math_log = Math.log;
+var Math_sqrt = Math.sqrt;
+var Math_ceil = Math.ceil;
+var Math_floor = Math.floor;
+var Math_pow = Math.pow;
+var Math_imul = Math.imul;
+var Math_fround = Math.fround;
+var Math_min = Math.min;
+
+// A counter of dependencies for calling run(). If we need to
+// do asynchronous work before running, increment this and
+// decrement it. Incrementing must happen in a place like
+// PRE_RUN_ADDITIONS (used by emcc to add file preloading).
+// Note that you can add dependencies in preRun, even though
+// it happens right before run - run will be postponed until
+// the dependencies are met.
+var runDependencies = 0;
+var runDependencyWatcher = null;
+var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
+
+function addRunDependency(id) {
+  runDependencies++;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+}
+Module['addRunDependency'] = addRunDependency;
+function removeRunDependency(id) {
+  runDependencies--;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+  if (runDependencies == 0) {
+    if (runDependencyWatcher !== null) {
+      clearInterval(runDependencyWatcher);
+      runDependencyWatcher = null;
+    }
+    if (dependenciesFulfilled) {
+      var callback = dependenciesFulfilled;
+      dependenciesFulfilled = null;
+      callback(); // can add another dependenciesFulfilled
+    }
+  }
+}
+Module['removeRunDependency'] = removeRunDependency;
+
+Module["preloadedImages"] = {}; // maps url to image data
+Module["preloadedAudios"] = {}; // maps url to audio data
+
+
+var memoryInitializer = null;
+
+// === Body ===
+
+
+
+
+
+STATIC_BASE = 8;
+
+STATICTOP = STATIC_BASE + Runtime.alignMemory(531);
+/* global initializers */ __ATINIT__.push();
+
+
+/* memory initializer */ allocate([101,114,114,111,114,58,32,37,100,10,0,0,0,0,0,0,102,105,110,97,108,58,32,37,100,46,10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE);
+
+
+
+
+var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);
+
+assert(tempDoublePtr % 8 == 0);
+
+function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+}
+
+function copyTempDouble(ptr) {
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+  HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];
+
+  HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];
+
+  HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];
+
+  HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];
+
+}
+
+
+
+
+
+
+  var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};
+
+  var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can   access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};
+
+
+  var ___errno_state=0;function ___setErrNo(value) {
+      // For convenient setting and returning of errno.
+      HEAP32[((___errno_state)>>2)]=value;
+      return value;
+    }
+
+  var PATH={splitPath:function (filename) {
+        var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+        return splitPathRe.exec(filename).slice(1);
+      },normalizeArray:function (parts, allowAboveRoot) {
+        // if the path tries to go above the root, `up` ends up > 0
+        var up = 0;
+        for (var i = parts.length - 1; i >= 0; i--) {
+          var last = parts[i];
+          if (last === '.') {
+            parts.splice(i, 1);
+          } else if (last === '..') {
+            parts.splice(i, 1);
+            up++;
+          } else if (up) {
+            parts.splice(i, 1);
+            up--;
+          }
+        }
+        // if the path is allowed to go above the root, restore leading ..s
+        if (allowAboveRoot) {
+          for (; up--; up) {
+            parts.unshift('..');
+          }
+        }
+        return parts;
+      },normalize:function (path) {
+        var isAbsolute = path.charAt(0) === '/',
+            trailingSlash = path.substr(-1) === '/';
+        // Normalize the path
+        path = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), !isAbsolute).join('/');
+        if (!path && !isAbsolute) {
+          path = '.';
+        }
+        if (path && trailingSlash) {
+          path += '/';
+        }
+        return (isAbsolute ? '/' : '') + path;
+      },dirname:function (path) {
+        var result = PATH.splitPath(path),
+            root = result[0],
+            dir = result[1];
+        if (!root && !dir) {
+          // No dirname whatsoever
+          return '.';
+        }
+        if (dir) {
+          // It has a dirname, strip trailing slash
+          dir = dir.substr(0, dir.length - 1);
+        }
+        return root + dir;
+      },basename:function (path) {
+        // EMSCRIPTEN return '/'' for '/', not an empty string
+        if (path === '/') return '/';
+        var lastSlash = path.lastIndexOf('/');
+        if (lastSlash === -1) return path;
+        return path.substr(lastSlash+1);
+      },extname:function (path) {
+        return PATH.splitPath(path)[3];
+      },join:function () {
+        var paths = Array.prototype.slice.call(arguments, 0);
+        return PATH.normalize(paths.join('/'));
+      },join2:function (l, r) {
+        return PATH.normalize(l + '/' + r);
+      },resolve:function () {
+        var resolvedPath = '',
+          resolvedAbsolute = false;
+        for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+          var path = (i >= 0) ? arguments[i] : FS.cwd();
+          // Skip empty and invalid entries
+          if (typeof path !== 'string') {
+            throw new TypeError('Arguments to path.resolve must be strings');
+          } else if (!path) {
+            continue;
+          }
+          resolvedPath = path + '/' + resolvedPath;
+          resolvedAbsolute = path.charAt(0) === '/';
+        }
+        // At this point the path should be resolved to a full absolute path, but
+        // handle relative paths to be safe (might happen when process.cwd() fails)
+        resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
+          return !!p;
+        }), !resolvedAbsolute).join('/');
+        return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+      },relative:function (from, to) {
+        from = PATH.resolve(from).substr(1);
+        to = PATH.resolve(to).substr(1);
+        function trim(arr) {
+          var start = 0;
+          for (; start < arr.length; start++) {
+            if (arr[start] !== '') break;
+          }
+          var end = arr.length - 1;
+          for (; end >= 0; end--) {
+            if (arr[end] !== '') break;
+          }
+          if (start > end) return [];
+          return arr.slice(start, end - start + 1);
+        }
+        var fromParts = trim(from.split('/'));
+        var toParts = trim(to.split('/'));
+        var length = Math.min(fromParts.length, toParts.length);
+        var samePartsLength = length;
+        for (var i = 0; i < length; i++) {
+          if (fromParts[i] !== toParts[i]) {
+            samePartsLength = i;
+            break;
+          }
+        }
+        var outputParts = [];
+        for (var i = samePartsLength; i < fromParts.length; i++) {
+          outputParts.push('..');
+        }
+        outputParts = outputParts.concat(toParts.slice(samePartsLength));
+        return outputParts.join('/');
+      }};
+
+  var TTY={ttys:[],init:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // currently, FS.init does not distinguish if process.stdin is a file or TTY
+        //   // device, it always assumes it's a TTY device. because of this, we're forcing
+        //   // process.stdin to UTF8 encoding to at least make stdin reading compatible
+        //   // with text files until FS.init can be refactored.
+        //   process['stdin']['setEncoding']('utf8');
+        // }
+      },shutdown:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
+        //   // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
+        //   // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
+        //   // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
+        //   // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
+        //   process['stdin']['pause']();
+        // }
+      },register:function (dev, ops) {
+        TTY.ttys[dev] = { input: [], output: [], ops: ops };
+        FS.registerDevice(dev, TTY.stream_ops);
+      },stream_ops:{open:function (stream) {
+          var tty = TTY.ttys[stream.node.rdev];
+          if (!tty) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          stream.tty = tty;
+          stream.seekable = false;
+        },close:function (stream) {
+          // flush any pending line data
+          if (stream.tty.output.length) {
+            stream.tty.ops.put_char(stream.tty, 10);
+          }
+        },read:function (stream, buffer, offset, length, pos /* ignored */) {
+          if (!stream.tty || !stream.tty.ops.get_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          var bytesRead = 0;
+          for (var i = 0; i < length; i++) {
+            var result;
+            try {
+              result = stream.tty.ops.get_char(stream.tty);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            if (result === undefined && bytesRead === 0) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+            if (result === null || result === undefined) break;
+            bytesRead++;
+            buffer[offset+i] = result;
+          }
+          if (bytesRead) {
+            stream.node.timestamp = Date.now();
+          }
+          return bytesRead;
+        },write:function (stream, buffer, offset, length, pos) {
+          if (!stream.tty || !stream.tty.ops.put_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          for (var i = 0; i < length; i++) {
+            try {
+              stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+          }
+          if (length) {
+            stream.node.timestamp = Date.now();
+          }
+          return i;
+        }},default_tty_ops:{get_char:function (tty) {
+          if (!tty.input.length) {
+            var result = null;
+            if (ENVIRONMENT_IS_NODE) {
+              result = process['stdin']['read']();
+              if (!result) {
+                if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) {
+                  return null;  // EOF
+                }
+                return undefined;  // no data available
+              }
+            } else if (typeof window != 'undefined' &&
+              typeof window.prompt == 'function') {
+              // Browser.
+              result = window.prompt('Input: ');  // returns null on cancel
+              if (result !== null) {
+                result += '\n';
+              }
+            } else if (typeof readline == 'function') {
+              // Command line.
+              result = readline();
+              if (result !== null) {
+                result += '\n';
+              }
+            }
+            if (!result) {
+              return null;
+            }
+            tty.input = intArrayFromString(result, true);
+          }
+          return tty.input.shift();
+        },put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['print'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }},default_tty1_ops:{put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['printErr'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }}};
+
+  var MEMFS={ops_table:null,CONTENT_OWNING:1,CONTENT_FLEXIBLE:2,CONTENT_FIXED:3,mount:function (mount) {
+        return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
+          // no supported
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (!MEMFS.ops_table) {
+          MEMFS.ops_table = {
+            dir: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                lookup: MEMFS.node_ops.lookup,
+                mknod: MEMFS.node_ops.mknod,
+                rename: MEMFS.node_ops.rename,
+                unlink: MEMFS.node_ops.unlink,
+                rmdir: MEMFS.node_ops.rmdir,
+                readdir: MEMFS.node_ops.readdir,
+                symlink: MEMFS.node_ops.symlink
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek
+              }
+            },
+            file: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek,
+                read: MEMFS.stream_ops.read,
+                write: MEMFS.stream_ops.write,
+                allocate: MEMFS.stream_ops.allocate,
+                mmap: MEMFS.stream_ops.mmap
+              }
+            },
+            link: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                readlink: MEMFS.node_ops.readlink
+              },
+              stream: {}
+            },
+            chrdev: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: FS.chrdev_stream_ops
+            },
+          };
+        }
+        var node = FS.createNode(parent, name, mode, dev);
+        if (FS.isDir(node.mode)) {
+          node.node_ops = MEMFS.ops_table.dir.node;
+          node.stream_ops = MEMFS.ops_table.dir.stream;
+          node.contents = {};
+        } else if (FS.isFile(node.mode)) {
+          node.node_ops = MEMFS.ops_table.file.node;
+          node.stream_ops = MEMFS.ops_table.file.stream;
+          node.contents = [];
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        } else if (FS.isLink(node.mode)) {
+          node.node_ops = MEMFS.ops_table.link.node;
+          node.stream_ops = MEMFS.ops_table.link.stream;
+        } else if (FS.isChrdev(node.mode)) {
+          node.node_ops = MEMFS.ops_table.chrdev.node;
+          node.stream_ops = MEMFS.ops_table.chrdev.stream;
+        }
+        node.timestamp = Date.now();
+        // add the new node to the parent
+        if (parent) {
+          parent.contents[name] = node;
+        }
+        return node;
+      },ensureFlexible:function (node) {
+        if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
+          var contents = node.contents;
+          node.contents = Array.prototype.slice.call(contents);
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        }
+      },node_ops:{getattr:function (node) {
+          var attr = {};
+          // device numbers reuse inode numbers.
+          attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
+          attr.ino = node.id;
+          attr.mode = node.mode;
+          attr.nlink = 1;
+          attr.uid = 0;
+          attr.gid = 0;
+          attr.rdev = node.rdev;
+          if (FS.isDir(node.mode)) {
+            attr.size = 4096;
+          } else if (FS.isFile(node.mode)) {
+            attr.size = node.contents.length;
+          } else if (FS.isLink(node.mode)) {
+            attr.size = node.link.length;
+          } else {
+            attr.size = 0;
+          }
+          attr.atime = new Date(node.timestamp);
+          attr.mtime = new Date(node.timestamp);
+          attr.ctime = new Date(node.timestamp);
+          // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
+          //       but this is not required by the standard.
+          attr.blksize = 4096;
+          attr.blocks = Math.ceil(attr.size / attr.blksize);
+          return attr;
+        },setattr:function (node, attr) {
+          if (attr.mode !== undefined) {
+            node.mode = attr.mode;
+          }
+          if (attr.timestamp !== undefined) {
+            node.timestamp = attr.timestamp;
+          }
+          if (attr.size !== undefined) {
+            MEMFS.ensureFlexible(node);
+            var contents = node.contents;
+            if (attr.size < contents.length) contents.length = attr.size;
+            else while (attr.size > contents.length) contents.push(0);
+          }
+        },lookup:function (parent, name) {
+          throw FS.genericErrors[ERRNO_CODES.ENOENT];
+        },mknod:function (parent, name, mode, dev) {
+          return MEMFS.createNode(parent, name, mode, dev);
+        },rename:function (old_node, new_dir, new_name) {
+          // if we're overwriting a directory at new_name, make sure it's empty.
+          if (FS.isDir(old_node.mode)) {
+            var new_node;
+            try {
+              new_node = FS.lookupNode(new_dir, new_name);
+            } catch (e) {
+            }
+            if (new_node) {
+              for (var i in new_node.contents) {
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+              }
+            }
+          }
+          // do the internal rewiring
+          delete old_node.parent.contents[old_node.name];
+          old_node.name = new_name;
+          new_dir.contents[new_name] = old_node;
+          old_node.parent = new_dir;
+        },unlink:function (parent, name) {
+          delete parent.contents[name];
+        },rmdir:function (parent, name) {
+          var node = FS.lookupNode(parent, name);
+          for (var i in node.contents) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+          }
+          delete parent.contents[name];
+        },readdir:function (node) {
+          var entries = ['.', '..']
+          for (var key in node.contents) {
+            if (!node.contents.hasOwnProperty(key)) {
+              continue;
+            }
+            entries.push(key);
+          }
+          return entries;
+        },symlink:function (parent, newname, oldpath) {
+          var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
+          node.link = oldpath;
+          return node;
+        },readlink:function (node) {
+          if (!FS.isLink(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          return node.link;
+        }},stream_ops:{read:function (stream, buffer, offset, length, position) {
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (size > 8 && contents.subarray) { // non-trivial, and typed array
+            buffer.set(contents.subarray(position, position + size), offset);
+          } else
+          {
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          }
+          return size;
+        },write:function (stream, buffer, offset, length, position, canOwn) {
+          var node = stream.node;
+          node.timestamp = Date.now();
+          var contents = node.contents;
+          if (length && contents.length === 0 && position === 0 && buffer.subarray) {
+            // just replace it with the new data
+            if (canOwn && offset === 0) {
+              node.contents = buffer; // this could be a subarray of Emscripten HEAP, or allocated from some other source.
+              node.contentMode = (buffer.buffer === HEAP8.buffer) ? MEMFS.CONTENT_OWNING : MEMFS.CONTENT_FIXED;
+            } else {
+              node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
+              node.contentMode = MEMFS.CONTENT_FIXED;
+            }
+            return length;
+          }
+          MEMFS.ensureFlexible(node);
+          var contents = node.contents;
+          while (contents.length < position) contents.push(0);
+          for (var i = 0; i < length; i++) {
+            contents[position + i] = buffer[offset + i];
+          }
+          return length;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              position += stream.node.contents.length;
+            }
+          }
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          stream.ungotten = [];
+          stream.position = position;
+          return position;
+        },allocate:function (stream, offset, length) {
+          MEMFS.ensureFlexible(stream.node);
+          var contents = stream.node.contents;
+          var limit = offset + length;
+          while (limit > contents.length) contents.push(0);
+        },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+          if (!FS.isFile(stream.node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          var ptr;
+          var allocated;
+          var contents = stream.node.contents;
+          // Only make a new copy when MAP_PRIVATE is specified.
+          if ( !(flags & 2) &&
+                (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
+            // We can't emulate MAP_SHARED when the file is not backed by the buffer
+            // we're mapping to (e.g. the HEAP buffer).
+            allocated = false;
+            ptr = contents.byteOffset;
+          } else {
+            // Try to avoid unnecessary slices.
+            if (position > 0 || position + length < contents.length) {
+              if (contents.subarray) {
+                contents = contents.subarray(position, position + length);
+              } else {
+                contents = Array.prototype.slice.call(contents, position, position + length);
+              }
+            }
+            allocated = true;
+            ptr = _malloc(length);
+            if (!ptr) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOMEM);
+            }
+            buffer.set(contents, ptr);
+          }
+          return { ptr: ptr, allocated: allocated };
+        }}};
+
+  var IDBFS={dbs:{},indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) {
+        // reuse all of the core MEMFS functionality
+        return MEMFS.mount.apply(null, arguments);
+      },syncfs:function (mount, populate, callback) {
+        IDBFS.getLocalSet(mount, function(err, local) {
+          if (err) return callback(err);
+
+          IDBFS.getRemoteSet(mount, function(err, remote) {
+            if (err) return callback(err);
+
+            var src = populate ? remote : local;
+            var dst = populate ? local : remote;
+
+            IDBFS.reconcile(src, dst, callback);
+          });
+        });
+      },getDB:function (name, callback) {
+        // check the cache first
+        var db = IDBFS.dbs[name];
+        if (db) {
+          return callback(null, db);
+        }
+
+        var req;
+        try {
+          req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
+        } catch (e) {
+          return callback(e);
+        }
+        req.onupgradeneeded = function(e) {
+          var db = e.target.result;
+          var transaction = e.target.transaction;
+
+          var fileStore;
+
+          if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
+            fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          } else {
+            fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
+          }
+
+          fileStore.createIndex('timestamp', 'timestamp', { unique: false });
+        };
+        req.onsuccess = function() {
+          db = req.result;
+
+          // add to the cache
+          IDBFS.dbs[name] = db;
+          callback(null, db);
+        };
+        req.onerror = function() {
+          callback(this.error);
+        };
+      },getLocalSet:function (mount, callback) {
+        var entries = {};
+
+        function isRealDir(p) {
+          return p !== '.' && p !== '..';
+        };
+        function toAbsolute(root) {
+          return function(p) {
+            return PATH.join2(root, p);
+          }
+        };
+
+        var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
+
+        while (check.length) {
+          var path = check.pop();
+          var stat;
+
+          try {
+            stat = FS.stat(path);
+          } catch (e) {
+            return callback(e);
+          }
+
+          if (FS.isDir(stat.mode)) {
+            check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
+          }
+
+          entries[path] = { timestamp: stat.mtime };
+        }
+
+        return callback(null, { type: 'local', entries: entries });
+      },getRemoteSet:function (mount, callback) {
+        var entries = {};
+
+        IDBFS.getDB(mount.mountpoint, function(err, db) {
+          if (err) return callback(err);
+
+          var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly');
+          transaction.onerror = function() { callback(this.error); };
+
+          var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          var index = store.index('timestamp');
+
+          index.openKeyCursor().onsuccess = function(event) {
+            var cursor = event.target.result;
+
+            if (!cursor) {
+              return callback(null, { type: 'remote', db: db, entries: entries });
+            }
+
+            entries[cursor.primaryKey] = { timestamp: cursor.key };
+
+            cursor.continue();
+          };
+        });
+      },loadLocalEntry:function (path, callback) {
+        var stat, node;
+
+        try {
+          var lookup = FS.lookupPath(path);
+          node = lookup.node;
+          stat = FS.stat(path);
+        } catch (e) {
+          return callback(e);
+        }
+
+        if (FS.isDir(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode });
+        } else if (FS.isFile(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents });
+        } else {
+          return callback(new Error('node type not supported'));
+        }
+      },storeLocalEntry:function (path, entry, callback) {
+        try {
+          if (FS.isDir(entry.mode)) {
+            FS.mkdir(path, entry.mode);
+          } else if (FS.isFile(entry.mode)) {
+            FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true });
+          } else {
+            return callback(new Error('node type not supported'));
+          }
+
+          FS.utime(path, entry.timestamp, entry.timestamp);
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },removeLocalEntry:function (path, callback) {
+        try {
+          var lookup = FS.lookupPath(path);
+          var stat = FS.stat(path);
+
+          if (FS.isDir(stat.mode)) {
+            FS.rmdir(path);
+          } else if (FS.isFile(stat.mode)) {
+            FS.unlink(path);
+          }
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },loadRemoteEntry:function (store, path, callback) {
+        var req = store.get(path);
+        req.onsuccess = function(event) { callback(null, event.target.result); };
+        req.onerror = function() { callback(this.error); };
+      },storeRemoteEntry:function (store, path, entry, callback) {
+        var req = store.put(entry, path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },removeRemoteEntry:function (store, path, callback) {
+        var req = store.delete(path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },reconcile:function (src, dst, callback) {
+        var total = 0;
+
+        var create = [];
+        Object.keys(src.entries).forEach(function (key) {
+          var e = src.entries[key];
+          var e2 = dst.entries[key];
+          if (!e2 || e.timestamp > e2.timestamp) {
+            create.push(key);
+            total++;
+          }
+        });
+
+        var remove = [];
+        Object.keys(dst.entries).forEach(function (key) {
+          var e = dst.entries[key];
+          var e2 = src.entries[key];
+          if (!e2) {
+            remove.push(key);
+            total++;
+          }
+        });
+
+        if (!total) {
+          return callback(null);
+        }
+
+        var errored = false;
+        var completed = 0;
+        var db = src.type === 'remote' ? src.db : dst.db;
+        var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
+        var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= total) {
+            return callback(null);
+          }
+        };
+
+        transaction.onerror = function() { done(this.error); };
+
+        // sort paths in ascending order so directory entries are created
+        // before the files inside them
+        create.sort().forEach(function (path) {
+          if (dst.type === 'local') {
+            IDBFS.loadRemoteEntry(store, path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeLocalEntry(path, entry, done);
+            });
+          } else {
+            IDBFS.loadLocalEntry(path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeRemoteEntry(store, path, entry, done);
+            });
+          }
+        });
+
+        // sort paths in descending order so files are deleted before their
+        // parent directories
+        remove.sort().reverse().forEach(function(path) {
+          if (dst.type === 'local') {
+            IDBFS.removeLocalEntry(path, done);
+          } else {
+            IDBFS.removeRemoteEntry(store, path, done);
+          }
+        });
+      }};
+
+  var NODEFS={isWindows:false,staticInit:function () {
+        NODEFS.isWindows = !!process.platform.match(/^win/);
+      },mount:function (mount) {
+        assert(ENVIRONMENT_IS_NODE);
+        return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node = FS.createNode(parent, name, mode);
+        node.node_ops = NODEFS.node_ops;
+        node.stream_ops = NODEFS.stream_ops;
+        return node;
+      },getMode:function (path) {
+        var stat;
+        try {
+          stat = fs.lstatSync(path);
+          if (NODEFS.isWindows) {
+            // On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so
+            // propagate write bits to execute bits.
+            stat.mode = stat.mode | ((stat.mode & 146) >> 1);
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        return stat.mode;
+      },realPath:function (node) {
+        var parts = [];
+        while (node.parent !== node) {
+          parts.push(node.name);
+          node = node.parent;
+        }
+        parts.push(node.mount.opts.root);
+        parts.reverse();
+        return PATH.join.apply(null, parts);
+      },flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) {
+        if (flags in NODEFS.flagsToPermissionStringMap) {
+          return NODEFS.flagsToPermissionStringMap[flags];
+        } else {
+          return flags;
+        }
+      },node_ops:{getattr:function (node) {
+          var path = NODEFS.realPath(node);
+          var stat;
+          try {
+            stat = fs.lstatSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096.
+          // See http://support.microsoft.com/kb/140365
+          if (NODEFS.isWindows && !stat.blksize) {
+            stat.blksize = 4096;
+          }
+          if (NODEFS.isWindows && !stat.blocks) {
+            stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0;
+          }
+          return {
+            dev: stat.dev,
+            ino: stat.ino,
+            mode: stat.mode,
+            nlink: stat.nlink,
+            uid: stat.uid,
+            gid: stat.gid,
+            rdev: stat.rdev,
+            size: stat.size,
+            atime: stat.atime,
+            mtime: stat.mtime,
+            ctime: stat.ctime,
+            blksize: stat.blksize,
+            blocks: stat.blocks
+          };
+        },setattr:function (node, attr) {
+          var path = NODEFS.realPath(node);
+          try {
+            if (attr.mode !== undefined) {
+              fs.chmodSync(path, attr.mode);
+              // update the common node structure mode as well
+              node.mode = attr.mode;
+            }
+            if (attr.timestamp !== undefined) {
+              var date = new Date(attr.timestamp);
+              fs.utimesSync(path, date, date);
+            }
+            if (attr.size !== undefined) {
+              fs.truncateSync(path, attr.size);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },lookup:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          var mode = NODEFS.getMode(path);
+          return NODEFS.createNode(parent, name, mode);
+        },mknod:function (parent, name, mode, dev) {
+          var node = NODEFS.createNode(parent, name, mode, dev);
+          // create the backing node for this in the fs root as well
+          var path = NODEFS.realPath(node);
+          try {
+            if (FS.isDir(node.mode)) {
+              fs.mkdirSync(path, node.mode);
+            } else {
+              fs.writeFileSync(path, '', { mode: node.mode });
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return node;
+        },rename:function (oldNode, newDir, newName) {
+          var oldPath = NODEFS.realPath(oldNode);
+          var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
+          try {
+            fs.renameSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },unlink:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.unlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },rmdir:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.rmdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readdir:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },symlink:function (parent, newName, oldPath) {
+          var newPath = PATH.join2(NODEFS.realPath(parent), newName);
+          try {
+            fs.symlinkSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readlink:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        }},stream_ops:{open:function (stream) {
+          var path = NODEFS.realPath(stream.node);
+          try {
+            if (FS.isFile(stream.node.mode)) {
+              stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags));
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },close:function (stream) {
+          try {
+            if (FS.isFile(stream.node.mode) && stream.nfd) {
+              fs.closeSync(stream.nfd);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },read:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(length);
+          var res;
+          try {
+            res = fs.readSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          if (res > 0) {
+            for (var i = 0; i < res; i++) {
+              buffer[offset + i] = nbuffer[i];
+            }
+          }
+          return res;
+        },write:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(buffer.subarray(offset, offset + length));
+          var res;
+          try {
+            res = fs.writeSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return res;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              try {
+                var stat = fs.fstatSync(stream.nfd);
+                position += stat.size;
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+              }
+            }
+          }
+
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+
+          stream.position = position;
+          return position;
+        }}};
+
+  var _stdin=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stdout=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stderr=allocate(1, "i32*", ALLOC_STATIC);
+
+  function _fflush(stream) {
+      // int fflush(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html
+      // we don't currently perform any user-space buffering of data
+    }var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},handleFSError:function (e) {
+        if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
+        return ___setErrNo(e.errno);
+      },lookupPath:function (path, opts) {
+        path = PATH.resolve(FS.cwd(), path);
+        opts = opts || {};
+
+        var defaults = {
+          follow_mount: true,
+          recurse_count: 0
+        };
+        for (var key in defaults) {
+          if (opts[key] === undefined) {
+            opts[key] = defaults[key];
+          }
+        }
+
+        if (opts.recurse_count > 8) {  // max recursive lookup of 8
+          throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+        }
+
+        // split the path
+        var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), false);
+
+        // start at the root
+        var current = FS.root;
+        var current_path = '/';
+
+        for (var i = 0; i < parts.length; i++) {
+          var islast = (i === parts.length-1);
+          if (islast && opts.parent) {
+            // stop resolving
+            break;
+          }
+
+          current = FS.lookupNode(current, parts[i]);
+          current_path = PATH.join2(current_path, parts[i]);
+
+          // jump to the mount's root node if this is a mountpoint
+          if (FS.isMountpoint(current)) {
+            if (!islast || (islast && opts.follow_mount)) {
+              current = current.mounted.root;
+            }
+          }
+
+          // by default, lookupPath will not follow a symlink if it is the final path component.
+          // setting opts.follow = true will override this behavior.
+          if (!islast || opts.follow) {
+            var count = 0;
+            while (FS.isLink(current.mode)) {
+              var link = FS.readlink(current_path);
+              current_path = PATH.resolve(PATH.dirname(current_path), link);
+
+              var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
+              current = lookup.node;
+
+              if (count++ > 40) {  // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
+                throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+              }
+            }
+          }
+        }
+
+        return { path: current_path, node: current };
+      },getPath:function (node) {
+        var path;
+        while (true) {
+          if (FS.isRoot(node)) {
+            var mount = node.mount.mountpoint;
+            if (!path) return mount;
+            return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
+          }
+          path = path ? node.name + '/' + path : node.name;
+          node = node.parent;
+        }
+      },hashName:function (parentid, name) {
+        var hash = 0;
+
+
+        for (var i = 0; i < name.length; i++) {
+          hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
+        }
+        return ((parentid + hash) >>> 0) % FS.nameTable.length;
+      },hashAddNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        node.name_next = FS.nameTable[hash];
+        FS.nameTable[hash] = node;
+      },hashRemoveNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        if (FS.nameTable[hash] === node) {
+          FS.nameTable[hash] = node.name_next;
+        } else {
+          var current = FS.nameTable[hash];
+          while (current) {
+            if (current.name_next === node) {
+              current.name_next = node.name_next;
+              break;
+            }
+            current = current.name_next;
+          }
+        }
+      },lookupNode:function (parent, name) {
+        var err = FS.mayLookup(parent);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        var hash = FS.hashName(parent.id, name);
+        for (var node = FS.nameTable[hash]; node; node = node.name_next) {
+          var nodeName = node.name;
+          if (node.parent.id === parent.id && nodeName === name) {
+            return node;
+          }
+        }
+        // if we failed to find it in the cache, call into the VFS
+        return FS.lookup(parent, name);
+      },createNode:function (parent, name, mode, rdev) {
+        if (!FS.FSNode) {
+          FS.FSNode = function(parent, name, mode, rdev) {
+            if (!parent) {
+              parent = this;  // root node sets parent to itself
+            }
+            this.parent = parent;
+            this.mount = parent.mount;
+            this.mounted = null;
+            this.id = FS.nextInode++;
+            this.name = name;
+            this.mode = mode;
+            this.node_ops = {};
+            this.stream_ops = {};
+            this.rdev = rdev;
+          };
+
+          FS.FSNode.prototype = {};
+
+          // compatibility
+          var readMode = 292 | 73;
+          var writeMode = 146;
+
+          // NOTE we must use Object.defineProperties instead of individual calls to
+          // Object.defineProperty in order to make closure compiler happy
+          Object.defineProperties(FS.FSNode.prototype, {
+            read: {
+              get: function() { return (this.mode & readMode) === readMode; },
+              set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; }
+            },
+            write: {
+              get: function() { return (this.mode & writeMode) === writeMode; },
+              set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; }
+            },
+            isFolder: {
+              get: function() { return FS.isDir(this.mode); },
+            },
+            isDevice: {
+              get: function() { return FS.isChrdev(this.mode); },
+            },
+          });
+        }
+
+        var node = new FS.FSNode(parent, name, mode, rdev);
+
+        FS.hashAddNode(node);
+
+        return node;
+      },destroyNode:function (node) {
+        FS.hashRemoveNode(node);
+      },isRoot:function (node) {
+        return node === node.parent;
+      },isMountpoint:function (node) {
+        return !!node.mounted;
+      },isFile:function (mode) {
+        return (mode & 61440) === 32768;
+      },isDir:function (mode) {
+        return (mode & 61440) === 16384;
+      },isLink:function (mode) {
+        return (mode & 61440) === 40960;
+      },isChrdev:function (mode) {
+        return (mode & 61440) === 8192;
+      },isBlkdev:function (mode) {
+        return (mode & 61440) === 24576;
+      },isFIFO:function (mode) {
+        return (mode & 61440) === 4096;
+      },isSocket:function (mode) {
+        return (mode & 49152) === 49152;
+      },flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function (str) {
+        var flags = FS.flagModes[str];
+        if (typeof flags === 'undefined') {
+          throw new Error('Unknown file open mode: ' + str);
+        }
+        return flags;
+      },flagsToPermissionString:function (flag) {
+        var accmode = flag & 2097155;
+        var perms = ['r', 'w', 'rw'][accmode];
+        if ((flag & 512)) {
+          perms += 'w';
+        }
+        return perms;
+      },nodePermissions:function (node, perms) {
+        if (FS.ignorePermissions) {
+          return 0;
+        }
+        // return 0 if any user, group or owner bits are set.
+        if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
+          return ERRNO_CODES.EACCES;
+        }
+        return 0;
+      },mayLookup:function (dir) {
+        return FS.nodePermissions(dir, 'x');
+      },mayCreate:function (dir, name) {
+        try {
+          var node = FS.lookupNode(dir, name);
+          return ERRNO_CODES.EEXIST;
+        } catch (e) {
+        }
+        return FS.nodePermissions(dir, 'wx');
+      },mayDelete:function (dir, name, isdir) {
+        var node;
+        try {
+          node = FS.lookupNode(dir, name);
+        } catch (e) {
+          return e.errno;
+        }
+        var err = FS.nodePermissions(dir, 'wx');
+        if (err) {
+          return err;
+        }
+        if (isdir) {
+          if (!FS.isDir(node.mode)) {
+            return ERRNO_CODES.ENOTDIR;
+          }
+          if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
+            return ERRNO_CODES.EBUSY;
+          }
+        } else {
+          if (FS.isDir(node.mode)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return 0;
+      },mayOpen:function (node, flags) {
+        if (!node) {
+          return ERRNO_CODES.ENOENT;
+        }
+        if (FS.isLink(node.mode)) {
+          return ERRNO_CODES.ELOOP;
+        } else if (FS.isDir(node.mode)) {
+          if ((flags & 2097155) !== 0 ||  // opening for write
+              (flags & 512)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
+      },MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) {
+        fd_start = fd_start || 0;
+        fd_end = fd_end || FS.MAX_OPEN_FDS;
+        for (var fd = fd_start; fd <= fd_end; fd++) {
+          if (!FS.streams[fd]) {
+            return fd;
+          }
+        }
+        throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
+      },getStream:function (fd) {
+        return FS.streams[fd];
+      },createStream:function (stream, fd_start, fd_end) {
+        if (!FS.FSStream) {
+          FS.FSStream = function(){};
+          FS.FSStream.prototype = {};
+          // compatibility
+          Object.defineProperties(FS.FSStream.prototype, {
+            object: {
+              get: function() { return this.node; },
+              set: function(val) { this.node = val; }
+            },
+            isRead: {
+              get: function() { return (this.flags & 2097155) !== 1; }
+            },
+            isWrite: {
+              get: function() { return (this.flags & 2097155) !== 0; }
+            },
+            isAppend: {
+              get: function() { return (this.flags & 1024); }
+            }
+          });
+        }
+        if (0) {
+          // reuse the object
+          stream.__proto__ = FS.FSStream.prototype;
+        } else {
+          var newStream = new FS.FSStream();
+          for (var p in stream) {
+            newStream[p] = stream[p];
+          }
+          stream = newStream;
+        }
+        var fd = FS.nextfd(fd_start, fd_end);
+        stream.fd = fd;
+        FS.streams[fd] = stream;
+        return stream;
+      },closeStream:function (fd) {
+        FS.streams[fd] = null;
+      },getStreamFromPtr:function (ptr) {
+        return FS.streams[ptr - 1];
+      },getPtrForStream:function (stream) {
+        return stream ? stream.fd + 1 : 0;
+      },chrdev_stream_ops:{open:function (stream) {
+          var device = FS.getDevice(stream.node.rdev);
+          // override node's stream ops with the device's
+          stream.stream_ops = device.stream_ops;
+          // forward the open call
+          if (stream.stream_ops.open) {
+            stream.stream_ops.open(stream);
+          }
+        },llseek:function () {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }},major:function (dev) {
+        return ((dev) >> 8);
+      },minor:function (dev) {
+        return ((dev) & 0xff);
+      },makedev:function (ma, mi) {
+        return ((ma) << 8 | (mi));
+      },registerDevice:function (dev, ops) {
+        FS.devices[dev] = { stream_ops: ops };
+      },getDevice:function (dev) {
+        return FS.devices[dev];
+      },getMounts:function (mount) {
+        var mounts = [];
+        var check = [mount];
+
+        while (check.length) {
+          var m = check.pop();
+
+          mounts.push(m);
+
+          check.push.apply(check, m.mounts);
+        }
+
+        return mounts;
+      },syncfs:function (populate, callback) {
+        if (typeof(populate) === 'function') {
+          callback = populate;
+          populate = false;
+        }
+
+        var mounts = FS.getMounts(FS.root.mount);
+        var completed = 0;
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= mounts.length) {
+            callback(null);
+          }
+        };
+
+        // sync all mounts
+        mounts.forEach(function (mount) {
+          if (!mount.type.syncfs) {
+            return done(null);
+          }
+          mount.type.syncfs(mount, populate, done);
+        });
+      },mount:function (type, opts, mountpoint) {
+        var root = mountpoint === '/';
+        var pseudo = !mountpoint;
+        var node;
+
+        if (root && FS.root) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        } else if (!root && !pseudo) {
+          var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+          mountpoint = lookup.path;  // use the absolute path
+          node = lookup.node;
+
+          if (FS.isMountpoint(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+          }
+
+          if (!FS.isDir(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+          }
+        }
+
+        var mount = {
+          type: type,
+          opts: opts,
+          mountpoint: mountpoint,
+          mounts: []
+        };
+
+        // create a root node for the fs
+        var mountRoot = type.mount(mount);
+        mountRoot.mount = mount;
+        mount.root = mountRoot;
+
+        if (root) {
+          FS.root = mountRoot;
+        } else if (node) {
+          // set as a mountpoint
+          node.mounted = mount;
+
+          // add the new mount to the current mount's children
+          if (node.mount) {
+            node.mount.mounts.push(mount);
+          }
+        }
+
+        return mountRoot;
+      },unmount:function (mountpoint) {
+        var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+        if (!FS.isMountpoint(lookup.node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+
+        // destroy the nodes for this mount, and all its child mounts
+        var node = lookup.node;
+        var mount = node.mounted;
+        var mounts = FS.getMounts(mount);
+
+        Object.keys(FS.nameTable).forEach(function (hash) {
+          var current = FS.nameTable[hash];
+
+          while (current) {
+            var next = current.name_next;
+
+            if (mounts.indexOf(current.mount) !== -1) {
+              FS.destroyNode(current);
+            }
+
+            current = next;
+          }
+        });
+
+        // no longer a mountpoint
+        node.mounted = null;
+
+        // remove this mount from the child mounts
+        var idx = node.mount.mounts.indexOf(mount);
+        assert(idx !== -1);
+        node.mount.mounts.splice(idx, 1);
+      },lookup:function (parent, name) {
+        return parent.node_ops.lookup(parent, name);
+      },mknod:function (path, mode, dev) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var err = FS.mayCreate(parent, name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.mknod) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.mknod(parent, name, mode, dev);
+      },create:function (path, mode) {
+        mode = mode !== undefined ? mode : 438 /* 0666 */;
+        mode &= 4095;
+        mode |= 32768;
+        return FS.mknod(path, mode, 0);
+      },mkdir:function (path, mode) {
+        mode = mode !== undefined ? mode : 511 /* 0777 */;
+        mode &= 511 | 512;
+        mode |= 16384;
+        return FS.mknod(path, mode, 0);
+      },mkdev:function (path, mode, dev) {
+        if (typeof(dev) === 'undefined') {
+          dev = mode;
+          mode = 438 /* 0666 */;
+        }
+        mode |= 8192;
+        return FS.mknod(path, mode, dev);
+      },symlink:function (oldpath, newpath) {
+        var lookup = FS.lookupPath(newpath, { parent: true });
+        var parent = lookup.node;
+        var newname = PATH.basename(newpath);
+        var err = FS.mayCreate(parent, newname);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.symlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.symlink(parent, newname, oldpath);
+      },rename:function (old_path, new_path) {
+        var old_dirname = PATH.dirname(old_path);
+        var new_dirname = PATH.dirname(new_path);
+        var old_name = PATH.basename(old_path);
+        var new_name = PATH.basename(new_path);
+        // parents must exist
+        var lookup, old_dir, new_dir;
+        try {
+          lookup = FS.lookupPath(old_path, { parent: true });
+          old_dir = lookup.node;
+          lookup = FS.lookupPath(new_path, { parent: true });
+          new_dir = lookup.node;
+        } catch (e) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // need to be part of the same mount
+        if (old_dir.mount !== new_dir.mount) {
+          throw new FS.ErrnoError(ERRNO_CODES.EXDEV);
+        }
+        // source must exist
+        var old_node = FS.lookupNode(old_dir, old_name);
+        // old path should not be an ancestor of the new path
+        var relative = PATH.relative(old_path, new_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        // new path should not be an ancestor of the old path
+        relative = PATH.relative(new_path, old_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+        }
+        // see if the new path already exists
+        var new_node;
+        try {
+          new_node = FS.lookupNode(new_dir, new_name);
+        } catch (e) {
+          // not fatal
+        }
+        // early out if nothing needs to change
+        if (old_node === new_node) {
+          return;
+        }
+        // we'll need to delete the old entry
+        var isdir = FS.isDir(old_node.mode);
+        var err = FS.mayDelete(old_dir, old_name, isdir);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // need delete permissions if we'll be overwriting.
+        // need create permissions if new doesn't already exist.
+        err = new_node ?
+          FS.mayDelete(new_dir, new_name, isdir) :
+          FS.mayCreate(new_dir, new_name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!old_dir.node_ops.rename) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // if we are going to change the parent, check write permissions
+        if (new_dir !== old_dir) {
+          err = FS.nodePermissions(old_dir, 'w');
+          if (err) {
+            throw new FS.ErrnoError(err);
+          }
+        }
+        // remove the node from the lookup hash
+        FS.hashRemoveNode(old_node);
+        // do the underlying fs rename
+        try {
+          old_dir.node_ops.rename(old_node, new_dir, new_name);
+        } catch (e) {
+          throw e;
+        } finally {
+          // add the node back to the hash (in case node_ops.rename
+          // changed its name)
+          FS.hashAddNode(old_node);
+        }
+      },rmdir:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, true);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.rmdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.rmdir(parent, name);
+        FS.destroyNode(node);
+      },readdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        if (!node.node_ops.readdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        return node.node_ops.readdir(node);
+      },unlink:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, false);
+        if (err) {
+          // POSIX says unlink should set EPERM, not EISDIR
+          if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM;
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.unlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.unlink(parent, name);
+        FS.destroyNode(node);
+      },readlink:function (path) {
+        var lookup = FS.lookupPath(path);
+        var link = lookup.node;
+        if (!link.node_ops.readlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        return link.node_ops.readlink(link);
+      },stat:function (path, dontFollow) {
+        var lookup = FS.lookupPath(path, { follow: !dontFollow });
+        var node = lookup.node;
+        if (!node.node_ops.getattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return node.node_ops.getattr(node);
+      },lstat:function (path) {
+        return FS.stat(path, true);
+      },chmod:function (path, mode, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          mode: (mode & 4095) | (node.mode & ~4095),
+          timestamp: Date.now()
+        });
+      },lchmod:function (path, mode) {
+        FS.chmod(path, mode, true);
+      },fchmod:function (fd, mode) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chmod(stream.node, mode);
+      },chown:function (path, uid, gid, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          timestamp: Date.now()
+          // we ignore the uid / gid for now
+        });
+      },lchown:function (path, uid, gid) {
+        FS.chown(path, uid, gid, true);
+      },fchown:function (fd, uid, gid) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chown(stream.node, uid, gid);
+      },truncate:function (path, len) {
+        if (len < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: true });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!FS.isFile(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var err = FS.nodePermissions(node, 'w');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        node.node_ops.setattr(node, {
+          size: len,
+          timestamp: Date.now()
+        });
+      },ftruncate:function (fd, len) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        FS.truncate(stream.node, len);
+      },utime:function (path, atime, mtime) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        node.node_ops.setattr(node, {
+          timestamp: Math.max(atime, mtime)
+        });
+      },open:function (path, flags, mode, fd_start, fd_end) {
+        flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
+        mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
+        if ((flags & 64)) {
+          mode = (mode & 4095) | 32768;
+        } else {
+          mode = 0;
+        }
+        var node;
+        if (typeof path === 'object') {
+          node = path;
+        } else {
+          path = PATH.normalize(path);
+          try {
+            var lookup = FS.lookupPath(path, {
+              follow: !(flags & 131072)
+            });
+            node = lookup.node;
+          } catch (e) {
+            // ignore
+          }
+        }
+        // perhaps we need to create the node
+        if ((flags & 64)) {
+          if (node) {
+            // if O_CREAT and O_EXCL are set, error out if the node already exists
+            if ((flags & 128)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EEXIST);
+            }
+          } else {
+            // node doesn't exist, try to create it
+            node = FS.mknod(path, mode, 0);
+          }
+        }
+        if (!node) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
+        }
+        // can't truncate a device
+        if (FS.isChrdev(node.mode)) {
+          flags &= ~512;
+        }
+        // check permissions
+        var err = FS.mayOpen(node, flags);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // do truncation if necessary
+        if ((flags & 512)) {
+          FS.truncate(node, 0);
+        }
+        // we've already handled these, don't pass down to the underlying vfs
+        flags &= ~(128 | 512);
+
+        // register the stream with the filesystem
+        var stream = FS.createStream({
+          node: node,
+          path: FS.getPath(node),  // we want the absolute path to the node
+          flags: flags,
+          seekable: true,
+          position: 0,
+          stream_ops: node.stream_ops,
+          // used by the file family libc calls (fopen, fwrite, ferror, etc.)
+          ungotten: [],
+          error: false
+        }, fd_start, fd_end);
+        // call the new stream's open function
+        if (stream.stream_ops.open) {
+          stream.stream_ops.open(stream);
+        }
+        if (Module['logReadFiles'] && !(flags & 1)) {
+          if (!FS.readFiles) FS.readFiles = {};
+          if (!(path in FS.readFiles)) {
+            FS.readFiles[path] = 1;
+            Module['printErr']('read file: ' + path);
+          }
+        }
+        return stream;
+      },close:function (stream) {
+        try {
+          if (stream.stream_ops.close) {
+            stream.stream_ops.close(stream);
+          }
+        } catch (e) {
+          throw e;
+        } finally {
+          FS.closeStream(stream.fd);
+        }
+      },llseek:function (stream, offset, whence) {
+        if (!stream.seekable || !stream.stream_ops.llseek) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        return stream.stream_ops.llseek(stream, offset, whence);
+      },read:function (stream, buffer, offset, length, position) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.read) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
+        if (!seeking) stream.position += bytesRead;
+        return bytesRead;
+      },write:function (stream, buffer, offset, length, position, canOwn) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.write) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        if (stream.flags & 1024) {
+          // seek to the end before writing in append mode
+          FS.llseek(stream, 0, 2);
+        }
+        var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
+        if (!seeking) stream.position += bytesWritten;
+        return bytesWritten;
+      },allocate:function (stream, offset, length) {
+        if (offset < 0 || length <= 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        if (!stream.stream_ops.allocate) {
+          throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+        }
+        stream.stream_ops.allocate(stream, offset, length);
+      },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+        // TODO if PROT is PROT_WRITE, make sure we have write access
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EACCES);
+        }
+        if (!stream.stream_ops.mmap) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
+      },ioctl:function (stream, cmd, arg) {
+        if (!stream.stream_ops.ioctl) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTTY);
+        }
+        return stream.stream_ops.ioctl(stream, cmd, arg);
+      },readFile:function (path, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'r';
+        opts.encoding = opts.encoding || 'binary';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var ret;
+        var stream = FS.open(path, opts.flags);
+        var stat = FS.stat(path);
+        var length = stat.size;
+        var buf = new Uint8Array(length);
+        FS.read(stream, buf, 0, length, 0);
+        if (opts.encoding === 'utf8') {
+          ret = '';
+          var utf8 = new Runtime.UTF8Processor();
+          for (var i = 0; i < length; i++) {
+            ret += utf8.processCChar(buf[i]);
+          }
+        } else if (opts.encoding === 'binary') {
+          ret = buf;
+        }
+        FS.close(stream);
+        return ret;
+      },writeFile:function (path, data, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'w';
+        opts.encoding = opts.encoding || 'utf8';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var stream = FS.open(path, opts.flags, opts.mode);
+        if (opts.encoding === 'utf8') {
+          var utf8 = new Runtime.UTF8Processor();
+          var buf = new Uint8Array(utf8.processJSString(data));
+          FS.write(stream, buf, 0, buf.length, 0, opts.canOwn);
+        } else if (opts.encoding === 'binary') {
+          FS.write(stream, data, 0, data.length, 0, opts.canOwn);
+        }
+        FS.close(stream);
+      },cwd:function () {
+        return FS.currentPath;
+      },chdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        if (!FS.isDir(lookup.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        var err = FS.nodePermissions(lookup.node, 'x');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        FS.currentPath = lookup.path;
+      },createDefaultDirectories:function () {
+        FS.mkdir('/tmp');
+      },createDefaultDevices:function () {
+        // create /dev
+        FS.mkdir('/dev');
+        // setup /dev/null
+        FS.registerDevice(FS.makedev(1, 3), {
+          read: function() { return 0; },
+          write: function() { return 0; }
+        });
+        FS.mkdev('/dev/null', FS.makedev(1, 3));
+        // setup /dev/tty and /dev/tty1
+        // stderr needs to print output using Module['printErr']
+        // so we register a second tty just for it.
+        TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
+        TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
+        FS.mkdev('/dev/tty', FS.makedev(5, 0));
+        FS.mkdev('/dev/tty1', FS.makedev(6, 0));
+        // we're not going to emulate the actual shm device,
+        // just create the tmp dirs that reside in it commonly
+        FS.mkdir('/dev/shm');
+        FS.mkdir('/dev/shm/tmp');
+      },createStandardStreams:function () {
+        // TODO deprecate the old functionality of a single
+        // input / output callback and that utilizes FS.createDevice
+        // and instead require a unique set of stream ops
+
+        // by default, we symlink the standard streams to the
+        // default tty devices. however, if the standard streams
+        // have been overwritten we create a unique device for
+        // them instead.
+        if (Module['stdin']) {
+          FS.createDevice('/dev', 'stdin', Module['stdin']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdin');
+        }
+        if (Module['stdout']) {
+          FS.createDevice('/dev', 'stdout', null, Module['stdout']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdout');
+        }
+        if (Module['stderr']) {
+          FS.createDevice('/dev', 'stderr', null, Module['stderr']);
+        } else {
+          FS.symlink('/dev/tty1', '/dev/stderr');
+        }
+
+        // open default streams for the stdin, stdout and stderr devices
+        var stdin = FS.open('/dev/stdin', 'r');
+        HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin);
+        assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
+
+        var stdout = FS.open('/dev/stdout', 'w');
+        HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout);
+        assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
+
+        var stderr = FS.open('/dev/stderr', 'w');
+        HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr);
+        assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
+      },ensureErrnoError:function () {
+        if (FS.ErrnoError) return;
+        FS.ErrnoError = function ErrnoError(errno) {
+          this.errno = errno;
+          for (var key in ERRNO_CODES) {
+            if (ERRNO_CODES[key] === errno) {
+              this.code = key;
+              break;
+            }
+          }
+          this.message = ERRNO_MESSAGES[errno];
+        };
+        FS.ErrnoError.prototype = new Error();
+        FS.ErrnoError.prototype.constructor = FS.ErrnoError;
+        // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
+        [ERRNO_CODES.ENOENT].forEach(function(code) {
+          FS.genericErrors[code] = new FS.ErrnoError(code);
+          FS.genericErrors[code].stack = '<generic error, no stack>';
+        });
+      },staticInit:function () {
+        FS.ensureErrnoError();
+
+        FS.nameTable = new Array(4096);
+
+        FS.mount(MEMFS, {}, '/');
+
+        FS.createDefaultDirectories();
+        FS.createDefaultDevices();
+      },init:function (input, output, error) {
+        assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
+        FS.init.initialized = true;
+
+        FS.ensureErrnoError();
+
+        // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
+        Module['stdin'] = input || Module['stdin'];
+        Module['stdout'] = output || Module['stdout'];
+        Module['stderr'] = error || Module['stderr'];
+
+        FS.createStandardStreams();
+      },quit:function () {
+        FS.init.initialized = false;
+        for (var i = 0; i < FS.streams.length; i++) {
+          var stream = FS.streams[i];
+          if (!stream) {
+            continue;
+          }
+          FS.close(stream);
+        }
+      },getMode:function (canRead, canWrite) {
+        var mode = 0;
+        if (canRead) mode |= 292 | 73;
+        if (canWrite) mode |= 146;
+        return mode;
+      },joinPath:function (parts, forceRelative) {
+        var path = PATH.join.apply(null, parts);
+        if (forceRelative && path[0] == '/') path = path.substr(1);
+        return path;
+      },absolutePath:function (relative, base) {
+        return PATH.resolve(base, relative);
+      },standardizePath:function (path) {
+        return PATH.normalize(path);
+      },findObject:function (path, dontResolveLastLink) {
+        var ret = FS.analyzePath(path, dontResolveLastLink);
+        if (ret.exists) {
+          return ret.object;
+        } else {
+          ___setErrNo(ret.error);
+          return null;
+        }
+      },analyzePath:function (path, dontResolveLastLink) {
+        // operate from within the context of the symlink's target
+        try {
+          var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          path = lookup.path;
+        } catch (e) {
+        }
+        var ret = {
+          isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
+          parentExists: false, parentPath: null, parentObject: null
+        };
+        try {
+          var lookup = FS.lookupPath(path, { parent: true });
+          ret.parentExists = true;
+          ret.parentPath = lookup.path;
+          ret.parentObject = lookup.node;
+          ret.name = PATH.basename(path);
+          lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          ret.exists = true;
+          ret.path = lookup.path;
+          ret.object = lookup.node;
+          ret.name = lookup.node.name;
+          ret.isRoot = lookup.path === '/';
+        } catch (e) {
+          ret.error = e.errno;
+        };
+        return ret;
+      },createFolder:function (parent, name, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.mkdir(path, mode);
+      },createPath:function (parent, path, canRead, canWrite) {
+        parent = typeof parent === 'string' ? parent : FS.getPath(parent);
+        var parts = path.split('/').reverse();
+        while (parts.length) {
+          var part = parts.pop();
+          if (!part) continue;
+          var current = PATH.join2(parent, part);
+          try {
+            FS.mkdir(current);
+          } catch (e) {
+            // ignore EEXIST
+          }
+          parent = current;
+        }
+        return current;
+      },createFile:function (parent, name, properties, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.create(path, mode);
+      },createDataFile:function (parent, name, data, canRead, canWrite, canOwn) {
+        var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
+        var mode = FS.getMode(canRead, canWrite);
+        var node = FS.create(path, mode);
+        if (data) {
+          if (typeof data === 'string') {
+            var arr = new Array(data.length);
+            for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
+            data = arr;
+          }
+          // make sure we can write to the file
+          FS.chmod(node, mode | 146);
+          var stream = FS.open(node, 'w');
+          FS.write(stream, data, 0, data.length, 0, canOwn);
+          FS.close(stream);
+          FS.chmod(node, mode);
+        }
+        return node;
+      },createDevice:function (parent, name, input, output) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(!!input, !!output);
+        if (!FS.createDevice.major) FS.createDevice.major = 64;
+        var dev = FS.makedev(FS.createDevice.major++, 0);
+        // Create a fake device that a set of stream ops to emulate
+        // the old behavior.
+        FS.registerDevice(dev, {
+          open: function(stream) {
+            stream.seekable = false;
+          },
+          close: function(stream) {
+            // flush any pending line data
+            if (output && output.buffer && output.buffer.length) {
+              output(10);
+            }
+          },
+          read: function(stream, buffer, offset, length, pos /* ignored */) {
+            var bytesRead = 0;
+            for (var i = 0; i < length; i++) {
+              var result;
+              try {
+                result = input();
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+              if (result === undefined && bytesRead === 0) {
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+              if (result === null || result === undefined) break;
+              bytesRead++;
+              buffer[offset+i] = result;
+            }
+            if (bytesRead) {
+              stream.node.timestamp = Date.now();
+            }
+            return bytesRead;
+          },
+          write: function(stream, buffer, offset, length, pos) {
+            for (var i = 0; i < length; i++) {
+              try {
+                output(buffer[offset+i]);
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+            }
+            if (length) {
+              stream.node.timestamp = Date.now();
+            }
+            return i;
+          }
+        });
+        return FS.mkdev(path, mode, dev);
+      },createLink:function (parent, name, target, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        return FS.symlink(target, path);
+      },forceLoadFile:function (obj) {
+        if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
+        var success = true;
+        if (typeof XMLHttpRequest !== 'undefined') {
+          throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
+        } else if (Module['read']) {
+          // Command-line.
+          try {
+            // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
+            //          read() will try to parse UTF8.
+            obj.contents = intArrayFromString(Module['read'](obj.url), true);
+          } catch (e) {
+            success = false;
+          }
+        } else {
+          throw new Error('Cannot load without read() or XMLHttpRequest.');
+        }
+        if (!success) ___setErrNo(ERRNO_CODES.EIO);
+        return success;
+      },createLazyFile:function (parent, name, url, canRead, canWrite) {
+        // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
+        function LazyUint8Array() {
+          this.lengthKnown = false;
+          this.chunks = []; // Loaded chunks. Index is the chunk number
+        }
+        LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
+          if (idx > this.length-1 || idx < 0) {
+            return undefined;
+          }
+          var chunkOffset = idx % this.chunkSize;
+          var chunkNum = Math.floor(idx / this.chunkSize);
+          return this.getter(chunkNum)[chunkOffset];
+        }
+        LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
+          this.getter = getter;
+        }
+        LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
+            // Find length
+            var xhr = new XMLHttpRequest();
+            xhr.open('HEAD', url, false);
+            xhr.send(null);
+            if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+            var datalength = Number(xhr.getResponseHeader("Content-length"));
+            var header;
+            var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
+            var chunkSize = 1024*1024; // Chunk size in bytes
+
+            if (!hasByteServing) chunkSize = datalength;
+
+            // Function to get a range from the remote URL.
+            var doXHR = (function(from, to) {
+              if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
+              if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
+
+              // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
+              var xhr = new XMLHttpRequest();
+              xhr.open('GET', url, false);
+              if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
+
+              // Some hints to the browser that we want binary data.
+              if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
+              if (xhr.overrideMimeType) {
+                xhr.overrideMimeType('text/plain; charset=x-user-defined');
+              }
+
+              xhr.send(null);
+              if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+              if (xhr.response !== undefined) {
+                return new Uint8Array(xhr.response || []);
+              } else {
+                return intArrayFromString(xhr.responseText || '', true);
+              }
+            });
+            var lazyArray = this;
+            lazyArray.setDataGetter(function(chunkNum) {
+              var start = chunkNum * chunkSize;
+              var end = (chunkNum+1) * chunkSize - 1; // including this byte
+              end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
+                lazyArray.chunks[chunkNum] = doXHR(start, end);
+              }
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
+              return lazyArray.chunks[chunkNum];
+            });
+
+            this._length = datalength;
+            this._chunkSize = chunkSize;
+            this.lengthKnown = true;
+        }
+        if (typeof XMLHttpRequest !== 'undefined') {
+          if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
+          var lazyArray = new LazyUint8Array();
+          Object.defineProperty(lazyArray, "length", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._length;
+              }
+          });
+          Object.defineProperty(lazyArray, "chunkSize", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._chunkSize;
+              }
+          });
+
+          var properties = { isDevice: false, contents: lazyArray };
+        } else {
+          var properties = { isDevice: false, url: url };
+        }
+
+        var node = FS.createFile(parent, name, properties, canRead, canWrite);
+        // This is a total hack, but I want to get this lazy file code out of the
+        // core of MEMFS. If we want to keep this lazy file concept I feel it should
+        // be its own thin LAZYFS proxying calls to MEMFS.
+        if (properties.contents) {
+          node.contents = properties.contents;
+        } else if (properties.url) {
+          node.contents = null;
+          node.url = properties.url;
+        }
+        // override each stream op with one that tries to force load the lazy file first
+        var stream_ops = {};
+        var keys = Object.keys(node.stream_ops);
+        keys.forEach(function(key) {
+          var fn = node.stream_ops[key];
+          stream_ops[key] = function forceLoadLazyFile() {
+            if (!FS.forceLoadFile(node)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            return fn.apply(null, arguments);
+          };
+        });
+        // use a custom read function
+        stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
+          if (!FS.forceLoadFile(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EIO);
+          }
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (contents.slice) { // normal array
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          } else {
+            for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
+              buffer[offset + i] = contents.get(position + i);
+            }
+          }
+          return size;
+        };
+        node.stream_ops = stream_ops;
+        return node;
+      },createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
+        Browser.init();
+        // TODO we should allow people to just pass in a complete filename instead
+        // of parent and name being that we just join them anyways
+        var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent;
+        function processData(byteArray) {
+          function finish(byteArray) {
+            if (!dontCreateFile) {
+              FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
+            }
+            if (onload) onload();
+            removeRunDependency('cp ' + fullname);
+          }
+          var handled = false;
+          Module['preloadPlugins'].forEach(function(plugin) {
+            if (handled) return;
+            if (plugin['canHandle'](fullname)) {
+              plugin['handle'](byteArray, fullname, finish, function() {
+                if (onerror) onerror();
+                removeRunDependency('cp ' + fullname);
+              });
+              handled = true;
+            }
+          });
+          if (!handled) finish(byteArray);
+        }
+        addRunDependency('cp ' + fullname);
+        if (typeof url == 'string') {
+          Browser.asyncLoad(url, function(byteArray) {
+            processData(byteArray);
+          }, onerror);
+        } else {
+          processData(url);
+        }
+      },indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_NAME:function () {
+        return 'EM_FS_' + window.location.pathname;
+      },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
+          console.log('creating db');
+          var db = openRequest.result;
+          db.createObjectStore(FS.DB_STORE_NAME);
+        };
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var putRequest = files.put(FS.analyzePath(path).object.contents, path);
+            putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
+            putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      },loadFilesFromDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = onerror; // no database to load from
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          try {
+            var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
+          } catch(e) {
+            onerror(e);
+            return;
+          }
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var getRequest = files.get(path);
+            getRequest.onsuccess = function getRequest_onsuccess() {
+              if (FS.analyzePath(path).exists) {
+                FS.unlink(path);
+              }
+              FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
+              ok++;
+              if (ok + fail == total) finish();
+            };
+            getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      }};
+
+
+
+
+  function _mkport() { throw 'TODO' }var SOCKFS={mount:function (mount) {
+        return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createSocket:function (family, type, protocol) {
+        var streaming = type == 1;
+        if (protocol) {
+          assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp
+        }
+
+        // create our internal socket structure
+        var sock = {
+          family: family,
+          type: type,
+          protocol: protocol,
+          server: null,
+          peers: {},
+          pending: [],
+          recv_queue: [],
+          sock_ops: SOCKFS.websocket_sock_ops
+        };
+
+        // create the filesystem node to store the socket structure
+        var name = SOCKFS.nextname();
+        var node = FS.createNode(SOCKFS.root, name, 49152, 0);
+        node.sock = sock;
+
+        // and the wrapping stream that enables library functions such
+        // as read and write to indirectly interact with the socket
+        var stream = FS.createStream({
+          path: name,
+          node: node,
+          flags: FS.modeStringToFlags('r+'),
+          seekable: false,
+          stream_ops: SOCKFS.stream_ops
+        });
+
+        // map the new stream to the socket structure (sockets have a 1:1
+        // relationship with a stream)
+        sock.stream = stream;
+
+        return sock;
+      },getSocket:function (fd) {
+        var stream = FS.getStream(fd);
+        if (!stream || !FS.isSocket(stream.node.mode)) {
+          return null;
+        }
+        return stream.node.sock;
+      },stream_ops:{poll:function (stream) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.poll(sock);
+        },ioctl:function (stream, request, varargs) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.ioctl(sock, request, varargs);
+        },read:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          var msg = sock.sock_ops.recvmsg(sock, length);
+          if (!msg) {
+            // socket is closed
+            return 0;
+          }
+          buffer.set(msg.buffer, offset);
+          return msg.buffer.length;
+        },write:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.sendmsg(sock, buffer, offset, length);
+        },close:function (stream) {
+          var sock = stream.node.sock;
+          sock.sock_ops.close(sock);
+        }},nextname:function () {
+        if (!SOCKFS.nextname.current) {
+          SOCKFS.nextname.current = 0;
+        }
+        return 'socket[' + (SOCKFS.nextname.current++) + ']';
+      },websocket_sock_ops:{createPeer:function (sock, addr, port) {
+          var ws;
+
+          if (typeof addr === 'object') {
+            ws = addr;
+            addr = null;
+            port = null;
+          }
+
+          if (ws) {
+            // for sockets that've already connected (e.g. we're the server)
+            // we can inspect the _socket property for the address
+            if (ws._socket) {
+              addr = ws._socket.remoteAddress;
+              port = ws._socket.remotePort;
+            }
+            // if we're just now initializing a connection to the remote,
+            // inspect the url property
+            else {
+              var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
+              if (!result) {
+                throw new Error('WebSocket URL must be in the format ws(s)://address:port');
+              }
+              addr = result[1];
+              port = parseInt(result[2], 10);
+            }
+          } else {
+            // create the actual websocket object and connect
+            try {
+              // runtimeConfig gets set to true if WebSocket runtime configuration is available.
+              var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
+
+              // The default value is 'ws://' the replace is needed because the compiler replaces "//" comments with '#'
+              // comments without checking context, so we'd end up with ws:#, the replace swaps the "#" for "//" again.
+              var url = 'ws:#'.replace('#', '//');
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['url']) {
+                  url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
+                }
+              }
+
+              if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
+                url = url + addr + ':' + port;
+              }
+
+              // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
+              var subProtocols = 'binary'; // The default value is 'binary'
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['subprotocol']) {
+                  subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
+                }
+              }
+
+              // The regex trims the string (removes spaces at the beginning and end, then splits the string by
+              // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
+              subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
+
+              // The node ws library API for specifying optional subprotocol is slightly different than the browser's.
+              var opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols;
+
+              // If node we use the ws library.
+              var WebSocket = ENVIRONMENT_IS_NODE ? require('ws') : window['WebSocket'];
+              ws = new WebSocket(url, opts);
+              ws.binaryType = 'arraybuffer';
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH);
+            }
+          }
+
+
+          var peer = {
+            addr: addr,
+            port: port,
+            socket: ws,
+            dgram_send_queue: []
+          };
+
+          SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+          SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
+
+          // if this is a bound dgram socket, send the port number first to allow
+          // us to override the ephemeral port reported to us by remotePort on the
+          // remote end.
+          if (sock.type === 2 && typeof sock.sport !== 'undefined') {
+            peer.dgram_send_queue.push(new Uint8Array([
+                255, 255, 255, 255,
+                'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
+                ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
+            ]));
+          }
+
+          return peer;
+        },getPeer:function (sock, addr, port) {
+          return sock.peers[addr + ':' + port];
+        },addPeer:function (sock, peer) {
+          sock.peers[peer.addr + ':' + peer.port] = peer;
+        },removePeer:function (sock, peer) {
+          delete sock.peers[peer.addr + ':' + peer.port];
+        },handlePeerEvents:function (sock, peer) {
+          var first = true;
+
+          var handleOpen = function () {
+            try {
+              var queued = peer.dgram_send_queue.shift();
+              while (queued) {
+                peer.socket.send(queued);
+                queued = peer.dgram_send_queue.shift();
+              }
+            } catch (e) {
+              // not much we can do here in the way of proper error handling as we've already
+              // lied and said this data was sent. shut it down.
+              peer.socket.close();
+            }
+          };
+
+          function handleMessage(data) {
+            assert(typeof data !== 'string' && data.byteLength !== undefined);  // must receive an ArrayBuffer
+            data = new Uint8Array(data);  // make a typed array view on the array buffer
+
+
+            // if this is the port message, override the peer's port with it
+            var wasfirst = first;
+            first = false;
+            if (wasfirst &&
+                data.length === 10 &&
+                data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
+                data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
+              // update the peer's port and it's key in the peer map
+              var newport = ((data[8] << 8) | data[9]);
+              SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+              peer.port = newport;
+              SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+              return;
+            }
+
+            sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
+          };
+
+          if (ENVIRONMENT_IS_NODE) {
+            peer.socket.on('open', handleOpen);
+            peer.socket.on('message', function(data, flags) {
+              if (!flags.binary) {
+                return;
+              }
+              handleMessage((new Uint8Array(data)).buffer);  // copy from node Buffer -> ArrayBuffer
+            });
+            peer.socket.on('error', function() {
+              // don't throw
+            });
+          } else {
+            peer.socket.onopen = handleOpen;
+            peer.socket.onmessage = function peer_socket_onmessage(event) {
+              handleMessage(event.data);
+            };
+          }
+        },poll:function (sock) {
+          if (sock.type === 1 && sock.server) {
+            // listen sockets should only say they're available for reading
+            // if there are pending clients.
+            return sock.pending.length ? (64 | 1) : 0;
+          }
+
+          var mask = 0;
+          var dest = sock.type === 1 ?  // we only care about the socket state for connection-based sockets
+            SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
+            null;
+
+          if (sock.recv_queue.length ||
+              !dest ||  // connection-less sockets are always ready to read
+              (dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {  // let recv return 0 once closed
+            mask |= (64 | 1);
+          }
+
+          if (!dest ||  // connection-less sockets are always ready to write
+              (dest && dest.socket.readyState === dest.socket.OPEN)) {
+            mask |= 4;
+          }
+
+          if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {
+            mask |= 16;
+          }
+
+          return mask;
+        },ioctl:function (sock, request, arg) {
+          switch (request) {
+            case 21531:
+              var bytes = 0;
+              if (sock.recv_queue.length) {
+                bytes = sock.recv_queue[0].data.length;
+              }
+              HEAP32[((arg)>>2)]=bytes;
+              return 0;
+            default:
+              return ERRNO_CODES.EINVAL;
+          }
+        },close:function (sock) {
+          // if we've spawned a listen server, close it
+          if (sock.server) {
+            try {
+              sock.server.close();
+            } catch (e) {
+            }
+            sock.server = null;
+          }
+          // close any peer connections
+          var peers = Object.keys(sock.peers);
+          for (var i = 0; i < peers.length; i++) {
+            var peer = sock.peers[peers[i]];
+            try {
+              peer.socket.close();
+            } catch (e) {
+            }
+            SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+          }
+          return 0;
+        },bind:function (sock, addr, port) {
+          if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already bound
+          }
+          sock.saddr = addr;
+          sock.sport = port || _mkport();
+          // in order to emulate dgram sockets, we need to launch a listen server when
+          // binding on a connection-less socket
+          // note: this is only required on the server side
+          if (sock.type === 2) {
+            // close the existing server if it exists
+            if (sock.server) {
+              sock.server.close();
+              sock.server = null;
+            }
+            // swallow error operation not supported error that occurs when binding in the
+            // browser where this isn't supported
+            try {
+              sock.sock_ops.listen(sock, 0);
+            } catch (e) {
+              if (!(e instanceof FS.ErrnoError)) throw e;
+              if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e;
+            }
+          }
+        },connect:function (sock, addr, port) {
+          if (sock.server) {
+            throw new FS.ErrnoError(ERRNO_CODS.EOPNOTSUPP);
+          }
+
+          // TODO autobind
+          // if (!sock.addr && sock.type == 2) {
+          // }
+
+          // early out if we're already connected / in the middle of connecting
+          if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') {
+            var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+            if (dest) {
+              if (dest.socket.readyState === dest.socket.CONNECTING) {
+                throw new FS.ErrnoError(ERRNO_CODES.EALREADY);
+              } else {
+                throw new FS.ErrnoError(ERRNO_CODES.EISCONN);
+              }
+            }
+          }
+
+          // add the socket to our peer list and set our
+          // destination address / port to match
+          var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+          sock.daddr = peer.addr;
+          sock.dport = peer.port;
+
+          // always "fail" in non-blocking mode
+          throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS);
+        },listen:function (sock, backlog) {
+          if (!ENVIRONMENT_IS_NODE) {
+            throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+          }
+          if (sock.server) {
+             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already listening
+          }
+          var WebSocketServer = require('ws').Server;
+          var host = sock.saddr;
+          sock.server = new WebSocketServer({
+            host: host,
+            port: sock.sport
+            // TODO support backlog
+          });
+
+          sock.server.on('connection', function(ws) {
+            if (sock.type === 1) {
+              var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
+
+              // create a peer on the new socket
+              var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
+              newsock.daddr = peer.addr;
+              newsock.dport = peer.port;
+
+              // push to queue for accept to pick up
+              sock.pending.push(newsock);
+            } else {
+              // create a peer on the listen socket so calling sendto
+              // with the listen socket and an address will resolve
+              // to the correct client
+              SOCKFS.websocket_sock_ops.createPeer(sock, ws);
+            }
+          });
+          sock.server.on('closed', function() {
+            sock.server = null;
+          });
+          sock.server.on('error', function() {
+            // don't throw
+          });
+        },accept:function (listensock) {
+          if (!listensock.server) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          var newsock = listensock.pending.shift();
+          newsock.stream.flags = listensock.stream.flags;
+          return newsock;
+        },getname:function (sock, peer) {
+          var addr, port;
+          if (peer) {
+            if (sock.daddr === undefined || sock.dport === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            }
+            addr = sock.daddr;
+            port = sock.dport;
+          } else {
+            // TODO saddr and sport will be set for bind()'d UDP sockets, but what
+            // should we be returning for TCP sockets that've been connect()'d?
+            addr = sock.saddr || 0;
+            port = sock.sport || 0;
+          }
+          return { addr: addr, port: port };
+        },sendmsg:function (sock, buffer, offset, length, addr, port) {
+          if (sock.type === 2) {
+            // connection-less sockets will honor the message address,
+            // and otherwise fall back to the bound destination address
+            if (addr === undefined || port === undefined) {
+              addr = sock.daddr;
+              port = sock.dport;
+            }
+            // if there was no address to fall back to, error out
+            if (addr === undefined || port === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ);
+            }
+          } else {
+            // connection-based sockets will only use the bound
+            addr = sock.daddr;
+            port = sock.dport;
+          }
+
+          // find the peer for the destination address
+          var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
+
+          // early out if not connected with a connection-based socket
+          if (sock.type === 1) {
+            if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            } else if (dest.socket.readyState === dest.socket.CONNECTING) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // create a copy of the incoming data to send, as the WebSocket API
+          // doesn't work entirely with an ArrayBufferView, it'll just send
+          // the entire underlying buffer
+          var data;
+          if (buffer instanceof Array || buffer instanceof ArrayBuffer) {
+            data = buffer.slice(offset, offset + length);
+          } else {  // ArrayBufferView
+            data = buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + length);
+          }
+
+          // if we're emulating a connection-less dgram socket and don't have
+          // a cached connection, queue the buffer to send upon connect and
+          // lie, saying the data was sent now.
+          if (sock.type === 2) {
+            if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
+              // if we're not connected, open a new connection
+              if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+              }
+              dest.dgram_send_queue.push(data);
+              return length;
+            }
+          }
+
+          try {
+            // send the actual data
+            dest.socket.send(data);
+            return length;
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+        },recvmsg:function (sock, length) {
+          // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
+          if (sock.type === 1 && sock.server) {
+            // tcp servers should not be recv()'ing on the listen socket
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+          }
+
+          var queued = sock.recv_queue.shift();
+          if (!queued) {
+            if (sock.type === 1) {
+              var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+
+              if (!dest) {
+                // if we have a destination address but are not connected, error out
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+              }
+              else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                // return null if the socket has closed
+                return null;
+              }
+              else {
+                // else, our socket is in a valid state but truly has nothing available
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+            } else {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
+          // requeued TCP data it'll be an ArrayBufferView
+          var queuedLength = queued.data.byteLength || queued.data.length;
+          var queuedOffset = queued.data.byteOffset || 0;
+          var queuedBuffer = queued.data.buffer || queued.data;
+          var bytesRead = Math.min(length, queuedLength);
+          var res = {
+            buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
+            addr: queued.addr,
+            port: queued.port
+          };
+
+
+          // push back any unread data for TCP connections
+          if (sock.type === 1 && bytesRead < queuedLength) {
+            var bytesRemaining = queuedLength - bytesRead;
+            queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
+            sock.recv_queue.unshift(queued);
+          }
+
+          return res;
+        }}};function _send(fd, buf, len, flags) {
+      var sock = SOCKFS.getSocket(fd);
+      if (!sock) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      // TODO honor flags
+      return _write(fd, buf, len);
+    }
+
+  function _pwrite(fildes, buf, nbyte, offset) {
+      // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte, offset);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _write(fildes, buf, nbyte) {
+      // ssize_t write(int fildes, const void *buf, size_t nbyte);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+
+
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }
+
+  function _fileno(stream) {
+      // int fileno(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
+      stream = FS.getStreamFromPtr(stream);
+      if (!stream) return -1;
+      return stream.fd;
+    }function _fwrite(ptr, size, nitems, stream) {
+      // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
+      var bytesToWrite = nitems * size;
+      if (bytesToWrite == 0) return 0;
+      var fd = _fileno(stream);
+      var bytesWritten = _write(fd, ptr, bytesToWrite);
+      if (bytesWritten == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return 0;
+      } else {
+        return Math.floor(bytesWritten / size);
+      }
+    }
+
+
+
+  Module["_strlen"] = _strlen;
+
+  function __reallyNegative(x) {
+      return x < 0 || (x === 0 && (1/x) === -Infinity);
+    }function __formatString(format, varargs) {
+      var textIndex = format;
+      var argIndex = 0;
+      function getNextArg(type) {
+        // NOTE: Explicitly ignoring type safety. Otherwise this fails:
+        //       int x = 4; printf("%c\n", (char)x);
+        var ret;
+        if (type === 'double') {
+          ret = HEAPF64[(((varargs)+(argIndex))>>3)];
+        } else if (type == 'i64') {
+          ret = [HEAP32[(((varargs)+(argIndex))>>2)],
+                 HEAP32[(((varargs)+(argIndex+4))>>2)]];
+
+        } else {
+          type = 'i32'; // varargs are always i32, i64, or double
+          ret = HEAP32[(((varargs)+(argIndex))>>2)];
+        }
+        argIndex += Runtime.getNativeFieldSize(type);
+        return ret;
+      }
+
+      var ret = [];
+      var curr, next, currArg;
+      while(1) {
+        var startTextIndex = textIndex;
+        curr = HEAP8[(textIndex)];
+        if (curr === 0) break;
+        next = HEAP8[((textIndex+1)|0)];
+        if (curr == 37) {
+          // Handle flags.
+          var flagAlwaysSigned = false;
+          var flagLeftAlign = false;
+          var flagAlternative = false;
+          var flagZeroPad = false;
+          var flagPadSign = false;
+          flagsLoop: while (1) {
+            switch (next) {
+              case 43:
+                flagAlwaysSigned = true;
+                break;
+              case 45:
+                flagLeftAlign = true;
+                break;
+              case 35:
+                flagAlternative = true;
+                break;
+              case 48:
+                if (flagZeroPad) {
+                  break flagsLoop;
+                } else {
+                  flagZeroPad = true;
+                  break;
+                }
+              case 32:
+                flagPadSign = true;
+                break;
+              default:
+                break flagsLoop;
+            }
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          }
+
+          // Handle width.
+          var width = 0;
+          if (next == 42) {
+            width = getNextArg('i32');
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          } else {
+            while (next >= 48 && next <= 57) {
+              width = width * 10 + (next - 48);
+              textIndex++;
+              next = HEAP8[((textIndex+1)|0)];
+            }
+          }
+
+          // Handle precision.
+          var precisionSet = false, precision = -1;
+          if (next == 46) {
+            precision = 0;
+            precisionSet = true;
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+            if (next == 42) {
+              precision = getNextArg('i32');
+              textIndex++;
+            } else {
+              while(1) {
+                var precisionChr = HEAP8[((textIndex+1)|0)];
+                if (precisionChr < 48 ||
+                    precisionChr > 57) break;
+                precision = precision * 10 + (precisionChr - 48);
+                textIndex++;
+              }
+            }
+            next = HEAP8[((textIndex+1)|0)];
+          }
+          if (precision < 0) {
+            precision = 6; // Standard default.
+            precisionSet = false;
+          }
+
+          // Handle integer sizes. WARNING: These assume a 32-bit architecture!
+          var argSize;
+          switch (String.fromCharCode(next)) {
+            case 'h':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 104) {
+                textIndex++;
+                argSize = 1; // char (actually i32 in varargs)
+              } else {
+                argSize = 2; // short (actually i32 in varargs)
+              }
+              break;
+            case 'l':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 108) {
+                textIndex++;
+                argSize = 8; // long long
+              } else {
+                argSize = 4; // long
+              }
+              break;
+            case 'L': // long long
+            case 'q': // int64_t
+            case 'j': // intmax_t
+              argSize = 8;
+              break;
+            case 'z': // size_t
+            case 't': // ptrdiff_t
+            case 'I': // signed ptrdiff_t or unsigned size_t
+              argSize = 4;
+              break;
+            default:
+              argSize = null;
+          }
+          if (argSize) textIndex++;
+          next = HEAP8[((textIndex+1)|0)];
+
+          // Handle type specifier.
+          switch (String.fromCharCode(next)) {
+            case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': {
+              // Integer.
+              var signed = next == 100 || next == 105;
+              argSize = argSize || 4;
+              var currArg = getNextArg('i' + (argSize * 8));
+              var argText;
+              // Flatten i64-1 [low, high] into a (slightly rounded) double
+              if (argSize == 8) {
+                currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117);
+              }
+              // Truncate to requested size.
+              if (argSize <= 4) {
+                var limit = Math.pow(256, argSize) - 1;
+                currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
+              }
+              // Format the number.
+              var currAbsArg = Math.abs(currArg);
+              var prefix = '';
+              if (next == 100 || next == 105) {
+                argText = reSign(currArg, 8 * argSize, 1).toString(10);
+              } else if (next == 117) {
+                argText = unSign(currArg, 8 * argSize, 1).toString(10);
+                currArg = Math.abs(currArg);
+              } else if (next == 111) {
+                argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
+              } else if (next == 120 || next == 88) {
+                prefix = (flagAlternative && currArg != 0) ? '0x' : '';
+                if (currArg < 0) {
+                  // Represent negative numbers in hex as 2's complement.
+                  currArg = -currArg;
+                  argText = (currAbsArg - 1).toString(16);
+                  var buffer = [];
+                  for (var i = 0; i < argText.length; i++) {
+                    buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
+                  }
+                  argText = buffer.join('');
+                  while (argText.length < argSize * 2) argText = 'f' + argText;
+                } else {
+                  argText = currAbsArg.toString(16);
+                }
+                if (next == 88) {
+                  prefix = prefix.toUpperCase();
+                  argText = argText.toUpperCase();
+                }
+              } else if (next == 112) {
+                if (currAbsArg === 0) {
+                  argText = '(nil)';
+                } else {
+                  prefix = '0x';
+                  argText = currAbsArg.toString(16);
+                }
+              }
+              if (precisionSet) {
+                while (argText.length < precision) {
+                  argText = '0' + argText;
+                }
+              }
+
+              // Add sign if needed
+              if (currArg >= 0) {
+                if (flagAlwaysSigned) {
+                  prefix = '+' + prefix;
+                } else if (flagPadSign) {
+                  prefix = ' ' + prefix;
+                }
+              }
+
+              // Move sign to prefix so we zero-pad after the sign
+              if (argText.charAt(0) == '-') {
+                prefix = '-' + prefix;
+                argText = argText.substr(1);
+              }
+
+              // Add padding.
+              while (prefix.length + argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad) {
+                    argText = '0' + argText;
+                  } else {
+                    prefix = ' ' + prefix;
+                  }
+                }
+              }
+
+              // Insert the result into the buffer.
+              argText = prefix + argText;
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': {
+              // Float.
+              var currArg = getNextArg('double');
+              var argText;
+              if (isNaN(currArg)) {
+                argText = 'nan';
+                flagZeroPad = false;
+              } else if (!isFinite(currArg)) {
+                argText = (currArg < 0 ? '-' : '') + 'inf';
+                flagZeroPad = false;
+              } else {
+                var isGeneral = false;
+                var effectivePrecision = Math.min(precision, 20);
+
+                // Convert g/G to f/F or e/E, as per:
+                // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
+                if (next == 103 || next == 71) {
+                  isGeneral = true;
+                  precision = precision || 1;
+                  var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
+                  if (precision > exponent && exponent >= -4) {
+                    next = ((next == 103) ? 'f' : 'F').charCodeAt(0);
+                    precision -= exponent + 1;
+                  } else {
+                    next = ((next == 103) ? 'e' : 'E').charCodeAt(0);
+                    precision--;
+                  }
+                  effectivePrecision = Math.min(precision, 20);
+                }
+
+                if (next == 101 || next == 69) {
+                  argText = currArg.toExponential(effectivePrecision);
+                  // Make sure the exponent has at least 2 digits.
+                  if (/[eE][-+]\d$/.test(argText)) {
+                    argText = argText.slice(0, -1) + '0' + argText.slice(-1);
+                  }
+                } else if (next == 102 || next == 70) {
+                  argText = currArg.toFixed(effectivePrecision);
+                  if (currArg === 0 && __reallyNegative(currArg)) {
+                    argText = '-' + argText;
+                  }
+                }
+
+                var parts = argText.split('e');
+                if (isGeneral && !flagAlternative) {
+                  // Discard trailing zeros and periods.
+                  while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
+                         (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
+                    parts[0] = parts[0].slice(0, -1);
+                  }
+                } else {
+                  // Make sure we have a period in alternative mode.
+                  if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
+                  // Zero pad until required precision.
+                  while (precision > effectivePrecision++) parts[0] += '0';
+                }
+                argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
+
+                // Capitalize 'E' if needed.
+                if (next == 69) argText = argText.toUpperCase();
+
+                // Add sign.
+                if (currArg >= 0) {
+                  if (flagAlwaysSigned) {
+                    argText = '+' + argText;
+                  } else if (flagPadSign) {
+                    argText = ' ' + argText;
+                  }
+                }
+              }
+
+              // Add padding.
+              while (argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
+                    argText = argText[0] + '0' + argText.slice(1);
+                  } else {
+                    argText = (flagZeroPad ? '0' : ' ') + argText;
+                  }
+                }
+              }
+
+              // Adjust case.
+              if (next < 97) argText = argText.toUpperCase();
+
+              // Insert the result into the buffer.
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 's': {
+              // String.
+              var arg = getNextArg('i8*');
+              var argLength = arg ? _strlen(arg) : '(null)'.length;
+              if (precisionSet) argLength = Math.min(argLength, precision);
+              if (!flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              if (arg) {
+                for (var i = 0; i < argLength; i++) {
+                  ret.push(HEAPU8[((arg++)|0)]);
+                }
+              } else {
+                ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true));
+              }
+              if (flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              break;
+            }
+            case 'c': {
+              // Character.
+              if (flagLeftAlign) ret.push(getNextArg('i8'));
+              while (--width > 0) {
+                ret.push(32);
+              }
+              if (!flagLeftAlign) ret.push(getNextArg('i8'));
+              break;
+            }
+            case 'n': {
+              // Write the length written so far to the next parameter.
+              var ptr = getNextArg('i32*');
+              HEAP32[((ptr)>>2)]=ret.length;
+              break;
+            }
+            case '%': {
+              // Literal percent sign.
+              ret.push(curr);
+              break;
+            }
+            default: {
+              // Unknown specifiers remain untouched.
+              for (var i = startTextIndex; i < textIndex + 2; i++) {
+                ret.push(HEAP8[(i)]);
+              }
+            }
+          }
+          textIndex += 2;
+          // TODO: Support a/A (hex float) and m (last error) specifiers.
+          // TODO: Support %1${specifier} for arg selection.
+        } else {
+          ret.push(curr);
+          textIndex += 1;
+        }
+      }
+      return ret;
+    }function _fprintf(stream, format, varargs) {
+      // int fprintf(FILE *restrict stream, const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var result = __formatString(format, varargs);
+      var stack = Runtime.stackSave();
+      var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream);
+      Runtime.stackRestore(stack);
+      return ret;
+    }function _printf(format, varargs) {
+      // int printf(const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var stdout = HEAP32[((_stdout)>>2)];
+      return _fprintf(stdout, format, varargs);
+    }
+
+  function _sbrk(bytes) {
+      // Implement a Linux-like 'memory area' for our 'process'.
+      // Changes the size of the memory area by |bytes|; returns the
+      // address of the previous top ('break') of the memory area
+      // We control the "dynamic" memory - DYNAMIC_BASE to DYNAMICTOP
+      var self = _sbrk;
+      if (!self.called) {
+        DYNAMICTOP = alignMemoryPage(DYNAMICTOP); // make sure we start out aligned
+        self.called = true;
+        assert(Runtime.dynamicAlloc);
+        self.alloc = Runtime.dynamicAlloc;
+        Runtime.dynamicAlloc = function() { abort('cannot dynamically allocate, sbrk now has control') };
+      }
+      var ret = DYNAMICTOP;
+      if (bytes != 0) self.alloc(bytes);
+      return ret;  // Previous break location.
+    }
+
+  function _sysconf(name) {
+      // long sysconf(int name);
+      // http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html
+      switch(name) {
+        case 30: return PAGE_SIZE;
+        case 132:
+        case 133:
+        case 12:
+        case 137:
+        case 138:
+        case 15:
+        case 235:
+        case 16:
+        case 17:
+        case 18:
+        case 19:
+        case 20:
+        case 149:
+        case 13:
+        case 10:
+        case 236:
+        case 153:
+        case 9:
+        case 21:
+        case 22:
+        case 159:
+        case 154:
+        case 14:
+        case 77:
+        case 78:
+        case 139:
+        case 80:
+        case 81:
+        case 79:
+        case 82:
+        case 68:
+        case 67:
+        case 164:
+        case 11:
+        case 29:
+        case 47:
+        case 48:
+        case 95:
+        case 52:
+        case 51:
+        case 46:
+          return 200809;
+        case 27:
+        case 246:
+        case 127:
+        case 128:
+        case 23:
+        case 24:
+        case 160:
+        case 161:
+        case 181:
+        case 182:
+        case 242:
+        case 183:
+        case 184:
+        case 243:
+        case 244:
+        case 245:
+        case 165:
+        case 178:
+        case 179:
+        case 49:
+        case 50:
+        case 168:
+        case 169:
+        case 175:
+        case 170:
+        case 171:
+        case 172:
+        case 97:
+        case 76:
+        case 32:
+        case 173:
+        case 35:
+          return -1;
+        case 176:
+        case 177:
+        case 7:
+        case 155:
+        case 8:
+        case 157:
+        case 125:
+        case 126:
+        case 92:
+        case 93:
+        case 129:
+        case 130:
+        case 131:
+        case 94:
+        case 91:
+          return 1;
+        case 74:
+        case 60:
+        case 69:
+        case 70:
+        case 4:
+          return 1024;
+        case 31:
+        case 42:
+        case 72:
+          return 32;
+        case 87:
+        case 26:
+        case 33:
+          return 2147483647;
+        case 34:
+        case 1:
+          return 47839;
+        case 38:
+        case 36:
+          return 99;
+        case 43:
+        case 37:
+          return 2048;
+        case 0: return 2097152;
+        case 3: return 65536;
+        case 28: return 32768;
+        case 44: return 32767;
+        case 75: return 16384;
+        case 39: return 1000;
+        case 89: return 700;
+        case 71: return 256;
+        case 40: return 255;
+        case 2: return 100;
+        case 180: return 64;
+        case 25: return 20;
+        case 5: return 16;
+        case 6: return 6;
+        case 73: return 4;
+        case 84: return 1;
+      }
+      ___setErrNo(ERRNO_CODES.EINVAL);
+      return -1;
+    }
+
+
+  Module["_memset"] = _memset;
+
+  function ___errno_location() {
+      return ___errno_state;
+    }
+
+  function _abort() {
+      Module['abort']();
+    }
+
+  var Browser={mainLoop:{scheduler:null,method:"",shouldPause:false,paused:false,queue:[],pause:function () {
+          Browser.mainLoop.shouldPause = true;
+        },resume:function () {
+          if (Browser.mainLoop.paused) {
+            Browser.mainLoop.paused = false;
+            Browser.mainLoop.scheduler();
+          }
+          Browser.mainLoop.shouldPause = false;
+        },updateStatus:function () {
+          if (Module['setStatus']) {
+            var message = Module['statusMessage'] || 'Please wait...';
+            var remaining = Browser.mainLoop.remainingBlockers;
+            var expected = Browser.mainLoop.expectedBlockers;
+            if (remaining) {
+              if (remaining < expected) {
+                Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
+              } else {
+                Module['setStatus'](message);
+              }
+            } else {
+              Module['setStatus']('');
+            }
+          }
+        }},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () {
+        if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
+
+        if (Browser.initted || ENVIRONMENT_IS_WORKER) return;
+        Browser.initted = true;
+
+        try {
+          new Blob();
+          Browser.hasBlobConstructor = true;
+        } catch(e) {
+          Browser.hasBlobConstructor = false;
+          console.log("warning: no blob constructor, cannot create blobs with mimetypes");
+        }
+        Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
+        Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
+        if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
+          console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
+          Module.noImageDecoding = true;
+        }
+
+        // Support for plugins that can process preloaded files. You can add more of these to
+        // your app by creating and appending to Module.preloadPlugins.
+        //
+        // Each plugin is asked if it can handle a file based on the file's name. If it can,
+        // it is given the file's raw data. When it is done, it calls a callback with the file's
+        // (possibly modified) data. For example, a plugin might decompress a file, or it
+        // might create some side data structure for use later (like an Image element, etc.).
+
+        var imagePlugin = {};
+        imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
+          return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
+        };
+        imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
+          var b = null;
+          if (Browser.hasBlobConstructor) {
+            try {
+              b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+              if (b.size !== byteArray.length) { // Safari bug #118630
+                // Safari's Blob can only take an ArrayBuffer
+                b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
+              }
+            } catch(e) {
+              Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
+            }
+          }
+          if (!b) {
+            var bb = new Browser.BlobBuilder();
+            bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
+            b = bb.getBlob();
+          }
+          var url = Browser.URLObject.createObjectURL(b);
+          var img = new Image();
+          img.onload = function img_onload() {
+            assert(img.complete, 'Image ' + name + ' could not be decoded');
+            var canvas = document.createElement('canvas');
+            canvas.width = img.width;
+            canvas.height = img.height;
+            var ctx = canvas.getContext('2d');
+            ctx.drawImage(img, 0, 0);
+            Module["preloadedImages"][name] = canvas;
+            Browser.URLObject.revokeObjectURL(url);
+            if (onload) onload(byteArray);
+          };
+          img.onerror = function img_onerror(event) {
+            console.log('Image ' + url + ' could not be decoded');
+            if (onerror) onerror();
+          };
+          img.src = url;
+        };
+        Module['preloadPlugins'].push(imagePlugin);
+
+        var audioPlugin = {};
+        audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
+          return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
+        };
+        audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
+          var done = false;
+          function finish(audio) {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = audio;
+            if (onload) onload(byteArray);
+          }
+          function fail() {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = new Audio(); // empty shim
+            if (onerror) onerror();
+          }
+          if (Browser.hasBlobConstructor) {
+            try {
+              var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+            } catch(e) {
+              return fail();
+            }
+            var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
+            var audio = new Audio();
+            audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926
+            audio.onerror = function audio_onerror(event) {
+              if (done) return;
+              console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
+              function encode64(data) {
+                var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+                var PAD = '=';
+                var ret = '';
+                var leftchar = 0;
+                var leftbits = 0;
+                for (var i = 0; i < data.length; i++) {
+                  leftchar = (leftchar << 8) | data[i];
+                  leftbits += 8;
+                  while (leftbits >= 6) {
+                    var curr = (leftchar >> (leftbits-6)) & 0x3f;
+                    leftbits -= 6;
+                    ret += BASE[curr];
+                  }
+                }
+                if (leftbits == 2) {
+                  ret += BASE[(leftchar&3) << 4];
+                  ret += PAD + PAD;
+                } else if (leftbits == 4) {
+                  ret += BASE[(leftchar&0xf) << 2];
+                  ret += PAD;
+                }
+                return ret;
+              }
+              audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
+              finish(audio); // we don't wait for confirmation this worked - but it's worth trying
+            };
+            audio.src = url;
+            // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
+            Browser.safeSetTimeout(function() {
+              finish(audio); // try to use it even though it is not necessarily ready to play
+            }, 10000);
+          } else {
+            return fail();
+          }
+        };
+        Module['preloadPlugins'].push(audioPlugin);
+
+        // Canvas event setup
+
+        var canvas = Module['canvas'];
+
+        // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
+        // Module['forcedAspectRatio'] = 4 / 3;
+
+        canvas.requestPointerLock = canvas['requestPointerLock'] ||
+                                    canvas['mozRequestPointerLock'] ||
+                                    canvas['webkitRequestPointerLock'] ||
+                                    canvas['msRequestPointerLock'] ||
+                                    function(){};
+        canvas.exitPointerLock = document['exitPointerLock'] ||
+                                 document['mozExitPointerLock'] ||
+                                 document['webkitExitPointerLock'] ||
+                                 document['msExitPointerLock'] ||
+                                 function(){}; // no-op if function does not exist
+        canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
+
+        function pointerLockChange() {
+          Browser.pointerLock = document['pointerLockElement'] === canvas ||
+                                document['mozPointerLockElement'] === canvas ||
+                                document['webkitPointerLockElement'] === canvas ||
+                                document['msPointerLockElement'] === canvas;
+        }
+
+        document.addEventListener('pointerlockchange', pointerLockChange, false);
+        document.addEventListener('mozpointerlockchange', pointerLockChange, false);
+        document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
+        document.addEventListener('mspointerlockchange', pointerLockChange, false);
+
+        if (Module['elementPointerLock']) {
+          canvas.addEventListener("click", function(ev) {
+            if (!Browser.pointerLock && canvas.requestPointerLock) {
+              canvas.requestPointerLock();
+              ev.preventDefault();
+            }
+          }, false);
+        }
+      },createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) {
+        var ctx;
+        var errorInfo = '?';
+        function onContextCreationError(event) {
+          errorInfo = event.statusMessage || errorInfo;
+        }
+        try {
+          if (useWebGL) {
+            var contextAttributes = {
+              antialias: false,
+              alpha: false
+            };
+
+            if (webGLContextAttributes) {
+              for (var attribute in webGLContextAttributes) {
+                contextAttributes[attribute] = webGLContextAttributes[attribute];
+              }
+            }
+
+
+            canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
+            try {
+              ['experimental-webgl', 'webgl'].some(function(webglId) {
+                return ctx = canvas.getContext(webglId, contextAttributes);
+              });
+            } finally {
+              canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
+            }
+          } else {
+            ctx = canvas.getContext('2d');
+          }
+          if (!ctx) throw ':(';
+        } catch (e) {
+          Module.print('Could not create canvas: ' + [errorInfo, e]);
+          return null;
+        }
+        if (useWebGL) {
+          // Set the background of the WebGL canvas to black
+          canvas.style.backgroundColor = "black";
+
+          // Warn on context loss
+          canvas.addEventListener('webglcontextlost', function(event) {
+            alert('WebGL context lost. You will need to reload the page.');
+          }, false);
+        }
+        if (setInModule) {
+          GLctx = Module.ctx = ctx;
+          Module.useWebGL = useWebGL;
+          Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
+          Browser.init();
+        }
+        return ctx;
+      },destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) {
+        Browser.lockPointer = lockPointer;
+        Browser.resizeCanvas = resizeCanvas;
+        if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;
+        if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;
+
+        var canvas = Module['canvas'];
+        function fullScreenChange() {
+          Browser.isFullScreen = false;
+          var canvasContainer = canvas.parentNode;
+          if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+               document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+               document['fullScreenElement'] || document['fullscreenElement'] ||
+               document['msFullScreenElement'] || document['msFullscreenElement'] ||
+               document['webkitCurrentFullScreenElement']) === canvasContainer) {
+            canvas.cancelFullScreen = document['cancelFullScreen'] ||
+                                      document['mozCancelFullScreen'] ||
+                                      document['webkitCancelFullScreen'] ||
+                                      document['msExitFullscreen'] ||
+                                      document['exitFullscreen'] ||
+                                      function() {};
+            canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document);
+            if (Browser.lockPointer) canvas.requestPointerLock();
+            Browser.isFullScreen = true;
+            if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize();
+          } else {
+
+            // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
+            canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
+            canvasContainer.parentNode.removeChild(canvasContainer);
+
+            if (Browser.resizeCanvas) Browser.setWindowedCanvasSize();
+          }
+          if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen);
+          Browser.updateCanvasDimensions(canvas);
+        }
+
+        if (!Browser.fullScreenHandlersInstalled) {
+          Browser.fullScreenHandlersInstalled = true;
+          document.addEventListener('fullscreenchange', fullScreenChange, false);
+          document.addEventListener('mozfullscreenchange', fullScreenChange, false);
+          document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
+          document.addEventListener('MSFullscreenChange', fullScreenChange, false);
+        }
+
+        // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
+        var canvasContainer = document.createElement("div");
+        canvas.parentNode.insertBefore(canvasContainer, canvas);
+        canvasContainer.appendChild(canvas);
+
+        // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
+        canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] ||
+                                            canvasContainer['mozRequestFullScreen'] ||
+                                            canvasContainer['msRequestFullscreen'] ||
+                                           (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
+        canvasContainer.requestFullScreen();
+      },requestAnimationFrame:function requestAnimationFrame(func) {
+        if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js)
+          setTimeout(func, 1000/60);
+        } else {
+          if (!window.requestAnimationFrame) {
+            window.requestAnimationFrame = window['requestAnimationFrame'] ||
+                                           window['mozRequestAnimationFrame'] ||
+                                           window['webkitRequestAnimationFrame'] ||
+                                           window['msRequestAnimationFrame'] ||
+                                           window['oRequestAnimationFrame'] ||
+                                           window['setTimeout'];
+          }
+          window.requestAnimationFrame(func);
+        }
+      },safeCallback:function (func) {
+        return function() {
+          if (!ABORT) return func.apply(null, arguments);
+        };
+      },safeRequestAnimationFrame:function (func) {
+        return Browser.requestAnimationFrame(function() {
+          if (!ABORT) func();
+        });
+      },safeSetTimeout:function (func, timeout) {
+        return setTimeout(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },safeSetInterval:function (func, timeout) {
+        return setInterval(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },getMimetype:function (name) {
+        return {
+          'jpg': 'image/jpeg',
+          'jpeg': 'image/jpeg',
+          'png': 'image/png',
+          'bmp': 'image/bmp',
+          'ogg': 'audio/ogg',
+          'wav': 'audio/wav',
+          'mp3': 'audio/mpeg'
+        }[name.substr(name.lastIndexOf('.')+1)];
+      },getUserMedia:function (func) {
+        if(!window.getUserMedia) {
+          window.getUserMedia = navigator['getUserMedia'] ||
+                                navigator['mozGetUserMedia'];
+        }
+        window.getUserMedia(func);
+      },getMovementX:function (event) {
+        return event['movementX'] ||
+               event['mozMovementX'] ||
+               event['webkitMovementX'] ||
+               0;
+      },getMovementY:function (event) {
+        return event['movementY'] ||
+               event['mozMovementY'] ||
+               event['webkitMovementY'] ||
+               0;
+      },getMouseWheelDelta:function (event) {
+        return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta));
+      },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup
+        if (Browser.pointerLock) {
+          // When the pointer is locked, calculate the coordinates
+          // based on the movement of the mouse.
+          // Workaround for Firefox bug 764498
+          if (event.type != 'mousemove' &&
+              ('mozMovementX' in event)) {
+            Browser.mouseMovementX = Browser.mouseMovementY = 0;
+          } else {
+            Browser.mouseMovementX = Browser.getMovementX(event);
+            Browser.mouseMovementY = Browser.getMovementY(event);
+          }
+
+          // check if SDL is available
+          if (typeof SDL != "undefined") {
+    Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
+    Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
+          } else {
+    // just add the mouse delta to the current absolut mouse position
+    // FIXME: ideally this should be clamped against the canvas size and zero
+    Browser.mouseX += Browser.mouseMovementX;
+    Browser.mouseY += Browser.mouseMovementY;
+          }
+        } else {
+          // Otherwise, calculate the movement based on the changes
+          // in the coordinates.
+          var rect = Module["canvas"].getBoundingClientRect();
+          var x, y;
+
+          // Neither .scrollX or .pageXOffset are defined in a spec, but
+          // we prefer .scrollX because it is currently in a spec draft.
+          // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
+          var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);
+          var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);
+          if (event.type == 'touchstart' ||
+              event.type == 'touchend' ||
+              event.type == 'touchmove') {
+            var t = event.touches.item(0);
+            if (t) {
+              x = t.pageX - (scrollX + rect.left);
+              y = t.pageY - (scrollY + rect.top);
+            } else {
+              return;
+            }
+          } else {
+            x = event.pageX - (scrollX + rect.left);
+            y = event.pageY - (scrollY + rect.top);
+          }
+
+          // the canvas might be CSS-scaled compared to its backbuffer;
+          // SDL-using content will want mouse coordinates in terms
+          // of backbuffer units.
+          var cw = Module["canvas"].width;
+          var ch = Module["canvas"].height;
+          x = x * (cw / rect.width);
+          y = y * (ch / rect.height);
+
+          Browser.mouseMovementX = x - Browser.mouseX;
+          Browser.mouseMovementY = y - Browser.mouseY;
+          Browser.mouseX = x;
+          Browser.mouseY = y;
+        }
+      },xhrLoad:function (url, onload, onerror) {
+        var xhr = new XMLHttpRequest();
+        xhr.open('GET', url, true);
+        xhr.responseType = 'arraybuffer';
+        xhr.onload = function xhr_onload() {
+          if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
+            onload(xhr.response);
+          } else {
+            onerror();
+          }
+        };
+        xhr.onerror = onerror;
+        xhr.send(null);
+      },asyncLoad:function (url, onload, onerror, noRunDep) {
+        Browser.xhrLoad(url, function(arrayBuffer) {
+          assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
+          onload(new Uint8Array(arrayBuffer));
+          if (!noRunDep) removeRunDependency('al ' + url);
+        }, function(event) {
+          if (onerror) {
+            onerror();
+          } else {
+            throw 'Loading data file "' + url + '" failed.';
+          }
+        });
+        if (!noRunDep) addRunDependency('al ' + url);
+      },resizeListeners:[],updateResizeListeners:function () {
+        var canvas = Module['canvas'];
+        Browser.resizeListeners.forEach(function(listener) {
+          listener(canvas.width, canvas.height);
+        });
+      },setCanvasSize:function (width, height, noUpdates) {
+        var canvas = Module['canvas'];
+        Browser.updateCanvasDimensions(canvas, width, height);
+        if (!noUpdates) Browser.updateResizeListeners();
+      },windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+    var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+    flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
+    HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },setWindowedCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+    var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+    flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
+    HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },updateCanvasDimensions:function (canvas, wNative, hNative) {
+        if (wNative && hNative) {
+          canvas.widthNative = wNative;
+          canvas.heightNative = hNative;
+        } else {
+          wNative = canvas.widthNative;
+          hNative = canvas.heightNative;
+        }
+        var w = wNative;
+        var h = hNative;
+        if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
+          if (w/h < Module['forcedAspectRatio']) {
+            w = Math.round(h * Module['forcedAspectRatio']);
+          } else {
+            h = Math.round(w / Module['forcedAspectRatio']);
+          }
+        }
+        if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+             document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+             document['fullScreenElement'] || document['fullscreenElement'] ||
+             document['msFullScreenElement'] || document['msFullscreenElement'] ||
+             document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
+           var factor = Math.min(screen.width / w, screen.height / h);
+           w = Math.round(w * factor);
+           h = Math.round(h * factor);
+        }
+        if (Browser.resizeCanvas) {
+          if (canvas.width  != w) canvas.width  = w;
+          if (canvas.height != h) canvas.height = h;
+          if (typeof canvas.style != 'undefined') {
+            canvas.style.removeProperty( "width");
+            canvas.style.removeProperty("height");
+          }
+        } else {
+          if (canvas.width  != wNative) canvas.width  = wNative;
+          if (canvas.height != hNative) canvas.height = hNative;
+          if (typeof canvas.style != 'undefined') {
+            if (w != wNative || h != hNative) {
+              canvas.style.setProperty( "width", w + "px", "important");
+              canvas.style.setProperty("height", h + "px", "important");
+            } else {
+              canvas.style.removeProperty( "width");
+              canvas.style.removeProperty("height");
+            }
+          }
+        }
+      }};
+
+  function _time(ptr) {
+      var ret = Math.floor(Date.now()/1000);
+      if (ptr) {
+        HEAP32[((ptr)>>2)]=ret;
+      }
+      return ret;
+    }
+
+
+
+  function _emscripten_memcpy_big(dest, src, num) {
+      HEAPU8.set(HEAPU8.subarray(src, src+num), dest);
+      return dest;
+    }
+  Module["_memcpy"] = _memcpy;
+FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice;
+___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0;
+__ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor();
+if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); }
+__ATINIT__.push({ func: function() { SOCKFS.root = FS.mount(SOCKFS, {}, null); } });
+Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };
+  Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
+  Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
+  Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
+  Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
+  Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }
+STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);
+
+staticSealed = true; // seal the static portion of memory
+
+STACK_MAX = STACK_BASE + 5242880;
+
+DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);
+
+assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");
+
+
+var Math_min = Math.min;
+function asmPrintInt(x, y) {
+  Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+function asmPrintFloat(x, y) {
+  Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+// EMSCRIPTEN_START_ASM
+var asm = (function(global, env, buffer) {
+  'use asm';
+  var HEAP8 = new global.Int8Array(buffer);
+  var HEAP16 = new global.Int16Array(buffer);
+  var HEAP32 = new global.Int32Array(buffer);
+  var HEAPU8 = new global.Uint8Array(buffer);
+  var HEAPU16 = new global.Uint16Array(buffer);
+  var HEAPU32 = new global.Uint32Array(buffer);
+  var HEAPF32 = new global.Float32Array(buffer);
+  var HEAPF64 = new global.Float64Array(buffer);
+
+  var STACKTOP=env.STACKTOP|0;
+  var STACK_MAX=env.STACK_MAX|0;
+  var tempDoublePtr=env.tempDoublePtr|0;
+  var ABORT=env.ABORT|0;
+
+  var __THREW__ = 0;
+  var threwValue = 0;
+  var setjmpId = 0;
+  var undef = 0;
+  var nan = +env.NaN, inf = +env.Infinity;
+  var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
+
+  var tempRet0 = 0;
+  var tempRet1 = 0;
+  var tempRet2 = 0;
+  var tempRet3 = 0;
+  var tempRet4 = 0;
+  var tempRet5 = 0;
+  var tempRet6 = 0;
+  var tempRet7 = 0;
+  var tempRet8 = 0;
+  var tempRet9 = 0;
+  var Math_floor=global.Math.floor;
+  var Math_abs=global.Math.abs;
+  var Math_sqrt=global.Math.sqrt;
+  var Math_pow=global.Math.pow;
+  var Math_cos=global.Math.cos;
+  var Math_sin=global.Math.sin;
+  var Math_tan=global.Math.tan;
+  var Math_acos=global.Math.acos;
+  var Math_asin=global.Math.asin;
+  var Math_atan=global.Math.atan;
+  var Math_atan2=global.Math.atan2;
+  var Math_exp=global.Math.exp;
+  var Math_log=global.Math.log;
+  var Math_ceil=global.Math.ceil;
+  var Math_imul=global.Math.imul;
+  var abort=env.abort;
+  var assert=env.assert;
+  var asmPrintInt=env.asmPrintInt;
+  var asmPrintFloat=env.asmPrintFloat;
+  var Math_min=env.min;
+  var _fflush=env._fflush;
+  var _emscripten_memcpy_big=env._emscripten_memcpy_big;
+  var _printf=env._printf;
+  var _send=env._send;
+  var _pwrite=env._pwrite;
+  var _abort=env._abort;
+  var ___setErrNo=env.___setErrNo;
+  var _fwrite=env._fwrite;
+  var _sbrk=env._sbrk;
+  var _time=env._time;
+  var _mkport=env._mkport;
+  var __reallyNegative=env.__reallyNegative;
+  var __formatString=env.__formatString;
+  var _fileno=env._fileno;
+  var _write=env._write;
+  var _fprintf=env._fprintf;
+  var _sysconf=env._sysconf;
+  var ___errno_location=env.___errno_location;
+  var tempFloat = 0.0;
+
+// EMSCRIPTEN_START_FUNCS
+function _malloc(i12) {
+ i12 = i12 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0;
+ i1 = STACKTOP;
+ do {
+  if (i12 >>> 0 < 245) {
+   if (i12 >>> 0 < 11) {
+    i12 = 16;
+   } else {
+    i12 = i12 + 11 & -8;
+   }
+   i20 = i12 >>> 3;
+   i18 = HEAP32[10] | 0;
+   i21 = i18 >>> i20;
+   if ((i21 & 3 | 0) != 0) {
+    i6 = (i21 & 1 ^ 1) + i20 | 0;
+    i5 = i6 << 1;
+    i3 = 80 + (i5 << 2) | 0;
+    i5 = 80 + (i5 + 2 << 2) | 0;
+    i7 = HEAP32[i5 >> 2] | 0;
+    i2 = i7 + 8 | 0;
+    i4 = HEAP32[i2 >> 2] | 0;
+    do {
+     if ((i3 | 0) != (i4 | 0)) {
+      if (i4 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i8 = i4 + 12 | 0;
+      if ((HEAP32[i8 >> 2] | 0) == (i7 | 0)) {
+       HEAP32[i8 >> 2] = i3;
+       HEAP32[i5 >> 2] = i4;
+       break;
+      } else {
+       _abort();
+      }
+     } else {
+      HEAP32[10] = i18 & ~(1 << i6);
+     }
+    } while (0);
+    i32 = i6 << 3;
+    HEAP32[i7 + 4 >> 2] = i32 | 3;
+    i32 = i7 + (i32 | 4) | 0;
+    HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+    i32 = i2;
+    STACKTOP = i1;
+    return i32 | 0;
+   }
+   if (i12 >>> 0 > (HEAP32[48 >> 2] | 0) >>> 0) {
+    if ((i21 | 0) != 0) {
+     i7 = 2 << i20;
+     i7 = i21 << i20 & (i7 | 0 - i7);
+     i7 = (i7 & 0 - i7) + -1 | 0;
+     i2 = i7 >>> 12 & 16;
+     i7 = i7 >>> i2;
+     i6 = i7 >>> 5 & 8;
+     i7 = i7 >>> i6;
+     i5 = i7 >>> 2 & 4;
+     i7 = i7 >>> i5;
+     i4 = i7 >>> 1 & 2;
+     i7 = i7 >>> i4;
+     i3 = i7 >>> 1 & 1;
+     i3 = (i6 | i2 | i5 | i4 | i3) + (i7 >>> i3) | 0;
+     i7 = i3 << 1;
+     i4 = 80 + (i7 << 2) | 0;
+     i7 = 80 + (i7 + 2 << 2) | 0;
+     i5 = HEAP32[i7 >> 2] | 0;
+     i2 = i5 + 8 | 0;
+     i6 = HEAP32[i2 >> 2] | 0;
+     do {
+      if ((i4 | 0) != (i6 | 0)) {
+       if (i6 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+        _abort();
+       }
+       i8 = i6 + 12 | 0;
+       if ((HEAP32[i8 >> 2] | 0) == (i5 | 0)) {
+        HEAP32[i8 >> 2] = i4;
+        HEAP32[i7 >> 2] = i6;
+        break;
+       } else {
+        _abort();
+       }
+      } else {
+       HEAP32[10] = i18 & ~(1 << i3);
+      }
+     } while (0);
+     i6 = i3 << 3;
+     i4 = i6 - i12 | 0;
+     HEAP32[i5 + 4 >> 2] = i12 | 3;
+     i3 = i5 + i12 | 0;
+     HEAP32[i5 + (i12 | 4) >> 2] = i4 | 1;
+     HEAP32[i5 + i6 >> 2] = i4;
+     i6 = HEAP32[48 >> 2] | 0;
+     if ((i6 | 0) != 0) {
+      i5 = HEAP32[60 >> 2] | 0;
+      i8 = i6 >>> 3;
+      i9 = i8 << 1;
+      i6 = 80 + (i9 << 2) | 0;
+      i7 = HEAP32[10] | 0;
+      i8 = 1 << i8;
+      if ((i7 & i8 | 0) != 0) {
+       i7 = 80 + (i9 + 2 << 2) | 0;
+       i8 = HEAP32[i7 >> 2] | 0;
+       if (i8 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        i28 = i7;
+        i27 = i8;
+       }
+      } else {
+       HEAP32[10] = i7 | i8;
+       i28 = 80 + (i9 + 2 << 2) | 0;
+       i27 = i6;
+      }
+      HEAP32[i28 >> 2] = i5;
+      HEAP32[i27 + 12 >> 2] = i5;
+      HEAP32[i5 + 8 >> 2] = i27;
+      HEAP32[i5 + 12 >> 2] = i6;
+     }
+     HEAP32[48 >> 2] = i4;
+     HEAP32[60 >> 2] = i3;
+     i32 = i2;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+    i18 = HEAP32[44 >> 2] | 0;
+    if ((i18 | 0) != 0) {
+     i2 = (i18 & 0 - i18) + -1 | 0;
+     i31 = i2 >>> 12 & 16;
+     i2 = i2 >>> i31;
+     i30 = i2 >>> 5 & 8;
+     i2 = i2 >>> i30;
+     i32 = i2 >>> 2 & 4;
+     i2 = i2 >>> i32;
+     i6 = i2 >>> 1 & 2;
+     i2 = i2 >>> i6;
+     i3 = i2 >>> 1 & 1;
+     i3 = HEAP32[344 + ((i30 | i31 | i32 | i6 | i3) + (i2 >>> i3) << 2) >> 2] | 0;
+     i2 = (HEAP32[i3 + 4 >> 2] & -8) - i12 | 0;
+     i6 = i3;
+     while (1) {
+      i5 = HEAP32[i6 + 16 >> 2] | 0;
+      if ((i5 | 0) == 0) {
+       i5 = HEAP32[i6 + 20 >> 2] | 0;
+       if ((i5 | 0) == 0) {
+        break;
+       }
+      }
+      i6 = (HEAP32[i5 + 4 >> 2] & -8) - i12 | 0;
+      i4 = i6 >>> 0 < i2 >>> 0;
+      i2 = i4 ? i6 : i2;
+      i6 = i5;
+      i3 = i4 ? i5 : i3;
+     }
+     i6 = HEAP32[56 >> 2] | 0;
+     if (i3 >>> 0 < i6 >>> 0) {
+      _abort();
+     }
+     i4 = i3 + i12 | 0;
+     if (!(i3 >>> 0 < i4 >>> 0)) {
+      _abort();
+     }
+     i5 = HEAP32[i3 + 24 >> 2] | 0;
+     i7 = HEAP32[i3 + 12 >> 2] | 0;
+     do {
+      if ((i7 | 0) == (i3 | 0)) {
+       i8 = i3 + 20 | 0;
+       i7 = HEAP32[i8 >> 2] | 0;
+       if ((i7 | 0) == 0) {
+        i8 = i3 + 16 | 0;
+        i7 = HEAP32[i8 >> 2] | 0;
+        if ((i7 | 0) == 0) {
+         i26 = 0;
+         break;
+        }
+       }
+       while (1) {
+        i10 = i7 + 20 | 0;
+        i9 = HEAP32[i10 >> 2] | 0;
+        if ((i9 | 0) != 0) {
+         i7 = i9;
+         i8 = i10;
+         continue;
+        }
+        i10 = i7 + 16 | 0;
+        i9 = HEAP32[i10 >> 2] | 0;
+        if ((i9 | 0) == 0) {
+         break;
+        } else {
+         i7 = i9;
+         i8 = i10;
+        }
+       }
+       if (i8 >>> 0 < i6 >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i8 >> 2] = 0;
+        i26 = i7;
+        break;
+       }
+      } else {
+       i8 = HEAP32[i3 + 8 >> 2] | 0;
+       if (i8 >>> 0 < i6 >>> 0) {
+        _abort();
+       }
+       i6 = i8 + 12 | 0;
+       if ((HEAP32[i6 >> 2] | 0) != (i3 | 0)) {
+        _abort();
+       }
+       i9 = i7 + 8 | 0;
+       if ((HEAP32[i9 >> 2] | 0) == (i3 | 0)) {
+        HEAP32[i6 >> 2] = i7;
+        HEAP32[i9 >> 2] = i8;
+        i26 = i7;
+        break;
+       } else {
+        _abort();
+       }
+      }
+     } while (0);
+     do {
+      if ((i5 | 0) != 0) {
+       i7 = HEAP32[i3 + 28 >> 2] | 0;
+       i6 = 344 + (i7 << 2) | 0;
+       if ((i3 | 0) == (HEAP32[i6 >> 2] | 0)) {
+        HEAP32[i6 >> 2] = i26;
+        if ((i26 | 0) == 0) {
+         HEAP32[44 >> 2] = HEAP32[44 >> 2] & ~(1 << i7);
+         break;
+        }
+       } else {
+        if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+         _abort();
+        }
+        i6 = i5 + 16 | 0;
+        if ((HEAP32[i6 >> 2] | 0) == (i3 | 0)) {
+         HEAP32[i6 >> 2] = i26;
+        } else {
+         HEAP32[i5 + 20 >> 2] = i26;
+        }
+        if ((i26 | 0) == 0) {
+         break;
+        }
+       }
+       if (i26 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+        _abort();
+       }
+       HEAP32[i26 + 24 >> 2] = i5;
+       i5 = HEAP32[i3 + 16 >> 2] | 0;
+       do {
+        if ((i5 | 0) != 0) {
+         if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i26 + 16 >> 2] = i5;
+          HEAP32[i5 + 24 >> 2] = i26;
+          break;
+         }
+        }
+       } while (0);
+       i5 = HEAP32[i3 + 20 >> 2] | 0;
+       if ((i5 | 0) != 0) {
+        if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i26 + 20 >> 2] = i5;
+         HEAP32[i5 + 24 >> 2] = i26;
+         break;
+        }
+       }
+      }
+     } while (0);
+     if (i2 >>> 0 < 16) {
+      i32 = i2 + i12 | 0;
+      HEAP32[i3 + 4 >> 2] = i32 | 3;
+      i32 = i3 + (i32 + 4) | 0;
+      HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+     } else {
+      HEAP32[i3 + 4 >> 2] = i12 | 3;
+      HEAP32[i3 + (i12 | 4) >> 2] = i2 | 1;
+      HEAP32[i3 + (i2 + i12) >> 2] = i2;
+      i6 = HEAP32[48 >> 2] | 0;
+      if ((i6 | 0) != 0) {
+       i5 = HEAP32[60 >> 2] | 0;
+       i8 = i6 >>> 3;
+       i9 = i8 << 1;
+       i6 = 80 + (i9 << 2) | 0;
+       i7 = HEAP32[10] | 0;
+       i8 = 1 << i8;
+       if ((i7 & i8 | 0) != 0) {
+        i7 = 80 + (i9 + 2 << 2) | 0;
+        i8 = HEAP32[i7 >> 2] | 0;
+        if (i8 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+         _abort();
+        } else {
+         i25 = i7;
+         i24 = i8;
+        }
+       } else {
+        HEAP32[10] = i7 | i8;
+        i25 = 80 + (i9 + 2 << 2) | 0;
+        i24 = i6;
+       }
+       HEAP32[i25 >> 2] = i5;
+       HEAP32[i24 + 12 >> 2] = i5;
+       HEAP32[i5 + 8 >> 2] = i24;
+       HEAP32[i5 + 12 >> 2] = i6;
+      }
+      HEAP32[48 >> 2] = i2;
+      HEAP32[60 >> 2] = i4;
+     }
+     i32 = i3 + 8 | 0;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+   }
+  } else {
+   if (!(i12 >>> 0 > 4294967231)) {
+    i24 = i12 + 11 | 0;
+    i12 = i24 & -8;
+    i26 = HEAP32[44 >> 2] | 0;
+    if ((i26 | 0) != 0) {
+     i25 = 0 - i12 | 0;
+     i24 = i24 >>> 8;
+     if ((i24 | 0) != 0) {
+      if (i12 >>> 0 > 16777215) {
+       i27 = 31;
+      } else {
+       i31 = (i24 + 1048320 | 0) >>> 16 & 8;
+       i32 = i24 << i31;
+       i30 = (i32 + 520192 | 0) >>> 16 & 4;
+       i32 = i32 << i30;
+       i27 = (i32 + 245760 | 0) >>> 16 & 2;
+       i27 = 14 - (i30 | i31 | i27) + (i32 << i27 >>> 15) | 0;
+       i27 = i12 >>> (i27 + 7 | 0) & 1 | i27 << 1;
+      }
+     } else {
+      i27 = 0;
+     }
+     i30 = HEAP32[344 + (i27 << 2) >> 2] | 0;
+     L126 : do {
+      if ((i30 | 0) == 0) {
+       i29 = 0;
+       i24 = 0;
+      } else {
+       if ((i27 | 0) == 31) {
+        i24 = 0;
+       } else {
+        i24 = 25 - (i27 >>> 1) | 0;
+       }
+       i29 = 0;
+       i28 = i12 << i24;
+       i24 = 0;
+       while (1) {
+        i32 = HEAP32[i30 + 4 >> 2] & -8;
+        i31 = i32 - i12 | 0;
+        if (i31 >>> 0 < i25 >>> 0) {
+         if ((i32 | 0) == (i12 | 0)) {
+          i25 = i31;
+          i29 = i30;
+          i24 = i30;
+          break L126;
+         } else {
+          i25 = i31;
+          i24 = i30;
+         }
+        }
+        i31 = HEAP32[i30 + 20 >> 2] | 0;
+        i30 = HEAP32[i30 + (i28 >>> 31 << 2) + 16 >> 2] | 0;
+        i29 = (i31 | 0) == 0 | (i31 | 0) == (i30 | 0) ? i29 : i31;
+        if ((i30 | 0) == 0) {
+         break;
+        } else {
+         i28 = i28 << 1;
+        }
+       }
+      }
+     } while (0);
+     if ((i29 | 0) == 0 & (i24 | 0) == 0) {
+      i32 = 2 << i27;
+      i26 = i26 & (i32 | 0 - i32);
+      if ((i26 | 0) == 0) {
+       break;
+      }
+      i32 = (i26 & 0 - i26) + -1 | 0;
+      i28 = i32 >>> 12 & 16;
+      i32 = i32 >>> i28;
+      i27 = i32 >>> 5 & 8;
+      i32 = i32 >>> i27;
+      i30 = i32 >>> 2 & 4;
+      i32 = i32 >>> i30;
+      i31 = i32 >>> 1 & 2;
+      i32 = i32 >>> i31;
+      i29 = i32 >>> 1 & 1;
+      i29 = HEAP32[344 + ((i27 | i28 | i30 | i31 | i29) + (i32 >>> i29) << 2) >> 2] | 0;
+     }
+     if ((i29 | 0) != 0) {
+      while (1) {
+       i27 = (HEAP32[i29 + 4 >> 2] & -8) - i12 | 0;
+       i26 = i27 >>> 0 < i25 >>> 0;
+       i25 = i26 ? i27 : i25;
+       i24 = i26 ? i29 : i24;
+       i26 = HEAP32[i29 + 16 >> 2] | 0;
+       if ((i26 | 0) != 0) {
+        i29 = i26;
+        continue;
+       }
+       i29 = HEAP32[i29 + 20 >> 2] | 0;
+       if ((i29 | 0) == 0) {
+        break;
+       }
+      }
+     }
+     if ((i24 | 0) != 0 ? i25 >>> 0 < ((HEAP32[48 >> 2] | 0) - i12 | 0) >>> 0 : 0) {
+      i4 = HEAP32[56 >> 2] | 0;
+      if (i24 >>> 0 < i4 >>> 0) {
+       _abort();
+      }
+      i2 = i24 + i12 | 0;
+      if (!(i24 >>> 0 < i2 >>> 0)) {
+       _abort();
+      }
+      i3 = HEAP32[i24 + 24 >> 2] | 0;
+      i6 = HEAP32[i24 + 12 >> 2] | 0;
+      do {
+       if ((i6 | 0) == (i24 | 0)) {
+        i6 = i24 + 20 | 0;
+        i5 = HEAP32[i6 >> 2] | 0;
+        if ((i5 | 0) == 0) {
+         i6 = i24 + 16 | 0;
+         i5 = HEAP32[i6 >> 2] | 0;
+         if ((i5 | 0) == 0) {
+          i22 = 0;
+          break;
+         }
+        }
+        while (1) {
+         i8 = i5 + 20 | 0;
+         i7 = HEAP32[i8 >> 2] | 0;
+         if ((i7 | 0) != 0) {
+          i5 = i7;
+          i6 = i8;
+          continue;
+         }
+         i7 = i5 + 16 | 0;
+         i8 = HEAP32[i7 >> 2] | 0;
+         if ((i8 | 0) == 0) {
+          break;
+         } else {
+          i5 = i8;
+          i6 = i7;
+         }
+        }
+        if (i6 >>> 0 < i4 >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i6 >> 2] = 0;
+         i22 = i5;
+         break;
+        }
+       } else {
+        i5 = HEAP32[i24 + 8 >> 2] | 0;
+        if (i5 >>> 0 < i4 >>> 0) {
+         _abort();
+        }
+        i7 = i5 + 12 | 0;
+        if ((HEAP32[i7 >> 2] | 0) != (i24 | 0)) {
+         _abort();
+        }
+        i4 = i6 + 8 | 0;
+        if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
+         HEAP32[i7 >> 2] = i6;
+         HEAP32[i4 >> 2] = i5;
+         i22 = i6;
+         break;
+        } else {
+         _abort();
+        }
+       }
+      } while (0);
+      do {
+       if ((i3 | 0) != 0) {
+        i4 = HEAP32[i24 + 28 >> 2] | 0;
+        i5 = 344 + (i4 << 2) | 0;
+        if ((i24 | 0) == (HEAP32[i5 >> 2] | 0)) {
+         HEAP32[i5 >> 2] = i22;
+         if ((i22 | 0) == 0) {
+          HEAP32[44 >> 2] = HEAP32[44 >> 2] & ~(1 << i4);
+          break;
+         }
+        } else {
+         if (i3 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+          _abort();
+         }
+         i4 = i3 + 16 | 0;
+         if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
+          HEAP32[i4 >> 2] = i22;
+         } else {
+          HEAP32[i3 + 20 >> 2] = i22;
+         }
+         if ((i22 | 0) == 0) {
+          break;
+         }
+        }
+        if (i22 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+         _abort();
+        }
+        HEAP32[i22 + 24 >> 2] = i3;
+        i3 = HEAP32[i24 + 16 >> 2] | 0;
+        do {
+         if ((i3 | 0) != 0) {
+          if (i3 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           HEAP32[i22 + 16 >> 2] = i3;
+           HEAP32[i3 + 24 >> 2] = i22;
+           break;
+          }
+         }
+        } while (0);
+        i3 = HEAP32[i24 + 20 >> 2] | 0;
+        if ((i3 | 0) != 0) {
+         if (i3 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i22 + 20 >> 2] = i3;
+          HEAP32[i3 + 24 >> 2] = i22;
+          break;
+         }
+        }
+       }
+      } while (0);
+      L204 : do {
+       if (!(i25 >>> 0 < 16)) {
+        HEAP32[i24 + 4 >> 2] = i12 | 3;
+        HEAP32[i24 + (i12 | 4) >> 2] = i25 | 1;
+        HEAP32[i24 + (i25 + i12) >> 2] = i25;
+        i4 = i25 >>> 3;
+        if (i25 >>> 0 < 256) {
+         i6 = i4 << 1;
+         i3 = 80 + (i6 << 2) | 0;
+         i5 = HEAP32[10] | 0;
+         i4 = 1 << i4;
+         if ((i5 & i4 | 0) != 0) {
+          i5 = 80 + (i6 + 2 << 2) | 0;
+          i4 = HEAP32[i5 >> 2] | 0;
+          if (i4 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           i21 = i5;
+           i20 = i4;
+          }
+         } else {
+          HEAP32[10] = i5 | i4;
+          i21 = 80 + (i6 + 2 << 2) | 0;
+          i20 = i3;
+         }
+         HEAP32[i21 >> 2] = i2;
+         HEAP32[i20 + 12 >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i20;
+         HEAP32[i24 + (i12 + 12) >> 2] = i3;
+         break;
+        }
+        i3 = i25 >>> 8;
+        if ((i3 | 0) != 0) {
+         if (i25 >>> 0 > 16777215) {
+          i3 = 31;
+         } else {
+          i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+          i32 = i3 << i31;
+          i30 = (i32 + 520192 | 0) >>> 16 & 4;
+          i32 = i32 << i30;
+          i3 = (i32 + 245760 | 0) >>> 16 & 2;
+          i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+          i3 = i25 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+         }
+        } else {
+         i3 = 0;
+        }
+        i6 = 344 + (i3 << 2) | 0;
+        HEAP32[i24 + (i12 + 28) >> 2] = i3;
+        HEAP32[i24 + (i12 + 20) >> 2] = 0;
+        HEAP32[i24 + (i12 + 16) >> 2] = 0;
+        i4 = HEAP32[44 >> 2] | 0;
+        i5 = 1 << i3;
+        if ((i4 & i5 | 0) == 0) {
+         HEAP32[44 >> 2] = i4 | i5;
+         HEAP32[i6 >> 2] = i2;
+         HEAP32[i24 + (i12 + 24) >> 2] = i6;
+         HEAP32[i24 + (i12 + 12) >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i2;
+         break;
+        }
+        i4 = HEAP32[i6 >> 2] | 0;
+        if ((i3 | 0) == 31) {
+         i3 = 0;
+        } else {
+         i3 = 25 - (i3 >>> 1) | 0;
+        }
+        L225 : do {
+         if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i25 | 0)) {
+          i3 = i25 << i3;
+          while (1) {
+           i6 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+           i5 = HEAP32[i6 >> 2] | 0;
+           if ((i5 | 0) == 0) {
+            break;
+           }
+           if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i25 | 0)) {
+            i18 = i5;
+            break L225;
+           } else {
+            i3 = i3 << 1;
+            i4 = i5;
+           }
+          }
+          if (i6 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           HEAP32[i6 >> 2] = i2;
+           HEAP32[i24 + (i12 + 24) >> 2] = i4;
+           HEAP32[i24 + (i12 + 12) >> 2] = i2;
+           HEAP32[i24 + (i12 + 8) >> 2] = i2;
+           break L204;
+          }
+         } else {
+          i18 = i4;
+         }
+        } while (0);
+        i4 = i18 + 8 | 0;
+        i3 = HEAP32[i4 >> 2] | 0;
+        i5 = HEAP32[56 >> 2] | 0;
+        if (i18 >>> 0 < i5 >>> 0) {
+         _abort();
+        }
+        if (i3 >>> 0 < i5 >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i3 + 12 >> 2] = i2;
+         HEAP32[i4 >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i3;
+         HEAP32[i24 + (i12 + 12) >> 2] = i18;
+         HEAP32[i24 + (i12 + 24) >> 2] = 0;
+         break;
+        }
+       } else {
+        i32 = i25 + i12 | 0;
+        HEAP32[i24 + 4 >> 2] = i32 | 3;
+        i32 = i24 + (i32 + 4) | 0;
+        HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+       }
+      } while (0);
+      i32 = i24 + 8 | 0;
+      STACKTOP = i1;
+      return i32 | 0;
+     }
+    }
+   } else {
+    i12 = -1;
+   }
+  }
+ } while (0);
+ i18 = HEAP32[48 >> 2] | 0;
+ if (!(i12 >>> 0 > i18 >>> 0)) {
+  i3 = i18 - i12 | 0;
+  i2 = HEAP32[60 >> 2] | 0;
+  if (i3 >>> 0 > 15) {
+   HEAP32[60 >> 2] = i2 + i12;
+   HEAP32[48 >> 2] = i3;
+   HEAP32[i2 + (i12 + 4) >> 2] = i3 | 1;
+   HEAP32[i2 + i18 >> 2] = i3;
+   HEAP32[i2 + 4 >> 2] = i12 | 3;
+  } else {
+   HEAP32[48 >> 2] = 0;
+   HEAP32[60 >> 2] = 0;
+   HEAP32[i2 + 4 >> 2] = i18 | 3;
+   i32 = i2 + (i18 + 4) | 0;
+   HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+  }
+  i32 = i2 + 8 | 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ i18 = HEAP32[52 >> 2] | 0;
+ if (i12 >>> 0 < i18 >>> 0) {
+  i31 = i18 - i12 | 0;
+  HEAP32[52 >> 2] = i31;
+  i32 = HEAP32[64 >> 2] | 0;
+  HEAP32[64 >> 2] = i32 + i12;
+  HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
+  HEAP32[i32 + 4 >> 2] = i12 | 3;
+  i32 = i32 + 8 | 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ do {
+  if ((HEAP32[128] | 0) == 0) {
+   i18 = _sysconf(30) | 0;
+   if ((i18 + -1 & i18 | 0) == 0) {
+    HEAP32[520 >> 2] = i18;
+    HEAP32[516 >> 2] = i18;
+    HEAP32[524 >> 2] = -1;
+    HEAP32[528 >> 2] = -1;
+    HEAP32[532 >> 2] = 0;
+    HEAP32[484 >> 2] = 0;
+    HEAP32[128] = (_time(0) | 0) & -16 ^ 1431655768;
+    break;
+   } else {
+    _abort();
+   }
+  }
+ } while (0);
+ i20 = i12 + 48 | 0;
+ i25 = HEAP32[520 >> 2] | 0;
+ i21 = i12 + 47 | 0;
+ i22 = i25 + i21 | 0;
+ i25 = 0 - i25 | 0;
+ i18 = i22 & i25;
+ if (!(i18 >>> 0 > i12 >>> 0)) {
+  i32 = 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ i24 = HEAP32[480 >> 2] | 0;
+ if ((i24 | 0) != 0 ? (i31 = HEAP32[472 >> 2] | 0, i32 = i31 + i18 | 0, i32 >>> 0 <= i31 >>> 0 | i32 >>> 0 > i24 >>> 0) : 0) {
+  i32 = 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ L269 : do {
+  if ((HEAP32[484 >> 2] & 4 | 0) == 0) {
+   i26 = HEAP32[64 >> 2] | 0;
+   L271 : do {
+    if ((i26 | 0) != 0) {
+     i24 = 488 | 0;
+     while (1) {
+      i27 = HEAP32[i24 >> 2] | 0;
+      if (!(i27 >>> 0 > i26 >>> 0) ? (i23 = i24 + 4 | 0, (i27 + (HEAP32[i23 >> 2] | 0) | 0) >>> 0 > i26 >>> 0) : 0) {
+       break;
+      }
+      i24 = HEAP32[i24 + 8 >> 2] | 0;
+      if ((i24 | 0) == 0) {
+       i13 = 182;
+       break L271;
+      }
+     }
+     if ((i24 | 0) != 0) {
+      i25 = i22 - (HEAP32[52 >> 2] | 0) & i25;
+      if (i25 >>> 0 < 2147483647) {
+       i13 = _sbrk(i25 | 0) | 0;
+       i26 = (i13 | 0) == ((HEAP32[i24 >> 2] | 0) + (HEAP32[i23 >> 2] | 0) | 0);
+       i22 = i13;
+       i24 = i25;
+       i23 = i26 ? i13 : -1;
+       i25 = i26 ? i25 : 0;
+       i13 = 191;
+      } else {
+       i25 = 0;
+      }
+     } else {
+      i13 = 182;
+     }
+    } else {
+     i13 = 182;
+    }
+   } while (0);
+   do {
+    if ((i13 | 0) == 182) {
+     i23 = _sbrk(0) | 0;
+     if ((i23 | 0) != (-1 | 0)) {
+      i24 = i23;
+      i22 = HEAP32[516 >> 2] | 0;
+      i25 = i22 + -1 | 0;
+      if ((i25 & i24 | 0) == 0) {
+       i25 = i18;
+      } else {
+       i25 = i18 - i24 + (i25 + i24 & 0 - i22) | 0;
+      }
+      i24 = HEAP32[472 >> 2] | 0;
+      i26 = i24 + i25 | 0;
+      if (i25 >>> 0 > i12 >>> 0 & i25 >>> 0 < 2147483647) {
+       i22 = HEAP32[480 >> 2] | 0;
+       if ((i22 | 0) != 0 ? i26 >>> 0 <= i24 >>> 0 | i26 >>> 0 > i22 >>> 0 : 0) {
+        i25 = 0;
+        break;
+       }
+       i22 = _sbrk(i25 | 0) | 0;
+       i13 = (i22 | 0) == (i23 | 0);
+       i24 = i25;
+       i23 = i13 ? i23 : -1;
+       i25 = i13 ? i25 : 0;
+       i13 = 191;
+      } else {
+       i25 = 0;
+      }
+     } else {
+      i25 = 0;
+     }
+    }
+   } while (0);
+   L291 : do {
+    if ((i13 | 0) == 191) {
+     i13 = 0 - i24 | 0;
+     if ((i23 | 0) != (-1 | 0)) {
+      i17 = i23;
+      i14 = i25;
+      i13 = 202;
+      break L269;
+     }
+     do {
+      if ((i22 | 0) != (-1 | 0) & i24 >>> 0 < 2147483647 & i24 >>> 0 < i20 >>> 0 ? (i19 = HEAP32[520 >> 2] | 0, i19 = i21 - i24 + i19 & 0 - i19, i19 >>> 0 < 2147483647) : 0) {
+       if ((_sbrk(i19 | 0) | 0) == (-1 | 0)) {
+        _sbrk(i13 | 0) | 0;
+        break L291;
+       } else {
+        i24 = i19 + i24 | 0;
+        break;
+       }
+      }
+     } while (0);
+     if ((i22 | 0) != (-1 | 0)) {
+      i17 = i22;
+      i14 = i24;
+      i13 = 202;
+      break L269;
+     }
+    }
+   } while (0);
+   HEAP32[484 >> 2] = HEAP32[484 >> 2] | 4;
+   i13 = 199;
+  } else {
+   i25 = 0;
+   i13 = 199;
+  }
+ } while (0);
+ if ((((i13 | 0) == 199 ? i18 >>> 0 < 2147483647 : 0) ? (i17 = _sbrk(i18 | 0) | 0, i16 = _sbrk(0) | 0, (i16 | 0) != (-1 | 0) & (i17 | 0) != (-1 | 0) & i17 >>> 0 < i16 >>> 0) : 0) ? (i15 = i16 - i17 | 0, i14 = i15 >>> 0 > (i12 + 40 | 0) >>> 0, i14) : 0) {
+  i14 = i14 ? i15 : i25;
+  i13 = 202;
+ }
+ if ((i13 | 0) == 202) {
+  i15 = (HEAP32[472 >> 2] | 0) + i14 | 0;
+  HEAP32[472 >> 2] = i15;
+  if (i15 >>> 0 > (HEAP32[476 >> 2] | 0) >>> 0) {
+   HEAP32[476 >> 2] = i15;
+  }
+  i15 = HEAP32[64 >> 2] | 0;
+  L311 : do {
+   if ((i15 | 0) != 0) {
+    i21 = 488 | 0;
+    while (1) {
+     i16 = HEAP32[i21 >> 2] | 0;
+     i19 = i21 + 4 | 0;
+     i20 = HEAP32[i19 >> 2] | 0;
+     if ((i17 | 0) == (i16 + i20 | 0)) {
+      i13 = 214;
+      break;
+     }
+     i18 = HEAP32[i21 + 8 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      break;
+     } else {
+      i21 = i18;
+     }
+    }
+    if (((i13 | 0) == 214 ? (HEAP32[i21 + 12 >> 2] & 8 | 0) == 0 : 0) ? i15 >>> 0 >= i16 >>> 0 & i15 >>> 0 < i17 >>> 0 : 0) {
+     HEAP32[i19 >> 2] = i20 + i14;
+     i2 = (HEAP32[52 >> 2] | 0) + i14 | 0;
+     i3 = i15 + 8 | 0;
+     if ((i3 & 7 | 0) == 0) {
+      i3 = 0;
+     } else {
+      i3 = 0 - i3 & 7;
+     }
+     i32 = i2 - i3 | 0;
+     HEAP32[64 >> 2] = i15 + i3;
+     HEAP32[52 >> 2] = i32;
+     HEAP32[i15 + (i3 + 4) >> 2] = i32 | 1;
+     HEAP32[i15 + (i2 + 4) >> 2] = 40;
+     HEAP32[68 >> 2] = HEAP32[528 >> 2];
+     break;
+    }
+    if (i17 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+     HEAP32[56 >> 2] = i17;
+    }
+    i19 = i17 + i14 | 0;
+    i16 = 488 | 0;
+    while (1) {
+     if ((HEAP32[i16 >> 2] | 0) == (i19 | 0)) {
+      i13 = 224;
+      break;
+     }
+     i18 = HEAP32[i16 + 8 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      break;
+     } else {
+      i16 = i18;
+     }
+    }
+    if ((i13 | 0) == 224 ? (HEAP32[i16 + 12 >> 2] & 8 | 0) == 0 : 0) {
+     HEAP32[i16 >> 2] = i17;
+     i6 = i16 + 4 | 0;
+     HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i14;
+     i6 = i17 + 8 | 0;
+     if ((i6 & 7 | 0) == 0) {
+      i6 = 0;
+     } else {
+      i6 = 0 - i6 & 7;
+     }
+     i7 = i17 + (i14 + 8) | 0;
+     if ((i7 & 7 | 0) == 0) {
+      i13 = 0;
+     } else {
+      i13 = 0 - i7 & 7;
+     }
+     i15 = i17 + (i13 + i14) | 0;
+     i8 = i6 + i12 | 0;
+     i7 = i17 + i8 | 0;
+     i10 = i15 - (i17 + i6) - i12 | 0;
+     HEAP32[i17 + (i6 + 4) >> 2] = i12 | 3;
+     L348 : do {
+      if ((i15 | 0) != (HEAP32[64 >> 2] | 0)) {
+       if ((i15 | 0) == (HEAP32[60 >> 2] | 0)) {
+        i32 = (HEAP32[48 >> 2] | 0) + i10 | 0;
+        HEAP32[48 >> 2] = i32;
+        HEAP32[60 >> 2] = i7;
+        HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
+        HEAP32[i17 + (i32 + i8) >> 2] = i32;
+        break;
+       }
+       i12 = i14 + 4 | 0;
+       i18 = HEAP32[i17 + (i12 + i13) >> 2] | 0;
+       if ((i18 & 3 | 0) == 1) {
+        i11 = i18 & -8;
+        i16 = i18 >>> 3;
+        do {
+         if (!(i18 >>> 0 < 256)) {
+          i9 = HEAP32[i17 + ((i13 | 24) + i14) >> 2] | 0;
+          i19 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
+          do {
+           if ((i19 | 0) == (i15 | 0)) {
+            i19 = i13 | 16;
+            i18 = i17 + (i12 + i19) | 0;
+            i16 = HEAP32[i18 >> 2] | 0;
+            if ((i16 | 0) == 0) {
+             i18 = i17 + (i19 + i14) | 0;
+             i16 = HEAP32[i18 >> 2] | 0;
+             if ((i16 | 0) == 0) {
+              i5 = 0;
+              break;
+             }
+            }
+            while (1) {
+             i20 = i16 + 20 | 0;
+             i19 = HEAP32[i20 >> 2] | 0;
+             if ((i19 | 0) != 0) {
+              i16 = i19;
+              i18 = i20;
+              continue;
+             }
+             i19 = i16 + 16 | 0;
+             i20 = HEAP32[i19 >> 2] | 0;
+             if ((i20 | 0) == 0) {
+              break;
+             } else {
+              i16 = i20;
+              i18 = i19;
+             }
+            }
+            if (i18 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+             _abort();
+            } else {
+             HEAP32[i18 >> 2] = 0;
+             i5 = i16;
+             break;
+            }
+           } else {
+            i18 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
+            if (i18 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+             _abort();
+            }
+            i16 = i18 + 12 | 0;
+            if ((HEAP32[i16 >> 2] | 0) != (i15 | 0)) {
+             _abort();
+            }
+            i20 = i19 + 8 | 0;
+            if ((HEAP32[i20 >> 2] | 0) == (i15 | 0)) {
+             HEAP32[i16 >> 2] = i19;
+             HEAP32[i20 >> 2] = i18;
+             i5 = i19;
+             break;
+            } else {
+             _abort();
+            }
+           }
+          } while (0);
+          if ((i9 | 0) != 0) {
+           i16 = HEAP32[i17 + (i14 + 28 + i13) >> 2] | 0;
+           i18 = 344 + (i16 << 2) | 0;
+           if ((i15 | 0) == (HEAP32[i18 >> 2] | 0)) {
+            HEAP32[i18 >> 2] = i5;
+            if ((i5 | 0) == 0) {
+             HEAP32[44 >> 2] = HEAP32[44 >> 2] & ~(1 << i16);
+             break;
+            }
+           } else {
+            if (i9 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+             _abort();
+            }
+            i16 = i9 + 16 | 0;
+            if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
+             HEAP32[i16 >> 2] = i5;
+            } else {
+             HEAP32[i9 + 20 >> 2] = i5;
+            }
+            if ((i5 | 0) == 0) {
+             break;
+            }
+           }
+           if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           HEAP32[i5 + 24 >> 2] = i9;
+           i15 = i13 | 16;
+           i9 = HEAP32[i17 + (i15 + i14) >> 2] | 0;
+           do {
+            if ((i9 | 0) != 0) {
+             if (i9 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+              _abort();
+             } else {
+              HEAP32[i5 + 16 >> 2] = i9;
+              HEAP32[i9 + 24 >> 2] = i5;
+              break;
+             }
+            }
+           } while (0);
+           i9 = HEAP32[i17 + (i12 + i15) >> 2] | 0;
+           if ((i9 | 0) != 0) {
+            if (i9 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+             _abort();
+            } else {
+             HEAP32[i5 + 20 >> 2] = i9;
+             HEAP32[i9 + 24 >> 2] = i5;
+             break;
+            }
+           }
+          }
+         } else {
+          i5 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
+          i12 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
+          i18 = 80 + (i16 << 1 << 2) | 0;
+          if ((i5 | 0) != (i18 | 0)) {
+           if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           if ((HEAP32[i5 + 12 >> 2] | 0) != (i15 | 0)) {
+            _abort();
+           }
+          }
+          if ((i12 | 0) == (i5 | 0)) {
+           HEAP32[10] = HEAP32[10] & ~(1 << i16);
+           break;
+          }
+          if ((i12 | 0) != (i18 | 0)) {
+           if (i12 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           i16 = i12 + 8 | 0;
+           if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
+            i9 = i16;
+           } else {
+            _abort();
+           }
+          } else {
+           i9 = i12 + 8 | 0;
+          }
+          HEAP32[i5 + 12 >> 2] = i12;
+          HEAP32[i9 >> 2] = i5;
+         }
+        } while (0);
+        i15 = i17 + ((i11 | i13) + i14) | 0;
+        i10 = i11 + i10 | 0;
+       }
+       i5 = i15 + 4 | 0;
+       HEAP32[i5 >> 2] = HEAP32[i5 >> 2] & -2;
+       HEAP32[i17 + (i8 + 4) >> 2] = i10 | 1;
+       HEAP32[i17 + (i10 + i8) >> 2] = i10;
+       i5 = i10 >>> 3;
+       if (i10 >>> 0 < 256) {
+        i10 = i5 << 1;
+        i2 = 80 + (i10 << 2) | 0;
+        i9 = HEAP32[10] | 0;
+        i5 = 1 << i5;
+        if ((i9 & i5 | 0) != 0) {
+         i9 = 80 + (i10 + 2 << 2) | 0;
+         i5 = HEAP32[i9 >> 2] | 0;
+         if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          i3 = i9;
+          i4 = i5;
+         }
+        } else {
+         HEAP32[10] = i9 | i5;
+         i3 = 80 + (i10 + 2 << 2) | 0;
+         i4 = i2;
+        }
+        HEAP32[i3 >> 2] = i7;
+        HEAP32[i4 + 12 >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i4;
+        HEAP32[i17 + (i8 + 12) >> 2] = i2;
+        break;
+       }
+       i3 = i10 >>> 8;
+       if ((i3 | 0) != 0) {
+        if (i10 >>> 0 > 16777215) {
+         i3 = 31;
+        } else {
+         i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+         i32 = i3 << i31;
+         i30 = (i32 + 520192 | 0) >>> 16 & 4;
+         i32 = i32 << i30;
+         i3 = (i32 + 245760 | 0) >>> 16 & 2;
+         i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+         i3 = i10 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+        }
+       } else {
+        i3 = 0;
+       }
+       i4 = 344 + (i3 << 2) | 0;
+       HEAP32[i17 + (i8 + 28) >> 2] = i3;
+       HEAP32[i17 + (i8 + 20) >> 2] = 0;
+       HEAP32[i17 + (i8 + 16) >> 2] = 0;
+       i9 = HEAP32[44 >> 2] | 0;
+       i5 = 1 << i3;
+       if ((i9 & i5 | 0) == 0) {
+        HEAP32[44 >> 2] = i9 | i5;
+        HEAP32[i4 >> 2] = i7;
+        HEAP32[i17 + (i8 + 24) >> 2] = i4;
+        HEAP32[i17 + (i8 + 12) >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i7;
+        break;
+       }
+       i4 = HEAP32[i4 >> 2] | 0;
+       if ((i3 | 0) == 31) {
+        i3 = 0;
+       } else {
+        i3 = 25 - (i3 >>> 1) | 0;
+       }
+       L444 : do {
+        if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i10 | 0)) {
+         i3 = i10 << i3;
+         while (1) {
+          i5 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+          i9 = HEAP32[i5 >> 2] | 0;
+          if ((i9 | 0) == 0) {
+           break;
+          }
+          if ((HEAP32[i9 + 4 >> 2] & -8 | 0) == (i10 | 0)) {
+           i2 = i9;
+           break L444;
+          } else {
+           i3 = i3 << 1;
+           i4 = i9;
+          }
+         }
+         if (i5 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i5 >> 2] = i7;
+          HEAP32[i17 + (i8 + 24) >> 2] = i4;
+          HEAP32[i17 + (i8 + 12) >> 2] = i7;
+          HEAP32[i17 + (i8 + 8) >> 2] = i7;
+          break L348;
+         }
+        } else {
+         i2 = i4;
+        }
+       } while (0);
+       i4 = i2 + 8 | 0;
+       i3 = HEAP32[i4 >> 2] | 0;
+       i5 = HEAP32[56 >> 2] | 0;
+       if (i2 >>> 0 < i5 >>> 0) {
+        _abort();
+       }
+       if (i3 >>> 0 < i5 >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i3 + 12 >> 2] = i7;
+        HEAP32[i4 >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i3;
+        HEAP32[i17 + (i8 + 12) >> 2] = i2;
+        HEAP32[i17 + (i8 + 24) >> 2] = 0;
+        break;
+       }
+      } else {
+       i32 = (HEAP32[52 >> 2] | 0) + i10 | 0;
+       HEAP32[52 >> 2] = i32;
+       HEAP32[64 >> 2] = i7;
+       HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
+      }
+     } while (0);
+     i32 = i17 + (i6 | 8) | 0;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+    i3 = 488 | 0;
+    while (1) {
+     i2 = HEAP32[i3 >> 2] | 0;
+     if (!(i2 >>> 0 > i15 >>> 0) ? (i11 = HEAP32[i3 + 4 >> 2] | 0, i10 = i2 + i11 | 0, i10 >>> 0 > i15 >>> 0) : 0) {
+      break;
+     }
+     i3 = HEAP32[i3 + 8 >> 2] | 0;
+    }
+    i3 = i2 + (i11 + -39) | 0;
+    if ((i3 & 7 | 0) == 0) {
+     i3 = 0;
+    } else {
+     i3 = 0 - i3 & 7;
+    }
+    i2 = i2 + (i11 + -47 + i3) | 0;
+    i2 = i2 >>> 0 < (i15 + 16 | 0) >>> 0 ? i15 : i2;
+    i3 = i2 + 8 | 0;
+    i4 = i17 + 8 | 0;
+    if ((i4 & 7 | 0) == 0) {
+     i4 = 0;
+    } else {
+     i4 = 0 - i4 & 7;
+    }
+    i32 = i14 + -40 - i4 | 0;
+    HEAP32[64 >> 2] = i17 + i4;
+    HEAP32[52 >> 2] = i32;
+    HEAP32[i17 + (i4 + 4) >> 2] = i32 | 1;
+    HEAP32[i17 + (i14 + -36) >> 2] = 40;
+    HEAP32[68 >> 2] = HEAP32[528 >> 2];
+    HEAP32[i2 + 4 >> 2] = 27;
+    HEAP32[i3 + 0 >> 2] = HEAP32[488 >> 2];
+    HEAP32[i3 + 4 >> 2] = HEAP32[492 >> 2];
+    HEAP32[i3 + 8 >> 2] = HEAP32[496 >> 2];
+    HEAP32[i3 + 12 >> 2] = HEAP32[500 >> 2];
+    HEAP32[488 >> 2] = i17;
+    HEAP32[492 >> 2] = i14;
+    HEAP32[500 >> 2] = 0;
+    HEAP32[496 >> 2] = i3;
+    i4 = i2 + 28 | 0;
+    HEAP32[i4 >> 2] = 7;
+    if ((i2 + 32 | 0) >>> 0 < i10 >>> 0) {
+     while (1) {
+      i3 = i4 + 4 | 0;
+      HEAP32[i3 >> 2] = 7;
+      if ((i4 + 8 | 0) >>> 0 < i10 >>> 0) {
+       i4 = i3;
+      } else {
+       break;
+      }
+     }
+    }
+    if ((i2 | 0) != (i15 | 0)) {
+     i2 = i2 - i15 | 0;
+     i3 = i15 + (i2 + 4) | 0;
+     HEAP32[i3 >> 2] = HEAP32[i3 >> 2] & -2;
+     HEAP32[i15 + 4 >> 2] = i2 | 1;
+     HEAP32[i15 + i2 >> 2] = i2;
+     i3 = i2 >>> 3;
+     if (i2 >>> 0 < 256) {
+      i4 = i3 << 1;
+      i2 = 80 + (i4 << 2) | 0;
+      i5 = HEAP32[10] | 0;
+      i3 = 1 << i3;
+      if ((i5 & i3 | 0) != 0) {
+       i4 = 80 + (i4 + 2 << 2) | 0;
+       i3 = HEAP32[i4 >> 2] | 0;
+       if (i3 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        i7 = i4;
+        i8 = i3;
+       }
+      } else {
+       HEAP32[10] = i5 | i3;
+       i7 = 80 + (i4 + 2 << 2) | 0;
+       i8 = i2;
+      }
+      HEAP32[i7 >> 2] = i15;
+      HEAP32[i8 + 12 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i8;
+      HEAP32[i15 + 12 >> 2] = i2;
+      break;
+     }
+     i3 = i2 >>> 8;
+     if ((i3 | 0) != 0) {
+      if (i2 >>> 0 > 16777215) {
+       i3 = 31;
+      } else {
+       i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+       i32 = i3 << i31;
+       i30 = (i32 + 520192 | 0) >>> 16 & 4;
+       i32 = i32 << i30;
+       i3 = (i32 + 245760 | 0) >>> 16 & 2;
+       i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+       i3 = i2 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+      }
+     } else {
+      i3 = 0;
+     }
+     i7 = 344 + (i3 << 2) | 0;
+     HEAP32[i15 + 28 >> 2] = i3;
+     HEAP32[i15 + 20 >> 2] = 0;
+     HEAP32[i15 + 16 >> 2] = 0;
+     i4 = HEAP32[44 >> 2] | 0;
+     i5 = 1 << i3;
+     if ((i4 & i5 | 0) == 0) {
+      HEAP32[44 >> 2] = i4 | i5;
+      HEAP32[i7 >> 2] = i15;
+      HEAP32[i15 + 24 >> 2] = i7;
+      HEAP32[i15 + 12 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i15;
+      break;
+     }
+     i4 = HEAP32[i7 >> 2] | 0;
+     if ((i3 | 0) == 31) {
+      i3 = 0;
+     } else {
+      i3 = 25 - (i3 >>> 1) | 0;
+     }
+     L499 : do {
+      if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i2 | 0)) {
+       i3 = i2 << i3;
+       while (1) {
+        i7 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+        i5 = HEAP32[i7 >> 2] | 0;
+        if ((i5 | 0) == 0) {
+         break;
+        }
+        if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i2 | 0)) {
+         i6 = i5;
+         break L499;
+        } else {
+         i3 = i3 << 1;
+         i4 = i5;
+        }
+       }
+       if (i7 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i7 >> 2] = i15;
+        HEAP32[i15 + 24 >> 2] = i4;
+        HEAP32[i15 + 12 >> 2] = i15;
+        HEAP32[i15 + 8 >> 2] = i15;
+        break L311;
+       }
+      } else {
+       i6 = i4;
+      }
+     } while (0);
+     i4 = i6 + 8 | 0;
+     i3 = HEAP32[i4 >> 2] | 0;
+     i2 = HEAP32[56 >> 2] | 0;
+     if (i6 >>> 0 < i2 >>> 0) {
+      _abort();
+     }
+     if (i3 >>> 0 < i2 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i3 + 12 >> 2] = i15;
+      HEAP32[i4 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i3;
+      HEAP32[i15 + 12 >> 2] = i6;
+      HEAP32[i15 + 24 >> 2] = 0;
+      break;
+     }
+    }
+   } else {
+    i32 = HEAP32[56 >> 2] | 0;
+    if ((i32 | 0) == 0 | i17 >>> 0 < i32 >>> 0) {
+     HEAP32[56 >> 2] = i17;
+    }
+    HEAP32[488 >> 2] = i17;
+    HEAP32[492 >> 2] = i14;
+    HEAP32[500 >> 2] = 0;
+    HEAP32[76 >> 2] = HEAP32[128];
+    HEAP32[72 >> 2] = -1;
+    i2 = 0;
+    do {
+     i32 = i2 << 1;
+     i31 = 80 + (i32 << 2) | 0;
+     HEAP32[80 + (i32 + 3 << 2) >> 2] = i31;
+     HEAP32[80 + (i32 + 2 << 2) >> 2] = i31;
+     i2 = i2 + 1 | 0;
+    } while ((i2 | 0) != 32);
+    i2 = i17 + 8 | 0;
+    if ((i2 & 7 | 0) == 0) {
+     i2 = 0;
+    } else {
+     i2 = 0 - i2 & 7;
+    }
+    i32 = i14 + -40 - i2 | 0;
+    HEAP32[64 >> 2] = i17 + i2;
+    HEAP32[52 >> 2] = i32;
+    HEAP32[i17 + (i2 + 4) >> 2] = i32 | 1;
+    HEAP32[i17 + (i14 + -36) >> 2] = 40;
+    HEAP32[68 >> 2] = HEAP32[528 >> 2];
+   }
+  } while (0);
+  i2 = HEAP32[52 >> 2] | 0;
+  if (i2 >>> 0 > i12 >>> 0) {
+   i31 = i2 - i12 | 0;
+   HEAP32[52 >> 2] = i31;
+   i32 = HEAP32[64 >> 2] | 0;
+   HEAP32[64 >> 2] = i32 + i12;
+   HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
+   HEAP32[i32 + 4 >> 2] = i12 | 3;
+   i32 = i32 + 8 | 0;
+   STACKTOP = i1;
+   return i32 | 0;
+  }
+ }
+ HEAP32[(___errno_location() | 0) >> 2] = 12;
+ i32 = 0;
+ STACKTOP = i1;
+ return i32 | 0;
+}
+function _free(i7) {
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0;
+ i1 = STACKTOP;
+ if ((i7 | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i15 = i7 + -8 | 0;
+ i16 = HEAP32[56 >> 2] | 0;
+ if (i15 >>> 0 < i16 >>> 0) {
+  _abort();
+ }
+ i13 = HEAP32[i7 + -4 >> 2] | 0;
+ i12 = i13 & 3;
+ if ((i12 | 0) == 1) {
+  _abort();
+ }
+ i8 = i13 & -8;
+ i6 = i7 + (i8 + -8) | 0;
+ do {
+  if ((i13 & 1 | 0) == 0) {
+   i19 = HEAP32[i15 >> 2] | 0;
+   if ((i12 | 0) == 0) {
+    STACKTOP = i1;
+    return;
+   }
+   i15 = -8 - i19 | 0;
+   i13 = i7 + i15 | 0;
+   i12 = i19 + i8 | 0;
+   if (i13 >>> 0 < i16 >>> 0) {
+    _abort();
+   }
+   if ((i13 | 0) == (HEAP32[60 >> 2] | 0)) {
+    i2 = i7 + (i8 + -4) | 0;
+    if ((HEAP32[i2 >> 2] & 3 | 0) != 3) {
+     i2 = i13;
+     i11 = i12;
+     break;
+    }
+    HEAP32[48 >> 2] = i12;
+    HEAP32[i2 >> 2] = HEAP32[i2 >> 2] & -2;
+    HEAP32[i7 + (i15 + 4) >> 2] = i12 | 1;
+    HEAP32[i6 >> 2] = i12;
+    STACKTOP = i1;
+    return;
+   }
+   i18 = i19 >>> 3;
+   if (i19 >>> 0 < 256) {
+    i2 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
+    i11 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
+    i14 = 80 + (i18 << 1 << 2) | 0;
+    if ((i2 | 0) != (i14 | 0)) {
+     if (i2 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i2 + 12 >> 2] | 0) != (i13 | 0)) {
+      _abort();
+     }
+    }
+    if ((i11 | 0) == (i2 | 0)) {
+     HEAP32[10] = HEAP32[10] & ~(1 << i18);
+     i2 = i13;
+     i11 = i12;
+     break;
+    }
+    if ((i11 | 0) != (i14 | 0)) {
+     if (i11 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     i14 = i11 + 8 | 0;
+     if ((HEAP32[i14 >> 2] | 0) == (i13 | 0)) {
+      i17 = i14;
+     } else {
+      _abort();
+     }
+    } else {
+     i17 = i11 + 8 | 0;
+    }
+    HEAP32[i2 + 12 >> 2] = i11;
+    HEAP32[i17 >> 2] = i2;
+    i2 = i13;
+    i11 = i12;
+    break;
+   }
+   i17 = HEAP32[i7 + (i15 + 24) >> 2] | 0;
+   i18 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
+   do {
+    if ((i18 | 0) == (i13 | 0)) {
+     i19 = i7 + (i15 + 20) | 0;
+     i18 = HEAP32[i19 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      i19 = i7 + (i15 + 16) | 0;
+      i18 = HEAP32[i19 >> 2] | 0;
+      if ((i18 | 0) == 0) {
+       i14 = 0;
+       break;
+      }
+     }
+     while (1) {
+      i21 = i18 + 20 | 0;
+      i20 = HEAP32[i21 >> 2] | 0;
+      if ((i20 | 0) != 0) {
+       i18 = i20;
+       i19 = i21;
+       continue;
+      }
+      i20 = i18 + 16 | 0;
+      i21 = HEAP32[i20 >> 2] | 0;
+      if ((i21 | 0) == 0) {
+       break;
+      } else {
+       i18 = i21;
+       i19 = i20;
+      }
+     }
+     if (i19 >>> 0 < i16 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i19 >> 2] = 0;
+      i14 = i18;
+      break;
+     }
+    } else {
+     i19 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
+     if (i19 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     i16 = i19 + 12 | 0;
+     if ((HEAP32[i16 >> 2] | 0) != (i13 | 0)) {
+      _abort();
+     }
+     i20 = i18 + 8 | 0;
+     if ((HEAP32[i20 >> 2] | 0) == (i13 | 0)) {
+      HEAP32[i16 >> 2] = i18;
+      HEAP32[i20 >> 2] = i19;
+      i14 = i18;
+      break;
+     } else {
+      _abort();
+     }
+    }
+   } while (0);
+   if ((i17 | 0) != 0) {
+    i18 = HEAP32[i7 + (i15 + 28) >> 2] | 0;
+    i16 = 344 + (i18 << 2) | 0;
+    if ((i13 | 0) == (HEAP32[i16 >> 2] | 0)) {
+     HEAP32[i16 >> 2] = i14;
+     if ((i14 | 0) == 0) {
+      HEAP32[44 >> 2] = HEAP32[44 >> 2] & ~(1 << i18);
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    } else {
+     if (i17 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i16 = i17 + 16 | 0;
+     if ((HEAP32[i16 >> 2] | 0) == (i13 | 0)) {
+      HEAP32[i16 >> 2] = i14;
+     } else {
+      HEAP32[i17 + 20 >> 2] = i14;
+     }
+     if ((i14 | 0) == 0) {
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    }
+    if (i14 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+     _abort();
+    }
+    HEAP32[i14 + 24 >> 2] = i17;
+    i16 = HEAP32[i7 + (i15 + 16) >> 2] | 0;
+    do {
+     if ((i16 | 0) != 0) {
+      if (i16 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i14 + 16 >> 2] = i16;
+       HEAP32[i16 + 24 >> 2] = i14;
+       break;
+      }
+     }
+    } while (0);
+    i15 = HEAP32[i7 + (i15 + 20) >> 2] | 0;
+    if ((i15 | 0) != 0) {
+     if (i15 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i14 + 20 >> 2] = i15;
+      HEAP32[i15 + 24 >> 2] = i14;
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    } else {
+     i2 = i13;
+     i11 = i12;
+    }
+   } else {
+    i2 = i13;
+    i11 = i12;
+   }
+  } else {
+   i2 = i15;
+   i11 = i8;
+  }
+ } while (0);
+ if (!(i2 >>> 0 < i6 >>> 0)) {
+  _abort();
+ }
+ i12 = i7 + (i8 + -4) | 0;
+ i13 = HEAP32[i12 >> 2] | 0;
+ if ((i13 & 1 | 0) == 0) {
+  _abort();
+ }
+ if ((i13 & 2 | 0) == 0) {
+  if ((i6 | 0) == (HEAP32[64 >> 2] | 0)) {
+   i21 = (HEAP32[52 >> 2] | 0) + i11 | 0;
+   HEAP32[52 >> 2] = i21;
+   HEAP32[64 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i21 | 1;
+   if ((i2 | 0) != (HEAP32[60 >> 2] | 0)) {
+    STACKTOP = i1;
+    return;
+   }
+   HEAP32[60 >> 2] = 0;
+   HEAP32[48 >> 2] = 0;
+   STACKTOP = i1;
+   return;
+  }
+  if ((i6 | 0) == (HEAP32[60 >> 2] | 0)) {
+   i21 = (HEAP32[48 >> 2] | 0) + i11 | 0;
+   HEAP32[48 >> 2] = i21;
+   HEAP32[60 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i21 | 1;
+   HEAP32[i2 + i21 >> 2] = i21;
+   STACKTOP = i1;
+   return;
+  }
+  i11 = (i13 & -8) + i11 | 0;
+  i12 = i13 >>> 3;
+  do {
+   if (!(i13 >>> 0 < 256)) {
+    i10 = HEAP32[i7 + (i8 + 16) >> 2] | 0;
+    i15 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
+    do {
+     if ((i15 | 0) == (i6 | 0)) {
+      i13 = i7 + (i8 + 12) | 0;
+      i12 = HEAP32[i13 >> 2] | 0;
+      if ((i12 | 0) == 0) {
+       i13 = i7 + (i8 + 8) | 0;
+       i12 = HEAP32[i13 >> 2] | 0;
+       if ((i12 | 0) == 0) {
+        i9 = 0;
+        break;
+       }
+      }
+      while (1) {
+       i14 = i12 + 20 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) != 0) {
+        i12 = i15;
+        i13 = i14;
+        continue;
+       }
+       i14 = i12 + 16 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) == 0) {
+        break;
+       } else {
+        i12 = i15;
+        i13 = i14;
+       }
+      }
+      if (i13 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i13 >> 2] = 0;
+       i9 = i12;
+       break;
+      }
+     } else {
+      i13 = HEAP32[i7 + i8 >> 2] | 0;
+      if (i13 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i14 = i13 + 12 | 0;
+      if ((HEAP32[i14 >> 2] | 0) != (i6 | 0)) {
+       _abort();
+      }
+      i12 = i15 + 8 | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+       HEAP32[i14 >> 2] = i15;
+       HEAP32[i12 >> 2] = i13;
+       i9 = i15;
+       break;
+      } else {
+       _abort();
+      }
+     }
+    } while (0);
+    if ((i10 | 0) != 0) {
+     i12 = HEAP32[i7 + (i8 + 20) >> 2] | 0;
+     i13 = 344 + (i12 << 2) | 0;
+     if ((i6 | 0) == (HEAP32[i13 >> 2] | 0)) {
+      HEAP32[i13 >> 2] = i9;
+      if ((i9 | 0) == 0) {
+       HEAP32[44 >> 2] = HEAP32[44 >> 2] & ~(1 << i12);
+       break;
+      }
+     } else {
+      if (i10 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i12 = i10 + 16 | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+       HEAP32[i12 >> 2] = i9;
+      } else {
+       HEAP32[i10 + 20 >> 2] = i9;
+      }
+      if ((i9 | 0) == 0) {
+       break;
+      }
+     }
+     if (i9 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     HEAP32[i9 + 24 >> 2] = i10;
+     i6 = HEAP32[i7 + (i8 + 8) >> 2] | 0;
+     do {
+      if ((i6 | 0) != 0) {
+       if (i6 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i9 + 16 >> 2] = i6;
+        HEAP32[i6 + 24 >> 2] = i9;
+        break;
+       }
+      }
+     } while (0);
+     i6 = HEAP32[i7 + (i8 + 12) >> 2] | 0;
+     if ((i6 | 0) != 0) {
+      if (i6 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i9 + 20 >> 2] = i6;
+       HEAP32[i6 + 24 >> 2] = i9;
+       break;
+      }
+     }
+    }
+   } else {
+    i9 = HEAP32[i7 + i8 >> 2] | 0;
+    i7 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
+    i8 = 80 + (i12 << 1 << 2) | 0;
+    if ((i9 | 0) != (i8 | 0)) {
+     if (i9 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i9 + 12 >> 2] | 0) != (i6 | 0)) {
+      _abort();
+     }
+    }
+    if ((i7 | 0) == (i9 | 0)) {
+     HEAP32[10] = HEAP32[10] & ~(1 << i12);
+     break;
+    }
+    if ((i7 | 0) != (i8 | 0)) {
+     if (i7 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i8 = i7 + 8 | 0;
+     if ((HEAP32[i8 >> 2] | 0) == (i6 | 0)) {
+      i10 = i8;
+     } else {
+      _abort();
+     }
+    } else {
+     i10 = i7 + 8 | 0;
+    }
+    HEAP32[i9 + 12 >> 2] = i7;
+    HEAP32[i10 >> 2] = i9;
+   }
+  } while (0);
+  HEAP32[i2 + 4 >> 2] = i11 | 1;
+  HEAP32[i2 + i11 >> 2] = i11;
+  if ((i2 | 0) == (HEAP32[60 >> 2] | 0)) {
+   HEAP32[48 >> 2] = i11;
+   STACKTOP = i1;
+   return;
+  }
+ } else {
+  HEAP32[i12 >> 2] = i13 & -2;
+  HEAP32[i2 + 4 >> 2] = i11 | 1;
+  HEAP32[i2 + i11 >> 2] = i11;
+ }
+ i6 = i11 >>> 3;
+ if (i11 >>> 0 < 256) {
+  i7 = i6 << 1;
+  i3 = 80 + (i7 << 2) | 0;
+  i8 = HEAP32[10] | 0;
+  i6 = 1 << i6;
+  if ((i8 & i6 | 0) != 0) {
+   i6 = 80 + (i7 + 2 << 2) | 0;
+   i7 = HEAP32[i6 >> 2] | 0;
+   if (i7 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+    _abort();
+   } else {
+    i4 = i6;
+    i5 = i7;
+   }
+  } else {
+   HEAP32[10] = i8 | i6;
+   i4 = 80 + (i7 + 2 << 2) | 0;
+   i5 = i3;
+  }
+  HEAP32[i4 >> 2] = i2;
+  HEAP32[i5 + 12 >> 2] = i2;
+  HEAP32[i2 + 8 >> 2] = i5;
+  HEAP32[i2 + 12 >> 2] = i3;
+  STACKTOP = i1;
+  return;
+ }
+ i4 = i11 >>> 8;
+ if ((i4 | 0) != 0) {
+  if (i11 >>> 0 > 16777215) {
+   i4 = 31;
+  } else {
+   i20 = (i4 + 1048320 | 0) >>> 16 & 8;
+   i21 = i4 << i20;
+   i19 = (i21 + 520192 | 0) >>> 16 & 4;
+   i21 = i21 << i19;
+   i4 = (i21 + 245760 | 0) >>> 16 & 2;
+   i4 = 14 - (i19 | i20 | i4) + (i21 << i4 >>> 15) | 0;
+   i4 = i11 >>> (i4 + 7 | 0) & 1 | i4 << 1;
+  }
+ } else {
+  i4 = 0;
+ }
+ i5 = 344 + (i4 << 2) | 0;
+ HEAP32[i2 + 28 >> 2] = i4;
+ HEAP32[i2 + 20 >> 2] = 0;
+ HEAP32[i2 + 16 >> 2] = 0;
+ i7 = HEAP32[44 >> 2] | 0;
+ i6 = 1 << i4;
+ L199 : do {
+  if ((i7 & i6 | 0) != 0) {
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((i4 | 0) == 31) {
+    i4 = 0;
+   } else {
+    i4 = 25 - (i4 >>> 1) | 0;
+   }
+   L205 : do {
+    if ((HEAP32[i5 + 4 >> 2] & -8 | 0) != (i11 | 0)) {
+     i4 = i11 << i4;
+     i7 = i5;
+     while (1) {
+      i6 = i7 + (i4 >>> 31 << 2) + 16 | 0;
+      i5 = HEAP32[i6 >> 2] | 0;
+      if ((i5 | 0) == 0) {
+       break;
+      }
+      if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i11 | 0)) {
+       i3 = i5;
+       break L205;
+      } else {
+       i4 = i4 << 1;
+       i7 = i5;
+      }
+     }
+     if (i6 >>> 0 < (HEAP32[56 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i6 >> 2] = i2;
+      HEAP32[i2 + 24 >> 2] = i7;
+      HEAP32[i2 + 12 >> 2] = i2;
+      HEAP32[i2 + 8 >> 2] = i2;
+      break L199;
+     }
+    } else {
+     i3 = i5;
+    }
+   } while (0);
+   i5 = i3 + 8 | 0;
+   i4 = HEAP32[i5 >> 2] | 0;
+   i6 = HEAP32[56 >> 2] | 0;
+   if (i3 >>> 0 < i6 >>> 0) {
+    _abort();
+   }
+   if (i4 >>> 0 < i6 >>> 0) {
+    _abort();
+   } else {
+    HEAP32[i4 + 12 >> 2] = i2;
+    HEAP32[i5 >> 2] = i2;
+    HEAP32[i2 + 8 >> 2] = i4;
+    HEAP32[i2 + 12 >> 2] = i3;
+    HEAP32[i2 + 24 >> 2] = 0;
+    break;
+   }
+  } else {
+   HEAP32[44 >> 2] = i7 | i6;
+   HEAP32[i5 >> 2] = i2;
+   HEAP32[i2 + 24 >> 2] = i5;
+   HEAP32[i2 + 12 >> 2] = i2;
+   HEAP32[i2 + 8 >> 2] = i2;
+  }
+ } while (0);
+ i21 = (HEAP32[72 >> 2] | 0) + -1 | 0;
+ HEAP32[72 >> 2] = i21;
+ if ((i21 | 0) == 0) {
+  i2 = 496 | 0;
+ } else {
+  STACKTOP = i1;
+  return;
+ }
+ while (1) {
+  i2 = HEAP32[i2 >> 2] | 0;
+  if ((i2 | 0) == 0) {
+   break;
+  } else {
+   i2 = i2 + 8 | 0;
+  }
+ }
+ HEAP32[72 >> 2] = -1;
+ STACKTOP = i1;
+ return;
+}
+function _main(i3, i5) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i6 = 0, i7 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i1;
+ L1 : do {
+  if ((i3 | 0) > 1) {
+   i3 = HEAP8[HEAP32[i5 + 4 >> 2] | 0] | 0;
+   switch (i3 | 0) {
+   case 50:
+    {
+     i3 = 400;
+     break L1;
+    }
+   case 51:
+    {
+     i4 = 4;
+     break L1;
+    }
+   case 52:
+    {
+     i3 = 4e3;
+     break L1;
+    }
+   case 53:
+    {
+     i3 = 8e3;
+     break L1;
+    }
+   case 49:
+    {
+     i3 = 55;
+     break L1;
+    }
+   case 48:
+    {
+     i7 = 0;
+     STACKTOP = i1;
+     return i7 | 0;
+    }
+   default:
+    {
+     HEAP32[i2 >> 2] = i3 + -48;
+     _printf(8, i2 | 0) | 0;
+     i7 = -1;
+     STACKTOP = i1;
+     return i7 | 0;
+    }
+   }
+  } else {
+   i4 = 4;
+  }
+ } while (0);
+ if ((i4 | 0) == 4) {
+  i3 = 800;
+ }
+ i5 = _malloc(1048576) | 0;
+ i6 = 0;
+ i4 = 0;
+ do {
+  i7 = 0;
+  while (1) {
+   HEAP8[i5 + i7 | 0] = i7 + i6;
+   i7 = i7 + 1 | 0;
+   if ((i7 | 0) == 1048576) {
+    i7 = 0;
+    break;
+   }
+  }
+  do {
+   i6 = (HEAP8[i5 + i7 | 0] & 1) + i6 | 0;
+   i7 = i7 + 1 | 0;
+  } while ((i7 | 0) != 1048576);
+  i6 = (i6 | 0) % 1e3 | 0;
+  i4 = i4 + 1 | 0;
+ } while ((i4 | 0) < (i3 | 0));
+ HEAP32[i2 >> 2] = i6;
+ _printf(24, i2 | 0) | 0;
+ i7 = 0;
+ STACKTOP = i1;
+ return i7 | 0;
+}
+function _memcpy(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ if ((i1 | 0) >= 4096) return _emscripten_memcpy_big(i3 | 0, i2 | 0, i1 | 0) | 0;
+ i4 = i3 | 0;
+ if ((i3 & 3) == (i2 & 3)) {
+  while (i3 & 3) {
+   if ((i1 | 0) == 0) return i4 | 0;
+   HEAP8[i3] = HEAP8[i2] | 0;
+   i3 = i3 + 1 | 0;
+   i2 = i2 + 1 | 0;
+   i1 = i1 - 1 | 0;
+  }
+  while ((i1 | 0) >= 4) {
+   HEAP32[i3 >> 2] = HEAP32[i2 >> 2];
+   i3 = i3 + 4 | 0;
+   i2 = i2 + 4 | 0;
+   i1 = i1 - 4 | 0;
+  }
+ }
+ while ((i1 | 0) > 0) {
+  HEAP8[i3] = HEAP8[i2] | 0;
+  i3 = i3 + 1 | 0;
+  i2 = i2 + 1 | 0;
+  i1 = i1 - 1 | 0;
+ }
+ return i4 | 0;
+}
+function _memset(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = i1 + i3 | 0;
+ if ((i3 | 0) >= 20) {
+  i4 = i4 & 255;
+  i7 = i1 & 3;
+  i6 = i4 | i4 << 8 | i4 << 16 | i4 << 24;
+  i5 = i2 & ~3;
+  if (i7) {
+   i7 = i1 + 4 - i7 | 0;
+   while ((i1 | 0) < (i7 | 0)) {
+    HEAP8[i1] = i4;
+    i1 = i1 + 1 | 0;
+   }
+  }
+  while ((i1 | 0) < (i5 | 0)) {
+   HEAP32[i1 >> 2] = i6;
+   i1 = i1 + 4 | 0;
+  }
+ }
+ while ((i1 | 0) < (i2 | 0)) {
+  HEAP8[i1] = i4;
+  i1 = i1 + 1 | 0;
+ }
+ return i1 - i3 | 0;
+}
+function copyTempDouble(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+ HEAP8[tempDoublePtr + 4 | 0] = HEAP8[i1 + 4 | 0];
+ HEAP8[tempDoublePtr + 5 | 0] = HEAP8[i1 + 5 | 0];
+ HEAP8[tempDoublePtr + 6 | 0] = HEAP8[i1 + 6 | 0];
+ HEAP8[tempDoublePtr + 7 | 0] = HEAP8[i1 + 7 | 0];
+}
+function copyTempFloat(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+}
+function runPostSets() {}
+function _strlen(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = i1;
+ while (HEAP8[i2] | 0) {
+  i2 = i2 + 1 | 0;
+ }
+ return i2 - i1 | 0;
+}
+function stackAlloc(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + i1 | 0;
+ STACKTOP = STACKTOP + 7 & -8;
+ return i2 | 0;
+}
+function setThrew(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ if ((__THREW__ | 0) == 0) {
+  __THREW__ = i1;
+  threwValue = i2;
+ }
+}
+function stackRestore(i1) {
+ i1 = i1 | 0;
+ STACKTOP = i1;
+}
+function setTempRet9(i1) {
+ i1 = i1 | 0;
+ tempRet9 = i1;
+}
+function setTempRet8(i1) {
+ i1 = i1 | 0;
+ tempRet8 = i1;
+}
+function setTempRet7(i1) {
+ i1 = i1 | 0;
+ tempRet7 = i1;
+}
+function setTempRet6(i1) {
+ i1 = i1 | 0;
+ tempRet6 = i1;
+}
+function setTempRet5(i1) {
+ i1 = i1 | 0;
+ tempRet5 = i1;
+}
+function setTempRet4(i1) {
+ i1 = i1 | 0;
+ tempRet4 = i1;
+}
+function setTempRet3(i1) {
+ i1 = i1 | 0;
+ tempRet3 = i1;
+}
+function setTempRet2(i1) {
+ i1 = i1 | 0;
+ tempRet2 = i1;
+}
+function setTempRet1(i1) {
+ i1 = i1 | 0;
+ tempRet1 = i1;
+}
+function setTempRet0(i1) {
+ i1 = i1 | 0;
+ tempRet0 = i1;
+}
+function stackSave() {
+ return STACKTOP | 0;
+}
+
+// EMSCRIPTEN_END_FUNCS
+
+
+  return { _strlen: _strlen, _free: _free, _main: _main, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, setTempRet1: setTempRet1, setTempRet2: setTempRet2, setTempRet3: setTempRet3, setTempRet4: setTempRet4, setTempRet5: setTempRet5, setTempRet6: setTempRet6, setTempRet7: setTempRet7, setTempRet8: setTempRet8, setTempRet9: setTempRet9 };
+})
+// EMSCRIPTEN_END_ASM
+({ "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array }, { "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "_fflush": _fflush, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_printf": _printf, "_send": _send, "_pwrite": _pwrite, "_abort": _abort, "___setErrNo": ___setErrNo, "_fwrite": _fwrite, "_sbrk": _sbrk, "_time": _time, "_mkport": _mkport, "__reallyNegative": __reallyNegative, "__formatString": __formatString, "_fileno": _fileno, "_write": _write, "_fprintf": _fprintf, "_sysconf": _sysconf, "___errno_location": ___errno_location, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "NaN": NaN, "Infinity": Infinity }, buffer);
+var _strlen = Module["_strlen"] = asm["_strlen"];
+var _free = Module["_free"] = asm["_free"];
+var _main = Module["_main"] = asm["_main"];
+var _memset = Module["_memset"] = asm["_memset"];
+var _malloc = Module["_malloc"] = asm["_malloc"];
+var _memcpy = Module["_memcpy"] = asm["_memcpy"];
+var runPostSets = Module["runPostSets"] = asm["runPostSets"];
+
+Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
+Runtime.stackSave = function() { return asm['stackSave']() };
+Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
+
+
+// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included
+var i64Math = null;
+
+// === Auto-generated postamble setup entry stuff ===
+
+if (memoryInitializer) {
+  if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
+    var data = Module['readBinary'](memoryInitializer);
+    HEAPU8.set(data, STATIC_BASE);
+  } else {
+    addRunDependency('memory initializer');
+    Browser.asyncLoad(memoryInitializer, function(data) {
+      HEAPU8.set(data, STATIC_BASE);
+      removeRunDependency('memory initializer');
+    }, function(data) {
+      throw 'could not load memory initializer ' + memoryInitializer;
+    });
+  }
+}
+
+function ExitStatus(status) {
+  this.name = "ExitStatus";
+  this.message = "Program terminated with exit(" + status + ")";
+  this.status = status;
+};
+ExitStatus.prototype = new Error();
+ExitStatus.prototype.constructor = ExitStatus;
+
+var initialStackTop;
+var preloadStartTime = null;
+var calledMain = false;
+
+dependenciesFulfilled = function runCaller() {
+  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
+  if (!Module['calledRun'] && shouldRunNow) run([].concat(Module["arguments"]));
+  if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
+}
+
+Module['callMain'] = Module.callMain = function callMain(args) {
+  assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
+  assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
+
+  args = args || [];
+
+  ensureInitRuntime();
+
+  var argc = args.length+1;
+  function pad() {
+    for (var i = 0; i < 4-1; i++) {
+      argv.push(0);
+    }
+  }
+  var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ];
+  pad();
+  for (var i = 0; i < argc-1; i = i + 1) {
+    argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL));
+    pad();
+  }
+  argv.push(0);
+  argv = allocate(argv, 'i32', ALLOC_NORMAL);
+
+  initialStackTop = STACKTOP;
+
+  try {
+
+    var ret = Module['_main'](argc, argv, 0);
+
+
+    // if we're not running an evented main loop, it's time to exit
+    if (!Module['noExitRuntime']) {
+      exit(ret);
+    }
+  }
+  catch(e) {
+    if (e instanceof ExitStatus) {
+      // exit() throws this once it's done to make sure execution
+      // has been stopped completely
+      return;
+    } else if (e == 'SimulateInfiniteLoop') {
+      // running an evented main loop, don't immediately exit
+      Module['noExitRuntime'] = true;
+      return;
+    } else {
+      if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
+      throw e;
+    }
+  } finally {
+    calledMain = true;
+  }
+}
+
+
+
+
+function run(args) {
+  args = args || Module['arguments'];
+
+  if (preloadStartTime === null) preloadStartTime = Date.now();
+
+  if (runDependencies > 0) {
+    Module.printErr('run() called, but dependencies remain, so not running');
+    return;
+  }
+
+  preRun();
+
+  if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
+  if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
+
+  function doRun() {
+    if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
+    Module['calledRun'] = true;
+
+    ensureInitRuntime();
+
+    preMain();
+
+    if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
+      Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
+    }
+
+    if (Module['_main'] && shouldRunNow) {
+      Module['callMain'](args);
+    }
+
+    postRun();
+  }
+
+  if (Module['setStatus']) {
+    Module['setStatus']('Running...');
+    setTimeout(function() {
+      setTimeout(function() {
+        Module['setStatus']('');
+      }, 1);
+      if (!ABORT) doRun();
+    }, 1);
+  } else {
+    doRun();
+  }
+}
+Module['run'] = Module.run = run;
+
+function exit(status) {
+  ABORT = true;
+  EXITSTATUS = status;
+  STACKTOP = initialStackTop;
+
+  // exit the runtime
+  exitRuntime();
+
+  // TODO We should handle this differently based on environment.
+  // In the browser, the best we can do is throw an exception
+  // to halt execution, but in node we could process.exit and
+  // I'd imagine SM shell would have something equivalent.
+  // This would let us set a proper exit status (which
+  // would be great for checking test exit statuses).
+  // https://github.com/kripken/emscripten/issues/1371
+
+  // throw an exception to halt the current execution
+  throw new ExitStatus(status);
+}
+Module['exit'] = Module.exit = exit;
+
+function abort(text) {
+  if (text) {
+    Module.print(text);
+    Module.printErr(text);
+  }
+
+  ABORT = true;
+  EXITSTATUS = 1;
+
+  var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.';
+
+  throw 'abort() at ' + stackTrace() + extra;
+}
+Module['abort'] = Module.abort = abort;
+
+// {{PRE_RUN_ADDITIONS}}
+
+if (Module['preInit']) {
+  if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
+  while (Module['preInit'].length > 0) {
+    Module['preInit'].pop()();
+  }
+}
+
+// shouldRunNow refers to calling main(), not run().
+var shouldRunNow = true;
+if (Module['noInitialRun']) {
+  shouldRunNow = false;
+}
+
+
+run([].concat(Module["arguments"]));
diff --git a/test/mjsunit/asm/embenchen/primes.js b/test/mjsunit/asm/embenchen/primes.js
new file mode 100644
index 0000000..32f80b8
--- /dev/null
+++ b/test/mjsunit/asm/embenchen/primes.js
@@ -0,0 +1,5984 @@
+var EXPECTED_OUTPUT = 'lastprime: 387677.\n';
+var Module = {
+  arguments: [1],
+  print: function(x) {Module.printBuffer += x + '\n';},
+  preRun: [function() {Module.printBuffer = ''}],
+  postRun: [function() {
+    assertEquals(EXPECTED_OUTPUT, Module.printBuffer);
+  }],
+};
+// The Module object: Our interface to the outside world. We import
+// and export values on it, and do the work to get that through
+// closure compiler if necessary. There are various ways Module can be used:
+// 1. Not defined. We create it here
+// 2. A function parameter, function(Module) { ..generated code.. }
+// 3. pre-run appended it, var Module = {}; ..generated code..
+// 4. External script tag defines var Module.
+// We need to do an eval in order to handle the closure compiler
+// case, where this code here is minified but Module was defined
+// elsewhere (e.g. case 4 above). We also need to check if Module
+// already exists (e.g. case 3 above).
+// Note that if you want to run closure, and also to use Module
+// after the generated code, you will need to define   var Module = {};
+// before the code. Then that object will be used in the code, and you
+// can continue to use Module afterwards as well.
+var Module;
+if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {};
+
+// Sometimes an existing Module object exists with properties
+// meant to overwrite the default module functionality. Here
+// we collect those properties and reapply _after_ we configure
+// the current environment's defaults to avoid having to be so
+// defensive during initialization.
+var moduleOverrides = {};
+for (var key in Module) {
+  if (Module.hasOwnProperty(key)) {
+    moduleOverrides[key] = Module[key];
+  }
+}
+
+// The environment setup code below is customized to use Module.
+// *** Environment setup code ***
+var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
+var ENVIRONMENT_IS_WEB = typeof window === 'object';
+var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
+var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
+
+if (ENVIRONMENT_IS_NODE) {
+  // Expose functionality in the same simple way that the shells work
+  // Note that we pollute the global namespace here, otherwise we break in node
+  if (!Module['print']) Module['print'] = function print(x) {
+    process['stdout'].write(x + '\n');
+  };
+  if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+    process['stderr'].write(x + '\n');
+  };
+
+  var nodeFS = require('fs');
+  var nodePath = require('path');
+
+  Module['read'] = function read(filename, binary) {
+    filename = nodePath['normalize'](filename);
+    var ret = nodeFS['readFileSync'](filename);
+    // The path is absolute if the normalized version is the same as the resolved.
+    if (!ret && filename != nodePath['resolve'](filename)) {
+      filename = path.join(__dirname, '..', 'src', filename);
+      ret = nodeFS['readFileSync'](filename);
+    }
+    if (ret && !binary) ret = ret.toString();
+    return ret;
+  };
+
+  Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) };
+
+  Module['load'] = function load(f) {
+    globalEval(read(f));
+  };
+
+  Module['arguments'] = process['argv'].slice(2);
+
+  module['exports'] = Module;
+}
+else if (ENVIRONMENT_IS_SHELL) {
+  if (!Module['print']) Module['print'] = print;
+  if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
+
+  if (typeof read != 'undefined') {
+    Module['read'] = read;
+  } else {
+    Module['read'] = function read() { throw 'no read() available (jsc?)' };
+  }
+
+  Module['readBinary'] = function readBinary(f) {
+    return read(f, 'binary');
+  };
+
+  if (typeof scriptArgs != 'undefined') {
+    Module['arguments'] = scriptArgs;
+  } else if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  this['Module'] = Module;
+
+  eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly)
+}
+else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+  Module['read'] = function read(url) {
+    var xhr = new XMLHttpRequest();
+    xhr.open('GET', url, false);
+    xhr.send(null);
+    return xhr.responseText;
+  };
+
+  if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  if (typeof console !== 'undefined') {
+    if (!Module['print']) Module['print'] = function print(x) {
+      console.log(x);
+    };
+    if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+      console.log(x);
+    };
+  } else {
+    // Probably a worker, and without console.log. We can do very little here...
+    var TRY_USE_DUMP = false;
+    if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
+      dump(x);
+    }) : (function(x) {
+      // self.postMessage(x); // enable this if you want stdout to be sent as messages
+    }));
+  }
+
+  if (ENVIRONMENT_IS_WEB) {
+    window['Module'] = Module;
+  } else {
+    Module['load'] = importScripts;
+  }
+}
+else {
+  // Unreachable because SHELL is dependant on the others
+  throw 'Unknown runtime environment. Where are we?';
+}
+
+function globalEval(x) {
+  eval.call(null, x);
+}
+if (!Module['load'] == 'undefined' && Module['read']) {
+  Module['load'] = function load(f) {
+    globalEval(Module['read'](f));
+  };
+}
+if (!Module['print']) {
+  Module['print'] = function(){};
+}
+if (!Module['printErr']) {
+  Module['printErr'] = Module['print'];
+}
+if (!Module['arguments']) {
+  Module['arguments'] = [];
+}
+// *** Environment setup code ***
+
+// Closure helpers
+Module.print = Module['print'];
+Module.printErr = Module['printErr'];
+
+// Callbacks
+Module['preRun'] = [];
+Module['postRun'] = [];
+
+// Merge back in the overrides
+for (var key in moduleOverrides) {
+  if (moduleOverrides.hasOwnProperty(key)) {
+    Module[key] = moduleOverrides[key];
+  }
+}
+
+
+
+// === Auto-generated preamble library stuff ===
+
+//========================================
+// Runtime code shared with compiler
+//========================================
+
+var Runtime = {
+  stackSave: function () {
+    return STACKTOP;
+  },
+  stackRestore: function (stackTop) {
+    STACKTOP = stackTop;
+  },
+  forceAlign: function (target, quantum) {
+    quantum = quantum || 4;
+    if (quantum == 1) return target;
+    if (isNumber(target) && isNumber(quantum)) {
+      return Math.ceil(target/quantum)*quantum;
+    } else if (isNumber(quantum) && isPowerOfTwo(quantum)) {
+      return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')';
+    }
+    return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
+  },
+  isNumberType: function (type) {
+    return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
+  },
+  isPointerType: function isPointerType(type) {
+  return type[type.length-1] == '*';
+},
+  isStructType: function isStructType(type) {
+  if (isPointerType(type)) return false;
+  if (isArrayType(type)) return true;
+  if (/<?\{ ?[^}]* ?\}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types
+  // See comment in isStructPointerType()
+  return type[0] == '%';
+},
+  INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
+  FLOAT_TYPES: {"float":0,"double":0},
+  or64: function (x, y) {
+    var l = (x | 0) | (y | 0);
+    var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  and64: function (x, y) {
+    var l = (x | 0) & (y | 0);
+    var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  xor64: function (x, y) {
+    var l = (x | 0) ^ (y | 0);
+    var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  getNativeTypeSize: function (type) {
+    switch (type) {
+      case 'i1': case 'i8': return 1;
+      case 'i16': return 2;
+      case 'i32': return 4;
+      case 'i64': return 8;
+      case 'float': return 4;
+      case 'double': return 8;
+      default: {
+        if (type[type.length-1] === '*') {
+          return Runtime.QUANTUM_SIZE; // A pointer
+        } else if (type[0] === 'i') {
+          var bits = parseInt(type.substr(1));
+          assert(bits % 8 === 0);
+          return bits/8;
+        } else {
+          return 0;
+        }
+      }
+    }
+  },
+  getNativeFieldSize: function (type) {
+    return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE);
+  },
+  dedup: function dedup(items, ident) {
+  var seen = {};
+  if (ident) {
+    return items.filter(function(item) {
+      if (seen[item[ident]]) return false;
+      seen[item[ident]] = true;
+      return true;
+    });
+  } else {
+    return items.filter(function(item) {
+      if (seen[item]) return false;
+      seen[item] = true;
+      return true;
+    });
+  }
+},
+  set: function set() {
+  var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
+  var ret = {};
+  for (var i = 0; i < args.length; i++) {
+    ret[args[i]] = 0;
+  }
+  return ret;
+},
+  STACK_ALIGN: 8,
+  getAlignSize: function (type, size, vararg) {
+    // we align i64s and doubles on 64-bit boundaries, unlike x86
+    if (!vararg && (type == 'i64' || type == 'double')) return 8;
+    if (!type) return Math.min(size, 8); // align structures internally to 64 bits
+    return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE);
+  },
+  calculateStructAlignment: function calculateStructAlignment(type) {
+    type.flatSize = 0;
+    type.alignSize = 0;
+    var diffs = [];
+    var prev = -1;
+    var index = 0;
+    type.flatIndexes = type.fields.map(function(field) {
+      index++;
+      var size, alignSize;
+      if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
+        size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
+        alignSize = Runtime.getAlignSize(field, size);
+      } else if (Runtime.isStructType(field)) {
+        if (field[1] === '0') {
+          // this is [0 x something]. When inside another structure like here, it must be at the end,
+          // and it adds no size
+          // XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!');
+          size = 0;
+          if (Types.types[field]) {
+            alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+          } else {
+            alignSize = type.alignSize || QUANTUM_SIZE;
+          }
+        } else {
+          size = Types.types[field].flatSize;
+          alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+        }
+      } else if (field[0] == 'b') {
+        // bN, large number field, like a [N x i8]
+        size = field.substr(1)|0;
+        alignSize = 1;
+      } else if (field[0] === '<') {
+        // vector type
+        size = alignSize = Types.types[field].flatSize; // fully aligned
+      } else if (field[0] === 'i') {
+        // illegal integer field, that could not be legalized because it is an internal structure field
+        // it is ok to have such fields, if we just use them as markers of field size and nothing more complex
+        size = alignSize = parseInt(field.substr(1))/8;
+        assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field);
+      } else {
+        assert(false, 'invalid type for calculateStructAlignment');
+      }
+      if (type.packed) alignSize = 1;
+      type.alignSize = Math.max(type.alignSize, alignSize);
+      var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
+      type.flatSize = curr + size;
+      if (prev >= 0) {
+        diffs.push(curr-prev);
+      }
+      prev = curr;
+      return curr;
+    });
+    if (type.name_ && type.name_[0] === '[') {
+      // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
+      // allocating a potentially huge array for [999999 x i8] etc.
+      type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
+    }
+    type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
+    if (diffs.length == 0) {
+      type.flatFactor = type.flatSize;
+    } else if (Runtime.dedup(diffs).length == 1) {
+      type.flatFactor = diffs[0];
+    }
+    type.needsFlattening = (type.flatFactor != 1);
+    return type.flatIndexes;
+  },
+  generateStructInfo: function (struct, typeName, offset) {
+    var type, alignment;
+    if (typeName) {
+      offset = offset || 0;
+      type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
+      if (!type) return null;
+      if (type.fields.length != struct.length) {
+        printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo');
+        return null;
+      }
+      alignment = type.flatIndexes;
+    } else {
+      var type = { fields: struct.map(function(item) { return item[0] }) };
+      alignment = Runtime.calculateStructAlignment(type);
+    }
+    var ret = {
+      __size__: type.flatSize
+    };
+    if (typeName) {
+      struct.forEach(function(item, i) {
+        if (typeof item === 'string') {
+          ret[item] = alignment[i] + offset;
+        } else {
+          // embedded struct
+          var key;
+          for (var k in item) key = k;
+          ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
+        }
+      });
+    } else {
+      struct.forEach(function(item, i) {
+        ret[item[1]] = alignment[i];
+      });
+    }
+    return ret;
+  },
+  dynCall: function (sig, ptr, args) {
+    if (args && args.length) {
+      if (!args.splice) args = Array.prototype.slice.call(args);
+      args.splice(0, 0, ptr);
+      return Module['dynCall_' + sig].apply(null, args);
+    } else {
+      return Module['dynCall_' + sig].call(null, ptr);
+    }
+  },
+  functionPointers: [],
+  addFunction: function (func) {
+    for (var i = 0; i < Runtime.functionPointers.length; i++) {
+      if (!Runtime.functionPointers[i]) {
+        Runtime.functionPointers[i] = func;
+        return 2*(1 + i);
+      }
+    }
+    throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
+  },
+  removeFunction: function (index) {
+    Runtime.functionPointers[(index-2)/2] = null;
+  },
+  getAsmConst: function (code, numArgs) {
+    // code is a constant string on the heap, so we can cache these
+    if (!Runtime.asmConstCache) Runtime.asmConstCache = {};
+    var func = Runtime.asmConstCache[code];
+    if (func) return func;
+    var args = [];
+    for (var i = 0; i < numArgs; i++) {
+      args.push(String.fromCharCode(36) + i); // $0, $1 etc
+    }
+    var source = Pointer_stringify(code);
+    if (source[0] === '"') {
+      // tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct
+      if (source.indexOf('"', 1) === source.length-1) {
+        source = source.substr(1, source.length-2);
+      } else {
+        // something invalid happened, e.g. EM_ASM("..code($0)..", input)
+        abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)');
+      }
+    }
+    try {
+      var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node
+    } catch(e) {
+      Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)');
+      throw e;
+    }
+    return Runtime.asmConstCache[code] = evalled;
+  },
+  warnOnce: function (text) {
+    if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
+    if (!Runtime.warnOnce.shown[text]) {
+      Runtime.warnOnce.shown[text] = 1;
+      Module.printErr(text);
+    }
+  },
+  funcWrappers: {},
+  getFuncWrapper: function (func, sig) {
+    assert(sig);
+    if (!Runtime.funcWrappers[func]) {
+      Runtime.funcWrappers[func] = function dynCall_wrapper() {
+        return Runtime.dynCall(sig, func, arguments);
+      };
+    }
+    return Runtime.funcWrappers[func];
+  },
+  UTF8Processor: function () {
+    var buffer = [];
+    var needed = 0;
+    this.processCChar = function (code) {
+      code = code & 0xFF;
+
+      if (buffer.length == 0) {
+        if ((code & 0x80) == 0x00) {        // 0xxxxxxx
+          return String.fromCharCode(code);
+        }
+        buffer.push(code);
+        if ((code & 0xE0) == 0xC0) {        // 110xxxxx
+          needed = 1;
+        } else if ((code & 0xF0) == 0xE0) { // 1110xxxx
+          needed = 2;
+        } else {                            // 11110xxx
+          needed = 3;
+        }
+        return '';
+      }
+
+      if (needed) {
+        buffer.push(code);
+        needed--;
+        if (needed > 0) return '';
+      }
+
+      var c1 = buffer[0];
+      var c2 = buffer[1];
+      var c3 = buffer[2];
+      var c4 = buffer[3];
+      var ret;
+      if (buffer.length == 2) {
+        ret = String.fromCharCode(((c1 & 0x1F) << 6)  | (c2 & 0x3F));
+      } else if (buffer.length == 3) {
+        ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6)  | (c3 & 0x3F));
+      } else {
+        // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+        var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
+                        ((c3 & 0x3F) << 6)  | (c4 & 0x3F);
+        ret = String.fromCharCode(
+          Math.floor((codePoint - 0x10000) / 0x400) + 0xD800,
+          (codePoint - 0x10000) % 0x400 + 0xDC00);
+      }
+      buffer.length = 0;
+      return ret;
+    }
+    this.processJSString = function processJSString(string) {
+      /* TODO: use TextEncoder when present,
+        var encoder = new TextEncoder();
+        encoder['encoding'] = "utf-8";
+        var utf8Array = encoder['encode'](aMsg.data);
+      */
+      string = unescape(encodeURIComponent(string));
+      var ret = [];
+      for (var i = 0; i < string.length; i++) {
+        ret.push(string.charCodeAt(i));
+      }
+      return ret;
+    }
+  },
+  getCompilerSetting: function (name) {
+    throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work';
+  },
+  stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+7)&-8); return ret; },
+  staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = (((STATICTOP)+7)&-8); return ret; },
+  dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = (((DYNAMICTOP)+7)&-8); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; },
+  alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; },
+  makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*(+4294967296))) : ((+((low>>>0)))+((+((high|0)))*(+4294967296)))); return ret; },
+  GLOBAL_BASE: 8,
+  QUANTUM_SIZE: 4,
+  __dummy__: 0
+}
+
+
+Module['Runtime'] = Runtime;
+
+
+
+
+
+
+
+
+
+//========================================
+// Runtime essentials
+//========================================
+
+var __THREW__ = 0; // Used in checking for thrown exceptions.
+
+var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort()
+var EXITSTATUS = 0;
+
+var undef = 0;
+// tempInt is used for 32-bit signed values or smaller. tempBigInt is used
+// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt
+var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat;
+var tempI64, tempI64b;
+var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9;
+
+function assert(condition, text) {
+  if (!condition) {
+    abort('Assertion failed: ' + text);
+  }
+}
+
+var globalScope = this;
+
+// C calling interface. A convenient way to call C functions (in C files, or
+// defined with extern "C").
+//
+// Note: LLVM optimizations can inline and remove functions, after which you will not be
+//       able to call them. Closure can also do so. To avoid that, add your function to
+//       the exports using something like
+//
+//         -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]'
+//
+// @param ident      The name of the C function (note that C++ functions will be name-mangled - use extern "C")
+// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and
+//                   'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit).
+// @param argTypes   An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType,
+//                   except that 'array' is not possible (there is no way for us to know the length of the array)
+// @param args       An array of the arguments to the function, as native JS values (as in returnType)
+//                   Note that string arguments will be stored on the stack (the JS string will become a C string on the stack).
+// @return           The return value, as a native JS value (as in returnType)
+function ccall(ident, returnType, argTypes, args) {
+  return ccallFunc(getCFunc(ident), returnType, argTypes, args);
+}
+Module["ccall"] = ccall;
+
+// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
+function getCFunc(ident) {
+  try {
+    var func = Module['_' + ident]; // closure exported function
+    if (!func) func = eval('_' + ident); // explicit lookup
+  } catch(e) {
+  }
+  assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)');
+  return func;
+}
+
+// Internal function that does a C call using a function, not an identifier
+function ccallFunc(func, returnType, argTypes, args) {
+  var stack = 0;
+  function toC(value, type) {
+    if (type == 'string') {
+      if (value === null || value === undefined || value === 0) return 0; // null string
+      value = intArrayFromString(value);
+      type = 'array';
+    }
+    if (type == 'array') {
+      if (!stack) stack = Runtime.stackSave();
+      var ret = Runtime.stackAlloc(value.length);
+      writeArrayToMemory(value, ret);
+      return ret;
+    }
+    return value;
+  }
+  function fromC(value, type) {
+    if (type == 'string') {
+      return Pointer_stringify(value);
+    }
+    assert(type != 'array');
+    return value;
+  }
+  var i = 0;
+  var cArgs = args ? args.map(function(arg) {
+    return toC(arg, argTypes[i++]);
+  }) : [];
+  var ret = fromC(func.apply(null, cArgs), returnType);
+  if (stack) Runtime.stackRestore(stack);
+  return ret;
+}
+
+// Returns a native JS wrapper for a C function. This is similar to ccall, but
+// returns a function you can call repeatedly in a normal way. For example:
+//
+//   var my_function = cwrap('my_c_function', 'number', ['number', 'number']);
+//   alert(my_function(5, 22));
+//   alert(my_function(99, 12));
+//
+function cwrap(ident, returnType, argTypes) {
+  var func = getCFunc(ident);
+  return function() {
+    return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments));
+  }
+}
+Module["cwrap"] = cwrap;
+
+// Sets a value in memory in a dynamic way at run-time. Uses the
+// type data. This is the same as makeSetValue, except that
+// makeSetValue is done at compile-time and generates the needed
+// code then, whereas this function picks the right code at
+// run-time.
+// Note that setValue and getValue only do *aligned* writes and reads!
+// Note that ccall uses JS types as for defining types, while setValue and
+// getValue need LLVM types ('i8', 'i32') - this is a lower-level operation
+function setValue(ptr, value, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': HEAP8[(ptr)]=value; break;
+      case 'i8': HEAP8[(ptr)]=value; break;
+      case 'i16': HEAP16[((ptr)>>1)]=value; break;
+      case 'i32': HEAP32[((ptr)>>2)]=value; break;
+      case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= (+1) ? (tempDouble > (+0) ? ((Math_min((+(Math_floor((tempDouble)/(+4294967296)))), (+4294967295)))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/(+4294967296))))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
+      case 'float': HEAPF32[((ptr)>>2)]=value; break;
+      case 'double': HEAPF64[((ptr)>>3)]=value; break;
+      default: abort('invalid type for setValue: ' + type);
+    }
+}
+Module['setValue'] = setValue;
+
+// Parallel to setValue.
+function getValue(ptr, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': return HEAP8[(ptr)];
+      case 'i8': return HEAP8[(ptr)];
+      case 'i16': return HEAP16[((ptr)>>1)];
+      case 'i32': return HEAP32[((ptr)>>2)];
+      case 'i64': return HEAP32[((ptr)>>2)];
+      case 'float': return HEAPF32[((ptr)>>2)];
+      case 'double': return HEAPF64[((ptr)>>3)];
+      default: abort('invalid type for setValue: ' + type);
+    }
+  return null;
+}
+Module['getValue'] = getValue;
+
+var ALLOC_NORMAL = 0; // Tries to use _malloc()
+var ALLOC_STACK = 1; // Lives for the duration of the current function call
+var ALLOC_STATIC = 2; // Cannot be freed
+var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
+var ALLOC_NONE = 4; // Do not allocate
+Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
+Module['ALLOC_STACK'] = ALLOC_STACK;
+Module['ALLOC_STATIC'] = ALLOC_STATIC;
+Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
+Module['ALLOC_NONE'] = ALLOC_NONE;
+
+// allocate(): This is for internal use. You can use it yourself as well, but the interface
+//             is a little tricky (see docs right below). The reason is that it is optimized
+//             for multiple syntaxes to save space in generated code. So you should
+//             normally not use allocate(), and instead allocate memory using _malloc(),
+//             initialize it with setValue(), and so forth.
+// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
+//        in *bytes* (note that this is sometimes confusing: the next parameter does not
+//        affect this!)
+// @types: Either an array of types, one for each byte (or 0 if no type at that position),
+//         or a single type which is used for the entire block. This only matters if there
+//         is initial data - if @slab is a number, then this does not matter at all and is
+//         ignored.
+// @allocator: How to allocate memory, see ALLOC_*
+function allocate(slab, types, allocator, ptr) {
+  var zeroinit, size;
+  if (typeof slab === 'number') {
+    zeroinit = true;
+    size = slab;
+  } else {
+    zeroinit = false;
+    size = slab.length;
+  }
+
+  var singleType = typeof types === 'string' ? types : null;
+
+  var ret;
+  if (allocator == ALLOC_NONE) {
+    ret = ptr;
+  } else {
+    ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
+  }
+
+  if (zeroinit) {
+    var ptr = ret, stop;
+    assert((ret & 3) == 0);
+    stop = ret + (size & ~3);
+    for (; ptr < stop; ptr += 4) {
+      HEAP32[((ptr)>>2)]=0;
+    }
+    stop = ret + size;
+    while (ptr < stop) {
+      HEAP8[((ptr++)|0)]=0;
+    }
+    return ret;
+  }
+
+  if (singleType === 'i8') {
+    if (slab.subarray || slab.slice) {
+      HEAPU8.set(slab, ret);
+    } else {
+      HEAPU8.set(new Uint8Array(slab), ret);
+    }
+    return ret;
+  }
+
+  var i = 0, type, typeSize, previousType;
+  while (i < size) {
+    var curr = slab[i];
+
+    if (typeof curr === 'function') {
+      curr = Runtime.getFunctionIndex(curr);
+    }
+
+    type = singleType || types[i];
+    if (type === 0) {
+      i++;
+      continue;
+    }
+
+    if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
+
+    setValue(ret+i, curr, type);
+
+    // no need to look up size unless type changes, so cache it
+    if (previousType !== type) {
+      typeSize = Runtime.getNativeTypeSize(type);
+      previousType = type;
+    }
+    i += typeSize;
+  }
+
+  return ret;
+}
+Module['allocate'] = allocate;
+
+function Pointer_stringify(ptr, /* optional */ length) {
+  // TODO: use TextDecoder
+  // Find the length, and check for UTF while doing so
+  var hasUtf = false;
+  var t;
+  var i = 0;
+  while (1) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    if (t >= 128) hasUtf = true;
+    else if (t == 0 && !length) break;
+    i++;
+    if (length && i == length) break;
+  }
+  if (!length) length = i;
+
+  var ret = '';
+
+  if (!hasUtf) {
+    var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack
+    var curr;
+    while (length > 0) {
+      curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
+      ret = ret ? ret + curr : curr;
+      ptr += MAX_CHUNK;
+      length -= MAX_CHUNK;
+    }
+    return ret;
+  }
+
+  var utf8 = new Runtime.UTF8Processor();
+  for (i = 0; i < length; i++) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    ret += utf8.processCChar(t);
+  }
+  return ret;
+}
+Module['Pointer_stringify'] = Pointer_stringify;
+
+// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF16ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
+    if (codeUnit == 0)
+      return str;
+    ++i;
+    // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
+    str += String.fromCharCode(codeUnit);
+  }
+}
+Module['UTF16ToString'] = UTF16ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF16LE form. The copy will require at most (str.length*2+1)*2 bytes of space in the HEAP.
+function stringToUTF16(str, outPtr) {
+  for(var i = 0; i < str.length; ++i) {
+    // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
+    var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
+    HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP16[(((outPtr)+(str.length*2))>>1)]=0;
+}
+Module['stringToUTF16'] = stringToUTF16;
+
+// Given a pointer 'ptr' to a null-terminated UTF32LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF32ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
+    if (utf32 == 0)
+      return str;
+    ++i;
+    // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
+    if (utf32 >= 0x10000) {
+      var ch = utf32 - 0x10000;
+      str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
+    } else {
+      str += String.fromCharCode(utf32);
+    }
+  }
+}
+Module['UTF32ToString'] = UTF32ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF32LE form. The copy will require at most (str.length+1)*4 bytes of space in the HEAP,
+// but can use less, since str.length does not return the number of characters in the string, but the number of UTF-16 code units in the string.
+function stringToUTF32(str, outPtr) {
+  var iChar = 0;
+  for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) {
+    // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
+    var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate
+    if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
+      var trailSurrogate = str.charCodeAt(++iCodeUnit);
+      codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
+    }
+    HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit;
+    ++iChar;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP32[(((outPtr)+(iChar*4))>>2)]=0;
+}
+Module['stringToUTF32'] = stringToUTF32;
+
+function demangle(func) {
+  var i = 3;
+  // params, etc.
+  var basicTypes = {
+    'v': 'void',
+    'b': 'bool',
+    'c': 'char',
+    's': 'short',
+    'i': 'int',
+    'l': 'long',
+    'f': 'float',
+    'd': 'double',
+    'w': 'wchar_t',
+    'a': 'signed char',
+    'h': 'unsigned char',
+    't': 'unsigned short',
+    'j': 'unsigned int',
+    'm': 'unsigned long',
+    'x': 'long long',
+    'y': 'unsigned long long',
+    'z': '...'
+  };
+  var subs = [];
+  var first = true;
+  function dump(x) {
+    //return;
+    if (x) Module.print(x);
+    Module.print(func);
+    var pre = '';
+    for (var a = 0; a < i; a++) pre += ' ';
+    Module.print (pre + '^');
+  }
+  function parseNested() {
+    i++;
+    if (func[i] === 'K') i++; // ignore const
+    var parts = [];
+    while (func[i] !== 'E') {
+      if (func[i] === 'S') { // substitution
+        i++;
+        var next = func.indexOf('_', i);
+        var num = func.substring(i, next) || 0;
+        parts.push(subs[num] || '?');
+        i = next+1;
+        continue;
+      }
+      if (func[i] === 'C') { // constructor
+        parts.push(parts[parts.length-1]);
+        i += 2;
+        continue;
+      }
+      var size = parseInt(func.substr(i));
+      var pre = size.toString().length;
+      if (!size || !pre) { i--; break; } // counter i++ below us
+      var curr = func.substr(i + pre, size);
+      parts.push(curr);
+      subs.push(curr);
+      i += pre + size;
+    }
+    i++; // skip E
+    return parts;
+  }
+  function parse(rawList, limit, allowVoid) { // main parser
+    limit = limit || Infinity;
+    var ret = '', list = [];
+    function flushList() {
+      return '(' + list.join(', ') + ')';
+    }
+    var name;
+    if (func[i] === 'N') {
+      // namespaced N-E
+      name = parseNested().join('::');
+      limit--;
+      if (limit === 0) return rawList ? [name] : name;
+    } else {
+      // not namespaced
+      if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L'
+      var size = parseInt(func.substr(i));
+      if (size) {
+        var pre = size.toString().length;
+        name = func.substr(i + pre, size);
+        i += pre + size;
+      }
+    }
+    first = false;
+    if (func[i] === 'I') {
+      i++;
+      var iList = parse(true);
+      var iRet = parse(true, 1, true);
+      ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>';
+    } else {
+      ret = name;
+    }
+    paramLoop: while (i < func.length && limit-- > 0) {
+      //dump('paramLoop');
+      var c = func[i++];
+      if (c in basicTypes) {
+        list.push(basicTypes[c]);
+      } else {
+        switch (c) {
+          case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer
+          case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference
+          case 'L': { // literal
+            i++; // skip basic type
+            var end = func.indexOf('E', i);
+            var size = end - i;
+            list.push(func.substr(i, size));
+            i += size + 2; // size + 'EE'
+            break;
+          }
+          case 'A': { // array
+            var size = parseInt(func.substr(i));
+            i += size.toString().length;
+            if (func[i] !== '_') throw '?';
+            i++; // skip _
+            list.push(parse(true, 1, true)[0] + ' [' + size + ']');
+            break;
+          }
+          case 'E': break paramLoop;
+          default: ret += '?' + c; break paramLoop;
+        }
+      }
+    }
+    if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void)
+    if (rawList) {
+      if (ret) {
+        list.push(ret + '?');
+      }
+      return list;
+    } else {
+      return ret + flushList();
+    }
+  }
+  try {
+    // Special-case the entry point, since its name differs from other name mangling.
+    if (func == 'Object._main' || func == '_main') {
+      return 'main()';
+    }
+    if (typeof func === 'number') func = Pointer_stringify(func);
+    if (func[0] !== '_') return func;
+    if (func[1] !== '_') return func; // C function
+    if (func[2] !== 'Z') return func;
+    switch (func[3]) {
+      case 'n': return 'operator new()';
+      case 'd': return 'operator delete()';
+    }
+    return parse();
+  } catch(e) {
+    return func;
+  }
+}
+
+function demangleAll(text) {
+  return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') });
+}
+
+function stackTrace() {
+  var stack = new Error().stack;
+  return stack ? demangleAll(stack) : '(no stack trace available)'; // Stack trace is not available at least on IE10 and Safari 6.
+}
+
+// Memory management
+
+var PAGE_SIZE = 4096;
+function alignMemoryPage(x) {
+  return (x+4095)&-4096;
+}
+
+var HEAP;
+var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
+
+var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area
+var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area
+var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk
+
+function enlargeMemory() {
+  abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
+}
+
+var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880;
+var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 134217728;
+var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152;
+
+var totalMemory = 4096;
+while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) {
+  if (totalMemory < 16*1024*1024) {
+    totalMemory *= 2;
+  } else {
+    totalMemory += 16*1024*1024
+  }
+}
+if (totalMemory !== TOTAL_MEMORY) {
+  Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be more reasonable');
+  TOTAL_MEMORY = totalMemory;
+}
+
+// Initialize the runtime's memory
+// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
+assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
+       'JS engine does not provide full typed array support');
+
+var buffer = new ArrayBuffer(TOTAL_MEMORY);
+HEAP8 = new Int8Array(buffer);
+HEAP16 = new Int16Array(buffer);
+HEAP32 = new Int32Array(buffer);
+HEAPU8 = new Uint8Array(buffer);
+HEAPU16 = new Uint16Array(buffer);
+HEAPU32 = new Uint32Array(buffer);
+HEAPF32 = new Float32Array(buffer);
+HEAPF64 = new Float64Array(buffer);
+
+// Endianness check (note: assumes compiler arch was little-endian)
+HEAP32[0] = 255;
+assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
+
+Module['HEAP'] = HEAP;
+Module['HEAP8'] = HEAP8;
+Module['HEAP16'] = HEAP16;
+Module['HEAP32'] = HEAP32;
+Module['HEAPU8'] = HEAPU8;
+Module['HEAPU16'] = HEAPU16;
+Module['HEAPU32'] = HEAPU32;
+Module['HEAPF32'] = HEAPF32;
+Module['HEAPF64'] = HEAPF64;
+
+function callRuntimeCallbacks(callbacks) {
+  while(callbacks.length > 0) {
+    var callback = callbacks.shift();
+    if (typeof callback == 'function') {
+      callback();
+      continue;
+    }
+    var func = callback.func;
+    if (typeof func === 'number') {
+      if (callback.arg === undefined) {
+        Runtime.dynCall('v', func);
+      } else {
+        Runtime.dynCall('vi', func, [callback.arg]);
+      }
+    } else {
+      func(callback.arg === undefined ? null : callback.arg);
+    }
+  }
+}
+
+var __ATPRERUN__  = []; // functions called before the runtime is initialized
+var __ATINIT__    = []; // functions called during startup
+var __ATMAIN__    = []; // functions called when main() is to be run
+var __ATEXIT__    = []; // functions called during shutdown
+var __ATPOSTRUN__ = []; // functions called after the runtime has exited
+
+var runtimeInitialized = false;
+
+function preRun() {
+  // compatibility - merge in anything from Module['preRun'] at this time
+  if (Module['preRun']) {
+    if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
+    while (Module['preRun'].length) {
+      addOnPreRun(Module['preRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPRERUN__);
+}
+
+function ensureInitRuntime() {
+  if (runtimeInitialized) return;
+  runtimeInitialized = true;
+  callRuntimeCallbacks(__ATINIT__);
+}
+
+function preMain() {
+  callRuntimeCallbacks(__ATMAIN__);
+}
+
+function exitRuntime() {
+  callRuntimeCallbacks(__ATEXIT__);
+}
+
+function postRun() {
+  // compatibility - merge in anything from Module['postRun'] at this time
+  if (Module['postRun']) {
+    if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
+    while (Module['postRun'].length) {
+      addOnPostRun(Module['postRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPOSTRUN__);
+}
+
+function addOnPreRun(cb) {
+  __ATPRERUN__.unshift(cb);
+}
+Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun;
+
+function addOnInit(cb) {
+  __ATINIT__.unshift(cb);
+}
+Module['addOnInit'] = Module.addOnInit = addOnInit;
+
+function addOnPreMain(cb) {
+  __ATMAIN__.unshift(cb);
+}
+Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain;
+
+function addOnExit(cb) {
+  __ATEXIT__.unshift(cb);
+}
+Module['addOnExit'] = Module.addOnExit = addOnExit;
+
+function addOnPostRun(cb) {
+  __ATPOSTRUN__.unshift(cb);
+}
+Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun;
+
+// Tools
+
+// This processes a JS string into a C-line array of numbers, 0-terminated.
+// For LLVM-originating strings, see parser.js:parseLLVMString function
+function intArrayFromString(stringy, dontAddNull, length /* optional */) {
+  var ret = (new Runtime.UTF8Processor()).processJSString(stringy);
+  if (length) {
+    ret.length = length;
+  }
+  if (!dontAddNull) {
+    ret.push(0);
+  }
+  return ret;
+}
+Module['intArrayFromString'] = intArrayFromString;
+
+function intArrayToString(array) {
+  var ret = [];
+  for (var i = 0; i < array.length; i++) {
+    var chr = array[i];
+    if (chr > 0xFF) {
+      chr &= 0xFF;
+    }
+    ret.push(String.fromCharCode(chr));
+  }
+  return ret.join('');
+}
+Module['intArrayToString'] = intArrayToString;
+
+// Write a Javascript array to somewhere in the heap
+function writeStringToMemory(string, buffer, dontAddNull) {
+  var array = intArrayFromString(string, dontAddNull);
+  var i = 0;
+  while (i < array.length) {
+    var chr = array[i];
+    HEAP8[(((buffer)+(i))|0)]=chr;
+    i = i + 1;
+  }
+}
+Module['writeStringToMemory'] = writeStringToMemory;
+
+function writeArrayToMemory(array, buffer) {
+  for (var i = 0; i < array.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=array[i];
+  }
+}
+Module['writeArrayToMemory'] = writeArrayToMemory;
+
+function writeAsciiToMemory(str, buffer, dontAddNull) {
+  for (var i = 0; i < str.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=str.charCodeAt(i);
+  }
+  if (!dontAddNull) HEAP8[(((buffer)+(str.length))|0)]=0;
+}
+Module['writeAsciiToMemory'] = writeAsciiToMemory;
+
+function unSign(value, bits, ignore) {
+  if (value >= 0) {
+    return value;
+  }
+  return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
+                    : Math.pow(2, bits)         + value;
+}
+function reSign(value, bits, ignore) {
+  if (value <= 0) {
+    return value;
+  }
+  var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
+                        : Math.pow(2, bits-1);
+  if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
+                                                       // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
+                                                       // TODO: In i64 mode 1, resign the two parts separately and safely
+    value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
+  }
+  return value;
+}
+
+// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
+if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) {
+  var ah  = a >>> 16;
+  var al = a & 0xffff;
+  var bh  = b >>> 16;
+  var bl = b & 0xffff;
+  return (al*bl + ((ah*bl + al*bh) << 16))|0;
+};
+Math.imul = Math['imul'];
+
+
+var Math_abs = Math.abs;
+var Math_cos = Math.cos;
+var Math_sin = Math.sin;
+var Math_tan = Math.tan;
+var Math_acos = Math.acos;
+var Math_asin = Math.asin;
+var Math_atan = Math.atan;
+var Math_atan2 = Math.atan2;
+var Math_exp = Math.exp;
+var Math_log = Math.log;
+var Math_sqrt = Math.sqrt;
+var Math_ceil = Math.ceil;
+var Math_floor = Math.floor;
+var Math_pow = Math.pow;
+var Math_imul = Math.imul;
+var Math_fround = Math.fround;
+var Math_min = Math.min;
+
+// A counter of dependencies for calling run(). If we need to
+// do asynchronous work before running, increment this and
+// decrement it. Incrementing must happen in a place like
+// PRE_RUN_ADDITIONS (used by emcc to add file preloading).
+// Note that you can add dependencies in preRun, even though
+// it happens right before run - run will be postponed until
+// the dependencies are met.
+var runDependencies = 0;
+var runDependencyWatcher = null;
+var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
+
+function addRunDependency(id) {
+  runDependencies++;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+}
+Module['addRunDependency'] = addRunDependency;
+function removeRunDependency(id) {
+  runDependencies--;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+  if (runDependencies == 0) {
+    if (runDependencyWatcher !== null) {
+      clearInterval(runDependencyWatcher);
+      runDependencyWatcher = null;
+    }
+    if (dependenciesFulfilled) {
+      var callback = dependenciesFulfilled;
+      dependenciesFulfilled = null;
+      callback(); // can add another dependenciesFulfilled
+    }
+  }
+}
+Module['removeRunDependency'] = removeRunDependency;
+
+Module["preloadedImages"] = {}; // maps url to image data
+Module["preloadedAudios"] = {}; // maps url to audio data
+
+
+var memoryInitializer = null;
+
+// === Body ===
+
+
+
+
+
+STATIC_BASE = 8;
+
+STATICTOP = STATIC_BASE + Runtime.alignMemory(35);
+/* global initializers */ __ATINIT__.push();
+
+
+/* memory initializer */ allocate([101,114,114,111,114,58,32,37,100,92,110,0,0,0,0,0,108,97,115,116,112,114,105,109,101,58,32,37,100,46,10,0], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE);
+
+
+
+
+var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);
+
+assert(tempDoublePtr % 8 == 0);
+
+function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+}
+
+function copyTempDouble(ptr) {
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+  HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];
+
+  HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];
+
+  HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];
+
+  HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];
+
+}
+
+
+  function _malloc(bytes) {
+      /* Over-allocate to make sure it is byte-aligned by 8.
+       * This will leak memory, but this is only the dummy
+       * implementation (replaced by dlmalloc normally) so
+       * not an issue.
+       */
+      var ptr = Runtime.dynamicAlloc(bytes + 8);
+      return (ptr+8) & 0xFFFFFFF8;
+    }
+  Module["_malloc"] = _malloc;
+
+
+  Module["_memset"] = _memset;
+
+  function _free() {
+  }
+  Module["_free"] = _free;
+
+
+  function _emscripten_memcpy_big(dest, src, num) {
+      HEAPU8.set(HEAPU8.subarray(src, src+num), dest);
+      return dest;
+    }
+  Module["_memcpy"] = _memcpy;
+
+
+
+
+  var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};
+
+  var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can   access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};
+
+
+  var ___errno_state=0;function ___setErrNo(value) {
+      // For convenient setting and returning of errno.
+      HEAP32[((___errno_state)>>2)]=value;
+      return value;
+    }
+
+  var TTY={ttys:[],init:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // currently, FS.init does not distinguish if process.stdin is a file or TTY
+        //   // device, it always assumes it's a TTY device. because of this, we're forcing
+        //   // process.stdin to UTF8 encoding to at least make stdin reading compatible
+        //   // with text files until FS.init can be refactored.
+        //   process['stdin']['setEncoding']('utf8');
+        // }
+      },shutdown:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
+        //   // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
+        //   // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
+        //   // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
+        //   // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
+        //   process['stdin']['pause']();
+        // }
+      },register:function (dev, ops) {
+        TTY.ttys[dev] = { input: [], output: [], ops: ops };
+        FS.registerDevice(dev, TTY.stream_ops);
+      },stream_ops:{open:function (stream) {
+          var tty = TTY.ttys[stream.node.rdev];
+          if (!tty) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          stream.tty = tty;
+          stream.seekable = false;
+        },close:function (stream) {
+          // flush any pending line data
+          if (stream.tty.output.length) {
+            stream.tty.ops.put_char(stream.tty, 10);
+          }
+        },read:function (stream, buffer, offset, length, pos /* ignored */) {
+          if (!stream.tty || !stream.tty.ops.get_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          var bytesRead = 0;
+          for (var i = 0; i < length; i++) {
+            var result;
+            try {
+              result = stream.tty.ops.get_char(stream.tty);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            if (result === undefined && bytesRead === 0) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+            if (result === null || result === undefined) break;
+            bytesRead++;
+            buffer[offset+i] = result;
+          }
+          if (bytesRead) {
+            stream.node.timestamp = Date.now();
+          }
+          return bytesRead;
+        },write:function (stream, buffer, offset, length, pos) {
+          if (!stream.tty || !stream.tty.ops.put_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          for (var i = 0; i < length; i++) {
+            try {
+              stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+          }
+          if (length) {
+            stream.node.timestamp = Date.now();
+          }
+          return i;
+        }},default_tty_ops:{get_char:function (tty) {
+          if (!tty.input.length) {
+            var result = null;
+            if (ENVIRONMENT_IS_NODE) {
+              result = process['stdin']['read']();
+              if (!result) {
+                if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) {
+                  return null;  // EOF
+                }
+                return undefined;  // no data available
+              }
+            } else if (typeof window != 'undefined' &&
+              typeof window.prompt == 'function') {
+              // Browser.
+              result = window.prompt('Input: ');  // returns null on cancel
+              if (result !== null) {
+                result += '\n';
+              }
+            } else if (typeof readline == 'function') {
+              // Command line.
+              result = readline();
+              if (result !== null) {
+                result += '\n';
+              }
+            }
+            if (!result) {
+              return null;
+            }
+            tty.input = intArrayFromString(result, true);
+          }
+          return tty.input.shift();
+        },put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['print'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }},default_tty1_ops:{put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['printErr'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }}};
+
+  var MEMFS={ops_table:null,CONTENT_OWNING:1,CONTENT_FLEXIBLE:2,CONTENT_FIXED:3,mount:function (mount) {
+        return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
+          // no supported
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (!MEMFS.ops_table) {
+          MEMFS.ops_table = {
+            dir: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                lookup: MEMFS.node_ops.lookup,
+                mknod: MEMFS.node_ops.mknod,
+                rename: MEMFS.node_ops.rename,
+                unlink: MEMFS.node_ops.unlink,
+                rmdir: MEMFS.node_ops.rmdir,
+                readdir: MEMFS.node_ops.readdir,
+                symlink: MEMFS.node_ops.symlink
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek
+              }
+            },
+            file: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek,
+                read: MEMFS.stream_ops.read,
+                write: MEMFS.stream_ops.write,
+                allocate: MEMFS.stream_ops.allocate,
+                mmap: MEMFS.stream_ops.mmap
+              }
+            },
+            link: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                readlink: MEMFS.node_ops.readlink
+              },
+              stream: {}
+            },
+            chrdev: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: FS.chrdev_stream_ops
+            },
+          };
+        }
+        var node = FS.createNode(parent, name, mode, dev);
+        if (FS.isDir(node.mode)) {
+          node.node_ops = MEMFS.ops_table.dir.node;
+          node.stream_ops = MEMFS.ops_table.dir.stream;
+          node.contents = {};
+        } else if (FS.isFile(node.mode)) {
+          node.node_ops = MEMFS.ops_table.file.node;
+          node.stream_ops = MEMFS.ops_table.file.stream;
+          node.contents = [];
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        } else if (FS.isLink(node.mode)) {
+          node.node_ops = MEMFS.ops_table.link.node;
+          node.stream_ops = MEMFS.ops_table.link.stream;
+        } else if (FS.isChrdev(node.mode)) {
+          node.node_ops = MEMFS.ops_table.chrdev.node;
+          node.stream_ops = MEMFS.ops_table.chrdev.stream;
+        }
+        node.timestamp = Date.now();
+        // add the new node to the parent
+        if (parent) {
+          parent.contents[name] = node;
+        }
+        return node;
+      },ensureFlexible:function (node) {
+        if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
+          var contents = node.contents;
+          node.contents = Array.prototype.slice.call(contents);
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        }
+      },node_ops:{getattr:function (node) {
+          var attr = {};
+          // device numbers reuse inode numbers.
+          attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
+          attr.ino = node.id;
+          attr.mode = node.mode;
+          attr.nlink = 1;
+          attr.uid = 0;
+          attr.gid = 0;
+          attr.rdev = node.rdev;
+          if (FS.isDir(node.mode)) {
+            attr.size = 4096;
+          } else if (FS.isFile(node.mode)) {
+            attr.size = node.contents.length;
+          } else if (FS.isLink(node.mode)) {
+            attr.size = node.link.length;
+          } else {
+            attr.size = 0;
+          }
+          attr.atime = new Date(node.timestamp);
+          attr.mtime = new Date(node.timestamp);
+          attr.ctime = new Date(node.timestamp);
+          // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
+          //       but this is not required by the standard.
+          attr.blksize = 4096;
+          attr.blocks = Math.ceil(attr.size / attr.blksize);
+          return attr;
+        },setattr:function (node, attr) {
+          if (attr.mode !== undefined) {
+            node.mode = attr.mode;
+          }
+          if (attr.timestamp !== undefined) {
+            node.timestamp = attr.timestamp;
+          }
+          if (attr.size !== undefined) {
+            MEMFS.ensureFlexible(node);
+            var contents = node.contents;
+            if (attr.size < contents.length) contents.length = attr.size;
+            else while (attr.size > contents.length) contents.push(0);
+          }
+        },lookup:function (parent, name) {
+          throw FS.genericErrors[ERRNO_CODES.ENOENT];
+        },mknod:function (parent, name, mode, dev) {
+          return MEMFS.createNode(parent, name, mode, dev);
+        },rename:function (old_node, new_dir, new_name) {
+          // if we're overwriting a directory at new_name, make sure it's empty.
+          if (FS.isDir(old_node.mode)) {
+            var new_node;
+            try {
+              new_node = FS.lookupNode(new_dir, new_name);
+            } catch (e) {
+            }
+            if (new_node) {
+              for (var i in new_node.contents) {
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+              }
+            }
+          }
+          // do the internal rewiring
+          delete old_node.parent.contents[old_node.name];
+          old_node.name = new_name;
+          new_dir.contents[new_name] = old_node;
+          old_node.parent = new_dir;
+        },unlink:function (parent, name) {
+          delete parent.contents[name];
+        },rmdir:function (parent, name) {
+          var node = FS.lookupNode(parent, name);
+          for (var i in node.contents) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+          }
+          delete parent.contents[name];
+        },readdir:function (node) {
+          var entries = ['.', '..']
+          for (var key in node.contents) {
+            if (!node.contents.hasOwnProperty(key)) {
+              continue;
+            }
+            entries.push(key);
+          }
+          return entries;
+        },symlink:function (parent, newname, oldpath) {
+          var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
+          node.link = oldpath;
+          return node;
+        },readlink:function (node) {
+          if (!FS.isLink(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          return node.link;
+        }},stream_ops:{read:function (stream, buffer, offset, length, position) {
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (size > 8 && contents.subarray) { // non-trivial, and typed array
+            buffer.set(contents.subarray(position, position + size), offset);
+          } else
+          {
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          }
+          return size;
+        },write:function (stream, buffer, offset, length, position, canOwn) {
+          var node = stream.node;
+          node.timestamp = Date.now();
+          var contents = node.contents;
+          if (length && contents.length === 0 && position === 0 && buffer.subarray) {
+            // just replace it with the new data
+            if (canOwn && offset === 0) {
+              node.contents = buffer; // this could be a subarray of Emscripten HEAP, or allocated from some other source.
+              node.contentMode = (buffer.buffer === HEAP8.buffer) ? MEMFS.CONTENT_OWNING : MEMFS.CONTENT_FIXED;
+            } else {
+              node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
+              node.contentMode = MEMFS.CONTENT_FIXED;
+            }
+            return length;
+          }
+          MEMFS.ensureFlexible(node);
+          var contents = node.contents;
+          while (contents.length < position) contents.push(0);
+          for (var i = 0; i < length; i++) {
+            contents[position + i] = buffer[offset + i];
+          }
+          return length;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              position += stream.node.contents.length;
+            }
+          }
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          stream.ungotten = [];
+          stream.position = position;
+          return position;
+        },allocate:function (stream, offset, length) {
+          MEMFS.ensureFlexible(stream.node);
+          var contents = stream.node.contents;
+          var limit = offset + length;
+          while (limit > contents.length) contents.push(0);
+        },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+          if (!FS.isFile(stream.node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          var ptr;
+          var allocated;
+          var contents = stream.node.contents;
+          // Only make a new copy when MAP_PRIVATE is specified.
+          if ( !(flags & 2) &&
+                (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
+            // We can't emulate MAP_SHARED when the file is not backed by the buffer
+            // we're mapping to (e.g. the HEAP buffer).
+            allocated = false;
+            ptr = contents.byteOffset;
+          } else {
+            // Try to avoid unnecessary slices.
+            if (position > 0 || position + length < contents.length) {
+              if (contents.subarray) {
+                contents = contents.subarray(position, position + length);
+              } else {
+                contents = Array.prototype.slice.call(contents, position, position + length);
+              }
+            }
+            allocated = true;
+            ptr = _malloc(length);
+            if (!ptr) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOMEM);
+            }
+            buffer.set(contents, ptr);
+          }
+          return { ptr: ptr, allocated: allocated };
+        }}};
+
+  var IDBFS={dbs:{},indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) {
+        // reuse all of the core MEMFS functionality
+        return MEMFS.mount.apply(null, arguments);
+      },syncfs:function (mount, populate, callback) {
+        IDBFS.getLocalSet(mount, function(err, local) {
+          if (err) return callback(err);
+
+          IDBFS.getRemoteSet(mount, function(err, remote) {
+            if (err) return callback(err);
+
+            var src = populate ? remote : local;
+            var dst = populate ? local : remote;
+
+            IDBFS.reconcile(src, dst, callback);
+          });
+        });
+      },getDB:function (name, callback) {
+        // check the cache first
+        var db = IDBFS.dbs[name];
+        if (db) {
+          return callback(null, db);
+        }
+
+        var req;
+        try {
+          req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
+        } catch (e) {
+          return callback(e);
+        }
+        req.onupgradeneeded = function(e) {
+          var db = e.target.result;
+          var transaction = e.target.transaction;
+
+          var fileStore;
+
+          if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
+            fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          } else {
+            fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
+          }
+
+          fileStore.createIndex('timestamp', 'timestamp', { unique: false });
+        };
+        req.onsuccess = function() {
+          db = req.result;
+
+          // add to the cache
+          IDBFS.dbs[name] = db;
+          callback(null, db);
+        };
+        req.onerror = function() {
+          callback(this.error);
+        };
+      },getLocalSet:function (mount, callback) {
+        var entries = {};
+
+        function isRealDir(p) {
+          return p !== '.' && p !== '..';
+        };
+        function toAbsolute(root) {
+          return function(p) {
+            return PATH.join2(root, p);
+          }
+        };
+
+        var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
+
+        while (check.length) {
+          var path = check.pop();
+          var stat;
+
+          try {
+            stat = FS.stat(path);
+          } catch (e) {
+            return callback(e);
+          }
+
+          if (FS.isDir(stat.mode)) {
+            check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
+          }
+
+          entries[path] = { timestamp: stat.mtime };
+        }
+
+        return callback(null, { type: 'local', entries: entries });
+      },getRemoteSet:function (mount, callback) {
+        var entries = {};
+
+        IDBFS.getDB(mount.mountpoint, function(err, db) {
+          if (err) return callback(err);
+
+          var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly');
+          transaction.onerror = function() { callback(this.error); };
+
+          var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          var index = store.index('timestamp');
+
+          index.openKeyCursor().onsuccess = function(event) {
+            var cursor = event.target.result;
+
+            if (!cursor) {
+              return callback(null, { type: 'remote', db: db, entries: entries });
+            }
+
+            entries[cursor.primaryKey] = { timestamp: cursor.key };
+
+            cursor.continue();
+          };
+        });
+      },loadLocalEntry:function (path, callback) {
+        var stat, node;
+
+        try {
+          var lookup = FS.lookupPath(path);
+          node = lookup.node;
+          stat = FS.stat(path);
+        } catch (e) {
+          return callback(e);
+        }
+
+        if (FS.isDir(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode });
+        } else if (FS.isFile(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents });
+        } else {
+          return callback(new Error('node type not supported'));
+        }
+      },storeLocalEntry:function (path, entry, callback) {
+        try {
+          if (FS.isDir(entry.mode)) {
+            FS.mkdir(path, entry.mode);
+          } else if (FS.isFile(entry.mode)) {
+            FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true });
+          } else {
+            return callback(new Error('node type not supported'));
+          }
+
+          FS.utime(path, entry.timestamp, entry.timestamp);
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },removeLocalEntry:function (path, callback) {
+        try {
+          var lookup = FS.lookupPath(path);
+          var stat = FS.stat(path);
+
+          if (FS.isDir(stat.mode)) {
+            FS.rmdir(path);
+          } else if (FS.isFile(stat.mode)) {
+            FS.unlink(path);
+          }
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },loadRemoteEntry:function (store, path, callback) {
+        var req = store.get(path);
+        req.onsuccess = function(event) { callback(null, event.target.result); };
+        req.onerror = function() { callback(this.error); };
+      },storeRemoteEntry:function (store, path, entry, callback) {
+        var req = store.put(entry, path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },removeRemoteEntry:function (store, path, callback) {
+        var req = store.delete(path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },reconcile:function (src, dst, callback) {
+        var total = 0;
+
+        var create = [];
+        Object.keys(src.entries).forEach(function (key) {
+          var e = src.entries[key];
+          var e2 = dst.entries[key];
+          if (!e2 || e.timestamp > e2.timestamp) {
+            create.push(key);
+            total++;
+          }
+        });
+
+        var remove = [];
+        Object.keys(dst.entries).forEach(function (key) {
+          var e = dst.entries[key];
+          var e2 = src.entries[key];
+          if (!e2) {
+            remove.push(key);
+            total++;
+          }
+        });
+
+        if (!total) {
+          return callback(null);
+        }
+
+        var errored = false;
+        var completed = 0;
+        var db = src.type === 'remote' ? src.db : dst.db;
+        var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
+        var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= total) {
+            return callback(null);
+          }
+        };
+
+        transaction.onerror = function() { done(this.error); };
+
+        // sort paths in ascending order so directory entries are created
+        // before the files inside them
+        create.sort().forEach(function (path) {
+          if (dst.type === 'local') {
+            IDBFS.loadRemoteEntry(store, path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeLocalEntry(path, entry, done);
+            });
+          } else {
+            IDBFS.loadLocalEntry(path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeRemoteEntry(store, path, entry, done);
+            });
+          }
+        });
+
+        // sort paths in descending order so files are deleted before their
+        // parent directories
+        remove.sort().reverse().forEach(function(path) {
+          if (dst.type === 'local') {
+            IDBFS.removeLocalEntry(path, done);
+          } else {
+            IDBFS.removeRemoteEntry(store, path, done);
+          }
+        });
+      }};
+
+  var NODEFS={isWindows:false,staticInit:function () {
+        NODEFS.isWindows = !!process.platform.match(/^win/);
+      },mount:function (mount) {
+        assert(ENVIRONMENT_IS_NODE);
+        return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node = FS.createNode(parent, name, mode);
+        node.node_ops = NODEFS.node_ops;
+        node.stream_ops = NODEFS.stream_ops;
+        return node;
+      },getMode:function (path) {
+        var stat;
+        try {
+          stat = fs.lstatSync(path);
+          if (NODEFS.isWindows) {
+            // On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so
+            // propagate write bits to execute bits.
+            stat.mode = stat.mode | ((stat.mode & 146) >> 1);
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        return stat.mode;
+      },realPath:function (node) {
+        var parts = [];
+        while (node.parent !== node) {
+          parts.push(node.name);
+          node = node.parent;
+        }
+        parts.push(node.mount.opts.root);
+        parts.reverse();
+        return PATH.join.apply(null, parts);
+      },flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) {
+        if (flags in NODEFS.flagsToPermissionStringMap) {
+          return NODEFS.flagsToPermissionStringMap[flags];
+        } else {
+          return flags;
+        }
+      },node_ops:{getattr:function (node) {
+          var path = NODEFS.realPath(node);
+          var stat;
+          try {
+            stat = fs.lstatSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096.
+          // See http://support.microsoft.com/kb/140365
+          if (NODEFS.isWindows && !stat.blksize) {
+            stat.blksize = 4096;
+          }
+          if (NODEFS.isWindows && !stat.blocks) {
+            stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0;
+          }
+          return {
+            dev: stat.dev,
+            ino: stat.ino,
+            mode: stat.mode,
+            nlink: stat.nlink,
+            uid: stat.uid,
+            gid: stat.gid,
+            rdev: stat.rdev,
+            size: stat.size,
+            atime: stat.atime,
+            mtime: stat.mtime,
+            ctime: stat.ctime,
+            blksize: stat.blksize,
+            blocks: stat.blocks
+          };
+        },setattr:function (node, attr) {
+          var path = NODEFS.realPath(node);
+          try {
+            if (attr.mode !== undefined) {
+              fs.chmodSync(path, attr.mode);
+              // update the common node structure mode as well
+              node.mode = attr.mode;
+            }
+            if (attr.timestamp !== undefined) {
+              var date = new Date(attr.timestamp);
+              fs.utimesSync(path, date, date);
+            }
+            if (attr.size !== undefined) {
+              fs.truncateSync(path, attr.size);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },lookup:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          var mode = NODEFS.getMode(path);
+          return NODEFS.createNode(parent, name, mode);
+        },mknod:function (parent, name, mode, dev) {
+          var node = NODEFS.createNode(parent, name, mode, dev);
+          // create the backing node for this in the fs root as well
+          var path = NODEFS.realPath(node);
+          try {
+            if (FS.isDir(node.mode)) {
+              fs.mkdirSync(path, node.mode);
+            } else {
+              fs.writeFileSync(path, '', { mode: node.mode });
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return node;
+        },rename:function (oldNode, newDir, newName) {
+          var oldPath = NODEFS.realPath(oldNode);
+          var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
+          try {
+            fs.renameSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },unlink:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.unlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },rmdir:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.rmdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readdir:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },symlink:function (parent, newName, oldPath) {
+          var newPath = PATH.join2(NODEFS.realPath(parent), newName);
+          try {
+            fs.symlinkSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readlink:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        }},stream_ops:{open:function (stream) {
+          var path = NODEFS.realPath(stream.node);
+          try {
+            if (FS.isFile(stream.node.mode)) {
+              stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags));
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },close:function (stream) {
+          try {
+            if (FS.isFile(stream.node.mode) && stream.nfd) {
+              fs.closeSync(stream.nfd);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },read:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(length);
+          var res;
+          try {
+            res = fs.readSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          if (res > 0) {
+            for (var i = 0; i < res; i++) {
+              buffer[offset + i] = nbuffer[i];
+            }
+          }
+          return res;
+        },write:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(buffer.subarray(offset, offset + length));
+          var res;
+          try {
+            res = fs.writeSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return res;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              try {
+                var stat = fs.fstatSync(stream.nfd);
+                position += stat.size;
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+              }
+            }
+          }
+
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+
+          stream.position = position;
+          return position;
+        }}};
+
+  var _stdin=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stdout=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stderr=allocate(1, "i32*", ALLOC_STATIC);
+
+  function _fflush(stream) {
+      // int fflush(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html
+      // we don't currently perform any user-space buffering of data
+    }var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},handleFSError:function (e) {
+        if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
+        return ___setErrNo(e.errno);
+      },lookupPath:function (path, opts) {
+        path = PATH.resolve(FS.cwd(), path);
+        opts = opts || {};
+
+        var defaults = {
+          follow_mount: true,
+          recurse_count: 0
+        };
+        for (var key in defaults) {
+          if (opts[key] === undefined) {
+            opts[key] = defaults[key];
+          }
+        }
+
+        if (opts.recurse_count > 8) {  // max recursive lookup of 8
+          throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+        }
+
+        // split the path
+        var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), false);
+
+        // start at the root
+        var current = FS.root;
+        var current_path = '/';
+
+        for (var i = 0; i < parts.length; i++) {
+          var islast = (i === parts.length-1);
+          if (islast && opts.parent) {
+            // stop resolving
+            break;
+          }
+
+          current = FS.lookupNode(current, parts[i]);
+          current_path = PATH.join2(current_path, parts[i]);
+
+          // jump to the mount's root node if this is a mountpoint
+          if (FS.isMountpoint(current)) {
+            if (!islast || (islast && opts.follow_mount)) {
+              current = current.mounted.root;
+            }
+          }
+
+          // by default, lookupPath will not follow a symlink if it is the final path component.
+          // setting opts.follow = true will override this behavior.
+          if (!islast || opts.follow) {
+            var count = 0;
+            while (FS.isLink(current.mode)) {
+              var link = FS.readlink(current_path);
+              current_path = PATH.resolve(PATH.dirname(current_path), link);
+
+              var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
+              current = lookup.node;
+
+              if (count++ > 40) {  // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
+                throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+              }
+            }
+          }
+        }
+
+        return { path: current_path, node: current };
+      },getPath:function (node) {
+        var path;
+        while (true) {
+          if (FS.isRoot(node)) {
+            var mount = node.mount.mountpoint;
+            if (!path) return mount;
+            return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
+          }
+          path = path ? node.name + '/' + path : node.name;
+          node = node.parent;
+        }
+      },hashName:function (parentid, name) {
+        var hash = 0;
+
+
+        for (var i = 0; i < name.length; i++) {
+          hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
+        }
+        return ((parentid + hash) >>> 0) % FS.nameTable.length;
+      },hashAddNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        node.name_next = FS.nameTable[hash];
+        FS.nameTable[hash] = node;
+      },hashRemoveNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        if (FS.nameTable[hash] === node) {
+          FS.nameTable[hash] = node.name_next;
+        } else {
+          var current = FS.nameTable[hash];
+          while (current) {
+            if (current.name_next === node) {
+              current.name_next = node.name_next;
+              break;
+            }
+            current = current.name_next;
+          }
+        }
+      },lookupNode:function (parent, name) {
+        var err = FS.mayLookup(parent);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        var hash = FS.hashName(parent.id, name);
+        for (var node = FS.nameTable[hash]; node; node = node.name_next) {
+          var nodeName = node.name;
+          if (node.parent.id === parent.id && nodeName === name) {
+            return node;
+          }
+        }
+        // if we failed to find it in the cache, call into the VFS
+        return FS.lookup(parent, name);
+      },createNode:function (parent, name, mode, rdev) {
+        if (!FS.FSNode) {
+          FS.FSNode = function(parent, name, mode, rdev) {
+            if (!parent) {
+              parent = this;  // root node sets parent to itself
+            }
+            this.parent = parent;
+            this.mount = parent.mount;
+            this.mounted = null;
+            this.id = FS.nextInode++;
+            this.name = name;
+            this.mode = mode;
+            this.node_ops = {};
+            this.stream_ops = {};
+            this.rdev = rdev;
+          };
+
+          FS.FSNode.prototype = {};
+
+          // compatibility
+          var readMode = 292 | 73;
+          var writeMode = 146;
+
+          // NOTE we must use Object.defineProperties instead of individual calls to
+          // Object.defineProperty in order to make closure compiler happy
+          Object.defineProperties(FS.FSNode.prototype, {
+            read: {
+              get: function() { return (this.mode & readMode) === readMode; },
+              set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; }
+            },
+            write: {
+              get: function() { return (this.mode & writeMode) === writeMode; },
+              set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; }
+            },
+            isFolder: {
+              get: function() { return FS.isDir(this.mode); },
+            },
+            isDevice: {
+              get: function() { return FS.isChrdev(this.mode); },
+            },
+          });
+        }
+
+        var node = new FS.FSNode(parent, name, mode, rdev);
+
+        FS.hashAddNode(node);
+
+        return node;
+      },destroyNode:function (node) {
+        FS.hashRemoveNode(node);
+      },isRoot:function (node) {
+        return node === node.parent;
+      },isMountpoint:function (node) {
+        return !!node.mounted;
+      },isFile:function (mode) {
+        return (mode & 61440) === 32768;
+      },isDir:function (mode) {
+        return (mode & 61440) === 16384;
+      },isLink:function (mode) {
+        return (mode & 61440) === 40960;
+      },isChrdev:function (mode) {
+        return (mode & 61440) === 8192;
+      },isBlkdev:function (mode) {
+        return (mode & 61440) === 24576;
+      },isFIFO:function (mode) {
+        return (mode & 61440) === 4096;
+      },isSocket:function (mode) {
+        return (mode & 49152) === 49152;
+      },flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function (str) {
+        var flags = FS.flagModes[str];
+        if (typeof flags === 'undefined') {
+          throw new Error('Unknown file open mode: ' + str);
+        }
+        return flags;
+      },flagsToPermissionString:function (flag) {
+        var accmode = flag & 2097155;
+        var perms = ['r', 'w', 'rw'][accmode];
+        if ((flag & 512)) {
+          perms += 'w';
+        }
+        return perms;
+      },nodePermissions:function (node, perms) {
+        if (FS.ignorePermissions) {
+          return 0;
+        }
+        // return 0 if any user, group or owner bits are set.
+        if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
+          return ERRNO_CODES.EACCES;
+        }
+        return 0;
+      },mayLookup:function (dir) {
+        return FS.nodePermissions(dir, 'x');
+      },mayCreate:function (dir, name) {
+        try {
+          var node = FS.lookupNode(dir, name);
+          return ERRNO_CODES.EEXIST;
+        } catch (e) {
+        }
+        return FS.nodePermissions(dir, 'wx');
+      },mayDelete:function (dir, name, isdir) {
+        var node;
+        try {
+          node = FS.lookupNode(dir, name);
+        } catch (e) {
+          return e.errno;
+        }
+        var err = FS.nodePermissions(dir, 'wx');
+        if (err) {
+          return err;
+        }
+        if (isdir) {
+          if (!FS.isDir(node.mode)) {
+            return ERRNO_CODES.ENOTDIR;
+          }
+          if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
+            return ERRNO_CODES.EBUSY;
+          }
+        } else {
+          if (FS.isDir(node.mode)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return 0;
+      },mayOpen:function (node, flags) {
+        if (!node) {
+          return ERRNO_CODES.ENOENT;
+        }
+        if (FS.isLink(node.mode)) {
+          return ERRNO_CODES.ELOOP;
+        } else if (FS.isDir(node.mode)) {
+          if ((flags & 2097155) !== 0 ||  // opening for write
+              (flags & 512)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
+      },MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) {
+        fd_start = fd_start || 0;
+        fd_end = fd_end || FS.MAX_OPEN_FDS;
+        for (var fd = fd_start; fd <= fd_end; fd++) {
+          if (!FS.streams[fd]) {
+            return fd;
+          }
+        }
+        throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
+      },getStream:function (fd) {
+        return FS.streams[fd];
+      },createStream:function (stream, fd_start, fd_end) {
+        if (!FS.FSStream) {
+          FS.FSStream = function(){};
+          FS.FSStream.prototype = {};
+          // compatibility
+          Object.defineProperties(FS.FSStream.prototype, {
+            object: {
+              get: function() { return this.node; },
+              set: function(val) { this.node = val; }
+            },
+            isRead: {
+              get: function() { return (this.flags & 2097155) !== 1; }
+            },
+            isWrite: {
+              get: function() { return (this.flags & 2097155) !== 0; }
+            },
+            isAppend: {
+              get: function() { return (this.flags & 1024); }
+            }
+          });
+        }
+        if (0) {
+          // reuse the object
+          stream.__proto__ = FS.FSStream.prototype;
+        } else {
+          var newStream = new FS.FSStream();
+          for (var p in stream) {
+            newStream[p] = stream[p];
+          }
+          stream = newStream;
+        }
+        var fd = FS.nextfd(fd_start, fd_end);
+        stream.fd = fd;
+        FS.streams[fd] = stream;
+        return stream;
+      },closeStream:function (fd) {
+        FS.streams[fd] = null;
+      },getStreamFromPtr:function (ptr) {
+        return FS.streams[ptr - 1];
+      },getPtrForStream:function (stream) {
+        return stream ? stream.fd + 1 : 0;
+      },chrdev_stream_ops:{open:function (stream) {
+          var device = FS.getDevice(stream.node.rdev);
+          // override node's stream ops with the device's
+          stream.stream_ops = device.stream_ops;
+          // forward the open call
+          if (stream.stream_ops.open) {
+            stream.stream_ops.open(stream);
+          }
+        },llseek:function () {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }},major:function (dev) {
+        return ((dev) >> 8);
+      },minor:function (dev) {
+        return ((dev) & 0xff);
+      },makedev:function (ma, mi) {
+        return ((ma) << 8 | (mi));
+      },registerDevice:function (dev, ops) {
+        FS.devices[dev] = { stream_ops: ops };
+      },getDevice:function (dev) {
+        return FS.devices[dev];
+      },getMounts:function (mount) {
+        var mounts = [];
+        var check = [mount];
+
+        while (check.length) {
+          var m = check.pop();
+
+          mounts.push(m);
+
+          check.push.apply(check, m.mounts);
+        }
+
+        return mounts;
+      },syncfs:function (populate, callback) {
+        if (typeof(populate) === 'function') {
+          callback = populate;
+          populate = false;
+        }
+
+        var mounts = FS.getMounts(FS.root.mount);
+        var completed = 0;
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= mounts.length) {
+            callback(null);
+          }
+        };
+
+        // sync all mounts
+        mounts.forEach(function (mount) {
+          if (!mount.type.syncfs) {
+            return done(null);
+          }
+          mount.type.syncfs(mount, populate, done);
+        });
+      },mount:function (type, opts, mountpoint) {
+        var root = mountpoint === '/';
+        var pseudo = !mountpoint;
+        var node;
+
+        if (root && FS.root) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        } else if (!root && !pseudo) {
+          var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+          mountpoint = lookup.path;  // use the absolute path
+          node = lookup.node;
+
+          if (FS.isMountpoint(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+          }
+
+          if (!FS.isDir(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+          }
+        }
+
+        var mount = {
+          type: type,
+          opts: opts,
+          mountpoint: mountpoint,
+          mounts: []
+        };
+
+        // create a root node for the fs
+        var mountRoot = type.mount(mount);
+        mountRoot.mount = mount;
+        mount.root = mountRoot;
+
+        if (root) {
+          FS.root = mountRoot;
+        } else if (node) {
+          // set as a mountpoint
+          node.mounted = mount;
+
+          // add the new mount to the current mount's children
+          if (node.mount) {
+            node.mount.mounts.push(mount);
+          }
+        }
+
+        return mountRoot;
+      },unmount:function (mountpoint) {
+        var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+        if (!FS.isMountpoint(lookup.node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+
+        // destroy the nodes for this mount, and all its child mounts
+        var node = lookup.node;
+        var mount = node.mounted;
+        var mounts = FS.getMounts(mount);
+
+        Object.keys(FS.nameTable).forEach(function (hash) {
+          var current = FS.nameTable[hash];
+
+          while (current) {
+            var next = current.name_next;
+
+            if (mounts.indexOf(current.mount) !== -1) {
+              FS.destroyNode(current);
+            }
+
+            current = next;
+          }
+        });
+
+        // no longer a mountpoint
+        node.mounted = null;
+
+        // remove this mount from the child mounts
+        var idx = node.mount.mounts.indexOf(mount);
+        assert(idx !== -1);
+        node.mount.mounts.splice(idx, 1);
+      },lookup:function (parent, name) {
+        return parent.node_ops.lookup(parent, name);
+      },mknod:function (path, mode, dev) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var err = FS.mayCreate(parent, name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.mknod) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.mknod(parent, name, mode, dev);
+      },create:function (path, mode) {
+        mode = mode !== undefined ? mode : 438 /* 0666 */;
+        mode &= 4095;
+        mode |= 32768;
+        return FS.mknod(path, mode, 0);
+      },mkdir:function (path, mode) {
+        mode = mode !== undefined ? mode : 511 /* 0777 */;
+        mode &= 511 | 512;
+        mode |= 16384;
+        return FS.mknod(path, mode, 0);
+      },mkdev:function (path, mode, dev) {
+        if (typeof(dev) === 'undefined') {
+          dev = mode;
+          mode = 438 /* 0666 */;
+        }
+        mode |= 8192;
+        return FS.mknod(path, mode, dev);
+      },symlink:function (oldpath, newpath) {
+        var lookup = FS.lookupPath(newpath, { parent: true });
+        var parent = lookup.node;
+        var newname = PATH.basename(newpath);
+        var err = FS.mayCreate(parent, newname);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.symlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.symlink(parent, newname, oldpath);
+      },rename:function (old_path, new_path) {
+        var old_dirname = PATH.dirname(old_path);
+        var new_dirname = PATH.dirname(new_path);
+        var old_name = PATH.basename(old_path);
+        var new_name = PATH.basename(new_path);
+        // parents must exist
+        var lookup, old_dir, new_dir;
+        try {
+          lookup = FS.lookupPath(old_path, { parent: true });
+          old_dir = lookup.node;
+          lookup = FS.lookupPath(new_path, { parent: true });
+          new_dir = lookup.node;
+        } catch (e) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // need to be part of the same mount
+        if (old_dir.mount !== new_dir.mount) {
+          throw new FS.ErrnoError(ERRNO_CODES.EXDEV);
+        }
+        // source must exist
+        var old_node = FS.lookupNode(old_dir, old_name);
+        // old path should not be an ancestor of the new path
+        var relative = PATH.relative(old_path, new_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        // new path should not be an ancestor of the old path
+        relative = PATH.relative(new_path, old_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+        }
+        // see if the new path already exists
+        var new_node;
+        try {
+          new_node = FS.lookupNode(new_dir, new_name);
+        } catch (e) {
+          // not fatal
+        }
+        // early out if nothing needs to change
+        if (old_node === new_node) {
+          return;
+        }
+        // we'll need to delete the old entry
+        var isdir = FS.isDir(old_node.mode);
+        var err = FS.mayDelete(old_dir, old_name, isdir);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // need delete permissions if we'll be overwriting.
+        // need create permissions if new doesn't already exist.
+        err = new_node ?
+          FS.mayDelete(new_dir, new_name, isdir) :
+          FS.mayCreate(new_dir, new_name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!old_dir.node_ops.rename) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // if we are going to change the parent, check write permissions
+        if (new_dir !== old_dir) {
+          err = FS.nodePermissions(old_dir, 'w');
+          if (err) {
+            throw new FS.ErrnoError(err);
+          }
+        }
+        // remove the node from the lookup hash
+        FS.hashRemoveNode(old_node);
+        // do the underlying fs rename
+        try {
+          old_dir.node_ops.rename(old_node, new_dir, new_name);
+        } catch (e) {
+          throw e;
+        } finally {
+          // add the node back to the hash (in case node_ops.rename
+          // changed its name)
+          FS.hashAddNode(old_node);
+        }
+      },rmdir:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, true);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.rmdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.rmdir(parent, name);
+        FS.destroyNode(node);
+      },readdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        if (!node.node_ops.readdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        return node.node_ops.readdir(node);
+      },unlink:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, false);
+        if (err) {
+          // POSIX says unlink should set EPERM, not EISDIR
+          if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM;
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.unlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.unlink(parent, name);
+        FS.destroyNode(node);
+      },readlink:function (path) {
+        var lookup = FS.lookupPath(path);
+        var link = lookup.node;
+        if (!link.node_ops.readlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        return link.node_ops.readlink(link);
+      },stat:function (path, dontFollow) {
+        var lookup = FS.lookupPath(path, { follow: !dontFollow });
+        var node = lookup.node;
+        if (!node.node_ops.getattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return node.node_ops.getattr(node);
+      },lstat:function (path) {
+        return FS.stat(path, true);
+      },chmod:function (path, mode, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          mode: (mode & 4095) | (node.mode & ~4095),
+          timestamp: Date.now()
+        });
+      },lchmod:function (path, mode) {
+        FS.chmod(path, mode, true);
+      },fchmod:function (fd, mode) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chmod(stream.node, mode);
+      },chown:function (path, uid, gid, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          timestamp: Date.now()
+          // we ignore the uid / gid for now
+        });
+      },lchown:function (path, uid, gid) {
+        FS.chown(path, uid, gid, true);
+      },fchown:function (fd, uid, gid) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chown(stream.node, uid, gid);
+      },truncate:function (path, len) {
+        if (len < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: true });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!FS.isFile(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var err = FS.nodePermissions(node, 'w');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        node.node_ops.setattr(node, {
+          size: len,
+          timestamp: Date.now()
+        });
+      },ftruncate:function (fd, len) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        FS.truncate(stream.node, len);
+      },utime:function (path, atime, mtime) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        node.node_ops.setattr(node, {
+          timestamp: Math.max(atime, mtime)
+        });
+      },open:function (path, flags, mode, fd_start, fd_end) {
+        flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
+        mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
+        if ((flags & 64)) {
+          mode = (mode & 4095) | 32768;
+        } else {
+          mode = 0;
+        }
+        var node;
+        if (typeof path === 'object') {
+          node = path;
+        } else {
+          path = PATH.normalize(path);
+          try {
+            var lookup = FS.lookupPath(path, {
+              follow: !(flags & 131072)
+            });
+            node = lookup.node;
+          } catch (e) {
+            // ignore
+          }
+        }
+        // perhaps we need to create the node
+        if ((flags & 64)) {
+          if (node) {
+            // if O_CREAT and O_EXCL are set, error out if the node already exists
+            if ((flags & 128)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EEXIST);
+            }
+          } else {
+            // node doesn't exist, try to create it
+            node = FS.mknod(path, mode, 0);
+          }
+        }
+        if (!node) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
+        }
+        // can't truncate a device
+        if (FS.isChrdev(node.mode)) {
+          flags &= ~512;
+        }
+        // check permissions
+        var err = FS.mayOpen(node, flags);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // do truncation if necessary
+        if ((flags & 512)) {
+          FS.truncate(node, 0);
+        }
+        // we've already handled these, don't pass down to the underlying vfs
+        flags &= ~(128 | 512);
+
+        // register the stream with the filesystem
+        var stream = FS.createStream({
+          node: node,
+          path: FS.getPath(node),  // we want the absolute path to the node
+          flags: flags,
+          seekable: true,
+          position: 0,
+          stream_ops: node.stream_ops,
+          // used by the file family libc calls (fopen, fwrite, ferror, etc.)
+          ungotten: [],
+          error: false
+        }, fd_start, fd_end);
+        // call the new stream's open function
+        if (stream.stream_ops.open) {
+          stream.stream_ops.open(stream);
+        }
+        if (Module['logReadFiles'] && !(flags & 1)) {
+          if (!FS.readFiles) FS.readFiles = {};
+          if (!(path in FS.readFiles)) {
+            FS.readFiles[path] = 1;
+            Module['printErr']('read file: ' + path);
+          }
+        }
+        return stream;
+      },close:function (stream) {
+        try {
+          if (stream.stream_ops.close) {
+            stream.stream_ops.close(stream);
+          }
+        } catch (e) {
+          throw e;
+        } finally {
+          FS.closeStream(stream.fd);
+        }
+      },llseek:function (stream, offset, whence) {
+        if (!stream.seekable || !stream.stream_ops.llseek) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        return stream.stream_ops.llseek(stream, offset, whence);
+      },read:function (stream, buffer, offset, length, position) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.read) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
+        if (!seeking) stream.position += bytesRead;
+        return bytesRead;
+      },write:function (stream, buffer, offset, length, position, canOwn) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.write) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        if (stream.flags & 1024) {
+          // seek to the end before writing in append mode
+          FS.llseek(stream, 0, 2);
+        }
+        var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
+        if (!seeking) stream.position += bytesWritten;
+        return bytesWritten;
+      },allocate:function (stream, offset, length) {
+        if (offset < 0 || length <= 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        if (!stream.stream_ops.allocate) {
+          throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+        }
+        stream.stream_ops.allocate(stream, offset, length);
+      },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+        // TODO if PROT is PROT_WRITE, make sure we have write access
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EACCES);
+        }
+        if (!stream.stream_ops.mmap) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
+      },ioctl:function (stream, cmd, arg) {
+        if (!stream.stream_ops.ioctl) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTTY);
+        }
+        return stream.stream_ops.ioctl(stream, cmd, arg);
+      },readFile:function (path, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'r';
+        opts.encoding = opts.encoding || 'binary';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var ret;
+        var stream = FS.open(path, opts.flags);
+        var stat = FS.stat(path);
+        var length = stat.size;
+        var buf = new Uint8Array(length);
+        FS.read(stream, buf, 0, length, 0);
+        if (opts.encoding === 'utf8') {
+          ret = '';
+          var utf8 = new Runtime.UTF8Processor();
+          for (var i = 0; i < length; i++) {
+            ret += utf8.processCChar(buf[i]);
+          }
+        } else if (opts.encoding === 'binary') {
+          ret = buf;
+        }
+        FS.close(stream);
+        return ret;
+      },writeFile:function (path, data, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'w';
+        opts.encoding = opts.encoding || 'utf8';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var stream = FS.open(path, opts.flags, opts.mode);
+        if (opts.encoding === 'utf8') {
+          var utf8 = new Runtime.UTF8Processor();
+          var buf = new Uint8Array(utf8.processJSString(data));
+          FS.write(stream, buf, 0, buf.length, 0, opts.canOwn);
+        } else if (opts.encoding === 'binary') {
+          FS.write(stream, data, 0, data.length, 0, opts.canOwn);
+        }
+        FS.close(stream);
+      },cwd:function () {
+        return FS.currentPath;
+      },chdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        if (!FS.isDir(lookup.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        var err = FS.nodePermissions(lookup.node, 'x');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        FS.currentPath = lookup.path;
+      },createDefaultDirectories:function () {
+        FS.mkdir('/tmp');
+      },createDefaultDevices:function () {
+        // create /dev
+        FS.mkdir('/dev');
+        // setup /dev/null
+        FS.registerDevice(FS.makedev(1, 3), {
+          read: function() { return 0; },
+          write: function() { return 0; }
+        });
+        FS.mkdev('/dev/null', FS.makedev(1, 3));
+        // setup /dev/tty and /dev/tty1
+        // stderr needs to print output using Module['printErr']
+        // so we register a second tty just for it.
+        TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
+        TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
+        FS.mkdev('/dev/tty', FS.makedev(5, 0));
+        FS.mkdev('/dev/tty1', FS.makedev(6, 0));
+        // we're not going to emulate the actual shm device,
+        // just create the tmp dirs that reside in it commonly
+        FS.mkdir('/dev/shm');
+        FS.mkdir('/dev/shm/tmp');
+      },createStandardStreams:function () {
+        // TODO deprecate the old functionality of a single
+        // input / output callback and that utilizes FS.createDevice
+        // and instead require a unique set of stream ops
+
+        // by default, we symlink the standard streams to the
+        // default tty devices. however, if the standard streams
+        // have been overwritten we create a unique device for
+        // them instead.
+        if (Module['stdin']) {
+          FS.createDevice('/dev', 'stdin', Module['stdin']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdin');
+        }
+        if (Module['stdout']) {
+          FS.createDevice('/dev', 'stdout', null, Module['stdout']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdout');
+        }
+        if (Module['stderr']) {
+          FS.createDevice('/dev', 'stderr', null, Module['stderr']);
+        } else {
+          FS.symlink('/dev/tty1', '/dev/stderr');
+        }
+
+        // open default streams for the stdin, stdout and stderr devices
+        var stdin = FS.open('/dev/stdin', 'r');
+        HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin);
+        assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
+
+        var stdout = FS.open('/dev/stdout', 'w');
+        HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout);
+        assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
+
+        var stderr = FS.open('/dev/stderr', 'w');
+        HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr);
+        assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
+      },ensureErrnoError:function () {
+        if (FS.ErrnoError) return;
+        FS.ErrnoError = function ErrnoError(errno) {
+          this.errno = errno;
+          for (var key in ERRNO_CODES) {
+            if (ERRNO_CODES[key] === errno) {
+              this.code = key;
+              break;
+            }
+          }
+          this.message = ERRNO_MESSAGES[errno];
+        };
+        FS.ErrnoError.prototype = new Error();
+        FS.ErrnoError.prototype.constructor = FS.ErrnoError;
+        // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
+        [ERRNO_CODES.ENOENT].forEach(function(code) {
+          FS.genericErrors[code] = new FS.ErrnoError(code);
+          FS.genericErrors[code].stack = '<generic error, no stack>';
+        });
+      },staticInit:function () {
+        FS.ensureErrnoError();
+
+        FS.nameTable = new Array(4096);
+
+        FS.mount(MEMFS, {}, '/');
+
+        FS.createDefaultDirectories();
+        FS.createDefaultDevices();
+      },init:function (input, output, error) {
+        assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
+        FS.init.initialized = true;
+
+        FS.ensureErrnoError();
+
+        // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
+        Module['stdin'] = input || Module['stdin'];
+        Module['stdout'] = output || Module['stdout'];
+        Module['stderr'] = error || Module['stderr'];
+
+        FS.createStandardStreams();
+      },quit:function () {
+        FS.init.initialized = false;
+        for (var i = 0; i < FS.streams.length; i++) {
+          var stream = FS.streams[i];
+          if (!stream) {
+            continue;
+          }
+          FS.close(stream);
+        }
+      },getMode:function (canRead, canWrite) {
+        var mode = 0;
+        if (canRead) mode |= 292 | 73;
+        if (canWrite) mode |= 146;
+        return mode;
+      },joinPath:function (parts, forceRelative) {
+        var path = PATH.join.apply(null, parts);
+        if (forceRelative && path[0] == '/') path = path.substr(1);
+        return path;
+      },absolutePath:function (relative, base) {
+        return PATH.resolve(base, relative);
+      },standardizePath:function (path) {
+        return PATH.normalize(path);
+      },findObject:function (path, dontResolveLastLink) {
+        var ret = FS.analyzePath(path, dontResolveLastLink);
+        if (ret.exists) {
+          return ret.object;
+        } else {
+          ___setErrNo(ret.error);
+          return null;
+        }
+      },analyzePath:function (path, dontResolveLastLink) {
+        // operate from within the context of the symlink's target
+        try {
+          var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          path = lookup.path;
+        } catch (e) {
+        }
+        var ret = {
+          isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
+          parentExists: false, parentPath: null, parentObject: null
+        };
+        try {
+          var lookup = FS.lookupPath(path, { parent: true });
+          ret.parentExists = true;
+          ret.parentPath = lookup.path;
+          ret.parentObject = lookup.node;
+          ret.name = PATH.basename(path);
+          lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          ret.exists = true;
+          ret.path = lookup.path;
+          ret.object = lookup.node;
+          ret.name = lookup.node.name;
+          ret.isRoot = lookup.path === '/';
+        } catch (e) {
+          ret.error = e.errno;
+        };
+        return ret;
+      },createFolder:function (parent, name, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.mkdir(path, mode);
+      },createPath:function (parent, path, canRead, canWrite) {
+        parent = typeof parent === 'string' ? parent : FS.getPath(parent);
+        var parts = path.split('/').reverse();
+        while (parts.length) {
+          var part = parts.pop();
+          if (!part) continue;
+          var current = PATH.join2(parent, part);
+          try {
+            FS.mkdir(current);
+          } catch (e) {
+            // ignore EEXIST
+          }
+          parent = current;
+        }
+        return current;
+      },createFile:function (parent, name, properties, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.create(path, mode);
+      },createDataFile:function (parent, name, data, canRead, canWrite, canOwn) {
+        var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
+        var mode = FS.getMode(canRead, canWrite);
+        var node = FS.create(path, mode);
+        if (data) {
+          if (typeof data === 'string') {
+            var arr = new Array(data.length);
+            for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
+            data = arr;
+          }
+          // make sure we can write to the file
+          FS.chmod(node, mode | 146);
+          var stream = FS.open(node, 'w');
+          FS.write(stream, data, 0, data.length, 0, canOwn);
+          FS.close(stream);
+          FS.chmod(node, mode);
+        }
+        return node;
+      },createDevice:function (parent, name, input, output) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(!!input, !!output);
+        if (!FS.createDevice.major) FS.createDevice.major = 64;
+        var dev = FS.makedev(FS.createDevice.major++, 0);
+        // Create a fake device that a set of stream ops to emulate
+        // the old behavior.
+        FS.registerDevice(dev, {
+          open: function(stream) {
+            stream.seekable = false;
+          },
+          close: function(stream) {
+            // flush any pending line data
+            if (output && output.buffer && output.buffer.length) {
+              output(10);
+            }
+          },
+          read: function(stream, buffer, offset, length, pos /* ignored */) {
+            var bytesRead = 0;
+            for (var i = 0; i < length; i++) {
+              var result;
+              try {
+                result = input();
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+              if (result === undefined && bytesRead === 0) {
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+              if (result === null || result === undefined) break;
+              bytesRead++;
+              buffer[offset+i] = result;
+            }
+            if (bytesRead) {
+              stream.node.timestamp = Date.now();
+            }
+            return bytesRead;
+          },
+          write: function(stream, buffer, offset, length, pos) {
+            for (var i = 0; i < length; i++) {
+              try {
+                output(buffer[offset+i]);
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+            }
+            if (length) {
+              stream.node.timestamp = Date.now();
+            }
+            return i;
+          }
+        });
+        return FS.mkdev(path, mode, dev);
+      },createLink:function (parent, name, target, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        return FS.symlink(target, path);
+      },forceLoadFile:function (obj) {
+        if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
+        var success = true;
+        if (typeof XMLHttpRequest !== 'undefined') {
+          throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
+        } else if (Module['read']) {
+          // Command-line.
+          try {
+            // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
+            //          read() will try to parse UTF8.
+            obj.contents = intArrayFromString(Module['read'](obj.url), true);
+          } catch (e) {
+            success = false;
+          }
+        } else {
+          throw new Error('Cannot load without read() or XMLHttpRequest.');
+        }
+        if (!success) ___setErrNo(ERRNO_CODES.EIO);
+        return success;
+      },createLazyFile:function (parent, name, url, canRead, canWrite) {
+        // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
+        function LazyUint8Array() {
+          this.lengthKnown = false;
+          this.chunks = []; // Loaded chunks. Index is the chunk number
+        }
+        LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
+          if (idx > this.length-1 || idx < 0) {
+            return undefined;
+          }
+          var chunkOffset = idx % this.chunkSize;
+          var chunkNum = Math.floor(idx / this.chunkSize);
+          return this.getter(chunkNum)[chunkOffset];
+        }
+        LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
+          this.getter = getter;
+        }
+        LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
+            // Find length
+            var xhr = new XMLHttpRequest();
+            xhr.open('HEAD', url, false);
+            xhr.send(null);
+            if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+            var datalength = Number(xhr.getResponseHeader("Content-length"));
+            var header;
+            var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
+            var chunkSize = 1024*1024; // Chunk size in bytes
+
+            if (!hasByteServing) chunkSize = datalength;
+
+            // Function to get a range from the remote URL.
+            var doXHR = (function(from, to) {
+              if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
+              if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
+
+              // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
+              var xhr = new XMLHttpRequest();
+              xhr.open('GET', url, false);
+              if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
+
+              // Some hints to the browser that we want binary data.
+              if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
+              if (xhr.overrideMimeType) {
+                xhr.overrideMimeType('text/plain; charset=x-user-defined');
+              }
+
+              xhr.send(null);
+              if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+              if (xhr.response !== undefined) {
+                return new Uint8Array(xhr.response || []);
+              } else {
+                return intArrayFromString(xhr.responseText || '', true);
+              }
+            });
+            var lazyArray = this;
+            lazyArray.setDataGetter(function(chunkNum) {
+              var start = chunkNum * chunkSize;
+              var end = (chunkNum+1) * chunkSize - 1; // including this byte
+              end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
+                lazyArray.chunks[chunkNum] = doXHR(start, end);
+              }
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
+              return lazyArray.chunks[chunkNum];
+            });
+
+            this._length = datalength;
+            this._chunkSize = chunkSize;
+            this.lengthKnown = true;
+        }
+        if (typeof XMLHttpRequest !== 'undefined') {
+          if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
+          var lazyArray = new LazyUint8Array();
+          Object.defineProperty(lazyArray, "length", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._length;
+              }
+          });
+          Object.defineProperty(lazyArray, "chunkSize", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._chunkSize;
+              }
+          });
+
+          var properties = { isDevice: false, contents: lazyArray };
+        } else {
+          var properties = { isDevice: false, url: url };
+        }
+
+        var node = FS.createFile(parent, name, properties, canRead, canWrite);
+        // This is a total hack, but I want to get this lazy file code out of the
+        // core of MEMFS. If we want to keep this lazy file concept I feel it should
+        // be its own thin LAZYFS proxying calls to MEMFS.
+        if (properties.contents) {
+          node.contents = properties.contents;
+        } else if (properties.url) {
+          node.contents = null;
+          node.url = properties.url;
+        }
+        // override each stream op with one that tries to force load the lazy file first
+        var stream_ops = {};
+        var keys = Object.keys(node.stream_ops);
+        keys.forEach(function(key) {
+          var fn = node.stream_ops[key];
+          stream_ops[key] = function forceLoadLazyFile() {
+            if (!FS.forceLoadFile(node)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            return fn.apply(null, arguments);
+          };
+        });
+        // use a custom read function
+        stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
+          if (!FS.forceLoadFile(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EIO);
+          }
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (contents.slice) { // normal array
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          } else {
+            for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
+              buffer[offset + i] = contents.get(position + i);
+            }
+          }
+          return size;
+        };
+        node.stream_ops = stream_ops;
+        return node;
+      },createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
+        Browser.init();
+        // TODO we should allow people to just pass in a complete filename instead
+        // of parent and name being that we just join them anyways
+        var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent;
+        function processData(byteArray) {
+          function finish(byteArray) {
+            if (!dontCreateFile) {
+              FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
+            }
+            if (onload) onload();
+            removeRunDependency('cp ' + fullname);
+          }
+          var handled = false;
+          Module['preloadPlugins'].forEach(function(plugin) {
+            if (handled) return;
+            if (plugin['canHandle'](fullname)) {
+              plugin['handle'](byteArray, fullname, finish, function() {
+                if (onerror) onerror();
+                removeRunDependency('cp ' + fullname);
+              });
+              handled = true;
+            }
+          });
+          if (!handled) finish(byteArray);
+        }
+        addRunDependency('cp ' + fullname);
+        if (typeof url == 'string') {
+          Browser.asyncLoad(url, function(byteArray) {
+            processData(byteArray);
+          }, onerror);
+        } else {
+          processData(url);
+        }
+      },indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_NAME:function () {
+        return 'EM_FS_' + window.location.pathname;
+      },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
+          console.log('creating db');
+          var db = openRequest.result;
+          db.createObjectStore(FS.DB_STORE_NAME);
+        };
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var putRequest = files.put(FS.analyzePath(path).object.contents, path);
+            putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
+            putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      },loadFilesFromDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = onerror; // no database to load from
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          try {
+            var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
+          } catch(e) {
+            onerror(e);
+            return;
+          }
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var getRequest = files.get(path);
+            getRequest.onsuccess = function getRequest_onsuccess() {
+              if (FS.analyzePath(path).exists) {
+                FS.unlink(path);
+              }
+              FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
+              ok++;
+              if (ok + fail == total) finish();
+            };
+            getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      }};var PATH={splitPath:function (filename) {
+        var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+        return splitPathRe.exec(filename).slice(1);
+      },normalizeArray:function (parts, allowAboveRoot) {
+        // if the path tries to go above the root, `up` ends up > 0
+        var up = 0;
+        for (var i = parts.length - 1; i >= 0; i--) {
+          var last = parts[i];
+          if (last === '.') {
+            parts.splice(i, 1);
+          } else if (last === '..') {
+            parts.splice(i, 1);
+            up++;
+          } else if (up) {
+            parts.splice(i, 1);
+            up--;
+          }
+        }
+        // if the path is allowed to go above the root, restore leading ..s
+        if (allowAboveRoot) {
+          for (; up--; up) {
+            parts.unshift('..');
+          }
+        }
+        return parts;
+      },normalize:function (path) {
+        var isAbsolute = path.charAt(0) === '/',
+            trailingSlash = path.substr(-1) === '/';
+        // Normalize the path
+        path = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), !isAbsolute).join('/');
+        if (!path && !isAbsolute) {
+          path = '.';
+        }
+        if (path && trailingSlash) {
+          path += '/';
+        }
+        return (isAbsolute ? '/' : '') + path;
+      },dirname:function (path) {
+        var result = PATH.splitPath(path),
+            root = result[0],
+            dir = result[1];
+        if (!root && !dir) {
+          // No dirname whatsoever
+          return '.';
+        }
+        if (dir) {
+          // It has a dirname, strip trailing slash
+          dir = dir.substr(0, dir.length - 1);
+        }
+        return root + dir;
+      },basename:function (path) {
+        // EMSCRIPTEN return '/'' for '/', not an empty string
+        if (path === '/') return '/';
+        var lastSlash = path.lastIndexOf('/');
+        if (lastSlash === -1) return path;
+        return path.substr(lastSlash+1);
+      },extname:function (path) {
+        return PATH.splitPath(path)[3];
+      },join:function () {
+        var paths = Array.prototype.slice.call(arguments, 0);
+        return PATH.normalize(paths.join('/'));
+      },join2:function (l, r) {
+        return PATH.normalize(l + '/' + r);
+      },resolve:function () {
+        var resolvedPath = '',
+          resolvedAbsolute = false;
+        for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+          var path = (i >= 0) ? arguments[i] : FS.cwd();
+          // Skip empty and invalid entries
+          if (typeof path !== 'string') {
+            throw new TypeError('Arguments to path.resolve must be strings');
+          } else if (!path) {
+            continue;
+          }
+          resolvedPath = path + '/' + resolvedPath;
+          resolvedAbsolute = path.charAt(0) === '/';
+        }
+        // At this point the path should be resolved to a full absolute path, but
+        // handle relative paths to be safe (might happen when process.cwd() fails)
+        resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
+          return !!p;
+        }), !resolvedAbsolute).join('/');
+        return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+      },relative:function (from, to) {
+        from = PATH.resolve(from).substr(1);
+        to = PATH.resolve(to).substr(1);
+        function trim(arr) {
+          var start = 0;
+          for (; start < arr.length; start++) {
+            if (arr[start] !== '') break;
+          }
+          var end = arr.length - 1;
+          for (; end >= 0; end--) {
+            if (arr[end] !== '') break;
+          }
+          if (start > end) return [];
+          return arr.slice(start, end - start + 1);
+        }
+        var fromParts = trim(from.split('/'));
+        var toParts = trim(to.split('/'));
+        var length = Math.min(fromParts.length, toParts.length);
+        var samePartsLength = length;
+        for (var i = 0; i < length; i++) {
+          if (fromParts[i] !== toParts[i]) {
+            samePartsLength = i;
+            break;
+          }
+        }
+        var outputParts = [];
+        for (var i = samePartsLength; i < fromParts.length; i++) {
+          outputParts.push('..');
+        }
+        outputParts = outputParts.concat(toParts.slice(samePartsLength));
+        return outputParts.join('/');
+      }};var Browser={mainLoop:{scheduler:null,method:"",shouldPause:false,paused:false,queue:[],pause:function () {
+          Browser.mainLoop.shouldPause = true;
+        },resume:function () {
+          if (Browser.mainLoop.paused) {
+            Browser.mainLoop.paused = false;
+            Browser.mainLoop.scheduler();
+          }
+          Browser.mainLoop.shouldPause = false;
+        },updateStatus:function () {
+          if (Module['setStatus']) {
+            var message = Module['statusMessage'] || 'Please wait...';
+            var remaining = Browser.mainLoop.remainingBlockers;
+            var expected = Browser.mainLoop.expectedBlockers;
+            if (remaining) {
+              if (remaining < expected) {
+                Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
+              } else {
+                Module['setStatus'](message);
+              }
+            } else {
+              Module['setStatus']('');
+            }
+          }
+        }},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () {
+        if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
+
+        if (Browser.initted || ENVIRONMENT_IS_WORKER) return;
+        Browser.initted = true;
+
+        try {
+          new Blob();
+          Browser.hasBlobConstructor = true;
+        } catch(e) {
+          Browser.hasBlobConstructor = false;
+          console.log("warning: no blob constructor, cannot create blobs with mimetypes");
+        }
+        Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
+        Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
+        if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
+          console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
+          Module.noImageDecoding = true;
+        }
+
+        // Support for plugins that can process preloaded files. You can add more of these to
+        // your app by creating and appending to Module.preloadPlugins.
+        //
+        // Each plugin is asked if it can handle a file based on the file's name. If it can,
+        // it is given the file's raw data. When it is done, it calls a callback with the file's
+        // (possibly modified) data. For example, a plugin might decompress a file, or it
+        // might create some side data structure for use later (like an Image element, etc.).
+
+        var imagePlugin = {};
+        imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
+          return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
+        };
+        imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
+          var b = null;
+          if (Browser.hasBlobConstructor) {
+            try {
+              b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+              if (b.size !== byteArray.length) { // Safari bug #118630
+                // Safari's Blob can only take an ArrayBuffer
+                b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
+              }
+            } catch(e) {
+              Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
+            }
+          }
+          if (!b) {
+            var bb = new Browser.BlobBuilder();
+            bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
+            b = bb.getBlob();
+          }
+          var url = Browser.URLObject.createObjectURL(b);
+          var img = new Image();
+          img.onload = function img_onload() {
+            assert(img.complete, 'Image ' + name + ' could not be decoded');
+            var canvas = document.createElement('canvas');
+            canvas.width = img.width;
+            canvas.height = img.height;
+            var ctx = canvas.getContext('2d');
+            ctx.drawImage(img, 0, 0);
+            Module["preloadedImages"][name] = canvas;
+            Browser.URLObject.revokeObjectURL(url);
+            if (onload) onload(byteArray);
+          };
+          img.onerror = function img_onerror(event) {
+            console.log('Image ' + url + ' could not be decoded');
+            if (onerror) onerror();
+          };
+          img.src = url;
+        };
+        Module['preloadPlugins'].push(imagePlugin);
+
+        var audioPlugin = {};
+        audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
+          return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
+        };
+        audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
+          var done = false;
+          function finish(audio) {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = audio;
+            if (onload) onload(byteArray);
+          }
+          function fail() {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = new Audio(); // empty shim
+            if (onerror) onerror();
+          }
+          if (Browser.hasBlobConstructor) {
+            try {
+              var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+            } catch(e) {
+              return fail();
+            }
+            var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
+            var audio = new Audio();
+            audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926
+            audio.onerror = function audio_onerror(event) {
+              if (done) return;
+              console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
+              function encode64(data) {
+                var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+                var PAD = '=';
+                var ret = '';
+                var leftchar = 0;
+                var leftbits = 0;
+                for (var i = 0; i < data.length; i++) {
+                  leftchar = (leftchar << 8) | data[i];
+                  leftbits += 8;
+                  while (leftbits >= 6) {
+                    var curr = (leftchar >> (leftbits-6)) & 0x3f;
+                    leftbits -= 6;
+                    ret += BASE[curr];
+                  }
+                }
+                if (leftbits == 2) {
+                  ret += BASE[(leftchar&3) << 4];
+                  ret += PAD + PAD;
+                } else if (leftbits == 4) {
+                  ret += BASE[(leftchar&0xf) << 2];
+                  ret += PAD;
+                }
+                return ret;
+              }
+              audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
+              finish(audio); // we don't wait for confirmation this worked - but it's worth trying
+            };
+            audio.src = url;
+            // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
+            Browser.safeSetTimeout(function() {
+              finish(audio); // try to use it even though it is not necessarily ready to play
+            }, 10000);
+          } else {
+            return fail();
+          }
+        };
+        Module['preloadPlugins'].push(audioPlugin);
+
+        // Canvas event setup
+
+        var canvas = Module['canvas'];
+
+        // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
+        // Module['forcedAspectRatio'] = 4 / 3;
+
+        canvas.requestPointerLock = canvas['requestPointerLock'] ||
+                                    canvas['mozRequestPointerLock'] ||
+                                    canvas['webkitRequestPointerLock'] ||
+                                    canvas['msRequestPointerLock'] ||
+                                    function(){};
+        canvas.exitPointerLock = document['exitPointerLock'] ||
+                                 document['mozExitPointerLock'] ||
+                                 document['webkitExitPointerLock'] ||
+                                 document['msExitPointerLock'] ||
+                                 function(){}; // no-op if function does not exist
+        canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
+
+        function pointerLockChange() {
+          Browser.pointerLock = document['pointerLockElement'] === canvas ||
+                                document['mozPointerLockElement'] === canvas ||
+                                document['webkitPointerLockElement'] === canvas ||
+                                document['msPointerLockElement'] === canvas;
+        }
+
+        document.addEventListener('pointerlockchange', pointerLockChange, false);
+        document.addEventListener('mozpointerlockchange', pointerLockChange, false);
+        document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
+        document.addEventListener('mspointerlockchange', pointerLockChange, false);
+
+        if (Module['elementPointerLock']) {
+          canvas.addEventListener("click", function(ev) {
+            if (!Browser.pointerLock && canvas.requestPointerLock) {
+              canvas.requestPointerLock();
+              ev.preventDefault();
+            }
+          }, false);
+        }
+      },createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) {
+        var ctx;
+        var errorInfo = '?';
+        function onContextCreationError(event) {
+          errorInfo = event.statusMessage || errorInfo;
+        }
+        try {
+          if (useWebGL) {
+            var contextAttributes = {
+              antialias: false,
+              alpha: false
+            };
+
+            if (webGLContextAttributes) {
+              for (var attribute in webGLContextAttributes) {
+                contextAttributes[attribute] = webGLContextAttributes[attribute];
+              }
+            }
+
+
+            canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
+            try {
+              ['experimental-webgl', 'webgl'].some(function(webglId) {
+                return ctx = canvas.getContext(webglId, contextAttributes);
+              });
+            } finally {
+              canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
+            }
+          } else {
+            ctx = canvas.getContext('2d');
+          }
+          if (!ctx) throw ':(';
+        } catch (e) {
+          Module.print('Could not create canvas: ' + [errorInfo, e]);
+          return null;
+        }
+        if (useWebGL) {
+          // Set the background of the WebGL canvas to black
+          canvas.style.backgroundColor = "black";
+
+          // Warn on context loss
+          canvas.addEventListener('webglcontextlost', function(event) {
+            alert('WebGL context lost. You will need to reload the page.');
+          }, false);
+        }
+        if (setInModule) {
+          GLctx = Module.ctx = ctx;
+          Module.useWebGL = useWebGL;
+          Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
+          Browser.init();
+        }
+        return ctx;
+      },destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) {
+        Browser.lockPointer = lockPointer;
+        Browser.resizeCanvas = resizeCanvas;
+        if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;
+        if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;
+
+        var canvas = Module['canvas'];
+        function fullScreenChange() {
+          Browser.isFullScreen = false;
+          var canvasContainer = canvas.parentNode;
+          if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+               document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+               document['fullScreenElement'] || document['fullscreenElement'] ||
+               document['msFullScreenElement'] || document['msFullscreenElement'] ||
+               document['webkitCurrentFullScreenElement']) === canvasContainer) {
+            canvas.cancelFullScreen = document['cancelFullScreen'] ||
+                                      document['mozCancelFullScreen'] ||
+                                      document['webkitCancelFullScreen'] ||
+                                      document['msExitFullscreen'] ||
+                                      document['exitFullscreen'] ||
+                                      function() {};
+            canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document);
+            if (Browser.lockPointer) canvas.requestPointerLock();
+            Browser.isFullScreen = true;
+            if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize();
+          } else {
+
+            // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
+            canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
+            canvasContainer.parentNode.removeChild(canvasContainer);
+
+            if (Browser.resizeCanvas) Browser.setWindowedCanvasSize();
+          }
+          if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen);
+          Browser.updateCanvasDimensions(canvas);
+        }
+
+        if (!Browser.fullScreenHandlersInstalled) {
+          Browser.fullScreenHandlersInstalled = true;
+          document.addEventListener('fullscreenchange', fullScreenChange, false);
+          document.addEventListener('mozfullscreenchange', fullScreenChange, false);
+          document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
+          document.addEventListener('MSFullscreenChange', fullScreenChange, false);
+        }
+
+        // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
+        var canvasContainer = document.createElement("div");
+        canvas.parentNode.insertBefore(canvasContainer, canvas);
+        canvasContainer.appendChild(canvas);
+
+        // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
+        canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] ||
+                                            canvasContainer['mozRequestFullScreen'] ||
+                                            canvasContainer['msRequestFullscreen'] ||
+                                           (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
+        canvasContainer.requestFullScreen();
+      },requestAnimationFrame:function requestAnimationFrame(func) {
+        if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js)
+          setTimeout(func, 1000/60);
+        } else {
+          if (!window.requestAnimationFrame) {
+            window.requestAnimationFrame = window['requestAnimationFrame'] ||
+                                           window['mozRequestAnimationFrame'] ||
+                                           window['webkitRequestAnimationFrame'] ||
+                                           window['msRequestAnimationFrame'] ||
+                                           window['oRequestAnimationFrame'] ||
+                                           window['setTimeout'];
+          }
+          window.requestAnimationFrame(func);
+        }
+      },safeCallback:function (func) {
+        return function() {
+          if (!ABORT) return func.apply(null, arguments);
+        };
+      },safeRequestAnimationFrame:function (func) {
+        return Browser.requestAnimationFrame(function() {
+          if (!ABORT) func();
+        });
+      },safeSetTimeout:function (func, timeout) {
+        return setTimeout(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },safeSetInterval:function (func, timeout) {
+        return setInterval(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },getMimetype:function (name) {
+        return {
+          'jpg': 'image/jpeg',
+          'jpeg': 'image/jpeg',
+          'png': 'image/png',
+          'bmp': 'image/bmp',
+          'ogg': 'audio/ogg',
+          'wav': 'audio/wav',
+          'mp3': 'audio/mpeg'
+        }[name.substr(name.lastIndexOf('.')+1)];
+      },getUserMedia:function (func) {
+        if(!window.getUserMedia) {
+          window.getUserMedia = navigator['getUserMedia'] ||
+                                navigator['mozGetUserMedia'];
+        }
+        window.getUserMedia(func);
+      },getMovementX:function (event) {
+        return event['movementX'] ||
+               event['mozMovementX'] ||
+               event['webkitMovementX'] ||
+               0;
+      },getMovementY:function (event) {
+        return event['movementY'] ||
+               event['mozMovementY'] ||
+               event['webkitMovementY'] ||
+               0;
+      },getMouseWheelDelta:function (event) {
+        return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta));
+      },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup
+        if (Browser.pointerLock) {
+          // When the pointer is locked, calculate the coordinates
+          // based on the movement of the mouse.
+          // Workaround for Firefox bug 764498
+          if (event.type != 'mousemove' &&
+              ('mozMovementX' in event)) {
+            Browser.mouseMovementX = Browser.mouseMovementY = 0;
+          } else {
+            Browser.mouseMovementX = Browser.getMovementX(event);
+            Browser.mouseMovementY = Browser.getMovementY(event);
+          }
+
+          // check if SDL is available
+          if (typeof SDL != "undefined") {
+            Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
+            Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
+          } else {
+            // just add the mouse delta to the current absolut mouse position
+            // FIXME: ideally this should be clamped against the canvas size and zero
+            Browser.mouseX += Browser.mouseMovementX;
+            Browser.mouseY += Browser.mouseMovementY;
+          }
+        } else {
+          // Otherwise, calculate the movement based on the changes
+          // in the coordinates.
+          var rect = Module["canvas"].getBoundingClientRect();
+          var x, y;
+
+          // Neither .scrollX or .pageXOffset are defined in a spec, but
+          // we prefer .scrollX because it is currently in a spec draft.
+          // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
+          var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);
+          var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);
+          if (event.type == 'touchstart' ||
+              event.type == 'touchend' ||
+              event.type == 'touchmove') {
+            var t = event.touches.item(0);
+            if (t) {
+              x = t.pageX - (scrollX + rect.left);
+              y = t.pageY - (scrollY + rect.top);
+            } else {
+              return;
+            }
+          } else {
+            x = event.pageX - (scrollX + rect.left);
+            y = event.pageY - (scrollY + rect.top);
+          }
+
+          // the canvas might be CSS-scaled compared to its backbuffer;
+          // SDL-using content will want mouse coordinates in terms
+          // of backbuffer units.
+          var cw = Module["canvas"].width;
+          var ch = Module["canvas"].height;
+          x = x * (cw / rect.width);
+          y = y * (ch / rect.height);
+
+          Browser.mouseMovementX = x - Browser.mouseX;
+          Browser.mouseMovementY = y - Browser.mouseY;
+          Browser.mouseX = x;
+          Browser.mouseY = y;
+        }
+      },xhrLoad:function (url, onload, onerror) {
+        var xhr = new XMLHttpRequest();
+        xhr.open('GET', url, true);
+        xhr.responseType = 'arraybuffer';
+        xhr.onload = function xhr_onload() {
+          if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
+            onload(xhr.response);
+          } else {
+            onerror();
+          }
+        };
+        xhr.onerror = onerror;
+        xhr.send(null);
+      },asyncLoad:function (url, onload, onerror, noRunDep) {
+        Browser.xhrLoad(url, function(arrayBuffer) {
+          assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
+          onload(new Uint8Array(arrayBuffer));
+          if (!noRunDep) removeRunDependency('al ' + url);
+        }, function(event) {
+          if (onerror) {
+            onerror();
+          } else {
+            throw 'Loading data file "' + url + '" failed.';
+          }
+        });
+        if (!noRunDep) addRunDependency('al ' + url);
+      },resizeListeners:[],updateResizeListeners:function () {
+        var canvas = Module['canvas'];
+        Browser.resizeListeners.forEach(function(listener) {
+          listener(canvas.width, canvas.height);
+        });
+      },setCanvasSize:function (width, height, noUpdates) {
+        var canvas = Module['canvas'];
+        Browser.updateCanvasDimensions(canvas, width, height);
+        if (!noUpdates) Browser.updateResizeListeners();
+      },windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+          var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+          flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
+          HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },setWindowedCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+          var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+          flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
+          HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },updateCanvasDimensions:function (canvas, wNative, hNative) {
+        if (wNative && hNative) {
+          canvas.widthNative = wNative;
+          canvas.heightNative = hNative;
+        } else {
+          wNative = canvas.widthNative;
+          hNative = canvas.heightNative;
+        }
+        var w = wNative;
+        var h = hNative;
+        if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
+          if (w/h < Module['forcedAspectRatio']) {
+            w = Math.round(h * Module['forcedAspectRatio']);
+          } else {
+            h = Math.round(w / Module['forcedAspectRatio']);
+          }
+        }
+        if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+             document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+             document['fullScreenElement'] || document['fullscreenElement'] ||
+             document['msFullScreenElement'] || document['msFullscreenElement'] ||
+             document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
+           var factor = Math.min(screen.width / w, screen.height / h);
+           w = Math.round(w * factor);
+           h = Math.round(h * factor);
+        }
+        if (Browser.resizeCanvas) {
+          if (canvas.width  != w) canvas.width  = w;
+          if (canvas.height != h) canvas.height = h;
+          if (typeof canvas.style != 'undefined') {
+            canvas.style.removeProperty( "width");
+            canvas.style.removeProperty("height");
+          }
+        } else {
+          if (canvas.width  != wNative) canvas.width  = wNative;
+          if (canvas.height != hNative) canvas.height = hNative;
+          if (typeof canvas.style != 'undefined') {
+            if (w != wNative || h != hNative) {
+              canvas.style.setProperty( "width", w + "px", "important");
+              canvas.style.setProperty("height", h + "px", "important");
+            } else {
+              canvas.style.removeProperty( "width");
+              canvas.style.removeProperty("height");
+            }
+          }
+        }
+      }};
+
+
+
+
+
+
+
+  function _mkport() { throw 'TODO' }var SOCKFS={mount:function (mount) {
+        return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createSocket:function (family, type, protocol) {
+        var streaming = type == 1;
+        if (protocol) {
+          assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp
+        }
+
+        // create our internal socket structure
+        var sock = {
+          family: family,
+          type: type,
+          protocol: protocol,
+          server: null,
+          peers: {},
+          pending: [],
+          recv_queue: [],
+          sock_ops: SOCKFS.websocket_sock_ops
+        };
+
+        // create the filesystem node to store the socket structure
+        var name = SOCKFS.nextname();
+        var node = FS.createNode(SOCKFS.root, name, 49152, 0);
+        node.sock = sock;
+
+        // and the wrapping stream that enables library functions such
+        // as read and write to indirectly interact with the socket
+        var stream = FS.createStream({
+          path: name,
+          node: node,
+          flags: FS.modeStringToFlags('r+'),
+          seekable: false,
+          stream_ops: SOCKFS.stream_ops
+        });
+
+        // map the new stream to the socket structure (sockets have a 1:1
+        // relationship with a stream)
+        sock.stream = stream;
+
+        return sock;
+      },getSocket:function (fd) {
+        var stream = FS.getStream(fd);
+        if (!stream || !FS.isSocket(stream.node.mode)) {
+          return null;
+        }
+        return stream.node.sock;
+      },stream_ops:{poll:function (stream) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.poll(sock);
+        },ioctl:function (stream, request, varargs) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.ioctl(sock, request, varargs);
+        },read:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          var msg = sock.sock_ops.recvmsg(sock, length);
+          if (!msg) {
+            // socket is closed
+            return 0;
+          }
+          buffer.set(msg.buffer, offset);
+          return msg.buffer.length;
+        },write:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.sendmsg(sock, buffer, offset, length);
+        },close:function (stream) {
+          var sock = stream.node.sock;
+          sock.sock_ops.close(sock);
+        }},nextname:function () {
+        if (!SOCKFS.nextname.current) {
+          SOCKFS.nextname.current = 0;
+        }
+        return 'socket[' + (SOCKFS.nextname.current++) + ']';
+      },websocket_sock_ops:{createPeer:function (sock, addr, port) {
+          var ws;
+
+          if (typeof addr === 'object') {
+            ws = addr;
+            addr = null;
+            port = null;
+          }
+
+          if (ws) {
+            // for sockets that've already connected (e.g. we're the server)
+            // we can inspect the _socket property for the address
+            if (ws._socket) {
+              addr = ws._socket.remoteAddress;
+              port = ws._socket.remotePort;
+            }
+            // if we're just now initializing a connection to the remote,
+            // inspect the url property
+            else {
+              var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
+              if (!result) {
+                throw new Error('WebSocket URL must be in the format ws(s)://address:port');
+              }
+              addr = result[1];
+              port = parseInt(result[2], 10);
+            }
+          } else {
+            // create the actual websocket object and connect
+            try {
+              // runtimeConfig gets set to true if WebSocket runtime configuration is available.
+              var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
+
+              // The default value is 'ws://' the replace is needed because the compiler replaces "//" comments with '#'
+              // comments without checking context, so we'd end up with ws:#, the replace swaps the "#" for "//" again.
+              var url = 'ws:#'.replace('#', '//');
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['url']) {
+                  url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
+                }
+              }
+
+              if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
+                url = url + addr + ':' + port;
+              }
+
+              // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
+              var subProtocols = 'binary'; // The default value is 'binary'
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['subprotocol']) {
+                  subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
+                }
+              }
+
+              // The regex trims the string (removes spaces at the beginning and end, then splits the string by
+              // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
+              subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
+
+              // The node ws library API for specifying optional subprotocol is slightly different than the browser's.
+              var opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols;
+
+              // If node we use the ws library.
+              var WebSocket = ENVIRONMENT_IS_NODE ? require('ws') : window['WebSocket'];
+              ws = new WebSocket(url, opts);
+              ws.binaryType = 'arraybuffer';
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH);
+            }
+          }
+
+
+          var peer = {
+            addr: addr,
+            port: port,
+            socket: ws,
+            dgram_send_queue: []
+          };
+
+          SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+          SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
+
+          // if this is a bound dgram socket, send the port number first to allow
+          // us to override the ephemeral port reported to us by remotePort on the
+          // remote end.
+          if (sock.type === 2 && typeof sock.sport !== 'undefined') {
+            peer.dgram_send_queue.push(new Uint8Array([
+                255, 255, 255, 255,
+                'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
+                ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
+            ]));
+          }
+
+          return peer;
+        },getPeer:function (sock, addr, port) {
+          return sock.peers[addr + ':' + port];
+        },addPeer:function (sock, peer) {
+          sock.peers[peer.addr + ':' + peer.port] = peer;
+        },removePeer:function (sock, peer) {
+          delete sock.peers[peer.addr + ':' + peer.port];
+        },handlePeerEvents:function (sock, peer) {
+          var first = true;
+
+          var handleOpen = function () {
+            try {
+              var queued = peer.dgram_send_queue.shift();
+              while (queued) {
+                peer.socket.send(queued);
+                queued = peer.dgram_send_queue.shift();
+              }
+            } catch (e) {
+              // not much we can do here in the way of proper error handling as we've already
+              // lied and said this data was sent. shut it down.
+              peer.socket.close();
+            }
+          };
+
+          function handleMessage(data) {
+            assert(typeof data !== 'string' && data.byteLength !== undefined);  // must receive an ArrayBuffer
+            data = new Uint8Array(data);  // make a typed array view on the array buffer
+
+
+            // if this is the port message, override the peer's port with it
+            var wasfirst = first;
+            first = false;
+            if (wasfirst &&
+                data.length === 10 &&
+                data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
+                data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
+              // update the peer's port and it's key in the peer map
+              var newport = ((data[8] << 8) | data[9]);
+              SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+              peer.port = newport;
+              SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+              return;
+            }
+
+            sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
+          };
+
+          if (ENVIRONMENT_IS_NODE) {
+            peer.socket.on('open', handleOpen);
+            peer.socket.on('message', function(data, flags) {
+              if (!flags.binary) {
+                return;
+              }
+              handleMessage((new Uint8Array(data)).buffer);  // copy from node Buffer -> ArrayBuffer
+            });
+            peer.socket.on('error', function() {
+              // don't throw
+            });
+          } else {
+            peer.socket.onopen = handleOpen;
+            peer.socket.onmessage = function peer_socket_onmessage(event) {
+              handleMessage(event.data);
+            };
+          }
+        },poll:function (sock) {
+          if (sock.type === 1 && sock.server) {
+            // listen sockets should only say they're available for reading
+            // if there are pending clients.
+            return sock.pending.length ? (64 | 1) : 0;
+          }
+
+          var mask = 0;
+          var dest = sock.type === 1 ?  // we only care about the socket state for connection-based sockets
+            SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
+            null;
+
+          if (sock.recv_queue.length ||
+              !dest ||  // connection-less sockets are always ready to read
+              (dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {  // let recv return 0 once closed
+            mask |= (64 | 1);
+          }
+
+          if (!dest ||  // connection-less sockets are always ready to write
+              (dest && dest.socket.readyState === dest.socket.OPEN)) {
+            mask |= 4;
+          }
+
+          if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {
+            mask |= 16;
+          }
+
+          return mask;
+        },ioctl:function (sock, request, arg) {
+          switch (request) {
+            case 21531:
+              var bytes = 0;
+              if (sock.recv_queue.length) {
+                bytes = sock.recv_queue[0].data.length;
+              }
+              HEAP32[((arg)>>2)]=bytes;
+              return 0;
+            default:
+              return ERRNO_CODES.EINVAL;
+          }
+        },close:function (sock) {
+          // if we've spawned a listen server, close it
+          if (sock.server) {
+            try {
+              sock.server.close();
+            } catch (e) {
+            }
+            sock.server = null;
+          }
+          // close any peer connections
+          var peers = Object.keys(sock.peers);
+          for (var i = 0; i < peers.length; i++) {
+            var peer = sock.peers[peers[i]];
+            try {
+              peer.socket.close();
+            } catch (e) {
+            }
+            SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+          }
+          return 0;
+        },bind:function (sock, addr, port) {
+          if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already bound
+          }
+          sock.saddr = addr;
+          sock.sport = port || _mkport();
+          // in order to emulate dgram sockets, we need to launch a listen server when
+          // binding on a connection-less socket
+          // note: this is only required on the server side
+          if (sock.type === 2) {
+            // close the existing server if it exists
+            if (sock.server) {
+              sock.server.close();
+              sock.server = null;
+            }
+            // swallow error operation not supported error that occurs when binding in the
+            // browser where this isn't supported
+            try {
+              sock.sock_ops.listen(sock, 0);
+            } catch (e) {
+              if (!(e instanceof FS.ErrnoError)) throw e;
+              if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e;
+            }
+          }
+        },connect:function (sock, addr, port) {
+          if (sock.server) {
+            throw new FS.ErrnoError(ERRNO_CODS.EOPNOTSUPP);
+          }
+
+          // TODO autobind
+          // if (!sock.addr && sock.type == 2) {
+          // }
+
+          // early out if we're already connected / in the middle of connecting
+          if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') {
+            var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+            if (dest) {
+              if (dest.socket.readyState === dest.socket.CONNECTING) {
+                throw new FS.ErrnoError(ERRNO_CODES.EALREADY);
+              } else {
+                throw new FS.ErrnoError(ERRNO_CODES.EISCONN);
+              }
+            }
+          }
+
+          // add the socket to our peer list and set our
+          // destination address / port to match
+          var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+          sock.daddr = peer.addr;
+          sock.dport = peer.port;
+
+          // always "fail" in non-blocking mode
+          throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS);
+        },listen:function (sock, backlog) {
+          if (!ENVIRONMENT_IS_NODE) {
+            throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+          }
+          if (sock.server) {
+             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already listening
+          }
+          var WebSocketServer = require('ws').Server;
+          var host = sock.saddr;
+          sock.server = new WebSocketServer({
+            host: host,
+            port: sock.sport
+            // TODO support backlog
+          });
+
+          sock.server.on('connection', function(ws) {
+            if (sock.type === 1) {
+              var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
+
+              // create a peer on the new socket
+              var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
+              newsock.daddr = peer.addr;
+              newsock.dport = peer.port;
+
+              // push to queue for accept to pick up
+              sock.pending.push(newsock);
+            } else {
+              // create a peer on the listen socket so calling sendto
+              // with the listen socket and an address will resolve
+              // to the correct client
+              SOCKFS.websocket_sock_ops.createPeer(sock, ws);
+            }
+          });
+          sock.server.on('closed', function() {
+            sock.server = null;
+          });
+          sock.server.on('error', function() {
+            // don't throw
+          });
+        },accept:function (listensock) {
+          if (!listensock.server) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          var newsock = listensock.pending.shift();
+          newsock.stream.flags = listensock.stream.flags;
+          return newsock;
+        },getname:function (sock, peer) {
+          var addr, port;
+          if (peer) {
+            if (sock.daddr === undefined || sock.dport === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            }
+            addr = sock.daddr;
+            port = sock.dport;
+          } else {
+            // TODO saddr and sport will be set for bind()'d UDP sockets, but what
+            // should we be returning for TCP sockets that've been connect()'d?
+            addr = sock.saddr || 0;
+            port = sock.sport || 0;
+          }
+          return { addr: addr, port: port };
+        },sendmsg:function (sock, buffer, offset, length, addr, port) {
+          if (sock.type === 2) {
+            // connection-less sockets will honor the message address,
+            // and otherwise fall back to the bound destination address
+            if (addr === undefined || port === undefined) {
+              addr = sock.daddr;
+              port = sock.dport;
+            }
+            // if there was no address to fall back to, error out
+            if (addr === undefined || port === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ);
+            }
+          } else {
+            // connection-based sockets will only use the bound
+            addr = sock.daddr;
+            port = sock.dport;
+          }
+
+          // find the peer for the destination address
+          var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
+
+          // early out if not connected with a connection-based socket
+          if (sock.type === 1) {
+            if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            } else if (dest.socket.readyState === dest.socket.CONNECTING) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // create a copy of the incoming data to send, as the WebSocket API
+          // doesn't work entirely with an ArrayBufferView, it'll just send
+          // the entire underlying buffer
+          var data;
+          if (buffer instanceof Array || buffer instanceof ArrayBuffer) {
+            data = buffer.slice(offset, offset + length);
+          } else {  // ArrayBufferView
+            data = buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + length);
+          }
+
+          // if we're emulating a connection-less dgram socket and don't have
+          // a cached connection, queue the buffer to send upon connect and
+          // lie, saying the data was sent now.
+          if (sock.type === 2) {
+            if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
+              // if we're not connected, open a new connection
+              if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+              }
+              dest.dgram_send_queue.push(data);
+              return length;
+            }
+          }
+
+          try {
+            // send the actual data
+            dest.socket.send(data);
+            return length;
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+        },recvmsg:function (sock, length) {
+          // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
+          if (sock.type === 1 && sock.server) {
+            // tcp servers should not be recv()'ing on the listen socket
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+          }
+
+          var queued = sock.recv_queue.shift();
+          if (!queued) {
+            if (sock.type === 1) {
+              var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+
+              if (!dest) {
+                // if we have a destination address but are not connected, error out
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+              }
+              else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                // return null if the socket has closed
+                return null;
+              }
+              else {
+                // else, our socket is in a valid state but truly has nothing available
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+            } else {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
+          // requeued TCP data it'll be an ArrayBufferView
+          var queuedLength = queued.data.byteLength || queued.data.length;
+          var queuedOffset = queued.data.byteOffset || 0;
+          var queuedBuffer = queued.data.buffer || queued.data;
+          var bytesRead = Math.min(length, queuedLength);
+          var res = {
+            buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
+            addr: queued.addr,
+            port: queued.port
+          };
+
+
+          // push back any unread data for TCP connections
+          if (sock.type === 1 && bytesRead < queuedLength) {
+            var bytesRemaining = queuedLength - bytesRead;
+            queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
+            sock.recv_queue.unshift(queued);
+          }
+
+          return res;
+        }}};function _send(fd, buf, len, flags) {
+      var sock = SOCKFS.getSocket(fd);
+      if (!sock) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      // TODO honor flags
+      return _write(fd, buf, len);
+    }
+
+  function _pwrite(fildes, buf, nbyte, offset) {
+      // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte, offset);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _write(fildes, buf, nbyte) {
+      // ssize_t write(int fildes, const void *buf, size_t nbyte);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+
+
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }
+
+  function _fileno(stream) {
+      // int fileno(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
+      stream = FS.getStreamFromPtr(stream);
+      if (!stream) return -1;
+      return stream.fd;
+    }function _fwrite(ptr, size, nitems, stream) {
+      // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
+      var bytesToWrite = nitems * size;
+      if (bytesToWrite == 0) return 0;
+      var fd = _fileno(stream);
+      var bytesWritten = _write(fd, ptr, bytesToWrite);
+      if (bytesWritten == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return 0;
+      } else {
+        return Math.floor(bytesWritten / size);
+      }
+    }
+
+
+
+  Module["_strlen"] = _strlen;
+
+  function __reallyNegative(x) {
+      return x < 0 || (x === 0 && (1/x) === -Infinity);
+    }function __formatString(format, varargs) {
+      var textIndex = format;
+      var argIndex = 0;
+      function getNextArg(type) {
+        // NOTE: Explicitly ignoring type safety. Otherwise this fails:
+        //       int x = 4; printf("%c\n", (char)x);
+        var ret;
+        if (type === 'double') {
+          ret = HEAPF64[(((varargs)+(argIndex))>>3)];
+        } else if (type == 'i64') {
+          ret = [HEAP32[(((varargs)+(argIndex))>>2)],
+                 HEAP32[(((varargs)+(argIndex+4))>>2)]];
+
+        } else {
+          type = 'i32'; // varargs are always i32, i64, or double
+          ret = HEAP32[(((varargs)+(argIndex))>>2)];
+        }
+        argIndex += Runtime.getNativeFieldSize(type);
+        return ret;
+      }
+
+      var ret = [];
+      var curr, next, currArg;
+      while(1) {
+        var startTextIndex = textIndex;
+        curr = HEAP8[(textIndex)];
+        if (curr === 0) break;
+        next = HEAP8[((textIndex+1)|0)];
+        if (curr == 37) {
+          // Handle flags.
+          var flagAlwaysSigned = false;
+          var flagLeftAlign = false;
+          var flagAlternative = false;
+          var flagZeroPad = false;
+          var flagPadSign = false;
+          flagsLoop: while (1) {
+            switch (next) {
+              case 43:
+                flagAlwaysSigned = true;
+                break;
+              case 45:
+                flagLeftAlign = true;
+                break;
+              case 35:
+                flagAlternative = true;
+                break;
+              case 48:
+                if (flagZeroPad) {
+                  break flagsLoop;
+                } else {
+                  flagZeroPad = true;
+                  break;
+                }
+              case 32:
+                flagPadSign = true;
+                break;
+              default:
+                break flagsLoop;
+            }
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          }
+
+          // Handle width.
+          var width = 0;
+          if (next == 42) {
+            width = getNextArg('i32');
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          } else {
+            while (next >= 48 && next <= 57) {
+              width = width * 10 + (next - 48);
+              textIndex++;
+              next = HEAP8[((textIndex+1)|0)];
+            }
+          }
+
+          // Handle precision.
+          var precisionSet = false, precision = -1;
+          if (next == 46) {
+            precision = 0;
+            precisionSet = true;
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+            if (next == 42) {
+              precision = getNextArg('i32');
+              textIndex++;
+            } else {
+              while(1) {
+                var precisionChr = HEAP8[((textIndex+1)|0)];
+                if (precisionChr < 48 ||
+                    precisionChr > 57) break;
+                precision = precision * 10 + (precisionChr - 48);
+                textIndex++;
+              }
+            }
+            next = HEAP8[((textIndex+1)|0)];
+          }
+          if (precision < 0) {
+            precision = 6; // Standard default.
+            precisionSet = false;
+          }
+
+          // Handle integer sizes. WARNING: These assume a 32-bit architecture!
+          var argSize;
+          switch (String.fromCharCode(next)) {
+            case 'h':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 104) {
+                textIndex++;
+                argSize = 1; // char (actually i32 in varargs)
+              } else {
+                argSize = 2; // short (actually i32 in varargs)
+              }
+              break;
+            case 'l':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 108) {
+                textIndex++;
+                argSize = 8; // long long
+              } else {
+                argSize = 4; // long
+              }
+              break;
+            case 'L': // long long
+            case 'q': // int64_t
+            case 'j': // intmax_t
+              argSize = 8;
+              break;
+            case 'z': // size_t
+            case 't': // ptrdiff_t
+            case 'I': // signed ptrdiff_t or unsigned size_t
+              argSize = 4;
+              break;
+            default:
+              argSize = null;
+          }
+          if (argSize) textIndex++;
+          next = HEAP8[((textIndex+1)|0)];
+
+          // Handle type specifier.
+          switch (String.fromCharCode(next)) {
+            case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': {
+              // Integer.
+              var signed = next == 100 || next == 105;
+              argSize = argSize || 4;
+              var currArg = getNextArg('i' + (argSize * 8));
+              var argText;
+              // Flatten i64-1 [low, high] into a (slightly rounded) double
+              if (argSize == 8) {
+                currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117);
+              }
+              // Truncate to requested size.
+              if (argSize <= 4) {
+                var limit = Math.pow(256, argSize) - 1;
+                currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
+              }
+              // Format the number.
+              var currAbsArg = Math.abs(currArg);
+              var prefix = '';
+              if (next == 100 || next == 105) {
+                argText = reSign(currArg, 8 * argSize, 1).toString(10);
+              } else if (next == 117) {
+                argText = unSign(currArg, 8 * argSize, 1).toString(10);
+                currArg = Math.abs(currArg);
+              } else if (next == 111) {
+                argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
+              } else if (next == 120 || next == 88) {
+                prefix = (flagAlternative && currArg != 0) ? '0x' : '';
+                if (currArg < 0) {
+                  // Represent negative numbers in hex as 2's complement.
+                  currArg = -currArg;
+                  argText = (currAbsArg - 1).toString(16);
+                  var buffer = [];
+                  for (var i = 0; i < argText.length; i++) {
+                    buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
+                  }
+                  argText = buffer.join('');
+                  while (argText.length < argSize * 2) argText = 'f' + argText;
+                } else {
+                  argText = currAbsArg.toString(16);
+                }
+                if (next == 88) {
+                  prefix = prefix.toUpperCase();
+                  argText = argText.toUpperCase();
+                }
+              } else if (next == 112) {
+                if (currAbsArg === 0) {
+                  argText = '(nil)';
+                } else {
+                  prefix = '0x';
+                  argText = currAbsArg.toString(16);
+                }
+              }
+              if (precisionSet) {
+                while (argText.length < precision) {
+                  argText = '0' + argText;
+                }
+              }
+
+              // Add sign if needed
+              if (currArg >= 0) {
+                if (flagAlwaysSigned) {
+                  prefix = '+' + prefix;
+                } else if (flagPadSign) {
+                  prefix = ' ' + prefix;
+                }
+              }
+
+              // Move sign to prefix so we zero-pad after the sign
+              if (argText.charAt(0) == '-') {
+                prefix = '-' + prefix;
+                argText = argText.substr(1);
+              }
+
+              // Add padding.
+              while (prefix.length + argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad) {
+                    argText = '0' + argText;
+                  } else {
+                    prefix = ' ' + prefix;
+                  }
+                }
+              }
+
+              // Insert the result into the buffer.
+              argText = prefix + argText;
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': {
+              // Float.
+              var currArg = getNextArg('double');
+              var argText;
+              if (isNaN(currArg)) {
+                argText = 'nan';
+                flagZeroPad = false;
+              } else if (!isFinite(currArg)) {
+                argText = (currArg < 0 ? '-' : '') + 'inf';
+                flagZeroPad = false;
+              } else {
+                var isGeneral = false;
+                var effectivePrecision = Math.min(precision, 20);
+
+                // Convert g/G to f/F or e/E, as per:
+                // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
+                if (next == 103 || next == 71) {
+                  isGeneral = true;
+                  precision = precision || 1;
+                  var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
+                  if (precision > exponent && exponent >= -4) {
+                    next = ((next == 103) ? 'f' : 'F').charCodeAt(0);
+                    precision -= exponent + 1;
+                  } else {
+                    next = ((next == 103) ? 'e' : 'E').charCodeAt(0);
+                    precision--;
+                  }
+                  effectivePrecision = Math.min(precision, 20);
+                }
+
+                if (next == 101 || next == 69) {
+                  argText = currArg.toExponential(effectivePrecision);
+                  // Make sure the exponent has at least 2 digits.
+                  if (/[eE][-+]\d$/.test(argText)) {
+                    argText = argText.slice(0, -1) + '0' + argText.slice(-1);
+                  }
+                } else if (next == 102 || next == 70) {
+                  argText = currArg.toFixed(effectivePrecision);
+                  if (currArg === 0 && __reallyNegative(currArg)) {
+                    argText = '-' + argText;
+                  }
+                }
+
+                var parts = argText.split('e');
+                if (isGeneral && !flagAlternative) {
+                  // Discard trailing zeros and periods.
+                  while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
+                         (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
+                    parts[0] = parts[0].slice(0, -1);
+                  }
+                } else {
+                  // Make sure we have a period in alternative mode.
+                  if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
+                  // Zero pad until required precision.
+                  while (precision > effectivePrecision++) parts[0] += '0';
+                }
+                argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
+
+                // Capitalize 'E' if needed.
+                if (next == 69) argText = argText.toUpperCase();
+
+                // Add sign.
+                if (currArg >= 0) {
+                  if (flagAlwaysSigned) {
+                    argText = '+' + argText;
+                  } else if (flagPadSign) {
+                    argText = ' ' + argText;
+                  }
+                }
+              }
+
+              // Add padding.
+              while (argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
+                    argText = argText[0] + '0' + argText.slice(1);
+                  } else {
+                    argText = (flagZeroPad ? '0' : ' ') + argText;
+                  }
+                }
+              }
+
+              // Adjust case.
+              if (next < 97) argText = argText.toUpperCase();
+
+              // Insert the result into the buffer.
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 's': {
+              // String.
+              var arg = getNextArg('i8*');
+              var argLength = arg ? _strlen(arg) : '(null)'.length;
+              if (precisionSet) argLength = Math.min(argLength, precision);
+              if (!flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              if (arg) {
+                for (var i = 0; i < argLength; i++) {
+                  ret.push(HEAPU8[((arg++)|0)]);
+                }
+              } else {
+                ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true));
+              }
+              if (flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              break;
+            }
+            case 'c': {
+              // Character.
+              if (flagLeftAlign) ret.push(getNextArg('i8'));
+              while (--width > 0) {
+                ret.push(32);
+              }
+              if (!flagLeftAlign) ret.push(getNextArg('i8'));
+              break;
+            }
+            case 'n': {
+              // Write the length written so far to the next parameter.
+              var ptr = getNextArg('i32*');
+              HEAP32[((ptr)>>2)]=ret.length;
+              break;
+            }
+            case '%': {
+              // Literal percent sign.
+              ret.push(curr);
+              break;
+            }
+            default: {
+              // Unknown specifiers remain untouched.
+              for (var i = startTextIndex; i < textIndex + 2; i++) {
+                ret.push(HEAP8[(i)]);
+              }
+            }
+          }
+          textIndex += 2;
+          // TODO: Support a/A (hex float) and m (last error) specifiers.
+          // TODO: Support %1${specifier} for arg selection.
+        } else {
+          ret.push(curr);
+          textIndex += 1;
+        }
+      }
+      return ret;
+    }function _fprintf(stream, format, varargs) {
+      // int fprintf(FILE *restrict stream, const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var result = __formatString(format, varargs);
+      var stack = Runtime.stackSave();
+      var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream);
+      Runtime.stackRestore(stack);
+      return ret;
+    }function _printf(format, varargs) {
+      // int printf(const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var stdout = HEAP32[((_stdout)>>2)];
+      return _fprintf(stdout, format, varargs);
+    }
+
+
+  var _sqrtf=Math_sqrt;
+Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };
+  Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
+  Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
+  Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
+  Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
+  Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }
+FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice;
+___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0;
+__ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor();
+if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); }
+__ATINIT__.push({ func: function() { SOCKFS.root = FS.mount(SOCKFS, {}, null); } });
+STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);
+
+staticSealed = true; // seal the static portion of memory
+
+STACK_MAX = STACK_BASE + 5242880;
+
+DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);
+
+assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");
+
+
+var Math_min = Math.min;
+function asmPrintInt(x, y) {
+  Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+function asmPrintFloat(x, y) {
+  Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+// EMSCRIPTEN_START_ASM
+var asm = (function(global, env, buffer) {
+  'use asm';
+  var HEAP8 = new global.Int8Array(buffer);
+  var HEAP16 = new global.Int16Array(buffer);
+  var HEAP32 = new global.Int32Array(buffer);
+  var HEAPU8 = new global.Uint8Array(buffer);
+  var HEAPU16 = new global.Uint16Array(buffer);
+  var HEAPU32 = new global.Uint32Array(buffer);
+  var HEAPF32 = new global.Float32Array(buffer);
+  var HEAPF64 = new global.Float64Array(buffer);
+
+  var STACKTOP=env.STACKTOP|0;
+  var STACK_MAX=env.STACK_MAX|0;
+  var tempDoublePtr=env.tempDoublePtr|0;
+  var ABORT=env.ABORT|0;
+
+  var __THREW__ = 0;
+  var threwValue = 0;
+  var setjmpId = 0;
+  var undef = 0;
+  var nan = +env.NaN, inf = +env.Infinity;
+  var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
+
+  var tempRet0 = 0;
+  var tempRet1 = 0;
+  var tempRet2 = 0;
+  var tempRet3 = 0;
+  var tempRet4 = 0;
+  var tempRet5 = 0;
+  var tempRet6 = 0;
+  var tempRet7 = 0;
+  var tempRet8 = 0;
+  var tempRet9 = 0;
+  var Math_floor=global.Math.floor;
+  var Math_abs=global.Math.abs;
+  var Math_sqrt=global.Math.sqrt;
+  var Math_pow=global.Math.pow;
+  var Math_cos=global.Math.cos;
+  var Math_sin=global.Math.sin;
+  var Math_tan=global.Math.tan;
+  var Math_acos=global.Math.acos;
+  var Math_asin=global.Math.asin;
+  var Math_atan=global.Math.atan;
+  var Math_atan2=global.Math.atan2;
+  var Math_exp=global.Math.exp;
+  var Math_log=global.Math.log;
+  var Math_ceil=global.Math.ceil;
+  var Math_imul=global.Math.imul;
+  var abort=env.abort;
+  var assert=env.assert;
+  var asmPrintInt=env.asmPrintInt;
+  var asmPrintFloat=env.asmPrintFloat;
+  var Math_min=env.min;
+  var _free=env._free;
+  var _emscripten_memcpy_big=env._emscripten_memcpy_big;
+  var _printf=env._printf;
+  var _send=env._send;
+  var _pwrite=env._pwrite;
+  var _sqrtf=env._sqrtf;
+  var __reallyNegative=env.__reallyNegative;
+  var _fwrite=env._fwrite;
+  var _malloc=env._malloc;
+  var _mkport=env._mkport;
+  var _fprintf=env._fprintf;
+  var ___setErrNo=env.___setErrNo;
+  var __formatString=env.__formatString;
+  var _fileno=env._fileno;
+  var _fflush=env._fflush;
+  var _write=env._write;
+  var tempFloat = 0.0;
+
+// EMSCRIPTEN_START_FUNCS
+function _main(i3, i5) {
+ i3 = i3 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i6 = 0, i7 = 0, d8 = 0.0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i1;
+ L1 : do {
+  if ((i3 | 0) > 1) {
+   i3 = HEAP8[HEAP32[i5 + 4 >> 2] | 0] | 0;
+   switch (i3 | 0) {
+   case 50:
+    {
+     i3 = 13e4;
+     break L1;
+    }
+   case 51:
+    {
+     i4 = 4;
+     break L1;
+    }
+   case 52:
+    {
+     i3 = 61e4;
+     break L1;
+    }
+   case 53:
+    {
+     i3 = 101e4;
+     break L1;
+    }
+   case 49:
+    {
+     i3 = 33e3;
+     break L1;
+    }
+   case 48:
+    {
+     i7 = 0;
+     STACKTOP = i1;
+     return i7 | 0;
+    }
+   default:
+    {
+     HEAP32[i2 >> 2] = i3 + -48;
+     _printf(8, i2 | 0) | 0;
+     i7 = -1;
+     STACKTOP = i1;
+     return i7 | 0;
+    }
+   }
+  } else {
+   i4 = 4;
+  }
+ } while (0);
+ if ((i4 | 0) == 4) {
+  i3 = 22e4;
+ }
+ i4 = 2;
+ i5 = 0;
+ while (1) {
+  d8 = +Math_sqrt(+(+(i4 | 0)));
+  L15 : do {
+   if (d8 > 2.0) {
+    i7 = 2;
+    while (1) {
+     i6 = i7 + 1 | 0;
+     if (((i4 | 0) % (i7 | 0) | 0 | 0) == 0) {
+      i6 = 0;
+      break L15;
+     }
+     if (+(i6 | 0) < d8) {
+      i7 = i6;
+     } else {
+      i6 = 1;
+      break;
+     }
+    }
+   } else {
+    i6 = 1;
+   }
+  } while (0);
+  i5 = i6 + i5 | 0;
+  if ((i5 | 0) >= (i3 | 0)) {
+   break;
+  } else {
+   i4 = i4 + 1 | 0;
+  }
+ }
+ HEAP32[i2 >> 2] = i4;
+ _printf(24, i2 | 0) | 0;
+ i7 = 0;
+ STACKTOP = i1;
+ return i7 | 0;
+}
+function _memcpy(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ if ((i1 | 0) >= 4096) return _emscripten_memcpy_big(i3 | 0, i2 | 0, i1 | 0) | 0;
+ i4 = i3 | 0;
+ if ((i3 & 3) == (i2 & 3)) {
+  while (i3 & 3) {
+   if ((i1 | 0) == 0) return i4 | 0;
+   HEAP8[i3] = HEAP8[i2] | 0;
+   i3 = i3 + 1 | 0;
+   i2 = i2 + 1 | 0;
+   i1 = i1 - 1 | 0;
+  }
+  while ((i1 | 0) >= 4) {
+   HEAP32[i3 >> 2] = HEAP32[i2 >> 2];
+   i3 = i3 + 4 | 0;
+   i2 = i2 + 4 | 0;
+   i1 = i1 - 4 | 0;
+  }
+ }
+ while ((i1 | 0) > 0) {
+  HEAP8[i3] = HEAP8[i2] | 0;
+  i3 = i3 + 1 | 0;
+  i2 = i2 + 1 | 0;
+  i1 = i1 - 1 | 0;
+ }
+ return i4 | 0;
+}
+function runPostSets() {}
+function _memset(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = i1 + i3 | 0;
+ if ((i3 | 0) >= 20) {
+  i4 = i4 & 255;
+  i7 = i1 & 3;
+  i6 = i4 | i4 << 8 | i4 << 16 | i4 << 24;
+  i5 = i2 & ~3;
+  if (i7) {
+   i7 = i1 + 4 - i7 | 0;
+   while ((i1 | 0) < (i7 | 0)) {
+    HEAP8[i1] = i4;
+    i1 = i1 + 1 | 0;
+   }
+  }
+  while ((i1 | 0) < (i5 | 0)) {
+   HEAP32[i1 >> 2] = i6;
+   i1 = i1 + 4 | 0;
+  }
+ }
+ while ((i1 | 0) < (i2 | 0)) {
+  HEAP8[i1] = i4;
+  i1 = i1 + 1 | 0;
+ }
+ return i1 - i3 | 0;
+}
+function copyTempDouble(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+ HEAP8[tempDoublePtr + 4 | 0] = HEAP8[i1 + 4 | 0];
+ HEAP8[tempDoublePtr + 5 | 0] = HEAP8[i1 + 5 | 0];
+ HEAP8[tempDoublePtr + 6 | 0] = HEAP8[i1 + 6 | 0];
+ HEAP8[tempDoublePtr + 7 | 0] = HEAP8[i1 + 7 | 0];
+}
+function copyTempFloat(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+}
+function stackAlloc(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + i1 | 0;
+ STACKTOP = STACKTOP + 7 & -8;
+ return i2 | 0;
+}
+function _strlen(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = i1;
+ while (HEAP8[i2] | 0) {
+  i2 = i2 + 1 | 0;
+ }
+ return i2 - i1 | 0;
+}
+function setThrew(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ if ((__THREW__ | 0) == 0) {
+  __THREW__ = i1;
+  threwValue = i2;
+ }
+}
+function stackRestore(i1) {
+ i1 = i1 | 0;
+ STACKTOP = i1;
+}
+function setTempRet9(i1) {
+ i1 = i1 | 0;
+ tempRet9 = i1;
+}
+function setTempRet8(i1) {
+ i1 = i1 | 0;
+ tempRet8 = i1;
+}
+function setTempRet7(i1) {
+ i1 = i1 | 0;
+ tempRet7 = i1;
+}
+function setTempRet6(i1) {
+ i1 = i1 | 0;
+ tempRet6 = i1;
+}
+function setTempRet5(i1) {
+ i1 = i1 | 0;
+ tempRet5 = i1;
+}
+function setTempRet4(i1) {
+ i1 = i1 | 0;
+ tempRet4 = i1;
+}
+function setTempRet3(i1) {
+ i1 = i1 | 0;
+ tempRet3 = i1;
+}
+function setTempRet2(i1) {
+ i1 = i1 | 0;
+ tempRet2 = i1;
+}
+function setTempRet1(i1) {
+ i1 = i1 | 0;
+ tempRet1 = i1;
+}
+function setTempRet0(i1) {
+ i1 = i1 | 0;
+ tempRet0 = i1;
+}
+function stackSave() {
+ return STACKTOP | 0;
+}
+
+// EMSCRIPTEN_END_FUNCS
+
+
+  return { _strlen: _strlen, _memcpy: _memcpy, _main: _main, _memset: _memset, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, setTempRet1: setTempRet1, setTempRet2: setTempRet2, setTempRet3: setTempRet3, setTempRet4: setTempRet4, setTempRet5: setTempRet5, setTempRet6: setTempRet6, setTempRet7: setTempRet7, setTempRet8: setTempRet8, setTempRet9: setTempRet9 };
+})
+// EMSCRIPTEN_END_ASM
+({ "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array }, { "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "_free": _free, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_printf": _printf, "_send": _send, "_pwrite": _pwrite, "_sqrtf": _sqrtf, "__reallyNegative": __reallyNegative, "_fwrite": _fwrite, "_malloc": _malloc, "_mkport": _mkport, "_fprintf": _fprintf, "___setErrNo": ___setErrNo, "__formatString": __formatString, "_fileno": _fileno, "_fflush": _fflush, "_write": _write, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "NaN": NaN, "Infinity": Infinity }, buffer);
+var _strlen = Module["_strlen"] = asm["_strlen"];
+var _memcpy = Module["_memcpy"] = asm["_memcpy"];
+var _main = Module["_main"] = asm["_main"];
+var _memset = Module["_memset"] = asm["_memset"];
+var runPostSets = Module["runPostSets"] = asm["runPostSets"];
+
+Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
+Runtime.stackSave = function() { return asm['stackSave']() };
+Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
+
+
+// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included
+var i64Math = null;
+
+// === Auto-generated postamble setup entry stuff ===
+
+if (memoryInitializer) {
+  if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
+    var data = Module['readBinary'](memoryInitializer);
+    HEAPU8.set(data, STATIC_BASE);
+  } else {
+    addRunDependency('memory initializer');
+    Browser.asyncLoad(memoryInitializer, function(data) {
+      HEAPU8.set(data, STATIC_BASE);
+      removeRunDependency('memory initializer');
+    }, function(data) {
+      throw 'could not load memory initializer ' + memoryInitializer;
+    });
+  }
+}
+
+function ExitStatus(status) {
+  this.name = "ExitStatus";
+  this.message = "Program terminated with exit(" + status + ")";
+  this.status = status;
+};
+ExitStatus.prototype = new Error();
+ExitStatus.prototype.constructor = ExitStatus;
+
+var initialStackTop;
+var preloadStartTime = null;
+var calledMain = false;
+
+dependenciesFulfilled = function runCaller() {
+  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
+  if (!Module['calledRun'] && shouldRunNow) run([].concat(Module["arguments"]));
+  if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
+}
+
+Module['callMain'] = Module.callMain = function callMain(args) {
+  assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
+  assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
+
+  args = args || [];
+
+  ensureInitRuntime();
+
+  var argc = args.length+1;
+  function pad() {
+    for (var i = 0; i < 4-1; i++) {
+      argv.push(0);
+    }
+  }
+  var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ];
+  pad();
+  for (var i = 0; i < argc-1; i = i + 1) {
+    argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL));
+    pad();
+  }
+  argv.push(0);
+  argv = allocate(argv, 'i32', ALLOC_NORMAL);
+
+  initialStackTop = STACKTOP;
+
+  try {
+
+    var ret = Module['_main'](argc, argv, 0);
+
+
+    // if we're not running an evented main loop, it's time to exit
+    if (!Module['noExitRuntime']) {
+      exit(ret);
+    }
+  }
+  catch(e) {
+    if (e instanceof ExitStatus) {
+      // exit() throws this once it's done to make sure execution
+      // has been stopped completely
+      return;
+    } else if (e == 'SimulateInfiniteLoop') {
+      // running an evented main loop, don't immediately exit
+      Module['noExitRuntime'] = true;
+      return;
+    } else {
+      if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
+      throw e;
+    }
+  } finally {
+    calledMain = true;
+  }
+}
+
+
+
+
+function run(args) {
+  args = args || Module['arguments'];
+
+  if (preloadStartTime === null) preloadStartTime = Date.now();
+
+  if (runDependencies > 0) {
+    Module.printErr('run() called, but dependencies remain, so not running');
+    return;
+  }
+
+  preRun();
+
+  if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
+  if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
+
+  function doRun() {
+    if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
+    Module['calledRun'] = true;
+
+    ensureInitRuntime();
+
+    preMain();
+
+    if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
+      Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
+    }
+
+    if (Module['_main'] && shouldRunNow) {
+      Module['callMain'](args);
+    }
+
+    postRun();
+  }
+
+  if (Module['setStatus']) {
+    Module['setStatus']('Running...');
+    setTimeout(function() {
+      setTimeout(function() {
+        Module['setStatus']('');
+      }, 1);
+      if (!ABORT) doRun();
+    }, 1);
+  } else {
+    doRun();
+  }
+}
+Module['run'] = Module.run = run;
+
+function exit(status) {
+  ABORT = true;
+  EXITSTATUS = status;
+  STACKTOP = initialStackTop;
+
+  // exit the runtime
+  exitRuntime();
+
+  // TODO We should handle this differently based on environment.
+  // In the browser, the best we can do is throw an exception
+  // to halt execution, but in node we could process.exit and
+  // I'd imagine SM shell would have something equivalent.
+  // This would let us set a proper exit status (which
+  // would be great for checking test exit statuses).
+  // https://github.com/kripken/emscripten/issues/1371
+
+  // throw an exception to halt the current execution
+  throw new ExitStatus(status);
+}
+Module['exit'] = Module.exit = exit;
+
+function abort(text) {
+  if (text) {
+    Module.print(text);
+    Module.printErr(text);
+  }
+
+  ABORT = true;
+  EXITSTATUS = 1;
+
+  var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.';
+
+  throw 'abort() at ' + stackTrace() + extra;
+}
+Module['abort'] = Module.abort = abort;
+
+// {{PRE_RUN_ADDITIONS}}
+
+if (Module['preInit']) {
+  if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
+  while (Module['preInit'].length > 0) {
+    Module['preInit'].pop()();
+  }
+}
+
+// shouldRunNow refers to calling main(), not run().
+var shouldRunNow = true;
+if (Module['noInitialRun']) {
+  shouldRunNow = false;
+}
+
+
+run([].concat(Module["arguments"]));
diff --git a/test/mjsunit/asm/embenchen/zlib.js b/test/mjsunit/asm/embenchen/zlib.js
new file mode 100644
index 0000000..d90ee38
--- /dev/null
+++ b/test/mjsunit/asm/embenchen/zlib.js
@@ -0,0 +1,14752 @@
+var EXPECTED_OUTPUT = 'sizes: 100000,25906\nok.\n';
+var Module = {
+  arguments: [1],
+  print: function(x) {Module.printBuffer += x + '\n';},
+  preRun: [function() {Module.printBuffer = ''}],
+  postRun: [function() {
+    assertEquals(EXPECTED_OUTPUT, Module.printBuffer);
+  }],
+};
+// The Module object: Our interface to the outside world. We import
+// and export values on it, and do the work to get that through
+// closure compiler if necessary. There are various ways Module can be used:
+// 1. Not defined. We create it here
+// 2. A function parameter, function(Module) { ..generated code.. }
+// 3. pre-run appended it, var Module = {}; ..generated code..
+// 4. External script tag defines var Module.
+// We need to do an eval in order to handle the closure compiler
+// case, where this code here is minified but Module was defined
+// elsewhere (e.g. case 4 above). We also need to check if Module
+// already exists (e.g. case 3 above).
+// Note that if you want to run closure, and also to use Module
+// after the generated code, you will need to define   var Module = {};
+// before the code. Then that object will be used in the code, and you
+// can continue to use Module afterwards as well.
+var Module;
+if (!Module) Module = (typeof Module !== 'undefined' ? Module : null) || {};
+
+// Sometimes an existing Module object exists with properties
+// meant to overwrite the default module functionality. Here
+// we collect those properties and reapply _after_ we configure
+// the current environment's defaults to avoid having to be so
+// defensive during initialization.
+var moduleOverrides = {};
+for (var key in Module) {
+  if (Module.hasOwnProperty(key)) {
+    moduleOverrides[key] = Module[key];
+  }
+}
+
+// The environment setup code below is customized to use Module.
+// *** Environment setup code ***
+var ENVIRONMENT_IS_NODE = typeof process === 'object' && typeof require === 'function';
+var ENVIRONMENT_IS_WEB = typeof window === 'object';
+var ENVIRONMENT_IS_WORKER = typeof importScripts === 'function';
+var ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;
+
+if (ENVIRONMENT_IS_NODE) {
+  // Expose functionality in the same simple way that the shells work
+  // Note that we pollute the global namespace here, otherwise we break in node
+  if (!Module['print']) Module['print'] = function print(x) {
+    process['stdout'].write(x + '\n');
+  };
+  if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+    process['stderr'].write(x + '\n');
+  };
+
+  var nodeFS = require('fs');
+  var nodePath = require('path');
+
+  Module['read'] = function read(filename, binary) {
+    filename = nodePath['normalize'](filename);
+    var ret = nodeFS['readFileSync'](filename);
+    // The path is absolute if the normalized version is the same as the resolved.
+    if (!ret && filename != nodePath['resolve'](filename)) {
+      filename = path.join(__dirname, '..', 'src', filename);
+      ret = nodeFS['readFileSync'](filename);
+    }
+    if (ret && !binary) ret = ret.toString();
+    return ret;
+  };
+
+  Module['readBinary'] = function readBinary(filename) { return Module['read'](filename, true) };
+
+  Module['load'] = function load(f) {
+    globalEval(read(f));
+  };
+
+  Module['arguments'] = process['argv'].slice(2);
+
+  module['exports'] = Module;
+}
+else if (ENVIRONMENT_IS_SHELL) {
+  if (!Module['print']) Module['print'] = print;
+  if (typeof printErr != 'undefined') Module['printErr'] = printErr; // not present in v8 or older sm
+
+  if (typeof read != 'undefined') {
+    Module['read'] = read;
+  } else {
+    Module['read'] = function read() { throw 'no read() available (jsc?)' };
+  }
+
+  Module['readBinary'] = function readBinary(f) {
+    return read(f, 'binary');
+  };
+
+  if (typeof scriptArgs != 'undefined') {
+    Module['arguments'] = scriptArgs;
+  } else if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  this['Module'] = Module;
+
+  eval("if (typeof gc === 'function' && gc.toString().indexOf('[native code]') > 0) var gc = undefined"); // wipe out the SpiderMonkey shell 'gc' function, which can confuse closure (uses it as a minified name, and it is then initted to a non-falsey value unexpectedly)
+}
+else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {
+  Module['read'] = function read(url) {
+    var xhr = new XMLHttpRequest();
+    xhr.open('GET', url, false);
+    xhr.send(null);
+    return xhr.responseText;
+  };
+
+  if (typeof arguments != 'undefined') {
+    Module['arguments'] = arguments;
+  }
+
+  if (typeof console !== 'undefined') {
+    if (!Module['print']) Module['print'] = function print(x) {
+      console.log(x);
+    };
+    if (!Module['printErr']) Module['printErr'] = function printErr(x) {
+      console.log(x);
+    };
+  } else {
+    // Probably a worker, and without console.log. We can do very little here...
+    var TRY_USE_DUMP = false;
+    if (!Module['print']) Module['print'] = (TRY_USE_DUMP && (typeof(dump) !== "undefined") ? (function(x) {
+      dump(x);
+    }) : (function(x) {
+      // self.postMessage(x); // enable this if you want stdout to be sent as messages
+    }));
+  }
+
+  if (ENVIRONMENT_IS_WEB) {
+    window['Module'] = Module;
+  } else {
+    Module['load'] = importScripts;
+  }
+}
+else {
+  // Unreachable because SHELL is dependant on the others
+  throw 'Unknown runtime environment. Where are we?';
+}
+
+function globalEval(x) {
+  eval.call(null, x);
+}
+if (!Module['load'] == 'undefined' && Module['read']) {
+  Module['load'] = function load(f) {
+    globalEval(Module['read'](f));
+  };
+}
+if (!Module['print']) {
+  Module['print'] = function(){};
+}
+if (!Module['printErr']) {
+  Module['printErr'] = Module['print'];
+}
+if (!Module['arguments']) {
+  Module['arguments'] = [];
+}
+// *** Environment setup code ***
+
+// Closure helpers
+Module.print = Module['print'];
+Module.printErr = Module['printErr'];
+
+// Callbacks
+Module['preRun'] = [];
+Module['postRun'] = [];
+
+// Merge back in the overrides
+for (var key in moduleOverrides) {
+  if (moduleOverrides.hasOwnProperty(key)) {
+    Module[key] = moduleOverrides[key];
+  }
+}
+
+
+
+// === Auto-generated preamble library stuff ===
+
+//========================================
+// Runtime code shared with compiler
+//========================================
+
+var Runtime = {
+  stackSave: function () {
+    return STACKTOP;
+  },
+  stackRestore: function (stackTop) {
+    STACKTOP = stackTop;
+  },
+  forceAlign: function (target, quantum) {
+    quantum = quantum || 4;
+    if (quantum == 1) return target;
+    if (isNumber(target) && isNumber(quantum)) {
+      return Math.ceil(target/quantum)*quantum;
+    } else if (isNumber(quantum) && isPowerOfTwo(quantum)) {
+      return '(((' +target + ')+' + (quantum-1) + ')&' + -quantum + ')';
+    }
+    return 'Math.ceil((' + target + ')/' + quantum + ')*' + quantum;
+  },
+  isNumberType: function (type) {
+    return type in Runtime.INT_TYPES || type in Runtime.FLOAT_TYPES;
+  },
+  isPointerType: function isPointerType(type) {
+  return type[type.length-1] == '*';
+},
+  isStructType: function isStructType(type) {
+  if (isPointerType(type)) return false;
+  if (isArrayType(type)) return true;
+  if (/<?\{ ?[^}]* ?\}>?/.test(type)) return true; // { i32, i8 } etc. - anonymous struct types
+  // See comment in isStructPointerType()
+  return type[0] == '%';
+},
+  INT_TYPES: {"i1":0,"i8":0,"i16":0,"i32":0,"i64":0},
+  FLOAT_TYPES: {"float":0,"double":0},
+  or64: function (x, y) {
+    var l = (x | 0) | (y | 0);
+    var h = (Math.round(x / 4294967296) | Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  and64: function (x, y) {
+    var l = (x | 0) & (y | 0);
+    var h = (Math.round(x / 4294967296) & Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  xor64: function (x, y) {
+    var l = (x | 0) ^ (y | 0);
+    var h = (Math.round(x / 4294967296) ^ Math.round(y / 4294967296)) * 4294967296;
+    return l + h;
+  },
+  getNativeTypeSize: function (type) {
+    switch (type) {
+      case 'i1': case 'i8': return 1;
+      case 'i16': return 2;
+      case 'i32': return 4;
+      case 'i64': return 8;
+      case 'float': return 4;
+      case 'double': return 8;
+      default: {
+        if (type[type.length-1] === '*') {
+          return Runtime.QUANTUM_SIZE; // A pointer
+        } else if (type[0] === 'i') {
+          var bits = parseInt(type.substr(1));
+          assert(bits % 8 === 0);
+          return bits/8;
+        } else {
+          return 0;
+        }
+      }
+    }
+  },
+  getNativeFieldSize: function (type) {
+    return Math.max(Runtime.getNativeTypeSize(type), Runtime.QUANTUM_SIZE);
+  },
+  dedup: function dedup(items, ident) {
+  var seen = {};
+  if (ident) {
+    return items.filter(function(item) {
+      if (seen[item[ident]]) return false;
+      seen[item[ident]] = true;
+      return true;
+    });
+  } else {
+    return items.filter(function(item) {
+      if (seen[item]) return false;
+      seen[item] = true;
+      return true;
+    });
+  }
+},
+  set: function set() {
+  var args = typeof arguments[0] === 'object' ? arguments[0] : arguments;
+  var ret = {};
+  for (var i = 0; i < args.length; i++) {
+    ret[args[i]] = 0;
+  }
+  return ret;
+},
+  STACK_ALIGN: 8,
+  getAlignSize: function (type, size, vararg) {
+    // we align i64s and doubles on 64-bit boundaries, unlike x86
+    if (!vararg && (type == 'i64' || type == 'double')) return 8;
+    if (!type) return Math.min(size, 8); // align structures internally to 64 bits
+    return Math.min(size || (type ? Runtime.getNativeFieldSize(type) : 0), Runtime.QUANTUM_SIZE);
+  },
+  calculateStructAlignment: function calculateStructAlignment(type) {
+    type.flatSize = 0;
+    type.alignSize = 0;
+    var diffs = [];
+    var prev = -1;
+    var index = 0;
+    type.flatIndexes = type.fields.map(function(field) {
+      index++;
+      var size, alignSize;
+      if (Runtime.isNumberType(field) || Runtime.isPointerType(field)) {
+        size = Runtime.getNativeTypeSize(field); // pack char; char; in structs, also char[X]s.
+        alignSize = Runtime.getAlignSize(field, size);
+      } else if (Runtime.isStructType(field)) {
+        if (field[1] === '0') {
+          // this is [0 x something]. When inside another structure like here, it must be at the end,
+          // and it adds no size
+          // XXX this happens in java-nbody for example... assert(index === type.fields.length, 'zero-length in the middle!');
+          size = 0;
+          if (Types.types[field]) {
+            alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+          } else {
+            alignSize = type.alignSize || QUANTUM_SIZE;
+          }
+        } else {
+          size = Types.types[field].flatSize;
+          alignSize = Runtime.getAlignSize(null, Types.types[field].alignSize);
+        }
+      } else if (field[0] == 'b') {
+        // bN, large number field, like a [N x i8]
+        size = field.substr(1)|0;
+        alignSize = 1;
+      } else if (field[0] === '<') {
+        // vector type
+        size = alignSize = Types.types[field].flatSize; // fully aligned
+      } else if (field[0] === 'i') {
+        // illegal integer field, that could not be legalized because it is an internal structure field
+        // it is ok to have such fields, if we just use them as markers of field size and nothing more complex
+        size = alignSize = parseInt(field.substr(1))/8;
+        assert(size % 1 === 0, 'cannot handle non-byte-size field ' + field);
+      } else {
+        assert(false, 'invalid type for calculateStructAlignment');
+      }
+      if (type.packed) alignSize = 1;
+      type.alignSize = Math.max(type.alignSize, alignSize);
+      var curr = Runtime.alignMemory(type.flatSize, alignSize); // if necessary, place this on aligned memory
+      type.flatSize = curr + size;
+      if (prev >= 0) {
+        diffs.push(curr-prev);
+      }
+      prev = curr;
+      return curr;
+    });
+    if (type.name_ && type.name_[0] === '[') {
+      // arrays have 2 elements, so we get the proper difference. then we scale here. that way we avoid
+      // allocating a potentially huge array for [999999 x i8] etc.
+      type.flatSize = parseInt(type.name_.substr(1))*type.flatSize/2;
+    }
+    type.flatSize = Runtime.alignMemory(type.flatSize, type.alignSize);
+    if (diffs.length == 0) {
+      type.flatFactor = type.flatSize;
+    } else if (Runtime.dedup(diffs).length == 1) {
+      type.flatFactor = diffs[0];
+    }
+    type.needsFlattening = (type.flatFactor != 1);
+    return type.flatIndexes;
+  },
+  generateStructInfo: function (struct, typeName, offset) {
+    var type, alignment;
+    if (typeName) {
+      offset = offset || 0;
+      type = (typeof Types === 'undefined' ? Runtime.typeInfo : Types.types)[typeName];
+      if (!type) return null;
+      if (type.fields.length != struct.length) {
+        printErr('Number of named fields must match the type for ' + typeName + ': possibly duplicate struct names. Cannot return structInfo');
+        return null;
+      }
+      alignment = type.flatIndexes;
+    } else {
+      var type = { fields: struct.map(function(item) { return item[0] }) };
+      alignment = Runtime.calculateStructAlignment(type);
+    }
+    var ret = {
+      __size__: type.flatSize
+    };
+    if (typeName) {
+      struct.forEach(function(item, i) {
+        if (typeof item === 'string') {
+          ret[item] = alignment[i] + offset;
+        } else {
+          // embedded struct
+          var key;
+          for (var k in item) key = k;
+          ret[key] = Runtime.generateStructInfo(item[key], type.fields[i], alignment[i]);
+        }
+      });
+    } else {
+      struct.forEach(function(item, i) {
+        ret[item[1]] = alignment[i];
+      });
+    }
+    return ret;
+  },
+  dynCall: function (sig, ptr, args) {
+    if (args && args.length) {
+      if (!args.splice) args = Array.prototype.slice.call(args);
+      args.splice(0, 0, ptr);
+      return Module['dynCall_' + sig].apply(null, args);
+    } else {
+      return Module['dynCall_' + sig].call(null, ptr);
+    }
+  },
+  functionPointers: [],
+  addFunction: function (func) {
+    for (var i = 0; i < Runtime.functionPointers.length; i++) {
+      if (!Runtime.functionPointers[i]) {
+        Runtime.functionPointers[i] = func;
+        return 2*(1 + i);
+      }
+    }
+    throw 'Finished up all reserved function pointers. Use a higher value for RESERVED_FUNCTION_POINTERS.';
+  },
+  removeFunction: function (index) {
+    Runtime.functionPointers[(index-2)/2] = null;
+  },
+  getAsmConst: function (code, numArgs) {
+    // code is a constant string on the heap, so we can cache these
+    if (!Runtime.asmConstCache) Runtime.asmConstCache = {};
+    var func = Runtime.asmConstCache[code];
+    if (func) return func;
+    var args = [];
+    for (var i = 0; i < numArgs; i++) {
+      args.push(String.fromCharCode(36) + i); // $0, $1 etc
+    }
+    var source = Pointer_stringify(code);
+    if (source[0] === '"') {
+      // tolerate EM_ASM("..code..") even though EM_ASM(..code..) is correct
+      if (source.indexOf('"', 1) === source.length-1) {
+        source = source.substr(1, source.length-2);
+      } else {
+        // something invalid happened, e.g. EM_ASM("..code($0)..", input)
+        abort('invalid EM_ASM input |' + source + '|. Please use EM_ASM(..code..) (no quotes) or EM_ASM({ ..code($0).. }, input) (to input values)');
+      }
+    }
+    try {
+      var evalled = eval('(function(' + args.join(',') + '){ ' + source + ' })'); // new Function does not allow upvars in node
+    } catch(e) {
+      Module.printErr('error in executing inline EM_ASM code: ' + e + ' on: \n\n' + source + '\n\nwith args |' + args + '| (make sure to use the right one out of EM_ASM, EM_ASM_ARGS, etc.)');
+      throw e;
+    }
+    return Runtime.asmConstCache[code] = evalled;
+  },
+  warnOnce: function (text) {
+    if (!Runtime.warnOnce.shown) Runtime.warnOnce.shown = {};
+    if (!Runtime.warnOnce.shown[text]) {
+      Runtime.warnOnce.shown[text] = 1;
+      Module.printErr(text);
+    }
+  },
+  funcWrappers: {},
+  getFuncWrapper: function (func, sig) {
+    assert(sig);
+    if (!Runtime.funcWrappers[func]) {
+      Runtime.funcWrappers[func] = function dynCall_wrapper() {
+        return Runtime.dynCall(sig, func, arguments);
+      };
+    }
+    return Runtime.funcWrappers[func];
+  },
+  UTF8Processor: function () {
+    var buffer = [];
+    var needed = 0;
+    this.processCChar = function (code) {
+      code = code & 0xFF;
+
+      if (buffer.length == 0) {
+        if ((code & 0x80) == 0x00) {        // 0xxxxxxx
+          return String.fromCharCode(code);
+        }
+        buffer.push(code);
+        if ((code & 0xE0) == 0xC0) {        // 110xxxxx
+          needed = 1;
+        } else if ((code & 0xF0) == 0xE0) { // 1110xxxx
+          needed = 2;
+        } else {                            // 11110xxx
+          needed = 3;
+        }
+        return '';
+      }
+
+      if (needed) {
+        buffer.push(code);
+        needed--;
+        if (needed > 0) return '';
+      }
+
+      var c1 = buffer[0];
+      var c2 = buffer[1];
+      var c3 = buffer[2];
+      var c4 = buffer[3];
+      var ret;
+      if (buffer.length == 2) {
+        ret = String.fromCharCode(((c1 & 0x1F) << 6)  | (c2 & 0x3F));
+      } else if (buffer.length == 3) {
+        ret = String.fromCharCode(((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6)  | (c3 & 0x3F));
+      } else {
+        // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
+        var codePoint = ((c1 & 0x07) << 18) | ((c2 & 0x3F) << 12) |
+                        ((c3 & 0x3F) << 6)  | (c4 & 0x3F);
+        ret = String.fromCharCode(
+          Math.floor((codePoint - 0x10000) / 0x400) + 0xD800,
+          (codePoint - 0x10000) % 0x400 + 0xDC00);
+      }
+      buffer.length = 0;
+      return ret;
+    }
+    this.processJSString = function processJSString(string) {
+      /* TODO: use TextEncoder when present,
+        var encoder = new TextEncoder();
+        encoder['encoding'] = "utf-8";
+        var utf8Array = encoder['encode'](aMsg.data);
+      */
+      string = unescape(encodeURIComponent(string));
+      var ret = [];
+      for (var i = 0; i < string.length; i++) {
+        ret.push(string.charCodeAt(i));
+      }
+      return ret;
+    }
+  },
+  getCompilerSetting: function (name) {
+    throw 'You must build with -s RETAIN_COMPILER_SETTINGS=1 for Runtime.getCompilerSetting or emscripten_get_compiler_setting to work';
+  },
+  stackAlloc: function (size) { var ret = STACKTOP;STACKTOP = (STACKTOP + size)|0;STACKTOP = (((STACKTOP)+7)&-8); return ret; },
+  staticAlloc: function (size) { var ret = STATICTOP;STATICTOP = (STATICTOP + size)|0;STATICTOP = (((STATICTOP)+7)&-8); return ret; },
+  dynamicAlloc: function (size) { var ret = DYNAMICTOP;DYNAMICTOP = (DYNAMICTOP + size)|0;DYNAMICTOP = (((DYNAMICTOP)+7)&-8); if (DYNAMICTOP >= TOTAL_MEMORY) enlargeMemory();; return ret; },
+  alignMemory: function (size,quantum) { var ret = size = Math.ceil((size)/(quantum ? quantum : 8))*(quantum ? quantum : 8); return ret; },
+  makeBigInt: function (low,high,unsigned) { var ret = (unsigned ? ((+((low>>>0)))+((+((high>>>0)))*(+4294967296))) : ((+((low>>>0)))+((+((high|0)))*(+4294967296)))); return ret; },
+  GLOBAL_BASE: 8,
+  QUANTUM_SIZE: 4,
+  __dummy__: 0
+}
+
+
+Module['Runtime'] = Runtime;
+
+
+
+
+
+
+
+
+
+//========================================
+// Runtime essentials
+//========================================
+
+var __THREW__ = 0; // Used in checking for thrown exceptions.
+
+var ABORT = false; // whether we are quitting the application. no code should run after this. set in exit() and abort()
+var EXITSTATUS = 0;
+
+var undef = 0;
+// tempInt is used for 32-bit signed values or smaller. tempBigInt is used
+// for 32-bit unsigned values or more than 32 bits. TODO: audit all uses of tempInt
+var tempValue, tempInt, tempBigInt, tempInt2, tempBigInt2, tempPair, tempBigIntI, tempBigIntR, tempBigIntS, tempBigIntP, tempBigIntD, tempDouble, tempFloat;
+var tempI64, tempI64b;
+var tempRet0, tempRet1, tempRet2, tempRet3, tempRet4, tempRet5, tempRet6, tempRet7, tempRet8, tempRet9;
+
+function assert(condition, text) {
+  if (!condition) {
+    abort('Assertion failed: ' + text);
+  }
+}
+
+var globalScope = this;
+
+// C calling interface. A convenient way to call C functions (in C files, or
+// defined with extern "C").
+//
+// Note: LLVM optimizations can inline and remove functions, after which you will not be
+//       able to call them. Closure can also do so. To avoid that, add your function to
+//       the exports using something like
+//
+//         -s EXPORTED_FUNCTIONS='["_main", "_myfunc"]'
+//
+// @param ident      The name of the C function (note that C++ functions will be name-mangled - use extern "C")
+// @param returnType The return type of the function, one of the JS types 'number', 'string' or 'array' (use 'number' for any C pointer, and
+//                   'array' for JavaScript arrays and typed arrays; note that arrays are 8-bit).
+// @param argTypes   An array of the types of arguments for the function (if there are no arguments, this can be ommitted). Types are as in returnType,
+//                   except that 'array' is not possible (there is no way for us to know the length of the array)
+// @param args       An array of the arguments to the function, as native JS values (as in returnType)
+//                   Note that string arguments will be stored on the stack (the JS string will become a C string on the stack).
+// @return           The return value, as a native JS value (as in returnType)
+function ccall(ident, returnType, argTypes, args) {
+  return ccallFunc(getCFunc(ident), returnType, argTypes, args);
+}
+Module["ccall"] = ccall;
+
+// Returns the C function with a specified identifier (for C++, you need to do manual name mangling)
+function getCFunc(ident) {
+  try {
+    var func = Module['_' + ident]; // closure exported function
+    if (!func) func = eval('_' + ident); // explicit lookup
+  } catch(e) {
+  }
+  assert(func, 'Cannot call unknown function ' + ident + ' (perhaps LLVM optimizations or closure removed it?)');
+  return func;
+}
+
+// Internal function that does a C call using a function, not an identifier
+function ccallFunc(func, returnType, argTypes, args) {
+  var stack = 0;
+  function toC(value, type) {
+    if (type == 'string') {
+      if (value === null || value === undefined || value === 0) return 0; // null string
+      value = intArrayFromString(value);
+      type = 'array';
+    }
+    if (type == 'array') {
+      if (!stack) stack = Runtime.stackSave();
+      var ret = Runtime.stackAlloc(value.length);
+      writeArrayToMemory(value, ret);
+      return ret;
+    }
+    return value;
+  }
+  function fromC(value, type) {
+    if (type == 'string') {
+      return Pointer_stringify(value);
+    }
+    assert(type != 'array');
+    return value;
+  }
+  var i = 0;
+  var cArgs = args ? args.map(function(arg) {
+    return toC(arg, argTypes[i++]);
+  }) : [];
+  var ret = fromC(func.apply(null, cArgs), returnType);
+  if (stack) Runtime.stackRestore(stack);
+  return ret;
+}
+
+// Returns a native JS wrapper for a C function. This is similar to ccall, but
+// returns a function you can call repeatedly in a normal way. For example:
+//
+//   var my_function = cwrap('my_c_function', 'number', ['number', 'number']);
+//   alert(my_function(5, 22));
+//   alert(my_function(99, 12));
+//
+function cwrap(ident, returnType, argTypes) {
+  var func = getCFunc(ident);
+  return function() {
+    return ccallFunc(func, returnType, argTypes, Array.prototype.slice.call(arguments));
+  }
+}
+Module["cwrap"] = cwrap;
+
+// Sets a value in memory in a dynamic way at run-time. Uses the
+// type data. This is the same as makeSetValue, except that
+// makeSetValue is done at compile-time and generates the needed
+// code then, whereas this function picks the right code at
+// run-time.
+// Note that setValue and getValue only do *aligned* writes and reads!
+// Note that ccall uses JS types as for defining types, while setValue and
+// getValue need LLVM types ('i8', 'i32') - this is a lower-level operation
+function setValue(ptr, value, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': HEAP8[(ptr)]=value; break;
+      case 'i8': HEAP8[(ptr)]=value; break;
+      case 'i16': HEAP16[((ptr)>>1)]=value; break;
+      case 'i32': HEAP32[((ptr)>>2)]=value; break;
+      case 'i64': (tempI64 = [value>>>0,(tempDouble=value,(+(Math_abs(tempDouble))) >= (+1) ? (tempDouble > (+0) ? ((Math_min((+(Math_floor((tempDouble)/(+4294967296)))), (+4294967295)))|0)>>>0 : (~~((+(Math_ceil((tempDouble - +(((~~(tempDouble)))>>>0))/(+4294967296))))))>>>0) : 0)],HEAP32[((ptr)>>2)]=tempI64[0],HEAP32[(((ptr)+(4))>>2)]=tempI64[1]); break;
+      case 'float': HEAPF32[((ptr)>>2)]=value; break;
+      case 'double': HEAPF64[((ptr)>>3)]=value; break;
+      default: abort('invalid type for setValue: ' + type);
+    }
+}
+Module['setValue'] = setValue;
+
+// Parallel to setValue.
+function getValue(ptr, type, noSafe) {
+  type = type || 'i8';
+  if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+    switch(type) {
+      case 'i1': return HEAP8[(ptr)];
+      case 'i8': return HEAP8[(ptr)];
+      case 'i16': return HEAP16[((ptr)>>1)];
+      case 'i32': return HEAP32[((ptr)>>2)];
+      case 'i64': return HEAP32[((ptr)>>2)];
+      case 'float': return HEAPF32[((ptr)>>2)];
+      case 'double': return HEAPF64[((ptr)>>3)];
+      default: abort('invalid type for setValue: ' + type);
+    }
+  return null;
+}
+Module['getValue'] = getValue;
+
+var ALLOC_NORMAL = 0; // Tries to use _malloc()
+var ALLOC_STACK = 1; // Lives for the duration of the current function call
+var ALLOC_STATIC = 2; // Cannot be freed
+var ALLOC_DYNAMIC = 3; // Cannot be freed except through sbrk
+var ALLOC_NONE = 4; // Do not allocate
+Module['ALLOC_NORMAL'] = ALLOC_NORMAL;
+Module['ALLOC_STACK'] = ALLOC_STACK;
+Module['ALLOC_STATIC'] = ALLOC_STATIC;
+Module['ALLOC_DYNAMIC'] = ALLOC_DYNAMIC;
+Module['ALLOC_NONE'] = ALLOC_NONE;
+
+// allocate(): This is for internal use. You can use it yourself as well, but the interface
+//             is a little tricky (see docs right below). The reason is that it is optimized
+//             for multiple syntaxes to save space in generated code. So you should
+//             normally not use allocate(), and instead allocate memory using _malloc(),
+//             initialize it with setValue(), and so forth.
+// @slab: An array of data, or a number. If a number, then the size of the block to allocate,
+//        in *bytes* (note that this is sometimes confusing: the next parameter does not
+//        affect this!)
+// @types: Either an array of types, one for each byte (or 0 if no type at that position),
+//         or a single type which is used for the entire block. This only matters if there
+//         is initial data - if @slab is a number, then this does not matter at all and is
+//         ignored.
+// @allocator: How to allocate memory, see ALLOC_*
+function allocate(slab, types, allocator, ptr) {
+  var zeroinit, size;
+  if (typeof slab === 'number') {
+    zeroinit = true;
+    size = slab;
+  } else {
+    zeroinit = false;
+    size = slab.length;
+  }
+
+  var singleType = typeof types === 'string' ? types : null;
+
+  var ret;
+  if (allocator == ALLOC_NONE) {
+    ret = ptr;
+  } else {
+    ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc, Runtime.dynamicAlloc][allocator === undefined ? ALLOC_STATIC : allocator](Math.max(size, singleType ? 1 : types.length));
+  }
+
+  if (zeroinit) {
+    var ptr = ret, stop;
+    assert((ret & 3) == 0);
+    stop = ret + (size & ~3);
+    for (; ptr < stop; ptr += 4) {
+      HEAP32[((ptr)>>2)]=0;
+    }
+    stop = ret + size;
+    while (ptr < stop) {
+      HEAP8[((ptr++)|0)]=0;
+    }
+    return ret;
+  }
+
+  if (singleType === 'i8') {
+    if (slab.subarray || slab.slice) {
+      HEAPU8.set(slab, ret);
+    } else {
+      HEAPU8.set(new Uint8Array(slab), ret);
+    }
+    return ret;
+  }
+
+  var i = 0, type, typeSize, previousType;
+  while (i < size) {
+    var curr = slab[i];
+
+    if (typeof curr === 'function') {
+      curr = Runtime.getFunctionIndex(curr);
+    }
+
+    type = singleType || types[i];
+    if (type === 0) {
+      i++;
+      continue;
+    }
+
+    if (type == 'i64') type = 'i32'; // special case: we have one i32 here, and one i32 later
+
+    setValue(ret+i, curr, type);
+
+    // no need to look up size unless type changes, so cache it
+    if (previousType !== type) {
+      typeSize = Runtime.getNativeTypeSize(type);
+      previousType = type;
+    }
+    i += typeSize;
+  }
+
+  return ret;
+}
+Module['allocate'] = allocate;
+
+function Pointer_stringify(ptr, /* optional */ length) {
+  // TODO: use TextDecoder
+  // Find the length, and check for UTF while doing so
+  var hasUtf = false;
+  var t;
+  var i = 0;
+  while (1) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    if (t >= 128) hasUtf = true;
+    else if (t == 0 && !length) break;
+    i++;
+    if (length && i == length) break;
+  }
+  if (!length) length = i;
+
+  var ret = '';
+
+  if (!hasUtf) {
+    var MAX_CHUNK = 1024; // split up into chunks, because .apply on a huge string can overflow the stack
+    var curr;
+    while (length > 0) {
+      curr = String.fromCharCode.apply(String, HEAPU8.subarray(ptr, ptr + Math.min(length, MAX_CHUNK)));
+      ret = ret ? ret + curr : curr;
+      ptr += MAX_CHUNK;
+      length -= MAX_CHUNK;
+    }
+    return ret;
+  }
+
+  var utf8 = new Runtime.UTF8Processor();
+  for (i = 0; i < length; i++) {
+    t = HEAPU8[(((ptr)+(i))|0)];
+    ret += utf8.processCChar(t);
+  }
+  return ret;
+}
+Module['Pointer_stringify'] = Pointer_stringify;
+
+// Given a pointer 'ptr' to a null-terminated UTF16LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF16ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var codeUnit = HEAP16[(((ptr)+(i*2))>>1)];
+    if (codeUnit == 0)
+      return str;
+    ++i;
+    // fromCharCode constructs a character from a UTF-16 code unit, so we can pass the UTF16 string right through.
+    str += String.fromCharCode(codeUnit);
+  }
+}
+Module['UTF16ToString'] = UTF16ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF16LE form. The copy will require at most (str.length*2+1)*2 bytes of space in the HEAP.
+function stringToUTF16(str, outPtr) {
+  for(var i = 0; i < str.length; ++i) {
+    // charCodeAt returns a UTF-16 encoded code unit, so it can be directly written to the HEAP.
+    var codeUnit = str.charCodeAt(i); // possibly a lead surrogate
+    HEAP16[(((outPtr)+(i*2))>>1)]=codeUnit;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP16[(((outPtr)+(str.length*2))>>1)]=0;
+}
+Module['stringToUTF16'] = stringToUTF16;
+
+// Given a pointer 'ptr' to a null-terminated UTF32LE-encoded string in the emscripten HEAP, returns
+// a copy of that string as a Javascript String object.
+function UTF32ToString(ptr) {
+  var i = 0;
+
+  var str = '';
+  while (1) {
+    var utf32 = HEAP32[(((ptr)+(i*4))>>2)];
+    if (utf32 == 0)
+      return str;
+    ++i;
+    // Gotcha: fromCharCode constructs a character from a UTF-16 encoded code (pair), not from a Unicode code point! So encode the code point to UTF-16 for constructing.
+    if (utf32 >= 0x10000) {
+      var ch = utf32 - 0x10000;
+      str += String.fromCharCode(0xD800 | (ch >> 10), 0xDC00 | (ch & 0x3FF));
+    } else {
+      str += String.fromCharCode(utf32);
+    }
+  }
+}
+Module['UTF32ToString'] = UTF32ToString;
+
+// Copies the given Javascript String object 'str' to the emscripten HEAP at address 'outPtr',
+// null-terminated and encoded in UTF32LE form. The copy will require at most (str.length+1)*4 bytes of space in the HEAP,
+// but can use less, since str.length does not return the number of characters in the string, but the number of UTF-16 code units in the string.
+function stringToUTF32(str, outPtr) {
+  var iChar = 0;
+  for(var iCodeUnit = 0; iCodeUnit < str.length; ++iCodeUnit) {
+    // Gotcha: charCodeAt returns a 16-bit word that is a UTF-16 encoded code unit, not a Unicode code point of the character! We must decode the string to UTF-32 to the heap.
+    var codeUnit = str.charCodeAt(iCodeUnit); // possibly a lead surrogate
+    if (codeUnit >= 0xD800 && codeUnit <= 0xDFFF) {
+      var trailSurrogate = str.charCodeAt(++iCodeUnit);
+      codeUnit = 0x10000 + ((codeUnit & 0x3FF) << 10) | (trailSurrogate & 0x3FF);
+    }
+    HEAP32[(((outPtr)+(iChar*4))>>2)]=codeUnit;
+    ++iChar;
+  }
+  // Null-terminate the pointer to the HEAP.
+  HEAP32[(((outPtr)+(iChar*4))>>2)]=0;
+}
+Module['stringToUTF32'] = stringToUTF32;
+
+function demangle(func) {
+  var i = 3;
+  // params, etc.
+  var basicTypes = {
+    'v': 'void',
+    'b': 'bool',
+    'c': 'char',
+    's': 'short',
+    'i': 'int',
+    'l': 'long',
+    'f': 'float',
+    'd': 'double',
+    'w': 'wchar_t',
+    'a': 'signed char',
+    'h': 'unsigned char',
+    't': 'unsigned short',
+    'j': 'unsigned int',
+    'm': 'unsigned long',
+    'x': 'long long',
+    'y': 'unsigned long long',
+    'z': '...'
+  };
+  var subs = [];
+  var first = true;
+  function dump(x) {
+    //return;
+    if (x) Module.print(x);
+    Module.print(func);
+    var pre = '';
+    for (var a = 0; a < i; a++) pre += ' ';
+    Module.print (pre + '^');
+  }
+  function parseNested() {
+    i++;
+    if (func[i] === 'K') i++; // ignore const
+    var parts = [];
+    while (func[i] !== 'E') {
+      if (func[i] === 'S') { // substitution
+        i++;
+        var next = func.indexOf('_', i);
+        var num = func.substring(i, next) || 0;
+        parts.push(subs[num] || '?');
+        i = next+1;
+        continue;
+      }
+      if (func[i] === 'C') { // constructor
+        parts.push(parts[parts.length-1]);
+        i += 2;
+        continue;
+      }
+      var size = parseInt(func.substr(i));
+      var pre = size.toString().length;
+      if (!size || !pre) { i--; break; } // counter i++ below us
+      var curr = func.substr(i + pre, size);
+      parts.push(curr);
+      subs.push(curr);
+      i += pre + size;
+    }
+    i++; // skip E
+    return parts;
+  }
+  function parse(rawList, limit, allowVoid) { // main parser
+    limit = limit || Infinity;
+    var ret = '', list = [];
+    function flushList() {
+      return '(' + list.join(', ') + ')';
+    }
+    var name;
+    if (func[i] === 'N') {
+      // namespaced N-E
+      name = parseNested().join('::');
+      limit--;
+      if (limit === 0) return rawList ? [name] : name;
+    } else {
+      // not namespaced
+      if (func[i] === 'K' || (first && func[i] === 'L')) i++; // ignore const and first 'L'
+      var size = parseInt(func.substr(i));
+      if (size) {
+        var pre = size.toString().length;
+        name = func.substr(i + pre, size);
+        i += pre + size;
+      }
+    }
+    first = false;
+    if (func[i] === 'I') {
+      i++;
+      var iList = parse(true);
+      var iRet = parse(true, 1, true);
+      ret += iRet[0] + ' ' + name + '<' + iList.join(', ') + '>';
+    } else {
+      ret = name;
+    }
+    paramLoop: while (i < func.length && limit-- > 0) {
+      //dump('paramLoop');
+      var c = func[i++];
+      if (c in basicTypes) {
+        list.push(basicTypes[c]);
+      } else {
+        switch (c) {
+          case 'P': list.push(parse(true, 1, true)[0] + '*'); break; // pointer
+          case 'R': list.push(parse(true, 1, true)[0] + '&'); break; // reference
+          case 'L': { // literal
+            i++; // skip basic type
+            var end = func.indexOf('E', i);
+            var size = end - i;
+            list.push(func.substr(i, size));
+            i += size + 2; // size + 'EE'
+            break;
+          }
+          case 'A': { // array
+            var size = parseInt(func.substr(i));
+            i += size.toString().length;
+            if (func[i] !== '_') throw '?';
+            i++; // skip _
+            list.push(parse(true, 1, true)[0] + ' [' + size + ']');
+            break;
+          }
+          case 'E': break paramLoop;
+          default: ret += '?' + c; break paramLoop;
+        }
+      }
+    }
+    if (!allowVoid && list.length === 1 && list[0] === 'void') list = []; // avoid (void)
+    if (rawList) {
+      if (ret) {
+        list.push(ret + '?');
+      }
+      return list;
+    } else {
+      return ret + flushList();
+    }
+  }
+  try {
+    // Special-case the entry point, since its name differs from other name mangling.
+    if (func == 'Object._main' || func == '_main') {
+      return 'main()';
+    }
+    if (typeof func === 'number') func = Pointer_stringify(func);
+    if (func[0] !== '_') return func;
+    if (func[1] !== '_') return func; // C function
+    if (func[2] !== 'Z') return func;
+    switch (func[3]) {
+      case 'n': return 'operator new()';
+      case 'd': return 'operator delete()';
+    }
+    return parse();
+  } catch(e) {
+    return func;
+  }
+}
+
+function demangleAll(text) {
+  return text.replace(/__Z[\w\d_]+/g, function(x) { var y = demangle(x); return x === y ? x : (x + ' [' + y + ']') });
+}
+
+function stackTrace() {
+  var stack = new Error().stack;
+  return stack ? demangleAll(stack) : '(no stack trace available)'; // Stack trace is not available at least on IE10 and Safari 6.
+}
+
+// Memory management
+
+var PAGE_SIZE = 4096;
+function alignMemoryPage(x) {
+  return (x+4095)&-4096;
+}
+
+var HEAP;
+var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;
+
+var STATIC_BASE = 0, STATICTOP = 0, staticSealed = false; // static area
+var STACK_BASE = 0, STACKTOP = 0, STACK_MAX = 0; // stack area
+var DYNAMIC_BASE = 0, DYNAMICTOP = 0; // dynamic area handled by sbrk
+
+function enlargeMemory() {
+  abort('Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value ' + TOTAL_MEMORY + ', (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.');
+}
+
+var TOTAL_STACK = Module['TOTAL_STACK'] || 5242880;
+var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || 134217728;
+var FAST_MEMORY = Module['FAST_MEMORY'] || 2097152;
+
+var totalMemory = 4096;
+while (totalMemory < TOTAL_MEMORY || totalMemory < 2*TOTAL_STACK) {
+  if (totalMemory < 16*1024*1024) {
+    totalMemory *= 2;
+  } else {
+    totalMemory += 16*1024*1024
+  }
+}
+if (totalMemory !== TOTAL_MEMORY) {
+  Module.printErr('increasing TOTAL_MEMORY to ' + totalMemory + ' to be more reasonable');
+  TOTAL_MEMORY = totalMemory;
+}
+
+// Initialize the runtime's memory
+// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
+assert(typeof Int32Array !== 'undefined' && typeof Float64Array !== 'undefined' && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
+       'JS engine does not provide full typed array support');
+
+var buffer = new ArrayBuffer(TOTAL_MEMORY);
+HEAP8 = new Int8Array(buffer);
+HEAP16 = new Int16Array(buffer);
+HEAP32 = new Int32Array(buffer);
+HEAPU8 = new Uint8Array(buffer);
+HEAPU16 = new Uint16Array(buffer);
+HEAPU32 = new Uint32Array(buffer);
+HEAPF32 = new Float32Array(buffer);
+HEAPF64 = new Float64Array(buffer);
+
+// Endianness check (note: assumes compiler arch was little-endian)
+HEAP32[0] = 255;
+assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
+
+Module['HEAP'] = HEAP;
+Module['HEAP8'] = HEAP8;
+Module['HEAP16'] = HEAP16;
+Module['HEAP32'] = HEAP32;
+Module['HEAPU8'] = HEAPU8;
+Module['HEAPU16'] = HEAPU16;
+Module['HEAPU32'] = HEAPU32;
+Module['HEAPF32'] = HEAPF32;
+Module['HEAPF64'] = HEAPF64;
+
+function callRuntimeCallbacks(callbacks) {
+  while(callbacks.length > 0) {
+    var callback = callbacks.shift();
+    if (typeof callback == 'function') {
+      callback();
+      continue;
+    }
+    var func = callback.func;
+    if (typeof func === 'number') {
+      if (callback.arg === undefined) {
+        Runtime.dynCall('v', func);
+      } else {
+        Runtime.dynCall('vi', func, [callback.arg]);
+      }
+    } else {
+      func(callback.arg === undefined ? null : callback.arg);
+    }
+  }
+}
+
+var __ATPRERUN__  = []; // functions called before the runtime is initialized
+var __ATINIT__    = []; // functions called during startup
+var __ATMAIN__    = []; // functions called when main() is to be run
+var __ATEXIT__    = []; // functions called during shutdown
+var __ATPOSTRUN__ = []; // functions called after the runtime has exited
+
+var runtimeInitialized = false;
+
+function preRun() {
+  // compatibility - merge in anything from Module['preRun'] at this time
+  if (Module['preRun']) {
+    if (typeof Module['preRun'] == 'function') Module['preRun'] = [Module['preRun']];
+    while (Module['preRun'].length) {
+      addOnPreRun(Module['preRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPRERUN__);
+}
+
+function ensureInitRuntime() {
+  if (runtimeInitialized) return;
+  runtimeInitialized = true;
+  callRuntimeCallbacks(__ATINIT__);
+}
+
+function preMain() {
+  callRuntimeCallbacks(__ATMAIN__);
+}
+
+function exitRuntime() {
+  callRuntimeCallbacks(__ATEXIT__);
+}
+
+function postRun() {
+  // compatibility - merge in anything from Module['postRun'] at this time
+  if (Module['postRun']) {
+    if (typeof Module['postRun'] == 'function') Module['postRun'] = [Module['postRun']];
+    while (Module['postRun'].length) {
+      addOnPostRun(Module['postRun'].shift());
+    }
+  }
+  callRuntimeCallbacks(__ATPOSTRUN__);
+}
+
+function addOnPreRun(cb) {
+  __ATPRERUN__.unshift(cb);
+}
+Module['addOnPreRun'] = Module.addOnPreRun = addOnPreRun;
+
+function addOnInit(cb) {
+  __ATINIT__.unshift(cb);
+}
+Module['addOnInit'] = Module.addOnInit = addOnInit;
+
+function addOnPreMain(cb) {
+  __ATMAIN__.unshift(cb);
+}
+Module['addOnPreMain'] = Module.addOnPreMain = addOnPreMain;
+
+function addOnExit(cb) {
+  __ATEXIT__.unshift(cb);
+}
+Module['addOnExit'] = Module.addOnExit = addOnExit;
+
+function addOnPostRun(cb) {
+  __ATPOSTRUN__.unshift(cb);
+}
+Module['addOnPostRun'] = Module.addOnPostRun = addOnPostRun;
+
+// Tools
+
+// This processes a JS string into a C-line array of numbers, 0-terminated.
+// For LLVM-originating strings, see parser.js:parseLLVMString function
+function intArrayFromString(stringy, dontAddNull, length /* optional */) {
+  var ret = (new Runtime.UTF8Processor()).processJSString(stringy);
+  if (length) {
+    ret.length = length;
+  }
+  if (!dontAddNull) {
+    ret.push(0);
+  }
+  return ret;
+}
+Module['intArrayFromString'] = intArrayFromString;
+
+function intArrayToString(array) {
+  var ret = [];
+  for (var i = 0; i < array.length; i++) {
+    var chr = array[i];
+    if (chr > 0xFF) {
+      chr &= 0xFF;
+    }
+    ret.push(String.fromCharCode(chr));
+  }
+  return ret.join('');
+}
+Module['intArrayToString'] = intArrayToString;
+
+// Write a Javascript array to somewhere in the heap
+function writeStringToMemory(string, buffer, dontAddNull) {
+  var array = intArrayFromString(string, dontAddNull);
+  var i = 0;
+  while (i < array.length) {
+    var chr = array[i];
+    HEAP8[(((buffer)+(i))|0)]=chr;
+    i = i + 1;
+  }
+}
+Module['writeStringToMemory'] = writeStringToMemory;
+
+function writeArrayToMemory(array, buffer) {
+  for (var i = 0; i < array.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=array[i];
+  }
+}
+Module['writeArrayToMemory'] = writeArrayToMemory;
+
+function writeAsciiToMemory(str, buffer, dontAddNull) {
+  for (var i = 0; i < str.length; i++) {
+    HEAP8[(((buffer)+(i))|0)]=str.charCodeAt(i);
+  }
+  if (!dontAddNull) HEAP8[(((buffer)+(str.length))|0)]=0;
+}
+Module['writeAsciiToMemory'] = writeAsciiToMemory;
+
+function unSign(value, bits, ignore) {
+  if (value >= 0) {
+    return value;
+  }
+  return bits <= 32 ? 2*Math.abs(1 << (bits-1)) + value // Need some trickery, since if bits == 32, we are right at the limit of the bits JS uses in bitshifts
+                    : Math.pow(2, bits)         + value;
+}
+function reSign(value, bits, ignore) {
+  if (value <= 0) {
+    return value;
+  }
+  var half = bits <= 32 ? Math.abs(1 << (bits-1)) // abs is needed if bits == 32
+                        : Math.pow(2, bits-1);
+  if (value >= half && (bits <= 32 || value > half)) { // for huge values, we can hit the precision limit and always get true here. so don't do that
+                                                       // but, in general there is no perfect solution here. With 64-bit ints, we get rounding and errors
+                                                       // TODO: In i64 mode 1, resign the two parts separately and safely
+    value = -2*half + value; // Cannot bitshift half, as it may be at the limit of the bits JS uses in bitshifts
+  }
+  return value;
+}
+
+// check for imul support, and also for correctness ( https://bugs.webkit.org/show_bug.cgi?id=126345 )
+if (!Math['imul'] || Math['imul'](0xffffffff, 5) !== -5) Math['imul'] = function imul(a, b) {
+  var ah  = a >>> 16;
+  var al = a & 0xffff;
+  var bh  = b >>> 16;
+  var bl = b & 0xffff;
+  return (al*bl + ((ah*bl + al*bh) << 16))|0;
+};
+Math.imul = Math['imul'];
+
+
+var Math_abs = Math.abs;
+var Math_cos = Math.cos;
+var Math_sin = Math.sin;
+var Math_tan = Math.tan;
+var Math_acos = Math.acos;
+var Math_asin = Math.asin;
+var Math_atan = Math.atan;
+var Math_atan2 = Math.atan2;
+var Math_exp = Math.exp;
+var Math_log = Math.log;
+var Math_sqrt = Math.sqrt;
+var Math_ceil = Math.ceil;
+var Math_floor = Math.floor;
+var Math_pow = Math.pow;
+var Math_imul = Math.imul;
+var Math_fround = Math.fround;
+var Math_min = Math.min;
+
+// A counter of dependencies for calling run(). If we need to
+// do asynchronous work before running, increment this and
+// decrement it. Incrementing must happen in a place like
+// PRE_RUN_ADDITIONS (used by emcc to add file preloading).
+// Note that you can add dependencies in preRun, even though
+// it happens right before run - run will be postponed until
+// the dependencies are met.
+var runDependencies = 0;
+var runDependencyWatcher = null;
+var dependenciesFulfilled = null; // overridden to take different actions when all run dependencies are fulfilled
+
+function addRunDependency(id) {
+  runDependencies++;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+}
+Module['addRunDependency'] = addRunDependency;
+function removeRunDependency(id) {
+  runDependencies--;
+  if (Module['monitorRunDependencies']) {
+    Module['monitorRunDependencies'](runDependencies);
+  }
+  if (runDependencies == 0) {
+    if (runDependencyWatcher !== null) {
+      clearInterval(runDependencyWatcher);
+      runDependencyWatcher = null;
+    }
+    if (dependenciesFulfilled) {
+      var callback = dependenciesFulfilled;
+      dependenciesFulfilled = null;
+      callback(); // can add another dependenciesFulfilled
+    }
+  }
+}
+Module['removeRunDependency'] = removeRunDependency;
+
+Module["preloadedImages"] = {}; // maps url to image data
+Module["preloadedAudios"] = {}; // maps url to audio data
+
+
+var memoryInitializer = null;
+
+// === Body ===
+
+
+
+
+
+STATIC_BASE = 8;
+
+STATICTOP = STATIC_BASE + Runtime.alignMemory(14963);
+/* global initializers */ __ATINIT__.push();
+
+
+/* memory initializer */ allocate([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,115,105,122,101,115,58,32,37,100,44,37,100,10,0,0,0,100,101,99,111,109,112,114,101,115,115,101,100,83,105,122,101,32,61,61,32,115,105,122,101,0,0,0,0,0,0,0,0,47,116,109,112,47,101,109,115,99,114,105,112,116,101,110,95,116,101,109,112,47,122,108,105,98,46,99,0,0,0,0,0,100,111,105,116,0,0,0,0,115,116,114,99,109,112,40,98,117,102,102,101,114,44,32,98,117,102,102,101,114,51,41,32,61,61,32,48,0,0,0,0,101,114,114,111,114,58,32,37,100,92,110,0,0,0,0,0,111,107,46,0,0,0,0,0,49,46,50,46,53,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,4,0,4,0,8,0,4,0,2,0,0,0,4,0,5,0,16,0,8,0,2,0,0,0,4,0,6,0,32,0,32,0,2,0,0,0,4,0,4,0,16,0,16,0,3,0,0,0,8,0,16,0,32,0,32,0,3,0,0,0,8,0,16,0,128,0,128,0,3,0,0,0,8,0,32,0,128,0,0,1,3,0,0,0,32,0,128,0,2,1,0,4,3,0,0,0,32,0,2,1,2,1,0,16,3,0,0,0,0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,16,17,18,18,19,19,20,20,20,20,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,112,4,0,0,104,9,0,0,1,1,0,0,30,1,0,0,15,0,0,0,0,0,0,0,240,8,0,0,88,10,0,0,0,0,0,0,30,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,96,11,0,0,0,0,0,0,19,0,0,0,7,0,0,0,0,0,0,0,12,0,8,0,140,0,8,0,76,0,8,0,204,0,8,0,44,0,8,0,172,0,8,0,108,0,8,0,236,0,8,0,28,0,8,0,156,0,8,0,92,0,8,0,220,0,8,0,60,0,8,0,188,0,8,0,124,0,8,0,252,0,8,0,2,0,8,0,130,0,8,0,66,0,8,0,194,0,8,0,34,0,8,0,162,0,8,0,98,0,8,0,226,0,8,0,18,0,8,0,146,0,8,0,82,0,8,0,210,0,8,0,50,0,8,0,178,0,8,0,114,0,8,0,242,0,8,0,10,0,8,0,138,0,8,0,74,0,8,0,202,0,8,0,42,0,8,0,170,0,8,0,106,0,8,0,234,0,8,0,26,0,8,0,154,0,8,0,90,0,8,0,218,0,8,0,58,0,8,0,186,0,8,0,122,0,8,0,250,0,8,0,6,0,8,0,134,0,8,0,70,0,8,0,198,0,8,0,38,0,8,0,166,0,8,0,102,0,8,0,230,0,8,0,22,0,8,0,150,0,8,0,86,0,8,0,214,0,8,0,54,0,8,0,182,0,8,0,118,0,8,0,246,0,8,0,14,0,8,0,142,0,8,0,78,0,8,0,206,0,8,0,46,0,8,0,174,0,8,0,110,0,8,0,238,0,8,0,30,0,8,0,158,0,8,0,94,0,8,0,222,0,8,0,62,0,8,0,190,0,8,0,126,0,8,0,254,0,8,0,1,0,8,0,129,0,8,0,65,0,8,0,193,0,8,0,33,0,8,0,161,0,8,0,97,0,8,0,225,0,8,0,17,0,8,0,145,0,8,0,81,0,8,0,209,0,8,0,49,0,8,0,177,0,8,0,113,0,8,0,241,0,8,0,9,0,8,0,137,0,8,0,73,0,8,0,201,0,8,0,41,0,8,0,169,0,8,0,105,0,8,0,233,0,8,0,25,0,8,0,153,0,8,0,89,0,8,0,217,0,8,0,57,0,8,0,185,0,8,0,121,0,8,0,249,0,8,0,5,0,8,0,133,0,8,0,69,0,8,0,197,0,8,0,37,0,8,0,165,0,8,0,101,0,8,0,229,0,8,0,21,0,8,0,149,0,8,0,85,0,8,0,213,0,8,0,53,0,8,0,181,0,8,0,117,0,8,0,245,0,8,0,13,0,8,0,141,0,8,0,77,0,8,0,205,0,8,0,45,0,8,0,173,0,8,0,109,0,8,0,237,0,8,0,29,0,8,0,157,0,8,0,93,0,8,0,221,0,8,0,61,0,8,0,189,0,8,0,125,0,8,0,253,0,8,0,19,0,9,0,19,1,9,0,147,0,9,0,147,1,9,0,83,0,9,0,83,1,9,0,211,0,9,0,211,1,9,0,51,0,9,0,51,1,9,0,179,0,9,0,179,1,9,0,115,0,9,0,115,1,9,0,243,0,9,0,243,1,9,0,11,0,9,0,11,1,9,0,139,0,9,0,139,1,9,0,75,0,9,0,75,1,9,0,203,0,9,0,203,1,9,0,43,0,9,0,43,1,9,0,171,0,9,0,171,1,9,0,107,0,9,0,107,1,9,0,235,0,9,0,235,1,9,0,27,0,9,0,27,1,9,0,155,0,9,0,155,1,9,0,91,0,9,0,91,1,9,0,219,0,9,0,219,1,9,0,59,0,9,0,59,1,9,0,187,0,9,0,187,1,9,0,123,0,9,0,123,1,9,0,251,0,9,0,251,1,9,0,7,0,9,0,7,1,9,0,135,0,9,0,135,1,9,0,71,0,9,0,71,1,9,0,199,0,9,0,199,1,9,0,39,0,9,0,39,1,9,0,167,0,9,0,167,1,9,0,103,0,9,0,103,1,9,0,231,0,9,0,231,1,9,0,23,0,9,0,23,1,9,0,151,0,9,0,151,1,9,0,87,0,9,0,87,1,9,0,215,0,9,0,215,1,9,0,55,0,9,0,55,1,9,0,183,0,9,0,183,1,9,0,119,0,9,0,119,1,9,0,247,0,9,0,247,1,9,0,15,0,9,0,15,1,9,0,143,0,9,0,143,1,9,0,79,0,9,0,79,1,9,0,207,0,9,0,207,1,9,0,47,0,9,0,47,1,9,0,175,0,9,0,175,1,9,0,111,0,9,0,111,1,9,0,239,0,9,0,239,1,9,0,31,0,9,0,31,1,9,0,159,0,9,0,159,1,9,0,95,0,9,0,95,1,9,0,223,0,9,0,223,1,9,0,63,0,9,0,63,1,9,0,191,0,9,0,191,1,9,0,127,0,9,0,127,1,9,0,255,0,9,0,255,1,9,0,0,0,7,0,64,0,7,0,32,0,7,0,96,0,7,0,16,0,7,0,80,0,7,0,48,0,7,0,112,0,7,0,8,0,7,0,72,0,7,0,40,0,7,0,104,0,7,0,24,0,7,0,88,0,7,0,56,0,7,0,120,0,7,0,4,0,7,0,68,0,7,0,36,0,7,0,100,0,7,0,20,0,7,0,84,0,7,0,52,0,7,0,116,0,7,0,3,0,8,0,131,0,8,0,67,0,8,0,195,0,8,0,35,0,8,0,163,0,8,0,99,0,8,0,227,0,8,0,0,0,5,0,16,0,5,0,8,0,5,0,24,0,5,0,4,0,5,0,20,0,5,0,12,0,5,0,28,0,5,0,2,0,5,0,18,0,5,0,10,0,5,0,26,0,5,0,6,0,5,0,22,0,5,0,14,0,5,0,30,0,5,0,1,0,5,0,17,0,5,0,9,0,5,0,25,0,5,0,5,0,5,0,21,0,5,0,13,0,5,0,29,0,5,0,3,0,5,0,19,0,5,0,11,0,5,0,27,0,5,0,7,0,5,0,23,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,3,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,5,0,0,0,5,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,5,0,0,0,6,0,0,0,7,0,0,0,8,0,0,0,10,0,0,0,12,0,0,0,14,0,0,0,16,0,0,0,20,0,0,0,24,0,0,0,28,0,0,0,32,0,0,0,40,0,0,0,48,0,0,0,56,0,0,0,64,0,0,0,80,0,0,0,96,0,0,0,112,0,0,0,128,0,0,0,160,0,0,0,192,0,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,2,0,0,0,2,0,0,0,3,0,0,0,3,0,0,0,4,0,0,0,4,0,0,0,5,0,0,0,5,0,0,0,6,0,0,0,6,0,0,0,7,0,0,0,7,0,0,0,8,0,0,0,8,0,0,0,9,0,0,0,9,0,0,0,10,0,0,0,10,0,0,0,11,0,0,0,11,0,0,0,12,0,0,0,12,0,0,0,13,0,0,0,13,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,8,0,0,0,12,0,0,0,16,0,0,0,24,0,0,0,32,0,0,0,48,0,0,0,64,0,0,0,96,0,0,0,128,0,0,0,192,0,0,0,0,1,0,0,128,1,0,0,0,2,0,0,0,3,0,0,0,4,0,0,0,6,0,0,0,8,0,0,0,12,0,0,0,16,0,0,0,24,0,0,0,32,0,0,0,48,0,0,0,64,0,0,0,96,0,0,16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,0,0,7,0,0,0,0,0,0,0,49,46,50,46,53,0,0,0,110,101,101,100,32,100,105,99,116,105,111,110,97,114,121,0,115,116,114,101,97,109,32,101,110,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,102,105,108,101,32,101,114,114,111,114,0,0,0,0,0,0,115,116,114,101,97,109,32,101,114,114,111,114,0,0,0,0,100,97,116,97,32,101,114,114,111,114,0,0,0,0,0,0,105,110,115,117,102,102,105,99,105,101,110,116,32,109,101,109,111,114,121,0,0,0,0,0,98,117,102,102,101,114,32,101,114,114,111,114,0,0,0,0,105,110,99,111,109,112,97,116,105,98,108,101,32,118,101,114,115,105,111,110,0,0,0,0,184,11,0,0,200,11,0,0,216,11,0,0,224,11,0,0,240,11,0,0,0,12,0,0,16,12,0,0,40,12,0,0,56,12,0,0,216,11,0,0,0,0,0,0,150,48,7,119,44,97,14,238,186,81,9,153,25,196,109,7,143,244,106,112,53,165,99,233,163,149,100,158,50,136,219,14,164,184,220,121,30,233,213,224,136,217,210,151,43,76,182,9,189,124,177,126,7,45,184,231,145,29,191,144,100,16,183,29,242,32,176,106,72,113,185,243,222,65,190,132,125,212,218,26,235,228,221,109,81,181,212,244,199,133,211,131,86,152,108,19,192,168,107,100,122,249,98,253,236,201,101,138,79,92,1,20,217,108,6,99,99,61,15,250,245,13,8,141,200,32,110,59,94,16,105,76,228,65,96,213,114,113,103,162,209,228,3,60,71,212,4,75,253,133,13,210,107,181,10,165,250,168,181,53,108,152,178,66,214,201,187,219,64,249,188,172,227,108,216,50,117,92,223,69,207,13,214,220,89,61,209,171,172,48,217,38,58,0,222,81,128,81,215,200,22,97,208,191,181,244,180,33,35,196,179,86,153,149,186,207,15,165,189,184,158,184,2,40,8,136,5,95,178,217,12,198,36,233,11,177,135,124,111,47,17,76,104,88,171,29,97,193,61,45,102,182,144,65,220,118,6,113,219,1,188,32,210,152,42,16,213,239,137,133,177,113,31,181,182,6,165,228,191,159,51,212,184,232,162,201,7,120,52,249,0,15,142,168,9,150,24,152,14,225,187,13,106,127,45,61,109,8,151,108,100,145,1,92,99,230,244,81,107,107,98,97,108,28,216,48,101,133,78,0,98,242,237,149,6,108,123,165,1,27,193,244,8,130,87,196,15,245,198,217,176,101,80,233,183,18,234,184,190,139,124,136,185,252,223,29,221,98,73,45,218,21,243,124,211,140,101,76,212,251,88,97,178,77,206,81,181,58,116,0,188,163,226,48,187,212,65,165,223,74,215,149,216,61,109,196,209,164,251,244,214,211,106,233,105,67,252,217,110,52,70,136,103,173,208,184,96,218,115,45,4,68,229,29,3,51,95,76,10,170,201,124,13,221,60,113,5,80,170,65,2,39,16,16,11,190,134,32,12,201,37,181,104,87,179,133,111,32,9,212,102,185,159,228,97,206,14,249,222,94,152,201,217,41,34,152,208,176,180,168,215,199,23,61,179,89,129,13,180,46,59,92,189,183,173,108,186,192,32,131,184,237,182,179,191,154,12,226,182,3,154,210,177,116,57,71,213,234,175,119,210,157,21,38,219,4,131,22,220,115,18,11,99,227,132,59,100,148,62,106,109,13,168,90,106,122,11,207,14,228,157,255,9,147,39,174,0,10,177,158,7,125,68,147,15,240,210,163,8,135,104,242,1,30,254,194,6,105,93,87,98,247,203,103,101,128,113,54,108,25,231,6,107,110,118,27,212,254,224,43,211,137,90,122,218,16,204,74,221,103,111,223,185,249,249,239,190,142,67,190,183,23,213,142,176,96,232,163,214,214,126,147,209,161,196,194,216,56,82,242,223,79,241,103,187,209,103,87,188,166,221,6,181,63,75,54,178,72,218,43,13,216,76,27,10,175,246,74,3,54,96,122,4,65,195,239,96,223,85,223,103,168,239,142,110,49,121,190,105,70,140,179,97,203,26,131,102,188,160,210,111,37,54,226,104,82,149,119,12,204,3,71,11,187,185,22,2,34,47,38,5,85,190,59,186,197,40,11,189,178,146,90,180,43,4,106,179,92,167,255,215,194,49,207,208,181,139,158,217,44,29,174,222,91,176,194,100,155,38,242,99,236,156,163,106,117,10,147,109,2,169,6,9,156,63,54,14,235,133,103,7,114,19,87,0,5,130,74,191,149,20,122,184,226,174,43,177,123,56,27,182,12,155,142,210,146,13,190,213,229,183,239,220,124,33,223,219,11,212,210,211,134,66,226,212,241,248,179,221,104,110,131,218,31,205,22,190,129,91,38,185,246,225,119,176,111,119,71,183,24,230,90,8,136,112,106,15,255,202,59,6,102,92,11,1,17,255,158,101,143,105,174,98,248,211,255,107,97,69,207,108,22,120,226,10,160,238,210,13,215,84,131,4,78,194,179,3,57,97,38,103,167,247,22,96,208,77,71,105,73,219,119,110,62,74,106,209,174,220,90,214,217,102,11,223,64,240,59,216,55,83,174,188,169,197,158,187,222,127,207,178,71,233,255,181,48,28,242,189,189,138,194,186,202,48,147,179,83,166,163,180,36,5,54,208,186,147,6,215,205,41,87,222,84,191,103,217,35,46,122,102,179,184,74,97,196,2,27,104,93,148,43,111,42,55,190,11,180,161,142,12,195,27,223,5,90,141,239,2,45,0,0,0,0,65,49,27,25,130,98,54,50,195,83,45,43,4,197,108,100,69,244,119,125,134,167,90,86,199,150,65,79,8,138,217,200,73,187,194,209,138,232,239,250,203,217,244,227,12,79,181,172,77,126,174,181,142,45,131,158,207,28,152,135,81,18,194,74,16,35,217,83,211,112,244,120,146,65,239,97,85,215,174,46,20,230,181,55,215,181,152,28,150,132,131,5,89,152,27,130,24,169,0,155,219,250,45,176,154,203,54,169,93,93,119,230,28,108,108,255,223,63,65,212,158,14,90,205,162,36,132,149,227,21,159,140,32,70,178,167,97,119,169,190,166,225,232,241,231,208,243,232,36,131,222,195,101,178,197,218,170,174,93,93,235,159,70,68,40,204,107,111,105,253,112,118,174,107,49,57,239,90,42,32,44,9,7,11,109,56,28,18,243,54,70,223,178,7,93,198,113,84,112,237,48,101,107,244,247,243,42,187,182,194,49,162,117,145,28,137,52,160,7,144,251,188,159,23,186,141,132,14,121,222,169,37,56,239,178,60,255,121,243,115,190,72,232,106,125,27,197,65,60,42,222,88,5,79,121,240,68,126,98,233,135,45,79,194,198,28,84,219,1,138,21,148,64,187,14,141,131,232,35,166,194,217,56,191,13,197,160,56,76,244,187,33,143,167,150,10,206,150,141,19,9,0,204,92,72,49,215,69,139,98,250,110,202,83,225,119,84,93,187,186,21,108,160,163,214,63,141,136,151,14,150,145,80,152,215,222,17,169,204,199,210,250,225,236,147,203,250,245,92,215,98,114,29,230,121,107,222,181,84,64,159,132,79,89,88,18,14,22,25,35,21,15,218,112,56,36,155,65,35,61,167,107,253,101,230,90,230,124,37,9,203,87,100,56,208,78,163,174,145,1,226,159,138,24,33,204,167,51,96,253,188,42,175,225,36,173,238,208,63,180,45,131,18,159,108,178,9,134,171,36,72,201,234,21,83,208,41,70,126,251,104,119,101,226,246,121,63,47,183,72,36,54,116,27,9,29,53,42,18,4,242,188,83,75,179,141,72,82,112,222,101,121,49,239,126,96,254,243,230,231,191,194,253,254,124,145,208,213,61,160,203,204,250,54,138,131,187,7,145,154,120,84,188,177,57,101,167,168,75,152,131,59,10,169,152,34,201,250,181,9,136,203,174,16,79,93,239,95,14,108,244,70,205,63,217,109,140,14,194,116,67,18,90,243,2,35,65,234,193,112,108,193,128,65,119,216,71,215,54,151,6,230,45,142,197,181,0,165,132,132,27,188,26,138,65,113,91,187,90,104,152,232,119,67,217,217,108,90,30,79,45,21,95,126,54,12,156,45,27,39,221,28,0,62,18,0,152,185,83,49,131,160,144,98,174,139,209,83,181,146,22,197,244,221,87,244,239,196,148,167,194,239,213,150,217,246,233,188,7,174,168,141,28,183,107,222,49,156,42,239,42,133,237,121,107,202,172,72,112,211,111,27,93,248,46,42,70,225,225,54,222,102,160,7,197,127,99,84,232,84,34,101,243,77,229,243,178,2,164,194,169,27,103,145,132,48,38,160,159,41,184,174,197,228,249,159,222,253,58,204,243,214,123,253,232,207,188,107,169,128,253,90,178,153,62,9,159,178,127,56,132,171,176,36,28,44,241,21,7,53,50,70,42,30,115,119,49,7,180,225,112,72,245,208,107,81,54,131,70,122,119,178,93,99,78,215,250,203,15,230,225,210,204,181,204,249,141,132,215,224,74,18,150,175,11,35,141,182,200,112,160,157,137,65,187,132,70,93,35,3,7,108,56,26,196,63,21,49,133,14,14,40,66,152,79,103,3,169,84,126,192,250,121,85,129,203,98,76,31,197,56,129,94,244,35,152,157,167,14,179,220,150,21,170,27,0,84,229,90,49,79,252,153,98,98,215,216,83,121,206,23,79,225,73,86,126,250,80,149,45,215,123,212,28,204,98,19,138,141,45,82,187,150,52,145,232,187,31,208,217,160,6,236,243,126,94,173,194,101,71,110,145,72,108,47,160,83,117,232,54,18,58,169,7,9,35,106,84,36,8,43,101,63,17,228,121,167,150,165,72,188,143,102,27,145,164,39,42,138,189,224,188,203,242,161,141,208,235,98,222,253,192,35,239,230,217,189,225,188,20,252,208,167,13,63,131,138,38,126,178,145,63,185,36,208,112,248,21,203,105,59,70,230,66,122,119,253,91,181,107,101,220,244,90,126,197,55,9,83,238,118,56,72,247,177,174,9,184,240,159,18,161,51,204,63,138,114,253,36,147,0,0,0,0,55,106,194,1,110,212,132,3,89,190,70,2,220,168,9,7,235,194,203,6,178,124,141,4,133,22,79,5,184,81,19,14,143,59,209,15,214,133,151,13,225,239,85,12,100,249,26,9,83,147,216,8,10,45,158,10,61,71,92,11,112,163,38,28,71,201,228,29,30,119,162,31,41,29,96,30,172,11,47,27,155,97,237,26,194,223,171,24,245,181,105,25,200,242,53,18,255,152,247,19,166,38,177,17,145,76,115,16,20,90,60,21,35,48,254,20,122,142,184,22,77,228,122,23,224,70,77,56,215,44,143,57,142,146,201,59,185,248,11,58,60,238,68,63,11,132,134,62,82,58,192,60,101,80,2,61,88,23,94,54,111,125,156,55,54,195,218,53,1,169,24,52,132,191,87,49,179,213,149,48,234,107,211,50,221,1,17,51,144,229,107,36,167,143,169,37,254,49,239,39,201,91,45,38,76,77,98,35,123,39,160,34,34,153,230,32,21,243,36,33,40,180,120,42,31,222,186,43,70,96,252,41,113,10,62,40,244,28,113,45,195,118,179,44,154,200,245,46,173,162,55,47,192,141,154,112,247,231,88,113,174,89,30,115,153,51,220,114,28,37,147,119,43,79,81,118,114,241,23,116,69,155,213,117,120,220,137,126,79,182,75,127,22,8,13,125,33,98,207,124,164,116,128,121,147,30,66,120,202,160,4,122,253,202,198,123,176,46,188,108,135,68,126,109,222,250,56,111,233,144,250,110,108,134,181,107,91,236,119,106,2,82,49,104,53,56,243,105,8,127,175,98,63,21,109,99,102,171,43,97,81,193,233,96,212,215,166,101,227,189,100,100,186,3,34,102,141,105,224,103,32,203,215,72,23,161,21,73,78,31,83,75,121,117,145,74,252,99,222,79,203,9,28,78,146,183,90,76,165,221,152,77,152,154,196,70,175,240,6,71,246,78,64,69,193,36,130,68,68,50,205,65,115,88,15,64,42,230,73,66,29,140,139,67,80,104,241,84,103,2,51,85,62,188,117,87,9,214,183,86,140,192,248,83,187,170,58,82,226,20,124,80,213,126,190,81,232,57,226,90,223,83,32,91,134,237,102,89,177,135,164,88,52,145,235,93,3,251,41,92,90,69,111,94,109,47,173,95,128,27,53,225,183,113,247,224,238,207,177,226,217,165,115,227,92,179,60,230,107,217,254,231,50,103,184,229,5,13,122,228,56,74,38,239,15,32,228,238,86,158,162,236,97,244,96,237,228,226,47,232,211,136,237,233,138,54,171,235,189,92,105,234,240,184,19,253,199,210,209,252,158,108,151,254,169,6,85,255,44,16,26,250,27,122,216,251,66,196,158,249,117,174,92,248,72,233,0,243,127,131,194,242,38,61,132,240,17,87,70,241,148,65,9,244,163,43,203,245,250,149,141,247,205,255,79,246,96,93,120,217,87,55,186,216,14,137,252,218,57,227,62,219,188,245,113,222,139,159,179,223,210,33,245,221,229,75,55,220,216,12,107,215,239,102,169,214,182,216,239,212,129,178,45,213,4,164,98,208,51,206,160,209,106,112,230,211,93,26,36,210,16,254,94,197,39,148,156,196,126,42,218,198,73,64,24,199,204,86,87,194,251,60,149,195,162,130,211,193,149,232,17,192,168,175,77,203,159,197,143,202,198,123,201,200,241,17,11,201,116,7,68,204,67,109,134,205,26,211,192,207,45,185,2,206,64,150,175,145,119,252,109,144,46,66,43,146,25,40,233,147,156,62,166,150,171,84,100,151,242,234,34,149,197,128,224,148,248,199,188,159,207,173,126,158,150,19,56,156,161,121,250,157,36,111,181,152,19,5,119,153,74,187,49,155,125,209,243,154,48,53,137,141,7,95,75,140,94,225,13,142,105,139,207,143,236,157,128,138,219,247,66,139,130,73,4,137,181,35,198,136,136,100,154,131,191,14,88,130,230,176,30,128,209,218,220,129,84,204,147,132,99,166,81,133,58,24,23,135,13,114,213,134,160,208,226,169,151,186,32,168,206,4,102,170,249,110,164,171,124,120,235,174,75,18,41,175,18,172,111,173,37,198,173,172,24,129,241,167,47,235,51,166,118,85,117,164,65,63,183,165,196,41,248,160,243,67,58,161,170,253,124,163,157,151,190,162,208,115,196,181,231,25,6,180,190,167,64,182,137,205,130,183,12,219,205,178,59,177,15,179,98,15,73,177,85,101,139,176,104,34,215,187,95,72,21,186,6,246,83,184,49,156,145,185,180,138,222,188,131,224,28,189,218,94,90,191,237,52,152,190,0,0,0,0,101,103,188,184,139,200,9,170,238,175,181,18,87,151,98,143,50,240,222,55,220,95,107,37,185,56,215,157,239,40,180,197,138,79,8,125,100,224,189,111,1,135,1,215,184,191,214,74,221,216,106,242,51,119,223,224,86,16,99,88,159,87,25,80,250,48,165,232,20,159,16,250,113,248,172,66,200,192,123,223,173,167,199,103,67,8,114,117,38,111,206,205,112,127,173,149,21,24,17,45,251,183,164,63,158,208,24,135,39,232,207,26,66,143,115,162,172,32,198,176,201,71,122,8,62,175,50,160,91,200,142,24,181,103,59,10,208,0,135,178,105,56,80,47,12,95,236,151,226,240,89,133,135,151,229,61,209,135,134,101,180,224,58,221,90,79,143,207,63,40,51,119,134,16,228,234,227,119,88,82,13,216,237,64,104,191,81,248,161,248,43,240,196,159,151,72,42,48,34,90,79,87,158,226,246,111,73,127,147,8,245,199,125,167,64,213,24,192,252,109,78,208,159,53,43,183,35,141,197,24,150,159,160,127,42,39,25,71,253,186,124,32,65,2,146,143,244,16,247,232,72,168,61,88,20,155,88,63,168,35,182,144,29,49,211,247,161,137,106,207,118,20,15,168,202,172,225,7,127,190,132,96,195,6,210,112,160,94,183,23,28,230,89,184,169,244,60,223,21,76,133,231,194,209,224,128,126,105,14,47,203,123,107,72,119,195,162,15,13,203,199,104,177,115,41,199,4,97,76,160,184,217,245,152,111,68,144,255,211,252,126,80,102,238,27,55,218,86,77,39,185,14,40,64,5,182,198,239,176,164,163,136,12,28,26,176,219,129,127,215,103,57,145,120,210,43,244,31,110,147,3,247,38,59,102,144,154,131,136,63,47,145,237,88,147,41,84,96,68,180,49,7,248,12,223,168,77,30,186,207,241,166,236,223,146,254,137,184,46,70,103,23,155,84,2,112,39,236,187,72,240,113,222,47,76,201,48,128,249,219,85,231,69,99,156,160,63,107,249,199,131,211,23,104,54,193,114,15,138,121,203,55,93,228,174,80,225,92,64,255,84,78,37,152,232,246,115,136,139,174,22,239,55,22,248,64,130,4,157,39,62,188,36,31,233,33,65,120,85,153,175,215,224,139,202,176,92,51,59,182,89,237,94,209,229,85,176,126,80,71,213,25,236,255,108,33,59,98,9,70,135,218,231,233,50,200,130,142,142,112,212,158,237,40,177,249,81,144,95,86,228,130,58,49,88,58,131,9,143,167,230,110,51,31,8,193,134,13,109,166,58,181,164,225,64,189,193,134,252,5,47,41,73,23,74,78,245,175,243,118,34,50,150,17,158,138,120,190,43,152,29,217,151,32,75,201,244,120,46,174,72,192,192,1,253,210,165,102,65,106,28,94,150,247,121,57,42,79,151,150,159,93,242,241,35,229,5,25,107,77,96,126,215,245,142,209,98,231,235,182,222,95,82,142,9,194,55,233,181,122,217,70,0,104,188,33,188,208,234,49,223,136,143,86,99,48,97,249,214,34,4,158,106,154,189,166,189,7,216,193,1,191,54,110,180,173,83,9,8,21,154,78,114,29,255,41,206,165,17,134,123,183,116,225,199,15,205,217,16,146,168,190,172,42,70,17,25,56,35,118,165,128,117,102,198,216,16,1,122,96,254,174,207,114,155,201,115,202,34,241,164,87,71,150,24,239,169,57,173,253,204,94,17,69,6,238,77,118,99,137,241,206,141,38,68,220,232,65,248,100,81,121,47,249,52,30,147,65,218,177,38,83,191,214,154,235,233,198,249,179,140,161,69,11,98,14,240,25,7,105,76,161,190,81,155,60,219,54,39,132,53,153,146,150,80,254,46,46,153,185,84,38,252,222,232,158,18,113,93,140,119,22,225,52,206,46,54,169,171,73,138,17,69,230,63,3,32,129,131,187,118,145,224,227,19,246,92,91,253,89,233,73,152,62,85,241,33,6,130,108,68,97,62,212,170,206,139,198,207,169,55,126,56,65,127,214,93,38,195,110,179,137,118,124,214,238,202,196,111,214,29,89,10,177,161,225,228,30,20,243,129,121,168,75,215,105,203,19,178,14,119,171,92,161,194,185,57,198,126,1,128,254,169,156,229,153,21,36,11,54,160,54,110,81,28,142,167,22,102,134,194,113,218,62,44,222,111,44,73,185,211,148,240,129,4,9,149,230,184,177,123,73,13,163,30,46,177,27,72,62,210,67,45,89,110,251,195,246,219,233,166,145,103,81,31,169,176,204,122,206,12,116,148,97,185,102,241,6,5,222,0,0,0,0,119,7,48,150,238,14,97,44,153,9,81,186,7,109,196,25,112,106,244,143,233,99,165,53,158,100,149,163,14,219,136,50,121,220,184,164,224,213,233,30,151,210,217,136,9,182,76,43,126,177,124,189,231,184,45,7,144,191,29,145,29,183,16,100,106,176,32,242,243,185,113,72,132,190,65,222,26,218,212,125,109,221,228,235,244,212,181,81,131,211,133,199,19,108,152,86,100,107,168,192,253,98,249,122,138,101,201,236,20,1,92,79,99,6,108,217,250,15,61,99,141,8,13,245,59,110,32,200,76,105,16,94,213,96,65,228,162,103,113,114,60,3,228,209,75,4,212,71,210,13,133,253,165,10,181,107,53,181,168,250,66,178,152,108,219,187,201,214,172,188,249,64,50,216,108,227,69,223,92,117,220,214,13,207,171,209,61,89,38,217,48,172,81,222,0,58,200,215,81,128,191,208,97,22,33,180,244,181,86,179,196,35,207,186,149,153,184,189,165,15,40,2,184,158,95,5,136,8,198,12,217,178,177,11,233,36,47,111,124,135,88,104,76,17,193,97,29,171,182,102,45,61,118,220,65,144,1,219,113,6,152,210,32,188,239,213,16,42,113,177,133,137,6,182,181,31,159,191,228,165,232,184,212,51,120,7,201,162,15,0,249,52,150,9,168,142,225,14,152,24,127,106,13,187,8,109,61,45,145,100,108,151,230,99,92,1,107,107,81,244,28,108,97,98,133,101,48,216,242,98,0,78,108,6,149,237,27,1,165,123,130,8,244,193,245,15,196,87,101,176,217,198,18,183,233,80,139,190,184,234,252,185,136,124,98,221,29,223,21,218,45,73,140,211,124,243,251,212,76,101,77,178,97,88,58,181,81,206,163,188,0,116,212,187,48,226,74,223,165,65,61,216,149,215,164,209,196,109,211,214,244,251,67,105,233,106,52,110,217,252,173,103,136,70,218,96,184,208,68,4,45,115,51,3,29,229,170,10,76,95,221,13,124,201,80,5,113,60,39,2,65,170,190,11,16,16,201,12,32,134,87,104,181,37,32,111,133,179,185,102,212,9,206,97,228,159,94,222,249,14,41,217,201,152,176,208,152,34,199,215,168,180,89,179,61,23,46,180,13,129,183,189,92,59,192,186,108,173,237,184,131,32,154,191,179,182,3,182,226,12,116,177,210,154,234,213,71,57,157,210,119,175,4,219,38,21,115,220,22,131,227,99,11,18,148,100,59,132,13,109,106,62,122,106,90,168,228,14,207,11,147,9,255,157,10,0,174,39,125,7,158,177,240,15,147,68,135,8,163,210,30,1,242,104,105,6,194,254,247,98,87,93,128,101,103,203,25,108,54,113,110,107,6,231,254,212,27,118,137,211,43,224,16,218,122,90,103,221,74,204,249,185,223,111,142,190,239,249,23,183,190,67,96,176,142,213,214,214,163,232,161,209,147,126,56,216,194,196,79,223,242,82,209,187,103,241,166,188,87,103,63,181,6,221,72,178,54,75,216,13,43,218,175,10,27,76,54,3,74,246,65,4,122,96,223,96,239,195,168,103,223,85,49,110,142,239,70,105,190,121,203,97,179,140,188,102,131,26,37,111,210,160,82,104,226,54,204,12,119,149,187,11,71,3,34,2,22,185,85,5,38,47,197,186,59,190,178,189,11,40,43,180,90,146,92,179,106,4,194,215,255,167,181,208,207,49,44,217,158,139,91,222,174,29,155,100,194,176,236,99,242,38,117,106,163,156,2,109,147,10,156,9,6,169,235,14,54,63,114,7,103,133,5,0,87,19,149,191,74,130,226,184,122,20,123,177,43,174,12,182,27,56,146,210,142,155,229,213,190,13,124,220,239,183,11,219,223,33,134,211,210,212,241,212,226,66,104,221,179,248,31,218,131,110,129,190,22,205,246,185,38,91,111,176,119,225,24,183,71,119,136,8,90,230,255,15,106,112,102,6,59,202,17,1,11,92,143,101,158,255,248,98,174,105,97,107,255,211,22,108,207,69,160,10,226,120,215,13,210,238,78,4,131,84,57,3,179,194,167,103,38,97,208,96,22,247,73,105,71,77,62,110,119,219,174,209,106,74,217,214,90,220,64,223,11,102,55,216,59,240,169,188,174,83,222,187,158,197,71,178,207,127,48,181,255,233,189,189,242,28,202,186,194,138,83,179,147,48,36,180,163,166,186,208,54,5,205,215,6,147,84,222,87,41,35,217,103,191,179,102,122,46,196,97,74,184,93,104,27,2,42,111,43,148,180,11,190,55,195,12,142,161,90,5,223,27,45,2,239,141,0,0,0,0,25,27,49,65,50,54,98,130,43,45,83,195,100,108,197,4,125,119,244,69,86,90,167,134,79,65,150,199,200,217,138,8,209,194,187,73,250,239,232,138,227,244,217,203,172,181,79,12,181,174,126,77,158,131,45,142,135,152,28,207,74,194,18,81,83,217,35,16,120,244,112,211,97,239,65,146,46,174,215,85,55,181,230,20,28,152,181,215,5,131,132,150,130,27,152,89,155,0,169,24,176,45,250,219,169,54,203,154,230,119,93,93,255,108,108,28,212,65,63,223,205,90,14,158,149,132,36,162,140,159,21,227,167,178,70,32,190,169,119,97,241,232,225,166,232,243,208,231,195,222,131,36,218,197,178,101,93,93,174,170,68,70,159,235,111,107,204,40,118,112,253,105,57,49,107,174,32,42,90,239,11,7,9,44,18,28,56,109,223,70,54,243,198,93,7,178,237,112,84,113,244,107,101,48,187,42,243,247,162,49,194,182,137,28,145,117,144,7,160,52,23,159,188,251,14,132,141,186,37,169,222,121,60,178,239,56,115,243,121,255,106,232,72,190,65,197,27,125,88,222,42,60,240,121,79,5,233,98,126,68,194,79,45,135,219,84,28,198,148,21,138,1,141,14,187,64,166,35,232,131,191,56,217,194,56,160,197,13,33,187,244,76,10,150,167,143,19,141,150,206,92,204,0,9,69,215,49,72,110,250,98,139,119,225,83,202,186,187,93,84,163,160,108,21,136,141,63,214,145,150,14,151,222,215,152,80,199,204,169,17,236,225,250,210,245,250,203,147,114,98,215,92,107,121,230,29,64,84,181,222,89,79,132,159,22,14,18,88,15,21,35,25,36,56,112,218,61,35,65,155,101,253,107,167,124,230,90,230,87,203,9,37,78,208,56,100,1,145,174,163,24,138,159,226,51,167,204,33,42,188,253,96,173,36,225,175,180,63,208,238,159,18,131,45,134,9,178,108,201,72,36,171,208,83,21,234,251,126,70,41,226,101,119,104,47,63,121,246,54,36,72,183,29,9,27,116,4,18,42,53,75,83,188,242,82,72,141,179,121,101,222,112,96,126,239,49,231,230,243,254,254,253,194,191,213,208,145,124,204,203,160,61,131,138,54,250,154,145,7,187,177,188,84,120,168,167,101,57,59,131,152,75,34,152,169,10,9,181,250,201,16,174,203,136,95,239,93,79,70,244,108,14,109,217,63,205,116,194,14,140,243,90,18,67,234,65,35,2,193,108,112,193,216,119,65,128,151,54,215,71,142,45,230,6,165,0,181,197,188,27,132,132,113,65,138,26,104,90,187,91,67,119,232,152,90,108,217,217,21,45,79,30,12,54,126,95,39,27,45,156,62,0,28,221,185,152,0,18,160,131,49,83,139,174,98,144,146,181,83,209,221,244,197,22,196,239,244,87,239,194,167,148,246,217,150,213,174,7,188,233,183,28,141,168,156,49,222,107,133,42,239,42,202,107,121,237,211,112,72,172,248,93,27,111,225,70,42,46,102,222,54,225,127,197,7,160,84,232,84,99,77,243,101,34,2,178,243,229,27,169,194,164,48,132,145,103,41,159,160,38,228,197,174,184,253,222,159,249,214,243,204,58,207,232,253,123,128,169,107,188,153,178,90,253,178,159,9,62,171,132,56,127,44,28,36,176,53,7,21,241,30,42,70,50,7,49,119,115,72,112,225,180,81,107,208,245,122,70,131,54,99,93,178,119,203,250,215,78,210,225,230,15,249,204,181,204,224,215,132,141,175,150,18,74,182,141,35,11,157,160,112,200,132,187,65,137,3,35,93,70,26,56,108,7,49,21,63,196,40,14,14,133,103,79,152,66,126,84,169,3,85,121,250,192,76,98,203,129,129,56,197,31,152,35,244,94,179,14,167,157,170,21,150,220,229,84,0,27,252,79,49,90,215,98,98,153,206,121,83,216,73,225,79,23,80,250,126,86,123,215,45,149,98,204,28,212,45,141,138,19,52,150,187,82,31,187,232,145,6,160,217,208,94,126,243,236,71,101,194,173,108,72,145,110,117,83,160,47,58,18,54,232,35,9,7,169,8,36,84,106,17,63,101,43,150,167,121,228,143,188,72,165,164,145,27,102,189,138,42,39,242,203,188,224,235,208,141,161,192,253,222,98,217,230,239,35,20,188,225,189,13,167,208,252,38,138,131,63,63,145,178,126,112,208,36,185,105,203,21,248,66,230,70,59,91,253,119,122,220,101,107,181,197,126,90,244,238,83,9,55,247,72,56,118,184,9,174,177,161,18,159,240,138,63,204,51,147,36,253,114,0,0,0,0,1,194,106,55,3,132,212,110,2,70,190,89,7,9,168,220,6,203,194,235,4,141,124,178,5,79,22,133,14,19,81,184,15,209,59,143,13,151,133,214,12,85,239,225,9,26,249,100,8,216,147,83,10,158,45,10,11,92,71,61,28,38,163,112,29,228,201,71,31,162,119,30,30,96,29,41,27,47,11,172,26,237,97,155,24,171,223,194,25,105,181,245,18,53,242,200,19,247,152,255,17,177,38,166,16,115,76,145,21,60,90,20,20,254,48,35,22,184,142,122,23,122,228,77,56,77,70,224,57,143,44,215,59,201,146,142,58,11,248,185,63,68,238,60,62,134,132,11,60,192,58,82,61,2,80,101,54,94,23,88,55,156,125,111,53,218,195,54,52,24,169,1,49,87,191,132,48,149,213,179,50,211,107,234,51,17,1,221,36,107,229,144,37,169,143,167,39,239,49,254,38,45,91,201,35,98,77,76,34,160,39,123,32,230,153,34,33,36,243,21,42,120,180,40,43,186,222,31,41,252,96,70,40,62,10,113,45,113,28,244,44,179,118,195,46,245,200,154,47,55,162,173,112,154,141,192,113,88,231,247,115,30,89,174,114,220,51,153,119,147,37,28,118,81,79,43,116,23,241,114,117,213,155,69,126,137,220,120,127,75,182,79,125,13,8,22,124,207,98,33,121,128,116,164,120,66,30,147,122,4,160,202,123,198,202,253,108,188,46,176,109,126,68,135,111,56,250,222,110,250,144,233,107,181,134,108,106,119,236,91,104,49,82,2,105,243,56,53,98,175,127,8,99,109,21,63,97,43,171,102,96,233,193,81,101,166,215,212,100,100,189,227,102,34,3,186,103,224,105,141,72,215,203,32,73,21,161,23,75,83,31,78,74,145,117,121,79,222,99,252,78,28,9,203,76,90,183,146,77,152,221,165,70,196,154,152,71,6,240,175,69,64,78,246,68,130,36,193,65,205,50,68,64,15,88,115,66,73,230,42,67,139,140,29,84,241,104,80,85,51,2,103,87,117,188,62,86,183,214,9,83,248,192,140,82,58,170,187,80,124,20,226,81,190,126,213,90,226,57,232,91,32,83,223,89,102,237,134,88,164,135,177,93,235,145,52,92,41,251,3,94,111,69,90,95,173,47,109,225,53,27,128,224,247,113,183,226,177,207,238,227,115,165,217,230,60,179,92,231,254,217,107,229,184,103,50,228,122,13,5,239,38,74,56,238,228,32,15,236,162,158,86,237,96,244,97,232,47,226,228,233,237,136,211,235,171,54,138,234,105,92,189,253,19,184,240,252,209,210,199,254,151,108,158,255,85,6,169,250,26,16,44,251,216,122,27,249,158,196,66,248,92,174,117,243,0,233,72,242,194,131,127,240,132,61,38,241,70,87,17,244,9,65,148,245,203,43,163,247,141,149,250,246,79,255,205,217,120,93,96,216,186,55,87,218,252,137,14,219,62,227,57,222,113,245,188,223,179,159,139,221,245,33,210,220,55,75,229,215,107,12,216,214,169,102,239,212,239,216,182,213,45,178,129,208,98,164,4,209,160,206,51,211,230,112,106,210,36,26,93,197,94,254,16,196,156,148,39,198,218,42,126,199,24,64,73,194,87,86,204,195,149,60,251,193,211,130,162,192,17,232,149,203,77,175,168,202,143,197,159,200,201,123,198,201,11,17,241,204,68,7,116,205,134,109,67,207,192,211,26,206,2,185,45,145,175,150,64,144,109,252,119,146,43,66,46,147,233,40,25,150,166,62,156,151,100,84,171,149,34,234,242,148,224,128,197,159,188,199,248,158,126,173,207,156,56,19,150,157,250,121,161,152,181,111,36,153,119,5,19,155,49,187,74,154,243,209,125,141,137,53,48,140,75,95,7,142,13,225,94,143,207,139,105,138,128,157,236,139,66,247,219,137,4,73,130,136,198,35,181,131,154,100,136,130,88,14,191,128,30,176,230,129,220,218,209,132,147,204,84,133,81,166,99,135,23,24,58,134,213,114,13,169,226,208,160,168,32,186,151,170,102,4,206,171,164,110,249], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE);
+/* memory initializer */ allocate([174,235,120,124,175,41,18,75,173,111,172,18,172,173,198,37,167,241,129,24,166,51,235,47,164,117,85,118,165,183,63,65,160,248,41,196,161,58,67,243,163,124,253,170,162,190,151,157,181,196,115,208,180,6,25,231,182,64,167,190,183,130,205,137,178,205,219,12,179,15,177,59,177,73,15,98,176,139,101,85,187,215,34,104,186,21,72,95,184,83,246,6,185,145,156,49,188,222,138,180,189,28,224,131,191,90,94,218,190,152,52,237,0,0,0,0,184,188,103,101,170,9,200,139,18,181,175,238,143,98,151,87,55,222,240,50,37,107,95,220,157,215,56,185,197,180,40,239,125,8,79,138,111,189,224,100,215,1,135,1,74,214,191,184,242,106,216,221,224,223,119,51,88,99,16,86,80,25,87,159,232,165,48,250,250,16,159,20,66,172,248,113,223,123,192,200,103,199,167,173,117,114,8,67,205,206,111,38,149,173,127,112,45,17,24,21,63,164,183,251,135,24,208,158,26,207,232,39,162,115,143,66,176,198,32,172,8,122,71,201,160,50,175,62,24,142,200,91,10,59,103,181,178,135,0,208,47,80,56,105,151,236,95,12,133,89,240,226,61,229,151,135,101,134,135,209,221,58,224,180,207,143,79,90,119,51,40,63,234,228,16,134,82,88,119,227,64,237,216,13,248,81,191,104,240,43,248,161,72,151,159,196,90,34,48,42,226,158,87,79,127,73,111,246,199,245,8,147,213,64,167,125,109,252,192,24,53,159,208,78,141,35,183,43,159,150,24,197,39,42,127,160,186,253,71,25,2,65,32,124,16,244,143,146,168,72,232,247,155,20,88,61,35,168,63,88,49,29,144,182,137,161,247,211,20,118,207,106,172,202,168,15,190,127,7,225,6,195,96,132,94,160,112,210,230,28,23,183,244,169,184,89,76,21,223,60,209,194,231,133,105,126,128,224,123,203,47,14,195,119,72,107,203,13,15,162,115,177,104,199,97,4,199,41,217,184,160,76,68,111,152,245,252,211,255,144,238,102,80,126,86,218,55,27,14,185,39,77,182,5,64,40,164,176,239,198,28,12,136,163,129,219,176,26,57,103,215,127,43,210,120,145,147,110,31,244,59,38,247,3,131,154,144,102,145,47,63,136,41,147,88,237,180,68,96,84,12,248,7,49,30,77,168,223,166,241,207,186,254,146,223,236,70,46,184,137,84,155,23,103,236,39,112,2,113,240,72,187,201,76,47,222,219,249,128,48,99,69,231,85,107,63,160,156,211,131,199,249,193,54,104,23,121,138,15,114,228,93,55,203,92,225,80,174,78,84,255,64,246,232,152,37,174,139,136,115,22,55,239,22,4,130,64,248,188,62,39,157,33,233,31,36,153,85,120,65,139,224,215,175,51,92,176,202,237,89,182,59,85,229,209,94,71,80,126,176,255,236,25,213,98,59,33,108,218,135,70,9,200,50,233,231,112,142,142,130,40,237,158,212,144,81,249,177,130,228,86,95,58,88,49,58,167,143,9,131,31,51,110,230,13,134,193,8,181,58,166,109,189,64,225,164,5,252,134,193,23,73,41,47,175,245,78,74,50,34,118,243,138,158,17,150,152,43,190,120,32,151,217,29,120,244,201,75,192,72,174,46,210,253,1,192,106,65,102,165,247,150,94,28,79,42,57,121,93,159,150,151,229,35,241,242,77,107,25,5,245,215,126,96,231,98,209,142,95,222,182,235,194,9,142,82,122,181,233,55,104,0,70,217,208,188,33,188,136,223,49,234,48,99,86,143,34,214,249,97,154,106,158,4,7,189,166,189,191,1,193,216,173,180,110,54,21,8,9,83,29,114,78,154,165,206,41,255,183,123,134,17,15,199,225,116,146,16,217,205,42,172,190,168,56,25,17,70,128,165,118,35,216,198,102,117,96,122,1,16,114,207,174,254,202,115,201,155,87,164,241,34,239,24,150,71,253,173,57,169,69,17,94,204,118,77,238,6,206,241,137,99,220,68,38,141,100,248,65,232,249,47,121,81,65,147,30,52,83,38,177,218,235,154,214,191,179,249,198,233,11,69,161,140,25,240,14,98,161,76,105,7,60,155,81,190,132,39,54,219,150,146,153,53,46,46,254,80,38,84,185,153,158,232,222,252,140,93,113,18,52,225,22,119,169,54,46,206,17,138,73,171,3,63,230,69,187,131,129,32,227,224,145,118,91,92,246,19,73,233,89,253,241,85,62,152,108,130,6,33,212,62,97,68,198,139,206,170,126,55,169,207,214,127,65,56,110,195,38,93,124,118,137,179,196,202,238,214,89,29,214,111,225,161,177,10,243,20,30,228,75,168,121,129,19,203,105,215,171,119,14,178,185,194,161,92,1,126,198,57,156,169,254,128,36,21,153,229,54,160,54,11,142,28,81,110,134,102,22,167,62,218,113,194,44,111,222,44,148,211,185,73,9,4,129,240,177,184,230,149,163,13,73,123,27,177,46,30,67,210,62,72,251,110,89,45,233,219,246,195,81,103,145,166,204,176,169,31,116,12,206,122,102,185,97,148,222,5,6,241,16,0,17,0,18,0,0,0,8,0,7,0,9,0,6,0,10,0,5,0,11,0,4,0,12,0,3,0,13,0,2,0,14,0,1,0,15,0,0,0,105,110,99,111,114,114,101,99,116,32,104,101,97,100,101,114,32,99,104,101,99,107,0,0,117,110,107,110,111,119,110,32,99,111,109,112,114,101,115,115,105,111,110,32,109,101,116,104,111,100,0,0,0,0,0,0,105,110,118,97,108,105,100,32,119,105,110,100,111,119,32,115,105,122,101,0,0,0,0,0,117,110,107,110,111,119,110,32,104,101,97,100,101,114,32,102,108,97,103,115,32,115,101,116,0,0,0,0,0,0,0,0,104,101,97,100,101,114,32,99,114,99,32,109,105,115,109,97,116,99,104,0,0,0,0,0,105,110,118,97,108,105,100,32,98,108,111,99,107,32,116,121,112,101,0,0,0,0,0,0,105,110,118,97,108,105,100,32,115,116,111,114,101,100,32,98,108,111,99,107,32,108,101,110,103,116,104,115,0,0,0,0,116,111,111,32,109,97,110,121,32,108,101,110,103,116,104,32,111,114,32,100,105,115,116,97,110,99,101,32,115,121,109,98,111,108,115,0,0,0,0,0,105,110,118,97,108,105,100,32,99,111,100,101,32,108,101,110,103,116,104,115,32,115,101,116,0,0,0,0,0,0,0,0,105,110,118,97,108,105,100,32,98,105,116,32,108,101,110,103,116,104,32,114,101,112,101,97,116,0,0,0,0,0,0,0,105,110,118,97,108,105,100,32,99,111,100,101,32,45,45,32,109,105,115,115,105,110,103,32,101,110,100,45,111,102,45,98,108,111,99,107,0,0,0,0,105,110,118,97,108,105,100,32,108,105,116,101,114,97,108,47,108,101,110,103,116,104,115,32,115,101,116,0,0,0,0,0,105,110,118,97,108,105,100,32,100,105,115,116,97,110,99,101,115,32,115,101,116,0,0,0,105,110,118,97,108,105,100,32,108,105,116,101,114,97,108,47,108,101,110,103,116,104,32,99,111,100,101,0,0,0,0,0,105,110,118,97,108,105,100,32,100,105,115,116,97,110,99,101,32,99,111,100,101,0,0,0,105,110,118,97,108,105,100,32,100,105,115,116,97,110,99,101,32,116,111,111,32,102,97,114,32,98,97,99,107,0,0,0,105,110,99,111,114,114,101,99,116,32,100,97,116,97,32,99,104,101,99,107,0,0,0,0,105,110,99,111,114,114,101,99,116,32,108,101,110,103,116,104,32,99,104,101,99,107,0,0,96,7,0,0,0,8,80,0,0,8,16,0,20,8,115,0,18,7,31,0,0,8,112,0,0,8,48,0,0,9,192,0,16,7,10,0,0,8,96,0,0,8,32,0,0,9,160,0,0,8,0,0,0,8,128,0,0,8,64,0,0,9,224,0,16,7,6,0,0,8,88,0,0,8,24,0,0,9,144,0,19,7,59,0,0,8,120,0,0,8,56,0,0,9,208,0,17,7,17,0,0,8,104,0,0,8,40,0,0,9,176,0,0,8,8,0,0,8,136,0,0,8,72,0,0,9,240,0,16,7,4,0,0,8,84,0,0,8,20,0,21,8,227,0,19,7,43,0,0,8,116,0,0,8,52,0,0,9,200,0,17,7,13,0,0,8,100,0,0,8,36,0,0,9,168,0,0,8,4,0,0,8,132,0,0,8,68,0,0,9,232,0,16,7,8,0,0,8,92,0,0,8,28,0,0,9,152,0,20,7,83,0,0,8,124,0,0,8,60,0,0,9,216,0,18,7,23,0,0,8,108,0,0,8,44,0,0,9,184,0,0,8,12,0,0,8,140,0,0,8,76,0,0,9,248,0,16,7,3,0,0,8,82,0,0,8,18,0,21,8,163,0,19,7,35,0,0,8,114,0,0,8,50,0,0,9,196,0,17,7,11,0,0,8,98,0,0,8,34,0,0,9,164,0,0,8,2,0,0,8,130,0,0,8,66,0,0,9,228,0,16,7,7,0,0,8,90,0,0,8,26,0,0,9,148,0,20,7,67,0,0,8,122,0,0,8,58,0,0,9,212,0,18,7,19,0,0,8,106,0,0,8,42,0,0,9,180,0,0,8,10,0,0,8,138,0,0,8,74,0,0,9,244,0,16,7,5,0,0,8,86,0,0,8,22,0,64,8,0,0,19,7,51,0,0,8,118,0,0,8,54,0,0,9,204,0,17,7,15,0,0,8,102,0,0,8,38,0,0,9,172,0,0,8,6,0,0,8,134,0,0,8,70,0,0,9,236,0,16,7,9,0,0,8,94,0,0,8,30,0,0,9,156,0,20,7,99,0,0,8,126,0,0,8,62,0,0,9,220,0,18,7,27,0,0,8,110,0,0,8,46,0,0,9,188,0,0,8,14,0,0,8,142,0,0,8,78,0,0,9,252,0,96,7,0,0,0,8,81,0,0,8,17,0,21,8,131,0,18,7,31,0,0,8,113,0,0,8,49,0,0,9,194,0,16,7,10,0,0,8,97,0,0,8,33,0,0,9,162,0,0,8,1,0,0,8,129,0,0,8,65,0,0,9,226,0,16,7,6,0,0,8,89,0,0,8,25,0,0,9,146,0,19,7,59,0,0,8,121,0,0,8,57,0,0,9,210,0,17,7,17,0,0,8,105,0,0,8,41,0,0,9,178,0,0,8,9,0,0,8,137,0,0,8,73,0,0,9,242,0,16,7,4,0,0,8,85,0,0,8,21,0,16,8,2,1,19,7,43,0,0,8,117,0,0,8,53,0,0,9,202,0,17,7,13,0,0,8,101,0,0,8,37,0,0,9,170,0,0,8,5,0,0,8,133,0,0,8,69,0,0,9,234,0,16,7,8,0,0,8,93,0,0,8,29,0,0,9,154,0,20,7,83,0,0,8,125,0,0,8,61,0,0,9,218,0,18,7,23,0,0,8,109,0,0,8,45,0,0,9,186,0,0,8,13,0,0,8,141,0,0,8,77,0,0,9,250,0,16,7,3,0,0,8,83,0,0,8,19,0,21,8,195,0,19,7,35,0,0,8,115,0,0,8,51,0,0,9,198,0,17,7,11,0,0,8,99,0,0,8,35,0,0,9,166,0,0,8,3,0,0,8,131,0,0,8,67,0,0,9,230,0,16,7,7,0,0,8,91,0,0,8,27,0,0,9,150,0,20,7,67,0,0,8,123,0,0,8,59,0,0,9,214,0,18,7,19,0,0,8,107,0,0,8,43,0,0,9,182,0,0,8,11,0,0,8,139,0,0,8,75,0,0,9,246,0,16,7,5,0,0,8,87,0,0,8,23,0,64,8,0,0,19,7,51,0,0,8,119,0,0,8,55,0,0,9,206,0,17,7,15,0,0,8,103,0,0,8,39,0,0,9,174,0,0,8,7,0,0,8,135,0,0,8,71,0,0,9,238,0,16,7,9,0,0,8,95,0,0,8,31,0,0,9,158,0,20,7,99,0,0,8,127,0,0,8,63,0,0,9,222,0,18,7,27,0,0,8,111,0,0,8,47,0,0,9,190,0,0,8,15,0,0,8,143,0,0,8,79,0,0,9,254,0,96,7,0,0,0,8,80,0,0,8,16,0,20,8,115,0,18,7,31,0,0,8,112,0,0,8,48,0,0,9,193,0,16,7,10,0,0,8,96,0,0,8,32,0,0,9,161,0,0,8,0,0,0,8,128,0,0,8,64,0,0,9,225,0,16,7,6,0,0,8,88,0,0,8,24,0,0,9,145,0,19,7,59,0,0,8,120,0,0,8,56,0,0,9,209,0,17,7,17,0,0,8,104,0,0,8,40,0,0,9,177,0,0,8,8,0,0,8,136,0,0,8,72,0,0,9,241,0,16,7,4,0,0,8,84,0,0,8,20,0,21,8,227,0,19,7,43,0,0,8,116,0,0,8,52,0,0,9,201,0,17,7,13,0,0,8,100,0,0,8,36,0,0,9,169,0,0,8,4,0,0,8,132,0,0,8,68,0,0,9,233,0,16,7,8,0,0,8,92,0,0,8,28,0,0,9,153,0,20,7,83,0,0,8,124,0,0,8,60,0,0,9,217,0,18,7,23,0,0,8,108,0,0,8,44,0,0,9,185,0,0,8,12,0,0,8,140,0,0,8,76,0,0,9,249,0,16,7,3,0,0,8,82,0,0,8,18,0,21,8,163,0,19,7,35,0,0,8,114,0,0,8,50,0,0,9,197,0,17,7,11,0,0,8,98,0,0,8,34,0,0,9,165,0,0,8,2,0,0,8,130,0,0,8,66,0,0,9,229,0,16,7,7,0,0,8,90,0,0,8,26,0,0,9,149,0,20,7,67,0,0,8,122,0,0,8,58,0,0,9,213,0,18,7,19,0,0,8,106,0,0,8,42,0,0,9,181,0,0,8,10,0,0,8,138,0,0,8,74,0,0,9,245,0,16,7,5,0,0,8,86,0,0,8,22,0,64,8,0,0,19,7,51,0,0,8,118,0,0,8,54,0,0,9,205,0,17,7,15,0,0,8,102,0,0,8,38,0,0,9,173,0,0,8,6,0,0,8,134,0,0,8,70,0,0,9,237,0,16,7,9,0,0,8,94,0,0,8,30,0,0,9,157,0,20,7,99,0,0,8,126,0,0,8,62,0,0,9,221,0,18,7,27,0,0,8,110,0,0,8,46,0,0,9,189,0,0,8,14,0,0,8,142,0,0,8,78,0,0,9,253,0,96,7,0,0,0,8,81,0,0,8,17,0,21,8,131,0,18,7,31,0,0,8,113,0,0,8,49,0,0,9,195,0,16,7,10,0,0,8,97,0,0,8,33,0,0,9,163,0,0,8,1,0,0,8,129,0,0,8,65,0,0,9,227,0,16,7,6,0,0,8,89,0,0,8,25,0,0,9,147,0,19,7,59,0,0,8,121,0,0,8,57,0,0,9,211,0,17,7,17,0,0,8,105,0,0,8,41,0,0,9,179,0,0,8,9,0,0,8,137,0,0,8,73,0,0,9,243,0,16,7,4,0,0,8,85,0,0,8,21,0,16,8,2,1,19,7,43,0,0,8,117,0,0,8,53,0,0,9,203,0,17,7,13,0,0,8,101,0,0,8,37,0,0,9,171,0,0,8,5,0,0,8,133,0,0,8,69,0,0,9,235,0,16,7,8,0,0,8,93,0,0,8,29,0,0,9,155,0,20,7,83,0,0,8,125,0,0,8,61,0,0,9,219,0,18,7,23,0,0,8,109,0,0,8,45,0,0,9,187,0,0,8,13,0,0,8,141,0,0,8,77,0,0,9,251,0,16,7,3,0,0,8,83,0,0,8,19,0,21,8,195,0,19,7,35,0,0,8,115,0,0,8,51,0,0,9,199,0,17,7,11,0,0,8,99,0,0,8,35,0,0,9,167,0,0,8,3,0,0,8,131,0,0,8,67,0,0,9,231,0,16,7,7,0,0,8,91,0,0,8,27,0,0,9,151,0,20,7,67,0,0,8,123,0,0,8,59,0,0,9,215,0,18,7,19,0,0,8,107,0,0,8,43,0,0,9,183,0,0,8,11,0,0,8,139,0,0,8,75,0,0,9,247,0,16,7,5,0,0,8,87,0,0,8,23,0,64,8,0,0,19,7,51,0,0,8,119,0,0,8,55,0,0,9,207,0,17,7,15,0,0,8,103,0,0,8,39,0,0,9,175,0,0,8,7,0,0,8,135,0,0,8,71,0,0,9,239,0,16,7,9,0,0,8,95,0,0,8,31,0,0,9,159,0,20,7,99,0,0,8,127,0,0,8,63,0,0,9,223,0,18,7,27,0,0,8,111,0,0,8,47,0,0,9,191,0,0,8,15,0,0,8,143,0,0,8,79,0,0,9,255,0,16,5,1,0,23,5,1,1,19,5,17,0,27,5,1,16,17,5,5,0,25,5,1,4,21,5,65,0,29,5,1,64,16,5,3,0,24,5,1,2,20,5,33,0,28,5,1,32,18,5,9,0,26,5,1,8,22,5,129,0,64,5,0,0,16,5,2,0,23,5,129,1,19,5,25,0,27,5,1,24,17,5,7,0,25,5,1,6,21,5,97,0,29,5,1,96,16,5,4,0,24,5,1,3,20,5,49,0,28,5,1,48,18,5,13,0,26,5,1,12,22,5,193,0,64,5,0,0,3,0,4,0,5,0,6,0,7,0,8,0,9,0,10,0,11,0,13,0,15,0,17,0,19,0,23,0,27,0,31,0,35,0,43,0,51,0,59,0,67,0,83,0,99,0,115,0,131,0,163,0,195,0,227,0,2,1,0,0,0,0,0,0,16,0,16,0,16,0,16,0,16,0,16,0,16,0,16,0,17,0,17,0,17,0,17,0,18,0,18,0,18,0,18,0,19,0,19,0,19,0,19,0,20,0,20,0,20,0,20,0,21,0,21,0,21,0,21,0,16,0,73,0,195,0,0,0,1,0,2,0,3,0,4,0,5,0,7,0,9,0,13,0,17,0,25,0,33,0,49,0,65,0,97,0,129,0,193,0,1,1,129,1,1,2,1,3,1,4,1,6,1,8,1,12,1,16,1,24,1,32,1,48,1,64,1,96,0,0,0,0,16,0,16,0,16,0,16,0,17,0,17,0,18,0,18,0,19,0,19,0,20,0,20,0,21,0,21,0,22,0,22,0,23,0,23,0,24,0,24,0,25,0,25,0,26,0,26,0,27,0,27,0,28,0,28,0,29,0,29,0,64,0,64,0,105,110,118,97,108,105,100,32,100,105,115,116,97,110,99,101,32,116,111,111,32,102,97,114,32,98,97,99,107,0,0,0,105,110,118,97,108,105,100,32,100,105,115,116,97,110,99,101,32,99,111,100,101,0,0,0,105,110,118,97,108,105,100,32,108,105,116,101,114,97,108,47,108,101,110,103,116,104,32,99,111,100,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], "i8", ALLOC_NONE, Runtime.GLOBAL_BASE+10240);
+
+
+
+
+var tempDoublePtr = Runtime.alignMemory(allocate(12, "i8", ALLOC_STATIC), 8);
+
+assert(tempDoublePtr % 8 == 0);
+
+function copyTempFloat(ptr) { // functions, because inlining this code increases code size too much
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+}
+
+function copyTempDouble(ptr) {
+
+  HEAP8[tempDoublePtr] = HEAP8[ptr];
+
+  HEAP8[tempDoublePtr+1] = HEAP8[ptr+1];
+
+  HEAP8[tempDoublePtr+2] = HEAP8[ptr+2];
+
+  HEAP8[tempDoublePtr+3] = HEAP8[ptr+3];
+
+  HEAP8[tempDoublePtr+4] = HEAP8[ptr+4];
+
+  HEAP8[tempDoublePtr+5] = HEAP8[ptr+5];
+
+  HEAP8[tempDoublePtr+6] = HEAP8[ptr+6];
+
+  HEAP8[tempDoublePtr+7] = HEAP8[ptr+7];
+
+}
+
+
+
+
+
+
+  var ERRNO_CODES={EPERM:1,ENOENT:2,ESRCH:3,EINTR:4,EIO:5,ENXIO:6,E2BIG:7,ENOEXEC:8,EBADF:9,ECHILD:10,EAGAIN:11,EWOULDBLOCK:11,ENOMEM:12,EACCES:13,EFAULT:14,ENOTBLK:15,EBUSY:16,EEXIST:17,EXDEV:18,ENODEV:19,ENOTDIR:20,EISDIR:21,EINVAL:22,ENFILE:23,EMFILE:24,ENOTTY:25,ETXTBSY:26,EFBIG:27,ENOSPC:28,ESPIPE:29,EROFS:30,EMLINK:31,EPIPE:32,EDOM:33,ERANGE:34,ENOMSG:42,EIDRM:43,ECHRNG:44,EL2NSYNC:45,EL3HLT:46,EL3RST:47,ELNRNG:48,EUNATCH:49,ENOCSI:50,EL2HLT:51,EDEADLK:35,ENOLCK:37,EBADE:52,EBADR:53,EXFULL:54,ENOANO:55,EBADRQC:56,EBADSLT:57,EDEADLOCK:35,EBFONT:59,ENOSTR:60,ENODATA:61,ETIME:62,ENOSR:63,ENONET:64,ENOPKG:65,EREMOTE:66,ENOLINK:67,EADV:68,ESRMNT:69,ECOMM:70,EPROTO:71,EMULTIHOP:72,EDOTDOT:73,EBADMSG:74,ENOTUNIQ:76,EBADFD:77,EREMCHG:78,ELIBACC:79,ELIBBAD:80,ELIBSCN:81,ELIBMAX:82,ELIBEXEC:83,ENOSYS:38,ENOTEMPTY:39,ENAMETOOLONG:36,ELOOP:40,EOPNOTSUPP:95,EPFNOSUPPORT:96,ECONNRESET:104,ENOBUFS:105,EAFNOSUPPORT:97,EPROTOTYPE:91,ENOTSOCK:88,ENOPROTOOPT:92,ESHUTDOWN:108,ECONNREFUSED:111,EADDRINUSE:98,ECONNABORTED:103,ENETUNREACH:101,ENETDOWN:100,ETIMEDOUT:110,EHOSTDOWN:112,EHOSTUNREACH:113,EINPROGRESS:115,EALREADY:114,EDESTADDRREQ:89,EMSGSIZE:90,EPROTONOSUPPORT:93,ESOCKTNOSUPPORT:94,EADDRNOTAVAIL:99,ENETRESET:102,EISCONN:106,ENOTCONN:107,ETOOMANYREFS:109,EUSERS:87,EDQUOT:122,ESTALE:116,ENOTSUP:95,ENOMEDIUM:123,EILSEQ:84,EOVERFLOW:75,ECANCELED:125,ENOTRECOVERABLE:131,EOWNERDEAD:130,ESTRPIPE:86};
+
+  var ERRNO_MESSAGES={0:"Success",1:"Not super-user",2:"No such file or directory",3:"No such process",4:"Interrupted system call",5:"I/O error",6:"No such device or address",7:"Arg list too long",8:"Exec format error",9:"Bad file number",10:"No children",11:"No more processes",12:"Not enough core",13:"Permission denied",14:"Bad address",15:"Block device required",16:"Mount device busy",17:"File exists",18:"Cross-device link",19:"No such device",20:"Not a directory",21:"Is a directory",22:"Invalid argument",23:"Too many open files in system",24:"Too many open files",25:"Not a typewriter",26:"Text file busy",27:"File too large",28:"No space left on device",29:"Illegal seek",30:"Read only file system",31:"Too many links",32:"Broken pipe",33:"Math arg out of domain of func",34:"Math result not representable",35:"File locking deadlock error",36:"File or path name too long",37:"No record locks available",38:"Function not implemented",39:"Directory not empty",40:"Too many symbolic links",42:"No message of desired type",43:"Identifier removed",44:"Channel number out of range",45:"Level 2 not synchronized",46:"Level 3 halted",47:"Level 3 reset",48:"Link number out of range",49:"Protocol driver not attached",50:"No CSI structure available",51:"Level 2 halted",52:"Invalid exchange",53:"Invalid request descriptor",54:"Exchange full",55:"No anode",56:"Invalid request code",57:"Invalid slot",59:"Bad font file fmt",60:"Device not a stream",61:"No data (for no delay io)",62:"Timer expired",63:"Out of streams resources",64:"Machine is not on the network",65:"Package not installed",66:"The object is remote",67:"The link has been severed",68:"Advertise error",69:"Srmount error",70:"Communication error on send",71:"Protocol error",72:"Multihop attempted",73:"Cross mount point (not really error)",74:"Trying to read unreadable message",75:"Value too large for defined data type",76:"Given log. name not unique",77:"f.d. invalid for this operation",78:"Remote address changed",79:"Can   access a needed shared lib",80:"Accessing a corrupted shared lib",81:".lib section in a.out corrupted",82:"Attempting to link in too many libs",83:"Attempting to exec a shared library",84:"Illegal byte sequence",86:"Streams pipe error",87:"Too many users",88:"Socket operation on non-socket",89:"Destination address required",90:"Message too long",91:"Protocol wrong type for socket",92:"Protocol not available",93:"Unknown protocol",94:"Socket type not supported",95:"Not supported",96:"Protocol family not supported",97:"Address family not supported by protocol family",98:"Address already in use",99:"Address not available",100:"Network interface is not configured",101:"Network is unreachable",102:"Connection reset by network",103:"Connection aborted",104:"Connection reset by peer",105:"No buffer space available",106:"Socket is already connected",107:"Socket is not connected",108:"Can't send after socket shutdown",109:"Too many references",110:"Connection timed out",111:"Connection refused",112:"Host is down",113:"Host is unreachable",114:"Socket already connected",115:"Connection already in progress",116:"Stale file handle",122:"Quota exceeded",123:"No medium (in tape drive)",125:"Operation canceled",130:"Previous owner died",131:"State not recoverable"};
+
+
+  var ___errno_state=0;function ___setErrNo(value) {
+      // For convenient setting and returning of errno.
+      HEAP32[((___errno_state)>>2)]=value;
+      return value;
+    }
+
+  var PATH={splitPath:function (filename) {
+        var splitPathRe = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
+        return splitPathRe.exec(filename).slice(1);
+      },normalizeArray:function (parts, allowAboveRoot) {
+        // if the path tries to go above the root, `up` ends up > 0
+        var up = 0;
+        for (var i = parts.length - 1; i >= 0; i--) {
+          var last = parts[i];
+          if (last === '.') {
+            parts.splice(i, 1);
+          } else if (last === '..') {
+            parts.splice(i, 1);
+            up++;
+          } else if (up) {
+            parts.splice(i, 1);
+            up--;
+          }
+        }
+        // if the path is allowed to go above the root, restore leading ..s
+        if (allowAboveRoot) {
+          for (; up--; up) {
+            parts.unshift('..');
+          }
+        }
+        return parts;
+      },normalize:function (path) {
+        var isAbsolute = path.charAt(0) === '/',
+            trailingSlash = path.substr(-1) === '/';
+        // Normalize the path
+        path = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), !isAbsolute).join('/');
+        if (!path && !isAbsolute) {
+          path = '.';
+        }
+        if (path && trailingSlash) {
+          path += '/';
+        }
+        return (isAbsolute ? '/' : '') + path;
+      },dirname:function (path) {
+        var result = PATH.splitPath(path),
+            root = result[0],
+            dir = result[1];
+        if (!root && !dir) {
+          // No dirname whatsoever
+          return '.';
+        }
+        if (dir) {
+          // It has a dirname, strip trailing slash
+          dir = dir.substr(0, dir.length - 1);
+        }
+        return root + dir;
+      },basename:function (path) {
+        // EMSCRIPTEN return '/'' for '/', not an empty string
+        if (path === '/') return '/';
+        var lastSlash = path.lastIndexOf('/');
+        if (lastSlash === -1) return path;
+        return path.substr(lastSlash+1);
+      },extname:function (path) {
+        return PATH.splitPath(path)[3];
+      },join:function () {
+        var paths = Array.prototype.slice.call(arguments, 0);
+        return PATH.normalize(paths.join('/'));
+      },join2:function (l, r) {
+        return PATH.normalize(l + '/' + r);
+      },resolve:function () {
+        var resolvedPath = '',
+          resolvedAbsolute = false;
+        for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+          var path = (i >= 0) ? arguments[i] : FS.cwd();
+          // Skip empty and invalid entries
+          if (typeof path !== 'string') {
+            throw new TypeError('Arguments to path.resolve must be strings');
+          } else if (!path) {
+            continue;
+          }
+          resolvedPath = path + '/' + resolvedPath;
+          resolvedAbsolute = path.charAt(0) === '/';
+        }
+        // At this point the path should be resolved to a full absolute path, but
+        // handle relative paths to be safe (might happen when process.cwd() fails)
+        resolvedPath = PATH.normalizeArray(resolvedPath.split('/').filter(function(p) {
+          return !!p;
+        }), !resolvedAbsolute).join('/');
+        return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+      },relative:function (from, to) {
+        from = PATH.resolve(from).substr(1);
+        to = PATH.resolve(to).substr(1);
+        function trim(arr) {
+          var start = 0;
+          for (; start < arr.length; start++) {
+            if (arr[start] !== '') break;
+          }
+          var end = arr.length - 1;
+          for (; end >= 0; end--) {
+            if (arr[end] !== '') break;
+          }
+          if (start > end) return [];
+          return arr.slice(start, end - start + 1);
+        }
+        var fromParts = trim(from.split('/'));
+        var toParts = trim(to.split('/'));
+        var length = Math.min(fromParts.length, toParts.length);
+        var samePartsLength = length;
+        for (var i = 0; i < length; i++) {
+          if (fromParts[i] !== toParts[i]) {
+            samePartsLength = i;
+            break;
+          }
+        }
+        var outputParts = [];
+        for (var i = samePartsLength; i < fromParts.length; i++) {
+          outputParts.push('..');
+        }
+        outputParts = outputParts.concat(toParts.slice(samePartsLength));
+        return outputParts.join('/');
+      }};
+
+  var TTY={ttys:[],init:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // currently, FS.init does not distinguish if process.stdin is a file or TTY
+        //   // device, it always assumes it's a TTY device. because of this, we're forcing
+        //   // process.stdin to UTF8 encoding to at least make stdin reading compatible
+        //   // with text files until FS.init can be refactored.
+        //   process['stdin']['setEncoding']('utf8');
+        // }
+      },shutdown:function () {
+        // https://github.com/kripken/emscripten/pull/1555
+        // if (ENVIRONMENT_IS_NODE) {
+        //   // inolen: any idea as to why node -e 'process.stdin.read()' wouldn't exit immediately (with process.stdin being a tty)?
+        //   // isaacs: because now it's reading from the stream, you've expressed interest in it, so that read() kicks off a _read() which creates a ReadReq operation
+        //   // inolen: I thought read() in that case was a synchronous operation that just grabbed some amount of buffered data if it exists?
+        //   // isaacs: it is. but it also triggers a _read() call, which calls readStart() on the handle
+        //   // isaacs: do process.stdin.pause() and i'd think it'd probably close the pending call
+        //   process['stdin']['pause']();
+        // }
+      },register:function (dev, ops) {
+        TTY.ttys[dev] = { input: [], output: [], ops: ops };
+        FS.registerDevice(dev, TTY.stream_ops);
+      },stream_ops:{open:function (stream) {
+          var tty = TTY.ttys[stream.node.rdev];
+          if (!tty) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          stream.tty = tty;
+          stream.seekable = false;
+        },close:function (stream) {
+          // flush any pending line data
+          if (stream.tty.output.length) {
+            stream.tty.ops.put_char(stream.tty, 10);
+          }
+        },read:function (stream, buffer, offset, length, pos /* ignored */) {
+          if (!stream.tty || !stream.tty.ops.get_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          var bytesRead = 0;
+          for (var i = 0; i < length; i++) {
+            var result;
+            try {
+              result = stream.tty.ops.get_char(stream.tty);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            if (result === undefined && bytesRead === 0) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+            if (result === null || result === undefined) break;
+            bytesRead++;
+            buffer[offset+i] = result;
+          }
+          if (bytesRead) {
+            stream.node.timestamp = Date.now();
+          }
+          return bytesRead;
+        },write:function (stream, buffer, offset, length, pos) {
+          if (!stream.tty || !stream.tty.ops.put_char) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENXIO);
+          }
+          for (var i = 0; i < length; i++) {
+            try {
+              stream.tty.ops.put_char(stream.tty, buffer[offset+i]);
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+          }
+          if (length) {
+            stream.node.timestamp = Date.now();
+          }
+          return i;
+        }},default_tty_ops:{get_char:function (tty) {
+          if (!tty.input.length) {
+            var result = null;
+            if (ENVIRONMENT_IS_NODE) {
+              result = process['stdin']['read']();
+              if (!result) {
+                if (process['stdin']['_readableState'] && process['stdin']['_readableState']['ended']) {
+                  return null;  // EOF
+                }
+                return undefined;  // no data available
+              }
+            } else if (typeof window != 'undefined' &&
+              typeof window.prompt == 'function') {
+              // Browser.
+              result = window.prompt('Input: ');  // returns null on cancel
+              if (result !== null) {
+                result += '\n';
+              }
+            } else if (typeof readline == 'function') {
+              // Command line.
+              result = readline();
+              if (result !== null) {
+                result += '\n';
+              }
+            }
+            if (!result) {
+              return null;
+            }
+            tty.input = intArrayFromString(result, true);
+          }
+          return tty.input.shift();
+        },put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['print'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }},default_tty1_ops:{put_char:function (tty, val) {
+          if (val === null || val === 10) {
+            Module['printErr'](tty.output.join(''));
+            tty.output = [];
+          } else {
+            tty.output.push(TTY.utf8.processCChar(val));
+          }
+        }}};
+
+  var MEMFS={ops_table:null,CONTENT_OWNING:1,CONTENT_FLEXIBLE:2,CONTENT_FIXED:3,mount:function (mount) {
+        return MEMFS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (FS.isBlkdev(mode) || FS.isFIFO(mode)) {
+          // no supported
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (!MEMFS.ops_table) {
+          MEMFS.ops_table = {
+            dir: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                lookup: MEMFS.node_ops.lookup,
+                mknod: MEMFS.node_ops.mknod,
+                rename: MEMFS.node_ops.rename,
+                unlink: MEMFS.node_ops.unlink,
+                rmdir: MEMFS.node_ops.rmdir,
+                readdir: MEMFS.node_ops.readdir,
+                symlink: MEMFS.node_ops.symlink
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek
+              }
+            },
+            file: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: {
+                llseek: MEMFS.stream_ops.llseek,
+                read: MEMFS.stream_ops.read,
+                write: MEMFS.stream_ops.write,
+                allocate: MEMFS.stream_ops.allocate,
+                mmap: MEMFS.stream_ops.mmap
+              }
+            },
+            link: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr,
+                readlink: MEMFS.node_ops.readlink
+              },
+              stream: {}
+            },
+            chrdev: {
+              node: {
+                getattr: MEMFS.node_ops.getattr,
+                setattr: MEMFS.node_ops.setattr
+              },
+              stream: FS.chrdev_stream_ops
+            },
+          };
+        }
+        var node = FS.createNode(parent, name, mode, dev);
+        if (FS.isDir(node.mode)) {
+          node.node_ops = MEMFS.ops_table.dir.node;
+          node.stream_ops = MEMFS.ops_table.dir.stream;
+          node.contents = {};
+        } else if (FS.isFile(node.mode)) {
+          node.node_ops = MEMFS.ops_table.file.node;
+          node.stream_ops = MEMFS.ops_table.file.stream;
+          node.contents = [];
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        } else if (FS.isLink(node.mode)) {
+          node.node_ops = MEMFS.ops_table.link.node;
+          node.stream_ops = MEMFS.ops_table.link.stream;
+        } else if (FS.isChrdev(node.mode)) {
+          node.node_ops = MEMFS.ops_table.chrdev.node;
+          node.stream_ops = MEMFS.ops_table.chrdev.stream;
+        }
+        node.timestamp = Date.now();
+        // add the new node to the parent
+        if (parent) {
+          parent.contents[name] = node;
+        }
+        return node;
+      },ensureFlexible:function (node) {
+        if (node.contentMode !== MEMFS.CONTENT_FLEXIBLE) {
+          var contents = node.contents;
+          node.contents = Array.prototype.slice.call(contents);
+          node.contentMode = MEMFS.CONTENT_FLEXIBLE;
+        }
+      },node_ops:{getattr:function (node) {
+          var attr = {};
+          // device numbers reuse inode numbers.
+          attr.dev = FS.isChrdev(node.mode) ? node.id : 1;
+          attr.ino = node.id;
+          attr.mode = node.mode;
+          attr.nlink = 1;
+          attr.uid = 0;
+          attr.gid = 0;
+          attr.rdev = node.rdev;
+          if (FS.isDir(node.mode)) {
+            attr.size = 4096;
+          } else if (FS.isFile(node.mode)) {
+            attr.size = node.contents.length;
+          } else if (FS.isLink(node.mode)) {
+            attr.size = node.link.length;
+          } else {
+            attr.size = 0;
+          }
+          attr.atime = new Date(node.timestamp);
+          attr.mtime = new Date(node.timestamp);
+          attr.ctime = new Date(node.timestamp);
+          // NOTE: In our implementation, st_blocks = Math.ceil(st_size/st_blksize),
+          //       but this is not required by the standard.
+          attr.blksize = 4096;
+          attr.blocks = Math.ceil(attr.size / attr.blksize);
+          return attr;
+        },setattr:function (node, attr) {
+          if (attr.mode !== undefined) {
+            node.mode = attr.mode;
+          }
+          if (attr.timestamp !== undefined) {
+            node.timestamp = attr.timestamp;
+          }
+          if (attr.size !== undefined) {
+            MEMFS.ensureFlexible(node);
+            var contents = node.contents;
+            if (attr.size < contents.length) contents.length = attr.size;
+            else while (attr.size > contents.length) contents.push(0);
+          }
+        },lookup:function (parent, name) {
+          throw FS.genericErrors[ERRNO_CODES.ENOENT];
+        },mknod:function (parent, name, mode, dev) {
+          return MEMFS.createNode(parent, name, mode, dev);
+        },rename:function (old_node, new_dir, new_name) {
+          // if we're overwriting a directory at new_name, make sure it's empty.
+          if (FS.isDir(old_node.mode)) {
+            var new_node;
+            try {
+              new_node = FS.lookupNode(new_dir, new_name);
+            } catch (e) {
+            }
+            if (new_node) {
+              for (var i in new_node.contents) {
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+              }
+            }
+          }
+          // do the internal rewiring
+          delete old_node.parent.contents[old_node.name];
+          old_node.name = new_name;
+          new_dir.contents[new_name] = old_node;
+          old_node.parent = new_dir;
+        },unlink:function (parent, name) {
+          delete parent.contents[name];
+        },rmdir:function (parent, name) {
+          var node = FS.lookupNode(parent, name);
+          for (var i in node.contents) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+          }
+          delete parent.contents[name];
+        },readdir:function (node) {
+          var entries = ['.', '..']
+          for (var key in node.contents) {
+            if (!node.contents.hasOwnProperty(key)) {
+              continue;
+            }
+            entries.push(key);
+          }
+          return entries;
+        },symlink:function (parent, newname, oldpath) {
+          var node = MEMFS.createNode(parent, newname, 511 /* 0777 */ | 40960, 0);
+          node.link = oldpath;
+          return node;
+        },readlink:function (node) {
+          if (!FS.isLink(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          return node.link;
+        }},stream_ops:{read:function (stream, buffer, offset, length, position) {
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (size > 8 && contents.subarray) { // non-trivial, and typed array
+            buffer.set(contents.subarray(position, position + size), offset);
+          } else
+          {
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          }
+          return size;
+        },write:function (stream, buffer, offset, length, position, canOwn) {
+          var node = stream.node;
+          node.timestamp = Date.now();
+          var contents = node.contents;
+          if (length && contents.length === 0 && position === 0 && buffer.subarray) {
+            // just replace it with the new data
+            if (canOwn && offset === 0) {
+              node.contents = buffer; // this could be a subarray of Emscripten HEAP, or allocated from some other source.
+              node.contentMode = (buffer.buffer === HEAP8.buffer) ? MEMFS.CONTENT_OWNING : MEMFS.CONTENT_FIXED;
+            } else {
+              node.contents = new Uint8Array(buffer.subarray(offset, offset+length));
+              node.contentMode = MEMFS.CONTENT_FIXED;
+            }
+            return length;
+          }
+          MEMFS.ensureFlexible(node);
+          var contents = node.contents;
+          while (contents.length < position) contents.push(0);
+          for (var i = 0; i < length; i++) {
+            contents[position + i] = buffer[offset + i];
+          }
+          return length;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              position += stream.node.contents.length;
+            }
+          }
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          stream.ungotten = [];
+          stream.position = position;
+          return position;
+        },allocate:function (stream, offset, length) {
+          MEMFS.ensureFlexible(stream.node);
+          var contents = stream.node.contents;
+          var limit = offset + length;
+          while (limit > contents.length) contents.push(0);
+        },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+          if (!FS.isFile(stream.node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+          }
+          var ptr;
+          var allocated;
+          var contents = stream.node.contents;
+          // Only make a new copy when MAP_PRIVATE is specified.
+          if ( !(flags & 2) &&
+                (contents.buffer === buffer || contents.buffer === buffer.buffer) ) {
+            // We can't emulate MAP_SHARED when the file is not backed by the buffer
+            // we're mapping to (e.g. the HEAP buffer).
+            allocated = false;
+            ptr = contents.byteOffset;
+          } else {
+            // Try to avoid unnecessary slices.
+            if (position > 0 || position + length < contents.length) {
+              if (contents.subarray) {
+                contents = contents.subarray(position, position + length);
+              } else {
+                contents = Array.prototype.slice.call(contents, position, position + length);
+              }
+            }
+            allocated = true;
+            ptr = _malloc(length);
+            if (!ptr) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOMEM);
+            }
+            buffer.set(contents, ptr);
+          }
+          return { ptr: ptr, allocated: allocated };
+        }}};
+
+  var IDBFS={dbs:{},indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_VERSION:21,DB_STORE_NAME:"FILE_DATA",mount:function (mount) {
+        // reuse all of the core MEMFS functionality
+        return MEMFS.mount.apply(null, arguments);
+      },syncfs:function (mount, populate, callback) {
+        IDBFS.getLocalSet(mount, function(err, local) {
+          if (err) return callback(err);
+
+          IDBFS.getRemoteSet(mount, function(err, remote) {
+            if (err) return callback(err);
+
+            var src = populate ? remote : local;
+            var dst = populate ? local : remote;
+
+            IDBFS.reconcile(src, dst, callback);
+          });
+        });
+      },getDB:function (name, callback) {
+        // check the cache first
+        var db = IDBFS.dbs[name];
+        if (db) {
+          return callback(null, db);
+        }
+
+        var req;
+        try {
+          req = IDBFS.indexedDB().open(name, IDBFS.DB_VERSION);
+        } catch (e) {
+          return callback(e);
+        }
+        req.onupgradeneeded = function(e) {
+          var db = e.target.result;
+          var transaction = e.target.transaction;
+
+          var fileStore;
+
+          if (db.objectStoreNames.contains(IDBFS.DB_STORE_NAME)) {
+            fileStore = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          } else {
+            fileStore = db.createObjectStore(IDBFS.DB_STORE_NAME);
+          }
+
+          fileStore.createIndex('timestamp', 'timestamp', { unique: false });
+        };
+        req.onsuccess = function() {
+          db = req.result;
+
+          // add to the cache
+          IDBFS.dbs[name] = db;
+          callback(null, db);
+        };
+        req.onerror = function() {
+          callback(this.error);
+        };
+      },getLocalSet:function (mount, callback) {
+        var entries = {};
+
+        function isRealDir(p) {
+          return p !== '.' && p !== '..';
+        };
+        function toAbsolute(root) {
+          return function(p) {
+            return PATH.join2(root, p);
+          }
+        };
+
+        var check = FS.readdir(mount.mountpoint).filter(isRealDir).map(toAbsolute(mount.mountpoint));
+
+        while (check.length) {
+          var path = check.pop();
+          var stat;
+
+          try {
+            stat = FS.stat(path);
+          } catch (e) {
+            return callback(e);
+          }
+
+          if (FS.isDir(stat.mode)) {
+            check.push.apply(check, FS.readdir(path).filter(isRealDir).map(toAbsolute(path)));
+          }
+
+          entries[path] = { timestamp: stat.mtime };
+        }
+
+        return callback(null, { type: 'local', entries: entries });
+      },getRemoteSet:function (mount, callback) {
+        var entries = {};
+
+        IDBFS.getDB(mount.mountpoint, function(err, db) {
+          if (err) return callback(err);
+
+          var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readonly');
+          transaction.onerror = function() { callback(this.error); };
+
+          var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+          var index = store.index('timestamp');
+
+          index.openKeyCursor().onsuccess = function(event) {
+            var cursor = event.target.result;
+
+            if (!cursor) {
+              return callback(null, { type: 'remote', db: db, entries: entries });
+            }
+
+            entries[cursor.primaryKey] = { timestamp: cursor.key };
+
+            cursor.continue();
+          };
+        });
+      },loadLocalEntry:function (path, callback) {
+        var stat, node;
+
+        try {
+          var lookup = FS.lookupPath(path);
+          node = lookup.node;
+          stat = FS.stat(path);
+        } catch (e) {
+          return callback(e);
+        }
+
+        if (FS.isDir(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode });
+        } else if (FS.isFile(stat.mode)) {
+          return callback(null, { timestamp: stat.mtime, mode: stat.mode, contents: node.contents });
+        } else {
+          return callback(new Error('node type not supported'));
+        }
+      },storeLocalEntry:function (path, entry, callback) {
+        try {
+          if (FS.isDir(entry.mode)) {
+            FS.mkdir(path, entry.mode);
+          } else if (FS.isFile(entry.mode)) {
+            FS.writeFile(path, entry.contents, { encoding: 'binary', canOwn: true });
+          } else {
+            return callback(new Error('node type not supported'));
+          }
+
+          FS.utime(path, entry.timestamp, entry.timestamp);
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },removeLocalEntry:function (path, callback) {
+        try {
+          var lookup = FS.lookupPath(path);
+          var stat = FS.stat(path);
+
+          if (FS.isDir(stat.mode)) {
+            FS.rmdir(path);
+          } else if (FS.isFile(stat.mode)) {
+            FS.unlink(path);
+          }
+        } catch (e) {
+          return callback(e);
+        }
+
+        callback(null);
+      },loadRemoteEntry:function (store, path, callback) {
+        var req = store.get(path);
+        req.onsuccess = function(event) { callback(null, event.target.result); };
+        req.onerror = function() { callback(this.error); };
+      },storeRemoteEntry:function (store, path, entry, callback) {
+        var req = store.put(entry, path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },removeRemoteEntry:function (store, path, callback) {
+        var req = store.delete(path);
+        req.onsuccess = function() { callback(null); };
+        req.onerror = function() { callback(this.error); };
+      },reconcile:function (src, dst, callback) {
+        var total = 0;
+
+        var create = [];
+        Object.keys(src.entries).forEach(function (key) {
+          var e = src.entries[key];
+          var e2 = dst.entries[key];
+          if (!e2 || e.timestamp > e2.timestamp) {
+            create.push(key);
+            total++;
+          }
+        });
+
+        var remove = [];
+        Object.keys(dst.entries).forEach(function (key) {
+          var e = dst.entries[key];
+          var e2 = src.entries[key];
+          if (!e2) {
+            remove.push(key);
+            total++;
+          }
+        });
+
+        if (!total) {
+          return callback(null);
+        }
+
+        var errored = false;
+        var completed = 0;
+        var db = src.type === 'remote' ? src.db : dst.db;
+        var transaction = db.transaction([IDBFS.DB_STORE_NAME], 'readwrite');
+        var store = transaction.objectStore(IDBFS.DB_STORE_NAME);
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= total) {
+            return callback(null);
+          }
+        };
+
+        transaction.onerror = function() { done(this.error); };
+
+        // sort paths in ascending order so directory entries are created
+        // before the files inside them
+        create.sort().forEach(function (path) {
+          if (dst.type === 'local') {
+            IDBFS.loadRemoteEntry(store, path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeLocalEntry(path, entry, done);
+            });
+          } else {
+            IDBFS.loadLocalEntry(path, function (err, entry) {
+              if (err) return done(err);
+              IDBFS.storeRemoteEntry(store, path, entry, done);
+            });
+          }
+        });
+
+        // sort paths in descending order so files are deleted before their
+        // parent directories
+        remove.sort().reverse().forEach(function(path) {
+          if (dst.type === 'local') {
+            IDBFS.removeLocalEntry(path, done);
+          } else {
+            IDBFS.removeRemoteEntry(store, path, done);
+          }
+        });
+      }};
+
+  var NODEFS={isWindows:false,staticInit:function () {
+        NODEFS.isWindows = !!process.platform.match(/^win/);
+      },mount:function (mount) {
+        assert(ENVIRONMENT_IS_NODE);
+        return NODEFS.createNode(null, '/', NODEFS.getMode(mount.opts.root), 0);
+      },createNode:function (parent, name, mode, dev) {
+        if (!FS.isDir(mode) && !FS.isFile(mode) && !FS.isLink(mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node = FS.createNode(parent, name, mode);
+        node.node_ops = NODEFS.node_ops;
+        node.stream_ops = NODEFS.stream_ops;
+        return node;
+      },getMode:function (path) {
+        var stat;
+        try {
+          stat = fs.lstatSync(path);
+          if (NODEFS.isWindows) {
+            // On Windows, directories return permission bits 'rw-rw-rw-', even though they have 'rwxrwxrwx', so
+            // propagate write bits to execute bits.
+            stat.mode = stat.mode | ((stat.mode & 146) >> 1);
+          }
+        } catch (e) {
+          if (!e.code) throw e;
+          throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+        }
+        return stat.mode;
+      },realPath:function (node) {
+        var parts = [];
+        while (node.parent !== node) {
+          parts.push(node.name);
+          node = node.parent;
+        }
+        parts.push(node.mount.opts.root);
+        parts.reverse();
+        return PATH.join.apply(null, parts);
+      },flagsToPermissionStringMap:{0:"r",1:"r+",2:"r+",64:"r",65:"r+",66:"r+",129:"rx+",193:"rx+",514:"w+",577:"w",578:"w+",705:"wx",706:"wx+",1024:"a",1025:"a",1026:"a+",1089:"a",1090:"a+",1153:"ax",1154:"ax+",1217:"ax",1218:"ax+",4096:"rs",4098:"rs+"},flagsToPermissionString:function (flags) {
+        if (flags in NODEFS.flagsToPermissionStringMap) {
+          return NODEFS.flagsToPermissionStringMap[flags];
+        } else {
+          return flags;
+        }
+      },node_ops:{getattr:function (node) {
+          var path = NODEFS.realPath(node);
+          var stat;
+          try {
+            stat = fs.lstatSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          // node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake them with default blksize of 4096.
+          // See http://support.microsoft.com/kb/140365
+          if (NODEFS.isWindows && !stat.blksize) {
+            stat.blksize = 4096;
+          }
+          if (NODEFS.isWindows && !stat.blocks) {
+            stat.blocks = (stat.size+stat.blksize-1)/stat.blksize|0;
+          }
+          return {
+            dev: stat.dev,
+            ino: stat.ino,
+            mode: stat.mode,
+            nlink: stat.nlink,
+            uid: stat.uid,
+            gid: stat.gid,
+            rdev: stat.rdev,
+            size: stat.size,
+            atime: stat.atime,
+            mtime: stat.mtime,
+            ctime: stat.ctime,
+            blksize: stat.blksize,
+            blocks: stat.blocks
+          };
+        },setattr:function (node, attr) {
+          var path = NODEFS.realPath(node);
+          try {
+            if (attr.mode !== undefined) {
+              fs.chmodSync(path, attr.mode);
+              // update the common node structure mode as well
+              node.mode = attr.mode;
+            }
+            if (attr.timestamp !== undefined) {
+              var date = new Date(attr.timestamp);
+              fs.utimesSync(path, date, date);
+            }
+            if (attr.size !== undefined) {
+              fs.truncateSync(path, attr.size);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },lookup:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          var mode = NODEFS.getMode(path);
+          return NODEFS.createNode(parent, name, mode);
+        },mknod:function (parent, name, mode, dev) {
+          var node = NODEFS.createNode(parent, name, mode, dev);
+          // create the backing node for this in the fs root as well
+          var path = NODEFS.realPath(node);
+          try {
+            if (FS.isDir(node.mode)) {
+              fs.mkdirSync(path, node.mode);
+            } else {
+              fs.writeFileSync(path, '', { mode: node.mode });
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return node;
+        },rename:function (oldNode, newDir, newName) {
+          var oldPath = NODEFS.realPath(oldNode);
+          var newPath = PATH.join2(NODEFS.realPath(newDir), newName);
+          try {
+            fs.renameSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },unlink:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.unlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },rmdir:function (parent, name) {
+          var path = PATH.join2(NODEFS.realPath(parent), name);
+          try {
+            fs.rmdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readdir:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readdirSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },symlink:function (parent, newName, oldPath) {
+          var newPath = PATH.join2(NODEFS.realPath(parent), newName);
+          try {
+            fs.symlinkSync(oldPath, newPath);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },readlink:function (node) {
+          var path = NODEFS.realPath(node);
+          try {
+            return fs.readlinkSync(path);
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        }},stream_ops:{open:function (stream) {
+          var path = NODEFS.realPath(stream.node);
+          try {
+            if (FS.isFile(stream.node.mode)) {
+              stream.nfd = fs.openSync(path, NODEFS.flagsToPermissionString(stream.flags));
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },close:function (stream) {
+          try {
+            if (FS.isFile(stream.node.mode) && stream.nfd) {
+              fs.closeSync(stream.nfd);
+            }
+          } catch (e) {
+            if (!e.code) throw e;
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+        },read:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(length);
+          var res;
+          try {
+            res = fs.readSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          if (res > 0) {
+            for (var i = 0; i < res; i++) {
+              buffer[offset + i] = nbuffer[i];
+            }
+          }
+          return res;
+        },write:function (stream, buffer, offset, length, position) {
+          // FIXME this is terrible.
+          var nbuffer = new Buffer(buffer.subarray(offset, offset + length));
+          var res;
+          try {
+            res = fs.writeSync(stream.nfd, nbuffer, 0, length, position);
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+          }
+          return res;
+        },llseek:function (stream, offset, whence) {
+          var position = offset;
+          if (whence === 1) {  // SEEK_CUR.
+            position += stream.position;
+          } else if (whence === 2) {  // SEEK_END.
+            if (FS.isFile(stream.node.mode)) {
+              try {
+                var stat = fs.fstatSync(stream.nfd);
+                position += stat.size;
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES[e.code]);
+              }
+            }
+          }
+
+          if (position < 0) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+
+          stream.position = position;
+          return position;
+        }}};
+
+  var _stdin=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stdout=allocate(1, "i32*", ALLOC_STATIC);
+
+  var _stderr=allocate(1, "i32*", ALLOC_STATIC);
+
+  function _fflush(stream) {
+      // int fflush(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fflush.html
+      // we don't currently perform any user-space buffering of data
+    }var FS={root:null,mounts:[],devices:[null],streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,ErrnoError:null,genericErrors:{},handleFSError:function (e) {
+        if (!(e instanceof FS.ErrnoError)) throw e + ' : ' + stackTrace();
+        return ___setErrNo(e.errno);
+      },lookupPath:function (path, opts) {
+        path = PATH.resolve(FS.cwd(), path);
+        opts = opts || {};
+
+        var defaults = {
+          follow_mount: true,
+          recurse_count: 0
+        };
+        for (var key in defaults) {
+          if (opts[key] === undefined) {
+            opts[key] = defaults[key];
+          }
+        }
+
+        if (opts.recurse_count > 8) {  // max recursive lookup of 8
+          throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+        }
+
+        // split the path
+        var parts = PATH.normalizeArray(path.split('/').filter(function(p) {
+          return !!p;
+        }), false);
+
+        // start at the root
+        var current = FS.root;
+        var current_path = '/';
+
+        for (var i = 0; i < parts.length; i++) {
+          var islast = (i === parts.length-1);
+          if (islast && opts.parent) {
+            // stop resolving
+            break;
+          }
+
+          current = FS.lookupNode(current, parts[i]);
+          current_path = PATH.join2(current_path, parts[i]);
+
+          // jump to the mount's root node if this is a mountpoint
+          if (FS.isMountpoint(current)) {
+            if (!islast || (islast && opts.follow_mount)) {
+              current = current.mounted.root;
+            }
+          }
+
+          // by default, lookupPath will not follow a symlink if it is the final path component.
+          // setting opts.follow = true will override this behavior.
+          if (!islast || opts.follow) {
+            var count = 0;
+            while (FS.isLink(current.mode)) {
+              var link = FS.readlink(current_path);
+              current_path = PATH.resolve(PATH.dirname(current_path), link);
+
+              var lookup = FS.lookupPath(current_path, { recurse_count: opts.recurse_count });
+              current = lookup.node;
+
+              if (count++ > 40) {  // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
+                throw new FS.ErrnoError(ERRNO_CODES.ELOOP);
+              }
+            }
+          }
+        }
+
+        return { path: current_path, node: current };
+      },getPath:function (node) {
+        var path;
+        while (true) {
+          if (FS.isRoot(node)) {
+            var mount = node.mount.mountpoint;
+            if (!path) return mount;
+            return mount[mount.length-1] !== '/' ? mount + '/' + path : mount + path;
+          }
+          path = path ? node.name + '/' + path : node.name;
+          node = node.parent;
+        }
+      },hashName:function (parentid, name) {
+        var hash = 0;
+
+
+        for (var i = 0; i < name.length; i++) {
+          hash = ((hash << 5) - hash + name.charCodeAt(i)) | 0;
+        }
+        return ((parentid + hash) >>> 0) % FS.nameTable.length;
+      },hashAddNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        node.name_next = FS.nameTable[hash];
+        FS.nameTable[hash] = node;
+      },hashRemoveNode:function (node) {
+        var hash = FS.hashName(node.parent.id, node.name);
+        if (FS.nameTable[hash] === node) {
+          FS.nameTable[hash] = node.name_next;
+        } else {
+          var current = FS.nameTable[hash];
+          while (current) {
+            if (current.name_next === node) {
+              current.name_next = node.name_next;
+              break;
+            }
+            current = current.name_next;
+          }
+        }
+      },lookupNode:function (parent, name) {
+        var err = FS.mayLookup(parent);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        var hash = FS.hashName(parent.id, name);
+        for (var node = FS.nameTable[hash]; node; node = node.name_next) {
+          var nodeName = node.name;
+          if (node.parent.id === parent.id && nodeName === name) {
+            return node;
+          }
+        }
+        // if we failed to find it in the cache, call into the VFS
+        return FS.lookup(parent, name);
+      },createNode:function (parent, name, mode, rdev) {
+        if (!FS.FSNode) {
+          FS.FSNode = function(parent, name, mode, rdev) {
+            if (!parent) {
+              parent = this;  // root node sets parent to itself
+            }
+            this.parent = parent;
+            this.mount = parent.mount;
+            this.mounted = null;
+            this.id = FS.nextInode++;
+            this.name = name;
+            this.mode = mode;
+            this.node_ops = {};
+            this.stream_ops = {};
+            this.rdev = rdev;
+          };
+
+          FS.FSNode.prototype = {};
+
+          // compatibility
+          var readMode = 292 | 73;
+          var writeMode = 146;
+
+          // NOTE we must use Object.defineProperties instead of individual calls to
+          // Object.defineProperty in order to make closure compiler happy
+          Object.defineProperties(FS.FSNode.prototype, {
+            read: {
+              get: function() { return (this.mode & readMode) === readMode; },
+              set: function(val) { val ? this.mode |= readMode : this.mode &= ~readMode; }
+            },
+            write: {
+              get: function() { return (this.mode & writeMode) === writeMode; },
+              set: function(val) { val ? this.mode |= writeMode : this.mode &= ~writeMode; }
+            },
+            isFolder: {
+              get: function() { return FS.isDir(this.mode); },
+            },
+            isDevice: {
+              get: function() { return FS.isChrdev(this.mode); },
+            },
+          });
+        }
+
+        var node = new FS.FSNode(parent, name, mode, rdev);
+
+        FS.hashAddNode(node);
+
+        return node;
+      },destroyNode:function (node) {
+        FS.hashRemoveNode(node);
+      },isRoot:function (node) {
+        return node === node.parent;
+      },isMountpoint:function (node) {
+        return !!node.mounted;
+      },isFile:function (mode) {
+        return (mode & 61440) === 32768;
+      },isDir:function (mode) {
+        return (mode & 61440) === 16384;
+      },isLink:function (mode) {
+        return (mode & 61440) === 40960;
+      },isChrdev:function (mode) {
+        return (mode & 61440) === 8192;
+      },isBlkdev:function (mode) {
+        return (mode & 61440) === 24576;
+      },isFIFO:function (mode) {
+        return (mode & 61440) === 4096;
+      },isSocket:function (mode) {
+        return (mode & 49152) === 49152;
+      },flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function (str) {
+        var flags = FS.flagModes[str];
+        if (typeof flags === 'undefined') {
+          throw new Error('Unknown file open mode: ' + str);
+        }
+        return flags;
+      },flagsToPermissionString:function (flag) {
+        var accmode = flag & 2097155;
+        var perms = ['r', 'w', 'rw'][accmode];
+        if ((flag & 512)) {
+          perms += 'w';
+        }
+        return perms;
+      },nodePermissions:function (node, perms) {
+        if (FS.ignorePermissions) {
+          return 0;
+        }
+        // return 0 if any user, group or owner bits are set.
+        if (perms.indexOf('r') !== -1 && !(node.mode & 292)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('w') !== -1 && !(node.mode & 146)) {
+          return ERRNO_CODES.EACCES;
+        } else if (perms.indexOf('x') !== -1 && !(node.mode & 73)) {
+          return ERRNO_CODES.EACCES;
+        }
+        return 0;
+      },mayLookup:function (dir) {
+        return FS.nodePermissions(dir, 'x');
+      },mayCreate:function (dir, name) {
+        try {
+          var node = FS.lookupNode(dir, name);
+          return ERRNO_CODES.EEXIST;
+        } catch (e) {
+        }
+        return FS.nodePermissions(dir, 'wx');
+      },mayDelete:function (dir, name, isdir) {
+        var node;
+        try {
+          node = FS.lookupNode(dir, name);
+        } catch (e) {
+          return e.errno;
+        }
+        var err = FS.nodePermissions(dir, 'wx');
+        if (err) {
+          return err;
+        }
+        if (isdir) {
+          if (!FS.isDir(node.mode)) {
+            return ERRNO_CODES.ENOTDIR;
+          }
+          if (FS.isRoot(node) || FS.getPath(node) === FS.cwd()) {
+            return ERRNO_CODES.EBUSY;
+          }
+        } else {
+          if (FS.isDir(node.mode)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return 0;
+      },mayOpen:function (node, flags) {
+        if (!node) {
+          return ERRNO_CODES.ENOENT;
+        }
+        if (FS.isLink(node.mode)) {
+          return ERRNO_CODES.ELOOP;
+        } else if (FS.isDir(node.mode)) {
+          if ((flags & 2097155) !== 0 ||  // opening for write
+              (flags & 512)) {
+            return ERRNO_CODES.EISDIR;
+          }
+        }
+        return FS.nodePermissions(node, FS.flagsToPermissionString(flags));
+      },MAX_OPEN_FDS:4096,nextfd:function (fd_start, fd_end) {
+        fd_start = fd_start || 0;
+        fd_end = fd_end || FS.MAX_OPEN_FDS;
+        for (var fd = fd_start; fd <= fd_end; fd++) {
+          if (!FS.streams[fd]) {
+            return fd;
+          }
+        }
+        throw new FS.ErrnoError(ERRNO_CODES.EMFILE);
+      },getStream:function (fd) {
+        return FS.streams[fd];
+      },createStream:function (stream, fd_start, fd_end) {
+        if (!FS.FSStream) {
+          FS.FSStream = function(){};
+          FS.FSStream.prototype = {};
+          // compatibility
+          Object.defineProperties(FS.FSStream.prototype, {
+            object: {
+              get: function() { return this.node; },
+              set: function(val) { this.node = val; }
+            },
+            isRead: {
+              get: function() { return (this.flags & 2097155) !== 1; }
+            },
+            isWrite: {
+              get: function() { return (this.flags & 2097155) !== 0; }
+            },
+            isAppend: {
+              get: function() { return (this.flags & 1024); }
+            }
+          });
+        }
+        if (0) {
+          // reuse the object
+          stream.__proto__ = FS.FSStream.prototype;
+        } else {
+          var newStream = new FS.FSStream();
+          for (var p in stream) {
+            newStream[p] = stream[p];
+          }
+          stream = newStream;
+        }
+        var fd = FS.nextfd(fd_start, fd_end);
+        stream.fd = fd;
+        FS.streams[fd] = stream;
+        return stream;
+      },closeStream:function (fd) {
+        FS.streams[fd] = null;
+      },getStreamFromPtr:function (ptr) {
+        return FS.streams[ptr - 1];
+      },getPtrForStream:function (stream) {
+        return stream ? stream.fd + 1 : 0;
+      },chrdev_stream_ops:{open:function (stream) {
+          var device = FS.getDevice(stream.node.rdev);
+          // override node's stream ops with the device's
+          stream.stream_ops = device.stream_ops;
+          // forward the open call
+          if (stream.stream_ops.open) {
+            stream.stream_ops.open(stream);
+          }
+        },llseek:function () {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }},major:function (dev) {
+        return ((dev) >> 8);
+      },minor:function (dev) {
+        return ((dev) & 0xff);
+      },makedev:function (ma, mi) {
+        return ((ma) << 8 | (mi));
+      },registerDevice:function (dev, ops) {
+        FS.devices[dev] = { stream_ops: ops };
+      },getDevice:function (dev) {
+        return FS.devices[dev];
+      },getMounts:function (mount) {
+        var mounts = [];
+        var check = [mount];
+
+        while (check.length) {
+          var m = check.pop();
+
+          mounts.push(m);
+
+          check.push.apply(check, m.mounts);
+        }
+
+        return mounts;
+      },syncfs:function (populate, callback) {
+        if (typeof(populate) === 'function') {
+          callback = populate;
+          populate = false;
+        }
+
+        var mounts = FS.getMounts(FS.root.mount);
+        var completed = 0;
+
+        function done(err) {
+          if (err) {
+            if (!done.errored) {
+              done.errored = true;
+              return callback(err);
+            }
+            return;
+          }
+          if (++completed >= mounts.length) {
+            callback(null);
+          }
+        };
+
+        // sync all mounts
+        mounts.forEach(function (mount) {
+          if (!mount.type.syncfs) {
+            return done(null);
+          }
+          mount.type.syncfs(mount, populate, done);
+        });
+      },mount:function (type, opts, mountpoint) {
+        var root = mountpoint === '/';
+        var pseudo = !mountpoint;
+        var node;
+
+        if (root && FS.root) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        } else if (!root && !pseudo) {
+          var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+          mountpoint = lookup.path;  // use the absolute path
+          node = lookup.node;
+
+          if (FS.isMountpoint(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+          }
+
+          if (!FS.isDir(node.mode)) {
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+          }
+        }
+
+        var mount = {
+          type: type,
+          opts: opts,
+          mountpoint: mountpoint,
+          mounts: []
+        };
+
+        // create a root node for the fs
+        var mountRoot = type.mount(mount);
+        mountRoot.mount = mount;
+        mount.root = mountRoot;
+
+        if (root) {
+          FS.root = mountRoot;
+        } else if (node) {
+          // set as a mountpoint
+          node.mounted = mount;
+
+          // add the new mount to the current mount's children
+          if (node.mount) {
+            node.mount.mounts.push(mount);
+          }
+        }
+
+        return mountRoot;
+      },unmount:function (mountpoint) {
+        var lookup = FS.lookupPath(mountpoint, { follow_mount: false });
+
+        if (!FS.isMountpoint(lookup.node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+
+        // destroy the nodes for this mount, and all its child mounts
+        var node = lookup.node;
+        var mount = node.mounted;
+        var mounts = FS.getMounts(mount);
+
+        Object.keys(FS.nameTable).forEach(function (hash) {
+          var current = FS.nameTable[hash];
+
+          while (current) {
+            var next = current.name_next;
+
+            if (mounts.indexOf(current.mount) !== -1) {
+              FS.destroyNode(current);
+            }
+
+            current = next;
+          }
+        });
+
+        // no longer a mountpoint
+        node.mounted = null;
+
+        // remove this mount from the child mounts
+        var idx = node.mount.mounts.indexOf(mount);
+        assert(idx !== -1);
+        node.mount.mounts.splice(idx, 1);
+      },lookup:function (parent, name) {
+        return parent.node_ops.lookup(parent, name);
+      },mknod:function (path, mode, dev) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var err = FS.mayCreate(parent, name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.mknod) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.mknod(parent, name, mode, dev);
+      },create:function (path, mode) {
+        mode = mode !== undefined ? mode : 438 /* 0666 */;
+        mode &= 4095;
+        mode |= 32768;
+        return FS.mknod(path, mode, 0);
+      },mkdir:function (path, mode) {
+        mode = mode !== undefined ? mode : 511 /* 0777 */;
+        mode &= 511 | 512;
+        mode |= 16384;
+        return FS.mknod(path, mode, 0);
+      },mkdev:function (path, mode, dev) {
+        if (typeof(dev) === 'undefined') {
+          dev = mode;
+          mode = 438 /* 0666 */;
+        }
+        mode |= 8192;
+        return FS.mknod(path, mode, dev);
+      },symlink:function (oldpath, newpath) {
+        var lookup = FS.lookupPath(newpath, { parent: true });
+        var parent = lookup.node;
+        var newname = PATH.basename(newpath);
+        var err = FS.mayCreate(parent, newname);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.symlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return parent.node_ops.symlink(parent, newname, oldpath);
+      },rename:function (old_path, new_path) {
+        var old_dirname = PATH.dirname(old_path);
+        var new_dirname = PATH.dirname(new_path);
+        var old_name = PATH.basename(old_path);
+        var new_name = PATH.basename(new_path);
+        // parents must exist
+        var lookup, old_dir, new_dir;
+        try {
+          lookup = FS.lookupPath(old_path, { parent: true });
+          old_dir = lookup.node;
+          lookup = FS.lookupPath(new_path, { parent: true });
+          new_dir = lookup.node;
+        } catch (e) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // need to be part of the same mount
+        if (old_dir.mount !== new_dir.mount) {
+          throw new FS.ErrnoError(ERRNO_CODES.EXDEV);
+        }
+        // source must exist
+        var old_node = FS.lookupNode(old_dir, old_name);
+        // old path should not be an ancestor of the new path
+        var relative = PATH.relative(old_path, new_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        // new path should not be an ancestor of the old path
+        relative = PATH.relative(new_path, old_dirname);
+        if (relative.charAt(0) !== '.') {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTEMPTY);
+        }
+        // see if the new path already exists
+        var new_node;
+        try {
+          new_node = FS.lookupNode(new_dir, new_name);
+        } catch (e) {
+          // not fatal
+        }
+        // early out if nothing needs to change
+        if (old_node === new_node) {
+          return;
+        }
+        // we'll need to delete the old entry
+        var isdir = FS.isDir(old_node.mode);
+        var err = FS.mayDelete(old_dir, old_name, isdir);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // need delete permissions if we'll be overwriting.
+        // need create permissions if new doesn't already exist.
+        err = new_node ?
+          FS.mayDelete(new_dir, new_name, isdir) :
+          FS.mayCreate(new_dir, new_name);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!old_dir.node_ops.rename) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(old_node) || (new_node && FS.isMountpoint(new_node))) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        // if we are going to change the parent, check write permissions
+        if (new_dir !== old_dir) {
+          err = FS.nodePermissions(old_dir, 'w');
+          if (err) {
+            throw new FS.ErrnoError(err);
+          }
+        }
+        // remove the node from the lookup hash
+        FS.hashRemoveNode(old_node);
+        // do the underlying fs rename
+        try {
+          old_dir.node_ops.rename(old_node, new_dir, new_name);
+        } catch (e) {
+          throw e;
+        } finally {
+          // add the node back to the hash (in case node_ops.rename
+          // changed its name)
+          FS.hashAddNode(old_node);
+        }
+      },rmdir:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, true);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.rmdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.rmdir(parent, name);
+        FS.destroyNode(node);
+      },readdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        if (!node.node_ops.readdir) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        return node.node_ops.readdir(node);
+      },unlink:function (path) {
+        var lookup = FS.lookupPath(path, { parent: true });
+        var parent = lookup.node;
+        var name = PATH.basename(path);
+        var node = FS.lookupNode(parent, name);
+        var err = FS.mayDelete(parent, name, false);
+        if (err) {
+          // POSIX says unlink should set EPERM, not EISDIR
+          if (err === ERRNO_CODES.EISDIR) err = ERRNO_CODES.EPERM;
+          throw new FS.ErrnoError(err);
+        }
+        if (!parent.node_ops.unlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isMountpoint(node)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBUSY);
+        }
+        parent.node_ops.unlink(parent, name);
+        FS.destroyNode(node);
+      },readlink:function (path) {
+        var lookup = FS.lookupPath(path);
+        var link = lookup.node;
+        if (!link.node_ops.readlink) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        return link.node_ops.readlink(link);
+      },stat:function (path, dontFollow) {
+        var lookup = FS.lookupPath(path, { follow: !dontFollow });
+        var node = lookup.node;
+        if (!node.node_ops.getattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        return node.node_ops.getattr(node);
+      },lstat:function (path) {
+        return FS.stat(path, true);
+      },chmod:function (path, mode, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          mode: (mode & 4095) | (node.mode & ~4095),
+          timestamp: Date.now()
+        });
+      },lchmod:function (path, mode) {
+        FS.chmod(path, mode, true);
+      },fchmod:function (fd, mode) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chmod(stream.node, mode);
+      },chown:function (path, uid, gid, dontFollow) {
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: !dontFollow });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        node.node_ops.setattr(node, {
+          timestamp: Date.now()
+          // we ignore the uid / gid for now
+        });
+      },lchown:function (path, uid, gid) {
+        FS.chown(path, uid, gid, true);
+      },fchown:function (fd, uid, gid) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        FS.chown(stream.node, uid, gid);
+      },truncate:function (path, len) {
+        if (len < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var node;
+        if (typeof path === 'string') {
+          var lookup = FS.lookupPath(path, { follow: true });
+          node = lookup.node;
+        } else {
+          node = path;
+        }
+        if (!node.node_ops.setattr) {
+          throw new FS.ErrnoError(ERRNO_CODES.EPERM);
+        }
+        if (FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!FS.isFile(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var err = FS.nodePermissions(node, 'w');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        node.node_ops.setattr(node, {
+          size: len,
+          timestamp: Date.now()
+        });
+      },ftruncate:function (fd, len) {
+        var stream = FS.getStream(fd);
+        if (!stream) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        FS.truncate(stream.node, len);
+      },utime:function (path, atime, mtime) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        var node = lookup.node;
+        node.node_ops.setattr(node, {
+          timestamp: Math.max(atime, mtime)
+        });
+      },open:function (path, flags, mode, fd_start, fd_end) {
+        flags = typeof flags === 'string' ? FS.modeStringToFlags(flags) : flags;
+        mode = typeof mode === 'undefined' ? 438 /* 0666 */ : mode;
+        if ((flags & 64)) {
+          mode = (mode & 4095) | 32768;
+        } else {
+          mode = 0;
+        }
+        var node;
+        if (typeof path === 'object') {
+          node = path;
+        } else {
+          path = PATH.normalize(path);
+          try {
+            var lookup = FS.lookupPath(path, {
+              follow: !(flags & 131072)
+            });
+            node = lookup.node;
+          } catch (e) {
+            // ignore
+          }
+        }
+        // perhaps we need to create the node
+        if ((flags & 64)) {
+          if (node) {
+            // if O_CREAT and O_EXCL are set, error out if the node already exists
+            if ((flags & 128)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EEXIST);
+            }
+          } else {
+            // node doesn't exist, try to create it
+            node = FS.mknod(path, mode, 0);
+          }
+        }
+        if (!node) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOENT);
+        }
+        // can't truncate a device
+        if (FS.isChrdev(node.mode)) {
+          flags &= ~512;
+        }
+        // check permissions
+        var err = FS.mayOpen(node, flags);
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        // do truncation if necessary
+        if ((flags & 512)) {
+          FS.truncate(node, 0);
+        }
+        // we've already handled these, don't pass down to the underlying vfs
+        flags &= ~(128 | 512);
+
+        // register the stream with the filesystem
+        var stream = FS.createStream({
+          node: node,
+          path: FS.getPath(node),  // we want the absolute path to the node
+          flags: flags,
+          seekable: true,
+          position: 0,
+          stream_ops: node.stream_ops,
+          // used by the file family libc calls (fopen, fwrite, ferror, etc.)
+          ungotten: [],
+          error: false
+        }, fd_start, fd_end);
+        // call the new stream's open function
+        if (stream.stream_ops.open) {
+          stream.stream_ops.open(stream);
+        }
+        if (Module['logReadFiles'] && !(flags & 1)) {
+          if (!FS.readFiles) FS.readFiles = {};
+          if (!(path in FS.readFiles)) {
+            FS.readFiles[path] = 1;
+            Module['printErr']('read file: ' + path);
+          }
+        }
+        return stream;
+      },close:function (stream) {
+        try {
+          if (stream.stream_ops.close) {
+            stream.stream_ops.close(stream);
+          }
+        } catch (e) {
+          throw e;
+        } finally {
+          FS.closeStream(stream.fd);
+        }
+      },llseek:function (stream, offset, whence) {
+        if (!stream.seekable || !stream.stream_ops.llseek) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        return stream.stream_ops.llseek(stream, offset, whence);
+      },read:function (stream, buffer, offset, length, position) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.read) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        var bytesRead = stream.stream_ops.read(stream, buffer, offset, length, position);
+        if (!seeking) stream.position += bytesRead;
+        return bytesRead;
+      },write:function (stream, buffer, offset, length, position, canOwn) {
+        if (length < 0 || position < 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (FS.isDir(stream.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.EISDIR);
+        }
+        if (!stream.stream_ops.write) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        var seeking = true;
+        if (typeof position === 'undefined') {
+          position = stream.position;
+          seeking = false;
+        } else if (!stream.seekable) {
+          throw new FS.ErrnoError(ERRNO_CODES.ESPIPE);
+        }
+        if (stream.flags & 1024) {
+          // seek to the end before writing in append mode
+          FS.llseek(stream, 0, 2);
+        }
+        var bytesWritten = stream.stream_ops.write(stream, buffer, offset, length, position, canOwn);
+        if (!seeking) stream.position += bytesWritten;
+        return bytesWritten;
+      },allocate:function (stream, offset, length) {
+        if (offset < 0 || length <= 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+        }
+        if ((stream.flags & 2097155) === 0) {
+          throw new FS.ErrnoError(ERRNO_CODES.EBADF);
+        }
+        if (!FS.isFile(stream.node.mode) && !FS.isDir(node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        if (!stream.stream_ops.allocate) {
+          throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+        }
+        stream.stream_ops.allocate(stream, offset, length);
+      },mmap:function (stream, buffer, offset, length, position, prot, flags) {
+        // TODO if PROT is PROT_WRITE, make sure we have write access
+        if ((stream.flags & 2097155) === 1) {
+          throw new FS.ErrnoError(ERRNO_CODES.EACCES);
+        }
+        if (!stream.stream_ops.mmap) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
+        }
+        return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
+      },ioctl:function (stream, cmd, arg) {
+        if (!stream.stream_ops.ioctl) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTTY);
+        }
+        return stream.stream_ops.ioctl(stream, cmd, arg);
+      },readFile:function (path, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'r';
+        opts.encoding = opts.encoding || 'binary';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var ret;
+        var stream = FS.open(path, opts.flags);
+        var stat = FS.stat(path);
+        var length = stat.size;
+        var buf = new Uint8Array(length);
+        FS.read(stream, buf, 0, length, 0);
+        if (opts.encoding === 'utf8') {
+          ret = '';
+          var utf8 = new Runtime.UTF8Processor();
+          for (var i = 0; i < length; i++) {
+            ret += utf8.processCChar(buf[i]);
+          }
+        } else if (opts.encoding === 'binary') {
+          ret = buf;
+        }
+        FS.close(stream);
+        return ret;
+      },writeFile:function (path, data, opts) {
+        opts = opts || {};
+        opts.flags = opts.flags || 'w';
+        opts.encoding = opts.encoding || 'utf8';
+        if (opts.encoding !== 'utf8' && opts.encoding !== 'binary') {
+          throw new Error('Invalid encoding type "' + opts.encoding + '"');
+        }
+        var stream = FS.open(path, opts.flags, opts.mode);
+        if (opts.encoding === 'utf8') {
+          var utf8 = new Runtime.UTF8Processor();
+          var buf = new Uint8Array(utf8.processJSString(data));
+          FS.write(stream, buf, 0, buf.length, 0, opts.canOwn);
+        } else if (opts.encoding === 'binary') {
+          FS.write(stream, data, 0, data.length, 0, opts.canOwn);
+        }
+        FS.close(stream);
+      },cwd:function () {
+        return FS.currentPath;
+      },chdir:function (path) {
+        var lookup = FS.lookupPath(path, { follow: true });
+        if (!FS.isDir(lookup.node.mode)) {
+          throw new FS.ErrnoError(ERRNO_CODES.ENOTDIR);
+        }
+        var err = FS.nodePermissions(lookup.node, 'x');
+        if (err) {
+          throw new FS.ErrnoError(err);
+        }
+        FS.currentPath = lookup.path;
+      },createDefaultDirectories:function () {
+        FS.mkdir('/tmp');
+      },createDefaultDevices:function () {
+        // create /dev
+        FS.mkdir('/dev');
+        // setup /dev/null
+        FS.registerDevice(FS.makedev(1, 3), {
+          read: function() { return 0; },
+          write: function() { return 0; }
+        });
+        FS.mkdev('/dev/null', FS.makedev(1, 3));
+        // setup /dev/tty and /dev/tty1
+        // stderr needs to print output using Module['printErr']
+        // so we register a second tty just for it.
+        TTY.register(FS.makedev(5, 0), TTY.default_tty_ops);
+        TTY.register(FS.makedev(6, 0), TTY.default_tty1_ops);
+        FS.mkdev('/dev/tty', FS.makedev(5, 0));
+        FS.mkdev('/dev/tty1', FS.makedev(6, 0));
+        // we're not going to emulate the actual shm device,
+        // just create the tmp dirs that reside in it commonly
+        FS.mkdir('/dev/shm');
+        FS.mkdir('/dev/shm/tmp');
+      },createStandardStreams:function () {
+        // TODO deprecate the old functionality of a single
+        // input / output callback and that utilizes FS.createDevice
+        // and instead require a unique set of stream ops
+
+        // by default, we symlink the standard streams to the
+        // default tty devices. however, if the standard streams
+        // have been overwritten we create a unique device for
+        // them instead.
+        if (Module['stdin']) {
+          FS.createDevice('/dev', 'stdin', Module['stdin']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdin');
+        }
+        if (Module['stdout']) {
+          FS.createDevice('/dev', 'stdout', null, Module['stdout']);
+        } else {
+          FS.symlink('/dev/tty', '/dev/stdout');
+        }
+        if (Module['stderr']) {
+          FS.createDevice('/dev', 'stderr', null, Module['stderr']);
+        } else {
+          FS.symlink('/dev/tty1', '/dev/stderr');
+        }
+
+        // open default streams for the stdin, stdout and stderr devices
+        var stdin = FS.open('/dev/stdin', 'r');
+        HEAP32[((_stdin)>>2)]=FS.getPtrForStream(stdin);
+        assert(stdin.fd === 0, 'invalid handle for stdin (' + stdin.fd + ')');
+
+        var stdout = FS.open('/dev/stdout', 'w');
+        HEAP32[((_stdout)>>2)]=FS.getPtrForStream(stdout);
+        assert(stdout.fd === 1, 'invalid handle for stdout (' + stdout.fd + ')');
+
+        var stderr = FS.open('/dev/stderr', 'w');
+        HEAP32[((_stderr)>>2)]=FS.getPtrForStream(stderr);
+        assert(stderr.fd === 2, 'invalid handle for stderr (' + stderr.fd + ')');
+      },ensureErrnoError:function () {
+        if (FS.ErrnoError) return;
+        FS.ErrnoError = function ErrnoError(errno) {
+          this.errno = errno;
+          for (var key in ERRNO_CODES) {
+            if (ERRNO_CODES[key] === errno) {
+              this.code = key;
+              break;
+            }
+          }
+          this.message = ERRNO_MESSAGES[errno];
+        };
+        FS.ErrnoError.prototype = new Error();
+        FS.ErrnoError.prototype.constructor = FS.ErrnoError;
+        // Some errors may happen quite a bit, to avoid overhead we reuse them (and suffer a lack of stack info)
+        [ERRNO_CODES.ENOENT].forEach(function(code) {
+          FS.genericErrors[code] = new FS.ErrnoError(code);
+          FS.genericErrors[code].stack = '<generic error, no stack>';
+        });
+      },staticInit:function () {
+        FS.ensureErrnoError();
+
+        FS.nameTable = new Array(4096);
+
+        FS.mount(MEMFS, {}, '/');
+
+        FS.createDefaultDirectories();
+        FS.createDefaultDevices();
+      },init:function (input, output, error) {
+        assert(!FS.init.initialized, 'FS.init was previously called. If you want to initialize later with custom parameters, remove any earlier calls (note that one is automatically added to the generated code)');
+        FS.init.initialized = true;
+
+        FS.ensureErrnoError();
+
+        // Allow Module.stdin etc. to provide defaults, if none explicitly passed to us here
+        Module['stdin'] = input || Module['stdin'];
+        Module['stdout'] = output || Module['stdout'];
+        Module['stderr'] = error || Module['stderr'];
+
+        FS.createStandardStreams();
+      },quit:function () {
+        FS.init.initialized = false;
+        for (var i = 0; i < FS.streams.length; i++) {
+          var stream = FS.streams[i];
+          if (!stream) {
+            continue;
+          }
+          FS.close(stream);
+        }
+      },getMode:function (canRead, canWrite) {
+        var mode = 0;
+        if (canRead) mode |= 292 | 73;
+        if (canWrite) mode |= 146;
+        return mode;
+      },joinPath:function (parts, forceRelative) {
+        var path = PATH.join.apply(null, parts);
+        if (forceRelative && path[0] == '/') path = path.substr(1);
+        return path;
+      },absolutePath:function (relative, base) {
+        return PATH.resolve(base, relative);
+      },standardizePath:function (path) {
+        return PATH.normalize(path);
+      },findObject:function (path, dontResolveLastLink) {
+        var ret = FS.analyzePath(path, dontResolveLastLink);
+        if (ret.exists) {
+          return ret.object;
+        } else {
+          ___setErrNo(ret.error);
+          return null;
+        }
+      },analyzePath:function (path, dontResolveLastLink) {
+        // operate from within the context of the symlink's target
+        try {
+          var lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          path = lookup.path;
+        } catch (e) {
+        }
+        var ret = {
+          isRoot: false, exists: false, error: 0, name: null, path: null, object: null,
+          parentExists: false, parentPath: null, parentObject: null
+        };
+        try {
+          var lookup = FS.lookupPath(path, { parent: true });
+          ret.parentExists = true;
+          ret.parentPath = lookup.path;
+          ret.parentObject = lookup.node;
+          ret.name = PATH.basename(path);
+          lookup = FS.lookupPath(path, { follow: !dontResolveLastLink });
+          ret.exists = true;
+          ret.path = lookup.path;
+          ret.object = lookup.node;
+          ret.name = lookup.node.name;
+          ret.isRoot = lookup.path === '/';
+        } catch (e) {
+          ret.error = e.errno;
+        };
+        return ret;
+      },createFolder:function (parent, name, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.mkdir(path, mode);
+      },createPath:function (parent, path, canRead, canWrite) {
+        parent = typeof parent === 'string' ? parent : FS.getPath(parent);
+        var parts = path.split('/').reverse();
+        while (parts.length) {
+          var part = parts.pop();
+          if (!part) continue;
+          var current = PATH.join2(parent, part);
+          try {
+            FS.mkdir(current);
+          } catch (e) {
+            // ignore EEXIST
+          }
+          parent = current;
+        }
+        return current;
+      },createFile:function (parent, name, properties, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(canRead, canWrite);
+        return FS.create(path, mode);
+      },createDataFile:function (parent, name, data, canRead, canWrite, canOwn) {
+        var path = name ? PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name) : parent;
+        var mode = FS.getMode(canRead, canWrite);
+        var node = FS.create(path, mode);
+        if (data) {
+          if (typeof data === 'string') {
+            var arr = new Array(data.length);
+            for (var i = 0, len = data.length; i < len; ++i) arr[i] = data.charCodeAt(i);
+            data = arr;
+          }
+          // make sure we can write to the file
+          FS.chmod(node, mode | 146);
+          var stream = FS.open(node, 'w');
+          FS.write(stream, data, 0, data.length, 0, canOwn);
+          FS.close(stream);
+          FS.chmod(node, mode);
+        }
+        return node;
+      },createDevice:function (parent, name, input, output) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        var mode = FS.getMode(!!input, !!output);
+        if (!FS.createDevice.major) FS.createDevice.major = 64;
+        var dev = FS.makedev(FS.createDevice.major++, 0);
+        // Create a fake device that a set of stream ops to emulate
+        // the old behavior.
+        FS.registerDevice(dev, {
+          open: function(stream) {
+            stream.seekable = false;
+          },
+          close: function(stream) {
+            // flush any pending line data
+            if (output && output.buffer && output.buffer.length) {
+              output(10);
+            }
+          },
+          read: function(stream, buffer, offset, length, pos /* ignored */) {
+            var bytesRead = 0;
+            for (var i = 0; i < length; i++) {
+              var result;
+              try {
+                result = input();
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+              if (result === undefined && bytesRead === 0) {
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+              if (result === null || result === undefined) break;
+              bytesRead++;
+              buffer[offset+i] = result;
+            }
+            if (bytesRead) {
+              stream.node.timestamp = Date.now();
+            }
+            return bytesRead;
+          },
+          write: function(stream, buffer, offset, length, pos) {
+            for (var i = 0; i < length; i++) {
+              try {
+                output(buffer[offset+i]);
+              } catch (e) {
+                throw new FS.ErrnoError(ERRNO_CODES.EIO);
+              }
+            }
+            if (length) {
+              stream.node.timestamp = Date.now();
+            }
+            return i;
+          }
+        });
+        return FS.mkdev(path, mode, dev);
+      },createLink:function (parent, name, target, canRead, canWrite) {
+        var path = PATH.join2(typeof parent === 'string' ? parent : FS.getPath(parent), name);
+        return FS.symlink(target, path);
+      },forceLoadFile:function (obj) {
+        if (obj.isDevice || obj.isFolder || obj.link || obj.contents) return true;
+        var success = true;
+        if (typeof XMLHttpRequest !== 'undefined') {
+          throw new Error("Lazy loading should have been performed (contents set) in createLazyFile, but it was not. Lazy loading only works in web workers. Use --embed-file or --preload-file in emcc on the main thread.");
+        } else if (Module['read']) {
+          // Command-line.
+          try {
+            // WARNING: Can't read binary files in V8's d8 or tracemonkey's js, as
+            //          read() will try to parse UTF8.
+            obj.contents = intArrayFromString(Module['read'](obj.url), true);
+          } catch (e) {
+            success = false;
+          }
+        } else {
+          throw new Error('Cannot load without read() or XMLHttpRequest.');
+        }
+        if (!success) ___setErrNo(ERRNO_CODES.EIO);
+        return success;
+      },createLazyFile:function (parent, name, url, canRead, canWrite) {
+        // Lazy chunked Uint8Array (implements get and length from Uint8Array). Actual getting is abstracted away for eventual reuse.
+        function LazyUint8Array() {
+          this.lengthKnown = false;
+          this.chunks = []; // Loaded chunks. Index is the chunk number
+        }
+        LazyUint8Array.prototype.get = function LazyUint8Array_get(idx) {
+          if (idx > this.length-1 || idx < 0) {
+            return undefined;
+          }
+          var chunkOffset = idx % this.chunkSize;
+          var chunkNum = Math.floor(idx / this.chunkSize);
+          return this.getter(chunkNum)[chunkOffset];
+        }
+        LazyUint8Array.prototype.setDataGetter = function LazyUint8Array_setDataGetter(getter) {
+          this.getter = getter;
+        }
+        LazyUint8Array.prototype.cacheLength = function LazyUint8Array_cacheLength() {
+            // Find length
+            var xhr = new XMLHttpRequest();
+            xhr.open('HEAD', url, false);
+            xhr.send(null);
+            if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+            var datalength = Number(xhr.getResponseHeader("Content-length"));
+            var header;
+            var hasByteServing = (header = xhr.getResponseHeader("Accept-Ranges")) && header === "bytes";
+            var chunkSize = 1024*1024; // Chunk size in bytes
+
+            if (!hasByteServing) chunkSize = datalength;
+
+            // Function to get a range from the remote URL.
+            var doXHR = (function(from, to) {
+              if (from > to) throw new Error("invalid range (" + from + ", " + to + ") or no bytes requested!");
+              if (to > datalength-1) throw new Error("only " + datalength + " bytes available! programmer error!");
+
+              // TODO: Use mozResponseArrayBuffer, responseStream, etc. if available.
+              var xhr = new XMLHttpRequest();
+              xhr.open('GET', url, false);
+              if (datalength !== chunkSize) xhr.setRequestHeader("Range", "bytes=" + from + "-" + to);
+
+              // Some hints to the browser that we want binary data.
+              if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
+              if (xhr.overrideMimeType) {
+                xhr.overrideMimeType('text/plain; charset=x-user-defined');
+              }
+
+              xhr.send(null);
+              if (!(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304)) throw new Error("Couldn't load " + url + ". Status: " + xhr.status);
+              if (xhr.response !== undefined) {
+                return new Uint8Array(xhr.response || []);
+              } else {
+                return intArrayFromString(xhr.responseText || '', true);
+              }
+            });
+            var lazyArray = this;
+            lazyArray.setDataGetter(function(chunkNum) {
+              var start = chunkNum * chunkSize;
+              var end = (chunkNum+1) * chunkSize - 1; // including this byte
+              end = Math.min(end, datalength-1); // if datalength-1 is selected, this is the last block
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") {
+                lazyArray.chunks[chunkNum] = doXHR(start, end);
+              }
+              if (typeof(lazyArray.chunks[chunkNum]) === "undefined") throw new Error("doXHR failed!");
+              return lazyArray.chunks[chunkNum];
+            });
+
+            this._length = datalength;
+            this._chunkSize = chunkSize;
+            this.lengthKnown = true;
+        }
+        if (typeof XMLHttpRequest !== 'undefined') {
+          if (!ENVIRONMENT_IS_WORKER) throw 'Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc';
+          var lazyArray = new LazyUint8Array();
+          Object.defineProperty(lazyArray, "length", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._length;
+              }
+          });
+          Object.defineProperty(lazyArray, "chunkSize", {
+              get: function() {
+                  if(!this.lengthKnown) {
+                      this.cacheLength();
+                  }
+                  return this._chunkSize;
+              }
+          });
+
+          var properties = { isDevice: false, contents: lazyArray };
+        } else {
+          var properties = { isDevice: false, url: url };
+        }
+
+        var node = FS.createFile(parent, name, properties, canRead, canWrite);
+        // This is a total hack, but I want to get this lazy file code out of the
+        // core of MEMFS. If we want to keep this lazy file concept I feel it should
+        // be its own thin LAZYFS proxying calls to MEMFS.
+        if (properties.contents) {
+          node.contents = properties.contents;
+        } else if (properties.url) {
+          node.contents = null;
+          node.url = properties.url;
+        }
+        // override each stream op with one that tries to force load the lazy file first
+        var stream_ops = {};
+        var keys = Object.keys(node.stream_ops);
+        keys.forEach(function(key) {
+          var fn = node.stream_ops[key];
+          stream_ops[key] = function forceLoadLazyFile() {
+            if (!FS.forceLoadFile(node)) {
+              throw new FS.ErrnoError(ERRNO_CODES.EIO);
+            }
+            return fn.apply(null, arguments);
+          };
+        });
+        // use a custom read function
+        stream_ops.read = function stream_ops_read(stream, buffer, offset, length, position) {
+          if (!FS.forceLoadFile(node)) {
+            throw new FS.ErrnoError(ERRNO_CODES.EIO);
+          }
+          var contents = stream.node.contents;
+          if (position >= contents.length)
+            return 0;
+          var size = Math.min(contents.length - position, length);
+          assert(size >= 0);
+          if (contents.slice) { // normal array
+            for (var i = 0; i < size; i++) {
+              buffer[offset + i] = contents[position + i];
+            }
+          } else {
+            for (var i = 0; i < size; i++) { // LazyUint8Array from sync binary XHR
+              buffer[offset + i] = contents.get(position + i);
+            }
+          }
+          return size;
+        };
+        node.stream_ops = stream_ops;
+        return node;
+      },createPreloadedFile:function (parent, name, url, canRead, canWrite, onload, onerror, dontCreateFile, canOwn) {
+        Browser.init();
+        // TODO we should allow people to just pass in a complete filename instead
+        // of parent and name being that we just join them anyways
+        var fullname = name ? PATH.resolve(PATH.join2(parent, name)) : parent;
+        function processData(byteArray) {
+          function finish(byteArray) {
+            if (!dontCreateFile) {
+              FS.createDataFile(parent, name, byteArray, canRead, canWrite, canOwn);
+            }
+            if (onload) onload();
+            removeRunDependency('cp ' + fullname);
+          }
+          var handled = false;
+          Module['preloadPlugins'].forEach(function(plugin) {
+            if (handled) return;
+            if (plugin['canHandle'](fullname)) {
+              plugin['handle'](byteArray, fullname, finish, function() {
+                if (onerror) onerror();
+                removeRunDependency('cp ' + fullname);
+              });
+              handled = true;
+            }
+          });
+          if (!handled) finish(byteArray);
+        }
+        addRunDependency('cp ' + fullname);
+        if (typeof url == 'string') {
+          Browser.asyncLoad(url, function(byteArray) {
+            processData(byteArray);
+          }, onerror);
+        } else {
+          processData(url);
+        }
+      },indexedDB:function () {
+        return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
+      },DB_NAME:function () {
+        return 'EM_FS_' + window.location.pathname;
+      },DB_VERSION:20,DB_STORE_NAME:"FILE_DATA",saveFilesToDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = function openRequest_onupgradeneeded() {
+          console.log('creating db');
+          var db = openRequest.result;
+          db.createObjectStore(FS.DB_STORE_NAME);
+        };
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          var transaction = db.transaction([FS.DB_STORE_NAME], 'readwrite');
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var putRequest = files.put(FS.analyzePath(path).object.contents, path);
+            putRequest.onsuccess = function putRequest_onsuccess() { ok++; if (ok + fail == total) finish() };
+            putRequest.onerror = function putRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      },loadFilesFromDB:function (paths, onload, onerror) {
+        onload = onload || function(){};
+        onerror = onerror || function(){};
+        var indexedDB = FS.indexedDB();
+        try {
+          var openRequest = indexedDB.open(FS.DB_NAME(), FS.DB_VERSION);
+        } catch (e) {
+          return onerror(e);
+        }
+        openRequest.onupgradeneeded = onerror; // no database to load from
+        openRequest.onsuccess = function openRequest_onsuccess() {
+          var db = openRequest.result;
+          try {
+            var transaction = db.transaction([FS.DB_STORE_NAME], 'readonly');
+          } catch(e) {
+            onerror(e);
+            return;
+          }
+          var files = transaction.objectStore(FS.DB_STORE_NAME);
+          var ok = 0, fail = 0, total = paths.length;
+          function finish() {
+            if (fail == 0) onload(); else onerror();
+          }
+          paths.forEach(function(path) {
+            var getRequest = files.get(path);
+            getRequest.onsuccess = function getRequest_onsuccess() {
+              if (FS.analyzePath(path).exists) {
+                FS.unlink(path);
+              }
+              FS.createDataFile(PATH.dirname(path), PATH.basename(path), getRequest.result, true, true, true);
+              ok++;
+              if (ok + fail == total) finish();
+            };
+            getRequest.onerror = function getRequest_onerror() { fail++; if (ok + fail == total) finish() };
+          });
+          transaction.onerror = onerror;
+        };
+        openRequest.onerror = onerror;
+      }};
+
+
+
+
+  function _mkport() { throw 'TODO' }var SOCKFS={mount:function (mount) {
+        return FS.createNode(null, '/', 16384 | 511 /* 0777 */, 0);
+      },createSocket:function (family, type, protocol) {
+        var streaming = type == 1;
+        if (protocol) {
+          assert(streaming == (protocol == 6)); // if SOCK_STREAM, must be tcp
+        }
+
+        // create our internal socket structure
+        var sock = {
+          family: family,
+          type: type,
+          protocol: protocol,
+          server: null,
+          peers: {},
+          pending: [],
+          recv_queue: [],
+          sock_ops: SOCKFS.websocket_sock_ops
+        };
+
+        // create the filesystem node to store the socket structure
+        var name = SOCKFS.nextname();
+        var node = FS.createNode(SOCKFS.root, name, 49152, 0);
+        node.sock = sock;
+
+        // and the wrapping stream that enables library functions such
+        // as read and write to indirectly interact with the socket
+        var stream = FS.createStream({
+          path: name,
+          node: node,
+          flags: FS.modeStringToFlags('r+'),
+          seekable: false,
+          stream_ops: SOCKFS.stream_ops
+        });
+
+        // map the new stream to the socket structure (sockets have a 1:1
+        // relationship with a stream)
+        sock.stream = stream;
+
+        return sock;
+      },getSocket:function (fd) {
+        var stream = FS.getStream(fd);
+        if (!stream || !FS.isSocket(stream.node.mode)) {
+          return null;
+        }
+        return stream.node.sock;
+      },stream_ops:{poll:function (stream) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.poll(sock);
+        },ioctl:function (stream, request, varargs) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.ioctl(sock, request, varargs);
+        },read:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          var msg = sock.sock_ops.recvmsg(sock, length);
+          if (!msg) {
+            // socket is closed
+            return 0;
+          }
+          buffer.set(msg.buffer, offset);
+          return msg.buffer.length;
+        },write:function (stream, buffer, offset, length, position /* ignored */) {
+          var sock = stream.node.sock;
+          return sock.sock_ops.sendmsg(sock, buffer, offset, length);
+        },close:function (stream) {
+          var sock = stream.node.sock;
+          sock.sock_ops.close(sock);
+        }},nextname:function () {
+        if (!SOCKFS.nextname.current) {
+          SOCKFS.nextname.current = 0;
+        }
+        return 'socket[' + (SOCKFS.nextname.current++) + ']';
+      },websocket_sock_ops:{createPeer:function (sock, addr, port) {
+          var ws;
+
+          if (typeof addr === 'object') {
+            ws = addr;
+            addr = null;
+            port = null;
+          }
+
+          if (ws) {
+            // for sockets that've already connected (e.g. we're the server)
+            // we can inspect the _socket property for the address
+            if (ws._socket) {
+              addr = ws._socket.remoteAddress;
+              port = ws._socket.remotePort;
+            }
+            // if we're just now initializing a connection to the remote,
+            // inspect the url property
+            else {
+              var result = /ws[s]?:\/\/([^:]+):(\d+)/.exec(ws.url);
+              if (!result) {
+                throw new Error('WebSocket URL must be in the format ws(s)://address:port');
+              }
+              addr = result[1];
+              port = parseInt(result[2], 10);
+            }
+          } else {
+            // create the actual websocket object and connect
+            try {
+              // runtimeConfig gets set to true if WebSocket runtime configuration is available.
+              var runtimeConfig = (Module['websocket'] && ('object' === typeof Module['websocket']));
+
+              // The default value is 'ws://' the replace is needed because the compiler replaces "//" comments with '#'
+              // comments without checking context, so we'd end up with ws:#, the replace swaps the "#" for "//" again.
+              var url = 'ws:#'.replace('#', '//');
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['url']) {
+                  url = Module['websocket']['url']; // Fetch runtime WebSocket URL config.
+                }
+              }
+
+              if (url === 'ws://' || url === 'wss://') { // Is the supplied URL config just a prefix, if so complete it.
+                url = url + addr + ':' + port;
+              }
+
+              // Make the WebSocket subprotocol (Sec-WebSocket-Protocol) default to binary if no configuration is set.
+              var subProtocols = 'binary'; // The default value is 'binary'
+
+              if (runtimeConfig) {
+                if ('string' === typeof Module['websocket']['subprotocol']) {
+                  subProtocols = Module['websocket']['subprotocol']; // Fetch runtime WebSocket subprotocol config.
+                }
+              }
+
+              // The regex trims the string (removes spaces at the beginning and end, then splits the string by
+              // <any space>,<any space> into an Array. Whitespace removal is important for Websockify and ws.
+              subProtocols = subProtocols.replace(/^ +| +$/g,"").split(/ *, */);
+
+              // The node ws library API for specifying optional subprotocol is slightly different than the browser's.
+              var opts = ENVIRONMENT_IS_NODE ? {'protocol': subProtocols.toString()} : subProtocols;
+
+              // If node we use the ws library.
+              var WebSocket = ENVIRONMENT_IS_NODE ? require('ws') : window['WebSocket'];
+              ws = new WebSocket(url, opts);
+              ws.binaryType = 'arraybuffer';
+            } catch (e) {
+              throw new FS.ErrnoError(ERRNO_CODES.EHOSTUNREACH);
+            }
+          }
+
+
+          var peer = {
+            addr: addr,
+            port: port,
+            socket: ws,
+            dgram_send_queue: []
+          };
+
+          SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+          SOCKFS.websocket_sock_ops.handlePeerEvents(sock, peer);
+
+          // if this is a bound dgram socket, send the port number first to allow
+          // us to override the ephemeral port reported to us by remotePort on the
+          // remote end.
+          if (sock.type === 2 && typeof sock.sport !== 'undefined') {
+            peer.dgram_send_queue.push(new Uint8Array([
+                255, 255, 255, 255,
+                'p'.charCodeAt(0), 'o'.charCodeAt(0), 'r'.charCodeAt(0), 't'.charCodeAt(0),
+                ((sock.sport & 0xff00) >> 8) , (sock.sport & 0xff)
+            ]));
+          }
+
+          return peer;
+        },getPeer:function (sock, addr, port) {
+          return sock.peers[addr + ':' + port];
+        },addPeer:function (sock, peer) {
+          sock.peers[peer.addr + ':' + peer.port] = peer;
+        },removePeer:function (sock, peer) {
+          delete sock.peers[peer.addr + ':' + peer.port];
+        },handlePeerEvents:function (sock, peer) {
+          var first = true;
+
+          var handleOpen = function () {
+            try {
+              var queued = peer.dgram_send_queue.shift();
+              while (queued) {
+                peer.socket.send(queued);
+                queued = peer.dgram_send_queue.shift();
+              }
+            } catch (e) {
+              // not much we can do here in the way of proper error handling as we've already
+              // lied and said this data was sent. shut it down.
+              peer.socket.close();
+            }
+          };
+
+          function handleMessage(data) {
+            assert(typeof data !== 'string' && data.byteLength !== undefined);  // must receive an ArrayBuffer
+            data = new Uint8Array(data);  // make a typed array view on the array buffer
+
+
+            // if this is the port message, override the peer's port with it
+            var wasfirst = first;
+            first = false;
+            if (wasfirst &&
+                data.length === 10 &&
+                data[0] === 255 && data[1] === 255 && data[2] === 255 && data[3] === 255 &&
+                data[4] === 'p'.charCodeAt(0) && data[5] === 'o'.charCodeAt(0) && data[6] === 'r'.charCodeAt(0) && data[7] === 't'.charCodeAt(0)) {
+              // update the peer's port and it's key in the peer map
+              var newport = ((data[8] << 8) | data[9]);
+              SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+              peer.port = newport;
+              SOCKFS.websocket_sock_ops.addPeer(sock, peer);
+              return;
+            }
+
+            sock.recv_queue.push({ addr: peer.addr, port: peer.port, data: data });
+          };
+
+          if (ENVIRONMENT_IS_NODE) {
+            peer.socket.on('open', handleOpen);
+            peer.socket.on('message', function(data, flags) {
+              if (!flags.binary) {
+                return;
+              }
+              handleMessage((new Uint8Array(data)).buffer);  // copy from node Buffer -> ArrayBuffer
+            });
+            peer.socket.on('error', function() {
+              // don't throw
+            });
+          } else {
+            peer.socket.onopen = handleOpen;
+            peer.socket.onmessage = function peer_socket_onmessage(event) {
+              handleMessage(event.data);
+            };
+          }
+        },poll:function (sock) {
+          if (sock.type === 1 && sock.server) {
+            // listen sockets should only say they're available for reading
+            // if there are pending clients.
+            return sock.pending.length ? (64 | 1) : 0;
+          }
+
+          var mask = 0;
+          var dest = sock.type === 1 ?  // we only care about the socket state for connection-based sockets
+            SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport) :
+            null;
+
+          if (sock.recv_queue.length ||
+              !dest ||  // connection-less sockets are always ready to read
+              (dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {  // let recv return 0 once closed
+            mask |= (64 | 1);
+          }
+
+          if (!dest ||  // connection-less sockets are always ready to write
+              (dest && dest.socket.readyState === dest.socket.OPEN)) {
+            mask |= 4;
+          }
+
+          if ((dest && dest.socket.readyState === dest.socket.CLOSING) ||
+              (dest && dest.socket.readyState === dest.socket.CLOSED)) {
+            mask |= 16;
+          }
+
+          return mask;
+        },ioctl:function (sock, request, arg) {
+          switch (request) {
+            case 21531:
+              var bytes = 0;
+              if (sock.recv_queue.length) {
+                bytes = sock.recv_queue[0].data.length;
+              }
+              HEAP32[((arg)>>2)]=bytes;
+              return 0;
+            default:
+              return ERRNO_CODES.EINVAL;
+          }
+        },close:function (sock) {
+          // if we've spawned a listen server, close it
+          if (sock.server) {
+            try {
+              sock.server.close();
+            } catch (e) {
+            }
+            sock.server = null;
+          }
+          // close any peer connections
+          var peers = Object.keys(sock.peers);
+          for (var i = 0; i < peers.length; i++) {
+            var peer = sock.peers[peers[i]];
+            try {
+              peer.socket.close();
+            } catch (e) {
+            }
+            SOCKFS.websocket_sock_ops.removePeer(sock, peer);
+          }
+          return 0;
+        },bind:function (sock, addr, port) {
+          if (typeof sock.saddr !== 'undefined' || typeof sock.sport !== 'undefined') {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already bound
+          }
+          sock.saddr = addr;
+          sock.sport = port || _mkport();
+          // in order to emulate dgram sockets, we need to launch a listen server when
+          // binding on a connection-less socket
+          // note: this is only required on the server side
+          if (sock.type === 2) {
+            // close the existing server if it exists
+            if (sock.server) {
+              sock.server.close();
+              sock.server = null;
+            }
+            // swallow error operation not supported error that occurs when binding in the
+            // browser where this isn't supported
+            try {
+              sock.sock_ops.listen(sock, 0);
+            } catch (e) {
+              if (!(e instanceof FS.ErrnoError)) throw e;
+              if (e.errno !== ERRNO_CODES.EOPNOTSUPP) throw e;
+            }
+          }
+        },connect:function (sock, addr, port) {
+          if (sock.server) {
+            throw new FS.ErrnoError(ERRNO_CODS.EOPNOTSUPP);
+          }
+
+          // TODO autobind
+          // if (!sock.addr && sock.type == 2) {
+          // }
+
+          // early out if we're already connected / in the middle of connecting
+          if (typeof sock.daddr !== 'undefined' && typeof sock.dport !== 'undefined') {
+            var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+            if (dest) {
+              if (dest.socket.readyState === dest.socket.CONNECTING) {
+                throw new FS.ErrnoError(ERRNO_CODES.EALREADY);
+              } else {
+                throw new FS.ErrnoError(ERRNO_CODES.EISCONN);
+              }
+            }
+          }
+
+          // add the socket to our peer list and set our
+          // destination address / port to match
+          var peer = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+          sock.daddr = peer.addr;
+          sock.dport = peer.port;
+
+          // always "fail" in non-blocking mode
+          throw new FS.ErrnoError(ERRNO_CODES.EINPROGRESS);
+        },listen:function (sock, backlog) {
+          if (!ENVIRONMENT_IS_NODE) {
+            throw new FS.ErrnoError(ERRNO_CODES.EOPNOTSUPP);
+          }
+          if (sock.server) {
+             throw new FS.ErrnoError(ERRNO_CODES.EINVAL);  // already listening
+          }
+          var WebSocketServer = require('ws').Server;
+          var host = sock.saddr;
+          sock.server = new WebSocketServer({
+            host: host,
+            port: sock.sport
+            // TODO support backlog
+          });
+
+          sock.server.on('connection', function(ws) {
+            if (sock.type === 1) {
+              var newsock = SOCKFS.createSocket(sock.family, sock.type, sock.protocol);
+
+              // create a peer on the new socket
+              var peer = SOCKFS.websocket_sock_ops.createPeer(newsock, ws);
+              newsock.daddr = peer.addr;
+              newsock.dport = peer.port;
+
+              // push to queue for accept to pick up
+              sock.pending.push(newsock);
+            } else {
+              // create a peer on the listen socket so calling sendto
+              // with the listen socket and an address will resolve
+              // to the correct client
+              SOCKFS.websocket_sock_ops.createPeer(sock, ws);
+            }
+          });
+          sock.server.on('closed', function() {
+            sock.server = null;
+          });
+          sock.server.on('error', function() {
+            // don't throw
+          });
+        },accept:function (listensock) {
+          if (!listensock.server) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+          var newsock = listensock.pending.shift();
+          newsock.stream.flags = listensock.stream.flags;
+          return newsock;
+        },getname:function (sock, peer) {
+          var addr, port;
+          if (peer) {
+            if (sock.daddr === undefined || sock.dport === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            }
+            addr = sock.daddr;
+            port = sock.dport;
+          } else {
+            // TODO saddr and sport will be set for bind()'d UDP sockets, but what
+            // should we be returning for TCP sockets that've been connect()'d?
+            addr = sock.saddr || 0;
+            port = sock.sport || 0;
+          }
+          return { addr: addr, port: port };
+        },sendmsg:function (sock, buffer, offset, length, addr, port) {
+          if (sock.type === 2) {
+            // connection-less sockets will honor the message address,
+            // and otherwise fall back to the bound destination address
+            if (addr === undefined || port === undefined) {
+              addr = sock.daddr;
+              port = sock.dport;
+            }
+            // if there was no address to fall back to, error out
+            if (addr === undefined || port === undefined) {
+              throw new FS.ErrnoError(ERRNO_CODES.EDESTADDRREQ);
+            }
+          } else {
+            // connection-based sockets will only use the bound
+            addr = sock.daddr;
+            port = sock.dport;
+          }
+
+          // find the peer for the destination address
+          var dest = SOCKFS.websocket_sock_ops.getPeer(sock, addr, port);
+
+          // early out if not connected with a connection-based socket
+          if (sock.type === 1) {
+            if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+              throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+            } else if (dest.socket.readyState === dest.socket.CONNECTING) {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // create a copy of the incoming data to send, as the WebSocket API
+          // doesn't work entirely with an ArrayBufferView, it'll just send
+          // the entire underlying buffer
+          var data;
+          if (buffer instanceof Array || buffer instanceof ArrayBuffer) {
+            data = buffer.slice(offset, offset + length);
+          } else {  // ArrayBufferView
+            data = buffer.buffer.slice(buffer.byteOffset + offset, buffer.byteOffset + offset + length);
+          }
+
+          // if we're emulating a connection-less dgram socket and don't have
+          // a cached connection, queue the buffer to send upon connect and
+          // lie, saying the data was sent now.
+          if (sock.type === 2) {
+            if (!dest || dest.socket.readyState !== dest.socket.OPEN) {
+              // if we're not connected, open a new connection
+              if (!dest || dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                dest = SOCKFS.websocket_sock_ops.createPeer(sock, addr, port);
+              }
+              dest.dgram_send_queue.push(data);
+              return length;
+            }
+          }
+
+          try {
+            // send the actual data
+            dest.socket.send(data);
+            return length;
+          } catch (e) {
+            throw new FS.ErrnoError(ERRNO_CODES.EINVAL);
+          }
+        },recvmsg:function (sock, length) {
+          // http://pubs.opengroup.org/onlinepubs/7908799/xns/recvmsg.html
+          if (sock.type === 1 && sock.server) {
+            // tcp servers should not be recv()'ing on the listen socket
+            throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+          }
+
+          var queued = sock.recv_queue.shift();
+          if (!queued) {
+            if (sock.type === 1) {
+              var dest = SOCKFS.websocket_sock_ops.getPeer(sock, sock.daddr, sock.dport);
+
+              if (!dest) {
+                // if we have a destination address but are not connected, error out
+                throw new FS.ErrnoError(ERRNO_CODES.ENOTCONN);
+              }
+              else if (dest.socket.readyState === dest.socket.CLOSING || dest.socket.readyState === dest.socket.CLOSED) {
+                // return null if the socket has closed
+                return null;
+              }
+              else {
+                // else, our socket is in a valid state but truly has nothing available
+                throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+              }
+            } else {
+              throw new FS.ErrnoError(ERRNO_CODES.EAGAIN);
+            }
+          }
+
+          // queued.data will be an ArrayBuffer if it's unadulterated, but if it's
+          // requeued TCP data it'll be an ArrayBufferView
+          var queuedLength = queued.data.byteLength || queued.data.length;
+          var queuedOffset = queued.data.byteOffset || 0;
+          var queuedBuffer = queued.data.buffer || queued.data;
+          var bytesRead = Math.min(length, queuedLength);
+          var res = {
+            buffer: new Uint8Array(queuedBuffer, queuedOffset, bytesRead),
+            addr: queued.addr,
+            port: queued.port
+          };
+
+
+          // push back any unread data for TCP connections
+          if (sock.type === 1 && bytesRead < queuedLength) {
+            var bytesRemaining = queuedLength - bytesRead;
+            queued.data = new Uint8Array(queuedBuffer, queuedOffset + bytesRead, bytesRemaining);
+            sock.recv_queue.unshift(queued);
+          }
+
+          return res;
+        }}};function _send(fd, buf, len, flags) {
+      var sock = SOCKFS.getSocket(fd);
+      if (!sock) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      // TODO honor flags
+      return _write(fd, buf, len);
+    }
+
+  function _pwrite(fildes, buf, nbyte, offset) {
+      // ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte, offset);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }function _write(fildes, buf, nbyte) {
+      // ssize_t write(int fildes, const void *buf, size_t nbyte);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/write.html
+      var stream = FS.getStream(fildes);
+      if (!stream) {
+        ___setErrNo(ERRNO_CODES.EBADF);
+        return -1;
+      }
+
+
+      try {
+        var slab = HEAP8;
+        return FS.write(stream, slab, buf, nbyte);
+      } catch (e) {
+        FS.handleFSError(e);
+        return -1;
+      }
+    }
+
+  function _fileno(stream) {
+      // int fileno(FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fileno.html
+      stream = FS.getStreamFromPtr(stream);
+      if (!stream) return -1;
+      return stream.fd;
+    }function _fwrite(ptr, size, nitems, stream) {
+      // size_t fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fwrite.html
+      var bytesToWrite = nitems * size;
+      if (bytesToWrite == 0) return 0;
+      var fd = _fileno(stream);
+      var bytesWritten = _write(fd, ptr, bytesToWrite);
+      if (bytesWritten == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return 0;
+      } else {
+        return Math.floor(bytesWritten / size);
+      }
+    }
+
+
+
+  Module["_strlen"] = _strlen;
+
+  function __reallyNegative(x) {
+      return x < 0 || (x === 0 && (1/x) === -Infinity);
+    }function __formatString(format, varargs) {
+      var textIndex = format;
+      var argIndex = 0;
+      function getNextArg(type) {
+        // NOTE: Explicitly ignoring type safety. Otherwise this fails:
+        //       int x = 4; printf("%c\n", (char)x);
+        var ret;
+        if (type === 'double') {
+          ret = HEAPF64[(((varargs)+(argIndex))>>3)];
+        } else if (type == 'i64') {
+          ret = [HEAP32[(((varargs)+(argIndex))>>2)],
+                 HEAP32[(((varargs)+(argIndex+4))>>2)]];
+
+        } else {
+          type = 'i32'; // varargs are always i32, i64, or double
+          ret = HEAP32[(((varargs)+(argIndex))>>2)];
+        }
+        argIndex += Runtime.getNativeFieldSize(type);
+        return ret;
+      }
+
+      var ret = [];
+      var curr, next, currArg;
+      while(1) {
+        var startTextIndex = textIndex;
+        curr = HEAP8[(textIndex)];
+        if (curr === 0) break;
+        next = HEAP8[((textIndex+1)|0)];
+        if (curr == 37) {
+          // Handle flags.
+          var flagAlwaysSigned = false;
+          var flagLeftAlign = false;
+          var flagAlternative = false;
+          var flagZeroPad = false;
+          var flagPadSign = false;
+          flagsLoop: while (1) {
+            switch (next) {
+              case 43:
+                flagAlwaysSigned = true;
+                break;
+              case 45:
+                flagLeftAlign = true;
+                break;
+              case 35:
+                flagAlternative = true;
+                break;
+              case 48:
+                if (flagZeroPad) {
+                  break flagsLoop;
+                } else {
+                  flagZeroPad = true;
+                  break;
+                }
+              case 32:
+                flagPadSign = true;
+                break;
+              default:
+                break flagsLoop;
+            }
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          }
+
+          // Handle width.
+          var width = 0;
+          if (next == 42) {
+            width = getNextArg('i32');
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+          } else {
+            while (next >= 48 && next <= 57) {
+              width = width * 10 + (next - 48);
+              textIndex++;
+              next = HEAP8[((textIndex+1)|0)];
+            }
+          }
+
+          // Handle precision.
+          var precisionSet = false, precision = -1;
+          if (next == 46) {
+            precision = 0;
+            precisionSet = true;
+            textIndex++;
+            next = HEAP8[((textIndex+1)|0)];
+            if (next == 42) {
+              precision = getNextArg('i32');
+              textIndex++;
+            } else {
+              while(1) {
+                var precisionChr = HEAP8[((textIndex+1)|0)];
+                if (precisionChr < 48 ||
+                    precisionChr > 57) break;
+                precision = precision * 10 + (precisionChr - 48);
+                textIndex++;
+              }
+            }
+            next = HEAP8[((textIndex+1)|0)];
+          }
+          if (precision < 0) {
+            precision = 6; // Standard default.
+            precisionSet = false;
+          }
+
+          // Handle integer sizes. WARNING: These assume a 32-bit architecture!
+          var argSize;
+          switch (String.fromCharCode(next)) {
+            case 'h':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 104) {
+                textIndex++;
+                argSize = 1; // char (actually i32 in varargs)
+              } else {
+                argSize = 2; // short (actually i32 in varargs)
+              }
+              break;
+            case 'l':
+              var nextNext = HEAP8[((textIndex+2)|0)];
+              if (nextNext == 108) {
+                textIndex++;
+                argSize = 8; // long long
+              } else {
+                argSize = 4; // long
+              }
+              break;
+            case 'L': // long long
+            case 'q': // int64_t
+            case 'j': // intmax_t
+              argSize = 8;
+              break;
+            case 'z': // size_t
+            case 't': // ptrdiff_t
+            case 'I': // signed ptrdiff_t or unsigned size_t
+              argSize = 4;
+              break;
+            default:
+              argSize = null;
+          }
+          if (argSize) textIndex++;
+          next = HEAP8[((textIndex+1)|0)];
+
+          // Handle type specifier.
+          switch (String.fromCharCode(next)) {
+            case 'd': case 'i': case 'u': case 'o': case 'x': case 'X': case 'p': {
+              // Integer.
+              var signed = next == 100 || next == 105;
+              argSize = argSize || 4;
+              var currArg = getNextArg('i' + (argSize * 8));
+              var argText;
+              // Flatten i64-1 [low, high] into a (slightly rounded) double
+              if (argSize == 8) {
+                currArg = Runtime.makeBigInt(currArg[0], currArg[1], next == 117);
+              }
+              // Truncate to requested size.
+              if (argSize <= 4) {
+                var limit = Math.pow(256, argSize) - 1;
+                currArg = (signed ? reSign : unSign)(currArg & limit, argSize * 8);
+              }
+              // Format the number.
+              var currAbsArg = Math.abs(currArg);
+              var prefix = '';
+              if (next == 100 || next == 105) {
+                argText = reSign(currArg, 8 * argSize, 1).toString(10);
+              } else if (next == 117) {
+                argText = unSign(currArg, 8 * argSize, 1).toString(10);
+                currArg = Math.abs(currArg);
+              } else if (next == 111) {
+                argText = (flagAlternative ? '0' : '') + currAbsArg.toString(8);
+              } else if (next == 120 || next == 88) {
+                prefix = (flagAlternative && currArg != 0) ? '0x' : '';
+                if (currArg < 0) {
+                  // Represent negative numbers in hex as 2's complement.
+                  currArg = -currArg;
+                  argText = (currAbsArg - 1).toString(16);
+                  var buffer = [];
+                  for (var i = 0; i < argText.length; i++) {
+                    buffer.push((0xF - parseInt(argText[i], 16)).toString(16));
+                  }
+                  argText = buffer.join('');
+                  while (argText.length < argSize * 2) argText = 'f' + argText;
+                } else {
+                  argText = currAbsArg.toString(16);
+                }
+                if (next == 88) {
+                  prefix = prefix.toUpperCase();
+                  argText = argText.toUpperCase();
+                }
+              } else if (next == 112) {
+                if (currAbsArg === 0) {
+                  argText = '(nil)';
+                } else {
+                  prefix = '0x';
+                  argText = currAbsArg.toString(16);
+                }
+              }
+              if (precisionSet) {
+                while (argText.length < precision) {
+                  argText = '0' + argText;
+                }
+              }
+
+              // Add sign if needed
+              if (currArg >= 0) {
+                if (flagAlwaysSigned) {
+                  prefix = '+' + prefix;
+                } else if (flagPadSign) {
+                  prefix = ' ' + prefix;
+                }
+              }
+
+              // Move sign to prefix so we zero-pad after the sign
+              if (argText.charAt(0) == '-') {
+                prefix = '-' + prefix;
+                argText = argText.substr(1);
+              }
+
+              // Add padding.
+              while (prefix.length + argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad) {
+                    argText = '0' + argText;
+                  } else {
+                    prefix = ' ' + prefix;
+                  }
+                }
+              }
+
+              // Insert the result into the buffer.
+              argText = prefix + argText;
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 'f': case 'F': case 'e': case 'E': case 'g': case 'G': {
+              // Float.
+              var currArg = getNextArg('double');
+              var argText;
+              if (isNaN(currArg)) {
+                argText = 'nan';
+                flagZeroPad = false;
+              } else if (!isFinite(currArg)) {
+                argText = (currArg < 0 ? '-' : '') + 'inf';
+                flagZeroPad = false;
+              } else {
+                var isGeneral = false;
+                var effectivePrecision = Math.min(precision, 20);
+
+                // Convert g/G to f/F or e/E, as per:
+                // http://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html
+                if (next == 103 || next == 71) {
+                  isGeneral = true;
+                  precision = precision || 1;
+                  var exponent = parseInt(currArg.toExponential(effectivePrecision).split('e')[1], 10);
+                  if (precision > exponent && exponent >= -4) {
+                    next = ((next == 103) ? 'f' : 'F').charCodeAt(0);
+                    precision -= exponent + 1;
+                  } else {
+                    next = ((next == 103) ? 'e' : 'E').charCodeAt(0);
+                    precision--;
+                  }
+                  effectivePrecision = Math.min(precision, 20);
+                }
+
+                if (next == 101 || next == 69) {
+                  argText = currArg.toExponential(effectivePrecision);
+                  // Make sure the exponent has at least 2 digits.
+                  if (/[eE][-+]\d$/.test(argText)) {
+                    argText = argText.slice(0, -1) + '0' + argText.slice(-1);
+                  }
+                } else if (next == 102 || next == 70) {
+                  argText = currArg.toFixed(effectivePrecision);
+                  if (currArg === 0 && __reallyNegative(currArg)) {
+                    argText = '-' + argText;
+                  }
+                }
+
+                var parts = argText.split('e');
+                if (isGeneral && !flagAlternative) {
+                  // Discard trailing zeros and periods.
+                  while (parts[0].length > 1 && parts[0].indexOf('.') != -1 &&
+                         (parts[0].slice(-1) == '0' || parts[0].slice(-1) == '.')) {
+                    parts[0] = parts[0].slice(0, -1);
+                  }
+                } else {
+                  // Make sure we have a period in alternative mode.
+                  if (flagAlternative && argText.indexOf('.') == -1) parts[0] += '.';
+                  // Zero pad until required precision.
+                  while (precision > effectivePrecision++) parts[0] += '0';
+                }
+                argText = parts[0] + (parts.length > 1 ? 'e' + parts[1] : '');
+
+                // Capitalize 'E' if needed.
+                if (next == 69) argText = argText.toUpperCase();
+
+                // Add sign.
+                if (currArg >= 0) {
+                  if (flagAlwaysSigned) {
+                    argText = '+' + argText;
+                  } else if (flagPadSign) {
+                    argText = ' ' + argText;
+                  }
+                }
+              }
+
+              // Add padding.
+              while (argText.length < width) {
+                if (flagLeftAlign) {
+                  argText += ' ';
+                } else {
+                  if (flagZeroPad && (argText[0] == '-' || argText[0] == '+')) {
+                    argText = argText[0] + '0' + argText.slice(1);
+                  } else {
+                    argText = (flagZeroPad ? '0' : ' ') + argText;
+                  }
+                }
+              }
+
+              // Adjust case.
+              if (next < 97) argText = argText.toUpperCase();
+
+              // Insert the result into the buffer.
+              argText.split('').forEach(function(chr) {
+                ret.push(chr.charCodeAt(0));
+              });
+              break;
+            }
+            case 's': {
+              // String.
+              var arg = getNextArg('i8*');
+              var argLength = arg ? _strlen(arg) : '(null)'.length;
+              if (precisionSet) argLength = Math.min(argLength, precision);
+              if (!flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              if (arg) {
+                for (var i = 0; i < argLength; i++) {
+                  ret.push(HEAPU8[((arg++)|0)]);
+                }
+              } else {
+                ret = ret.concat(intArrayFromString('(null)'.substr(0, argLength), true));
+              }
+              if (flagLeftAlign) {
+                while (argLength < width--) {
+                  ret.push(32);
+                }
+              }
+              break;
+            }
+            case 'c': {
+              // Character.
+              if (flagLeftAlign) ret.push(getNextArg('i8'));
+              while (--width > 0) {
+                ret.push(32);
+              }
+              if (!flagLeftAlign) ret.push(getNextArg('i8'));
+              break;
+            }
+            case 'n': {
+              // Write the length written so far to the next parameter.
+              var ptr = getNextArg('i32*');
+              HEAP32[((ptr)>>2)]=ret.length;
+              break;
+            }
+            case '%': {
+              // Literal percent sign.
+              ret.push(curr);
+              break;
+            }
+            default: {
+              // Unknown specifiers remain untouched.
+              for (var i = startTextIndex; i < textIndex + 2; i++) {
+                ret.push(HEAP8[(i)]);
+              }
+            }
+          }
+          textIndex += 2;
+          // TODO: Support a/A (hex float) and m (last error) specifiers.
+          // TODO: Support %1${specifier} for arg selection.
+        } else {
+          ret.push(curr);
+          textIndex += 1;
+        }
+      }
+      return ret;
+    }function _fprintf(stream, format, varargs) {
+      // int fprintf(FILE *restrict stream, const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var result = __formatString(format, varargs);
+      var stack = Runtime.stackSave();
+      var ret = _fwrite(allocate(result, 'i8', ALLOC_STACK), 1, result.length, stream);
+      Runtime.stackRestore(stack);
+      return ret;
+    }function _printf(format, varargs) {
+      // int printf(const char *restrict format, ...);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/printf.html
+      var stdout = HEAP32[((_stdout)>>2)];
+      return _fprintf(stdout, format, varargs);
+    }
+
+
+  function _fputs(s, stream) {
+      // int fputs(const char *restrict s, FILE *restrict stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fputs.html
+      var fd = _fileno(stream);
+      return _write(fd, s, _strlen(s));
+    }
+
+  function _fputc(c, stream) {
+      // int fputc(int c, FILE *stream);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/fputc.html
+      var chr = unSign(c & 0xFF);
+      HEAP8[((_fputc.ret)|0)]=chr;
+      var fd = _fileno(stream);
+      var ret = _write(fd, _fputc.ret, 1);
+      if (ret == -1) {
+        var streamObj = FS.getStreamFromPtr(stream);
+        if (streamObj) streamObj.error = true;
+        return -1;
+      } else {
+        return chr;
+      }
+    }function _puts(s) {
+      // int puts(const char *s);
+      // http://pubs.opengroup.org/onlinepubs/000095399/functions/puts.html
+      // NOTE: puts() always writes an extra newline.
+      var stdout = HEAP32[((_stdout)>>2)];
+      var ret = _fputs(s, stdout);
+      if (ret < 0) {
+        return ret;
+      } else {
+        var newlineRet = _fputc(10, stdout);
+        return (newlineRet < 0) ? -1 : ret + 1;
+      }
+    }
+
+  function _sysconf(name) {
+      // long sysconf(int name);
+      // http://pubs.opengroup.org/onlinepubs/009695399/functions/sysconf.html
+      switch(name) {
+        case 30: return PAGE_SIZE;
+        case 132:
+        case 133:
+        case 12:
+        case 137:
+        case 138:
+        case 15:
+        case 235:
+        case 16:
+        case 17:
+        case 18:
+        case 19:
+        case 20:
+        case 149:
+        case 13:
+        case 10:
+        case 236:
+        case 153:
+        case 9:
+        case 21:
+        case 22:
+        case 159:
+        case 154:
+        case 14:
+        case 77:
+        case 78:
+        case 139:
+        case 80:
+        case 81:
+        case 79:
+        case 82:
+        case 68:
+        case 67:
+        case 164:
+        case 11:
+        case 29:
+        case 47:
+        case 48:
+        case 95:
+        case 52:
+        case 51:
+        case 46:
+          return 200809;
+        case 27:
+        case 246:
+        case 127:
+        case 128:
+        case 23:
+        case 24:
+        case 160:
+        case 161:
+        case 181:
+        case 182:
+        case 242:
+        case 183:
+        case 184:
+        case 243:
+        case 244:
+        case 245:
+        case 165:
+        case 178:
+        case 179:
+        case 49:
+        case 50:
+        case 168:
+        case 169:
+        case 175:
+        case 170:
+        case 171:
+        case 172:
+        case 97:
+        case 76:
+        case 32:
+        case 173:
+        case 35:
+          return -1;
+        case 176:
+        case 177:
+        case 7:
+        case 155:
+        case 8:
+        case 157:
+        case 125:
+        case 126:
+        case 92:
+        case 93:
+        case 129:
+        case 130:
+        case 131:
+        case 94:
+        case 91:
+          return 1;
+        case 74:
+        case 60:
+        case 69:
+        case 70:
+        case 4:
+          return 1024;
+        case 31:
+        case 42:
+        case 72:
+          return 32;
+        case 87:
+        case 26:
+        case 33:
+          return 2147483647;
+        case 34:
+        case 1:
+          return 47839;
+        case 38:
+        case 36:
+          return 99;
+        case 43:
+        case 37:
+          return 2048;
+        case 0: return 2097152;
+        case 3: return 65536;
+        case 28: return 32768;
+        case 44: return 32767;
+        case 75: return 16384;
+        case 39: return 1000;
+        case 89: return 700;
+        case 71: return 256;
+        case 40: return 255;
+        case 2: return 100;
+        case 180: return 64;
+        case 25: return 20;
+        case 5: return 16;
+        case 6: return 6;
+        case 73: return 4;
+        case 84: return 1;
+      }
+      ___setErrNo(ERRNO_CODES.EINVAL);
+      return -1;
+    }
+
+
+  Module["_memset"] = _memset;
+
+  function ___errno_location() {
+      return ___errno_state;
+    }
+
+  function _abort() {
+      Module['abort']();
+    }
+
+  var Browser={mainLoop:{scheduler:null,method:"",shouldPause:false,paused:false,queue:[],pause:function () {
+          Browser.mainLoop.shouldPause = true;
+        },resume:function () {
+          if (Browser.mainLoop.paused) {
+            Browser.mainLoop.paused = false;
+            Browser.mainLoop.scheduler();
+          }
+          Browser.mainLoop.shouldPause = false;
+        },updateStatus:function () {
+          if (Module['setStatus']) {
+            var message = Module['statusMessage'] || 'Please wait...';
+            var remaining = Browser.mainLoop.remainingBlockers;
+            var expected = Browser.mainLoop.expectedBlockers;
+            if (remaining) {
+              if (remaining < expected) {
+                Module['setStatus'](message + ' (' + (expected - remaining) + '/' + expected + ')');
+              } else {
+                Module['setStatus'](message);
+              }
+            } else {
+              Module['setStatus']('');
+            }
+          }
+        }},isFullScreen:false,pointerLock:false,moduleContextCreatedCallbacks:[],workers:[],init:function () {
+        if (!Module["preloadPlugins"]) Module["preloadPlugins"] = []; // needs to exist even in workers
+
+        if (Browser.initted || ENVIRONMENT_IS_WORKER) return;
+        Browser.initted = true;
+
+        try {
+          new Blob();
+          Browser.hasBlobConstructor = true;
+        } catch(e) {
+          Browser.hasBlobConstructor = false;
+          console.log("warning: no blob constructor, cannot create blobs with mimetypes");
+        }
+        Browser.BlobBuilder = typeof MozBlobBuilder != "undefined" ? MozBlobBuilder : (typeof WebKitBlobBuilder != "undefined" ? WebKitBlobBuilder : (!Browser.hasBlobConstructor ? console.log("warning: no BlobBuilder") : null));
+        Browser.URLObject = typeof window != "undefined" ? (window.URL ? window.URL : window.webkitURL) : undefined;
+        if (!Module.noImageDecoding && typeof Browser.URLObject === 'undefined') {
+          console.log("warning: Browser does not support creating object URLs. Built-in browser image decoding will not be available.");
+          Module.noImageDecoding = true;
+        }
+
+        // Support for plugins that can process preloaded files. You can add more of these to
+        // your app by creating and appending to Module.preloadPlugins.
+        //
+        // Each plugin is asked if it can handle a file based on the file's name. If it can,
+        // it is given the file's raw data. When it is done, it calls a callback with the file's
+        // (possibly modified) data. For example, a plugin might decompress a file, or it
+        // might create some side data structure for use later (like an Image element, etc.).
+
+        var imagePlugin = {};
+        imagePlugin['canHandle'] = function imagePlugin_canHandle(name) {
+          return !Module.noImageDecoding && /\.(jpg|jpeg|png|bmp)$/i.test(name);
+        };
+        imagePlugin['handle'] = function imagePlugin_handle(byteArray, name, onload, onerror) {
+          var b = null;
+          if (Browser.hasBlobConstructor) {
+            try {
+              b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+              if (b.size !== byteArray.length) { // Safari bug #118630
+                // Safari's Blob can only take an ArrayBuffer
+                b = new Blob([(new Uint8Array(byteArray)).buffer], { type: Browser.getMimetype(name) });
+              }
+            } catch(e) {
+              Runtime.warnOnce('Blob constructor present but fails: ' + e + '; falling back to blob builder');
+            }
+          }
+          if (!b) {
+            var bb = new Browser.BlobBuilder();
+            bb.append((new Uint8Array(byteArray)).buffer); // we need to pass a buffer, and must copy the array to get the right data range
+            b = bb.getBlob();
+          }
+          var url = Browser.URLObject.createObjectURL(b);
+          var img = new Image();
+          img.onload = function img_onload() {
+            assert(img.complete, 'Image ' + name + ' could not be decoded');
+            var canvas = document.createElement('canvas');
+            canvas.width = img.width;
+            canvas.height = img.height;
+            var ctx = canvas.getContext('2d');
+            ctx.drawImage(img, 0, 0);
+            Module["preloadedImages"][name] = canvas;
+            Browser.URLObject.revokeObjectURL(url);
+            if (onload) onload(byteArray);
+          };
+          img.onerror = function img_onerror(event) {
+            console.log('Image ' + url + ' could not be decoded');
+            if (onerror) onerror();
+          };
+          img.src = url;
+        };
+        Module['preloadPlugins'].push(imagePlugin);
+
+        var audioPlugin = {};
+        audioPlugin['canHandle'] = function audioPlugin_canHandle(name) {
+          return !Module.noAudioDecoding && name.substr(-4) in { '.ogg': 1, '.wav': 1, '.mp3': 1 };
+        };
+        audioPlugin['handle'] = function audioPlugin_handle(byteArray, name, onload, onerror) {
+          var done = false;
+          function finish(audio) {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = audio;
+            if (onload) onload(byteArray);
+          }
+          function fail() {
+            if (done) return;
+            done = true;
+            Module["preloadedAudios"][name] = new Audio(); // empty shim
+            if (onerror) onerror();
+          }
+          if (Browser.hasBlobConstructor) {
+            try {
+              var b = new Blob([byteArray], { type: Browser.getMimetype(name) });
+            } catch(e) {
+              return fail();
+            }
+            var url = Browser.URLObject.createObjectURL(b); // XXX we never revoke this!
+            var audio = new Audio();
+            audio.addEventListener('canplaythrough', function() { finish(audio) }, false); // use addEventListener due to chromium bug 124926
+            audio.onerror = function audio_onerror(event) {
+              if (done) return;
+              console.log('warning: browser could not fully decode audio ' + name + ', trying slower base64 approach');
+              function encode64(data) {
+                var BASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+                var PAD = '=';
+                var ret = '';
+                var leftchar = 0;
+                var leftbits = 0;
+                for (var i = 0; i < data.length; i++) {
+                  leftchar = (leftchar << 8) | data[i];
+                  leftbits += 8;
+                  while (leftbits >= 6) {
+                    var curr = (leftchar >> (leftbits-6)) & 0x3f;
+                    leftbits -= 6;
+                    ret += BASE[curr];
+                  }
+                }
+                if (leftbits == 2) {
+                  ret += BASE[(leftchar&3) << 4];
+                  ret += PAD + PAD;
+                } else if (leftbits == 4) {
+                  ret += BASE[(leftchar&0xf) << 2];
+                  ret += PAD;
+                }
+                return ret;
+              }
+              audio.src = 'data:audio/x-' + name.substr(-3) + ';base64,' + encode64(byteArray);
+              finish(audio); // we don't wait for confirmation this worked - but it's worth trying
+            };
+            audio.src = url;
+            // workaround for chrome bug 124926 - we do not always get oncanplaythrough or onerror
+            Browser.safeSetTimeout(function() {
+              finish(audio); // try to use it even though it is not necessarily ready to play
+            }, 10000);
+          } else {
+            return fail();
+          }
+        };
+        Module['preloadPlugins'].push(audioPlugin);
+
+        // Canvas event setup
+
+        var canvas = Module['canvas'];
+
+        // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module
+        // Module['forcedAspectRatio'] = 4 / 3;
+
+        canvas.requestPointerLock = canvas['requestPointerLock'] ||
+                                    canvas['mozRequestPointerLock'] ||
+                                    canvas['webkitRequestPointerLock'] ||
+                                    canvas['msRequestPointerLock'] ||
+                                    function(){};
+        canvas.exitPointerLock = document['exitPointerLock'] ||
+                                 document['mozExitPointerLock'] ||
+                                 document['webkitExitPointerLock'] ||
+                                 document['msExitPointerLock'] ||
+                                 function(){}; // no-op if function does not exist
+        canvas.exitPointerLock = canvas.exitPointerLock.bind(document);
+
+        function pointerLockChange() {
+          Browser.pointerLock = document['pointerLockElement'] === canvas ||
+                                document['mozPointerLockElement'] === canvas ||
+                                document['webkitPointerLockElement'] === canvas ||
+                                document['msPointerLockElement'] === canvas;
+        }
+
+        document.addEventListener('pointerlockchange', pointerLockChange, false);
+        document.addEventListener('mozpointerlockchange', pointerLockChange, false);
+        document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
+        document.addEventListener('mspointerlockchange', pointerLockChange, false);
+
+        if (Module['elementPointerLock']) {
+          canvas.addEventListener("click", function(ev) {
+            if (!Browser.pointerLock && canvas.requestPointerLock) {
+              canvas.requestPointerLock();
+              ev.preventDefault();
+            }
+          }, false);
+        }
+      },createContext:function (canvas, useWebGL, setInModule, webGLContextAttributes) {
+        var ctx;
+        var errorInfo = '?';
+        function onContextCreationError(event) {
+          errorInfo = event.statusMessage || errorInfo;
+        }
+        try {
+          if (useWebGL) {
+            var contextAttributes = {
+              antialias: false,
+              alpha: false
+            };
+
+            if (webGLContextAttributes) {
+              for (var attribute in webGLContextAttributes) {
+                contextAttributes[attribute] = webGLContextAttributes[attribute];
+              }
+            }
+
+
+            canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
+            try {
+              ['experimental-webgl', 'webgl'].some(function(webglId) {
+                return ctx = canvas.getContext(webglId, contextAttributes);
+              });
+            } finally {
+              canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
+            }
+          } else {
+            ctx = canvas.getContext('2d');
+          }
+          if (!ctx) throw ':(';
+        } catch (e) {
+          Module.print('Could not create canvas: ' + [errorInfo, e]);
+          return null;
+        }
+        if (useWebGL) {
+          // Set the background of the WebGL canvas to black
+          canvas.style.backgroundColor = "black";
+
+          // Warn on context loss
+          canvas.addEventListener('webglcontextlost', function(event) {
+            alert('WebGL context lost. You will need to reload the page.');
+          }, false);
+        }
+        if (setInModule) {
+          GLctx = Module.ctx = ctx;
+          Module.useWebGL = useWebGL;
+          Browser.moduleContextCreatedCallbacks.forEach(function(callback) { callback() });
+          Browser.init();
+        }
+        return ctx;
+      },destroyContext:function (canvas, useWebGL, setInModule) {},fullScreenHandlersInstalled:false,lockPointer:undefined,resizeCanvas:undefined,requestFullScreen:function (lockPointer, resizeCanvas) {
+        Browser.lockPointer = lockPointer;
+        Browser.resizeCanvas = resizeCanvas;
+        if (typeof Browser.lockPointer === 'undefined') Browser.lockPointer = true;
+        if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false;
+
+        var canvas = Module['canvas'];
+        function fullScreenChange() {
+          Browser.isFullScreen = false;
+          var canvasContainer = canvas.parentNode;
+          if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+               document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+               document['fullScreenElement'] || document['fullscreenElement'] ||
+               document['msFullScreenElement'] || document['msFullscreenElement'] ||
+               document['webkitCurrentFullScreenElement']) === canvasContainer) {
+            canvas.cancelFullScreen = document['cancelFullScreen'] ||
+                                      document['mozCancelFullScreen'] ||
+                                      document['webkitCancelFullScreen'] ||
+                                      document['msExitFullscreen'] ||
+                                      document['exitFullscreen'] ||
+                                      function() {};
+            canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document);
+            if (Browser.lockPointer) canvas.requestPointerLock();
+            Browser.isFullScreen = true;
+            if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize();
+          } else {
+
+            // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen
+            canvasContainer.parentNode.insertBefore(canvas, canvasContainer);
+            canvasContainer.parentNode.removeChild(canvasContainer);
+
+            if (Browser.resizeCanvas) Browser.setWindowedCanvasSize();
+          }
+          if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen);
+          Browser.updateCanvasDimensions(canvas);
+        }
+
+        if (!Browser.fullScreenHandlersInstalled) {
+          Browser.fullScreenHandlersInstalled = true;
+          document.addEventListener('fullscreenchange', fullScreenChange, false);
+          document.addEventListener('mozfullscreenchange', fullScreenChange, false);
+          document.addEventListener('webkitfullscreenchange', fullScreenChange, false);
+          document.addEventListener('MSFullscreenChange', fullScreenChange, false);
+        }
+
+        // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root
+        var canvasContainer = document.createElement("div");
+        canvas.parentNode.insertBefore(canvasContainer, canvas);
+        canvasContainer.appendChild(canvas);
+
+        // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size)
+        canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] ||
+                                            canvasContainer['mozRequestFullScreen'] ||
+                                            canvasContainer['msRequestFullscreen'] ||
+                                           (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null);
+        canvasContainer.requestFullScreen();
+      },requestAnimationFrame:function requestAnimationFrame(func) {
+        if (typeof window === 'undefined') { // Provide fallback to setTimeout if window is undefined (e.g. in Node.js)
+          setTimeout(func, 1000/60);
+        } else {
+          if (!window.requestAnimationFrame) {
+            window.requestAnimationFrame = window['requestAnimationFrame'] ||
+                                           window['mozRequestAnimationFrame'] ||
+                                           window['webkitRequestAnimationFrame'] ||
+                                           window['msRequestAnimationFrame'] ||
+                                           window['oRequestAnimationFrame'] ||
+                                           window['setTimeout'];
+          }
+          window.requestAnimationFrame(func);
+        }
+      },safeCallback:function (func) {
+        return function() {
+          if (!ABORT) return func.apply(null, arguments);
+        };
+      },safeRequestAnimationFrame:function (func) {
+        return Browser.requestAnimationFrame(function() {
+          if (!ABORT) func();
+        });
+      },safeSetTimeout:function (func, timeout) {
+        return setTimeout(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },safeSetInterval:function (func, timeout) {
+        return setInterval(function() {
+          if (!ABORT) func();
+        }, timeout);
+      },getMimetype:function (name) {
+        return {
+          'jpg': 'image/jpeg',
+          'jpeg': 'image/jpeg',
+          'png': 'image/png',
+          'bmp': 'image/bmp',
+          'ogg': 'audio/ogg',
+          'wav': 'audio/wav',
+          'mp3': 'audio/mpeg'
+        }[name.substr(name.lastIndexOf('.')+1)];
+      },getUserMedia:function (func) {
+        if(!window.getUserMedia) {
+          window.getUserMedia = navigator['getUserMedia'] ||
+                                navigator['mozGetUserMedia'];
+        }
+        window.getUserMedia(func);
+      },getMovementX:function (event) {
+        return event['movementX'] ||
+               event['mozMovementX'] ||
+               event['webkitMovementX'] ||
+               0;
+      },getMovementY:function (event) {
+        return event['movementY'] ||
+               event['mozMovementY'] ||
+               event['webkitMovementY'] ||
+               0;
+      },getMouseWheelDelta:function (event) {
+        return Math.max(-1, Math.min(1, event.type === 'DOMMouseScroll' ? event.detail : -event.wheelDelta));
+      },mouseX:0,mouseY:0,mouseMovementX:0,mouseMovementY:0,calculateMouseEvent:function (event) { // event should be mousemove, mousedown or mouseup
+        if (Browser.pointerLock) {
+          // When the pointer is locked, calculate the coordinates
+          // based on the movement of the mouse.
+          // Workaround for Firefox bug 764498
+          if (event.type != 'mousemove' &&
+              ('mozMovementX' in event)) {
+            Browser.mouseMovementX = Browser.mouseMovementY = 0;
+          } else {
+            Browser.mouseMovementX = Browser.getMovementX(event);
+            Browser.mouseMovementY = Browser.getMovementY(event);
+          }
+
+          // check if SDL is available
+          if (typeof SDL != "undefined") {
+    Browser.mouseX = SDL.mouseX + Browser.mouseMovementX;
+    Browser.mouseY = SDL.mouseY + Browser.mouseMovementY;
+          } else {
+    // just add the mouse delta to the current absolut mouse position
+    // FIXME: ideally this should be clamped against the canvas size and zero
+    Browser.mouseX += Browser.mouseMovementX;
+    Browser.mouseY += Browser.mouseMovementY;
+          }
+        } else {
+          // Otherwise, calculate the movement based on the changes
+          // in the coordinates.
+          var rect = Module["canvas"].getBoundingClientRect();
+          var x, y;
+
+          // Neither .scrollX or .pageXOffset are defined in a spec, but
+          // we prefer .scrollX because it is currently in a spec draft.
+          // (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
+          var scrollX = ((typeof window.scrollX !== 'undefined') ? window.scrollX : window.pageXOffset);
+          var scrollY = ((typeof window.scrollY !== 'undefined') ? window.scrollY : window.pageYOffset);
+          if (event.type == 'touchstart' ||
+              event.type == 'touchend' ||
+              event.type == 'touchmove') {
+            var t = event.touches.item(0);
+            if (t) {
+              x = t.pageX - (scrollX + rect.left);
+              y = t.pageY - (scrollY + rect.top);
+            } else {
+              return;
+            }
+          } else {
+            x = event.pageX - (scrollX + rect.left);
+            y = event.pageY - (scrollY + rect.top);
+          }
+
+          // the canvas might be CSS-scaled compared to its backbuffer;
+          // SDL-using content will want mouse coordinates in terms
+          // of backbuffer units.
+          var cw = Module["canvas"].width;
+          var ch = Module["canvas"].height;
+          x = x * (cw / rect.width);
+          y = y * (ch / rect.height);
+
+          Browser.mouseMovementX = x - Browser.mouseX;
+          Browser.mouseMovementY = y - Browser.mouseY;
+          Browser.mouseX = x;
+          Browser.mouseY = y;
+        }
+      },xhrLoad:function (url, onload, onerror) {
+        var xhr = new XMLHttpRequest();
+        xhr.open('GET', url, true);
+        xhr.responseType = 'arraybuffer';
+        xhr.onload = function xhr_onload() {
+          if (xhr.status == 200 || (xhr.status == 0 && xhr.response)) { // file URLs can return 0
+            onload(xhr.response);
+          } else {
+            onerror();
+          }
+        };
+        xhr.onerror = onerror;
+        xhr.send(null);
+      },asyncLoad:function (url, onload, onerror, noRunDep) {
+        Browser.xhrLoad(url, function(arrayBuffer) {
+          assert(arrayBuffer, 'Loading data file "' + url + '" failed (no arrayBuffer).');
+          onload(new Uint8Array(arrayBuffer));
+          if (!noRunDep) removeRunDependency('al ' + url);
+        }, function(event) {
+          if (onerror) {
+            onerror();
+          } else {
+            throw 'Loading data file "' + url + '" failed.';
+          }
+        });
+        if (!noRunDep) addRunDependency('al ' + url);
+      },resizeListeners:[],updateResizeListeners:function () {
+        var canvas = Module['canvas'];
+        Browser.resizeListeners.forEach(function(listener) {
+          listener(canvas.width, canvas.height);
+        });
+      },setCanvasSize:function (width, height, noUpdates) {
+        var canvas = Module['canvas'];
+        Browser.updateCanvasDimensions(canvas, width, height);
+        if (!noUpdates) Browser.updateResizeListeners();
+      },windowedWidth:0,windowedHeight:0,setFullScreenCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+    var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+    flags = flags | 0x00800000; // set SDL_FULLSCREEN flag
+    HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },setWindowedCanvasSize:function () {
+        // check if SDL is available
+        if (typeof SDL != "undefined") {
+    var flags = HEAPU32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)];
+    flags = flags & ~0x00800000; // clear SDL_FULLSCREEN flag
+    HEAP32[((SDL.screen+Runtime.QUANTUM_SIZE*0)>>2)]=flags
+        }
+        Browser.updateResizeListeners();
+      },updateCanvasDimensions:function (canvas, wNative, hNative) {
+        if (wNative && hNative) {
+          canvas.widthNative = wNative;
+          canvas.heightNative = hNative;
+        } else {
+          wNative = canvas.widthNative;
+          hNative = canvas.heightNative;
+        }
+        var w = wNative;
+        var h = hNative;
+        if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) {
+          if (w/h < Module['forcedAspectRatio']) {
+            w = Math.round(h * Module['forcedAspectRatio']);
+          } else {
+            h = Math.round(w / Module['forcedAspectRatio']);
+          }
+        }
+        if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] ||
+             document['mozFullScreenElement'] || document['mozFullscreenElement'] ||
+             document['fullScreenElement'] || document['fullscreenElement'] ||
+             document['msFullScreenElement'] || document['msFullscreenElement'] ||
+             document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) {
+           var factor = Math.min(screen.width / w, screen.height / h);
+           w = Math.round(w * factor);
+           h = Math.round(h * factor);
+        }
+        if (Browser.resizeCanvas) {
+          if (canvas.width  != w) canvas.width  = w;
+          if (canvas.height != h) canvas.height = h;
+          if (typeof canvas.style != 'undefined') {
+            canvas.style.removeProperty( "width");
+            canvas.style.removeProperty("height");
+          }
+        } else {
+          if (canvas.width  != wNative) canvas.width  = wNative;
+          if (canvas.height != hNative) canvas.height = hNative;
+          if (typeof canvas.style != 'undefined') {
+            if (w != wNative || h != hNative) {
+              canvas.style.setProperty( "width", w + "px", "important");
+              canvas.style.setProperty("height", h + "px", "important");
+            } else {
+              canvas.style.removeProperty( "width");
+              canvas.style.removeProperty("height");
+            }
+          }
+        }
+      }};
+
+  function _sbrk(bytes) {
+      // Implement a Linux-like 'memory area' for our 'process'.
+      // Changes the size of the memory area by |bytes|; returns the
+      // address of the previous top ('break') of the memory area
+      // We control the "dynamic" memory - DYNAMIC_BASE to DYNAMICTOP
+      var self = _sbrk;
+      if (!self.called) {
+        DYNAMICTOP = alignMemoryPage(DYNAMICTOP); // make sure we start out aligned
+        self.called = true;
+        assert(Runtime.dynamicAlloc);
+        self.alloc = Runtime.dynamicAlloc;
+        Runtime.dynamicAlloc = function() { abort('cannot dynamically allocate, sbrk now has control') };
+      }
+      var ret = DYNAMICTOP;
+      if (bytes != 0) self.alloc(bytes);
+      return ret;  // Previous break location.
+    }
+
+  function ___assert_fail(condition, filename, line, func) {
+      ABORT = true;
+      throw 'Assertion failed: ' + Pointer_stringify(condition) + ', at: ' + [filename ? Pointer_stringify(filename) : 'unknown filename', line, func ? Pointer_stringify(func) : 'unknown function'] + ' at ' + stackTrace();
+    }
+
+  function _time(ptr) {
+      var ret = Math.floor(Date.now()/1000);
+      if (ptr) {
+        HEAP32[((ptr)>>2)]=ret;
+      }
+      return ret;
+    }
+
+  function _llvm_bswap_i32(x) {
+      return ((x&0xff)<<24) | (((x>>8)&0xff)<<16) | (((x>>16)&0xff)<<8) | (x>>>24);
+    }
+
+
+
+  function _emscripten_memcpy_big(dest, src, num) {
+      HEAPU8.set(HEAPU8.subarray(src, src+num), dest);
+      return dest;
+    }
+  Module["_memcpy"] = _memcpy;
+FS.staticInit();__ATINIT__.unshift({ func: function() { if (!Module["noFSInit"] && !FS.init.initialized) FS.init() } });__ATMAIN__.push({ func: function() { FS.ignorePermissions = false } });__ATEXIT__.push({ func: function() { FS.quit() } });Module["FS_createFolder"] = FS.createFolder;Module["FS_createPath"] = FS.createPath;Module["FS_createDataFile"] = FS.createDataFile;Module["FS_createPreloadedFile"] = FS.createPreloadedFile;Module["FS_createLazyFile"] = FS.createLazyFile;Module["FS_createLink"] = FS.createLink;Module["FS_createDevice"] = FS.createDevice;
+___errno_state = Runtime.staticAlloc(4); HEAP32[((___errno_state)>>2)]=0;
+__ATINIT__.unshift({ func: function() { TTY.init() } });__ATEXIT__.push({ func: function() { TTY.shutdown() } });TTY.utf8 = new Runtime.UTF8Processor();
+if (ENVIRONMENT_IS_NODE) { var fs = require("fs"); NODEFS.staticInit(); }
+__ATINIT__.push({ func: function() { SOCKFS.root = FS.mount(SOCKFS, {}, null); } });
+_fputc.ret = allocate([0], "i8", ALLOC_STATIC);
+Module["requestFullScreen"] = function Module_requestFullScreen(lockPointer, resizeCanvas) { Browser.requestFullScreen(lockPointer, resizeCanvas) };
+  Module["requestAnimationFrame"] = function Module_requestAnimationFrame(func) { Browser.requestAnimationFrame(func) };
+  Module["setCanvasSize"] = function Module_setCanvasSize(width, height, noUpdates) { Browser.setCanvasSize(width, height, noUpdates) };
+  Module["pauseMainLoop"] = function Module_pauseMainLoop() { Browser.mainLoop.pause() };
+  Module["resumeMainLoop"] = function Module_resumeMainLoop() { Browser.mainLoop.resume() };
+  Module["getUserMedia"] = function Module_getUserMedia() { Browser.getUserMedia() }
+STACK_BASE = STACKTOP = Runtime.alignMemory(STATICTOP);
+
+staticSealed = true; // seal the static portion of memory
+
+STACK_MAX = STACK_BASE + 5242880;
+
+DYNAMIC_BASE = DYNAMICTOP = Runtime.alignMemory(STACK_MAX);
+
+assert(DYNAMIC_BASE < TOTAL_MEMORY, "TOTAL_MEMORY not big enough for stack");
+
+
+var Math_min = Math.min;
+function invoke_iiii(index,a1,a2,a3) {
+  try {
+    return Module["dynCall_iiii"](index,a1,a2,a3);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_vii(index,a1,a2) {
+  try {
+    Module["dynCall_vii"](index,a1,a2);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function invoke_iii(index,a1,a2) {
+  try {
+    return Module["dynCall_iii"](index,a1,a2);
+  } catch(e) {
+    if (typeof e !== 'number' && e !== 'longjmp') throw e;
+    asm["setThrew"](1, 0);
+  }
+}
+
+function asmPrintInt(x, y) {
+  Module.print('int ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+function asmPrintFloat(x, y) {
+  Module.print('float ' + x + ',' + y);// + ' ' + new Error().stack);
+}
+// EMSCRIPTEN_START_ASM
+var asm = (function(global, env, buffer) {
+  'use asm';
+  var HEAP8 = new global.Int8Array(buffer);
+  var HEAP16 = new global.Int16Array(buffer);
+  var HEAP32 = new global.Int32Array(buffer);
+  var HEAPU8 = new global.Uint8Array(buffer);
+  var HEAPU16 = new global.Uint16Array(buffer);
+  var HEAPU32 = new global.Uint32Array(buffer);
+  var HEAPF32 = new global.Float32Array(buffer);
+  var HEAPF64 = new global.Float64Array(buffer);
+
+  var STACKTOP=env.STACKTOP|0;
+  var STACK_MAX=env.STACK_MAX|0;
+  var tempDoublePtr=env.tempDoublePtr|0;
+  var ABORT=env.ABORT|0;
+
+  var __THREW__ = 0;
+  var threwValue = 0;
+  var setjmpId = 0;
+  var undef = 0;
+  var nan = +env.NaN, inf = +env.Infinity;
+  var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
+
+  var tempRet0 = 0;
+  var tempRet1 = 0;
+  var tempRet2 = 0;
+  var tempRet3 = 0;
+  var tempRet4 = 0;
+  var tempRet5 = 0;
+  var tempRet6 = 0;
+  var tempRet7 = 0;
+  var tempRet8 = 0;
+  var tempRet9 = 0;
+  var Math_floor=global.Math.floor;
+  var Math_abs=global.Math.abs;
+  var Math_sqrt=global.Math.sqrt;
+  var Math_pow=global.Math.pow;
+  var Math_cos=global.Math.cos;
+  var Math_sin=global.Math.sin;
+  var Math_tan=global.Math.tan;
+  var Math_acos=global.Math.acos;
+  var Math_asin=global.Math.asin;
+  var Math_atan=global.Math.atan;
+  var Math_atan2=global.Math.atan2;
+  var Math_exp=global.Math.exp;
+  var Math_log=global.Math.log;
+  var Math_ceil=global.Math.ceil;
+  var Math_imul=global.Math.imul;
+  var abort=env.abort;
+  var assert=env.assert;
+  var asmPrintInt=env.asmPrintInt;
+  var asmPrintFloat=env.asmPrintFloat;
+  var Math_min=env.min;
+  var invoke_iiii=env.invoke_iiii;
+  var invoke_vii=env.invoke_vii;
+  var invoke_iii=env.invoke_iii;
+  var _send=env._send;
+  var ___setErrNo=env.___setErrNo;
+  var ___assert_fail=env.___assert_fail;
+  var _fflush=env._fflush;
+  var _pwrite=env._pwrite;
+  var __reallyNegative=env.__reallyNegative;
+  var _sbrk=env._sbrk;
+  var ___errno_location=env.___errno_location;
+  var _emscripten_memcpy_big=env._emscripten_memcpy_big;
+  var _fileno=env._fileno;
+  var _sysconf=env._sysconf;
+  var _puts=env._puts;
+  var _mkport=env._mkport;
+  var _write=env._write;
+  var _llvm_bswap_i32=env._llvm_bswap_i32;
+  var _fputc=env._fputc;
+  var _abort=env._abort;
+  var _fwrite=env._fwrite;
+  var _time=env._time;
+  var _fprintf=env._fprintf;
+  var __formatString=env.__formatString;
+  var _fputs=env._fputs;
+  var _printf=env._printf;
+  var tempFloat = 0.0;
+
+// EMSCRIPTEN_START_FUNCS
+function _inflate(i2, i3) {
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, i36 = 0, i37 = 0, i38 = 0, i39 = 0, i40 = 0, i41 = 0, i42 = 0, i43 = 0, i44 = 0, i45 = 0, i46 = 0, i47 = 0, i48 = 0, i49 = 0, i50 = 0, i51 = 0, i52 = 0, i53 = 0, i54 = 0, i55 = 0, i56 = 0, i57 = 0, i58 = 0, i59 = 0, i60 = 0, i61 = 0, i62 = 0, i63 = 0, i64 = 0, i65 = 0, i66 = 0, i67 = 0, i68 = 0, i69 = 0, i70 = 0, i71 = 0, i72 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i25 = i1;
+ if ((i2 | 0) == 0) {
+  i72 = -2;
+  STACKTOP = i1;
+  return i72 | 0;
+ }
+ i4 = HEAP32[i2 + 28 >> 2] | 0;
+ if ((i4 | 0) == 0) {
+  i72 = -2;
+  STACKTOP = i1;
+  return i72 | 0;
+ }
+ i8 = i2 + 12 | 0;
+ i19 = HEAP32[i8 >> 2] | 0;
+ if ((i19 | 0) == 0) {
+  i72 = -2;
+  STACKTOP = i1;
+  return i72 | 0;
+ }
+ i62 = HEAP32[i2 >> 2] | 0;
+ if ((i62 | 0) == 0 ? (HEAP32[i2 + 4 >> 2] | 0) != 0 : 0) {
+  i72 = -2;
+  STACKTOP = i1;
+  return i72 | 0;
+ }
+ i68 = HEAP32[i4 >> 2] | 0;
+ if ((i68 | 0) == 11) {
+  HEAP32[i4 >> 2] = 12;
+  i68 = 12;
+  i62 = HEAP32[i2 >> 2] | 0;
+  i19 = HEAP32[i8 >> 2] | 0;
+ }
+ i15 = i2 + 16 | 0;
+ i59 = HEAP32[i15 >> 2] | 0;
+ i16 = i2 + 4 | 0;
+ i5 = HEAP32[i16 >> 2] | 0;
+ i17 = i4 + 56 | 0;
+ i6 = i4 + 60 | 0;
+ i12 = i4 + 8 | 0;
+ i10 = i4 + 24 | 0;
+ i39 = i25 + 1 | 0;
+ i11 = i4 + 16 | 0;
+ i38 = i4 + 32 | 0;
+ i35 = i2 + 24 | 0;
+ i40 = i4 + 36 | 0;
+ i41 = i4 + 20 | 0;
+ i9 = i2 + 48 | 0;
+ i42 = i4 + 64 | 0;
+ i46 = i4 + 12 | 0;
+ i47 = (i3 + -5 | 0) >>> 0 < 2;
+ i7 = i4 + 4 | 0;
+ i48 = i4 + 76 | 0;
+ i49 = i4 + 84 | 0;
+ i50 = i4 + 80 | 0;
+ i51 = i4 + 88 | 0;
+ i43 = (i3 | 0) == 6;
+ i57 = i4 + 7108 | 0;
+ i37 = i4 + 72 | 0;
+ i58 = i4 + 7112 | 0;
+ i54 = i4 + 68 | 0;
+ i28 = i4 + 44 | 0;
+ i29 = i4 + 7104 | 0;
+ i30 = i4 + 48 | 0;
+ i31 = i4 + 52 | 0;
+ i18 = i4 + 40 | 0;
+ i13 = i2 + 20 | 0;
+ i14 = i4 + 28 | 0;
+ i32 = i4 + 96 | 0;
+ i33 = i4 + 100 | 0;
+ i34 = i4 + 92 | 0;
+ i36 = i4 + 104 | 0;
+ i52 = i4 + 1328 | 0;
+ i53 = i4 + 108 | 0;
+ i27 = i4 + 112 | 0;
+ i55 = i4 + 752 | 0;
+ i56 = i4 + 624 | 0;
+ i44 = i25 + 2 | 0;
+ i45 = i25 + 3 | 0;
+ i67 = HEAP32[i6 >> 2] | 0;
+ i65 = i5;
+ i64 = HEAP32[i17 >> 2] | 0;
+ i26 = i59;
+ i61 = 0;
+ L17 : while (1) {
+  L19 : do {
+   switch (i68 | 0) {
+   case 16:
+    {
+     if (i67 >>> 0 < 14) {
+      i63 = i67;
+      while (1) {
+       if ((i65 | 0) == 0) {
+        i65 = 0;
+        break L17;
+       }
+       i65 = i65 + -1 | 0;
+       i66 = i62 + 1 | 0;
+       i64 = (HEAPU8[i62] << i63) + i64 | 0;
+       i63 = i63 + 8 | 0;
+       if (i63 >>> 0 < 14) {
+        i62 = i66;
+       } else {
+        i62 = i66;
+        break;
+       }
+      }
+     } else {
+      i63 = i67;
+     }
+     i71 = (i64 & 31) + 257 | 0;
+     HEAP32[i32 >> 2] = i71;
+     i72 = (i64 >>> 5 & 31) + 1 | 0;
+     HEAP32[i33 >> 2] = i72;
+     HEAP32[i34 >> 2] = (i64 >>> 10 & 15) + 4;
+     i64 = i64 >>> 14;
+     i63 = i63 + -14 | 0;
+     if (i71 >>> 0 > 286 | i72 >>> 0 > 30) {
+      HEAP32[i35 >> 2] = 11616;
+      HEAP32[i4 >> 2] = 29;
+      i66 = i26;
+      break L19;
+     } else {
+      HEAP32[i36 >> 2] = 0;
+      HEAP32[i4 >> 2] = 17;
+      i66 = 0;
+      i60 = 154;
+      break L19;
+     }
+    }
+   case 2:
+    {
+     if (i67 >>> 0 < 32) {
+      i63 = i67;
+      i60 = 47;
+     } else {
+      i60 = 49;
+     }
+     break;
+    }
+   case 23:
+    {
+     i66 = HEAP32[i37 >> 2] | 0;
+     i63 = i67;
+     i60 = 240;
+     break;
+    }
+   case 18:
+    {
+     i63 = HEAP32[i36 >> 2] | 0;
+     i69 = i65;
+     i60 = 164;
+     break;
+    }
+   case 1:
+    {
+     if (i67 >>> 0 < 16) {
+      i63 = i67;
+      while (1) {
+       if ((i65 | 0) == 0) {
+        i65 = 0;
+        break L17;
+       }
+       i65 = i65 + -1 | 0;
+       i66 = i62 + 1 | 0;
+       i64 = (HEAPU8[i62] << i63) + i64 | 0;
+       i63 = i63 + 8 | 0;
+       if (i63 >>> 0 < 16) {
+        i62 = i66;
+       } else {
+        i62 = i66;
+        break;
+       }
+      }
+     } else {
+      i63 = i67;
+     }
+     HEAP32[i11 >> 2] = i64;
+     if ((i64 & 255 | 0) != 8) {
+      HEAP32[i35 >> 2] = 11448;
+      HEAP32[i4 >> 2] = 29;
+      i66 = i26;
+      break L19;
+     }
+     if ((i64 & 57344 | 0) != 0) {
+      HEAP32[i35 >> 2] = 11504;
+      HEAP32[i4 >> 2] = 29;
+      i66 = i26;
+      break L19;
+     }
+     i60 = HEAP32[i38 >> 2] | 0;
+     if ((i60 | 0) == 0) {
+      i60 = i64;
+     } else {
+      HEAP32[i60 >> 2] = i64 >>> 8 & 1;
+      i60 = HEAP32[i11 >> 2] | 0;
+     }
+     if ((i60 & 512 | 0) != 0) {
+      HEAP8[i25] = i64;
+      HEAP8[i39] = i64 >>> 8;
+      HEAP32[i10 >> 2] = _crc32(HEAP32[i10 >> 2] | 0, i25, 2) | 0;
+     }
+     HEAP32[i4 >> 2] = 2;
+     i63 = 0;
+     i64 = 0;
+     i60 = 47;
+     break;
+    }
+   case 8:
+    {
+     i63 = i67;
+     i60 = 109;
+     break;
+    }
+   case 22:
+    {
+     i63 = i67;
+     i60 = 228;
+     break;
+    }
+   case 24:
+    {
+     i63 = i67;
+     i60 = 246;
+     break;
+    }
+   case 19:
+    {
+     i63 = i67;
+     i60 = 201;
+     break;
+    }
+   case 20:
+    {
+     i63 = i67;
+     i60 = 202;
+     break;
+    }
+   case 21:
+    {
+     i66 = HEAP32[i37 >> 2] | 0;
+     i63 = i67;
+     i60 = 221;
+     break;
+    }
+   case 10:
+    {
+     i63 = i67;
+     i60 = 121;
+     break;
+    }
+   case 11:
+    {
+     i63 = i67;
+     i60 = 124;
+     break;
+    }
+   case 12:
+    {
+     i63 = i67;
+     i60 = 125;
+     break;
+    }
+   case 5:
+    {
+     i63 = i67;
+     i60 = 73;
+     break;
+    }
+   case 4:
+    {
+     i63 = i67;
+     i60 = 62;
+     break;
+    }
+   case 0:
+    {
+     i66 = HEAP32[i12 >> 2] | 0;
+     if ((i66 | 0) == 0) {
+      HEAP32[i4 >> 2] = 12;
+      i63 = i67;
+      i66 = i26;
+      break L19;
+     }
+     if (i67 >>> 0 < 16) {
+      i63 = i67;
+      while (1) {
+       if ((i65 | 0) == 0) {
+        i65 = 0;
+        break L17;
+       }
+       i65 = i65 + -1 | 0;
+       i67 = i62 + 1 | 0;
+       i64 = (HEAPU8[i62] << i63) + i64 | 0;
+       i63 = i63 + 8 | 0;
+       if (i63 >>> 0 < 16) {
+        i62 = i67;
+       } else {
+        i62 = i67;
+        break;
+       }
+      }
+     } else {
+      i63 = i67;
+     }
+     if ((i66 & 2 | 0) != 0 & (i64 | 0) == 35615) {
+      HEAP32[i10 >> 2] = _crc32(0, 0, 0) | 0;
+      HEAP8[i25] = 31;
+      HEAP8[i39] = -117;
+      HEAP32[i10 >> 2] = _crc32(HEAP32[i10 >> 2] | 0, i25, 2) | 0;
+      HEAP32[i4 >> 2] = 1;
+      i63 = 0;
+      i64 = 0;
+      i66 = i26;
+      break L19;
+     }
+     HEAP32[i11 >> 2] = 0;
+     i67 = HEAP32[i38 >> 2] | 0;
+     if ((i67 | 0) != 0) {
+      HEAP32[i67 + 48 >> 2] = -1;
+      i66 = HEAP32[i12 >> 2] | 0;
+     }
+     if ((i66 & 1 | 0) != 0 ? ((((i64 << 8 & 65280) + (i64 >>> 8) | 0) >>> 0) % 31 | 0 | 0) == 0 : 0) {
+      if ((i64 & 15 | 0) != 8) {
+       HEAP32[i35 >> 2] = 11448;
+       HEAP32[i4 >> 2] = 29;
+       i66 = i26;
+       break L19;
+      }
+      i66 = i64 >>> 4;
+      i63 = i63 + -4 | 0;
+      i68 = (i66 & 15) + 8 | 0;
+      i67 = HEAP32[i40 >> 2] | 0;
+      if ((i67 | 0) != 0) {
+       if (i68 >>> 0 > i67 >>> 0) {
+        HEAP32[i35 >> 2] = 11480;
+        HEAP32[i4 >> 2] = 29;
+        i64 = i66;
+        i66 = i26;
+        break L19;
+       }
+      } else {
+       HEAP32[i40 >> 2] = i68;
+      }
+      HEAP32[i41 >> 2] = 1 << i68;
+      i63 = _adler32(0, 0, 0) | 0;
+      HEAP32[i10 >> 2] = i63;
+      HEAP32[i9 >> 2] = i63;
+      HEAP32[i4 >> 2] = i64 >>> 12 & 2 ^ 11;
+      i63 = 0;
+      i64 = 0;
+      i66 = i26;
+      break L19;
+     }
+     HEAP32[i35 >> 2] = 11424;
+     HEAP32[i4 >> 2] = 29;
+     i66 = i26;
+     break;
+    }
+   case 26:
+    {
+     if ((HEAP32[i12 >> 2] | 0) != 0) {
+      if (i67 >>> 0 < 32) {
+       i63 = i67;
+       while (1) {
+        if ((i65 | 0) == 0) {
+         i65 = 0;
+         break L17;
+        }
+        i65 = i65 + -1 | 0;
+        i66 = i62 + 1 | 0;
+        i64 = (HEAPU8[i62] << i63) + i64 | 0;
+        i63 = i63 + 8 | 0;
+        if (i63 >>> 0 < 32) {
+         i62 = i66;
+        } else {
+         i62 = i66;
+         break;
+        }
+       }
+      } else {
+       i63 = i67;
+      }
+      i66 = i59 - i26 | 0;
+      HEAP32[i13 >> 2] = (HEAP32[i13 >> 2] | 0) + i66;
+      HEAP32[i14 >> 2] = (HEAP32[i14 >> 2] | 0) + i66;
+      if ((i59 | 0) != (i26 | 0)) {
+       i59 = HEAP32[i10 >> 2] | 0;
+       i67 = i19 + (0 - i66) | 0;
+       if ((HEAP32[i11 >> 2] | 0) == 0) {
+        i59 = _adler32(i59, i67, i66) | 0;
+       } else {
+        i59 = _crc32(i59, i67, i66) | 0;
+       }
+       HEAP32[i10 >> 2] = i59;
+       HEAP32[i9 >> 2] = i59;
+      }
+      if ((HEAP32[i11 >> 2] | 0) == 0) {
+       i59 = _llvm_bswap_i32(i64 | 0) | 0;
+      } else {
+       i59 = i64;
+      }
+      if ((i59 | 0) == (HEAP32[i10 >> 2] | 0)) {
+       i63 = 0;
+       i64 = 0;
+       i59 = i26;
+      } else {
+       HEAP32[i35 >> 2] = 11904;
+       HEAP32[i4 >> 2] = 29;
+       i66 = i26;
+       i59 = i26;
+       break L19;
+      }
+     } else {
+      i63 = i67;
+     }
+     HEAP32[i4 >> 2] = 27;
+     i60 = 277;
+     break;
+    }
+   case 27:
+    {
+     i63 = i67;
+     i60 = 277;
+     break;
+    }
+   case 28:
+    {
+     i63 = i67;
+     i61 = 1;
+     i60 = 285;
+     break L17;
+    }
+   case 29:
+    {
+     i63 = i67;
+     i61 = -3;
+     break L17;
+    }
+   case 25:
+    {
+     if ((i26 | 0) == 0) {
+      i63 = i67;
+      i26 = 0;
+      i60 = 285;
+      break L17;
+     }
+     HEAP8[i19] = HEAP32[i42 >> 2];
+     HEAP32[i4 >> 2] = 20;
+     i63 = i67;
+     i66 = i26 + -1 | 0;
+     i19 = i19 + 1 | 0;
+     break;
+    }
+   case 17:
+    {
+     i66 = HEAP32[i36 >> 2] | 0;
+     if (i66 >>> 0 < (HEAP32[i34 >> 2] | 0) >>> 0) {
+      i63 = i67;
+      i60 = 154;
+     } else {
+      i60 = 158;
+     }
+     break;
+    }
+   case 13:
+    {
+     i63 = i67 & 7;
+     i64 = i64 >>> i63;
+     i63 = i67 - i63 | 0;
+     if (i63 >>> 0 < 32) {
+      while (1) {
+       if ((i65 | 0) == 0) {
+        i65 = 0;
+        break L17;
+       }
+       i65 = i65 + -1 | 0;
+       i66 = i62 + 1 | 0;
+       i64 = (HEAPU8[i62] << i63) + i64 | 0;
+       i63 = i63 + 8 | 0;
+       if (i63 >>> 0 < 32) {
+        i62 = i66;
+       } else {
+        i62 = i66;
+        break;
+       }
+      }
+     }
+     i66 = i64 & 65535;
+     if ((i66 | 0) == (i64 >>> 16 ^ 65535 | 0)) {
+      HEAP32[i42 >> 2] = i66;
+      HEAP32[i4 >> 2] = 14;
+      if (i43) {
+       i63 = 0;
+       i64 = 0;
+       i60 = 285;
+       break L17;
+      } else {
+       i63 = 0;
+       i64 = 0;
+       i60 = 143;
+       break L19;
+      }
+     } else {
+      HEAP32[i35 >> 2] = 11584;
+      HEAP32[i4 >> 2] = 29;
+      i66 = i26;
+      break L19;
+     }
+    }
+   case 7:
+    {
+     i63 = i67;
+     i60 = 96;
+     break;
+    }
+   case 14:
+    {
+     i63 = i67;
+     i60 = 143;
+     break;
+    }
+   case 15:
+    {
+     i63 = i67;
+     i60 = 144;
+     break;
+    }
+   case 9:
+    {
+     if (i67 >>> 0 < 32) {
+      i63 = i67;
+      while (1) {
+       if ((i65 | 0) == 0) {
+        i65 = 0;
+        break L17;
+       }
+       i65 = i65 + -1 | 0;
+       i66 = i62 + 1 | 0;
+       i64 = (HEAPU8[i62] << i63) + i64 | 0;
+       i63 = i63 + 8 | 0;
+       if (i63 >>> 0 < 32) {
+        i62 = i66;
+       } else {
+        i62 = i66;
+        break;
+       }
+      }
+     }
+     i63 = _llvm_bswap_i32(i64 | 0) | 0;
+     HEAP32[i10 >> 2] = i63;
+     HEAP32[i9 >> 2] = i63;
+     HEAP32[i4 >> 2] = 10;
+     i63 = 0;
+     i64 = 0;
+     i60 = 121;
+     break;
+    }
+   case 30:
+    {
+     i60 = 299;
+     break L17;
+    }
+   case 6:
+    {
+     i63 = i67;
+     i60 = 83;
+     break;
+    }
+   case 3:
+    {
+     if (i67 >>> 0 < 16) {
+      i63 = i67;
+      i66 = i62;
+      i60 = 55;
+     } else {
+      i60 = 57;
+     }
+     break;
+    }
+   default:
+    {
+     i2 = -2;
+     i60 = 300;
+     break L17;
+    }
+   }
+  } while (0);
+  if ((i60 | 0) == 47) {
+   while (1) {
+    i60 = 0;
+    if ((i65 | 0) == 0) {
+     i65 = 0;
+     break L17;
+    }
+    i65 = i65 + -1 | 0;
+    i60 = i62 + 1 | 0;
+    i64 = (HEAPU8[i62] << i63) + i64 | 0;
+    i63 = i63 + 8 | 0;
+    if (i63 >>> 0 < 32) {
+     i62 = i60;
+     i60 = 47;
+    } else {
+     i62 = i60;
+     i60 = 49;
+     break;
+    }
+   }
+  } else if ((i60 | 0) == 121) {
+   if ((HEAP32[i46 >> 2] | 0) == 0) {
+    i60 = 122;
+    break;
+   }
+   i60 = _adler32(0, 0, 0) | 0;
+   HEAP32[i10 >> 2] = i60;
+   HEAP32[i9 >> 2] = i60;
+   HEAP32[i4 >> 2] = 11;
+   i60 = 124;
+  } else if ((i60 | 0) == 143) {
+   HEAP32[i4 >> 2] = 15;
+   i60 = 144;
+  } else if ((i60 | 0) == 154) {
+   while (1) {
+    i60 = 0;
+    if (i63 >>> 0 < 3) {
+     while (1) {
+      if ((i65 | 0) == 0) {
+       i65 = 0;
+       break L17;
+      }
+      i65 = i65 + -1 | 0;
+      i67 = i62 + 1 | 0;
+      i64 = (HEAPU8[i62] << i63) + i64 | 0;
+      i63 = i63 + 8 | 0;
+      if (i63 >>> 0 < 3) {
+       i62 = i67;
+      } else {
+       i62 = i67;
+       break;
+      }
+     }
+    }
+    HEAP32[i36 >> 2] = i66 + 1;
+    HEAP16[i4 + (HEAPU16[11384 + (i66 << 1) >> 1] << 1) + 112 >> 1] = i64 & 7;
+    i64 = i64 >>> 3;
+    i63 = i63 + -3 | 0;
+    i66 = HEAP32[i36 >> 2] | 0;
+    if (i66 >>> 0 < (HEAP32[i34 >> 2] | 0) >>> 0) {
+     i60 = 154;
+    } else {
+     i67 = i63;
+     i60 = 158;
+     break;
+    }
+   }
+  } else if ((i60 | 0) == 277) {
+   i60 = 0;
+   if ((HEAP32[i12 >> 2] | 0) == 0) {
+    i60 = 284;
+    break;
+   }
+   if ((HEAP32[i11 >> 2] | 0) == 0) {
+    i60 = 284;
+    break;
+   }
+   if (i63 >>> 0 < 32) {
+    i66 = i62;
+    while (1) {
+     if ((i65 | 0) == 0) {
+      i65 = 0;
+      i62 = i66;
+      break L17;
+     }
+     i65 = i65 + -1 | 0;
+     i62 = i66 + 1 | 0;
+     i64 = (HEAPU8[i66] << i63) + i64 | 0;
+     i63 = i63 + 8 | 0;
+     if (i63 >>> 0 < 32) {
+      i66 = i62;
+     } else {
+      break;
+     }
+    }
+   }
+   if ((i64 | 0) == (HEAP32[i14 >> 2] | 0)) {
+    i63 = 0;
+    i64 = 0;
+    i60 = 284;
+    break;
+   }
+   HEAP32[i35 >> 2] = 11928;
+   HEAP32[i4 >> 2] = 29;
+   i66 = i26;
+  }
+  do {
+   if ((i60 | 0) == 49) {
+    i60 = HEAP32[i38 >> 2] | 0;
+    if ((i60 | 0) != 0) {
+     HEAP32[i60 + 4 >> 2] = i64;
+    }
+    if ((HEAP32[i11 >> 2] & 512 | 0) != 0) {
+     HEAP8[i25] = i64;
+     HEAP8[i39] = i64 >>> 8;
+     HEAP8[i44] = i64 >>> 16;
+     HEAP8[i45] = i64 >>> 24;
+     HEAP32[i10 >> 2] = _crc32(HEAP32[i10 >> 2] | 0, i25, 4) | 0;
+    }
+    HEAP32[i4 >> 2] = 3;
+    i63 = 0;
+    i64 = 0;
+    i66 = i62;
+    i60 = 55;
+   } else if ((i60 | 0) == 124) {
+    if (i47) {
+     i60 = 285;
+     break L17;
+    } else {
+     i60 = 125;
+    }
+   } else if ((i60 | 0) == 144) {
+    i60 = 0;
+    i66 = HEAP32[i42 >> 2] | 0;
+    if ((i66 | 0) == 0) {
+     HEAP32[i4 >> 2] = 11;
+     i66 = i26;
+     break;
+    }
+    i66 = i66 >>> 0 > i65 >>> 0 ? i65 : i66;
+    i67 = i66 >>> 0 > i26 >>> 0 ? i26 : i66;
+    if ((i67 | 0) == 0) {
+     i60 = 285;
+     break L17;
+    }
+    _memcpy(i19 | 0, i62 | 0, i67 | 0) | 0;
+    HEAP32[i42 >> 2] = (HEAP32[i42 >> 2] | 0) - i67;
+    i65 = i65 - i67 | 0;
+    i66 = i26 - i67 | 0;
+    i62 = i62 + i67 | 0;
+    i19 = i19 + i67 | 0;
+   } else if ((i60 | 0) == 158) {
+    i60 = 0;
+    if (i66 >>> 0 < 19) {
+     while (1) {
+      i61 = i66 + 1 | 0;
+      HEAP16[i4 + (HEAPU16[11384 + (i66 << 1) >> 1] << 1) + 112 >> 1] = 0;
+      if ((i61 | 0) == 19) {
+       break;
+      } else {
+       i66 = i61;
+      }
+     }
+     HEAP32[i36 >> 2] = 19;
+    }
+    HEAP32[i53 >> 2] = i52;
+    HEAP32[i48 >> 2] = i52;
+    HEAP32[i49 >> 2] = 7;
+    i61 = _inflate_table(0, i27, 19, i53, i49, i55) | 0;
+    if ((i61 | 0) == 0) {
+     HEAP32[i36 >> 2] = 0;
+     HEAP32[i4 >> 2] = 18;
+     i63 = 0;
+     i69 = i65;
+     i61 = 0;
+     i60 = 164;
+     break;
+    } else {
+     HEAP32[i35 >> 2] = 11656;
+     HEAP32[i4 >> 2] = 29;
+     i63 = i67;
+     i66 = i26;
+     break;
+    }
+   }
+  } while (0);
+  L163 : do {
+   if ((i60 | 0) == 55) {
+    while (1) {
+     i60 = 0;
+     if ((i65 | 0) == 0) {
+      i65 = 0;
+      i62 = i66;
+      break L17;
+     }
+     i65 = i65 + -1 | 0;
+     i62 = i66 + 1 | 0;
+     i64 = (HEAPU8[i66] << i63) + i64 | 0;
+     i63 = i63 + 8 | 0;
+     if (i63 >>> 0 < 16) {
+      i66 = i62;
+      i60 = 55;
+     } else {
+      i60 = 57;
+      break;
+     }
+    }
+   } else if ((i60 | 0) == 125) {
+    i60 = 0;
+    if ((HEAP32[i7 >> 2] | 0) != 0) {
+     i66 = i63 & 7;
+     HEAP32[i4 >> 2] = 26;
+     i63 = i63 - i66 | 0;
+     i64 = i64 >>> i66;
+     i66 = i26;
+     break;
+    }
+    if (i63 >>> 0 < 3) {
+     while (1) {
+      if ((i65 | 0) == 0) {
+       i65 = 0;
+       break L17;
+      }
+      i65 = i65 + -1 | 0;
+      i66 = i62 + 1 | 0;
+      i64 = (HEAPU8[i62] << i63) + i64 | 0;
+      i63 = i63 + 8 | 0;
+      if (i63 >>> 0 < 3) {
+       i62 = i66;
+      } else {
+       i62 = i66;
+       break;
+      }
+     }
+    }
+    HEAP32[i7 >> 2] = i64 & 1;
+    i66 = i64 >>> 1 & 3;
+    if ((i66 | 0) == 0) {
+     HEAP32[i4 >> 2] = 13;
+    } else if ((i66 | 0) == 1) {
+     HEAP32[i48 >> 2] = 11952;
+     HEAP32[i49 >> 2] = 9;
+     HEAP32[i50 >> 2] = 14e3;
+     HEAP32[i51 >> 2] = 5;
+     HEAP32[i4 >> 2] = 19;
+     if (i43) {
+      i60 = 133;
+      break L17;
+     }
+    } else if ((i66 | 0) == 2) {
+     HEAP32[i4 >> 2] = 16;
+    } else if ((i66 | 0) == 3) {
+     HEAP32[i35 >> 2] = 11560;
+     HEAP32[i4 >> 2] = 29;
+    }
+    i63 = i63 + -3 | 0;
+    i64 = i64 >>> 3;
+    i66 = i26;
+   } else if ((i60 | 0) == 164) {
+    i60 = 0;
+    i65 = HEAP32[i32 >> 2] | 0;
+    i66 = HEAP32[i33 >> 2] | 0;
+    do {
+     if (i63 >>> 0 < (i66 + i65 | 0) >>> 0) {
+      i71 = i67;
+      L181 : while (1) {
+       i70 = (1 << HEAP32[i49 >> 2]) + -1 | 0;
+       i72 = i70 & i64;
+       i68 = HEAP32[i48 >> 2] | 0;
+       i67 = HEAPU8[i68 + (i72 << 2) + 1 | 0] | 0;
+       if (i67 >>> 0 > i71 >>> 0) {
+        i67 = i71;
+        while (1) {
+         if ((i69 | 0) == 0) {
+          i63 = i67;
+          i65 = 0;
+          break L17;
+         }
+         i69 = i69 + -1 | 0;
+         i71 = i62 + 1 | 0;
+         i64 = (HEAPU8[i62] << i67) + i64 | 0;
+         i62 = i67 + 8 | 0;
+         i72 = i70 & i64;
+         i67 = HEAPU8[i68 + (i72 << 2) + 1 | 0] | 0;
+         if (i67 >>> 0 > i62 >>> 0) {
+          i67 = i62;
+          i62 = i71;
+         } else {
+          i70 = i62;
+          i62 = i71;
+          break;
+         }
+        }
+       } else {
+        i70 = i71;
+       }
+       i68 = HEAP16[i68 + (i72 << 2) + 2 >> 1] | 0;
+       L188 : do {
+        if ((i68 & 65535) < 16) {
+         if (i70 >>> 0 < i67 >>> 0) {
+          while (1) {
+           if ((i69 | 0) == 0) {
+            i63 = i70;
+            i65 = 0;
+            break L17;
+           }
+           i69 = i69 + -1 | 0;
+           i65 = i62 + 1 | 0;
+           i64 = (HEAPU8[i62] << i70) + i64 | 0;
+           i70 = i70 + 8 | 0;
+           if (i70 >>> 0 < i67 >>> 0) {
+            i62 = i65;
+           } else {
+            i62 = i65;
+            break;
+           }
+          }
+         }
+         HEAP32[i36 >> 2] = i63 + 1;
+         HEAP16[i4 + (i63 << 1) + 112 >> 1] = i68;
+         i71 = i70 - i67 | 0;
+         i64 = i64 >>> i67;
+        } else {
+         if (i68 << 16 >> 16 == 16) {
+          i68 = i67 + 2 | 0;
+          if (i70 >>> 0 < i68 >>> 0) {
+           i71 = i62;
+           while (1) {
+            if ((i69 | 0) == 0) {
+             i63 = i70;
+             i65 = 0;
+             i62 = i71;
+             break L17;
+            }
+            i69 = i69 + -1 | 0;
+            i62 = i71 + 1 | 0;
+            i64 = (HEAPU8[i71] << i70) + i64 | 0;
+            i70 = i70 + 8 | 0;
+            if (i70 >>> 0 < i68 >>> 0) {
+             i71 = i62;
+            } else {
+             break;
+            }
+           }
+          }
+          i64 = i64 >>> i67;
+          i67 = i70 - i67 | 0;
+          if ((i63 | 0) == 0) {
+           i60 = 181;
+           break L181;
+          }
+          i67 = i67 + -2 | 0;
+          i68 = (i64 & 3) + 3 | 0;
+          i64 = i64 >>> 2;
+          i70 = HEAP16[i4 + (i63 + -1 << 1) + 112 >> 1] | 0;
+         } else if (i68 << 16 >> 16 == 17) {
+          i68 = i67 + 3 | 0;
+          if (i70 >>> 0 < i68 >>> 0) {
+           i71 = i62;
+           while (1) {
+            if ((i69 | 0) == 0) {
+             i63 = i70;
+             i65 = 0;
+             i62 = i71;
+             break L17;
+            }
+            i69 = i69 + -1 | 0;
+            i62 = i71 + 1 | 0;
+            i64 = (HEAPU8[i71] << i70) + i64 | 0;
+            i70 = i70 + 8 | 0;
+            if (i70 >>> 0 < i68 >>> 0) {
+             i71 = i62;
+            } else {
+             break;
+            }
+           }
+          }
+          i64 = i64 >>> i67;
+          i67 = -3 - i67 + i70 | 0;
+          i68 = (i64 & 7) + 3 | 0;
+          i64 = i64 >>> 3;
+          i70 = 0;
+         } else {
+          i68 = i67 + 7 | 0;
+          if (i70 >>> 0 < i68 >>> 0) {
+           i71 = i62;
+           while (1) {
+            if ((i69 | 0) == 0) {
+             i63 = i70;
+             i65 = 0;
+             i62 = i71;
+             break L17;
+            }
+            i69 = i69 + -1 | 0;
+            i62 = i71 + 1 | 0;
+            i64 = (HEAPU8[i71] << i70) + i64 | 0;
+            i70 = i70 + 8 | 0;
+            if (i70 >>> 0 < i68 >>> 0) {
+             i71 = i62;
+            } else {
+             break;
+            }
+           }
+          }
+          i64 = i64 >>> i67;
+          i67 = -7 - i67 + i70 | 0;
+          i68 = (i64 & 127) + 11 | 0;
+          i64 = i64 >>> 7;
+          i70 = 0;
+         }
+         if ((i63 + i68 | 0) >>> 0 > (i66 + i65 | 0) >>> 0) {
+          i60 = 190;
+          break L181;
+         }
+         while (1) {
+          i68 = i68 + -1 | 0;
+          HEAP32[i36 >> 2] = i63 + 1;
+          HEAP16[i4 + (i63 << 1) + 112 >> 1] = i70;
+          if ((i68 | 0) == 0) {
+           i71 = i67;
+           break L188;
+          }
+          i63 = HEAP32[i36 >> 2] | 0;
+         }
+        }
+       } while (0);
+       i63 = HEAP32[i36 >> 2] | 0;
+       i65 = HEAP32[i32 >> 2] | 0;
+       i66 = HEAP32[i33 >> 2] | 0;
+       if (!(i63 >>> 0 < (i66 + i65 | 0) >>> 0)) {
+        i60 = 193;
+        break;
+       }
+      }
+      if ((i60 | 0) == 181) {
+       i60 = 0;
+       HEAP32[i35 >> 2] = 11688;
+       HEAP32[i4 >> 2] = 29;
+       i63 = i67;
+       i65 = i69;
+       i66 = i26;
+       break L163;
+      } else if ((i60 | 0) == 190) {
+       i60 = 0;
+       HEAP32[i35 >> 2] = 11688;
+       HEAP32[i4 >> 2] = 29;
+       i63 = i67;
+       i65 = i69;
+       i66 = i26;
+       break L163;
+      } else if ((i60 | 0) == 193) {
+       i60 = 0;
+       if ((HEAP32[i4 >> 2] | 0) == 29) {
+        i63 = i71;
+        i65 = i69;
+        i66 = i26;
+        break L163;
+       } else {
+        i63 = i71;
+        break;
+       }
+      }
+     } else {
+      i63 = i67;
+     }
+    } while (0);
+    if ((HEAP16[i56 >> 1] | 0) == 0) {
+     HEAP32[i35 >> 2] = 11720;
+     HEAP32[i4 >> 2] = 29;
+     i65 = i69;
+     i66 = i26;
+     break;
+    }
+    HEAP32[i53 >> 2] = i52;
+    HEAP32[i48 >> 2] = i52;
+    HEAP32[i49 >> 2] = 9;
+    i61 = _inflate_table(1, i27, i65, i53, i49, i55) | 0;
+    if ((i61 | 0) != 0) {
+     HEAP32[i35 >> 2] = 11760;
+     HEAP32[i4 >> 2] = 29;
+     i65 = i69;
+     i66 = i26;
+     break;
+    }
+    HEAP32[i50 >> 2] = HEAP32[i53 >> 2];
+    HEAP32[i51 >> 2] = 6;
+    i61 = _inflate_table(2, i4 + (HEAP32[i32 >> 2] << 1) + 112 | 0, HEAP32[i33 >> 2] | 0, i53, i51, i55) | 0;
+    if ((i61 | 0) == 0) {
+     HEAP32[i4 >> 2] = 19;
+     if (i43) {
+      i65 = i69;
+      i61 = 0;
+      i60 = 285;
+      break L17;
+     } else {
+      i65 = i69;
+      i61 = 0;
+      i60 = 201;
+      break;
+     }
+    } else {
+     HEAP32[i35 >> 2] = 11792;
+     HEAP32[i4 >> 2] = 29;
+     i65 = i69;
+     i66 = i26;
+     break;
+    }
+   }
+  } while (0);
+  if ((i60 | 0) == 57) {
+   i60 = HEAP32[i38 >> 2] | 0;
+   if ((i60 | 0) != 0) {
+    HEAP32[i60 + 8 >> 2] = i64 & 255;
+    HEAP32[i60 + 12 >> 2] = i64 >>> 8;
+   }
+   if ((HEAP32[i11 >> 2] & 512 | 0) != 0) {
+    HEAP8[i25] = i64;
+    HEAP8[i39] = i64 >>> 8;
+    HEAP32[i10 >> 2] = _crc32(HEAP32[i10 >> 2] | 0, i25, 2) | 0;
+   }
+   HEAP32[i4 >> 2] = 4;
+   i63 = 0;
+   i64 = 0;
+   i60 = 62;
+  } else if ((i60 | 0) == 201) {
+   HEAP32[i4 >> 2] = 20;
+   i60 = 202;
+  }
+  do {
+   if ((i60 | 0) == 62) {
+    i60 = 0;
+    i66 = HEAP32[i11 >> 2] | 0;
+    if ((i66 & 1024 | 0) == 0) {
+     i60 = HEAP32[i38 >> 2] | 0;
+     if ((i60 | 0) != 0) {
+      HEAP32[i60 + 16 >> 2] = 0;
+     }
+    } else {
+     if (i63 >>> 0 < 16) {
+      while (1) {
+       if ((i65 | 0) == 0) {
+        i65 = 0;
+        break L17;
+       }
+       i65 = i65 + -1 | 0;
+       i67 = i62 + 1 | 0;
+       i64 = (HEAPU8[i62] << i63) + i64 | 0;
+       i63 = i63 + 8 | 0;
+       if (i63 >>> 0 < 16) {
+        i62 = i67;
+       } else {
+        i62 = i67;
+        break;
+       }
+      }
+     }
+     HEAP32[i42 >> 2] = i64;
+     i60 = HEAP32[i38 >> 2] | 0;
+     if ((i60 | 0) != 0) {
+      HEAP32[i60 + 20 >> 2] = i64;
+      i66 = HEAP32[i11 >> 2] | 0;
+     }
+     if ((i66 & 512 | 0) == 0) {
+      i63 = 0;
+      i64 = 0;
+     } else {
+      HEAP8[i25] = i64;
+      HEAP8[i39] = i64 >>> 8;
+      HEAP32[i10 >> 2] = _crc32(HEAP32[i10 >> 2] | 0, i25, 2) | 0;
+      i63 = 0;
+      i64 = 0;
+     }
+    }
+    HEAP32[i4 >> 2] = 5;
+    i60 = 73;
+   } else if ((i60 | 0) == 202) {
+    i60 = 0;
+    if (i65 >>> 0 > 5 & i26 >>> 0 > 257) {
+     HEAP32[i8 >> 2] = i19;
+     HEAP32[i15 >> 2] = i26;
+     HEAP32[i2 >> 2] = i62;
+     HEAP32[i16 >> 2] = i65;
+     HEAP32[i17 >> 2] = i64;
+     HEAP32[i6 >> 2] = i63;
+     _inflate_fast(i2, i59);
+     i19 = HEAP32[i8 >> 2] | 0;
+     i66 = HEAP32[i15 >> 2] | 0;
+     i62 = HEAP32[i2 >> 2] | 0;
+     i65 = HEAP32[i16 >> 2] | 0;
+     i64 = HEAP32[i17 >> 2] | 0;
+     i63 = HEAP32[i6 >> 2] | 0;
+     if ((HEAP32[i4 >> 2] | 0) != 11) {
+      break;
+     }
+     HEAP32[i57 >> 2] = -1;
+     break;
+    }
+    HEAP32[i57 >> 2] = 0;
+    i69 = (1 << HEAP32[i49 >> 2]) + -1 | 0;
+    i71 = i69 & i64;
+    i66 = HEAP32[i48 >> 2] | 0;
+    i68 = HEAP8[i66 + (i71 << 2) + 1 | 0] | 0;
+    i67 = i68 & 255;
+    if (i67 >>> 0 > i63 >>> 0) {
+     while (1) {
+      if ((i65 | 0) == 0) {
+       i65 = 0;
+       break L17;
+      }
+      i65 = i65 + -1 | 0;
+      i70 = i62 + 1 | 0;
+      i64 = (HEAPU8[i62] << i63) + i64 | 0;
+      i63 = i63 + 8 | 0;
+      i71 = i69 & i64;
+      i68 = HEAP8[i66 + (i71 << 2) + 1 | 0] | 0;
+      i67 = i68 & 255;
+      if (i67 >>> 0 > i63 >>> 0) {
+       i62 = i70;
+      } else {
+       i62 = i70;
+       break;
+      }
+     }
+    }
+    i69 = HEAP8[i66 + (i71 << 2) | 0] | 0;
+    i70 = HEAP16[i66 + (i71 << 2) + 2 >> 1] | 0;
+    i71 = i69 & 255;
+    if (!(i69 << 24 >> 24 == 0)) {
+     if ((i71 & 240 | 0) == 0) {
+      i69 = i70 & 65535;
+      i70 = (1 << i67 + i71) + -1 | 0;
+      i71 = ((i64 & i70) >>> i67) + i69 | 0;
+      i68 = HEAP8[i66 + (i71 << 2) + 1 | 0] | 0;
+      if (((i68 & 255) + i67 | 0) >>> 0 > i63 >>> 0) {
+       while (1) {
+        if ((i65 | 0) == 0) {
+         i65 = 0;
+         break L17;
+        }
+        i65 = i65 + -1 | 0;
+        i71 = i62 + 1 | 0;
+        i64 = (HEAPU8[i62] << i63) + i64 | 0;
+        i63 = i63 + 8 | 0;
+        i62 = ((i64 & i70) >>> i67) + i69 | 0;
+        i68 = HEAP8[i66 + (i62 << 2) + 1 | 0] | 0;
+        if (((i68 & 255) + i67 | 0) >>> 0 > i63 >>> 0) {
+         i62 = i71;
+        } else {
+         i69 = i62;
+         i62 = i71;
+         break;
+        }
+       }
+      } else {
+       i69 = i71;
+      }
+      i70 = HEAP16[i66 + (i69 << 2) + 2 >> 1] | 0;
+      i69 = HEAP8[i66 + (i69 << 2) | 0] | 0;
+      HEAP32[i57 >> 2] = i67;
+      i66 = i67;
+      i63 = i63 - i67 | 0;
+      i64 = i64 >>> i67;
+     } else {
+      i66 = 0;
+     }
+    } else {
+     i66 = 0;
+     i69 = 0;
+    }
+    i72 = i68 & 255;
+    i64 = i64 >>> i72;
+    i63 = i63 - i72 | 0;
+    HEAP32[i57 >> 2] = i66 + i72;
+    HEAP32[i42 >> 2] = i70 & 65535;
+    i66 = i69 & 255;
+    if (i69 << 24 >> 24 == 0) {
+     HEAP32[i4 >> 2] = 25;
+     i66 = i26;
+     break;
+    }
+    if ((i66 & 32 | 0) != 0) {
+     HEAP32[i57 >> 2] = -1;
+     HEAP32[i4 >> 2] = 11;
+     i66 = i26;
+     break;
+    }
+    if ((i66 & 64 | 0) == 0) {
+     i66 = i66 & 15;
+     HEAP32[i37 >> 2] = i66;
+     HEAP32[i4 >> 2] = 21;
+     i60 = 221;
+     break;
+    } else {
+     HEAP32[i35 >> 2] = 11816;
+     HEAP32[i4 >> 2] = 29;
+     i66 = i26;
+     break;
+    }
+   }
+  } while (0);
+  if ((i60 | 0) == 73) {
+   i68 = HEAP32[i11 >> 2] | 0;
+   if ((i68 & 1024 | 0) != 0) {
+    i67 = HEAP32[i42 >> 2] | 0;
+    i60 = i67 >>> 0 > i65 >>> 0 ? i65 : i67;
+    if ((i60 | 0) != 0) {
+     i66 = HEAP32[i38 >> 2] | 0;
+     if ((i66 | 0) != 0 ? (i20 = HEAP32[i66 + 16 >> 2] | 0, (i20 | 0) != 0) : 0) {
+      i67 = (HEAP32[i66 + 20 >> 2] | 0) - i67 | 0;
+      i66 = HEAP32[i66 + 24 >> 2] | 0;
+      _memcpy(i20 + i67 | 0, i62 | 0, ((i67 + i60 | 0) >>> 0 > i66 >>> 0 ? i66 - i67 | 0 : i60) | 0) | 0;
+      i68 = HEAP32[i11 >> 2] | 0;
+     }
+     if ((i68 & 512 | 0) != 0) {
+      HEAP32[i10 >> 2] = _crc32(HEAP32[i10 >> 2] | 0, i62, i60) | 0;
+     }
+     i67 = (HEAP32[i42 >> 2] | 0) - i60 | 0;
+     HEAP32[i42 >> 2] = i67;
+     i65 = i65 - i60 | 0;
+     i62 = i62 + i60 | 0;
+    }
+    if ((i67 | 0) != 0) {
+     i60 = 285;
+     break;
+    }
+   }
+   HEAP32[i42 >> 2] = 0;
+   HEAP32[i4 >> 2] = 6;
+   i60 = 83;
+  } else if ((i60 | 0) == 221) {
+   i60 = 0;
+   if ((i66 | 0) == 0) {
+    i60 = HEAP32[i42 >> 2] | 0;
+   } else {
+    if (i63 >>> 0 < i66 >>> 0) {
+     while (1) {
+      if ((i65 | 0) == 0) {
+       i65 = 0;
+       break L17;
+      }
+      i65 = i65 + -1 | 0;
+      i67 = i62 + 1 | 0;
+      i64 = (HEAPU8[i62] << i63) + i64 | 0;
+      i63 = i63 + 8 | 0;
+      if (i63 >>> 0 < i66 >>> 0) {
+       i62 = i67;
+      } else {
+       i62 = i67;
+       break;
+      }
+     }
+    }
+    i60 = (HEAP32[i42 >> 2] | 0) + ((1 << i66) + -1 & i64) | 0;
+    HEAP32[i42 >> 2] = i60;
+    HEAP32[i57 >> 2] = (HEAP32[i57 >> 2] | 0) + i66;
+    i63 = i63 - i66 | 0;
+    i64 = i64 >>> i66;
+   }
+   HEAP32[i58 >> 2] = i60;
+   HEAP32[i4 >> 2] = 22;
+   i60 = 228;
+  }
+  do {
+   if ((i60 | 0) == 83) {
+    if ((HEAP32[i11 >> 2] & 2048 | 0) == 0) {
+     i60 = HEAP32[i38 >> 2] | 0;
+     if ((i60 | 0) != 0) {
+      HEAP32[i60 + 28 >> 2] = 0;
+     }
+    } else {
+     if ((i65 | 0) == 0) {
+      i65 = 0;
+      i60 = 285;
+      break L17;
+     } else {
+      i66 = 0;
+     }
+     while (1) {
+      i60 = i66 + 1 | 0;
+      i67 = HEAP8[i62 + i66 | 0] | 0;
+      i66 = HEAP32[i38 >> 2] | 0;
+      if (((i66 | 0) != 0 ? (i23 = HEAP32[i66 + 28 >> 2] | 0, (i23 | 0) != 0) : 0) ? (i21 = HEAP32[i42 >> 2] | 0, i21 >>> 0 < (HEAP32[i66 + 32 >> 2] | 0) >>> 0) : 0) {
+       HEAP32[i42 >> 2] = i21 + 1;
+       HEAP8[i23 + i21 | 0] = i67;
+      }
+      i66 = i67 << 24 >> 24 != 0;
+      if (i66 & i60 >>> 0 < i65 >>> 0) {
+       i66 = i60;
+      } else {
+       break;
+      }
+     }
+     if ((HEAP32[i11 >> 2] & 512 | 0) != 0) {
+      HEAP32[i10 >> 2] = _crc32(HEAP32[i10 >> 2] | 0, i62, i60) | 0;
+     }
+     i65 = i65 - i60 | 0;
+     i62 = i62 + i60 | 0;
+     if (i66) {
+      i60 = 285;
+      break L17;
+     }
+    }
+    HEAP32[i42 >> 2] = 0;
+    HEAP32[i4 >> 2] = 7;
+    i60 = 96;
+   } else if ((i60 | 0) == 228) {
+    i60 = 0;
+    i69 = (1 << HEAP32[i51 >> 2]) + -1 | 0;
+    i71 = i69 & i64;
+    i66 = HEAP32[i50 >> 2] | 0;
+    i68 = HEAP8[i66 + (i71 << 2) + 1 | 0] | 0;
+    i67 = i68 & 255;
+    if (i67 >>> 0 > i63 >>> 0) {
+     while (1) {
+      if ((i65 | 0) == 0) {
+       i65 = 0;
+       break L17;
+      }
+      i65 = i65 + -1 | 0;
+      i70 = i62 + 1 | 0;
+      i64 = (HEAPU8[i62] << i63) + i64 | 0;
+      i63 = i63 + 8 | 0;
+      i71 = i69 & i64;
+      i68 = HEAP8[i66 + (i71 << 2) + 1 | 0] | 0;
+      i67 = i68 & 255;
+      if (i67 >>> 0 > i63 >>> 0) {
+       i62 = i70;
+      } else {
+       i62 = i70;
+       break;
+      }
+     }
+    }
+    i69 = HEAP8[i66 + (i71 << 2) | 0] | 0;
+    i70 = HEAP16[i66 + (i71 << 2) + 2 >> 1] | 0;
+    i71 = i69 & 255;
+    if ((i71 & 240 | 0) == 0) {
+     i69 = i70 & 65535;
+     i70 = (1 << i67 + i71) + -1 | 0;
+     i71 = ((i64 & i70) >>> i67) + i69 | 0;
+     i68 = HEAP8[i66 + (i71 << 2) + 1 | 0] | 0;
+     if (((i68 & 255) + i67 | 0) >>> 0 > i63 >>> 0) {
+      while (1) {
+       if ((i65 | 0) == 0) {
+        i65 = 0;
+        break L17;
+       }
+       i65 = i65 + -1 | 0;
+       i71 = i62 + 1 | 0;
+       i64 = (HEAPU8[i62] << i63) + i64 | 0;
+       i63 = i63 + 8 | 0;
+       i62 = ((i64 & i70) >>> i67) + i69 | 0;
+       i68 = HEAP8[i66 + (i62 << 2) + 1 | 0] | 0;
+       if (((i68 & 255) + i67 | 0) >>> 0 > i63 >>> 0) {
+        i62 = i71;
+       } else {
+        i69 = i62;
+        i62 = i71;
+        break;
+       }
+      }
+     } else {
+      i69 = i71;
+     }
+     i70 = HEAP16[i66 + (i69 << 2) + 2 >> 1] | 0;
+     i69 = HEAP8[i66 + (i69 << 2) | 0] | 0;
+     i66 = (HEAP32[i57 >> 2] | 0) + i67 | 0;
+     HEAP32[i57 >> 2] = i66;
+     i63 = i63 - i67 | 0;
+     i64 = i64 >>> i67;
+    } else {
+     i66 = HEAP32[i57 >> 2] | 0;
+    }
+    i72 = i68 & 255;
+    i64 = i64 >>> i72;
+    i63 = i63 - i72 | 0;
+    HEAP32[i57 >> 2] = i66 + i72;
+    i66 = i69 & 255;
+    if ((i66 & 64 | 0) == 0) {
+     HEAP32[i54 >> 2] = i70 & 65535;
+     i66 = i66 & 15;
+     HEAP32[i37 >> 2] = i66;
+     HEAP32[i4 >> 2] = 23;
+     i60 = 240;
+     break;
+    } else {
+     HEAP32[i35 >> 2] = 11848;
+     HEAP32[i4 >> 2] = 29;
+     i66 = i26;
+     break;
+    }
+   }
+  } while (0);
+  if ((i60 | 0) == 96) {
+   if ((HEAP32[i11 >> 2] & 4096 | 0) == 0) {
+    i60 = HEAP32[i38 >> 2] | 0;
+    if ((i60 | 0) != 0) {
+     HEAP32[i60 + 36 >> 2] = 0;
+    }
+   } else {
+    if ((i65 | 0) == 0) {
+     i65 = 0;
+     i60 = 285;
+     break;
+    } else {
+     i66 = 0;
+    }
+    while (1) {
+     i60 = i66 + 1 | 0;
+     i66 = HEAP8[i62 + i66 | 0] | 0;
+     i67 = HEAP32[i38 >> 2] | 0;
+     if (((i67 | 0) != 0 ? (i24 = HEAP32[i67 + 36 >> 2] | 0, (i24 | 0) != 0) : 0) ? (i22 = HEAP32[i42 >> 2] | 0, i22 >>> 0 < (HEAP32[i67 + 40 >> 2] | 0) >>> 0) : 0) {
+      HEAP32[i42 >> 2] = i22 + 1;
+      HEAP8[i24 + i22 | 0] = i66;
+     }
+     i66 = i66 << 24 >> 24 != 0;
+     if (i66 & i60 >>> 0 < i65 >>> 0) {
+      i66 = i60;
+     } else {
+      break;
+     }
+    }
+    if ((HEAP32[i11 >> 2] & 512 | 0) != 0) {
+     HEAP32[i10 >> 2] = _crc32(HEAP32[i10 >> 2] | 0, i62, i60) | 0;
+    }
+    i65 = i65 - i60 | 0;
+    i62 = i62 + i60 | 0;
+    if (i66) {
+     i60 = 285;
+     break;
+    }
+   }
+   HEAP32[i4 >> 2] = 8;
+   i60 = 109;
+  } else if ((i60 | 0) == 240) {
+   i60 = 0;
+   if ((i66 | 0) != 0) {
+    if (i63 >>> 0 < i66 >>> 0) {
+     i67 = i62;
+     while (1) {
+      if ((i65 | 0) == 0) {
+       i65 = 0;
+       i62 = i67;
+       break L17;
+      }
+      i65 = i65 + -1 | 0;
+      i62 = i67 + 1 | 0;
+      i64 = (HEAPU8[i67] << i63) + i64 | 0;
+      i63 = i63 + 8 | 0;
+      if (i63 >>> 0 < i66 >>> 0) {
+       i67 = i62;
+      } else {
+       break;
+      }
+     }
+    }
+    HEAP32[i54 >> 2] = (HEAP32[i54 >> 2] | 0) + ((1 << i66) + -1 & i64);
+    HEAP32[i57 >> 2] = (HEAP32[i57 >> 2] | 0) + i66;
+    i63 = i63 - i66 | 0;
+    i64 = i64 >>> i66;
+   }
+   HEAP32[i4 >> 2] = 24;
+   i60 = 246;
+  }
+  do {
+   if ((i60 | 0) == 109) {
+    i60 = 0;
+    i66 = HEAP32[i11 >> 2] | 0;
+    if ((i66 & 512 | 0) != 0) {
+     if (i63 >>> 0 < 16) {
+      i67 = i62;
+      while (1) {
+       if ((i65 | 0) == 0) {
+        i65 = 0;
+        i62 = i67;
+        break L17;
+       }
+       i65 = i65 + -1 | 0;
+       i62 = i67 + 1 | 0;
+       i64 = (HEAPU8[i67] << i63) + i64 | 0;
+       i63 = i63 + 8 | 0;
+       if (i63 >>> 0 < 16) {
+        i67 = i62;
+       } else {
+        break;
+       }
+      }
+     }
+     if ((i64 | 0) == (HEAP32[i10 >> 2] & 65535 | 0)) {
+      i63 = 0;
+      i64 = 0;
+     } else {
+      HEAP32[i35 >> 2] = 11536;
+      HEAP32[i4 >> 2] = 29;
+      i66 = i26;
+      break;
+     }
+    }
+    i67 = HEAP32[i38 >> 2] | 0;
+    if ((i67 | 0) != 0) {
+     HEAP32[i67 + 44 >> 2] = i66 >>> 9 & 1;
+     HEAP32[i67 + 48 >> 2] = 1;
+    }
+    i66 = _crc32(0, 0, 0) | 0;
+    HEAP32[i10 >> 2] = i66;
+    HEAP32[i9 >> 2] = i66;
+    HEAP32[i4 >> 2] = 11;
+    i66 = i26;
+   } else if ((i60 | 0) == 246) {
+    i60 = 0;
+    if ((i26 | 0) == 0) {
+     i26 = 0;
+     i60 = 285;
+     break L17;
+    }
+    i67 = i59 - i26 | 0;
+    i66 = HEAP32[i54 >> 2] | 0;
+    if (i66 >>> 0 > i67 >>> 0) {
+     i67 = i66 - i67 | 0;
+     if (i67 >>> 0 > (HEAP32[i28 >> 2] | 0) >>> 0 ? (HEAP32[i29 >> 2] | 0) != 0 : 0) {
+      HEAP32[i35 >> 2] = 11872;
+      HEAP32[i4 >> 2] = 29;
+      i66 = i26;
+      break;
+     }
+     i68 = HEAP32[i30 >> 2] | 0;
+     if (i67 >>> 0 > i68 >>> 0) {
+      i68 = i67 - i68 | 0;
+      i66 = i68;
+      i68 = (HEAP32[i31 >> 2] | 0) + ((HEAP32[i18 >> 2] | 0) - i68) | 0;
+     } else {
+      i66 = i67;
+      i68 = (HEAP32[i31 >> 2] | 0) + (i68 - i67) | 0;
+     }
+     i69 = HEAP32[i42 >> 2] | 0;
+     i67 = i69;
+     i69 = i66 >>> 0 > i69 >>> 0 ? i69 : i66;
+    } else {
+     i69 = HEAP32[i42 >> 2] | 0;
+     i67 = i69;
+     i68 = i19 + (0 - i66) | 0;
+    }
+    i66 = i69 >>> 0 > i26 >>> 0 ? i26 : i69;
+    HEAP32[i42 >> 2] = i67 - i66;
+    i67 = ~i26;
+    i69 = ~i69;
+    i67 = i67 >>> 0 > i69 >>> 0 ? i67 : i69;
+    i69 = i66;
+    i70 = i19;
+    while (1) {
+     HEAP8[i70] = HEAP8[i68] | 0;
+     i69 = i69 + -1 | 0;
+     if ((i69 | 0) == 0) {
+      break;
+     } else {
+      i68 = i68 + 1 | 0;
+      i70 = i70 + 1 | 0;
+     }
+    }
+    i66 = i26 - i66 | 0;
+    i19 = i19 + ~i67 | 0;
+    if ((HEAP32[i42 >> 2] | 0) == 0) {
+     HEAP32[i4 >> 2] = 20;
+    }
+   }
+  } while (0);
+  i68 = HEAP32[i4 >> 2] | 0;
+  i67 = i63;
+  i26 = i66;
+ }
+ if ((i60 | 0) == 122) {
+  HEAP32[i8 >> 2] = i19;
+  HEAP32[i15 >> 2] = i26;
+  HEAP32[i2 >> 2] = i62;
+  HEAP32[i16 >> 2] = i65;
+  HEAP32[i17 >> 2] = i64;
+  HEAP32[i6 >> 2] = i63;
+  i72 = 2;
+  STACKTOP = i1;
+  return i72 | 0;
+ } else if ((i60 | 0) == 133) {
+  i63 = i63 + -3 | 0;
+  i64 = i64 >>> 3;
+ } else if ((i60 | 0) == 284) {
+  HEAP32[i4 >> 2] = 28;
+  i61 = 1;
+ } else if ((i60 | 0) != 285) if ((i60 | 0) == 299) {
+  i72 = -4;
+  STACKTOP = i1;
+  return i72 | 0;
+ } else if ((i60 | 0) == 300) {
+  STACKTOP = i1;
+  return i2 | 0;
+ }
+ HEAP32[i8 >> 2] = i19;
+ HEAP32[i15 >> 2] = i26;
+ HEAP32[i2 >> 2] = i62;
+ HEAP32[i16 >> 2] = i65;
+ HEAP32[i17 >> 2] = i64;
+ HEAP32[i6 >> 2] = i63;
+ if ((HEAP32[i18 >> 2] | 0) == 0) {
+  if ((HEAP32[i4 >> 2] | 0) >>> 0 < 26 ? (i59 | 0) != (HEAP32[i15 >> 2] | 0) : 0) {
+   i60 = 289;
+  }
+ } else {
+  i60 = 289;
+ }
+ if ((i60 | 0) == 289 ? (_updatewindow(i2, i59) | 0) != 0 : 0) {
+  HEAP32[i4 >> 2] = 30;
+  i72 = -4;
+  STACKTOP = i1;
+  return i72 | 0;
+ }
+ i16 = HEAP32[i16 >> 2] | 0;
+ i72 = HEAP32[i15 >> 2] | 0;
+ i15 = i59 - i72 | 0;
+ i71 = i2 + 8 | 0;
+ HEAP32[i71 >> 2] = i5 - i16 + (HEAP32[i71 >> 2] | 0);
+ HEAP32[i13 >> 2] = (HEAP32[i13 >> 2] | 0) + i15;
+ HEAP32[i14 >> 2] = (HEAP32[i14 >> 2] | 0) + i15;
+ i13 = (i59 | 0) == (i72 | 0);
+ if (!((HEAP32[i12 >> 2] | 0) == 0 | i13)) {
+  i12 = HEAP32[i10 >> 2] | 0;
+  i8 = (HEAP32[i8 >> 2] | 0) + (0 - i15) | 0;
+  if ((HEAP32[i11 >> 2] | 0) == 0) {
+   i8 = _adler32(i12, i8, i15) | 0;
+  } else {
+   i8 = _crc32(i12, i8, i15) | 0;
+  }
+  HEAP32[i10 >> 2] = i8;
+  HEAP32[i9 >> 2] = i8;
+ }
+ i4 = HEAP32[i4 >> 2] | 0;
+ if ((i4 | 0) == 19) {
+  i8 = 256;
+ } else {
+  i8 = (i4 | 0) == 14 ? 256 : 0;
+ }
+ HEAP32[i2 + 44 >> 2] = ((HEAP32[i7 >> 2] | 0) != 0 ? 64 : 0) + (HEAP32[i6 >> 2] | 0) + ((i4 | 0) == 11 ? 128 : 0) + i8;
+ i72 = ((i5 | 0) == (i16 | 0) & i13 | (i3 | 0) == 4) & (i61 | 0) == 0 ? -5 : i61;
+ STACKTOP = i1;
+ return i72 | 0;
+}
+function _malloc(i12) {
+ i12 = i12 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0;
+ i1 = STACKTOP;
+ do {
+  if (i12 >>> 0 < 245) {
+   if (i12 >>> 0 < 11) {
+    i12 = 16;
+   } else {
+    i12 = i12 + 11 & -8;
+   }
+   i20 = i12 >>> 3;
+   i18 = HEAP32[3618] | 0;
+   i21 = i18 >>> i20;
+   if ((i21 & 3 | 0) != 0) {
+    i6 = (i21 & 1 ^ 1) + i20 | 0;
+    i5 = i6 << 1;
+    i3 = 14512 + (i5 << 2) | 0;
+    i5 = 14512 + (i5 + 2 << 2) | 0;
+    i7 = HEAP32[i5 >> 2] | 0;
+    i2 = i7 + 8 | 0;
+    i4 = HEAP32[i2 >> 2] | 0;
+    do {
+     if ((i3 | 0) != (i4 | 0)) {
+      if (i4 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i8 = i4 + 12 | 0;
+      if ((HEAP32[i8 >> 2] | 0) == (i7 | 0)) {
+       HEAP32[i8 >> 2] = i3;
+       HEAP32[i5 >> 2] = i4;
+       break;
+      } else {
+       _abort();
+      }
+     } else {
+      HEAP32[3618] = i18 & ~(1 << i6);
+     }
+    } while (0);
+    i32 = i6 << 3;
+    HEAP32[i7 + 4 >> 2] = i32 | 3;
+    i32 = i7 + (i32 | 4) | 0;
+    HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+    i32 = i2;
+    STACKTOP = i1;
+    return i32 | 0;
+   }
+   if (i12 >>> 0 > (HEAP32[14480 >> 2] | 0) >>> 0) {
+    if ((i21 | 0) != 0) {
+     i7 = 2 << i20;
+     i7 = i21 << i20 & (i7 | 0 - i7);
+     i7 = (i7 & 0 - i7) + -1 | 0;
+     i2 = i7 >>> 12 & 16;
+     i7 = i7 >>> i2;
+     i6 = i7 >>> 5 & 8;
+     i7 = i7 >>> i6;
+     i5 = i7 >>> 2 & 4;
+     i7 = i7 >>> i5;
+     i4 = i7 >>> 1 & 2;
+     i7 = i7 >>> i4;
+     i3 = i7 >>> 1 & 1;
+     i3 = (i6 | i2 | i5 | i4 | i3) + (i7 >>> i3) | 0;
+     i7 = i3 << 1;
+     i4 = 14512 + (i7 << 2) | 0;
+     i7 = 14512 + (i7 + 2 << 2) | 0;
+     i5 = HEAP32[i7 >> 2] | 0;
+     i2 = i5 + 8 | 0;
+     i6 = HEAP32[i2 >> 2] | 0;
+     do {
+      if ((i4 | 0) != (i6 | 0)) {
+       if (i6 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+        _abort();
+       }
+       i8 = i6 + 12 | 0;
+       if ((HEAP32[i8 >> 2] | 0) == (i5 | 0)) {
+        HEAP32[i8 >> 2] = i4;
+        HEAP32[i7 >> 2] = i6;
+        break;
+       } else {
+        _abort();
+       }
+      } else {
+       HEAP32[3618] = i18 & ~(1 << i3);
+      }
+     } while (0);
+     i6 = i3 << 3;
+     i4 = i6 - i12 | 0;
+     HEAP32[i5 + 4 >> 2] = i12 | 3;
+     i3 = i5 + i12 | 0;
+     HEAP32[i5 + (i12 | 4) >> 2] = i4 | 1;
+     HEAP32[i5 + i6 >> 2] = i4;
+     i6 = HEAP32[14480 >> 2] | 0;
+     if ((i6 | 0) != 0) {
+      i5 = HEAP32[14492 >> 2] | 0;
+      i8 = i6 >>> 3;
+      i9 = i8 << 1;
+      i6 = 14512 + (i9 << 2) | 0;
+      i7 = HEAP32[3618] | 0;
+      i8 = 1 << i8;
+      if ((i7 & i8 | 0) != 0) {
+       i7 = 14512 + (i9 + 2 << 2) | 0;
+       i8 = HEAP32[i7 >> 2] | 0;
+       if (i8 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        i28 = i7;
+        i27 = i8;
+       }
+      } else {
+       HEAP32[3618] = i7 | i8;
+       i28 = 14512 + (i9 + 2 << 2) | 0;
+       i27 = i6;
+      }
+      HEAP32[i28 >> 2] = i5;
+      HEAP32[i27 + 12 >> 2] = i5;
+      HEAP32[i5 + 8 >> 2] = i27;
+      HEAP32[i5 + 12 >> 2] = i6;
+     }
+     HEAP32[14480 >> 2] = i4;
+     HEAP32[14492 >> 2] = i3;
+     i32 = i2;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+    i18 = HEAP32[14476 >> 2] | 0;
+    if ((i18 | 0) != 0) {
+     i2 = (i18 & 0 - i18) + -1 | 0;
+     i31 = i2 >>> 12 & 16;
+     i2 = i2 >>> i31;
+     i30 = i2 >>> 5 & 8;
+     i2 = i2 >>> i30;
+     i32 = i2 >>> 2 & 4;
+     i2 = i2 >>> i32;
+     i6 = i2 >>> 1 & 2;
+     i2 = i2 >>> i6;
+     i3 = i2 >>> 1 & 1;
+     i3 = HEAP32[14776 + ((i30 | i31 | i32 | i6 | i3) + (i2 >>> i3) << 2) >> 2] | 0;
+     i2 = (HEAP32[i3 + 4 >> 2] & -8) - i12 | 0;
+     i6 = i3;
+     while (1) {
+      i5 = HEAP32[i6 + 16 >> 2] | 0;
+      if ((i5 | 0) == 0) {
+       i5 = HEAP32[i6 + 20 >> 2] | 0;
+       if ((i5 | 0) == 0) {
+        break;
+       }
+      }
+      i6 = (HEAP32[i5 + 4 >> 2] & -8) - i12 | 0;
+      i4 = i6 >>> 0 < i2 >>> 0;
+      i2 = i4 ? i6 : i2;
+      i6 = i5;
+      i3 = i4 ? i5 : i3;
+     }
+     i6 = HEAP32[14488 >> 2] | 0;
+     if (i3 >>> 0 < i6 >>> 0) {
+      _abort();
+     }
+     i4 = i3 + i12 | 0;
+     if (!(i3 >>> 0 < i4 >>> 0)) {
+      _abort();
+     }
+     i5 = HEAP32[i3 + 24 >> 2] | 0;
+     i7 = HEAP32[i3 + 12 >> 2] | 0;
+     do {
+      if ((i7 | 0) == (i3 | 0)) {
+       i8 = i3 + 20 | 0;
+       i7 = HEAP32[i8 >> 2] | 0;
+       if ((i7 | 0) == 0) {
+        i8 = i3 + 16 | 0;
+        i7 = HEAP32[i8 >> 2] | 0;
+        if ((i7 | 0) == 0) {
+         i26 = 0;
+         break;
+        }
+       }
+       while (1) {
+        i10 = i7 + 20 | 0;
+        i9 = HEAP32[i10 >> 2] | 0;
+        if ((i9 | 0) != 0) {
+         i7 = i9;
+         i8 = i10;
+         continue;
+        }
+        i10 = i7 + 16 | 0;
+        i9 = HEAP32[i10 >> 2] | 0;
+        if ((i9 | 0) == 0) {
+         break;
+        } else {
+         i7 = i9;
+         i8 = i10;
+        }
+       }
+       if (i8 >>> 0 < i6 >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i8 >> 2] = 0;
+        i26 = i7;
+        break;
+       }
+      } else {
+       i8 = HEAP32[i3 + 8 >> 2] | 0;
+       if (i8 >>> 0 < i6 >>> 0) {
+        _abort();
+       }
+       i6 = i8 + 12 | 0;
+       if ((HEAP32[i6 >> 2] | 0) != (i3 | 0)) {
+        _abort();
+       }
+       i9 = i7 + 8 | 0;
+       if ((HEAP32[i9 >> 2] | 0) == (i3 | 0)) {
+        HEAP32[i6 >> 2] = i7;
+        HEAP32[i9 >> 2] = i8;
+        i26 = i7;
+        break;
+       } else {
+        _abort();
+       }
+      }
+     } while (0);
+     do {
+      if ((i5 | 0) != 0) {
+       i7 = HEAP32[i3 + 28 >> 2] | 0;
+       i6 = 14776 + (i7 << 2) | 0;
+       if ((i3 | 0) == (HEAP32[i6 >> 2] | 0)) {
+        HEAP32[i6 >> 2] = i26;
+        if ((i26 | 0) == 0) {
+         HEAP32[14476 >> 2] = HEAP32[14476 >> 2] & ~(1 << i7);
+         break;
+        }
+       } else {
+        if (i5 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+         _abort();
+        }
+        i6 = i5 + 16 | 0;
+        if ((HEAP32[i6 >> 2] | 0) == (i3 | 0)) {
+         HEAP32[i6 >> 2] = i26;
+        } else {
+         HEAP32[i5 + 20 >> 2] = i26;
+        }
+        if ((i26 | 0) == 0) {
+         break;
+        }
+       }
+       if (i26 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+        _abort();
+       }
+       HEAP32[i26 + 24 >> 2] = i5;
+       i5 = HEAP32[i3 + 16 >> 2] | 0;
+       do {
+        if ((i5 | 0) != 0) {
+         if (i5 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i26 + 16 >> 2] = i5;
+          HEAP32[i5 + 24 >> 2] = i26;
+          break;
+         }
+        }
+       } while (0);
+       i5 = HEAP32[i3 + 20 >> 2] | 0;
+       if ((i5 | 0) != 0) {
+        if (i5 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i26 + 20 >> 2] = i5;
+         HEAP32[i5 + 24 >> 2] = i26;
+         break;
+        }
+       }
+      }
+     } while (0);
+     if (i2 >>> 0 < 16) {
+      i32 = i2 + i12 | 0;
+      HEAP32[i3 + 4 >> 2] = i32 | 3;
+      i32 = i3 + (i32 + 4) | 0;
+      HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+     } else {
+      HEAP32[i3 + 4 >> 2] = i12 | 3;
+      HEAP32[i3 + (i12 | 4) >> 2] = i2 | 1;
+      HEAP32[i3 + (i2 + i12) >> 2] = i2;
+      i6 = HEAP32[14480 >> 2] | 0;
+      if ((i6 | 0) != 0) {
+       i5 = HEAP32[14492 >> 2] | 0;
+       i8 = i6 >>> 3;
+       i9 = i8 << 1;
+       i6 = 14512 + (i9 << 2) | 0;
+       i7 = HEAP32[3618] | 0;
+       i8 = 1 << i8;
+       if ((i7 & i8 | 0) != 0) {
+        i7 = 14512 + (i9 + 2 << 2) | 0;
+        i8 = HEAP32[i7 >> 2] | 0;
+        if (i8 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+         _abort();
+        } else {
+         i25 = i7;
+         i24 = i8;
+        }
+       } else {
+        HEAP32[3618] = i7 | i8;
+        i25 = 14512 + (i9 + 2 << 2) | 0;
+        i24 = i6;
+       }
+       HEAP32[i25 >> 2] = i5;
+       HEAP32[i24 + 12 >> 2] = i5;
+       HEAP32[i5 + 8 >> 2] = i24;
+       HEAP32[i5 + 12 >> 2] = i6;
+      }
+      HEAP32[14480 >> 2] = i2;
+      HEAP32[14492 >> 2] = i4;
+     }
+     i32 = i3 + 8 | 0;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+   }
+  } else {
+   if (!(i12 >>> 0 > 4294967231)) {
+    i24 = i12 + 11 | 0;
+    i12 = i24 & -8;
+    i26 = HEAP32[14476 >> 2] | 0;
+    if ((i26 | 0) != 0) {
+     i25 = 0 - i12 | 0;
+     i24 = i24 >>> 8;
+     if ((i24 | 0) != 0) {
+      if (i12 >>> 0 > 16777215) {
+       i27 = 31;
+      } else {
+       i31 = (i24 + 1048320 | 0) >>> 16 & 8;
+       i32 = i24 << i31;
+       i30 = (i32 + 520192 | 0) >>> 16 & 4;
+       i32 = i32 << i30;
+       i27 = (i32 + 245760 | 0) >>> 16 & 2;
+       i27 = 14 - (i30 | i31 | i27) + (i32 << i27 >>> 15) | 0;
+       i27 = i12 >>> (i27 + 7 | 0) & 1 | i27 << 1;
+      }
+     } else {
+      i27 = 0;
+     }
+     i30 = HEAP32[14776 + (i27 << 2) >> 2] | 0;
+     L126 : do {
+      if ((i30 | 0) == 0) {
+       i29 = 0;
+       i24 = 0;
+      } else {
+       if ((i27 | 0) == 31) {
+        i24 = 0;
+       } else {
+        i24 = 25 - (i27 >>> 1) | 0;
+       }
+       i29 = 0;
+       i28 = i12 << i24;
+       i24 = 0;
+       while (1) {
+        i32 = HEAP32[i30 + 4 >> 2] & -8;
+        i31 = i32 - i12 | 0;
+        if (i31 >>> 0 < i25 >>> 0) {
+         if ((i32 | 0) == (i12 | 0)) {
+          i25 = i31;
+          i29 = i30;
+          i24 = i30;
+          break L126;
+         } else {
+          i25 = i31;
+          i24 = i30;
+         }
+        }
+        i31 = HEAP32[i30 + 20 >> 2] | 0;
+        i30 = HEAP32[i30 + (i28 >>> 31 << 2) + 16 >> 2] | 0;
+        i29 = (i31 | 0) == 0 | (i31 | 0) == (i30 | 0) ? i29 : i31;
+        if ((i30 | 0) == 0) {
+         break;
+        } else {
+         i28 = i28 << 1;
+        }
+       }
+      }
+     } while (0);
+     if ((i29 | 0) == 0 & (i24 | 0) == 0) {
+      i32 = 2 << i27;
+      i26 = i26 & (i32 | 0 - i32);
+      if ((i26 | 0) == 0) {
+       break;
+      }
+      i32 = (i26 & 0 - i26) + -1 | 0;
+      i28 = i32 >>> 12 & 16;
+      i32 = i32 >>> i28;
+      i27 = i32 >>> 5 & 8;
+      i32 = i32 >>> i27;
+      i30 = i32 >>> 2 & 4;
+      i32 = i32 >>> i30;
+      i31 = i32 >>> 1 & 2;
+      i32 = i32 >>> i31;
+      i29 = i32 >>> 1 & 1;
+      i29 = HEAP32[14776 + ((i27 | i28 | i30 | i31 | i29) + (i32 >>> i29) << 2) >> 2] | 0;
+     }
+     if ((i29 | 0) != 0) {
+      while (1) {
+       i27 = (HEAP32[i29 + 4 >> 2] & -8) - i12 | 0;
+       i26 = i27 >>> 0 < i25 >>> 0;
+       i25 = i26 ? i27 : i25;
+       i24 = i26 ? i29 : i24;
+       i26 = HEAP32[i29 + 16 >> 2] | 0;
+       if ((i26 | 0) != 0) {
+        i29 = i26;
+        continue;
+       }
+       i29 = HEAP32[i29 + 20 >> 2] | 0;
+       if ((i29 | 0) == 0) {
+        break;
+       }
+      }
+     }
+     if ((i24 | 0) != 0 ? i25 >>> 0 < ((HEAP32[14480 >> 2] | 0) - i12 | 0) >>> 0 : 0) {
+      i4 = HEAP32[14488 >> 2] | 0;
+      if (i24 >>> 0 < i4 >>> 0) {
+       _abort();
+      }
+      i2 = i24 + i12 | 0;
+      if (!(i24 >>> 0 < i2 >>> 0)) {
+       _abort();
+      }
+      i3 = HEAP32[i24 + 24 >> 2] | 0;
+      i6 = HEAP32[i24 + 12 >> 2] | 0;
+      do {
+       if ((i6 | 0) == (i24 | 0)) {
+        i6 = i24 + 20 | 0;
+        i5 = HEAP32[i6 >> 2] | 0;
+        if ((i5 | 0) == 0) {
+         i6 = i24 + 16 | 0;
+         i5 = HEAP32[i6 >> 2] | 0;
+         if ((i5 | 0) == 0) {
+          i22 = 0;
+          break;
+         }
+        }
+        while (1) {
+         i8 = i5 + 20 | 0;
+         i7 = HEAP32[i8 >> 2] | 0;
+         if ((i7 | 0) != 0) {
+          i5 = i7;
+          i6 = i8;
+          continue;
+         }
+         i7 = i5 + 16 | 0;
+         i8 = HEAP32[i7 >> 2] | 0;
+         if ((i8 | 0) == 0) {
+          break;
+         } else {
+          i5 = i8;
+          i6 = i7;
+         }
+        }
+        if (i6 >>> 0 < i4 >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i6 >> 2] = 0;
+         i22 = i5;
+         break;
+        }
+       } else {
+        i5 = HEAP32[i24 + 8 >> 2] | 0;
+        if (i5 >>> 0 < i4 >>> 0) {
+         _abort();
+        }
+        i7 = i5 + 12 | 0;
+        if ((HEAP32[i7 >> 2] | 0) != (i24 | 0)) {
+         _abort();
+        }
+        i4 = i6 + 8 | 0;
+        if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
+         HEAP32[i7 >> 2] = i6;
+         HEAP32[i4 >> 2] = i5;
+         i22 = i6;
+         break;
+        } else {
+         _abort();
+        }
+       }
+      } while (0);
+      do {
+       if ((i3 | 0) != 0) {
+        i4 = HEAP32[i24 + 28 >> 2] | 0;
+        i5 = 14776 + (i4 << 2) | 0;
+        if ((i24 | 0) == (HEAP32[i5 >> 2] | 0)) {
+         HEAP32[i5 >> 2] = i22;
+         if ((i22 | 0) == 0) {
+          HEAP32[14476 >> 2] = HEAP32[14476 >> 2] & ~(1 << i4);
+          break;
+         }
+        } else {
+         if (i3 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+          _abort();
+         }
+         i4 = i3 + 16 | 0;
+         if ((HEAP32[i4 >> 2] | 0) == (i24 | 0)) {
+          HEAP32[i4 >> 2] = i22;
+         } else {
+          HEAP32[i3 + 20 >> 2] = i22;
+         }
+         if ((i22 | 0) == 0) {
+          break;
+         }
+        }
+        if (i22 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+         _abort();
+        }
+        HEAP32[i22 + 24 >> 2] = i3;
+        i3 = HEAP32[i24 + 16 >> 2] | 0;
+        do {
+         if ((i3 | 0) != 0) {
+          if (i3 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           HEAP32[i22 + 16 >> 2] = i3;
+           HEAP32[i3 + 24 >> 2] = i22;
+           break;
+          }
+         }
+        } while (0);
+        i3 = HEAP32[i24 + 20 >> 2] | 0;
+        if ((i3 | 0) != 0) {
+         if (i3 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i22 + 20 >> 2] = i3;
+          HEAP32[i3 + 24 >> 2] = i22;
+          break;
+         }
+        }
+       }
+      } while (0);
+      L204 : do {
+       if (!(i25 >>> 0 < 16)) {
+        HEAP32[i24 + 4 >> 2] = i12 | 3;
+        HEAP32[i24 + (i12 | 4) >> 2] = i25 | 1;
+        HEAP32[i24 + (i25 + i12) >> 2] = i25;
+        i4 = i25 >>> 3;
+        if (i25 >>> 0 < 256) {
+         i6 = i4 << 1;
+         i3 = 14512 + (i6 << 2) | 0;
+         i5 = HEAP32[3618] | 0;
+         i4 = 1 << i4;
+         if ((i5 & i4 | 0) != 0) {
+          i5 = 14512 + (i6 + 2 << 2) | 0;
+          i4 = HEAP32[i5 >> 2] | 0;
+          if (i4 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           i21 = i5;
+           i20 = i4;
+          }
+         } else {
+          HEAP32[3618] = i5 | i4;
+          i21 = 14512 + (i6 + 2 << 2) | 0;
+          i20 = i3;
+         }
+         HEAP32[i21 >> 2] = i2;
+         HEAP32[i20 + 12 >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i20;
+         HEAP32[i24 + (i12 + 12) >> 2] = i3;
+         break;
+        }
+        i3 = i25 >>> 8;
+        if ((i3 | 0) != 0) {
+         if (i25 >>> 0 > 16777215) {
+          i3 = 31;
+         } else {
+          i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+          i32 = i3 << i31;
+          i30 = (i32 + 520192 | 0) >>> 16 & 4;
+          i32 = i32 << i30;
+          i3 = (i32 + 245760 | 0) >>> 16 & 2;
+          i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+          i3 = i25 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+         }
+        } else {
+         i3 = 0;
+        }
+        i6 = 14776 + (i3 << 2) | 0;
+        HEAP32[i24 + (i12 + 28) >> 2] = i3;
+        HEAP32[i24 + (i12 + 20) >> 2] = 0;
+        HEAP32[i24 + (i12 + 16) >> 2] = 0;
+        i4 = HEAP32[14476 >> 2] | 0;
+        i5 = 1 << i3;
+        if ((i4 & i5 | 0) == 0) {
+         HEAP32[14476 >> 2] = i4 | i5;
+         HEAP32[i6 >> 2] = i2;
+         HEAP32[i24 + (i12 + 24) >> 2] = i6;
+         HEAP32[i24 + (i12 + 12) >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i2;
+         break;
+        }
+        i4 = HEAP32[i6 >> 2] | 0;
+        if ((i3 | 0) == 31) {
+         i3 = 0;
+        } else {
+         i3 = 25 - (i3 >>> 1) | 0;
+        }
+        L225 : do {
+         if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i25 | 0)) {
+          i3 = i25 << i3;
+          while (1) {
+           i6 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+           i5 = HEAP32[i6 >> 2] | 0;
+           if ((i5 | 0) == 0) {
+            break;
+           }
+           if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i25 | 0)) {
+            i18 = i5;
+            break L225;
+           } else {
+            i3 = i3 << 1;
+            i4 = i5;
+           }
+          }
+          if (i6 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+           _abort();
+          } else {
+           HEAP32[i6 >> 2] = i2;
+           HEAP32[i24 + (i12 + 24) >> 2] = i4;
+           HEAP32[i24 + (i12 + 12) >> 2] = i2;
+           HEAP32[i24 + (i12 + 8) >> 2] = i2;
+           break L204;
+          }
+         } else {
+          i18 = i4;
+         }
+        } while (0);
+        i4 = i18 + 8 | 0;
+        i3 = HEAP32[i4 >> 2] | 0;
+        i5 = HEAP32[14488 >> 2] | 0;
+        if (i18 >>> 0 < i5 >>> 0) {
+         _abort();
+        }
+        if (i3 >>> 0 < i5 >>> 0) {
+         _abort();
+        } else {
+         HEAP32[i3 + 12 >> 2] = i2;
+         HEAP32[i4 >> 2] = i2;
+         HEAP32[i24 + (i12 + 8) >> 2] = i3;
+         HEAP32[i24 + (i12 + 12) >> 2] = i18;
+         HEAP32[i24 + (i12 + 24) >> 2] = 0;
+         break;
+        }
+       } else {
+        i32 = i25 + i12 | 0;
+        HEAP32[i24 + 4 >> 2] = i32 | 3;
+        i32 = i24 + (i32 + 4) | 0;
+        HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+       }
+      } while (0);
+      i32 = i24 + 8 | 0;
+      STACKTOP = i1;
+      return i32 | 0;
+     }
+    }
+   } else {
+    i12 = -1;
+   }
+  }
+ } while (0);
+ i18 = HEAP32[14480 >> 2] | 0;
+ if (!(i12 >>> 0 > i18 >>> 0)) {
+  i3 = i18 - i12 | 0;
+  i2 = HEAP32[14492 >> 2] | 0;
+  if (i3 >>> 0 > 15) {
+   HEAP32[14492 >> 2] = i2 + i12;
+   HEAP32[14480 >> 2] = i3;
+   HEAP32[i2 + (i12 + 4) >> 2] = i3 | 1;
+   HEAP32[i2 + i18 >> 2] = i3;
+   HEAP32[i2 + 4 >> 2] = i12 | 3;
+  } else {
+   HEAP32[14480 >> 2] = 0;
+   HEAP32[14492 >> 2] = 0;
+   HEAP32[i2 + 4 >> 2] = i18 | 3;
+   i32 = i2 + (i18 + 4) | 0;
+   HEAP32[i32 >> 2] = HEAP32[i32 >> 2] | 1;
+  }
+  i32 = i2 + 8 | 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ i18 = HEAP32[14484 >> 2] | 0;
+ if (i12 >>> 0 < i18 >>> 0) {
+  i31 = i18 - i12 | 0;
+  HEAP32[14484 >> 2] = i31;
+  i32 = HEAP32[14496 >> 2] | 0;
+  HEAP32[14496 >> 2] = i32 + i12;
+  HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
+  HEAP32[i32 + 4 >> 2] = i12 | 3;
+  i32 = i32 + 8 | 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ do {
+  if ((HEAP32[3736] | 0) == 0) {
+   i18 = _sysconf(30) | 0;
+   if ((i18 + -1 & i18 | 0) == 0) {
+    HEAP32[14952 >> 2] = i18;
+    HEAP32[14948 >> 2] = i18;
+    HEAP32[14956 >> 2] = -1;
+    HEAP32[14960 >> 2] = -1;
+    HEAP32[14964 >> 2] = 0;
+    HEAP32[14916 >> 2] = 0;
+    HEAP32[3736] = (_time(0) | 0) & -16 ^ 1431655768;
+    break;
+   } else {
+    _abort();
+   }
+  }
+ } while (0);
+ i20 = i12 + 48 | 0;
+ i25 = HEAP32[14952 >> 2] | 0;
+ i21 = i12 + 47 | 0;
+ i22 = i25 + i21 | 0;
+ i25 = 0 - i25 | 0;
+ i18 = i22 & i25;
+ if (!(i18 >>> 0 > i12 >>> 0)) {
+  i32 = 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ i24 = HEAP32[14912 >> 2] | 0;
+ if ((i24 | 0) != 0 ? (i31 = HEAP32[14904 >> 2] | 0, i32 = i31 + i18 | 0, i32 >>> 0 <= i31 >>> 0 | i32 >>> 0 > i24 >>> 0) : 0) {
+  i32 = 0;
+  STACKTOP = i1;
+  return i32 | 0;
+ }
+ L269 : do {
+  if ((HEAP32[14916 >> 2] & 4 | 0) == 0) {
+   i26 = HEAP32[14496 >> 2] | 0;
+   L271 : do {
+    if ((i26 | 0) != 0) {
+     i24 = 14920 | 0;
+     while (1) {
+      i27 = HEAP32[i24 >> 2] | 0;
+      if (!(i27 >>> 0 > i26 >>> 0) ? (i23 = i24 + 4 | 0, (i27 + (HEAP32[i23 >> 2] | 0) | 0) >>> 0 > i26 >>> 0) : 0) {
+       break;
+      }
+      i24 = HEAP32[i24 + 8 >> 2] | 0;
+      if ((i24 | 0) == 0) {
+       i13 = 182;
+       break L271;
+      }
+     }
+     if ((i24 | 0) != 0) {
+      i25 = i22 - (HEAP32[14484 >> 2] | 0) & i25;
+      if (i25 >>> 0 < 2147483647) {
+       i13 = _sbrk(i25 | 0) | 0;
+       i26 = (i13 | 0) == ((HEAP32[i24 >> 2] | 0) + (HEAP32[i23 >> 2] | 0) | 0);
+       i22 = i13;
+       i24 = i25;
+       i23 = i26 ? i13 : -1;
+       i25 = i26 ? i25 : 0;
+       i13 = 191;
+      } else {
+       i25 = 0;
+      }
+     } else {
+      i13 = 182;
+     }
+    } else {
+     i13 = 182;
+    }
+   } while (0);
+   do {
+    if ((i13 | 0) == 182) {
+     i23 = _sbrk(0) | 0;
+     if ((i23 | 0) != (-1 | 0)) {
+      i24 = i23;
+      i22 = HEAP32[14948 >> 2] | 0;
+      i25 = i22 + -1 | 0;
+      if ((i25 & i24 | 0) == 0) {
+       i25 = i18;
+      } else {
+       i25 = i18 - i24 + (i25 + i24 & 0 - i22) | 0;
+      }
+      i24 = HEAP32[14904 >> 2] | 0;
+      i26 = i24 + i25 | 0;
+      if (i25 >>> 0 > i12 >>> 0 & i25 >>> 0 < 2147483647) {
+       i22 = HEAP32[14912 >> 2] | 0;
+       if ((i22 | 0) != 0 ? i26 >>> 0 <= i24 >>> 0 | i26 >>> 0 > i22 >>> 0 : 0) {
+        i25 = 0;
+        break;
+       }
+       i22 = _sbrk(i25 | 0) | 0;
+       i13 = (i22 | 0) == (i23 | 0);
+       i24 = i25;
+       i23 = i13 ? i23 : -1;
+       i25 = i13 ? i25 : 0;
+       i13 = 191;
+      } else {
+       i25 = 0;
+      }
+     } else {
+      i25 = 0;
+     }
+    }
+   } while (0);
+   L291 : do {
+    if ((i13 | 0) == 191) {
+     i13 = 0 - i24 | 0;
+     if ((i23 | 0) != (-1 | 0)) {
+      i17 = i23;
+      i14 = i25;
+      i13 = 202;
+      break L269;
+     }
+     do {
+      if ((i22 | 0) != (-1 | 0) & i24 >>> 0 < 2147483647 & i24 >>> 0 < i20 >>> 0 ? (i19 = HEAP32[14952 >> 2] | 0, i19 = i21 - i24 + i19 & 0 - i19, i19 >>> 0 < 2147483647) : 0) {
+       if ((_sbrk(i19 | 0) | 0) == (-1 | 0)) {
+        _sbrk(i13 | 0) | 0;
+        break L291;
+       } else {
+        i24 = i19 + i24 | 0;
+        break;
+       }
+      }
+     } while (0);
+     if ((i22 | 0) != (-1 | 0)) {
+      i17 = i22;
+      i14 = i24;
+      i13 = 202;
+      break L269;
+     }
+    }
+   } while (0);
+   HEAP32[14916 >> 2] = HEAP32[14916 >> 2] | 4;
+   i13 = 199;
+  } else {
+   i25 = 0;
+   i13 = 199;
+  }
+ } while (0);
+ if ((((i13 | 0) == 199 ? i18 >>> 0 < 2147483647 : 0) ? (i17 = _sbrk(i18 | 0) | 0, i16 = _sbrk(0) | 0, (i16 | 0) != (-1 | 0) & (i17 | 0) != (-1 | 0) & i17 >>> 0 < i16 >>> 0) : 0) ? (i15 = i16 - i17 | 0, i14 = i15 >>> 0 > (i12 + 40 | 0) >>> 0, i14) : 0) {
+  i14 = i14 ? i15 : i25;
+  i13 = 202;
+ }
+ if ((i13 | 0) == 202) {
+  i15 = (HEAP32[14904 >> 2] | 0) + i14 | 0;
+  HEAP32[14904 >> 2] = i15;
+  if (i15 >>> 0 > (HEAP32[14908 >> 2] | 0) >>> 0) {
+   HEAP32[14908 >> 2] = i15;
+  }
+  i15 = HEAP32[14496 >> 2] | 0;
+  L311 : do {
+   if ((i15 | 0) != 0) {
+    i21 = 14920 | 0;
+    while (1) {
+     i16 = HEAP32[i21 >> 2] | 0;
+     i19 = i21 + 4 | 0;
+     i20 = HEAP32[i19 >> 2] | 0;
+     if ((i17 | 0) == (i16 + i20 | 0)) {
+      i13 = 214;
+      break;
+     }
+     i18 = HEAP32[i21 + 8 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      break;
+     } else {
+      i21 = i18;
+     }
+    }
+    if (((i13 | 0) == 214 ? (HEAP32[i21 + 12 >> 2] & 8 | 0) == 0 : 0) ? i15 >>> 0 >= i16 >>> 0 & i15 >>> 0 < i17 >>> 0 : 0) {
+     HEAP32[i19 >> 2] = i20 + i14;
+     i2 = (HEAP32[14484 >> 2] | 0) + i14 | 0;
+     i3 = i15 + 8 | 0;
+     if ((i3 & 7 | 0) == 0) {
+      i3 = 0;
+     } else {
+      i3 = 0 - i3 & 7;
+     }
+     i32 = i2 - i3 | 0;
+     HEAP32[14496 >> 2] = i15 + i3;
+     HEAP32[14484 >> 2] = i32;
+     HEAP32[i15 + (i3 + 4) >> 2] = i32 | 1;
+     HEAP32[i15 + (i2 + 4) >> 2] = 40;
+     HEAP32[14500 >> 2] = HEAP32[14960 >> 2];
+     break;
+    }
+    if (i17 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+     HEAP32[14488 >> 2] = i17;
+    }
+    i19 = i17 + i14 | 0;
+    i16 = 14920 | 0;
+    while (1) {
+     if ((HEAP32[i16 >> 2] | 0) == (i19 | 0)) {
+      i13 = 224;
+      break;
+     }
+     i18 = HEAP32[i16 + 8 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      break;
+     } else {
+      i16 = i18;
+     }
+    }
+    if ((i13 | 0) == 224 ? (HEAP32[i16 + 12 >> 2] & 8 | 0) == 0 : 0) {
+     HEAP32[i16 >> 2] = i17;
+     i6 = i16 + 4 | 0;
+     HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i14;
+     i6 = i17 + 8 | 0;
+     if ((i6 & 7 | 0) == 0) {
+      i6 = 0;
+     } else {
+      i6 = 0 - i6 & 7;
+     }
+     i7 = i17 + (i14 + 8) | 0;
+     if ((i7 & 7 | 0) == 0) {
+      i13 = 0;
+     } else {
+      i13 = 0 - i7 & 7;
+     }
+     i15 = i17 + (i13 + i14) | 0;
+     i8 = i6 + i12 | 0;
+     i7 = i17 + i8 | 0;
+     i10 = i15 - (i17 + i6) - i12 | 0;
+     HEAP32[i17 + (i6 + 4) >> 2] = i12 | 3;
+     L348 : do {
+      if ((i15 | 0) != (HEAP32[14496 >> 2] | 0)) {
+       if ((i15 | 0) == (HEAP32[14492 >> 2] | 0)) {
+        i32 = (HEAP32[14480 >> 2] | 0) + i10 | 0;
+        HEAP32[14480 >> 2] = i32;
+        HEAP32[14492 >> 2] = i7;
+        HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
+        HEAP32[i17 + (i32 + i8) >> 2] = i32;
+        break;
+       }
+       i12 = i14 + 4 | 0;
+       i18 = HEAP32[i17 + (i12 + i13) >> 2] | 0;
+       if ((i18 & 3 | 0) == 1) {
+        i11 = i18 & -8;
+        i16 = i18 >>> 3;
+        do {
+         if (!(i18 >>> 0 < 256)) {
+          i9 = HEAP32[i17 + ((i13 | 24) + i14) >> 2] | 0;
+          i19 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
+          do {
+           if ((i19 | 0) == (i15 | 0)) {
+            i19 = i13 | 16;
+            i18 = i17 + (i12 + i19) | 0;
+            i16 = HEAP32[i18 >> 2] | 0;
+            if ((i16 | 0) == 0) {
+             i18 = i17 + (i19 + i14) | 0;
+             i16 = HEAP32[i18 >> 2] | 0;
+             if ((i16 | 0) == 0) {
+              i5 = 0;
+              break;
+             }
+            }
+            while (1) {
+             i20 = i16 + 20 | 0;
+             i19 = HEAP32[i20 >> 2] | 0;
+             if ((i19 | 0) != 0) {
+              i16 = i19;
+              i18 = i20;
+              continue;
+             }
+             i19 = i16 + 16 | 0;
+             i20 = HEAP32[i19 >> 2] | 0;
+             if ((i20 | 0) == 0) {
+              break;
+             } else {
+              i16 = i20;
+              i18 = i19;
+             }
+            }
+            if (i18 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+             _abort();
+            } else {
+             HEAP32[i18 >> 2] = 0;
+             i5 = i16;
+             break;
+            }
+           } else {
+            i18 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
+            if (i18 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+             _abort();
+            }
+            i16 = i18 + 12 | 0;
+            if ((HEAP32[i16 >> 2] | 0) != (i15 | 0)) {
+             _abort();
+            }
+            i20 = i19 + 8 | 0;
+            if ((HEAP32[i20 >> 2] | 0) == (i15 | 0)) {
+             HEAP32[i16 >> 2] = i19;
+             HEAP32[i20 >> 2] = i18;
+             i5 = i19;
+             break;
+            } else {
+             _abort();
+            }
+           }
+          } while (0);
+          if ((i9 | 0) != 0) {
+           i16 = HEAP32[i17 + (i14 + 28 + i13) >> 2] | 0;
+           i18 = 14776 + (i16 << 2) | 0;
+           if ((i15 | 0) == (HEAP32[i18 >> 2] | 0)) {
+            HEAP32[i18 >> 2] = i5;
+            if ((i5 | 0) == 0) {
+             HEAP32[14476 >> 2] = HEAP32[14476 >> 2] & ~(1 << i16);
+             break;
+            }
+           } else {
+            if (i9 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+             _abort();
+            }
+            i16 = i9 + 16 | 0;
+            if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
+             HEAP32[i16 >> 2] = i5;
+            } else {
+             HEAP32[i9 + 20 >> 2] = i5;
+            }
+            if ((i5 | 0) == 0) {
+             break;
+            }
+           }
+           if (i5 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           HEAP32[i5 + 24 >> 2] = i9;
+           i15 = i13 | 16;
+           i9 = HEAP32[i17 + (i15 + i14) >> 2] | 0;
+           do {
+            if ((i9 | 0) != 0) {
+             if (i9 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+              _abort();
+             } else {
+              HEAP32[i5 + 16 >> 2] = i9;
+              HEAP32[i9 + 24 >> 2] = i5;
+              break;
+             }
+            }
+           } while (0);
+           i9 = HEAP32[i17 + (i12 + i15) >> 2] | 0;
+           if ((i9 | 0) != 0) {
+            if (i9 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+             _abort();
+            } else {
+             HEAP32[i5 + 20 >> 2] = i9;
+             HEAP32[i9 + 24 >> 2] = i5;
+             break;
+            }
+           }
+          }
+         } else {
+          i5 = HEAP32[i17 + ((i13 | 8) + i14) >> 2] | 0;
+          i12 = HEAP32[i17 + (i14 + 12 + i13) >> 2] | 0;
+          i18 = 14512 + (i16 << 1 << 2) | 0;
+          if ((i5 | 0) != (i18 | 0)) {
+           if (i5 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           if ((HEAP32[i5 + 12 >> 2] | 0) != (i15 | 0)) {
+            _abort();
+           }
+          }
+          if ((i12 | 0) == (i5 | 0)) {
+           HEAP32[3618] = HEAP32[3618] & ~(1 << i16);
+           break;
+          }
+          if ((i12 | 0) != (i18 | 0)) {
+           if (i12 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+            _abort();
+           }
+           i16 = i12 + 8 | 0;
+           if ((HEAP32[i16 >> 2] | 0) == (i15 | 0)) {
+            i9 = i16;
+           } else {
+            _abort();
+           }
+          } else {
+           i9 = i12 + 8 | 0;
+          }
+          HEAP32[i5 + 12 >> 2] = i12;
+          HEAP32[i9 >> 2] = i5;
+         }
+        } while (0);
+        i15 = i17 + ((i11 | i13) + i14) | 0;
+        i10 = i11 + i10 | 0;
+       }
+       i5 = i15 + 4 | 0;
+       HEAP32[i5 >> 2] = HEAP32[i5 >> 2] & -2;
+       HEAP32[i17 + (i8 + 4) >> 2] = i10 | 1;
+       HEAP32[i17 + (i10 + i8) >> 2] = i10;
+       i5 = i10 >>> 3;
+       if (i10 >>> 0 < 256) {
+        i10 = i5 << 1;
+        i2 = 14512 + (i10 << 2) | 0;
+        i9 = HEAP32[3618] | 0;
+        i5 = 1 << i5;
+        if ((i9 & i5 | 0) != 0) {
+         i9 = 14512 + (i10 + 2 << 2) | 0;
+         i5 = HEAP32[i9 >> 2] | 0;
+         if (i5 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          i3 = i9;
+          i4 = i5;
+         }
+        } else {
+         HEAP32[3618] = i9 | i5;
+         i3 = 14512 + (i10 + 2 << 2) | 0;
+         i4 = i2;
+        }
+        HEAP32[i3 >> 2] = i7;
+        HEAP32[i4 + 12 >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i4;
+        HEAP32[i17 + (i8 + 12) >> 2] = i2;
+        break;
+       }
+       i3 = i10 >>> 8;
+       if ((i3 | 0) != 0) {
+        if (i10 >>> 0 > 16777215) {
+         i3 = 31;
+        } else {
+         i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+         i32 = i3 << i31;
+         i30 = (i32 + 520192 | 0) >>> 16 & 4;
+         i32 = i32 << i30;
+         i3 = (i32 + 245760 | 0) >>> 16 & 2;
+         i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+         i3 = i10 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+        }
+       } else {
+        i3 = 0;
+       }
+       i4 = 14776 + (i3 << 2) | 0;
+       HEAP32[i17 + (i8 + 28) >> 2] = i3;
+       HEAP32[i17 + (i8 + 20) >> 2] = 0;
+       HEAP32[i17 + (i8 + 16) >> 2] = 0;
+       i9 = HEAP32[14476 >> 2] | 0;
+       i5 = 1 << i3;
+       if ((i9 & i5 | 0) == 0) {
+        HEAP32[14476 >> 2] = i9 | i5;
+        HEAP32[i4 >> 2] = i7;
+        HEAP32[i17 + (i8 + 24) >> 2] = i4;
+        HEAP32[i17 + (i8 + 12) >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i7;
+        break;
+       }
+       i4 = HEAP32[i4 >> 2] | 0;
+       if ((i3 | 0) == 31) {
+        i3 = 0;
+       } else {
+        i3 = 25 - (i3 >>> 1) | 0;
+       }
+       L444 : do {
+        if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i10 | 0)) {
+         i3 = i10 << i3;
+         while (1) {
+          i5 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+          i9 = HEAP32[i5 >> 2] | 0;
+          if ((i9 | 0) == 0) {
+           break;
+          }
+          if ((HEAP32[i9 + 4 >> 2] & -8 | 0) == (i10 | 0)) {
+           i2 = i9;
+           break L444;
+          } else {
+           i3 = i3 << 1;
+           i4 = i9;
+          }
+         }
+         if (i5 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+          _abort();
+         } else {
+          HEAP32[i5 >> 2] = i7;
+          HEAP32[i17 + (i8 + 24) >> 2] = i4;
+          HEAP32[i17 + (i8 + 12) >> 2] = i7;
+          HEAP32[i17 + (i8 + 8) >> 2] = i7;
+          break L348;
+         }
+        } else {
+         i2 = i4;
+        }
+       } while (0);
+       i4 = i2 + 8 | 0;
+       i3 = HEAP32[i4 >> 2] | 0;
+       i5 = HEAP32[14488 >> 2] | 0;
+       if (i2 >>> 0 < i5 >>> 0) {
+        _abort();
+       }
+       if (i3 >>> 0 < i5 >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i3 + 12 >> 2] = i7;
+        HEAP32[i4 >> 2] = i7;
+        HEAP32[i17 + (i8 + 8) >> 2] = i3;
+        HEAP32[i17 + (i8 + 12) >> 2] = i2;
+        HEAP32[i17 + (i8 + 24) >> 2] = 0;
+        break;
+       }
+      } else {
+       i32 = (HEAP32[14484 >> 2] | 0) + i10 | 0;
+       HEAP32[14484 >> 2] = i32;
+       HEAP32[14496 >> 2] = i7;
+       HEAP32[i17 + (i8 + 4) >> 2] = i32 | 1;
+      }
+     } while (0);
+     i32 = i17 + (i6 | 8) | 0;
+     STACKTOP = i1;
+     return i32 | 0;
+    }
+    i3 = 14920 | 0;
+    while (1) {
+     i2 = HEAP32[i3 >> 2] | 0;
+     if (!(i2 >>> 0 > i15 >>> 0) ? (i11 = HEAP32[i3 + 4 >> 2] | 0, i10 = i2 + i11 | 0, i10 >>> 0 > i15 >>> 0) : 0) {
+      break;
+     }
+     i3 = HEAP32[i3 + 8 >> 2] | 0;
+    }
+    i3 = i2 + (i11 + -39) | 0;
+    if ((i3 & 7 | 0) == 0) {
+     i3 = 0;
+    } else {
+     i3 = 0 - i3 & 7;
+    }
+    i2 = i2 + (i11 + -47 + i3) | 0;
+    i2 = i2 >>> 0 < (i15 + 16 | 0) >>> 0 ? i15 : i2;
+    i3 = i2 + 8 | 0;
+    i4 = i17 + 8 | 0;
+    if ((i4 & 7 | 0) == 0) {
+     i4 = 0;
+    } else {
+     i4 = 0 - i4 & 7;
+    }
+    i32 = i14 + -40 - i4 | 0;
+    HEAP32[14496 >> 2] = i17 + i4;
+    HEAP32[14484 >> 2] = i32;
+    HEAP32[i17 + (i4 + 4) >> 2] = i32 | 1;
+    HEAP32[i17 + (i14 + -36) >> 2] = 40;
+    HEAP32[14500 >> 2] = HEAP32[14960 >> 2];
+    HEAP32[i2 + 4 >> 2] = 27;
+    HEAP32[i3 + 0 >> 2] = HEAP32[14920 >> 2];
+    HEAP32[i3 + 4 >> 2] = HEAP32[14924 >> 2];
+    HEAP32[i3 + 8 >> 2] = HEAP32[14928 >> 2];
+    HEAP32[i3 + 12 >> 2] = HEAP32[14932 >> 2];
+    HEAP32[14920 >> 2] = i17;
+    HEAP32[14924 >> 2] = i14;
+    HEAP32[14932 >> 2] = 0;
+    HEAP32[14928 >> 2] = i3;
+    i4 = i2 + 28 | 0;
+    HEAP32[i4 >> 2] = 7;
+    if ((i2 + 32 | 0) >>> 0 < i10 >>> 0) {
+     while (1) {
+      i3 = i4 + 4 | 0;
+      HEAP32[i3 >> 2] = 7;
+      if ((i4 + 8 | 0) >>> 0 < i10 >>> 0) {
+       i4 = i3;
+      } else {
+       break;
+      }
+     }
+    }
+    if ((i2 | 0) != (i15 | 0)) {
+     i2 = i2 - i15 | 0;
+     i3 = i15 + (i2 + 4) | 0;
+     HEAP32[i3 >> 2] = HEAP32[i3 >> 2] & -2;
+     HEAP32[i15 + 4 >> 2] = i2 | 1;
+     HEAP32[i15 + i2 >> 2] = i2;
+     i3 = i2 >>> 3;
+     if (i2 >>> 0 < 256) {
+      i4 = i3 << 1;
+      i2 = 14512 + (i4 << 2) | 0;
+      i5 = HEAP32[3618] | 0;
+      i3 = 1 << i3;
+      if ((i5 & i3 | 0) != 0) {
+       i4 = 14512 + (i4 + 2 << 2) | 0;
+       i3 = HEAP32[i4 >> 2] | 0;
+       if (i3 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        i7 = i4;
+        i8 = i3;
+       }
+      } else {
+       HEAP32[3618] = i5 | i3;
+       i7 = 14512 + (i4 + 2 << 2) | 0;
+       i8 = i2;
+      }
+      HEAP32[i7 >> 2] = i15;
+      HEAP32[i8 + 12 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i8;
+      HEAP32[i15 + 12 >> 2] = i2;
+      break;
+     }
+     i3 = i2 >>> 8;
+     if ((i3 | 0) != 0) {
+      if (i2 >>> 0 > 16777215) {
+       i3 = 31;
+      } else {
+       i31 = (i3 + 1048320 | 0) >>> 16 & 8;
+       i32 = i3 << i31;
+       i30 = (i32 + 520192 | 0) >>> 16 & 4;
+       i32 = i32 << i30;
+       i3 = (i32 + 245760 | 0) >>> 16 & 2;
+       i3 = 14 - (i30 | i31 | i3) + (i32 << i3 >>> 15) | 0;
+       i3 = i2 >>> (i3 + 7 | 0) & 1 | i3 << 1;
+      }
+     } else {
+      i3 = 0;
+     }
+     i7 = 14776 + (i3 << 2) | 0;
+     HEAP32[i15 + 28 >> 2] = i3;
+     HEAP32[i15 + 20 >> 2] = 0;
+     HEAP32[i15 + 16 >> 2] = 0;
+     i4 = HEAP32[14476 >> 2] | 0;
+     i5 = 1 << i3;
+     if ((i4 & i5 | 0) == 0) {
+      HEAP32[14476 >> 2] = i4 | i5;
+      HEAP32[i7 >> 2] = i15;
+      HEAP32[i15 + 24 >> 2] = i7;
+      HEAP32[i15 + 12 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i15;
+      break;
+     }
+     i4 = HEAP32[i7 >> 2] | 0;
+     if ((i3 | 0) == 31) {
+      i3 = 0;
+     } else {
+      i3 = 25 - (i3 >>> 1) | 0;
+     }
+     L499 : do {
+      if ((HEAP32[i4 + 4 >> 2] & -8 | 0) != (i2 | 0)) {
+       i3 = i2 << i3;
+       while (1) {
+        i7 = i4 + (i3 >>> 31 << 2) + 16 | 0;
+        i5 = HEAP32[i7 >> 2] | 0;
+        if ((i5 | 0) == 0) {
+         break;
+        }
+        if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i2 | 0)) {
+         i6 = i5;
+         break L499;
+        } else {
+         i3 = i3 << 1;
+         i4 = i5;
+        }
+       }
+       if (i7 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i7 >> 2] = i15;
+        HEAP32[i15 + 24 >> 2] = i4;
+        HEAP32[i15 + 12 >> 2] = i15;
+        HEAP32[i15 + 8 >> 2] = i15;
+        break L311;
+       }
+      } else {
+       i6 = i4;
+      }
+     } while (0);
+     i4 = i6 + 8 | 0;
+     i3 = HEAP32[i4 >> 2] | 0;
+     i2 = HEAP32[14488 >> 2] | 0;
+     if (i6 >>> 0 < i2 >>> 0) {
+      _abort();
+     }
+     if (i3 >>> 0 < i2 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i3 + 12 >> 2] = i15;
+      HEAP32[i4 >> 2] = i15;
+      HEAP32[i15 + 8 >> 2] = i3;
+      HEAP32[i15 + 12 >> 2] = i6;
+      HEAP32[i15 + 24 >> 2] = 0;
+      break;
+     }
+    }
+   } else {
+    i32 = HEAP32[14488 >> 2] | 0;
+    if ((i32 | 0) == 0 | i17 >>> 0 < i32 >>> 0) {
+     HEAP32[14488 >> 2] = i17;
+    }
+    HEAP32[14920 >> 2] = i17;
+    HEAP32[14924 >> 2] = i14;
+    HEAP32[14932 >> 2] = 0;
+    HEAP32[14508 >> 2] = HEAP32[3736];
+    HEAP32[14504 >> 2] = -1;
+    i2 = 0;
+    do {
+     i32 = i2 << 1;
+     i31 = 14512 + (i32 << 2) | 0;
+     HEAP32[14512 + (i32 + 3 << 2) >> 2] = i31;
+     HEAP32[14512 + (i32 + 2 << 2) >> 2] = i31;
+     i2 = i2 + 1 | 0;
+    } while ((i2 | 0) != 32);
+    i2 = i17 + 8 | 0;
+    if ((i2 & 7 | 0) == 0) {
+     i2 = 0;
+    } else {
+     i2 = 0 - i2 & 7;
+    }
+    i32 = i14 + -40 - i2 | 0;
+    HEAP32[14496 >> 2] = i17 + i2;
+    HEAP32[14484 >> 2] = i32;
+    HEAP32[i17 + (i2 + 4) >> 2] = i32 | 1;
+    HEAP32[i17 + (i14 + -36) >> 2] = 40;
+    HEAP32[14500 >> 2] = HEAP32[14960 >> 2];
+   }
+  } while (0);
+  i2 = HEAP32[14484 >> 2] | 0;
+  if (i2 >>> 0 > i12 >>> 0) {
+   i31 = i2 - i12 | 0;
+   HEAP32[14484 >> 2] = i31;
+   i32 = HEAP32[14496 >> 2] | 0;
+   HEAP32[14496 >> 2] = i32 + i12;
+   HEAP32[i32 + (i12 + 4) >> 2] = i31 | 1;
+   HEAP32[i32 + 4 >> 2] = i12 | 3;
+   i32 = i32 + 8 | 0;
+   STACKTOP = i1;
+   return i32 | 0;
+  }
+ }
+ HEAP32[(___errno_location() | 0) >> 2] = 12;
+ i32 = 0;
+ STACKTOP = i1;
+ return i32 | 0;
+}
+function _deflate(i2, i10) {
+ i2 = i2 | 0;
+ i10 = i10 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, i36 = 0, i37 = 0;
+ i1 = STACKTOP;
+ if ((i2 | 0) == 0) {
+  i37 = -2;
+  STACKTOP = i1;
+  return i37 | 0;
+ }
+ i5 = i2 + 28 | 0;
+ i7 = HEAP32[i5 >> 2] | 0;
+ if ((i7 | 0) == 0 | i10 >>> 0 > 5) {
+  i37 = -2;
+  STACKTOP = i1;
+  return i37 | 0;
+ }
+ i4 = i2 + 12 | 0;
+ do {
+  if ((HEAP32[i4 >> 2] | 0) != 0) {
+   if ((HEAP32[i2 >> 2] | 0) == 0 ? (HEAP32[i2 + 4 >> 2] | 0) != 0 : 0) {
+    break;
+   }
+   i11 = i7 + 4 | 0;
+   i29 = HEAP32[i11 >> 2] | 0;
+   i9 = (i10 | 0) == 4;
+   if ((i29 | 0) != 666 | i9) {
+    i3 = i2 + 16 | 0;
+    if ((HEAP32[i3 >> 2] | 0) == 0) {
+     HEAP32[i2 + 24 >> 2] = HEAP32[3180 >> 2];
+     i37 = -5;
+     STACKTOP = i1;
+     return i37 | 0;
+    }
+    HEAP32[i7 >> 2] = i2;
+    i8 = i7 + 40 | 0;
+    i18 = HEAP32[i8 >> 2] | 0;
+    HEAP32[i8 >> 2] = i10;
+    do {
+     if ((i29 | 0) == 42) {
+      if ((HEAP32[i7 + 24 >> 2] | 0) != 2) {
+       i17 = (HEAP32[i7 + 48 >> 2] << 12) + -30720 | 0;
+       if ((HEAP32[i7 + 136 >> 2] | 0) <= 1 ? (i28 = HEAP32[i7 + 132 >> 2] | 0, (i28 | 0) >= 2) : 0) {
+        if ((i28 | 0) < 6) {
+         i28 = 64;
+        } else {
+         i28 = (i28 | 0) == 6 ? 128 : 192;
+        }
+       } else {
+        i28 = 0;
+       }
+       i28 = i28 | i17;
+       i17 = i7 + 108 | 0;
+       i37 = (HEAP32[i17 >> 2] | 0) == 0 ? i28 : i28 | 32;
+       HEAP32[i11 >> 2] = 113;
+       i29 = i7 + 20 | 0;
+       i30 = HEAP32[i29 >> 2] | 0;
+       HEAP32[i29 >> 2] = i30 + 1;
+       i28 = i7 + 8 | 0;
+       HEAP8[(HEAP32[i28 >> 2] | 0) + i30 | 0] = i37 >>> 8;
+       i30 = HEAP32[i29 >> 2] | 0;
+       HEAP32[i29 >> 2] = i30 + 1;
+       HEAP8[(HEAP32[i28 >> 2] | 0) + i30 | 0] = (i37 | ((i37 >>> 0) % 31 | 0)) ^ 31;
+       i30 = i2 + 48 | 0;
+       if ((HEAP32[i17 >> 2] | 0) != 0) {
+        i37 = HEAP32[i30 >> 2] | 0;
+        i36 = HEAP32[i29 >> 2] | 0;
+        HEAP32[i29 >> 2] = i36 + 1;
+        HEAP8[(HEAP32[i28 >> 2] | 0) + i36 | 0] = i37 >>> 24;
+        i36 = HEAP32[i29 >> 2] | 0;
+        HEAP32[i29 >> 2] = i36 + 1;
+        HEAP8[(HEAP32[i28 >> 2] | 0) + i36 | 0] = i37 >>> 16;
+        i36 = HEAP32[i30 >> 2] | 0;
+        i37 = HEAP32[i29 >> 2] | 0;
+        HEAP32[i29 >> 2] = i37 + 1;
+        HEAP8[(HEAP32[i28 >> 2] | 0) + i37 | 0] = i36 >>> 8;
+        i37 = HEAP32[i29 >> 2] | 0;
+        HEAP32[i29 >> 2] = i37 + 1;
+        HEAP8[(HEAP32[i28 >> 2] | 0) + i37 | 0] = i36;
+       }
+       HEAP32[i30 >> 2] = _adler32(0, 0, 0) | 0;
+       i31 = HEAP32[i11 >> 2] | 0;
+       i17 = 32;
+       break;
+      }
+      i32 = i2 + 48 | 0;
+      HEAP32[i32 >> 2] = _crc32(0, 0, 0) | 0;
+      i30 = i7 + 20 | 0;
+      i28 = HEAP32[i30 >> 2] | 0;
+      HEAP32[i30 >> 2] = i28 + 1;
+      i29 = i7 + 8 | 0;
+      HEAP8[(HEAP32[i29 >> 2] | 0) + i28 | 0] = 31;
+      i28 = HEAP32[i30 >> 2] | 0;
+      HEAP32[i30 >> 2] = i28 + 1;
+      HEAP8[(HEAP32[i29 >> 2] | 0) + i28 | 0] = -117;
+      i28 = HEAP32[i30 >> 2] | 0;
+      HEAP32[i30 >> 2] = i28 + 1;
+      HEAP8[(HEAP32[i29 >> 2] | 0) + i28 | 0] = 8;
+      i28 = i7 + 28 | 0;
+      i33 = HEAP32[i28 >> 2] | 0;
+      if ((i33 | 0) == 0) {
+       i22 = HEAP32[i30 >> 2] | 0;
+       HEAP32[i30 >> 2] = i22 + 1;
+       HEAP8[(HEAP32[i29 >> 2] | 0) + i22 | 0] = 0;
+       i22 = HEAP32[i30 >> 2] | 0;
+       HEAP32[i30 >> 2] = i22 + 1;
+       HEAP8[(HEAP32[i29 >> 2] | 0) + i22 | 0] = 0;
+       i22 = HEAP32[i30 >> 2] | 0;
+       HEAP32[i30 >> 2] = i22 + 1;
+       HEAP8[(HEAP32[i29 >> 2] | 0) + i22 | 0] = 0;
+       i22 = HEAP32[i30 >> 2] | 0;
+       HEAP32[i30 >> 2] = i22 + 1;
+       HEAP8[(HEAP32[i29 >> 2] | 0) + i22 | 0] = 0;
+       i22 = HEAP32[i30 >> 2] | 0;
+       HEAP32[i30 >> 2] = i22 + 1;
+       HEAP8[(HEAP32[i29 >> 2] | 0) + i22 | 0] = 0;
+       i22 = HEAP32[i7 + 132 >> 2] | 0;
+       if ((i22 | 0) != 9) {
+        if ((HEAP32[i7 + 136 >> 2] | 0) > 1) {
+         i22 = 4;
+        } else {
+         i22 = (i22 | 0) < 2 ? 4 : 0;
+        }
+       } else {
+        i22 = 2;
+       }
+       i37 = HEAP32[i30 >> 2] | 0;
+       HEAP32[i30 >> 2] = i37 + 1;
+       HEAP8[(HEAP32[i29 >> 2] | 0) + i37 | 0] = i22;
+       i37 = HEAP32[i30 >> 2] | 0;
+       HEAP32[i30 >> 2] = i37 + 1;
+       HEAP8[(HEAP32[i29 >> 2] | 0) + i37 | 0] = 3;
+       HEAP32[i11 >> 2] = 113;
+       break;
+      }
+      i37 = (((HEAP32[i33 + 44 >> 2] | 0) != 0 ? 2 : 0) | (HEAP32[i33 >> 2] | 0) != 0 | ((HEAP32[i33 + 16 >> 2] | 0) == 0 ? 0 : 4) | ((HEAP32[i33 + 28 >> 2] | 0) == 0 ? 0 : 8) | ((HEAP32[i33 + 36 >> 2] | 0) == 0 ? 0 : 16)) & 255;
+      i17 = HEAP32[i30 >> 2] | 0;
+      HEAP32[i30 >> 2] = i17 + 1;
+      HEAP8[(HEAP32[i29 >> 2] | 0) + i17 | 0] = i37;
+      i17 = HEAP32[(HEAP32[i28 >> 2] | 0) + 4 >> 2] & 255;
+      i37 = HEAP32[i30 >> 2] | 0;
+      HEAP32[i30 >> 2] = i37 + 1;
+      HEAP8[(HEAP32[i29 >> 2] | 0) + i37 | 0] = i17;
+      i37 = (HEAP32[(HEAP32[i28 >> 2] | 0) + 4 >> 2] | 0) >>> 8 & 255;
+      i17 = HEAP32[i30 >> 2] | 0;
+      HEAP32[i30 >> 2] = i17 + 1;
+      HEAP8[(HEAP32[i29 >> 2] | 0) + i17 | 0] = i37;
+      i17 = (HEAP32[(HEAP32[i28 >> 2] | 0) + 4 >> 2] | 0) >>> 16 & 255;
+      i37 = HEAP32[i30 >> 2] | 0;
+      HEAP32[i30 >> 2] = i37 + 1;
+      HEAP8[(HEAP32[i29 >> 2] | 0) + i37 | 0] = i17;
+      i37 = (HEAP32[(HEAP32[i28 >> 2] | 0) + 4 >> 2] | 0) >>> 24 & 255;
+      i17 = HEAP32[i30 >> 2] | 0;
+      HEAP32[i30 >> 2] = i17 + 1;
+      HEAP8[(HEAP32[i29 >> 2] | 0) + i17 | 0] = i37;
+      i17 = HEAP32[i7 + 132 >> 2] | 0;
+      if ((i17 | 0) != 9) {
+       if ((HEAP32[i7 + 136 >> 2] | 0) > 1) {
+        i17 = 4;
+       } else {
+        i17 = (i17 | 0) < 2 ? 4 : 0;
+       }
+      } else {
+       i17 = 2;
+      }
+      i37 = HEAP32[i30 >> 2] | 0;
+      HEAP32[i30 >> 2] = i37 + 1;
+      HEAP8[(HEAP32[i29 >> 2] | 0) + i37 | 0] = i17;
+      i37 = HEAP32[(HEAP32[i28 >> 2] | 0) + 12 >> 2] & 255;
+      i17 = HEAP32[i30 >> 2] | 0;
+      HEAP32[i30 >> 2] = i17 + 1;
+      HEAP8[(HEAP32[i29 >> 2] | 0) + i17 | 0] = i37;
+      i17 = HEAP32[i28 >> 2] | 0;
+      if ((HEAP32[i17 + 16 >> 2] | 0) != 0) {
+       i17 = HEAP32[i17 + 20 >> 2] & 255;
+       i37 = HEAP32[i30 >> 2] | 0;
+       HEAP32[i30 >> 2] = i37 + 1;
+       HEAP8[(HEAP32[i29 >> 2] | 0) + i37 | 0] = i17;
+       i37 = (HEAP32[(HEAP32[i28 >> 2] | 0) + 20 >> 2] | 0) >>> 8 & 255;
+       i17 = HEAP32[i30 >> 2] | 0;
+       HEAP32[i30 >> 2] = i17 + 1;
+       HEAP8[(HEAP32[i29 >> 2] | 0) + i17 | 0] = i37;
+       i17 = HEAP32[i28 >> 2] | 0;
+      }
+      if ((HEAP32[i17 + 44 >> 2] | 0) != 0) {
+       HEAP32[i32 >> 2] = _crc32(HEAP32[i32 >> 2] | 0, HEAP32[i29 >> 2] | 0, HEAP32[i30 >> 2] | 0) | 0;
+      }
+      HEAP32[i7 + 32 >> 2] = 0;
+      HEAP32[i11 >> 2] = 69;
+      i17 = 34;
+     } else {
+      i31 = i29;
+      i17 = 32;
+     }
+    } while (0);
+    if ((i17 | 0) == 32) {
+     if ((i31 | 0) == 69) {
+      i28 = i7 + 28 | 0;
+      i17 = 34;
+     } else {
+      i17 = 55;
+     }
+    }
+    do {
+     if ((i17 | 0) == 34) {
+      i37 = HEAP32[i28 >> 2] | 0;
+      if ((HEAP32[i37 + 16 >> 2] | 0) == 0) {
+       HEAP32[i11 >> 2] = 73;
+       i17 = 57;
+       break;
+      }
+      i29 = i7 + 20 | 0;
+      i34 = HEAP32[i29 >> 2] | 0;
+      i17 = i7 + 32 | 0;
+      i36 = HEAP32[i17 >> 2] | 0;
+      L55 : do {
+       if (i36 >>> 0 < (HEAP32[i37 + 20 >> 2] & 65535) >>> 0) {
+        i30 = i7 + 12 | 0;
+        i32 = i2 + 48 | 0;
+        i31 = i7 + 8 | 0;
+        i33 = i2 + 20 | 0;
+        i35 = i34;
+        while (1) {
+         if ((i35 | 0) == (HEAP32[i30 >> 2] | 0)) {
+          if ((HEAP32[i37 + 44 >> 2] | 0) != 0 & i35 >>> 0 > i34 >>> 0) {
+           HEAP32[i32 >> 2] = _crc32(HEAP32[i32 >> 2] | 0, (HEAP32[i31 >> 2] | 0) + i34 | 0, i35 - i34 | 0) | 0;
+          }
+          i34 = HEAP32[i5 >> 2] | 0;
+          i35 = HEAP32[i34 + 20 >> 2] | 0;
+          i36 = HEAP32[i3 >> 2] | 0;
+          i35 = i35 >>> 0 > i36 >>> 0 ? i36 : i35;
+          if ((i35 | 0) != 0 ? (_memcpy(HEAP32[i4 >> 2] | 0, HEAP32[i34 + 16 >> 2] | 0, i35 | 0) | 0, HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + i35, i27 = (HEAP32[i5 >> 2] | 0) + 16 | 0, HEAP32[i27 >> 2] = (HEAP32[i27 >> 2] | 0) + i35, HEAP32[i33 >> 2] = (HEAP32[i33 >> 2] | 0) + i35, HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) - i35, i27 = HEAP32[i5 >> 2] | 0, i36 = i27 + 20 | 0, i37 = HEAP32[i36 >> 2] | 0, HEAP32[i36 >> 2] = i37 - i35, (i37 | 0) == (i35 | 0)) : 0) {
+           HEAP32[i27 + 16 >> 2] = HEAP32[i27 + 8 >> 2];
+          }
+          i34 = HEAP32[i29 >> 2] | 0;
+          if ((i34 | 0) == (HEAP32[i30 >> 2] | 0)) {
+           break;
+          }
+          i37 = HEAP32[i28 >> 2] | 0;
+          i36 = HEAP32[i17 >> 2] | 0;
+          i35 = i34;
+         }
+         i36 = HEAP8[(HEAP32[i37 + 16 >> 2] | 0) + i36 | 0] | 0;
+         HEAP32[i29 >> 2] = i35 + 1;
+         HEAP8[(HEAP32[i31 >> 2] | 0) + i35 | 0] = i36;
+         i36 = (HEAP32[i17 >> 2] | 0) + 1 | 0;
+         HEAP32[i17 >> 2] = i36;
+         i37 = HEAP32[i28 >> 2] | 0;
+         if (!(i36 >>> 0 < (HEAP32[i37 + 20 >> 2] & 65535) >>> 0)) {
+          break L55;
+         }
+         i35 = HEAP32[i29 >> 2] | 0;
+        }
+        i37 = HEAP32[i28 >> 2] | 0;
+       }
+      } while (0);
+      if ((HEAP32[i37 + 44 >> 2] | 0) != 0 ? (i26 = HEAP32[i29 >> 2] | 0, i26 >>> 0 > i34 >>> 0) : 0) {
+       i37 = i2 + 48 | 0;
+       HEAP32[i37 >> 2] = _crc32(HEAP32[i37 >> 2] | 0, (HEAP32[i7 + 8 >> 2] | 0) + i34 | 0, i26 - i34 | 0) | 0;
+       i37 = HEAP32[i28 >> 2] | 0;
+      }
+      if ((HEAP32[i17 >> 2] | 0) == (HEAP32[i37 + 20 >> 2] | 0)) {
+       HEAP32[i17 >> 2] = 0;
+       HEAP32[i11 >> 2] = 73;
+       i17 = 57;
+       break;
+      } else {
+       i31 = HEAP32[i11 >> 2] | 0;
+       i17 = 55;
+       break;
+      }
+     }
+    } while (0);
+    if ((i17 | 0) == 55) {
+     if ((i31 | 0) == 73) {
+      i37 = HEAP32[i7 + 28 >> 2] | 0;
+      i17 = 57;
+     } else {
+      i17 = 76;
+     }
+    }
+    do {
+     if ((i17 | 0) == 57) {
+      i26 = i7 + 28 | 0;
+      if ((HEAP32[i37 + 28 >> 2] | 0) == 0) {
+       HEAP32[i11 >> 2] = 91;
+       i17 = 78;
+       break;
+      }
+      i27 = i7 + 20 | 0;
+      i35 = HEAP32[i27 >> 2] | 0;
+      i32 = i7 + 12 | 0;
+      i29 = i2 + 48 | 0;
+      i28 = i7 + 8 | 0;
+      i31 = i2 + 20 | 0;
+      i30 = i7 + 32 | 0;
+      i33 = i35;
+      while (1) {
+       if ((i33 | 0) == (HEAP32[i32 >> 2] | 0)) {
+        if ((HEAP32[(HEAP32[i26 >> 2] | 0) + 44 >> 2] | 0) != 0 & i33 >>> 0 > i35 >>> 0) {
+         HEAP32[i29 >> 2] = _crc32(HEAP32[i29 >> 2] | 0, (HEAP32[i28 >> 2] | 0) + i35 | 0, i33 - i35 | 0) | 0;
+        }
+        i33 = HEAP32[i5 >> 2] | 0;
+        i34 = HEAP32[i33 + 20 >> 2] | 0;
+        i35 = HEAP32[i3 >> 2] | 0;
+        i34 = i34 >>> 0 > i35 >>> 0 ? i35 : i34;
+        if ((i34 | 0) != 0 ? (_memcpy(HEAP32[i4 >> 2] | 0, HEAP32[i33 + 16 >> 2] | 0, i34 | 0) | 0, HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + i34, i25 = (HEAP32[i5 >> 2] | 0) + 16 | 0, HEAP32[i25 >> 2] = (HEAP32[i25 >> 2] | 0) + i34, HEAP32[i31 >> 2] = (HEAP32[i31 >> 2] | 0) + i34, HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) - i34, i25 = HEAP32[i5 >> 2] | 0, i36 = i25 + 20 | 0, i37 = HEAP32[i36 >> 2] | 0, HEAP32[i36 >> 2] = i37 - i34, (i37 | 0) == (i34 | 0)) : 0) {
+         HEAP32[i25 + 16 >> 2] = HEAP32[i25 + 8 >> 2];
+        }
+        i35 = HEAP32[i27 >> 2] | 0;
+        if ((i35 | 0) == (HEAP32[i32 >> 2] | 0)) {
+         i25 = 1;
+         break;
+        } else {
+         i33 = i35;
+        }
+       }
+       i34 = HEAP32[i30 >> 2] | 0;
+       HEAP32[i30 >> 2] = i34 + 1;
+       i34 = HEAP8[(HEAP32[(HEAP32[i26 >> 2] | 0) + 28 >> 2] | 0) + i34 | 0] | 0;
+       HEAP32[i27 >> 2] = i33 + 1;
+       HEAP8[(HEAP32[i28 >> 2] | 0) + i33 | 0] = i34;
+       if (i34 << 24 >> 24 == 0) {
+        i17 = 68;
+        break;
+       }
+       i33 = HEAP32[i27 >> 2] | 0;
+      }
+      if ((i17 | 0) == 68) {
+       i25 = i34 & 255;
+      }
+      if ((HEAP32[(HEAP32[i26 >> 2] | 0) + 44 >> 2] | 0) != 0 ? (i24 = HEAP32[i27 >> 2] | 0, i24 >>> 0 > i35 >>> 0) : 0) {
+       HEAP32[i29 >> 2] = _crc32(HEAP32[i29 >> 2] | 0, (HEAP32[i28 >> 2] | 0) + i35 | 0, i24 - i35 | 0) | 0;
+      }
+      if ((i25 | 0) == 0) {
+       HEAP32[i30 >> 2] = 0;
+       HEAP32[i11 >> 2] = 91;
+       i17 = 78;
+       break;
+      } else {
+       i31 = HEAP32[i11 >> 2] | 0;
+       i17 = 76;
+       break;
+      }
+     }
+    } while (0);
+    if ((i17 | 0) == 76) {
+     if ((i31 | 0) == 91) {
+      i26 = i7 + 28 | 0;
+      i17 = 78;
+     } else {
+      i17 = 97;
+     }
+    }
+    do {
+     if ((i17 | 0) == 78) {
+      if ((HEAP32[(HEAP32[i26 >> 2] | 0) + 36 >> 2] | 0) == 0) {
+       HEAP32[i11 >> 2] = 103;
+       i17 = 99;
+       break;
+      }
+      i24 = i7 + 20 | 0;
+      i32 = HEAP32[i24 >> 2] | 0;
+      i29 = i7 + 12 | 0;
+      i27 = i2 + 48 | 0;
+      i25 = i7 + 8 | 0;
+      i28 = i2 + 20 | 0;
+      i30 = i7 + 32 | 0;
+      i31 = i32;
+      while (1) {
+       if ((i31 | 0) == (HEAP32[i29 >> 2] | 0)) {
+        if ((HEAP32[(HEAP32[i26 >> 2] | 0) + 44 >> 2] | 0) != 0 & i31 >>> 0 > i32 >>> 0) {
+         HEAP32[i27 >> 2] = _crc32(HEAP32[i27 >> 2] | 0, (HEAP32[i25 >> 2] | 0) + i32 | 0, i31 - i32 | 0) | 0;
+        }
+        i31 = HEAP32[i5 >> 2] | 0;
+        i33 = HEAP32[i31 + 20 >> 2] | 0;
+        i32 = HEAP32[i3 >> 2] | 0;
+        i32 = i33 >>> 0 > i32 >>> 0 ? i32 : i33;
+        if ((i32 | 0) != 0 ? (_memcpy(HEAP32[i4 >> 2] | 0, HEAP32[i31 + 16 >> 2] | 0, i32 | 0) | 0, HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + i32, i23 = (HEAP32[i5 >> 2] | 0) + 16 | 0, HEAP32[i23 >> 2] = (HEAP32[i23 >> 2] | 0) + i32, HEAP32[i28 >> 2] = (HEAP32[i28 >> 2] | 0) + i32, HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) - i32, i23 = HEAP32[i5 >> 2] | 0, i36 = i23 + 20 | 0, i37 = HEAP32[i36 >> 2] | 0, HEAP32[i36 >> 2] = i37 - i32, (i37 | 0) == (i32 | 0)) : 0) {
+         HEAP32[i23 + 16 >> 2] = HEAP32[i23 + 8 >> 2];
+        }
+        i32 = HEAP32[i24 >> 2] | 0;
+        if ((i32 | 0) == (HEAP32[i29 >> 2] | 0)) {
+         i23 = 1;
+         break;
+        } else {
+         i31 = i32;
+        }
+       }
+       i33 = HEAP32[i30 >> 2] | 0;
+       HEAP32[i30 >> 2] = i33 + 1;
+       i33 = HEAP8[(HEAP32[(HEAP32[i26 >> 2] | 0) + 36 >> 2] | 0) + i33 | 0] | 0;
+       HEAP32[i24 >> 2] = i31 + 1;
+       HEAP8[(HEAP32[i25 >> 2] | 0) + i31 | 0] = i33;
+       if (i33 << 24 >> 24 == 0) {
+        i17 = 89;
+        break;
+       }
+       i31 = HEAP32[i24 >> 2] | 0;
+      }
+      if ((i17 | 0) == 89) {
+       i23 = i33 & 255;
+      }
+      if ((HEAP32[(HEAP32[i26 >> 2] | 0) + 44 >> 2] | 0) != 0 ? (i22 = HEAP32[i24 >> 2] | 0, i22 >>> 0 > i32 >>> 0) : 0) {
+       HEAP32[i27 >> 2] = _crc32(HEAP32[i27 >> 2] | 0, (HEAP32[i25 >> 2] | 0) + i32 | 0, i22 - i32 | 0) | 0;
+      }
+      if ((i23 | 0) == 0) {
+       HEAP32[i11 >> 2] = 103;
+       i17 = 99;
+       break;
+      } else {
+       i31 = HEAP32[i11 >> 2] | 0;
+       i17 = 97;
+       break;
+      }
+     }
+    } while (0);
+    if ((i17 | 0) == 97 ? (i31 | 0) == 103 : 0) {
+     i26 = i7 + 28 | 0;
+     i17 = 99;
+    }
+    do {
+     if ((i17 | 0) == 99) {
+      if ((HEAP32[(HEAP32[i26 >> 2] | 0) + 44 >> 2] | 0) == 0) {
+       HEAP32[i11 >> 2] = 113;
+       break;
+      }
+      i17 = i7 + 20 | 0;
+      i22 = i7 + 12 | 0;
+      if ((((HEAP32[i17 >> 2] | 0) + 2 | 0) >>> 0 > (HEAP32[i22 >> 2] | 0) >>> 0 ? (i20 = HEAP32[i5 >> 2] | 0, i21 = HEAP32[i20 + 20 >> 2] | 0, i23 = HEAP32[i3 >> 2] | 0, i21 = i21 >>> 0 > i23 >>> 0 ? i23 : i21, (i21 | 0) != 0) : 0) ? (_memcpy(HEAP32[i4 >> 2] | 0, HEAP32[i20 + 16 >> 2] | 0, i21 | 0) | 0, HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + i21, i19 = (HEAP32[i5 >> 2] | 0) + 16 | 0, HEAP32[i19 >> 2] = (HEAP32[i19 >> 2] | 0) + i21, i19 = i2 + 20 | 0, HEAP32[i19 >> 2] = (HEAP32[i19 >> 2] | 0) + i21, HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) - i21, i19 = HEAP32[i5 >> 2] | 0, i36 = i19 + 20 | 0, i37 = HEAP32[i36 >> 2] | 0, HEAP32[i36 >> 2] = i37 - i21, (i37 | 0) == (i21 | 0)) : 0) {
+       HEAP32[i19 + 16 >> 2] = HEAP32[i19 + 8 >> 2];
+      }
+      i19 = HEAP32[i17 >> 2] | 0;
+      if (!((i19 + 2 | 0) >>> 0 > (HEAP32[i22 >> 2] | 0) >>> 0)) {
+       i37 = i2 + 48 | 0;
+       i34 = HEAP32[i37 >> 2] & 255;
+       HEAP32[i17 >> 2] = i19 + 1;
+       i35 = i7 + 8 | 0;
+       HEAP8[(HEAP32[i35 >> 2] | 0) + i19 | 0] = i34;
+       i34 = (HEAP32[i37 >> 2] | 0) >>> 8 & 255;
+       i36 = HEAP32[i17 >> 2] | 0;
+       HEAP32[i17 >> 2] = i36 + 1;
+       HEAP8[(HEAP32[i35 >> 2] | 0) + i36 | 0] = i34;
+       HEAP32[i37 >> 2] = _crc32(0, 0, 0) | 0;
+       HEAP32[i11 >> 2] = 113;
+      }
+     }
+    } while (0);
+    i19 = i7 + 20 | 0;
+    if ((HEAP32[i19 >> 2] | 0) == 0) {
+     if ((HEAP32[i2 + 4 >> 2] | 0) == 0 ? (i18 | 0) >= (i10 | 0) & (i10 | 0) != 4 : 0) {
+      HEAP32[i2 + 24 >> 2] = HEAP32[3180 >> 2];
+      i37 = -5;
+      STACKTOP = i1;
+      return i37 | 0;
+     }
+    } else {
+     i17 = HEAP32[i5 >> 2] | 0;
+     i20 = HEAP32[i17 + 20 >> 2] | 0;
+     i18 = HEAP32[i3 >> 2] | 0;
+     i20 = i20 >>> 0 > i18 >>> 0 ? i18 : i20;
+     if ((i20 | 0) != 0) {
+      _memcpy(HEAP32[i4 >> 2] | 0, HEAP32[i17 + 16 >> 2] | 0, i20 | 0) | 0;
+      HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + i20;
+      i17 = (HEAP32[i5 >> 2] | 0) + 16 | 0;
+      HEAP32[i17 >> 2] = (HEAP32[i17 >> 2] | 0) + i20;
+      i17 = i2 + 20 | 0;
+      HEAP32[i17 >> 2] = (HEAP32[i17 >> 2] | 0) + i20;
+      HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) - i20;
+      i17 = HEAP32[i5 >> 2] | 0;
+      i36 = i17 + 20 | 0;
+      i37 = HEAP32[i36 >> 2] | 0;
+      HEAP32[i36 >> 2] = i37 - i20;
+      if ((i37 | 0) == (i20 | 0)) {
+       HEAP32[i17 + 16 >> 2] = HEAP32[i17 + 8 >> 2];
+      }
+      i18 = HEAP32[i3 >> 2] | 0;
+     }
+     if ((i18 | 0) == 0) {
+      HEAP32[i8 >> 2] = -1;
+      i37 = 0;
+      STACKTOP = i1;
+      return i37 | 0;
+     }
+    }
+    i18 = (HEAP32[i11 >> 2] | 0) == 666;
+    i17 = (HEAP32[i2 + 4 >> 2] | 0) == 0;
+    if (i18) {
+     if (i17) {
+      i17 = 121;
+     } else {
+      HEAP32[i2 + 24 >> 2] = HEAP32[3180 >> 2];
+      i37 = -5;
+      STACKTOP = i1;
+      return i37 | 0;
+     }
+    } else {
+     if (i17) {
+      i17 = 121;
+     } else {
+      i17 = 124;
+     }
+    }
+    do {
+     if ((i17 | 0) == 121) {
+      if ((HEAP32[i7 + 116 >> 2] | 0) == 0) {
+       if ((i10 | 0) != 0) {
+        if (i18) {
+         break;
+        } else {
+         i17 = 124;
+         break;
+        }
+       } else {
+        i37 = 0;
+        STACKTOP = i1;
+        return i37 | 0;
+       }
+      } else {
+       i17 = 124;
+      }
+     }
+    } while (0);
+    do {
+     if ((i17 | 0) == 124) {
+      i18 = HEAP32[i7 + 136 >> 2] | 0;
+      L185 : do {
+       if ((i18 | 0) == 2) {
+        i22 = i7 + 116 | 0;
+        i18 = i7 + 96 | 0;
+        i13 = i7 + 108 | 0;
+        i14 = i7 + 56 | 0;
+        i21 = i7 + 5792 | 0;
+        i20 = i7 + 5796 | 0;
+        i24 = i7 + 5784 | 0;
+        i23 = i7 + 5788 | 0;
+        i12 = i7 + 92 | 0;
+        while (1) {
+         if ((HEAP32[i22 >> 2] | 0) == 0 ? (_fill_window(i7), (HEAP32[i22 >> 2] | 0) == 0) : 0) {
+          break;
+         }
+         HEAP32[i18 >> 2] = 0;
+         i37 = HEAP8[(HEAP32[i14 >> 2] | 0) + (HEAP32[i13 >> 2] | 0) | 0] | 0;
+         i26 = HEAP32[i21 >> 2] | 0;
+         HEAP16[(HEAP32[i20 >> 2] | 0) + (i26 << 1) >> 1] = 0;
+         HEAP32[i21 >> 2] = i26 + 1;
+         HEAP8[(HEAP32[i24 >> 2] | 0) + i26 | 0] = i37;
+         i37 = i7 + ((i37 & 255) << 2) + 148 | 0;
+         HEAP16[i37 >> 1] = (HEAP16[i37 >> 1] | 0) + 1 << 16 >> 16;
+         i37 = (HEAP32[i21 >> 2] | 0) == ((HEAP32[i23 >> 2] | 0) + -1 | 0);
+         HEAP32[i22 >> 2] = (HEAP32[i22 >> 2] | 0) + -1;
+         i26 = (HEAP32[i13 >> 2] | 0) + 1 | 0;
+         HEAP32[i13 >> 2] = i26;
+         if (!i37) {
+          continue;
+         }
+         i25 = HEAP32[i12 >> 2] | 0;
+         if ((i25 | 0) > -1) {
+          i27 = (HEAP32[i14 >> 2] | 0) + i25 | 0;
+         } else {
+          i27 = 0;
+         }
+         __tr_flush_block(i7, i27, i26 - i25 | 0, 0);
+         HEAP32[i12 >> 2] = HEAP32[i13 >> 2];
+         i26 = HEAP32[i7 >> 2] | 0;
+         i25 = i26 + 28 | 0;
+         i27 = HEAP32[i25 >> 2] | 0;
+         i30 = HEAP32[i27 + 20 >> 2] | 0;
+         i28 = i26 + 16 | 0;
+         i29 = HEAP32[i28 >> 2] | 0;
+         i29 = i30 >>> 0 > i29 >>> 0 ? i29 : i30;
+         if ((i29 | 0) != 0 ? (i16 = i26 + 12 | 0, _memcpy(HEAP32[i16 >> 2] | 0, HEAP32[i27 + 16 >> 2] | 0, i29 | 0) | 0, HEAP32[i16 >> 2] = (HEAP32[i16 >> 2] | 0) + i29, i16 = (HEAP32[i25 >> 2] | 0) + 16 | 0, HEAP32[i16 >> 2] = (HEAP32[i16 >> 2] | 0) + i29, i16 = i26 + 20 | 0, HEAP32[i16 >> 2] = (HEAP32[i16 >> 2] | 0) + i29, HEAP32[i28 >> 2] = (HEAP32[i28 >> 2] | 0) - i29, i16 = HEAP32[i25 >> 2] | 0, i36 = i16 + 20 | 0, i37 = HEAP32[i36 >> 2] | 0, HEAP32[i36 >> 2] = i37 - i29, (i37 | 0) == (i29 | 0)) : 0) {
+          HEAP32[i16 + 16 >> 2] = HEAP32[i16 + 8 >> 2];
+         }
+         if ((HEAP32[(HEAP32[i7 >> 2] | 0) + 16 >> 2] | 0) == 0) {
+          break L185;
+         }
+        }
+        if ((i10 | 0) != 0) {
+         i16 = HEAP32[i12 >> 2] | 0;
+         if ((i16 | 0) > -1) {
+          i14 = (HEAP32[i14 >> 2] | 0) + i16 | 0;
+         } else {
+          i14 = 0;
+         }
+         __tr_flush_block(i7, i14, (HEAP32[i13 >> 2] | 0) - i16 | 0, i9 & 1);
+         HEAP32[i12 >> 2] = HEAP32[i13 >> 2];
+         i14 = HEAP32[i7 >> 2] | 0;
+         i13 = i14 + 28 | 0;
+         i12 = HEAP32[i13 >> 2] | 0;
+         i17 = HEAP32[i12 + 20 >> 2] | 0;
+         i16 = i14 + 16 | 0;
+         i18 = HEAP32[i16 >> 2] | 0;
+         i17 = i17 >>> 0 > i18 >>> 0 ? i18 : i17;
+         if ((i17 | 0) != 0 ? (i15 = i14 + 12 | 0, _memcpy(HEAP32[i15 >> 2] | 0, HEAP32[i12 + 16 >> 2] | 0, i17 | 0) | 0, HEAP32[i15 >> 2] = (HEAP32[i15 >> 2] | 0) + i17, i15 = (HEAP32[i13 >> 2] | 0) + 16 | 0, HEAP32[i15 >> 2] = (HEAP32[i15 >> 2] | 0) + i17, i15 = i14 + 20 | 0, HEAP32[i15 >> 2] = (HEAP32[i15 >> 2] | 0) + i17, HEAP32[i16 >> 2] = (HEAP32[i16 >> 2] | 0) - i17, i15 = HEAP32[i13 >> 2] | 0, i36 = i15 + 20 | 0, i37 = HEAP32[i36 >> 2] | 0, HEAP32[i36 >> 2] = i37 - i17, (i37 | 0) == (i17 | 0)) : 0) {
+          HEAP32[i15 + 16 >> 2] = HEAP32[i15 + 8 >> 2];
+         }
+         if ((HEAP32[(HEAP32[i7 >> 2] | 0) + 16 >> 2] | 0) == 0) {
+          i12 = i9 ? 2 : 0;
+          i17 = 183;
+          break;
+         } else {
+          i12 = i9 ? 3 : 1;
+          i17 = 183;
+          break;
+         }
+        }
+       } else if ((i18 | 0) == 3) {
+        i27 = i7 + 116 | 0;
+        i26 = (i10 | 0) == 0;
+        i22 = i7 + 96 | 0;
+        i15 = i7 + 108 | 0;
+        i20 = i7 + 5792 | 0;
+        i24 = i7 + 5796 | 0;
+        i23 = i7 + 5784 | 0;
+        i21 = i7 + (HEAPU8[296] << 2) + 2440 | 0;
+        i25 = i7 + 5788 | 0;
+        i18 = i7 + 56 | 0;
+        i16 = i7 + 92 | 0;
+        while (1) {
+         i29 = HEAP32[i27 >> 2] | 0;
+         if (i29 >>> 0 < 258) {
+          _fill_window(i7);
+          i29 = HEAP32[i27 >> 2] | 0;
+          if (i29 >>> 0 < 258 & i26) {
+           break L185;
+          }
+          if ((i29 | 0) == 0) {
+           break;
+          }
+          HEAP32[i22 >> 2] = 0;
+          if (i29 >>> 0 > 2) {
+           i17 = 151;
+          } else {
+           i28 = HEAP32[i15 >> 2] | 0;
+           i17 = 166;
+          }
+         } else {
+          HEAP32[i22 >> 2] = 0;
+          i17 = 151;
+         }
+         if ((i17 | 0) == 151) {
+          i17 = 0;
+          i28 = HEAP32[i15 >> 2] | 0;
+          if ((i28 | 0) != 0) {
+           i31 = HEAP32[i18 >> 2] | 0;
+           i30 = HEAP8[i31 + (i28 + -1) | 0] | 0;
+           if ((i30 << 24 >> 24 == (HEAP8[i31 + i28 | 0] | 0) ? i30 << 24 >> 24 == (HEAP8[i31 + (i28 + 1) | 0] | 0) : 0) ? (i14 = i31 + (i28 + 2) | 0, i30 << 24 >> 24 == (HEAP8[i14] | 0)) : 0) {
+            i31 = i31 + (i28 + 258) | 0;
+            i32 = i14;
+            do {
+             i33 = i32 + 1 | 0;
+             if (!(i30 << 24 >> 24 == (HEAP8[i33] | 0))) {
+              i32 = i33;
+              break;
+             }
+             i33 = i32 + 2 | 0;
+             if (!(i30 << 24 >> 24 == (HEAP8[i33] | 0))) {
+              i32 = i33;
+              break;
+             }
+             i33 = i32 + 3 | 0;
+             if (!(i30 << 24 >> 24 == (HEAP8[i33] | 0))) {
+              i32 = i33;
+              break;
+             }
+             i33 = i32 + 4 | 0;
+             if (!(i30 << 24 >> 24 == (HEAP8[i33] | 0))) {
+              i32 = i33;
+              break;
+             }
+             i33 = i32 + 5 | 0;
+             if (!(i30 << 24 >> 24 == (HEAP8[i33] | 0))) {
+              i32 = i33;
+              break;
+             }
+             i33 = i32 + 6 | 0;
+             if (!(i30 << 24 >> 24 == (HEAP8[i33] | 0))) {
+              i32 = i33;
+              break;
+             }
+             i33 = i32 + 7 | 0;
+             if (!(i30 << 24 >> 24 == (HEAP8[i33] | 0))) {
+              i32 = i33;
+              break;
+             }
+             i32 = i32 + 8 | 0;
+            } while (i30 << 24 >> 24 == (HEAP8[i32] | 0) & i32 >>> 0 < i31 >>> 0);
+            i30 = i32 - i31 + 258 | 0;
+            i29 = i30 >>> 0 > i29 >>> 0 ? i29 : i30;
+            HEAP32[i22 >> 2] = i29;
+            if (i29 >>> 0 > 2) {
+             i29 = i29 + 253 | 0;
+             i28 = HEAP32[i20 >> 2] | 0;
+             HEAP16[(HEAP32[i24 >> 2] | 0) + (i28 << 1) >> 1] = 1;
+             HEAP32[i20 >> 2] = i28 + 1;
+             HEAP8[(HEAP32[i23 >> 2] | 0) + i28 | 0] = i29;
+             i29 = i7 + ((HEAPU8[808 + (i29 & 255) | 0] | 256) + 1 << 2) + 148 | 0;
+             HEAP16[i29 >> 1] = (HEAP16[i29 >> 1] | 0) + 1 << 16 >> 16;
+             HEAP16[i21 >> 1] = (HEAP16[i21 >> 1] | 0) + 1 << 16 >> 16;
+             i29 = (HEAP32[i20 >> 2] | 0) == ((HEAP32[i25 >> 2] | 0) + -1 | 0) | 0;
+             i28 = HEAP32[i22 >> 2] | 0;
+             HEAP32[i27 >> 2] = (HEAP32[i27 >> 2] | 0) - i28;
+             i28 = (HEAP32[i15 >> 2] | 0) + i28 | 0;
+             HEAP32[i15 >> 2] = i28;
+             HEAP32[i22 >> 2] = 0;
+            } else {
+             i17 = 166;
+            }
+           } else {
+            i17 = 166;
+           }
+          } else {
+           i28 = 0;
+           i17 = 166;
+          }
+         }
+         if ((i17 | 0) == 166) {
+          i17 = 0;
+          i29 = HEAP8[(HEAP32[i18 >> 2] | 0) + i28 | 0] | 0;
+          i28 = HEAP32[i20 >> 2] | 0;
+          HEAP16[(HEAP32[i24 >> 2] | 0) + (i28 << 1) >> 1] = 0;
+          HEAP32[i20 >> 2] = i28 + 1;
+          HEAP8[(HEAP32[i23 >> 2] | 0) + i28 | 0] = i29;
+          i29 = i7 + ((i29 & 255) << 2) + 148 | 0;
+          HEAP16[i29 >> 1] = (HEAP16[i29 >> 1] | 0) + 1 << 16 >> 16;
+          i29 = (HEAP32[i20 >> 2] | 0) == ((HEAP32[i25 >> 2] | 0) + -1 | 0) | 0;
+          HEAP32[i27 >> 2] = (HEAP32[i27 >> 2] | 0) + -1;
+          i28 = (HEAP32[i15 >> 2] | 0) + 1 | 0;
+          HEAP32[i15 >> 2] = i28;
+         }
+         if ((i29 | 0) == 0) {
+          continue;
+         }
+         i29 = HEAP32[i16 >> 2] | 0;
+         if ((i29 | 0) > -1) {
+          i30 = (HEAP32[i18 >> 2] | 0) + i29 | 0;
+         } else {
+          i30 = 0;
+         }
+         __tr_flush_block(i7, i30, i28 - i29 | 0, 0);
+         HEAP32[i16 >> 2] = HEAP32[i15 >> 2];
+         i30 = HEAP32[i7 >> 2] | 0;
+         i28 = i30 + 28 | 0;
+         i29 = HEAP32[i28 >> 2] | 0;
+         i33 = HEAP32[i29 + 20 >> 2] | 0;
+         i31 = i30 + 16 | 0;
+         i32 = HEAP32[i31 >> 2] | 0;
+         i32 = i33 >>> 0 > i32 >>> 0 ? i32 : i33;
+         if ((i32 | 0) != 0 ? (i13 = i30 + 12 | 0, _memcpy(HEAP32[i13 >> 2] | 0, HEAP32[i29 + 16 >> 2] | 0, i32 | 0) | 0, HEAP32[i13 >> 2] = (HEAP32[i13 >> 2] | 0) + i32, i13 = (HEAP32[i28 >> 2] | 0) + 16 | 0, HEAP32[i13 >> 2] = (HEAP32[i13 >> 2] | 0) + i32, i13 = i30 + 20 | 0, HEAP32[i13 >> 2] = (HEAP32[i13 >> 2] | 0) + i32, HEAP32[i31 >> 2] = (HEAP32[i31 >> 2] | 0) - i32, i13 = HEAP32[i28 >> 2] | 0, i36 = i13 + 20 | 0, i37 = HEAP32[i36 >> 2] | 0, HEAP32[i36 >> 2] = i37 - i32, (i37 | 0) == (i32 | 0)) : 0) {
+          HEAP32[i13 + 16 >> 2] = HEAP32[i13 + 8 >> 2];
+         }
+         if ((HEAP32[(HEAP32[i7 >> 2] | 0) + 16 >> 2] | 0) == 0) {
+          break L185;
+         }
+        }
+        i13 = HEAP32[i16 >> 2] | 0;
+        if ((i13 | 0) > -1) {
+         i14 = (HEAP32[i18 >> 2] | 0) + i13 | 0;
+        } else {
+         i14 = 0;
+        }
+        __tr_flush_block(i7, i14, (HEAP32[i15 >> 2] | 0) - i13 | 0, i9 & 1);
+        HEAP32[i16 >> 2] = HEAP32[i15 >> 2];
+        i14 = HEAP32[i7 >> 2] | 0;
+        i16 = i14 + 28 | 0;
+        i15 = HEAP32[i16 >> 2] | 0;
+        i18 = HEAP32[i15 + 20 >> 2] | 0;
+        i13 = i14 + 16 | 0;
+        i17 = HEAP32[i13 >> 2] | 0;
+        i17 = i18 >>> 0 > i17 >>> 0 ? i17 : i18;
+        if ((i17 | 0) != 0 ? (i12 = i14 + 12 | 0, _memcpy(HEAP32[i12 >> 2] | 0, HEAP32[i15 + 16 >> 2] | 0, i17 | 0) | 0, HEAP32[i12 >> 2] = (HEAP32[i12 >> 2] | 0) + i17, i12 = (HEAP32[i16 >> 2] | 0) + 16 | 0, HEAP32[i12 >> 2] = (HEAP32[i12 >> 2] | 0) + i17, i12 = i14 + 20 | 0, HEAP32[i12 >> 2] = (HEAP32[i12 >> 2] | 0) + i17, HEAP32[i13 >> 2] = (HEAP32[i13 >> 2] | 0) - i17, i12 = HEAP32[i16 >> 2] | 0, i36 = i12 + 20 | 0, i37 = HEAP32[i36 >> 2] | 0, HEAP32[i36 >> 2] = i37 - i17, (i37 | 0) == (i17 | 0)) : 0) {
+         HEAP32[i12 + 16 >> 2] = HEAP32[i12 + 8 >> 2];
+        }
+        if ((HEAP32[(HEAP32[i7 >> 2] | 0) + 16 >> 2] | 0) == 0) {
+         i12 = i9 ? 2 : 0;
+         i17 = 183;
+         break;
+        } else {
+         i12 = i9 ? 3 : 1;
+         i17 = 183;
+         break;
+        }
+       } else {
+        i12 = FUNCTION_TABLE_iii[HEAP32[184 + ((HEAP32[i7 + 132 >> 2] | 0) * 12 | 0) >> 2] & 3](i7, i10) | 0;
+        i17 = 183;
+       }
+      } while (0);
+      if ((i17 | 0) == 183) {
+       if ((i12 & -2 | 0) == 2) {
+        HEAP32[i11 >> 2] = 666;
+       }
+       if ((i12 & -3 | 0) != 0) {
+        if ((i12 | 0) != 1) {
+         break;
+        }
+        if ((i10 | 0) == 1) {
+         __tr_align(i7);
+        } else if (((i10 | 0) != 5 ? (__tr_stored_block(i7, 0, 0, 0), (i10 | 0) == 3) : 0) ? (i37 = HEAP32[i7 + 76 >> 2] | 0, i36 = HEAP32[i7 + 68 >> 2] | 0, HEAP16[i36 + (i37 + -1 << 1) >> 1] = 0, _memset(i36 | 0, 0, (i37 << 1) + -2 | 0) | 0, (HEAP32[i7 + 116 >> 2] | 0) == 0) : 0) {
+         HEAP32[i7 + 108 >> 2] = 0;
+         HEAP32[i7 + 92 >> 2] = 0;
+        }
+        i11 = HEAP32[i5 >> 2] | 0;
+        i12 = HEAP32[i11 + 20 >> 2] | 0;
+        i10 = HEAP32[i3 >> 2] | 0;
+        i12 = i12 >>> 0 > i10 >>> 0 ? i10 : i12;
+        if ((i12 | 0) != 0) {
+         _memcpy(HEAP32[i4 >> 2] | 0, HEAP32[i11 + 16 >> 2] | 0, i12 | 0) | 0;
+         HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + i12;
+         i10 = (HEAP32[i5 >> 2] | 0) + 16 | 0;
+         HEAP32[i10 >> 2] = (HEAP32[i10 >> 2] | 0) + i12;
+         i10 = i2 + 20 | 0;
+         HEAP32[i10 >> 2] = (HEAP32[i10 >> 2] | 0) + i12;
+         HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) - i12;
+         i10 = HEAP32[i5 >> 2] | 0;
+         i36 = i10 + 20 | 0;
+         i37 = HEAP32[i36 >> 2] | 0;
+         HEAP32[i36 >> 2] = i37 - i12;
+         if ((i37 | 0) == (i12 | 0)) {
+          HEAP32[i10 + 16 >> 2] = HEAP32[i10 + 8 >> 2];
+         }
+         i10 = HEAP32[i3 >> 2] | 0;
+        }
+        if ((i10 | 0) != 0) {
+         break;
+        }
+        HEAP32[i8 >> 2] = -1;
+        i37 = 0;
+        STACKTOP = i1;
+        return i37 | 0;
+       }
+      }
+      if ((HEAP32[i3 >> 2] | 0) != 0) {
+       i37 = 0;
+       STACKTOP = i1;
+       return i37 | 0;
+      }
+      HEAP32[i8 >> 2] = -1;
+      i37 = 0;
+      STACKTOP = i1;
+      return i37 | 0;
+     }
+    } while (0);
+    if (!i9) {
+     i37 = 0;
+     STACKTOP = i1;
+     return i37 | 0;
+    }
+    i8 = i7 + 24 | 0;
+    i10 = HEAP32[i8 >> 2] | 0;
+    if ((i10 | 0) < 1) {
+     i37 = 1;
+     STACKTOP = i1;
+     return i37 | 0;
+    }
+    i11 = i2 + 48 | 0;
+    i9 = HEAP32[i11 >> 2] | 0;
+    if ((i10 | 0) == 2) {
+     i34 = HEAP32[i19 >> 2] | 0;
+     HEAP32[i19 >> 2] = i34 + 1;
+     i36 = i7 + 8 | 0;
+     HEAP8[(HEAP32[i36 >> 2] | 0) + i34 | 0] = i9;
+     i34 = (HEAP32[i11 >> 2] | 0) >>> 8 & 255;
+     i35 = HEAP32[i19 >> 2] | 0;
+     HEAP32[i19 >> 2] = i35 + 1;
+     HEAP8[(HEAP32[i36 >> 2] | 0) + i35 | 0] = i34;
+     i35 = (HEAP32[i11 >> 2] | 0) >>> 16 & 255;
+     i34 = HEAP32[i19 >> 2] | 0;
+     HEAP32[i19 >> 2] = i34 + 1;
+     HEAP8[(HEAP32[i36 >> 2] | 0) + i34 | 0] = i35;
+     i34 = (HEAP32[i11 >> 2] | 0) >>> 24 & 255;
+     i35 = HEAP32[i19 >> 2] | 0;
+     HEAP32[i19 >> 2] = i35 + 1;
+     HEAP8[(HEAP32[i36 >> 2] | 0) + i35 | 0] = i34;
+     i35 = i2 + 8 | 0;
+     i34 = HEAP32[i35 >> 2] & 255;
+     i37 = HEAP32[i19 >> 2] | 0;
+     HEAP32[i19 >> 2] = i37 + 1;
+     HEAP8[(HEAP32[i36 >> 2] | 0) + i37 | 0] = i34;
+     i37 = (HEAP32[i35 >> 2] | 0) >>> 8 & 255;
+     i34 = HEAP32[i19 >> 2] | 0;
+     HEAP32[i19 >> 2] = i34 + 1;
+     HEAP8[(HEAP32[i36 >> 2] | 0) + i34 | 0] = i37;
+     i34 = (HEAP32[i35 >> 2] | 0) >>> 16 & 255;
+     i37 = HEAP32[i19 >> 2] | 0;
+     HEAP32[i19 >> 2] = i37 + 1;
+     HEAP8[(HEAP32[i36 >> 2] | 0) + i37 | 0] = i34;
+     i35 = (HEAP32[i35 >> 2] | 0) >>> 24 & 255;
+     i37 = HEAP32[i19 >> 2] | 0;
+     HEAP32[i19 >> 2] = i37 + 1;
+     HEAP8[(HEAP32[i36 >> 2] | 0) + i37 | 0] = i35;
+    } else {
+     i35 = HEAP32[i19 >> 2] | 0;
+     HEAP32[i19 >> 2] = i35 + 1;
+     i36 = i7 + 8 | 0;
+     HEAP8[(HEAP32[i36 >> 2] | 0) + i35 | 0] = i9 >>> 24;
+     i35 = HEAP32[i19 >> 2] | 0;
+     HEAP32[i19 >> 2] = i35 + 1;
+     HEAP8[(HEAP32[i36 >> 2] | 0) + i35 | 0] = i9 >>> 16;
+     i35 = HEAP32[i11 >> 2] | 0;
+     i37 = HEAP32[i19 >> 2] | 0;
+     HEAP32[i19 >> 2] = i37 + 1;
+     HEAP8[(HEAP32[i36 >> 2] | 0) + i37 | 0] = i35 >>> 8;
+     i37 = HEAP32[i19 >> 2] | 0;
+     HEAP32[i19 >> 2] = i37 + 1;
+     HEAP8[(HEAP32[i36 >> 2] | 0) + i37 | 0] = i35;
+    }
+    i7 = HEAP32[i5 >> 2] | 0;
+    i10 = HEAP32[i7 + 20 >> 2] | 0;
+    i9 = HEAP32[i3 >> 2] | 0;
+    i9 = i10 >>> 0 > i9 >>> 0 ? i9 : i10;
+    if ((i9 | 0) != 0 ? (_memcpy(HEAP32[i4 >> 2] | 0, HEAP32[i7 + 16 >> 2] | 0, i9 | 0) | 0, HEAP32[i4 >> 2] = (HEAP32[i4 >> 2] | 0) + i9, i6 = (HEAP32[i5 >> 2] | 0) + 16 | 0, HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i9, i6 = i2 + 20 | 0, HEAP32[i6 >> 2] = (HEAP32[i6 >> 2] | 0) + i9, HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) - i9, i6 = HEAP32[i5 >> 2] | 0, i36 = i6 + 20 | 0, i37 = HEAP32[i36 >> 2] | 0, HEAP32[i36 >> 2] = i37 - i9, (i37 | 0) == (i9 | 0)) : 0) {
+     HEAP32[i6 + 16 >> 2] = HEAP32[i6 + 8 >> 2];
+    }
+    i2 = HEAP32[i8 >> 2] | 0;
+    if ((i2 | 0) > 0) {
+     HEAP32[i8 >> 2] = 0 - i2;
+    }
+    i37 = (HEAP32[i19 >> 2] | 0) == 0 | 0;
+    STACKTOP = i1;
+    return i37 | 0;
+   }
+  }
+ } while (0);
+ HEAP32[i2 + 24 >> 2] = HEAP32[3168 >> 2];
+ i37 = -2;
+ STACKTOP = i1;
+ return i37 | 0;
+}
+function _free(i7) {
+ i7 = i7 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0;
+ i1 = STACKTOP;
+ if ((i7 | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i15 = i7 + -8 | 0;
+ i16 = HEAP32[14488 >> 2] | 0;
+ if (i15 >>> 0 < i16 >>> 0) {
+  _abort();
+ }
+ i13 = HEAP32[i7 + -4 >> 2] | 0;
+ i12 = i13 & 3;
+ if ((i12 | 0) == 1) {
+  _abort();
+ }
+ i8 = i13 & -8;
+ i6 = i7 + (i8 + -8) | 0;
+ do {
+  if ((i13 & 1 | 0) == 0) {
+   i19 = HEAP32[i15 >> 2] | 0;
+   if ((i12 | 0) == 0) {
+    STACKTOP = i1;
+    return;
+   }
+   i15 = -8 - i19 | 0;
+   i13 = i7 + i15 | 0;
+   i12 = i19 + i8 | 0;
+   if (i13 >>> 0 < i16 >>> 0) {
+    _abort();
+   }
+   if ((i13 | 0) == (HEAP32[14492 >> 2] | 0)) {
+    i2 = i7 + (i8 + -4) | 0;
+    if ((HEAP32[i2 >> 2] & 3 | 0) != 3) {
+     i2 = i13;
+     i11 = i12;
+     break;
+    }
+    HEAP32[14480 >> 2] = i12;
+    HEAP32[i2 >> 2] = HEAP32[i2 >> 2] & -2;
+    HEAP32[i7 + (i15 + 4) >> 2] = i12 | 1;
+    HEAP32[i6 >> 2] = i12;
+    STACKTOP = i1;
+    return;
+   }
+   i18 = i19 >>> 3;
+   if (i19 >>> 0 < 256) {
+    i2 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
+    i11 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
+    i14 = 14512 + (i18 << 1 << 2) | 0;
+    if ((i2 | 0) != (i14 | 0)) {
+     if (i2 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i2 + 12 >> 2] | 0) != (i13 | 0)) {
+      _abort();
+     }
+    }
+    if ((i11 | 0) == (i2 | 0)) {
+     HEAP32[3618] = HEAP32[3618] & ~(1 << i18);
+     i2 = i13;
+     i11 = i12;
+     break;
+    }
+    if ((i11 | 0) != (i14 | 0)) {
+     if (i11 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     i14 = i11 + 8 | 0;
+     if ((HEAP32[i14 >> 2] | 0) == (i13 | 0)) {
+      i17 = i14;
+     } else {
+      _abort();
+     }
+    } else {
+     i17 = i11 + 8 | 0;
+    }
+    HEAP32[i2 + 12 >> 2] = i11;
+    HEAP32[i17 >> 2] = i2;
+    i2 = i13;
+    i11 = i12;
+    break;
+   }
+   i17 = HEAP32[i7 + (i15 + 24) >> 2] | 0;
+   i18 = HEAP32[i7 + (i15 + 12) >> 2] | 0;
+   do {
+    if ((i18 | 0) == (i13 | 0)) {
+     i19 = i7 + (i15 + 20) | 0;
+     i18 = HEAP32[i19 >> 2] | 0;
+     if ((i18 | 0) == 0) {
+      i19 = i7 + (i15 + 16) | 0;
+      i18 = HEAP32[i19 >> 2] | 0;
+      if ((i18 | 0) == 0) {
+       i14 = 0;
+       break;
+      }
+     }
+     while (1) {
+      i21 = i18 + 20 | 0;
+      i20 = HEAP32[i21 >> 2] | 0;
+      if ((i20 | 0) != 0) {
+       i18 = i20;
+       i19 = i21;
+       continue;
+      }
+      i20 = i18 + 16 | 0;
+      i21 = HEAP32[i20 >> 2] | 0;
+      if ((i21 | 0) == 0) {
+       break;
+      } else {
+       i18 = i21;
+       i19 = i20;
+      }
+     }
+     if (i19 >>> 0 < i16 >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i19 >> 2] = 0;
+      i14 = i18;
+      break;
+     }
+    } else {
+     i19 = HEAP32[i7 + (i15 + 8) >> 2] | 0;
+     if (i19 >>> 0 < i16 >>> 0) {
+      _abort();
+     }
+     i16 = i19 + 12 | 0;
+     if ((HEAP32[i16 >> 2] | 0) != (i13 | 0)) {
+      _abort();
+     }
+     i20 = i18 + 8 | 0;
+     if ((HEAP32[i20 >> 2] | 0) == (i13 | 0)) {
+      HEAP32[i16 >> 2] = i18;
+      HEAP32[i20 >> 2] = i19;
+      i14 = i18;
+      break;
+     } else {
+      _abort();
+     }
+    }
+   } while (0);
+   if ((i17 | 0) != 0) {
+    i18 = HEAP32[i7 + (i15 + 28) >> 2] | 0;
+    i16 = 14776 + (i18 << 2) | 0;
+    if ((i13 | 0) == (HEAP32[i16 >> 2] | 0)) {
+     HEAP32[i16 >> 2] = i14;
+     if ((i14 | 0) == 0) {
+      HEAP32[14476 >> 2] = HEAP32[14476 >> 2] & ~(1 << i18);
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    } else {
+     if (i17 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i16 = i17 + 16 | 0;
+     if ((HEAP32[i16 >> 2] | 0) == (i13 | 0)) {
+      HEAP32[i16 >> 2] = i14;
+     } else {
+      HEAP32[i17 + 20 >> 2] = i14;
+     }
+     if ((i14 | 0) == 0) {
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    }
+    if (i14 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+     _abort();
+    }
+    HEAP32[i14 + 24 >> 2] = i17;
+    i16 = HEAP32[i7 + (i15 + 16) >> 2] | 0;
+    do {
+     if ((i16 | 0) != 0) {
+      if (i16 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i14 + 16 >> 2] = i16;
+       HEAP32[i16 + 24 >> 2] = i14;
+       break;
+      }
+     }
+    } while (0);
+    i15 = HEAP32[i7 + (i15 + 20) >> 2] | 0;
+    if ((i15 | 0) != 0) {
+     if (i15 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i14 + 20 >> 2] = i15;
+      HEAP32[i15 + 24 >> 2] = i14;
+      i2 = i13;
+      i11 = i12;
+      break;
+     }
+    } else {
+     i2 = i13;
+     i11 = i12;
+    }
+   } else {
+    i2 = i13;
+    i11 = i12;
+   }
+  } else {
+   i2 = i15;
+   i11 = i8;
+  }
+ } while (0);
+ if (!(i2 >>> 0 < i6 >>> 0)) {
+  _abort();
+ }
+ i12 = i7 + (i8 + -4) | 0;
+ i13 = HEAP32[i12 >> 2] | 0;
+ if ((i13 & 1 | 0) == 0) {
+  _abort();
+ }
+ if ((i13 & 2 | 0) == 0) {
+  if ((i6 | 0) == (HEAP32[14496 >> 2] | 0)) {
+   i21 = (HEAP32[14484 >> 2] | 0) + i11 | 0;
+   HEAP32[14484 >> 2] = i21;
+   HEAP32[14496 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i21 | 1;
+   if ((i2 | 0) != (HEAP32[14492 >> 2] | 0)) {
+    STACKTOP = i1;
+    return;
+   }
+   HEAP32[14492 >> 2] = 0;
+   HEAP32[14480 >> 2] = 0;
+   STACKTOP = i1;
+   return;
+  }
+  if ((i6 | 0) == (HEAP32[14492 >> 2] | 0)) {
+   i21 = (HEAP32[14480 >> 2] | 0) + i11 | 0;
+   HEAP32[14480 >> 2] = i21;
+   HEAP32[14492 >> 2] = i2;
+   HEAP32[i2 + 4 >> 2] = i21 | 1;
+   HEAP32[i2 + i21 >> 2] = i21;
+   STACKTOP = i1;
+   return;
+  }
+  i11 = (i13 & -8) + i11 | 0;
+  i12 = i13 >>> 3;
+  do {
+   if (!(i13 >>> 0 < 256)) {
+    i10 = HEAP32[i7 + (i8 + 16) >> 2] | 0;
+    i15 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
+    do {
+     if ((i15 | 0) == (i6 | 0)) {
+      i13 = i7 + (i8 + 12) | 0;
+      i12 = HEAP32[i13 >> 2] | 0;
+      if ((i12 | 0) == 0) {
+       i13 = i7 + (i8 + 8) | 0;
+       i12 = HEAP32[i13 >> 2] | 0;
+       if ((i12 | 0) == 0) {
+        i9 = 0;
+        break;
+       }
+      }
+      while (1) {
+       i14 = i12 + 20 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) != 0) {
+        i12 = i15;
+        i13 = i14;
+        continue;
+       }
+       i14 = i12 + 16 | 0;
+       i15 = HEAP32[i14 >> 2] | 0;
+       if ((i15 | 0) == 0) {
+        break;
+       } else {
+        i12 = i15;
+        i13 = i14;
+       }
+      }
+      if (i13 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i13 >> 2] = 0;
+       i9 = i12;
+       break;
+      }
+     } else {
+      i13 = HEAP32[i7 + i8 >> 2] | 0;
+      if (i13 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i14 = i13 + 12 | 0;
+      if ((HEAP32[i14 >> 2] | 0) != (i6 | 0)) {
+       _abort();
+      }
+      i12 = i15 + 8 | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+       HEAP32[i14 >> 2] = i15;
+       HEAP32[i12 >> 2] = i13;
+       i9 = i15;
+       break;
+      } else {
+       _abort();
+      }
+     }
+    } while (0);
+    if ((i10 | 0) != 0) {
+     i12 = HEAP32[i7 + (i8 + 20) >> 2] | 0;
+     i13 = 14776 + (i12 << 2) | 0;
+     if ((i6 | 0) == (HEAP32[i13 >> 2] | 0)) {
+      HEAP32[i13 >> 2] = i9;
+      if ((i9 | 0) == 0) {
+       HEAP32[14476 >> 2] = HEAP32[14476 >> 2] & ~(1 << i12);
+       break;
+      }
+     } else {
+      if (i10 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+       _abort();
+      }
+      i12 = i10 + 16 | 0;
+      if ((HEAP32[i12 >> 2] | 0) == (i6 | 0)) {
+       HEAP32[i12 >> 2] = i9;
+      } else {
+       HEAP32[i10 + 20 >> 2] = i9;
+      }
+      if ((i9 | 0) == 0) {
+       break;
+      }
+     }
+     if (i9 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     HEAP32[i9 + 24 >> 2] = i10;
+     i6 = HEAP32[i7 + (i8 + 8) >> 2] | 0;
+     do {
+      if ((i6 | 0) != 0) {
+       if (i6 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+        _abort();
+       } else {
+        HEAP32[i9 + 16 >> 2] = i6;
+        HEAP32[i6 + 24 >> 2] = i9;
+        break;
+       }
+      }
+     } while (0);
+     i6 = HEAP32[i7 + (i8 + 12) >> 2] | 0;
+     if ((i6 | 0) != 0) {
+      if (i6 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+       _abort();
+      } else {
+       HEAP32[i9 + 20 >> 2] = i6;
+       HEAP32[i6 + 24 >> 2] = i9;
+       break;
+      }
+     }
+    }
+   } else {
+    i9 = HEAP32[i7 + i8 >> 2] | 0;
+    i7 = HEAP32[i7 + (i8 | 4) >> 2] | 0;
+    i8 = 14512 + (i12 << 1 << 2) | 0;
+    if ((i9 | 0) != (i8 | 0)) {
+     if (i9 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     if ((HEAP32[i9 + 12 >> 2] | 0) != (i6 | 0)) {
+      _abort();
+     }
+    }
+    if ((i7 | 0) == (i9 | 0)) {
+     HEAP32[3618] = HEAP32[3618] & ~(1 << i12);
+     break;
+    }
+    if ((i7 | 0) != (i8 | 0)) {
+     if (i7 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+      _abort();
+     }
+     i8 = i7 + 8 | 0;
+     if ((HEAP32[i8 >> 2] | 0) == (i6 | 0)) {
+      i10 = i8;
+     } else {
+      _abort();
+     }
+    } else {
+     i10 = i7 + 8 | 0;
+    }
+    HEAP32[i9 + 12 >> 2] = i7;
+    HEAP32[i10 >> 2] = i9;
+   }
+  } while (0);
+  HEAP32[i2 + 4 >> 2] = i11 | 1;
+  HEAP32[i2 + i11 >> 2] = i11;
+  if ((i2 | 0) == (HEAP32[14492 >> 2] | 0)) {
+   HEAP32[14480 >> 2] = i11;
+   STACKTOP = i1;
+   return;
+  }
+ } else {
+  HEAP32[i12 >> 2] = i13 & -2;
+  HEAP32[i2 + 4 >> 2] = i11 | 1;
+  HEAP32[i2 + i11 >> 2] = i11;
+ }
+ i6 = i11 >>> 3;
+ if (i11 >>> 0 < 256) {
+  i7 = i6 << 1;
+  i3 = 14512 + (i7 << 2) | 0;
+  i8 = HEAP32[3618] | 0;
+  i6 = 1 << i6;
+  if ((i8 & i6 | 0) != 0) {
+   i6 = 14512 + (i7 + 2 << 2) | 0;
+   i7 = HEAP32[i6 >> 2] | 0;
+   if (i7 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+    _abort();
+   } else {
+    i4 = i6;
+    i5 = i7;
+   }
+  } else {
+   HEAP32[3618] = i8 | i6;
+   i4 = 14512 + (i7 + 2 << 2) | 0;
+   i5 = i3;
+  }
+  HEAP32[i4 >> 2] = i2;
+  HEAP32[i5 + 12 >> 2] = i2;
+  HEAP32[i2 + 8 >> 2] = i5;
+  HEAP32[i2 + 12 >> 2] = i3;
+  STACKTOP = i1;
+  return;
+ }
+ i4 = i11 >>> 8;
+ if ((i4 | 0) != 0) {
+  if (i11 >>> 0 > 16777215) {
+   i4 = 31;
+  } else {
+   i20 = (i4 + 1048320 | 0) >>> 16 & 8;
+   i21 = i4 << i20;
+   i19 = (i21 + 520192 | 0) >>> 16 & 4;
+   i21 = i21 << i19;
+   i4 = (i21 + 245760 | 0) >>> 16 & 2;
+   i4 = 14 - (i19 | i20 | i4) + (i21 << i4 >>> 15) | 0;
+   i4 = i11 >>> (i4 + 7 | 0) & 1 | i4 << 1;
+  }
+ } else {
+  i4 = 0;
+ }
+ i5 = 14776 + (i4 << 2) | 0;
+ HEAP32[i2 + 28 >> 2] = i4;
+ HEAP32[i2 + 20 >> 2] = 0;
+ HEAP32[i2 + 16 >> 2] = 0;
+ i7 = HEAP32[14476 >> 2] | 0;
+ i6 = 1 << i4;
+ L199 : do {
+  if ((i7 & i6 | 0) != 0) {
+   i5 = HEAP32[i5 >> 2] | 0;
+   if ((i4 | 0) == 31) {
+    i4 = 0;
+   } else {
+    i4 = 25 - (i4 >>> 1) | 0;
+   }
+   L204 : do {
+    if ((HEAP32[i5 + 4 >> 2] & -8 | 0) != (i11 | 0)) {
+     i4 = i11 << i4;
+     i7 = i5;
+     while (1) {
+      i6 = i7 + (i4 >>> 31 << 2) + 16 | 0;
+      i5 = HEAP32[i6 >> 2] | 0;
+      if ((i5 | 0) == 0) {
+       break;
+      }
+      if ((HEAP32[i5 + 4 >> 2] & -8 | 0) == (i11 | 0)) {
+       i3 = i5;
+       break L204;
+      } else {
+       i4 = i4 << 1;
+       i7 = i5;
+      }
+     }
+     if (i6 >>> 0 < (HEAP32[14488 >> 2] | 0) >>> 0) {
+      _abort();
+     } else {
+      HEAP32[i6 >> 2] = i2;
+      HEAP32[i2 + 24 >> 2] = i7;
+      HEAP32[i2 + 12 >> 2] = i2;
+      HEAP32[i2 + 8 >> 2] = i2;
+      break L199;
+     }
+    } else {
+     i3 = i5;
+    }
+   } while (0);
+   i5 = i3 + 8 | 0;
+   i4 = HEAP32[i5 >> 2] | 0;
+   i6 = HEAP32[14488 >> 2] | 0;
+   if (i3 >>> 0 < i6 >>> 0) {
+    _abort();
+   }
+   if (i4 >>> 0 < i6 >>> 0) {
+    _abort();
+   } else {
+    HEAP32[i4 + 12 >> 2] = i2;
+    HEAP32[i5 >> 2] = i2;
+    HEAP32[i2 + 8 >> 2] = i4;
+    HEAP32[i2 + 12 >> 2] = i3;
+    HEAP32[i2 + 24 >> 2] = 0;
+    break;
+   }
+  } else {
+   HEAP32[14476 >> 2] = i7 | i6;
+   HEAP32[i5 >> 2] = i2;
+   HEAP32[i2 + 24 >> 2] = i5;
+   HEAP32[i2 + 12 >> 2] = i2;
+   HEAP32[i2 + 8 >> 2] = i2;
+  }
+ } while (0);
+ i21 = (HEAP32[14504 >> 2] | 0) + -1 | 0;
+ HEAP32[14504 >> 2] = i21;
+ if ((i21 | 0) == 0) {
+  i2 = 14928 | 0;
+ } else {
+  STACKTOP = i1;
+  return;
+ }
+ while (1) {
+  i2 = HEAP32[i2 >> 2] | 0;
+  if ((i2 | 0) == 0) {
+   break;
+  } else {
+   i2 = i2 + 8 | 0;
+  }
+ }
+ HEAP32[14504 >> 2] = -1;
+ STACKTOP = i1;
+ return;
+}
+function _build_tree(i4, i9) {
+ i4 = i4 | 0;
+ i9 = i9 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 32 | 0;
+ i1 = i2;
+ i3 = HEAP32[i9 >> 2] | 0;
+ i7 = i9 + 8 | 0;
+ i11 = HEAP32[i7 >> 2] | 0;
+ i12 = HEAP32[i11 >> 2] | 0;
+ i11 = HEAP32[i11 + 12 >> 2] | 0;
+ i8 = i4 + 5200 | 0;
+ HEAP32[i8 >> 2] = 0;
+ i6 = i4 + 5204 | 0;
+ HEAP32[i6 >> 2] = 573;
+ if ((i11 | 0) > 0) {
+  i5 = -1;
+  i13 = 0;
+  do {
+   if ((HEAP16[i3 + (i13 << 2) >> 1] | 0) == 0) {
+    HEAP16[i3 + (i13 << 2) + 2 >> 1] = 0;
+   } else {
+    i5 = (HEAP32[i8 >> 2] | 0) + 1 | 0;
+    HEAP32[i8 >> 2] = i5;
+    HEAP32[i4 + (i5 << 2) + 2908 >> 2] = i13;
+    HEAP8[i4 + i13 + 5208 | 0] = 0;
+    i5 = i13;
+   }
+   i13 = i13 + 1 | 0;
+  } while ((i13 | 0) != (i11 | 0));
+  i14 = HEAP32[i8 >> 2] | 0;
+  if ((i14 | 0) < 2) {
+   i10 = 3;
+  }
+ } else {
+  i14 = 0;
+  i5 = -1;
+  i10 = 3;
+ }
+ if ((i10 | 0) == 3) {
+  i10 = i4 + 5800 | 0;
+  i13 = i4 + 5804 | 0;
+  if ((i12 | 0) == 0) {
+   do {
+    i12 = (i5 | 0) < 2;
+    i13 = i5 + 1 | 0;
+    i5 = i12 ? i13 : i5;
+    i23 = i12 ? i13 : 0;
+    i14 = i14 + 1 | 0;
+    HEAP32[i8 >> 2] = i14;
+    HEAP32[i4 + (i14 << 2) + 2908 >> 2] = i23;
+    HEAP16[i3 + (i23 << 2) >> 1] = 1;
+    HEAP8[i4 + i23 + 5208 | 0] = 0;
+    HEAP32[i10 >> 2] = (HEAP32[i10 >> 2] | 0) + -1;
+    i14 = HEAP32[i8 >> 2] | 0;
+   } while ((i14 | 0) < 2);
+  } else {
+   do {
+    i15 = (i5 | 0) < 2;
+    i16 = i5 + 1 | 0;
+    i5 = i15 ? i16 : i5;
+    i23 = i15 ? i16 : 0;
+    i14 = i14 + 1 | 0;
+    HEAP32[i8 >> 2] = i14;
+    HEAP32[i4 + (i14 << 2) + 2908 >> 2] = i23;
+    HEAP16[i3 + (i23 << 2) >> 1] = 1;
+    HEAP8[i4 + i23 + 5208 | 0] = 0;
+    HEAP32[i10 >> 2] = (HEAP32[i10 >> 2] | 0) + -1;
+    HEAP32[i13 >> 2] = (HEAP32[i13 >> 2] | 0) - (HEAPU16[i12 + (i23 << 2) + 2 >> 1] | 0);
+    i14 = HEAP32[i8 >> 2] | 0;
+   } while ((i14 | 0) < 2);
+  }
+ }
+ i10 = i9 + 4 | 0;
+ HEAP32[i10 >> 2] = i5;
+ i12 = HEAP32[i8 >> 2] | 0;
+ if ((i12 | 0) > 1) {
+  i18 = i12;
+  i13 = (i12 | 0) / 2 | 0;
+  do {
+   i12 = HEAP32[i4 + (i13 << 2) + 2908 >> 2] | 0;
+   i14 = i4 + i12 + 5208 | 0;
+   i17 = i13 << 1;
+   L21 : do {
+    if ((i17 | 0) > (i18 | 0)) {
+     i15 = i13;
+    } else {
+     i16 = i3 + (i12 << 2) | 0;
+     i15 = i13;
+     while (1) {
+      do {
+       if ((i17 | 0) < (i18 | 0)) {
+        i18 = i17 | 1;
+        i19 = HEAP32[i4 + (i18 << 2) + 2908 >> 2] | 0;
+        i22 = HEAP16[i3 + (i19 << 2) >> 1] | 0;
+        i20 = HEAP32[i4 + (i17 << 2) + 2908 >> 2] | 0;
+        i21 = HEAP16[i3 + (i20 << 2) >> 1] | 0;
+        if (!((i22 & 65535) < (i21 & 65535))) {
+         if (!(i22 << 16 >> 16 == i21 << 16 >> 16)) {
+          break;
+         }
+         if ((HEAPU8[i4 + i19 + 5208 | 0] | 0) > (HEAPU8[i4 + i20 + 5208 | 0] | 0)) {
+          break;
+         }
+        }
+        i17 = i18;
+       }
+      } while (0);
+      i19 = HEAP16[i16 >> 1] | 0;
+      i18 = HEAP32[i4 + (i17 << 2) + 2908 >> 2] | 0;
+      i20 = HEAP16[i3 + (i18 << 2) >> 1] | 0;
+      if ((i19 & 65535) < (i20 & 65535)) {
+       break L21;
+      }
+      if (i19 << 16 >> 16 == i20 << 16 >> 16 ? (HEAPU8[i14] | 0) <= (HEAPU8[i4 + i18 + 5208 | 0] | 0) : 0) {
+       break L21;
+      }
+      HEAP32[i4 + (i15 << 2) + 2908 >> 2] = i18;
+      i19 = i17 << 1;
+      i18 = HEAP32[i8 >> 2] | 0;
+      if ((i19 | 0) > (i18 | 0)) {
+       i15 = i17;
+       break;
+      } else {
+       i15 = i17;
+       i17 = i19;
+      }
+     }
+    }
+   } while (0);
+   HEAP32[i4 + (i15 << 2) + 2908 >> 2] = i12;
+   i13 = i13 + -1 | 0;
+   i18 = HEAP32[i8 >> 2] | 0;
+  } while ((i13 | 0) > 0);
+ } else {
+  i18 = i12;
+ }
+ i12 = i4 + 2912 | 0;
+ while (1) {
+  i13 = HEAP32[i12 >> 2] | 0;
+  i20 = i18 + -1 | 0;
+  HEAP32[i8 >> 2] = i20;
+  i14 = HEAP32[i4 + (i18 << 2) + 2908 >> 2] | 0;
+  HEAP32[i12 >> 2] = i14;
+  i15 = i4 + i14 + 5208 | 0;
+  L40 : do {
+   if ((i18 | 0) < 3) {
+    i17 = 1;
+   } else {
+    i16 = i3 + (i14 << 2) | 0;
+    i17 = 1;
+    i18 = 2;
+    while (1) {
+     do {
+      if ((i18 | 0) < (i20 | 0)) {
+       i22 = i18 | 1;
+       i21 = HEAP32[i4 + (i22 << 2) + 2908 >> 2] | 0;
+       i23 = HEAP16[i3 + (i21 << 2) >> 1] | 0;
+       i20 = HEAP32[i4 + (i18 << 2) + 2908 >> 2] | 0;
+       i19 = HEAP16[i3 + (i20 << 2) >> 1] | 0;
+       if (!((i23 & 65535) < (i19 & 65535))) {
+        if (!(i23 << 16 >> 16 == i19 << 16 >> 16)) {
+         break;
+        }
+        if ((HEAPU8[i4 + i21 + 5208 | 0] | 0) > (HEAPU8[i4 + i20 + 5208 | 0] | 0)) {
+         break;
+        }
+       }
+       i18 = i22;
+      }
+     } while (0);
+     i21 = HEAP16[i16 >> 1] | 0;
+     i20 = HEAP32[i4 + (i18 << 2) + 2908 >> 2] | 0;
+     i19 = HEAP16[i3 + (i20 << 2) >> 1] | 0;
+     if ((i21 & 65535) < (i19 & 65535)) {
+      break L40;
+     }
+     if (i21 << 16 >> 16 == i19 << 16 >> 16 ? (HEAPU8[i15] | 0) <= (HEAPU8[i4 + i20 + 5208 | 0] | 0) : 0) {
+      break L40;
+     }
+     HEAP32[i4 + (i17 << 2) + 2908 >> 2] = i20;
+     i19 = i18 << 1;
+     i20 = HEAP32[i8 >> 2] | 0;
+     if ((i19 | 0) > (i20 | 0)) {
+      i17 = i18;
+      break;
+     } else {
+      i17 = i18;
+      i18 = i19;
+     }
+    }
+   }
+  } while (0);
+  HEAP32[i4 + (i17 << 2) + 2908 >> 2] = i14;
+  i17 = HEAP32[i12 >> 2] | 0;
+  i14 = (HEAP32[i6 >> 2] | 0) + -1 | 0;
+  HEAP32[i6 >> 2] = i14;
+  HEAP32[i4 + (i14 << 2) + 2908 >> 2] = i13;
+  i14 = (HEAP32[i6 >> 2] | 0) + -1 | 0;
+  HEAP32[i6 >> 2] = i14;
+  HEAP32[i4 + (i14 << 2) + 2908 >> 2] = i17;
+  i14 = i3 + (i11 << 2) | 0;
+  HEAP16[i14 >> 1] = (HEAPU16[i3 + (i17 << 2) >> 1] | 0) + (HEAPU16[i3 + (i13 << 2) >> 1] | 0);
+  i18 = HEAP8[i4 + i13 + 5208 | 0] | 0;
+  i16 = HEAP8[i4 + i17 + 5208 | 0] | 0;
+  i15 = i4 + i11 + 5208 | 0;
+  HEAP8[i15] = (((i18 & 255) < (i16 & 255) ? i16 : i18) & 255) + 1;
+  i19 = i11 & 65535;
+  HEAP16[i3 + (i17 << 2) + 2 >> 1] = i19;
+  HEAP16[i3 + (i13 << 2) + 2 >> 1] = i19;
+  i13 = i11 + 1 | 0;
+  HEAP32[i12 >> 2] = i11;
+  i19 = HEAP32[i8 >> 2] | 0;
+  L56 : do {
+   if ((i19 | 0) < 2) {
+    i16 = 1;
+   } else {
+    i16 = 1;
+    i17 = 2;
+    while (1) {
+     do {
+      if ((i17 | 0) < (i19 | 0)) {
+       i21 = i17 | 1;
+       i22 = HEAP32[i4 + (i21 << 2) + 2908 >> 2] | 0;
+       i19 = HEAP16[i3 + (i22 << 2) >> 1] | 0;
+       i18 = HEAP32[i4 + (i17 << 2) + 2908 >> 2] | 0;
+       i20 = HEAP16[i3 + (i18 << 2) >> 1] | 0;
+       if (!((i19 & 65535) < (i20 & 65535))) {
+        if (!(i19 << 16 >> 16 == i20 << 16 >> 16)) {
+         break;
+        }
+        if ((HEAPU8[i4 + i22 + 5208 | 0] | 0) > (HEAPU8[i4 + i18 + 5208 | 0] | 0)) {
+         break;
+        }
+       }
+       i17 = i21;
+      }
+     } while (0);
+     i19 = HEAP16[i14 >> 1] | 0;
+     i20 = HEAP32[i4 + (i17 << 2) + 2908 >> 2] | 0;
+     i18 = HEAP16[i3 + (i20 << 2) >> 1] | 0;
+     if ((i19 & 65535) < (i18 & 65535)) {
+      break L56;
+     }
+     if (i19 << 16 >> 16 == i18 << 16 >> 16 ? (HEAPU8[i15] | 0) <= (HEAPU8[i4 + i20 + 5208 | 0] | 0) : 0) {
+      break L56;
+     }
+     HEAP32[i4 + (i16 << 2) + 2908 >> 2] = i20;
+     i18 = i17 << 1;
+     i19 = HEAP32[i8 >> 2] | 0;
+     if ((i18 | 0) > (i19 | 0)) {
+      i16 = i17;
+      break;
+     } else {
+      i16 = i17;
+      i17 = i18;
+     }
+    }
+   }
+  } while (0);
+  HEAP32[i4 + (i16 << 2) + 2908 >> 2] = i11;
+  i18 = HEAP32[i8 >> 2] | 0;
+  if ((i18 | 0) > 1) {
+   i11 = i13;
+  } else {
+   break;
+  }
+ }
+ i12 = HEAP32[i12 >> 2] | 0;
+ i8 = (HEAP32[i6 >> 2] | 0) + -1 | 0;
+ HEAP32[i6 >> 2] = i8;
+ HEAP32[i4 + (i8 << 2) + 2908 >> 2] = i12;
+ i8 = HEAP32[i9 >> 2] | 0;
+ i9 = HEAP32[i10 >> 2] | 0;
+ i7 = HEAP32[i7 >> 2] | 0;
+ i12 = HEAP32[i7 >> 2] | 0;
+ i11 = HEAP32[i7 + 4 >> 2] | 0;
+ i10 = HEAP32[i7 + 8 >> 2] | 0;
+ i7 = HEAP32[i7 + 16 >> 2] | 0;
+ i13 = i4 + 2876 | 0;
+ i14 = i13 + 32 | 0;
+ do {
+  HEAP16[i13 >> 1] = 0;
+  i13 = i13 + 2 | 0;
+ } while ((i13 | 0) < (i14 | 0));
+ i14 = HEAP32[i6 >> 2] | 0;
+ HEAP16[i8 + (HEAP32[i4 + (i14 << 2) + 2908 >> 2] << 2) + 2 >> 1] = 0;
+ i14 = i14 + 1 | 0;
+ L72 : do {
+  if ((i14 | 0) < 573) {
+   i6 = i4 + 5800 | 0;
+   i13 = i4 + 5804 | 0;
+   if ((i12 | 0) == 0) {
+    i18 = 0;
+    do {
+     i12 = HEAP32[i4 + (i14 << 2) + 2908 >> 2] | 0;
+     i13 = i8 + (i12 << 2) + 2 | 0;
+     i15 = HEAPU16[i8 + (HEAPU16[i13 >> 1] << 2) + 2 >> 1] | 0;
+     i16 = (i15 | 0) < (i7 | 0);
+     i15 = i16 ? i15 + 1 | 0 : i7;
+     i18 = (i16 & 1 ^ 1) + i18 | 0;
+     HEAP16[i13 >> 1] = i15;
+     if ((i12 | 0) <= (i9 | 0)) {
+      i23 = i4 + (i15 << 1) + 2876 | 0;
+      HEAP16[i23 >> 1] = (HEAP16[i23 >> 1] | 0) + 1 << 16 >> 16;
+      if ((i12 | 0) < (i10 | 0)) {
+       i13 = 0;
+      } else {
+       i13 = HEAP32[i11 + (i12 - i10 << 2) >> 2] | 0;
+      }
+      i23 = Math_imul(HEAPU16[i8 + (i12 << 2) >> 1] | 0, i13 + i15 | 0) | 0;
+      HEAP32[i6 >> 2] = i23 + (HEAP32[i6 >> 2] | 0);
+     }
+     i14 = i14 + 1 | 0;
+    } while ((i14 | 0) != 573);
+   } else {
+    i18 = 0;
+    do {
+     i15 = HEAP32[i4 + (i14 << 2) + 2908 >> 2] | 0;
+     i16 = i8 + (i15 << 2) + 2 | 0;
+     i17 = HEAPU16[i8 + (HEAPU16[i16 >> 1] << 2) + 2 >> 1] | 0;
+     i19 = (i17 | 0) < (i7 | 0);
+     i17 = i19 ? i17 + 1 | 0 : i7;
+     i18 = (i19 & 1 ^ 1) + i18 | 0;
+     HEAP16[i16 >> 1] = i17;
+     if ((i15 | 0) <= (i9 | 0)) {
+      i23 = i4 + (i17 << 1) + 2876 | 0;
+      HEAP16[i23 >> 1] = (HEAP16[i23 >> 1] | 0) + 1 << 16 >> 16;
+      if ((i15 | 0) < (i10 | 0)) {
+       i16 = 0;
+      } else {
+       i16 = HEAP32[i11 + (i15 - i10 << 2) >> 2] | 0;
+      }
+      i23 = HEAPU16[i8 + (i15 << 2) >> 1] | 0;
+      i22 = Math_imul(i23, i16 + i17 | 0) | 0;
+      HEAP32[i6 >> 2] = i22 + (HEAP32[i6 >> 2] | 0);
+      i23 = Math_imul((HEAPU16[i12 + (i15 << 2) + 2 >> 1] | 0) + i16 | 0, i23) | 0;
+      HEAP32[i13 >> 2] = i23 + (HEAP32[i13 >> 2] | 0);
+     }
+     i14 = i14 + 1 | 0;
+    } while ((i14 | 0) != 573);
+   }
+   if ((i18 | 0) != 0) {
+    i10 = i4 + (i7 << 1) + 2876 | 0;
+    do {
+     i12 = i7;
+     while (1) {
+      i11 = i12 + -1 | 0;
+      i13 = i4 + (i11 << 1) + 2876 | 0;
+      i14 = HEAP16[i13 >> 1] | 0;
+      if (i14 << 16 >> 16 == 0) {
+       i12 = i11;
+      } else {
+       break;
+      }
+     }
+     HEAP16[i13 >> 1] = i14 + -1 << 16 >> 16;
+     i11 = i4 + (i12 << 1) + 2876 | 0;
+     HEAP16[i11 >> 1] = (HEAPU16[i11 >> 1] | 0) + 2;
+     i11 = (HEAP16[i10 >> 1] | 0) + -1 << 16 >> 16;
+     HEAP16[i10 >> 1] = i11;
+     i18 = i18 + -2 | 0;
+    } while ((i18 | 0) > 0);
+    if ((i7 | 0) != 0) {
+     i12 = 573;
+     while (1) {
+      i10 = i7 & 65535;
+      if (!(i11 << 16 >> 16 == 0)) {
+       i11 = i11 & 65535;
+       do {
+        do {
+         i12 = i12 + -1 | 0;
+         i15 = HEAP32[i4 + (i12 << 2) + 2908 >> 2] | 0;
+        } while ((i15 | 0) > (i9 | 0));
+        i13 = i8 + (i15 << 2) + 2 | 0;
+        i14 = HEAPU16[i13 >> 1] | 0;
+        if ((i14 | 0) != (i7 | 0)) {
+         i23 = Math_imul(HEAPU16[i8 + (i15 << 2) >> 1] | 0, i7 - i14 | 0) | 0;
+         HEAP32[i6 >> 2] = i23 + (HEAP32[i6 >> 2] | 0);
+         HEAP16[i13 >> 1] = i10;
+        }
+        i11 = i11 + -1 | 0;
+       } while ((i11 | 0) != 0);
+      }
+      i7 = i7 + -1 | 0;
+      if ((i7 | 0) == 0) {
+       break L72;
+      }
+      i11 = HEAP16[i4 + (i7 << 1) + 2876 >> 1] | 0;
+     }
+    }
+   }
+  }
+ } while (0);
+ i7 = 1;
+ i6 = 0;
+ do {
+  i6 = (HEAPU16[i4 + (i7 + -1 << 1) + 2876 >> 1] | 0) + (i6 & 65534) << 1;
+  HEAP16[i1 + (i7 << 1) >> 1] = i6;
+  i7 = i7 + 1 | 0;
+ } while ((i7 | 0) != 16);
+ if ((i5 | 0) < 0) {
+  STACKTOP = i2;
+  return;
+ } else {
+  i4 = 0;
+ }
+ while (1) {
+  i23 = HEAP16[i3 + (i4 << 2) + 2 >> 1] | 0;
+  i7 = i23 & 65535;
+  if (!(i23 << 16 >> 16 == 0)) {
+   i8 = i1 + (i7 << 1) | 0;
+   i6 = HEAP16[i8 >> 1] | 0;
+   HEAP16[i8 >> 1] = i6 + 1 << 16 >> 16;
+   i6 = i6 & 65535;
+   i8 = 0;
+   while (1) {
+    i8 = i8 | i6 & 1;
+    i7 = i7 + -1 | 0;
+    if ((i7 | 0) <= 0) {
+     break;
+    } else {
+     i6 = i6 >>> 1;
+     i8 = i8 << 1;
+    }
+   }
+   HEAP16[i3 + (i4 << 2) >> 1] = i8;
+  }
+  if ((i4 | 0) == (i5 | 0)) {
+   break;
+  } else {
+   i4 = i4 + 1 | 0;
+  }
+ }
+ STACKTOP = i2;
+ return;
+}
+function _deflate_slow(i2, i6) {
+ i2 = i2 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, i36 = 0;
+ i1 = STACKTOP;
+ i15 = i2 + 116 | 0;
+ i16 = (i6 | 0) == 0;
+ i17 = i2 + 72 | 0;
+ i18 = i2 + 88 | 0;
+ i5 = i2 + 108 | 0;
+ i7 = i2 + 56 | 0;
+ i19 = i2 + 84 | 0;
+ i20 = i2 + 68 | 0;
+ i22 = i2 + 52 | 0;
+ i21 = i2 + 64 | 0;
+ i9 = i2 + 96 | 0;
+ i10 = i2 + 120 | 0;
+ i11 = i2 + 112 | 0;
+ i12 = i2 + 100 | 0;
+ i26 = i2 + 5792 | 0;
+ i27 = i2 + 5796 | 0;
+ i29 = i2 + 5784 | 0;
+ i23 = i2 + 5788 | 0;
+ i8 = i2 + 104 | 0;
+ i4 = i2 + 92 | 0;
+ i24 = i2 + 128 | 0;
+ i14 = i2 + 44 | 0;
+ i13 = i2 + 136 | 0;
+ L1 : while (1) {
+  i30 = HEAP32[i15 >> 2] | 0;
+  while (1) {
+   if (i30 >>> 0 < 262) {
+    _fill_window(i2);
+    i30 = HEAP32[i15 >> 2] | 0;
+    if (i30 >>> 0 < 262 & i16) {
+     i2 = 0;
+     i30 = 50;
+     break L1;
+    }
+    if ((i30 | 0) == 0) {
+     i30 = 40;
+     break L1;
+    }
+    if (!(i30 >>> 0 > 2)) {
+     HEAP32[i10 >> 2] = HEAP32[i9 >> 2];
+     HEAP32[i12 >> 2] = HEAP32[i11 >> 2];
+     HEAP32[i9 >> 2] = 2;
+     i32 = 2;
+     i30 = 16;
+    } else {
+     i30 = 8;
+    }
+   } else {
+    i30 = 8;
+   }
+   do {
+    if ((i30 | 0) == 8) {
+     i30 = 0;
+     i34 = HEAP32[i5 >> 2] | 0;
+     i31 = ((HEAPU8[(HEAP32[i7 >> 2] | 0) + (i34 + 2) | 0] | 0) ^ HEAP32[i17 >> 2] << HEAP32[i18 >> 2]) & HEAP32[i19 >> 2];
+     HEAP32[i17 >> 2] = i31;
+     i31 = (HEAP32[i20 >> 2] | 0) + (i31 << 1) | 0;
+     i35 = HEAP16[i31 >> 1] | 0;
+     HEAP16[(HEAP32[i21 >> 2] | 0) + ((HEAP32[i22 >> 2] & i34) << 1) >> 1] = i35;
+     i32 = i35 & 65535;
+     HEAP16[i31 >> 1] = i34;
+     i31 = HEAP32[i9 >> 2] | 0;
+     HEAP32[i10 >> 2] = i31;
+     HEAP32[i12 >> 2] = HEAP32[i11 >> 2];
+     HEAP32[i9 >> 2] = 2;
+     if (!(i35 << 16 >> 16 == 0)) {
+      if (i31 >>> 0 < (HEAP32[i24 >> 2] | 0) >>> 0) {
+       if (!(((HEAP32[i5 >> 2] | 0) - i32 | 0) >>> 0 > ((HEAP32[i14 >> 2] | 0) + -262 | 0) >>> 0)) {
+        i32 = _longest_match(i2, i32) | 0;
+        HEAP32[i9 >> 2] = i32;
+        if (i32 >>> 0 < 6) {
+         if ((HEAP32[i13 >> 2] | 0) != 1) {
+          if ((i32 | 0) != 3) {
+           i30 = 16;
+           break;
+          }
+          if (!(((HEAP32[i5 >> 2] | 0) - (HEAP32[i11 >> 2] | 0) | 0) >>> 0 > 4096)) {
+           i32 = 3;
+           i30 = 16;
+           break;
+          }
+         }
+         HEAP32[i9 >> 2] = 2;
+         i32 = 2;
+         i30 = 16;
+        } else {
+         i30 = 16;
+        }
+       } else {
+        i32 = 2;
+        i30 = 16;
+       }
+      } else {
+       i32 = 2;
+      }
+     } else {
+      i32 = 2;
+      i30 = 16;
+     }
+    }
+   } while (0);
+   if ((i30 | 0) == 16) {
+    i31 = HEAP32[i10 >> 2] | 0;
+   }
+   if (!(i31 >>> 0 < 3 | i32 >>> 0 > i31 >>> 0)) {
+    break;
+   }
+   if ((HEAP32[i8 >> 2] | 0) == 0) {
+    HEAP32[i8 >> 2] = 1;
+    HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + 1;
+    i30 = (HEAP32[i15 >> 2] | 0) + -1 | 0;
+    HEAP32[i15 >> 2] = i30;
+    continue;
+   }
+   i35 = HEAP8[(HEAP32[i7 >> 2] | 0) + ((HEAP32[i5 >> 2] | 0) + -1) | 0] | 0;
+   i34 = HEAP32[i26 >> 2] | 0;
+   HEAP16[(HEAP32[i27 >> 2] | 0) + (i34 << 1) >> 1] = 0;
+   HEAP32[i26 >> 2] = i34 + 1;
+   HEAP8[(HEAP32[i29 >> 2] | 0) + i34 | 0] = i35;
+   i35 = i2 + ((i35 & 255) << 2) + 148 | 0;
+   HEAP16[i35 >> 1] = (HEAP16[i35 >> 1] | 0) + 1 << 16 >> 16;
+   if ((HEAP32[i26 >> 2] | 0) == ((HEAP32[i23 >> 2] | 0) + -1 | 0)) {
+    i30 = HEAP32[i4 >> 2] | 0;
+    if ((i30 | 0) > -1) {
+     i31 = (HEAP32[i7 >> 2] | 0) + i30 | 0;
+    } else {
+     i31 = 0;
+    }
+    __tr_flush_block(i2, i31, (HEAP32[i5 >> 2] | 0) - i30 | 0, 0);
+    HEAP32[i4 >> 2] = HEAP32[i5 >> 2];
+    i33 = HEAP32[i2 >> 2] | 0;
+    i32 = i33 + 28 | 0;
+    i30 = HEAP32[i32 >> 2] | 0;
+    i35 = HEAP32[i30 + 20 >> 2] | 0;
+    i31 = i33 + 16 | 0;
+    i34 = HEAP32[i31 >> 2] | 0;
+    i34 = i35 >>> 0 > i34 >>> 0 ? i34 : i35;
+    if ((i34 | 0) != 0 ? (i28 = i33 + 12 | 0, _memcpy(HEAP32[i28 >> 2] | 0, HEAP32[i30 + 16 >> 2] | 0, i34 | 0) | 0, HEAP32[i28 >> 2] = (HEAP32[i28 >> 2] | 0) + i34, i28 = (HEAP32[i32 >> 2] | 0) + 16 | 0, HEAP32[i28 >> 2] = (HEAP32[i28 >> 2] | 0) + i34, i28 = i33 + 20 | 0, HEAP32[i28 >> 2] = (HEAP32[i28 >> 2] | 0) + i34, HEAP32[i31 >> 2] = (HEAP32[i31 >> 2] | 0) - i34, i28 = HEAP32[i32 >> 2] | 0, i33 = i28 + 20 | 0, i35 = HEAP32[i33 >> 2] | 0, HEAP32[i33 >> 2] = i35 - i34, (i35 | 0) == (i34 | 0)) : 0) {
+     HEAP32[i28 + 16 >> 2] = HEAP32[i28 + 8 >> 2];
+    }
+   }
+   HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + 1;
+   i30 = (HEAP32[i15 >> 2] | 0) + -1 | 0;
+   HEAP32[i15 >> 2] = i30;
+   if ((HEAP32[(HEAP32[i2 >> 2] | 0) + 16 >> 2] | 0) == 0) {
+    i2 = 0;
+    i30 = 50;
+    break L1;
+   }
+  }
+  i34 = HEAP32[i5 >> 2] | 0;
+  i30 = i34 + -3 + (HEAP32[i15 >> 2] | 0) | 0;
+  i35 = i31 + 253 | 0;
+  i31 = i34 + 65535 - (HEAP32[i12 >> 2] | 0) | 0;
+  i34 = HEAP32[i26 >> 2] | 0;
+  HEAP16[(HEAP32[i27 >> 2] | 0) + (i34 << 1) >> 1] = i31;
+  HEAP32[i26 >> 2] = i34 + 1;
+  HEAP8[(HEAP32[i29 >> 2] | 0) + i34 | 0] = i35;
+  i35 = i2 + ((HEAPU8[808 + (i35 & 255) | 0] | 0 | 256) + 1 << 2) + 148 | 0;
+  HEAP16[i35 >> 1] = (HEAP16[i35 >> 1] | 0) + 1 << 16 >> 16;
+  i31 = i31 + 65535 & 65535;
+  if (!(i31 >>> 0 < 256)) {
+   i31 = (i31 >>> 7) + 256 | 0;
+  }
+  i32 = i2 + ((HEAPU8[296 + i31 | 0] | 0) << 2) + 2440 | 0;
+  HEAP16[i32 >> 1] = (HEAP16[i32 >> 1] | 0) + 1 << 16 >> 16;
+  i32 = HEAP32[i26 >> 2] | 0;
+  i31 = (HEAP32[i23 >> 2] | 0) + -1 | 0;
+  i34 = HEAP32[i10 >> 2] | 0;
+  HEAP32[i15 >> 2] = 1 - i34 + (HEAP32[i15 >> 2] | 0);
+  i34 = i34 + -2 | 0;
+  HEAP32[i10 >> 2] = i34;
+  i33 = HEAP32[i5 >> 2] | 0;
+  while (1) {
+   i35 = i33 + 1 | 0;
+   HEAP32[i5 >> 2] = i35;
+   if (!(i35 >>> 0 > i30 >>> 0)) {
+    i36 = ((HEAPU8[(HEAP32[i7 >> 2] | 0) + (i33 + 3) | 0] | 0) ^ HEAP32[i17 >> 2] << HEAP32[i18 >> 2]) & HEAP32[i19 >> 2];
+    HEAP32[i17 >> 2] = i36;
+    i36 = (HEAP32[i20 >> 2] | 0) + (i36 << 1) | 0;
+    HEAP16[(HEAP32[i21 >> 2] | 0) + ((HEAP32[i22 >> 2] & i35) << 1) >> 1] = HEAP16[i36 >> 1] | 0;
+    HEAP16[i36 >> 1] = i35;
+   }
+   i34 = i34 + -1 | 0;
+   HEAP32[i10 >> 2] = i34;
+   if ((i34 | 0) == 0) {
+    break;
+   } else {
+    i33 = i35;
+   }
+  }
+  HEAP32[i8 >> 2] = 0;
+  HEAP32[i9 >> 2] = 2;
+  i30 = i33 + 2 | 0;
+  HEAP32[i5 >> 2] = i30;
+  if ((i32 | 0) != (i31 | 0)) {
+   continue;
+  }
+  i32 = HEAP32[i4 >> 2] | 0;
+  if ((i32 | 0) > -1) {
+   i31 = (HEAP32[i7 >> 2] | 0) + i32 | 0;
+  } else {
+   i31 = 0;
+  }
+  __tr_flush_block(i2, i31, i30 - i32 | 0, 0);
+  HEAP32[i4 >> 2] = HEAP32[i5 >> 2];
+  i33 = HEAP32[i2 >> 2] | 0;
+  i31 = i33 + 28 | 0;
+  i32 = HEAP32[i31 >> 2] | 0;
+  i35 = HEAP32[i32 + 20 >> 2] | 0;
+  i30 = i33 + 16 | 0;
+  i34 = HEAP32[i30 >> 2] | 0;
+  i34 = i35 >>> 0 > i34 >>> 0 ? i34 : i35;
+  if ((i34 | 0) != 0 ? (i25 = i33 + 12 | 0, _memcpy(HEAP32[i25 >> 2] | 0, HEAP32[i32 + 16 >> 2] | 0, i34 | 0) | 0, HEAP32[i25 >> 2] = (HEAP32[i25 >> 2] | 0) + i34, i25 = (HEAP32[i31 >> 2] | 0) + 16 | 0, HEAP32[i25 >> 2] = (HEAP32[i25 >> 2] | 0) + i34, i25 = i33 + 20 | 0, HEAP32[i25 >> 2] = (HEAP32[i25 >> 2] | 0) + i34, HEAP32[i30 >> 2] = (HEAP32[i30 >> 2] | 0) - i34, i25 = HEAP32[i31 >> 2] | 0, i35 = i25 + 20 | 0, i36 = HEAP32[i35 >> 2] | 0, HEAP32[i35 >> 2] = i36 - i34, (i36 | 0) == (i34 | 0)) : 0) {
+   HEAP32[i25 + 16 >> 2] = HEAP32[i25 + 8 >> 2];
+  }
+  if ((HEAP32[(HEAP32[i2 >> 2] | 0) + 16 >> 2] | 0) == 0) {
+   i2 = 0;
+   i30 = 50;
+   break;
+  }
+ }
+ if ((i30 | 0) == 40) {
+  if ((HEAP32[i8 >> 2] | 0) != 0) {
+   i36 = HEAP8[(HEAP32[i7 >> 2] | 0) + ((HEAP32[i5 >> 2] | 0) + -1) | 0] | 0;
+   i35 = HEAP32[i26 >> 2] | 0;
+   HEAP16[(HEAP32[i27 >> 2] | 0) + (i35 << 1) >> 1] = 0;
+   HEAP32[i26 >> 2] = i35 + 1;
+   HEAP8[(HEAP32[i29 >> 2] | 0) + i35 | 0] = i36;
+   i36 = i2 + ((i36 & 255) << 2) + 148 | 0;
+   HEAP16[i36 >> 1] = (HEAP16[i36 >> 1] | 0) + 1 << 16 >> 16;
+   HEAP32[i8 >> 2] = 0;
+  }
+  i8 = HEAP32[i4 >> 2] | 0;
+  if ((i8 | 0) > -1) {
+   i7 = (HEAP32[i7 >> 2] | 0) + i8 | 0;
+  } else {
+   i7 = 0;
+  }
+  i6 = (i6 | 0) == 4;
+  __tr_flush_block(i2, i7, (HEAP32[i5 >> 2] | 0) - i8 | 0, i6 & 1);
+  HEAP32[i4 >> 2] = HEAP32[i5 >> 2];
+  i4 = HEAP32[i2 >> 2] | 0;
+  i7 = i4 + 28 | 0;
+  i5 = HEAP32[i7 >> 2] | 0;
+  i10 = HEAP32[i5 + 20 >> 2] | 0;
+  i8 = i4 + 16 | 0;
+  i9 = HEAP32[i8 >> 2] | 0;
+  i9 = i10 >>> 0 > i9 >>> 0 ? i9 : i10;
+  if ((i9 | 0) != 0 ? (i3 = i4 + 12 | 0, _memcpy(HEAP32[i3 >> 2] | 0, HEAP32[i5 + 16 >> 2] | 0, i9 | 0) | 0, HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + i9, i3 = (HEAP32[i7 >> 2] | 0) + 16 | 0, HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + i9, i3 = i4 + 20 | 0, HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + i9, HEAP32[i8 >> 2] = (HEAP32[i8 >> 2] | 0) - i9, i3 = HEAP32[i7 >> 2] | 0, i35 = i3 + 20 | 0, i36 = HEAP32[i35 >> 2] | 0, HEAP32[i35 >> 2] = i36 - i9, (i36 | 0) == (i9 | 0)) : 0) {
+   HEAP32[i3 + 16 >> 2] = HEAP32[i3 + 8 >> 2];
+  }
+  if ((HEAP32[(HEAP32[i2 >> 2] | 0) + 16 >> 2] | 0) == 0) {
+   i36 = i6 ? 2 : 0;
+   STACKTOP = i1;
+   return i36 | 0;
+  } else {
+   i36 = i6 ? 3 : 1;
+   STACKTOP = i1;
+   return i36 | 0;
+  }
+ } else if ((i30 | 0) == 50) {
+  STACKTOP = i1;
+  return i2 | 0;
+ }
+ return 0;
+}
+function _inflate_fast(i7, i19) {
+ i7 = i7 | 0;
+ i19 = i19 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, i36 = 0, i37 = 0;
+ i1 = STACKTOP;
+ i11 = HEAP32[i7 + 28 >> 2] | 0;
+ i29 = HEAP32[i7 >> 2] | 0;
+ i5 = i7 + 4 | 0;
+ i8 = i29 + ((HEAP32[i5 >> 2] | 0) + -6) | 0;
+ i9 = i7 + 12 | 0;
+ i28 = HEAP32[i9 >> 2] | 0;
+ i4 = i7 + 16 | 0;
+ i25 = HEAP32[i4 >> 2] | 0;
+ i6 = i28 + (i25 + -258) | 0;
+ i17 = HEAP32[i11 + 44 >> 2] | 0;
+ i12 = HEAP32[i11 + 48 >> 2] | 0;
+ i18 = HEAP32[i11 + 52 >> 2] | 0;
+ i3 = i11 + 56 | 0;
+ i2 = i11 + 60 | 0;
+ i16 = HEAP32[i11 + 76 >> 2] | 0;
+ i13 = HEAP32[i11 + 80 >> 2] | 0;
+ i14 = (1 << HEAP32[i11 + 84 >> 2]) + -1 | 0;
+ i15 = (1 << HEAP32[i11 + 88 >> 2]) + -1 | 0;
+ i19 = i28 + (i25 + ~i19) | 0;
+ i25 = i11 + 7104 | 0;
+ i20 = i18 + -1 | 0;
+ i27 = (i12 | 0) == 0;
+ i24 = (HEAP32[i11 + 40 >> 2] | 0) + -1 | 0;
+ i21 = i24 + i12 | 0;
+ i22 = i12 + -1 | 0;
+ i23 = i19 + -1 | 0;
+ i26 = i19 - i12 | 0;
+ i31 = HEAP32[i2 >> 2] | 0;
+ i30 = HEAP32[i3 >> 2] | 0;
+ i29 = i29 + -1 | 0;
+ i28 = i28 + -1 | 0;
+ L1 : do {
+  if (i31 >>> 0 < 15) {
+   i37 = i29 + 2 | 0;
+   i33 = i31 + 16 | 0;
+   i30 = ((HEAPU8[i29 + 1 | 0] | 0) << i31) + i30 + ((HEAPU8[i37] | 0) << i31 + 8) | 0;
+   i29 = i37;
+  } else {
+   i33 = i31;
+  }
+  i31 = i30 & i14;
+  i34 = HEAP8[i16 + (i31 << 2) | 0] | 0;
+  i32 = HEAP16[i16 + (i31 << 2) + 2 >> 1] | 0;
+  i31 = HEAPU8[i16 + (i31 << 2) + 1 | 0] | 0;
+  i30 = i30 >>> i31;
+  i31 = i33 - i31 | 0;
+  do {
+   if (!(i34 << 24 >> 24 == 0)) {
+    i33 = i34 & 255;
+    while (1) {
+     if ((i33 & 16 | 0) != 0) {
+      break;
+     }
+     if ((i33 & 64 | 0) != 0) {
+      i10 = 55;
+      break L1;
+     }
+     i37 = (i30 & (1 << i33) + -1) + (i32 & 65535) | 0;
+     i33 = HEAP8[i16 + (i37 << 2) | 0] | 0;
+     i32 = HEAP16[i16 + (i37 << 2) + 2 >> 1] | 0;
+     i37 = HEAPU8[i16 + (i37 << 2) + 1 | 0] | 0;
+     i30 = i30 >>> i37;
+     i31 = i31 - i37 | 0;
+     if (i33 << 24 >> 24 == 0) {
+      i10 = 6;
+      break;
+     } else {
+      i33 = i33 & 255;
+     }
+    }
+    if ((i10 | 0) == 6) {
+     i32 = i32 & 255;
+     i10 = 7;
+     break;
+    }
+    i32 = i32 & 65535;
+    i33 = i33 & 15;
+    if ((i33 | 0) != 0) {
+     if (i31 >>> 0 < i33 >>> 0) {
+      i29 = i29 + 1 | 0;
+      i35 = i31 + 8 | 0;
+      i34 = ((HEAPU8[i29] | 0) << i31) + i30 | 0;
+     } else {
+      i35 = i31;
+      i34 = i30;
+     }
+     i31 = i35 - i33 | 0;
+     i30 = i34 >>> i33;
+     i32 = (i34 & (1 << i33) + -1) + i32 | 0;
+    }
+    if (i31 >>> 0 < 15) {
+     i37 = i29 + 2 | 0;
+     i34 = i31 + 16 | 0;
+     i30 = ((HEAPU8[i29 + 1 | 0] | 0) << i31) + i30 + ((HEAPU8[i37] | 0) << i31 + 8) | 0;
+     i29 = i37;
+    } else {
+     i34 = i31;
+    }
+    i37 = i30 & i15;
+    i33 = HEAP16[i13 + (i37 << 2) + 2 >> 1] | 0;
+    i31 = HEAPU8[i13 + (i37 << 2) + 1 | 0] | 0;
+    i30 = i30 >>> i31;
+    i31 = i34 - i31 | 0;
+    i34 = HEAPU8[i13 + (i37 << 2) | 0] | 0;
+    if ((i34 & 16 | 0) == 0) {
+     do {
+      if ((i34 & 64 | 0) != 0) {
+       i10 = 52;
+       break L1;
+      }
+      i34 = (i30 & (1 << i34) + -1) + (i33 & 65535) | 0;
+      i33 = HEAP16[i13 + (i34 << 2) + 2 >> 1] | 0;
+      i37 = HEAPU8[i13 + (i34 << 2) + 1 | 0] | 0;
+      i30 = i30 >>> i37;
+      i31 = i31 - i37 | 0;
+      i34 = HEAPU8[i13 + (i34 << 2) | 0] | 0;
+     } while ((i34 & 16 | 0) == 0);
+    }
+    i33 = i33 & 65535;
+    i34 = i34 & 15;
+    if (i31 >>> 0 < i34 >>> 0) {
+     i35 = i29 + 1 | 0;
+     i30 = ((HEAPU8[i35] | 0) << i31) + i30 | 0;
+     i36 = i31 + 8 | 0;
+     if (i36 >>> 0 < i34 >>> 0) {
+      i29 = i29 + 2 | 0;
+      i31 = i31 + 16 | 0;
+      i30 = ((HEAPU8[i29] | 0) << i36) + i30 | 0;
+     } else {
+      i31 = i36;
+      i29 = i35;
+     }
+    }
+    i33 = (i30 & (1 << i34) + -1) + i33 | 0;
+    i30 = i30 >>> i34;
+    i31 = i31 - i34 | 0;
+    i35 = i28;
+    i34 = i35 - i19 | 0;
+    if (!(i33 >>> 0 > i34 >>> 0)) {
+     i34 = i28 + (0 - i33) | 0;
+     while (1) {
+      HEAP8[i28 + 1 | 0] = HEAP8[i34 + 1 | 0] | 0;
+      HEAP8[i28 + 2 | 0] = HEAP8[i34 + 2 | 0] | 0;
+      i35 = i34 + 3 | 0;
+      i33 = i28 + 3 | 0;
+      HEAP8[i33] = HEAP8[i35] | 0;
+      i32 = i32 + -3 | 0;
+      if (!(i32 >>> 0 > 2)) {
+       break;
+      } else {
+       i34 = i35;
+       i28 = i33;
+      }
+     }
+     if ((i32 | 0) == 0) {
+      i28 = i33;
+      break;
+     }
+     i33 = i28 + 4 | 0;
+     HEAP8[i33] = HEAP8[i34 + 4 | 0] | 0;
+     if (!(i32 >>> 0 > 1)) {
+      i28 = i33;
+      break;
+     }
+     i28 = i28 + 5 | 0;
+     HEAP8[i28] = HEAP8[i34 + 5 | 0] | 0;
+     break;
+    }
+    i34 = i33 - i34 | 0;
+    if (i34 >>> 0 > i17 >>> 0 ? (HEAP32[i25 >> 2] | 0) != 0 : 0) {
+     i10 = 22;
+     break L1;
+    }
+    do {
+     if (i27) {
+      i36 = i18 + (i24 - i34) | 0;
+      if (i34 >>> 0 < i32 >>> 0) {
+       i32 = i32 - i34 | 0;
+       i35 = i33 - i35 | 0;
+       i37 = i28;
+       do {
+        i36 = i36 + 1 | 0;
+        i37 = i37 + 1 | 0;
+        HEAP8[i37] = HEAP8[i36] | 0;
+        i34 = i34 + -1 | 0;
+       } while ((i34 | 0) != 0);
+       i33 = i28 + (i23 + i35 + (1 - i33)) | 0;
+       i28 = i28 + (i19 + i35) | 0;
+      } else {
+       i33 = i36;
+      }
+     } else {
+      if (!(i12 >>> 0 < i34 >>> 0)) {
+       i36 = i18 + (i22 - i34) | 0;
+       if (!(i34 >>> 0 < i32 >>> 0)) {
+        i33 = i36;
+        break;
+       }
+       i32 = i32 - i34 | 0;
+       i35 = i33 - i35 | 0;
+       i37 = i28;
+       do {
+        i36 = i36 + 1 | 0;
+        i37 = i37 + 1 | 0;
+        HEAP8[i37] = HEAP8[i36] | 0;
+        i34 = i34 + -1 | 0;
+       } while ((i34 | 0) != 0);
+       i33 = i28 + (i23 + i35 + (1 - i33)) | 0;
+       i28 = i28 + (i19 + i35) | 0;
+       break;
+      }
+      i37 = i18 + (i21 - i34) | 0;
+      i36 = i34 - i12 | 0;
+      if (i36 >>> 0 < i32 >>> 0) {
+       i32 = i32 - i36 | 0;
+       i34 = i33 - i35 | 0;
+       i35 = i28;
+       do {
+        i37 = i37 + 1 | 0;
+        i35 = i35 + 1 | 0;
+        HEAP8[i35] = HEAP8[i37] | 0;
+        i36 = i36 + -1 | 0;
+       } while ((i36 | 0) != 0);
+       i35 = i28 + (i26 + i34) | 0;
+       if (i12 >>> 0 < i32 >>> 0) {
+        i32 = i32 - i12 | 0;
+        i37 = i20;
+        i36 = i12;
+        do {
+         i37 = i37 + 1 | 0;
+         i35 = i35 + 1 | 0;
+         HEAP8[i35] = HEAP8[i37] | 0;
+         i36 = i36 + -1 | 0;
+        } while ((i36 | 0) != 0);
+        i33 = i28 + (i23 + i34 + (1 - i33)) | 0;
+        i28 = i28 + (i19 + i34) | 0;
+       } else {
+        i33 = i20;
+        i28 = i35;
+       }
+      } else {
+       i33 = i37;
+      }
+     }
+    } while (0);
+    if (i32 >>> 0 > 2) {
+     do {
+      HEAP8[i28 + 1 | 0] = HEAP8[i33 + 1 | 0] | 0;
+      HEAP8[i28 + 2 | 0] = HEAP8[i33 + 2 | 0] | 0;
+      i33 = i33 + 3 | 0;
+      i28 = i28 + 3 | 0;
+      HEAP8[i28] = HEAP8[i33] | 0;
+      i32 = i32 + -3 | 0;
+     } while (i32 >>> 0 > 2);
+    }
+    if ((i32 | 0) != 0) {
+     i34 = i28 + 1 | 0;
+     HEAP8[i34] = HEAP8[i33 + 1 | 0] | 0;
+     if (i32 >>> 0 > 1) {
+      i28 = i28 + 2 | 0;
+      HEAP8[i28] = HEAP8[i33 + 2 | 0] | 0;
+     } else {
+      i28 = i34;
+     }
+    }
+   } else {
+    i32 = i32 & 255;
+    i10 = 7;
+   }
+  } while (0);
+  if ((i10 | 0) == 7) {
+   i10 = 0;
+   i28 = i28 + 1 | 0;
+   HEAP8[i28] = i32;
+  }
+ } while (i29 >>> 0 < i8 >>> 0 & i28 >>> 0 < i6 >>> 0);
+ do {
+  if ((i10 | 0) == 22) {
+   HEAP32[i7 + 24 >> 2] = 14384;
+   HEAP32[i11 >> 2] = 29;
+  } else if ((i10 | 0) == 52) {
+   HEAP32[i7 + 24 >> 2] = 14416;
+   HEAP32[i11 >> 2] = 29;
+  } else if ((i10 | 0) == 55) {
+   if ((i33 & 32 | 0) == 0) {
+    HEAP32[i7 + 24 >> 2] = 14440;
+    HEAP32[i11 >> 2] = 29;
+    break;
+   } else {
+    HEAP32[i11 >> 2] = 11;
+    break;
+   }
+  }
+ } while (0);
+ i37 = i31 >>> 3;
+ i11 = i29 + (0 - i37) | 0;
+ i10 = i31 - (i37 << 3) | 0;
+ i12 = (1 << i10) + -1 & i30;
+ HEAP32[i7 >> 2] = i29 + (1 - i37);
+ HEAP32[i9 >> 2] = i28 + 1;
+ if (i11 >>> 0 < i8 >>> 0) {
+  i7 = i8 - i11 | 0;
+ } else {
+  i7 = i8 - i11 | 0;
+ }
+ HEAP32[i5 >> 2] = i7 + 5;
+ if (i28 >>> 0 < i6 >>> 0) {
+  i37 = i6 - i28 | 0;
+  i37 = i37 + 257 | 0;
+  HEAP32[i4 >> 2] = i37;
+  HEAP32[i3 >> 2] = i12;
+  HEAP32[i2 >> 2] = i10;
+  STACKTOP = i1;
+  return;
+ } else {
+  i37 = i6 - i28 | 0;
+  i37 = i37 + 257 | 0;
+  HEAP32[i4 >> 2] = i37;
+  HEAP32[i3 >> 2] = i12;
+  HEAP32[i2 >> 2] = i10;
+  STACKTOP = i1;
+  return;
+ }
+}
+function _send_tree(i2, i13, i12) {
+ i2 = i2 | 0;
+ i13 = i13 | 0;
+ i12 = i12 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0;
+ i11 = STACKTOP;
+ i15 = HEAP16[i13 + 2 >> 1] | 0;
+ i16 = i15 << 16 >> 16 == 0;
+ i7 = i2 + 2754 | 0;
+ i4 = i2 + 5820 | 0;
+ i8 = i2 + 2752 | 0;
+ i3 = i2 + 5816 | 0;
+ i14 = i2 + 20 | 0;
+ i10 = i2 + 8 | 0;
+ i9 = i2 + 2758 | 0;
+ i1 = i2 + 2756 | 0;
+ i5 = i2 + 2750 | 0;
+ i6 = i2 + 2748 | 0;
+ i21 = i16 ? 138 : 7;
+ i23 = i16 ? 3 : 4;
+ i18 = 0;
+ i15 = i15 & 65535;
+ i24 = -1;
+ L1 : while (1) {
+  i20 = 0;
+  while (1) {
+   if ((i18 | 0) > (i12 | 0)) {
+    break L1;
+   }
+   i18 = i18 + 1 | 0;
+   i19 = HEAP16[i13 + (i18 << 2) + 2 >> 1] | 0;
+   i16 = i19 & 65535;
+   i22 = i20 + 1 | 0;
+   i17 = (i15 | 0) == (i16 | 0);
+   if (!((i22 | 0) < (i21 | 0) & i17)) {
+    break;
+   } else {
+    i20 = i22;
+   }
+  }
+  do {
+   if ((i22 | 0) >= (i23 | 0)) {
+    if ((i15 | 0) != 0) {
+     if ((i15 | 0) == (i24 | 0)) {
+      i23 = HEAP16[i3 >> 1] | 0;
+      i21 = HEAP32[i4 >> 2] | 0;
+      i20 = i22;
+     } else {
+      i22 = HEAPU16[i2 + (i15 << 2) + 2686 >> 1] | 0;
+      i21 = HEAP32[i4 >> 2] | 0;
+      i24 = HEAPU16[i2 + (i15 << 2) + 2684 >> 1] | 0;
+      i25 = HEAPU16[i3 >> 1] | 0 | i24 << i21;
+      i23 = i25 & 65535;
+      HEAP16[i3 >> 1] = i23;
+      if ((i21 | 0) > (16 - i22 | 0)) {
+       i23 = HEAP32[i14 >> 2] | 0;
+       HEAP32[i14 >> 2] = i23 + 1;
+       HEAP8[(HEAP32[i10 >> 2] | 0) + i23 | 0] = i25;
+       i23 = (HEAPU16[i3 >> 1] | 0) >>> 8 & 255;
+       i21 = HEAP32[i14 >> 2] | 0;
+       HEAP32[i14 >> 2] = i21 + 1;
+       HEAP8[(HEAP32[i10 >> 2] | 0) + i21 | 0] = i23;
+       i21 = HEAP32[i4 >> 2] | 0;
+       i23 = i24 >>> (16 - i21 | 0) & 65535;
+       HEAP16[i3 >> 1] = i23;
+       i21 = i22 + -16 + i21 | 0;
+      } else {
+       i21 = i21 + i22 | 0;
+      }
+      HEAP32[i4 >> 2] = i21;
+     }
+     i22 = HEAPU16[i5 >> 1] | 0;
+     i24 = HEAPU16[i6 >> 1] | 0;
+     i23 = i23 & 65535 | i24 << i21;
+     HEAP16[i3 >> 1] = i23;
+     if ((i21 | 0) > (16 - i22 | 0)) {
+      i21 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i21 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i21 | 0] = i23;
+      i23 = (HEAPU16[i3 >> 1] | 0) >>> 8 & 255;
+      i21 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i21 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i21 | 0] = i23;
+      i21 = HEAP32[i4 >> 2] | 0;
+      i23 = i24 >>> (16 - i21 | 0);
+      HEAP16[i3 >> 1] = i23;
+      i21 = i22 + -16 + i21 | 0;
+     } else {
+      i21 = i21 + i22 | 0;
+     }
+     HEAP32[i4 >> 2] = i21;
+     i20 = i20 + 65533 & 65535;
+     i22 = i23 & 65535 | i20 << i21;
+     HEAP16[i3 >> 1] = i22;
+     if ((i21 | 0) > 14) {
+      i26 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i26 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i26 | 0] = i22;
+      i26 = (HEAPU16[i3 >> 1] | 0) >>> 8 & 255;
+      i27 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i27 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i27 | 0] = i26;
+      i27 = HEAP32[i4 >> 2] | 0;
+      HEAP16[i3 >> 1] = i20 >>> (16 - i27 | 0);
+      HEAP32[i4 >> 2] = i27 + -14;
+      break;
+     } else {
+      HEAP32[i4 >> 2] = i21 + 2;
+      break;
+     }
+    }
+    if ((i22 | 0) < 11) {
+     i24 = HEAPU16[i7 >> 1] | 0;
+     i23 = HEAP32[i4 >> 2] | 0;
+     i21 = HEAPU16[i8 >> 1] | 0;
+     i22 = HEAPU16[i3 >> 1] | 0 | i21 << i23;
+     HEAP16[i3 >> 1] = i22;
+     if ((i23 | 0) > (16 - i24 | 0)) {
+      i27 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i27 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i27 | 0] = i22;
+      i22 = (HEAPU16[i3 >> 1] | 0) >>> 8 & 255;
+      i27 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i27 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i27 | 0] = i22;
+      i27 = HEAP32[i4 >> 2] | 0;
+      i22 = i21 >>> (16 - i27 | 0);
+      HEAP16[i3 >> 1] = i22;
+      i21 = i24 + -16 + i27 | 0;
+     } else {
+      i21 = i23 + i24 | 0;
+     }
+     HEAP32[i4 >> 2] = i21;
+     i20 = i20 + 65534 & 65535;
+     i22 = i22 & 65535 | i20 << i21;
+     HEAP16[i3 >> 1] = i22;
+     if ((i21 | 0) > 13) {
+      i26 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i26 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i26 | 0] = i22;
+      i26 = (HEAPU16[i3 >> 1] | 0) >>> 8 & 255;
+      i27 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i27 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i27 | 0] = i26;
+      i27 = HEAP32[i4 >> 2] | 0;
+      HEAP16[i3 >> 1] = i20 >>> (16 - i27 | 0);
+      HEAP32[i4 >> 2] = i27 + -13;
+      break;
+     } else {
+      HEAP32[i4 >> 2] = i21 + 3;
+      break;
+     }
+    } else {
+     i21 = HEAPU16[i9 >> 1] | 0;
+     i24 = HEAP32[i4 >> 2] | 0;
+     i23 = HEAPU16[i1 >> 1] | 0;
+     i22 = HEAPU16[i3 >> 1] | 0 | i23 << i24;
+     HEAP16[i3 >> 1] = i22;
+     if ((i24 | 0) > (16 - i21 | 0)) {
+      i27 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i27 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i27 | 0] = i22;
+      i22 = (HEAPU16[i3 >> 1] | 0) >>> 8 & 255;
+      i27 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i27 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i27 | 0] = i22;
+      i27 = HEAP32[i4 >> 2] | 0;
+      i22 = i23 >>> (16 - i27 | 0);
+      HEAP16[i3 >> 1] = i22;
+      i21 = i21 + -16 + i27 | 0;
+     } else {
+      i21 = i24 + i21 | 0;
+     }
+     HEAP32[i4 >> 2] = i21;
+     i20 = i20 + 65526 & 65535;
+     i22 = i22 & 65535 | i20 << i21;
+     HEAP16[i3 >> 1] = i22;
+     if ((i21 | 0) > 9) {
+      i26 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i26 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i26 | 0] = i22;
+      i26 = (HEAPU16[i3 >> 1] | 0) >>> 8 & 255;
+      i27 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i27 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i27 | 0] = i26;
+      i27 = HEAP32[i4 >> 2] | 0;
+      HEAP16[i3 >> 1] = i20 >>> (16 - i27 | 0);
+      HEAP32[i4 >> 2] = i27 + -9;
+      break;
+     } else {
+      HEAP32[i4 >> 2] = i21 + 7;
+      break;
+     }
+    }
+   } else {
+    i20 = i2 + (i15 << 2) + 2686 | 0;
+    i21 = i2 + (i15 << 2) + 2684 | 0;
+    i23 = HEAP32[i4 >> 2] | 0;
+    i26 = HEAP16[i3 >> 1] | 0;
+    do {
+     i24 = HEAPU16[i20 >> 1] | 0;
+     i25 = HEAPU16[i21 >> 1] | 0;
+     i27 = i26 & 65535 | i25 << i23;
+     i26 = i27 & 65535;
+     HEAP16[i3 >> 1] = i26;
+     if ((i23 | 0) > (16 - i24 | 0)) {
+      i26 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i26 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i26 | 0] = i27;
+      i26 = (HEAPU16[i3 >> 1] | 0) >>> 8 & 255;
+      i23 = HEAP32[i14 >> 2] | 0;
+      HEAP32[i14 >> 2] = i23 + 1;
+      HEAP8[(HEAP32[i10 >> 2] | 0) + i23 | 0] = i26;
+      i23 = HEAP32[i4 >> 2] | 0;
+      i26 = i25 >>> (16 - i23 | 0) & 65535;
+      HEAP16[i3 >> 1] = i26;
+      i23 = i24 + -16 + i23 | 0;
+     } else {
+      i23 = i23 + i24 | 0;
+     }
+     HEAP32[i4 >> 2] = i23;
+     i22 = i22 + -1 | 0;
+    } while ((i22 | 0) != 0);
+   }
+  } while (0);
+  if (i19 << 16 >> 16 == 0) {
+   i24 = i15;
+   i21 = 138;
+   i23 = 3;
+   i15 = i16;
+   continue;
+  }
+  i24 = i15;
+  i21 = i17 ? 6 : 7;
+  i23 = i17 ? 3 : 4;
+  i15 = i16;
+ }
+ STACKTOP = i11;
+ return;
+}
+function __tr_flush_block(i2, i4, i6, i3) {
+ i2 = i2 | 0;
+ i4 = i4 | 0;
+ i6 = i6 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0;
+ i1 = STACKTOP;
+ if ((HEAP32[i2 + 132 >> 2] | 0) > 0) {
+  i5 = (HEAP32[i2 >> 2] | 0) + 44 | 0;
+  if ((HEAP32[i5 >> 2] | 0) == 2) {
+   i8 = -201342849;
+   i9 = 0;
+   while (1) {
+    if ((i8 & 1 | 0) != 0 ? (HEAP16[i2 + (i9 << 2) + 148 >> 1] | 0) != 0 : 0) {
+     i8 = 0;
+     break;
+    }
+    i9 = i9 + 1 | 0;
+    if ((i9 | 0) < 32) {
+     i8 = i8 >>> 1;
+    } else {
+     i7 = 6;
+     break;
+    }
+   }
+   L9 : do {
+    if ((i7 | 0) == 6) {
+     if (((HEAP16[i2 + 184 >> 1] | 0) == 0 ? (HEAP16[i2 + 188 >> 1] | 0) == 0 : 0) ? (HEAP16[i2 + 200 >> 1] | 0) == 0 : 0) {
+      i8 = 32;
+      while (1) {
+       i7 = i8 + 1 | 0;
+       if ((HEAP16[i2 + (i8 << 2) + 148 >> 1] | 0) != 0) {
+        i8 = 1;
+        break L9;
+       }
+       if ((i7 | 0) < 256) {
+        i8 = i7;
+       } else {
+        i8 = 0;
+        break;
+       }
+      }
+     } else {
+      i8 = 1;
+     }
+    }
+   } while (0);
+   HEAP32[i5 >> 2] = i8;
+  }
+  _build_tree(i2, i2 + 2840 | 0);
+  _build_tree(i2, i2 + 2852 | 0);
+  _scan_tree(i2, i2 + 148 | 0, HEAP32[i2 + 2844 >> 2] | 0);
+  _scan_tree(i2, i2 + 2440 | 0, HEAP32[i2 + 2856 >> 2] | 0);
+  _build_tree(i2, i2 + 2864 | 0);
+  i5 = 18;
+  while (1) {
+   i7 = i5 + -1 | 0;
+   if ((HEAP16[i2 + (HEAPU8[2888 + i5 | 0] << 2) + 2686 >> 1] | 0) != 0) {
+    break;
+   }
+   if ((i7 | 0) > 2) {
+    i5 = i7;
+   } else {
+    i5 = i7;
+    break;
+   }
+  }
+  i10 = i2 + 5800 | 0;
+  i7 = (i5 * 3 | 0) + 17 + (HEAP32[i10 >> 2] | 0) | 0;
+  HEAP32[i10 >> 2] = i7;
+  i7 = (i7 + 10 | 0) >>> 3;
+  i10 = ((HEAP32[i2 + 5804 >> 2] | 0) + 10 | 0) >>> 3;
+  i9 = i10 >>> 0 > i7 >>> 0 ? i7 : i10;
+ } else {
+  i10 = i6 + 5 | 0;
+  i5 = 0;
+  i9 = i10;
+ }
+ do {
+  if ((i6 + 4 | 0) >>> 0 > i9 >>> 0 | (i4 | 0) == 0) {
+   i4 = i2 + 5820 | 0;
+   i7 = HEAP32[i4 >> 2] | 0;
+   i8 = (i7 | 0) > 13;
+   if ((HEAP32[i2 + 136 >> 2] | 0) == 4 | (i10 | 0) == (i9 | 0)) {
+    i9 = i3 + 2 & 65535;
+    i6 = i2 + 5816 | 0;
+    i5 = HEAPU16[i6 >> 1] | i9 << i7;
+    HEAP16[i6 >> 1] = i5;
+    if (i8) {
+     i12 = i2 + 20 | 0;
+     i13 = HEAP32[i12 >> 2] | 0;
+     HEAP32[i12 >> 2] = i13 + 1;
+     i14 = i2 + 8 | 0;
+     HEAP8[(HEAP32[i14 >> 2] | 0) + i13 | 0] = i5;
+     i13 = (HEAPU16[i6 >> 1] | 0) >>> 8 & 255;
+     i5 = HEAP32[i12 >> 2] | 0;
+     HEAP32[i12 >> 2] = i5 + 1;
+     HEAP8[(HEAP32[i14 >> 2] | 0) + i5 | 0] = i13;
+     i5 = HEAP32[i4 >> 2] | 0;
+     HEAP16[i6 >> 1] = i9 >>> (16 - i5 | 0);
+     i5 = i5 + -13 | 0;
+    } else {
+     i5 = i7 + 3 | 0;
+    }
+    HEAP32[i4 >> 2] = i5;
+    _compress_block(i2, 1136, 2288);
+    break;
+   }
+   i10 = i3 + 4 & 65535;
+   i6 = i2 + 5816 | 0;
+   i9 = HEAPU16[i6 >> 1] | i10 << i7;
+   HEAP16[i6 >> 1] = i9;
+   if (i8) {
+    i13 = i2 + 20 | 0;
+    i12 = HEAP32[i13 >> 2] | 0;
+    HEAP32[i13 >> 2] = i12 + 1;
+    i14 = i2 + 8 | 0;
+    HEAP8[(HEAP32[i14 >> 2] | 0) + i12 | 0] = i9;
+    i9 = (HEAPU16[i6 >> 1] | 0) >>> 8 & 255;
+    i12 = HEAP32[i13 >> 2] | 0;
+    HEAP32[i13 >> 2] = i12 + 1;
+    HEAP8[(HEAP32[i14 >> 2] | 0) + i12 | 0] = i9;
+    i12 = HEAP32[i4 >> 2] | 0;
+    i9 = i10 >>> (16 - i12 | 0);
+    HEAP16[i6 >> 1] = i9;
+    i12 = i12 + -13 | 0;
+   } else {
+    i12 = i7 + 3 | 0;
+   }
+   HEAP32[i4 >> 2] = i12;
+   i7 = HEAP32[i2 + 2844 >> 2] | 0;
+   i8 = HEAP32[i2 + 2856 >> 2] | 0;
+   i10 = i7 + 65280 & 65535;
+   i11 = i9 & 65535 | i10 << i12;
+   HEAP16[i6 >> 1] = i11;
+   if ((i12 | 0) > 11) {
+    i13 = i2 + 20 | 0;
+    i9 = HEAP32[i13 >> 2] | 0;
+    HEAP32[i13 >> 2] = i9 + 1;
+    i14 = i2 + 8 | 0;
+    HEAP8[(HEAP32[i14 >> 2] | 0) + i9 | 0] = i11;
+    i11 = (HEAPU16[i6 >> 1] | 0) >>> 8 & 255;
+    i9 = HEAP32[i13 >> 2] | 0;
+    HEAP32[i13 >> 2] = i9 + 1;
+    HEAP8[(HEAP32[i14 >> 2] | 0) + i9 | 0] = i11;
+    i9 = HEAP32[i4 >> 2] | 0;
+    i11 = i10 >>> (16 - i9 | 0);
+    HEAP16[i6 >> 1] = i11;
+    i9 = i9 + -11 | 0;
+   } else {
+    i9 = i12 + 5 | 0;
+   }
+   HEAP32[i4 >> 2] = i9;
+   i10 = i8 & 65535;
+   i11 = i10 << i9 | i11 & 65535;
+   HEAP16[i6 >> 1] = i11;
+   if ((i9 | 0) > 11) {
+    i13 = i2 + 20 | 0;
+    i9 = HEAP32[i13 >> 2] | 0;
+    HEAP32[i13 >> 2] = i9 + 1;
+    i14 = i2 + 8 | 0;
+    HEAP8[(HEAP32[i14 >> 2] | 0) + i9 | 0] = i11;
+    i11 = (HEAPU16[i6 >> 1] | 0) >>> 8 & 255;
+    i9 = HEAP32[i13 >> 2] | 0;
+    HEAP32[i13 >> 2] = i9 + 1;
+    HEAP8[(HEAP32[i14 >> 2] | 0) + i9 | 0] = i11;
+    i9 = HEAP32[i4 >> 2] | 0;
+    i11 = i10 >>> (16 - i9 | 0);
+    HEAP16[i6 >> 1] = i11;
+    i9 = i9 + -11 | 0;
+   } else {
+    i9 = i9 + 5 | 0;
+   }
+   HEAP32[i4 >> 2] = i9;
+   i10 = i5 + 65533 & 65535;
+   i14 = i10 << i9 | i11 & 65535;
+   HEAP16[i6 >> 1] = i14;
+   if ((i9 | 0) > 12) {
+    i12 = i2 + 20 | 0;
+    i11 = HEAP32[i12 >> 2] | 0;
+    HEAP32[i12 >> 2] = i11 + 1;
+    i13 = i2 + 8 | 0;
+    HEAP8[(HEAP32[i13 >> 2] | 0) + i11 | 0] = i14;
+    i14 = (HEAPU16[i6 >> 1] | 0) >>> 8 & 255;
+    i11 = HEAP32[i12 >> 2] | 0;
+    HEAP32[i12 >> 2] = i11 + 1;
+    HEAP8[(HEAP32[i13 >> 2] | 0) + i11 | 0] = i14;
+    i11 = HEAP32[i4 >> 2] | 0;
+    i14 = i10 >>> (16 - i11 | 0);
+    HEAP16[i6 >> 1] = i14;
+    i11 = i11 + -12 | 0;
+   } else {
+    i11 = i9 + 4 | 0;
+   }
+   HEAP32[i4 >> 2] = i11;
+   if ((i5 | 0) > -1) {
+    i10 = i2 + 20 | 0;
+    i9 = i2 + 8 | 0;
+    i12 = 0;
+    while (1) {
+     i13 = HEAPU16[i2 + (HEAPU8[2888 + i12 | 0] << 2) + 2686 >> 1] | 0;
+     i14 = i13 << i11 | i14 & 65535;
+     HEAP16[i6 >> 1] = i14;
+     if ((i11 | 0) > 13) {
+      i11 = HEAP32[i10 >> 2] | 0;
+      HEAP32[i10 >> 2] = i11 + 1;
+      HEAP8[(HEAP32[i9 >> 2] | 0) + i11 | 0] = i14;
+      i14 = (HEAPU16[i6 >> 1] | 0) >>> 8 & 255;
+      i11 = HEAP32[i10 >> 2] | 0;
+      HEAP32[i10 >> 2] = i11 + 1;
+      HEAP8[(HEAP32[i9 >> 2] | 0) + i11 | 0] = i14;
+      i11 = HEAP32[i4 >> 2] | 0;
+      i14 = i13 >>> (16 - i11 | 0);
+      HEAP16[i6 >> 1] = i14;
+      i11 = i11 + -13 | 0;
+     } else {
+      i11 = i11 + 3 | 0;
+     }
+     HEAP32[i4 >> 2] = i11;
+     if ((i12 | 0) == (i5 | 0)) {
+      break;
+     } else {
+      i12 = i12 + 1 | 0;
+     }
+    }
+   }
+   i13 = i2 + 148 | 0;
+   _send_tree(i2, i13, i7);
+   i14 = i2 + 2440 | 0;
+   _send_tree(i2, i14, i8);
+   _compress_block(i2, i13, i14);
+  } else {
+   __tr_stored_block(i2, i4, i6, i3);
+  }
+ } while (0);
+ _init_block(i2);
+ if ((i3 | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ i3 = i2 + 5820 | 0;
+ i4 = HEAP32[i3 >> 2] | 0;
+ if ((i4 | 0) <= 8) {
+  i5 = i2 + 5816 | 0;
+  if ((i4 | 0) > 0) {
+   i13 = HEAP16[i5 >> 1] & 255;
+   i12 = i2 + 20 | 0;
+   i14 = HEAP32[i12 >> 2] | 0;
+   HEAP32[i12 >> 2] = i14 + 1;
+   HEAP8[(HEAP32[i2 + 8 >> 2] | 0) + i14 | 0] = i13;
+  }
+ } else {
+  i5 = i2 + 5816 | 0;
+  i14 = HEAP16[i5 >> 1] & 255;
+  i11 = i2 + 20 | 0;
+  i12 = HEAP32[i11 >> 2] | 0;
+  HEAP32[i11 >> 2] = i12 + 1;
+  i13 = i2 + 8 | 0;
+  HEAP8[(HEAP32[i13 >> 2] | 0) + i12 | 0] = i14;
+  i12 = (HEAPU16[i5 >> 1] | 0) >>> 8 & 255;
+  i14 = HEAP32[i11 >> 2] | 0;
+  HEAP32[i11 >> 2] = i14 + 1;
+  HEAP8[(HEAP32[i13 >> 2] | 0) + i14 | 0] = i12;
+ }
+ HEAP16[i5 >> 1] = 0;
+ HEAP32[i3 >> 2] = 0;
+ STACKTOP = i1;
+ return;
+}
+function _deflate_fast(i3, i6) {
+ i3 = i3 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i2 = 0, i4 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0, i33 = 0, i34 = 0, i35 = 0, i36 = 0;
+ i1 = STACKTOP;
+ i20 = i3 + 116 | 0;
+ i22 = (i6 | 0) == 0;
+ i23 = i3 + 72 | 0;
+ i24 = i3 + 88 | 0;
+ i5 = i3 + 108 | 0;
+ i7 = i3 + 56 | 0;
+ i9 = i3 + 84 | 0;
+ i10 = i3 + 68 | 0;
+ i11 = i3 + 52 | 0;
+ i12 = i3 + 64 | 0;
+ i19 = i3 + 44 | 0;
+ i21 = i3 + 96 | 0;
+ i16 = i3 + 112 | 0;
+ i13 = i3 + 5792 | 0;
+ i17 = i3 + 5796 | 0;
+ i18 = i3 + 5784 | 0;
+ i14 = i3 + 5788 | 0;
+ i15 = i3 + 128 | 0;
+ i4 = i3 + 92 | 0;
+ while (1) {
+  if ((HEAP32[i20 >> 2] | 0) >>> 0 < 262) {
+   _fill_window(i3);
+   i25 = HEAP32[i20 >> 2] | 0;
+   if (i25 >>> 0 < 262 & i22) {
+    i2 = 0;
+    i25 = 34;
+    break;
+   }
+   if ((i25 | 0) == 0) {
+    i25 = 26;
+    break;
+   }
+   if (!(i25 >>> 0 > 2)) {
+    i25 = 9;
+   } else {
+    i25 = 6;
+   }
+  } else {
+   i25 = 6;
+  }
+  if ((i25 | 0) == 6) {
+   i25 = 0;
+   i26 = HEAP32[i5 >> 2] | 0;
+   i34 = ((HEAPU8[(HEAP32[i7 >> 2] | 0) + (i26 + 2) | 0] | 0) ^ HEAP32[i23 >> 2] << HEAP32[i24 >> 2]) & HEAP32[i9 >> 2];
+   HEAP32[i23 >> 2] = i34;
+   i34 = (HEAP32[i10 >> 2] | 0) + (i34 << 1) | 0;
+   i35 = HEAP16[i34 >> 1] | 0;
+   HEAP16[(HEAP32[i12 >> 2] | 0) + ((HEAP32[i11 >> 2] & i26) << 1) >> 1] = i35;
+   i27 = i35 & 65535;
+   HEAP16[i34 >> 1] = i26;
+   if (!(i35 << 16 >> 16 == 0) ? !((i26 - i27 | 0) >>> 0 > ((HEAP32[i19 >> 2] | 0) + -262 | 0) >>> 0) : 0) {
+    i26 = _longest_match(i3, i27) | 0;
+    HEAP32[i21 >> 2] = i26;
+   } else {
+    i25 = 9;
+   }
+  }
+  if ((i25 | 0) == 9) {
+   i26 = HEAP32[i21 >> 2] | 0;
+  }
+  do {
+   if (i26 >>> 0 > 2) {
+    i35 = i26 + 253 | 0;
+    i25 = (HEAP32[i5 >> 2] | 0) - (HEAP32[i16 >> 2] | 0) | 0;
+    i34 = HEAP32[i13 >> 2] | 0;
+    HEAP16[(HEAP32[i17 >> 2] | 0) + (i34 << 1) >> 1] = i25;
+    HEAP32[i13 >> 2] = i34 + 1;
+    HEAP8[(HEAP32[i18 >> 2] | 0) + i34 | 0] = i35;
+    i35 = i3 + ((HEAPU8[808 + (i35 & 255) | 0] | 0 | 256) + 1 << 2) + 148 | 0;
+    HEAP16[i35 >> 1] = (HEAP16[i35 >> 1] | 0) + 1 << 16 >> 16;
+    i25 = i25 + 65535 & 65535;
+    if (!(i25 >>> 0 < 256)) {
+     i25 = (i25 >>> 7) + 256 | 0;
+    }
+    i25 = i3 + ((HEAPU8[296 + i25 | 0] | 0) << 2) + 2440 | 0;
+    HEAP16[i25 >> 1] = (HEAP16[i25 >> 1] | 0) + 1 << 16 >> 16;
+    i25 = (HEAP32[i13 >> 2] | 0) == ((HEAP32[i14 >> 2] | 0) + -1 | 0) | 0;
+    i26 = HEAP32[i21 >> 2] | 0;
+    i35 = (HEAP32[i20 >> 2] | 0) - i26 | 0;
+    HEAP32[i20 >> 2] = i35;
+    if (!(i26 >>> 0 <= (HEAP32[i15 >> 2] | 0) >>> 0 & i35 >>> 0 > 2)) {
+     i26 = (HEAP32[i5 >> 2] | 0) + i26 | 0;
+     HEAP32[i5 >> 2] = i26;
+     HEAP32[i21 >> 2] = 0;
+     i34 = HEAP32[i7 >> 2] | 0;
+     i35 = HEAPU8[i34 + i26 | 0] | 0;
+     HEAP32[i23 >> 2] = i35;
+     HEAP32[i23 >> 2] = ((HEAPU8[i34 + (i26 + 1) | 0] | 0) ^ i35 << HEAP32[i24 >> 2]) & HEAP32[i9 >> 2];
+     break;
+    }
+    i30 = i26 + -1 | 0;
+    HEAP32[i21 >> 2] = i30;
+    i34 = HEAP32[i24 >> 2] | 0;
+    i33 = HEAP32[i7 >> 2] | 0;
+    i35 = HEAP32[i9 >> 2] | 0;
+    i32 = HEAP32[i10 >> 2] | 0;
+    i27 = HEAP32[i11 >> 2] | 0;
+    i29 = HEAP32[i12 >> 2] | 0;
+    i26 = HEAP32[i5 >> 2] | 0;
+    i31 = HEAP32[i23 >> 2] | 0;
+    while (1) {
+     i28 = i26 + 1 | 0;
+     HEAP32[i5 >> 2] = i28;
+     i31 = ((HEAPU8[i33 + (i26 + 3) | 0] | 0) ^ i31 << i34) & i35;
+     HEAP32[i23 >> 2] = i31;
+     i36 = i32 + (i31 << 1) | 0;
+     HEAP16[i29 + ((i27 & i28) << 1) >> 1] = HEAP16[i36 >> 1] | 0;
+     HEAP16[i36 >> 1] = i28;
+     i30 = i30 + -1 | 0;
+     HEAP32[i21 >> 2] = i30;
+     if ((i30 | 0) == 0) {
+      break;
+     } else {
+      i26 = i28;
+     }
+    }
+    i26 = i26 + 2 | 0;
+    HEAP32[i5 >> 2] = i26;
+   } else {
+    i25 = HEAP8[(HEAP32[i7 >> 2] | 0) + (HEAP32[i5 >> 2] | 0) | 0] | 0;
+    i26 = HEAP32[i13 >> 2] | 0;
+    HEAP16[(HEAP32[i17 >> 2] | 0) + (i26 << 1) >> 1] = 0;
+    HEAP32[i13 >> 2] = i26 + 1;
+    HEAP8[(HEAP32[i18 >> 2] | 0) + i26 | 0] = i25;
+    i25 = i3 + ((i25 & 255) << 2) + 148 | 0;
+    HEAP16[i25 >> 1] = (HEAP16[i25 >> 1] | 0) + 1 << 16 >> 16;
+    i25 = (HEAP32[i13 >> 2] | 0) == ((HEAP32[i14 >> 2] | 0) + -1 | 0) | 0;
+    HEAP32[i20 >> 2] = (HEAP32[i20 >> 2] | 0) + -1;
+    i26 = (HEAP32[i5 >> 2] | 0) + 1 | 0;
+    HEAP32[i5 >> 2] = i26;
+   }
+  } while (0);
+  if ((i25 | 0) == 0) {
+   continue;
+  }
+  i25 = HEAP32[i4 >> 2] | 0;
+  if ((i25 | 0) > -1) {
+   i27 = (HEAP32[i7 >> 2] | 0) + i25 | 0;
+  } else {
+   i27 = 0;
+  }
+  __tr_flush_block(i3, i27, i26 - i25 | 0, 0);
+  HEAP32[i4 >> 2] = HEAP32[i5 >> 2];
+  i27 = HEAP32[i3 >> 2] | 0;
+  i28 = i27 + 28 | 0;
+  i25 = HEAP32[i28 >> 2] | 0;
+  i30 = HEAP32[i25 + 20 >> 2] | 0;
+  i26 = i27 + 16 | 0;
+  i29 = HEAP32[i26 >> 2] | 0;
+  i29 = i30 >>> 0 > i29 >>> 0 ? i29 : i30;
+  if ((i29 | 0) != 0 ? (i8 = i27 + 12 | 0, _memcpy(HEAP32[i8 >> 2] | 0, HEAP32[i25 + 16 >> 2] | 0, i29 | 0) | 0, HEAP32[i8 >> 2] = (HEAP32[i8 >> 2] | 0) + i29, i8 = (HEAP32[i28 >> 2] | 0) + 16 | 0, HEAP32[i8 >> 2] = (HEAP32[i8 >> 2] | 0) + i29, i8 = i27 + 20 | 0, HEAP32[i8 >> 2] = (HEAP32[i8 >> 2] | 0) + i29, HEAP32[i26 >> 2] = (HEAP32[i26 >> 2] | 0) - i29, i8 = HEAP32[i28 >> 2] | 0, i35 = i8 + 20 | 0, i36 = HEAP32[i35 >> 2] | 0, HEAP32[i35 >> 2] = i36 - i29, (i36 | 0) == (i29 | 0)) : 0) {
+   HEAP32[i8 + 16 >> 2] = HEAP32[i8 + 8 >> 2];
+  }
+  if ((HEAP32[(HEAP32[i3 >> 2] | 0) + 16 >> 2] | 0) == 0) {
+   i2 = 0;
+   i25 = 34;
+   break;
+  }
+ }
+ if ((i25 | 0) == 26) {
+  i8 = HEAP32[i4 >> 2] | 0;
+  if ((i8 | 0) > -1) {
+   i7 = (HEAP32[i7 >> 2] | 0) + i8 | 0;
+  } else {
+   i7 = 0;
+  }
+  i6 = (i6 | 0) == 4;
+  __tr_flush_block(i3, i7, (HEAP32[i5 >> 2] | 0) - i8 | 0, i6 & 1);
+  HEAP32[i4 >> 2] = HEAP32[i5 >> 2];
+  i5 = HEAP32[i3 >> 2] | 0;
+  i7 = i5 + 28 | 0;
+  i4 = HEAP32[i7 >> 2] | 0;
+  i10 = HEAP32[i4 + 20 >> 2] | 0;
+  i8 = i5 + 16 | 0;
+  i9 = HEAP32[i8 >> 2] | 0;
+  i9 = i10 >>> 0 > i9 >>> 0 ? i9 : i10;
+  if ((i9 | 0) != 0 ? (i2 = i5 + 12 | 0, _memcpy(HEAP32[i2 >> 2] | 0, HEAP32[i4 + 16 >> 2] | 0, i9 | 0) | 0, HEAP32[i2 >> 2] = (HEAP32[i2 >> 2] | 0) + i9, i2 = (HEAP32[i7 >> 2] | 0) + 16 | 0, HEAP32[i2 >> 2] = (HEAP32[i2 >> 2] | 0) + i9, i2 = i5 + 20 | 0, HEAP32[i2 >> 2] = (HEAP32[i2 >> 2] | 0) + i9, HEAP32[i8 >> 2] = (HEAP32[i8 >> 2] | 0) - i9, i2 = HEAP32[i7 >> 2] | 0, i35 = i2 + 20 | 0, i36 = HEAP32[i35 >> 2] | 0, HEAP32[i35 >> 2] = i36 - i9, (i36 | 0) == (i9 | 0)) : 0) {
+   HEAP32[i2 + 16 >> 2] = HEAP32[i2 + 8 >> 2];
+  }
+  if ((HEAP32[(HEAP32[i3 >> 2] | 0) + 16 >> 2] | 0) == 0) {
+   i36 = i6 ? 2 : 0;
+   STACKTOP = i1;
+   return i36 | 0;
+  } else {
+   i36 = i6 ? 3 : 1;
+   STACKTOP = i1;
+   return i36 | 0;
+  }
+ } else if ((i25 | 0) == 34) {
+  STACKTOP = i1;
+  return i2 | 0;
+ }
+ return 0;
+}
+function _inflate_table(i11, i5, i13, i2, i1, i10) {
+ i11 = i11 | 0;
+ i5 = i5 | 0;
+ i13 = i13 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ i10 = i10 | 0;
+ var i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i12 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0, i25 = 0, i26 = 0, i27 = 0, i28 = 0, i29 = 0, i30 = 0, i31 = 0, i32 = 0, i33 = 0;
+ i3 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i7 = i3 + 32 | 0;
+ i12 = i3;
+ i4 = i7 + 0 | 0;
+ i9 = i4 + 32 | 0;
+ do {
+  HEAP16[i4 >> 1] = 0;
+  i4 = i4 + 2 | 0;
+ } while ((i4 | 0) < (i9 | 0));
+ i14 = (i13 | 0) == 0;
+ if (!i14) {
+  i4 = 0;
+  do {
+   i32 = i7 + (HEAPU16[i5 + (i4 << 1) >> 1] << 1) | 0;
+   HEAP16[i32 >> 1] = (HEAP16[i32 >> 1] | 0) + 1 << 16 >> 16;
+   i4 = i4 + 1 | 0;
+  } while ((i4 | 0) != (i13 | 0));
+ }
+ i4 = HEAP32[i1 >> 2] | 0;
+ i9 = 15;
+ while (1) {
+  i15 = i9 + -1 | 0;
+  if ((HEAP16[i7 + (i9 << 1) >> 1] | 0) != 0) {
+   break;
+  }
+  if ((i15 | 0) == 0) {
+   i6 = 7;
+   break;
+  } else {
+   i9 = i15;
+  }
+ }
+ if ((i6 | 0) == 7) {
+  i32 = HEAP32[i2 >> 2] | 0;
+  HEAP32[i2 >> 2] = i32 + 4;
+  HEAP8[i32] = 64;
+  HEAP8[i32 + 1 | 0] = 1;
+  HEAP16[i32 + 2 >> 1] = 0;
+  i32 = HEAP32[i2 >> 2] | 0;
+  HEAP32[i2 >> 2] = i32 + 4;
+  HEAP8[i32] = 64;
+  HEAP8[i32 + 1 | 0] = 1;
+  HEAP16[i32 + 2 >> 1] = 0;
+  HEAP32[i1 >> 2] = 1;
+  i32 = 0;
+  STACKTOP = i3;
+  return i32 | 0;
+ }
+ i4 = i4 >>> 0 > i9 >>> 0 ? i9 : i4;
+ L12 : do {
+  if (i9 >>> 0 > 1) {
+   i27 = 1;
+   while (1) {
+    i15 = i27 + 1 | 0;
+    if ((HEAP16[i7 + (i27 << 1) >> 1] | 0) != 0) {
+     break L12;
+    }
+    if (i15 >>> 0 < i9 >>> 0) {
+     i27 = i15;
+    } else {
+     i27 = i15;
+     break;
+    }
+   }
+  } else {
+   i27 = 1;
+  }
+ } while (0);
+ i4 = i4 >>> 0 < i27 >>> 0 ? i27 : i4;
+ i16 = 1;
+ i15 = 1;
+ do {
+  i16 = (i16 << 1) - (HEAPU16[i7 + (i15 << 1) >> 1] | 0) | 0;
+  i15 = i15 + 1 | 0;
+  if ((i16 | 0) < 0) {
+   i8 = -1;
+   i6 = 56;
+   break;
+  }
+ } while (i15 >>> 0 < 16);
+ if ((i6 | 0) == 56) {
+  STACKTOP = i3;
+  return i8 | 0;
+ }
+ if ((i16 | 0) > 0 ? !((i11 | 0) != 0 & (i9 | 0) == 1) : 0) {
+  i32 = -1;
+  STACKTOP = i3;
+  return i32 | 0;
+ }
+ HEAP16[i12 + 2 >> 1] = 0;
+ i16 = 0;
+ i15 = 1;
+ do {
+  i16 = (HEAPU16[i7 + (i15 << 1) >> 1] | 0) + (i16 & 65535) | 0;
+  i15 = i15 + 1 | 0;
+  HEAP16[i12 + (i15 << 1) >> 1] = i16;
+ } while ((i15 | 0) != 15);
+ if (!i14) {
+  i15 = 0;
+  do {
+   i14 = HEAP16[i5 + (i15 << 1) >> 1] | 0;
+   if (!(i14 << 16 >> 16 == 0)) {
+    i31 = i12 + ((i14 & 65535) << 1) | 0;
+    i32 = HEAP16[i31 >> 1] | 0;
+    HEAP16[i31 >> 1] = i32 + 1 << 16 >> 16;
+    HEAP16[i10 + ((i32 & 65535) << 1) >> 1] = i15;
+   }
+   i15 = i15 + 1 | 0;
+  } while ((i15 | 0) != (i13 | 0));
+ }
+ if ((i11 | 0) == 1) {
+  i14 = 1 << i4;
+  if (i14 >>> 0 > 851) {
+   i32 = 1;
+   STACKTOP = i3;
+   return i32 | 0;
+  } else {
+   i16 = 0;
+   i20 = 1;
+   i17 = 14128 + -514 | 0;
+   i19 = 256;
+   i18 = 14192 + -514 | 0;
+  }
+ } else if ((i11 | 0) != 0) {
+  i14 = 1 << i4;
+  i16 = (i11 | 0) == 2;
+  if (i16 & i14 >>> 0 > 591) {
+   i32 = 1;
+   STACKTOP = i3;
+   return i32 | 0;
+  } else {
+   i20 = 0;
+   i17 = 14256;
+   i19 = -1;
+   i18 = 14320;
+  }
+ } else {
+  i16 = 0;
+  i14 = 1 << i4;
+  i20 = 0;
+  i17 = i10;
+  i19 = 19;
+  i18 = i10;
+ }
+ i11 = i14 + -1 | 0;
+ i12 = i4 & 255;
+ i22 = i4;
+ i21 = 0;
+ i25 = 0;
+ i13 = -1;
+ i15 = HEAP32[i2 >> 2] | 0;
+ i24 = 0;
+ L44 : while (1) {
+  i23 = 1 << i22;
+  while (1) {
+   i29 = i27 - i21 | 0;
+   i22 = i29 & 255;
+   i28 = HEAP16[i10 + (i24 << 1) >> 1] | 0;
+   i30 = i28 & 65535;
+   if ((i30 | 0) >= (i19 | 0)) {
+    if ((i30 | 0) > (i19 | 0)) {
+     i26 = HEAP16[i18 + (i30 << 1) >> 1] & 255;
+     i28 = HEAP16[i17 + (i30 << 1) >> 1] | 0;
+    } else {
+     i26 = 96;
+     i28 = 0;
+    }
+   } else {
+    i26 = 0;
+   }
+   i31 = 1 << i29;
+   i30 = i25 >>> i21;
+   i32 = i23;
+   while (1) {
+    i29 = i32 - i31 | 0;
+    i33 = i29 + i30 | 0;
+    HEAP8[i15 + (i33 << 2) | 0] = i26;
+    HEAP8[i15 + (i33 << 2) + 1 | 0] = i22;
+    HEAP16[i15 + (i33 << 2) + 2 >> 1] = i28;
+    if ((i32 | 0) == (i31 | 0)) {
+     break;
+    } else {
+     i32 = i29;
+    }
+   }
+   i26 = 1 << i27 + -1;
+   while (1) {
+    if ((i26 & i25 | 0) == 0) {
+     break;
+    } else {
+     i26 = i26 >>> 1;
+    }
+   }
+   if ((i26 | 0) == 0) {
+    i25 = 0;
+   } else {
+    i25 = (i26 + -1 & i25) + i26 | 0;
+   }
+   i24 = i24 + 1 | 0;
+   i32 = i7 + (i27 << 1) | 0;
+   i33 = (HEAP16[i32 >> 1] | 0) + -1 << 16 >> 16;
+   HEAP16[i32 >> 1] = i33;
+   if (i33 << 16 >> 16 == 0) {
+    if ((i27 | 0) == (i9 | 0)) {
+     break L44;
+    }
+    i27 = HEAPU16[i5 + (HEAPU16[i10 + (i24 << 1) >> 1] << 1) >> 1] | 0;
+   }
+   if (!(i27 >>> 0 > i4 >>> 0)) {
+    continue;
+   }
+   i26 = i25 & i11;
+   if ((i26 | 0) != (i13 | 0)) {
+    break;
+   }
+  }
+  i28 = (i21 | 0) == 0 ? i4 : i21;
+  i23 = i15 + (i23 << 2) | 0;
+  i31 = i27 - i28 | 0;
+  L67 : do {
+   if (i27 >>> 0 < i9 >>> 0) {
+    i29 = i27;
+    i30 = i31;
+    i31 = 1 << i31;
+    while (1) {
+     i31 = i31 - (HEAPU16[i7 + (i29 << 1) >> 1] | 0) | 0;
+     if ((i31 | 0) < 1) {
+      break L67;
+     }
+     i30 = i30 + 1 | 0;
+     i29 = i30 + i28 | 0;
+     if (i29 >>> 0 < i9 >>> 0) {
+      i31 = i31 << 1;
+     } else {
+      break;
+     }
+    }
+   } else {
+    i30 = i31;
+   }
+  } while (0);
+  i29 = (1 << i30) + i14 | 0;
+  if (i20 & i29 >>> 0 > 851 | i16 & i29 >>> 0 > 591) {
+   i8 = 1;
+   i6 = 56;
+   break;
+  }
+  HEAP8[(HEAP32[i2 >> 2] | 0) + (i26 << 2) | 0] = i30;
+  HEAP8[(HEAP32[i2 >> 2] | 0) + (i26 << 2) + 1 | 0] = i12;
+  i22 = HEAP32[i2 >> 2] | 0;
+  HEAP16[i22 + (i26 << 2) + 2 >> 1] = (i23 - i22 | 0) >>> 2;
+  i22 = i30;
+  i21 = i28;
+  i13 = i26;
+  i15 = i23;
+  i14 = i29;
+ }
+ if ((i6 | 0) == 56) {
+  STACKTOP = i3;
+  return i8 | 0;
+ }
+ L77 : do {
+  if ((i25 | 0) != 0) {
+   do {
+    if ((i21 | 0) != 0) {
+     if ((i25 & i11 | 0) != (i13 | 0)) {
+      i21 = 0;
+      i22 = i12;
+      i9 = i4;
+      i15 = HEAP32[i2 >> 2] | 0;
+     }
+    } else {
+     i21 = 0;
+    }
+    i5 = i25 >>> i21;
+    HEAP8[i15 + (i5 << 2) | 0] = 64;
+    HEAP8[i15 + (i5 << 2) + 1 | 0] = i22;
+    HEAP16[i15 + (i5 << 2) + 2 >> 1] = 0;
+    i5 = 1 << i9 + -1;
+    while (1) {
+     if ((i5 & i25 | 0) == 0) {
+      break;
+     } else {
+      i5 = i5 >>> 1;
+     }
+    }
+    if ((i5 | 0) == 0) {
+     break L77;
+    }
+    i25 = (i5 + -1 & i25) + i5 | 0;
+   } while ((i25 | 0) != 0);
+  }
+ } while (0);
+ HEAP32[i2 >> 2] = (HEAP32[i2 >> 2] | 0) + (i14 << 2);
+ HEAP32[i1 >> 2] = i4;
+ i33 = 0;
+ STACKTOP = i3;
+ return i33 | 0;
+}
+function _compress_block(i1, i3, i7) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i7 = i7 | 0;
+ var i2 = 0, i4 = 0, i5 = 0, i6 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0;
+ i2 = STACKTOP;
+ i11 = i1 + 5792 | 0;
+ if ((HEAP32[i11 >> 2] | 0) == 0) {
+  i14 = HEAP32[i1 + 5820 >> 2] | 0;
+  i17 = HEAP16[i1 + 5816 >> 1] | 0;
+ } else {
+  i9 = i1 + 5796 | 0;
+  i10 = i1 + 5784 | 0;
+  i8 = i1 + 5820 | 0;
+  i12 = i1 + 5816 | 0;
+  i5 = i1 + 20 | 0;
+  i6 = i1 + 8 | 0;
+  i14 = 0;
+  while (1) {
+   i20 = HEAP16[(HEAP32[i9 >> 2] | 0) + (i14 << 1) >> 1] | 0;
+   i13 = i20 & 65535;
+   i4 = i14 + 1 | 0;
+   i14 = HEAPU8[(HEAP32[i10 >> 2] | 0) + i14 | 0] | 0;
+   do {
+    if (i20 << 16 >> 16 == 0) {
+     i15 = HEAPU16[i3 + (i14 << 2) + 2 >> 1] | 0;
+     i13 = HEAP32[i8 >> 2] | 0;
+     i14 = HEAPU16[i3 + (i14 << 2) >> 1] | 0;
+     i16 = HEAPU16[i12 >> 1] | 0 | i14 << i13;
+     i17 = i16 & 65535;
+     HEAP16[i12 >> 1] = i17;
+     if ((i13 | 0) > (16 - i15 | 0)) {
+      i17 = HEAP32[i5 >> 2] | 0;
+      HEAP32[i5 >> 2] = i17 + 1;
+      HEAP8[(HEAP32[i6 >> 2] | 0) + i17 | 0] = i16;
+      i17 = (HEAPU16[i12 >> 1] | 0) >>> 8 & 255;
+      i20 = HEAP32[i5 >> 2] | 0;
+      HEAP32[i5 >> 2] = i20 + 1;
+      HEAP8[(HEAP32[i6 >> 2] | 0) + i20 | 0] = i17;
+      i20 = HEAP32[i8 >> 2] | 0;
+      i17 = i14 >>> (16 - i20 | 0) & 65535;
+      HEAP16[i12 >> 1] = i17;
+      i14 = i15 + -16 + i20 | 0;
+      HEAP32[i8 >> 2] = i14;
+      break;
+     } else {
+      i14 = i13 + i15 | 0;
+      HEAP32[i8 >> 2] = i14;
+      break;
+     }
+    } else {
+     i15 = HEAPU8[808 + i14 | 0] | 0;
+     i19 = (i15 | 256) + 1 | 0;
+     i18 = HEAPU16[i3 + (i19 << 2) + 2 >> 1] | 0;
+     i17 = HEAP32[i8 >> 2] | 0;
+     i19 = HEAPU16[i3 + (i19 << 2) >> 1] | 0;
+     i20 = HEAPU16[i12 >> 1] | 0 | i19 << i17;
+     i16 = i20 & 65535;
+     HEAP16[i12 >> 1] = i16;
+     if ((i17 | 0) > (16 - i18 | 0)) {
+      i16 = HEAP32[i5 >> 2] | 0;
+      HEAP32[i5 >> 2] = i16 + 1;
+      HEAP8[(HEAP32[i6 >> 2] | 0) + i16 | 0] = i20;
+      i16 = (HEAPU16[i12 >> 1] | 0) >>> 8 & 255;
+      i20 = HEAP32[i5 >> 2] | 0;
+      HEAP32[i5 >> 2] = i20 + 1;
+      HEAP8[(HEAP32[i6 >> 2] | 0) + i20 | 0] = i16;
+      i20 = HEAP32[i8 >> 2] | 0;
+      i16 = i19 >>> (16 - i20 | 0) & 65535;
+      HEAP16[i12 >> 1] = i16;
+      i18 = i18 + -16 + i20 | 0;
+     } else {
+      i18 = i17 + i18 | 0;
+     }
+     HEAP32[i8 >> 2] = i18;
+     i17 = HEAP32[2408 + (i15 << 2) >> 2] | 0;
+     do {
+      if ((i15 + -8 | 0) >>> 0 < 20) {
+       i14 = i14 - (HEAP32[2528 + (i15 << 2) >> 2] | 0) & 65535;
+       i15 = i14 << i18 | i16 & 65535;
+       i16 = i15 & 65535;
+       HEAP16[i12 >> 1] = i16;
+       if ((i18 | 0) > (16 - i17 | 0)) {
+        i16 = HEAP32[i5 >> 2] | 0;
+        HEAP32[i5 >> 2] = i16 + 1;
+        HEAP8[(HEAP32[i6 >> 2] | 0) + i16 | 0] = i15;
+        i16 = (HEAPU16[i12 >> 1] | 0) >>> 8 & 255;
+        i20 = HEAP32[i5 >> 2] | 0;
+        HEAP32[i5 >> 2] = i20 + 1;
+        HEAP8[(HEAP32[i6 >> 2] | 0) + i20 | 0] = i16;
+        i20 = HEAP32[i8 >> 2] | 0;
+        i16 = i14 >>> (16 - i20 | 0) & 65535;
+        HEAP16[i12 >> 1] = i16;
+        i14 = i17 + -16 + i20 | 0;
+        HEAP32[i8 >> 2] = i14;
+        break;
+       } else {
+        i14 = i18 + i17 | 0;
+        HEAP32[i8 >> 2] = i14;
+        break;
+       }
+      } else {
+       i14 = i18;
+      }
+     } while (0);
+     i13 = i13 + -1 | 0;
+     if (i13 >>> 0 < 256) {
+      i15 = i13;
+     } else {
+      i15 = (i13 >>> 7) + 256 | 0;
+     }
+     i15 = HEAPU8[296 + i15 | 0] | 0;
+     i17 = HEAPU16[i7 + (i15 << 2) + 2 >> 1] | 0;
+     i18 = HEAPU16[i7 + (i15 << 2) >> 1] | 0;
+     i19 = i16 & 65535 | i18 << i14;
+     i16 = i19 & 65535;
+     HEAP16[i12 >> 1] = i16;
+     if ((i14 | 0) > (16 - i17 | 0)) {
+      i20 = HEAP32[i5 >> 2] | 0;
+      HEAP32[i5 >> 2] = i20 + 1;
+      HEAP8[(HEAP32[i6 >> 2] | 0) + i20 | 0] = i19;
+      i20 = (HEAPU16[i12 >> 1] | 0) >>> 8 & 255;
+      i14 = HEAP32[i5 >> 2] | 0;
+      HEAP32[i5 >> 2] = i14 + 1;
+      HEAP8[(HEAP32[i6 >> 2] | 0) + i14 | 0] = i20;
+      i14 = HEAP32[i8 >> 2] | 0;
+      i20 = i18 >>> (16 - i14 | 0) & 65535;
+      HEAP16[i12 >> 1] = i20;
+      i14 = i17 + -16 + i14 | 0;
+      i17 = i20;
+     } else {
+      i14 = i14 + i17 | 0;
+      i17 = i16;
+     }
+     HEAP32[i8 >> 2] = i14;
+     i16 = HEAP32[2648 + (i15 << 2) >> 2] | 0;
+     if ((i15 + -4 | 0) >>> 0 < 26) {
+      i13 = i13 - (HEAP32[2768 + (i15 << 2) >> 2] | 0) & 65535;
+      i15 = i13 << i14 | i17 & 65535;
+      i17 = i15 & 65535;
+      HEAP16[i12 >> 1] = i17;
+      if ((i14 | 0) > (16 - i16 | 0)) {
+       i17 = HEAP32[i5 >> 2] | 0;
+       HEAP32[i5 >> 2] = i17 + 1;
+       HEAP8[(HEAP32[i6 >> 2] | 0) + i17 | 0] = i15;
+       i17 = (HEAPU16[i12 >> 1] | 0) >>> 8 & 255;
+       i14 = HEAP32[i5 >> 2] | 0;
+       HEAP32[i5 >> 2] = i14 + 1;
+       HEAP8[(HEAP32[i6 >> 2] | 0) + i14 | 0] = i17;
+       i14 = HEAP32[i8 >> 2] | 0;
+       i17 = i13 >>> (16 - i14 | 0) & 65535;
+       HEAP16[i12 >> 1] = i17;
+       i14 = i16 + -16 + i14 | 0;
+       HEAP32[i8 >> 2] = i14;
+       break;
+      } else {
+       i14 = i14 + i16 | 0;
+       HEAP32[i8 >> 2] = i14;
+       break;
+      }
+     }
+    }
+   } while (0);
+   if (i4 >>> 0 < (HEAP32[i11 >> 2] | 0) >>> 0) {
+    i14 = i4;
+   } else {
+    break;
+   }
+  }
+ }
+ i5 = i3 + 1026 | 0;
+ i6 = HEAPU16[i5 >> 1] | 0;
+ i4 = i1 + 5820 | 0;
+ i3 = HEAPU16[i3 + 1024 >> 1] | 0;
+ i7 = i1 + 5816 | 0;
+ i8 = i17 & 65535 | i3 << i14;
+ HEAP16[i7 >> 1] = i8;
+ if ((i14 | 0) > (16 - i6 | 0)) {
+  i17 = i1 + 20 | 0;
+  i18 = HEAP32[i17 >> 2] | 0;
+  HEAP32[i17 >> 2] = i18 + 1;
+  i20 = i1 + 8 | 0;
+  HEAP8[(HEAP32[i20 >> 2] | 0) + i18 | 0] = i8;
+  i18 = (HEAPU16[i7 >> 1] | 0) >>> 8 & 255;
+  i19 = HEAP32[i17 >> 2] | 0;
+  HEAP32[i17 >> 2] = i19 + 1;
+  HEAP8[(HEAP32[i20 >> 2] | 0) + i19 | 0] = i18;
+  i19 = HEAP32[i4 >> 2] | 0;
+  HEAP16[i7 >> 1] = i3 >>> (16 - i19 | 0);
+  i19 = i6 + -16 + i19 | 0;
+  HEAP32[i4 >> 2] = i19;
+  i19 = HEAP16[i5 >> 1] | 0;
+  i19 = i19 & 65535;
+  i20 = i1 + 5812 | 0;
+  HEAP32[i20 >> 2] = i19;
+  STACKTOP = i2;
+  return;
+ } else {
+  i19 = i14 + i6 | 0;
+  HEAP32[i4 >> 2] = i19;
+  i19 = HEAP16[i5 >> 1] | 0;
+  i19 = i19 & 65535;
+  i20 = i1 + 5812 | 0;
+  HEAP32[i20 >> 2] = i19;
+  STACKTOP = i2;
+  return;
+ }
+}
+function _deflate_stored(i2, i5) {
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i3 = 0, i4 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0;
+ i1 = STACKTOP;
+ i4 = (HEAP32[i2 + 12 >> 2] | 0) + -5 | 0;
+ i11 = i4 >>> 0 < 65535 ? i4 : 65535;
+ i12 = i2 + 116 | 0;
+ i4 = i2 + 108 | 0;
+ i6 = i2 + 92 | 0;
+ i10 = i2 + 44 | 0;
+ i7 = i2 + 56 | 0;
+ while (1) {
+  i13 = HEAP32[i12 >> 2] | 0;
+  if (i13 >>> 0 < 2) {
+   _fill_window(i2);
+   i13 = HEAP32[i12 >> 2] | 0;
+   if ((i13 | i5 | 0) == 0) {
+    i2 = 0;
+    i8 = 28;
+    break;
+   }
+   if ((i13 | 0) == 0) {
+    i8 = 20;
+    break;
+   }
+  }
+  i13 = (HEAP32[i4 >> 2] | 0) + i13 | 0;
+  HEAP32[i4 >> 2] = i13;
+  HEAP32[i12 >> 2] = 0;
+  i14 = HEAP32[i6 >> 2] | 0;
+  i15 = i14 + i11 | 0;
+  if (!((i13 | 0) != 0 & i13 >>> 0 < i15 >>> 0)) {
+   HEAP32[i12 >> 2] = i13 - i15;
+   HEAP32[i4 >> 2] = i15;
+   if ((i14 | 0) > -1) {
+    i13 = (HEAP32[i7 >> 2] | 0) + i14 | 0;
+   } else {
+    i13 = 0;
+   }
+   __tr_flush_block(i2, i13, i11, 0);
+   HEAP32[i6 >> 2] = HEAP32[i4 >> 2];
+   i16 = HEAP32[i2 >> 2] | 0;
+   i14 = i16 + 28 | 0;
+   i15 = HEAP32[i14 >> 2] | 0;
+   i17 = HEAP32[i15 + 20 >> 2] | 0;
+   i13 = i16 + 16 | 0;
+   i18 = HEAP32[i13 >> 2] | 0;
+   i17 = i17 >>> 0 > i18 >>> 0 ? i18 : i17;
+   if ((i17 | 0) != 0 ? (i8 = i16 + 12 | 0, _memcpy(HEAP32[i8 >> 2] | 0, HEAP32[i15 + 16 >> 2] | 0, i17 | 0) | 0, HEAP32[i8 >> 2] = (HEAP32[i8 >> 2] | 0) + i17, i8 = (HEAP32[i14 >> 2] | 0) + 16 | 0, HEAP32[i8 >> 2] = (HEAP32[i8 >> 2] | 0) + i17, i8 = i16 + 20 | 0, HEAP32[i8 >> 2] = (HEAP32[i8 >> 2] | 0) + i17, HEAP32[i13 >> 2] = (HEAP32[i13 >> 2] | 0) - i17, i8 = HEAP32[i14 >> 2] | 0, i16 = i8 + 20 | 0, i18 = HEAP32[i16 >> 2] | 0, HEAP32[i16 >> 2] = i18 - i17, (i18 | 0) == (i17 | 0)) : 0) {
+    HEAP32[i8 + 16 >> 2] = HEAP32[i8 + 8 >> 2];
+   }
+   if ((HEAP32[(HEAP32[i2 >> 2] | 0) + 16 >> 2] | 0) == 0) {
+    i2 = 0;
+    i8 = 28;
+    break;
+   }
+   i14 = HEAP32[i6 >> 2] | 0;
+   i13 = HEAP32[i4 >> 2] | 0;
+  }
+  i13 = i13 - i14 | 0;
+  if (i13 >>> 0 < ((HEAP32[i10 >> 2] | 0) + -262 | 0) >>> 0) {
+   continue;
+  }
+  if ((i14 | 0) > -1) {
+   i14 = (HEAP32[i7 >> 2] | 0) + i14 | 0;
+  } else {
+   i14 = 0;
+  }
+  __tr_flush_block(i2, i14, i13, 0);
+  HEAP32[i6 >> 2] = HEAP32[i4 >> 2];
+  i16 = HEAP32[i2 >> 2] | 0;
+  i14 = i16 + 28 | 0;
+  i15 = HEAP32[i14 >> 2] | 0;
+  i17 = HEAP32[i15 + 20 >> 2] | 0;
+  i13 = i16 + 16 | 0;
+  i18 = HEAP32[i13 >> 2] | 0;
+  i17 = i17 >>> 0 > i18 >>> 0 ? i18 : i17;
+  if ((i17 | 0) != 0 ? (i9 = i16 + 12 | 0, _memcpy(HEAP32[i9 >> 2] | 0, HEAP32[i15 + 16 >> 2] | 0, i17 | 0) | 0, HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + i17, i9 = (HEAP32[i14 >> 2] | 0) + 16 | 0, HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + i17, i9 = i16 + 20 | 0, HEAP32[i9 >> 2] = (HEAP32[i9 >> 2] | 0) + i17, HEAP32[i13 >> 2] = (HEAP32[i13 >> 2] | 0) - i17, i9 = HEAP32[i14 >> 2] | 0, i16 = i9 + 20 | 0, i18 = HEAP32[i16 >> 2] | 0, HEAP32[i16 >> 2] = i18 - i17, (i18 | 0) == (i17 | 0)) : 0) {
+   HEAP32[i9 + 16 >> 2] = HEAP32[i9 + 8 >> 2];
+  }
+  if ((HEAP32[(HEAP32[i2 >> 2] | 0) + 16 >> 2] | 0) == 0) {
+   i2 = 0;
+   i8 = 28;
+   break;
+  }
+ }
+ if ((i8 | 0) == 20) {
+  i8 = HEAP32[i6 >> 2] | 0;
+  if ((i8 | 0) > -1) {
+   i7 = (HEAP32[i7 >> 2] | 0) + i8 | 0;
+  } else {
+   i7 = 0;
+  }
+  i5 = (i5 | 0) == 4;
+  __tr_flush_block(i2, i7, (HEAP32[i4 >> 2] | 0) - i8 | 0, i5 & 1);
+  HEAP32[i6 >> 2] = HEAP32[i4 >> 2];
+  i4 = HEAP32[i2 >> 2] | 0;
+  i7 = i4 + 28 | 0;
+  i6 = HEAP32[i7 >> 2] | 0;
+  i9 = HEAP32[i6 + 20 >> 2] | 0;
+  i8 = i4 + 16 | 0;
+  i10 = HEAP32[i8 >> 2] | 0;
+  i9 = i9 >>> 0 > i10 >>> 0 ? i10 : i9;
+  if ((i9 | 0) != 0 ? (i3 = i4 + 12 | 0, _memcpy(HEAP32[i3 >> 2] | 0, HEAP32[i6 + 16 >> 2] | 0, i9 | 0) | 0, HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + i9, i3 = (HEAP32[i7 >> 2] | 0) + 16 | 0, HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + i9, i3 = i4 + 20 | 0, HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + i9, HEAP32[i8 >> 2] = (HEAP32[i8 >> 2] | 0) - i9, i3 = HEAP32[i7 >> 2] | 0, i17 = i3 + 20 | 0, i18 = HEAP32[i17 >> 2] | 0, HEAP32[i17 >> 2] = i18 - i9, (i18 | 0) == (i9 | 0)) : 0) {
+   HEAP32[i3 + 16 >> 2] = HEAP32[i3 + 8 >> 2];
+  }
+  if ((HEAP32[(HEAP32[i2 >> 2] | 0) + 16 >> 2] | 0) == 0) {
+   i18 = i5 ? 2 : 0;
+   STACKTOP = i1;
+   return i18 | 0;
+  } else {
+   i18 = i5 ? 3 : 1;
+   STACKTOP = i1;
+   return i18 | 0;
+  }
+ } else if ((i8 | 0) == 28) {
+  STACKTOP = i1;
+  return i2 | 0;
+ }
+ return 0;
+}
+function _fill_window(i15) {
+ i15 = i15 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0, i24 = 0;
+ i2 = STACKTOP;
+ i16 = i15 + 44 | 0;
+ i9 = HEAP32[i16 >> 2] | 0;
+ i4 = i15 + 60 | 0;
+ i8 = i15 + 116 | 0;
+ i3 = i15 + 108 | 0;
+ i5 = i9 + -262 | 0;
+ i1 = i15 + 56 | 0;
+ i17 = i15 + 72 | 0;
+ i6 = i15 + 88 | 0;
+ i7 = i15 + 84 | 0;
+ i11 = i15 + 112 | 0;
+ i12 = i15 + 92 | 0;
+ i13 = i15 + 76 | 0;
+ i14 = i15 + 68 | 0;
+ i10 = i15 + 64 | 0;
+ i19 = HEAP32[i8 >> 2] | 0;
+ i21 = i9;
+ while (1) {
+  i20 = HEAP32[i3 >> 2] | 0;
+  i19 = (HEAP32[i4 >> 2] | 0) - i19 - i20 | 0;
+  if (!(i20 >>> 0 < (i5 + i21 | 0) >>> 0)) {
+   i20 = HEAP32[i1 >> 2] | 0;
+   _memcpy(i20 | 0, i20 + i9 | 0, i9 | 0) | 0;
+   HEAP32[i11 >> 2] = (HEAP32[i11 >> 2] | 0) - i9;
+   i20 = (HEAP32[i3 >> 2] | 0) - i9 | 0;
+   HEAP32[i3 >> 2] = i20;
+   HEAP32[i12 >> 2] = (HEAP32[i12 >> 2] | 0) - i9;
+   i22 = HEAP32[i13 >> 2] | 0;
+   i21 = i22;
+   i22 = (HEAP32[i14 >> 2] | 0) + (i22 << 1) | 0;
+   do {
+    i22 = i22 + -2 | 0;
+    i23 = HEAPU16[i22 >> 1] | 0;
+    if (i23 >>> 0 < i9 >>> 0) {
+     i23 = 0;
+    } else {
+     i23 = i23 - i9 & 65535;
+    }
+    HEAP16[i22 >> 1] = i23;
+    i21 = i21 + -1 | 0;
+   } while ((i21 | 0) != 0);
+   i22 = i9;
+   i21 = (HEAP32[i10 >> 2] | 0) + (i9 << 1) | 0;
+   do {
+    i21 = i21 + -2 | 0;
+    i23 = HEAPU16[i21 >> 1] | 0;
+    if (i23 >>> 0 < i9 >>> 0) {
+     i23 = 0;
+    } else {
+     i23 = i23 - i9 & 65535;
+    }
+    HEAP16[i21 >> 1] = i23;
+    i22 = i22 + -1 | 0;
+   } while ((i22 | 0) != 0);
+   i19 = i19 + i9 | 0;
+  }
+  i21 = HEAP32[i15 >> 2] | 0;
+  i24 = i21 + 4 | 0;
+  i23 = HEAP32[i24 >> 2] | 0;
+  if ((i23 | 0) == 0) {
+   i18 = 28;
+   break;
+  }
+  i22 = HEAP32[i8 >> 2] | 0;
+  i20 = (HEAP32[i1 >> 2] | 0) + (i22 + i20) | 0;
+  i19 = i23 >>> 0 > i19 >>> 0 ? i19 : i23;
+  if ((i19 | 0) == 0) {
+   i19 = 0;
+  } else {
+   HEAP32[i24 >> 2] = i23 - i19;
+   i22 = HEAP32[(HEAP32[i21 + 28 >> 2] | 0) + 24 >> 2] | 0;
+   if ((i22 | 0) == 1) {
+    i22 = i21 + 48 | 0;
+    HEAP32[i22 >> 2] = _adler32(HEAP32[i22 >> 2] | 0, HEAP32[i21 >> 2] | 0, i19) | 0;
+    i22 = i21;
+   } else if ((i22 | 0) == 2) {
+    i22 = i21 + 48 | 0;
+    HEAP32[i22 >> 2] = _crc32(HEAP32[i22 >> 2] | 0, HEAP32[i21 >> 2] | 0, i19) | 0;
+    i22 = i21;
+   } else {
+    i22 = i21;
+   }
+   _memcpy(i20 | 0, HEAP32[i22 >> 2] | 0, i19 | 0) | 0;
+   HEAP32[i22 >> 2] = (HEAP32[i22 >> 2] | 0) + i19;
+   i22 = i21 + 8 | 0;
+   HEAP32[i22 >> 2] = (HEAP32[i22 >> 2] | 0) + i19;
+   i22 = HEAP32[i8 >> 2] | 0;
+  }
+  i19 = i22 + i19 | 0;
+  HEAP32[i8 >> 2] = i19;
+  if (i19 >>> 0 > 2 ? (i23 = HEAP32[i3 >> 2] | 0, i22 = HEAP32[i1 >> 2] | 0, i24 = HEAPU8[i22 + i23 | 0] | 0, HEAP32[i17 >> 2] = i24, HEAP32[i17 >> 2] = ((HEAPU8[i22 + (i23 + 1) | 0] | 0) ^ i24 << HEAP32[i6 >> 2]) & HEAP32[i7 >> 2], !(i19 >>> 0 < 262)) : 0) {
+   break;
+  }
+  if ((HEAP32[(HEAP32[i15 >> 2] | 0) + 4 >> 2] | 0) == 0) {
+   break;
+  }
+  i21 = HEAP32[i16 >> 2] | 0;
+ }
+ if ((i18 | 0) == 28) {
+  STACKTOP = i2;
+  return;
+ }
+ i5 = i15 + 5824 | 0;
+ i6 = HEAP32[i5 >> 2] | 0;
+ i4 = HEAP32[i4 >> 2] | 0;
+ if (!(i6 >>> 0 < i4 >>> 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ i3 = i19 + (HEAP32[i3 >> 2] | 0) | 0;
+ if (i6 >>> 0 < i3 >>> 0) {
+  i4 = i4 - i3 | 0;
+  i24 = i4 >>> 0 > 258 ? 258 : i4;
+  _memset((HEAP32[i1 >> 2] | 0) + i3 | 0, 0, i24 | 0) | 0;
+  HEAP32[i5 >> 2] = i24 + i3;
+  STACKTOP = i2;
+  return;
+ }
+ i3 = i3 + 258 | 0;
+ if (!(i6 >>> 0 < i3 >>> 0)) {
+  STACKTOP = i2;
+  return;
+ }
+ i3 = i3 - i6 | 0;
+ i4 = i4 - i6 | 0;
+ i24 = i3 >>> 0 > i4 >>> 0 ? i4 : i3;
+ _memset((HEAP32[i1 >> 2] | 0) + i6 | 0, 0, i24 | 0) | 0;
+ HEAP32[i5 >> 2] = (HEAP32[i5 >> 2] | 0) + i24;
+ STACKTOP = i2;
+ return;
+}
+function __tr_align(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0;
+ i2 = STACKTOP;
+ i3 = i1 + 5820 | 0;
+ i6 = HEAP32[i3 >> 2] | 0;
+ i4 = i1 + 5816 | 0;
+ i7 = HEAPU16[i4 >> 1] | 0 | 2 << i6;
+ i5 = i7 & 65535;
+ HEAP16[i4 >> 1] = i5;
+ if ((i6 | 0) > 13) {
+  i8 = i1 + 20 | 0;
+  i6 = HEAP32[i8 >> 2] | 0;
+  HEAP32[i8 >> 2] = i6 + 1;
+  i5 = i1 + 8 | 0;
+  HEAP8[(HEAP32[i5 >> 2] | 0) + i6 | 0] = i7;
+  i7 = (HEAPU16[i4 >> 1] | 0) >>> 8 & 255;
+  i6 = HEAP32[i8 >> 2] | 0;
+  HEAP32[i8 >> 2] = i6 + 1;
+  HEAP8[(HEAP32[i5 >> 2] | 0) + i6 | 0] = i7;
+  i6 = HEAP32[i3 >> 2] | 0;
+  i5 = 2 >>> (16 - i6 | 0) & 65535;
+  HEAP16[i4 >> 1] = i5;
+  i6 = i6 + -13 | 0;
+ } else {
+  i6 = i6 + 3 | 0;
+ }
+ HEAP32[i3 >> 2] = i6;
+ if ((i6 | 0) > 9) {
+  i7 = i1 + 20 | 0;
+  i6 = HEAP32[i7 >> 2] | 0;
+  HEAP32[i7 >> 2] = i6 + 1;
+  i8 = i1 + 8 | 0;
+  HEAP8[(HEAP32[i8 >> 2] | 0) + i6 | 0] = i5;
+  i5 = (HEAPU16[i4 >> 1] | 0) >>> 8 & 255;
+  i6 = HEAP32[i7 >> 2] | 0;
+  HEAP32[i7 >> 2] = i6 + 1;
+  HEAP8[(HEAP32[i8 >> 2] | 0) + i6 | 0] = i5;
+  HEAP16[i4 >> 1] = 0;
+  i6 = (HEAP32[i3 >> 2] | 0) + -9 | 0;
+  i5 = 0;
+ } else {
+  i6 = i6 + 7 | 0;
+ }
+ HEAP32[i3 >> 2] = i6;
+ if ((i6 | 0) != 16) {
+  if ((i6 | 0) > 7) {
+   i6 = i1 + 20 | 0;
+   i7 = HEAP32[i6 >> 2] | 0;
+   HEAP32[i6 >> 2] = i7 + 1;
+   HEAP8[(HEAP32[i1 + 8 >> 2] | 0) + i7 | 0] = i5;
+   i7 = (HEAPU16[i4 >> 1] | 0) >>> 8;
+   HEAP16[i4 >> 1] = i7;
+   i6 = (HEAP32[i3 >> 2] | 0) + -8 | 0;
+   HEAP32[i3 >> 2] = i6;
+  } else {
+   i7 = i5;
+  }
+ } else {
+  i9 = i1 + 20 | 0;
+  i8 = HEAP32[i9 >> 2] | 0;
+  HEAP32[i9 >> 2] = i8 + 1;
+  i7 = i1 + 8 | 0;
+  HEAP8[(HEAP32[i7 >> 2] | 0) + i8 | 0] = i5;
+  i8 = (HEAPU16[i4 >> 1] | 0) >>> 8 & 255;
+  i6 = HEAP32[i9 >> 2] | 0;
+  HEAP32[i9 >> 2] = i6 + 1;
+  HEAP8[(HEAP32[i7 >> 2] | 0) + i6 | 0] = i8;
+  HEAP16[i4 >> 1] = 0;
+  HEAP32[i3 >> 2] = 0;
+  i6 = 0;
+  i7 = 0;
+ }
+ i5 = i1 + 5812 | 0;
+ if ((11 - i6 + (HEAP32[i5 >> 2] | 0) | 0) >= 9) {
+  HEAP32[i5 >> 2] = 7;
+  STACKTOP = i2;
+  return;
+ }
+ i7 = i7 & 65535 | 2 << i6;
+ HEAP16[i4 >> 1] = i7;
+ if ((i6 | 0) > 13) {
+  i8 = i1 + 20 | 0;
+  i6 = HEAP32[i8 >> 2] | 0;
+  HEAP32[i8 >> 2] = i6 + 1;
+  i9 = i1 + 8 | 0;
+  HEAP8[(HEAP32[i9 >> 2] | 0) + i6 | 0] = i7;
+  i7 = (HEAPU16[i4 >> 1] | 0) >>> 8 & 255;
+  i6 = HEAP32[i8 >> 2] | 0;
+  HEAP32[i8 >> 2] = i6 + 1;
+  HEAP8[(HEAP32[i9 >> 2] | 0) + i6 | 0] = i7;
+  i6 = HEAP32[i3 >> 2] | 0;
+  i7 = 2 >>> (16 - i6 | 0);
+  HEAP16[i4 >> 1] = i7;
+  i6 = i6 + -13 | 0;
+ } else {
+  i6 = i6 + 3 | 0;
+ }
+ i7 = i7 & 255;
+ HEAP32[i3 >> 2] = i6;
+ if ((i6 | 0) > 9) {
+  i8 = i1 + 20 | 0;
+  i9 = HEAP32[i8 >> 2] | 0;
+  HEAP32[i8 >> 2] = i9 + 1;
+  i6 = i1 + 8 | 0;
+  HEAP8[(HEAP32[i6 >> 2] | 0) + i9 | 0] = i7;
+  i9 = (HEAPU16[i4 >> 1] | 0) >>> 8 & 255;
+  i7 = HEAP32[i8 >> 2] | 0;
+  HEAP32[i8 >> 2] = i7 + 1;
+  HEAP8[(HEAP32[i6 >> 2] | 0) + i7 | 0] = i9;
+  HEAP16[i4 >> 1] = 0;
+  i7 = 0;
+  i6 = (HEAP32[i3 >> 2] | 0) + -9 | 0;
+ } else {
+  i6 = i6 + 7 | 0;
+ }
+ HEAP32[i3 >> 2] = i6;
+ if ((i6 | 0) == 16) {
+  i6 = i1 + 20 | 0;
+  i9 = HEAP32[i6 >> 2] | 0;
+  HEAP32[i6 >> 2] = i9 + 1;
+  i8 = i1 + 8 | 0;
+  HEAP8[(HEAP32[i8 >> 2] | 0) + i9 | 0] = i7;
+  i7 = (HEAPU16[i4 >> 1] | 0) >>> 8 & 255;
+  i9 = HEAP32[i6 >> 2] | 0;
+  HEAP32[i6 >> 2] = i9 + 1;
+  HEAP8[(HEAP32[i8 >> 2] | 0) + i9 | 0] = i7;
+  HEAP16[i4 >> 1] = 0;
+  HEAP32[i3 >> 2] = 0;
+  HEAP32[i5 >> 2] = 7;
+  STACKTOP = i2;
+  return;
+ }
+ if ((i6 | 0) <= 7) {
+  HEAP32[i5 >> 2] = 7;
+  STACKTOP = i2;
+  return;
+ }
+ i8 = i1 + 20 | 0;
+ i9 = HEAP32[i8 >> 2] | 0;
+ HEAP32[i8 >> 2] = i9 + 1;
+ HEAP8[(HEAP32[i1 + 8 >> 2] | 0) + i9 | 0] = i7;
+ HEAP16[i4 >> 1] = (HEAPU16[i4 >> 1] | 0) >>> 8;
+ HEAP32[i3 >> 2] = (HEAP32[i3 >> 2] | 0) + -8;
+ HEAP32[i5 >> 2] = 7;
+ STACKTOP = i2;
+ return;
+}
+function _adler32(i6, i4, i5) {
+ i6 = i6 | 0;
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0, i17 = 0, i18 = 0, i19 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0;
+ i1 = STACKTOP;
+ i3 = i6 >>> 16;
+ i6 = i6 & 65535;
+ if ((i5 | 0) == 1) {
+  i2 = (HEAPU8[i4] | 0) + i6 | 0;
+  i2 = i2 >>> 0 > 65520 ? i2 + -65521 | 0 : i2;
+  i3 = i2 + i3 | 0;
+  i8 = (i3 >>> 0 > 65520 ? i3 + 15 | 0 : i3) << 16 | i2;
+  STACKTOP = i1;
+  return i8 | 0;
+ }
+ if ((i4 | 0) == 0) {
+  i8 = 1;
+  STACKTOP = i1;
+  return i8 | 0;
+ }
+ if (i5 >>> 0 < 16) {
+  if ((i5 | 0) != 0) {
+   while (1) {
+    i5 = i5 + -1 | 0;
+    i6 = (HEAPU8[i4] | 0) + i6 | 0;
+    i3 = i6 + i3 | 0;
+    if ((i5 | 0) == 0) {
+     break;
+    } else {
+     i4 = i4 + 1 | 0;
+    }
+   }
+  }
+  i8 = ((i3 >>> 0) % 65521 | 0) << 16 | (i6 >>> 0 > 65520 ? i6 + -65521 | 0 : i6);
+  STACKTOP = i1;
+  return i8 | 0;
+ }
+ if (i5 >>> 0 > 5551) {
+  do {
+   i5 = i5 + -5552 | 0;
+   i7 = i4;
+   i8 = 347;
+   while (1) {
+    i23 = (HEAPU8[i7] | 0) + i6 | 0;
+    i22 = i23 + (HEAPU8[i7 + 1 | 0] | 0) | 0;
+    i21 = i22 + (HEAPU8[i7 + 2 | 0] | 0) | 0;
+    i20 = i21 + (HEAPU8[i7 + 3 | 0] | 0) | 0;
+    i19 = i20 + (HEAPU8[i7 + 4 | 0] | 0) | 0;
+    i18 = i19 + (HEAPU8[i7 + 5 | 0] | 0) | 0;
+    i17 = i18 + (HEAPU8[i7 + 6 | 0] | 0) | 0;
+    i16 = i17 + (HEAPU8[i7 + 7 | 0] | 0) | 0;
+    i15 = i16 + (HEAPU8[i7 + 8 | 0] | 0) | 0;
+    i14 = i15 + (HEAPU8[i7 + 9 | 0] | 0) | 0;
+    i13 = i14 + (HEAPU8[i7 + 10 | 0] | 0) | 0;
+    i12 = i13 + (HEAPU8[i7 + 11 | 0] | 0) | 0;
+    i11 = i12 + (HEAPU8[i7 + 12 | 0] | 0) | 0;
+    i10 = i11 + (HEAPU8[i7 + 13 | 0] | 0) | 0;
+    i9 = i10 + (HEAPU8[i7 + 14 | 0] | 0) | 0;
+    i6 = i9 + (HEAPU8[i7 + 15 | 0] | 0) | 0;
+    i3 = i23 + i3 + i22 + i21 + i20 + i19 + i18 + i17 + i16 + i15 + i14 + i13 + i12 + i11 + i10 + i9 + i6 | 0;
+    i8 = i8 + -1 | 0;
+    if ((i8 | 0) == 0) {
+     break;
+    } else {
+     i7 = i7 + 16 | 0;
+    }
+   }
+   i4 = i4 + 5552 | 0;
+   i6 = (i6 >>> 0) % 65521 | 0;
+   i3 = (i3 >>> 0) % 65521 | 0;
+  } while (i5 >>> 0 > 5551);
+  if ((i5 | 0) != 0) {
+   if (i5 >>> 0 > 15) {
+    i2 = 15;
+   } else {
+    i2 = 16;
+   }
+  }
+ } else {
+  i2 = 15;
+ }
+ if ((i2 | 0) == 15) {
+  while (1) {
+   i5 = i5 + -16 | 0;
+   i9 = (HEAPU8[i4] | 0) + i6 | 0;
+   i10 = i9 + (HEAPU8[i4 + 1 | 0] | 0) | 0;
+   i11 = i10 + (HEAPU8[i4 + 2 | 0] | 0) | 0;
+   i12 = i11 + (HEAPU8[i4 + 3 | 0] | 0) | 0;
+   i13 = i12 + (HEAPU8[i4 + 4 | 0] | 0) | 0;
+   i14 = i13 + (HEAPU8[i4 + 5 | 0] | 0) | 0;
+   i15 = i14 + (HEAPU8[i4 + 6 | 0] | 0) | 0;
+   i16 = i15 + (HEAPU8[i4 + 7 | 0] | 0) | 0;
+   i17 = i16 + (HEAPU8[i4 + 8 | 0] | 0) | 0;
+   i18 = i17 + (HEAPU8[i4 + 9 | 0] | 0) | 0;
+   i19 = i18 + (HEAPU8[i4 + 10 | 0] | 0) | 0;
+   i20 = i19 + (HEAPU8[i4 + 11 | 0] | 0) | 0;
+   i21 = i20 + (HEAPU8[i4 + 12 | 0] | 0) | 0;
+   i22 = i21 + (HEAPU8[i4 + 13 | 0] | 0) | 0;
+   i23 = i22 + (HEAPU8[i4 + 14 | 0] | 0) | 0;
+   i6 = i23 + (HEAPU8[i4 + 15 | 0] | 0) | 0;
+   i3 = i9 + i3 + i10 + i11 + i12 + i13 + i14 + i15 + i16 + i17 + i18 + i19 + i20 + i21 + i22 + i23 + i6 | 0;
+   i4 = i4 + 16 | 0;
+   if (!(i5 >>> 0 > 15)) {
+    break;
+   } else {
+    i2 = 15;
+   }
+  }
+  if ((i5 | 0) == 0) {
+   i2 = 17;
+  } else {
+   i2 = 16;
+  }
+ }
+ if ((i2 | 0) == 16) {
+  while (1) {
+   i5 = i5 + -1 | 0;
+   i6 = (HEAPU8[i4] | 0) + i6 | 0;
+   i3 = i6 + i3 | 0;
+   if ((i5 | 0) == 0) {
+    i2 = 17;
+    break;
+   } else {
+    i4 = i4 + 1 | 0;
+    i2 = 16;
+   }
+  }
+ }
+ if ((i2 | 0) == 17) {
+  i6 = (i6 >>> 0) % 65521 | 0;
+  i3 = (i3 >>> 0) % 65521 | 0;
+ }
+ i23 = i3 << 16 | i6;
+ STACKTOP = i1;
+ return i23 | 0;
+}
+function _crc32(i4, i2, i3) {
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ var i1 = 0, i5 = 0;
+ i1 = STACKTOP;
+ if ((i2 | 0) == 0) {
+  i5 = 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ i4 = ~i4;
+ L4 : do {
+  if ((i3 | 0) != 0) {
+   while (1) {
+    if ((i2 & 3 | 0) == 0) {
+     break;
+    }
+    i4 = HEAP32[3192 + (((HEAPU8[i2] | 0) ^ i4 & 255) << 2) >> 2] ^ i4 >>> 8;
+    i3 = i3 + -1 | 0;
+    if ((i3 | 0) == 0) {
+     break L4;
+    } else {
+     i2 = i2 + 1 | 0;
+    }
+   }
+   if (i3 >>> 0 > 31) {
+    while (1) {
+     i4 = HEAP32[i2 >> 2] ^ i4;
+     i4 = HEAP32[5240 + ((i4 >>> 8 & 255) << 2) >> 2] ^ HEAP32[6264 + ((i4 & 255) << 2) >> 2] ^ HEAP32[4216 + ((i4 >>> 16 & 255) << 2) >> 2] ^ HEAP32[3192 + (i4 >>> 24 << 2) >> 2] ^ HEAP32[i2 + 4 >> 2];
+     i4 = HEAP32[5240 + ((i4 >>> 8 & 255) << 2) >> 2] ^ HEAP32[6264 + ((i4 & 255) << 2) >> 2] ^ HEAP32[4216 + ((i4 >>> 16 & 255) << 2) >> 2] ^ HEAP32[3192 + (i4 >>> 24 << 2) >> 2] ^ HEAP32[i2 + 8 >> 2];
+     i4 = HEAP32[5240 + ((i4 >>> 8 & 255) << 2) >> 2] ^ HEAP32[6264 + ((i4 & 255) << 2) >> 2] ^ HEAP32[4216 + ((i4 >>> 16 & 255) << 2) >> 2] ^ HEAP32[3192 + (i4 >>> 24 << 2) >> 2] ^ HEAP32[i2 + 12 >> 2];
+     i4 = HEAP32[5240 + ((i4 >>> 8 & 255) << 2) >> 2] ^ HEAP32[6264 + ((i4 & 255) << 2) >> 2] ^ HEAP32[4216 + ((i4 >>> 16 & 255) << 2) >> 2] ^ HEAP32[3192 + (i4 >>> 24 << 2) >> 2] ^ HEAP32[i2 + 16 >> 2];
+     i4 = HEAP32[5240 + ((i4 >>> 8 & 255) << 2) >> 2] ^ HEAP32[6264 + ((i4 & 255) << 2) >> 2] ^ HEAP32[4216 + ((i4 >>> 16 & 255) << 2) >> 2] ^ HEAP32[3192 + (i4 >>> 24 << 2) >> 2] ^ HEAP32[i2 + 20 >> 2];
+     i4 = HEAP32[5240 + ((i4 >>> 8 & 255) << 2) >> 2] ^ HEAP32[6264 + ((i4 & 255) << 2) >> 2] ^ HEAP32[4216 + ((i4 >>> 16 & 255) << 2) >> 2] ^ HEAP32[3192 + (i4 >>> 24 << 2) >> 2] ^ HEAP32[i2 + 24 >> 2];
+     i5 = i2 + 32 | 0;
+     i4 = HEAP32[5240 + ((i4 >>> 8 & 255) << 2) >> 2] ^ HEAP32[6264 + ((i4 & 255) << 2) >> 2] ^ HEAP32[4216 + ((i4 >>> 16 & 255) << 2) >> 2] ^ HEAP32[3192 + (i4 >>> 24 << 2) >> 2] ^ HEAP32[i2 + 28 >> 2];
+     i4 = HEAP32[5240 + ((i4 >>> 8 & 255) << 2) >> 2] ^ HEAP32[6264 + ((i4 & 255) << 2) >> 2] ^ HEAP32[4216 + ((i4 >>> 16 & 255) << 2) >> 2] ^ HEAP32[3192 + (i4 >>> 24 << 2) >> 2];
+     i3 = i3 + -32 | 0;
+     if (i3 >>> 0 > 31) {
+      i2 = i5;
+     } else {
+      i2 = i5;
+      break;
+     }
+    }
+   }
+   if (i3 >>> 0 > 3) {
+    while (1) {
+     i5 = i2 + 4 | 0;
+     i4 = HEAP32[i2 >> 2] ^ i4;
+     i4 = HEAP32[5240 + ((i4 >>> 8 & 255) << 2) >> 2] ^ HEAP32[6264 + ((i4 & 255) << 2) >> 2] ^ HEAP32[4216 + ((i4 >>> 16 & 255) << 2) >> 2] ^ HEAP32[3192 + (i4 >>> 24 << 2) >> 2];
+     i3 = i3 + -4 | 0;
+     if (i3 >>> 0 > 3) {
+      i2 = i5;
+     } else {
+      i2 = i5;
+      break;
+     }
+    }
+   }
+   if ((i3 | 0) != 0) {
+    while (1) {
+     i4 = HEAP32[3192 + (((HEAPU8[i2] | 0) ^ i4 & 255) << 2) >> 2] ^ i4 >>> 8;
+     i3 = i3 + -1 | 0;
+     if ((i3 | 0) == 0) {
+      break;
+     } else {
+      i2 = i2 + 1 | 0;
+     }
+    }
+   }
+  }
+ } while (0);
+ i5 = ~i4;
+ STACKTOP = i1;
+ return i5 | 0;
+}
+function _deflateInit2_(i3, i7, i8, i10, i4, i1, i5, i6) {
+ i3 = i3 | 0;
+ i7 = i7 | 0;
+ i8 = i8 | 0;
+ i10 = i10 | 0;
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ var i2 = 0, i9 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0;
+ i2 = STACKTOP;
+ if ((i5 | 0) == 0) {
+  i12 = -6;
+  STACKTOP = i2;
+  return i12 | 0;
+ }
+ if (!((HEAP8[i5] | 0) == 49 & (i6 | 0) == 56)) {
+  i12 = -6;
+  STACKTOP = i2;
+  return i12 | 0;
+ }
+ if ((i3 | 0) == 0) {
+  i12 = -2;
+  STACKTOP = i2;
+  return i12 | 0;
+ }
+ i5 = i3 + 24 | 0;
+ HEAP32[i5 >> 2] = 0;
+ i6 = i3 + 32 | 0;
+ i9 = HEAP32[i6 >> 2] | 0;
+ if ((i9 | 0) == 0) {
+  HEAP32[i6 >> 2] = 1;
+  HEAP32[i3 + 40 >> 2] = 0;
+  i9 = 1;
+ }
+ i11 = i3 + 36 | 0;
+ if ((HEAP32[i11 >> 2] | 0) == 0) {
+  HEAP32[i11 >> 2] = 1;
+ }
+ i7 = (i7 | 0) == -1 ? 6 : i7;
+ if ((i10 | 0) < 0) {
+  i10 = 0 - i10 | 0;
+  i11 = 0;
+ } else {
+  i11 = (i10 | 0) > 15;
+  i10 = i11 ? i10 + -16 | 0 : i10;
+  i11 = i11 ? 2 : 1;
+ }
+ if (!((i4 + -1 | 0) >>> 0 < 9 & (i8 | 0) == 8)) {
+  i12 = -2;
+  STACKTOP = i2;
+  return i12 | 0;
+ }
+ if ((i10 + -8 | 0) >>> 0 > 7 | i7 >>> 0 > 9 | i1 >>> 0 > 4) {
+  i12 = -2;
+  STACKTOP = i2;
+  return i12 | 0;
+ }
+ i12 = (i10 | 0) == 8 ? 9 : i10;
+ i10 = i3 + 40 | 0;
+ i8 = FUNCTION_TABLE_iiii[i9 & 1](HEAP32[i10 >> 2] | 0, 1, 5828) | 0;
+ if ((i8 | 0) == 0) {
+  i12 = -4;
+  STACKTOP = i2;
+  return i12 | 0;
+ }
+ HEAP32[i3 + 28 >> 2] = i8;
+ HEAP32[i8 >> 2] = i3;
+ HEAP32[i8 + 24 >> 2] = i11;
+ HEAP32[i8 + 28 >> 2] = 0;
+ HEAP32[i8 + 48 >> 2] = i12;
+ i14 = 1 << i12;
+ i11 = i8 + 44 | 0;
+ HEAP32[i11 >> 2] = i14;
+ HEAP32[i8 + 52 >> 2] = i14 + -1;
+ i12 = i4 + 7 | 0;
+ HEAP32[i8 + 80 >> 2] = i12;
+ i12 = 1 << i12;
+ i13 = i8 + 76 | 0;
+ HEAP32[i13 >> 2] = i12;
+ HEAP32[i8 + 84 >> 2] = i12 + -1;
+ HEAP32[i8 + 88 >> 2] = ((i4 + 9 | 0) >>> 0) / 3 | 0;
+ i12 = i8 + 56 | 0;
+ HEAP32[i12 >> 2] = FUNCTION_TABLE_iiii[HEAP32[i6 >> 2] & 1](HEAP32[i10 >> 2] | 0, i14, 2) | 0;
+ i14 = FUNCTION_TABLE_iiii[HEAP32[i6 >> 2] & 1](HEAP32[i10 >> 2] | 0, HEAP32[i11 >> 2] | 0, 2) | 0;
+ i9 = i8 + 64 | 0;
+ HEAP32[i9 >> 2] = i14;
+ _memset(i14 | 0, 0, HEAP32[i11 >> 2] << 1 | 0) | 0;
+ i11 = i8 + 68 | 0;
+ HEAP32[i11 >> 2] = FUNCTION_TABLE_iiii[HEAP32[i6 >> 2] & 1](HEAP32[i10 >> 2] | 0, HEAP32[i13 >> 2] | 0, 2) | 0;
+ HEAP32[i8 + 5824 >> 2] = 0;
+ i4 = 1 << i4 + 6;
+ i13 = i8 + 5788 | 0;
+ HEAP32[i13 >> 2] = i4;
+ i4 = FUNCTION_TABLE_iiii[HEAP32[i6 >> 2] & 1](HEAP32[i10 >> 2] | 0, i4, 4) | 0;
+ HEAP32[i8 + 8 >> 2] = i4;
+ i6 = HEAP32[i13 >> 2] | 0;
+ HEAP32[i8 + 12 >> 2] = i6 << 2;
+ if (((HEAP32[i12 >> 2] | 0) != 0 ? (HEAP32[i9 >> 2] | 0) != 0 : 0) ? !((HEAP32[i11 >> 2] | 0) == 0 | (i4 | 0) == 0) : 0) {
+  HEAP32[i8 + 5796 >> 2] = i4 + (i6 >>> 1 << 1);
+  HEAP32[i8 + 5784 >> 2] = i4 + (i6 * 3 | 0);
+  HEAP32[i8 + 132 >> 2] = i7;
+  HEAP32[i8 + 136 >> 2] = i1;
+  HEAP8[i8 + 36 | 0] = 8;
+  i14 = _deflateReset(i3) | 0;
+  STACKTOP = i2;
+  return i14 | 0;
+ }
+ HEAP32[i8 + 4 >> 2] = 666;
+ HEAP32[i5 >> 2] = HEAP32[3176 >> 2];
+ _deflateEnd(i3) | 0;
+ i14 = -4;
+ STACKTOP = i2;
+ return i14 | 0;
+}
+function _longest_match(i19, i16) {
+ i19 = i19 | 0;
+ i16 = i16 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i17 = 0, i18 = 0, i20 = 0, i21 = 0, i22 = 0, i23 = 0;
+ i1 = STACKTOP;
+ i18 = HEAP32[i19 + 124 >> 2] | 0;
+ i3 = HEAP32[i19 + 56 >> 2] | 0;
+ i5 = HEAP32[i19 + 108 >> 2] | 0;
+ i4 = i3 + i5 | 0;
+ i20 = HEAP32[i19 + 120 >> 2] | 0;
+ i10 = HEAP32[i19 + 144 >> 2] | 0;
+ i2 = (HEAP32[i19 + 44 >> 2] | 0) + -262 | 0;
+ i8 = i5 >>> 0 > i2 >>> 0 ? i5 - i2 | 0 : 0;
+ i6 = HEAP32[i19 + 64 >> 2] | 0;
+ i7 = HEAP32[i19 + 52 >> 2] | 0;
+ i9 = i3 + (i5 + 258) | 0;
+ i2 = HEAP32[i19 + 116 >> 2] | 0;
+ i12 = i10 >>> 0 > i2 >>> 0 ? i2 : i10;
+ i11 = i19 + 112 | 0;
+ i15 = i3 + (i5 + 1) | 0;
+ i14 = i3 + (i5 + 2) | 0;
+ i13 = i9;
+ i10 = i5 + 257 | 0;
+ i17 = i20;
+ i18 = i20 >>> 0 < (HEAP32[i19 + 140 >> 2] | 0) >>> 0 ? i18 : i18 >>> 2;
+ i19 = HEAP8[i3 + (i20 + i5) | 0] | 0;
+ i20 = HEAP8[i3 + (i5 + -1 + i20) | 0] | 0;
+ while (1) {
+  i21 = i3 + i16 | 0;
+  if ((((HEAP8[i3 + (i16 + i17) | 0] | 0) == i19 << 24 >> 24 ? (HEAP8[i3 + (i17 + -1 + i16) | 0] | 0) == i20 << 24 >> 24 : 0) ? (HEAP8[i21] | 0) == (HEAP8[i4] | 0) : 0) ? (HEAP8[i3 + (i16 + 1) | 0] | 0) == (HEAP8[i15] | 0) : 0) {
+   i21 = i3 + (i16 + 2) | 0;
+   i22 = i14;
+   do {
+    i23 = i22 + 1 | 0;
+    if ((HEAP8[i23] | 0) != (HEAP8[i21 + 1 | 0] | 0)) {
+     i22 = i23;
+     break;
+    }
+    i23 = i22 + 2 | 0;
+    if ((HEAP8[i23] | 0) != (HEAP8[i21 + 2 | 0] | 0)) {
+     i22 = i23;
+     break;
+    }
+    i23 = i22 + 3 | 0;
+    if ((HEAP8[i23] | 0) != (HEAP8[i21 + 3 | 0] | 0)) {
+     i22 = i23;
+     break;
+    }
+    i23 = i22 + 4 | 0;
+    if ((HEAP8[i23] | 0) != (HEAP8[i21 + 4 | 0] | 0)) {
+     i22 = i23;
+     break;
+    }
+    i23 = i22 + 5 | 0;
+    if ((HEAP8[i23] | 0) != (HEAP8[i21 + 5 | 0] | 0)) {
+     i22 = i23;
+     break;
+    }
+    i23 = i22 + 6 | 0;
+    if ((HEAP8[i23] | 0) != (HEAP8[i21 + 6 | 0] | 0)) {
+     i22 = i23;
+     break;
+    }
+    i23 = i22 + 7 | 0;
+    if ((HEAP8[i23] | 0) != (HEAP8[i21 + 7 | 0] | 0)) {
+     i22 = i23;
+     break;
+    }
+    i22 = i22 + 8 | 0;
+    i21 = i21 + 8 | 0;
+   } while ((HEAP8[i22] | 0) == (HEAP8[i21] | 0) & i22 >>> 0 < i9 >>> 0);
+   i21 = i22 - i13 | 0;
+   i22 = i21 + 258 | 0;
+   if ((i22 | 0) > (i17 | 0)) {
+    HEAP32[i11 >> 2] = i16;
+    if ((i22 | 0) >= (i12 | 0)) {
+     i17 = i22;
+     i3 = 20;
+     break;
+    }
+    i17 = i22;
+    i19 = HEAP8[i3 + (i22 + i5) | 0] | 0;
+    i20 = HEAP8[i3 + (i10 + i21) | 0] | 0;
+   }
+  }
+  i16 = HEAPU16[i6 + ((i16 & i7) << 1) >> 1] | 0;
+  if (!(i16 >>> 0 > i8 >>> 0)) {
+   i3 = 20;
+   break;
+  }
+  i18 = i18 + -1 | 0;
+  if ((i18 | 0) == 0) {
+   i3 = 20;
+   break;
+  }
+ }
+ if ((i3 | 0) == 20) {
+  STACKTOP = i1;
+  return (i17 >>> 0 > i2 >>> 0 ? i2 : i17) | 0;
+ }
+ return 0;
+}
+function __tr_stored_block(i3, i2, i5, i6) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ var i1 = 0, i4 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0;
+ i1 = STACKTOP;
+ i4 = i3 + 5820 | 0;
+ i7 = HEAP32[i4 >> 2] | 0;
+ i9 = i6 & 65535;
+ i6 = i3 + 5816 | 0;
+ i8 = HEAPU16[i6 >> 1] | 0 | i9 << i7;
+ HEAP16[i6 >> 1] = i8;
+ if ((i7 | 0) > 13) {
+  i11 = i3 + 20 | 0;
+  i7 = HEAP32[i11 >> 2] | 0;
+  HEAP32[i11 >> 2] = i7 + 1;
+  i10 = i3 + 8 | 0;
+  HEAP8[(HEAP32[i10 >> 2] | 0) + i7 | 0] = i8;
+  i8 = (HEAPU16[i6 >> 1] | 0) >>> 8 & 255;
+  i7 = HEAP32[i11 >> 2] | 0;
+  HEAP32[i11 >> 2] = i7 + 1;
+  HEAP8[(HEAP32[i10 >> 2] | 0) + i7 | 0] = i8;
+  i7 = HEAP32[i4 >> 2] | 0;
+  i8 = i9 >>> (16 - i7 | 0);
+  HEAP16[i6 >> 1] = i8;
+  i7 = i7 + -13 | 0;
+ } else {
+  i7 = i7 + 3 | 0;
+ }
+ i8 = i8 & 255;
+ HEAP32[i4 >> 2] = i7;
+ do {
+  if ((i7 | 0) <= 8) {
+   i9 = i3 + 20 | 0;
+   if ((i7 | 0) > 0) {
+    i7 = HEAP32[i9 >> 2] | 0;
+    HEAP32[i9 >> 2] = i7 + 1;
+    i11 = i3 + 8 | 0;
+    HEAP8[(HEAP32[i11 >> 2] | 0) + i7 | 0] = i8;
+    i7 = i9;
+    i8 = i11;
+    break;
+   } else {
+    i7 = i9;
+    i8 = i3 + 8 | 0;
+    break;
+   }
+  } else {
+   i7 = i3 + 20 | 0;
+   i10 = HEAP32[i7 >> 2] | 0;
+   HEAP32[i7 >> 2] = i10 + 1;
+   i11 = i3 + 8 | 0;
+   HEAP8[(HEAP32[i11 >> 2] | 0) + i10 | 0] = i8;
+   i10 = (HEAPU16[i6 >> 1] | 0) >>> 8 & 255;
+   i8 = HEAP32[i7 >> 2] | 0;
+   HEAP32[i7 >> 2] = i8 + 1;
+   HEAP8[(HEAP32[i11 >> 2] | 0) + i8 | 0] = i10;
+   i8 = i11;
+  }
+ } while (0);
+ HEAP16[i6 >> 1] = 0;
+ HEAP32[i4 >> 2] = 0;
+ HEAP32[i3 + 5812 >> 2] = 8;
+ i10 = HEAP32[i7 >> 2] | 0;
+ HEAP32[i7 >> 2] = i10 + 1;
+ HEAP8[(HEAP32[i8 >> 2] | 0) + i10 | 0] = i5;
+ i10 = HEAP32[i7 >> 2] | 0;
+ HEAP32[i7 >> 2] = i10 + 1;
+ HEAP8[(HEAP32[i8 >> 2] | 0) + i10 | 0] = i5 >>> 8;
+ i10 = i5 & 65535 ^ 65535;
+ i11 = HEAP32[i7 >> 2] | 0;
+ HEAP32[i7 >> 2] = i11 + 1;
+ HEAP8[(HEAP32[i8 >> 2] | 0) + i11 | 0] = i10;
+ i11 = HEAP32[i7 >> 2] | 0;
+ HEAP32[i7 >> 2] = i11 + 1;
+ HEAP8[(HEAP32[i8 >> 2] | 0) + i11 | 0] = i10 >>> 8;
+ if ((i5 | 0) == 0) {
+  STACKTOP = i1;
+  return;
+ }
+ while (1) {
+  i5 = i5 + -1 | 0;
+  i10 = HEAP8[i2] | 0;
+  i11 = HEAP32[i7 >> 2] | 0;
+  HEAP32[i7 >> 2] = i11 + 1;
+  HEAP8[(HEAP32[i8 >> 2] | 0) + i11 | 0] = i10;
+  if ((i5 | 0) == 0) {
+   break;
+  } else {
+   i2 = i2 + 1 | 0;
+  }
+ }
+ STACKTOP = i1;
+ return;
+}
+function _inflateInit_(i1, i3, i4) {
+ i1 = i1 | 0;
+ i3 = i3 | 0;
+ i4 = i4 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0;
+ i2 = STACKTOP;
+ if ((i3 | 0) == 0) {
+  i11 = -6;
+  STACKTOP = i2;
+  return i11 | 0;
+ }
+ if (!((HEAP8[i3] | 0) == 49 & (i4 | 0) == 56)) {
+  i11 = -6;
+  STACKTOP = i2;
+  return i11 | 0;
+ }
+ if ((i1 | 0) == 0) {
+  i11 = -2;
+  STACKTOP = i2;
+  return i11 | 0;
+ }
+ i3 = i1 + 24 | 0;
+ HEAP32[i3 >> 2] = 0;
+ i4 = i1 + 32 | 0;
+ i6 = HEAP32[i4 >> 2] | 0;
+ if ((i6 | 0) == 0) {
+  HEAP32[i4 >> 2] = 1;
+  HEAP32[i1 + 40 >> 2] = 0;
+  i6 = 1;
+ }
+ i4 = i1 + 36 | 0;
+ if ((HEAP32[i4 >> 2] | 0) == 0) {
+  HEAP32[i4 >> 2] = 1;
+ }
+ i5 = i1 + 40 | 0;
+ i8 = FUNCTION_TABLE_iiii[i6 & 1](HEAP32[i5 >> 2] | 0, 1, 7116) | 0;
+ if ((i8 | 0) == 0) {
+  i11 = -4;
+  STACKTOP = i2;
+  return i11 | 0;
+ }
+ i6 = i1 + 28 | 0;
+ HEAP32[i6 >> 2] = i8;
+ HEAP32[i8 + 52 >> 2] = 0;
+ i9 = HEAP32[i6 >> 2] | 0;
+ do {
+  if ((i9 | 0) != 0) {
+   i10 = i9 + 52 | 0;
+   i11 = HEAP32[i10 >> 2] | 0;
+   i7 = i9 + 36 | 0;
+   if ((i11 | 0) != 0) {
+    if ((HEAP32[i7 >> 2] | 0) == 15) {
+     i10 = i9;
+    } else {
+     FUNCTION_TABLE_vii[HEAP32[i4 >> 2] & 1](HEAP32[i5 >> 2] | 0, i11);
+     HEAP32[i10 >> 2] = 0;
+     i10 = HEAP32[i6 >> 2] | 0;
+    }
+    HEAP32[i9 + 8 >> 2] = 1;
+    HEAP32[i7 >> 2] = 15;
+    if ((i10 | 0) == 0) {
+     break;
+    } else {
+     i9 = i10;
+    }
+   } else {
+    HEAP32[i9 + 8 >> 2] = 1;
+    HEAP32[i7 >> 2] = 15;
+   }
+   HEAP32[i9 + 28 >> 2] = 0;
+   HEAP32[i1 + 20 >> 2] = 0;
+   HEAP32[i1 + 8 >> 2] = 0;
+   HEAP32[i3 >> 2] = 0;
+   HEAP32[i1 + 48 >> 2] = 1;
+   HEAP32[i9 >> 2] = 0;
+   HEAP32[i9 + 4 >> 2] = 0;
+   HEAP32[i9 + 12 >> 2] = 0;
+   HEAP32[i9 + 20 >> 2] = 32768;
+   HEAP32[i9 + 32 >> 2] = 0;
+   HEAP32[i9 + 40 >> 2] = 0;
+   HEAP32[i9 + 44 >> 2] = 0;
+   HEAP32[i9 + 48 >> 2] = 0;
+   HEAP32[i9 + 56 >> 2] = 0;
+   HEAP32[i9 + 60 >> 2] = 0;
+   i11 = i9 + 1328 | 0;
+   HEAP32[i9 + 108 >> 2] = i11;
+   HEAP32[i9 + 80 >> 2] = i11;
+   HEAP32[i9 + 76 >> 2] = i11;
+   HEAP32[i9 + 7104 >> 2] = 1;
+   HEAP32[i9 + 7108 >> 2] = -1;
+   i11 = 0;
+   STACKTOP = i2;
+   return i11 | 0;
+  }
+ } while (0);
+ FUNCTION_TABLE_vii[HEAP32[i4 >> 2] & 1](HEAP32[i5 >> 2] | 0, i8);
+ HEAP32[i6 >> 2] = 0;
+ i11 = -2;
+ STACKTOP = i2;
+ return i11 | 0;
+}
+function _init_block(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ i3 = 0;
+ do {
+  HEAP16[i1 + (i3 << 2) + 148 >> 1] = 0;
+  i3 = i3 + 1 | 0;
+ } while ((i3 | 0) != 286);
+ HEAP16[i1 + 2440 >> 1] = 0;
+ HEAP16[i1 + 2444 >> 1] = 0;
+ HEAP16[i1 + 2448 >> 1] = 0;
+ HEAP16[i1 + 2452 >> 1] = 0;
+ HEAP16[i1 + 2456 >> 1] = 0;
+ HEAP16[i1 + 2460 >> 1] = 0;
+ HEAP16[i1 + 2464 >> 1] = 0;
+ HEAP16[i1 + 2468 >> 1] = 0;
+ HEAP16[i1 + 2472 >> 1] = 0;
+ HEAP16[i1 + 2476 >> 1] = 0;
+ HEAP16[i1 + 2480 >> 1] = 0;
+ HEAP16[i1 + 2484 >> 1] = 0;
+ HEAP16[i1 + 2488 >> 1] = 0;
+ HEAP16[i1 + 2492 >> 1] = 0;
+ HEAP16[i1 + 2496 >> 1] = 0;
+ HEAP16[i1 + 2500 >> 1] = 0;
+ HEAP16[i1 + 2504 >> 1] = 0;
+ HEAP16[i1 + 2508 >> 1] = 0;
+ HEAP16[i1 + 2512 >> 1] = 0;
+ HEAP16[i1 + 2516 >> 1] = 0;
+ HEAP16[i1 + 2520 >> 1] = 0;
+ HEAP16[i1 + 2524 >> 1] = 0;
+ HEAP16[i1 + 2528 >> 1] = 0;
+ HEAP16[i1 + 2532 >> 1] = 0;
+ HEAP16[i1 + 2536 >> 1] = 0;
+ HEAP16[i1 + 2540 >> 1] = 0;
+ HEAP16[i1 + 2544 >> 1] = 0;
+ HEAP16[i1 + 2548 >> 1] = 0;
+ HEAP16[i1 + 2552 >> 1] = 0;
+ HEAP16[i1 + 2556 >> 1] = 0;
+ HEAP16[i1 + 2684 >> 1] = 0;
+ HEAP16[i1 + 2688 >> 1] = 0;
+ HEAP16[i1 + 2692 >> 1] = 0;
+ HEAP16[i1 + 2696 >> 1] = 0;
+ HEAP16[i1 + 2700 >> 1] = 0;
+ HEAP16[i1 + 2704 >> 1] = 0;
+ HEAP16[i1 + 2708 >> 1] = 0;
+ HEAP16[i1 + 2712 >> 1] = 0;
+ HEAP16[i1 + 2716 >> 1] = 0;
+ HEAP16[i1 + 2720 >> 1] = 0;
+ HEAP16[i1 + 2724 >> 1] = 0;
+ HEAP16[i1 + 2728 >> 1] = 0;
+ HEAP16[i1 + 2732 >> 1] = 0;
+ HEAP16[i1 + 2736 >> 1] = 0;
+ HEAP16[i1 + 2740 >> 1] = 0;
+ HEAP16[i1 + 2744 >> 1] = 0;
+ HEAP16[i1 + 2748 >> 1] = 0;
+ HEAP16[i1 + 2752 >> 1] = 0;
+ HEAP16[i1 + 2756 >> 1] = 0;
+ HEAP16[i1 + 1172 >> 1] = 1;
+ HEAP32[i1 + 5804 >> 2] = 0;
+ HEAP32[i1 + 5800 >> 2] = 0;
+ HEAP32[i1 + 5808 >> 2] = 0;
+ HEAP32[i1 + 5792 >> 2] = 0;
+ STACKTOP = i2;
+ return;
+}
+function _deflateReset(i1) {
+ i1 = i1 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0;
+ i2 = STACKTOP;
+ if ((i1 | 0) == 0) {
+  i5 = -2;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ i3 = HEAP32[i1 + 28 >> 2] | 0;
+ if ((i3 | 0) == 0) {
+  i5 = -2;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ if ((HEAP32[i1 + 32 >> 2] | 0) == 0) {
+  i5 = -2;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ if ((HEAP32[i1 + 36 >> 2] | 0) == 0) {
+  i5 = -2;
+  STACKTOP = i2;
+  return i5 | 0;
+ }
+ HEAP32[i1 + 20 >> 2] = 0;
+ HEAP32[i1 + 8 >> 2] = 0;
+ HEAP32[i1 + 24 >> 2] = 0;
+ HEAP32[i1 + 44 >> 2] = 2;
+ HEAP32[i3 + 20 >> 2] = 0;
+ HEAP32[i3 + 16 >> 2] = HEAP32[i3 + 8 >> 2];
+ i4 = i3 + 24 | 0;
+ i5 = HEAP32[i4 >> 2] | 0;
+ if ((i5 | 0) < 0) {
+  i5 = 0 - i5 | 0;
+  HEAP32[i4 >> 2] = i5;
+ }
+ HEAP32[i3 + 4 >> 2] = (i5 | 0) != 0 ? 42 : 113;
+ if ((i5 | 0) == 2) {
+  i4 = _crc32(0, 0, 0) | 0;
+ } else {
+  i4 = _adler32(0, 0, 0) | 0;
+ }
+ HEAP32[i1 + 48 >> 2] = i4;
+ HEAP32[i3 + 40 >> 2] = 0;
+ __tr_init(i3);
+ HEAP32[i3 + 60 >> 2] = HEAP32[i3 + 44 >> 2] << 1;
+ i5 = HEAP32[i3 + 76 >> 2] | 0;
+ i4 = HEAP32[i3 + 68 >> 2] | 0;
+ HEAP16[i4 + (i5 + -1 << 1) >> 1] = 0;
+ _memset(i4 | 0, 0, (i5 << 1) + -2 | 0) | 0;
+ i5 = HEAP32[i3 + 132 >> 2] | 0;
+ HEAP32[i3 + 128 >> 2] = HEAPU16[178 + (i5 * 12 | 0) >> 1] | 0;
+ HEAP32[i3 + 140 >> 2] = HEAPU16[176 + (i5 * 12 | 0) >> 1] | 0;
+ HEAP32[i3 + 144 >> 2] = HEAPU16[180 + (i5 * 12 | 0) >> 1] | 0;
+ HEAP32[i3 + 124 >> 2] = HEAPU16[182 + (i5 * 12 | 0) >> 1] | 0;
+ HEAP32[i3 + 108 >> 2] = 0;
+ HEAP32[i3 + 92 >> 2] = 0;
+ HEAP32[i3 + 116 >> 2] = 0;
+ HEAP32[i3 + 120 >> 2] = 2;
+ HEAP32[i3 + 96 >> 2] = 2;
+ HEAP32[i3 + 112 >> 2] = 0;
+ HEAP32[i3 + 104 >> 2] = 0;
+ HEAP32[i3 + 72 >> 2] = 0;
+ i5 = 0;
+ STACKTOP = i2;
+ return i5 | 0;
+}
+function _updatewindow(i6, i4) {
+ i6 = i6 | 0;
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0;
+ i1 = STACKTOP;
+ i2 = HEAP32[i6 + 28 >> 2] | 0;
+ i3 = i2 + 52 | 0;
+ i8 = HEAP32[i3 >> 2] | 0;
+ if ((i8 | 0) == 0) {
+  i8 = FUNCTION_TABLE_iiii[HEAP32[i6 + 32 >> 2] & 1](HEAP32[i6 + 40 >> 2] | 0, 1 << HEAP32[i2 + 36 >> 2], 1) | 0;
+  HEAP32[i3 >> 2] = i8;
+  if ((i8 | 0) == 0) {
+   i10 = 1;
+   STACKTOP = i1;
+   return i10 | 0;
+  }
+ }
+ i5 = i2 + 40 | 0;
+ i10 = HEAP32[i5 >> 2] | 0;
+ if ((i10 | 0) == 0) {
+  i10 = 1 << HEAP32[i2 + 36 >> 2];
+  HEAP32[i5 >> 2] = i10;
+  HEAP32[i2 + 48 >> 2] = 0;
+  HEAP32[i2 + 44 >> 2] = 0;
+ }
+ i4 = i4 - (HEAP32[i6 + 16 >> 2] | 0) | 0;
+ if (!(i4 >>> 0 < i10 >>> 0)) {
+  _memcpy(i8 | 0, (HEAP32[i6 + 12 >> 2] | 0) + (0 - i10) | 0, i10 | 0) | 0;
+  HEAP32[i2 + 48 >> 2] = 0;
+  HEAP32[i2 + 44 >> 2] = HEAP32[i5 >> 2];
+  i10 = 0;
+  STACKTOP = i1;
+  return i10 | 0;
+ }
+ i7 = i2 + 48 | 0;
+ i9 = HEAP32[i7 >> 2] | 0;
+ i10 = i10 - i9 | 0;
+ i10 = i10 >>> 0 > i4 >>> 0 ? i4 : i10;
+ i6 = i6 + 12 | 0;
+ _memcpy(i8 + i9 | 0, (HEAP32[i6 >> 2] | 0) + (0 - i4) | 0, i10 | 0) | 0;
+ i8 = i4 - i10 | 0;
+ if ((i4 | 0) != (i10 | 0)) {
+  _memcpy(HEAP32[i3 >> 2] | 0, (HEAP32[i6 >> 2] | 0) + (0 - i8) | 0, i8 | 0) | 0;
+  HEAP32[i7 >> 2] = i8;
+  HEAP32[i2 + 44 >> 2] = HEAP32[i5 >> 2];
+  i10 = 0;
+  STACKTOP = i1;
+  return i10 | 0;
+ }
+ i6 = (HEAP32[i7 >> 2] | 0) + i4 | 0;
+ i3 = HEAP32[i5 >> 2] | 0;
+ HEAP32[i7 >> 2] = (i6 | 0) == (i3 | 0) ? 0 : i6;
+ i5 = i2 + 44 | 0;
+ i2 = HEAP32[i5 >> 2] | 0;
+ if (!(i2 >>> 0 < i3 >>> 0)) {
+  i10 = 0;
+  STACKTOP = i1;
+  return i10 | 0;
+ }
+ HEAP32[i5 >> 2] = i2 + i4;
+ i10 = 0;
+ STACKTOP = i1;
+ return i10 | 0;
+}
+function _scan_tree(i1, i5, i6) {
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i6 = i6 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i7 = 0, i8 = 0, i9 = 0, i10 = 0, i11 = 0, i12 = 0, i13 = 0, i14 = 0, i15 = 0, i16 = 0;
+ i8 = STACKTOP;
+ i10 = HEAP16[i5 + 2 >> 1] | 0;
+ i9 = i10 << 16 >> 16 == 0;
+ HEAP16[i5 + (i6 + 1 << 2) + 2 >> 1] = -1;
+ i2 = i1 + 2752 | 0;
+ i3 = i1 + 2756 | 0;
+ i4 = i1 + 2748 | 0;
+ i7 = i9 ? 138 : 7;
+ i9 = i9 ? 3 : 4;
+ i13 = 0;
+ i11 = i10 & 65535;
+ i12 = -1;
+ L1 : while (1) {
+  i14 = 0;
+  do {
+   if ((i13 | 0) > (i6 | 0)) {
+    break L1;
+   }
+   i13 = i13 + 1 | 0;
+   i16 = HEAP16[i5 + (i13 << 2) + 2 >> 1] | 0;
+   i10 = i16 & 65535;
+   i14 = i14 + 1 | 0;
+   i15 = (i11 | 0) == (i10 | 0);
+  } while ((i14 | 0) < (i7 | 0) & i15);
+  do {
+   if ((i14 | 0) >= (i9 | 0)) {
+    if ((i11 | 0) == 0) {
+     if ((i14 | 0) < 11) {
+      HEAP16[i2 >> 1] = (HEAP16[i2 >> 1] | 0) + 1 << 16 >> 16;
+      break;
+     } else {
+      HEAP16[i3 >> 1] = (HEAP16[i3 >> 1] | 0) + 1 << 16 >> 16;
+      break;
+     }
+    } else {
+     if ((i11 | 0) != (i12 | 0)) {
+      i14 = i1 + (i11 << 2) + 2684 | 0;
+      HEAP16[i14 >> 1] = (HEAP16[i14 >> 1] | 0) + 1 << 16 >> 16;
+     }
+     HEAP16[i4 >> 1] = (HEAP16[i4 >> 1] | 0) + 1 << 16 >> 16;
+     break;
+    }
+   } else {
+    i12 = i1 + (i11 << 2) + 2684 | 0;
+    HEAP16[i12 >> 1] = (HEAPU16[i12 >> 1] | 0) + i14;
+   }
+  } while (0);
+  if (i16 << 16 >> 16 == 0) {
+   i12 = i11;
+   i7 = 138;
+   i9 = 3;
+   i11 = i10;
+   continue;
+  }
+  i12 = i11;
+  i7 = i15 ? 6 : 7;
+  i9 = i15 ? 3 : 4;
+  i11 = i10;
+ }
+ STACKTOP = i8;
+ return;
+}
+function _deflateEnd(i4) {
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i3 = STACKTOP;
+ if ((i4 | 0) == 0) {
+  i7 = -2;
+  STACKTOP = i3;
+  return i7 | 0;
+ }
+ i1 = i4 + 28 | 0;
+ i6 = HEAP32[i1 >> 2] | 0;
+ if ((i6 | 0) == 0) {
+  i7 = -2;
+  STACKTOP = i3;
+  return i7 | 0;
+ }
+ i2 = HEAP32[i6 + 4 >> 2] | 0;
+ switch (i2 | 0) {
+ case 42:
+ case 69:
+ case 73:
+ case 91:
+ case 103:
+ case 113:
+ case 666:
+  {
+   break;
+  }
+ default:
+  {
+   i7 = -2;
+   STACKTOP = i3;
+   return i7 | 0;
+  }
+ }
+ i5 = HEAP32[i6 + 8 >> 2] | 0;
+ if ((i5 | 0) != 0) {
+  FUNCTION_TABLE_vii[HEAP32[i4 + 36 >> 2] & 1](HEAP32[i4 + 40 >> 2] | 0, i5);
+  i6 = HEAP32[i1 >> 2] | 0;
+ }
+ i5 = HEAP32[i6 + 68 >> 2] | 0;
+ if ((i5 | 0) != 0) {
+  FUNCTION_TABLE_vii[HEAP32[i4 + 36 >> 2] & 1](HEAP32[i4 + 40 >> 2] | 0, i5);
+  i6 = HEAP32[i1 >> 2] | 0;
+ }
+ i5 = HEAP32[i6 + 64 >> 2] | 0;
+ if ((i5 | 0) != 0) {
+  FUNCTION_TABLE_vii[HEAP32[i4 + 36 >> 2] & 1](HEAP32[i4 + 40 >> 2] | 0, i5);
+  i6 = HEAP32[i1 >> 2] | 0;
+ }
+ i7 = HEAP32[i6 + 56 >> 2] | 0;
+ i5 = i4 + 36 | 0;
+ if ((i7 | 0) == 0) {
+  i4 = i4 + 40 | 0;
+ } else {
+  i4 = i4 + 40 | 0;
+  FUNCTION_TABLE_vii[HEAP32[i5 >> 2] & 1](HEAP32[i4 >> 2] | 0, i7);
+  i6 = HEAP32[i1 >> 2] | 0;
+ }
+ FUNCTION_TABLE_vii[HEAP32[i5 >> 2] & 1](HEAP32[i4 >> 2] | 0, i6);
+ HEAP32[i1 >> 2] = 0;
+ i7 = (i2 | 0) == 113 ? -3 : 0;
+ STACKTOP = i3;
+ return i7 | 0;
+}
+function _main(i4, i5) {
+ i4 = i4 | 0;
+ i5 = i5 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i6 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i2 = i1;
+ L1 : do {
+  if ((i4 | 0) > 1) {
+   i4 = HEAP8[HEAP32[i5 + 4 >> 2] | 0] | 0;
+   switch (i4 | 0) {
+   case 50:
+    {
+     i2 = 250;
+     break L1;
+    }
+   case 51:
+    {
+     i3 = 4;
+     break L1;
+    }
+   case 52:
+    {
+     i2 = 2500;
+     break L1;
+    }
+   case 53:
+    {
+     i2 = 5e3;
+     break L1;
+    }
+   case 48:
+    {
+     i6 = 0;
+     STACKTOP = i1;
+     return i6 | 0;
+    }
+   case 49:
+    {
+     i2 = 60;
+     break L1;
+    }
+   default:
+    {
+     HEAP32[i2 >> 2] = i4 + -48;
+     _printf(144, i2 | 0) | 0;
+     i6 = -1;
+     STACKTOP = i1;
+     return i6 | 0;
+    }
+   }
+  } else {
+   i3 = 4;
+  }
+ } while (0);
+ if ((i3 | 0) == 4) {
+  i2 = 500;
+ }
+ i3 = _malloc(1e5) | 0;
+ i4 = 0;
+ i6 = 0;
+ i5 = 17;
+ while (1) {
+  do {
+   if ((i6 | 0) <= 0) {
+    if ((i4 & 7 | 0) == 0) {
+     i6 = i4 & 31;
+     i5 = 0;
+     break;
+    } else {
+     i5 = (((Math_imul(i4, i4) | 0) >>> 0) % 6714 | 0) & 255;
+     break;
+    }
+   } else {
+    i6 = i6 + -1 | 0;
+   }
+  } while (0);
+  HEAP8[i3 + i4 | 0] = i5;
+  i4 = i4 + 1 | 0;
+  if ((i4 | 0) == 1e5) {
+   i4 = 0;
+   break;
+  }
+ }
+ do {
+  _doit(i3, 1e5, i4);
+  i4 = i4 + 1 | 0;
+ } while ((i4 | 0) < (i2 | 0));
+ _puts(160) | 0;
+ i6 = 0;
+ STACKTOP = i1;
+ return i6 | 0;
+}
+function _doit(i6, i1, i7) {
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ i7 = i7 | 0;
+ var i2 = 0, i3 = 0, i4 = 0, i5 = 0, i8 = 0, i9 = 0;
+ i5 = STACKTOP;
+ STACKTOP = STACKTOP + 16 | 0;
+ i4 = i5;
+ i3 = i5 + 12 | 0;
+ i2 = i5 + 8 | 0;
+ i8 = _compressBound(i1) | 0;
+ i9 = HEAP32[2] | 0;
+ if ((i9 | 0) == 0) {
+  i9 = _malloc(i8) | 0;
+  HEAP32[2] = i9;
+ }
+ if ((HEAP32[4] | 0) == 0) {
+  HEAP32[4] = _malloc(i1) | 0;
+ }
+ HEAP32[i3 >> 2] = i8;
+ _compress(i9, i3, i6, i1) | 0;
+ i7 = (i7 | 0) == 0;
+ if (i7) {
+  i9 = HEAP32[i3 >> 2] | 0;
+  HEAP32[i4 >> 2] = i1;
+  HEAP32[i4 + 4 >> 2] = i9;
+  _printf(24, i4 | 0) | 0;
+ }
+ HEAP32[i2 >> 2] = i1;
+ _uncompress(HEAP32[4] | 0, i2, HEAP32[2] | 0, HEAP32[i3 >> 2] | 0) | 0;
+ if ((HEAP32[i2 >> 2] | 0) != (i1 | 0)) {
+  ___assert_fail(40, 72, 24, 104);
+ }
+ if (!i7) {
+  STACKTOP = i5;
+  return;
+ }
+ if ((_strcmp(i6, HEAP32[4] | 0) | 0) == 0) {
+  STACKTOP = i5;
+  return;
+ } else {
+  ___assert_fail(112, 72, 25, 104);
+ }
+}
+function _uncompress(i6, i1, i5, i7) {
+ i6 = i6 | 0;
+ i1 = i1 | 0;
+ i5 = i5 | 0;
+ i7 = i7 | 0;
+ var i2 = 0, i3 = 0, i4 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i3 = i2;
+ HEAP32[i3 >> 2] = i5;
+ i5 = i3 + 4 | 0;
+ HEAP32[i5 >> 2] = i7;
+ HEAP32[i3 + 12 >> 2] = i6;
+ HEAP32[i3 + 16 >> 2] = HEAP32[i1 >> 2];
+ HEAP32[i3 + 32 >> 2] = 0;
+ HEAP32[i3 + 36 >> 2] = 0;
+ i6 = _inflateInit_(i3, 2992, 56) | 0;
+ if ((i6 | 0) != 0) {
+  i7 = i6;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ i6 = _inflate(i3, 4) | 0;
+ if ((i6 | 0) == 1) {
+  HEAP32[i1 >> 2] = HEAP32[i3 + 20 >> 2];
+  i7 = _inflateEnd(i3) | 0;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ _inflateEnd(i3) | 0;
+ if ((i6 | 0) == 2) {
+  i7 = -3;
+  STACKTOP = i2;
+  return i7 | 0;
+ } else if ((i6 | 0) == -5) {
+  i4 = 4;
+ }
+ if ((i4 | 0) == 4 ? (HEAP32[i5 >> 2] | 0) == 0 : 0) {
+  i7 = -3;
+  STACKTOP = i2;
+  return i7 | 0;
+ }
+ i7 = i6;
+ STACKTOP = i2;
+ return i7 | 0;
+}
+function _compress(i4, i1, i6, i5) {
+ i4 = i4 | 0;
+ i1 = i1 | 0;
+ i6 = i6 | 0;
+ i5 = i5 | 0;
+ var i2 = 0, i3 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + 64 | 0;
+ i3 = i2;
+ HEAP32[i3 >> 2] = i6;
+ HEAP32[i3 + 4 >> 2] = i5;
+ HEAP32[i3 + 12 >> 2] = i4;
+ HEAP32[i3 + 16 >> 2] = HEAP32[i1 >> 2];
+ HEAP32[i3 + 32 >> 2] = 0;
+ HEAP32[i3 + 36 >> 2] = 0;
+ HEAP32[i3 + 40 >> 2] = 0;
+ i4 = _deflateInit_(i3, -1, 168, 56) | 0;
+ if ((i4 | 0) != 0) {
+  i6 = i4;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ i4 = _deflate(i3, 4) | 0;
+ if ((i4 | 0) == 1) {
+  HEAP32[i1 >> 2] = HEAP32[i3 + 20 >> 2];
+  i6 = _deflateEnd(i3) | 0;
+  STACKTOP = i2;
+  return i6 | 0;
+ } else {
+  _deflateEnd(i3) | 0;
+  i6 = (i4 | 0) == 0 ? -5 : i4;
+  STACKTOP = i2;
+  return i6 | 0;
+ }
+ return 0;
+}
+function _inflateEnd(i4) {
+ i4 = i4 | 0;
+ var i1 = 0, i2 = 0, i3 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i1 = STACKTOP;
+ if ((i4 | 0) == 0) {
+  i7 = -2;
+  STACKTOP = i1;
+  return i7 | 0;
+ }
+ i2 = i4 + 28 | 0;
+ i3 = HEAP32[i2 >> 2] | 0;
+ if ((i3 | 0) == 0) {
+  i7 = -2;
+  STACKTOP = i1;
+  return i7 | 0;
+ }
+ i6 = i4 + 36 | 0;
+ i5 = HEAP32[i6 >> 2] | 0;
+ if ((i5 | 0) == 0) {
+  i7 = -2;
+  STACKTOP = i1;
+  return i7 | 0;
+ }
+ i7 = HEAP32[i3 + 52 >> 2] | 0;
+ i4 = i4 + 40 | 0;
+ if ((i7 | 0) != 0) {
+  FUNCTION_TABLE_vii[i5 & 1](HEAP32[i4 >> 2] | 0, i7);
+  i5 = HEAP32[i6 >> 2] | 0;
+  i3 = HEAP32[i2 >> 2] | 0;
+ }
+ FUNCTION_TABLE_vii[i5 & 1](HEAP32[i4 >> 2] | 0, i3);
+ HEAP32[i2 >> 2] = 0;
+ i7 = 0;
+ STACKTOP = i1;
+ return i7 | 0;
+}
+function _memcpy(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i4 = 0;
+ if ((i1 | 0) >= 4096) return _emscripten_memcpy_big(i3 | 0, i2 | 0, i1 | 0) | 0;
+ i4 = i3 | 0;
+ if ((i3 & 3) == (i2 & 3)) {
+  while (i3 & 3) {
+   if ((i1 | 0) == 0) return i4 | 0;
+   HEAP8[i3] = HEAP8[i2] | 0;
+   i3 = i3 + 1 | 0;
+   i2 = i2 + 1 | 0;
+   i1 = i1 - 1 | 0;
+  }
+  while ((i1 | 0) >= 4) {
+   HEAP32[i3 >> 2] = HEAP32[i2 >> 2];
+   i3 = i3 + 4 | 0;
+   i2 = i2 + 4 | 0;
+   i1 = i1 - 4 | 0;
+  }
+ }
+ while ((i1 | 0) > 0) {
+  HEAP8[i3] = HEAP8[i2] | 0;
+  i3 = i3 + 1 | 0;
+  i2 = i2 + 1 | 0;
+  i1 = i1 - 1 | 0;
+ }
+ return i4 | 0;
+}
+function _strcmp(i4, i2) {
+ i4 = i4 | 0;
+ i2 = i2 | 0;
+ var i1 = 0, i3 = 0, i5 = 0;
+ i1 = STACKTOP;
+ i5 = HEAP8[i4] | 0;
+ i3 = HEAP8[i2] | 0;
+ if (i5 << 24 >> 24 != i3 << 24 >> 24 | i5 << 24 >> 24 == 0 | i3 << 24 >> 24 == 0) {
+  i4 = i5;
+  i5 = i3;
+  i4 = i4 & 255;
+  i5 = i5 & 255;
+  i5 = i4 - i5 | 0;
+  STACKTOP = i1;
+  return i5 | 0;
+ }
+ do {
+  i4 = i4 + 1 | 0;
+  i2 = i2 + 1 | 0;
+  i5 = HEAP8[i4] | 0;
+  i3 = HEAP8[i2] | 0;
+ } while (!(i5 << 24 >> 24 != i3 << 24 >> 24 | i5 << 24 >> 24 == 0 | i3 << 24 >> 24 == 0));
+ i4 = i5 & 255;
+ i5 = i3 & 255;
+ i5 = i4 - i5 | 0;
+ STACKTOP = i1;
+ return i5 | 0;
+}
+function _memset(i1, i4, i3) {
+ i1 = i1 | 0;
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ var i2 = 0, i5 = 0, i6 = 0, i7 = 0;
+ i2 = i1 + i3 | 0;
+ if ((i3 | 0) >= 20) {
+  i4 = i4 & 255;
+  i7 = i1 & 3;
+  i6 = i4 | i4 << 8 | i4 << 16 | i4 << 24;
+  i5 = i2 & ~3;
+  if (i7) {
+   i7 = i1 + 4 - i7 | 0;
+   while ((i1 | 0) < (i7 | 0)) {
+    HEAP8[i1] = i4;
+    i1 = i1 + 1 | 0;
+   }
+  }
+  while ((i1 | 0) < (i5 | 0)) {
+   HEAP32[i1 >> 2] = i6;
+   i1 = i1 + 4 | 0;
+  }
+ }
+ while ((i1 | 0) < (i2 | 0)) {
+  HEAP8[i1] = i4;
+  i1 = i1 + 1 | 0;
+ }
+ return i1 - i3 | 0;
+}
+function copyTempDouble(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+ HEAP8[tempDoublePtr + 4 | 0] = HEAP8[i1 + 4 | 0];
+ HEAP8[tempDoublePtr + 5 | 0] = HEAP8[i1 + 5 | 0];
+ HEAP8[tempDoublePtr + 6 | 0] = HEAP8[i1 + 6 | 0];
+ HEAP8[tempDoublePtr + 7 | 0] = HEAP8[i1 + 7 | 0];
+}
+function __tr_init(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ HEAP32[i1 + 2840 >> 2] = i1 + 148;
+ HEAP32[i1 + 2848 >> 2] = 1064;
+ HEAP32[i1 + 2852 >> 2] = i1 + 2440;
+ HEAP32[i1 + 2860 >> 2] = 1088;
+ HEAP32[i1 + 2864 >> 2] = i1 + 2684;
+ HEAP32[i1 + 2872 >> 2] = 1112;
+ HEAP16[i1 + 5816 >> 1] = 0;
+ HEAP32[i1 + 5820 >> 2] = 0;
+ HEAP32[i1 + 5812 >> 2] = 8;
+ _init_block(i1);
+ STACKTOP = i2;
+ return;
+}
+function copyTempFloat(i1) {
+ i1 = i1 | 0;
+ HEAP8[tempDoublePtr] = HEAP8[i1];
+ HEAP8[tempDoublePtr + 1 | 0] = HEAP8[i1 + 1 | 0];
+ HEAP8[tempDoublePtr + 2 | 0] = HEAP8[i1 + 2 | 0];
+ HEAP8[tempDoublePtr + 3 | 0] = HEAP8[i1 + 3 | 0];
+}
+function _deflateInit_(i4, i3, i2, i1) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ var i5 = 0;
+ i5 = STACKTOP;
+ i4 = _deflateInit2_(i4, i3, 8, 15, 8, 0, i2, i1) | 0;
+ STACKTOP = i5;
+ return i4 | 0;
+}
+function _zcalloc(i3, i1, i2) {
+ i3 = i3 | 0;
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ var i4 = 0;
+ i4 = STACKTOP;
+ i3 = _malloc(Math_imul(i2, i1) | 0) | 0;
+ STACKTOP = i4;
+ return i3 | 0;
+}
+function dynCall_iiii(i4, i3, i2, i1) {
+ i4 = i4 | 0;
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ return FUNCTION_TABLE_iiii[i4 & 1](i3 | 0, i2 | 0, i1 | 0) | 0;
+}
+function runPostSets() {}
+function _strlen(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = i1;
+ while (HEAP8[i2] | 0) {
+  i2 = i2 + 1 | 0;
+ }
+ return i2 - i1 | 0;
+}
+function stackAlloc(i1) {
+ i1 = i1 | 0;
+ var i2 = 0;
+ i2 = STACKTOP;
+ STACKTOP = STACKTOP + i1 | 0;
+ STACKTOP = STACKTOP + 7 & -8;
+ return i2 | 0;
+}
+function dynCall_iii(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ return FUNCTION_TABLE_iii[i3 & 3](i2 | 0, i1 | 0) | 0;
+}
+function setThrew(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ if ((__THREW__ | 0) == 0) {
+  __THREW__ = i1;
+  threwValue = i2;
+ }
+}
+function dynCall_vii(i3, i2, i1) {
+ i3 = i3 | 0;
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ FUNCTION_TABLE_vii[i3 & 1](i2 | 0, i1 | 0);
+}
+function _zcfree(i2, i1) {
+ i2 = i2 | 0;
+ i1 = i1 | 0;
+ i2 = STACKTOP;
+ _free(i1);
+ STACKTOP = i2;
+ return;
+}
+function _compressBound(i1) {
+ i1 = i1 | 0;
+ return i1 + 13 + (i1 >>> 12) + (i1 >>> 14) + (i1 >>> 25) | 0;
+}
+function b0(i1, i2, i3) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ abort(0);
+ return 0;
+}
+function b2(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ abort(2);
+ return 0;
+}
+function b1(i1, i2) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ abort(1);
+}
+function stackRestore(i1) {
+ i1 = i1 | 0;
+ STACKTOP = i1;
+}
+function setTempRet9(i1) {
+ i1 = i1 | 0;
+ tempRet9 = i1;
+}
+function setTempRet8(i1) {
+ i1 = i1 | 0;
+ tempRet8 = i1;
+}
+function setTempRet7(i1) {
+ i1 = i1 | 0;
+ tempRet7 = i1;
+}
+function setTempRet6(i1) {
+ i1 = i1 | 0;
+ tempRet6 = i1;
+}
+function setTempRet5(i1) {
+ i1 = i1 | 0;
+ tempRet5 = i1;
+}
+function setTempRet4(i1) {
+ i1 = i1 | 0;
+ tempRet4 = i1;
+}
+function setTempRet3(i1) {
+ i1 = i1 | 0;
+ tempRet3 = i1;
+}
+function setTempRet2(i1) {
+ i1 = i1 | 0;
+ tempRet2 = i1;
+}
+function setTempRet1(i1) {
+ i1 = i1 | 0;
+ tempRet1 = i1;
+}
+function setTempRet0(i1) {
+ i1 = i1 | 0;
+ tempRet0 = i1;
+}
+function stackSave() {
+ return STACKTOP | 0;
+}
+
+// EMSCRIPTEN_END_FUNCS
+  var FUNCTION_TABLE_iiii = [b0,_zcalloc];
+  var FUNCTION_TABLE_vii = [b1,_zcfree];
+  var FUNCTION_TABLE_iii = [b2,_deflate_stored,_deflate_fast,_deflate_slow];
+
+  return { _strlen: _strlen, _free: _free, _main: _main, _memset: _memset, _malloc: _malloc, _memcpy: _memcpy, runPostSets: runPostSets, stackAlloc: stackAlloc, stackSave: stackSave, stackRestore: stackRestore, setThrew: setThrew, setTempRet0: setTempRet0, setTempRet1: setTempRet1, setTempRet2: setTempRet2, setTempRet3: setTempRet3, setTempRet4: setTempRet4, setTempRet5: setTempRet5, setTempRet6: setTempRet6, setTempRet7: setTempRet7, setTempRet8: setTempRet8, setTempRet9: setTempRet9, dynCall_iiii: dynCall_iiii, dynCall_vii: dynCall_vii, dynCall_iii: dynCall_iii };
+})
+// EMSCRIPTEN_END_ASM
+({ "Math": Math, "Int8Array": Int8Array, "Int16Array": Int16Array, "Int32Array": Int32Array, "Uint8Array": Uint8Array, "Uint16Array": Uint16Array, "Uint32Array": Uint32Array, "Float32Array": Float32Array, "Float64Array": Float64Array }, { "abort": abort, "assert": assert, "asmPrintInt": asmPrintInt, "asmPrintFloat": asmPrintFloat, "min": Math_min, "invoke_iiii": invoke_iiii, "invoke_vii": invoke_vii, "invoke_iii": invoke_iii, "_send": _send, "___setErrNo": ___setErrNo, "___assert_fail": ___assert_fail, "_fflush": _fflush, "_pwrite": _pwrite, "__reallyNegative": __reallyNegative, "_sbrk": _sbrk, "___errno_location": ___errno_location, "_emscripten_memcpy_big": _emscripten_memcpy_big, "_fileno": _fileno, "_sysconf": _sysconf, "_puts": _puts, "_mkport": _mkport, "_write": _write, "_llvm_bswap_i32": _llvm_bswap_i32, "_fputc": _fputc, "_abort": _abort, "_fwrite": _fwrite, "_time": _time, "_fprintf": _fprintf, "__formatString": __formatString, "_fputs": _fputs, "_printf": _printf, "STACKTOP": STACKTOP, "STACK_MAX": STACK_MAX, "tempDoublePtr": tempDoublePtr, "ABORT": ABORT, "NaN": NaN, "Infinity": Infinity }, buffer);
+var _strlen = Module["_strlen"] = asm["_strlen"];
+var _free = Module["_free"] = asm["_free"];
+var _main = Module["_main"] = asm["_main"];
+var _memset = Module["_memset"] = asm["_memset"];
+var _malloc = Module["_malloc"] = asm["_malloc"];
+var _memcpy = Module["_memcpy"] = asm["_memcpy"];
+var runPostSets = Module["runPostSets"] = asm["runPostSets"];
+var dynCall_iiii = Module["dynCall_iiii"] = asm["dynCall_iiii"];
+var dynCall_vii = Module["dynCall_vii"] = asm["dynCall_vii"];
+var dynCall_iii = Module["dynCall_iii"] = asm["dynCall_iii"];
+
+Runtime.stackAlloc = function(size) { return asm['stackAlloc'](size) };
+Runtime.stackSave = function() { return asm['stackSave']() };
+Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
+
+
+// Warning: printing of i64 values may be slightly rounded! No deep i64 math used, so precise i64 code not included
+var i64Math = null;
+
+// === Auto-generated postamble setup entry stuff ===
+
+if (memoryInitializer) {
+  if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {
+    var data = Module['readBinary'](memoryInitializer);
+    HEAPU8.set(data, STATIC_BASE);
+  } else {
+    addRunDependency('memory initializer');
+    Browser.asyncLoad(memoryInitializer, function(data) {
+      HEAPU8.set(data, STATIC_BASE);
+      removeRunDependency('memory initializer');
+    }, function(data) {
+      throw 'could not load memory initializer ' + memoryInitializer;
+    });
+  }
+}
+
+function ExitStatus(status) {
+  this.name = "ExitStatus";
+  this.message = "Program terminated with exit(" + status + ")";
+  this.status = status;
+};
+ExitStatus.prototype = new Error();
+ExitStatus.prototype.constructor = ExitStatus;
+
+var initialStackTop;
+var preloadStartTime = null;
+var calledMain = false;
+
+dependenciesFulfilled = function runCaller() {
+  // If run has never been called, and we should call run (INVOKE_RUN is true, and Module.noInitialRun is not false)
+  if (!Module['calledRun'] && shouldRunNow) run([].concat(Module["arguments"]));
+  if (!Module['calledRun']) dependenciesFulfilled = runCaller; // try this again later, after new deps are fulfilled
+}
+
+Module['callMain'] = Module.callMain = function callMain(args) {
+  assert(runDependencies == 0, 'cannot call main when async dependencies remain! (listen on __ATMAIN__)');
+  assert(__ATPRERUN__.length == 0, 'cannot call main when preRun functions remain to be called');
+
+  args = args || [];
+
+  ensureInitRuntime();
+
+  var argc = args.length+1;
+  function pad() {
+    for (var i = 0; i < 4-1; i++) {
+      argv.push(0);
+    }
+  }
+  var argv = [allocate(intArrayFromString("/bin/this.program"), 'i8', ALLOC_NORMAL) ];
+  pad();
+  for (var i = 0; i < argc-1; i = i + 1) {
+    argv.push(allocate(intArrayFromString(args[i]), 'i8', ALLOC_NORMAL));
+    pad();
+  }
+  argv.push(0);
+  argv = allocate(argv, 'i32', ALLOC_NORMAL);
+
+  initialStackTop = STACKTOP;
+
+  try {
+
+    var ret = Module['_main'](argc, argv, 0);
+
+
+    // if we're not running an evented main loop, it's time to exit
+    if (!Module['noExitRuntime']) {
+      exit(ret);
+    }
+  }
+  catch(e) {
+    if (e instanceof ExitStatus) {
+      // exit() throws this once it's done to make sure execution
+      // has been stopped completely
+      return;
+    } else if (e == 'SimulateInfiniteLoop') {
+      // running an evented main loop, don't immediately exit
+      Module['noExitRuntime'] = true;
+      return;
+    } else {
+      if (e && typeof e === 'object' && e.stack) Module.printErr('exception thrown: ' + [e, e.stack]);
+      throw e;
+    }
+  } finally {
+    calledMain = true;
+  }
+}
+
+
+
+
+function run(args) {
+  args = args || Module['arguments'];
+
+  if (preloadStartTime === null) preloadStartTime = Date.now();
+
+  if (runDependencies > 0) {
+    Module.printErr('run() called, but dependencies remain, so not running');
+    return;
+  }
+
+  preRun();
+
+  if (runDependencies > 0) return; // a preRun added a dependency, run will be called later
+  if (Module['calledRun']) return; // run may have just been called through dependencies being fulfilled just in this very frame
+
+  function doRun() {
+    if (Module['calledRun']) return; // run may have just been called while the async setStatus time below was happening
+    Module['calledRun'] = true;
+
+    ensureInitRuntime();
+
+    preMain();
+
+    if (ENVIRONMENT_IS_WEB && preloadStartTime !== null) {
+      Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
+    }
+
+    if (Module['_main'] && shouldRunNow) {
+      Module['callMain'](args);
+    }
+
+    postRun();
+  }
+
+  if (Module['setStatus']) {
+    Module['setStatus']('Running...');
+    setTimeout(function() {
+      setTimeout(function() {
+        Module['setStatus']('');
+      }, 1);
+      if (!ABORT) doRun();
+    }, 1);
+  } else {
+    doRun();
+  }
+}
+Module['run'] = Module.run = run;
+
+function exit(status) {
+  ABORT = true;
+  EXITSTATUS = status;
+  STACKTOP = initialStackTop;
+
+  // exit the runtime
+  exitRuntime();
+
+  // TODO We should handle this differently based on environment.
+  // In the browser, the best we can do is throw an exception
+  // to halt execution, but in node we could process.exit and
+  // I'd imagine SM shell would have something equivalent.
+  // This would let us set a proper exit status (which
+  // would be great for checking test exit statuses).
+  // https://github.com/kripken/emscripten/issues/1371
+
+  // throw an exception to halt the current execution
+  throw new ExitStatus(status);
+}
+Module['exit'] = Module.exit = exit;
+
+function abort(text) {
+  if (text) {
+    Module.print(text);
+    Module.printErr(text);
+  }
+
+  ABORT = true;
+  EXITSTATUS = 1;
+
+  var extra = '\nIf this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.';
+
+  throw 'abort() at ' + stackTrace() + extra;
+}
+Module['abort'] = Module.abort = abort;
+
+// {{PRE_RUN_ADDITIONS}}
+
+if (Module['preInit']) {
+  if (typeof Module['preInit'] == 'function') Module['preInit'] = [Module['preInit']];
+  while (Module['preInit'].length > 0) {
+    Module['preInit'].pop()();
+  }
+}
+
+// shouldRunNow refers to calling main(), not run().
+var shouldRunNow = true;
+if (Module['noInitialRun']) {
+  shouldRunNow = false;
+}
+
+
+run([].concat(Module["arguments"]));
diff --git a/test/mjsunit/asm/float32array-negative-offset.js b/test/mjsunit/asm/float32array-negative-offset.js
new file mode 100644
index 0000000..524bdc8
--- /dev/null
+++ b/test/mjsunit/asm/float32array-negative-offset.js
@@ -0,0 +1,42 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = this;
+var buffer = new ArrayBuffer(64 * 1024);
+var foreign = {}
+
+
+var m = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM32 = new stdlib.Float32Array(heap);
+  function load(i) {
+    i = i|0;
+    i = +MEM32[i >> 2];
+    return i;
+  }
+  function store(i, v) {
+    i = i|0;
+    v = +v;
+    MEM32[i >> 2] = v;
+  }
+  function load8(i) {
+    i = i|0;
+    i = +MEM32[i + 8 >> 2];
+    return i;
+  }
+  function store8(i, v) {
+    i = i|0;
+    v = +v;
+    MEM32[i + 8 >> 2] = v;
+  }
+  return { load: load, store: store, load8: load8, store8: store8 };
+})(stdlib, foreign, buffer);
+
+assertEquals(NaN, m.load(-8));
+assertEquals(NaN, m.load8(-16));
+m.store(0, 42.0);
+assertEquals(42.0, m.load8(-8));
+m.store8(-8, 99.0);
+assertEquals(99.0, m.load(0));
+assertEquals(99.0, m.load8(-8));
diff --git a/test/mjsunit/asm/float32array-outofbounds.js b/test/mjsunit/asm/float32array-outofbounds.js
new file mode 100644
index 0000000..8709b70
--- /dev/null
+++ b/test/mjsunit/asm/float32array-outofbounds.js
@@ -0,0 +1,30 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM32 = new stdlib.Float32Array(heap);
+  function load(i) {
+    i = i|0;
+    i = +MEM32[i >> 2];
+    return i;
+  }
+  function store(i, v) {
+    i = i|0;
+    v = +v;
+    MEM32[i >> 2] = v;
+  }
+  return { load: load, store: store };
+}
+
+var m = Module(this, {}, new ArrayBuffer(4));
+
+m.store(0, 42.0);
+for (var i = 1; i < 64; ++i) {
+  m.store(i * 4 * 32 * 1024, i);
+}
+assertEquals(42.0, m.load(0));
+for (var i = 1; i < 64; ++i) {
+  assertEquals(NaN, m.load(i * 4 * 32 * 1024));
+}
diff --git a/test/mjsunit/asm/float32array-store-div.js b/test/mjsunit/asm/float32array-store-div.js
new file mode 100644
index 0000000..78224f9
--- /dev/null
+++ b/test/mjsunit/asm/float32array-store-div.js
@@ -0,0 +1,16 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM32 = new stdlib.Float32Array(heap);
+  function foo(i) {
+    MEM32[0] = (i >>> 0) / 2;
+    return MEM32[0];
+  }
+  return { foo: foo };
+}
+
+var foo = Module(this, {}, new ArrayBuffer(64 * 1024)).foo;
+assertEquals(0.5, foo(1));
diff --git a/test/mjsunit/asm/float64array-negative-offset.js b/test/mjsunit/asm/float64array-negative-offset.js
new file mode 100644
index 0000000..154bd82
--- /dev/null
+++ b/test/mjsunit/asm/float64array-negative-offset.js
@@ -0,0 +1,42 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = this;
+var buffer = new ArrayBuffer(64 * 1024);
+var foreign = {}
+
+
+var m = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM64 = new stdlib.Float64Array(heap);
+  function load(i) {
+    i = i|0;
+    i = +MEM64[i >> 3];
+    return i;
+  }
+  function store(i, v) {
+    i = i|0;
+    v = +v;
+    MEM64[i >> 3] = v;
+  }
+  function load8(i) {
+    i = i|0;
+    i = +MEM64[i + 8 >> 3];
+    return i;
+  }
+  function store8(i, v) {
+    i = i|0;
+    v = +v;
+    MEM64[i + 8 >> 3] = v;
+  }
+  return { load: load, store: store, load8: load8, store8: store8 };
+})(stdlib, foreign, buffer);
+
+assertEquals(NaN, m.load(-8));
+assertEquals(NaN, m.load8(-16));
+m.store(0, 42.0);
+assertEquals(42.0, m.load8(-8));
+m.store8(-8, 99.0);
+assertEquals(99.0, m.load(0));
+assertEquals(99.0, m.load8(-8));
diff --git a/test/mjsunit/asm/float64array-outofbounds.js b/test/mjsunit/asm/float64array-outofbounds.js
new file mode 100644
index 0000000..106d8e4
--- /dev/null
+++ b/test/mjsunit/asm/float64array-outofbounds.js
@@ -0,0 +1,30 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM64 = new stdlib.Float64Array(heap);
+  function load(i) {
+    i = i|0;
+    i = +MEM64[i >> 3];
+    return i;
+  }
+  function store(i, v) {
+    i = i|0;
+    v = +v;
+    MEM64[i >> 3] = v;
+  }
+  return { load: load, store: store };
+}
+
+var m = Module(this, {}, new ArrayBuffer(8));
+
+m.store(0, 3.12);
+for (var i = 1; i < 64; ++i) {
+  m.store(i * 8 * 32 * 1024, i);
+}
+assertEquals(3.12, m.load(0));
+for (var i = 1; i < 64; ++i) {
+  assertEquals(NaN, m.load(i * 8 * 32 * 1024));
+}
diff --git a/test/mjsunit/asm/float64array-store-div.js b/test/mjsunit/asm/float64array-store-div.js
new file mode 100644
index 0000000..10b0011
--- /dev/null
+++ b/test/mjsunit/asm/float64array-store-div.js
@@ -0,0 +1,16 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM64 = new stdlib.Float64Array(heap);
+  function foo(i) {
+    MEM64[0] = (i >>> 0) / 2;
+    return MEM64[0];
+  }
+  return { foo: foo };
+}
+
+var foo = Module(this, {}, new ArrayBuffer(64 * 1024)).foo;
+assertEquals(0.5, foo(1));
diff --git a/test/mjsunit/asm/float64mul.js b/test/mjsunit/asm/float64mul.js
new file mode 100644
index 0000000..9cd9582
--- /dev/null
+++ b/test/mjsunit/asm/float64mul.js
@@ -0,0 +1,43 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  function f1(i) {
+    i = +i;
+    return +(i * -1);
+  }
+  function f2(i) {
+    i = +i;
+    return +(-1 * i);
+  }
+  function f3(i) {
+    i = +i;
+    return +(-i);
+  }
+  return { f1: f1, f2: f2, f3: f3 };
+}
+
+var m = Module(this, {}, new ArrayBuffer(64 * 1024));
+
+assertEquals(NaN, m.f1(NaN));
+assertEquals(NaN, m.f2(NaN));
+assertEquals(NaN, m.f3(NaN));
+assertEquals(Infinity, 1 / m.f1(-0));
+assertEquals(Infinity, 1 / m.f2(-0));
+assertEquals(Infinity, 1 / m.f3(-0));
+assertEquals(Infinity, m.f1(-Infinity));
+assertEquals(Infinity, m.f2(-Infinity));
+assertEquals(Infinity, m.f3(-Infinity));
+assertEquals(-Infinity, 1 / m.f1(0));
+assertEquals(-Infinity, 1 / m.f2(0));
+assertEquals(-Infinity, 1 / m.f3(0));
+assertEquals(-Infinity, m.f1(Infinity));
+assertEquals(-Infinity, m.f2(Infinity));
+assertEquals(-Infinity, m.f3(Infinity));
+for (var i = -2147483648; i < 2147483648; i += 3999777) {
+  assertEquals(-i, m.f1(i));
+  assertEquals(-i, m.f2(i));
+  assertEquals(-i, m.f3(i));
+}
diff --git a/test/mjsunit/asm/if-folding.js b/test/mjsunit/asm/if-folding.js
new file mode 100644
index 0000000..80070ee
--- /dev/null
+++ b/test/mjsunit/asm/if-folding.js
@@ -0,0 +1,100 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module() {
+  "use asm";
+
+  function if0() {
+    if (0) return 11;
+    return 12;
+  }
+
+  function if1() {
+    if (1) return 13;
+    return 14;
+  }
+
+  function if2() {
+    if (0) return 15;
+    else return 16;
+  }
+
+  function if3() {
+    if (1) return 17;
+    else return 18;
+  }
+
+  function if4() {
+    return 1 ? 19 : 20;
+  }
+
+  function if5() {
+    return 0 ? 21 : 22;
+  }
+
+  function if6() {
+    var x = 0 ? 23 : 24;
+    return x;
+  }
+
+  function if7() {
+    if (0) { var x = 0 ? 25 : 26; }
+    else { var x = 0 ? 27 : 28; }
+    return x;
+  }
+
+  function if8() {
+    if (0) {
+      if (0) { var x = 0 ? 29 : 30; }
+      else { var x = 0 ? 31 : 32; }
+    } else {
+      if (0) { var x = 0 ? 33 : 34; }
+      else { var x = 0 ? 35 : 36; }
+    }
+    return x;
+  }
+
+  return {if0: if0, if1: if1, if2: if2, if3: if3, if4: if4, if5: if5, if6: if6, if7: if7, if8: if8 };
+}
+
+var m = Module();
+assertEquals(12, m.if0());
+assertEquals(13, m.if1());
+assertEquals(16, m.if2());
+assertEquals(17, m.if3());
+assertEquals(19, m.if4());
+assertEquals(22, m.if5());
+assertEquals(24, m.if6());
+assertEquals(28, m.if7());
+assertEquals(36, m.if8());
+
+
+function Spec(a,b,c) {
+  "use asm";
+
+  var xx = a | 0;
+  var yy = b | 0;
+  var zz = c | 0;
+
+  function f() {
+    if (xx) {
+      if (yy) { var x = zz ? 29 : 30; }
+      else { var x = zz ? 31 : 32; }
+    } else {
+      if (yy) { var x = zz ? 33 : 34; }
+      else { var x = zz ? 35 : 36; }
+    }
+    return x;
+  }
+  return {f: f};
+}
+
+assertEquals(36, Spec(0,0,0).f());
+assertEquals(35, Spec(0,0,1).f());
+assertEquals(34, Spec(0,1,0).f());
+assertEquals(33, Spec(0,1,1).f());
+assertEquals(32, Spec(1,0,0).f());
+assertEquals(31, Spec(1,0,1).f());
+assertEquals(30, Spec(1,1,0).f());
+assertEquals(29, Spec(1,1,1).f());
diff --git a/test/mjsunit/asm/if-reduction.js b/test/mjsunit/asm/if-reduction.js
new file mode 100644
index 0000000..b0dcc13
--- /dev/null
+++ b/test/mjsunit/asm/if-reduction.js
@@ -0,0 +1,111 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module() {
+  "use asm";
+
+  function if0() {
+    var x = 0 ? 11 : 12;
+    return (x == 11) | 0;
+  }
+
+  function if1() {
+    var x = 1 ? 13 : 14;
+    return (x == 13) | 0;
+  }
+
+  function if2() {
+    var x = 0 ? 15 : 16;
+    return (x != 15) | 0;
+  }
+
+  function if3() {
+    var x = 1 ? 17 : 18;
+    return (x != 17) | 0;
+  }
+
+  function if4() {
+    var x = 0 ? 19 : 20;
+    var y = (x == 19) ? 21 : 22;
+    return y;
+  }
+
+  function if5() {
+    var x = 1 ? 23 : 24;
+    var y = (x == 23) ? 25 : 26;
+    return y;
+  }
+
+  function if6() {
+    var x = 0 ? 27 : 28;
+    var y = (x == 27) ? 29 : 30;
+    var z = (y == 29) ? 31 : 32;
+    return z;
+  }
+
+  function if7() {
+    var x = 1 ? 33 : 34;
+    var y = (x == 33) ? 35 : 36;
+    var z = (y == 35) ? 37 : 38;
+    var w = (z == 37) ? 39 : 40;
+    return w;
+  }
+
+  function if8() {
+    if (0) {
+      var x = 0 ? 43 : 44;
+      var y = (x == 43) ? 45 : 46;
+      var z = (y == 45) ? 47 : 48;
+      var w = (z == 47) ? 49 : 50;
+    } else {
+      var x = 1 ? 53 : 54;
+      var y = (x == 53) ? 55 : 56;
+      var z = (y == 55) ? 57 : 58;
+      var w = (z == 57) ? 59 : 60;
+    }
+    return w;
+  }
+
+  return {if0: if0, if1: if1, if2: if2, if3: if3, if4: if4, if5: if5, if6: if6, if7: if7, if8: if8 };
+}
+
+var m = Module();
+assertEquals(0, m.if0());
+assertEquals(1, m.if1());
+assertEquals(1, m.if2());
+assertEquals(0, m.if3());
+assertEquals(22, m.if4());
+assertEquals(25, m.if5());
+assertEquals(32, m.if6());
+assertEquals(39, m.if7());
+assertEquals(59, m.if8());
+
+
+function Spec(a,b) {
+  "use asm";
+
+  var xx = a | 0;
+  var yy = b | 0;
+
+  function f() {
+    if (xx) {
+      var x = yy ? 43 : 44;
+      var y = (x == 43) ? 45 : 46;
+      var z = (y == 45) ? 47 : 48;
+      var w = (z == 47) ? 49 : 50;
+    } else {
+      var x = yy ? 53 : 54;
+      var y = (x == 53) ? 55 : 56;
+      var z = (y == 55) ? 57 : 58;
+      var w = (z == 57) ? 59 : 60;
+    }
+    return w;
+  }
+  return {f: f};
+}
+
+assertEquals(60, Spec(0,0).f());
+assertEquals(59, Spec(0,1).f());
+assertEquals(50, Spec(1,0).f());
+assertEquals(49, Spec(1,1).f());
diff --git a/test/mjsunit/asm/if-tonumber.js b/test/mjsunit/asm/if-tonumber.js
new file mode 100644
index 0000000..dd3f73b
--- /dev/null
+++ b/test/mjsunit/asm/if-tonumber.js
@@ -0,0 +1,31 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = this;
+var buffer = new ArrayBuffer(64 * 1024);
+var foreign = {}
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  function foo(i) {
+    i = i|0;
+    if (i > 0) {
+      i = i == 1;
+    } else {
+      i = 1;
+    }
+    return i & 1|0;
+  }
+  return { foo: foo };
+}
+
+var m = Module(stdlib, foreign, buffer);
+
+assertEquals(1, m.foo(-1));
+assertEquals(1, m.foo(-0));
+assertEquals(1, m.foo(0));
+assertEquals(1, m.foo(1));
+assertEquals(0, m.foo(2));
+assertEquals(1, m.foo(true));
+assertEquals(1, m.foo(false));
diff --git a/test/mjsunit/asm/infinite-loops-taken.js b/test/mjsunit/asm/infinite-loops-taken.js
new file mode 100644
index 0000000..d136c62
--- /dev/null
+++ b/test/mjsunit/asm/infinite-loops-taken.js
@@ -0,0 +1,41 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var error = "error";
+function counter(x) {
+  return (function() { if (x-- == 0) throw error;});
+}
+
+function Module() {
+  "use asm";
+
+  function w0(f) {
+    while (1) f();
+    return 108;
+  }
+
+  function w1(f) {
+    if (1) while (1) f();
+    return 109;
+  }
+
+  function w2(f) {
+    if (1) while (1) f();
+    else while (1) f();
+    return 110;
+  }
+
+  function w3(f) {
+    if (0) while (1) f();
+    return 111;
+  }
+
+  return { w0: w0, w1: w1, w2: w2, w3: w3 };
+}
+
+var m = Module();
+assertThrows(function() { m.w0(counter(5)) }, error);
+assertThrows(function() { m.w1(counter(5)) }, error);
+assertThrows(function() { m.w2(counter(5)) }, error);
+assertEquals(111, m.w3(counter(5)));
diff --git a/test/mjsunit/asm/infinite-loops.js b/test/mjsunit/asm/infinite-loops.js
new file mode 100644
index 0000000..03f4f6b
--- /dev/null
+++ b/test/mjsunit/asm/infinite-loops.js
@@ -0,0 +1,53 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module() {
+  "use asm";
+
+  function w0(a) {
+    a = a | 0;
+    if (a) while (1);
+    return 42;
+  }
+
+  function w1(a) {
+    a = a | 0;
+    while (1) return 42;
+    return 106;
+  }
+
+  function d0(a) {
+    a = a | 0;
+    if (a) do ; while(1);
+    return 42;
+  }
+
+  function d1(a) {
+    a = a | 0;
+    do return 42; while(1);
+    return 107;
+  }
+
+  function f0(a) {
+    a = a | 0;
+    if (a) for (;;) ;
+    return 42;
+  }
+
+  function f1(a) {
+    a = a | 0;
+    for(;;) return 42;
+    return 108;
+  }
+
+  return { w0: w0, w1: w1, d0: d0, d1: d1, f0: f0, f1: f1 };
+}
+
+var m = Module();
+assertEquals(42, m.w0(0));
+assertEquals(42, m.w1(0));
+assertEquals(42, m.d0(0));
+assertEquals(42, m.d1(0));
+assertEquals(42, m.f0(0));
+assertEquals(42, m.f1(0));
diff --git a/test/mjsunit/asm/int16array-negative-offset.js b/test/mjsunit/asm/int16array-negative-offset.js
new file mode 100644
index 0000000..5d33115
--- /dev/null
+++ b/test/mjsunit/asm/int16array-negative-offset.js
@@ -0,0 +1,42 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = this;
+var buffer = new ArrayBuffer(64 * 1024);
+var foreign = {}
+
+
+var m = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM16 = new stdlib.Int16Array(heap);
+  function load(i) {
+    i = i|0;
+    i = MEM16[i >> 1]|0;
+    return i;
+  }
+  function store(i, v) {
+    i = i|0;
+    v = v|0;
+    MEM16[i >> 1] = v;
+  }
+  function load8(i) {
+    i = i|0;
+    i = MEM16[i + 8 >> 1]|0;
+    return i;
+  }
+  function store8(i, v) {
+    i = i|0;
+    v = v|0;
+    MEM16[i + 8 >> 1] = v;
+  }
+  return { load: load, store: store, load8: load8, store8: store8 };
+})(stdlib, foreign, buffer);
+
+assertEquals(0, m.load(-8));
+assertEquals(0, m.load8(-16));
+m.store(0, 42);
+assertEquals(42, m.load8(-8));
+m.store8(-8, 99);
+assertEquals(99, m.load(0));
+assertEquals(99, m.load8(-8));
diff --git a/test/mjsunit/asm/int16array-outofbounds.js b/test/mjsunit/asm/int16array-outofbounds.js
new file mode 100644
index 0000000..7982c00
--- /dev/null
+++ b/test/mjsunit/asm/int16array-outofbounds.js
@@ -0,0 +1,42 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM16 = new stdlib.Int16Array(heap);
+  function load(i) {
+    i = i|0;
+    i = MEM16[i >> 1] | 0;
+    return i;
+  }
+  function loadm1() {
+    return MEM16[-1] | 0;
+  }
+  function store(i, v) {
+    i = i|0;
+    v = v|0;
+    MEM16[i >> 1] = v;
+  }
+  function storem1(v) {
+    v = v|0;
+    MEM16[-1] = v;
+  }
+  return {load: load, loadm1: loadm1, store: store, storem1: storem1};
+}
+
+var m = Module(this, {}, new ArrayBuffer(2));
+
+m.store(-1000, 4);
+assertEquals(0, m.load(-1000));
+assertEquals(0, m.loadm1());
+m.storem1(1);
+assertEquals(0, m.loadm1());
+m.store(0, 32767);
+for (var i = 1; i < 64; ++i) {
+  m.store(i * 2 * 32 * 1024, i);
+}
+assertEquals(32767, m.load(0));
+for (var i = 1; i < 64; ++i) {
+  assertEquals(0, m.load(i * 2 * 32 * 1024));
+}
diff --git a/test/mjsunit/asm/int32-div.js b/test/mjsunit/asm/int32-div.js
new file mode 100644
index 0000000..b4d0fef
--- /dev/null
+++ b/test/mjsunit/asm/int32-div.js
@@ -0,0 +1,33 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  function f1(i) {
+    i = i|0;
+    return i / 3 | 0;
+  }
+  function f2(i) {
+    i = i|0;
+    return i / 13 | 0;
+  }
+  function f3(i) {
+    i = i|0;
+    return i / 1024 | 0;
+  }
+  function f4(i) {
+    i = i|0;
+    return i / 3733331 | 0;
+  }
+  return { f1: f1, f2: f2, f3: f3, f4: f4 };
+}
+
+var m = Module(this, {}, new ArrayBuffer(1024));
+
+for (var i = -2147483648; i < 2147483648; i += 3999777) {
+  assertEquals(i / 3 | 0, m.f1(i));
+  assertEquals(i / 13 | 0, m.f2(i));
+  assertEquals(i / 1024 | 0, m.f3(i));
+  assertEquals(i / 3733331 | 0, m.f4(i));
+}
diff --git a/test/mjsunit/asm/int32-mod.js b/test/mjsunit/asm/int32-mod.js
new file mode 100644
index 0000000..b3a7c0e
--- /dev/null
+++ b/test/mjsunit/asm/int32-mod.js
@@ -0,0 +1,33 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  function f1(i) {
+    i = i|0;
+    return i % 3;
+  }
+  function f2(i) {
+    i = i|0;
+    return i % 9;
+  }
+  function f3(i) {
+    i = i|0;
+    return i % 1024;
+  }
+  function f4(i) {
+    i = i|0;
+    return i % 3133335;
+  }
+  return { f1: f1, f2: f2, f3: f3, f4: f4 };
+}
+
+var m = Module(this, {}, new ArrayBuffer(1024));
+
+for (var i = -2147483648; i < 2147483648; i += 3999773) {
+  assertEquals(i % 3, m.f1(i));
+  assertEquals(i % 9, m.f2(i));
+  assertEquals(i % 1024, m.f3(i));
+  assertEquals(i % 3133335, m.f4(i));
+}
diff --git a/test/mjsunit/asm/int32-mul.js b/test/mjsunit/asm/int32-mul.js
new file mode 100644
index 0000000..c5af8a0
--- /dev/null
+++ b/test/mjsunit/asm/int32-mul.js
@@ -0,0 +1,33 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  function f1(i) {
+    i = i|0;
+    return i * 3 | 0;
+  }
+  function f2(i) {
+    i = i|0;
+    return i * 7 | 0;
+  }
+  function f3(i) {
+    i = i|0;
+    return i * 1024 | 0;
+  }
+  function f4(i) {
+    i = i|0;
+    return i * 3333339 | 0;
+  }
+  return { f1: f1, f2: f2, f3: f3, f4: f4 };
+}
+
+var m = Module(this, {}, new ArrayBuffer(1024));
+
+for (var i = -2147483648; i < 2147483648; i += 3999771) {
+  assertEquals(i * 3 | 0, m.f1(i));
+  assertEquals(i * 7 | 0, m.f2(i));
+  assertEquals(i * 1024 | 0, m.f3(i));
+  assertEquals(i * 3333339 | 0, m.f4(i));
+}
diff --git a/test/mjsunit/asm/int32-tmod.js b/test/mjsunit/asm/int32-tmod.js
new file mode 100644
index 0000000..0e294d3
--- /dev/null
+++ b/test/mjsunit/asm/int32-tmod.js
@@ -0,0 +1,38 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  function f0(i) {
+    i = i|0;
+    return i % 2 | 0;
+  }
+  function f1(i) {
+    i = i|0;
+    return i % 3 | 0;
+  }
+  function f2(i) {
+    i = i|0;
+    return i % 9 | 0;
+  }
+  function f3(i) {
+    i = i|0;
+    return i % 1024 | 0;
+  }
+  function f4(i) {
+    i = i|0;
+    return i % 3333339 | 0;
+  }
+  return { f0: f0, f1: f1, f2: f2, f3: f3, f4: f4 };
+}
+
+var m = Module(this, {}, new ArrayBuffer(1024));
+
+for (var i = -2147483648; i < 2147483648; i += 3999773) {
+  assertEquals(i % 2 | 0, m.f0(i));
+  assertEquals(i % 3 | 0, m.f1(i));
+  assertEquals(i % 9 | 0, m.f2(i));
+  assertEquals(i % 1024 | 0, m.f3(i));
+  assertEquals(i % 3333339 | 0, m.f4(i));
+}
diff --git a/test/mjsunit/asm/int32-udiv.js b/test/mjsunit/asm/int32-udiv.js
new file mode 100644
index 0000000..9c67d6f
--- /dev/null
+++ b/test/mjsunit/asm/int32-udiv.js
@@ -0,0 +1,33 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  function f1(i) {
+    i = i>>>0;
+    return i / 3 | 0;
+  }
+  function f2(i) {
+    i = i>>>0;
+    return i / 17 | 0;
+  }
+  function f3(i) {
+    i = i>>>0;
+    return i / 1024 | 0;
+  }
+  function f4(i) {
+    i = i>>>0;
+    return i / 3343330 | 0;
+  }
+  return { f1: f1, f2: f2, f3: f3, f4: f4 };
+}
+
+var m = Module(this, {}, new ArrayBuffer(1024));
+
+for (var i = 0; i < 4294967296; i += 3999777) {
+  assertEquals(i / 3 | 0, m.f1(i));
+  assertEquals(i / 17 | 0, m.f2(i));
+  assertEquals(i / 1024 | 0, m.f3(i));
+  assertEquals(i / 3343330 | 0, m.f4(i));
+}
diff --git a/test/mjsunit/asm/int32-umod.js b/test/mjsunit/asm/int32-umod.js
new file mode 100644
index 0000000..2268966
--- /dev/null
+++ b/test/mjsunit/asm/int32-umod.js
@@ -0,0 +1,33 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  function f1(i) {
+    i = i>>>0;
+    return i % 3;
+  }
+  function f2(i) {
+    i = i>>>0;
+    return i % 11;
+  }
+  function f3(i) {
+    i = i>>>0;
+    return i % 1024;
+  }
+  function f4(i) {
+    i = i>>>0;
+    return i % 3333337;
+  }
+  return { f1: f1, f2: f2, f3: f3, f4: f4 };
+}
+
+var m = Module(this, {}, new ArrayBuffer(1024));
+
+for (var i = 0; i < 4294967296; i += 3999777) {
+  assertEquals(i % 3, m.f1(i));
+  assertEquals(i % 11, m.f2(i));
+  assertEquals(i % 1024, m.f3(i));
+  assertEquals(i % 3333337, m.f4(i));
+}
diff --git a/test/mjsunit/asm/int32array-constant-key.js b/test/mjsunit/asm/int32array-constant-key.js
new file mode 100644
index 0000000..bb5b650
--- /dev/null
+++ b/test/mjsunit/asm/int32array-constant-key.js
@@ -0,0 +1,62 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM32 = new stdlib.Int32Array(heap);
+  function loadm4194304() {
+    return MEM32[-4194304];
+  }
+  function loadm0() {
+    return MEM32[-0];
+  }
+  function load0() {
+    return MEM32[0];
+  }
+  function load4() {
+    return MEM32[4];
+  }
+  function storem4194304(v) {
+    MEM32[-4194304] = v;
+  }
+  function storem0(v) {
+    MEM32[-0] = v;
+  }
+  function store0(v) {
+    MEM32[0] = v;
+  }
+  function store4(v) {
+    MEM32[4] = v;
+  }
+  return { loadm4194304: loadm4194304, storem4194304: storem4194304,
+           loadm0: loadm0, storem0: storem0, load0: load0, store0: store0,
+           load4: load4, store4: store4 };
+}
+
+var m = Module(this, {}, new ArrayBuffer(4));
+
+assertEquals(undefined, m.loadm4194304());
+assertEquals(0, m.loadm0());
+assertEquals(0, m.load0());
+assertEquals(undefined, m.load4());
+m.storem4194304(123456789);
+assertEquals(undefined, m.loadm4194304());
+assertEquals(0, m.loadm0());
+assertEquals(0, m.load0());
+assertEquals(undefined, m.load4());
+m.storem0(987654321);
+assertEquals(undefined, m.loadm4194304());
+assertEquals(987654321, m.loadm0());
+assertEquals(987654321, m.load0());
+assertEquals(undefined, m.load4());
+m.store0(0x12345678);
+assertEquals(undefined, m.loadm4194304());
+assertEquals(0x12345678, m.loadm0());
+assertEquals(0x12345678, m.load0());
+assertEquals(undefined, m.load4());
+m.store4(43);
+assertEquals(undefined, m.loadm4194304());
+assertEquals(0x12345678, m.loadm0());
+assertEquals(0x12345678, m.load0());
+assertEquals(undefined, m.load4());
diff --git a/test/mjsunit/asm/int32array-negative-offset.js b/test/mjsunit/asm/int32array-negative-offset.js
new file mode 100644
index 0000000..d1a8efa
--- /dev/null
+++ b/test/mjsunit/asm/int32array-negative-offset.js
@@ -0,0 +1,42 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = this;
+var buffer = new ArrayBuffer(64 * 1024);
+var foreign = {}
+
+
+var m = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM32 = new stdlib.Int32Array(heap);
+  function load(i) {
+    i = i|0;
+    i = MEM32[i >> 2]|0;
+    return i;
+  }
+  function store(i, v) {
+    i = i|0;
+    v = v|0;
+    MEM32[i >> 2] = v;
+  }
+  function load8(i) {
+    i = i|0;
+    i = MEM32[i + 8 >> 2]|0;
+    return i;
+  }
+  function store8(i, v) {
+    i = i|0;
+    v = v|0;
+    MEM32[i + 8 >> 2] = v;
+  }
+  return { load: load, store: store, load8: load8, store8: store8 };
+})(stdlib, foreign, buffer);
+
+assertEquals(0, m.load(-8));
+assertEquals(0, m.load8(-16));
+m.store(0, 42);
+assertEquals(42, m.load8(-8));
+m.store8(-8, 99);
+assertEquals(99, m.load(0));
+assertEquals(99, m.load8(-8));
diff --git a/test/mjsunit/asm/int32array-outofbounds.js b/test/mjsunit/asm/int32array-outofbounds.js
new file mode 100644
index 0000000..ba7043d
--- /dev/null
+++ b/test/mjsunit/asm/int32array-outofbounds.js
@@ -0,0 +1,30 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM32 = new stdlib.Int32Array(heap);
+  function load(i) {
+    i = i|0;
+    i = MEM32[i >> 2] | 0;
+    return i;
+  }
+  function store(i, v) {
+    i = i|0;
+    v = v|0;
+    MEM32[i >> 2] = v;
+  }
+  return { load: load, store: store };
+}
+
+var m = Module(this, {}, new ArrayBuffer(4));
+
+m.store(0, 0x12345678);
+for (var i = 1; i < 64; ++i) {
+  m.store(i * 4 * 32 * 1024, i);
+}
+assertEquals(0x12345678, m.load(0));
+for (var i = 1; i < 64; ++i) {
+  assertEquals(0, m.load(i * 4 * 32 * 1024));
+}
diff --git a/test/mjsunit/asm/int32array-unaligned.js b/test/mjsunit/asm/int32array-unaligned.js
new file mode 100644
index 0000000..698ec5e
--- /dev/null
+++ b/test/mjsunit/asm/int32array-unaligned.js
@@ -0,0 +1,43 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM32 = new stdlib.Int32Array(heap);
+  function load(i) {
+    i = i|0;
+    i = MEM32[i >> 2] | 0;
+    return i;
+  }
+  function store(i, v) {
+    i = i|0;
+    v = v|0;
+    MEM32[i >> 2] = v;
+  }
+  return { load: load, store: store };
+}
+
+var m = Module(this, {}, new ArrayBuffer(1024));
+
+m.store(0, 0x12345678);
+m.store(4, -1);
+m.store(8, -1);
+for (var i = 0; i < 4; ++i) {
+  assertEquals(0x12345678, m.load(i));
+}
+for (var i = 4; i < 12; ++i) {
+  assertEquals(-1, m.load(i));
+}
+for (var j = 4; j < 8; ++j) {
+  m.store(j, 0x11223344);
+  for (var i = 0; i < 4; ++i) {
+    assertEquals(0x12345678, m.load(i));
+  }
+  for (var i = 4; i < 8; ++i) {
+    assertEquals(0x11223344, m.load(i));
+  }
+  for (var i = 8; i < 12; ++i) {
+    assertEquals(-1, m.load(i));
+  }
+}
diff --git a/test/mjsunit/asm/int32div.js b/test/mjsunit/asm/int32div.js
new file mode 100644
index 0000000..f5d2433
--- /dev/null
+++ b/test/mjsunit/asm/int32div.js
@@ -0,0 +1,33 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = {};
+var foreign = {};
+var heap = new ArrayBuffer(64 * 1024);
+
+function Int32Div(divisor) {
+  var name = "div_";
+  if (divisor < 0) {
+    name += "minus_";
+  }
+  name += Math.abs(divisor);
+  var m = eval("function Module(stdlib, foreign, heap) {\n"
+      + " \"use asm\";\n"
+      + " function " + name + "(dividend) {\n"
+      + "  return ((dividend | 0) / " + divisor + ") | 0;\n"
+      + " }\n"
+      + " return { f: " + name + "}\n"
+      + "}; Module");
+  return m(stdlib, foreign, heap).f;
+}
+
+var divisors = [-2147483648, -32 * 1024, -1000, -16, -7, -2, -1, 0,
+                1, 3, 4, 10, 64, 100, 1024, 2147483647];
+for (var i in divisors) {
+  var divisor = divisors[i];
+  var div = Int32Div(divisor);
+  for (var dividend = -2147483648; dividend < 2147483648; dividend += 3999773) {
+    assertEquals((dividend / divisor) | 0, div(dividend));
+  }
+}
diff --git a/test/mjsunit/asm/int32mod-constant.js b/test/mjsunit/asm/int32mod-constant.js
new file mode 100644
index 0000000..fdbdc5d
--- /dev/null
+++ b/test/mjsunit/asm/int32mod-constant.js
@@ -0,0 +1,33 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = {};
+var foreign = {};
+var heap = new ArrayBuffer(64 * 1024);
+
+function Int32Mod(divisor) {
+  var name = "mod_";
+  if (divisor < 0) {
+    name += "minus_";
+  }
+  name += Math.abs(divisor);
+  var m = eval("function Module(stdlib, foreign, heap) {\n"
+      + " \"use asm\";\n"
+      + " function " + name + "(dividend) {\n"
+      + "  return ((dividend | 0) % " + divisor + ") | 0;\n"
+      + " }\n"
+      + " return { f: " + name + "}\n"
+      + "}; Module");
+  return m(stdlib, foreign, heap).f;
+}
+
+var divisors = [-2147483648, -32 * 1024, -1000, -16, -7, -2, -1, 0,
+                1, 3, 4, 10, 64, 100, 1024, 2147483647];
+for (var i in divisors) {
+  var divisor = divisors[i];
+  var mod = Int32Mod(divisor);
+  for (var dividend = -2147483648; dividend < 2147483648; dividend += 3999773) {
+    assertEquals((dividend % divisor) | 0, mod(dividend));
+  }
+}
diff --git a/test/mjsunit/asm/int32mod.js b/test/mjsunit/asm/int32mod.js
new file mode 100644
index 0000000..22fa813
--- /dev/null
+++ b/test/mjsunit/asm/int32mod.js
@@ -0,0 +1,26 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = {};
+var foreign = {};
+var heap = new ArrayBuffer(64 * 1024);
+
+var mod = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  function mod(dividend, divisor) {
+    dividend = dividend|0;
+    divisor = divisor|0;
+    return (dividend % divisor) | 0;
+  }
+  return { mod: mod };
+})(stdlib, foreign, heap).mod;
+
+var divisors = [-2147483648, -32 * 1024, -1000, -16, -7, -2, -1, 0,
+                1, 3, 4, 10, 64, 100, 1024, 2147483647];
+for (var i in divisors) {
+  var divisor = divisors[i];
+  for (var dividend = -2147483648; dividend < 2147483648; dividend += 3999773) {
+    assertEquals((dividend % divisor) | 0, mod(dividend, divisor));
+  }
+}
diff --git a/test/mjsunit/asm/int8array-negative-offset.js b/test/mjsunit/asm/int8array-negative-offset.js
new file mode 100644
index 0000000..47dbc1b
--- /dev/null
+++ b/test/mjsunit/asm/int8array-negative-offset.js
@@ -0,0 +1,42 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = this;
+var buffer = new ArrayBuffer(64 * 1024);
+var foreign = {}
+
+
+var m = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM8 = new stdlib.Int8Array(heap);
+  function load(i) {
+    i = i|0;
+    i = MEM8[i >> 0]|0;
+    return i;
+  }
+  function store(i, v) {
+    i = i|0;
+    v = v|0;
+    MEM8[i >> 0] = v;
+  }
+  function load8(i) {
+    i = i|0;
+    i = MEM8[i + 8 >> 0]|0;
+    return i;
+  }
+  function store8(i, v) {
+    i = i|0;
+    v = v|0;
+    MEM8[i + 8 >> 0] = v;
+  }
+  return { load: load, store: store, load8: load8, store8: store8 };
+})(stdlib, foreign, buffer);
+
+assertEquals(0, m.load(-8));
+assertEquals(0, m.load8(-16));
+m.store(0, 42);
+assertEquals(42, m.load8(-8));
+m.store8(-8, 99);
+assertEquals(99, m.load(0));
+assertEquals(99, m.load8(-8));
diff --git a/test/mjsunit/asm/math-abs.js b/test/mjsunit/asm/math-abs.js
new file mode 100644
index 0000000..6387749
--- /dev/null
+++ b/test/mjsunit/asm/math-abs.js
@@ -0,0 +1,84 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib) {
+  "use asm";
+
+  var abs = stdlib.Math.abs;
+
+  // f: double -> double
+  function f(a) {
+    a = +a;
+    return +abs(a);
+  }
+
+  // g: unsigned -> double
+  function g(a) {
+    a = a>>>0;
+    return +abs(a);
+  }
+
+  // h: signed -> double
+  function h(a) {
+    a = a|0;
+    return +abs(a);
+  }
+
+  return { f: f, g: g, h: h };
+}
+
+var m = Module({ Math: Math });
+var f = m.f;
+var g = m.g;
+var h = m.h;
+
+assertTrue(isNaN(f(NaN)));
+assertTrue(isNaN(f(undefined)));
+assertTrue(isNaN(f(function() {})));
+
+assertEquals("Infinity", String(1/f(0)));
+assertEquals("Infinity", String(1/f(-0)));
+assertEquals("Infinity", String(f(Infinity)));
+assertEquals("Infinity", String(f(-Infinity)));
+
+assertEquals(0,   f(0));
+assertEquals(0.1, f(0.1));
+assertEquals(0.5, f(0.5));
+assertEquals(0.1, f(-0.1));
+assertEquals(0.5, f(-0.5));
+assertEquals(1,   f(1));
+assertEquals(1.1, f(1.1));
+assertEquals(1.5, f(1.5));
+assertEquals(1,   f(-1));
+assertEquals(1.1, f(-1.1));
+assertEquals(1.5, f(-1.5));
+
+assertEquals(0,          g(0));
+assertEquals(0,          g(0.1));
+assertEquals(0,          g(0.5));
+assertEquals(0,          g(-0.1));
+assertEquals(0,          g(-0.5));
+assertEquals(1,          g(1));
+assertEquals(1,          g(1.1));
+assertEquals(1,          g(1.5));
+assertEquals(4294967295, g(-1));
+assertEquals(4294967295, g(-1.1));
+assertEquals(4294967295, g(-1.5));
+
+assertEquals(0, h(0));
+assertEquals(0, h(0.1));
+assertEquals(0, h(0.5));
+assertEquals(0, h(-0.1));
+assertEquals(0, h(-0.5));
+assertEquals(1, h(1));
+assertEquals(1, h(1.1));
+assertEquals(1, h(1.5));
+assertEquals(1, h(-1));
+assertEquals(1, h(-1.1));
+assertEquals(1, h(-1.5));
+
+assertEquals(Number.MIN_VALUE, f(Number.MIN_VALUE));
+assertEquals(Number.MIN_VALUE, f(-Number.MIN_VALUE));
+assertEquals(Number.MAX_VALUE, f(Number.MAX_VALUE));
+assertEquals(Number.MAX_VALUE, f(-Number.MAX_VALUE));
diff --git a/test/mjsunit/asm/math-ceil.js b/test/mjsunit/asm/math-ceil.js
new file mode 100644
index 0000000..edb9493
--- /dev/null
+++ b/test/mjsunit/asm/math-ceil.js
@@ -0,0 +1,38 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib) {
+  "use asm";
+
+  var ceil = stdlib.Math.ceil;
+
+  // f: double -> float
+  function f(a) {
+    a = +a;
+    return ceil(a);
+  }
+
+  return { f: f };
+}
+
+var f = Module({ Math: Math }).f;
+
+assertTrue(isNaN(f(NaN)));
+assertTrue(isNaN(f(undefined)));
+assertTrue(isNaN(f(function() {})));
+
+assertEquals(0,                   f(0));
+assertEquals(+0,                  f(+0));
+assertEquals(-0,                  f(-0));
+assertEquals(1,                   f(0.49999));
+assertEquals(1,                   f(0.6));
+assertEquals(1,                   f(0.5));
+assertEquals(-0,                  f(-0.1));
+assertEquals(-0,                  f(-0.5));
+assertEquals(-0,                  f(-0.6));
+assertEquals(-1,                  f(-1.6));
+assertEquals(-0,                  f(-0.50001));
+
+assertEquals("Infinity", String(f(Infinity)));
+assertEquals("-Infinity", String(f(-Infinity)));
diff --git a/test/mjsunit/asm/math-floor.js b/test/mjsunit/asm/math-floor.js
new file mode 100644
index 0000000..e8c3f34
--- /dev/null
+++ b/test/mjsunit/asm/math-floor.js
@@ -0,0 +1,38 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib) {
+  "use asm";
+
+  var floor = stdlib.Math.floor;
+
+  // f: double -> float
+  function f(a) {
+    a = +a;
+    return floor(a);
+  }
+
+  return { f: f };
+}
+
+var f = Module({ Math: Math }).f;
+
+assertTrue(isNaN(f(NaN)));
+assertTrue(isNaN(f(undefined)));
+assertTrue(isNaN(f(function() {})));
+
+assertEquals(0,                   f(0));
+assertEquals(+0,                  f(+0));
+assertEquals(-0,                  f(-0));
+assertEquals(0,                   f(0.49999));
+assertEquals(+0,                  f(0.6));
+assertEquals(+0,                  f(0.5));
+assertEquals(-1,                  f(-0.1));
+assertEquals(-1,                  f(-0.5));
+assertEquals(-1,                  f(-0.6));
+assertEquals(-2,                  f(-1.6));
+assertEquals(-1,                  f(-0.50001));
+
+assertEquals("Infinity", String(f(Infinity)));
+assertEquals("-Infinity", String(f(-Infinity)));
diff --git a/test/mjsunit/asm/math-fround.js b/test/mjsunit/asm/math-fround.js
new file mode 100644
index 0000000..b1d37e9
--- /dev/null
+++ b/test/mjsunit/asm/math-fround.js
@@ -0,0 +1,38 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib) {
+  "use asm";
+
+  var fround = stdlib.Math.fround;
+
+  // f: double -> float
+  function f(a) {
+    a = +a;
+    return fround(a);
+  }
+
+  return { f: f };
+}
+
+var f = Module({ Math: Math }).f;
+
+assertTrue(isNaN(f(NaN)));
+assertTrue(isNaN(f(undefined)));
+assertTrue(isNaN(f(function() {})));
+
+assertEquals("Infinity", String(1/f(0)));
+assertEquals("-Infinity", String(1/f(-0)));
+assertEquals("Infinity", String(f(Infinity)));
+assertEquals("-Infinity", String(f(-Infinity)));
+assertEquals("Infinity", String(f(1E200)));
+assertEquals("-Infinity", String(f(-1E200)));
+assertEquals("Infinity", String(1/f(1E-300)));
+assertEquals("-Infinity", String(1/f(-1E-300)));
+
+assertEquals(0,                  f(0));
+assertEquals(1,                  f(1));
+assertEquals(1.5,                f(1.5));
+assertEquals(1.3370000123977661, f(1.337));
+assertEquals(-4.300000190734863, f(-4.3));
diff --git a/test/mjsunit/asm/sign-extend.js b/test/mjsunit/asm/sign-extend.js
new file mode 100644
index 0000000..62d8d34
--- /dev/null
+++ b/test/mjsunit/asm/sign-extend.js
@@ -0,0 +1,45 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = this;
+var buffer = new ArrayBuffer(64 * 1024);
+var foreign = {}
+
+
+var sext8 = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  function sext8(i) {
+    i = i|0;
+    i = i << 24 >> 24;
+    return i|0;
+  }
+  return { sext8: sext8 };
+})(stdlib, foreign, buffer).sext8;
+
+assertEquals(-128, sext8(128));
+assertEquals(-1, sext8(-1));
+assertEquals(-1, sext8(255));
+assertEquals(0, sext8(0));
+assertEquals(0, sext8(256));
+assertEquals(42, sext8(42));
+assertEquals(127, sext8(127));
+
+
+var sext16 = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  function sext16(i) {
+    i = i|0;
+    i = i << 16 >> 16;
+    return i|0;
+  }
+  return { sext16: sext16 };
+})(stdlib, foreign, buffer).sext16;
+
+assertEquals(-32768, sext16(32768));
+assertEquals(-1, sext16(-1));
+assertEquals(-1, sext16(65535));
+assertEquals(0, sext16(0));
+assertEquals(0, sext16(65536));
+assertEquals(128, sext16(128));
+assertEquals(32767, sext16(32767));
diff --git a/test/mjsunit/asm/uint32-less-than-shift.js b/test/mjsunit/asm/uint32-less-than-shift.js
new file mode 100644
index 0000000..7384e21
--- /dev/null
+++ b/test/mjsunit/asm/uint32-less-than-shift.js
@@ -0,0 +1,61 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  'use asm';
+
+  function foo1(i1) {
+    i1 = i1 | 0;
+    var i10 = i1 >> 5;
+    if (i10 >>> 0 < 5) {
+      return 1;
+    } else {
+      return 0;
+    }
+    return 0;
+  }
+
+  function foo2(i1) {
+    i1 = i1 | 0;
+    var i10 = i1 / 32 | 0;
+    if (i10 >>> 0 < 5) {
+      return 1;
+    } else {
+      return 0;
+    }
+    return 0;
+  }
+
+  function foo3(i1) {
+    i1 = i1 | 0;
+    var i10 = (i1 + 32 | 0) / 32 | 0;
+    if (i10 >>> 0 < 5) {
+      return 1;
+    } else {
+      return 0;
+    }
+    return 0;
+  }
+  return {foo1: foo1, foo2: foo2, foo3: foo3};
+}
+
+var m = Module(this, {}, undefined);
+
+for (var i = 0; i < 4 * 32; i++) {
+  assertEquals(1, m.foo1(i));
+  assertEquals(1, m.foo2(i));
+  assertEquals(1, m.foo3(i));
+}
+
+for (var i = 4 * 32; i < 5 * 32; i++) {
+  assertEquals(1, m.foo1(i));
+  assertEquals(1, m.foo2(i));
+  assertEquals(0, m.foo3(i));
+}
+
+for (var i = 5 * 32; i < 10 * 32; i++) {
+  assertEquals(0, m.foo1(i));
+  assertEquals(0, m.foo2(i));
+  assertEquals(0, m.foo3(i));
+}
diff --git a/test/mjsunit/asm/uint32div.js b/test/mjsunit/asm/uint32div.js
new file mode 100644
index 0000000..dcbb73b
--- /dev/null
+++ b/test/mjsunit/asm/uint32div.js
@@ -0,0 +1,45 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = {};
+var foreign = {};
+var heap = new ArrayBuffer(64 * 1024);
+
+function Uint32Div(divisor) {
+  var name = "div_";
+  name += divisor;
+  var m = eval("function Module(stdlib, foreign, heap) {\n"
+      + " \"use asm\";\n"
+      + " function " + name + "(dividend) {\n"
+      + "  return ((dividend >>> 0) / " + divisor + ") >>> 0;\n"
+      + " }\n"
+      + " return { f: " + name + "}\n"
+      + "}; Module");
+  return m(stdlib, foreign, heap).f;
+}
+
+var divisors = [0, 1, 3, 4, 10, 42, 64, 100, 1024, 2147483647, 4294967295];
+for (var i in divisors) {
+  var divisor = divisors[i];
+  var div = Uint32Div(divisor);
+  for (var dividend = 0; dividend < 4294967296; dividend += 3999773) {
+    assertEquals((dividend / divisor) >>> 0, div(dividend));
+  }
+}
+
+var div = (function(stdlib, foreign, heap) {
+  "use asm";
+  function div(dividend, divisor) {
+    return (dividend >>> 0) / (divisor >>> 0) | 0;
+  }
+  return {div: div};
+})(stdlib, foreign, heap).div;
+
+for (var i in divisors) {
+  var divisor =  divisors[i];
+  for (var dividend = 0; dividend < 4294967296; dividend += 3999773) {
+    assertEquals((dividend >>> 0) / (divisor >>> 0) | 0,
+                 div(dividend, divisor));
+  }
+}
diff --git a/test/mjsunit/asm/uint32mod-constant.js b/test/mjsunit/asm/uint32mod-constant.js
new file mode 100644
index 0000000..4ba94da
--- /dev/null
+++ b/test/mjsunit/asm/uint32mod-constant.js
@@ -0,0 +1,29 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = {};
+var foreign = {};
+var heap = new ArrayBuffer(64 * 1024);
+
+function Uint32Mod(divisor) {
+  var name = "mod_";
+  name += divisor;
+  var m = eval("function Module(stdlib, foreign, heap) {\n"
+      + " \"use asm\";\n"
+      + " function " + name + "(dividend) {\n"
+      + "  return ((dividend >>> 0) % " + divisor + ") >>> 0;\n"
+      + " }\n"
+      + " return { f: " + name + "}\n"
+      + "}; Module");
+  return m(stdlib, foreign, heap).f;
+}
+
+var divisors = [0, 1, 3, 4, 10, 42, 64, 100, 1024, 2147483647, 4294967295];
+for (var i in divisors) {
+  var divisor = divisors[i];
+  var mod = Uint32Mod(divisor);
+  for (var dividend = 0; dividend < 4294967296; dividend += 3999773) {
+    assertEquals((dividend % divisor) >>> 0, mod(dividend));
+  }
+}
diff --git a/test/mjsunit/asm/uint32mod.js b/test/mjsunit/asm/uint32mod.js
new file mode 100644
index 0000000..fa40507
--- /dev/null
+++ b/test/mjsunit/asm/uint32mod.js
@@ -0,0 +1,25 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = {};
+var foreign = {};
+var heap = new ArrayBuffer(64 * 1024);
+
+var mod = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  function mod(dividend, divisor) {
+    dividend = dividend >>> 0;
+    divisor = divisor >>> 0;
+    return (dividend % divisor) >>> 0;
+  }
+  return { mod: mod };
+})(stdlib, foreign, heap).mod;
+
+var divisors = [0, 1, 3, 4, 10, 42, 64, 100, 1024, 2147483647, 4294967295];
+for (var i in divisors) {
+  var divisor = divisors[i];
+  for (var dividend = 0; dividend < 4294967296; dividend += 3999773) {
+    assertEquals((dividend % divisor) >>> 0, mod(dividend, divisor));
+  }
+}
diff --git a/test/mjsunit/asm/uint8array-outofbounds.js b/test/mjsunit/asm/uint8array-outofbounds.js
new file mode 100644
index 0000000..179efa4
--- /dev/null
+++ b/test/mjsunit/asm/uint8array-outofbounds.js
@@ -0,0 +1,30 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM8 = new stdlib.Uint8Array(heap);
+  function load(i) {
+    i = i|0;
+    i = MEM8[i] | 0;
+    return i;
+  }
+  function store(i, v) {
+    i = i|0;
+    v = v|0;
+    MEM8[i] = v;
+  }
+  return { load: load, store: store };
+}
+
+var m = Module(this, {}, new ArrayBuffer(1));
+
+m.store(0, 255);
+for (var i = 1; i < 64; ++i) {
+  m.store(i * 1 * 32 * 1024, i);
+}
+assertEquals(255, m.load(0));
+for (var i = 1; i < 64; ++i) {
+  assertEquals(0, m.load(i * 1 * 32 * 1024));
+}
diff --git a/test/mjsunit/asm/word32and.js b/test/mjsunit/asm/word32and.js
new file mode 100644
index 0000000..6c41f88
--- /dev/null
+++ b/test/mjsunit/asm/word32and.js
@@ -0,0 +1,29 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = {};
+var foreign = {};
+var heap = new ArrayBuffer(64 * 1024);
+
+function Word32And(rhs) {
+  var name = "and_0x" + Number(rhs).toString(16);
+  var m = eval("function Module(stdlib, foreign, heap) {\n"
+      + " \"use asm\";\n"
+      + " function " + name + "(lhs) {\n"
+      + "  return (lhs | 0) & 0x" + Number(rhs).toString(16) + ";\n"
+      + " }\n"
+      + " return { f: " + name + "}\n"
+      + "}; Module");
+  return m(stdlib, foreign, heap).f;
+}
+
+var masks = [0xffffffff, 0xf0f0f0f0, 0x80ffffff, 0x07f77f0f, 0xdeadbeef,
+             0x0fffff00, 0x0ff0, 0xff, 0x00];
+for (var i in masks) {
+  var rhs = masks[i];
+  var and = Word32And(rhs);
+  for (var lhs = -2147483648; lhs < 2147483648; lhs += 3999773) {
+    assertEquals(lhs & rhs, and(lhs));
+  }
+}
diff --git a/test/mjsunit/asm/word32ror.js b/test/mjsunit/asm/word32ror.js
new file mode 100644
index 0000000..9535bde
--- /dev/null
+++ b/test/mjsunit/asm/word32ror.js
@@ -0,0 +1,37 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = {};
+var foreign = {};
+var heap = new ArrayBuffer(64 * 1024);
+
+var rol = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  function rol(x, y) {
+    x = x | 0;
+    y = y | 0;
+    return (x << y) | (x >>> (32 - y));
+  }
+  return { rol: rol };
+})(stdlib, foreign, heap).rol;
+
+assertEquals(10, rol(10, 0));
+assertEquals(2, rol(1, 1));
+assertEquals(0x40000000, rol(1, 30));
+assertEquals(-0x80000000, rol(1, 31));
+
+var ror = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  function ror(x, y) {
+    x = x | 0;
+    y = y | 0;
+    return (x << (32 - y)) | (x >>> y);
+  }
+  return { ror: ror };
+})(stdlib, foreign, heap).ror;
+
+assertEquals(10, ror(10, 0));
+assertEquals(-0x80000000, ror(1, 1));
+assertEquals(0x40000000, ror(1, 2));
+assertEquals(2, ror(1, 31));
diff --git a/test/mjsunit/asm/zero-extend.js b/test/mjsunit/asm/zero-extend.js
new file mode 100644
index 0000000..a1f9da6
--- /dev/null
+++ b/test/mjsunit/asm/zero-extend.js
@@ -0,0 +1,37 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = this;
+var buffer = new ArrayBuffer(64 * 1024);
+var foreign = {}
+
+
+var zext8 = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  function zext8(i) {
+    i = i|0;
+    return i & 0xff;
+  }
+  return { zext8: zext8 };
+})(stdlib, foreign, buffer).zext8;
+
+assertEquals(0, zext8(0));
+assertEquals(0, zext8(0x100));
+assertEquals(0xff, zext8(-1));
+assertEquals(0xff, zext8(0xff));
+
+
+var zext16 = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  function zext16(i) {
+    i = i|0;
+    return i & 0xffff;
+  }
+  return { zext16: zext16 };
+})(stdlib, foreign, buffer).zext16;
+
+assertEquals(0, zext16(0));
+assertEquals(0, zext16(0x10000));
+assertEquals(0xffff, zext16(-1));
+assertEquals(0xffff, zext16(0xffff));
diff --git a/test/mjsunit/big-array-literal.js b/test/mjsunit/big-array-literal.js
index 13f91f8..401807f 100644
--- a/test/mjsunit/big-array-literal.js
+++ b/test/mjsunit/big-array-literal.js
@@ -27,6 +27,7 @@
 
 // On MacOS X 10.7.5, this test needs a stack size of at least 788 kBytes.
 // Flags: --stack-size=800
+// Flags: --turbo-deoptimization
 
 // Test that we can make large object literals that work.
 // Also test that we can attempt to make even larger object literals without
diff --git a/test/mjsunit/boolean.js b/test/mjsunit/boolean.js
index d955855..9b9edd2 100644
--- a/test/mjsunit/boolean.js
+++ b/test/mjsunit/boolean.js
@@ -72,3 +72,10 @@
 assertEquals('foo', o.p || (o.p == 0));
 assertEquals('foo', o.p || (o.p == null));
 assertEquals('foo', o.p || (o.p == o.p));
+
+// JSToBoolean(x:string)
+function f(x) { return !!("" + x); }
+assertEquals(false, f(""));
+assertEquals(true, f("narf"));
+assertEquals(true, f(12345678));
+assertEquals(true, f(undefined));
diff --git a/test/mjsunit/bugs/bug-2615.js b/test/mjsunit/bugs/bug-2615.js
deleted file mode 100644
index 51aeaf4..0000000
--- a/test/mjsunit/bugs/bug-2615.js
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * 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 = [];
-a[0xfffffffe] = 10;
-assertThrows("a.unshift(1);", RangeError);
-assertEquals(0xffffffff, a.length);
-assertEquals(10, a[0xffffffff]);
-assertEquals(undefined, a[0xfffffffe]);
-
-a = [1,2,3];
-a[0xfffffffe] = 10;
-assertThrows("a.splice(1,1,7,7,7,7,7);", RangeError);
-assertEquals([1,7,7,7,7,7,3], a.slice(0, 7));
-assertEquals(0xffffffff, a.length);
-assertEquals(10, a[0xfffffffe + 5 - 1]);
-
-a = [1];
-Object.defineProperty(a, "1", {writable:false, configurable:false, value: 100});
-assertThrows("a.unshift(4);", TypeError);
-assertEquals([1, 100, 100], a);
-var desc = Object.getOwnPropertyDescriptor(a, "1");
-assertEquals(false, desc.writable);
-assertEquals(false, desc.configurable);
-
-a = [1];
-var g = function() { return 100; };
-Object.defineProperty(a, "1", {get:g});
-assertThrows("a.unshift(0);", TypeError);
-assertEquals([1, 100, 100], a);
-desc = Object.getOwnPropertyDescriptor(a, "1");
-assertEquals(false, desc.configurable);
-assertEquals(g, desc.get);
-
-a = [1];
-var c = 0;
-var s = function(v) { c += 1; };
-Object.defineProperty(a, "1", {set:s});
-a.unshift(10);
-assertEquals([10, undefined, undefined], a);
-assertEquals(1, c);
-desc = Object.getOwnPropertyDescriptor(a, "1");
-assertEquals(false, desc.configurable);
-assertEquals(s, desc.set);
-
-a = [1];
-Object.defineProperty(a, "1", {configurable:false, value:10});
-assertThrows("a.splice(1,1);", TypeError);
-assertEquals([1, 10], a);
-desc = Object.getOwnPropertyDescriptor(a, "1");
-assertEquals(false, desc.configurable);
-
-a = [0,1,2,3,4,5,6];
-Object.defineProperty(a, "3", {configurable:false, writable:false, value:3});
-assertThrows("a.splice(1,4);", TypeError);
-assertEquals([0,5,6,3,,,,,], a);
-desc = Object.getOwnPropertyDescriptor(a, "3");
-assertEquals(false, desc.configurable);
-assertEquals(false, desc.writable);
-
-a = [0,1,2,3,4,5,6];
-Object.defineProperty(a, "5", {configurable:false, value:5});
-assertThrows("a.splice(1,4);", TypeError);
-assertEquals([0,5,6,3,4,5,,,], a);
-desc = Object.getOwnPropertyDescriptor(a, "5");
-assertEquals(false, desc.configurable);
-
-a = [1,2,3,,5];
-Object.defineProperty(a, "1", {configurable:false, writable:true, value:2});
-assertEquals(1, a.shift());
-assertEquals([2,3,,5], a);
-desc = Object.getOwnPropertyDescriptor(a, "1");
-assertEquals(false, desc.configurable);
-assertEquals(true, desc.writable);
-assertThrows("a.shift();", TypeError);
-assertEquals([3,3,,5], a);
-desc = Object.getOwnPropertyDescriptor(a, "1");
-assertEquals(false, desc.configurable);
-assertEquals(true, desc.writable);
-
-a = [1,2,3];
-Object.defineProperty(a, "2", {configurable:false, value:3});
-assertThrows("a.pop();", TypeError);
-assertEquals([1,2,3], a);
-desc = Object.getOwnPropertyDescriptor(a, "2");
-assertEquals(false, desc.configurable);
-
-a = [1,2,,,5];
-Object.defineProperty(a, "4", {writable:true, configurable:false, value:5});
-assertThrows("a.sort();", TypeError);
-assertEquals([1,2,5,,5], a);
-desc = Object.getOwnPropertyDescriptor(a, "2");
-assertEquals(true, desc.configurable);
-desc = Object.getOwnPropertyDescriptor(a, "4");
-assertEquals(false, desc.configurable);
-
-a = [1,2,3,,5,6];
-Object.defineProperty(a, "4", {value:5, writable:false});
-assertThrows("a.sort();", TypeError);
-assertEquals([1,2,3,5,5,6], a);
-desc = Object.getOwnPropertyDescriptor(a, "4");
-assertEquals(false, desc.writable);
diff --git a/test/mjsunit/compiler/deopt-inlined-from-call.js b/test/mjsunit/compiler/deopt-inlined-from-call.js
new file mode 100644
index 0000000..24d7354
--- /dev/null
+++ b/test/mjsunit/compiler/deopt-inlined-from-call.js
@@ -0,0 +1,154 @@
+// Copyright 2014 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 --noalways-opt
+
+var global = this;
+
+Array.prototype.f = function() {
+  return 0;
+};
+
+(function() {
+  var called = 0;
+
+  function g(x, y, called) {
+    return called + 1;
+  }
+
+  function f(deopt, called) {
+    return g([].f.call({}), deopt + 1, called);
+  }
+
+  called = f(0, called);
+  called = f(0, called);
+  %OptimizeFunctionOnNextCall(f);
+  called = f(0, called);
+  assertOptimized(f);
+  called = f({}, called);
+  assertUnoptimized(f);
+  assertEquals(4, called);
+})();
+
+(function() {
+  // The array built-ins are only inlined if the receiver is a
+  // HConstant, this seems to require a *unique* global identifier
+  // each time.
+  global.a1 = [1,2,3,4];
+  var obj = {value: 3};
+
+  function f(b) {
+    return [].pop.call(a1) + b.value;
+  }
+
+  assertEquals(7, f(obj));
+  assertEquals(6, f(obj));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(5, f(obj));
+  assertOptimized(f);
+  assertEquals(4, f({d: 0, value: 3}));
+  assertUnoptimized(f);
+  assertEquals(0, a1.length);
+})();
+
+
+(function() {
+  global.a2 = [1,2,3,4];
+  var obj = {value: 3};
+
+  function f(b) {
+    return [].shift.call(a2) + b.value;
+  }
+
+  assertEquals(4, f(obj));
+  assertEquals(5, f(obj));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(6, f(obj));
+  assertOptimized(f);
+  assertEquals(7, f({d: 0, value: 3}));
+  assertUnoptimized(f);
+  assertEquals(0, a2.length);
+})();
+
+(function() {
+  global.a3 = [1,2,3,4];
+  var obj = {value: 3};
+
+  function f(b) {
+    return [].push.call(a3, b.value);
+  }
+
+  assertEquals(5, f(obj));
+  assertEquals(6, f(obj));
+  %OptimizeFunctionOnNextCall(f);
+  assertEquals(7, f(obj));
+  assertOptimized(f);
+  assertEquals(8, f({d: 0, value: 3}));
+  assertUnoptimized(f);
+  assertEquals(8, a3.length);
+  assertEquals(3, a3[7]);
+})();
+
+(function() {
+  global.a4 = [1,2,3,4];
+  var obj = {value: 3};
+
+  function f(b) {
+    return [].indexOf.call(a4, b.value);
+  }
+
+  f(obj);
+  f(obj);
+  %OptimizeFunctionOnNextCall(f);
+  var index1 = f(obj);
+  assertOptimized(f);
+  var index2 = f({d: 0, value: 3});
+  assertUnoptimized(f);
+
+  assertEquals(2, index1);
+  assertEquals(index1, index2);
+})();
+
+(function() {
+  global.a5 = [1,2,3,4];
+  var obj = {value: 3};
+
+  function f(b) {
+    return [].lastIndexOf.call(a5, b.value);
+  }
+
+  f(obj);
+  f(obj);
+  %OptimizeFunctionOnNextCall(f);
+  var index1 = f(obj);
+  assertOptimized(f);
+  var index2 = f({d: 0, value: 3});
+  assertUnoptimized(f);
+
+  assertEquals(2, index1);
+  assertEquals(index1, index2);
+})();
diff --git a/test/mjsunit/compiler/division-by-constant.js b/test/mjsunit/compiler/division-by-constant.js
index 0778e95..d3f3ac3 100644
--- a/test/mjsunit/compiler/division-by-constant.js
+++ b/test/mjsunit/compiler/division-by-constant.js
@@ -101,6 +101,7 @@
 
 // -----------------------------------------------------------------------------
 
+
 function TestDivisionLike(ref, construct, values, divisor) {
   // Define the function to test.
   var OptFun = new Function("dividend", construct(divisor));
@@ -111,12 +112,14 @@
   %OptimizeFunctionOnNextCall(OptFun);
   OptFun(13);
 
-  // Check results.
-  values.forEach(function(dividend) {
+function dude(dividend) {
     // Avoid deopt caused by overflow, we do not want to test this here.
     if (dividend === -2147483648 && divisor === -1) return;
     assertEquals(ref(dividend, divisor), OptFun(dividend));
-  });
+  }
+
+  // Check results.
+  values.forEach(dude);
 }
 
 function Test(ref, construct) {
diff --git a/test/mjsunit/compiler/inlined-call-mapcheck.js b/test/mjsunit/compiler/inlined-call-mapcheck.js
new file mode 100644
index 0000000..84ec1d2
--- /dev/null
+++ b/test/mjsunit/compiler/inlined-call-mapcheck.js
@@ -0,0 +1,43 @@
+// Copyright 2014 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 --noalways-opt
+
+(function() {
+    function f(x) {
+        for (i = 0; i < 1; i++) {
+            x.call(this);
+        }
+    }
+
+    function g() {}
+
+    f(g);
+    f(g);
+    %OptimizeFunctionOnNextCall(f);
+    assertThrows(function() { f('whatever') }, TypeError);
+})();
diff --git a/test/mjsunit/compiler/inlined-call.js b/test/mjsunit/compiler/inlined-call.js
new file mode 100644
index 0000000..dfa1675
--- /dev/null
+++ b/test/mjsunit/compiler/inlined-call.js
@@ -0,0 +1,190 @@
+// Copyright 2014 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 --noalways-opt
+
+var global = this;
+
+// For the HConstant
+Array.prototype.fun = function() {
+  funRecv = this;
+  called++;
+  assertEquals(0, arguments.length);
+};
+
+Array.prototype.funStrict = function() {
+  "use strict";
+  funStrictRecv = this;
+  called++;
+  assertEquals(0, arguments.length);
+};
+
+Array.prototype.manyArgs = function() {
+  "use strict";
+  assertEquals(5, arguments.length);
+  assertEquals(0, this);
+  assertEquals(5, arguments[4]);
+  called++;
+}
+
+Array.prototype.manyArgsSloppy = function() {
+  assertEquals(global, this);
+  assertEquals(5, arguments.length);
+  assertEquals(5, arguments[4]);
+  called++;
+}
+
+var array = [];
+for (var i = 0; i < 100; ++i) {
+  array[i] = i;
+}
+
+var copy = array.slice();
+
+function unshiftsArray(num) {
+  [].unshift.call(array, num);
+}
+
+unshiftsArray(50);
+unshiftsArray(60);
+%OptimizeFunctionOnNextCall(unshiftsArray);
+unshiftsArray(80);
+unshiftsArray(50);
+unshiftsArray(60);
+
+copy.unshift(50);
+copy.unshift(60);
+copy.unshift(80);
+copy.unshift(50);
+copy.unshift(60);
+
+assertOptimized(unshiftsArray);
+assertArrayEquals(array, copy);
+
+
+var called = 0;
+var funRecv;
+
+function callNoArgs() {
+  [].fun.call();
+}
+
+callNoArgs();
+callNoArgs();
+assertEquals(this, funRecv);
+%OptimizeFunctionOnNextCall(callNoArgs);
+callNoArgs();
+assertEquals(this, funRecv);
+assertEquals(3, called);
+assertOptimized(callNoArgs);
+
+var funStrictRecv;
+called = 0;
+
+function callStrictNoArgs() {
+  [].funStrict.call();
+}
+
+callStrictNoArgs();
+callStrictNoArgs();
+assertEquals(undefined, funStrictRecv);
+%OptimizeFunctionOnNextCall(callStrictNoArgs);
+callStrictNoArgs();
+assertEquals(undefined, funStrictRecv);
+assertEquals(3, called);
+assertOptimized(callStrictNoArgs);
+
+called = 0;
+
+
+function callManyArgs() {
+  [].manyArgs.call(0, 1, 2, 3, 4, 5);
+}
+
+callManyArgs();
+callManyArgs();
+%OptimizeFunctionOnNextCall(callManyArgs);
+callManyArgs();
+assertOptimized(callManyArgs);
+assertEquals(called, 3);
+
+called = 0;
+
+
+function callManyArgsSloppy() {
+  [].manyArgsSloppy.call(null, 1, 2, 3, 4, 5);
+}
+
+callManyArgsSloppy();
+callManyArgsSloppy();
+%OptimizeFunctionOnNextCall(callManyArgsSloppy);
+callManyArgsSloppy();
+assertOptimized(callManyArgsSloppy);
+assertEquals(called, 3);
+
+var str = "hello";
+var code = str.charCodeAt(3);
+called = 0;
+function callBuiltinIndirectly() {
+  called++;
+  return "".charCodeAt.call(str, 3);
+}
+
+callBuiltinIndirectly();
+callBuiltinIndirectly();
+%OptimizeFunctionOnNextCall(callBuiltinIndirectly);
+assertEquals(code, callBuiltinIndirectly());
+assertOptimized(callBuiltinIndirectly);
+assertEquals(3, called);
+
+this.array = [1,2,3,4,5,6,7,8,9];
+var copy = this.array.slice();
+called = 0;
+
+function callInlineableBuiltinIndirectlyWhileInlined() {
+    called++;
+    return [].push.apply(array, arguments);
+}
+
+function callInlined(num) {
+  return callInlineableBuiltinIndirectlyWhileInlined(num);
+}
+
+callInlineableBuiltinIndirectlyWhileInlined(1);
+callInlineableBuiltinIndirectlyWhileInlined(2);
+%OptimizeFunctionOnNextCall(callInlineableBuiltinIndirectlyWhileInlined);
+callInlineableBuiltinIndirectlyWhileInlined(3);
+assertOptimized(callInlineableBuiltinIndirectlyWhileInlined);
+
+callInlined(1);
+callInlined(2);
+%OptimizeFunctionOnNextCall(callInlined);
+callInlined(3);
+copy.push(1, 2, 3, 1, 2, 3);
+assertOptimized(callInlined);
+assertArrayEquals(copy, this.array);
+assertEquals(6, called);
diff --git a/test/mjsunit/compiler/literals.js b/test/mjsunit/compiler/literals.js
index 8607cd9..3bda9fc 100644
--- a/test/mjsunit/compiler/literals.js
+++ b/test/mjsunit/compiler/literals.js
@@ -38,8 +38,8 @@
 // "/" comes just before "0".
 assertThrows('"\\x1/"');
 assertThrows('"\\u111/"');
-assertEquals("\\x1/", RegExp("\\x1/").source);
-assertEquals("\\u111/", RegExp("\\u111/").source);
+assertEquals("\\x1\\/", RegExp("\\x1/").source);
+assertEquals("\\u111\\/", RegExp("\\u111/").source);
 
 // ":" comes just after "9".
 assertThrows('"\\x1:"');
diff --git a/test/mjsunit/compiler/regress-3786.js b/test/mjsunit/compiler/regress-3786.js
new file mode 100644
index 0000000..d30ac0e
--- /dev/null
+++ b/test/mjsunit/compiler/regress-3786.js
@@ -0,0 +1,12 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var foo = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  var f = stdlib.Math.cos;
+  function foo() {
+    return f(48,48,48,59,32,102,111,110,116,45,119,101,105,103,104,116,58,98,111,108,100,59,102,111,110,116,45,102,97,109,105,108,121,58,65,114,105,97,108,44,32,72,101,108,118,101,116,105,99,97,44,32,115,97,110,115,45,115,101,114,105,102,44,86,101,114,100,97,110,97,34,32,99,111,108,111,114,61,34,35,70,70,48,48,48,48,34,62,70,79,82,69,88,47,80,65,82,38,35,51,48,52,59,60,119,98,114,32,47,62,84,69,32,38,35,51,48,52,59,38,35,51,53,48,59,76,69,77,76,69,82,38,35,51,48,52,59,60,47,102,111,110,116,62,60,47,115,112,97,110,62,60,47,116,100,62,10,60,47,116,114,62,60,116,114,62,10,60,116,100,32,97,108,105,103,110,61,34,108,101,102,116,34,62,60,115,112,97,110,32,105,100,61,34,97,99,95,100,101,115,99,34,62,60,102,111,110,116,32,115,116,121,108,101,61,34,102,111,110,116,45,115,105,122,101,58,49,49,112,120,59,32,99,111,108,111,114,58,35,48,48,48,48,48,48,59,32,102,111,110,116,45,102,97,109,105,108,121,58,65,114,105,97,108,44,32,72,101,108,118,101,116,105,99,97,44,32,115,97,110,115,45,115,101,114,105,102,44,86,101,114,100,97,110,97,34,62,38,112,111,117,110,100,59,47,36,32,50,32,112,105,112,44,32,89,84,76,32,49,50,32,112,105,112,44,65,108,116,38,35,51,48,53,59,110,32,51,32,99,101,110,116,46,32,83,97,98,105,116,32,83,112,114,101,97,100,45,84,38,117,117,109,108,59,114,60,119,98,114,32,47,62,107,32,66,97,110,107,97,115,38,35,51,48,53,59,32,65,86,65,78,84,65,74,73,60,47,102,111,110,116,62,60,47,115,112,97,110,62,60,47,116,100,62,10,60,47,116,114,62,60,116,114,62,10,60,116,100,32,97,108,105,103,110,61,34,108,101,102,116,34,62,60,100,105,118,32,105,100,61,34,97,99,95,117,114,108,34,62,60,102,111,110,116,32,115,116,121,108,101,61,34,102,111,110,116,45,115,105,122,101,58,49,48,112,120,59,32,99,111,108,111,114,58,35,70,70,54,54,57,57,59,32,102,111,110,116,45,102,97114,105,97);
+  }
+  return { foo: foo };
+})(this, {}).foo();
diff --git a/test/mjsunit/compiler/regress-439743.js b/test/mjsunit/compiler/regress-439743.js
new file mode 100644
index 0000000..288e2a4
--- /dev/null
+++ b/test/mjsunit/compiler/regress-439743.js
@@ -0,0 +1,17 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function module(stdlib, foreign, heap) {
+    "use asm";
+    var MEM32 = new stdlib.Int32Array(heap);
+    function foo(i) {
+      i = i|0;
+      MEM32[0] = i;
+      return MEM32[i + 4 >> 2]|0;
+    }
+    return { foo: foo };
+}
+
+var foo = module(this, {}, new ArrayBuffer(64*1024)).foo;
+assertEquals(-4, foo(-4));
diff --git a/test/mjsunit/compiler/regress-443744.js b/test/mjsunit/compiler/regress-443744.js
new file mode 100644
index 0000000..5e7f3bc
--- /dev/null
+++ b/test/mjsunit/compiler/regress-443744.js
@@ -0,0 +1,14 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var m = (function(stdlib, foreign, heap) {
+  "use asm";
+  var MEM = new stdlib.Uint8Array(heap);
+  function f(x) {
+    x = x | 0;
+    MEM[x] = 0;
+  }
+  return {f: f};
+})(this, {}, new ArrayBuffer(1));
+m.f(-926416896 * 32 * 1024);
diff --git a/test/mjsunit/compiler/regress-444508.js b/test/mjsunit/compiler/regress-444508.js
new file mode 100644
index 0000000..e7d51ae
--- /dev/null
+++ b/test/mjsunit/compiler/regress-444508.js
@@ -0,0 +1,11 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function Module(stdlib, foreign, heap) {
+  "use asm";
+  // This is not valid asm.js, but should nevertheless work.
+  var MEM = new Uint8ClampedArray(heap);
+  function foo(i) { MEM[0] = 1; }
+  return {foo: foo};
+})(this, {}, new ArrayBuffer(64 * 1024)).foo();
diff --git a/test/mjsunit/compiler/regress-444695.js b/test/mjsunit/compiler/regress-444695.js
new file mode 100644
index 0000000..168ae25
--- /dev/null
+++ b/test/mjsunit/compiler/regress-444695.js
@@ -0,0 +1,11 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var foo = (function(stdlib, foreign, heap) {
+  "use asm";
+  var MEM = new stdlib.Uint8Array(heap);
+  function foo(x) { MEM[x | 0] *= 0; }
+  return {foo: foo};
+})(this, {}, new ArrayBuffer(1)).foo;
+foo(-926416896 * 8 * 1024);
diff --git a/test/mjsunit/compiler/regress-445267.js b/test/mjsunit/compiler/regress-445267.js
new file mode 100644
index 0000000..465168b
--- /dev/null
+++ b/test/mjsunit/compiler/regress-445267.js
@@ -0,0 +1,16 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var foo = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM16 = new stdlib.Int16Array(heap);
+  function foo(i) {
+    i = i|0;
+    i = MEM16[i + 2147483650 >> 1]|0;
+    return i;
+  }
+  return { foo: foo };
+})(this, {}, new ArrayBuffer(64 * 1024)).foo;
+
+foo(0);
diff --git a/test/mjsunit/compiler/regress-445732.js b/test/mjsunit/compiler/regress-445732.js
new file mode 100644
index 0000000..199a29a
--- /dev/null
+++ b/test/mjsunit/compiler/regress-445732.js
@@ -0,0 +1,11 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --turbo-asm
+
+"use asm";
+
+%NeverOptimizeFunction(f);
+function f() { }
+f();
diff --git a/test/mjsunit/compiler/regress-445858.js b/test/mjsunit/compiler/regress-445858.js
new file mode 100644
index 0000000..b2214ea
--- /dev/null
+++ b/test/mjsunit/compiler/regress-445858.js
@@ -0,0 +1,15 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var foo = (function module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM = new stdlib.Int8Array(heap);
+  function foo(i) {
+    i = i|0;
+    i[0] = i;
+    return MEM[i + 1 >> 0]|0;
+  }
+  return { foo: foo };
+})(this, {}, new ArrayBuffer(64 * 1024)).foo;
+foo(-1);
diff --git a/test/mjsunit/compiler/regress-445859.js b/test/mjsunit/compiler/regress-445859.js
new file mode 100644
index 0000000..256af3e
--- /dev/null
+++ b/test/mjsunit/compiler/regress-445859.js
@@ -0,0 +1,11 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var foo = (function Module(global, env, buffer) {
+  "use asm";
+  var i8 = new global.Int8Array(buffer);
+  function foo() { i8[0] += 4294967295; }
+  return { foo: foo };
+})(this, {}, new ArrayBuffer(64 * 1024)).foo;
+foo();
diff --git a/test/mjsunit/compiler/regress-445876.js b/test/mjsunit/compiler/regress-445876.js
new file mode 100644
index 0000000..30e10e5
--- /dev/null
+++ b/test/mjsunit/compiler/regress-445876.js
@@ -0,0 +1,12 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function f(x) {
+  while (1) { s++; }
+  while (x) { s++; }
+}
+
+assertThrows(function () { f(1); });
diff --git a/test/mjsunit/compiler/regress-446156.js b/test/mjsunit/compiler/regress-446156.js
new file mode 100644
index 0000000..f3cd2dd
--- /dev/null
+++ b/test/mjsunit/compiler/regress-446156.js
@@ -0,0 +1,11 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function Module(stdlib, foreign, heap) {
+  "use asm";
+  // This is not valid asm.js, but should nevertheless work.
+  var MEM = new Uint8ClampedArray(heap);
+  function foo(  )  { MEM[0] ^=  1; }
+  return {foo: foo};
+})(this, {}, new ArrayBuffer(  ) ).foo();
diff --git a/test/mjsunit/compiler/regress-446778.js b/test/mjsunit/compiler/regress-446778.js
new file mode 100644
index 0000000..a7fa3fd
--- /dev/null
+++ b/test/mjsunit/compiler/regress-446778.js
@@ -0,0 +1,17 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module() {
+  "use asm";
+  function f() {
+   var i = (140737463189505);
+   do {
+    i = i + i | 0;
+    x = undefined + i | 0;
+   } while (!i);
+  }
+  return { f: f };
+}
+
+Module().f();
diff --git a/test/mjsunit/compiler/regress-bit-number-constant.js b/test/mjsunit/compiler/regress-bit-number-constant.js
new file mode 100644
index 0000000..d36fe30
--- /dev/null
+++ b/test/mjsunit/compiler/regress-bit-number-constant.js
@@ -0,0 +1,17 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var stdlib = this;
+var buffer = new ArrayBuffer(64 * 1024);
+var foreign = {}
+
+var foo = (function Module(stdlib, foreign, heap) {
+  "use asm";
+  function foo(i) {
+    return !(i ? 1 : false);
+  }
+  return {foo:foo};
+})(stdlib, foreign, buffer).foo;
+
+assertFalse(foo(1));
diff --git a/test/mjsunit/compiler/regress-int32array-outofbounds-nan.js b/test/mjsunit/compiler/regress-int32array-outofbounds-nan.js
new file mode 100644
index 0000000..2eba2a4
--- /dev/null
+++ b/test/mjsunit/compiler/regress-int32array-outofbounds-nan.js
@@ -0,0 +1,17 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, heap) {
+  "use asm";
+  var MEM32 = new stdlib.Int32Array(heap);
+  function foo(i) {
+    i = i|0;
+    return +MEM32[i >> 2];
+  }
+  return {foo: foo};
+}
+
+var foo = Module(this, {}, new ArrayBuffer(4)).foo;
+assertEquals(NaN, foo(-4));
+assertEquals(NaN, foo(4));
diff --git a/test/mjsunit/compiler/regress-ntl-effect.js b/test/mjsunit/compiler/regress-ntl-effect.js
new file mode 100644
index 0000000..708fe32
--- /dev/null
+++ b/test/mjsunit/compiler/regress-ntl-effect.js
@@ -0,0 +1,16 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function g() {
+  throw 0;
+}
+
+function f() {
+  g();
+  while (1) {}
+}
+
+assertThrows(function () { f(); });
diff --git a/test/mjsunit/compiler/regress-register-allocator.js b/test/mjsunit/compiler/regress-register-allocator.js
new file mode 100644
index 0000000..08877ee
--- /dev/null
+++ b/test/mjsunit/compiler/regress-register-allocator.js
@@ -0,0 +1,33 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function Module(stdlib, foreign, buffer) {
+  "use asm";
+  var HEAP32 = new stdlib.Int32Array(buffer);
+  function g(a) {
+    HEAP32[a] = 9982 * 100;
+    return a;
+  }
+  function f(i1) {
+    i1 = i1 | 0;
+    var i2 = HEAP32[i1 >> 2] | 0;
+    g(i1);
+    L2909: {
+      L2: {
+        if (0) {
+          if (0) break L2;
+          g(i2);
+          break L2909;
+        }
+      }
+      var r = (HEAP32[1] | 0) / 100 | 0;
+      g(r);
+      return r;
+    }
+  }
+  return {f: f};
+}
+
+var f = Module(this, {}, new ArrayBuffer(64 * 1024)).f;
+assertEquals(9982, f(1));
diff --git a/test/mjsunit/compiler/regress-register-allocator2.js b/test/mjsunit/compiler/regress-register-allocator2.js
new file mode 100644
index 0000000..06e0c49
--- /dev/null
+++ b/test/mjsunit/compiler/regress-register-allocator2.js
@@ -0,0 +1,17 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function f() {
+  var x = 0;
+  var y = 0;
+  x ^= undefined;
+  assertEquals(x /= 1);
+  assertEquals(NaN, y %= 1);
+  assertEquals(y = 1);
+  f();
+  y = -2;
+  assertEquals(x >>= 1);
+  assertEquals(0, ((y+(y+(y+((y^(x%5))+y)))+(y+y))>>y)+y);
+}
+try { f(); } catch (e) {}
diff --git a/test/mjsunit/compiler/regress-register-allocator3.js b/test/mjsunit/compiler/regress-register-allocator3.js
new file mode 100644
index 0000000..f412c57
--- /dev/null
+++ b/test/mjsunit/compiler/regress-register-allocator3.js
@@ -0,0 +1,46 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+function Module() {
+  "use asm";
+  function f() {
+   var $0 = 0, $25 = 0, $i$014$i = 0, $sum$013$i = 0, $v_0$01$i = 0, $v_1$02$i = 0, $v_10$011$i = 0, $v_11$012$i = 0, $v_2$03$i = 0, $v_3$04$i = 0, $v_4$05$i = 0, $v_5$06$i = 0, $v_6$07$i = 0, $v_7$08$i = 0, $v_8$09$i = 0, $v_9$010$i = 0;
+   $i$014$i = 0;
+   $sum$013$i = 0;
+   $v_0$01$i = 8;
+   $v_1$02$i = 9;
+   $v_10$011$i = 18;
+   $v_11$012$i = 19;
+   $v_2$03$i = 10;
+   $v_3$04$i = 11;
+   $v_4$05$i = 12;
+   $v_5$06$i = 13;
+   $v_6$07$i = 14;
+   $v_7$08$i = 15;
+   $v_8$09$i = 16;
+   $v_9$010$i = 17;
+   do {
+    $v_0$01$i = $v_3$04$i + $v_9$010$i + $v_0$01$i | 0;
+    $v_1$02$i = $v_4$05$i + $v_10$011$i + $v_1$02$i | 0;
+    $v_2$03$i = $v_5$06$i + $v_11$012$i + $v_2$03$i | 0;
+    $v_3$04$i = $v_3$04$i + $v_6$07$i + $v_0$01$i | 0;
+    $v_4$05$i = $v_4$05$i + $v_7$08$i + $v_1$02$i | 0;
+    $v_5$06$i = $v_5$06$i + $v_8$09$i + $v_2$03$i | 0;
+    $v_6$07$i = $v_6$07$i + $v_9$010$i + $v_3$04$i | 0;
+    $v_7$08$i = $v_7$08$i + $v_10$011$i + $v_4$05$i | 0;
+    $v_8$09$i = $v_8$09$i + $v_11$012$i + $v_5$06$i | 0;
+    $v_9$010$i = $v_0$01$i + $v_9$010$i + $v_6$07$i | 0;
+    $v_10$011$i = $v_1$02$i + $v_10$011$i + $v_7$08$i | 0;
+    $v_11$012$i = $v_2$03$i + $v_11$012$i + $v_8$09$i | 0;
+    $25 = $v_0$01$i + $v_1$02$i | 0;
+    $sum$013$i = $v_2$03$i + $sum$013$i + $v_5$06$i + $v_4$05$i + $v_8$09$i + $v_3$04$i + $25 + $v_7$08$i + $v_11$012$i + $v_6$07$i + $v_10$011$i + $v_9$010$i | 0;
+    $i$014$i = $i$014$i + 1 | 0;
+   } while (($i$014$i | 0) <= 0);
+   return $sum$013$i - ($v_5$06$i + $v_2$03$i + $v_4$05$i + $v_8$09$i + $25 + $v_3$04$i + $v_7$08$i + $v_11$012$i + $v_6$07$i + $v_10$011$i + $v_9$010$i);
+  }
+  return { f: f };
+}
+
+Module().f();
diff --git a/test/mjsunit/compiler/regress-uint8-deopt.js b/test/mjsunit/compiler/regress-uint8-deopt.js
new file mode 100644
index 0000000..ba2823f
--- /dev/null
+++ b/test/mjsunit/compiler/regress-uint8-deopt.js
@@ -0,0 +1,17 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --turbo-asm --turbo-deoptimization --allow-natives-syntax
+
+function Module(heap) {
+  "use asm";
+  var a = new Uint8Array(heap);
+  function f() {
+    var x = a[0] | 0;
+    %DeoptimizeFunction(f);
+    return x;
+  }
+  return f;
+}
+assertEquals(0, Module(new ArrayBuffer(1))());
diff --git a/test/mjsunit/compiler/shift-shr.js b/test/mjsunit/compiler/shift-shr.js
index a300b2a..52cd370 100644
--- a/test/mjsunit/compiler/shift-shr.js
+++ b/test/mjsunit/compiler/shift-shr.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --allow-natives-syntax --noopt-safe-uint32-operations
+// Flags: --allow-natives-syntax
 
 // Check the results of `left >>> right`. The result is always unsigned (and
 // therefore positive).
diff --git a/test/mjsunit/compiler/truncating-store.js b/test/mjsunit/compiler/truncating-store.js
new file mode 100644
index 0000000..9e3dd38
--- /dev/null
+++ b/test/mjsunit/compiler/truncating-store.js
@@ -0,0 +1,98 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+  var asm = (function Module(global, env, buffer) {
+    "use asm";
+
+    var i8 = new global.Int8Array(buffer);
+    var u8 = new global.Uint8Array(buffer);
+    var i16 = new global.Int16Array(buffer);
+    var u16 = new global.Uint16Array(buffer);
+    var i32 = new global.Int32Array(buffer);
+    var u32 = new global.Uint32Array(buffer);
+
+    var H = 0;
+
+    function store_i8() {
+      H = 4294967295;
+      i8[0 >> 0]= H;
+      return i8[0 >> 0];
+    }
+
+    function store_u8() {
+      H = 4294967295;
+      u8[0 >> 0]= H;
+      return u8[0 >> 0];
+    }
+
+    function store_i16() {
+      H = 4294967295;
+      i16[0 >> 0]= H;
+      return i16[0 >> 0];
+    }
+
+    function store_u16() {
+      H = 4294967295;
+      u16[0 >> 0]= H;
+      return u16[0 >> 0];
+    }
+
+    function store_i32() {
+      H = 4294967295;
+      i32[0 >> 0]= H;
+      return i32[0 >> 0];
+    }
+
+    function store_u32() {
+      H = 4294967295;
+      u32[0 >> 0]= H;
+      return u32[0 >> 0];
+    }
+
+    return { store_i8: store_i8,
+             store_u8: store_u8,
+             store_i16: store_i16,
+             store_u16: store_u16,
+             store_i32: store_i32,
+             store_u32: store_u32 };
+  })({
+    "Int8Array": Int8Array,
+    "Uint8Array": Uint8Array,
+    "Int16Array": Int16Array,
+    "Uint16Array": Uint16Array,
+    "Int32Array": Int32Array,
+    "Uint32Array": Uint32Array
+  }, {}, new ArrayBuffer(64 * 1024));
+
+  assertEquals(-1, asm.store_i8());
+  assertEquals(255, asm.store_u8());
+  assertEquals(-1, asm.store_i16());
+  assertEquals(65535, asm.store_u16());
+  assertEquals(-1, asm.store_i32());
+  assertEquals(4294967295, asm.store_u32());
+})();
+
+(function() {
+  var asm = (function Module(global, env, buffer) {
+    "use asm";
+
+    var i32 = new global.Int32Array(buffer);
+
+    var H = 0;
+
+    // This is not valid asm.js, but we should still generate correct code.
+    function store_i32_from_string() {
+      H = "3";
+      i32[0 >> 0]= H;
+      return i32[0 >> 0];
+    }
+
+    return { store_i32_from_string: store_i32_from_string };
+  })({
+    "Int32Array": Int32Array
+  }, {}, new ArrayBuffer(64 * 1024));
+
+  assertEquals(3, asm.store_i32_from_string());
+})();
diff --git a/test/mjsunit/debug-clearbreakpointgroup.js b/test/mjsunit/debug-clearbreakpointgroup.js
index 137dfec..3c03bda 100644
--- a/test/mjsunit/debug-clearbreakpointgroup.js
+++ b/test/mjsunit/debug-clearbreakpointgroup.js
@@ -36,13 +36,17 @@
 
 var base_request = '"seq":0,"type":"request","command":"clearbreakpointgroup"';
 var scriptId = null;
+var muteListener = false;
 
 function safeEval(code) {
   try {
+    muteListener = true;
     return eval('(' + code + ')');
   } catch (e) {
     assertEquals(void 0, e);
     return undefined;
+  } finally {
+    muteListener = false;
   }
 }
 
@@ -58,6 +62,7 @@
 }
 
 function listener(event, exec_state, event_data, data) {
+  if (muteListener) return;
   try {
     if (event == Debug.DebugEvent.Break) {
       // Get the debug command processor.
diff --git a/test/mjsunit/debug-compile-event.js b/test/mjsunit/debug-compile-event.js
index c38cd84..8623406 100644
--- a/test/mjsunit/debug-compile-event.js
+++ b/test/mjsunit/debug-compile-event.js
@@ -37,7 +37,7 @@
 var source_count = 0;  // Total number of scources compiled.
 var host_compilations = 0;  // Number of scources compiled through the API.
 var eval_compilations = 0;  // Number of scources compiled through eval.
-
+var mute_listener = false;
 
 function compileSource(source) {
   current_source = source;
@@ -45,8 +45,20 @@
   source_count++;
 }
 
+function safeEval(code) {
+  try {
+    mute_listener = true;
+    return eval('(' + code + ')');
+  } catch (e) {
+    assertEquals(void 0, e);
+    return undefined;
+  } finally {
+    mute_listener = false;
+  }
+}
 
 function listener(event, exec_state, event_data, data) {
+  if (mute_listener) return;
   try {
     if (event == Debug.DebugEvent.BeforeCompile ||
         event == Debug.DebugEvent.AfterCompile ||
@@ -81,7 +93,7 @@
       }
       // Check that script context is included into the event message.
       var json = event_data.toJSONProtocol();
-      var msg = eval('(' + json + ')');
+      var msg = safeEval(json);
       assertTrue('context' in msg.body.script);
 
       // Check that we pick script name from //# sourceURL, iff present
diff --git a/test/mjsunit/debug-evaluate-locals-optimized-double.js b/test/mjsunit/debug-evaluate-locals-optimized-double.js
index 6696ec5..84b7e20 100644
--- a/test/mjsunit/debug-evaluate-locals-optimized-double.js
+++ b/test/mjsunit/debug-evaluate-locals-optimized-double.js
@@ -89,9 +89,10 @@
           }
 
           // All frames except the bottom one have two scopes.
-          assertEquals(2, frame.scopeCount());
+          assertEquals(3, frame.scopeCount());
           assertEquals(debug.ScopeType.Local, frame.scope(0).scopeType());
-          assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
+          assertEquals(debug.ScopeType.Script, frame.scope(1).scopeType());
+          assertEquals(debug.ScopeType.Global, frame.scope(2).scopeType());
 
           Object.keys(expected_locals).forEach(function (name) {
             assertEquals(expected_locals[name],
@@ -134,8 +135,9 @@
                        frame.evaluate(arguments_sum).value());
         } else {
           // The bottom frame only have the global scope.
-          assertEquals(1, frame.scopeCount());
-          assertEquals(debug.ScopeType.Global, frame.scope(0).scopeType());
+          assertEquals(2, frame.scopeCount());
+          assertEquals(debug.ScopeType.Script, frame.scope(0).scopeType());
+          assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
         }
 
         // Check the frame function.
diff --git a/test/mjsunit/debug-evaluate-locals-optimized.js b/test/mjsunit/debug-evaluate-locals-optimized.js
index d424001..9d539fe 100644
--- a/test/mjsunit/debug-evaluate-locals-optimized.js
+++ b/test/mjsunit/debug-evaluate-locals-optimized.js
@@ -79,10 +79,11 @@
                          frame.argumentValue(j).value());
           }
 
-          // All frames except the bottom one have two scopes.
-          assertEquals(2, frame.scopeCount());
+          // All frames except the bottom one have three scopes.
+          assertEquals(3, frame.scopeCount());
           assertEquals(debug.ScopeType.Local, frame.scope(0).scopeType());
-          assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
+          assertEquals(debug.ScopeType.Script, frame.scope(1).scopeType());
+          assertEquals(debug.ScopeType.Global, frame.scope(2).scopeType());
 
           Object.keys(expected_locals).forEach(function (name) {
             assertEquals(expected_locals[name],
@@ -124,9 +125,10 @@
           assertEquals(expected_args_sum,
                        frame.evaluate(arguments_sum).value());
         } else {
-          // The bottom frame only have the global scope.
-          assertEquals(1, frame.scopeCount());
-          assertEquals(debug.ScopeType.Global, frame.scope(0).scopeType());
+          // The bottom frame only have the script scope and the global scope.
+          assertEquals(2, frame.scopeCount());
+          assertEquals(debug.ScopeType.Script, frame.scope(0).scopeType());
+          assertEquals(debug.ScopeType.Global, frame.scope(1).scopeType());
         }
 
         // Check the frame function.
diff --git a/test/mjsunit/debug-evaluate-with-context.js b/test/mjsunit/debug-evaluate-with-context.js
index 5e1c83c..fa615ad 100644
--- a/test/mjsunit/debug-evaluate-with-context.js
+++ b/test/mjsunit/debug-evaluate-with-context.js
@@ -32,6 +32,7 @@
 var evaluate_callback;
 
 function listener(event, exec_state, event_data, data) {
+  if (event !== Debug.DebugEvent.Break) return;
   try {
     var context = { what_is_capybara: "a fish" };
     var context2 = { what_is_capybara: "a fish", what_is_parrot: "a beard" };
diff --git a/test/mjsunit/debug-function-scopes.js b/test/mjsunit/debug-function-scopes.js
index b51e8b4..8992fe7 100644
--- a/test/mjsunit/debug-function-scopes.js
+++ b/test/mjsunit/debug-function-scopes.js
@@ -48,7 +48,8 @@
                   With: 2,
                   Closure: 3,
                   Catch: 4,
-                  Block: 5 };
+                  Block: 5,
+                  Script: 6};
 
 var f1 = (function F1(x) {
   function F2(y) {
@@ -68,21 +69,23 @@
 
 var mirror = Debug.MakeMirror(f1);
 
-assertEquals(5, mirror.scopeCount());
+assertEquals(6, 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);
+CheckScope(mirror.scope(4), {}, ScopeType.Script);
+CheckScope(mirror.scope(5), {}, ScopeType.Global);
 
 var f2 = function() { return 5; }
 
 var mirror = Debug.MakeMirror(f2);
 
-assertEquals(1, mirror.scopeCount());
+assertEquals(2, mirror.scopeCount());
 
-CheckScope(mirror.scope(0), {}, ScopeType.Global);
+CheckScope(mirror.scope(0), {}, ScopeType.Script);
+CheckScope(mirror.scope(1), {}, ScopeType.Global);
 
 var f3 = (function F1(invisible_parameter) {
   var invisible1 = 1;
@@ -99,11 +102,12 @@
 
 var mirror = Debug.MakeMirror(f3);
 
-assertEquals(3, mirror.scopeCount());
+assertEquals(4, mirror.scopeCount());
 
 CheckScope(mirror.scope(0), { visible2: 20 }, ScopeType.Closure);
 CheckScope(mirror.scope(1), { visible1: 10 }, ScopeType.Closure);
-CheckScope(mirror.scope(2), {}, ScopeType.Global);
+CheckScope(mirror.scope(2), {}, ScopeType.Script);
+CheckScope(mirror.scope(3), {}, ScopeType.Global);
 
 
 var f4 = (function One() {
@@ -122,11 +126,12 @@
 
 var mirror = Debug.MakeMirror(f4);
 
-assertEquals(3, mirror.scopeCount());
+assertEquals(4, 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);
+CheckScope(mirror.scope(2), {}, ScopeType.Script);
+CheckScope(mirror.scope(3), {}, ScopeType.Global);
 
 
 var f5 = (function Raz(p1, p2) {
@@ -141,11 +146,12 @@
 
 var mirror = Debug.MakeMirror(f5);
 
-assertEquals(3, mirror.scopeCount());
+assertEquals(4, 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);
+CheckScope(mirror.scope(2), {}, ScopeType.Script);
+CheckScope(mirror.scope(3), {}, ScopeType.Global);
 
 
 function CheckNoScopeVisible(f) {
diff --git a/test/mjsunit/debug-references.js b/test/mjsunit/debug-references.js
index 763e354..bb33976 100644
--- a/test/mjsunit/debug-references.js
+++ b/test/mjsunit/debug-references.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --expose-debug-as debug
+// Flags: --expose-debug-as debug --turbo-deoptimization
 // Get the Debug object exposed from the debug context global object.
 Debug = debug.Debug
 
diff --git a/test/mjsunit/debug-scopes.js b/test/mjsunit/debug-scopes.js
index 4823496..7c08120 100644
--- a/test/mjsunit/debug-scopes.js
+++ b/test/mjsunit/debug-scopes.js
@@ -130,6 +130,7 @@
     assertEquals(i, response.body.scopes[i].index);
     assertEquals(scopes[i], response.body.scopes[i].type);
     if (scopes[i] == debug.ScopeType.Local ||
+        scopes[i] == debug.ScopeType.Script ||
         scopes[i] == debug.ScopeType.Closure) {
       assertTrue(response.body.scopes[i].object.ref < 0);
     } else {
@@ -193,6 +194,7 @@
   assertEquals(scope.scopeType(), response.body.type);
   assertEquals(number, response.body.index);
   if (scope.scopeType() == debug.ScopeType.Local ||
+      scope.scopeType() == debug.ScopeType.Script ||
       scope.scopeType() == debug.ScopeType.Closure) {
     assertTrue(response.body.object.ref < 0);
   } else {
@@ -215,6 +217,7 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({}, 0, exec_state);
 };
@@ -231,6 +234,7 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1}, 0, exec_state);
 };
@@ -248,6 +252,7 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1,x:3}, 0, exec_state);
 };
@@ -266,6 +271,7 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
 };
@@ -283,6 +289,7 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({}, 0, exec_state);
 };
@@ -300,6 +307,7 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({i:5}, 0, exec_state);
 };
@@ -321,6 +329,7 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
 };
@@ -340,6 +349,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({}, 0, exec_state);
 };
@@ -362,6 +372,7 @@
   CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.With,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({}, 0, exec_state);
   CheckScopeContent({}, 1, exec_state);
@@ -382,6 +393,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1,b:2}, 0, exec_state);
 };
@@ -404,6 +416,7 @@
   CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.With,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:2,b:1}, 0, exec_state);
   CheckScopeContent({a:1,b:2}, 1, exec_state);
@@ -428,6 +441,7 @@
   CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.With,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent(with_object, 0, exec_state);
   CheckScopeContent(with_object, 1, exec_state);
@@ -443,6 +457,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.With,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent(with_object, 0, exec_state);
   CheckScopeContent(with_object, 1, exec_state);
@@ -472,6 +487,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({}, 0, exec_state);
 };
@@ -494,6 +510,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1}, 1, exec_state);
 };
@@ -519,6 +536,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1,x:3}, 1, exec_state);
 };
@@ -545,6 +563,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1,b:2,x:3,y:4}, 1, exec_state);
 };
@@ -574,6 +593,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state);
 };
@@ -602,6 +622,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1,b:2,x:3,y:4,f:function(){}}, 1, exec_state);
 };
@@ -631,6 +652,7 @@
   CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.Closure,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1}, 1, exec_state);
   CheckScopeContent({f:function(){}}, 2, exec_state);
@@ -665,6 +687,7 @@
   CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.Closure,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({}, 0, exec_state);
   CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 1, exec_state);
@@ -684,6 +707,7 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x: 2}, 0, exec_state);
 };
@@ -705,6 +729,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
 };
 closure_9();
@@ -746,6 +771,7 @@
                    debug.ScopeType.With,
                    debug.ScopeType.Closure,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({b:16}, 0, exec_state);
   CheckScopeContent({a:15}, 1, exec_state);
@@ -771,6 +797,7 @@
   CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.With,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x: 2}, 0, exec_state);
 };
@@ -794,6 +821,7 @@
                    debug.ScopeType.Local,
                    debug.ScopeType.With,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x: 3}, 0, exec_state);
   CheckScopeContent({x: 2}, 1, exec_state);
@@ -826,6 +854,7 @@
                    debug.ScopeType.Local,
                    debug.ScopeType.Closure,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
 }
 closure_in_with_3();
@@ -836,6 +865,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.With,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x: 2}, 0, exec_state);
   CheckScopeContent({x: 1}, 1, exec_state);
@@ -852,7 +882,7 @@
 // Test global scope.
 BeginTest("Global");
 listener_delegate = function(exec_state) {
-  CheckScopeChain([debug.ScopeType.Global], exec_state);
+  CheckScopeChain([debug.ScopeType.Script, debug.ScopeType.Global], exec_state);
 };
 debugger;
 EndTest();
@@ -871,6 +901,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Catch,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({e:'Exception'}, 0, exec_state);
 };
@@ -894,6 +925,7 @@
   CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.Catch,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({n:10}, 0, exec_state);
   CheckScopeContent({e:'Exception'}, 1, exec_state);
@@ -918,6 +950,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Catch,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({e:'Exception'}, 0, exec_state);
   CheckScopeContent({y:78}, 1, exec_state);
@@ -944,6 +977,7 @@
   CheckScopeChain([debug.ScopeType.With,
                    debug.ScopeType.Catch,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({n:10}, 0, exec_state);
   CheckScopeContent({e:'Exception'}, 1, exec_state);
@@ -957,6 +991,7 @@
 BeginTest("Catch block 5");
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Catch,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({e:'Exception'}, 0, exec_state);
 };
@@ -975,6 +1010,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.Catch,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x: 2}, 0, exec_state);
   CheckScopeContent({e:'Exception'}, 1, exec_state);
@@ -1005,6 +1041,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Catch,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({e:'Exception'}, 0, exec_state);
 };
diff --git a/test/mjsunit/debug-script.js b/test/mjsunit/debug-script.js
index 5ffada1..07f0e3c 100644
--- a/test/mjsunit/debug-script.js
+++ b/test/mjsunit/debug-script.js
@@ -26,6 +26,13 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Flags: --expose-debug-as debug --expose-gc --send-idle-notification
+// Flags: --allow-natives-syntax
+// Flags: --noharmony-shipping
+// Note: this test checks that that the number of scripts reported as native
+// by Debug.scripts() is the same as a number of core native scripts.
+// Native scripts that are added by --harmony-shipping are classified
+// as 'experimental', but are still returned by Debug.scripts(), so
+// we disable harmony-shipping for this test
 
 // Get the Debug object exposed from the debug context global object.
 Debug = debug.Debug;
@@ -59,7 +66,7 @@
 }
 
 // This has to be updated if the number of native scripts change.
-assertTrue(named_native_count == 26 || named_native_count == 27);
+assertEquals(%NativeScriptsCount(), named_native_count);
 // Only the 'gc' extension is loaded.
 assertEquals(1, extension_count);
 // This script and mjsunit.js has been loaded.  If using d8, d8 loads
diff --git a/test/mjsunit/debug-step-turbofan.js b/test/mjsunit/debug-step-turbofan.js
new file mode 100644
index 0000000..c8c346b
--- /dev/null
+++ b/test/mjsunit/debug-step-turbofan.js
@@ -0,0 +1,57 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --turbo-filter=g --allow-natives-syntax
+
+// Test that Debug::PrepareForBreakPoints can deal with turbofan code (g)
+// on the stack.  Without deoptimization support, we will not be able to
+// replace optimized code for g by unoptimized code with debug break slots.
+// This would cause stepping to fail (V8 issue 3660).
+
+function f(x) {
+  g(x);
+  var a = 0;              // Break 6
+  return a;               // Break 7
+}                         // Break 8
+
+function g(x) {
+  if (x) h();
+  var a = 0;              // Break 2
+  var b = 1;              // Break 3
+  return a + b;           // Break 4
+}                         // Break 5
+
+function h() {
+  debugger;               // Break 0
+}                         // Break 1
+
+Debug = debug.Debug;
+var exception = null;
+var break_count = 0;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    exec_state.prepareStep(Debug.StepAction.StepNext, 1);
+    print(exec_state.frame(0).sourceLineText());
+    var match = exec_state.frame(0).sourceLineText().match(/Break (\d)/);
+    assertNotNull(match);
+    assertEquals(break_count++, parseInt(match[1]));
+  } catch (e) {
+    print(e + e.stack);
+    exception = e;
+  }
+}
+
+f(0);
+f(0);
+%OptimizeFunctionOnNextCall(g);
+
+Debug.setListener(listener);
+
+f(1);
+
+Debug.setListener(null);  // Break 9
+assertNull(exception);
+assertEquals(10, break_count);
diff --git a/test/mjsunit/debug-step.js b/test/mjsunit/debug-step.js
index 2233e36..45f077f 100644
--- a/test/mjsunit/debug-step.js
+++ b/test/mjsunit/debug-step.js
@@ -68,7 +68,7 @@
 state = 0;
 result = -1;
 f();
-assertEquals(499, result);
+assertEquals(332, result);
 
 // Check that performing 1000 steps with a break point on the statement in the
 // for loop (line 2) will only make i 0 as a real break point breaks even when
diff --git a/test/mjsunit/debug-stepframe.js b/test/mjsunit/debug-stepframe.js
new file mode 100644
index 0000000..8f4ee4c
--- /dev/null
+++ b/test/mjsunit/debug-stepframe.js
@@ -0,0 +1,111 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+
+function f0() {
+  var v00 = 0;              // Break 1
+  var v01 = 1;
+  // Normal function call in a catch scope.
+  try {
+    throw 1;
+  } catch (e) {
+    try{
+      f1();
+    } catch (e) {
+      var v02 = 2;          // Break 13
+    }
+  }
+  var v03 = 3;
+  var v04 = 4;
+}
+
+function f1() {
+  var v10 = 0;              // Break 2
+  var v11 = 1;
+  // Getter call.
+  var v12 = o.get;
+  var v13 = 3               // Break 4
+  // Setter call.
+  o.set = 2;
+  var v14 = 4;              // Break 6
+  // Function.prototype.call.
+  f2.call();
+  var v15 = 5;              // Break 12
+  var v16 = 6;
+  // Exit function by throw.
+  throw 1;
+  var v17 = 7;
+}
+
+function get() {
+  var g0 = 0;               // Break 3
+  var g1 = 1;
+  return 3;
+}
+
+function set() {
+  var s0 = 0;               // Break 5
+  return 3;
+}
+
+function f2() {
+  var v20 = 0;              // Break 7
+  // Construct call.
+  var v21 = new c0();
+  var v22 = 2;              // Break 9
+  // Bound function.
+  b0();
+  return 2;                 // Break 11
+}
+
+function c0() {
+  this.v0 = 0;              // Break 8
+  this.v1 = 1;
+}
+
+function f3() {
+  var v30 = 0;              // Break 10
+  var v31 = 1;
+  return 3;
+}
+
+var b0 = f3.bind(o);
+
+var o = {};
+Object.defineProperty(o, "get", { get : get });
+Object.defineProperty(o, "set", { set : set });
+
+Debug = debug.Debug;
+var break_count = 0
+var exception = null;
+var step_size;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var line = exec_state.frame(0).sourceLineText();
+    print(line);
+    var match = line.match(/\/\/ Break (\d+)$/);
+    assertEquals(2, match.length);
+    assertEquals(break_count, parseInt(match[1]));
+    break_count += step_size;
+    exec_state.prepareStep(Debug.StepAction.StepFrame, step_size);
+  } catch (e) {
+    print(e + e.stack);
+    exception = e;
+  }
+}
+
+for (step_size = 1; step_size < 6; step_size++) {
+  print("step size = " + step_size);
+  break_count = 0;
+  Debug.setListener(listener);
+  debugger;                 // Break 0
+  f0();
+  Debug.setListener(null);  // Break 14
+  assertTrue(break_count > 14);
+}
+
+assertNull(exception);
diff --git a/test/mjsunit/debug-stepin-foreach.js b/test/mjsunit/debug-stepin-foreach.js
new file mode 100644
index 0000000..fa728e0
--- /dev/null
+++ b/test/mjsunit/debug-stepin-foreach.js
@@ -0,0 +1,51 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+// Tests stepping into through Array.prototype.forEach callbacks.
+
+Debug = debug.Debug
+var exception = null;
+var break_count = 0;
+var expected_breaks = -1;
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      assertTrue(exec_state.frameCount() != 0, "FAIL: Empty stack trace");
+      if (!break_count) {
+        // Count number of expected breakpoints in this source file.
+        var source_text = exec_state.frame(0).func().script().source();
+        expected_breaks = source_text.match(/\/\/\s*Break\s+\d+\./g).length;
+        print("Expected breaks: " + expected_breaks);
+      }
+      var source = exec_state.frame(0).sourceLineText();
+      print("paused at: " + source);
+      assertTrue(source.indexOf("// Break " + break_count + ".") > 0,
+                 "Unexpected pause at: " + source + "\n" +
+                 "Expected: // Break " + break_count + ".");
+      ++break_count;
+      if (break_count !== expected_breaks) {
+        exec_state.prepareStep(Debug.StepAction.StepIn, 1);
+      }
+    }
+  } catch(e) {
+    exception = e;
+    print(e, e.stack);
+  }
+};
+
+Debug.setListener(listener);
+
+debugger; // Break 0.
+[1,2].forEach(callback); // Break 1.
+
+function callback(x) {
+  return x; // Break 2. // Break 4.
+} // Break 3. // Break 5.
+
+assertNull(exception); // Break 6.
+assertEquals(expected_breaks, break_count);
+
+Debug.setListener(null);
diff --git a/test/mjsunit/debug-stepin-property-function-call.js b/test/mjsunit/debug-stepin-property-function-call.js
new file mode 100644
index 0000000..081fb24
--- /dev/null
+++ b/test/mjsunit/debug-stepin-property-function-call.js
@@ -0,0 +1,153 @@
+// Copyright 2014 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 --nocrankshaft
+// Get the Debug object exposed from the debug context global object.
+Debug = debug.Debug
+
+var exception = null;
+var state = 1;
+
+// Simple debug event handler which first time will cause 'step in' action
+// to get into g.call and than check that execution is stopped inside
+// function 'g'.
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      if (state == 1) {
+        exec_state.prepareStep(Debug.StepAction.StepIn, 3);
+        state = 2;
+      } else if (state == 2) {
+        assertTrue(event_data.sourceLineText().indexOf("Expected to step") > 0,
+          "source line: \"" + event_data.sourceLineText() + "\"");
+        state = 3;
+      }
+    }
+  } catch(e) {
+    print("Exception: " + e);
+    exception = e;
+  }
+};
+
+// Add the debug event listener.
+Debug.setListener(listener);
+
+var count = 0;
+var obj = {
+  fun: function() {
+    ++count;
+    return count; // Expected to step
+  }
+};
+obj.fun2 = obj.fun;
+
+function testCall_Dots() {
+  debugger;
+  obj.fun();
+}
+
+function testCall_Quotes() {
+  debugger;
+  obj["fun"]();
+}
+
+function testCall_Call() {
+  debugger;
+  obj.fun.call(obj);
+}
+
+function testCall_Apply() {
+  debugger;
+  obj.fun.apply(obj);
+}
+
+function testCall_Variable() {
+  var functionName = "fun";
+  debugger;
+  obj[functionName]();
+}
+
+function testCall_Fun2() {
+  debugger;
+  obj.fun2();
+}
+
+function testCall_InternStrings() {
+  var cache = { "fun": "fun" };
+  var functionName = "fu" + "n";
+  debugger;
+  obj[cache[functionName]]();
+}
+
+function testCall_ViaFunRef() {
+  var functionName = "fu" + "n";
+  var funRef = obj[functionName];
+  debugger;
+  funRef();
+}
+
+// bug 2888
+function testCall_RuntimeVariable1() {
+  var functionName = "fu" + "n";
+  debugger;
+  obj[functionName]();
+}
+
+// bug 2888
+function testCall_RuntimeVariable2() {
+  var functionName = "un".replace(/u/, "fu");
+  debugger;
+  obj[functionName]();
+}
+
+// bug 2888
+function testCall_RuntimeVariable3() {
+  var expr = "fu" + "n";
+  const functionName = expr;
+  assertEquals("fun", functionName);
+  debugger;
+  obj[functionName]();
+}
+
+var functionsCalled = 0;
+for (var n in this) {
+  if (n.substr(0, 4) != 'test' || typeof this[n] !== "function") {
+    continue;
+  }
+  state = 1;
+  print("Running " + n + "...");
+  this[n]();
+  ++functionsCalled;
+  assertNull(exception, n);
+  assertEquals(3, state, n);
+  assertEquals(functionsCalled, count, n);
+}
+
+assertEquals(11, functionsCalled);
+
+// Get rid of the debug event listener.
+Debug.setListener(null);
diff --git a/test/mjsunit/deserialize-optimize-inner.js b/test/mjsunit/deserialize-optimize-inner.js
new file mode 100644
index 0000000..72df320
--- /dev/null
+++ b/test/mjsunit/deserialize-optimize-inner.js
@@ -0,0 +1,13 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --cache=code --no-lazy --serialize-inner
+
+function f(x, y) { return x + y; }
+
+assertEquals(1, f(0, 1));
+assertEquals(5, f(2, 3));
+%OptimizeFunctionOnNextCall(f);
+assertEquals(9, f(4, 5));
+assertOptimized(f);
diff --git a/test/mjsunit/es6/array-iterator.js b/test/mjsunit/es6/array-iterator.js
index 96122cd..767991e 100644
--- a/test/mjsunit/es6/array-iterator.js
+++ b/test/mjsunit/es6/array-iterator.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --harmony-tostring
 
 
 var NONE = 0;
@@ -158,6 +158,15 @@
       Object.getOwnPropertyNames(ArrayIteratorPrototype));
   assertHasOwnProperty(ArrayIteratorPrototype, 'next', DONT_ENUM);
   assertHasOwnProperty(ArrayIteratorPrototype, Symbol.iterator, DONT_ENUM);
+
+  assertEquals("[object Array Iterator]",
+      Object.prototype.toString.call(iterator));
+  assertEquals("Array Iterator", ArrayIteratorPrototype[Symbol.toStringTag]);
+  var desc = Object.getOwnPropertyDescriptor(
+      ArrayIteratorPrototype, Symbol.toStringTag);
+  assertTrue(desc.configurable);
+  assertFalse(desc.writable);
+  assertEquals("Array Iterator", desc.value);
 }
 TestArrayIteratorPrototype();
 
diff --git a/test/mjsunit/es6/collection-iterator.js b/test/mjsunit/es6/collection-iterator.js
index 5503fe5..18b3f1a 100644
--- a/test/mjsunit/es6/collection-iterator.js
+++ b/test/mjsunit/es6/collection-iterator.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --harmony-tostring
 
 
 (function TestSetIterator() {
@@ -19,6 +19,15 @@
 
   assertEquals(new Set().values().__proto__, SetIteratorPrototype);
   assertEquals(new Set().entries().__proto__, SetIteratorPrototype);
+
+  assertEquals("[object Set Iterator]",
+      Object.prototype.toString.call(iter));
+  assertEquals("Set Iterator", SetIteratorPrototype[Symbol.toStringTag]);
+  var desc = Object.getOwnPropertyDescriptor(
+      SetIteratorPrototype, Symbol.toStringTag);
+  assertTrue(desc.configurable);
+  assertFalse(desc.writable);
+  assertEquals("Set Iterator", desc.value);
 })();
 
 
@@ -120,6 +129,15 @@
   assertEquals(new Map().values().__proto__, MapIteratorPrototype);
   assertEquals(new Map().keys().__proto__, MapIteratorPrototype);
   assertEquals(new Map().entries().__proto__, MapIteratorPrototype);
+
+  assertEquals("[object Map Iterator]",
+      Object.prototype.toString.call(iter));
+  assertEquals("Map Iterator", MapIteratorPrototype[Symbol.toStringTag]);
+  var desc = Object.getOwnPropertyDescriptor(
+      MapIteratorPrototype, Symbol.toStringTag);
+  assertTrue(desc.configurable);
+  assertFalse(desc.writable);
+  assertEquals("Map Iterator", desc.value);
 })();
 
 
diff --git a/test/mjsunit/es6/collections.js b/test/mjsunit/es6/collections.js
index 940c0b9..92cd087 100644
--- a/test/mjsunit/es6/collections.js
+++ b/test/mjsunit/es6/collections.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --expose-gc --allow-natives-syntax
+// Flags: --expose-gc --allow-natives-syntax --harmony-tostring
 
 
 function assertSize(expected, collection) {
@@ -266,7 +266,6 @@
 assertTrue(WeakMap.prototype.get instanceof Function)
 assertTrue(WeakMap.prototype.has instanceof Function)
 assertTrue(WeakMap.prototype.delete instanceof Function)
-assertTrue(WeakMap.prototype.clear instanceof Function)
 
 
 // Test some common JavaScript idioms for WeakSets
@@ -275,7 +274,6 @@
 assertTrue(WeakSet.prototype.add instanceof Function)
 assertTrue(WeakSet.prototype.has instanceof Function)
 assertTrue(WeakSet.prototype.delete instanceof Function)
-assertTrue(WeakSet.prototype.clear instanceof Function)
 
 
 // Test class of instance and prototype.
@@ -300,7 +298,7 @@
 function TestPrototype(C) {
   assertTrue(C.prototype instanceof Object);
   assertEquals({
-    value: {},
+    value: C.prototype,
     writable: false,
     enumerable: false,
     configurable: false
@@ -471,30 +469,6 @@
 })();
 
 
-// Test WeakMap clear
-(function() {
-  var k = new Object();
-  var w = new WeakMap();
-  w.set(k, 23);
-  assertTrue(w.has(k));
-  assertEquals(23, w.get(k));
-  w.clear();
-  assertFalse(w.has(k));
-  assertEquals(undefined, w.get(k));
-})();
-
-
-// Test WeakSet clear
-(function() {
-  var k = new Object();
-  var w = new WeakSet();
-  w.add(k);
-  assertTrue(w.has(k));
-  w.clear();
-  assertFalse(w.has(k));
-})();
-
-
 (function TestMinusZeroSet() {
   var s = new Set();
   s.add(-0);
@@ -691,6 +665,33 @@
   assertEquals(4950, accumulated);
 })();
 
+
+(function TestSetForEachReceiverAsObject() {
+  var set = new Set(["1", "2"]);
+
+  // Create a new object in each function call when receiver is a
+  // primitive value. See ECMA-262, Annex C.
+  var a = [];
+  set.forEach(function() { a.push(this) }, "");
+  assertTrue(a[0] !== a[1]);
+
+  // Do not create a new object otherwise.
+  a = [];
+  set.forEach(function() { a.push(this); }, {});
+  assertEquals(a[0], a[1]);
+})();
+
+
+(function TestSetForEachReceiverAsObjectInStrictMode() {
+  var set = new Set(["1", "2"]);
+
+  // In strict mode primitive values should not be coerced to an object.
+  var a = [];
+  set.forEach(function() { 'use strict'; a.push(this); }, "");
+  assertTrue(a[0] === "" && a[0] === a[1]);
+})();
+
+
 (function TestMapForEachInvalidTypes() {
   assertThrows(function() {
     Map.prototype.map.forEach.call({});
@@ -998,6 +999,36 @@
 })();
 
 
+(function TestMapForEachReceiverAsObject() {
+  var map = new Map();
+  map.set("key1", "value1");
+  map.set("key2", "value2");
+
+  // Create a new object in each function call when receiver is a
+  // primitive value. See ECMA-262, Annex C.
+  var a = [];
+  map.forEach(function() { a.push(this) }, "");
+  assertTrue(a[0] !== a[1]);
+
+  // Do not create a new object otherwise.
+  a = [];
+  map.forEach(function() { a.push(this); }, {});
+  assertEquals(a[0], a[1]);
+})();
+
+
+(function TestMapForEachReceiverAsObjectInStrictMode() {
+  var map = new Map();
+  map.set("key1", "value1");
+  map.set("key2", "value2");
+
+  // In strict mode primitive values should not be coerced to an object.
+  var a = [];
+  map.forEach(function() { 'use strict'; a.push(this); }, "");
+  assertTrue(a[0] === "" && a[0] === a[1]);
+})();
+
+
 // Allows testing iterator-based constructors easily.
 var oneAndTwo = new Map();
 var k0 = {key: 0};
@@ -1366,3 +1397,12 @@
 }
 TestMapConstructorIterableValue(Map);
 TestMapConstructorIterableValue(WeakMap);
+
+function TestCollectionToString(C) {
+  assertEquals("[object " + C.name + "]",
+      Object.prototype.toString.call(new C()));
+}
+TestCollectionToString(Map);
+TestCollectionToString(Set);
+TestCollectionToString(WeakMap);
+TestCollectionToString(WeakSet);
diff --git a/test/mjsunit/es6/debug-stepin-microtasks.js b/test/mjsunit/es6/debug-stepin-microtasks.js
new file mode 100644
index 0000000..8dbdb34
--- /dev/null
+++ b/test/mjsunit/es6/debug-stepin-microtasks.js
@@ -0,0 +1,101 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --expose-debug-as debug
+
+Debug = debug.Debug
+var exception = null;
+var break_count = 0;
+var expected_breaks = -1;
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      assertTrue(exec_state.frameCount() != 0, "FAIL: Empty stack trace");
+      if (!break_count) {
+        // Count number of expected breakpoints in this source file.
+        var source_text = exec_state.frame(0).func().script().source();
+        expected_breaks = source_text.match(/\/\/\s*Break\s+\d+\./g).length;
+        print("Expected breaks: " + expected_breaks);
+      }
+      var source = exec_state.frame(0).sourceLineText();
+      print("paused at: " + source);
+      assertTrue(source.indexOf("// Break " + break_count + ".") > 0,
+                 "Unexpected pause at: " + source + "\n" +
+                 "Expected: // Break " + break_count + ".");
+      if (source.indexOf("StepOver.") !== -1) {
+        exec_state.prepareStep(Debug.StepAction.StepNext, 1);
+      } else {
+        exec_state.prepareStep(Debug.StepAction.StepIn, 1);
+      }
+      ++break_count;
+    }
+  } catch (e) {
+    exception = e;
+    print(e, e.stack);
+  }
+};
+
+Debug.setListener(listener);
+
+Promise.resolve(42)
+  .then(promise1)
+  .then(Object) // Should skip stepping into native.
+  .then(Boolean) // Should skip stepping into native.
+  .then(promise2)
+  .catch(promise3)
+  .catch(function(e) {
+    %AbortJS("FAIL: uncaught exception " + e);
+  });
+
+function promise1() {
+  debugger; // Break 0.
+  return exception || 1; // Break 1.
+} // Break 2.
+
+function promise2() {
+  throw new Error; // Break 3.
+}
+
+function promise3() {
+  installObservers(); // Break 4. StepOver.
+  return break_count; // Break 5.
+} // Break 6.
+
+function installObservers() {
+  var dummy = {};
+  Object.observe(dummy, observer1);
+  Object.observe(dummy, Object); // Should skip stepping into native.
+  Object.observe(dummy, Boolean); // Should skip stepping into native.
+  Object.observe(dummy, observer2);
+  dummy.foo = 1;
+}
+
+function observer1() {
+  return exception || 3; // Break 7.
+} // Break 8.
+
+function observer2() {
+  Promise.resolve().then(promise4); // Break 9. StepOver.
+  return break_count + 1; // Break 10.
+} // Break 11.
+
+function promise4() {
+  finalize(); // Break 12. StepOver.
+  return 0; // Break 13.
+} // Break 14. StepOver.
+
+function finalize() {
+  var dummy = {};
+  Object.observe(dummy, function() {
+    if (expected_breaks !== break_count) {
+      %AbortJS("FAIL: expected <" + expected_breaks + "> breaks instead of <" +
+               break_count + ">");
+    }
+    if (exception !== null) {
+      %AbortJS("FAIL: exception: " + exception);
+    }
+  });
+  dummy.foo = 1;
+}
diff --git a/test/mjsunit/es6/debug-stepnext-for.js b/test/mjsunit/es6/debug-stepnext-for.js
new file mode 100644
index 0000000..98af911
--- /dev/null
+++ b/test/mjsunit/es6/debug-stepnext-for.js
@@ -0,0 +1,116 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --harmony
+
+Debug = debug.Debug;
+var break_count = 0
+var exception = null;
+var log = []
+
+var s = 0;
+var a = [1, 2, 3];
+var i = 0;
+
+function f() {
+  "use strict";
+  debugger;                      // Break a
+  var j;                         // Break b
+
+  for (var i in null) {          // Break c
+    s += a[i];
+  }
+
+  for (j in null) {              // Break d
+    s += a[j];
+  }
+
+  for (var i in a) {             // Break e
+    s += a[i];                   // Break E
+  }
+
+  for (j in a) {                 // Break f
+    s += a[j];                   // Break F
+  }
+
+  for (let i in a) {             // Break g
+    s += a[i];                   // Break G
+  }
+
+  for (var i of a) {             // Break h
+    s += i;                      // Break H
+  }
+
+  for (j of a) {                 // Break i
+    s += j;                      // Break I
+  }
+
+  for (let i of a) {             // Break j
+    s += i;                      // Break J
+  }
+
+  for (var i = 0; i < 3; i++) {  // Break k
+    s += a[i];                   // Break K
+  }
+
+  for (j = 0; j < 3; j++) {      // Break l
+    s += a[j];                   // Break L
+  }
+
+  // TODO(yangguo): add test case for for-let.
+}                                // Break y
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    var line = exec_state.frame(0).sourceLineText();
+    var col = exec_state.frame(0).sourceColumn();
+    print(line);
+    var match = line.match(/\/\/ Break (\w)$/);
+    assertEquals(2, match.length);
+    log.push(match[1] + col);
+    exec_state.prepareStep(Debug.StepAction.StepNext, 1);
+    break_count++;
+  } catch (e) {
+    exception = e;
+  }
+}
+
+Debug.setListener(listener);
+f();
+Debug.setListener(null);         // Break z
+
+print(JSON.stringify(log));
+// The let declaration differs from var in that the loop variable
+// is declared in every iteration.
+var expected = [
+  // Entry
+  "a2","b2",
+  // Empty for-in-var: var decl, get enumerable
+  "c7","c16",
+  // Empty for-in: get enumerable
+  "d12",
+  // For-in-var: var decl, get enumerable, assign, body, assign, body, ...
+  "e7","e16","e11","E4","e11","E4","e11","E4","e11",
+  // For-in: get enumerable, assign, body, assign, body, ...
+  "f12","f7","F4","f7","F4","f7","F4","f7",
+  // For-in-let: get enumerable, next, new let, body, next, new let, ...
+  "g16","g11","g7","G4","g11","g7","G4","g11","g7","G4","g11",
+  // For-of-var: var decl, next(), body, next(), body, ...
+  "h7","h16","H4","h16","H4","h16","H4","h16",
+  // For-of: next(), body, next(), body, ...
+  "i12","I4","i12","I4","i12","I4","i12",
+  // For-of-let: next(), new let, body, next(), new let, ...
+  "j16","j7","J4","j16","j7","J4","j16","j7","J4","j16",
+  // For-var: var decl, condition, body, next, condition, body, ...
+  "k7","k20","K4","k23","k20","K4","k23","k20","K4","k23","k20",
+  // For: init, condition, body, next, condition, body, ...
+  "l11","l16","L4","l19","l16","L4","l19","l16","L4","l19","l16",
+  // Exit.
+  "y0","z0",
+]
+
+assertArrayEquals(expected, log);
+assertEquals(48, s);
+assertNull(exception);
diff --git a/test/mjsunit/es6/generators-debug-scopes.js b/test/mjsunit/es6/generators-debug-scopes.js
index d55e561..126572d 100644
--- a/test/mjsunit/es6/generators-debug-scopes.js
+++ b/test/mjsunit/es6/generators-debug-scopes.js
@@ -97,6 +97,7 @@
     assertEquals(i, response.body.scopes[i].index);
     assertEquals(scopes[i], response.body.scopes[i].type);
     if (scopes[i] == debug.ScopeType.Local ||
+        scopes[i] == debug.ScopeType.Script ||
         scopes[i] == debug.ScopeType.Closure) {
       assertTrue(response.body.scopes[i].object.ref < 0);
     } else {
@@ -159,6 +160,7 @@
   assertEquals(scope.scopeType(), response.body.type);
   assertEquals(number, response.body.index);
   if (scope.scopeType() == debug.ScopeType.Local ||
+      scope.scopeType() == debug.ScopeType.Script ||
       scope.scopeType() == debug.ScopeType.Closure) {
     assertTrue(response.body.object.ref < 0);
   } else {
@@ -178,6 +180,7 @@
         [],
         function (exec_state) {
           CheckScopeChain([debug.ScopeType.Local,
+                           debug.ScopeType.Script,
                            debug.ScopeType.Global], exec_state);
           CheckScopeContent({}, 0, exec_state);
         });
@@ -188,6 +191,7 @@
         [1],
         function (exec_state) {
           CheckScopeChain([debug.ScopeType.Local,
+                           debug.ScopeType.Script,
                            debug.ScopeType.Global], exec_state);
           CheckScopeContent({a:1}, 0, exec_state);
         });
@@ -198,6 +202,7 @@
         [1],
         function (exec_state) {
           CheckScopeChain([debug.ScopeType.Local,
+                           debug.ScopeType.Script,
                            debug.ScopeType.Global], exec_state);
           CheckScopeContent({a:1,x:3}, 0, exec_state);
         });
@@ -208,6 +213,7 @@
         [1, 2],
         function (exec_state) {
           CheckScopeChain([debug.ScopeType.Local,
+                           debug.ScopeType.Script,
                            debug.ScopeType.Global], exec_state);
           CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
         });
@@ -218,6 +224,7 @@
         [],
         function (exec_state) {
           CheckScopeChain([debug.ScopeType.Local,
+                           debug.ScopeType.Script,
                            debug.ScopeType.Global], exec_state);
           CheckScopeContent({}, 0, exec_state);
         });
@@ -228,6 +235,7 @@
         [],
         function (exec_state) {
           CheckScopeChain([debug.ScopeType.Local,
+                           debug.ScopeType.Script,
                            debug.ScopeType.Global], exec_state);
           CheckScopeContent({i:5}, 0, exec_state);
         });
@@ -242,6 +250,7 @@
         [1, 2],
         function (exec_state) {
           CheckScopeChain([debug.ScopeType.Local,
+                           debug.ScopeType.Script,
                            debug.ScopeType.Global], exec_state);
           CheckScopeContent({a:1,b:2,x:3,y:4,i:5,j:6}, 0, exec_state);
         });
@@ -254,6 +263,7 @@
           CheckScopeChain([debug.ScopeType.With,
                            debug.ScopeType.With,
                            debug.ScopeType.Local,
+                           debug.ScopeType.Script,
                            debug.ScopeType.Global], exec_state);
           CheckScopeContent({}, 0, exec_state);
           CheckScopeContent({}, 1, exec_state);
@@ -267,6 +277,7 @@
         function (exec_state) {
           CheckScopeChain([debug.ScopeType.Local,
                            debug.ScopeType.Closure,
+                           debug.ScopeType.Script,
                            debug.ScopeType.Global], exec_state);
           CheckScopeContent({a:1}, 1, exec_state);
         },
@@ -305,6 +316,7 @@
                            debug.ScopeType.With,
                            debug.ScopeType.Closure,
                            debug.ScopeType.Closure,
+                           debug.ScopeType.Script,
                            debug.ScopeType.Global], exec_state);
           CheckScopeContent({b:16}, 0, exec_state);
           CheckScopeContent({a:15}, 1, exec_state);
@@ -321,6 +333,7 @@
         function (exec_state) {
           CheckScopeChain([debug.ScopeType.Catch,
                            debug.ScopeType.Local,
+                           debug.ScopeType.Script,
                            debug.ScopeType.Global], exec_state);
           CheckScopeContent({e:'Exception'}, 0, exec_state);
         });
diff --git a/test/mjsunit/es6/generators-iteration.js b/test/mjsunit/es6/generators-iteration.js
index b6fcdaa..faeb683 100644
--- a/test/mjsunit/es6/generators-iteration.js
+++ b/test/mjsunit/es6/generators-iteration.js
@@ -41,10 +41,7 @@
 }
 
 function assertThrownIteratorIsClosed(iter) {
-  // TODO(yusukesuzuki): Since status of a thrown generator is "executing",
-  // following tests are failed.
-  // https://code.google.com/p/v8/issues/detail?id=3096
-  // assertIteratorIsClosed(iter);
+  assertIteratorIsClosed(iter);
 }
 
 function TestGeneratorResultPrototype() {
diff --git a/test/mjsunit/es6/generators-mirror.js b/test/mjsunit/es6/generators-mirror.js
index 6925285..bf21f4d 100644
--- a/test/mjsunit/es6/generators-mirror.js
+++ b/test/mjsunit/es6/generators-mirror.js
@@ -24,7 +24,7 @@
   return this.refs_[handle];
 }
 
-function TestGeneratorMirror(g, test) {
+function TestGeneratorMirror(g, status, line, column, receiver) {
   // Create mirror and JSON representation.
   var mirror = debug.MakeMirror(g);
   var serializer = debug.MakeMirrorSerializer();
@@ -44,41 +44,69 @@
   assertFalse(mirror.isPrimitive());
   assertEquals('Generator', mirror.className());
 
-  assertTrue(mirror.receiver().isUndefined());
+  assertEquals(receiver, mirror.receiver().value());
   assertEquals(generator, mirror.func().value());
 
-  test(mirror);
+  assertEquals(status, mirror.status());
+
+  // Note that line numbers are 0-based, not 1-based.
+  var loc = mirror.sourceLocation();
+  if (status === 'suspended') {
+    assertTrue(!!loc);
+    assertEquals(line, loc.line);
+    assertEquals(column, loc.column);
+  } else {
+    assertEquals(undefined, loc);
+  }
+
+  TestInternalProperties(mirror, status, receiver);
 }
 
-var iter = generator(function () {
-  assertEquals('running', debug.MakeMirror(iter).status());
-})
-
-// Note that line numbers are 0-based, not 1-based.
-function assertSourceLocation(loc, line, column) {
-  assertEquals(line, loc.line);
-  assertEquals(column, loc.column);
+function TestInternalProperties(mirror, status, receiver) {
+  var properties = mirror.internalProperties();
+  assertEquals(3, properties.length);
+  assertEquals("[[GeneratorStatus]]", properties[0].name());
+  assertEquals(status, properties[0].value().value());
+  assertEquals("[[GeneratorFunction]]", properties[1].name());
+  assertEquals(generator, properties[1].value().value());
+  assertEquals("[[GeneratorReceiver]]", properties[2].name());
+  assertEquals(receiver, properties[2].value().value());
 }
 
-TestGeneratorMirror(iter, function (mirror) {
-  assertEquals('suspended', mirror.status())
-  assertSourceLocation(mirror.sourceLocation(), 7, 19);
-});
-
-iter.next();
-TestGeneratorMirror(iter, function (mirror) {
-  assertEquals('suspended', mirror.status())
-  assertSourceLocation(mirror.sourceLocation(), 9, 2);
-});
-
-iter.next();
-TestGeneratorMirror(iter, function (mirror) {
-  assertEquals('suspended', mirror.status())
-  assertSourceLocation(mirror.sourceLocation(), 11, 2);
-});
-
-iter.next();
-TestGeneratorMirror(iter, function (mirror) {
-  assertEquals('closed', mirror.status())
+var iter = generator(function() {
+  var mirror = debug.MakeMirror(iter);
+  assertEquals('running', mirror.status());
   assertEquals(undefined, mirror.sourceLocation());
+  TestInternalProperties(mirror, 'running');
 });
+
+TestGeneratorMirror(iter, 'suspended', 7, 19);
+
+iter.next();
+TestGeneratorMirror(iter, 'suspended', 9, 2);
+
+iter.next();
+TestGeneratorMirror(iter, 'suspended', 11, 2);
+
+iter.next();
+TestGeneratorMirror(iter, 'closed');
+
+// Test generator with receiver.
+var obj = {foo: 42};
+var iter2 = generator.call(obj, function() {
+  var mirror = debug.MakeMirror(iter2);
+  assertEquals('running', mirror.status());
+  assertEquals(undefined, mirror.sourceLocation());
+  TestInternalProperties(mirror, 'running', obj);
+});
+
+TestGeneratorMirror(iter2, 'suspended', 7, 19, obj);
+
+iter2.next();
+TestGeneratorMirror(iter2, 'suspended', 9, 2, obj);
+
+iter2.next();
+TestGeneratorMirror(iter2, 'suspended', 11, 2, obj);
+
+iter2.next();
+TestGeneratorMirror(iter2, 'closed', 0, 0, obj);
diff --git a/test/mjsunit/es6/generators-objects.js b/test/mjsunit/es6/generators-objects.js
index 8a052ff..8039ca8 100644
--- a/test/mjsunit/es6/generators-objects.js
+++ b/test/mjsunit/es6/generators-objects.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --harmony-scoping --allow-natives-syntax
+// Flags: --harmony-scoping --allow-natives-syntax --harmony-tostring
 
 // Test instantations of generators.
 
@@ -66,6 +66,9 @@
   assertTrue(iter instanceof g);
   assertEquals("Generator", %_ClassOf(iter));
   assertEquals("[object Generator]", String(iter));
+  assertEquals("[object Generator]", Object.prototype.toString.call(iter));
+  var gf = iter.__proto__.constructor;
+  assertEquals("[object GeneratorFunction]", Object.prototype.toString.call(gf));
   assertEquals([], Object.getOwnPropertyNames(iter));
   assertTrue(iter !== new g());
 }
diff --git a/test/mjsunit/es6/generators-states.js b/test/mjsunit/es6/generators-states.js
new file mode 100644
index 0000000..0a2173a
--- /dev/null
+++ b/test/mjsunit/es6/generators-states.js
@@ -0,0 +1,67 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Test generator states.
+
+function Foo() {}
+function Bar() {}
+
+function assertIteratorResult(value, done, result) {
+  assertEquals({ value: value, done: done}, result);
+}
+
+function assertIteratorIsClosed(iter) {
+  assertIteratorResult(undefined, true, iter.next());
+  // Next and throw on a closed iterator.
+  assertDoesNotThrow(function() { iter.next(); });
+  assertThrows(function() { iter.throw(new Bar); }, Bar);
+}
+
+var iter;
+function* nextGenerator() { yield iter.next(); }
+function* throwGenerator() { yield iter.throw(new Bar); }
+
+// Throw on a suspendedStart iterator.
+iter = nextGenerator();
+assertThrows(function() { iter.throw(new Foo) }, Foo)
+assertThrows(function() { iter.throw(new Foo) }, Foo)
+assertIteratorIsClosed(iter);
+
+// The same.
+iter = throwGenerator();
+assertThrows(function() { iter.throw(new Foo) }, Foo)
+assertThrows(function() { iter.throw(new Foo) }, Foo)
+assertIteratorIsClosed(iter);
+
+// Next on an executing iterator raises a TypeError.
+iter = nextGenerator();
+assertThrows(function() { iter.next() }, TypeError)
+assertIteratorIsClosed(iter);
+
+// Throw on an executing iterator raises a TypeError.
+iter = throwGenerator();
+assertThrows(function() { iter.next() }, TypeError)
+assertIteratorIsClosed(iter);
+
+// Next on an executing iterator doesn't change the state of the
+// generator.
+iter = (function* () {
+  try {
+    iter.next();
+    yield 1;
+  } catch (e) {
+    try {
+      // This next() should raise the same exception, because the first
+      // next() left the iter in the executing state.
+      iter.next();
+      yield 2;
+    } catch (e) {
+      yield 3;
+    }
+  }
+  yield 4;
+})();
+assertIteratorResult(3, false, iter.next());
+assertIteratorResult(4, false, iter.next());
+assertIteratorIsClosed(iter);
diff --git a/test/mjsunit/es6/json.js b/test/mjsunit/es6/json.js
new file mode 100644
index 0000000..3fad083
--- /dev/null
+++ b/test/mjsunit/es6/json.js
@@ -0,0 +1,15 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-tostring
+
+function testJSONToString() {
+  assertEquals('[object JSON]', "" + JSON);
+  assertEquals("JSON", JSON[Symbol.toStringTag]);
+  var desc = Object.getOwnPropertyDescriptor(JSON, Symbol.toStringTag);
+  assertTrue(desc.configurable);
+  assertFalse(desc.writable);
+  assertEquals("JSON", desc.value);
+}
+testJSONToString();
diff --git a/test/mjsunit/es6/math-log2-log10.js b/test/mjsunit/es6/math-log2-log10.js
index 4479894..fa3f468 100644
--- a/test/mjsunit/es6/math-log2-log10.js
+++ b/test/mjsunit/es6/math-log2-log10.js
@@ -25,6 +25,8 @@
 // (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
+
 [Math.log10, Math.log2].forEach( function(fun) {
   assertTrue(isNaN(fun(NaN)));
   assertTrue(isNaN(fun(fun)));
@@ -39,7 +41,59 @@
   assertEquals("Infinity", String(fun(Infinity)));
 });
 
-for (var i = -300; i < 300; i += 0.7) {
-  assertEqualsDelta(i, Math.log10(Math.pow(10, i)), 1E-13);
-  assertEqualsDelta(i, Math.log2(Math.pow(2, i)), 1E-13);
+for (var i = -310; i <= 308; i += 0.5) {
+  assertEquals(i, Math.log10(Math.pow(10, i)));
+  // Square roots are tested below.
+  if (i != -0.5 && i != 0.5) assertEquals(i, Math.log2(Math.pow(2, i)));
+}
+
+// Test denormals.
+assertEquals(-307.77759430519706, Math.log10(1.5 * Math.pow(2, -1023)));
+
+// Test Math.log2(2^k) for -1074 <= k <= 1023.
+var n = -1074;
+// This loop covers n from -1074 to -1043
+for (var lowbits = 1; lowbits <= 0x80000000; lowbits *= 2) {
+  var x = %_ConstructDouble(0, lowbits);
+  assertEquals(n, Math.log2(x));
+  n++;
+}
+// This loop covers n from -1042 to -1023
+for (var hibits = 1; hibits <= 0x80000; hibits *= 2) {
+  var x = %_ConstructDouble(hibits, 0);
+  assertEquals(n, Math.log2(x));
+  n++;
+}
+// The rest of the normal values of 2^n
+var x = 1;
+for (var n = -1022; n <= 1023; ++n) {
+  var x = Math.pow(2, n);
+  assertEquals(n, Math.log2(x));
+}
+
+// Test special values.
+// Expectation isn't exactly 1/2 because Math.SQRT2 isn't exactly sqrt(2).
+assertEquals(0.5000000000000001, Math.log2(Math.SQRT2));
+
+// Expectation isn't exactly -1/2 because Math.SQRT1_2 isn't exactly sqrt(1/2).
+assertEquals(-0.4999999999999999, Math.log2(Math.SQRT1_2));
+
+assertEquals(3.321928094887362, Math.log2(10));
+assertEquals(6.643856189774724, Math.log2(100));
+
+// Test relationships
+x = 1;
+for (var k = 0; k < 1000; ++k) {
+  var y = Math.abs(Math.log2(x) + Math.log2(1/x));
+  assertEqualsDelta(0, y, 1.5e-14);
+  x *= 1.1;
+}
+
+x = Math.pow(2, -100);
+for (var k = 0; k < 1000; ++k) {
+  var y = Math.log2(x);
+  var expected = Math.log(x) / Math.LN2;
+  var err = Math.abs(y - expected) / expected;
+  assertEqualsDelta(0, err, 1e-15);
+  x *= 1.1;
 }
diff --git a/test/mjsunit/es6/math.js b/test/mjsunit/es6/math.js
new file mode 100644
index 0000000..3f76f11
--- /dev/null
+++ b/test/mjsunit/es6/math.js
@@ -0,0 +1,15 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-tostring
+
+function testMathToString() {
+  assertEquals('[object Math]', "" + Math);
+  assertEquals("Math", Math[Symbol.toStringTag]);
+  var desc = Object.getOwnPropertyDescriptor(Math, Symbol.toStringTag);
+  assertTrue(desc.configurable);
+  assertFalse(desc.writable);
+  assertEquals("Math", desc.value);
+}
+testMathToString();
diff --git a/test/mjsunit/es6/mirror-collections.js b/test/mjsunit/es6/mirror-collections.js
index e10f5c1..81a98b8 100644
--- a/test/mjsunit/es6/mirror-collections.js
+++ b/test/mjsunit/es6/mirror-collections.js
@@ -51,6 +51,7 @@
 map.delete(o1);
 var mapMirror = debug.MakeMirror(map);
 testMapMirror(mapMirror);
+
 var entries = mapMirror.entries();
 assertEquals(1, entries.length);
 assertSame(o2, entries[0].key);
@@ -59,6 +60,7 @@
 map.set(o3, o2);
 map.delete(o2);
 map.set(undefined, 44);
+
 entries = mapMirror.entries();
 assertEquals(3, entries.length);
 assertSame(o1, entries[0].key);
@@ -68,6 +70,10 @@
 assertEquals(undefined, entries[2].key);
 assertEquals(44, entries[2].value);
 
+assertEquals(3, mapMirror.entries(0).length);
+assertEquals(1, mapMirror.entries(1).length);
+assertEquals(2, mapMirror.entries(2).length);
+
 // Test the mirror object for Sets
 var set = new Set();
 set.add(o1);
@@ -78,6 +84,7 @@
 testSetMirror(setMirror);
 var values = setMirror.values();
 assertEquals(2, values.length);
+assertEquals(1, setMirror.values(1).length);
 assertSame(o2, values[0]);
 assertEquals(undefined, values[1]);
 
@@ -96,6 +103,8 @@
 function testWeakMapEntries(weakMapMirror) {
   var entries = weakMapMirror.entries();
   assertEquals(2, entries.length);
+  assertEquals(2, weakMapMirror.entries(0).length);
+  assertEquals(1, weakMapMirror.entries(1).length);
   var found = 0;
   for (var i = 0; i < entries.length; i++) {
     if (Object.is(entries[i].key, o1)) {
@@ -129,6 +138,8 @@
 function testWeakSetValues(weakSetMirror) {
   var values = weakSetMirror.values();
   assertEquals(2, values.length);
+  assertEquals(2, weakSetMirror.values(0).length);
+  assertEquals(1, weakSetMirror.values(1).length);
   var found = 0;
   for (var i = 0; i < values.length; i++) {
     if (Object.is(values[i], o1)) {
diff --git a/test/mjsunit/es6/mirror-iterators.js b/test/mjsunit/es6/mirror-iterators.js
new file mode 100644
index 0000000..22ce424
--- /dev/null
+++ b/test/mjsunit/es6/mirror-iterators.js
@@ -0,0 +1,103 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+// Test the mirror object for collection iterators.
+
+function testIteratorMirror(iter, offset, expected, opt_limit) {
+  while (offset-- > 0) iter.next();
+
+  var mirror = debug.MakeMirror(iter);
+  assertTrue(mirror.isIterator());
+
+  var preview = mirror.preview(opt_limit);
+  assertArrayEquals(expected, preview);
+
+  // Check that iterator has not changed after taking preview.
+  var values = [];
+  for (var i of iter) {
+    if (opt_limit && values.length >= opt_limit) break;
+    values.push(i);
+  }
+  assertArrayEquals(expected, values);
+}
+
+function testIteratorInternalProperties(iter, offset, kind, index, has_more) {
+  while (offset-- > 0) iter.next();
+
+  var mirror = debug.MakeMirror(iter);
+  assertTrue(mirror.isIterator());
+
+  var properties = mirror.internalProperties();
+  assertEquals(3, properties.length);
+  assertEquals("[[IteratorHasMore]]", properties[0].name());
+  assertEquals(has_more, properties[0].value().value());
+  assertEquals("[[IteratorIndex]]", properties[1].name());
+  assertEquals(index, properties[1].value().value());
+  assertEquals("[[IteratorKind]]", properties[2].name());
+  assertEquals(kind, properties[2].value().value());
+}
+
+var o1 = { foo: 1 };
+var o2 = { foo: 2 };
+
+var map = new Map();
+map.set(41, 42);
+map.set(o1, o2);
+
+testIteratorMirror(map.keys(), 0, [41, o1]);
+testIteratorMirror(map.values(), 0, [42, o2]);
+testIteratorMirror(map.entries(), 0, [[41, 42], [o1, o2]]);
+
+testIteratorMirror(map.keys(), 1, [o1]);
+testIteratorMirror(map.values(), 1, [o2]);
+testIteratorMirror(map.entries(), 1, [[o1, o2]]);
+
+testIteratorMirror(map.keys(), 2, []);
+testIteratorMirror(map.values(), 2, []);
+testIteratorMirror(map.entries(), 2, []);
+
+// Test with maximum limit.
+testIteratorMirror(map.keys(), 0, [41], 1);
+testIteratorMirror(map.values(), 0, [42], 1);
+testIteratorMirror(map.entries(), 0, [[41, 42]], 1);
+
+testIteratorInternalProperties(map.keys(), 0, "keys", 0, true);
+testIteratorInternalProperties(map.values(), 1, "values", 1, true);
+testIteratorInternalProperties(map.entries(), 2, "entries", 2, false);
+testIteratorInternalProperties(map.keys(), 3, "keys", 2, false);
+
+var set = new Set();
+set.add(41);
+set.add(42);
+set.add(o1);
+set.add(o2);
+
+testIteratorMirror(set.keys(), 0, [41, 42, o1, o2]);
+testIteratorMirror(set.values(), 0, [41, 42, o1, o2]);
+testIteratorMirror(set.entries(), 0, [[41, 41], [42, 42], [o1, o1], [o2, o2]]);
+
+testIteratorMirror(set.keys(), 1, [42, o1, o2]);
+testIteratorMirror(set.values(), 1, [42, o1, o2]);
+testIteratorMirror(set.entries(), 1, [[42, 42], [o1, o1], [o2, o2]]);
+
+testIteratorMirror(set.keys(), 3, [o2]);
+testIteratorMirror(set.values(), 3, [o2]);
+testIteratorMirror(set.entries(), 3, [[o2, o2]]);
+
+testIteratorMirror(set.keys(), 5, []);
+testIteratorMirror(set.values(), 5, []);
+testIteratorMirror(set.entries(), 5, []);
+
+// Test with maximum limit.
+testIteratorMirror(set.keys(), 1, [42, o1], 2);
+testIteratorMirror(set.values(), 1, [42, o1], 2);
+testIteratorMirror(set.entries(), 1, [[42, 42], [o1, o1]], 2);
+
+testIteratorInternalProperties(set.keys(), 0, "values", 0, true);
+testIteratorInternalProperties(set.values(), 1, "values", 1, true);
+testIteratorInternalProperties(set.entries(), 2, "entries", 2, true);
+testIteratorInternalProperties(set.keys(), 3, "values", 3, true);
+testIteratorInternalProperties(set.values(), 4, "values", 4, false);
+testIteratorInternalProperties(set.entries(), 5, "entries", 4, false);
diff --git a/test/mjsunit/harmony/numeric-literals.js b/test/mjsunit/es6/numeric-literals.js
similarity index 100%
rename from test/mjsunit/harmony/numeric-literals.js
rename to test/mjsunit/es6/numeric-literals.js
diff --git a/test/mjsunit/es6/object-tostring.js b/test/mjsunit/es6/object-tostring.js
new file mode 100644
index 0000000..26dff14
--- /dev/null
+++ b/test/mjsunit/es6/object-tostring.js
@@ -0,0 +1,133 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-tostring
+
+var global = this;
+
+var funs = {
+  Object:   [ Object ],
+  Function: [ Function ],
+  Array:    [ Array ],
+  String:   [ String ],
+  Boolean:  [ Boolean ],
+  Number:   [ Number ],
+  Date:     [ Date ],
+  RegExp:   [ RegExp ],
+  Error:    [ Error, TypeError, RangeError, SyntaxError, ReferenceError,
+              EvalError, URIError ]
+}
+for (f in funs) {
+  for (i in funs[f]) {
+    assertEquals("[object " + f + "]",
+                 Object.prototype.toString.call(new funs[f][i]),
+                 funs[f][i]);
+    assertEquals("[object Function]",
+                 Object.prototype.toString.call(funs[f][i]),
+                 funs[f][i]);
+  }
+}
+
+function testToStringTag(className) {
+  // Using builtin toStringTags
+  var obj = {};
+  obj[Symbol.toStringTag] = className;
+  assertEquals("[object ~" + className + "]",
+               Object.prototype.toString.call(obj));
+
+  // Getter throws
+  obj = {};
+  Object.defineProperty(obj, Symbol.toStringTag, {
+    get: function() { throw className; }
+  });
+  assertThrows(function() {
+    Object.prototype.toString.call(obj);
+  }, className);
+
+  // Getter does not throw
+  obj = {};
+  Object.defineProperty(obj, Symbol.toStringTag, {
+    get: function() { return className; }
+  });
+  assertEquals("[object ~" + className + "]",
+               Object.prototype.toString.call(obj));
+
+  // Custom, non-builtin toStringTags
+  obj = {};
+  obj[Symbol.toStringTag] = "X" + className;
+  assertEquals("[object X" + className + "]",
+               Object.prototype.toString.call(obj));
+
+  // With getter
+  obj = {};
+  Object.defineProperty(obj, Symbol.toStringTag, {
+    get: function() { return "X" + className; }
+  });
+  assertEquals("[object X" + className + "]",
+               Object.prototype.toString.call(obj));
+
+  // Undefined toStringTag should return [object className]
+  var obj = className === "Arguments" ?
+      (function() { return arguments; })() : new global[className];
+  obj[Symbol.toStringTag] = undefined;
+  assertEquals("[object " + className + "]",
+               Object.prototype.toString.call(obj));
+
+  // With getter
+  var obj = className === "Arguments" ?
+      (function() { return arguments; })() : new global[className];
+  Object.defineProperty(obj, Symbol.toStringTag, {
+    get: function() { return undefined; }
+  });
+  assertEquals("[object " + className + "]",
+               Object.prototype.toString.call(obj));
+}
+
+[
+  "Arguments",
+  "Array",
+  "Boolean",
+  "Date",
+  "Error",
+  "Function",
+  "Number",
+  "RegExp",
+  "String"
+].forEach(testToStringTag);
+
+function testToStringTagNonString(value) {
+  var obj = {};
+  obj[Symbol.toStringTag] = value;
+  assertEquals("[object ???]", Object.prototype.toString.call(obj));
+
+  // With getter
+  obj = {};
+  Object.defineProperty(obj, Symbol.toStringTag, {
+    get: function() { return value; }
+  });
+  assertEquals("[object ???]", Object.prototype.toString.call(obj));
+}
+
+[
+  null,
+  function() {},
+  [],
+  {},
+  /regexp/,
+  42,
+  Symbol("sym"),
+  new Date(),
+  (function() { return arguments; })(),
+  true,
+  new Error("oops"),
+  new String("str")
+].forEach(testToStringTagNonString);
+
+function testObjectToStringPropertyDesc() {
+  var desc = Object.getOwnPropertyDescriptor(Object.prototype, "toString");
+  assertTrue(desc.writable);
+  assertFalse(desc.enumerable);
+  assertTrue(desc.configurable);
+}
+testObjectToStringPropertyDesc();
diff --git a/test/mjsunit/es6/promises.js b/test/mjsunit/es6/promises.js
index faf154e..04059aa 100644
--- a/test/mjsunit/es6/promises.js
+++ b/test/mjsunit/es6/promises.js
@@ -25,13 +25,21 @@
 // (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
+// Flags: --allow-natives-syntax --harmony-tostring
 
 // Make sure we don't rely on functions patchable by monkeys.
 var call = Function.prototype.call.call.bind(Function.prototype.call)
 var observe = Object.observe;
-var getOwnPropertyNames = Object.getOwnPropertyNames
-var defineProperty = Object.defineProperty
+var getOwnPropertyNames = Object.getOwnPropertyNames;
+var defineProperty = Object.defineProperty;
+
+
+(function() {
+  // Test before clearing global (fails otherwise)
+  assertEquals("[object Promise]",
+      Object.prototype.toString.call(new Promise(function() {})));
+})();
+
 
 function clear(o) {
   if (o === null || (typeof o !== 'object' && typeof o !== 'function')) return
diff --git a/test/mjsunit/es6/regress/regress-3902.js b/test/mjsunit/es6/regress/regress-3902.js
new file mode 100644
index 0000000..768a4a1
--- /dev/null
+++ b/test/mjsunit/es6/regress/regress-3902.js
@@ -0,0 +1,15 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function* g() {}
+assertTrue(Object.getOwnPropertyDescriptor(g.__proto__, "constructor").configurable);
+assertTrue(Object.getOwnPropertyDescriptor(g.prototype.__proto__, "constructor").configurable);
+
+function FakeGeneratorFunctionConstructor() {}
+Object.defineProperty(g.__proto__, "constructor", {value: FakeGeneratorFunctionConstructor});
+assertSame(g.__proto__.constructor, FakeGeneratorFunctionConstructor);
+
+function FakeGeneratorObjectConstructor() {}
+Object.defineProperty(g.prototype.__proto__, "constructor", {value: FakeGeneratorObjectConstructor});
+assertSame(g.prototype.__proto__.constructor, FakeGeneratorObjectConstructor);
diff --git a/test/mjsunit/es6/string-iterator.js b/test/mjsunit/es6/string-iterator.js
index e6bea6d..769f549 100644
--- a/test/mjsunit/es6/string-iterator.js
+++ b/test/mjsunit/es6/string-iterator.js
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Flags: --harmony-tostring
 
 function TestStringPrototypeIterator() {
   assertTrue(String.prototype.hasOwnProperty(Symbol.iterator));
@@ -59,6 +60,12 @@
   assertArrayEquals(['next'],
       Object.getOwnPropertyNames(StringIteratorPrototype));
   assertEquals('[object String Iterator]', "" + iterator);
+  assertEquals("String Iterator", StringIteratorPrototype[Symbol.toStringTag]);
+  var desc = Object.getOwnPropertyDescriptor(
+      StringIteratorPrototype, Symbol.toStringTag);
+  assertTrue(desc.configurable);
+  assertFalse(desc.writable);
+  assertEquals("String Iterator", desc.value);
 }
 TestStringIteratorPrototype();
 
diff --git a/test/mjsunit/es6/symbols.js b/test/mjsunit/es6/symbols.js
index 60737af..b9811f5 100644
--- a/test/mjsunit/es6/symbols.js
+++ b/test/mjsunit/es6/symbols.js
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --expose-gc --allow-natives-syntax
+// Flags: --expose-gc --allow-natives-syntax --harmony-tostring
 
 var symbols = []
 
@@ -501,3 +501,11 @@
   assertSame("x3", Symbol.keyFor(symbol3))
 }
 TestRegistry()
+
+
+function TestGetOwnPropertySymbolsOnPrimitives() {
+  assertEquals(Object.getOwnPropertySymbols(true), []);
+  assertEquals(Object.getOwnPropertySymbols(5000), []);
+  assertEquals(Object.getOwnPropertySymbols("OK"), []);
+}
+TestGetOwnPropertySymbolsOnPrimitives();
diff --git a/test/mjsunit/es6/unscopables.js b/test/mjsunit/es6/unscopables.js
index 36365d2..03612be 100644
--- a/test/mjsunit/es6/unscopables.js
+++ b/test/mjsunit/es6/unscopables.js
@@ -143,6 +143,13 @@
     assertEquals(2, y);
     assertEquals(3, z);
   }
+
+  object[Symbol.unscopables] = {x: 0, y: undefined};
+  with (object) {
+    assertEquals(1, x);
+    assertEquals(5, y);
+    assertEquals(3, z);
+  }
 }
 runTest(TestBasics);
 
@@ -161,6 +168,13 @@
   with (object) {
     assertEquals(1, x);
   }
+
+  object[Symbol.unscopables] = {
+    __proto__: {x: undefined}
+  };
+  with (object) {
+    assertEquals(2, x);
+  }
 }
 runTest(TestUnscopableChain);
 
@@ -222,6 +236,14 @@
     assertEquals(5, y);
     assertEquals(3, z);
   }
+
+  proto[Symbol.unscopables] = {y: true};
+  object[Symbol.unscopables] = {x: true, y: undefined};
+  with (object) {
+    assertEquals(1, x);
+    assertEquals(5, y);
+    assertEquals(3, z);
+  }
 }
 runTest(TestOnProto);
 
@@ -341,6 +363,20 @@
 TestChangeDuringWithWithPossibleOptimization4({});
 
 
+function TestChangeDuringWithWithPossibleOptimization4(object) {
+  var x = 1;
+  object.x = 2;
+  object[Symbol.unscopables] = {x: true};
+  with (object) {
+    for (var i = 0; i < 1000; i++) {
+      if (i === 500) object[Symbol.unscopables].x = undefined;
+      assertEquals(i < 500 ? 1 : 2, x);
+    }
+  }
+}
+TestChangeDuringWithWithPossibleOptimization4({});
+
+
 function TestAccessorReceiver(object, proto) {
   var x = 'local';
 
@@ -532,9 +568,11 @@
   var x = 1;
   object.x = 2;
 
+  var calls = 0;
   var unscopables = {
     get x() {
-      assertUnreachable();
+      calls++;
+      return calls === 1 ? true : undefined;
     }
   };
 
@@ -542,7 +580,9 @@
     assertEquals(2, x);
     object[Symbol.unscopables] = unscopables;
     assertEquals(1, x);
+    assertEquals(2, x);
   }
+  assertEquals(2, calls);
 }
 runTest(TestAccessorOnUnscopables);
 
@@ -659,3 +699,25 @@
   }, CustomError);
 }
 TestGetUnscopablesGetterThrows();
+
+
+function TestGetUnscopablesGetterThrows2() {
+  var object = {
+    get x() {
+      assertUnreachable();
+    }
+  };
+  function CustomError() {}
+
+  object[Symbol.unscopables] = {
+    get x() {
+      throw new CustomError();
+    }
+  };
+  assertThrows(function() {
+    with (object) {
+      x;
+    }
+  }, CustomError);
+}
+TestGetUnscopablesGetterThrows();
diff --git a/test/mjsunit/es7/regress/regress-443982.js b/test/mjsunit/es7/regress/regress-443982.js
new file mode 100644
index 0000000..5a2e9cd
--- /dev/null
+++ b/test/mjsunit/es7/regress/regress-443982.js
@@ -0,0 +1,22 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var records;
+function observer(r) {
+  records = r;
+}
+
+Object.defineProperty(Array.prototype, '0', {
+  get: function() { return 0; },
+  set: function() { throw "boom!"; }
+});
+arr = [1, 2];
+Array.observe(arr, observer);
+arr.length = 0;
+assertEquals(0, arr.length);
+
+Object.deliverChangeRecords(observer);
+assertEquals(1, records.length);
+assertEquals('splice', records[0].type);
+assertArrayEquals([1, 2], records[0].removed);
diff --git a/test/mjsunit/fast-prototype.js b/test/mjsunit/fast-prototype.js
index 9864761..c59ec94 100644
--- a/test/mjsunit/fast-prototype.js
+++ b/test/mjsunit/fast-prototype.js
@@ -114,9 +114,9 @@
   assertTrue(key == 'a');
   break;
 }
-assertFalse(%HasFastProperties(x));
+assertTrue(%HasFastProperties(x));
 x.d = 4;
-assertFalse(%HasFastProperties(x));
+assertTrue(%HasFastProperties(x));
 for (key in x) {
   assertTrue(key == 'a');
   break;
diff --git a/test/mjsunit/function-call.js b/test/mjsunit/function-call.js
index 88df353..fb91dcd 100644
--- a/test/mjsunit/function-call.js
+++ b/test/mjsunit/function-call.js
@@ -162,13 +162,10 @@
 
   var exception = false;
   try {
-    // We call all functions with no parameters, which means that essential
-    // parameters will have the undefined value.
-    // The test for whether the "this" value is null or undefined is always
-    // performed before access to the other parameters, so even if the
-    // undefined value is an invalid argument value, it mustn't change
-    // the result of the test.
-    should_throw_on_null_and_undefined[i].call(null);
+    // We need to pass a dummy object argument ({}) to these functions because
+    // of Object.prototype.isPrototypeOf's special behavior, see issue 3483
+    // for more details.
+    should_throw_on_null_and_undefined[i].call(null, {});
   } catch (e) {
     exception = true;
     checkExpectedMessage(e);
@@ -177,7 +174,7 @@
 
   exception = false;
   try {
-    should_throw_on_null_and_undefined[i].call(undefined);
+    should_throw_on_null_and_undefined[i].call(undefined, {});
   } catch (e) {
     exception = true;
     checkExpectedMessage(e);
@@ -186,7 +183,7 @@
 
   exception = false;
   try {
-    should_throw_on_null_and_undefined[i].apply(null);
+    should_throw_on_null_and_undefined[i].apply(null, [{}]);
   } catch (e) {
     exception = true;
     checkExpectedMessage(e);
@@ -195,7 +192,7 @@
 
   exception = false;
   try {
-    should_throw_on_null_and_undefined[i].apply(undefined);
+    should_throw_on_null_and_undefined[i].apply(undefined, [{}]);
   } catch (e) {
     exception = true;
     checkExpectedMessage(e);
@@ -248,7 +245,9 @@
 
 // Test that we still throw when calling with thisArg null or undefined
 // through an array mapping function.
-var array = [1,2,3,4,5];
+// We need to make sure that the elements of `array` are all object values,
+// see issue 3483 for more details.
+var array = [{}, [], new Number, new Map, new WeakSet];
 for (var j = 0; j < mapping_functions.length; j++) {
   for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) {
     exception = false;
diff --git a/test/mjsunit/function-length-accessor.js b/test/mjsunit/function-length-accessor.js
index 357ac3f..97c9f65 100644
--- a/test/mjsunit/function-length-accessor.js
+++ b/test/mjsunit/function-length-accessor.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony-scoping
+// Flags: --harmony-scoping --lazy
 
 function foo(a, b, c, d) {
   "use strict"
diff --git a/test/mjsunit/getters-on-elements.js b/test/mjsunit/getters-on-elements.js
index 3bc360f..7f2c98b 100644
--- a/test/mjsunit/getters-on-elements.js
+++ b/test/mjsunit/getters-on-elements.js
@@ -176,7 +176,7 @@
           create_func_double,
           create_func_fast];
 
-for(var c = 0; c < 3; c++) {
+for(var c = 0; c < cf.length; c++) {
   base_getter_test(cf[c]);
 }
 
diff --git a/test/mjsunit/harmony/array-concat.js b/test/mjsunit/harmony/array-concat.js
new file mode 100644
index 0000000..286aefd
--- /dev/null
+++ b/test/mjsunit/harmony/array-concat.js
@@ -0,0 +1,686 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-arrays --harmony-classes
+
+(function testArrayConcatArity() {
+  "use strict";
+  assertEquals(1, Array.prototype.concat.length);
+})();
+
+
+(function testArrayConcatNoPrototype() {
+  "use strict";
+  assertEquals(void 0, Array.prototype.concat.prototype);
+})();
+
+
+(function testArrayConcatDescriptor() {
+  "use strict";
+  var desc = Object.getOwnPropertyDescriptor(Array.prototype, 'concat');
+  assertEquals(false, desc.enumerable);
+})();
+
+
+(function testConcatArrayLike() {
+  "use strict";
+  var obj = {
+    "length": 6,
+    "1": "A",
+    "3": "B",
+    "5": "C"
+  };
+  obj[Symbol.isConcatSpreadable] = true;
+  var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
+  var arr = ["X", "Y", "Z"];
+  assertEquals([void 0, "A", void 0, "B", void 0, "C",
+               { "length": 3, "0": "0", "1": "1", "2": "2" },
+               "X", "Y", "Z"], Array.prototype.concat.call(obj, obj2, arr));
+})();
+
+
+(function testConcatArrayLikeStringLength() {
+  "use strict";
+  var obj = {
+    "length": "6",
+    "1": "A",
+    "3": "B",
+    "5": "C"
+  };
+  obj[Symbol.isConcatSpreadable] = true;
+  var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
+  var arr = ["X", "Y", "Z"];
+  assertEquals([void 0, "A", void 0, "B", void 0, "C",
+               { "length": 3, "0": "0", "1": "1", "2": "2" },
+               "X", "Y", "Z"], Array.prototype.concat.call(obj, obj2, arr));
+})();
+
+
+(function testConcatArrayLikeNegativeLength() {
+  "use strict";
+  var obj = {
+    "length": -6,
+    "1": "A",
+    "3": "B",
+    "5": "C"
+  };
+  obj[Symbol.isConcatSpreadable] = true;
+  assertEquals([], [].concat(obj));
+  obj.length = -6.7;
+  assertEquals([], [].concat(obj));
+  obj.length = "-6";
+  assertEquals([], [].concat(obj));
+})();
+
+
+(function testConcatArrayLikeToLengthThrows() {
+  "use strict";
+  var obj = {
+    "length": {valueOf: null, toString: null},
+    "1": "A",
+    "3": "B",
+    "5": "C"
+  };
+  obj[Symbol.isConcatSpreadable] = true;
+  var obj2 = { length: 3, "0": "0", "1": "1", "2": "2" };
+  var arr = ["X", "Y", "Z"];
+  assertThrows(function() {
+    Array.prototype.concat.call(obj, obj2, arr);
+  }, TypeError);
+})();
+
+
+(function testConcatArrayLikePrimitiveNonNumberLength() {
+  "use strict";
+  var obj = {
+    "1": "A",
+    "3": "B",
+    "5": "C"
+  };
+  obj[Symbol.isConcatSpreadable] = true;
+  obj.length = {toString: function() { return "SIX"; }, valueOf: null };
+  assertEquals([], [].concat(obj));
+  obj.length = {toString: null, valueOf: function() { return "SIX"; } };
+  assertEquals([], [].concat(obj));
+})();
+
+
+(function testConcatArrayLikeLengthToStringThrows() {
+  "use strict";
+  function MyError() {}
+  var obj = {
+    "length": { toString: function() {
+        throw new MyError();
+      }, valueOf: null
+    },
+    "1": "A",
+    "3": "B",
+    "5": "C"
+  };
+  obj[Symbol.isConcatSpreadable] = true;
+  assertThrows(function() {
+    [].concat(obj);
+  }, MyError);
+})();
+
+
+(function testConcatArrayLikeLengthValueOfThrows() {
+  "use strict";
+  function MyError() {}
+  var obj = {
+    "length": { valueOf: function() {
+      throw new MyError();
+    }, toString: null
+  },
+  "1": "A",
+  "3": "B",
+  "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+assertThrows(function() {
+  [].concat(obj);
+}, MyError);
+})();
+
+
+(function testConcatHoleyArray() {
+  "use strict";
+  var arr = [];
+  arr[4] = "Item 4";
+  arr[8] = "Item 8";
+  var arr2 = [".", "!", "?"];
+  assertEquals([void 0, void 0, void 0, void 0, "Item 4", void 0, void 0,
+                void 0, "Item 8", ".", "!", "?"], arr.concat(arr2));
+})();
+
+
+(function testIsConcatSpreadableGetterThrows() {
+  "use strict";
+  function MyError() {}
+  var obj = {};
+  Object.defineProperty(obj, Symbol.isConcatSpreadable, {
+    get: function() { throw new MyError(); }
+  });
+
+  assertThrows(function() {
+    [].concat(obj);
+  }, MyError);
+
+  assertThrows(function() {
+    Array.prototype.concat.call(obj, 1, 2, 3);
+  }, MyError);
+})();
+
+
+(function testConcatLengthThrows() {
+  "use strict";
+  function MyError() {}
+  var obj = {};
+  obj[Symbol.isConcatSpreadable] = true;
+  Object.defineProperty(obj, "length", {
+    get: function() { throw new MyError(); }
+  });
+
+  assertThrows(function() {
+    [].concat(obj);
+  }, MyError);
+
+  assertThrows(function() {
+    Array.prototype.concat.call(obj, 1, 2, 3);
+  }, MyError);
+})();
+
+
+(function testConcatArraySubclass() {
+  "use strict";
+  // TODO(caitp): when concat is called on instances of classes which extend
+  // Array, they should:
+  //
+  // - return an instance of the class, rather than an Array instance (if from
+  //   same Realm)
+  // - always treat such classes as concat-spreadable
+})();
+
+
+(function testConcatNonArray() {
+  "use strict";
+  class NonArray {
+    constructor() { Array.apply(this, arguments); }
+  };
+
+  var obj = new NonArray(1,2,3);
+  var result = Array.prototype.concat.call(obj, 4, 5, 6);
+  assertEquals(Array, result.constructor);
+  assertEquals([obj,4,5,6], result);
+  assertFalse(result instanceof NonArray);
+})();
+
+
+function testConcatTypedArray(type, elems, modulo) {
+  "use strict";
+  var items = new Array(elems);
+  var ta_by_len = new type(elems);
+  for (var i = 0; i < elems; ++i) {
+    ta_by_len[i] = items[i] = modulo === false ? i : elems % modulo;
+  }
+  var ta = new type(items);
+  assertEquals([ta, ta], [].concat(ta, ta));
+  ta[Symbol.isConcatSpreadable] = true;
+  assertEquals(items, [].concat(ta));
+
+  assertEquals([ta_by_len, ta_by_len], [].concat(ta_by_len, ta_by_len));
+  ta_by_len[Symbol.isConcatSpreadable] = true;
+  assertEquals(items, [].concat(ta_by_len));
+
+  // TypedArray with fake `length`.
+  ta = new type(1);
+  var defValue = ta[0];
+  var expected = new Array(4000);
+  expected[0] = defValue;
+
+  Object.defineProperty(ta, "length", { value: 4000 });
+  ta[Symbol.isConcatSpreadable] = true;
+  assertEquals(expected, [].concat(ta));
+}
+
+(function testConcatSmallTypedArray() {
+  var max = [2^8, 2^16, 2^32, false, false];
+  [
+    Uint8Array,
+    Uint16Array,
+    Uint32Array,
+    Float32Array,
+    Float64Array
+  ].forEach(function(ctor, i) {
+    testConcatTypedArray(ctor, 1, max[i]);
+  });
+})();
+
+
+(function testConcatLargeTypedArray() {
+  var max = [2^8, 2^16, 2^32, false, false];
+  [
+    Uint8Array,
+    Uint16Array,
+    Uint32Array,
+    Float32Array,
+    Float64Array
+  ].forEach(function(ctor, i) {
+    testConcatTypedArray(ctor, 4000, max[i]);
+  });
+})();
+
+
+(function testConcatStrictArguments() {
+  var args = (function(a, b, c) { "use strict"; return arguments; })(1,2,3);
+  args[Symbol.isConcatSpreadable] = true;
+  assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
+
+  Object.defineProperty(args, "length", { value: 6 });
+  assertEquals([1, 2, 3, void 0, void 0, void 0], [].concat(args));
+})();
+
+
+(function testConcatSloppyArguments() {
+  var args = (function(a, b, c) { return arguments; })(1,2,3);
+  args[Symbol.isConcatSpreadable] = true;
+  assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
+
+  Object.defineProperty(args, "length", { value: 6 });
+  assertEquals([1, 2, 3, void 0, void 0, void 0], [].concat(args));
+})();
+
+
+(function testConcatSloppyArgumentsWithDupes() {
+  var args = (function(a, a, a) { return arguments; })(1,2,3);
+  args[Symbol.isConcatSpreadable] = true;
+  assertEquals([1, 2, 3, 1, 2, 3], [].concat(args, args));
+
+  Object.defineProperty(args, "length", { value: 6 });
+  assertEquals([1, 2, 3, void 0, void 0, void 0], [].concat(args));
+})();
+
+
+(function testConcatSloppyArgumentsThrows() {
+  function MyError() {}
+  var args = (function(a) { return arguments; })(1,2,3);
+  Object.defineProperty(args, 0, {
+    get: function() { throw new MyError(); }
+  });
+  args[Symbol.isConcatSpreadable] = true;
+  assertThrows(function() {
+    return [].concat(args, args);
+  }, MyError);
+})();
+
+
+(function testConcatHoleySloppyArguments() {
+  var args = (function(a) { return arguments; })(1,2,3);
+  delete args[1];
+  args[Symbol.isConcatSpreadable] = true;
+  assertEquals([1, void 0, 3, 1, void 0, 3], [].concat(args, args));
+})();
+
+
+(function testConcatSpreadableStringWrapper() {
+  "use strict";
+  var str1 = new String("yuck\uD83D\uDCA9")
+  // String wrapper objects are not concat-spreadable by default
+  assertEquals([str1], [].concat(str1));
+
+  // String wrapper objects may be individually concat-spreadable
+  str1[Symbol.isConcatSpreadable] = true;
+  assertEquals(["y", "u", "c", "k", "\uD83D", "\uDCA9"],
+               [].concat(str1));
+
+  String.prototype[Symbol.isConcatSpreadable] = true;
+  // String wrapper objects may be concat-spreadable
+  assertEquals(["y", "u", "c", "k", "\uD83D", "\uDCA9"],
+               [].concat(new String("yuck\uD83D\uDCA9")));
+
+  // String values are never concat-spreadable
+  assertEquals(["yuck\uD83D\uDCA9"], [].concat("yuck\uD83D\uDCA9"));
+  delete String.prototype[Symbol.isConcatSpreadable];
+})();
+
+
+(function testConcatSpreadableBooleanWrapper() {
+  "use strict";
+  var bool = new Boolean(true)
+  // Boolean wrapper objects are not concat-spreadable by default
+  assertEquals([bool], [].concat(bool));
+
+  // Boolean wrapper objects may be individually concat-spreadable
+  bool[Symbol.isConcatSpreadable] = true;
+  bool.length = 3;
+  bool[0] = 1, bool[1] = 2, bool[2] = 3;
+  assertEquals([1, 2, 3], [].concat(bool));
+
+  Boolean.prototype[Symbol.isConcatSpreadable] = true;
+  // Boolean wrapper objects may be concat-spreadable
+  assertEquals([], [].concat(new Boolean(true)));
+  Boolean.prototype[0] = 1;
+  Boolean.prototype[1] = 2;
+  Boolean.prototype[2] = 3;
+  Boolean.prototype.length = 3;
+  assertEquals([1,2,3], [].concat(new Boolean(true)));
+
+  // Boolean values are never concat-spreadable
+  assertEquals([true], [].concat(true));
+  delete Boolean.prototype[Symbol.isConcatSpreadable];
+  delete Boolean.prototype[0];
+  delete Boolean.prototype[1];
+  delete Boolean.prototype[2];
+  delete Boolean.prototype.length;
+})();
+
+
+(function testConcatSpreadableNumberWrapper() {
+  "use strict";
+  var num = new Number(true)
+  // Number wrapper objects are not concat-spreadable by default
+  assertEquals([num], [].concat(num));
+
+  // Number wrapper objects may be individually concat-spreadable
+  num[Symbol.isConcatSpreadable] = true;
+  num.length = 3;
+  num[0] = 1, num[1] = 2, num[2] = 3;
+  assertEquals([1, 2, 3], [].concat(num));
+
+  Number.prototype[Symbol.isConcatSpreadable] = true;
+  // Number wrapper objects may be concat-spreadable
+  assertEquals([], [].concat(new Number(123)));
+  Number.prototype[0] = 1;
+  Number.prototype[1] = 2;
+  Number.prototype[2] = 3;
+  Number.prototype.length = 3;
+  assertEquals([1,2,3], [].concat(new Number(123)));
+
+  // Number values are never concat-spreadable
+  assertEquals([true], [].concat(true));
+  delete Number.prototype[Symbol.isConcatSpreadable];
+  delete Number.prototype[0];
+  delete Number.prototype[1];
+  delete Number.prototype[2];
+  delete Number.prototype.length;
+})();
+
+
+(function testConcatSpreadableFunction() {
+  "use strict";
+  var fn = function(a, b, c) {}
+  // Functions are not concat-spreadable by default
+  assertEquals([fn], [].concat(fn));
+
+  // Functions may be individually concat-spreadable
+  fn[Symbol.isConcatSpreadable] = true;
+  fn[0] = 1, fn[1] = 2, fn[2] = 3;
+  assertEquals([1, 2, 3], [].concat(fn));
+
+  Function.prototype[Symbol.isConcatSpreadable] = true;
+  // Functions may be concat-spreadable
+  assertEquals([void 0, void 0, void 0], [].concat(function(a,b,c) {}));
+  Function.prototype[0] = 1;
+  Function.prototype[1] = 2;
+  Function.prototype[2] = 3;
+  assertEquals([1,2,3], [].concat(function(a, b, c) {}));
+
+  delete Function.prototype[Symbol.isConcatSpreadable];
+  delete Function.prototype[0];
+  delete Function.prototype[1];
+  delete Function.prototype[2];
+})();
+
+
+(function testConcatSpreadableRegExp() {
+  "use strict";
+  var re = /abc/;
+  // RegExps are not concat-spreadable by default
+  assertEquals([re], [].concat(re));
+
+  // RegExps may be individually concat-spreadable
+  re[Symbol.isConcatSpreadable] = true;
+  re[0] = 1, re[1] = 2, re[2] = 3, re.length = 3;
+  assertEquals([1, 2, 3], [].concat(re));
+
+  // RegExps may be concat-spreadable
+  RegExp.prototype[Symbol.isConcatSpreadable] = true;
+  RegExp.prototype.length = 3;
+
+  assertEquals([void 0, void 0, void 0], [].concat(/abc/));
+  RegExp.prototype[0] = 1;
+  RegExp.prototype[1] = 2;
+  RegExp.prototype[2] = 3;
+  assertEquals([1,2,3], [].concat(/abc/));
+
+  delete RegExp.prototype[Symbol.isConcatSpreadable];
+  delete RegExp.prototype[0];
+  delete RegExp.prototype[1];
+  delete RegExp.prototype[2];
+  delete RegExp.prototype.length;
+})();
+
+
+(function testArrayConcatSpreadableSparseObject() {
+  "use strict";
+  var obj = { length: 5 };
+  obj[Symbol.isConcatSpreadable] = true;
+  assertEquals([void 0, void 0, void 0, void 0, void 0], [].concat(obj));
+
+  obj.length = 4000;
+  assertEquals(new Array(4000), [].concat(obj));
+})();
+
+
+// ES5 tests
+(function testArrayConcatES5() {
+  "use strict";
+  var poses;
+  var pos;
+
+  poses = [140, 4000000000];
+  while (pos = poses.shift()) {
+    var a = new Array(pos);
+    var array_proto = [];
+    a.__proto__ = array_proto;
+    assertEquals(pos, a.length);
+    a.push('foo');
+    assertEquals(pos + 1, a.length);
+    var b = ['bar'];
+    var c = a.concat(b);
+    assertEquals(pos + 2, c.length);
+    assertEquals("undefined", typeof(c[pos - 1]));
+    assertEquals("foo", c[pos]);
+    assertEquals("bar", c[pos + 1]);
+
+    // Can we fool the system by putting a number in a string?
+    var onetwofour = "124";
+    a[onetwofour] = 'doo';
+    assertEquals(a[124], 'doo');
+    c = a.concat(b);
+    assertEquals(c[124], 'doo');
+
+    // If we put a number in the prototype, then the spec says it should be
+    // copied on concat.
+    array_proto["123"] = 'baz';
+    assertEquals(a[123], 'baz');
+
+    c = a.concat(b);
+    assertEquals(pos + 2, c.length);
+    assertEquals("baz", c[123]);
+    assertEquals("undefined", typeof(c[pos - 1]));
+    assertEquals("foo", c[pos]);
+    assertEquals("bar", c[pos + 1]);
+
+    // When we take the number off the prototype it disappears from a, but
+    // the concat put it in c itself.
+    array_proto["123"] = undefined;
+    assertEquals("undefined", typeof(a[123]));
+    assertEquals("baz", c[123]);
+
+    // If the element of prototype is shadowed, the element on the instance
+    // should be copied, but not the one on the prototype.
+    array_proto[123] = 'baz';
+    a[123] = 'xyz';
+    assertEquals('xyz', a[123]);
+    c = a.concat(b);
+    assertEquals('xyz', c[123]);
+
+    // Non-numeric properties on the prototype or the array shouldn't get
+    // copied.
+    array_proto.moe = 'joe';
+    a.ben = 'jerry';
+    assertEquals(a["moe"], 'joe');
+    assertEquals(a["ben"], 'jerry');
+    c = a.concat(b);
+    // ben was not copied
+    assertEquals("undefined", typeof(c.ben));
+
+    // When we take moe off the prototype it disappears from all arrays.
+    array_proto.moe = undefined;
+    assertEquals("undefined", typeof(c.moe));
+
+    // Negative indices don't get concated.
+    a[-1] = 'minus1';
+    assertEquals("minus1", a[-1]);
+    assertEquals("undefined", typeof(a[0xffffffff]));
+    c = a.concat(b);
+    assertEquals("undefined", typeof(c[-1]));
+    assertEquals("undefined", typeof(c[0xffffffff]));
+    assertEquals(c.length, a.length + 1);
+  }
+
+  poses = [140, 4000000000];
+  while (pos = poses.shift()) {
+    var a = new Array(pos);
+    assertEquals(pos, a.length);
+    a.push('foo');
+    assertEquals(pos + 1, a.length);
+    var b = ['bar'];
+    var c = a.concat(b);
+    assertEquals(pos + 2, c.length);
+    assertEquals("undefined", typeof(c[pos - 1]));
+    assertEquals("foo", c[pos]);
+    assertEquals("bar", c[pos + 1]);
+
+    // Can we fool the system by putting a number in a string?
+    var onetwofour = "124";
+    a[onetwofour] = 'doo';
+    assertEquals(a[124], 'doo');
+    c = a.concat(b);
+    assertEquals(c[124], 'doo');
+
+    // If we put a number in the prototype, then the spec says it should be
+    // copied on concat.
+    Array.prototype["123"] = 'baz';
+    assertEquals(a[123], 'baz');
+
+    c = a.concat(b);
+    assertEquals(pos + 2, c.length);
+    assertEquals("baz", c[123]);
+    assertEquals("undefined", typeof(c[pos - 1]));
+    assertEquals("foo", c[pos]);
+    assertEquals("bar", c[pos + 1]);
+
+    // When we take the number off the prototype it disappears from a, but
+    // the concat put it in c itself.
+    Array.prototype["123"] = undefined;
+    assertEquals("undefined", typeof(a[123]));
+    assertEquals("baz", c[123]);
+
+    // If the element of prototype is shadowed, the element on the instance
+    // should be copied, but not the one on the prototype.
+    Array.prototype[123] = 'baz';
+    a[123] = 'xyz';
+    assertEquals('xyz', a[123]);
+    c = a.concat(b);
+    assertEquals('xyz', c[123]);
+
+    // Non-numeric properties on the prototype or the array shouldn't get
+    // copied.
+    Array.prototype.moe = 'joe';
+    a.ben = 'jerry';
+    assertEquals(a["moe"], 'joe');
+    assertEquals(a["ben"], 'jerry');
+    c = a.concat(b);
+    // ben was not copied
+    assertEquals("undefined", typeof(c.ben));
+    // moe was not copied, but we can see it through the prototype
+    assertEquals("joe", c.moe);
+
+    // When we take moe off the prototype it disappears from all arrays.
+    Array.prototype.moe = undefined;
+    assertEquals("undefined", typeof(c.moe));
+
+    // Negative indices don't get concated.
+    a[-1] = 'minus1';
+    assertEquals("minus1", a[-1]);
+    assertEquals("undefined", typeof(a[0xffffffff]));
+    c = a.concat(b);
+    assertEquals("undefined", typeof(c[-1]));
+    assertEquals("undefined", typeof(c[0xffffffff]));
+    assertEquals(c.length, a.length + 1);
+
+  }
+
+  a = [];
+  c = a.concat('Hello');
+  assertEquals(1, c.length);
+  assertEquals("Hello", c[0]);
+  assertEquals("Hello", c.toString());
+
+  // Check that concat preserves holes.
+  var holey = [void 0,'a',,'c'].concat(['d',,'f',[0,,2],void 0])
+  assertEquals(9, holey.length);  // hole in embedded array is ignored
+  for (var i = 0; i < holey.length; i++) {
+    if (i == 2 || i == 5) {
+      assertFalse(i in holey);
+    } else {
+      assertTrue(i in holey);
+    }
+  }
+
+  // Polluted prototype from prior tests.
+  delete Array.prototype[123];
+
+  // Check that concat reads getters in the correct order.
+  var arr1 = [,2];
+  var arr2 = [1,3];
+  var r1 = [].concat(arr1, arr2);  // [,2,1,3]
+  assertEquals([,2,1,3], r1);
+
+  // Make first array change length of second array.
+  Object.defineProperty(arr1, 0, {get: function() {
+        arr2.push("X");
+        return undefined;
+      }, configurable: true})
+  var r2 = [].concat(arr1, arr2);  // [undefined,2,1,3,"X"]
+  assertEquals([undefined,2,1,3,"X"], r2);
+
+  // Make first array change length of second array massively.
+  arr2.length = 2;
+  Object.defineProperty(arr1, 0, {get: function() {
+        arr2[500000] = "X";
+        return undefined;
+      }, configurable: true})
+  var r3 = [].concat(arr1, arr2);  // [undefined,2,1,3,"X"]
+  var expected = [undefined,2,1,3];
+  expected[500000 + 2] = "X";
+
+  assertEquals(expected, r3);
+
+  var arr3 = [];
+  var trace = [];
+  var expectedTrace = []
+  function mkGetter(i) { return function() { trace.push(i); }; }
+  arr3.length = 10000;
+  for (var i = 0; i < 100; i++) {
+    Object.defineProperty(arr3, i * i, {get: mkGetter(i)});
+    expectedTrace[i] = i;
+    expectedTrace[100 + i] = i;
+  }
+  var r4 = [0].concat(arr3, arr3);
+  assertEquals(1 + arr3.length * 2, r4.length);
+  assertEquals(expectedTrace, trace);
+})();
diff --git a/test/mjsunit/harmony/array-find.js b/test/mjsunit/harmony/array-find.js
index 9f5750e..eb32082 100644
--- a/test/mjsunit/harmony/array-find.js
+++ b/test/mjsunit/harmony/array-find.js
@@ -237,6 +237,24 @@
     return this.elementAt(key) === val;
   }, thisArg);
   assertEquals("b", found);
+
+  // Create a new object in each function call when receiver is a
+  // primitive value. See ECMA-262, Annex C.
+  a = [];
+  [1, 2].find(function() { a.push(this) }, "");
+  assertTrue(a[0] !== a[1]);
+
+  // Do not create a new object otherwise.
+  a = [];
+  [1, 2].find(function() { a.push(this) }, {});
+  assertEquals(a[0], a[1]);
+
+  // In strict mode primitive values should not be coerced to an object.
+  a = [];
+  [1, 2].find(function() { 'use strict'; a.push(this); }, "");
+  assertEquals("", a[0]);
+  assertEquals(a[0], a[1]);
+
 })();
 
 // Test exceptions
diff --git a/test/mjsunit/harmony/array-findindex.js b/test/mjsunit/harmony/array-findindex.js
index a33849d..a5df05a 100644
--- a/test/mjsunit/harmony/array-findindex.js
+++ b/test/mjsunit/harmony/array-findindex.js
@@ -237,6 +237,24 @@
     return this.elementAt(key) === val;
   }, thisArg);
   assertEquals(1, index);
+
+  // Create a new object in each function call when receiver is a
+  // primitive value. See ECMA-262, Annex C.
+  a = [];
+  [1, 2].findIndex(function() { a.push(this) }, "");
+  assertTrue(a[0] !== a[1]);
+
+  // Do not create a new object otherwise.
+  a = [];
+  [1, 2].findIndex(function() { a.push(this) }, {});
+  assertEquals(a[0], a[1]);
+
+  // In strict mode primitive values should not be coerced to an object.
+  a = [];
+  [1, 2].findIndex(function() { 'use strict'; a.push(this); }, "");
+  assertEquals("", a[0]);
+  assertEquals(a[0], a[1]);
+
 })();
 
 // Test exceptions
diff --git a/test/mjsunit/harmony/array-from.js b/test/mjsunit/harmony/array-from.js
new file mode 100644
index 0000000..e7c9fef
--- /dev/null
+++ b/test/mjsunit/harmony/array-from.js
@@ -0,0 +1,123 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-arrays --harmony-generators
+(function() {
+
+assertEquals(1, Array.from.length);
+
+function assertArrayLikeEquals(value, expected, type) {
+  assertInstanceof(value, type);
+  assertEquals(expected.length, value.length);
+  for (var i=0; i<value.length; ++i) {
+    assertEquals(expected[i], value[i]);
+  }
+}
+
+// Assert that constructor is called with "length" for array-like objects
+var myCollectionCalled = false;
+function MyCollection(length) {
+  myCollectionCalled = true;
+  assertEquals(1, arguments.length);
+  assertEquals(5, length);
+}
+
+Array.from.call(MyCollection, {length: 5});
+assertTrue(myCollectionCalled);
+
+// Assert that calling mapfn with / without thisArg in sloppy and strict modes
+// works as expected.
+var global = this;
+function non_strict(){ assertEquals(global, this); }
+function strict(){ "use strict"; assertEquals(void 0, this); }
+function strict_null(){ "use strict"; assertEquals(null, this); }
+Array.from([1], non_strict);
+Array.from([1], non_strict, void 0);
+Array.from([1], non_strict, null);
+Array.from([1], strict);
+Array.from([1], strict, void 0);
+Array.from([1], strict_null, null);
+
+function testArrayFrom(thisArg, constructor) {
+  assertArrayLikeEquals(Array.from.call(thisArg, [], undefined), [],
+      constructor);
+  assertArrayLikeEquals(Array.from.call(thisArg, NaN), [], constructor);
+  assertArrayLikeEquals(Array.from.call(thisArg, Infinity), [], constructor);
+  assertArrayLikeEquals(Array.from.call(thisArg, 10000000), [], constructor);
+  assertArrayLikeEquals(Array.from.call(thisArg, 'test'), ['t', 'e', 's', 't'],
+      constructor);
+
+  assertArrayLikeEquals(Array.from.call(thisArg,
+      { length: 1, '0': { 'foo': 'bar' } }), [{'foo': 'bar'}], constructor);
+
+  assertArrayLikeEquals(Array.from.call(thisArg,
+      { length: -1, '0': { 'foo': 'bar' } }), [], constructor);
+
+  assertArrayLikeEquals(Array.from.call(thisArg,
+      [ 'foo', 'bar', 'baz' ]), ['foo', 'bar', 'baz'], constructor);
+
+  var kSet = new Set(['foo', 'bar', 'baz']);
+  assertArrayLikeEquals(Array.from.call(thisArg, kSet), ['foo', 'bar', 'baz'],
+      constructor);
+
+  var kMap = new Map(['foo', 'bar', 'baz'].entries());
+  assertArrayLikeEquals(Array.from.call(thisArg, kMap),
+      [[0, 'foo'], [1, 'bar'], [2, 'baz']], constructor);
+
+
+  function* generator() {
+    yield 'a';
+    yield 'b';
+    yield 'c';
+  }
+
+  assertArrayLikeEquals(Array.from.call(thisArg, generator()),
+                        ['a', 'b', 'c'], constructor);
+
+  // Mozilla:
+  // Array.from on a string handles surrogate pairs correctly.
+  var gclef = "\uD834\uDD1E"; // U+1D11E MUSICAL SYMBOL G CLEF
+  assertArrayLikeEquals(Array.from.call(thisArg, gclef), [gclef], constructor);
+  assertArrayLikeEquals(Array.from.call(thisArg, gclef + " G"),
+      [gclef, " ", "G"], constructor);
+
+  assertArrayLikeEquals(Array.from.call(thisArg, 'test', function(x) {
+    return this.filter(x);
+  }, {
+    filter: function(x) { return x.toUpperCase(); }
+  }), ['T', 'E', 'S', 'T'], constructor);
+  assertArrayLikeEquals(Array.from.call(thisArg, 'test', function(x) {
+    return x.toUpperCase();
+  }), ['T', 'E', 'S', 'T'], constructor);
+
+  this.thisArg = thisArg;
+  assertThrows('Array.from.call(thisArg, null)', TypeError);
+  assertThrows('Array.from.call(thisArg, undefined)', TypeError);
+  assertThrows('Array.from.call(thisArg, [], null)', TypeError);
+  assertThrows('Array.from.call(thisArg, [], "noncallable")', TypeError);
+
+  this.nullIterator = {};
+  nullIterator[Symbol.iterator] = null;
+  assertThrows('Array.from.call(thisArg, nullIterator)', TypeError);
+
+  this.nonObjIterator = {};
+  nonObjIterator[Symbol.iterator] = function() { return "nonObject"; };
+  assertThrows('Array.from.call(thisArg, nonObjIterator)', TypeError);
+
+  assertThrows('Array.from.call(thisArg, [], null)', TypeError);
+}
+
+function Other() {}
+
+var boundFn = (function() {}).bind(Array, 27);
+
+testArrayFrom(Array, Array);
+testArrayFrom(null, Array);
+testArrayFrom({}, Array);
+testArrayFrom(Object, Object);
+testArrayFrom(Other, Other);
+testArrayFrom(Math.cos, Array);
+testArrayFrom(boundFn, Array);
+
+})();
diff --git a/test/mjsunit/harmony/array-includes-to-object-sloppy.js b/test/mjsunit/harmony/array-includes-to-object-sloppy.js
new file mode 100644
index 0000000..0f5d731
--- /dev/null
+++ b/test/mjsunit/harmony/array-includes-to-object-sloppy.js
@@ -0,0 +1,29 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-array-includes
+
+// Ported from
+// https://github.com/tc39/Array.prototype.includes/blob/master/test/number-this.js
+// using https://www.npmjs.org/package/test262-to-mjsunit
+
+// Array.prototype.includes should use ToObject on this, so that when called
+// with a number, it picks up numeric properties from Number.prototype
+(function() {
+  Number.prototype[0] = "a";
+  Number.prototype[1] = "b";
+
+  Object.defineProperty(Number.prototype, 2, {
+    get: function() {
+      assertEquals("object", typeof this);
+      return "c";
+    }
+  });
+
+  Number.prototype.length = 3;
+  assertTrue(Array.prototype.includes.call(5, "a"));
+  assertTrue(Array.prototype.includes.call(5, "b"));
+  assertTrue(Array.prototype.includes.call(5, "c"));
+  assertFalse(Array.prototype.includes.call(5, "d"));
+})();
diff --git a/test/mjsunit/harmony/array-includes-to-object-strict.js b/test/mjsunit/harmony/array-includes-to-object-strict.js
new file mode 100644
index 0000000..ee87136
--- /dev/null
+++ b/test/mjsunit/harmony/array-includes-to-object-strict.js
@@ -0,0 +1,32 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-array-includes
+
+// Ported from
+// https://github.com/tc39/Array.prototype.includes/blob/master/test/number-this.js
+// using https://www.npmjs.org/package/test262-to-mjsunit
+
+// Array.prototype.includes should use ToObject on this, so that when called
+// with a number, it picks up numeric properties from Number.prototype (even in
+// strict mode)
+(function() {
+  "use strict";
+
+  Number.prototype[0] = "a";
+  Number.prototype[1] = "b";
+
+  Object.defineProperty(Number.prototype, 2, {
+    get: function() {
+      assertEquals("object", typeof this);
+      return "c";
+    }
+  });
+
+  Number.prototype.length = 3;
+  assertTrue(Array.prototype.includes.call(5, "a"));
+  assertTrue(Array.prototype.includes.call(5, "b"));
+  assertTrue(Array.prototype.includes.call(5, "c"));
+  assertFalse(Array.prototype.includes.call(5, "d"));
+})();
diff --git a/test/mjsunit/harmony/array-includes.js b/test/mjsunit/harmony/array-includes.js
new file mode 100644
index 0000000..2cdd112
--- /dev/null
+++ b/test/mjsunit/harmony/array-includes.js
@@ -0,0 +1,677 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-array-includes
+
+// Largely ported from
+// https://github.com/tc39/Array.prototype.includes/tree/master/test
+// using https://www.npmjs.org/package/test262-to-mjsunit with further edits
+
+
+// Array.prototype.includes sees a new element added by a getter that is hit
+// during iteration
+(function() {
+  var arrayLike = {
+    length: 5,
+    0: "a",
+
+    get 1() {
+      this[2] = "c";
+      return "b";
+    }
+  };
+
+  assertTrue(Array.prototype.includes.call(arrayLike, "c"));
+})();
+
+
+// Array.prototype.includes works on array-like objects
+(function() {
+  var arrayLike1 = {
+    length: 5,
+    0: "a",
+    1: "b"
+  };
+
+  assertTrue(Array.prototype.includes.call(arrayLike1, "a"));
+  assertFalse(Array.prototype.includes.call(arrayLike1, "c"));
+
+  var arrayLike2 = {
+    length: 2,
+    0: "a",
+    1: "b",
+    2: "c"
+  };
+
+  assertTrue(Array.prototype.includes.call(arrayLike2, "b"));
+  assertFalse(Array.prototype.includes.call(arrayLike2, "c"));
+})();
+
+
+// Array.prototype.includes should fail if used on a null or undefined this
+(function() {
+  assertThrows(function() {
+    Array.prototype.includes.call(null, "a");
+  }, TypeError);
+
+  assertThrows(function() {
+    Array.prototype.includes.call(undefined, "a");
+  }, TypeError);
+})();
+
+
+// Array.prototype.includes should terminate if getting an index throws an
+// exception
+(function() {
+  function Test262Error() {}
+
+  var trappedZero = {
+    length: 2,
+
+    get 0() {
+      throw new Test262Error();
+    },
+
+    get 1() {
+      assertUnreachable("Should not try to get the first element");
+    }
+  };
+
+  assertThrows(function() {
+    Array.prototype.includes.call(trappedZero, "a");
+  }, Test262Error);
+})();
+
+
+// Array.prototype.includes should terminate if ToNumber ends up being called on
+// a symbol fromIndex
+(function() {
+  var trappedZero = {
+    length: 1,
+
+    get 0() {
+      assertUnreachable("Should not try to get the zeroth element");
+    }
+  };
+
+  assertThrows(function() {
+    Array.prototype.includes.call(trappedZero, "a", Symbol());
+  }, TypeError);
+})();
+
+
+// Array.prototype.includes should terminate if an exception occurs converting
+// the fromIndex to a number
+(function() {
+  function Test262Error() {}
+
+  var fromIndex = {
+    valueOf: function() {
+      throw new Test262Error();
+    }
+  };
+
+  var trappedZero = {
+    length: 1,
+
+    get 0() {
+      assertUnreachable("Should not try to get the zeroth element");
+    }
+  };
+
+  assertThrows(function() {
+    Array.prototype.includes.call(trappedZero, "a", fromIndex);
+  }, Test262Error);
+})();
+
+
+// Array.prototype.includes should terminate if an exception occurs getting the
+// length
+(function() {
+  function Test262Error() {}
+
+  var fromIndexTrap = {
+    valueOf: function() {
+      assertUnreachable("Should not try to call ToInteger on valueOf");
+    }
+  };
+
+  var throwingLength = {
+    get length() {
+      throw new Test262Error();
+    },
+
+    get 0() {
+      assertUnreachable("Should not try to get the zeroth element");
+    }
+  };
+
+  assertThrows(function() {
+    Array.prototype.includes.call(throwingLength, "a", fromIndexTrap);
+  }, Test262Error);
+})();
+
+
+// Array.prototype.includes should terminate if ToLength ends up being called on
+// a symbol length
+(function() {
+  var fromIndexTrap = {
+    valueOf: function() {
+      assertUnreachable("Should not try to call ToInteger on valueOf");
+    }
+  };
+
+  var badLength = {
+    length: Symbol(),
+
+    get 0() {
+      assertUnreachable("Should not try to get the zeroth element");
+    }
+  };
+
+  assertThrows(function() {
+    Array.prototype.includes.call(badLength, "a", fromIndexTrap);
+  }, TypeError);
+})();
+
+
+// Array.prototype.includes should terminate if an exception occurs converting
+// the length to a number
+(function() {
+  function Test262Error() {}
+
+  var fromIndexTrap = {
+    valueOf: function() {
+      assertUnreachable("Should not try to call ToInteger on valueOf");
+    }
+  };
+
+  var badLength = {
+    length: {
+      valueOf: function() {
+        throw new Test262Error();
+      }
+    },
+
+    get 0() {
+      assertUnreachable("Should not try to get the zeroth element");
+    }
+  };
+
+  assertThrows(function() {
+    Array.prototype.includes.call(badLength, "a", fromIndexTrap);
+  }, Test262Error);
+})();
+
+
+// Array.prototype.includes should search the whole array, as the optional
+// second argument fromIndex defaults to 0
+(function() {
+  assertTrue([10, 11].includes(10));
+  assertTrue([10, 11].includes(11));
+
+  var arrayLike = {
+    length: 2,
+
+    get 0() {
+      return "1";
+    },
+
+    get 1() {
+      return "2";
+    }
+  };
+
+  assertTrue(Array.prototype.includes.call(arrayLike, "1"));
+  assertTrue(Array.prototype.includes.call(arrayLike, "2"));
+})();
+
+
+// Array.prototype.includes returns false if fromIndex is greater or equal to
+// the length of the array
+(function() {
+  assertFalse([1, 2].includes(2, 3));
+  assertFalse([1, 2].includes(2, 2));
+
+  var arrayLikeWithTrap = {
+    length: 2,
+
+    get 0() {
+      assertUnreachable("Getter for 0 was called");
+    },
+
+    get 1() {
+      assertUnreachable("Getter for 1 was called");
+    }
+  };
+
+  assertFalse(Array.prototype.includes.call(arrayLikeWithTrap, "c", 2));
+  assertFalse(Array.prototype.includes.call(arrayLikeWithTrap, "c", 3));
+})();
+
+
+// Array.prototype.includes searches the whole array if the computed index from
+// the given negative fromIndex argument is less than 0
+(function() {
+  assertTrue([1, 3].includes(1, -4));
+  assertTrue([1, 3].includes(3, -4));
+
+  var arrayLike = {
+    length: 2,
+    0: "a",
+
+    get 1() {
+      return "b";
+    },
+
+    get "-1"() {
+      assertUnreachable("Should not try to get the element at index -1");
+    }
+  };
+
+  assertTrue(Array.prototype.includes.call(arrayLike, "a", -4));
+  assertTrue(Array.prototype.includes.call(arrayLike, "b", -4));
+})();
+
+
+// Array.prototype.includes should use a negative value as the offset from the
+// end of the array to compute fromIndex
+(function() {
+  assertTrue([12, 13].includes(13, -1));
+  assertFalse([12, 13].includes(12, -1));
+  assertTrue([12, 13].includes(12, -2));
+
+  var arrayLike = {
+    length: 2,
+
+    get 0() {
+      return "a";
+    },
+
+    get 1() {
+      return "b";
+    }
+  };
+
+  assertTrue(Array.prototype.includes.call(arrayLike, "b", -1));
+  assertFalse(Array.prototype.includes.call(arrayLike, "a", -1));
+  assertTrue(Array.prototype.includes.call(arrayLike, "a", -2));
+})();
+
+
+// Array.prototype.includes converts its fromIndex parameter to an integer
+(function() {
+  assertFalse(["a", "b"].includes("a", 2.3));
+
+  var arrayLikeWithTraps = {
+    length: 2,
+
+    get 0() {
+      assertUnreachable("Getter for 0 was called");
+    },
+
+    get 1() {
+      assertUnreachable("Getter for 1 was called");
+    }
+  };
+
+  assertFalse(Array.prototype.includes.call(arrayLikeWithTraps, "c", 2.1));
+  assertFalse(Array.prototype.includes.call(arrayLikeWithTraps, "c", +Infinity));
+  assertTrue(["a", "b", "c"].includes("a", -Infinity));
+  assertTrue(["a", "b", "c"].includes("c", 2.9));
+  assertTrue(["a", "b", "c"].includes("c", NaN));
+
+  var arrayLikeWithTrapAfterZero = {
+    length: 2,
+
+    get 0() {
+      return "a";
+    },
+
+    get 1() {
+      assertUnreachable("Getter for 1 was called");
+    }
+  };
+
+  assertTrue(Array.prototype.includes.call(arrayLikeWithTrapAfterZero, "a", NaN));
+
+  var numberLike = {
+    valueOf: function() {
+      return 2;
+    }
+  };
+
+  assertFalse(["a", "b", "c"].includes("a", numberLike));
+  assertFalse(["a", "b", "c"].includes("a", "2"));
+  assertTrue(["a", "b", "c"].includes("c", numberLike));
+  assertTrue(["a", "b", "c"].includes("c", "2"));
+})();
+
+
+// Array.prototype.includes should have length 1
+(function() {
+  assertEquals(1, Array.prototype.includes.length);
+})();
+
+
+// Array.prototype.includes should have name property with value 'includes'
+(function() {
+  assertEquals("includes", Array.prototype.includes.name);
+})();
+
+
+// !!! Test failed to convert:
+// Cannot convert tests with includes.
+// !!!
+
+
+// Array.prototype.includes does not skip holes; if the array has a prototype it
+// gets from that
+(function() {
+  var holesEverywhere = [,,,];
+
+  holesEverywhere.__proto__ = {
+    1: "a"
+  };
+
+  holesEverywhere.__proto__.__proto__ = Array.prototype;
+  assertTrue(holesEverywhere.includes("a"));
+  var oneHole = ["a", "b",, "d"];
+
+  oneHole.__proto__ = {
+    get 2() {
+      return "c";
+    }
+  };
+
+  assertTrue(Array.prototype.includes.call(oneHole, "c"));
+})();
+
+
+// Array.prototype.includes does not skip holes; instead it treates them as
+// undefined
+(function() {
+  assertTrue([,,,].includes(undefined));
+  assertTrue(["a", "b",, "d"].includes(undefined));
+})();
+
+
+// Array.prototype.includes gets length property from the prototype if it's
+// available
+(function() {
+  var proto = {
+    length: 1
+  };
+
+  var arrayLike = Object.create(proto);
+  arrayLike[0] = "a";
+
+  Object.defineProperty(arrayLike, "1", {
+    get: function() {
+      assertUnreachable("Getter for 1 was called");
+    }
+  });
+
+  assertTrue(Array.prototype.includes.call(arrayLike, "a"));
+})();
+
+
+// Array.prototype.includes treats a missing length property as zero
+(function() {
+  var arrayLikeWithTraps = {
+    get 0() {
+      assertUnreachable("Getter for 0 was called");
+    },
+
+    get 1() {
+      assertUnreachable("Getter for 1 was called");
+    }
+  };
+
+  assertFalse(Array.prototype.includes.call(arrayLikeWithTraps, "a"));
+})();
+
+
+// Array.prototype.includes should always return false on negative-length
+// objects
+(function() {
+  assertFalse(Array.prototype.includes.call({
+    length: -1
+  }, 2));
+
+  assertFalse(Array.prototype.includes.call({
+    length: -2
+  }));
+
+  assertFalse(Array.prototype.includes.call({
+    length: -Infinity
+  }, undefined));
+
+  assertFalse(Array.prototype.includes.call({
+    length: -Math.pow(2, 53)
+  }, NaN));
+
+  assertFalse(Array.prototype.includes.call({
+    length: -1,
+    "-1": 2
+  }, 2));
+
+  assertFalse(Array.prototype.includes.call({
+    length: -3,
+    "-1": 2
+  }, 2));
+
+  assertFalse(Array.prototype.includes.call({
+    length: -Infinity,
+    "-1": 2
+  }, 2));
+
+  var arrayLikeWithTrap = {
+    length: -1,
+
+    get 0() {
+      assertUnreachable("Getter for 0 was called");
+    }
+  };
+
+  assertFalse(Array.prototype.includes.call(arrayLikeWithTrap, 2));
+})();
+
+
+// Array.prototype.includes should clamp positive lengths to 2^53 - 1
+(function() {
+  var fromIndexForLargeIndexTests = 9007199254740990;
+
+  assertFalse(Array.prototype.includes.call({
+    length: 1
+  }, 2));
+
+  assertTrue(Array.prototype.includes.call({
+    length: 1,
+    0: "a"
+  }, "a"));
+
+  assertTrue(Array.prototype.includes.call({
+    length: +Infinity,
+    0: "a"
+  }, "a"));
+
+  assertFalse(Array.prototype.includes.call({
+    length: +Infinity
+  }, "a", fromIndexForLargeIndexTests));
+
+  var arrayLikeWithTrap = {
+    length: +Infinity,
+
+    get 9007199254740992() {
+      assertUnreachable("Getter for 9007199254740992 (i.e. 2^53) was called");
+    },
+
+    "9007199254740993": "a"
+  };
+
+  assertFalse(
+    Array.prototype.includes.call(arrayLikeWithTrap, "a", fromIndexForLargeIndexTests)
+  );
+
+  var arrayLikeWithTooBigLength = {
+    length: 9007199254740996,
+    "9007199254740992": "a"
+  };
+
+  assertFalse(
+    Array.prototype.includes.call(arrayLikeWithTooBigLength, "a", fromIndexForLargeIndexTests)
+  );
+})();
+
+
+// Array.prototype.includes should always return false on zero-length objects
+(function() {
+  assertFalse([].includes(2));
+  assertFalse([].includes());
+  assertFalse([].includes(undefined));
+  assertFalse([].includes(NaN));
+
+  assertFalse(Array.prototype.includes.call({
+    length: 0
+  }, 2));
+
+  assertFalse(Array.prototype.includes.call({
+    length: 0
+  }));
+
+  assertFalse(Array.prototype.includes.call({
+    length: 0
+  }, undefined));
+
+  assertFalse(Array.prototype.includes.call({
+    length: 0
+  }, NaN));
+
+  assertFalse(Array.prototype.includes.call({
+    length: 0,
+    0: 2
+  }, 2));
+
+  assertFalse(Array.prototype.includes.call({
+    length: 0,
+    0: undefined
+  }));
+
+  assertFalse(Array.prototype.includes.call({
+    length: 0,
+    0: undefined
+  }, undefined));
+
+  assertFalse(Array.prototype.includes.call({
+    length: 0,
+    0: NaN
+  }, NaN));
+
+  var arrayLikeWithTrap = {
+    length: 0,
+
+    get 0() {
+      assertUnreachable("Getter for 0 was called");
+    }
+  };
+
+  Array.prototype.includes.call(arrayLikeWithTrap);
+
+  var trappedFromIndex = {
+    valueOf: function() {
+      assertUnreachable("Should not try to convert fromIndex to a number on a zero-length array");
+    }
+  };
+
+  [].includes("a", trappedFromIndex);
+
+  Array.prototype.includes.call({
+    length: 0
+  }, trappedFromIndex);
+})();
+
+
+// Array.prototype.includes works on objects
+(function() {
+  assertFalse(["a", "b", "c"].includes({}));
+  assertFalse([{}, {}].includes({}));
+  var obj = {};
+  assertTrue([obj].includes(obj));
+  assertFalse([obj].includes(obj, 1));
+  assertTrue([obj, obj].includes(obj, 1));
+
+  var stringyObject = {
+    toString: function() {
+      return "a";
+    }
+  };
+
+  assertFalse(["a", "b", obj].includes(stringyObject));
+})();
+
+
+// Array.prototype.includes does not see an element removed by a getter that is
+// hit during iteration
+(function() {
+  var arrayLike = {
+    length: 5,
+    0: "a",
+
+    get 1() {
+      delete this[2];
+      return "b";
+    },
+
+    2: "c"
+  };
+
+  assertFalse(Array.prototype.includes.call(arrayLike, "c"));
+})();
+
+
+// Array.prototype.includes should use the SameValueZero algorithm to compare
+(function() {
+  assertTrue([1, 2, 3].includes(2));
+  assertFalse([1, 2, 3].includes(4));
+  assertTrue([1, 2, NaN].includes(NaN));
+  assertTrue([1, 2, -0].includes(+0));
+  assertTrue([1, 2, -0].includes(-0));
+  assertTrue([1, 2, +0].includes(-0));
+  assertTrue([1, 2, +0].includes(+0));
+  assertFalse([1, 2, -Infinity].includes(+Infinity));
+  assertTrue([1, 2, -Infinity].includes(-Infinity));
+  assertFalse([1, 2, +Infinity].includes(-Infinity));
+  assertTrue([1, 2, +Infinity].includes(+Infinity));
+})();
+
+
+// Array.prototype.includes stops once it hits the length of an array-like, even
+// if there are more after
+(function() {
+  var arrayLike = {
+    length: 2,
+    0: "a",
+    1: "b",
+
+    get 2() {
+      assertUnreachable("Should not try to get the second element");
+    }
+  };
+
+  assertFalse(Array.prototype.includes.call(arrayLike, "c"));
+})();
+
+
+// Array.prototype.includes works on typed arrays
+(function() {
+  assertTrue(Array.prototype.includes.call(new Uint8Array([1, 2, 3]), 2));
+
+  assertTrue(
+    Array.prototype.includes.call(new Float32Array([2.5, 3.14, Math.PI]), 3.1415927410125732)
+  );
+
+  assertFalse(Array.prototype.includes.call(new Uint8Array([1, 2, 3]), 4));
+  assertFalse(Array.prototype.includes.call(new Uint8Array([1, 2, 3]), 2, 2));
+})();
diff --git a/test/mjsunit/harmony/block-conflicts.js b/test/mjsunit/harmony/block-conflicts.js
index 1eedb68..d19a34a 100644
--- a/test/mjsunit/harmony/block-conflicts.js
+++ b/test/mjsunit/harmony/block-conflicts.js
@@ -1,30 +1,7 @@
 // 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:
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
 //
-//     * 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-scoping
 
 // Test for conflicting variable bindings.
@@ -175,7 +152,7 @@
 
 // Test conflicting catch/var bindings.
 for (var v = 0; v < varbinds.length; ++v) {
-  TestConflict('try {} catch(x) {' + varbinds[v] + '}');
+  TestNoConflict('try {} catch(x) {' + varbinds[v] + '}');
 }
 
 // Test conflicting parameter/var bindings.
diff --git a/test/mjsunit/harmony/block-const-assign.js b/test/mjsunit/harmony/block-const-assign.js
index b71729e..c21a0a3 100644
--- a/test/mjsunit/harmony/block-const-assign.js
+++ b/test/mjsunit/harmony/block-const-assign.js
@@ -35,61 +35,61 @@
 
 // Function local const.
 function constDecl0(use) {
-  return "(function() { const constvar = 1; " + use + "; });";
+  return "(function() { const constvar = 1; " + use + "; })();";
 }
 
 
 function constDecl1(use) {
-  return "(function() { " + use + "; const constvar = 1; });";
+  return "(function() { " + use + "; const constvar = 1; })();";
 }
 
 
 // Function local const, assign from eval.
 function constDecl2(use) {
-  use = "eval('(function() { " + use + " })')";
+  use = "eval('(function() { " + use + " })')()";
   return "(function() { const constvar = 1; " + use + "; })();";
 }
 
 
 function constDecl3(use) {
-  use = "eval('(function() { " + use + " })')";
+  use = "eval('(function() { " + use + " })')()";
   return "(function() { " + use + "; const constvar = 1; })();";
 }
 
 
 // Block local const.
 function constDecl4(use) {
-  return "(function() { { const constvar = 1; " + use + "; } });";
+  return "(function() { { const constvar = 1; " + use + "; } })();";
 }
 
 
 function constDecl5(use) {
-  return "(function() { { " + use + "; const constvar = 1; } });";
+  return "(function() { { " + use + "; const constvar = 1; } })();";
 }
 
 
 // Block local const, assign from eval.
 function constDecl6(use) {
-  use = "eval('(function() {" + use + "})')";
+  use = "eval('(function() {" + use + "})')()";
   return "(function() { { const constvar = 1; " + use + "; } })();";
 }
 
 
 function constDecl7(use) {
-  use = "eval('(function() {" + use + "})')";
+  use = "eval('(function() {" + use + "})')()";
   return "(function() { { " + use + "; const constvar = 1; } })();";
 }
 
 
 // Function expression name.
 function constDecl8(use) {
-  return "(function constvar() { " + use + "; });";
+  return "(function constvar() { " + use + "; })();";
 }
 
 
 // Function expression name, assign from eval.
 function constDecl9(use) {
-  use = "eval('(function(){" + use + "})')";
+  use = "eval('(function(){" + use + "})')()";
   return "(function constvar() { " + use + "; })();";
 }
 
@@ -104,6 +104,7 @@
               constDecl8,
               constDecl9
               ];
+let declsForTDZ = new Set([constDecl1, constDecl3, constDecl5, constDecl7]);
 let uses = [ 'constvar = 1;',
              'constvar += 1;',
              '++constvar;',
@@ -116,7 +117,13 @@
     print(d(u));
     eval(d(u));
   } catch (e) {
-    assertInstanceof(e, SyntaxError);
+    if (declsForTDZ.has(d) && u !== uses[0]) {
+      // In these cases, read of a const variable occurs
+      // before a write to it, so TDZ kicks in before const check.
+      assertInstanceof(e, ReferenceError);
+      return;
+    }
+    assertInstanceof(e, TypeError);
     assertTrue(e.toString().indexOf("Assignment to constant variable") >= 0);
     return;
   }
diff --git a/test/mjsunit/harmony/block-non-strict-errors.js b/test/mjsunit/harmony/block-non-strict-errors.js
new file mode 100644
index 0000000..11fa5c6
--- /dev/null
+++ b/test/mjsunit/harmony/block-non-strict-errors.js
@@ -0,0 +1,41 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-scoping --harmony-classes
+
+function CheckError(source) {
+  var exception = null;
+  try {
+    eval(source);
+  } catch (e) {
+    exception = e;
+  }
+  assertNotNull(exception);
+  assertEquals(
+      "Block-scoped declarations (let, const, function, class) not yet supported outside strict mode",
+      exception.message);
+}
+
+
+function CheckOk(source) {
+  eval(source);
+}
+
+CheckError("let x = 1;");
+CheckError("{ let x = 1; }");
+CheckError("function f() { let x = 1; }");
+CheckError("for (let x = 1; x < 1; x++) {}");
+CheckError("for (let x of []) {}");
+CheckError("for (let x in []) {}");
+CheckError("class C {}");
+CheckError("class C extends Array {}");
+CheckError("(class {});");
+CheckError("(class extends Array {});");
+CheckError("(class C {});");
+CheckError("(class C exends Array {});");
+
+CheckOk("let = 1;");
+CheckOk("{ let = 1; }");
+CheckOk("function f() { let = 1; }");
+CheckOk("for (let = 1; let < 1; let++) {}");
diff --git a/test/mjsunit/harmony/classes.js b/test/mjsunit/harmony/classes.js
new file mode 100644
index 0000000..29ffbf8
--- /dev/null
+++ b/test/mjsunit/harmony/classes.js
@@ -0,0 +1,879 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-classes --harmony-sloppy
+
+(function TestBasics() {
+  var C = class C {}
+  assertEquals(typeof C, 'function');
+  assertEquals(C.__proto__, Function.prototype);
+  assertEquals(Object.prototype, Object.getPrototypeOf(C.prototype));
+  assertEquals(Function.prototype, Object.getPrototypeOf(C));
+  assertEquals('C', C.name);
+
+  class D {}
+  assertEquals(typeof D, 'function');
+  assertEquals(D.__proto__, Function.prototype);
+  assertEquals(Object.prototype, Object.getPrototypeOf(D.prototype));
+  assertEquals(Function.prototype, Object.getPrototypeOf(D));
+  assertEquals('D', D.name);
+
+  class D2 { constructor() {} }
+  assertEquals('D2', D2.name);
+
+  // TODO(arv): The logic for the name of anonymous functions in ES6 requires
+  // the below to be 'E';
+  var E = class {}
+  assertEquals('', E.name);  // Should be 'E'.
+
+  var F = class { constructor() {} };
+  assertEquals('', F.name);  // Should be 'F'.
+})();
+
+
+(function TestBasicsExtends() {
+  class C extends null {}
+  assertEquals(typeof C, 'function');
+  assertEquals(C.__proto__, Function.prototype);
+  assertEquals(null, Object.getPrototypeOf(C.prototype));
+
+  class D extends C {}
+  assertEquals(typeof D, 'function');
+  assertEquals(D.__proto__, C);
+  assertEquals(C.prototype, Object.getPrototypeOf(D.prototype));
+})();
+
+
+(function TestSideEffectInExtends() {
+  var calls = 0;
+  class C {}
+  class D extends (calls++, C) {}
+  assertEquals(1, calls);
+  assertEquals(typeof D, 'function');
+  assertEquals(D.__proto__, C);
+  assertEquals(C.prototype, Object.getPrototypeOf(D.prototype));
+})();
+
+
+(function TestInvalidExtends() {
+  assertThrows(function() {
+    class C extends 42 {}
+  }, TypeError);
+
+  assertThrows(function() {
+    // Function but its .prototype is not null or a function.
+    class C extends Math.abs {}
+  }, TypeError);
+
+  assertThrows(function() {
+    Math.abs.prototype = 42;
+    class C extends Math.abs {}
+  }, TypeError);
+  delete Math.abs.prototype;
+})();
+
+
+(function TestConstructorProperty() {
+  class C {}
+  assertEquals(C, C.prototype.constructor);
+  var descr = Object.getOwnPropertyDescriptor(C.prototype, 'constructor');
+  assertTrue(descr.configurable);
+  assertFalse(descr.enumerable);
+  assertTrue(descr.writable);
+})();
+
+
+(function TestPrototypeProperty() {
+  class C {}
+  var descr = Object.getOwnPropertyDescriptor(C, 'prototype');
+  assertFalse(descr.configurable);
+  assertFalse(descr.enumerable);
+  assertFalse(descr.writable);
+})();
+
+
+(function TestConstructor() {
+  var count = 0;
+  class C {
+    constructor() {
+      assertEquals(Object.getPrototypeOf(this), C.prototype);
+      count++;
+    }
+  }
+  assertEquals(C, C.prototype.constructor);
+  var descr = Object.getOwnPropertyDescriptor(C.prototype, 'constructor');
+  assertTrue(descr.configurable);
+  assertFalse(descr.enumerable);
+  assertTrue(descr.writable);
+
+  var c = new C();
+  assertEquals(1, count);
+  assertEquals(Object.getPrototypeOf(c), C.prototype);
+})();
+
+
+(function TestImplicitConstructor() {
+  class C {}
+  var c = new C();
+  assertEquals(Object.getPrototypeOf(c), C.prototype);
+})();
+
+
+(function TestConstructorStrict() {
+  class C {
+    constructor() {
+      assertThrows(function() {
+        nonExistingBinding = 42;
+      }, ReferenceError);
+    }
+  }
+  new C();
+})();
+
+
+(function TestSuperInConstructor() {
+  var calls = 0;
+  class B {}
+  B.prototype.x = 42;
+
+  class C extends B {
+    constructor() {
+      calls++;
+      assertEquals(42, super.x);
+    }
+  }
+
+  new C;
+  assertEquals(1, calls);
+})();
+
+
+(function TestStrictMode() {
+  class C {}
+
+  with ({a: 1}) {
+    assertEquals(1, a);
+  }
+
+  assertThrows('class C extends function B() { with ({}); return B; }() {}',
+               SyntaxError);
+
+  var D = class extends function() {
+    arguments.caller;
+  } {};
+  assertThrows(function() {
+    Object.getPrototypeOf(D).arguments;
+  }, TypeError);
+  assertThrows(function() {
+    new D;
+  }, TypeError);
+})();
+
+
+(function TestToString() {
+  class C {}
+  assertEquals('class C {}', C.toString());
+
+  class D { constructor() { 42; } }
+  assertEquals('class D { constructor() { 42; } }', D.toString());
+
+  class E { x() { 42; } }
+  assertEquals('class E { x() { 42; } }', E.toString());
+})();
+
+
+function assertMethodDescriptor(object, name) {
+  var descr = Object.getOwnPropertyDescriptor(object, name);
+  assertTrue(descr.configurable);
+  assertTrue(descr.enumerable);
+  assertTrue(descr.writable);
+  assertEquals('function', typeof descr.value);
+  assertFalse('prototype' in descr.value);
+}
+
+
+function assertGetterDescriptor(object, name) {
+  var descr = Object.getOwnPropertyDescriptor(object, name);
+  assertTrue(descr.configurable);
+  assertTrue(descr.enumerable);
+  assertEquals('function', typeof descr.get);
+  assertEquals(undefined, descr.set);
+}
+
+
+function assertSetterDescriptor(object, name) {
+  var descr = Object.getOwnPropertyDescriptor(object, name);
+  assertTrue(descr.configurable);
+  assertTrue(descr.enumerable);
+  assertEquals(undefined, descr.get);
+  assertEquals('function', typeof descr.set);
+}
+
+
+function assertAccessorDescriptor(object, name) {
+  var descr = Object.getOwnPropertyDescriptor(object, name);
+  assertTrue(descr.configurable);
+  assertTrue(descr.enumerable);
+  assertEquals('function', typeof descr.get);
+  assertEquals('function', typeof descr.set);
+}
+
+
+(function TestMethods() {
+  class C {
+    method() { return 1; }
+    static staticMethod() { return 2; }
+    method2() { return 3; }
+    static staticMethod2() { return 4; }
+  }
+
+  assertMethodDescriptor(C.prototype, 'method');
+  assertMethodDescriptor(C.prototype, 'method2');
+  assertMethodDescriptor(C, 'staticMethod');
+  assertMethodDescriptor(C, 'staticMethod2');
+
+  assertEquals(1, new C().method());
+  assertEquals(2, C.staticMethod());
+  assertEquals(3, new C().method2());
+  assertEquals(4, C.staticMethod2());
+})();
+
+
+(function TestGetters() {
+  class C {
+    get x() { return 1; }
+    static get staticX() { return 2; }
+    get y() { return 3; }
+    static get staticY() { return 4; }
+  }
+
+  assertGetterDescriptor(C.prototype, 'x');
+  assertGetterDescriptor(C.prototype, 'y');
+  assertGetterDescriptor(C, 'staticX');
+  assertGetterDescriptor(C, 'staticY');
+
+  assertEquals(1, new C().x);
+  assertEquals(2, C.staticX);
+  assertEquals(3, new C().y);
+  assertEquals(4, C.staticY);
+})();
+
+
+
+(function TestSetters() {
+  var x, staticX, y, staticY;
+  class C {
+    set x(v) { x = v; }
+    static set staticX(v) { staticX = v; }
+    set y(v) { y = v; }
+    static set staticY(v) { staticY = v; }
+  }
+
+  assertSetterDescriptor(C.prototype, 'x');
+  assertSetterDescriptor(C.prototype, 'y');
+  assertSetterDescriptor(C, 'staticX');
+  assertSetterDescriptor(C, 'staticY');
+
+  assertEquals(1, new C().x = 1);
+  assertEquals(1, x);
+  assertEquals(2, C.staticX = 2);
+  assertEquals(2, staticX);
+  assertEquals(3, new C().y = 3);
+  assertEquals(3, y);
+  assertEquals(4, C.staticY = 4);
+  assertEquals(4, staticY);
+})();
+
+
+(function TestSideEffectsInPropertyDefine() {
+  function B() {}
+  B.prototype = {
+    constructor: B,
+    set m(v) {
+      throw Error();
+    }
+  };
+
+  class C extends B {
+    m() { return 1; }
+  }
+
+  assertEquals(1, new C().m());
+})();
+
+
+(function TestAccessors() {
+  class C {
+    constructor(x) {
+      this._x = x;
+    }
+
+    get x() { return this._x; }
+    set x(v) { this._x = v; }
+
+    static get staticX() { return this._x; }
+    static set staticX(v) { this._x = v; }
+  }
+
+  assertAccessorDescriptor(C.prototype, 'x');
+  assertAccessorDescriptor(C, 'staticX');
+
+  var c = new C(1);
+  c._x = 1;
+  assertEquals(1, c.x);
+  c.x = 2;
+  assertEquals(2, c._x);
+
+  C._x = 3;
+  assertEquals(3, C.staticX);
+  C._x = 4;
+  assertEquals(4, C.staticX );
+})();
+
+
+(function TestProto() {
+  class C {
+    __proto__() { return 1; }
+  }
+  assertMethodDescriptor(C.prototype, '__proto__');
+  assertEquals(1, new C().__proto__());
+})();
+
+
+(function TestProtoStatic() {
+  class C {
+    static __proto__() { return 1; }
+  }
+  assertMethodDescriptor(C, '__proto__');
+  assertEquals(1, C.__proto__());
+})();
+
+
+(function TestProtoAccessor() {
+  class C {
+    get __proto__() { return this._p; }
+    set __proto__(v) { this._p = v; }
+  }
+  assertAccessorDescriptor(C.prototype, '__proto__');
+  var c = new C();
+  c._p = 1;
+  assertEquals(1, c.__proto__);
+  c.__proto__ = 2;
+  assertEquals(2, c.__proto__);
+})();
+
+
+(function TestStaticProtoAccessor() {
+  class C {
+    static get __proto__() { return this._p; }
+    static set __proto__(v) { this._p = v; }
+  }
+  assertAccessorDescriptor(C, '__proto__');
+  C._p = 1;
+  assertEquals(1, C.__proto__);
+  C.__proto__ = 2;
+  assertEquals(2, C.__proto__);
+})();
+
+
+(function TestSettersOnProto() {
+  function Base() {}
+  Base.prototype = {
+    set constructor(_) {
+      assertUnreachable();
+    },
+    set m(_) {
+      assertUnreachable();
+    }
+  };
+  Object.defineProperty(Base, 'staticM', {
+    set: function() {
+      assertUnreachable();
+    }
+  });
+
+  class C extends Base {
+    m() {
+      return 1;
+    }
+    static staticM() {
+      return 2;
+    }
+  }
+
+  assertEquals(1, new C().m());
+  assertEquals(2, C.staticM());
+})();
+
+
+(function TestConstructableButNoPrototype() {
+  var Base = function() {}.bind();
+  assertThrows(function() {
+    class C extends Base {}
+  }, TypeError);
+})();
+
+
+(function TestPrototypeGetter() {
+  var calls = 0;
+  var Base = function() {}.bind();
+  Object.defineProperty(Base, 'prototype', {
+    get: function() {
+      calls++;
+      return null;
+    },
+    configurable: true
+  });
+  class C extends Base {}
+  assertEquals(1, calls);
+
+  calls = 0;
+  Object.defineProperty(Base, 'prototype', {
+    get: function() {
+      calls++;
+      return 42;
+    },
+    configurable: true
+  });
+  assertThrows(function() {
+    class C extends Base {}
+  }, TypeError);
+  assertEquals(1, calls);
+})();
+
+
+(function TestPrototypeSetter() {
+  var Base = function() {}.bind();
+  Object.defineProperty(Base, 'prototype', {
+    set: function() {
+      assertUnreachable();
+    }
+  });
+  assertThrows(function() {
+    class C extends Base {}
+  }, TypeError);
+})();
+
+
+(function TestSuperInMethods() {
+  class B {
+    method() {
+      return 1;
+    }
+    get x() {
+      return 2;
+    }
+  }
+  class C extends B {
+    method() {
+      assertEquals(2, super.x);
+      return super.method();
+    }
+  }
+  assertEquals(1, new C().method());
+})();
+
+
+(function TestSuperInGetter() {
+  class B {
+    method() {
+      return 1;
+    }
+    get x() {
+      return 2;
+    }
+  }
+  class C extends B {
+    get y() {
+      assertEquals(2, super.x);
+      return super.method();
+    }
+  }
+  assertEquals(1, new C().y);
+})();
+
+
+(function TestSuperInSetter() {
+  class B {
+    method() {
+      return 1;
+    }
+    get x() {
+      return 2;
+    }
+  }
+  class C extends B {
+    set y(v) {
+      assertEquals(3, v);
+      assertEquals(2, super.x);
+      assertEquals(1, super.method());
+    }
+  }
+  assertEquals(3, new C().y = 3);
+})();
+
+
+(function TestSuperInStaticMethods() {
+  class B {
+    static method() {
+      return 1;
+    }
+    static get x() {
+      return 2;
+    }
+  }
+  class C extends B {
+    static method() {
+      assertEquals(2, super.x);
+      return super.method();
+    }
+  }
+  assertEquals(1, C.method());
+})();
+
+
+(function TestSuperInStaticGetter() {
+  class B {
+    static method() {
+      return 1;
+    }
+    static get x() {
+      return 2;
+    }
+  }
+  class C extends B {
+    static get x() {
+      assertEquals(2, super.x);
+      return super.method();
+    }
+  }
+  assertEquals(1, C.x);
+})();
+
+
+(function TestSuperInStaticSetter() {
+  class B {
+    static method() {
+      return 1;
+    }
+    static get x() {
+      return 2;
+    }
+  }
+  class C extends B {
+    static set x(v) {
+      assertEquals(3, v);
+      assertEquals(2, super.x);
+      assertEquals(1, super.method());
+    }
+  }
+  assertEquals(3, C.x = 3);
+})();
+
+
+(function TestNumericPropertyNames() {
+  class B {
+    1() { return 1; }
+    get 2() { return 2; }
+    set 3(_) {}
+
+    static 4() { return 4; }
+    static get 5() { return 5; }
+    static set 6(_) {}
+  }
+
+  assertMethodDescriptor(B.prototype, '1');
+  assertGetterDescriptor(B.prototype, '2');
+  assertSetterDescriptor(B.prototype, '3');
+
+  assertMethodDescriptor(B, '4');
+  assertGetterDescriptor(B, '5');
+  assertSetterDescriptor(B, '6');
+
+  class C extends B {
+    1() { return super[1](); }
+    get 2() { return super[2]; }
+
+    static 4() { return super[4](); }
+    static get 5() { return super[5]; }
+  }
+
+  assertEquals(1, new C()[1]());
+  assertEquals(2, new C()[2]);
+  assertEquals(4, C[4]());
+  assertEquals(5, C[5]);
+})();
+
+
+(function TestDefaultConstructorNoCrash() {
+  // Regression test for https://code.google.com/p/v8/issues/detail?id=3661
+  class C {}
+  assertEquals(undefined, C());
+  assertEquals(undefined, C(1));
+  assertTrue(new C() instanceof C);
+  assertTrue(new C(1) instanceof C);
+})();
+
+
+(function TestDefaultConstructor() {
+  var calls = 0;
+  class Base {
+    constructor() {
+      calls++;
+    }
+  }
+  class Derived extends Base {}
+  var object = new Derived;
+  assertEquals(1, calls);
+
+  calls = 0;
+  Derived();
+  assertEquals(1, calls);
+})();
+
+
+(function TestDefaultConstructorArguments() {
+  var args, self;
+  class Base {
+    constructor() {
+      self = this;
+      args = arguments;
+    }
+  }
+  class Derived extends Base {}
+
+  new Derived;
+  assertEquals(0, args.length);
+
+  new Derived(0, 1, 2);
+  assertEquals(3, args.length);
+  assertTrue(self instanceof Derived);
+
+  var arr = new Array(100);
+  var obj = {};
+  Derived.apply(obj, arr);
+  assertEquals(100, args.length);
+  assertEquals(obj, self);
+})();
+
+
+(function TestDefaultConstructorArguments2() {
+  var args;
+  class Base {
+    constructor(x, y) {
+      args = arguments;
+    }
+  }
+  class Derived extends Base {}
+
+  new Derived;
+  assertEquals(0, args.length);
+
+  new Derived(1);
+  assertEquals(1, args.length);
+  assertEquals(1, args[0]);
+
+  new Derived(1, 2, 3);
+  assertEquals(3, args.length);
+  assertEquals(1, args[0]);
+  assertEquals(2, args[1]);
+  assertEquals(3, args[2]);
+})();
+
+
+(function TestNameBindingConst() {
+  assertThrows('class C { constructor() { C = 42; } }; new C();', TypeError);
+  assertThrows('new (class C { constructor() { C = 42; } })', TypeError);
+  assertThrows('class C { m() { C = 42; } }; new C().m()', TypeError);
+  assertThrows('new (class C { m() { C = 42; } }).m()', TypeError);
+  assertThrows('class C { get x() { C = 42; } }; new C().x', TypeError);
+  assertThrows('(new (class C { get x() { C = 42; } })).x', TypeError);
+  assertThrows('class C { set x(_) { C = 42; } }; new C().x = 15;', TypeError);
+  assertThrows('(new (class C { set x(_) { C = 42; } })).x = 15;', TypeError);
+})();
+
+
+(function TestNameBinding() {
+  var C2;
+  class C {
+    constructor() {
+      C2 = C;
+    }
+    m() {
+      C2 = C;
+    }
+    get x() {
+      C2 = C;
+    }
+    set x(_) {
+      C2 = C;
+    }
+  }
+  new C();
+  assertEquals(C, C2);
+
+  C2 = undefined;
+  new C().m();
+  assertEquals(C, C2);
+
+  C2 = undefined;
+  new C().x;
+  assertEquals(C, C2);
+
+  C2 = undefined;
+  new C().x = 1;
+  assertEquals(C, C2);
+})();
+
+
+(function TestNameBindingExpression() {
+  var C3;
+  var C = class C2 {
+    constructor() {
+      assertEquals(C2, C);
+      C3 = C2;
+    }
+    m() {
+      assertEquals(C2, C);
+      C3 = C2;
+    }
+    get x() {
+      assertEquals(C2, C);
+      C3 = C2;
+    }
+    set x(_) {
+      assertEquals(C2, C);
+      C3 = C2;
+    }
+  }
+  new C();
+  assertEquals(C, C3);
+
+  C3 = undefined;
+  new C().m();
+  assertEquals(C, C3);
+
+  C3 = undefined;
+  new C().x;
+  assertEquals(C, C3);
+
+  C3 = undefined;
+  new C().x = 1;
+  assertEquals(C, C3);
+})();
+
+
+(function TestNameBindingInExtendsExpression() {
+  assertThrows(function() {
+    class x extends x {}
+  }, ReferenceError);
+
+  assertThrows(function() {
+    (class x extends x {});
+  }, ReferenceError);
+
+  assertThrows(function() {
+    var x = (class x extends x {});
+  }, ReferenceError);
+})();
+
+
+(function TestSuperCallSyntacticRestriction() {
+  assertThrows(function() {
+    class C {
+      constructor() {
+        var y;
+        super();
+      }
+    }; new C();
+  }, TypeError);
+  assertThrows(function() {
+    class C {
+      constructor() {
+        super(this.x);
+      }
+    }; new C();
+  }, TypeError);
+  assertThrows(function() {
+    class C {
+      constructor() {
+        super(this);
+      }
+    }; new C();
+  }, TypeError);
+  assertThrows(function() {
+    class C {
+      constructor() {
+        super.method();
+        super(this);
+      }
+    }; new C();
+  }, TypeError);
+  assertThrows(function() {
+    class C {
+      constructor() {
+        super(super.method());
+      }
+    }; new C();
+  }, TypeError);
+  assertThrows(function() {
+    class C {
+      constructor() {
+        super(super());
+      }
+    }; new C();
+  }, TypeError);
+  assertThrows(function() {
+    class C {
+      constructor() {
+        super(1, 2, Object.getPrototypeOf(this));
+      }
+    }; new C();
+  }, TypeError);
+  assertThrows(function() {
+    class C {
+      constructor() {
+        { super(1, 2); }
+      }
+    }; new C();
+  }, TypeError);
+  assertThrows(function() {
+    class C {
+      constructor() {
+        if (1) super();
+      }
+    }; new C();
+  }, TypeError);
+
+  class C1 extends Object {
+    constructor() {
+      'use strict';
+      super();
+    }
+  };
+  new C1();
+
+  class C2 extends Object {
+    constructor() {
+      ; 'use strict';;;;;
+      super();
+    }
+  };
+  new C2();
+
+  class C3 extends Object {
+    constructor() {
+      ; 'use strict';;;;;
+      // This is a comment.
+      super();
+    }
+  };
+  new C3();
+
+  class C4 extends Object {
+    constructor() {
+      super(new super());
+    }
+  }; new C4();
+}());
diff --git a/test/mjsunit/harmony/debug-blockscopes.js b/test/mjsunit/harmony/debug-blockscopes.js
index 2db4942..8180377 100644
--- a/test/mjsunit/harmony/debug-blockscopes.js
+++ b/test/mjsunit/harmony/debug-blockscopes.js
@@ -73,7 +73,7 @@
 // Check result of a test.
 function EndTest() {
   assertTrue(listener_called, "listerner not called for " + test_name);
-  assertNull(exception, test_name);
+  assertNull(exception, test_name, exception);
   end_test_count++;
 }
 
@@ -108,6 +108,7 @@
     assertEquals(i, response.body.scopes[i].index);
     assertEquals(scopes[i], response.body.scopes[i].type);
     if (scopes[i] == debug.ScopeType.Local ||
+        scopes[i] == debug.ScopeType.Script ||
         scopes[i] == debug.ScopeType.Closure) {
       assertTrue(response.body.scopes[i].object.ref < 0);
     } else {
@@ -197,6 +198,7 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({}, 0, exec_state);
 };
@@ -215,6 +217,7 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1}, 0, exec_state);
 };
@@ -232,6 +235,7 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1,x:3}, 0, exec_state);
 };
@@ -250,6 +254,7 @@
 
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({a:1,b:2,x:3,y:4}, 0, exec_state);
 };
@@ -270,6 +275,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Block,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x:5}, 0, exec_state);
   CheckScopeContent({a:1}, 1, exec_state);
@@ -292,6 +298,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Block,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x:6,y:7}, 0, exec_state);
   CheckScopeContent({a:1}, 1, exec_state);
@@ -315,6 +322,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Block,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x:8}, 0, exec_state);
   CheckScopeContent({a:1}, 1, exec_state);
@@ -344,6 +352,7 @@
   CheckScopeChain([debug.ScopeType.Local,
                    debug.ScopeType.Block,
                    debug.ScopeType.Closure,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({}, 0, exec_state);
   CheckScopeContent({a:1,x:2,y:3}, 2, exec_state);
@@ -364,6 +373,7 @@
 listener_delegate = function(exec_state) {
   CheckScopeChain([debug.ScopeType.Block,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x:'y'}, 0, exec_state);
   // The function scope contains a temporary iteration variable, but it is
@@ -389,6 +399,7 @@
   CheckScopeChain([debug.ScopeType.Block,
                    debug.ScopeType.Block,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x:3}, 0, exec_state);
   CheckScopeContent({x:'y'}, 1, exec_state);
@@ -413,6 +424,7 @@
   CheckScopeChain([debug.ScopeType.Block,
                    debug.ScopeType.Block,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x:3}, 0, exec_state);
   CheckScopeContent({x:3}, 1, exec_state);
@@ -437,6 +449,7 @@
                    debug.ScopeType.Block,
                    debug.ScopeType.Block,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x:5}, 0, exec_state);
   CheckScopeContent({x:3}, 1, exec_state);
@@ -460,6 +473,7 @@
   CheckScopeChain([debug.ScopeType.Block,
                    debug.ScopeType.Block,
                    debug.ScopeType.Local,
+                   debug.ScopeType.Script,
                    debug.ScopeType.Global], exec_state);
   CheckScopeContent({x:3,y:5}, 0, exec_state);
   CheckScopeContent({x:3,y:5}, 1, exec_state);
@@ -467,3 +481,24 @@
 };
 for_loop_5();
 EndTest();
+
+
+// Uninitialized variables
+BeginTest("Uninitialized 1");
+
+function uninitialized_1() {
+  {
+    debugger;
+    let x = 1;
+  }
+}
+
+listener_delegate = function(exec_state) {
+  CheckScopeChain([debug.ScopeType.Block,
+                   debug.ScopeType.Local,
+                   debug.ScopeType.Script,
+                   debug.ScopeType.Global], exec_state);
+  CheckScopeContent({}, 0, exec_state);
+};
+uninitialized_1();
+EndTest();
diff --git a/test/mjsunit/harmony/debug-evaluate-blockscopes.js b/test/mjsunit/harmony/debug-evaluate-blockscopes.js
index 16885d0..d133cc0 100644
--- a/test/mjsunit/harmony/debug-evaluate-blockscopes.js
+++ b/test/mjsunit/harmony/debug-evaluate-blockscopes.js
@@ -67,3 +67,43 @@
 Debug.clearBreakPoint(bp);
 // Get rid of the debug event listener.
 Debug.setListener(null);
+
+
+function f1() {
+  {
+    let i = 1;
+    debugger;
+    assertEquals(2, i);
+  }
+}
+
+function f2() {
+  {
+    let i = 1;
+    debugger;
+    assertEquals(2, i);
+    return function() { return i++; }
+  }
+}
+
+var exception;
+Debug.setListener(function (event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      var frame = exec_state.frame();
+      assertEquals(1, frame.evaluate("i").value());
+      var allScopes = frame.allScopes();
+      assertEquals(1, allScopes[0].scopeObject().value().i);
+      allScopes[0].setVariableValue("i", 2);
+    }
+  } catch (e) {
+    exception = e;
+  }
+});
+
+exception = null;
+f1();
+assertEquals(null, exception, exception);
+exception = null;
+f2();
+assertEquals(null, exception, exception);
diff --git a/test/mjsunit/harmony/debug-function-scopes.js b/test/mjsunit/harmony/debug-function-scopes.js
index 0113be6..1b380c2 100644
--- a/test/mjsunit/harmony/debug-function-scopes.js
+++ b/test/mjsunit/harmony/debug-function-scopes.js
@@ -28,6 +28,7 @@
 // Flags: --expose-debug-as debug --harmony-scoping
 
 "use strict";
+let top_level_let = 255;
 
 // Get the Debug object exposed from the debug context global object.
 var Debug = debug.Debug;
@@ -50,7 +51,8 @@
                   With: 2,
                   Closure: 3,
                   Catch: 4,
-                  Block: 5 };
+                  Block: 5,
+                  Script: 6};
 
 var f1 = (function F1(x) {
   function F2(y) {
@@ -72,12 +74,13 @@
 
 var mirror = Debug.MakeMirror(f1);
 
-assertEquals(4, mirror.scopeCount());
+assertEquals(5, 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);
+CheckScope(mirror.scope(3), { top_level_let: 255 }, ScopeType.Script);
+CheckScope(mirror.scope(4), {}, ScopeType.Global);
 
 var f2 = (function() {
   var v1 = 3;
@@ -104,7 +107,7 @@
 
 var mirror = Debug.MakeMirror(f2);
 
-assertEquals(5, mirror.scopeCount());
+assertEquals(6, mirror.scopeCount());
 
 // Implementation artifact: l4 isn't used in closure, but still it is saved.
 CheckScope(mirror.scope(0), { l4: 11 }, ScopeType.Block);
@@ -112,4 +115,5 @@
 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);
+CheckScope(mirror.scope(4), { top_level_let: 255 }, ScopeType.Script);
+CheckScope(mirror.scope(5), {}, ScopeType.Global);
diff --git a/test/mjsunit/harmony/debug-step-into-class-extends.js b/test/mjsunit/harmony/debug-step-into-class-extends.js
new file mode 100644
index 0000000..ffc6fda
--- /dev/null
+++ b/test/mjsunit/harmony/debug-step-into-class-extends.js
@@ -0,0 +1,42 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --harmony-classes
+
+'use strict';
+
+var Debug = debug.Debug
+
+var done = false;
+var stepCount = 0;
+
+function listener(event, execState, eventData, data) {
+  if (event == Debug.DebugEvent.Break) {
+    if (!done) {
+      execState.prepareStep(Debug.StepAction.StepInto);
+      var s = execState.frame().sourceLineText();
+      assertTrue(s.indexOf('// ' + stepCount + '.') !== -1);
+      stepCount++;
+    }
+  }
+};
+
+Debug.setListener(listener);
+
+function GetBase() {
+  var x = 1;   // 1.
+  var y = 2;   // 2.
+  done = true; // 3.
+  return null;
+}
+
+function f() {
+  class Derived extends GetBase() {} // 0.
+}
+
+var bp = Debug.setBreakPoint(f, 0);
+f();
+assertEquals(4, stepCount);
+
+Debug.setListener(null);
diff --git a/test/mjsunit/harmony/debug-step-into-constructor.js b/test/mjsunit/harmony/debug-step-into-constructor.js
new file mode 100644
index 0000000..dbef60f
--- /dev/null
+++ b/test/mjsunit/harmony/debug-step-into-constructor.js
@@ -0,0 +1,113 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --harmony-classes
+
+'use strict';
+
+var Debug = debug.Debug
+var done, stepCount;
+
+function listener(event, execState, eventData, data) {
+  if (event == Debug.DebugEvent.Break) {
+    if (!done) {
+      execState.prepareStep(Debug.StepAction.StepInto);
+      var s = execState.frame().sourceLineText();
+      assertTrue(s.indexOf('// ' + stepCount + '.') !== -1);
+      stepCount++;
+    }
+  }
+};
+
+Debug.setListener(listener);
+
+
+class Base {
+  constructor() {
+    var x = 1;   // 1.
+    var y = 2;   // 2.
+    done = true; // 3.
+  }
+}
+
+class Derived extends Base {}
+
+
+(function TestBreakPointInConstructor() {
+  done = false;
+  stepCount = 1;
+  var bp = Debug.setBreakPoint(Base, 0);
+
+  new Base();
+  assertEquals(4, stepCount);
+
+  Debug.clearBreakPoint(bp);
+})();
+
+
+(function TestDefaultConstructor() {
+  done = false;
+  stepCount = 1;
+
+  var bp = Debug.setBreakPoint(Base, 0);
+  new Derived();
+  assertEquals(4, stepCount);
+
+  Debug.clearBreakPoint(bp);
+})();
+
+
+(function TestStepInto() {
+  done = false;
+  stepCount = 0;
+
+  function f() {
+    new Derived();  // 0.
+  }
+
+  var bp = Debug.setBreakPoint(f, 0);
+  f();
+  assertEquals(4, stepCount);
+
+  Debug.clearBreakPoint(bp);
+})();
+
+
+(function TestExtraIndirection() {
+  done = false;
+  stepCount = 0;
+
+  class Derived2 extends Derived {}
+
+  function f() {
+    new Derived2();  // 0.
+  }
+
+  var bp = Debug.setBreakPoint(f, 0);
+  f();
+  assertEquals(4, stepCount);
+
+  Debug.clearBreakPoint(bp);
+})();
+
+
+(function TestBoundClass() {
+  done = false;
+  stepCount = 0;
+
+  var bound = Derived.bind(null);
+
+  function f() {
+    new bound();  // 0.
+  }
+
+  var bp = Debug.setBreakPoint(f, 0);
+  f();
+  assertEquals(4, stepCount);
+
+  Debug.clearBreakPoint(bp);
+})();
+
+
+Debug.setListener(null);
diff --git a/test/mjsunit/harmony/disable-harmony-string.js b/test/mjsunit/harmony/disable-harmony-string.js
new file mode 100644
index 0000000..0b88ae0
--- /dev/null
+++ b/test/mjsunit/harmony/disable-harmony-string.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --noharmony-strings
+
+assertEquals(undefined, String.prototype.includes);
diff --git a/test/mjsunit/harmony/module-linking.js b/test/mjsunit/harmony/module-linking.js
index 3c0f18c..3a5bc89 100644
--- a/test/mjsunit/harmony/module-linking.js
+++ b/test/mjsunit/harmony/module-linking.js
@@ -109,7 +109,7 @@
   assertThrows(function() { l }, ReferenceError)
   assertThrows(function() { R.l }, ReferenceError)
 
-  assertThrows(function() { eval("c = -1") }, SyntaxError)
+  assertThrows(function() { eval("c = -1") }, TypeError)
   assertThrows(function() { R.c = -2 }, TypeError)
 
   // Initialize first bunch of variables.
@@ -129,7 +129,7 @@
   assertEquals(-4, R.v = -4)
   assertEquals(-3, l = -3)
   assertEquals(-4, R.l = -4)
-  assertThrows(function() { eval("c = -3") }, SyntaxError)
+  assertThrows(function() { eval("c = -3") }, TypeError)
   assertThrows(function() { R.c = -4 }, TypeError)
 
   assertEquals(-4, v)
diff --git a/test/mjsunit/harmony/numeric-literals-off.js b/test/mjsunit/harmony/numeric-literals-off.js
deleted file mode 100644
index 37204ed..0000000
--- a/test/mjsunit/harmony/numeric-literals-off.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-//       notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-//       copyright notice, this list of conditions and the following
-//       disclaimer in the documentation and/or other materials provided
-//       with the distribution.
-//     * Neither the name of Google Inc. nor the names of its
-//       contributors may be used to endorse or promote products derived
-//       from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This is to ensure that we do not support 0b and 0o in Number when
-// the --harmony-numeric-literals flag is not set.
-
-
-function TestOctalLiteralUsingNumberFunction() {
-  assertEquals(NaN, Number('0o0'));
-}
-TestOctalLiteralUsingNumberFunction();
-
-
-function TestBinaryLiteralUsingNumberFunction() {
-  assertEquals(NaN, Number('0b0'));
-}
-TestBinaryLiteralUsingNumberFunction();
diff --git a/test/mjsunit/harmony/object-literals-property-shorthand.js b/test/mjsunit/harmony/object-literals-property-shorthand.js
new file mode 100644
index 0000000..2921495
--- /dev/null
+++ b/test/mjsunit/harmony/object-literals-property-shorthand.js
@@ -0,0 +1,51 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-object-literals
+
+
+(function TestBasics() {
+  var x = 1;
+  var object = {x};
+  assertEquals(1, object.x);
+})();
+
+
+(function TestDescriptor() {
+  var x = 1;
+  var object = {x};
+  var descr = Object.getOwnPropertyDescriptor(object, 'x');
+  assertEquals(1, descr.value);
+  assertTrue(descr.enumerable);
+  assertTrue(descr.writable);
+  assertTrue(descr.configurable);
+})();
+
+
+(function TestNotDefined() {
+  'use strict';
+  assertThrows(function() {
+    return {notDefined};
+  }, ReferenceError);
+})();
+
+
+(function TestLet() {
+  var let = 1;
+  var object = {let};
+  assertEquals(1, object.let);
+})();
+
+
+(function TestYieldInFunction() {
+  var yield = 1;
+  var object = {yield};
+  assertEquals(1, object.yield);
+})();
+
+
+(function TestToString() {
+  function f(x) { return {x}; }
+  assertEquals('function f(x) { return {x}; }', f.toString());
+})();
diff --git a/test/mjsunit/harmony/object-literals-super.js b/test/mjsunit/harmony/object-literals-super.js
new file mode 100644
index 0000000..ec22b8a
--- /dev/null
+++ b/test/mjsunit/harmony/object-literals-super.js
@@ -0,0 +1,168 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-classes --allow-natives-syntax
+
+
+(function TestHomeObject() {
+  var object = {
+    method() {
+      return super.method();
+    },
+    get getter() {
+      return super.getter;
+    },
+    set setter(v) {
+      super.setter = v;
+    },
+    get accessor() {
+      return super.accessor;
+    },
+    set accessor(v) {
+      super.accessor = v;
+    },
+    property: function() {
+      super.property();
+    },
+    propertyWithParen: (function() {
+      super.property();
+    }),
+    propertyWithParens: ((function() {
+      super.property();
+    })),
+
+    methodNoSuper() {},
+    get getterNoSuper() {},
+    set setterNoSuper(v) {},
+    get accessorNoSuper() {},
+    set accessorNoSuper(v) {},
+    propertyNoSuper: function() {},
+    propertyWithParenNoSuper: (function() {}),
+    propertyWithParensNoSuper: ((function() {}))
+  };
+
+  assertEquals(object, object.method[%HomeObjectSymbol()]);
+  var desc = Object.getOwnPropertyDescriptor(object, 'getter');
+  assertEquals(object, desc.get[%HomeObjectSymbol()]);
+  desc = Object.getOwnPropertyDescriptor(object, 'setter');
+  assertEquals(object, desc.set[%HomeObjectSymbol()]);
+  desc = Object.getOwnPropertyDescriptor(object, 'accessor');
+  assertEquals(object, desc.get[%HomeObjectSymbol()]);
+  assertEquals(object, desc.set[%HomeObjectSymbol()]);
+  assertEquals(object, object.property[%HomeObjectSymbol()]);
+  assertEquals(object, object.propertyWithParen[%HomeObjectSymbol()]);
+  assertEquals(object, object.propertyWithParens[%HomeObjectSymbol()]);
+
+  assertEquals(undefined, object.methodNoSuper[%HomeObjectSymbol()]);
+  desc = Object.getOwnPropertyDescriptor(object, 'getterNoSuper');
+  assertEquals(undefined, desc.get[%HomeObjectSymbol()]);
+  desc = Object.getOwnPropertyDescriptor(object, 'setterNoSuper');
+  assertEquals(undefined, desc.set[%HomeObjectSymbol()]);
+  desc = Object.getOwnPropertyDescriptor(object, 'accessorNoSuper');
+  assertEquals(undefined, desc.get[%HomeObjectSymbol()]);
+  assertEquals(undefined, desc.set[%HomeObjectSymbol()]);
+  assertEquals(undefined, object.propertyNoSuper[%HomeObjectSymbol()]);
+  assertEquals(undefined, object.propertyWithParenNoSuper[%HomeObjectSymbol()]);
+  assertEquals(undefined,
+               object.propertyWithParensNoSuper[%HomeObjectSymbol()]);
+})();
+
+
+(function TestMethod() {
+  var object = {
+    __proto__: {
+      method(x) {
+        return 'proto' + x;
+      }
+    },
+    method(x) {
+      return super.method(x);
+    }
+  };
+  assertEquals('proto42', object.method(42));
+})();
+
+
+(function TestGetter() {
+  var object = {
+    __proto__: {
+      _x: 42,
+      get x() {
+        return 'proto' + this._x;
+      }
+    },
+    get x() {
+      return super.x;
+    }
+  };
+  assertEquals('proto42', object.x);
+})();
+
+
+(function TestSetter() {
+  var object = {
+    __proto__: {
+      _x: 0,
+      set x(v) {
+        return this._x = v;
+      }
+    },
+    set x(v) {
+      super.x = v;
+    }
+  };
+  assertEquals(1, object.x = 1);
+  assertEquals(1, object._x);
+  assertEquals(0, Object.getPrototypeOf(object)._x);
+})();
+
+
+(function TestMethodAsProperty() {
+  var object = {
+    __proto__: {
+      method: function(x) {
+        return 'proto' + x;
+      }
+    },
+    method: function(x) {
+      return super.method(x);
+    }
+  };
+  assertEquals('proto42', object.method(42));
+})();
+
+
+(function TestOptimized() {
+  // Object literals without any accessors get optimized.
+  var object = {
+    method() {
+      return super.toString;
+    }
+  };
+  assertEquals(Object.prototype.toString, object.method());
+})();
+
+
+(function TestConciseGenerator() {
+  var o = {
+    __proto__: {
+      m() {
+        return 42;
+      }
+    },
+    *g() {
+      yield super.m();
+    },
+    g2: function*() {
+      yield super.m() + 1;
+    },
+    g3: (function*() {
+      yield super.m() + 2;
+    })
+  };
+
+  assertEquals(42, o.g().next().value);
+  assertEquals(43, o.g2().next().value);
+  assertEquals(44, o.g3().next().value);
+})();
diff --git a/test/mjsunit/harmony/proxies-with-unscopables.js b/test/mjsunit/harmony/proxies-with-unscopables.js
index 191bad3..8a03ef4 100644
--- a/test/mjsunit/harmony/proxies-with-unscopables.js
+++ b/test/mjsunit/harmony/proxies-with-unscopables.js
@@ -74,12 +74,17 @@
   var calls = 0;
   var proxy = Proxy.create({
     has: function(key) {
-      calls++;
-      assertEquals('x', key);
-      return calls === 2;
+      assertUnreachable();
     },
     getPropertyDescriptor: function(key) {
-      assertUnreachable();
+      calls++;
+      assertEquals('x', key);
+      return {
+        value: calls === 2 ? true : undefined,
+        configurable: true,
+        enumerable: true,
+        writable: true,
+      };
     }
   });
 
@@ -107,12 +112,12 @@
   var calls = 0;
   var proxy = Proxy.create({
     has: function(key) {
-      if (calls++ === 0) {
-        throw new CustomError();
-      }
       assertUnreachable();
     },
     getPropertyDescriptor: function(key) {
+      if (calls++ === 0) {
+        throw new CustomError();
+      }
       assertUnreachable();
     }
   });
diff --git a/test/mjsunit/harmony/proxies.js b/test/mjsunit/harmony/proxies.js
index b082c06..2b0ec76 100644
--- a/test/mjsunit/harmony/proxies.js
+++ b/test/mjsunit/harmony/proxies.js
@@ -29,7 +29,7 @@
 // test enters an infinite recursion which goes through the runtime and we
 // overflow the system stack before the simulator stack.
 
-// Flags: --harmony-proxies --sim-stack-size=500
+// Flags: --harmony-proxies --sim-stack-size=500 --turbo-deoptimization
 
 
 // Helper.
diff --git a/test/mjsunit/harmony/regexp-flags.js b/test/mjsunit/harmony/regexp-flags.js
new file mode 100644
index 0000000..475fda4
--- /dev/null
+++ b/test/mjsunit/harmony/regexp-flags.js
@@ -0,0 +1,61 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-regexps
+
+RegExp.prototype.flags = 'setter should be undefined';
+
+assertEquals('', RegExp('').flags);
+assertEquals('', /./.flags);
+assertEquals('gimy', RegExp('', 'ygmi').flags);
+assertEquals('gimy', /foo/ymig.flags);
+
+// TODO(dslomov): When support for the `u` flag is added, uncomment the first
+// line below and remove the second line.
+//assertEquals(RegExp('', 'yumig').flags, 'gimuy');
+assertThrows(function() { RegExp('', 'yumig').flags; }, SyntaxError);
+
+var descriptor = Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags');
+assertTrue(descriptor.configurable);
+assertFalse(descriptor.enumerable);
+assertInstanceof(descriptor.get, Function);
+assertEquals(undefined, descriptor.set);
+
+function testGenericFlags(object) {
+  return descriptor.get.call(object);
+}
+
+assertEquals('', testGenericFlags({}));
+assertEquals('i', testGenericFlags({ ignoreCase: true }));
+assertEquals('uy', testGenericFlags({ global: 0, sticky: 1, unicode: 1 }));
+assertEquals('m', testGenericFlags({ __proto__: { multiline: true } }));
+assertThrows(function() { testGenericFlags(); }, TypeError);
+assertThrows(function() { testGenericFlags(undefined); }, TypeError);
+assertThrows(function() { testGenericFlags(null); }, TypeError);
+assertThrows(function() { testGenericFlags(true); }, TypeError);
+assertThrows(function() { testGenericFlags(false); }, TypeError);
+assertThrows(function() { testGenericFlags(''); }, TypeError);
+assertThrows(function() { testGenericFlags(42); }, TypeError);
+
+var counter = 0;
+var map = {};
+var object = {
+  get global() {
+    map.g = counter++;
+  },
+  get ignoreCase() {
+    map.i = counter++;
+  },
+  get multiline() {
+    map.m = counter++;
+  },
+  get unicode() {
+    map.u = counter++;
+  },
+  get sticky() {
+    map.y = counter++;
+  }
+};
+testGenericFlags(object);
+assertEquals({ g: 0, i: 1, m: 2, u: 3, y: 4 }, map);
diff --git a/test/mjsunit/harmony/regress/regress-2243.js b/test/mjsunit/harmony/regress/regress-2243.js
index 31c2e55..e2411d2 100644
--- a/test/mjsunit/harmony/regress/regress-2243.js
+++ b/test/mjsunit/harmony/regress/regress-2243.js
@@ -27,5 +27,5 @@
 
 // Flags: --harmony-scoping
 
-assertThrows("'use strict'; (function f() { f = 123; })", SyntaxError);
-assertThrows("(function f() { 'use strict'; f = 123; })", SyntaxError);
+assertThrows("'use strict'; (function f() { f = 123; })()", TypeError);
+assertThrows("(function f() { 'use strict'; f = 123; })()", TypeError);
diff --git a/test/mjsunit/harmony/regress/regress-2858.js b/test/mjsunit/harmony/regress/regress-2858.js
new file mode 100644
index 0000000..4ce9478
--- /dev/null
+++ b/test/mjsunit/harmony/regress/regress-2858.js
@@ -0,0 +1,27 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --harmony-scoping
+"use strict";
+
+function f() {
+    var y = 1;
+    var q1;
+    var q;
+    var z = new Error();
+    try {
+        throw z;
+    } catch (y) {
+      assertTrue(z === y);
+      q1 = function() { return y; }
+      var y = 15;
+      q = function() { return y; }
+      assertSame(15, y);
+    }
+    assertSame(1, y);
+    assertSame(15, q1());
+    assertSame(15, q());
+}
+
+f();
diff --git a/test/mjsunit/harmony/regress/regress-343928.js b/test/mjsunit/harmony/regress/regress-343928.js
index b102ab9..f2ff371 100644
--- a/test/mjsunit/harmony/regress/regress-343928.js
+++ b/test/mjsunit/harmony/regress/regress-343928.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Flags: --harmony --expose-debug-as=debug
+// Flags: --harmony-modules --expose-debug-as=debug
 
 (function () {  // Scope for utility functions.
   escaping_function = function(object) {
diff --git a/test/mjsunit/harmony/regress/regress-3683.js b/test/mjsunit/harmony/regress/regress-3683.js
new file mode 100644
index 0000000..a00d82b
--- /dev/null
+++ b/test/mjsunit/harmony/regress/regress-3683.js
@@ -0,0 +1,84 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --harmony-scoping
+
+"use strict";
+
+// Simplest case
+var count = 0;
+for (let x = 0; x < 10;) {
+  x++;
+  count++;
+  continue;
+}
+assertEquals(10, count);
+
+// Labeled
+count = 0;
+label: for (let x = 0; x < 10;) {
+  while (true) {
+    x++;
+    count++;
+    continue label;
+  }
+}
+assertEquals(10, count);
+
+// Simple and labeled
+count = 0;
+label: for (let x = 0; x < 10;) {
+  x++;
+  count++;
+  continue label;
+}
+assertEquals(10, count);
+
+// Shadowing loop variable in same scope as continue
+count = 0;
+for (let x = 0; x < 10;) {
+  x++;
+  count++;
+  {
+    let x = "hello";
+    continue;
+  }
+}
+assertEquals(10, count);
+
+// Nested let-bound for loops, inner continue
+count = 0;
+for (let x = 0; x < 10;) {
+  x++;
+  for (let y = 0; y < 2;) {
+    y++;
+    count++;
+    continue;
+  }
+}
+assertEquals(20, count);
+
+// Nested let-bound for loops, outer continue
+count = 0;
+for (let x = 0; x < 10;) {
+  x++;
+  for (let y = 0; y < 2;) {
+    y++;
+    count++;
+  }
+  continue;
+}
+assertEquals(20, count);
+
+// Nested let-bound for loops, labeled continue
+count = 0;
+outer: for (let x = 0; x < 10;) {
+  x++;
+  for (let y = 0; y < 2;) {
+    y++;
+    count++;
+    if (y == 2) continue outer;
+  }
+}
+assertEquals(20, count);
diff --git a/test/mjsunit/harmony/regress/regress-3741.js b/test/mjsunit/harmony/regress/regress-3741.js
new file mode 100644
index 0000000..8a9dd9e
--- /dev/null
+++ b/test/mjsunit/harmony/regress/regress-3741.js
@@ -0,0 +1,26 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --harmony-scoping --allow-natives-syntax
+'use strict';
+function f24(deopt) {
+  let x = 1;
+  {
+    let x = 2;
+    {
+      let x = 3;
+      assertEquals(3, x);
+    }
+    deopt + 1;
+    assertEquals(2, x);
+  }
+  assertEquals(1, x);
+}
+
+
+for (var j = 0; j < 10; ++j) {
+  f24(12);
+}
+%OptimizeFunctionOnNextCall(f24);
+f24({});
diff --git a/test/mjsunit/harmony/regress/regress-3750.js b/test/mjsunit/harmony/regress/regress-3750.js
new file mode 100644
index 0000000..d1f21f9
--- /dev/null
+++ b/test/mjsunit/harmony/regress/regress-3750.js
@@ -0,0 +1,8 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --harmony-classes
+'use strict';
+class Example { }
+Object.observe(Example.prototype, function(){});
diff --git a/test/mjsunit/harmony/string-contains.js b/test/mjsunit/harmony/string-contains.js
deleted file mode 100644
index b853ed9..0000000
--- a/test/mjsunit/harmony/string-contains.js
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * 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-strings
-
-assertEquals(1, String.prototype.contains.length);
-
-var reString = "asdf[a-z]+(asdf)?";
-assertTrue(reString.contains("[a-z]+"));
-assertTrue(reString.contains("(asdf)?"));
-
-// Random greek letters
-var twoByteString = "\u039a\u0391\u03a3\u03a3\u0395";
-
-// Test single char pattern
-assertTrue(twoByteString.contains("\u039a"), "Lamda");
-assertTrue(twoByteString.contains("\u0391"), "Alpha");
-assertTrue(twoByteString.contains("\u03a3"), "First Sigma");
-assertTrue(twoByteString.contains("\u03a3",3), "Second Sigma");
-assertTrue(twoByteString.contains("\u0395"), "Epsilon");
-assertFalse(twoByteString.contains("\u0392"), "Not beta");
-
-// Test multi-char pattern
-assertTrue(twoByteString.contains("\u039a\u0391"), "lambda Alpha");
-assertTrue(twoByteString.contains("\u0391\u03a3"), "Alpha Sigma");
-assertTrue(twoByteString.contains("\u03a3\u03a3"), "Sigma Sigma");
-assertTrue(twoByteString.contains("\u03a3\u0395"), "Sigma Epsilon");
-
-assertFalse(twoByteString.contains("\u0391\u03a3\u0395"),
-    "Not Alpha Sigma Epsilon");
-
-//single char pattern
-assertTrue(twoByteString.contains("\u0395"));
-
-assertThrows("String.prototype.contains.call(null, 'test')", TypeError);
-assertThrows("String.prototype.contains.call(null, null)", TypeError);
-assertThrows("String.prototype.contains.call(undefined, undefined)", TypeError);
-
-assertThrows("String.prototype.contains.apply(null, ['test'])", TypeError);
-assertThrows("String.prototype.contains.apply(null, [null])", TypeError);
-assertThrows("String.prototype.contains.apply(undefined, [undefined])", TypeError);
-
-var TEST_INPUT = [{
-  msg: "Empty string", val: ""
-}, {
-  msg: "Number 1234.34", val: 1234.34
-}, {
-  msg: "Integer number 0", val: 0
-}, {
-  msg: "Negative number -1", val: -1
-}, {
-  msg: "Boolean true", val: true
-}, {
-  msg: "Boolean false", val: false
-}, {
-  msg: "Empty array []", val: []
-}, {
-  msg: "Empty object {}", val: {}
-}, {
-  msg: "Array of size 3", val: new Array(3)
-}];
-
-var i = 0;
-var l = TEST_INPUT.length;
-
-for (; i < l; i++) {
-  var e = TEST_INPUT[i];
-  var v = e.val;
-  var s = String(v);
-  assertTrue(s.contains(v), e.msg);
-  assertTrue(String.prototype.contains.call(v, v), e.msg);
-  assertTrue(String.prototype.contains.apply(v, [v]), e.msg);
-}
-
-// Test cases found in FF
-assertTrue("abc".contains("a"));
-assertTrue("abc".contains("b"));
-assertTrue("abc".contains("abc"));
-assertTrue("abc".contains("bc"));
-assertFalse("abc".contains("d"));
-assertFalse("abc".contains("abcd"));
-assertFalse("abc".contains("ac"));
-assertTrue("abc".contains("abc", 0));
-assertTrue("abc".contains("bc", 0));
-assertFalse("abc".contains("de", 0));
-assertTrue("abc".contains("bc", 1));
-assertTrue("abc".contains("c", 1));
-assertFalse("abc".contains("a", 1));
-assertFalse("abc".contains("abc", 1));
-assertTrue("abc".contains("c", 2));
-assertFalse("abc".contains("d", 2));
-assertFalse("abc".contains("dcd", 2));
-assertFalse("abc".contains("a", 42));
-assertFalse("abc".contains("a", Infinity));
-assertTrue("abc".contains("ab", -43));
-assertFalse("abc".contains("cd", -42));
-assertTrue("abc".contains("ab", -Infinity));
-assertFalse("abc".contains("cd", -Infinity));
-assertTrue("abc".contains("ab", NaN));
-assertFalse("abc".contains("cd", NaN));
-assertFalse("xyzzy".contains("zy\0", 2));
-
-var dots = Array(10000).join(".");
-assertFalse(dots.contains("\x01", 10000));
-assertFalse(dots.contains("\0", 10000));
-
-var myobj = {
-  toString: function () {
-    return "abc";
-  },
-  contains: String.prototype.contains
-};
-assertTrue(myobj.contains("abc"));
-assertFalse(myobj.contains("cd"));
-
-var gotStr = false;
-var gotPos = false;
-myobj = {
-  toString: function () {
-    assertFalse(gotPos);
-    gotStr = true;
-    return "xyz";
-  },
-  contains: String.prototype.contains
-};
-
-assertEquals("foo[a-z]+(bar)?".contains("[a-z]+"), true);
-assertThrows("'foo[a-z]+(bar)?'.contains(/[a-z]+/)", TypeError);
-assertThrows("'foo/[a-z]+/(bar)?'.contains(/[a-z]+/)", TypeError);
-assertEquals("foo[a-z]+(bar)?".contains("(bar)?"), true);
-assertThrows("'foo[a-z]+(bar)?'.contains(/(bar)?/)", TypeError);
-assertThrows("'foo[a-z]+/(bar)?/'.contains(/(bar)?/)", TypeError);
-
-assertThrows("String.prototype.contains.call({ 'toString': function() { " +
-  "throw RangeError(); } }, /./)", RangeError);
-assertThrows("String.prototype.contains.call({ 'toString': function() { " +
-  "return 'abc'; } }, /./)", TypeError);
-
-assertThrows("String.prototype.contains.apply({ 'toString': function() { " +
-  "throw RangeError(); } }, [/./])", RangeError);
-assertThrows("String.prototype.contains.apply({ 'toString': function() { " +
-  "return 'abc'; } }, [/./])", TypeError);
diff --git a/test/mjsunit/harmony/string-includes.js b/test/mjsunit/harmony/string-includes.js
new file mode 100644
index 0000000..33ed8ea
--- /dev/null
+++ b/test/mjsunit/harmony/string-includes.js
@@ -0,0 +1,166 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * 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-strings
+
+assertEquals(1, String.prototype.includes.length);
+
+var reString = "asdf[a-z]+(asdf)?";
+assertTrue(reString.includes("[a-z]+"));
+assertTrue(reString.includes("(asdf)?"));
+
+// Random greek letters
+var twoByteString = "\u039a\u0391\u03a3\u03a3\u0395";
+
+// Test single char pattern
+assertTrue(twoByteString.includes("\u039a"), "Lamda");
+assertTrue(twoByteString.includes("\u0391"), "Alpha");
+assertTrue(twoByteString.includes("\u03a3"), "First Sigma");
+assertTrue(twoByteString.includes("\u03a3",3), "Second Sigma");
+assertTrue(twoByteString.includes("\u0395"), "Epsilon");
+assertFalse(twoByteString.includes("\u0392"), "Not beta");
+
+// Test multi-char pattern
+assertTrue(twoByteString.includes("\u039a\u0391"), "lambda Alpha");
+assertTrue(twoByteString.includes("\u0391\u03a3"), "Alpha Sigma");
+assertTrue(twoByteString.includes("\u03a3\u03a3"), "Sigma Sigma");
+assertTrue(twoByteString.includes("\u03a3\u0395"), "Sigma Epsilon");
+
+assertFalse(twoByteString.includes("\u0391\u03a3\u0395"),
+    "Not Alpha Sigma Epsilon");
+
+//single char pattern
+assertTrue(twoByteString.includes("\u0395"));
+
+assertThrows("String.prototype.includes.call(null, 'test')", TypeError);
+assertThrows("String.prototype.includes.call(null, null)", TypeError);
+assertThrows("String.prototype.includes.call(undefined, undefined)", TypeError);
+
+assertThrows("String.prototype.includes.apply(null, ['test'])", TypeError);
+assertThrows("String.prototype.includes.apply(null, [null])", TypeError);
+assertThrows("String.prototype.includes.apply(undefined, [undefined])", TypeError);
+
+var TEST_INPUT = [{
+  msg: "Empty string", val: ""
+}, {
+  msg: "Number 1234.34", val: 1234.34
+}, {
+  msg: "Integer number 0", val: 0
+}, {
+  msg: "Negative number -1", val: -1
+}, {
+  msg: "Boolean true", val: true
+}, {
+  msg: "Boolean false", val: false
+}, {
+  msg: "Empty array []", val: []
+}, {
+  msg: "Empty object {}", val: {}
+}, {
+  msg: "Array of size 3", val: new Array(3)
+}];
+
+var i = 0;
+var l = TEST_INPUT.length;
+
+for (; i < l; i++) {
+  var e = TEST_INPUT[i];
+  var v = e.val;
+  var s = String(v);
+  assertTrue(s.includes(v), e.msg);
+  assertTrue(String.prototype.includes.call(v, v), e.msg);
+  assertTrue(String.prototype.includes.apply(v, [v]), e.msg);
+}
+
+// Test cases found in FF
+assertTrue("abc".includes("a"));
+assertTrue("abc".includes("b"));
+assertTrue("abc".includes("abc"));
+assertTrue("abc".includes("bc"));
+assertFalse("abc".includes("d"));
+assertFalse("abc".includes("abcd"));
+assertFalse("abc".includes("ac"));
+assertTrue("abc".includes("abc", 0));
+assertTrue("abc".includes("bc", 0));
+assertFalse("abc".includes("de", 0));
+assertTrue("abc".includes("bc", 1));
+assertTrue("abc".includes("c", 1));
+assertFalse("abc".includes("a", 1));
+assertFalse("abc".includes("abc", 1));
+assertTrue("abc".includes("c", 2));
+assertFalse("abc".includes("d", 2));
+assertFalse("abc".includes("dcd", 2));
+assertFalse("abc".includes("a", 42));
+assertFalse("abc".includes("a", Infinity));
+assertTrue("abc".includes("ab", -43));
+assertFalse("abc".includes("cd", -42));
+assertTrue("abc".includes("ab", -Infinity));
+assertFalse("abc".includes("cd", -Infinity));
+assertTrue("abc".includes("ab", NaN));
+assertFalse("abc".includes("cd", NaN));
+assertFalse("xyzzy".includes("zy\0", 2));
+
+var dots = Array(10000).join(".");
+assertFalse(dots.includes("\x01", 10000));
+assertFalse(dots.includes("\0", 10000));
+
+var myobj = {
+  toString: function () {
+    return "abc";
+  },
+  includes: String.prototype.includes
+};
+assertTrue(myobj.includes("abc"));
+assertFalse(myobj.includes("cd"));
+
+var gotStr = false;
+var gotPos = false;
+myobj = {
+  toString: function () {
+    assertFalse(gotPos);
+    gotStr = true;
+    return "xyz";
+  },
+  includes: String.prototype.includes
+};
+
+assertEquals("foo[a-z]+(bar)?".includes("[a-z]+"), true);
+assertThrows("'foo[a-z]+(bar)?'.includes(/[a-z]+/)", TypeError);
+assertThrows("'foo/[a-z]+/(bar)?'.includes(/[a-z]+/)", TypeError);
+assertEquals("foo[a-z]+(bar)?".includes("(bar)?"), true);
+assertThrows("'foo[a-z]+(bar)?'.includes(/(bar)?/)", TypeError);
+assertThrows("'foo[a-z]+/(bar)?/'.includes(/(bar)?/)", TypeError);
+
+assertThrows("String.prototype.includes.call({ 'toString': function() { " +
+  "throw RangeError(); } }, /./)", RangeError);
+assertThrows("String.prototype.includes.call({ 'toString': function() { " +
+  "return 'abc'; } }, /./)", TypeError);
+
+assertThrows("String.prototype.includes.apply({ 'toString': function() { " +
+  "throw RangeError(); } }, [/./])", RangeError);
+assertThrows("String.prototype.includes.apply({ 'toString': function() { " +
+  "return 'abc'; } }, [/./])", TypeError);
diff --git a/test/mjsunit/harmony/string-raw.js b/test/mjsunit/harmony/string-raw.js
new file mode 100644
index 0000000..28e2af9
--- /dev/null
+++ b/test/mjsunit/harmony/string-raw.js
@@ -0,0 +1,258 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-templates
+
+(function testStringRawArity() {
+  assertEquals(1, String.raw.length);
+})();
+
+
+(function testStringRawCallSiteToObject() {
+  assertThrows("String.raw()", TypeError);
+})();
+
+
+(function testStringRawCallSiteRawToObject() {
+  assertThrows("String.raw([])", TypeError);
+})();
+
+
+(function testStringRawUndefinedLength() {
+  var callSiteObj = [];
+  callSiteObj.raw = {};
+  assertEquals("", String.raw(callSiteObj));
+
+  callSiteObj.raw = { lengt: 0 };
+  assertEquals("", String.raw(callSiteObj));
+})();
+
+
+(function testStringRawZeroLength() {
+  var callSiteObj = [];
+  callSiteObj.raw = { length: 0 };
+  assertEquals("", String.raw(callSiteObj));
+  assertEquals("", String.raw(callSiteObj, "a", "b", "c"));
+
+  callSiteObj.raw = [];
+  assertEquals("", String.raw(callSiteObj));
+  assertEquals("", String.raw(callSiteObj, "a", "b", "c"));
+})();
+
+
+(function testStringRawNegativeLength() {
+  var callSiteObj = [];
+  callSiteObj.raw = { length: -85 };
+  assertEquals("", String.raw(callSiteObj));
+  assertEquals("", String.raw(callSiteObj, "a", "b", "c"));
+
+  callSiteObj.raw = [];
+  assertEquals("", String.raw(callSiteObj));
+  assertEquals("", String.raw(callSiteObj, "a", "b", "c"));
+})();
+
+
+(function testStringRawNaNLength() {
+  var callSiteObj = [];
+  callSiteObj.raw = { length: NaN };
+  assertEquals("", String.raw(callSiteObj));
+  assertEquals("", String.raw(callSiteObj, "a", "b", "c"));
+
+  callSiteObj.raw = [];
+  assertEquals("", String.raw(callSiteObj));
+  assertEquals("", String.raw(callSiteObj, "a", "b", "c"));
+})();
+
+
+(function testStringRawBasic() {
+  var callSiteObj = [];
+  callSiteObj.raw = ["a"];
+  assertEquals("a", String.raw(callSiteObj));
+})();
+
+
+(function testStringRawNoSubst() {
+  var callSiteObj = [];
+  callSiteObj.raw = ["a", "b"];
+  assertEquals("ab", String.raw(callSiteObj));
+})();
+
+
+(function testStringRawSubst() {
+  var callSiteObj = [];
+  callSiteObj.raw = ["a", "b"];
+  assertEquals("a!b", String.raw(callSiteObj, "!"));
+
+  callSiteObj.raw = ["a", "b", "c"];
+  assertEquals("abc", String.raw(callSiteObj));
+
+  callSiteObj.raw = ["a", "b", "c"];
+  assertEquals("a!bc", String.raw(callSiteObj, "!"));
+
+  callSiteObj.raw = ["a", "b", "c"];
+  assertEquals("a!b?c", String.raw(callSiteObj, "!", "?"));
+
+  callSiteObj.raw = ["\n", "\r\n", "\r"];
+  assertEquals("\nx\r\ny\r", String.raw(callSiteObj, "x", "y"));
+
+  callSiteObj.raw = ["\n", "\r\n", "\r"];
+  assertEquals("\n\r\r\r\n\n\r", String.raw(callSiteObj, "\r\r", "\n"));
+})();
+
+
+(function testStringRawArrayLikeSubst() {
+  var callSiteObj = [];
+  callSiteObj.raw = {"length": 2, "0": "a", "1": "b", "2": "c"};
+  assertEquals("axb", String.raw(callSiteObj, "x", "y"));
+
+  callSiteObj.raw = {"length": 4, "0": "a", "1": "b", "2": "c"};
+  assertEquals("axbycundefined", String.raw(callSiteObj, "x", "y"));
+})();
+
+
+(function testStringRawAccessors() {
+  var callSiteObj = {};
+  callSiteObj.raw = {};
+  Object.defineProperties(callSiteObj, {
+    "length": {
+      get: function() { assertUnreachable(); },
+      set: function(v) { assertUnreachable(); }
+    },
+    "0": {
+      get: function() { assertUnreachable(); },
+      set: function(v) { assertUnreachable(); }
+    },
+    "1": {
+      get: function() { assertUnreachable(); },
+      set: function(v) { assertUnreachable(); }
+    }
+  });
+  Object.defineProperties(callSiteObj.raw, {
+    "length": {
+      get: function() { return 2; },
+      set: function(v) { assertUnreachable(); }
+    },
+    "0": {
+      get: function() { return "getter values"; },
+      set: function(v) { assertUnreachable(); }
+    },
+    "1": {
+      get: function() { return "are nice"; },
+      set: function(v) { assertUnreachable(); }
+    }
+  });
+  assertEquals("getter values are nice", String.raw(callSiteObj, " "));
+})();
+
+
+(function testStringRawHoleyArray() {
+  var callSiteObj = [];
+  callSiteObj.raw = ["1."];
+  callSiteObj.raw[2] = ".2";
+  assertEquals("1.undefined.2", String.raw(callSiteObj));
+})();
+
+
+(function testStringRawAccessorThrows() {
+  var callSiteObj = [];
+  callSiteObj.raw = [1];
+  function MyError() {}
+  Object.defineProperty(callSiteObj.raw, "0", {
+    get: function() { throw new MyError(); }
+  });
+  assertThrows(function() { String.raw(callSiteObj); }, MyError);
+})();
+
+
+(function testStringRawToStringSafe() {
+  var callSiteObj = [];
+  callSiteObj.raw = [null, undefined, 1, "str", true, false, NaN, Infinity, {}];
+  assertEquals("nullundefined1strtruefalseNaNInfinity[object Object]",
+               String.raw(callSiteObj));
+
+  callSiteObj.raw = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
+  assertEquals("0null1undefined213str4true5false6NaN7Infinity8[object Object]9",
+               String.raw(callSiteObj, null, void 0, 1, "str", true, false,
+               NaN, Infinity, {}));
+})();
+
+
+(function testStringRawToStringSymbolThrows() {
+  var callSiteObj = [];
+  callSiteObj.raw = [Symbol("foo")];
+  assertThrows(function() {
+    String.raw(callSiteObj);
+  }, TypeError);
+
+  callSiteObj.raw = ["1", "2"];
+  assertThrows(function() {
+    String.raw(callSiteObj, Symbol("foo"));
+  }, TypeError);
+})();
+
+
+(function testStringRawToStringThrows() {
+  var callSiteObj = [];
+  var thrower = {};
+  function MyError() {}
+  thrower.toString = function() {
+    throw new MyError();
+  }
+
+  callSiteObj.raw = [thrower];
+  assertThrows(function() {
+    String.raw(callSiteObj);
+  }, MyError);
+
+  callSiteObj.raw = ["1", "2"];
+  assertThrows(function() {
+    String.raw(callSiteObj, thrower);
+  }, MyError);
+})();
+
+
+(function testStringRawToStringValueOfThrows() {
+  var callSiteObj = [];
+  var thrower = {};
+  function MyError() {}
+  thrower.toString = null;
+  thrower.valueOf = function() {
+    throw new MyError();
+  }
+
+  callSiteObj.raw = [thrower];
+  assertThrows(function() {
+    String.raw(callSiteObj);
+  }, MyError);
+
+  callSiteObj.raw = ["1", "2"];
+  assertThrows(function() {
+    String.raw(callSiteObj, thrower);
+  }, MyError);
+})();
+
+
+(function testStringRawOrder() {
+  var order = [];
+  var callSiteObj = [];
+  callSiteObj.raw = {};
+  function arg(v) {
+    var result = {};
+    result.toString = null;
+    result.valueOf = function() { order.push("arg" + v); return v; }
+    return result;
+  }
+
+  Object.defineProperty(callSiteObj.raw, "length", {
+    get: function() { order.push("length"); return 3; }
+  });
+  [1, 3, 5].forEach(function(v, i) {
+    Object.defineProperty(callSiteObj.raw, i, {
+      get: function() { order.push("raw" + v); return v; }
+    });
+  });
+
+  assertEquals("12345", String.raw(callSiteObj, arg(2), arg(4), arg(6)));
+  assertEquals(["length", "raw1", "arg2", "raw3", "arg4", "raw5"], order);
+})();
diff --git a/test/mjsunit/harmony/string-repeat.js b/test/mjsunit/harmony/string-repeat.js
index 761089b..0af7448 100644
--- a/test/mjsunit/harmony/string-repeat.js
+++ b/test/mjsunit/harmony/string-repeat.js
@@ -61,8 +61,11 @@
 assertEquals("", "abc".repeat(0));
 assertEquals("abcabc", "abc".repeat(2.0));
 
+assertEquals("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "a".repeat(37));
 assertThrows('"a".repeat(-1)', RangeError);
 assertThrows('"a".repeat(Number.POSITIVE_INFINITY)', RangeError);
+assertThrows('"a".repeat(Math.pow(2, 30))', RangeError);
+assertThrows('"a".repeat(Math.pow(2, 40))', RangeError);
 
 var myobj = {
   toString: function() {
diff --git a/test/mjsunit/harmony/super.js b/test/mjsunit/harmony/super.js
index 89fb4b1..6dcc393 100644
--- a/test/mjsunit/harmony/super.js
+++ b/test/mjsunit/harmony/super.js
@@ -18,6 +18,8 @@
 
   function fDerived() {
      assertEquals("Base this is Derived", super.f());
+     var a = super.x;
+     assertEquals(15, a);
      assertEquals(15, super.x);
      assertEquals(27, this.x);
 
@@ -34,6 +36,77 @@
   assertEquals("Derived", new Derived().f());
 }());
 
+
+(function TestSuperKeyedLoads() {
+  var x = 'x';
+  var derivedDataProperty = 'derivedDataProperty';
+  var f = 'f';
+  function Base() { }
+  function Derived() {
+    this[derivedDataProperty] = 'xxx';
+  }
+  Derived.prototype = Object.create(Base.prototype);
+
+  function fBase() { return "Base " + this.toString(); }
+
+  Base.prototype[f] = fBase.toMethod(Base.prototype);
+
+  function fDerived() {
+     assertEquals("Base this is Derived", super[f]());
+     var a = super[x];
+     assertEquals(15, a);
+     assertEquals(15, super[x]);
+     assertEquals(27, this[x]);
+
+     return "Derived"
+  }
+
+  Base.prototype[x] = 15;
+  Base.prototype.toString = function() { return "this is Base"; };
+  Derived.prototype.toString = function() { return "this is Derived"; };
+  Derived.prototype[x] = 27;
+  Derived.prototype[f] = fDerived.toMethod(Derived.prototype);
+
+  assertEquals("Base this is Base", new Base().f());
+  assertEquals("Derived", new Derived().f());
+}());
+
+
+(function TestSuperNumericKeyedLoads() {
+  var x = 1;
+  var derivedDataProperty = 2;
+  var f = 3;
+  function Base() { }
+  function Derived() {
+    this[derivedDataProperty] = 'xxx';
+  }
+  Derived.prototype = Object.create(Base.prototype);
+
+  function fBase() { return "Base " + this.toString(); }
+
+  Base.prototype[f] = fBase.toMethod(Base.prototype);
+
+  function fDerived() {
+     assertEquals("Base this is Derived", super[f]());
+     var a = super[x];
+     assertEquals(15, a);
+     assertEquals(15, super[x]);
+     assertEquals(27, this[x]);
+
+     return "Derived"
+  }
+
+  Base.prototype[x] = 15;
+  Base.prototype.toString = function() { return "this is Base"; };
+  Derived.prototype.toString = function() { return "this is Derived"; };
+  Derived.prototype[x] = 27;
+  Derived.prototype[f] = fDerived.toMethod(Derived.prototype);
+
+  assertEquals("Base this is Base", new Base()[f]());
+  assertEquals("Derived", new Derived()[f]());
+}());
+
+
 (function TestSuperKeywordNonMethod() {
   function f() {
     super.unknown();
@@ -65,12 +138,149 @@
   Derived.prototype.testGetter = function() {
     return super.x;
   }.toMethod(Derived.prototype);
+  Derived.prototype.testGetterStrict = function() {
+    'use strict';
+    return super.x;
+  }.toMethod(Derived.prototype);
   derived = new Derived();
   assertEquals('derived', derived.testGetter());
+  derived = new Derived();
+  assertEquals('derived', derived.testGetterStrict());
 }());
 
-/*
- * TODO[dslomov]: named stores and keyed loads/stores not implemented yet.
+
+(function TestGetterKeyed() {
+  var x = 'x';
+  function Base() {}
+  var derived;
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      assertSame(this, derived);
+      return this._x;
+    },
+    _x: 'base'
+  };
+
+  function Derived() {}
+  Derived.__proto__ = Base;
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+    _x: 'derived'
+  };
+  Derived.prototype.testGetter = function() {
+    return super[x];
+  }.toMethod(Derived.prototype);
+  Derived.prototype.testGetterStrict = function() {
+    'use strict';
+    return super[x];
+  }.toMethod(Derived.prototype);
+  Derived.prototype.testGetterWithToString = function() {
+    var toStringCalled;
+    var o = { toString: function() {
+      toStringCalled++;
+      return 'x';
+    } };
+
+    toStringCalled = 0;
+    assertEquals('derived', super[o]);
+    assertEquals(1, toStringCalled);
+
+    var eToThrow = new Error();
+    var oThrowsInToString = { toString: function() {
+      throw eToThrow;
+    } };
+
+    var ex = null;
+    try {
+      super[oThrowsInToString];
+    } catch(e) { ex = e }
+    assertEquals(eToThrow, ex);
+
+    var oReturnsNumericString = { toString: function() {
+      return "1";
+    } };
+
+    assertEquals(undefined, super[oReturnsNumericString]);
+    assertEquals(undefined, super[1]);
+  }.toMethod(Derived.prototype);
+  derived = new Derived();
+  assertEquals('derived', derived.testGetter());
+  derived = new Derived();
+  assertEquals('derived', derived.testGetterStrict());
+  derived = new Derived();
+  derived.testGetterWithToString();
+}());
+
+
+(function TestGetterNumericKeyed() {
+  var x = 42;
+  function Base() {}
+  var derived;
+  Base.prototype = {
+    constructor: Base,
+    _x: 'base'
+  };
+
+  Object.defineProperty(Base.prototype, x, { get: function() {
+      assertSame(this, derived);
+      return this._x;
+  }});
+
+  function Derived() {}
+  Derived.__proto__ = Base;
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+    _x: 'derived'
+  };
+  Derived.prototype.testGetter = function() {
+    return super[x];
+  }.toMethod(Derived.prototype);
+  Derived.prototype.testGetterStrict = function() {
+    'use strict';
+    return super[x];
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testGetterWithToString = function() {
+    var toStringCalled;
+    var o = { toString: function() {
+      toStringCalled++;
+      return '42';
+    } };
+
+    toStringCalled = 0;
+    assertEquals('derived', super[o]);
+    assertEquals(1, toStringCalled);
+
+    var eToThrow = new Error();
+    var oThrowsInToString = { toString: function() {
+      throw eToThrow;
+    } };
+
+    var ex = null;
+    try {
+      super[oThrowsInToString];
+    } catch(e) { ex = e }
+    assertEquals(eToThrow, ex);
+
+    var oReturnsNumericString = { toString: function() {
+      return "42";
+    } };
+
+    assertEquals('derived', super[oReturnsNumericString]);
+    assertEquals('derived', super[42]);
+  }.toMethod(Derived.prototype);
+  derived = new Derived();
+  assertEquals('derived', derived.testGetter());
+  derived = new Derived();
+  assertEquals('derived', derived.testGetterStrict());
+  derived = new Derived();
+  derived.testGetterWithToString();
+}());
+
+
 (function TestSetter() {
   function Base() {}
   Base.prototype = {
@@ -92,24 +302,37 @@
     _x: 'derived'
   };
   Derived.prototype.testSetter = function() {
-      super.x = 'foobar';
-    }.toMethod(Derived.prototype);
+    assertEquals('foobar', super.x = 'foobar');
+    assertEquals('foobarabc', super.x += 'abc');
+  }.toMethod(Derived.prototype);
   var d = new Derived();
   d.testSetter();
   assertEquals('base', Base.prototype._x);
-  assertEquals('foobar', d._x);
+  assertEquals('foobarabc', d._x);
+  d._x = '';
+  Derived.prototype.testSetterStrict = function() {
+    'use strict';
+    assertEquals('foobar', super.x = 'foobar');
+    assertEquals('foobarabc', super.x += 'abc');
+  }.toMethod(Derived.prototype);
+  d.testSetterStrict();
+  assertEquals('base', Base.prototype._x);
+  assertEquals('foobarabc', d._x);
 }());
 
 
-(function TestKeyedGetter() {
+(function TestSetterNumericKeyed() {
+  var x = 42;
   function Base() {}
   Base.prototype = {
     constructor: Base,
     _x: 'base'
   };
 
-  Object.defineProperty(Base.prototype, '0',
-        { get: function() { return this._x; } });
+  Object.defineProperty(Base.prototype, x,
+    { get: function() { return this._x; },
+      set: function(v) { this._x = v; }
+    });
 
   function Derived() {}
   Derived.__proto__ = Base;
@@ -118,10 +341,1581 @@
     constructor: Derived,
     _x: 'derived'
   };
-  Derived.prototype.testGetter = function() {
-      return super[0];
-    }.toMethod(Derived.prototype);
-  assertEquals('derived', new Derived()[0]);
-  // assertEquals('derived', new Derived().testGetter());
+  Derived.prototype.testSetter = function() {
+    assertEquals('foobar', super[x] = 'foobar');
+    assertEquals('foobarabc', super[x] += 'abc');
+  }.toMethod(Derived.prototype);
+  var d = new Derived();
+  d.testSetter();
+  assertEquals('base', Base.prototype._x);
+  assertEquals('foobarabc', d._x);
+  d._x = '';
+  Derived.prototype.testSetterStrict = function() {
+    'use strict';
+    assertEquals('foobar', super[x] = 'foobar');
+    assertEquals('foobarabc', super[x] += 'abc');
+  }.toMethod(Derived.prototype);
+  d.testSetterStrict();
+  assertEquals('base', Base.prototype._x);
+  assertEquals('foobarabc', d._x);
+
+
+  Derived.prototype.testSetterWithToString = function() {
+    var toStringCalled;
+    var o = { toString: function() {
+      toStringCalled++;
+      return x;
+    } };
+
+    toStringCalled = 0;
+    super[o] = 'set';
+    assertEquals(1, toStringCalled);
+    assertEquals('set', this._x);
+
+    var eToThrow = new Error();
+    var oThrowsInToString = { toString: function() {
+      throw eToThrow;
+    } };
+
+    var ex = null;
+    try {
+      super[oThrowsInToString] = 'xyz';
+    } catch(e) { ex = e }
+    assertEquals(eToThrow, ex);
+    assertEquals('set', this._x);
+  }.toMethod(Derived.prototype);
+  d = new Derived();
+  d.testSetterWithToString();
 }());
-*/
+
+
+(function TestSetterKeyed() {
+  var x = 'x';
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      return this._x;
+    },
+    set x(v) {
+      this._x = v;
+    },
+    _x: 'base'
+  };
+
+  function Derived() {}
+  Derived.__proto__ = Base;
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+    _x: 'derived'
+  };
+  Derived.prototype.testSetter = function() {
+    assertEquals('foobar', super[x] = 'foobar');
+    assertEquals('foobarabc', super[x] += 'abc');
+  }.toMethod(Derived.prototype);
+  var d = new Derived();
+  d.testSetter();
+  assertEquals('base', Base.prototype._x);
+  assertEquals('foobarabc', d._x);
+  d._x = '';
+  Derived.prototype.testSetterStrict = function() {
+    'use strict';
+    assertEquals('foobar', super[x] = 'foobar');
+    assertEquals('foobarabc', super[x] += 'abc');
+  }.toMethod(Derived.prototype);
+  d.testSetterStrict();
+  assertEquals('base', Base.prototype._x);
+  assertEquals('foobarabc', d._x);
+
+
+  Derived.prototype.testSetterWithToString = function() {
+    var toStringCalled;
+    var o = { toString: function() {
+      toStringCalled++;
+      return 'x';
+    } };
+
+    toStringCalled = 0;
+    super[o] = 'set';
+    assertEquals(1, toStringCalled);
+    assertEquals('set', this._x);
+
+    var eToThrow = new Error();
+    var oThrowsInToString = { toString: function() {
+      throw eToThrow;
+    } };
+
+    var ex = null;
+    try {
+      super[oThrowsInToString] = 'xyz';
+    } catch(e) { ex = e }
+    assertEquals(eToThrow, ex);
+    assertEquals('set', this._x);
+
+    var oReturnsNumericString = { toString: function() {
+      return "1";
+    } };
+
+    assertEquals('abc', super[oReturnsNumericString] = 'abc');
+
+    assertEquals('set', this._x);
+
+    assertEquals(10,  super[1] = 10);
+  }.toMethod(Derived.prototype);
+  d = new Derived();
+  d.testSetterWithToString();
+}());
+
+
+(function TestSetterDataProperties() {
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    x: 'x from Base'
+  };
+
+  function Derived() {}
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+
+  Derived.prototype.testSetter = function() {
+    assertEquals('x from Base', super.x);
+    super.x = 'data property';
+    assertEquals('x from Base', super.x);
+    assertEquals('data property', this.x);
+  }.toMethod(Derived.prototype);
+
+  new Derived().testSetter();
+}());
+
+
+(function TestKeyedSetterDataProperties() {
+  var x = 'x';
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    x: 'x from Base'
+  };
+
+  function Derived() {}
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+
+  Derived.prototype.testSetter = function() {
+    assertEquals('x from Base', super[x]);
+    super[x] = 'data property';
+    assertEquals('x from Base', super[x]);
+    assertEquals('data property', this[x]);
+  }.toMethod(Derived.prototype);
+
+  new Derived().testSetter();
+}());
+
+
+(function TestKeyedNumericSetterDataProperties() {
+  var x = 42;
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    42: 'x from Base'
+  };
+
+  function Derived() {}
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+
+  Derived.prototype.testSetter = function() {
+    assertEquals('x from Base', super[x]);
+    super[x] = 'data property';
+    assertEquals('x from Base', super[x]);
+    assertEquals('data property', this[x]);
+  }.toMethod(Derived.prototype);
+
+  new Derived().testSetter();
+}());
+
+
+(function TestAccessorsOnPrimitives() {
+  var getCalled = 0;
+  var setCalled = 0;
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      getCalled++;
+      return 1;
+    },
+    set x(v) {
+      setCalled++;
+      return v;
+    },
+  };
+
+  function Derived() {}
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+  Derived.prototype.testSetter = function() {
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals('object', typeof this);
+    assertTrue(this instanceof Number)
+    assertEquals(42, this.valueOf());
+    assertEquals(1, super.x);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    assertEquals(5, super.x = 5);
+    assertEquals(1, getCalled);
+    assertEquals(1, setCalled);
+
+    assertEquals(6, super.x += 5);
+    assertEquals(2, getCalled);
+    assertEquals(2, setCalled);
+
+    super.newProperty = 15;
+    assertEquals(15, this.newProperty);
+    assertEquals(undefined, super.newProperty);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testSetterStrict = function() {
+    'use strict';
+    getCalled = 0;
+    setCalled = 0;
+    assertTrue(42 === this);
+
+    assertEquals(1, super.x);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    assertEquals(5, super.x = 5);
+    assertEquals(1, getCalled);
+    assertEquals(1, setCalled);
+
+    assertEquals(6, super.x += 5);
+    assertEquals(2, getCalled);
+    assertEquals(2, setCalled);
+
+    var ex;
+    try {
+      super.newProperty = 15;
+    } catch (e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testSetter.call(42);
+  Derived.prototype.testSetterStrict.call(42);
+
+  function DerivedFromString() {}
+  DerivedFromString.prototype = Object.create(String.prototype);
+
+  function f() {
+    'use strict';
+    assertTrue(42 === this);
+    assertEquals(String.prototype.toString, super.toString);
+    var ex;
+    try {
+      super.toString();
+    } catch(e) { ex = e; }
+
+    assertTrue(ex instanceof TypeError);
+  }
+  f.toMethod(DerivedFromString.prototype).call(42);
+}());
+
+
+(function TestKeyedAccessorsOnPrimitives() {
+  var x = 'x';
+  var newProperty = 'newProperty';
+  var toString = 'toString';
+  var getCalled = 0;
+  var setCalled = 0;
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      getCalled++;
+      return 1;
+    },
+    set x(v) {
+      setCalled++;
+      return v;
+    },
+  };
+
+  function Derived() {}
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+  Derived.prototype.testSetter = function() {
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals('object', typeof this);
+    assertTrue(this instanceof Number)
+    assertEquals(42, this.valueOf());
+    assertEquals(1, super[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    assertEquals(5, super[x] = 5);
+    assertEquals(1, getCalled);
+    assertEquals(1, setCalled);
+
+    assertEquals(6, super[x] += 5);
+    assertEquals(2, getCalled);
+    assertEquals(2, setCalled);
+
+    super[newProperty] = 15;
+    assertEquals(15, this[newProperty]);
+    assertEquals(undefined, super[newProperty]);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testSetterStrict = function() {
+    'use strict';
+    getCalled = 0;
+    setCalled = 0;
+    assertTrue(42 === this);
+
+    assertEquals(1, super[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    assertEquals(5, super[x] = 5);
+    assertEquals(1, getCalled);
+    assertEquals(1, setCalled);
+
+    assertEquals(6, super[x] += 5);
+    assertEquals(2, getCalled);
+    assertEquals(2, setCalled);
+
+    var ex;
+    try {
+      super[newProperty] = 15;
+    } catch (e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testSetter.call(42);
+  Derived.prototype.testSetterStrict.call(42);
+
+  function DerivedFromString() {}
+  DerivedFromString.prototype = Object.create(String.prototype);
+
+  function f() {
+    'use strict';
+    assertTrue(42 === this);
+    assertEquals(String.prototype.toString, super[toString]);
+    var ex;
+    try {
+      super[toString]();
+    } catch(e) { ex = e; }
+
+    assertTrue(ex instanceof TypeError);
+  }
+  f.toMethod(DerivedFromString.prototype).call(42);
+}());
+
+
+(function TestNumericKeyedAccessorsOnPrimitives() {
+  var x = 42;
+  var newProperty = 43;
+  var getCalled = 0;
+  var setCalled = 0;
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+  };
+
+  Object.defineProperty(Base.prototype, x, {
+    get: function() {
+      getCalled++;
+      return 1;
+    },
+    set: function(v) {
+      setCalled++;
+      return v;
+    }
+  });
+
+  function Derived() {}
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+  Derived.prototype.testSetter = function() {
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals('object', typeof this);
+    assertTrue(this instanceof Number)
+    assertEquals(42, this.valueOf());
+    assertEquals(1, super[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    assertEquals(5, super[x] = 5);
+    assertEquals(1, getCalled);
+    assertEquals(1, setCalled);
+
+    assertEquals(6, super[x] += 5);
+    assertEquals(2, getCalled);
+    assertEquals(2, setCalled);
+
+    super[newProperty] = 15;
+    assertEquals(15, this[newProperty]);
+    assertEquals(undefined, super[newProperty]);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testSetterStrict = function() {
+    'use strict';
+    getCalled = 0;
+    setCalled = 0;
+    assertTrue(42 === this);
+
+    assertEquals(1, super[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    assertEquals(5, super[x] = 5);
+    assertEquals(1, getCalled);
+    assertEquals(1, setCalled);
+
+    assertEquals(6, super[x] += 5);
+    assertEquals(2, getCalled);
+    assertEquals(2, setCalled);
+
+    var ex;
+    try {
+      super[newProperty] = 15;
+    } catch (e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.testSetter.call(42);
+  Derived.prototype.testSetterStrict.call(42);
+}());
+
+
+(function TestKeyedNumericSetterOnExotics() {
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__: Base.prototype };
+
+  Derived.prototype.callSetterOnArray = function() {
+    super[42] = 1;
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.callStrictSetterOnString = function() {
+    'use strict';
+    assertEquals('string', typeof this);
+    assertTrue('abcdef' === this);
+    var ex = null;
+    try {
+      super[5] = 'q';
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+
+    ex = null;
+    try {
+      super[1024] = 'q';
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+  }.toMethod(Derived.prototype);
+
+  var x = [];
+  assertEquals(0, x.length);
+  Derived.prototype.callSetterOnArray.call(x);
+  assertEquals(43, x.length);
+  assertEquals(1, x[42]);
+
+  var s = 'abcdef';
+  Derived.prototype.callStrictSetterOnString.call(s)
+}());
+
+
+(function TestSetterUndefinedProperties() {
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__ : Base.prototype };
+  Derived.prototype.mSloppy = function () {
+    assertEquals(undefined, super.x);
+    assertEquals(undefined, this.x);
+    super.x = 10;
+    assertEquals(10, this.x);
+    assertEquals(undefined, super.x);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function () {
+    'use strict';
+    assertEquals(undefined, super.x);
+    assertEquals(undefined, this.x);
+    super.x = 10;
+    assertEquals(10, this.x);
+    assertEquals(undefined, super.x);
+  }.toMethod(Derived.prototype);
+  var d = new Derived();
+  d.mSloppy();
+  assertEquals(10, d.x);
+  var d1 = new Derived();
+  d1.mStrict();
+  assertEquals(10, d.x);
+}());
+
+
+(function TestKeyedSetterUndefinedProperties() {
+  var x = 'x';
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__ : Base.prototype };
+  Derived.prototype.mSloppy = function () {
+    assertEquals(undefined, super[x]);
+    assertEquals(undefined, this[x]);
+    super[x] = 10;
+    assertEquals(10, this[x]);
+    assertEquals(undefined, super[x]);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function () {
+    'use strict';
+    assertEquals(undefined, super[x]);
+    assertEquals(undefined, this[x]);
+    super[x] = 10;
+    assertEquals(10, this[x]);
+    assertEquals(undefined, super[x]);
+  }.toMethod(Derived.prototype);
+  var d = new Derived();
+  d.mSloppy();
+  assertEquals(10, d.x);
+  var d1 = new Derived();
+  d1.mStrict();
+  assertEquals(10, d.x);
+}());
+
+
+(function TestKeyedNumericSetterUndefinedProperties() {
+  var x = 42;
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__ : Base.prototype };
+  Derived.prototype.mSloppy = function () {
+    assertEquals(undefined, super[x]);
+    assertEquals(undefined, this[x]);
+    super[x] = 10;
+    assertEquals(10, this[x]);
+    assertEquals(undefined, super[x]);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function () {
+    'use strict';
+    assertEquals(undefined, super[x]);
+    assertEquals(undefined, this[x]);
+    super[x] = 10;
+    assertEquals(10, this[x]);
+    assertEquals(undefined, super[x]);
+  }.toMethod(Derived.prototype);
+  var d = new Derived();
+  d.mSloppy();
+  assertEquals(10, d[x]);
+  var d1 = new Derived();
+  d1.mStrict();
+  assertEquals(10, d[x]);
+}());
+
+
+(function TestSetterCreatingOwnProperties() {
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__ : Base.prototype };
+  var setterCalled;
+
+  Derived.prototype.mSloppy = function() {
+    assertEquals(42, this.ownReadOnly);
+    super.ownReadOnly = 55;
+    assertEquals(42, this.ownReadOnly);
+
+    assertEquals(15, this.ownReadonlyAccessor);
+    super.ownReadonlyAccessor = 55;
+    assertEquals(15, this.ownReadonlyAccessor);
+
+    setterCalled = 0;
+    super.ownSetter = 42;
+    assertEquals(1, setterCalled);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    assertEquals(42, this.ownReadOnly);
+    var ex;
+    try {
+      super.ownReadOnly = 55;
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(42, this.ownReadOnly);
+
+    assertEquals(15, this.ownReadonlyAccessor);
+    ex = null;
+    try {
+      super.ownReadonlyAccessor = 55;
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(15, this.ownReadonlyAccessor);
+
+    setterCalled = 0;
+    super.ownSetter = 42;
+    assertEquals(1, setterCalled);
+  }.toMethod(Derived.prototype);
+
+  var d = new Derived();
+  Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false });
+  Object.defineProperty(d, 'ownSetter',
+      { set : function() { setterCalled++; } });
+  Object.defineProperty(d, 'ownReadonlyAccessor',
+      { get : function() { return 15; }});
+  d.mSloppy();
+  d.mStrict();
+}());
+
+
+(function TestSetterInForIn() {
+  var setCalled = 0;
+  var getCalled = 0;
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      getCalled++;
+      return 1;
+    },
+    set x(v) {
+      setCalled++;
+      this.x_.push(v);
+    },
+  };
+
+  function Derived() {
+    this.x_ = [];
+  }
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+  };
+
+  Derived.prototype.testIter = function() {
+    setCalled = 0;
+    getCalled = 0;
+    for (super.x in [1,2,3]) {}
+    assertEquals(0, getCalled);
+    assertEquals(3, setCalled);
+    assertEquals(["0","1","2"], this.x_);
+  }.toMethod(Derived.prototype);
+
+  new Derived().testIter();
+
+  var x = 'x';
+  Derived.prototype.testIterKeyed = function() {
+    setCalled = 0;
+    getCalled = 0;
+    for (super[x] in [1,2,3]) {}
+    assertEquals(0, getCalled);
+    assertEquals(3, setCalled);
+    assertEquals(["0","1","2"], this.x_);
+
+    this.x_ = [];
+    setCalled = 0;
+    getCalled = 0;
+    var toStringCalled = 0;
+    var o = {toString: function () { toStringCalled++; return x }};
+    for (super[o] in [1,2,3]) {}
+    assertEquals(0, getCalled);
+    assertEquals(3, setCalled);
+    assertEquals(3, toStringCalled);
+    assertEquals(["0","1","2"], this.x_);
+  }.toMethod(Derived.prototype);
+
+  new Derived().testIterKeyed();
+}());
+
+
+(function TestKeyedSetterCreatingOwnProperties() {
+  var ownReadOnly = 'ownReadOnly';
+  var ownReadonlyAccessor = 'ownReadonlyAccessor';
+  var ownSetter = 'ownSetter';
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__ : Base.prototype };
+  var setterCalled;
+
+  Derived.prototype.mSloppy = function() {
+    assertEquals(42, this[ownReadOnly]);
+    super[ownReadOnly] = 55;
+    assertEquals(42, this[ownReadOnly]);
+
+    assertEquals(15, this[ownReadonlyAccessor]);
+    super[ownReadonlyAccessor] = 55;
+    assertEquals(15, this[ownReadonlyAccessor]);
+
+    setterCalled = 0;
+    super[ownSetter] = 42;
+    assertEquals(1, setterCalled);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    assertEquals(42, this[ownReadOnly]);
+    var ex;
+    try {
+      super[ownReadOnly] = 55;
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(42, this[ownReadOnly]);
+
+    assertEquals(15, this[ownReadonlyAccessor]);
+    ex = null;
+    try {
+      super[ownReadonlyAccessor] = 55;
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(15, this[ownReadonlyAccessor]);
+
+    setterCalled = 0;
+    super[ownSetter] = 42;
+    assertEquals(1, setterCalled);
+  }.toMethod(Derived.prototype);
+
+  var d = new Derived();
+  Object.defineProperty(d, 'ownReadOnly', { value : 42, writable : false });
+  Object.defineProperty(d, 'ownSetter',
+      { set : function() { setterCalled++; } });
+  Object.defineProperty(d, 'ownReadonlyAccessor',
+      { get : function() { return 15; }});
+  d.mSloppy();
+  d.mStrict();
+}());
+
+
+(function TestKeyedNumericSetterCreatingOwnProperties() {
+  var ownReadOnly = 42;
+  var ownReadonlyAccessor = 43;
+  var ownSetter = 44;
+  function Base() {}
+  function Derived() {}
+  Derived.prototype = { __proto__ : Base.prototype };
+  var setterCalled;
+
+  Derived.prototype.mSloppy = function() {
+    assertEquals(42, this[ownReadOnly]);
+    super[ownReadOnly] = 55;
+    assertEquals(42, this[ownReadOnly]);
+
+    assertEquals(15, this[ownReadonlyAccessor]);
+    super[ownReadonlyAccessor] = 55;
+    assertEquals(15, this[ownReadonlyAccessor]);
+
+    setterCalled = 0;
+    super[ownSetter] = 42;
+    assertEquals(1, setterCalled);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    assertEquals(42, this[ownReadOnly]);
+    var ex;
+    try {
+      super[ownReadOnly] = 55;
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(42, this[ownReadOnly]);
+
+    assertEquals(15, this[ownReadonlyAccessor]);
+    ex = null;
+    try {
+      super[ownReadonlyAccessor] = 55;
+    } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(15, this[ownReadonlyAccessor]);
+
+    setterCalled = 0;
+    super[ownSetter] = 42;
+    assertEquals(1, setterCalled);
+  }.toMethod(Derived.prototype);
+
+  var d = new Derived();
+  Object.defineProperty(d, ownReadOnly, { value : 42, writable : false });
+  Object.defineProperty(d, ownSetter,
+      { set : function() { setterCalled++; } });
+  Object.defineProperty(d, ownReadonlyAccessor,
+      { get : function() { return 15; }});
+  d.mSloppy();
+  d.mStrict();
+}());
+
+
+(function TestSetterNoProtoWalk() {
+  function Base() {}
+  function Derived() {}
+  var getCalled;
+  var setCalled;
+  Derived.prototype = {
+    __proto__ : Base.prototype,
+    get x() { getCalled++; return 42; },
+    set x(v) { setCalled++; }
+  };
+
+  Derived.prototype.mSloppy = function() {
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals(42, this.x);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    this.x = 43;
+    assertEquals(0, getCalled);
+    assertEquals(1, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    super.x = 15;
+    assertEquals(0, setCalled);
+    assertEquals(0, getCalled);
+
+    assertEquals(15, this.x);
+    assertEquals(0, getCalled);
+    assertEquals(0, setCalled);
+
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals(42, this.x);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    this.x = 43;
+    assertEquals(0, getCalled);
+    assertEquals(1, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    super.x = 15;
+    assertEquals(0, setCalled);
+    assertEquals(0, getCalled);
+
+    assertEquals(15, this.x);
+    assertEquals(0, getCalled);
+    assertEquals(0, setCalled);
+
+  }.toMethod(Derived.prototype);
+
+  new Derived().mSloppy();
+  new Derived().mStrict();
+}());
+
+
+(function TestKeyedSetterNoProtoWalk() {
+  var x = 'x';
+  function Base() {}
+  function Derived() {}
+  var getCalled;
+  var setCalled;
+  Derived.prototype = {
+    __proto__ : Base.prototype,
+    get x() { getCalled++; return 42; },
+    set x(v) { setCalled++; }
+  };
+
+  Derived.prototype.mSloppy = function() {
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals(42, this[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    this[x] = 43;
+    assertEquals(0, getCalled);
+    assertEquals(1, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    super[x] = 15;
+    assertEquals(0, setCalled);
+    assertEquals(0, getCalled);
+
+    assertEquals(15, this[x]);
+    assertEquals(0, getCalled);
+    assertEquals(0, setCalled);
+
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals(42, this[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    this[x] = 43;
+    assertEquals(0, getCalled);
+    assertEquals(1, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    super[x] = 15;
+    assertEquals(0, setCalled);
+    assertEquals(0, getCalled);
+
+    assertEquals(15, this[x]);
+    assertEquals(0, getCalled);
+    assertEquals(0, setCalled);
+
+  }.toMethod(Derived.prototype);
+
+  new Derived().mSloppy();
+  new Derived().mStrict();
+}());
+
+
+(function TestKeyedNumericSetterNoProtoWalk() {
+  var x = 42;
+  function Base() {}
+  function Derived() {}
+  var getCalled;
+  var setCalled;
+  Derived.prototype = {
+    __proto__ : Base.prototype,
+  };
+
+  Object.defineProperty(Derived.prototype, x, {
+    get: function() { getCalled++; return 42; },
+    set: function(v) { setCalled++; }
+  });
+
+  Derived.prototype.mSloppy = function() {
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals(42, this[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    this[x] = 43;
+    assertEquals(0, getCalled);
+    assertEquals(1, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    super[x] = 15;
+    assertEquals(0, setCalled);
+    assertEquals(0, getCalled);
+
+    assertEquals(15, this[x]);
+    assertEquals(0, getCalled);
+    assertEquals(0, setCalled);
+
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    setCalled = 0;
+    getCalled = 0;
+    assertEquals(42, this[x]);
+    assertEquals(1, getCalled);
+    assertEquals(0, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    this[x] = 43;
+    assertEquals(0, getCalled);
+    assertEquals(1, setCalled);
+
+    getCalled = 0;
+    setCalled = 0;
+    super[x] = 15;
+    assertEquals(0, setCalled);
+    assertEquals(0, getCalled);
+
+    assertEquals(15, this[x]);
+    assertEquals(0, getCalled);
+    assertEquals(0, setCalled);
+
+  }.toMethod(Derived.prototype);
+
+  new Derived().mSloppy();
+  new Derived().mStrict();
+}());
+
+
+(function TestSetterDoesNotReconfigure() {
+  function Base() {}
+  function Derived() {}
+
+  Derived.prototype.mStrict = function (){
+    'use strict';
+    super.nonEnumConfig = 5;
+    var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig');
+    assertEquals(5, d1.value);
+    assertTrue(d1.configurable);
+    assertFalse(d1.enumerable);
+
+    super.nonEnumNonConfig = 5;
+    var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig');
+    assertEquals(5, d1.value);
+    assertFalse(d1.configurable);
+    assertFalse(d1.enumerable);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mSloppy = function (){
+    super.nonEnumConfig = 42;
+    var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumConfig');
+    assertEquals(42, d1.value);
+    assertTrue(d1.configurable);
+    assertFalse(d1.enumerable);
+
+    super.nonEnumNonConfig = 42;
+    var d1 = Object.getOwnPropertyDescriptor(this, 'nonEnumNonConfig');
+    assertEquals(42, d1.value);
+    assertFalse(d1.configurable);
+    assertFalse(d1.enumerable);
+  }.toMethod(Derived.prototype);
+
+  var d = new Derived();
+  Object.defineProperty(d, 'nonEnumConfig',
+      { value : 0, enumerable : false, configurable : true, writable : true });
+  Object.defineProperty(d, 'nonEnumNonConfig',
+      { value : 0, enumerable : false, configurable : false, writable : true });
+  d.mStrict();
+  d.mSloppy();
+}());
+
+
+(function TestKeyedSetterDoesNotReconfigure() {
+  var nonEnumConfig = 'nonEnumConfig';
+  var nonEnumNonConfig = 'nonEnumNonConfig';
+  function Base() {}
+  function Derived() {}
+
+  Derived.prototype = { __proto__: Base.prototype };
+
+  Derived.prototype.mStrict = function (){
+    'use strict';
+    super[nonEnumConfig] = 5;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
+    assertEquals(5, d1.value);
+    assertTrue(d1.configurable);
+    assertFalse(d1.enumerable);
+
+    super[nonEnumNonConfig] = 5;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
+    assertEquals(5, d1.value);
+    assertFalse(d1.configurable);
+    assertFalse(d1.enumerable);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mSloppy = function (){
+    super[nonEnumConfig] = 42;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
+    assertEquals(42, d1.value);
+    assertTrue(d1.configurable);
+    assertFalse(d1.enumerable);
+
+    super[nonEnumNonConfig] = 42;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
+    assertEquals(42, d1.value);
+    assertFalse(d1.configurable);
+    assertFalse(d1.enumerable);
+  }.toMethod(Derived.prototype);
+
+  var d = new Derived();
+  Object.defineProperty(d, nonEnumConfig,
+      { value : 0, enumerable : false, configurable : true, writable : true });
+  Object.defineProperty(d, nonEnumNonConfig,
+      { value : 0, enumerable : false, configurable : false, writable : true });
+  d.mStrict();
+  d.mSloppy();
+}());
+
+
+(function TestKeyedNumericSetterDoesNotReconfigure() {
+  var nonEnumConfig = 42;
+  var nonEnumNonConfig = 43;
+  function Base() {}
+  function Derived() {}
+
+  Derived.prototype = { __proto__: Base.prototype };
+
+  Derived.prototype.mStrict = function (){
+    'use strict';
+    super[nonEnumConfig] = 5;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
+    assertEquals(5, d1.value);
+    assertTrue(d1.configurable);
+    assertFalse(d1.enumerable);
+
+    super[nonEnumNonConfig] = 5;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
+    assertEquals(5, d1.value);
+    assertFalse(d1.configurable);
+    assertFalse(d1.enumerable);
+  }.toMethod(Derived.prototype);
+
+  Derived.prototype.mSloppy = function (){
+    super[nonEnumConfig] = 42;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumConfig);
+    assertEquals(42, d1.value);
+    assertTrue(d1.configurable);
+    assertFalse(d1.enumerable);
+
+    super[nonEnumNonConfig] = 42;
+    var d1 = Object.getOwnPropertyDescriptor(this, nonEnumNonConfig);
+    assertEquals(42, d1.value);
+    assertFalse(d1.configurable);
+    assertFalse(d1.enumerable);
+  }.toMethod(Derived.prototype);
+
+  var d = new Derived();
+  Object.defineProperty(d, nonEnumConfig,
+      { value : 0, enumerable : false, configurable : true, writable : true });
+  Object.defineProperty(d, nonEnumNonConfig,
+      { value : 0, enumerable : false, configurable : false, writable : true });
+  d.mStrict();
+  d.mSloppy();
+}());
+
+
+(function TestCountOperations() {
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      return this._x;
+    },
+    set x(v) {
+      this._x = v;
+    },
+    _x: 1
+  };
+
+  function Derived() {}
+  Derived.__proto__ = Base;
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+    _x: 2
+  };
+
+  Derived.prototype.testCounts = function() {
+    assertEquals(2, this._x);
+    assertEquals(2, super.x);
+    super.x++;
+    assertEquals(3, super.x);
+    ++super.x;
+    assertEquals(4, super.x);
+    assertEquals(4, super.x++);
+    assertEquals(5, super.x);
+    assertEquals(6, ++super.x);
+    assertEquals(6, super.x);
+    assertEquals(6, this._x);
+
+    super.x--;
+    assertEquals(5, super.x);
+    --super.x;
+    assertEquals(4, super.x);
+    assertEquals(4, super.x--);
+    assertEquals(3, super.x);
+    assertEquals(2, --super.x);
+    assertEquals(2, super.x);
+    assertEquals(2, this._x);
+  }.toMethod(Derived.prototype);
+  new Derived().testCounts();
+}());
+
+
+(function TestKeyedCountOperations() {
+  var x = 'x';
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    get x() {
+      return this._x;
+    },
+    set x(v) {
+      this._x = v;
+    },
+    _x: 1
+  };
+
+  function Derived() {}
+  Derived.__proto__ = Base;
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+    _x: 2
+  };
+
+  Derived.prototype.testCounts = function() {
+    assertEquals(2, this._x);
+    assertEquals(2, super[x]);
+    super[x]++;
+    assertEquals(3, super[x]);
+    ++super[x];
+    assertEquals(4, super[x]);
+    assertEquals(4, super[x]++);
+    assertEquals(5, super[x]);
+    assertEquals(6, ++super[x]);
+    assertEquals(6, super[x]);
+    assertEquals(6, this._x);
+
+    super[x]--;
+    assertEquals(5, super[x]);
+    --super[x];
+    assertEquals(4, super[x]);
+    assertEquals(4, super[x]--);
+    assertEquals(3, super[x]);
+    assertEquals(2, --super[x]);
+    assertEquals(2, super[x]);
+    assertEquals(2, this._x);
+  }.toMethod(Derived.prototype);
+  new Derived().testCounts();
+}());
+
+
+(function TestKeyedNumericCountOperations() {
+  var x = 42;
+  function Base() {}
+  Base.prototype = {
+    constructor: Base,
+    _x: 1
+  };
+
+  Object.defineProperty(Base.prototype, x, {
+    get: function() { return this._x; },
+    set: function(v) { this._x = v;; }
+  });
+
+  function Derived() {}
+  Derived.__proto__ = Base;
+  Derived.prototype = {
+    __proto__: Base.prototype,
+    constructor: Derived,
+    _x: 2
+  };
+
+  Derived.prototype.testCounts = function() {
+    assertEquals(2, this._x);
+    assertEquals(2, super[x]);
+    super[x]++;
+    assertEquals(3, super[x]);
+    ++super[x];
+    assertEquals(4, super[x]);
+    assertEquals(4, super[x]++);
+    assertEquals(5, super[x]);
+    assertEquals(6, ++super[x]);
+    assertEquals(6, super[x]);
+    assertEquals(6, this._x);
+
+    super[x]--;
+    assertEquals(5, super[x]);
+    --super[x];
+    assertEquals(4, super[x]);
+    assertEquals(4, super[x]--);
+    assertEquals(3, super[x]);
+    assertEquals(2, --super[x]);
+    assertEquals(2, super[x]);
+    assertEquals(2, this._x);
+  }.toMethod(Derived.prototype);
+  new Derived().testCounts();
+}());
+
+
+(function TestSetterSuperNonWritable() {
+  function Base() {}
+  Object.defineProperty(Base.prototype, 'x', { value : 27, writable: false });
+  function Derived() {}
+
+  Derived.prototype = { __proto__: Base.prototype, constructor: Derived };
+
+  Derived.prototype.mSloppy = function() {
+    assertEquals(27, super.x);
+    assertEquals(27, this.x);
+    super.x = 10;
+    assertEquals(27, super.x);
+    assertEquals(27, this.x);
+  }.toMethod(Derived.prototype);
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    assertEquals(27, super.x);
+    assertEquals(27, this.x);
+    var ex = null;
+    try { super.x = 10; } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(27, super.x);
+    assertEquals(27, this.x);
+  }.toMethod(Derived.prototype);
+  new Derived().mSloppy();
+  new Derived().mStrict();
+}());
+
+
+(function TestSetterKeyedSuperNonWritable() {
+  var x = 'xyz';
+  function Base() {}
+  Object.defineProperty(Base.prototype, x, { value : 27, writable: false });
+  function Derived() {}
+
+  Derived.prototype = { __proto__: Base.prototype, constructor: Derived };
+
+  Derived.prototype.mSloppy = function() {
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+    super[x] = 10;
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+  }.toMethod(Derived.prototype);
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+    var ex = null;
+    try { super[x] = 10; } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+  }.toMethod(Derived.prototype);
+  new Derived().mSloppy();
+  new Derived().mStrict();
+}());
+
+
+(function TestSetterKeyedNumericSuperNonWritable() {
+  var x = 42;
+  function Base() {}
+  Object.defineProperty(Base.prototype, x, { value : 27, writable: false });
+  function Derived() {}
+
+  Derived.prototype = { __proto__: Base.prototype, constructor: Derived };
+
+  Derived.prototype.mSloppy = function() {
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+    super[x] = 10;
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+  }.toMethod(Derived.prototype);
+  Derived.prototype.mStrict = function() {
+    'use strict';
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+    var ex = null;
+    try { super[x] = 10; } catch(e) { ex = e; }
+    assertTrue(ex instanceof TypeError);
+    assertEquals(27, super[x]);
+    assertEquals(27, this[x]);
+  }.toMethod(Derived.prototype);
+  new Derived().mSloppy();
+  new Derived().mStrict();
+}());
+
+
+function Subclass(base, constructor) {
+  var homeObject = {
+    __proto__: base.prototype,
+    constructor: constructor
+  };
+  constructor.__proto__ = base;
+  constructor.prototype = homeObject;
+  // not doing toMethod: home object is not required for
+  // super constructor calls.
+  return constructor;
+}
+
+(function TestSuperCall() {
+  var baseCalled = 0;
+  var derivedCalled = 0;
+  var derivedDerivedCalled = 0;
+
+  function Base() {
+    baseCalled++;
+  }
+
+  var Derived = Subclass(Base, function () {
+    super();
+    derivedCalled++;
+  });
+
+  assertEquals(Base, Base.prototype.constructor);
+  assertEquals(Base.prototype, Derived.prototype.__proto__);
+
+  baseCalled = 0;
+  derivedCalled = 0;
+  new Derived();
+  assertEquals(1, baseCalled);
+  assertEquals(1, derivedCalled);
+
+  var DerivedDerived = Subclass(Derived, function () {
+    super();
+    derivedDerivedCalled++;
+  });
+
+  baseCalled = 0;
+  derivedCalled = 0;
+  derivedDerivedCalled = 0;
+  new DerivedDerived();
+  assertEquals(1, baseCalled);
+  assertEquals(1, derivedCalled);
+  assertEquals(1, derivedDerivedCalled);
+
+  function Base2(v) {
+    this.fromBase = v;
+  }
+  var Derived2 = Subclass(Base2, function (v1, v2) {
+    super(v1);
+    this.fromDerived = v2;
+  });
+
+  var d = new Derived2("base", "derived");
+  assertEquals("base", d.fromBase);
+  assertEquals("derived", d.fromDerived);
+
+  function ImplicitSubclassOfFunction() {
+    super();
+    this.x = 123;
+  }
+
+  var o = new ImplicitSubclassOfFunction();
+  assertEquals(123, o.x);
+
+  var calls = 0;
+  function G() {
+    calls++;
+  }
+  function F() {
+    super();
+  }
+  F.__proto__ = G;
+  new F();
+  assertEquals(1, calls);
+  F.__proto__ = function() {};
+  new F();
+  assertEquals(1, calls);
+}());
+
+
+(function TestNewSuper() {
+  var baseCalled = 0;
+  var derivedCalled = 0;
+
+  function Base() {
+    baseCalled++;
+    this.x = 15;
+  }
+
+
+  var Derived = Subclass(Base, function() {
+    baseCalled = 0;
+    var b = new super();
+    assertEquals(1, baseCalled)
+    assertEquals(Base.prototype, b.__proto__);
+    assertEquals(15, b.x);
+    assertEquals(undefined, this.x);
+    derivedCalled++;
+  });
+
+  derivedCalled = 0;
+  new Derived();
+  assertEquals(1, derivedCalled);
+}());
+
+
+(function TestSuperCallErrorCases() {
+  function T() {
+    super();
+  }
+  T.__proto__ = null;
+  // Spec says ReferenceError here, but for other IsCallable failures
+  // we throw TypeError.
+  // Filed https://bugs.ecmascript.org/show_bug.cgi?id=3282
+  assertThrows(function() { new T(); }, TypeError);
+
+  function T1() {
+    var b = new super();
+  }
+  T1.__proto = null;
+  assertThrows(function() { new T1(); }, TypeError);
+}());
+
+
+(function TestSuperCallSyntacticRestriction() {
+  assertThrows(function() {
+    function C() {
+        var y;
+        super();
+    }
+    new C();
+  }, TypeError);
+  assertThrows(function() {
+    function C() {
+      super(this.x);
+    }
+    new C();
+  }, TypeError);
+  assertThrows(function() {
+    function C() {
+      super(this);
+    }
+    new C();
+  }, TypeError);
+  assertThrows(function() {
+    function C() {
+      super(1, 2, Object.getPrototypeOf(this));
+    }
+    new C();
+  }, TypeError);
+  assertThrows(function() {
+    function C() {
+      { super(1, 2); }
+    }; new C();
+  }, TypeError);
+  assertThrows(function() {
+    function C() {
+      if (1) super();
+    }; new C();
+  }, TypeError);
+
+  function C1() {
+    'use strict';
+    super();
+  };
+  new C1();
+
+  function C2() {
+    ; 'use strict';;;;;
+    super();
+  };
+  new C2();
+
+  function C3() {
+    ; 'use strict';;;;;
+    // This is a comment.
+    super();
+  }
+  new C3();
+}());
diff --git a/test/mjsunit/harmony/templates.js b/test/mjsunit/harmony/templates.js
new file mode 100644
index 0000000..c339bb8
--- /dev/null
+++ b/test/mjsunit/harmony/templates.js
@@ -0,0 +1,507 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-templates --harmony-unicode
+
+var num = 5;
+var str = "str";
+function fn() { return "result"; }
+var obj = {
+  num: num,
+  str: str,
+  fn: function() { return "result"; }
+};
+
+(function testBasicExpressions() {
+  assertEquals("foo 5 bar", `foo ${num} bar`);
+  assertEquals("foo str bar", `foo ${str} bar`);
+  assertEquals("foo [object Object] bar", `foo ${obj} bar`);
+  assertEquals("foo result bar", `foo ${fn()} bar`);
+  assertEquals("foo 5 bar", `foo ${obj.num} bar`);
+  assertEquals("foo str bar", `foo ${obj.str} bar`);
+  assertEquals("foo result bar", `foo ${obj.fn()} bar`);
+})();
+
+(function testExpressionsContainingTemplates() {
+  assertEquals("foo bar 5", `foo ${`bar ${num}`}`);
+})();
+
+(function testMultilineTemplates() {
+  assertEquals("foo\n    bar\n    baz", `foo
+    bar
+    baz`);
+
+  assertEquals("foo\n  bar\n  baz", eval("`foo\r\n  bar\r  baz`"));
+})();
+
+(function testLineContinuation() {
+  assertEquals("\n", `\
+
+`);
+})();
+
+(function testTaggedTemplates() {
+  var calls = 0;
+  (function(s) {
+    calls++;
+  })`test`;
+  assertEquals(1, calls);
+
+  calls = 0;
+  // assert tag is invoked in right context
+  obj = {
+    fn: function() {
+      calls++;
+      assertEquals(obj, this);
+    }
+  };
+
+  obj.fn`test`;
+  assertEquals(1, calls);
+
+  calls = 0;
+  // Simple templates only have a callSiteObj
+  (function(s) {
+    calls++;
+    assertEquals(1, arguments.length);
+  })`test`;
+  assertEquals(1, calls);
+
+  // Templates containing expressions have the values of evaluated expressions
+  calls = 0;
+  (function(site, n, s, o, f, r) {
+    calls++;
+    assertEquals(6, arguments.length);
+    assertEquals("number", typeof n);
+    assertEquals("string", typeof s);
+    assertEquals("object", typeof o);
+    assertEquals("function", typeof f);
+    assertEquals("result", r);
+  })`${num}${str}${obj}${fn}${fn()}`;
+  assertEquals(1, calls);
+
+  // The TV and TRV of NoSubstitutionTemplate :: `` is the empty code unit
+  // sequence.
+  calls = 0;
+  (function(s) {
+    calls++;
+    assertEquals(1, s.length);
+    assertEquals(1, s.raw.length);
+    assertEquals("", s[0]);
+
+    // Failure: expected <""> found <"foo  barfoo  barfoo foo foo foo testtest">
+    assertEquals("", s.raw[0]);
+  })``;
+  assertEquals(1, calls);
+
+  // The TV and TRV of TemplateHead :: `${ is the empty code unit sequence.
+  calls = 0;
+  (function(s) {
+    calls++;
+    assertEquals(2, s.length);
+    assertEquals(2, s.raw.length);
+    assertEquals("", s[0]);
+    assertEquals("", s.raw[0]);
+  })`${1}`;
+  assertEquals(1, calls);
+
+  // The TV and TRV of TemplateMiddle :: }${ is the empty code unit sequence.
+  calls = 0;
+  (function(s) {
+    calls++;
+    assertEquals(3, s.length);
+    assertEquals(3, s.raw.length);
+    assertEquals("", s[1]);
+    assertEquals("", s.raw[1]);
+  })`${1}${2}`;
+  assertEquals(1, calls);
+
+  // The TV and TRV of TemplateTail :: }` is the empty code unit sequence.
+  calls = 0;
+  (function(s) {
+    calls++;
+    assertEquals(2, s.length);
+    assertEquals(2, s.raw.length);
+    assertEquals("", s[1]);
+    assertEquals("", s.raw[1]);
+  })`${1}`;
+  assertEquals(1, calls);
+
+  // The TV of NoSubstitutionTemplate :: ` TemplateCharacters ` is the TV of
+  // TemplateCharacters.
+  calls = 0;
+  (function(s) { calls++; assertEquals("foo", s[0]); })`foo`;
+  assertEquals(1, calls);
+
+  // The TV of TemplateHead :: ` TemplateCharacters ${ is the TV of
+  // TemplateCharacters.
+  calls = 0;
+  (function(s) { calls++; assertEquals("foo", s[0]); })`foo${1}`;
+  assertEquals(1, calls);
+
+  // The TV of TemplateMiddle :: } TemplateCharacters ${ is the TV of
+  // TemplateCharacters.
+  calls = 0;
+  (function(s) { calls++; assertEquals("foo", s[1]); })`${1}foo${2}`;
+  assertEquals(1, calls);
+
+  // The TV of TemplateTail :: } TemplateCharacters ` is the TV of
+  // TemplateCharacters.
+  calls = 0;
+  (function(s) { calls++; assertEquals("foo", s[1]); })`${1}foo`;
+  assertEquals(1, calls);
+
+  // The TV of TemplateCharacters :: TemplateCharacter is the TV of
+  // TemplateCharacter.
+  calls = 0;
+  (function(s) { calls++; assertEquals("f", s[0]); })`f`;
+  assertEquals(1, calls);
+
+  // The TV of TemplateCharacter :: $ is the code unit value 0x0024.
+  calls = 0;
+  (function(s) { calls++; assertEquals("$", s[0]); })`$`;
+  assertEquals(1, calls);
+
+  // The TV of TemplateCharacter :: \ EscapeSequence is the CV of
+  // EscapeSequence.
+  calls = 0;
+  (function(s) { calls++; assertEquals("안녕", s[0]); })`\uc548\uB155`;
+  (function(s) { calls++; assertEquals("\xff", s[0]); })`\xff`;
+  (function(s) { calls++; assertEquals("\n", s[0]); })`\n`;
+  assertEquals(3, calls);
+
+  // The TV of TemplateCharacter :: LineContinuation is the TV of
+  // LineContinuation. The TV of LineContinuation :: \ LineTerminatorSequence is
+  // the empty code unit sequence.
+  calls = 0;
+  (function(s) { calls++; assertEquals("", s[0]); })`\
+`;
+  assertEquals(1, calls);
+
+  // The TRV of NoSubstitutionTemplate :: ` TemplateCharacters ` is the TRV of
+  // TemplateCharacters.
+  calls = 0;
+  (function(s) { calls++; assertEquals("test", s.raw[0]); })`test`;
+  assertEquals(1, calls);
+
+  // The TRV of TemplateHead :: ` TemplateCharacters ${ is the TRV of
+  // TemplateCharacters.
+  calls = 0;
+  (function(s) { calls++; assertEquals("test", s.raw[0]); })`test${1}`;
+  assertEquals(1, calls);
+
+  // The TRV of TemplateMiddle :: } TemplateCharacters ${ is the TRV of
+  // TemplateCharacters.
+  calls = 0;
+  (function(s) { calls++; assertEquals("test", s.raw[1]); })`${1}test${2}`;
+  assertEquals(1, calls);
+
+  // The TRV of TemplateTail :: } TemplateCharacters ` is the TRV of
+  // TemplateCharacters.
+  calls = 0;
+  (function(s) { calls++; assertEquals("test", s.raw[1]); })`${1}test`;
+  assertEquals(1, calls);
+
+  // The TRV of TemplateCharacters :: TemplateCharacter is the TRV of
+  // TemplateCharacter.
+  calls = 0;
+  (function(s) { calls++; assertEquals("f", s.raw[0]); })`f`;
+  assertEquals(1, calls);
+
+  // The TRV of TemplateCharacter :: $ is the code unit value 0x0024.
+  calls = 0;
+  (function(s) { calls++; assertEquals("\u0024", s.raw[0]); })`$`;
+  assertEquals(1, calls);
+
+  // The TRV of EscapeSequence :: 0 is the code unit value 0x0030.
+  calls = 0;
+  (function(s) { calls++; assertEquals("\u005C\u0030", s.raw[0]); })`\0`;
+  assertEquals(1, calls);
+
+  // The TRV of TemplateCharacter :: \ EscapeSequence is the sequence consisting
+  // of the code unit value 0x005C followed by the code units of TRV of
+  // EscapeSequence.
+
+  //   The TRV of EscapeSequence :: HexEscapeSequence is the TRV of the
+  //   HexEscapeSequence.
+  calls = 0;
+  (function(s) { calls++; assertEquals("\u005Cxff", s.raw[0]); })`\xff`;
+  assertEquals(1, calls);
+
+  //   The TRV of EscapeSequence :: UnicodeEscapeSequence is the TRV of the
+  //   UnicodeEscapeSequence.
+  calls = 0;
+  (function(s) { calls++; assertEquals("\u005Cuc548", s.raw[0]); })`\uc548`;
+  assertEquals(1, calls);
+
+  //   The TRV of CharacterEscapeSequence :: SingleEscapeCharacter is the TRV of
+  //   the SingleEscapeCharacter.
+  calls = 0;
+  (function(s) { calls++; assertEquals("\u005C\u0027", s.raw[0]); })`\'`;
+  (function(s) { calls++; assertEquals("\u005C\u0022", s.raw[0]); })`\"`;
+  (function(s) { calls++; assertEquals("\u005C\u005C", s.raw[0]); })`\\`;
+  (function(s) { calls++; assertEquals("\u005Cb", s.raw[0]); })`\b`;
+  (function(s) { calls++; assertEquals("\u005Cf", s.raw[0]); })`\f`;
+  (function(s) { calls++; assertEquals("\u005Cn", s.raw[0]); })`\n`;
+  (function(s) { calls++; assertEquals("\u005Cr", s.raw[0]); })`\r`;
+  (function(s) { calls++; assertEquals("\u005Ct", s.raw[0]); })`\t`;
+  (function(s) { calls++; assertEquals("\u005Cv", s.raw[0]); })`\v`;
+  (function(s) { calls++; assertEquals("\u005C`", s.raw[0]); })`\``;
+  assertEquals(10, calls);
+
+  //   The TRV of CharacterEscapeSequence :: NonEscapeCharacter is the CV of the
+  //   NonEscapeCharacter.
+  calls = 0;
+  (function(s) { calls++; assertEquals("\u005Cz", s.raw[0]); })`\z`;
+  assertEquals(1, calls);
+
+  // The TRV of LineTerminatorSequence :: <LF> is the code unit value 0x000A.
+  // The TRV of LineTerminatorSequence :: <CR> is the code unit value 0x000A.
+  // The TRV of LineTerminatorSequence :: <CR><LF> is the sequence consisting of
+  // the code unit value 0x000A.
+  calls = 0;
+  function testRawLineNormalization(cs) {
+    calls++;
+    assertEquals(cs.raw[0], "\n\n\n");
+    assertEquals(cs.raw[1], "\n\n\n");
+  }
+  eval("testRawLineNormalization`\r\n\n\r${1}\r\n\n\r`");
+  assertEquals(1, calls);
+
+  // The TRV of LineContinuation :: \ LineTerminatorSequence is the sequence
+  // consisting of the code unit value 0x005C followed by the code units of TRV
+  // of LineTerminatorSequence.
+  calls = 0;
+  function testRawLineContinuation(cs) {
+    calls++;
+    assertEquals(cs.raw[0], "\u005C\n\u005C\n\u005C\n");
+    assertEquals(cs.raw[1], "\u005C\n\u005C\n\u005C\n");
+  }
+  eval("testRawLineContinuation`\\\r\n\\\n\\\r${1}\\\r\n\\\n\\\r`");
+  assertEquals(1, calls);
+})();
+
+
+(function testCallSiteObj() {
+  var calls = 0;
+  function tag(cs) {
+    calls++;
+    assertTrue(cs.hasOwnProperty("raw"));
+    assertTrue(Object.isFrozen(cs));
+    assertTrue(Object.isFrozen(cs.raw));
+    var raw = Object.getOwnPropertyDescriptor(cs, "raw");
+    assertFalse(raw.writable);
+    assertFalse(raw.configurable);
+    assertFalse(raw.enumerable);
+    assertEquals(Array.prototype, Object.getPrototypeOf(cs.raw));
+    assertTrue(Array.isArray(cs.raw));
+    assertEquals(Array.prototype, Object.getPrototypeOf(cs));
+    assertTrue(Array.isArray(cs));
+
+    var cooked0 = Object.getOwnPropertyDescriptor(cs, "0");
+    assertFalse(cooked0.writable);
+    assertFalse(cooked0.configurable);
+    assertTrue(cooked0.enumerable);
+
+    var raw0 = Object.getOwnPropertyDescriptor(cs.raw, "0");
+    assertFalse(cooked0.writable);
+    assertFalse(cooked0.configurable);
+    assertTrue(cooked0.enumerable);
+
+    var length = Object.getOwnPropertyDescriptor(cs, "length");
+    assertFalse(length.writable);
+    assertFalse(length.configurable);
+    assertFalse(length.enumerable);
+
+    length = Object.getOwnPropertyDescriptor(cs.raw, "length");
+    assertFalse(length.writable);
+    assertFalse(length.configurable);
+    assertFalse(length.enumerable);
+  }
+  tag`${1}`;
+  assertEquals(1, calls);
+})();
+
+
+(function testUTF16ByteOrderMark() {
+  assertEquals("\uFEFFtest", `\uFEFFtest`);
+  assertEquals("\uFEFFtest", eval("`\uFEFFtest`"));
+})();
+
+
+(function testStringRawAsTagFn() {
+  assertEquals("\\u0065\\`\\r\\r\\n\\ntestcheck",
+               String.raw`\u0065\`\r\r\n\n${"test"}check`);
+  assertEquals("\\\n\\\n\\\n", eval("String.raw`\\\r\\\r\n\\\n`"));
+  assertEquals("", String.raw``);
+})();
+
+
+(function testCallSiteCaching() {
+  var callSites = [];
+  function tag(cs) { callSites.push(cs); }
+  var a = 1;
+  var b = 2;
+
+  tag`head${a}tail`;
+  tag`head${b}tail`;
+
+  assertEquals(2, callSites.length);
+  assertSame(callSites[0], callSites[1]);
+
+  eval("tag`head${a}tail`");
+  assertEquals(3, callSites.length);
+  assertSame(callSites[1], callSites[2]);
+
+  eval("tag`head${b}tail`");
+  assertEquals(4, callSites.length);
+  assertSame(callSites[2], callSites[3]);
+
+  (new Function("tag", "a", "b", "return tag`head${a}tail`;"))(tag, 1, 2);
+  assertEquals(5, callSites.length);
+  assertSame(callSites[3], callSites[4]);
+
+  (new Function("tag", "a", "b", "return tag`head${b}tail`;"))(tag, 1, 2);
+  assertEquals(6, callSites.length);
+  assertSame(callSites[4], callSites[5]);
+
+  callSites = [];
+
+  tag`foo${a}bar`;
+  tag`foo\${.}bar`;
+  assertEquals(2, callSites.length);
+  assertEquals(2, callSites[0].length);
+  assertEquals(1, callSites[1].length);
+
+  callSites = [];
+
+  eval("tag`\\\r\n\\\n\\\r`");
+  eval("tag`\\\r\n\\\n\\\r`");
+  assertEquals(2, callSites.length);
+  assertSame(callSites[0], callSites[1]);
+  assertEquals("", callSites[0][0]);
+  assertEquals("\\\n\\\n\\\n", callSites[0].raw[0]);
+
+  callSites = [];
+
+  tag`\uc548\ub155`;
+  tag`\uc548\ub155`;
+  assertEquals(2, callSites.length);
+  assertSame(callSites[0], callSites[1]);
+  assertEquals("안녕", callSites[0][0]);
+  assertEquals("\\uc548\\ub155", callSites[0].raw[0]);
+
+  callSites = [];
+
+  tag`\uc548\ub155`;
+  tag`안녕`;
+  assertEquals(2, callSites.length);
+  assertTrue(callSites[0] !== callSites[1]);
+  assertEquals("안녕", callSites[0][0]);
+  assertEquals("\\uc548\\ub155", callSites[0].raw[0]);
+  assertEquals("안녕", callSites[1][0]);
+  assertEquals("안녕", callSites[1].raw[0]);
+
+  // Extra-thorough UTF8 decoding test.
+  callSites = [];
+
+  tag`Iñtërnâtiônàlizætiøn\u2603\uD83D\uDCA9`;
+  tag`Iñtërnâtiônàlizætiøn☃💩`;
+
+  assertEquals(2, callSites.length);
+  assertTrue(callSites[0] !== callSites[1]);
+  assertEquals("Iñtërnâtiônàlizætiøn☃💩", callSites[0][0]);
+  assertEquals(
+      "Iñtërnâtiônàlizætiøn\\u2603\\uD83D\\uDCA9", callSites[0].raw[0]);
+  assertEquals("Iñtërnâtiônàlizætiøn☃💩", callSites[1][0]);
+  assertEquals("Iñtërnâtiônàlizætiøn☃💩", callSites[1].raw[0]);
+})();
+
+
+(function testExtendedArrayPrototype() {
+  Object.defineProperty(Array.prototype, 0, {
+    set: function() {
+      assertUnreachable();
+    }
+  });
+  function tag(){}
+  tag`a${1}b`;
+})();
+
+
+(function testRawLineNormalization() {
+  function raw0(callSiteObj) {
+    return callSiteObj.raw[0];
+  }
+  assertEquals(eval("raw0`\r`"), "\n");
+  assertEquals(eval("raw0`\r\n`"), "\n");
+  assertEquals(eval("raw0`\r\r\n`"), "\n\n");
+  assertEquals(eval("raw0`\r\n\r\n`"), "\n\n");
+  assertEquals(eval("raw0`\r\r\r\n`"), "\n\n\n");
+})();
+
+
+(function testHarmonyUnicode() {
+  function raw0(callSiteObj) {
+    return callSiteObj.raw[0];
+  }
+  assertEquals(raw0`a\u{62}c`, "a\\u{62}c");
+  assertEquals(raw0`a\u{000062}c`, "a\\u{000062}c");
+  assertEquals(raw0`a\u{0}c`, "a\\u{0}c");
+
+  assertEquals(`a\u{62}c`, "abc");
+  assertEquals(`a\u{000062}c`, "abc");
+})();
+
+
+(function testLiteralAfterRightBrace() {
+  // Regression test for https://code.google.com/p/v8/issues/detail?id=3734
+  function f() {}
+  `abc`;
+
+  function g() {}`def`;
+
+  {
+    // block
+  }
+  `ghi`;
+
+  {
+    // block
+  }`jkl`;
+})();
+
+
+(function testLegacyOctal() {
+  assertEquals('\u0000', `\0`);
+  assertEquals('\u0000a', `\0a`);
+  for (var i = 0; i < 8; i++) {
+    var code = "`\\0" + i + "`";
+    assertThrows(code, SyntaxError);
+    code = "(function(){})" + code;
+    assertThrows(code, SyntaxError);
+  }
+
+  assertEquals('\\0', String.raw`\0`);
+})();
+
+
+(function testSyntaxErrorsNonEscapeCharacter() {
+  assertThrows("`\\x`", SyntaxError);
+  assertThrows("`\\u`", SyntaxError);
+  for (var i = 1; i < 8; i++) {
+    var code = "`\\" + i + "`";
+    assertThrows(code, SyntaxError);
+    code = "(function(){})" + code;
+    assertThrows(code, SyntaxError);
+  }
+})();
+
+
+(function testValidNumericEscapes() {
+  assertEquals("8", `\8`);
+  assertEquals("9", `\9`);
+  assertEquals("\u00008", `\08`);
+  assertEquals("\u00009", `\09`);
+})();
diff --git a/test/mjsunit/harmony/typedarrays-foreach.js b/test/mjsunit/harmony/typedarrays-foreach.js
new file mode 100644
index 0000000..4bfa655
--- /dev/null
+++ b/test/mjsunit/harmony/typedarrays-foreach.js
@@ -0,0 +1,140 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-arrays --allow-natives-syntax
+
+var typedArrayConstructors = [
+  Uint8Array,
+  Int8Array,
+  Uint16Array,
+  Int16Array,
+  Uint32Array,
+  Int32Array,
+  Uint8ClampedArray,
+  Float32Array,
+  Float64Array];
+
+function CheckTypedArrayIsNeutered(array) {
+  assertEquals(0, array.byteLength);
+  assertEquals(0, array.byteOffset);
+  assertEquals(0, array.length);
+}
+
+function TestTypedArrayForEach(constructor) {
+  assertEquals(1, constructor.prototype.forEach.length);
+
+  var a = new constructor(2);
+  a[0] = 0;
+  a[1] = 1;
+
+  var count = 0;
+  a.forEach(function (n) { count++; });
+  assertEquals(2, count);
+
+  // Use specified object as this object when calling the function.
+  var o = { value: 42 };
+  var result = [];
+  a.forEach(function (n, index, array) { result.push(this.value); }, o);
+  assertArrayEquals([42, 42], result);
+
+  // Modify the original array.
+  count = 0;
+  a.forEach(function (n, index, array) { array[index] = n + 1; count++ });
+  assertEquals(2, count);
+  assertArrayEquals([1, 2], a);
+
+  // Check that values passed as second argument are wrapped into
+  // objects when calling into sloppy mode functions.
+  function CheckWrapping(value, wrapper) {
+    var wrappedValue = new wrapper(value);
+
+    a.forEach(function () {
+      assertEquals("object", typeof this);
+      assertEquals(wrappedValue, this);
+    }, value);
+
+    a.forEach(function () {
+      "use strict";
+      assertEquals(typeof value, typeof this);
+      assertEquals(value, this);
+    }, value);
+  }
+  CheckWrapping(true, Boolean);
+  CheckWrapping(false, Boolean);
+  CheckWrapping("xxx", String);
+  CheckWrapping(42, Number);
+  CheckWrapping(3.14, Number);
+  CheckWrapping({}, Object);
+
+  // Throw before completing iteration, only the first element
+  // should be modified when thorwing mid-way.
+  count = 0;
+  a[0] = 42;
+  a[1] = 42;
+  try {
+    a.forEach(function (n, index, array) {
+      if (count > 0) throw "meh";
+      array[index] = n + 1;
+      count++;
+    });
+  } catch (e) {
+  }
+  assertEquals(1, count);
+  assertEquals(43, a[0]);
+  assertEquals(42, a[1]);
+
+  // Neutering the buffer backing the typed array mid-way should
+  // still make .forEach() finish, and the array should keep being
+  // empty after neutering it.
+  count = 0;
+  a.forEach(function (n, index, array) {
+    if (count > 0) %ArrayBufferNeuter(array.buffer);
+    array[index] = n + 1;
+    count++;
+  });
+  assertEquals(2, count);
+  CheckTypedArrayIsNeutered(a);
+  assertEquals(undefined, a[0]);
+
+  // The method must work for typed arrays created from ArrayBuffer.
+  // The length of the ArrayBuffer is chosen so it is a multiple of
+  // all lengths of the typed array items.
+  a = new constructor(new ArrayBuffer(64));
+  count = 0;
+  a.forEach(function (n) { count++ });
+  assertEquals(a.length, count);
+
+  // Externalizing the array mid-way accessing the .buffer property
+  // should work.
+  a = new constructor(2);
+  count = 0;
+  var buffer = undefined;
+  a.forEach(function (n, index, array) {
+    if (count++ > 0)
+      buffer = array.buffer;
+  });
+  assertEquals(2, count);
+  assertTrue(!!buffer);
+  assertEquals("ArrayBuffer", %_ClassOf(buffer));
+  assertSame(buffer, a.buffer);
+
+  // The %TypedArray%.forEach() method should not work when
+  // transplanted to objects that are not typed arrays.
+  assertThrows(function () { constructor.prototype.forEach.call([1, 2, 3], function (x) {}) }, TypeError);
+  assertThrows(function () { constructor.prototype.forEach.call("abc", function (x) {}) }, TypeError);
+  assertThrows(function () { constructor.prototype.forEach.call({}, function (x) {}) }, TypeError);
+  assertThrows(function () { constructor.prototype.forEach.call(0, function (x) {}) }, TypeError);
+
+  // Method must be useable on instances of other typed arrays.
+  for (var i = 0; i < typedArrayConstructors.length; i++) {
+    count = 0;
+    a = new typedArrayConstructors[i](4);
+    constructor.prototype.forEach.call(a, function (x) { count++ });
+    assertEquals(a.length, count);
+  }
+}
+
+for (i = 0; i < typedArrayConstructors.length; i++) {
+  TestTypedArrayForEach(typedArrayConstructors[i]);
+}
diff --git a/test/mjsunit/harmony/typedarrays-of.js b/test/mjsunit/harmony/typedarrays-of.js
new file mode 100644
index 0000000..9df1d30
--- /dev/null
+++ b/test/mjsunit/harmony/typedarrays-of.js
@@ -0,0 +1,135 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Based on Mozilla Array.of() tests at http://dxr.mozilla.org/mozilla-central/source/js/src/jit-test/tests/collections
+
+// Flags: --harmony-arrays
+
+var typedArrayConstructors = [
+  Uint8Array,
+  Int8Array,
+  Uint16Array,
+  Int16Array,
+  Uint32Array,
+  Int32Array,
+  Uint8ClampedArray,
+  Float32Array,
+  Float64Array];
+
+
+function TestTypedArrayOf(constructor) {
+  // %TypedArray%.of basics.
+  var a = constructor.of();
+  assertEquals(0, a.length);
+  assertEquals(constructor.prototype, Object.getPrototypeOf(a));
+  assertEquals(false, Array.isArray(a));
+
+  // Items are coerced to numerical values.
+  a = constructor.of(undefined, null, [], true, false, 3.14);
+
+  // For typed arrays of floating point values, values are not rounded.
+  if (constructor === Float32Array || constructor === Float64Array) {
+    assertEquals(NaN, a[0]);
+    assertEquals(0, a[1]);
+    assertEquals(0, a[2]);
+    assertEquals(1, a[3]);
+    assertEquals(0, a[4]);
+    assertEquals(true, Math.abs(a[5] - 3.14) < 1e-6);
+  } else {
+    assertEquals(0, a[0]);
+    assertEquals(0, a[1]);
+    assertEquals(0, a[2]);
+    assertEquals(1, a[3]);
+    assertEquals(0, a[4]);
+    assertEquals(3, a[5]);
+  }
+
+  var aux = [];
+  for (var i = 0; i < 100; i++)
+    aux[i] = i;
+
+  a = constructor.of.apply(constructor, aux);
+  assertEquals(aux.length, a.length);
+  assertArrayEquals(aux, a);
+
+  // %TypedArray%.of can be transplanted to other constructors.
+  var hits = 0;
+  function Bag(length) {
+    assertEquals(arguments.length, 1);
+    assertEquals(length, 2);
+    this.length = length;
+    hits++;
+  }
+  Bag.of = constructor.of;
+
+  hits = 0;
+  a = Bag.of("zero", "one");
+  assertEquals(1, hits);
+  assertEquals(2, a.length);
+  assertArrayEquals(["zero", "one"], a);
+  assertEquals(Bag.prototype, a.__proto__);
+
+  hits = 0;
+  actual = constructor.of.call(Bag, "zero", "one");
+  assertEquals(1, hits);
+  assertEquals(2, a.length);
+  assertArrayEquals(["zero", "one"], a);
+  assertEquals(Bag.prototype, a.__proto__);
+
+  // %TypedArray%.of does not trigger prototype setters.
+  // (It defines elements rather than assigning to them.)
+  var status = "pass";
+  Object.defineProperty(constructor.prototype, "0", {
+    set: function(v) { status = "fail"; }
+  });
+  assertEquals(1, constructor.of(1)[0], 1);
+  assertEquals("pass", status);
+
+  // Note that %TypedArray%.of does not trigger "length" setter itself, as
+  // it relies on the constructor to set "length" to the value passed to it.
+  // If the constructor does not assign "length", the setter should not be
+  // invoked.
+
+  // Setter on the newly created object.
+  function Pack() {
+    Object.defineProperty(this, "length", {
+      set: function (v) { status = "fail"; }
+    });
+  }
+  Pack.of = constructor.of;
+  var pack = Pack.of("wolves", "cards", "cigarettes", "lies");
+  assertEquals("pass", status);
+
+  // when the setter is on the new object's prototype
+  function Bevy() {}
+  Object.defineProperty(Bevy.prototype, "length", {
+    set: function (v) { status = "fail"; }
+  });
+  Bevy.of = constructor.of;
+  var bevy = Bevy.of("quail");
+  assertEquals("pass", status);
+
+  // Check superficial features of %TypedArray%.of.
+  var desc = Object.getOwnPropertyDescriptor(constructor, "of");
+
+  assertEquals(desc.configurable, false);
+  assertEquals(desc.enumerable, false);
+  assertEquals(desc.writable, false);
+  assertEquals(constructor.of.length, 0);
+
+  // %TypedArray%.of is not a constructor.
+  assertThrows(function() { new constructor.of(); }, TypeError);
+
+  // For receivers which are not constructors %TypedArray%.of does not
+  // allocate a typed array using a default constructor, but throws an
+  // exception. Note that this is different from Array.of, which uses
+  // Array as default constructor.
+  for (var x of [undefined, null, false, true, "cow", 42, 3.14]) {
+    assertThrows(function () { constructor.of.call(x); }, TypeError);
+  }
+}
+
+for (var constructor of typedArrayConstructors) {
+  TestTypedArrayOf(constructor);
+}
diff --git a/test/mjsunit/harmony/typedarrays.js b/test/mjsunit/harmony/typedarrays.js
index f26b0be..a4d6e79 100644
--- a/test/mjsunit/harmony/typedarrays.js
+++ b/test/mjsunit/harmony/typedarrays.js
@@ -25,6 +25,8 @@
 // (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-tostring
+
 // ArrayBuffer
 
 function TestByteLength(param, expectedByteLength) {
@@ -52,6 +54,8 @@
 
   var ab = new ArrayBuffer();
   assertSame(0, ab.byteLength);
+  assertEquals("[object ArrayBuffer]",
+      Object.prototype.toString.call(ab));
 }
 
 TestArrayBufferCreation();
@@ -123,6 +127,9 @@
   var ab = new ArrayBuffer(256*elementSize);
 
   var a0 = new constr(30);
+  assertEquals("[object " + constr.name + "]",
+      Object.prototype.toString.call(a0));
+
   assertTrue(ArrayBuffer.isView(a0));
   assertSame(elementSize, a0.BYTES_PER_ELEMENT);
   assertSame(30, a0.length);
@@ -258,6 +265,17 @@
   assertSame(0, aNoParam.length);
   assertSame(0, aNoParam.byteLength);
   assertSame(0, aNoParam.byteOffset);
+
+  var a = new constr(ab, 64*elementSize, 128);
+  assertEquals("[object " + constr.name + "]",
+      Object.prototype.toString.call(a));
+  var desc = Object.getOwnPropertyDescriptor(
+      constr.prototype, Symbol.toStringTag);
+  assertTrue(desc.configurable);
+  assertFalse(desc.enumerable);
+  assertFalse(!!desc.writable);
+  assertFalse(!!desc.set);
+  assertEquals("function", typeof desc.get);
 }
 
 TestTypedArray(Uint8Array, 1, 0xFF);
@@ -361,14 +379,18 @@
   Float64Array];
 
 function TestPropertyTypeChecks(constructor) {
-  var a = new constructor();
   function CheckProperty(name) {
     var d = Object.getOwnPropertyDescriptor(constructor.prototype, name);
-    var o = {}
+    var o = {};
     assertThrows(function() {d.get.call(o);}, TypeError);
-    d.get.call(a); // shouldn't throw
-    for (var i = 0 ; i < typedArrayConstructors.length; i++) {
-      d.get.call(new typedArrayConstructors[i](10));
+    for (var i = 0; i < typedArrayConstructors.length; i++) {
+      var ctor = typedArrayConstructors[i];
+      var a = new ctor(10);
+      if (ctor === constructor) {
+        d.get.call(a); // shouldn't throw
+      } else {
+        assertThrows(function() {d.get.call(a);}, TypeError);
+      }
     }
   }
 
@@ -378,7 +400,7 @@
   CheckProperty("length");
 }
 
-for(i = 0; i < typedArrayConstructors.lenght; i++) {
+for(i = 0; i < typedArrayConstructors.length; i++) {
   TestPropertyTypeChecks(typedArrayConstructors[i]);
 }
 
@@ -477,6 +499,103 @@
 
 TestTypedArraySet();
 
+function TestTypedArraysWithIllegalIndices() {
+  var a = new Int32Array(100);
+
+  a[-10] = 10;
+  assertEquals(undefined, a[-10]);
+  a["-10"] = 10;
+  assertEquals(undefined, a["-10"]);
+
+  var s = "    -10";
+  a[s] = 10;
+  assertEquals(10, a[s]);
+  var s1 = "    -10   ";
+  a[s] = 10;
+  assertEquals(10, a[s]);
+
+  a["-1e2"] = 10;
+  assertEquals(10, a["-1e2"]);
+  assertEquals(undefined, a[-1e2]);
+
+  a["-0"] = 256;
+  var s2 = "     -0";
+  a[s2] = 255;
+  assertEquals(undefined, a["-0"]);
+  assertEquals(255, a[s2]);
+  assertEquals(0, a[-0]);
+
+  /* Chromium bug: 424619
+   * a[-Infinity] = 50;
+   * assertEquals(undefined, a[-Infinity]);
+   */
+  a[1.5] = 10;
+  assertEquals(undefined, a[1.5]);
+  var nan = Math.sqrt(-1);
+  a[nan] = 5;
+  assertEquals(5, a[nan]);
+
+  var x = 0;
+  var y = -0;
+  assertEquals(Infinity, 1/x);
+  assertEquals(-Infinity, 1/y);
+  a[x] = 5;
+  a[y] = 27;
+  assertEquals(27, a[x]);
+  assertEquals(27, a[y]);
+}
+
+TestTypedArraysWithIllegalIndices();
+
+function TestTypedArraysWithIllegalIndicesStrict() {
+  'use strict';
+  var a = new Int32Array(100);
+
+  a[-10] = 10;
+  assertEquals(undefined, a[-10]);
+  a["-10"] = 10;
+  assertEquals(undefined, a["-10"]);
+
+  var s = "    -10";
+  a[s] = 10;
+  assertEquals(10, a[s]);
+  var s1 = "    -10   ";
+  a[s] = 10;
+  assertEquals(10, a[s]);
+
+  a["-1e2"] = 10;
+  assertEquals(10, a["-1e2"]);
+  assertEquals(undefined, a[-1e2]);
+
+  a["-0"] = 256;
+  var s2 = "     -0";
+  a[s2] = 255;
+  assertEquals(undefined, a["-0"]);
+  assertEquals(255, a[s2]);
+  assertEquals(0, a[-0]);
+
+  /* Chromium bug: 424619
+   * a[-Infinity] = 50;
+   * assertEquals(undefined, a[-Infinity]);
+   */
+  a[1.5] = 10;
+  assertEquals(undefined, a[1.5]);
+  var nan = Math.sqrt(-1);
+  a[nan] = 5;
+  assertEquals(5, a[nan]);
+
+  var x = 0;
+  var y = -0;
+  assertEquals(Infinity, 1/x);
+  assertEquals(-Infinity, 1/y);
+  a[x] = 5;
+  a[y] = 27;
+  assertEquals(27, a[x]);
+  assertEquals(27, a[y]);
+}
+
+TestTypedArraysWithIllegalIndicesStrict();
+
 // DataView
 function TestDataViewConstructor() {
   var ab = new ArrayBuffer(256);
@@ -546,6 +665,19 @@
 
 TestDataViewPropertyTypeChecks();
 
+
+function TestDataViewToStringTag() {
+  var a = new DataView(new ArrayBuffer(10));
+  assertEquals("[object DataView]", Object.prototype.toString.call(a));
+  var desc = Object.getOwnPropertyDescriptor(
+      DataView.prototype, Symbol.toStringTag);
+  assertTrue(desc.configurable);
+  assertFalse(desc.enumerable);
+  assertFalse(desc.writable);
+  assertEquals("DataView", desc.value);
+}
+
+
 // General tests for properties
 
 // Test property attribute [[Enumerable]]
@@ -561,7 +693,7 @@
     assertArrayEquals([], props(obj));
 }
 TestEnumerable(ArrayBuffer, new ArrayBuffer());
-for(i = 0; i < typedArrayConstructors.lenght; i++) {
+for(i = 0; i < typedArrayConstructors.length; i++) {
   TestEnumerable(typedArrayConstructors[i]);
 }
 TestEnumerable(DataView, new DataView(new ArrayBuffer()));
@@ -573,13 +705,13 @@
     assertEquals(value, map[property]);
   }
   for (var i = 0; i < 20; i++) {
-    TestProperty(m, i, 'val' + i);
+    TestProperty(m, 'key' + i, 'val' + i);
     TestProperty(m, 'foo' + i, 'bar' + i);
   }
 }
 TestArbitrary(new ArrayBuffer(256));
-for(i = 0; i < typedArrayConstructors.lenght; i++) {
-  TestArbitary(new typedArrayConstructors[i](10));
+for(i = 0; i < typedArrayConstructors.length; i++) {
+  TestArbitrary(new typedArrayConstructors[i](10));
 }
 TestArbitrary(new DataView(new ArrayBuffer(256)));
 
diff --git a/test/mjsunit/harmony/unicode-escapes.js b/test/mjsunit/harmony/unicode-escapes.js
new file mode 100644
index 0000000..b39ee1a
--- /dev/null
+++ b/test/mjsunit/harmony/unicode-escapes.js
@@ -0,0 +1,46 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// ES6 extends the \uxxxx escape and also allows \u{xxxxx}.
+
+// Flags: --harmony-unicode
+
+// Unicode escapes in variable names.
+
+(function TestVariableNames1() {
+  var foobar = 1;
+  assertEquals(foob\u0061r, 1);
+  assertEquals(foob\u{0061}r, 1);
+  assertEquals(foob\u{61}r, 1);
+  assertEquals(foob\u{0000000061}r, 1);
+})();
+
+(function TestVariableNames2() {
+  var foobar = 1;
+  assertEquals(\u0066oobar, 1);
+  assertEquals(\u{0066}oobar, 1);
+  assertEquals(\u{66}oobar, 1);
+  assertEquals(\u{0000000066}oobar, 1);
+})();
+
+// Unicode escapes in strings.
+
+(function TestStrings() {
+  var s1 = "foob\u0061r";
+  assertEquals(s1, "foobar");
+  var s2 = "foob\u{0061}r";
+  assertEquals(s2, "foobar");
+  var s3 = "foob\u{61}r";
+  assertEquals(s3, "foobar");
+  var s4 = "foob\u{0000000061}r";
+  assertEquals(s4, "foobar");
+})();
+
+
+(function TestSurrogates() {
+  // U+10E6D corresponds to the surrogate pair [U+D803, U+DE6D].
+  var s1 = "foo\u{10e6d}";
+  var s2 = "foo\u{d803}\u{de6d}";
+  assertEquals(s1, s2);
+})();
diff --git a/test/mjsunit/keyed-load-with-string-key.js b/test/mjsunit/keyed-load-with-string-key.js
new file mode 100644
index 0000000..4388946
--- /dev/null
+++ b/test/mjsunit/keyed-load-with-string-key.js
@@ -0,0 +1,46 @@
+// Copyright 2014 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 o = {
+  "foo": "bar",
+}
+
+function get(obj, key) {
+  return obj[key];
+}
+
+get(o, "foo");
+get(o, "foo");
+get(o, "foo");
+
+%OptimizeFunctionOnNextCall(get);
+get(o, "foo");
+
+assertOptimized(get);
diff --git a/test/mjsunit/mirror-object.js b/test/mjsunit/mirror-object.js
index 7020338..91d0f82 100644
--- a/test/mjsunit/mirror-object.js
+++ b/test/mjsunit/mirror-object.js
@@ -125,12 +125,7 @@
         // Check that serialized name is correct.
         assertEquals(properties[i].name(), fromJSON.properties[i].name, 'Unexpected serialized name');
 
-        // If property type is normal property type is not serialized.
-        if (properties[i].propertyType() != debug.PropertyType.Normal) {
-          assertEquals(properties[i].propertyType(), fromJSON.properties[i].propertyType, 'Unexpected serialized property type');
-        } else {
-          assertTrue(typeof(fromJSON.properties[i].propertyType) === 'undefined', 'Unexpected serialized property type');
-        }
+        assertEquals(properties[i].propertyType(), fromJSON.properties[i].propertyType, 'Unexpected serialized property type');
 
         // If there are no attributes attributes are not serialized.
         if (properties[i].attributes() != debug.PropertyAttribute.None) {
diff --git a/test/mjsunit/mjsunit.js b/test/mjsunit/mjsunit.js
index 0430279..b360425 100644
--- a/test/mjsunit/mjsunit.js
+++ b/test/mjsunit/mjsunit.js
@@ -231,16 +231,7 @@
     return deepObjectEquals(a, b);
   }
 
-  function checkArity(args, arity, name) {
-    if (args.length < arity) {
-      fail(PrettyPrint(arity), args.length,
-           name + " requires " + arity + " or more arguments");
-    }
-  }
-
   assertSame = function assertSame(expected, found, name_opt) {
-    checkArity(arguments, 2, "assertSame");
-
     // TODO(mstarzinger): We should think about using Harmony's egal operator
     // or the function equivalent Object.is() here.
     if (found === expected) {
@@ -253,8 +244,6 @@
 
 
   assertEquals = function assertEquals(expected, found, name_opt) {
-    checkArity(arguments, 2, "assertEquals");
-
     if (!deepEquals(found, expected)) {
       fail(PrettyPrint(expected), found, name_opt);
     }
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index bba86bd..26ec10b 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -51,9 +51,8 @@
   # Issue 3389: deopt_every_n_garbage_collections is unsafe
   'regress/regress-2653': [SKIP],
 
-  # This test relies on --noopt-safe-uint32-operations, which is broken. See
-  # issue 3487 for details.
-  'compiler/shift-shr': [SKIP],
+  # Issue 3784: setters-on-elements is flaky
+  'setters-on-elements': [PASS, FAIL],
 
   ##############################################################################
   # TurboFan compiler failures.
@@ -63,16 +62,10 @@
   # from the deoptimizer to do that.
   'arguments-indirect': [PASS, NO_VARIANTS],
 
-  # TODO(rossberg): Typer doesn't like contexts very much.
-  'harmony/block-conflicts': [PASS, NO_VARIANTS],
-  'harmony/block-for': [PASS, NO_VARIANTS],
-  'harmony/block-leave': [PASS, NO_VARIANTS],
-  'harmony/block-let-crankshaft': [PASS, NO_VARIANTS],
-  'harmony/empty-for': [PASS, NO_VARIANTS],
-
-  # Some tests are over-restrictive about object layout.
+  # TODO(verwaest): Some tests are over-restrictive about object layout.
   'array-constructor-feedback': [PASS, NO_VARIANTS],
   'array-feedback': [PASS, NO_VARIANTS],
+  'compare-known-objects-slow': [PASS, NO_VARIANTS],
   'elements-kind': [PASS, NO_VARIANTS],
 
   # Some tests are just too slow to run for now.
@@ -84,6 +77,10 @@
   'compiler/osr-assert': [PASS, NO_VARIANTS],
   'regress/regress-2185-2': [PASS, NO_VARIANTS],
 
+  # Issue 3660: Replacing activated TurboFan frames by unoptimized code does
+  # not work, but we expect it to not crash.
+  'debug-step-turbofan': [PASS, FAIL],
+
   # Support for %GetFrameDetails is missing and requires checkpoints.
   'debug-evaluate-bool-constructor': [PASS, NO_VARIANTS],
   'debug-evaluate-const': [PASS, NO_VARIANTS],
@@ -123,6 +120,9 @@
   'regress/regress-crbug-259300': [PASS, NO_VARIANTS],
   'regress/regress-frame-details-null-receiver': [PASS, NO_VARIANTS],
 
+  # TODO(arv): TurboFan does not yet add [[HomeObject]] as needed.
+  'harmony/object-literals-super': [PASS, NO_VARIANTS],
+
   ##############################################################################
   # Too slow in debug mode with --stress-opt mode.
   'compiler/regress-stacktrace-methods': [PASS, ['mode == debug', SKIP]],
@@ -177,7 +177,7 @@
   ##############################################################################
   # Tests verifying CHECK and ASSERT.
   'verify-check-false': [FAIL, NO_VARIANTS],
-  'verify-assert-false': [NO_VARIANTS, ['mode == release', PASS], ['mode == debug', FAIL]],
+  'verify-assert-false': [NO_VARIANTS, ['mode == release and dcheck_always_on == False', PASS], ['mode == debug or dcheck_always_on == True', FAIL]],
 
   ##############################################################################
   # Tests with different versions for release and debug.
@@ -195,8 +195,13 @@
 
   # Skip endain dependent test for mips due to different typed views of the same
   # array buffer.
-  'nans': [PASS, ['arch == mips', SKIP]],
+  'nans': [PASS, ],
 
+  # This test variant makes only sense on arm.
+  'math-floor-of-div-nosudiv': [PASS, SLOW, ['arch not in [arm, arm64, android_arm, android_arm64]', SKIP]],
+
+  # Too slow for slow variants.
+  'asm/embenchen/*': [PASS, SLOW, FAST_VARIANTS],
 }],  # ALWAYS
 
 ##############################################################################
@@ -211,10 +216,12 @@
   'elements-kind': [SKIP],
   'elements-transition-hoisting': [SKIP],
   'fast-prototype': [SKIP],
+  'field-type-tracking': [SKIP],
   'getters-on-elements': [SKIP],
   'harmony/block-let-crankshaft': [SKIP],
   'opt-elements-kind': [SKIP],
   'osr-elements-kind': [SKIP],
+  'regress/regress-crbug-137689': [SKIP],
   'regress/regress-165637': [SKIP],
   'regress/regress-2249': [SKIP],
   # Tests taking too long
@@ -233,6 +240,20 @@
   # TODO(mstarzinger): Takes too long with TF.
   'array-sort': [PASS, NO_VARIANTS],
   'regress/regress-91008': [PASS, NO_VARIANTS],
+  'regress/regress-417709a': [PASS, ['arch == arm64', NO_VARIANTS]],
+  'regress/regress-transcendental': [PASS, ['arch == arm64', NO_VARIANTS]],
+  'compiler/osr-regress-max-locals': [PASS, NO_VARIANTS],
+  'math-floor-of-div': [PASS, NO_VARIANTS],
+  'unicodelctest': [PASS, NO_VARIANTS],
+  'unicodelctest-no-optimization': [PASS, NO_VARIANTS],
+
+  # Too slow for gc stress.
+  'asm/embenchen/box2d': [SKIP],
+
+  # Issue 3723.
+  'regress/regress-3717': [SKIP],
+  # Issue 3776.
+  'debug-stepframe': [SKIP],
 }],  # 'gc_stress == True'
 
 ##############################################################################
@@ -249,6 +270,8 @@
   # Pass but take too long to run. Skip.
   # Some similar tests (with fewer iterations) may be included in arm64-js
   # tests.
+  'asm/embenchen/box2d': [SKIP],
+  'asm/embenchen/lua_binarytrees': [SKIP],
   'big-object-literal': [SKIP],
   'compiler/regress-arguments': [SKIP],
   'compiler/regress-gvn': [SKIP],
@@ -313,11 +336,16 @@
 ['arch == arm64 and mode == debug and simulator_run == True', {
 
   # Pass but take too long with the simulator in debug mode.
+  'array-iterate-backwards': [PASS, TIMEOUT],
   'array-sort': [PASS, TIMEOUT],
   'packed-elements': [SKIP],
   'regexp-global': [SKIP],
   'compiler/alloc-numbers': [SKIP],
   'harmony/symbols': [SKIP],
+  'math-floor-of-div': [PASS, TIMEOUT],
+  'math-floor-of-div-nosudiv': [PASS, TIMEOUT],
+  'unicodelctest': [PASS, TIMEOUT],
+  'unicodelctest-no-optimization': [PASS, TIMEOUT],
   # Issue 3219:
   'getters-on-elements': [PASS, ['gc_stress == True', FAIL]],
 }],  # 'arch == arm64 and mode == debug and simulator_run == True'
@@ -414,6 +442,15 @@
 }],  # 'arch == mipsel or arch == mips'
 
 ##############################################################################
+['arch == mips', {
+  # Flaky with TF.
+  'mirror-script': [PASS, NO_VARIANTS],
+
+  # Emscripten requires little-endian, skip all tests on MIPS EB.
+  'asm/embenchen/*': [SKIP],
+}],  # 'arch == mips'
+
+##############################################################################
 ['arch == mips64el', {
 
   # Slow tests which times out in debug mode.
@@ -472,6 +509,10 @@
 ['system == windows', {
   # TODO(mstarzinger): Too slow with turbo fan.
   'big-object-literal': [PASS, ['mode == debug', SKIP]],
+  'math-floor-of-div': [PASS, ['mode == debug', SKIP]],
+  'math-floor-of-div-nosudiv': [PASS, ['mode == debug', SKIP]],
+  'osr-regress-max-locals': [PASS, ['mode == debug', SKIP]],
+  'unicodelctest': [PASS, ['mode == debug', SKIP]],
 
   # BUG(v8:3435)
   'debug-script-breakpoints': [PASS, FAIL],
diff --git a/test/mjsunit/mod-range.js b/test/mjsunit/mod-range.js
new file mode 100644
index 0000000..0cded89
--- /dev/null
+++ b/test/mjsunit/mod-range.js
@@ -0,0 +1,79 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function g1(i) {
+  var x = i * 1;
+  return (x >>> 0) % 1000000000000;
+}
+
+function g2(i) {
+  var x = i * 1;
+  return ((x >>> 0) % 1000000000000) | 0;
+}
+
+function test1() {
+  assertEquals(2294967296, g1(-2000000000));
+  assertEquals(2294967295, g1(-2000000001));
+  assertEquals(2294967290, g1(-2000000006));
+
+  assertEquals(2147483651, g1(-2147483645));
+  assertEquals(2147483650, g1(-2147483646));
+  assertEquals(2147483649, g1(-2147483647));
+  assertEquals(2147483648, g1(-2147483648));
+  assertEquals(2147483647, g1(-2147483649));
+
+  assertEquals(3000000000, g1(3000000000));
+  assertEquals(3000000001, g1(3000000001));
+  assertEquals(3000000002, g1(3000000002));
+
+  assertEquals(4000000000, g1(4000000000));
+  assertEquals(4000400001, g1(4000400001));
+  assertEquals(4000400002, g1(4000400002));
+
+  assertEquals(3, g1(4294967299));
+  assertEquals(2, g1(4294967298));
+  assertEquals(1, g1(4294967297));
+  assertEquals(0, g1(4294967296));
+  assertEquals(4294967295, g1(4294967295));
+  assertEquals(4294967294, g1(4294967294));
+  assertEquals(4294967293, g1(4294967293));
+  assertEquals(4294967292, g1(4294967292));
+}
+
+%NeverOptimizeFunction(test1);
+test1();
+
+function test2() {
+  assertEquals(-2000000000, g2(-2000000000));
+  assertEquals(-2000000001, g2(-2000000001));
+  assertEquals(-2000000006, g2(-2000000006));
+
+  assertEquals(-2147483645, g2(-2147483645));
+  assertEquals(-2147483646, g2(-2147483646));
+  assertEquals(-2147483647, g2(-2147483647));
+  assertEquals(-2147483648, g2(-2147483648));
+  assertEquals(2147483647, g2(-2147483649));
+
+  assertEquals(-1294967296, g2(3000000000));
+  assertEquals(-1294967295, g2(3000000001));
+  assertEquals(-1294967294, g2(3000000002));
+
+  assertEquals(-294967296, g2(4000000000));
+  assertEquals(-294567295, g2(4000400001));
+  assertEquals(-294567294, g2(4000400002));
+
+  assertEquals(3, g2(4294967299));
+  assertEquals(2, g2(4294967298));
+  assertEquals(1, g2(4294967297));
+  assertEquals(0, g2(4294967296));
+  assertEquals(-1, g2(4294967295));
+  assertEquals(-2, g2(4294967294));
+  assertEquals(-3, g2(4294967293));
+  assertEquals(-4, g2(4294967292));
+}
+
+%NeverOptimizeFunction(test2);
+test2();
diff --git a/test/mjsunit/nans.js b/test/mjsunit/nans.js
index 987ad6e..5630e5b 100644
--- a/test/mjsunit/nans.js
+++ b/test/mjsunit/nans.js
@@ -27,6 +27,11 @@
 
 // Flags: --allow-natives-syntax
 
+// Helper to determine endian - returns true on little endian platforms
+function isLittleEndian() {
+  return ((new Uint32Array((new Uint8Array([4,3,2,1])).buffer))[0])
+           == 0x01020304;
+}
 
 // Test that both kinds of NaNs (signaling or quiet) do not signal
 
@@ -41,7 +46,11 @@
 function TestDoubleSignalingNan() {
   // NaN with signal bit set
   function f() {
-    var bytes = new Uint32Array([1, 0x7FF00000]);
+    if(isLittleEndian()) {
+      var bytes = new Uint32Array([1, 0x7FF00000]);
+    } else {
+      var bytes = new Uint32Array([0x7FF00000, 1]);
+    }
     var doubles = new Float64Array(bytes.buffer);
     assertTrue(isNaN(doubles[0]));
     assertTrue(isNaN(doubles[0]*2.0));
@@ -56,7 +65,11 @@
 function TestDoubleQuietNan() {
   // NaN with signal bit cleared
   function f() {
-    var bytes = new Uint32Array([0, 0x7FF80000]);
+    if(isLittleEndian()) {
+      var bytes = new Uint32Array([0, 0x7FF80000]);
+    } else {
+      var bytes = new Uint32Array([0x7FF80000, 0]);
+    }
     var doubles = new Float64Array(bytes.buffer);
     assertTrue(isNaN(doubles[0]));
     assertTrue(isNaN(doubles[0]*2.0));
diff --git a/test/mjsunit/object-freeze-global.js b/test/mjsunit/object-freeze-global.js
new file mode 100644
index 0000000..8ab5b85
--- /dev/null
+++ b/test/mjsunit/object-freeze-global.js
@@ -0,0 +1,6 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Object.freeze(this);
+assertTrue(Object.isFrozen(this));
diff --git a/test/mjsunit/object-freeze.js b/test/mjsunit/object-freeze.js
index 4144936..5d1f8b7 100644
--- a/test/mjsunit/object-freeze.js
+++ b/test/mjsunit/object-freeze.js
@@ -303,7 +303,7 @@
 
 // Also test a simpler case
 obj = {};
-Object.defineProperty(obj, 'accessor', {
+Object.defineProperty(obj, 'accessor2', {
   get: function() { return 42 },
   set: function() { accessorDidRun = true },
   configurable: true,
@@ -339,3 +339,12 @@
 assertEquals(1, obj[1]);
 Object.freeze(obj);
 assertThrows(function() { obj.unshift(); }, TypeError);
+
+// Sealing and then Freezing should do the right thing.
+var obj = { foo: 'bar', 0: 'element' };
+Object.seal(obj);
+assertTrue(Object.isSealed(obj));
+assertFalse(Object.isFrozen(obj));
+Object.freeze(obj);
+assertTrue(Object.isSealed(obj));
+assertTrue(Object.isFrozen(obj));
diff --git a/test/mjsunit/object-get-own-property-names.js b/test/mjsunit/object-get-own-property-names.js
index 64607c6..aee6585 100644
--- a/test/mjsunit/object-get-own-property-names.js
+++ b/test/mjsunit/object-get-own-property-names.js
@@ -87,30 +87,20 @@
 assertSame(Array.prototype, propertyNames.__proto__);
 Array.prototype.concat = savedConcat;
 
-try {
-  Object.getOwnPropertyNames(4);
-  assertTrue(false);
-} catch (e) {
-  assertTrue(/on non-object/.test(e));
-}
-
-try {
-  Object.getOwnPropertyNames("foo");
-  assertTrue(false);
-} catch (e) {
-  assertTrue(/on non-object/.test(e));
-}
+assertEquals(Object.getOwnPropertyNames(4), []);
+assertEquals(Object.getOwnPropertyNames("foo"), ["0", "1", "2", "length"]);
+assertEquals(Object.getOwnPropertyNames(true), []);
 
 try {
   Object.getOwnPropertyNames(undefined);
   assertTrue(false);
 } catch (e) {
-  assertTrue(/on non-object/.test(e));
+  assertTrue(/Cannot convert undefined or null to object/.test(e));
 }
 
 try {
   Object.getOwnPropertyNames(null);
   assertTrue(false);
 } catch (e) {
-  assertTrue(/on non-object/.test(e));
+  assertTrue(/Cannot convert undefined or null to object/.test(e));
 }
diff --git a/test/mjsunit/object-is.js b/test/mjsunit/object-is.js
index b9fdc84..c57542f 100644
--- a/test/mjsunit/object-is.js
+++ b/test/mjsunit/object-is.js
@@ -32,8 +32,8 @@
   assertSame(expected, Object.is(x, y));
 }
 
-var test_set = [ {}, [], 1/0, -1/0, "s", 0, 0/-1, null, undefined ];
-print(test_set);
+var test_set = [ {}, [], Infinity, -Infinity, "s", "ア", 0, 0/-1, null,
+    undefined, true, false, Symbol("foo"), NaN ];
 for (var i = 0; i < test_set.length; i++) {
   for (var j = 0; j < test_set.length; j++) {
     if (i == j) {
diff --git a/test/mjsunit/object-prevent-extensions.js b/test/mjsunit/object-prevent-extensions.js
index 6b9184d..bde3161 100644
--- a/test/mjsunit/object-prevent-extensions.js
+++ b/test/mjsunit/object-prevent-extensions.js
@@ -27,6 +27,8 @@
 
 // Tests the Object.preventExtensions method - ES 15.2.3.10
 
+// Flags: --allow-natives-syntax
+
 
 var obj1 = {};
 // Extensible defaults to true.
@@ -126,3 +128,35 @@
 var n = o[0] = 100;
 assertEquals(undefined, o[0]);
 assertEquals(100, n);
+
+// Fast properties should remain fast
+obj = { x: 42, y: 'foo' };
+assertTrue(%HasFastProperties(obj));
+Object.preventExtensions(obj);
+assertFalse(Object.isExtensible(obj));
+assertFalse(Object.isSealed(obj));
+assertTrue(%HasFastProperties(obj));
+
+// Non-extensible objects should share maps where possible
+obj = { prop1: 1, prop2: 2 };
+obj2 = { prop1: 3, prop2: 4 };
+assertTrue(%HaveSameMap(obj, obj2));
+Object.preventExtensions(obj);
+Object.preventExtensions(obj2);
+assertFalse(Object.isExtensible(obj));
+assertFalse(Object.isExtensible(obj2));
+assertFalse(Object.isSealed(obj));
+assertFalse(Object.isSealed(obj2));
+assertTrue(%HaveSameMap(obj, obj2));
+
+// Non-extensible objects should share maps even when they have elements
+obj = { prop1: 1, prop2: 2, 75: 'foo' };
+obj2 = { prop1: 3, prop2: 4, 150: 'bar' };
+assertTrue(%HaveSameMap(obj, obj2));
+Object.preventExtensions(obj);
+Object.preventExtensions(obj2);
+assertFalse(Object.isExtensible(obj));
+assertFalse(Object.isExtensible(obj2));
+assertFalse(Object.isSealed(obj));
+assertFalse(Object.isSealed(obj2));
+assertTrue(%HaveSameMap(obj, obj2));
diff --git a/test/mjsunit/object-seal-global.js b/test/mjsunit/object-seal-global.js
new file mode 100644
index 0000000..ec9f82e
--- /dev/null
+++ b/test/mjsunit/object-seal-global.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Object.seal(this);
+assertTrue(Object.isSealed(this));
+assertFalse(Object.isFrozen(this));
diff --git a/test/mjsunit/object-seal.js b/test/mjsunit/object-seal.js
index 3afddb9..3c46ab2 100644
--- a/test/mjsunit/object-seal.js
+++ b/test/mjsunit/object-seal.js
@@ -267,3 +267,132 @@
 assertDoesNotThrow(function() { obj.splice(1,2000,1,2); });
 assertThrows(function() { obj.splice(0,0,1); }, TypeError);
 assertThrows(function() { obj.splice(1,2000,1,2,3); }, TypeError);
+
+// Test that the enumerable attribute is unperturbed by sealing.
+obj = { x: 42, y: 'foo' };
+Object.defineProperty(obj, 'y', {enumerable: false});
+Object.seal(obj);
+assertTrue(Object.isSealed(obj));
+assertFalse(Object.isFrozen(obj));
+desc = Object.getOwnPropertyDescriptor(obj, 'x');
+assertTrue(desc.enumerable);
+desc = Object.getOwnPropertyDescriptor(obj, 'y');
+assertFalse(desc.enumerable);
+
+// Fast properties should remain fast
+obj = { x: 42, y: 'foo' };
+assertTrue(%HasFastProperties(obj));
+Object.seal(obj);
+assertTrue(Object.isSealed(obj));
+assertFalse(Object.isFrozen(obj));
+assertTrue(%HasFastProperties(obj));
+
+// Sealed objects should share maps where possible
+obj = { prop1: 1, prop2: 2 };
+obj2 = { prop1: 3, prop2: 4 };
+assertTrue(%HaveSameMap(obj, obj2));
+Object.seal(obj);
+Object.seal(obj2);
+assertTrue(Object.isSealed(obj));
+assertTrue(Object.isSealed(obj2));
+assertFalse(Object.isFrozen(obj));
+assertFalse(Object.isFrozen(obj2));
+assertTrue(%HaveSameMap(obj, obj2));
+
+// Sealed objects should share maps even when they have elements
+obj = { prop1: 1, prop2: 2, 75: 'foo' };
+obj2 = { prop1: 3, prop2: 4, 150: 'bar' };
+assertTrue(%HaveSameMap(obj, obj2));
+Object.seal(obj);
+Object.seal(obj2);
+assertTrue(Object.isSealed(obj));
+assertTrue(Object.isSealed(obj2));
+assertFalse(Object.isFrozen(obj));
+assertFalse(Object.isFrozen(obj));
+assertTrue(%HaveSameMap(obj, obj2));
+
+// Setting elements after sealing should not be allowed
+obj = { prop: 'thing' };
+Object.seal(obj);
+assertTrue(Object.isSealed(obj));
+assertFalse(Object.isFrozen(obj));
+obj[0] = 'hello';
+assertFalse(obj.hasOwnProperty(0));
+
+// Sealing an object in dictionary mode should work
+// Also testing that getter/setter properties work after sealing
+obj = { };
+for (var i = 0; i < 100; ++i) {
+  obj['x' + i] = i;
+}
+var accessorDidRun = false;
+Object.defineProperty(obj, 'accessor', {
+  get: function() { return 42 },
+  set: function() { accessorDidRun = true },
+  configurable: true,
+  enumerable: true
+});
+
+assertFalse(%HasFastProperties(obj));
+Object.seal(obj);
+assertFalse(%HasFastProperties(obj));
+assertTrue(Object.isSealed(obj));
+assertFalse(Object.isFrozen(obj));
+assertFalse(Object.isExtensible(obj));
+for (var i = 0; i < 100; ++i) {
+  desc = Object.getOwnPropertyDescriptor(obj, 'x' + i);
+  assertFalse(desc.configurable);
+}
+assertEquals(42, obj.accessor);
+assertFalse(accessorDidRun);
+obj.accessor = 'ignored value';
+assertTrue(accessorDidRun);
+
+// Sealing arguments should work
+var func = function(arg) {
+  Object.seal(arguments);
+  assertTrue(Object.isSealed(arguments));
+};
+func('hello', 'world');
+func('goodbye', 'world');
+
+// Sealing sparse arrays
+var sparseArr = [0, 1];
+sparseArr[10000] = 10000;
+Object.seal(sparseArr);
+assertTrue(Object.isSealed(sparseArr));
+
+// Accessors on fast object should behavior properly after sealing
+obj = {};
+Object.defineProperty(obj, 'accessor', {
+  get: function() { return 42 },
+  set: function() { accessorDidRun = true },
+  configurable: true,
+  enumerable: true
+});
+assertTrue(%HasFastProperties(obj));
+Object.seal(obj);
+assertTrue(Object.isSealed(obj));
+assertTrue(%HasFastProperties(obj));
+assertEquals(42, obj.accessor);
+accessorDidRun = false;
+obj.accessor = 'ignored value';
+assertTrue(accessorDidRun);
+
+// Test for regression in mixed accessor/data property objects.
+// The strict function is one such object.
+assertTrue(Object.isSealed(Object.seal(function(){"use strict";})));
+
+// Also test a simpler case
+obj = {};
+Object.defineProperty(obj, 'accessor2', {
+  get: function() { return 42 },
+  set: function() { accessorDidRun = true },
+  configurable: true,
+  enumerable: true
+});
+obj.data = 'foo';
+assertTrue(%HasFastProperties(obj));
+Object.seal(obj);
+assertTrue(%HasFastProperties(obj));
+assertTrue(Object.isSealed(obj));
diff --git a/test/mjsunit/opt-elements-kind.js b/test/mjsunit/opt-elements-kind.js
index be7303b..5f4f437 100644
--- a/test/mjsunit/opt-elements-kind.js
+++ b/test/mjsunit/opt-elements-kind.js
@@ -142,10 +142,16 @@
   assertTrue(%HaveSameMap(smis, doubles));
 }
 
+function clear_ic_state() {
+  %ClearFunctionTypeFeedback(construct_smis);
+  %ClearFunctionTypeFeedback(construct_doubles);
+  %ClearFunctionTypeFeedback(convert_mixed);
+}
+
 test1();
-gc(); // clear IC state
+clear_ic_state();
 test1();
-gc(); // clear IC state
+clear_ic_state();
 %OptimizeFunctionOnNextCall(test1);
 test1();
-gc(); // clear IC state
+clear_ic_state();
diff --git a/test/mjsunit/parse-surrogates.js b/test/mjsunit/parse-surrogates.js
new file mode 100644
index 0000000..5ed9b52
--- /dev/null
+++ b/test/mjsunit/parse-surrogates.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Test that the parser throws on unmatched surrogates.
+assertThrows("var \uD801\uABCD;", SyntaxError);
+assertThrows("'\\u000\uD801\uABCD'", SyntaxError);
diff --git a/test/mjsunit/polymorph-arrays.js b/test/mjsunit/polymorph-arrays.js
index 2bb0433..6a05c9f 100644
--- a/test/mjsunit/polymorph-arrays.js
+++ b/test/mjsunit/polymorph-arrays.js
@@ -36,7 +36,7 @@
   for (var i = 0; i < 10; ++i ){
     a[i] = i;
   }
-  a[5000000] = 256;
+  a[200000] = 256;
   return %NormalizeElements(a);
 }
 
@@ -115,7 +115,7 @@
     var sparse_object_array = new Object;
     var js_array = new Array(10);
     var sparse_js_array = [];
-    sparse_js_array.length = 5000001;
+    sparse_js_array.length = 200001;
 
     init_array(object_array);
     init_array(js_array);
@@ -134,7 +134,8 @@
   var sparse_object_array = new Object;
   var js_array = new Array(10);
   var sparse_js_array = %NormalizeElements([]);
-  sparse_js_array.length = 5000001;
+  sparse_js_array.length = 200001;
+  assertTrue(%HasDictionaryElements(sparse_js_array));
 
   init_array(object_array);
   init_array(js_array);
diff --git a/test/mjsunit/regress-ntl.js b/test/mjsunit/regress-ntl.js
new file mode 100644
index 0000000..993599e
--- /dev/null
+++ b/test/mjsunit/regress-ntl.js
@@ -0,0 +1,41 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function mod1() {
+  var v_1 = 1;
+  var v_2 = 1;
+  v_1++;
+  v_2 = {valueOf: function() { throw "gagh"; }};
+
+  function bug1() {
+    for (var i = 0; i < 1; v_2++) {
+      if (v_1 == 1) ;
+    }
+  }
+
+  return bug1;
+}
+
+var f = mod1();
+assertThrows(f);
+%OptimizeFunctionOnNextCall(f);
+assertThrows(f);
+
+
+var v_3 = 1;
+var v_4 = 1;
+v_3++;
+v_4 = {valueOf: function() { throw "gagh"; }};
+
+function bug2() {
+  for (var i = 0; i < 1; v_4++) {
+    if (v_3 == 1) ;
+  }
+}
+
+assertThrows(bug2);
+%OptimizeFunctionOnNextCall(bug2);
+assertThrows(bug2);
diff --git a/test/mjsunit/regress/regress-136048.js b/test/mjsunit/regress/regress-136048.js
index c9972e9..21ae622 100644
--- a/test/mjsunit/regress/regress-136048.js
+++ b/test/mjsunit/regress/regress-136048.js
@@ -26,9 +26,9 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 try {
-  /foo/\u0069
+  eval("/foo/\\u0069")
 } catch (e) {
   assertEquals(
-      "SyntaxError: Invalid flags supplied to RegExp constructor '\\u0069'",
+      "SyntaxError: Invalid regular expression flags",
       e.toString());
 }
diff --git a/test/mjsunit/regress/regress-1757.js b/test/mjsunit/regress/regress-1757.js
index 35e7355..a850f70 100644
--- a/test/mjsunit/regress/regress-1757.js
+++ b/test/mjsunit/regress/regress-1757.js
@@ -27,6 +27,7 @@
 
 // Flags: --string-slices --expose-externalize-string
 
-var a = "abcdefghijklmnopqrstuvqxy"+"z";
+var a = "internalized dummy";
+a = "abcdefghijklmnopqrstuvqxy"+"z";
 externalizeString(a, true);
 assertEquals('b', a.substring(1).charAt(0));
diff --git a/test/mjsunit/regress/regress-2506.js b/test/mjsunit/regress/regress-2506.js
new file mode 100644
index 0000000..0eb2770
--- /dev/null
+++ b/test/mjsunit/regress/regress-2506.js
@@ -0,0 +1,78 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --harmony-scoping
+
+'use strict';
+
+// Top-level code
+let s = 0;
+let f = [undefined, undefined, undefined]
+for (const x of [1,2,3]) {
+  s += x;
+  f[x-1] = function() { return x; }
+}
+assertEquals(6, s);
+assertEquals(1, f[0]());
+assertEquals(2, f[1]());
+assertEquals(3, f[2]());
+
+let x = 1;
+s = 0;
+for (const x of [x, x+1, x+2]) {
+  s += x;
+}
+assertEquals(6, s);
+
+s = 0;
+var q = 1;
+for (const q of [q, q+1, q+2]) {
+  s += q;
+}
+assertEquals(6, s);
+
+let z = 1;
+s = 0;
+for (const x = 1; z < 2; z++) {
+  s += x + z;
+}
+assertEquals(2, s);
+
+
+s = "";
+for (const x in [1,2,3]) {
+  s += x;
+}
+assertEquals("012", s);
+
+assertThrows("'use strict'; for (const x in [1,2,3]) { x++ }", TypeError);
+
+// Function scope
+(function() {
+  let s = 0;
+  for (const x of [1,2,3]) {
+    s += x;
+  }
+  assertEquals(6, s);
+
+  let x = 1;
+  s = 0;
+  for (const x of [x, x+1, x+2]) {
+    s += x;
+  }
+  assertEquals(6, s);
+
+  s = 0;
+  var q = 1;
+  for (const q of [q, q+1, q+2]) {
+    s += q;
+  }
+  assertEquals(6, s);
+
+  s = "";
+  for (const x in [1,2,3]) {
+    s += x;
+  }
+  assertEquals("012", s);
+}());
diff --git a/test/mjsunit/regress/regress-2615.js b/test/mjsunit/regress/regress-2615.js
new file mode 100644
index 0000000..6b277e8
--- /dev/null
+++ b/test/mjsunit/regress/regress-2615.js
@@ -0,0 +1,96 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * 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.
+
+a = [1];
+Object.defineProperty(a, "1", {writable:false, configurable:false, value: 100});
+assertThrows("a.unshift(4);", TypeError);
+assertEquals([1, 100, 100], a);
+var desc = Object.getOwnPropertyDescriptor(a, "1");
+assertEquals(false, desc.writable);
+assertEquals(false, desc.configurable);
+
+a = [1];
+var g = function() { return 100; };
+Object.defineProperty(a, "1", {get:g});
+assertThrows("a.unshift(0);", TypeError);
+assertEquals([1, 100, 100], a);
+desc = Object.getOwnPropertyDescriptor(a, "1");
+assertEquals(false, desc.configurable);
+assertEquals(g, desc.get);
+
+a = [1];
+var c = 0;
+var s = function(v) { c += 1; };
+Object.defineProperty(a, "1", {set:s});
+a.unshift(10);
+assertEquals([10, undefined, undefined], a);
+assertEquals(1, c);
+desc = Object.getOwnPropertyDescriptor(a, "1");
+assertEquals(false, desc.configurable);
+assertEquals(s, desc.set);
+
+a = [1];
+Object.defineProperty(a, "1", {configurable:false, value:10});
+assertThrows("a.splice(1,1);", TypeError);
+assertEquals([1, 10], a);
+desc = Object.getOwnPropertyDescriptor(a, "1");
+assertEquals(false, desc.configurable);
+
+a = [0,1,2,3,4,5,6];
+Object.defineProperty(a, "3", {configurable:false, writable:false, value:3});
+assertThrows("a.splice(1,4);", TypeError);
+assertEquals([0,5,6,3,,,,], a);
+desc = Object.getOwnPropertyDescriptor(a, "3");
+assertEquals(false, desc.configurable);
+assertEquals(false, desc.writable);
+
+a = [0,1,2,3,4,5,6];
+Object.defineProperty(a, "5", {configurable:false, value:5});
+assertThrows("a.splice(1,4);", TypeError);
+assertEquals([0,5,6,3,4,5,,], a);
+desc = Object.getOwnPropertyDescriptor(a, "5");
+assertEquals(false, desc.configurable);
+
+a = [1,2,3,,5];
+Object.defineProperty(a, "1", {configurable:false, writable:true, value:2});
+assertEquals(1, a.shift());
+assertEquals([2,3,,5], a);
+desc = Object.getOwnPropertyDescriptor(a, "1");
+assertEquals(false, desc.configurable);
+assertEquals(true, desc.writable);
+assertThrows("a.shift();", TypeError);
+assertEquals([3,3,,5], a);
+desc = Object.getOwnPropertyDescriptor(a, "1");
+assertEquals(false, desc.configurable);
+assertEquals(true, desc.writable);
+
+a = [1,2,3];
+Object.defineProperty(a, "2", {configurable:false, value:3});
+assertThrows("a.pop();", TypeError);
+assertEquals([1,2,3], a);
+desc = Object.getOwnPropertyDescriptor(a, "2");
+assertEquals(false, desc.configurable);
diff --git a/test/mjsunit/regress/regress-3229.js b/test/mjsunit/regress/regress-3229.js
new file mode 100644
index 0000000..1a0ed64
--- /dev/null
+++ b/test/mjsunit/regress/regress-3229.js
@@ -0,0 +1,26 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Escape '/'.
+function testEscapes(expected, regexp) {
+  assertEquals(expected, regexp.source);
+  assertEquals("/" + expected + "/", regexp.toString());
+}
+
+testEscapes("\\/", /\//);
+testEscapes("\\/\\/", /\/\//);
+testEscapes("\\/", new RegExp("/"));
+testEscapes("\\/", new RegExp("\\/"));
+testEscapes("\\\\/", new RegExp("\\\\/"));
+testEscapes("\\/\\/", new RegExp("\\/\\/"));
+testEscapes("\\/\\/\\/\\/", new RegExp("////"));
+testEscapes("\\/\\/\\/\\/", new RegExp("\\//\\//"));
+testEscapes("(?:)", new RegExp(""));
+testEscapes("(?:)", RegExp.prototype);
+
+// Read-only property.
+var r = /\/\//;
+testEscapes("\\/\\/", r);
+r.source = "garbage";
+testEscapes("\\/\\/", r);
diff --git a/test/mjsunit/regress/regress-3483.js b/test/mjsunit/regress/regress-3483.js
new file mode 100644
index 0000000..dec95c4
--- /dev/null
+++ b/test/mjsunit/regress/regress-3483.js
@@ -0,0 +1,30 @@
+// Copyright 2014 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.
+
+assertFalse(Object.prototype.isPrototypeOf.call());
+assertFalse(Object.prototype.isPrototypeOf.call(null, 1));
+assertFalse(Object.prototype.isPrototypeOf.call(undefined, 1));
diff --git a/test/mjsunit/regress/regress-3612.js b/test/mjsunit/regress/regress-3612.js
new file mode 100644
index 0000000..8c30ebf
--- /dev/null
+++ b/test/mjsunit/regress/regress-3612.js
@@ -0,0 +1,21 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var a = [1];
+var getterValue = 2;
+var endIndex = 0xffff;
+Object.defineProperty(a, endIndex, {
+  get: function() {
+    this[1] = 3;
+    return getterValue;
+  },
+  set: function(val) {
+    getterValue = val;
+  },
+  configurable: true,
+  enumerable: true
+});
+a.reverse();
+assertFalse(a.hasOwnProperty(1));
+assertEquals(3, a[endIndex-1]);
diff --git a/test/mjsunit/regress/regress-3621.js b/test/mjsunit/regress/regress-3621.js
new file mode 100644
index 0000000..16ddde1
--- /dev/null
+++ b/test/mjsunit/regress/regress-3621.js
@@ -0,0 +1,11 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var a = [];
+var endIndex = 0xffff;
+a[endIndex] = 3;
+Object.defineProperty(a, 0, { get: function() { this[1] = 2; return 1; } });
+assertEquals('123', a.join(''));
+delete a[1];  // reset the array
+assertEquals('1,2,', a.join().slice(0, 4));
diff --git a/test/mjsunit/regress/regress-3643.js b/test/mjsunit/regress/regress-3643.js
new file mode 100644
index 0000000..bbc94fd
--- /dev/null
+++ b/test/mjsunit/regress/regress-3643.js
@@ -0,0 +1,30 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function newArrayWithGetter() {
+  var arr = [1, 2, 3];
+  Object.defineProperty(arr, '1', {
+    get: function() { delete this[1]; return undefined; },
+    configurable: true
+  });
+  return arr;
+}
+
+var a = newArrayWithGetter();
+var s = a.slice(1);
+assertTrue('0' in s);
+
+// Sparse case should hit the same code as above due to presence of the getter.
+a = newArrayWithGetter();
+a[0xffff] = 4;
+s = a.slice(1);
+assertTrue('0' in s);
+
+a = newArrayWithGetter();
+a.shift();
+assertTrue('0' in a);
+
+a = newArrayWithGetter();
+a.unshift(0);
+assertTrue('2' in a);
diff --git a/test/mjsunit/regress/regress-3687.js b/test/mjsunit/regress/regress-3687.js
new file mode 100644
index 0000000..e1df1b4
--- /dev/null
+++ b/test/mjsunit/regress/regress-3687.js
@@ -0,0 +1,22 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+var t1 = { f1: 0 };
+var t2 = { f2: 0 };
+
+var z = {
+  x: {
+    x: t1,
+    y: {
+      x: {},
+      z1: {
+        x: t2,
+        y: 1
+      }
+    }
+  },
+  z2: 0
+};
diff --git a/test/mjsunit/regress/regress-3709.js b/test/mjsunit/regress/regress-3709.js
new file mode 100644
index 0000000..d2de711
--- /dev/null
+++ b/test/mjsunit/regress/regress-3709.js
@@ -0,0 +1,28 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function getobj() {
+  return { bar : function() { return 0}};
+}
+
+function foo() {
+  var obj = getobj();
+  var length = arguments.length;
+  if (length == 0) {
+     obj.bar();
+  } else {
+     obj.bar.apply(obj, arguments);
+  }
+}
+
+foo();
+foo();
+%OptimizeFunctionOnNextCall(foo);
+foo();
+assertOptimized(foo);
+foo(10);
+assertUnoptimized(foo);
+%ClearFunctionTypeFeedback(foo);
diff --git a/test/mjsunit/regress/regress-3717.js b/test/mjsunit/regress/regress-3717.js
new file mode 100644
index 0000000..1f7bc7d
--- /dev/null
+++ b/test/mjsunit/regress/regress-3717.js
@@ -0,0 +1,33 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug --no-lazy
+
+Debug = debug.Debug;
+var exception = null;
+var break_count = 0;
+
+function f() {
+  function g(p) {
+    return 1;
+  }
+  g(1);
+};
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) break_count++;
+  } catch (e) {
+    exception = e;
+  }
+}
+
+Debug.setListener(listener);
+var bp = Debug.setBreakPoint(f, 2);
+f();
+Debug.clearBreakPoint(bp);
+Debug.setListener(null);
+
+assertEquals(1, break_count);
+assertNull(exception);
diff --git a/test/mjsunit/regress/regress-3756.js b/test/mjsunit/regress/regress-3756.js
new file mode 100644
index 0000000..6b1f029
--- /dev/null
+++ b/test/mjsunit/regress/regress-3756.js
@@ -0,0 +1,74 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function TestIdentityEscapes() {
+  // \u not followed by 4 hex digits is treated as an identity escape.
+  var r0 = /\u/;
+  assertTrue(r0.test("u"));
+
+  r0 = RegExp("\\u");
+  assertTrue(r0.test("u"));
+
+  var r1 = /\usecond/;
+  assertTrue(r1.test("usecond"));
+
+  r1 = RegExp("\\usecond");
+  assertTrue(r1.test("usecond"));
+
+  var r2 = /first\u/;
+  assertTrue(r2.test("firstu"));
+  // This used to return true (which was a bug).
+  assertFalse(r2.test("first\\u"));
+
+  r2 = RegExp("first\\u");
+  assertTrue(r2.test("firstu"));
+  // This used to return true (which was a bug).
+  assertFalse(r2.test("first\\u"));
+
+  var r3 = /first\usecond/;
+  assertTrue(r3.test("firstusecond"));
+  assertFalse(r3.test("first\\usecond"));
+
+  r3 = RegExp("first\\usecond");
+  assertTrue(r3.test("firstusecond"));
+  assertFalse(r3.test("first\\usecond"));
+
+  var r4 = /first\u123second/;
+  assertTrue(r4.test("firstu123second"));
+  assertFalse(r4.test("first\\u123second"));
+
+  r4 = RegExp("first\\u123second");
+  assertTrue(r4.test("firstu123second"));
+  assertFalse(r4.test("first\\u123second"));
+
+  // \X where X is not a legal escape character is treated as identity escape
+  // too.
+  var r5 = /\a/;
+  assertTrue(r5.test("a"));
+
+  r5 = RegExp("\\a");
+  assertTrue(r5.test("a"));
+
+  var r6 = /\asecond/;
+  assertTrue(r6.test("asecond"));
+
+  r6 = RegExp("\\asecond");
+  assertTrue(r6.test("asecond"));
+
+  var r7 = /first\a/;
+  assertTrue(r7.test("firsta"));
+  assertFalse(r7.test("first\\a"));
+
+  r7 = RegExp("first\\a");
+  assertTrue(r7.test("firsta"));
+  assertFalse(r7.test("first\\a"));
+
+  var r8 = /first\asecond/;
+  assertTrue(r8.test("firstasecond"));
+  assertFalse(r8.test("first\\asecond"));
+
+  r8 = RegExp("first\\asecond");
+  assertTrue(r8.test("firstasecond"));
+  assertFalse(r8.test("first\\asecond"));
+})();
diff --git a/test/mjsunit/regress/regress-385565.js b/test/mjsunit/regress/regress-385565.js
new file mode 100644
index 0000000..d2a0875
--- /dev/null
+++ b/test/mjsunit/regress/regress-385565.js
@@ -0,0 +1,70 @@
+// Copyright 2014 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 --noalways-opt
+
+var calls = 0;
+
+function callsFReceiver(o) {
+    return [].f.call(new Number(o.m), 1, 2, 3);
+}
+
+// For the HConstant
+Array.prototype.f = function() {
+    calls++;
+    return +this;
+};
+
+
+var o1 = {m: 1};
+var o2 = {a: 0, m:1};
+
+var r1 = callsFReceiver(o1);
+callsFReceiver(o1);
+%OptimizeFunctionOnNextCall(callsFReceiver);
+var r2 = callsFReceiver(o1);
+assertOptimized(callsFReceiver);
+callsFReceiver(o2);
+assertUnoptimized(callsFReceiver);
+var r3 = callsFReceiver(o1);
+
+assertEquals(1, r1);
+assertTrue(r1 === r2);
+assertTrue(r2 === r3);
+
+r1 = callsFReceiver(o1);
+callsFReceiver(o1);
+%OptimizeFunctionOnNextCall(callsFReceiver);
+r2 = callsFReceiver(o1);
+callsFReceiver(o2);
+r3 = callsFReceiver(o1);
+
+assertEquals(1, r1);
+assertTrue(r1 === r2);
+assertTrue(r2 === r3);
+
+assertEquals(10, calls);
diff --git a/test/mjsunit/regress/regress-410030.js b/test/mjsunit/regress/regress-410030.js
new file mode 100644
index 0000000..efd4b1e
--- /dev/null
+++ b/test/mjsunit/regress/regress-410030.js
@@ -0,0 +1,43 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+try {
+  throw 0;
+} catch(e) {
+  assertSame(3, eval("delete x; const x=3; x"));
+}
+
+
+try {
+  throw 0;
+} catch(e) {
+  assertSame(3, (1,eval)("delete x1; const x1=3; x1"));
+}
+
+
+try {
+  throw 0;
+} catch(e) {
+  with({}) {
+    assertSame(3, eval("delete x2; const x2=3; x2"));
+  }
+}
+
+
+(function f() {
+  try {
+    throw 0;
+  } catch(e) {
+    assertSame(3, eval("delete x; const x=3; x"));
+  }
+}());
+
+
+(function f() {
+  try {
+    throw 0;
+  } catch(e) {
+    assertSame(3, (1,eval)("delete x4; const x4=3; x4"));
+  }
+}());
diff --git a/test/mjsunit/regress/regress-416730.js b/test/mjsunit/regress/regress-416730.js
new file mode 100644
index 0000000..8d7f207
--- /dev/null
+++ b/test/mjsunit/regress/regress-416730.js
@@ -0,0 +1,24 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+var d = {x: undefined, y: undefined};
+
+function Crash(left, right) {
+  var c = {
+    x: right.x - left.x,
+    y: right.y - left.y
+  };
+  return c.x * c.y;
+}
+
+var a = {x: 0.5, y: 0};
+var b = {x: 1, y: 0};
+
+for (var i = 0; i < 3; i++) Crash(a, b);
+%OptimizeFunctionOnNextCall(Crash);
+Crash(a, b);
+
+Crash({x: 0, y: 0.5}, b);
diff --git a/test/mjsunit/regress/regress-417709a.js b/test/mjsunit/regress/regress-417709a.js
new file mode 100644
index 0000000..7c4d4f7
--- /dev/null
+++ b/test/mjsunit/regress/regress-417709a.js
@@ -0,0 +1,16 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --stack-size=100 --turbo-deoptimization
+
+var a = [];
+
+Object.observe(a, function() {});
+
+function f(a, x) {
+  a.length = x;
+  f(a, x + 1);
+}
+
+assertThrows(function() { f(a, 1); }, RangeError);
diff --git a/test/mjsunit/regress/regress-417709b.js b/test/mjsunit/regress/regress-417709b.js
new file mode 100644
index 0000000..7680543
--- /dev/null
+++ b/test/mjsunit/regress/regress-417709b.js
@@ -0,0 +1,16 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --stack-size=100
+
+var a = [];
+
+Array.observe(a, function() {});
+
+function f(a, x) {
+  a.length = x;
+  f(a, x + 1);
+}
+
+assertThrows(function() { f(a, 1); }, RangeError);
diff --git a/test/mjsunit/regress/regress-419663.js b/test/mjsunit/regress/regress-419663.js
new file mode 100644
index 0000000..6f51741
--- /dev/null
+++ b/test/mjsunit/regress/regress-419663.js
@@ -0,0 +1,37 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+
+var o = {
+  f: function(x) {
+    var a = x + 1;
+    o = 1;
+  }
+}
+
+function sentinel() {}
+
+var Debug = debug.Debug;
+
+Debug.setListener(function() {});
+
+var script = Debug.findScript(sentinel);
+
+// Used in Debug.setScriptBreakPointById.
+var p = Debug.findScriptSourcePosition(script, 9, 0);
+var q = Debug.setBreakPointByScriptIdAndPosition(script.id, p).actual_position;
+var r = Debug.setBreakPointByScriptIdAndPosition(script.id, q).actual_position;
+
+assertEquals(q, r);
+
+function assertLocation(p, l, c) {
+  var location = script.locationFromPosition(p, false);
+  assertEquals(l, location.line);
+  assertEquals(c, location.column);
+}
+
+assertLocation(p, 9, 0);
+assertLocation(q, 9, 4);
+assertLocation(r, 9, 4);
diff --git a/test/mjsunit/regress/regress-423633.js b/test/mjsunit/regress/regress-423633.js
new file mode 100644
index 0000000..12d2483
--- /dev/null
+++ b/test/mjsunit/regress/regress-423633.js
@@ -0,0 +1,18 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Object.defineProperty(Array.prototype, '0', {
+  get: function() { return false; },
+});
+var a = [1, 2, 3];
+assertEquals(a, a.slice());
+assertEquals([3], a.splice(2, 1));
+
+a = [1, 2, 3];
+a[0xffff] = 4;
+// nulling the prototype lets us stay in the sparse case; otherwise the
+// getter on Array.prototype would force us into the non-sparse code.
+a.__proto__ = null;
+assertEquals(a, Array.prototype.slice.call(a));
+assertEquals([3], Array.prototype.splice.call(a, 2, 1));
diff --git a/test/mjsunit/regress/regress-425551.js b/test/mjsunit/regress/regress-425551.js
new file mode 100644
index 0000000..eee5e32
--- /dev/null
+++ b/test/mjsunit/regress/regress-425551.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var array = new Int8Array(10);
+array[/\u007d\u00fc\u0043/] = 1.499
+assertEquals(1.499, array[/\u007d\u00fc\u0043/]);
diff --git a/test/mjsunit/regress/regress-430201.js b/test/mjsunit/regress/regress-430201.js
new file mode 100644
index 0000000..b53383e
--- /dev/null
+++ b/test/mjsunit/regress/regress-430201.js
@@ -0,0 +1,41 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * 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 array_1 = [];
+
+%SetFlags("--stress-compaction");
+for (var a = 0; a < 10000; a++) { array_1[a * 100] = 0; }
+
+gc();
+gc();
+
+var array_2 = [];
+for (var i = 0; i < 321361; i++) {
+  array_2[i] = String.fromCharCode(i)[0];
+}
diff --git a/test/mjsunit/regress/regress-435073.js b/test/mjsunit/regress/regress-435073.js
new file mode 100644
index 0000000..dbaa612
--- /dev/null
+++ b/test/mjsunit/regress/regress-435073.js
@@ -0,0 +1,12 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --verify-heap
+
+function test(x) { [x,,]; }
+
+test(0);
+test(0);
+%OptimizeFunctionOnNextCall(test);
+test(0);
diff --git a/test/mjsunit/regress/regress-435477.js b/test/mjsunit/regress/regress-435477.js
new file mode 100644
index 0000000..0a15000
--- /dev/null
+++ b/test/mjsunit/regress/regress-435477.js
@@ -0,0 +1,16 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+var a = new Array(128);
+
+function f(a, base) {
+  a[base] = 2;
+}
+
+f(a, undefined);
+f("r12", undefined);
+f(a, 0);
+%OptimizeFunctionOnNextCall(f);
+f(a, 0);
diff --git a/test/mjsunit/regress/regress-436893.js b/test/mjsunit/regress/regress-436893.js
new file mode 100644
index 0000000..38e7b5f
--- /dev/null
+++ b/test/mjsunit/regress/regress-436893.js
@@ -0,0 +1,37 @@
+// Copyright 2010 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * 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 x = 11;
+function foo() {
+  return 42;
+}
+// Test passing null or undefined as receiver.
+function g() { return foo.apply(null, x()++); }
+%OptimizeFunctionOnNextCall(g);
+assertThrows(g);
diff --git a/test/mjsunit/regress/regress-436896.js b/test/mjsunit/regress/regress-436896.js
new file mode 100644
index 0000000..344a7a3
--- /dev/null
+++ b/test/mjsunit/regress/regress-436896.js
@@ -0,0 +1,17 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function f(x) {
+  const x = 0;
+  return x;
+}
+
+function g(x) {
+  return f(x);
+}
+
+%OptimizeFunctionOnNextCall(g);
+assertThrows(function() { g(42); }, TypeError);
diff --git a/test/mjsunit/regress/regress-437765.js b/test/mjsunit/regress/regress-437765.js
new file mode 100644
index 0000000..88d5388
--- /dev/null
+++ b/test/mjsunit/regress/regress-437765.js
@@ -0,0 +1,22 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --no-fold-constants
+
+function foo(x, y) {
+  return Math.floor(x / y);
+}
+
+function bar(x, y) {
+  return foo(x + 1, y + 1);
+}
+
+function baz() {
+  bar(64, 2);
+}
+
+baz();
+baz();
+%OptimizeFunctionOnNextCall(baz);
+baz();
diff --git a/test/mjsunit/regress/regress-441099.js b/test/mjsunit/regress/regress-441099.js
new file mode 100644
index 0000000..63aecfd
--- /dev/null
+++ b/test/mjsunit/regress/regress-441099.js
@@ -0,0 +1,53 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var Module;
+if (!Module) Module = eval('(function() { try { return Module || {} } catch(e) { return {} } })()');
+else if (ENVIRONMENT_IS_SHELL) {
+}
+var Runtime = {
+  stackSave: function () {
+  },
+  alignMemory: function (quantum) { var ret = size = Math.ceil()*(quantum ? quantum : 8); return ret; }}
+function allocate() {
+}
+function callRuntimeCallbacks(callbacks) {
+    var callback = callbacks.shift();
+    var func = callback.func;
+    if (typeof func === 'number') {
+    } else {
+      func();
+    }
+}
+var __ATINIT__    = []; // functions called during startup
+function ensureInitRuntime() {
+  callRuntimeCallbacks(__ATINIT__);
+}
+/* global initializers */ __ATINIT__.push({ func: function() { runPostSets() } });
+    function __formatString() {
+            switch (next) {
+            }
+    }
+  var Browser={mainLoop:{queue:[],pause:function () {
+        }},moduleContextCreatedCallbacks:[],workers:[],init:function () {
+      }};
+var asm = (function() {
+  'use asm';
+function setThrew() {
+}
+function runPostSets() {
+}
+function _main() {
+}
+function _free() {
+}
+  return { runPostSets: runPostSets};
+})
+();
+var runPostSets = Module["runPostSets"] = asm["runPostSets"];
+var i64Math = (function() { // Emscripten wrapper
+  /**
+   */
+})();
+    ensureInitRuntime();
diff --git a/test/mjsunit/regress/regress-447756.js b/test/mjsunit/regress/regress-447756.js
new file mode 100644
index 0000000..1fc7518
--- /dev/null
+++ b/test/mjsunit/regress/regress-447756.js
@@ -0,0 +1,48 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --allow-natives-syntax
+
+function TestConstructor(c) {
+  var a = new c(-0);
+  assertSame(Infinity, 1 / a.length);
+  assertSame(Infinity, 1 / a.byteLength);
+
+  var ab = new ArrayBuffer(-0);
+  assertSame(Infinity, 1 / ab.byteLength);
+
+  var a1 = new c(ab, -0, -0);
+  assertSame(Infinity, 1 / a1.length);
+  assertSame(Infinity, 1 / a1.byteLength);
+  assertSame(Infinity, 1 / a1.byteOffset);
+}
+
+var constructors =
+  [ Uint8Array, Int8Array, Uint8ClampedArray,
+    Uint16Array, Int16Array,
+    Uint32Array, Int32Array,
+    Float32Array, Float64Array ];
+for (var i = 0; i < constructors.length; i++) {
+  TestConstructor(constructors[i]);
+}
+
+
+function TestOptimizedCode() {
+  var a = new Uint8Array(-0);
+  assertSame(Infinity, 1 / a.length);
+  assertSame(Infinity, 1 / a.byteLength);
+
+  var ab = new ArrayBuffer(-0);
+  assertSame(Infinity, 1 / ab.byteLength);
+
+  var a1 = new Uint8Array(ab, -0, -0);
+  assertSame(Infinity, 1 / a1.length);
+  assertSame(Infinity, 1 / a1.byteLength);
+  assertSame(Infinity, 1 / a1.byteOffset);
+}
+
+%OptimizeFunctionOnNextCall(Uint8Array);
+for (var i = 0; i < 1000; i++) {
+  TestOptimizedCode();
+}
diff --git a/test/mjsunit/regress/regress-78270.js b/test/mjsunit/regress/regress-78270.js
index b9ce286..02c4b14 100644
--- a/test/mjsunit/regress/regress-78270.js
+++ b/test/mjsunit/regress/regress-78270.js
@@ -25,6 +25,8 @@
 // (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: --turbo-deoptimization
+
 for (var i = 0; i < 10000; i++) {
   try {
     var object = { };
diff --git a/test/mjsunit/regress/regress-assignment-in-test-context.js b/test/mjsunit/regress/regress-assignment-in-test-context.js
new file mode 100644
index 0000000..bc40985
--- /dev/null
+++ b/test/mjsunit/regress/regress-assignment-in-test-context.js
@@ -0,0 +1,20 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --always-opt
+// Flags: --turbo-filter=* --turbo-deoptimization
+
+function assertEquals() {}
+
+function f(o) {
+  if (o.setterProperty = 0) {
+    return 1;
+  }
+  return 2;
+}
+
+function deopt() { %DeoptimizeFunction(f); }
+
+assertEquals(2,
+             f(Object.defineProperty({}, "setterProperty", { set: deopt })));
diff --git a/test/mjsunit/regress/regress-crbug-109362.js b/test/mjsunit/regress/regress-crbug-109362.js
new file mode 100644
index 0000000..b156013
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-109362.js
@@ -0,0 +1,26 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+
+function test(expectation, f) {
+  var stack;
+  try {
+    f();
+  } catch (e) {
+    stack = e.stack;
+  }
+  print(stack);
+  assertTrue(stack.indexOf("at eval (evaltest:" + expectation + ")") > 0);
+}
+
+test("1:5", new Function(
+    '1 + reference_error //@ sourceURL=evaltest'));
+test("2:6", new Function(
+    'x', '\n 1 + reference_error //@ sourceURL=evaltest'));
+test("2:6", new Function(
+    'x\n\n', "z//\n", "y", '\n 1 + reference_error //@ sourceURL=evaltest'));
+test("1:5", new Function(
+    'x/*', "z//\n", "y*/", '1 + reference_error //@ sourceURL=evaltest'));
+test("2:6", eval(
+    '(function () {\n 1 + reference_error //@ sourceURL=evaltest\n})'));
diff --git a/test/mjsunit/regress/regress-crbug-320922.js b/test/mjsunit/regress/regress-crbug-320922.js
index 9ba759a..f199628 100644
--- a/test/mjsunit/regress/regress-crbug-320922.js
+++ b/test/mjsunit/regress/regress-crbug-320922.js
@@ -27,8 +27,10 @@
 
 // Flags: --allow-natives-syntax
 
-var string = "hello world";
-var expected = "Hello " + "world";
+var string = "internalized dummy";
+var expected = "internalized dummy";
+string = "hello world";
+expected = "Hello " + "world";
 function Capitalize() {
   %_OneByteSeqStringSetChar(0, 0x48, string);
 }
diff --git a/test/mjsunit/regress/regress-crbug-323936.js b/test/mjsunit/regress/regress-crbug-323936.js
new file mode 100644
index 0000000..d896ead
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-323936.js
@@ -0,0 +1,46 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+
+Debug = debug.Debug;
+
+var step = 0;
+var exception = null;
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    if (step == 0) {
+      assertEquals("error", exec_state.frame(0).evaluate("e").value());
+      exec_state.frame(0).evaluate("e = 'foo'");
+      exec_state.frame(0).evaluate("x = 'modified'");
+    } else {
+      assertEquals("argument", exec_state.frame(0).evaluate("e").value());
+      exec_state.frame(0).evaluate("e = 'bar'");
+    }
+    step++;
+  } catch (e) {
+    print(e + e.stack);
+    exception = e;
+  }
+}
+
+Debug.setListener(listener);
+
+function f(e, x) {
+  try {
+    throw "error";
+  } catch(e) {
+    debugger;
+    assertEquals("foo", e);
+  }
+  debugger;
+  assertEquals("bar", e);
+  assertEquals("modified", x);
+}
+
+f("argument")
+assertNull(exception);
+assertEquals(2, step);
diff --git a/test/mjsunit/regress/regress-crbug-409614.js b/test/mjsunit/regress/regress-crbug-409614.js
new file mode 100644
index 0000000..7b27404
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-409614.js
@@ -0,0 +1,37 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+
+Debug = debug.Debug;
+var exception = null;
+var error_count = 0;
+
+function f() {
+  return 0;  // Break
+}
+
+function listener(event, exec_state, event_data, data) {
+  if (event != Debug.DebugEvent.Break) return;
+  try {
+    if (exec_state.frame(0).sourceLineText().indexOf("Break") <0) {
+      error_count++;
+    }
+    exec_state.prepareStep(Debug.StepAction.StepIn, 2);
+    f();  // We should not break in this call of f().
+  } catch (e) {
+    print(e + e.stack);
+    exception = e;
+  }
+}
+
+Debug.setListener(listener);
+
+debugger;  // Break
+f();
+
+Debug.setListener(null);  // Break
+
+assertNull(exception);
+assertEquals(0, error_count);
diff --git a/test/mjsunit/regress/regress-crbug-410033.js b/test/mjsunit/regress/regress-crbug-410033.js
new file mode 100644
index 0000000..63693e6
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-410033.js
@@ -0,0 +1,7 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+%GetScript('v8/gc');
diff --git a/test/mjsunit/regress/regress-crbug-412319.js b/test/mjsunit/regress/regress-crbug-412319.js
index 21386e3..c597b0d 100644
--- a/test/mjsunit/regress/regress-crbug-412319.js
+++ b/test/mjsunit/regress/regress-crbug-412319.js
@@ -15,5 +15,5 @@
 %OptimizeFunctionOnNextCall(__f_6);
 __f_6();
 function __f_7(__v_7) {
-  __v_7.push(Infinity);
+  __v_7.pop();
 }
diff --git a/test/mjsunit/regress/regress-crbug-416558.js b/test/mjsunit/regress/regress-crbug-416558.js
new file mode 100644
index 0000000..375ad40
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-416558.js
@@ -0,0 +1,115 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function() {
+  function store(x) { x[0] = 0; }
+  store([]);
+  var c = /x/;
+  store(c);
+  function get_hole() {
+    var b = /x/;
+    store(b);
+    return b[1];
+  }
+  assertEquals(undefined, get_hole());
+  assertEquals(undefined, get_hole());
+})();
+
+(function() {
+  function store(x) { x[0] = 0; }
+  store([]);
+  var c = new Date();
+  store(c);
+  function get_hole() {
+    var b = new Date();
+    store(b);
+    return b[1];
+  }
+  assertEquals(undefined, get_hole());
+  assertEquals(undefined, get_hole());
+})();
+
+(function() {
+  function store(x) { x[0] = 0; }
+  store([]);
+  var c = new Number(1);
+  store(c);
+  function get_hole() {
+    var b = new Number(1);
+    store(b);
+    return b[1];
+  }
+  assertEquals(undefined, get_hole());
+  assertEquals(undefined, get_hole());
+})();
+
+(function() {
+  function store(x) { x[0] = 0; }
+  store([]);
+  var c = new Boolean();
+  store(c);
+  function get_hole() {
+    var b = new Boolean();
+    store(b);
+    return b[1];
+  }
+  assertEquals(undefined, get_hole());
+  assertEquals(undefined, get_hole());
+})();
+
+(function() {
+  function store(x) { x[0] = 0; }
+  store([]);
+  var c = new Map();
+  store(c);
+  function get_hole() {
+    var b = new Map();
+    store(b);
+    return b[1];
+  }
+  assertEquals(undefined, get_hole());
+  assertEquals(undefined, get_hole());
+})();
+
+(function() {
+  function store(x) { x[0] = 0; }
+  store([]);
+  var c = new Set();
+  store(c);
+  function get_hole() {
+    var b = new Set();
+    store(b);
+    return b[1];
+  }
+  assertEquals(undefined, get_hole());
+  assertEquals(undefined, get_hole());
+})();
+
+(function() {
+  function store(x) { x[0] = 0; }
+  store([]);
+  var c = new WeakMap();
+  store(c);
+  function get_hole() {
+    var b = new WeakMap();
+    store(b);
+    return b[1];
+  }
+  assertEquals(undefined, get_hole());
+  assertEquals(undefined, get_hole());
+})();
+
+(function() {
+  function store(x) { x[0] = 0; }
+  store([]);
+  var c = new WeakSet();
+  store(c);
+  function get_hole() {
+    var b = new WeakSet();
+    store(b);
+    return b[1];
+  }
+  assertEquals(undefined, get_hole());
+  assertEquals(undefined, get_hole());
+})();
diff --git a/test/mjsunit/regress/regress-crbug-424142.js b/test/mjsunit/regress/regress-crbug-424142.js
new file mode 100644
index 0000000..0a370d4
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-424142.js
@@ -0,0 +1,36 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+
+(function outer() {
+  var C = (function C_() {
+    var y = 1;
+    function CC() {
+      this.x = 0;
+    }
+    CC.prototype.f = function CCf() {
+      this.x += y;
+      return this.x;
+    };
+    return CC;
+  })();
+
+  var c = new C(0);
+})
+
+function sentinel() {}
+
+Debug = debug.Debug;
+
+var script = Debug.findScript(sentinel);
+var line = 14;
+var line_start = Debug.findScriptSourcePosition(script, line, 0);
+var line_end = Debug.findScriptSourcePosition(script, line + 1, 0) - 1;
+var actual = Debug.setBreakPointByScriptIdAndPosition(
+                 script.id, line_start).actual_position;
+// Make sure the actual break position is within the line where we set
+// the break point.
+assertTrue(line_start <= actual);
+assertTrue(actual <= line_end);
diff --git a/test/mjsunit/regress/regress-crbug-425519.js b/test/mjsunit/regress/regress-crbug-425519.js
new file mode 100644
index 0000000..d08e7b9
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-425519.js
@@ -0,0 +1,15 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function load(a, i) {
+  return a[i];
+}
+
+load([]);
+load(0);
+load("x", 0);
+%OptimizeFunctionOnNextCall(load);
+load([], 0);
diff --git a/test/mjsunit/regress/regress-crbug-425585.js b/test/mjsunit/regress/regress-crbug-425585.js
new file mode 100644
index 0000000..c27febb
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-425585.js
@@ -0,0 +1,48 @@
+// Copyright 2014 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 correct_result = "This is the correct result.";
+
+function foo(recursion_depth) {
+   if (recursion_depth > 0) return foo(recursion_depth - 1);
+   return new String(correct_result, 1, 2, 3, 4, 5, 6);
+}
+
+// Roll our own non-strict assertEquals replacement.
+function test(i) {
+   var actual = foo(i);
+   if (correct_result != actual) {
+     var msg = "Expected \"" + correct_result + "\", found " + actual;
+     throw new MjsUnitAssertionError(msg);
+   }
+}
+
+test(1);
+test(1);
+test(10);
+test(100);
diff --git a/test/mjsunit/regress/regress-crbug-429159.js b/test/mjsunit/regress/regress-crbug-429159.js
new file mode 100644
index 0000000..69f1856
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-429159.js
@@ -0,0 +1,12 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+try {
+  var src = "return " + Array(12000).join("src,") + "src";
+  var fun = Function(src);
+  assertEquals(src, fun());
+} catch (e) {
+  // Some architectures throw a RangeError, that is fine.
+  assertInstanceof(e, RangeError);
+}
diff --git a/test/mjsunit/regress/regress-crbug-430846.js b/test/mjsunit/regress/regress-crbug-430846.js
new file mode 100644
index 0000000..3047c7f
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-430846.js
@@ -0,0 +1,14 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function foo() { return 1; };
+var o1 = {};
+o1.foo = foo;
+
+var json = '{"foo": {"x": 1}}';
+var o2 = JSON.parse(json);
+var o3 = JSON.parse(json);
+assertTrue(%HaveSameMap(o2, o3));
diff --git a/test/mjsunit/regress/regress-crbug-431602.js b/test/mjsunit/regress/regress-crbug-431602.js
new file mode 100644
index 0000000..2467aaf
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-431602.js
@@ -0,0 +1,23 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --always-opt
+
+var heap_number_producer = {y:1.5};
+heap_number_producer.y = 0;
+var heap_number_zero = heap_number_producer.y;
+var non_constant_eight = {};
+non_constant_eight = 8;
+
+function BreakIt() {
+  return heap_number_zero | (1 | non_constant_eight);
+}
+
+function expose(a, b, c) {
+  return b;
+}
+
+assertEquals(9, expose(8, 9, 10));
+assertEquals(9, expose(8, BreakIt(), 10));
+assertEquals(9, BreakIt());
diff --git a/test/mjsunit/regress/regress-crbug-432493.js b/test/mjsunit/regress/regress-crbug-432493.js
new file mode 100644
index 0000000..87c4f83
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-432493.js
@@ -0,0 +1,57 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --expose-debug-as debug
+
+function f() {
+  var a = 1;
+  var b = 2;
+  return a + b;
+}
+
+var exception = null;
+var break_count = 0;
+var throw_count = 0;
+
+function listener(event, exec_state, event_data, data) {
+  try {
+    if (event == Debug.DebugEvent.Break) {
+      break_count++;
+      // Disable all breakpoints from within the debug event callback.
+      Debug.debuggerFlags().breakPointsActive.setValue(false);
+    } else if (event = Debug.DebugEvent.Exception) {
+      throw_count++;
+      // Enable all breakpoints from within the debug event callback.
+      Debug.debuggerFlags().breakPointsActive.setValue(true);
+    }
+  } catch (e) {
+    exception = e;
+  }
+}
+
+Debug = debug.Debug;
+
+Debug.setListener(listener);
+Debug.setBreakOnException();
+Debug.setBreakPoint(f, 2);
+
+f();
+f();
+
+assertEquals(1, break_count);
+assertEquals(0, throw_count);
+
+// Trigger exception event.
+try { throw 1; } catch (e) {}
+
+f();
+f();
+
+Debug.setListener(null);
+Debug.clearBreakOnException();
+Debug.debuggerFlags().breakPointsActive.setValue(true);
+
+assertEquals(2, break_count);
+assertEquals(1, throw_count);
+assertNull(exception);
diff --git a/test/mjsunit/regress/regress-crbug-433332.js b/test/mjsunit/regress/regress-crbug-433332.js
new file mode 100644
index 0000000..d763243
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-433332.js
@@ -0,0 +1,16 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function f(foo) {
+  var g;
+  true ? (g = 0.1) : g |=  null;
+  if (null != g) {}
+};
+
+f(1.4);
+f(1.4);
+%OptimizeFunctionOnNextCall(f);
+f(1.4);
diff --git a/test/mjsunit/regress/regress-crbug-433766.js b/test/mjsunit/regress/regress-crbug-433766.js
new file mode 100644
index 0000000..fae9483
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-433766.js
@@ -0,0 +1,16 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var filler = "//" + new Array(('@')).join('x');
+
+// Test strict eval in global context.
+eval(
+  "'use strict';" +
+  "var x = 23;" +
+  "var f = function bozo1() {" +
+  "  return x;" +
+  "};" +
+  "f;" +
+  filler
+)();
diff --git a/test/mjsunit/regress/regress-crbug-435825.js b/test/mjsunit/regress/regress-crbug-435825.js
new file mode 100644
index 0000000..e10b812
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-435825.js
@@ -0,0 +1,11 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+Error.prepareStackTrace = function (a,b) { return b; };
+
+try {
+  /(invalid regexp/;
+} catch (e) {
+  e.stack[0].getThis().toString();
+}
diff --git a/test/mjsunit/regress/regress-crbug-436820.js b/test/mjsunit/regress/regress-crbug-436820.js
new file mode 100644
index 0000000..eea386c
--- /dev/null
+++ b/test/mjsunit/regress/regress-crbug-436820.js
@@ -0,0 +1,13 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function c(p) {
+  return {__proto__: p};
+}
+var p = {};
+var o = c(p);
+p.x = 0.6;
+Object.defineProperty(p, "x", { writable: false });
diff --git a/test/mjsunit/regress/regress-eval-cache.js b/test/mjsunit/regress/regress-eval-cache.js
new file mode 100644
index 0000000..8f8dc18
--- /dev/null
+++ b/test/mjsunit/regress/regress-eval-cache.js
@@ -0,0 +1,19 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function f() {
+  try {
+    throw 1;
+  } catch (e) {
+    var a = 0;
+    var b = 0;
+    var c = 0;
+    var x = 1;
+    var result = eval('eval("x")').toString();
+    assertEquals("1", result);
+  }
+  var x = 2;
+  var result = eval('eval("x")').toString();
+  assertEquals("2", result);
+})();
diff --git a/test/mjsunit/regress/regress-lea-matching.js b/test/mjsunit/regress/regress-lea-matching.js
new file mode 100644
index 0000000..988368a
--- /dev/null
+++ b/test/mjsunit/regress/regress-lea-matching.js
@@ -0,0 +1,14 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function f(a, b, c) {
+  a = a|0;
+  b = b|0;
+  c = c|0;
+  var r = 0;
+  r = a + ((b << 1) + c) | 0;
+  return r|0;
+}
+
+assertEquals(8, f(1, 2, 3));
diff --git a/test/mjsunit/regress/regress-parse-object-literal.js b/test/mjsunit/regress/regress-parse-object-literal.js
index 96d63c2..93725eb 100644
--- a/test/mjsunit/regress/regress-parse-object-literal.js
+++ b/test/mjsunit/regress/regress-parse-object-literal.js
@@ -24,6 +24,8 @@
 // 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: --noharmony-classes --noharmony-object-literals
 
 // Should throw, not crash.
 assertThrows("var o = { get /*space*/ () {} }");
diff --git a/test/mjsunit/regress/regress-shift-enumerable.js b/test/mjsunit/regress/regress-shift-enumerable.js
new file mode 100644
index 0000000..f3ee258
--- /dev/null
+++ b/test/mjsunit/regress/regress-shift-enumerable.js
@@ -0,0 +1,16 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var arr = [1, 2];
+Object.defineProperty(arr, 0xfffe, {
+  value: 3,
+  configurable: true,
+  writable: true,
+  enumerable: false
+});
+arr[0xffff] = 4;
+arr.shift();
+var desc = Object.getOwnPropertyDescriptor(arr, 0xfffe);
+assertEquals(4, desc.value);
+assertFalse(desc.enumerable);
diff --git a/test/mjsunit/regress/regress-splice-large-index.js b/test/mjsunit/regress/regress-splice-large-index.js
new file mode 100644
index 0000000..5da17ee
--- /dev/null
+++ b/test/mjsunit/regress/regress-splice-large-index.js
@@ -0,0 +1,40 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * 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 = [];
+a[0xfffffffe] = 10;
+assertThrows("a.unshift(1);", RangeError);
+assertEquals(0xffffffff, a.length);
+assertEquals(10, a[0xffffffff]);
+assertEquals(undefined, a[0xfffffffe]);
+
+a = [1,2,3];
+a[0xfffffffe] = 10;
+assertThrows("a.splice(1,1,7,7,7,7,7);", RangeError);
+assertEquals([1,7,7,7,7,7,3], a.slice(0, 7));
+assertEquals(0xffffffff, a.length);
+assertEquals(10, a[0xfffffffe + 5 - 1]);
diff --git a/test/mjsunit/regress/regress-unsigned-mul-add.js b/test/mjsunit/regress/regress-unsigned-mul-add.js
new file mode 100644
index 0000000..0a2fc65
--- /dev/null
+++ b/test/mjsunit/regress/regress-unsigned-mul-add.js
@@ -0,0 +1,10 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function f(a) {
+  var x = a >>> 0;
+  return (x * 1.0 + x * 1.0) << 0;
+}
+
+assertEquals(-2, f(-1));
diff --git a/test/mjsunit/regress/regress-weakening-multiplication.js b/test/mjsunit/regress/regress-weakening-multiplication.js
new file mode 100644
index 0000000..dcf0011
--- /dev/null
+++ b/test/mjsunit/regress/regress-weakening-multiplication.js
@@ -0,0 +1,12 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function f() {
+  for (var j = 1; j < 1; j *= -8) {
+  }
+  for (var i = 1; i < 1; j += 2) {
+    j * -1;
+  }
+}
+f();
diff --git a/test/mjsunit/runtime-gen/loadfromsuper.js b/test/mjsunit/runtime-gen/loadfromsuper.js
deleted file mode 100644
index 25f4ff9..0000000
--- a/test/mjsunit/runtime-gen/loadfromsuper.js
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// AUTO-GENERATED BY tools/generate-runtime-tests.py, DO NOT MODIFY
-// Flags: --allow-natives-syntax --harmony --harmony-proxies
-var _home_object = new Object();
-var _receiver = new Object();
-var _name = "name";
-%LoadFromSuper(_home_object, _receiver, _name);
diff --git a/test/mjsunit/serialize-embedded-error.js b/test/mjsunit/serialize-embedded-error.js
new file mode 100644
index 0000000..473c931
--- /dev/null
+++ b/test/mjsunit/serialize-embedded-error.js
@@ -0,0 +1,13 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// --serialize-toplevel --cache=code
+
+var caught = false;
+try {
+  parseInt() = 0;
+} catch(e) {
+  caught = true;
+}
+assertTrue(caught);
diff --git a/test/mjsunit/serialize-ic.js b/test/mjsunit/serialize-ic.js
new file mode 100644
index 0000000..8e5cd2f
--- /dev/null
+++ b/test/mjsunit/serialize-ic.js
@@ -0,0 +1,18 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --cache=code --serialize-toplevel
+
+var foo = [];
+foo[0] = "bar";
+assertEquals(["bar"], foo);
+
+var a;
+var b = 1;
+a = [2];               // STORE_IC
+a[0] = a[0] + 1;       // KEYED_STORE_IC, KEYED_LOAD_IC, BINARY_OP_IC
+assertTrue(a[0] > b);  // CALL_IC, COMPARE_IC
+b = b == null;         // COMPARE_NIL_IC
+b = b || Boolean('');  // TO_BOOLEAN_IC
+assertFalse(b);
diff --git a/test/mjsunit/setters-on-elements.js b/test/mjsunit/setters-on-elements.js
index dd3fabf..001906c 100644
--- a/test/mjsunit/setters-on-elements.js
+++ b/test/mjsunit/setters-on-elements.js
@@ -191,8 +191,8 @@
 
 var values = [3, 3.5, true];
 
-for(var c = 0; c < 3; c++) {
-  for(var s = 0; s < 3; s++) {
+for(var c = 0; c < cf.length; c++) {
+  for(var s = 0; s < values.length; s++) {
     base_setter_test(cf[c], 0, values[s]);
     base_setter_test(cf[c], 1, values[s]);
   }
diff --git a/test/mjsunit/strict-mode.js b/test/mjsunit/strict-mode.js
index 5fb404a..62d003f 100644
--- a/test/mjsunit/strict-mode.js
+++ b/test/mjsunit/strict-mode.js
@@ -25,6 +25,9 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// Flags: --turbo-deoptimization --noharmony-scoping
+// Flags: --noharmony-classes --noharmony-object-literals
+
 function CheckStrictMode(code, exception) {
   assertDoesNotThrow(code);
   assertThrows("'use strict';\n" + code, exception);
diff --git a/test/mjsunit/string-slices.js b/test/mjsunit/string-slices.js
index c3f889b..52f1506 100644
--- a/test/mjsunit/string-slices.js
+++ b/test/mjsunit/string-slices.js
@@ -193,7 +193,8 @@
     utf.substring(5,1) + utf.substring(3,7));
 
 // Externalizing strings.
-var a = "123456789" + "qwertyuiopasdfghjklzxcvbnm";
+var a = "internalized dummy";
+a = "123456789" + "qwertyuiopasdfghjklzxcvbnm";
 var b = "23456789qwertyuiopasdfghjklzxcvbn"
 assertEquals(a.slice(1,-1), b);
 
diff --git a/test/mjsunit/test-hidden-string.js b/test/mjsunit/test-hidden-string.js
deleted file mode 100644
index a5d32c8..0000000
--- a/test/mjsunit/test-hidden-string.js
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --allow-natives-syntax
-
-var o = {};
-%SetHiddenProperty(o, "test", 1);
-// Create non-internalized ""
-var empty = "a".substring(1, 1);
-assertEquals(undefined, o[empty]);
diff --git a/test/mjsunit/third_party/object-keys.js b/test/mjsunit/third_party/object-keys.js
index d09265c..c800374 100644
--- a/test/mjsunit/third_party/object-keys.js
+++ b/test/mjsunit/third_party/object-keys.js
@@ -31,8 +31,8 @@
 
 // Based on LayoutTests/fast/js/Object-keys.html
 
-assertThrows(function () { Object.keys(2) }, TypeError);
-assertThrows(function () { Object.keys("foo") }, TypeError);
+assertEquals(Object.keys(2), []);
+assertEquals(Object.keys("foo"), ["0", "1", "2"]);
 assertThrows(function () { Object.keys(null) }, TypeError);
 assertThrows(function () { Object.keys(undefined) }, TypeError);
 
diff --git a/test/mjsunit/tools/tickprocessor-test.default b/test/mjsunit/tools/tickprocessor-test.default
index 3e01532..c2fe441 100644
--- a/test/mjsunit/tools/tickprocessor-test.default
+++ b/test/mjsunit/tools/tickprocessor-test.default
@@ -24,6 +24,13 @@
       4   30.8%          Shared libraries
       2   15.4%          Unaccounted
 
+ [C++ entry points]:
+   ticks    cpp   total   name
+      2   40.0%   15.4%  v8::internal::Runtime_Math_exp(v8::internal::Arguments)
+      1   20.0%    7.7%  v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+      1   20.0%    7.7%  v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
+      1   20.0%    7.7%  exp
+
  [Bottom up (heavy) profile]:
   Note: percentage shows a share of a particular caller in the total
   amount of its parent calls.
diff --git a/test/mjsunit/tools/tickprocessor-test.func-info b/test/mjsunit/tools/tickprocessor-test.func-info
index c93b6ec..1f34cfb 100644
--- a/test/mjsunit/tools/tickprocessor-test.func-info
+++ b/test/mjsunit/tools/tickprocessor-test.func-info
@@ -18,6 +18,9 @@
       0    0.0%    0.0%  GC
       0    0.0%          Shared libraries
 
+ [C++ entry points]:
+   ticks    cpp   total   name
+
  [Bottom up (heavy) profile]:
   Note: percentage shows a share of a particular caller in the total
   amount of its parent calls.
diff --git a/test/mjsunit/tools/tickprocessor-test.gc-state b/test/mjsunit/tools/tickprocessor-test.gc-state
index 6b1a6a3..d96acf5 100644
--- a/test/mjsunit/tools/tickprocessor-test.gc-state
+++ b/test/mjsunit/tools/tickprocessor-test.gc-state
@@ -16,6 +16,9 @@
       0    0.0%    0.0%  GC
       0    0.0%          Shared libraries
 
+ [C++ entry points]:
+   ticks    cpp   total   name
+
  [Bottom up (heavy) profile]:
   Note: percentage shows a share of a particular caller in the total
   amount of its parent calls.
diff --git a/test/mjsunit/tools/tickprocessor-test.ignore-unknown b/test/mjsunit/tools/tickprocessor-test.ignore-unknown
index de70527..263cec5 100644
--- a/test/mjsunit/tools/tickprocessor-test.ignore-unknown
+++ b/test/mjsunit/tools/tickprocessor-test.ignore-unknown
@@ -23,6 +23,13 @@
       0    0.0%    0.0%  GC
       4   36.4%          Shared libraries
 
+ [C++ entry points]:
+   ticks    cpp   total   name
+      2   40.0%   18.2%  v8::internal::Runtime_Math_exp(v8::internal::Arguments)
+      1   20.0%    9.1%  v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+      1   20.0%    9.1%  v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
+      1   20.0%    9.1%  exp
+
  [Bottom up (heavy) profile]:
   Note: percentage shows a share of a particular caller in the total
   amount of its parent calls.
diff --git a/test/mjsunit/tools/tickprocessor-test.separate-ic b/test/mjsunit/tools/tickprocessor-test.separate-ic
index 119ccbe..aee1d1f 100644
--- a/test/mjsunit/tools/tickprocessor-test.separate-ic
+++ b/test/mjsunit/tools/tickprocessor-test.separate-ic
@@ -26,6 +26,13 @@
       4   30.8%          Shared libraries
       2   15.4%          Unaccounted
 
+ [C++ entry points]:
+   ticks    cpp   total   name
+      2   40.0%   15.4%  v8::internal::Runtime_Math_exp(v8::internal::Arguments)
+      1   20.0%    7.7%  v8::internal::JSObject::LookupOwnRealNamedProperty(v8::internal::String*, v8::internal::LookupResult*)
+      1   20.0%    7.7%  v8::internal::HashTable<v8::internal::StringDictionaryShape, v8::internal::String*>::FindEntry(v8::internal::String*)
+      1   20.0%    7.7%  exp
+
  [Bottom up (heavy) profile]:
   Note: percentage shows a share of a particular caller in the total
   amount of its parent calls.
diff --git a/test/mjsunit/unused-context-in-with.js b/test/mjsunit/unused-context-in-with.js
new file mode 100644
index 0000000..2973ca2
--- /dev/null
+++ b/test/mjsunit/unused-context-in-with.js
@@ -0,0 +1,13 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var x = 1;
+function foo(object) {
+  with(object) {
+    x;
+  }
+  return 100;
+}
+
+assertEquals(100,foo("str"));
diff --git a/test/mjsunit/var.js b/test/mjsunit/var.js
index 5999d70..c3c331e 100644
--- a/test/mjsunit/var.js
+++ b/test/mjsunit/var.js
@@ -35,3 +35,22 @@
 assertTrue(!z && typeof z == 'undefined');
 if (false) { var z; }
 assertTrue(!z && typeof z == 'undefined');
+
+assertThrows("var \u2E2F;", SyntaxError);
+assertThrows("var \\u2E2F;", SyntaxError);
+
+assertDoesNotThrow("var \u2118;");
+assertDoesNotThrow("var \\u2118;");
+assertDoesNotThrow("var \u212E;");
+assertDoesNotThrow("var \\u212E;");
+assertDoesNotThrow("var \u309B;");
+assertDoesNotThrow("var \\u309B;");
+assertDoesNotThrow("var \u309C;");
+assertDoesNotThrow("var \\u309C;");
+
+assertDoesNotThrow("var $\u00B7;");
+assertDoesNotThrow("var $\u0387;");
+assertDoesNotThrow("var $\u1369;");
+assertDoesNotThrow("var $\u1370;");
+assertDoesNotThrow("var $\u1371;");
+assertDoesNotThrow("var $\u19DA;");
diff --git a/test/mozilla/mozilla.status b/test/mozilla/mozilla.status
index e9f58c6..9ba07f7 100644
--- a/test/mozilla/mozilla.status
+++ b/test/mozilla/mozilla.status
@@ -117,6 +117,11 @@
   'js1_5/GC/regress-348532': [SKIP],
 
 
+  # Runs for too long: huge array with getters and setters. As it says
+  # in the test: "This test will probably run out of memory".
+  'js1_5/extensions/regress-345967': [SKIP],
+
+
   ##################### FLAKY TESTS #####################
 
   # These tests time out in debug mode but pass in product mode
@@ -216,7 +221,8 @@
 
   # Test that depends on timer resolution. Fails every now and then
   # if we're unlucky enough to get a context switch at a bad time.
-  'js1_5/extensions/regress-363258': [PASS, FAIL],
+  # TODO(mstarzinger): Switch off TF on windows due to timeouts.
+  'js1_5/extensions/regress-363258': [PASS, FAIL, ['system == windows', NO_VARIANTS]],
 
 
   # Test that assumes specific runtime for a regexp, flaky in debug mode.
@@ -273,21 +279,6 @@
   # RegExp flags.
   'ecma_3/RegExp/15.10.4.1-6': [FAIL_OK],
 
-  # PCRE doesn't allow subpattern nesting deeper than 200, this tests
-  # depth 500.  JSC detects the case, and return null from the match,
-  # and passes this test (the test doesn't check for a correct return
-  # value).
-  'ecma_3/RegExp/regress-119909': [PASS, FAIL_OK],
-
-
-  # Difference in the way capturing subpatterns work.  In JS, when the
-  # 'minimum repeat count' is reached, the empty string must not match.
-  # In this case, we are similar but not identical to JSC.  Hard to
-  # support the JS behavior with PCRE, so maybe emulate JSC?
-  'ecma_3/RegExp/regress-209919': [PASS, FAIL_OK],
-  'js1_5/extensions/regress-459606': [PASS, FAIL_OK],
-
-
   # PCRE's match limit is reached.  SpiderMonkey hangs on the first one,
   # JSC returns true somehow.  Maybe they up the match limit?  There is
   # an open V8 bug 676063 about this.
@@ -310,12 +301,12 @@
   'js1_5/Regress/regress-230216-2': [FAIL_OK],
 
 
-  # Regexp too long for PCRE.
-  'js1_5/Regress/regress-280769': [PASS, FAIL],
-  'js1_5/Regress/regress-280769-1': [PASS, FAIL],
-  'js1_5/Regress/regress-280769-2': [PASS, FAIL],
-  'js1_5/Regress/regress-280769-4': [PASS, FAIL],
-  'js1_5/Regress/regress-280769-5': [PASS, FAIL],
+  # BUG(v8:3767)
+  'js1_5/Regress/regress-280769-2': [PASS, ['arch == arm64', SKIP]],
+
+  # Regexps too big.
+  'js1_5/Regress/regress-280769-1': [SKIP],
+  'js1_5/Regress/regress-280769-5': [SKIP],
 
 
   # We do not support static RegExp.multiline - should we?.
@@ -361,9 +352,9 @@
 
 
   # No support for toSource().
-  'js1_5/Regress/regress-248444': [FAIL_OK],
   'js1_5/Regress/regress-313967-01': [FAIL_OK],
   'js1_5/Regress/regress-313967-02': [FAIL_OK],
+  'js1_5/extensions/regress-459606': [FAIL_OK],
 
   # This fails because we don't have stack space for Function.prototype.apply
   # with very large numbers of arguments.  The test uses 2^24 arguments.
@@ -567,11 +558,6 @@
   'js1_5/Regress/regress-336100': [FAIL_OK],
 
 
-  # Regular expression test failures due to PCRE. We match JSC (ie, perl)
-  # behavior and not the ECMA spec.
-  'ecma_3/RegExp/perlstress-001': [PASS, FAIL_OK],
-  'ecma_3/RegExp/regress-334158': [PASS, FAIL],
-
   # This test fails due to http://code.google.com/p/v8/issues/detail?id=187
   # Failure to clear captures when a lookahead is unwound.
   'ecma_3/RegExp/15.10.2-1': [PASS, FAIL_OK],
@@ -674,7 +660,6 @@
   'js1_5/extensions/regress-311792-01': [FAIL_OK],
   'js1_5/extensions/regress-312278': [FAIL_OK],
   'js1_5/extensions/regress-313630': [FAIL_OK],
-  'js1_5/extensions/regress-313763': [FAIL_OK],
   'js1_5/extensions/regress-313803': [FAIL_OK],
   'js1_5/extensions/regress-314874': [FAIL_OK],
   'js1_5/extensions/regress-322957': [FAIL_OK],
@@ -684,8 +669,6 @@
   'js1_5/extensions/regress-336409-1': [FAIL_OK],
   'js1_5/extensions/regress-336409-2': [FAIL_OK],
   'js1_5/extensions/regress-336410-2': [FAIL_OK],
-  'js1_5/extensions/regress-341956-01': [FAIL_OK],
-  'js1_5/extensions/regress-345967': [FAIL_OK],
   'js1_5/extensions/regress-346494-01': [FAIL_OK],
   'js1_5/extensions/regress-346494': [FAIL_OK],
   'js1_5/extensions/regress-347306-02': [FAIL_OK],
@@ -863,11 +846,10 @@
 
 
 ['arch ==  arm64', {
-  # BUG(v8:3152): Runs out of stack in debug mode.
-  'js1_5/extensions/regress-355497': [FAIL_OK, ['mode == debug', SKIP]],
-
   # BUG(v8:3503): Times out in debug mode.
   'js1_5/Regress/regress-280769-2': [PASS, FAIL, ['mode == debug', SKIP]],
+  # BUG(v8:3716): Flaky failure.
+  'ecma/Date/15.9.5.26-1': [PASS, FAIL],
 }],  # 'arch ==  arm64'
 
 
@@ -890,6 +872,10 @@
   'js1_5/GC/regress-203278-2': [PASS, TIMEOUT, NO_VARIANTS],
 }],  # 'arch == mipsel or arch == mips64el'
 
+['arch == mips64el and simulator_run == True', {
+  'js1_5/extensions/regress-355497': [FAIL_OK, 'Flags: --sim-stack-size=512'],
+}],
+
 ['arch == mips', {
 
   # BUG(3251229): Times out when running new crankshaft test script.
@@ -928,5 +914,8 @@
   'js1_5/extensions/regress-330569': [SKIP],
   'js1_5/extensions/regress-351448': [SKIP],
   'js1_5/extensions/regress-336410-1': [SKIP],
+
+  #BUG(3152): Avoid C stack overflow.
+  'js1_5/extensions/regress-355497': [FAIL_OK, 'Flags: --sim-stack-size=512'],
 }],  # 'arch == arm64 and simulator_run == True'
 ]
diff --git a/test/perf-test/Collections/Collections.json b/test/perf-test/Collections/Collections.json
deleted file mode 100644
index bf735c0..0000000
--- a/test/perf-test/Collections/Collections.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "path": ["."],
-  "main": "run.js",
-  "flags": ["--harmony-collections"],
-  "run_count": 5,
-  "units": "score",
-  "results_regexp": "^%s\\-Collections\\(Score\\): (.+)$",
-  "total": true,
-  "tests": [
-    {"name": "Map"},
-    {"name": "Set"},
-    {"name": "WeakMap"},
-    {"name": "WeakSet"}
-  ]
-}
diff --git a/test/perf-test/Collections/map.js b/test/perf-test/Collections/map.js
deleted file mode 100644
index b310a71..0000000
--- a/test/perf-test/Collections/map.js
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-var MapBenchmark = new BenchmarkSuite('Map', [1000], [
-  new Benchmark('Set', false, false, 0, MapSet),
-  new Benchmark('Has', false, false, 0, MapHas, MapSetup, MapTearDown),
-  new Benchmark('Get', false, false, 0, MapGet, MapSetup, MapTearDown),
-  new Benchmark('Delete', false, false, 0, MapDelete, MapSetup, MapTearDown),
-  new Benchmark('ForEach', false, false, 0, MapForEach, MapSetup, MapTearDown),
-]);
-
-
-var map;
-var N = 10;
-
-
-function MapSetup() {
-  map = new Map;
-  for (var i = 0; i < N; i++) {
-    map.set(i, i);
-  }
-}
-
-
-function MapTearDown() {
-  map = null;
-}
-
-
-function MapSet() {
-  MapSetup();
-  MapTearDown();
-}
-
-
-function MapHas() {
-  for (var i = 0; i < N; i++) {
-    if (!map.has(i)) {
-      throw new Error();
-    }
-  }
-  for (var i = N; i < 2 * N; i++) {
-    if (map.has(i)) {
-      throw new Error();
-    }
-  }
-}
-
-
-function MapGet() {
-  for (var i = 0; i < N; i++) {
-    if (map.get(i) !== i) {
-      throw new Error();
-    }
-  }
-  for (var i = N; i < 2 * N; i++) {
-    if (map.get(i) !== undefined) {
-      throw new Error();
-    }
-  }
-}
-
-
-function MapDelete() {
-  // This is run more than once per setup so we will end up deleting items
-  // more than once. Therefore, we do not the return value of delete.
-  for (var i = 0; i < N; i++) {
-    map.delete(i);
-  }
-}
-
-
-function MapForEach() {
-  map.forEach(function(v, k) {
-    if (v !== k) {
-      throw new Error();
-    }
-  });
-}
diff --git a/test/perf-test/Collections/run.js b/test/perf-test/Collections/run.js
deleted file mode 100644
index cfd1aef..0000000
--- a/test/perf-test/Collections/run.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-load('base.js');
-load('map.js');
-load('set.js');
-load('weakmap.js');
-load('weakset.js');
-
-
-var success = true;
-
-function PrintResult(name, result) {
-  print(name + '-Collections(Score): ' + result);
-}
-
-
-function PrintError(name, error) {
-  PrintResult(name, error);
-  success = false;
-}
-
-
-BenchmarkSuite.config.doWarmup = undefined;
-BenchmarkSuite.config.doDeterministic = undefined;
-
-BenchmarkSuite.RunSuites({ NotifyResult: PrintResult,
-                           NotifyError: PrintError });
diff --git a/test/perf-test/Collections/set.js b/test/perf-test/Collections/set.js
deleted file mode 100644
index e6455e1..0000000
--- a/test/perf-test/Collections/set.js
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-var SetBenchmark = new BenchmarkSuite('Set', [1000], [
-  new Benchmark('Add', false, false, 0, SetAdd),
-  new Benchmark('Has', false, false, 0, SetHas, SetSetup, SetTearDown),
-  new Benchmark('Delete', false, false, 0, SetDelete, SetSetup, SetTearDown),
-  new Benchmark('ForEach', false, false, 0, SetForEach, SetSetup, SetTearDown),
-]);
-
-
-var set;
-var N = 10;
-
-
-function SetSetup() {
-  set = new Set;
-  for (var i = 0; i < N; i++) {
-    set.add(i);
-  }
-}
-
-
-function SetTearDown() {
-  map = null;
-}
-
-
-function SetAdd() {
-  SetSetup();
-  SetTearDown();
-}
-
-
-function SetHas() {
-  for (var i = 0; i < N; i++) {
-    if (!set.has(i)) {
-      throw new Error();
-    }
-  }
-  for (var i = N; i < 2 * N; i++) {
-    if (set.has(i)) {
-      throw new Error();
-    }
-  }
-}
-
-
-function SetDelete() {
-  // This is run more than once per setup so we will end up deleting items
-  // more than once. Therefore, we do not the return value of delete.
-  for (var i = 0; i < N; i++) {
-    set.delete(i);
-  }
-}
-
-
-function SetForEach() {
-  set.forEach(function(v, k) {
-    if (v !== k) {
-      throw new Error();
-    }
-  });
-}
diff --git a/test/perf-test/Collections/weakmap.js b/test/perf-test/Collections/weakmap.js
deleted file mode 100644
index 8736dfd..0000000
--- a/test/perf-test/Collections/weakmap.js
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-var MapBenchmark = new BenchmarkSuite('WeakMap', [1000], [
-  new Benchmark('Set', false, false, 0, WeakMapSet),
-  new Benchmark('Has', false, false, 0, WeakMapHas, WeakMapSetup,
-      WeakMapTearDown),
-  new Benchmark('Get', false, false, 0, WeakMapGet, WeakMapSetup,
-      WeakMapTearDown),
-  new Benchmark('Delete', false, false, 0, WeakMapDelete, WeakMapSetup,
-      WeakMapTearDown),
-]);
-
-
-var wm;
-var N = 10;
-var keys = [];
-
-
-for (var i = 0; i < N * 2; i++) {
-  keys[i] = {};
-}
-
-
-function WeakMapSetup() {
-  wm = new WeakMap;
-  for (var i = 0; i < N; i++) {
-    wm.set(keys[i], i);
-  }
-}
-
-
-function WeakMapTearDown() {
-  wm = null;
-}
-
-
-function WeakMapSet() {
-  WeakMapSetup();
-  WeakMapTearDown();
-}
-
-
-function WeakMapHas() {
-  for (var i = 0; i < N; i++) {
-    if (!wm.has(keys[i])) {
-      throw new Error();
-    }
-  }
-  for (var i = N; i < 2 * N; i++) {
-    if (wm.has(keys[i])) {
-      throw new Error();
-    }
-  }
-}
-
-
-function WeakMapGet() {
-  for (var i = 0; i < N; i++) {
-    if (wm.get(keys[i]) !== i) {
-      throw new Error();
-    }
-  }
-  for (var i = N; i < 2 * N; i++) {
-    if (wm.get(keys[i]) !== undefined) {
-      throw new Error();
-    }
-  }
-}
-
-
-function WeakMapDelete() {
-  // This is run more than once per setup so we will end up deleting items
-  // more than once. Therefore, we do not the return value of delete.
-  for (var i = 0; i < N; i++) {
-    wm.delete(keys[i]);
-  }
-}
diff --git a/test/perf-test/Collections/weakset.js b/test/perf-test/Collections/weakset.js
deleted file mode 100644
index a7d0f3d..0000000
--- a/test/perf-test/Collections/weakset.js
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-var SetBenchmark = new BenchmarkSuite('WeakSet', [1000], [
-  new Benchmark('Add', false, false, 0, WeakSetAdd),
-  new Benchmark('Has', false, false, 0, WeakSetHas, WeakSetSetup,
-      WeakSetTearDown),
-  new Benchmark('Delete', false, false, 0, WeakSetDelete, WeakSetSetup,
-      WeakSetTearDown),
-]);
-
-
-var ws;
-var N = 10;
-var keys = [];
-
-
-for (var i = 0; i < N * 2; i++) {
-  keys[i] = {};
-}
-
-
-function WeakSetSetup() {
-  ws = new WeakSet;
-  for (var i = 0; i < N; i++) {
-    ws.add(keys[i]);
-  }
-}
-
-
-function WeakSetTearDown() {
-  ws = null;
-}
-
-
-function WeakSetAdd() {
-  WeakSetSetup();
-  WeakSetTearDown();
-}
-
-
-function WeakSetHas() {
-  for (var i = 0; i < N; i++) {
-    if (!ws.has(keys[i])) {
-      throw new Error();
-    }
-  }
-  for (var i = N; i < 2 * N; i++) {
-    if (ws.has(keys[i])) {
-      throw new Error();
-    }
-  }
-}
-
-
-function WeakSetDelete() {
-  // This is run more than once per setup so we will end up deleting items
-  // more than once. Therefore, we do not the return value of delete.
-  for (var i = 0; i < N; i++) {
-    ws.delete(keys[i]);
-  }
-}
diff --git a/test/preparser/strict-const.js b/test/preparser/strict-const.js
index 2b9230c..97b9081 100644
--- a/test/preparser/strict-const.js
+++ b/test/preparser/strict-const.js
@@ -24,6 +24,8 @@
 // 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: --noharmony-scoping
 
 "use strict";
 const x = 42;
diff --git a/test/preparser/strict-function-statement.pyt b/test/preparser/strict-function-statement.pyt
index 08c4288..cc3d7bb 100644
--- a/test/preparser/strict-function-statement.pyt
+++ b/test/preparser/strict-function-statement.pyt
@@ -29,71 +29,81 @@
 
 # A template that performs the same strict-mode test in different
 # scopes (global scope, function scope, and nested function scope).
-def StrictTest(name, source):
-  Test(name, '"use strict";\n' + source, "strict_function")
+def StrictTest(name, source, legacy):
+  if legacy:
+    extra_flags = [
+      "--noharmony-scoping",
+      "--noharmony-classes",
+      "--noharmony-object-literals"]
+  else:
+    extra_flags = []
+  Test(name, '"use strict";\n' + source, "strict_function",
+       extra_flags)
   Test(name + '-infunc',
        'function foo() {\n "use strict";\n' + source +'\n}\n',
-       "strict_function")
+       "strict_function", 
+       extra_flags)
   Test(name + '-infunc2',
        'function foo() {\n "use strict";\n  function bar() {\n' +
        source +'\n }\n}\n',
-       "strict_function")
+       "strict_function",
+       extra_flags)
 
 # Not testing with-scope, since with is not allowed in strict mode at all.
 
 StrictTest("block", """
   { function foo() { } }
-""")
+""", True)
 
 StrictTest("try-w-catch", """
   try { function foo() { } } catch (e) { }
-""")
+""", True)
 
 StrictTest("try-w-finally", """
   try { function foo() { } } finally { }
-""")
+""", True)
 
 StrictTest("catch", """
   try { } catch (e) { function foo() { } }
-""")
+""", True)
 
 StrictTest("finally", """
   try { } finally { function foo() { } }
-""")
+""", True)
 
 StrictTest("for", """
   for (;;) { function foo() { } }
-""")
+""", True)
 
 StrictTest("while", """
   while (true) { function foo() { } }
-""")
+""", True)
 
 StrictTest("do", """
   do { function foo() { } } while (true);
-""")
+""", True)
 
 StrictTest("then", """
   if (true) { function foo() { } }
-""")
+""", True)
 
 
 StrictTest("then-w-else", """
   if (true) { function foo() { } } else { }
-""")
+""", True)
 
 
 StrictTest("else", """
   if (true) { } else { function foo() { } }
-""")
+""", True)
 
 StrictTest("switch-case", """
   switch (true) { case true: function foo() { } }
-""")
+""", False)
 
 StrictTest("labeled", """
   label: function foo() { }
-""")
+""", False)
 
 
 
diff --git a/test/preparser/testcfg.py b/test/preparser/testcfg.py
index 850c0a4..ddd311c 100644
--- a/test/preparser/testcfg.py
+++ b/test/preparser/testcfg.py
@@ -34,6 +34,10 @@
 from testrunner.objects import testcase
 
 
+FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
+INVALID_FLAGS = ["--enable-slow-asserts"]
+
+
 class PreparserTestSuite(testsuite.TestSuite):
   def __init__(self, name, root):
     super(PreparserTestSuite, self).__init__(name, root)
@@ -59,12 +63,13 @@
 
   def _ParsePythonTestTemplates(self, result, filename):
     pathname = os.path.join(self.root, filename + ".pyt")
-    def Test(name, source, expectation):
+    def Test(name, source, expectation, extra_flags=[]):
       source = source.replace("\n", " ")
       testname = os.path.join(filename, name)
       flags = ["-e", source]
       if expectation:
         flags += ["--throws"]
+      flags += extra_flags
       test = testcase.TestCase(self, testname, flags=flags)
       result.append(test)
     def Template(name, source):
@@ -104,6 +109,15 @@
     first = testcase.flags[0]
     if first != "-e":
       testcase.flags[0] = os.path.join(self.root, first)
+      source = self.GetSourceForTest(testcase)
+      result = []
+      flags_match = re.findall(FLAGS_PATTERN, source)
+      for match in flags_match:
+        result += match.strip().split()
+      result += context.mode_flags
+      result = [x for x in result if x not in INVALID_FLAGS]
+      result.append(os.path.join(self.root, testcase.path + ".js"))
+      return testcase.flags + result
     return testcase.flags
 
   def GetSourceForTest(self, testcase):
diff --git a/test/test262-es6/README b/test/test262-es6/README
index d0b3b42..86fa0dc 100644
--- a/test/test262-es6/README
+++ b/test/test262-es6/README
@@ -4,13 +4,13 @@
 
   https://github.com/tc39/test262
 
-at hash 9bd6686 (2014/08/25 revision) as 'data' in this directory.  Using later
+at hash 61113db (2014/10/23 revision) 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.
 
   git clone https://github.com/tc39/test262 data
   cd data
-  git checkout 9bd6686
+  git checkout 61113db
 
 If you do update to a newer revision you may have to change the test
 harness adapter code since it uses internal functionality from the
diff --git a/test/test262-es6/test262-es6.status b/test/test262-es6/test262-es6.status
index c4c94f3..8662159 100644
--- a/test/test262-es6/test262-es6.status
+++ b/test/test262-es6/test262-es6.status
@@ -29,12 +29,13 @@
 [ALWAYS, {
   ############################### BUGS ###################################
 
-  '15.5.4.9_CE': [['no_i18n', SKIP]],
-
   # BUG(v8:3455)
   '11.2.3_b': [FAIL],
   '12.2.3_b': [FAIL],
 
+  # Unicode canonicalization is not available with i18n turned off.
+  '15.5.4.9_CE': [['no_i18n', SKIP]],
+
   ###################### NEEDS INVESTIGATION #######################
 
   # Possibly same cause as S8.5_A2.1, below: floating-point tests.
@@ -49,6 +50,25 @@
 
   ###################### MISSING ES6 FEATURES #######################
 
+  # Array.fill (currently requires --harmony-arrays)
+  'S22.1.3.6_T1': [FAIL],
+
+  # Array.find (currently requires --harmony-arrays)
+  'S22.1.2.3_T1': [FAIL],
+  'S22.1.2.3_T2': [FAIL],
+  'Array.prototype.find_empty-array-undefined': [FAIL],
+  'Array.prototype.find_length-property': [FAIL],
+  'Array.prototype.find_modify-after-start': [FAIL],
+  'Array.prototype.find_non-returning-predicate': [FAIL],
+  'Array.prototype.find_predicate-arguments': [FAIL],
+  'Array.prototype.find_push-after-start': [FAIL],
+  'Array.prototype.find_remove-after-start': [FAIL],
+  'Array.prototype.find_return-found-value': [FAIL],
+  'Array.prototype.find_skip-empty': [FAIL],
+  'Array.prototype.find_this-defined': [FAIL],
+  'Array.prototype.find_this-is-object': [FAIL],
+  'Array.prototype.find_this-undefined': [FAIL],
+
   # Array.from
   'S22.1.2.1_T1': [FAIL],
   'S22.1.2.1_T2': [FAIL],
@@ -70,6 +90,11 @@
   # '11.1.5_4-4-d-3': [FAIL],
   # '11.1.5_4-4-d-4': [FAIL],
 
+  # ES6 does ToObject for Object.prototype.getOwnPropertyNames
+  '15.2.3.4-1': [FAIL],
+  '15.2.3.4-1-4': [FAIL],
+  '15.2.3.4-1-5': [FAIL],
+
   # ES6 allows block-local functions.
   'Sbp_A1_T1': [FAIL],
   'Sbp_A2_T1': [FAIL],
@@ -137,6 +162,20 @@
   # Test262 Bug: https://bugs.ecmascript.org/show_bug.cgi?id=596
   'bug_596_1': [PASS, FAIL_OK],
 
+  # Tests do not return boolean.
+  '15.2.3.14-1-1': [PASS, FAIL_OK],
+  '15.2.3.14-1-2': [PASS, FAIL_OK],
+  '15.2.3.14-1-3': [PASS, FAIL_OK],
+
+  # String.prototype.contains renamed to 'S.p.includes'
+  'String.prototype.contains_FailBadLocation' : [FAIL_OK],
+  'String.prototype.contains_FailLocation' : [FAIL_OK],
+  'String.prototype.contains_FailMissingLetter' : [FAIL_OK],
+  'String.prototype.contains_lengthProp' : [FAIL_OK],
+  'String.prototype.contains_Success' : [FAIL_OK],
+  'String.prototype.contains_SuccessNoLocation' : [FAIL_OK],
+
+
   ############################ SKIPPED TESTS #############################
 
   # These tests take a looong time to run in debug mode.
diff --git a/test/test262-es6/testcfg.py b/test/test262-es6/testcfg.py
index 59eda32..0a89410 100644
--- a/test/test262-es6/testcfg.py
+++ b/test/test262-es6/testcfg.py
@@ -37,8 +37,8 @@
 from testrunner.local import utils
 from testrunner.objects import testcase
 
-TEST_262_ARCHIVE_REVISION = "9bd6686"  # This is the 2014-08-25 revision.
-TEST_262_ARCHIVE_MD5 = "0f5928b391864890d5a397f8cdc82705"
+TEST_262_ARCHIVE_REVISION = "61113db"  # This is the 2014-10-23 revision.
+TEST_262_ARCHIVE_MD5 = "261e69b4a97a4bfc18225cf3938daf50"
 TEST_262_URL = "https://github.com/tc39/test262/tarball/%s"
 TEST_262_HARNESS_FILES = ["sta.js"]
 
@@ -147,9 +147,11 @@
       with open(archive_name, "rb") as f:
         for chunk in iter(lambda: f.read(8192), ""):
           md5.update(chunk)
+      print "MD5 hash is %s" % md5.hexdigest()
       if md5.hexdigest() != TEST_262_ARCHIVE_MD5:
         os.remove(archive_name)
-        raise Exception("Hash mismatch of test data file")
+        print "MD5 expected %s" % TEST_262_ARCHIVE_MD5
+        raise Exception("MD5 hash mismatch of test data file")
       archive = tarfile.open(archive_name, "r:gz")
       if sys.platform in ("win32", "cygwin"):
         # Magic incantation to allow longer path names on Windows.
diff --git a/test/test262/test262.status b/test/test262/test262.status
index 8666313..d32f8f3 100644
--- a/test/test262/test262.status
+++ b/test/test262/test262.status
@@ -35,6 +35,22 @@
   '11.2.3_b': [FAIL],
   '12.2.3_b': [FAIL],
 
+  ############################### ES6 ###################################
+  # ES6 allows block-local functions.
+  'Sbp_A1_T1': [PASS, FAIL_OK],
+  'Sbp_A2_T1': [PASS, FAIL_OK],
+  'Sbp_A2_T2': [PASS, FAIL_OK],
+  'Sbp_A3_T1': [PASS, FAIL_OK],
+  'Sbp_A3_T2': [PASS, FAIL_OK],
+  'Sbp_A4_T1': [PASS, FAIL_OK],
+  'Sbp_A4_T2': [PASS, FAIL_OK],
+  'Sbp_A5_T1': [PASS], # Test is broken (strict reference to unbound variable)
+  'Sbp_A5_T2': [PASS, FAIL_OK],
+
+  # Passes in ES6 since {__arr} syntax is parsed as object literal.
+  'S12.1_A4_T2': [PASS, FAIL_OK],
+  'S12.6.4_A15': [PASS, FAIL_OK],
+
   ######################## NEEDS INVESTIGATION ###########################
 
   # These test failures are specific to the intl402 suite and need investigation
@@ -87,6 +103,17 @@
   'S15.9.3.1_A5_T5': [PASS, FAIL_OK],
   'S15.9.3.1_A5_T6': [PASS, FAIL_OK],
 
+  # ObjectKeys() no longer throws TypeError when passed a primitive value which
+  # is not null or undefined (per ES6).
+  '15.2.3.14-1-1': [FAIL_OK],
+  '15.2.3.14-1-2': [FAIL_OK],
+  '15.2.3.14-1-3': [FAIL_OK],
+
+  # Object.getOwnPropertyNames(O) no longer throws when passed a primitive value.
+  '15.2.3.4-1-4': [FAIL_OK],
+  '15.2.3.4-1-5': [FAIL_OK],
+  '15.2.3.4-1': [FAIL_OK],
+
   ############################ SKIPPED TESTS #############################
 
   # These tests take a looong time to run in debug mode.
diff --git a/test/unittests/DEPS b/test/unittests/DEPS
new file mode 100644
index 0000000..4df37f8
--- /dev/null
+++ b/test/unittests/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+  "+src",
+  "+testing"
+]
diff --git a/test/unittests/base/bits-unittest.cc b/test/unittests/base/bits-unittest.cc
new file mode 100644
index 0000000..9caba84
--- /dev/null
+++ b/test/unittests/base/bits-unittest.cc
@@ -0,0 +1,281 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <limits>
+
+#include "src/base/bits.h"
+#include "src/base/macros.h"
+#include "testing/gtest-support.h"
+
+#ifdef DEBUG
+#define DISABLE_IN_RELEASE(Name) Name
+#else
+#define DISABLE_IN_RELEASE(Name) DISABLED_##Name
+#endif
+
+namespace v8 {
+namespace base {
+namespace bits {
+
+TEST(Bits, CountPopulation32) {
+  EXPECT_EQ(0u, CountPopulation32(0));
+  EXPECT_EQ(1u, CountPopulation32(1));
+  EXPECT_EQ(8u, CountPopulation32(0x11111111));
+  EXPECT_EQ(16u, CountPopulation32(0xf0f0f0f0));
+  EXPECT_EQ(24u, CountPopulation32(0xfff0f0ff));
+  EXPECT_EQ(32u, CountPopulation32(0xffffffff));
+}
+
+
+TEST(Bits, CountPopulation64) {
+  EXPECT_EQ(0u, CountPopulation64(0));
+  EXPECT_EQ(1u, CountPopulation64(1));
+  EXPECT_EQ(2u, CountPopulation64(0x8000000000000001));
+  EXPECT_EQ(8u, CountPopulation64(0x11111111));
+  EXPECT_EQ(16u, CountPopulation64(0xf0f0f0f0));
+  EXPECT_EQ(24u, CountPopulation64(0xfff0f0ff));
+  EXPECT_EQ(32u, CountPopulation64(0xffffffff));
+  EXPECT_EQ(16u, CountPopulation64(0x1111111111111111));
+  EXPECT_EQ(32u, CountPopulation64(0xf0f0f0f0f0f0f0f0));
+  EXPECT_EQ(48u, CountPopulation64(0xfff0f0fffff0f0ff));
+  EXPECT_EQ(64u, CountPopulation64(0xffffffffffffffff));
+}
+
+
+TEST(Bits, CountLeadingZeros32) {
+  EXPECT_EQ(32u, CountLeadingZeros32(0));
+  EXPECT_EQ(31u, CountLeadingZeros32(1));
+  TRACED_FORRANGE(uint32_t, shift, 0, 31) {
+    EXPECT_EQ(31u - shift, CountLeadingZeros32(1u << shift));
+  }
+  EXPECT_EQ(4u, CountLeadingZeros32(0x0f0f0f0f));
+}
+
+
+TEST(Bits, CountLeadingZeros64) {
+  EXPECT_EQ(64u, CountLeadingZeros64(0));
+  EXPECT_EQ(63u, CountLeadingZeros64(1));
+  TRACED_FORRANGE(uint32_t, shift, 0, 63) {
+    EXPECT_EQ(63u - shift, CountLeadingZeros64(V8_UINT64_C(1) << shift));
+  }
+  EXPECT_EQ(36u, CountLeadingZeros64(0x0f0f0f0f));
+  EXPECT_EQ(4u, CountLeadingZeros64(0x0f0f0f0f00000000));
+}
+
+
+TEST(Bits, CountTrailingZeros32) {
+  EXPECT_EQ(32u, CountTrailingZeros32(0));
+  EXPECT_EQ(31u, CountTrailingZeros32(0x80000000));
+  TRACED_FORRANGE(uint32_t, shift, 0, 31) {
+    EXPECT_EQ(shift, CountTrailingZeros32(1u << shift));
+  }
+  EXPECT_EQ(4u, CountTrailingZeros32(0xf0f0f0f0));
+}
+
+
+TEST(Bits, CountTrailingZeros64) {
+  EXPECT_EQ(64u, CountTrailingZeros64(0));
+  EXPECT_EQ(63u, CountTrailingZeros64(0x8000000000000000));
+  TRACED_FORRANGE(uint32_t, shift, 0, 63) {
+    EXPECT_EQ(shift, CountTrailingZeros64(V8_UINT64_C(1) << shift));
+  }
+  EXPECT_EQ(4u, CountTrailingZeros64(0xf0f0f0f0));
+  EXPECT_EQ(36u, CountTrailingZeros64(0xf0f0f0f000000000));
+}
+
+
+TEST(Bits, IsPowerOfTwo32) {
+  EXPECT_FALSE(IsPowerOfTwo32(0U));
+  TRACED_FORRANGE(uint32_t, shift, 0, 31) {
+    EXPECT_TRUE(IsPowerOfTwo32(1U << shift));
+    EXPECT_FALSE(IsPowerOfTwo32((1U << shift) + 5U));
+    EXPECT_FALSE(IsPowerOfTwo32(~(1U << shift)));
+  }
+  TRACED_FORRANGE(uint32_t, shift, 2, 31) {
+    EXPECT_FALSE(IsPowerOfTwo32((1U << shift) - 1U));
+  }
+  EXPECT_FALSE(IsPowerOfTwo32(0xffffffff));
+}
+
+
+TEST(Bits, IsPowerOfTwo64) {
+  EXPECT_FALSE(IsPowerOfTwo64(0U));
+  TRACED_FORRANGE(uint32_t, shift, 0, 63) {
+    EXPECT_TRUE(IsPowerOfTwo64(V8_UINT64_C(1) << shift));
+    EXPECT_FALSE(IsPowerOfTwo64((V8_UINT64_C(1) << shift) + 5U));
+    EXPECT_FALSE(IsPowerOfTwo64(~(V8_UINT64_C(1) << shift)));
+  }
+  TRACED_FORRANGE(uint32_t, shift, 2, 63) {
+    EXPECT_FALSE(IsPowerOfTwo64((V8_UINT64_C(1) << shift) - 1U));
+  }
+  EXPECT_FALSE(IsPowerOfTwo64(V8_UINT64_C(0xffffffffffffffff)));
+}
+
+
+TEST(Bits, RoundUpToPowerOfTwo32) {
+  TRACED_FORRANGE(uint32_t, shift, 0, 31) {
+    EXPECT_EQ(1u << shift, RoundUpToPowerOfTwo32(1u << shift));
+  }
+  EXPECT_EQ(0u, RoundUpToPowerOfTwo32(0));
+  EXPECT_EQ(4u, RoundUpToPowerOfTwo32(3));
+  EXPECT_EQ(0x80000000u, RoundUpToPowerOfTwo32(0x7fffffffu));
+}
+
+
+TEST(BitsDeathTest, DISABLE_IN_RELEASE(RoundUpToPowerOfTwo32)) {
+  ASSERT_DEATH_IF_SUPPORTED({ RoundUpToPowerOfTwo32(0x80000001u); },
+                            "0x80000000");
+}
+
+
+TEST(Bits, RoundDownToPowerOfTwo32) {
+  TRACED_FORRANGE(uint32_t, shift, 0, 31) {
+    EXPECT_EQ(1u << shift, RoundDownToPowerOfTwo32(1u << shift));
+  }
+  EXPECT_EQ(0u, RoundDownToPowerOfTwo32(0));
+  EXPECT_EQ(4u, RoundDownToPowerOfTwo32(5));
+  EXPECT_EQ(0x80000000u, RoundDownToPowerOfTwo32(0x80000001u));
+}
+
+
+TEST(Bits, RotateRight32) {
+  TRACED_FORRANGE(uint32_t, shift, 0, 31) {
+    EXPECT_EQ(0u, RotateRight32(0u, shift));
+  }
+  EXPECT_EQ(1u, RotateRight32(1, 0));
+  EXPECT_EQ(1u, RotateRight32(2, 1));
+  EXPECT_EQ(0x80000000u, RotateRight32(1, 1));
+}
+
+
+TEST(Bits, RotateRight64) {
+  TRACED_FORRANGE(uint64_t, shift, 0, 63) {
+    EXPECT_EQ(0u, RotateRight64(0u, shift));
+  }
+  EXPECT_EQ(1u, RotateRight64(1, 0));
+  EXPECT_EQ(1u, RotateRight64(2, 1));
+  EXPECT_EQ(V8_UINT64_C(0x8000000000000000), RotateRight64(1, 1));
+}
+
+
+TEST(Bits, SignedAddOverflow32) {
+  int32_t val = 0;
+  EXPECT_FALSE(SignedAddOverflow32(0, 0, &val));
+  EXPECT_EQ(0, val);
+  EXPECT_TRUE(
+      SignedAddOverflow32(std::numeric_limits<int32_t>::max(), 1, &val));
+  EXPECT_EQ(std::numeric_limits<int32_t>::min(), val);
+  EXPECT_TRUE(
+      SignedAddOverflow32(std::numeric_limits<int32_t>::min(), -1, &val));
+  EXPECT_EQ(std::numeric_limits<int32_t>::max(), val);
+  EXPECT_TRUE(SignedAddOverflow32(std::numeric_limits<int32_t>::max(),
+                                  std::numeric_limits<int32_t>::max(), &val));
+  EXPECT_EQ(-2, val);
+  TRACED_FORRANGE(int32_t, i, 1, 50) {
+    TRACED_FORRANGE(int32_t, j, 1, i) {
+      EXPECT_FALSE(SignedAddOverflow32(i, j, &val));
+      EXPECT_EQ(i + j, val);
+    }
+  }
+}
+
+
+TEST(Bits, SignedSubOverflow32) {
+  int32_t val = 0;
+  EXPECT_FALSE(SignedSubOverflow32(0, 0, &val));
+  EXPECT_EQ(0, val);
+  EXPECT_TRUE(
+      SignedSubOverflow32(std::numeric_limits<int32_t>::min(), 1, &val));
+  EXPECT_EQ(std::numeric_limits<int32_t>::max(), val);
+  EXPECT_TRUE(
+      SignedSubOverflow32(std::numeric_limits<int32_t>::max(), -1, &val));
+  EXPECT_EQ(std::numeric_limits<int32_t>::min(), val);
+  TRACED_FORRANGE(int32_t, i, 1, 50) {
+    TRACED_FORRANGE(int32_t, j, 1, i) {
+      EXPECT_FALSE(SignedSubOverflow32(i, j, &val));
+      EXPECT_EQ(i - j, val);
+    }
+  }
+}
+
+
+TEST(Bits, SignedMulHigh32) {
+  EXPECT_EQ(0, SignedMulHigh32(0, 0));
+  TRACED_FORRANGE(int32_t, i, 1, 50) {
+    TRACED_FORRANGE(int32_t, j, 1, i) { EXPECT_EQ(0, SignedMulHigh32(i, j)); }
+  }
+  EXPECT_EQ(-1073741824, SignedMulHigh32(std::numeric_limits<int32_t>::max(),
+                                         std::numeric_limits<int32_t>::min()));
+  EXPECT_EQ(-1073741824, SignedMulHigh32(std::numeric_limits<int32_t>::min(),
+                                         std::numeric_limits<int32_t>::max()));
+  EXPECT_EQ(1, SignedMulHigh32(1024 * 1024 * 1024, 4));
+  EXPECT_EQ(2, SignedMulHigh32(8 * 1024, 1024 * 1024));
+}
+
+
+TEST(Bits, SignedMulHighAndAdd32) {
+  TRACED_FORRANGE(int32_t, i, 1, 50) {
+    EXPECT_EQ(i, SignedMulHighAndAdd32(0, 0, i));
+    TRACED_FORRANGE(int32_t, j, 1, i) {
+      EXPECT_EQ(i, SignedMulHighAndAdd32(j, j, i));
+    }
+    EXPECT_EQ(i + 1, SignedMulHighAndAdd32(1024 * 1024 * 1024, 4, i));
+  }
+}
+
+
+TEST(Bits, SignedDiv32) {
+  EXPECT_EQ(std::numeric_limits<int32_t>::min(),
+            SignedDiv32(std::numeric_limits<int32_t>::min(), -1));
+  EXPECT_EQ(std::numeric_limits<int32_t>::max(),
+            SignedDiv32(std::numeric_limits<int32_t>::max(), 1));
+  TRACED_FORRANGE(int32_t, i, 0, 50) {
+    EXPECT_EQ(0, SignedDiv32(i, 0));
+    TRACED_FORRANGE(int32_t, j, 1, i) {
+      EXPECT_EQ(1, SignedDiv32(j, j));
+      EXPECT_EQ(i / j, SignedDiv32(i, j));
+      EXPECT_EQ(-i / j, SignedDiv32(i, -j));
+    }
+  }
+}
+
+
+TEST(Bits, SignedMod32) {
+  EXPECT_EQ(0, SignedMod32(std::numeric_limits<int32_t>::min(), -1));
+  EXPECT_EQ(0, SignedMod32(std::numeric_limits<int32_t>::max(), 1));
+  TRACED_FORRANGE(int32_t, i, 0, 50) {
+    EXPECT_EQ(0, SignedMod32(i, 0));
+    TRACED_FORRANGE(int32_t, j, 1, i) {
+      EXPECT_EQ(0, SignedMod32(j, j));
+      EXPECT_EQ(i % j, SignedMod32(i, j));
+      EXPECT_EQ(i % j, SignedMod32(i, -j));
+    }
+  }
+}
+
+
+TEST(Bits, UnsignedDiv32) {
+  TRACED_FORRANGE(uint32_t, i, 0, 50) {
+    EXPECT_EQ(0u, UnsignedDiv32(i, 0));
+    TRACED_FORRANGE(uint32_t, j, i + 1, 100) {
+      EXPECT_EQ(1u, UnsignedDiv32(j, j));
+      EXPECT_EQ(i / j, UnsignedDiv32(i, j));
+    }
+  }
+}
+
+
+TEST(Bits, UnsignedMod32) {
+  TRACED_FORRANGE(uint32_t, i, 0, 50) {
+    EXPECT_EQ(0u, UnsignedMod32(i, 0));
+    TRACED_FORRANGE(uint32_t, j, i + 1, 100) {
+      EXPECT_EQ(0u, UnsignedMod32(j, j));
+      EXPECT_EQ(i % j, UnsignedMod32(i, j));
+    }
+  }
+}
+
+}  // namespace bits
+}  // namespace base
+}  // namespace v8
diff --git a/src/base/cpu-unittest.cc b/test/unittests/base/cpu-unittest.cc
similarity index 100%
rename from src/base/cpu-unittest.cc
rename to test/unittests/base/cpu-unittest.cc
diff --git a/test/unittests/base/division-by-constant-unittest.cc b/test/unittests/base/division-by-constant-unittest.cc
new file mode 100644
index 0000000..58816db
--- /dev/null
+++ b/test/unittests/base/division-by-constant-unittest.cc
@@ -0,0 +1,134 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Check all examples from table 10-1 of "Hacker's Delight".
+
+#include "src/base/division-by-constant.h"
+
+#include <stdint.h>
+
+#include <ostream>  // NOLINT
+
+#include "testing/gtest-support.h"
+
+namespace v8 {
+namespace base {
+
+template <class T>
+std::ostream& operator<<(std::ostream& os,
+                         const MagicNumbersForDivision<T>& mag) {
+  return os << "{ multiplier: " << mag.multiplier << ", shift: " << mag.shift
+            << ", add: " << mag.add << " }";
+}
+
+
+// Some abbreviations...
+
+typedef MagicNumbersForDivision<uint32_t> M32;
+typedef MagicNumbersForDivision<uint64_t> M64;
+
+
+static M32 s32(int32_t d) {
+  return SignedDivisionByConstant<uint32_t>(static_cast<uint32_t>(d));
+}
+
+
+static M64 s64(int64_t d) {
+  return SignedDivisionByConstant<uint64_t>(static_cast<uint64_t>(d));
+}
+
+
+static M32 u32(uint32_t d) { return UnsignedDivisionByConstant<uint32_t>(d); }
+static M64 u64(uint64_t d) { return UnsignedDivisionByConstant<uint64_t>(d); }
+
+
+TEST(DivisionByConstant, Signed32) {
+  EXPECT_EQ(M32(0x99999999U, 1, false), s32(-5));
+  EXPECT_EQ(M32(0x55555555U, 1, false), s32(-3));
+  int32_t d = -1;
+  for (unsigned k = 1; k <= 32 - 1; ++k) {
+    d *= 2;
+    EXPECT_EQ(M32(0x7FFFFFFFU, k - 1, false), s32(d));
+  }
+  for (unsigned k = 1; k <= 32 - 2; ++k) {
+    EXPECT_EQ(M32(0x80000001U, k - 1, false), s32(1 << k));
+  }
+  EXPECT_EQ(M32(0x55555556U, 0, false), s32(3));
+  EXPECT_EQ(M32(0x66666667U, 1, false), s32(5));
+  EXPECT_EQ(M32(0x2AAAAAABU, 0, false), s32(6));
+  EXPECT_EQ(M32(0x92492493U, 2, false), s32(7));
+  EXPECT_EQ(M32(0x38E38E39U, 1, false), s32(9));
+  EXPECT_EQ(M32(0x66666667U, 2, false), s32(10));
+  EXPECT_EQ(M32(0x2E8BA2E9U, 1, false), s32(11));
+  EXPECT_EQ(M32(0x2AAAAAABU, 1, false), s32(12));
+  EXPECT_EQ(M32(0x51EB851FU, 3, false), s32(25));
+  EXPECT_EQ(M32(0x10624DD3U, 3, false), s32(125));
+  EXPECT_EQ(M32(0x68DB8BADU, 8, false), s32(625));
+}
+
+
+TEST(DivisionByConstant, Unsigned32) {
+  EXPECT_EQ(M32(0x00000000U, 0, true), u32(1));
+  for (unsigned k = 1; k <= 30; ++k) {
+    EXPECT_EQ(M32(1U << (32 - k), 0, false), u32(1U << k));
+  }
+  EXPECT_EQ(M32(0xAAAAAAABU, 1, false), u32(3));
+  EXPECT_EQ(M32(0xCCCCCCCDU, 2, false), u32(5));
+  EXPECT_EQ(M32(0xAAAAAAABU, 2, false), u32(6));
+  EXPECT_EQ(M32(0x24924925U, 3, true), u32(7));
+  EXPECT_EQ(M32(0x38E38E39U, 1, false), u32(9));
+  EXPECT_EQ(M32(0xCCCCCCCDU, 3, false), u32(10));
+  EXPECT_EQ(M32(0xBA2E8BA3U, 3, false), u32(11));
+  EXPECT_EQ(M32(0xAAAAAAABU, 3, false), u32(12));
+  EXPECT_EQ(M32(0x51EB851FU, 3, false), u32(25));
+  EXPECT_EQ(M32(0x10624DD3U, 3, false), u32(125));
+  EXPECT_EQ(M32(0xD1B71759U, 9, false), u32(625));
+}
+
+
+TEST(DivisionByConstant, Signed64) {
+  EXPECT_EQ(M64(0x9999999999999999ULL, 1, false), s64(-5));
+  EXPECT_EQ(M64(0x5555555555555555ULL, 1, false), s64(-3));
+  int64_t d = -1;
+  for (unsigned k = 1; k <= 64 - 1; ++k) {
+    d *= 2;
+    EXPECT_EQ(M64(0x7FFFFFFFFFFFFFFFULL, k - 1, false), s64(d));
+  }
+  for (unsigned k = 1; k <= 64 - 2; ++k) {
+    EXPECT_EQ(M64(0x8000000000000001ULL, k - 1, false), s64(1LL << k));
+  }
+  EXPECT_EQ(M64(0x5555555555555556ULL, 0, false), s64(3));
+  EXPECT_EQ(M64(0x6666666666666667ULL, 1, false), s64(5));
+  EXPECT_EQ(M64(0x2AAAAAAAAAAAAAABULL, 0, false), s64(6));
+  EXPECT_EQ(M64(0x4924924924924925ULL, 1, false), s64(7));
+  EXPECT_EQ(M64(0x1C71C71C71C71C72ULL, 0, false), s64(9));
+  EXPECT_EQ(M64(0x6666666666666667ULL, 2, false), s64(10));
+  EXPECT_EQ(M64(0x2E8BA2E8BA2E8BA3ULL, 1, false), s64(11));
+  EXPECT_EQ(M64(0x2AAAAAAAAAAAAAABULL, 1, false), s64(12));
+  EXPECT_EQ(M64(0xA3D70A3D70A3D70BULL, 4, false), s64(25));
+  EXPECT_EQ(M64(0x20C49BA5E353F7CFULL, 4, false), s64(125));
+  EXPECT_EQ(M64(0x346DC5D63886594BULL, 7, false), s64(625));
+}
+
+
+TEST(DivisionByConstant, Unsigned64) {
+  EXPECT_EQ(M64(0x0000000000000000ULL, 0, true), u64(1));
+  for (unsigned k = 1; k <= 64 - 2; ++k) {
+    EXPECT_EQ(M64(1ULL << (64 - k), 0, false), u64(1ULL << k));
+  }
+  EXPECT_EQ(M64(0xAAAAAAAAAAAAAAABULL, 1, false), u64(3));
+  EXPECT_EQ(M64(0xCCCCCCCCCCCCCCCDULL, 2, false), u64(5));
+  EXPECT_EQ(M64(0xAAAAAAAAAAAAAAABULL, 2, false), u64(6));
+  EXPECT_EQ(M64(0x2492492492492493ULL, 3, true), u64(7));
+  EXPECT_EQ(M64(0xE38E38E38E38E38FULL, 3, false), u64(9));
+  EXPECT_EQ(M64(0xCCCCCCCCCCCCCCCDULL, 3, false), u64(10));
+  EXPECT_EQ(M64(0x2E8BA2E8BA2E8BA3ULL, 1, false), u64(11));
+  EXPECT_EQ(M64(0xAAAAAAAAAAAAAAABULL, 3, false), u64(12));
+  EXPECT_EQ(M64(0x47AE147AE147AE15ULL, 5, true), u64(25));
+  EXPECT_EQ(M64(0x0624DD2F1A9FBE77ULL, 7, true), u64(125));
+  EXPECT_EQ(M64(0x346DC5D63886594BULL, 7, false), u64(625));
+}
+
+}  // namespace base
+}  // namespace v8
diff --git a/test/unittests/base/flags-unittest.cc b/test/unittests/base/flags-unittest.cc
new file mode 100644
index 0000000..6f19399
--- /dev/null
+++ b/test/unittests/base/flags-unittest.cc
@@ -0,0 +1,104 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+#include "src/base/flags.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace base {
+
+namespace {
+
+enum Flag1 {
+  kFlag1None = 0,
+  kFlag1First = 1u << 1,
+  kFlag1Second = 1u << 2,
+  kFlag1All = kFlag1None | kFlag1First | kFlag1Second
+};
+typedef Flags<Flag1> Flags1;
+
+
+DEFINE_OPERATORS_FOR_FLAGS(Flags1)
+
+
+Flags1 bar(Flags1 flags1) { return flags1; }
+
+}  // namespace
+
+
+TEST(FlagsTest, BasicOperations) {
+  Flags1 a;
+  EXPECT_EQ(kFlag1None, static_cast<int>(a));
+  a |= kFlag1First;
+  EXPECT_EQ(kFlag1First, static_cast<int>(a));
+  a = a | kFlag1Second;
+  EXPECT_EQ(kFlag1All, static_cast<int>(a));
+  a &= kFlag1Second;
+  EXPECT_EQ(kFlag1Second, static_cast<int>(a));
+  a = kFlag1None & a;
+  EXPECT_EQ(kFlag1None, static_cast<int>(a));
+  a ^= (kFlag1All | kFlag1None);
+  EXPECT_EQ(kFlag1All, static_cast<int>(a));
+  Flags1 b = ~a;
+  EXPECT_EQ(kFlag1All, static_cast<int>(a));
+  EXPECT_EQ(~static_cast<int>(a), static_cast<int>(b));
+  Flags1 c = a;
+  EXPECT_EQ(a, c);
+  EXPECT_NE(a, b);
+  EXPECT_EQ(a, bar(a));
+  EXPECT_EQ(a, bar(kFlag1All));
+}
+
+
+namespace {
+namespace foo {
+
+enum Option {
+  kNoOptions = 0,
+  kOption1 = 1,
+  kOption2 = 2,
+  kAllOptions = kNoOptions | kOption1 | kOption2
+};
+typedef Flags<Option> Options;
+
+}  // namespace foo
+
+
+DEFINE_OPERATORS_FOR_FLAGS(foo::Options)
+
+}  // namespace
+
+
+TEST(FlagsTest, NamespaceScope) {
+  foo::Options options;
+  options ^= foo::kNoOptions;
+  options |= foo::kOption1 | foo::kOption2;
+  EXPECT_EQ(foo::kAllOptions, static_cast<int>(options));
+}
+
+
+namespace {
+
+struct Foo {
+  enum Enum { kEnum1 = 1, kEnum2 = 2 };
+  typedef Flags<Enum, uint32_t> Enums;
+};
+
+
+DEFINE_OPERATORS_FOR_FLAGS(Foo::Enums)
+
+}  // namespace
+
+
+TEST(FlagsTest, ClassScope) {
+  Foo::Enums enums;
+  enums |= Foo::kEnum1;
+  enums |= Foo::kEnum2;
+  EXPECT_TRUE(enums & Foo::kEnum1);
+  EXPECT_TRUE(enums & Foo::kEnum2);
+}
+
+}  // namespace base
+}  // namespace v8
diff --git a/test/unittests/base/functional-unittest.cc b/test/unittests/base/functional-unittest.cc
new file mode 100644
index 0000000..97a27a4
--- /dev/null
+++ b/test/unittests/base/functional-unittest.cc
@@ -0,0 +1,196 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/base/functional.h"
+
+#include <limits>
+#include <set>
+
+#include "test/unittests/test-utils.h"
+
+namespace v8 {
+namespace base {
+
+TEST(FunctionalTest, HashBool) {
+  hash<bool> h, h1, h2;
+  EXPECT_EQ(h1(true), h2(true));
+  EXPECT_EQ(h1(false), h2(false));
+  EXPECT_NE(h(true), h(false));
+}
+
+
+TEST(FunctionalTest, HashFloatZero) {
+  hash<float> h;
+  EXPECT_EQ(h(0.0f), h(-0.0f));
+}
+
+
+TEST(FunctionalTest, HashDoubleZero) {
+  hash<double> h;
+  EXPECT_EQ(h(0.0), h(-0.0));
+}
+
+
+template <typename T>
+class FunctionalTest : public TestWithRandomNumberGenerator {};
+
+typedef ::testing::Types<signed char, unsigned char,
+                         short,                    // NOLINT(runtime/int)
+                         unsigned short,           // NOLINT(runtime/int)
+                         int, unsigned int, long,  // NOLINT(runtime/int)
+                         unsigned long,            // NOLINT(runtime/int)
+                         long long,                // NOLINT(runtime/int)
+                         unsigned long long,       // NOLINT(runtime/int)
+                         int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
+                         int64_t, uint64_t, float, double> FunctionalTypes;
+
+TYPED_TEST_CASE(FunctionalTest, FunctionalTypes);
+
+
+TYPED_TEST(FunctionalTest, EqualToImpliesSameHashCode) {
+  hash<TypeParam> h;
+  std::equal_to<TypeParam> e;
+  TypeParam values[32];
+  this->rng()->NextBytes(values, sizeof(values));
+  TRACED_FOREACH(TypeParam, v1, values) {
+    TRACED_FOREACH(TypeParam, v2, values) {
+      if (e(v1, v2)) EXPECT_EQ(h(v1), h(v2));
+    }
+  }
+}
+
+
+TYPED_TEST(FunctionalTest, HashEqualsHashValue) {
+  for (int i = 0; i < 128; ++i) {
+    TypeParam v;
+    this->rng()->NextBytes(&v, sizeof(v));
+    hash<TypeParam> h;
+    EXPECT_EQ(h(v), hash_value(v));
+  }
+}
+
+
+TYPED_TEST(FunctionalTest, HashIsStateless) {
+  hash<TypeParam> h1, h2;
+  for (int i = 0; i < 128; ++i) {
+    TypeParam v;
+    this->rng()->NextBytes(&v, sizeof(v));
+    EXPECT_EQ(h1(v), h2(v));
+  }
+}
+
+
+TYPED_TEST(FunctionalTest, HashIsOkish) {
+  std::set<TypeParam> vs;
+  for (size_t i = 0; i < 128; ++i) {
+    TypeParam v;
+    this->rng()->NextBytes(&v, sizeof(v));
+    vs.insert(v);
+  }
+  std::set<size_t> hs;
+  for (const auto& v : vs) {
+    hash<TypeParam> h;
+    hs.insert(h(v));
+  }
+  EXPECT_LE(vs.size() / 4u, hs.size());
+}
+
+
+TYPED_TEST(FunctionalTest, HashValueArrayUsesHashRange) {
+  TypeParam values[128];
+  this->rng()->NextBytes(&values, sizeof(values));
+  EXPECT_EQ(hash_range(values, values + arraysize(values)), hash_value(values));
+}
+
+
+TYPED_TEST(FunctionalTest, BitEqualTo) {
+  bit_equal_to<TypeParam> pred;
+  for (size_t i = 0; i < 128; ++i) {
+    TypeParam v1, v2;
+    this->rng()->NextBytes(&v1, sizeof(v1));
+    this->rng()->NextBytes(&v2, sizeof(v2));
+    EXPECT_PRED2(pred, v1, v1);
+    EXPECT_PRED2(pred, v2, v2);
+    EXPECT_EQ(memcmp(&v1, &v2, sizeof(TypeParam)) == 0, pred(v1, v2));
+  }
+}
+
+
+TYPED_TEST(FunctionalTest, BitEqualToImpliesSameBitHash) {
+  bit_hash<TypeParam> h;
+  bit_equal_to<TypeParam> e;
+  TypeParam values[32];
+  this->rng()->NextBytes(&values, sizeof(values));
+  TRACED_FOREACH(TypeParam, v1, values) {
+    TRACED_FOREACH(TypeParam, v2, values) {
+      if (e(v1, v2)) EXPECT_EQ(h(v1), h(v2));
+    }
+  }
+}
+
+
+namespace {
+
+struct Foo {
+  int x;
+  double y;
+};
+
+
+size_t hash_value(Foo const& v) { return hash_combine(v.x, v.y); }
+
+}  // namespace
+
+
+TEST(FunctionalTest, HashUsesArgumentDependentLookup) {
+  const int kIntValues[] = {std::numeric_limits<int>::min(), -1, 0, 1, 42,
+                            std::numeric_limits<int>::max()};
+  const double kDoubleValues[] = {
+      std::numeric_limits<double>::min(), -1, -0, 0, 1,
+      std::numeric_limits<double>::max()};
+  TRACED_FOREACH(int, x, kIntValues) {
+    TRACED_FOREACH(double, y, kDoubleValues) {
+      hash<Foo> h;
+      Foo foo = {x, y};
+      EXPECT_EQ(hash_combine(x, y), h(foo));
+    }
+  }
+}
+
+
+TEST(FunctionalTest, BitEqualToFloat) {
+  bit_equal_to<float> pred;
+  EXPECT_FALSE(pred(0.0f, -0.0f));
+  EXPECT_FALSE(pred(-0.0f, 0.0f));
+  float const qNaN = std::numeric_limits<float>::quiet_NaN();
+  float const sNaN = std::numeric_limits<float>::signaling_NaN();
+  EXPECT_PRED2(pred, qNaN, qNaN);
+  EXPECT_PRED2(pred, sNaN, sNaN);
+}
+
+
+TEST(FunctionalTest, BitHashFloatDifferentForZeroAndMinusZero) {
+  bit_hash<float> h;
+  EXPECT_NE(h(0.0f), h(-0.0f));
+}
+
+
+TEST(FunctionalTest, BitEqualToDouble) {
+  bit_equal_to<double> pred;
+  EXPECT_FALSE(pred(0.0, -0.0));
+  EXPECT_FALSE(pred(-0.0, 0.0));
+  double const qNaN = std::numeric_limits<double>::quiet_NaN();
+  double const sNaN = std::numeric_limits<double>::signaling_NaN();
+  EXPECT_PRED2(pred, qNaN, qNaN);
+  EXPECT_PRED2(pred, sNaN, sNaN);
+}
+
+
+TEST(FunctionalTest, BitHashDoubleDifferentForZeroAndMinusZero) {
+  bit_hash<double> h;
+  EXPECT_NE(h(0.0), h(-0.0));
+}
+
+}  // namespace base
+}  // namespace v8
diff --git a/test/unittests/base/iterator-unittest.cc b/test/unittests/base/iterator-unittest.cc
new file mode 100644
index 0000000..8da26ce
--- /dev/null
+++ b/test/unittests/base/iterator-unittest.cc
@@ -0,0 +1,61 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/base/iterator.h"
+
+#include <deque>
+
+#include "test/unittests/test-utils.h"
+
+namespace v8 {
+namespace base {
+
+TEST(IteratorTest, IteratorRangeEmpty) {
+  base::iterator_range<char*> r;
+  EXPECT_EQ(r.begin(), r.end());
+  EXPECT_EQ(r.end(), r.cend());
+  EXPECT_EQ(r.begin(), r.cbegin());
+  EXPECT_TRUE(r.empty());
+  EXPECT_EQ(0, r.size());
+}
+
+
+TEST(IteratorTest, IteratorRangeArray) {
+  int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+  base::iterator_range<int*> r1(&array[0], &array[10]);
+  for (auto i : r1) {
+    EXPECT_EQ(array[i], i);
+  }
+  EXPECT_EQ(10, r1.size());
+  EXPECT_FALSE(r1.empty());
+  for (size_t i = 0; i < arraysize(array); ++i) {
+    EXPECT_EQ(r1[i], array[i]);
+  }
+  base::iterator_range<int*> r2(&array[0], &array[0]);
+  EXPECT_EQ(0, r2.size());
+  EXPECT_TRUE(r2.empty());
+  for (auto i : array) {
+    EXPECT_EQ(r2.end(), std::find(r2.begin(), r2.end(), i));
+  }
+}
+
+
+TEST(IteratorTest, IteratorRangeDeque) {
+  typedef std::deque<unsigned> C;
+  C c;
+  c.push_back(1);
+  c.push_back(2);
+  c.push_back(2);
+  base::iterator_range<typename C::iterator> r(c.begin(), c.end());
+  EXPECT_EQ(3, r.size());
+  EXPECT_FALSE(r.empty());
+  EXPECT_TRUE(c.begin() == r.begin());
+  EXPECT_TRUE(c.end() == r.end());
+  EXPECT_EQ(0, std::count(r.begin(), r.end(), 0));
+  EXPECT_EQ(1, std::count(r.begin(), r.end(), 1));
+  EXPECT_EQ(2, std::count(r.begin(), r.end(), 2));
+}
+
+}  // namespace base
+}  // namespace v8
diff --git a/src/base/platform/condition-variable-unittest.cc b/test/unittests/base/platform/condition-variable-unittest.cc
similarity index 100%
rename from src/base/platform/condition-variable-unittest.cc
rename to test/unittests/base/platform/condition-variable-unittest.cc
diff --git a/src/base/platform/mutex-unittest.cc b/test/unittests/base/platform/mutex-unittest.cc
similarity index 100%
rename from src/base/platform/mutex-unittest.cc
rename to test/unittests/base/platform/mutex-unittest.cc
diff --git a/test/unittests/base/platform/platform-unittest.cc b/test/unittests/base/platform/platform-unittest.cc
new file mode 100644
index 0000000..b17a9b9
--- /dev/null
+++ b/test/unittests/base/platform/platform-unittest.cc
@@ -0,0 +1,118 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/base/platform/platform.h"
+
+#if V8_OS_POSIX
+#include <unistd.h>  // NOLINT
+#endif
+
+#if V8_OS_WIN
+#include "src/base/win32-headers.h"
+#endif
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if V8_OS_ANDROID
+#define DISABLE_ON_ANDROID(Name) DISABLED_##Name
+#else
+#define DISABLE_ON_ANDROID(Name) Name
+#endif
+
+namespace v8 {
+namespace base {
+
+TEST(OS, GetCurrentProcessId) {
+#if V8_OS_POSIX
+  EXPECT_EQ(static_cast<int>(getpid()), OS::GetCurrentProcessId());
+#endif
+
+#if V8_OS_WIN
+  EXPECT_EQ(static_cast<int>(::GetCurrentProcessId()),
+            OS::GetCurrentProcessId());
+#endif
+}
+
+
+namespace {
+
+class SelfJoinThread FINAL : public Thread {
+ public:
+  SelfJoinThread() : Thread(Options("SelfJoinThread")) {}
+  void Run() FINAL { Join(); }
+};
+
+}  // namespace
+
+
+TEST(Thread, DISABLE_ON_ANDROID(SelfJoin)) {
+  SelfJoinThread thread;
+  thread.Start();
+  thread.Join();
+}
+
+
+namespace {
+
+class ThreadLocalStorageTest : public Thread, public ::testing::Test {
+ public:
+  ThreadLocalStorageTest() : Thread(Options("ThreadLocalStorageTest")) {
+    for (size_t i = 0; i < arraysize(keys_); ++i) {
+      keys_[i] = Thread::CreateThreadLocalKey();
+    }
+  }
+  ~ThreadLocalStorageTest() {
+    for (size_t i = 0; i < arraysize(keys_); ++i) {
+      Thread::DeleteThreadLocalKey(keys_[i]);
+    }
+  }
+
+  void Run() FINAL {
+    for (size_t i = 0; i < arraysize(keys_); i++) {
+      CHECK(!Thread::HasThreadLocal(keys_[i]));
+    }
+    for (size_t i = 0; i < arraysize(keys_); i++) {
+      Thread::SetThreadLocal(keys_[i], GetValue(i));
+    }
+    for (size_t i = 0; i < arraysize(keys_); i++) {
+      CHECK(Thread::HasThreadLocal(keys_[i]));
+    }
+    for (size_t i = 0; i < arraysize(keys_); i++) {
+      CHECK_EQ(GetValue(i), Thread::GetThreadLocal(keys_[i]));
+      CHECK_EQ(GetValue(i), Thread::GetExistingThreadLocal(keys_[i]));
+    }
+    for (size_t i = 0; i < arraysize(keys_); i++) {
+      Thread::SetThreadLocal(keys_[i], GetValue(arraysize(keys_) - i - 1));
+    }
+    for (size_t i = 0; i < arraysize(keys_); i++) {
+      CHECK(Thread::HasThreadLocal(keys_[i]));
+    }
+    for (size_t i = 0; i < arraysize(keys_); i++) {
+      CHECK_EQ(GetValue(arraysize(keys_) - i - 1),
+               Thread::GetThreadLocal(keys_[i]));
+      CHECK_EQ(GetValue(arraysize(keys_) - i - 1),
+               Thread::GetExistingThreadLocal(keys_[i]));
+    }
+  }
+
+ private:
+  static void* GetValue(size_t x) {
+    return bit_cast<void*>(static_cast<uintptr_t>(x + 1));
+  }
+
+  // Older versions of Android have fewer TLS slots (nominally 64, but the
+  // system uses "about 5 of them" itself).
+  Thread::LocalStorageKey keys_[32];
+};
+
+}  // namespace
+
+
+TEST_F(ThreadLocalStorageTest, DoTest) {
+  Run();
+  Start();
+  Join();
+}
+
+}  // namespace base
+}  // namespace v8
diff --git a/src/base/platform/semaphore-unittest.cc b/test/unittests/base/platform/semaphore-unittest.cc
similarity index 100%
rename from src/base/platform/semaphore-unittest.cc
rename to test/unittests/base/platform/semaphore-unittest.cc
diff --git a/src/base/platform/time-unittest.cc b/test/unittests/base/platform/time-unittest.cc
similarity index 100%
rename from src/base/platform/time-unittest.cc
rename to test/unittests/base/platform/time-unittest.cc
diff --git a/src/base/sys-info-unittest.cc b/test/unittests/base/sys-info-unittest.cc
similarity index 100%
rename from src/base/sys-info-unittest.cc
rename to test/unittests/base/sys-info-unittest.cc
diff --git a/src/base/utils/random-number-generator-unittest.cc b/test/unittests/base/utils/random-number-generator-unittest.cc
similarity index 100%
rename from src/base/utils/random-number-generator-unittest.cc
rename to test/unittests/base/utils/random-number-generator-unittest.cc
diff --git a/test/unittests/char-predicates-unittest.cc b/test/unittests/char-predicates-unittest.cc
new file mode 100644
index 0000000..d1ba2c5
--- /dev/null
+++ b/test/unittests/char-predicates-unittest.cc
@@ -0,0 +1,121 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/char-predicates.h"
+#include "src/unicode.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace internal {
+
+TEST(CharPredicatesTest, WhiteSpace) {
+  // As of Unicode 6.3.0, \u180E is no longer a white space. We still consider
+  // it to be one though, since JS recognizes all white spaces in Unicode 5.1.
+  EXPECT_TRUE(WhiteSpace::Is(0x0009));
+  EXPECT_TRUE(WhiteSpace::Is(0x000B));
+  EXPECT_TRUE(WhiteSpace::Is(0x000C));
+  EXPECT_TRUE(WhiteSpace::Is(' '));
+  EXPECT_TRUE(WhiteSpace::Is(0x00A0));
+  EXPECT_TRUE(WhiteSpace::Is(0x180E));
+  EXPECT_TRUE(WhiteSpace::Is(0xFEFF));
+}
+
+
+TEST(CharPredicatesTest, WhiteSpaceOrLineTerminator) {
+  // As of Unicode 6.3.0, \u180E is no longer a white space. We still consider
+  // it to be one though, since JS recognizes all white spaces in Unicode 5.1.
+  // White spaces
+  EXPECT_TRUE(WhiteSpaceOrLineTerminator::Is(0x0009));
+  EXPECT_TRUE(WhiteSpaceOrLineTerminator::Is(0x000B));
+  EXPECT_TRUE(WhiteSpaceOrLineTerminator::Is(0x000C));
+  EXPECT_TRUE(WhiteSpaceOrLineTerminator::Is(' '));
+  EXPECT_TRUE(WhiteSpaceOrLineTerminator::Is(0x00A0));
+  EXPECT_TRUE(WhiteSpaceOrLineTerminator::Is(0x180E));
+  EXPECT_TRUE(WhiteSpaceOrLineTerminator::Is(0xFEFF));
+  // Line terminators
+  EXPECT_TRUE(WhiteSpaceOrLineTerminator::Is(0x000A));
+  EXPECT_TRUE(WhiteSpaceOrLineTerminator::Is(0x000D));
+  EXPECT_TRUE(WhiteSpaceOrLineTerminator::Is(0x2028));
+  EXPECT_TRUE(WhiteSpaceOrLineTerminator::Is(0x2029));
+}
+
+
+TEST(CharPredicatesTest, IdentifierStart) {
+  EXPECT_TRUE(IdentifierStart::Is('$'));
+  EXPECT_TRUE(IdentifierStart::Is('_'));
+  EXPECT_TRUE(IdentifierStart::Is('\\'));
+
+  // http://www.unicode.org/reports/tr31/
+  // Other_ID_Start
+  EXPECT_TRUE(IdentifierStart::Is(0x2118));
+  EXPECT_TRUE(IdentifierStart::Is(0x212E));
+  EXPECT_TRUE(IdentifierStart::Is(0x309B));
+  EXPECT_TRUE(IdentifierStart::Is(0x309C));
+
+  // Issue 2892:
+  // \u2E2F has the Pattern_Syntax property, excluding it from ID_Start.
+  EXPECT_FALSE(unibrow::ID_Start::Is(0x2E2F));
+}
+
+
+TEST(CharPredicatesTest, IdentifierPart) {
+  EXPECT_TRUE(IdentifierPart::Is('$'));
+  EXPECT_TRUE(IdentifierPart::Is('_'));
+  EXPECT_TRUE(IdentifierPart::Is('\\'));
+  EXPECT_TRUE(IdentifierPart::Is(0x200C));
+  EXPECT_TRUE(IdentifierPart::Is(0x200D));
+
+  // http://www.unicode.org/reports/tr31/
+  // Other_ID_Start
+  EXPECT_TRUE(IdentifierPart::Is(0x2118));
+  EXPECT_TRUE(IdentifierPart::Is(0x212E));
+  EXPECT_TRUE(IdentifierPart::Is(0x309B));
+  EXPECT_TRUE(IdentifierPart::Is(0x309C));
+
+  // Other_ID_Continue
+  EXPECT_TRUE(IdentifierPart::Is(0x00B7));
+  EXPECT_TRUE(IdentifierPart::Is(0x0387));
+  EXPECT_TRUE(IdentifierPart::Is(0x1369));
+  EXPECT_TRUE(IdentifierPart::Is(0x1370));
+  EXPECT_TRUE(IdentifierPart::Is(0x1371));
+  EXPECT_TRUE(IdentifierPart::Is(0x19DA));
+
+  // Issue 2892:
+  // \u2E2F has the Pattern_Syntax property, excluding it from ID_Start.
+  EXPECT_FALSE(IdentifierPart::Is(0x2E2F));
+}
+
+
+#ifdef V8_I18N_SUPPORT
+TEST(CharPredicatesTest, SupplementaryPlaneIdentifiers) {
+  // Both ID_Start and ID_Continue.
+  EXPECT_TRUE(IdentifierStart::Is(0x10403));  // Category Lu
+  EXPECT_TRUE(IdentifierPart::Is(0x10403));
+  EXPECT_TRUE(IdentifierStart::Is(0x1043C));  // Category Ll
+  EXPECT_TRUE(IdentifierPart::Is(0x1043C));
+  EXPECT_TRUE(IdentifierStart::Is(0x16F9C));  // Category Lm
+  EXPECT_TRUE(IdentifierPart::Is(0x16F9C));
+  EXPECT_TRUE(IdentifierStart::Is(0x10048));  // Category Lo
+  EXPECT_TRUE(IdentifierPart::Is(0x10048));
+  EXPECT_TRUE(IdentifierStart::Is(0x1014D));  // Category Nl
+  EXPECT_TRUE(IdentifierPart::Is(0x1014D));
+
+  // Only ID_Continue.
+  EXPECT_FALSE(IdentifierStart::Is(0x101FD));  // Category Mn
+  EXPECT_TRUE(IdentifierPart::Is(0x101FD));
+  EXPECT_FALSE(IdentifierStart::Is(0x11002));  // Category Mc
+  EXPECT_TRUE(IdentifierPart::Is(0x11002));
+  EXPECT_FALSE(IdentifierStart::Is(0x104A9));  // Category Nd
+  EXPECT_TRUE(IdentifierPart::Is(0x104A9));
+
+  // Neither.
+  EXPECT_FALSE(IdentifierStart::Is(0x10111));  // Category No
+  EXPECT_FALSE(IdentifierPart::Is(0x10111));
+  EXPECT_FALSE(IdentifierStart::Is(0x1F4A9));  // Category So
+  EXPECT_FALSE(IdentifierPart::Is(0x1F4A9));
+}
+#endif  // V8_I18N_SUPPORT
+
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc b/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
new file mode 100644
index 0000000..fbdf87a
--- /dev/null
+++ b/test/unittests/compiler/arm/instruction-selector-arm-unittest.cc
@@ -0,0 +1,2352 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <limits>
+
+#include "test/unittests/compiler/instruction-selector-unittest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+typedef RawMachineAssembler::Label MLabel;
+typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);
+
+
+// Data processing instructions.
+struct DPI {
+  Constructor constructor;
+  const char* constructor_name;
+  ArchOpcode arch_opcode;
+  ArchOpcode reverse_arch_opcode;
+  ArchOpcode test_arch_opcode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const DPI& dpi) {
+  return os << dpi.constructor_name;
+}
+
+
+static const DPI kDPIs[] = {
+    {&RawMachineAssembler::Word32And, "Word32And", kArmAnd, kArmAnd, kArmTst},
+    {&RawMachineAssembler::Word32Or, "Word32Or", kArmOrr, kArmOrr, kArmOrr},
+    {&RawMachineAssembler::Word32Xor, "Word32Xor", kArmEor, kArmEor, kArmTeq},
+    {&RawMachineAssembler::Int32Add, "Int32Add", kArmAdd, kArmAdd, kArmCmn},
+    {&RawMachineAssembler::Int32Sub, "Int32Sub", kArmSub, kArmRsb, kArmCmp}};
+
+
+// Data processing instructions with overflow.
+struct ODPI {
+  Constructor constructor;
+  const char* constructor_name;
+  ArchOpcode arch_opcode;
+  ArchOpcode reverse_arch_opcode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const ODPI& odpi) {
+  return os << odpi.constructor_name;
+}
+
+
+static const ODPI kODPIs[] = {{&RawMachineAssembler::Int32AddWithOverflow,
+                               "Int32AddWithOverflow", kArmAdd, kArmAdd},
+                              {&RawMachineAssembler::Int32SubWithOverflow,
+                               "Int32SubWithOverflow", kArmSub, kArmRsb}};
+
+
+// Shifts.
+struct Shift {
+  Constructor constructor;
+  const char* constructor_name;
+  int32_t i_low;          // lowest possible immediate
+  int32_t i_high;         // highest possible immediate
+  AddressingMode i_mode;  // Operand2_R_<shift>_I
+  AddressingMode r_mode;  // Operand2_R_<shift>_R
+};
+
+
+std::ostream& operator<<(std::ostream& os, const Shift& shift) {
+  return os << shift.constructor_name;
+}
+
+
+static const Shift kShifts[] = {
+    {&RawMachineAssembler::Word32Sar, "Word32Sar", 1, 32,
+     kMode_Operand2_R_ASR_I, kMode_Operand2_R_ASR_R},
+    {&RawMachineAssembler::Word32Shl, "Word32Shl", 0, 31,
+     kMode_Operand2_R_LSL_I, kMode_Operand2_R_LSL_R},
+    {&RawMachineAssembler::Word32Shr, "Word32Shr", 1, 32,
+     kMode_Operand2_R_LSR_I, kMode_Operand2_R_LSR_R},
+    {&RawMachineAssembler::Word32Ror, "Word32Ror", 1, 31,
+     kMode_Operand2_R_ROR_I, kMode_Operand2_R_ROR_R}};
+
+
+// Immediates (random subset).
+static const int32_t kImmediates[] = {
+    std::numeric_limits<int32_t>::min(), -2147483617, -2147483606, -2113929216,
+    -2080374784,                         -1996488704, -1879048192, -1459617792,
+    -1358954496,                         -1342177265, -1275068414, -1073741818,
+    -1073741777,                         -855638016,  -805306368,  -402653184,
+    -268435444,                          -16777216,   0,           35,
+    61,                                  105,         116,         171,
+    245,                                 255,         692,         1216,
+    1248,                                1520,        1600,        1888,
+    3744,                                4080,        5888,        8384,
+    9344,                                9472,        9792,        13312,
+    15040,                               15360,       20736,       22272,
+    23296,                               32000,       33536,       37120,
+    45824,                               47872,       56320,       59392,
+    65280,                               72704,       101376,      147456,
+    161792,                              164864,      167936,      173056,
+    195584,                              209920,      212992,      356352,
+    655360,                              704512,      716800,      851968,
+    901120,                              1044480,     1523712,     2572288,
+    3211264,                             3588096,     3833856,     3866624,
+    4325376,                             5177344,     6488064,     7012352,
+    7471104,                             14090240,    16711680,    19398656,
+    22282240,                            28573696,    30408704,    30670848,
+    43253760,                            54525952,    55312384,    56623104,
+    68157440,                            115343360,   131072000,   187695104,
+    188743680,                           195035136,   197132288,   203423744,
+    218103808,                           267386880,   268435470,   285212672,
+    402653185,                           415236096,   595591168,   603979776,
+    603979778,                           629145600,   1073741835,  1073741855,
+    1073741861,                          1073741884,  1157627904,  1476395008,
+    1476395010,                          1610612741,  2030043136,  2080374785,
+    2097152000};
+
+}  // namespace
+
+
+// -----------------------------------------------------------------------------
+// Data processing instructions.
+
+
+typedef InstructionSelectorTestWithParam<DPI> InstructionSelectorDPITest;
+
+
+TEST_P(InstructionSelectorDPITest, Parameters) {
+  const DPI dpi = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorDPITest, Immediate) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, ShiftByParameter) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    m.Return((m.*dpi.constructor)(
+        m.Parameter(0),
+        (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    m.Return((m.*dpi.constructor)(
+        (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
+        m.Parameter(2)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, ShiftByImmediate) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+      m.Return((m.*dpi.constructor)(
+          m.Parameter(0),
+          (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+      m.Return((m.*dpi.constructor)(
+          (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
+          m.Parameter(1)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.reverse_arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchWithParameters) {
+  const DPI dpi = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  MLabel a, b;
+  m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)), &a, &b);
+  m.Bind(&a);
+  m.Return(m.Int32Constant(1));
+  m.Bind(&b);
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchWithImmediate) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)), &a,
+             &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)), &a,
+             &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchWithShiftByParameter) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch((m.*dpi.constructor)(
+                 m.Parameter(0),
+                 (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))),
+             &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch((m.*dpi.constructor)(
+                 (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
+                 m.Parameter(2)),
+             &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchWithShiftByImmediate) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+      MLabel a, b;
+      m.Branch((m.*dpi.constructor)(m.Parameter(0),
+                                    (m.*shift.constructor)(
+                                        m.Parameter(1), m.Int32Constant(imm))),
+               &a, &b);
+      m.Bind(&a);
+      m.Return(m.Int32Constant(1));
+      m.Bind(&b);
+      m.Return(m.Int32Constant(0));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(5U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+      EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+    }
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+      MLabel a, b;
+      m.Branch((m.*dpi.constructor)(
+                   (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
+                   m.Parameter(1)),
+               &a, &b);
+      m.Bind(&a);
+      m.Return(m.Int32Constant(1));
+      m.Bind(&b);
+      m.Return(m.Int32Constant(0));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(5U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+      EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+    }
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchIfZeroWithParameters) {
+  const DPI dpi = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  MLabel a, b;
+  m.Branch(m.Word32Equal((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
+                         m.Int32Constant(0)),
+           &a, &b);
+  m.Bind(&a);
+  m.Return(m.Int32Constant(1));
+  m.Bind(&b);
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kEqual, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithParameters) {
+  const DPI dpi = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  MLabel a, b;
+  m.Branch(
+      m.Word32NotEqual((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)),
+                       m.Int32Constant(0)),
+      &a, &b);
+  m.Bind(&a);
+  m.Return(m.Int32Constant(1));
+  m.Bind(&b);
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchIfZeroWithImmediate) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(m.Word32Equal(
+                 (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
+                 m.Int32Constant(0)),
+             &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(m.Word32Equal(
+                 (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
+                 m.Int32Constant(0)),
+             &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorDPITest, BranchIfNotZeroWithImmediate) {
+  const DPI dpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(m.Word32NotEqual(
+                 (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)),
+                 m.Int32Constant(0)),
+             &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(m.Word32NotEqual(
+                 (m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)),
+                 m.Int32Constant(0)),
+             &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.test_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorDPITest,
+                        ::testing::ValuesIn(kDPIs));
+
+
+// -----------------------------------------------------------------------------
+// Data processing instructions with overflow.
+
+
+typedef InstructionSelectorTestWithParam<ODPI> InstructionSelectorODPITest;
+
+
+TEST_P(InstructionSelectorODPITest, OvfWithParameters) {
+  const ODPI odpi = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(
+      m.Projection(1, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_LE(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(kOverflow, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorODPITest, OvfWithImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Projection(
+        1, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Projection(
+        1, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, OvfWithShiftByParameter) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Projection(
+        1, (m.*odpi.constructor)(
+               m.Parameter(0),
+               (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Projection(
+        1, (m.*odpi.constructor)(
+               (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
+               m.Parameter(0))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, OvfWithShiftByImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+      m.Return(m.Projection(
+          1, (m.*odpi.constructor)(m.Parameter(0),
+                                   (m.*shift.constructor)(
+                                       m.Parameter(1), m.Int32Constant(imm)))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_LE(1U, s[0]->OutputCount());
+      EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+      EXPECT_EQ(kOverflow, s[0]->flags_condition());
+    }
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+      m.Return(m.Projection(
+          1, (m.*odpi.constructor)(
+                 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
+                 m.Parameter(0))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_LE(1U, s[0]->OutputCount());
+      EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+      EXPECT_EQ(kOverflow, s[0]->flags_condition());
+    }
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, ValWithParameters) {
+  const ODPI odpi = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(
+      m.Projection(0, (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1))));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_LE(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+}
+
+
+TEST_P(InstructionSelectorODPITest, ValWithImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Projection(
+        0, (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Projection(
+        0, (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, ValWithShiftByParameter) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Projection(
+        0, (m.*odpi.constructor)(
+               m.Parameter(0),
+               (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Projection(
+        0, (m.*odpi.constructor)(
+               (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)),
+               m.Parameter(0))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, ValWithShiftByImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+      m.Return(m.Projection(
+          0, (m.*odpi.constructor)(m.Parameter(0),
+                                   (m.*shift.constructor)(
+                                       m.Parameter(1), m.Int32Constant(imm)))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_LE(1U, s[0]->OutputCount());
+      EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+    }
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+      m.Return(m.Projection(
+          0, (m.*odpi.constructor)(
+                 (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
+                 m.Parameter(0))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_LE(1U, s[0]->OutputCount());
+      EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+    }
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, BothWithParameters) {
+  const ODPI odpi = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
+  m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+  Stream s = m.Build();
+  ASSERT_LE(1U, s.size());
+  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(2U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(kOverflow, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorODPITest, BothWithImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
+    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+    Stream s = m.Build();
+    ASSERT_LE(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(2U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
+    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+    Stream s = m.Build();
+    ASSERT_LE(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(2U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, BothWithShiftByParameter) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    Node* n = (m.*odpi.constructor)(
+        m.Parameter(0), (m.*shift.constructor)(m.Parameter(1), m.Parameter(2)));
+    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+    Stream s = m.Build();
+    ASSERT_LE(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(2U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    Node* n = (m.*odpi.constructor)(
+        (m.*shift.constructor)(m.Parameter(0), m.Parameter(1)), m.Parameter(2));
+    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+    Stream s = m.Build();
+    ASSERT_LE(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(2U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, BothWithShiftByImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+      Node* n = (m.*odpi.constructor)(
+          m.Parameter(0),
+          (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)));
+      m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+      Stream s = m.Build();
+      ASSERT_LE(1U, s.size());
+      EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_EQ(2U, s[0]->OutputCount());
+      EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+      EXPECT_EQ(kOverflow, s[0]->flags_condition());
+    }
+  }
+  TRACED_FOREACH(Shift, shift, kShifts) {
+    TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+      Node* n = (m.*odpi.constructor)(
+          (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)),
+          m.Parameter(1));
+      m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+      Stream s = m.Build();
+      ASSERT_LE(1U, s.size());
+      EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+      EXPECT_EQ(2U, s[0]->OutputCount());
+      EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+      EXPECT_EQ(kOverflow, s[0]->flags_condition());
+    }
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, BranchWithParameters) {
+  const ODPI odpi = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  MLabel a, b;
+  Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
+  m.Branch(m.Projection(1, n), &a, &b);
+  m.Bind(&a);
+  m.Return(m.Int32Constant(0));
+  m.Bind(&b);
+  m.Return(m.Projection(0, n));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(4U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kOverflow, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorODPITest, BranchWithImmediate) {
+  const ODPI odpi = GetParam();
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
+    m.Branch(m.Projection(1, n), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(0));
+    m.Bind(&b);
+    m.Return(m.Projection(0, n));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    Node* n = (m.*odpi.constructor)(m.Int32Constant(imm), m.Parameter(0));
+    m.Branch(m.Projection(1, n), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(0));
+    m.Bind(&b);
+    m.Return(m.Projection(0, n));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(odpi.reverse_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorODPITest, BranchIfZeroWithParameters) {
+  const ODPI odpi = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  MLabel a, b;
+  Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
+  m.Branch(m.Word32Equal(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
+  m.Bind(&a);
+  m.Return(m.Projection(0, n));
+  m.Bind(&b);
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(4U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kNotOverflow, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorODPITest, BranchIfNotZeroWithParameters) {
+  const ODPI odpi = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  MLabel a, b;
+  Node* n = (m.*odpi.constructor)(m.Parameter(0), m.Parameter(1));
+  m.Branch(m.Word32NotEqual(m.Projection(1, n), m.Int32Constant(0)), &a, &b);
+  m.Bind(&a);
+  m.Return(m.Projection(0, n));
+  m.Bind(&b);
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(odpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(4U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kOverflow, s[0]->flags_condition());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorODPITest,
+                        ::testing::ValuesIn(kODPIs));
+
+
+// -----------------------------------------------------------------------------
+// Shifts.
+
+
+typedef InstructionSelectorTestWithParam<Shift> InstructionSelectorShiftTest;
+
+
+TEST_P(InstructionSelectorShiftTest, Parameters) {
+  const Shift shift = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return((m.*shift.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmMov, s[0]->arch_opcode());
+  EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorShiftTest, Immediate) {
+  const Shift shift = GetParam();
+  TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return((m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmMov, s[0]->arch_opcode());
+    EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameter) {
+  const Shift shift = GetParam();
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(
+        m.Word32Equal(m.Parameter(0),
+                      (m.*shift.constructor)(m.Parameter(1), m.Parameter(2))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(
+        m.Word32Equal((m.*shift.constructor)(m.Parameter(1), m.Parameter(2)),
+                      m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
+    EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorShiftTest, Word32EqualWithParameterAndImmediate) {
+  const Shift shift = GetParam();
+  TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(
+        (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm)),
+        m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
+    EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+  TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(
+        m.Parameter(0),
+        (m.*shift.constructor)(m.Parameter(1), m.Int32Constant(imm))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
+    EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorShiftTest, Word32EqualToZeroWithParameters) {
+  const Shift shift = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(
+      m.Word32Equal(m.Int32Constant(0),
+                    (m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmMov, s[0]->arch_opcode());
+  EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(2U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(kEqual, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorShiftTest, Word32EqualToZeroWithImmediate) {
+  const Shift shift = GetParam();
+  TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(
+        m.Int32Constant(0),
+        (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmMov, s[0]->arch_opcode());
+    EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(2U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorShiftTest, Word32NotWithParameters) {
+  const Shift shift = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Word32Not((m.*shift.constructor)(m.Parameter(0), m.Parameter(1))));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
+  EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorShiftTest, Word32NotWithImmediate) {
+  const Shift shift = GetParam();
+  TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Not(
+        (m.*shift.constructor)(m.Parameter(0), m.Int32Constant(imm))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
+    EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithParameters) {
+  const Shift shift = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Word32And(m.Parameter(0), m.Word32Not((m.*shift.constructor)(
+                                           m.Parameter(1), m.Parameter(2)))));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmBic, s[0]->arch_opcode());
+  EXPECT_EQ(shift.r_mode, s[0]->addressing_mode());
+  EXPECT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorShiftTest, Word32AndWithWord32NotWithImmediate) {
+  const Shift shift = GetParam();
+  TRACED_FORRANGE(int32_t, imm, shift.i_low, shift.i_high) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Word32And(m.Parameter(0),
+                         m.Word32Not((m.*shift.constructor)(
+                             m.Parameter(1), m.Int32Constant(imm)))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmBic, s[0]->arch_opcode());
+    EXPECT_EQ(shift.i_mode, s[0]->addressing_mode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(2)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
+                        ::testing::ValuesIn(kShifts));
+
+
+// -----------------------------------------------------------------------------
+// Memory access instructions.
+
+
+namespace {
+
+struct MemoryAccess {
+  MachineType type;
+  ArchOpcode ldr_opcode;
+  ArchOpcode str_opcode;
+  bool (InstructionSelectorTest::Stream::*val_predicate)(
+      const InstructionOperand*) const;
+  const int32_t immediates[40];
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
+  return os << memacc.type;
+}
+
+
+static const MemoryAccess kMemoryAccesses[] = {
+    {kMachInt8,
+     kArmLdrsb,
+     kArmStrb,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachUint8,
+     kArmLdrb,
+     kArmStrb,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3914, -3536, -3234, -3185, -3169, -1073, -990, -859, -720, -434,
+      -127, -124, -122, -105, -91, -86, -64, -55, -53, -30, -10, -3, 0, 20, 28,
+      39, 58, 64, 73, 75, 100, 108, 121, 686, 963, 1363, 2759, 3449, 4095}},
+    {kMachInt16,
+     kArmLdrsh,
+     kArmStrh,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-255, -251, -232, -220, -144, -138, -130, -126, -116, -115, -102, -101,
+      -98, -69, -59, -56, -39, -35, -23, -19, -7, 0, 22, 26, 37, 68, 83, 87, 98,
+      102, 108, 111, 117, 171, 195, 203, 204, 245, 246, 255}},
+    {kMachUint16,
+     kArmLdrh,
+     kArmStrh,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-255, -230, -201, -172, -125, -119, -118, -105, -98, -79, -54, -42, -41,
+      -32, -12, -11, -5, -4, 0, 5, 9, 25, 28, 51, 58, 60, 89, 104, 108, 109,
+      114, 116, 120, 138, 150, 161, 166, 172, 228, 255}},
+    {kMachInt32,
+     kArmLdr,
+     kArmStr,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -1898, -1685, -1562, -1408, -1313, -344, -128, -116, -100, -92,
+      -80, -72, -71, -56, -25, -21, -11, -9, 0, 3, 5, 27, 28, 42, 52, 63, 88,
+      93, 97, 125, 846, 1037, 2102, 2403, 2597, 2632, 2997, 3935, 4095}},
+    {kMachFloat32,
+     kArmVldrF32,
+     kArmVstrF32,
+     &InstructionSelectorTest::Stream::IsDouble,
+     {-1020, -928, -896, -772, -728, -680, -660, -488, -372, -112, -100, -92,
+      -84, -80, -72, -64, -60, -56, -52, -48, -36, -32, -20, -8, -4, 0, 8, 20,
+      24, 40, 64, 112, 204, 388, 516, 852, 856, 976, 988, 1020}},
+    {kMachFloat64,
+     kArmVldrF64,
+     kArmVstrF64,
+     &InstructionSelectorTest::Stream::IsDouble,
+     {-1020, -948, -796, -696, -612, -364, -320, -308, -128, -112, -108, -104,
+      -96, -84, -80, -56, -48, -40, -20, 0, 24, 28, 36, 48, 64, 84, 96, 100,
+      108, 116, 120, 140, 156, 408, 432, 444, 772, 832, 940, 1020}}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccess>
+    InstructionSelectorMemoryAccessTest;
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
+  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, memacc.type, kMachPtr);
+    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
+  }
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
+  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Offset_RR, s[0]->addressing_mode());
+  EXPECT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(0U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
+    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
+            m.Parameter(1));
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Offset_RI, s[0]->addressing_mode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(0U, s[0]->OutputCount());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessTest,
+                        ::testing::ValuesIn(kMemoryAccesses));
+
+
+// -----------------------------------------------------------------------------
+// Conversions.
+
+
+TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) {
+  StreamBuilder m(this, kMachFloat64, kMachFloat32);
+  m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmVcvtF64F32, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_F(InstructionSelectorTest, TruncateFloat64ToFloat32WithParameter) {
+  StreamBuilder m(this, kMachFloat32, kMachFloat64);
+  m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmVcvtF32F64, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+// -----------------------------------------------------------------------------
+// Comparisons.
+
+
+namespace {
+
+struct Comparison {
+  Constructor constructor;
+  const char* constructor_name;
+  FlagsCondition flags_condition;
+  FlagsCondition negated_flags_condition;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const Comparison& cmp) {
+  return os << cmp.constructor_name;
+}
+
+
+const Comparison kComparisons[] = {
+    {&RawMachineAssembler::Word32Equal, "Word32Equal", kEqual, kNotEqual},
+    {&RawMachineAssembler::Int32LessThan, "Int32LessThan", kSignedLessThan,
+     kSignedGreaterThanOrEqual},
+    {&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual",
+     kSignedLessThanOrEqual, kSignedGreaterThan},
+    {&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kUnsignedLessThan,
+     kUnsignedGreaterThanOrEqual},
+    {&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual",
+     kUnsignedLessThanOrEqual, kUnsignedGreaterThan}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<Comparison>
+    InstructionSelectorComparisonTest;
+
+
+TEST_P(InstructionSelectorComparisonTest, Parameters) {
+  const Comparison& cmp = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const r = (m.*cmp.constructor)(p0, p1);
+  m.Return(r);
+  Stream const s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(cmp.flags_condition, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorComparisonTest, Word32EqualWithZero) {
+  {
+    const Comparison& cmp = GetParam();
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const r =
+        m.Word32Equal((m.*cmp.constructor)(p0, p1), m.Int32Constant(0));
+    m.Return(r);
+    Stream const s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
+  }
+  {
+    const Comparison& cmp = GetParam();
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const r =
+        m.Word32Equal(m.Int32Constant(0), (m.*cmp.constructor)(p0, p1));
+    m.Return(r);
+    Stream const s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->OutputAt(0)));
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(cmp.negated_flags_condition, s[0]->flags_condition());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorComparisonTest,
+                        ::testing::ValuesIn(kComparisons));
+
+
+// -----------------------------------------------------------------------------
+// Miscellaneous.
+
+
+TEST_F(InstructionSelectorTest, Float64SubWithMinusZero) {
+  StreamBuilder m(this, kMachFloat64, kMachFloat64);
+  Node* const p0 = m.Parameter(0);
+  Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmVnegF64, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddWithInt32Mul) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const p2 = m.Parameter(2);
+    Node* const n = m.Int32Add(p0, m.Int32Mul(p1, p2));
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmMla, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const p2 = m.Parameter(2);
+    Node* const n = m.Int32Add(m.Int32Mul(p1, p2), p0);
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmMla, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddWithInt32MulHigh) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const p2 = m.Parameter(2);
+    Node* const n = m.Int32Add(p0, m.Int32MulHigh(p1, p2));
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmSmmla, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const p2 = m.Parameter(2);
+    Node* const n = m.Int32Add(m.Int32MulHigh(p1, p2), p0);
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmSmmla, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(2)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddWithWord32And) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const r = m.Int32Add(m.Word32And(p0, m.Int32Constant(0xff)), p1);
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmUxtab, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const r = m.Int32Add(p1, m.Word32And(p0, m.Int32Constant(0xff)));
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmUxtab, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const r = m.Int32Add(m.Word32And(p0, m.Int32Constant(0xffff)), p1);
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmUxtah, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const r = m.Int32Add(p1, m.Word32And(p0, m.Int32Constant(0xffff)));
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmUxtah, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddWithWord32SarWithWord32Shl) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const r = m.Int32Add(
+        m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24)),
+        p1);
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmSxtab, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const r = m.Int32Add(
+        p1,
+        m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24)));
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmSxtab, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const r = m.Int32Add(
+        m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16)),
+        p1);
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmSxtah, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const p1 = m.Parameter(1);
+    Node* const r = m.Int32Add(
+        p1,
+        m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16)));
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmSxtah, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(2)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Int32SubWithInt32Mul) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(
+      m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
+  Stream s = m.Build();
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kArmMul, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kArmSub, s[1]->arch_opcode());
+  ASSERT_EQ(2U, s[1]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32SubWithInt32MulForMLS) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(
+      m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2))));
+  Stream s = m.Build(MLS);
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmMls, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(3U, s[0]->InputCount());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32DivWithParameters) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(4U, s.size());
+  EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
+  ASSERT_EQ(1U, s[1]->OutputCount());
+  EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
+  ASSERT_EQ(2U, s[2]->InputCount());
+  ASSERT_EQ(1U, s[2]->OutputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
+  EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
+  ASSERT_EQ(1U, s[3]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32DivWithParametersForSUDIV) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Int32Div(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build(SUDIV);
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32ModWithParameters) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(6U, s.size());
+  EXPECT_EQ(kArmVcvtF64S32, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kArmVcvtF64S32, s[1]->arch_opcode());
+  ASSERT_EQ(1U, s[1]->OutputCount());
+  EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
+  ASSERT_EQ(2U, s[2]->InputCount());
+  ASSERT_EQ(1U, s[2]->OutputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
+  EXPECT_EQ(kArmVcvtS32F64, s[3]->arch_opcode());
+  ASSERT_EQ(1U, s[3]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
+  EXPECT_EQ(kArmMul, s[4]->arch_opcode());
+  ASSERT_EQ(1U, s[4]->OutputCount());
+  ASSERT_EQ(2U, s[4]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
+  EXPECT_EQ(kArmSub, s[5]->arch_opcode());
+  ASSERT_EQ(1U, s[5]->OutputCount());
+  ASSERT_EQ(2U, s[5]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIV) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build(SUDIV);
+  ASSERT_EQ(3U, s.size());
+  EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(kArmMul, s[1]->arch_opcode());
+  ASSERT_EQ(1U, s[1]->OutputCount());
+  ASSERT_EQ(2U, s[1]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
+  EXPECT_EQ(kArmSub, s[2]->arch_opcode());
+  ASSERT_EQ(1U, s[2]->OutputCount());
+  ASSERT_EQ(2U, s[2]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32ModWithParametersForSUDIVAndMLS) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Int32Mod(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build(MLS, SUDIV);
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kArmSdiv, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(kArmMls, s[1]->arch_opcode());
+  ASSERT_EQ(1U, s[1]->OutputCount());
+  ASSERT_EQ(3U, s[1]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
+  EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32MulWithParameters) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Int32Mul(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmMul, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32MulWithImmediate) {
+  // x * (2^k + 1) -> x + (x >> k)
+  TRACED_FORRANGE(int32_t, k, 1, 30) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) + 1)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  // x * (2^k - 1) -> -x + (x >> k)
+  TRACED_FORRANGE(int32_t, k, 3, 30) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant((1 << k) - 1)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  // (2^k + 1) * x -> x + (x >> k)
+  TRACED_FORRANGE(int32_t, k, 1, 30) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Int32Mul(m.Int32Constant((1 << k) + 1), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmAdd, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  // x * (2^k - 1) -> -x + (x >> k)
+  TRACED_FORRANGE(int32_t, k, 3, 30) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Int32Mul(m.Int32Constant((1 << k) - 1), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmRsb, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_R_LSL_I, s[0]->addressing_mode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(k, s.ToInt32(s[0]->InputAt(2)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Int32MulHighWithParameters) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const n = m.Int32MulHigh(p0, p1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmSmmul, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Uint32MulHighWithParameters) {
+  StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const n = m.Uint32MulHigh(p0, p1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmUmull, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  ASSERT_EQ(2U, s[0]->OutputCount());
+  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->OutputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Uint32DivWithParameters) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Uint32Div(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(4U, s.size());
+  EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
+  ASSERT_EQ(1U, s[1]->OutputCount());
+  EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
+  ASSERT_EQ(2U, s[2]->InputCount());
+  ASSERT_EQ(1U, s[2]->OutputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
+  EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
+  ASSERT_EQ(1U, s[3]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
+}
+
+
+TEST_F(InstructionSelectorTest, Uint32DivWithParametersForSUDIV) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Uint32Div(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build(SUDIV);
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
+}
+
+
+TEST_F(InstructionSelectorTest, Uint32ModWithParameters) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(6U, s.size());
+  EXPECT_EQ(kArmVcvtF64U32, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kArmVcvtF64U32, s[1]->arch_opcode());
+  ASSERT_EQ(1U, s[1]->OutputCount());
+  EXPECT_EQ(kArmVdivF64, s[2]->arch_opcode());
+  ASSERT_EQ(2U, s[2]->InputCount());
+  ASSERT_EQ(1U, s[2]->OutputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[2]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
+  EXPECT_EQ(kArmVcvtU32F64, s[3]->arch_opcode());
+  ASSERT_EQ(1U, s[3]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[2]->Output()), s.ToVreg(s[3]->InputAt(0)));
+  EXPECT_EQ(kArmMul, s[4]->arch_opcode());
+  ASSERT_EQ(1U, s[4]->OutputCount());
+  ASSERT_EQ(2U, s[4]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[3]->Output()), s.ToVreg(s[4]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[1]->InputAt(0)), s.ToVreg(s[4]->InputAt(1)));
+  EXPECT_EQ(kArmSub, s[5]->arch_opcode());
+  ASSERT_EQ(1U, s[5]->OutputCount());
+  ASSERT_EQ(2U, s[5]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[5]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[4]->Output()), s.ToVreg(s[5]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Uint32ModWithParametersForSUDIV) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build(SUDIV);
+  ASSERT_EQ(3U, s.size());
+  EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(kArmMul, s[1]->arch_opcode());
+  ASSERT_EQ(1U, s[1]->OutputCount());
+  ASSERT_EQ(2U, s[1]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
+  EXPECT_EQ(kArmSub, s[2]->arch_opcode());
+  ASSERT_EQ(1U, s[2]->OutputCount());
+  ASSERT_EQ(2U, s[2]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[2]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[1]->Output()), s.ToVreg(s[2]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Uint32ModWithParametersForSUDIVAndMLS) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Uint32Mod(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build(MLS, SUDIV);
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kArmUdiv, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(kArmMls, s[1]->arch_opcode());
+  ASSERT_EQ(1U, s[1]->OutputCount());
+  ASSERT_EQ(3U, s[1]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1)));
+  EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2)));
+}
+
+
+TEST_F(InstructionSelectorTest, Word32AndWithUbfxImmediateForARMv7) {
+  TRACED_FORRANGE(int32_t, width, 1, 32) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32And(m.Parameter(0),
+                         m.Int32Constant(0xffffffffu >> (32 - width))));
+    Stream s = m.Build(ARMv7);
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+  }
+  TRACED_FORRANGE(int32_t, width, 1, 32) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
+                         m.Parameter(0)));
+    Stream s = m.Build(ARMv7);
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32AndWithBfcImmediateForARMv7) {
+  TRACED_FORRANGE(int32_t, lsb, 0, 31) {
+    TRACED_FORRANGE(int32_t, width, 9, (32 - lsb) - 1) {
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Word32And(
+          m.Parameter(0),
+          m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb))));
+      Stream s = m.Build(ARMv7);
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
+      ASSERT_EQ(1U, s[0]->OutputCount());
+      EXPECT_TRUE(
+          UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
+      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+    }
+  }
+  TRACED_FORRANGE(int32_t, lsb, 0, 31) {
+    TRACED_FORRANGE(int32_t, width, 9, (32 - lsb) - 1) {
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(
+          m.Word32And(m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb)),
+                      m.Parameter(0)));
+      Stream s = m.Build(ARMv7);
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArmBfc, s[0]->arch_opcode());
+      ASSERT_EQ(1U, s[0]->OutputCount());
+      EXPECT_TRUE(
+          UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
+      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+    }
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32AndWith0xffff) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const r = m.Word32And(p0, m.Int32Constant(0xffff));
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmUxth, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const r = m.Word32And(m.Int32Constant(0xffff), p0);
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmUxth, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32SarWithWord32Shl) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const r =
+        m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24));
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmSxtb, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const r =
+        m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16));
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmSxth, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediateForARMv7) {
+  TRACED_FORRANGE(int32_t, lsb, 0, 31) {
+    TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
+      uint32_t max = 1 << lsb;
+      if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
+      uint32_t jnk = rng()->NextInt(max);
+      uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
+                           m.Int32Constant(lsb)));
+      Stream s = m.Build(ARMv7);
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
+      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+    }
+  }
+  TRACED_FORRANGE(int32_t, lsb, 0, 31) {
+    TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
+      uint32_t max = 1 << lsb;
+      if (max > static_cast<uint32_t>(kMaxInt)) max -= 1;
+      uint32_t jnk = rng()->NextInt(max);
+      uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
+                           m.Int32Constant(lsb)));
+      Stream s = m.Build(ARMv7);
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
+      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+    }
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32AndWithWord32Not) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Word32And(m.Parameter(0), m.Word32Not(m.Parameter(1))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmBic, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Word32And(m.Word32Not(m.Parameter(0)), m.Parameter(1)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmBic, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32EqualWithParameters) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Word32Equal(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(kEqual, s[0]->flags_condition());
+}
+
+
+TEST_F(InstructionSelectorTest, Word32EqualWithImmediate) {
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    if (imm == 0) continue;
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(imm)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    if (imm == 0) continue;
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(m.Int32Constant(imm), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmCmp, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_I, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmTst, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArmTst, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32NotWithParameter) {
+  StreamBuilder m(this, kMachInt32, kMachInt32);
+  m.Return(m.Word32Not(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArmMvn, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrWithImmediateForARMv7) {
+  TRACED_FORRANGE(int32_t, lsb, 0, 31) {
+    TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)),
+                           m.Int32Constant(0xffffffffu >> (32 - width))));
+      Stream s = m.Build(ARMv7);
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
+      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+    }
+  }
+  TRACED_FORRANGE(int32_t, lsb, 0, 31) {
+    TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)),
+                           m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb))));
+      Stream s = m.Build(ARMv7);
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArmUbfx, s[0]->arch_opcode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
+      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+    }
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc b/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
new file mode 100644
index 0000000..cd3ce09
--- /dev/null
+++ b/test/unittests/compiler/arm64/instruction-selector-arm64-unittest.cc
@@ -0,0 +1,2176 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "test/unittests/compiler/instruction-selector-unittest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+typedef RawMachineAssembler::Label MLabel;
+
+template <typename T>
+struct MachInst {
+  T constructor;
+  const char* constructor_name;
+  ArchOpcode arch_opcode;
+  MachineType machine_type;
+};
+
+typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1;
+typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2;
+
+
+template <typename T>
+std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) {
+  return os << mi.constructor_name;
+}
+
+
+struct Shift {
+  MachInst2 mi;
+  AddressingMode mode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const Shift& shift) {
+  return os << shift.mi;
+}
+
+
+// Helper to build Int32Constant or Int64Constant depending on the given
+// machine type.
+Node* BuildConstant(InstructionSelectorTest::StreamBuilder& m, MachineType type,
+                    int64_t value) {
+  switch (type) {
+    case kMachInt32:
+      return m.Int32Constant(value);
+      break;
+
+    case kMachInt64:
+      return m.Int64Constant(value);
+      break;
+
+    default:
+      UNIMPLEMENTED();
+  }
+  return NULL;
+}
+
+
+// ARM64 logical instructions.
+static const MachInst2 kLogicalInstructions[] = {
+    {&RawMachineAssembler::Word32And, "Word32And", kArm64And32, kMachInt32},
+    {&RawMachineAssembler::Word64And, "Word64And", kArm64And, kMachInt64},
+    {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Or32, kMachInt32},
+    {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Or, kMachInt64},
+    {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Eor32, kMachInt32},
+    {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Eor, kMachInt64}};
+
+
+// ARM64 logical immediates: contiguous set bits, rotated about a power of two
+// sized block. The block is then duplicated across the word. Below is a random
+// subset of the 32-bit immediates.
+static const uint32_t kLogical32Immediates[] = {
+    0x00000002, 0x00000003, 0x00000070, 0x00000080, 0x00000100, 0x000001c0,
+    0x00000300, 0x000007e0, 0x00003ffc, 0x00007fc0, 0x0003c000, 0x0003f000,
+    0x0003ffc0, 0x0003fff8, 0x0007ff00, 0x0007ffe0, 0x000e0000, 0x001e0000,
+    0x001ffffc, 0x003f0000, 0x003f8000, 0x00780000, 0x007fc000, 0x00ff0000,
+    0x01800000, 0x01800180, 0x01f801f8, 0x03fe0000, 0x03ffffc0, 0x03fffffc,
+    0x06000000, 0x07fc0000, 0x07ffc000, 0x07ffffc0, 0x07ffffe0, 0x0ffe0ffe,
+    0x0ffff800, 0x0ffffff0, 0x0fffffff, 0x18001800, 0x1f001f00, 0x1f801f80,
+    0x30303030, 0x3ff03ff0, 0x3ff83ff8, 0x3fff0000, 0x3fff8000, 0x3fffffc0,
+    0x70007000, 0x7f7f7f7f, 0x7fc00000, 0x7fffffc0, 0x8000001f, 0x800001ff,
+    0x81818181, 0x9fff9fff, 0xc00007ff, 0xc0ffffff, 0xdddddddd, 0xe00001ff,
+    0xe00003ff, 0xe007ffff, 0xefffefff, 0xf000003f, 0xf001f001, 0xf3fff3ff,
+    0xf800001f, 0xf80fffff, 0xf87ff87f, 0xfbfbfbfb, 0xfc00001f, 0xfc0000ff,
+    0xfc0001ff, 0xfc03fc03, 0xfe0001ff, 0xff000001, 0xff03ff03, 0xff800000,
+    0xff800fff, 0xff801fff, 0xff87ffff, 0xffc0003f, 0xffc007ff, 0xffcfffcf,
+    0xffe00003, 0xffe1ffff, 0xfff0001f, 0xfff07fff, 0xfff80007, 0xfff87fff,
+    0xfffc00ff, 0xfffe07ff, 0xffff00ff, 0xffffc001, 0xfffff007, 0xfffff3ff,
+    0xfffff807, 0xfffff9ff, 0xfffffc0f, 0xfffffeff};
+
+
+// Random subset of 64-bit logical immediates.
+static const uint64_t kLogical64Immediates[] = {
+    0x0000000000000001, 0x0000000000000002, 0x0000000000000003,
+    0x0000000000000070, 0x0000000000000080, 0x0000000000000100,
+    0x00000000000001c0, 0x0000000000000300, 0x0000000000000600,
+    0x00000000000007e0, 0x0000000000003ffc, 0x0000000000007fc0,
+    0x0000000600000000, 0x0000003ffffffffc, 0x000000f000000000,
+    0x000001f800000000, 0x0003fc0000000000, 0x0003fc000003fc00,
+    0x0003ffffffc00000, 0x0003ffffffffffc0, 0x0006000000060000,
+    0x003ffffffffc0000, 0x0180018001800180, 0x01f801f801f801f8,
+    0x0600000000000000, 0x1000000010000000, 0x1000100010001000,
+    0x1010101010101010, 0x1111111111111111, 0x1f001f001f001f00,
+    0x1f1f1f1f1f1f1f1f, 0x1ffffffffffffffe, 0x3ffc3ffc3ffc3ffc,
+    0x5555555555555555, 0x7f7f7f7f7f7f7f7f, 0x8000000000000000,
+    0x8000001f8000001f, 0x8181818181818181, 0x9999999999999999,
+    0x9fff9fff9fff9fff, 0xaaaaaaaaaaaaaaaa, 0xdddddddddddddddd,
+    0xe0000000000001ff, 0xf800000000000000, 0xf8000000000001ff,
+    0xf807f807f807f807, 0xfefefefefefefefe, 0xfffefffefffefffe,
+    0xfffff807fffff807, 0xfffff9fffffff9ff, 0xfffffc0ffffffc0f,
+    0xfffffc0fffffffff, 0xfffffefffffffeff, 0xfffffeffffffffff,
+    0xffffff8000000000, 0xfffffffefffffffe, 0xffffffffefffffff,
+    0xfffffffff9ffffff, 0xffffffffff800000, 0xffffffffffffc0ff,
+    0xfffffffffffffffe};
+
+
+// ARM64 arithmetic instructions.
+struct AddSub {
+  MachInst2 mi;
+  ArchOpcode negate_arch_opcode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const AddSub& op) {
+  return os << op.mi;
+}
+
+
+static const AddSub kAddSubInstructions[] = {
+    {{&RawMachineAssembler::Int32Add, "Int32Add", kArm64Add32, kMachInt32},
+     kArm64Sub32},
+    {{&RawMachineAssembler::Int64Add, "Int64Add", kArm64Add, kMachInt64},
+     kArm64Sub},
+    {{&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Sub32, kMachInt32},
+     kArm64Add32},
+    {{&RawMachineAssembler::Int64Sub, "Int64Sub", kArm64Sub, kMachInt64},
+     kArm64Add}};
+
+
+// ARM64 Add/Sub immediates: 12-bit immediate optionally shifted by 12.
+// Below is a combination of a random subset and some edge values.
+static const int32_t kAddSubImmediates[] = {
+    0,        1,        69,       493,      599,      701,      719,
+    768,      818,      842,      945,      1246,     1286,     1429,
+    1669,     2171,     2179,     2182,     2254,     2334,     2338,
+    2343,     2396,     2449,     2610,     2732,     2855,     2876,
+    2944,     3377,     3458,     3475,     3476,     3540,     3574,
+    3601,     3813,     3871,     3917,     4095,     4096,     16384,
+    364544,   462848,   970752,   1523712,  1863680,  2363392,  3219456,
+    3280896,  4247552,  4526080,  4575232,  4960256,  5505024,  5894144,
+    6004736,  6193152,  6385664,  6795264,  7114752,  7233536,  7348224,
+    7499776,  7573504,  7729152,  8634368,  8937472,  9465856,  10354688,
+    10682368, 11059200, 11460608, 13168640, 13176832, 14336000, 15028224,
+    15597568, 15892480, 16773120};
+
+
+// ARM64 flag setting data processing instructions.
+static const MachInst2 kDPFlagSetInstructions[] = {
+    {&RawMachineAssembler::Word32And, "Word32And", kArm64Tst32, kMachInt32},
+    {&RawMachineAssembler::Int32Add, "Int32Add", kArm64Cmn32, kMachInt32},
+    {&RawMachineAssembler::Int32Sub, "Int32Sub", kArm64Cmp32, kMachInt32},
+    {&RawMachineAssembler::Word64And, "Word64And", kArm64Tst, kMachInt64}};
+
+
+// ARM64 arithmetic with overflow instructions.
+static const MachInst2 kOvfAddSubInstructions[] = {
+    {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow",
+     kArm64Add32, kMachInt32},
+    {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow",
+     kArm64Sub32, kMachInt32}};
+
+
+// ARM64 shift instructions.
+static const Shift kShiftInstructions[] = {
+    {{&RawMachineAssembler::Word32Shl, "Word32Shl", kArm64Lsl32, kMachInt32},
+     kMode_Operand2_R_LSL_I},
+    {{&RawMachineAssembler::Word64Shl, "Word64Shl", kArm64Lsl, kMachInt64},
+     kMode_Operand2_R_LSL_I},
+    {{&RawMachineAssembler::Word32Shr, "Word32Shr", kArm64Lsr32, kMachInt32},
+     kMode_Operand2_R_LSR_I},
+    {{&RawMachineAssembler::Word64Shr, "Word64Shr", kArm64Lsr, kMachInt64},
+     kMode_Operand2_R_LSR_I},
+    {{&RawMachineAssembler::Word32Sar, "Word32Sar", kArm64Asr32, kMachInt32},
+     kMode_Operand2_R_ASR_I},
+    {{&RawMachineAssembler::Word64Sar, "Word64Sar", kArm64Asr, kMachInt64},
+     kMode_Operand2_R_ASR_I},
+    {{&RawMachineAssembler::Word32Ror, "Word32Ror", kArm64Ror32, kMachInt32},
+     kMode_Operand2_R_ROR_I},
+    {{&RawMachineAssembler::Word64Ror, "Word64Ror", kArm64Ror, kMachInt64},
+     kMode_Operand2_R_ROR_I}};
+
+
+// ARM64 Mul/Div instructions.
+static const MachInst2 kMulDivInstructions[] = {
+    {&RawMachineAssembler::Int32Mul, "Int32Mul", kArm64Mul32, kMachInt32},
+    {&RawMachineAssembler::Int64Mul, "Int64Mul", kArm64Mul, kMachInt64},
+    {&RawMachineAssembler::Int32Div, "Int32Div", kArm64Idiv32, kMachInt32},
+    {&RawMachineAssembler::Int64Div, "Int64Div", kArm64Idiv, kMachInt64},
+    {&RawMachineAssembler::Uint32Div, "Uint32Div", kArm64Udiv32, kMachInt32},
+    {&RawMachineAssembler::Uint64Div, "Uint64Div", kArm64Udiv, kMachInt64}};
+
+
+// ARM64 FP arithmetic instructions.
+static const MachInst2 kFPArithInstructions[] = {
+    {&RawMachineAssembler::Float64Add, "Float64Add", kArm64Float64Add,
+     kMachFloat64},
+    {&RawMachineAssembler::Float64Sub, "Float64Sub", kArm64Float64Sub,
+     kMachFloat64},
+    {&RawMachineAssembler::Float64Mul, "Float64Mul", kArm64Float64Mul,
+     kMachFloat64},
+    {&RawMachineAssembler::Float64Div, "Float64Div", kArm64Float64Div,
+     kMachFloat64}};
+
+
+struct FPCmp {
+  MachInst2 mi;
+  FlagsCondition cond;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const FPCmp& cmp) {
+  return os << cmp.mi;
+}
+
+
+// ARM64 FP comparison instructions.
+static const FPCmp kFPCmpInstructions[] = {
+    {{&RawMachineAssembler::Float64Equal, "Float64Equal", kArm64Float64Cmp,
+      kMachFloat64},
+     kUnorderedEqual},
+    {{&RawMachineAssembler::Float64LessThan, "Float64LessThan",
+      kArm64Float64Cmp, kMachFloat64},
+     kUnorderedLessThan},
+    {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
+      kArm64Float64Cmp, kMachFloat64},
+     kUnorderedLessThanOrEqual}};
+
+
+struct Conversion {
+  // The machine_type field in MachInst1 represents the destination type.
+  MachInst1 mi;
+  MachineType src_machine_type;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const Conversion& conv) {
+  return os << conv.mi;
+}
+
+
+// ARM64 type conversion instructions.
+static const Conversion kConversionInstructions[] = {
+    {{&RawMachineAssembler::ChangeFloat32ToFloat64, "ChangeFloat32ToFloat64",
+      kArm64Float32ToFloat64, kMachFloat64},
+     kMachFloat32},
+    {{&RawMachineAssembler::TruncateFloat64ToFloat32,
+      "TruncateFloat64ToFloat32", kArm64Float64ToFloat32, kMachFloat32},
+     kMachFloat64},
+    {{&RawMachineAssembler::ChangeInt32ToInt64, "ChangeInt32ToInt64",
+      kArm64Sxtw, kMachInt64},
+     kMachInt32},
+    {{&RawMachineAssembler::ChangeUint32ToUint64, "ChangeUint32ToUint64",
+      kArm64Mov32, kMachUint64},
+     kMachUint32},
+    {{&RawMachineAssembler::TruncateInt64ToInt32, "TruncateInt64ToInt32",
+      kArm64Mov32, kMachInt32},
+     kMachInt64},
+    {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64",
+      kArm64Int32ToFloat64, kMachFloat64},
+     kMachInt32},
+    {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64",
+      kArm64Uint32ToFloat64, kMachFloat64},
+     kMachUint32},
+    {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32",
+      kArm64Float64ToInt32, kMachInt32},
+     kMachFloat64},
+    {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32",
+      kArm64Float64ToUint32, kMachUint32},
+     kMachFloat64}};
+
+}  // namespace
+
+
+// -----------------------------------------------------------------------------
+// Logical instructions.
+
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorLogicalTest;
+
+
+TEST_P(InstructionSelectorLogicalTest, Parameter) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorLogicalTest, Immediate) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  // TODO(all): Add support for testing 64-bit immediates.
+  if (type == kMachInt32) {
+    // Immediate on the right.
+    TRACED_FOREACH(int32_t, imm, kLogical32Immediates) {
+      StreamBuilder m(this, type, type);
+      m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+      ASSERT_EQ(2U, s[0]->InputCount());
+      EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+
+    // Immediate on the left; all logical ops should commute.
+    TRACED_FOREACH(int32_t, imm, kLogical32Immediates) {
+      StreamBuilder m(this, type, type);
+      m.Return((m.*dpi.constructor)(m.Int32Constant(imm), m.Parameter(0)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+      ASSERT_EQ(2U, s[0]->InputCount());
+      EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+}
+
+
+TEST_P(InstructionSelectorLogicalTest, ShiftByImmediate) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  TRACED_FOREACH(Shift, shift, kShiftInstructions) {
+    // Only test 64-bit shifted operands with 64-bit instructions.
+    if (shift.mi.machine_type != type) continue;
+
+    TRACED_FORRANGE(int, imm, 0, ((type == kMachInt32) ? 31 : 63)) {
+      StreamBuilder m(this, type, type, type);
+      m.Return((m.*dpi.constructor)(
+          m.Parameter(0),
+          (m.*shift.mi.constructor)(m.Parameter(1),
+                                    BuildConstant(m, type, imm))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.mode, s[0]->addressing_mode());
+      EXPECT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+
+    TRACED_FORRANGE(int, imm, 0, ((type == kMachInt32) ? 31 : 63)) {
+      StreamBuilder m(this, type, type, type);
+      m.Return((m.*dpi.constructor)(
+          (m.*shift.mi.constructor)(m.Parameter(1),
+                                    BuildConstant(m, type, imm)),
+          m.Parameter(0)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.mode, s[0]->addressing_mode());
+      EXPECT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest,
+                        ::testing::ValuesIn(kLogicalInstructions));
+
+
+// -----------------------------------------------------------------------------
+// Add and Sub instructions.
+
+typedef InstructionSelectorTestWithParam<AddSub> InstructionSelectorAddSubTest;
+
+
+TEST_P(InstructionSelectorAddSubTest, Parameter) {
+  const AddSub dpi = GetParam();
+  const MachineType type = dpi.mi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*dpi.mi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorAddSubTest, ImmediateOnRight) {
+  const AddSub dpi = GetParam();
+  const MachineType type = dpi.mi.machine_type;
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    StreamBuilder m(this, type, type);
+    m.Return(
+        (m.*dpi.mi.constructor)(m.Parameter(0), BuildConstant(m, type, imm)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+    EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorAddSubTest, NegImmediateOnRight) {
+  const AddSub dpi = GetParam();
+  const MachineType type = dpi.mi.machine_type;
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    if (imm == 0) continue;
+    StreamBuilder m(this, type, type);
+    m.Return(
+        (m.*dpi.mi.constructor)(m.Parameter(0), BuildConstant(m, type, -imm)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.negate_arch_opcode, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorAddSubTest, ShiftByImmediateOnRight) {
+  const AddSub dpi = GetParam();
+  const MachineType type = dpi.mi.machine_type;
+  TRACED_FOREACH(Shift, shift, kShiftInstructions) {
+    // Only test 64-bit shifted operands with 64-bit instructions.
+    if (shift.mi.machine_type != type) continue;
+
+    if ((shift.mi.arch_opcode == kArm64Ror32) ||
+        (shift.mi.arch_opcode == kArm64Ror)) {
+      // Not supported by add/sub instructions.
+      continue;
+    }
+
+    TRACED_FORRANGE(int, imm, 0, ((type == kMachInt32) ? 31 : 63)) {
+      StreamBuilder m(this, type, type, type);
+      m.Return((m.*dpi.mi.constructor)(
+          m.Parameter(0),
+          (m.*shift.mi.constructor)(m.Parameter(1),
+                                    BuildConstant(m, type, imm))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(dpi.mi.arch_opcode, s[0]->arch_opcode());
+      EXPECT_EQ(shift.mode, s[0]->addressing_mode());
+      EXPECT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorAddSubTest,
+                        ::testing::ValuesIn(kAddSubInstructions));
+
+
+TEST_F(InstructionSelectorTest, AddImmediateOnLeft) {
+  {
+    // 32-bit add.
+    TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
+      ASSERT_EQ(2U, s[0]->InputCount());
+      EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+  {
+    // 64-bit add.
+    TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+      StreamBuilder m(this, kMachInt64, kMachInt64);
+      m.Return(m.Int64Add(m.Int64Constant(imm), m.Parameter(0)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
+      ASSERT_EQ(2U, s[0]->InputCount());
+      EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+      EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, SubZeroOnLeft) {
+  // Subtraction with zero on the left maps to Neg.
+  {
+    // 32-bit subtract.
+    StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+    m.Return(m.Int32Sub(m.Int32Constant(0), m.Parameter(0)));
+    Stream s = m.Build();
+
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Neg32, s[0]->arch_opcode());
+    EXPECT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  {
+    // 64-bit subtract.
+    StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
+    m.Return(m.Int64Sub(m.Int64Constant(0), m.Parameter(0)));
+    Stream s = m.Build();
+
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Neg, s[0]->arch_opcode());
+    EXPECT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, AddNegImmediateOnLeft) {
+  {
+    // 32-bit add.
+    TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+      if (imm == 0) continue;
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Int32Add(m.Int32Constant(-imm), m.Parameter(0)));
+      Stream s = m.Build();
+
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Sub32, s[0]->arch_opcode());
+      ASSERT_EQ(2U, s[0]->InputCount());
+      ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate());
+      EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+  {
+    // 64-bit add.
+    TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+      if (imm == 0) continue;
+      StreamBuilder m(this, kMachInt64, kMachInt64);
+      m.Return(m.Int64Add(m.Int64Constant(-imm), m.Parameter(0)));
+      Stream s = m.Build();
+
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Sub, s[0]->arch_opcode());
+      ASSERT_EQ(2U, s[0]->InputCount());
+      ASSERT_TRUE(s[0]->InputAt(1)->IsImmediate());
+      EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, AddShiftByImmediateOnLeft) {
+  // 32-bit add.
+  TRACED_FOREACH(Shift, shift, kShiftInstructions) {
+    // Only test relevant shifted operands.
+    if (shift.mi.machine_type != kMachInt32) continue;
+    if (shift.mi.arch_opcode == kArm64Ror32) continue;
+
+    TRACED_FORRANGE(int, imm, 0, 31) {
+      StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+      m.Return((m.Int32Add)(
+          (m.*shift.mi.constructor)(m.Parameter(1), m.Int32Constant(imm)),
+          m.Parameter(0)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
+      EXPECT_EQ(shift.mode, s[0]->addressing_mode());
+      EXPECT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+
+  // 64-bit add.
+  TRACED_FOREACH(Shift, shift, kShiftInstructions) {
+    // Only test relevant shifted operands.
+    if (shift.mi.machine_type != kMachInt64) continue;
+    if (shift.mi.arch_opcode == kArm64Ror) continue;
+
+    TRACED_FORRANGE(int, imm, 0, 63) {
+      StreamBuilder m(this, kMachInt64, kMachInt64, kMachInt64);
+      m.Return((m.Int64Add)(
+          (m.*shift.mi.constructor)(m.Parameter(1), m.Int64Constant(imm)),
+          m.Parameter(0)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
+      EXPECT_EQ(shift.mode, s[0]->addressing_mode());
+      EXPECT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(2)));
+      EXPECT_EQ(1U, s[0]->OutputCount());
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Data processing controlled branches.
+
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorDPFlagSetTest;
+
+
+TEST_P(InstructionSelectorDPFlagSetTest, BranchWithParameters) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  MLabel a, b;
+  m.Branch((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)), &a, &b);
+  m.Bind(&a);
+  m.Return(m.Int32Constant(1));
+  m.Bind(&b);
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorDPFlagSetTest,
+                        ::testing::ValuesIn(kDPFlagSetInstructions));
+
+
+TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnRight) {
+  TRACED_FOREACH(int32_t, imm, kLogical32Immediates) {
+    // Skip the cases where the instruction selector would use tbz/tbnz.
+    if (base::bits::CountPopulation32(imm) == 1) continue;
+
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(imm)), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
+    EXPECT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnRight) {
+  TRACED_FOREACH(int64_t, imm, kLogical64Immediates) {
+    // Skip the cases where the instruction selector would use tbz/tbnz.
+    if (base::bits::CountPopulation64(imm) == 1) continue;
+
+    StreamBuilder m(this, kMachInt64, kMachInt64);
+    MLabel a, b;
+    m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(imm)), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
+    EXPECT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnRight) {
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(m.Int32Add(m.Parameter(0), m.Int32Constant(imm)), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, SubBranchWithImmediateOnRight) {
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm)), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnLeft) {
+  TRACED_FOREACH(int32_t, imm, kLogical32Immediates) {
+    // Skip the cases where the instruction selector would use tbz/tbnz.
+    if (base::bits::CountPopulation32(imm) == 1) continue;
+
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(m.Word32And(m.Int32Constant(imm), m.Parameter(0)), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
+    EXPECT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    ASSERT_LE(1U, s[0]->InputCount());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnLeft) {
+  TRACED_FOREACH(int64_t, imm, kLogical64Immediates) {
+    // Skip the cases where the instruction selector would use tbz/tbnz.
+    if (base::bits::CountPopulation64(imm) == 1) continue;
+
+    StreamBuilder m(this, kMachInt64, kMachInt64);
+    MLabel a, b;
+    m.Branch(m.Word64And(m.Int64Constant(imm), m.Parameter(0)), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
+    EXPECT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    ASSERT_LE(1U, s[0]->InputCount());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, AddBranchWithImmediateOnLeft) {
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode());
+    ASSERT_LE(1U, s[0]->InputCount());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnRight) {
+  TRACED_FORRANGE(int, bit, 0, 31) {
+    uint32_t mask = 1 << bit;
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(mask)), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+    EXPECT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1)));
+  }
+
+  TRACED_FORRANGE(int, bit, 0, 31) {
+    uint32_t mask = 1 << bit;
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(
+        m.Word32BinaryNot(m.Word32And(m.Parameter(0), m.Int32Constant(mask))),
+        &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+    EXPECT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1)));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnLeft) {
+  TRACED_FORRANGE(int, bit, 0, 31) {
+    uint32_t mask = 1 << bit;
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(m.Word32And(m.Int32Constant(mask), m.Parameter(0)), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+    EXPECT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1)));
+  }
+
+  TRACED_FORRANGE(int, bit, 0, 31) {
+    uint32_t mask = 1 << bit;
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    m.Branch(
+        m.Word32BinaryNot(m.Word32And(m.Int32Constant(mask), m.Parameter(0))),
+        &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+    EXPECT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1)));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnRight) {
+  TRACED_FORRANGE(int, bit, 0, 63) {
+    uint64_t mask = 1L << bit;
+    StreamBuilder m(this, kMachInt64, kMachInt64);
+    MLabel a, b;
+    m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(mask)), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+    EXPECT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1)));
+  }
+
+  TRACED_FORRANGE(int, bit, 0, 63) {
+    uint64_t mask = 1L << bit;
+    StreamBuilder m(this, kMachInt64, kMachInt64);
+    MLabel a, b;
+    m.Branch(
+        m.Word64BinaryNot(m.Word64And(m.Parameter(0), m.Int64Constant(mask))),
+        &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+    EXPECT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1)));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnLeft) {
+  TRACED_FORRANGE(int, bit, 0, 63) {
+    uint64_t mask = 1L << bit;
+    StreamBuilder m(this, kMachInt64, kMachInt64);
+    MLabel a, b;
+    m.Branch(m.Word64And(m.Int64Constant(mask), m.Parameter(0)), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+    EXPECT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1)));
+  }
+
+  TRACED_FORRANGE(int, bit, 0, 63) {
+    uint64_t mask = 1L << bit;
+    StreamBuilder m(this, kMachInt64, kMachInt64);
+    MLabel a, b;
+    m.Branch(
+        m.Word64BinaryNot(m.Word64And(m.Int64Constant(mask), m.Parameter(0))),
+        &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+    EXPECT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1)));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, CompareAgainstZeroAndBranch) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    Node* p0 = m.Parameter(0);
+    m.Branch(p0, &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode());
+    EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  }
+
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    Node* p0 = m.Parameter(0);
+    m.Branch(m.Word32BinaryNot(p0), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(1));
+    m.Bind(&b);
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Add and subtract instructions with overflow.
+
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorOvfAddSubTest;
+
+
+TEST_P(InstructionSelectorOvfAddSubTest, OvfParameter) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return(
+      m.Projection(1, (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_LE(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(kOverflow, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorOvfAddSubTest, OvfImmediateOnRight) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    StreamBuilder m(this, type, type);
+    m.Return(m.Projection(
+        1, (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorOvfAddSubTest, ValParameter) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return(
+      m.Projection(0, (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1))));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_LE(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+}
+
+
+TEST_P(InstructionSelectorOvfAddSubTest, ValImmediateOnRight) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    StreamBuilder m(this, type, type);
+    m.Return(m.Projection(
+        0, (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm))));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+}
+
+
+TEST_P(InstructionSelectorOvfAddSubTest, BothParameter) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1));
+  m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+  Stream s = m.Build();
+  ASSERT_LE(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(2U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(kOverflow, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorOvfAddSubTest, BothImmediateOnRight) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    StreamBuilder m(this, type, type);
+    Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
+    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+    Stream s = m.Build();
+    ASSERT_LE(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(2U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_P(InstructionSelectorOvfAddSubTest, BranchWithParameters) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  MLabel a, b;
+  Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Parameter(1));
+  m.Branch(m.Projection(1, n), &a, &b);
+  m.Bind(&a);
+  m.Return(m.Int32Constant(0));
+  m.Bind(&b);
+  m.Return(m.Projection(0, n));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(4U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+  EXPECT_EQ(kOverflow, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorOvfAddSubTest, BranchWithImmediateOnRight) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    StreamBuilder m(this, type, type);
+    MLabel a, b;
+    Node* n = (m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm));
+    m.Branch(m.Projection(1, n), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(0));
+    m.Bind(&b);
+    m.Return(m.Projection(0, n));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+    ASSERT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorOvfAddSubTest,
+                        ::testing::ValuesIn(kOvfAddSubInstructions));
+
+
+TEST_F(InstructionSelectorTest, OvfFlagAddImmediateOnLeft) {
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Projection(
+        1, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0))));
+    Stream s = m.Build();
+
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, OvfValAddImmediateOnLeft) {
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Projection(
+        0, m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0))));
+    Stream s = m.Build();
+
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_LE(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_none, s[0]->flags_mode());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, OvfBothAddImmediateOnLeft) {
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0));
+    m.Return(m.Word32Equal(m.Projection(0, n), m.Projection(1, n)));
+    Stream s = m.Build();
+
+    ASSERT_LE(1U, s.size());
+    EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(2U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, OvfBranchWithImmediateOnLeft) {
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    MLabel a, b;
+    Node* n = m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0));
+    m.Branch(m.Projection(1, n), &a, &b);
+    m.Bind(&a);
+    m.Return(m.Int32Constant(0));
+    m.Bind(&b);
+    m.Return(m.Projection(0, n));
+    Stream s = m.Build();
+
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Add32, s[0]->arch_opcode());
+    ASSERT_EQ(4U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
+    EXPECT_EQ(kOverflow, s[0]->flags_condition());
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Shift instructions.
+
+
+typedef InstructionSelectorTestWithParam<Shift> InstructionSelectorShiftTest;
+
+
+TEST_P(InstructionSelectorShiftTest, Parameter) {
+  const Shift shift = GetParam();
+  const MachineType type = shift.mi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*shift.mi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(shift.mi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorShiftTest, Immediate) {
+  const Shift shift = GetParam();
+  const MachineType type = shift.mi.machine_type;
+  TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) {
+    StreamBuilder m(this, type, type);
+    m.Return((m.*shift.mi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(shift.mi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
+                        ::testing::ValuesIn(kShiftInstructions));
+
+
+TEST_F(InstructionSelectorTest, Word64ShlWithChangeInt32ToInt64) {
+  TRACED_FORRANGE(int64_t, x, 32, 63) {
+    StreamBuilder m(this, kMachInt64, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Word64Shl(m.ChangeInt32ToInt64(p0), m.Int64Constant(x));
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Lsl, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word64ShlWithChangeUint32ToUint64) {
+  TRACED_FORRANGE(int64_t, x, 32, 63) {
+    StreamBuilder m(this, kMachInt64, kMachUint32);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Word64Shl(m.ChangeUint32ToUint64(p0), m.Int64Constant(x));
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Lsl, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Sar) {
+  StreamBuilder m(this, kMachInt32, kMachInt64);
+  Node* const p = m.Parameter(0);
+  Node* const t = m.TruncateInt64ToInt32(m.Word64Sar(p, m.Int64Constant(32)));
+  m.Return(t);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArm64Lsr, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(32, s.ToInt64(s[0]->InputAt(1)));
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0)));
+}
+
+
+TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Shr) {
+  TRACED_FORRANGE(int64_t, x, 32, 63) {
+    StreamBuilder m(this, kMachInt32, kMachInt64);
+    Node* const p = m.Parameter(0);
+    Node* const t = m.TruncateInt64ToInt32(m.Word64Shr(p, m.Int64Constant(x)));
+    m.Return(t);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Lsr, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(x, s.ToInt64(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0)));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Mul and Div instructions.
+
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorMulDivTest;
+
+
+TEST_P(InstructionSelectorMulDivTest, Parameter) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMulDivTest,
+                        ::testing::ValuesIn(kMulDivInstructions));
+
+
+namespace {
+
+struct MulDPInst {
+  const char* mul_constructor_name;
+  Node* (RawMachineAssembler::*mul_constructor)(Node*, Node*);
+  Node* (RawMachineAssembler::*add_constructor)(Node*, Node*);
+  Node* (RawMachineAssembler::*sub_constructor)(Node*, Node*);
+  ArchOpcode add_arch_opcode;
+  ArchOpcode sub_arch_opcode;
+  ArchOpcode neg_arch_opcode;
+  MachineType machine_type;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MulDPInst& inst) {
+  return os << inst.mul_constructor_name;
+}
+
+}  // namespace
+
+
+static const MulDPInst kMulDPInstructions[] = {
+    {"Int32Mul", &RawMachineAssembler::Int32Mul, &RawMachineAssembler::Int32Add,
+     &RawMachineAssembler::Int32Sub, kArm64Madd32, kArm64Msub32, kArm64Mneg32,
+     kMachInt32},
+    {"Int64Mul", &RawMachineAssembler::Int64Mul, &RawMachineAssembler::Int64Add,
+     &RawMachineAssembler::Int64Sub, kArm64Madd, kArm64Msub, kArm64Mneg,
+     kMachInt64}};
+
+
+typedef InstructionSelectorTestWithParam<MulDPInst>
+    InstructionSelectorIntDPWithIntMulTest;
+
+
+TEST_P(InstructionSelectorIntDPWithIntMulTest, AddWithMul) {
+  const MulDPInst mdpi = GetParam();
+  const MachineType type = mdpi.machine_type;
+  {
+    StreamBuilder m(this, type, type, type, type);
+    Node* n = (m.*mdpi.mul_constructor)(m.Parameter(1), m.Parameter(2));
+    m.Return((m.*mdpi.add_constructor)(m.Parameter(0), n));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(mdpi.add_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  {
+    StreamBuilder m(this, type, type, type, type);
+    Node* n = (m.*mdpi.mul_constructor)(m.Parameter(0), m.Parameter(1));
+    m.Return((m.*mdpi.add_constructor)(n, m.Parameter(2)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(mdpi.add_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorIntDPWithIntMulTest, SubWithMul) {
+  const MulDPInst mdpi = GetParam();
+  const MachineType type = mdpi.machine_type;
+  {
+    StreamBuilder m(this, type, type, type, type);
+    Node* n = (m.*mdpi.mul_constructor)(m.Parameter(1), m.Parameter(2));
+    m.Return((m.*mdpi.sub_constructor)(m.Parameter(0), n));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(mdpi.sub_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(3U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorIntDPWithIntMulTest, NegativeMul) {
+  const MulDPInst mdpi = GetParam();
+  const MachineType type = mdpi.machine_type;
+  {
+    StreamBuilder m(this, type, type, type);
+    Node* n =
+        (m.*mdpi.sub_constructor)(BuildConstant(m, type, 0), m.Parameter(0));
+    m.Return((m.*mdpi.mul_constructor)(n, m.Parameter(1)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(mdpi.neg_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  {
+    StreamBuilder m(this, type, type, type);
+    Node* n =
+        (m.*mdpi.sub_constructor)(BuildConstant(m, type, 0), m.Parameter(1));
+    m.Return((m.*mdpi.mul_constructor)(m.Parameter(0), n));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(mdpi.neg_arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorIntDPWithIntMulTest,
+                        ::testing::ValuesIn(kMulDPInstructions));
+
+
+// -----------------------------------------------------------------------------
+// Floating point instructions.
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorFPArithTest;
+
+
+TEST_P(InstructionSelectorFPArithTest, Parameter) {
+  const MachInst2 fpa = GetParam();
+  StreamBuilder m(this, fpa.machine_type, fpa.machine_type, fpa.machine_type);
+  m.Return((m.*fpa.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(fpa.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest,
+                        ::testing::ValuesIn(kFPArithInstructions));
+
+
+typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest;
+
+
+TEST_P(InstructionSelectorFPCmpTest, Parameter) {
+  const FPCmp cmp = GetParam();
+  StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type);
+  m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(cmp.cond, s[0]->flags_condition());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPCmpTest,
+                        ::testing::ValuesIn(kFPCmpInstructions));
+
+
+// -----------------------------------------------------------------------------
+// Conversions.
+
+typedef InstructionSelectorTestWithParam<Conversion>
+    InstructionSelectorConversionTest;
+
+
+TEST_P(InstructionSelectorConversionTest, Parameter) {
+  const Conversion conv = GetParam();
+  StreamBuilder m(this, conv.mi.machine_type, conv.src_machine_type);
+  m.Return((m.*conv.mi.constructor)(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(conv.mi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorConversionTest,
+                        ::testing::ValuesIn(kConversionInstructions));
+
+
+// -----------------------------------------------------------------------------
+// Memory access instructions.
+
+
+namespace {
+
+struct MemoryAccess {
+  MachineType type;
+  ArchOpcode ldr_opcode;
+  ArchOpcode str_opcode;
+  const int32_t immediates[20];
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
+  return os << memacc.type;
+}
+
+}  // namespace
+
+
+static const MemoryAccess kMemoryAccesses[] = {
+    {kMachInt8,
+     kArm64Ldrsb,
+     kArm64Strb,
+     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001, 2121,
+      2442, 4093, 4094, 4095}},
+    {kMachUint8,
+     kArm64Ldrb,
+     kArm64Strb,
+     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 257, 258, 1000, 1001, 2121,
+      2442, 4093, 4094, 4095}},
+    {kMachInt16,
+     kArm64Ldrsh,
+     kArm64Strh,
+     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098, 4100,
+      4242, 6786, 8188, 8190}},
+    {kMachUint16,
+     kArm64Ldrh,
+     kArm64Strh,
+     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 258, 260, 4096, 4098, 4100,
+      4242, 6786, 8188, 8190}},
+    {kMachInt32,
+     kArm64LdrW,
+     kArm64StrW,
+     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196,
+      3276, 3280, 16376, 16380}},
+    {kMachUint32,
+     kArm64LdrW,
+     kArm64StrW,
+     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196,
+      3276, 3280, 16376, 16380}},
+    {kMachInt64,
+     kArm64Ldr,
+     kArm64Str,
+     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200,
+      16384, 16392, 32752, 32760}},
+    {kMachUint64,
+     kArm64Ldr,
+     kArm64Str,
+     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200,
+      16384, 16392, 32752, 32760}},
+    {kMachFloat32,
+     kArm64LdrS,
+     kArm64StrS,
+     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 260, 4096, 4100, 8192, 8196,
+      3276, 3280, 16376, 16380}},
+    {kMachFloat64,
+     kArm64LdrD,
+     kArm64StrD,
+     {-256, -255, -3, -2, -1, 0, 1, 2, 3, 255, 256, 264, 4096, 4104, 8192, 8200,
+      16384, 16392, 32752, 32760}}};
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccess>
+    InstructionSelectorMemoryAccessTest;
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
+  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRR, s[0]->addressing_mode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, memacc.type, kMachPtr);
+    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.ldr_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
+  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRR, s[0]->addressing_mode());
+  EXPECT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(0U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
+    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
+            m.Parameter(1));
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.str_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(0U, s[0]->OutputCount());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessTest,
+                        ::testing::ValuesIn(kMemoryAccesses));
+
+
+// -----------------------------------------------------------------------------
+// Comparison instructions.
+
+static const MachInst2 kComparisonInstructions[] = {
+    {&RawMachineAssembler::Word32Equal, "Word32Equal", kArm64Cmp32, kMachInt32},
+    {&RawMachineAssembler::Word64Equal, "Word64Equal", kArm64Cmp, kMachInt64},
+};
+
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorComparisonTest;
+
+
+TEST_P(InstructionSelectorComparisonTest, WithParameters) {
+  const MachInst2 cmp = GetParam();
+  const MachineType type = cmp.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*cmp.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(kEqual, s[0]->flags_condition());
+}
+
+
+TEST_P(InstructionSelectorComparisonTest, WithImmediate) {
+  const MachInst2 cmp = GetParam();
+  const MachineType type = cmp.machine_type;
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    // Compare with 0 are turned into tst instruction.
+    if (imm == 0) continue;
+    StreamBuilder m(this, type, type);
+    m.Return((m.*cmp.constructor)(m.Parameter(0), BuildConstant(m, type, imm)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+  TRACED_FOREACH(int32_t, imm, kAddSubImmediates) {
+    // Compare with 0 are turned into tst instruction.
+    if (imm == 0) continue;
+    StreamBuilder m(this, type, type);
+    m.Return((m.*cmp.constructor)(BuildConstant(m, type, imm), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(cmp.arch_opcode, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(imm, s.ToInt64(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorComparisonTest,
+                        ::testing::ValuesIn(kComparisonInstructions));
+
+
+TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word64EqualWithZero) {
+  {
+    StreamBuilder m(this, kMachInt64, kMachInt64);
+    m.Return(m.Word64Equal(m.Parameter(0), m.Int64Constant(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+  {
+    StreamBuilder m(this, kMachInt64, kMachInt64);
+    m.Return(m.Word64Equal(m.Int64Constant(0), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Miscellaneous
+
+
+static const MachInst2 kLogicalWithNotRHSs[] = {
+    {&RawMachineAssembler::Word32And, "Word32And", kArm64Bic32, kMachInt32},
+    {&RawMachineAssembler::Word64And, "Word64And", kArm64Bic, kMachInt64},
+    {&RawMachineAssembler::Word32Or, "Word32Or", kArm64Orn32, kMachInt32},
+    {&RawMachineAssembler::Word64Or, "Word64Or", kArm64Orn, kMachInt64},
+    {&RawMachineAssembler::Word32Xor, "Word32Xor", kArm64Eon32, kMachInt32},
+    {&RawMachineAssembler::Word64Xor, "Word64Xor", kArm64Eon, kMachInt64}};
+
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorLogicalWithNotRHSTest;
+
+
+TEST_P(InstructionSelectorLogicalWithNotRHSTest, Parameter) {
+  const MachInst2 inst = GetParam();
+  const MachineType type = inst.machine_type;
+  // Test cases where RHS is Xor(x, -1).
+  {
+    StreamBuilder m(this, type, type, type);
+    if (type == kMachInt32) {
+      m.Return((m.*inst.constructor)(
+          m.Parameter(0), m.Word32Xor(m.Parameter(1), m.Int32Constant(-1))));
+    } else {
+      ASSERT_EQ(kMachInt64, type);
+      m.Return((m.*inst.constructor)(
+          m.Parameter(0), m.Word64Xor(m.Parameter(1), m.Int64Constant(-1))));
+    }
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  {
+    StreamBuilder m(this, type, type, type);
+    if (type == kMachInt32) {
+      m.Return((m.*inst.constructor)(
+          m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)), m.Parameter(1)));
+    } else {
+      ASSERT_EQ(kMachInt64, type);
+      m.Return((m.*inst.constructor)(
+          m.Word64Xor(m.Parameter(0), m.Int64Constant(-1)), m.Parameter(1)));
+    }
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  // Test cases where RHS is Not(x).
+  {
+    StreamBuilder m(this, type, type, type);
+    if (type == kMachInt32) {
+      m.Return(
+          (m.*inst.constructor)(m.Parameter(0), m.Word32Not(m.Parameter(1))));
+    } else {
+      ASSERT_EQ(kMachInt64, type);
+      m.Return(
+          (m.*inst.constructor)(m.Parameter(0), m.Word64Not(m.Parameter(1))));
+    }
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  {
+    StreamBuilder m(this, type, type, type);
+    if (type == kMachInt32) {
+      m.Return(
+          (m.*inst.constructor)(m.Word32Not(m.Parameter(0)), m.Parameter(1)));
+    } else {
+      ASSERT_EQ(kMachInt64, type);
+      m.Return(
+          (m.*inst.constructor)(m.Word64Not(m.Parameter(0)), m.Parameter(1)));
+    }
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(inst.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorLogicalWithNotRHSTest,
+                        ::testing::ValuesIn(kLogicalWithNotRHSs));
+
+
+TEST_F(InstructionSelectorTest, Word32NotWithParameter) {
+  StreamBuilder m(this, kMachInt32, kMachInt32);
+  m.Return(m.Word32Not(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArm64Not32, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_F(InstructionSelectorTest, Word64NotWithParameter) {
+  StreamBuilder m(this, kMachInt64, kMachInt64);
+  m.Return(m.Word64Not(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kArm64Not, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_F(InstructionSelectorTest, Word32XorMinusOneWithParameter) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Xor(m.Parameter(0), m.Int32Constant(-1)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Not32, s[0]->arch_opcode());
+    EXPECT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Xor(m.Int32Constant(-1), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Not32, s[0]->arch_opcode());
+    EXPECT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word64XorMinusOneWithParameter) {
+  {
+    StreamBuilder m(this, kMachInt64, kMachInt64);
+    m.Return(m.Word64Xor(m.Parameter(0), m.Int64Constant(-1)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Not, s[0]->arch_opcode());
+    EXPECT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+  {
+    StreamBuilder m(this, kMachInt64, kMachInt64);
+    m.Return(m.Word64Xor(m.Int64Constant(-1), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Not, s[0]->arch_opcode());
+    EXPECT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32ShrWithWord32AndWithImmediate) {
+  TRACED_FORRANGE(int32_t, lsb, 1, 31) {
+    TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
+      uint32_t jnk = rng()->NextInt();
+      jnk >>= 32 - lsb;
+      uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Word32Shr(m.Word32And(m.Parameter(0), m.Int32Constant(msk)),
+                           m.Int32Constant(lsb)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
+      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+    }
+  }
+  TRACED_FORRANGE(int32_t, lsb, 1, 31) {
+    TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) {
+      uint32_t jnk = rng()->NextInt();
+      jnk >>= 32 - lsb;
+      uint32_t msk = ((0xffffffffu >> (32 - width)) << lsb) | jnk;
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Word32Shr(m.Word32And(m.Int32Constant(msk), m.Parameter(0)),
+                           m.Int32Constant(lsb)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
+      EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+    }
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word64ShrWithWord64AndWithImmediate) {
+  TRACED_FORRANGE(int32_t, lsb, 1, 63) {
+    TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) {
+      uint64_t jnk = rng()->NextInt64();
+      jnk >>= 64 - lsb;
+      uint64_t msk =
+          ((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk;
+      StreamBuilder m(this, kMachInt64, kMachInt64);
+      m.Return(m.Word64Shr(m.Word64And(m.Parameter(0), m.Int64Constant(msk)),
+                           m.Int64Constant(lsb)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
+      EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2)));
+    }
+  }
+  TRACED_FORRANGE(int32_t, lsb, 1, 63) {
+    TRACED_FORRANGE(int32_t, width, 1, 64 - lsb) {
+      uint64_t jnk = rng()->NextInt64();
+      jnk >>= 64 - lsb;
+      uint64_t msk =
+          ((V8_UINT64_C(0xffffffffffffffff) >> (64 - width)) << lsb) | jnk;
+      StreamBuilder m(this, kMachInt64, kMachInt64);
+      m.Return(m.Word64Shr(m.Word64And(m.Int64Constant(msk), m.Parameter(0)),
+                           m.Int64Constant(lsb)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
+      EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2)));
+    }
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word32AndWithImmediateWithWord32Shr) {
+  TRACED_FORRANGE(int32_t, lsb, 1, 31) {
+    TRACED_FORRANGE(int32_t, width, 1, 31) {
+      uint32_t msk = (1 << width) - 1;
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)),
+                           m.Int32Constant(msk)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
+      int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width;
+      EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2)));
+    }
+  }
+  TRACED_FORRANGE(int32_t, lsb, 1, 31) {
+    TRACED_FORRANGE(int32_t, width, 1, 31) {
+      uint32_t msk = (1 << width) - 1;
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Word32And(m.Int32Constant(msk),
+                           m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
+      int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width;
+      EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2)));
+    }
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word64AndWithImmediateWithWord64Shr) {
+  TRACED_FORRANGE(int64_t, lsb, 1, 63) {
+    TRACED_FORRANGE(int64_t, width, 1, 63) {
+      uint64_t msk = (V8_UINT64_C(1) << width) - 1;
+      StreamBuilder m(this, kMachInt64, kMachInt64);
+      m.Return(m.Word64And(m.Word64Shr(m.Parameter(0), m.Int64Constant(lsb)),
+                           m.Int64Constant(msk)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
+      int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width;
+      EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2)));
+    }
+  }
+  TRACED_FORRANGE(int64_t, lsb, 1, 63) {
+    TRACED_FORRANGE(int64_t, width, 1, 63) {
+      uint64_t msk = (V8_UINT64_C(1) << width) - 1;
+      StreamBuilder m(this, kMachInt64, kMachInt64);
+      m.Return(m.Word64And(m.Int64Constant(msk),
+                           m.Word64Shr(m.Parameter(0), m.Int64Constant(lsb))));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
+      ASSERT_EQ(3U, s[0]->InputCount());
+      EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
+      int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width;
+      EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2)));
+    }
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Int32MulHighWithParameters) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const n = m.Int32MulHigh(p0, p1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kArm64Smull, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kArm64Asr, s[1]->arch_opcode());
+  ASSERT_EQ(2U, s[1]->InputCount());
+  EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0)));
+  EXPECT_EQ(32, s.ToInt64(s[1]->InputAt(1)));
+  ASSERT_EQ(1U, s[1]->OutputCount());
+  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output()));
+}
+
+
+TEST_F(InstructionSelectorTest, Word32SarWithWord32Shl) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const r =
+        m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(24)), m.Int32Constant(24));
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Sxtb32, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const r =
+        m.Word32Sar(m.Word32Shl(p0, m.Int32Constant(16)), m.Int32Constant(16));
+    m.Return(r);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kArm64Sxth32, s[0]->arch_opcode());
+    ASSERT_EQ(1U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output()));
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/change-lowering-unittest.cc b/test/unittests/compiler/change-lowering-unittest.cc
new file mode 100644
index 0000000..060b1c1
--- /dev/null
+++ b/test/unittests/compiler/change-lowering-unittest.cc
@@ -0,0 +1,463 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/code-stubs.h"
+#include "src/compiler/change-lowering.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/linkage.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/simplified-operator.h"
+#include "test/unittests/compiler/compiler-test-utils.h"
+#include "test/unittests/compiler/graph-unittest.h"
+#include "test/unittests/compiler/node-test-utils.h"
+#include "testing/gmock-support.h"
+
+using testing::_;
+using testing::AllOf;
+using testing::BitEq;
+using testing::Capture;
+using testing::CaptureEq;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class ChangeLoweringTest : public GraphTest {
+ public:
+  ChangeLoweringTest() : simplified_(zone()) {}
+  ~ChangeLoweringTest() OVERRIDE {}
+
+  virtual MachineType WordRepresentation() const = 0;
+
+ protected:
+  int HeapNumberValueOffset() const {
+    STATIC_ASSERT(HeapNumber::kValueOffset % kApiPointerSize == 0);
+    return (HeapNumber::kValueOffset / kApiPointerSize) * PointerSize() -
+           kHeapObjectTag;
+  }
+  bool Is32() const { return WordRepresentation() == kRepWord32; }
+  int PointerSize() const {
+    switch (WordRepresentation()) {
+      case kRepWord32:
+        return 4;
+      case kRepWord64:
+        return 8;
+      default:
+        break;
+    }
+    UNREACHABLE();
+    return 0;
+  }
+  int SmiMaxValue() const { return -(SmiMinValue() + 1); }
+  int SmiMinValue() const {
+    return static_cast<int>(0xffffffffu << (SmiValueSize() - 1));
+  }
+  int SmiShiftAmount() const { return kSmiTagSize + SmiShiftSize(); }
+  int SmiShiftSize() const {
+    return Is32() ? SmiTagging<4>::SmiShiftSize()
+                  : SmiTagging<8>::SmiShiftSize();
+  }
+  int SmiValueSize() const {
+    return Is32() ? SmiTagging<4>::SmiValueSize()
+                  : SmiTagging<8>::SmiValueSize();
+  }
+
+  Reduction Reduce(Node* node) {
+    MachineOperatorBuilder machine(zone(), WordRepresentation());
+    JSOperatorBuilder javascript(zone());
+    JSGraph jsgraph(graph(), common(), &javascript, &machine);
+    CompilationInfo info(isolate(), zone());
+    Linkage linkage(zone(), &info);
+    ChangeLowering reducer(&jsgraph, &linkage);
+    return reducer.Reduce(node);
+  }
+
+  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
+
+  Matcher<Node*> IsAllocateHeapNumber(const Matcher<Node*>& effect_matcher,
+                                      const Matcher<Node*>& control_matcher) {
+    return IsCall(_, IsHeapConstant(Unique<HeapObject>::CreateImmovable(
+                         AllocateHeapNumberStub(isolate()).GetCode())),
+                  IsNumberConstant(BitEq(0.0)), effect_matcher,
+                  control_matcher);
+  }
+  Matcher<Node*> IsLoadHeapNumber(const Matcher<Node*>& value_matcher,
+                                  const Matcher<Node*>& control_matcher) {
+    return IsLoad(kMachFloat64, value_matcher,
+                  IsIntPtrConstant(HeapNumberValueOffset()), graph()->start(),
+                  control_matcher);
+  }
+  Matcher<Node*> IsIntPtrConstant(int value) {
+    return Is32() ? IsInt32Constant(value) : IsInt64Constant(value);
+  }
+  Matcher<Node*> IsWordEqual(const Matcher<Node*>& lhs_matcher,
+                             const Matcher<Node*>& rhs_matcher) {
+    return Is32() ? IsWord32Equal(lhs_matcher, rhs_matcher)
+                  : IsWord64Equal(lhs_matcher, rhs_matcher);
+  }
+
+ private:
+  SimplifiedOperatorBuilder simplified_;
+};
+
+
+// -----------------------------------------------------------------------------
+// Common.
+
+
+class ChangeLoweringCommonTest
+    : public ChangeLoweringTest,
+      public ::testing::WithParamInterface<MachineType> {
+ public:
+  ~ChangeLoweringCommonTest() OVERRIDE {}
+
+  MachineType WordRepresentation() const FINAL { return GetParam(); }
+};
+
+
+TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBitToBool) {
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeBitToBool(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(),
+              IsSelect(static_cast<MachineType>(kTypeBool | kRepTagged), val,
+                       IsTrueConstant(), IsFalseConstant()));
+}
+
+
+TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBoolToBit) {
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeBoolToBit(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  EXPECT_THAT(reduction.replacement(), IsWordEqual(val, IsTrueConstant()));
+}
+
+
+TARGET_TEST_P(ChangeLoweringCommonTest, ChangeFloat64ToTagged) {
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeFloat64ToTagged(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* finish = reduction.replacement();
+  Capture<Node*> heap_number;
+  EXPECT_THAT(
+      finish,
+      IsFinish(
+          AllOf(CaptureEq(&heap_number),
+                IsAllocateHeapNumber(IsValueEffect(val), graph()->start())),
+          IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
+                  CaptureEq(&heap_number),
+                  IsIntPtrConstant(HeapNumberValueOffset()), val,
+                  CaptureEq(&heap_number), graph()->start())));
+}
+
+
+TARGET_TEST_P(ChangeLoweringCommonTest, StringAdd) {
+  Node* node =
+      graph()->NewNode(simplified()->StringAdd(), Parameter(0), Parameter(1));
+  Reduction reduction = Reduce(node);
+  EXPECT_FALSE(reduction.Changed());
+}
+
+
+INSTANTIATE_TEST_CASE_P(ChangeLoweringTest, ChangeLoweringCommonTest,
+                        ::testing::Values(kRepWord32, kRepWord64));
+
+
+// -----------------------------------------------------------------------------
+// 32-bit
+
+
+class ChangeLowering32Test : public ChangeLoweringTest {
+ public:
+  ~ChangeLowering32Test() OVERRIDE {}
+  MachineType WordRepresentation() const FINAL { return kRepWord32; }
+};
+
+
+TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) {
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
+  NodeProperties::SetBounds(val, Bounds(Type::None(), Type::Signed32()));
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* phi = reduction.replacement();
+  Capture<Node*> add, branch, heap_number, if_true;
+  EXPECT_THAT(
+      phi,
+      IsPhi(kMachAnyTagged,
+            IsFinish(AllOf(CaptureEq(&heap_number),
+                           IsAllocateHeapNumber(_, CaptureEq(&if_true))),
+                     IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
+                             CaptureEq(&heap_number),
+                             IsIntPtrConstant(HeapNumberValueOffset()),
+                             IsChangeInt32ToFloat64(val),
+                             CaptureEq(&heap_number), CaptureEq(&if_true))),
+            IsProjection(
+                0, AllOf(CaptureEq(&add), IsInt32AddWithOverflow(val, val))),
+            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
+                    IsIfFalse(AllOf(CaptureEq(&branch),
+                                    IsBranch(IsProjection(1, CaptureEq(&add)),
+                                             graph()->start()))))));
+}
+
+
+TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTaggedSmall) {
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
+  NodeProperties::SetBounds(val, Bounds(Type::None(), Type::SignedSmall()));
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* change = reduction.replacement();
+  Capture<Node*> add, branch, heap_number, if_true;
+  EXPECT_THAT(change, IsWord32Shl(val, IsInt32Constant(SmiShiftAmount())));
+}
+
+
+TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToFloat64) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* phi = reduction.replacement();
+  Capture<Node*> branch, if_true;
+  EXPECT_THAT(
+      phi,
+      IsPhi(
+          kMachFloat64, IsLoadHeapNumber(val, CaptureEq(&if_true)),
+          IsChangeInt32ToFloat64(
+              IsWord32Sar(val, IsInt32Constant(SmiShiftAmount()))),
+          IsMerge(
+              AllOf(CaptureEq(&if_true),
+                    IsIfTrue(AllOf(
+                        CaptureEq(&branch),
+                        IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
+                                 graph()->start())))),
+              IsIfFalse(CaptureEq(&branch)))));
+}
+
+
+TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToInt32) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeTaggedToInt32(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* phi = reduction.replacement();
+  Capture<Node*> branch, if_true;
+  EXPECT_THAT(
+      phi,
+      IsPhi(kMachInt32,
+            IsChangeFloat64ToInt32(IsLoadHeapNumber(val, CaptureEq(&if_true))),
+            IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
+            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
+                    IsIfFalse(AllOf(
+                        CaptureEq(&branch),
+                        IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
+                                 graph()->start()))))));
+}
+
+
+TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToUint32) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* phi = reduction.replacement();
+  Capture<Node*> branch, if_true;
+  EXPECT_THAT(
+      phi,
+      IsPhi(kMachUint32,
+            IsChangeFloat64ToUint32(IsLoadHeapNumber(val, CaptureEq(&if_true))),
+            IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())),
+            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
+                    IsIfFalse(AllOf(
+                        CaptureEq(&branch),
+                        IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
+                                 graph()->start()))))));
+}
+
+
+TARGET_TEST_F(ChangeLowering32Test, ChangeUint32ToTagged) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* phi = reduction.replacement();
+  Capture<Node*> branch, heap_number, if_false;
+  EXPECT_THAT(
+      phi,
+      IsPhi(
+          kMachAnyTagged, IsWord32Shl(val, IsInt32Constant(SmiShiftAmount())),
+          IsFinish(AllOf(CaptureEq(&heap_number),
+                         IsAllocateHeapNumber(_, CaptureEq(&if_false))),
+                   IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
+                           CaptureEq(&heap_number),
+                           IsInt32Constant(HeapNumberValueOffset()),
+                           IsChangeUint32ToFloat64(val),
+                           CaptureEq(&heap_number), CaptureEq(&if_false))),
+          IsMerge(
+              IsIfTrue(AllOf(CaptureEq(&branch),
+                             IsBranch(IsUint32LessThanOrEqual(
+                                          val, IsInt32Constant(SmiMaxValue())),
+                                      graph()->start()))),
+              AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
+}
+
+
+// -----------------------------------------------------------------------------
+// 64-bit
+
+
+class ChangeLowering64Test : public ChangeLoweringTest {
+ public:
+  ~ChangeLowering64Test() OVERRIDE {}
+  MachineType WordRepresentation() const FINAL { return kRepWord64; }
+};
+
+
+TARGET_TEST_F(ChangeLowering64Test, ChangeInt32ToTagged) {
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  EXPECT_THAT(reduction.replacement(),
+              IsWord64Shl(IsChangeInt32ToInt64(val),
+                          IsInt64Constant(SmiShiftAmount())));
+}
+
+
+TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToFloat64) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* phi = reduction.replacement();
+  Capture<Node*> branch, if_true;
+  EXPECT_THAT(
+      phi,
+      IsPhi(
+          kMachFloat64, IsLoadHeapNumber(val, CaptureEq(&if_true)),
+          IsChangeInt32ToFloat64(IsTruncateInt64ToInt32(
+              IsWord64Sar(val, IsInt64Constant(SmiShiftAmount())))),
+          IsMerge(
+              AllOf(CaptureEq(&if_true),
+                    IsIfTrue(AllOf(
+                        CaptureEq(&branch),
+                        IsBranch(IsWord64And(val, IsInt64Constant(kSmiTagMask)),
+                                 graph()->start())))),
+              IsIfFalse(CaptureEq(&branch)))));
+}
+
+
+TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToInt32) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeTaggedToInt32(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* phi = reduction.replacement();
+  Capture<Node*> branch, if_true;
+  EXPECT_THAT(
+      phi,
+      IsPhi(kMachInt32,
+            IsChangeFloat64ToInt32(IsLoadHeapNumber(val, CaptureEq(&if_true))),
+            IsTruncateInt64ToInt32(
+                IsWord64Sar(val, IsInt64Constant(SmiShiftAmount()))),
+            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
+                    IsIfFalse(AllOf(
+                        CaptureEq(&branch),
+                        IsBranch(IsWord64And(val, IsInt64Constant(kSmiTagMask)),
+                                 graph()->start()))))));
+}
+
+
+TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToUint32) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* phi = reduction.replacement();
+  Capture<Node*> branch, if_true;
+  EXPECT_THAT(
+      phi,
+      IsPhi(kMachUint32,
+            IsChangeFloat64ToUint32(IsLoadHeapNumber(val, CaptureEq(&if_true))),
+            IsTruncateInt64ToInt32(
+                IsWord64Sar(val, IsInt64Constant(SmiShiftAmount()))),
+            IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))),
+                    IsIfFalse(AllOf(
+                        CaptureEq(&branch),
+                        IsBranch(IsWord64And(val, IsInt64Constant(kSmiTagMask)),
+                                 graph()->start()))))));
+}
+
+
+TARGET_TEST_F(ChangeLowering64Test, ChangeUint32ToTagged) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* phi = reduction.replacement();
+  Capture<Node*> branch, heap_number, if_false;
+  EXPECT_THAT(
+      phi,
+      IsPhi(
+          kMachAnyTagged, IsWord64Shl(IsChangeUint32ToUint64(val),
+                                      IsInt64Constant(SmiShiftAmount())),
+          IsFinish(AllOf(CaptureEq(&heap_number),
+                         IsAllocateHeapNumber(_, CaptureEq(&if_false))),
+                   IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier),
+                           CaptureEq(&heap_number),
+                           IsInt64Constant(HeapNumberValueOffset()),
+                           IsChangeUint32ToFloat64(val),
+                           CaptureEq(&heap_number), CaptureEq(&if_false))),
+          IsMerge(
+              IsIfTrue(AllOf(CaptureEq(&branch),
+                             IsBranch(IsUint32LessThanOrEqual(
+                                          val, IsInt32Constant(SmiMaxValue())),
+                                      graph()->start()))),
+              AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/common-operator-reducer-unittest.cc b/test/unittests/compiler/common-operator-reducer-unittest.cc
new file mode 100644
index 0000000..c713815
--- /dev/null
+++ b/test/unittests/compiler/common-operator-reducer-unittest.cc
@@ -0,0 +1,110 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/common-operator-reducer.h"
+#include "src/compiler/machine-type.h"
+#include "test/unittests/compiler/graph-unittest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class CommonOperatorReducerTest : public GraphTest {
+ public:
+  explicit CommonOperatorReducerTest(int num_parameters = 1)
+      : GraphTest(num_parameters) {}
+  ~CommonOperatorReducerTest() OVERRIDE {}
+
+ protected:
+  Reduction Reduce(Node* node) {
+    CommonOperatorReducer reducer;
+    return reducer.Reduce(node);
+  }
+};
+
+
+namespace {
+
+const BranchHint kBranchHints[] = {BranchHint::kNone, BranchHint::kFalse,
+                                   BranchHint::kTrue};
+
+
+const MachineType kMachineTypes[] = {
+    kMachFloat32, kMachFloat64,   kMachInt8,   kMachUint8,  kMachInt16,
+    kMachUint16,  kMachInt32,     kMachUint32, kMachInt64,  kMachUint64,
+    kMachPtr,     kMachAnyTagged, kRepBit,     kRepWord8,   kRepWord16,
+    kRepWord32,   kRepWord64,     kRepFloat32, kRepFloat64, kRepTagged};
+
+
+const Operator kOp0(0, Operator::kNoProperties, "Op0", 0, 0, 0, 1, 1, 0);
+
+}  // namespace
+
+
+// -----------------------------------------------------------------------------
+// EffectPhi
+
+
+TEST_F(CommonOperatorReducerTest, RedundantEffectPhi) {
+  const int kMaxInputs = 64;
+  Node* inputs[kMaxInputs];
+  Node* const input = graph()->NewNode(&kOp0);
+  TRACED_FORRANGE(int, input_count, 2, kMaxInputs - 1) {
+    int const value_input_count = input_count - 1;
+    for (int i = 0; i < value_input_count; ++i) {
+      inputs[i] = input;
+    }
+    inputs[value_input_count] = graph()->start();
+    Reduction r = Reduce(graph()->NewNode(
+        common()->EffectPhi(value_input_count), input_count, inputs));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_EQ(input, r.replacement());
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Phi
+
+
+TEST_F(CommonOperatorReducerTest, RedundantPhi) {
+  const int kMaxInputs = 64;
+  Node* inputs[kMaxInputs];
+  Node* const input = graph()->NewNode(&kOp0);
+  TRACED_FORRANGE(int, input_count, 2, kMaxInputs - 1) {
+    int const value_input_count = input_count - 1;
+    TRACED_FOREACH(MachineType, type, kMachineTypes) {
+      for (int i = 0; i < value_input_count; ++i) {
+        inputs[i] = input;
+      }
+      inputs[value_input_count] = graph()->start();
+      Reduction r = Reduce(graph()->NewNode(
+          common()->Phi(type, value_input_count), input_count, inputs));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_EQ(input, r.replacement());
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Select
+
+
+TEST_F(CommonOperatorReducerTest, RedundantSelect) {
+  Node* const input = graph()->NewNode(&kOp0);
+  TRACED_FOREACH(BranchHint, hint, kBranchHints) {
+    TRACED_FOREACH(MachineType, type, kMachineTypes) {
+      Reduction r = Reduce(
+          graph()->NewNode(common()->Select(type, hint), input, input, input));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_EQ(input, r.replacement());
+    }
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/common-operator-unittest.cc b/test/unittests/compiler/common-operator-unittest.cc
new file mode 100644
index 0000000..d0ac145
--- /dev/null
+++ b/test/unittests/compiler/common-operator-unittest.cc
@@ -0,0 +1,293 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <limits>
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/opcodes.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/operator-properties.h"
+#include "test/unittests/test-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+
+// -----------------------------------------------------------------------------
+// Shared operators.
+
+
+namespace {
+
+struct SharedOperator {
+  const Operator* (CommonOperatorBuilder::*constructor)();
+  IrOpcode::Value opcode;
+  Operator::Properties properties;
+  int value_input_count;
+  int effect_input_count;
+  int control_input_count;
+  int effect_output_count;
+  int control_output_count;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const SharedOperator& fop) {
+  return os << IrOpcode::Mnemonic(fop.opcode);
+}
+
+
+const SharedOperator kSharedOperators[] = {
+#define SHARED(Name, properties, value_input_count, effect_input_count,        \
+               control_input_count, effect_output_count, control_output_count) \
+  {                                                                            \
+    &CommonOperatorBuilder::Name, IrOpcode::k##Name, properties,               \
+        value_input_count, effect_input_count, control_input_count,            \
+        effect_output_count, control_output_count                              \
+  }
+    SHARED(Dead, Operator::kFoldable, 0, 0, 0, 0, 1),
+    SHARED(End, Operator::kFoldable, 0, 0, 1, 0, 0),
+    SHARED(IfTrue, Operator::kFoldable, 0, 0, 1, 0, 1),
+    SHARED(IfFalse, Operator::kFoldable, 0, 0, 1, 0, 1),
+    SHARED(Throw, Operator::kFoldable, 1, 1, 1, 0, 1),
+    SHARED(Return, Operator::kNoProperties, 1, 1, 1, 0, 1)
+#undef SHARED
+};
+
+
+class CommonSharedOperatorTest
+    : public TestWithZone,
+      public ::testing::WithParamInterface<SharedOperator> {};
+
+}  // namespace
+
+
+TEST_P(CommonSharedOperatorTest, InstancesAreGloballyShared) {
+  const SharedOperator& sop = GetParam();
+  CommonOperatorBuilder common1(zone());
+  CommonOperatorBuilder common2(zone());
+  EXPECT_EQ((common1.*sop.constructor)(), (common2.*sop.constructor)());
+}
+
+
+TEST_P(CommonSharedOperatorTest, NumberOfInputsAndOutputs) {
+  CommonOperatorBuilder common(zone());
+  const SharedOperator& sop = GetParam();
+  const Operator* op = (common.*sop.constructor)();
+
+  EXPECT_EQ(sop.value_input_count, op->ValueInputCount());
+  EXPECT_EQ(sop.effect_input_count, op->EffectInputCount());
+  EXPECT_EQ(sop.control_input_count, op->ControlInputCount());
+  EXPECT_EQ(
+      sop.value_input_count + sop.effect_input_count + sop.control_input_count,
+      OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(0, op->ValueOutputCount());
+  EXPECT_EQ(sop.effect_output_count, op->EffectOutputCount());
+  EXPECT_EQ(sop.control_output_count, op->ControlOutputCount());
+}
+
+
+TEST_P(CommonSharedOperatorTest, OpcodeIsCorrect) {
+  CommonOperatorBuilder common(zone());
+  const SharedOperator& sop = GetParam();
+  const Operator* op = (common.*sop.constructor)();
+  EXPECT_EQ(sop.opcode, op->opcode());
+}
+
+
+TEST_P(CommonSharedOperatorTest, Properties) {
+  CommonOperatorBuilder common(zone());
+  const SharedOperator& sop = GetParam();
+  const Operator* op = (common.*sop.constructor)();
+  EXPECT_EQ(sop.properties, op->properties());
+}
+
+
+INSTANTIATE_TEST_CASE_P(CommonOperatorTest, CommonSharedOperatorTest,
+                        ::testing::ValuesIn(kSharedOperators));
+
+
+// -----------------------------------------------------------------------------
+// Other operators.
+
+
+namespace {
+
+class CommonOperatorTest : public TestWithZone {
+ public:
+  CommonOperatorTest() : common_(zone()) {}
+  ~CommonOperatorTest() OVERRIDE {}
+
+  CommonOperatorBuilder* common() { return &common_; }
+
+ private:
+  CommonOperatorBuilder common_;
+};
+
+
+const int kArguments[] = {1, 5, 6, 42, 100, 10000, 65000};
+
+
+const float kFloatValues[] = {-std::numeric_limits<float>::infinity(),
+                              std::numeric_limits<float>::min(),
+                              -1.0f,
+                              -0.0f,
+                              0.0f,
+                              1.0f,
+                              std::numeric_limits<float>::max(),
+                              std::numeric_limits<float>::infinity(),
+                              std::numeric_limits<float>::quiet_NaN(),
+                              std::numeric_limits<float>::signaling_NaN()};
+
+
+const double kDoubleValues[] = {-std::numeric_limits<double>::infinity(),
+                                std::numeric_limits<double>::min(),
+                                -1.0,
+                                -0.0,
+                                0.0,
+                                1.0,
+                                std::numeric_limits<double>::max(),
+                                std::numeric_limits<double>::infinity(),
+                                std::numeric_limits<double>::quiet_NaN(),
+                                std::numeric_limits<double>::signaling_NaN()};
+
+
+const BranchHint kHints[] = {BranchHint::kNone, BranchHint::kTrue,
+                             BranchHint::kFalse};
+
+}  // namespace
+
+
+TEST_F(CommonOperatorTest, Branch) {
+  TRACED_FOREACH(BranchHint, hint, kHints) {
+    const Operator* const op = common()->Branch(hint);
+    EXPECT_EQ(IrOpcode::kBranch, op->opcode());
+    EXPECT_EQ(Operator::kFoldable, op->properties());
+    EXPECT_EQ(hint, BranchHintOf(op));
+    EXPECT_EQ(1, op->ValueInputCount());
+    EXPECT_EQ(0, op->EffectInputCount());
+    EXPECT_EQ(1, op->ControlInputCount());
+    EXPECT_EQ(2, OperatorProperties::GetTotalInputCount(op));
+    EXPECT_EQ(0, op->ValueOutputCount());
+    EXPECT_EQ(0, op->EffectOutputCount());
+    EXPECT_EQ(2, op->ControlOutputCount());
+  }
+}
+
+
+TEST_F(CommonOperatorTest, Select) {
+  static const MachineType kTypes[] = {
+      kMachInt8,    kMachUint8,   kMachInt16,    kMachUint16,
+      kMachInt32,   kMachUint32,  kMachInt64,    kMachUint64,
+      kMachFloat32, kMachFloat64, kMachAnyTagged};
+  TRACED_FOREACH(MachineType, type, kTypes) {
+    TRACED_FOREACH(BranchHint, hint, kHints) {
+      const Operator* const op = common()->Select(type, hint);
+      EXPECT_EQ(IrOpcode::kSelect, op->opcode());
+      EXPECT_EQ(Operator::kPure, op->properties());
+      EXPECT_EQ(type, SelectParametersOf(op).type());
+      EXPECT_EQ(hint, SelectParametersOf(op).hint());
+      EXPECT_EQ(3, op->ValueInputCount());
+      EXPECT_EQ(0, op->EffectInputCount());
+      EXPECT_EQ(0, op->ControlInputCount());
+      EXPECT_EQ(3, OperatorProperties::GetTotalInputCount(op));
+      EXPECT_EQ(1, op->ValueOutputCount());
+      EXPECT_EQ(0, op->EffectOutputCount());
+      EXPECT_EQ(0, op->ControlOutputCount());
+    }
+  }
+}
+
+
+TEST_F(CommonOperatorTest, Float32Constant) {
+  TRACED_FOREACH(float, value, kFloatValues) {
+    const Operator* op = common()->Float32Constant(value);
+    EXPECT_PRED2(base::bit_equal_to<float>(), value, OpParameter<float>(op));
+    EXPECT_EQ(0, op->ValueInputCount());
+    EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
+    EXPECT_EQ(0, op->ControlOutputCount());
+    EXPECT_EQ(0, op->EffectOutputCount());
+    EXPECT_EQ(1, op->ValueOutputCount());
+  }
+  TRACED_FOREACH(float, v1, kFloatValues) {
+    TRACED_FOREACH(float, v2, kFloatValues) {
+      const Operator* op1 = common()->Float32Constant(v1);
+      const Operator* op2 = common()->Float32Constant(v2);
+      EXPECT_EQ(bit_cast<uint32_t>(v1) == bit_cast<uint32_t>(v2),
+                op1->Equals(op2));
+    }
+  }
+}
+
+
+TEST_F(CommonOperatorTest, Float64Constant) {
+  TRACED_FOREACH(double, value, kFloatValues) {
+    const Operator* op = common()->Float64Constant(value);
+    EXPECT_PRED2(base::bit_equal_to<double>(), value, OpParameter<double>(op));
+    EXPECT_EQ(0, op->ValueInputCount());
+    EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
+    EXPECT_EQ(0, op->ControlOutputCount());
+    EXPECT_EQ(0, op->EffectOutputCount());
+    EXPECT_EQ(1, op->ValueOutputCount());
+  }
+  TRACED_FOREACH(double, v1, kFloatValues) {
+    TRACED_FOREACH(double, v2, kFloatValues) {
+      const Operator* op1 = common()->Float64Constant(v1);
+      const Operator* op2 = common()->Float64Constant(v2);
+      EXPECT_EQ(bit_cast<uint64_t>(v1) == bit_cast<uint64_t>(v2),
+                op1->Equals(op2));
+    }
+  }
+}
+
+
+TEST_F(CommonOperatorTest, NumberConstant) {
+  TRACED_FOREACH(double, value, kFloatValues) {
+    const Operator* op = common()->NumberConstant(value);
+    EXPECT_PRED2(base::bit_equal_to<double>(), value, OpParameter<double>(op));
+    EXPECT_EQ(0, op->ValueInputCount());
+    EXPECT_EQ(0, OperatorProperties::GetTotalInputCount(op));
+    EXPECT_EQ(0, op->ControlOutputCount());
+    EXPECT_EQ(0, op->EffectOutputCount());
+    EXPECT_EQ(1, op->ValueOutputCount());
+  }
+  TRACED_FOREACH(double, v1, kFloatValues) {
+    TRACED_FOREACH(double, v2, kFloatValues) {
+      const Operator* op1 = common()->NumberConstant(v1);
+      const Operator* op2 = common()->NumberConstant(v2);
+      EXPECT_EQ(bit_cast<uint64_t>(v1) == bit_cast<uint64_t>(v2),
+                op1->Equals(op2));
+    }
+  }
+}
+
+
+TEST_F(CommonOperatorTest, ValueEffect) {
+  TRACED_FOREACH(int, arguments, kArguments) {
+    const Operator* op = common()->ValueEffect(arguments);
+    EXPECT_EQ(arguments, op->ValueInputCount());
+    EXPECT_EQ(arguments, OperatorProperties::GetTotalInputCount(op));
+    EXPECT_EQ(0, op->ControlOutputCount());
+    EXPECT_EQ(1, op->EffectOutputCount());
+    EXPECT_EQ(0, op->ValueOutputCount());
+  }
+}
+
+
+TEST_F(CommonOperatorTest, Finish) {
+  TRACED_FOREACH(int, arguments, kArguments) {
+    const Operator* op = common()->Finish(arguments);
+    EXPECT_EQ(1, op->ValueInputCount());
+    EXPECT_EQ(arguments, op->EffectInputCount());
+    EXPECT_EQ(arguments + 1, OperatorProperties::GetTotalInputCount(op));
+    EXPECT_EQ(0, op->ControlOutputCount());
+    EXPECT_EQ(0, op->EffectOutputCount());
+    EXPECT_EQ(1, op->ValueOutputCount());
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/compiler-test-utils.h b/test/unittests/compiler/compiler-test-utils.h
new file mode 100644
index 0000000..6ce28f9
--- /dev/null
+++ b/test/unittests/compiler/compiler-test-utils.h
@@ -0,0 +1,57 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_UNITTESTS_COMPILER_COMPILER_TEST_UTILS_H_
+#define V8_UNITTESTS_COMPILER_COMPILER_TEST_UTILS_H_
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// The TARGET_TEST(Case, Name) macro works just like
+// TEST(Case, Name), except that the test is disabled
+// if the platform is not a supported TurboFan target.
+#if V8_TURBOFAN_TARGET
+#define TARGET_TEST(Case, Name) TEST(Case, Name)
+#else
+#define TARGET_TEST(Case, Name) TEST(Case, DISABLED_##Name)
+#endif
+
+
+// The TARGET_TEST_F(Case, Name) macro works just like
+// TEST_F(Case, Name), except that the test is disabled
+// if the platform is not a supported TurboFan target.
+#if V8_TURBOFAN_TARGET
+#define TARGET_TEST_F(Case, Name) TEST_F(Case, Name)
+#else
+#define TARGET_TEST_F(Case, Name) TEST_F(Case, DISABLED_##Name)
+#endif
+
+
+// The TARGET_TEST_P(Case, Name) macro works just like
+// TEST_P(Case, Name), except that the test is disabled
+// if the platform is not a supported TurboFan target.
+#if V8_TURBOFAN_TARGET
+#define TARGET_TEST_P(Case, Name) TEST_P(Case, Name)
+#else
+#define TARGET_TEST_P(Case, Name) TEST_P(Case, DISABLED_##Name)
+#endif
+
+
+// The TARGET_TYPED_TEST(Case, Name) macro works just like
+// TYPED_TEST(Case, Name), except that the test is disabled
+// if the platform is not a supported TurboFan target.
+#if V8_TURBOFAN_TARGET
+#define TARGET_TYPED_TEST(Case, Name) TYPED_TEST(Case, Name)
+#else
+#define TARGET_TYPED_TEST(Case, Name) TYPED_TEST(Case, DISABLED_##Name)
+#endif
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_UNITTESTS_COMPILER_COMPILER_TEST_UTILS_H_
diff --git a/test/unittests/compiler/control-equivalence-unittest.cc b/test/unittests/compiler/control-equivalence-unittest.cc
new file mode 100644
index 0000000..56b4a2b
--- /dev/null
+++ b/test/unittests/compiler/control-equivalence-unittest.cc
@@ -0,0 +1,255 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/bit-vector.h"
+#include "src/compiler/control-equivalence.h"
+#include "src/compiler/graph-visualizer.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/zone-containers.h"
+#include "test/unittests/compiler/graph-unittest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+#define ASSERT_EQUIVALENCE(...)                           \
+  do {                                                    \
+    Node* __n[] = {__VA_ARGS__};                          \
+    ASSERT_TRUE(IsEquivalenceClass(arraysize(__n), __n)); \
+  } while (false);
+
+class ControlEquivalenceTest : public GraphTest {
+ public:
+  ControlEquivalenceTest() : all_nodes_(zone()), classes_(zone()) {
+    Store(graph()->start());
+  }
+
+ protected:
+  void ComputeEquivalence(Node* node) {
+    graph()->SetEnd(graph()->NewNode(common()->End(), node));
+    if (FLAG_trace_turbo) {
+      OFStream os(stdout);
+      os << AsDOT(*graph());
+    }
+    ControlEquivalence equivalence(zone(), graph());
+    equivalence.Run(node);
+    classes_.resize(graph()->NodeCount());
+    for (Node* node : all_nodes_) {
+      classes_[node->id()] = equivalence.ClassOf(node);
+    }
+  }
+
+  bool IsEquivalenceClass(size_t length, Node** nodes) {
+    BitVector in_class(graph()->NodeCount(), zone());
+    size_t expected_class = classes_[nodes[0]->id()];
+    for (size_t i = 0; i < length; ++i) {
+      in_class.Add(nodes[i]->id());
+    }
+    for (Node* node : all_nodes_) {
+      if (in_class.Contains(node->id())) {
+        if (classes_[node->id()] != expected_class) return false;
+      } else {
+        if (classes_[node->id()] == expected_class) return false;
+      }
+    }
+    return true;
+  }
+
+  Node* Value() { return NumberConstant(0.0); }
+
+  Node* Branch(Node* control) {
+    return Store(graph()->NewNode(common()->Branch(), Value(), control));
+  }
+
+  Node* IfTrue(Node* control) {
+    return Store(graph()->NewNode(common()->IfTrue(), control));
+  }
+
+  Node* IfFalse(Node* control) {
+    return Store(graph()->NewNode(common()->IfFalse(), control));
+  }
+
+  Node* Merge2(Node* control1, Node* control2) {
+    return Store(graph()->NewNode(common()->Merge(2), control1, control2));
+  }
+
+  Node* Loop2(Node* control) {
+    return Store(graph()->NewNode(common()->Loop(2), control, control));
+  }
+
+  Node* End(Node* control) {
+    return Store(graph()->NewNode(common()->End(), control));
+  }
+
+ private:
+  Node* Store(Node* node) {
+    all_nodes_.push_back(node);
+    return node;
+  }
+
+  ZoneVector<Node*> all_nodes_;
+  ZoneVector<size_t> classes_;
+};
+
+
+// -----------------------------------------------------------------------------
+// Test cases.
+
+
+TEST_F(ControlEquivalenceTest, Empty1) {
+  Node* start = graph()->start();
+  ComputeEquivalence(start);
+
+  ASSERT_EQUIVALENCE(start);
+}
+
+
+TEST_F(ControlEquivalenceTest, Empty2) {
+  Node* start = graph()->start();
+  Node* end = End(start);
+  ComputeEquivalence(end);
+
+  ASSERT_EQUIVALENCE(start, end);
+}
+
+
+TEST_F(ControlEquivalenceTest, Diamond1) {
+  Node* start = graph()->start();
+  Node* b = Branch(start);
+  Node* t = IfTrue(b);
+  Node* f = IfFalse(b);
+  Node* m = Merge2(t, f);
+  ComputeEquivalence(m);
+
+  ASSERT_EQUIVALENCE(b, m, start);
+  ASSERT_EQUIVALENCE(f);
+  ASSERT_EQUIVALENCE(t);
+}
+
+
+TEST_F(ControlEquivalenceTest, Diamond2) {
+  Node* start = graph()->start();
+  Node* b1 = Branch(start);
+  Node* t1 = IfTrue(b1);
+  Node* f1 = IfFalse(b1);
+  Node* b2 = Branch(f1);
+  Node* t2 = IfTrue(b2);
+  Node* f2 = IfFalse(b2);
+  Node* m2 = Merge2(t2, f2);
+  Node* m1 = Merge2(t1, m2);
+  ComputeEquivalence(m1);
+
+  ASSERT_EQUIVALENCE(b1, m1, start);
+  ASSERT_EQUIVALENCE(t1);
+  ASSERT_EQUIVALENCE(f1, b2, m2);
+  ASSERT_EQUIVALENCE(t2);
+  ASSERT_EQUIVALENCE(f2);
+}
+
+
+TEST_F(ControlEquivalenceTest, Diamond3) {
+  Node* start = graph()->start();
+  Node* b1 = Branch(start);
+  Node* t1 = IfTrue(b1);
+  Node* f1 = IfFalse(b1);
+  Node* m1 = Merge2(t1, f1);
+  Node* b2 = Branch(m1);
+  Node* t2 = IfTrue(b2);
+  Node* f2 = IfFalse(b2);
+  Node* m2 = Merge2(t2, f2);
+  ComputeEquivalence(m2);
+
+  ASSERT_EQUIVALENCE(b1, m1, b2, m2, start);
+  ASSERT_EQUIVALENCE(t1);
+  ASSERT_EQUIVALENCE(f1);
+  ASSERT_EQUIVALENCE(t2);
+  ASSERT_EQUIVALENCE(f2);
+}
+
+
+TEST_F(ControlEquivalenceTest, Switch1) {
+  Node* start = graph()->start();
+  Node* b1 = Branch(start);
+  Node* t1 = IfTrue(b1);
+  Node* f1 = IfFalse(b1);
+  Node* b2 = Branch(f1);
+  Node* t2 = IfTrue(b2);
+  Node* f2 = IfFalse(b2);
+  Node* b3 = Branch(f2);
+  Node* t3 = IfTrue(b3);
+  Node* f3 = IfFalse(b3);
+  Node* m1 = Merge2(t1, t2);
+  Node* m2 = Merge2(m1, t3);
+  Node* m3 = Merge2(m2, f3);
+  ComputeEquivalence(m3);
+
+  ASSERT_EQUIVALENCE(b1, m3, start);
+  ASSERT_EQUIVALENCE(t1);
+  ASSERT_EQUIVALENCE(f1, b2);
+  ASSERT_EQUIVALENCE(t2);
+  ASSERT_EQUIVALENCE(f2, b3);
+  ASSERT_EQUIVALENCE(t3);
+  ASSERT_EQUIVALENCE(f3);
+  ASSERT_EQUIVALENCE(m1);
+  ASSERT_EQUIVALENCE(m2);
+}
+
+
+TEST_F(ControlEquivalenceTest, Loop1) {
+  Node* start = graph()->start();
+  Node* l = Loop2(start);
+  l->ReplaceInput(1, l);
+  ComputeEquivalence(l);
+
+  ASSERT_EQUIVALENCE(start);
+  ASSERT_EQUIVALENCE(l);
+}
+
+
+TEST_F(ControlEquivalenceTest, Loop2) {
+  Node* start = graph()->start();
+  Node* l = Loop2(start);
+  Node* b = Branch(l);
+  Node* t = IfTrue(b);
+  Node* f = IfFalse(b);
+  l->ReplaceInput(1, t);
+  ComputeEquivalence(f);
+
+  ASSERT_EQUIVALENCE(f, start);
+  ASSERT_EQUIVALENCE(t);
+  ASSERT_EQUIVALENCE(l, b);
+}
+
+
+TEST_F(ControlEquivalenceTest, Irreducible) {
+  Node* start = graph()->start();
+  Node* b1 = Branch(start);
+  Node* t1 = IfTrue(b1);
+  Node* f1 = IfFalse(b1);
+  Node* lp = Loop2(f1);
+  Node* m1 = Merge2(t1, lp);
+  Node* b2 = Branch(m1);
+  Node* t2 = IfTrue(b2);
+  Node* f2 = IfFalse(b2);
+  Node* m2 = Merge2(t2, f2);
+  Node* b3 = Branch(m2);
+  Node* t3 = IfTrue(b3);
+  Node* f3 = IfFalse(b3);
+  lp->ReplaceInput(1, f3);
+  ComputeEquivalence(t3);
+
+  ASSERT_EQUIVALENCE(b1, t3, start);
+  ASSERT_EQUIVALENCE(t1);
+  ASSERT_EQUIVALENCE(f1);
+  ASSERT_EQUIVALENCE(m1, b2, m2, b3);
+  ASSERT_EQUIVALENCE(t2);
+  ASSERT_EQUIVALENCE(f2);
+  ASSERT_EQUIVALENCE(f3);
+  ASSERT_EQUIVALENCE(lp);
+}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/diamond-unittest.cc b/test/unittests/compiler/diamond-unittest.cc
new file mode 100644
index 0000000..c14886f
--- /dev/null
+++ b/test/unittests/compiler/diamond-unittest.cc
@@ -0,0 +1,161 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/diamond.h"
+#include "test/unittests/compiler/graph-unittest.h"
+#include "test/unittests/compiler/node-test-utils.h"
+#include "testing/gmock-support.h"
+
+using testing::AllOf;
+using testing::Capture;
+using testing::CaptureEq;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class DiamondTest : public GraphTest {
+ public:
+  DiamondTest() : GraphTest(5) {}
+};
+
+
+TEST_F(DiamondTest, SimpleDiamond) {
+  Node* p = Parameter(0);
+  Diamond d(graph(), common(), p);
+  EXPECT_THAT(d.branch, IsBranch(p, graph()->start()));
+  EXPECT_THAT(d.if_true, IsIfTrue(d.branch));
+  EXPECT_THAT(d.if_false, IsIfFalse(d.branch));
+  EXPECT_THAT(d.merge, IsMerge(d.if_true, d.if_false));
+}
+
+
+TEST_F(DiamondTest, DiamondChainDiamond) {
+  Node* p0 = Parameter(0);
+  Node* p1 = Parameter(1);
+  Diamond d0(graph(), common(), p0);
+  Diamond d1(graph(), common(), p1);
+  d1.Chain(d0);
+  EXPECT_THAT(d1.branch, IsBranch(p1, d0.merge));
+  EXPECT_THAT(d0.branch, IsBranch(p0, graph()->start()));
+}
+
+
+TEST_F(DiamondTest, DiamondChainNode) {
+  Node* p1 = Parameter(1);
+  Diamond d1(graph(), common(), p1);
+  Node* other = graph()->NewNode(common()->Merge(0));
+  d1.Chain(other);
+  EXPECT_THAT(d1.branch, IsBranch(p1, other));
+}
+
+
+TEST_F(DiamondTest, DiamondChainN) {
+  Node* params[5] = {Parameter(0), Parameter(1), Parameter(2), Parameter(3),
+                     Parameter(4)};
+  Diamond d[5] = {Diamond(graph(), common(), params[0]),
+                  Diamond(graph(), common(), params[1]),
+                  Diamond(graph(), common(), params[2]),
+                  Diamond(graph(), common(), params[3]),
+                  Diamond(graph(), common(), params[4])};
+
+  for (int i = 1; i < 5; i++) {
+    d[i].Chain(d[i - 1]);
+    EXPECT_THAT(d[i].branch, IsBranch(params[i], d[i - 1].merge));
+  }
+}
+
+
+TEST_F(DiamondTest, DiamondNested_true) {
+  Node* p0 = Parameter(0);
+  Node* p1 = Parameter(1);
+  Diamond d0(graph(), common(), p0);
+  Diamond d1(graph(), common(), p1);
+
+  d1.Nest(d0, true);
+
+  EXPECT_THAT(d0.branch, IsBranch(p0, graph()->start()));
+  EXPECT_THAT(d0.if_true, IsIfTrue(d0.branch));
+  EXPECT_THAT(d0.if_false, IsIfFalse(d0.branch));
+  EXPECT_THAT(d0.merge, IsMerge(d1.merge, d0.if_false));
+
+  EXPECT_THAT(d1.branch, IsBranch(p1, d0.if_true));
+  EXPECT_THAT(d1.if_true, IsIfTrue(d1.branch));
+  EXPECT_THAT(d1.if_false, IsIfFalse(d1.branch));
+  EXPECT_THAT(d1.merge, IsMerge(d1.if_true, d1.if_false));
+}
+
+
+TEST_F(DiamondTest, DiamondNested_false) {
+  Node* p0 = Parameter(0);
+  Node* p1 = Parameter(1);
+  Diamond d0(graph(), common(), p0);
+  Diamond d1(graph(), common(), p1);
+
+  d1.Nest(d0, false);
+
+  EXPECT_THAT(d0.branch, IsBranch(p0, graph()->start()));
+  EXPECT_THAT(d0.if_true, IsIfTrue(d0.branch));
+  EXPECT_THAT(d0.if_false, IsIfFalse(d0.branch));
+  EXPECT_THAT(d0.merge, IsMerge(d0.if_true, d1.merge));
+
+  EXPECT_THAT(d1.branch, IsBranch(p1, d0.if_false));
+  EXPECT_THAT(d1.if_true, IsIfTrue(d1.branch));
+  EXPECT_THAT(d1.if_false, IsIfFalse(d1.branch));
+  EXPECT_THAT(d1.merge, IsMerge(d1.if_true, d1.if_false));
+}
+
+
+TEST_F(DiamondTest, DiamondPhis) {
+  Node* p0 = Parameter(0);
+  Node* p1 = Parameter(1);
+  Node* p2 = Parameter(2);
+  Diamond d(graph(), common(), p0);
+
+  MachineType types[] = {kMachAnyTagged, kMachUint32, kMachInt32};
+
+  for (size_t i = 0; i < arraysize(types); i++) {
+    Node* phi = d.Phi(types[i], p1, p2);
+
+    EXPECT_THAT(d.branch, IsBranch(p0, graph()->start()));
+    EXPECT_THAT(d.if_true, IsIfTrue(d.branch));
+    EXPECT_THAT(d.if_false, IsIfFalse(d.branch));
+    EXPECT_THAT(d.merge, IsMerge(d.if_true, d.if_false));
+    EXPECT_THAT(phi, IsPhi(types[i], p1, p2, d.merge));
+  }
+}
+
+
+TEST_F(DiamondTest, DiamondEffectPhis) {
+  Node* p0 = Parameter(0);
+  Node* p1 = Parameter(1);
+  Node* p2 = Parameter(2);
+  Diamond d(graph(), common(), p0);
+
+  Node* phi = d.EffectPhi(p1, p2);
+
+  EXPECT_THAT(d.branch, IsBranch(p0, graph()->start()));
+  EXPECT_THAT(d.if_true, IsIfTrue(d.branch));
+  EXPECT_THAT(d.if_false, IsIfFalse(d.branch));
+  EXPECT_THAT(d.merge, IsMerge(d.if_true, d.if_false));
+  EXPECT_THAT(phi, IsEffectPhi(p1, p2, d.merge));
+}
+
+
+TEST_F(DiamondTest, BranchHint) {
+  Diamond dn(graph(), common(), Parameter(0));
+  CHECK(BranchHint::kNone == BranchHintOf(dn.branch->op()));
+
+  Diamond dt(graph(), common(), Parameter(0), BranchHint::kTrue);
+  CHECK(BranchHint::kTrue == BranchHintOf(dt.branch->op()));
+
+  Diamond df(graph(), common(), Parameter(0), BranchHint::kFalse);
+  CHECK(BranchHint::kFalse == BranchHintOf(df.branch->op()));
+}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/graph-reducer-unittest.cc b/test/unittests/compiler/graph-reducer-unittest.cc
new file mode 100644
index 0000000..dbdd4bb
--- /dev/null
+++ b/test/unittests/compiler/graph-reducer-unittest.cc
@@ -0,0 +1,123 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/graph.h"
+#include "src/compiler/graph-reducer.h"
+#include "src/compiler/operator.h"
+#include "test/unittests/test-utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+using testing::_;
+using testing::DefaultValue;
+using testing::Return;
+using testing::Sequence;
+using testing::StrictMock;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+struct TestOperator : public Operator {
+  TestOperator(Operator::Opcode opcode, Operator::Properties properties,
+               size_t value_in, size_t value_out)
+      : Operator(opcode, properties, "TestOp", value_in, 0, 0, value_out, 0,
+                 0) {}
+};
+
+
+namespace {
+
+TestOperator OP0(0, Operator::kNoWrite, 0, 1);
+TestOperator OP1(1, Operator::kNoProperties, 1, 1);
+
+
+struct MockReducer : public Reducer {
+  MOCK_METHOD1(Reduce, Reduction(Node*));
+};
+
+}  // namespace
+
+
+class GraphReducerTest : public TestWithZone {
+ public:
+  GraphReducerTest() : graph_(zone()) {}
+
+  static void SetUpTestCase() {
+    TestWithZone::SetUpTestCase();
+    DefaultValue<Reduction>::Set(Reducer::NoChange());
+  }
+
+  static void TearDownTestCase() {
+    DefaultValue<Reduction>::Clear();
+    TestWithZone::TearDownTestCase();
+  }
+
+ protected:
+  void ReduceNode(Node* node, Reducer* r) {
+    GraphReducer reducer(graph(), zone());
+    reducer.AddReducer(r);
+    reducer.ReduceNode(node);
+  }
+
+  void ReduceNode(Node* node, Reducer* r1, Reducer* r2) {
+    GraphReducer reducer(graph(), zone());
+    reducer.AddReducer(r1);
+    reducer.AddReducer(r2);
+    reducer.ReduceNode(node);
+  }
+
+  void ReduceNode(Node* node, Reducer* r1, Reducer* r2, Reducer* r3) {
+    GraphReducer reducer(graph(), zone());
+    reducer.AddReducer(r1);
+    reducer.AddReducer(r2);
+    reducer.AddReducer(r3);
+    reducer.ReduceNode(node);
+  }
+
+  Graph* graph() { return &graph_; }
+
+ private:
+  Graph graph_;
+};
+
+
+TEST_F(GraphReducerTest, NodeIsDeadAfterReplace) {
+  StrictMock<MockReducer> r;
+  Node* node0 = graph()->NewNode(&OP0);
+  Node* node1 = graph()->NewNode(&OP1, node0);
+  Node* node2 = graph()->NewNode(&OP1, node0);
+  EXPECT_CALL(r, Reduce(node0)).WillOnce(Return(Reducer::NoChange()));
+  EXPECT_CALL(r, Reduce(node1)).WillOnce(Return(Reducer::Replace(node2)));
+  ReduceNode(node1, &r);
+  EXPECT_FALSE(node0->IsDead());
+  EXPECT_TRUE(node1->IsDead());
+  EXPECT_FALSE(node2->IsDead());
+}
+
+
+TEST_F(GraphReducerTest, ReduceOnceForEveryReducer) {
+  StrictMock<MockReducer> r1, r2;
+  Node* node0 = graph()->NewNode(&OP0);
+  EXPECT_CALL(r1, Reduce(node0));
+  EXPECT_CALL(r2, Reduce(node0));
+  ReduceNode(node0, &r1, &r2);
+}
+
+
+TEST_F(GraphReducerTest, ReduceAgainAfterChanged) {
+  Sequence s1, s2, s3;
+  StrictMock<MockReducer> r1, r2, r3;
+  Node* node0 = graph()->NewNode(&OP0);
+  EXPECT_CALL(r1, Reduce(node0));
+  EXPECT_CALL(r2, Reduce(node0));
+  EXPECT_CALL(r3, Reduce(node0)).InSequence(s1, s2, s3).WillOnce(
+      Return(Reducer::Changed(node0)));
+  EXPECT_CALL(r1, Reduce(node0)).InSequence(s1);
+  EXPECT_CALL(r2, Reduce(node0)).InSequence(s2);
+  ReduceNode(node0, &r1, &r2, &r3);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/graph-unittest.cc b/test/unittests/compiler/graph-unittest.cc
new file mode 100644
index 0000000..9543258
--- /dev/null
+++ b/test/unittests/compiler/graph-unittest.cc
@@ -0,0 +1,110 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "test/unittests/compiler/graph-unittest.h"
+
+#include "src/compiler/node-properties-inl.h"
+#include "test/unittests/compiler/node-test-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+GraphTest::GraphTest(int num_parameters) : common_(zone()), graph_(zone()) {
+  graph()->SetStart(graph()->NewNode(common()->Start(num_parameters)));
+}
+
+
+GraphTest::~GraphTest() {}
+
+
+Node* GraphTest::Parameter(int32_t index) {
+  return graph()->NewNode(common()->Parameter(index), graph()->start());
+}
+
+
+Node* GraphTest::Float32Constant(volatile float value) {
+  return graph()->NewNode(common()->Float32Constant(value));
+}
+
+
+Node* GraphTest::Float64Constant(volatile double value) {
+  return graph()->NewNode(common()->Float64Constant(value));
+}
+
+
+Node* GraphTest::Int32Constant(int32_t value) {
+  return graph()->NewNode(common()->Int32Constant(value));
+}
+
+
+Node* GraphTest::Int64Constant(int64_t value) {
+  return graph()->NewNode(common()->Int64Constant(value));
+}
+
+
+Node* GraphTest::NumberConstant(volatile double value) {
+  return graph()->NewNode(common()->NumberConstant(value));
+}
+
+
+Node* GraphTest::HeapConstant(const Handle<HeapObject>& value) {
+  return HeapConstant(Unique<HeapObject>::CreateUninitialized(value));
+}
+
+
+Node* GraphTest::HeapConstant(const Unique<HeapObject>& value) {
+  Node* node = graph()->NewNode(common()->HeapConstant(value));
+  Type* type = Type::Constant(value.handle(), zone());
+  NodeProperties::SetBounds(node, Bounds(type));
+  return node;
+}
+
+
+Node* GraphTest::FalseConstant() {
+  return HeapConstant(
+      Unique<HeapObject>::CreateImmovable(factory()->false_value()));
+}
+
+
+Node* GraphTest::TrueConstant() {
+  return HeapConstant(
+      Unique<HeapObject>::CreateImmovable(factory()->true_value()));
+}
+
+
+Node* GraphTest::UndefinedConstant() {
+  return HeapConstant(
+      Unique<HeapObject>::CreateImmovable(factory()->undefined_value()));
+}
+
+
+Matcher<Node*> GraphTest::IsFalseConstant() {
+  return IsHeapConstant(
+      Unique<HeapObject>::CreateImmovable(factory()->false_value()));
+}
+
+
+Matcher<Node*> GraphTest::IsTrueConstant() {
+  return IsHeapConstant(
+      Unique<HeapObject>::CreateImmovable(factory()->true_value()));
+}
+
+
+TypedGraphTest::TypedGraphTest(int num_parameters)
+    : GraphTest(num_parameters), typer_(graph(), MaybeHandle<Context>()) {}
+
+
+TypedGraphTest::~TypedGraphTest() {}
+
+
+Node* TypedGraphTest::Parameter(Type* type, int32_t index) {
+  Node* node = GraphTest::Parameter(index);
+  NodeProperties::SetBounds(node, Bounds(type));
+  return node;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/graph-unittest.h b/test/unittests/compiler/graph-unittest.h
new file mode 100644
index 0000000..7c75161
--- /dev/null
+++ b/test/unittests/compiler/graph-unittest.h
@@ -0,0 +1,81 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_UNITTESTS_COMPILER_GRAPH_UNITTEST_H_
+#define V8_UNITTESTS_COMPILER_GRAPH_UNITTEST_H_
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/typer.h"
+#include "test/unittests/test-utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+template <class T>
+class Handle;
+class HeapObject;
+template <class T>
+class Unique;
+
+namespace compiler {
+
+using ::testing::Matcher;
+
+
+class GraphTest : public TestWithContext, public TestWithZone {
+ public:
+  explicit GraphTest(int num_parameters = 1);
+  ~GraphTest() OVERRIDE;
+
+ protected:
+  Node* Parameter(int32_t index = 0);
+  Node* Float32Constant(volatile float value);
+  Node* Float64Constant(volatile double value);
+  Node* Int32Constant(int32_t value);
+  Node* Uint32Constant(uint32_t value) {
+    return Int32Constant(bit_cast<int32_t>(value));
+  }
+  Node* Int64Constant(int64_t value);
+  Node* NumberConstant(volatile double value);
+  Node* HeapConstant(const Handle<HeapObject>& value);
+  Node* HeapConstant(const Unique<HeapObject>& value);
+  Node* FalseConstant();
+  Node* TrueConstant();
+  Node* UndefinedConstant();
+
+  Matcher<Node*> IsFalseConstant();
+  Matcher<Node*> IsTrueConstant();
+
+  CommonOperatorBuilder* common() { return &common_; }
+  Graph* graph() { return &graph_; }
+
+ private:
+  CommonOperatorBuilder common_;
+  Graph graph_;
+};
+
+
+class TypedGraphTest : public GraphTest {
+ public:
+  explicit TypedGraphTest(int num_parameters = 1);
+  ~TypedGraphTest() OVERRIDE;
+
+ protected:
+  Node* Parameter(int32_t index = 0) { return GraphTest::Parameter(index); }
+  Node* Parameter(Type* type, int32_t index = 0);
+
+  Typer* typer() { return &typer_; }
+
+ private:
+  Typer typer_;
+};
+
+}  //  namespace compiler
+}  //  namespace internal
+}  //  namespace v8
+
+#endif  // V8_UNITTESTS_COMPILER_GRAPH_UNITTEST_H_
diff --git a/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc b/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc
new file mode 100644
index 0000000..afa1e94
--- /dev/null
+++ b/test/unittests/compiler/ia32/instruction-selector-ia32-unittest.cc
@@ -0,0 +1,671 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "test/unittests/compiler/instruction-selector-unittest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+// Immediates (random subset).
+static const int32_t kImmediates[] = {
+    kMinInt, -42, -1, 0,  1,  2,    3,      4,          5,
+    6,       7,   8,  16, 42, 0xff, 0xffff, 0x0f0f0f0f, kMaxInt};
+
+}  // namespace
+
+
+TEST_F(InstructionSelectorTest, Int32AddWithParameter) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Int32Add(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kIA32Lea, s[0]->arch_opcode());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddWithImmediate) {
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    {
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Int32Add(m.Parameter(0), m.Int32Constant(imm)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kIA32Lea, s[0]->arch_opcode());
+      if (imm == 0) {
+        ASSERT_EQ(1U, s[0]->InputCount());
+      } else {
+        ASSERT_EQ(2U, s[0]->InputCount());
+        EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+      }
+    }
+    {
+      StreamBuilder m(this, kMachInt32, kMachInt32);
+      m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0)));
+      Stream s = m.Build();
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kIA32Lea, s[0]->arch_opcode());
+      if (imm == 0) {
+        ASSERT_EQ(1U, s[0]->InputCount());
+      } else {
+        ASSERT_EQ(2U, s[0]->InputCount());
+        EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+      }
+    }
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Int32SubWithParameter) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  m.Return(m.Int32Sub(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kIA32Sub, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32SubWithImmediate) {
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kIA32Sub, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Conversions.
+
+
+TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) {
+  StreamBuilder m(this, kMachFloat32, kMachFloat64);
+  m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kSSECvtss2sd, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_F(InstructionSelectorTest, TruncateFloat64ToFloat32WithParameter) {
+  StreamBuilder m(this, kMachFloat64, kMachFloat32);
+  m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kSSECvtsd2ss, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+// -----------------------------------------------------------------------------
+// Better left operand for commutative binops
+
+
+TEST_F(InstructionSelectorTest, BetterLeftOperandTestAddBinop) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* param1 = m.Parameter(0);
+  Node* param2 = m.Parameter(1);
+  Node* add = m.Int32Add(param1, param2);
+  m.Return(m.Int32Add(add, param1));
+  Stream s = m.Build();
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kIA32Lea, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  ASSERT_TRUE(s[0]->InputAt(0)->IsUnallocated());
+  EXPECT_EQ(s.ToVreg(param1), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(param2), s.ToVreg(s[0]->InputAt(1)));
+  ASSERT_EQ(2U, s[1]->InputCount());
+  EXPECT_EQ(s.ToVreg(param1), s.ToVreg(s[0]->InputAt(0)));
+}
+
+
+TEST_F(InstructionSelectorTest, BetterLeftOperandTestMulBinop) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* param1 = m.Parameter(0);
+  Node* param2 = m.Parameter(1);
+  Node* mul = m.Int32Mul(param1, param2);
+  m.Return(m.Int32Mul(mul, param1));
+  Stream s = m.Build();
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kIA32Imul, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  ASSERT_TRUE(s[0]->InputAt(0)->IsUnallocated());
+  EXPECT_EQ(s.ToVreg(param2), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(param1), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+// -----------------------------------------------------------------------------
+// Conversions.
+
+
+TEST_F(InstructionSelectorTest, ChangeUint32ToFloat64WithParameter) {
+  StreamBuilder m(this, kMachFloat64, kMachUint32);
+  m.Return(m.ChangeUint32ToFloat64(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kSSEUint32ToFloat64, s[0]->arch_opcode());
+}
+
+
+// -----------------------------------------------------------------------------
+// Loads and stores
+
+
+namespace {
+
+struct MemoryAccess {
+  MachineType type;
+  ArchOpcode load_opcode;
+  ArchOpcode store_opcode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
+  return os << memacc.type;
+}
+
+
+static const MemoryAccess kMemoryAccesses[] = {
+    {kMachInt8, kIA32Movsxbl, kIA32Movb},
+    {kMachUint8, kIA32Movzxbl, kIA32Movb},
+    {kMachInt16, kIA32Movsxwl, kIA32Movw},
+    {kMachUint16, kIA32Movzxwl, kIA32Movw},
+    {kMachInt32, kIA32Movl, kIA32Movl},
+    {kMachUint32, kIA32Movl, kIA32Movl},
+    {kMachFloat32, kIA32Movss, kIA32Movss},
+    {kMachFloat64, kIA32Movsd, kIA32Movsd}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccess>
+    InstructionSelectorMemoryAccessTest;
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
+  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateBase) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, base, kImmediates) {
+    StreamBuilder m(this, memacc.type, kMachPtr);
+    m.Return(m.Load(memacc.type, m.Int32Constant(base), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
+    if (base == 0) {
+      ASSERT_EQ(1U, s[0]->InputCount());
+    } else {
+      ASSERT_EQ(2U, s[0]->InputCount());
+      ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+      EXPECT_EQ(base, s.ToInt32(s[0]->InputAt(1)));
+    }
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, kImmediates) {
+    StreamBuilder m(this, memacc.type, kMachPtr);
+    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
+    if (index == 0) {
+      ASSERT_EQ(1U, s[0]->InputCount());
+    } else {
+      ASSERT_EQ(2U, s[0]->InputCount());
+      ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+      EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    }
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
+  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(0U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateBase) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, base, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachInt32, memacc.type);
+    m.Store(memacc.type, m.Int32Constant(base), m.Parameter(0), m.Parameter(1));
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
+    if (base == 0) {
+      ASSERT_EQ(2U, s[0]->InputCount());
+    } else {
+      ASSERT_EQ(3U, s[0]->InputCount());
+      ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+      EXPECT_EQ(base, s.ToInt32(s[0]->InputAt(1)));
+    }
+    EXPECT_EQ(0U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) {
+  const MemoryAccess memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, kImmediates) {
+    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
+    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
+            m.Parameter(1));
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
+    if (index == 0) {
+      ASSERT_EQ(2U, s[0]->InputCount());
+    } else {
+      ASSERT_EQ(3U, s[0]->InputCount());
+      ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+      EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    }
+    EXPECT_EQ(0U, s[0]->OutputCount());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessTest,
+                        ::testing::ValuesIn(kMemoryAccesses));
+
+
+// -----------------------------------------------------------------------------
+// AddressingMode for loads and stores.
+
+
+class AddressingModeUnitTest : public InstructionSelectorTest {
+ public:
+  AddressingModeUnitTest() : m(NULL) { Reset(); }
+  ~AddressingModeUnitTest() { delete m; }
+
+  void Run(Node* base, Node* load_index, Node* store_index,
+           AddressingMode mode) {
+    Node* load = m->Load(kMachInt32, base, load_index);
+    m->Store(kMachInt32, base, store_index, load);
+    m->Return(m->Int32Constant(0));
+    Stream s = m->Build();
+    ASSERT_EQ(2U, s.size());
+    EXPECT_EQ(mode, s[0]->addressing_mode());
+    EXPECT_EQ(mode, s[1]->addressing_mode());
+  }
+
+  Node* zero;
+  Node* null_ptr;
+  Node* non_zero;
+  Node* base_reg;   // opaque value to generate base as register
+  Node* index_reg;  // opaque value to generate index as register
+  Node* scales[4];
+  StreamBuilder* m;
+
+  void Reset() {
+    delete m;
+    m = new StreamBuilder(this, kMachInt32, kMachInt32, kMachInt32);
+    zero = m->Int32Constant(0);
+    null_ptr = m->Int32Constant(0);
+    non_zero = m->Int32Constant(127);
+    base_reg = m->Parameter(0);
+    index_reg = m->Parameter(0);
+
+    scales[0] = m->Int32Constant(1);
+    scales[1] = m->Int32Constant(2);
+    scales[2] = m->Int32Constant(4);
+    scales[3] = m->Int32Constant(8);
+  }
+};
+
+
+TEST_F(AddressingModeUnitTest, AddressingMode_MR) {
+  Node* base = base_reg;
+  Node* index = zero;
+  Run(base, index, index, kMode_MR);
+}
+
+
+TEST_F(AddressingModeUnitTest, AddressingMode_MRI) {
+  Node* base = base_reg;
+  Node* index = non_zero;
+  Run(base, index, index, kMode_MRI);
+}
+
+
+TEST_F(AddressingModeUnitTest, AddressingMode_MR1) {
+  Node* base = base_reg;
+  Node* index = index_reg;
+  Run(base, index, index, kMode_MR1);
+}
+
+
+TEST_F(AddressingModeUnitTest, AddressingMode_MRN) {
+  AddressingMode expected[] = {kMode_MR1, kMode_MR2, kMode_MR4, kMode_MR8};
+  for (size_t i = 0; i < arraysize(scales); ++i) {
+    Reset();
+    Node* base = base_reg;
+    Node* load_index = m->Int32Mul(index_reg, scales[i]);
+    Node* store_index = m->Int32Mul(index_reg, scales[i]);
+    Run(base, load_index, store_index, expected[i]);
+  }
+}
+
+
+TEST_F(AddressingModeUnitTest, AddressingMode_MR1I) {
+  Node* base = base_reg;
+  Node* load_index = m->Int32Add(index_reg, non_zero);
+  Node* store_index = m->Int32Add(index_reg, non_zero);
+  Run(base, load_index, store_index, kMode_MR1I);
+}
+
+
+TEST_F(AddressingModeUnitTest, AddressingMode_MRNI) {
+  AddressingMode expected[] = {kMode_MR1I, kMode_MR2I, kMode_MR4I, kMode_MR8I};
+  for (size_t i = 0; i < arraysize(scales); ++i) {
+    Reset();
+    Node* base = base_reg;
+    Node* load_index = m->Int32Add(m->Int32Mul(index_reg, scales[i]), non_zero);
+    Node* store_index =
+        m->Int32Add(m->Int32Mul(index_reg, scales[i]), non_zero);
+    Run(base, load_index, store_index, expected[i]);
+  }
+}
+
+
+TEST_F(AddressingModeUnitTest, AddressingMode_M1ToMR) {
+  Node* base = null_ptr;
+  Node* index = index_reg;
+  // M1 maps to MR
+  Run(base, index, index, kMode_MR);
+}
+
+
+TEST_F(AddressingModeUnitTest, AddressingMode_MN) {
+  AddressingMode expected[] = {kMode_MR, kMode_M2, kMode_M4, kMode_M8};
+  for (size_t i = 0; i < arraysize(scales); ++i) {
+    Reset();
+    Node* base = null_ptr;
+    Node* load_index = m->Int32Mul(index_reg, scales[i]);
+    Node* store_index = m->Int32Mul(index_reg, scales[i]);
+    Run(base, load_index, store_index, expected[i]);
+  }
+}
+
+
+TEST_F(AddressingModeUnitTest, AddressingMode_M1IToMRI) {
+  Node* base = null_ptr;
+  Node* load_index = m->Int32Add(index_reg, non_zero);
+  Node* store_index = m->Int32Add(index_reg, non_zero);
+  // M1I maps to MRI
+  Run(base, load_index, store_index, kMode_MRI);
+}
+
+
+TEST_F(AddressingModeUnitTest, AddressingMode_MNI) {
+  AddressingMode expected[] = {kMode_MRI, kMode_M2I, kMode_M4I, kMode_M8I};
+  for (size_t i = 0; i < arraysize(scales); ++i) {
+    Reset();
+    Node* base = null_ptr;
+    Node* load_index = m->Int32Add(m->Int32Mul(index_reg, scales[i]), non_zero);
+    Node* store_index =
+        m->Int32Add(m->Int32Mul(index_reg, scales[i]), non_zero);
+    Run(base, load_index, store_index, expected[i]);
+  }
+}
+
+
+TEST_F(AddressingModeUnitTest, AddressingMode_MI) {
+  Node* bases[] = {null_ptr, non_zero};
+  Node* indices[] = {zero, non_zero};
+  for (size_t i = 0; i < arraysize(bases); ++i) {
+    for (size_t j = 0; j < arraysize(indices); ++j) {
+      Reset();
+      Node* base = bases[i];
+      Node* index = indices[j];
+      Run(base, index, index, kMode_MI);
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Multiplication.
+
+
+namespace {
+
+struct MultParam {
+  int value;
+  bool lea_expected;
+  AddressingMode addressing_mode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MultParam& m) {
+  return os << m.value << "." << m.lea_expected << "." << m.addressing_mode;
+}
+
+
+const MultParam kMultParams[] = {{-1, false, kMode_None},
+                                 {0, false, kMode_None},
+                                 {1, true, kMode_MR},
+                                 {2, true, kMode_M2},
+                                 {3, true, kMode_MR2},
+                                 {4, true, kMode_M4},
+                                 {5, true, kMode_MR4},
+                                 {6, false, kMode_None},
+                                 {7, false, kMode_None},
+                                 {8, true, kMode_M8},
+                                 {9, true, kMode_MR8},
+                                 {10, false, kMode_None},
+                                 {11, false, kMode_None}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<MultParam> InstructionSelectorMultTest;
+
+
+static unsigned InputCountForLea(AddressingMode mode) {
+  switch (mode) {
+    case kMode_MR1I:
+    case kMode_MR2I:
+    case kMode_MR4I:
+    case kMode_MR8I:
+      return 3U;
+    case kMode_M1I:
+    case kMode_M2I:
+    case kMode_M4I:
+    case kMode_M8I:
+      return 2U;
+    case kMode_MR1:
+    case kMode_MR2:
+    case kMode_MR4:
+    case kMode_MR8:
+    case kMode_MRI:
+      return 2U;
+    case kMode_M1:
+    case kMode_M2:
+    case kMode_M4:
+    case kMode_M8:
+    case kMode_MI:
+    case kMode_MR:
+      return 1U;
+    default:
+      UNREACHABLE();
+      return 0U;
+  }
+}
+
+
+static AddressingMode AddressingModeForAddMult(int32_t imm,
+                                               const MultParam& m) {
+  if (imm == 0) return m.addressing_mode;
+  switch (m.addressing_mode) {
+    case kMode_MR1:
+      return kMode_MR1I;
+    case kMode_MR2:
+      return kMode_MR2I;
+    case kMode_MR4:
+      return kMode_MR4I;
+    case kMode_MR8:
+      return kMode_MR8I;
+    case kMode_M1:
+      return kMode_M1I;
+    case kMode_M2:
+      return kMode_M2I;
+    case kMode_M4:
+      return kMode_M4I;
+    case kMode_M8:
+      return kMode_M8I;
+    case kMode_MR:
+      return kMode_MRI;
+    default:
+      UNREACHABLE();
+      return kMode_None;
+  }
+}
+
+
+TEST_P(InstructionSelectorMultTest, Mult32) {
+  const MultParam m_param = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachInt32);
+  Node* param = m.Parameter(0);
+  Node* mult = m.Int32Mul(param, m.Int32Constant(m_param.value));
+  m.Return(mult);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(m_param.addressing_mode, s[0]->addressing_mode());
+  if (m_param.lea_expected) {
+    EXPECT_EQ(kIA32Lea, s[0]->arch_opcode());
+    ASSERT_EQ(InputCountForLea(s[0]->addressing_mode()), s[0]->InputCount());
+  } else {
+    EXPECT_EQ(kIA32Imul, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+  }
+  EXPECT_EQ(s.ToVreg(param), s.ToVreg(s[0]->InputAt(0)));
+}
+
+
+TEST_P(InstructionSelectorMultTest, MultAdd32) {
+  TRACED_FOREACH(int32_t, imm, kImmediates) {
+    const MultParam m_param = GetParam();
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    Node* param = m.Parameter(0);
+    Node* mult = m.Int32Add(m.Int32Mul(param, m.Int32Constant(m_param.value)),
+                            m.Int32Constant(imm));
+    m.Return(mult);
+    Stream s = m.Build();
+    if (m_param.lea_expected) {
+      ASSERT_EQ(1U, s.size());
+      EXPECT_EQ(kIA32Lea, s[0]->arch_opcode());
+      EXPECT_EQ(AddressingModeForAddMult(imm, m_param),
+                s[0]->addressing_mode());
+      unsigned input_count = InputCountForLea(s[0]->addressing_mode());
+      ASSERT_EQ(input_count, s[0]->InputCount());
+      if (imm != 0) {
+        ASSERT_EQ(InstructionOperand::IMMEDIATE,
+                  s[0]->InputAt(input_count - 1)->kind());
+        EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(input_count - 1)));
+      }
+    } else {
+      ASSERT_EQ(2U, s.size());
+      EXPECT_EQ(kIA32Imul, s[0]->arch_opcode());
+      EXPECT_EQ(kIA32Lea, s[1]->arch_opcode());
+    }
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMultTest,
+                        ::testing::ValuesIn(kMultParams));
+
+
+TEST_F(InstructionSelectorTest, Int32MulHigh) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const n = m.Int32MulHigh(p0, p1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kIA32ImulHigh, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), eax));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1)));
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), edx));
+}
+
+
+TEST_F(InstructionSelectorTest, Float64BinopArithmetic) {
+  {
+    StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64);
+    Node* add = m.Float64Add(m.Parameter(0), m.Parameter(1));
+    Node* mul = m.Float64Mul(add, m.Parameter(1));
+    Node* sub = m.Float64Sub(mul, add);
+    Node* ret = m.Float64Div(mul, sub);
+    m.Return(ret);
+    Stream s = m.Build(AVX);
+    ASSERT_EQ(4U, s.size());
+    EXPECT_EQ(kAVXFloat64Add, s[0]->arch_opcode());
+    EXPECT_EQ(kAVXFloat64Mul, s[1]->arch_opcode());
+    EXPECT_EQ(kAVXFloat64Sub, s[2]->arch_opcode());
+    EXPECT_EQ(kAVXFloat64Div, s[3]->arch_opcode());
+  }
+  {
+    StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64);
+    Node* add = m.Float64Add(m.Parameter(0), m.Parameter(1));
+    Node* mul = m.Float64Mul(add, m.Parameter(1));
+    Node* sub = m.Float64Sub(mul, add);
+    Node* ret = m.Float64Div(mul, sub);
+    m.Return(ret);
+    Stream s = m.Build();
+    ASSERT_EQ(4U, s.size());
+    EXPECT_EQ(kSSEFloat64Add, s[0]->arch_opcode());
+    EXPECT_EQ(kSSEFloat64Mul, s[1]->arch_opcode());
+    EXPECT_EQ(kSSEFloat64Sub, s[2]->arch_opcode());
+    EXPECT_EQ(kSSEFloat64Div, s[3]->arch_opcode());
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/instruction-selector-unittest.cc b/test/unittests/compiler/instruction-selector-unittest.cc
new file mode 100644
index 0000000..c79a9e4
--- /dev/null
+++ b/test/unittests/compiler/instruction-selector-unittest.cc
@@ -0,0 +1,589 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "test/unittests/compiler/instruction-selector-unittest.h"
+
+#include "src/compiler/graph-inl.h"
+#include "src/flags.h"
+#include "test/unittests/compiler/compiler-test-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+typedef RawMachineAssembler::Label MLabel;
+
+}  // namespace
+
+
+InstructionSelectorTest::InstructionSelectorTest() : rng_(FLAG_random_seed) {}
+
+
+InstructionSelectorTest::~InstructionSelectorTest() {}
+
+
+InstructionSelectorTest::Stream InstructionSelectorTest::StreamBuilder::Build(
+    InstructionSelector::Features features,
+    InstructionSelectorTest::StreamBuilderMode mode) {
+  Schedule* schedule = Export();
+  if (FLAG_trace_turbo) {
+    OFStream out(stdout);
+    out << "=== Schedule before instruction selection ===" << std::endl
+        << *schedule;
+  }
+  EXPECT_NE(0, graph()->NodeCount());
+  int initial_node_count = graph()->NodeCount();
+  Linkage linkage(test_->zone(), call_descriptor());
+  InstructionBlocks* instruction_blocks =
+      InstructionSequence::InstructionBlocksFor(test_->zone(), schedule);
+  InstructionSequence sequence(test_->zone(), instruction_blocks);
+  SourcePositionTable source_position_table(graph());
+  InstructionSelector selector(test_->zone(), graph(), &linkage, &sequence,
+                               schedule, &source_position_table, features);
+  selector.SelectInstructions();
+  if (FLAG_trace_turbo) {
+    OFStream out(stdout);
+    PrintableInstructionSequence printable = {
+        RegisterConfiguration::ArchDefault(), &sequence};
+    out << "=== Code sequence after instruction selection ===" << std::endl
+        << printable;
+  }
+  Stream s;
+  // Map virtual registers.
+  {
+    const NodeToVregMap& node_map = selector.GetNodeMapForTesting();
+    for (int i = 0; i < initial_node_count; ++i) {
+      if (node_map[i] != InstructionSelector::kNodeUnmapped) {
+        s.virtual_registers_.insert(std::make_pair(i, node_map[i]));
+      }
+    }
+  }
+  std::set<int> virtual_registers;
+  for (InstructionSequence::const_iterator i = sequence.begin();
+       i != sequence.end(); ++i) {
+    Instruction* instr = *i;
+    if (instr->opcode() < 0) continue;
+    if (mode == kTargetInstructions) {
+      switch (instr->arch_opcode()) {
+#define CASE(Name) \
+  case k##Name:    \
+    break;
+        TARGET_ARCH_OPCODE_LIST(CASE)
+#undef CASE
+        default:
+          continue;
+      }
+    }
+    if (mode == kAllExceptNopInstructions && instr->arch_opcode() == kArchNop) {
+      continue;
+    }
+    for (size_t i = 0; i < instr->OutputCount(); ++i) {
+      InstructionOperand* output = instr->OutputAt(i);
+      EXPECT_NE(InstructionOperand::IMMEDIATE, output->kind());
+      if (output->IsConstant()) {
+        s.constants_.insert(std::make_pair(
+            output->index(), sequence.GetConstant(output->index())));
+        virtual_registers.insert(output->index());
+      } else if (output->IsUnallocated()) {
+        virtual_registers.insert(
+            UnallocatedOperand::cast(output)->virtual_register());
+      }
+    }
+    for (size_t i = 0; i < instr->InputCount(); ++i) {
+      InstructionOperand* input = instr->InputAt(i);
+      EXPECT_NE(InstructionOperand::CONSTANT, input->kind());
+      if (input->IsImmediate()) {
+        s.immediates_.insert(std::make_pair(
+            input->index(), sequence.GetImmediate(input->index())));
+      } else if (input->IsUnallocated()) {
+        virtual_registers.insert(
+            UnallocatedOperand::cast(input)->virtual_register());
+      }
+    }
+    s.instructions_.push_back(instr);
+  }
+  for (std::set<int>::const_iterator i = virtual_registers.begin();
+       i != virtual_registers.end(); ++i) {
+    int virtual_register = *i;
+    if (sequence.IsDouble(virtual_register)) {
+      EXPECT_FALSE(sequence.IsReference(virtual_register));
+      s.doubles_.insert(virtual_register);
+    }
+    if (sequence.IsReference(virtual_register)) {
+      EXPECT_FALSE(sequence.IsDouble(virtual_register));
+      s.references_.insert(virtual_register);
+    }
+  }
+  for (int i = 0; i < sequence.GetFrameStateDescriptorCount(); i++) {
+    s.deoptimization_entries_.push_back(sequence.GetFrameStateDescriptor(
+        InstructionSequence::StateId::FromInt(i)));
+  }
+  return s;
+}
+
+
+int InstructionSelectorTest::Stream::ToVreg(const Node* node) const {
+  VirtualRegisters::const_iterator i = virtual_registers_.find(node->id());
+  CHECK(i != virtual_registers_.end());
+  return i->second;
+}
+
+
+bool InstructionSelectorTest::Stream::IsFixed(const InstructionOperand* operand,
+                                              Register reg) const {
+  if (!operand->IsUnallocated()) return false;
+  const UnallocatedOperand* unallocated = UnallocatedOperand::cast(operand);
+  if (!unallocated->HasFixedRegisterPolicy()) return false;
+  const int index = Register::ToAllocationIndex(reg);
+  return unallocated->fixed_register_index() == index;
+}
+
+
+bool InstructionSelectorTest::Stream::IsSameAsFirst(
+    const InstructionOperand* operand) const {
+  if (!operand->IsUnallocated()) return false;
+  const UnallocatedOperand* unallocated = UnallocatedOperand::cast(operand);
+  return unallocated->HasSameAsInputPolicy();
+}
+
+
+bool InstructionSelectorTest::Stream::IsUsedAtStart(
+    const InstructionOperand* operand) const {
+  if (!operand->IsUnallocated()) return false;
+  const UnallocatedOperand* unallocated = UnallocatedOperand::cast(operand);
+  return unallocated->IsUsedAtStart();
+}
+
+
+// -----------------------------------------------------------------------------
+// Return.
+
+
+TARGET_TEST_F(InstructionSelectorTest, ReturnFloat32Constant) {
+  const float kValue = 4.2f;
+  StreamBuilder m(this, kMachFloat32);
+  m.Return(m.Float32Constant(kValue));
+  Stream s = m.Build(kAllInstructions);
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
+  ASSERT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind());
+  EXPECT_FLOAT_EQ(kValue, s.ToFloat32(s[0]->OutputAt(0)));
+  EXPECT_EQ(kArchRet, s[1]->arch_opcode());
+  EXPECT_EQ(1U, s[1]->InputCount());
+}
+
+
+TARGET_TEST_F(InstructionSelectorTest, ReturnParameter) {
+  StreamBuilder m(this, kMachInt32, kMachInt32);
+  m.Return(m.Parameter(0));
+  Stream s = m.Build(kAllInstructions);
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kArchRet, s[1]->arch_opcode());
+  EXPECT_EQ(1U, s[1]->InputCount());
+}
+
+
+TARGET_TEST_F(InstructionSelectorTest, ReturnZero) {
+  StreamBuilder m(this, kMachInt32);
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build(kAllInstructions);
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(InstructionOperand::CONSTANT, s[0]->OutputAt(0)->kind());
+  EXPECT_EQ(0, s.ToInt32(s[0]->OutputAt(0)));
+  EXPECT_EQ(kArchRet, s[1]->arch_opcode());
+  EXPECT_EQ(1U, s[1]->InputCount());
+}
+
+
+// -----------------------------------------------------------------------------
+// Conversions.
+
+
+TARGET_TEST_F(InstructionSelectorTest, TruncateFloat64ToInt32WithParameter) {
+  StreamBuilder m(this, kMachInt32, kMachFloat64);
+  m.Return(m.TruncateFloat64ToInt32(m.Parameter(0)));
+  Stream s = m.Build(kAllInstructions);
+  ASSERT_EQ(3U, s.size());
+  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
+  EXPECT_EQ(kArchTruncateDoubleToI, s[1]->arch_opcode());
+  EXPECT_EQ(1U, s[1]->InputCount());
+  EXPECT_EQ(1U, s[1]->OutputCount());
+  EXPECT_EQ(kArchRet, s[2]->arch_opcode());
+}
+
+
+// -----------------------------------------------------------------------------
+// Parameters.
+
+
+TARGET_TEST_F(InstructionSelectorTest, DoubleParameter) {
+  StreamBuilder m(this, kMachFloat64, kMachFloat64);
+  Node* param = m.Parameter(0);
+  m.Return(param);
+  Stream s = m.Build(kAllInstructions);
+  EXPECT_TRUE(s.IsDouble(param));
+}
+
+
+TARGET_TEST_F(InstructionSelectorTest, ReferenceParameter) {
+  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged);
+  Node* param = m.Parameter(0);
+  m.Return(param);
+  Stream s = m.Build(kAllInstructions);
+  EXPECT_TRUE(s.IsReference(param));
+}
+
+
+// -----------------------------------------------------------------------------
+// Finish.
+
+
+TARGET_TEST_F(InstructionSelectorTest, Finish) {
+  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged);
+  Node* param = m.Parameter(0);
+  Node* finish = m.NewNode(m.common()->Finish(1), param, m.graph()->start());
+  m.Return(finish);
+  Stream s = m.Build(kAllInstructions);
+  ASSERT_EQ(3U, s.size());
+  EXPECT_EQ(kArchNop, s[0]->arch_opcode());
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  ASSERT_TRUE(s[0]->Output()->IsUnallocated());
+  EXPECT_EQ(s.ToVreg(param), s.ToVreg(s[0]->Output()));
+  EXPECT_EQ(kArchNop, s[1]->arch_opcode());
+  ASSERT_EQ(1U, s[1]->InputCount());
+  ASSERT_TRUE(s[1]->InputAt(0)->IsUnallocated());
+  EXPECT_EQ(s.ToVreg(param), s.ToVreg(s[1]->InputAt(0)));
+  ASSERT_EQ(1U, s[1]->OutputCount());
+  ASSERT_TRUE(s[1]->Output()->IsUnallocated());
+  EXPECT_TRUE(UnallocatedOperand::cast(s[1]->Output())->HasSameAsInputPolicy());
+  EXPECT_EQ(s.ToVreg(finish), s.ToVreg(s[1]->Output()));
+  EXPECT_TRUE(s.IsReference(finish));
+}
+
+
+// -----------------------------------------------------------------------------
+// Phi.
+
+
+typedef InstructionSelectorTestWithParam<MachineType>
+    InstructionSelectorPhiTest;
+
+
+TARGET_TEST_P(InstructionSelectorPhiTest, Doubleness) {
+  const MachineType type = GetParam();
+  StreamBuilder m(this, type, type, type);
+  Node* param0 = m.Parameter(0);
+  Node* param1 = m.Parameter(1);
+  MLabel a, b, c;
+  m.Branch(m.Int32Constant(0), &a, &b);
+  m.Bind(&a);
+  m.Goto(&c);
+  m.Bind(&b);
+  m.Goto(&c);
+  m.Bind(&c);
+  Node* phi = m.Phi(type, param0, param1);
+  m.Return(phi);
+  Stream s = m.Build(kAllInstructions);
+  EXPECT_EQ(s.IsDouble(phi), s.IsDouble(param0));
+  EXPECT_EQ(s.IsDouble(phi), s.IsDouble(param1));
+}
+
+
+TARGET_TEST_P(InstructionSelectorPhiTest, Referenceness) {
+  const MachineType type = GetParam();
+  StreamBuilder m(this, type, type, type);
+  Node* param0 = m.Parameter(0);
+  Node* param1 = m.Parameter(1);
+  MLabel a, b, c;
+  m.Branch(m.Int32Constant(1), &a, &b);
+  m.Bind(&a);
+  m.Goto(&c);
+  m.Bind(&b);
+  m.Goto(&c);
+  m.Bind(&c);
+  Node* phi = m.Phi(type, param0, param1);
+  m.Return(phi);
+  Stream s = m.Build(kAllInstructions);
+  EXPECT_EQ(s.IsReference(phi), s.IsReference(param0));
+  EXPECT_EQ(s.IsReference(phi), s.IsReference(param1));
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorPhiTest,
+                        ::testing::Values(kMachFloat64, kMachInt8, kMachUint8,
+                                          kMachInt16, kMachUint16, kMachInt32,
+                                          kMachUint32, kMachInt64, kMachUint64,
+                                          kMachPtr, kMachAnyTagged));
+
+
+// -----------------------------------------------------------------------------
+// ValueEffect.
+
+
+TARGET_TEST_F(InstructionSelectorTest, ValueEffect) {
+  StreamBuilder m1(this, kMachInt32, kMachPtr);
+  Node* p1 = m1.Parameter(0);
+  m1.Return(m1.Load(kMachInt32, p1, m1.Int32Constant(0)));
+  Stream s1 = m1.Build(kAllInstructions);
+  StreamBuilder m2(this, kMachInt32, kMachPtr);
+  Node* p2 = m2.Parameter(0);
+  m2.Return(m2.NewNode(m2.machine()->Load(kMachInt32), p2, m2.Int32Constant(0),
+                       m2.NewNode(m2.common()->ValueEffect(1), p2)));
+  Stream s2 = m2.Build(kAllInstructions);
+  EXPECT_LE(3U, s1.size());
+  ASSERT_EQ(s1.size(), s2.size());
+  TRACED_FORRANGE(size_t, i, 0, s1.size() - 1) {
+    const Instruction* i1 = s1[i];
+    const Instruction* i2 = s2[i];
+    EXPECT_EQ(i1->arch_opcode(), i2->arch_opcode());
+    EXPECT_EQ(i1->InputCount(), i2->InputCount());
+    EXPECT_EQ(i1->OutputCount(), i2->OutputCount());
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Calls with deoptimization.
+
+
+TARGET_TEST_F(InstructionSelectorTest, CallJSFunctionWithDeopt) {
+  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
+                  kMachAnyTagged);
+
+  BailoutId bailout_id(42);
+
+  Node* function_node = m.Parameter(0);
+  Node* receiver = m.Parameter(1);
+  Node* context = m.Parameter(2);
+
+  Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(1));
+  Node* locals = m.NewNode(m.common()->StateValues(0));
+  Node* stack = m.NewNode(m.common()->StateValues(0));
+  Node* context_dummy = m.Int32Constant(0);
+
+  Node* state_node = m.NewNode(
+      m.common()->FrameState(JS_FRAME, bailout_id,
+                             OutputFrameStateCombine::Push()),
+      parameters, locals, stack, context_dummy, m.UndefinedConstant());
+  Node* call = m.CallJS0(function_node, receiver, context, state_node);
+  m.Return(call);
+
+  Stream s = m.Build(kAllExceptNopInstructions);
+
+  // Skip until kArchCallJSFunction.
+  size_t index = 0;
+  for (; index < s.size() && s[index]->arch_opcode() != kArchCallJSFunction;
+       index++) {
+  }
+  // Now we should have two instructions: call and return.
+  ASSERT_EQ(index + 2, s.size());
+
+  EXPECT_EQ(kArchCallJSFunction, s[index++]->arch_opcode());
+  EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
+
+  // TODO(jarin) Check deoptimization table.
+}
+
+
+TARGET_TEST_F(InstructionSelectorTest, CallFunctionStubWithDeopt) {
+  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
+                  kMachAnyTagged);
+
+  BailoutId bailout_id_before(42);
+
+  // Some arguments for the call node.
+  Node* function_node = m.Parameter(0);
+  Node* receiver = m.Parameter(1);
+  Node* context = m.Int32Constant(1);  // Context is ignored.
+
+  // Build frame state for the state before the call.
+  Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(43));
+  Node* locals = m.NewNode(m.common()->StateValues(1), m.Float64Constant(0.5));
+  Node* stack = m.NewNode(m.common()->StateValues(1), m.UndefinedConstant());
+
+  Node* context_sentinel = m.Int32Constant(0);
+  Node* frame_state_before = m.NewNode(
+      m.common()->FrameState(JS_FRAME, bailout_id_before,
+                             OutputFrameStateCombine::Push()),
+      parameters, locals, stack, context_sentinel, m.UndefinedConstant());
+
+  // Build the call.
+  Node* call = m.CallFunctionStub0(function_node, receiver, context,
+                                   frame_state_before, CALL_AS_METHOD);
+
+  m.Return(call);
+
+  Stream s = m.Build(kAllExceptNopInstructions);
+
+  // Skip until kArchCallJSFunction.
+  size_t index = 0;
+  for (; index < s.size() && s[index]->arch_opcode() != kArchCallCodeObject;
+       index++) {
+  }
+  // Now we should have two instructions: call, return.
+  ASSERT_EQ(index + 2, s.size());
+
+  // Check the call instruction
+  const Instruction* call_instr = s[index++];
+  EXPECT_EQ(kArchCallCodeObject, call_instr->arch_opcode());
+  size_t num_operands =
+      1 +  // Code object.
+      1 +
+      4 +  // Frame state deopt id + one input for each value in frame state.
+      1 +  // Function.
+      1;   // Context.
+  ASSERT_EQ(num_operands, call_instr->InputCount());
+
+  // Code object.
+  EXPECT_TRUE(call_instr->InputAt(0)->IsImmediate());
+
+  // Deoptimization id.
+  int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1));
+  FrameStateDescriptor* desc_before =
+      s.GetFrameStateDescriptor(deopt_id_before);
+  EXPECT_EQ(bailout_id_before, desc_before->bailout_id());
+  EXPECT_EQ(OutputFrameStateCombine::kPushOutput,
+            desc_before->state_combine().kind());
+  EXPECT_EQ(1u, desc_before->parameters_count());
+  EXPECT_EQ(1u, desc_before->locals_count());
+  EXPECT_EQ(1u, desc_before->stack_count());
+  EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(2)));
+  EXPECT_EQ(0, s.ToInt32(call_instr->InputAt(3)));  // This should be a context.
+                                                    // We inserted 0 here.
+  EXPECT_EQ(0.5, s.ToFloat64(call_instr->InputAt(4)));
+  EXPECT_TRUE(s.ToHeapObject(call_instr->InputAt(5))->IsUndefined());
+  EXPECT_EQ(kMachInt32, desc_before->GetType(0));
+  EXPECT_EQ(kMachAnyTagged, desc_before->GetType(1));  // context is always
+                                                       // tagged/any.
+  EXPECT_EQ(kMachFloat64, desc_before->GetType(2));
+  EXPECT_EQ(kMachAnyTagged, desc_before->GetType(3));
+
+  // Function.
+  EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(6)));
+  // Context.
+  EXPECT_EQ(s.ToVreg(context), s.ToVreg(call_instr->InputAt(7)));
+
+  EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
+
+  EXPECT_EQ(index, s.size());
+}
+
+
+TARGET_TEST_F(InstructionSelectorTest,
+              CallFunctionStubDeoptRecursiveFrameState) {
+  StreamBuilder m(this, kMachAnyTagged, kMachAnyTagged, kMachAnyTagged,
+                  kMachAnyTagged);
+
+  BailoutId bailout_id_before(42);
+  BailoutId bailout_id_parent(62);
+
+  // Some arguments for the call node.
+  Node* function_node = m.Parameter(0);
+  Node* receiver = m.Parameter(1);
+  Node* context = m.Int32Constant(66);
+
+  // Build frame state for the state before the call.
+  Node* parameters = m.NewNode(m.common()->StateValues(1), m.Int32Constant(63));
+  Node* locals = m.NewNode(m.common()->StateValues(1), m.Int32Constant(64));
+  Node* stack = m.NewNode(m.common()->StateValues(1), m.Int32Constant(65));
+  Node* frame_state_parent =
+      m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id_parent,
+                                       OutputFrameStateCombine::Ignore()),
+                parameters, locals, stack, context, m.UndefinedConstant());
+
+  Node* context2 = m.Int32Constant(46);
+  Node* parameters2 =
+      m.NewNode(m.common()->StateValues(1), m.Int32Constant(43));
+  Node* locals2 =
+      m.NewNode(m.common()->StateValues(1), m.Float64Constant(0.25));
+  Node* stack2 = m.NewNode(m.common()->StateValues(2), m.Int32Constant(44),
+                           m.Int32Constant(45));
+  Node* frame_state_before =
+      m.NewNode(m.common()->FrameState(JS_FRAME, bailout_id_before,
+                                       OutputFrameStateCombine::Push()),
+                parameters2, locals2, stack2, context2, frame_state_parent);
+
+  // Build the call.
+  Node* call = m.CallFunctionStub0(function_node, receiver, context2,
+                                   frame_state_before, CALL_AS_METHOD);
+
+  m.Return(call);
+
+  Stream s = m.Build(kAllExceptNopInstructions);
+
+  // Skip until kArchCallJSFunction.
+  size_t index = 0;
+  for (; index < s.size() && s[index]->arch_opcode() != kArchCallCodeObject;
+       index++) {
+  }
+  // Now we should have three instructions: call, return.
+  EXPECT_EQ(index + 2, s.size());
+
+  // Check the call instruction
+  const Instruction* call_instr = s[index++];
+  EXPECT_EQ(kArchCallCodeObject, call_instr->arch_opcode());
+  size_t num_operands =
+      1 +  // Code object.
+      1 +  // Frame state deopt id
+      5 +  // One input for each value in frame state + context.
+      4 +  // One input for each value in the parent frame state + context.
+      1 +  // Function.
+      1;   // Context.
+  EXPECT_EQ(num_operands, call_instr->InputCount());
+  // Code object.
+  EXPECT_TRUE(call_instr->InputAt(0)->IsImmediate());
+
+  // Deoptimization id.
+  int32_t deopt_id_before = s.ToInt32(call_instr->InputAt(1));
+  FrameStateDescriptor* desc_before =
+      s.GetFrameStateDescriptor(deopt_id_before);
+  FrameStateDescriptor* desc_before_outer = desc_before->outer_state();
+  EXPECT_EQ(bailout_id_before, desc_before->bailout_id());
+  EXPECT_EQ(1u, desc_before_outer->parameters_count());
+  EXPECT_EQ(1u, desc_before_outer->locals_count());
+  EXPECT_EQ(1u, desc_before_outer->stack_count());
+  // Values from parent environment.
+  EXPECT_EQ(63, s.ToInt32(call_instr->InputAt(2)));
+  EXPECT_EQ(kMachInt32, desc_before_outer->GetType(0));
+  // Context:
+  EXPECT_EQ(66, s.ToInt32(call_instr->InputAt(3)));
+  EXPECT_EQ(kMachAnyTagged, desc_before_outer->GetType(1));
+  EXPECT_EQ(64, s.ToInt32(call_instr->InputAt(4)));
+  EXPECT_EQ(kMachInt32, desc_before_outer->GetType(2));
+  EXPECT_EQ(65, s.ToInt32(call_instr->InputAt(5)));
+  EXPECT_EQ(kMachInt32, desc_before_outer->GetType(3));
+  // Values from the nested frame.
+  EXPECT_EQ(1u, desc_before->parameters_count());
+  EXPECT_EQ(1u, desc_before->locals_count());
+  EXPECT_EQ(2u, desc_before->stack_count());
+  EXPECT_EQ(43, s.ToInt32(call_instr->InputAt(6)));
+  EXPECT_EQ(kMachInt32, desc_before->GetType(0));
+  EXPECT_EQ(46, s.ToInt32(call_instr->InputAt(7)));
+  EXPECT_EQ(kMachAnyTagged, desc_before->GetType(1));
+  EXPECT_EQ(0.25, s.ToFloat64(call_instr->InputAt(8)));
+  EXPECT_EQ(kMachFloat64, desc_before->GetType(2));
+  EXPECT_EQ(44, s.ToInt32(call_instr->InputAt(9)));
+  EXPECT_EQ(kMachInt32, desc_before->GetType(3));
+  EXPECT_EQ(45, s.ToInt32(call_instr->InputAt(10)));
+  EXPECT_EQ(kMachInt32, desc_before->GetType(4));
+
+  // Function.
+  EXPECT_EQ(s.ToVreg(function_node), s.ToVreg(call_instr->InputAt(11)));
+  // Context.
+  EXPECT_EQ(s.ToVreg(context2), s.ToVreg(call_instr->InputAt(12)));
+  // Continuation.
+
+  EXPECT_EQ(kArchRet, s[index++]->arch_opcode());
+  EXPECT_EQ(index, s.size());
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/instruction-selector-unittest.h b/test/unittests/compiler/instruction-selector-unittest.h
new file mode 100644
index 0000000..e65d68b
--- /dev/null
+++ b/test/unittests/compiler/instruction-selector-unittest.h
@@ -0,0 +1,241 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_UNITTESTS_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_
+#define V8_UNITTESTS_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_
+
+#include <deque>
+#include <set>
+
+#include "src/base/utils/random-number-generator.h"
+#include "src/compiler/instruction-selector.h"
+#include "src/compiler/raw-machine-assembler.h"
+#include "src/macro-assembler.h"
+#include "test/unittests/test-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class InstructionSelectorTest : public TestWithContext, public TestWithZone {
+ public:
+  InstructionSelectorTest();
+  ~InstructionSelectorTest() OVERRIDE;
+
+  base::RandomNumberGenerator* rng() { return &rng_; }
+
+  class Stream;
+
+  enum StreamBuilderMode {
+    kAllInstructions,
+    kTargetInstructions,
+    kAllExceptNopInstructions
+  };
+
+  class StreamBuilder FINAL : public RawMachineAssembler {
+   public:
+    StreamBuilder(InstructionSelectorTest* test, MachineType return_type)
+        : RawMachineAssembler(new (test->zone()) Graph(test->zone()),
+                              MakeMachineSignature(test->zone(), return_type)),
+          test_(test) {}
+    StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
+                  MachineType parameter0_type)
+        : RawMachineAssembler(
+              new (test->zone()) Graph(test->zone()),
+              MakeMachineSignature(test->zone(), return_type, parameter0_type)),
+          test_(test) {}
+    StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
+                  MachineType parameter0_type, MachineType parameter1_type)
+        : RawMachineAssembler(
+              new (test->zone()) Graph(test->zone()),
+              MakeMachineSignature(test->zone(), return_type, parameter0_type,
+                                   parameter1_type)),
+          test_(test) {}
+    StreamBuilder(InstructionSelectorTest* test, MachineType return_type,
+                  MachineType parameter0_type, MachineType parameter1_type,
+                  MachineType parameter2_type)
+        : RawMachineAssembler(
+              new (test->zone()) Graph(test->zone()),
+              MakeMachineSignature(test->zone(), return_type, parameter0_type,
+                                   parameter1_type, parameter2_type)),
+          test_(test) {}
+
+    Stream Build(CpuFeature feature) {
+      return Build(InstructionSelector::Features(feature));
+    }
+    Stream Build(CpuFeature feature1, CpuFeature feature2) {
+      return Build(InstructionSelector::Features(feature1, feature2));
+    }
+    Stream Build(StreamBuilderMode mode = kTargetInstructions) {
+      return Build(InstructionSelector::Features(), mode);
+    }
+    Stream Build(InstructionSelector::Features features,
+                 StreamBuilderMode mode = kTargetInstructions);
+
+   private:
+    MachineSignature* MakeMachineSignature(Zone* zone,
+                                           MachineType return_type) {
+      MachineSignature::Builder builder(zone, 1, 0);
+      builder.AddReturn(return_type);
+      return builder.Build();
+    }
+
+    MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type,
+                                           MachineType parameter0_type) {
+      MachineSignature::Builder builder(zone, 1, 1);
+      builder.AddReturn(return_type);
+      builder.AddParam(parameter0_type);
+      return builder.Build();
+    }
+
+    MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type,
+                                           MachineType parameter0_type,
+                                           MachineType parameter1_type) {
+      MachineSignature::Builder builder(zone, 1, 2);
+      builder.AddReturn(return_type);
+      builder.AddParam(parameter0_type);
+      builder.AddParam(parameter1_type);
+      return builder.Build();
+    }
+
+    MachineSignature* MakeMachineSignature(Zone* zone, MachineType return_type,
+                                           MachineType parameter0_type,
+                                           MachineType parameter1_type,
+                                           MachineType parameter2_type) {
+      MachineSignature::Builder builder(zone, 1, 3);
+      builder.AddReturn(return_type);
+      builder.AddParam(parameter0_type);
+      builder.AddParam(parameter1_type);
+      builder.AddParam(parameter2_type);
+      return builder.Build();
+    }
+
+   private:
+    InstructionSelectorTest* test_;
+  };
+
+  class Stream FINAL {
+   public:
+    size_t size() const { return instructions_.size(); }
+    const Instruction* operator[](size_t index) const {
+      EXPECT_LT(index, size());
+      return instructions_[index];
+    }
+
+    bool IsDouble(const InstructionOperand* operand) const {
+      return IsDouble(ToVreg(operand));
+    }
+
+    bool IsDouble(const Node* node) const { return IsDouble(ToVreg(node)); }
+
+    bool IsInteger(const InstructionOperand* operand) const {
+      return IsInteger(ToVreg(operand));
+    }
+
+    bool IsInteger(const Node* node) const { return IsInteger(ToVreg(node)); }
+
+    bool IsReference(const InstructionOperand* operand) const {
+      return IsReference(ToVreg(operand));
+    }
+
+    bool IsReference(const Node* node) const {
+      return IsReference(ToVreg(node));
+    }
+
+    float ToFloat32(const InstructionOperand* operand) const {
+      return ToConstant(operand).ToFloat32();
+    }
+
+    double ToFloat64(const InstructionOperand* operand) const {
+      return ToConstant(operand).ToFloat64();
+    }
+
+    int32_t ToInt32(const InstructionOperand* operand) const {
+      return ToConstant(operand).ToInt32();
+    }
+
+    int64_t ToInt64(const InstructionOperand* operand) const {
+      return ToConstant(operand).ToInt64();
+    }
+
+    Handle<HeapObject> ToHeapObject(const InstructionOperand* operand) const {
+      return ToConstant(operand).ToHeapObject();
+    }
+
+    int ToVreg(const InstructionOperand* operand) const {
+      if (operand->IsConstant()) return operand->index();
+      EXPECT_EQ(InstructionOperand::UNALLOCATED, operand->kind());
+      return UnallocatedOperand::cast(operand)->virtual_register();
+    }
+
+    int ToVreg(const Node* node) const;
+
+    bool IsFixed(const InstructionOperand* operand, Register reg) const;
+    bool IsSameAsFirst(const InstructionOperand* operand) const;
+    bool IsUsedAtStart(const InstructionOperand* operand) const;
+
+    FrameStateDescriptor* GetFrameStateDescriptor(int deoptimization_id) {
+      EXPECT_LT(deoptimization_id, GetFrameStateDescriptorCount());
+      return deoptimization_entries_[deoptimization_id];
+    }
+
+    int GetFrameStateDescriptorCount() {
+      return static_cast<int>(deoptimization_entries_.size());
+    }
+
+   private:
+    bool IsDouble(int virtual_register) const {
+      return doubles_.find(virtual_register) != doubles_.end();
+    }
+
+    bool IsInteger(int virtual_register) const {
+      return !IsDouble(virtual_register) && !IsReference(virtual_register);
+    }
+
+    bool IsReference(int virtual_register) const {
+      return references_.find(virtual_register) != references_.end();
+    }
+
+    Constant ToConstant(const InstructionOperand* operand) const {
+      ConstantMap::const_iterator i;
+      if (operand->IsConstant()) {
+        i = constants_.find(operand->index());
+        EXPECT_FALSE(constants_.end() == i);
+      } else {
+        EXPECT_EQ(InstructionOperand::IMMEDIATE, operand->kind());
+        i = immediates_.find(operand->index());
+        EXPECT_FALSE(immediates_.end() == i);
+      }
+      EXPECT_EQ(operand->index(), i->first);
+      return i->second;
+    }
+
+    friend class StreamBuilder;
+
+    typedef std::map<int, Constant> ConstantMap;
+    typedef std::map<NodeId, int> VirtualRegisters;
+
+    ConstantMap constants_;
+    ConstantMap immediates_;
+    std::deque<Instruction*> instructions_;
+    std::set<int> doubles_;
+    std::set<int> references_;
+    VirtualRegisters virtual_registers_;
+    std::deque<FrameStateDescriptor*> deoptimization_entries_;
+  };
+
+  base::RandomNumberGenerator rng_;
+};
+
+
+template <typename T>
+class InstructionSelectorTestWithParam
+    : public InstructionSelectorTest,
+      public ::testing::WithParamInterface<T> {};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_UNITTESTS_COMPILER_INSTRUCTION_SELECTOR_UNITTEST_H_
diff --git a/test/unittests/compiler/instruction-sequence-unittest.cc b/test/unittests/compiler/instruction-sequence-unittest.cc
new file mode 100644
index 0000000..9546376
--- /dev/null
+++ b/test/unittests/compiler/instruction-sequence-unittest.cc
@@ -0,0 +1,475 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/base/utils/random-number-generator.h"
+#include "src/compiler/pipeline.h"
+#include "test/unittests/compiler/instruction-sequence-unittest.h"
+#include "test/unittests/test-utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+static const char*
+    general_register_names_[RegisterConfiguration::kMaxGeneralRegisters];
+static const char*
+    double_register_names_[RegisterConfiguration::kMaxDoubleRegisters];
+static char register_names_[10 * (RegisterConfiguration::kMaxGeneralRegisters +
+                                  RegisterConfiguration::kMaxDoubleRegisters)];
+
+
+static void InitializeRegisterNames() {
+  char* loc = register_names_;
+  for (int i = 0; i < RegisterConfiguration::kMaxGeneralRegisters; ++i) {
+    general_register_names_[i] = loc;
+    loc += base::OS::SNPrintF(loc, 100, "gp_%d", i);
+    *loc++ = 0;
+  }
+  for (int i = 0; i < RegisterConfiguration::kMaxDoubleRegisters; ++i) {
+    double_register_names_[i] = loc;
+    loc += base::OS::SNPrintF(loc, 100, "fp_%d", i) + 1;
+    *loc++ = 0;
+  }
+}
+
+
+InstructionSequenceTest::InstructionSequenceTest()
+    : sequence_(nullptr),
+      num_general_registers_(kDefaultNRegs),
+      num_double_registers_(kDefaultNRegs),
+      instruction_blocks_(zone()),
+      current_instruction_index_(-1),
+      current_block_(nullptr),
+      block_returns_(false) {
+  InitializeRegisterNames();
+}
+
+
+void InstructionSequenceTest::SetNumRegs(int num_general_registers,
+                                         int num_double_registers) {
+  CHECK(config_.is_empty());
+  CHECK(instructions_.empty());
+  CHECK(instruction_blocks_.empty());
+  num_general_registers_ = num_general_registers;
+  num_double_registers_ = num_double_registers;
+}
+
+
+RegisterConfiguration* InstructionSequenceTest::config() {
+  if (config_.is_empty()) {
+    config_.Reset(new RegisterConfiguration(
+        num_general_registers_, num_double_registers_, num_double_registers_,
+        general_register_names_, double_register_names_));
+  }
+  return config_.get();
+}
+
+
+InstructionSequence* InstructionSequenceTest::sequence() {
+  if (sequence_ == nullptr) {
+    sequence_ = new (zone()) InstructionSequence(zone(), &instruction_blocks_);
+  }
+  return sequence_;
+}
+
+
+void InstructionSequenceTest::StartLoop(int loop_blocks) {
+  CHECK(current_block_ == nullptr);
+  if (!loop_blocks_.empty()) {
+    CHECK(!loop_blocks_.back().loop_header_.IsValid());
+  }
+  LoopData loop_data = {Rpo::Invalid(), loop_blocks};
+  loop_blocks_.push_back(loop_data);
+}
+
+
+void InstructionSequenceTest::EndLoop() {
+  CHECK(current_block_ == nullptr);
+  CHECK(!loop_blocks_.empty());
+  CHECK_EQ(0, loop_blocks_.back().expected_blocks_);
+  loop_blocks_.pop_back();
+}
+
+
+void InstructionSequenceTest::StartBlock() {
+  block_returns_ = false;
+  NewBlock();
+}
+
+
+int InstructionSequenceTest::EndBlock(BlockCompletion completion) {
+  int instruction_index = kMinInt;
+  if (block_returns_) {
+    CHECK(completion.type_ == kBlockEnd || completion.type_ == kFallThrough);
+    completion.type_ = kBlockEnd;
+  }
+  switch (completion.type_) {
+    case kBlockEnd:
+      break;
+    case kFallThrough:
+      instruction_index = EmitFallThrough();
+      break;
+    case kJump:
+      CHECK(!block_returns_);
+      instruction_index = EmitJump();
+      break;
+    case kBranch:
+      CHECK(!block_returns_);
+      instruction_index = EmitBranch(completion.op_);
+      break;
+  }
+  completions_.push_back(completion);
+  CHECK(current_block_ != nullptr);
+  sequence()->EndBlock(current_block_->rpo_number());
+  current_block_ = nullptr;
+  return instruction_index;
+}
+
+
+InstructionSequenceTest::TestOperand InstructionSequenceTest::Imm(int32_t imm) {
+  int index = sequence()->AddImmediate(Constant(imm));
+  return TestOperand(kImmediate, index);
+}
+
+
+InstructionSequenceTest::VReg InstructionSequenceTest::Define(
+    TestOperand output_op) {
+  VReg vreg = NewReg();
+  InstructionOperand* outputs[1]{ConvertOutputOp(vreg, output_op)};
+  Emit(vreg.value_, kArchNop, 1, outputs);
+  return vreg;
+}
+
+
+int InstructionSequenceTest::Return(TestOperand input_op_0) {
+  block_returns_ = true;
+  InstructionOperand* inputs[1]{ConvertInputOp(input_op_0)};
+  return Emit(NewIndex(), kArchRet, 0, nullptr, 1, inputs);
+}
+
+
+PhiInstruction* InstructionSequenceTest::Phi(VReg incoming_vreg_0,
+                                             VReg incoming_vreg_1,
+                                             VReg incoming_vreg_2,
+                                             VReg incoming_vreg_3) {
+  auto phi = new (zone()) PhiInstruction(zone(), NewReg().value_, 10);
+  VReg inputs[] = {incoming_vreg_0, incoming_vreg_1, incoming_vreg_2,
+                   incoming_vreg_3};
+  for (size_t i = 0; i < arraysize(inputs); ++i) {
+    if (inputs[i].value_ == kNoValue) break;
+    Extend(phi, inputs[i]);
+  }
+  current_block_->AddPhi(phi);
+  return phi;
+}
+
+
+void InstructionSequenceTest::Extend(PhiInstruction* phi, VReg vreg) {
+  phi->Extend(zone(), vreg.value_);
+}
+
+
+InstructionSequenceTest::VReg InstructionSequenceTest::DefineConstant(
+    int32_t imm) {
+  VReg vreg = NewReg();
+  sequence()->AddConstant(vreg.value_, Constant(imm));
+  InstructionOperand* outputs[1]{ConstantOperand::Create(vreg.value_, zone())};
+  Emit(vreg.value_, kArchNop, 1, outputs);
+  return vreg;
+}
+
+
+int InstructionSequenceTest::EmitNop() { return Emit(NewIndex(), kArchNop); }
+
+
+static size_t CountInputs(size_t size,
+                          InstructionSequenceTest::TestOperand* inputs) {
+  size_t i = 0;
+  for (; i < size; ++i) {
+    if (inputs[i].type_ == InstructionSequenceTest::kInvalid) break;
+  }
+  return i;
+}
+
+
+int InstructionSequenceTest::EmitI(size_t input_size, TestOperand* inputs) {
+  InstructionOperand** mapped_inputs = ConvertInputs(input_size, inputs);
+  return Emit(NewIndex(), kArchNop, 0, nullptr, input_size, mapped_inputs);
+}
+
+
+int InstructionSequenceTest::EmitI(TestOperand input_op_0,
+                                   TestOperand input_op_1,
+                                   TestOperand input_op_2,
+                                   TestOperand input_op_3) {
+  TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3};
+  return EmitI(CountInputs(arraysize(inputs), inputs), inputs);
+}
+
+
+InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI(
+    TestOperand output_op, size_t input_size, TestOperand* inputs) {
+  VReg output_vreg = NewReg();
+  InstructionOperand* outputs[1]{ConvertOutputOp(output_vreg, output_op)};
+  InstructionOperand** mapped_inputs = ConvertInputs(input_size, inputs);
+  Emit(output_vreg.value_, kArchNop, 1, outputs, input_size, mapped_inputs);
+  return output_vreg;
+}
+
+
+InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI(
+    TestOperand output_op, TestOperand input_op_0, TestOperand input_op_1,
+    TestOperand input_op_2, TestOperand input_op_3) {
+  TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3};
+  return EmitOI(output_op, CountInputs(arraysize(inputs), inputs), inputs);
+}
+
+
+InstructionSequenceTest::VReg InstructionSequenceTest::EmitCall(
+    TestOperand output_op, size_t input_size, TestOperand* inputs) {
+  VReg output_vreg = NewReg();
+  InstructionOperand* outputs[1]{ConvertOutputOp(output_vreg, output_op)};
+  CHECK(UnallocatedOperand::cast(outputs[0])->HasFixedPolicy());
+  InstructionOperand** mapped_inputs = ConvertInputs(input_size, inputs);
+  Emit(output_vreg.value_, kArchCallCodeObject, 1, outputs, input_size,
+       mapped_inputs, 0, nullptr, true);
+  return output_vreg;
+}
+
+
+InstructionSequenceTest::VReg InstructionSequenceTest::EmitCall(
+    TestOperand output_op, TestOperand input_op_0, TestOperand input_op_1,
+    TestOperand input_op_2, TestOperand input_op_3) {
+  TestOperand inputs[] = {input_op_0, input_op_1, input_op_2, input_op_3};
+  return EmitCall(output_op, CountInputs(arraysize(inputs), inputs), inputs);
+}
+
+
+const Instruction* InstructionSequenceTest::GetInstruction(
+    int instruction_index) {
+  auto it = instructions_.find(instruction_index);
+  CHECK(it != instructions_.end());
+  return it->second;
+}
+
+
+int InstructionSequenceTest::EmitBranch(TestOperand input_op) {
+  InstructionOperand* inputs[4]{ConvertInputOp(input_op), ConvertInputOp(Imm()),
+                                ConvertInputOp(Imm()), ConvertInputOp(Imm())};
+  InstructionCode opcode = kArchJmp | FlagsModeField::encode(kFlags_branch) |
+                           FlagsConditionField::encode(kEqual);
+  auto instruction =
+      NewInstruction(opcode, 0, nullptr, 4, inputs)->MarkAsControl();
+  return AddInstruction(NewIndex(), instruction);
+}
+
+
+int InstructionSequenceTest::EmitFallThrough() {
+  auto instruction = NewInstruction(kArchNop, 0, nullptr)->MarkAsControl();
+  return AddInstruction(NewIndex(), instruction);
+}
+
+
+int InstructionSequenceTest::EmitJump() {
+  InstructionOperand* inputs[1]{ConvertInputOp(Imm())};
+  auto instruction =
+      NewInstruction(kArchJmp, 0, nullptr, 1, inputs)->MarkAsControl();
+  return AddInstruction(NewIndex(), instruction);
+}
+
+
+Instruction* InstructionSequenceTest::NewInstruction(
+    InstructionCode code, size_t outputs_size, InstructionOperand** outputs,
+    size_t inputs_size, InstructionOperand** inputs, size_t temps_size,
+    InstructionOperand** temps) {
+  CHECK_NE(nullptr, current_block_);
+  return Instruction::New(zone(), code, outputs_size, outputs, inputs_size,
+                          inputs, temps_size, temps);
+}
+
+
+InstructionOperand* InstructionSequenceTest::Unallocated(
+    TestOperand op, UnallocatedOperand::ExtendedPolicy policy) {
+  auto unallocated = new (zone()) UnallocatedOperand(policy);
+  unallocated->set_virtual_register(op.vreg_.value_);
+  return unallocated;
+}
+
+
+InstructionOperand* InstructionSequenceTest::Unallocated(
+    TestOperand op, UnallocatedOperand::ExtendedPolicy policy,
+    UnallocatedOperand::Lifetime lifetime) {
+  auto unallocated = new (zone()) UnallocatedOperand(policy, lifetime);
+  unallocated->set_virtual_register(op.vreg_.value_);
+  return unallocated;
+}
+
+
+InstructionOperand* InstructionSequenceTest::Unallocated(
+    TestOperand op, UnallocatedOperand::ExtendedPolicy policy, int index) {
+  auto unallocated = new (zone()) UnallocatedOperand(policy, index);
+  unallocated->set_virtual_register(op.vreg_.value_);
+  return unallocated;
+}
+
+
+InstructionOperand* InstructionSequenceTest::Unallocated(
+    TestOperand op, UnallocatedOperand::BasicPolicy policy, int index) {
+  auto unallocated = new (zone()) UnallocatedOperand(policy, index);
+  unallocated->set_virtual_register(op.vreg_.value_);
+  return unallocated;
+}
+
+
+InstructionOperand** InstructionSequenceTest::ConvertInputs(
+    size_t input_size, TestOperand* inputs) {
+  InstructionOperand** mapped_inputs =
+      zone()->NewArray<InstructionOperand*>(static_cast<int>(input_size));
+  for (size_t i = 0; i < input_size; ++i) {
+    mapped_inputs[i] = ConvertInputOp(inputs[i]);
+  }
+  return mapped_inputs;
+}
+
+
+InstructionOperand* InstructionSequenceTest::ConvertInputOp(TestOperand op) {
+  if (op.type_ == kImmediate) {
+    CHECK_EQ(op.vreg_.value_, kNoValue);
+    return ImmediateOperand::Create(op.value_, zone());
+  }
+  CHECK_NE(op.vreg_.value_, kNoValue);
+  switch (op.type_) {
+    case kNone:
+      return Unallocated(op, UnallocatedOperand::NONE,
+                         UnallocatedOperand::USED_AT_START);
+    case kUnique:
+      return Unallocated(op, UnallocatedOperand::NONE);
+    case kUniqueRegister:
+      return Unallocated(op, UnallocatedOperand::MUST_HAVE_REGISTER);
+    case kRegister:
+      return Unallocated(op, UnallocatedOperand::MUST_HAVE_REGISTER,
+                         UnallocatedOperand::USED_AT_START);
+    case kFixedRegister:
+      CHECK(0 <= op.value_ && op.value_ < num_general_registers_);
+      return Unallocated(op, UnallocatedOperand::FIXED_REGISTER, op.value_);
+    case kFixedSlot:
+      return Unallocated(op, UnallocatedOperand::FIXED_SLOT, op.value_);
+    default:
+      break;
+  }
+  CHECK(false);
+  return NULL;
+}
+
+
+InstructionOperand* InstructionSequenceTest::ConvertOutputOp(VReg vreg,
+                                                             TestOperand op) {
+  CHECK_EQ(op.vreg_.value_, kNoValue);
+  op.vreg_ = vreg;
+  switch (op.type_) {
+    case kSameAsFirst:
+      return Unallocated(op, UnallocatedOperand::SAME_AS_FIRST_INPUT);
+    case kRegister:
+      return Unallocated(op, UnallocatedOperand::MUST_HAVE_REGISTER);
+    case kFixedSlot:
+      return Unallocated(op, UnallocatedOperand::FIXED_SLOT, op.value_);
+    case kFixedRegister:
+      CHECK(0 <= op.value_ && op.value_ < num_general_registers_);
+      return Unallocated(op, UnallocatedOperand::FIXED_REGISTER, op.value_);
+    default:
+      break;
+  }
+  CHECK(false);
+  return NULL;
+}
+
+
+InstructionBlock* InstructionSequenceTest::NewBlock() {
+  CHECK(current_block_ == nullptr);
+  auto block_id = BasicBlock::Id::FromSize(instruction_blocks_.size());
+  Rpo rpo = Rpo::FromInt(block_id.ToInt());
+  Rpo loop_header = Rpo::Invalid();
+  Rpo loop_end = Rpo::Invalid();
+  if (!loop_blocks_.empty()) {
+    auto& loop_data = loop_blocks_.back();
+    // This is a loop header.
+    if (!loop_data.loop_header_.IsValid()) {
+      loop_end = Rpo::FromInt(block_id.ToInt() + loop_data.expected_blocks_);
+      loop_data.expected_blocks_--;
+      loop_data.loop_header_ = rpo;
+    } else {
+      // This is a loop body.
+      CHECK_NE(0, loop_data.expected_blocks_);
+      // TODO(dcarney): handle nested loops.
+      loop_data.expected_blocks_--;
+      loop_header = loop_data.loop_header_;
+    }
+  }
+  // Construct instruction block.
+  auto instruction_block = new (zone())
+      InstructionBlock(zone(), block_id, rpo, loop_header, loop_end, false);
+  instruction_blocks_.push_back(instruction_block);
+  current_block_ = instruction_block;
+  sequence()->StartBlock(rpo);
+  return instruction_block;
+}
+
+
+void InstructionSequenceTest::WireBlocks() {
+  CHECK_EQ(nullptr, current_block());
+  CHECK(instruction_blocks_.size() == completions_.size());
+  size_t offset = 0;
+  for (const auto& completion : completions_) {
+    switch (completion.type_) {
+      case kBlockEnd:
+        break;
+      case kFallThrough:  // Fallthrough.
+      case kJump:
+        WireBlock(offset, completion.offset_0_);
+        break;
+      case kBranch:
+        WireBlock(offset, completion.offset_0_);
+        WireBlock(offset, completion.offset_1_);
+        break;
+    }
+    ++offset;
+  }
+}
+
+
+void InstructionSequenceTest::WireBlock(size_t block_offset, int jump_offset) {
+  size_t target_block_offset = block_offset + static_cast<size_t>(jump_offset);
+  CHECK(block_offset < instruction_blocks_.size());
+  CHECK(target_block_offset < instruction_blocks_.size());
+  auto block = instruction_blocks_[block_offset];
+  auto target = instruction_blocks_[target_block_offset];
+  block->successors().push_back(target->rpo_number());
+  target->predecessors().push_back(block->rpo_number());
+}
+
+
+int InstructionSequenceTest::Emit(int instruction_index, InstructionCode code,
+                                  size_t outputs_size,
+                                  InstructionOperand** outputs,
+                                  size_t inputs_size,
+                                  InstructionOperand** inputs,
+                                  size_t temps_size, InstructionOperand** temps,
+                                  bool is_call) {
+  auto instruction = NewInstruction(code, outputs_size, outputs, inputs_size,
+                                    inputs, temps_size, temps);
+  if (is_call) instruction->MarkAsCall();
+  return AddInstruction(instruction_index, instruction);
+}
+
+
+int InstructionSequenceTest::AddInstruction(int instruction_index,
+                                            Instruction* instruction) {
+  sequence()->AddInstruction(instruction);
+  return instruction_index;
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/instruction-sequence-unittest.h b/test/unittests/compiler/instruction-sequence-unittest.h
new file mode 100644
index 0000000..ce0a5b4
--- /dev/null
+++ b/test/unittests/compiler/instruction-sequence-unittest.h
@@ -0,0 +1,239 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_UNITTESTS_COMPILER_INSTRUCTION_SEQUENCE_UNITTEST_H_
+#define V8_UNITTESTS_COMPILER_INSTRUCTION_SEQUENCE_UNITTEST_H_
+
+#include "src/compiler/instruction.h"
+#include "test/unittests/test-utils.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class InstructionSequenceTest : public TestWithZone {
+ public:
+  static const int kDefaultNRegs = 4;
+  static const int kNoValue = kMinInt;
+
+  typedef BasicBlock::RpoNumber Rpo;
+
+  struct VReg {
+    VReg() : value_(kNoValue) {}
+    VReg(PhiInstruction* phi) : value_(phi->virtual_register()) {}  // NOLINT
+    explicit VReg(int value) : value_(value) {}
+    int value_;
+  };
+
+  enum TestOperandType {
+    kInvalid,
+    kSameAsFirst,
+    kRegister,
+    kFixedRegister,
+    kSlot,
+    kFixedSlot,
+    kImmediate,
+    kNone,
+    kConstant,
+    kUnique,
+    kUniqueRegister
+  };
+
+  struct TestOperand {
+    TestOperand() : type_(kInvalid), vreg_(), value_(kNoValue) {}
+    TestOperand(TestOperandType type, int imm)
+        : type_(type), vreg_(), value_(imm) {}
+    TestOperand(TestOperandType type, VReg vreg, int value = kNoValue)
+        : type_(type), vreg_(vreg), value_(value) {}
+
+    TestOperandType type_;
+    VReg vreg_;
+    int value_;
+  };
+
+  static TestOperand Same() { return TestOperand(kSameAsFirst, VReg()); }
+
+  static TestOperand Reg(VReg vreg, int index = kNoValue) {
+    TestOperandType type = kRegister;
+    if (index != kNoValue) type = kFixedRegister;
+    return TestOperand(type, vreg, index);
+  }
+
+  static TestOperand Reg(int index = kNoValue) { return Reg(VReg(), index); }
+
+  static TestOperand Slot(VReg vreg, int index = kNoValue) {
+    TestOperandType type = kSlot;
+    if (index != kNoValue) type = kFixedSlot;
+    return TestOperand(type, vreg, index);
+  }
+
+  static TestOperand Slot(int index = kNoValue) { return Slot(VReg(), index); }
+
+  static TestOperand Const(int index) {
+    CHECK_NE(kNoValue, index);
+    return TestOperand(kConstant, VReg(), index);
+  }
+
+  static TestOperand Use(VReg vreg) { return TestOperand(kNone, vreg); }
+
+  static TestOperand Use() { return Use(VReg()); }
+
+  static TestOperand Unique(VReg vreg) { return TestOperand(kUnique, vreg); }
+
+  static TestOperand UniqueReg(VReg vreg) {
+    return TestOperand(kUniqueRegister, vreg);
+  }
+
+  enum BlockCompletionType { kBlockEnd, kFallThrough, kBranch, kJump };
+
+  struct BlockCompletion {
+    BlockCompletionType type_;
+    TestOperand op_;
+    int offset_0_;
+    int offset_1_;
+  };
+
+  static BlockCompletion FallThrough() {
+    BlockCompletion completion = {kFallThrough, TestOperand(), 1, kNoValue};
+    return completion;
+  }
+
+  static BlockCompletion Jump(int offset) {
+    BlockCompletion completion = {kJump, TestOperand(), offset, kNoValue};
+    return completion;
+  }
+
+  static BlockCompletion Branch(TestOperand op, int left_offset,
+                                int right_offset) {
+    BlockCompletion completion = {kBranch, op, left_offset, right_offset};
+    return completion;
+  }
+
+  static BlockCompletion Last() {
+    BlockCompletion completion = {kBlockEnd, TestOperand(), kNoValue, kNoValue};
+    return completion;
+  }
+
+  InstructionSequenceTest();
+
+  void SetNumRegs(int num_general_registers, int num_double_registers);
+  RegisterConfiguration* config();
+  InstructionSequence* sequence();
+
+  void StartLoop(int loop_blocks);
+  void EndLoop();
+  void StartBlock();
+  int EndBlock(BlockCompletion completion = FallThrough());
+
+  TestOperand Imm(int32_t imm = 0);
+  VReg Define(TestOperand output_op);
+  VReg Parameter(TestOperand output_op = Reg()) { return Define(output_op); }
+
+  int Return(TestOperand input_op_0);
+  int Return(VReg vreg) { return Return(Reg(vreg, 0)); }
+
+  PhiInstruction* Phi(VReg incoming_vreg_0 = VReg(),
+                      VReg incoming_vreg_1 = VReg(),
+                      VReg incoming_vreg_2 = VReg(),
+                      VReg incoming_vreg_3 = VReg());
+  void Extend(PhiInstruction* phi, VReg vreg);
+
+  VReg DefineConstant(int32_t imm = 0);
+  int EmitNop();
+  int EmitI(size_t input_size, TestOperand* inputs);
+  int EmitI(TestOperand input_op_0 = TestOperand(),
+            TestOperand input_op_1 = TestOperand(),
+            TestOperand input_op_2 = TestOperand(),
+            TestOperand input_op_3 = TestOperand());
+  VReg EmitOI(TestOperand output_op, size_t input_size, TestOperand* inputs);
+  VReg EmitOI(TestOperand output_op, TestOperand input_op_0 = TestOperand(),
+              TestOperand input_op_1 = TestOperand(),
+              TestOperand input_op_2 = TestOperand(),
+              TestOperand input_op_3 = TestOperand());
+  VReg EmitCall(TestOperand output_op, size_t input_size, TestOperand* inputs);
+  VReg EmitCall(TestOperand output_op, TestOperand input_op_0 = TestOperand(),
+                TestOperand input_op_1 = TestOperand(),
+                TestOperand input_op_2 = TestOperand(),
+                TestOperand input_op_3 = TestOperand());
+
+  // Get defining instruction vreg or value returned at instruction creation
+  // time when there is no return value.
+  const Instruction* GetInstruction(int instruction_index);
+
+  InstructionBlock* current_block() const { return current_block_; }
+  int num_general_registers() const { return num_general_registers_; }
+  int num_double_registers() const { return num_double_registers_; }
+
+  // Called after all instructions have been inserted.
+  void WireBlocks();
+
+ private:
+  VReg NewReg() { return VReg(sequence()->NextVirtualRegister()); }
+  int NewIndex() { return current_instruction_index_--; }
+
+  static TestOperand Invalid() { return TestOperand(kInvalid, VReg()); }
+
+  int EmitBranch(TestOperand input_op);
+  int EmitFallThrough();
+  int EmitJump();
+  Instruction* NewInstruction(InstructionCode code, size_t outputs_size,
+                              InstructionOperand** outputs,
+                              size_t inputs_size = 0,
+                              InstructionOperand* *inputs = nullptr,
+                              size_t temps_size = 0,
+                              InstructionOperand* *temps = nullptr);
+  InstructionOperand* Unallocated(TestOperand op,
+                                  UnallocatedOperand::ExtendedPolicy policy);
+  InstructionOperand* Unallocated(TestOperand op,
+                                  UnallocatedOperand::ExtendedPolicy policy,
+                                  UnallocatedOperand::Lifetime lifetime);
+  InstructionOperand* Unallocated(TestOperand op,
+                                  UnallocatedOperand::ExtendedPolicy policy,
+                                  int index);
+  InstructionOperand* Unallocated(TestOperand op,
+                                  UnallocatedOperand::BasicPolicy policy,
+                                  int index);
+  InstructionOperand** ConvertInputs(size_t input_size, TestOperand* inputs);
+  InstructionOperand* ConvertInputOp(TestOperand op);
+  InstructionOperand* ConvertOutputOp(VReg vreg, TestOperand op);
+  InstructionBlock* NewBlock();
+  void WireBlock(size_t block_offset, int jump_offset);
+
+  int Emit(int instruction_index, InstructionCode code, size_t outputs_size = 0,
+           InstructionOperand* *outputs = nullptr, size_t inputs_size = 0,
+           InstructionOperand* *inputs = nullptr, size_t temps_size = 0,
+           InstructionOperand* *temps = nullptr, bool is_call = false);
+
+  int AddInstruction(int instruction_index, Instruction* instruction);
+
+  struct LoopData {
+    Rpo loop_header_;
+    int expected_blocks_;
+  };
+
+  typedef std::vector<LoopData> LoopBlocks;
+  typedef std::map<int, const Instruction*> Instructions;
+  typedef std::vector<BlockCompletion> Completions;
+
+  SmartPointer<RegisterConfiguration> config_;
+  InstructionSequence* sequence_;
+  int num_general_registers_;
+  int num_double_registers_;
+
+  // Block building state.
+  InstructionBlocks instruction_blocks_;
+  Instructions instructions_;
+  int current_instruction_index_;
+  Completions completions_;
+  LoopBlocks loop_blocks_;
+  InstructionBlock* current_block_;
+  bool block_returns_;
+};
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_UNITTESTS_COMPILER_INSTRUCTION_SEQUENCE_UNITTEST_H_
diff --git a/test/unittests/compiler/js-builtin-reducer-unittest.cc b/test/unittests/compiler/js-builtin-reducer-unittest.cc
new file mode 100644
index 0000000..9c57282
--- /dev/null
+++ b/test/unittests/compiler/js-builtin-reducer-unittest.cc
@@ -0,0 +1,303 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/js-builtin-reducer.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/typer.h"
+#include "test/unittests/compiler/graph-unittest.h"
+#include "test/unittests/compiler/node-test-utils.h"
+#include "testing/gmock-support.h"
+
+using testing::BitEq;
+using testing::Capture;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class JSBuiltinReducerTest : public TypedGraphTest {
+ public:
+  JSBuiltinReducerTest() : javascript_(zone()) {}
+
+ protected:
+  Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags =
+                                   MachineOperatorBuilder::Flag::kNoFlags) {
+    MachineOperatorBuilder machine(zone(), kMachPtr, flags);
+    JSGraph jsgraph(graph(), common(), javascript(), &machine);
+    JSBuiltinReducer reducer(&jsgraph);
+    return reducer.Reduce(node);
+  }
+
+  Handle<JSFunction> MathFunction(const char* name) {
+    Handle<Object> m =
+        JSObject::GetProperty(isolate()->global_object(),
+                              isolate()->factory()->NewStringFromAsciiChecked(
+                                  "Math")).ToHandleChecked();
+    Handle<JSFunction> f = Handle<JSFunction>::cast(
+        JSObject::GetProperty(
+            m, isolate()->factory()->NewStringFromAsciiChecked(name))
+            .ToHandleChecked());
+    return f;
+  }
+
+  JSOperatorBuilder* javascript() { return &javascript_; }
+
+ private:
+  JSOperatorBuilder javascript_;
+};
+
+
+namespace {
+
+// TODO(mstarzinger): Find a common place and unify with test-js-typed-lowering.
+Type* const kNumberTypes[] = {
+    Type::UnsignedSmall(),       Type::NegativeSigned32(),
+    Type::NonNegativeSigned32(), Type::SignedSmall(),
+    Type::Signed32(),            Type::Unsigned32(),
+    Type::Integral32(),          Type::MinusZero(),
+    Type::NaN(),                 Type::OrderedNumber(),
+    Type::PlainNumber(),         Type::Number()};
+
+}  // namespace
+
+
+// -----------------------------------------------------------------------------
+// Math.abs
+
+
+TEST_F(JSBuiltinReducerTest, MathAbs) {
+  Handle<JSFunction> f = MathFunction("abs");
+
+  TRACED_FOREACH(Type*, t0, kNumberTypes) {
+    Node* p0 = Parameter(t0, 0);
+    Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
+    Node* call =
+        graph()->NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS),
+                         fun, UndefinedConstant(), p0);
+    Reduction r = Reduce(call);
+
+    if (t0->Is(Type::Unsigned32())) {
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(r.replacement(), p0);
+    } else {
+      Capture<Node*> branch;
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(
+          r.replacement(),
+          IsSelect(kMachNone,
+                   IsNumberLessThan(IsNumberConstant(BitEq(0.0)), p0), p0,
+                   IsNumberSubtract(IsNumberConstant(BitEq(0.0)), p0)));
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Math.sqrt
+
+
+TEST_F(JSBuiltinReducerTest, MathSqrt) {
+  Handle<JSFunction> f = MathFunction("sqrt");
+
+  TRACED_FOREACH(Type*, t0, kNumberTypes) {
+    Node* p0 = Parameter(t0, 0);
+    Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
+    Node* call =
+        graph()->NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS),
+                         fun, UndefinedConstant(), p0);
+    Reduction r = Reduce(call);
+
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsFloat64Sqrt(p0));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Math.max
+
+
+TEST_F(JSBuiltinReducerTest, MathMax0) {
+  Handle<JSFunction> f = MathFunction("max");
+
+  Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
+  Node* call =
+      graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS),
+                       fun, UndefinedConstant());
+  Reduction r = Reduce(call);
+
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsNumberConstant(-V8_INFINITY));
+}
+
+
+TEST_F(JSBuiltinReducerTest, MathMax1) {
+  Handle<JSFunction> f = MathFunction("max");
+
+  TRACED_FOREACH(Type*, t0, kNumberTypes) {
+    Node* p0 = Parameter(t0, 0);
+    Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
+    Node* call =
+        graph()->NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS),
+                         fun, UndefinedConstant(), p0);
+    Reduction r = Reduce(call);
+
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), p0);
+  }
+}
+
+
+TEST_F(JSBuiltinReducerTest, MathMax2) {
+  Handle<JSFunction> f = MathFunction("max");
+
+  TRACED_FOREACH(Type*, t0, kNumberTypes) {
+    TRACED_FOREACH(Type*, t1, kNumberTypes) {
+      Node* p0 = Parameter(t0, 0);
+      Node* p1 = Parameter(t1, 1);
+      Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
+      Node* call = graph()->NewNode(
+          javascript()->CallFunction(4, NO_CALL_FUNCTION_FLAGS), fun,
+          UndefinedConstant(), p0, p1);
+      Reduction r = Reduce(call);
+
+      if (t0->Is(Type::Integral32()) && t1->Is(Type::Integral32())) {
+        ASSERT_TRUE(r.Changed());
+        EXPECT_THAT(r.replacement(),
+                    IsSelect(kMachNone, IsNumberLessThan(p1, p0), p1, p0));
+      } else {
+        ASSERT_FALSE(r.Changed());
+        EXPECT_EQ(IrOpcode::kJSCallFunction, call->opcode());
+      }
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Math.imul
+
+
+TEST_F(JSBuiltinReducerTest, MathImul) {
+  Handle<JSFunction> f = MathFunction("imul");
+
+  TRACED_FOREACH(Type*, t0, kNumberTypes) {
+    TRACED_FOREACH(Type*, t1, kNumberTypes) {
+      Node* p0 = Parameter(t0, 0);
+      Node* p1 = Parameter(t1, 1);
+      Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
+      Node* call = graph()->NewNode(
+          javascript()->CallFunction(4, NO_CALL_FUNCTION_FLAGS), fun,
+          UndefinedConstant(), p0, p1);
+      Reduction r = Reduce(call);
+
+      if (t0->Is(Type::Integral32()) && t1->Is(Type::Integral32())) {
+        ASSERT_TRUE(r.Changed());
+        EXPECT_THAT(r.replacement(), IsInt32Mul(p0, p1));
+      } else {
+        ASSERT_FALSE(r.Changed());
+        EXPECT_EQ(IrOpcode::kJSCallFunction, call->opcode());
+      }
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Math.fround
+
+
+TEST_F(JSBuiltinReducerTest, MathFround) {
+  Handle<JSFunction> f = MathFunction("fround");
+
+  TRACED_FOREACH(Type*, t0, kNumberTypes) {
+    Node* p0 = Parameter(t0, 0);
+    Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
+    Node* call =
+        graph()->NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS),
+                         fun, UndefinedConstant(), p0);
+    Reduction r = Reduce(call);
+
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsTruncateFloat64ToFloat32(p0));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Math.floor
+
+
+TEST_F(JSBuiltinReducerTest, MathFloorAvailable) {
+  Handle<JSFunction> f = MathFunction("floor");
+
+  TRACED_FOREACH(Type*, t0, kNumberTypes) {
+    Node* p0 = Parameter(t0, 0);
+    Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
+    Node* call =
+        graph()->NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS),
+                         fun, UndefinedConstant(), p0);
+    Reduction r = Reduce(call, MachineOperatorBuilder::Flag::kFloat64Floor);
+
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsFloat64Floor(p0));
+  }
+}
+
+
+TEST_F(JSBuiltinReducerTest, MathFloorUnavailable) {
+  Handle<JSFunction> f = MathFunction("floor");
+
+  TRACED_FOREACH(Type*, t0, kNumberTypes) {
+    Node* p0 = Parameter(t0, 0);
+    Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
+    Node* call =
+        graph()->NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS),
+                         fun, UndefinedConstant(), p0);
+    Reduction r = Reduce(call, MachineOperatorBuilder::Flag::kNoFlags);
+
+    ASSERT_FALSE(r.Changed());
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Math.ceil
+
+
+TEST_F(JSBuiltinReducerTest, MathCeilAvailable) {
+  Handle<JSFunction> f = MathFunction("ceil");
+
+  TRACED_FOREACH(Type*, t0, kNumberTypes) {
+    Node* p0 = Parameter(t0, 0);
+    Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
+    Node* call =
+        graph()->NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS),
+                         fun, UndefinedConstant(), p0);
+    Reduction r = Reduce(call, MachineOperatorBuilder::Flag::kFloat64Ceil);
+
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsFloat64Ceil(p0));
+  }
+}
+
+
+TEST_F(JSBuiltinReducerTest, MathCeilUnavailable) {
+  Handle<JSFunction> f = MathFunction("ceil");
+
+  TRACED_FOREACH(Type*, t0, kNumberTypes) {
+    Node* p0 = Parameter(t0, 0);
+    Node* fun = HeapConstant(Unique<HeapObject>::CreateUninitialized(f));
+    Node* call =
+        graph()->NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS),
+                         fun, UndefinedConstant(), p0);
+    Reduction r = Reduce(call, MachineOperatorBuilder::Flag::kNoFlags);
+
+    ASSERT_FALSE(r.Changed());
+  }
+}
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/js-operator-unittest.cc b/test/unittests/compiler/js-operator-unittest.cc
new file mode 100644
index 0000000..7aa0c64
--- /dev/null
+++ b/test/unittests/compiler/js-operator-unittest.cc
@@ -0,0 +1,217 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/js-operator.h"
+#include "src/compiler/opcodes.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/operator-properties.h"
+#include "test/unittests/test-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// -----------------------------------------------------------------------------
+// Shared operators.
+
+
+namespace {
+
+struct SharedOperator {
+  const Operator* (JSOperatorBuilder::*constructor)();
+  IrOpcode::Value opcode;
+  Operator::Properties properties;
+  int value_input_count;
+  int frame_state_input_count;
+  int effect_input_count;
+  int control_input_count;
+  int value_output_count;
+  int effect_output_count;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const SharedOperator& sop) {
+  return os << IrOpcode::Mnemonic(sop.opcode);
+}
+
+
+const SharedOperator kSharedOperators[] = {
+#define SHARED(Name, properties, value_input_count, frame_state_input_count, \
+               effect_input_count, control_input_count, value_output_count,  \
+               effect_output_count)                                          \
+  {                                                                          \
+    &JSOperatorBuilder::Name, IrOpcode::kJS##Name, properties,               \
+        value_input_count, frame_state_input_count, effect_input_count,      \
+        control_input_count, value_output_count, effect_output_count         \
+  }
+    SHARED(Equal, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(NotEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(StrictEqual, Operator::kPure, 2, 0, 0, 0, 1, 0),
+    SHARED(StrictNotEqual, Operator::kPure, 2, 0, 0, 0, 1, 0),
+    SHARED(LessThan, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(GreaterThan, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(LessThanOrEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(GreaterThanOrEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(BitwiseOr, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(BitwiseXor, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(BitwiseAnd, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(ShiftLeft, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(ShiftRight, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(ShiftRightLogical, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(Add, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(Subtract, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(Multiply, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(Divide, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(Modulus, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(UnaryNot, Operator::kPure, 1, 0, 0, 0, 1, 0),
+    SHARED(ToBoolean, Operator::kPure, 1, 0, 0, 0, 1, 0),
+    SHARED(ToNumber, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
+    SHARED(ToString, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
+    SHARED(ToName, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
+    SHARED(ToObject, Operator::kNoProperties, 1, 1, 1, 1, 1, 1),
+    SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
+    SHARED(Create, Operator::kEliminatable, 0, 0, 1, 1, 1, 1),
+    SHARED(HasProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(TypeOf, Operator::kPure, 1, 0, 0, 0, 1, 0),
+    SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1),
+    SHARED(Debugger, Operator::kNoProperties, 0, 0, 1, 1, 0, 1),
+    SHARED(CreateFunctionContext, Operator::kNoProperties, 1, 0, 1, 1, 1, 1),
+    SHARED(CreateWithContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),
+    SHARED(CreateBlockContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),
+    SHARED(CreateModuleContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1),
+    SHARED(CreateScriptContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1)
+#undef SHARED
+};
+
+}  // namespace
+
+
+class JSSharedOperatorTest
+    : public TestWithZone,
+      public ::testing::WithParamInterface<SharedOperator> {};
+
+
+TEST_P(JSSharedOperatorTest, InstancesAreGloballyShared) {
+  const SharedOperator& sop = GetParam();
+  JSOperatorBuilder javascript1(zone());
+  JSOperatorBuilder javascript2(zone());
+  EXPECT_EQ((javascript1.*sop.constructor)(), (javascript2.*sop.constructor)());
+}
+
+
+TEST_P(JSSharedOperatorTest, NumberOfInputsAndOutputs) {
+  JSOperatorBuilder javascript(zone());
+  const SharedOperator& sop = GetParam();
+  const Operator* op = (javascript.*sop.constructor)();
+
+  const int context_input_count = 1;
+  // TODO(jarin): Get rid of this hack.
+  const int frame_state_input_count =
+      FLAG_turbo_deoptimization ? sop.frame_state_input_count : 0;
+  EXPECT_EQ(sop.value_input_count, op->ValueInputCount());
+  EXPECT_EQ(context_input_count, OperatorProperties::GetContextInputCount(op));
+  EXPECT_EQ(frame_state_input_count,
+            OperatorProperties::GetFrameStateInputCount(op));
+  EXPECT_EQ(sop.effect_input_count, op->EffectInputCount());
+  EXPECT_EQ(sop.control_input_count, op->ControlInputCount());
+  EXPECT_EQ(sop.value_input_count + context_input_count +
+                frame_state_input_count + sop.effect_input_count +
+                sop.control_input_count,
+            OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(sop.value_output_count, op->ValueOutputCount());
+  EXPECT_EQ(sop.effect_output_count, op->EffectOutputCount());
+  EXPECT_EQ(0, op->ControlOutputCount());
+}
+
+
+TEST_P(JSSharedOperatorTest, OpcodeIsCorrect) {
+  JSOperatorBuilder javascript(zone());
+  const SharedOperator& sop = GetParam();
+  const Operator* op = (javascript.*sop.constructor)();
+  EXPECT_EQ(sop.opcode, op->opcode());
+}
+
+
+TEST_P(JSSharedOperatorTest, Properties) {
+  JSOperatorBuilder javascript(zone());
+  const SharedOperator& sop = GetParam();
+  const Operator* op = (javascript.*sop.constructor)();
+  EXPECT_EQ(sop.properties, op->properties());
+}
+
+
+INSTANTIATE_TEST_CASE_P(JSOperatorTest, JSSharedOperatorTest,
+                        ::testing::ValuesIn(kSharedOperators));
+
+
+// -----------------------------------------------------------------------------
+// JSStoreProperty.
+
+
+class JSStorePropertyOperatorTest
+    : public TestWithZone,
+      public ::testing::WithParamInterface<StrictMode> {};
+
+
+TEST_P(JSStorePropertyOperatorTest, InstancesAreGloballyShared) {
+  const StrictMode mode = GetParam();
+  JSOperatorBuilder javascript1(zone());
+  JSOperatorBuilder javascript2(zone());
+  EXPECT_EQ(javascript1.StoreProperty(mode), javascript2.StoreProperty(mode));
+}
+
+
+TEST_P(JSStorePropertyOperatorTest, NumberOfInputsAndOutputs) {
+  JSOperatorBuilder javascript(zone());
+  const StrictMode mode = GetParam();
+  const Operator* op = javascript.StoreProperty(mode);
+
+  // TODO(jarin): Get rid of this hack.
+  const int frame_state_input_count = FLAG_turbo_deoptimization ? 1 : 0;
+  EXPECT_EQ(3, op->ValueInputCount());
+  EXPECT_EQ(1, OperatorProperties::GetContextInputCount(op));
+  EXPECT_EQ(frame_state_input_count,
+            OperatorProperties::GetFrameStateInputCount(op));
+  EXPECT_EQ(1, op->EffectInputCount());
+  EXPECT_EQ(1, op->ControlInputCount());
+  EXPECT_EQ(6 + frame_state_input_count,
+            OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(0, op->ValueOutputCount());
+  EXPECT_EQ(1, op->EffectOutputCount());
+  EXPECT_EQ(0, op->ControlOutputCount());
+}
+
+
+TEST_P(JSStorePropertyOperatorTest, OpcodeIsCorrect) {
+  JSOperatorBuilder javascript(zone());
+  const StrictMode mode = GetParam();
+  const Operator* op = javascript.StoreProperty(mode);
+  EXPECT_EQ(IrOpcode::kJSStoreProperty, op->opcode());
+}
+
+
+TEST_P(JSStorePropertyOperatorTest, OpParameter) {
+  JSOperatorBuilder javascript(zone());
+  const StrictMode mode = GetParam();
+  const Operator* op = javascript.StoreProperty(mode);
+  EXPECT_EQ(mode, OpParameter<StrictMode>(op));
+}
+
+
+TEST_P(JSStorePropertyOperatorTest, Properties) {
+  JSOperatorBuilder javascript(zone());
+  const StrictMode mode = GetParam();
+  const Operator* op = javascript.StoreProperty(mode);
+  EXPECT_EQ(Operator::kNoProperties, op->properties());
+}
+
+
+INSTANTIATE_TEST_CASE_P(JSOperatorTest, JSStorePropertyOperatorTest,
+                        ::testing::Values(SLOPPY, STRICT));
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/js-typed-lowering-unittest.cc b/test/unittests/compiler/js-typed-lowering-unittest.cc
new file mode 100644
index 0000000..97ff106
--- /dev/null
+++ b/test/unittests/compiler/js-typed-lowering-unittest.cc
@@ -0,0 +1,808 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/access-builder.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/js-operator.h"
+#include "src/compiler/js-typed-lowering.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/node-properties-inl.h"
+#include "test/unittests/compiler/compiler-test-utils.h"
+#include "test/unittests/compiler/graph-unittest.h"
+#include "test/unittests/compiler/node-test-utils.h"
+#include "testing/gmock-support.h"
+
+using testing::BitEq;
+using testing::IsNaN;
+
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+const ExternalArrayType kExternalArrayTypes[] = {
+    kExternalUint8Array,   kExternalInt8Array,   kExternalUint16Array,
+    kExternalInt16Array,   kExternalUint32Array, kExternalInt32Array,
+    kExternalFloat32Array, kExternalFloat64Array};
+
+
+const double kFloat64Values[] = {
+    -V8_INFINITY, -4.23878e+275, -5.82632e+265, -6.60355e+220, -6.26172e+212,
+    -2.56222e+211, -4.82408e+201, -1.84106e+157, -1.63662e+127, -1.55772e+100,
+    -1.67813e+72, -2.3382e+55, -3.179e+30, -1.441e+09, -1.0647e+09,
+    -7.99361e+08, -5.77375e+08, -2.20984e+08, -32757, -13171, -9970, -3984,
+    -107, -105, -92, -77, -61, -0.000208163, -1.86685e-06, -1.17296e-10,
+    -9.26358e-11, -5.08004e-60, -1.74753e-65, -1.06561e-71, -5.67879e-79,
+    -5.78459e-130, -2.90989e-171, -7.15489e-243, -3.76242e-252, -1.05639e-263,
+    -4.40497e-267, -2.19666e-273, -4.9998e-276, -5.59821e-278, -2.03855e-282,
+    -5.99335e-283, -7.17554e-284, -3.11744e-309, -0.0, 0.0, 2.22507e-308,
+    1.30127e-270, 7.62898e-260, 4.00313e-249, 3.16829e-233, 1.85244e-228,
+    2.03544e-129, 1.35126e-110, 1.01182e-106, 5.26333e-94, 1.35292e-90,
+    2.85394e-83, 1.78323e-77, 5.4967e-57, 1.03207e-25, 4.57401e-25, 1.58738e-05,
+    2, 125, 2310, 9636, 14802, 17168, 28945, 29305, 4.81336e+07, 1.41207e+08,
+    4.65962e+08, 1.40499e+09, 2.12648e+09, 8.80006e+30, 1.4446e+45, 1.12164e+54,
+    2.48188e+89, 6.71121e+102, 3.074e+112, 4.9699e+152, 5.58383e+166,
+    4.30654e+172, 7.08824e+185, 9.6586e+214, 2.028e+223, 6.63277e+243,
+    1.56192e+261, 1.23202e+269, 5.72883e+289, 8.5798e+290, 1.40256e+294,
+    1.79769e+308, V8_INFINITY};
+
+
+const size_t kIndices[] = {0, 1, 42, 100, 1024};
+
+
+const double kIntegerValues[] = {-V8_INFINITY, INT_MIN, -1000.0,  -42.0,
+                                 -1.0,         0.0,     1.0,      42.0,
+                                 1000.0,       INT_MAX, UINT_MAX, V8_INFINITY};
+
+
+Type* const kJSTypes[] = {Type::Undefined(), Type::Null(),   Type::Boolean(),
+                          Type::Number(),    Type::String(), Type::Object()};
+
+
+const StrictMode kStrictModes[] = {SLOPPY, STRICT};
+
+}  // namespace
+
+
+class JSTypedLoweringTest : public TypedGraphTest {
+ public:
+  JSTypedLoweringTest() : TypedGraphTest(3), javascript_(zone()) {}
+  ~JSTypedLoweringTest() OVERRIDE {}
+
+ protected:
+  Reduction Reduce(Node* node) {
+    MachineOperatorBuilder machine(zone());
+    JSGraph jsgraph(graph(), common(), javascript(), &machine);
+    JSTypedLowering reducer(&jsgraph, zone());
+    return reducer.Reduce(node);
+  }
+
+  Handle<JSArrayBuffer> NewArrayBuffer(void* bytes, size_t byte_length) {
+    Handle<JSArrayBuffer> buffer = factory()->NewJSArrayBuffer();
+    Runtime::SetupArrayBuffer(isolate(), buffer, true, bytes, byte_length);
+    return buffer;
+  }
+
+  Matcher<Node*> IsIntPtrConstant(intptr_t value) {
+    return sizeof(value) == 4 ? IsInt32Constant(static_cast<int32_t>(value))
+                              : IsInt64Constant(static_cast<int64_t>(value));
+  }
+
+  JSOperatorBuilder* javascript() { return &javascript_; }
+
+ private:
+  JSOperatorBuilder javascript_;
+};
+
+
+// -----------------------------------------------------------------------------
+// JSUnaryNot
+
+
+TEST_F(JSTypedLoweringTest, JSUnaryNotWithBoolean) {
+  Node* input = Parameter(Type::Boolean(), 0);
+  Node* context = Parameter(Type::Any(), 1);
+  Reduction r =
+      Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsBooleanNot(input));
+}
+
+
+TEST_F(JSTypedLoweringTest, JSUnaryNotWithFalsish) {
+  Handle<Object> zero = factory()->NewNumber(0);
+  Node* input = Parameter(
+      Type::Union(
+          Type::MinusZero(),
+          Type::Union(
+              Type::NaN(),
+              Type::Union(
+                  Type::Null(),
+                  Type::Union(
+                      Type::Undefined(),
+                      Type::Union(
+                          Type::Undetectable(),
+                          Type::Union(
+                              Type::Constant(factory()->false_value(), zone()),
+                              Type::Range(zero, zero, zone()), zone()),
+                          zone()),
+                      zone()),
+                  zone()),
+              zone()),
+          zone()),
+      0);
+  Node* context = Parameter(Type::Any(), 1);
+  Reduction r =
+      Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsTrueConstant());
+}
+
+
+TEST_F(JSTypedLoweringTest, JSUnaryNotWithTruish) {
+  Node* input = Parameter(
+      Type::Union(
+          Type::Constant(factory()->true_value(), zone()),
+          Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone()),
+          zone()),
+      0);
+  Node* context = Parameter(Type::Any(), 1);
+  Reduction r =
+      Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsFalseConstant());
+}
+
+
+TEST_F(JSTypedLoweringTest, JSUnaryNotWithNonZeroPlainNumber) {
+  Node* input = Parameter(
+      Type::Range(factory()->NewNumber(1), factory()->NewNumber(42), zone()),
+      0);
+  Node* context = Parameter(Type::Any(), 1);
+  Reduction r =
+      Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsFalseConstant());
+}
+
+
+TEST_F(JSTypedLoweringTest, JSUnaryNotWithAny) {
+  Node* input = Parameter(Type::Any(), 0);
+  Node* context = Parameter(Type::Any(), 1);
+  Reduction r =
+      Reduce(graph()->NewNode(javascript()->UnaryNot(), input, context));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsBooleanNot(IsAnyToBoolean(input)));
+}
+
+
+// -----------------------------------------------------------------------------
+// Constant propagation
+
+
+TEST_F(JSTypedLoweringTest, ParameterWithMinusZero) {
+  {
+    Reduction r = Reduce(
+        Parameter(Type::Constant(factory()->minus_zero_value(), zone())));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0));
+  }
+  {
+    Reduction r = Reduce(Parameter(Type::MinusZero()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsNumberConstant(-0.0));
+  }
+  {
+    Reduction r = Reduce(Parameter(
+        Type::Union(Type::MinusZero(),
+                    Type::Constant(factory()->NewNumber(0), zone()), zone())));
+    EXPECT_FALSE(r.Changed());
+  }
+}
+
+
+TEST_F(JSTypedLoweringTest, ParameterWithNull) {
+  Handle<HeapObject> null = factory()->null_value();
+  {
+    Reduction r = Reduce(Parameter(Type::Constant(null, zone())));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsHeapConstant(Unique<HeapObject>::CreateImmovable(null)));
+  }
+  {
+    Reduction r = Reduce(Parameter(Type::Null()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsHeapConstant(Unique<HeapObject>::CreateImmovable(null)));
+  }
+}
+
+
+TEST_F(JSTypedLoweringTest, ParameterWithNaN) {
+  const double kNaNs[] = {base::OS::nan_value(),
+                          std::numeric_limits<double>::quiet_NaN(),
+                          std::numeric_limits<double>::signaling_NaN()};
+  TRACED_FOREACH(double, nan, kNaNs) {
+    Handle<Object> constant = factory()->NewNumber(nan);
+    Reduction r = Reduce(Parameter(Type::Constant(constant, zone())));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
+  }
+  {
+    Reduction r =
+        Reduce(Parameter(Type::Constant(factory()->nan_value(), zone())));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
+  }
+  {
+    Reduction r = Reduce(Parameter(Type::NaN()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsNumberConstant(IsNaN()));
+  }
+}
+
+
+TEST_F(JSTypedLoweringTest, ParameterWithPlainNumber) {
+  TRACED_FOREACH(double, value, kFloat64Values) {
+    Handle<Object> constant = factory()->NewNumber(value);
+    Reduction r = Reduce(Parameter(Type::Constant(constant, zone())));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsNumberConstant(value));
+  }
+  TRACED_FOREACH(double, value, kIntegerValues) {
+    Handle<Object> constant = factory()->NewNumber(value);
+    Reduction r = Reduce(Parameter(Type::Range(constant, constant, zone())));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsNumberConstant(value));
+  }
+}
+
+
+TEST_F(JSTypedLoweringTest, ParameterWithUndefined) {
+  Handle<HeapObject> undefined = factory()->undefined_value();
+  {
+    Reduction r = Reduce(Parameter(Type::Undefined()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsHeapConstant(Unique<HeapObject>::CreateImmovable(undefined)));
+  }
+  {
+    Reduction r = Reduce(Parameter(Type::Constant(undefined, zone())));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsHeapConstant(Unique<HeapObject>::CreateImmovable(undefined)));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// JSToBoolean
+
+
+TEST_F(JSTypedLoweringTest, JSToBooleanWithBoolean) {
+  Node* input = Parameter(Type::Boolean(), 0);
+  Node* context = Parameter(Type::Any(), 1);
+  Reduction r =
+      Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_EQ(input, r.replacement());
+}
+
+
+TEST_F(JSTypedLoweringTest, JSToBooleanWithFalsish) {
+  Handle<Object> zero = factory()->NewNumber(0);
+  Node* input = Parameter(
+      Type::Union(
+          Type::MinusZero(),
+          Type::Union(
+              Type::NaN(),
+              Type::Union(
+                  Type::Null(),
+                  Type::Union(
+                      Type::Undefined(),
+                      Type::Union(
+                          Type::Undetectable(),
+                          Type::Union(
+                              Type::Constant(factory()->false_value(), zone()),
+                              Type::Range(zero, zero, zone()), zone()),
+                          zone()),
+                      zone()),
+                  zone()),
+              zone()),
+          zone()),
+      0);
+  Node* context = Parameter(Type::Any(), 1);
+  Reduction r =
+      Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsFalseConstant());
+}
+
+
+TEST_F(JSTypedLoweringTest, JSToBooleanWithTruish) {
+  Node* input = Parameter(
+      Type::Union(
+          Type::Constant(factory()->true_value(), zone()),
+          Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone()),
+          zone()),
+      0);
+  Node* context = Parameter(Type::Any(), 1);
+  Reduction r =
+      Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsTrueConstant());
+}
+
+
+TEST_F(JSTypedLoweringTest, JSToBooleanWithNonZeroPlainNumber) {
+  Node* input =
+      Parameter(Type::Range(factory()->NewNumber(1),
+                            factory()->NewNumber(V8_INFINITY), zone()),
+                0);
+  Node* context = Parameter(Type::Any(), 1);
+  Reduction r =
+      Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsTrueConstant());
+}
+
+
+TEST_F(JSTypedLoweringTest, JSToBooleanWithAny) {
+  Node* input = Parameter(Type::Any(), 0);
+  Node* context = Parameter(Type::Any(), 1);
+  Reduction r =
+      Reduce(graph()->NewNode(javascript()->ToBoolean(), input, context));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsAnyToBoolean(input));
+}
+
+
+// -----------------------------------------------------------------------------
+// JSToNumber
+
+
+TEST_F(JSTypedLoweringTest, JSToNumberWithPlainPrimitive) {
+  Node* const input = Parameter(Type::PlainPrimitive(), 0);
+  Node* const context = Parameter(Type::Any(), 1);
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  Reduction r = Reduce(graph()->NewNode(javascript()->ToNumber(), input,
+                                        context, effect, control));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsToNumber(input, IsNumberConstant(BitEq(0.0)),
+                                          graph()->start(), control));
+}
+
+
+// -----------------------------------------------------------------------------
+// JSStrictEqual
+
+
+TEST_F(JSTypedLoweringTest, JSStrictEqualWithTheHole) {
+  Node* const the_hole = HeapConstant(factory()->the_hole_value());
+  Node* const context = UndefinedConstant();
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  TRACED_FOREACH(Type*, type, kJSTypes) {
+    Node* const lhs = Parameter(type);
+    Reduction r = Reduce(graph()->NewNode(javascript()->StrictEqual(), lhs,
+                                          the_hole, context, effect, control));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsFalseConstant());
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// JSShiftLeft
+
+
+TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndConstant) {
+  Node* const lhs = Parameter(Type::Signed32());
+  Node* const context = UndefinedConstant();
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  TRACED_FORRANGE(double, rhs, 0, 31) {
+    Reduction r =
+        Reduce(graph()->NewNode(javascript()->ShiftLeft(), lhs,
+                                NumberConstant(rhs), context, effect, control));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsWord32Shl(lhs, IsNumberConstant(BitEq(rhs))));
+  }
+}
+
+
+TEST_F(JSTypedLoweringTest, JSShiftLeftWithSigned32AndUnsigned32) {
+  Node* const lhs = Parameter(Type::Signed32());
+  Node* const rhs = Parameter(Type::Unsigned32());
+  Node* const context = UndefinedConstant();
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  Reduction r = Reduce(graph()->NewNode(javascript()->ShiftLeft(), lhs, rhs,
+                                        context, effect, control));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(),
+              IsWord32Shl(lhs, IsWord32And(rhs, IsInt32Constant(0x1f))));
+}
+
+
+// -----------------------------------------------------------------------------
+// JSShiftRight
+
+
+TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndConstant) {
+  Node* const lhs = Parameter(Type::Signed32());
+  Node* const context = UndefinedConstant();
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  TRACED_FORRANGE(double, rhs, 0, 31) {
+    Reduction r =
+        Reduce(graph()->NewNode(javascript()->ShiftRight(), lhs,
+                                NumberConstant(rhs), context, effect, control));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsWord32Sar(lhs, IsNumberConstant(BitEq(rhs))));
+  }
+}
+
+
+TEST_F(JSTypedLoweringTest, JSShiftRightWithSigned32AndUnsigned32) {
+  Node* const lhs = Parameter(Type::Signed32());
+  Node* const rhs = Parameter(Type::Unsigned32());
+  Node* const context = UndefinedConstant();
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRight(), lhs, rhs,
+                                        context, effect, control));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(),
+              IsWord32Sar(lhs, IsWord32And(rhs, IsInt32Constant(0x1f))));
+}
+
+
+// -----------------------------------------------------------------------------
+// JSShiftRightLogical
+
+
+TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndConstant) {
+  Node* const lhs = Parameter(Type::Unsigned32());
+  Node* const context = UndefinedConstant();
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  TRACED_FORRANGE(double, rhs, 0, 31) {
+    Reduction r =
+        Reduce(graph()->NewNode(javascript()->ShiftRightLogical(), lhs,
+                                NumberConstant(rhs), context, effect, control));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsWord32Shr(lhs, IsNumberConstant(BitEq(rhs))));
+  }
+}
+
+
+TEST_F(JSTypedLoweringTest, JSShiftRightLogicalWithUnsigned32AndUnsigned32) {
+  Node* const lhs = Parameter(Type::Unsigned32());
+  Node* const rhs = Parameter(Type::Unsigned32());
+  Node* const context = UndefinedConstant();
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  Reduction r = Reduce(graph()->NewNode(javascript()->ShiftRightLogical(), lhs,
+                                        rhs, context, effect, control));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(),
+              IsWord32Shr(lhs, IsWord32And(rhs, IsInt32Constant(0x1f))));
+}
+
+
+// -----------------------------------------------------------------------------
+// JSLoadContext
+
+
+TEST_F(JSTypedLoweringTest, JSLoadContext) {
+  Node* const context = Parameter(Type::Any());
+  Node* const effect = graph()->start();
+  static bool kBooleans[] = {false, true};
+  TRACED_FOREACH(size_t, index, kIndices) {
+    TRACED_FOREACH(bool, immutable, kBooleans) {
+      Reduction const r1 = Reduce(
+          graph()->NewNode(javascript()->LoadContext(0, index, immutable),
+                           context, context, effect));
+      ASSERT_TRUE(r1.Changed());
+      EXPECT_THAT(r1.replacement(),
+                  IsLoadField(AccessBuilder::ForContextSlot(index), context,
+                              effect, graph()->start()));
+
+      Reduction const r2 = Reduce(
+          graph()->NewNode(javascript()->LoadContext(1, index, immutable),
+                           context, context, effect));
+      ASSERT_TRUE(r2.Changed());
+      EXPECT_THAT(r2.replacement(),
+                  IsLoadField(AccessBuilder::ForContextSlot(index),
+                              IsLoadField(AccessBuilder::ForContextSlot(
+                                              Context::PREVIOUS_INDEX),
+                                          context, effect, graph()->start()),
+                              effect, graph()->start()));
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// JSStoreContext
+
+
+TEST_F(JSTypedLoweringTest, JSStoreContext) {
+  Node* const context = Parameter(Type::Any());
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  TRACED_FOREACH(size_t, index, kIndices) {
+    TRACED_FOREACH(Type*, type, kJSTypes) {
+      Node* const value = Parameter(type);
+
+      Reduction const r1 =
+          Reduce(graph()->NewNode(javascript()->StoreContext(0, index), context,
+                                  value, context, effect, control));
+      ASSERT_TRUE(r1.Changed());
+      EXPECT_THAT(r1.replacement(),
+                  IsStoreField(AccessBuilder::ForContextSlot(index), context,
+                               value, effect, control));
+
+      Reduction const r2 =
+          Reduce(graph()->NewNode(javascript()->StoreContext(1, index), context,
+                                  value, context, effect, control));
+      ASSERT_TRUE(r2.Changed());
+      EXPECT_THAT(r2.replacement(),
+                  IsStoreField(AccessBuilder::ForContextSlot(index),
+                               IsLoadField(AccessBuilder::ForContextSlot(
+                                               Context::PREVIOUS_INDEX),
+                                           context, effect, graph()->start()),
+                               value, effect, control));
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// JSLoadProperty
+
+
+TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
+  const size_t kLength = 17;
+  double backing_store[kLength];
+  Handle<JSArrayBuffer> buffer =
+      NewArrayBuffer(backing_store, sizeof(backing_store));
+  VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(),
+                          FeedbackVectorICSlot::Invalid());
+  TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
+    Handle<JSTypedArray> array =
+        factory()->NewJSTypedArray(type, buffer, 0, kLength);
+    int const element_size = static_cast<int>(array->element_size());
+
+    Node* key = Parameter(
+        Type::Range(factory()->NewNumber(kMinInt / element_size),
+                    factory()->NewNumber(kMaxInt / element_size), zone()));
+    Node* base = HeapConstant(array);
+    Node* context = UndefinedConstant();
+    Node* effect = graph()->start();
+    Node* control = graph()->start();
+    Node* node = graph()->NewNode(javascript()->LoadProperty(feedback), base,
+                                  key, context);
+    if (FLAG_turbo_deoptimization) {
+      node->AppendInput(zone(), UndefinedConstant());
+    }
+    node->AppendInput(zone(), effect);
+    node->AppendInput(zone(), control);
+    Reduction r = Reduce(node);
+
+    Matcher<Node*> offset_matcher =
+        element_size == 1
+            ? key
+            : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
+
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(
+        r.replacement(),
+        IsLoadBuffer(BufferAccess(type),
+                     IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
+                     offset_matcher,
+                     IsNumberConstant(array->byte_length()->Number()), effect,
+                     control));
+  }
+}
+
+
+TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArrayWithSafeKey) {
+  const size_t kLength = 17;
+  double backing_store[kLength];
+  Handle<JSArrayBuffer> buffer =
+      NewArrayBuffer(backing_store, sizeof(backing_store));
+  VectorSlotPair feedback(Handle<TypeFeedbackVector>::null(),
+                          FeedbackVectorICSlot::Invalid());
+  TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
+    Handle<JSTypedArray> array =
+        factory()->NewJSTypedArray(type, buffer, 0, kLength);
+    ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
+
+    int min = random_number_generator()->NextInt(static_cast<int>(kLength));
+    int max = random_number_generator()->NextInt(static_cast<int>(kLength));
+    if (min > max) std::swap(min, max);
+    Node* key = Parameter(Type::Range(factory()->NewNumber(min),
+                                      factory()->NewNumber(max), zone()));
+    Node* base = HeapConstant(array);
+    Node* context = UndefinedConstant();
+    Node* effect = graph()->start();
+    Node* control = graph()->start();
+    Node* node = graph()->NewNode(javascript()->LoadProperty(feedback), base,
+                                  key, context);
+    if (FLAG_turbo_deoptimization) {
+      node->AppendInput(zone(), UndefinedConstant());
+    }
+    node->AppendInput(zone(), effect);
+    node->AppendInput(zone(), control);
+    Reduction r = Reduce(node);
+
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(
+        r.replacement(),
+        IsLoadElement(access,
+                      IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
+                      key, effect, control));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// JSStoreProperty
+
+
+TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) {
+  const size_t kLength = 17;
+  double backing_store[kLength];
+  Handle<JSArrayBuffer> buffer =
+      NewArrayBuffer(backing_store, sizeof(backing_store));
+  TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
+    TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) {
+      Handle<JSTypedArray> array =
+          factory()->NewJSTypedArray(type, buffer, 0, kLength);
+      int const element_size = static_cast<int>(array->element_size());
+
+      Node* key = Parameter(
+          Type::Range(factory()->NewNumber(kMinInt / element_size),
+                      factory()->NewNumber(kMaxInt / element_size), zone()));
+      Node* base = HeapConstant(array);
+      Node* value =
+          Parameter(AccessBuilder::ForTypedArrayElement(type, true).type);
+      Node* context = UndefinedConstant();
+      Node* effect = graph()->start();
+      Node* control = graph()->start();
+      Node* node = graph()->NewNode(javascript()->StoreProperty(strict_mode),
+                                    base, key, value, context);
+      if (FLAG_turbo_deoptimization) {
+        node->AppendInput(zone(), UndefinedConstant());
+      }
+      node->AppendInput(zone(), effect);
+      node->AppendInput(zone(), control);
+      Reduction r = Reduce(node);
+
+      Matcher<Node*> offset_matcher =
+          element_size == 1
+              ? key
+              : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
+
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(
+          r.replacement(),
+          IsStoreBuffer(BufferAccess(type),
+                        IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
+                        offset_matcher,
+                        IsNumberConstant(array->byte_length()->Number()), value,
+                        effect, control));
+    }
+  }
+}
+
+
+TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
+  const size_t kLength = 17;
+  double backing_store[kLength];
+  Handle<JSArrayBuffer> buffer =
+      NewArrayBuffer(backing_store, sizeof(backing_store));
+  TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
+    TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) {
+      Handle<JSTypedArray> array =
+          factory()->NewJSTypedArray(type, buffer, 0, kLength);
+      int const element_size = static_cast<int>(array->element_size());
+
+      Node* key = Parameter(
+          Type::Range(factory()->NewNumber(kMinInt / element_size),
+                      factory()->NewNumber(kMaxInt / element_size), zone()));
+      Node* base = HeapConstant(array);
+      Node* value = Parameter(Type::Any());
+      Node* context = UndefinedConstant();
+      Node* effect = graph()->start();
+      Node* control = graph()->start();
+      Node* node = graph()->NewNode(javascript()->StoreProperty(strict_mode),
+                                    base, key, value, context);
+      if (FLAG_turbo_deoptimization) {
+        node->AppendInput(zone(), UndefinedConstant());
+      }
+      node->AppendInput(zone(), effect);
+      node->AppendInput(zone(), control);
+      Reduction r = Reduce(node);
+
+      Matcher<Node*> offset_matcher =
+          element_size == 1
+              ? key
+              : IsWord32Shl(key, IsInt32Constant(WhichPowerOf2(element_size)));
+
+      Matcher<Node*> value_matcher =
+          IsToNumber(value, context, effect, control);
+      Matcher<Node*> effect_matcher = value_matcher;
+      if (AccessBuilder::ForTypedArrayElement(type, true)
+              .type->Is(Type::Signed32())) {
+        value_matcher = IsNumberToInt32(value_matcher);
+      } else if (AccessBuilder::ForTypedArrayElement(type, true)
+                     .type->Is(Type::Unsigned32())) {
+        value_matcher = IsNumberToUint32(value_matcher);
+      }
+
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(
+          r.replacement(),
+          IsStoreBuffer(BufferAccess(type),
+                        IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
+                        offset_matcher,
+                        IsNumberConstant(array->byte_length()->Number()),
+                        value_matcher, effect_matcher, control));
+    }
+  }
+}
+
+
+TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) {
+  const size_t kLength = 17;
+  double backing_store[kLength];
+  Handle<JSArrayBuffer> buffer =
+      NewArrayBuffer(backing_store, sizeof(backing_store));
+  TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
+    TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) {
+      Handle<JSTypedArray> array =
+          factory()->NewJSTypedArray(type, buffer, 0, kLength);
+      ElementAccess access = AccessBuilder::ForTypedArrayElement(type, true);
+
+      int min = random_number_generator()->NextInt(static_cast<int>(kLength));
+      int max = random_number_generator()->NextInt(static_cast<int>(kLength));
+      if (min > max) std::swap(min, max);
+      Node* key = Parameter(Type::Range(factory()->NewNumber(min),
+                                        factory()->NewNumber(max), zone()));
+      Node* base = HeapConstant(array);
+      Node* value = Parameter(access.type);
+      Node* context = UndefinedConstant();
+      Node* effect = graph()->start();
+      Node* control = graph()->start();
+      Node* node = graph()->NewNode(javascript()->StoreProperty(strict_mode),
+                                    base, key, value, context);
+      if (FLAG_turbo_deoptimization) {
+        node->AppendInput(zone(), UndefinedConstant());
+      }
+      node->AppendInput(zone(), effect);
+      node->AppendInput(zone(), control);
+      Reduction r = Reduce(node);
+
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(
+          r.replacement(),
+          IsStoreElement(
+              access, IsIntPtrConstant(bit_cast<intptr_t>(&backing_store[0])),
+              key, value, effect, control));
+    }
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/load-elimination-unittest.cc b/test/unittests/compiler/load-elimination-unittest.cc
new file mode 100644
index 0000000..f0cd60e
--- /dev/null
+++ b/test/unittests/compiler/load-elimination-unittest.cc
@@ -0,0 +1,72 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/access-builder.h"
+#include "src/compiler/load-elimination.h"
+#include "src/compiler/simplified-operator.h"
+#include "test/unittests/compiler/graph-unittest.h"
+#include "test/unittests/compiler/node-test-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class LoadEliminationTest : public GraphTest {
+ public:
+  LoadEliminationTest() : GraphTest(3), simplified_(zone()) {}
+  ~LoadEliminationTest() OVERRIDE {}
+
+ protected:
+  Reduction Reduce(Node* node) {
+    LoadElimination reducer;
+    return reducer.Reduce(node);
+  }
+
+  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
+
+ private:
+  SimplifiedOperatorBuilder simplified_;
+};
+
+
+TEST_F(LoadEliminationTest, LoadFieldWithStoreField) {
+  Node* object1 = Parameter(0);
+  Node* object2 = Parameter(1);
+  Node* value = Parameter(2);
+  Node* effect = graph()->start();
+  Node* control = graph()->start();
+
+  FieldAccess access1 = AccessBuilder::ForContextSlot(42);
+  Node* store1 = graph()->NewNode(simplified()->StoreField(access1), object1,
+                                  value, effect, control);
+  Reduction r1 = Reduce(graph()->NewNode(simplified()->LoadField(access1),
+                                         object1, store1, control));
+  ASSERT_TRUE(r1.Changed());
+  EXPECT_EQ(value, r1.replacement());
+
+  FieldAccess access2 = AccessBuilder::ForMap();
+  Node* store2 = graph()->NewNode(simplified()->StoreField(access2), object1,
+                                  object2, store1, control);
+  Reduction r2 = Reduce(graph()->NewNode(simplified()->LoadField(access2),
+                                         object1, store2, control));
+  ASSERT_TRUE(r2.Changed());
+  EXPECT_EQ(object2, r2.replacement());
+
+  Node* store3 = graph()->NewNode(
+      simplified()->StoreBuffer(BufferAccess(kExternalInt8Array)), object2,
+      value, Int32Constant(10), object1, store2, control);
+
+  Reduction r3 = Reduce(graph()->NewNode(simplified()->LoadField(access1),
+                                         object2, store3, control));
+  ASSERT_FALSE(r3.Changed());
+
+  Reduction r4 = Reduce(graph()->NewNode(simplified()->LoadField(access1),
+                                         object1, store3, control));
+  ASSERT_TRUE(r4.Changed());
+  EXPECT_EQ(value, r4.replacement());
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/machine-operator-reducer-unittest.cc b/test/unittests/compiler/machine-operator-reducer-unittest.cc
new file mode 100644
index 0000000..6fdba35
--- /dev/null
+++ b/test/unittests/compiler/machine-operator-reducer-unittest.cc
@@ -0,0 +1,1383 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/base/bits.h"
+#include "src/base/division-by-constant.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/machine-operator-reducer.h"
+#include "src/compiler/typer.h"
+#include "test/unittests/compiler/graph-unittest.h"
+#include "test/unittests/compiler/node-test-utils.h"
+#include "testing/gmock-support.h"
+
+using testing::AllOf;
+using testing::BitEq;
+using testing::Capture;
+using testing::CaptureEq;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class MachineOperatorReducerTest : public TypedGraphTest {
+ public:
+  explicit MachineOperatorReducerTest(int num_parameters = 2)
+      : TypedGraphTest(num_parameters), machine_(zone()) {}
+
+ protected:
+  Reduction Reduce(Node* node) {
+    JSOperatorBuilder javascript(zone());
+    JSGraph jsgraph(graph(), common(), &javascript, &machine_);
+    MachineOperatorReducer reducer(&jsgraph);
+    return reducer.Reduce(node);
+  }
+
+  Matcher<Node*> IsTruncatingDiv(const Matcher<Node*>& dividend_matcher,
+                                 const int32_t divisor) {
+    base::MagicNumbersForDivision<uint32_t> const mag =
+        base::SignedDivisionByConstant(bit_cast<uint32_t>(divisor));
+    int32_t const multiplier = bit_cast<int32_t>(mag.multiplier);
+    int32_t const shift = bit_cast<int32_t>(mag.shift);
+    Matcher<Node*> quotient_matcher =
+        IsInt32MulHigh(dividend_matcher, IsInt32Constant(multiplier));
+    if (divisor > 0 && multiplier < 0) {
+      quotient_matcher = IsInt32Add(quotient_matcher, dividend_matcher);
+    } else if (divisor < 0 && multiplier > 0) {
+      quotient_matcher = IsInt32Sub(quotient_matcher, dividend_matcher);
+    }
+    if (shift) {
+      quotient_matcher = IsWord32Sar(quotient_matcher, IsInt32Constant(shift));
+    }
+    return IsInt32Add(quotient_matcher,
+                      IsWord32Shr(dividend_matcher, IsInt32Constant(31)));
+  }
+
+  MachineOperatorBuilder* machine() { return &machine_; }
+
+ private:
+  MachineOperatorBuilder machine_;
+};
+
+
+template <typename T>
+class MachineOperatorReducerTestWithParam
+    : public MachineOperatorReducerTest,
+      public ::testing::WithParamInterface<T> {
+ public:
+  explicit MachineOperatorReducerTestWithParam(int num_parameters = 2)
+      : MachineOperatorReducerTest(num_parameters) {}
+  ~MachineOperatorReducerTestWithParam() OVERRIDE {}
+};
+
+
+namespace {
+
+const float kFloat32Values[] = {
+    -std::numeric_limits<float>::infinity(), -2.70497e+38f, -1.4698e+37f,
+    -1.22813e+35f,                           -1.20555e+35f, -1.34584e+34f,
+    -1.0079e+32f,                            -6.49364e+26f, -3.06077e+25f,
+    -1.46821e+25f,                           -1.17658e+23f, -1.9617e+22f,
+    -2.7357e+20f,                            -1.48708e+13f, -1.89633e+12f,
+    -4.66622e+11f,                           -2.22581e+11f, -1.45381e+10f,
+    -1.3956e+09f,                            -1.32951e+09f, -1.30721e+09f,
+    -1.19756e+09f,                           -9.26822e+08f, -6.35647e+08f,
+    -4.00037e+08f,                           -1.81227e+08f, -5.09256e+07f,
+    -964300.0f,                              -192446.0f,    -28455.0f,
+    -27194.0f,                               -26401.0f,     -20575.0f,
+    -17069.0f,                               -9167.0f,      -960.178f,
+    -113.0f,                                 -62.0f,        -15.0f,
+    -7.0f,                                   -0.0256635f,   -4.60374e-07f,
+    -3.63759e-10f,                           -4.30175e-14f, -5.27385e-15f,
+    -1.48084e-15f,                           -1.05755e-19f, -3.2995e-21f,
+    -1.67354e-23f,                           -1.11885e-23f, -1.78506e-30f,
+    -5.07594e-31f,                           -3.65799e-31f, -1.43718e-34f,
+    -1.27126e-38f,                           -0.0f,         0.0f,
+    1.17549e-38f,                            1.56657e-37f,  4.08512e-29f,
+    3.31357e-28f,                            6.25073e-22f,  4.1723e-13f,
+    1.44343e-09f,                            5.27004e-08f,  9.48298e-08f,
+    5.57888e-07f,                            4.89988e-05f,  0.244326f,
+    12.4895f,                                19.0f,         47.0f,
+    106.0f,                                  538.324f,      564.536f,
+    819.124f,                                7048.0f,       12611.0f,
+    19878.0f,                                20309.0f,      797056.0f,
+    1.77219e+09f,                            1.51116e+11f,  4.18193e+13f,
+    3.59167e+16f,                            3.38211e+19f,  2.67488e+20f,
+    1.78831e+21f,                            9.20914e+21f,  8.35654e+23f,
+    1.4495e+24f,                             5.94015e+25f,  4.43608e+30f,
+    2.44502e+33f,                            2.61152e+33f,  1.38178e+37f,
+    1.71306e+37f,                            3.31899e+38f,  3.40282e+38f,
+    std::numeric_limits<float>::infinity()};
+
+
+const double kFloat64Values[] = {
+    -V8_INFINITY,  -4.23878e+275, -5.82632e+265, -6.60355e+220, -6.26172e+212,
+    -2.56222e+211, -4.82408e+201, -1.84106e+157, -1.63662e+127, -1.55772e+100,
+    -1.67813e+72,  -2.3382e+55,   -3.179e+30,    -1.441e+09,    -1.0647e+09,
+    -7.99361e+08,  -5.77375e+08,  -2.20984e+08,  -32757,        -13171,
+    -9970,         -3984,         -107,          -105,          -92,
+    -77,           -61,           -0.000208163,  -1.86685e-06,  -1.17296e-10,
+    -9.26358e-11,  -5.08004e-60,  -1.74753e-65,  -1.06561e-71,  -5.67879e-79,
+    -5.78459e-130, -2.90989e-171, -7.15489e-243, -3.76242e-252, -1.05639e-263,
+    -4.40497e-267, -2.19666e-273, -4.9998e-276,  -5.59821e-278, -2.03855e-282,
+    -5.99335e-283, -7.17554e-284, -3.11744e-309, -0.0,          0.0,
+    2.22507e-308,  1.30127e-270,  7.62898e-260,  4.00313e-249,  3.16829e-233,
+    1.85244e-228,  2.03544e-129,  1.35126e-110,  1.01182e-106,  5.26333e-94,
+    1.35292e-90,   2.85394e-83,   1.78323e-77,   5.4967e-57,    1.03207e-25,
+    4.57401e-25,   1.58738e-05,   2,             125,           2310,
+    9636,          14802,         17168,         28945,         29305,
+    4.81336e+07,   1.41207e+08,   4.65962e+08,   1.40499e+09,   2.12648e+09,
+    8.80006e+30,   1.4446e+45,    1.12164e+54,   2.48188e+89,   6.71121e+102,
+    3.074e+112,    4.9699e+152,   5.58383e+166,  4.30654e+172,  7.08824e+185,
+    9.6586e+214,   2.028e+223,    6.63277e+243,  1.56192e+261,  1.23202e+269,
+    5.72883e+289,  8.5798e+290,   1.40256e+294,  1.79769e+308,  V8_INFINITY};
+
+
+const int32_t kInt32Values[] = {
+    std::numeric_limits<int32_t>::min(), -1914954528, -1698749618,
+    -1578693386,                         -1577976073, -1573998034,
+    -1529085059,                         -1499540537, -1299205097,
+    -1090814845,                         -938186388,  -806828902,
+    -750927650,                          -520676892,  -513661538,
+    -453036354,                          -433622833,  -282638793,
+    -28375,                              -27788,      -22770,
+    -18806,                              -14173,      -11956,
+    -11200,                              -10212,      -8160,
+    -3751,                               -2758,       -1522,
+    -121,                                -120,        -118,
+    -117,                                -106,        -84,
+    -80,                                 -74,         -59,
+    -52,                                 -48,         -39,
+    -35,                                 -17,         -11,
+    -10,                                 -9,          -7,
+    -5,                                  0,           9,
+    12,                                  17,          23,
+    29,                                  31,          33,
+    35,                                  40,          47,
+    55,                                  56,          62,
+    64,                                  67,          68,
+    69,                                  74,          79,
+    84,                                  89,          90,
+    97,                                  104,         118,
+    124,                                 126,         127,
+    7278,                                17787,       24136,
+    24202,                               25570,       26680,
+    30242,                               32399,       420886487,
+    642166225,                           821912648,   822577803,
+    851385718,                           1212241078,  1411419304,
+    1589626102,                          1596437184,  1876245816,
+    1954730266,                          2008792749,  2045320228,
+    std::numeric_limits<int32_t>::max()};
+
+
+const int64_t kInt64Values[] = {
+    std::numeric_limits<int64_t>::min(), V8_INT64_C(-8974392461363618006),
+    V8_INT64_C(-8874367046689588135),    V8_INT64_C(-8269197512118230839),
+    V8_INT64_C(-8146091527100606733),    V8_INT64_C(-7550917981466150848),
+    V8_INT64_C(-7216590251577894337),    V8_INT64_C(-6464086891160048440),
+    V8_INT64_C(-6365616494908257190),    V8_INT64_C(-6305630541365849726),
+    V8_INT64_C(-5982222642272245453),    V8_INT64_C(-5510103099058504169),
+    V8_INT64_C(-5496838675802432701),    V8_INT64_C(-4047626578868642657),
+    V8_INT64_C(-4033755046900164544),    V8_INT64_C(-3554299241457877041),
+    V8_INT64_C(-2482258764588614470),    V8_INT64_C(-1688515425526875335),
+    V8_INT64_C(-924784137176548532),     V8_INT64_C(-725316567157391307),
+    V8_INT64_C(-439022654781092241),     V8_INT64_C(-105545757668917080),
+    V8_INT64_C(-2088319373),             V8_INT64_C(-2073699916),
+    V8_INT64_C(-1844949911),             V8_INT64_C(-1831090548),
+    V8_INT64_C(-1756711933),             V8_INT64_C(-1559409497),
+    V8_INT64_C(-1281179700),             V8_INT64_C(-1211513985),
+    V8_INT64_C(-1182371520),             V8_INT64_C(-785934753),
+    V8_INT64_C(-767480697),              V8_INT64_C(-705745662),
+    V8_INT64_C(-514362436),              V8_INT64_C(-459916580),
+    V8_INT64_C(-312328082),              V8_INT64_C(-302949707),
+    V8_INT64_C(-285499304),              V8_INT64_C(-125701262),
+    V8_INT64_C(-95139843),               V8_INT64_C(-32768),
+    V8_INT64_C(-27542),                  V8_INT64_C(-23600),
+    V8_INT64_C(-18582),                  V8_INT64_C(-17770),
+    V8_INT64_C(-9086),                   V8_INT64_C(-9010),
+    V8_INT64_C(-8244),                   V8_INT64_C(-2890),
+    V8_INT64_C(-103),                    V8_INT64_C(-34),
+    V8_INT64_C(-27),                     V8_INT64_C(-25),
+    V8_INT64_C(-9),                      V8_INT64_C(-7),
+    V8_INT64_C(0),                       V8_INT64_C(2),
+    V8_INT64_C(38),                      V8_INT64_C(58),
+    V8_INT64_C(65),                      V8_INT64_C(93),
+    V8_INT64_C(111),                     V8_INT64_C(1003),
+    V8_INT64_C(1267),                    V8_INT64_C(12797),
+    V8_INT64_C(23122),                   V8_INT64_C(28200),
+    V8_INT64_C(30888),                   V8_INT64_C(42648848),
+    V8_INT64_C(116836693),               V8_INT64_C(263003643),
+    V8_INT64_C(571039860),               V8_INT64_C(1079398689),
+    V8_INT64_C(1145196402),              V8_INT64_C(1184846321),
+    V8_INT64_C(1758281648),              V8_INT64_C(1859991374),
+    V8_INT64_C(1960251588),              V8_INT64_C(2042443199),
+    V8_INT64_C(296220586027987448),      V8_INT64_C(1015494173071134726),
+    V8_INT64_C(1151237951914455318),     V8_INT64_C(1331941174616854174),
+    V8_INT64_C(2022020418667972654),     V8_INT64_C(2450251424374977035),
+    V8_INT64_C(3668393562685561486),     V8_INT64_C(4858229301215502171),
+    V8_INT64_C(4919426235170669383),     V8_INT64_C(5034286595330341762),
+    V8_INT64_C(5055797915536941182),     V8_INT64_C(6072389716149252074),
+    V8_INT64_C(6185309910199801210),     V8_INT64_C(6297328311011094138),
+    V8_INT64_C(6932372858072165827),     V8_INT64_C(8483640924987737210),
+    V8_INT64_C(8663764179455849203),     V8_INT64_C(8877197042645298254),
+    V8_INT64_C(8901543506779157333),     std::numeric_limits<int64_t>::max()};
+
+
+const uint32_t kUint32Values[] = {
+    0x00000000, 0x00000001, 0xffffffff, 0x1b09788b, 0x04c5fce8, 0xcc0de5bf,
+    0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344,
+    0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c,
+    0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00,
+    0x761c4761, 0x80000000, 0x88888888, 0xa0000000, 0xdddddddd, 0xe0000000,
+    0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff,
+    0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, 0x0000ffff, 0x00007fff,
+    0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff};
+
+}  // namespace
+
+
+// -----------------------------------------------------------------------------
+// Unary operators
+
+
+namespace {
+
+struct UnaryOperator {
+  const Operator* (MachineOperatorBuilder::*constructor)();
+  const char* constructor_name;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) {
+  return os << unop.constructor_name;
+}
+
+
+static const UnaryOperator kUnaryOperators[] = {
+    {&MachineOperatorBuilder::ChangeInt32ToFloat64, "ChangeInt32ToFloat64"},
+    {&MachineOperatorBuilder::ChangeUint32ToFloat64, "ChangeUint32ToFloat64"},
+    {&MachineOperatorBuilder::ChangeFloat64ToInt32, "ChangeFloat64ToInt32"},
+    {&MachineOperatorBuilder::ChangeFloat64ToUint32, "ChangeFloat64ToUint32"},
+    {&MachineOperatorBuilder::ChangeInt32ToInt64, "ChangeInt32ToInt64"},
+    {&MachineOperatorBuilder::ChangeUint32ToUint64, "ChangeUint32ToUint64"},
+    {&MachineOperatorBuilder::TruncateFloat64ToInt32, "TruncateFloat64ToInt32"},
+    {&MachineOperatorBuilder::TruncateInt64ToInt32, "TruncateInt64ToInt32"}};
+
+}  // namespace
+
+
+typedef MachineOperatorReducerTestWithParam<UnaryOperator>
+    MachineUnaryOperatorReducerTest;
+
+
+TEST_P(MachineUnaryOperatorReducerTest, Parameter) {
+  const UnaryOperator unop = GetParam();
+  Reduction reduction =
+      Reduce(graph()->NewNode((machine()->*unop.constructor)(), Parameter(0)));
+  EXPECT_FALSE(reduction.Changed());
+}
+
+
+INSTANTIATE_TEST_CASE_P(MachineOperatorReducerTest,
+                        MachineUnaryOperatorReducerTest,
+                        ::testing::ValuesIn(kUnaryOperators));
+
+
+// -----------------------------------------------------------------------------
+// ChangeFloat64ToFloat32
+
+
+TEST_F(MachineOperatorReducerTest, ChangeFloat64ToFloat32WithConstant) {
+  TRACED_FOREACH(float, x, kFloat32Values) {
+    Reduction reduction = Reduce(graph()->NewNode(
+        machine()->ChangeFloat32ToFloat64(), Float32Constant(x)));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq<double>(x)));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeFloat64ToInt32
+
+
+TEST_F(MachineOperatorReducerTest,
+       ChangeFloat64ToInt32WithChangeInt32ToFloat64) {
+  Node* value = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      machine()->ChangeFloat64ToInt32(),
+      graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_EQ(value, reduction.replacement());
+}
+
+
+TEST_F(MachineOperatorReducerTest, ChangeFloat64ToInt32WithConstant) {
+  TRACED_FOREACH(int32_t, x, kInt32Values) {
+    Reduction reduction = Reduce(graph()->NewNode(
+        machine()->ChangeFloat64ToInt32(), Float64Constant(FastI2D(x))));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(), IsInt32Constant(x));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeFloat64ToUint32
+
+
+TEST_F(MachineOperatorReducerTest,
+       ChangeFloat64ToUint32WithChangeUint32ToFloat64) {
+  Node* value = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      machine()->ChangeFloat64ToUint32(),
+      graph()->NewNode(machine()->ChangeUint32ToFloat64(), value)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_EQ(value, reduction.replacement());
+}
+
+
+TEST_F(MachineOperatorReducerTest, ChangeFloat64ToUint32WithConstant) {
+  TRACED_FOREACH(uint32_t, x, kUint32Values) {
+    Reduction reduction = Reduce(graph()->NewNode(
+        machine()->ChangeFloat64ToUint32(), Float64Constant(FastUI2D(x))));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(), IsInt32Constant(bit_cast<int32_t>(x)));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeInt32ToFloat64
+
+
+TEST_F(MachineOperatorReducerTest, ChangeInt32ToFloat64WithConstant) {
+  TRACED_FOREACH(int32_t, x, kInt32Values) {
+    Reduction reduction = Reduce(
+        graph()->NewNode(machine()->ChangeInt32ToFloat64(), Int32Constant(x)));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastI2D(x))));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeInt32ToInt64
+
+
+TEST_F(MachineOperatorReducerTest, ChangeInt32ToInt64WithConstant) {
+  TRACED_FOREACH(int32_t, x, kInt32Values) {
+    Reduction reduction = Reduce(
+        graph()->NewNode(machine()->ChangeInt32ToInt64(), Int32Constant(x)));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(), IsInt64Constant(x));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeUint32ToFloat64
+
+
+TEST_F(MachineOperatorReducerTest, ChangeUint32ToFloat64WithConstant) {
+  TRACED_FOREACH(uint32_t, x, kUint32Values) {
+    Reduction reduction =
+        Reduce(graph()->NewNode(machine()->ChangeUint32ToFloat64(),
+                                Int32Constant(bit_cast<int32_t>(x))));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(FastUI2D(x))));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeUint32ToUint64
+
+
+TEST_F(MachineOperatorReducerTest, ChangeUint32ToUint64WithConstant) {
+  TRACED_FOREACH(uint32_t, x, kUint32Values) {
+    Reduction reduction =
+        Reduce(graph()->NewNode(machine()->ChangeUint32ToUint64(),
+                                Int32Constant(bit_cast<int32_t>(x))));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(),
+                IsInt64Constant(bit_cast<int64_t>(static_cast<uint64_t>(x))));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// TruncateFloat64ToFloat32
+
+
+TEST_F(MachineOperatorReducerTest,
+       TruncateFloat64ToFloat32WithChangeFloat32ToFloat64) {
+  Node* value = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      machine()->TruncateFloat64ToFloat32(),
+      graph()->NewNode(machine()->ChangeFloat32ToFloat64(), value)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_EQ(value, reduction.replacement());
+}
+
+
+TEST_F(MachineOperatorReducerTest, TruncateFloat64ToFloat32WithConstant) {
+  TRACED_FOREACH(double, x, kFloat64Values) {
+    Reduction reduction = Reduce(graph()->NewNode(
+        machine()->TruncateFloat64ToFloat32(), Float64Constant(x)));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(),
+                IsFloat32Constant(BitEq(DoubleToFloat32(x))));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// TruncateFloat64ToInt32
+
+
+TEST_F(MachineOperatorReducerTest,
+       TruncateFloat64ToInt32WithChangeInt32ToFloat64) {
+  Node* value = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      machine()->TruncateFloat64ToInt32(),
+      graph()->NewNode(machine()->ChangeInt32ToFloat64(), value)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_EQ(value, reduction.replacement());
+}
+
+
+TEST_F(MachineOperatorReducerTest, TruncateFloat64ToInt32WithConstant) {
+  TRACED_FOREACH(double, x, kFloat64Values) {
+    Reduction reduction = Reduce(graph()->NewNode(
+        machine()->TruncateFloat64ToInt32(), Float64Constant(x)));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(x)));
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest, TruncateFloat64ToInt32WithPhi) {
+  Node* const p0 = Parameter(0);
+  Node* const p1 = Parameter(1);
+  Node* const merge = graph()->start();
+  Reduction reduction = Reduce(graph()->NewNode(
+      machine()->TruncateFloat64ToInt32(),
+      graph()->NewNode(common()->Phi(kMachFloat64, 2), p0, p1, merge)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(),
+              IsPhi(kMachInt32, IsTruncateFloat64ToInt32(p0),
+                    IsTruncateFloat64ToInt32(p1), merge));
+}
+
+
+// -----------------------------------------------------------------------------
+// TruncateInt64ToInt32
+
+
+TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithChangeInt32ToInt64) {
+  Node* value = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      machine()->TruncateInt64ToInt32(),
+      graph()->NewNode(machine()->ChangeInt32ToInt64(), value)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_EQ(value, reduction.replacement());
+}
+
+
+TEST_F(MachineOperatorReducerTest, TruncateInt64ToInt32WithConstant) {
+  TRACED_FOREACH(int64_t, x, kInt64Values) {
+    Reduction reduction = Reduce(
+        graph()->NewNode(machine()->TruncateInt64ToInt32(), Int64Constant(x)));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(),
+                IsInt32Constant(bit_cast<int32_t>(
+                    static_cast<uint32_t>(bit_cast<uint64_t>(x)))));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Word32And
+
+
+TEST_F(MachineOperatorReducerTest, Word32AndWithWord32AndWithConstant) {
+  Node* const p0 = Parameter(0);
+
+  TRACED_FOREACH(int32_t, k, kInt32Values) {
+    TRACED_FOREACH(int32_t, l, kInt32Values) {
+      if (k == 0 || k == -1 || l == 0 || l == -1) continue;
+
+      // (x & K) & L => x & (K & L)
+      Reduction const r1 = Reduce(graph()->NewNode(
+          machine()->Word32And(),
+          graph()->NewNode(machine()->Word32And(), p0, Int32Constant(k)),
+          Int32Constant(l)));
+      ASSERT_TRUE(r1.Changed());
+      EXPECT_THAT(r1.replacement(),
+                  (k & l) ? IsWord32And(p0, IsInt32Constant(k & l))
+                          : IsInt32Constant(0));
+
+      // (K & x) & L => x & (K & L)
+      Reduction const r2 = Reduce(graph()->NewNode(
+          machine()->Word32And(),
+          graph()->NewNode(machine()->Word32And(), Int32Constant(k), p0),
+          Int32Constant(l)));
+      ASSERT_TRUE(r2.Changed());
+      EXPECT_THAT(r2.replacement(),
+                  (k & l) ? IsWord32And(p0, IsInt32Constant(k & l))
+                          : IsInt32Constant(0));
+    }
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest, Word32AndWithInt32AddAndConstant) {
+  Node* const p0 = Parameter(0);
+  Node* const p1 = Parameter(1);
+
+  TRACED_FORRANGE(int32_t, l, 1, 31) {
+    TRACED_FOREACH(int32_t, k, kInt32Values) {
+      if ((k << l) == 0) continue;
+      // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
+      Reduction const r = Reduce(graph()->NewNode(
+          machine()->Word32And(),
+          graph()->NewNode(machine()->Int32Add(), p0, Int32Constant(k << l)),
+          Int32Constant(-1 << l)));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(r.replacement(),
+                  IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
+                             IsInt32Constant(k << l)));
+    }
+
+    Node* s1 = graph()->NewNode(machine()->Word32Shl(), p1, Int32Constant(l));
+
+    // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
+    Reduction const r1 = Reduce(graph()->NewNode(
+        machine()->Word32And(), graph()->NewNode(machine()->Int32Add(), s1, p0),
+        Int32Constant(-1 << l)));
+    ASSERT_TRUE(r1.Changed());
+    EXPECT_THAT(r1.replacement(),
+                IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)), s1));
+
+    // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
+    Reduction const r2 = Reduce(graph()->NewNode(
+        machine()->Word32And(), graph()->NewNode(machine()->Int32Add(), p0, s1),
+        Int32Constant(-1 << l)));
+    ASSERT_TRUE(r2.Changed());
+    EXPECT_THAT(r2.replacement(),
+                IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)), s1));
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest,
+       Word32AndWithInt32AddAndInt32MulAndConstant) {
+  Node* const p0 = Parameter(0);
+  Node* const p1 = Parameter(1);
+
+  TRACED_FORRANGE(int32_t, l, 1, 31) {
+    TRACED_FOREACH(int32_t, k, kInt32Values) {
+      if ((k << l) == 0) continue;
+      // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
+      Reduction const r1 = Reduce(graph()->NewNode(
+          machine()->Word32And(),
+          graph()->NewNode(machine()->Int32Add(),
+                           graph()->NewNode(machine()->Int32Mul(), p1,
+                                            Int32Constant(k << l)),
+                           p0),
+          Int32Constant(-1 << l)));
+      ASSERT_TRUE(r1.Changed());
+      EXPECT_THAT(r1.replacement(),
+                  IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
+                             IsInt32Mul(p1, IsInt32Constant(k << l))));
+
+      // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
+      Reduction const r2 = Reduce(graph()->NewNode(
+          machine()->Word32And(),
+          graph()->NewNode(machine()->Int32Add(), p0,
+                           graph()->NewNode(machine()->Int32Mul(), p1,
+                                            Int32Constant(k << l))),
+          Int32Constant(-1 << l)));
+      ASSERT_TRUE(r2.Changed());
+      EXPECT_THAT(r2.replacement(),
+                  IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
+                             IsInt32Mul(p1, IsInt32Constant(k << l))));
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Word32Xor
+
+
+TEST_F(MachineOperatorReducerTest, Word32XorWithWord32XorAndMinusOne) {
+  Node* const p0 = Parameter(0);
+
+  // (x ^ -1) ^ -1 => x
+  Reduction r1 = Reduce(graph()->NewNode(
+      machine()->Word32Xor(),
+      graph()->NewNode(machine()->Word32Xor(), p0, Int32Constant(-1)),
+      Int32Constant(-1)));
+  ASSERT_TRUE(r1.Changed());
+  EXPECT_EQ(r1.replacement(), p0);
+
+  // -1 ^ (x ^ -1) => x
+  Reduction r2 = Reduce(graph()->NewNode(
+      machine()->Word32Xor(), Int32Constant(-1),
+      graph()->NewNode(machine()->Word32Xor(), p0, Int32Constant(-1))));
+  ASSERT_TRUE(r2.Changed());
+  EXPECT_EQ(r2.replacement(), p0);
+
+  // (-1 ^ x) ^ -1 => x
+  Reduction r3 = Reduce(graph()->NewNode(
+      machine()->Word32Xor(),
+      graph()->NewNode(machine()->Word32Xor(), Int32Constant(-1), p0),
+      Int32Constant(-1)));
+  ASSERT_TRUE(r3.Changed());
+  EXPECT_EQ(r3.replacement(), p0);
+
+  // -1 ^ (-1 ^ x) => x
+  Reduction r4 = Reduce(graph()->NewNode(
+      machine()->Word32Xor(), Int32Constant(-1),
+      graph()->NewNode(machine()->Word32Xor(), Int32Constant(-1), p0)));
+  ASSERT_TRUE(r4.Changed());
+  EXPECT_EQ(r4.replacement(), p0);
+}
+
+
+// -----------------------------------------------------------------------------
+// Word32Ror
+
+
+TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithParameters) {
+  Node* value = Parameter(0);
+  Node* shift = Parameter(1);
+  Node* sub = graph()->NewNode(machine()->Int32Sub(), Int32Constant(32), shift);
+
+  // Testing rotate left.
+  Node* shl_l = graph()->NewNode(machine()->Word32Shl(), value, shift);
+  Node* shr_l = graph()->NewNode(machine()->Word32Shr(), value, sub);
+
+  // (x << y) | (x >>> (32 - y)) => x ror (32 - y)
+  Node* node1 = graph()->NewNode(machine()->Word32Or(), shl_l, shr_l);
+  Reduction reduction1 = Reduce(node1);
+  EXPECT_TRUE(reduction1.Changed());
+  EXPECT_EQ(reduction1.replacement(), node1);
+  EXPECT_THAT(reduction1.replacement(), IsWord32Ror(value, sub));
+
+  // (x >>> (32 - y)) | (x << y) => x ror (32 - y)
+  Node* node2 = graph()->NewNode(machine()->Word32Or(), shr_l, shl_l);
+  Reduction reduction2 = Reduce(node2);
+  EXPECT_TRUE(reduction2.Changed());
+  EXPECT_EQ(reduction2.replacement(), node2);
+  EXPECT_THAT(reduction2.replacement(), IsWord32Ror(value, sub));
+
+  // Testing rotate right.
+  Node* shl_r = graph()->NewNode(machine()->Word32Shl(), value, sub);
+  Node* shr_r = graph()->NewNode(machine()->Word32Shr(), value, shift);
+
+  // (x << (32 - y)) | (x >>> y) => x ror y
+  Node* node3 = graph()->NewNode(machine()->Word32Or(), shl_r, shr_r);
+  Reduction reduction3 = Reduce(node3);
+  EXPECT_TRUE(reduction3.Changed());
+  EXPECT_EQ(reduction3.replacement(), node3);
+  EXPECT_THAT(reduction3.replacement(), IsWord32Ror(value, shift));
+
+  // (x >>> y) | (x << (32 - y)) => x ror y
+  Node* node4 = graph()->NewNode(machine()->Word32Or(), shr_r, shl_r);
+  Reduction reduction4 = Reduce(node4);
+  EXPECT_TRUE(reduction4.Changed());
+  EXPECT_EQ(reduction4.replacement(), node4);
+  EXPECT_THAT(reduction4.replacement(), IsWord32Ror(value, shift));
+}
+
+
+TEST_F(MachineOperatorReducerTest, ReduceToWord32RorWithConstant) {
+  Node* value = Parameter(0);
+  TRACED_FORRANGE(int32_t, k, 0, 31) {
+    Node* shl =
+        graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(k));
+    Node* shr =
+        graph()->NewNode(machine()->Word32Shr(), value, Int32Constant(32 - k));
+
+    // (x << K) | (x >>> ((32 - K) - y)) => x ror (32 - K)
+    Node* node1 = graph()->NewNode(machine()->Word32Or(), shl, shr);
+    Reduction reduction1 = Reduce(node1);
+    EXPECT_TRUE(reduction1.Changed());
+    EXPECT_EQ(reduction1.replacement(), node1);
+    EXPECT_THAT(reduction1.replacement(),
+                IsWord32Ror(value, IsInt32Constant(32 - k)));
+
+    // (x >>> (32 - K)) | (x << K) => x ror (32 - K)
+    Node* node2 = graph()->NewNode(machine()->Word32Or(), shr, shl);
+    Reduction reduction2 = Reduce(node2);
+    EXPECT_TRUE(reduction2.Changed());
+    EXPECT_EQ(reduction2.replacement(), node2);
+    EXPECT_THAT(reduction2.replacement(),
+                IsWord32Ror(value, IsInt32Constant(32 - k)));
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest, Word32RorWithZeroShift) {
+  Node* value = Parameter(0);
+  Node* node =
+      graph()->NewNode(machine()->Word32Ror(), value, Int32Constant(0));
+  Reduction reduction = Reduce(node);
+  EXPECT_TRUE(reduction.Changed());
+  EXPECT_EQ(reduction.replacement(), value);
+}
+
+
+TEST_F(MachineOperatorReducerTest, Word32RorWithConstants) {
+  TRACED_FOREACH(int32_t, x, kUint32Values) {
+    TRACED_FORRANGE(int32_t, y, 0, 31) {
+      Node* node = graph()->NewNode(machine()->Word32Ror(), Int32Constant(x),
+                                    Int32Constant(y));
+      Reduction reduction = Reduce(node);
+      EXPECT_TRUE(reduction.Changed());
+      EXPECT_THAT(reduction.replacement(),
+                  IsInt32Constant(base::bits::RotateRight32(x, y)));
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Word32Sar
+
+
+TEST_F(MachineOperatorReducerTest, Word32SarWithWord32ShlAndLoad) {
+  Node* const p0 = Parameter(0);
+  Node* const p1 = Parameter(1);
+  {
+    Node* const l = graph()->NewNode(machine()->Load(kMachInt8), p0, p1,
+                                     graph()->start(), graph()->start());
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Word32Sar(),
+        graph()->NewNode(machine()->Word32Shl(), l, Int32Constant(24)),
+        Int32Constant(24)));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_EQ(l, r.replacement());
+  }
+  {
+    Node* const l = graph()->NewNode(machine()->Load(kMachInt16), p0, p1,
+                                     graph()->start(), graph()->start());
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Word32Sar(),
+        graph()->NewNode(machine()->Word32Shl(), l, Int32Constant(16)),
+        Int32Constant(16)));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_EQ(l, r.replacement());
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Word32Shl
+
+
+TEST_F(MachineOperatorReducerTest, Word32ShlWithZeroShift) {
+  Node* p0 = Parameter(0);
+  Node* node = graph()->NewNode(machine()->Word32Shl(), p0, Int32Constant(0));
+  Reduction r = Reduce(node);
+  ASSERT_TRUE(r.Changed());
+  EXPECT_EQ(p0, r.replacement());
+}
+
+
+TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Sar) {
+  Node* p0 = Parameter(0);
+  TRACED_FORRANGE(int32_t, x, 1, 31) {
+    Node* node = graph()->NewNode(
+        machine()->Word32Shl(),
+        graph()->NewNode(machine()->Word32Sar(), p0, Int32Constant(x)),
+        Int32Constant(x));
+    Reduction r = Reduce(node);
+    ASSERT_TRUE(r.Changed());
+    int32_t m = bit_cast<int32_t>(~((1U << x) - 1U));
+    EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest,
+       Word32ShlWithWord32SarAndInt32AddAndConstant) {
+  Node* const p0 = Parameter(0);
+  TRACED_FOREACH(int32_t, k, kInt32Values) {
+    TRACED_FORRANGE(int32_t, l, 1, 31) {
+      if ((k << l) == 0) continue;
+      // (x + (K << L)) >> L << L => (x & (-1 << L)) + (K << L)
+      Reduction const r = Reduce(graph()->NewNode(
+          machine()->Word32Shl(),
+          graph()->NewNode(machine()->Word32Sar(),
+                           graph()->NewNode(machine()->Int32Add(), p0,
+                                            Int32Constant(k << l)),
+                           Int32Constant(l)),
+          Int32Constant(l)));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(r.replacement(),
+                  IsInt32Add(IsWord32And(p0, IsInt32Constant(-1 << l)),
+                             IsInt32Constant(k << l)));
+    }
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest, Word32ShlWithWord32Shr) {
+  Node* p0 = Parameter(0);
+  TRACED_FORRANGE(int32_t, x, 1, 31) {
+    Node* node = graph()->NewNode(
+        machine()->Word32Shl(),
+        graph()->NewNode(machine()->Word32Shr(), p0, Int32Constant(x)),
+        Int32Constant(x));
+    Reduction r = Reduce(node);
+    ASSERT_TRUE(r.Changed());
+    int32_t m = bit_cast<int32_t>(~((1U << x) - 1U));
+    EXPECT_THAT(r.replacement(), IsWord32And(p0, IsInt32Constant(m)));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Int32Div
+
+
+TEST_F(MachineOperatorReducerTest, Int32DivWithConstant) {
+  Node* const p0 = Parameter(0);
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Int32Div(), p0, Int32Constant(0), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+  }
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Int32Div(), p0, Int32Constant(1), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_EQ(r.replacement(), p0);
+  }
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Int32Div(), p0, Int32Constant(-1), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0), p0));
+  }
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Int32Div(), p0, Int32Constant(2), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(
+        r.replacement(),
+        IsWord32Sar(IsInt32Add(IsWord32Shr(p0, IsInt32Constant(31)), p0),
+                    IsInt32Constant(1)));
+  }
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Int32Div(), p0, Int32Constant(-2), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(
+        r.replacement(),
+        IsInt32Sub(
+            IsInt32Constant(0),
+            IsWord32Sar(IsInt32Add(IsWord32Shr(p0, IsInt32Constant(31)), p0),
+                        IsInt32Constant(1))));
+  }
+  TRACED_FORRANGE(int32_t, shift, 2, 30) {
+    Reduction const r =
+        Reduce(graph()->NewNode(machine()->Int32Div(), p0,
+                                Int32Constant(1 << shift), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(
+        r.replacement(),
+        IsWord32Sar(IsInt32Add(IsWord32Shr(IsWord32Sar(p0, IsInt32Constant(31)),
+                                           IsInt32Constant(32 - shift)),
+                               p0),
+                    IsInt32Constant(shift)));
+  }
+  TRACED_FORRANGE(int32_t, shift, 2, 31) {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Int32Div(), p0,
+        Uint32Constant(bit_cast<uint32_t, int32_t>(-1) << shift),
+        graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(
+        r.replacement(),
+        IsInt32Sub(
+            IsInt32Constant(0),
+            IsWord32Sar(
+                IsInt32Add(IsWord32Shr(IsWord32Sar(p0, IsInt32Constant(31)),
+                                       IsInt32Constant(32 - shift)),
+                           p0),
+                IsInt32Constant(shift))));
+  }
+  TRACED_FOREACH(int32_t, divisor, kInt32Values) {
+    if (divisor < 0) {
+      if (base::bits::IsPowerOfTwo32(-divisor)) continue;
+      Reduction const r = Reduce(graph()->NewNode(
+          machine()->Int32Div(), p0, Int32Constant(divisor), graph()->start()));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(r.replacement(), IsInt32Sub(IsInt32Constant(0),
+                                              IsTruncatingDiv(p0, -divisor)));
+    } else if (divisor > 0) {
+      if (base::bits::IsPowerOfTwo32(divisor)) continue;
+      Reduction const r = Reduce(graph()->NewNode(
+          machine()->Int32Div(), p0, Int32Constant(divisor), graph()->start()));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(r.replacement(), IsTruncatingDiv(p0, divisor));
+    }
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest, Int32DivWithParameters) {
+  Node* const p0 = Parameter(0);
+  Reduction const r =
+      Reduce(graph()->NewNode(machine()->Int32Div(), p0, p0, graph()->start()));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(
+      r.replacement(),
+      IsWord32Equal(IsWord32Equal(p0, IsInt32Constant(0)), IsInt32Constant(0)));
+}
+
+
+// -----------------------------------------------------------------------------
+// Uint32Div
+
+
+TEST_F(MachineOperatorReducerTest, Uint32DivWithConstant) {
+  Node* const p0 = Parameter(0);
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Uint32Div(), Int32Constant(0), p0, graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+  }
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Uint32Div(), p0, Int32Constant(0), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+  }
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Uint32Div(), p0, Int32Constant(1), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_EQ(r.replacement(), p0);
+  }
+  TRACED_FOREACH(uint32_t, dividend, kUint32Values) {
+    TRACED_FOREACH(uint32_t, divisor, kUint32Values) {
+      Reduction const r = Reduce(
+          graph()->NewNode(machine()->Uint32Div(), Uint32Constant(dividend),
+                           Uint32Constant(divisor), graph()->start()));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(r.replacement(),
+                  IsInt32Constant(bit_cast<int32_t>(
+                      base::bits::UnsignedDiv32(dividend, divisor))));
+    }
+  }
+  TRACED_FORRANGE(uint32_t, shift, 1, 31) {
+    Reduction const r =
+        Reduce(graph()->NewNode(machine()->Uint32Div(), p0,
+                                Uint32Constant(1u << shift), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsWord32Shr(p0, IsInt32Constant(bit_cast<int32_t>(shift))));
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest, Uint32DivWithParameters) {
+  Node* const p0 = Parameter(0);
+  Reduction const r = Reduce(
+      graph()->NewNode(machine()->Uint32Div(), p0, p0, graph()->start()));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(
+      r.replacement(),
+      IsWord32Equal(IsWord32Equal(p0, IsInt32Constant(0)), IsInt32Constant(0)));
+}
+
+
+// -----------------------------------------------------------------------------
+// Int32Mod
+
+
+TEST_F(MachineOperatorReducerTest, Int32ModWithConstant) {
+  Node* const p0 = Parameter(0);
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Int32Mod(), Int32Constant(0), p0, graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+  }
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Int32Mod(), p0, Int32Constant(0), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+  }
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Int32Mod(), p0, Int32Constant(1), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+  }
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Int32Mod(), p0, Int32Constant(-1), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+  }
+  TRACED_FOREACH(int32_t, dividend, kInt32Values) {
+    TRACED_FOREACH(int32_t, divisor, kInt32Values) {
+      Reduction const r = Reduce(
+          graph()->NewNode(machine()->Int32Mod(), Int32Constant(dividend),
+                           Int32Constant(divisor), graph()->start()));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(r.replacement(),
+                  IsInt32Constant(base::bits::SignedMod32(dividend, divisor)));
+    }
+  }
+  TRACED_FORRANGE(int32_t, shift, 1, 30) {
+    Reduction const r =
+        Reduce(graph()->NewNode(machine()->Int32Mod(), p0,
+                                Int32Constant(1 << shift), graph()->start()));
+    int32_t const mask = (1 << shift) - 1;
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(
+        r.replacement(),
+        IsSelect(kMachInt32, IsInt32LessThan(p0, IsInt32Constant(0)),
+                 IsInt32Sub(IsInt32Constant(0),
+                            IsWord32And(IsInt32Sub(IsInt32Constant(0), p0),
+                                        IsInt32Constant(mask))),
+                 IsWord32And(p0, IsInt32Constant(mask))));
+  }
+  TRACED_FORRANGE(int32_t, shift, 1, 31) {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Int32Mod(), p0,
+        Uint32Constant(bit_cast<uint32_t, int32_t>(-1) << shift),
+        graph()->start()));
+    int32_t const mask = bit_cast<int32_t, uint32_t>((1U << shift) - 1);
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(
+        r.replacement(),
+        IsSelect(kMachInt32, IsInt32LessThan(p0, IsInt32Constant(0)),
+                 IsInt32Sub(IsInt32Constant(0),
+                            IsWord32And(IsInt32Sub(IsInt32Constant(0), p0),
+                                        IsInt32Constant(mask))),
+                 IsWord32And(p0, IsInt32Constant(mask))));
+  }
+  TRACED_FOREACH(int32_t, divisor, kInt32Values) {
+    if (divisor == 0 || base::bits::IsPowerOfTwo32(Abs(divisor))) continue;
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Int32Mod(), p0, Int32Constant(divisor), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsInt32Sub(p0, IsInt32Mul(IsTruncatingDiv(p0, Abs(divisor)),
+                                          IsInt32Constant(Abs(divisor)))));
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest, Int32ModWithParameters) {
+  Node* const p0 = Parameter(0);
+  Reduction const r =
+      Reduce(graph()->NewNode(machine()->Int32Mod(), p0, p0, graph()->start()));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+}
+
+
+// -----------------------------------------------------------------------------
+// Uint32Mod
+
+
+TEST_F(MachineOperatorReducerTest, Uint32ModWithConstant) {
+  Node* const p0 = Parameter(0);
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Uint32Mod(), p0, Int32Constant(0), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+  }
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Uint32Mod(), Int32Constant(0), p0, graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+  }
+  {
+    Reduction const r = Reduce(graph()->NewNode(
+        machine()->Uint32Mod(), p0, Int32Constant(1), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+  }
+  TRACED_FOREACH(uint32_t, dividend, kUint32Values) {
+    TRACED_FOREACH(uint32_t, divisor, kUint32Values) {
+      Reduction const r = Reduce(
+          graph()->NewNode(machine()->Uint32Mod(), Uint32Constant(dividend),
+                           Uint32Constant(divisor), graph()->start()));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(r.replacement(),
+                  IsInt32Constant(bit_cast<int32_t>(
+                      base::bits::UnsignedMod32(dividend, divisor))));
+    }
+  }
+  TRACED_FORRANGE(uint32_t, shift, 1, 31) {
+    Reduction const r =
+        Reduce(graph()->NewNode(machine()->Uint32Mod(), p0,
+                                Uint32Constant(1u << shift), graph()->start()));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsWord32And(p0, IsInt32Constant(
+                                    bit_cast<int32_t>((1u << shift) - 1u))));
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest, Uint32ModWithParameters) {
+  Node* const p0 = Parameter(0);
+  Reduction const r = Reduce(
+      graph()->NewNode(machine()->Uint32Mod(), p0, p0, graph()->start()));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+}
+
+
+// -----------------------------------------------------------------------------
+// Int32AddWithOverflow
+
+
+TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithZero) {
+  Node* p0 = Parameter(0);
+  {
+    Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
+                                 Int32Constant(0), p0);
+
+    Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+
+    r = Reduce(graph()->NewNode(common()->Projection(0), add));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_EQ(p0, r.replacement());
+  }
+  {
+    Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), p0,
+                                 Int32Constant(0));
+
+    Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+
+    r = Reduce(graph()->NewNode(common()->Projection(0), add));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_EQ(p0, r.replacement());
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest, Int32AddWithOverflowWithConstant) {
+  TRACED_FOREACH(int32_t, x, kInt32Values) {
+    TRACED_FOREACH(int32_t, y, kInt32Values) {
+      int32_t z;
+      Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(),
+                                   Int32Constant(x), Int32Constant(y));
+
+      Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(r.replacement(),
+                  IsInt32Constant(base::bits::SignedAddOverflow32(x, y, &z)));
+
+      r = Reduce(graph()->NewNode(common()->Projection(0), add));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(r.replacement(), IsInt32Constant(z));
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Int32SubWithOverflow
+
+
+TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithZero) {
+  Node* p0 = Parameter(0);
+  Node* add =
+      graph()->NewNode(machine()->Int32SubWithOverflow(), p0, Int32Constant(0));
+
+  Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(), IsInt32Constant(0));
+
+  r = Reduce(graph()->NewNode(common()->Projection(0), add));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_EQ(p0, r.replacement());
+}
+
+
+TEST_F(MachineOperatorReducerTest, Int32SubWithOverflowWithConstant) {
+  TRACED_FOREACH(int32_t, x, kInt32Values) {
+    TRACED_FOREACH(int32_t, y, kInt32Values) {
+      int32_t z;
+      Node* add = graph()->NewNode(machine()->Int32SubWithOverflow(),
+                                   Int32Constant(x), Int32Constant(y));
+
+      Reduction r = Reduce(graph()->NewNode(common()->Projection(1), add));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(r.replacement(),
+                  IsInt32Constant(base::bits::SignedSubOverflow32(x, y, &z)));
+
+      r = Reduce(graph()->NewNode(common()->Projection(0), add));
+      ASSERT_TRUE(r.Changed());
+      EXPECT_THAT(r.replacement(), IsInt32Constant(z));
+    }
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Uint32LessThan
+
+
+TEST_F(MachineOperatorReducerTest, Uint32LessThanWithWord32Sar) {
+  Node* const p0 = Parameter(0);
+  TRACED_FORRANGE(uint32_t, shift, 1, 3) {
+    const uint32_t limit = (kMaxInt >> shift) - 1;
+    Node* const node = graph()->NewNode(
+        machine()->Uint32LessThan(),
+        graph()->NewNode(machine()->Word32Sar(), p0, Uint32Constant(shift)),
+        Uint32Constant(limit));
+
+    Reduction r = Reduce(node);
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsUint32LessThan(
+                    p0, IsInt32Constant(bit_cast<int32_t>(limit << shift))));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Float64Mul
+
+
+TEST_F(MachineOperatorReducerTest, Float64MulWithMinusOne) {
+  Node* const p0 = Parameter(0);
+  {
+    Reduction r = Reduce(
+        graph()->NewNode(machine()->Float64Mul(), p0, Float64Constant(-1.0)));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsFloat64Sub(IsFloat64Constant(BitEq(-0.0)), p0));
+  }
+  {
+    Reduction r = Reduce(
+        graph()->NewNode(machine()->Float64Mul(), Float64Constant(-1.0), p0));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsFloat64Sub(IsFloat64Constant(BitEq(-0.0)), p0));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// Store
+
+
+TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32And) {
+  const StoreRepresentation rep(kRepWord8, kNoWriteBarrier);
+  Node* const base = Parameter(0);
+  Node* const index = Parameter(1);
+  Node* const value = Parameter(2);
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  TRACED_FOREACH(uint32_t, x, kUint32Values) {
+    Node* const node =
+        graph()->NewNode(machine()->Store(rep), base, index,
+                         graph()->NewNode(machine()->Word32And(), value,
+                                          Uint32Constant(x | 0xffu)),
+                         effect, control);
+
+    Reduction r = Reduce(node);
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsStore(rep, base, index, value, effect, control));
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest, StoreRepWord8WithWord32SarAndWord32Shl) {
+  const StoreRepresentation rep(kRepWord8, kNoWriteBarrier);
+  Node* const base = Parameter(0);
+  Node* const index = Parameter(1);
+  Node* const value = Parameter(2);
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  TRACED_FORRANGE(int32_t, x, 1, 24) {
+    Node* const node = graph()->NewNode(
+        machine()->Store(rep), base, index,
+        graph()->NewNode(
+            machine()->Word32Sar(),
+            graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(x)),
+            Int32Constant(x)),
+        effect, control);
+
+    Reduction r = Reduce(node);
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsStore(rep, base, index, value, effect, control));
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32And) {
+  const StoreRepresentation rep(kRepWord16, kNoWriteBarrier);
+  Node* const base = Parameter(0);
+  Node* const index = Parameter(1);
+  Node* const value = Parameter(2);
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  TRACED_FOREACH(uint32_t, x, kUint32Values) {
+    Node* const node =
+        graph()->NewNode(machine()->Store(rep), base, index,
+                         graph()->NewNode(machine()->Word32And(), value,
+                                          Uint32Constant(x | 0xffffu)),
+                         effect, control);
+
+    Reduction r = Reduce(node);
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsStore(rep, base, index, value, effect, control));
+  }
+}
+
+
+TEST_F(MachineOperatorReducerTest, StoreRepWord16WithWord32SarAndWord32Shl) {
+  const StoreRepresentation rep(kRepWord16, kNoWriteBarrier);
+  Node* const base = Parameter(0);
+  Node* const index = Parameter(1);
+  Node* const value = Parameter(2);
+  Node* const effect = graph()->start();
+  Node* const control = graph()->start();
+  TRACED_FORRANGE(int32_t, x, 1, 16) {
+    Node* const node = graph()->NewNode(
+        machine()->Store(rep), base, index,
+        graph()->NewNode(
+            machine()->Word32Sar(),
+            graph()->NewNode(machine()->Word32Shl(), value, Int32Constant(x)),
+            Int32Constant(x)),
+        effect, control);
+
+    Reduction r = Reduce(node);
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsStore(rep, base, index, value, effect, control));
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/machine-operator-unittest.cc b/test/unittests/compiler/machine-operator-unittest.cc
new file mode 100644
index 0000000..6e0df2a
--- /dev/null
+++ b/test/unittests/compiler/machine-operator-unittest.cc
@@ -0,0 +1,324 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/opcodes.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/operator-properties.h"
+#include "test/unittests/test-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+#if GTEST_HAS_COMBINE
+
+template <typename T>
+class MachineOperatorTestWithParam
+    : public TestWithZone,
+      public ::testing::WithParamInterface< ::testing::tuple<MachineType, T> > {
+ protected:
+  MachineType type() const { return ::testing::get<0>(B::GetParam()); }
+  const T& GetParam() const { return ::testing::get<1>(B::GetParam()); }
+
+ private:
+  typedef ::testing::WithParamInterface< ::testing::tuple<MachineType, T> > B;
+};
+
+
+namespace {
+
+const MachineType kMachineReps[] = {kRepWord32, kRepWord64};
+
+
+const MachineType kMachineTypes[] = {
+    kMachFloat32, kMachFloat64,   kMachInt8,   kMachUint8,  kMachInt16,
+    kMachUint16,  kMachInt32,     kMachUint32, kMachInt64,  kMachUint64,
+    kMachPtr,     kMachAnyTagged, kRepBit,     kRepWord8,   kRepWord16,
+    kRepWord32,   kRepWord64,     kRepFloat32, kRepFloat64, kRepTagged};
+
+}  // namespace
+
+
+// -----------------------------------------------------------------------------
+// Load operator.
+
+
+typedef MachineOperatorTestWithParam<LoadRepresentation>
+    MachineLoadOperatorTest;
+
+
+TEST_P(MachineLoadOperatorTest, InstancesAreGloballyShared) {
+  MachineOperatorBuilder machine1(zone(), type());
+  MachineOperatorBuilder machine2(zone(), type());
+  EXPECT_EQ(machine1.Load(GetParam()), machine2.Load(GetParam()));
+}
+
+
+TEST_P(MachineLoadOperatorTest, NumberOfInputsAndOutputs) {
+  MachineOperatorBuilder machine(zone(), type());
+  const Operator* op = machine.Load(GetParam());
+
+  EXPECT_EQ(2, op->ValueInputCount());
+  EXPECT_EQ(1, op->EffectInputCount());
+  EXPECT_EQ(1, op->ControlInputCount());
+  EXPECT_EQ(4, OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(1, op->ValueOutputCount());
+  EXPECT_EQ(1, op->EffectOutputCount());
+  EXPECT_EQ(0, op->ControlOutputCount());
+}
+
+
+TEST_P(MachineLoadOperatorTest, OpcodeIsCorrect) {
+  MachineOperatorBuilder machine(zone(), type());
+  EXPECT_EQ(IrOpcode::kLoad, machine.Load(GetParam())->opcode());
+}
+
+
+TEST_P(MachineLoadOperatorTest, ParameterIsCorrect) {
+  MachineOperatorBuilder machine(zone(), type());
+  EXPECT_EQ(GetParam(),
+            OpParameter<LoadRepresentation>(machine.Load(GetParam())));
+}
+
+
+INSTANTIATE_TEST_CASE_P(MachineOperatorTest, MachineLoadOperatorTest,
+                        ::testing::Combine(::testing::ValuesIn(kMachineReps),
+                                           ::testing::ValuesIn(kMachineTypes)));
+
+
+// -----------------------------------------------------------------------------
+// Store operator.
+
+
+class MachineStoreOperatorTest
+    : public MachineOperatorTestWithParam<
+          ::testing::tuple<MachineType, WriteBarrierKind> > {
+ protected:
+  StoreRepresentation GetParam() const {
+    return StoreRepresentation(
+        ::testing::get<0>(MachineOperatorTestWithParam<
+            ::testing::tuple<MachineType, WriteBarrierKind> >::GetParam()),
+        ::testing::get<1>(MachineOperatorTestWithParam<
+            ::testing::tuple<MachineType, WriteBarrierKind> >::GetParam()));
+  }
+};
+
+
+TEST_P(MachineStoreOperatorTest, InstancesAreGloballyShared) {
+  MachineOperatorBuilder machine1(zone(), type());
+  MachineOperatorBuilder machine2(zone(), type());
+  EXPECT_EQ(machine1.Store(GetParam()), machine2.Store(GetParam()));
+}
+
+
+TEST_P(MachineStoreOperatorTest, NumberOfInputsAndOutputs) {
+  MachineOperatorBuilder machine(zone(), type());
+  const Operator* op = machine.Store(GetParam());
+
+  EXPECT_EQ(3, op->ValueInputCount());
+  EXPECT_EQ(1, op->EffectInputCount());
+  EXPECT_EQ(1, op->ControlInputCount());
+  EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(0, op->ValueOutputCount());
+  EXPECT_EQ(1, op->EffectOutputCount());
+  EXPECT_EQ(0, op->ControlOutputCount());
+}
+
+
+TEST_P(MachineStoreOperatorTest, OpcodeIsCorrect) {
+  MachineOperatorBuilder machine(zone(), type());
+  EXPECT_EQ(IrOpcode::kStore, machine.Store(GetParam())->opcode());
+}
+
+
+TEST_P(MachineStoreOperatorTest, ParameterIsCorrect) {
+  MachineOperatorBuilder machine(zone(), type());
+  EXPECT_EQ(GetParam(),
+            OpParameter<StoreRepresentation>(machine.Store(GetParam())));
+}
+
+
+INSTANTIATE_TEST_CASE_P(
+    MachineOperatorTest, MachineStoreOperatorTest,
+    ::testing::Combine(
+        ::testing::ValuesIn(kMachineReps),
+        ::testing::Combine(::testing::ValuesIn(kMachineTypes),
+                           ::testing::Values(kNoWriteBarrier,
+                                             kFullWriteBarrier))));
+
+
+// -----------------------------------------------------------------------------
+// Pure operators.
+
+
+namespace {
+
+struct PureOperator {
+  const Operator* (MachineOperatorBuilder::*constructor)();
+  IrOpcode::Value opcode;
+  int value_input_count;
+  int control_input_count;
+  int value_output_count;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
+  return os << IrOpcode::Mnemonic(pop.opcode);
+}
+
+
+const PureOperator kPureOperators[] = {
+#define PURE(Name, value_input_count, control_input_count, value_output_count) \
+  {                                                                            \
+    &MachineOperatorBuilder::Name, IrOpcode::k##Name, value_input_count,       \
+        control_input_count, value_output_count                                \
+  }
+    PURE(Word32And, 2, 0, 1), PURE(Word32Or, 2, 0, 1), PURE(Word32Xor, 2, 0, 1),
+    PURE(Word32Shl, 2, 0, 1), PURE(Word32Shr, 2, 0, 1),
+    PURE(Word32Sar, 2, 0, 1), PURE(Word32Ror, 2, 0, 1),
+    PURE(Word32Equal, 2, 0, 1), PURE(Word64And, 2, 0, 1),
+    PURE(Word64Or, 2, 0, 1), PURE(Word64Xor, 2, 0, 1), PURE(Word64Shl, 2, 0, 1),
+    PURE(Word64Shr, 2, 0, 1), PURE(Word64Sar, 2, 0, 1),
+    PURE(Word64Ror, 2, 0, 1), PURE(Word64Equal, 2, 0, 1),
+    PURE(Int32Add, 2, 0, 1), PURE(Int32AddWithOverflow, 2, 0, 2),
+    PURE(Int32Sub, 2, 0, 1), PURE(Int32SubWithOverflow, 2, 0, 2),
+    PURE(Int32Mul, 2, 0, 1), PURE(Int32MulHigh, 2, 0, 1),
+    PURE(Int32Div, 2, 1, 1), PURE(Uint32Div, 2, 1, 1), PURE(Int32Mod, 2, 1, 1),
+    PURE(Uint32Mod, 2, 1, 1), PURE(Int32LessThan, 2, 0, 1),
+    PURE(Int32LessThanOrEqual, 2, 0, 1), PURE(Uint32LessThan, 2, 0, 1),
+    PURE(Uint32LessThanOrEqual, 2, 0, 1), PURE(Int64Add, 2, 0, 1),
+    PURE(Int64Sub, 2, 0, 1), PURE(Int64Mul, 2, 0, 1), PURE(Int64Div, 2, 0, 1),
+    PURE(Uint64Div, 2, 0, 1), PURE(Int64Mod, 2, 0, 1), PURE(Uint64Mod, 2, 0, 1),
+    PURE(Int64LessThan, 2, 0, 1), PURE(Int64LessThanOrEqual, 2, 0, 1),
+    PURE(Uint64LessThan, 2, 0, 1), PURE(ChangeFloat32ToFloat64, 1, 0, 1),
+    PURE(ChangeFloat64ToInt32, 1, 0, 1), PURE(ChangeFloat64ToUint32, 1, 0, 1),
+    PURE(ChangeInt32ToInt64, 1, 0, 1), PURE(ChangeUint32ToFloat64, 1, 0, 1),
+    PURE(ChangeUint32ToUint64, 1, 0, 1),
+    PURE(TruncateFloat64ToFloat32, 1, 0, 1),
+    PURE(TruncateFloat64ToInt32, 1, 0, 1), PURE(TruncateInt64ToInt32, 1, 0, 1),
+    PURE(Float64Add, 2, 0, 1), PURE(Float64Sub, 2, 0, 1),
+    PURE(Float64Mul, 2, 0, 1), PURE(Float64Div, 2, 0, 1),
+    PURE(Float64Mod, 2, 0, 1), PURE(Float64Sqrt, 1, 0, 1),
+    PURE(Float64Equal, 2, 0, 1), PURE(Float64LessThan, 2, 0, 1),
+    PURE(Float64LessThanOrEqual, 2, 0, 1), PURE(LoadStackPointer, 0, 0, 1),
+    PURE(Float64Floor, 1, 0, 1), PURE(Float64Ceil, 1, 0, 1),
+    PURE(Float64RoundTruncate, 1, 0, 1), PURE(Float64RoundTiesAway, 1, 0, 1)
+#undef PURE
+};
+
+
+typedef MachineOperatorTestWithParam<PureOperator> MachinePureOperatorTest;
+
+}  // namespace
+
+
+TEST_P(MachinePureOperatorTest, InstancesAreGloballyShared) {
+  const PureOperator& pop = GetParam();
+  MachineOperatorBuilder machine1(zone(), type());
+  MachineOperatorBuilder machine2(zone(), type());
+  EXPECT_EQ((machine1.*pop.constructor)(), (machine2.*pop.constructor)());
+}
+
+
+TEST_P(MachinePureOperatorTest, NumberOfInputsAndOutputs) {
+  MachineOperatorBuilder machine(zone(), type());
+  const PureOperator& pop = GetParam();
+  const Operator* op = (machine.*pop.constructor)();
+
+  EXPECT_EQ(pop.value_input_count, op->ValueInputCount());
+  EXPECT_EQ(0, op->EffectInputCount());
+  EXPECT_EQ(pop.control_input_count, op->ControlInputCount());
+  EXPECT_EQ(pop.value_input_count + pop.control_input_count,
+            OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(pop.value_output_count, op->ValueOutputCount());
+  EXPECT_EQ(0, op->EffectOutputCount());
+  EXPECT_EQ(0, op->ControlOutputCount());
+}
+
+
+TEST_P(MachinePureOperatorTest, MarkedAsPure) {
+  MachineOperatorBuilder machine(zone(), type());
+  const PureOperator& pop = GetParam();
+  const Operator* op = (machine.*pop.constructor)();
+  EXPECT_TRUE(op->HasProperty(Operator::kPure));
+}
+
+
+TEST_P(MachinePureOperatorTest, OpcodeIsCorrect) {
+  MachineOperatorBuilder machine(zone(), type());
+  const PureOperator& pop = GetParam();
+  const Operator* op = (machine.*pop.constructor)();
+  EXPECT_EQ(pop.opcode, op->opcode());
+}
+
+
+INSTANTIATE_TEST_CASE_P(
+    MachineOperatorTest, MachinePureOperatorTest,
+    ::testing::Combine(::testing::ValuesIn(kMachineReps),
+                       ::testing::ValuesIn(kPureOperators)));
+
+#endif  // GTEST_HAS_COMBINE
+
+
+// -----------------------------------------------------------------------------
+// Pseudo operators.
+
+
+namespace {
+
+typedef TestWithZone MachineOperatorTest;
+
+}  // namespace
+
+
+TEST_F(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs32Bit) {
+  MachineOperatorBuilder machine(zone(), kRepWord32);
+  EXPECT_EQ(machine.Word32And(), machine.WordAnd());
+  EXPECT_EQ(machine.Word32Or(), machine.WordOr());
+  EXPECT_EQ(machine.Word32Xor(), machine.WordXor());
+  EXPECT_EQ(machine.Word32Shl(), machine.WordShl());
+  EXPECT_EQ(machine.Word32Shr(), machine.WordShr());
+  EXPECT_EQ(machine.Word32Sar(), machine.WordSar());
+  EXPECT_EQ(machine.Word32Ror(), machine.WordRor());
+  EXPECT_EQ(machine.Word32Equal(), machine.WordEqual());
+  EXPECT_EQ(machine.Int32Add(), machine.IntAdd());
+  EXPECT_EQ(machine.Int32Sub(), machine.IntSub());
+  EXPECT_EQ(machine.Int32Mul(), machine.IntMul());
+  EXPECT_EQ(machine.Int32Div(), machine.IntDiv());
+  EXPECT_EQ(machine.Uint32Div(), machine.UintDiv());
+  EXPECT_EQ(machine.Int32Mod(), machine.IntMod());
+  EXPECT_EQ(machine.Uint32Mod(), machine.UintMod());
+  EXPECT_EQ(machine.Int32LessThan(), machine.IntLessThan());
+  EXPECT_EQ(machine.Int32LessThanOrEqual(), machine.IntLessThanOrEqual());
+}
+
+
+TEST_F(MachineOperatorTest, PseudoOperatorsWhenWordSizeIs64Bit) {
+  MachineOperatorBuilder machine(zone(), kRepWord64);
+  EXPECT_EQ(machine.Word64And(), machine.WordAnd());
+  EXPECT_EQ(machine.Word64Or(), machine.WordOr());
+  EXPECT_EQ(machine.Word64Xor(), machine.WordXor());
+  EXPECT_EQ(machine.Word64Shl(), machine.WordShl());
+  EXPECT_EQ(machine.Word64Shr(), machine.WordShr());
+  EXPECT_EQ(machine.Word64Sar(), machine.WordSar());
+  EXPECT_EQ(machine.Word64Ror(), machine.WordRor());
+  EXPECT_EQ(machine.Word64Equal(), machine.WordEqual());
+  EXPECT_EQ(machine.Int64Add(), machine.IntAdd());
+  EXPECT_EQ(machine.Int64Sub(), machine.IntSub());
+  EXPECT_EQ(machine.Int64Mul(), machine.IntMul());
+  EXPECT_EQ(machine.Int64Div(), machine.IntDiv());
+  EXPECT_EQ(machine.Uint64Div(), machine.UintDiv());
+  EXPECT_EQ(machine.Int64Mod(), machine.IntMod());
+  EXPECT_EQ(machine.Uint64Mod(), machine.UintMod());
+  EXPECT_EQ(machine.Int64LessThan(), machine.IntLessThan());
+  EXPECT_EQ(machine.Int64LessThanOrEqual(), machine.IntLessThanOrEqual());
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/mips/OWNERS b/test/unittests/compiler/mips/OWNERS
new file mode 100644
index 0000000..5508ba6
--- /dev/null
+++ b/test/unittests/compiler/mips/OWNERS
@@ -0,0 +1,5 @@
+paul.lind@imgtec.com
+gergely.kis@imgtec.com
+akos.palfi@imgtec.com
+balazs.kilvady@imgtec.com
+dusan.milosavljevic@imgtec.com
diff --git a/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc b/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc
new file mode 100644
index 0000000..0b3a0f5
--- /dev/null
+++ b/test/unittests/compiler/mips/instruction-selector-mips-unittest.cc
@@ -0,0 +1,805 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file
+
+#include "test/unittests/compiler/instruction-selector-unittest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+template <typename T>
+struct MachInst {
+  T constructor;
+  const char* constructor_name;
+  ArchOpcode arch_opcode;
+  MachineType machine_type;
+};
+
+template <typename T>
+std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) {
+  return os << mi.constructor_name;
+}
+
+typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1;
+typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2;
+
+// To avoid duplicated code IntCmp helper structure
+// is created. It contains MachInst2 with two nodes and expected_size
+// because different cmp instructions have different size.
+struct IntCmp {
+  MachInst2 mi;
+  uint32_t expected_size;
+};
+
+struct FPCmp {
+  MachInst2 mi;
+  FlagsCondition cond;
+};
+
+const FPCmp kFPCmpInstructions[] = {
+    {{&RawMachineAssembler::Float64Equal, "Float64Equal", kMipsCmpD,
+      kMachFloat64},
+     kUnorderedEqual},
+    {{&RawMachineAssembler::Float64LessThan, "Float64LessThan", kMipsCmpD,
+      kMachFloat64},
+     kUnorderedLessThan},
+    {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
+      kMipsCmpD, kMachFloat64},
+     kUnorderedLessThanOrEqual},
+    {{&RawMachineAssembler::Float64GreaterThan, "Float64GreaterThan", kMipsCmpD,
+      kMachFloat64},
+     kUnorderedLessThan},
+    {{&RawMachineAssembler::Float64GreaterThanOrEqual,
+      "Float64GreaterThanOrEqual", kMipsCmpD, kMachFloat64},
+     kUnorderedLessThanOrEqual}};
+
+struct Conversion {
+  // The machine_type field in MachInst1 represents the destination type.
+  MachInst1 mi;
+  MachineType src_machine_type;
+};
+
+
+// ----------------------------------------------------------------------------
+// Logical instructions.
+// ----------------------------------------------------------------------------
+
+
+const MachInst2 kLogicalInstructions[] = {
+    {&RawMachineAssembler::WordAnd, "WordAnd", kMipsAnd, kMachInt16},
+    {&RawMachineAssembler::WordOr, "WordOr", kMipsOr, kMachInt16},
+    {&RawMachineAssembler::WordXor, "WordXor", kMipsXor, kMachInt16},
+    {&RawMachineAssembler::Word32And, "Word32And", kMipsAnd, kMachInt32},
+    {&RawMachineAssembler::Word32Or, "Word32Or", kMipsOr, kMachInt32},
+    {&RawMachineAssembler::Word32Xor, "Word32Xor", kMipsXor, kMachInt32}};
+
+
+// ----------------------------------------------------------------------------
+// Shift instructions.
+// ----------------------------------------------------------------------------
+
+
+const MachInst2 kShiftInstructions[] = {
+    {&RawMachineAssembler::WordShl, "WordShl", kMipsShl, kMachInt16},
+    {&RawMachineAssembler::WordShr, "WordShr", kMipsShr, kMachInt16},
+    {&RawMachineAssembler::WordSar, "WordSar", kMipsSar, kMachInt16},
+    {&RawMachineAssembler::WordRor, "WordRor", kMipsRor, kMachInt16},
+    {&RawMachineAssembler::Word32Shl, "Word32Shl", kMipsShl, kMachInt32},
+    {&RawMachineAssembler::Word32Shr, "Word32Shr", kMipsShr, kMachInt32},
+    {&RawMachineAssembler::Word32Sar, "Word32Sar", kMipsSar, kMachInt32},
+    {&RawMachineAssembler::Word32Ror, "Word32Ror", kMipsRor, kMachInt32}};
+
+
+// ----------------------------------------------------------------------------
+// MUL/DIV instructions.
+// ----------------------------------------------------------------------------
+
+
+const MachInst2 kMulDivInstructions[] = {
+    {&RawMachineAssembler::Int32Mul, "Int32Mul", kMipsMul, kMachInt32},
+    {&RawMachineAssembler::Int32Div, "Int32Div", kMipsDiv, kMachInt32},
+    {&RawMachineAssembler::Uint32Div, "Uint32Div", kMipsDivU, kMachUint32},
+    {&RawMachineAssembler::Float64Mul, "Float64Mul", kMipsMulD, kMachFloat64},
+    {&RawMachineAssembler::Float64Div, "Float64Div", kMipsDivD, kMachFloat64}};
+
+
+// ----------------------------------------------------------------------------
+// MOD instructions.
+// ----------------------------------------------------------------------------
+
+
+const MachInst2 kModInstructions[] = {
+    {&RawMachineAssembler::Int32Mod, "Int32Mod", kMipsMod, kMachInt32},
+    {&RawMachineAssembler::Uint32Mod, "Int32UMod", kMipsModU, kMachInt32},
+    {&RawMachineAssembler::Float64Mod, "Float64Mod", kMipsModD, kMachFloat64}};
+
+
+// ----------------------------------------------------------------------------
+// Arithmetic FPU instructions.
+// ----------------------------------------------------------------------------
+
+
+const MachInst2 kFPArithInstructions[] = {
+    {&RawMachineAssembler::Float64Add, "Float64Add", kMipsAddD, kMachFloat64},
+    {&RawMachineAssembler::Float64Sub, "Float64Sub", kMipsSubD, kMachFloat64}};
+
+
+// ----------------------------------------------------------------------------
+// IntArithTest instructions, two nodes.
+// ----------------------------------------------------------------------------
+
+
+const MachInst2 kAddSubInstructions[] = {
+    {&RawMachineAssembler::Int32Add, "Int32Add", kMipsAdd, kMachInt32},
+    {&RawMachineAssembler::Int32Sub, "Int32Sub", kMipsSub, kMachInt32},
+    {&RawMachineAssembler::Int32AddWithOverflow, "Int32AddWithOverflow",
+     kMipsAddOvf, kMachInt32},
+    {&RawMachineAssembler::Int32SubWithOverflow, "Int32SubWithOverflow",
+     kMipsSubOvf, kMachInt32}};
+
+
+// ----------------------------------------------------------------------------
+// IntArithTest instructions, one node.
+// ----------------------------------------------------------------------------
+
+
+const MachInst1 kAddSubOneInstructions[] = {
+    {&RawMachineAssembler::Int32Neg, "Int32Neg", kMipsSub, kMachInt32},
+    // TODO(dusmil): check this ...
+    // {&RawMachineAssembler::WordEqual  , "WordEqual"  , kMipsTst, kMachInt32}
+};
+
+
+// ----------------------------------------------------------------------------
+// Arithmetic compare instructions.
+// ----------------------------------------------------------------------------
+
+
+const IntCmp kCmpInstructions[] = {
+    {{&RawMachineAssembler::WordEqual, "WordEqual", kMipsCmp, kMachInt16}, 1U},
+    {{&RawMachineAssembler::WordNotEqual, "WordNotEqual", kMipsCmp, kMachInt16},
+     1U},
+    {{&RawMachineAssembler::Word32Equal, "Word32Equal", kMipsCmp, kMachInt32},
+     1U},
+    {{&RawMachineAssembler::Word32NotEqual, "Word32NotEqual", kMipsCmp,
+      kMachInt32},
+     1U},
+    {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kMipsCmp,
+      kMachInt32},
+     1U},
+    {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual",
+      kMipsCmp, kMachInt32},
+     1U},
+    {{&RawMachineAssembler::Int32GreaterThan, "Int32GreaterThan", kMipsCmp,
+      kMachInt32},
+     1U},
+    {{&RawMachineAssembler::Int32GreaterThanOrEqual, "Int32GreaterThanOrEqual",
+      kMipsCmp, kMachInt32},
+     1U},
+    {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kMipsCmp,
+      kMachUint32},
+     1U},
+    {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual",
+      kMipsCmp, kMachUint32},
+     1U}};
+
+
+// ----------------------------------------------------------------------------
+// Conversion instructions.
+// ----------------------------------------------------------------------------
+
+const Conversion kConversionInstructions[] = {
+    // Conversion instructions are related to machine_operator.h:
+    // FPU conversions:
+    // Convert representation of integers between float64 and int32/uint32.
+    // The precise rounding mode and handling of out of range inputs are *not*
+    // defined for these operators, since they are intended only for use with
+    // integers.
+    // mips instruction: cvt_d_w
+    {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64",
+      kMipsCvtDW, kMachFloat64},
+     kMachInt32},
+
+    // mips instruction: cvt_d_uw
+    {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64",
+      kMipsCvtDUw, kMachFloat64},
+     kMachInt32},
+
+    // mips instruction: trunc_w_d
+    {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32",
+      kMipsTruncWD, kMachFloat64},
+     kMachInt32},
+
+    // mips instruction: trunc_uw_d
+    {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32",
+      kMipsTruncUwD, kMachFloat64},
+     kMachInt32}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest;
+
+
+TEST_P(InstructionSelectorFPCmpTest, Parameter) {
+  const FPCmp cmp = GetParam();
+  StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type);
+  m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(cmp.cond, s[0]->flags_condition());
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPCmpTest,
+                        ::testing::ValuesIn(kFPCmpInstructions));
+
+
+// ----------------------------------------------------------------------------
+// Arithmetic compare instructions integers.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<IntCmp> InstructionSelectorCmpTest;
+
+
+TEST_P(InstructionSelectorCmpTest, Parameter) {
+  const IntCmp cmp = GetParam();
+  const MachineType type = cmp.mi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(cmp.expected_size, s.size());
+  EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorCmpTest,
+                        ::testing::ValuesIn(kCmpInstructions));
+
+
+// ----------------------------------------------------------------------------
+// Shift instructions.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorShiftTest;
+
+
+TEST_P(InstructionSelectorShiftTest, Immediate) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) {
+    StreamBuilder m(this, type, type);
+    m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
+                        ::testing::ValuesIn(kShiftInstructions));
+
+
+// ----------------------------------------------------------------------------
+// Logical instructions.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorLogicalTest;
+
+
+TEST_P(InstructionSelectorLogicalTest, Parameter) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest,
+                        ::testing::ValuesIn(kLogicalInstructions));
+
+
+// ----------------------------------------------------------------------------
+// MUL/DIV instructions.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorMulDivTest;
+
+
+TEST_P(InstructionSelectorMulDivTest, Parameter) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMulDivTest,
+                        ::testing::ValuesIn(kMulDivInstructions));
+
+
+// ----------------------------------------------------------------------------
+// MOD instructions.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<MachInst2> InstructionSelectorModTest;
+
+
+TEST_P(InstructionSelectorModTest, Parameter) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorModTest,
+                        ::testing::ValuesIn(kModInstructions));
+
+
+// ----------------------------------------------------------------------------
+// Floating point instructions.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorFPArithTest;
+
+
+TEST_P(InstructionSelectorFPArithTest, Parameter) {
+  const MachInst2 fpa = GetParam();
+  StreamBuilder m(this, fpa.machine_type, fpa.machine_type, fpa.machine_type);
+  m.Return((m.*fpa.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(fpa.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest,
+                        ::testing::ValuesIn(kFPArithInstructions));
+
+
+// ----------------------------------------------------------------------------
+// Integer arithmetic.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorIntArithTwoTest;
+
+
+TEST_P(InstructionSelectorIntArithTwoTest, Parameter) {
+  const MachInst2 intpa = GetParam();
+  StreamBuilder m(this, intpa.machine_type, intpa.machine_type,
+                  intpa.machine_type);
+  m.Return((m.*intpa.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(intpa.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorIntArithTwoTest,
+                        ::testing::ValuesIn(kAddSubInstructions));
+
+
+// ----------------------------------------------------------------------------
+// One node.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<MachInst1>
+    InstructionSelectorIntArithOneTest;
+
+
+TEST_P(InstructionSelectorIntArithOneTest, Parameter) {
+  const MachInst1 intpa = GetParam();
+  StreamBuilder m(this, intpa.machine_type, intpa.machine_type,
+                  intpa.machine_type);
+  m.Return((m.*intpa.constructor)(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(intpa.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorIntArithOneTest,
+                        ::testing::ValuesIn(kAddSubOneInstructions));
+
+
+// ----------------------------------------------------------------------------
+// Conversions.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<Conversion>
+    InstructionSelectorConversionTest;
+
+
+TEST_P(InstructionSelectorConversionTest, Parameter) {
+  const Conversion conv = GetParam();
+  StreamBuilder m(this, conv.mi.machine_type, conv.src_machine_type);
+  m.Return((m.*conv.mi.constructor)(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(conv.mi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorConversionTest,
+                        ::testing::ValuesIn(kConversionInstructions));
+
+
+// ----------------------------------------------------------------------------
+// Loads and stores.
+// ----------------------------------------------------------------------------
+
+namespace {
+
+struct MemoryAccess {
+  MachineType type;
+  ArchOpcode load_opcode;
+  ArchOpcode store_opcode;
+};
+
+
+static const MemoryAccess kMemoryAccesses[] = {
+    {kMachInt8, kMipsLb, kMipsSb},
+    {kMachUint8, kMipsLbu, kMipsSb},
+    {kMachInt16, kMipsLh, kMipsSh},
+    {kMachUint16, kMipsLhu, kMipsSh},
+    {kMachInt32, kMipsLw, kMipsSw},
+    {kRepFloat32, kMipsLwc1, kMipsSwc1},
+    {kRepFloat64, kMipsLdc1, kMipsSdc1}};
+
+
+struct MemoryAccessImm {
+  MachineType type;
+  ArchOpcode load_opcode;
+  ArchOpcode store_opcode;
+  bool (InstructionSelectorTest::Stream::*val_predicate)(
+      const InstructionOperand*) const;
+  const int32_t immediates[40];
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MemoryAccessImm& acc) {
+  return os << acc.type;
+}
+
+
+struct MemoryAccessImm1 {
+  MachineType type;
+  ArchOpcode load_opcode;
+  ArchOpcode store_opcode;
+  bool (InstructionSelectorTest::Stream::*val_predicate)(
+      const InstructionOperand*) const;
+  const int32_t immediates[5];
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MemoryAccessImm1& acc) {
+  return os << acc.type;
+}
+
+
+// ----------------------------------------------------------------------------
+// Loads and stores immediate values.
+// ----------------------------------------------------------------------------
+
+
+const MemoryAccessImm kMemoryAccessesImm[] = {
+    {kMachInt8,
+     kMipsLb,
+     kMipsSb,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachUint8,
+     kMipsLbu,
+     kMipsSb,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachInt16,
+     kMipsLh,
+     kMipsSh,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachUint16,
+     kMipsLhu,
+     kMipsSh,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachInt32,
+     kMipsLw,
+     kMipsSw,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachFloat32,
+     kMipsLwc1,
+     kMipsSwc1,
+     &InstructionSelectorTest::Stream::IsDouble,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachFloat64,
+     kMipsLdc1,
+     kMipsSdc1,
+     &InstructionSelectorTest::Stream::IsDouble,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}};
+
+
+const MemoryAccessImm1 kMemoryAccessImmMoreThan16bit[] = {
+    {kMachInt8,
+     kMipsLb,
+     kMipsSb,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachInt8,
+     kMipsLbu,
+     kMipsSb,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachInt16,
+     kMipsLh,
+     kMipsSh,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachInt16,
+     kMipsLhu,
+     kMipsSh,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachInt32,
+     kMipsLw,
+     kMipsSw,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachFloat32,
+     kMipsLwc1,
+     kMipsSwc1,
+     &InstructionSelectorTest::Stream::IsDouble,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachFloat64,
+     kMipsLdc1,
+     kMipsSdc1,
+     &InstructionSelectorTest::Stream::IsDouble,
+     {-65000, -55000, 32777, 55000, 65000}}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccess>
+    InstructionSelectorMemoryAccessTest;
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
+  m.Return(m.Load(memacc.type, m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
+  m.Store(memacc.type, m.Parameter(0), m.Parameter(1));
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessTest,
+                        ::testing::ValuesIn(kMemoryAccesses));
+
+
+// ----------------------------------------------------------------------------
+// Load immediate.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccessImm>
+    InstructionSelectorMemoryAccessImmTest;
+
+
+TEST_P(InstructionSelectorMemoryAccessImmTest, LoadWithImmediateIndex) {
+  const MemoryAccessImm memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, memacc.type, kMachPtr);
+    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
+  }
+}
+
+
+// ----------------------------------------------------------------------------
+// Store immediate.
+// ----------------------------------------------------------------------------
+
+
+TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) {
+  const MemoryAccessImm memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
+    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
+            m.Parameter(1));
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(0U, s[0]->OutputCount());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessImmTest,
+                        ::testing::ValuesIn(kMemoryAccessesImm));
+
+
+// ----------------------------------------------------------------------------
+// Load/store offsets more than 16 bits.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccessImm1>
+    InstructionSelectorMemoryAccessImmMoreThan16bitTest;
+
+
+TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
+       LoadWithImmediateIndex) {
+  const MemoryAccessImm1 memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, memacc.type, kMachPtr);
+    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
+    Stream s = m.Build();
+    ASSERT_EQ(2U, s.size());
+    // kMipsAdd is expected opcode.
+    // size more than 16 bits wide.
+    EXPECT_EQ(kMipsAdd, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_None, s[0]->addressing_mode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
+       StoreWithImmediateIndex) {
+  const MemoryAccessImm1 memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
+    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
+            m.Parameter(1));
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(2U, s.size());
+    // kMipsAdd is expected opcode
+    // size more than 16 bits wide
+    EXPECT_EQ(kMipsAdd, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_None, s[0]->addressing_mode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessImmMoreThan16bitTest,
+                        ::testing::ValuesIn(kMemoryAccessImmMoreThan16bit));
+
+
+// ----------------------------------------------------------------------------
+// kMipsTst testing.
+// ----------------------------------------------------------------------------
+
+
+TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kMipsCmp, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_None, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kMipsCmp, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_None, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/mips64/OWNERS b/test/unittests/compiler/mips64/OWNERS
new file mode 100644
index 0000000..5508ba6
--- /dev/null
+++ b/test/unittests/compiler/mips64/OWNERS
@@ -0,0 +1,5 @@
+paul.lind@imgtec.com
+gergely.kis@imgtec.com
+akos.palfi@imgtec.com
+balazs.kilvady@imgtec.com
+dusan.milosavljevic@imgtec.com
diff --git a/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc b/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc
new file mode 100644
index 0000000..a39ae75
--- /dev/null
+++ b/test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc
@@ -0,0 +1,807 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file
+
+#include "test/unittests/compiler/instruction-selector-unittest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+template <typename T>
+struct MachInst {
+  T constructor;
+  const char* constructor_name;
+  ArchOpcode arch_opcode;
+  MachineType machine_type;
+};
+
+template <typename T>
+std::ostream& operator<<(std::ostream& os, const MachInst<T>& mi) {
+  return os << mi.constructor_name;
+}
+
+typedef MachInst<Node* (RawMachineAssembler::*)(Node*)> MachInst1;
+typedef MachInst<Node* (RawMachineAssembler::*)(Node*, Node*)> MachInst2;
+
+
+// To avoid duplicated code IntCmp helper structure
+// is created. It contains MachInst2 with two nodes and expected_size
+// because different cmp instructions have different size.
+struct IntCmp {
+  MachInst2 mi;
+  uint32_t expected_size;
+};
+
+struct FPCmp {
+  MachInst2 mi;
+  FlagsCondition cond;
+};
+
+const FPCmp kFPCmpInstructions[] = {
+    {{&RawMachineAssembler::Float64Equal, "Float64Equal", kMips64CmpD,
+      kMachFloat64},
+     kUnorderedEqual},
+    {{&RawMachineAssembler::Float64LessThan, "Float64LessThan", kMips64CmpD,
+      kMachFloat64},
+     kUnorderedLessThan},
+    {{&RawMachineAssembler::Float64LessThanOrEqual, "Float64LessThanOrEqual",
+      kMips64CmpD, kMachFloat64},
+     kUnorderedLessThanOrEqual},
+    {{&RawMachineAssembler::Float64GreaterThan, "Float64GreaterThan",
+      kMips64CmpD, kMachFloat64},
+     kUnorderedLessThan},
+    {{&RawMachineAssembler::Float64GreaterThanOrEqual,
+      "Float64GreaterThanOrEqual", kMips64CmpD, kMachFloat64},
+     kUnorderedLessThanOrEqual}};
+
+struct Conversion {
+  // The machine_type field in MachInst1 represents the destination type.
+  MachInst1 mi;
+  MachineType src_machine_type;
+};
+
+
+// ----------------------------------------------------------------------------
+// Logical instructions.
+// ----------------------------------------------------------------------------
+
+
+const MachInst2 kLogicalInstructions[] = {
+    {&RawMachineAssembler::Word32And, "Word32And", kMips64And, kMachInt32},
+    {&RawMachineAssembler::Word64And, "Word64And", kMips64And, kMachInt64},
+    {&RawMachineAssembler::Word32Or, "Word32Or", kMips64Or, kMachInt32},
+    {&RawMachineAssembler::Word64Or, "Word64Or", kMips64Or, kMachInt64},
+    {&RawMachineAssembler::Word32Xor, "Word32Xor", kMips64Xor, kMachInt32},
+    {&RawMachineAssembler::Word64Xor, "Word64Xor", kMips64Xor, kMachInt64}};
+
+
+// ----------------------------------------------------------------------------
+// Shift instructions.
+// ----------------------------------------------------------------------------
+
+
+const MachInst2 kShiftInstructions[] = {
+    {&RawMachineAssembler::Word32Shl, "Word32Shl", kMips64Shl, kMachInt32},
+    {&RawMachineAssembler::Word64Shl, "Word64Shl", kMips64Dshl, kMachInt64},
+    {&RawMachineAssembler::Word32Shr, "Word32Shr", kMips64Shr, kMachInt32},
+    {&RawMachineAssembler::Word64Shr, "Word64Shr", kMips64Dshr, kMachInt64},
+    {&RawMachineAssembler::Word32Sar, "Word32Sar", kMips64Sar, kMachInt32},
+    {&RawMachineAssembler::Word64Sar, "Word64Sar", kMips64Dsar, kMachInt64},
+    {&RawMachineAssembler::Word32Ror, "Word32Ror", kMips64Ror, kMachInt32},
+    {&RawMachineAssembler::Word64Ror, "Word64Ror", kMips64Dror, kMachInt64}};
+
+
+// ----------------------------------------------------------------------------
+// MUL/DIV instructions.
+// ----------------------------------------------------------------------------
+
+
+const MachInst2 kMulDivInstructions[] = {
+    {&RawMachineAssembler::Int32Mul, "Int32Mul", kMips64Mul, kMachInt32},
+    {&RawMachineAssembler::Int32Div, "Int32Div", kMips64Div, kMachInt32},
+    {&RawMachineAssembler::Uint32Div, "Uint32Div", kMips64DivU, kMachUint32},
+    {&RawMachineAssembler::Int64Mul, "Int64Mul", kMips64Dmul, kMachInt64},
+    {&RawMachineAssembler::Int64Div, "Int64Div", kMips64Ddiv, kMachInt64},
+    {&RawMachineAssembler::Uint64Div, "Uint64Div", kMips64DdivU, kMachUint64},
+    {&RawMachineAssembler::Float64Mul, "Float64Mul", kMips64MulD, kMachFloat64},
+    {&RawMachineAssembler::Float64Div, "Float64Div", kMips64DivD,
+     kMachFloat64}};
+
+
+// ----------------------------------------------------------------------------
+// MOD instructions.
+// ----------------------------------------------------------------------------
+
+
+const MachInst2 kModInstructions[] = {
+    {&RawMachineAssembler::Int32Mod, "Int32Mod", kMips64Mod, kMachInt32},
+    {&RawMachineAssembler::Uint32Mod, "Uint32Mod", kMips64ModU, kMachInt32},
+    {&RawMachineAssembler::Float64Mod, "Float64Mod", kMips64ModD,
+     kMachFloat64}};
+
+
+// ----------------------------------------------------------------------------
+// Arithmetic FPU instructions.
+// ----------------------------------------------------------------------------
+
+
+const MachInst2 kFPArithInstructions[] = {
+    {&RawMachineAssembler::Float64Add, "Float64Add", kMips64AddD, kMachFloat64},
+    {&RawMachineAssembler::Float64Sub, "Float64Sub", kMips64SubD,
+     kMachFloat64}};
+
+
+// ----------------------------------------------------------------------------
+// IntArithTest instructions, two nodes.
+// ----------------------------------------------------------------------------
+
+
+const MachInst2 kAddSubInstructions[] = {
+    {&RawMachineAssembler::Int32Add, "Int32Add", kMips64Add, kMachInt32},
+    {&RawMachineAssembler::Int64Add, "Int64Add", kMips64Dadd, kMachInt64},
+    {&RawMachineAssembler::Int32Sub, "Int32Sub", kMips64Sub, kMachInt32},
+    {&RawMachineAssembler::Int64Sub, "Int64Sub", kMips64Dsub, kMachInt64}};
+
+
+// ----------------------------------------------------------------------------
+// IntArithTest instructions, one node.
+// ----------------------------------------------------------------------------
+
+
+const MachInst1 kAddSubOneInstructions[] = {
+    {&RawMachineAssembler::Int32Neg, "Int32Neg", kMips64Sub, kMachInt32},
+    {&RawMachineAssembler::Int64Neg, "Int64Neg", kMips64Dsub, kMachInt64}};
+
+
+// ----------------------------------------------------------------------------
+// Arithmetic compare instructions.
+// ----------------------------------------------------------------------------
+
+
+const IntCmp kCmpInstructions[] = {
+    {{&RawMachineAssembler::WordEqual, "WordEqual", kMips64Cmp, kMachInt64},
+     1U},
+    {{&RawMachineAssembler::WordNotEqual, "WordNotEqual", kMips64Cmp,
+      kMachInt64},
+     1U},
+    {{&RawMachineAssembler::Word32Equal, "Word32Equal", kMips64Cmp32,
+      kMachInt32},
+     1U},
+    {{&RawMachineAssembler::Word32NotEqual, "Word32NotEqual", kMips64Cmp32,
+      kMachInt32},
+     1U},
+    {{&RawMachineAssembler::Int32LessThan, "Int32LessThan", kMips64Cmp32,
+      kMachInt32},
+     1U},
+    {{&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual",
+      kMips64Cmp32, kMachInt32},
+     1U},
+    {{&RawMachineAssembler::Int32GreaterThan, "Int32GreaterThan", kMips64Cmp32,
+      kMachInt32},
+     1U},
+    {{&RawMachineAssembler::Int32GreaterThanOrEqual, "Int32GreaterThanOrEqual",
+      kMips64Cmp32, kMachInt32},
+     1U},
+    {{&RawMachineAssembler::Uint32LessThan, "Uint32LessThan", kMips64Cmp32,
+      kMachUint32},
+     1U},
+    {{&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual",
+      kMips64Cmp32, kMachUint32},
+     1U}};
+
+
+// ----------------------------------------------------------------------------
+// Conversion instructions.
+// ----------------------------------------------------------------------------
+
+const Conversion kConversionInstructions[] = {
+    // Conversion instructions are related to machine_operator.h:
+    // FPU conversions:
+    // Convert representation of integers between float64 and int32/uint32.
+    // The precise rounding mode and handling of out of range inputs are *not*
+    // defined for these operators, since they are intended only for use with
+    // integers.
+    // mips instructions:
+    // mtc1, cvt.d.w
+    {{&RawMachineAssembler::ChangeInt32ToFloat64, "ChangeInt32ToFloat64",
+      kMips64CvtDW, kMachFloat64},
+     kMachInt32},
+
+    // mips instructions:
+    // cvt.d.uw
+    {{&RawMachineAssembler::ChangeUint32ToFloat64, "ChangeUint32ToFloat64",
+      kMips64CvtDUw, kMachFloat64},
+     kMachInt32},
+
+    // mips instructions:
+    // mfc1, trunc double to word, for more details look at mips macro
+    // asm and mips asm file
+    {{&RawMachineAssembler::ChangeFloat64ToInt32, "ChangeFloat64ToInt32",
+      kMips64TruncWD, kMachFloat64},
+     kMachInt32},
+
+    // mips instructions:
+    // trunc double to unsigned word, for more details look at mips macro
+    // asm and mips asm file
+    {{&RawMachineAssembler::ChangeFloat64ToUint32, "ChangeFloat64ToUint32",
+      kMips64TruncUwD, kMachFloat64},
+     kMachInt32}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<FPCmp> InstructionSelectorFPCmpTest;
+
+TEST_P(InstructionSelectorFPCmpTest, Parameter) {
+  const FPCmp cmp = GetParam();
+  StreamBuilder m(this, kMachInt32, cmp.mi.machine_type, cmp.mi.machine_type);
+  m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+  EXPECT_EQ(cmp.cond, s[0]->flags_condition());
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPCmpTest,
+                        ::testing::ValuesIn(kFPCmpInstructions));
+
+// ----------------------------------------------------------------------------
+// Arithmetic compare instructions integers
+// ----------------------------------------------------------------------------
+typedef InstructionSelectorTestWithParam<IntCmp> InstructionSelectorCmpTest;
+
+
+TEST_P(InstructionSelectorCmpTest, Parameter) {
+  const IntCmp cmp = GetParam();
+  const MachineType type = cmp.mi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*cmp.mi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(cmp.expected_size, s.size());
+  EXPECT_EQ(cmp.mi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorCmpTest,
+                        ::testing::ValuesIn(kCmpInstructions));
+
+// ----------------------------------------------------------------------------
+// Shift instructions.
+// ----------------------------------------------------------------------------
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorShiftTest;
+
+TEST_P(InstructionSelectorShiftTest, Immediate) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  TRACED_FORRANGE(int32_t, imm, 0, (ElementSizeOf(type) * 8) - 1) {
+    StreamBuilder m(this, type, type);
+    m.Return((m.*dpi.constructor)(m.Parameter(0), m.Int32Constant(imm)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+    EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorShiftTest,
+                        ::testing::ValuesIn(kShiftInstructions));
+
+// ----------------------------------------------------------------------------
+// Logical instructions.
+// ----------------------------------------------------------------------------
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorLogicalTest;
+
+
+TEST_P(InstructionSelectorLogicalTest, Parameter) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorLogicalTest,
+                        ::testing::ValuesIn(kLogicalInstructions));
+
+// ----------------------------------------------------------------------------
+// MUL/DIV instructions.
+// ----------------------------------------------------------------------------
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorMulDivTest;
+
+TEST_P(InstructionSelectorMulDivTest, Parameter) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMulDivTest,
+                        ::testing::ValuesIn(kMulDivInstructions));
+
+// ----------------------------------------------------------------------------
+// MOD instructions.
+// ----------------------------------------------------------------------------
+typedef InstructionSelectorTestWithParam<MachInst2> InstructionSelectorModTest;
+
+TEST_P(InstructionSelectorModTest, Parameter) {
+  const MachInst2 dpi = GetParam();
+  const MachineType type = dpi.machine_type;
+  StreamBuilder m(this, type, type, type);
+  m.Return((m.*dpi.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(dpi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorModTest,
+                        ::testing::ValuesIn(kModInstructions));
+
+// ----------------------------------------------------------------------------
+// Floating point instructions.
+// ----------------------------------------------------------------------------
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorFPArithTest;
+
+TEST_P(InstructionSelectorFPArithTest, Parameter) {
+  const MachInst2 fpa = GetParam();
+  StreamBuilder m(this, fpa.machine_type, fpa.machine_type, fpa.machine_type);
+  m.Return((m.*fpa.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(fpa.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorFPArithTest,
+                        ::testing::ValuesIn(kFPArithInstructions));
+// ----------------------------------------------------------------------------
+// Integer arithmetic
+// ----------------------------------------------------------------------------
+typedef InstructionSelectorTestWithParam<MachInst2>
+    InstructionSelectorIntArithTwoTest;
+
+TEST_P(InstructionSelectorIntArithTwoTest, Parameter) {
+  const MachInst2 intpa = GetParam();
+  StreamBuilder m(this, intpa.machine_type, intpa.machine_type,
+                  intpa.machine_type);
+  m.Return((m.*intpa.constructor)(m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(intpa.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorIntArithTwoTest,
+                        ::testing::ValuesIn(kAddSubInstructions));
+
+
+// ----------------------------------------------------------------------------
+// One node.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<MachInst1>
+    InstructionSelectorIntArithOneTest;
+
+TEST_P(InstructionSelectorIntArithOneTest, Parameter) {
+  const MachInst1 intpa = GetParam();
+  StreamBuilder m(this, intpa.machine_type, intpa.machine_type,
+                  intpa.machine_type);
+  m.Return((m.*intpa.constructor)(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(intpa.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorIntArithOneTest,
+                        ::testing::ValuesIn(kAddSubOneInstructions));
+// ----------------------------------------------------------------------------
+// Conversions.
+// ----------------------------------------------------------------------------
+typedef InstructionSelectorTestWithParam<Conversion>
+    InstructionSelectorConversionTest;
+
+TEST_P(InstructionSelectorConversionTest, Parameter) {
+  const Conversion conv = GetParam();
+  StreamBuilder m(this, conv.mi.machine_type, conv.src_machine_type);
+  m.Return((m.*conv.mi.constructor)(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(conv.mi.arch_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorConversionTest,
+                        ::testing::ValuesIn(kConversionInstructions));
+
+
+// ----------------------------------------------------------------------------
+// Loads and stores.
+// ----------------------------------------------------------------------------
+
+
+namespace {
+
+struct MemoryAccess {
+  MachineType type;
+  ArchOpcode load_opcode;
+  ArchOpcode store_opcode;
+};
+
+static const MemoryAccess kMemoryAccesses[] = {
+    {kMachInt8, kMips64Lb, kMips64Sb},
+    {kMachUint8, kMips64Lbu, kMips64Sb},
+    {kMachInt16, kMips64Lh, kMips64Sh},
+    {kMachUint16, kMips64Lhu, kMips64Sh},
+    {kMachInt32, kMips64Lw, kMips64Sw},
+    {kRepFloat32, kMips64Lwc1, kMips64Swc1},
+    {kRepFloat64, kMips64Ldc1, kMips64Sdc1},
+    {kMachInt64, kMips64Ld, kMips64Sd}};
+
+
+struct MemoryAccessImm {
+  MachineType type;
+  ArchOpcode load_opcode;
+  ArchOpcode store_opcode;
+  bool (InstructionSelectorTest::Stream::*val_predicate)(
+      const InstructionOperand*) const;
+  const int32_t immediates[40];
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MemoryAccessImm& acc) {
+  return os << acc.type;
+}
+
+
+struct MemoryAccessImm1 {
+  MachineType type;
+  ArchOpcode load_opcode;
+  ArchOpcode store_opcode;
+  bool (InstructionSelectorTest::Stream::*val_predicate)(
+      const InstructionOperand*) const;
+  const int32_t immediates[5];
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MemoryAccessImm1& acc) {
+  return os << acc.type;
+}
+
+
+// ----------------------------------------------------------------------------
+// Loads and stores immediate values
+// ----------------------------------------------------------------------------
+
+
+const MemoryAccessImm kMemoryAccessesImm[] = {
+    {kMachInt8,
+     kMips64Lb,
+     kMips64Sb,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachUint8,
+     kMips64Lbu,
+     kMips64Sb,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachInt16,
+     kMips64Lh,
+     kMips64Sh,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachUint16,
+     kMips64Lhu,
+     kMips64Sh,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachInt32,
+     kMips64Lw,
+     kMips64Sw,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachFloat32,
+     kMips64Lwc1,
+     kMips64Swc1,
+     &InstructionSelectorTest::Stream::IsDouble,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachFloat64,
+     kMips64Ldc1,
+     kMips64Sdc1,
+     &InstructionSelectorTest::Stream::IsDouble,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}},
+    {kMachInt64,
+     kMips64Ld,
+     kMips64Sd,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-4095, -3340, -3231, -3224, -3088, -1758, -1203, -123, -117, -91, -89,
+      -87, -86, -82, -44, -23, -3, 0, 7, 10, 39, 52, 69, 71, 91, 92, 107, 109,
+      115, 124, 286, 655, 1362, 1569, 2587, 3067, 3096, 3462, 3510, 4095}}};
+
+
+const MemoryAccessImm1 kMemoryAccessImmMoreThan16bit[] = {
+    {kMachInt8,
+     kMips64Lb,
+     kMips64Sb,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachInt8,
+     kMips64Lbu,
+     kMips64Sb,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachInt16,
+     kMips64Lh,
+     kMips64Sh,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachInt16,
+     kMips64Lhu,
+     kMips64Sh,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachInt32,
+     kMips64Lw,
+     kMips64Sw,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachFloat32,
+     kMips64Lwc1,
+     kMips64Swc1,
+     &InstructionSelectorTest::Stream::IsDouble,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachFloat64,
+     kMips64Ldc1,
+     kMips64Sdc1,
+     &InstructionSelectorTest::Stream::IsDouble,
+     {-65000, -55000, 32777, 55000, 65000}},
+    {kMachInt64,
+     kMips64Ld,
+     kMips64Sd,
+     &InstructionSelectorTest::Stream::IsInteger,
+     {-65000, -55000, 32777, 55000, 65000}}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccess>
+    InstructionSelectorMemoryAccessTest;
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
+  m.Return(m.Load(memacc.type, m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
+  m.Store(memacc.type, m.Parameter(0), m.Parameter(1));
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessTest,
+                        ::testing::ValuesIn(kMemoryAccesses));
+
+
+// ----------------------------------------------------------------------------
+// Load immediate.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccessImm>
+    InstructionSelectorMemoryAccessImmTest;
+
+TEST_P(InstructionSelectorMemoryAccessImmTest, LoadWithImmediateIndex) {
+  const MemoryAccessImm memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, memacc.type, kMachPtr);
+    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_TRUE((s.*memacc.val_predicate)(s[0]->Output()));
+  }
+}
+
+
+// ----------------------------------------------------------------------------
+// Store immediate.
+// ----------------------------------------------------------------------------
+
+
+TEST_P(InstructionSelectorMemoryAccessImmTest, StoreWithImmediateIndex) {
+  const MemoryAccessImm memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
+    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
+            m.Parameter(1));
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+    ASSERT_EQ(3U, s[0]->InputCount());
+    ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+    EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1)));
+    EXPECT_EQ(0U, s[0]->OutputCount());
+  }
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessImmTest,
+                        ::testing::ValuesIn(kMemoryAccessesImm));
+
+
+// ----------------------------------------------------------------------------
+// Load/store offsets more than 16 bits.
+// ----------------------------------------------------------------------------
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccessImm1>
+    InstructionSelectorMemoryAccessImmMoreThan16bitTest;
+
+TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
+       LoadWithImmediateIndex) {
+  const MemoryAccessImm1 memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, memacc.type, kMachPtr);
+    m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index)));
+    Stream s = m.Build();
+    ASSERT_EQ(2U, s.size());
+    // kMips64Dadd is expected opcode
+    // size more than 16 bits wide
+    EXPECT_EQ(kMips64Dadd, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_None, s[0]->addressing_mode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+TEST_P(InstructionSelectorMemoryAccessImmMoreThan16bitTest,
+       StoreWithImmediateIndex) {
+  const MemoryAccessImm1 memacc = GetParam();
+  TRACED_FOREACH(int32_t, index, memacc.immediates) {
+    StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type);
+    m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index),
+            m.Parameter(1));
+    m.Return(m.Int32Constant(0));
+    Stream s = m.Build();
+    ASSERT_EQ(2U, s.size());
+    // kMips64Add is expected opcode
+    // size more than 16 bits wide
+    EXPECT_EQ(kMips64Dadd, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_None, s[0]->addressing_mode());
+    EXPECT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+  }
+}
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessImmMoreThan16bitTest,
+                        ::testing::ValuesIn(kMemoryAccessImmMoreThan16bit));
+
+
+// ----------------------------------------------------------------------------
+// kMips64Cmp with zero testing.
+// ----------------------------------------------------------------------------
+
+
+TEST_F(InstructionSelectorTest, Word32EqualWithZero) {
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(m.Parameter(0), m.Int32Constant(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kMips64Cmp32, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_None, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+  {
+    StreamBuilder m(this, kMachInt32, kMachInt32);
+    m.Return(m.Word32Equal(m.Int32Constant(0), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kMips64Cmp32, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_None, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word64EqualWithZero) {
+  {
+    StreamBuilder m(this, kMachInt64, kMachInt64);
+    m.Return(m.Word64Equal(m.Parameter(0), m.Int64Constant(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kMips64Cmp, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_None, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+  {
+    StreamBuilder m(this, kMachInt64, kMachInt64);
+    m.Return(m.Word64Equal(m.Int32Constant(0), m.Parameter(0)));
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kMips64Cmp, s[0]->arch_opcode());
+    EXPECT_EQ(kMode_None, s[0]->addressing_mode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(1U, s[0]->OutputCount());
+    EXPECT_EQ(kFlags_set, s[0]->flags_mode());
+    EXPECT_EQ(kEqual, s[0]->flags_condition());
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/move-optimizer-unittest.cc b/test/unittests/compiler/move-optimizer-unittest.cc
new file mode 100644
index 0000000..5b956f0
--- /dev/null
+++ b/test/unittests/compiler/move-optimizer-unittest.cc
@@ -0,0 +1,133 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/move-optimizer.h"
+#include "test/unittests/compiler/instruction-sequence-unittest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class MoveOptimizerTest : public InstructionSequenceTest {
+ public:
+  GapInstruction* LastGap() {
+    auto instruction = sequence()->instructions().back();
+    if (!instruction->IsGapMoves()) {
+      instruction = *(sequence()->instructions().rbegin() + 1);
+    }
+    return GapInstruction::cast(instruction);
+  }
+
+  void AddMove(GapInstruction* gap, TestOperand from, TestOperand to,
+               GapInstruction::InnerPosition pos = GapInstruction::START) {
+    auto parallel_move = gap->GetOrCreateParallelMove(pos, zone());
+    parallel_move->AddMove(ConvertMoveArg(from), ConvertMoveArg(to), zone());
+  }
+
+  int NonRedundantSize(ParallelMove* move) {
+    int i = 0;
+    auto ops = move->move_operands();
+    for (auto op = ops->begin(); op != ops->end(); ++op) {
+      if (op->IsRedundant()) continue;
+      i++;
+    }
+    return i;
+  }
+
+  bool Contains(ParallelMove* move, TestOperand from_op, TestOperand to_op) {
+    auto from = ConvertMoveArg(from_op);
+    auto to = ConvertMoveArg(to_op);
+    auto ops = move->move_operands();
+    for (auto op = ops->begin(); op != ops->end(); ++op) {
+      if (op->IsRedundant()) continue;
+      if (op->source()->Equals(from) && op->destination()->Equals(to)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  // TODO(dcarney): add a verifier.
+  void Optimize() {
+    WireBlocks();
+    if (FLAG_trace_turbo) {
+      OFStream os(stdout);
+      PrintableInstructionSequence printable = {config(), sequence()};
+      os << "----- Instruction sequence before move optimization -----\n"
+         << printable;
+    }
+    MoveOptimizer move_optimizer(zone(), sequence());
+    move_optimizer.Run();
+    if (FLAG_trace_turbo) {
+      OFStream os(stdout);
+      PrintableInstructionSequence printable = {config(), sequence()};
+      os << "----- Instruction sequence after move optimization -----\n"
+         << printable;
+    }
+  }
+
+ private:
+  InstructionOperand* ConvertMoveArg(TestOperand op) {
+    CHECK_EQ(kNoValue, op.vreg_.value_);
+    CHECK_NE(kNoValue, op.value_);
+    switch (op.type_) {
+      case kConstant:
+        return ConstantOperand::Create(op.value_, zone());
+      case kFixedSlot:
+        return StackSlotOperand::Create(op.value_, zone());
+      case kFixedRegister:
+        CHECK(0 <= op.value_ && op.value_ < num_general_registers());
+        return RegisterOperand::Create(op.value_, zone());
+      default:
+        break;
+    }
+    CHECK(false);
+    return nullptr;
+  }
+};
+
+
+TEST_F(MoveOptimizerTest, RemovesRedundant) {
+  StartBlock();
+  AddMove(LastGap(), Reg(0), Reg(1));
+  EmitNop();
+  AddMove(LastGap(), Reg(1), Reg(0));
+  EmitNop();
+  EndBlock(Last());
+
+  Optimize();
+
+  auto gap = LastGap();
+  auto move = gap->parallel_moves()[0];
+  CHECK_EQ(1, NonRedundantSize(move));
+  CHECK(Contains(move, Reg(0), Reg(1)));
+}
+
+
+TEST_F(MoveOptimizerTest, SplitsConstants) {
+  StartBlock();
+  EndBlock(Last());
+
+  auto gap = LastGap();
+  AddMove(gap, Const(1), Slot(0));
+  AddMove(gap, Const(1), Slot(1));
+  AddMove(gap, Const(1), Reg(0));
+  AddMove(gap, Const(1), Slot(2));
+
+  Optimize();
+
+  auto move = gap->parallel_moves()[0];
+  CHECK_EQ(1, NonRedundantSize(move));
+  CHECK(Contains(move, Const(1), Reg(0)));
+
+  move = gap->parallel_moves()[1];
+  CHECK_EQ(3, NonRedundantSize(move));
+  CHECK(Contains(move, Reg(0), Slot(0)));
+  CHECK(Contains(move, Reg(0), Slot(1)));
+  CHECK(Contains(move, Reg(0), Slot(2)));
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/node-matchers-unittest.cc b/test/unittests/compiler/node-matchers-unittest.cc
new file mode 100644
index 0000000..85db9db
--- /dev/null
+++ b/test/unittests/compiler/node-matchers-unittest.cc
@@ -0,0 +1,733 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/common-operator.h"
+#include "src/compiler/graph.h"
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/node.h"
+#include "src/compiler/node-matchers.h"
+#include "src/compiler/opcodes.h"
+
+#include "test/unittests/compiler/graph-unittest.h"
+#include "test/unittests/test-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class NodeMatcherTest : public GraphTest {
+ public:
+  NodeMatcherTest() : machine_(zone()) {}
+  ~NodeMatcherTest() OVERRIDE {}
+
+  MachineOperatorBuilder* machine() { return &machine_; }
+
+ private:
+  MachineOperatorBuilder machine_;
+};
+
+namespace {
+
+template <class Matcher>
+void CheckBaseWithIndexAndDisplacement(Matcher* matcher, Node* index, int scale,
+                                       Node* base, Node* displacement) {
+  EXPECT_TRUE(matcher->matches());
+  EXPECT_EQ(index, matcher->index());
+  EXPECT_EQ(scale, matcher->scale());
+  EXPECT_EQ(base, matcher->base());
+  EXPECT_EQ(displacement, matcher->displacement());
+}
+};
+
+
+TEST_F(NodeMatcherTest, ScaledWithOffset32Matcher) {
+  graph()->SetStart(graph()->NewNode(common()->Start(0)));
+
+  const Operator* d0_op = common()->Int32Constant(0);
+  Node* d0 = graph()->NewNode(d0_op);
+  USE(d0);
+  const Operator* d1_op = common()->Int32Constant(1);
+  Node* d1 = graph()->NewNode(d1_op);
+  USE(d1);
+  const Operator* d2_op = common()->Int32Constant(2);
+  Node* d2 = graph()->NewNode(d2_op);
+  USE(d2);
+  const Operator* d3_op = common()->Int32Constant(3);
+  Node* d3 = graph()->NewNode(d3_op);
+  USE(d3);
+  const Operator* d4_op = common()->Int32Constant(4);
+  Node* d4 = graph()->NewNode(d4_op);
+  USE(d4);
+  const Operator* d5_op = common()->Int32Constant(5);
+  Node* d5 = graph()->NewNode(d5_op);
+  USE(d5);
+  const Operator* d7_op = common()->Int32Constant(7);
+  Node* d7 = graph()->NewNode(d7_op);
+  USE(d4);
+  const Operator* d8_op = common()->Int32Constant(8);
+  Node* d8 = graph()->NewNode(d8_op);
+  USE(d8);
+  const Operator* d9_op = common()->Int32Constant(9);
+  Node* d9 = graph()->NewNode(d9_op);
+  USE(d9);
+  const Operator* d15_op = common()->Int32Constant(15);
+  Node* d15 = graph()->NewNode(d15_op);
+  USE(d15);
+
+  const Operator* b0_op = common()->Parameter(0);
+  Node* b0 = graph()->NewNode(b0_op, graph()->start());
+  USE(b0);
+  const Operator* b1_op = common()->Parameter(1);
+  Node* b1 = graph()->NewNode(b1_op, graph()->start());
+  USE(b0);
+
+  const Operator* p1_op = common()->Parameter(3);
+  Node* p1 = graph()->NewNode(p1_op, graph()->start());
+  USE(p1);
+
+  const Operator* a_op = machine()->Int32Add();
+  USE(a_op);
+
+  const Operator* m_op = machine()->Int32Mul();
+  Node* m1 = graph()->NewNode(m_op, p1, d1);
+  Node* m2 = graph()->NewNode(m_op, p1, d2);
+  Node* m3 = graph()->NewNode(m_op, p1, d3);
+  Node* m4 = graph()->NewNode(m_op, p1, d4);
+  Node* m5 = graph()->NewNode(m_op, p1, d5);
+  Node* m7 = graph()->NewNode(m_op, p1, d7);
+  Node* m8 = graph()->NewNode(m_op, p1, d8);
+  Node* m9 = graph()->NewNode(m_op, p1, d9);
+  USE(m1);
+  USE(m2);
+  USE(m3);
+  USE(m4);
+  USE(m5);
+  USE(m7);
+  USE(m8);
+  USE(m9);
+
+  const Operator* s_op = machine()->Word32Shl();
+  Node* s0 = graph()->NewNode(s_op, p1, d0);
+  Node* s1 = graph()->NewNode(s_op, p1, d1);
+  Node* s2 = graph()->NewNode(s_op, p1, d2);
+  Node* s3 = graph()->NewNode(s_op, p1, d3);
+  Node* s4 = graph()->NewNode(s_op, p1, d4);
+  USE(s0);
+  USE(s1);
+  USE(s2);
+  USE(s3);
+  USE(s4);
+
+  // 1 INPUT
+
+  // Only relevant test dases is Checking for non-match.
+  BaseWithIndexAndDisplacement32Matcher match0(d15);
+  EXPECT_FALSE(match0.matches());
+
+  // 2 INPUT
+
+  // (B0 + B1) -> [B0, 0, B1, NULL]
+  BaseWithIndexAndDisplacement32Matcher match1(graph()->NewNode(a_op, b0, b1));
+  CheckBaseWithIndexAndDisplacement(&match1, b1, 0, b0, NULL);
+
+  // (B0 + D15) -> [NULL, 0, B0, D15]
+  BaseWithIndexAndDisplacement32Matcher match2(graph()->NewNode(a_op, b0, d15));
+  CheckBaseWithIndexAndDisplacement(&match2, NULL, 0, b0, d15);
+
+  // (D15 + B0) -> [NULL, 0, B0, D15]
+  BaseWithIndexAndDisplacement32Matcher match3(graph()->NewNode(a_op, d15, b0));
+  CheckBaseWithIndexAndDisplacement(&match3, NULL, 0, b0, d15);
+
+  // (B0 + M1) -> [p1, 0, B0, NULL]
+  BaseWithIndexAndDisplacement32Matcher match4(graph()->NewNode(a_op, b0, m1));
+  CheckBaseWithIndexAndDisplacement(&match4, p1, 0, b0, NULL);
+
+  // (M1 + B0) -> [p1, 0, B0, NULL]
+  m1 = graph()->NewNode(m_op, p1, d1);
+  BaseWithIndexAndDisplacement32Matcher match5(graph()->NewNode(a_op, m1, b0));
+  CheckBaseWithIndexAndDisplacement(&match5, p1, 0, b0, NULL);
+
+  // (D15 + M1) -> [P1, 0, NULL, D15]
+  m1 = graph()->NewNode(m_op, p1, d1);
+  BaseWithIndexAndDisplacement32Matcher match6(graph()->NewNode(a_op, d15, m1));
+  CheckBaseWithIndexAndDisplacement(&match6, p1, 0, NULL, d15);
+
+  // (M1 + D15) -> [P1, 0, NULL, D15]
+  m1 = graph()->NewNode(m_op, p1, d1);
+  BaseWithIndexAndDisplacement32Matcher match7(graph()->NewNode(a_op, m1, d15));
+  CheckBaseWithIndexAndDisplacement(&match7, p1, 0, NULL, d15);
+
+  // (B0 + S0) -> [p1, 0, B0, NULL]
+  BaseWithIndexAndDisplacement32Matcher match8(graph()->NewNode(a_op, b0, s0));
+  CheckBaseWithIndexAndDisplacement(&match8, p1, 0, b0, NULL);
+
+  // (S0 + B0) -> [p1, 0, B0, NULL]
+  s0 = graph()->NewNode(s_op, p1, d0);
+  BaseWithIndexAndDisplacement32Matcher match9(graph()->NewNode(a_op, s0, b0));
+  CheckBaseWithIndexAndDisplacement(&match9, p1, 0, b0, NULL);
+
+  // (D15 + S0) -> [P1, 0, NULL, D15]
+  s0 = graph()->NewNode(s_op, p1, d0);
+  BaseWithIndexAndDisplacement32Matcher match10(
+      graph()->NewNode(a_op, d15, s0));
+  CheckBaseWithIndexAndDisplacement(&match10, p1, 0, NULL, d15);
+
+  // (S0 + D15) -> [P1, 0, NULL, D15]
+  s0 = graph()->NewNode(s_op, p1, d0);
+  BaseWithIndexAndDisplacement32Matcher match11(
+      graph()->NewNode(a_op, s0, d15));
+  CheckBaseWithIndexAndDisplacement(&match11, p1, 0, NULL, d15);
+
+  // (B0 + M2) -> [p1, 1, B0, NULL]
+  BaseWithIndexAndDisplacement32Matcher match12(graph()->NewNode(a_op, b0, m2));
+  CheckBaseWithIndexAndDisplacement(&match12, p1, 1, b0, NULL);
+
+  // (M2 + B0) -> [p1, 1, B0, NULL]
+  m2 = graph()->NewNode(m_op, p1, d2);
+  BaseWithIndexAndDisplacement32Matcher match13(graph()->NewNode(a_op, m2, b0));
+  CheckBaseWithIndexAndDisplacement(&match13, p1, 1, b0, NULL);
+
+  // (D15 + M2) -> [P1, 1, NULL, D15]
+  m2 = graph()->NewNode(m_op, p1, d2);
+  BaseWithIndexAndDisplacement32Matcher match14(
+      graph()->NewNode(a_op, d15, m2));
+  CheckBaseWithIndexAndDisplacement(&match14, p1, 1, NULL, d15);
+
+  // (M2 + D15) -> [P1, 1, NULL, D15]
+  m2 = graph()->NewNode(m_op, p1, d2);
+  BaseWithIndexAndDisplacement32Matcher match15(
+      graph()->NewNode(a_op, m2, d15));
+  CheckBaseWithIndexAndDisplacement(&match15, p1, 1, NULL, d15);
+
+  // (B0 + S1) -> [p1, 1, B0, NULL]
+  BaseWithIndexAndDisplacement32Matcher match16(graph()->NewNode(a_op, b0, s1));
+  CheckBaseWithIndexAndDisplacement(&match16, p1, 1, b0, NULL);
+
+  // (S1 + B0) -> [p1, 1, B0, NULL]
+  s1 = graph()->NewNode(s_op, p1, d1);
+  BaseWithIndexAndDisplacement32Matcher match17(graph()->NewNode(a_op, s1, b0));
+  CheckBaseWithIndexAndDisplacement(&match17, p1, 1, b0, NULL);
+
+  // (D15 + S1) -> [P1, 1, NULL, D15]
+  s1 = graph()->NewNode(s_op, p1, d1);
+  BaseWithIndexAndDisplacement32Matcher match18(
+      graph()->NewNode(a_op, d15, s1));
+  CheckBaseWithIndexAndDisplacement(&match18, p1, 1, NULL, d15);
+
+  // (S1 + D15) -> [P1, 1, NULL, D15]
+  s1 = graph()->NewNode(s_op, p1, d1);
+  BaseWithIndexAndDisplacement32Matcher match19(
+      graph()->NewNode(a_op, s1, d15));
+  CheckBaseWithIndexAndDisplacement(&match19, p1, 1, NULL, d15);
+
+  // (B0 + M4) -> [p1, 2, B0, NULL]
+  BaseWithIndexAndDisplacement32Matcher match20(graph()->NewNode(a_op, b0, m4));
+  CheckBaseWithIndexAndDisplacement(&match20, p1, 2, b0, NULL);
+
+  // (M4 + B0) -> [p1, 2, B0, NULL]
+  m4 = graph()->NewNode(m_op, p1, d4);
+  BaseWithIndexAndDisplacement32Matcher match21(graph()->NewNode(a_op, m4, b0));
+  CheckBaseWithIndexAndDisplacement(&match21, p1, 2, b0, NULL);
+
+  // (D15 + M4) -> [p1, 2, NULL, D15]
+  m4 = graph()->NewNode(m_op, p1, d4);
+  BaseWithIndexAndDisplacement32Matcher match22(
+      graph()->NewNode(a_op, d15, m4));
+  CheckBaseWithIndexAndDisplacement(&match22, p1, 2, NULL, d15);
+
+  // (M4 + D15) -> [p1, 2, NULL, D15]
+  m4 = graph()->NewNode(m_op, p1, d4);
+  BaseWithIndexAndDisplacement32Matcher match23(
+      graph()->NewNode(a_op, m4, d15));
+  CheckBaseWithIndexAndDisplacement(&match23, p1, 2, NULL, d15);
+
+  // (B0 + S2) -> [p1, 2, B0, NULL]
+  BaseWithIndexAndDisplacement32Matcher match24(graph()->NewNode(a_op, b0, s2));
+  CheckBaseWithIndexAndDisplacement(&match24, p1, 2, b0, NULL);
+
+  // (S2 + B0) -> [p1, 2, B0, NULL]
+  s2 = graph()->NewNode(s_op, p1, d2);
+  BaseWithIndexAndDisplacement32Matcher match25(graph()->NewNode(a_op, s2, b0));
+  CheckBaseWithIndexAndDisplacement(&match25, p1, 2, b0, NULL);
+
+  // (D15 + S2) -> [p1, 2, NULL, D15]
+  s2 = graph()->NewNode(s_op, p1, d2);
+  BaseWithIndexAndDisplacement32Matcher match26(
+      graph()->NewNode(a_op, d15, s2));
+  CheckBaseWithIndexAndDisplacement(&match26, p1, 2, NULL, d15);
+
+  // (S2 + D15) -> [p1, 2, NULL, D15]
+  s2 = graph()->NewNode(s_op, p1, d2);
+  BaseWithIndexAndDisplacement32Matcher match27(
+      graph()->NewNode(a_op, s2, d15));
+  CheckBaseWithIndexAndDisplacement(&match27, p1, 2, NULL, d15);
+
+  // (B0 + M8) -> [p1, 2, B0, NULL]
+  BaseWithIndexAndDisplacement32Matcher match28(graph()->NewNode(a_op, b0, m8));
+  CheckBaseWithIndexAndDisplacement(&match28, p1, 3, b0, NULL);
+
+  // (M8 + B0) -> [p1, 2, B0, NULL]
+  m8 = graph()->NewNode(m_op, p1, d8);
+  BaseWithIndexAndDisplacement32Matcher match29(graph()->NewNode(a_op, m8, b0));
+  CheckBaseWithIndexAndDisplacement(&match29, p1, 3, b0, NULL);
+
+  // (D15 + M8) -> [p1, 2, NULL, D15]
+  m8 = graph()->NewNode(m_op, p1, d8);
+  BaseWithIndexAndDisplacement32Matcher match30(
+      graph()->NewNode(a_op, d15, m8));
+  CheckBaseWithIndexAndDisplacement(&match30, p1, 3, NULL, d15);
+
+  // (M8 + D15) -> [p1, 2, NULL, D15]
+  m8 = graph()->NewNode(m_op, p1, d8);
+  BaseWithIndexAndDisplacement32Matcher match31(
+      graph()->NewNode(a_op, m8, d15));
+  CheckBaseWithIndexAndDisplacement(&match31, p1, 3, NULL, d15);
+
+  // (B0 + S3) -> [p1, 2, B0, NULL]
+  BaseWithIndexAndDisplacement32Matcher match32(graph()->NewNode(a_op, b0, s3));
+  CheckBaseWithIndexAndDisplacement(&match32, p1, 3, b0, NULL);
+
+  // (S3 + B0) -> [p1, 2, B0, NULL]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement32Matcher match33(graph()->NewNode(a_op, s3, b0));
+  CheckBaseWithIndexAndDisplacement(&match33, p1, 3, b0, NULL);
+
+  // (D15 + S3) -> [p1, 2, NULL, D15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement32Matcher match34(
+      graph()->NewNode(a_op, d15, s3));
+  CheckBaseWithIndexAndDisplacement(&match34, p1, 3, NULL, d15);
+
+  // (S3 + D15) -> [p1, 2, NULL, D15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement32Matcher match35(
+      graph()->NewNode(a_op, s3, d15));
+  CheckBaseWithIndexAndDisplacement(&match35, p1, 3, NULL, d15);
+
+  // 2 INPUT - NEGATIVE CASES
+
+  // (M3 + B1) -> [B0, 0, M3, NULL]
+  BaseWithIndexAndDisplacement32Matcher match36(graph()->NewNode(a_op, b1, m3));
+  CheckBaseWithIndexAndDisplacement(&match36, m3, 0, b1, NULL);
+
+  // (S4 + B1) -> [B0, 0, S4, NULL]
+  BaseWithIndexAndDisplacement32Matcher match37(graph()->NewNode(a_op, b1, s4));
+  CheckBaseWithIndexAndDisplacement(&match37, s4, 0, b1, NULL);
+
+  // 3 INPUT
+
+  // (D15 + S3) + B0 -> [p1, 2, b0, d15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement32Matcher match38(
+      graph()->NewNode(a_op, graph()->NewNode(a_op, d15, s3), b0));
+  CheckBaseWithIndexAndDisplacement(&match38, p1, 3, b0, d15);
+
+  // (B0 + D15) + S3 -> [p1, 2, b0, d15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement32Matcher match39(
+      graph()->NewNode(a_op, graph()->NewNode(a_op, b0, d15), s3));
+  CheckBaseWithIndexAndDisplacement(&match39, p1, 3, b0, d15);
+
+  // (S3 + B0) + D15 -> [p1, 2, b0, d15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement32Matcher match40(
+      graph()->NewNode(a_op, graph()->NewNode(a_op, s3, b0), d15));
+  CheckBaseWithIndexAndDisplacement(&match40, p1, 3, b0, d15);
+
+  // D15 + (S3 + B0) -> [p1, 2, b0, d15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement32Matcher match41(
+      graph()->NewNode(a_op, d15, graph()->NewNode(a_op, s3, b0)));
+  CheckBaseWithIndexAndDisplacement(&match41, p1, 3, b0, d15);
+
+  // B0 + (D15 + S3) -> [p1, 2, b0, d15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement32Matcher match42(
+      graph()->NewNode(a_op, b0, graph()->NewNode(a_op, d15, s3)));
+  CheckBaseWithIndexAndDisplacement(&match42, p1, 3, b0, d15);
+
+  // S3 + (B0 + D15) -> [p1, 2, b0, d15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement32Matcher match43(
+      graph()->NewNode(a_op, s3, graph()->NewNode(a_op, b0, d15)));
+  CheckBaseWithIndexAndDisplacement(&match43, p1, 3, b0, d15);
+
+  // Check that scales that require using the base address work dorrectly.
+}
+
+
+TEST_F(NodeMatcherTest, ScaledWithOffset64Matcher) {
+  graph()->SetStart(graph()->NewNode(common()->Start(0)));
+
+  const Operator* d0_op = common()->Int64Constant(0);
+  Node* d0 = graph()->NewNode(d0_op);
+  USE(d0);
+  const Operator* d1_op = common()->Int64Constant(1);
+  Node* d1 = graph()->NewNode(d1_op);
+  USE(d1);
+  const Operator* d2_op = common()->Int64Constant(2);
+  Node* d2 = graph()->NewNode(d2_op);
+  USE(d2);
+  const Operator* d3_op = common()->Int64Constant(3);
+  Node* d3 = graph()->NewNode(d3_op);
+  USE(d3);
+  const Operator* d4_op = common()->Int64Constant(4);
+  Node* d4 = graph()->NewNode(d4_op);
+  USE(d4);
+  const Operator* d5_op = common()->Int64Constant(5);
+  Node* d5 = graph()->NewNode(d5_op);
+  USE(d5);
+  const Operator* d7_op = common()->Int64Constant(7);
+  Node* d7 = graph()->NewNode(d7_op);
+  USE(d7);
+  const Operator* d8_op = common()->Int64Constant(8);
+  Node* d8 = graph()->NewNode(d8_op);
+  USE(d8);
+  const Operator* d9_op = common()->Int64Constant(9);
+  Node* d9 = graph()->NewNode(d9_op);
+  USE(d8);
+  const Operator* d15_op = common()->Int64Constant(15);
+  Node* d15 = graph()->NewNode(d15_op);
+  USE(d15);
+  const Operator* d15_32_op = common()->Int32Constant(15);
+  Node* d15_32 = graph()->NewNode(d15_32_op);
+  USE(d15_32);
+
+  const Operator* b0_op = common()->Parameter(0);
+  Node* b0 = graph()->NewNode(b0_op, graph()->start());
+  USE(b0);
+  const Operator* b1_op = common()->Parameter(1);
+  Node* b1 = graph()->NewNode(b1_op, graph()->start());
+  USE(b0);
+
+  const Operator* p1_op = common()->Parameter(3);
+  Node* p1 = graph()->NewNode(p1_op, graph()->start());
+  USE(p1);
+
+  const Operator* a_op = machine()->Int64Add();
+  USE(a_op);
+
+  const Operator* m_op = machine()->Int64Mul();
+  Node* m1 = graph()->NewNode(m_op, p1, d1);
+  Node* m2 = graph()->NewNode(m_op, p1, d2);
+  Node* m3 = graph()->NewNode(m_op, p1, d3);
+  Node* m4 = graph()->NewNode(m_op, p1, d4);
+  Node* m5 = graph()->NewNode(m_op, p1, d5);
+  Node* m7 = graph()->NewNode(m_op, p1, d7);
+  Node* m8 = graph()->NewNode(m_op, p1, d8);
+  Node* m9 = graph()->NewNode(m_op, p1, d9);
+  USE(m1);
+  USE(m2);
+  USE(m3);
+  USE(m4);
+  USE(m5);
+  USE(m7);
+  USE(m8);
+  USE(m9);
+
+  const Operator* s_op = machine()->Word64Shl();
+  Node* s0 = graph()->NewNode(s_op, p1, d0);
+  Node* s1 = graph()->NewNode(s_op, p1, d1);
+  Node* s2 = graph()->NewNode(s_op, p1, d2);
+  Node* s3 = graph()->NewNode(s_op, p1, d3);
+  Node* s4 = graph()->NewNode(s_op, p1, d4);
+  USE(s0);
+  USE(s1);
+  USE(s2);
+  USE(s3);
+  USE(s4);
+
+  // 1 INPUT
+
+  // Only relevant test dases is Checking for non-match.
+  BaseWithIndexAndDisplacement64Matcher match0(d15);
+  EXPECT_FALSE(match0.matches());
+
+  // 2 INPUT
+
+  // (B0 + B1) -> [B0, 0, B1, NULL]
+  BaseWithIndexAndDisplacement64Matcher match1(graph()->NewNode(a_op, b0, b1));
+  CheckBaseWithIndexAndDisplacement(&match1, b1, 0, b0, NULL);
+
+  // (B0 + D15) -> [NULL, 0, B0, D15]
+  BaseWithIndexAndDisplacement64Matcher match2(graph()->NewNode(a_op, b0, d15));
+  CheckBaseWithIndexAndDisplacement(&match2, NULL, 0, b0, d15);
+
+  BaseWithIndexAndDisplacement64Matcher match2_32(
+      graph()->NewNode(a_op, b0, d15_32));
+  CheckBaseWithIndexAndDisplacement(&match2_32, NULL, 0, b0, d15_32);
+
+  // (D15 + B0) -> [NULL, 0, B0, D15]
+  BaseWithIndexAndDisplacement64Matcher match3(graph()->NewNode(a_op, d15, b0));
+  CheckBaseWithIndexAndDisplacement(&match3, NULL, 0, b0, d15);
+
+  // (B0 + M1) -> [p1, 0, B0, NULL]
+  BaseWithIndexAndDisplacement64Matcher match4(graph()->NewNode(a_op, b0, m1));
+  CheckBaseWithIndexAndDisplacement(&match4, p1, 0, b0, NULL);
+
+  // (M1 + B0) -> [p1, 0, B0, NULL]
+  m1 = graph()->NewNode(m_op, p1, d1);
+  BaseWithIndexAndDisplacement64Matcher match5(graph()->NewNode(a_op, m1, b0));
+  CheckBaseWithIndexAndDisplacement(&match5, p1, 0, b0, NULL);
+
+  // (D15 + M1) -> [P1, 0, NULL, D15]
+  m1 = graph()->NewNode(m_op, p1, d1);
+  BaseWithIndexAndDisplacement64Matcher match6(graph()->NewNode(a_op, d15, m1));
+  CheckBaseWithIndexAndDisplacement(&match6, p1, 0, NULL, d15);
+
+  // (M1 + D15) -> [P1, 0, NULL, D15]
+  m1 = graph()->NewNode(m_op, p1, d1);
+  BaseWithIndexAndDisplacement64Matcher match7(graph()->NewNode(a_op, m1, d15));
+  CheckBaseWithIndexAndDisplacement(&match7, p1, 0, NULL, d15);
+
+  // (B0 + S0) -> [p1, 0, B0, NULL]
+  BaseWithIndexAndDisplacement64Matcher match8(graph()->NewNode(a_op, b0, s0));
+  CheckBaseWithIndexAndDisplacement(&match8, p1, 0, b0, NULL);
+
+  // (S0 + B0) -> [p1, 0, B0, NULL]
+  s0 = graph()->NewNode(s_op, p1, d0);
+  BaseWithIndexAndDisplacement64Matcher match9(graph()->NewNode(a_op, s0, b0));
+  CheckBaseWithIndexAndDisplacement(&match9, p1, 0, b0, NULL);
+
+  // (D15 + S0) -> [P1, 0, NULL, D15]
+  s0 = graph()->NewNode(s_op, p1, d0);
+  BaseWithIndexAndDisplacement64Matcher match10(
+      graph()->NewNode(a_op, d15, s0));
+  CheckBaseWithIndexAndDisplacement(&match10, p1, 0, NULL, d15);
+
+  // (S0 + D15) -> [P1, 0, NULL, D15]
+  s0 = graph()->NewNode(s_op, p1, d0);
+  BaseWithIndexAndDisplacement64Matcher match11(
+      graph()->NewNode(a_op, s0, d15));
+  CheckBaseWithIndexAndDisplacement(&match11, p1, 0, NULL, d15);
+
+  // (B0 + M2) -> [p1, 1, B0, NULL]
+  BaseWithIndexAndDisplacement64Matcher match12(graph()->NewNode(a_op, b0, m2));
+  CheckBaseWithIndexAndDisplacement(&match12, p1, 1, b0, NULL);
+
+  // (M2 + B0) -> [p1, 1, B0, NULL]
+  m2 = graph()->NewNode(m_op, p1, d2);
+  BaseWithIndexAndDisplacement64Matcher match13(graph()->NewNode(a_op, m2, b0));
+  CheckBaseWithIndexAndDisplacement(&match13, p1, 1, b0, NULL);
+
+  // (D15 + M2) -> [P1, 1, NULL, D15]
+  m2 = graph()->NewNode(m_op, p1, d2);
+  BaseWithIndexAndDisplacement64Matcher match14(
+      graph()->NewNode(a_op, d15, m2));
+  CheckBaseWithIndexAndDisplacement(&match14, p1, 1, NULL, d15);
+
+  // (M2 + D15) -> [P1, 1, NULL, D15]
+  m2 = graph()->NewNode(m_op, p1, d2);
+  BaseWithIndexAndDisplacement64Matcher match15(
+      graph()->NewNode(a_op, m2, d15));
+  CheckBaseWithIndexAndDisplacement(&match15, p1, 1, NULL, d15);
+
+  // (B0 + S1) -> [p1, 1, B0, NULL]
+  BaseWithIndexAndDisplacement64Matcher match16(graph()->NewNode(a_op, b0, s1));
+  CheckBaseWithIndexAndDisplacement(&match16, p1, 1, b0, NULL);
+
+  // (S1 + B0) -> [p1, 1, B0, NULL]
+  s1 = graph()->NewNode(s_op, p1, d1);
+  BaseWithIndexAndDisplacement64Matcher match17(graph()->NewNode(a_op, s1, b0));
+  CheckBaseWithIndexAndDisplacement(&match17, p1, 1, b0, NULL);
+
+  // (D15 + S1) -> [P1, 1, NULL, D15]
+  s1 = graph()->NewNode(s_op, p1, d1);
+  BaseWithIndexAndDisplacement64Matcher match18(
+      graph()->NewNode(a_op, d15, s1));
+  CheckBaseWithIndexAndDisplacement(&match18, p1, 1, NULL, d15);
+
+  // (S1 + D15) -> [P1, 1, NULL, D15]
+  s1 = graph()->NewNode(s_op, p1, d1);
+  BaseWithIndexAndDisplacement64Matcher match19(
+      graph()->NewNode(a_op, s1, d15));
+  CheckBaseWithIndexAndDisplacement(&match19, p1, 1, NULL, d15);
+
+  // (B0 + M4) -> [p1, 2, B0, NULL]
+  BaseWithIndexAndDisplacement64Matcher match20(graph()->NewNode(a_op, b0, m4));
+  CheckBaseWithIndexAndDisplacement(&match20, p1, 2, b0, NULL);
+
+  // (M4 + B0) -> [p1, 2, B0, NULL]
+  m4 = graph()->NewNode(m_op, p1, d4);
+  BaseWithIndexAndDisplacement64Matcher match21(graph()->NewNode(a_op, m4, b0));
+  CheckBaseWithIndexAndDisplacement(&match21, p1, 2, b0, NULL);
+
+  // (D15 + M4) -> [p1, 2, NULL, D15]
+  m4 = graph()->NewNode(m_op, p1, d4);
+  BaseWithIndexAndDisplacement64Matcher match22(
+      graph()->NewNode(a_op, d15, m4));
+  CheckBaseWithIndexAndDisplacement(&match22, p1, 2, NULL, d15);
+
+  // (M4 + D15) -> [p1, 2, NULL, D15]
+  m4 = graph()->NewNode(m_op, p1, d4);
+  BaseWithIndexAndDisplacement64Matcher match23(
+      graph()->NewNode(a_op, m4, d15));
+  CheckBaseWithIndexAndDisplacement(&match23, p1, 2, NULL, d15);
+
+  // (B0 + S2) -> [p1, 2, B0, NULL]
+  BaseWithIndexAndDisplacement64Matcher match24(graph()->NewNode(a_op, b0, s2));
+  CheckBaseWithIndexAndDisplacement(&match24, p1, 2, b0, NULL);
+
+  // (S2 + B0) -> [p1, 2, B0, NULL]
+  s2 = graph()->NewNode(s_op, p1, d2);
+  BaseWithIndexAndDisplacement64Matcher match25(graph()->NewNode(a_op, s2, b0));
+  CheckBaseWithIndexAndDisplacement(&match25, p1, 2, b0, NULL);
+
+  // (D15 + S2) -> [p1, 2, NULL, D15]
+  s2 = graph()->NewNode(s_op, p1, d2);
+  BaseWithIndexAndDisplacement64Matcher match26(
+      graph()->NewNode(a_op, d15, s2));
+  CheckBaseWithIndexAndDisplacement(&match26, p1, 2, NULL, d15);
+
+  // (S2 + D15) -> [p1, 2, NULL, D15]
+  s2 = graph()->NewNode(s_op, p1, d2);
+  BaseWithIndexAndDisplacement64Matcher match27(
+      graph()->NewNode(a_op, s2, d15));
+  CheckBaseWithIndexAndDisplacement(&match27, p1, 2, NULL, d15);
+
+  // (B0 + M8) -> [p1, 2, B0, NULL]
+  BaseWithIndexAndDisplacement64Matcher match28(graph()->NewNode(a_op, b0, m8));
+  CheckBaseWithIndexAndDisplacement(&match28, p1, 3, b0, NULL);
+
+  // (M8 + B0) -> [p1, 2, B0, NULL]
+  m8 = graph()->NewNode(m_op, p1, d8);
+  BaseWithIndexAndDisplacement64Matcher match29(graph()->NewNode(a_op, m8, b0));
+  CheckBaseWithIndexAndDisplacement(&match29, p1, 3, b0, NULL);
+
+  // (D15 + M8) -> [p1, 2, NULL, D15]
+  m8 = graph()->NewNode(m_op, p1, d8);
+  BaseWithIndexAndDisplacement64Matcher match30(
+      graph()->NewNode(a_op, d15, m8));
+  CheckBaseWithIndexAndDisplacement(&match30, p1, 3, NULL, d15);
+
+  // (M8 + D15) -> [p1, 2, NULL, D15]
+  m8 = graph()->NewNode(m_op, p1, d8);
+  BaseWithIndexAndDisplacement64Matcher match31(
+      graph()->NewNode(a_op, m8, d15));
+  CheckBaseWithIndexAndDisplacement(&match31, p1, 3, NULL, d15);
+
+  // (B0 + S3) -> [p1, 2, B0, NULL]
+  BaseWithIndexAndDisplacement64Matcher match64(graph()->NewNode(a_op, b0, s3));
+  CheckBaseWithIndexAndDisplacement(&match64, p1, 3, b0, NULL);
+
+  // (S3 + B0) -> [p1, 2, B0, NULL]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement64Matcher match33(graph()->NewNode(a_op, s3, b0));
+  CheckBaseWithIndexAndDisplacement(&match33, p1, 3, b0, NULL);
+
+  // (D15 + S3) -> [p1, 2, NULL, D15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement64Matcher match34(
+      graph()->NewNode(a_op, d15, s3));
+  CheckBaseWithIndexAndDisplacement(&match34, p1, 3, NULL, d15);
+
+  // (S3 + D15) -> [p1, 2, NULL, D15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement64Matcher match35(
+      graph()->NewNode(a_op, s3, d15));
+  CheckBaseWithIndexAndDisplacement(&match35, p1, 3, NULL, d15);
+
+  // 2 INPUT - NEGATIVE CASES
+
+  // (M3 + B1) -> [B0, 0, M3, NULL]
+  BaseWithIndexAndDisplacement64Matcher match36(graph()->NewNode(a_op, b1, m3));
+  CheckBaseWithIndexAndDisplacement(&match36, m3, 0, b1, NULL);
+
+  // (S4 + B1) -> [B0, 0, S4, NULL]
+  BaseWithIndexAndDisplacement64Matcher match37(graph()->NewNode(a_op, b1, s4));
+  CheckBaseWithIndexAndDisplacement(&match37, s4, 0, b1, NULL);
+
+  // 3 INPUT
+
+  // (D15 + S3) + B0 -> [p1, 2, b0, d15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement64Matcher match38(
+      graph()->NewNode(a_op, graph()->NewNode(a_op, d15, s3), b0));
+  CheckBaseWithIndexAndDisplacement(&match38, p1, 3, b0, d15);
+
+  // (B0 + D15) + S3 -> [p1, 2, b0, d15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement64Matcher match39(
+      graph()->NewNode(a_op, graph()->NewNode(a_op, b0, d15), s3));
+  CheckBaseWithIndexAndDisplacement(&match39, p1, 3, b0, d15);
+
+  // (S3 + B0) + D15 -> [p1, 2, b0, d15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement64Matcher match40(
+      graph()->NewNode(a_op, graph()->NewNode(a_op, s3, b0), d15));
+  CheckBaseWithIndexAndDisplacement(&match40, p1, 3, b0, d15);
+
+  // D15 + (S3 + B0) -> [p1, 2, b0, d15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement64Matcher match41(
+      graph()->NewNode(a_op, d15, graph()->NewNode(a_op, s3, b0)));
+  CheckBaseWithIndexAndDisplacement(&match41, p1, 3, b0, d15);
+
+  // B0 + (D15 + S3) -> [p1, 2, b0, d15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement64Matcher match42(
+      graph()->NewNode(a_op, b0, graph()->NewNode(a_op, d15, s3)));
+  CheckBaseWithIndexAndDisplacement(&match42, p1, 3, b0, d15);
+
+  // S3 + (B0 + D15) -> [p1, 2, b0, d15]
+  s3 = graph()->NewNode(s_op, p1, d3);
+  BaseWithIndexAndDisplacement64Matcher match43(
+      graph()->NewNode(a_op, s3, graph()->NewNode(a_op, b0, d15)));
+  CheckBaseWithIndexAndDisplacement(&match43, p1, 3, b0, d15);
+
+  // 2 INPUT with non-power of 2 scale
+
+  // (M3 + D15) -> [p1, 1, p1, D15]
+  m3 = graph()->NewNode(m_op, p1, d3);
+  BaseWithIndexAndDisplacement64Matcher match44(
+      graph()->NewNode(a_op, m3, d15));
+  CheckBaseWithIndexAndDisplacement(&match44, p1, 1, p1, d15);
+
+  // (M5 + D15) -> [p1, 2, p1, D15]
+  m5 = graph()->NewNode(m_op, p1, d5);
+  BaseWithIndexAndDisplacement64Matcher match45(
+      graph()->NewNode(a_op, m5, d15));
+  CheckBaseWithIndexAndDisplacement(&match45, p1, 2, p1, d15);
+
+  // (M9 + D15) -> [p1, 3, p1, D15]
+  m9 = graph()->NewNode(m_op, p1, d9);
+  BaseWithIndexAndDisplacement64Matcher match46(
+      graph()->NewNode(a_op, m9, d15));
+  CheckBaseWithIndexAndDisplacement(&match46, p1, 3, p1, d15);
+
+  // 3 INPUT negative cases: non-power of 2 scale but with a base
+
+  // ((M3 + B0) + D15) -> [m3, 0, b0, D15]
+  m3 = graph()->NewNode(m_op, p1, d3);
+  Node* temp = graph()->NewNode(a_op, m3, b0);
+  BaseWithIndexAndDisplacement64Matcher match47(
+      graph()->NewNode(a_op, temp, d15));
+  CheckBaseWithIndexAndDisplacement(&match47, m3, 0, b0, d15);
+
+  // (M3 + (B0 + D15)) -> [m3, 0, b0, D15]
+  m3 = graph()->NewNode(m_op, p1, d3);
+  temp = graph()->NewNode(a_op, d15, b0);
+  BaseWithIndexAndDisplacement64Matcher match48(
+      graph()->NewNode(a_op, m3, temp));
+  CheckBaseWithIndexAndDisplacement(&match48, m3, 0, b0, d15);
+
+  // ((B0 + M3) + D15) -> [m3, 0, b0, D15]
+  m3 = graph()->NewNode(m_op, p1, d3);
+  temp = graph()->NewNode(a_op, b0, m3);
+  BaseWithIndexAndDisplacement64Matcher match49(
+      graph()->NewNode(a_op, temp, d15));
+  CheckBaseWithIndexAndDisplacement(&match49, m3, 0, b0, d15);
+
+  // (M3 + (D15 + B0)) -> [m3, 0, b0, D15]
+  m3 = graph()->NewNode(m_op, p1, d3);
+  temp = graph()->NewNode(a_op, b0, d15);
+  BaseWithIndexAndDisplacement64Matcher match50(
+      graph()->NewNode(a_op, m3, temp));
+  CheckBaseWithIndexAndDisplacement(&match50, m3, 0, b0, d15);
+}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/node-test-utils.cc b/test/unittests/compiler/node-test-utils.cc
new file mode 100644
index 0000000..74afda9
--- /dev/null
+++ b/test/unittests/compiler/node-test-utils.cc
@@ -0,0 +1,1315 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "test/unittests/compiler/node-test-utils.h"
+
+#include "src/assembler.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/simplified-operator.h"
+
+using testing::_;
+using testing::MakeMatcher;
+using testing::MatcherInterface;
+using testing::MatchResultListener;
+using testing::StringMatchResultListener;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+namespace {
+
+template <typename T>
+bool PrintMatchAndExplain(const T& value, const char* value_name,
+                          const Matcher<T>& value_matcher,
+                          MatchResultListener* listener) {
+  StringMatchResultListener value_listener;
+  if (!value_matcher.MatchAndExplain(value, &value_listener)) {
+    *listener << "whose " << value_name << " " << value << " doesn't match";
+    if (value_listener.str() != "") {
+      *listener << ", " << value_listener.str();
+    }
+    return false;
+  }
+  return true;
+}
+
+
+class NodeMatcher : public MatcherInterface<Node*> {
+ public:
+  explicit NodeMatcher(IrOpcode::Value opcode) : opcode_(opcode) {}
+
+  void DescribeTo(std::ostream* os) const OVERRIDE {
+    *os << "is a " << IrOpcode::Mnemonic(opcode_) << " node";
+  }
+
+  bool MatchAndExplain(Node* node,
+                       MatchResultListener* listener) const OVERRIDE {
+    if (node == NULL) {
+      *listener << "which is NULL";
+      return false;
+    }
+    if (node->opcode() != opcode_) {
+      *listener << "whose opcode is " << IrOpcode::Mnemonic(node->opcode())
+                << " but should have been " << IrOpcode::Mnemonic(opcode_);
+      return false;
+    }
+    return true;
+  }
+
+ private:
+  const IrOpcode::Value opcode_;
+};
+
+
+class IsBranchMatcher FINAL : public NodeMatcher {
+ public:
+  IsBranchMatcher(const Matcher<Node*>& value_matcher,
+                  const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kBranch),
+        value_matcher_(value_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose value (";
+    value_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+                                 "value", value_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> value_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsMergeMatcher FINAL : public NodeMatcher {
+ public:
+  IsMergeMatcher(const Matcher<Node*>& control0_matcher,
+                 const Matcher<Node*>& control1_matcher)
+      : NodeMatcher(IrOpcode::kMerge),
+        control0_matcher_(control0_matcher),
+        control1_matcher_(control1_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose control0 (";
+    control0_matcher_.DescribeTo(os);
+    *os << ") and control1 (";
+    control1_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node, 0),
+                                 "control0", control0_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node, 1),
+                                 "control1", control1_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> control0_matcher_;
+  const Matcher<Node*> control1_matcher_;
+};
+
+
+class IsControl1Matcher FINAL : public NodeMatcher {
+ public:
+  IsControl1Matcher(IrOpcode::Value opcode,
+                    const Matcher<Node*>& control_matcher)
+      : NodeMatcher(opcode), control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsFinishMatcher FINAL : public NodeMatcher {
+ public:
+  IsFinishMatcher(const Matcher<Node*>& value_matcher,
+                  const Matcher<Node*>& effect_matcher)
+      : NodeMatcher(IrOpcode::kFinish),
+        value_matcher_(value_matcher),
+        effect_matcher_(effect_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose value (";
+    value_matcher_.DescribeTo(os);
+    *os << ") and effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+                                 "value", value_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> value_matcher_;
+  const Matcher<Node*> effect_matcher_;
+};
+
+
+template <typename T>
+class IsConstantMatcher FINAL : public NodeMatcher {
+ public:
+  IsConstantMatcher(IrOpcode::Value opcode, const Matcher<T>& value_matcher)
+      : NodeMatcher(opcode), value_matcher_(value_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose value (";
+    value_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<T>(node), "value", value_matcher_,
+                                 listener));
+  }
+
+ private:
+  const Matcher<T> value_matcher_;
+};
+
+
+class IsSelectMatcher FINAL : public NodeMatcher {
+ public:
+  IsSelectMatcher(const Matcher<MachineType>& type_matcher,
+                  const Matcher<Node*>& value0_matcher,
+                  const Matcher<Node*>& value1_matcher,
+                  const Matcher<Node*>& value2_matcher)
+      : NodeMatcher(IrOpcode::kSelect),
+        type_matcher_(type_matcher),
+        value0_matcher_(value0_matcher),
+        value1_matcher_(value1_matcher),
+        value2_matcher_(value2_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose type (";
+    type_matcher_.DescribeTo(os);
+    *os << "), value0 (";
+    value0_matcher_.DescribeTo(os);
+    *os << "), value1 (";
+    value1_matcher_.DescribeTo(os);
+    *os << ") and value2 (";
+    value2_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
+                                 type_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+                                 "value0", value0_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "value1", value1_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
+                                 "value2", value2_matcher_, listener));
+  }
+
+ private:
+  const Matcher<MachineType> type_matcher_;
+  const Matcher<Node*> value0_matcher_;
+  const Matcher<Node*> value1_matcher_;
+  const Matcher<Node*> value2_matcher_;
+};
+
+
+class IsPhiMatcher FINAL : public NodeMatcher {
+ public:
+  IsPhiMatcher(const Matcher<MachineType>& type_matcher,
+               const Matcher<Node*>& value0_matcher,
+               const Matcher<Node*>& value1_matcher,
+               const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kPhi),
+        type_matcher_(type_matcher),
+        value0_matcher_(value0_matcher),
+        value1_matcher_(value1_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose type (";
+    type_matcher_.DescribeTo(os);
+    *os << "), value0 (";
+    value0_matcher_.DescribeTo(os);
+    *os << "), value1 (";
+    value1_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<MachineType>(node), "type",
+                                 type_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+                                 "value0", value0_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "value1", value1_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<MachineType> type_matcher_;
+  const Matcher<Node*> value0_matcher_;
+  const Matcher<Node*> value1_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsEffectPhiMatcher FINAL : public NodeMatcher {
+ public:
+  IsEffectPhiMatcher(const Matcher<Node*>& effect0_matcher,
+                     const Matcher<Node*>& effect1_matcher,
+                     const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kEffectPhi),
+        effect0_matcher_(effect0_matcher),
+        effect1_matcher_(effect1_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << "), effect0 (";
+    effect0_matcher_.DescribeTo(os);
+    *os << "), effect1 (";
+    effect1_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 0),
+                                 "effect0", effect0_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node, 1),
+                                 "effect1", effect1_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> effect0_matcher_;
+  const Matcher<Node*> effect1_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsProjectionMatcher FINAL : public NodeMatcher {
+ public:
+  IsProjectionMatcher(const Matcher<size_t>& index_matcher,
+                      const Matcher<Node*>& base_matcher)
+      : NodeMatcher(IrOpcode::kProjection),
+        index_matcher_(index_matcher),
+        base_matcher_(base_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose index (";
+    index_matcher_.DescribeTo(os);
+    *os << ") and base (";
+    base_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<size_t>(node), "index",
+                                 index_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+                                 base_matcher_, listener));
+  }
+
+ private:
+  const Matcher<size_t> index_matcher_;
+  const Matcher<Node*> base_matcher_;
+};
+
+
+class IsCall2Matcher FINAL : public NodeMatcher {
+ public:
+  IsCall2Matcher(const Matcher<CallDescriptor*>& descriptor_matcher,
+                 const Matcher<Node*>& value0_matcher,
+                 const Matcher<Node*>& value1_matcher,
+                 const Matcher<Node*>& effect_matcher,
+                 const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kCall),
+        descriptor_matcher_(descriptor_matcher),
+        value0_matcher_(value0_matcher),
+        value1_matcher_(value1_matcher),
+        effect_matcher_(effect_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose value0 (";
+    value0_matcher_.DescribeTo(os);
+    *os << ") and value1 (";
+    value1_matcher_.DescribeTo(os);
+    *os << ") and effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<CallDescriptor*>(node),
+                                 "descriptor", descriptor_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+                                 "value0", value0_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "value1", value1_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<CallDescriptor*> descriptor_matcher_;
+  const Matcher<Node*> value0_matcher_;
+  const Matcher<Node*> value1_matcher_;
+  const Matcher<Node*> effect_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsCall4Matcher FINAL : public NodeMatcher {
+ public:
+  IsCall4Matcher(const Matcher<CallDescriptor*>& descriptor_matcher,
+                 const Matcher<Node*>& value0_matcher,
+                 const Matcher<Node*>& value1_matcher,
+                 const Matcher<Node*>& value2_matcher,
+                 const Matcher<Node*>& value3_matcher,
+                 const Matcher<Node*>& effect_matcher,
+                 const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kCall),
+        descriptor_matcher_(descriptor_matcher),
+        value0_matcher_(value0_matcher),
+        value1_matcher_(value1_matcher),
+        value2_matcher_(value2_matcher),
+        value3_matcher_(value3_matcher),
+        effect_matcher_(effect_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose value0 (";
+    value0_matcher_.DescribeTo(os);
+    *os << ") and value1 (";
+    value1_matcher_.DescribeTo(os);
+    *os << ") and value2 (";
+    value2_matcher_.DescribeTo(os);
+    *os << ") and value3 (";
+    value3_matcher_.DescribeTo(os);
+    *os << ") and effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<CallDescriptor*>(node),
+                                 "descriptor", descriptor_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+                                 "value0", value0_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "value1", value1_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
+                                 "value2", value2_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3),
+                                 "value3", value3_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<CallDescriptor*> descriptor_matcher_;
+  const Matcher<Node*> value0_matcher_;
+  const Matcher<Node*> value1_matcher_;
+  const Matcher<Node*> value2_matcher_;
+  const Matcher<Node*> value3_matcher_;
+  const Matcher<Node*> effect_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsLoadFieldMatcher FINAL : public NodeMatcher {
+ public:
+  IsLoadFieldMatcher(const Matcher<FieldAccess>& access_matcher,
+                     const Matcher<Node*>& base_matcher,
+                     const Matcher<Node*>& effect_matcher,
+                     const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kLoadField),
+        access_matcher_(access_matcher),
+        base_matcher_(base_matcher),
+        effect_matcher_(effect_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose access (";
+    access_matcher_.DescribeTo(os);
+    *os << "), base (";
+    base_matcher_.DescribeTo(os);
+    *os << "), effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<FieldAccess>(node), "access",
+                                 access_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+                                 base_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<FieldAccess> access_matcher_;
+  const Matcher<Node*> base_matcher_;
+  const Matcher<Node*> effect_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsStoreFieldMatcher FINAL : public NodeMatcher {
+ public:
+  IsStoreFieldMatcher(const Matcher<FieldAccess>& access_matcher,
+                      const Matcher<Node*>& base_matcher,
+                      const Matcher<Node*>& value_matcher,
+                      const Matcher<Node*>& effect_matcher,
+                      const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kStoreField),
+        access_matcher_(access_matcher),
+        base_matcher_(base_matcher),
+        value_matcher_(value_matcher),
+        effect_matcher_(effect_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose access (";
+    access_matcher_.DescribeTo(os);
+    *os << "), base (";
+    base_matcher_.DescribeTo(os);
+    *os << "), value (";
+    value_matcher_.DescribeTo(os);
+    *os << "), effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<FieldAccess>(node), "access",
+                                 access_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+                                 base_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "value", value_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<FieldAccess> access_matcher_;
+  const Matcher<Node*> base_matcher_;
+  const Matcher<Node*> value_matcher_;
+  const Matcher<Node*> effect_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsLoadBufferMatcher FINAL : public NodeMatcher {
+ public:
+  IsLoadBufferMatcher(const Matcher<BufferAccess>& access_matcher,
+                      const Matcher<Node*>& buffer_matcher,
+                      const Matcher<Node*>& offset_matcher,
+                      const Matcher<Node*>& length_matcher,
+                      const Matcher<Node*>& effect_matcher,
+                      const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kLoadBuffer),
+        access_matcher_(access_matcher),
+        buffer_matcher_(buffer_matcher),
+        offset_matcher_(offset_matcher),
+        length_matcher_(length_matcher),
+        effect_matcher_(effect_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose access (";
+    access_matcher_.DescribeTo(os);
+    *os << "), buffer (";
+    buffer_matcher_.DescribeTo(os);
+    *os << "), offset (";
+    offset_matcher_.DescribeTo(os);
+    *os << "), length (";
+    length_matcher_.DescribeTo(os);
+    *os << "), effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(BufferAccessOf(node->op()), "access",
+                                 access_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+                                 "buffer", buffer_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "offset", offset_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
+                                 "length", length_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<BufferAccess> access_matcher_;
+  const Matcher<Node*> buffer_matcher_;
+  const Matcher<Node*> offset_matcher_;
+  const Matcher<Node*> length_matcher_;
+  const Matcher<Node*> effect_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsStoreBufferMatcher FINAL : public NodeMatcher {
+ public:
+  IsStoreBufferMatcher(const Matcher<BufferAccess>& access_matcher,
+                       const Matcher<Node*>& buffer_matcher,
+                       const Matcher<Node*>& offset_matcher,
+                       const Matcher<Node*>& length_matcher,
+                       const Matcher<Node*>& value_matcher,
+                       const Matcher<Node*>& effect_matcher,
+                       const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kStoreBuffer),
+        access_matcher_(access_matcher),
+        buffer_matcher_(buffer_matcher),
+        offset_matcher_(offset_matcher),
+        length_matcher_(length_matcher),
+        value_matcher_(value_matcher),
+        effect_matcher_(effect_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose access (";
+    access_matcher_.DescribeTo(os);
+    *os << "), buffer (";
+    buffer_matcher_.DescribeTo(os);
+    *os << "), offset (";
+    offset_matcher_.DescribeTo(os);
+    *os << "), length (";
+    length_matcher_.DescribeTo(os);
+    *os << "), value (";
+    value_matcher_.DescribeTo(os);
+    *os << "), effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(BufferAccessOf(node->op()), "access",
+                                 access_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+                                 "buffer", buffer_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "offset", offset_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
+                                 "length", length_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 3),
+                                 "value", value_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<BufferAccess> access_matcher_;
+  const Matcher<Node*> buffer_matcher_;
+  const Matcher<Node*> offset_matcher_;
+  const Matcher<Node*> length_matcher_;
+  const Matcher<Node*> value_matcher_;
+  const Matcher<Node*> effect_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsLoadElementMatcher FINAL : public NodeMatcher {
+ public:
+  IsLoadElementMatcher(const Matcher<ElementAccess>& access_matcher,
+                       const Matcher<Node*>& base_matcher,
+                       const Matcher<Node*>& index_matcher,
+                       const Matcher<Node*>& effect_matcher,
+                       const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kLoadElement),
+        access_matcher_(access_matcher),
+        base_matcher_(base_matcher),
+        index_matcher_(index_matcher),
+        effect_matcher_(effect_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose access (";
+    access_matcher_.DescribeTo(os);
+    *os << "), base (";
+    base_matcher_.DescribeTo(os);
+    *os << "), index (";
+    index_matcher_.DescribeTo(os);
+    *os << "), effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access",
+                                 access_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+                                 base_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "index", index_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<ElementAccess> access_matcher_;
+  const Matcher<Node*> base_matcher_;
+  const Matcher<Node*> index_matcher_;
+  const Matcher<Node*> effect_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsStoreElementMatcher FINAL : public NodeMatcher {
+ public:
+  IsStoreElementMatcher(const Matcher<ElementAccess>& access_matcher,
+                        const Matcher<Node*>& base_matcher,
+                        const Matcher<Node*>& index_matcher,
+                        const Matcher<Node*>& value_matcher,
+                        const Matcher<Node*>& effect_matcher,
+                        const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kStoreElement),
+        access_matcher_(access_matcher),
+        base_matcher_(base_matcher),
+        index_matcher_(index_matcher),
+        value_matcher_(value_matcher),
+        effect_matcher_(effect_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose access (";
+    access_matcher_.DescribeTo(os);
+    *os << "), base (";
+    base_matcher_.DescribeTo(os);
+    *os << "), index (";
+    index_matcher_.DescribeTo(os);
+    *os << "), value (";
+    value_matcher_.DescribeTo(os);
+    *os << "), effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<ElementAccess>(node), "access",
+                                 access_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+                                 base_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "index", index_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
+                                 "value", value_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<ElementAccess> access_matcher_;
+  const Matcher<Node*> base_matcher_;
+  const Matcher<Node*> index_matcher_;
+  const Matcher<Node*> value_matcher_;
+  const Matcher<Node*> effect_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsLoadMatcher FINAL : public NodeMatcher {
+ public:
+  IsLoadMatcher(const Matcher<LoadRepresentation>& rep_matcher,
+                const Matcher<Node*>& base_matcher,
+                const Matcher<Node*>& index_matcher,
+                const Matcher<Node*>& effect_matcher,
+                const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kLoad),
+        rep_matcher_(rep_matcher),
+        base_matcher_(base_matcher),
+        index_matcher_(index_matcher),
+        effect_matcher_(effect_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose rep (";
+    rep_matcher_.DescribeTo(os);
+    *os << "), base (";
+    base_matcher_.DescribeTo(os);
+    *os << "), index (";
+    index_matcher_.DescribeTo(os);
+    *os << "), effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<LoadRepresentation>(node), "rep",
+                                 rep_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+                                 base_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "index", index_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<LoadRepresentation> rep_matcher_;
+  const Matcher<Node*> base_matcher_;
+  const Matcher<Node*> index_matcher_;
+  const Matcher<Node*> effect_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsToNumberMatcher FINAL : public NodeMatcher {
+ public:
+  IsToNumberMatcher(const Matcher<Node*>& base_matcher,
+                    const Matcher<Node*>& context_matcher,
+                    const Matcher<Node*>& effect_matcher,
+                    const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kJSToNumber),
+        base_matcher_(base_matcher),
+        context_matcher_(context_matcher),
+        effect_matcher_(effect_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose base (";
+    base_matcher_.DescribeTo(os);
+    *os << "), context (";
+    context_matcher_.DescribeTo(os);
+    *os << "), effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+                                 base_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetContextInput(node),
+                                 "context", context_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> base_matcher_;
+  const Matcher<Node*> context_matcher_;
+  const Matcher<Node*> effect_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsStoreMatcher FINAL : public NodeMatcher {
+ public:
+  IsStoreMatcher(const Matcher<StoreRepresentation>& rep_matcher,
+                 const Matcher<Node*>& base_matcher,
+                 const Matcher<Node*>& index_matcher,
+                 const Matcher<Node*>& value_matcher,
+                 const Matcher<Node*>& effect_matcher,
+                 const Matcher<Node*>& control_matcher)
+      : NodeMatcher(IrOpcode::kStore),
+        rep_matcher_(rep_matcher),
+        base_matcher_(base_matcher),
+        index_matcher_(index_matcher),
+        value_matcher_(value_matcher),
+        effect_matcher_(effect_matcher),
+        control_matcher_(control_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose rep (";
+    rep_matcher_.DescribeTo(os);
+    *os << "), base (";
+    base_matcher_.DescribeTo(os);
+    *os << "), index (";
+    index_matcher_.DescribeTo(os);
+    *os << "), value (";
+    value_matcher_.DescribeTo(os);
+    *os << "), effect (";
+    effect_matcher_.DescribeTo(os);
+    *os << ") and control (";
+    control_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(OpParameter<StoreRepresentation>(node), "rep",
+                                 rep_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "base",
+                                 base_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1),
+                                 "index", index_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 2),
+                                 "value", value_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetEffectInput(node), "effect",
+                                 effect_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetControlInput(node),
+                                 "control", control_matcher_, listener));
+  }
+
+ private:
+  const Matcher<StoreRepresentation> rep_matcher_;
+  const Matcher<Node*> base_matcher_;
+  const Matcher<Node*> index_matcher_;
+  const Matcher<Node*> value_matcher_;
+  const Matcher<Node*> effect_matcher_;
+  const Matcher<Node*> control_matcher_;
+};
+
+
+class IsBinopMatcher FINAL : public NodeMatcher {
+ public:
+  IsBinopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& lhs_matcher,
+                 const Matcher<Node*>& rhs_matcher)
+      : NodeMatcher(opcode),
+        lhs_matcher_(lhs_matcher),
+        rhs_matcher_(rhs_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose lhs (";
+    lhs_matcher_.DescribeTo(os);
+    *os << ") and rhs (";
+    rhs_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0), "lhs",
+                                 lhs_matcher_, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 1), "rhs",
+                                 rhs_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> lhs_matcher_;
+  const Matcher<Node*> rhs_matcher_;
+};
+
+
+class IsUnopMatcher FINAL : public NodeMatcher {
+ public:
+  IsUnopMatcher(IrOpcode::Value opcode, const Matcher<Node*>& input_matcher)
+      : NodeMatcher(opcode), input_matcher_(input_matcher) {}
+
+  void DescribeTo(std::ostream* os) const FINAL {
+    NodeMatcher::DescribeTo(os);
+    *os << " whose input (";
+    input_matcher_.DescribeTo(os);
+    *os << ")";
+  }
+
+  bool MatchAndExplain(Node* node, MatchResultListener* listener) const FINAL {
+    return (NodeMatcher::MatchAndExplain(node, listener) &&
+            PrintMatchAndExplain(NodeProperties::GetValueInput(node, 0),
+                                 "input", input_matcher_, listener));
+  }
+
+ private:
+  const Matcher<Node*> input_matcher_;
+};
+}
+
+
+Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
+                        const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsBranchMatcher(value_matcher, control_matcher));
+}
+
+
+Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
+                       const Matcher<Node*>& control1_matcher) {
+  return MakeMatcher(new IsMergeMatcher(control0_matcher, control1_matcher));
+}
+
+
+Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsControl1Matcher(IrOpcode::kIfTrue, control_matcher));
+}
+
+
+Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(
+      new IsControl1Matcher(IrOpcode::kIfFalse, control_matcher));
+}
+
+
+Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) {
+  return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect, value_matcher));
+}
+
+
+Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
+                        const Matcher<Node*>& effect_matcher) {
+  return MakeMatcher(new IsFinishMatcher(value_matcher, effect_matcher));
+}
+
+
+Matcher<Node*> IsExternalConstant(
+    const Matcher<ExternalReference>& value_matcher) {
+  return MakeMatcher(new IsConstantMatcher<ExternalReference>(
+      IrOpcode::kExternalConstant, value_matcher));
+}
+
+
+Matcher<Node*> IsHeapConstant(
+    const Matcher<Unique<HeapObject> >& value_matcher) {
+  return MakeMatcher(new IsConstantMatcher<Unique<HeapObject> >(
+      IrOpcode::kHeapConstant, value_matcher));
+}
+
+
+Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher) {
+  return MakeMatcher(
+      new IsConstantMatcher<int32_t>(IrOpcode::kInt32Constant, value_matcher));
+}
+
+
+Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher) {
+  return MakeMatcher(
+      new IsConstantMatcher<int64_t>(IrOpcode::kInt64Constant, value_matcher));
+}
+
+
+Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher) {
+  return MakeMatcher(
+      new IsConstantMatcher<float>(IrOpcode::kFloat32Constant, value_matcher));
+}
+
+
+Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher) {
+  return MakeMatcher(
+      new IsConstantMatcher<double>(IrOpcode::kFloat64Constant, value_matcher));
+}
+
+
+Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher) {
+  return MakeMatcher(
+      new IsConstantMatcher<double>(IrOpcode::kNumberConstant, value_matcher));
+}
+
+
+Matcher<Node*> IsSelect(const Matcher<MachineType>& type_matcher,
+                        const Matcher<Node*>& value0_matcher,
+                        const Matcher<Node*>& value1_matcher,
+                        const Matcher<Node*>& value2_matcher) {
+  return MakeMatcher(new IsSelectMatcher(type_matcher, value0_matcher,
+                                         value1_matcher, value2_matcher));
+}
+
+
+Matcher<Node*> IsPhi(const Matcher<MachineType>& type_matcher,
+                     const Matcher<Node*>& value0_matcher,
+                     const Matcher<Node*>& value1_matcher,
+                     const Matcher<Node*>& merge_matcher) {
+  return MakeMatcher(new IsPhiMatcher(type_matcher, value0_matcher,
+                                      value1_matcher, merge_matcher));
+}
+
+
+Matcher<Node*> IsEffectPhi(const Matcher<Node*>& effect0_matcher,
+                           const Matcher<Node*>& effect1_matcher,
+                           const Matcher<Node*>& merge_matcher) {
+  return MakeMatcher(
+      new IsEffectPhiMatcher(effect0_matcher, effect1_matcher, merge_matcher));
+}
+
+
+Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher,
+                            const Matcher<Node*>& base_matcher) {
+  return MakeMatcher(new IsProjectionMatcher(index_matcher, base_matcher));
+}
+
+
+Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
+                      const Matcher<Node*>& value0_matcher,
+                      const Matcher<Node*>& value1_matcher,
+                      const Matcher<Node*>& effect_matcher,
+                      const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsCall2Matcher(descriptor_matcher, value0_matcher,
+                                        value1_matcher, effect_matcher,
+                                        control_matcher));
+}
+
+
+Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
+                      const Matcher<Node*>& value0_matcher,
+                      const Matcher<Node*>& value1_matcher,
+                      const Matcher<Node*>& value2_matcher,
+                      const Matcher<Node*>& value3_matcher,
+                      const Matcher<Node*>& effect_matcher,
+                      const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsCall4Matcher(
+      descriptor_matcher, value0_matcher, value1_matcher, value2_matcher,
+      value3_matcher, effect_matcher, control_matcher));
+}
+
+
+Matcher<Node*> IsLoadField(const Matcher<FieldAccess>& access_matcher,
+                           const Matcher<Node*>& base_matcher,
+                           const Matcher<Node*>& effect_matcher,
+                           const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsLoadFieldMatcher(access_matcher, base_matcher,
+                                            effect_matcher, control_matcher));
+}
+
+
+Matcher<Node*> IsStoreField(const Matcher<FieldAccess>& access_matcher,
+                            const Matcher<Node*>& base_matcher,
+                            const Matcher<Node*>& value_matcher,
+                            const Matcher<Node*>& effect_matcher,
+                            const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsStoreFieldMatcher(access_matcher, base_matcher,
+                                             value_matcher, effect_matcher,
+                                             control_matcher));
+}
+
+
+Matcher<Node*> IsLoadBuffer(const Matcher<BufferAccess>& access_matcher,
+                            const Matcher<Node*>& buffer_matcher,
+                            const Matcher<Node*>& offset_matcher,
+                            const Matcher<Node*>& length_matcher,
+                            const Matcher<Node*>& effect_matcher,
+                            const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsLoadBufferMatcher(access_matcher, buffer_matcher,
+                                             offset_matcher, length_matcher,
+                                             effect_matcher, control_matcher));
+}
+
+
+Matcher<Node*> IsStoreBuffer(const Matcher<BufferAccess>& access_matcher,
+                             const Matcher<Node*>& buffer_matcher,
+                             const Matcher<Node*>& offset_matcher,
+                             const Matcher<Node*>& length_matcher,
+                             const Matcher<Node*>& value_matcher,
+                             const Matcher<Node*>& effect_matcher,
+                             const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsStoreBufferMatcher(
+      access_matcher, buffer_matcher, offset_matcher, length_matcher,
+      value_matcher, effect_matcher, control_matcher));
+}
+
+
+Matcher<Node*> IsLoadElement(const Matcher<ElementAccess>& access_matcher,
+                             const Matcher<Node*>& base_matcher,
+                             const Matcher<Node*>& index_matcher,
+                             const Matcher<Node*>& effect_matcher,
+                             const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsLoadElementMatcher(access_matcher, base_matcher,
+                                              index_matcher, effect_matcher,
+                                              control_matcher));
+}
+
+
+Matcher<Node*> IsStoreElement(const Matcher<ElementAccess>& access_matcher,
+                              const Matcher<Node*>& base_matcher,
+                              const Matcher<Node*>& index_matcher,
+                              const Matcher<Node*>& value_matcher,
+                              const Matcher<Node*>& effect_matcher,
+                              const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsStoreElementMatcher(
+      access_matcher, base_matcher, index_matcher, value_matcher,
+      effect_matcher, control_matcher));
+}
+
+
+Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
+                      const Matcher<Node*>& base_matcher,
+                      const Matcher<Node*>& index_matcher,
+                      const Matcher<Node*>& effect_matcher,
+                      const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsLoadMatcher(rep_matcher, base_matcher, index_matcher,
+                                       effect_matcher, control_matcher));
+}
+
+
+Matcher<Node*> IsToNumber(const Matcher<Node*>& base_matcher,
+                          const Matcher<Node*>& context_matcher,
+                          const Matcher<Node*>& effect_matcher,
+                          const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsToNumberMatcher(base_matcher, context_matcher,
+                                           effect_matcher, control_matcher));
+}
+
+
+Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
+                       const Matcher<Node*>& base_matcher,
+                       const Matcher<Node*>& index_matcher,
+                       const Matcher<Node*>& value_matcher,
+                       const Matcher<Node*>& effect_matcher,
+                       const Matcher<Node*>& control_matcher) {
+  return MakeMatcher(new IsStoreMatcher(rep_matcher, base_matcher,
+                                        index_matcher, value_matcher,
+                                        effect_matcher, control_matcher));
+}
+
+
+#define IS_BINOP_MATCHER(Name)                                            \
+  Matcher<Node*> Is##Name(const Matcher<Node*>& lhs_matcher,              \
+                          const Matcher<Node*>& rhs_matcher) {            \
+    return MakeMatcher(                                                   \
+        new IsBinopMatcher(IrOpcode::k##Name, lhs_matcher, rhs_matcher)); \
+  }
+IS_BINOP_MATCHER(NumberEqual)
+IS_BINOP_MATCHER(NumberLessThan)
+IS_BINOP_MATCHER(NumberSubtract)
+IS_BINOP_MATCHER(NumberMultiply)
+IS_BINOP_MATCHER(Word32And)
+IS_BINOP_MATCHER(Word32Sar)
+IS_BINOP_MATCHER(Word32Shl)
+IS_BINOP_MATCHER(Word32Shr)
+IS_BINOP_MATCHER(Word32Ror)
+IS_BINOP_MATCHER(Word32Equal)
+IS_BINOP_MATCHER(Word64And)
+IS_BINOP_MATCHER(Word64Sar)
+IS_BINOP_MATCHER(Word64Shl)
+IS_BINOP_MATCHER(Word64Equal)
+IS_BINOP_MATCHER(Int32AddWithOverflow)
+IS_BINOP_MATCHER(Int32Add)
+IS_BINOP_MATCHER(Int32Sub)
+IS_BINOP_MATCHER(Int32Mul)
+IS_BINOP_MATCHER(Int32MulHigh)
+IS_BINOP_MATCHER(Int32LessThan)
+IS_BINOP_MATCHER(Uint32LessThan)
+IS_BINOP_MATCHER(Uint32LessThanOrEqual)
+IS_BINOP_MATCHER(Float64Sub)
+#undef IS_BINOP_MATCHER
+
+
+#define IS_UNOP_MATCHER(Name)                                                \
+  Matcher<Node*> Is##Name(const Matcher<Node*>& input_matcher) {             \
+    return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name, input_matcher)); \
+  }
+IS_UNOP_MATCHER(AnyToBoolean)
+IS_UNOP_MATCHER(BooleanNot)
+IS_UNOP_MATCHER(ChangeFloat64ToInt32)
+IS_UNOP_MATCHER(ChangeFloat64ToUint32)
+IS_UNOP_MATCHER(ChangeInt32ToFloat64)
+IS_UNOP_MATCHER(ChangeInt32ToInt64)
+IS_UNOP_MATCHER(ChangeUint32ToFloat64)
+IS_UNOP_MATCHER(ChangeUint32ToUint64)
+IS_UNOP_MATCHER(TruncateFloat64ToFloat32)
+IS_UNOP_MATCHER(TruncateFloat64ToInt32)
+IS_UNOP_MATCHER(TruncateInt64ToInt32)
+IS_UNOP_MATCHER(Float64Sqrt)
+IS_UNOP_MATCHER(Float64Floor)
+IS_UNOP_MATCHER(Float64Ceil)
+IS_UNOP_MATCHER(Float64RoundTruncate)
+IS_UNOP_MATCHER(Float64RoundTiesAway)
+IS_UNOP_MATCHER(NumberToInt32)
+IS_UNOP_MATCHER(NumberToUint32)
+#undef IS_UNOP_MATCHER
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/node-test-utils.h b/test/unittests/compiler/node-test-utils.h
new file mode 100644
index 0000000..02b6e43
--- /dev/null
+++ b/test/unittests/compiler/node-test-utils.h
@@ -0,0 +1,196 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_UNITTESTS_COMPILER_NODE_TEST_UTILS_H_
+#define V8_UNITTESTS_COMPILER_NODE_TEST_UTILS_H_
+
+#include "src/compiler/machine-operator.h"
+#include "src/compiler/machine-type.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace v8 {
+namespace internal {
+
+// Forward declarations.
+class ExternalReference;
+class HeapObject;
+template <class T>
+class Unique;
+
+namespace compiler {
+
+// Forward declarations.
+class BufferAccess;
+class CallDescriptor;
+struct ElementAccess;
+struct FieldAccess;
+class Node;
+
+
+using ::testing::Matcher;
+
+
+Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
+                        const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
+                       const Matcher<Node*>& control1_matcher);
+Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
+                        const Matcher<Node*>& effect_matcher);
+Matcher<Node*> IsExternalConstant(
+    const Matcher<ExternalReference>& value_matcher);
+Matcher<Node*> IsHeapConstant(
+    const Matcher<Unique<HeapObject> >& value_matcher);
+Matcher<Node*> IsFloat32Constant(const Matcher<float>& value_matcher);
+Matcher<Node*> IsFloat64Constant(const Matcher<double>& value_matcher);
+Matcher<Node*> IsInt32Constant(const Matcher<int32_t>& value_matcher);
+Matcher<Node*> IsInt64Constant(const Matcher<int64_t>& value_matcher);
+Matcher<Node*> IsNumberConstant(const Matcher<double>& value_matcher);
+Matcher<Node*> IsSelect(const Matcher<MachineType>& type_matcher,
+                        const Matcher<Node*>& value0_matcher,
+                        const Matcher<Node*>& value1_matcher,
+                        const Matcher<Node*>& value2_matcher);
+Matcher<Node*> IsPhi(const Matcher<MachineType>& type_matcher,
+                     const Matcher<Node*>& value0_matcher,
+                     const Matcher<Node*>& value1_matcher,
+                     const Matcher<Node*>& merge_matcher);
+Matcher<Node*> IsEffectPhi(const Matcher<Node*>& effect0_matcher,
+                           const Matcher<Node*>& effect1_matcher,
+                           const Matcher<Node*>& merge_matcher);
+Matcher<Node*> IsProjection(const Matcher<size_t>& index_matcher,
+                            const Matcher<Node*>& base_matcher);
+Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
+                      const Matcher<Node*>& value0_matcher,
+                      const Matcher<Node*>& value1_matcher,
+                      const Matcher<Node*>& effect_matcher,
+                      const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsCall(const Matcher<CallDescriptor*>& descriptor_matcher,
+                      const Matcher<Node*>& value0_matcher,
+                      const Matcher<Node*>& value1_matcher,
+                      const Matcher<Node*>& value2_matcher,
+                      const Matcher<Node*>& value3_matcher,
+                      const Matcher<Node*>& effect_matcher,
+                      const Matcher<Node*>& control_matcher);
+
+Matcher<Node*> IsAnyToBoolean(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsBooleanNot(const Matcher<Node*>& value_matcher);
+Matcher<Node*> IsNumberEqual(const Matcher<Node*>& lhs_matcher,
+                             const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsNumberLessThan(const Matcher<Node*>& lhs_matcher,
+                                const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsNumberSubtract(const Matcher<Node*>& lhs_matcher,
+                                const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsNumberMultiply(const Matcher<Node*>& lhs_matcher,
+                                const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsLoadField(const Matcher<FieldAccess>& access_matcher,
+                           const Matcher<Node*>& base_matcher,
+                           const Matcher<Node*>& effect_matcher,
+                           const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsStoreField(const Matcher<FieldAccess>& access_matcher,
+                            const Matcher<Node*>& base_matcher,
+                            const Matcher<Node*>& value_matcher,
+                            const Matcher<Node*>& effect_matcher,
+                            const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsLoadBuffer(const Matcher<BufferAccess>& access_matcher,
+                            const Matcher<Node*>& buffer_matcher,
+                            const Matcher<Node*>& offset_matcher,
+                            const Matcher<Node*>& length_matcher,
+                            const Matcher<Node*>& effect_matcher,
+                            const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsStoreBuffer(const Matcher<BufferAccess>& access_matcher,
+                             const Matcher<Node*>& buffer_matcher,
+                             const Matcher<Node*>& offset_matcher,
+                             const Matcher<Node*>& length_matcher,
+                             const Matcher<Node*>& value_matcher,
+                             const Matcher<Node*>& effect_matcher,
+                             const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsLoadElement(const Matcher<ElementAccess>& access_matcher,
+                             const Matcher<Node*>& base_matcher,
+                             const Matcher<Node*>& index_matcher,
+                             const Matcher<Node*>& control_matcher,
+                             const Matcher<Node*>& effect_matcher);
+Matcher<Node*> IsStoreElement(const Matcher<ElementAccess>& access_matcher,
+                              const Matcher<Node*>& base_matcher,
+                              const Matcher<Node*>& index_matcher,
+                              const Matcher<Node*>& value_matcher,
+                              const Matcher<Node*>& effect_matcher,
+                              const Matcher<Node*>& control_matcher);
+
+Matcher<Node*> IsLoad(const Matcher<LoadRepresentation>& rep_matcher,
+                      const Matcher<Node*>& base_matcher,
+                      const Matcher<Node*>& index_matcher,
+                      const Matcher<Node*>& effect_matcher,
+                      const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsStore(const Matcher<StoreRepresentation>& rep_matcher,
+                       const Matcher<Node*>& base_matcher,
+                       const Matcher<Node*>& index_matcher,
+                       const Matcher<Node*>& value_matcher,
+                       const Matcher<Node*>& effect_matcher,
+                       const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsWord32And(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord32Sar(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord32Shl(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord32Shr(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord32Ror(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord32Equal(const Matcher<Node*>& lhs_matcher,
+                             const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64And(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64Shl(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64Sar(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord64Equal(const Matcher<Node*>& lhs_matcher,
+                             const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsInt32AddWithOverflow(const Matcher<Node*>& lhs_matcher,
+                                      const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsInt32Add(const Matcher<Node*>& lhs_matcher,
+                          const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsInt32Sub(const Matcher<Node*>& lhs_matcher,
+                          const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsInt32Mul(const Matcher<Node*>& lhs_matcher,
+                          const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsInt32MulHigh(const Matcher<Node*>& lhs_matcher,
+                              const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsInt32LessThan(const Matcher<Node*>& lhs_matcher,
+                               const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsUint32LessThan(const Matcher<Node*>& lhs_matcher,
+                                const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsUint32LessThanOrEqual(const Matcher<Node*>& lhs_matcher,
+                                       const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsChangeFloat64ToInt32(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsChangeFloat64ToUint32(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsChangeInt32ToFloat64(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsChangeInt32ToInt64(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsChangeUint32ToFloat64(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsChangeUint32ToUint64(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsTruncateFloat64ToFloat32(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsTruncateFloat64ToInt32(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsTruncateInt64ToInt32(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsFloat64Sub(const Matcher<Node*>& lhs_matcher,
+                            const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsFloat64Sqrt(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsFloat64Floor(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsFloat64Ceil(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsFloat64RoundTruncate(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsFloat64RoundTiesAway(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsToNumber(const Matcher<Node*>& base_matcher,
+                          const Matcher<Node*>& context_matcher,
+                          const Matcher<Node*>& effect_matcher,
+                          const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsNumberToInt32(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsNumberToUint32(const Matcher<Node*>& input_matcher);
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_UNITTESTS_COMPILER_NODE_TEST_UTILS_H_
diff --git a/test/unittests/compiler/register-allocator-unittest.cc b/test/unittests/compiler/register-allocator-unittest.cc
new file mode 100644
index 0000000..12dedbd
--- /dev/null
+++ b/test/unittests/compiler/register-allocator-unittest.cc
@@ -0,0 +1,437 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/pipeline.h"
+#include "test/unittests/compiler/instruction-sequence-unittest.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class RegisterAllocatorTest : public InstructionSequenceTest {
+ public:
+  void Allocate() {
+    WireBlocks();
+    Pipeline::AllocateRegistersForTesting(config(), sequence(), true);
+  }
+};
+
+
+TEST_F(RegisterAllocatorTest, CanAllocateThreeRegisters) {
+  // return p0 + p1;
+  StartBlock();
+  auto a_reg = Parameter();
+  auto b_reg = Parameter();
+  auto c_reg = EmitOI(Reg(1), Reg(a_reg, 1), Reg(b_reg, 0));
+  Return(c_reg);
+  EndBlock(Last());
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, SimpleLoop) {
+  // i = K;
+  // while(true) { i++ }
+  StartBlock();
+  auto i_reg = DefineConstant();
+  EndBlock();
+
+  {
+    StartLoop(1);
+
+    StartBlock();
+    auto phi = Phi(i_reg);
+    auto ipp = EmitOI(Same(), Reg(phi), Use(DefineConstant()));
+    Extend(phi, ipp);
+    EndBlock(Jump(0));
+
+    EndLoop();
+  }
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, SimpleBranch) {
+  // return i ? K1 : K2
+  StartBlock();
+  auto i = DefineConstant();
+  EndBlock(Branch(Reg(i), 1, 2));
+
+  StartBlock();
+  Return(DefineConstant());
+  EndBlock(Last());
+
+  StartBlock();
+  Return(DefineConstant());
+  EndBlock(Last());
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, SimpleDiamond) {
+  // return p0 ? p0 : p0
+  StartBlock();
+  auto param = Parameter();
+  EndBlock(Branch(Reg(param), 1, 2));
+
+  StartBlock();
+  EndBlock(Jump(2));
+
+  StartBlock();
+  EndBlock(Jump(1));
+
+  StartBlock();
+  Return(param);
+  EndBlock();
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, SimpleDiamondPhi) {
+  // return i ? K1 : K2
+  StartBlock();
+  EndBlock(Branch(Reg(DefineConstant()), 1, 2));
+
+  StartBlock();
+  auto t_val = DefineConstant();
+  EndBlock(Jump(2));
+
+  StartBlock();
+  auto f_val = DefineConstant();
+  EndBlock(Jump(1));
+
+  StartBlock();
+  Return(Reg(Phi(t_val, f_val)));
+  EndBlock();
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, DiamondManyPhis) {
+  const int kPhis = kDefaultNRegs * 2;
+
+  StartBlock();
+  EndBlock(Branch(Reg(DefineConstant()), 1, 2));
+
+  StartBlock();
+  VReg t_vals[kPhis];
+  for (int i = 0; i < kPhis; ++i) {
+    t_vals[i] = DefineConstant();
+  }
+  EndBlock(Jump(2));
+
+  StartBlock();
+  VReg f_vals[kPhis];
+  for (int i = 0; i < kPhis; ++i) {
+    f_vals[i] = DefineConstant();
+  }
+  EndBlock(Jump(1));
+
+  StartBlock();
+  TestOperand merged[kPhis];
+  for (int i = 0; i < kPhis; ++i) {
+    merged[i] = Use(Phi(t_vals[i], f_vals[i]));
+  }
+  Return(EmitCall(Slot(-1), kPhis, merged));
+  EndBlock();
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, DoubleDiamondManyRedundantPhis) {
+  const int kPhis = kDefaultNRegs * 2;
+
+  // First diamond.
+  StartBlock();
+  VReg vals[kPhis];
+  for (int i = 0; i < kPhis; ++i) {
+    vals[i] = Parameter(Slot(-1 - i));
+  }
+  EndBlock(Branch(Reg(DefineConstant()), 1, 2));
+
+  StartBlock();
+  EndBlock(Jump(2));
+
+  StartBlock();
+  EndBlock(Jump(1));
+
+  // Second diamond.
+  StartBlock();
+  EndBlock(Branch(Reg(DefineConstant()), 1, 2));
+
+  StartBlock();
+  EndBlock(Jump(2));
+
+  StartBlock();
+  EndBlock(Jump(1));
+
+  StartBlock();
+  TestOperand merged[kPhis];
+  for (int i = 0; i < kPhis; ++i) {
+    merged[i] = Use(Phi(vals[i], vals[i]));
+  }
+  Return(EmitCall(Reg(0), kPhis, merged));
+  EndBlock();
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, RegressionPhisNeedTooManyRegisters) {
+  const size_t kNumRegs = 3;
+  const size_t kParams = kNumRegs + 1;
+  // Override number of registers.
+  SetNumRegs(kNumRegs, kNumRegs);
+
+  StartBlock();
+  auto constant = DefineConstant();
+  VReg parameters[kParams];
+  for (size_t i = 0; i < arraysize(parameters); ++i) {
+    parameters[i] = DefineConstant();
+  }
+  EndBlock();
+
+  PhiInstruction* phis[kParams];
+  {
+    StartLoop(2);
+
+    // Loop header.
+    StartBlock();
+
+    for (size_t i = 0; i < arraysize(parameters); ++i) {
+      phis[i] = Phi(parameters[i]);
+    }
+
+    // Perform some computations.
+    // something like phi[i] += const
+    for (size_t i = 0; i < arraysize(parameters); ++i) {
+      auto result = EmitOI(Same(), Reg(phis[i]), Use(constant));
+      Extend(phis[i], result);
+    }
+
+    EndBlock(Branch(Reg(DefineConstant()), 1, 2));
+
+    // Jump back to loop header.
+    StartBlock();
+    EndBlock(Jump(-1));
+
+    EndLoop();
+  }
+
+  StartBlock();
+  Return(DefineConstant());
+  EndBlock();
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, SpillPhi) {
+  StartBlock();
+  EndBlock(Branch(Imm(), 1, 2));
+
+  StartBlock();
+  auto left = Define(Reg(0));
+  EndBlock(Jump(2));
+
+  StartBlock();
+  auto right = Define(Reg(0));
+  EndBlock();
+
+  StartBlock();
+  auto phi = Phi(left, right);
+  EmitCall(Slot(-1));
+  Return(Reg(phi));
+  EndBlock();
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, MoveLotsOfConstants) {
+  StartBlock();
+  VReg constants[kDefaultNRegs];
+  for (size_t i = 0; i < arraysize(constants); ++i) {
+    constants[i] = DefineConstant();
+  }
+  TestOperand call_ops[kDefaultNRegs * 2];
+  for (int i = 0; i < kDefaultNRegs; ++i) {
+    call_ops[i] = Reg(constants[i], i);
+  }
+  for (int i = 0; i < kDefaultNRegs; ++i) {
+    call_ops[i + kDefaultNRegs] = Slot(constants[i], i);
+  }
+  EmitCall(Slot(-1), arraysize(call_ops), call_ops);
+  EndBlock(Last());
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, SplitBeforeInstruction) {
+  const int kNumRegs = 6;
+  SetNumRegs(kNumRegs, kNumRegs);
+
+  StartBlock();
+
+  // Stack parameters/spilled values.
+  auto p_0 = Define(Slot(-1));
+  auto p_1 = Define(Slot(-2));
+
+  // Fill registers.
+  VReg values[kNumRegs];
+  for (size_t i = 0; i < arraysize(values); ++i) {
+    values[i] = Define(Reg(static_cast<int>(i)));
+  }
+
+  // values[0] will be split in the second half of this instruction.
+  // Models Intel mod instructions.
+  EmitOI(Reg(0), Reg(p_0, 1), UniqueReg(p_1));
+  EmitI(Reg(values[0], 0));
+  EndBlock(Last());
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, NestedDiamondPhiMerge) {
+  // Outer diamond.
+  StartBlock();
+  EndBlock(Branch(Imm(), 1, 5));
+
+  // Diamond 1
+  StartBlock();
+  EndBlock(Branch(Imm(), 1, 2));
+
+  StartBlock();
+  auto ll = Define(Reg());
+  EndBlock(Jump(2));
+
+  StartBlock();
+  auto lr = Define(Reg());
+  EndBlock();
+
+  StartBlock();
+  auto l_phi = Phi(ll, lr);
+  EndBlock(Jump(5));
+
+  // Diamond 2
+  StartBlock();
+  EndBlock(Branch(Imm(), 1, 2));
+
+  StartBlock();
+  auto rl = Define(Reg());
+  EndBlock(Jump(2));
+
+  StartBlock();
+  auto rr = Define(Reg());
+  EndBlock();
+
+  StartBlock();
+  auto r_phi = Phi(rl, rr);
+  EndBlock();
+
+  // Outer diamond merge.
+  StartBlock();
+  auto phi = Phi(l_phi, r_phi);
+  Return(Reg(phi));
+  EndBlock();
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, NestedDiamondPhiMergeDifferent) {
+  // Outer diamond.
+  StartBlock();
+  EndBlock(Branch(Imm(), 1, 5));
+
+  // Diamond 1
+  StartBlock();
+  EndBlock(Branch(Imm(), 1, 2));
+
+  StartBlock();
+  auto ll = Define(Reg(0));
+  EndBlock(Jump(2));
+
+  StartBlock();
+  auto lr = Define(Reg(1));
+  EndBlock();
+
+  StartBlock();
+  auto l_phi = Phi(ll, lr);
+  EndBlock(Jump(5));
+
+  // Diamond 2
+  StartBlock();
+  EndBlock(Branch(Imm(), 1, 2));
+
+  StartBlock();
+  auto rl = Define(Reg(2));
+  EndBlock(Jump(2));
+
+  StartBlock();
+  auto rr = Define(Reg(3));
+  EndBlock();
+
+  StartBlock();
+  auto r_phi = Phi(rl, rr);
+  EndBlock();
+
+  // Outer diamond merge.
+  StartBlock();
+  auto phi = Phi(l_phi, r_phi);
+  Return(Reg(phi));
+  EndBlock();
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, RegressionSplitBeforeAndMove) {
+  StartBlock();
+
+  // Fill registers.
+  VReg values[kDefaultNRegs];
+  for (size_t i = 0; i < arraysize(values); ++i) {
+    if (i == 0 || i == 1) continue;  // Leave a hole for c_1 to take.
+    values[i] = Define(Reg(static_cast<int>(i)));
+  }
+
+  auto c_0 = DefineConstant();
+  auto c_1 = DefineConstant();
+
+  EmitOI(Reg(1), Reg(c_0, 0), UniqueReg(c_1));
+
+  // Use previous values to force c_1 to split before the previous instruction.
+  for (size_t i = 0; i < arraysize(values); ++i) {
+    if (i == 0 || i == 1) continue;
+    EmitI(Reg(values[i], static_cast<int>(i)));
+  }
+
+  EndBlock(Last());
+
+  Allocate();
+}
+
+
+TEST_F(RegisterAllocatorTest, RegressionSpillTwice) {
+  StartBlock();
+  auto p_0 = Parameter(Reg(1));
+  EmitCall(Slot(-2), Unique(p_0), Reg(p_0, 1));
+  EndBlock(Last());
+
+  Allocate();
+}
+
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/select-lowering-unittest.cc b/test/unittests/compiler/select-lowering-unittest.cc
new file mode 100644
index 0000000..51efc83
--- /dev/null
+++ b/test/unittests/compiler/select-lowering-unittest.cc
@@ -0,0 +1,72 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/select-lowering.h"
+#include "test/unittests/compiler/graph-unittest.h"
+#include "test/unittests/compiler/node-test-utils.h"
+#include "testing/gmock-support.h"
+
+using testing::AllOf;
+using testing::Capture;
+using testing::CaptureEq;
+using testing::Not;
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class SelectLoweringTest : public GraphTest {
+ public:
+  SelectLoweringTest() : GraphTest(5), lowering_(graph(), common()) {}
+
+ protected:
+  Reduction Reduce(Node* node) { return lowering_.Reduce(node); }
+
+ private:
+  SelectLowering lowering_;
+};
+
+
+TEST_F(SelectLoweringTest, SelectWithSameConditions) {
+  Node* const p0 = Parameter(0);
+  Node* const p1 = Parameter(1);
+  Node* const p2 = Parameter(2);
+  Node* const p3 = Parameter(3);
+  Node* const p4 = Parameter(4);
+  Node* const s0 = graph()->NewNode(common()->Select(kMachInt32), p0, p1, p2);
+
+  Capture<Node*> branch;
+  Capture<Node*> merge;
+  {
+    Reduction const r = Reduce(s0);
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(
+        r.replacement(),
+        IsPhi(
+            kMachInt32, p1, p2,
+            AllOf(CaptureEq(&merge),
+                  IsMerge(IsIfTrue(CaptureEq(&branch)),
+                          IsIfFalse(AllOf(CaptureEq(&branch),
+                                          IsBranch(p0, graph()->start())))))));
+  }
+  {
+    Reduction const r =
+        Reduce(graph()->NewNode(common()->Select(kMachInt32), p0, p3, p4));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(), IsPhi(kMachInt32, p3, p4, CaptureEq(&merge)));
+  }
+  {
+    // We must not reuse the diamond if it is reachable from either else/then
+    // values of the Select, because the resulting graph can not be scheduled.
+    Reduction const r =
+        Reduce(graph()->NewNode(common()->Select(kMachInt32), p0, s0, p0));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_THAT(r.replacement(),
+                IsPhi(kMachInt32, s0, p0, Not(CaptureEq(&merge))));
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/simplified-operator-reducer-unittest.cc b/test/unittests/compiler/simplified-operator-reducer-unittest.cc
new file mode 100644
index 0000000..e5f46c0
--- /dev/null
+++ b/test/unittests/compiler/simplified-operator-reducer-unittest.cc
@@ -0,0 +1,520 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/access-builder.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/node-properties-inl.h"
+#include "src/compiler/simplified-operator.h"
+#include "src/compiler/simplified-operator-reducer.h"
+#include "src/conversions.h"
+#include "src/types.h"
+#include "test/unittests/compiler/graph-unittest.h"
+#include "test/unittests/compiler/node-test-utils.h"
+#include "testing/gmock-support.h"
+
+using testing::BitEq;
+
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class SimplifiedOperatorReducerTest : public TypedGraphTest {
+ public:
+  explicit SimplifiedOperatorReducerTest(int num_parameters = 1)
+      : TypedGraphTest(num_parameters), simplified_(zone()) {}
+  ~SimplifiedOperatorReducerTest() OVERRIDE {}
+
+ protected:
+  Reduction Reduce(Node* node) {
+    MachineOperatorBuilder machine(zone());
+    JSOperatorBuilder javascript(zone());
+    JSGraph jsgraph(graph(), common(), &javascript, &machine);
+    SimplifiedOperatorReducer reducer(&jsgraph);
+    return reducer.Reduce(node);
+  }
+
+  SimplifiedOperatorBuilder* simplified() { return &simplified_; }
+
+ private:
+  SimplifiedOperatorBuilder simplified_;
+};
+
+
+template <typename T>
+class SimplifiedOperatorReducerTestWithParam
+    : public SimplifiedOperatorReducerTest,
+      public ::testing::WithParamInterface<T> {
+ public:
+  explicit SimplifiedOperatorReducerTestWithParam(int num_parameters = 1)
+      : SimplifiedOperatorReducerTest(num_parameters) {}
+  ~SimplifiedOperatorReducerTestWithParam() OVERRIDE {}
+};
+
+
+namespace {
+
+static const double kFloat64Values[] = {
+    -V8_INFINITY,  -6.52696e+290, -1.05768e+290, -5.34203e+268, -1.01997e+268,
+    -8.22758e+266, -1.58402e+261, -5.15246e+241, -5.92107e+226, -1.21477e+226,
+    -1.67913e+188, -1.6257e+184,  -2.60043e+170, -2.52941e+168, -3.06033e+116,
+    -4.56201e+52,  -3.56788e+50,  -9.9066e+38,   -3.07261e+31,  -2.1271e+09,
+    -1.91489e+09,  -1.73053e+09,  -9.30675e+08,  -26030,        -20453,
+    -15790,        -11699,        -111,          -97,           -78,
+    -63,           -58,           -1.53858e-06,  -2.98914e-12,  -1.14741e-39,
+    -8.20347e-57,  -1.48932e-59,  -3.17692e-66,  -8.93103e-81,  -3.91337e-83,
+    -6.0489e-92,   -8.83291e-113, -4.28266e-117, -1.92058e-178, -2.0567e-192,
+    -1.68167e-194, -1.51841e-214, -3.98738e-234, -7.31851e-242, -2.21875e-253,
+    -1.11612e-293, -0.0,          0.0,           2.22507e-308,  1.06526e-307,
+    4.16643e-227,  6.76624e-223,  2.0432e-197,   3.16254e-184,  1.37315e-173,
+    2.88603e-172,  1.54155e-99,   4.42923e-81,   1.40539e-73,   5.4462e-73,
+    1.24064e-58,   3.11167e-58,   2.75826e-39,   0.143815,      58,
+    67,            601,           7941,          11644,         13697,
+    25680,         29882,         1.32165e+08,   1.62439e+08,   4.16837e+08,
+    9.59097e+08,   1.32491e+09,   1.8728e+09,    1.0672e+17,    2.69606e+46,
+    1.98285e+79,   1.0098e+82,    7.93064e+88,   3.67444e+121,  9.36506e+123,
+    7.27954e+162,  3.05316e+168,  1.16171e+175,  1.64771e+189,  1.1622e+202,
+    2.00748e+239,  2.51778e+244,  3.90282e+306,  1.79769e+308,  V8_INFINITY};
+
+
+static const int32_t kInt32Values[] = {
+    -2147483647 - 1, -2104508227, -2103151830, -1435284490, -1378926425,
+    -1318814539,     -1289388009, -1287537572, -1279026536, -1241605942,
+    -1226046939,     -941837148,  -779818051,  -413830641,  -245798087,
+    -184657557,      -127145950,  -105483328,  -32325,      -26653,
+    -23858,          -23834,      -22363,      -19858,      -19044,
+    -18744,          -15528,      -5309,       -3372,       -2093,
+    -104,            -98,         -97,         -93,         -84,
+    -80,             -78,         -76,         -72,         -58,
+    -57,             -56,         -55,         -45,         -40,
+    -34,             -32,         -25,         -24,         -5,
+    -2,              0,           3,           10,          24,
+    34,              42,          46,          47,          48,
+    52,              56,          64,          65,          71,
+    76,              79,          81,          82,          97,
+    102,             103,         104,         106,         107,
+    109,             116,         122,         3653,        4485,
+    12405,           16504,       26262,       28704,       29755,
+    30554,           16476817,    605431957,   832401070,   873617242,
+    914205764,       1062628108,  1087581664,  1488498068,  1534668023,
+    1661587028,      1696896187,  1866841746,  2032089723,  2147483647};
+
+
+static const uint32_t kUint32Values[] = {
+    0x0,        0x5,        0x8,        0xc,        0xd,        0x26,
+    0x28,       0x29,       0x30,       0x34,       0x3e,       0x42,
+    0x50,       0x5b,       0x63,       0x71,       0x77,       0x7c,
+    0x83,       0x88,       0x96,       0x9c,       0xa3,       0xfa,
+    0x7a7,      0x165d,     0x234d,     0x3acb,     0x43a5,     0x4573,
+    0x5b4f,     0x5f14,     0x6996,     0x6c6e,     0x7289,     0x7b9a,
+    0x7bc9,     0x86bb,     0xa839,     0xaa41,     0xb03b,     0xc942,
+    0xce68,     0xcf4c,     0xd3ad,     0xdea3,     0xe90c,     0xed86,
+    0xfba5,     0x172dcc6,  0x114d8fc1, 0x182d6c9d, 0x1b1e3fad, 0x1db033bf,
+    0x1e1de755, 0x1f625c80, 0x28f6cf00, 0x2acb6a94, 0x2c20240e, 0x2f0fe54e,
+    0x31863a7c, 0x33325474, 0x3532fae3, 0x3bab82ea, 0x4c4b83a2, 0x4cd93d1e,
+    0x4f7331d4, 0x5491b09b, 0x57cc6ff9, 0x60d3b4dc, 0x653f5904, 0x690ae256,
+    0x69fe3276, 0x6bebf0ba, 0x6e2c69a3, 0x73b84ff7, 0x7b3a1924, 0x7ed032d9,
+    0x84dd734b, 0x8552ea53, 0x8680754f, 0x8e9660eb, 0x94fe2b9c, 0x972d30cf,
+    0x9b98c482, 0xb158667e, 0xb432932c, 0xb5b70989, 0xb669971a, 0xb7c359d1,
+    0xbeb15c0d, 0xc171c53d, 0xc743dd38, 0xc8e2af50, 0xc98e2df0, 0xd9d1cdf9,
+    0xdcc91049, 0xe46f396d, 0xee991950, 0xef64e521, 0xf7aeefc9, 0xffffffff};
+
+}  // namespace
+
+
+// -----------------------------------------------------------------------------
+// Unary operators
+
+
+namespace {
+
+struct UnaryOperator {
+  const Operator* (SimplifiedOperatorBuilder::*constructor)();
+  const char* constructor_name;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const UnaryOperator& unop) {
+  return os << unop.constructor_name;
+}
+
+
+static const UnaryOperator kUnaryOperators[] = {
+    {&SimplifiedOperatorBuilder::AnyToBoolean, "AnyToBoolean"},
+    {&SimplifiedOperatorBuilder::BooleanNot, "BooleanNot"},
+    {&SimplifiedOperatorBuilder::ChangeBitToBool, "ChangeBitToBool"},
+    {&SimplifiedOperatorBuilder::ChangeBoolToBit, "ChangeBoolToBit"},
+    {&SimplifiedOperatorBuilder::ChangeFloat64ToTagged,
+     "ChangeFloat64ToTagged"},
+    {&SimplifiedOperatorBuilder::ChangeInt32ToTagged, "ChangeInt32ToTagged"},
+    {&SimplifiedOperatorBuilder::ChangeTaggedToFloat64,
+     "ChangeTaggedToFloat64"},
+    {&SimplifiedOperatorBuilder::ChangeTaggedToInt32, "ChangeTaggedToInt32"},
+    {&SimplifiedOperatorBuilder::ChangeTaggedToUint32, "ChangeTaggedToUint32"},
+    {&SimplifiedOperatorBuilder::ChangeUint32ToTagged, "ChangeUint32ToTagged"}};
+
+}  // namespace
+
+
+typedef SimplifiedOperatorReducerTestWithParam<UnaryOperator>
+    SimplifiedUnaryOperatorTest;
+
+
+TEST_P(SimplifiedUnaryOperatorTest, Parameter) {
+  const UnaryOperator& unop = GetParam();
+  Reduction reduction = Reduce(graph()->NewNode(
+      (simplified()->*unop.constructor)(), Parameter(Type::Any())));
+  EXPECT_FALSE(reduction.Changed());
+}
+
+
+INSTANTIATE_TEST_CASE_P(SimplifiedOperatorReducerTest,
+                        SimplifiedUnaryOperatorTest,
+                        ::testing::ValuesIn(kUnaryOperators));
+
+
+// -----------------------------------------------------------------------------
+// AnyToBoolean
+
+
+TEST_F(SimplifiedOperatorReducerTest, AnyToBooleanWithBoolean) {
+  Node* p = Parameter(Type::Boolean());
+  Reduction r = Reduce(graph()->NewNode(simplified()->AnyToBoolean(), p));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_EQ(p, r.replacement());
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, AnyToBooleanWithOrderedNumber) {
+  Node* p = Parameter(Type::OrderedNumber());
+  Reduction r = Reduce(graph()->NewNode(simplified()->AnyToBoolean(), p));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(),
+              IsBooleanNot(IsNumberEqual(p, IsNumberConstant(0))));
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, AnyToBooleanWithString) {
+  Node* p = Parameter(Type::String());
+  Reduction r = Reduce(graph()->NewNode(simplified()->AnyToBoolean(), p));
+  ASSERT_TRUE(r.Changed());
+  EXPECT_THAT(r.replacement(),
+              IsBooleanNot(
+                  IsNumberEqual(IsLoadField(AccessBuilder::ForStringLength(), p,
+                                            graph()->start(), graph()->start()),
+                                IsNumberConstant(0))));
+}
+
+
+// -----------------------------------------------------------------------------
+// BooleanNot
+
+
+TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithBooleanNot) {
+  Node* param0 = Parameter(0);
+  Reduction reduction = Reduce(
+      graph()->NewNode(simplified()->BooleanNot(),
+                       graph()->NewNode(simplified()->BooleanNot(), param0)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_EQ(param0, reduction.replacement());
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithFalseConstant) {
+  Reduction reduction0 =
+      Reduce(graph()->NewNode(simplified()->BooleanNot(), FalseConstant()));
+  ASSERT_TRUE(reduction0.Changed());
+  EXPECT_THAT(reduction0.replacement(), IsTrueConstant());
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, BooleanNotWithTrueConstant) {
+  Reduction reduction1 =
+      Reduce(graph()->NewNode(simplified()->BooleanNot(), TrueConstant()));
+  ASSERT_TRUE(reduction1.Changed());
+  EXPECT_THAT(reduction1.replacement(), IsFalseConstant());
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeBoolToBit
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeBitToBoolWithChangeBoolToBit) {
+  Node* param0 = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      simplified()->ChangeBitToBool(),
+      graph()->NewNode(simplified()->ChangeBoolToBit(), param0)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_EQ(param0, reduction.replacement());
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeBitToBoolWithZeroConstant) {
+  Reduction reduction = Reduce(
+      graph()->NewNode(simplified()->ChangeBitToBool(), Int32Constant(0)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(), IsFalseConstant());
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeBitToBoolWithOneConstant) {
+  Reduction reduction = Reduce(
+      graph()->NewNode(simplified()->ChangeBitToBool(), Int32Constant(1)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(), IsTrueConstant());
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeBoolToBit
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithFalseConstant) {
+  Reduction reduction = Reduce(
+      graph()->NewNode(simplified()->ChangeBoolToBit(), FalseConstant()));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithTrueConstant) {
+  Reduction reduction =
+      Reduce(graph()->NewNode(simplified()->ChangeBoolToBit(), TrueConstant()));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(), IsInt32Constant(1));
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeBoolToBitWithChangeBitToBool) {
+  Node* param0 = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      simplified()->ChangeBoolToBit(),
+      graph()->NewNode(simplified()->ChangeBitToBool(), param0)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_EQ(param0, reduction.replacement());
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeFloat64ToTagged
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeFloat64ToTaggedWithConstant) {
+  TRACED_FOREACH(double, n, kFloat64Values) {
+    Reduction reduction = Reduce(graph()->NewNode(
+        simplified()->ChangeFloat64ToTagged(), Float64Constant(n)));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(), IsNumberConstant(BitEq(n)));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeInt32ToTagged
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeInt32ToTaggedWithConstant) {
+  TRACED_FOREACH(int32_t, n, kInt32Values) {
+    Reduction reduction = Reduce(graph()->NewNode(
+        simplified()->ChangeInt32ToTagged(), Int32Constant(n)));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(), IsNumberConstant(BitEq(FastI2D(n))));
+  }
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeTaggedToFloat64
+
+
+TEST_F(SimplifiedOperatorReducerTest,
+       ChangeTaggedToFloat64WithChangeFloat64ToTagged) {
+  Node* param0 = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      simplified()->ChangeTaggedToFloat64(),
+      graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_EQ(param0, reduction.replacement());
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest,
+       ChangeTaggedToFloat64WithChangeInt32ToTagged) {
+  Node* param0 = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      simplified()->ChangeTaggedToFloat64(),
+      graph()->NewNode(simplified()->ChangeInt32ToTagged(), param0)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(), IsChangeInt32ToFloat64(param0));
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest,
+       ChangeTaggedToFloat64WithChangeUint32ToTagged) {
+  Node* param0 = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      simplified()->ChangeTaggedToFloat64(),
+      graph()->NewNode(simplified()->ChangeUint32ToTagged(), param0)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(), IsChangeUint32ToFloat64(param0));
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithConstant) {
+  TRACED_FOREACH(double, n, kFloat64Values) {
+    Reduction reduction = Reduce(graph()->NewNode(
+        simplified()->ChangeTaggedToFloat64(), NumberConstant(n)));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(), IsFloat64Constant(BitEq(n)));
+  }
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithNaNConstant1) {
+  Reduction reduction =
+      Reduce(graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
+                              NumberConstant(-base::OS::nan_value())));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(),
+              IsFloat64Constant(BitEq(-base::OS::nan_value())));
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToFloat64WithNaNConstant2) {
+  Reduction reduction =
+      Reduce(graph()->NewNode(simplified()->ChangeTaggedToFloat64(),
+                              NumberConstant(base::OS::nan_value())));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(),
+              IsFloat64Constant(BitEq(base::OS::nan_value())));
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeTaggedToInt32
+
+
+TEST_F(SimplifiedOperatorReducerTest,
+       ChangeTaggedToInt32WithChangeFloat64ToTagged) {
+  Node* param0 = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      simplified()->ChangeTaggedToInt32(),
+      graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(), IsChangeFloat64ToInt32(param0));
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest,
+       ChangeTaggedToInt32WithChangeInt32ToTagged) {
+  Node* param0 = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      simplified()->ChangeTaggedToInt32(),
+      graph()->NewNode(simplified()->ChangeInt32ToTagged(), param0)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_EQ(param0, reduction.replacement());
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithConstant) {
+  TRACED_FOREACH(double, n, kFloat64Values) {
+    Reduction reduction = Reduce(graph()->NewNode(
+        simplified()->ChangeTaggedToInt32(), NumberConstant(n)));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(), IsInt32Constant(DoubleToInt32(n)));
+  }
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithNaNConstant1) {
+  Reduction reduction =
+      Reduce(graph()->NewNode(simplified()->ChangeTaggedToInt32(),
+                              NumberConstant(-base::OS::nan_value())));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToInt32WithNaNConstant2) {
+  Reduction reduction =
+      Reduce(graph()->NewNode(simplified()->ChangeTaggedToInt32(),
+                              NumberConstant(base::OS::nan_value())));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeTaggedToUint32
+
+
+TEST_F(SimplifiedOperatorReducerTest,
+       ChangeTaggedToUint32WithChangeFloat64ToTagged) {
+  Node* param0 = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      simplified()->ChangeTaggedToUint32(),
+      graph()->NewNode(simplified()->ChangeFloat64ToTagged(), param0)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(), IsChangeFloat64ToUint32(param0));
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest,
+       ChangeTaggedToUint32WithChangeUint32ToTagged) {
+  Node* param0 = Parameter(0);
+  Reduction reduction = Reduce(graph()->NewNode(
+      simplified()->ChangeTaggedToUint32(),
+      graph()->NewNode(simplified()->ChangeUint32ToTagged(), param0)));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_EQ(param0, reduction.replacement());
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithConstant) {
+  TRACED_FOREACH(double, n, kFloat64Values) {
+    Reduction reduction = Reduce(graph()->NewNode(
+        simplified()->ChangeTaggedToUint32(), NumberConstant(n)));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(),
+                IsInt32Constant(bit_cast<int32_t>(DoubleToUint32(n))));
+  }
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithNaNConstant1) {
+  Reduction reduction =
+      Reduce(graph()->NewNode(simplified()->ChangeTaggedToUint32(),
+                              NumberConstant(-base::OS::nan_value())));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
+}
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeTaggedToUint32WithNaNConstant2) {
+  Reduction reduction =
+      Reduce(graph()->NewNode(simplified()->ChangeTaggedToUint32(),
+                              NumberConstant(base::OS::nan_value())));
+  ASSERT_TRUE(reduction.Changed());
+  EXPECT_THAT(reduction.replacement(), IsInt32Constant(0));
+}
+
+
+// -----------------------------------------------------------------------------
+// ChangeUint32ToTagged
+
+
+TEST_F(SimplifiedOperatorReducerTest, ChangeUint32ToTagged) {
+  TRACED_FOREACH(uint32_t, n, kUint32Values) {
+    Reduction reduction =
+        Reduce(graph()->NewNode(simplified()->ChangeUint32ToTagged(),
+                                Int32Constant(bit_cast<int32_t>(n))));
+    ASSERT_TRUE(reduction.Changed());
+    EXPECT_THAT(reduction.replacement(), IsNumberConstant(BitEq(FastUI2D(n))));
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/simplified-operator-unittest.cc b/test/unittests/compiler/simplified-operator-unittest.cc
new file mode 100644
index 0000000..bc537fd
--- /dev/null
+++ b/test/unittests/compiler/simplified-operator-unittest.cc
@@ -0,0 +1,288 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/opcodes.h"
+#include "src/compiler/operator.h"
+#include "src/compiler/operator-properties.h"
+#include "src/compiler/simplified-operator.h"
+#include "src/types-inl.h"
+#include "test/unittests/test-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// -----------------------------------------------------------------------------
+// Pure operators.
+
+
+namespace {
+
+struct PureOperator {
+  const Operator* (SimplifiedOperatorBuilder::*constructor)();
+  IrOpcode::Value opcode;
+  Operator::Properties properties;
+  int value_input_count;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
+  return os << IrOpcode::Mnemonic(pop.opcode);
+}
+
+
+const PureOperator kPureOperators[] = {
+#define PURE(Name, properties, input_count)              \
+  {                                                      \
+    &SimplifiedOperatorBuilder::Name, IrOpcode::k##Name, \
+        Operator::kPure | properties, input_count        \
+  }
+    PURE(AnyToBoolean, Operator::kNoProperties, 1),
+    PURE(BooleanNot, Operator::kNoProperties, 1),
+    PURE(BooleanToNumber, Operator::kNoProperties, 1),
+    PURE(NumberEqual, Operator::kCommutative, 2),
+    PURE(NumberLessThan, Operator::kNoProperties, 2),
+    PURE(NumberLessThanOrEqual, Operator::kNoProperties, 2),
+    PURE(NumberAdd, Operator::kCommutative, 2),
+    PURE(NumberSubtract, Operator::kNoProperties, 2),
+    PURE(NumberMultiply, Operator::kCommutative, 2),
+    PURE(NumberDivide, Operator::kNoProperties, 2),
+    PURE(NumberModulus, Operator::kNoProperties, 2),
+    PURE(NumberToInt32, Operator::kNoProperties, 1),
+    PURE(NumberToUint32, Operator::kNoProperties, 1),
+    PURE(StringEqual, Operator::kCommutative, 2),
+    PURE(StringLessThan, Operator::kNoProperties, 2),
+    PURE(StringLessThanOrEqual, Operator::kNoProperties, 2),
+    PURE(StringAdd, Operator::kNoProperties, 2),
+    PURE(ChangeTaggedToInt32, Operator::kNoProperties, 1),
+    PURE(ChangeTaggedToUint32, Operator::kNoProperties, 1),
+    PURE(ChangeTaggedToFloat64, Operator::kNoProperties, 1),
+    PURE(ChangeInt32ToTagged, Operator::kNoProperties, 1),
+    PURE(ChangeUint32ToTagged, Operator::kNoProperties, 1),
+    PURE(ChangeFloat64ToTagged, Operator::kNoProperties, 1),
+    PURE(ChangeBoolToBit, Operator::kNoProperties, 1),
+    PURE(ChangeBitToBool, Operator::kNoProperties, 1),
+    PURE(ObjectIsSmi, Operator::kNoProperties, 1),
+    PURE(ObjectIsNonNegativeSmi, Operator::kNoProperties, 1)
+#undef PURE
+};
+
+}  // namespace
+
+
+class SimplifiedPureOperatorTest
+    : public TestWithZone,
+      public ::testing::WithParamInterface<PureOperator> {};
+
+
+TEST_P(SimplifiedPureOperatorTest, InstancesAreGloballyShared) {
+  const PureOperator& pop = GetParam();
+  SimplifiedOperatorBuilder simplified1(zone());
+  SimplifiedOperatorBuilder simplified2(zone());
+  EXPECT_EQ((simplified1.*pop.constructor)(), (simplified2.*pop.constructor)());
+}
+
+
+TEST_P(SimplifiedPureOperatorTest, NumberOfInputsAndOutputs) {
+  SimplifiedOperatorBuilder simplified(zone());
+  const PureOperator& pop = GetParam();
+  const Operator* op = (simplified.*pop.constructor)();
+
+  EXPECT_EQ(pop.value_input_count, op->ValueInputCount());
+  EXPECT_EQ(0, op->EffectInputCount());
+  EXPECT_EQ(0, op->ControlInputCount());
+  EXPECT_EQ(pop.value_input_count, OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(1, op->ValueOutputCount());
+  EXPECT_EQ(0, op->EffectOutputCount());
+  EXPECT_EQ(0, op->ControlOutputCount());
+}
+
+
+TEST_P(SimplifiedPureOperatorTest, OpcodeIsCorrect) {
+  SimplifiedOperatorBuilder simplified(zone());
+  const PureOperator& pop = GetParam();
+  const Operator* op = (simplified.*pop.constructor)();
+  EXPECT_EQ(pop.opcode, op->opcode());
+}
+
+
+TEST_P(SimplifiedPureOperatorTest, Properties) {
+  SimplifiedOperatorBuilder simplified(zone());
+  const PureOperator& pop = GetParam();
+  const Operator* op = (simplified.*pop.constructor)();
+  EXPECT_EQ(pop.properties, op->properties() & pop.properties);
+}
+
+INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest, SimplifiedPureOperatorTest,
+                        ::testing::ValuesIn(kPureOperators));
+
+
+// -----------------------------------------------------------------------------
+// Buffer access operators.
+
+
+namespace {
+
+const ExternalArrayType kExternalArrayTypes[] = {
+    kExternalUint8Array,   kExternalInt8Array,   kExternalUint16Array,
+    kExternalInt16Array,   kExternalUint32Array, kExternalInt32Array,
+    kExternalFloat32Array, kExternalFloat64Array};
+
+}  // namespace
+
+
+class SimplifiedBufferAccessOperatorTest
+    : public TestWithZone,
+      public ::testing::WithParamInterface<ExternalArrayType> {};
+
+
+TEST_P(SimplifiedBufferAccessOperatorTest, InstancesAreGloballyShared) {
+  BufferAccess const access(GetParam());
+  SimplifiedOperatorBuilder simplified1(zone());
+  SimplifiedOperatorBuilder simplified2(zone());
+  EXPECT_EQ(simplified1.LoadBuffer(access), simplified2.LoadBuffer(access));
+  EXPECT_EQ(simplified1.StoreBuffer(access), simplified2.StoreBuffer(access));
+}
+
+
+TEST_P(SimplifiedBufferAccessOperatorTest, LoadBuffer) {
+  SimplifiedOperatorBuilder simplified(zone());
+  BufferAccess const access(GetParam());
+  const Operator* op = simplified.LoadBuffer(access);
+
+  EXPECT_EQ(IrOpcode::kLoadBuffer, op->opcode());
+  EXPECT_EQ(Operator::kNoThrow | Operator::kNoWrite, op->properties());
+  EXPECT_EQ(access, BufferAccessOf(op));
+
+  EXPECT_EQ(3, op->ValueInputCount());
+  EXPECT_EQ(1, op->EffectInputCount());
+  EXPECT_EQ(1, op->ControlInputCount());
+  EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(1, op->ValueOutputCount());
+  EXPECT_EQ(1, op->EffectOutputCount());
+  EXPECT_EQ(0, op->ControlOutputCount());
+}
+
+
+TEST_P(SimplifiedBufferAccessOperatorTest, StoreBuffer) {
+  SimplifiedOperatorBuilder simplified(zone());
+  BufferAccess const access(GetParam());
+  const Operator* op = simplified.StoreBuffer(access);
+
+  EXPECT_EQ(IrOpcode::kStoreBuffer, op->opcode());
+  EXPECT_EQ(Operator::kNoRead | Operator::kNoThrow, op->properties());
+  EXPECT_EQ(access, BufferAccessOf(op));
+
+  EXPECT_EQ(4, op->ValueInputCount());
+  EXPECT_EQ(1, op->EffectInputCount());
+  EXPECT_EQ(1, op->ControlInputCount());
+  EXPECT_EQ(6, OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(0, op->ValueOutputCount());
+  EXPECT_EQ(1, op->EffectOutputCount());
+  EXPECT_EQ(0, op->ControlOutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest,
+                        SimplifiedBufferAccessOperatorTest,
+                        ::testing::ValuesIn(kExternalArrayTypes));
+
+
+// -----------------------------------------------------------------------------
+// Element access operators.
+
+
+namespace {
+
+const ElementAccess kElementAccesses[] = {
+    {kTaggedBase, FixedArray::kHeaderSize, Type::Any(), kMachAnyTagged},
+    {kUntaggedBase, 0, Type::Any(), kMachInt8},
+    {kUntaggedBase, 0, Type::Any(), kMachInt16},
+    {kUntaggedBase, 0, Type::Any(), kMachInt32},
+    {kUntaggedBase, 0, Type::Any(), kMachUint8},
+    {kUntaggedBase, 0, Type::Any(), kMachUint16},
+    {kUntaggedBase, 0, Type::Any(), kMachUint32},
+    {kUntaggedBase, 0, Type::Signed32(), kMachInt8},
+    {kUntaggedBase, 0, Type::Unsigned32(), kMachUint8},
+    {kUntaggedBase, 0, Type::Signed32(), kMachInt16},
+    {kUntaggedBase, 0, Type::Unsigned32(), kMachUint16},
+    {kUntaggedBase, 0, Type::Signed32(), kMachInt32},
+    {kUntaggedBase, 0, Type::Unsigned32(), kMachUint32},
+    {kUntaggedBase, 0, Type::Number(), kRepFloat32},
+    {kUntaggedBase, 0, Type::Number(), kRepFloat64},
+    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
+     kMachInt8},
+    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
+     kMachUint8},
+    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
+     kMachInt16},
+    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
+     kMachUint16},
+    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
+     kMachInt32},
+    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
+     kMachUint32},
+    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
+     kRepFloat32},
+    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
+     kRepFloat64}};
+
+}  // namespace
+
+
+class SimplifiedElementAccessOperatorTest
+    : public TestWithZone,
+      public ::testing::WithParamInterface<ElementAccess> {};
+
+
+TEST_P(SimplifiedElementAccessOperatorTest, LoadElement) {
+  SimplifiedOperatorBuilder simplified(zone());
+  const ElementAccess& access = GetParam();
+  const Operator* op = simplified.LoadElement(access);
+
+  EXPECT_EQ(IrOpcode::kLoadElement, op->opcode());
+  EXPECT_EQ(Operator::kNoThrow | Operator::kNoWrite, op->properties());
+  EXPECT_EQ(access, ElementAccessOf(op));
+
+  EXPECT_EQ(2, op->ValueInputCount());
+  EXPECT_EQ(1, op->EffectInputCount());
+  EXPECT_EQ(1, op->ControlInputCount());
+  EXPECT_EQ(4, OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(1, op->ValueOutputCount());
+  EXPECT_EQ(1, op->EffectOutputCount());
+  EXPECT_EQ(0, op->ControlOutputCount());
+}
+
+
+TEST_P(SimplifiedElementAccessOperatorTest, StoreElement) {
+  SimplifiedOperatorBuilder simplified(zone());
+  const ElementAccess& access = GetParam();
+  const Operator* op = simplified.StoreElement(access);
+
+  EXPECT_EQ(IrOpcode::kStoreElement, op->opcode());
+  EXPECT_EQ(Operator::kNoRead | Operator::kNoThrow, op->properties());
+  EXPECT_EQ(access, ElementAccessOf(op));
+
+  EXPECT_EQ(3, op->ValueInputCount());
+  EXPECT_EQ(1, op->EffectInputCount());
+  EXPECT_EQ(1, op->ControlInputCount());
+  EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));
+
+  EXPECT_EQ(0, op->ValueOutputCount());
+  EXPECT_EQ(1, op->EffectOutputCount());
+  EXPECT_EQ(0, op->ControlOutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest,
+                        SimplifiedElementAccessOperatorTest,
+                        ::testing::ValuesIn(kElementAccesses));
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/value-numbering-reducer-unittest.cc b/test/unittests/compiler/value-numbering-reducer-unittest.cc
new file mode 100644
index 0000000..b6be0bf
--- /dev/null
+++ b/test/unittests/compiler/value-numbering-reducer-unittest.cc
@@ -0,0 +1,130 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <limits>
+
+#include "src/compiler/graph.h"
+#include "src/compiler/value-numbering-reducer.h"
+#include "test/unittests/test-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+struct TestOperator : public Operator {
+  TestOperator(Operator::Opcode opcode, Operator::Properties properties,
+               size_t value_in, size_t value_out)
+      : Operator(opcode, properties, "TestOp", value_in, 0, 0, value_out, 0,
+                 0) {}
+};
+
+
+static const TestOperator kOp0(0, Operator::kEliminatable, 0, 1);
+static const TestOperator kOp1(1, Operator::kEliminatable, 1, 1);
+
+
+class ValueNumberingReducerTest : public TestWithZone {
+ public:
+  ValueNumberingReducerTest() : graph_(zone()), reducer_(zone()) {}
+
+ protected:
+  Reduction Reduce(Node* node) { return reducer_.Reduce(node); }
+
+  Graph* graph() { return &graph_; }
+
+ private:
+  Graph graph_;
+  ValueNumberingReducer reducer_;
+};
+
+
+TEST_F(ValueNumberingReducerTest, AllInputsAreChecked) {
+  Node* na = graph()->NewNode(&kOp0);
+  Node* nb = graph()->NewNode(&kOp0);
+  Node* n1 = graph()->NewNode(&kOp0, na);
+  Node* n2 = graph()->NewNode(&kOp0, nb);
+  EXPECT_FALSE(Reduce(n1).Changed());
+  EXPECT_FALSE(Reduce(n2).Changed());
+}
+
+
+TEST_F(ValueNumberingReducerTest, DeadNodesAreNeverReturned) {
+  Node* n0 = graph()->NewNode(&kOp0);
+  Node* n1 = graph()->NewNode(&kOp1, n0);
+  EXPECT_FALSE(Reduce(n1).Changed());
+  n1->Kill();
+  EXPECT_FALSE(Reduce(graph()->NewNode(&kOp1, n0)).Changed());
+}
+
+
+TEST_F(ValueNumberingReducerTest, OnlyEliminatableNodesAreReduced) {
+  TestOperator op(0, Operator::kNoProperties, 0, 1);
+  Node* n0 = graph()->NewNode(&op);
+  Node* n1 = graph()->NewNode(&op);
+  EXPECT_FALSE(Reduce(n0).Changed());
+  EXPECT_FALSE(Reduce(n1).Changed());
+}
+
+
+TEST_F(ValueNumberingReducerTest, OperatorEqualityNotIdentity) {
+  static const size_t kMaxInputCount = 16;
+  Node* inputs[kMaxInputCount];
+  for (size_t i = 0; i < arraysize(inputs); ++i) {
+    Operator::Opcode opcode = static_cast<Operator::Opcode>(
+        std::numeric_limits<Operator::Opcode>::max() - i);
+    inputs[i] = graph()->NewNode(
+        new (zone()) TestOperator(opcode, Operator::kEliminatable, 0, 1));
+  }
+  TRACED_FORRANGE(size_t, input_count, 0, arraysize(inputs)) {
+    const TestOperator op1(static_cast<Operator::Opcode>(input_count),
+                           Operator::kEliminatable, input_count, 1);
+    Node* n1 = graph()->NewNode(&op1, static_cast<int>(input_count), inputs);
+    Reduction r1 = Reduce(n1);
+    EXPECT_FALSE(r1.Changed());
+
+    const TestOperator op2(static_cast<Operator::Opcode>(input_count),
+                           Operator::kEliminatable, input_count, 1);
+    Node* n2 = graph()->NewNode(&op2, static_cast<int>(input_count), inputs);
+    Reduction r2 = Reduce(n2);
+    EXPECT_TRUE(r2.Changed());
+    EXPECT_EQ(n1, r2.replacement());
+  }
+}
+
+
+TEST_F(ValueNumberingReducerTest, SubsequentReductionsYieldTheSameNode) {
+  static const size_t kMaxInputCount = 16;
+  Node* inputs[kMaxInputCount];
+  for (size_t i = 0; i < arraysize(inputs); ++i) {
+    Operator::Opcode opcode = static_cast<Operator::Opcode>(
+        std::numeric_limits<Operator::Opcode>::max() - i);
+    inputs[i] = graph()->NewNode(
+        new (zone()) TestOperator(opcode, Operator::kEliminatable, 0, 1));
+  }
+  TRACED_FORRANGE(size_t, input_count, 0, arraysize(inputs)) {
+    const TestOperator op1(1, Operator::kEliminatable, input_count, 1);
+    Node* n = graph()->NewNode(&op1, static_cast<int>(input_count), inputs);
+    Reduction r = Reduce(n);
+    EXPECT_FALSE(r.Changed());
+
+    r = Reduce(graph()->NewNode(&op1, static_cast<int>(input_count), inputs));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_EQ(n, r.replacement());
+
+    r = Reduce(graph()->NewNode(&op1, static_cast<int>(input_count), inputs));
+    ASSERT_TRUE(r.Changed());
+    EXPECT_EQ(n, r.replacement());
+  }
+}
+
+
+TEST_F(ValueNumberingReducerTest, WontReplaceNodeWithItself) {
+  Node* n = graph()->NewNode(&kOp0);
+  EXPECT_FALSE(Reduce(n).Changed());
+  EXPECT_FALSE(Reduce(n).Changed());
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc b/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc
new file mode 100644
index 0000000..9ef0fa5
--- /dev/null
+++ b/test/unittests/compiler/x64/instruction-selector-x64-unittest.cc
@@ -0,0 +1,1068 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "test/unittests/compiler/instruction-selector-unittest.h"
+
+#include "src/compiler/node-matchers.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+// -----------------------------------------------------------------------------
+// Conversions.
+
+
+TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) {
+  StreamBuilder m(this, kMachFloat32, kMachFloat64);
+  m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kSSECvtss2sd, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_F(InstructionSelectorTest, ChangeInt32ToInt64WithParameter) {
+  StreamBuilder m(this, kMachInt64, kMachInt32);
+  m.Return(m.ChangeInt32ToInt64(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Movsxlq, s[0]->arch_opcode());
+}
+
+
+TEST_F(InstructionSelectorTest, ChangeUint32ToFloat64WithParameter) {
+  StreamBuilder m(this, kMachFloat64, kMachUint32);
+  m.Return(m.ChangeUint32ToFloat64(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kSSEUint32ToFloat64, s[0]->arch_opcode());
+}
+
+
+TEST_F(InstructionSelectorTest, ChangeUint32ToUint64WithParameter) {
+  StreamBuilder m(this, kMachUint64, kMachUint32);
+  m.Return(m.ChangeUint32ToUint64(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Movl, s[0]->arch_opcode());
+}
+
+
+TEST_F(InstructionSelectorTest, TruncateFloat64ToFloat32WithParameter) {
+  StreamBuilder m(this, kMachFloat64, kMachFloat32);
+  m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kSSECvtsd2ss, s[0]->arch_opcode());
+  EXPECT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithParameter) {
+  StreamBuilder m(this, kMachInt32, kMachInt64);
+  m.Return(m.TruncateInt64ToInt32(m.Parameter(0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Movl, s[0]->arch_opcode());
+}
+
+
+// -----------------------------------------------------------------------------
+// Loads and stores
+
+namespace {
+
+struct MemoryAccess {
+  MachineType type;
+  ArchOpcode load_opcode;
+  ArchOpcode store_opcode;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) {
+  return os << memacc.type;
+}
+
+
+static const MemoryAccess kMemoryAccesses[] = {
+    {kMachInt8, kX64Movsxbl, kX64Movb},
+    {kMachUint8, kX64Movzxbl, kX64Movb},
+    {kMachInt16, kX64Movsxwl, kX64Movw},
+    {kMachUint16, kX64Movzxwl, kX64Movw},
+    {kMachInt32, kX64Movl, kX64Movl},
+    {kMachUint32, kX64Movl, kX64Movl},
+    {kMachInt64, kX64Movq, kX64Movq},
+    {kMachUint64, kX64Movq, kX64Movq},
+    {kMachFloat32, kX64Movss, kX64Movss},
+    {kMachFloat64, kX64Movsd, kX64Movsd}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<MemoryAccess>
+    InstructionSelectorMemoryAccessTest;
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32);
+  m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(1U, s[0]->OutputCount());
+}
+
+
+TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) {
+  const MemoryAccess memacc = GetParam();
+  StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type);
+  m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2));
+  m.Return(m.Int32Constant(0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode());
+  EXPECT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(0U, s[0]->OutputCount());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorMemoryAccessTest,
+                        ::testing::ValuesIn(kMemoryAccesses));
+
+// -----------------------------------------------------------------------------
+// ChangeUint32ToUint64.
+
+
+namespace {
+
+typedef Node* (RawMachineAssembler::*Constructor)(Node*, Node*);
+
+
+struct BinaryOperation {
+  Constructor constructor;
+  const char* constructor_name;
+};
+
+
+std::ostream& operator<<(std::ostream& os, const BinaryOperation& bop) {
+  return os << bop.constructor_name;
+}
+
+
+const BinaryOperation kWord32BinaryOperations[] = {
+    {&RawMachineAssembler::Word32And, "Word32And"},
+    {&RawMachineAssembler::Word32Or, "Word32Or"},
+    {&RawMachineAssembler::Word32Xor, "Word32Xor"},
+    {&RawMachineAssembler::Word32Shl, "Word32Shl"},
+    {&RawMachineAssembler::Word32Shr, "Word32Shr"},
+    {&RawMachineAssembler::Word32Sar, "Word32Sar"},
+    {&RawMachineAssembler::Word32Ror, "Word32Ror"},
+    {&RawMachineAssembler::Word32Equal, "Word32Equal"},
+    {&RawMachineAssembler::Int32Add, "Int32Add"},
+    {&RawMachineAssembler::Int32Sub, "Int32Sub"},
+    {&RawMachineAssembler::Int32Mul, "Int32Mul"},
+    {&RawMachineAssembler::Int32MulHigh, "Int32MulHigh"},
+    {&RawMachineAssembler::Int32Div, "Int32Div"},
+    {&RawMachineAssembler::Int32LessThan, "Int32LessThan"},
+    {&RawMachineAssembler::Int32LessThanOrEqual, "Int32LessThanOrEqual"},
+    {&RawMachineAssembler::Int32Mod, "Int32Mod"},
+    {&RawMachineAssembler::Uint32Div, "Uint32Div"},
+    {&RawMachineAssembler::Uint32LessThan, "Uint32LessThan"},
+    {&RawMachineAssembler::Uint32LessThanOrEqual, "Uint32LessThanOrEqual"},
+    {&RawMachineAssembler::Uint32Mod, "Uint32Mod"}};
+
+}  // namespace
+
+
+typedef InstructionSelectorTestWithParam<BinaryOperation>
+    InstructionSelectorChangeUint32ToUint64Test;
+
+
+TEST_P(InstructionSelectorChangeUint32ToUint64Test, ChangeUint32ToUint64) {
+  const BinaryOperation& bop = GetParam();
+  StreamBuilder m(this, kMachUint64, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  m.Return(m.ChangeUint32ToUint64((m.*bop.constructor)(p0, p1)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+}
+
+
+INSTANTIATE_TEST_CASE_P(InstructionSelectorTest,
+                        InstructionSelectorChangeUint32ToUint64Test,
+                        ::testing::ValuesIn(kWord32BinaryOperations));
+
+
+// -----------------------------------------------------------------------------
+// TruncateInt64ToInt32.
+
+
+TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Sar) {
+  StreamBuilder m(this, kMachInt32, kMachInt64);
+  Node* const p = m.Parameter(0);
+  Node* const t = m.TruncateInt64ToInt32(m.Word64Sar(p, m.Int64Constant(32)));
+  m.Return(t);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Shr, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(32, s.ToInt32(s[0]->InputAt(1)));
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_TRUE(s.IsSameAsFirst(s[0]->OutputAt(0)));
+  EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0)));
+}
+
+
+TEST_F(InstructionSelectorTest, TruncateInt64ToInt32WithWord64Shr) {
+  StreamBuilder m(this, kMachInt32, kMachInt64);
+  Node* const p = m.Parameter(0);
+  Node* const t = m.TruncateInt64ToInt32(m.Word64Shr(p, m.Int64Constant(32)));
+  m.Return(t);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Shr, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(32, s.ToInt32(s[0]->InputAt(1)));
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_TRUE(s.IsSameAsFirst(s[0]->OutputAt(0)));
+  EXPECT_EQ(s.ToVreg(t), s.ToVreg(s[0]->OutputAt(0)));
+}
+
+
+// -----------------------------------------------------------------------------
+// Addition.
+
+
+TEST_F(InstructionSelectorTest, Int32AddWithInt32ParametersLea) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const a0 = m.Int32Add(p0, p1);
+  // Additional uses of input to add chooses lea
+  Node* const a1 = m.Int32Div(p0, p1);
+  m.Return(m.Int32Div(a0, a1));
+  Stream s = m.Build();
+  ASSERT_EQ(3U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddConstantAsLeaSingle) {
+  StreamBuilder m(this, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c0 = m.Int32Constant(15);
+  // If one of the add's operands is only used once, use an "leal", even though
+  // an "addl" could be used. The "leal" has proven faster--out best guess is
+  // that it gives the register allocation more freedom and it doesn't set
+  // flags, reducing pressure in the CPU's pipeline. If we're lucky with
+  // register allocation, then code generation will select an "addl" later for
+  // the cases that have been measured to be faster.
+  Node* const v0 = m.Int32Add(p0, c0);
+  m.Return(v0);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddConstantAsAdd) {
+  StreamBuilder m(this, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c0 = m.Int32Constant(1);
+  // If there is only a single use of an add's input and the immediate constant
+  // for the add is 1, don't use an inc. It is much slower on modern Intel
+  // architectures.
+  m.Return(m.Int32Add(p0, c0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddConstantAsLeaDouble) {
+  StreamBuilder m(this, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c0 = m.Int32Constant(15);
+  // A second use of an add's input uses lea
+  Node* const a0 = m.Int32Add(p0, c0);
+  m.Return(m.Int32Div(a0, p0));
+  Stream s = m.Build();
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddCommutedConstantAsLeaSingle) {
+  StreamBuilder m(this, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c0 = m.Int32Constant(15);
+  // If one of the add's operands is only used once, use an "leal", even though
+  // an "addl" could be used. The "leal" has proven faster--out best guess is
+  // that it gives the register allocation more freedom and it doesn't set
+  // flags, reducing pressure in the CPU's pipeline. If we're lucky with
+  // register allocation, then code generation will select an "addl" later for
+  // the cases that have been measured to be faster.
+  m.Return(m.Int32Add(c0, p0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddCommutedConstantAsLeaDouble) {
+  StreamBuilder m(this, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c0 = m.Int32Constant(15);
+  // A second use of an add's input uses lea
+  Node* const a0 = m.Int32Add(c0, p0);
+  USE(a0);
+  m.Return(m.Int32Div(a0, p0));
+  Stream s = m.Build();
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddSimpleAsAdd) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  // If one of the add's operands is only used once, use an "leal", even though
+  // an "addl" could be used. The "leal" has proven faster--out best guess is
+  // that it gives the register allocation more freedom and it doesn't set
+  // flags, reducing pressure in the CPU's pipeline. If we're lucky with
+  // register allocation, then code generation will select an "addl" later for
+  // the cases that have been measured to be faster.
+  m.Return(m.Int32Add(p0, p1));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR1, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddSimpleAsLea) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  // If all of of the add's operands are used multiple times, use an "leal".
+  Node* const v1 = m.Int32Add(p0, p1);
+  m.Return(m.Int32Add(m.Int32Add(v1, p1), p0));
+  Stream s = m.Build();
+  ASSERT_EQ(3U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR1, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled2Mul) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
+  m.Return(m.Int32Add(p0, s0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddCommutedScaled2Mul) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
+  m.Return(m.Int32Add(s0, p0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled2Shl) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Word32Shl(p1, m.Int32Constant(1));
+  m.Return(m.Int32Add(p0, s0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddCommutedScaled2Shl) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Word32Shl(p1, m.Int32Constant(1));
+  m.Return(m.Int32Add(s0, p0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled4Mul) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(4));
+  m.Return(m.Int32Add(p0, s0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR4, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled4Shl) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Word32Shl(p1, m.Int32Constant(2));
+  m.Return(m.Int32Add(p0, s0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR4, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled8Mul) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(8));
+  m.Return(m.Int32Add(p0, s0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR8, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled8Shl) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Word32Shl(p1, m.Int32Constant(3));
+  m.Return(m.Int32Add(p0, s0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR8, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled2MulWithConstant) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
+  Node* const c0 = m.Int32Constant(15);
+  m.Return(m.Int32Add(c0, m.Int32Add(p0, s0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
+  ASSERT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled2MulWithConstantShuffle1) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
+  Node* const c0 = m.Int32Constant(15);
+  m.Return(m.Int32Add(p0, m.Int32Add(s0, c0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
+  ASSERT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled2MulWithConstantShuffle2) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
+  Node* const c0 = m.Int32Constant(15);
+  m.Return(m.Int32Add(s0, m.Int32Add(c0, p0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
+  ASSERT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled2MulWithConstantShuffle3) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
+  Node* const c0 = m.Int32Constant(15);
+  m.Return(m.Int32Add(m.Int32Add(s0, c0), p0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
+  ASSERT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled2MulWithConstantShuffle4) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
+  Node* const c0 = m.Int32Constant(15);
+  m.Return(m.Int32Add(m.Int32Add(c0, p0), s0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
+  ASSERT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled2MulWithConstantShuffle5) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
+  Node* const c0 = m.Int32Constant(15);
+  m.Return(m.Int32Add(m.Int32Add(p0, s0), c0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
+  ASSERT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled2ShlWithConstant) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Word32Shl(p1, m.Int32Constant(1));
+  Node* const c0 = m.Int32Constant(15);
+  m.Return(m.Int32Add(c0, m.Int32Add(p0, s0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2I, s[0]->addressing_mode());
+  ASSERT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled4MulWithConstant) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(4));
+  Node* const c0 = m.Int32Constant(15);
+  m.Return(m.Int32Add(c0, m.Int32Add(p0, s0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR4I, s[0]->addressing_mode());
+  ASSERT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled4ShlWithConstant) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Word32Shl(p1, m.Int32Constant(2));
+  Node* const c0 = m.Int32Constant(15);
+  m.Return(m.Int32Add(c0, m.Int32Add(p0, s0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR4I, s[0]->addressing_mode());
+  ASSERT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled8MulWithConstant) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(8));
+  Node* const c0 = m.Int32Constant(15);
+  m.Return(m.Int32Add(c0, m.Int32Add(p0, s0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR8I, s[0]->addressing_mode());
+  ASSERT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled8ShlWithConstant) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const s0 = m.Word32Shl(p1, m.Int32Constant(3));
+  Node* const c0 = m.Int32Constant(15);
+  m.Return(m.Int32Add(c0, m.Int32Add(p0, s0)));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR8I, s[0]->addressing_mode());
+  ASSERT_EQ(3U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(s[0]->InputAt(2)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32SubConstantAsSub) {
+  StreamBuilder m(this, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c0 = m.Int32Constant(-1);
+  // If there is only a single use of on of the sub's non-constant input, use a
+  // "subl" instruction.
+  m.Return(m.Int32Sub(p0, c0));
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32SubConstantAsLea) {
+  StreamBuilder m(this, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c0 = m.Int32Constant(-1);
+  // If there are multiple uses of on of the sub's non-constant input, use a
+  // "leal" instruction.
+  Node* const v0 = m.Int32Sub(p0, c0);
+  m.Return(m.Int32Div(p0, v0));
+  Stream s = m.Build();
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MRI, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+}
+
+
+TEST_F(InstructionSelectorTest, Int32AddScaled2Other) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const p2 = m.Parameter(2);
+  Node* const s0 = m.Int32Mul(p1, m.Int32Constant(2));
+  Node* const a0 = m.Int32Add(s0, p2);
+  Node* const a1 = m.Int32Add(p0, a0);
+  m.Return(a1);
+  Stream s = m.Build();
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p2), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_EQ(s.ToVreg(a0), s.ToVreg(s[0]->OutputAt(0)));
+  ASSERT_EQ(2U, s[1]->InputCount());
+  EXPECT_EQ(kX64Lea32, s[1]->arch_opcode());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[1]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(a0), s.ToVreg(s[1]->InputAt(1)));
+  EXPECT_EQ(s.ToVreg(a1), s.ToVreg(s[1]->OutputAt(0)));
+}
+
+
+// -----------------------------------------------------------------------------
+// Multiplication.
+
+
+TEST_F(InstructionSelectorTest, Int32MulWithInt32MulWithParameters) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const m0 = m.Int32Mul(p0, p1);
+  m.Return(m.Int32Mul(m0, p0));
+  Stream s = m.Build();
+  ASSERT_EQ(2U, s.size());
+  EXPECT_EQ(kX64Imul32, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+  ASSERT_EQ(1U, s[0]->OutputCount());
+  EXPECT_EQ(s.ToVreg(m0), s.ToVreg(s[0]->OutputAt(0)));
+  EXPECT_EQ(kX64Imul32, s[1]->arch_opcode());
+  ASSERT_EQ(2U, s[1]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[1]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(m0), s.ToVreg(s[1]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32MulHigh) {
+  StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const n = m.Int32MulHigh(p0, p1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64ImulHigh32, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), rax));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1)));
+  ASSERT_LE(1U, s[0]->OutputCount());
+  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), rdx));
+}
+
+
+TEST_F(InstructionSelectorTest, Uint32MulHigh) {
+  StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
+  Node* const p0 = m.Parameter(0);
+  Node* const p1 = m.Parameter(1);
+  Node* const n = m.Uint32MulHigh(p0, p1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64UmulHigh32, s[0]->arch_opcode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), rax));
+  EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
+  EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1)));
+  ASSERT_LE(1U, s[0]->OutputCount());
+  EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), rdx));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32Mul2BecomesLea) {
+  StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c1 = m.Int32Constant(2);
+  Node* const n = m.Int32Mul(p0, c1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR1, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32Mul3BecomesLea) {
+  StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c1 = m.Int32Constant(3);
+  Node* const n = m.Int32Mul(p0, c1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR2, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32Mul4BecomesLea) {
+  StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c1 = m.Int32Constant(4);
+  Node* const n = m.Int32Mul(p0, c1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_M4, s[0]->addressing_mode());
+  ASSERT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32Mul5BecomesLea) {
+  StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c1 = m.Int32Constant(5);
+  Node* const n = m.Int32Mul(p0, c1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR4, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32Mul8BecomesLea) {
+  StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c1 = m.Int32Constant(8);
+  Node* const n = m.Int32Mul(p0, c1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_M8, s[0]->addressing_mode());
+  ASSERT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32Mul9BecomesLea) {
+  StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c1 = m.Int32Constant(9);
+  Node* const n = m.Int32Mul(p0, c1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR8, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+// -----------------------------------------------------------------------------
+// Word32Shl.
+
+
+TEST_F(InstructionSelectorTest, Int32Shl1BecomesLea) {
+  StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c1 = m.Int32Constant(1);
+  Node* const n = m.Word32Shl(p0, c1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_MR1, s[0]->addressing_mode());
+  ASSERT_EQ(2U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(1)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32Shl2BecomesLea) {
+  StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c1 = m.Int32Constant(2);
+  Node* const n = m.Word32Shl(p0, c1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_M4, s[0]->addressing_mode());
+  ASSERT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+}
+
+
+TEST_F(InstructionSelectorTest, Int32Shl4BecomesLea) {
+  StreamBuilder m(this, kMachUint32, kMachUint32, kMachUint32);
+  Node* const p0 = m.Parameter(0);
+  Node* const c1 = m.Int32Constant(3);
+  Node* const n = m.Word32Shl(p0, c1);
+  m.Return(n);
+  Stream s = m.Build();
+  ASSERT_EQ(1U, s.size());
+  EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
+  EXPECT_EQ(kMode_M8, s[0]->addressing_mode());
+  ASSERT_EQ(1U, s[0]->InputCount());
+  EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+}
+
+
+// -----------------------------------------------------------------------------
+// Word64Shl.
+
+
+TEST_F(InstructionSelectorTest, Word64ShlWithChangeInt32ToInt64) {
+  TRACED_FORRANGE(int64_t, x, 32, 63) {
+    StreamBuilder m(this, kMachInt64, kMachInt32);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Word64Shl(m.ChangeInt32ToInt64(p0), m.Int64Constant(x));
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kX64Shl, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(x, s.ToInt32(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Word64ShlWithChangeUint32ToUint64) {
+  TRACED_FORRANGE(int64_t, x, 32, 63) {
+    StreamBuilder m(this, kMachInt64, kMachUint32);
+    Node* const p0 = m.Parameter(0);
+    Node* const n = m.Word64Shl(m.ChangeUint32ToUint64(p0), m.Int64Constant(x));
+    m.Return(n);
+    Stream s = m.Build();
+    ASSERT_EQ(1U, s.size());
+    EXPECT_EQ(kX64Shl, s[0]->arch_opcode());
+    ASSERT_EQ(2U, s[0]->InputCount());
+    EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+    EXPECT_EQ(x, s.ToInt32(s[0]->InputAt(1)));
+    ASSERT_EQ(1U, s[0]->OutputCount());
+    EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output()));
+    EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+  }
+}
+
+
+TEST_F(InstructionSelectorTest, Float64BinopArithmetic) {
+  {
+    StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64);
+    Node* add = m.Float64Add(m.Parameter(0), m.Parameter(1));
+    Node* mul = m.Float64Mul(add, m.Parameter(1));
+    Node* sub = m.Float64Sub(mul, add);
+    Node* ret = m.Float64Div(mul, sub);
+    m.Return(ret);
+    Stream s = m.Build(AVX);
+    ASSERT_EQ(4U, s.size());
+    EXPECT_EQ(kAVXFloat64Add, s[0]->arch_opcode());
+    EXPECT_EQ(kAVXFloat64Mul, s[1]->arch_opcode());
+    EXPECT_EQ(kAVXFloat64Sub, s[2]->arch_opcode());
+    EXPECT_EQ(kAVXFloat64Div, s[3]->arch_opcode());
+  }
+  {
+    StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64);
+    Node* add = m.Float64Add(m.Parameter(0), m.Parameter(1));
+    Node* mul = m.Float64Mul(add, m.Parameter(1));
+    Node* sub = m.Float64Sub(mul, add);
+    Node* ret = m.Float64Div(mul, sub);
+    m.Return(ret);
+    Stream s = m.Build();
+    ASSERT_EQ(4U, s.size());
+    EXPECT_EQ(kSSEFloat64Add, s[0]->arch_opcode());
+    EXPECT_EQ(kSSEFloat64Mul, s[1]->arch_opcode());
+    EXPECT_EQ(kSSEFloat64Sub, s[2]->arch_opcode());
+    EXPECT_EQ(kSSEFloat64Div, s[3]->arch_opcode());
+  }
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/compiler/zone-pool-unittest.cc b/test/unittests/compiler/zone-pool-unittest.cc
new file mode 100644
index 0000000..e23557a
--- /dev/null
+++ b/test/unittests/compiler/zone-pool-unittest.cc
@@ -0,0 +1,162 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/base/utils/random-number-generator.h"
+#include "src/compiler/zone-pool.h"
+#include "test/unittests/test-utils.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+class ZonePoolTest : public TestWithIsolate {
+ public:
+  ZonePoolTest() : zone_pool_(isolate()) {}
+
+ protected:
+  ZonePool* zone_pool() { return &zone_pool_; }
+
+  void ExpectForPool(size_t current, size_t max, size_t total) {
+    ASSERT_EQ(current, zone_pool()->GetCurrentAllocatedBytes());
+    ASSERT_EQ(max, zone_pool()->GetMaxAllocatedBytes());
+    ASSERT_EQ(total, zone_pool()->GetTotalAllocatedBytes());
+  }
+
+  void Expect(ZonePool::StatsScope* stats, size_t current, size_t max,
+              size_t total) {
+    ASSERT_EQ(current, stats->GetCurrentAllocatedBytes());
+    ASSERT_EQ(max, stats->GetMaxAllocatedBytes());
+    ASSERT_EQ(total, stats->GetTotalAllocatedBytes());
+  }
+
+  size_t Allocate(Zone* zone) {
+    size_t bytes = rng.NextInt(25) + 7;
+    int size_before = zone->allocation_size();
+    zone->New(static_cast<int>(bytes));
+    return static_cast<size_t>(zone->allocation_size() - size_before);
+  }
+
+ private:
+  ZonePool zone_pool_;
+  base::RandomNumberGenerator rng;
+};
+
+
+TEST_F(ZonePoolTest, Empty) {
+  ExpectForPool(0, 0, 0);
+  {
+    ZonePool::StatsScope stats(zone_pool());
+    Expect(&stats, 0, 0, 0);
+  }
+  ExpectForPool(0, 0, 0);
+  {
+    ZonePool::Scope scope(zone_pool());
+    scope.zone();
+  }
+  ExpectForPool(0, 0, 0);
+}
+
+
+TEST_F(ZonePoolTest, MultipleZonesWithDeletion) {
+  static const size_t kArraySize = 10;
+
+  ZonePool::Scope* scopes[kArraySize];
+
+  // Initialize.
+  size_t before_stats = 0;
+  for (size_t i = 0; i < kArraySize; ++i) {
+    scopes[i] = new ZonePool::Scope(zone_pool());
+    before_stats += Allocate(scopes[i]->zone());  // Add some stuff.
+  }
+
+  ExpectForPool(before_stats, before_stats, before_stats);
+
+  ZonePool::StatsScope stats(zone_pool());
+
+  size_t before_deletion = 0;
+  for (size_t i = 0; i < kArraySize; ++i) {
+    before_deletion += Allocate(scopes[i]->zone());  // Add some stuff.
+  }
+
+  Expect(&stats, before_deletion, before_deletion, before_deletion);
+  ExpectForPool(before_stats + before_deletion, before_stats + before_deletion,
+                before_stats + before_deletion);
+
+  // Delete the scopes and create new ones.
+  for (size_t i = 0; i < kArraySize; ++i) {
+    delete scopes[i];
+    scopes[i] = new ZonePool::Scope(zone_pool());
+  }
+
+  Expect(&stats, 0, before_deletion, before_deletion);
+  ExpectForPool(0, before_stats + before_deletion,
+                before_stats + before_deletion);
+
+  size_t after_deletion = 0;
+  for (size_t i = 0; i < kArraySize; ++i) {
+    after_deletion += Allocate(scopes[i]->zone());  // Add some stuff.
+  }
+
+  Expect(&stats, after_deletion, std::max(after_deletion, before_deletion),
+         before_deletion + after_deletion);
+  ExpectForPool(after_deletion,
+                std::max(after_deletion, before_stats + before_deletion),
+                before_stats + before_deletion + after_deletion);
+
+  // Cleanup.
+  for (size_t i = 0; i < kArraySize; ++i) {
+    delete scopes[i];
+  }
+
+  Expect(&stats, 0, std::max(after_deletion, before_deletion),
+         before_deletion + after_deletion);
+  ExpectForPool(0, std::max(after_deletion, before_stats + before_deletion),
+                before_stats + before_deletion + after_deletion);
+}
+
+
+TEST_F(ZonePoolTest, SimpleAllocationLoop) {
+  int runs = 20;
+  size_t total_allocated = 0;
+  size_t max_loop_allocation = 0;
+  ZonePool::StatsScope outer_stats(zone_pool());
+  {
+    ZonePool::Scope outer_scope(zone_pool());
+    size_t outer_allocated = 0;
+    for (int i = 0; i < runs; ++i) {
+      {
+        size_t bytes = Allocate(outer_scope.zone());
+        outer_allocated += bytes;
+        total_allocated += bytes;
+      }
+      ZonePool::StatsScope inner_stats(zone_pool());
+      size_t allocated = 0;
+      {
+        ZonePool::Scope inner_scope(zone_pool());
+        for (int j = 0; j < 20; ++j) {
+          size_t bytes = Allocate(inner_scope.zone());
+          allocated += bytes;
+          total_allocated += bytes;
+          max_loop_allocation =
+              std::max(max_loop_allocation, outer_allocated + allocated);
+          Expect(&inner_stats, allocated, allocated, allocated);
+          Expect(&outer_stats, outer_allocated + allocated, max_loop_allocation,
+                 total_allocated);
+          ExpectForPool(outer_allocated + allocated, max_loop_allocation,
+                        total_allocated);
+        }
+      }
+      Expect(&inner_stats, 0, allocated, allocated);
+      Expect(&outer_stats, outer_allocated, max_loop_allocation,
+             total_allocated);
+      ExpectForPool(outer_allocated, max_loop_allocation, total_allocated);
+    }
+  }
+  Expect(&outer_stats, 0, max_loop_allocation, total_allocated);
+  ExpectForPool(0, max_loop_allocation, total_allocated);
+}
+
+}  // namespace compiler
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/heap/gc-idle-time-handler-unittest.cc b/test/unittests/heap/gc-idle-time-handler-unittest.cc
new file mode 100644
index 0000000..2076e60
--- /dev/null
+++ b/test/unittests/heap/gc-idle-time-handler-unittest.cc
@@ -0,0 +1,444 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <limits>
+
+#include "src/heap/gc-idle-time-handler.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace internal {
+
+namespace {
+
+class GCIdleTimeHandlerTest : public ::testing::Test {
+ public:
+  GCIdleTimeHandlerTest() {}
+  virtual ~GCIdleTimeHandlerTest() {}
+
+  GCIdleTimeHandler* handler() { return &handler_; }
+
+  GCIdleTimeHandler::HeapState DefaultHeapState() {
+    GCIdleTimeHandler::HeapState result;
+    result.contexts_disposed = 0;
+    result.contexts_disposal_rate = GCIdleTimeHandler::kHighContextDisposalRate;
+    result.size_of_objects = kSizeOfObjects;
+    result.incremental_marking_stopped = false;
+    result.can_start_incremental_marking = true;
+    result.sweeping_in_progress = false;
+    result.mark_compact_speed_in_bytes_per_ms = kMarkCompactSpeed;
+    result.incremental_marking_speed_in_bytes_per_ms = kMarkingSpeed;
+    result.scavenge_speed_in_bytes_per_ms = kScavengeSpeed;
+    result.used_new_space_size = 0;
+    result.new_space_capacity = kNewSpaceCapacity;
+    result.new_space_allocation_throughput_in_bytes_per_ms =
+        kNewSpaceAllocationThroughput;
+    return result;
+  }
+
+  static const size_t kSizeOfObjects = 100 * MB;
+  static const size_t kMarkCompactSpeed = 200 * KB;
+  static const size_t kMarkingSpeed = 200 * KB;
+  static const size_t kScavengeSpeed = 100 * KB;
+  static const size_t kNewSpaceCapacity = 1 * MB;
+  static const size_t kNewSpaceAllocationThroughput = 10 * KB;
+
+ private:
+  GCIdleTimeHandler handler_;
+};
+
+}  // namespace
+
+
+TEST(GCIdleTimeHandler, EstimateMarkingStepSizeInitial) {
+  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(1, 0);
+  EXPECT_EQ(
+      static_cast<size_t>(GCIdleTimeHandler::kInitialConservativeMarkingSpeed *
+                          GCIdleTimeHandler::kConservativeTimeRatio),
+      step_size);
+}
+
+
+TEST(GCIdleTimeHandler, EstimateMarkingStepSizeNonZero) {
+  size_t marking_speed_in_bytes_per_millisecond = 100;
+  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
+      1, marking_speed_in_bytes_per_millisecond);
+  EXPECT_EQ(static_cast<size_t>(marking_speed_in_bytes_per_millisecond *
+                                GCIdleTimeHandler::kConservativeTimeRatio),
+            step_size);
+}
+
+
+TEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow1) {
+  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
+      10, std::numeric_limits<size_t>::max());
+  EXPECT_EQ(static_cast<size_t>(GCIdleTimeHandler::kMaximumMarkingStepSize),
+            step_size);
+}
+
+
+TEST(GCIdleTimeHandler, EstimateMarkingStepSizeOverflow2) {
+  size_t step_size = GCIdleTimeHandler::EstimateMarkingStepSize(
+      std::numeric_limits<size_t>::max(), 10);
+  EXPECT_EQ(static_cast<size_t>(GCIdleTimeHandler::kMaximumMarkingStepSize),
+            step_size);
+}
+
+
+TEST(GCIdleTimeHandler, EstimateMarkCompactTimeInitial) {
+  size_t size = 100 * MB;
+  size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, 0);
+  EXPECT_EQ(size / GCIdleTimeHandler::kInitialConservativeMarkCompactSpeed,
+            time);
+}
+
+
+TEST(GCIdleTimeHandler, EstimateMarkCompactTimeNonZero) {
+  size_t size = 100 * MB;
+  size_t speed = 1 * MB;
+  size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed);
+  EXPECT_EQ(size / speed, time);
+}
+
+
+TEST(GCIdleTimeHandler, EstimateMarkCompactTimeMax) {
+  size_t size = std::numeric_limits<size_t>::max();
+  size_t speed = 1;
+  size_t time = GCIdleTimeHandler::EstimateMarkCompactTime(size, speed);
+  EXPECT_EQ(GCIdleTimeHandler::kMaxMarkCompactTimeInMs, time);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, DoScavengeEmptyNewSpace) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  int idle_time_in_ms = 16;
+  EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge(
+      idle_time_in_ms, heap_state.new_space_capacity,
+      heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
+      heap_state.new_space_allocation_throughput_in_bytes_per_ms));
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, DoScavengeFullNewSpace) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.used_new_space_size = kNewSpaceCapacity;
+  int idle_time_in_ms = 16;
+  EXPECT_TRUE(GCIdleTimeHandler::ShouldDoScavenge(
+      idle_time_in_ms, heap_state.new_space_capacity,
+      heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
+      heap_state.new_space_allocation_throughput_in_bytes_per_ms));
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, DoScavengeUnknownScavengeSpeed) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.used_new_space_size = kNewSpaceCapacity;
+  heap_state.scavenge_speed_in_bytes_per_ms = 0;
+  int idle_time_in_ms = 16;
+  EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge(
+      idle_time_in_ms, heap_state.new_space_capacity,
+      heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
+      heap_state.new_space_allocation_throughput_in_bytes_per_ms));
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, DoScavengeLowScavengeSpeed) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.used_new_space_size = kNewSpaceCapacity;
+  heap_state.scavenge_speed_in_bytes_per_ms = 1 * KB;
+  int idle_time_in_ms = 16;
+  EXPECT_FALSE(GCIdleTimeHandler::ShouldDoScavenge(
+      idle_time_in_ms, heap_state.new_space_capacity,
+      heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
+      heap_state.new_space_allocation_throughput_in_bytes_per_ms));
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, DoScavengeHighScavengeSpeed) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.used_new_space_size = kNewSpaceCapacity;
+  heap_state.scavenge_speed_in_bytes_per_ms = kNewSpaceCapacity;
+  int idle_time_in_ms = 16;
+  EXPECT_TRUE(GCIdleTimeHandler::ShouldDoScavenge(
+      idle_time_in_ms, heap_state.new_space_capacity,
+      heap_state.used_new_space_size, heap_state.scavenge_speed_in_bytes_per_ms,
+      heap_state.new_space_allocation_throughput_in_bytes_per_ms));
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, ShouldDoMarkCompact) {
+  size_t idle_time_in_ms = 16;
+  EXPECT_TRUE(GCIdleTimeHandler::ShouldDoMarkCompact(idle_time_in_ms, 0, 0));
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, DontDoMarkCompact) {
+  size_t idle_time_in_ms = 1;
+  EXPECT_FALSE(GCIdleTimeHandler::ShouldDoMarkCompact(
+      idle_time_in_ms, kSizeOfObjects, kMarkingSpeed));
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, ShouldDoFinalIncrementalMarkCompact) {
+  size_t idle_time_in_ms = 16;
+  EXPECT_TRUE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
+      idle_time_in_ms, 0, 0));
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, DontDoFinalIncrementalMarkCompact) {
+  size_t idle_time_in_ms = 1;
+  EXPECT_FALSE(GCIdleTimeHandler::ShouldDoFinalIncrementalMarkCompact(
+      idle_time_in_ms, kSizeOfObjects, kMarkingSpeed));
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, ContextDisposeLowRate) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.contexts_disposed = 1;
+  heap_state.incremental_marking_stopped = true;
+  double idle_time_ms = 0;
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DO_NOTHING, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, ContextDisposeHighRate) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.contexts_disposed = 1;
+  heap_state.contexts_disposal_rate =
+      GCIdleTimeHandler::kHighContextDisposalRate - 1;
+  heap_state.incremental_marking_stopped = true;
+  double idle_time_ms = 0;
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DO_FULL_GC, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeLargeIdleTime) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.contexts_disposed = 1;
+  heap_state.contexts_disposal_rate = 1.0;
+  heap_state.incremental_marking_stopped = true;
+  heap_state.can_start_incremental_marking = false;
+  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
+  double idle_time_ms =
+      static_cast<double>((heap_state.size_of_objects + speed - 1) / speed);
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DO_FULL_GC, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeZeroIdleTime) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.contexts_disposed = 1;
+  heap_state.contexts_disposal_rate = 1.0;
+  heap_state.incremental_marking_stopped = true;
+  double idle_time_ms = 0;
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DO_FULL_GC, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime1) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.contexts_disposed = 1;
+  heap_state.contexts_disposal_rate = 1.0;
+  heap_state.incremental_marking_stopped = true;
+  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
+  double idle_time_ms =
+      static_cast<double>(heap_state.size_of_objects / speed - 1);
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, AfterContextDisposeSmallIdleTime2) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.contexts_disposed = 1;
+  heap_state.contexts_disposal_rate = 1.0;
+  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
+  double idle_time_ms =
+      static_cast<double>(heap_state.size_of_objects / speed - 1);
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, IncrementalMarking1) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
+  double idle_time_ms = 10;
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+  EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
+            static_cast<size_t>(action.parameter));
+  EXPECT_LT(0, action.parameter);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, IncrementalMarking2) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.incremental_marking_stopped = true;
+  size_t speed = heap_state.incremental_marking_speed_in_bytes_per_ms;
+  double idle_time_ms = 10;
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+  EXPECT_GT(speed * static_cast<size_t>(idle_time_ms),
+            static_cast<size_t>(action.parameter));
+  EXPECT_LT(0, action.parameter);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, NotEnoughTime) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.incremental_marking_stopped = true;
+  heap_state.can_start_incremental_marking = false;
+  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
+  double idle_time_ms =
+      static_cast<double>(heap_state.size_of_objects / speed - 1);
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DO_NOTHING, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, StopEventually1) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.incremental_marking_stopped = true;
+  heap_state.can_start_incremental_marking = false;
+  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
+  double idle_time_ms =
+      static_cast<double>(heap_state.size_of_objects / speed + 1);
+  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
+    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+    EXPECT_EQ(DO_FULL_GC, action.type);
+    handler()->NotifyIdleMarkCompact();
+  }
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DONE, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, StopEventually2) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  double idle_time_ms = 10;
+  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
+    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+    EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+    // In this case we emulate incremental marking steps that finish with a
+    // full gc.
+    handler()->NotifyIdleMarkCompact();
+  }
+  heap_state.can_start_incremental_marking = false;
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DONE, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop1) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  heap_state.incremental_marking_stopped = true;
+  heap_state.can_start_incremental_marking = false;
+  size_t speed = heap_state.mark_compact_speed_in_bytes_per_ms;
+  double idle_time_ms =
+      static_cast<double>(heap_state.size_of_objects / speed + 1);
+  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
+    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+    EXPECT_EQ(DO_FULL_GC, action.type);
+    handler()->NotifyIdleMarkCompact();
+  }
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DONE, action.type);
+  // Emulate mutator work.
+  for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
+    handler()->NotifyScavenge();
+  }
+  action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DO_FULL_GC, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, ContinueAfterStop2) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  double idle_time_ms = 10;
+  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
+    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+    if (action.type == DONE) break;
+    EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+    // In this case we try to emulate incremental marking steps the finish with
+    // a full gc.
+    handler()->NotifyIdleMarkCompact();
+  }
+  heap_state.can_start_incremental_marking = false;
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DONE, action.type);
+  // Emulate mutator work.
+  for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
+    handler()->NotifyScavenge();
+  }
+  heap_state.can_start_incremental_marking = true;
+  action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, Scavenge) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  int idle_time_ms = 10;
+  heap_state.used_new_space_size =
+      heap_state.new_space_capacity -
+      (kNewSpaceAllocationThroughput * idle_time_ms);
+  GCIdleTimeAction action =
+      handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
+  EXPECT_EQ(DO_SCAVENGE, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, ScavengeAndDone) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  int idle_time_ms = 10;
+  heap_state.can_start_incremental_marking = false;
+  heap_state.incremental_marking_stopped = true;
+  heap_state.used_new_space_size =
+      heap_state.new_space_capacity -
+      (kNewSpaceAllocationThroughput * idle_time_ms);
+  GCIdleTimeAction action =
+      handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
+  EXPECT_EQ(DO_SCAVENGE, action.type);
+  heap_state.used_new_space_size = 0;
+  action = handler()->Compute(static_cast<double>(idle_time_ms), heap_state);
+  EXPECT_EQ(DO_NOTHING, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeNothingToDo) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  double idle_time_ms = 0;
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  EXPECT_EQ(DO_NOTHING, action.type);
+}
+
+
+TEST_F(GCIdleTimeHandlerTest, ZeroIdleTimeDoNothingButStartIdleRound) {
+  GCIdleTimeHandler::HeapState heap_state = DefaultHeapState();
+  double idle_time_ms = 10;
+  for (int i = 0; i < GCIdleTimeHandler::kMaxMarkCompactsInIdleRound; i++) {
+    GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+    if (action.type == DONE) break;
+    EXPECT_EQ(DO_INCREMENTAL_MARKING, action.type);
+    // In this case we try to emulate incremental marking steps the finish with
+    // a full gc.
+    handler()->NotifyIdleMarkCompact();
+  }
+  GCIdleTimeAction action = handler()->Compute(idle_time_ms, heap_state);
+  // Emulate mutator work.
+  for (int i = 0; i < GCIdleTimeHandler::kIdleScavengeThreshold; i++) {
+    handler()->NotifyScavenge();
+  }
+  action = handler()->Compute(0, heap_state);
+  EXPECT_EQ(DO_NOTHING, action.type);
+}
+
+}  // namespace internal
+}  // namespace v8
diff --git a/src/libplatform/default-platform-unittest.cc b/test/unittests/libplatform/default-platform-unittest.cc
similarity index 100%
rename from src/libplatform/default-platform-unittest.cc
rename to test/unittests/libplatform/default-platform-unittest.cc
diff --git a/src/libplatform/task-queue-unittest.cc b/test/unittests/libplatform/task-queue-unittest.cc
similarity index 100%
rename from src/libplatform/task-queue-unittest.cc
rename to test/unittests/libplatform/task-queue-unittest.cc
diff --git a/src/libplatform/worker-thread-unittest.cc b/test/unittests/libplatform/worker-thread-unittest.cc
similarity index 100%
rename from src/libplatform/worker-thread-unittest.cc
rename to test/unittests/libplatform/worker-thread-unittest.cc
diff --git a/src/test/run-all-unittests.cc b/test/unittests/run-all-unittests.cc
similarity index 100%
rename from src/test/run-all-unittests.cc
rename to test/unittests/run-all-unittests.cc
diff --git a/test/unittests/test-utils.cc b/test/unittests/test-utils.cc
new file mode 100644
index 0000000..31d724a
--- /dev/null
+++ b/test/unittests/test-utils.cc
@@ -0,0 +1,109 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "test/unittests/test-utils.h"
+
+#include "src/base/platform/time.h"
+#include "src/flags.h"
+#include "src/isolate-inl.h"
+
+namespace v8 {
+
+std::ostream& operator<<(std::ostream& os, ExternalArrayType type) {
+  switch (type) {
+    case kExternalInt8Array:
+      return os << "ExternalInt8Array";
+    case kExternalUint8Array:
+      return os << "ExternalUint8Array";
+    case kExternalInt16Array:
+      return os << "ExternalInt16Array";
+    case kExternalUint16Array:
+      return os << "ExternalUint16Array";
+    case kExternalInt32Array:
+      return os << "ExternalInt32Array";
+    case kExternalUint32Array:
+      return os << "ExternalUint32Array";
+    case kExternalFloat32Array:
+      return os << "ExternalFloat32Array";
+    case kExternalFloat64Array:
+      return os << "ExternalFloat64Array";
+    case kExternalUint8ClampedArray:
+      return os << "ExternalUint8ClampedArray";
+  }
+  UNREACHABLE();
+  return os;
+}
+
+
+// static
+Isolate* TestWithIsolate::isolate_ = NULL;
+
+
+TestWithIsolate::TestWithIsolate()
+    : isolate_scope_(isolate()), handle_scope_(isolate()) {}
+
+
+TestWithIsolate::~TestWithIsolate() {}
+
+
+// static
+void TestWithIsolate::SetUpTestCase() {
+  Test::SetUpTestCase();
+  EXPECT_EQ(NULL, isolate_);
+  isolate_ = v8::Isolate::New();
+  EXPECT_TRUE(isolate_ != NULL);
+}
+
+
+// static
+void TestWithIsolate::TearDownTestCase() {
+  ASSERT_TRUE(isolate_ != NULL);
+  isolate_->Dispose();
+  isolate_ = NULL;
+  Test::TearDownTestCase();
+}
+
+
+TestWithContext::TestWithContext()
+    : context_(Context::New(isolate())), context_scope_(context_) {}
+
+
+TestWithContext::~TestWithContext() {}
+
+
+namespace base {
+namespace {
+
+inline int64_t GetRandomSeedFromFlag(int random_seed) {
+  return random_seed ? random_seed : TimeTicks::Now().ToInternalValue();
+}
+
+}  // namespace
+
+TestWithRandomNumberGenerator::TestWithRandomNumberGenerator()
+    : rng_(GetRandomSeedFromFlag(internal::FLAG_random_seed)) {}
+
+
+TestWithRandomNumberGenerator::~TestWithRandomNumberGenerator() {}
+
+}  // namespace base
+
+
+namespace internal {
+
+TestWithIsolate::~TestWithIsolate() {}
+
+
+Factory* TestWithIsolate::factory() const { return isolate()->factory(); }
+
+
+base::RandomNumberGenerator* TestWithIsolate::random_number_generator() const {
+  return isolate()->random_number_generator();
+}
+
+
+TestWithZone::~TestWithZone() {}
+
+}  // namespace internal
+}  // namespace v8
diff --git a/test/unittests/test-utils.h b/test/unittests/test-utils.h
new file mode 100644
index 0000000..511e357
--- /dev/null
+++ b/test/unittests/test-utils.h
@@ -0,0 +1,109 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_UNITTESTS_TEST_UTILS_H_
+#define V8_UNITTESTS_TEST_UTILS_H_
+
+#include "include/v8.h"
+#include "src/base/macros.h"
+#include "src/base/utils/random-number-generator.h"
+#include "src/zone.h"
+#include "testing/gtest-support.h"
+
+namespace v8 {
+
+std::ostream& operator<<(std::ostream&, ExternalArrayType);
+
+
+class TestWithIsolate : public ::testing::Test {
+ public:
+  TestWithIsolate();
+  virtual ~TestWithIsolate();
+
+  Isolate* isolate() const { return isolate_; }
+
+  static void SetUpTestCase();
+  static void TearDownTestCase();
+
+ private:
+  static Isolate* isolate_;
+  Isolate::Scope isolate_scope_;
+  HandleScope handle_scope_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestWithIsolate);
+};
+
+
+class TestWithContext : public virtual TestWithIsolate {
+ public:
+  TestWithContext();
+  virtual ~TestWithContext();
+
+  const Local<Context>& context() const { return context_; }
+
+ private:
+  Local<Context> context_;
+  Context::Scope context_scope_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestWithContext);
+};
+
+
+namespace base {
+
+class TestWithRandomNumberGenerator : public ::testing::Test {
+ public:
+  TestWithRandomNumberGenerator();
+  virtual ~TestWithRandomNumberGenerator();
+
+  RandomNumberGenerator* rng() { return &rng_; }
+
+ private:
+  RandomNumberGenerator rng_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestWithRandomNumberGenerator);
+};
+
+}  // namespace base
+
+
+namespace internal {
+
+// Forward declarations.
+class Factory;
+
+
+class TestWithIsolate : public virtual ::v8::TestWithIsolate {
+ public:
+  TestWithIsolate() {}
+  virtual ~TestWithIsolate();
+
+  Factory* factory() const;
+  Isolate* isolate() const {
+    return reinterpret_cast<Isolate*>(::v8::TestWithIsolate::isolate());
+  }
+  base::RandomNumberGenerator* random_number_generator() const;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestWithIsolate);
+};
+
+
+class TestWithZone : public TestWithIsolate {
+ public:
+  TestWithZone() : zone_(isolate()) {}
+  virtual ~TestWithZone();
+
+  Zone* zone() { return &zone_; }
+
+ private:
+  Zone zone_;
+
+  DISALLOW_COPY_AND_ASSIGN(TestWithZone);
+};
+
+}  // namespace internal
+}  // namespace v8
+
+#endif  // V8_UNITTESTS_TEST_UTILS_H_
diff --git a/test/unittests/unittests.gyp b/test/unittests/unittests.gyp
new file mode 100644
index 0000000..2ead44f
--- /dev/null
+++ b/test/unittests/unittests.gyp
@@ -0,0 +1,140 @@
+# Copyright 2014 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+{
+  'variables': {
+    'v8_code': 1,
+  },
+  'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
+  'targets': [
+    {
+      'target_name': 'unittests',
+      'type': 'executable',
+      'variables': {
+        'optimize': 'max',
+      },
+      'dependencies': [
+        '../../testing/gmock.gyp:gmock',
+        '../../testing/gtest.gyp:gtest',
+        '../../tools/gyp/v8.gyp:v8_libplatform',
+      ],
+      'include_dirs': [
+        '../..',
+      ],
+      'sources': [  ### gcmole(all) ###
+        'base/bits-unittest.cc',
+        'base/cpu-unittest.cc',
+        'base/division-by-constant-unittest.cc',
+        'base/flags-unittest.cc',
+        'base/functional-unittest.cc',
+        'base/iterator-unittest.cc',
+        'base/platform/condition-variable-unittest.cc',
+        'base/platform/mutex-unittest.cc',
+        'base/platform/platform-unittest.cc',
+        'base/platform/semaphore-unittest.cc',
+        'base/platform/time-unittest.cc',
+        'base/sys-info-unittest.cc',
+        'base/utils/random-number-generator-unittest.cc',
+        'char-predicates-unittest.cc',
+        'compiler/change-lowering-unittest.cc',
+        'compiler/common-operator-reducer-unittest.cc',
+        'compiler/common-operator-unittest.cc',
+        'compiler/compiler-test-utils.h',
+        'compiler/control-equivalence-unittest.cc',
+        'compiler/diamond-unittest.cc',
+        'compiler/graph-reducer-unittest.cc',
+        'compiler/graph-unittest.cc',
+        'compiler/graph-unittest.h',
+        'compiler/instruction-selector-unittest.cc',
+        'compiler/instruction-selector-unittest.h',
+        'compiler/instruction-sequence-unittest.cc',
+        'compiler/instruction-sequence-unittest.h',
+        'compiler/js-builtin-reducer-unittest.cc',
+        'compiler/js-operator-unittest.cc',
+        'compiler/js-typed-lowering-unittest.cc',
+        'compiler/load-elimination-unittest.cc',
+        'compiler/machine-operator-reducer-unittest.cc',
+        'compiler/machine-operator-unittest.cc',
+        'compiler/move-optimizer-unittest.cc',
+        'compiler/node-matchers-unittest.cc',
+        'compiler/node-test-utils.cc',
+        'compiler/node-test-utils.h',
+        'compiler/register-allocator-unittest.cc',
+        'compiler/select-lowering-unittest.cc',
+        'compiler/simplified-operator-reducer-unittest.cc',
+        'compiler/simplified-operator-unittest.cc',
+        'compiler/value-numbering-reducer-unittest.cc',
+        'compiler/zone-pool-unittest.cc',
+        'libplatform/default-platform-unittest.cc',
+        'libplatform/task-queue-unittest.cc',
+        'libplatform/worker-thread-unittest.cc',
+        'heap/gc-idle-time-handler-unittest.cc',
+        'run-all-unittests.cc',
+        'test-utils.h',
+        'test-utils.cc',
+      ],
+      'conditions': [
+        ['v8_target_arch=="arm"', {
+          'sources': [  ### gcmole(arch:arm) ###
+            'compiler/arm/instruction-selector-arm-unittest.cc',
+          ],
+        }],
+        ['v8_target_arch=="arm64"', {
+          'sources': [  ### gcmole(arch:arm64) ###
+            'compiler/arm64/instruction-selector-arm64-unittest.cc',
+          ],
+        }],
+        ['v8_target_arch=="ia32"', {
+          'sources': [  ### gcmole(arch:ia32) ###
+            'compiler/ia32/instruction-selector-ia32-unittest.cc',
+          ],
+        }],
+        ['v8_target_arch=="mipsel"', {
+          'sources': [  ### gcmole(arch:mipsel) ###
+            'compiler/mips/instruction-selector-mips-unittest.cc',
+          ],
+        }],
+        ['v8_target_arch=="mips64el"', {
+          'sources': [  ### gcmole(arch:mips64el) ###
+            'compiler/mips64/instruction-selector-mips64-unittest.cc',
+          ],
+        }],
+        ['v8_target_arch=="x64"', {
+          'sources': [  ### gcmole(arch:x64) ###
+            'compiler/x64/instruction-selector-x64-unittest.cc',
+          ],
+        }],
+        ['component=="shared_library"', {
+          # compiler-unittests can't be built against a shared library, so we
+          # need to depend on the underlying static target in that case.
+          'conditions': [
+            ['v8_use_snapshot=="true" and v8_use_external_startup_data==0', {
+              'dependencies': ['../../tools/gyp/v8.gyp:v8_snapshot'],
+            }],
+            ['v8_use_snapshot=="true" and v8_use_external_startup_data==1', {
+              'dependencies': ['../../tools/gyp/v8.gyp:v8_external_snapshot'],
+            }],
+            ['v8_use_snapshot!="true"', {
+              'dependencies': ['../../tools/gyp/v8.gyp:v8_nosnapshot'],
+            }],
+          ],
+        }, {
+          'dependencies': ['../../tools/gyp/v8.gyp:v8'],
+        }],
+        ['os_posix == 1', {
+          # TODO(svenpanne): This is a temporary work-around to fix the warnings
+          # that show up because we use -std=gnu++0x instead of -std=c++11.
+          'cflags!': [
+            '-pedantic',
+          ],
+          'direct_dependent_settings': {
+            'cflags!': [
+              '-pedantic',
+            ],
+          },
+        }],
+      ],
+    },
+  ],
+}
diff --git a/test/base-unittests/base-unittests.status b/test/unittests/unittests.status
similarity index 100%
rename from test/base-unittests/base-unittests.status
rename to test/unittests/unittests.status
diff --git a/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt b/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
index 030d7f9..0e00f23 100644
--- a/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
+++ b/test/webkit/fast/js/Object-getOwnPropertyNames-expected.txt
@@ -1,25 +1,6 @@
-# Copyright 2013 the V8 project authors. All rights reserved.
-# Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-# 1.  Redistributions of source code must retain the above copyright
-#     notice, this list of conditions and the following disclaimer.
-# 2.  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.
-#
-# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
+# Copyright 2014 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
 
 Test to ensure correct behaviour of Object.getOwnPropertyNames
 
@@ -69,8 +50,8 @@
 PASS getSortedOwnPropertyNames(Function.prototype) is ['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toString']
 PASS getSortedOwnPropertyNames(Array) is ['arguments', 'caller', 'isArray', 'length', 'name', 'observe', 'prototype', 'unobserve']
 PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'entries', 'every', 'filter', 'forEach', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']
-PASS getSortedOwnPropertyNames(String) is ['arguments', 'caller', 'fromCharCode', 'length', 'name', 'prototype']
-PASS getSortedOwnPropertyNames(String.prototype) is ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'replace', 'search', 'slice', 'small', 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']
+PASS getSortedOwnPropertyNames(String) is ['arguments', 'caller', 'fromCharCode', 'fromCodePoint', 'length', 'name', 'prototype', 'raw']
+PASS getSortedOwnPropertyNames(String.prototype) is ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'codePointAt', 'concat', 'constructor', 'endsWith', 'fixed', 'fontcolor', 'fontsize', 'includes', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'repeat', 'replace', 'search', 'slice', 'small', 'split', 'startsWith', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']
 PASS getSortedOwnPropertyNames(Boolean) is ['arguments', 'caller', 'length', 'name', 'prototype']
 PASS getSortedOwnPropertyNames(Boolean.prototype) is ['constructor', 'toString', 'valueOf']
 PASS getSortedOwnPropertyNames(Number) is ['EPSILON', 'MAX_SAFE_INTEGER', 'MAX_VALUE', 'MIN_SAFE_INTEGER', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'arguments', 'caller', 'isFinite', 'isInteger', 'isNaN', 'isSafeInteger', 'length', 'name', 'parseFloat', 'parseInt', 'prototype']
diff --git a/test/webkit/fast/js/Object-getOwnPropertyNames.js b/test/webkit/fast/js/Object-getOwnPropertyNames.js
index caa0111..72bd21b 100644
--- a/test/webkit/fast/js/Object-getOwnPropertyNames.js
+++ b/test/webkit/fast/js/Object-getOwnPropertyNames.js
@@ -77,8 +77,8 @@
     "Function.prototype": "['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toString']",
     "Array": "['arguments', 'caller', 'isArray', 'length', 'name', 'observe', 'prototype', 'unobserve']",
     "Array.prototype": "['concat', 'constructor', 'entries', 'every', 'filter', 'forEach', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift']",
-    "String": "['arguments', 'caller', 'fromCharCode', 'length', 'name', 'prototype']",
-    "String.prototype": "['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'concat', 'constructor', 'fixed', 'fontcolor', 'fontsize', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'replace', 'search', 'slice', 'small', 'split', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']",
+    "String": "['arguments', 'caller', 'fromCharCode', 'fromCodePoint', 'length', 'name', 'prototype', 'raw']",
+    "String.prototype": "['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'codePointAt', 'concat', 'constructor', 'endsWith', 'fixed', 'fontcolor', 'fontsize', 'includes', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'repeat', 'replace', 'search', 'slice', 'small', 'split', 'startsWith', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimLeft', 'trimRight', 'valueOf']",
     "Boolean": "['arguments', 'caller', 'length', 'name', 'prototype']",
     "Boolean.prototype": "['constructor', 'toString', 'valueOf']",
     "Number": "['EPSILON', 'MAX_SAFE_INTEGER', 'MAX_VALUE', 'MIN_SAFE_INTEGER', 'MIN_VALUE', 'NEGATIVE_INFINITY', 'NaN', 'POSITIVE_INFINITY', 'arguments', 'caller', 'isFinite', 'isInteger', 'isNaN', 'isSafeInteger', 'length', 'name', 'parseFloat', 'parseInt', 'prototype']",
diff --git a/test/webkit/fast/js/basic-strict-mode-expected.txt b/test/webkit/fast/js/basic-strict-mode-expected.txt
index 45f71bf..0e6228e 100644
--- a/test/webkit/fast/js/basic-strict-mode-expected.txt
+++ b/test/webkit/fast/js/basic-strict-mode-expected.txt
@@ -129,7 +129,7 @@
 PASS (function(){(function (){ 'use strict'; delete someDeclaredGlobal;})}) threw exception SyntaxError: Delete of an unqualified identifier in strict mode..
 PASS 'use strict'; if (0) { someGlobal = 'Shouldn\'t be able to assign this.'; }; true; is true
 PASS 'use strict'; someGlobal = 'Shouldn\'t be able to assign this.';  threw exception ReferenceError: someGlobal is not defined.
-FAIL 'use strict'; (function f(){ f = 'shouldn\'t be able to assign to function expression name'; })() should throw an exception. Was undefined.
+PASS 'use strict'; (function f(){ f = 'shouldn\'t be able to assign to function expression name'; })() threw exception TypeError: Assignment to constant variable..
 PASS 'use strict'; eval('var introducedVariable = "FAIL: variable introduced into containing scope";'); introducedVariable threw exception ReferenceError: introducedVariable is not defined.
 PASS 'use strict'; objectWithReadonlyProperty.prop = 'fail' threw exception TypeError: Cannot assign to read only property 'prop' of #<Object>.
 PASS 'use strict'; delete objectWithReadonlyProperty.prop threw exception TypeError: Cannot delete property 'prop' of #<Object>.
diff --git a/test/webkit/fast/regex/toString-expected.txt b/test/webkit/fast/regex/toString-expected.txt
index a6eefd9..1024072 100644
--- a/test/webkit/fast/regex/toString-expected.txt
+++ b/test/webkit/fast/regex/toString-expected.txt
@@ -26,23 +26,23 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
-FAIL RegExp('/').source should be \/. Was /.
+PASS RegExp('/').source is "\\/"
 PASS RegExp('').source is "(?:)"
 PASS RegExp.prototype.source is "(?:)"
-FAIL RegExp('/').toString() should be /\//. Was ///.
+PASS RegExp('/').toString() is "/\\//"
 PASS RegExp('').toString() is "/(?:)/"
 PASS RegExp.prototype.toString() is "/(?:)/"
-FAIL testForwardSlash("^/$", "/"); should be true. Threw exception SyntaxError: Unexpected end of input
-FAIL testForwardSlash("^/$", "/"); should be true. Threw exception SyntaxError: Unexpected end of input
-FAIL testForwardSlash("^\/$", "/"); should be true. Threw exception SyntaxError: Unexpected end of input
+PASS testForwardSlash("^/$", "/"); is true
+PASS testForwardSlash("^/$", "/"); is true
+PASS testForwardSlash("^\/$", "/"); is true
 PASS testForwardSlash("^\\/$", "\/"); is true
 PASS testForwardSlash("^\\\/$", "\/"); is true
 FAIL testForwardSlash("^\\\\/$", "\\/"); should be true. Threw exception SyntaxError: Unexpected end of input
 FAIL testForwardSlash("^\\\\\/$", "\\/"); should be true. Threw exception SyntaxError: Unexpected end of input
-FAIL testForwardSlash("x/x/x", "x\/x\/x"); should be true. Threw exception SyntaxError: Unexpected end of input
-FAIL testForwardSlash("x\/x/x", "x\/x\/x"); should be true. Threw exception SyntaxError: Unexpected end of input
-FAIL testForwardSlash("x/x\/x", "x\/x\/x"); should be true. Threw exception SyntaxError: Unexpected end of input
-FAIL testForwardSlash("x\/x\/x", "x\/x\/x"); should be true. Threw exception SyntaxError: Unexpected end of input
+PASS testForwardSlash("x/x/x", "x\/x\/x"); is true
+PASS testForwardSlash("x\/x/x", "x\/x\/x"); is true
+PASS testForwardSlash("x/x\/x", "x\/x\/x"); is true
+PASS testForwardSlash("x\/x\/x", "x\/x\/x"); is true
 FAIL testLineTerminator("\n"); should be false. Was true.
 PASS testLineTerminator("\\n"); is false
 FAIL testLineTerminator("\r"); should be false. Was true.
@@ -51,8 +51,8 @@
 PASS testLineTerminator("\\u2028"); is false
 FAIL testLineTerminator("\u2029"); should be false. Was true.
 PASS testLineTerminator("\\u2029"); is false
-PASS RegExp('[/]').source is '[/]'
-FAIL RegExp('\\[/]').source should be \[\/]. Was \[/].
+FAIL RegExp('[/]').source should be [/]. Was [\/].
+PASS RegExp('\\[/]').source is '\\[\\/]'
 PASS var o = new RegExp(); o.toString() === '/'+o.source+'/' && eval(o.toString()+'.exec(String())') is [""]
 PASS successfullyParsed is true
 
diff --git a/test/webkit/testcfg.py b/test/webkit/testcfg.py
index e4e3f8f..aa81964 100644
--- a/test/webkit/testcfg.py
+++ b/test/webkit/testcfg.py
@@ -109,7 +109,11 @@
             string.startswith("tools/nacl-run.py") or
             string.find("BYPASSING ALL ACL CHECKS") > 0 or
             string.find("Native Client module will be loaded") > 0 or
-            string.find("NaClHostDescOpen:") > 0)
+            string.find("NaClHostDescOpen:") > 0 or
+            # FIXME(machenbach): The test driver shouldn't try to use slow
+            # asserts if they weren't compiled. This fails in optdebug=2.
+            string == "Warning: unknown flag --enable-slow-asserts." or
+            string == "Try --help for options")
 
   def IsFailureOutput(self, output, testpath):
     if super(WebkitTestSuite, self).IsFailureOutput(output, testpath):
diff --git a/test/webkit/webkit.status b/test/webkit/webkit.status
index 3bb6574..c33f1b9 100644
--- a/test/webkit/webkit.status
+++ b/test/webkit/webkit.status
@@ -44,13 +44,23 @@
   'dfg-double-vote-fuzz': [SKIP],
   'reentrant-caching': [SKIP],
   'sort-large-array': [SKIP],
+  # Too slow on windows with --nocrankshaft.
+  # TODO(mstarzinger): Too slow with TF.
+  'array-iterate-backwards': [PASS, NO_VARIANTS],
 }],  # 'mode == debug'
 ['simulator', {
+  # Skip tests that timeout with turbofan.
+  'dfg-int-overflow-in-loop': [PASS, NO_VARIANTS],
+  'array-iterate-backwards': [PASS, NO_VARIANTS],
   'function-apply-aliased': [SKIP],
 }],  # 'simulator'
 ['arch == arm64 and simulator_run == True', {
   'dfg-int-overflow-in-loop': [SKIP],
 }],  # 'arch == arm64 and simulator_run == True'
+['dcheck_always_on == True and arch == arm64', {
+  # Doesn't work with gcc 4.6 on arm64 for some reason.
+  'reentrant-caching': [SKIP],
+}],  # 'dcheck_always_on == True and arch == arm64'
 
 
 ##############################################################################
@@ -59,5 +69,10 @@
   'fast/js/excessive-comma-usage': [SKIP]
 }],  # 'gc_stress == True'
 
+['gc_stress == True and mode == debug', {
+  # Skip tests that timeout.
+  'array-iterate-backwards': [SKIP]
+}],  # 'gc_stress == True and mode == debug'
+
 ##############################################################################
 ]
diff --git a/testing/gmock-support.h b/testing/gmock-support.h
index 44348b6..012775b 100644
--- a/testing/gmock-support.h
+++ b/testing/gmock-support.h
@@ -5,6 +5,9 @@
 #ifndef V8_TESTING_GMOCK_SUPPORT_H_
 #define V8_TESTING_GMOCK_SUPPORT_H_
 
+#include <cmath>
+#include <cstring>
+
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace testing {
@@ -31,6 +34,25 @@
 
 namespace internal {
 
+struct AnyBitEq {
+  template <typename A, typename B>
+  bool operator()(A const& a, B const& b) const {
+    if (sizeof(A) != sizeof(B)) return false;
+    return std::memcmp(&a, &b, sizeof(A)) == 0;
+  }
+};
+
+
+template <typename Rhs>
+class BitEqMatcher : public ComparisonBase<BitEqMatcher<Rhs>, Rhs, AnyBitEq> {
+ public:
+  explicit BitEqMatcher(Rhs const& rhs)
+      : ComparisonBase<BitEqMatcher<Rhs>, Rhs, AnyBitEq>(rhs) {}
+  static const char* Desc() { return "is bitwise equal to"; }
+  static const char* NegatedDesc() { return "isn't bitwise equal to"; }
+};
+
+
 template <typename T>
 class CaptureEqMatcher : public MatcherInterface<T> {
  public:
@@ -60,13 +82,27 @@
 }  // namespace internal
 
 
+// Creates a polymorphic matcher that matches anything whose bit representation
+// is equal to that of x.
+template <typename T>
+inline internal::BitEqMatcher<T> BitEq(T const& x) {
+  return internal::BitEqMatcher<T>(x);
+}
+
+
 // CaptureEq(capture) captures the value passed in during matching as long as it
 // is unset, and once set, compares the value for equality with the argument.
 template <typename T>
-Matcher<T> CaptureEq(Capture<T>* capture) {
+inline Matcher<T> CaptureEq(Capture<T>* capture) {
   return MakeMatcher(new internal::CaptureEqMatcher<T>(capture));
 }
 
+
+// Creates a polymorphic matcher that matches any floating point NaN value.
+MATCHER(IsNaN, std::string(negation ? "isn't" : "is") + " not a number") {
+  return std::isnan(arg);
+}
+
 }  // namespace testing
 
 #endif  // V8_TESTING_GMOCK_SUPPORT_H_
diff --git a/testing/gtest-support.h b/testing/gtest-support.h
index 66b1094..04daa55 100644
--- a/testing/gtest-support.h
+++ b/testing/gtest-support.h
@@ -5,7 +5,7 @@
 #ifndef V8_TESTING_GTEST_SUPPORT_H_
 #define V8_TESTING_GTEST_SUPPORT_H_
 
-#include "include/v8stdint.h"
+#include <stddef.h>
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace testing {
@@ -16,14 +16,17 @@
   inline std::string GetTypeName<type>() { \
     return #type;                          \
   }
-GET_TYPE_NAME(int8_t)
-GET_TYPE_NAME(uint8_t)
-GET_TYPE_NAME(int16_t)
-GET_TYPE_NAME(uint16_t)
-GET_TYPE_NAME(int32_t)
-GET_TYPE_NAME(uint32_t)
-GET_TYPE_NAME(int64_t)
-GET_TYPE_NAME(uint64_t)
+GET_TYPE_NAME(bool)
+GET_TYPE_NAME(signed char)
+GET_TYPE_NAME(unsigned char)
+GET_TYPE_NAME(short)
+GET_TYPE_NAME(unsigned short)
+GET_TYPE_NAME(int)
+GET_TYPE_NAME(unsigned int)
+GET_TYPE_NAME(long)
+GET_TYPE_NAME(unsigned long)
+GET_TYPE_NAME(long long)
+GET_TYPE_NAME(unsigned long long)
 GET_TYPE_NAME(float)
 GET_TYPE_NAME(double)
 #undef GET_TYPE_NAME
diff --git a/third_party/fdlibm/fdlibm.cc b/third_party/fdlibm/fdlibm.cc
deleted file mode 100644
index c009cd0..0000000
--- a/third_party/fdlibm/fdlibm.cc
+++ /dev/null
@@ -1,281 +0,0 @@
-// The following is adapted from fdlibm (http://www.netlib.org/fdlibm).
-//
-// ====================================================
-// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-//
-// Developed at SunSoft, a Sun Microsystems, Inc. business.
-// Permission to use, copy, modify, and distribute this
-// software is freely granted, provided that this notice
-// is preserved.
-// ====================================================
-//
-// The original source code covered by the above license above has been
-// modified significantly by Google Inc.
-// Copyright 2014 the V8 project authors. All rights reserved.
-
-#include "src/v8.h"
-
-#include "src/double.h"
-#include "third_party/fdlibm/fdlibm.h"
-
-
-namespace v8 {
-namespace fdlibm {
-
-#ifdef _MSC_VER
-inline double scalbn(double x, int y) { return _scalb(x, y); }
-#endif  // _MSC_VER
-
-const double MathConstants::constants[] = {
-    6.36619772367581382433e-01,   // invpio2   0
-    1.57079632673412561417e+00,   // pio2_1    1
-    6.07710050650619224932e-11,   // pio2_1t   2
-    6.07710050630396597660e-11,   // pio2_2    3
-    2.02226624879595063154e-21,   // pio2_2t   4
-    2.02226624871116645580e-21,   // pio2_3    5
-    8.47842766036889956997e-32,   // pio2_3t   6
-    -1.66666666666666324348e-01,  // S1        7  coefficients for sin
-    8.33333333332248946124e-03,   //           8
-    -1.98412698298579493134e-04,  //           9
-    2.75573137070700676789e-06,   //          10
-    -2.50507602534068634195e-08,  //          11
-    1.58969099521155010221e-10,   // S6       12
-    4.16666666666666019037e-02,   // C1       13  coefficients for cos
-    -1.38888888888741095749e-03,  //          14
-    2.48015872894767294178e-05,   //          15
-    -2.75573143513906633035e-07,  //          16
-    2.08757232129817482790e-09,   //          17
-    -1.13596475577881948265e-11,  // C6       18
-    3.33333333333334091986e-01,   // T0       19  coefficients for tan
-    1.33333333333201242699e-01,   //          20
-    5.39682539762260521377e-02,   //          21
-    2.18694882948595424599e-02,   //          22
-    8.86323982359930005737e-03,   //          23
-    3.59207910759131235356e-03,   //          24
-    1.45620945432529025516e-03,   //          25
-    5.88041240820264096874e-04,   //          26
-    2.46463134818469906812e-04,   //          27
-    7.81794442939557092300e-05,   //          28
-    7.14072491382608190305e-05,   //          29
-    -1.85586374855275456654e-05,  //          30
-    2.59073051863633712884e-05,   // T12      31
-    7.85398163397448278999e-01,   // pio4     32
-    3.06161699786838301793e-17,   // pio4lo   33
-    6.93147180369123816490e-01,   // ln2_hi   34
-    1.90821492927058770002e-10,   // ln2_lo   35
-    1.80143985094819840000e+16,   // 2^54     36
-    6.666666666666666666e-01,     // 2/3      37
-    6.666666666666735130e-01,     // LP1      38  coefficients for log1p
-    3.999999999940941908e-01,     //          39
-    2.857142874366239149e-01,     //          40
-    2.222219843214978396e-01,     //          41
-    1.818357216161805012e-01,     //          42
-    1.531383769920937332e-01,     //          43
-    1.479819860511658591e-01,     // LP7      44
-    7.09782712893383973096e+02,   //          45  overflow threshold for expm1
-    1.44269504088896338700e+00,   // 1/ln2    46
-    -3.33333333333331316428e-02,  // Q1       47  coefficients for expm1
-    1.58730158725481460165e-03,   //          48
-    -7.93650757867487942473e-05,  //          49
-    4.00821782732936239552e-06,   //          50
-    -2.01099218183624371326e-07,  // Q5       51
-    710.4758600739439             //          52  overflow threshold sinh, cosh
-};
-
-
-// Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
-static const int two_over_pi[] = {
-    0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, 0x95993C,
-    0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, 0x424DD2, 0xE00649,
-    0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, 0xA73EE8, 0x8235F5, 0x2EBB44,
-    0x84E99C, 0x7026B4, 0x5F7E41, 0x3991D6, 0x398353, 0x39F49C, 0x845F8B,
-    0xBDF928, 0x3B1FF8, 0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D,
-    0x367ECF, 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
-    0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, 0x560330,
-    0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, 0x91615E, 0xE61B08,
-    0x659985, 0x5F14A0, 0x68408D, 0xFFD880, 0x4D7327, 0x310606, 0x1556CA,
-    0x73A8C9, 0x60E27B, 0xC08C6B};
-
-static const double zero = 0.0;
-static const double two24 = 1.6777216e+07;
-static const double one = 1.0;
-static const double twon24 = 5.9604644775390625e-08;
-
-static const double PIo2[] = {
-    1.57079625129699707031e+00,  // 0x3FF921FB, 0x40000000
-    7.54978941586159635335e-08,  // 0x3E74442D, 0x00000000
-    5.39030252995776476554e-15,  // 0x3CF84698, 0x80000000
-    3.28200341580791294123e-22,  // 0x3B78CC51, 0x60000000
-    1.27065575308067607349e-29,  // 0x39F01B83, 0x80000000
-    1.22933308981111328932e-36,  // 0x387A2520, 0x40000000
-    2.73370053816464559624e-44,  // 0x36E38222, 0x80000000
-    2.16741683877804819444e-51   // 0x3569F31D, 0x00000000
-};
-
-
-int __kernel_rem_pio2(double* x, double* y, int e0, int nx) {
-  static const int32_t jk = 3;
-  double fw;
-  int32_t jx = nx - 1;
-  int32_t jv = (e0 - 3) / 24;
-  if (jv < 0) jv = 0;
-  int32_t q0 = e0 - 24 * (jv + 1);
-  int32_t m = jx + jk;
-
-  double f[10];
-  for (int i = 0, j = jv - jx; i <= m; i++, j++) {
-    f[i] = (j < 0) ? zero : static_cast<double>(two_over_pi[j]);
-  }
-
-  double q[10];
-  for (int i = 0; i <= jk; i++) {
-    fw = 0.0;
-    for (int j = 0; j <= jx; j++) fw += x[j] * f[jx + i - j];
-    q[i] = fw;
-  }
-
-  int32_t jz = jk;
-
-recompute:
-
-  int32_t iq[10];
-  double z = q[jz];
-  for (int i = 0, j = jz; j > 0; i++, j--) {
-    fw = static_cast<double>(static_cast<int32_t>(twon24 * z));
-    iq[i] = static_cast<int32_t>(z - two24 * fw);
-    z = q[j - 1] + fw;
-  }
-
-  z = scalbn(z, q0);
-  z -= 8.0 * std::floor(z * 0.125);
-  int32_t n = static_cast<int32_t>(z);
-  z -= static_cast<double>(n);
-  int32_t ih = 0;
-  if (q0 > 0) {
-    int32_t i = (iq[jz - 1] >> (24 - q0));
-    n += i;
-    iq[jz - 1] -= i << (24 - q0);
-    ih = iq[jz - 1] >> (23 - q0);
-  } else if (q0 == 0) {
-    ih = iq[jz - 1] >> 23;
-  } else if (z >= 0.5) {
-    ih = 2;
-  }
-
-  if (ih > 0) {
-    n += 1;
-    int32_t carry = 0;
-    for (int i = 0; i < jz; i++) {
-      int32_t j = iq[i];
-      if (carry == 0) {
-        if (j != 0) {
-          carry = 1;
-          iq[i] = 0x1000000 - j;
-        }
-      } else {
-        iq[i] = 0xffffff - j;
-      }
-    }
-    if (q0 == 1) {
-      iq[jz - 1] &= 0x7fffff;
-    } else if (q0 == 2) {
-      iq[jz - 1] &= 0x3fffff;
-    }
-    if (ih == 2) {
-      z = one - z;
-      if (carry != 0) z -= scalbn(one, q0);
-    }
-  }
-
-  if (z == zero) {
-    int32_t j = 0;
-    for (int i = jz - 1; i >= jk; i--) j |= iq[i];
-    if (j == 0) {
-      int32_t k = 1;
-      while (iq[jk - k] == 0) k++;
-      for (int i = jz + 1; i <= jz + k; i++) {
-        f[jx + i] = static_cast<double>(two_over_pi[jv + i]);
-        for (j = 0, fw = 0.0; j <= jx; j++) fw += x[j] * f[jx + i - j];
-        q[i] = fw;
-      }
-      jz += k;
-      goto recompute;
-    }
-  }
-
-  if (z == 0.0) {
-    jz -= 1;
-    q0 -= 24;
-    while (iq[jz] == 0) {
-      jz--;
-      q0 -= 24;
-    }
-  } else {
-    z = scalbn(z, -q0);
-    if (z >= two24) {
-      fw = static_cast<double>(static_cast<int32_t>(twon24 * z));
-      iq[jz] = static_cast<int32_t>(z - two24 * fw);
-      jz += 1;
-      q0 += 24;
-      iq[jz] = static_cast<int32_t>(fw);
-    } else {
-      iq[jz] = static_cast<int32_t>(z);
-    }
-  }
-
-  fw = scalbn(one, q0);
-  for (int i = jz; i >= 0; i--) {
-    q[i] = fw * static_cast<double>(iq[i]);
-    fw *= twon24;
-  }
-
-  double fq[10];
-  for (int i = jz; i >= 0; i--) {
-    fw = 0.0;
-    for (int k = 0; k <= jk && k <= jz - i; k++) fw += PIo2[k] * q[i + k];
-    fq[jz - i] = fw;
-  }
-
-  fw = 0.0;
-  for (int i = jz; i >= 0; i--) fw += fq[i];
-  y[0] = (ih == 0) ? fw : -fw;
-  fw = fq[0] - fw;
-  for (int i = 1; i <= jz; i++) fw += fq[i];
-  y[1] = (ih == 0) ? fw : -fw;
-  return n & 7;
-}
-
-
-int rempio2(double x, double* y) {
-  int32_t hx = static_cast<int32_t>(internal::double_to_uint64(x) >> 32);
-  int32_t ix = hx & 0x7fffffff;
-
-  if (ix >= 0x7ff00000) {
-    *y = base::OS::nan_value();
-    return 0;
-  }
-
-  int32_t e0 = (ix >> 20) - 1046;
-  uint64_t zi = internal::double_to_uint64(x) & 0xFFFFFFFFu;
-  zi |= static_cast<uint64_t>(ix - (e0 << 20)) << 32;
-  double z = internal::uint64_to_double(zi);
-
-  double tx[3];
-  for (int i = 0; i < 2; i++) {
-    tx[i] = static_cast<double>(static_cast<int32_t>(z));
-    z = (z - tx[i]) * two24;
-  }
-  tx[2] = z;
-
-  int nx = 3;
-  while (tx[nx - 1] == zero) nx--;
-  int n = __kernel_rem_pio2(tx, y, e0, nx);
-  if (hx < 0) {
-    y[0] = -y[0];
-    y[1] = -y[1];
-    return -n;
-  }
-  return n;
-}
-}
-}  // namespace v8::internal
diff --git a/third_party/fdlibm/fdlibm.h b/third_party/fdlibm/fdlibm.h
deleted file mode 100644
index cadf85b..0000000
--- a/third_party/fdlibm/fdlibm.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// The following is adapted from fdlibm (http://www.netlib.org/fdlibm).
-//
-// ====================================================
-// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-//
-// Developed at SunSoft, a Sun Microsystems, Inc. business.
-// Permission to use, copy, modify, and distribute this
-// software is freely granted, provided that this notice
-// is preserved.
-// ====================================================
-//
-// The original source code covered by the above license above has been
-// modified significantly by Google Inc.
-// Copyright 2014 the V8 project authors. All rights reserved.
-
-#ifndef V8_FDLIBM_H_
-#define V8_FDLIBM_H_
-
-namespace v8 {
-namespace fdlibm {
-
-int rempio2(double x, double* y);
-
-// Constants to be exposed to builtins via Float64Array.
-struct MathConstants {
-  static const double constants[53];
-};
-}
-}  // namespace v8::internal
-
-#endif  // V8_FDLIBM_H_
diff --git a/third_party/fdlibm/fdlibm.js b/third_party/fdlibm/fdlibm.js
deleted file mode 100644
index 7fd9adf..0000000
--- a/third_party/fdlibm/fdlibm.js
+++ /dev/null
@@ -1,814 +0,0 @@
-// The following is adapted from fdlibm (http://www.netlib.org/fdlibm),
-//
-// ====================================================
-// Copyright (C) 1993-2004 by Sun Microsystems, Inc. All rights reserved.
-//
-// Developed at SunSoft, a Sun Microsystems, Inc. business.
-// Permission to use, copy, modify, and distribute this
-// software is freely granted, provided that this notice
-// is preserved.
-// ====================================================
-//
-// The original source code covered by the above license above has been
-// modified significantly by Google Inc.
-// Copyright 2014 the V8 project authors. All rights reserved.
-//
-// The following is a straightforward translation of fdlibm routines
-// by Raymond Toy (rtoy@google.com).
-
-// Double constants that do not have empty lower 32 bits are found in fdlibm.cc
-// and exposed through kMath as typed array. We assume the compiler to convert
-// from decimal to binary accurately enough to produce the intended values.
-// kMath is initialized to a Float64Array during genesis and not writable.
-var kMath;
-
-const INVPIO2 = kMath[0];
-const PIO2_1  = kMath[1];
-const PIO2_1T = kMath[2];
-const PIO2_2  = kMath[3];
-const PIO2_2T = kMath[4];
-const PIO2_3  = kMath[5];
-const PIO2_3T = kMath[6];
-const PIO4    = kMath[32];
-const PIO4LO  = kMath[33];
-
-// Compute k and r such that x - k*pi/2 = r where |r| < pi/4. For
-// precision, r is returned as two values y0 and y1 such that r = y0 + y1
-// to more than double precision.
-macro REMPIO2(X)
-  var n, y0, y1;
-  var hx = %_DoubleHi(X);
-  var ix = hx & 0x7fffffff;
-
-  if (ix < 0x4002d97c) {
-    // |X| ~< 3*pi/4, special case with n = +/- 1
-    if (hx > 0) {
-      var z = X - PIO2_1;
-      if (ix != 0x3ff921fb) {
-        // 33+53 bit pi is good enough
-        y0 = z - PIO2_1T;
-        y1 = (z - y0) - PIO2_1T;
-      } else {
-        // near pi/2, use 33+33+53 bit pi
-        z -= PIO2_2;
-        y0 = z - PIO2_2T;
-        y1 = (z - y0) - PIO2_2T;
-      }
-      n = 1;
-    } else {
-      // Negative X
-      var z = X + PIO2_1;
-      if (ix != 0x3ff921fb) {
-        // 33+53 bit pi is good enough
-        y0 = z + PIO2_1T;
-        y1 = (z - y0) + PIO2_1T;
-      } else {
-        // near pi/2, use 33+33+53 bit pi
-        z += PIO2_2;
-        y0 = z + PIO2_2T;
-        y1 = (z - y0) + PIO2_2T;
-      }
-      n = -1;
-    }
-  } else if (ix <= 0x413921fb) {
-    // |X| ~<= 2^19*(pi/2), medium size
-    var t = MathAbs(X);
-    n = (t * INVPIO2 + 0.5) | 0;
-    var r = t - n * PIO2_1;
-    var w = n * PIO2_1T;
-    // First round good to 85 bit
-    y0 = r - w;
-    if (ix - (%_DoubleHi(y0) & 0x7ff00000) > 0x1000000) {
-      // 2nd iteration needed, good to 118
-      t = r;
-      w = n * PIO2_2;
-      r = t - w;
-      w = n * PIO2_2T - ((t - r) - w);
-      y0 = r - w;
-      if (ix - (%_DoubleHi(y0) & 0x7ff00000) > 0x3100000) {
-        // 3rd iteration needed. 151 bits accuracy
-        t = r;
-        w = n * PIO2_3;
-        r = t - w;
-        w = n * PIO2_3T - ((t - r) - w);
-        y0 = r - w;
-      }
-    }
-    y1 = (r - y0) - w;
-    if (hx < 0) {
-      n = -n;
-      y0 = -y0;
-      y1 = -y1;
-    }
-  } else {
-    // Need to do full Payne-Hanek reduction here.
-    var r = %RemPiO2(X);
-    n = r[0];
-    y0 = r[1];
-    y1 = r[2];
-  }
-endmacro
-
-
-// __kernel_sin(X, Y, IY)
-// kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854
-// Input X is assumed to be bounded by ~pi/4 in magnitude.
-// Input Y is the tail of X so that x = X + Y.
-//
-// Algorithm
-//  1. Since ieee_sin(-x) = -ieee_sin(x), we need only to consider positive x.
-//  2. ieee_sin(x) is approximated by a polynomial of degree 13 on
-//     [0,pi/4]
-//                           3            13
-//          sin(x) ~ x + S1*x + ... + S6*x
-//     where
-//
-//    |ieee_sin(x)    2     4     6     8     10     12  |     -58
-//    |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x  +S6*x   )| <= 2
-//    |  x                                               |
-//
-//  3. ieee_sin(X+Y) = ieee_sin(X) + sin'(X')*Y
-//              ~ ieee_sin(X) + (1-X*X/2)*Y
-//     For better accuracy, let
-//               3      2      2      2      2
-//          r = X *(S2+X *(S3+X *(S4+X *(S5+X *S6))))
-//     then                   3    2
-//          sin(x) = X + (S1*X + (X *(r-Y/2)+Y))
-//
-macro KSIN(x)
-kMath[7+x]
-endmacro
-
-macro RETURN_KERNELSIN(X, Y, SIGN)
-  var z = X * X;
-  var v = z * X;
-  var r = KSIN(1) + z * (KSIN(2) + z * (KSIN(3) +
-                    z * (KSIN(4) + z * KSIN(5))));
-  return (X - ((z * (0.5 * Y - v * r) - Y) - v * KSIN(0))) SIGN;
-endmacro
-
-// __kernel_cos(X, Y)
-// kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
-// Input X is assumed to be bounded by ~pi/4 in magnitude.
-// Input Y is the tail of X so that x = X + Y.
-//
-// Algorithm
-//  1. Since ieee_cos(-x) = ieee_cos(x), we need only to consider positive x.
-//  2. ieee_cos(x) is approximated by a polynomial of degree 14 on
-//     [0,pi/4]
-//                                   4            14
-//          cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
-//     where the remez error is
-//
-//  |                   2     4     6     8     10    12     14 |     -58
-//  |ieee_cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  )| <= 2
-//  |                                                           |
-//
-//                 4     6     8     10    12     14
-//  3. let r = C1*x +C2*x +C3*x +C4*x +C5*x  +C6*x  , then
-//         ieee_cos(x) = 1 - x*x/2 + r
-//     since ieee_cos(X+Y) ~ ieee_cos(X) - ieee_sin(X)*Y
-//                    ~ ieee_cos(X) - X*Y,
-//     a correction term is necessary in ieee_cos(x) and hence
-//         cos(X+Y) = 1 - (X*X/2 - (r - X*Y))
-//     For better accuracy when x > 0.3, let qx = |x|/4 with
-//     the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
-//     Then
-//         cos(X+Y) = (1-qx) - ((X*X/2-qx) - (r-X*Y)).
-//     Note that 1-qx and (X*X/2-qx) is EXACT here, and the
-//     magnitude of the latter is at least a quarter of X*X/2,
-//     thus, reducing the rounding error in the subtraction.
-//
-macro KCOS(x)
-kMath[13+x]
-endmacro
-
-macro RETURN_KERNELCOS(X, Y, SIGN)
-  var ix = %_DoubleHi(X) & 0x7fffffff;
-  var z = X * X;
-  var r = z * (KCOS(0) + z * (KCOS(1) + z * (KCOS(2)+
-          z * (KCOS(3) + z * (KCOS(4) + z * KCOS(5))))));
-  if (ix < 0x3fd33333) {  // |x| ~< 0.3
-    return (1 - (0.5 * z - (z * r - X * Y))) SIGN;
-  } else {
-    var qx;
-    if (ix > 0x3fe90000) {  // |x| > 0.78125
-      qx = 0.28125;
-    } else {
-      qx = %_ConstructDouble(%_DoubleHi(0.25 * X), 0);
-    }
-    var hz = 0.5 * z - qx;
-    return (1 - qx - (hz - (z * r - X * Y))) SIGN;
-  }
-endmacro
-
-
-// kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
-// Input x is assumed to be bounded by ~pi/4 in magnitude.
-// Input y is the tail of x.
-// Input k indicates whether ieee_tan (if k = 1) or -1/tan (if k = -1)
-// is returned.
-//
-// Algorithm
-//  1. Since ieee_tan(-x) = -ieee_tan(x), we need only to consider positive x.
-//  2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0.
-//  3. ieee_tan(x) is approximated by a odd polynomial of degree 27 on
-//     [0,0.67434]
-//                           3             27
-//          tan(x) ~ x + T1*x + ... + T13*x
-//     where
-//
-//     |ieee_tan(x)    2     4            26   |     -59.2
-//     |----- - (1+T1*x +T2*x +.... +T13*x    )| <= 2
-//     |  x                                    |
-//
-//     Note: ieee_tan(x+y) = ieee_tan(x) + tan'(x)*y
-//                    ~ ieee_tan(x) + (1+x*x)*y
-//     Therefore, for better accuracy in computing ieee_tan(x+y), let
-//               3      2      2       2       2
-//          r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
-//     then
-//                              3    2
-//          tan(x+y) = x + (T1*x + (x *(r+y)+y))
-//
-//  4. For x in [0.67434,pi/4],  let y = pi/4 - x, then
-//          tan(x) = ieee_tan(pi/4-y) = (1-ieee_tan(y))/(1+ieee_tan(y))
-//                 = 1 - 2*(ieee_tan(y) - (ieee_tan(y)^2)/(1+ieee_tan(y)))
-//
-// Set returnTan to 1 for tan; -1 for cot.  Anything else is illegal
-// and will cause incorrect results.
-//
-macro KTAN(x)
-kMath[19+x]
-endmacro
-
-function KernelTan(x, y, returnTan) {
-  var z;
-  var w;
-  var hx = %_DoubleHi(x);
-  var ix = hx & 0x7fffffff;
-
-  if (ix < 0x3e300000) {  // |x| < 2^-28
-    if (((ix | %_DoubleLo(x)) | (returnTan + 1)) == 0) {
-      // x == 0 && returnTan = -1
-      return 1 / MathAbs(x);
-    } else {
-      if (returnTan == 1) {
-        return x;
-      } else {
-        // Compute -1/(x + y) carefully
-        var w = x + y;
-        var z = %_ConstructDouble(%_DoubleHi(w), 0);
-        var v = y - (z - x);
-        var a = -1 / w;
-        var t = %_ConstructDouble(%_DoubleHi(a), 0);
-        var s = 1 + t * z;
-        return t + a * (s + t * v);
-      }
-    }
-  }
-  if (ix >= 0x3fe59428) {  // |x| > .6744
-    if (x < 0) {
-      x = -x;
-      y = -y;
-    }
-    z = PIO4 - x;
-    w = PIO4LO - y;
-    x = z + w;
-    y = 0;
-  }
-  z = x * x;
-  w = z * z;
-
-  // Break x^5 * (T1 + x^2*T2 + ...) into
-  // x^5 * (T1 + x^4*T3 + ... + x^20*T11) +
-  // x^5 * (x^2 * (T2 + x^4*T4 + ... + x^22*T12))
-  var r = KTAN(1) + w * (KTAN(3) + w * (KTAN(5) +
-                    w * (KTAN(7) + w * (KTAN(9) + w * KTAN(11)))));
-  var v = z * (KTAN(2) + w * (KTAN(4) + w * (KTAN(6) +
-                         w * (KTAN(8) + w * (KTAN(10) + w * KTAN(12))))));
-  var s = z * x;
-  r = y + z * (s * (r + v) + y);
-  r = r + KTAN(0) * s;
-  w = x + r;
-  if (ix >= 0x3fe59428) {
-    return (1 - ((hx >> 30) & 2)) *
-      (returnTan - 2.0 * (x - (w * w / (w + returnTan) - r)));
-  }
-  if (returnTan == 1) {
-    return w;
-  } else {
-    z = %_ConstructDouble(%_DoubleHi(w), 0);
-    v = r - (z - x);
-    var a = -1 / w;
-    var t = %_ConstructDouble(%_DoubleHi(a), 0);
-    s = 1 + t * z;
-    return t + a * (s + t * v);
-  }
-}
-
-function MathSinSlow(x) {
-  REMPIO2(x);
-  var sign = 1 - (n & 2);
-  if (n & 1) {
-    RETURN_KERNELCOS(y0, y1, * sign);
-  } else {
-    RETURN_KERNELSIN(y0, y1, * sign);
-  }
-}
-
-function MathCosSlow(x) {
-  REMPIO2(x);
-  if (n & 1) {
-    var sign = (n & 2) - 1;
-    RETURN_KERNELSIN(y0, y1, * sign);
-  } else {
-    var sign = 1 - (n & 2);
-    RETURN_KERNELCOS(y0, y1, * sign);
-  }
-}
-
-// ECMA 262 - 15.8.2.16
-function MathSin(x) {
-  x = x * 1;  // Convert to number.
-  if ((%_DoubleHi(x) & 0x7fffffff) <= 0x3fe921fb) {
-    // |x| < pi/4, approximately.  No reduction needed.
-    RETURN_KERNELSIN(x, 0, /* empty */);
-  }
-  return MathSinSlow(x);
-}
-
-// ECMA 262 - 15.8.2.7
-function MathCos(x) {
-  x = x * 1;  // Convert to number.
-  if ((%_DoubleHi(x) & 0x7fffffff) <= 0x3fe921fb) {
-    // |x| < pi/4, approximately.  No reduction needed.
-    RETURN_KERNELCOS(x, 0, /* empty */);
-  }
-  return MathCosSlow(x);
-}
-
-// ECMA 262 - 15.8.2.18
-function MathTan(x) {
-  x = x * 1;  // Convert to number.
-  if ((%_DoubleHi(x) & 0x7fffffff) <= 0x3fe921fb) {
-    // |x| < pi/4, approximately.  No reduction needed.
-    return KernelTan(x, 0, 1);
-  }
-  REMPIO2(x);
-  return KernelTan(y0, y1, (n & 1) ? -1 : 1);
-}
-
-// ES6 draft 09-27-13, section 20.2.2.20.
-// Math.log1p
-//
-// Method :
-//   1. Argument Reduction: find k and f such that
-//                      1+x = 2^k * (1+f),
-//         where  sqrt(2)/2 < 1+f < sqrt(2) .
-//
-//      Note. If k=0, then f=x is exact. However, if k!=0, then f
-//      may not be representable exactly. In that case, a correction
-//      term is need. Let u=1+x rounded. Let c = (1+x)-u, then
-//      log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),
-//      and add back the correction term c/u.
-//      (Note: when x > 2**53, one can simply return log(x))
-//
-//   2. Approximation of log1p(f).
-//      Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
-//            = 2s + 2/3 s**3 + 2/5 s**5 + .....,
-//            = 2s + s*R
-//      We use a special Reme algorithm on [0,0.1716] to generate
-//      a polynomial of degree 14 to approximate R The maximum error
-//      of this polynomial approximation is bounded by 2**-58.45. In
-//      other words,
-//                      2      4      6      8      10      12      14
-//          R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s  +Lp6*s  +Lp7*s
-//      (the values of Lp1 to Lp7 are listed in the program)
-//      and
-//          |      2          14          |     -58.45
-//          | Lp1*s +...+Lp7*s    -  R(z) | <= 2
-//          |                             |
-//      Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
-//      In order to guarantee error in log below 1ulp, we compute log
-//      by
-//              log1p(f) = f - (hfsq - s*(hfsq+R)).
-//
-//      3. Finally, log1p(x) = k*ln2 + log1p(f).
-//                           = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
-//         Here ln2 is split into two floating point number:
-//                      ln2_hi + ln2_lo,
-//         where n*ln2_hi is always exact for |n| < 2000.
-//
-// Special cases:
-//      log1p(x) is NaN with signal if x < -1 (including -INF) ;
-//      log1p(+INF) is +INF; log1p(-1) is -INF with signal;
-//      log1p(NaN) is that NaN with no signal.
-//
-// Accuracy:
-//      according to an error analysis, the error is always less than
-//      1 ulp (unit in the last place).
-//
-// Constants:
-//      Constants are found in fdlibm.cc. We assume the C++ compiler to convert
-//      from decimal to binary accurately enough to produce the intended values.
-//
-// Note: Assuming log() return accurate answer, the following
-//       algorithm can be used to compute log1p(x) to within a few ULP:
-//
-//              u = 1+x;
-//              if (u==1.0) return x ; else
-//                          return log(u)*(x/(u-1.0));
-//
-//       See HP-15C Advanced Functions Handbook, p.193.
-//
-const LN2_HI    = kMath[34];
-const LN2_LO    = kMath[35];
-const TWO54     = kMath[36];
-const TWO_THIRD = kMath[37];
-macro KLOG1P(x)
-(kMath[38+x])
-endmacro
-
-function MathLog1p(x) {
-  x = x * 1;  // Convert to number.
-  var hx = %_DoubleHi(x);
-  var ax = hx & 0x7fffffff;
-  var k = 1;
-  var f = x;
-  var hu = 1;
-  var c = 0;
-  var u = x;
-
-  if (hx < 0x3fda827a) {
-    // x < 0.41422
-    if (ax >= 0x3ff00000) {  // |x| >= 1
-      if (x === -1) {
-        return -INFINITY;  // log1p(-1) = -inf
-      } else {
-        return NAN;  // log1p(x<-1) = NaN
-      }
-    } else if (ax < 0x3c900000)  {
-      // For |x| < 2^-54 we can return x.
-      return x;
-    } else if (ax < 0x3e200000) {
-      // For |x| < 2^-29 we can use a simple two-term Taylor series.
-      return x - x * x * 0.5;
-    }
-
-    if ((hx > 0) || (hx <= -0x402D413D)) {  // (int) 0xbfd2bec3 = -0x402d413d
-      // -.2929 < x < 0.41422
-      k = 0;
-    }
-  }
-
-  // Handle Infinity and NAN
-  if (hx >= 0x7ff00000) return x;
-
-  if (k !== 0) {
-    if (hx < 0x43400000) {
-      // x < 2^53
-      u = 1 + x;
-      hu = %_DoubleHi(u);
-      k = (hu >> 20) - 1023;
-      c = (k > 0) ? 1 - (u - x) : x - (u - 1);
-      c = c / u;
-    } else {
-      hu = %_DoubleHi(u);
-      k = (hu >> 20) - 1023;
-    }
-    hu = hu & 0xfffff;
-    if (hu < 0x6a09e) {
-      u = %_ConstructDouble(hu | 0x3ff00000, %_DoubleLo(u));  // Normalize u.
-    } else {
-      ++k;
-      u = %_ConstructDouble(hu | 0x3fe00000, %_DoubleLo(u));  // Normalize u/2.
-      hu = (0x00100000 - hu) >> 2;
-    }
-    f = u - 1;
-  }
-
-  var hfsq = 0.5 * f * f;
-  if (hu === 0) {
-    // |f| < 2^-20;
-    if (f === 0) {
-      if (k === 0) {
-        return 0.0;
-      } else {
-        return k * LN2_HI + (c + k * LN2_LO);
-      }
-    }
-    var R = hfsq * (1 - TWO_THIRD * f);
-    if (k === 0) {
-      return f - R;
-    } else {
-      return k * LN2_HI - ((R - (k * LN2_LO + c)) - f);
-    }
-  }
-
-  var s = f / (2 + f);
-  var z = s * s;
-  var R = z * (KLOG1P(0) + z * (KLOG1P(1) + z *
-              (KLOG1P(2) + z * (KLOG1P(3) + z *
-              (KLOG1P(4) + z * (KLOG1P(5) + z * KLOG1P(6)))))));
-  if (k === 0) {
-    return f - (hfsq - s * (hfsq + R));
-  } else {
-    return k * LN2_HI - ((hfsq - (s * (hfsq + R) + (k * LN2_LO + c))) - f);
-  }
-}
-
-// ES6 draft 09-27-13, section 20.2.2.14.
-// Math.expm1
-// Returns exp(x)-1, the exponential of x minus 1.
-//
-// Method
-//   1. Argument reduction:
-//      Given x, find r and integer k such that
-//
-//               x = k*ln2 + r,  |r| <= 0.5*ln2 ~ 0.34658
-//
-//      Here a correction term c will be computed to compensate
-//      the error in r when rounded to a floating-point number.
-//
-//   2. Approximating expm1(r) by a special rational function on
-//      the interval [0,0.34658]:
-//      Since
-//          r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
-//      we define R1(r*r) by
-//          r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
-//      That is,
-//          R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
-//                   = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
-//                   = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
-//      We use a special Remes algorithm on [0,0.347] to generate
-//      a polynomial of degree 5 in r*r to approximate R1. The
-//      maximum error of this polynomial approximation is bounded
-//      by 2**-61. In other words,
-//          R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
-//      where   Q1  =  -1.6666666666666567384E-2,
-//              Q2  =   3.9682539681370365873E-4,
-//              Q3  =  -9.9206344733435987357E-6,
-//              Q4  =   2.5051361420808517002E-7,
-//              Q5  =  -6.2843505682382617102E-9;
-//      (where z=r*r, and the values of Q1 to Q5 are listed below)
-//      with error bounded by
-//          |                  5           |     -61
-//          | 1.0+Q1*z+...+Q5*z   -  R1(z) | <= 2
-//          |                              |
-//
-//      expm1(r) = exp(r)-1 is then computed by the following
-//      specific way which minimize the accumulation rounding error:
-//                             2     3
-//                            r     r    [ 3 - (R1 + R1*r/2)  ]
-//            expm1(r) = r + --- + --- * [--------------------]
-//                            2     2    [ 6 - r*(3 - R1*r/2) ]
-//
-//      To compensate the error in the argument reduction, we use
-//              expm1(r+c) = expm1(r) + c + expm1(r)*c
-//                         ~ expm1(r) + c + r*c
-//      Thus c+r*c will be added in as the correction terms for
-//      expm1(r+c). Now rearrange the term to avoid optimization
-//      screw up:
-//                      (      2                                    2 )
-//                      ({  ( r    [ R1 -  (3 - R1*r/2) ]  )  }    r  )
-//       expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
-//                      ({  ( 2    [ 6 - r*(3 - R1*r/2) ]  )  }    2  )
-//                      (                                             )
-//
-//                 = r - E
-//   3. Scale back to obtain expm1(x):
-//      From step 1, we have
-//         expm1(x) = either 2^k*[expm1(r)+1] - 1
-//                  = or     2^k*[expm1(r) + (1-2^-k)]
-//   4. Implementation notes:
-//      (A). To save one multiplication, we scale the coefficient Qi
-//           to Qi*2^i, and replace z by (x^2)/2.
-//      (B). To achieve maximum accuracy, we compute expm1(x) by
-//        (i)   if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
-//        (ii)  if k=0, return r-E
-//        (iii) if k=-1, return 0.5*(r-E)-0.5
-//        (iv)  if k=1 if r < -0.25, return 2*((r+0.5)- E)
-//                     else          return  1.0+2.0*(r-E);
-//        (v)   if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
-//        (vi)  if k <= 20, return 2^k((1-2^-k)-(E-r)), else
-//        (vii) return 2^k(1-((E+2^-k)-r))
-//
-// Special cases:
-//      expm1(INF) is INF, expm1(NaN) is NaN;
-//      expm1(-INF) is -1, and
-//      for finite argument, only expm1(0)=0 is exact.
-//
-// Accuracy:
-//      according to an error analysis, the error is always less than
-//      1 ulp (unit in the last place).
-//
-// Misc. info.
-//      For IEEE double
-//          if x > 7.09782712893383973096e+02 then expm1(x) overflow
-//
-const KEXPM1_OVERFLOW = kMath[45];
-const INVLN2          = kMath[46];
-macro KEXPM1(x)
-(kMath[47+x])
-endmacro
-
-function MathExpm1(x) {
-  x = x * 1;  // Convert to number.
-  var y;
-  var hi;
-  var lo;
-  var k;
-  var t;
-  var c;
-
-  var hx = %_DoubleHi(x);
-  var xsb = hx & 0x80000000;     // Sign bit of x
-  var y = (xsb === 0) ? x : -x;  // y = |x|
-  hx &= 0x7fffffff;              // High word of |x|
-
-  // Filter out huge and non-finite argument
-  if (hx >= 0x4043687a) {     // if |x| ~=> 56 * ln2
-    if (hx >= 0x40862e42) {   // if |x| >= 709.78
-      if (hx >= 0x7ff00000) {
-        // expm1(inf) = inf; expm1(-inf) = -1; expm1(nan) = nan;
-        return (x === -INFINITY) ? -1 : x;
-      }
-      if (x > KEXPM1_OVERFLOW) return INFINITY;  // Overflow
-    }
-    if (xsb != 0) return -1;  // x < -56 * ln2, return -1.
-  }
-
-  // Argument reduction
-  if (hx > 0x3fd62e42) {    // if |x| > 0.5 * ln2
-    if (hx < 0x3ff0a2b2) {  // and |x| < 1.5 * ln2
-      if (xsb === 0) {
-        hi = x - LN2_HI;
-        lo = LN2_LO;
-        k = 1;
-      } else {
-        hi = x + LN2_HI;
-        lo = -LN2_LO;
-        k = -1;
-      }
-    } else {
-      k = (INVLN2 * x + ((xsb === 0) ? 0.5 : -0.5)) | 0;
-      t = k;
-      // t * ln2_hi is exact here.
-      hi = x - t * LN2_HI;
-      lo = t * LN2_LO;
-    }
-    x = hi - lo;
-    c = (hi - x) - lo;
-  } else if (hx < 0x3c900000)	{
-    // When |x| < 2^-54, we can return x.
-    return x;
-  } else {
-    // Fall through.
-    k = 0;
-  }
-
-  // x is now in primary range
-  var hfx = 0.5 * x;
-  var hxs = x * hfx;
-  var r1 = 1 + hxs * (KEXPM1(0) + hxs * (KEXPM1(1) + hxs *
-                     (KEXPM1(2) + hxs * (KEXPM1(3) + hxs * KEXPM1(4)))));
-  t = 3 - r1 * hfx;
-  var e = hxs * ((r1 - t) / (6 - x * t));
-  if (k === 0) {  // c is 0
-    return x - (x*e - hxs);
-  } else {
-    e = (x * (e - c) - c);
-    e -= hxs;
-    if (k === -1) return 0.5 * (x - e) - 0.5;
-    if (k === 1) {
-      if (x < -0.25) return -2 * (e - (x + 0.5));
-      return 1 + 2 * (x - e);
-    }
-
-    if (k <= -2 || k > 56) {
-      // suffice to return exp(x) + 1
-      y = 1 - (e - x);
-      // Add k to y's exponent
-      y = %_ConstructDouble(%_DoubleHi(y) + (k << 20), %_DoubleLo(y));
-      return y - 1;
-    }
-    if (k < 20) {
-      // t = 1 - 2^k
-      t = %_ConstructDouble(0x3ff00000 - (0x200000 >> k), 0);
-      y = t - (e - x);
-      // Add k to y's exponent
-      y = %_ConstructDouble(%_DoubleHi(y) + (k << 20), %_DoubleLo(y));
-    } else {
-      // t = 2^-k
-      t = %_ConstructDouble((0x3ff - k) << 20, 0);
-      y = x - (e + t);
-      y += 1;
-      // Add k to y's exponent
-      y = %_ConstructDouble(%_DoubleHi(y) + (k << 20), %_DoubleLo(y));
-    }
-  }
-  return y;
-}
-
-
-// ES6 draft 09-27-13, section 20.2.2.30.
-// Math.sinh
-// Method :
-// mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2
-//      1. Replace x by |x| (sinh(-x) = -sinh(x)).
-//      2.
-//                                                  E + E/(E+1)
-//          0        <= x <= 22     :  sinh(x) := --------------, E=expm1(x)
-//                                                      2
-//
-//          22       <= x <= lnovft :  sinh(x) := exp(x)/2
-//          lnovft   <= x <= ln2ovft:  sinh(x) := exp(x/2)/2 * exp(x/2)
-//          ln2ovft  <  x           :  sinh(x) := x*shuge (overflow)
-//
-// Special cases:
-//      sinh(x) is |x| if x is +Infinity, -Infinity, or NaN.
-//      only sinh(0)=0 is exact for finite x.
-//
-const KSINH_OVERFLOW = kMath[52];
-const TWO_M28 = 3.725290298461914e-9;  // 2^-28, empty lower half
-const LOG_MAXD = 709.7822265625;  // 0x40862e42 00000000, empty lower half
-
-function MathSinh(x) {
-  x = x * 1;  // Convert to number.
-  var h = (x < 0) ? -0.5 : 0.5;
-  // |x| in [0, 22]. return sign(x)*0.5*(E+E/(E+1))
-  var ax = MathAbs(x);
-  if (ax < 22) {
-    // For |x| < 2^-28, sinh(x) = x
-    if (ax < TWO_M28) return x;
-    var t = MathExpm1(ax);
-    if (ax < 1) return h * (2 * t - t * t / (t + 1));
-    return h * (t + t / (t + 1));
-  }
-  // |x| in [22, log(maxdouble)], return 0.5 * exp(|x|)
-  if (ax < LOG_MAXD) return h * MathExp(ax);
-  // |x| in [log(maxdouble), overflowthreshold]
-  // overflowthreshold = 710.4758600739426
-  if (ax <= KSINH_OVERFLOW) {
-    var w = MathExp(0.5 * ax);
-    var t = h * w;
-    return t * w;
-  }
-  // |x| > overflowthreshold or is NaN.
-  // Return Infinity of the appropriate sign or NaN.
-  return x * INFINITY;
-}
-
-
-// ES6 draft 09-27-13, section 20.2.2.12.
-// Math.cosh
-// Method :
-// mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2
-//      1. Replace x by |x| (cosh(x) = cosh(-x)).
-//      2.
-//                                                      [ exp(x) - 1 ]^2
-//          0        <= x <= ln2/2  :  cosh(x) := 1 + -------------------
-//                                                         2*exp(x)
-//
-//                                                 exp(x) + 1/exp(x)
-//          ln2/2    <= x <= 22     :  cosh(x) := -------------------
-//                                                        2
-//          22       <= x <= lnovft :  cosh(x) := exp(x)/2
-//          lnovft   <= x <= ln2ovft:  cosh(x) := exp(x/2)/2 * exp(x/2)
-//          ln2ovft  <  x           :  cosh(x) := huge*huge (overflow)
-//
-// Special cases:
-//      cosh(x) is |x| if x is +INF, -INF, or NaN.
-//      only cosh(0)=1 is exact for finite x.
-//
-const KCOSH_OVERFLOW = kMath[52];
-
-function MathCosh(x) {
-  x = x * 1;  // Convert to number.
-  var ix = %_DoubleHi(x) & 0x7fffffff;
-  // |x| in [0,0.5*log2], return 1+expm1(|x|)^2/(2*exp(|x|))
-  if (ix < 0x3fd62e43) {
-    var t = MathExpm1(MathAbs(x));
-    var w = 1 + t;
-    // For |x| < 2^-55, cosh(x) = 1
-    if (ix < 0x3c800000) return w;
-    return 1 + (t * t) / (w + w);
-  }
-  // |x| in [0.5*log2, 22], return (exp(|x|)+1/exp(|x|)/2
-  if (ix < 0x40360000) {
-    var t = MathExp(MathAbs(x));
-    return 0.5 * t + 0.5 / t;
-  }
-  // |x| in [22, log(maxdouble)], return half*exp(|x|)
-  if (ix < 0x40862e42) return 0.5 * MathExp(MathAbs(x));
-  // |x| in [log(maxdouble), overflowthreshold]
-  if (MathAbs(x) <= KCOSH_OVERFLOW) {
-    var w = MathExp(0.5 * MathAbs(x));
-    var t = 0.5 * w;
-    return t * w;
-  }
-  if (NUMBER_IS_NAN(x)) return x;
-  // |x| > overflowthreshold.
-  return INFINITY;
-}
diff --git a/tools/android-sync.sh b/tools/android-sync.sh
index 460e92d..4acb1cc 100755
--- a/tools/android-sync.sh
+++ b/tools/android-sync.sh
@@ -88,6 +88,7 @@
 echo -n "sync to $ANDROID_V8/$OUTDIR/$ARCH_MODE"
 sync_file "$OUTDIR/$ARCH_MODE/cctest"
 sync_file "$OUTDIR/$ARCH_MODE/d8"
+sync_file "$OUTDIR/$ARCH_MODE/unittests"
 echo ""
 echo -n "sync to $ANDROID_V8/tools"
 sync_file tools/consarray.js
diff --git a/tools/check-name-clashes.py b/tools/check-name-clashes.py
index e448930..89a7dee 100755
--- a/tools/check-name-clashes.py
+++ b/tools/check-name-clashes.py
@@ -8,135 +8,53 @@
 import re
 import sys
 
-FILENAME = "src/runtime.cc"
-FUNCTION = re.compile("^RUNTIME_FUNCTION\(Runtime_(\w+)")
-FUNCTIONEND = "}\n"
-MACRO = re.compile(r"^#define ([^ ]+)\(([^)]*)\) *([^\\]*)\\?\n$")
-FIRST_WORD = re.compile("^\s*(.*?)[\s({\[]")
-
-# Expand these macros, they define further runtime functions.
-EXPAND_MACROS = [
-  "BUFFER_VIEW_GETTER",
-  "DATA_VIEW_GETTER",
-  "DATA_VIEW_SETTER",
-  "ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION",
-  "FIXED_TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION",
-  "RUNTIME_UNARY_MATH",
-  "TYPED_ARRAYS_CHECK_RUNTIME_FUNCTION",
-]
+FILENAME = "src/runtime/runtime.h"
+LISTHEAD = re.compile(r"#define\s+(\w+LIST\w*)\((\w+)\)")
+LISTBODY = re.compile(r".*\\$")
+BLACKLIST = ['INLINE_FUNCTION_LIST']
 
 
 class Function(object):
   def __init__(self, match):
-    self.name = match.group(1)
+    self.name = match.group(1).strip()
+
+def ListMacroRe(list):
+  macro = LISTHEAD.match(list[0]).group(2)
+  re_string = "\s*%s\((\w+)" % macro
+  return re.compile(re_string)
 
 
-class Macro(object):
-  def __init__(self, match):
-    self.name = match.group(1)
-    self.args = [s.strip() for s in match.group(2).split(",")]
-    self.lines = []
-    self.indentation = 0
-    self.AddLine(match.group(3))
-
-  def AddLine(self, line):
-    if not line: return
-    if not self.lines:
-      # This is the first line, detect indentation.
-      self.indentation = len(line) - len(line.lstrip())
-    line = line.rstrip("\\\n ")
-    if not line: return
-    assert len(line[:self.indentation].strip()) == 0, \
-        ("expected whitespace: '%s', full line: '%s'" %
-         (line[:self.indentation], line))
-    line = line[self.indentation:]
-    if not line: return
-    self.lines.append(line + "\n")
-
-  def Finalize(self):
-    for arg in self.args:
-      pattern = re.compile(r"(##|\b)%s(##|\b)" % arg)
-      for i in range(len(self.lines)):
-        self.lines[i] = re.sub(pattern, "%%(%s)s" % arg, self.lines[i])
-
-  def FillIn(self, arg_values):
-    filler = {}
-    assert len(arg_values) == len(self.args)
-    for i in range(len(self.args)):
-      filler[self.args[i]] = arg_values[i]
-    result = []
-    for line in self.lines:
-      result.append(line % filler)
-    return result
-
-
-def ReadFileAndExpandMacros(filename):
-  found_macros = {}
-  expanded_lines = []
+def FindLists(filename):
+  lists = []
+  current_list = []
+  mode = "SEARCHING"
   with open(filename, "r") as f:
-    found_macro = None
     for line in f:
-      if found_macro is not None:
-        found_macro.AddLine(line)
-        if not line.endswith("\\\n"):
-          found_macro.Finalize()
-          found_macro = None
-        continue
-
-      match = MACRO.match(line)
-      if match:
-        found_macro = Macro(match)
-        if found_macro.name in EXPAND_MACROS:
-          found_macros[found_macro.name] = found_macro
-        else:
-          found_macro = None
-        continue
-
-      match = FIRST_WORD.match(line)
-      if match:
-        first_word = match.group(1)
-        if first_word in found_macros:
-          MACRO_CALL = re.compile("%s\(([^)]*)\)" % first_word)
-          match = MACRO_CALL.match(line)
-          assert match
-          args = [s.strip() for s in match.group(1).split(",")]
-          expanded_lines += found_macros[first_word].FillIn(args)
-          continue
-
-      expanded_lines.append(line)
-  return expanded_lines
+      if mode == "SEARCHING":
+        match = LISTHEAD.match(line)
+        if match and match.group(1) not in BLACKLIST:
+          mode = "APPENDING"
+          current_list.append(line)
+      else:
+        current_list.append(line)
+        match = LISTBODY.match(line)
+        if not match:
+          mode = "SEARCHING"
+          lists.append(current_list)
+          current_list = []
+  return lists
 
 
 # Detects runtime functions by parsing FILENAME.
 def FindRuntimeFunctions():
   functions = []
-  expanded_lines = ReadFileAndExpandMacros(FILENAME)
-  function = None
-  partial_line = ""
-  for line in expanded_lines:
-    # Multi-line definition support, ignoring macros.
-    if line.startswith("RUNTIME_FUNCTION") and not line.endswith("{\n"):
-      if line.endswith("\\\n"): continue
-      partial_line = line.rstrip()
-      continue
-    if partial_line:
-      partial_line += " " + line.strip()
-      if partial_line.endswith("{"):
-        line = partial_line
-        partial_line = ""
-      else:
-        continue
-
-    match = FUNCTION.match(line)
-    if match:
-      function = Function(match)
-      continue
-    if function is None: continue
-
-    if line == FUNCTIONEND:
-      if function is not None:
-        functions.append(function)
-        function = None
+  lists = FindLists(FILENAME)
+  for list in lists:
+    function_re = ListMacroRe(list)
+    for line in list:
+      match = function_re.match(line)
+      if match:
+        functions.append(Function(match))
   return functions
 
 
diff --git a/tools/codemap.js b/tools/codemap.js
index 129179e..fa6c36b 100644
--- a/tools/codemap.js
+++ b/tools/codemap.js
@@ -258,11 +258,13 @@
  *
  * @param {number} size Code entry size in bytes.
  * @param {string} opt_name Code entry name.
+ * @param {string} opt_type Code entry type, e.g. SHARED_LIB, CPP.
  * @constructor
  */
-CodeMap.CodeEntry = function(size, opt_name) {
+CodeMap.CodeEntry = function(size, opt_name, opt_type) {
   this.size = size;
   this.name = opt_name || '';
+  this.type = opt_type || '';
   this.nameUpdated_ = false;
 };
 
diff --git a/tools/find-commit-for-patch.py b/tools/find-commit-for-patch.py
new file mode 100755
index 0000000..657826c
--- /dev/null
+++ b/tools/find-commit-for-patch.py
@@ -0,0 +1,93 @@
+#!/usr/bin/env python
+# Copyright 2014 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import subprocess
+import sys
+
+
+def GetArgs():
+  parser = argparse.ArgumentParser(
+      description="Finds a commit that a given patch can be applied to. "
+                  "Does not actually apply the patch or modify your checkout "
+                  "in any way.")
+  parser.add_argument("patch_file", help="Patch file to match")
+  parser.add_argument(
+      "--branch", "-b", default="origin/master", type=str,
+      help="Git tree-ish where to start searching for commits, "
+           "default: %(default)s")
+  parser.add_argument(
+      "--limit", "-l", default=500, type=int,
+      help="Maximum number of commits to search, default: %(default)s")
+  parser.add_argument(
+      "--verbose", "-v", default=False, action="store_true",
+      help="Print verbose output for your entertainment")
+  return parser.parse_args()
+
+
+def FindFilesInPatch(patch_file):
+  files = {}
+  next_file = ""
+  with open(patch_file) as patch:
+    for line in patch:
+      if line.startswith("diff --git "):
+        # diff --git a/src/objects.cc b/src/objects.cc
+        words = line.split()
+        assert words[2].startswith("a/") and len(words[2]) > 2
+        next_file = words[2][2:]
+      elif line.startswith("index "):
+        # index add3e61..d1bbf6a 100644
+        hashes = line.split()[1]
+        old_hash = hashes.split("..")[0]
+        if old_hash.startswith("0000000"): continue  # Ignore new files.
+        files[next_file] = old_hash
+  return files
+
+
+def GetGitCommitHash(treeish):
+  cmd = ["git", "log", "-1", "--format=%H", treeish]
+  return subprocess.check_output(cmd).strip()
+
+
+def CountMatchingFiles(commit, files):
+  matched_files = 0
+  # Calling out to git once and parsing the result Python-side is faster
+  # than calling 'git ls-tree' for every file.
+  cmd = ["git", "ls-tree", "-r", commit] + [f for f in files]
+  output = subprocess.check_output(cmd)
+  for line in output.splitlines():
+    # 100644 blob c6d5daaa7d42e49a653f9861224aad0a0244b944      src/objects.cc
+    _, _, actual_hash, filename = line.split()
+    expected_hash = files[filename]
+    if actual_hash.startswith(expected_hash): matched_files += 1
+  return matched_files
+
+
+def FindFirstMatchingCommit(start, files, limit, verbose):
+  commit = GetGitCommitHash(start)
+  num_files = len(files)
+  if verbose: print(">>> Found %d files modified by patch." % num_files)
+  for _ in range(limit):
+    matched_files = CountMatchingFiles(commit, files)
+    if verbose: print("Commit %s matched %d files" % (commit, matched_files))
+    if matched_files == num_files:
+      return commit
+    commit = GetGitCommitHash("%s^" % commit)
+  print("Sorry, no matching commit found. "
+        "Try running 'git fetch', specifying the correct --branch, "
+        "and/or setting a higher --limit.")
+  sys.exit(1)
+
+
+if __name__ == "__main__":
+  args = GetArgs()
+  files = FindFilesInPatch(args.patch_file)
+  commit = FindFirstMatchingCommit(args.branch, files, args.limit, args.verbose)
+  if args.verbose:
+    print(">>> Matching commit: %s" % commit)
+    print(subprocess.check_output(["git", "log", "-1", commit]))
+    print(">>> Kthxbai.")
+  else:
+    print(commit)
diff --git a/tools/find_depot_tools.py b/tools/find_depot_tools.py
new file mode 100644
index 0000000..95ae9e8
--- /dev/null
+++ b/tools/find_depot_tools.py
@@ -0,0 +1,40 @@
+# Copyright 2014 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""Small utility function to find depot_tools and add it to the python path.
+"""
+
+import os
+import sys
+
+
+def directory_really_is_depot_tools(directory):
+  return os.path.isfile(os.path.join(directory, 'gclient.py'))
+
+
+def add_depot_tools_to_path():
+  """Search for depot_tools and add it to sys.path."""
+  # First look if depot_tools is already in PYTHONPATH.
+  for i in sys.path:
+    if i.rstrip(os.sep).endswith('depot_tools'):
+      if directory_really_is_depot_tools(i):
+        return i
+
+  # Then look if depot_tools is in PATH, common case.
+  for i in os.environ['PATH'].split(os.pathsep):
+    if i.rstrip(os.sep).endswith('depot_tools'):
+      if directory_really_is_depot_tools(i):
+        sys.path.insert(0, i.rstrip(os.sep))
+        return i
+  # Rare case, it's not even in PATH, look upward up to root.
+  root_dir = os.path.dirname(os.path.abspath(__file__))
+  previous_dir = os.path.abspath(__file__)
+  while root_dir and root_dir != previous_dir:
+    if directory_really_is_depot_tools(os.path.join(root_dir, 'depot_tools')):
+      i = os.path.join(root_dir, 'depot_tools')
+      sys.path.insert(0, i)
+      return i
+    previous_dir = root_dir
+    root_dir = os.path.dirname(root_dir)
+  print >> sys.stderr, 'Failed to find depot_tools'
+  return None
diff --git a/tools/gdbinit b/tools/gdbinit
index 20cdff6..8d0345a 100644
--- a/tools/gdbinit
+++ b/tools/gdbinit
@@ -20,9 +20,27 @@
 Usage: jco pc
 end
 
+# Print DescriptorArray.
+define jda
+print ((v8::internal::DescriptorArray*)($arg0))->Print()
+end
+document jda
+Print a v8 DescriptorArray object
+Usage: jda tagged_ptr
+end
+
+# Print TransitionArray.
+define jta
+print ((v8::internal::TransitionArray*)($arg0))->Print()
+end
+document jta
+Print a v8 TransitionArray object
+Usage: jta tagged_ptr
+end
+
 # Print JavaScript stack trace.
 define jst
-print v8::internal::Isolate::Current()->PrintStack(stdout)
+print v8::internal::Isolate::Current()->PrintStack((FILE*) stdout)
 end
 document jst
 Print the current JavaScript stack trace
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index c63cd94..696434d 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -164,7 +164,6 @@
         '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
         '<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
         '<(INTERMEDIATE_DIR)/snapshot.cc',
-        '../../src/snapshot-common.cc',
       ],
       'actions': [
         {
@@ -206,7 +205,6 @@
       'sources': [
         '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
         '<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
-        '../../src/snapshot-common.cc',
         '../../src/snapshot-empty.cc',
       ],
       'conditions': [
@@ -229,89 +227,105 @@
       'target_name': 'v8_external_snapshot',
       'type': 'static_library',
       'conditions': [
-        ['want_separate_host_toolset==1', {
-          'toolsets': ['host', 'target'],
-          'dependencies': [
-            'mksnapshot#host',
-            'js2c#host',
-            'natives_blob',
-        ]}, {
-          'toolsets': ['target'],
-          'dependencies': [
-            'mksnapshot',
-            'js2c',
-            'natives_blob',
-          ],
-        }],
-        ['component=="shared_library"', {
-          'defines': [
-            'V8_SHARED',
-            'BUILDING_V8_SHARED',
-          ],
-          'direct_dependent_settings': {
-            'defines': [
-              'V8_SHARED',
-              'USING_V8_SHARED',
-            ],
-          },
-        }],
-      ],
-      'dependencies': [
-        'v8_base',
-      ],
-      'include_dirs+': [
-        '../..',
-      ],
-      'sources': [
-        '../../src/natives-external.cc',
-        '../../src/snapshot-external.cc',
-      ],
-      'actions': [
-        {
-          'action_name': 'run_mksnapshot (external)',
-          'inputs': [
-            '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)',
-          ],
+        [ 'v8_use_external_startup_data==1', {
           'conditions': [
             ['want_separate_host_toolset==1', {
-              'target_conditions': [
-                ['_toolset=="host"', {
-                  'outputs': [
-                    '<(INTERMEDIATE_DIR)/snapshot.cc',
-                    '<(PRODUCT_DIR)/snapshot_blob_host.bin',
+              'toolsets': ['host', 'target'],
+              'dependencies': [
+                'mksnapshot#host',
+                'js2c#host',
+                'natives_blob',
+            ]}, {
+              'toolsets': ['target'],
+              'dependencies': [
+                'mksnapshot',
+                'js2c',
+                'natives_blob',
+              ],
+            }],
+            ['component=="shared_library"', {
+              'defines': [
+                'V8_SHARED',
+                'BUILDING_V8_SHARED',
+              ],
+              'direct_dependent_settings': {
+                'defines': [
+                  'V8_SHARED',
+                  'USING_V8_SHARED',
+                ],
+              },
+            }],
+          ],
+          'dependencies': [
+            'v8_base',
+          ],
+          'include_dirs+': [
+            '../..',
+          ],
+          'sources': [
+            '../../src/natives-external.cc',
+            '../../src/snapshot-external.cc',
+          ],
+          'actions': [
+            {
+              'action_name': 'run_mksnapshot (external)',
+              'inputs': [
+                '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)mksnapshot<(EXECUTABLE_SUFFIX)',
+              ],
+              'variables': {
+                'mksnapshot_flags': [
+                  '--log-snapshot-positions',
+                  '--logfile', '<(INTERMEDIATE_DIR)/snapshot.log',
+                ],
+                'conditions': [
+                  ['v8_random_seed!=0', {
+                    'mksnapshot_flags': ['--random-seed', '<(v8_random_seed)'],
+                  }],
+                ],
+              },
+              'conditions': [
+                ['want_separate_host_toolset==1', {
+                  'target_conditions': [
+                    ['_toolset=="host"', {
+                      'outputs': [
+                        '<(INTERMEDIATE_DIR)/snapshot.cc',
+                        '<(PRODUCT_DIR)/snapshot_blob_host.bin',
+                      ],
+                      'action': [
+                        '<@(_inputs)',
+                        '<@(mksnapshot_flags)',
+                        '<@(INTERMEDIATE_DIR)/snapshot.cc',
+                        '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob_host.bin',
+                      ],
+                    }, {
+                      'outputs': [
+                        '<(INTERMEDIATE_DIR)/snapshot.cc',
+                        '<(PRODUCT_DIR)/snapshot_blob.bin',
+                      ],
+                      'action': [
+                        '<@(_inputs)',
+                        '<@(mksnapshot_flags)',
+                        '<@(INTERMEDIATE_DIR)/snapshot.cc',
+                        '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin',
+                      ],
+                    }],
                   ],
                 }, {
                   'outputs': [
                     '<(INTERMEDIATE_DIR)/snapshot.cc',
                     '<(PRODUCT_DIR)/snapshot_blob.bin',
                   ],
+                  'action': [
+                    '<@(_inputs)',
+                    '<@(mksnapshot_flags)',
+                    '<@(INTERMEDIATE_DIR)/snapshot.cc',
+                    '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin',
+                  ],
                 }],
               ],
-            }, {
-              'outputs': [
-                '<(INTERMEDIATE_DIR)/snapshot.cc',
-                '<(PRODUCT_DIR)/snapshot_blob.bin',
-              ],
-            }],
+            },
           ],
-          'variables': {
-            'mksnapshot_flags': [
-              '--log-snapshot-positions',
-              '--logfile', '<(INTERMEDIATE_DIR)/snapshot.log',
-            ],
-            'conditions': [
-              ['v8_random_seed!=0', {
-                'mksnapshot_flags': ['--random-seed', '<(v8_random_seed)'],
-              }],
-            ],
-          },
-          'action': [
-            '<@(_inputs)',
-            '<@(mksnapshot_flags)',
-            '<@(INTERMEDIATE_DIR)/snapshot.cc',
-            '--startup_blob', '<(PRODUCT_DIR)/snapshot_blob.bin',
-          ],
-        },
+        }],
       ],
     },
     {
@@ -343,18 +357,26 @@
         '../../src/assembler.h',
         '../../src/assert-scope.h',
         '../../src/assert-scope.cc',
+        '../../src/ast-this-access-visitor.cc',
+        '../../src/ast-this-access-visitor.h',
         '../../src/ast-value-factory.cc',
         '../../src/ast-value-factory.h',
+        '../../src/ast-numbering.cc',
+        '../../src/ast-numbering.h',
         '../../src/ast.cc',
         '../../src/ast.h',
         '../../src/background-parsing-task.cc',
         '../../src/background-parsing-task.h',
         '../../src/bailout-reason.cc',
         '../../src/bailout-reason.h',
+        '../../src/basic-block-profiler.cc',
+        '../../src/basic-block-profiler.h',
         '../../src/bignum-dtoa.cc',
         '../../src/bignum-dtoa.h',
         '../../src/bignum.cc',
         '../../src/bignum.h',
+        '../../src/bit-vector.cc',
+        '../../src/bit-vector.h',
         '../../src/bootstrapper.cc',
         '../../src/bootstrapper.h',
         '../../src/builtins.cc',
@@ -362,6 +384,7 @@
         '../../src/bytecodes-irregexp.h',
         '../../src/cached-powers.cc',
         '../../src/cached-powers.h',
+        '../../src/char-predicates.cc',
         '../../src/char-predicates-inl.h',
         '../../src/char-predicates.h',
         '../../src/checks.cc',
@@ -378,28 +401,37 @@
         '../../src/codegen.h',
         '../../src/compilation-cache.cc',
         '../../src/compilation-cache.h',
+        '../../src/compilation-statistics.cc',
+        '../../src/compilation-statistics.h',
         '../../src/compiler/access-builder.cc',
         '../../src/compiler/access-builder.h',
         '../../src/compiler/ast-graph-builder.cc',
         '../../src/compiler/ast-graph-builder.h',
+        '../../src/compiler/ast-loop-assignment-analyzer.cc',
+        '../../src/compiler/ast-loop-assignment-analyzer.h',
+        '../../src/compiler/basic-block-instrumentor.cc',
+        '../../src/compiler/basic-block-instrumentor.h',
         '../../src/compiler/change-lowering.cc',
         '../../src/compiler/change-lowering.h',
         '../../src/compiler/code-generator-impl.h',
         '../../src/compiler/code-generator.cc',
         '../../src/compiler/code-generator.h',
+        '../../src/compiler/common-node-cache.cc',
         '../../src/compiler/common-node-cache.h',
+        '../../src/compiler/common-operator-reducer.cc',
+        '../../src/compiler/common-operator-reducer.h',
         '../../src/compiler/common-operator.cc',
         '../../src/compiler/common-operator.h',
         '../../src/compiler/control-builders.cc',
         '../../src/compiler/control-builders.h',
+        '../../src/compiler/control-equivalence.h',
+        '../../src/compiler/control-reducer.cc',
+        '../../src/compiler/control-reducer.h',
+        '../../src/compiler/diamond.h',
         '../../src/compiler/frame.h',
         '../../src/compiler/gap-resolver.cc',
         '../../src/compiler/gap-resolver.h',
-        '../../src/compiler/generic-algorithm-inl.h',
         '../../src/compiler/generic-algorithm.h',
-        '../../src/compiler/generic-graph.h',
-        '../../src/compiler/generic-node-inl.h',
-        '../../src/compiler/generic-node.h',
         '../../src/compiler/graph-builder.cc',
         '../../src/compiler/graph-builder.h',
         '../../src/compiler/graph-inl.h',
@@ -427,18 +459,29 @@
         '../../src/compiler/js-graph.h',
         '../../src/compiler/js-inlining.cc',
         '../../src/compiler/js-inlining.h',
+        '../../src/compiler/js-intrinsic-builder.cc',
+        '../../src/compiler/js-intrinsic-builder.h',
+        '../../src/compiler/js-operator.cc',
         '../../src/compiler/js-operator.h',
         '../../src/compiler/js-typed-lowering.cc',
         '../../src/compiler/js-typed-lowering.h',
+        '../../src/compiler/jump-threading.cc',
+        '../../src/compiler/jump-threading.h',
         '../../src/compiler/linkage-impl.h',
         '../../src/compiler/linkage.cc',
         '../../src/compiler/linkage.h',
+        '../../src/compiler/load-elimination.cc',
+        '../../src/compiler/load-elimination.h',
+        '../../src/compiler/loop-analysis.cc',
+        '../../src/compiler/loop-analysis.h',
         '../../src/compiler/machine-operator-reducer.cc',
         '../../src/compiler/machine-operator-reducer.h',
         '../../src/compiler/machine-operator.cc',
         '../../src/compiler/machine-operator.h',
         '../../src/compiler/machine-type.cc',
         '../../src/compiler/machine-type.h',
+        '../../src/compiler/move-optimizer.cc',
+        '../../src/compiler/move-optimizer.h',
         '../../src/compiler/node-aux-data-inl.h',
         '../../src/compiler/node-aux-data.h',
         '../../src/compiler/node-cache.cc',
@@ -448,23 +491,31 @@
         '../../src/compiler/node-properties.h',
         '../../src/compiler/node.cc',
         '../../src/compiler/node.h',
+        '../../src/compiler/opcodes.cc',
         '../../src/compiler/opcodes.h',
-        '../../src/compiler/operator-properties-inl.h',
+        '../../src/compiler/operator-properties.cc',
         '../../src/compiler/operator-properties.h',
         '../../src/compiler/operator.cc',
         '../../src/compiler/operator.h',
-        '../../src/compiler/phi-reducer.h',
         '../../src/compiler/pipeline.cc',
         '../../src/compiler/pipeline.h',
+        '../../src/compiler/pipeline-statistics.cc',
+        '../../src/compiler/pipeline-statistics.h',
         '../../src/compiler/raw-machine-assembler.cc',
         '../../src/compiler/raw-machine-assembler.h',
         '../../src/compiler/register-allocator.cc',
         '../../src/compiler/register-allocator.h',
+        '../../src/compiler/register-allocator-verifier.cc',
+        '../../src/compiler/register-allocator-verifier.h',
+        '../../src/compiler/register-configuration.cc',
+        '../../src/compiler/register-configuration.h',
         '../../src/compiler/representation-change.h',
         '../../src/compiler/schedule.cc',
         '../../src/compiler/schedule.h',
         '../../src/compiler/scheduler.cc',
         '../../src/compiler/scheduler.h',
+        '../../src/compiler/select-lowering.cc',
+        '../../src/compiler/select-lowering.h',
         '../../src/compiler/simplified-lowering.cc',
         '../../src/compiler/simplified-lowering.h',
         '../../src/compiler/simplified-operator-reducer.cc',
@@ -479,6 +530,8 @@
         '../../src/compiler/value-numbering-reducer.h',
         '../../src/compiler/verifier.cc',
         '../../src/compiler/verifier.h',
+        '../../src/compiler/zone-pool.cc',
+        '../../src/compiler/zone-pool.h',
         '../../src/compiler.cc',
         '../../src/compiler.h',
         '../../src/contexts.cc',
@@ -491,8 +544,6 @@
         '../../src/cpu-profiler-inl.h',
         '../../src/cpu-profiler.cc',
         '../../src/cpu-profiler.h',
-        '../../src/data-flow.cc',
-        '../../src/data-flow.h',
         '../../src/date.cc',
         '../../src/date.h',
         '../../src/dateparser-inl.h',
@@ -531,7 +582,6 @@
         '../../src/factory.h',
         '../../src/fast-dtoa.cc',
         '../../src/fast-dtoa.h',
-        '../../src/feedback-slots.h',
         '../../src/field-index.h',
         '../../src/field-index-inl.h',
         '../../src/fixed-dtoa.cc',
@@ -582,8 +632,6 @@
         '../../src/heap/store-buffer-inl.h',
         '../../src/heap/store-buffer.cc',
         '../../src/heap/store-buffer.h',
-        '../../src/heap/sweeper-thread.h',
-        '../../src/heap/sweeper-thread.cc',
         '../../src/hydrogen-alias-analysis.h',
         '../../src/hydrogen-bce.cc',
         '../../src/hydrogen-bce.h',
@@ -666,6 +714,9 @@
         '../../src/jsregexp-inl.h',
         '../../src/jsregexp.cc',
         '../../src/jsregexp.h',
+	'../../src/layout-descriptor-inl.h',
+	'../../src/layout-descriptor.cc',
+	'../../src/layout-descriptor.h',
         '../../src/list-inl.h',
         '../../src/list.h',
         '../../src/lithium-allocator-inl.h',
@@ -731,8 +782,35 @@
         '../../src/rewriter.h',
         '../../src/runtime-profiler.cc',
         '../../src/runtime-profiler.h',
-        '../../src/runtime.cc',
-        '../../src/runtime.h',
+        '../../src/runtime/runtime-api.cc',
+        '../../src/runtime/runtime-array.cc',
+        '../../src/runtime/runtime-classes.cc',
+        '../../src/runtime/runtime-collections.cc',
+        '../../src/runtime/runtime-compiler.cc',
+        '../../src/runtime/runtime-date.cc',
+        '../../src/runtime/runtime-debug.cc',
+        '../../src/runtime/runtime-function.cc',
+        '../../src/runtime/runtime-generator.cc',
+        '../../src/runtime/runtime-i18n.cc',
+        '../../src/runtime/runtime-internal.cc',
+        '../../src/runtime/runtime-json.cc',
+        '../../src/runtime/runtime-literals.cc',
+        '../../src/runtime/runtime-liveedit.cc',
+        '../../src/runtime/runtime-maths.cc',
+        '../../src/runtime/runtime-numbers.cc',
+        '../../src/runtime/runtime-object.cc',
+        '../../src/runtime/runtime-observe.cc',
+        '../../src/runtime/runtime-proxy.cc',
+        '../../src/runtime/runtime-regexp.cc',
+        '../../src/runtime/runtime-scopes.cc',
+        '../../src/runtime/runtime-strings.cc',
+        '../../src/runtime/runtime-symbol.cc',
+        '../../src/runtime/runtime-test.cc',
+        '../../src/runtime/runtime-typedarray.cc',
+        '../../src/runtime/runtime-uri.cc',
+        '../../src/runtime/runtime-utils.h',
+        '../../src/runtime/runtime.cc',
+        '../../src/runtime/runtime.h',
         '../../src/safepoint-table.cc',
         '../../src/safepoint-table.h',
         '../../src/sampler.cc',
@@ -750,8 +828,11 @@
         '../../src/small-pointer-list.h',
         '../../src/smart-pointers.h',
         '../../src/snapshot.h',
+        '../../src/snapshot-common.cc',
         '../../src/snapshot-source-sink.cc',
         '../../src/snapshot-source-sink.h',
+        '../../src/string-builder.cc',
+        '../../src/string-builder.h',
         '../../src/string-search.cc',
         '../../src/string-search.h',
         '../../src/string-stream.cc',
@@ -780,8 +861,9 @@
         '../../src/unicode-inl.h',
         '../../src/unicode.cc',
         '../../src/unicode.h',
+        '../../src/unicode-decoder.cc',
+        '../../src/unicode-decoder.h',
         '../../src/unique.h',
-        '../../src/uri.h',
         '../../src/utils-inl.h',
         '../../src/utils.cc',
         '../../src/utils.h',
@@ -800,8 +882,8 @@
         '../../src/zone-inl.h',
         '../../src/zone.cc',
         '../../src/zone.h',
-        '../../third_party/fdlibm/fdlibm.cc',
-        '../../third_party/fdlibm/fdlibm.h',
+        '../../src/third_party/fdlibm/fdlibm.cc',
+        '../../src/third_party/fdlibm/fdlibm.h',
       ],
       'conditions': [
         ['want_separate_host_toolset==1', {
@@ -1014,6 +1096,10 @@
             '../../src/mips/regexp-macro-assembler-mips.cc',
             '../../src/mips/regexp-macro-assembler-mips.h',
             '../../src/mips/simulator-mips.cc',
+            '../../src/compiler/mips/code-generator-mips.cc',
+            '../../src/compiler/mips/instruction-codes-mips.h',
+            '../../src/compiler/mips/instruction-selector-mips.cc',
+            '../../src/compiler/mips/linkage-mips.cc',
             '../../src/ic/mips/access-compiler-mips.cc',
             '../../src/ic/mips/handler-compiler-mips.cc',
             '../../src/ic/mips/ic-mips.cc',
@@ -1052,6 +1138,10 @@
             '../../src/mips64/regexp-macro-assembler-mips64.cc',
             '../../src/mips64/regexp-macro-assembler-mips64.h',
             '../../src/mips64/simulator-mips64.cc',
+            '../../src/compiler/mips64/code-generator-mips64.cc',
+            '../../src/compiler/mips64/instruction-codes-mips64.h',
+            '../../src/compiler/mips64/instruction-selector-mips64.cc',
+            '../../src/compiler/mips64/linkage-mips64.cc',
             '../../src/ic/mips64/access-compiler-mips64.cc',
             '../../src/ic/mips64/handler-compiler-mips64.cc',
             '../../src/ic/mips64/ic-mips64.cc',
@@ -1087,10 +1177,6 @@
             '../../src/x64/macro-assembler-x64.h',
             '../../src/x64/regexp-macro-assembler-x64.cc',
             '../../src/x64/regexp-macro-assembler-x64.h',
-            '../../src/compiler/x64/code-generator-x64.cc',
-            '../../src/compiler/x64/instruction-codes-x64.h',
-            '../../src/compiler/x64/instruction-selector-x64.cc',
-            '../../src/compiler/x64/linkage-x64.cc',
             '../../src/ic/x64/access-compiler-x64.cc',
             '../../src/ic/x64/handler-compiler-x64.cc',
             '../../src/ic/x64/ic-x64.cc',
@@ -1098,18 +1184,14 @@
             '../../src/ic/x64/stub-cache-x64.cc',
           ],
         }],
-        ['OS=="linux"', {
-            'link_settings': {
-              'conditions': [
-                ['v8_compress_startup_data=="bz2"', {
-                  'libraries': [
-                    '-lbz2',
-                  ]
-                }],
-              ],
-            },
-          }
-        ],
+        ['v8_target_arch=="x64"', {
+          'sources': [
+            '../../src/compiler/x64/code-generator-x64.cc',
+            '../../src/compiler/x64/instruction-codes-x64.h',
+            '../../src/compiler/x64/instruction-selector-x64.cc',
+            '../../src/compiler/x64/linkage-x64.cc',
+          ],
+        }],
         ['OS=="win"', {
           'variables': {
             'gyp_generators': '<!(echo $GYP_GENERATORS)',
@@ -1185,6 +1267,9 @@
         '../../src/base/division-by-constant.cc',
         '../../src/base/division-by-constant.h',
         '../../src/base/flags.h',
+        '../../src/base/functional.cc',
+        '../../src/base/functional.h',
+        '../../src/base/iterator.h',
         '../../src/base/lazy-instance.h',
         '../../src/base/logging.cc',
         '../../src/base/logging.h',
@@ -1217,11 +1302,19 @@
           'toolsets': ['target'],
         }],
         ['OS=="linux"', {
-            'link_settings': {
-              'libraries': [
-                '-lrt'
-              ]
-            },
+            'conditions': [
+              ['nacl_target_arch=="none"', {
+                'link_settings': {
+                  'libraries': [
+                    '-lrt'
+                  ],
+                },
+              }, {
+                'defines': [
+                  'V8_LIBRT_NOT_AVAILABLE=1',
+                ],
+              }],
+            ],
             'sources': [
               '../../src/base/platform/platform-linux.cc',
               '../../src/base/platform/platform-posix.cc'
@@ -1349,7 +1442,7 @@
         ['OS=="solaris"', {
             'link_settings': {
               'libraries': [
-                '-lnsl',
+                '-lnsl -lrt',
             ]},
             'sources': [
               '../../src/base/platform/platform-solaris.cc',
@@ -1385,8 +1478,6 @@
                   'sources': [
                     '../../src/base/platform/platform-win32.cc',
                     '../../src/base/win32-headers.h',
-                    '../../src/base/win32-math.cc',
-                    '../../src/base/win32-math.h'
                   ],
                 }],
               ],
@@ -1397,8 +1488,6 @@
               'sources': [
                 '../../src/base/platform/platform-win32.cc',
                 '../../src/base/win32-headers.h',
-                '../../src/base/win32-math.cc',
-                '../../src/base/win32-math.h'
               ],
               'msvs_disabled_warnings': [4351, 4355, 4800],
               'link_settings':  {
@@ -1523,7 +1612,7 @@
           '../../src/array.js',
           '../../src/string.js',
           '../../src/uri.js',
-          '../../third_party/fdlibm/fdlibm.js',
+          '../../src/third_party/fdlibm/fdlibm.js',
           '../../src/math.js',
           '../../src/apinatives.js',
           '../../src/date.js',
@@ -1551,7 +1640,12 @@
           '../../src/generator.js',
           '../../src/harmony-string.js',
           '../../src/harmony-array.js',
+          '../../src/harmony-array-includes.js',
+          '../../src/harmony-tostring.js',
+          '../../src/harmony-typedarray.js',
           '../../src/harmony-classes.js',
+          '../../src/harmony-templates.js',
+          '../../src/harmony-regexp.js'
         ],
         'libraries_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries.bin',
         'libraries_experimental_bin_file': '<(SHARED_INTERMEDIATE_DIR)/libraries-experimental.bin',
@@ -1572,7 +1666,6 @@
             '../../tools/js2c.py',
             '<(SHARED_INTERMEDIATE_DIR)/libraries.cc',
             'CORE',
-            '<(v8_compress_startup_data)',
             '<@(library_files)',
             '<@(i18n_library_files)',
           ],
@@ -1599,7 +1692,6 @@
             '../../tools/js2c.py',
             '<(SHARED_INTERMEDIATE_DIR)/experimental-libraries.cc',
             'EXPERIMENTAL',
-            '<(v8_compress_startup_data)',
             '<@(experimental_library_files)'
           ],
           'conditions': [
@@ -1652,16 +1744,17 @@
         '../../src/mksnapshot.cc',
       ],
       'conditions': [
+        ['v8_enable_i18n_support==1', {
+          'dependencies': [
+            '<(icu_gyp_path):icui18n',
+            '<(icu_gyp_path):icuuc',
+          ]
+        }],
         ['want_separate_host_toolset==1', {
           'toolsets': ['host'],
         }, {
           'toolsets': ['target'],
         }],
-        ['v8_compress_startup_data=="bz2"', {
-          'libraries': [
-            '-lbz2',
-          ]
-        }],
       ],
     },
   ],
diff --git a/tools/js2c.py b/tools/js2c.py
index 77485f6..621ed5a 100755
--- a/tools/js2c.py
+++ b/tools/js2c.py
@@ -255,8 +255,6 @@
 
 %(sources_declaration)s\
 
-%(raw_sources_declaration)s\
-
   template <>
   int NativesCollection<%(type)s>::GetBuiltinsCount() {
     return %(builtin_count)i;
@@ -274,13 +272,8 @@
   }
 
   template <>
-  int NativesCollection<%(type)s>::GetRawScriptsSize() {
-    return %(raw_total_length)i;
-  }
-
-  template <>
-  Vector<const char> NativesCollection<%(type)s>::GetRawScriptSource(int index) {
-%(get_raw_script_source_cases)s\
+  Vector<const char> NativesCollection<%(type)s>::GetScriptSource(int index) {
+%(get_script_source_cases)s\
     return Vector<const char>("", 0);
   }
 
@@ -291,32 +284,15 @@
   }
 
   template <>
-  Vector<const byte> NativesCollection<%(type)s>::GetScriptsSource() {
-    return Vector<const byte>(sources, %(total_length)i);
+  Vector<const char> NativesCollection<%(type)s>::GetScriptsSource() {
+    return Vector<const char>(sources, %(total_length)i);
   }
-
-  template <>
-  void NativesCollection<%(type)s>::SetRawScriptsSource(Vector<const char> raw_source) {
-    DCHECK(%(raw_total_length)i == raw_source.length());
-    raw_sources = raw_source.start();
-  }
-
 }  // internal
 }  // v8
 """
 
 SOURCES_DECLARATION = """\
-  static const byte sources[] = { %s };
-"""
-
-
-RAW_SOURCES_COMPRESSION_DECLARATION = """\
-  static const char* raw_sources = NULL;
-"""
-
-
-RAW_SOURCES_DECLARATION = """\
-  static const char* raw_sources = reinterpret_cast<const char*>(sources);
+  static const char sources[] = { %s };
 """
 
 
@@ -325,8 +301,8 @@
 """
 
 
-GET_RAW_SCRIPT_SOURCE_CASE = """\
-    if (index == %(i)i) return Vector<const char>(raw_sources + %(offset)i, %(raw_length)i);
+GET_SCRIPT_SOURCE_CASE = """\
+    if (index == %(i)i) return Vector<const char>(sources + %(offset)i, %(source_length)i);
 """
 
 
@@ -440,7 +416,7 @@
   # Loop over modules and build up indices into the source blob:
   get_index_cases = []
   get_script_name_cases = []
-  get_raw_script_source_cases = []
+  get_script_source_cases = []
   offset = 0
   for i in xrange(len(sources.modules)):
     native_name = "native %s.js" % sources.names[i]
@@ -450,57 +426,38 @@
         "name": native_name,
         "length": len(native_name),
         "offset": offset,
-        "raw_length": len(sources.modules[i]),
+        "source_length": len(sources.modules[i]),
     }
     get_index_cases.append(GET_INDEX_CASE % d)
     get_script_name_cases.append(GET_SCRIPT_NAME_CASE % d)
-    get_raw_script_source_cases.append(GET_RAW_SCRIPT_SOURCE_CASE % d)
+    get_script_source_cases.append(GET_SCRIPT_SOURCE_CASE % d)
     offset += len(sources.modules[i])
   assert offset == len(raw_sources)
 
-  # If we have the raw sources we can declare them accordingly.
-  have_raw_sources = source_bytes == raw_sources
-  raw_sources_declaration = (RAW_SOURCES_DECLARATION
-      if have_raw_sources else RAW_SOURCES_COMPRESSION_DECLARATION)
-
   metadata = {
     "builtin_count": len(sources.modules),
     "debugger_count": sum(sources.is_debugger_id),
     "sources_declaration": SOURCES_DECLARATION % ToCArray(source_bytes),
-    "raw_sources_declaration": raw_sources_declaration,
-    "raw_total_length": sum(map(len, sources.modules)),
     "total_length": total_length,
     "get_index_cases": "".join(get_index_cases),
-    "get_raw_script_source_cases": "".join(get_raw_script_source_cases),
+    "get_script_source_cases": "".join(get_script_source_cases),
     "get_script_name_cases": "".join(get_script_name_cases),
     "type": native_type,
   }
   return metadata
 
 
-def CompressMaybe(sources, compression_type):
-  """Take the prepared sources and generate a sequence of bytes.
-
-  Args:
-    sources: A Sources instance with the prepared sourced.
-    compression_type: string, describing the desired compression.
-
-  Returns:
-    A sequence of bytes.
-  """
-  sources_bytes = "".join(sources.modules)
-  if compression_type == "off":
-    return sources_bytes
-  elif compression_type == "bz2":
-    return bz2.compress(sources_bytes)
-  else:
-    raise Error("Unknown compression type %s." % compression_type)
-
-
 def PutInt(blob_file, value):
-  assert(value >= 0 and value < (1 << 20))
-  size = 1 if (value < 1 << 6) else (2 if (value < 1 << 14) else 3)
-  value_with_length = (value << 2) | size
+  assert(value >= 0 and value < (1 << 28))
+  if (value < 1 << 6):
+    size = 1
+  elif (value < 1 << 14):
+    size = 2
+  elif (value < 1 << 22):
+    size = 3
+  else:
+    size = 4
+  value_with_length = (value << 2) | (size - 1)
 
   byte_sequence = bytearray()
   for i in xrange(size):
@@ -538,9 +495,9 @@
   output.close()
 
 
-def JS2C(source, target, native_type, compression_type, raw_file, startup_blob):
+def JS2C(source, target, native_type, raw_file, startup_blob):
   sources = PrepareSources(source)
-  sources_bytes = CompressMaybe(sources, compression_type)
+  sources_bytes = "".join(sources.modules)
   metadata = BuildMetadata(sources, sources_bytes, native_type)
 
   # Optionally emit raw file.
@@ -564,14 +521,13 @@
                     help="file to write the processed sources array to.")
   parser.add_option("--startup_blob", action="store",
                     help="file to write the startup blob to.")
-  parser.set_usage("""js2c out.cc type compression sources.js ...
+  parser.set_usage("""js2c out.cc type sources.js ...
       out.cc: C code to be generated.
       type: type parameter for NativesCollection template.
-      compression: type of compression used. [off|bz2]
       sources.js: JS internal sources or macros.py.""")
   (options, args) = parser.parse_args()
 
-  JS2C(args[3:], args[0], args[1], args[2], options.raw, options.startup_blob)
+  JS2C(args[2:], args[0], args[1], options.raw, options.startup_blob)
 
 
 if __name__ == "__main__":
diff --git a/tools/lexer-shell.cc b/tools/lexer-shell.cc
deleted file mode 100644
index f8ddc02..0000000
--- a/tools/lexer-shell.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2013 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * 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.
-
-#include <assert.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string>
-#include <vector>
-#include "src/v8.h"
-
-#include "include/libplatform/libplatform.h"
-#include "src/api.h"
-#include "src/base/platform/platform.h"
-#include "src/messages.h"
-#include "src/runtime.h"
-#include "src/scanner-character-streams.h"
-#include "src/scopeinfo.h"
-#include "tools/shell-utils.h"
-#include "src/string-stream.h"
-#include "src/scanner.h"
-
-
-using namespace v8::internal;
-
-
-class BaselineScanner {
- public:
-  BaselineScanner(const char* fname,
-                  Isolate* isolate,
-                  Encoding encoding,
-                  v8::base::ElapsedTimer* timer,
-                  int repeat)
-      : stream_(NULL) {
-    int length = 0;
-    source_ = ReadFileAndRepeat(fname, &length, repeat);
-    unicode_cache_ = new UnicodeCache();
-    scanner_ = new Scanner(unicode_cache_);
-    switch (encoding) {
-      case UTF8:
-        stream_ = new Utf8ToUtf16CharacterStream(source_, length);
-        break;
-      case UTF16: {
-        Handle<String> result = isolate->factory()->NewStringFromTwoByte(
-            Vector<const uint16_t>(
-                reinterpret_cast<const uint16_t*>(source_),
-                length / 2)).ToHandleChecked();
-        stream_ =
-            new GenericStringUtf16CharacterStream(result, 0, result->length());
-        break;
-      }
-      case LATIN1: {
-        Handle<String> result = isolate->factory()->NewStringFromOneByte(
-            Vector<const uint8_t>(source_, length)).ToHandleChecked();
-        stream_ =
-            new GenericStringUtf16CharacterStream(result, 0, result->length());
-        break;
-      }
-    }
-    timer->Start();
-    scanner_->Initialize(stream_);
-  }
-
-  ~BaselineScanner() {
-    delete scanner_;
-    delete stream_;
-    delete unicode_cache_;
-    delete[] source_;
-  }
-
-  Token::Value Next(int* beg_pos, int* end_pos) {
-    Token::Value res = scanner_->Next();
-    *beg_pos = scanner_->location().beg_pos;
-    *end_pos = scanner_->location().end_pos;
-    return res;
-  }
-
- private:
-  UnicodeCache* unicode_cache_;
-  Scanner* scanner_;
-  const byte* source_;
-  BufferedUtf16CharacterStream* stream_;
-};
-
-
-struct TokenWithLocation {
-  Token::Value value;
-  size_t beg;
-  size_t end;
-  TokenWithLocation() : value(Token::ILLEGAL), beg(0), end(0) { }
-  TokenWithLocation(Token::Value value, size_t beg, size_t end) :
-      value(value), beg(beg), end(end) { }
-  bool operator==(const TokenWithLocation& other) {
-    return value == other.value && beg == other.beg && end == other.end;
-  }
-  bool operator!=(const TokenWithLocation& other) {
-    return !(*this == other);
-  }
-  void Print(const char* prefix) const {
-    printf("%s %11s at (%d, %d)\n",
-           prefix, Token::Name(value),
-           static_cast<int>(beg), static_cast<int>(end));
-  }
-};
-
-
-v8::base::TimeDelta RunBaselineScanner(const char* fname, Isolate* isolate,
-                                       Encoding encoding, bool dump_tokens,
-                                       std::vector<TokenWithLocation>* tokens,
-                                       int repeat) {
-  v8::base::ElapsedTimer timer;
-  BaselineScanner scanner(fname, isolate, encoding, &timer, repeat);
-  Token::Value token;
-  int beg, end;
-  do {
-    token = scanner.Next(&beg, &end);
-    if (dump_tokens) {
-      tokens->push_back(TokenWithLocation(token, beg, end));
-    }
-  } while (token != Token::EOS);
-  return timer.Elapsed();
-}
-
-
-void PrintTokens(const char* name,
-                 const std::vector<TokenWithLocation>& tokens) {
-  printf("No of tokens: %d\n",
-         static_cast<int>(tokens.size()));
-  printf("%s:\n", name);
-  for (size_t i = 0; i < tokens.size(); ++i) {
-    tokens[i].Print("=>");
-  }
-}
-
-
-v8::base::TimeDelta ProcessFile(
-    const char* fname,
-    Encoding encoding,
-    Isolate* isolate,
-    bool print_tokens,
-    int repeat) {
-  if (print_tokens) {
-    printf("Processing file %s\n", fname);
-  }
-  HandleScope handle_scope(isolate);
-  std::vector<TokenWithLocation> baseline_tokens;
-  v8::base::TimeDelta baseline_time;
-  baseline_time = RunBaselineScanner(
-      fname, isolate, encoding, print_tokens,
-      &baseline_tokens, repeat);
-  if (print_tokens) {
-    PrintTokens("Baseline", baseline_tokens);
-  }
-  return baseline_time;
-}
-
-
-int main(int argc, char* argv[]) {
-  v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
-  v8::V8::InitializeICU();
-  v8::Platform* platform = v8::platform::CreateDefaultPlatform();
-  v8::V8::InitializePlatform(platform);
-  v8::V8::Initialize();
-  Encoding encoding = LATIN1;
-  bool print_tokens = false;
-  std::vector<std::string> fnames;
-  std::string benchmark;
-  int repeat = 1;
-  for (int i = 0; i < argc; ++i) {
-    if (strcmp(argv[i], "--latin1") == 0) {
-      encoding = LATIN1;
-    } else if (strcmp(argv[i], "--utf8") == 0) {
-      encoding = UTF8;
-    } else if (strcmp(argv[i], "--utf16") == 0) {
-      encoding = UTF16;
-    } else if (strcmp(argv[i], "--print-tokens") == 0) {
-      print_tokens = true;
-    } else if (strncmp(argv[i], "--benchmark=", 12) == 0) {
-      benchmark = std::string(argv[i]).substr(12);
-    } else if (strncmp(argv[i], "--repeat=", 9) == 0) {
-      std::string repeat_str = std::string(argv[i]).substr(9);
-      repeat = atoi(repeat_str.c_str());
-    } else if (i > 0 && argv[i][0] != '-') {
-      fnames.push_back(std::string(argv[i]));
-    }
-  }
-  v8::Isolate* isolate = v8::Isolate::New();
-  {
-    v8::Isolate::Scope isolate_scope(isolate);
-    v8::HandleScope handle_scope(isolate);
-    v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate, NULL, global);
-    DCHECK(!context.IsEmpty());
-    {
-      v8::Context::Scope scope(context);
-      double baseline_total = 0;
-      for (size_t i = 0; i < fnames.size(); i++) {
-        v8::base::TimeDelta time;
-        time = ProcessFile(fnames[i].c_str(), encoding,
-                           reinterpret_cast<Isolate*>(isolate), print_tokens,
-                           repeat);
-        baseline_total += time.InMillisecondsF();
-      }
-      if (benchmark.empty()) benchmark = "Baseline";
-      printf("%s(RunTime): %.f ms\n", benchmark.c_str(), baseline_total);
-    }
-  }
-  v8::V8::Dispose();
-  v8::V8::ShutdownPlatform();
-  delete platform;
-  return 0;
-}
diff --git a/tools/lexer-shell.gyp b/tools/lexer-shell.gyp
deleted file mode 100644
index 836ea97..0000000
--- a/tools/lexer-shell.gyp
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2013 the V8 project authors. All rights reserved.
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * 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': {
-    'v8_code': 1,
-    'v8_enable_i18n_support%': 1,
-  },
-  'includes': ['../build/toolchain.gypi', '../build/features.gypi'],
-  'targets': [
-    {
-      'target_name': 'lexer-shell',
-      'type': 'executable',
-      'dependencies': [
-        '../tools/gyp/v8.gyp:v8',
-        '../tools/gyp/v8.gyp:v8_libplatform',
-      ],
-      'conditions': [
-        ['v8_enable_i18n_support==1', {
-          'dependencies': [
-            '<(icu_gyp_path):icui18n',
-            '<(icu_gyp_path):icuuc',
-          ],
-        }],
-      ],
-      'include_dirs+': [
-        '..',
-      ],
-      'sources': [
-        'lexer-shell.cc',
-        'shell-utils.h',
-      ],
-    },
-    {
-      'target_name': 'parser-shell',
-      'type': 'executable',
-      'dependencies': [
-        '../tools/gyp/v8.gyp:v8',
-        '../tools/gyp/v8.gyp:v8_libplatform',
-      ],
-      'conditions': [
-        ['v8_enable_i18n_support==1', {
-          'dependencies': [
-            '<(icu_gyp_path):icui18n',
-            '<(icu_gyp_path):icuuc',
-          ],
-        }],
-      ],
-      'include_dirs+': [
-        '..',
-      ],
-      'sources': [
-        'parser-shell.cc',
-        'shell-utils.h',
-      ],
-    },
-  ],
-}
diff --git a/tools/logreader.js b/tools/logreader.js
index a8141da..5f0ec7f 100644
--- a/tools/logreader.js
+++ b/tools/logreader.js
@@ -108,6 +108,8 @@
     // Filter out possible 'overflow' string.
     } else if (firstChar != 'o') {
       fullStack.push(parseInt(frame, 16));
+    } else {
+      print("dropping: " + frame);
     }
   }
   return fullStack;
diff --git a/tools/nacl-run.py b/tools/nacl-run.py
index 135172c..32055fe 100755
--- a/tools/nacl-run.py
+++ b/tools/nacl-run.py
@@ -32,6 +32,7 @@
 
 import os
 from os.path import join, dirname, abspath
+import re
 import subprocess
 import sys
 import tempfile
@@ -82,7 +83,7 @@
   try:
     p = subprocess.Popen(['file', nexe], stdout=subprocess.PIPE)
     out, err = p.communicate()
-    lines = out.split('\n')
+    lines = [re.sub("\s+", " " , line) for line in out.split('\n')]
     if lines[0].find(": ELF 32-bit LSB executable, Intel 80386") > 0:
       return "x86_32"
     if lines[0].find(": ELF 64-bit LSB executable, x86-64") > 0:
@@ -116,17 +117,13 @@
     print("NaCl V8 ARM support is not ready yet.")
     sys.exit(1)
   else:
-    print("Invalid nexe %s" % nexe)
+    print("Invalid nexe %s with NaCl arch %s" % (nexe, nacl_arch))
     sys.exit(1)
 
   nacl_sel_ldr = os.path.join(nacl_sdk_dir, "tools", sel_ldr)
   nacl_irt = os.path.join(nacl_sdk_dir, "tools", irt)
-  nacl_ld_so = os.path.join(nacl_sdk_dir, "toolchain", toolchain,
-                            "x86_64-nacl", libdir, "runnable-ld.so")
-  nacl_lib_path = os.path.join(nacl_sdk_dir, "toolchain", toolchain,
-                               "x86_64-nacl", libdir)
 
-  return (nacl_sdk_dir, nacl_sel_ldr, nacl_irt, nacl_ld_so, nacl_lib_path)
+  return (nacl_sdk_dir, nacl_sel_ldr, nacl_irt)
 
 def Main():
   if (len(sys.argv) == 1):
@@ -135,15 +132,14 @@
 
   args = [Escape(arg) for arg in sys.argv[1:]]
 
-  (nacl_sdk_dir, nacl_sel_ldr, nacl_irt, nacl_ld_so,
-   nacl_lib_path) = GetNaClResources(sys.argv[1])
+  (nacl_sdk_dir, nacl_sel_ldr, nacl_irt) = GetNaClResources(sys.argv[1])
 
   # sel_ldr Options:
   # -c -c: disable validation (for performance)
   # -a: allow file access
   # -B <irt>: load the IRT
-  command = ' '.join([nacl_sel_ldr, '-c', '-c', '-a', '-B', nacl_irt, '--',
-                     nacl_ld_so, '--library-path', nacl_lib_path] + args)
+  command = ' '.join([nacl_sel_ldr, '-c', '-c', '-a', '-B', nacl_irt, '--'] +
+                     args)
   error_code = Execute(command)
   return error_code
 
diff --git a/tools/parser-shell.gyp b/tools/parser-shell.gyp
new file mode 100644
index 0000000..f0f0b8b
--- /dev/null
+++ b/tools/parser-shell.gyp
@@ -0,0 +1,59 @@
+# Copyright 2013 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * 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': {
+    'v8_code': 1,
+    'v8_enable_i18n_support%': 1,
+  },
+  'includes': ['../build/toolchain.gypi', '../build/features.gypi'],
+  'targets': [
+    {
+      'target_name': 'parser-shell',
+      'type': 'executable',
+      'dependencies': [
+        '../tools/gyp/v8.gyp:v8',
+        '../tools/gyp/v8.gyp:v8_libplatform',
+      ],
+      'conditions': [
+        ['v8_enable_i18n_support==1', {
+          'dependencies': [
+            '<(icu_gyp_path):icui18n',
+            '<(icu_gyp_path):icuuc',
+          ],
+        }],
+      ],
+      'include_dirs+': [
+        '..',
+      ],
+      'sources': [
+        'parser-shell.cc',
+        'shell-utils.h',
+      ],
+    },
+  ],
+}
diff --git a/tools/presubmit.py b/tools/presubmit.py
index 8a6ff2a..321d291 100755
--- a/tools/presubmit.py
+++ b/tools/presubmit.py
@@ -236,7 +236,8 @@
               or (name in CppLintProcessor.IGNORE_LINT))
 
   def GetPathsToSearch(self):
-    return ['src', 'include', 'samples', join('test', 'cctest')]
+    return ['src', 'include', 'samples', join('test', 'cctest'),
+            join('test', 'unittests')]
 
   def GetCpplintScript(self, prio_path):
     for path in [prio_path] + os.environ["PATH"].split(os.pathsep):
@@ -326,16 +327,25 @@
     return (super(SourceProcessor, self).IgnoreDir(name) or
             name in ('third_party', 'gyp', 'out', 'obj', 'DerivedSources'))
 
-  IGNORE_COPYRIGHTS = ['cpplint.py',
+  IGNORE_COPYRIGHTS = ['box2d.js',
+                       'cpplint.py',
+                       'copy.js',
+                       'corrections.js',
+                       'crypto.js',
                        'daemon.py',
                        'earley-boyer.js',
-                       'raytrace.js',
-                       'crypto.js',
+                       'fannkuch.js',
+                       'fasta.js',
+                       'jsmin.py',
                        'libraries.cc',
                        'libraries-empty.cc',
-                       'jsmin.py',
+                       'lua_binarytrees.js',
+                       'memops.js',
+                       'primes.js',
+                       'raytrace.js',
                        'regexp-pcre.js',
-                       'gnuplot-4.6.3-emscripten.js']
+                       'gnuplot-4.6.3-emscripten.js',
+                       'zlib.js']
   IGNORE_TABS = IGNORE_COPYRIGHTS + ['unicode-test.js', 'html-comments.js']
 
   def EndOfDeclaration(self, line):
diff --git a/tools/profile.js b/tools/profile.js
index 10a07f8..a06cd3a 100644
--- a/tools/profile.js
+++ b/tools/profile.js
@@ -36,6 +36,7 @@
   this.codeMap_ = new CodeMap();
   this.topDownTree_ = new CallTree();
   this.bottomUpTree_ = new CallTree();
+  this.c_entries_ = {};
 };
 
 
@@ -102,7 +103,7 @@
 Profile.prototype.addLibrary = function(
     name, startAddr, endAddr) {
   var entry = new CodeMap.CodeEntry(
-      endAddr - startAddr, name);
+      endAddr - startAddr, name, 'SHARED_LIB');
   this.codeMap_.addLibrary(startAddr, entry);
   return entry;
 };
@@ -118,7 +119,7 @@
 Profile.prototype.addStaticCode = function(
     name, startAddr, endAddr) {
   var entry = new CodeMap.CodeEntry(
-      endAddr - startAddr, name);
+      endAddr - startAddr, name, 'CPP');
   this.codeMap_.addStaticCode(startAddr, entry);
   return entry;
 };
@@ -250,10 +251,26 @@
  */
 Profile.prototype.resolveAndFilterFuncs_ = function(stack) {
   var result = [];
+  var last_seen_c_function = '';
+  var look_for_first_c_function = false;
   for (var i = 0; i < stack.length; ++i) {
     var entry = this.codeMap_.findEntry(stack[i]);
     if (entry) {
       var name = entry.getName();
+      if (i == 0 && (entry.type == 'CPP' || entry.type == 'SHARED_LIB')) {
+        look_for_first_c_function = true;
+      }
+      if (look_for_first_c_function) {
+        if (entry.type == 'CPP') {
+          last_seen_c_function = name;
+        } else if (i > 0 && last_seen_c_function != '') {
+          if (this.c_entries_[last_seen_c_function] === undefined) {
+            this.c_entries_[last_seen_c_function] = 0;
+          }
+          this.c_entries_[last_seen_c_function]++;
+          look_for_first_c_function = false;  // Found it, we're done.
+        }
+      }
       if (!this.skipThisFunction(name)) {
         result.push(name);
       }
@@ -381,6 +398,28 @@
 };
 
 
+Profile.CEntryNode = function(name, ticks) {
+  this.name = name;
+  this.ticks = ticks;
+}
+
+
+Profile.prototype.getCEntryProfile = function() {
+  var result = [new Profile.CEntryNode("TOTAL", 0)];
+  var total_ticks = 0;
+  for (var f in this.c_entries_) {
+    var ticks = this.c_entries_[f];
+    total_ticks += ticks;
+    result.push(new Profile.CEntryNode(f, ticks));
+  }
+  result[0].ticks = total_ticks;  // Sorting will keep this at index 0.
+  result.sort(function(n1, n2) {
+    return n2.ticks - n1.ticks || (n2.name < n1.name ? -1 : 1)
+  });
+  return result;
+}
+
+
 /**
  * Cleans up function entries that are not referenced by code entries.
  */
@@ -415,8 +454,7 @@
  * @constructor
  */
 Profile.DynamicCodeEntry = function(size, type, name) {
-  CodeMap.CodeEntry.call(this, size, name);
-  this.type = type;
+  CodeMap.CodeEntry.call(this, size, name, type);
 };
 
 
@@ -456,8 +494,7 @@
  * @constructor
  */
 Profile.DynamicFuncCodeEntry = function(size, type, func, state) {
-  CodeMap.CodeEntry.call(this, size);
-  this.type = type;
+  CodeMap.CodeEntry.call(this, size, '', type);
   this.func = func;
   this.state = state;
 };
diff --git a/tools/push-to-trunk/auto_push.py b/tools/push-to-trunk/auto_push.py
index fef3b53..34afa4a 100755
--- a/tools/push-to-trunk/auto_push.py
+++ b/tools/push-to-trunk/auto_push.py
@@ -36,7 +36,7 @@
 from common_includes import *
 import push_to_trunk
 
-PUSH_MESSAGE_RE = re.compile(r".* \(based on bleeding_edge revision r(\d+)\)$")
+PUSH_MESSAGE_RE = re.compile(r".* \(based on ([a-fA-F0-9]+)\)$")
 
 class Preparation(Step):
   MESSAGE = "Preparation."
@@ -70,13 +70,12 @@
                % self["tree_message"])
 
 
-class FetchLKGR(Step):
-  MESSAGE = "Fetching V8 LKGR."
+class FetchCandidate(Step):
+  MESSAGE = "Fetching V8 roll candidate ref."
 
   def RunStep(self):
-    lkgr_url = "https://v8-status.appspot.com/lkgr"
-    # Retry several times since app engine might have issues.
-    self["lkgr"] = self.ReadURL(lkgr_url, wait_plan=[5, 20, 300, 300])
+    self.Git("fetch origin +refs/heads/candidate:refs/heads/candidate")
+    self["candidate"] = self.Git("show-ref -s refs/heads/candidate").strip()
 
 
 class CheckLastPush(Step):
@@ -94,28 +93,30 @@
       self.Die("Could not retrieve bleeding edge revision for trunk push %s"
                % last_push)
 
-    # TODO(machenbach): This metric counts all revisions. It could be
-    # improved by counting only the revisions on bleeding_edge.
-    if int(self["lkgr"]) - int(last_push_be) < 10:  # pragma: no cover
-      # This makes sure the script doesn't push twice in a row when the cron
-      # job retries several times.
-      self.Die("Last push too recently: %s" % last_push_be)
+    if self["candidate"] == last_push_be:
+      print "Already pushed current candidate %s" % last_push_be
+      return True
 
 
-class PushToTrunk(Step):
-  MESSAGE = "Pushing to trunk if specified."
+class PushToCandidates(Step):
+  MESSAGE = "Pushing to candidates if specified."
 
   def RunStep(self):
-    print "Pushing lkgr %s to trunk." % self["lkgr"]
+    print "Pushing candidate %s to candidates." % self["candidate"]
+
+    args = [
+      "--author", self._options.author,
+      "--reviewer", self._options.reviewer,
+      "--revision", self["candidate"],
+      "--force",
+    ]
+
+    if self._options.work_dir:
+      args.extend(["--work-dir", self._options.work_dir])
 
     # TODO(machenbach): Update the script before calling it.
     if self._options.push:
-      self._side_effect_handler.Call(
-          push_to_trunk.PushToTrunk().Run,
-          ["--author", self._options.author,
-           "--reviewer", self._options.reviewer,
-           "--revision", self["lkgr"],
-           "--force"])
+      self._side_effect_handler.Call(push_to_trunk.PushToTrunk().Run, args)
 
 
 class AutoPush(ScriptsBase):
@@ -142,9 +143,9 @@
       Preparation,
       CheckAutoPushSettings,
       CheckTreeStatus,
-      FetchLKGR,
+      FetchCandidate,
       CheckLastPush,
-      PushToTrunk,
+      PushToCandidates,
     ]
 
 
diff --git a/tools/push-to-trunk/auto_roll.py b/tools/push-to-trunk/auto_roll.py
index 120e633..1b57097 100755
--- a/tools/push-to-trunk/auto_roll.py
+++ b/tools/push-to-trunk/auto_roll.py
@@ -42,8 +42,9 @@
   MESSAGE = "Detect commit ID of the last push to trunk."
 
   def RunStep(self):
+    self.vc.Fetch()
     push_hash = self.FindLastTrunkPush(
-        branch="origin/master", include_patches=True)
+        branch="origin/candidates", include_patches=True)
     self["last_push"] = self.GetCommitPositionNumber(push_hash)
 
 
@@ -99,6 +100,8 @@
             "--sheriff", "--googlers-mapping", self._options.googlers_mapping])
       if self._options.dry_run:
         args.extend(["--dry-run"])
+      if self._options.work_dir:
+        args.extend(["--work-dir", self._options.work_dir])
       self._side_effect_handler.Call(chromium_roll.ChromiumRoll().Run, args)
 
 
diff --git a/tools/push-to-trunk/auto_tag.py b/tools/push-to-trunk/auto_tag.py
index 175e10e..a52a028 100755
--- a/tools/push-to-trunk/auto_tag.py
+++ b/tools/push-to-trunk/auto_tag.py
@@ -13,10 +13,15 @@
   MESSAGE = "Preparation."
 
   def RunStep(self):
+    # TODO(machenbach): Remove after the git switch.
+    if self.Config("PERSISTFILE_BASENAME") == "/tmp/v8-auto-tag-tempfile":
+      print "This script is disabled until after the v8 git migration."
+      return True
+
     self.CommonPrepare()
     self.PrepareBranch()
     self.GitCheckout("master")
-    self.GitSVNRebase()
+    self.vc.Pull()
 
 
 class GetTags(Step):
@@ -24,13 +29,7 @@
 
   def RunStep(self):
     self.GitCreateBranch(self._config["BRANCHNAME"])
-
-    # Get remote tags.
-    tags = filter(lambda s: re.match(r"^svn/tags/[\d+\.]+$", s),
-                  self.GitRemotes())
-
-    # Remove 'svn/tags/' prefix.
-    self["tags"] = map(lambda s: s[9:], tags)
+    self["tags"] = self.vc.GetTags()
 
 
 class GetOldestUntaggedVersion(Step):
@@ -114,9 +113,9 @@
 
   def RunStep(self):
     # Get the lkgr after the tag candidate and before the next tag candidate.
-    candidate_svn = self.GitSVNFindSVNRev(self["candidate"])
+    candidate_svn = self.vc.GitSvn(self["candidate"])
     if self["next"]:
-      next_svn = self.GitSVNFindSVNRev(self["next"])
+      next_svn = self.vc.GitSvn(self["next"])
     else:
       # Don't include the version change commit itself if there is no upper
       # limit yet.
@@ -130,7 +129,7 @@
       return True
 
     # Let's check if the lkgr is at least three hours old.
-    self["lkgr"] = self.GitSVNFindGitHash(lkgr_svn)
+    self["lkgr"] = self.vc.SvnGit(lkgr_svn)
     if not self["lkgr"]:
       print "Couldn't find git hash for lkgr %s" % lkgr_svn
       self.CommonCleanup()
@@ -153,7 +152,10 @@
   def RunStep(self):
     if not self._options.dry_run:
       self.GitReset(self["lkgr"])
-      self.GitSVNTag(self["candidate_version"])
+      # FIXME(machenbach): Make this work with the git repo.
+      self.vc.Tag(self["candidate_version"],
+                  "svn/bleeding_edge",
+                  "This won't work!")
 
 
 class CleanUp(Step):
diff --git a/tools/push-to-trunk/bump_up_version.py b/tools/push-to-trunk/bump_up_version.py
index c9f052b..647708c 100755
--- a/tools/push-to-trunk/bump_up_version.py
+++ b/tools/push-to-trunk/bump_up_version.py
@@ -28,17 +28,23 @@
 VERSION_BRANCH = "auto-bump-up-version"
 
 
+# TODO(machenbach): Add vc interface that works on git mirror.
 class Preparation(Step):
   MESSAGE = "Preparation."
 
   def RunStep(self):
+    # TODO(machenbach): Remove after the git switch.
+    if(self.Config("PERSISTFILE_BASENAME") ==
+       "/tmp/v8-bump-up-version-tempfile"):
+      print "This script is disabled until after the v8 git migration."
+      return True
+
     # Check for a clean workdir.
     if not self.GitIsWorkdirClean():  # pragma: no cover
       # This is in case a developer runs this script on a dirty tree.
       self.GitStash()
 
-    # TODO(machenbach): This should be called master after the git switch.
-    self.GitCheckout("bleeding_edge")
+    self.GitCheckout("master")
 
     self.GitPull()
 
@@ -50,8 +56,7 @@
   MESSAGE = "Get latest bleeding edge version."
 
   def RunStep(self):
-    # TODO(machenbach): This should be called master after the git switch.
-    self.GitCheckout("bleeding_edge")
+    self.GitCheckout("master")
 
     # Store latest version and revision.
     self.ReadAndPersistVersion()
@@ -88,7 +93,7 @@
   MESSAGE = "Get bleeding edge lkgr version."
 
   def RunStep(self):
-    self.GitCheckout("bleeding_edge")
+    self.GitCheckout("master")
     # If the commit was made from svn, there is a mapping entry in the commit
     # message.
     self["lkgr"] = self.GitLog(
@@ -106,7 +111,7 @@
     print "LKGR version: %s" % self["lkgr_version"]
 
     # Ensure a clean version branch.
-    self.GitCheckout("bleeding_edge")
+    self.GitCheckout("master")
     self.DeleteBranch(VERSION_BRANCH)
 
 
@@ -131,8 +136,7 @@
   MESSAGE = "Get latest trunk version."
 
   def RunStep(self):
-    # TODO(machenbach): This should be called trunk after the git switch.
-    self.GitCheckout("master")
+    self.GitCheckout("candidates")
     self.GitPull()
     self.ReadAndPersistVersion("trunk_")
     self["trunk_version"] = self.ArrayToVersion("trunk_")
@@ -186,7 +190,7 @@
   MESSAGE = "Bump up the version."
 
   def RunStep(self):
-    self.GitCreateBranch(VERSION_BRANCH, "bleeding_edge")
+    self.GitCreateBranch(VERSION_BRANCH, "master")
 
     self.SetVersion(os.path.join(self.default_cwd, VERSION_FILE), "new_")
 
@@ -194,17 +198,14 @@
       msg = "[Auto-roll] Bump up version to %s" % self["new_version"]
       self.GitCommit("%s\n\nTBR=%s" % (msg, self._options.author),
                      author=self._options.author)
-      if self._options.svn:
-        self.SVNCommit("branches/bleeding_edge", msg)
-      else:
-        self.GitUpload(author=self._options.author,
-                       force=self._options.force_upload,
-                       bypass_hooks=True)
-        self.GitDCommit()
+      self.GitUpload(author=self._options.author,
+                     force=self._options.force_upload,
+                     bypass_hooks=True)
+      self.GitCLLand()
       print "Successfully changed the version."
     finally:
       # Clean up.
-      self.GitCheckout("bleeding_edge")
+      self.GitCheckout("master")
       self.DeleteBranch(VERSION_BRANCH)
 
 
@@ -225,6 +226,7 @@
   def _Config(self):
     return {
       "PERSISTFILE_BASENAME": "/tmp/v8-bump-up-version-tempfile",
+      "PATCH_FILE": "/tmp/v8-bump-up-version-tempfile-patch-file",
     }
 
   def _Steps(self):
diff --git a/tools/push-to-trunk/check_clusterfuzz.py b/tools/push-to-trunk/check_clusterfuzz.py
new file mode 100755
index 0000000..d4ba90b
--- /dev/null
+++ b/tools/push-to-trunk/check_clusterfuzz.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+# Copyright 2014 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Script to check for new clusterfuzz issues since the last rolled v8 revision.
+
+Returns a json list with test case IDs if any.
+
+Security considerations: The security key and request data must never be
+written to public logs. Public automated callers of this script should
+suppress stdout and stderr and only process contents of the results_file.
+"""
+
+
+import argparse
+import httplib
+import json
+import os
+import re
+import sys
+import urllib
+import urllib2
+
+
+# Constants to git repos.
+BASE_URL = "https://chromium.googlesource.com"
+DEPS_LOG = BASE_URL + "/chromium/src/+log/master/DEPS?format=JSON"
+
+# Constants for retrieving v8 rolls.
+CRREV = "https://cr-rev.appspot.com/_ah/api/crrev/v1/commit/%s"
+V8_COMMIT_RE = re.compile(
+    r"^Update V8 to version \d+\.\d+\.\d+ \(based on ([a-fA-F0-9]+)\)\..*")
+
+# Constants for the clusterfuzz backend.
+HOSTNAME = "backend-dot-cluster-fuzz.appspot.com"
+
+# Crash patterns.
+V8_INTERNAL_RE = re.compile(r"^v8::internal.*")
+ANY_RE = re.compile(r".*")
+
+# List of all api requests.
+BUG_SPECS = [
+  {
+    "args": {
+      "job_type": "linux_asan_chrome_v8",
+      "reproducible": "True",
+      "open": "True",
+      "bug_information": "",
+    },
+    "crash_state": V8_INTERNAL_RE,
+  },
+  {
+    "args": {
+      "job_type": "linux_asan_d8_dbg",
+      "reproducible": "True",
+      "open": "True",
+      "bug_information": "",
+    },
+    "crash_state": ANY_RE,
+  },
+]
+
+
+def GetRequest(url):
+  url_fh = urllib2.urlopen(url, None, 60)
+  try:
+    return url_fh.read()
+  finally:
+    url_fh.close()
+
+
+def GetLatestV8InChromium():
+  """Returns the commit position number of the latest v8 roll in chromium."""
+
+  # Check currently rolled v8 revision.
+  result = GetRequest(DEPS_LOG)
+  if not result:
+    return None
+
+  # Strip security header and load json.
+  commits = json.loads(result[5:])
+
+  git_revision = None
+  for commit in commits["log"]:
+    # Get latest commit that matches the v8 roll pattern. Ignore cherry-picks.
+    match = re.match(V8_COMMIT_RE, commit["message"])
+    if match:
+      git_revision = match.group(1)
+      break
+  else:
+    return None
+
+  # Get commit position number for v8 revision.
+  result = GetRequest(CRREV % git_revision)
+  if not result:
+    return None
+
+  commit = json.loads(result)
+  assert commit["repo"] == "v8/v8"
+  return commit["number"]
+
+
+def APIRequest(key, **params):
+  """Send a request to the clusterfuzz api.
+
+  Returns a json dict of the response.
+  """
+
+  params["api_key"] = key
+  params = urllib.urlencode(params)
+
+  headers = {"Content-type": "application/x-www-form-urlencoded"}
+
+  try:
+    conn = httplib.HTTPSConnection(HOSTNAME)
+    conn.request("POST", "/_api/", params, headers)
+
+    response = conn.getresponse()
+
+    # Never leak "data" into public logs.
+    data = response.read()
+  except:
+    raise Exception("ERROR: Connection problem.")
+
+  try:
+    return json.loads(data)
+  except:
+    raise Exception("ERROR: Could not read response. Is your key valid?")
+
+  return None
+
+
+def Main():
+  parser = argparse.ArgumentParser()
+  parser.add_argument("-k", "--key-file", required=True,
+                      help="A file with the clusterfuzz api key.")
+  parser.add_argument("-r", "--results-file",
+                      help="A file to write the results to.")
+  options = parser.parse_args()
+
+  # Get api key. The key's content must never be logged.
+  assert options.key_file
+  with open(options.key_file) as f:
+    key = f.read().strip()
+  assert key
+
+  revision_number = GetLatestV8InChromium()
+
+  results = []
+  for spec in BUG_SPECS:
+    args = dict(spec["args"])
+    # Use incremented revision as we're interested in all revision greater than
+    # what's currently rolled into chromium.
+    if revision_number:
+      args["revision_greater_or_equal"] = str(int(revision_number) + 1)
+
+    # Never print issue details in public logs.
+    issues = APIRequest(key, **args)
+    assert issues is not None
+    for issue in issues:
+      if re.match(spec["crash_state"], issue["crash_state"]):
+        results.append(issue["id"])
+
+  if options.results_file:
+    with open(options.results_file, "w") as f:
+      f.write(json.dumps(results))
+  else:
+    print results
+
+
+if __name__ == "__main__":
+  sys.exit(Main())
diff --git a/tools/push-to-trunk/chromium_roll.py b/tools/push-to-trunk/chromium_roll.py
index dc5e6eb..5c9a38e 100755
--- a/tools/push-to-trunk/chromium_roll.py
+++ b/tools/push-to-trunk/chromium_roll.py
@@ -23,8 +23,7 @@
 
   def RunStep(self):
     self["last_push"] = self._options.last_push or self.FindLastTrunkPush(
-        branch="origin/master", include_patches=True)
-    self["trunk_revision"] = self.GetCommitPositionNumber(self["last_push"])
+        branch="origin/candidates", include_patches=True)
     self["push_title"] = self.GitLog(n=1, format="%s",
                                      git_hash=self["last_push"])
 
@@ -56,7 +55,7 @@
     # Update v8 remotes.
     self.GitFetchOrigin()
 
-    self.GitCreateBranch("v8-roll-%s" % self["trunk_revision"],
+    self.GitCreateBranch("v8-roll-%s" % self["last_push"],
                          cwd=self._options.chromium)
 
 
@@ -66,9 +65,9 @@
   def RunStep(self):
     # Patch DEPS file.
     if self.Command(
-        "roll-dep", "v8 %s" % self["trunk_revision"],
+        "roll-dep", "v8 %s" % self["last_push"],
         cwd=self._options.chromium) is None:
-      self.Die("Failed to create deps for %s" % self["trunk_revision"])
+      self.Die("Failed to create deps for %s" % self["last_push"])
 
     commit_title = "Update V8 to %s." % self["push_title"].lower()
     sheriff = ""
@@ -87,7 +86,7 @@
       print "CL uploaded."
     else:
       self.GitCheckout("master", cwd=self._options.chromium)
-      self.GitDeleteBranch("v8-roll-%s" % self["trunk_revision"],
+      self.GitDeleteBranch("v8-roll-%s" % self["last_push"],
                            cwd=self._options.chromium)
       print "Dry run - don't upload."
 
@@ -105,9 +104,9 @@
   MESSAGE = "Done!"
 
   def RunStep(self):
-    print("Congratulations, you have successfully rolled the push r%s it into "
+    print("Congratulations, you have successfully rolled %s into "
           "Chromium. Please don't forget to update the v8rel spreadsheet."
-          % self["trunk_revision"])
+          % self["last_push"])
 
     # Clean up all temporary files.
     Command("rm", "-f %s*" % self._config["PERSISTFILE_BASENAME"])
diff --git a/tools/push-to-trunk/common_includes.py b/tools/push-to-trunk/common_includes.py
index 00fb097..ac78ef8 100644
--- a/tools/push-to-trunk/common_includes.py
+++ b/tools/push-to-trunk/common_includes.py
@@ -45,10 +45,11 @@
 from git_recipes import GitRecipesMixin
 from git_recipes import GitFailedException
 
+CHANGELOG_FILE = "ChangeLog"
 VERSION_FILE = os.path.join("src", "version.cc")
 
 # V8 base directory.
-DEFAULT_CWD = os.path.dirname(
+V8_BASE = os.path.dirname(
     os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
 
 
@@ -255,6 +256,107 @@
   pass
 
 
+class VCInterface(object):
+  def InjectStep(self, step):
+    self.step=step
+
+  def Pull(self):
+    raise NotImplementedError()
+
+  def Fetch(self):
+    raise NotImplementedError()
+
+  def GetTags(self):
+    raise NotImplementedError()
+
+  def GetBranches(self):
+    raise NotImplementedError()
+
+  def MasterBranch(self):
+    raise NotImplementedError()
+
+  def CandidateBranch(self):
+    raise NotImplementedError()
+
+  def RemoteMasterBranch(self):
+    raise NotImplementedError()
+
+  def RemoteCandidateBranch(self):
+    raise NotImplementedError()
+
+  def RemoteBranch(self, name):
+    raise NotImplementedError()
+
+  def CLLand(self):
+    raise NotImplementedError()
+
+  def Tag(self, tag, remote, message):
+    """Sets a tag for the current commit.
+
+    Assumptions: The commit already landed and the commit message is unique.
+    """
+    raise NotImplementedError()
+
+
+class GitInterface(VCInterface):
+  def Pull(self):
+    self.step.GitPull()
+
+  def Fetch(self):
+    self.step.Git("fetch")
+
+  def GetTags(self):
+     return self.step.Git("tag").strip().splitlines()
+
+  def GetBranches(self):
+    # Get relevant remote branches, e.g. "branch-heads/3.25".
+    branches = filter(
+        lambda s: re.match(r"^branch\-heads/\d+\.\d+$", s),
+        self.step.GitRemotes())
+    # Remove 'branch-heads/' prefix.
+    return map(lambda s: s[13:], branches)
+
+  def MasterBranch(self):
+    return "master"
+
+  def CandidateBranch(self):
+    return "candidates"
+
+  def RemoteMasterBranch(self):
+    return "origin/master"
+
+  def RemoteCandidateBranch(self):
+    return "origin/candidates"
+
+  def RemoteBranch(self, name):
+    if name in ["candidates", "master"]:
+      return "origin/%s" % name
+    return "branch-heads/%s" % name
+
+  def Tag(self, tag, remote, message):
+    # Wait for the commit to appear. Assumes unique commit message titles (this
+    # is the case for all automated merge and push commits - also no title is
+    # the prefix of another title).
+    commit = None
+    for wait_interval in [3, 7, 15, 35, 45, 60]:
+      self.step.Git("fetch")
+      commit = self.step.GitLog(n=1, format="%H", grep=message, branch=remote)
+      if commit:
+        break
+      print("The commit has not replicated to git. Waiting for %s seconds." %
+            wait_interval)
+      self.step._side_effect_handler.Sleep(wait_interval)
+    else:
+      self.step.Die("Couldn't determine commit for setting the tag. Maybe the "
+                    "git updater is lagging behind?")
+
+    self.step.Git("tag %s %s" % (tag, commit))
+    self.step.Git("push origin %s" % tag)
+
+  def CLLand(self):
+    self.step.GitCLLand()
+
+
 class Step(GitRecipesMixin):
   def __init__(self, text, number, config, state, options, handler):
     self._text = text
@@ -263,9 +365,12 @@
     self._state = state
     self._options = options
     self._side_effect_handler = handler
+    self.vc = GitInterface()
+    self.vc.InjectStep(self)
 
     # The testing configuration might set a different default cwd.
-    self.default_cwd = self._config.get("DEFAULT_CWD") or DEFAULT_CWD
+    self.default_cwd = (self._config.get("DEFAULT_CWD") or
+                        os.path.join(self._options.work_dir, "v8"))
 
     assert self._number >= 0
     assert self._config is not None
@@ -354,11 +459,6 @@
       raise GitFailedException("'git %s' failed." % args)
     return result
 
-  def SVN(self, args="", prefix="", pipe=True, retry_on=None, cwd=None):
-    cmd = lambda: self._side_effect_handler.Command(
-        "svn", args, prefix, pipe, cwd=cwd or self.default_cwd)
-    return self.Retry(cmd, retry_on, [5, 30])
-
   def Editor(self, args):
     if self._options.requires_editor:
       return self._side_effect_handler.Command(
@@ -422,14 +522,17 @@
     self["current_branch"] = self.GitCurrentBranch()
 
     # Fetch unfetched revisions.
-    self.GitSVNFetch()
+    self.vc.Fetch()
 
   def PrepareBranch(self):
     # Delete the branch that will be created later if it exists already.
     self.DeleteBranch(self._config["BRANCHNAME"])
 
   def CommonCleanup(self):
-    self.GitCheckout(self["current_branch"])
+    if ' ' in self["current_branch"]:
+      self.GitCheckout('master')
+    else:
+      self.GitCheckout(self["current_branch"])
     if self._config["BRANCHNAME"] != self["current_branch"]:
       self.GitDeleteBranch(self._config["BRANCHNAME"])
 
@@ -493,7 +596,7 @@
       # Non-patched versions only have three numbers followed by the "(based
       # on...) comment."
       push_pattern += " (based"
-    branch = "" if parent_hash else branch or "svn/trunk"
+    branch = "" if parent_hash else branch or self.vc.RemoteCandidateBranch()
     return self.GitLog(n=1, format="%H", grep=push_pattern,
                        parent_hash=parent_hash, branch=branch)
 
@@ -517,21 +620,18 @@
       output += "%s\n" % line
     TextToFile(output, version_file)
 
-  def SVNCommit(self, root, commit_message):
-    patch = self.GitDiff("HEAD^", "HEAD")
-    TextToFile(patch, self._config["PATCH_FILE"])
-    self.Command("svn", "update", cwd=self._options.svn)
-    if self.Command("svn", "status", cwd=self._options.svn) != "":
-      self.Die("SVN checkout not clean.")
-    if not self.Command("patch", "-d %s -p1 -i %s" %
-                        (root, self._config["PATCH_FILE"]),
-                        cwd=self._options.svn):
-      self.Die("Could not apply patch.")
-    self.Command(
-        "svn",
-        "commit --non-interactive --username=%s --config-dir=%s -m \"%s\"" %
-            (self._options.author, self._options.svn_config, commit_message),
-        cwd=self._options.svn)
+
+class BootstrapStep(Step):
+  MESSAGE = "Bootstapping v8 checkout."
+
+  def RunStep(self):
+    if os.path.realpath(self.default_cwd) == os.path.realpath(V8_BASE):
+      self.Die("Can't use v8 checkout with calling script as work checkout.")
+    # Directory containing the working v8 checkout.
+    if not os.path.exists(self._options.work_dir):
+      os.makedirs(self._options.work_dir)
+    if not os.path.exists(self.default_cwd):
+      self.Command("fetch", "v8", cwd=self._options.work_dir)
 
 
 class UploadStep(Step):
@@ -546,7 +646,8 @@
       self.DieNoManualMode("A reviewer must be specified in forced mode.")
       reviewer = self.ReadLine()
     self.GitUpload(reviewer, self._options.author, self._options.force_upload,
-                   bypass_hooks=self._options.bypass_upload_hooks)
+                   bypass_hooks=self._options.bypass_upload_hooks,
+                   cc=self._options.cc)
 
 
 class DetermineV8Sheriff(Step):
@@ -600,7 +701,6 @@
 
 
 class ScriptsBase(object):
-  # TODO(machenbach): Move static config here.
   def __init__(self,
                config=None,
                side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER,
@@ -638,14 +738,12 @@
                         help=("Determine current sheriff to review CLs. On "
                               "success, this will overwrite the reviewer "
                               "option."))
-    parser.add_argument("--svn",
-                        help=("Optional full svn checkout for the commit."
-                              "The folder needs to be the svn root."))
-    parser.add_argument("--svn-config",
-                        help=("Optional folder used as svn --config-dir."))
     parser.add_argument("-s", "--step",
         help="Specify the step where to start work. Default: 0.",
         default=0, type=int)
+    parser.add_argument("--work-dir",
+                        help=("Location where to bootstrap a working v8 "
+                              "checkout."))
     self._PrepareOptions(parser)
 
     if args is None:  # pragma: no cover
@@ -662,10 +760,6 @@
       print "To determine the current sheriff, requires the googler mapping"
       parser.print_help()
       return None
-    if options.svn and not options.svn_config:
-      print "Using pure svn for committing requires also --svn-config"
-      parser.print_help()
-      return None
 
     # Defaults for options, common to all scripts.
     options.manual = getattr(options, "manual", True)
@@ -682,6 +776,9 @@
     if not self._ProcessOptions(options):
       parser.print_help()
       return None
+
+    if not options.work_dir:
+      options.work_dir = "/tmp/v8-release-scripts-work-dir"
     return options
 
   def RunSteps(self, step_classes, args=None):
@@ -694,7 +791,7 @@
       os.remove(state_file)
 
     steps = []
-    for (number, step_class) in enumerate(step_classes):
+    for (number, step_class) in enumerate([BootstrapStep] + step_classes):
       steps.append(MakeStep(step_class, number, self._state, self._config,
                             options, self._side_effect_handler))
     for step in steps[options.step:]:
diff --git a/tools/push-to-trunk/generate_version.py b/tools/push-to-trunk/generate_version.py
new file mode 100755
index 0000000..b4a0221
--- /dev/null
+++ b/tools/push-to-trunk/generate_version.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python
+# Copyright 2014 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""
+Script to set v8's version file to the version given by the latest tag.
+"""
+
+
+import os
+import re
+import subprocess
+import sys
+
+
+CWD = os.path.abspath(
+    os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
+VERSION_CC = os.path.join(CWD, "src", "version.cc")
+
+def main():
+  tag = subprocess.check_output(
+      "git describe --tags",
+      shell=True,
+      cwd=CWD,
+  ).strip()
+  assert tag
+
+  # Check for commits not exactly matching a tag. Those are candidate builds
+  # for the next version. The output has the form
+  # <tag name>-<n commits>-<hash>.
+  if "-" in tag:
+    version = tag.split("-")[0]
+    candidate = "1"
+  else:
+    version = tag
+    candidate = "0"
+  version_levels = version.split(".")
+
+  # Set default patch level if none is given.
+  if len(version_levels) == 3:
+    version_levels.append("0")
+  assert len(version_levels) == 4
+
+  major, minor, build, patch = version_levels
+
+  # Increment build level for candidate builds.
+  if candidate == "1":
+    build = str(int(build) + 1)
+    patch = "0"
+
+  # Modify version.cc with the new values.
+  with open(VERSION_CC, "r") as f:
+    text = f.read()
+  output = []
+  for line in text.split("\n"):
+    for definition, substitute in (
+        ("MAJOR_VERSION", major),
+        ("MINOR_VERSION", minor),
+        ("BUILD_NUMBER", build),
+        ("PATCH_LEVEL", patch),
+        ("IS_CANDIDATE_VERSION", candidate)):
+      if line.startswith("#define %s" % definition):
+        line =  re.sub("\d+$", substitute, line)
+    output.append(line)
+  with open(VERSION_CC, "w") as f:
+    f.write("\n".join(output))
+
+  # Log what was done.
+  candidate_txt = " (candidate)" if candidate == "1" else ""
+  patch_txt = ".%s" % patch if patch != "0" else ""
+  version_txt = ("%s.%s.%s%s%s" %
+                 (major, minor, build, patch_txt, candidate_txt))
+  print "Modified version.cc. Set V8 version to %s" %  version_txt
+  return 0
+
+if __name__ == "__main__":
+  sys.exit(main())
diff --git a/tools/push-to-trunk/git_recipes.py b/tools/push-to-trunk/git_recipes.py
index 0f8fcef..3d2a9ef 100644
--- a/tools/push-to-trunk/git_recipes.py
+++ b/tools/push-to-trunk/git_recipes.py
@@ -45,7 +45,7 @@
 
 # e.g., git-svn-id: https://v8.googlecode.com/svn/trunk@23117
 #     ce2b1a6d-e550-0410-aec6-3dcde31c8c00
-GIT_SVN_ID_RE = re.compile(r'((?:\w+)://[^@]+)@(\d+)\s+(?:[a-zA-Z0-9\-]+)')
+GIT_SVN_ID_RE = re.compile(r'[^@]+@(\d+)\s+(?:[a-zA-Z0-9\-]+)')
 
 
 # Copied from bot_update.py.
@@ -80,7 +80,11 @@
 
 def Strip(f):
   def new_f(*args, **kwargs):
-    return f(*args, **kwargs).strip()
+    result = f(*args, **kwargs)
+    if result is None:
+      return result
+    else:
+      return result.strip()
   return new_f
 
 
@@ -101,9 +105,10 @@
   def GitBranch(self, **kwargs):
     return self.Git("branch", **kwargs)
 
-  def GitCreateBranch(self, name, branch="", **kwargs):
+  def GitCreateBranch(self, name, remote="", **kwargs):
     assert name
-    self.Git(MakeArgs(["checkout -b", name, branch]), **kwargs)
+    remote_args = ["--upstream", remote] if remote else []
+    self.Git(MakeArgs(["new-branch", name] + remote_args), **kwargs)
 
   def GitDeleteBranch(self, name, **kwargs):
     assert name
@@ -194,7 +199,7 @@
     self.Git(MakeArgs(args), **kwargs)
 
   def GitUpload(self, reviewer="", author="", force=False, cq=False,
-                bypass_hooks=False, **kwargs):
+                bypass_hooks=False, cc="", **kwargs):
     args = ["cl upload --send-mail"]
     if author:
       args += ["--email", Quoted(author)]
@@ -206,6 +211,8 @@
       args.append("--use-commit-queue")
     if bypass_hooks:
       args.append("--bypass-hooks")
+    if cc:
+      args += ["--cc", Quoted(cc)]
     # TODO(machenbach): Check output in forced mode. Verify that all required
     # base files were uploaded, if not retry.
     self.Git(MakeArgs(args), pipe=False, **kwargs)
@@ -224,9 +231,9 @@
   def GitPresubmit(self, **kwargs):
     self.Git("cl presubmit", "PRESUBMIT_TREE_CHECK=\"skip\"", **kwargs)
 
-  def GitDCommit(self, **kwargs):
+  def GitCLLand(self, **kwargs):
     self.Git(
-        "cl dcommit -f --bypass-hooks", retry_on=lambda x: x is None, **kwargs)
+        "cl land -f --bypass-hooks", retry_on=lambda x: x is None, **kwargs)
 
   def GitDiff(self, loc1, loc2, **kwargs):
     return self.Git(MakeArgs(["diff", loc1, loc2]), **kwargs)
@@ -237,17 +244,6 @@
   def GitFetchOrigin(self, **kwargs):
     self.Git("fetch origin", **kwargs)
 
-  def GitConvertToSVNRevision(self, git_hash, **kwargs):
-    result = self.Git(MakeArgs(["rev-list", "-n", "1", git_hash]), **kwargs)
-    if not result or not SHA1_RE.match(result):
-      raise GitFailedException("Git hash %s is unknown." % git_hash)
-    log = self.GitLog(n=1, format="%B", git_hash=git_hash, **kwargs)
-    for line in reversed(log.splitlines()):
-      match = ROLL_DEPS_GIT_SVN_ID_RE.match(line.strip())
-      if match:
-        return match.group(1)
-    raise GitFailedException("Couldn't convert %s to SVN." % git_hash)
-
   @Strip
   # Copied from bot_update.py and modified for svn-like numbers only.
   def GetCommitPositionNumber(self, git_hash, **kwargs):
@@ -274,36 +270,6 @@
     if value:
       match = GIT_SVN_ID_RE.match(value)
       if match:
-        return match.group(2)
-    return None
-
-  ### Git svn stuff
-
-  def GitSVNFetch(self, **kwargs):
-    self.Git("svn fetch", **kwargs)
-
-  def GitSVNRebase(self, **kwargs):
-    self.Git("svn rebase", **kwargs)
-
-  # TODO(machenbach): Unused? Remove.
-  @Strip
-  def GitSVNLog(self, **kwargs):
-    return self.Git("svn log -1 --oneline", **kwargs)
-
-  @Strip
-  def GitSVNFindGitHash(self, revision, branch="", **kwargs):
-    assert revision
-    return self.Git(
-        MakeArgs(["svn find-rev", "r%s" % revision, branch]), **kwargs)
-
-  @Strip
-  def GitSVNFindSVNRev(self, git_hash, branch="", **kwargs):
-    return self.Git(MakeArgs(["svn find-rev", git_hash, branch]), **kwargs)
-
-  def GitSVNDCommit(self, **kwargs):
-    return self.Git("svn dcommit 2>&1", retry_on=lambda x: x is None, **kwargs)
-
-  def GitSVNTag(self, version, **kwargs):
-    self.Git(("svn tag %s -m \"Tagging version %s\"" % (version, version)),
-             retry_on=lambda x: x is None,
-             **kwargs)
+        return match.group(1)
+    raise GitFailedException("Couldn't determine commit position for %s" %
+                             git_hash)
diff --git a/tools/push-to-trunk/merge_to_branch.py b/tools/push-to-trunk/merge_to_branch.py
index 3fd3450..9e7f1fb 100755
--- a/tools/push-to-trunk/merge_to_branch.py
+++ b/tools/push-to-trunk/merge_to_branch.py
@@ -32,6 +32,9 @@
 
 from common_includes import *
 
+def IsSvnNumber(rev):
+  return rev.isdigit() and len(rev) < 8
+
 class Preparation(Step):
   MESSAGE = "Preparation."
 
@@ -45,6 +48,7 @@
 
     self.InitialEnvironmentChecks(self.default_cwd)
     if self._options.revert_bleeding_edge:
+      # FIXME(machenbach): Make revert bleeding_edge obsolete?
       self["merge_to_branch"] = "bleeding_edge"
     elif self._options.branch:
       self["merge_to_branch"] = self._options.branch
@@ -60,7 +64,7 @@
 
   def RunStep(self):
     self.GitCreateBranch(self.Config("BRANCHNAME"),
-                         "svn/%s" % self["merge_to_branch"])
+                         self.vc.RemoteBranch(self["merge_to_branch"]))
 
 
 class SearchArchitecturePorts(Step):
@@ -71,24 +75,21 @@
         self._options.revisions))
     port_revision_list = []
     for revision in self["full_revision_list"]:
-      # Search for commits which matches the "Port rXXX" pattern.
+      # Search for commits which matches the "Port XXX" pattern.
       git_hashes = self.GitLog(reverse=True, format="%H",
-                               grep="Port r%d" % int(revision),
-                               branch="svn/bleeding_edge")
+                               grep="Port %s" % revision,
+                               branch=self.vc.RemoteMasterBranch())
       for git_hash in git_hashes.splitlines():
-        svn_revision = self.GitSVNFindSVNRev(git_hash, "svn/bleeding_edge")
-        if not svn_revision:  # pragma: no cover
-          self.Die("Cannot determine svn revision for %s" % git_hash)
         revision_title = self.GitLog(n=1, format="%s", git_hash=git_hash)
 
         # Is this revision included in the original revision list?
-        if svn_revision in self["full_revision_list"]:
-          print("Found port of r%s -> r%s (already included): %s"
-                % (revision, svn_revision, revision_title))
+        if git_hash in self["full_revision_list"]:
+          print("Found port of %s -> %s (already included): %s"
+                % (revision, git_hash, revision_title))
         else:
-          print("Found port of r%s -> r%s: %s"
-                % (revision, svn_revision, revision_title))
-          port_revision_list.append(svn_revision)
+          print("Found port of %s -> %s: %s"
+                % (revision, git_hash, revision_title))
+          port_revision_list.append(git_hash)
 
     # Do we find any port?
     if len(port_revision_list) > 0:
@@ -98,16 +99,10 @@
         self["full_revision_list"].extend(port_revision_list)
 
 
-class FindGitRevisions(Step):
-  MESSAGE = "Find the git revisions associated with the patches."
+class CreateCommitMessage(Step):
+  MESSAGE = "Create commit message."
 
   def RunStep(self):
-    self["patch_commit_hashes"] = []
-    for revision in self["full_revision_list"]:
-      next_hash = self.GitSVNFindGitHash(revision, "svn/bleeding_edge")
-      if not next_hash:  # pragma: no cover
-        self.Die("Cannot determine git hash for r%s" % revision)
-      self["patch_commit_hashes"].append(next_hash)
 
     # Stringify: [123, 234] -> "r123, r234"
     self["revision_list"] = ", ".join(map(lambda s: "r%s" % s,
@@ -116,29 +111,38 @@
     if not self["revision_list"]:  # pragma: no cover
       self.Die("Revision list is empty.")
 
-    # The commit message title is added below after the version is specified.
-    self["new_commit_msg"] = ""
+    if self._options.revert and not self._options.revert_bleeding_edge:
+      action_text = "Rollback of %s"
+    else:
+      action_text = "Merged %s"
 
-    for commit_hash in self["patch_commit_hashes"]:
+    # The commit message title is added below after the version is specified.
+    msg_pieces = [
+      "\n".join(action_text % s for s in self["full_revision_list"]),
+    ]
+    msg_pieces.append("\n\n")
+
+    for commit_hash in self["full_revision_list"]:
       patch_merge_desc = self.GitLog(n=1, format="%s", git_hash=commit_hash)
-      self["new_commit_msg"] += "%s\n\n" % patch_merge_desc
+      msg_pieces.append("%s\n\n" % patch_merge_desc)
 
     bugs = []
-    for commit_hash in self["patch_commit_hashes"]:
+    for commit_hash in self["full_revision_list"]:
       msg = self.GitLog(n=1, git_hash=commit_hash)
-      for bug in re.findall(r"^[ \t]*BUG[ \t]*=[ \t]*(.*?)[ \t]*$", msg,
-                            re.M):
-        bugs.extend(map(lambda s: s.strip(), bug.split(",")))
+      for bug in re.findall(r"^[ \t]*BUG[ \t]*=[ \t]*(.*?)[ \t]*$", msg, re.M):
+        bugs.extend(s.strip() for s in bug.split(","))
     bug_aggregate = ",".join(sorted(filter(lambda s: s and s != "none", bugs)))
     if bug_aggregate:
-      self["new_commit_msg"] += "BUG=%s\nLOG=N\n" % bug_aggregate
+      msg_pieces.append("BUG=%s\nLOG=N\n" % bug_aggregate)
+
+    self["new_commit_msg"] = "".join(msg_pieces)
 
 
 class ApplyPatches(Step):
   MESSAGE = "Apply patches for selected revisions."
 
   def RunStep(self):
-    for commit_hash in self["patch_commit_hashes"]:
+    for commit_hash in self["full_revision_list"]:
       print("Applying patch for %s to %s..."
             % (commit_hash, self["merge_to_branch"]))
       patch = self.GitGetPatch(commit_hash)
@@ -188,16 +192,14 @@
 
   def RunStep(self):
     # Add a commit message title.
-    if self._options.revert:
-      if not self._options.revert_bleeding_edge:
-        title = ("Version %s (rollback of %s)"
-                 % (self["version"], self["revision_list"]))
-      else:
-        title = "Revert %s." % self["revision_list"]
+    if self._options.revert and self._options.revert_bleeding_edge:
+      # TODO(machenbach): Find a better convention if multiple patches are
+      # reverted in one CL.
+      self["commit_title"] = "Revert on master"
     else:
-      title = ("Version %s (merged %s)"
-               % (self["version"], self["revision_list"]))
-    self["new_commit_msg"] = "%s\n\n%s" % (title, self["new_commit_msg"])
+      self["commit_title"] = "Version %s (cherry-pick)" % self["version"]
+    self["new_commit_msg"] = "%s\n\n%s" % (self["commit_title"],
+                                           self["new_commit_msg"])
     TextToFile(self["new_commit_msg"], self.Config("COMMITMSG_FILE"))
     self.GitCommit(file_name=self.Config("COMMITMSG_FILE"))
 
@@ -209,22 +211,7 @@
     self.GitCheckout(self.Config("BRANCHNAME"))
     self.WaitForLGTM()
     self.GitPresubmit()
-    self.GitDCommit()
-
-
-class PrepareSVN(Step):
-  MESSAGE = "Determine svn commit revision."
-
-  def RunStep(self):
-    if self._options.revert_bleeding_edge:
-      return
-    self.GitSVNFetch()
-    commit_hash = self.GitLog(n=1, format="%H", grep=self["new_commit_msg"],
-                              branch="svn/%s" % self["merge_to_branch"])
-    if not commit_hash:  # pragma: no cover
-      self.Die("Unable to map git commit to svn revision.")
-    self["svn_revision"] = self.GitSVNFindSVNRev(commit_hash)
-    print "subversion revision number is r%s" % self["svn_revision"]
+    self.vc.CLLand()
 
 
 class TagRevision(Step):
@@ -233,16 +220,10 @@
   def RunStep(self):
     if self._options.revert_bleeding_edge:
       return
-    print "Creating tag svn/tags/%s" % self["version"]
-    if self["merge_to_branch"] == "trunk":
-      self["to_url"] = "trunk"
-    else:
-      self["to_url"] = "branches/%s" % self["merge_to_branch"]
-    self.SVN("copy -r %s https://v8.googlecode.com/svn/%s "
-             "https://v8.googlecode.com/svn/tags/%s -m "
-             "\"Tagging version %s\""
-             % (self["svn_revision"], self["to_url"],
-                self["version"], self["version"]))
+    print "Creating tag %s" % self["version"]
+    self.vc.Tag(self["version"],
+                self.vc.RemoteBranch(self["merge_to_branch"]),
+                self["commit_title"])
 
 
 class CleanUp(Step):
@@ -253,8 +234,7 @@
     if not self._options.revert_bleeding_edge:
       print "*** SUMMARY ***"
       print "version: %s" % self["version"]
-      print "branch: %s" % self["to_url"]
-      print "svn revision: %s" % self["svn_revision"]
+      print "branch: %s" % self["merge_to_branch"]
       if self["revision_list"]:
         print "patches: %s" % self["revision_list"]
 
@@ -293,6 +273,16 @@
         print "You must specify a merge comment if no patches are specified"
         return False
     options.bypass_upload_hooks = True
+    # CC ulan to make sure that fixes are merged to Google3.
+    options.cc = "ulan@chromium.org"
+
+    # Make sure to use git hashes in the new workflows.
+    for revision in options.revisions:
+      if (IsSvnNumber(revision) or
+          (revision[0:1] == "r" and IsSvnNumber(revision[1:]))):
+        print "Please provide full git hashes of the patches to merge."
+        print "Got: %s" % revision
+        return False
     return True
 
   def _Config(self):
@@ -310,14 +300,13 @@
       Preparation,
       CreateBranch,
       SearchArchitecturePorts,
-      FindGitRevisions,
+      CreateCommitMessage,
       ApplyPatches,
       PrepareVersion,
       IncrementVersion,
       CommitLocal,
       UploadStep,
       CommitRepository,
-      PrepareSVN,
       TagRevision,
       CleanUp,
     ]
diff --git a/tools/push-to-trunk/push_to_trunk.py b/tools/push-to-trunk/push_to_trunk.py
index 8a9629e..6e821f2 100755
--- a/tools/push-to-trunk/push_to_trunk.py
+++ b/tools/push-to-trunk/push_to_trunk.py
@@ -34,8 +34,8 @@
 
 from common_includes import *
 
-PUSH_MESSAGE_SUFFIX = " (based on bleeding_edge revision r%d)"
-PUSH_MESSAGE_RE = re.compile(r".* \(based on bleeding_edge revision r(\d+)\)$")
+PUSH_MSG_GIT_SUFFIX = " (based on %s)"
+PUSH_MSG_GIT_RE = re.compile(r".* \(based on (?P<git_rev>[a-fA-F0-9]+)\)$")
 
 class Preparation(Step):
   MESSAGE = "Preparation."
@@ -56,7 +56,8 @@
   MESSAGE = "Create a fresh branch."
 
   def RunStep(self):
-    self.GitCreateBranch(self.Config("BRANCHNAME"), "svn/bleeding_edge")
+    self.GitCreateBranch(self.Config("BRANCHNAME"),
+                         self.vc.RemoteMasterBranch())
 
 
 class PreparePushRevision(Step):
@@ -64,7 +65,7 @@
 
   def RunStep(self):
     if self._options.revision:
-      self["push_hash"] = self.GitSVNFindGitHash(self._options.revision)
+      self["push_hash"] = self._options.revision
     else:
       self["push_hash"] = self.GitLog(n=1, format="%H", git_hash="HEAD")
     if not self["push_hash"]:  # pragma: no cover
@@ -91,16 +92,14 @@
       # Retrieve the bleeding edge revision of the last push from the text in
       # the push commit message.
       last_push_title = self.GitLog(n=1, format="%s", git_hash=last_push)
-      last_push_be_svn = PUSH_MESSAGE_RE.match(last_push_title).group(1)
-      if not last_push_be_svn:  # pragma: no cover
-        self.Die("Could not retrieve bleeding edge revision for trunk push %s"
-                 % last_push)
-      last_push_bleeding_edge = self.GitSVNFindGitHash(last_push_be_svn)
+      last_push_bleeding_edge = PUSH_MSG_GIT_RE.match(
+          last_push_title).group("git_rev")
+
       if not last_push_bleeding_edge:  # pragma: no cover
         self.Die("Could not retrieve bleeding edge git hash for trunk push %s"
                  % last_push)
 
-    # This points to the svn revision of the last push on trunk.
+    # This points to the git hash of the last push on trunk.
     self["last_push_trunk"] = last_push
     # This points to the last bleeding_edge revision that went into the last
     # push.
@@ -116,7 +115,7 @@
   MESSAGE = "Get latest bleeding edge version."
 
   def RunStep(self):
-    self.GitCheckoutFile(VERSION_FILE, "svn/bleeding_edge")
+    self.GitCheckoutFile(VERSION_FILE, self.vc.RemoteMasterBranch())
 
     # Store latest version.
     self.ReadAndPersistVersion("latest_")
@@ -140,7 +139,7 @@
 
     if SortingKey(self["trunk_version"]) < SortingKey(self["latest_version"]):
       # If the version on bleeding_edge is newer than on trunk, use it.
-      self.GitCheckoutFile(VERSION_FILE, "svn/bleeding_edge")
+      self.GitCheckoutFile(VERSION_FILE, self.vc.RemoteMasterBranch())
       self.ReadAndPersistVersion()
 
     if self.Confirm(("Automatically increment BUILD_NUMBER? (Saying 'n' will "
@@ -249,8 +248,8 @@
              "started.")
 
   def RunStep(self):
-    self.GitSVNFetch()
-    self.GitCheckout("svn/bleeding_edge")
+    self.vc.Fetch()
+    self.GitCheckout(self.vc.RemoteMasterBranch())
 
 
 class SquashCommits(Step):
@@ -259,7 +258,8 @@
   def RunStep(self):
     # Instead of relying on "git rebase -i", we'll just create a diff, because
     # that's easier to automate.
-    TextToFile(self.GitDiff("svn/trunk", self["push_hash"]),
+    TextToFile(self.GitDiff(self.vc.RemoteCandidateBranch(),
+                            self["push_hash"]),
                self.Config("PATCH_FILE"))
 
     # Convert the ChangeLog entry to commit message format.
@@ -268,10 +268,8 @@
     # Remove date and trailing white space.
     text = re.sub(r"^%s: " % self["date"], "", text.rstrip())
 
-    # Retrieve svn revision for showing the used bleeding edge revision in the
-    # commit message.
-    self["svn_revision"] = self.GitSVNFindSVNRev(self["push_hash"])
-    suffix = PUSH_MESSAGE_SUFFIX % int(self["svn_revision"])
+    # Show the used master hash in the commit message.
+    suffix = PUSH_MSG_GIT_SUFFIX % self["push_hash"]
     text = MSub(r"^(Version \d+\.\d+\.\d+)$", "\\1%s" % suffix, text)
 
     # Remove indentation and merge paragraphs into single long lines, keeping
@@ -283,6 +281,7 @@
 
     if not text:  # pragma: no cover
       self.Die("Commit message editing failed.")
+    self["commit_title"] = text.splitlines()[0]
     TextToFile(text, self.Config("COMMITMSG_FILE"))
 
 
@@ -290,7 +289,8 @@
   MESSAGE = "Create a new branch from trunk."
 
   def RunStep(self):
-    self.GitCreateBranch(self.Config("TRUNKBRANCH"), "svn/trunk")
+    self.GitCreateBranch(self.Config("TRUNKBRANCH"),
+                         self.vc.RemoteCandidateBranch())
 
 
 class ApplyChanges(Step):
@@ -308,11 +308,11 @@
     # The change log has been modified by the patch. Reset it to the version
     # on trunk and apply the exact changes determined by this PrepareChangeLog
     # step above.
-    self.GitCheckoutFile(self.Config("CHANGELOG_FILE"), "svn/trunk")
+    self.GitCheckoutFile(CHANGELOG_FILE, self.vc.RemoteCandidateBranch())
     changelog_entry = FileToText(self.Config("CHANGELOG_ENTRY_FILE"))
-    old_change_log = FileToText(self.Config("CHANGELOG_FILE"))
+    old_change_log = FileToText(os.path.join(self.default_cwd, CHANGELOG_FILE))
     new_change_log = "%s\n\n\n%s" % (changelog_entry, old_change_log)
-    TextToFile(new_change_log, self.Config("CHANGELOG_FILE"))
+    TextToFile(new_change_log, os.path.join(self.default_cwd, CHANGELOG_FILE))
     os.remove(self.Config("CHANGELOG_ENTRY_FILE"))
 
 
@@ -322,7 +322,7 @@
   def RunStep(self):
     # The version file has been modified by the patch. Reset it to the version
     # on trunk and apply the correct version.
-    self.GitCheckoutFile(VERSION_FILE, "svn/trunk")
+    self.GitCheckoutFile(VERSION_FILE, self.vc.RemoteCandidateBranch())
     self.SetVersion(os.path.join(self.default_cwd, VERSION_FILE), "new_")
 
 
@@ -346,35 +346,19 @@
       self.Die("Execution canceled.")  # pragma: no cover
 
 
-class CommitSVN(Step):
-  MESSAGE = "Commit to SVN."
+class Land(Step):
+  MESSAGE = "Land the patch."
 
   def RunStep(self):
-    result = self.GitSVNDCommit()
-    if not result:  # pragma: no cover
-      self.Die("'git svn dcommit' failed.")
-    result = filter(lambda x: re.search(r"^Committed r[0-9]+", x),
-                    result.splitlines())
-    if len(result) > 0:
-      self["trunk_revision"] = re.sub(r"^Committed r([0-9]+)", r"\1",result[0])
-
-    # Sometimes grepping for the revision fails. No idea why. If you figure
-    # out why it is flaky, please do fix it properly.
-    if not self["trunk_revision"]:
-      print("Sorry, grepping for the SVN revision failed. Please look for it "
-            "in the last command's output above and provide it manually (just "
-            "the number, without the leading \"r\").")
-      self.DieNoManualMode("Can't prompt in forced mode.")
-      while not self["trunk_revision"]:
-        print "> ",
-        self["trunk_revision"] = self.ReadLine()
+    self.vc.CLLand()
 
 
 class TagRevision(Step):
   MESSAGE = "Tag the new revision."
 
   def RunStep(self):
-    self.GitSVNTag(self["version"])
+    self.vc.Tag(
+        self["version"], self.vc.RemoteCandidateBranch(), self["commit_title"])
 
 
 class CleanUp(Step):
@@ -382,10 +366,8 @@
 
   def RunStep(self):
     print("Congratulations, you have successfully created the trunk "
-          "revision %s. Please don't forget to roll this new version into "
-          "Chromium, and to update the v8rel spreadsheet:"
+          "revision %s."
           % self["version"])
-    print "%s\ttrunk\t%s" % (self["version"], self["trunk_revision"])
 
     self.CommonCleanup()
     if self.Config("TRUNKBRANCH") != self["current_branch"]:
@@ -408,7 +390,7 @@
     parser.add_argument("-l", "--last-push",
                         help="The git commit ID of the last push to trunk.")
     parser.add_argument("-R", "--revision",
-                        help="The svn revision to push (defaults to HEAD).")
+                        help="The git commit ID to push (defaults to HEAD).")
 
   def _ProcessOptions(self, options):  # pragma: no cover
     if not options.manual and not options.reviewer:
@@ -417,10 +399,6 @@
     if not options.manual and not options.author:
       print "Specify your chromium.org email with -a in (semi-)automatic mode."
       return False
-    if options.revision and not int(options.revision) > 0:
-      print("The --revision flag must be a positiv integer pointing to a "
-            "valid svn revision.")
-      return False
 
     options.tbr_commit = not options.manual
     return True
@@ -430,7 +408,6 @@
       "BRANCHNAME": "prepare-push",
       "TRUNKBRANCH": "trunk-push",
       "PERSISTFILE_BASENAME": "/tmp/v8-push-to-trunk-tempfile",
-      "CHANGELOG_FILE": "ChangeLog",
       "CHANGELOG_ENTRY_FILE": "/tmp/v8-push-to-trunk-tempfile-changelog-entry",
       "PATCH_FILE": "/tmp/v8-push-to-trunk-tempfile-patch-file",
       "COMMITMSG_FILE": "/tmp/v8-push-to-trunk-tempfile-commitmsg",
@@ -454,7 +431,7 @@
       SetVersion,
       CommitTrunk,
       SanityCheck,
-      CommitSVN,
+      Land,
       TagRevision,
       CleanUp,
     ]
diff --git a/tools/push-to-trunk/releases.py b/tools/push-to-trunk/releases.py
index 1d26198..1a5b15c 100755
--- a/tools/push-to-trunk/releases.py
+++ b/tools/push-to-trunk/releases.py
@@ -26,16 +26,25 @@
 }
 
 # Expression for retrieving the bleeding edge revision from a commit message.
-PUSH_MESSAGE_RE = re.compile(r".* \(based on bleeding_edge revision r(\d+)\)$")
+PUSH_MSG_SVN_RE = re.compile(r".* \(based on bleeding_edge revision r(\d+)\)$")
+PUSH_MSG_GIT_RE = re.compile(r".* \(based on ([a-fA-F0-9]+)\)$")
 
 # Expression for retrieving the merged patches from a merge commit message
 # (old and new format).
 MERGE_MESSAGE_RE = re.compile(r"^.*[M|m]erged (.+)(\)| into).*$", re.M)
 
+CHERRY_PICK_TITLE_GIT_RE = re.compile(r"^.* \(cherry\-pick\)\.?$")
+
+# New git message for cherry-picked CLs. One message per line.
+MERGE_MESSAGE_GIT_RE = re.compile(r"^Merged ([a-fA-F0-9]+)\.?$")
+
 # Expression for retrieving reverted patches from a commit message (old and
 # new format).
 ROLLBACK_MESSAGE_RE = re.compile(r"^.*[R|r]ollback of (.+)(\)| in).*$", re.M)
 
+# New git message for reverted CLs. One message per line.
+ROLLBACK_MESSAGE_GIT_RE = re.compile(r"^Rollback of ([a-fA-F0-9]+)\.?$")
+
 # Expression for retrieving the code review link.
 REVIEW_LINK_RE = re.compile(r"^Review URL: (.+)$", re.M)
 
@@ -127,8 +136,8 @@
     return (self._options.max_releases > 0
             and len(releases) > self._options.max_releases)
 
-  def GetBleedingEdgeFromPush(self, title):
-    return MatchSafe(PUSH_MESSAGE_RE.match(title))
+  def GetBleedingEdgeGitFromPush(self, title):
+    return MatchSafe(PUSH_MSG_GIT_RE.match(title))
 
   def GetMergedPatches(self, body):
     patches = MatchSafe(MERGE_MESSAGE_RE.search(body))
@@ -139,14 +148,31 @@
         patches = "-%s" % patches
     return patches
 
+  def GetMergedPatchesGit(self, body):
+    patches = []
+    for line in body.splitlines():
+      patch = MatchSafe(MERGE_MESSAGE_GIT_RE.match(line))
+      if patch:
+        patches.append(patch)
+      patch = MatchSafe(ROLLBACK_MESSAGE_GIT_RE.match(line))
+      if patch:
+        patches.append("-%s" % patch)
+    return ", ".join(patches)
+
+
   def GetReleaseDict(
-      self, git_hash, bleeding_edge_rev, branch, version, patches, cl_body):
-    revision = self.GitSVNFindSVNRev(git_hash)
+      self, git_hash, bleeding_edge_rev, bleeding_edge_git, branch, version,
+      patches, cl_body):
+    revision = self.GetCommitPositionNumber(git_hash)
     return {
-      # The SVN revision on the branch.
+      # The cr commit position number on the branch.
       "revision": revision,
-      # The SVN revision on bleeding edge (only for newer trunk pushes).
+      # The git revision on the branch.
+      "revision_git": git_hash,
+      # The cr commit position number on master.
       "bleeding_edge": bleeding_edge_rev,
+      # The same for git.
+      "bleeding_edge_git": bleeding_edge_git,
       # The branch name.
       "branch": branch,
       # The version for displaying in the form 3.26.3 or 3.26.3.12.
@@ -176,29 +202,40 @@
     patches = ""
     if self["patch"] != "0":
       version += ".%s" % self["patch"]
-      patches = self.GetMergedPatches(body)
+      if CHERRY_PICK_TITLE_GIT_RE.match(body.splitlines()[0]):
+        patches = self.GetMergedPatchesGit(body)
+      else:
+        patches = self.GetMergedPatches(body)
 
     title = self.GitLog(n=1, format="%s", git_hash=git_hash)
+    bleeding_edge_git = self.GetBleedingEdgeGitFromPush(title)
+    bleeding_edge_position = ""
+    if bleeding_edge_git:
+      bleeding_edge_position = self.GetCommitPositionNumber(bleeding_edge_git)
+    # TODO(machenbach): Add the commit position number.
     return self.GetReleaseDict(
-        git_hash, self.GetBleedingEdgeFromPush(title), branch, version,
+        git_hash, bleeding_edge_position, bleeding_edge_git, branch, version,
         patches, body), self["patch"]
 
-  def GetReleasesFromBleedingEdge(self):
-    tag_text = self.SVN("log https://v8.googlecode.com/svn/tags -v --limit 20")
-    releases = []
-    for (tag, revision) in re.findall(BLEEDING_EDGE_TAGS_RE, tag_text):
-      git_hash = self.GitSVNFindGitHash(revision)
+  def GetReleasesFromMaster(self):
+    # TODO(machenbach): Implement this in git as soon as we tag again on
+    # master.
+    # tag_text = self.SVN("log https://v8.googlecode.com/svn/tags -v
+    # --limit 20")
+    # releases = []
+    # for (tag, revision) in re.findall(BLEEDING_EDGE_TAGS_RE, tag_text):
+    #   git_hash = self.vc.SvnGit(revision)
 
       # Add bleeding edge release. It does not contain patches or a code
       # review link, as tags are not uploaded.
-      releases.append(self.GetReleaseDict(
-        git_hash, revision, "bleeding_edge", tag, "", ""))
-    return releases
+    #   releases.append(self.GetReleaseDict(
+    #     git_hash, revision, git_hash, self.vc.MasterBranch(), tag, "", ""))
+    return []
 
   def GetReleasesFromBranch(self, branch):
-    self.GitReset("svn/%s" % branch)
-    if branch == 'bleeding_edge':
-      return self.GetReleasesFromBleedingEdge()
+    self.GitReset(self.vc.RemoteBranch(branch))
+    if branch == self.vc.MasterBranch():
+      return self.GetReleasesFromMaster()
 
     releases = []
     try:
@@ -217,7 +254,7 @@
         # TODO(machenbach): This omits patches if the version file wasn't
         # manipulated correctly. Find a better way to detect the point where
         # the parent of the branch head leads to the trunk branch.
-        if branch != "trunk" and patch_level == "0":
+        if branch != self.vc.CandidateBranch() and patch_level == "0":
           break
 
     # Allow Ctrl-C interrupt.
@@ -230,12 +267,7 @@
 
   def RunStep(self):
     self.GitCreateBranch(self._config["BRANCHNAME"])
-    # Get relevant remote branches, e.g. "svn/3.25".
-    branches = filter(lambda s: re.match(r"^svn/\d+\.\d+$", s),
-                      self.GitRemotes())
-    # Remove 'svn/' prefix.
-    branches = map(lambda s: s[4:], branches)
-
+    branches = self.vc.GetBranches()
     releases = []
     if self._options.branch == 'recent':
       # Get only recent development on trunk, beta and stable.
@@ -244,17 +276,18 @@
       beta, stable = SortBranches(branches)[0:2]
       releases += self.GetReleasesFromBranch(stable)
       releases += self.GetReleasesFromBranch(beta)
-      releases += self.GetReleasesFromBranch("trunk")
-      releases += self.GetReleasesFromBranch("bleeding_edge")
+      releases += self.GetReleasesFromBranch(self.vc.CandidateBranch())
+      releases += self.GetReleasesFromBranch(self.vc.MasterBranch())
     elif self._options.branch == 'all':  # pragma: no cover
       # Retrieve the full release history.
       for branch in branches:
         releases += self.GetReleasesFromBranch(branch)
-      releases += self.GetReleasesFromBranch("trunk")
-      releases += self.GetReleasesFromBranch("bleeding_edge")
+      releases += self.GetReleasesFromBranch(self.vc.CandidateBranch())
+      releases += self.GetReleasesFromBranch(self.vc.MasterBranch())
     else:  # pragma: no cover
       # Retrieve history for a specified branch.
-      assert self._options.branch in branches + ["trunk", "bleeding_edge"]
+      assert self._options.branch in (branches +
+          [self.vc.CandidateBranch(), self.vc.MasterBranch()])
       releases += self.GetReleasesFromBranch(self._options.branch)
 
     self["releases"] = sorted(releases,
@@ -289,7 +322,7 @@
   # Simple check for git hashes.
   if revision.isdigit() and len(revision) < 8:
     return revision
-  return step.GitConvertToSVNRevision(
+  return step.GetCommitPositionNumber(
       revision, cwd=os.path.join(step._options.chromium, "v8"))
 
 
@@ -299,7 +332,9 @@
   def RunStep(self):
     cwd = self._options.chromium
     releases = filter(
-        lambda r: r["branch"] in ["trunk", "bleeding_edge"], self["releases"])
+        lambda r: r["branch"] in [self.vc.CandidateBranch(),
+                                  self.vc.MasterBranch()],
+        self["releases"])
     if not releases:  # pragma: no cover
       print "No releases detected. Skipping chromium history."
       return True
@@ -351,7 +386,8 @@
 
   def RunStep(self):
     cwd = self._options.chromium
-    trunk_releases = filter(lambda r: r["branch"] == "trunk", self["releases"])
+    trunk_releases = filter(lambda r: r["branch"] == self.vc.CandidateBranch(),
+                            self["releases"])
     if not trunk_releases:  # pragma: no cover
       print "No trunk releases detected. Skipping chromium history."
       return True
diff --git a/tools/push-to-trunk/test_scripts.py b/tools/push-to-trunk/test_scripts.py
index b0d1c58..db702a3 100644
--- a/tools/push-to-trunk/test_scripts.py
+++ b/tools/push-to-trunk/test_scripts.py
@@ -57,7 +57,6 @@
   "BRANCHNAME": "test-prepare-push",
   "TRUNKBRANCH": "test-trunk-push",
   "PERSISTFILE_BASENAME": "/tmp/test-v8-push-to-trunk-tempfile",
-  "CHANGELOG_FILE": None,
   "CHANGELOG_ENTRY_FILE": "/tmp/test-v8-push-to-trunk-tempfile-changelog-entry",
   "PATCH_FILE": "/tmp/test-v8-push-to-trunk-tempfile-patch",
   "COMMITMSG_FILE": "/tmp/test-v8-push-to-trunk-tempfile-commitmsg",
@@ -446,7 +445,7 @@
     self.Expect([
       Cmd("git status -s -uno", ""),
       Cmd("git status -s -b -uno", "## some_branch"),
-      Cmd("git svn fetch", ""),
+      Cmd("git fetch", ""),
       Cmd("git branch", "  branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
       RL("Y"),
       Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
@@ -459,7 +458,7 @@
     self.Expect([
       Cmd("git status -s -uno", ""),
       Cmd("git status -s -b -uno", "## some_branch"),
-      Cmd("git svn fetch", ""),
+      Cmd("git fetch", ""),
       Cmd("git branch", "  branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
       RL("n"),
     ])
@@ -471,7 +470,7 @@
     self.Expect([
       Cmd("git status -s -uno", ""),
       Cmd("git status -s -b -uno", "## some_branch"),
-      Cmd("git svn fetch", ""),
+      Cmd("git fetch", ""),
       Cmd("git branch", "  branch1\n* %s" % TEST_CONFIG["BRANCHNAME"]),
       RL("Y"),
       Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], None),
@@ -488,6 +487,23 @@
     ])
     self.MakeStep().InitialEnvironmentChecks(TEST_CONFIG["DEFAULT_CWD"])
 
+  def testTagTimeout(self):
+    self.Expect([
+      Cmd("git fetch", ""),
+      Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
+      Cmd("git fetch", ""),
+      Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
+      Cmd("git fetch", ""),
+      Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
+      Cmd("git fetch", ""),
+      Cmd("git log -1 --format=%H --grep=\"Title\" origin/candidates", ""),
+    ])
+    args = ["--branch", "candidates", "ab12345"]
+    self._state["version"] = "tag_name"
+    self._state["commit_title"] = "Title"
+    self.assertRaises(Exception,
+        lambda: self.RunStep(MergeToBranch, TagRevision, args))
+
   def testReadAndPersistVersion(self):
     self.WriteFakeVersionFile(build=5)
     step = self.MakeStep()
@@ -610,7 +626,7 @@
 
     self.Expect([
       Cmd("git checkout -f hash1 -- src/version.cc", ""),
-      Cmd("git checkout -f svn/bleeding_edge -- src/version.cc",
+      Cmd("git checkout -f origin/master -- src/version.cc",
           "", cb=lambda: self.WriteFakeVersionFile(22, 6)),
       RL("Y"),  # Increment build number.
     ])
@@ -628,8 +644,7 @@
       f.write(change_log)
 
     self.Expect([
-      Cmd("git diff svn/trunk hash1", "patch content"),
-      Cmd("git svn find-rev hash1", "123455\n"),
+      Cmd("git diff origin/candidates hash1", "patch content"),
     ])
 
     self._state["push_hash"] = "hash1"
@@ -648,7 +663,7 @@
         Chromium issue 12345
 
         Performance and stability improvements on all platforms.\n"""
-    commit_msg = """Version 3.22.5 (based on bleeding_edge revision r123455)
+    commit_msg = """Version 3.22.5 (based on hash1)
 
 Log text 1. Chromium issue 12345
 
@@ -662,7 +677,7 @@
         12345).
 
         Performance and stability improvements on all platforms.\n"""
-    commit_msg = """Version 3.22.5 (based on bleeding_edge revision r123455)
+    commit_msg = """Version 3.22.5 (based on hash1)
 
 Long commit message that fills more than 80 characters (Chromium issue 12345).
 
@@ -674,6 +689,21 @@
     commit_msg = """Line with "quotation marks"."""
     self._TestSquashCommits(change_log, commit_msg)
 
+  def testBootstrapper(self):
+    work_dir = self.MakeEmptyTempDirectory()
+    class FakeScript(ScriptsBase):
+      def _Steps(self):
+        return []
+
+    # Use the test configuration without the fake testing default work dir.
+    fake_config = dict(TEST_CONFIG)
+    del(fake_config["DEFAULT_CWD"])
+
+    self.Expect([
+      Cmd("fetch v8", "", cwd=work_dir),
+    ])
+    FakeScript(fake_config, self).Run(["--work-dir", work_dir])
+
   def _PushToTrunk(self, force=False, manual=False):
     TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
 
@@ -682,9 +712,9 @@
     self.WriteFakeVersionFile(build=5)
 
     TEST_CONFIG["CHANGELOG_ENTRY_FILE"] = self.MakeEmptyTempFile()
-    TEST_CONFIG["CHANGELOG_FILE"] = self.MakeEmptyTempFile()
     bleeding_edge_change_log = "2014-03-17: Sentinel\n"
-    TextToFile(bleeding_edge_change_log, TEST_CONFIG["CHANGELOG_FILE"])
+    TextToFile(bleeding_edge_change_log,
+               os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
     os.environ["EDITOR"] = "vi"
 
     def ResetChangeLog():
@@ -693,7 +723,8 @@
       trunk_change_log = """1999-04-05: Version 3.22.4
 
         Performance and stability improvements on all platforms.\n"""
-      TextToFile(trunk_change_log, TEST_CONFIG["CHANGELOG_FILE"])
+      TextToFile(trunk_change_log,
+                 os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
 
     def ResetToTrunk():
       ResetChangeLog()
@@ -702,7 +733,7 @@
     def CheckSVNCommit():
       commit = FileToText(TEST_CONFIG["COMMITMSG_FILE"])
       self.assertEquals(
-"""Version 3.22.5 (based on bleeding_edge revision r123455)
+"""Version 3.22.5 (based on push_hash)
 
 Log text 1 (issue 321).
 
@@ -716,7 +747,8 @@
       self.assertTrue(re.search(r"#define IS_CANDIDATE_VERSION\s+0", version))
 
       # Check that the change log on the trunk branch got correctly modified.
-      change_log = FileToText(TEST_CONFIG["CHANGELOG_FILE"])
+      change_log = FileToText(
+          os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
       self.assertEquals(
 """1999-07-31: Version 3.22.5
 
@@ -737,24 +769,23 @@
     expectations += [
       Cmd("git status -s -uno", ""),
       Cmd("git status -s -b -uno", "## some_branch\n"),
-      Cmd("git svn fetch", ""),
+      Cmd("git fetch", ""),
       Cmd("git branch", "  branch1\n* branch2\n"),
       Cmd("git branch", "  branch1\n* branch2\n"),
-      Cmd("git checkout -b %s svn/bleeding_edge" % TEST_CONFIG["BRANCHNAME"],
+      Cmd(("git new-branch %s --upstream origin/master" %
+           TEST_CONFIG["BRANCHNAME"]),
           ""),
-      Cmd("git svn find-rev r123455", "push_hash\n"),
       Cmd(("git log -1 --format=%H --grep="
            "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\" "
-           "svn/trunk"), "hash2\n"),
+           "origin/candidates"), "hash2\n"),
       Cmd("git log -1 hash2", "Log message\n"),
     ]
     if manual:
       expectations.append(RL("Y"))  # Confirm last push.
     expectations += [
       Cmd("git log -1 --format=%s hash2",
-       "Version 3.4.5 (based on bleeding_edge revision r1234)\n"),
-      Cmd("git svn find-rev r1234", "hash3\n"),
-      Cmd("git checkout -f svn/bleeding_edge -- src/version.cc",
+       "Version 3.4.5 (based on abc3)\n"),
+      Cmd("git checkout -f origin/master -- src/version.cc",
           "", cb=self.WriteFakeVersionFile),
       Cmd("git checkout -f hash2 -- src/version.cc", "",
           cb=self.WriteFakeVersionFile),
@@ -762,7 +793,7 @@
     if manual:
       expectations.append(RL(""))  # Increment build number.
     expectations += [
-      Cmd("git log --format=%H hash3..push_hash", "rev1\n"),
+      Cmd("git log --format=%H abc3..push_hash", "rev1\n"),
       Cmd("git log -1 --format=%s rev1", "Log text 1.\n"),
       Cmd("git log -1 --format=%B rev1", "Text\nLOG=YES\nBUG=v8:321\nText\n"),
       Cmd("git log -1 --format=%an rev1", "author1@chromium.org\n"),
@@ -773,16 +804,15 @@
       expectations.append(
           Cmd("vi %s" % TEST_CONFIG["CHANGELOG_ENTRY_FILE"], ""))
     expectations += [
-      Cmd("git svn fetch", "fetch result\n"),
-      Cmd("git checkout -f svn/bleeding_edge", ""),
-      Cmd("git diff svn/trunk push_hash", "patch content\n"),
-      Cmd("git svn find-rev push_hash", "123455\n"),
-      Cmd("git checkout -b %s svn/trunk" % TEST_CONFIG["TRUNKBRANCH"], "",
-          cb=ResetToTrunk),
+      Cmd("git fetch", ""),
+      Cmd("git checkout -f origin/master", ""),
+      Cmd("git diff origin/candidates push_hash", "patch content\n"),
+      Cmd(("git new-branch %s --upstream origin/candidates" %
+           TEST_CONFIG["TRUNKBRANCH"]), "", cb=ResetToTrunk),
       Cmd("git apply --index --reject \"%s\"" % TEST_CONFIG["PATCH_FILE"], ""),
-      Cmd("git checkout -f svn/trunk -- %s" % TEST_CONFIG["CHANGELOG_FILE"], "",
+      Cmd("git checkout -f origin/candidates -- ChangeLog", "",
           cb=ResetChangeLog),
-      Cmd("git checkout -f svn/trunk -- src/version.cc", "",
+      Cmd("git checkout -f origin/candidates -- src/version.cc", "",
           cb=self.WriteFakeVersionFile),
       Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], "",
           cb=CheckSVNCommit),
@@ -790,22 +820,26 @@
     if manual:
       expectations.append(RL("Y"))  # Sanity check.
     expectations += [
-      Cmd("git svn dcommit 2>&1",
-          "Some output\nCommitted r123456\nSome output\n"),
-      Cmd("git svn tag 3.22.5 -m \"Tagging version 3.22.5\"", ""),
+      Cmd("git cl land -f --bypass-hooks", ""),
+      Cmd("git fetch", ""),
+      Cmd("git log -1 --format=%H --grep="
+          "\"Version 3.22.5 (based on push_hash)\""
+          " origin/candidates", "hsh_to_tag"),
+      Cmd("git tag 3.22.5 hsh_to_tag", ""),
+      Cmd("git push origin 3.22.5", ""),
       Cmd("git checkout -f some_branch", ""),
       Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
       Cmd("git branch -D %s" % TEST_CONFIG["TRUNKBRANCH"], ""),
     ]
     self.Expect(expectations)
 
-    args = ["-a", "author@chromium.org", "--revision", "123455"]
+    args = ["-a", "author@chromium.org", "--revision", "push_hash"]
     if force: args.append("-f")
     if manual: args.append("-m")
     else: args += ["-r", "reviewer@chromium.org"]
     PushToTrunk(TEST_CONFIG, self).Run(args)
 
-    cl = FileToText(TEST_CONFIG["CHANGELOG_FILE"])
+    cl = FileToText(os.path.join(TEST_CONFIG["DEFAULT_CWD"], CHANGELOG_FILE))
     self.assertTrue(re.search(r"^\d\d\d\d\-\d+\-\d+: Version 3\.22\.5", cl))
     self.assertTrue(re.search(r"        Log text 1 \(issue 321\).", cl))
     self.assertTrue(re.search(r"1999\-04\-05: Version 3\.22\.4", cl))
@@ -867,8 +901,7 @@
       Cmd("git fetch origin", ""),
       Cmd(("git log -1 --format=%H --grep="
            "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\" "
-           "origin/master"), "push_hash\n"),
-      Cmd("git log -1 --format=%B push_hash", self.C_V8_22624_LOG),
+           "origin/candidates"), "push_hash\n"),
       Cmd("git log -1 --format=%s push_hash",
           "Version 3.22.5 (based on bleeding_edge revision r22622)\n"),
       URL("https://chromium-build.appspot.com/p/chromium/sheriff_v8.js",
@@ -878,8 +911,8 @@
       Cmd("gclient sync --nohooks", "syncing...", cwd=chrome_dir),
       Cmd("git pull", "", cwd=chrome_dir),
       Cmd("git fetch origin", ""),
-      Cmd("git checkout -b v8-roll-22624", "", cwd=chrome_dir),
-      Cmd("roll-dep v8 22624", "rolled", cb=WriteDeps, cwd=chrome_dir),
+      Cmd("git new-branch v8-roll-push_hash", "", cwd=chrome_dir),
+      Cmd("roll-dep v8 push_hash", "rolled", cb=WriteDeps, cwd=chrome_dir),
       Cmd(("git commit -am \"Update V8 to version 3.22.5 "
            "(based on bleeding_edge revision r22622).\n\n"
            "Please reply to the V8 sheriff c_name@chromium.org in "
@@ -903,16 +936,14 @@
     self.Expect([
       Cmd(("git log -1 --format=%H --grep="
            "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\" "
-           "svn/trunk"), "hash2\n"),
+           "origin/candidates"), "hash2\n"),
       Cmd("git log -1 --format=%s hash2",
-          "Version 3.4.5 (based on bleeding_edge revision r99)\n"),
+          "Version 3.4.5 (based on abc123)\n"),
     ])
 
-    self._state["lkgr"] = "101"
-
-    self.assertRaises(Exception, lambda: self.RunStep(auto_push.AutoPush,
-                                                      CheckLastPush,
-                                                      AUTO_PUSH_ARGS))
+    self._state["candidate"] = "abc123"
+    self.assertEquals(0, self.RunStep(
+        auto_push.AutoPush, CheckLastPush, AUTO_PUSH_ARGS))
 
   def testAutoPush(self):
     TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
@@ -921,16 +952,16 @@
     self.Expect([
       Cmd("git status -s -uno", ""),
       Cmd("git status -s -b -uno", "## some_branch\n"),
-      Cmd("git svn fetch", ""),
+      Cmd("git fetch", ""),
       URL("https://v8-status.appspot.com/current?format=json",
           "{\"message\": \"Tree is throttled\"}"),
-      URL("https://v8-status.appspot.com/lkgr", Exception("Network problem")),
-      URL("https://v8-status.appspot.com/lkgr", "100"),
+      Cmd("git fetch origin +refs/heads/candidate:refs/heads/candidate", ""),
+      Cmd("git show-ref -s refs/heads/candidate", "abc123\n"),
       Cmd(("git log -1 --format=%H --grep=\""
            "^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]* (based\""
-           " svn/trunk"), "push_hash\n"),
+           " origin/candidates"), "push_hash\n"),
       Cmd("git log -1 --format=%s push_hash",
-          "Version 3.4.5 (based on bleeding_edge revision r79)\n"),
+          "Version 3.4.5 (based on abc101)\n"),
     ])
 
     auto_push.AutoPush(TEST_CONFIG, self).Run(AUTO_PUSH_ARGS + ["--push"])
@@ -938,7 +969,7 @@
     state = json.loads(FileToText("%s-state.json"
                                   % TEST_CONFIG["PERSISTFILE_BASENAME"]))
 
-    self.assertEquals("100", state["lkgr"])
+    self.assertEquals("abc123", state["candidate"])
 
   def testAutoPushStoppedBySettings(self):
     TextToFile("", os.path.join(TEST_CONFIG["DEFAULT_CWD"], ".git"))
@@ -949,7 +980,7 @@
     self.Expect([
       Cmd("git status -s -uno", ""),
       Cmd("git status -s -b -uno", "## some_branch\n"),
-      Cmd("git svn fetch", ""),
+      Cmd("git fetch", ""),
     ])
 
     def RunAutoPush():
@@ -963,7 +994,7 @@
     self.Expect([
       Cmd("git status -s -uno", ""),
       Cmd("git status -s -b -uno", "## some_branch\n"),
-      Cmd("git svn fetch", ""),
+      Cmd("git fetch", ""),
       URL("https://v8-status.appspot.com/current?format=json",
           "{\"message\": \"Tree is throttled (no push)\"}"),
     ])
@@ -1003,9 +1034,10 @@
       URL("https://codereview.chromium.org/search",
           "owner=author%40chromium.org&limit=30&closed=3&format=json",
           ("{\"results\": [{\"subject\": \"different\"}]}")),
+      Cmd("git fetch", ""),
       Cmd(("git log -1 --format=%H --grep="
            "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\" "
-           "origin/master"), "push_hash\n"),
+           "origin/candidates"), "push_hash\n"),
       Cmd("git log -1 --format=%B push_hash", self.C_V8_22624_LOG),
       Cmd("git log -1 --format=%B abcd123455", self.C_V8_123455_LOG),
     ])
@@ -1024,9 +1056,10 @@
       URL("https://codereview.chromium.org/search",
           "owner=author%40chromium.org&limit=30&closed=3&format=json",
           ("{\"results\": [{\"subject\": \"different\"}]}")),
+      Cmd("git fetch", ""),
       Cmd(("git log -1 --format=%H --grep="
            "\"^Version [[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\" "
-           "origin/master"), "push_hash\n"),
+           "origin/candidates"), "push_hash\n"),
       Cmd("git log -1 --format=%B push_hash", self.C_V8_123456_LOG),
       Cmd("git log -1 --format=%B abcd123455", self.C_V8_123455_LOG),
     ])
@@ -1046,7 +1079,13 @@
       return lambda: self.assertEquals(patch,
           FileToText(TEST_CONFIG["TEMPORARY_PATCH_FILE"]))
 
-    msg = """Version 3.22.5.1 (merged r12345, r23456, r34567, r45678, r56789)
+    msg = """Version 3.22.5.1 (cherry-pick)
+
+Merged ab12345
+Merged ab23456
+Merged ab34567
+Merged ab45678
+Merged ab56789
 
 Title4
 
@@ -1075,61 +1114,53 @@
     self.Expect([
       Cmd("git status -s -uno", ""),
       Cmd("git status -s -b -uno", "## some_branch\n"),
-      Cmd("git svn fetch", ""),
+      Cmd("git fetch", ""),
       Cmd("git branch", "  branch1\n* branch2\n"),
-      Cmd("git checkout -b %s svn/trunk" % TEST_CONFIG["BRANCHNAME"], ""),
-      Cmd(("git log --format=%H --grep=\"Port r12345\" "
-           "--reverse svn/bleeding_edge"),
-          "hash1\nhash2"),
-      Cmd("git svn find-rev hash1 svn/bleeding_edge", "45678"),
-      Cmd("git log -1 --format=%s hash1", "Title1"),
-      Cmd("git svn find-rev hash2 svn/bleeding_edge", "23456"),
-      Cmd("git log -1 --format=%s hash2", "Title2"),
-      Cmd(("git log --format=%H --grep=\"Port r23456\" "
-           "--reverse svn/bleeding_edge"),
+      Cmd("git new-branch %s --upstream origin/candidates" %
+          TEST_CONFIG["BRANCHNAME"], ""),
+      Cmd(("git log --format=%H --grep=\"Port ab12345\" "
+           "--reverse origin/master"),
+          "ab45678\nab23456"),
+      Cmd("git log -1 --format=%s ab45678", "Title1"),
+      Cmd("git log -1 --format=%s ab23456", "Title2"),
+      Cmd(("git log --format=%H --grep=\"Port ab23456\" "
+           "--reverse origin/master"),
           ""),
-      Cmd(("git log --format=%H --grep=\"Port r34567\" "
-           "--reverse svn/bleeding_edge"),
-          "hash3"),
-      Cmd("git svn find-rev hash3 svn/bleeding_edge", "56789"),
-      Cmd("git log -1 --format=%s hash3", "Title3"),
-      RL("Y"),  # Automatically add corresponding ports (34567, 56789)?
-      Cmd("git svn find-rev r12345 svn/bleeding_edge", "hash4"),
-      # Simulate svn being down which stops the script.
-      Cmd("git svn find-rev r23456 svn/bleeding_edge", None),
+      Cmd(("git log --format=%H --grep=\"Port ab34567\" "
+           "--reverse origin/master"),
+          "ab56789"),
+      Cmd("git log -1 --format=%s ab56789", "Title3"),
+      RL("Y"),  # Automatically add corresponding ports (ab34567, ab56789)?
+      # Simulate git being down which stops the script.
+      Cmd("git log -1 --format=%s ab12345", None),
       # Restart script in the failing step.
-      Cmd("git svn find-rev r12345 svn/bleeding_edge", "hash4"),
-      Cmd("git svn find-rev r23456 svn/bleeding_edge", "hash2"),
-      Cmd("git svn find-rev r34567 svn/bleeding_edge", "hash3"),
-      Cmd("git svn find-rev r45678 svn/bleeding_edge", "hash1"),
-      Cmd("git svn find-rev r56789 svn/bleeding_edge", "hash5"),
-      Cmd("git log -1 --format=%s hash4", "Title4"),
-      Cmd("git log -1 --format=%s hash2", "Title2"),
-      Cmd("git log -1 --format=%s hash3", "Title3"),
-      Cmd("git log -1 --format=%s hash1", "Title1"),
-      Cmd("git log -1 --format=%s hash5", "Revert \"Something\""),
-      Cmd("git log -1 hash4", "Title4\nBUG=123\nBUG=234"),
-      Cmd("git log -1 hash2", "Title2\n BUG = v8:123,345"),
-      Cmd("git log -1 hash3", "Title3\nLOG=n\nBUG=567, 456"),
-      Cmd("git log -1 hash1", "Title1\nBUG="),
-      Cmd("git log -1 hash5", "Revert \"Something\"\nBUG=none"),
-      Cmd("git log -1 -p hash4", "patch4"),
+      Cmd("git log -1 --format=%s ab12345", "Title4"),
+      Cmd("git log -1 --format=%s ab23456", "Title2"),
+      Cmd("git log -1 --format=%s ab34567", "Title3"),
+      Cmd("git log -1 --format=%s ab45678", "Title1"),
+      Cmd("git log -1 --format=%s ab56789", "Revert \"Something\""),
+      Cmd("git log -1 ab12345", "Title4\nBUG=123\nBUG=234"),
+      Cmd("git log -1 ab23456", "Title2\n BUG = v8:123,345"),
+      Cmd("git log -1 ab34567", "Title3\nLOG=n\nBUG=567, 456"),
+      Cmd("git log -1 ab45678", "Title1\nBUG="),
+      Cmd("git log -1 ab56789", "Revert \"Something\"\nBUG=none"),
+      Cmd("git log -1 -p ab12345", "patch4"),
       Cmd(("git apply --index --reject \"%s\"" %
            TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
           "", cb=VerifyPatch("patch4")),
-      Cmd("git log -1 -p hash2", "patch2"),
+      Cmd("git log -1 -p ab23456", "patch2"),
       Cmd(("git apply --index --reject \"%s\"" %
            TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
           "", cb=VerifyPatch("patch2")),
-      Cmd("git log -1 -p hash3", "patch3"),
+      Cmd("git log -1 -p ab34567", "patch3"),
       Cmd(("git apply --index --reject \"%s\"" %
            TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
           "", cb=VerifyPatch("patch3")),
-      Cmd("git log -1 -p hash1", "patch1"),
+      Cmd("git log -1 -p ab45678", "patch1"),
       Cmd(("git apply --index --reject \"%s\"" %
            TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
           "", cb=VerifyPatch("patch1")),
-      Cmd("git log -1 -p hash5", "patch5\n"),
+      Cmd("git log -1 -p ab56789", "patch5\n"),
       Cmd(("git apply --index --reject \"%s\"" %
            TEST_CONFIG["TEMPORARY_PATCH_FILE"]),
           "", cb=VerifyPatch("patch5\n")),
@@ -1138,64 +1169,42 @@
       Cmd("git commit -aF \"%s\"" % TEST_CONFIG["COMMITMSG_FILE"], ""),
       RL("reviewer@chromium.org"),  # V8 reviewer.
       Cmd("git cl upload --send-mail -r \"reviewer@chromium.org\" "
-          "--bypass-hooks", ""),
+          "--bypass-hooks --cc \"ulan@chromium.org\"", ""),
       Cmd("git checkout -f %s" % TEST_CONFIG["BRANCHNAME"], ""),
       RL("LGTM"),  # Enter LGTM for V8 CL.
       Cmd("git cl presubmit", "Presubmit successfull\n"),
-      Cmd("git cl dcommit -f --bypass-hooks", "Closing issue\n",
+      Cmd("git cl land -f --bypass-hooks", "Closing issue\n",
           cb=VerifySVNCommit),
-      Cmd("git svn fetch", ""),
-      Cmd(("git log -1 --format=%%H --grep=\"%s\" svn/trunk"
-           % msg.replace("\"", "\\\"")), "hash6"),
-      Cmd("git svn find-rev hash6", "1324"),
-      Cmd(("svn copy -r 1324 https://v8.googlecode.com/svn/trunk "
-           "https://v8.googlecode.com/svn/tags/3.22.5.1 -m "
-           "\"Tagging version 3.22.5.1\""), ""),
+      Cmd("git fetch", ""),
+      Cmd("git log -1 --format=%H --grep=\""
+          "Version 3.22.5.1 (cherry-pick)"
+          "\" origin/candidates",
+          ""),
+      Cmd("git fetch", ""),
+      Cmd("git log -1 --format=%H --grep=\""
+          "Version 3.22.5.1 (cherry-pick)"
+          "\" origin/candidates",
+          "hsh_to_tag"),
+      Cmd("git tag 3.22.5.1 hsh_to_tag", ""),
+      Cmd("git push origin 3.22.5.1", ""),
       Cmd("git checkout -f some_branch", ""),
       Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
     ])
 
-    # r12345 and r34567 are patches. r23456 (included) and r45678 are the MIPS
-    # ports of r12345. r56789 is the MIPS port of r34567.
-    args = ["-f", "-p", extra_patch, "--branch", "trunk", "12345", "23456",
-            "34567"]
+    # ab12345 and ab34567 are patches. ab23456 (included) and ab45678 are the
+    # MIPS ports of ab12345. ab56789 is the MIPS port of ab34567.
+    args = ["-f", "-p", extra_patch, "--branch", "candidates",
+            "ab12345", "ab23456", "ab34567"]
 
-    # The first run of the script stops because of the svn being down.
+    # The first run of the script stops because of git being down.
     self.assertRaises(GitFailedException,
         lambda: MergeToBranch(TEST_CONFIG, self).Run(args))
 
     # Test that state recovery after restarting the script works.
-    args += ["-s", "3"]
+    args += ["-s", "4"]
     MergeToBranch(TEST_CONFIG, self).Run(args)
 
   def testReleases(self):
-    tag_response_text = """
-------------------------------------------------------------------------
-r22631 | author1@chromium.org | 2014-07-28 02:05:29 +0200 (Mon, 28 Jul 2014)
-Changed paths:
-   A /tags/3.28.43 (from /trunk:22630)
-
-Tagging version 3.28.43
-------------------------------------------------------------------------
-r22629 | author2@chromium.org | 2014-07-26 05:09:29 +0200 (Sat, 26 Jul 2014)
-Changed paths:
-   A /tags/3.28.41 (from /branches/bleeding_edge:22626)
-
-Tagging version 3.28.41
-------------------------------------------------------------------------
-r22556 | author3@chromium.org | 2014-07-23 13:31:59 +0200 (Wed, 23 Jul 2014)
-Changed paths:
-   A /tags/3.27.34.7 (from /branches/3.27:22555)
-
-Tagging version 3.27.34.7
-------------------------------------------------------------------------
-r22627 | author4@chromium.org | 2014-07-26 01:39:15 +0200 (Sat, 26 Jul 2014)
-Changed paths:
-   A /tags/3.28.40 (from /branches/bleeding_edge:22624)
-
-Tagging version 3.28.40
-------------------------------------------------------------------------
-"""
     c_hash2_commit_log = """Revert something.
 
 BUG=12345
@@ -1216,6 +1225,23 @@
 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@3456 0039-1c4b
 
 """
+    c_hash_234_commit_log = """Version 3.3.1.1 (cherry-pick).
+
+Merged abc12.
+
+Review URL: fake.com
+
+Cr-Commit-Position: refs/heads/candidates@{#234}
+"""
+    c_hash_123_commit_log = """Version 3.3.1.0
+
+git-svn-id: googlecode@123 0039-1c4b
+"""
+    c_hash_345_commit_log = """Version 3.4.0.
+
+Cr-Commit-Position: refs/heads/candidates@{#345}
+"""
+
     json_output = self.MakeEmptyTempFile()
     csv_output = self.MakeEmptyTempFile()
     self.WriteFakeVersionFile()
@@ -1240,58 +1266,50 @@
     self.Expect([
       Cmd("git status -s -uno", ""),
       Cmd("git status -s -b -uno", "## some_branch\n"),
-      Cmd("git svn fetch", ""),
+      Cmd("git fetch", ""),
       Cmd("git branch", "  branch1\n* branch2\n"),
-      Cmd("git checkout -b %s" % TEST_CONFIG["BRANCHNAME"], ""),
-      Cmd("git branch -r", "  svn/3.21\n  svn/3.3\n"),
-      Cmd("git reset --hard svn/3.3", ""),
-      Cmd("git log --format=%H", "hash1\nhash2"),
+      Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], ""),
+      Cmd("git branch -r", "  branch-heads/3.21\n  branch-heads/3.3\n"),
+      Cmd("git reset --hard branch-heads/3.3", ""),
+      Cmd("git log --format=%H", "hash1\nhash_234"),
       Cmd("git diff --name-only hash1 hash1^", ""),
-      Cmd("git diff --name-only hash2 hash2^", VERSION_FILE),
-      Cmd("git checkout -f hash2 -- %s" % VERSION_FILE, "",
+      Cmd("git diff --name-only hash_234 hash_234^", VERSION_FILE),
+      Cmd("git checkout -f hash_234 -- %s" % VERSION_FILE, "",
           cb=ResetVersion(3, 1, 1)),
-      Cmd("git log -1 --format=%B hash2",
-          "Version 3.3.1.1 (merged 12)\n\nReview URL: fake.com\n"),
-      Cmd("git log -1 --format=%s hash2", ""),
-      Cmd("git svn find-rev hash2", "234"),
-      Cmd("git log -1 --format=%ci hash2", "18:15"),
+      Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log),
+      Cmd("git log -1 --format=%s hash_234", ""),
+      Cmd("git log -1 --format=%B hash_234", c_hash_234_commit_log),
+      Cmd("git log -1 --format=%ci hash_234", "18:15"),
       Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
           cb=ResetVersion(22, 5)),
-      Cmd("git reset --hard svn/3.21", ""),
-      Cmd("git log --format=%H", "hash3\nhash4\nhash5\n"),
-      Cmd("git diff --name-only hash3 hash3^", VERSION_FILE),
-      Cmd("git checkout -f hash3 -- %s" % VERSION_FILE, "",
+      Cmd("git reset --hard branch-heads/3.21", ""),
+      Cmd("git log --format=%H", "hash_123\nhash4\nhash5\n"),
+      Cmd("git diff --name-only hash_123 hash_123^", VERSION_FILE),
+      Cmd("git checkout -f hash_123 -- %s" % VERSION_FILE, "",
           cb=ResetVersion(21, 2)),
-      Cmd("git log -1 --format=%B hash3", ""),
-      Cmd("git log -1 --format=%s hash3", ""),
-      Cmd("git svn find-rev hash3", "123"),
-      Cmd("git log -1 --format=%ci hash3", "03:15"),
+      Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log),
+      Cmd("git log -1 --format=%s hash_123", ""),
+      Cmd("git log -1 --format=%B hash_123", c_hash_123_commit_log),
+      Cmd("git log -1 --format=%ci hash_123", "03:15"),
       Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
           cb=ResetVersion(22, 5)),
-      Cmd("git reset --hard svn/trunk", ""),
-      Cmd("git log --format=%H", "hash6\n"),
-      Cmd("git diff --name-only hash6 hash6^", VERSION_FILE),
-      Cmd("git checkout -f hash6 -- %s" % VERSION_FILE, "",
+      Cmd("git reset --hard origin/candidates", ""),
+      Cmd("git log --format=%H", "hash_345\n"),
+      Cmd("git diff --name-only hash_345 hash_345^", VERSION_FILE),
+      Cmd("git checkout -f hash_345 -- %s" % VERSION_FILE, "",
           cb=ResetVersion(22, 3)),
-      Cmd("git log -1 --format=%B hash6", ""),
-      Cmd("git log -1 --format=%s hash6", ""),
-      Cmd("git svn find-rev hash6", "345"),
-      Cmd("git log -1 --format=%ci hash6", ""),
+      Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log),
+      Cmd("git log -1 --format=%s hash_345", ""),
+      Cmd("git log -1 --format=%B hash_345", c_hash_345_commit_log),
+      Cmd("git log -1 --format=%ci hash_345", ""),
       Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
           cb=ResetVersion(22, 5)),
-      Cmd("git reset --hard svn/bleeding_edge", ""),
-      Cmd("svn log https://v8.googlecode.com/svn/tags -v --limit 20",
-          tag_response_text),
-      Cmd("git svn find-rev r22626", "hash_22626"),
-      Cmd("git svn find-rev hash_22626", "22626"),
-      Cmd("git log -1 --format=%ci hash_22626", "01:23"),
-      Cmd("git svn find-rev r22624", "hash_22624"),
-      Cmd("git svn find-rev hash_22624", "22624"),
-      Cmd("git log -1 --format=%ci hash_22624", "02:34"),
+      Cmd("git reset --hard origin/master", ""),
       Cmd("git status -s -uno", "", cwd=chrome_dir),
       Cmd("git checkout -f master", "", cwd=chrome_dir),
       Cmd("git pull", "", cwd=chrome_dir),
-      Cmd("git checkout -b %s" % TEST_CONFIG["BRANCHNAME"], "", cwd=chrome_dir),
+      Cmd("git new-branch %s" % TEST_CONFIG["BRANCHNAME"], "",
+          cwd=chrome_dir),
       Cmd("git fetch origin", "", cwd=chrome_v8_dir),
       Cmd("git log --format=%H --grep=\"V8\"", "c_hash1\nc_hash2\nc_hash3\n",
           cwd=chrome_dir),
@@ -1302,8 +1320,6 @@
           cwd=chrome_dir),
       Cmd("git log -1 --format=%B c_hash2", c_hash2_commit_log,
           cwd=chrome_dir),
-      Cmd("git rev-list -n 1 0123456789012345678901234567890123456789",
-          "0123456789012345678901234567890123456789", cwd=chrome_v8_dir),
       Cmd("git log -1 --format=%B 0123456789012345678901234567890123456789",
           self.C_V8_22624_LOG, cwd=chrome_v8_dir),
       Cmd("git diff --name-only c_hash3 c_hash3^", "DEPS", cwd=chrome_dir),
@@ -1331,35 +1347,54 @@
     Releases(TEST_CONFIG, self).Run(args)
 
     # Check expected output.
-    csv = ("3.28.41,bleeding_edge,22626,,\r\n"
-           "3.28.40,bleeding_edge,22624,4567,\r\n"
-           "3.22.3,trunk,345,3456:4566,\r\n"
+    csv = ("3.22.3,candidates,345,3456:4566,\r\n"
            "3.21.2,3.21,123,,\r\n"
-           "3.3.1.1,3.3,234,,12\r\n")
+           "3.3.1.1,3.3,234,,abc12\r\n")
     self.assertEquals(csv, FileToText(csv_output))
 
     expected_json = [
-      {"bleeding_edge": "22626", "patches_merged": "", "version": "3.28.41",
-       "chromium_revision": "", "branch": "bleeding_edge", "revision": "22626",
-       "review_link": "", "date": "01:23", "chromium_branch": "",
-       "revision_link": "https://code.google.com/p/v8/source/detail?r=22626"},
-      {"bleeding_edge": "22624", "patches_merged": "", "version": "3.28.40",
-       "chromium_revision": "4567", "branch": "bleeding_edge",
-       "revision": "22624", "review_link": "", "date": "02:34",
-       "chromium_branch": "",
-       "revision_link": "https://code.google.com/p/v8/source/detail?r=22624"},
-      {"bleeding_edge": "", "patches_merged": "", "version": "3.22.3",
-       "chromium_revision": "3456:4566", "branch": "trunk", "revision": "345",
-       "review_link": "", "date": "", "chromium_branch": "7",
-       "revision_link": "https://code.google.com/p/v8/source/detail?r=345"},
-      {"patches_merged": "", "bleeding_edge": "", "version": "3.21.2",
-       "chromium_revision": "", "branch": "3.21", "revision": "123",
-       "review_link": "", "date": "03:15", "chromium_branch": "",
-       "revision_link": "https://code.google.com/p/v8/source/detail?r=123"},
-      {"patches_merged": "12", "bleeding_edge": "", "version": "3.3.1.1",
-       "chromium_revision": "", "branch": "3.3", "revision": "234",
-       "review_link": "fake.com", "date": "18:15", "chromium_branch": "",
-       "revision_link": "https://code.google.com/p/v8/source/detail?r=234"},
+      {
+        "revision": "345",
+        "revision_git": "hash_345",
+        "bleeding_edge": "",
+        "bleeding_edge_git": "",
+        "patches_merged": "",
+        "version": "3.22.3",
+        "chromium_revision": "3456:4566",
+        "branch": "candidates",
+        "review_link": "",
+        "date": "",
+        "chromium_branch": "7",
+        "revision_link": "https://code.google.com/p/v8/source/detail?r=345",
+      },
+      {
+        "revision": "123",
+        "revision_git": "hash_123",
+        "patches_merged": "",
+        "bleeding_edge": "",
+        "bleeding_edge_git": "",
+        "version": "3.21.2",
+        "chromium_revision": "",
+        "branch": "3.21",
+        "review_link": "",
+        "date": "03:15",
+        "chromium_branch": "",
+        "revision_link": "https://code.google.com/p/v8/source/detail?r=123",
+      },
+      {
+        "revision": "234",
+        "revision_git": "hash_234",
+        "patches_merged": "abc12",
+        "bleeding_edge": "",
+        "bleeding_edge_git": "",
+        "version": "3.3.1.1",
+        "chromium_revision": "",
+        "branch": "3.3",
+        "review_link": "fake.com",
+        "date": "18:15",
+        "chromium_branch": "",
+        "revision_link": "https://code.google.com/p/v8/source/detail?r=234",
+      },
     ]
     self.assertEquals(expected_json, json.loads(FileToText(json_output)))
 
@@ -1374,26 +1409,27 @@
 
     return [
       Cmd("git status -s -uno", ""),
-      Cmd("git checkout -f bleeding_edge", "", cb=ResetVersion(11, 4)),
+      Cmd("git checkout -f master", "", cb=ResetVersion(11, 4)),
       Cmd("git pull", ""),
       Cmd("git branch", ""),
-      Cmd("git checkout -f bleeding_edge", ""),
+      Cmd("git checkout -f master", ""),
       Cmd("git log -1 --format=%H", "latest_hash"),
       Cmd("git diff --name-only latest_hash latest_hash^", ""),
       URL("https://v8-status.appspot.com/lkgr", "12345"),
-      Cmd("git checkout -f bleeding_edge", ""),
+      Cmd("git checkout -f master", ""),
       Cmd(("git log --format=%H --grep="
            "\"^git-svn-id: [^@]*@12345 [A-Za-z0-9-]*$\""),
           "lkgr_hash"),
-      Cmd("git checkout -b auto-bump-up-version lkgr_hash", ""),
-      Cmd("git checkout -f bleeding_edge", ""),
-      Cmd("git branch", ""),
+      Cmd("git new-branch auto-bump-up-version --upstream lkgr_hash", ""),
+      Cmd("git checkout -f master", ""),
+      Cmd("git branch", "auto-bump-up-version\n* master"),
+      Cmd("git branch -D auto-bump-up-version", ""),
       Cmd("git diff --name-only lkgr_hash lkgr_hash^", ""),
-      Cmd("git checkout -f master", "", cb=ResetVersion(11, 5)),
+      Cmd("git checkout -f candidates", "", cb=ResetVersion(11, 5)),
       Cmd("git pull", ""),
       URL("https://v8-status.appspot.com/current?format=json",
           "{\"message\": \"Tree is open\"}"),
-      Cmd("git checkout -b auto-bump-up-version bleeding_edge", "",
+      Cmd("git new-branch auto-bump-up-version --upstream master", "",
           cb=ResetVersion(11, 4)),
       Cmd("git commit -am \"[Auto-roll] Bump up version to 3.11.6.0\n\n"
           "TBR=author@chromium.org\" "
@@ -1405,88 +1441,15 @@
     expectations += [
       Cmd("git cl upload --send-mail --email \"author@chromium.org\" -f "
           "--bypass-hooks", ""),
-      Cmd("git cl dcommit -f --bypass-hooks", ""),
-      Cmd("git checkout -f bleeding_edge", ""),
-      Cmd("git branch", "auto-bump-up-version\n* bleeding_edge"),
+      Cmd("git cl land -f --bypass-hooks", ""),
+      Cmd("git checkout -f master", ""),
+      Cmd("git branch", "auto-bump-up-version\n* master"),
       Cmd("git branch -D auto-bump-up-version", ""),
     ]
     self.Expect(expectations)
 
     BumpUpVersion(TEST_CONFIG, self).Run(["-a", "author@chromium.org"])
 
-  def testBumpUpVersionSvn(self):
-    svn_root = self.MakeEmptyTempDirectory()
-    expectations = self._bumpUpVersion()
-    expectations += [
-      Cmd("git diff HEAD^ HEAD", "patch content"),
-      Cmd("svn update", "", cwd=svn_root),
-      Cmd("svn status", "", cwd=svn_root),
-      Cmd("patch -d branches/bleeding_edge -p1 -i %s" %
-          TEST_CONFIG["PATCH_FILE"], "Applied patch...", cwd=svn_root),
-      Cmd("svn commit --non-interactive --username=author@chromium.org "
-          "--config-dir=[CONFIG_DIR] "
-          "-m \"[Auto-roll] Bump up version to 3.11.6.0\"",
-          "", cwd=svn_root),
-      Cmd("git checkout -f bleeding_edge", ""),
-      Cmd("git branch", "auto-bump-up-version\n* bleeding_edge"),
-      Cmd("git branch -D auto-bump-up-version", ""),
-    ]
-    self.Expect(expectations)
-
-    BumpUpVersion(TEST_CONFIG, self).Run(
-        ["-a", "author@chromium.org",
-         "--svn", svn_root,
-         "--svn-config", "[CONFIG_DIR]"])
-
-  def testAutoTag(self):
-    self.WriteFakeVersionFile()
-
-    def ResetVersion(minor, build, patch=0):
-      return lambda: self.WriteFakeVersionFile(minor=minor,
-                                               build=build,
-                                               patch=patch)
-
-    self.Expect([
-      Cmd("git status -s -uno", ""),
-      Cmd("git status -s -b -uno", "## some_branch\n"),
-      Cmd("git svn fetch", ""),
-      Cmd("git branch", "  branch1\n* branch2\n"),
-      Cmd("git checkout -f master", ""),
-      Cmd("git svn rebase", ""),
-      Cmd("git checkout -b %s" % TEST_CONFIG["BRANCHNAME"], "",
-          cb=ResetVersion(4, 5)),
-      Cmd("git branch -r",
-          "svn/tags/3.4.2\nsvn/tags/3.2.1.0\nsvn/branches/3.4"),
-      Cmd(("git log --format=%H --grep="
-           "\"\\[Auto\\-roll\\] Bump up version to\""),
-          "hash125\nhash118\nhash111\nhash101"),
-      Cmd("git checkout -f hash125 -- %s" % VERSION_FILE, "",
-          cb=ResetVersion(4, 4)),
-      Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
-          cb=ResetVersion(4, 5)),
-      Cmd("git checkout -f hash118 -- %s" % VERSION_FILE, "",
-          cb=ResetVersion(4, 3)),
-      Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
-          cb=ResetVersion(4, 5)),
-      Cmd("git checkout -f hash111 -- %s" % VERSION_FILE, "",
-          cb=ResetVersion(4, 2)),
-      Cmd("git checkout -f HEAD -- %s" % VERSION_FILE, "",
-          cb=ResetVersion(4, 5)),
-      URL("https://v8-status.appspot.com/revisions?format=json",
-          "[{\"revision\": \"126\", \"status\": true},"
-           "{\"revision\": \"123\", \"status\": true},"
-           "{\"revision\": \"112\", \"status\": true}]"),
-      Cmd("git svn find-rev hash118", "118"),
-      Cmd("git svn find-rev hash125", "125"),
-      Cmd("git svn find-rev r123", "hash123"),
-      Cmd("git log -1 --format=%at hash123", "1"),
-      Cmd("git reset --hard hash123", ""),
-      Cmd("git svn tag 3.4.3 -m \"Tagging version 3.4.3\"", ""),
-      Cmd("git checkout -f some_branch", ""),
-      Cmd("git branch -D %s" % TEST_CONFIG["BRANCHNAME"], ""),
-    ])
-
-    AutoTag(TEST_CONFIG, self).Run(["-a", "author@chromium.org"])
 
   # Test that we bail out if the last change was a version change.
   def testBumpUpVersionBailout1(self):
@@ -1527,7 +1490,10 @@
 
 class SystemTest(unittest.TestCase):
   def testReload(self):
+    options = ScriptsBase(
+        TEST_CONFIG, DEFAULT_SIDE_EFFECT_HANDLER, {}).MakeOptions([])
     step = MakeStep(step_class=PrepareChangeLog, number=0, state={}, config={},
+                    options=options,
                     side_effect_handler=DEFAULT_SIDE_EFFECT_HANDLER)
     body = step.Reload(
 """------------------------------------------------------------------------
diff --git a/tools/run-deopt-fuzzer.py b/tools/run-deopt-fuzzer.py
index 57cb6b2..a6fdf31 100755
--- a/tools/run-deopt-fuzzer.py
+++ b/tools/run-deopt-fuzzer.py
@@ -160,6 +160,9 @@
   result.add_option("--buildbot",
                     help="Adapt to path structure used on buildbots",
                     default=False, action="store_true")
+  result.add_option("--dcheck-always-on",
+                    help="Indicates that V8 was compiled with DCHECKs enabled",
+                    default=False, action="store_true")
   result.add_option("--command-prefix",
                     help="Prepended to each shell command used to run a test",
                     default="")
@@ -389,6 +392,8 @@
     "simulator": utils.UseSimulator(arch),
     "system": utils.GuessOS(),
     "tsan": False,
+    "msan": False,
+    "dcheck_always_on": options.dcheck_always_on,
   }
   all_tests = []
   num_tests = 0
diff --git a/tools/run-llprof.sh b/tools/run-llprof.sh
index d526170..54a3881 100755
--- a/tools/run-llprof.sh
+++ b/tools/run-llprof.sh
@@ -66,4 +66,4 @@
 fi
 
 echo "Running benchmark..."
-perf record -R -e cycles -c $SAMPLE_EVERY_N_CYCLES -f -i $@ --ll-prof
+perf record -R -e cycles -c $SAMPLE_EVERY_N_CYCLES -i $@ --ll-prof
diff --git a/tools/run-tests.py b/tools/run-tests.py
index d48b70c..d68d1f8 100755
--- a/tools/run-tests.py
+++ b/tools/run-tests.py
@@ -44,6 +44,7 @@
 from testrunner.local import execution
 from testrunner.local import progress
 from testrunner.local import testsuite
+from testrunner.local.testsuite import VARIANT_FLAGS
 from testrunner.local import utils
 from testrunner.local import verbose
 from testrunner.network import network_execution
@@ -51,9 +52,13 @@
 
 
 ARCH_GUESS = utils.DefaultArch()
-DEFAULT_TESTS = ["mjsunit", "fuzz-natives", "base-unittests",
-                 "cctest", "compiler-unittests", "heap-unittests",
-                 "libplatform-unittests", "message", "preparser"]
+DEFAULT_TESTS = [
+  "mjsunit",
+  "unittests",
+  "cctest",
+  "message",
+  "preparser",
+]
 
 # Map of test name synonyms to lists of test suites. Should be ordered by
 # expected runtimes (suites with slow test cases first). These groups are
@@ -61,7 +66,6 @@
 TEST_MAP = {
   "default": [
     "mjsunit",
-    "fuzz-natives",
     "cctest",
     "message",
     "preparser",
@@ -72,10 +76,7 @@
     "webkit",
   ],
   "unittests": [
-    "compiler-unittests",
-    "heap-unittests",
-    "base-unittests",
-    "libplatform-unittests",
+    "unittests",
   ],
 }
 
@@ -83,13 +84,6 @@
 TIMEOUT_SCALEFACTOR = {"debug"   : 4,
                        "release" : 1 }
 
-# Use this to run several variants of the tests.
-VARIANT_FLAGS = {
-    "default": [],
-    "stress": ["--stress-opt", "--always-opt"],
-    "turbofan": ["--turbo-filter=*", "--always-opt"],
-    "nocrankshaft": ["--nocrankshaft"]}
-
 VARIANTS = ["default", "stress", "turbofan", "nocrankshaft"]
 
 MODE_FLAGS = {
@@ -147,6 +141,9 @@
   result.add_option("--buildbot",
                     help="Adapt to path structure used on buildbots",
                     default=False, action="store_true")
+  result.add_option("--dcheck-always-on",
+                    help="Indicates that V8 was compiled with DCHECKs enabled",
+                    default=False, action="store_true")
   result.add_option("--cat", help="Print the source of the tests",
                     default=False, action="store_true")
   result.add_option("--flaky-tests",
@@ -257,6 +254,9 @@
                     default="v8tests")
   result.add_option("--random-seed", default=0, dest="random_seed",
                     help="Default seed for initializing random generator")
+  result.add_option("--msan",
+                    help="Regard test expectations for MSAN",
+                    default=False, action="store_true")
   return result
 
 
@@ -309,6 +309,11 @@
 
   if options.tsan:
     VARIANTS = ["default"]
+    suppressions_file = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+                                     'sanitizers', 'tsan_suppressions.txt')
+    tsan_options = '%s suppressions=%s' % (
+        os.environ.get('TSAN_OPTIONS', ''), suppressions_file)
+    os.environ['TSAN_OPTIONS'] = tsan_options
 
   if options.j == 0:
     options.j = multiprocessing.cpu_count()
@@ -489,7 +494,8 @@
 
   # TODO(all): Combine "simulator" and "simulator_run".
   simulator_run = not options.dont_skip_simulator_slow_tests and \
-      arch in ['arm64', 'arm', 'mips'] and ARCH_GUESS and arch != ARCH_GUESS
+      arch in ['arm64', 'arm', 'mipsel', 'mips', 'mips64el'] and \
+      ARCH_GUESS and arch != ARCH_GUESS
   # Find available test suites and read test cases from them.
   variables = {
     "arch": arch,
@@ -504,6 +510,8 @@
     "simulator": utils.UseSimulator(arch),
     "system": utils.GuessOS(),
     "tsan": options.tsan,
+    "msan": options.msan,
+    "dcheck_always_on": options.dcheck_always_on,
   }
   all_tests = []
   num_tests = 0
diff --git a/tools/run_perf.py b/tools/run_perf.py
index 920c18d..63c9148 100755
--- a/tools/run_perf.py
+++ b/tools/run_perf.py
@@ -15,9 +15,10 @@
   "archs": [<architecture name for which this suite is run>, ...],
   "binary": <name of binary to run, default "d8">,
   "flags": [<flag to d8>, ...],
+  "test_flags": [<flag to the test file>, ...],
   "run_count": <how often will this suite run (optional)>,
   "run_count_XXX": <how often will this suite run for arch XXX (optional)>,
-  "resources": [<js file to be loaded before main>, ...]
+  "resources": [<js file to be moved to android device>, ...]
   "main": <main js perf runner file>,
   "results_regexp": <optional regexp>,
   "results_processor": <optional python results processor script>,
@@ -54,6 +55,7 @@
 {
   "path": ["."],
   "flags": ["--expose-gc"],
+  "test_flags": ["5"],
   "archs": ["ia32", "x64"],
   "run_count": 5,
   "run_count_ia32": 3,
@@ -89,9 +91,13 @@
 }
 
 Path pieces are concatenated. D8 is always run with the suite's path as cwd.
+
+The test flags are passed to the js test file after '--'.
 """
 
+from collections import OrderedDict
 import json
+import logging
 import math
 import optparse
 import os
@@ -114,8 +120,25 @@
                    "x64",
                    "arm64"]
 
-GENERIC_RESULTS_RE = re.compile(
-    r"^Trace\(([^\)]+)\), Result\(([^\)]+)\), StdDev\(([^\)]+)\)$")
+GENERIC_RESULTS_RE = re.compile(r"^RESULT ([^:]+): ([^=]+)= ([^ ]+) ([^ ]*)$")
+RESULT_STDDEV_RE = re.compile(r"^\{([^\}]+)\}$")
+RESULT_LIST_RE = re.compile(r"^\[([^\]]+)\]$")
+
+
+def LoadAndroidBuildTools(path):  # pragma: no cover
+  assert os.path.exists(path)
+  sys.path.insert(0, path)
+
+  from pylib.device import device_utils  # pylint: disable=F0401
+  from pylib.device import device_errors  # pylint: disable=F0401
+  from pylib.perf import cache_control  # pylint: disable=F0401
+  from pylib.perf import perf_control  # pylint: disable=F0401
+  import pylib.android_commands  # pylint: disable=F0401
+  global cache_control
+  global device_errors
+  global device_utils
+  global perf_control
+  global pylib
 
 
 def GeometricMean(values):
@@ -168,6 +191,7 @@
     self.path = []
     self.graphs = []
     self.flags = []
+    self.test_flags = []
     self.resources = []
     self.results_regexp = None
     self.stddev_regexp = None
@@ -187,19 +211,24 @@
     assert isinstance(suite.get("path", []), list)
     assert isinstance(suite["name"], basestring)
     assert isinstance(suite.get("flags", []), list)
+    assert isinstance(suite.get("test_flags", []), list)
     assert isinstance(suite.get("resources", []), list)
 
     # Accumulated values.
     self.path = parent.path[:] + suite.get("path", [])
     self.graphs = parent.graphs[:] + [suite["name"]]
     self.flags = parent.flags[:] + suite.get("flags", [])
-    self.resources = parent.resources[:] + suite.get("resources", [])
+    self.test_flags = parent.test_flags[:] + suite.get("test_flags", [])
+
+    # Values independent of parent node.
+    self.resources = suite.get("resources", [])
 
     # Descrete values (with parent defaults).
     self.binary = suite.get("binary", parent.binary)
     self.run_count = suite.get("run_count", parent.run_count)
     self.run_count = suite.get("run_count_%s" % arch, self.run_count)
     self.timeout = suite.get("timeout", parent.timeout)
+    self.timeout = suite.get("timeout_%s" % arch, self.timeout)
     self.units = suite.get("units", parent.units)
     self.total = suite.get("total", parent.total)
 
@@ -236,8 +265,11 @@
 
   def ConsumeOutput(self, stdout):
     try:
-      self.results.append(
-          re.search(self.results_regexp, stdout, re.M).group(1))
+      result = re.search(self.results_regexp, stdout, re.M).group(1)
+      self.results.append(str(float(result)))
+    except ValueError:
+      self.errors.append("Regexp \"%s\" returned a non-numeric for test %s."
+                         % (self.results_regexp, self.graphs[-1]))
     except:
       self.errors.append("Regexp \"%s\" didn't match for test %s."
                          % (self.results_regexp, self.graphs[-1]))
@@ -277,14 +309,13 @@
     bench_dir = os.path.normpath(os.path.join(*self.path))
     os.chdir(os.path.join(suite_dir, bench_dir))
 
+  def GetCommandFlags(self):
+    suffix = ["--"] + self.test_flags if self.test_flags else []
+    return self.flags + [self.main] + suffix
+
   def GetCommand(self, shell_dir):
     # TODO(machenbach): This requires +.exe if run on windows.
-    return (
-      [os.path.join(shell_dir, self.binary)] +
-      self.flags +
-      self.resources +
-      [self.main]
-    )
+    return [os.path.join(shell_dir, self.binary)] + self.GetCommandFlags()
 
   def Run(self, runner):
     """Iterates over several runs and handles the output for all traces."""
@@ -334,21 +365,41 @@
 
   def Run(self, runner):
     """Iterates over several runs and handles the output."""
-    traces = {}
+    traces = OrderedDict()
     for stdout in runner():
       for line in stdout.strip().splitlines():
         match = GENERIC_RESULTS_RE.match(line)
         if match:
-          trace = match.group(1)
-          result = match.group(2)
-          stddev = match.group(3)
+          stddev = ""
+          graph = match.group(1)
+          trace = match.group(2)
+          body = match.group(3)
+          units = match.group(4)
+          match_stddev = RESULT_STDDEV_RE.match(body)
+          match_list = RESULT_LIST_RE.match(body)
+          errors = []
+          if match_stddev:
+            result, stddev = map(str.strip, match_stddev.group(1).split(","))
+            results = [result]
+          elif match_list:
+            results = map(str.strip, match_list.group(1).split(","))
+          else:
+            results = [body.strip()]
+
+          try:
+            results = map(lambda r: str(float(r)), results)
+          except ValueError:
+            results = []
+            errors = ["Found non-numeric in %s" %
+                      "/".join(self.graphs + [graph, trace])]
+
           trace_result = traces.setdefault(trace, Results([{
-            "graphs": self.graphs + [trace],
-            "units": self.units,
+            "graphs": self.graphs + [graph, trace],
+            "units": (units or self.units).strip(),
             "results": [],
             "stddev": "",
-          }], []))
-          trace_result.traces[0]["results"].append(result)
+          }], errors))
+          trace_result.traces[0]["results"].extend(results)
           trace_result.traces[0]["stddev"] = stddev
 
     return reduce(lambda r, t: r + t, traces.itervalues(), Results())
@@ -385,7 +436,7 @@
   parent = parent or DefaultSentinel()
 
   # TODO(machenbach): Implement notion of cpu type?
-  if arch not in suite.get("archs", ["ia32", "x64"]):
+  if arch not in suite.get("archs", SUPPORTED_ARCHS):
     return None
 
   graph = MakeGraph(suite, arch, parent)
@@ -395,23 +446,167 @@
   return graph
 
 
-def FlattenRunnables(node):
+def FlattenRunnables(node, node_cb):
   """Generator that traverses the tree structure and iterates over all
   runnables.
   """
+  node_cb(node)
   if isinstance(node, Runnable):
     yield node
   elif isinstance(node, Node):
     for child in node._children:
-      for result in FlattenRunnables(child):
+      for result in FlattenRunnables(child, node_cb):
         yield result
   else:  # pragma: no cover
     raise Exception("Invalid suite configuration.")
 
 
+class Platform(object):
+  @staticmethod
+  def GetPlatform(options):
+    if options.arch.startswith("android"):
+      return AndroidPlatform(options)
+    else:
+      return DesktopPlatform(options)
+
+
+class DesktopPlatform(Platform):
+  def __init__(self, options):
+    self.shell_dir = options.shell_dir
+
+  def PreExecution(self):
+    pass
+
+  def PostExecution(self):
+    pass
+
+  def PreTests(self, node, path):
+    if isinstance(node, Runnable):
+      node.ChangeCWD(path)
+
+  def Run(self, runnable, count):
+    output = commands.Execute(runnable.GetCommand(self.shell_dir),
+                              timeout=runnable.timeout)
+    print ">>> Stdout (#%d):" % (count + 1)
+    print output.stdout
+    if output.stderr:  # pragma: no cover
+      # Print stderr for debugging.
+      print ">>> Stderr (#%d):" % (count + 1)
+      print output.stderr
+    if output.timed_out:
+      print ">>> Test timed out after %ss." % runnable.timeout
+    return output.stdout
+
+
+class AndroidPlatform(Platform):  # pragma: no cover
+  DEVICE_DIR = "/data/local/tmp/v8/"
+
+  def __init__(self, options):
+    self.shell_dir = options.shell_dir
+    LoadAndroidBuildTools(options.android_build_tools)
+
+    if not options.device:
+      # Detect attached device if not specified.
+      devices = pylib.android_commands.GetAttachedDevices(
+          hardware=True, emulator=False, offline=False)
+      assert devices and len(devices) == 1, (
+          "None or multiple devices detected. Please specify the device on "
+          "the command-line with --device")
+      options.device = devices[0]
+    adb_wrapper = pylib.android_commands.AndroidCommands(options.device)
+    self.device = device_utils.DeviceUtils(adb_wrapper)
+    self.adb = adb_wrapper.Adb()
+
+  def PreExecution(self):
+    perf = perf_control.PerfControl(self.device)
+    perf.SetHighPerfMode()
+
+    # Remember what we have already pushed to the device.
+    self.pushed = set()
+
+  def PostExecution(self):
+    perf = perf_control.PerfControl(self.device)
+    perf.SetDefaultPerfMode()
+    self.device.RunShellCommand(["rm", "-rf", AndroidPlatform.DEVICE_DIR])
+
+  def _SendCommand(self, cmd):
+    logging.info("adb -s %s %s" % (str(self.device), cmd))
+    return self.adb.SendCommand(cmd, timeout_time=60)
+
+  def _PushFile(self, host_dir, file_name, target_rel="."):
+    file_on_host = os.path.join(host_dir, file_name)
+    file_on_device_tmp = os.path.join(
+        AndroidPlatform.DEVICE_DIR, "_tmp_", file_name)
+    file_on_device = os.path.join(
+        AndroidPlatform.DEVICE_DIR, target_rel, file_name)
+    folder_on_device = os.path.dirname(file_on_device)
+
+    # Only push files not yet pushed in one execution.
+    if file_on_host in self.pushed:
+      return
+    else:
+      self.pushed.add(file_on_host)
+
+    # Work-around for "text file busy" errors. Push the files to a temporary
+    # location and then copy them with a shell command.
+    output = self._SendCommand(
+        "push %s %s" % (file_on_host, file_on_device_tmp))
+    # Success looks like this: "3035 KB/s (12512056 bytes in 4.025s)".
+    # Errors look like this: "failed to copy  ... ".
+    if output and not re.search('^[0-9]', output.splitlines()[-1]):
+      logging.critical('PUSH FAILED: ' + output)
+    self._SendCommand("shell mkdir -p %s" % folder_on_device)
+    self._SendCommand("shell cp %s %s" % (file_on_device_tmp, file_on_device))
+
+  def PreTests(self, node, path):
+    suite_dir = os.path.abspath(os.path.dirname(path))
+    if node.path:
+      bench_rel = os.path.normpath(os.path.join(*node.path))
+      bench_abs = os.path.join(suite_dir, bench_rel)
+    else:
+      bench_rel = "."
+      bench_abs = suite_dir
+
+    self._PushFile(self.shell_dir, node.binary)
+    if isinstance(node, Runnable):
+      self._PushFile(bench_abs, node.main, bench_rel)
+    for resource in node.resources:
+      self._PushFile(bench_abs, resource, bench_rel)
+
+  def Run(self, runnable, count):
+    cache = cache_control.CacheControl(self.device)
+    cache.DropRamCaches()
+    binary_on_device = AndroidPlatform.DEVICE_DIR + runnable.binary
+    cmd = [binary_on_device] + runnable.GetCommandFlags()
+
+    # Relative path to benchmark directory.
+    if runnable.path:
+      bench_rel = os.path.normpath(os.path.join(*runnable.path))
+    else:
+      bench_rel = "."
+
+    try:
+      output = self.device.RunShellCommand(
+          cmd,
+          cwd=os.path.join(AndroidPlatform.DEVICE_DIR, bench_rel),
+          timeout=runnable.timeout,
+          retries=0,
+      )
+      stdout = "\n".join(output)
+      print ">>> Stdout (#%d):" % (count + 1)
+      print stdout
+    except device_errors.CommandTimeoutError:
+      print ">>> Test timed out after %ss." % runnable.timeout
+      stdout = ""
+    return stdout
+
+
 # TODO: Implement results_processor.
 def Main(args):
+  logging.getLogger().setLevel(logging.INFO)
   parser = optparse.OptionParser()
+  parser.add_option("--android-build-tools",
+                    help="Path to chromium's build/android.")
   parser.add_option("--arch",
                     help=("The architecture to run tests for, "
                           "'auto' or 'native' for auto-detect"),
@@ -419,6 +614,9 @@
   parser.add_option("--buildbot",
                     help="Adapt to path structure used on buildbots",
                     default=False, action="store_true")
+  parser.add_option("--device",
+                    help="The device ID to run Android tests on. If not given "
+                         "it will be autodetected.")
   parser.add_option("--json-test-results",
                     help="Path to a file for storing json results.")
   parser.add_option("--outdir", help="Base directory with compile output",
@@ -436,13 +634,26 @@
     print "Unknown architecture %s" % options.arch
     return 1
 
+  if (bool(options.arch.startswith("android")) !=
+      bool(options.android_build_tools)):  # pragma: no cover
+    print ("Android architectures imply setting --android-build-tools and the "
+           "other way around.")
+    return 1
+
+  if (options.device and not
+      options.arch.startswith("android")):  # pragma: no cover
+    print "Specifying a device requires an Android architecture to be used."
+    return 1
+
   workspace = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
 
   if options.buildbot:
-    shell_dir = os.path.join(workspace, options.outdir, "Release")
+    options.shell_dir = os.path.join(workspace, options.outdir, "Release")
   else:
-    shell_dir = os.path.join(workspace, options.outdir,
-                             "%s.release" % options.arch)
+    options.shell_dir = os.path.join(workspace, options.outdir,
+                                     "%s.release" % options.arch)
+
+  platform = Platform.GetPlatform(options)
 
   results = Results()
   for path in args:
@@ -458,30 +669,32 @@
     # If no name is given, default to the file name without .json.
     suite.setdefault("name", os.path.splitext(os.path.basename(path))[0])
 
-    for runnable in FlattenRunnables(BuildGraphs(suite, options.arch)):
+    # Setup things common to one test suite.
+    platform.PreExecution()
+
+    # Build the graph/trace tree structure.
+    root = BuildGraphs(suite, options.arch)
+
+    # Callback to be called on each node on traversal.
+    def NodeCB(node):
+      platform.PreTests(node, path)
+
+    # Traverse graph/trace tree and interate over all runnables.
+    for runnable in FlattenRunnables(root, NodeCB):
       print ">>> Running suite: %s" % "/".join(runnable.graphs)
-      runnable.ChangeCWD(path)
 
       def Runner():
         """Output generator that reruns several times."""
         for i in xrange(0, max(1, runnable.run_count)):
           # TODO(machenbach): Allow timeout per arch like with run_count per
           # arch.
-          output = commands.Execute(runnable.GetCommand(shell_dir),
-                                    timeout=runnable.timeout)
-          print ">>> Stdout (#%d):" % (i + 1)
-          print output.stdout
-          if output.stderr:  # pragma: no cover
-            # Print stderr for debugging.
-            print ">>> Stderr (#%d):" % (i + 1)
-            print output.stderr
-          if output.timed_out:
-            print ">>> Test timed out after %ss." % runnable.timeout
-          yield output.stdout
+          yield platform.Run(runnable, i)
 
       # Let runnable iterate over all runs and handle output.
       results += runnable.Run(Runner)
 
+    platform.PostExecution()
+
   if options.json_test_results:
     results.WriteToFile(options.json_test_results)
   else:  # pragma: no cover
diff --git a/tools/sanitizers/tsan_suppressions.txt b/tools/sanitizers/tsan_suppressions.txt
new file mode 100644
index 0000000..270340e
--- /dev/null
+++ b/tools/sanitizers/tsan_suppressions.txt
@@ -0,0 +1,6 @@
+# Suppressions for TSan v2
+# https://code.google.com/p/thread-sanitizer/wiki/Suppressions
+
+# Incorrectly detected lock cycles in test-lockers
+# https://code.google.com/p/thread-sanitizer/issues/detail?id=81
+deadlock:LockAndUnlockDifferentIsolatesThread::Run
diff --git a/tools/shell-utils.h b/tools/shell-utils.h
index ac61fb6..7b51d2f 100644
--- a/tools/shell-utils.h
+++ b/tools/shell-utils.h
@@ -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.
 
-// Utility functions used by parser-shell and lexer-shell.
+// Utility functions used by parser-shell.
 
 #include <stdio.h>
 
diff --git a/tools/testrunner/local/execution.py b/tools/testrunner/local/execution.py
index 36ce7be..5c5fbac 100644
--- a/tools/testrunner/local/execution.py
+++ b/tools/testrunner/local/execution.py
@@ -33,6 +33,7 @@
 from pool import Pool
 from . import commands
 from . import perfdata
+from . import statusfile
 from . import utils
 
 
@@ -98,6 +99,10 @@
         "--stress-opt" in self.context.mode_flags or
         "--stress-opt" in self.context.extra_flags):
       timeout *= 4
+    # FIXME(machenbach): Make this more OO. Don't expose default outcomes or
+    # the like.
+    if statusfile.IsSlow(test.outcomes or [statusfile.PASS]):
+      timeout *= 2
     if test.dependency is not None:
       dep_command = [ c.replace(test.path, test.dependency) for c in command ]
     else:
diff --git a/tools/testrunner/local/progress.py b/tools/testrunner/local/progress.py
index 8caa58c..2616958 100644
--- a/tools/testrunner/local/progress.py
+++ b/tools/testrunner/local/progress.py
@@ -333,6 +333,7 @@
       "stderr": test.output.stderr,
       "exit_code": test.output.exit_code,
       "result": test.suite.GetOutcome(test),
+      "expected": list(test.outcomes or ["PASS"]),
     })
 
 
diff --git a/tools/testrunner/local/statusfile.py b/tools/testrunner/local/statusfile.py
index 7c3ca7f..a313f05 100644
--- a/tools/testrunner/local/statusfile.py
+++ b/tools/testrunner/local/statusfile.py
@@ -35,6 +35,7 @@
 CRASH = "CRASH"
 SLOW = "SLOW"
 FLAKY = "FLAKY"
+FAST_VARIANTS = "FAST_VARIANTS"
 NO_VARIANTS = "NO_VARIANTS"
 # These are just for the status files and are mapped below in DEFS:
 FAIL_OK = "FAIL_OK"
@@ -44,7 +45,7 @@
 
 KEYWORDS = {}
 for key in [SKIP, FAIL, PASS, OKAY, TIMEOUT, CRASH, SLOW, FLAKY, FAIL_OK,
-            NO_VARIANTS, PASS_OR_FAIL, ALWAYS]:
+            FAST_VARIANTS, NO_VARIANTS, PASS_OR_FAIL, ALWAYS]:
   KEYWORDS[key] = key
 
 DEFS = {FAIL_OK: [FAIL, OKAY],
@@ -70,6 +71,10 @@
   return NO_VARIANTS in outcomes
 
 
+def OnlyFastVariants(outcomes):
+  return FAST_VARIANTS in outcomes
+
+
 def IsFlaky(outcomes):
   return FLAKY in outcomes
 
diff --git a/tools/testrunner/local/testsuite.py b/tools/testrunner/local/testsuite.py
index 47bc08f..84f07fe 100644
--- a/tools/testrunner/local/testsuite.py
+++ b/tools/testrunner/local/testsuite.py
@@ -34,6 +34,17 @@
 from . import utils
 from ..objects import testcase
 
+# Use this to run several variants of the tests.
+VARIANT_FLAGS = {
+    "default": [],
+    "stress": ["--stress-opt", "--always-opt"],
+    "turbofan": ["--turbo-asm", "--turbo-filter=*", "--always-opt"],
+    "nocrankshaft": ["--nocrankshaft"]}
+
+FAST_VARIANT_FLAGS = [
+    f for v, f in VARIANT_FLAGS.iteritems() if v in ["default", "turbofan"]
+]
+
 class TestSuite(object):
 
   @staticmethod
@@ -81,6 +92,8 @@
   def VariantFlags(self, testcase, default_flags):
     if testcase.outcomes and statusfile.OnlyStandardVariant(testcase.outcomes):
       return [[]]
+    if testcase.outcomes and statusfile.OnlyFastVariants(testcase.outcomes):
+      return filter(lambda flags: flags in FAST_VARIANT_FLAGS, default_flags)
     return default_flags
 
   def DownloadData(self):
@@ -123,6 +136,9 @@
         t.outcomes = self.rules[testname]
         if statusfile.DoSkip(t.outcomes):
           continue  # Don't add skipped tests to |filtered|.
+        for outcome in t.outcomes:
+          if outcome.startswith('Flags: '):
+            t.flags += outcome[7:].split()
         flaky = statusfile.IsFlaky(t.outcomes)
         slow = statusfile.IsSlow(t.outcomes)
         pass_fail = statusfile.IsPassOrFail(t.outcomes)
@@ -234,7 +250,7 @@
     if output.exit_code != 0:
       print output.stdout
       print output.stderr
-      return []
+      raise Exception("Test executable failed to list the tests.")
     tests = []
     test_case = ''
     for line in output.stdout.splitlines():
diff --git a/tools/testrunner/objects/testcase.py b/tools/testrunner/objects/testcase.py
index ca82606..6c55082 100644
--- a/tools/testrunner/objects/testcase.py
+++ b/tools/testrunner/objects/testcase.py
@@ -29,10 +29,10 @@
 from . import output
 
 class TestCase(object):
-  def __init__(self, suite, path, flags=[], dependency=None):
-    self.suite = suite  # TestSuite object
-    self.path = path    # string, e.g. 'div-mod', 'test-api/foo'
-    self.flags = flags  # list of strings, flags specific to this test case
+  def __init__(self, suite, path, flags=None, dependency=None):
+    self.suite = suite        # TestSuite object
+    self.path = path          # string, e.g. 'div-mod', 'test-api/foo'
+    self.flags = flags or []  # list of strings, flags specific to this test
     self.dependency = dependency  # |path| for testcase that must be run first
     self.outcomes = None
     self.output = None
diff --git a/tools/tickprocessor.js b/tools/tickprocessor.js
index acd7a71..d544717 100644
--- a/tools/tickprocessor.js
+++ b/tools/tickprocessor.js
@@ -485,6 +485,15 @@
                    this.ticks_.total, null);
   }
 
+  print('\n [C++ entry points]:');
+  print('   ticks    cpp   total   name');
+  var c_entry_functions = this.profile_.getCEntryProfile();
+  var total_c_entry = c_entry_functions[0].ticks;
+  for (var i = 1; i < c_entry_functions.length; i++) {
+    c = c_entry_functions[i];
+    this.printLine(c.name, c.ticks, total_c_entry, totalTicks);
+  }
+
   this.printHeavyProfHeader();
   var heavyProfile = this.profile_.getBottomUpProfile();
   var heavyView = this.viewBuilder_.buildView(heavyProfile);
diff --git a/tools/trace-maps-processor.py b/tools/trace-maps-processor.py
new file mode 100755
index 0000000..bf8c8a8
--- /dev/null
+++ b/tools/trace-maps-processor.py
@@ -0,0 +1,172 @@
+#!/usr/bin/env python
+# Copyright 2014 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import sys
+
+
+action = sys.argv[1]
+
+if action in ["help", "-h", "--help"] or len(sys.argv) != 3:
+  print("Usage: %s <action> <inputfile>, where action can be: \n"
+        "help    Print this message\n"
+        "plain   Print ASCII tree to stdout\n"
+        "dot     Print dot file to stdout\n"
+        "count   Count most frequent transition reasons\n" % sys.argv[0])
+  sys.exit(0)
+
+
+filename = sys.argv[2]
+maps = {}
+root_maps = []
+transitions = {}
+annotations = {}
+
+
+class Map(object):
+
+  def __init__(self, pointer, origin):
+    self.pointer = pointer
+    self.origin = origin
+
+  def __str__(self):
+    return "%s (%s)" % (self.pointer, self.origin)
+
+
+class Transition(object):
+
+  def __init__(self, from_map, to_map, reason):
+    self.from_map = from_map
+    self.to_map = to_map
+    self.reason = reason
+
+
+def RegisterNewMap(raw_map):
+  if raw_map in annotations:
+    annotations[raw_map] += 1
+  else:
+    annotations[raw_map] = 0
+  return AnnotateExistingMap(raw_map)
+
+
+def AnnotateExistingMap(raw_map):
+  return "%s_%d" % (raw_map, annotations[raw_map])
+
+
+def AddMap(pointer, origin):
+  pointer = RegisterNewMap(pointer)
+  maps[pointer] = Map(pointer, origin)
+  return pointer
+
+
+def AddTransition(from_map, to_map, reason):
+  from_map = AnnotateExistingMap(from_map)
+  to_map = AnnotateExistingMap(to_map)
+  if from_map not in transitions:
+    transitions[from_map] = {}
+  targets = transitions[from_map]
+  if to_map in targets:
+    # Some events get printed twice, that's OK. In some cases, ignore the
+    # second output...
+    old_reason = targets[to_map].reason
+    if old_reason.startswith("ReplaceDescriptors"):
+      return
+    # ...and in others use it for additional detail.
+    if reason in []:
+      targets[to_map].reason = reason
+      return
+    # Unexpected duplicate events? Warn.
+    print("// warning: already have a transition from %s to %s, reason: %s" %
+            (from_map, to_map, targets[to_map].reason))
+    return
+  targets[to_map] = Transition(from_map, to_map, reason)
+
+
+with open(filename, "r") as f:
+  last_to_map = ""
+  for line in f:
+    if not line.startswith("[TraceMaps: "): continue
+    words = line.split(" ")
+    event = words[1]
+    if event == "InitialMap":
+      assert words[2] == "map="
+      assert words[4] == "SFI="
+      new_map = AddMap(words[3], "SFI#%s" % words[5])
+      root_maps.append(new_map)
+      continue
+    if words[2] == "from=" and words[4] == "to=":
+      from_map = words[3]
+      to_map = words[5]
+      if from_map not in annotations:
+        print("// warning: unknown from_map %s" % from_map)
+        new_map = AddMap(from_map, "<unknown>")
+        root_maps.append(new_map)
+      if to_map != last_to_map:
+        AddMap(to_map, "<transition> (%s)" % event)
+      last_to_map = to_map
+      if event in ["Transition", "NoTransition"]:
+        assert words[6] == "name=", line
+        reason = "%s: %s" % (event, words[7])
+      elif event in ["Normalize", "ReplaceDescriptors", "SlowToFast"]:
+        assert words[6] == "reason=", line
+        reason = "%s: %s" % (event, words[7])
+        if words[8].strip() != "]":
+          reason = "%s_%s" % (reason, words[8])
+      else:
+        reason = event
+      AddTransition(from_map, to_map, reason)
+      continue
+
+
+def PlainPrint(m, indent, label):
+  print("%s%s (%s)" % (indent, m, label))
+  if m in transitions:
+    for t in transitions[m]:
+      PlainPrint(t, indent + "  ", transitions[m][t].reason)
+
+
+def CountTransitions(m):
+  if m not in transitions: return 0
+  return len(transitions[m])
+
+
+def DotPrint(m, label):
+  print("m%s [label=\"%s\"]" % (m[2:], label))
+  if m in transitions:
+    for t in transitions[m]:
+      # GraphViz doesn't like node labels looking like numbers, so use
+      # "m..." instead of "0x...".
+      print("m%s -> m%s" % (m[2:], t[2:]))
+      reason = transitions[m][t].reason
+      reason = reason.replace("\\", "BACKSLASH")
+      reason = reason.replace("\"", "\\\"")
+      DotPrint(t, reason)
+
+
+if action == "plain":
+  root_maps = sorted(root_maps, key=CountTransitions, reverse=True)
+  for m in root_maps:
+    PlainPrint(m, "", maps[m].origin)
+
+elif action == "dot":
+  print("digraph g {")
+  for m in root_maps:
+    DotPrint(m, maps[m].origin)
+  print("}")
+
+elif action == "count":
+  reasons = {}
+  for s in transitions:
+    for t in transitions[s]:
+      reason = transitions[s][t].reason
+      if reason not in reasons:
+        reasons[reason] = 1
+      else:
+        reasons[reason] += 1
+  reasons_list = []
+  for r in reasons:
+    reasons_list.append("%8d %s" % (reasons[r], r))
+  reasons_list.sort(reverse=True)
+  for r in reasons_list[:20]:
+    print r
diff --git a/tools/try_perf.py b/tools/try_perf.py
new file mode 100755
index 0000000..fcd1ddc
--- /dev/null
+++ b/tools/try_perf.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+# Copyright 2014 the V8 project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import find_depot_tools
+import sys
+
+find_depot_tools.add_depot_tools_to_path()
+
+from git_cl import Changelist
+
+BOTS = [
+  'v8_linux32_perf_try',
+  'v8_linux64_perf_try',
+]
+
+def main(tests):
+  cl = Changelist()
+  if not cl.GetIssue():
+    print 'Need to upload first'
+    return 1
+
+  props = cl.GetIssueProperties()
+  if props.get('closed'):
+    print 'Cannot send tryjobs for a closed CL'
+    return 1
+
+  if props.get('private'):
+    print 'Cannot use trybots with private issue'
+    return 1
+
+  if not tests:
+    print 'Please specify the benchmarks to run as arguments.'
+    return 1
+
+  masters = {'internal.client.v8': dict((b, tests) for b in BOTS)}
+  cl.RpcServer().trigger_distributed_try_jobs(
+        cl.GetIssue(), cl.GetMostRecentPatchset(), cl.GetBranch(),
+        False, None, masters)
+  return 0
+
+if __name__ == "__main__":  # pragma: no cover
+  sys.exit(main(sys.argv[1:]))
diff --git a/tools/unittests/run_perf_test.py b/tools/unittests/run_perf_test.py
index 76e8d23..f9ea0c0 100644
--- a/tools/unittests/run_perf_test.py
+++ b/tools/unittests/run_perf_test.py
@@ -174,11 +174,25 @@
     self.assertEquals(0, self._CallMain())
     self._VerifyResults("test", "score", [
       {"name": "Richards", "results": ["1.234"], "stddev": ""},
-      {"name": "DeltaBlue", "results": ["10657567"], "stddev": ""},
+      {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""},
     ])
     self._VerifyErrors([])
     self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js")
 
+  def testOneRunWithTestFlags(self):
+    test_input = dict(V8_JSON)
+    test_input["test_flags"] = ["2", "test_name"]
+    self._WriteTestInput(test_input)
+    self._MockCommand(["."], ["Richards: 1.234\nDeltaBlue: 10657567"])
+    self.assertEquals(0, self._CallMain())
+    self._VerifyResults("test", "score", [
+      {"name": "Richards", "results": ["1.234"], "stddev": ""},
+      {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""},
+    ])
+    self._VerifyErrors([])
+    self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js",
+                     "--", "2", "test_name")
+
   def testTwoRuns_Units_SuiteName(self):
     test_input = dict(V8_JSON)
     test_input["run_count"] = 2
@@ -190,8 +204,8 @@
                        "Richards: 50\nDeltaBlue: 300\n"])
     self.assertEquals(0, self._CallMain())
     self._VerifyResults("v8", "ms", [
-      {"name": "Richards", "results": ["50", "100"], "stddev": ""},
-      {"name": "DeltaBlue", "results": ["300", "200"], "stddev": ""},
+      {"name": "Richards", "results": ["50.0", "100.0"], "stddev": ""},
+      {"name": "DeltaBlue", "results": ["300.0", "200.0"], "stddev": ""},
     ])
     self._VerifyErrors([])
     self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js")
@@ -208,8 +222,8 @@
                        "Richards: 50\nDeltaBlue: 300\n"])
     self.assertEquals(0, self._CallMain())
     self._VerifyResults("test", "score", [
-      {"name": "Richards", "results": ["50", "100"], "stddev": ""},
-      {"name": "DeltaBlue", "results": ["300", "200"], "stddev": ""},
+      {"name": "Richards", "results": ["50.0", "100.0"], "stddev": ""},
+      {"name": "DeltaBlue", "results": ["300.0", "200.0"], "stddev": ""},
     ])
     self._VerifyErrors([])
     self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js")
@@ -227,23 +241,21 @@
     self.assertEquals([
       {"units": "score",
        "graphs": ["test", "Richards"],
-       "results": ["50", "100"],
+       "results": ["50.0", "100.0"],
        "stddev": ""},
       {"units": "ms",
        "graphs": ["test", "Sub", "Leaf"],
-       "results": ["3", "2", "1"],
+       "results": ["3.0", "2.0", "1.0"],
        "stddev": ""},
       {"units": "score",
        "graphs": ["test", "DeltaBlue"],
-       "results": ["200"],
+       "results": ["200.0"],
        "stddev": ""},
       ], self._LoadResults()["traces"])
     self._VerifyErrors([])
     self._VerifyMockMultiple(
-        (path.join("out", "x64.release", "d7"), "--flag", "file1.js",
-         "file2.js", "run.js"),
-        (path.join("out", "x64.release", "d7"), "--flag", "file1.js",
-         "file2.js", "run.js"),
+        (path.join("out", "x64.release", "d7"), "--flag", "run.js"),
+        (path.join("out", "x64.release", "d7"), "--flag", "run.js"),
         (path.join("out", "x64.release", "d8"), "--flag", "run.js"),
         (path.join("out", "x64.release", "d8"), "--flag", "run.js"),
         (path.join("out", "x64.release", "d8"), "--flag", "run.js"),
@@ -258,7 +270,7 @@
     self.assertEquals(0, self._CallMain())
     self._VerifyResults("test", "score", [
       {"name": "Richards", "results": ["1.234"], "stddev": "0.23"},
-      {"name": "DeltaBlue", "results": ["10657567"], "stddev": "106"},
+      {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": "106"},
     ])
     self._VerifyErrors([])
     self._VerifyMock(path.join("out", "x64.release", "d7"), "--flag", "run.js")
@@ -274,8 +286,8 @@
                               "DeltaBlue: 5\nDeltaBlue-stddev: 0.8\n"])
     self.assertEquals(1, self._CallMain())
     self._VerifyResults("test", "score", [
-      {"name": "Richards", "results": ["2", "3"], "stddev": "0.7"},
-      {"name": "DeltaBlue", "results": ["5", "6"], "stddev": "0.8"},
+      {"name": "Richards", "results": ["2.0", "3.0"], "stddev": "0.7"},
+      {"name": "DeltaBlue", "results": ["5.0", "6.0"], "stddev": "0.8"},
     ])
     self._VerifyErrors(
         ["Test Richards should only run once since a stddev is provided "
@@ -292,7 +304,7 @@
     self.assertEquals(0, self._CallMain("--buildbot"))
     self._VerifyResults("test", "score", [
       {"name": "Richards", "results": ["1.234"], "stddev": ""},
-      {"name": "DeltaBlue", "results": ["10657567"], "stddev": ""},
+      {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""},
     ])
     self._VerifyErrors([])
     self._VerifyMock(path.join("out", "Release", "d7"), "--flag", "run.js")
@@ -305,7 +317,7 @@
     self.assertEquals(0, self._CallMain("--buildbot"))
     self._VerifyResults("test", "score", [
       {"name": "Richards", "results": ["1.234"], "stddev": ""},
-      {"name": "DeltaBlue", "results": ["10657567"], "stddev": ""},
+      {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""},
       {"name": "Total", "results": ["3626.49109719"], "stddev": ""},
     ])
     self._VerifyErrors([])
@@ -315,14 +327,15 @@
     test_input = dict(V8_JSON)
     test_input["total"] = True
     self._WriteTestInput(test_input)
-    self._MockCommand(["."], ["x\nRichaards: 1.234\nDeltaBlue: 10657567\ny\n"])
+    self._MockCommand(["."], ["x\nRichards: bla\nDeltaBlue: 10657567\ny\n"])
     self.assertEquals(1, self._CallMain("--buildbot"))
     self._VerifyResults("test", "score", [
       {"name": "Richards", "results": [], "stddev": ""},
-      {"name": "DeltaBlue", "results": ["10657567"], "stddev": ""},
+      {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""},
     ])
     self._VerifyErrors(
-        ["Regexp \"^Richards: (.+)$\" didn't match for test Richards.",
+        ["Regexp \"^Richards: (.+)$\" "
+         "returned a non-numeric for test Richards.",
          "Not all traces have the same number of results."])
     self._VerifyMock(path.join("out", "Release", "d7"), "--flag", "run.js")
 
@@ -332,7 +345,7 @@
     self.assertEquals(1, self._CallMain())
     self._VerifyResults("test", "score", [
       {"name": "Richards", "results": [], "stddev": ""},
-      {"name": "DeltaBlue", "results": ["10657567"], "stddev": ""},
+      {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""},
     ])
     self._VerifyErrors(
         ["Regexp \"^Richards: (.+)$\" didn't match for test Richards."])
@@ -342,14 +355,30 @@
     test_input = dict(V8_GENERIC_JSON)
     self._WriteTestInput(test_input)
     self._MockCommand(["."], [
-      "Trace(Test1), Result(1.234), StdDev(0.23)\n"
-      "Trace(Test2), Result(10657567), StdDev(106)\n"])
-    self.assertEquals(0, self._CallMain())
-    self._VerifyResults("test", "ms", [
-      {"name": "Test1", "results": ["1.234"], "stddev": "0.23"},
-      {"name": "Test2", "results": ["10657567"], "stddev": "106"},
-    ])
-    self._VerifyErrors([])
+      "RESULT Infra: Constant1= 11 count\n"
+      "RESULT Infra: Constant2= [10,5,10,15] count\n"
+      "RESULT Infra: Constant3= {12,1.2} count\n"
+      "RESULT Infra: Constant4= [10,5,error,15] count\n"])
+    self.assertEquals(1, self._CallMain())
+    self.assertEquals([
+      {"units": "count",
+       "graphs": ["test", "Infra", "Constant1"],
+       "results": ["11.0"],
+       "stddev": ""},
+      {"units": "count",
+       "graphs": ["test", "Infra", "Constant2"],
+       "results": ["10.0", "5.0", "10.0", "15.0"],
+       "stddev": ""},
+      {"units": "count",
+       "graphs": ["test", "Infra", "Constant3"],
+       "results": ["12.0"],
+       "stddev": "1.2"},
+      {"units": "count",
+       "graphs": ["test", "Infra", "Constant4"],
+       "results": [],
+       "stddev": ""},
+      ], self._LoadResults()["traces"])
+    self._VerifyErrors(["Found non-numeric in test/Infra/Constant4"])
     self._VerifyMock(path.join("out", "x64.release", "cc"), "--flag", "")
 
   def testOneRunTimingOut(self):
@@ -368,3 +397,22 @@
     ])
     self._VerifyMock(
         path.join("out", "x64.release", "d7"), "--flag", "run.js", timeout=70)
+
+  # Simple test that mocks out the android platform. Testing the platform would
+  # require lots of complicated mocks for the android tools.
+  def testAndroid(self):
+    self._WriteTestInput(V8_JSON)
+    platform = run_perf.Platform
+    platform.PreExecution = MagicMock(return_value=None)
+    platform.PostExecution = MagicMock(return_value=None)
+    platform.PreTests = MagicMock(return_value=None)
+    platform.Run = MagicMock(
+        return_value="Richards: 1.234\nDeltaBlue: 10657567\n")
+    run_perf.AndroidPlatform = MagicMock(return_value=platform)
+    self.assertEquals(
+        0, self._CallMain("--android-build-tools", "/some/dir",
+                          "--arch", "android_arm"))
+    self._VerifyResults("test", "score", [
+      {"name": "Richards", "results": ["1.234"], "stddev": ""},
+      {"name": "DeltaBlue", "results": ["10657567.0"], "stddev": ""},
+    ])
diff --git a/tools/whitespace.txt b/tools/whitespace.txt
index 305e8ed..657e68f 100644
--- a/tools/whitespace.txt
+++ b/tools/whitespace.txt
@@ -1,8 +1,8 @@
-You can modify this file to create no-op changelists..
+You can modify this file to create no-op changelists.
 
 Try to write something funny. And please don't add trailing whitespace.
 
 A Smi walks into a bar and says:
 "I'm so deoptimized today!"
 The doubles heard this and started to unbox.
-The Smi looked at them when a crazy v8-autoroll account showed up..............
+The Smi looked at them when a crazy v8-autoroll account showed up...........
